diff --git a/.mailmap b/.mailmap index 5273cfd70ad62996ba8374698fb5e22e91d33f45..c7b10caecc4ee24a17f14be238c301391451f0b3 100644 --- a/.mailmap +++ b/.mailmap @@ -68,6 +68,8 @@ Jacob Shin James Bottomley James Bottomley James E Wilson +James Hogan +James Hogan James Ketrenos Javi Merino diff --git a/CREDITS b/CREDITS index 5d09c26d69cdc0f4709cf48f5f3ff6195d53e85d..9fbd2c77b5462d71dd9d24b5966c03d528094ce6 100644 --- a/CREDITS +++ b/CREDITS @@ -2090,7 +2090,7 @@ S: Kuala Lumpur, Malaysia N: Mohit Kumar D: ST Microelectronics SPEAr13xx PCI host bridge driver -D: Synopsys Designware PCI host bridge driver +D: Synopsys DesignWare PCI host bridge driver N: Gabor Kuti E: seasons@falcon.sch.bme.hu @@ -2606,11 +2606,9 @@ E: tmolina@cablespeed.com D: bug fixes, documentation, minor hackery N: Paul Moore -E: paul.moore@hp.com -D: NetLabel author -S: Hewlett-Packard -S: 110 Spit Brook Road -S: Nashua, NH 03062 +E: paul@paul-moore.com +W: http://www.paul-moore.com +D: NetLabel, SELinux, audit N: James Morris E: jmorris@namei.org diff --git a/Documentation/ABI/stable/sysfs-bus-nvmem b/Documentation/ABI/stable/sysfs-bus-nvmem new file mode 100644 index 0000000000000000000000000000000000000000..5923ab4620c5d829e4a4f8f5fd338fd9b00d54ec --- /dev/null +++ b/Documentation/ABI/stable/sysfs-bus-nvmem @@ -0,0 +1,19 @@ +What: /sys/bus/nvmem/devices/.../nvmem +Date: July 2015 +KernelVersion: 4.2 +Contact: Srinivas Kandagatla +Description: + This file allows user to read/write the raw NVMEM contents. + Permissions for write to this file depends on the nvmem + provider configuration. + + ex: + hexdump /sys/bus/nvmem/devices/qfprom0/nvmem + + 0000000 0000 0000 0000 0000 0000 0000 0000 0000 + * + 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00 + 0000000 0000 0000 0000 0000 0000 0000 0000 0000 + ... + * + 0001000 diff --git a/Documentation/ABI/stable/sysfs-driver-dma-ioatdma b/Documentation/ABI/stable/sysfs-driver-dma-ioatdma new file mode 100644 index 0000000000000000000000000000000000000000..420c1d09e42f36fa9cbd24375cf985815450a575 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-dma-ioatdma @@ -0,0 +1,30 @@ +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/cap +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: Capabilities the DMA supports.Currently there are DMA_PQ, DMA_PQ_VAL, + DMA_XOR,DMA_XOR_VAL,DMA_INTERRUPT. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/ring_active +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: The number of descriptors active in the ring. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/ring_size +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: Descriptor ring size, total number of descriptors available. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/version +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: Version of ioatdma device. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/intr_coalesce +Date: August 8, 2017 +KernelVersion: 4.14 +Contact: dmaengine@vger.kernel.org +Description: Tune-able interrupt delay value per channel basis. diff --git a/Documentation/ABI/testing/configfs-usb-gadget-rndis b/Documentation/ABI/testing/configfs-usb-gadget-rndis index e32879b84b4d092ffc3aa3c655c470ec5135c9fd..137399095d74b53540deed58ffc10b5329a97136 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-rndis +++ b/Documentation/ABI/testing/configfs-usb-gadget-rndis @@ -12,3 +12,6 @@ Description: Ethernet over USB link dev_addr - MAC address of device's end of this Ethernet over USB link + class - USB interface class, default is 02 (hex) + subclass - USB interface subclass, default is 06 (hex) + protocol - USB interface protocol, default is 00 (hex) diff --git a/Documentation/ABI/testing/ppc-memtrace b/Documentation/ABI/testing/ppc-memtrace new file mode 100644 index 0000000000000000000000000000000000000000..2e8b9374127002a0a82920099d23e642b89a6aa4 --- /dev/null +++ b/Documentation/ABI/testing/ppc-memtrace @@ -0,0 +1,45 @@ +What: /sys/kernel/debug/powerpc/memtrace +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This folder contains the relevant debugfs files for the + hardware trace macro to use. CONFIG_PPC64_HARDWARE_TRACING + must be set. + +What: /sys/kernel/debug/powerpc/memtrace/enable +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: Write an integer containing the size in bytes of the memory + you want removed from each NUMA node to this file - it must be + aligned to the memblock size. This amount of RAM will be removed + from the kernel mappings and the following debugfs files will be + created. This can only be successfully done once per boot. Once + memory is successfully removed from each node, the following + files are created. + +What: /sys/kernel/debug/powerpc/memtrace/ +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This directory contains information about the removed memory + from the specific NUMA node. + +What: /sys/kernel/debug/powerpc/memtrace//size +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This contains the size of the memory removed from the node. + +What: /sys/kernel/debug/powerpc/memtrace//start +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This contains the start address of the removed memory. + +What: /sys/kernel/debug/powerpc/memtrace//trace +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This is where the hardware trace macro will output the trace + it generates. diff --git a/Documentation/ABI/testing/procfs-smaps_rollup b/Documentation/ABI/testing/procfs-smaps_rollup new file mode 100644 index 0000000000000000000000000000000000000000..0a54ed0d63c99377becfbefe2273a46dd1087f75 --- /dev/null +++ b/Documentation/ABI/testing/procfs-smaps_rollup @@ -0,0 +1,31 @@ +What: /proc/pid/smaps_rollup +Date: August 2017 +Contact: Daniel Colascione +Description: + This file provides pre-summed memory information for a + process. The format is identical to /proc/pid/smaps, + except instead of an entry for each VMA in a process, + smaps_rollup has a single entry (tagged "[rollup]") + for which each field is the sum of the corresponding + fields from all the maps in /proc/pid/smaps. + For more details, see the procfs man page. + + Typical output looks like this: + + 00100000-ff709000 ---p 00000000 00:00 0 [rollup] + Rss: 884 kB + Pss: 385 kB + Shared_Clean: 696 kB + Shared_Dirty: 0 kB + Private_Clean: 120 kB + Private_Dirty: 68 kB + Referenced: 884 kB + Anonymous: 68 kB + LazyFree: 0 kB + AnonHugePages: 0 kB + ShmemPmdMapped: 0 kB + Shared_Hugetlb: 0 kB + Private_Hugetlb: 0 kB + Swap: 0 kB + SwapPss: 0 kB + Locked: 385 kB diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram index 451b6d882b2c182af1e9ce9b28bcd73b1218ae26..c1513c756af125ce5adb76ee8e4522e25572a099 100644 --- a/Documentation/ABI/testing/sysfs-block-zram +++ b/Documentation/ABI/testing/sysfs-block-zram @@ -90,3 +90,11 @@ Description: device's debugging info useful for kernel developers. Its format is not documented intentionally and may change anytime without any notice. + +What: /sys/block/zram/backing_dev +Date: June 2017 +Contact: Minchan Kim +Description: + The backing_dev file is read-write and set up backing + device for zram to write incompressible pages. + For using, user should enable CONFIG_ZRAM_WRITEBACK. diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 2db2cdf42d5417fc218ea29763274503467e7d01..7eead5f97e0295b009c56b1d82d13ecf9e6163e6 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -119,6 +119,15 @@ Description: unique to allow association with event codes. Units after application of scale and offset are milliamps. +What: /sys/bus/iio/devices/iio:deviceX/in_powerY_raw +KernelVersion: 4.5 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no bias removal etc.) power measurement from + channel Y. The number must always be specified and + unique to allow association with event codes. Units after + application of scale and offset are milliwatts. + What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw KernelVersion: 3.2 Contact: linux-iio@vger.kernel.org diff --git a/Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32 new file mode 100644 index 0000000000000000000000000000000000000000..ad2cc63e4bf8252ace73583faa7c9fffbe6cede8 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32 @@ -0,0 +1,57 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_count0_preset +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Reading returns the current preset value. Writing sets the + preset value. Encoder counts continuously from 0 to preset + value, depending on direction (up/down). + +What: /sys/bus/iio/devices/iio:deviceX/in_count_quadrature_mode_available +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Reading returns the list possible quadrature modes. + +What: /sys/bus/iio/devices/iio:deviceX/in_count0_quadrature_mode +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Configure the device counter quadrature modes: + - non-quadrature: + Encoder IN1 input servers as the count input (up + direction). + - quadrature: + Encoder IN1 and IN2 inputs are mixed to get direction + and count. + +What: /sys/bus/iio/devices/iio:deviceX/in_count_polarity_available +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Reading returns the list possible active edges. + +What: /sys/bus/iio/devices/iio:deviceX/in_count0_polarity +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Configure the device encoder/counter active edge: + - rising-edge + - falling-edge + - both-edges + + In non-quadrature mode, device counts up on active edge. + In quadrature mode, encoder counting scenarios are as follows: + ---------------------------------------------------------------- + | Active | Level on | IN1 signal | IN2 signal | + | edge | opposite |------------------------------------------ + | | signal | Rising | Falling | Rising | Falling | + ---------------------------------------------------------------- + | Rising | High -> | Down | - | Up | - | + | edge | Low -> | Up | - | Down | - | + ---------------------------------------------------------------- + | Falling | High -> | - | Up | - | Down | + | edge | Low -> | - | Down | - | Up | + ---------------------------------------------------------------- + | Both | High -> | Down | Up | Up | Down | + | edges | Low -> | Up | Down | Down | Up | + ---------------------------------------------------------------- diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index 2a98149943ea542868cab5423e28166d4db48a5e..392bef5bd3996f71e5d73f934e701f9396afbf71 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -45,6 +45,8 @@ Contact: thunderbolt-software@lists.01.org Description: When a devices supports Thunderbolt secure connect it will have this attribute. Writing 32 byte hex string changes authorization to use the secure connection method instead. + Writing an empty string clears the key and regular connection + method can be used again. What: /sys/bus/thunderbolt/devices/.../device Date: Sep 2017 diff --git a/Documentation/ABI/testing/sysfs-bus-usb-lvstest b/Documentation/ABI/testing/sysfs-bus-usb-lvstest index 5151290cf8e75f27642d1c4d52ede0cd039f3d24..ee0046dc41928ae01e537026d443c832c73b83ab 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb-lvstest +++ b/Documentation/ABI/testing/sysfs-bus-usb-lvstest @@ -45,3 +45,16 @@ Contact: Pratyush Anand Description: Write to this node to issue "U3 exit" for Link Layer Validation device. It is needed for TD.7.36. + +What: /sys/bus/usb/devices/.../enable_compliance +Date: July 2017 +Description: + Write to this node to set the port to compliance mode to test + with Link Layer Validation device. It is needed for TD.7.34. + +What: /sys/bus/usb/devices/.../warm_reset +Date: July 2017 +Description: + Write to this node to issue "Warm Reset" for Link Layer Validation + device. It may be needed to properly reset an xHCI 1.1 host port if + compliance mode needed to be explicitly enabled. diff --git a/Documentation/ABI/testing/sysfs-driver-altera-cvp b/Documentation/ABI/testing/sysfs-driver-altera-cvp new file mode 100644 index 0000000000000000000000000000000000000000..8cde64a71edba2c15dd24026c705b15b6016e162 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-altera-cvp @@ -0,0 +1,8 @@ +What: /sys/bus/pci/drivers/altera-cvp/chkcfg +Date: May 2017 +Kernel Version: 4.13 +Contact: Anatolij Gustschin +Description: + Contains either 1 or 0 and controls if configuration + error checking in altera-cvp driver is turned on or + off. diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-powercap b/Documentation/ABI/testing/sysfs-firmware-opal-powercap new file mode 100644 index 0000000000000000000000000000000000000000..c9b66ec4f165d2700653a6d42f6150472dc19e5e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-opal-powercap @@ -0,0 +1,31 @@ +What: /sys/firmware/opal/powercap +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: Powercap directory for Powernv (P8, P9) servers + + Each folder in this directory contains a + power-cappable component. + +What: /sys/firmware/opal/powercap/system-powercap + /sys/firmware/opal/powercap/system-powercap/powercap-min + /sys/firmware/opal/powercap/system-powercap/powercap-max + /sys/firmware/opal/powercap/system-powercap/powercap-current +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: System powercap directory and attributes applicable for + Powernv (P8, P9) servers + + This directory provides powercap information. It + contains below sysfs attributes: + + - powercap-min : This file provides the minimum + possible powercap in Watt units + + - powercap-max : This file provides the maximum + possible powercap in Watt units + + - powercap-current : This file provides the current + powercap set on the system. Writing to this file + creates a request for setting a new-powercap. The + powercap requested must be between powercap-min + and powercap-max. diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-psr b/Documentation/ABI/testing/sysfs-firmware-opal-psr new file mode 100644 index 0000000000000000000000000000000000000000..cc2ece70e365749fcfde78cff8c3988eb9a509c3 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-opal-psr @@ -0,0 +1,18 @@ +What: /sys/firmware/opal/psr +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: Power-Shift-Ratio directory for Powernv P9 servers + + Power-Shift-Ratio allows to provide hints the firmware + to shift/throttle power between different entities in + the system. Each attribute in this directory indicates + a settable PSR. + +What: /sys/firmware/opal/psr/cpu_to_gpu_X +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: PSR sysfs attributes for Powernv P9 servers + + Power-Shift-Ratio between CPU and GPU for a given chip + with chip-id X. This file gives the ratio (0-100) + which is used by OCC for power-capping. diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 84c606fb3ca4dff45bbd59af27de49d6d86884ca..11b7f4ebea7c4b6a04d2ce3894ff1a8d9907e60a 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -57,6 +57,15 @@ Contact: "Jaegeuk Kim" Description: Controls the issue rate of small discard commands. +What: /sys/fs/f2fs//discard_granularity +Date: July 2017 +Contact: "Chao Yu" +Description: + Controls discard granularity of inner discard thread, inner thread + will not issue discards with size that is smaller than granularity. + The unit size is one block, now only support configuring in range + of [1, 512]. + What: /sys/fs/f2fs//max_victim_search Date: January 2014 Contact: "Jaegeuk Kim" @@ -130,3 +139,15 @@ Date: June 2017 Contact: "Chao Yu" Description: Controls current reserved blocks in system. + +What: /sys/fs/f2fs//gc_urgent +Date: August 2017 +Contact: "Jaegeuk Kim" +Description: + Do background GC agressively + +What: /sys/fs/f2fs//gc_urgent_sleep_time +Date: August 2017 +Contact: "Jaegeuk Kim" +Description: + Controls sleep time of GC urgent mode diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-swap b/Documentation/ABI/testing/sysfs-kernel-mm-swap new file mode 100644 index 0000000000000000000000000000000000000000..587db52084c7c21a6db250dffd9b794859d7466a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-mm-swap @@ -0,0 +1,26 @@ +What: /sys/kernel/mm/swap/ +Date: August 2017 +Contact: Linux memory management mailing list +Description: Interface for swapping + +What: /sys/kernel/mm/swap/vma_ra_enabled +Date: August 2017 +Contact: Linux memory management mailing list +Description: Enable/disable VMA based swap readahead. + + If set to true, the VMA based swap readahead algorithm + will be used for swappable anonymous pages mapped in a + VMA, and the global swap readahead algorithm will be + still used for tmpfs etc. other users. If set to + false, the global swap readahead algorithm will be + used for all swappable pages. + +What: /sys/kernel/mm/swap/vma_ra_max_order +Date: August 2017 +Contact: Linux memory management mailing list +Description: The max readahead size in order for VMA based swap readahead + + VMA based swap readahead algorithm will readahead at + most 1 << max_order pages for each readahead. The + real readahead size for each readahead will be scaled + according to the estimation algorithm. diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power index f523e5a3ac33297999aba5c52a81b6075b0a7fa1..a1d1612f36519f832c2d307293527083cf025271 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power @@ -127,7 +127,7 @@ Description: What; /sys/power/pm_trace_dev_match Date: October 2010 -Contact: James Hogan +Contact: James Hogan Description: The /sys/power/pm_trace_dev_match file contains the name of the device associated with the last PM event point saved in the RTC @@ -273,3 +273,15 @@ Description: This output is useful for system wakeup diagnostics of spurious wakeup interrupts. + +What: /sys/power/pm_debug_messages +Date: July 2017 +Contact: Rafael J. Wysocki +Description: + The /sys/power/pm_debug_messages file controls the printing + of debug messages from the system suspend/hiberbation + infrastructure to the kernel log. + + Writing a "1" to this file enables the debug messages and + writing a "0" (default) to it disables them. Reads from + this file return the current value. diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 45b29326d719b25395accc371177348a52ca1ace..ac66ae2509a91c50174f4e21091d025529cfe7fd 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -515,14 +515,15 @@ API at all. :: void * - dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) + dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flag, unsigned long attrs) -Identical to dma_alloc_coherent() except that the platform will -choose to return either consistent or non-consistent memory as it sees -fit. By using this API, you are guaranteeing to the platform that you -have all the correct and necessary sync points for this memory in the -driver should it choose to return non-consistent memory. +Identical to dma_alloc_coherent() except that when the +DMA_ATTR_NON_CONSISTENT flags is passed in the attrs argument, the +platform will choose to return either consistent or non-consistent memory +as it sees fit. By using this API, you are guaranteeing to the platform +that you have all the correct and necessary sync points for this memory +in the driver should it choose to return non-consistent memory. Note: where the platform can return consistent memory, it will guarantee that the sync points become nops. @@ -535,12 +536,13 @@ that simply cannot make consistent memory. :: void - dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) + dma_free_attrs(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle, unsigned long attrs) -Free memory allocated by the nonconsistent API. All parameters must -be identical to those passed in (and returned by -dma_alloc_noncoherent()). +Free memory allocated by the dma_alloc_attrs(). All parameters common +parameters must identical to those otherwise passed to dma_fre_coherent, +and the attrs argument must be identical to the attrs passed to +dma_alloc_attrs(). :: @@ -564,8 +566,8 @@ memory or doing partial flushes. dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) -Do a partial sync of memory that was allocated by -dma_alloc_noncoherent(), starting at virtual address vaddr and +Do a partial sync of memory that was allocated by dma_alloc_attrs() with +the DMA_ATTR_NON_CONSISTENT flag starting at virtual address vaddr and continuing on for size. Again, you *must* observe the cache line boundaries when doing this. @@ -590,34 +592,11 @@ size is the size of the area (must be multiples of PAGE_SIZE). flags can be ORed together and are: -- DMA_MEMORY_MAP - request that the memory returned from - dma_alloc_coherent() be directly writable. - -- DMA_MEMORY_IO - request that the memory returned from - dma_alloc_coherent() be addressable using read()/write()/memcpy_toio() etc. - -One or both of these flags must be present. - -- DMA_MEMORY_INCLUDES_CHILDREN - make the declared memory be allocated by - dma_alloc_coherent of any child devices of this one (for memory residing - on a bridge). - - DMA_MEMORY_EXCLUSIVE - only allocate memory from the declared regions. Do not allow dma_alloc_coherent() to fall back to system memory when it's out of memory in the declared region. -The return value will be either DMA_MEMORY_MAP or DMA_MEMORY_IO and -must correspond to a passed in flag (i.e. no returning DMA_MEMORY_IO -if only DMA_MEMORY_MAP were passed in) for success or zero for -failure. - -Note, for DMA_MEMORY_IO returns, all subsequent memory returned by -dma_alloc_coherent() may no longer be accessed directly, but instead -must be accessed using the correct bus functions. If your driver -isn't prepared to handle this contingency, it should not specify -DMA_MEMORY_IO in the input flags. - -As a simplification for the platforms, only **one** such region of +As a simplification for the platforms, only *one* such region of memory may be declared per device. For reasons of efficiency, most platforms choose to track the declared diff --git a/Documentation/Makefile b/Documentation/Makefile index a42320385df34eed57b2ece17e9f859ae1a92a2d..85f7856f009203d9e7d15487e452a8b9771c3784 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -22,6 +22,8 @@ ifeq ($(HAVE_SPHINX),0) .DEFAULT: $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) + @echo + @./scripts/sphinx-pre-install @echo " SKIP Sphinx $@ target." else # HAVE_SPHINX @@ -95,16 +97,6 @@ endif # HAVE_SPHINX # The following targets are independent of HAVE_SPHINX, and the rules should # work or silently pass without Sphinx. -# no-ops for the Sphinx toolchain -sgmldocs: - @: -psdocs: - @: -mandocs: - @: -installmandocs: - @: - cleandocs: $(Q)rm -rf $(BUILDDIR) $(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html index 95b30fa25d56ae88155d8a1268882a90fe2250b9..62e847bcdcddf9c454361b3cfb080db4278d3d60 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.html +++ b/Documentation/RCU/Design/Requirements/Requirements.html @@ -2080,6 +2080,8 @@ Some of the relevant points of interest are as follows:
  • Scheduler and RCU.
  • Tracing and RCU.
  • Energy Efficiency. +
  • + Scheduling-Clock Interrupts and RCU.
  • Memory Efficiency.
  • Performance, Scalability, Response Time, and Reliability. @@ -2532,6 +2534,134 @@ I learned of many of these requirements via angry phone calls: Flaming me on the Linux-kernel mailing list was apparently not sufficient to fully vent their ire at RCU's energy-efficiency bugs! +

    +Scheduling-Clock Interrupts and RCU

    + +

    +The kernel transitions between in-kernel non-idle execution, userspace +execution, and the idle loop. +Depending on kernel configuration, RCU handles these states differently: + + + + + + + + + + + + + + + + + + +
    HZ KconfigIn-KernelUsermodeIdle
    HZ_PERIODICCan rely on scheduling-clock interrupt.Can rely on scheduling-clock interrupt and its + detection of interrupt from usermode.Can rely on RCU's dyntick-idle detection.
    NO_HZ_IDLECan rely on scheduling-clock interrupt.Can rely on scheduling-clock interrupt and its + detection of interrupt from usermode.Can rely on RCU's dyntick-idle detection.
    NO_HZ_FULLCan only sometimes rely on scheduling-clock interrupt. + In other cases, it is necessary to bound kernel execution + times and/or use IPIs.Can rely on RCU's dyntick-idle detection.Can rely on RCU's dyntick-idle detection.
    + + + + + + + + +
     
    Quick Quiz:
    + Why can't NO_HZ_FULL in-kernel execution rely on the + scheduling-clock interrupt, just like HZ_PERIODIC + and NO_HZ_IDLE do? +
    Answer:
    + Because, as a performance optimization, NO_HZ_FULL + does not necessarily re-enable the scheduling-clock interrupt + on entry to each and every system call. +
     
    + +

    +However, RCU must be reliably informed as to whether any given +CPU is currently in the idle loop, and, for NO_HZ_FULL, +also whether that CPU is executing in usermode, as discussed +earlier. +It also requires that the scheduling-clock interrupt be enabled when +RCU needs it to be: + +

      +
    1. If a CPU is either idle or executing in usermode, and RCU believes + it is non-idle, the scheduling-clock tick had better be running. + Otherwise, you will get RCU CPU stall warnings. Or at best, + very long (11-second) grace periods, with a pointless IPI waking + the CPU from time to time. +
    2. If a CPU is in a portion of the kernel that executes RCU read-side + critical sections, and RCU believes this CPU to be idle, you will get + random memory corruption. DON'T DO THIS!!! + +
      This is one reason to test with lockdep, which will complain + about this sort of thing. +
    3. If a CPU is in a portion of the kernel that is absolutely + positively no-joking guaranteed to never execute any RCU read-side + critical sections, and RCU believes this CPU to to be idle, + no problem. This sort of thing is used by some architectures + for light-weight exception handlers, which can then avoid the + overhead of rcu_irq_enter() and rcu_irq_exit() + at exception entry and exit, respectively. + Some go further and avoid the entireties of irq_enter() + and irq_exit(). + +
      Just make very sure you are running some of your tests with + CONFIG_PROVE_RCU=y, just in case one of your code paths + was in fact joking about not doing RCU read-side critical sections. +
    4. If a CPU is executing in the kernel with the scheduling-clock + interrupt disabled and RCU believes this CPU to be non-idle, + and if the CPU goes idle (from an RCU perspective) every few + jiffies, no problem. It is usually OK for there to be the + occasional gap between idle periods of up to a second or so. + +
      If the gap grows too long, you get RCU CPU stall warnings. +
    5. If a CPU is either idle or executing in usermode, and RCU believes + it to be idle, of course no problem. +
    6. If a CPU is executing in the kernel, the kernel code + path is passing through quiescent states at a reasonable + frequency (preferably about once per few jiffies, but the + occasional excursion to a second or so is usually OK) and the + scheduling-clock interrupt is enabled, of course no problem. + +
      If the gap between a successive pair of quiescent states grows + too long, you get RCU CPU stall warnings. +
    + + + + + + + + +
     
    Quick Quiz:
    + But what if my driver has a hardware interrupt handler + that can run for many seconds? + I cannot invoke schedule() from an hardware + interrupt handler, after all! +
    Answer:
    + One approach is to do rcu_irq_exit();rcu_irq_enter(); + every so often. + But given that long-running interrupt handlers can cause + other problems, not least for response time, shouldn't you + work to keep your interrupt handler's runtime within reasonable + bounds? +
     
    + +

    +But as long as RCU is properly informed of kernel state transitions between +in-kernel execution, usermode execution, and idle, and as long as the +scheduling-clock interrupt is enabled when RCU needs it to be, you +can rest assured that the bugs you encounter will be in some other +part of RCU or some other part of the kernel! +

    Memory Efficiency

    diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index 6beda556faf32a3b3a90719cd20183c6476a9b30..49747717d90579d02abd6c07f5b34cf9f3543ee6 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt @@ -23,6 +23,14 @@ over a rather long period of time, but improvements are always welcome! Yet another exception is where the low real-time latency of RCU's read-side primitives is critically important. + One final exception is where RCU readers are used to prevent + the ABA problem (https://en.wikipedia.org/wiki/ABA_problem) + for lockless updates. This does result in the mildly + counter-intuitive situation where rcu_read_lock() and + rcu_read_unlock() are used to protect updates, however, this + approach provides the same potential simplifications that garbage + collectors do. + 1. Does the update code have proper mutual exclusion? RCU does allow -readers- to run (almost) naked, but -writers- must @@ -40,7 +48,9 @@ over a rather long period of time, but improvements are always welcome! explain how this single task does not become a major bottleneck on big multiprocessor machines (for example, if the task is updating information relating to itself that other tasks can read, there - by definition can be no bottleneck). + by definition can be no bottleneck). Note that the definition + of "large" has changed significantly: Eight CPUs was "large" + in the year 2000, but a hundred CPUs was unremarkable in 2017. 2. Do the RCU read-side critical sections make proper use of rcu_read_lock() and friends? These primitives are needed @@ -55,6 +65,12 @@ over a rather long period of time, but improvements are always welcome! Disabling of preemption can serve as rcu_read_lock_sched(), but is less readable. + Letting RCU-protected pointers "leak" out of an RCU read-side + critical section is every bid as bad as letting them leak out + from under a lock. Unless, of course, you have arranged some + other means of protection, such as a lock or a reference count + -before- letting them out of the RCU read-side critical section. + 3. Does the update code tolerate concurrent accesses? The whole point of RCU is to permit readers to run without @@ -78,10 +94,10 @@ over a rather long period of time, but improvements are always welcome! This works quite well, also. - c. Make updates appear atomic to readers. For example, + c. Make updates appear atomic to readers. For example, pointer updates to properly aligned fields will appear atomic, as will individual atomic primitives. - Sequences of perations performed under a lock will -not- + Sequences of operations performed under a lock will -not- appear to be atomic to RCU readers, nor will sequences of multiple atomic primitives. @@ -168,8 +184,8 @@ over a rather long period of time, but improvements are always welcome! 5. If call_rcu(), or a related primitive such as call_rcu_bh(), call_rcu_sched(), or call_srcu() is used, the callback function - must be written to be called from softirq context. In particular, - it cannot block. + will be called from softirq context. In particular, it cannot + block. 6. Since synchronize_rcu() can block, it cannot be called from any sort of irq context. The same rule applies for @@ -178,11 +194,14 @@ over a rather long period of time, but improvements are always welcome! synchronize_sched_expedite(), and synchronize_srcu_expedited(). The expedited forms of these primitives have the same semantics - as the non-expedited forms, but expediting is both expensive - and unfriendly to real-time workloads. Use of the expedited - primitives should be restricted to rare configuration-change - operations that would not normally be undertaken while a real-time - workload is running. + as the non-expedited forms, but expediting is both expensive and + (with the exception of synchronize_srcu_expedited()) unfriendly + to real-time workloads. Use of the expedited primitives should + be restricted to rare configuration-change operations that would + not normally be undertaken while a real-time workload is running. + However, real-time workloads can use rcupdate.rcu_normal kernel + boot parameter to completely disable expedited grace periods, + though this might have performance implications. In particular, if you find yourself invoking one of the expedited primitives repeatedly in a loop, please do everyone a favor: @@ -193,11 +212,6 @@ over a rather long period of time, but improvements are always welcome! of the system, especially to real-time workloads running on the rest of the system. - In addition, it is illegal to call the expedited forms from - a CPU-hotplug notifier, or while holding a lock that is acquired - by a CPU-hotplug notifier. Failing to observe this restriction - will result in deadlock. - 7. If the updater uses call_rcu() or synchronize_rcu(), then the corresponding readers must use rcu_read_lock() and rcu_read_unlock(). If the updater uses call_rcu_bh() or @@ -321,7 +335,7 @@ over a rather long period of time, but improvements are always welcome! Similarly, disabling preemption is not an acceptable substitute for rcu_read_lock(). Code that attempts to use preemption disabling where it should be using rcu_read_lock() will break - in real-time kernel builds. + in CONFIG_PREEMPT=y kernel builds. If you want to wait for interrupt handlers, NMI handlers, and code under the influence of preempt_disable(), you instead @@ -356,23 +370,22 @@ over a rather long period of time, but improvements are always welcome! not the case, a self-spawning RCU callback would prevent the victim CPU from ever going offline.) -14. SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), - synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu()) - may only be invoked from process context. Unlike other forms of - RCU, it -is- permissible to block in an SRCU read-side critical - section (demarked by srcu_read_lock() and srcu_read_unlock()), - hence the "SRCU": "sleepable RCU". Please note that if you - don't need to sleep in read-side critical sections, you should be - using RCU rather than SRCU, because RCU is almost always faster - and easier to use than is SRCU. - - Also unlike other forms of RCU, explicit initialization - and cleanup is required via init_srcu_struct() and - cleanup_srcu_struct(). These are passed a "struct srcu_struct" - that defines the scope of a given SRCU domain. Once initialized, - the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() - synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu(). - A given synchronize_srcu() waits only for SRCU read-side critical +14. Unlike other forms of RCU, it -is- permissible to block in an + SRCU read-side critical section (demarked by srcu_read_lock() + and srcu_read_unlock()), hence the "SRCU": "sleepable RCU". + Please note that if you don't need to sleep in read-side critical + sections, you should be using RCU rather than SRCU, because RCU + is almost always faster and easier to use than is SRCU. + + Also unlike other forms of RCU, explicit initialization and + cleanup is required either at build time via DEFINE_SRCU() + or DEFINE_STATIC_SRCU() or at runtime via init_srcu_struct() + and cleanup_srcu_struct(). These last two are passed a + "struct srcu_struct" that defines the scope of a given + SRCU domain. Once initialized, the srcu_struct is passed + to srcu_read_lock(), srcu_read_unlock() synchronize_srcu(), + synchronize_srcu_expedited(), and call_srcu(). A given + synchronize_srcu() waits only for SRCU read-side critical sections governed by srcu_read_lock() and srcu_read_unlock() calls that have been passed the same srcu_struct. This property is what makes sleeping read-side critical sections tolerable -- @@ -390,10 +403,16 @@ over a rather long period of time, but improvements are always welcome! Therefore, SRCU should be used in preference to rw_semaphore only in extremely read-intensive situations, or in situations requiring SRCU's read-side deadlock immunity or low read-side - realtime latency. + realtime latency. You should also consider percpu_rw_semaphore + when you need lightweight readers. - Note that, rcu_assign_pointer() relates to SRCU just as it does - to other forms of RCU. + SRCU's expedited primitive (synchronize_srcu_expedited()) + never sends IPIs to other CPUs, so it is easier on + real-time workloads than is synchronize_rcu_expedited(), + synchronize_rcu_bh_expedited() or synchronize_sched_expedited(). + + Note that rcu_dereference() and rcu_assign_pointer() relate to + SRCU just as they do to other forms of RCU. 15. The whole point of call_rcu(), synchronize_rcu(), and friends is to wait until all pre-existing readers have finished before @@ -435,3 +454,33 @@ over a rather long period of time, but improvements are always welcome! These debugging aids can help you find problems that are otherwise extremely difficult to spot. + +18. If you register a callback using call_rcu(), call_rcu_bh(), + call_rcu_sched(), or call_srcu(), and pass in a function defined + within a loadable module, then it in necessary to wait for + all pending callbacks to be invoked after the last invocation + and before unloading that module. Note that it is absolutely + -not- sufficient to wait for a grace period! The current (say) + synchronize_rcu() implementation waits only for all previous + callbacks registered on the CPU that synchronize_rcu() is running + on, but it is -not- guaranteed to wait for callbacks registered + on other CPUs. + + You instead need to use one of the barrier functions: + + o call_rcu() -> rcu_barrier() + o call_rcu_bh() -> rcu_barrier_bh() + o call_rcu_sched() -> rcu_barrier_sched() + o call_srcu() -> srcu_barrier() + + However, these barrier functions are absolutely -not- guaranteed + to wait for a grace period. In fact, if there are no call_rcu() + callbacks waiting anywhere in the system, rcu_barrier() is within + its rights to return immediately. + + So if you need to wait for both an RCU grace period and for + all pre-existing call_rcu() callbacks, you will need to execute + both rcu_barrier() and synchronize_rcu(), if necessary, using + something like workqueues to to execute them concurrently. + + See rcubarrier.txt for more information. diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt index 745f429fda7938f499fce4388309c39bf6bfeef6..7d4ae110c2c9164e2dea06a2cf31feb66ea78656 100644 --- a/Documentation/RCU/rcu.txt +++ b/Documentation/RCU/rcu.txt @@ -76,15 +76,12 @@ o I hear that RCU is patented? What is with that? Of these, one was allowed to lapse by the assignee, and the others have been contributed to the Linux kernel under GPL. There are now also LGPL implementations of user-level RCU - available (http://lttng.org/?q=node/18). + available (http://liburcu.org/). o I hear that RCU needs work in order to support realtime kernels? - This work is largely completed. Realtime-friendly RCU can be - enabled via the CONFIG_PREEMPT_RCU kernel configuration - parameter. However, work is in progress for enabling priority - boosting of preempted RCU read-side critical sections. This is - needed if you have CPU-bound realtime threads. + Realtime-friendly RCU can be enabled via the CONFIG_PREEMPT_RCU + kernel configuration parameter. o Where can I find more information on RCU? diff --git a/Documentation/RCU/rcu_dereference.txt b/Documentation/RCU/rcu_dereference.txt index b2a613f16d747828e35fd182a0c9fe06c1107d0f..1acb26b09b48bf2877c0bd4b96a72f9d9758c045 100644 --- a/Documentation/RCU/rcu_dereference.txt +++ b/Documentation/RCU/rcu_dereference.txt @@ -25,35 +25,35 @@ o You must use one of the rcu_dereference() family of primitives for an example where the compiler can in fact deduce the exact value of the pointer, and thus cause misordering. +o You are only permitted to use rcu_dereference on pointer values. + The compiler simply knows too much about integral values to + trust it to carry dependencies through integer operations. + There are a very few exceptions, namely that you can temporarily + cast the pointer to uintptr_t in order to: + + o Set bits and clear bits down in the must-be-zero low-order + bits of that pointer. This clearly means that the pointer + must have alignment constraints, for example, this does + -not- work in general for char* pointers. + + o XOR bits to translate pointers, as is done in some + classic buddy-allocator algorithms. + + It is important to cast the value back to pointer before + doing much of anything else with it. + o Avoid cancellation when using the "+" and "-" infix arithmetic operators. For example, for a given variable "x", avoid - "(x-x)". There are similar arithmetic pitfalls from other - arithmetic operators, such as "(x*0)", "(x/(x+1))" or "(x%1)". - The compiler is within its rights to substitute zero for all of - these expressions, so that subsequent accesses no longer depend - on the rcu_dereference(), again possibly resulting in bugs due - to misordering. + "(x-(uintptr_t)x)" for char* pointers. The compiler is within its + rights to substitute zero for this sort of expression, so that + subsequent accesses no longer depend on the rcu_dereference(), + again possibly resulting in bugs due to misordering. Of course, if "p" is a pointer from rcu_dereference(), and "a" and "b" are integers that happen to be equal, the expression "p+a-b" is safe because its value still necessarily depends on the rcu_dereference(), thus maintaining proper ordering. -o Avoid all-zero operands to the bitwise "&" operator, and - similarly avoid all-ones operands to the bitwise "|" operator. - If the compiler is able to deduce the value of such operands, - it is within its rights to substitute the corresponding constant - for the bitwise operation. Once again, this causes subsequent - accesses to no longer depend on the rcu_dereference(), causing - bugs due to misordering. - - Please note that single-bit operands to bitwise "&" can also - be dangerous. At this point, the compiler knows that the - resulting value can only take on one of two possible values. - Therefore, a very small amount of additional information will - allow the compiler to deduce the exact value, which again can - result in misordering. - o If you are using RCU to protect JITed functions, so that the "()" function-invocation operator is applied to a value obtained (directly or indirectly) from rcu_dereference(), you may need to @@ -61,25 +61,6 @@ o If you are using RCU to protect JITed functions, so that the This issue arises on some systems when a newly JITed function is using the same memory that was used by an earlier JITed function. -o Do not use the results from the boolean "&&" and "||" when - dereferencing. For example, the following (rather improbable) - code is buggy: - - int *p; - int *q; - - ... - - p = rcu_dereference(gp) - q = &global_q; - q += p != &oom_p1 && p != &oom_p2; - r1 = *q; /* BUGGY!!! */ - - The reason this is buggy is that "&&" and "||" are often compiled - using branches. While weak-memory machines such as ARM or PowerPC - do order stores after such branches, they can speculate loads, - which can result in misordering bugs. - o Do not use the results from relational operators ("==", "!=", ">", ">=", "<", or "<=") when dereferencing. For example, the following (quite strange) code is buggy: diff --git a/Documentation/RCU/rcubarrier.txt b/Documentation/RCU/rcubarrier.txt index b10cfe711e68e48fe6d516ea531126dfc947fc13..5d7759071a3edbb3ef818e0d41a7081f39dc54ea 100644 --- a/Documentation/RCU/rcubarrier.txt +++ b/Documentation/RCU/rcubarrier.txt @@ -263,6 +263,11 @@ Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes are delayed for a full grace period? Couldn't this result in rcu_barrier() returning prematurely? +The current rcu_barrier() implementation is more complex, due to the need +to avoid disturbing idle CPUs (especially on battery-powered systems) +and the need to minimally disturb non-idle CPUs in real-time systems. +However, the code above illustrates the concepts. + rcu_barrier() Summary diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt index 278f6a9383b6c29c4714b97e9d51058984bd2711..55918b54808b8be6ed7d222b7e1fd678de100428 100644 --- a/Documentation/RCU/torture.txt +++ b/Documentation/RCU/torture.txt @@ -276,15 +276,17 @@ o "Free-Block Circulation": Shows the number of torture structures somehow gets incremented farther than it should. Different implementations of RCU can provide implementation-specific -additional information. For example, SRCU provides the following +additional information. For example, Tree SRCU provides the following additional line: - srcu-torture: per-CPU(idx=1): 0(0,1) 1(0,1) 2(0,0) 3(0,1) + srcud-torture: Tree SRCU per-CPU(idx=0): 0(35,-21) 1(-4,24) 2(1,1) 3(-26,20) 4(28,-47) 5(-9,4) 6(-10,14) 7(-14,11) T(1,6) -This line shows the per-CPU counter state. The numbers in parentheses are -the values of the "old" and "current" counters for the corresponding CPU. -The "idx" value maps the "old" and "current" values to the underlying -array, and is useful for debugging. +This line shows the per-CPU counter state, in this case for Tree SRCU +using a dynamically allocated srcu_struct (hence "srcud-" rather than +"srcu-"). The numbers in parentheses are the values of the "old" and +"current" counters for the corresponding CPU. The "idx" value maps the +"old" and "current" values to the underlying array, and is useful for +debugging. The final "T" entry contains the totals of the counters. USAGE @@ -304,3 +306,9 @@ checked for such errors. The "rmmod" command forces a "SUCCESS", "FAILURE", or "RCU_HOTPLUG" indication to be printk()ed. The first two are self-explanatory, while the last indicates that while there were no RCU failures, CPU-hotplug problems were detected. + +However, the tools/testing/selftests/rcutorture/bin/kvm.sh script +provides better automation, including automatic failure analysis. +It assumes a qemu/kvm-enabled platform, and runs guest OSes out of initrd. +See tools/testing/selftests/rcutorture/doc/initrd.txt for instructions +on setting up such an initrd. diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 8ed6c9f6133c45a54c442d04ed0814dc2dcd1a45..df62466da4e0692086143fdd1294e6bb69eacb5f 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -890,6 +890,8 @@ SRCU: Critical sections Grace period Barrier srcu_read_lock_held SRCU: Initialization/cleanup + DEFINE_SRCU + DEFINE_STATIC_SRCU init_srcu_struct cleanup_srcu_struct @@ -913,7 +915,8 @@ a. Will readers need to block? If so, you need SRCU. b. What about the -rt patchset? If readers would need to block in an non-rt kernel, you need SRCU. If readers would block in a -rt kernel, but not in a non-rt kernel, SRCU is not - necessary. + necessary. (The -rt patchset turns spinlocks into sleeplocks, + hence this distinction.) c. Do you need to treat NMI handlers, hardirq handlers, and code segments with preemption disabled (whether diff --git a/Documentation/admin-guide/LSM/tomoyo.rst b/Documentation/admin-guide/LSM/tomoyo.rst index a5947218fa647f4f4e2cb2b032dfec85d34ce709..e2d6b6e150825e4f0d0b643850420dae867fbe5e 100644 --- a/Documentation/admin-guide/LSM/tomoyo.rst +++ b/Documentation/admin-guide/LSM/tomoyo.rst @@ -9,8 +9,8 @@ TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel. LiveCD-based tutorials are available at -http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/ -http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/ +http://tomoyo.sourceforge.jp/1.8/ubuntu12.04-live.html +http://tomoyo.sourceforge.jp/1.8/centos6-live.html Though these tutorials use non-LSM version of TOMOYO, they are useful for you to know what TOMOYO is. @@ -21,35 +21,35 @@ How to enable TOMOYO? Build the kernel with ``CONFIG_SECURITY_TOMOYO=y`` and pass ``security=tomoyo`` on kernel's command line. -Please see http://tomoyo.sourceforge.jp/2.3/ for details. +Please see http://tomoyo.osdn.jp/2.5/ for details. Where is documentation? ======================= User <-> Kernel interface documentation is available at -http://tomoyo.sourceforge.jp/2.3/policy-reference.html . +http://tomoyo.osdn.jp/2.5/policy-specification/index.html . Materials we prepared for seminars and symposiums are available at -http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 . +http://osdn.jp/projects/tomoyo/docs/?category_id=532&language_id=1 . Below lists are chosen from three aspects. What is TOMOYO? TOMOYO Linux Overview - http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf + http://osdn.jp/projects/tomoyo/docs/lca2009-takeda.pdf TOMOYO Linux: pragmatic and manageable security for Linux - http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf + http://osdn.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box - http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf + http://osdn.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf What can TOMOYO do? Deep inside TOMOYO Linux - http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf + http://osdn.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf The role of "pathname based access control" in security. - http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf + http://osdn.jp/projects/tomoyo/docs/lfj2008-bof.pdf History of TOMOYO? Realities of Mainlining - http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf + http://osdn.jp/projects/tomoyo/docs/lfj2008.pdf What is future plan? ==================== @@ -60,6 +60,6 @@ multiple LSM modules at the same time. We feel sorry that you have to give up SELinux/SMACK/AppArmor etc. when you want to use TOMOYO. We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM -version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ . +version of TOMOYO, available at http://tomoyo.osdn.jp/1.8/ . LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning to port non-LSM version's functionalities to LSM versions. diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 6b71852dadc277c638310beb63d89064024e7d5b..4ec843123cc3bd1f206aa8b2315b3acad11b1a88 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -3081,3 +3081,8 @@ 1 = /dev/osd1 Second OSD Device ... 255 = /dev/osd255 256th OSD Device + + 384-511 char RESERVED FOR DYNAMIC ASSIGNMENT + Character devices that request a dynamic allocation of major + number will take numbers starting from 511 and downward, + once the 234-254 range is full. diff --git a/Documentation/admin-guide/kernel-parameters.rst b/Documentation/admin-guide/kernel-parameters.rst index d76ab3907e2bd3b07cba39de90434f6e0490d0e7..b2598cc9834c3cbacfd9b3b1d885ed69c4c4c133 100644 --- a/Documentation/admin-guide/kernel-parameters.rst +++ b/Documentation/admin-guide/kernel-parameters.rst @@ -138,6 +138,7 @@ parameter is applicable:: PPT Parallel port support is enabled. PS2 Appropriate PS/2 support is enabled. RAM RAM disk support is enabled. + RDT Intel Resource Director Technology. S390 S390 architecture is enabled. SCSI Appropriate SCSI support is enabled. A lot of drivers have their options described inside diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index d9c171ce4190845950e7c14e362265b4d26adc74..05496622b4effb8212eb2175bea67f9a7bebe0d0 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2233,6 +2233,17 @@ memory contents and reserves bad memory regions that are detected. + mem_encrypt= [X86-64] AMD Secure Memory Encryption (SME) control + Valid arguments: on, off + Default (depends on kernel configuration option): + on (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) + off (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=n) + mem_encrypt=on: Activate SME + mem_encrypt=off: Do not activate SME + + Refer to Documentation/x86/amd-memory-encryption.txt + for details on when memory encryption can be activated. + mem_sleep_default= [SUSPEND] Default system suspend mode: s2idle - Suspend-To-Idle shallow - Power-On Suspend or equivalent (if supported) @@ -2633,9 +2644,10 @@ In kernels built with CONFIG_NO_HZ_FULL=y, set the specified list of CPUs whose tick will be stopped whenever possible. The boot CPU will be forced outside - the range to maintain the timekeeping. - The CPUs in this range must also be included in the - rcu_nocbs= set. + the range to maintain the timekeeping. Any CPUs + in this list will have their RCU callbacks offloaded, + just as if they had also been called out in the + rcu_nocbs= boot parameter. noiotrap [SH] Disables trapped I/O port accesses. @@ -2696,6 +2708,8 @@ nopat [X86] Disable PAT (page attribute table extension of pagetables) support. + nopcid [X86-64] Disable the PCID cpu feature. + norandmaps Don't use address space randomization. Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space @@ -2750,6 +2764,15 @@ If the dependencies are under your control, you can turn on cpu0_hotplug. + nps_mtm_hs_ctr= [KNL,ARC] + This parameter sets the maximum duration, in + cycles, each HW thread of the CTOP can run + without interruptions, before HW switches it. + The actual maximum duration is 16 times this + parameter's value. + Format: integer between 1 and 255 + Default: 255 + nptcg= [IA-64] Override max number of concurrent global TLB purges which is reported from either PAL_VM_SUMMARY or SAL PALO. @@ -2769,7 +2792,7 @@ Allowed values are enable and disable numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA. - one of ['zone', 'node', 'default'] can be specified + 'node', 'default' can be specified This can be set from sysctl after boot. See Documentation/sysctl/vm.txt for details. @@ -3598,6 +3621,12 @@ Run specified binary instead of /init from the ramdisk, used for early userspace startup. See initrd. + rdt= [HW,X86,RDT] + Turn on/off individual RDT features. List is: + cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, mba. + E.g. to turn on cmt and turn off mba use: + rdt=cmt,!mba + reboot= [KNL] Format (x86 or x86_64): [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \ @@ -4375,6 +4404,10 @@ decrease the size and leave more room for directly mapped kernel RAM. + vmcp_cma=nn[MG] [KNL,S390] + Sets the memory size reserved for contiguous memory + allocations for the vmcp device driver. + vmhalt= [KNL,S390] Perform z/VM CP command after system halt. Format: diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst index 463cf7e73db80b3bf3f8a36afe91bcf3d7f0d429..47153e64dfb530465ca01d28272e058293eb08b5 100644 --- a/Documentation/admin-guide/pm/cpufreq.rst +++ b/Documentation/admin-guide/pm/cpufreq.rst @@ -237,6 +237,14 @@ are the following: This attribute is not present if the scaling driver in use does not support it. +``cpuinfo_cur_freq`` + Current frequency of the CPUs belonging to this policy as obtained from + the hardware (in KHz). + + This is expected to be the frequency the hardware actually runs at. + If that frequency cannot be determined, this attribute should not + be present. + ``cpuinfo_max_freq`` Maximum possible operating frequency the CPUs belonging to this policy can run at (in kHz). @@ -471,14 +479,6 @@ This governor exposes the following tunables: # echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) > ondemand/sampling_rate - -``min_sampling_rate`` - The minimum value of ``sampling_rate``. - - Equal to 10000 (10 ms) if :c:macro:`CONFIG_NO_HZ_COMMON` and - :c:data:`tick_nohz_active` are both set or to 20 times the value of - :c:data:`jiffies` in microseconds otherwise. - ``up_threshold`` If the estimated CPU load is above this value (in percent), the governor will set the frequency to the maximum value allowed for the policy. diff --git a/Documentation/admin-guide/pm/index.rst b/Documentation/admin-guide/pm/index.rst index 7f148f76f432cbfc62ed663a6be7b9849b66b3c6..49237ac734428b63951837ad40fd110f3b346dfb 100644 --- a/Documentation/admin-guide/pm/index.rst +++ b/Documentation/admin-guide/pm/index.rst @@ -5,12 +5,6 @@ Power Management .. toctree:: :maxdepth: 2 - cpufreq - intel_pstate - -.. only:: subproject and html - - Indices - ======= - - * :ref:`genindex` + strategies + system-wide + working-state diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst index 1d6249825efc81947955c4b677b7e8e2607ee5aa..d2b6fda3d67b97eeeb44c0c045eb3e5963f9233f 100644 --- a/Documentation/admin-guide/pm/intel_pstate.rst +++ b/Documentation/admin-guide/pm/intel_pstate.rst @@ -167,35 +167,17 @@ is set. ``powersave`` ............. -Without HWP, this P-state selection algorithm generally depends on the -processor model and/or the system profile setting in the ACPI tables and there -are two variants of it. - -One of them is used with processors from the Atom line and (regardless of the -processor model) on platforms with the system profile in the ACPI tables set to -"mobile" (laptops mostly), "tablet", "appliance PC", "desktop", or -"workstation". It is also used with processors supporting the HWP feature if -that feature has not been enabled (that is, with the ``intel_pstate=no_hwp`` -argument in the kernel command line). It is similar to the algorithm +Without HWP, this P-state selection algorithm is similar to the algorithm implemented by the generic ``schedutil`` scaling governor except that the utilization metric used by it is based on numbers coming from feedback registers of the CPU. It generally selects P-states proportional to the -current CPU utilization, so it is referred to as the "proportional" algorithm. - -The second variant of the ``powersave`` P-state selection algorithm, used in all -of the other cases (generally, on processors from the Core line, so it is -referred to as the "Core" algorithm), is based on the values read from the APERF -and MPERF feedback registers and the previously requested target P-state. -It does not really take CPU utilization into account explicitly, but as a rule -it causes the CPU P-state to ramp up very quickly in response to increased -utilization which is generally desirable in server environments. - -Regardless of the variant, this algorithm is run by the driver's utilization -update callback for the given CPU when it is invoked by the CPU scheduler, but -not more often than every 10 ms (that can be tweaked via ``debugfs`` in `this -particular case `_). Like in the ``performance`` -case, the hardware configuration is not touched if the new P-state turns out to -be the same as the current one. +current CPU utilization. + +This algorithm is run by the driver's utilization update callback for the +given CPU when it is invoked by the CPU scheduler, but not more often than +every 10 ms. Like in the ``performance`` case, the hardware configuration +is not touched if the new P-state turns out to be the same as the current +one. This is the default P-state selection algorithm if the :c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option @@ -720,34 +702,7 @@ P-state is called, the ``ftrace`` filter can be set to to gnome-shell-3409 [001] ..s. 2537.650850: intel_pstate_set_pstate <-intel_pstate_timer_func -0 [000] ..s. 2537.654843: intel_pstate_set_pstate <-intel_pstate_timer_func -Tuning Interface in ``debugfs`` -------------------------------- - -The ``powersave`` algorithm provided by ``intel_pstate`` for `the Core line of -processors in the active mode `_ is based on a `PID controller`_ -whose parameters were chosen to address a number of different use cases at the -same time. However, it still is possible to fine-tune it to a specific workload -and the ``debugfs`` interface under ``/sys/kernel/debug/pstate_snb/`` is -provided for this purpose. [Note that the ``pstate_snb`` directory will be -present only if the specific P-state selection algorithm matching the interface -in it actually is in use.] - -The following files present in that directory can be used to modify the PID -controller parameters at run time: - -| ``deadband`` -| ``d_gain_pct`` -| ``i_gain_pct`` -| ``p_gain_pct`` -| ``sample_rate_ms`` -| ``setpoint`` - -Note, however, that achieving desirable results this way generally requires -expert-level understanding of the power vs performance tradeoff, so extra care -is recommended when attempting to do that. - .. _LCEU2015: http://events.linuxfoundation.org/sites/events/files/slides/LinuxConEurope_2015.pdf .. _SDM: http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-system-programming-manual-325384.html .. _ACPI specification: http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf -.. _PID controller: https://en.wikipedia.org/wiki/PID_controller diff --git a/Documentation/admin-guide/pm/sleep-states.rst b/Documentation/admin-guide/pm/sleep-states.rst new file mode 100644 index 0000000000000000000000000000000000000000..1e5c0f00cb2fee319032ea0b27e93a03eef8aee6 --- /dev/null +++ b/Documentation/admin-guide/pm/sleep-states.rst @@ -0,0 +1,245 @@ +=================== +System Sleep States +=================== + +:: + + Copyright (c) 2017 Intel Corp., Rafael J. Wysocki + +Sleep states are global low-power states of the entire system in which user +space code cannot be executed and the overall system activity is significantly +reduced. + + +Sleep States That Can Be Supported +================================== + +Depending on its configuration and the capabilities of the platform it runs on, +the Linux kernel can support up to four system sleep states, includig +hibernation and up to three variants of system suspend. The sleep states that +can be supported by the kernel are listed below. + +.. _s2idle: + +Suspend-to-Idle +--------------- + +This is a generic, pure software, light-weight variant of system suspend (also +referred to as S2I or S2Idle). It allows more energy to be saved relative to +runtime idle by freezing user space, suspending the timekeeping and putting all +I/O devices into low-power states (possibly lower-power than available in the +working state), such that the processors can spend time in their deepest idle +states while the system is suspended. + +The system is woken up from this state by in-band interrupts, so theoretically +any devices that can cause interrupts to be generated in the working state can +also be set up as wakeup devices for S2Idle. + +This state can be used on platforms without support for :ref:`standby ` +or :ref:`suspend-to-RAM `, or it can be used in addition to any of the +deeper system suspend variants to provide reduced resume latency. It is always +supported if the :c:macro:`CONFIG_SUSPEND` kernel configuration option is set. + +.. _standby: + +Standby +------- + +This state, if supported, offers moderate, but real, energy savings, while +providing a relatively straightforward transition back to the working state. No +operating state is lost (the system core logic retains power), so the system can +go back to where it left off easily enough. + +In addition to freezing user space, suspending the timekeeping and putting all +I/O devices into low-power states, which is done for :ref:`suspend-to-idle +` too, nonboot CPUs are taken offline and all low-level system functions +are suspended during transitions into this state. For this reason, it should +allow more energy to be saved relative to :ref:`suspend-to-idle `, but +the resume latency will generally be greater than for that state. + +The set of devices that can wake up the system from this state usually is +reduced relative to :ref:`suspend-to-idle ` and it may be necessary to +rely on the platform for setting up the wakeup functionality as appropriate. + +This state is supported if the :c:macro:`CONFIG_SUSPEND` kernel configuration +option is set and the support for it is registered by the platform with the +core system suspend subsystem. On ACPI-based systems this state is mapped to +the S1 system state defined by ACPI. + +.. _s2ram: + +Suspend-to-RAM +-------------- + +This state (also referred to as STR or S2RAM), if supported, offers significant +energy savings as everything in the system is put into a low-power state, except +for memory, which should be placed into the self-refresh mode to retain its +contents. All of the steps carried out when entering :ref:`standby ` +are also carried out during transitions to S2RAM. Additional operations may +take place depending on the platform capabilities. In particular, on ACPI-based +systems the kernel passes control to the platform firmware (BIOS) as the last +step during S2RAM transitions and that usually results in powering down some +more low-level components that are not directly controlled by the kernel. + +The state of devices and CPUs is saved and held in memory. All devices are +suspended and put into low-power states. In many cases, all peripheral buses +lose power when entering S2RAM, so devices must be able to handle the transition +back to the "on" state. + +On ACPI-based systems S2RAM requires some minimal boot-strapping code in the +platform firmware to resume the system from it. This may be the case on other +platforms too. + +The set of devices that can wake up the system from S2RAM usually is reduced +relative to :ref:`suspend-to-idle ` and :ref:`standby ` and it +may be necessary to rely on the platform for setting up the wakeup functionality +as appropriate. + +S2RAM is supported if the :c:macro:`CONFIG_SUSPEND` kernel configuration option +is set and the support for it is registered by the platform with the core system +suspend subsystem. On ACPI-based systems it is mapped to the S3 system state +defined by ACPI. + +.. _hibernation: + +Hibernation +----------- + +This state (also referred to as Suspend-to-Disk or STD) offers the greatest +energy savings and can be used even in the absence of low-level platform support +for system suspend. However, it requires some low-level code for resuming the +system to be present for the underlying CPU architecture. + +Hibernation is significantly different from any of the system suspend variants. +It takes three system state changes to put it into hibernation and two system +state changes to resume it. + +First, when hibernation is triggered, the kernel stops all system activity and +creates a snapshot image of memory to be written into persistent storage. Next, +the system goes into a state in which the snapshot image can be saved, the image +is written out and finally the system goes into the target low-power state in +which power is cut from almost all of its hardware components, including memory, +except for a limited set of wakeup devices. + +Once the snapshot image has been written out, the system may either enter a +special low-power state (like ACPI S4), or it may simply power down itself. +Powering down means minimum power draw and it allows this mechanism to work on +any system. However, entering a special low-power state may allow additional +means of system wakeup to be used (e.g. pressing a key on the keyboard or +opening a laptop lid). + +After wakeup, control goes to the platform firmware that runs a boot loader +which boots a fresh instance of the kernel (control may also go directly to +the boot loader, depending on the system configuration, but anyway it causes +a fresh instance of the kernel to be booted). That new instance of the kernel +(referred to as the ``restore kernel``) looks for a hibernation image in +persistent storage and if one is found, it is loaded into memory. Next, all +activity in the system is stopped and the restore kernel overwrites itself with +the image contents and jumps into a special trampoline area in the original +kernel stored in the image (referred to as the ``image kernel``), which is where +the special architecture-specific low-level code is needed. Finally, the +image kernel restores the system to the pre-hibernation state and allows user +space to run again. + +Hibernation is supported if the :c:macro:`CONFIG_HIBERNATION` kernel +configuration option is set. However, this option can only be set if support +for the given CPU architecture includes the low-level code for system resume. + + +Basic ``sysfs`` Interfaces for System Suspend and Hibernation +============================================================= + +The following files located in the :file:`/sys/power/` directory can be used by +user space for sleep states control. + +``state`` + This file contains a list of strings representing sleep states supported + by the kernel. Writing one of these strings into it causes the kernel + to start a transition of the system into the sleep state represented by + that string. + + In particular, the strings "disk", "freeze" and "standby" represent the + :ref:`hibernation `, :ref:`suspend-to-idle ` and + :ref:`standby ` sleep states, respectively. The string "mem" + is interpreted in accordance with the contents of the ``mem_sleep`` file + described below. + + If the kernel does not support any system sleep states, this file is + not present. + +``mem_sleep`` + This file contains a list of strings representing supported system + suspend variants and allows user space to select the variant to be + associated with the "mem" string in the ``state`` file described above. + + The strings that may be present in this file are "s2idle", "shallow" + and "deep". The string "s2idle" always represents :ref:`suspend-to-idle + ` and, by convention, "shallow" and "deep" represent + :ref:`standby ` and :ref:`suspend-to-RAM `, + respectively. + + Writing one of the listed strings into this file causes the system + suspend variant represented by it to be associated with the "mem" string + in the ``state`` file. The string representing the suspend variant + currently associated with the "mem" string in the ``state`` file + is listed in square brackets. + + If the kernel does not support system suspend, this file is not present. + +``disk`` + This file contains a list of strings representing different operations + that can be carried out after the hibernation image has been saved. The + possible options are as follows: + + ``platform`` + Put the system into a special low-power state (e.g. ACPI S4) to + make additional wakeup options available and possibly allow the + platform firmware to take a simplified initialization path after + wakeup. + + ``shutdown`` + Power off the system. + + ``reboot`` + Reboot the system (useful for diagnostics mostly). + + ``suspend`` + Hybrid system suspend. Put the system into the suspend sleep + state selected through the ``mem_sleep`` file described above. + If the system is successfully woken up from that state, discard + the hibernation image and continue. Otherwise, use the image + to restore the previous state of the system. + + ``test_resume`` + Diagnostic operation. Load the image as though the system had + just woken up from hibernation and the currently running kernel + instance was a restore kernel and follow up with full system + resume. + + Writing one of the listed strings into this file causes the option + represented by it to be selected. + + The currently selected option is shown in square brackets which means + that the operation represented by it will be carried out after creating + and saving the image next time hibernation is triggered by writing + ``disk`` to :file:`/sys/power/state`. + + If the kernel does not support hibernation, this file is not present. + +According to the above, there are two ways to make the system go into the +:ref:`suspend-to-idle ` state. The first one is to write "freeze" +directly to :file:`/sys/power/state`. The second one is to write "s2idle" to +:file:`/sys/power/mem_sleep` and then to write "mem" to +:file:`/sys/power/state`. Likewise, there are two ways to make the system go +into the :ref:`standby ` state (the strings to write to the control +files in that case are "standby" or "shallow" and "mem", respectively) if that +state is supported by the platform. However, there is only one way to make the +system go into the :ref:`suspend-to-RAM ` state (write "deep" into +:file:`/sys/power/mem_sleep` and "mem" into :file:`/sys/power/state`). + +The default suspend variant (ie. the one to be used without writing anything +into :file:`/sys/power/mem_sleep`) is either "deep" (on the majority of systems +supporting :ref:`suspend-to-RAM `) or "s2idle", but it can be overridden +by the value of the "mem_sleep_default" parameter in the kernel command line. +On some ACPI-based systems, depending on the information in the ACPI tables, the +default may be "s2idle" even if :ref:`suspend-to-RAM ` is supported. diff --git a/Documentation/admin-guide/pm/strategies.rst b/Documentation/admin-guide/pm/strategies.rst new file mode 100644 index 0000000000000000000000000000000000000000..afe4d3f831fe06fb7e04989cf317f1d5caaaebd8 --- /dev/null +++ b/Documentation/admin-guide/pm/strategies.rst @@ -0,0 +1,52 @@ +=========================== +Power Management Strategies +=========================== + +:: + + Copyright (c) 2017 Intel Corp., Rafael J. Wysocki + +The Linux kernel supports two major high-level power management strategies. + +One of them is based on using global low-power states of the whole system in +which user space code cannot be executed and the overall system activity is +significantly reduced, referred to as :doc:`sleep states `. The +kernel puts the system into one of these states when requested by user space +and the system stays in it until a special signal is received from one of +designated devices, triggering a transition to the ``working state`` in which +user space code can run. Because sleep states are global and the whole system +is affected by the state changes, this strategy is referred to as the +:doc:`system-wide power management `. + +The other strategy, referred to as the :doc:`working-state power management +`, is based on adjusting the power states of individual hardware +components of the system, as needed, in the working state. In consequence, if +this strategy is in use, the working state of the system usually does not +correspond to any particular physical configuration of it, but can be treated as +a metastate covering a range of different power states of the system in which +the individual components of it can be either ``active`` (in use) or +``inactive`` (idle). If they are active, they have to be in power states +allowing them to process data and to be accessed by software. In turn, if they +are inactive, ideally, they should be in low-power states in which they may not +be accessible. + +If all of the system components are active, the system as a whole is regarded as +"runtime active" and that situation typically corresponds to the maximum power +draw (or maximum energy usage) of it. If all of them are inactive, the system +as a whole is regarded as "runtime idle" which may be very close to a sleep +state from the physical system configuration and power draw perspective, but +then it takes much less time and effort to start executing user space code than +for the same system in a sleep state. However, transitions from sleep states +back to the working state can only be started by a limited set of devices, so +typically the system can spend much more time in a sleep state than it can be +runtime idle in one go. For this reason, systems usually use less energy in +sleep states than when they are runtime idle most of the time. + +Moreover, the two power management strategies address different usage scenarios. +Namely, if the user indicates that the system will not be in use going forward, +for example by closing its lid (if the system is a laptop), it probably should +go into a sleep state at that point. On the other hand, if the user simply goes +away from the laptop keyboard, it probably should stay in the working state and +use the working-state power management in case it becomes idle, because the user +may come back to it at any time and then may want the system to be immediately +accessible. diff --git a/Documentation/admin-guide/pm/system-wide.rst b/Documentation/admin-guide/pm/system-wide.rst new file mode 100644 index 0000000000000000000000000000000000000000..0c81e4c5de398db435e85d486cd821bebea65a33 --- /dev/null +++ b/Documentation/admin-guide/pm/system-wide.rst @@ -0,0 +1,8 @@ +============================ +System-Wide Power Management +============================ + +.. toctree:: + :maxdepth: 2 + + sleep-states diff --git a/Documentation/admin-guide/pm/working-state.rst b/Documentation/admin-guide/pm/working-state.rst new file mode 100644 index 0000000000000000000000000000000000000000..fa01bf083dfe67877b43bfa3a94e2f7b78d48cec --- /dev/null +++ b/Documentation/admin-guide/pm/working-state.rst @@ -0,0 +1,9 @@ +============================== +Working-State Power Management +============================== + +.. toctree:: + :maxdepth: 2 + + cpufreq + intel_pstate diff --git a/Documentation/arm/firmware.txt b/Documentation/arm/firmware.txt index da6713adac8acffc5924d447473351ab84c2d289..7f175dbb427e631acafdb7b72d07023c3eb8e540 100644 --- a/Documentation/arm/firmware.txt +++ b/Documentation/arm/firmware.txt @@ -60,7 +60,7 @@ Example of using a firmware operation: /* some platform code, e.g. SMP initialization */ - __raw_writel(virt_to_phys(exynos4_secondary_startup), + __raw_writel(__pa_symbol(exynos4_secondary_startup), CPU1_BOOT_REG); /* Call Exynos specific smc call */ diff --git a/Documentation/arm64/cpu-feature-registers.txt b/Documentation/arm64/cpu-feature-registers.txt index d1c97f9f51cc3bd3fd21ad181253bb354e7771b1..dad411d635d88c09c6965f506e9ff27b5cfbc38b 100644 --- a/Documentation/arm64/cpu-feature-registers.txt +++ b/Documentation/arm64/cpu-feature-registers.txt @@ -179,6 +179,8 @@ infrastructure: | FCMA | [19-16] | y | |--------------------------------------------------| | JSCVT | [15-12] | y | + |--------------------------------------------------| + | DPB | [3-0] | y | x--------------------------------------------------x Appendix I: Example diff --git a/Documentation/atomic_bitops.txt b/Documentation/atomic_bitops.txt new file mode 100644 index 0000000000000000000000000000000000000000..5550bfdcce5f1cfaab57728f4c272e9e84902860 --- /dev/null +++ b/Documentation/atomic_bitops.txt @@ -0,0 +1,66 @@ + +On atomic bitops. + + +While our bitmap_{}() functions are non-atomic, we have a number of operations +operating on single bits in a bitmap that are atomic. + + +API +--- + +The single bit operations are: + +Non-RMW ops: + + test_bit() + +RMW atomic operations without return value: + + {set,clear,change}_bit() + clear_bit_unlock() + +RMW atomic operations with return value: + + test_and_{set,clear,change}_bit() + test_and_set_bit_lock() + +Barriers: + + smp_mb__{before,after}_atomic() + + +All RMW atomic operations have a '__' prefixed variant which is non-atomic. + + +SEMANTICS +--------- + +Non-atomic ops: + +In particular __clear_bit_unlock() suffers the same issue as atomic_set(), +which is why the generic version maps to clear_bit_unlock(), see atomic_t.txt. + + +RMW ops: + +The test_and_{}_bit() operations return the original value of the bit. + + +ORDERING +-------- + +Like with atomic_t, the rule of thumb is: + + - non-RMW operations are unordered; + + - RMW operations that have no return value are unordered; + + - RMW operations that have a return value are fully ordered. + +Except for test_and_set_bit_lock() which has ACQUIRE semantics and +clear_bit_unlock() which has RELEASE semantics. + +Since a platform only has a single means of achieving atomic operations +the same barriers as for atomic_t are used, see atomic_t.txt. + diff --git a/Documentation/atomic_t.txt b/Documentation/atomic_t.txt new file mode 100644 index 0000000000000000000000000000000000000000..913396ac582431cb3acbdc96a1bd7f4293661d0b --- /dev/null +++ b/Documentation/atomic_t.txt @@ -0,0 +1,242 @@ + +On atomic types (atomic_t atomic64_t and atomic_long_t). + +The atomic type provides an interface to the architecture's means of atomic +RMW operations between CPUs (atomic operations on MMIO are not supported and +can lead to fatal traps on some platforms). + +API +--- + +The 'full' API consists of (atomic64_ and atomic_long_ prefixes omitted for +brevity): + +Non-RMW ops: + + atomic_read(), atomic_set() + atomic_read_acquire(), atomic_set_release() + + +RMW atomic operations: + +Arithmetic: + + atomic_{add,sub,inc,dec}() + atomic_{add,sub,inc,dec}_return{,_relaxed,_acquire,_release}() + atomic_fetch_{add,sub,inc,dec}{,_relaxed,_acquire,_release}() + + +Bitwise: + + atomic_{and,or,xor,andnot}() + atomic_fetch_{and,or,xor,andnot}{,_relaxed,_acquire,_release}() + + +Swap: + + atomic_xchg{,_relaxed,_acquire,_release}() + atomic_cmpxchg{,_relaxed,_acquire,_release}() + atomic_try_cmpxchg{,_relaxed,_acquire,_release}() + + +Reference count (but please see refcount_t): + + atomic_add_unless(), atomic_inc_not_zero() + atomic_sub_and_test(), atomic_dec_and_test() + + +Misc: + + atomic_inc_and_test(), atomic_add_negative() + atomic_dec_unless_positive(), atomic_inc_unless_negative() + + +Barriers: + + smp_mb__{before,after}_atomic() + + + +SEMANTICS +--------- + +Non-RMW ops: + +The non-RMW ops are (typically) regular LOADs and STOREs and are canonically +implemented using READ_ONCE(), WRITE_ONCE(), smp_load_acquire() and +smp_store_release() respectively. + +The one detail to this is that atomic_set{}() should be observable to the RMW +ops. That is: + + C atomic-set + + { + atomic_set(v, 1); + } + + P1(atomic_t *v) + { + atomic_add_unless(v, 1, 0); + } + + P2(atomic_t *v) + { + atomic_set(v, 0); + } + + exists + (v=2) + +In this case we would expect the atomic_set() from CPU1 to either happen +before the atomic_add_unless(), in which case that latter one would no-op, or +_after_ in which case we'd overwrite its result. In no case is "2" a valid +outcome. + +This is typically true on 'normal' platforms, where a regular competing STORE +will invalidate a LL/SC or fail a CMPXCHG. + +The obvious case where this is not so is when we need to implement atomic ops +with a lock: + + CPU0 CPU1 + + atomic_add_unless(v, 1, 0); + lock(); + ret = READ_ONCE(v->counter); // == 1 + atomic_set(v, 0); + if (ret != u) WRITE_ONCE(v->counter, 0); + WRITE_ONCE(v->counter, ret + 1); + unlock(); + +the typical solution is to then implement atomic_set{}() with atomic_xchg(). + + +RMW ops: + +These come in various forms: + + - plain operations without return value: atomic_{}() + + - operations which return the modified value: atomic_{}_return() + + these are limited to the arithmetic operations because those are + reversible. Bitops are irreversible and therefore the modified value + is of dubious utility. + + - operations which return the original value: atomic_fetch_{}() + + - swap operations: xchg(), cmpxchg() and try_cmpxchg() + + - misc; the special purpose operations that are commonly used and would, + given the interface, normally be implemented using (try_)cmpxchg loops but + are time critical and can, (typically) on LL/SC architectures, be more + efficiently implemented. + +All these operations are SMP atomic; that is, the operations (for a single +atomic variable) can be fully ordered and no intermediate state is lost or +visible. + + +ORDERING (go read memory-barriers.txt first) +-------- + +The rule of thumb: + + - non-RMW operations are unordered; + + - RMW operations that have no return value are unordered; + + - RMW operations that have a return value are fully ordered; + + - RMW operations that are conditional are unordered on FAILURE, + otherwise the above rules apply. + +Except of course when an operation has an explicit ordering like: + + {}_relaxed: unordered + {}_acquire: the R of the RMW (or atomic_read) is an ACQUIRE + {}_release: the W of the RMW (or atomic_set) is a RELEASE + +Where 'unordered' is against other memory locations. Address dependencies are +not defeated. + +Fully ordered primitives are ordered against everything prior and everything +subsequent. Therefore a fully ordered primitive is like having an smp_mb() +before and an smp_mb() after the primitive. + + +The barriers: + + smp_mb__{before,after}_atomic() + +only apply to the RMW ops and can be used to augment/upgrade the ordering +inherent to the used atomic op. These barriers provide a full smp_mb(). + +These helper barriers exist because architectures have varying implicit +ordering on their SMP atomic primitives. For example our TSO architectures +provide full ordered atomics and these barriers are no-ops. + +Thus: + + atomic_fetch_add(); + +is equivalent to: + + smp_mb__before_atomic(); + atomic_fetch_add_relaxed(); + smp_mb__after_atomic(); + +However the atomic_fetch_add() might be implemented more efficiently. + +Further, while something like: + + smp_mb__before_atomic(); + atomic_dec(&X); + +is a 'typical' RELEASE pattern, the barrier is strictly stronger than +a RELEASE. Similarly for something like: + + atomic_inc(&X); + smp_mb__after_atomic(); + +is an ACQUIRE pattern (though very much not typical), but again the barrier is +strictly stronger than ACQUIRE. As illustrated: + + C strong-acquire + + { + } + + P1(int *x, atomic_t *y) + { + r0 = READ_ONCE(*x); + smp_rmb(); + r1 = atomic_read(y); + } + + P2(int *x, atomic_t *y) + { + atomic_inc(y); + smp_mb__after_atomic(); + WRITE_ONCE(*x, 1); + } + + exists + (r0=1 /\ r1=0) + +This should not happen; but a hypothetical atomic_inc_acquire() -- +(void)atomic_fetch_inc_acquire() for instance -- would allow the outcome, +since then: + + P1 P2 + + t = LL.acq *y (0) + t++; + *x = 1; + r0 = *x (1) + RMB + r1 = *y (0) + SC *y, t; + +is allowed. diff --git a/Documentation/block/bfq-iosched.txt b/Documentation/block/bfq-iosched.txt index 05e2822a80b34d0f31649cfb486ade2b4679f9e8..3d6951d63489563e60f4da62eabd8e49608479f8 100644 --- a/Documentation/block/bfq-iosched.txt +++ b/Documentation/block/bfq-iosched.txt @@ -16,14 +16,16 @@ throughput. So, when needed for achieving a lower latency, BFQ builds schedules that may lead to a lower throughput. If your main or only goal, for a given device, is to achieve the maximum-possible throughput at all times, then do switch off all low-latency heuristics -for that device, by setting low_latency to 0. Full details in Section 3. +for that device, by setting low_latency to 0. See Section 3 for +details on how to configure BFQ for the desired tradeoff between +latency and throughput, or on how to maximize throughput. On average CPUs, the current version of BFQ can handle devices performing at most ~30K IOPS; at most ~50 KIOPS on faster CPUs. As a reference, 30-50 KIOPS correspond to very high bandwidths with sequential I/O (e.g., 8-12 GB/s if I/O requests are 256 KB large), and -to 120-200 MB/s with 4KB random I/O. BFQ has not yet been tested on -multi-queue devices. +to 120-200 MB/s with 4KB random I/O. BFQ is currently being tested on +multi-queue devices too. The table of contents follow. Impatients can just jump to Section 3. @@ -33,7 +35,7 @@ CONTENTS 1-1 Personal systems 1-2 Server systems 2. How does BFQ work? -3. What are BFQ's tunable? +3. What are BFQ's tunables and how to properly configure BFQ? 4. BFQ group scheduling 4-1 Service guarantees provided 4-2 Interface @@ -145,19 +147,28 @@ plus a lot of code, are borrowed from CFQ. contrast, BFQ may idle the device for a short time interval, giving the process the chance to go on being served if it issues a new request in time. Device idling typically boosts the - throughput on rotational devices, if processes do synchronous - and sequential I/O. In addition, under BFQ, device idling is - also instrumental in guaranteeing the desired throughput - fraction to processes issuing sync requests (see the description - of the slice_idle tunable in this document, or [1, 2], for more - details). + throughput on rotational devices and on non-queueing flash-based + devices, if processes do synchronous and sequential I/O. In + addition, under BFQ, device idling is also instrumental in + guaranteeing the desired throughput fraction to processes + issuing sync requests (see the description of the slice_idle + tunable in this document, or [1, 2], for more details). - With respect to idling for service guarantees, if several processes are competing for the device at the same time, but - all processes (and groups, after the following commit) have - the same weight, then BFQ guarantees the expected throughput - distribution without ever idling the device. Throughput is - thus as high as possible in this common scenario. + all processes and groups have the same weight, then BFQ + guarantees the expected throughput distribution without ever + idling the device. Throughput is thus as high as possible in + this common scenario. + + - On flash-based storage with internal queueing of commands + (typically NCQ), device idling happens to be always detrimental + for throughput. So, with these devices, BFQ performs idling + only when strictly needed for service guarantees, i.e., for + guaranteeing low latency or fairness. In these cases, overall + throughput may be sub-optimal. No solution currently exists to + provide both strong service guarantees and optimal throughput + on devices with internal queueing. - If low-latency mode is enabled (default configuration), BFQ executes some special heuristics to detect interactive and soft @@ -191,10 +202,7 @@ plus a lot of code, are borrowed from CFQ. - Queues are scheduled according to a variant of WF2Q+, named B-WF2Q+, and implemented using an augmented rb-tree to preserve an O(log N) overall complexity. See [2] for more details. B-WF2Q+ is - also ready for hierarchical scheduling. However, for a cleaner - logical breakdown, the code that enables and completes - hierarchical support is provided in the next commit, which focuses - exactly on this feature. + also ready for hierarchical scheduling, details in Section 4. - B-WF2Q+ guarantees a tight deviation with respect to an ideal, perfectly fair, and smooth service. In particular, B-WF2Q+ @@ -249,13 +257,24 @@ plus a lot of code, are borrowed from CFQ. the Idle class, to prevent it from starving. -3. What are BFQ's tunable? -========================== +3. What are BFQ's tunables and how to properly configure BFQ? +============================================================= + +Most BFQ tunables affect service guarantees (basically latency and +fairness) and throughput. For full details on how to choose the +desired tradeoff between service guarantees and throughput, see the +parameters slice_idle, strict_guarantees and low_latency. For details +on how to maximise throughput, see slice_idle, timeout_sync and +max_budget. The other performance-related parameters have been +inherited from, and have been preserved mostly for compatibility with +CFQ. So far, no performance improvement has been reported after +changing the latter parameters in BFQ. -The tunables back_seek-max, back_seek_penalty, fifo_expire_async and -fifo_expire_sync below are the same as in CFQ. Their description is -just copied from that for CFQ. Some considerations in the description -of slice_idle are copied from CFQ too. +In particular, the tunables back_seek-max, back_seek_penalty, +fifo_expire_async and fifo_expire_sync below are the same as in +CFQ. Their description is just copied from that for CFQ. Some +considerations in the description of slice_idle are copied from CFQ +too. per-process ioprio and weight ----------------------------- @@ -285,15 +304,17 @@ number of seeks and see improved throughput. Setting slice_idle to 0 will remove all the idling on queues and one should see an overall improved throughput on faster storage devices -like multiple SATA/SAS disks in hardware RAID configuration. +like multiple SATA/SAS disks in hardware RAID configuration, as well +as flash-based storage with internal command queueing (and +parallelism). So depending on storage and workload, it might be useful to set slice_idle=0. In general for SATA/SAS disks and software RAID of SATA/SAS disks keeping slice_idle enabled should be useful. For any configurations where there are multiple spindles behind single LUN -(Host based hardware RAID controller or for storage arrays), setting -slice_idle=0 might end up in better throughput and acceptable -latencies. +(Host based hardware RAID controller or for storage arrays), or with +flash-based fast storage, setting slice_idle=0 might end up in better +throughput and acceptable latencies. Idling is however necessary to have service guarantees enforced in case of differentiated weights or differentiated I/O-request lengths. @@ -312,13 +333,14 @@ There is an important flipside for idling: apart from the above cases where it is beneficial also for throughput, idling can severely impact throughput. One important case is random workload. Because of this issue, BFQ tends to avoid idling as much as possible, when it is not -beneficial also for throughput. As a consequence of this behavior, and -of further issues described for the strict_guarantees tunable, -short-term service guarantees may be occasionally violated. And, in -some cases, these guarantees may be more important than guaranteeing -maximum throughput. For example, in video playing/streaming, a very -low drop rate may be more important than maximum throughput. In these -cases, consider setting the strict_guarantees parameter. +beneficial also for throughput (as detailed in Section 2). As a +consequence of this behavior, and of further issues described for the +strict_guarantees tunable, short-term service guarantees may be +occasionally violated. And, in some cases, these guarantees may be +more important than guaranteeing maximum throughput. For example, in +video playing/streaming, a very low drop rate may be more important +than maximum throughput. In these cases, consider setting the +strict_guarantees parameter. strict_guarantees ----------------- @@ -420,6 +442,13 @@ The default value is 0, which enables auto-tuning: BFQ sets max_budget to the maximum number of sectors that can be served during timeout_sync, according to the estimated peak rate. +For specific devices, some users have occasionally reported to have +reached a higher throughput by setting max_budget explicitly, i.e., by +setting max_budget to a higher value than 0. In particular, they have +set max_budget to higher values than those to which BFQ would have set +it with auto-tuning. An alternative way to achieve this goal is to +just increase the value of timeout_sync, leaving max_budget equal to 0. + weights ------- @@ -427,51 +456,6 @@ Read-only parameter, used to show the weights of the currently active BFQ queues. -wr_ tunables ------------- - -BFQ exports a few parameters to control/tune the behavior of -low-latency heuristics. - -wr_coeff - -Factor by which the weight of a weight-raised queue is multiplied. If -the queue is deemed soft real-time, then the weight is further -multiplied by an additional, constant factor. - -wr_max_time - -Maximum duration of a weight-raising period for an interactive task -(ms). If set to zero (default value), then this value is computed -automatically, as a function of the peak rate of the device. In any -case, when the value of this parameter is read, it always reports the -current duration, regardless of whether it has been set manually or -computed automatically. - -wr_max_softrt_rate - -Maximum service rate below which a queue is deemed to be associated -with a soft real-time application, and is then weight-raised -accordingly (sectors/sec). - -wr_min_idle_time - -Minimum idle period after which interactive weight-raising may be -reactivated for a queue (in ms). - -wr_rt_max_time - -Maximum weight-raising duration for soft real-time queues (in ms). The -start time from which this duration is considered is automatically -moved forward if the queue is detected to be still soft real-time -before the current soft real-time weight-raising period finishes. - -wr_min_inter_arr_async - -Minimum period between I/O request arrivals after which weight-raising -may be reactivated for an already busy async queue (in ms). - - 4. Group scheduling with BFQ ============================ diff --git a/Documentation/blockdev/cciss.txt b/Documentation/blockdev/cciss.txt deleted file mode 100644 index 3a5477cc456efd25168fac0df6236b4e91507435..0000000000000000000000000000000000000000 --- a/Documentation/blockdev/cciss.txt +++ /dev/null @@ -1,194 +0,0 @@ -This driver is for Compaq's SMART Array Controllers. - -Supported Cards: ----------------- - -This driver is known to work with the following cards: - - * SA 5300 - * SA 5i - * SA 532 - * SA 5312 - * SA 641 - * SA 642 - * SA 6400 - * SA 6400 U320 Expansion Module - * SA 6i - * SA P600 - * SA P800 - * SA E400 - * SA P400i - * SA E200 - * SA E200i - * SA E500 - * SA P700m - * SA P212 - * SA P410 - * SA P410i - * SA P411 - * SA P812 - * SA P712m - * SA P711m - -Detecting drive failures: -------------------------- - -To get the status of logical volumes and to detect physical drive -failures, you can use the cciss_vol_status program found here: -http://cciss.sourceforge.net/#cciss_utils - -Device Naming: --------------- - -If nodes are not already created in the /dev/cciss directory, run as root: - -# cd /dev -# ./MAKEDEV cciss - -You need some entries in /dev for the cciss device. The MAKEDEV script -can make device nodes for you automatically. Currently the device setup -is as follows: - -Major numbers: - 104 cciss0 - 105 cciss1 - 106 cciss2 - 105 cciss3 - 108 cciss4 - 109 cciss5 - 110 cciss6 - 111 cciss7 - -Minor numbers: - b7 b6 b5 b4 b3 b2 b1 b0 - |----+----| |----+----| - | | - | +-------- Partition ID (0=wholedev, 1-15 partition) - | - +-------------------- Logical Volume number - -The device naming scheme is: -/dev/cciss/c0d0 Controller 0, disk 0, whole device -/dev/cciss/c0d0p1 Controller 0, disk 0, partition 1 -/dev/cciss/c0d0p2 Controller 0, disk 0, partition 2 -/dev/cciss/c0d0p3 Controller 0, disk 0, partition 3 - -/dev/cciss/c1d1 Controller 1, disk 1, whole device -/dev/cciss/c1d1p1 Controller 1, disk 1, partition 1 -/dev/cciss/c1d1p2 Controller 1, disk 1, partition 2 -/dev/cciss/c1d1p3 Controller 1, disk 1, partition 3 - -CCISS simple mode support -------------------------- - -The "cciss_simple_mode=1" boot parameter may be used to prevent the driver -from putting the controller into "performant" mode. The difference is that -with simple mode, each command completion requires an interrupt, while with -"performant mode" (the default, and ordinarily better performing) it is -possible to have multiple command completions indicated by a single -interrupt. - -SCSI tape drive and medium changer support ------------------------------------------- - -SCSI sequential access devices and medium changer devices are supported and -appropriate device nodes are automatically created. (e.g. -/dev/st0, /dev/st1, etc. See the "st" man page for more details.) -You must enable "SCSI tape drive support for Smart Array 5xxx" and -"SCSI support" in your kernel configuration to be able to use SCSI -tape drives with your Smart Array 5xxx controller. - -Additionally, note that the driver will engage the SCSI core at init -time if any tape drives or medium changers are detected. The driver may -also be directed to dynamically engage the SCSI core via the /proc filesystem -entry which the "block" side of the driver creates as -/proc/driver/cciss/cciss* at runtime. This is best done via a script. - -For example: - - for x in /proc/driver/cciss/cciss[0-9]* - do - echo "engage scsi" > $x - done - -Once the SCSI core is engaged by the driver, it cannot be disengaged -(except by unloading the driver, if it happens to be linked as a module.) - -Note also that if no sequential access devices or medium changers are -detected, the SCSI core will not be engaged by the action of the above -script. - -Hot plug support for SCSI tape drives -------------------------------------- - -Hot plugging of SCSI tape drives is supported, with some caveats. -The cciss driver must be informed that changes to the SCSI bus -have been made. This may be done via the /proc filesystem. -For example: - - echo "rescan" > /proc/scsi/cciss0/1 - -This causes the driver to query the adapter about changes to the -physical SCSI buses and/or fibre channel arbitrated loop and the -driver to make note of any new or removed sequential access devices -or medium changers. The driver will output messages indicating what -devices have been added or removed and the controller, bus, target and -lun used to address the device. It then notifies the SCSI mid layer -of these changes. - -Note that the naming convention of the /proc filesystem entries -contains a number in addition to the driver name. (E.g. "cciss0" -instead of just "cciss" which you might expect.) - -Note: ONLY sequential access devices and medium changers are presented -as SCSI devices to the SCSI mid layer by the cciss driver. Specifically, -physical SCSI disk drives are NOT presented to the SCSI mid layer. The -physical SCSI disk drives are controlled directly by the array controller -hardware and it is important to prevent the kernel from attempting to directly -access these devices too, as if the array controller were merely a SCSI -controller in the same way that we are allowing it to access SCSI tape drives. - -SCSI error handling for tape drives and medium changers -------------------------------------------------------- - -The linux SCSI mid layer provides an error handling protocol which -kicks into gear whenever a SCSI command fails to complete within a -certain amount of time (which can vary depending on the command). -The cciss driver participates in this protocol to some extent. The -normal protocol is a four step process. First the device is told -to abort the command. If that doesn't work, the device is reset. -If that doesn't work, the SCSI bus is reset. If that doesn't work -the host bus adapter is reset. Because the cciss driver is a block -driver as well as a SCSI driver and only the tape drives and medium -changers are presented to the SCSI mid layer, and unlike more -straightforward SCSI drivers, disk i/o continues through the block -side during the SCSI error recovery process, the cciss driver only -implements the first two of these actions, aborting the command, and -resetting the device. Additionally, most tape drives will not oblige -in aborting commands, and sometimes it appears they will not even -obey a reset command, though in most circumstances they will. In -the case that the command cannot be aborted and the device cannot be -reset, the device will be set offline. - -In the event the error handling code is triggered and a tape drive is -successfully reset or the tardy command is successfully aborted, the -tape drive may still not allow i/o to continue until some command -is issued which positions the tape to a known position. Typically you -must rewind the tape (by issuing "mt -f /dev/st0 rewind" for example) -before i/o can proceed again to a tape drive which was reset. - -There is a cciss_tape_cmds module parameter which can be used to make cciss -allocate more commands for use by tape drives. Ordinarily only a few commands -(6) are allocated for tape drives because tape drives are slow and -infrequently used and the primary purpose of Smart Array controllers is to -act as a RAID controller for disk drives, so the vast majority of commands -are allocated for disk devices. However, if you have more than a few tape -drives attached to a smart array, the default number of commands may not be -enough (for example, if you have 8 tape drives, you could only rewind 6 -at one time with the default number of commands.) The cciss_tape_cmds module -parameter allows more commands (up to 16 more) to be allocated for use by -tape drives. For example: - - insmod cciss.ko cciss_tape_cmds=16 - -Or, as a kernel boot parameter passed in via grub: cciss.cciss_tape_cmds=8 diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 4fced8a21307517d82b77329aa1705c7569787eb..257e65714c6a216f3fce9ebce7398eb821f96176 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -168,6 +168,7 @@ max_comp_streams RW the number of possible concurrent compress operations comp_algorithm RW show and change the compression algorithm compact WO trigger memory compaction debug_stat RO this file is used for zram debugging purposes +backing_dev RW set up backend storage for zram to write out User space is advised to use the following files to read the device statistics. @@ -231,5 +232,15 @@ line of text and contains the following stats separated by whitespace: resets the disksize to zero. You must set the disksize again before reusing the device. +* Optional Feature + += writeback + +With incompressible pages, there is no memory saving with zram. +Instead, with CONFIG_ZRAM_WRITEBACK, zram can write incompressible page +to backing storage rather than keeping it in memory. +User should set up backing device via /sys/block/zramX/backing_dev +before disksize setting. + Nitin Gupta ngupta@vflare.org diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index bde1771035671314c65d9def375b2e472ba274c7..dc44785dc0fa146a2de30aa11ef2c410f1b00622 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt @@ -18,7 +18,9 @@ v1 is available under Documentation/cgroup-v1/. 1-2. What is cgroup? 2. Basic Operations 2-1. Mounting - 2-2. Organizing Processes + 2-2. Organizing Processes and Threads + 2-2-1. Processes + 2-2-2. Threads 2-3. [Un]populated Notification 2-4. Controlling Controllers 2-4-1. Enabling and Disabling @@ -167,8 +169,11 @@ cgroup v2 currently supports the following mount options. Delegation section for details. -Organizing Processes --------------------- +Organizing Processes and Threads +-------------------------------- + +Processes +~~~~~~~~~ Initially, only the root cgroup exists to which all processes belong. A child cgroup can be created by creating a sub-directory:: @@ -219,6 +224,105 @@ is removed subsequently, " (deleted)" is appended to the path:: 0::/test-cgroup/test-cgroup-nested (deleted) +Threads +~~~~~~~ + +cgroup v2 supports thread granularity for a subset of controllers to +support use cases requiring hierarchical resource distribution across +the threads of a group of processes. By default, all threads of a +process belong to the same cgroup, which also serves as the resource +domain to host resource consumptions which are not specific to a +process or thread. The thread mode allows threads to be spread across +a subtree while still maintaining the common resource domain for them. + +Controllers which support thread mode are called threaded controllers. +The ones which don't are called domain controllers. + +Marking a cgroup threaded makes it join the resource domain of its +parent as a threaded cgroup. The parent may be another threaded +cgroup whose resource domain is further up in the hierarchy. The root +of a threaded subtree, that is, the nearest ancestor which is not +threaded, is called threaded domain or thread root interchangeably and +serves as the resource domain for the entire subtree. + +Inside a threaded subtree, threads of a process can be put in +different cgroups and are not subject to the no internal process +constraint - threaded controllers can be enabled on non-leaf cgroups +whether they have threads in them or not. + +As the threaded domain cgroup hosts all the domain resource +consumptions of the subtree, it is considered to have internal +resource consumptions whether there are processes in it or not and +can't have populated child cgroups which aren't threaded. Because the +root cgroup is not subject to no internal process constraint, it can +serve both as a threaded domain and a parent to domain cgroups. + +The current operation mode or type of the cgroup is shown in the +"cgroup.type" file which indicates whether the cgroup is a normal +domain, a domain which is serving as the domain of a threaded subtree, +or a threaded cgroup. + +On creation, a cgroup is always a domain cgroup and can be made +threaded by writing "threaded" to the "cgroup.type" file. The +operation is single direction:: + + # echo threaded > cgroup.type + +Once threaded, the cgroup can't be made a domain again. To enable the +thread mode, the following conditions must be met. + +- As the cgroup will join the parent's resource domain. The parent + must either be a valid (threaded) domain or a threaded cgroup. + +- When the parent is an unthreaded domain, it must not have any domain + controllers enabled or populated domain children. The root is + exempt from this requirement. + +Topology-wise, a cgroup can be in an invalid state. Please consider +the following toplogy:: + + A (threaded domain) - B (threaded) - C (domain, just created) + +C is created as a domain but isn't connected to a parent which can +host child domains. C can't be used until it is turned into a +threaded cgroup. "cgroup.type" file will report "domain (invalid)" in +these cases. Operations which fail due to invalid topology use +EOPNOTSUPP as the errno. + +A domain cgroup is turned into a threaded domain when one of its child +cgroup becomes threaded or threaded controllers are enabled in the +"cgroup.subtree_control" file while there are processes in the cgroup. +A threaded domain reverts to a normal domain when the conditions +clear. + +When read, "cgroup.threads" contains the list of the thread IDs of all +threads in the cgroup. Except that the operations are per-thread +instead of per-process, "cgroup.threads" has the same format and +behaves the same way as "cgroup.procs". While "cgroup.threads" can be +written to in any cgroup, as it can only move threads inside the same +threaded domain, its operations are confined inside each threaded +subtree. + +The threaded domain cgroup serves as the resource domain for the whole +subtree, and, while the threads can be scattered across the subtree, +all the processes are considered to be in the threaded domain cgroup. +"cgroup.procs" in a threaded domain cgroup contains the PIDs of all +processes in the subtree and is not readable in the subtree proper. +However, "cgroup.procs" can be written to from anywhere in the subtree +to migrate all threads of the matching process to the cgroup. + +Only threaded controllers can be enabled in a threaded subtree. When +a threaded controller is enabled inside a threaded subtree, it only +accounts for and controls resource consumptions associated with the +threads in the cgroup and its descendants. All consumptions which +aren't tied to a specific thread belong to the threaded domain cgroup. + +Because a threaded subtree is exempt from no internal process +constraint, a threaded controller must be able to handle competition +between threads in a non-leaf cgroup and its child cgroups. Each +threaded controller defines how such competitions are handled. + + [Un]populated Notification -------------------------- @@ -302,15 +406,15 @@ disabled if one or more children have it enabled. No Internal Process Constraint ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Non-root cgroups can only distribute resources to their children when -they don't have any processes of their own. In other words, only -cgroups which don't contain any processes can have controllers enabled -in their "cgroup.subtree_control" files. +Non-root cgroups can distribute domain resources to their children +only when they don't have any processes of their own. In other words, +only domain cgroups which don't contain any processes can have domain +controllers enabled in their "cgroup.subtree_control" files. -This guarantees that, when a controller is looking at the part of the -hierarchy which has it enabled, processes are always only on the -leaves. This rules out situations where child cgroups compete against -internal processes of the parent. +This guarantees that, when a domain controller is looking at the part +of the hierarchy which has it enabled, processes are always only on +the leaves. This rules out situations where child cgroups compete +against internal processes of the parent. The root cgroup is exempt from this restriction. Root contains processes and anonymous resource consumption which can't be associated @@ -334,10 +438,10 @@ Model of Delegation ~~~~~~~~~~~~~~~~~~~ A cgroup can be delegated in two ways. First, to a less privileged -user by granting write access of the directory and its "cgroup.procs" -and "cgroup.subtree_control" files to the user. Second, if the -"nsdelegate" mount option is set, automatically to a cgroup namespace -on namespace creation. +user by granting write access of the directory and its "cgroup.procs", +"cgroup.threads" and "cgroup.subtree_control" files to the user. +Second, if the "nsdelegate" mount option is set, automatically to a +cgroup namespace on namespace creation. Because the resource control interface files in a given directory control the distribution of the parent's resources, the delegatee @@ -644,6 +748,29 @@ Core Interface Files All cgroup core files are prefixed with "cgroup." + cgroup.type + + A read-write single value file which exists on non-root + cgroups. + + When read, it indicates the current type of the cgroup, which + can be one of the following values. + + - "domain" : A normal valid domain cgroup. + + - "domain threaded" : A threaded domain cgroup which is + serving as the root of a threaded subtree. + + - "domain invalid" : A cgroup which is in an invalid state. + It can't be populated or have controllers enabled. It may + be allowed to become a threaded cgroup. + + - "threaded" : A threaded cgroup which is a member of a + threaded subtree. + + A cgroup can be turned into a threaded cgroup by writing + "threaded" to this file. + cgroup.procs A read-write new-line separated values file which exists on all cgroups. @@ -658,9 +785,6 @@ All cgroup core files are prefixed with "cgroup." the PID to the cgroup. The writer should match all of the following conditions. - - Its euid is either root or must match either uid or suid of - the target process. - - It must have write access to the "cgroup.procs" file. - It must have write access to the "cgroup.procs" file of the @@ -669,6 +793,35 @@ All cgroup core files are prefixed with "cgroup." When delegating a sub-hierarchy, write access to this file should be granted along with the containing directory. + In a threaded cgroup, reading this file fails with EOPNOTSUPP + as all the processes belong to the thread root. Writing is + supported and moves every thread of the process to the cgroup. + + cgroup.threads + A read-write new-line separated values file which exists on + all cgroups. + + When read, it lists the TIDs of all threads which belong to + the cgroup one-per-line. The TIDs are not ordered and the + same TID may show up more than once if the thread got moved to + another cgroup and then back or the TID got recycled while + reading. + + A TID can be written to migrate the thread associated with the + TID to the cgroup. The writer should match all of the + following conditions. + + - It must have write access to the "cgroup.threads" file. + + - The cgroup that the thread is currently in must be in the + same resource domain as the destination cgroup. + + - It must have write access to the "cgroup.procs" file of the + common ancestor of the source and destination cgroups. + + When delegating a sub-hierarchy, write access to this file + should be granted along with the containing directory. + cgroup.controllers A read-only space separated values file which exists on all cgroups. @@ -701,6 +854,38 @@ All cgroup core files are prefixed with "cgroup." 1 if the cgroup or its descendants contains any live processes; otherwise, 0. + cgroup.max.descendants + A read-write single value files. The default is "max". + + Maximum allowed number of descent cgroups. + If the actual number of descendants is equal or larger, + an attempt to create a new cgroup in the hierarchy will fail. + + cgroup.max.depth + A read-write single value files. The default is "max". + + Maximum allowed descent depth below the current cgroup. + If the actual descent depth is equal or larger, + an attempt to create a new child cgroup will fail. + + cgroup.stat + A read-only flat-keyed file with the following entries: + + nr_descendants + Total number of visible descendant cgroups. + + nr_dying_descendants + Total number of dying descendant cgroups. A cgroup becomes + dying after being deleted by a user. The cgroup will remain + in dying state for some time undefined time (which can depend + on system load) before being completely destroyed. + + A process can't enter a dying cgroup under any circumstances, + a dying cgroup can't revive. + + A dying cgroup can consume system resources not exceeding + limits, which were active at the moment of cgroup deletion. + Controllers =========== diff --git a/Documentation/conf.py b/Documentation/conf.py index 71b032bb44fd14b772512d9f2769cc8c47569389..63857d33778ce253b0b90dea8198ddab52a2bbe7 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -29,7 +29,7 @@ from load_config import loadConfig # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.2' +needs_sphinx = '1.3' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -271,10 +271,29 @@ latex_elements = { # Additional stuff for the LaTeX preamble. 'preamble': ''' - \\usepackage{ifthen} + % Use some font with UTF-8 support with XeLaTeX + \\usepackage{fontspec} + \\setsansfont{DejaVu Serif} + \\setromanfont{DejaVu Sans} + \\setmonofont{DejaVu Sans Mono} - % Allow generate some pages in landscape - \\usepackage{lscape} + ''' +} + +# Fix reference escape troubles with Sphinx 1.4.x +if major == 1 and minor > 3: + latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n' + +if major == 1 and minor <= 4: + latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}' +elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)): + latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=1in' + latex_elements['preamble'] += '\\fvset{fontsize=auto}\n' + +# Customize notice background colors on Sphinx < 1.6: +if major == 1 and minor < 6: + latex_elements['preamble'] += ''' + \\usepackage{ifthen} % Put notes in color and let them be inside a table \\definecolor{NoteColor}{RGB}{204,255,255} @@ -325,27 +344,26 @@ latex_elements = { } \\makeatother - % Use some font with UTF-8 support with XeLaTeX - \\usepackage{fontspec} - \\setsansfont{DejaVu Serif} - \\setromanfont{DejaVu Sans} - \\setmonofont{DejaVu Sans Mono} - - % To allow adjusting table sizes - \\usepackage{adjustbox} - ''' -} - -# Fix reference escape troubles with Sphinx 1.4.x -if major == 1 and minor > 3: - latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n' - -if major == 1 and minor <= 4: - latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}' -elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)): - latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=0.5in' +# With Sphinx 1.6, it is possible to change the Bg color directly +# by using: +# \definecolor{sphinxnoteBgColor}{RGB}{204,255,255} +# \definecolor{sphinxwarningBgColor}{RGB}{255,204,204} +# \definecolor{sphinxattentionBgColor}{RGB}{255,255,204} +# \definecolor{sphinximportantBgColor}{RGB}{192,255,204} +# +# However, it require to use sphinx heavy box with: +# +# \renewenvironment{sphinxlightbox} {% +# \\begin{sphinxheavybox} +# } +# \\end{sphinxheavybox} +# } +# +# Unfortunately, the implementation is buggy: if a note is inside a +# table, it isn't displayed well. So, for now, let's use boring +# black and white notes. # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, diff --git a/Documentation/core-api/genalloc.rst b/Documentation/core-api/genalloc.rst new file mode 100644 index 0000000000000000000000000000000000000000..6b38a39fab24c5c7b901fa4a5ac6d2c93d8f37e0 --- /dev/null +++ b/Documentation/core-api/genalloc.rst @@ -0,0 +1,144 @@ +The genalloc/genpool subsystem +============================== + +There are a number of memory-allocation subsystems in the kernel, each +aimed at a specific need. Sometimes, however, a kernel developer needs to +implement a new allocator for a specific range of special-purpose memory; +often that memory is located on a device somewhere. The author of the +driver for that device can certainly write a little allocator to get the +job done, but that is the way to fill the kernel with dozens of poorly +tested allocators. Back in 2005, Jes Sorensen lifted one of those +allocators from the sym53c8xx_2 driver and posted_ it as a generic module +for the creation of ad hoc memory allocators. This code was merged +for the 2.6.13 release; it has been modified considerably since then. + +.. _posted: https://lwn.net/Articles/125842/ + +Code using this allocator should include . The action +begins with the creation of a pool using one of: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_create + +.. kernel-doc:: lib/genalloc.c + :functions: devm_gen_pool_create + +A call to :c:func:`gen_pool_create` will create a pool. The granularity of +allocations is set with min_alloc_order; it is a log-base-2 number like +those used by the page allocator, but it refers to bytes rather than pages. +So, if min_alloc_order is passed as 3, then all allocations will be a +multiple of eight bytes. Increasing min_alloc_order decreases the memory +required to track the memory in the pool. The nid parameter specifies +which NUMA node should be used for the allocation of the housekeeping +structures; it can be -1 if the caller doesn't care. + +The "managed" interface :c:func:`devm_gen_pool_create` ties the pool to a +specific device. Among other things, it will automatically clean up the +pool when the given device is destroyed. + +A pool is shut down with: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_destroy + +It's worth noting that, if there are still allocations outstanding from the +given pool, this function will take the rather extreme step of invoking +BUG(), crashing the entire system. You have been warned. + +A freshly created pool has no memory to allocate. It is fairly useless in +that state, so one of the first orders of business is usually to add memory +to the pool. That can be done with one of: + +.. kernel-doc:: include/linux/genalloc.h + :functions: gen_pool_add + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_add_virt + +A call to :c:func:`gen_pool_add` will place the size bytes of memory +starting at addr (in the kernel's virtual address space) into the given +pool, once again using nid as the node ID for ancillary memory allocations. +The :c:func:`gen_pool_add_virt` variant associates an explicit physical +address with the memory; this is only necessary if the pool will be used +for DMA allocations. + +The functions for allocating memory from the pool (and putting it back) +are: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_alloc + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_dma_alloc + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_free + +As one would expect, :c:func:`gen_pool_alloc` will allocate size< bytes +from the given pool. The :c:func:`gen_pool_dma_alloc` variant allocates +memory for use with DMA operations, returning the associated physical +address in the space pointed to by dma. This will only work if the memory +was added with :c:func:`gen_pool_add_virt`. Note that this function +departs from the usual genpool pattern of using unsigned long values to +represent kernel addresses; it returns a void * instead. + +That all seems relatively simple; indeed, some developers clearly found it +to be too simple. After all, the interface above provides no control over +how the allocation functions choose which specific piece of memory to +return. If that sort of control is needed, the following functions will be +of interest: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_alloc_algo + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_set_algo + +Allocations with :c:func:`gen_pool_alloc_algo` specify an algorithm to be +used to choose the memory to be allocated; the default algorithm can be set +with :c:func:`gen_pool_set_algo`. The data value is passed to the +algorithm; most ignore it, but it is occasionally needed. One can, +naturally, write a special-purpose algorithm, but there is a fair set +already available: + +- gen_pool_first_fit is a simple first-fit allocator; this is the default + algorithm if none other has been specified. + +- gen_pool_first_fit_align forces the allocation to have a specific + alignment (passed via data in a genpool_data_align structure). + +- gen_pool_first_fit_order_align aligns the allocation to the order of the + size. A 60-byte allocation will thus be 64-byte aligned, for example. + +- gen_pool_best_fit, as one would expect, is a simple best-fit allocator. + +- gen_pool_fixed_alloc allocates at a specific offset (passed in a + genpool_data_fixed structure via the data parameter) within the pool. + If the indicated memory is not available the allocation fails. + +There is a handful of other functions, mostly for purposes like querying +the space available in the pool or iterating through chunks of memory. +Most users, however, should not need much beyond what has been described +above. With luck, wider awareness of this module will help to prevent the +writing of special-purpose memory allocators in the future. + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_virt_to_phys + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_for_each_chunk + +.. kernel-doc:: lib/genalloc.c + :functions: addr_in_gen_pool + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_avail + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_size + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_get + +.. kernel-doc:: lib/genalloc.c + :functions: of_gen_pool_get diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index 0606be3a3111819de772c3ce13ba61c0915898e5..d5bbe035316d5b69ffc8fbf3bb5465323ae68339 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -20,6 +20,7 @@ Core utilities genericirq flexible-arrays librs + genalloc Interfaces for kernel debugging =============================== diff --git a/Documentation/core-api/kernel-api.rst b/Documentation/core-api/kernel-api.rst index 17b00914c6aba26d3aa0972dc413b77021be499d..8282099e0cbf446bbebaaf63868ca04610999408 100644 --- a/Documentation/core-api/kernel-api.rst +++ b/Documentation/core-api/kernel-api.rst @@ -344,3 +344,52 @@ codecs, and devices with strict requirements for interface clocking. .. kernel-doc:: include/linux/clk.h :internal: + +Synchronization Primitives +========================== + +Read-Copy Update (RCU) +---------------------- + +.. kernel-doc:: include/linux/rcupdate.h + :external: + +.. kernel-doc:: include/linux/rcupdate_wait.h + :external: + +.. kernel-doc:: include/linux/rcutree.h + :external: + +.. kernel-doc:: kernel/rcu/tree.c + :external: + +.. kernel-doc:: kernel/rcu/tree_plugin.h + :external: + +.. kernel-doc:: kernel/rcu/tree_exp.h + :external: + +.. kernel-doc:: kernel/rcu/update.c + :external: + +.. kernel-doc:: include/linux/srcu.h + :external: + +.. kernel-doc:: kernel/rcu/srcutree.c + :external: + +.. kernel-doc:: include/linux/rculist_bl.h + :external: + +.. kernel-doc:: include/linux/rculist.h + :external: + +.. kernel-doc:: include/linux/rculist_nulls.h + :external: + +.. kernel-doc:: include/linux/rcu_sync.h + :external: + +.. kernel-doc:: kernel/rcu/sync.c + :external: + diff --git a/Documentation/core-api/workqueue.rst b/Documentation/core-api/workqueue.rst index ffdec94fbca185eb78d518a02e5a0f27bad8129a..00a5ba51e63fb79803e01539cc9f40dcd757c9e4 100644 --- a/Documentation/core-api/workqueue.rst +++ b/Documentation/core-api/workqueue.rst @@ -39,8 +39,8 @@ up. Although MT wq wasted a lot of resource, the level of concurrency provided was unsatisfactory. The limitation was common to both ST and MT wq albeit less severe on MT. Each wq maintained its own separate -worker pool. A MT wq could provide only one execution context per CPU -while a ST wq one for the whole system. Work items had to compete for +worker pool. An MT wq could provide only one execution context per CPU +while an ST wq one for the whole system. Work items had to compete for those very limited execution contexts leading to various problems including proneness to deadlocks around the single execution context. @@ -151,7 +151,7 @@ Application Programming Interface (API) ``alloc_workqueue()`` allocates a wq. The original ``create_*workqueue()`` functions are deprecated and scheduled for -removal. ``alloc_workqueue()`` takes three arguments - @``name``, +removal. ``alloc_workqueue()`` takes three arguments - ``@name``, ``@flags`` and ``@max_active``. ``@name`` is the name of the wq and also used as the name of the rescuer thread if there is one. @@ -197,7 +197,7 @@ resources, scheduled and executed. served by worker threads with elevated nice level. Note that normal and highpri worker-pools don't interact with - each other. Each maintain its separate pool of workers and + each other. Each maintains its separate pool of workers and implements concurrency management among its workers. ``WQ_CPU_INTENSIVE`` @@ -243,11 +243,15 @@ throttling the number of active work items, specifying '0' is recommended. Some users depend on the strict execution ordering of ST wq. The -combination of ``@max_active`` of 1 and ``WQ_UNBOUND`` is used to -achieve this behavior. Work items on such wq are always queued to the -unbound worker-pools and only one work item can be active at any given +combination of ``@max_active`` of 1 and ``WQ_UNBOUND`` used to +achieve this behavior. Work items on such wq were always queued to the +unbound worker-pools and only one work item could be active at any given time thus achieving the same ordering property as ST wq. +In the current implementation the above configuration only guarantees +ST behavior within a given NUMA node. Instead ``alloc_ordered_queue()`` should +be used to achieve system-wide ST behavior. + Example Execution Scenarios =========================== diff --git a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt index 03a7cee6ac73a4f2dd48248196994538d81f6a4e..c15e75386a0523d5398290aa9a63cc1d9f40f45e 100644 --- a/Documentation/cpu-freq/index.txt +++ b/Documentation/cpu-freq/index.txt @@ -32,8 +32,6 @@ cpufreq-stats.txt - General description of sysfs cpufreq stats. index.txt - File index, Mailing list and Links (this document) -intel-pstate.txt - Intel pstate cpufreq driver specific file. - pcc-cpufreq.txt - PCC cpufreq driver specific file. diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst index 5e93c9bc6619da5d75a75179d858d60004e6f843..19df79286f000cac9ef12e1241b496dcce96dbe6 100644 --- a/Documentation/dev-tools/gdb-kernel-debugging.rst +++ b/Documentation/dev-tools/gdb-kernel-debugging.rst @@ -31,11 +31,13 @@ Setup CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports CONFIG_FRAME_POINTER, keep it enabled. -- Install that kernel on the guest. +- Install that kernel on the guest, turn off KASLR if necessary by adding + "nokaslr" to the kernel command line. Alternatively, QEMU allows to boot the kernel directly using -kernel, -append, -initrd command line switches. This is generally only useful if you do not depend on modules. See QEMU documentation for more details on - this mode. + this mode. In this case, you should build the kernel with + CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR. - Enable the gdb stub of QEMU/KVM, either diff --git a/Documentation/dev-tools/kgdb.rst b/Documentation/dev-tools/kgdb.rst index 75273203a35a25bcab3e4b90e4b368941fdc2b2a..d38be58f872af6511a5d9568d586fff09e7c504d 100644 --- a/Documentation/dev-tools/kgdb.rst +++ b/Documentation/dev-tools/kgdb.rst @@ -348,6 +348,15 @@ default behavior is always set to 0. - ``echo 1 > /sys/module/debug_core/parameters/kgdbreboot`` - Enter the debugger on reboot notify. +Kernel parameter: ``nokaslr`` +----------------------------- + +If the architecture that you are using enable KASLR by default, +you should consider turning it off. KASLR randomizes the +virtual address where the kernel image is mapped and confuse +gdb which resolve kernel symbol address from symbol table +of vmlinux. + Using kdb ========= @@ -358,7 +367,7 @@ This is a quick example of how to use kdb. 1. Configure kgdboc at boot using kernel parameters:: - console=ttyS0,115200 kgdboc=ttyS0,115200 + console=ttyS0,115200 kgdboc=ttyS0,115200 nokaslr OR diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt index 4a0a7469fdd7bbcd93e26ea5ae9c11e4285f7c7f..32df07e29f6860d4c1de9e3c3c63d2b4d0fc454f 100644 --- a/Documentation/device-mapper/dm-raid.txt +++ b/Documentation/device-mapper/dm-raid.txt @@ -344,3 +344,4 @@ Version History (wrong raid10_copies/raid10_format sequence) 1.11.1 Add raid4/5/6 journal write-back support via journal_mode option 1.12.1 fix for MD deadlock between mddev_suspend() and md_write_start() available +1.13.0 Fix dev_health status at end of "recover" (was 'a', now 'A') diff --git a/Documentation/devicetree/bindings/arc/hsdk.txt b/Documentation/devicetree/bindings/arc/hsdk.txt new file mode 100644 index 0000000000000000000000000000000000000000..be50654bbf61c185d334ac2b055ec66d6c88838c --- /dev/null +++ b/Documentation/devicetree/bindings/arc/hsdk.txt @@ -0,0 +1,7 @@ +Synopsys DesignWare ARC HS Development Kit Device Tree Bindings +--------------------------------------------------------------------------- + +ARC HSDK Board with quad-core ARC HS38x4 in silicon. + +Required root node properties: + - compatible = "snps,hsdk"; diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index 0fff40a6330dd851f76424b88b4e116567f11b9e..4e4bc0bae597ad27b488a74c7b83762e7cb51a88 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt @@ -1,6 +1,18 @@ Amlogic MesonX device tree bindings ------------------------------------------- +Work in progress statement: + +Device tree files and bindings applying to Amlogic SoCs and boards are +considered "unstable". Any Amlogic device tree binding may change at +any time. Be sure to use a device tree binary and a kernel image +generated from the same source tree. + +Please refer to Documentation/devicetree/bindings/ABI.txt for a definition of a +stable binding/ABI. + +--------------------------------------------------------------- + Boards with the Amlogic Meson6 SoC shall have the following properties: Required root node property: compatible: "amlogic,meson6" @@ -61,3 +73,32 @@ Board compatible values (alphabetically, grouped by SoC): - "amlogic,q201" (Meson gxm s912) - "kingnovel,r-box-pro" (Meson gxm S912) - "nexbox,a1" (Meson gxm s912) + +Amlogic Meson Firmware registers Interface +------------------------------------------ + +The Meson SoCs have a register bank with status and data shared with the +secure firmware. + +Required properties: + - compatible: For Meson GX SoCs, must be "amlogic,meson-gx-ao-secure", "syscon" + +Properties should indentify components of this register interface : + +Meson GX SoC Information +------------------------ +A firmware register encodes the SoC type, package and revision information on +the Meson GX SoCs. +If present, the following property should be added : + +Optional properties: + - amlogic,has-chip-id: If present, the interface gives the current SoC version. + +Example +------- + +ao-secure@140 { + compatible = "amlogic,meson-gx-ao-secure", "syscon"; + reg = <0x0 0x140 0x0 0x140>; + amlogic,has-chip-id; +}; diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt index e926aea1147d49a06aadb5bc39cd4802afba7053..68301b77e854c86abc7d8e63cf67bcedb8b4b174 100644 --- a/Documentation/devicetree/bindings/arm/arch_timer.txt +++ b/Documentation/devicetree/bindings/arm/arch_timer.txt @@ -108,6 +108,5 @@ Example: frame-number = <1> interrupts = <0 15 0x8>; reg = <0xf0003000 0x1000>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt index 9c97de23919ae4312c3c42085393baf2536a727d..3e3efa046ac57ab49cee7d706cfff3b2d93c6247 100644 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt @@ -42,6 +42,10 @@ Raspberry Pi Zero Required root node properties: compatible = "raspberrypi,model-zero", "brcm,bcm2835"; +Raspberry Pi Zero W +Required root node properties: +compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; + Generic BCM2835 board Required root node properties: compatible = "brcm,bcm2835"; diff --git a/Documentation/devicetree/bindings/arm/bhf.txt b/Documentation/devicetree/bindings/arm/bhf.txt new file mode 100644 index 0000000000000000000000000000000000000000..886b503caf9cc07b30c92f3027853e24ced181d2 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/bhf.txt @@ -0,0 +1,6 @@ +Beckhoff Automation Platforms Device Tree Bindings +-------------------------------------------------- + +CX9020 Embedded PC +Required root node properties: + - compatible = "bhf,cx9020", "fsl,imx53"; diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index fcbae6a5e6c1563eba0335dfd58a67cd59ca567b..15ac8e8dcfdf0a6b88abdd31737aac19c19f2a1a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -34,8 +34,8 @@ its hardware characteristcs. - Embedded Trace Macrocell (version 4.x): "arm,coresight-etm4x", "arm,primecell"; - - Qualcomm Configurable Replicator (version 1.x): - "qcom,coresight-replicator1x", "arm,primecell"; + - Coresight programmable Replicator : + "arm,coresight-dynamic-replicator", "arm,primecell"; - System Trace Macrocell: "arm,coresight-stm", "arm,primecell"; [1] diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index a44253cad2692e2c209e4fa1f148ccd89415496c..b92f12bd5244a7e6fe911f8000f7a37e499e0e40 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -200,6 +200,7 @@ described below. "arm,realview-smp" "brcm,bcm11351-cpu-method" "brcm,bcm23550" + "brcm,bcm2836-smp" "brcm,bcm-nsp-smp" "brcm,brahma-b15" "marvell,armada-375-smp" diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-8kp.txt b/Documentation/devicetree/bindings/arm/marvell/armada-8kp.txt new file mode 100644 index 0000000000000000000000000000000000000000..f3e9624534c6baf30cca4dc41fff5d65a1be129b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/armada-8kp.txt @@ -0,0 +1,15 @@ +Marvell Armada 8KPlus Platforms Device Tree Bindings +---------------------------------------------------- + +Boards using a SoC of the Marvell Armada 8KP families must carry +the following root node property: + + - compatible, with one of the following values: + + - "marvell,armada-8080", "marvell,armada-ap810-octa", "marvell,armada-ap810" + when the SoC being used is the Armada 8080 + +Example: + +compatible = "marvell,armada-8080-db", "marvell,armada-8080", + "marvell,armada-ap810-octa", "marvell,armada-ap810" diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt index 171d02cadea478f50d5e95f52b489b8b11d77dc0..29cdbae6c5ac7f76fd5c7981714f113692766cd7 100644 --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt @@ -183,7 +183,6 @@ cpm_syscon0: system-controller@440000 { gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cpm_pinctrl 0 0 32>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt index da7bd138e6f2133bb43107e8b3cb8885f9791cb7..91d5178494834b57e2abe152bf5739a8930c0cd2 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.txt +++ b/Documentation/devicetree/bindings/arm/mediatek.txt @@ -1,12 +1,12 @@ -MediaTek mt65xx, mt67xx & mt81xx Platforms Device Tree Bindings +MediaTek SoC based Platforms Device Tree Bindings -Boards with a MediaTek mt65xx/mt67xx/mt81xx SoC shall have the -following property: +Boards with a MediaTek SoC shall have the following property: Required root node property: compatible: Must contain one of "mediatek,mt2701" + "mediatek,mt2712" "mediatek,mt6580" "mediatek,mt6589" "mediatek,mt6592" @@ -14,7 +14,8 @@ compatible: Must contain one of "mediatek,mt6795" "mediatek,mt6797" "mediatek,mt7622" - "mediatek,mt7623" + "mediatek,mt7623" which is referred to MT7623N SoC + "mediatek,mt7623a" "mediatek,mt8127" "mediatek,mt8135" "mediatek,mt8173" @@ -25,6 +26,9 @@ Supported boards: - Evaluation board for MT2701: Required root node properties: - compatible = "mediatek,mt2701-evb", "mediatek,mt2701"; +- Evaluation board for MT2712: + Required root node properties: + - compatible = "mediatek,mt2712-evb", "mediatek,mt2712"; - Evaluation board for MT6580: Required root node properties: - compatible = "mediatek,mt6580-evbp1", "mediatek,mt6580"; @@ -46,9 +50,11 @@ Supported boards: - Reference board variant 1 for MT7622: Required root node properties: - compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622"; -- Evaluation board for MT7623: +- Reference board for MT7623n with NAND: Required root node properties: - - compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; + - compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623"; +- Bananapi BPI-R2 board: + - compatible = "bananapi,bpi-r2", "mediatek,mt7623"; - MTK mt8127 tablet moose EVB: Required root node properties: - compatible = "mediatek,mt8127-moose", "mediatek,mt8127"; diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt index 8219b2c6bb29ab6862a65dd4adeae9d0b3aeafd9..2ecc712bf7075da21bd29104024a9c0fc15186f6 100644 --- a/Documentation/devicetree/bindings/arm/omap/omap.txt +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt @@ -80,6 +80,9 @@ SoCs: - OMAP5432 compatible = "ti,omap5432", "ti,omap5" +- DRA762 + compatible = "ti,dra762", "ti,dra7" + - DRA742 compatible = "ti,dra742", "ti,dra74", "ti,dra7" @@ -154,6 +157,9 @@ Boards: - AM335X phyCORE-AM335x: Development kit compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx" +- AM335X UC-8100-ME-T: Communication-centric industrial computing platform + compatible = "moxa,uc-8100-me-t", "ti,am33xx"; + - OMAP5 EVM : Evaluation Module compatible = "ti,omap5-evm", "ti,omap5" @@ -184,6 +190,9 @@ Boards: - AM5718 IDK compatible = "ti,am5718-idk", "ti,am5718", "ti,dra7" +- DRA762 EVM: Software Development Board for DRA762 + compatible = "ti,dra76-evm", "ti,dra762", "ti,dra7" + - DRA742 EVM: Software Development Board for DRA742 compatible = "ti,dra7-evm", "ti,dra742", "ti,dra74", "ti,dra7" diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 61c8b4620415ece32691509d6b27fe636e2fc027..13611a8199bbf14626c8024d0d4b4098d65efc60 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -9,9 +9,11 @@ Required properties: - compatible : should be one of "apm,potenza-pmu" "arm,armv8-pmuv3" + "arm,cortex-a73-pmu" "arm,cortex-a72-pmu" "arm,cortex-a57-pmu" "arm,cortex-a53-pmu" + "arm,cortex-a35-pmu" "arm,cortex-a17-pmu" "arm,cortex-a15-pmu" "arm,cortex-a12-pmu" diff --git a/Documentation/devicetree/bindings/arm/qcom.txt b/Documentation/devicetree/bindings/arm/qcom.txt index 028d16e721862effcf95ee4e9055856255e99879..0ed4d39d7fe1876ec439a713576dfc4bf8d18518 100644 --- a/Documentation/devicetree/bindings/arm/qcom.txt +++ b/Documentation/devicetree/bindings/arm/qcom.txt @@ -25,6 +25,7 @@ The 'SoC' element must be one of the following strings: msm8994 msm8996 mdm9615 + ipq8074 The 'board' element must be one of the following strings: @@ -33,6 +34,7 @@ The 'board' element must be one of the following strings: dragonboard mtp sbc + hk01 The 'soc_version' and 'board_version' elements take the form of v. where the minor number may be omitted when it's zero, i.e. v1.0 is the same diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index 11c0ac4a2d56686d04bd969c44ea3c9c7efeabe2..b003148e2945129ef834feacb5b198813195484e 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -134,6 +134,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "phytec,rk3288-pcm-947", "phytec,rk3288-phycore-som", "rockchip,rk3288"; +- Pine64 Rock64 board: + Required root node properties: + - compatible = "pine64,rock64", "rockchip,rk3328"; + - Rockchip PX3 Evaluation board: Required root node properties: - compatible = "rockchip,px3-evb", "rockchip,px3", "rockchip,rk3188"; @@ -173,6 +177,14 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "rockchip,rk3399-evb", "rockchip,rk3399"; +- Rockchip RK3399 Sapphire Excavator board: + Required root node properties: + - compatible = "rockchip,rk3399-sapphire-excavator", "rockchip,rk3399"; + +- Theobroma Systems RK3399-Q7 Haikou Baseboard: + Required root node properties: + - compatible = "tsd,rk3399-q7-haikou", "rockchip,rk3399"; + - Tronsmart Orion R68 Meta Required root node properties: - compatible = "tronsmart,orion-r68-meta", "rockchip,rk3368"; diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 1a671e3298643d9eaaec617b2b6183f77b380bed..ae75cb3b1331f82782c95a814d3a6bbda3f63857 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -39,6 +39,8 @@ SoCs: compatible = "renesas,r8a7795" - R-Car M3-W (R8A77960) compatible = "renesas,r8a7796" + - R-Car D3 (R8A77995) + compatible = "renesas,r8a77995" Boards: @@ -53,6 +55,8 @@ Boards: compatible = "renesas,blanche", "renesas,r8a7792" - BOCK-W compatible = "renesas,bockw", "renesas,r8a7778" + - Draak (RTP0RC77995SEB0010S) + compatible = "renesas,draak", "renesas,r8a77995" - Genmai (RTK772100BC00000BR) compatible = "renesas,genmai", "renesas,r7s72100" - GR-Peach (X28A-M01-E/F) @@ -64,6 +68,10 @@ Boards: compatible = "renesas,h3ulcb", "renesas,r8a7795"; - Henninger compatible = "renesas,henninger", "renesas,r8a7791" + - iWave Systems RZ/G1E SODIMM SOM Development Platform (iW-RainboW-G22D) + compatible = "iwave,g22d", "iwave,g22m", "renesas,r8a7745" + - iWave Systems RZ/G1E SODIMM System On Module (iW-RainboW-G22M-SM) + compatible = "iwave,g22m", "renesas,r8a7745" - iWave Systems RZ/G1M Qseven Development Platform (iW-RainboW-G20D-Qseven) compatible = "iwave,g20d", "iwave,g20m", "renesas,r8a7743" - iWave Systems RZ/G1M Qseven System On Module (iW-RainboW-G20M-Qseven) diff --git a/Documentation/devicetree/bindings/ata/ahci-mtk.txt b/Documentation/devicetree/bindings/ata/ahci-mtk.txt new file mode 100644 index 0000000000000000000000000000000000000000..d2aa696b161b3139210d5a7588af068a539b3040 --- /dev/null +++ b/Documentation/devicetree/bindings/ata/ahci-mtk.txt @@ -0,0 +1,51 @@ +MediaTek Serial ATA controller + +Required properties: + - compatible : Must be "mediatek,-ahci", "mediatek,mtk-ahci". + When using "mediatek,mtk-ahci" compatible strings, you + need SoC specific ones in addition, one of: + - "mediatek,mt7622-ahci" + - reg : Physical base addresses and length of register sets. + - interrupts : Interrupt associated with the SATA device. + - interrupt-names : Associated name must be: "hostc". + - clocks : A list of phandle and clock specifier pairs, one for each + entry in clock-names. + - clock-names : Associated names must be: "ahb", "axi", "asic", "rbc", "pm". + - phys : A phandle and PHY specifier pair for the PHY port. + - phy-names : Associated name must be: "sata-phy". + - ports-implemented : See ./ahci-platform.txt for details. + +Optional properties: + - power-domains : A phandle and power domain specifier pair to the power + domain which is responsible for collapsing and restoring + power to the peripheral. + - resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names : Associated names must be: "axi", "sw", "reg". + - mediatek,phy-mode : A phandle to the system controller, used to enable + SATA function. + +Example: + + sata: sata@1a200000 { + compatible = "mediatek,mt7622-ahci", + "mediatek,mtk-ahci"; + reg = <0 0x1a200000 0 0x1100>; + interrupts = ; + interrupt-names = "hostc"; + clocks = <&pciesys CLK_SATA_AHB_EN>, + <&pciesys CLK_SATA_AXI_EN>, + <&pciesys CLK_SATA_ASIC_EN>, + <&pciesys CLK_SATA_RBC_EN>, + <&pciesys CLK_SATA_PM_EN>; + clock-names = "ahb", "axi", "asic", "rbc", "pm"; + phys = <&u3port1 PHY_TYPE_SATA>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + resets = <&pciesys MT7622_SATA_AXI_BUS_RST>, + <&pciesys MT7622_SATA_PHY_SW_RST>, + <&pciesys MT7622_SATA_PHY_REG_RST>; + reset-names = "axi", "sw", "reg"; + mediatek,phy-mode = <&pciesys>; + }; diff --git a/Documentation/devicetree/bindings/ata/apm-xgene.txt b/Documentation/devicetree/bindings/ata/apm-xgene.txt index a668f0e7d0018b76841127db20845a7fd45affd6..02e690a675db738dc98555112d4faad578254100 100644 --- a/Documentation/devicetree/bindings/ata/apm-xgene.txt +++ b/Documentation/devicetree/bindings/ata/apm-xgene.txt @@ -57,7 +57,6 @@ Example: <0x0 0x1f227000 0x0 0x1000>; interrupts = <0x0 0x87 0x4>; dma-coherent; - status = "ok"; clocks = <&sataclk 0>; phys = <&phy2 0>; phy-names = "sata-phy"; @@ -72,7 +71,6 @@ Example: <0x0 0x1f237000 0x0 0x1000>; interrupts = <0x0 0x88 0x4>; dma-coherent; - status = "ok"; clocks = <&sataclk 0>; phys = <&phy3 0>; phy-names = "sata-phy"; diff --git a/Documentation/devicetree/bindings/ata/imx-pata.txt b/Documentation/devicetree/bindings/ata/imx-pata.txt index e38d73414b0d266474d9e40f4b795c089821e8da..f1172f00188aeba2ae7638a4acc4955c064e5624 100644 --- a/Documentation/devicetree/bindings/ata/imx-pata.txt +++ b/Documentation/devicetree/bindings/ata/imx-pata.txt @@ -13,5 +13,4 @@ Example: reg = <0x83fe0000 0x4000>; interrupts = <70>; clocks = <&clks 161>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt index 0764f9ab63dcde31f7efff01f74e56c5c6fa1c56..e20eac7a30874f0db82adefa0cdf3a77ac09aec2 100644 --- a/Documentation/devicetree/bindings/ata/sata_rcar.txt +++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt @@ -1,14 +1,22 @@ * Renesas R-Car SATA Required properties: -- compatible : should contain one of the following: +- compatible : should contain one or more of the following: - "renesas,sata-r8a7779" for R-Car H1 - ("renesas,rcar-sata" is deprecated) - "renesas,sata-r8a7790-es1" for R-Car H2 ES1 - "renesas,sata-r8a7790" for R-Car H2 other than ES1 - "renesas,sata-r8a7791" for R-Car M2-W - "renesas,sata-r8a7793" for R-Car M2-N - "renesas,sata-r8a7795" for R-Car H3 + - "renesas,rcar-gen2-sata" for a generic R-Car Gen2 compatible device + - "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device + - "renesas,rcar-sata" is deprecated + + When compatible with the generic version nodes + must list the SoC-specific version corresponding + to the platform first followed by the generic + version. + - reg : address and length of the SATA registers; - interrupts : must consist of one interrupt specifier. - clocks : must contain a reference to the functional clock. @@ -16,7 +24,7 @@ Required properties: Example: sata0: sata@ee300000 { - compatible = "renesas,sata-r8a7791"; + compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata"; reg = <0 0xee300000 0 0x2000>; interrupt-parent = <&gic>; interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; diff --git a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt index fa6cde41b4603537aa77eb5d650558f755b96d2a..f2ab7fd013bd514e1a4a6ef6a4094deaf65a2184 100644 --- a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt +++ b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt @@ -227,7 +227,6 @@ See the example below, where a more complete device tree is shown: }; devbus-bootcs { - status = "okay"; ranges = <0 MBUS_ID(0x01, 0x2f) 0 0x8000000>; /* NOR */ @@ -240,7 +239,6 @@ See the example below, where a more complete device tree is shown: pcie-controller { compatible = "marvell,armada-xp-pcie"; - status = "okay"; device_type = "pci"; #address-cells = <3>; @@ -258,7 +256,6 @@ See the example below, where a more complete device tree is shown: pcie@1,0 { /* Port 0, Lane 0 */ - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt index 83b0e54f727c36b468107d28c83870603f5acabb..3e21eb82281161977f9d8172e5e20f749891febe 100644 --- a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt +++ b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt @@ -84,7 +84,6 @@ gmi@70090000 { reset-names = "gmi"; ranges = <4 0 0xd0000000 0xfffffff>; - status = "okay"; bus@4,0 { compatible = "simple-bus"; @@ -121,7 +120,6 @@ gmi@70090000 { reset-names = "gmi"; ranges = <4 0 0xd0000000 0xfffffff>; - status = "okay"; can@4,0 { reg = <4 0 0x100>; diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt index 7ff13be1750ba542e5c79a355178f617523adadb..3108d03802ee9c2d7e16de057f3ccfb9e999c455 100644 --- a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt +++ b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt @@ -33,7 +33,6 @@ Example: #size-cells = <1>; ranges = <0x702c0000 0x0 0x702c0000 0x00040000>; - status = "disabled"; child1 { ... diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt index dee3f5d9df2665f55ac2b3a84ee948eba4257320..e3b13ea7d2ae38ea658adc551ea65377a36c7f97 100644 --- a/Documentation/devicetree/bindings/chosen.txt +++ b/Documentation/devicetree/bindings/chosen.txt @@ -5,9 +5,31 @@ The chosen node does not represent a real device, but serves as a place for passing data between firmware and the operating system, like boot arguments. Data in the chosen node does not represent the hardware. +The following properties are recognized: -stdout-path property --------------------- + +kaslr-seed +----------- + +This property is used when booting with CONFIG_RANDOMIZE_BASE as the +entropy used to randomize the kernel image base address location. Since +it is used directly, this value is intended only for KASLR, and should +not be used for other purposes (as it may leak information about KASLR +offsets). It is parsed as a u64 value, e.g. + +/ { + chosen { + kaslr-seed = <0xfeedbeef 0xc0def00d>; + }; +}; + +Note that if this property is set from UEFI (or a bootloader in EFI +mode) when EFI_RNG_PROTOCOL is supported, it will be overwritten by +the Linux EFI stub (which will populate the property itself, using +EFI_RNG_PROTOCOL). + +stdout-path +----------- Device trees may specify the device to be used for boot console output with a stdout-path property under /chosen, as described in the Devicetree diff --git a/Documentation/devicetree/bindings/clock/alphascale,acc.txt b/Documentation/devicetree/bindings/clock/alphascale,acc.txt index 62e67e883e76ca7ce995b1ff92c8b4133422af5c..b3205b21c9d03647a21715fd0c5574e4a49695c6 100644 --- a/Documentation/devicetree/bindings/clock/alphascale,acc.txt +++ b/Documentation/devicetree/bindings/clock/alphascale,acc.txt @@ -102,7 +102,6 @@ uart4: serial@80010000 { reg = <0x80010000 0x4000>; clocks = <&acc CLKID_SYS_UART4>, <&acc CLKID_AHB_UART4>; interrupts = <19>; - status = "disabled"; }; Clock consumer with only one, _AHB_ sink. diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt index a55d31b48d6efb88e3de71d74410def2c3aa5d3c..786dc39ca904ddd02ede6af5b7617fb9ef2e7d32 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt @@ -5,9 +5,11 @@ controllers within the Always-On part of the SoC. Required Properties: -- compatible: should be "amlogic,gxbb-aoclkc" -- reg: physical base address of the clock controller and length of memory - mapped region. +- compatible: value should be different for each SoC family as : + - GXBB (S905) : "amlogic,meson-gxbb-aoclkc" + - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" + - GXM (S912) : "amlogic,meson-gxm-aoclkc" + followed by the common "amlogic,meson-gx-aoclkc" - #clock-cells: should be 1. @@ -23,14 +25,22 @@ to specify the reset which they consume. All available resets are defined as preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be used in device tree sources. +Parent node should have the following properties : +- compatible: "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd" +- reg: base address and size of the AO system control register space. + Example: AO Clock controller node: - clkc_AO: clock-controller@040 { - compatible = "amlogic,gxbb-aoclkc"; - reg = <0x0 0x040 0x0 0x4>; +ao_sysctrl: sys-ctrl@0 { + compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; + reg = <0x0 0x0 0x0 0x100>; + + clkc_AO: clock-controller { + compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc"; #clock-cells = <1>; #reset-cells = <1>; }; +}; Example: UART controller node that consumes the clock and reset generated by the clock controller: @@ -41,5 +51,4 @@ Example: UART controller node that consumes the clock and reset generated interrupts = <0 90 1>; clocks = <&clkc_AO CLKID_AO_UART1>; resets = <&clkc_AO RESET_AO_UART1>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt index a09d627b5508a2f8c9905dc9c02c09387acfe9e6..9240407691860d90d36e0991d0672affdb9d4077 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt @@ -33,5 +33,4 @@ Example: UART controller node that consumes the clock generated by the clock reg = <0xc81004c0 0x14>; interrupts = <0 90 1>; clocks = <&clkc CLKID_CLK81>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt index 606da38c095951f3559fb89ab763f0b6d748ccad..b455c5aa9139edba0223ba9c25270255b60a0d86 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt @@ -16,18 +16,25 @@ Required Properties: mapped region. - #clock-cells: should be 1. +- #reset-cells: should be 1. Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. All available clocks are defined as preprocessor macros in the dt-bindings/clock/meson8b-clkc.h header and can be used in device tree sources. +Similarly a preprocessor macro for each reset line is defined in +dt-bindings/reset/amlogic,meson8b-clkc-reset.h (which can be used from the +device tree sources). + + Example: Clock controller node: clkc: clock-controller@c1104000 { - #clock-cells = <1>; compatible = "amlogic,meson8b-clkc"; reg = <0xc1108000 0x4>, <0xc1104000 0x460>; + #clock-cells = <1>; + #reset-cells = <1>; }; @@ -39,5 +46,4 @@ Example: UART controller node that consumes the clock generated by the clock reg = <0xc81004c0 0x14>; interrupts = <0 90 1>; clocks = <&clkc CLKID_CLK81>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index 5f3ad65daf69d48b8fc0f6cffc59e4f4210293cc..51c259a92d0294e31be12a2b4552e074b7d38e70 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt @@ -81,6 +81,16 @@ Required properties: "atmel,sama5d2-clk-generated": at91 generated clock + "atmel,sama5d2-clk-audio-pll-frac": + at91 audio fractional pll + + "atmel,sama5d2-clk-audio-pll-pad": + at91 audio pll CLK_AUDIO output pin + + "atmel,sama5d2-clk-audio-pll-pmc" + at91 audio pll output on AUDIOPLLCLK that feeds the PMC + and can be used by peripheral clock or generic clock + Required properties for SCKC node: - reg : defines the IO memory reserved for the SCKC. - #size-cells : shall be 0 (reg is used to encode clk id). diff --git a/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt b/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt index 5286e260fcae5ea4a81f888964e273fdbec13958..8e5a7d868557bcfa9165b91a36f319823163eec4 100644 --- a/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt +++ b/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt @@ -46,7 +46,6 @@ Device tree example: uart@3e002000 { compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; - status = "disabled"; reg = <0x3e002000 0x1000>; clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>; interrupts = ; diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 1dc80f8811fe8ba03b13c1180301a255983d33ad..fe885abc9cb44874b2e7b7d42d6118a7a0828533 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -465,5 +465,4 @@ Example 3: UART controller node that consumes the clock generated by the clock clock-names = "uart", "clk_uart_baud0"; pinctrl-names = "default"; pinctrl-0 = <&uart0_bus>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/hi3660-clock.txt b/Documentation/devicetree/bindings/clock/hi3660-clock.txt index cc9b86c357581bb16f908a2207d81dec597d713c..0035a7ecaf207e43a7f6bdfd1cf27ad7754f42da 100644 --- a/Documentation/devicetree/bindings/clock/hi3660-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3660-clock.txt @@ -38,5 +38,4 @@ Examples: clocks = <&crg_ctrl HI3660_CLK_MUX_UART0>, <&crg_ctrl HI3660_PCLK>; clock-names = "uartclk", "apb_pclk"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt b/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt index 7894a64887cb16e56be8aaedca7cc2c9cb14436d..4733e58e491ba7e82cac0c5c41ba448b6fdb37d1 100644 --- a/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt +++ b/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt @@ -27,5 +27,4 @@ Examples: interrupts = <0 49 4>; clocks = <&clock HIX5HD2_FIXED_83M>; clock-names = "apb_pclk"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt index 53d7e50ed875ae0db438af18f9f3354c2548c705..05a245c9df08fe48738a1d3e27e6bd45711b4a50 100644 --- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt +++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt @@ -1,24 +1,32 @@ -Binding for IDT VersaClock5 programmable i2c clock generator. +Binding for IDT VersaClock 5,6 programmable i2c clock generators. -The IDT VersaClock5 are programmable i2c clock generators providing -from 3 to 12 output clocks. +The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock +generators providing from 3 to 12 output clocks. ==I2C device node== Required properties: -- compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933" , - "idt,5p49v5935". +- compatible: shall be one of + "idt,5p49v5923" + "idt,5p49v5925" + "idt,5p49v5933" + "idt,5p49v5935" + "idt,5p49v6901" - reg: i2c device address, shall be 0x68 or 0x6a. - #clock-cells: from common clock binding; shall be set to 1. - clocks: from common clock binding; list of parent clock handles, - - 5p49v5923: (required) either or both of XTAL or CLKIN + - 5p49v5923 and + 5p49v5925 and + 5p49v6901: (required) either or both of XTAL or CLKIN reference clock. - 5p49v5933 and - 5p49v5935: (optional) property not present (internal Xtal used) or CLKIN reference clock. - clock-names: from common clock binding; clock input names, can be - - 5p49v5923: (required) either or both of "xin", "clkin". + - 5p49v5923 and + 5p49v5925 and + 5p49v6901: (required) either or both of "xin", "clkin". - 5p49v5933 and - 5p49v5935: (optional) property not present or "clkin". @@ -37,6 +45,7 @@ clock specifier, the following mapping applies: 1 -- OUT1 2 -- OUT4 +5P49V5925 and 5P49V5935: 0 -- OUT0_SEL_I2CB 1 -- OUT1 @@ -44,6 +53,13 @@ clock specifier, the following mapping applies: 3 -- OUT3 4 -- OUT4 +5P49V6901: + 0 -- OUT0_SEL_I2CB + 1 -- OUT1 + 2 -- OUT2 + 3 -- OUT3 + 4 -- OUT4 + ==Example== /* 25MHz reference crystal */ diff --git a/Documentation/devicetree/bindings/clock/imx21-clock.txt b/Documentation/devicetree/bindings/clock/imx21-clock.txt index c3b0db437c48da2bfa29431f3f45eae8c70597c1..806f63d628bdf8182fe6b974450804a31acd79e7 100644 --- a/Documentation/devicetree/bindings/clock/imx21-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx21-clock.txt @@ -24,5 +24,4 @@ Examples: clocks = <&clks IMX21_CLK_UART1_IPG_GATE>, <&clks IMX21_CLK_PER1>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.txt b/Documentation/devicetree/bindings/clock/imx23-clock.txt index 5083c0b834b25094fe7d5159cc51238cc37ef921..8385348d3bd99f16db9bb3c13887edf8f83546a9 100644 --- a/Documentation/devicetree/bindings/clock/imx23-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx23-clock.txt @@ -67,5 +67,4 @@ auart0: serial@8006c000 { reg = <0x8006c000 0x2000>; interrupts = <24 25 23>; clocks = <&clks 32>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx25-clock.txt b/Documentation/devicetree/bindings/clock/imx25-clock.txt index ba6b312ff8a58145a834cf424caad44d26efef4d..f8135ea9ca4e2a371e95d12e5dcebccd40b3989a 100644 --- a/Documentation/devicetree/bindings/clock/imx25-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx25-clock.txt @@ -157,5 +157,4 @@ uart1: serial@43f90000 { interrupts = <45>; clocks = <&clks 79>, <&clks 50>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx27-clock.txt b/Documentation/devicetree/bindings/clock/imx27-clock.txt index cc05de9ec393574c740f77d1b74ed6694fcb9b80..4c95c048d3b294c154d0f2f7e0c1eb27fed01e14 100644 --- a/Documentation/devicetree/bindings/clock/imx27-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx27-clock.txt @@ -24,5 +24,4 @@ Examples: clocks = <&clks IMX27_CLK_UART1_IPG_GATE>, <&clks IMX27_CLK_PER1_GATE>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.txt b/Documentation/devicetree/bindings/clock/imx28-clock.txt index e6587af62ff0fe6e740ee8bdeb3f4b32d851c5de..d84a37d2885f6d2637e5285a9f69e904835287cc 100644 --- a/Documentation/devicetree/bindings/clock/imx28-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx28-clock.txt @@ -90,5 +90,4 @@ auart0: serial@8006a000 { reg = <0x8006a000 0x2000>; interrupts = <112 70 71>; clocks = <&clks 45>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Documentation/devicetree/bindings/clock/imx31-clock.txt index 8163d565f697709d38e2f482adfa2ab385ebc64a..0a291090e56265090f0284b0a7823b8fb790780e 100644 --- a/Documentation/devicetree/bindings/clock/imx31-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx31-clock.txt @@ -87,5 +87,4 @@ uart1: serial@43f90000 { interrupts = <45>; clocks = <&clks 10>, <&clks 30>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index cadc4d29ada6663716c5135f78adcc3df902ee8e..a24ca9e582d2768380fef60819eb2e8820e6688c 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -25,5 +25,4 @@ can1: can@53fc8000 { interrupts = <82>; clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index 9252912a5b0ea890668df648e092ca10c1da2164..aa0a4d423ef58d83e4107538779fa237d5eee27e 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -27,5 +27,4 @@ uart1: serial@02020000 { interrupts = <0 26 0x04>; clocks = <&clks IMX6QDL_CLK_UART_IPG>, <&clks IMX6QDL_CLK_UART_SERIAL>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt b/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt deleted file mode 100644 index 52b457c23eede4a90557231d857ca098a95be546..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt +++ /dev/null @@ -1,83 +0,0 @@ -Device Tree Clock bindins for CPU DVFS of Mediatek MT8173 SoC - -Required properties: -- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names. -- clock-names: Should contain the following: - "cpu" - The multiplexer for clock input of CPU cluster. - "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock - source (usually MAINPLL) when the original CPU PLL is under - transition and not stable yet. - Please refer to Documentation/devicetree/bindings/clk/clock-bindings.txt for - generic clock consumer properties. -- proc-supply: Regulator for Vproc of CPU cluster. - -Optional properties: -- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver - needs to do "voltage tracking" to step by step scale up/down Vproc and - Vsram to fit SoC specific needs. When absent, the voltage scaling - flow is handled by hardware, hence no software "voltage tracking" is - needed. - -Example: --------- - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x000>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA53SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x001>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA53SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - cpu2: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x100>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA57SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - cpu3: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x101>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA57SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - &cpu0 { - proc-supply = <&mt6397_vpca15_reg>; - }; - - &cpu1 { - proc-supply = <&mt6397_vpca15_reg>; - }; - - &cpu2 { - proc-supply = <&da9211_vcpu_reg>; - sram-supply = <&mt6397_vsramca7_reg>; - }; - - &cpu3 { - proc-supply = <&da9211_vcpu_reg>; - sram-supply = <&mt6397_vsramca7_reg>; - }; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt index 63f9d8277d48bb06a1b6b9c436865524764ab399..dff236f524a73844f95cf945397edc3143fcc205 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt @@ -66,7 +66,6 @@ clock@70110000 { #clock-cells = <0>; clock-output-names = "dfllCPU_out"; vdd-cpu-supply = <&vdd_cpu>; - status = "okay"; nvidia,sample-rate = <12500>; nvidia,droop-ctrl = <0x00000f00>; diff --git a/Documentation/devicetree/bindings/clock/pxa-clock.txt b/Documentation/devicetree/bindings/clock/pxa-clock.txt index 4b4a9024bd990bfa4b714b64f71a785da5494ea9..8f67239411fee74af684f01d0d73913ba6884963 100644 --- a/Documentation/devicetree/bindings/clock/pxa-clock.txt +++ b/Documentation/devicetree/bindings/clock/pxa-clock.txt @@ -12,5 +12,4 @@ Examples: pxa2xx_clks: pxa2xx_clks@41300004 { compatible = "marvell,pxa-clocks"; #clock-cells = <1>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 0cd894f987a38e8137acf03b3a441bfd5070d0c4..316e136865688b7c4fe0c6f1d7b23934d66634d1 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -22,6 +22,7 @@ Required Properties: - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) + - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) - reg: Base address and length of the memory resource used by the CPG/MSSR block @@ -30,7 +31,7 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, - r8a7795, r8a7796) + r8a7795, r8a7796, r8a77995) - "extalr" (r8a7795, r8a7796) - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) @@ -81,5 +82,4 @@ Examples dma-names = "tx", "rx"; power-domains = <&cpg>; resets = <&cpg 310>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt index e4cdaf1cb3333012c797039c8aec1c7638ac5646..7cc4c0330b534660d97758ce9a7e8f304670db8a 100644 --- a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt @@ -44,5 +44,4 @@ Examples interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7778_CLK_SDHI0>; power-domains = <&cpg_clocks>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt new file mode 100644 index 0000000000000000000000000000000000000000..e96e085271c134f4889d08febddbab10141f6235 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt @@ -0,0 +1,55 @@ +* Renesas R-Car USB 2.0 clock selector + +This file provides information on what the device node for the R-Car USB 2.0 +clock selector. + +If you connect an external clock to the USB_EXTAL pin only, you should set +the clock rate to "usb_extal" node only. +If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module +is not needed because this is default setting. (Of course, you can set the +clock rates to both "usb_extal" and "usb_xtal" nodes. + +Case 1: An external clock connects to R-Car SoC + +----------+ +--- R-Car ---------------------+ + |External |---|USB_EXTAL ---> all usb channels| + |clock | |USB_XTAL | + +----------+ +-------------------------------+ +In this case, we need this driver with "usb_extal" clock. + +Case 2: An oscillator connects to R-Car SoC + +----------+ +--- R-Car ---------------------+ + |Oscillator|---|USB_EXTAL -+-> all usb channels| + | |---|USB_XTAL --+ | + +----------+ +-------------------------------+ +In this case, we don't need this selector. + +Required properties: +- compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of + an R8A7795 SoC. + "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of + an R8A7796 SoC. + "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3 + compatible device. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + +- reg: offset and length of the USB 2.0 clock selector register block. +- clocks: A list of phandles and specifier pairs. +- clock-names: Name of the clocks. + - The functional clock must be "ehci_ohci" + - The USB_EXTAL clock pin must be "usb_extal" + - The USB_XTAL clock pin must be "usb_xtal" +- #clock-cells: Must be 0 + +Example (R-Car H3): + + usb2_clksel: clock-controller@e6590630 { + compatible = "renesas,r8a77950-rcar-usb2-clock-sel", + "renesas,rcar-gen3-usb2-clock-sel"; + reg = <0 0xe6590630 0 0x02>; + clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; + clock-names = "ehci_ohci", "usb_extal", "usb_xtal"; + #clock-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt index bb51a33a1fbfbc9798be9800c1b865dda201de21..bb5d942075fbf0bf18fb9d924f34e3508fcf4298 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt @@ -50,5 +50,4 @@ Examples clocks = <&mstp3_clks R7S72100_CLK_MTU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt index 455a9a00a623155dea4acd74e47b2153871b8904..6f8744fd301b23609f924873f325b9fc4e0c98a0 100644 --- a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt @@ -1,12 +1,14 @@ -* Rockchip RK3128 Clock and Reset Unit +* Rockchip RK3126/RK3128 Clock and Reset Unit -The RK3128 clock controller generates and supplies clock to various +The RK3126/RK3128 clock controller generates and supplies clock to various controllers within the SoC and also implements a reset controller for SoC peripherals. Required Properties: -- compatible: should be "rockchip,rk3128-cru" +- compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru" + "rockchip,rk3126-cru" - controller compatible with RK3126 SoC. + "rockchip,rk3128-cru" - controller compatible with RK3128 SoC. - reg: physical base address of the controller and length of memory mapped region. - #clock-cells: should be 1. diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt index 822505e715aeac3cc9a2b4dd9293fa4a4b6f248b..2632d3f130045ff4523b07f676ed126200cdd4b1 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt @@ -46,5 +46,4 @@ Example: UART controller node that consumes the clock generated by the clock interrupts = <1 23 3 4>, <1 23 4 4>; clock-names = "uart", "clk_uart_baud2"; clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt index 2b430960ba472255373d94b067a0f161f73c9dad..21a8c23e658f3458167124a20a3f700b5a8566b2 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt @@ -46,5 +46,4 @@ Example: UART controller node that consumes the clock generated by the clock clock-names = "uart", "clk_uart_baud2", "clk_uart_baud3"; clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, <&clocks SCLK_UART>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt index e67bb05478afd27c40a8dac1a98c660e9dd27c24..985c0f574e9a831cbef4a874587eb12c133c7625 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt @@ -52,5 +52,4 @@ Example: UART controller node that consumes the clock generated by the clock "clk_uart_baud3"; clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, <&clocks SCLK_UART>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt index fa171dc4bd3ca4d4750fc9f711478ebcf06562b2..872ee8e0f041258956a22ae31a1c4d2236597166 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt @@ -73,5 +73,4 @@ Example: UART controller node that consumes the clock generated by the clock "clk_uart_baud3"; clocks = <&clock PCLK_UART0>, <&clocks PCLK_UART0>, <&clock SCLK_UART>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt index effd9401c13317934a38eeaa03e273a4c804d97e..15b48e20a061f8010a59209dadeca415b6d5dbb7 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt @@ -74,5 +74,4 @@ Example: UART controller node that consumes the clock generated by the clock "clk_uart_baud1"; clocks = <&clocks UART0>, <&clocks UART0>, <&clocks SCLK_UART0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt index 28b28309f53575e91752cba6453e5594ea985de3..a6c4ef343b44cee72351805ad9bda8328e4e6a47 100644 --- a/Documentation/devicetree/bindings/clock/silabs,si5351.txt +++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt @@ -12,7 +12,11 @@ generators can be found in [1]. ==I2C device node== Required properties: -- compatible: shall be one of "silabs,si5351{a,a-msop,b,c}". +- compatible: shall be one of the following: + "silabs,si5351a" - Si5351a, QFN20 package + "silabs,si5351a-msop" - Si5351a, MSOP10 package + "silabs,si5351b" - Si5351b, QFN20 package + "silabs,si5351c" - Si5351c, QFN20 package - reg: i2c device address, shall be 0x60 or 0x61. - #clock-cells: from common clock binding; shall be set to 1. - clocks: from common clock binding; list of parent clock diff --git a/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt new file mode 100644 index 0000000000000000000000000000000000000000..c56c7553c7300213cc2a12865eb0589a269b6fce --- /dev/null +++ b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt @@ -0,0 +1,28 @@ +Binding for the HSDK Generic PLL clock + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible: should be "snps,hsdk--pll-clock" + "snps,hsdk-core-pll-clock" + "snps,hsdk-gp-pll-clock" + "snps,hsdk-hdmi-pll-clock" +- reg : should contain base register location and length. +- clocks: shall be the input parent clock phandle for the PLL. +- #clock-cells: from common clock binding; Should always be set to 0. + +Example: + input_clk: input-clk { + clock-frequency = <33333333>; + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + cpu_clk: cpu-clk@0 { + compatible = "snps,hsdk-core-pll-clock"; + reg = <0x00 0x10>; + #clock-cells = <0>; + clocks = <&input_clk>; + }; diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt new file mode 100644 index 0000000000000000000000000000000000000000..11fe4876612c46aef0c1fab910806e2d82e121ed --- /dev/null +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt @@ -0,0 +1,28 @@ +Binding for the AXS10X Generic PLL clock + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible: should be "snps,axs10x--pll-clock" + "snps,axs10x-arc-pll-clock" + "snps,axs10x-pgu-pll-clock" +- reg: should always contain 2 pairs address - length: first for PLL config +registers and second for corresponding LOCK CGU register. +- clocks: shall be the input parent clock phandle for the PLL. +- #clock-cells: from common clock binding; Should always be set to 0. + +Example: + input-clk: input-clk { + clock-frequency = <33333333>; + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + core-clk: core-clk@80 { + compatible = "snps,axs10x-arc-pll-clock"; + reg = <0x80 0x10>, <0x100 0x10>; + #clock-cells = <0>; + clocks = <&input-clk>; + }; diff --git a/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt new file mode 100644 index 0000000000000000000000000000000000000000..cac24ee10b72ebc3765d29708fa27c5ae6848950 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt @@ -0,0 +1,71 @@ +STMicroelectronics STM32H7 Reset and Clock Controller +===================================================== + +The RCC IP is both a reset and a clock controller. + +Please refer to clock-bindings.txt for common clock controller binding usage. +Please also refer to reset.txt for common reset controller binding usage. + +Required properties: +- compatible: Should be: + "st,stm32h743-rcc" + +- reg: should be register base and length as documented in the + datasheet + +- #reset-cells: 1, see below + +- #clock-cells : from common clock binding; shall be set to 1 + +- clocks: External oscillator clock phandle + - high speed external clock signal (HSE) + - low speed external clock signal (LSE) + - external I2S clock (I2S_CKIN) + +Optional properties: +- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain + write protection (RTC clock). + +Example: + + rcc: reset-clock-controller@58024400 { + compatible = "st,stm32h743-rcc", "st,stm32-rcc"; + reg = <0x58024400 0x400>; + #reset-cells = <1>; + #clock-cells = <1>; + clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>; + + st,syscfg = <&pwrcfg>; +}; + +The peripheral clock consumer should specify the desired clock by +having the clock ID in its "clocks" phandle cell. + +Example: + + timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; + clocks = <&rcc TIM5_CK>; + }; + +Specifying softreset control of devices +======================================= + +Device nodes should specify the reset channel required in their "resets" +property, containing a phandle to the reset device node and an index specifying +which channel to use. +The index is the bit number within the RCC registers bank, starting from RCC +base address. +It is calculated as: index = register_offset / 4 * 32 + bit_offset. +Where bit_offset is the bit offset within the register. + +For example, for CRC reset: + crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107 + +Example: + + timer2 { + resets = <&rcc STM32H7_APB1L_RESET(TIM2)>; + }; diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index df9fad58facdc22b995e9066275cac3344724a6d..7eda08eb8a1e336cf0756baa62a91f21fd58bce6 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt @@ -3,18 +3,24 @@ Allwinner Clock Control Unit Binding Required properties : - compatible: must contain one of the following compatibles: + - "allwinner,sun4i-a10-ccu" + - "allwinner,sun5i-a10s-ccu" + - "allwinner,sun5i-a13-ccu" - "allwinner,sun6i-a31-ccu" + - "allwinner,sun7i-a20-ccu" - "allwinner,sun8i-a23-ccu" - "allwinner,sun8i-a33-ccu" - "allwinner,sun8i-a83t-ccu" - "allwinner,sun8i-a83t-r-ccu" - "allwinner,sun8i-h3-ccu" - "allwinner,sun8i-h3-r-ccu" ++ - "allwinner,sun8i-r40-ccu" - "allwinner,sun8i-v3s-ccu" - "allwinner,sun9i-a80-ccu" - "allwinner,sun50i-a64-ccu" - "allwinner,sun50i-a64-r-ccu" - "allwinner,sun50i-h5-ccu" + - "nextthing,gr8-ccu" - reg: Must contain the registers base address and length - clocks: phandle to the oscillators feeding the CCU. Two are needed: diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt index 1e884c40ab5068dd22658c244f3d0cd59ebd0cce..4e59dc6b177897b3840388d7b192286e28d7e67b 100644 --- a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt @@ -14,10 +14,9 @@ Required properties: - compatible: Must be "ti,k2g-sci-clk" - #clock-cells: Shall be 2. In clock consumers, this cell represents the device ID and clock ID - exposed by the PM firmware. The assignments can be found in the header - files .h> (which covers the device IDs) and - .h> (which covers the clock IDs), where - is the SoC involved, for example 'k2g'. + exposed by the PM firmware. The list of valid values for the device IDs + and clocks IDs for 66AK2G SoC are documented at + http://processors.wiki.ti.com/index.php/TISCI#66AK2G02_Data Examples: -------- diff --git a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt index 585e8c191f50df4b2df1e13fb0cbd7dbde682bbf..10f7047755f39817d7d5bf3d4b369ebd46227fa0 100644 --- a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt +++ b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt @@ -81,13 +81,11 @@ atl: atl@4843c000 { <&atl_clkin2_ck>, <&atl_clkin3_ck>; clocks = <&atl_gfclk_mux>; clock-names = "fck"; - status = "disabled"; }; #include &atl { - status = "okay"; atl2 { bws = ; diff --git a/Documentation/devicetree/bindings/clock/uniphier-clock.txt b/Documentation/devicetree/bindings/clock/uniphier-clock.txt index 812163060fa3e4cb4e4f39fe22c9fbd2aeb41d9f..7b5f602765fe2fc318fef07c8c4ffc5168ddd5d8 100644 --- a/Documentation/devicetree/bindings/clock/uniphier-clock.txt +++ b/Documentation/devicetree/bindings/clock/uniphier-clock.txt @@ -6,7 +6,6 @@ System clock Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-clock" - for sLD3 SoC. "socionext,uniphier-ld4-clock" - for LD4 SoC. "socionext,uniphier-pro4-clock" - for Pro4 SoC. "socionext,uniphier-sld8-clock" - for sLD8 SoC. @@ -14,6 +13,7 @@ Required properties: "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC. "socionext,uniphier-ld11-clock" - for LD11 SoC. "socionext,uniphier-ld20-clock" - for LD20 SoC. + "socionext,uniphier-pxs3-clock" - for PXs3 SoC - #clock-cells: should be 1. Example: @@ -48,7 +48,6 @@ Media I/O (MIO) clock, SD clock Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-mio-clock" - for sLD3 SoC. "socionext,uniphier-ld4-mio-clock" - for LD4 SoC. "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC. "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC. @@ -56,6 +55,7 @@ Required properties: "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC. "socionext,uniphier-ld11-mio-clock" - for LD11 SoC. "socionext,uniphier-ld20-sd-clock" - for LD20 SoC. + "socionext,uniphier-pxs3-sd-clock" - for PXs3 SoC - #clock-cells: should be 1. Example: @@ -82,11 +82,9 @@ Provided clocks: 8: USB2 ch0 host 9: USB2 ch1 host 10: USB2 ch2 host -11: USB2 ch3 host 12: USB2 ch0 PHY 13: USB2 ch1 PHY 14: USB2 ch2 PHY -15: USB2 ch3 PHY Peripheral clock @@ -94,7 +92,6 @@ Peripheral clock Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-peri-clock" - for sLD3 SoC. "socionext,uniphier-ld4-peri-clock" - for LD4 SoC. "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC. "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC. @@ -102,6 +99,7 @@ Required properties: "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC. "socionext,uniphier-ld11-peri-clock" - for LD11 SoC. "socionext,uniphier-ld20-peri-clock" - for LD20 SoC. + "socionext,uniphier-pxs3-peri-clock" - for PXs3 SoC - #clock-cells: should be 1. Example: diff --git a/Documentation/devicetree/bindings/clock/zx296702-clk.txt b/Documentation/devicetree/bindings/clock/zx296702-clk.txt index 750442b65505cbcc8f4b0652c7082350c2c302a9..e85ecb510d56daad83ffbbe3572a96dc110a43a3 100644 --- a/Documentation/devicetree/bindings/clock/zx296702-clk.txt +++ b/Documentation/devicetree/bindings/clock/zx296702-clk.txt @@ -31,5 +31,4 @@ uart0: serial@0x09405000 { reg = <0x09405000 0x1000>; interrupts = ; clocks = <&lsp1clk ZX296702_UART0_PCLK>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/zx296718-clk.txt b/Documentation/devicetree/bindings/clock/zx296718-clk.txt index 4ad7038084074e405bdeb5a69a4c1fcccb210d6b..3a46bf0b2540cf7a6c6b565cc0cd47f2e9a0bdfa 100644 --- a/Documentation/devicetree/bindings/clock/zx296718-clk.txt +++ b/Documentation/devicetree/bindings/clock/zx296718-clk.txt @@ -34,5 +34,4 @@ usbphy0:usb-phy0 { #phy-cells = <0>; clocks = <&topclk USB20_PHY_CLK>; clock-names = "phyclk"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt new file mode 100644 index 0000000000000000000000000000000000000000..f6403089edcf80d6cabc56607b49464f8b44b5ac --- /dev/null +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt @@ -0,0 +1,247 @@ +Binding for MediaTek's CPUFreq driver +===================================== + +Required properties: +- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names. +- clock-names: Should contain the following: + "cpu" - The multiplexer for clock input of CPU cluster. + "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock + source (usually MAINPLL) when the original CPU PLL is under + transition and not stable yet. + Please refer to Documentation/devicetree/bindings/clk/clock-bindings.txt for + generic clock consumer properties. +- operating-points-v2: Please refer to Documentation/devicetree/bindings/opp/opp.txt + for detail. +- proc-supply: Regulator for Vproc of CPU cluster. + +Optional properties: +- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver + needs to do "voltage tracking" to step by step scale up/down Vproc and + Vsram to fit SoC specific needs. When absent, the voltage scaling + flow is handled by hardware, hence no software "voltage tracking" is + needed. +- #cooling-cells: +- cooling-min-level: +- cooling-max-level: + Please refer to Documentation/devicetree/bindings/thermal/thermal.txt + for detail. + +Example 1 (MT7623 SoC): + + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-598000000 { + opp-hz = /bits/ 64 <598000000>; + opp-microvolt = <1050000>; + }; + + opp-747500000 { + opp-hz = /bits/ 64 <747500000>; + opp-microvolt = <1050000>; + }; + + opp-1040000000 { + opp-hz = /bits/ 64 <1040000000>; + opp-microvolt = <1150000>; + }; + + opp-1196000000 { + opp-hz = /bits/ 64 <1196000000>; + opp-microvolt = <1200000>; + }; + + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1300000>; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x0>; + clocks = <&infracfg CLK_INFRA_CPUSEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + cooling-min-level = <0>; + cooling-max-level = <7>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x2>; + operating-points-v2 = <&cpu_opp_table>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x3>; + operating-points-v2 = <&cpu_opp_table>; + }; + +Example 2 (MT8173 SoC): + cpu_opp_table_a: opp_table_a { + compatible = "operating-points-v2"; + opp-shared; + + opp-507000000 { + opp-hz = /bits/ 64 <507000000>; + opp-microvolt = <859000>; + }; + + opp-702000000 { + opp-hz = /bits/ 64 <702000000>; + opp-microvolt = <908000>; + }; + + opp-1001000000 { + opp-hz = /bits/ 64 <1001000000>; + opp-microvolt = <983000>; + }; + + opp-1105000000 { + opp-hz = /bits/ 64 <1105000000>; + opp-microvolt = <1009000>; + }; + + opp-1183000000 { + opp-hz = /bits/ 64 <1183000000>; + opp-microvolt = <1028000>; + }; + + opp-1404000000 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <1083000>; + }; + + opp-1508000000 { + opp-hz = /bits/ 64 <1508000000>; + opp-microvolt = <1109000>; + }; + + opp-1573000000 { + opp-hz = /bits/ 64 <1573000000>; + opp-microvolt = <1125000>; + }; + }; + + cpu_opp_table_b: opp_table_b { + compatible = "operating-points-v2"; + opp-shared; + + opp-507000000 { + opp-hz = /bits/ 64 <507000000>; + opp-microvolt = <828000>; + }; + + opp-702000000 { + opp-hz = /bits/ 64 <702000000>; + opp-microvolt = <867000>; + }; + + opp-1001000000 { + opp-hz = /bits/ 64 <1001000000>; + opp-microvolt = <927000>; + }; + + opp-1209000000 { + opp-hz = /bits/ 64 <1209000000>; + opp-microvolt = <968000>; + }; + + opp-1404000000 { + opp-hz = /bits/ 64 <1007000000>; + opp-microvolt = <1028000>; + }; + + opp-1612000000 { + opp-hz = /bits/ 64 <1612000000>; + opp-microvolt = <1049000>; + }; + + opp-1807000000 { + opp-hz = /bits/ 64 <1807000000>; + opp-microvolt = <1089000>; + }; + + opp-1989000000 { + opp-hz = /bits/ 64 <1989000000>; + opp-microvolt = <1125000>; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x000>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA53SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_a>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x001>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA53SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_a>; + }; + + cpu2: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x100>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA57SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_b>; + }; + + cpu3: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x101>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA57SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_b>; + }; + + &cpu0 { + proc-supply = <&mt6397_vpca15_reg>; + }; + + &cpu1 { + proc-supply = <&mt6397_vpca15_reg>; + }; + + &cpu2 { + proc-supply = <&da9211_vcpu_reg>; + sram-supply = <&mt6397_vsramca7_reg>; + }; + + &cpu3 { + proc-supply = <&da9211_vcpu_reg>; + sram-supply = <&mt6397_vsramca7_reg>; + }; diff --git a/Documentation/devicetree/bindings/crypto/artpec6-crypto.txt b/Documentation/devicetree/bindings/crypto/artpec6-crypto.txt new file mode 100644 index 0000000000000000000000000000000000000000..d9cca4875bd64659079b114712974f82a1950b17 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/artpec6-crypto.txt @@ -0,0 +1,16 @@ +Axis crypto engine with PDMA interface. + +Required properties: +- compatible : Should be one of the following strings: + "axis,artpec6-crypto" for the version in the Axis ARTPEC-6 SoC + "axis,artpec7-crypto" for the version in the Axis ARTPEC-7 SoC. +- reg: Base address and size for the PDMA register area. +- interrupts: Interrupt handle for the PDMA interrupt line. + +Example: + +crypto@f4264000 { + compatible = "axis,artpec6-crypto"; + reg = <0xf4264000 0x1000>; + interrupts = ; +}; diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt index f2aab3dc2b523459f2f1a48c7a7360b31f6abc22..7de1a9674c7075d33833ccd2f310bd905d8ef4fe 100644 --- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt +++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt @@ -66,3 +66,16 @@ sha@f8034000 { dmas = <&dma1 2 17>; dma-names = "tx"; }; + +* Eliptic Curve Cryptography (I2C) + +Required properties: +- compatible : must be "atmel,atecc508a". +- reg: I2C bus address of the device. +- clock-frequency: must be present in the i2c controller node. + +Example: +atecc508a@C0 { + compatible = "atmel,atecc508a"; + reg = <0xC0>; +}; diff --git a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt index 6949e50f1f1696aa07f7e43c182ddb8d2bd4a2a1..76a0b4e80e83edd46510783274d834748eaff7a9 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt @@ -13,5 +13,4 @@ dcp@80028000 { compatible = "fsl,imx28-dcp", "fsl,imx23-dcp"; reg = <0x80028000 0x2000>; interrupts = <52 53>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt index 941bb6a6fb1304609bb3fa8a94520bfbdcca06f7..fbc07d12322f8020bc7a1ab282cd2eaffb587f9f 100644 --- a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt +++ b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt @@ -23,5 +23,4 @@ Example: interrupt-names = "mem", "ring0", "ring1", "ring2", "ring3", "eip"; clocks = <&cpm_syscon0 1 26>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/crypto/marvell-cesa.txt b/Documentation/devicetree/bindings/crypto/marvell-cesa.txt index c6c6a4a045bde3b27f4442e7c97e551483d14064..28d3f2496b8925393669967c389433ca2af7f8e7 100644 --- a/Documentation/devicetree/bindings/crypto/marvell-cesa.txt +++ b/Documentation/devicetree/bindings/crypto/marvell-cesa.txt @@ -41,5 +41,4 @@ Examples: clock-names = "cesa0", "cesa1"; marvell,crypto-srams = <&crypto_sram0>, <&crypto_sram1>; marvell,crypto-sram-size = <0x600>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/mv_cesa.txt b/Documentation/devicetree/bindings/crypto/mv_cesa.txt index c0c35f00335bfe0e66994bff1bfb4540db5dfea3..d9b92e2f3138106c2fc11a4660a8bf2b5b8f39af 100644 --- a/Documentation/devicetree/bindings/crypto/mv_cesa.txt +++ b/Documentation/devicetree/bindings/crypto/mv_cesa.txt @@ -29,5 +29,4 @@ Examples: interrupts = <22>; marvell,crypto-srams = <&crypto_sram>; marvell,crypto-sram-size = <0x600>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt index 096df34b11c162a84711f73ea426d86a6864f4a7..5e2ba385b8c9b9a6118af61c36c2a4e0b8463287 100644 --- a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -25,5 +25,4 @@ Examples: clock-names = "aclk", "hclk", "sclk", "apb_pclk"; resets = <&cru SRST_CRYPTO>; reset-names = "crypto-rst"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/st,stm32-hash.txt b/Documentation/devicetree/bindings/crypto/st,stm32-hash.txt new file mode 100644 index 0000000000000000000000000000000000000000..04fc246f02f79326999ea09ebfae58872100d089 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/st,stm32-hash.txt @@ -0,0 +1,30 @@ +* STMicroelectronics STM32 HASH + +Required properties: +- compatible: Should contain entries for this and backward compatible + HASH versions: + - "st,stm32f456-hash" for stm32 F456. + - "st,stm32f756-hash" for stm32 F756. +- reg: The address and length of the peripheral registers space +- interrupts: the interrupt specifier for the HASH +- clocks: The input clock of the HASH instance + +Optional properties: +- resets: The input reset of the HASH instance +- dmas: DMA specifiers for the HASH. See the DMA client binding, + Documentation/devicetree/bindings/dma/dma.txt +- dma-names: DMA request name. Should be "in" if a dma is present. +- dma-maxburst: Set number of maximum dma burst supported + +Example: + +hash1: hash@50060400 { + compatible = "st,stm32f756-hash"; + reg = <0x50060400 0x400>; + interrupts = <80>; + clocks = <&rcc 0 STM32F7_AHB2_CLOCK(HASH)>; + resets = <&rcc STM32F7_AHB2_RESET(HASH)>; + dmas = <&dma2 7 2 0x400 0x0>; + dma-names = "in"; + dma-maxburst = <0>; +}; diff --git a/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt b/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt index f2233138eba97a58172dfa6598846a07fe339680..001dd63979a974802fe69b6e72b12fe79c7c1c6b 100644 --- a/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt +++ b/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt @@ -15,5 +15,4 @@ Example: rockchip,pmu = <&pmugrf>; clocks = <&cru PCLK_DDR_MON>; clock-names = "pclk_ddr_mon"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt index 7a9e8603c150805829485c639f0aee66a2c519be..d6d2833482c9b09ba1f7c664ea4952b8f2b63464 100644 --- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt +++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt @@ -205,5 +205,4 @@ Example: rockchip,phy_lpddr4_ck_cs_drv = ; rockchip,phy_lpddr4_dq_drv = ; rockchip,phy_lpddr4_odt = ; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/display/atmel,lcdc.txt b/Documentation/devicetree/bindings/display/atmel,lcdc.txt index ecb8da063d07b82350060ff3ce8f3af9df35a549..1a21202778ee354af7e5fc1f3d9ce65b0a7a964a 100644 --- a/Documentation/devicetree/bindings/display/atmel,lcdc.txt +++ b/Documentation/devicetree/bindings/display/atmel,lcdc.txt @@ -34,7 +34,6 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fb>; display = <&display0>; - status = "okay"; #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt index ec94468b35beca724152ab48c4f7630e3383ef2c..82f2acb3d37406d0916b2a202d3d28cc64c5fc06 100644 --- a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt +++ b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt @@ -23,7 +23,6 @@ Example: interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; clock-names = "periph_clk","sys_clk", "slow_clk"; - status = "disabled"; hlcdc-display-controller { compatible = "atmel,hlcdc-display-controller"; diff --git a/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt new file mode 100644 index 0000000000000000000000000000000000000000..b13adf30b8d3b4d21322a91baa8912bafc0083a1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt @@ -0,0 +1,32 @@ +Synopsys DesignWare MIPI DSI host controller +============================================ + +This document defines device tree properties for the Synopsys DesignWare MIPI +DSI host controller. It doesn't constitue a device tree binding specification +by itself but is meant to be referenced by platform-specific device tree +bindings. + +When referenced from platform device tree bindings the properties defined in +this document are defined as follows. The platform device tree bindings are +responsible for defining whether each optional property is used or not. + +- reg: Memory mapped base address and length of the DesignWare MIPI DSI + host controller registers. (mandatory) + +- clocks: References to all the clocks specified in the clock-names property + as specified in [1]. (mandatory) + +- clock-names: + - "pclk" is the peripheral clock for either AHB and APB. (mandatory) + - "px_clk" is the pixel clock for the DPI/RGB input. (optional) + +- resets: References to all the resets specified in the reset-names property + as specified in [2]. (optional) + +- reset-names: string reset name, must be "apb" if used. (optional) + +- panel or bridge node: see [3]. (mandatory) + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/reset/reset.txt +[3] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt diff --git a/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt b/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt index 7baa6582517e6d8844a245fbf1c58b15c36b2770..aacc8b92968c63670a62724c5cedf65eb49788cf 100644 --- a/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt +++ b/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt @@ -33,7 +33,6 @@ stdp2690-ge-b850v3-fw required properties: Example: &mux2_i2c2 { - status = "okay"; clock-frequency = <100000>; stdp4028@73 { diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt index 81b68580e19995e5c292ce70d9f5395d5e30d8c3..b1a8929c2536cc324a1d34073dabc2fe2ddf53cf 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt +++ b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt @@ -13,6 +13,7 @@ Required properties: - compatible : Shall contain one or more of - "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX + - "renesas,r8a7796-hdmi" for R8A7796 (R-Car M3-W) compatible HDMI TX - "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX When compatible with generic versions, nodes must list the SoC-specific @@ -43,7 +44,6 @@ Example: clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>; clock-names = "iahb", "isfr"; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; - status = "disabled"; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt index 549c538b38a5b7a9e31b8366a954d1a79d57edb6..fc2588292a68173347521e87ce80b9fa1b9ea19a 100644 --- a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt +++ b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt @@ -25,12 +25,6 @@ Required properties: size-cells must 1 and 0, respectively. - port: contains an endpoint node which is connected to the endpoint in the mic node. The reg value muset be 0. -- i80-if-timings: specify whether the panel which is connected to decon uses - i80 lcd interface or mipi video interface. This node contains - no timing information as that of fimd does. Because there is - no register in decon to specify i80 interface timing value, - it is not needed, but make it remain to use same kind of node - in fimd and exynos7 decon. Example: SoC specific DT entry: @@ -59,9 +53,3 @@ decon: decon@13800000 { }; }; }; - -Board specific DT entry: -&decon { - i80-if-timings { - }; -}; diff --git a/Documentation/devicetree/bindings/display/fsl,tcon.txt b/Documentation/devicetree/bindings/display/fsl,tcon.txt index 6fa4ab668db52f57e4e64e76ef68aabea2013dbe..475008747801e64ed3577d74d22d1a57dee2cb4f 100644 --- a/Documentation/devicetree/bindings/display/fsl,tcon.txt +++ b/Documentation/devicetree/bindings/display/fsl,tcon.txt @@ -14,5 +14,4 @@ timing-controller@4003d000 { reg = <0x4003d000 0x1000>; clocks = <&clks VF610_CLK_TCON0>; clock-names = "ipg"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt index fa01db7eb66c5d79b433a8c9294374a2bdcbad5a..f79854783c2c342655b37e1ffc31cb3cb3f2a02e 100644 --- a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt +++ b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt @@ -116,7 +116,7 @@ Parallel display support Required properties: - compatible: Should be "fsl,imx-parallel-display" Optional properties: -- interface_pix_fmt: How this display is connected to the +- interface-pix-fmt: How this display is connected to the display interface. Currently supported types: "rgb24", "rgb565", "bgr666" and "lvds666". - edid: verbatim EDID data block describing attached display. diff --git a/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt b/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt index 309c47f25b87f7a1f6b6e925cde6d52f096f891a..f79641bd5f18e013a69ff939aa81a3f8cb02de5f 100644 --- a/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt +++ b/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt @@ -23,7 +23,6 @@ Example: reg = <0x44000000 0x10000>; interrupts = <17>; clocks = <&clks CLK_LCD>; - status = "okay"; port { lcdc_out: endpoint { diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt b/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt index 5c70a8380e58d8d5d7854823baf53cb45ee69561..d0f55161579a55f6c83146929fb46b7ad40f7d96 100644 --- a/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt +++ b/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt @@ -18,6 +18,5 @@ Example: power-supply = <...>; backlight = <&backlight>; enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt index c6cb96a4fa939a5672b4770ba7f8673136cb0031..4bbd1e9bf3be40ee158be1e62a9be15167cec57c 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.txt +++ b/Documentation/devicetree/bindings/display/renesas,du.txt @@ -36,8 +36,10 @@ Required Properties: When supplied they must be named "dclkin.x" with "x" being the input clock numerical index. - - vsps: A list of phandles to the VSP nodes that handle the memory - interfaces for the DU channels. + - vsps: A list of phandle and channel index tuples to the VSPs that handle + the memory interfaces for the DU channels. The phandle identifies the VSP + instance that serves the DU channel, and the channel index identifies the + LIF instance in that VSP. Required nodes: @@ -59,24 +61,24 @@ corresponding to each DU output. R8A7796 (M3-W) DPAD HDMI LVDS - -Example: R8A7790 (R-Car H2) DU +Example: R8A7795 (R-Car H3) ES2.0 DU - du: du@feb00000 { - compatible = "renesas,du-r8a7790"; - reg = <0 0xfeb00000 0 0x70000>, - <0 0xfeb90000 0 0x1c>, - <0 0xfeb94000 0 0x1c>; - reg-names = "du", "lvds.0", "lvds.1"; - interrupt-parent = <&gic>; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>, - <0 269 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_DU0>, - <&mstp7_clks R8A7790_CLK_DU1>, - <&mstp7_clks R8A7790_CLK_DU2>, - <&mstp7_clks R8A7790_CLK_LVDS0>, - <&mstp7_clks R8A7790_CLK_LVDS1>; - clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1"; + du: display@feb00000 { + compatible = "renesas,du-r8a7795"; + reg = <0 0xfeb00000 0 0x80000>, + <0 0xfeb90000 0 0x14>; + reg-names = "du", "lvds.0"; + interrupts = , + , + , + ; + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 721>, + <&cpg CPG_MOD 727>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; + vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>; ports { #address-cells = <1>; @@ -89,12 +91,19 @@ Example: R8A7790 (R-Car H2) DU }; port@1 { reg = <1>; - du_out_lvds0: endpoint { + du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; }; }; port@2 { reg = <2>; - du_out_lvds1: endpoint { + du_out_hdmi1: endpoint { + remote-endpoint = <&dw_hdmi1_in>; + }; + }; + port@3 { + reg = <3>; + du_out_lvds0: endpoint { }; }; }; diff --git a/Documentation/devicetree/bindings/display/repaper.txt b/Documentation/devicetree/bindings/display/repaper.txt new file mode 100644 index 0000000000000000000000000000000000000000..f5f9f9cf6a25bf5ad4ed3022a4c6d71e45b66225 --- /dev/null +++ b/Documentation/devicetree/bindings/display/repaper.txt @@ -0,0 +1,52 @@ +Pervasive Displays RePaper branded e-ink displays + +Required properties: +- compatible: "pervasive,e1144cs021" for 1.44" display + "pervasive,e1190cs021" for 1.9" display + "pervasive,e2200cs021" for 2.0" display + "pervasive,e2271cs021" for 2.7" display + +- panel-on-gpios: Timing controller power control +- discharge-gpios: Discharge control +- reset-gpios: RESET pin +- busy-gpios: BUSY pin + +Required property for e2271cs021: +- border-gpios: Border control + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in ../spi/spi-bus.txt must be specified. + +Optional property: +- pervasive,thermal-zone: name of thermometer's thermal zone + +Example: + + display_temp: lm75@48 { + compatible = "lm75b"; + reg = <0x48>; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + display { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&display_temp>; + }; + }; + + papirus27@0{ + compatible = "pervasive,e2271cs021"; + reg = <0>; + + spi-max-frequency = <8000000>; + + panel-on-gpios = <&gpio 23 0>; + border-gpios = <&gpio 14 0>; + discharge-gpios = <&gpio 15 0>; + reset-gpios = <&gpio 24 0>; + busy-gpios = <&gpio 25 0>; + + pervasive,thermal-zone = "display"; + }; diff --git a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt index 47665a12786ffc31fcf5d187100a031528f18429..43561584c13af152655a7afb9dd2ddc65574ad76 100644 --- a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt @@ -59,7 +59,6 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&edp_hpd>; - status = "disabled"; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt index 046076c6b2775b8124da53ce4647094fe7e3c96c..adc94fc3c9f88543862821bbc0ac6f506f6cfc1c 100644 --- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt @@ -11,7 +11,9 @@ following device-specific properties. Required properties: -- compatible: Shall contain "rockchip,rk3288-dw-hdmi". +- compatible: should be one of the following: + "rockchip,rk3288-dw-hdmi" + "rockchip,rk3399-dw-hdmi" - reg: See dw_hdmi.txt. - reg-io-width: See dw_hdmi.txt. Shall be 4. - interrupts: HDMI interrupt number @@ -30,7 +32,8 @@ Optional properties I2C master controller. - clock-names: See dw_hdmi.txt. The "cec" clock is optional. - clock-names: May contain "cec" as defined in dw_hdmi.txt. - +- clock-names: May contain "grf", power for grf io. +- clock-names: May contain "vpll", external clock for some hdmi phy. Example: @@ -43,7 +46,6 @@ hdmi: hdmi@ff980000 { interrupts = ; clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>; clock-names = "iahb", "isfr"; - status = "disabled"; ports { hdmi_in: port { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt index 543b07435f4fc5246032a0b12b3a0898e4b5527d..6bb59ab39f2f1ac1ebd587b49408608e1f32f92c 100644 --- a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt @@ -36,7 +36,6 @@ Example: resets = <&cru SRST_MIPIDSI0>; reset-names = "apb"; rockchip,grf = <&grf>; - status = "okay"; ports { #address-cells = <1>; @@ -65,6 +64,5 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&lcd_en>; backlight = <&backlight>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt index 8096a29f9776aa133249a51ac4b2b3912d507fab..cec21714f0e0a32ca8fc2e6079887e255f91175c 100644 --- a/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt @@ -25,7 +25,6 @@ hdmi: hdmi@20034000 { clock-names = "pclk"; pinctrl-names = "default"; pinctrl-0 = <&hdmi_ctl>; - status = "disabled"; hdmi_in: port { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt index 9eb3f0a2a078b4e1f62d71daf123cf7d8363b683..5d835d9c1ba807540d1bc065640513ab092dea42 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt @@ -8,8 +8,12 @@ Required properties: - compatible: value should be one of the following "rockchip,rk3036-vop"; "rockchip,rk3288-vop"; + "rockchip,rk3368-vop"; + "rockchip,rk3366-vop"; "rockchip,rk3399-vop-big"; "rockchip,rk3399-vop-lit"; + "rockchip,rk3228-vop"; + "rockchip,rk3328-vop"; - interrupts: should contain a list of all VOP IP block interrupts in the order: VSYNC, LCD_SYSTEM. The interrupt specifier diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt b/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt index c46ba641a1df37f39241f68d2539302bfd389e2e..a9168ae6946c1d9f75993331ec24e7818f6e0a3c 100644 --- a/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt +++ b/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt @@ -28,6 +28,5 @@ chosen { allwinner,pipeline = "de_be0-lcd0-hdmi"; clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/display/sitronix,st7586.txt b/Documentation/devicetree/bindings/display/sitronix,st7586.txt new file mode 100644 index 0000000000000000000000000000000000000000..1d0dad1210d380849370738dbfb6a7b0e07773e8 --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7586.txt @@ -0,0 +1,22 @@ +Sitronix ST7586 display panel + +Required properties: +- compatible: "lego,ev3-lcd". +- a0-gpios: The A0 signal (since this binding is for serial mode, this is + the pin labeled D1 on the controller, not the pin labeled A0) +- reset-gpios: Reset pin + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in ../spi/spi-bus.txt must be specified. + +Optional properties: +- rotation: panel rotation in degrees counter clockwise (0,90,180,270) + +Example: + display@0{ + compatible = "lego,ev3-lcd"; + reg = <0>; + spi-max-frequency = <10000000>; + a0-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt index 8e1476941c0ff86b4ae4d032975f60e45616346d..74b5ac7b26d65278e7453301be2b8491e1c6668c 100644 --- a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt +++ b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt @@ -1,7 +1,6 @@ * STMicroelectronics STM32 lcd-tft display controller - ltdc: lcd-tft display controller host - must be a sub-node of st-display-subsystem Required properties: - compatible: "st,stm32-ltdc" - reg: Physical base address of the IP registers and length of memory mapped region. @@ -13,8 +12,40 @@ Required nodes: - Video port for RGB output. -Example: +* STMicroelectronics STM32 DSI controller specific extensions to Synopsys + DesignWare MIPI DSI host controller +The STMicroelectronics STM32 DSI controller uses the Synopsys DesignWare MIPI +DSI host controller. For all mandatory properties & nodes, please refer +to the related documentation in [5]. + +Mandatory properties specific to STM32 DSI: +- #address-cells: Should be <1>. +- #size-cells: Should be <0>. +- compatible: "st,stm32-dsi". +- clock-names: + - phy pll reference clock string name, must be "ref". +- resets: see [5]. +- reset-names: see [5]. + +Mandatory nodes specific to STM32 DSI: +- ports: A node containing DSI input & output port nodes with endpoint + definitions as documented in [3] & [4]. + - port@0: DSI input port node, connected to the ltdc rgb output port. + - port@1: DSI output port node, connected to a panel or a bridge input port. +- panel or bridge node: A node containing the panel or bridge description as + documented in [6]. + - port: panel or bridge port node, connected to the DSI output port (port@1). + +Note: You can find more documentation in the following references +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/reset/reset.txt +[3] Documentation/devicetree/bindings/media/video-interfaces.txt +[4] Documentation/devicetree/bindings/graph.txt +[5] Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt +[6] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt + +Example 1: RGB panel / { ... soc { @@ -34,3 +65,73 @@ Example: }; }; }; + +Example 2: DSI panel + +/ { + ... + soc { + ... + ltdc: display-controller@40016800 { + compatible = "st,stm32-ltdc"; + reg = <0x40016800 0x200>; + interrupts = <88>, <89>; + resets = <&rcc STM32F4_APB2_RESET(LTDC)>; + clocks = <&rcc 1 CLK_LCD>; + clock-names = "lcd"; + + port { + ltdc_out_dsi: endpoint { + remote-endpoint = <&dsi_in>; + }; + }; + }; + + + dsi: dsi@40016c00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-dsi"; + reg = <0x40016c00 0x800>; + clocks = <&rcc 1 CLK_F469_DSI>, <&clk_hse>; + clock-names = "ref", "pclk"; + resets = <&rcc STM32F4_APB2_RESET(DSI)>; + reset-names = "apb"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi_in: endpoint { + remote-endpoint = <<dc_out_dsi>; + }; + }; + + port@1 { + reg = <1>; + dsi_out: endpoint { + remote-endpoint = <&dsi_in_panel>; + }; + }; + + }; + + panel-dsi@0 { + reg = <0>; /* dsi virtual channel (0..3) */ + compatible = ...; + enable-gpios = ...; + + port { + dsi_in_panel: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + + }; + + }; + + }; +}; diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index b83e6018041d68d8fb0b552c3984233dab5b6d84..92441086cabad07cb9bfe44095cfbd605ef03e38 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -4,15 +4,33 @@ Allwinner A10 Display Pipeline The Allwinner A10 Display pipeline is composed of several components that are going to be documented below: -For the input port of all components up to the TCON in the display -pipeline, if there are multiple components, the local endpoint IDs -must correspond to the index of the upstream block. For example, if -the remote endpoint is Frontend 1, then the local endpoint ID must -be 1. - -Conversely, for the output ports of the same group, the remote endpoint -ID must be the index of the local hardware block. If the local backend -is backend 1, then the remote endpoint ID must be 1. +For all connections between components up to the TCONs in the display +pipeline, when there are multiple components of the same type at the +same depth, the local endpoint ID must be the same as the remote +component's index. For example, if the remote endpoint is Frontend 1, +then the local endpoint ID must be 1. + + Frontend 0 [0] ------- [0] Backend 0 [0] ------- [0] TCON 0 + [1] -- -- [1] [1] -- -- [1] + \ / \ / + X X + / \ / \ + [0] -- -- [0] [0] -- -- [0] + Frontend 1 [1] ------- [1] Backend 1 [1] ------- [1] TCON 1 + +For a two pipeline system such as the one depicted above, the lines +represent the connections between the components, while the numbers +within the square brackets corresponds to the ID of the local endpoint. + +The same rule also applies to DE 2.0 mixer-TCON connections: + + Mixer 0 [0] ----------- [0] TCON 0 + [1] ---- ---- [1] + \ / + X + / \ + [0] ---- ---- [0] + Mixer 1 [1] ----------- [1] TCON 1 HDMI Encoder ------------ @@ -260,7 +278,6 @@ hdmi: hdmi@01c16000 { <&dma SUN4I_DMA_NORMAL 16>, <&dma SUN4I_DMA_DEDICATED 24>; dma-names = "ddc-tx", "ddc-rx", "audio-tx"; - status = "disabled"; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt b/Documentation/devicetree/bindings/dma/fsl-edma.txt index 191d7bd8a6fefd412ce4e63f8e4e49401bcbbc82..97e213e07660816a2f81d19f400b104e09b1fe90 100644 --- a/Documentation/devicetree/bindings/dma/fsl-edma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt @@ -72,5 +72,4 @@ sai2: sai@40031000 { dma-names = "tx", "rx"; dmas = <&edma0 0 21>, <&edma0 0 20>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/dma/mv-xor.txt b/Documentation/devicetree/bindings/dma/mv-xor.txt index c075f5988135c75fa97c104b3e848b3f78b61242..0ffb4d8766a844a0bf82cf6fb08c2645ae6187e5 100644 --- a/Documentation/devicetree/bindings/dma/mv-xor.txt +++ b/Documentation/devicetree/bindings/dma/mv-xor.txt @@ -30,7 +30,6 @@ xor@d0060900 { reg = <0xd0060900 0x100 0xd0060b00 0x100>; clocks = <&coreclk 0>; - status = "okay"; xor00 { interrupts = <51>; diff --git a/Documentation/devicetree/bindings/dma/qcom_adm.txt b/Documentation/devicetree/bindings/dma/qcom_adm.txt index 9bcab911598200b159ef0c032a95d20990cffd53..9d3b2f917b7b31ea0c9ac6ff7e545b5324b77005 100644 --- a/Documentation/devicetree/bindings/dma/qcom_adm.txt +++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt @@ -48,7 +48,6 @@ Each dmas request consists of 3 cells: Example: spi4: spi@1a280000 { - status = "ok"; spi-max-frequency = <50000000>; pinctrl-0 = <&spi_pins>; diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt index 79a204d50234f287db233ce20b9c4300c7e206ec..891db41e94201ce69944133854eaedc97b9e672a 100644 --- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt +++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt @@ -25,6 +25,7 @@ Required Properties: - "renesas,dmac-r8a7794" (R-Car E2) - "renesas,dmac-r8a7795" (R-Car H3) - "renesas,dmac-r8a7796" (R-Car M3-W) + - "renesas,dmac-r8a77970" (R-Car V3M) - reg: base address and length of the registers block for the DMAC diff --git a/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt index e7780a186a36bc37c383f28f404e4d23916d1b9e..1be6941ac1e514cfd31ea0f6d4a44baaed5a7db2 100644 --- a/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt +++ b/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt @@ -8,6 +8,7 @@ Required Properties: - "renesas,r8a7793-usb-dmac" (R-Car M2-N) - "renesas,r8a7794-usb-dmac" (R-Car E2) - "renesas,r8a7795-usb-dmac" (R-Car H3) + - "renesas,r8a7796-usb-dmac" (R-Car M3-W) - reg: base address and length of the registers block for the DMAC - interrupts: interrupt specifiers for the DMAC, one for each entry in interrupt-names. diff --git a/Documentation/devicetree/bindings/dma/snps-dma.txt b/Documentation/devicetree/bindings/dma/snps-dma.txt index 4775c66f4508c5c0dbdd1091495bc7ff95dc584b..a122723907acb9be6fce0bd236eaa5e8f26191ca 100644 --- a/Documentation/devicetree/bindings/dma/snps-dma.txt +++ b/Documentation/devicetree/bindings/dma/snps-dma.txt @@ -63,7 +63,6 @@ Example: compatible = "arm,pl011", "arm,primecell"; reg = <0xe0000000 0x1000>; interrupts = <0 35 0x4>; - status = "disabled"; dmas = <&dmahost 12 0 1>, <&dmahost 13 0 1 0>; dma-names = "rx", "rx"; diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt index 495d853c569b7d2ed4d40dfc9534d8291edcd6b1..52cfec9e77ad528287f7ff18670802162d2a72cf 100644 --- a/Documentation/devicetree/bindings/dma/st_fdma.txt +++ b/Documentation/devicetree/bindings/dma/st_fdma.txt @@ -69,7 +69,6 @@ Example: sti_uni_player2: sti-uni-player@2 { compatible = "st,sti-uni-player"; - status = "disabled"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_PCM_2>; diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index 95800ab37bb00cce3fdfe2278625e6ba47cdec69..aa7dbd565ad0edddc0021b02c8f9d44e7f6b7438 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -135,5 +135,4 @@ Example: <&dma 13 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "rx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/dma/sun4i-dma.txt b/Documentation/devicetree/bindings/dma/sun4i-dma.txt index f1634a27a8300fc15de7fbff9a897ed987d7cd3b..3b484380c56a9ff468421667d5703bb29d1dc587 100644 --- a/Documentation/devicetree/bindings/dma/sun4i-dma.txt +++ b/Documentation/devicetree/bindings/dma/sun4i-dma.txt @@ -40,7 +40,6 @@ Example: clock-names = "ahb", "mod"; dmas = <&dma 1 29>, <&dma 1 28>; dma-names = "rx", "tx"; - status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt index 6b267045f5221c40524e9da19cf28bd1e2c3d8c6..98fbe1a5c6dd3d0cc366227eb2def392b797b4da 100644 --- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt +++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt @@ -9,6 +9,7 @@ Required properties: "allwinner,sun8i-a23-dma" "allwinner,sun8i-a83t-dma" "allwinner,sun8i-h3-dma" + "allwinner,sun8i-v3s-dma" - reg: Should contain the registers base address and length - interrupts: Should contain a reference to the interrupt used by this device - clocks: Should contain a reference to the parent AHB clock diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt index aead5869a28d9cbd71846caf6e94e7844adb9153..b849a1ed389d55df9662ca5708f8b93424b9ce88 100644 --- a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt +++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt @@ -62,7 +62,6 @@ uart1: serial@4806a000 { interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart1"; clock-frequency = <48000000>; - status = "disabled"; /* Requesting crossbar input 49 and 50 */ dmas = <&sdma_xbar 49>, <&sdma_xbar 50>; dma-names = "tx", "rx"; diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt index 18090e7226b40a063d8f32bfc6633edcba09dfee..41f0c1a07c562b754fd2324d7a41d9cb6df52158 100644 --- a/Documentation/devicetree/bindings/dma/ti-edma.txt +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -9,7 +9,12 @@ execute the actual DMA tansfer. eDMA3 Channel Controller Required properties: -- compatible: "ti,edma3-tpcc" for the channel controller(s) +-------------------- +- compatible: Should be: + - "ti,edma3-tpcc" for the channel controller(s) on OMAP, + AM33xx and AM43xx SoCs. + - "ti,k2g-edma3-tpcc", "ti,edma3-tpcc" for the + channel controller(s) on 66AK2G. - #dma-cells: Should be set to <2>. The first number is the DMA request number and the second is the TC the channel is serviced on. - reg: Memory map of eDMA CC @@ -19,8 +24,19 @@ Required properties: - ti,tptcs: List of TPTCs associated with the eDMA in the following form: <&tptc_phandle TC_priority_number>. The highest priority is 0. +SoC-specific Required properties: +-------------------------------- +The following are mandatory properties for OMAP, AM33xx and AM43xx SoCs only: +- ti,hwmods: Name of the hwmods associated to the eDMA CC. + +The following are mandatory properties for 66AK2G SoCs only: +- power-domains:Should contain a phandle to a PM domain provider node + and an args specifier containing the device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + Optional properties: -- ti,hwmods: Name of the hwmods associated to the eDMA CC +------------------- - ti,edma-memcpy-channels: List of channels allocated to be used for memcpy, iow these channels will be SW triggered channels. See example. - ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by @@ -31,17 +47,34 @@ Optional properties: eDMA3 Transfer Controller Required properties: -- compatible: "ti,edma3-tptc" for the transfer controller(s) +-------------------- +- compatible: Should be: + - "ti,edma3-tptc" for the transfer controller(s) on OMAP, + AM33xx and AM43xx SoCs. + - "ti,k2g-edma3-tptc", "ti,edma3-tptc" for the + transfer controller(s) on 66AK2G. - reg: Memory map of eDMA TC - interrupts: Interrupt number for TCerrint. +SoC-specific Required properties: +-------------------------------- +The following are mandatory properties for OMAP, AM33xx and AM43xx SoCs only: +- ti,hwmods: Name of the hwmods associated to the eDMA TC. + +The following are mandatory properties for 66AK2G SoCs only: +- power-domains:Should contain a phandle to a PM domain provider node + and an args specifier containing the device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + Optional properties: -- ti,hwmods: Name of the hwmods associated to the given eDMA TC +------------------- - interrupt-names: "edma3_tcerrint" ------------------------------------------------------------------------------ -Example: +Examples: +1. edma: edma@49000000 { compatible = "ti,edma3-tpcc"; ti,hwmods = "tpcc"; @@ -102,13 +135,64 @@ mcasp0: mcasp@48038000 { reg-names = "mpu", "dat"; interrupts = <80>, <81>; interrupt-names = "tx", "rx"; - status = "disabled"; /* DMA channels 8 and 9 executed on eDMA TC2 - high priority queue */ dmas = <&edma 8 2>, <&edma 9 2>; dma-names = "tx", "rx"; }; +2. +edma1: edma@02728000 { + compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; + reg = <0x02728000 0x8000>; + reg-names = "edma3_cc"; + interrupts = , + , + ; + interrupt-names = "edma3_ccint", "emda3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma1_tptc0 7>, <&edma1_tptc1 0>; + + /* + * memcpy is disabled, can be enabled with: + * ti,edma-memcpy-channels = <12 13 14 15>; + * for example. + */ + + power-domains = <&k2g_pds 0x4f>; +}; + +edma1_tptc0: tptc@027b0000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b0000 0x400>; + power-domains = <&k2g_pds 0x4f>; +}; + +edma1_tptc1: tptc@027b8000 { + compatible = "ti, k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b8000 0x400>; + power-domains = <&k2g_pds 0x4f>; +}; + +mmc0: mmc@23000000 { + compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc"; + reg = <0x23000000 0x400>; + interrupts = ; + dmas = <&edma1 24 0>, <&edma1 25 0>; + dma-names = "tx", "rx"; + bus-width = <4>; + ti,needs-special-reset; + no-1-8-v; + max-frequency = <96000000>; + power-domains = <&k2g_pds 0xb>; + clocks = <&k2g_clks 0xb 1>, <&k2g_clks 0xb 2>; + clock-names = "fck", "mmchsdb_fck"; + status = "disabled"; +}; + ------------------------------------------------------------------------------ DEPRECATED binding, new DTS files must use the ti,edma3-tpcc/ti,edma3-tptc binding. diff --git a/Documentation/devicetree/bindings/eeprom/eeprom.txt b/Documentation/devicetree/bindings/eeprom/eeprom.txt index 5696eb508e9568da3c99217756e1c3cd9c7da5fc..afc04589eadf35bbe2e339b79f07701225648140 100644 --- a/Documentation/devicetree/bindings/eeprom/eeprom.txt +++ b/Documentation/devicetree/bindings/eeprom/eeprom.txt @@ -16,8 +16,12 @@ Required properties: "renesas,r1ex24002" + The following manufacturers values have been deprecated: + "at", "at24" + If there is no specific driver for , a generic - driver based on is selected. Possible types are: + device with and manufacturer "atmel" should be used. + Possible types are: "24c00", "24c01", "24c02", "24c04", "24c08", "24c16", "24c32", "24c64", "24c128", "24c256", "24c512", "24c1024", "spd" diff --git a/Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.txt b/Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.txt new file mode 100644 index 0000000000000000000000000000000000000000..8e8625c00dfac9926743f0d3f8441519021797e5 --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.txt @@ -0,0 +1,24 @@ +ChromeOS EC USB Type-C cable and accessories detection + +On ChromeOS systems with USB Type C ports, the ChromeOS Embedded Controller is +able to detect the state of external accessories such as display adapters +or USB devices when said accessories are attached or detached. + +The node for this device must be under a cros-ec node like google,cros-ec-spi +or google,cros-ec-i2c. + +Required properties: +- compatible: Should be "google,extcon-usbc-cros-ec". +- google,usb-port-id: Specifies the USB port ID to use. + +Example: + cros-ec@0 { + compatible = "google,cros-ec-i2c"; + + ... + + extcon { + compatible = "google,extcon-usbc-cros-ec"; + google,usb-port-id = <0>; + }; + } diff --git a/Documentation/devicetree/bindings/fpga/altera-passive-serial.txt b/Documentation/devicetree/bindings/fpga/altera-passive-serial.txt new file mode 100644 index 0000000000000000000000000000000000000000..48478bc07e29c597e6e2c542c6caf3ee07197b6c --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/altera-passive-serial.txt @@ -0,0 +1,29 @@ +Altera Passive Serial SPI FPGA Manager + +Altera FPGAs support a method of loading the bitstream over what is +referred to as "passive serial". +The passive serial link is not technically SPI, and might require extra +circuits in order to play nicely with other SPI slaves on the same bus. + +See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf + +Required properties: +- compatible: Must be one of the following: + "altr,fpga-passive-serial", + "altr,fpga-arria10-passive-serial" +- reg: SPI chip select of the FPGA +- nconfig-gpios: config pin (referred to as nCONFIG in the manual) +- nstat-gpios: status pin (referred to as nSTATUS in the manual) + +Optional properties: +- confd-gpios: confd pin (referred to as CONF_DONE in the manual) + +Example: + fpga: fpga@0 { + compatible = "altr,fpga-passive-serial"; + spi-max-frequency = <20000000>; + reg = <0>; + nconfig-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + nstat-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + confd-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; + }; diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt new file mode 100644 index 0000000000000000000000000000000000000000..8dcfba926bc78c7d577ef0491a062b0c6e741ad9 --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt @@ -0,0 +1,36 @@ +Xilinx LogiCORE Partial Reconfig Decoupler Softcore + +The Xilinx LogiCORE Partial Reconfig Decoupler manages one or more +decouplers / fpga bridges. +The controller can decouple/disable the bridges which prevents signal +changes from passing through the bridge. The controller can also +couple / enable the bridges which allows traffic to pass through the +bridge normally. + +The Driver supports only MMIO handling. A PR region can have multiple +PR Decouplers which can be handled independently or chained via decouple/ +decouple_status signals. + +Required properties: +- compatible : Should contain "xlnx,pr-decoupler-1.00" followed by + "xlnx,pr-decoupler" +- regs : base address and size for decoupler module +- clocks : input clock to IP +- clock-names : should contain "aclk" + +Optional properties: +- bridge-enable : 0 if driver should disable bridge at startup + 1 if driver should enable bridge at startup + Default is to leave bridge in current state. + +See Documentation/devicetree/bindings/fpga/fpga-region.txt for generic bindings. + +Example: + fpga-bridge@100000450 { + compatible = "xlnx,pr-decoupler-1.00", + "xlnx-pr-decoupler"; + regs = <0x10000045 0x10>; + clocks = <&clkc 15>; + clock-names = "aclk"; + bridge-enable = <0>; + }; diff --git a/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt b/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt index 9766f7472f512fec9652fb15d8d74f1f1f5133c7..cfa4ed42b62f9bad7d4a5dd56f69b2eca94f4639 100644 --- a/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt +++ b/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt @@ -31,7 +31,6 @@ Example for full FPGA configuration: cell-index = <1>; interrupts = <92>; clocks = <&coreclk 0>; - status = "okay"; fpga_mgr_spi: fpga-mgr@0 { compatible = "xlnx,fpga-slave-serial"; diff --git a/Documentation/devicetree/bindings/gpio/gpio-74x164.txt b/Documentation/devicetree/bindings/gpio/gpio-74x164.txt index ce1b2231bf5dbf5ed0ca0703c51ba95a2202098b..2a97553d8d76d9f5d42452eda2f979f94752ead4 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-74x164.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-74x164.txt @@ -12,6 +12,9 @@ Required properties: 1 = active low - registers-number: Number of daisy-chained shift registers +Optional properties: +- enable-gpios: GPIO connected to the OE (Output Enable) pin. + Example: gpio5: gpio5@0 { diff --git a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt index c756afa88cc62359323cfe3f0cc1171a31e955f4..fc6378c778c55b3f0fe7d8f2bff1826060ff9ef5 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt @@ -18,7 +18,7 @@ Required properties: Optional properties: - interrupt-parent : The parent interrupt controller, optional if inherited -- clocks : A phandle to the HPLL clock node for debounce timings +- clocks : A phandle to the clock to use for debounce timings The gpio and interrupt properties are further described in their respective bindings documentation: diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt index 5079ba7d65681dfa0b48a3874de414fec9a99189..8beb0539b6d84b3cdf7ebb1b77f1a598e7c91151 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt @@ -1,7 +1,10 @@ Davinci/Keystone GPIO controller bindings Required Properties: -- compatible: should be "ti,dm6441-gpio", "ti,keystone-gpio" +- compatible: should be "ti,dm6441-gpio": for Davinci da850 SoCs + "ti,keystone-gpio": for Keystone 2 66AK2H/K, 66AK2L, + 66AK2E SoCs + "ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G - reg: Physical base address of the controller and the size of memory mapped registers. @@ -20,7 +23,21 @@ Required Properties: - ti,ngpio: The number of GPIO pins supported. - ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt - line to processor. + line to processor. + +- clocks: Should contain the device's input clock, and should be defined as per + the appropriate clock bindings consumer usage in, + + Documentation/devicetree/bindings/clock/keystone-gate.txt + for 66AK2HK/66AK2L/66AK2E SoCs or, + + Documentation/devicetree/bindings/clock/ti,sci-clk.txt + for 66AK2G SoCs + +- clock-names: Name should be "gpio"; + +Currently clock-names and clocks are needed for all keystone 2 platforms +Davinci platforms do not have DT clocks as of now. The GPIO controller also acts as an interrupt controller. It uses the default two cells specifier as described in Documentation/devicetree/bindings/ @@ -60,3 +77,73 @@ leds { ... }; }; + +Example for 66AK2G: + +gpio0: gpio@2603000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x02603000 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k2g_clks 0x001b 0x0>; + clock-names = "gpio"; +}; + +Example for 66AK2HK/66AK2L/66AK2E: + +gpio0: gpio@260bf00 { + compatible = "ti,keystone-gpio"; + reg = <0x0260bf00 0x100>; + gpio-controller; + #gpio-cells = <2>; + /* HW Interrupts mapped to GPIO pins */ + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + clocks = <&clkgpio>; + clock-names = "gpio"; + ti,ngpio = <32>; + ti,davinci-gpio-unbanked = <32>; +}; diff --git a/Documentation/devicetree/bindings/gpio/gpio-exar.txt b/Documentation/devicetree/bindings/gpio/gpio-exar.txt new file mode 100644 index 0000000000000000000000000000000000000000..4540d61824af8a3d9cccb33398876570d66fd6ab --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-exar.txt @@ -0,0 +1,5 @@ +Exportable MPIO interface of Exar UART chips + +Required properties of the device: + - exar,first-pin: first exportable pins (0..15) + - ngpios: number of exportable pins (1..16) diff --git a/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt b/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt index 4b6cc632ca5c53f38a98d23c22aca05e0d078781..69d46162d0f5ba385da868a0ce9240e2b34b06ee 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt @@ -23,7 +23,6 @@ gpio0: gpio@1100 { #gpio-cells = <2>; reg = <0x1100 0x080>; interrupts = <78 0x8>; - status = "okay"; }; Example of gpio-controller node for a ls2080a SoC: diff --git a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt index 436cc99c659832253cd7feb2358135e1da05c858..0ccbae44019cca07ce6627ebd5ed5f496d4b879d 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt @@ -5,7 +5,9 @@ functionality. Each pair serves 32 GPIOs. The VF610 has 5 instances of each, and each PORT module has its own interrupt. Required properties for GPIO node: -- compatible : Should be "fsl,-gpio", currently "fsl,vf610-gpio" +- compatible : Should be "fsl,-gpio", below is supported list: + "fsl,vf610-gpio" + "fsl,imx7ulp-gpio" - reg : The first reg tuple represents the PORT module, the second tuple the GPIO module. - interrupts : Should be the port interrupt shared by all 32 pins. diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt index 6826a371fb696a13742aad215d0986702b69b330..51c86f69995e5441875d89adff4e9e4f137819d2 100644 --- a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt +++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt @@ -2,8 +2,9 @@ Required Properties: - - compatible: should contain one of the following. + - compatible: should contain one or more of the following: - "renesas,gpio-r8a7743": for R8A7743 (RZ/G1M) compatible GPIO controller. + - "renesas,gpio-r8a7745": for R8A7745 (RZ/G1E) compatible GPIO controller. - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller. - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller. @@ -13,7 +14,14 @@ Required Properties: - "renesas,gpio-r8a7794": for R8A7794 (R-Car E2) compatible GPIO controller. - "renesas,gpio-r8a7795": for R8A7795 (R-Car H3) compatible GPIO controller. - "renesas,gpio-r8a7796": for R8A7796 (R-Car M3-W) compatible GPIO controller. - - "renesas,gpio-rcar": for generic R-Car GPIO controller. + - "renesas,rcar-gen1-gpio": for a generic R-Car Gen1 GPIO controller. + - "renesas,rcar-gen2-gpio": for a generic R-Car Gen2 or RZ/G1 GPIO controller. + - "renesas,rcar-gen3-gpio": for a generic R-Car Gen3 GPIO controller. + - "renesas,gpio-rcar": deprecated. + + When compatible with the generic version nodes must list the + SoC-specific version corresponding to the platform first followed by + the generic version. - reg: Base address and length of each memory resource used by the GPIO controller hardware module. @@ -43,7 +51,7 @@ interrupt-controller/interrupts.txt. Example: R8A7779 (R-Car H1) GPIO controller nodes gpio0: gpio@ffc40000 { - compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; + compatible = "renesas,gpio-r8a7779", "renesas,rcar-gen1-gpio"; reg = <0xffc40000 0x2c>; interrupt-parent = <&gic>; interrupts = <0 141 0x4>; @@ -55,7 +63,7 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes }; ... gpio6: gpio@ffc46000 { - compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; + compatible = "renesas,gpio-r8a7779", "renesas,rcar-gen1-gpio"; reg = <0xffc46000 0x2c>; interrupt-parent = <&gic>; interrupts = <0 147 0x4>; diff --git a/Documentation/devicetree/bindings/gpio/spear_spics.txt b/Documentation/devicetree/bindings/gpio/spear_spics.txt index 96c37eb15075c35d8f4cd2942aa91b97167ffa08..dd04d96e6ff1596d7c69ab0c94f9d389ab72137a 100644 --- a/Documentation/devicetree/bindings/gpio/spear_spics.txt +++ b/Documentation/devicetree/bindings/gpio/spear_spics.txt @@ -42,7 +42,6 @@ spics: spics@e0700000{ spi0: spi@e0100000 { - status = "okay"; num-cs = <3>; cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>; diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt index d3b6e1a4713a58d00692ab8bf2ae74f1956a40e3..039219df05c5f69836a39bac48bac64ce33d476a 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt @@ -17,6 +17,7 @@ Required properties: * which must be preceded by one of the following vendor specifics: + "amlogic,meson-gxm-mali" + "rockchip,rk3288-mali" + + "rockchip,rk3399-mali" - reg : Physical base address of the device and length of the register area. @@ -40,7 +41,7 @@ Optional properties: Example for a Mali-T760: gpu@ffa30000 { - compatible = "rockchip,rk3288-mali", "arm,mali-t760", "arm,mali-midgard"; + compatible = "rockchip,rk3288-mali", "arm,mali-t760"; reg = <0xffa30000 0x10000>; interrupts = , , diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt index 2b6243e730f690f9bbf2f0c50295b91c0699129f..b4ebd56d03f340a9e16752daedad188674ff4564 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt +++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt @@ -10,6 +10,7 @@ Required properties: * And, optionally, one of the vendor specific compatible: + allwinner,sun4i-a10-mali + allwinner,sun7i-a20-mali + + allwinner,sun50i-h5-mali + amlogic,meson-gxbb-mali + amlogic,meson-gxl-mali + stericsson,db8500-mali @@ -58,6 +59,10 @@ to specify one more vendor-specific compatible, among: Required properties: * resets: phandle to the reset line for the GPU + - allwinner,sun50i-h5-mali + Required properties: + * resets: phandle to the reset line for the GPU + - stericsson,db8500-mali Required properties: * interrupt-names and interrupts: diff --git a/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt b/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt index b7e4c74445108dcd2c966529a85a4a930b40e831..f32bbba4d3bca902242049fabd1a2d92eca36cc5 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt @@ -51,7 +51,6 @@ Example for GK20A: resets = <&tegra_car 184>; reset-names = "gpu"; iommus = <&mc TEGRA_SWGROUP_GPU>; - status = "disabled"; }; Example for GM20B: @@ -70,7 +69,6 @@ Example for GM20B: resets = <&tegra_car 184>; reset-names = "gpu"; iommus = <&mc TEGRA_SWGROUP_GPU>; - status = "disabled"; }; Example for GP10B: @@ -89,5 +87,4 @@ Example for GP10B: reset-names = "gpu"; power-domains = <&bpmp TEGRA186_POWER_DOMAIN_GPU>; iommus = <&smmu TEGRA186_SID_GPU>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/gpu/samsung-g2d.txt b/Documentation/devicetree/bindings/gpu/samsung-g2d.txt index c4f358dafdaa58c8a2d2c197789cf740a802202d..1e7959332dbcb2bff6954e35b401d307b202e4af 100644 --- a/Documentation/devicetree/bindings/gpu/samsung-g2d.txt +++ b/Documentation/devicetree/bindings/gpu/samsung-g2d.txt @@ -24,5 +24,4 @@ Example: interrupts = <0 89 0>; clocks = <&clock 177>, <&clock 277>; clock-names = "sclk_fimg2d", "fimg2d"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/hsi/omap-ssi.txt b/Documentation/devicetree/bindings/hsi/omap-ssi.txt index f26625e4269363355d8e402299b3d3a91b88b793..b8eca3c7810dfb0ca184339537cd1e3e43383ac2 100644 --- a/Documentation/devicetree/bindings/hsi/omap-ssi.txt +++ b/Documentation/devicetree/bindings/hsi/omap-ssi.txt @@ -92,6 +92,5 @@ ssi-controller@48058000 { interrupts = <69>, <70>; - status = "disabled"; /* second port is not used on N900 */ } } diff --git a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt index cf4460564adb20941f127008fdb0ec235dc5f7ff..367c8203213b198bd9bf3deeaa4389b430951475 100644 --- a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt +++ b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt @@ -11,6 +11,8 @@ Required properties for pwm-tacho node: - #size-cells : should be 1. +- #cooling-cells: should be 2. + - reg : address and length of the register set for the device. - pinctrl-names : a pinctrl state named "default" must be defined. @@ -28,12 +30,17 @@ fan subnode format: Under fan subnode there can upto 8 child nodes, with each child node representing a fan. If there are 8 fans each fan can have one PWM port and one/two Fan tach inputs. +For PWM port can be configured cooling-levels to create cooling device. +Cooling device could be bound to a thermal zone for the thermal control. Required properties for each child node: - reg : should specify PWM source port. integer value in the range 0 to 7 with 0 indicating PWM port A and 7 indicating PWM port H. +- cooling-levels: PWM duty cycle values in a range from 0 to 255 + which correspond to thermal cooling states. + - aspeed,fan-tach-ch : should specify the Fan tach input channel. integer value in the range 0 through 15, with 0 indicating Fan tach channel 0 and 15 indicating Fan tach channel 15. @@ -50,6 +57,7 @@ pwm_tacho_fixed_clk: fixedclk { pwm_tacho: pwmtachocontroller@1e786000 { #address-cells = <1>; #size-cells = <1>; + #cooling-cells = <2>; reg = <0x1E786000 0x1000>; compatible = "aspeed,ast2500-pwm-tacho"; clocks = <&pwm_tacho_fixed_clk>; @@ -58,6 +66,7 @@ pwm_tacho: pwmtachocontroller@1e786000 { fan@0 { reg = <0x00>; + cooling-levels = /bits/ 8 <125 151 177 203 229 255>; aspeed,fan-tach-ch = /bits/ 8 <0x00>; }; diff --git a/Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt b/Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt new file mode 100644 index 0000000000000000000000000000000000000000..f68a0a68fc524cdc1ee547313892a34e78248800 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt @@ -0,0 +1,21 @@ +Device-tree bindings for IBM Common Form Factor Power Supply Version 1 +---------------------------------------------------------------------- + +Required properties: + - compatible = "ibm,cffps1"; + - reg = < I2C bus address >; : Address of the power supply on the + I2C bus. + +Example: + + i2c-bus@100 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + < more properties > + + power-supply@68 { + compatible = "ibm,cffps1"; + reg = <0x68>; + }; + }; diff --git a/Documentation/devicetree/bindings/hwmon/ltq-cputemp.txt b/Documentation/devicetree/bindings/hwmon/ltq-cputemp.txt new file mode 100644 index 0000000000000000000000000000000000000000..33fd00a987c7d924cd7b1b67970c2c6ee9100b79 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ltq-cputemp.txt @@ -0,0 +1,10 @@ +Lantiq cpu temperatur sensor + +Requires node properties: +- compatible value : + "lantiq,cputemp" + +Example: + cputemp@0 { + compatible = "lantiq,cputemp"; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-altera.txt b/Documentation/devicetree/bindings/i2c/i2c-altera.txt new file mode 100644 index 0000000000000000000000000000000000000000..767664f448ece3315dc376f33ad0fdaef5ecb23d --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-altera.txt @@ -0,0 +1,39 @@ +* Altera I2C Controller +* This is Altera's synthesizable logic block I2C Controller for use +* in Altera's FPGAs. + +Required properties : + - compatible : should be "altr,softip-i2c-v1.0" + - reg : Offset and length of the register set for the device + - interrupts : where IRQ is the interrupt number. + - clocks : phandle to input clock. + - #address-cells = <1>; + - #size-cells = <0>; + +Recommended properties : + - clock-frequency : desired I2C bus clock frequency in Hz. + +Optional properties : + - fifo-size : Size of the RX and TX FIFOs in bytes. + - Child nodes conforming to i2c bus binding + +Example : + + i2c@100080000 { + compatible = "altr,softip-i2c-v1.0"; + reg = <0x00000001 0x00080000 0x00000040>; + interrupt-parent = <&intc>; + interrupts = <0 43 4>; + clocks = <&clk_0>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + fifo-size = <4>; + + eeprom@51 { + compatible = "atmel,24c32"; + reg = <0x51>; + pagesize = <32>; + }; + }; + diff --git a/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt index 8ce9cd2855b5cf11dfcd61a227b68568e5e33d49..c143948b2a37fc31b9aa7cc200bb82ff0a839787 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt @@ -20,8 +20,8 @@ i2c@0 { #address-cells = <1>; #size-cells = <0>; - retu-mfd: retu@1 { - compatible = "retu-mfd"; + retu: retu@1 { + compatible = "nokia,retu"; reg = <0x1>; }; }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt index 7ce23ac6130808da6a7f621f1991b13f17f185d6..81b5d55086fa60a0118047ee9bec880c9cc8250a 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt @@ -102,7 +102,6 @@ And for clarification, here are the snipplets for the i2c-parents: #address-cells = <1>; #size-cells = <0>; compatible = "i2c-gpio"; - status = "disabled"; gpios = <&gpio5 6 GPIO_ACTIVE_HIGH /* sda */ &gpio5 5 GPIO_ACTIVE_HIGH /* scl */ >; diff --git a/Documentation/devicetree/bindings/i2c/i2c-efm32.txt b/Documentation/devicetree/bindings/i2c/i2c-efm32.txt index 50b25c3da186e0f625c2715d123509820a8c98c1..3b30e54ae3c7a2aefb1afd760e623c132a4a5ce8 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-efm32.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-efm32.txt @@ -22,7 +22,6 @@ Example: interrupts = <9>; clocks = <&cmu clk_HFPERCLKI2C0>; clock-frequency = <100000>; - status = "ok"; energymicro,location = <3>; eeprom@50 { diff --git a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt index bd5a7befd951f38314320e7c801b946dfdf7f3c7..ff7bf37deb43e241746a6cfa1105d22a8c72651d 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt @@ -1,14 +1,15 @@ -* Mediatek's I2C controller +* MediaTek's I2C controller -The Mediatek's I2C controller is used to interface with I2C devices. +The MediaTek's I2C controller is used to interface with I2C devices. Required properties: - compatible: value should be either of the following. - "mediatek,mt2701-i2c", "mediatek,mt6577-i2c": for Mediatek mt2701 - "mediatek,mt6577-i2c": for i2c compatible with mt6577. - "mediatek,mt6589-i2c": for i2c compatible with mt6589. - "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for i2c compatible with mt7623. - "mediatek,mt8173-i2c": for i2c compatible with mt8173. + "mediatek,mt2701-i2c", "mediatek,mt6577-i2c": for MediaTek MT2701 + "mediatek,mt6577-i2c": for MediaTek MT6577 + "mediatek,mt6589-i2c": for MediaTek MT6589 + "mediatek,mt7622-i2c": for MediaTek MT7622 + "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for MediaTek MT7623 + "mediatek,mt8173-i2c": for MediaTek MT8173 - reg: physical base address of the controller and dma base, length of memory mapped region. - interrupts: interrupt number to the cpu. diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index 2b8bd33dbf8d7545c0e4e5b73c01b6d94e79b84a..cad39aee9f73b99b8006029dfd52c52289d78f15 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -2,6 +2,8 @@ I2C for R-Car platforms Required properties: - compatible: + "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC. + "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC. "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC. "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC. "renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC. @@ -12,7 +14,8 @@ Required properties: "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC. "renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC. "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device. - "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 compatible device. + "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible + device. "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 compatible device. "renesas,i2c-rcar" (deprecated) diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt index e18445d0980cc6ab5d2b0d6b3b10fb35e6d3cff3..22f2eeb2c4c93a69e82d1742a902c8820b04e8fe 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt @@ -7,6 +7,7 @@ Required properties : - reg : Offset and length of the register set for the device - compatible: should be one of the following: + - "rockchip,rv1108-i2c": for rv1108 - "rockchip,rk3066-i2c": for rk3066 - "rockchip,rk3188-i2c": for rk3188 - "rockchip,rk3228-i2c": for rk3228 diff --git a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt index ae9c2a735f39fd3ff0a6bd945d5ba64fba470afd..224390999e817f333ca1606a21ce218ab896fe0b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt @@ -4,6 +4,8 @@ Required properties: - compatible : - "renesas,iic-r8a73a4" (R-Mobile APE6) - "renesas,iic-r8a7740" (R-Mobile A1) + - "renesas,iic-r8a7743" (RZ/G1M) + - "renesas,iic-r8a7745" (RZ/G1E) - "renesas,iic-r8a7790" (R-Car H2) - "renesas,iic-r8a7791" (R-Car M2-W) - "renesas,iic-r8a7792" (R-Car V2H) @@ -12,7 +14,8 @@ Required properties: - "renesas,iic-r8a7795" (R-Car H3) - "renesas,iic-r8a7796" (R-Car M3-W) - "renesas,iic-sh73a0" (SH-Mobile AG5) - - "renesas,rcar-gen2-iic" (generic R-Car Gen2 compatible device) + - "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1 + compatible device) - "renesas,rcar-gen3-iic" (generic R-Car Gen3 compatible device) - "renesas,rmobile-iic" (generic device) diff --git a/Documentation/devicetree/bindings/i2c/i2c-sprd.txt b/Documentation/devicetree/bindings/i2c/i2c-sprd.txt new file mode 100644 index 0000000000000000000000000000000000000000..60b7cda15dd2b2badabcdae29a60cefa92cdc24a --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-sprd.txt @@ -0,0 +1,31 @@ +I2C for Spreadtrum platforms + +Required properties: +- compatible: Should be "sprd,sc9860-i2c". +- reg: Specify the physical base address of the controller and length + of memory mapped region. +- interrupts: Should contain I2C interrupt. +- clock-names: Should contain following entries: + "i2c" for I2C clock, + "source" for I2C source (parent) clock, + "enable" for I2C module enable clock. +- clocks: Should contain a clock specifier for each entry in clock-names. +- clock-frequency: Constains desired I2C bus clock frequency in Hz. +- #address-cells: Should be 1 to describe address cells for I2C device address. +- #size-cells: Should be 0 means no size cell for I2C device address. + +Optional properties: +- Child nodes conforming to I2C bus binding + +Examples: +i2c0: i2c@70500000 { + compatible = "sprd,sc9860-i2c"; + reg = <0 0x70500000 0 0x1000>; + interrupts = ; + clock-names = "i2c", "source", "enable"; + clocks = <&clk_i2c3>, <&ext_26m>, <&clk_ap_apb_gates 11>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; +}; + diff --git a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt index 78eaf7b718eddc764385357449cffa835c3c0d97..3b54899666342b8e5a114bc0842e193871139d5e 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt @@ -1,7 +1,9 @@ * I2C controller embedded in STMicroelectronics STM32 I2C platform Required properties : -- compatible : Must be "st,stm32f4-i2c" +- compatible : Must be one of the following + - "st,stm32f4-i2c" + - "st,stm32f7-i2c" - reg : Offset and length of the register set for the device - interrupts : Must contain the interrupt id for I2C event and then the interrupt id for I2C error. @@ -14,8 +16,16 @@ Required properties : Optional properties : - clock-frequency : Desired I2C bus clock frequency in Hz. If not specified, - the default 100 kHz frequency will be used. As only Normal and Fast modes - are supported, possible values are 100000 and 400000. + the default 100 kHz frequency will be used. + For STM32F4 SoC Standard-mode and Fast-mode are supported, possible values are + 100000 and 400000. + For STM32F7 SoC, Standard-mode, Fast-mode and Fast-mode Plus are supported, + possible values are 100000, 400000 and 1000000. +- i2c-scl-rising-time-ns : Only for STM32F7, I2C SCL Rising time for the board + (default: 25) +- i2c-scl-falling-time-ns : Only for STM32F7, I2C SCL Falling time for the board + (default: 10) + I2C Timings are derived from these 2 values Example : @@ -31,3 +41,16 @@ Example : pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; pinctrl-names = "default"; }; + + i2c@40005400 { + compatible = "st,stm32f7-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40005400 0x400>; + interrupts = <31>, + <32>; + resets = <&rcc STM32F7_APB1_RESET(I2C1)>; + clocks = <&rcc 1 CLK_I2C1>; + pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; + pinctrl-names = "default"; + }; diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt index 656716b72cc4d53362d997040339c4a5e45a13cb..f64064f8bdc25e5f0ee52c024fa1e2b8e36b8a5b 100644 --- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt +++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt @@ -71,5 +71,4 @@ Example: reset-names = "i2c"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt index 3223684a643b81791454ee48b250a5fba4cb094a..552e7a83951d774bacb1b9e0211b72b766bbb7fa 100644 --- a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt @@ -11,6 +11,11 @@ Required properties: - atmel,min-sample-rate-hz: Minimum sampling rate, it depends on SoC. - atmel,max-sample-rate-hz: Maximum sampling rate, it depends on SoC. - atmel,startup-time-ms: Startup time expressed in ms, it depends on SoC. + - atmel,trigger-edge-type: One of possible edge types for the ADTRG hardware + trigger pin. When the specific edge type is detected, the conversion will + start. Possible values are rising, falling, or both. + This property uses the IRQ edge types values: IRQ_TYPE_EDGE_RISING , + IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_BOTH Example: @@ -25,4 +30,5 @@ adc: adc@fc030000 { atmel,startup-time-ms = <4>; vddana-supply = <&vdd_3v3_lp_reg>; vref-supply = <&vdd_3v3_lp_reg>; + atmel,trigger-edge-type = ; } diff --git a/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt b/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt index caaaed765ce4314977754eeb7edfe0da75418bfa..7b1b1e4086d4f1eb11a12bfba7a256e1aba86727 100644 --- a/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt @@ -37,5 +37,4 @@ For example: clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>; clock-names = "tsc_clk"; interrupts = ; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt index 0bcae5140bc568b06b7a12a0f3a2d8ceb5f7b010..9ada5abd45fa05401cb9611d456a095583c07e53 100644 --- a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt @@ -17,5 +17,4 @@ adc0: adc@400e3000 { clocks = <&ccu1 CLK_APB3_ADC0>; vref-supply = <®_vdda>; resets = <&rgu 40>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt b/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt index 68c45cbbe3d9f7dcc04c0a00b5d3622273dcef4b..64dc4843c1803a261c6d68efff75ab6cd86608b3 100644 --- a/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt +++ b/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt @@ -12,6 +12,7 @@ for the Thermal Controller which holds a phandle to the AUXADC. Required properties: - compatible: Should be one of: - "mediatek,mt2701-auxadc": For MT2701 family of SoCs + - "mediatek,mt7622-auxadc": For MT7622 family of SoCs - "mediatek,mt8173-auxadc": For MT8173 family of SoCs - reg: Address range of the AUXADC unit. - clocks: Should contain a clock specifier for each entry in clock-names diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt index e0a9b9d6d6fdc1b84f74a81fe9516fb343be3c9e..c2c50b59873d8b2ec69a4d7084ce8e8addb87a31 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt @@ -6,6 +6,7 @@ Required properties: - "rockchip,rk3066-tsadc": for rk3036 - "rockchip,rk3328-saradc", "rockchip,rk3399-saradc": for rk3328 - "rockchip,rk3399-saradc": for rk3399 + - "rockchip,rv1108-saradc", "rockchip,rk3399-saradc": for rv1108 - reg: physical base address of the controller and length of memory mapped region. diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt index 8310073f14e1370b6d937675f5ff60c83e751da9..48bfcaa3ffcdd6e04e4acb8c60c62344e1b677fc 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt @@ -74,6 +74,11 @@ Optional properties: * can be 6, 8, 10 or 12 on stm32f4 * can be 8, 10, 12, 14 or 16 on stm32h7 Default is maximum resolution if unset. +- st,min-sample-time-nsecs: Minimum sampling time in nanoseconds. + Depending on hardware (board) e.g. high/low analog input source impedance, + fine tune of ADC sampling time may be recommended. + This can be either one value or an array that matches 'st,adc-channels' list, + to set sample time resp. for all channels, or independently for each channel. Example: adc: adc@40012000 { diff --git a/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt b/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt new file mode 100644 index 0000000000000000000000000000000000000000..a04aa5c041034369b340d0a7ebbf28bf28da883c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt @@ -0,0 +1,27 @@ +STMicroelectronics STM32 Low-Power Timer quadrature encoder and counter + +STM32 Low-Power Timer provides several counter modes. It can be used as: +- quadrature encoder to detect angular position and direction of rotary + elements, from IN1 and IN2 input signals. +- simple counter from IN1 input signal. + +Must be a sub-node of an STM32 Low-Power Timer device tree node. +See ../mfd/stm32-lptimer.txt for details about the parent node. + +Required properties: +- compatible: Must be "st,stm32-lptimer-counter". +- pinctrl-names: Set to "default". +- pinctrl-0: List of phandles pointing to pin configuration nodes, + to set IN1/IN2 pins in mode of operation for Low-Power + Timer input on external pin. + +Example: + timer@40002400 { + compatible = "st,stm32-lptimer"; + ... + counter { + compatible = "st,stm32-lptimer-counter"; + pinctrl-names = "default"; + pinctrl-0 = <&lptim1_in_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt b/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt index 7d6647d4af5e4353c8acb630a3a99b64385001c8..42db783c4e7552b4e3eab7cc34fce4ec340413aa 100644 --- a/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt +++ b/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt @@ -16,5 +16,4 @@ dac: dac@400e1000 { clocks = <&ccu1 CLK_APB3_DAC>; vref-supply = <®_vdda>; resets = <&rgu 42>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt b/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt index bcee71f808d00d96dac04954f7ba464282460236..bf2925c671c68f7a357e4a0f125af6713c4956aa 100644 --- a/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt +++ b/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt @@ -10,7 +10,9 @@ current. Contents of a stm32 dac root node: ----------------------------------- Required properties: -- compatible: Must be "st,stm32h7-dac-core". +- compatible: Should be one of: + "st,stm32f4-dac-core" + "st,stm32h7-dac-core" - reg: Offset and length of the device's register set. - clocks: Must contain an entry for pclk (which feeds the peripheral bus interface) diff --git a/Documentation/devicetree/bindings/iio/humidity/hdc100x.txt b/Documentation/devicetree/bindings/iio/humidity/hdc100x.txt new file mode 100644 index 0000000000000000000000000000000000000000..c52333bdfd1997384f0fde55b5b7512af0b531fc --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/hdc100x.txt @@ -0,0 +1,17 @@ +* HDC100x temperature + humidity sensors + +Required properties: + - compatible: Should contain one of the following: + ti,hdc1000 + ti,hdc1008 + ti,hdc1010 + ti,hdc1050 + ti,hdc1080 + - reg: i2c address of the sensor + +Example: + +hdc100x@40 { + compatible = "ti,hdc1000"; + reg = <0x40>; +}; diff --git a/Documentation/devicetree/bindings/iio/humidity/hts221.txt b/Documentation/devicetree/bindings/iio/humidity/hts221.txt index b20ab9c12080e74877937c4b90c5955c283941a1..10adeb0d703d486694468ae15ea906849a8afaa9 100644 --- a/Documentation/devicetree/bindings/iio/humidity/hts221.txt +++ b/Documentation/devicetree/bindings/iio/humidity/hts221.txt @@ -5,9 +5,18 @@ Required properties: - reg: i2c address of the sensor / spi cs line Optional properties: +- drive-open-drain: the interrupt/data ready line will be configured + as open drain, which is useful if several sensors share the same + interrupt line. This is a boolean property. + If the requested interrupt is configured as IRQ_TYPE_LEVEL_HIGH or + IRQ_TYPE_EDGE_RISING a pull-down resistor is needed to drive the line + when it is not active, whereas a pull-up one is needed when interrupt + line is configured as IRQ_TYPE_LEVEL_LOW or IRQ_TYPE_EDGE_FALLING. + Refer to pinctrl/pinctrl-bindings.txt for the property description. - interrupt-parent: should be the phandle for the interrupt controller - interrupts: interrupt mapping for IRQ. It should be configured with - flags IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING. + flags IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW or + IRQ_TYPE_EDGE_FALLING. Refer to interrupt-controller/interrupts.txt for generic interrupt client node bindings. diff --git a/Documentation/devicetree/bindings/iio/humidity/htu21.txt b/Documentation/devicetree/bindings/iio/humidity/htu21.txt new file mode 100644 index 0000000000000000000000000000000000000000..97d79636f7ae151e2867cd0d01e1ee87a1dea399 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/htu21.txt @@ -0,0 +1,13 @@ +*HTU21 - Measurement-Specialties htu21 temperature & humidity sensor and humidity part of MS8607 sensor + +Required properties: + + - compatible: should be "meas,htu21" or "meas,ms8607-humidity" + - reg: I2C address of the sensor + +Example: + +htu21@40 { + compatible = "meas,htu21"; + reg = <0x40>; +}; diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt index 6f28ff55f3ec2d58949b572d1d16d8dbf96f194e..1ff1af799c76f3dcad89ee065bbe0f423369f6d7 100644 --- a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt @@ -11,6 +11,14 @@ Required properties: Optional properties: - st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2). +- drive-open-drain: the interrupt/data ready line will be configured + as open drain, which is useful if several sensors share the same + interrupt line. This is a boolean property. + (This binding is taken from pinctrl/pinctrl-bindings.txt) + If the requested interrupt is configured as IRQ_TYPE_LEVEL_HIGH or + IRQ_TYPE_EDGE_RISING a pull-down resistor is needed to drive the line + when it is not active, whereas a pull-up one is needed when interrupt + line is configured as IRQ_TYPE_LEVEL_LOW or IRQ_TYPE_EDGE_FALLING. - interrupt-parent: should be the phandle for the interrupt controller - interrupts: interrupt mapping for IRQ. It should be configured with flags IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW or diff --git a/Documentation/devicetree/bindings/iio/pressure/ms5637.txt b/Documentation/devicetree/bindings/iio/pressure/ms5637.txt new file mode 100644 index 0000000000000000000000000000000000000000..1f43ffa068ac60f5323e52a069b8e21643b9a3d2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/ms5637.txt @@ -0,0 +1,17 @@ +* MS5637 - Measurement-Specialties MS5637, MS5805, MS5837 and MS8607 pressure & temperature sensor + +Required properties: + + -compatible: should be one of the following + meas,ms5637 + meas,ms5805 + meas,ms5837 + meas,ms8607-temppressure + -reg: I2C address of the sensor + +Example: + +ms5637@76 { + compatible = "meas,ms5637"; + reg = <0x76>; +}; diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index eaa8fbba34e2eb89f971eae2fdf5af136db0f751..9ec6f5ce54fca5e0de95fac1f99fe2e96427fde1 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -45,6 +45,7 @@ Accelerometers: - st,lis2dh12-accel - st,h3lis331dl-accel - st,lng2dm-accel +- st,lis3l02dq Gyroscopes: - st,l3g4200d-gyro @@ -52,6 +53,7 @@ Gyroscopes: - st,lsm330dl-gyro - st,lsm330dlc-gyro - st,l3gd20-gyro +- st,l3gd20h-gyro - st,l3g4is-gyro - st,lsm330-gyro - st,lsm9ds0-gyro @@ -62,6 +64,7 @@ Magnetometers: - st,lsm303dlhc-magn - st,lsm303dlm-magn - st,lis3mdl-magn +- st,lis2mdl Pressure sensors: - st,lps001wp-press diff --git a/Documentation/devicetree/bindings/iio/temperature/tsys01.txt b/Documentation/devicetree/bindings/iio/temperature/tsys01.txt new file mode 100644 index 0000000000000000000000000000000000000000..0d5cc5595d0cd589ac32992a9df4ab4b66c747d8 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/temperature/tsys01.txt @@ -0,0 +1,19 @@ +* TSYS01 - Measurement Specialties temperature sensor + +Required properties: + + - compatible: should be "meas,tsys01" + - reg: I2C address of the sensor (changeable via CSB pin) + + ------------------------ + | CSB | Device Address | + ------------------------ + 1 0x76 + 0 0x77 + +Example: + +tsys01@76 { + compatible = "meas,tsys01"; + reg = <0x76>; +}; diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-lptimer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-lptimer-trigger.txt new file mode 100644 index 0000000000000000000000000000000000000000..85e6806b17d73440273f48bb86f9e5a55c0fa1b3 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/timer/stm32-lptimer-trigger.txt @@ -0,0 +1,23 @@ +STMicroelectronics STM32 Low-Power Timer Trigger + +STM32 Low-Power Timer provides trigger source (LPTIM output) that can be used +by STM32 internal ADC and/or DAC. + +Must be a sub-node of an STM32 Low-Power Timer device tree node. +See ../mfd/stm32-lptimer.txt for details about the parent node. + +Required properties: +- compatible: Must be "st,stm32-lptimer-trigger". +- reg: Identify trigger hardware block. Must be 0, 1 or 2 + respectively for lptimer1, lptimer2 or lptimer3 + trigger output. + +Example: + timer@40002400 { + compatible = "st,stm32-lptimer"; + ... + trigger@0 { + compatible = "st,stm32-lptimer-trigger"; + reg = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt index 55a653d153034f21f6499dbb8dee7e6e6a79bbf5..b8e8c769d434371e29f05d966e4060c5b3827575 100644 --- a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt +++ b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt @@ -4,7 +4,9 @@ Must be a sub-node of an STM32 Timers device tree node. See ../mfd/stm32-timers.txt for details about the parent node. Required parameters: -- compatible: Must be "st,stm32-timer-trigger". +- compatible: Must be one of: + "st,stm32-timer-trigger" + "st,stm32h7-timer-trigger" - reg: Identify trigger hardware block. Example: @@ -14,7 +16,7 @@ Example: compatible = "st,stm32-timers"; reg = <0x40010000 0x400>; clocks = <&rcc 0 160>; - clock-names = "clk_int"; + clock-names = "int"; timer@0 { compatible = "st,stm32-timer-trigger"; diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index 1852906517ab1c1b691fb4df75f8b5bdd7c9c78c..23e3abc3fdef0c084ed61a78d15c49597f075c72 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @@ -22,6 +22,8 @@ Optional properties for main touchpad device: experiment to determine which bit corresponds to which input. Use KEY_RESERVED for unused padding values. +- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low) + Example: touch@4b { diff --git a/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt b/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt index b77f50bd64036614a9cd50fc8e71592c8df197f6..262deab7358898ea8ae1a626bec492c64b148faf 100644 --- a/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt +++ b/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt @@ -72,7 +72,6 @@ Example: /* Required Board specific properties */ keypad,num-rows = <5>; keypad,num-columns = <5>; - status = "okay"; linux,keymap = ; + }; + + vibrator_enable_pin: pinmux_vibrator_enable_pin { + pinctrl-single,pins = < + OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1) /* dmtimer9_pwm_evt (gpio_28) */ + >; + }; +}; + +/ { + pwm8: dmtimer-pwm { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_direction_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer8>; + ti,clock-source = <0x01>; + }; + + pwm9: dmtimer-pwm { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_enable_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer9>; + ti,clock-source = <0x01>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm8 0 1000000000 0>, + <&pwm9 0 1000000000 0>; + pwm-names = "enable", "direction"; + direction-duty-cycle-ns = <1000000000>; + }; +}; diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.txt b/Documentation/devicetree/bindings/input/ti,drv260x.txt index ee09c8f4474a2e2ccfca4fa6cd9830f94273b192..4c5312eaaa85a7894b04208cc34478c5e28abe00 100644 --- a/Documentation/devicetree/bindings/input/ti,drv260x.txt +++ b/Documentation/devicetree/bindings/input/ti,drv260x.txt @@ -43,7 +43,7 @@ haptics: haptics@5a { mode = ; library-sel = ; vib-rated-mv = <3200>; - vib-overdriver-mv = <3200>; + vib-overdrive-mv = <3200>; } For more product information please see the link below: diff --git a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt index 9d9e930f3251263fde538dfa1b1463796bd5c904..df531b5b6a0d2ff398dab162573aa46b38453158 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt @@ -32,5 +32,4 @@ Example: pinctrl-1 = <&pinctrl_touchctrl_default>; pinctrl-2 = <&pinctrl_touchctrl_gpios>; vf50-ts-min-pressure = <200>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt index d4927c202aef271554022e5fd84451f1febe9212..e67e58b61706243153a2a70ebc5f4cc8cf66b643 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt @@ -35,5 +35,4 @@ Example: measure-delay-time = <0xfff>; pre-charge-time = <0xffff>; touchscreen-average-samples = <32>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt index 9e389493203ffc384efca8233d09178107881567..49ccabbfa6f3dcd13634f52ef308d8251e163027 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt @@ -4,8 +4,10 @@ Required properties: - compatible: should be "fsl,-msi" to identify Layerscape PCIe MSI controller block such as: - "fsl,1s1021a-msi" - "fsl,1s1043a-msi" + "fsl,ls1021a-msi" + "fsl,ls1043a-msi" + "fsl,ls1046a-msi" + "fsl,ls1043a-v1.1-msi" - msi-controller: indicates that this is a PCIe MSI controller node - reg: physical base address of the controller and length of memory mapped. - interrupts: an interrupt to the parent interrupt controller. @@ -23,7 +25,7 @@ MSI controller node Examples: msi1: msi-controller@1571000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1571000 0x0 0x8>, msi-controller; interrupts = <0 116 0x4>; diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt index 11cc87aeb276f0a25b869ba53ed2b6b9213888d8..07bf0b9a5139fed3d5297d495bab184111deb9f9 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt @@ -17,6 +17,7 @@ Required properties: "mediatek,mt6582-sysirq", "mediatek,mt6577-sysirq": for MT6582 "mediatek,mt6580-sysirq", "mediatek,mt6577-sysirq": for MT6580 "mediatek,mt6577-sysirq": for MT6577 + "mediatek,mt2712-sysirq", "mediatek,mt6577-sysirq": for MT2712 "mediatek,mt2701-sysirq", "mediatek,mt6577-sysirq": for MT2701 - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt. diff --git a/Documentation/devicetree/bindings/interrupt-controller/socionext,uniphier-aidet.txt b/Documentation/devicetree/bindings/interrupt-controller/socionext,uniphier-aidet.txt new file mode 100644 index 0000000000000000000000000000000000000000..48e71d3ac2adfaff8f7cd5da2c42f54eb3219deb --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/socionext,uniphier-aidet.txt @@ -0,0 +1,32 @@ +UniPhier AIDET + +UniPhier AIDET (ARM Interrupt Detector) is an add-on block for ARM GIC (Generic +Interrupt Controller). GIC itself can handle only high level and rising edge +interrupts. The AIDET provides logic inverter to support low level and falling +edge interrupts. + +Required properties: +- compatible: Should be one of the following: + "socionext,uniphier-ld4-aidet" - for LD4 SoC + "socionext,uniphier-pro4-aidet" - for Pro4 SoC + "socionext,uniphier-sld8-aidet" - for sLD8 SoC + "socionext,uniphier-pro5-aidet" - for Pro5 SoC + "socionext,uniphier-pxs2-aidet" - for PXs2/LD6b SoC + "socionext,uniphier-ld11-aidet" - for LD11 SoC + "socionext,uniphier-ld20-aidet" - for LD20 SoC + "socionext,uniphier-pxs3-aidet" - for PXs3 SoC +- reg: Specifies offset and length of the register set for the device. +- interrupt-controller: Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an interrupt + source. The value should be 2. The first cell defines the interrupt number + (corresponds to the SPI interrupt number of GIC). The second cell specifies + the trigger type as defined in interrupts.txt in this directory. + +Example: + + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pro4-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt new file mode 100644 index 0000000000000000000000000000000000000000..b2641ceb2b4060bfe441c85d57ec177ca1635691 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt @@ -0,0 +1,121 @@ +* QCOM IOMMU v1 Implementation + +Qualcomm "B" family devices which are not compatible with arm-smmu have +a similar looking IOMMU but without access to the global register space, +and optionally requiring additional configuration to route context irqs +to non-secure vs secure interrupt line. + +** Required properties: + +- compatible : Should be one of: + + "qcom,msm8916-iommu" + + Followed by "qcom,msm-iommu-v1". + +- clock-names : Should be a pair of "iface" (required for IOMMUs + register group access) and "bus" (required for + the IOMMUs underlying bus access). + +- clocks : Phandles for respective clocks described by + clock-names. + +- #address-cells : must be 1. + +- #size-cells : must be 1. + +- #iommu-cells : Must be 1. Index identifies the context-bank #. + +- ranges : Base address and size of the iommu context banks. + +- qcom,iommu-secure-id : secure-id. + +- List of sub-nodes, one per translation context bank. Each sub-node + has the following required properties: + + - compatible : Should be one of: + - "qcom,msm-iommu-v1-ns" : non-secure context bank + - "qcom,msm-iommu-v1-sec" : secure context bank + - reg : Base address and size of context bank within the iommu + - interrupts : The context fault irq. + +** Optional properties: + +- reg : Base address and size of the SMMU local base, should + be only specified if the iommu requires configuration + for routing of context bank irq's to secure vs non- + secure lines. (Ie. if the iommu contains secure + context banks) + + +** Examples: + + apps_iommu: iommu@1e20000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1e20000 0x40000>; + reg = <0x1ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <17>; + + // mdp_0: + iommu-ctx@4000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x4000 0x1000>; + interrupts = ; + }; + + // venus_ns: + iommu-ctx@5000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x5000 0x1000>; + interrupts = ; + }; + }; + + gpu_iommu: iommu@1f08000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1f08000 0x10000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <18>; + + // gfx3d_user: + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = ; + }; + + // gfx3d_priv: + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x2000 0x1000>; + interrupts = ; + }; + }; + + ... + + venus: video-codec@1d00000 { + ... + iommus = <&apps_iommu 5>; + }; + + mdp: mdp@1a01000 { + ... + iommus = <&apps_iommu 4>; + }; + + gpu@01c00000 { + ... + iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; + }; diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt index 9a55ac3735e541360287125dbcd2876212fa8264..2098f7732264e41fddb8e58c22a309f2693715e7 100644 --- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt +++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt @@ -15,6 +15,11 @@ Required properties: to associate with its master device. See: Documentation/devicetree/bindings/iommu/iommu.txt +Optional properties: +- rockchip,disable-mmu-reset : Don't use the mmu reset operation. + Some mmu instances may produce unexpected results + when the reset operation is used. + Example: vopl_mmu: iommu@ff940300 { diff --git a/Documentation/devicetree/bindings/leds/ams,as3645a.txt b/Documentation/devicetree/bindings/leds/ams,as3645a.txt new file mode 100644 index 0000000000000000000000000000000000000000..fdc40e354a64dd582d86841afac520a73d6fa5f0 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ams,as3645a.txt @@ -0,0 +1,79 @@ +Analog devices AS3645A device tree bindings + +The AS3645A flash LED controller can drive two LEDs, one high current +flash LED and one indicator LED. The high current flash LED can be +used in torch mode as well. + +Ranges below noted as [a, b] are closed ranges between a and b, i.e. a +and b are included in the range. + +Please also see common.txt in the same directory. + + +Required properties +=================== + +compatible : Must be "ams,as3645a". +reg : The I2C address of the device. Typically 0x30. +#address-cells : 1 +#size-cells : 0 + + +Required properties of the flash child node (0) +=============================================== + +reg: 0 +flash-timeout-us: Flash timeout in microseconds. The value must be in + the range [100000, 850000] and divisible by 50000. +flash-max-microamp: Maximum flash current in microamperes. Has to be + in the range between [200000, 500000] and + divisible by 20000. +led-max-microamp: Maximum torch (assist) current in microamperes. The + value must be in the range between [20000, 160000] and + divisible by 20000. +ams,input-max-microamp: Maximum flash controller input current. The + value must be in the range [1250000, 2000000] + and divisible by 50000. + + +Optional properties of the flash child node +=========================================== + +label : The label of the flash LED. + + +Required properties of the indicator child node (1) +=================================================== + +reg: 1 +led-max-microamp: Maximum indicator current. The allowed values are + 2500, 5000, 7500 and 10000. + +Optional properties of the indicator child node +=============================================== + +label : The label of the indicator LED. + + +Example +======= + + as3645a@30 { + #address-cells: 1 + #size-cells: 0 + reg = <0x30>; + compatible = "ams,as3645a"; + flash@0 { + reg = <0x0>; + flash-timeout-us = <150000>; + flash-max-microamp = <320000>; + led-max-microamp = <60000>; + ams,input-max-microamp = <1750000>; + label = "as3645a:flash"; + }; + indicator@1 { + reg = <0x1>; + led-max-microamp = <10000>; + label = "as3645a:indicator"; + }; + }; diff --git a/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt b/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt new file mode 100644 index 0000000000000000000000000000000000000000..cbe8dfd29715b1f7660906d3cd87ce46e422abae --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt @@ -0,0 +1,14 @@ +Device tree bindings for IR LED connected through gpio pin which is used as +remote controller transmitter. + +Required properties: + - compatible: should be "gpio-ir-tx". + - gpios : Should specify the IR LED GPIO, see "gpios property" in + Documentation/devicetree/bindings/gpio/gpio.txt. Active low LEDs + should be indicated using flags in the GPIO specifier. + +Example: + irled@0 { + compatible = "gpio-ir-tx"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt b/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt new file mode 100644 index 0000000000000000000000000000000000000000..66e5672c2e3d852262a7d027fff3ec2c8daf8204 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt @@ -0,0 +1,13 @@ +Device tree bindings for IR LED connected through pwm pin which is used as +remote controller transmitter. + +Required properties: + - compatible: should be "pwm-ir-tx". + - pwms : PWM property to point to the PWM device (phandle)/port (id) + and to specify the period time to be used: <&phandle id period_ns>; + +Example: + irled { + compatible = "pwm-ir-tx"; + pwms = <&pwm0 0 10000000>; + }; diff --git a/Documentation/devicetree/bindings/leds/leds-gpio.txt b/Documentation/devicetree/bindings/leds/leds-gpio.txt index 76535ca371209216be9e021622d55bbf4ebe900a..a48dda268f81b4f3fcb3cceeb8dea6ff536bceb9 100644 --- a/Documentation/devicetree/bindings/leds/leds-gpio.txt +++ b/Documentation/devicetree/bindings/leds/leds-gpio.txt @@ -18,6 +18,9 @@ LED sub-node properties: see Documentation/devicetree/bindings/leds/common.txt - retain-state-suspended: (optional) The suspend state can be retained.Such as charge-led gpio. +- retain-state-shutdown: (optional) Retain the state of the LED on shutdown. + Useful in BMC systems, for example when the BMC is rebooted while the host + remains up. - panic-indicator : (optional) see Documentation/devicetree/bindings/leds/common.txt diff --git a/Documentation/devicetree/bindings/leds/leds-pca955x.txt b/Documentation/devicetree/bindings/leds/leds-pca955x.txt new file mode 100644 index 0000000000000000000000000000000000000000..7984efb767b411ac6814bd139513e53d48fa7ff3 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-pca955x.txt @@ -0,0 +1,88 @@ +* NXP - pca955x LED driver + +The PCA955x family of chips are I2C LED blinkers whose pins not used +to control LEDs can be used as general purpose I/Os. The GPIO pins can +be input or output, and output pins can also be pulse-width controlled. + +Required properties: +- compatible : should be one of : + "nxp,pca9550" + "nxp,pca9551" + "nxp,pca9552" + "nxp,pca9553" +- #address-cells: must be 1 +- #size-cells: must be 0 +- reg: I2C slave address. depends on the model. + +Optional properties: +- gpio-controller: allows pins to be used as GPIOs. +- #gpio-cells: must be 2. +- gpio-line-names: define the names of the GPIO lines + +LED sub-node properties: +- reg : number of LED line. + from 0 to 1 for the pca9550 + from 0 to 7 for the pca9551 + from 0 to 15 for the pca9552 + from 0 to 3 for the pca9553 +- type: (optional) either + PCA9532_TYPE_NONE + PCA9532_TYPE_LED + PCA9532_TYPE_GPIO + see dt-bindings/leds/leds-pca955x.h (default to LED) +- label : (optional) + see Documentation/devicetree/bindings/leds/common.txt +- linux,default-trigger : (optional) + see Documentation/devicetree/bindings/leds/common.txt + +Examples: + +pca9552: pca9552@60 { + compatible = "nxp,pca9552"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60>; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "GPIO12", "GPIO13", "GPIO14", "GPIO15"; + + gpio@12 { + reg = <12>; + type = ; + }; + gpio@13 { + reg = <13>; + type = ; + }; + gpio@14 { + reg = <14>; + type = ; + }; + gpio@15 { + reg = <15>; + type = ; + }; + + led@0 { + label = "red:power"; + linux,default-trigger = "default-on"; + reg = <0>; + type = ; + }; + led@1 { + label = "green:power"; + reg = <1>; + type = ; + }; + led@2 { + label = "pca9552:yellow"; + reg = <2>; + type = ; + }; + led@3 { + label = "pca9552:white"; + reg = <3>; + type = ; + }; +}; diff --git a/Documentation/devicetree/bindings/media/i2c/adv748x.txt b/Documentation/devicetree/bindings/media/i2c/adv748x.txt new file mode 100644 index 0000000000000000000000000000000000000000..21ffb5ed818302ff4fb709a213aebfc1d4980b1f --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/adv748x.txt @@ -0,0 +1,95 @@ +* Analog Devices ADV748X video decoder with HDMI receiver + +The ADV7481 and ADV7482 are multi format video decoders with an integrated +HDMI receiver. They can output CSI-2 on two independent outputs TXA and TXB +from three input sources HDMI, analog and TTL. + +Required Properties: + + - compatible: Must contain one of the following + - "adi,adv7481" for the ADV7481 + - "adi,adv7482" for the ADV7482 + + - reg: I2C slave address + +Optional Properties: + + - interrupt-names: Should specify the interrupts as "intrq1", "intrq2" and/or + "intrq3". All interrupts are optional. The "intrq3" interrupt + is only available on the adv7481 + - interrupts: Specify the interrupt lines for the ADV748x + +The device node must contain one 'port' child node per device input and output +port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes +are numbered as follows. + + Name Type Port + --------------------------------------- + AIN0 sink 0 + AIN1 sink 1 + AIN2 sink 2 + AIN3 sink 3 + AIN4 sink 4 + AIN5 sink 5 + AIN6 sink 6 + AIN7 sink 7 + HDMI sink 8 + TTL sink 9 + TXA source 10 + TXB source 11 + +The digital output port nodes must contain at least one endpoint. + +Ports are optional if they are not connected to anything at the hardware level. + +Example: + + video-receiver@70 { + compatible = "adi,adv7482"; + reg = <0x70>; + + #address-cells = <1>; + #size-cells = <0>; + + interrupt-parent = <&gpio6>; + interrupt-names = "intrq1", "intrq2"; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>, + <31 IRQ_TYPE_LEVEL_LOW>; + + port@7 { + reg = <7>; + + adv7482_ain7: endpoint { + remote-endpoint = <&cvbs_in>; + }; + }; + + port@8 { + reg = <8>; + + adv7482_hdmi: endpoint { + remote-endpoint = <&hdmi_in>; + }; + }; + + port@10 { + reg = <10>; + + adv7482_txa: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&csi40_in>; + }; + }; + + port@11 { + reg = <11>; + + adv7482_txb: endpoint { + clock-lanes = <0>; + data-lanes = <1>; + remote-endpoint = <&csi20_in>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt new file mode 100644 index 0000000000000000000000000000000000000000..b88dcdd41def013f1710371eb5a6c41ed357caa8 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt @@ -0,0 +1,9 @@ +Dongwoon Anatech DW9714 camera voice coil lens driver + +DW9174 is a 10-bit DAC with current sink capability. It is intended +for driving voice coil lenses in camera modules. + +Mandatory properties: + +- compatible: "dongwoon,dw9714" +- reg: I²C slave address diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt b/Documentation/devicetree/bindings/media/meson-ao-cec.txt new file mode 100644 index 0000000000000000000000000000000000000000..8671bdb08080e37303227d5b6e55d78c24402ccc --- /dev/null +++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt @@ -0,0 +1,28 @@ +* Amlogic Meson AO-CEC driver + +The Amlogic Meson AO-CEC module is present is Amlogic SoCs and its purpose is +to handle communication between HDMI connected devices over the CEC bus. + +Required properties: + - compatible : value should be following + "amlogic,meson-gx-ao-cec" + + - reg : Physical base address of the IP registers and length of memory + mapped region. + + - interrupts : AO-CEC interrupt number to the CPU. + - clocks : from common clock binding: handle to AO-CEC clock. + - clock-names : from common clock binding: must contain "core", + corresponding to entry in the clocks property. + - hdmi-phandle: phandle to the HDMI controller + +Example: + +cec_AO: cec@100 { + compatible = "amlogic,meson-gx-ao-cec"; + reg = <0x0 0x00100 0x0 0x14>; + interrupts = ; + clocks = <&clkc_AO CLKID_AO_CEC_32K>; + clock-names = "core"; + hdmi-phandle = <&hdmi_tx>; +}; diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt index 2be2005577d6e5dd3fa66f329df9b68c8ebc34c5..5e18087ce11f25410fdff901d398f8d60d6f7133 100644 --- a/Documentation/devicetree/bindings/media/mtk-cir.txt +++ b/Documentation/devicetree/bindings/media/mtk-cir.txt @@ -2,10 +2,14 @@ Device-Tree bindings for Mediatek consumer IR controller found in Mediatek SoC family Required properties: -- compatible : "mediatek,mt7623-cir" +- compatible : Should be + "mediatek,mt7623-cir": for MT7623 SoC + "mediatek,mt7622-cir": for MT7622 SoC - clocks : list of clock specifiers, corresponding to entries in clock-names property; -- clock-names : should contain "clk" entries; +- clock-names : should contain + - "clk" entries: for MT7623 SoC + - "clk", "bus" entries: for MT7622 SoC - interrupts : should contain IR IRQ number; - reg : should contain IO map address for IR. diff --git a/Documentation/devicetree/bindings/media/pxa-camera.txt b/Documentation/devicetree/bindings/media/pxa-camera.txt index 11f5b5d51af8c8c9c1bbb494e3a44b857f619bac..bc03ec096269dc60fb429bc4ef0409c472a39d4a 100644 --- a/Documentation/devicetree/bindings/media/pxa-camera.txt +++ b/Documentation/devicetree/bindings/media/pxa-camera.txt @@ -24,7 +24,6 @@ Example: clock-frequency = <50000000>; clock-output-names = "qci_mclk"; - status = "okay"; port { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt new file mode 100644 index 0000000000000000000000000000000000000000..cadecebc73f7136647b5b82782226d4484e9c207 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -0,0 +1,197 @@ +Qualcomm Camera Subsystem + +* Properties + +- compatible: + Usage: required + Value type: + Definition: Should contain: + - "qcom,msm8916-camss" +- reg: + Usage: required + Value type: + Definition: Register ranges as listed in the reg-names property. +- reg-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "csiphy0" + - "csiphy0_clk_mux" + - "csiphy1" + - "csiphy1_clk_mux" + - "csid0" + - "csid1" + - "ispif" + - "csi_clk_mux" + - "vfe0" +- interrupts: + Usage: required + Value type: + Definition: Interrupts as listed in the interrupt-names property. +- interrupt-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "csiphy0" + - "csiphy1" + - "csid0" + - "csid1" + - "ispif" + - "vfe0" +- power-domains: + Usage: required + Value type: + Definition: A phandle and power domain specifier pairs to the + power domain which is responsible for collapsing + and restoring power to the peripheral. +- clocks: + Usage: required + Value type: + Definition: A list of phandle and clock specifier pairs as listed + in clock-names property. +- clock-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "camss_top_ahb" + - "ispif_ahb" + - "csiphy0_timer" + - "csiphy1_timer" + - "csi0_ahb" + - "csi0" + - "csi0_phy" + - "csi0_pix" + - "csi0_rdi" + - "csi1_ahb" + - "csi1" + - "csi1_phy" + - "csi1_pix" + - "csi1_rdi" + - "camss_ahb" + - "camss_vfe_vfe" + - "camss_csi_vfe" + - "iface" + - "bus" +- vdda-supply: + Usage: required + Value type: + Definition: A phandle to voltage supply for CSI2. +- iommus: + Usage: required + Value type: + Definition: A list of phandle and IOMMU specifier pairs. + +* Nodes + +- ports: + Usage: required + Definition: As described in video-interfaces.txt in same directory. + Properties: + - reg: + Usage: required + Value type: + Definition: Selects CSI2 PHY interface - PHY0 or PHY1. + Endpoint node properties: + - clock-lanes: + Usage: required + Value type: + Definition: The physical clock lane index. The value + must always be <1> as the physical clock + lane is lane 1. + - data-lanes: + Usage: required + Value type: + Definition: An array of physical data lanes indexes. + Position of an entry determines the logical + lane number, while the value of an entry + indicates physical lane index. Lane swapping + is supported. + +* An Example + + camss: camss@1b00000 { + compatible = "qcom,msm8916-camss"; + reg = <0x1b0ac00 0x200>, + <0x1b00030 0x4>, + <0x1b0b000 0x200>, + <0x1b00038 0x4>, + <0x1b08000 0x100>, + <0x1b08400 0x100>, + <0x1b0a000 0x500>, + <0x1b00020 0x10>, + <0x1b10000 0x1000>; + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csid0", + "csid1", + "ispif", + "csi_clk_mux", + "vfe0"; + interrupts = , + , + , + , + , + ; + interrupt-names = "csiphy0", + "csiphy1", + "csid0", + "csid1", + "ispif", + "vfe0"; + power-domains = <&gcc VFE_GDSC>; + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_ISPIF_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI0_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0_CLK>, + <&gcc GCC_CAMSS_CSI0PHY_CLK>, + <&gcc GCC_CAMSS_CSI0PIX_CLK>, + <&gcc GCC_CAMSS_CSI0RDI_CLK>, + <&gcc GCC_CAMSS_CSI1_AHB_CLK>, + <&gcc GCC_CAMSS_CSI1_CLK>, + <&gcc GCC_CAMSS_CSI1PHY_CLK>, + <&gcc GCC_CAMSS_CSI1PIX_CLK>, + <&gcc GCC_CAMSS_CSI1RDI_CLK>, + <&gcc GCC_CAMSS_AHB_CLK>, + <&gcc GCC_CAMSS_VFE0_CLK>, + <&gcc GCC_CAMSS_CSI_VFE0_CLK>, + <&gcc GCC_CAMSS_VFE_AHB_CLK>, + <&gcc GCC_CAMSS_VFE_AXI_CLK>; + clock-names = "camss_top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "camss_ahb", + "camss_vfe_vfe", + "camss_csi_vfe", + "iface", + "bus"; + vdda-supply = <&pm8916_l2>; + iommus = <&apps_iommu 3>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csiphy0_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0 2>; + remote-endpoint = <&ov5645_ep>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/renesas,drif.txt b/Documentation/devicetree/bindings/media/renesas,drif.txt index 39516b94c28fbef0a4539e04d861332b04184637..0d8974aa8b38f362bf2331da1094f6000f2ddbb4 100644 --- a/Documentation/devicetree/bindings/media/renesas,drif.txt +++ b/Documentation/devicetree/bindings/media/renesas,drif.txt @@ -40,6 +40,7 @@ To summarize, Required properties of an internal channel: ------------------------------------------- - compatible: "renesas,r8a7795-drif" if DRIF controller is a part of R8A7795 SoC. + "renesas,r8a7796-drif" if DRIF controller is a part of R8A7796 SoC. "renesas,rcar-gen3-drif" for a generic R-Car Gen3 compatible device. When compatible with the generic version, nodes must list the diff --git a/Documentation/devicetree/bindings/media/s5p-cec.txt b/Documentation/devicetree/bindings/media/s5p-cec.txt index 1b1a10ba48cec34727000fe72efa89daf413d61e..6f3756da900f0fb56349e4d1854424637eb8cca9 100644 --- a/Documentation/devicetree/bindings/media/s5p-cec.txt +++ b/Documentation/devicetree/bindings/media/s5p-cec.txt @@ -33,5 +33,4 @@ hdmicec: cec@100B0000 { hdmi-phandle = <&hdmi>; pinctrl-names = "default"; pinctrl-0 = <&hdmi_cec>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt index 922d6f8e74be37c9992655402861af59ae8ff83a..e4e15d8d752157909e03344ee04ce7621ba5b967 100644 --- a/Documentation/devicetree/bindings/media/samsung-fimc.txt +++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt @@ -166,7 +166,6 @@ Example: clock-output-names = "cam_a_clkout", "cam_b_clkout"; pinctrl-names = "default"; pinctrl-0 = <&cam_port_a_clk_active>; - status = "okay"; #address-cells = <1>; #size-cells = <1>; @@ -189,7 +188,6 @@ Example: compatible = "samsung,exynos4210-fimc"; reg = <0x11800000 0x1000>; interrupts = <0 85 0>; - status = "okay"; }; csis_0: csis@11880000 { diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt index cc51b1fd6e0cee6e7e6a17123be60f20b9c318f8..6af3fc210ecce9e84640631308d59d12ceb8ad38 100644 --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt +++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt @@ -52,7 +52,6 @@ Example: c8sectpfe@08a20000 { compatible = "st,stih407-c8sectpfe"; - status = "okay"; reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>; reg-names = "stfe", "stfe-ram"; interrupts = , ; diff --git a/Documentation/devicetree/bindings/media/ti,da850-vpif.txt b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt index df7182a63e59aef757c58fd930279a400f7fb210..e47c7ccc57f11ec53fe9aa5eb28b4c48e6397a27 100644 --- a/Documentation/devicetree/bindings/media/ti,da850-vpif.txt +++ b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt @@ -59,7 +59,6 @@ I2C-connected TVP5147 decoder: tvp5147@5d { compatible = "ti,tvp5147"; reg = <0x5d>; - status = "okay"; port { composite_in: endpoint { diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt index 9cd2a369125d440cb393582c1b7d0f253ef25d06..852041a7480c0a8054489f54a15e6667a70c0dc6 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.txt +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt @@ -76,6 +76,11 @@ Optional endpoint properties mode horizontal and vertical synchronization signals are provided to the slave device (data source) by the master device (data sink). In the master mode the data source device is also the source of the synchronization signals. +- bus-type: data bus type. Possible values are: + 0 - autodetect based on other properties (MIPI CSI-2 D-PHY, parallel or Bt656) + 1 - MIPI CSI-2 C-PHY + 2 - MIPI CSI1 + 3 - CCP2 - bus-width: number of data lines actively used, valid for the parallel busses. - data-shift: on the parallel data busses, if bus-width is used to specify the number of data lines, data-shift can be used to specify which data lines are @@ -112,7 +117,8 @@ Optional endpoint properties should be the combined length of data-lanes and clock-lanes properties. If the lane-polarities property is omitted, the value must be interpreted as 0 (normal). This property is valid for serial busses only. - +- strobe: Whether the clock signal is used as clock (0) or strobe (1). Used + with CCP2, for instance. Example ------- diff --git a/Documentation/devicetree/bindings/media/zx-irdec.txt b/Documentation/devicetree/bindings/media/zx-irdec.txt new file mode 100644 index 0000000000000000000000000000000000000000..295b9fab593ef36375d4ac37ff1b67eb143ce939 --- /dev/null +++ b/Documentation/devicetree/bindings/media/zx-irdec.txt @@ -0,0 +1,14 @@ +IR Decoder (IRDEC) on ZTE ZX family SoCs + +Required properties: + - compatible: Should be "zte,zx296718-irdec". + - reg: Physical base address and length of IRDEC registers. + - interrupts: Interrupt number of IRDEC. + +Exmaples: + + irdec: ir-decoder@111000 { + compatible = "zte,zx296718-irdec"; + reg = <0x111000 0x1000>; + interrupts = ; + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt index 21277a56e94c7c790656fc9fad7bb3f3e7442da7..ddf46b8856a565da83744c4402ec9ae738e67b9e 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt @@ -15,6 +15,9 @@ Required properties: the register. - "smi" : It's the clock for transfer data and command. +Required property for mt2701: +- mediatek,larb-id :the hardware id of this larb. + Example: larb1: larb@16010000 { compatible = "mediatek,mt8173-smi-larb"; @@ -25,3 +28,15 @@ Example: <&vdecsys CLK_VDEC_LARB_CKEN>; clock-names = "apb", "smi"; }; + +Example for mt2701: + larb0: larb@14010000 { + compatible = "mediatek,mt2701-smi-larb"; + reg = <0 0x14010000 0 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt index 1ee3bc09f31982d3bf554e22972e4a6768920501..8b9388cc1ccc6d8884feaa115233ea099ff6907c 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt @@ -130,7 +130,6 @@ The reg property implicitly specifies the chip select as this: Example: devbus-bootcs@d0010400 { - status = "okay"; ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf0000000, size 0x1000000 */ #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/mfd/act8945a.txt b/Documentation/devicetree/bindings/mfd/act8945a.txt index 462819ac3da8f1cff2737fd7a5cf2b6906eb0c91..e6f168db6c723e018dc50389c5405dac614d1f0f 100644 --- a/Documentation/devicetree/bindings/mfd/act8945a.txt +++ b/Documentation/devicetree/bindings/mfd/act8945a.txt @@ -12,7 +12,6 @@ Example: pmic@5b { compatible = "active-semi,act8945a"; reg = <0x5b>; - status = "okay"; active-semi,vsel-high; @@ -79,6 +78,5 @@ Example: active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,precondition-timeout = <40>; active-semi,total-timeout = <3>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt index eec40be7f79a007005a2e835c1d73e59298a02bc..3f643ef121ff51ade6dd0205d5d3ec770cebf6f9 100644 --- a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt +++ b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt @@ -25,7 +25,6 @@ Example: clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; clock-names = "periph_clk","sys_clk", "slow_clk"; interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; - status = "disabled"; hlcdc-display-controller { compatible = "atmel,hlcdc-display-controller"; diff --git a/Documentation/devicetree/bindings/mfd/atmel-smc.txt b/Documentation/devicetree/bindings/mfd/atmel-smc.txt index 26eeed373934aa75ad4501a21a160e713447006e..1103ce2030fbbcda2a303340cc1344326201e76a 100644 --- a/Documentation/devicetree/bindings/mfd/atmel-smc.txt +++ b/Documentation/devicetree/bindings/mfd/atmel-smc.txt @@ -8,6 +8,7 @@ Required properties: - compatible: Should be one of the following "atmel,at91sam9260-smc", "syscon" "atmel,sama5d3-smc", "syscon" + "atmel,sama5d2-smc", "syscon" - reg: Contains offset/length value of the SMC memory region. diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index aca09af665142c21f9512136817fd2d8f856f490..9455503b02993109cb0621519654eacadbc2f35a 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt @@ -7,7 +7,14 @@ axp209 (X-Powers) axp221 (X-Powers) axp223 (X-Powers) axp803 (X-Powers) +axp806 (X-Powers) axp809 (X-Powers) +axp813 (X-Powers) + +The AXP813 is 2 chips packaged into 1. The 2 chips do not share anything +other than the packaging. Pins are routed separately. As such they should +be treated as separate entities. The other half is an AC100 RTC/codec +combo chip. Please see ./ac100.txt for its bindings. Required properties: - compatible: should be one of: @@ -19,6 +26,7 @@ Required properties: * "x-powers,axp803" * "x-powers,axp806" * "x-powers,axp809" + * "x-powers,axp813" - reg: The I2C slave address or RSB hardware address for the AXP chip - interrupt-parent: The parent interrupt controller - interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin @@ -28,12 +36,14 @@ Required properties: Optional properties: - x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz AXP152/20X: range: 750-1875, Default: 1.5 MHz - AXP22X/80X: range: 1800-4050, Default: 3 MHz + AXP22X/8XX: range: 1800-4050, Default: 3 MHz -- x-powers,drive-vbus-en: axp221 / axp223 only boolean, set this when the - N_VBUSEN pin is used as an output pin to control an external - regulator to drive the OTG VBus, rather then as an input pin - which signals whether the board is driving OTG VBus or not. +- x-powers,drive-vbus-en: boolean, set this when the N_VBUSEN pin is + used as an output pin to control an external + regulator to drive the OTG VBus, rather then + as an input pin which signals whether the + board is driving OTG VBus or not. + (axp221 / axp223 / axp813 only) - x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is wired for master mode. The default is slave mode. @@ -171,6 +181,36 @@ LDO_IO1 : LDO : ips-supply : GPIO 1 RTC_LDO : LDO : ips-supply : always on SW : On/Off Switch : swin-supply +AXP813 regulators, type, and corresponding input supply names: + +Regulator Type Supply Name Notes +--------- ---- ----------- ----- +DCDC1 : DC-DC buck : vin1-supply +DCDC2 : DC-DC buck : vin2-supply : poly-phase capable +DCDC3 : DC-DC buck : vin3-supply : poly-phase capable +DCDC4 : DC-DC buck : vin4-supply +DCDC5 : DC-DC buck : vin5-supply : poly-phase capable +DCDC6 : DC-DC buck : vin6-supply : poly-phase capable +DCDC7 : DC-DC buck : vin7-supply +ALDO1 : LDO : aldoin-supply : shared supply +ALDO2 : LDO : aldoin-supply : shared supply +ALDO3 : LDO : aldoin-supply : shared supply +DLDO1 : LDO : dldoin-supply : shared supply +DLDO2 : LDO : dldoin-supply : shared supply +DLDO3 : LDO : dldoin-supply : shared supply +DLDO4 : LDO : dldoin-supply : shared supply +ELDO1 : LDO : eldoin-supply : shared supply +ELDO2 : LDO : eldoin-supply : shared supply +ELDO3 : LDO : eldoin-supply : shared supply +FLDO1 : LDO : fldoin-supply : shared supply +FLDO2 : LDO : fldoin-supply : shared supply +FLDO3 : LDO : fldoin-supply : shared supply +LDO_IO0 : LDO : ips-supply : GPIO 0 +LDO_IO1 : LDO : ips-supply : GPIO 1 +RTC_LDO : LDO : ips-supply : always on +SW : On/Off Switch : swin-supply +DRIVEVBUS : Enable output : drivevbus-supply : external regulator + Example: axp209: pmic@34 { diff --git a/Documentation/devicetree/bindings/mfd/bd9571mwv.txt b/Documentation/devicetree/bindings/mfd/bd9571mwv.txt new file mode 100644 index 0000000000000000000000000000000000000000..9ab216a851d5619becdf70da0b5a2c14f73026e2 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/bd9571mwv.txt @@ -0,0 +1,49 @@ +* ROHM BD9571MWV Power Management Integrated Circuit (PMIC) bindings + +Required properties: + - compatible : Should be "rohm,bd9571mwv". + - reg : I2C slave address. + - interrupt-parent : Phandle to the parent interrupt controller. + - interrupts : The interrupt line the device is connected to. + - interrupt-controller : Marks the device node as an interrupt controller. + - #interrupt-cells : The number of cells to describe an IRQ, should be 2. + The first cell is the IRQ number. + The second cell is the flags, encoded as trigger + masks from ../interrupt-controller/interrupts.txt. + - gpio-controller : Marks the device node as a GPIO Controller. + - #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify flags. + See ../gpio/gpio.txt for more information. + - regulators: : List of child nodes that specify the regulator + initialization data. Child nodes must be named + after their hardware counterparts: + - vd09 + - vd18 + - vd25 + - vd33 + - dvfs + Each child node is defined using the standard + binding for regulators. + +Example: + + pmic: pmic@30 { + compatible = "rohm,bd9571mwv"; + reg = <0x30>; + interrupt-parent = <&gpio2>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + + regulators { + dvfs: dvfs { + regulator-name = "dvfs"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1030000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/da9052-i2c.txt b/Documentation/devicetree/bindings/mfd/da9052-i2c.txt index 9554292dc6cbb0643c0ce4898117e81804dfc087..07c69c0c6624ce2e2d0adab034c4d10ce8b373e2 100644 --- a/Documentation/devicetree/bindings/mfd/da9052-i2c.txt +++ b/Documentation/devicetree/bindings/mfd/da9052-i2c.txt @@ -4,6 +4,14 @@ Required properties: - compatible : Should be "dlg,da9052", "dlg,da9053-aa", "dlg,da9053-ab", or "dlg,da9053-bb" +Optional properties: +- dlg,tsi-as-adc : Boolean, if set the X+, X-, Y+, Y- touchscreen + input lines are used as general purpose analogue + input. +- tsiref-supply: Phandle to the regulator, which provides the reference + voltage for the TSIREF pin. Must be provided when the + touchscreen pins are used for ADC purposes. + Sub-nodes: - regulators : Contain the regulator nodes. The DA9052/53 regulators are bound using their names as listed below: @@ -29,7 +37,6 @@ Sub-nodes: Examples: i2c@63fc8000 { /* I2C1 */ - status = "okay"; pmic: dialog@48 { compatible = "dlg,da9053-aa"; diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt index 8aba48821a85a3284ac92a31c2c401922fad3744..39ba4146769deb9ab3549a0789bbb340e693e7ca 100644 --- a/Documentation/devicetree/bindings/mfd/mc13xxx.txt +++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt @@ -116,7 +116,6 @@ ecspi@70010000 { /* ECSPI1 */ fsl,spi-num-chipselects = <2>; cs-gpios = <&gpio4 24 0>, /* GPIO4_24 */ <&gpio4 25 0>; /* GPIO4_25 */ - status = "okay"; pmic: mc13892@0 { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/mfd/mxs-lradc.txt b/Documentation/devicetree/bindings/mfd/mxs-lradc.txt index 555fb117d4facd8dc8e7b60c84500d873b44f1cd..755cbef0647df9d07ac7921526f103b4736360c5 100644 --- a/Documentation/devicetree/bindings/mfd/mxs-lradc.txt +++ b/Documentation/devicetree/bindings/mfd/mxs-lradc.txt @@ -26,7 +26,6 @@ Example for i.MX23 SoC: compatible = "fsl,imx23-lradc"; reg = <0x80050000 0x2000>; interrupts = <36 37 38 39 40 41 42 43 44>; - status = "okay"; fsl,lradc-touchscreen-wires = <4>; fsl,ave-ctrl = <4>; fsl,ave-delay = <2>; @@ -39,7 +38,6 @@ Example for i.MX28 SoC: compatible = "fsl,imx28-lradc"; reg = <0x80050000 0x2000>; interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>; - status = "okay"; fsl,lradc-touchscreen-wires = <5>; fsl,ave-ctrl = <4>; fsl,ave-delay = <2>; diff --git a/Documentation/devicetree/bindings/mfd/retu.txt b/Documentation/devicetree/bindings/mfd/retu.txt new file mode 100644 index 0000000000000000000000000000000000000000..876242394a16c39398298d04968f519511ae0c96 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/retu.txt @@ -0,0 +1,25 @@ +* Device tree bindings for Nokia Retu and Tahvo multi-function device + +Retu and Tahvo are a multi-function devices found on Nokia Internet +Tablets (770, N800 and N810). The Retu chip provides watchdog timer +and power button control functionalities while Tahvo chip provides +USB transceiver functionality. + +Required properties: +- compatible: "nokia,retu" or "nokia,tahvo" +- reg: Specifies the CBUS slave address of the ASIC chip +- interrupts: The interrupt line the device is connected to +- interrupt-parent: The parent interrupt controller + +Example: + +cbus0 { + compatible = "i2c-cbus-gpio"; + ... + retu: retu@1 { + compatible = "nokia,retu"; + interrupt-parent = <&gpio4>; + interrupts = <12 IRQ_TYPE_EDGE_RISING>; + reg = <0x1>; + }; +}; diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt index 9636ae8d8d41d446fd2345623c2ed9ff8d685a7c..91b65227afeb34a6d666bb89ada750c4652684b0 100644 --- a/Documentation/devicetree/bindings/mfd/rk808.txt +++ b/Documentation/devicetree/bindings/mfd/rk808.txt @@ -1,11 +1,14 @@ RK8XX Power Management Integrated Circuit The rk8xx family current members: +rk805 rk808 rk818 Required properties: -- compatible: "rockchip,rk808", "rockchip,rk818" +- compatible: "rockchip,rk805" +- compatible: "rockchip,rk808" +- compatible: "rockchip,rk818" - reg: I2C slave address - interrupt-parent: The parent interrupt controller. - interrupts: the interrupt outputs of the controller. @@ -18,6 +21,14 @@ Optional properties: - rockchip,system-power-controller: Telling whether or not this pmic is controlling the system power. +Optional RK805 properties: +- vcc1-supply: The input supply for DCDC_REG1 +- vcc2-supply: The input supply for DCDC_REG2 +- vcc3-supply: The input supply for DCDC_REG3 +- vcc4-supply: The input supply for DCDC_REG4 +- vcc5-supply: The input supply for LDO_REG1 and LDO_REG2 +- vcc6-supply: The input supply for LDO_REG3 + Optional RK808 properties: - vcc1-supply: The input supply for DCDC_REG1 - vcc2-supply: The input supply for DCDC_REG2 @@ -56,6 +67,15 @@ by a child node of the 'regulators' node. /* standard regulator bindings here */ }; +Following regulators of the RK805 PMIC regulators are supported. Note that +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO +number as described in RK805 datasheet. + + - DCDC_REGn + - valid values for n are 1 to 4. + - LDO_REGn + - valid values for n are 1 to 3 + Following regulators of the RK808 PMIC block are supported. Note that the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO number as described in RK808 datasheet. diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index df664018c148edf237fcc89e0a85b68c94c299e7..d759da606f757360d5498c92b41b713ffb66819c 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -57,7 +57,6 @@ audio-subsystem { clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; pinctrl-names = "default"; pinctrl-0 = <&i2s0_bus>; - status = "disabled"; }; serial_3: serial@11460000 { @@ -69,6 +68,5 @@ audio-subsystem { clock-names = "uart", "clk_uart_baud0"; pinctrl-names = "default"; pinctrl-0 = <&uart_aud_bus>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt b/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a9ff29db9c9519697a3653edee8c0c2ed80be46 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt @@ -0,0 +1,48 @@ +STMicroelectronics STM32 Low-Power Timer + +The STM32 Low-Power Timer (LPTIM) is a 16-bit timer that provides several +functions: +- PWM output (with programmable prescaler, configurable polarity) +- Quadrature encoder, counter +- Trigger source for STM32 ADC/DAC (LPTIM_OUT) + +Required properties: +- compatible: Must be "st,stm32-lptimer". +- reg: Offset and length of the device's register set. +- clocks: Phandle to the clock used by the LP Timer module. +- clock-names: Must be "mux". +- #address-cells: Should be '<1>'. +- #size-cells: Should be '<0>'. + +Optional subnodes: +- pwm: See ../pwm/pwm-stm32-lp.txt +- counter: See ../iio/timer/stm32-lptimer-cnt.txt +- trigger: See ../iio/timer/stm32-lptimer-trigger.txt + +Example: + + timer@40002400 { + compatible = "st,stm32-lptimer"; + reg = <0x40002400 0x400>; + clocks = <&timer_clk>; + clock-names = "mux"; + #address-cells = <1>; + #size-cells = <0>; + + pwm { + compatible = "st,stm32-pwm-lp"; + pinctrl-names = "default"; + pinctrl-0 = <&lppwm1_pins>; + }; + + trigger@0 { + compatible = "st,stm32-lptimer-trigger"; + reg = <0>; + }; + + counter { + compatible = "st,stm32-lptimer-counter"; + pinctrl-names = "default"; + pinctrl-0 = <&lptim1_in_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/tps6105x.txt b/Documentation/devicetree/bindings/mfd/tps6105x.txt new file mode 100644 index 0000000000000000000000000000000000000000..93602c7a19c8e296259198e7178dc8e9434f44a6 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/tps6105x.txt @@ -0,0 +1,17 @@ +* Device tree bindings for TI TPS61050/61052 Boost Converters + +The TP61050/TPS61052 is a high-power "white LED driver". The +device provides LED, GPIO and regulator functionalities. + +Required properties: +- compatible: "ti,tps61050" or "ti,tps61052" +- reg: Specifies the I2C slave address + +Example: + +i2c0 { + tps61052@33 { + compatible = "ti,tps61052"; + reg = <0x33>; + }; +}; diff --git a/Documentation/devicetree/bindings/mfd/wm831x.txt b/Documentation/devicetree/bindings/mfd/wm831x.txt index 9f8b7430673c922b2d7f857a8c558e8345a2e831..505709403d3f8a21f270617fadf8a0e51128aee5 100644 --- a/Documentation/devicetree/bindings/mfd/wm831x.txt +++ b/Documentation/devicetree/bindings/mfd/wm831x.txt @@ -31,6 +31,7 @@ Required properties: ../interrupt-controller/interrupts.txt Optional sub-nodes: + - phys : Contains a phandle to the USB PHY. - regulators : Contains sub-nodes for each of the regulators supplied by the device. The regulators are bound using their names listed below: diff --git a/Documentation/devicetree/bindings/mfd/zii,rave-sp.txt b/Documentation/devicetree/bindings/mfd/zii,rave-sp.txt new file mode 100644 index 0000000000000000000000000000000000000000..088eff9ddb786cdbdf0a26ea3d9fed27f048b021 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/zii,rave-sp.txt @@ -0,0 +1,39 @@ +Zodiac Inflight Innovations RAVE Supervisory Processor + +RAVE Supervisory Processor communicates with SoC over UART. It is +expected that its Device Tree node is specified as a child of a node +corresponding to UART controller used for communication. + +Required parent device properties: + + - compatible: Should be one of: + - "zii,rave-sp-niu" + - "zii,rave-sp-mezz" + - "zii,rave-sp-esb" + - "zii,rave-sp-rdu1" + - "zii,rave-sp-rdu2" + + - current-speed: Should be set to baud rate SP device is using + +RAVE SP consists of the following sub-devices: + +Device Description +------ ----------- +rave-sp-wdt : Watchdog +rave-sp-nvmem : Interface to onborad EEPROM +rave-sp-backlight : Display backlight +rave-sp-hwmon : Interface to onboard hardware sensors +rave-sp-leds : Interface to onboard LEDs +rave-sp-input : Interface to onboard power button + +Example of usage: + + rdu { + compatible = "zii,rave-sp-rdu2"; + current-speed = <1000000>; + + watchdog { + compatible = "zii,rave-sp-watchdog"; + }; + }; + diff --git a/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt b/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt new file mode 100644 index 0000000000000000000000000000000000000000..0a2df433833202fd80903720d9ca9e45dad306ba --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt @@ -0,0 +1,31 @@ +Lantiq XWAY SoC FPI BUS binding +============================ + + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,xrx200-fpi" +- reg : The address and length of the XBAR + configuration register. + Address and length of the FPI bus itself. +- lantiq,rcu : A phandle to the RCU syscon +- lantiq,offset-endianness : Offset of the endianness configuration + register + +------------------------------------------------------------------------------- +Example for the FPI on the xrx200 SoCs: + fpi@10000000 { + compatible = "lantiq,xrx200-fpi"; + ranges = <0x0 0x10000000 0xf000000>; + reg = <0x1f400000 0x1000>, + <0x10000000 0xf000000>; + lantiq,rcu = <&rcu0>; + lantiq,offset-endianness = <0x4c>; + #address-cells = <1>; + #size-cells = <1>; + + gptu@e100a00 { + ...... + }; + }; diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt new file mode 100644 index 0000000000000000000000000000000000000000..a0c19bd1ce6625e603a658aba8420e033cf60910 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt @@ -0,0 +1,36 @@ +Lantiq XWAY SoC GPHY binding +============================ + +This binding describes a software-defined ethernet PHY, provided by the RCU +module on newer Lantiq XWAY SoCs (xRX200 and newer). + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,xrx200a1x-gphy" + "lantiq,xrx200a2x-gphy" + "lantiq,xrx300-gphy" + "lantiq,xrx330-gphy" +- reg : Addrress of the GPHY FW load address register +- resets : Must reference the RCU GPHY reset bit +- reset-names : One entry, value must be "gphy" or optional "gphy2" +- clocks : A reference to the (PMU) GPHY clock gate + +Optional properties: +- lantiq,gphy-mode : GPHY_MODE_GE (default) or GPHY_MODE_FE as defined in + + + +------------------------------------------------------------------------------- +Example for the GPHys on the xRX200 SoCs: + +#include + gphy0: gphy@20 { + compatible = "lantiq,xrx200a2x-gphy"; + reg = <0x20 0x4>; + + resets = <&reset0 31 30>, <&reset1 7 7>; + reset-names = "gphy", "gphy2"; + clocks = <&pmu0 XRX200_PMU_GATE_GPHY>; + lantiq,gphy-mode = ; + }; diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt new file mode 100644 index 0000000000000000000000000000000000000000..a086f1e1cdd78809f87f145dba13adaf68849602 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt @@ -0,0 +1,89 @@ +Lantiq XWAY SoC RCU binding +=========================== + +This binding describes the RCU (reset controller unit) multifunction device, +where each sub-device has it's own set of registers. + +The RCU register range is used for multiple purposes. Mostly one device +uses one or multiple register exclusively, but for some registers some +bits are for one driver and some other bits are for a different driver. +With this patch all accesses to the RCU registers will go through +syscon. + + +------------------------------------------------------------------------------- +Required properties: +- compatible : The first and second values must be: + "lantiq,xrx200-rcu", "simple-mfd", "syscon" +- reg : The address and length of the system control registers + + +------------------------------------------------------------------------------- +Example of the RCU bindings on a xRX200 SoC: + rcu0: rcu@203000 { + compatible = "lantiq,xrx200-rcu", "simple-mfd", "syscon"; + reg = <0x203000 0x100>; + ranges = <0x0 0x203000 0x100>; + big-endian; + + gphy0: gphy@20 { + compatible = "lantiq,xrx200a2x-gphy"; + reg = <0x20 0x4>; + + resets = <&reset0 31 30>, <&reset1 7 7>; + reset-names = "gphy", "gphy2"; + lantiq,gphy-mode = ; + }; + + gphy1: gphy@68 { + compatible = "lantiq,xrx200a2x-gphy"; + reg = <0x68 0x4>; + + resets = <&reset0 29 28>, <&reset1 6 6>; + reset-names = "gphy", "gphy2"; + lantiq,gphy-mode = ; + }; + + reset0: reset-controller@10 { + compatible = "lantiq,xrx200-reset"; + reg = <0x10 4>, <0x14 4>; + + #reset-cells = <2>; + }; + + reset1: reset-controller@48 { + compatible = "lantiq,xrx200-reset"; + reg = <0x48 4>, <0x24 4>; + + #reset-cells = <2>; + }; + + usb_phy0: usb2-phy@18 { + compatible = "lantiq,xrx200-usb2-phy"; + reg = <0x18 4>, <0x38 4>; + status = "disabled"; + + resets = <&reset1 4 4>, <&reset0 4 4>; + reset-names = "phy", "ctrl"; + #phy-cells = <0>; + }; + + usb_phy1: usb2-phy@34 { + compatible = "lantiq,xrx200-usb2-phy"; + reg = <0x34 4>, <0x3C 4>; + status = "disabled"; + + resets = <&reset1 5 4>, <&reset0 4 4>; + reset-names = "phy", "ctrl"; + #phy-cells = <0>; + }; + + reboot@10 { + compatible = "syscon-reboot"; + reg = <0x10 4>; + + regmap = <&rcu0>; + offset = <0x10>; + mask = <0x40000000>; + }; + }; diff --git a/Documentation/devicetree/bindings/mips/ni.txt b/Documentation/devicetree/bindings/mips/ni.txt new file mode 100644 index 0000000000000000000000000000000000000000..722bf2d62da9644f3595e8125d53a0c80c184d31 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/ni.txt @@ -0,0 +1,7 @@ +National Instruments MIPS platforms + +required root node properties: + - compatible: must be "ni,169445" + +CPU Nodes + - compatible: must be "mti,mips14KEc" diff --git a/Documentation/devicetree/bindings/mips/ralink.txt b/Documentation/devicetree/bindings/mips/ralink.txt index b35a8d04f8b6e3c9fe62b7c460c2aea5217386ef..a16e8d7fe56c55eb8c9486f1e8825a6e18fc16ee 100644 --- a/Documentation/devicetree/bindings/mips/ralink.txt +++ b/Documentation/devicetree/bindings/mips/ralink.txt @@ -15,3 +15,4 @@ value must be one of the following values: ralink,rt5350-soc ralink,mt7620a-soc ralink,mt7620n-soc + ralink,mt7628a-soc diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt index f8629bb7394578d8f1ae22123ee0da0179137270..f9fb412642fe09937adeeafd620859af858c0952 100644 --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -47,5 +47,4 @@ ssc0: ssc@f0010000 { dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 49df630bd44ff7af11a65cc2113697fb2bbeae77..60481bfc3d31e3d0167670deaa107118f76ef2c1 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -74,5 +74,4 @@ Example: phys = <&emmc_phy>; phy-names = "phy_arasan"; #clock-cells = <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt index e5a0140b2381c5663738b82ec3a6970513fe9b20..516fb0143d4c21d1c8e44a8846d55ea5458d7b74 100644 --- a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt @@ -24,7 +24,6 @@ mmc0: mmc@1c40000 { compatible = "ti,da830-mmc", reg = <0x40000 0x1000>; interrupts = <16>; - status = "okay"; bus-width = <4>; max-frequency = <50000000>; dmas = <&edma 16 diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt index db442355cd247457bc4f98a70afb4b27f87fc562..184ccffe273946dbb8f7e9c644fe135d55b8c7ee 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt @@ -20,5 +20,4 @@ sdhci1: sdhci@10014000 { dma-names = "rx-tx"; bus-width = <4>; cd-gpios = <&gpio3 29>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt index b878a1e305af6e143a646b3473be522c82a62e8a..ed1456f5c94dda21ecaf2eebd86bcd7934d11376 100644 --- a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt @@ -16,11 +16,13 @@ Required Properties: - clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory. - clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi". - reg: * For "marvell,armada-3700-sdhci", two register areas. @@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core", "axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>; @@ -126,8 +128,8 @@ Example: interrupts = vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>, <&axi_clk>; + clock-names = "core", "axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; }; diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.txt b/Documentation/devicetree/bindings/mmc/mmc-card.txt index a70fcd65b9ea9b3d3f24dcb2c4969f9783bc6a43..8d2d71758907ecd403af09f17799722d6b3c616c 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-card.txt +++ b/Documentation/devicetree/bindings/mmc/mmc-card.txt @@ -21,7 +21,6 @@ Example: vmmc-supply = <®_vcc3v3>; bus-width = <8>; non-removable; - status = "okay"; mmccard: mmccard@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index c7f4a0ec48eda788359a06ce07e6330d932da9d5..b32ade645ad97cbc655dbd0b53b7a998905d6f7f 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt @@ -153,7 +153,6 @@ mmc3: mmc@01c12000 { bus-width = <4>; non-removable; mmc-pwrseq = <&sdhci0_pwrseq> - status = "okay"; brcmf: bcrmf@1 { reg = <1>; diff --git a/Documentation/devicetree/bindings/mmc/orion-sdio.txt b/Documentation/devicetree/bindings/mmc/orion-sdio.txt index 84f0ebd67a130b990a0f0b80e475d2f30b3daac7..10f0818a34c59d9dfad7a5f2d80429fd1ebab7c3 100644 --- a/Documentation/devicetree/bindings/mmc/orion-sdio.txt +++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt @@ -13,5 +13,4 @@ Example: reg = <0xd00d4000 0x200>; interrupts = <54>; clocks = <&gateclk 17>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt b/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt index c32dc5a9dbe6cf2e434e049c4149ff0c2c3e1f4f..5ff1e12c655a56b99804ed68bf3ffb954b371498 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt +++ b/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt @@ -11,6 +11,8 @@ Required properties: - "renesas,mmcif-r7s72100" for the MMCIF found in r7s72100 SoCs - "renesas,mmcif-r8a73a4" for the MMCIF found in r8a73a4 SoCs - "renesas,mmcif-r8a7740" for the MMCIF found in r8a7740 SoCs + - "renesas,mmcif-r8a7743" for the MMCIF found in r8a7743 SoCs + - "renesas,mmcif-r8a7745" for the MMCIF found in r8a7745 SoCs - "renesas,mmcif-r8a7778" for the MMCIF found in r8a7778 SoCs - "renesas,mmcif-r8a7790" for the MMCIF found in r8a7790 SoCs - "renesas,mmcif-r8a7791" for the MMCIF found in r8a7791 SoCs @@ -21,7 +23,7 @@ Required properties: - interrupts: Some SoCs have only 1 shared interrupt, while others have either 2 or 3 individual interrupts (error, int, card detect). Below is the number of interrupts for each SoC: - 1: r8a73a4, r8a7778, r8a7790, r8a7791, r8a7793, r8a7794 + 1: r8a73a4, r8a7743, r8a7745, r8a7778, r8a7790, r8a7791, r8a7793, r8a7794 2: r8a7740, sh73a0 3: r7s72100 diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 49ed3ad2524a4e7d64661117be3225ef6718257a..c6558785e61be3bc620c506d6c40f28653d9ddee 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt @@ -15,6 +15,7 @@ Required Properties: - "rockchip,rk3288-dw-mshc": for Rockchip RK3288 - "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RV1108 - "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036 + - "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK322x - "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3328 - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368 - "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399 diff --git a/Documentation/devicetree/bindings/mmc/sdhci-st.txt b/Documentation/devicetree/bindings/mmc/sdhci-st.txt index 230fd696eb922fabc5820509a8f9c355f94a1f93..e35645598315ff6a685961a21ffda0d53ea5ed4f 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-st.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-st.txt @@ -63,7 +63,6 @@ Example: mmc0: sdhci@fe81e000 { compatible = "st,sdhci"; - status = "disabled"; reg = <0xfe81e000 0x1000>; interrupts = ; interrupt-names = "mmcirq"; @@ -77,7 +76,6 @@ mmc0: sdhci@fe81e000 { mmc1: sdhci@09080000 { compatible = "st,sdhci-stih407", "st,sdhci"; - status = "disabled"; reg = <0x09080000 0x7ff>; reg-names = "mmc"; interrupts = ; @@ -94,7 +92,6 @@ mmc1: sdhci@09080000 { mmc0: sdhci@09060000 { compatible = "st,sdhci-stih407", "st,sdhci"; - status = "disabled"; reg = <0x09060000 0x7ff>, <0x9061008 0x20>; reg-names = "mmc", "top-mmc-delay"; interrupts = ; diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt index 7d53a799f140edf378412909dfbd14be4a5fb973..63b57e2a10fb2eac92be0ef7d24cb6079b326af5 100644 --- a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt +++ b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt @@ -12,6 +12,7 @@ Required properties: * "allwinner,sun4i-a10-mmc" * "allwinner,sun5i-a13-mmc" * "allwinner,sun7i-a20-mmc" + * "allwinner,sun8i-a83t-emmc" * "allwinner,sun9i-a80-mmc" * "allwinner,sun50i-a64-emmc" * "allwinner,sun50i-a64-mmc" diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index 0e026c151c1c1a1aa3191129658dc5788f2ed4f2..3a4ac401e6f93a9d8ce3becd4d75410f95f1e50d 100644 --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -1,33 +1,55 @@ -* TI Highspeed MMC host controller for OMAP +* TI Highspeed MMC host controller for OMAP and 66AK2G family. -The Highspeed MMC Host Controller on TI OMAP family +The Highspeed MMC Host Controller on TI OMAP and 66AK2G family provides an interface for MMC, SD, and SDIO types of memory cards. This file documents differences between the core properties described by mmc.txt and the properties used by the omap_hsmmc driver. Required properties: +-------------------- - compatible: Should be "ti,omap2-hsmmc", for OMAP2 controllers Should be "ti,omap3-hsmmc", for OMAP3 controllers Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0 Should be "ti,omap4-hsmmc", for OMAP4 controllers Should be "ti,am33xx-hsmmc", for AM335x controllers -- ti,hwmods: Must be "mmc", n is controller instance starting 1 + Should be "ti,k2g-hsmmc", "ti,omap4-hsmmc" for 66AK2G controllers. + +SoC specific required properties: +--------------------------------- +The following are mandatory properties for OMAPs, AM33xx and AM43xx SoCs only: +- ti,hwmods: Must be "mmc", n is controller instance starting 1. + +The following are mandatory properties for 66AK2G SoCs only: +- power-domains:Should contain a phandle to a PM domain provider node + and an args specifier containing the MMC device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +- clocks: Must contain an entry for each entry in clock-names. Should + be defined as per the he appropriate clock bindings consumer + usage in Documentation/devicetree/bindings/clock/ti,sci-clk.txt +- clock-names: Shall be "fck" for the functional clock, + and "mmchsdb_fck" for the debounce clock. + Optional properties: -ti,dual-volt: boolean, supports dual voltage cards --supply: phandle to the regulator device tree node -"supply-name" examples are "vmmc", "vmmc_aux"(deprecated)/"vqmmc" etc -ti,non-removable: non-removable slot (like eMMC) -ti,needs-special-reset: Requires a special softreset sequence -ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed -dmas: List of DMA specifiers with the controller specific format -as described in the generic DMA client binding. A tx and rx -specifier is required. -dma-names: List of DMA request names. These strings correspond -1:1 with the DMA specifiers listed in dmas. The string naming is -to be "rx" and "tx" for RX and TX DMA requests, respectively. +-------------------- +- ti,dual-volt: boolean, supports dual voltage cards +- -supply: phandle to the regulator device tree node + "supply-name" examples are "vmmc", + "vmmc_aux"(deprecated)/"vqmmc" etc +- ti,non-removable: non-removable slot (like eMMC) +- ti,needs-special-reset: Requires a special softreset sequence +- ti,needs-special-hs-handling: HSMMC IP needs special setting + for handling High Speed +- dmas: List of DMA specifiers with the controller specific + format as described in the generic DMA client + binding. A tx and rx specifier is required. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the DMA specifiers listed in dmas. + The string naming is to be "rx" and "tx" for + RX and TX DMA requests, respectively. Examples: diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index 4fd8b7acc510c57453b092d70637c32cc252b85b..54ef642f23a05291258b283431b21b191f0ad39a 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt @@ -15,6 +15,8 @@ Required properties: "renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC "renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC "renesas,sdhi-r8a7740" - SDHI IP on R8A7740 SoC + "renesas,sdhi-r8a7743" - SDHI IP on R8A7743 SoC + "renesas,sdhi-r8a7745" - SDHI IP on R8A7745 SoC "renesas,sdhi-r8a7778" - SDHI IP on R8A7778 SoC "renesas,sdhi-r8a7779" - SDHI IP on R8A7779 SoC "renesas,sdhi-r8a7790" - SDHI IP on R8A7790 SoC @@ -33,10 +35,8 @@ Required properties: If 2 clocks are specified by the hardware, you must name them as "core" and "cd". If the controller only has 1 clock, naming is not required. - Below is the number clocks for each supported SoC: - 1: SH73A0, R8A73A4, R8A7740, R8A7778, R8A7779, R8A7790 - R8A7791, R8A7792, R8A7793, R8A7794, R8A7795, R8A7796 - 2: R7S72100 + Devices which have more than 1 clock are listed below: + 2: R7S72100 Optional properties: - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable diff --git a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt index 906819a90c2bb6232f82f1549ea563c58132aec4..0f59bd5361f530c4c6b343a2b5a39396637940f5 100644 --- a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt @@ -28,5 +28,4 @@ Example: max-frequency = <50000000>; cap-sdio-irq; cap-sd-highspeed; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt index 489807005eda5c477648585777561bffedafec92..b93c1e2f25dd62ac878be49ee24ad8d7b54a9c6f 100644 --- a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt +++ b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt @@ -24,7 +24,6 @@ spi@f0020000 { #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi0_default>; - status = "okay"; m25p80@0 { ... diff --git a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt index 5ded66ad7aef762c91b9436ec400380d505210af..840f9405dcf0736cc294c6432b8176421e34d609 100644 --- a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt +++ b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt @@ -37,7 +37,6 @@ nor_flash: spi@1100d000 { clock-names = "spi", "sf"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; flash@0 { compatible = "jedec,spi-nor"; diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt index 70dd5118a3247c19b14e673b3673fd095973dd8e..73d336befa081b95fb96d8e33863bb6c602fcca9 100644 --- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt @@ -1,11 +1,20 @@ * Qualcomm NAND controller Required properties: -- compatible: should be "qcom,ipq806x-nand" +- compatible: must be one of the following: + * "qcom,ipq806x-nand" - for EBI2 NAND controller being used in IPQ806x + SoC and it uses ADM DMA + * "qcom,ipq4019-nand" - for QPIC NAND controller v1.4.0 being used in + IPQ4019 SoC and it uses BAM DMA + * "qcom,ipq8074-nand" - for QPIC NAND controller v1.5.0 being used in + IPQ8074 SoC and it uses BAM DMA + - reg: MMIO address range - clocks: must contain core clock and always on clock - clock-names: must contain "core" for the core clock and "aon" for the always on clock + +EBI2 specific properties: - dmas: DMA specifier, consisting of a phandle to the ADM DMA controller node and the channel number to be used for NAND. Refer to dma.txt and qcom_adm.txt for more details @@ -16,6 +25,12 @@ Required properties: - qcom,data-crci: must contain the ADM data type CRCI block instance number specified for the NAND controller on the given platform + +QPIC specific properties: +- dmas: DMA specifier, consisting of a phandle to the BAM DMA + and the channel number to be used for NAND. Refer to + dma.txt, qcom_bam_dma.txt for more details +- dma-names: must contain all 3 channel names : "tx", "rx", "cmd" - #address-cells: <1> - subnodes give the chip-select number - #size-cells: <0> @@ -26,7 +41,6 @@ chip-selects which (may) contain NAND flash chips. Their properties are as follows. Required properties: -- compatible: should contain "qcom,nandcs" - reg: a single integer representing the chip-select number (e.g., 0, 1, 2, etc.) - #address-cells: see partition.txt @@ -43,8 +57,8 @@ partition.txt for more detail. Example: -nand@1ac00000 { - compatible = "qcom,ebi2-nandc"; +nand-controller@1ac00000 { + compatible = "qcom,ipq806x-nand"; reg = <0x1ac00000 0x800>; clocks = <&gcc EBI2_CLK>, @@ -59,8 +73,7 @@ nand@1ac00000 { #address-cells = <1>; #size-cells = <0>; - nandcs@0 { - compatible = "qcom,nandcs"; + nand@0 { reg = <0>; nand-ecc-strength = <4>; @@ -84,3 +97,43 @@ nand@1ac00000 { }; }; }; + +nand-controller@79b0000 { + compatible = "qcom,ipq4019-nand"; + reg = <0x79b0000 0x1000>; + + clocks = <&gcc GCC_QPIC_CLK>, + <&gcc GCC_QPIC_AHB_CLK>; + clock-names = "core", "aon"; + + dmas = <&qpicbam 0>, + <&qpicbam 1>, + <&qpicbam 2>; + dma-names = "tx", "rx", "cmd"; + + #address-cells = <1>; + #size-cells = <0>; + + nand@0 { + reg = <0>; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot-nand"; + reg = <0 0x58a0000>; + }; + + partition@58a0000 { + label = "fs-nand"; + reg = <0x58a0000 0x4000000>; + }; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt index c2489391c437503bf24d550f56e7d45799ca3803..54cef9ef3083d90689b69d5ec5ffbd591a0e3ba1 100644 --- a/Documentation/devicetree/bindings/mtd/st-fsm.txt +++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt @@ -21,6 +21,5 @@ Example: st,syscfg = <&syscfg_rear>; st,boot-device-reg = <0x958>; st,boot-device-spi = <0x1a>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt index f322f56aef74eab778244c6ccaa5a5d4a4463e32..a37c67bcb43b6b8e35ce8215e734bd016e41199a 100644 --- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt @@ -41,7 +41,6 @@ nfc: nand@01c03000 { #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>; - status = "okay"; nand@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/net/anarion-gmac.txt b/Documentation/devicetree/bindings/net/anarion-gmac.txt new file mode 100644 index 0000000000000000000000000000000000000000..fe678965ae690e7e2177c0dd3e43831da8af4bdb --- /dev/null +++ b/Documentation/devicetree/bindings/net/anarion-gmac.txt @@ -0,0 +1,25 @@ +* Adaptrum Anarion ethernet controller + +This device is a platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +Required properties: + - compatible: Should be "adaptrum,anarion-gmac", "snps,dwmac" + - phy-mode: Should be "rgmii". Other modes are not currently supported. + + +Examples: + + gmac1: ethernet@f2014000 { + compatible = "adaptrum,anarion-gmac", "snps,dwmac"; + reg = <0xf2014000 0x4000>, <0xf2018100 8>; + + interrupt-parent = <&core_intc>; + interrupts = <21>; + interrupt-names = "macirq"; + + clocks = <&core_clk>; + clock-names = "stmmaceth"; + + phy-mode = "rgmii"; + }; diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ad16c1f481f77fed199e1c24bc3450aa75fbb970..0bfad656a9ff26fc4f672e06f1123198bb9259e7 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -27,5 +27,4 @@ amac0: ethernet@18022000 { <0x18110000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt new file mode 100644 index 0000000000000000000000000000000000000000..4194ff7e6ee678181f18b9cf1b9dc3e90bf93abb --- /dev/null +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt @@ -0,0 +1,35 @@ +Broadcom Bluetooth Chips +--------------------- + +This documents the binding structure and common properties for serial +attached Broadcom devices. + +Serial attached Broadcom devices shall be a child node of the host UART +device the slave device is attached to. + +Required properties: + + - compatible: should contain one of the following: + * "brcm,bcm43438-bt" + +Optional properties: + + - max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt + - shutdown-gpios: GPIO specifier, used to enable the BT module + - device-wakeup-gpios: GPIO specifier, used to wakeup the controller + - host-wakeup-gpios: GPIO specifier, used to wakeup the host processor + - clocks: clock specifier if external clock provided to the controller + - clock-names: should be "extclk" + + +Example: + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <921600>; + }; +}; diff --git a/Documentation/devicetree/bindings/net/btusb.txt b/Documentation/devicetree/bindings/net/btusb.txt index 01fa2d4188d4a90048258229a9433792f1078b28..9c5e663fa1afccaf519ea0af0641b74eb198a483 100644 --- a/Documentation/devicetree/bindings/net/btusb.txt +++ b/Documentation/devicetree/bindings/net/btusb.txt @@ -29,7 +29,6 @@ Example: Following example uses irq pin number 3 of gpio0 for out of band wake-on-bt: &usb_host1_ehci { - status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index 5a1d8b0c39e97af6d3ef56589f0196541d912a51..2d504256b0d8e73183ebe114158f194a85e964d8 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -11,9 +11,20 @@ Required properties: - interrupts : property with a value describing the interrupt number -Optional properties: +The following are mandatory properties for DRA7x, AM33xx and AM43xx SoCs only: - ti,hwmods : Must be "d_can" or "c_can", n being the instance number + +The following are mandatory properties for Keystone 2 66AK2G SoCs only: +- power-domains : Should contain a phandle to a PM domain provider node + and an args specifier containing the DCAN device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +- clocks : CAN functional clock phandle. This property is as per the + binding, + Documentation/devicetree/bindings/clock/ti,sci-clk.txt + +Optional properties: - syscon-raminit : Handle to system control region that contains the RAMINIT register, register offset to the RAMINIT register and the CAN instance number (0 offset). diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt b/Documentation/devicetree/bindings/net/can/m_can.txt index 9e331777c2036ae6e2a9c685add8f32633aa77e7..78138333ff7a3611f8671a4372e08a0da55eddbc 100644 --- a/Documentation/devicetree/bindings/net/can/m_can.txt +++ b/Documentation/devicetree/bindings/net/can/m_can.txt @@ -56,7 +56,6 @@ m_can1: can@020e8000 { <&clks IMX6SX_CLK_CANFD>; clock-names = "hclk", "cclk"; bosch,mram-cfg = <0x0 0 0 32 0 0 0 1>; - status = "disabled"; }; Board dts: diff --git a/Documentation/devicetree/bindings/net/dsa/ksz.txt b/Documentation/devicetree/bindings/net/dsa/ksz.txt index 0ab8b39d0b306d33c10c1d1f4f3211d09001c9f4..fd23904ac68e929adcc6657b6cde29ea4206fd7e 100644 --- a/Documentation/devicetree/bindings/net/dsa/ksz.txt +++ b/Documentation/devicetree/bindings/net/dsa/ksz.txt @@ -24,7 +24,6 @@ Ethernet switch connected via SPI to the host, CPU port wired to eth0: pinctrl-0 = <&pinctrl_spi_ksz>; cs-gpios = <&pioC 25 0>; id = <1>; - status = "okay"; ksz9477: ksz9477@0 { compatible = "microchip,ksz9477"; @@ -34,7 +33,6 @@ Ethernet switch connected via SPI to the host, CPU port wired to eth0: spi-cpha; spi-cpol; - status = "okay"; ports { #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/dsa/lan9303.txt b/Documentation/devicetree/bindings/net/dsa/lan9303.txt index 04f2965a446768920ae90f846419d438773a633d..4448d063ddf6c96402d3773ba1280c37fb5b692e 100644 --- a/Documentation/devicetree/bindings/net/dsa/lan9303.txt +++ b/Documentation/devicetree/bindings/net/dsa/lan9303.txt @@ -27,7 +27,6 @@ Example: I2C managed mode: master: masterdevice@X { - status = "okay"; fixed-link { /* RMII fixed link to LAN9303 */ speed = <100>; @@ -38,7 +37,6 @@ I2C managed mode: switch: switch@a { compatible = "smsc,lan9303-i2c"; reg = <0xa>; - status = "okay"; reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; reset-duration = <200>; @@ -67,7 +65,6 @@ I2C managed mode: MDIO managed mode: master: masterdevice@X { - status = "okay"; phy-handle = <&switch>; mdio { diff --git a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt deleted file mode 100644 index 725f3b18788614f2d7bd8abdb2201d5d216ed7be..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt +++ /dev/null @@ -1,84 +0,0 @@ -* Allwinner sun8i GMAC ethernet controller - -This device is a platform glue layer for stmmac. -Please see stmmac.txt for the other unchanged properties. - -Required properties: -- compatible: should be one of the following string: - "allwinner,sun8i-a83t-emac" - "allwinner,sun8i-h3-emac" - "allwinner,sun8i-v3s-emac" - "allwinner,sun50i-a64-emac" -- reg: address and length of the register for the device. -- interrupts: interrupt for the device -- interrupt-names: should be "macirq" -- clocks: A phandle to the reference clock for this device -- clock-names: should be "stmmaceth" -- resets: A phandle to the reset control for this device -- reset-names: should be "stmmaceth" -- phy-mode: See ethernet.txt -- phy-handle: See ethernet.txt -- #address-cells: shall be 1 -- #size-cells: shall be 0 -- syscon: A phandle to the syscon of the SoC with one of the following - compatible string: - - allwinner,sun8i-h3-system-controller - - allwinner,sun8i-v3s-system-controller - - allwinner,sun50i-a64-system-controller - - allwinner,sun8i-a83t-system-controller - -Optional properties: -- allwinner,tx-delay-ps: TX clock delay chain value in ps. Range value is 0-700. Default is 0) -- allwinner,rx-delay-ps: RX clock delay chain value in ps. Range value is 0-3100. Default is 0) -Both delay properties need to be a multiple of 100. They control the delay for -external PHY. - -Optional properties for the following compatibles: - - "allwinner,sun8i-h3-emac", - - "allwinner,sun8i-v3s-emac": -- allwinner,leds-active-low: EPHY LEDs are active low - -Required child node of emac: -- mdio bus node: should be named mdio - -Required properties of the mdio node: -- #address-cells: shall be 1 -- #size-cells: shall be 0 - -The device node referenced by "phy" or "phy-handle" should be a child node -of the mdio node. See phy.txt for the generic PHY bindings. - -Required properties of the phy node with the following compatibles: - - "allwinner,sun8i-h3-emac", - - "allwinner,sun8i-v3s-emac": -- clocks: a phandle to the reference clock for the EPHY -- resets: a phandle to the reset control for the EPHY - -Example: - -emac: ethernet@1c0b000 { - compatible = "allwinner,sun8i-h3-emac"; - syscon = <&syscon>; - reg = <0x01c0b000 0x104>; - interrupts = ; - interrupt-names = "macirq"; - resets = <&ccu RST_BUS_EMAC>; - reset-names = "stmmaceth"; - clocks = <&ccu CLK_BUS_EMAC>; - clock-names = "stmmaceth"; - #address-cells = <1>; - #size-cells = <0>; - - phy-handle = <&int_mii_phy>; - phy-mode = "mii"; - allwinner,leds-active-low; - mdio: mdio { - #address-cells = <1>; - #size-cells = <0>; - int_mii_phy: ethernet-phy@1 { - reg = <1>; - clocks = <&ccu CLK_BUS_EPHY>; - resets = <&ccu RST_BUS_EPHY>; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt index 7da86f22a13b80843d087fe859d6633de4d8b11d..2974e63ba311aa4d053ee32cd63baea3c415d756 100644 --- a/Documentation/devicetree/bindings/net/ethernet.txt +++ b/Documentation/devicetree/bindings/net/ethernet.txt @@ -1,5 +1,9 @@ The following properties are common to the Ethernet controllers: +NOTE: All 'phy*' properties documented below are Ethernet specific. For the +generic PHY 'phys' property, see +Documentation/devicetree/bindings/phy/phy-bindings.txt. + - local-mac-address: array of 6 bytes, specifies the MAC address that was assigned to the network device; - mac-address: array of 6 bytes, specifies the MAC address that was last used by diff --git a/Documentation/devicetree/bindings/net/ftgmac100.txt b/Documentation/devicetree/bindings/net/ftgmac100.txt index c1ce1680246f0134f08a8b1957d29d0f49f655ca..72e7aaf7242e6cbfd80b02c21fcda9e6a920536b 100644 --- a/Documentation/devicetree/bindings/net/ftgmac100.txt +++ b/Documentation/devicetree/bindings/net/ftgmac100.txt @@ -30,6 +30,5 @@ Example: compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; reg = <0x1e660000 0x180>; interrupts = <2>; - status = "okay"; use-ncsi; }; diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt index ae4234ca4ee44e91fbfc9a4a9fd0e9ba74368ca1..bedcfd5a52cd3966ea867e5ea4326e2aa4e11511 100644 --- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt +++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt @@ -41,7 +41,6 @@ ethernet@70000 { interrupts = <8>; clocks = <&gate_clk 4>; tx-csum-limit = <9800> - status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; buffer-manager = <&bm>; diff --git a/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt index 9be1059ff03f00a54c3d7aec2311a90e2c05373f..3d27c68613a678b06c9c3013794fd709d40dc12e 100644 --- a/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt +++ b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt @@ -44,7 +44,6 @@ Example for SDIO device follows (calibration data is also available in below example). &mmc3 { - status = "okay"; vmmc-supply = <&wlan_en_reg>; bus-width = <4>; cap-power-off-card; @@ -70,7 +69,6 @@ below example). Example for USB device: &usb_host1_ohci { - status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/marvell-neta-bm.txt b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt index c1b1d7c3bde13a25afaa520fd5bb53438f2692e7..07b31050dbe51adf91d5decaaac3d973f64a962e 100644 --- a/Documentation/devicetree/bindings/net/marvell-neta-bm.txt +++ b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt @@ -31,7 +31,6 @@ bm: bm@c8000 { reg = <0xc8000 0xac>; clocks = <&gateclk 13>; internal-mem = <&bm_bppi>; - status = "okay"; pool2,capacity = <4096>; pool1,pkt-size = <512>; }; @@ -45,5 +44,4 @@ bm_bppi: bm-bppi { #address-cells = <1>; #size-cells = <1>; clocks = <&gateclk 13>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/net/marvell-pp2.txt b/Documentation/devicetree/bindings/net/marvell-pp2.txt index 6b4956beff8c42c3214906c83d94072fca8e9083..1814fa13f6ab8078a52a32fa2a55156124d696bb 100644 --- a/Documentation/devicetree/bindings/net/marvell-pp2.txt +++ b/Documentation/devicetree/bindings/net/marvell-pp2.txt @@ -21,8 +21,9 @@ Required properties: - main controller clock (for both armada-375-pp2 and armada-7k-pp2) - GOP clock (for both armada-375-pp2 and armada-7k-pp2) - MG clock (only for armada-7k-pp2) -- clock-names: names of used clocks, must be "pp_clk", "gop_clk" and - "mg_clk" (the latter only for armada-7k-pp2). + - AXI clock (only for armada-7k-pp2) +- clock-names: names of used clocks, must be "pp_clk", "gop_clk", "mg_clk" + and "axi_clk" (the 2 latter only for armada-7k-pp2). The ethernet ports are represented by subnodes. At least one port is required. @@ -41,6 +42,11 @@ Optional properties (port): - marvell,loopback: port is loopback mode - phy: a phandle to a phy node defining the PHY address (as the reg property, a single integer). +- interrupt-names: if more than a single interrupt for rx is given, must + be the name associated to the interrupts listed. Valid + names are: "tx-cpu0", "tx-cpu1", "tx-cpu2", "tx-cpu3", + "rx-shared", "link". +- marvell,system-controller: a phandle to the system controller. Example for marvell,armada-375-pp2: @@ -52,12 +58,10 @@ ethernet@f0000 { <0xc5000 0x100>; clocks = <&gateclk 3>, <&gateclk 19>; clock-names = "pp_clk", "gop_clk"; - status = "okay"; eth0: eth0@c4000 { interrupts = ; port-id = <0>; - status = "okay"; phy = <&phy0>; phy-mode = "gmii"; }; @@ -65,7 +69,6 @@ ethernet@f0000 { eth1: eth1@c5000 { interrupts = ; port-id = <1>; - status = "okay"; phy = <&phy3>; phy-mode = "gmii"; }; @@ -76,23 +79,42 @@ Example for marvell,armada-7k-pp2: cpm_ethernet: ethernet@0 { compatible = "marvell,armada-7k-pp22"; reg = <0x0 0x100000>, <0x129000 0xb000>; - clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, <&cpm_syscon0 1 5>; - clock-names = "pp_clk", "gop_clk", "gp_clk"; + clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, + <&cpm_syscon0 1 5>, <&cpm_syscon0 1 18>; + clock-names = "pp_clk", "gop_clk", "gp_clk", "axi_clk"; eth0: eth0 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <0>; gop-port-id = <0>; }; eth1: eth1 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <1>; gop-port-id = <2>; }; eth2: eth2 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <2>; gop-port-id = <3>; }; diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt index c7194e87d5f4b7d9b61927a430479e39f52ddca8..214eaa9a6683861fd529d2af6fb84e361b27d80d 100644 --- a/Documentation/devicetree/bindings/net/mediatek-net.txt +++ b/Documentation/devicetree/bindings/net/mediatek-net.txt @@ -7,24 +7,32 @@ have dual GMAC each represented by a child node.. * Ethernet controller node Required properties: -- compatible: Should be "mediatek,mt2701-eth" +- compatible: Should be + "mediatek,mt2701-eth": for MT2701 SoC + "mediatek,mt7623-eth", "mediatek,mt2701-eth": for MT7623 SoC + "mediatek,mt7622-eth": for MT7622 SoC - reg: Address and length of the register set for the device - interrupts: Should contain the three frame engines interrupts in numeric order. These are fe_int0, fe_int1 and fe_int2. - clocks: the clock used by the core - clock-names: the names of the clock listed in the clocks property. These are - "ethif", "esw", "gp2", "gp1" + "ethif", "esw", "gp2", "gp1" : For MT2701 and MT7623 SoC + "ethif", "esw", "gp0", "gp1", "gp2", "sgmii_tx250m", "sgmii_rx250m", + "sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck", "eth2pll" : For MT7622 SoC - power-domains: phandle to the power domain that the ethernet is part of -- resets: Should contain a phandle to the ethsys reset signal -- reset-names: Should contain the reset signal name "eth" +- resets: Should contain phandles to the ethsys reset signals +- reset-names: Should contain the names of reset signal listed in the resets + property + These are "fe", "gmac" and "ppe" - mediatek,ethsys: phandle to the syscon node that handles the port setup +- mediatek,sgmiisys: phandle to the syscon node that handles the SGMII setup + which is required for those SoCs equipped with SGMII such as MT7622 SoC. - mediatek,pctl: phandle to the syscon node that handles the ports slew rate and driver current Optional properties: - interrupt-parent: Should be the phandle for the interrupt controller that services interrupts for this device - * Ethernet MAC node Required properties: diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt b/Documentation/devicetree/bindings/net/meson-dwmac.txt index 0703ad3f3c1eba631905102c6f9b77c49cfb764e..354dd9896bb54bbe9cbcb7da56a659d5846f80b3 100644 --- a/Documentation/devicetree/bindings/net/meson-dwmac.txt +++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt @@ -66,5 +66,4 @@ Example for GXBB: <&clkc CLKID_MPLL2>; clock-names = "stmmaceth", "clkin0", "clkin1"; phy-mode = "rgmii"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt index c35b5b428a7f5f78f69d02dcadbbfd383bb38a0b..42a248301615d9e69915a424104f1fc932605175 100644 --- a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt +++ b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt @@ -69,7 +69,6 @@ Examples: }; }; ethernet@70000 { - status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; }; diff --git a/Documentation/devicetree/bindings/net/microchip,enc28j60.txt b/Documentation/devicetree/bindings/net/microchip,enc28j60.txt index 1dc3bc75539db2dc7b1e0c939ca87a55ab7a51c7..44dff53d4ddae7fdc635f07ce0d2ee5e8f1c2370 100644 --- a/Documentation/devicetree/bindings/net/microchip,enc28j60.txt +++ b/Documentation/devicetree/bindings/net/microchip,enc28j60.txt @@ -33,7 +33,6 @@ Example (for NXP i.MX28 with pin control stuff for GPIO irq): compatible = "fsl,imx28-spi"; pinctrl-names = "default"; pinctrl-0 = <&spi2_pins_b &spi2_sck_cfg>; - status = "okay"; enc28j60: ethernet@0 { compatible = "microchip,enc28j60"; diff --git a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt index 76df9173825a00e39cca99a9a8c35bc51f2b57b8..c9b35251bb20d933f892bca518a7dc6752fa4c49 100644 --- a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt +++ b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt @@ -25,7 +25,6 @@ Optional I2C-based chip specific properties: Example (for ARM-based BeagleBoard Black with 88W8887 on UART5): &uart5 { - status = "okay"; nfcmrvluart: nfcmrvluart@5 { compatible = "marvell,nfc-uart"; @@ -41,7 +40,6 @@ Example (for ARM-based BeagleBoard Black with 88W8887 on UART5): Example (for ARM-based BeagleBoard Black with 88W8887 on I2C1): &i2c1 { - status = "okay"; clock-frequency = <400000>; nfcmrvli2c0: i2c@1 { diff --git a/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt b/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt index 5b6cd9b3f628aa3f266e03179f60d1b2447b30b6..92486733df714d9cdf72633470fb5e56542d64bd 100644 --- a/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt +++ b/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt @@ -17,7 +17,6 @@ Example (for ARM-based BeagleBone with NPC100 NFC controller on I2C2): &i2c2 { - status = "okay"; npc100: npc100@29 { diff --git a/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt index 1aea822d4530aae3086e21fea9d9d7e45e96c33e..122460e42e3cfdcf47d525ef096085fb13667e01 100644 --- a/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt +++ b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt @@ -15,7 +15,6 @@ Example (for ARM-based BeagleBone with PN532 on I2C2): &i2c2 { - status = "okay"; pn532: pn532@24 { diff --git a/Documentation/devicetree/bindings/net/nfc/pn544.txt b/Documentation/devicetree/bindings/net/nfc/pn544.txt index dab69f36167c751a758b8b98de5e24033a6e9d88..538a86f7b2b0c99787792b1452f7a5595b079cb9 100644 --- a/Documentation/devicetree/bindings/net/nfc/pn544.txt +++ b/Documentation/devicetree/bindings/net/nfc/pn544.txt @@ -17,7 +17,6 @@ Example (for ARM-based BeagleBone with PN544 on I2C2): &i2c2 { - status = "okay"; pn544: pn544@28 { diff --git a/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt b/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt index fb1e75facf1bacb4e609403eaea37deeb23dbdc7..ed5b3eaadb3926cddb26a8a5c09e59cf3f5072f5 100644 --- a/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt +++ b/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt @@ -12,7 +12,6 @@ Required properties: Example: &hsi2c_4 { - status = "okay"; s3fwrn5@27 { compatible = "samsung,s3fwrn5-i2c"; diff --git a/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt b/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt index 263732e8879f1ecd249f7427c78583b40a24c913..b46d473be425e7f0cd533b195d43326f10924936 100644 --- a/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt +++ b/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt @@ -20,7 +20,6 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on I2C2): &i2c2 { - status = "okay"; st21nfcb: st21nfcb@8 { diff --git a/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt b/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt index 711ca85a363d2e501cb2c936d4b16473aee30f30..54ce8e7ac6810a12f0c3100180a57c9defcbec6c 100644 --- a/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt +++ b/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt @@ -19,7 +19,6 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on SPI4): &mcspi4 { - status = "okay"; st21nfcb: st21nfcb@0 { diff --git a/Documentation/devicetree/bindings/net/nfc/st21nfca.txt b/Documentation/devicetree/bindings/net/nfc/st21nfca.txt index 7bb2e213d6f924ba7c3a908f726ec6b83b2c211d..5ee9440fa9ad7d0050855e4bfc5d8bf164fbdfa9 100644 --- a/Documentation/devicetree/bindings/net/nfc/st21nfca.txt +++ b/Documentation/devicetree/bindings/net/nfc/st21nfca.txt @@ -20,7 +20,6 @@ Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2): &i2c2 { - status = "okay"; st21nfca: st21nfca@1 { diff --git a/Documentation/devicetree/bindings/net/nfc/st95hf.txt b/Documentation/devicetree/bindings/net/nfc/st95hf.txt index ea3178bc9ddd5f85dc6bc02f1ac0b5060b44fb99..08a202e00d47beb1e9e3e7ff6337eb3b948f543b 100644 --- a/Documentation/devicetree/bindings/net/nfc/st95hf.txt +++ b/Documentation/devicetree/bindings/net/nfc/st95hf.txt @@ -35,12 +35,10 @@ spi@9840000 { #address-cells = <1>; #size-cells = <0>; cs-gpios = <&pio0 4>; - status = "okay"; st95hf@0{ reg = <0>; compatible = "st,st95hf"; - status = "okay"; spi-max-frequency = <1000000>; enable-gpio = <&pio4 0>; interrupt-parent = <&pio0>; diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt index 60c833d6218184fb54c1da368400fcdc71ccd9b4..5ca9362ef127dd8a28c5ad98df43d1a0f205d1b9 100644 --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt @@ -23,7 +23,6 @@ Optional SoC Specific Properties: Example (for ARM-based BeagleBone with TRF7970A on SPI1): &spi1 { - status = "okay"; nfc@0 { compatible = "ti,trf7970a"; @@ -41,6 +40,5 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1): irq-status-read-quirk; en2-rf-quirk; clock-frequency = <27120000>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt index df0534e2eda1a05da205b7ba580d7058a5a138fb..d7117a22fd870070950e2c6c811f244f2b8f2979 100644 --- a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt +++ b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt @@ -35,5 +35,4 @@ etha: ethernet@40400000 { /* Regmap for sys registers */ oxsemi,sys-ctrl = <&sys>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index b55857696fc315dc5c1cfad52bb4f40d152e9b8d..77d0b2a61ffa96fcd45375d62e9b911a4d6597df 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -2,11 +2,7 @@ PHY nodes Required properties: - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. + - interrupts : interrupt specifier for the sole interrupt. - interrupt-parent : the phandle for the interrupt controller that services interrupts for this device. - reg : The ID number for the phy, usually a small integer @@ -52,11 +48,16 @@ Optional Properties: Mark the corresponding energy efficient ethernet mode as broken and request the ethernet to stop advertising it. +- phy-is-integrated: If set, indicates that the PHY is integrated into the same + physical package as the Ethernet MAC. If needed, muxers should be configured + to ensure the integrated PHY is used. The absence of this property indicates + the muxers should be configured so that the external PHY is used. + Example: ethernet-phy@0 { compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22"; - interrupt-parent = <40000>; - interrupts = <35 1>; + interrupt-parent = <&PIC>; + interrupts = <35 IRQ_TYPE_EDGE_RISING>; reg = <0>; }; diff --git a/Documentation/devicetree/bindings/net/qca,qca7000.txt b/Documentation/devicetree/bindings/net/qca,qca7000.txt index 6d9efb2eb9a53d4495943122e19c87b3f7f7a889..3987846b3fd302e2be1b3f9266d06a733aba06d6 100644 --- a/Documentation/devicetree/bindings/net/qca,qca7000.txt +++ b/Documentation/devicetree/bindings/net/qca,qca7000.txt @@ -41,7 +41,6 @@ ssp2: spi@80014000 { compatible = "fsl,imx28-spi"; pinctrl-names = "default"; pinctrl-0 = <&spi2_pins_a>; - status = "okay"; qca7000: ethernet@0 { compatible = "qca,qca7000"; @@ -78,7 +77,6 @@ auart0: serial@8006a000 { reg = <0x8006a000 0x2000>; pinctrl-names = "default"; pinctrl-0 = <&auart0_2pins_a>; - status = "okay"; qca7000: ethernet { compatible = "qca,qca7000"; diff --git a/Documentation/devicetree/bindings/net/renesas,ravb.txt b/Documentation/devicetree/bindings/net/renesas,ravb.txt index b519503be51a54de0d36cebaf8c1f91b92234d0a..16723535e1aa7cee73517739cfee3136f933fe29 100644 --- a/Documentation/devicetree/bindings/net/renesas,ravb.txt +++ b/Documentation/devicetree/bindings/net/renesas,ravb.txt @@ -4,19 +4,25 @@ This file provides information on what the device node for the Ethernet AVB interface contains. Required properties: -- compatible: "renesas,etheravb-r8a7790" if the device is a part of R8A7790 SoC. - "renesas,etheravb-r8a7791" if the device is a part of R8A7791 SoC. - "renesas,etheravb-r8a7792" if the device is a part of R8A7792 SoC. - "renesas,etheravb-r8a7793" if the device is a part of R8A7793 SoC. - "renesas,etheravb-r8a7794" if the device is a part of R8A7794 SoC. - "renesas,etheravb-r8a7795" if the device is a part of R8A7795 SoC. - "renesas,etheravb-r8a7796" if the device is a part of R8A7796 SoC. - "renesas,etheravb-rcar-gen2" for generic R-Car Gen 2 compatible interface. - "renesas,etheravb-rcar-gen3" for generic R-Car Gen 3 compatible interface. +- compatible: Must contain one or more of the following: + - "renesas,etheravb-r8a7743" for the R8A7743 SoC. + - "renesas,etheravb-r8a7745" for the R8A7745 SoC. + - "renesas,etheravb-r8a7790" for the R8A7790 SoC. + - "renesas,etheravb-r8a7791" for the R8A7791 SoC. + - "renesas,etheravb-r8a7792" for the R8A7792 SoC. + - "renesas,etheravb-r8a7793" for the R8A7793 SoC. + - "renesas,etheravb-r8a7794" for the R8A7794 SoC. + - "renesas,etheravb-rcar-gen2" as a fallback for the above + R-Car Gen2 and RZ/G1 devices. - When compatible with the generic version, nodes must list the - SoC-specific version corresponding to the platform first - followed by the generic version. + - "renesas,etheravb-r8a7795" for the R8A7795 SoC. + - "renesas,etheravb-r8a7796" for the R8A7796 SoC. + - "renesas,etheravb-rcar-gen3" as a fallback for the above + R-Car Gen3 devices. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first followed by + the generic version. - reg: offset and length of (1) the register block and (2) the stream buffer. - interrupts: A list of interrupt-specifiers, one for each entry in diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt index 8f427550720a3ecce2ca4bac3a164f764cc445f4..9c16ee2965a2ce756acc23d6956fedc38157144b 100644 --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt @@ -4,12 +4,14 @@ The device node has following properties. Required properties: - compatible: should be "rockchip,-gamc" + "rockchip,rk3128-gmac": found on RK312x SoCs "rockchip,rk3228-gmac": found on RK322x SoCs "rockchip,rk3288-gmac": found on RK3288 SoCs "rockchip,rk3328-gmac": found on RK3328 SoCs "rockchip,rk3366-gmac": found on RK3366 SoCs "rockchip,rk3368-gmac": found on RK3368 SoCs "rockchip,rk3399-gmac": found on RK3399 SoCs + "rockchip,rv1108-gmac": found on RV1108 SoCs - reg: addresses and length of the register sets for the device. - interrupts: Should contain the GMAC interrupts. - interrupt-names: Should contain the interrupt names "macirq". @@ -70,5 +72,4 @@ gmac: ethernet@ff290000 { tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/net/sff,sfp.txt b/Documentation/devicetree/bindings/net/sff,sfp.txt new file mode 100644 index 0000000000000000000000000000000000000000..60e970ce10ee0074b2a8da439bd13658ed187aae --- /dev/null +++ b/Documentation/devicetree/bindings/net/sff,sfp.txt @@ -0,0 +1,76 @@ +Small Form Factor (SFF) Committee Small Form-factor Pluggable (SFP) +Transceiver + +Required properties: + +- compatible : must be "sff,sfp" + +Optional Properties: + +- i2c-bus : phandle of an I2C bus controller for the SFP two wire serial + interface + +- mod-def0-gpios : GPIO phandle and a specifier of the MOD-DEF0 (AKA Mod_ABS) + module presence input gpio signal, active (module absent) high + +- los-gpios : GPIO phandle and a specifier of the Receiver Loss of Signal + Indication input gpio signal, active (signal lost) high + +- tx-fault-gpios : GPIO phandle and a specifier of the Module Transmitter + Fault input gpio signal, active (fault condition) high + +- tx-disable-gpios : GPIO phandle and a specifier of the Transmitter Disable + output gpio signal, active (Tx disable) high + +- rate-select0-gpios : GPIO phandle and a specifier of the Rx Signaling Rate + Select (AKA RS0) output gpio signal, low: low Rx rate, high: high Rx rate + +- rate-select1-gpios : GPIO phandle and a specifier of the Tx Signaling Rate + Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high: + high Tx rate + +Example #1: Direct serdes to SFP connection + +sfp_eth3: sfp-eth3 { + compatible = "sff,sfp"; + i2c-bus = <&sfp_1g_i2c>; + los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>; + tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&cpm_gpio2 19 GPIO_ACTIVE_HIGH>; +}; + +&cps_emac3 { + phy-names = "comphy"; + phys = <&cps_comphy5 0>; + sfp = <&sfp_eth3>; +}; + +Example #2: Serdes to PHY to SFP connection + +sfp_eth0: sfp-eth0 { + compatible = "sff,sfp"; + i2c-bus = <&sfpp0_i2c>; + los-gpios = <&cps_gpio1 28 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&cps_gpio1 27 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&cps_sfpp0_pins>; + tx-disable-gpios = <&cps_gpio1 29 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&cps_gpio1 26 GPIO_ACTIVE_HIGH>; +}; + +p0_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_phy0_pins &cps_phy0_pins>; + reg = <0>; + interrupt = <&cpm_gpio2 18 IRQ_TYPE_EDGE_FALLING>; + sfp = <&sfp_eth0>; +}; + +&cpm_eth0 { + phy = <&p0_phy>; + phy-mode = "10gbase-kr"; +}; diff --git a/Documentation/devicetree/bindings/net/smsc-lan87xx.txt b/Documentation/devicetree/bindings/net/smsc-lan87xx.txt index 974edd5c85cc757322ad48d64cf64460cd0c7518..8b7c719b0bb94ecef956387b866bcb5fa7b39c58 100644 --- a/Documentation/devicetree/bindings/net/smsc-lan87xx.txt +++ b/Documentation/devicetree/bindings/net/smsc-lan87xx.txt @@ -15,7 +15,6 @@ smsc phy with disabled energy detect mode on an am335x based board. pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; - status = "okay"; ethernetphy0: ethernet-phy@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt index 2e68a3cd851350fd9177d3ee8f5451090ad79e60..b30d04b54ee94f93910421caca3badda8fcae01e 100644 --- a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt +++ b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt @@ -40,7 +40,6 @@ gmii_to_sgmii_converter: phy@0x100000240 { gmac0: ethernet@ff700000 { compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; altr,sysmgr-syscon = <&sysmgr 0x60 0>; - status = "disabled"; reg = <0xff700000 0x2000>; interrupts = <0 115 4>; interrupt-names = "macirq"; diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt index d05c1e1fd9b6f05a763efbeb18179d43ac35a50c..062c5174add3263d54a00fb1083fbfd810164f83 100644 --- a/Documentation/devicetree/bindings/net/sti-dwmac.txt +++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt @@ -34,7 +34,6 @@ Example: ethernet0: dwmac@9630000 { device_type = "network"; - status = "disabled"; compatible = "st,stih407-dwmac", "snps,dwmac", "snps,dwmac-3.710"; reg = <0x9630000 0x8000>; reg-names = "stmmaceth"; diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt index c35afb7e956a7120859128bae4cc6de3a80967aa..489dbcb66c5a273df0d444dee4f0a3a280bf8f83 100644 --- a/Documentation/devicetree/bindings/net/stm32-dwmac.txt +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -18,7 +18,6 @@ Example: ethernet@40028000 { compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; - status = "disabled"; reg = <0x40028000 0x8000>; reg-names = "stmmaceth"; interrupts = <0 61 0>, <0 62 0>; diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt index 590f622188de8874586a1b11772f82c4f17f100c..b2bd4704f85928fe96ad43a6c9005d9f43b98907 100644 --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt @@ -29,7 +29,6 @@ mmc3: mmc@01c12000 { vmmc-supply = <®_vmmc3>; bus-width = <4>; non-removable; - status = "okay"; brcmf: wifi@1 { reg = <1>; diff --git a/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt b/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt index 19331bb4ff6e27c3c08fe8883ba5ab363764999b..6830c4786f8ab82d658067b0a16587b436f02abd 100644 --- a/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt +++ b/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt @@ -21,7 +21,6 @@ Example: mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; non-removable; - status = "okay"; esp8089: sdio_wifi@1 { compatible = "esp,esp8089"; diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt index 0854451ff91d79a2f4b224abc3f3c5b4ebee9496..59de8646862d9dc1706a64cd2c79a5c4828de76b 100644 --- a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt +++ b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt @@ -48,7 +48,6 @@ IRQ pin 38 is used as system wakeup source interrupt. wakeup pin 3 is configured so that firmware can wakeup host using this device side pin. &mmc3 { - status = "okay"; vmmc-supply = <&wlan_en_reg>; mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt b/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt index 7b2cbb14113efa83ffee7cb318c33723dfcc956e..f42f6b0f1bc7d5edd3000edea72f90565e79d542 100644 --- a/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt +++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt @@ -31,7 +31,6 @@ clock, new bindings (for parsing the clock nodes) have to be added. Example: &mmc3 { - status = "okay"; vmmc-supply = <&wlan_en_reg>; bus-width = <4>; cap-power-off-card; diff --git a/Documentation/devicetree/bindings/net/xilinx_axienet.txt b/Documentation/devicetree/bindings/net/xilinx_axienet.txt new file mode 100644 index 0000000000000000000000000000000000000000..38f9ec076743a607e57775b9806b7f09b04c6fd1 --- /dev/null +++ b/Documentation/devicetree/bindings/net/xilinx_axienet.txt @@ -0,0 +1,55 @@ +XILINX AXI ETHERNET Device Tree Bindings +-------------------------------------------------------- + +Also called AXI 1G/2.5G Ethernet Subsystem, the xilinx axi ethernet IP core +provides connectivity to an external ethernet PHY supporting different +interfaces: MII, GMII, RGMII, SGMII, 1000BaseX. It also includes two +segments of memory for buffering TX and RX, as well as the capability of +offloading TX/RX checksum calculation off the processor. + +Management configuration is done through the AXI interface, while payload is +sent and received through means of an AXI DMA controller. This driver +includes the DMA driver code, so this driver is incompatible with AXI DMA +driver. + +For more details about mdio please refer phy.txt file in the same directory. + +Required properties: +- compatible : Must be one of "xlnx,axi-ethernet-1.00.a", + "xlnx,axi-ethernet-1.01.a", "xlnx,axi-ethernet-2.01.a" +- reg : Address and length of the IO space. +- interrupts : Should be a list of two interrupt, TX and RX. +- phy-handle : Should point to the external phy device. + See ethernet.txt file in the same directory. +- xlnx,rxmem : Set to allocated memory buffer for Rx/Tx in the hardware + +Optional properties: +- phy-mode : See ethernet.txt +- xlnx,phy-type : Deprecated, do not use, but still accepted in preference + to phy-mode. +- xlnx,txcsum : 0 or empty for disabling TX checksum offload, + 1 to enable partial TX checksum offload, + 2 to enable full TX checksum offload +- xlnx,rxcsum : Same values as xlnx,txcsum but for RX checksum offload + +Example: + axi_ethernet_eth: ethernet@40c00000 { + compatible = "xlnx,axi-ethernet-1.00.a"; + device_type = "network"; + interrupt-parent = <µblaze_0_axi_intc>; + interrupts = <2 0>; + phy-mode = "mii"; + reg = <0x40c00000 0x40000>; + xlnx,rxcsum = <0x2>; + xlnx,rxmem = <0x800>; + xlnx,txcsum = <0x2>; + phy-handle = <&phy0>; + axi_ethernetlite_0_mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@0 { + device_type = "ethernet-phy"; + reg = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt index 74cf52908a6cbe2bb1cdb56148fc0b8fd5971070..0668c45a156d3324fa41f920870b72057fb9567c 100644 --- a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt @@ -3,7 +3,10 @@ This binding is intended to represent MTK-EFUSE which is found in most Mediatek SOCs. Required properties: -- compatible: should be "mediatek,mt8173-efuse" or "mediatek,efuse" +- compatible: should be + "mediatek,mt7622-efuse", "mediatek,efuse": for MT7622 + "mediatek,mt7623-efuse", "mediatek,efuse": for MT7623 + "mediatek,mt8173-efuse" or "mediatek,efuse": for MT8173 - reg: Should contain registers location and length = Data cells = diff --git a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt index daebce9e6b07f470b4ddad31798a67dfb7ecf976..372c72fd64dcdf70b258f41993400e55e44fd65c 100644 --- a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt +++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt @@ -21,5 +21,4 @@ Example for i.MX28: #size-cells = <1>; reg = <0x8002c000 0x2000>; clocks = <&clks 25>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt index e36d261b9ba6427518487b2f7fcbc4692a80a648..9d733af26be7161ac332a187887d244b41e4f211 100644 --- a/Documentation/devicetree/bindings/opp/opp.txt +++ b/Documentation/devicetree/bindings/opp/opp.txt @@ -464,7 +464,6 @@ Example 5: opp-supported-hw opp_table { compatible = "operating-points-v2"; - status = "okay"; opp-shared; opp-600000000 { diff --git a/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt index 35a465362408c2916797f2cf2f107232bb92fe30..b9165b72473c10f6245bd656a6ac169d67cd3257 100644 --- a/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt +++ b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt @@ -1,11 +1,11 @@ * Freescale 83xx and 512x PCI bridges -Freescale 83xx and 512x SOCs include the same pci bridge core. +Freescale 83xx and 512x SOCs include the same PCI bridge core. 83xx/512x specific notes: - reg: should contain two address length tuples - The first is for the internal pci bridge registers - The second is for the pci config space access registers + The first is for the internal PCI bridge registers + The second is for the PCI config space access registers Example (MPC8313ERDB) pci0: pci@e0008500 { diff --git a/Documentation/devicetree/bindings/pci/aardvark-pci.txt b/Documentation/devicetree/bindings/pci/aardvark-pci.txt index bbcd9f4c501fb2b0aa59a85420acfb2ec6eb38d1..310ef7145c47e1b2068648ceb21d190ec1d0aca5 100644 --- a/Documentation/devicetree/bindings/pci/aardvark-pci.txt +++ b/Documentation/devicetree/bindings/pci/aardvark-pci.txt @@ -33,7 +33,6 @@ Example: pcie0: pcie@d0070000 { compatible = "marvell,armada-3700-pcie"; device_type = "pci"; - status = "disabled"; reg = <0 0xd0070000 0 0x20000>; #address-cells = <3>; #size-cells = <2>; diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt index 2951a6a50704bf3234782be2e64abcfaf2496684..495880193adc8c9e9403b5fda893df580718630c 100644 --- a/Documentation/devicetree/bindings/pci/altera-pcie.txt +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt @@ -7,21 +7,21 @@ Required properties: "Txs": TX slave port region "Cra": Control register access region - interrupt-parent: interrupt source phandle. -- interrupts: specifies the interrupt source of the parent interrupt controller. - The format of the interrupt specifier depends on the parent interrupt - controller. +- interrupts: specifies the interrupt source of the parent interrupt + controller. The format of the interrupt specifier depends + on the parent interrupt controller. - device_type: must be "pci" - #address-cells: set to <3> -- #size-cells: set to <2> +- #size-cells: set to <2> - #interrupt-cells: set to <1> -- ranges: describes the translation of addresses for root ports and standard - PCI regions. +- ranges: describes the translation of addresses for root ports and + standard PCI regions. - interrupt-map-mask and interrupt-map: standard PCI properties to define the mapping of the PCIe interface to interrupt numbers. Optional properties: -- msi-parent: Link to the hardware entity that serves as the MSI controller for this PCIe - controller. +- msi-parent: Link to the hardware entity that serves as the MSI controller + for this PCIe controller. - bus-range: PCI bus numbers covered Example @@ -45,5 +45,5 @@ Example <0 0 0 3 &pcie_0 3>, <0 0 0 4 &pcie_0 4>; ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000 - 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>; + 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>; }; diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt index 5ecaea1e6eee8bdbd533f45d1afe371820b72b8d..4e4aee4439ea12acc6eb43a24587e7d67a8acd2e 100644 --- a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt @@ -6,7 +6,7 @@ and thus inherits all the common properties defined in designware-pcie.txt. Required properties: - compatible: "axis,artpec6-pcie", "snps,dw-pcie" - reg: base addresses and lengths of the PCIe controller (DBI), - the phy controller, and configuration address space. + the PHY controller, and configuration address space. - reg-names: Must include the following entries: - "dbi" - "phy" diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index b2480dd38c1135747c6bcceb5153df94a6a36326..1da7ade3183c8f7e0b88a7315036bdd16fcaa09c 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt @@ -1,4 +1,4 @@ -* Synopsys Designware PCIe interface +* Synopsys DesignWare PCIe interface Required properties: - compatible: should contain "snps,dw-pcie" to identify the core. @@ -17,29 +17,27 @@ RC mode: properties to define the mapping of the PCIe interface to interrupt numbers. EP mode: -- num-ib-windows: number of inbound address translation - windows -- num-ob-windows: number of outbound address translation - windows +- num-ib-windows: number of inbound address translation windows +- num-ob-windows: number of outbound address translation windows Optional properties: - num-lanes: number of lanes to use (this property should be specified unless the link is brought already up in BIOS) -- reset-gpio: gpio pin number of power good signal +- reset-gpio: GPIO pin number of power good signal - clocks: Must contain an entry for each entry in clock-names. See ../clocks/clock-bindings.txt for details. - clock-names: Must include the following entries: - "pcie" - "pcie_bus" RC mode: -- num-viewport: number of view ports configured in - hardware. If a platform does not specify it, the driver assumes 2. -- bus-range: PCI bus numbers covered (it is recommended - for new devicetrees to specify this property, to keep backwards - compatibility a range of 0x00-0xff is assumed if not present) +- num-viewport: number of view ports configured in hardware. If a platform + does not specify it, the driver assumes 2. +- bus-range: PCI bus numbers covered (it is recommended for new devicetrees + to specify this property, to keep backwards compatibility a range of + 0x00-0xff is assumed if not present) + EP mode: -- max-functions: maximum number of functions that can be - configured +- max-functions: maximum number of functions that can be configured Example configuration: diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt index cf92d3ba5a269fc10de4eef2057b33fd4fcd6928..7b1e48bf172b74ba51755409cf8510dc0a15fb6d 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt @@ -1,6 +1,6 @@ * Freescale i.MX6 PCIe interface -This PCIe host controller is based on the Synopsis Designware PCIe IP +This PCIe host controller is based on the Synopsys DesignWare PCIe IP and thus inherits all the common properties defined in designware-pcie.txt. Required properties: diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt index a339dbb154933282ee06aaeec0571e0d95a72b42..bdb7ab39d2d7effafede0803adef4eeef1d9bf9a 100644 --- a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt +++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt @@ -1,7 +1,7 @@ HiSilicon Hip05 and Hip06 PCIe host bridge DT description -HiSilicon PCIe host controller is based on Designware PCI core. -It shares common functions with PCIe Designware core driver and inherits +HiSilicon PCIe host controller is based on the Synopsys DesignWare PCI core. +It shares common functions with the PCIe DesignWare core driver and inherits common properties defined in Documentation/devicetree/bindings/pci/designware-pci.txt. @@ -40,7 +40,6 @@ Hip05 Example (note that Hip06 is the same except compatible): 0x0 0 0 2 &mbigen_pcie 2 11 0x0 0 0 3 &mbigen_pcie 3 12 0x0 0 0 4 &mbigen_pcie 4 13>; - status = "ok"; }; HiSilicon Hip06/Hip07 PCIe host bridge DT (almost-ECAM) description. @@ -83,5 +82,4 @@ Example: 0x0 0 0 2 &mbigen_pcie0 650 4 0x0 0 0 3 &mbigen_pcie0 650 4 0x0 0 0 4 &mbigen_pcie0 650 4>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/pci/kirin-pcie.txt b/Documentation/devicetree/bindings/pci/kirin-pcie.txt index 68ffa0fbcd73361b61807d2eef5975846439cadb..6e217c63123db6c1021dba04d09ec419be05fd67 100644 --- a/Documentation/devicetree/bindings/pci/kirin-pcie.txt +++ b/Documentation/devicetree/bindings/pci/kirin-pcie.txt @@ -1,8 +1,8 @@ HiSilicon Kirin SoCs PCIe host DT description -Kirin PCIe host controller is based on Designware PCI core. -It shares common functions with PCIe Designware core driver -and inherits common properties defined in +Kirin PCIe host controller is based on the Synopsys DesignWare PCI core. +It shares common functions with the PCIe DesignWare core driver and +inherits common properties defined in Documentation/devicetree/bindings/pci/designware-pci.txt. Additional properties are described here: @@ -16,7 +16,7 @@ Required properties "apb": apb Ctrl register defined by Kirin; "phy": apb PHY register defined by Kirin; "config": PCIe configuration space registers. -- reset-gpios: The gpio to generate PCIe perst assert and deassert signal. +- reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal. Optional properties: diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index ee1c72d5162ea191ca9a83fd8dcd7baac21312fa..c0484da0f20d9d87f3be44f9bfd844362820bb59 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -15,8 +15,10 @@ Required properties: - compatible: should contain the platform identifier such as: "fsl,ls1021a-pcie", "snps,dw-pcie" "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" + "fsl,ls2088a-pcie" + "fsl,ls1088a-pcie" "fsl,ls1046a-pcie" -- reg: base addresses and lengths of the PCIe controller +- reg: base addresses and lengths of the PCIe controller register blocks. - interrupts: A list of interrupt outputs of the controller. Must contain an entry for each entry in the interrupt-names property. - interrupt-names: Must include the following entries: diff --git a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt deleted file mode 100644 index fe80dda9bf73198caabba24d14999023aee1d64f..0000000000000000000000000000000000000000 --- a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt +++ /dev/null @@ -1,130 +0,0 @@ -MediaTek Gen2 PCIe controller which is available on MT7623 series SoCs - -PCIe subsys supports single root complex (RC) with 3 Root Ports. Each root -ports supports a Gen2 1-lane Link and has PIPE interface to PHY. - -Required properties: -- compatible: Should contain "mediatek,mt7623-pcie". -- device_type: Must be "pci" -- reg: Base addresses and lengths of the PCIe controller. -- #address-cells: Address representation for root ports (must be 3) -- #size-cells: Size representation for root ports (must be 2) -- #interrupt-cells: Size representation for interrupts (must be 1) -- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties - Please refer to the standard PCI bus binding document for a more detailed - explanation. -- clocks: Must contain an entry for each entry in clock-names. - See ../clocks/clock-bindings.txt for details. -- clock-names: Must include the following entries: - - free_ck :for reference clock of PCIe subsys - - sys_ck0 :for clock of Port0 - - sys_ck1 :for clock of Port1 - - sys_ck2 :for clock of Port2 -- resets: Must contain an entry for each entry in reset-names. - See ../reset/reset.txt for details. -- reset-names: Must include the following entries: - - pcie-rst0 :port0 reset - - pcie-rst1 :port1 reset - - pcie-rst2 :port2 reset -- phys: List of PHY specifiers (used by generic PHY framework). -- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the - number of PHYs as specified in *phys* property. -- power-domains: A phandle and power domain specifier pair to the power domain - which is responsible for collapsing and restoring power to the peripheral. -- bus-range: Range of bus numbers associated with this controller. -- ranges: Ranges for the PCI memory and I/O regions. - -In addition, the device tree node must have sub-nodes describing each -PCIe port interface, having the following mandatory properties: - -Required properties: -- device_type: Must be "pci" -- reg: Only the first four bytes are used to refer to the correct bus number - and device number. -- #address-cells: Must be 3 -- #size-cells: Must be 2 -- #interrupt-cells: Must be 1 -- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties - Please refer to the standard PCI bus binding document for a more detailed - explanation. -- ranges: Sub-ranges distributed from the PCIe controller node. An empty - property is sufficient. -- num-lanes: Number of lanes to use for this port. - -Examples: - - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", - "syscon"; - reg = <0 0x1a000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - pcie: pcie-controller@1a140000 { - compatible = "mediatek,mt7623-pcie"; - device_type = "pci"; - reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ - <0 0x1a142000 0 0x1000>, /* Port0 registers */ - <0 0x1a143000 0 0x1000>, /* Port1 registers */ - <0 0x1a144000 0 0x1000>; /* Port2 registers */ - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0xf800 0 0 0>; - interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, - <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, - <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; - clocks = <&topckgen CLK_TOP_ETHIF_SEL>, - <&hifsys CLK_HIFSYS_PCIE0>, - <&hifsys CLK_HIFSYS_PCIE1>, - <&hifsys CLK_HIFSYS_PCIE2>; - clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; - resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, - <&hifsys MT2701_HIFSYS_PCIE1_RST>, - <&hifsys MT2701_HIFSYS_PCIE2_RST>; - reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; - phys = <&pcie0_phy>, <&pcie1_phy>, <&pcie2_phy>; - phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; - bus-range = <0x00 0xff>; - ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ - 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ - - pcie@0,0 { - device_type = "pci"; - reg = <0x0000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; - ranges; - num-lanes = <1>; - }; - - pcie@1,0 { - device_type = "pci"; - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; - ranges; - num-lanes = <1>; - }; - - pcie@2,0 { - device_type = "pci"; - reg = <0x1000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; - ranges; - num-lanes = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a6ce55dd310b1a2e2ba2ff572a8692a65bf8e35 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt @@ -0,0 +1,284 @@ +MediaTek Gen2 PCIe controller + +Required properties: +- compatible: Should contain one of the following strings: + "mediatek,mt2701-pcie" + "mediatek,mt2712-pcie" + "mediatek,mt7622-pcie" + "mediatek,mt7623-pcie" +- device_type: Must be "pci" +- reg: Base addresses and lengths of the PCIe subsys and root ports. +- reg-names: Names of the above areas to use during resource lookup. +- #address-cells: Address representation for root ports (must be 3) +- #size-cells: Size representation for root ports (must be 2) +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: + Mandatory entries: + - sys_ckN :transaction layer and data link layer clock + Required entries for MT2701/MT7623: + - free_ck :for reference clock of PCIe subsys + Required entries for MT2712/MT7622: + - ahb_ckN :AHB slave interface operating clock for CSR access and RC + initiated MMIO access + Required entries for MT7622: + - axi_ckN :application layer MMIO channel operating clock + - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when + pcie_mac_ck/pcie_pipe_ck is turned off + - obff_ckN :OBFF functional block operating clock + - pipe_ckN :LTSSM and PHY/MAC layer operating clock + where N starting from 0 to one less than the number of root ports. +- phys: List of PHY specifiers (used by generic PHY framework). +- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the + number of PHYs as specified in *phys* property. +- power-domains: A phandle and power domain specifier pair to the power domain + which is responsible for collapsing and restoring power to the peripheral. +- bus-range: Range of bus numbers associated with this controller. +- ranges: Ranges for the PCI memory and I/O regions. + +Required properties for MT7623/MT2701: +- #interrupt-cells: Size representation for interrupts (must be 1) +- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties + Please refer to the standard PCI bus binding document for a more detailed + explanation. +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the + number of root ports. + +Required properties for MT2712/MT7622: +-interrupts: A list of interrupt outputs of the controller, must have one + entry for each PCIe port + +In addition, the device tree node must have sub-nodes describing each +PCIe port interface, having the following mandatory properties: + +Required properties: +- device_type: Must be "pci" +- reg: Only the first four bytes are used to refer to the correct bus number + and device number. +- #address-cells: Must be 3 +- #size-cells: Must be 2 +- #interrupt-cells: Must be 1 +- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties + Please refer to the standard PCI bus binding document for a more detailed + explanation. +- ranges: Sub-ranges distributed from the PCIe controller node. An empty + property is sufficient. +- num-lanes: Number of lanes to use for this port. + +Examples for MT7623: + + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pcie: pcie-controller@1a140000 { + compatible = "mediatek,mt7623-pcie"; + device_type = "pci"; + reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ + <0 0x1a142000 0 0x1000>, /* Port0 registers */ + <0 0x1a143000 0 0x1000>, /* Port1 registers */ + <0 0x1a144000 0 0x1000>; /* Port2 registers */ + reg-names = "subsys", "port0", "port1", "port2"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 0>; + interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, + <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, + <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <&hifsys CLK_HIFSYS_PCIE0>, + <&hifsys CLK_HIFSYS_PCIE1>, + <&hifsys CLK_HIFSYS_PCIE2>; + clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; + resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, + <&hifsys MT2701_HIFSYS_PCIE1_RST>, + <&hifsys MT2701_HIFSYS_PCIE2_RST>; + reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>, + <&pcie2_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + bus-range = <0x00 0xff>; + ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ + 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ + + pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + + pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + + pcie@2,0 { + device_type = "pci"; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + }; + +Examples for MT2712: + pcie: pcie@11700000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; + reg = <0 0x11700000 0 0x1000>, + <0 0x112ff000 0 0x1000>; + reg-names = "port0", "port1"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = , + ; + clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, + <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, + <&pericfg CLK_PERI_PCIE0>, + <&pericfg CLK_PERI_PCIE1>; + clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1"; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; + + pcie0: pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie1: pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; + +Examples for MT7622: + pcie: pcie@1a140000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0 0x1a140000 0 0x1000>, + <0 0x1a143000 0 0x1000>, + <0 0x1a145000 0 0x1000>; + reg-names = "subsys", "port0", "port1"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = , + ; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, + <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P1_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, + <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, + <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, + <&pciesys CLK_PCIE_P1_OBFF_EN>, + <&pciesys CLK_PCIE_P0_PIPE_EN>, + <&pciesys CLK_PCIE_P1_PIPE_EN>; + clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", + "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", + "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1"; + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; + + pcie0: pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie1: pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt index 2de6f65ecfb11017e31a3313cdc07fce0c9dbb00..6173af6885f86731a9e81182737afc0a185cd212 100644 --- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt +++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt @@ -77,7 +77,7 @@ and the following optional properties: - marvell,pcie-lane: the physical PCIe lane number, for ports having multiple lanes. If this property is not found, we assume that the value is 0. -- reset-gpios: optional gpio to PERST# +- reset-gpios: optional GPIO to PERST# - reset-delay-us: delay in us to wait after reset de-assertion, if not specified will default to 100ms, as required by the PCIe specification. @@ -85,7 +85,6 @@ Example: pcie-controller { compatible = "marvell,armada-xp-pcie"; - status = "disabled"; device_type = "pci"; #address-cells = <3>; @@ -147,7 +146,6 @@ pcie-controller { /* wait 20ms for device settle after reset deassertion */ reset-delay-us = <20000>; clocks = <&gateclk 5>; - status = "disabled"; }; pcie@2,0 { @@ -164,7 +162,6 @@ pcie-controller { marvell,pcie-port = <0>; marvell,pcie-lane = <1>; clocks = <&gateclk 6>; - status = "disabled"; }; pcie@3,0 { @@ -181,7 +178,6 @@ pcie-controller { marvell,pcie-port = <0>; marvell,pcie-lane = <2>; clocks = <&gateclk 7>; - status = "disabled"; }; pcie@4,0 { @@ -198,7 +194,6 @@ pcie-controller { marvell,pcie-port = <0>; marvell,pcie-lane = <3>; clocks = <&gateclk 8>; - status = "disabled"; }; pcie@5,0 { @@ -215,7 +210,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 9>; - status = "disabled"; }; pcie@6,0 { @@ -232,7 +226,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <1>; clocks = <&gateclk 10>; - status = "disabled"; }; pcie@7,0 { @@ -249,7 +242,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <2>; clocks = <&gateclk 11>; - status = "disabled"; }; pcie@8,0 { @@ -266,7 +258,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <3>; clocks = <&gateclk 12>; - status = "disabled"; }; pcie@9,0 { @@ -283,10 +274,9 @@ pcie-controller { marvell,pcie-port = <2>; marvell,pcie-lane = <0>; clocks = <&gateclk 26>; - status = "disabled"; }; - pcie@10,0 { + pcie@a,0 { device_type = "pci"; assigned-addresses = <0x82005000 0 0x82000 0 0x2000>; reg = <0x5000 0 0 0 0>; @@ -300,6 +290,5 @@ pcie-controller { marvell,pcie-port = <3>; marvell,pcie-lane = <0>; clocks = <&gateclk 27>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/pci/pci-armada8k.txt b/Documentation/devicetree/bindings/pci/pci-armada8k.txt index 598533a57d79bc0155e456fdd3bac0a715b661c6..c1e4c3d10a747c008c2b914c89194228caed395e 100644 --- a/Documentation/devicetree/bindings/pci/pci-armada8k.txt +++ b/Documentation/devicetree/bindings/pci/pci-armada8k.txt @@ -1,6 +1,6 @@ * Marvell Armada 7K/8K PCIe interface -This PCIe host controller is based on the Synopsis Designware PCIe IP +This PCIe host controller is based on the Synopsys DesignWare PCIe IP and thus inherits all the common properties defined in designware-pcie.txt. Required properties: @@ -34,5 +34,4 @@ Example: interrupts = ; num-lanes = <1>; clocks = <&cpm_syscon0 1 13>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pci/pci-keystone.txt b/Documentation/devicetree/bindings/pci/pci-keystone.txt index d08a4d51108f7419e2ec547dbed4d9b9620ccc09..7e05487544edffae025e1071406fe711cf220773 100644 --- a/Documentation/devicetree/bindings/pci/pci-keystone.txt +++ b/Documentation/devicetree/bindings/pci/pci-keystone.txt @@ -1,12 +1,12 @@ TI Keystone PCIe interface -Keystone PCI host Controller is based on Designware PCI h/w version 3.65. -It shares common functions with PCIe Designware core driver and inherit -common properties defined in +Keystone PCI host Controller is based on the Synopsys DesignWare PCI +hardware version 3.65. It shares common functions with the PCIe DesignWare +core driver and inherits common properties defined in Documentation/devicetree/bindings/pci/designware-pci.txt Please refer to Documentation/devicetree/bindings/pci/designware-pci.txt -for the details of Designware DT bindings. Additional properties are +for the details of DesignWare DT bindings. Additional properties are described here as well as properties that are not applicable. Required Properties:- @@ -52,13 +52,12 @@ pcie_intc: Interrupt controller device node for Legacy IRQ chip }; Optional properties:- - phys: phandle to Generic Keystone SerDes phy for PCI - phy-names: name of the Generic Keystine SerDes phy for PCI + phys: phandle to generic Keystone SerDes PHY for PCI + phy-names: name of the generic Keystone SerDes PHY for PCI - If boot loader already does PCI link establishment, then phys and phy-names shouldn't be present. interrupts: platform interrupt for error interrupts. -Designware DT Properties not applicable for Keystone PCI +DesignWare DT Properties not applicable for Keystone PCI 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. - diff --git a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt index 07a75094c5a8ed07e927c0641584d5e8348e3dc6..3d038638612b8ec2af704adaf6dcd5b0bc81b1e6 100644 --- a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt +++ b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt @@ -6,11 +6,14 @@ AHB. There is one bridge instance per USB port connected to the internal OHCI and EHCI controllers. Required properties: -- compatible: "renesas,pci-r8a7790" for the R8A7790 SoC; +- compatible: "renesas,pci-r8a7743" for the R8A7743 SoC; + "renesas,pci-r8a7745" for the R8A7745 SoC; + "renesas,pci-r8a7790" for the R8A7790 SoC; "renesas,pci-r8a7791" for the R8A7791 SoC; "renesas,pci-r8a7793" for the R8A7793 SoC; "renesas,pci-r8a7794" for the R8A7794 SoC; - "renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device + "renesas,pci-rcar-gen2" for a generic R-Car Gen2 or + RZ/G1 compatible device. When compatible with the generic version, nodes must list the diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt index 50f9e2ca5b13dd6677aca086437c24e2aadeb750..c77981c5dd18f6edff3affcb40cd88720633b5db 100644 --- a/Documentation/devicetree/bindings/pci/pci.txt +++ b/Documentation/devicetree/bindings/pci/pci.txt @@ -1,12 +1,12 @@ PCI bus bridges have standardized Device Tree bindings: PCI Bus Binding to: IEEE Std 1275-1994 -http://www.firmware.org/1275/bindings/pci/pci2_1.pdf +http://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf And for the interrupt mapping part: Open Firmware Recommended Practice: Interrupt Mapping -http://www.firmware.org/1275/practice/imap/imap0_9d.pdf +http://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf Additionally to the properties specified in the above standards a host bridge driver implementation may support the following properties: diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt index 9d418b71774f356c22c640c72943a836fdb5fe14..3c9d321b3d3b0d22e04d7ba8f022982ffc452cce 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt @@ -9,6 +9,7 @@ - "qcom,pcie-apq8084" for apq8084 - "qcom,pcie-msm8996" for msm8996 or apq8096 - "qcom,pcie-ipq4019" for ipq4019 + - "qcom,pcie-ipq8074" for ipq8074 - reg: Usage: required @@ -20,7 +21,7 @@ Value type: Definition: Must include the following entries - "parf" Qualcomm specific registers - - "dbi" Designware PCIe registers + - "dbi" DesignWare PCIe registers - "elbi" External local bus interface registers - "config" PCIe configuration space @@ -105,6 +106,16 @@ - "bus_master" Master AXI clock - "bus_slave" Slave AXI clock +- clock-names: + Usage: required for ipq8074 + Value type: + Definition: Should contain the following entries + - "iface" PCIe to SysNOC BIU clock + - "axi_m" AXI Master clock + - "axi_s" AXI Slave clock + - "ahb" AHB clock + - "aux" Auxiliary clock + - resets: Usage: required Value type: @@ -144,6 +155,18 @@ - "ahb" AHB reset - "phy_ahb" PHY AHB reset +- reset-names: + Usage: required for ipq8074 + Value type: + Definition: Should contain the following entries + - "pipe" PIPE reset + - "sleep" Sleep reset + - "sticky" Core Sticky reset + - "axi_m" AXI Master reset + - "axi_s" AXI Slave reset + - "ahb" AHB Reset + - "axi_m_sticky" AXI Master Sticky reset + - power-domains: Usage: required for apq8084 and msm8996/apq8096 Value type: @@ -180,7 +203,7 @@ - -gpios: Usage: optional Value type: - Definition: List of phandle and gpio specifier pairs. Should contain + Definition: List of phandle and GPIO specifier pairs. Should contain - "perst-gpios" PCIe endpoint reset signal line - "wake-gpios" PCIe endpoint wake signal line diff --git a/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt b/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt index 8e0a1eb0acbbd73938e9a22cba8e96f497e9ef59..a04ab1b762110fc3f63441e5aa771c04334a6a44 100644 --- a/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt +++ b/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt @@ -71,7 +71,7 @@ - interrupt-map: standard PCI properties to define the mapping of the PCI interface to interrupt numbers. - The PCI host bridge node migh have additional sub-nodes representing + The PCI host bridge node might have additional sub-nodes representing the onboard PCI devices/PCI slots. Each such sub-node must have the following mandatory properties: diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt index bd27428dda619d613a1af05dbd583b743c0e6c22..76ba3a61d1a31c1fea2e492a438e6d4a01a316cd 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci.txt +++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt @@ -14,7 +14,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; SoC-specific version corresponding to the platform first followed by the generic version. -- reg: base address and length of the pcie controller registers. +- reg: base address and length of the PCIe controller registers. - #address-cells: set to <3> - #size-cells: set to <2> - bus-range: PCI bus numbers covered @@ -25,15 +25,14 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; source for hardware related interrupts (e.g. link speed change). - #interrupt-cells: set to <1> - interrupt-map-mask and interrupt-map: standard PCI properties - to define the mapping of the PCIe interface to interrupt - numbers. + to define the mapping of the PCIe interface to interrupt numbers. - clocks: from common clock binding: clock specifiers for the PCIe controller and PCIe bus clocks. - clock-names: from common clock binding: should be "pcie" and "pcie_bus". Example: -SoC specific DT Entry: +SoC-specific DT Entry: pcie: pcie@fe000000 { compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2"; @@ -54,5 +53,4 @@ SoC specific DT Entry: interrupt-map = <0 0 0 0 &gic 0 116 4>; clocks = <&mstp3_clks R8A7791_CLK_PCIE>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt index 1453a734c2f5b53bf606807e99871619ca132b12..af34c65773fd7fc540411b06be96011cc84828d1 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt +++ b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt @@ -19,8 +19,6 @@ Required properties: - "pm" - msi-map: Maps a Requester ID to an MSI controller and associated msi-specifier data. See ./pci-msi.txt -- phys: From PHY bindings: Phandle for the Generic PHY for PCIe. -- phy-names: MUST be "pcie-phy". - interrupts: Three interrupt entries must be specified. - interrupt-names: Must include the following names - "sys" @@ -42,11 +40,24 @@ Required properties: interrupt source. The value must be 1. - interrupt-map-mask and interrupt-map: standard PCI properties +Required properties for legacy PHY model (deprecated): +- phys: From PHY bindings: Phandle for the Generic PHY for PCIe. +- phy-names: MUST be "pcie-phy". + +Required properties for per-lane PHY model (preferred): +- phys: Must contain an phandle to a PHY for each entry in phy-names. +- phy-names: Must include 4 entries for all 4 lanes even if some of + them won't be used for your cases. Entries are of the form "pcie-phy-N": + where N ranges from 0 to 3. + (see example below and you MUST also refer to ../phy/rockchip-pcie-phy.txt + for changing the #phy-cells of phy node to support it) + Optional Property: - aspm-no-l0s: RC won't support ASPM L0s. This property is needed if using 24MHz OSC for RC's PHY. -- ep-gpios: contain the entry for pre-reset gpio +- ep-gpios: contain the entry for pre-reset GPIO - num-lanes: number of lanes to use +- vpcie12v-supply: The phandle to the 12v regulator to use for PCIe. - vpcie3v3-supply: The phandle to the 3.3v regulator to use for PCIe. - vpcie1v8-supply: The phandle to the 1.8v regulator to use for PCIe. - vpcie0v9-supply: The phandle to the 0.9v regulator to use for PCIe. @@ -95,6 +106,7 @@ pcie0: pcie@f8000000 { <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; reset-names = "core", "mgmt", "mgmt-sticky", "pipe", "pm", "pclk", "aclk"; + /* deprecated legacy PHY model */ phys = <&pcie_phy>; phy-names = "pcie-phy"; pinctrl-names = "default"; @@ -111,3 +123,13 @@ pcie0: pcie@f8000000 { #interrupt-cells = <1>; }; }; + +pcie0: pcie@f8000000 { + ... + + /* preferred per-lane PHY model */ + phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>; + phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3"; + + ... +}; diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt index 7d3b09474657b81b7574932786e856475ead2f10..34a11bfbfb600ea38ceaabfea145811b4f40f946 100644 --- a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt +++ b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt @@ -1,29 +1,29 @@ * Samsung Exynos 5440 PCIe interface -This PCIe host controller is based on the Synopsis Designware PCIe IP +This PCIe host controller is based on the Synopsys DesignWare PCIe IP and thus inherits all the common properties defined in designware-pcie.txt. Required properties: - compatible: "samsung,exynos5440-pcie" -- reg: base addresses and lengths of the pcie controller, - the phy controller, additional register for the phy controller. - (Registers for the phy controller are DEPRECATED. +- reg: base addresses and lengths of the PCIe controller, + the PHY controller, additional register for the PHY controller. + (Registers for the PHY controller are DEPRECATED. Use the PHY framework.) - reg-names : First name should be set to "elbi". - And use the "config" instead of getting the confgiruation address space + And use the "config" instead of getting the configuration address space from "ranges". - NOTE: When use the "config" property, reg-names must be set. + NOTE: When using the "config" property, reg-names must be set. - interrupts: A list of interrupt outputs for level interrupt, pulse interrupt, special interrupt. -- phys: From PHY binding. Phandle for the Generic PHY. +- phys: From PHY binding. Phandle for the generic PHY. Refer to Documentation/devicetree/bindings/phy/samsung-phy.txt -Other common properties refer to - Documentation/devicetree/binding/pci/designware-pcie.txt +For other common properties, refer to + Documentation/devicetree/bindings/pci/designware-pcie.txt Example: -SoC specific DT Entry: +SoC-specific DT Entry: pcie@290000 { compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; @@ -83,7 +83,7 @@ With using PHY framework: ... }; -Board specific DT Entry: +Board-specific DT Entry: pcie@290000 { reset-gpio = <&pin_ctrl 5 0>; diff --git a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt index 49ea76da77183cf89a15a1cfff13ed4a7ac1b3c5..d5a14f5dad46cc5937031045cc0bd698610130f4 100644 --- a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt +++ b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt @@ -1,12 +1,12 @@ SPEAr13XX PCIe DT detail: ================================ -SPEAr13XX uses synopsis designware PCIe controller and ST MiPHY as phy +SPEAr13XX uses the Synopsys DesignWare PCIe controller and ST MiPHY as PHY controller. Required properties: -- compatible : should be "st,spear1340-pcie", "snps,dw-pcie". -- phys : phandle to phy node associated with pcie controller +- compatible : should be "st,spear1340-pcie", "snps,dw-pcie". +- phys : phandle to PHY node associated with PCIe controller - phy-names : must be "pcie-phy" - All other definitions as per generic PCI bindings diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt index 6a07c96227e0a0a9bd96530c2833df195657e7dc..7f7af3044016a6b4578cb4df6e8ff90e2a7ed45c 100644 --- a/Documentation/devicetree/bindings/pci/ti-pci.txt +++ b/Documentation/devicetree/bindings/pci/ti-pci.txt @@ -1,6 +1,6 @@ TI PCI Controllers -PCIe Designware Controller +PCIe DesignWare Controller - compatible: Should be "ti,dra7-pcie" for RC Should be "ti,dra7-pcie-ep" for EP - phys : list of PHY specifiers (used by generic PHY framework) @@ -13,7 +13,7 @@ PCIe Designware Controller HOST MODE ========= - reg : Two register ranges as listed in the reg-names property - - reg-names : The first entry must be "ti-conf" for the TI specific registers + - reg-names : The first entry must be "ti-conf" for the TI-specific registers The second entry must be "rc-dbics" for the DesignWare PCIe registers The third entry must be "config" for the PCIe configuration space @@ -30,7 +30,7 @@ HOST MODE DEVICE MODE =========== - reg : Four register ranges as listed in the reg-names property - - reg-names : "ti-conf" for the TI specific registers + - reg-names : "ti-conf" for the TI-specific registers "ep_dbics" for the standard configuration registers as they are locally accessed within the DIF CS space "ep_dbics2" for the standard configuration registers as @@ -46,7 +46,7 @@ DEVICE MODE access. Optional Property: - - gpios : Should be added if a gpio line is required to drive PERST# line + - gpios : Should be added if a GPIO line is required to drive PERST# line NOTE: Two DT nodes may be added for each PCI controller; one for host mode and another for device mode. So in order for PCI to diff --git a/Documentation/devicetree/bindings/pci/versatile.txt b/Documentation/devicetree/bindings/pci/versatile.txt index ebd1e7d0403ed1406a846f0cf08f173cb3a8eab7..0a702b13d2acc28a5e460f033384e2d4f57dbc25 100644 --- a/Documentation/devicetree/bindings/pci/versatile.txt +++ b/Documentation/devicetree/bindings/pci/versatile.txt @@ -5,7 +5,7 @@ PCI host controller found on the ARM Versatile PB board's FPGA. Required properties: - compatible: should contain "arm,versatile-pci" to identify the Versatile PCI controller. -- reg: base addresses and lengths of the pci controller. There must be 3 +- reg: base addresses and lengths of the PCI controller. There must be 3 entries: - Versatile-specific registers - Self Config space diff --git a/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt b/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt index 36d881c8e6d448e835430bfe227bdad85ed54b1a..85d9b95234f7d914af80ae1c81b98cd2ff31cdae 100644 --- a/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt +++ b/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt @@ -4,7 +4,7 @@ Required properties: - compatible: should be "apm,xgene1-msi" to identify X-Gene v1 PCIe MSI controller block. -- msi-controller: indicates that this is X-Gene v1 PCIe MSI controller node +- msi-controller: indicates that this is an X-Gene v1 PCIe MSI controller node - reg: physical base address (0x79000000) and length (0x900000) for controller registers. These registers include the MSI termination address and data registers as well as the MSI interrupt status registers. @@ -13,7 +13,8 @@ Required properties: interrupt number 0x10 to 0x1f. - interrupt-names: not required -Each PCIe node needs to have property msi-parent that points to msi controller node +Each PCIe node needs to have property msi-parent that points to an MSI +controller node Examples: @@ -44,7 +45,6 @@ SoC DTSI: + PCIe controller node with msi-parent property pointing to MSI node: pcie0: pcie@1f2b0000 { - status = "disabled"; device_type = "pci"; compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; #interrupt-cells = <1>; diff --git a/Documentation/devicetree/bindings/pci/xgene-pci.txt b/Documentation/devicetree/bindings/pci/xgene-pci.txt index 1070b068c7c6496e917eadeff79083b41328077a..6fd2decfa66c4b30d0de6d77f57ceef77eadd28a 100644 --- a/Documentation/devicetree/bindings/pci/xgene-pci.txt +++ b/Documentation/devicetree/bindings/pci/xgene-pci.txt @@ -8,7 +8,7 @@ Required properties: property. - reg-names: Must include the following entries: "csr": controller configuration registers. - "cfg": pcie configuration space registers. + "cfg": PCIe configuration space registers. - #address-cells: set to <3> - #size-cells: set to <2> - ranges: ranges for the outbound memory, I/O regions. @@ -21,11 +21,11 @@ Required properties: Optional properties: - status: Either "ok" or "disabled". -- dma-coherent: Present if dma operations are coherent +- dma-coherent: Present if DMA operations are coherent Example: -SoC specific DT Entry: +SoC-specific DT Entry: pcie0: pcie@1f2b0000 { status = "disabled"; @@ -51,7 +51,7 @@ SoC specific DT Entry: }; -Board specific DT Entry: +Board-specific DT Entry: &pcie0 { status = "ok"; }; diff --git a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt index 3259798a1192b051520b3cad2412a6f59fb6dfa5..01bf7fdf4c19208f38dba304909e432a45b90560 100644 --- a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt +++ b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt @@ -15,9 +15,9 @@ Required properties: - device_type: must be "pci" - interrupts: Should contain NWL PCIe interrupt - interrupt-names: Must include the following entries: - "msi1, msi0": interrupt asserted when MSI is received + "msi1, msi0": interrupt asserted when an MSI is received "intx": interrupt asserted when a legacy interrupt is received - "misc": interrupt asserted when miscellaneous is received + "misc": interrupt asserted when miscellaneous interrupt is received - interrupt-map-mask and interrupt-map: standard PCI properties to define the mapping of the PCI interface to interrupt numbers. - ranges: ranges for the PCI memory regions (I/O space region is not @@ -26,7 +26,8 @@ Required properties: detailed explanation - msi-controller: indicates that this is MSI controller node - msi-parent: MSI parent of the root complex itself -- legacy-interrupt-controller: Interrupt controller device node for Legacy interrupts +- legacy-interrupt-controller: Interrupt controller device node for Legacy + interrupts - interrupt-controller: identifies the node as an interrupt controller - #interrupt-cells: should be set to 1 - #address-cells: specifies the number of cells needed to encode an diff --git a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt index 5f3a65a9dd885be01826435c69f35a7989348bd5..e1bb12711fbf8266bccecde2cbac1cf39ea29b94 100644 --- a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt +++ b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt @@ -61,19 +61,16 @@ Example: compatible = "apm,xgene-phy"; reg = <0x0 0x1f21a000 0x0 0x100>; #phy-cells = <1>; - status = "disabled"; }; phy2: phy@1f22a000 { compatible = "apm,xgene-phy"; reg = <0x0 0x1f22a000 0x0 0x100>; #phy-cells = <1>; - status = "ok"; }; phy3: phy@1f23a000 { compatible = "apm,xgene-phy"; reg = <0x0 0x1f23a000 0x0 0x100>; #phy-cells = <1>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt b/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt index f37b3a86341d9d47e1c3d8b6e468b287e27bb6cb..300830dda0bf2f72a5e70308ed7e4ff85c4457c3 100644 --- a/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt @@ -16,5 +16,4 @@ usb_phy: usb_phy@2620738 { #address-cells = <1>; #size-cells = <1>; reg = <0x2620738 32>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt index 1293c321754c67014a4bdc4d4165ba517bac398d..a403b81d0679622d0b473edf545898618fc66836 100644 --- a/Documentation/devicetree/bindings/phy/phy-bindings.txt +++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt @@ -34,7 +34,9 @@ PHY user node ============= Required Properties: -phys : the phandle for the PHY device (used by the PHY subsystem) +phys : the phandle for the PHY device (used by the PHY subsystem; not to be + confused with the Ethernet specific 'phy' and 'phy-handle' properties, + see Documentation/devicetree/bindings/net/ethernet.txt for these) phy-names : the names of the PHY corresponding to the PHYs present in the *phys* phandle diff --git a/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt new file mode 100644 index 0000000000000000000000000000000000000000..643948b6b576515ac83d4c39e0ff24087947e61b --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt @@ -0,0 +1,40 @@ +Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding +=========================================== + +This binding describes the USB PHY hardware provided by the RCU module on the +Lantiq XWAY SoCs. + +This node has to be a sub node of the Lantiq RCU block. + +------------------------------------------------------------------------------- +Required properties (controller (parent) node): +- compatible : Should be one of + "lantiq,ase-usb2-phy" + "lantiq,danube-usb2-phy" + "lantiq,xrx100-usb2-phy" + "lantiq,xrx200-usb2-phy" + "lantiq,xrx300-usb2-phy" +- reg : Defines the following sets of registers in the parent + syscon device + - Offset of the USB PHY configuration register + - Offset of the USB Analog configuration + register (only for xrx200 and xrx200) +- clocks : References to the (PMU) "phy" clk gate. +- clock-names : Must be "phy" +- resets : References to the RCU USB configuration reset bits. +- reset-names : Must be one of the following: + "phy" (optional) + "ctrl" (shared) + +------------------------------------------------------------------------------- +Example for the USB PHYs on an xRX200 SoC: + usb_phy0: usb2-phy@18 { + compatible = "lantiq,xrx200-usb2-phy"; + reg = <0x18 4>, <0x38 4>; + + clocks = <&pmu PMU_GATE_USB0_PHY>; + clock-names = "phy"; + resets = <&reset1 4 4>, <&reset0 4 4>; + reset-names = "phy", "ctrl"; + #phy-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt similarity index 88% rename from Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt rename to Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt index 0acc5a99fb79227262ed6ef1f8d8774fefcb914a..41e09ed2ca70e2caaf7ee65b2f67651fba7bb9f4 100644 --- a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt +++ b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt @@ -1,13 +1,18 @@ -mt65xx USB3.0 PHY binding +MediaTek T-PHY binding -------------------------- -This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC. +T-phy controller supports physical layer functionality for a number of +controllers on MediaTek SoCs, such as, USB2.0, USB3.0, PCIe, and SATA. Required properties (controller (parent) node): - compatible : should be one of - "mediatek,mt2701-u3phy" - "mediatek,mt2712-u3phy" - "mediatek,mt8173-u3phy" + "mediatek,generic-tphy-v1" + "mediatek,generic-tphy-v2" + "mediatek,mt2701-u3phy" (deprecated) + "mediatek,mt2712-u3phy" (deprecated) + "mediatek,mt8173-u3phy"; + make use of "mediatek,generic-tphy-v1" on mt2701 instead and + "mediatek,generic-tphy-v2" on mt2712 instead. - clocks : (deprecated, use port's clocks instead) a list of phandle + clock-specifier pairs, one for each entry in clock-names - clock-names : (deprecated, use port's one instead) must contain @@ -35,6 +40,8 @@ Required properties (port (child) node): cell after port phandle is phy type from: - PHY_TYPE_USB2 - PHY_TYPE_USB3 + - PHY_TYPE_PCIE + - PHY_TYPE_SATA Example: @@ -44,14 +51,12 @@ u3phy: usb-phy@11290000 { #address-cells = <2>; #size-cells = <2>; ranges; - status = "okay"; u2port0: usb-phy@11290800 { reg = <0 0x11290800 0 0x100>; clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; clock-names = "ref"; #phy-cells = <1>; - status = "okay"; }; u3port0: usb-phy@11290900 { @@ -59,7 +64,6 @@ u3phy: usb-phy@11290000 { clocks = <&clk26m>; clock-names = "ref"; #phy-cells = <1>; - status = "okay"; }; u2port1: usb-phy@11291000 { @@ -67,7 +71,6 @@ u3phy: usb-phy@11290000 { clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; clock-names = "ref"; #phy-cells = <1>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt b/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt new file mode 100644 index 0000000000000000000000000000000000000000..bfcf80341657ce6ba39891ff10b1c9c19d775a0a --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt @@ -0,0 +1,43 @@ +mvebu comphy driver +------------------- + +A comphy controller can be found on Marvell Armada 7k/8k on the CP110. It +provides a number of shared PHYs used by various interfaces (network, sata, +usb, PCIe...). + +Required properties: + +- compatible: should be "marvell,comphy-cp110" +- reg: should contain the comphy register location and length. +- marvell,system-controller: should contain a phandle to the + system controller node. +- #address-cells: should be 1. +- #size-cells: should be 0. + +A sub-node is required for each comphy lane provided by the comphy. + +Required properties (child nodes): + +- reg: comphy lane number. +- #phy-cells : from the generic phy bindings, must be 1. Defines the + input port to use for a given comphy lane. + +Example: + + cpm_comphy: phy@120000 { + compatible = "marvell,comphy-cp110"; + reg = <0x120000 0x6000>; + marvell,system-controller = <&cpm_syscon0>; + #address-cells = <1>; + #size-cells = <0>; + + cpm_comphy0: phy@0 { + reg = <0>; + #phy-cells = <1>; + }; + + cpm_comphy1: phy@1 { + reg = <1>; + #phy-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu.txt b/Documentation/devicetree/bindings/phy/phy-mvebu.txt index f95b6260a3b3d148570a06e7a5e08d9659794661..64afdd13d91dfd4a9f1f299d632b64689f8a8b8d 100644 --- a/Documentation/devicetree/bindings/phy/phy-mvebu.txt +++ b/Documentation/devicetree/bindings/phy/phy-mvebu.txt @@ -18,7 +18,6 @@ Example: clocks = <&gate_clk 15>; clock-names = "sata"; #phy-cells = <0>; - status = "ok"; }; Armada 375 USB cluster diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt index 84d59b0db8df5f095cdbe2c5328407af122b9b79..074a7b3b0425ddadac96079d0cdd83f7f9352582 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt @@ -6,6 +6,7 @@ Required properties (phy (parent) node): * "rockchip,rk3328-usb2phy" * "rockchip,rk3366-usb2phy" * "rockchip,rk3399-usb2phy" + * "rockchip,rv1108-usb2phy" - reg : the address offset of grf for usb-phy configuration. - #clock-cells : should be 0. - clock-output-names : specify the 480m output clock name. @@ -18,6 +19,10 @@ Optional properties: usb-phy output 480m and xin24m. Refer to clk/clock-bindings.txt for generic clock consumer properties. + - rockchip,usbgrf : phandle to the syscon managing the "usb general + register files". When set driver will request its + phandle as one companion-grf for some special SoCs + (e.g RV1108). Required nodes : a sub-node is required for each port the phy provides. The sub-node name is used to identify host or otg port, @@ -28,10 +33,14 @@ Required nodes : a sub-node is required for each port the phy provides. Required properties (port (child) node): - #phy-cells : must be 0. See ./phy-bindings.txt for details. - interrupts : specify an interrupt for each entry in interrupt-names. - - interrupt-names : a list which shall be the following entries: + - interrupt-names : a list which should be one of the following cases: + Regular case: * "otg-id" : for the otg id interrupt. * "otg-bvalid" : for the otg vbus interrupt. * "linestate" : for the host/otg linestate interrupt. + Some SoCs use one interrupt with the above muxed together, so for these + * "otg-mux" : otg-port interrupt, which mux otg-id/otg-bvalid/linestate + to one. Optional properties: - phy-supply : phandle to a regulator that provides power to VBUS. @@ -58,14 +67,12 @@ grf: syscon@ff770000 { , ; interrupt-names = "otg-id", "otg-bvalid", "linestate"; - status = "okay"; }; u2phy_host: host-port { #phy-cells = <0>; interrupts = ; interrupt-names = "linestate"; - status = "okay"; }; }; }; diff --git a/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt b/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt index 86f2dbe07ed42f5013f97e3c13453c9d3074fabc..a1697c27aecde4f3e0f7633c700f4e8c20eab4b4 100644 --- a/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt @@ -25,7 +25,6 @@ Example: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; phy@100f8830 { @@ -35,5 +34,4 @@ Example: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt index e11c563a65ecac285bcc058e80774190c8b3e71b..b6a9f2b92bab11c0a303c92535ddc193996de537 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt @@ -6,6 +6,7 @@ controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB. Required properties: - compatible: compatible list, contains: + "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074 "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996, "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996. @@ -38,6 +39,8 @@ Required properties: "phy", "common", "cfg". For "qcom,msm8996-qmp-usb3-phy" must contain "phy", "common". + For "qcom,ipq8074-qmp-pcie-phy" must contain: + "phy", "common". - vdda-phy-supply: Phandle to a regulator supply to PHY core block. - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block. @@ -60,6 +63,13 @@ Required properties for child node: one for each entry in clock-names. - clock-names: Must contain following for pcie and usb qmp phys: "pipe" for pipe clock specific to each lane. + - clock-output-names: Name of the PHY clock that will be the parent for + the above pipe clock. + + For "qcom,ipq8074-qmp-pcie-phy": + - "pcie20_phy0_pipe_clk" Pipe Clock parent + (or) + "pcie20_phy1_pipe_clk" - resets: a list of phandles and reset controller specifier pairs, one for each entry in reset-names. @@ -96,6 +106,7 @@ Example: clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; clock-names = "pipe0"; + clock-output-names = "pcie_0_pipe_clk_src"; resets = <&gcc GCC_PCIE_0_PHY_BCR>; reset-names = "lane0"; }; diff --git a/Documentation/devicetree/bindings/phy/ralink-usb-phy.txt b/Documentation/devicetree/bindings/phy/ralink-usb-phy.txt new file mode 100644 index 0000000000000000000000000000000000000000..9d2868a437abfad18af5dfb68a185ebff0132397 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/ralink-usb-phy.txt @@ -0,0 +1,23 @@ +Mediatek/Ralink USB PHY + +Required properties: + - compatible: "ralink,rt3352-usbphy" + "mediatek,mt7620-usbphy" + "mediatek,mt7628-usbphy" + - reg: required for "mediatek,mt7628-usbphy", unused otherwise + - #phy-cells: should be 0 + - ralink,sysctl: a phandle to a ralink syscon register region + - resets: the two reset controllers for host and device + - reset-names: the names of the 2 reset controllers + +Example: + +usbphy: phy { + compatible = "mediatek,mt7628-usbphy"; + reg = <0x10120000 0x1000>; + #phy-cells = <0>; + + ralink,sysctl = <&sysc>; + resets = <&rstctrl 22 &rstctrl 25>; + reset-names = "host", "device"; +}; diff --git a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt index 0f6222a672ced616ba4e21b5310f7087dcb31655..b496042f1f4436f4543b7b835d41afd1d1e4adb7 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt @@ -3,7 +3,6 @@ Rockchip PCIE PHY Required properties: - compatible: rockchip,rk3399-pcie-phy - - #phy-cells: must be 0 - clocks: Must contain an entry in clock-names. See ../clocks/clock-bindings.txt for details. - clock-names: Must be "refclk" @@ -11,6 +10,12 @@ Required properties: See ../reset/reset.txt for details. - reset-names: Must be "phy" +Required properties for legacy PHY mode (deprecated): + - #phy-cells: must be 0 + +Required properties for per-lane PHY mode (preferred): + - #phy-cells: must be 1 + Example: grf: syscon@ff770000 { diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index ab80bfe31cb339fc9f617463212a99db7519ea0a..1c40ccd40ce4402735d72ad80dc4d3c28f44eb1f 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -82,7 +82,6 @@ usbphy: phy@125b0000 { reg = <0x125b0000 0x100>; clocks = <&clock 305>, <&clock 2>; clock-names = "phy", "ref"; - status = "okay"; #phy-cells = <1>; samsung,sysreg-phandle = <&sys_reg>; samsung,pmureg-phandle = <&pmu_reg>; diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index 005bc22938fffb76d73fcee9b8cb29731a1e4584..cbc7847dbf6c59ffeb845f95682d9b9a427d81b8 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -9,6 +9,7 @@ Required properties: * allwinner,sun7i-a20-usb-phy * allwinner,sun8i-a23-usb-phy * allwinner,sun8i-a33-usb-phy + * allwinner,sun8i-a83t-usb-phy * allwinner,sun8i-h3-usb-phy * allwinner,sun8i-v3s-usb-phy * allwinner,sun50i-a64-usb-phy @@ -17,18 +18,22 @@ Required properties: * "phy_ctrl" * "pmu0" for H3, V3s and A64 * "pmu1" - * "pmu2" for sun4i, sun6i or sun7i + * "pmu2" for sun4i, sun6i, sun7i, sun8i-a83t or sun8i-h3 + * "pmu3" for sun8i-h3 - #phy-cells : from the generic phy bindings, must be 1 - clocks : phandle + clock specifier for the phy clocks - clock-names : * "usb_phy" for sun4i, sun5i or sun7i * "usb0_phy", "usb1_phy" and "usb2_phy" for sun6i * "usb0_phy", "usb1_phy" for sun8i + * "usb0_phy", "usb1_phy", "usb2_phy" and "usb2_hsic_12M" for sun8i-a83t + * "usb0_phy", "usb1_phy", "usb2_phy" and "usb3_phy" for sun8i-h3 - resets : a list of phandle + reset specifier pairs - reset-names : * "usb0_reset" * "usb1_reset" - * "usb2_reset" for sun4i, sun6i or sun7i + * "usb2_reset" for sun4i, sun6i, sun7i, sun8i-a83t or sun8i-h3 + * "usb3_reset" for sun8i-h3 Optional properties: - usb0_id_det-gpios : gpio phandle for reading the otg id pin value @@ -37,6 +42,7 @@ Optional properties: - usb0_vbus-supply : regulator phandle for controller usb0 vbus - usb1_vbus-supply : regulator phandle for controller usb1 vbus - usb2_vbus-supply : regulator phandle for controller usb2 vbus +- usb3_vbus-supply : regulator phandle for controller usb3 vbus Example: usbphy: phy@0x01c13400 { diff --git a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt index 1cca85c709d1bc281bd25abd790a7f4f5a935260..f9853156e311fb1180a373cb8ed93a293ff59c9b 100644 --- a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt @@ -33,6 +33,5 @@ Example: clock-names = "hsic_480M", "hsic_12M", "phy"; resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>; reset-names = "hsic", "phy"; - status = "disabled"; #phy-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt index 590e60378be30dd8ff6838b6a7923dfc2a761b09..3e23fece99dabda20f18e649b708702524e02454 100644 --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt @@ -148,5 +148,4 @@ dbgu: serial@fffff200 { interrupts = <1 4 7>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dbgu>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt new file mode 100644 index 0000000000000000000000000000000000000000..61466c58faae3b0ed384fe08cd7e1604fdd9f2e1 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt @@ -0,0 +1,59 @@ +Cortina Systems Gemini pin controller + +This pin controller is found in the Cortina Systems Gemini SoC family, +see further arm/gemini.txt. It is a purely group-based multiplexing pin +controller. + +The pin controller node must be a subnode of the system controller node. + +Required properties: +- compatible: "cortina,gemini-pinctrl" + +Subnodes of the pin controller contain pin control multiplexing set-up. +Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes. + +Example: + + +syscon { + compatible = "cortina,gemini-syscon"; + ... + pinctrl { + compatible = "cortina,gemini-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&dram_default_pins>, <&system_default_pins>, + <&vcontrol_default_pins>; + + dram_default_pins: pinctrl-dram { + mux { + function = "dram"; + groups = "dramgrp"; + }; + }; + rtc_default_pins: pinctrl-rtc { + mux { + function = "rtc"; + groups = "rtcgrp"; + }; + }; + power_default_pins: pinctrl-power { + mux { + function = "power"; + groups = "powergrp"; + }; + }; + system_default_pins: pinctrl-system { + mux { + function = "system"; + groups = "systemgrp"; + }; + }; + (...) + uart_default_pins: pinctrl-uart { + mux { + function = "uart"; + groups = "uartrxtxgrp"; + }; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt index 9fde25f1401a55b64b8b3fa80f27f9310e7cb706..42d74f8a1bccfea6c2f701af9c9f63dad04e975f 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt @@ -61,7 +61,6 @@ Examples: usdhc@0219c000 { /* uSDHC4 */ non-removable; vmmc-supply = <®_3p3v>; - status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc4_1>; }; diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt index 8c5d27c5b56217e469acf4322309739d7ff50dea..6666277c3acb72988131d13e3d176b78956a727a 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt @@ -61,7 +61,6 @@ iomuxc-lpsr controller and SDA pad from iomuxc controller as: i2c1: i2c@30a20000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1_1 &pinctrl_i2c1_2>; - status = "okay"; }; iomuxc-lpsr@302c0000 { diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx7ulp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx7ulp-pinctrl.txt new file mode 100644 index 0000000000000000000000000000000000000000..44ad670ae11e14eec28685bddc1506789e4f5e61 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx7ulp-pinctrl.txt @@ -0,0 +1,61 @@ +* Freescale i.MX7ULP IOMUX Controller + +i.MX 7ULP has three IOMUXC instances: IOMUXC0 for M4 ports, IOMUXC1 for A7 +ports and IOMUXC DDR for DDR interface. + +Note: +This binding doc is only for the IOMUXC1 support in A7 Domain and it only +supports generic pin config. + +Please also refer pinctrl-bindings.txt in this directory for generic pinctrl +binding. + +=== Pin Controller Node === + +Required properties: +- compatible: "fsl,imx7ulp-iomuxc1" +- reg: Should contain the base physical address and size of the iomuxc + registers. + +=== Pin Configuration Node === +- pinmux: One integers array, represents a group of pins mux setting. + The format is pinmux = , PIN_FUNC_ID is a pin working on + a specific function. + + NOTE: i.MX7ULP PIN_FUNC_ID consists of 4 integers as it shares one mux + and config register as follows: + + + Refer to imx7ulp-pinfunc.h in in device tree source folder for all + available imx7ulp PIN_FUNC_ID. + +Optional Properties: +- drive-strength Integer. Controls Drive Strength + 0: Standard + 1: Hi Driver +- drive-push-pull Bool. Enable Pin Push-pull +- drive-open-drain Bool. Enable Pin Open-drian +- slew-rate: Integer. Controls Slew Rate + 0: Standard + 1: Slow +- bias-disable: Bool. Pull disabled +- bias-pull-down: Bool. Pull down on pin +- bias-pull-up: Bool. Pull up on pin + +Examples: +#include "imx7ulp-pinfunc.h" + +/* Pin Controller Node */ +iomuxc1: iomuxc@40ac0000 { + compatible = "fsl,imx7ulp-iomuxc1"; + reg = <0x40ac0000 0x1000>; + + /* Pin Configuration Node */ + pinctrl_lpuart4: lpuart4grp { + pinmux = < + IMX7ULP_PAD_PTC3__LPUART4_RX + IMX7ULP_PAD_PTC2__LPUART4_TX + >; + bias-pull-up; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt index f2abdaee902260f6cb4bca18e6546b56150cc3f2..e0e886b7352783da41b93270b425aef5232ba59e 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt @@ -56,5 +56,4 @@ Example: pinctrl-0 = <&state_dpaux_i2c>; pinctrl-1 = <&state_dpaux_off>; pinctrl-names = "default", "idle"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt index 09e81a95bbfd34a48b381830b34b8cfa154dba3c..b1159434f593285b3299fb0ee0b38486078e6b4c 100644 --- a/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt @@ -50,7 +50,6 @@ uart2: serial@900000 { reg-io-width = <1>; current-speed = <115200>; no-loopback-test; - status = "disabled"; resets = <&reset 22>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt index ca01710ee29afde12272a904907f49273403388d..3b7266c7c43888f3977be3ee0aee2c636dde5a64 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt @@ -69,8 +69,9 @@ PWM1 PWM2 PWM3 PWM4 PWM5 PWM6 PWM7 RGMII1 RGMII2 RMII1 RMII2 ROM16 ROM8 ROMCS1 ROMCS2 ROMCS3 ROMCS4 RXD1 RXD2 RXD3 RXD4 SALT1 SALT2 SALT3 SALT4 SD1 SD2 SGPMCK SGPMI SGPMLD SGPMO SGPSCK SGPSI0 SGPSI1 SGPSLD SIOONCTRL SIOPBI SIOPBO SIOPWREQ SIOPWRGD SIOS3 SIOS5 SIOSCI SPI1 SPI1DEBUG SPI1PASSTHRU SPICS1 TIMER3 TIMER4 -TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2 TXD3 TXD4 UART6 USBCKI VGABIOS_ROM VGAHS -VGAVS VPI18 VPI24 VPI30 VPO12 VPO24 WDTRST1 WDTRST2 +TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2 TXD3 TXD4 UART6 USB11D1 USB11H2 USB2D1 +USB2H1 USBCKI VGABIOS_ROM VGAHS VGAVS VPI18 VPI24 VPI30 VPO12 VPO24 WDTRST1 +WDTRST2 aspeed,ast2500-pinctrl, aspeed,g5-pinctrl: @@ -86,7 +87,8 @@ SALT11 SALT12 SALT13 SALT14 SALT2 SALT3 SALT4 SALT5 SALT6 SALT7 SALT8 SALT9 SCL1 SCL2 SD1 SD2 SDA1 SDA2 SGPS1 SGPS2 SIOONCTRL SIOPBI SIOPBO SIOPWREQ SIOPWRGD SIOS3 SIOS5 SIOSCI SPI1 SPI1CS1 SPI1DEBUG SPI1PASSTHRU SPI2CK SPI2CS0 SPI2CS1 SPI2MISO SPI2MOSI TIMER3 TIMER4 TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2 -TXD3 TXD4 UART6 USBCKI VGABIOSROM VGAHS VGAVS VPI24 VPO WDTRST1 WDTRST2 +TXD3 TXD4 UART6 USB11BHID USB2AD USB2AH USB2BD USB2BH USBCKI VGABIOSROM VGAHS +VGAVS VPI24 VPO WDTRST1 WDTRST2 Examples ======== diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index 62d0f33fa65e4d9725aa84ac6b6b7e5972f90288..4483cc31e5310a234a075d34b879f957596846fc 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -268,6 +268,8 @@ output-enable - enable output on a pin without actively driving it (such as enabling an output buffer) output-low - set the pin to output mode with low level output-high - set the pin to output mode with high level +sleep-hardware-state - indicate this is sleep related state which will be programmed + into the registers for the sleep state. slew-rate - set the slew rate For example: diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt index 17631d0a9af7bd01fe316b06f9caae6815f7d70f..37d744750579aa0cb027e14b2733a3533086c3e4 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt @@ -5,6 +5,7 @@ The Mediatek's Pin controller is used to control SoC pins. Required properties: - compatible: value should be one of the following. "mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl. + "mediatek,mt2712-pinctrl", compatible with mt2712 pinctrl. "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl. "mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl. "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl. diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt new file mode 100644 index 0000000000000000000000000000000000000000..eee3dc26093437e22b2271dda50c627eafcfe39f --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt @@ -0,0 +1,63 @@ +Pincontrol driver for RK805 Power management IC. + +RK805 has 2 pins which can be configured as GPIO output only. + +Please refer file +for details of the common pinctrl bindings used by client devices, +including the meaning of the phrase "pin configuration node". + +Optional Pinmux properties: +-------------------------- +Following properties are required if default setting of pins are required +at boot. +- pinctrl-names: A pinctrl state named per . +- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per + . + +The pin configurations are defined as child of the pinctrl states node. Each +sub-node have following properties: + +Required properties: +------------------ +- #gpio-cells: Should be two. The first cell is the pin number and the + second is the GPIO flags. + +- gpio-controller: Marks the device node as a GPIO controller. + +- pins: List of pins. Valid values of pins properties are: gpio0, gpio1. + +First 2 properties must be added in the RK805 PMIC node, documented in +Documentation/devicetree/bindings/mfd/rk808.txt + +Optional properties: +------------------- +Following are optional properties defined as pinmux DT binding document +. Absence of properties will leave the configuration +on default. + function, + output-low, + output-high. + +Valid values for function properties are: gpio. + +Theres is also not customised properties for any GPIO. + +Example: +-------- +rk805: rk805@18 { + compatible = "rockchip,rk805"; + ... + gpio-controller; + #gpio-cells = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>, <&rk805_default>; + + rk805_default: pinmux { + gpio01 { + pins = "gpio0", "gpio1"; + function = "gpio"; + output-high; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt index e219849b21cac82069881fc6101cb8554bbfa685..39170f372599b2a95f5ce23db7a33967387f8ea7 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt @@ -81,5 +81,4 @@ pmm: pin-controller@1462000 { &vga { pinctrl-names = "default"; pinctrl-0 = <&vga_pins>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt index a7bde64798c7e33a7a84e73bb92f82d5d7fd53eb..a752a47164860a1c7ff1986cba6749594dcad696 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt @@ -46,7 +46,8 @@ Valid values for pins are: gpio0-gpio89 Valid values for function are: - cam_mclk, codec_mic_i2s, codec_spkr_i2s, gpio, gsbi1, gsbi2, gsbi3, gsbi4, + cam_mclk, codec_mic_i2s, codec_spkr_i2s, gp_clk_0a, gp_clk_0b, gp_clk_1a, + gp_clk_1b, gp_clk_2a, gp_clk_2b, gpio, gsbi1, gsbi2, gsbi3, gsbi4, gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1, gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm, diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt index cfb8500dd56beb852ba35e0e09d93091f745eed0..93374f478b9e071b126d56911a4023535152cd66 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt @@ -50,7 +50,11 @@ Valid values for qcom,pins are: Supports mux, bias and drive-strength Valid values for qcom,function are: -gpio, blsp_uart1, blsp_i2c0, blsp_i2c1, blsp_uart0, blsp_spi1, blsp_spi0 +aud_pin, audio_pwm, blsp_i2c0, blsp_i2c1, blsp_spi0, blsp_spi1, blsp_uart0, +blsp_uart1, chip_rst, gpio, i2s_rx, i2s_spdif_in, i2s_spdif_out, i2s_td, i2s_tx, +jtag, led0, led1, led2, led3, led4, led5, led6, led7, led8, led9, led10, led11, +mdc, mdio, pcie, pmu, prng_rosc, qpic, rgmii, rmii, sdio, smart0, smart1, +smart2, smart3, tm, wifi0, wifi1 Example: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 8d893a874634281127ddb2f69962577ee33a6798..5b12c57e7f022e58ba262191246f23b4852cc7df 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -16,6 +16,7 @@ PMIC's from Qualcomm. "qcom,pm8941-gpio" "qcom,pm8994-gpio" "qcom,pma8084-gpio" + "qcom,pmi8994-gpio" And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio" if the device is on an spmi bus or an ssbi bus respectively @@ -85,6 +86,7 @@ to specify in a pin configuration subnode: gpio1-gpio36 for pm8941 gpio1-gpio22 for pm8994 gpio1-gpio22 for pma8084 + gpio1-gpio10 for pmi8994 - function: Usage: required @@ -98,7 +100,10 @@ to specify in a pin configuration subnode: "dtest1", "dtest2", "dtest3", - "dtest4" + "dtest4", + And following values are supported by LV/MV GPIO subtypes: + "func3", + "func4" - bias-disable: Usage: optional @@ -183,6 +188,25 @@ to specify in a pin configuration subnode: Value type: Definition: The specified pins are configured in open-source mode. +- qcom,analog-pass: + Usage: optional + Value type: + Definition: The specified pins are configured in analog-pass-through mode. + +- qcom,atest: + Usage: optional + Value type: + Definition: Selects ATEST rail to route to GPIO when it's configured + in analog-pass-through mode. + Valid values are 1-4 corresponding to ATEST1 to ATEST4. + +- qcom,dtest-buffer: + Usage: optional + Value type: + Definition: Selects DTEST rail to route to GPIO when it's configured + as digital input. + Valid values are 1-4 corresponding to DTEST1 to DTEST4. + Example: pm8921_gpio: gpio@150 { diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index 645082f032592997b8c46a63ac99cc43ecf7e921..9b4f8041c36a62e7cdb4ddd77935e49c20dd8859 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -24,6 +24,7 @@ Required Properties: - "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller. - "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller. - "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller. + - "renesas,pfc-r8a77995": for R8A77995 (R-Car D3) compatible pin-controller. - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller. - reg: Base address and length of each memory resource used by the pin @@ -111,7 +112,7 @@ Examples Example 1: SH73A0 (SH-Mobile AG5) pin controller node - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-sh73a0"; reg = <0xe6050000 0x8000>, <0xe605801c 0x1c>; @@ -172,5 +173,4 @@ Example 4: KZM-A9-GT (SH-Mobile AG5) default pin state for the MMCIF device bus-width = <8>; vmmc-supply = <®_1p8v>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index ee01ab58224d5e3907b3a115dcf6d0d8ed7c595f..4864e3a74de311ff02e6f3c54a04ae2fbba5ae2d 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt @@ -24,6 +24,7 @@ Required properties for iomux controller: "rockchip,rk2928-pinctrl": for Rockchip RK2928 "rockchip,rk3066a-pinctrl": for Rockchip RK3066a "rockchip,rk3066b-pinctrl": for Rockchip RK3066b + "rockchip,rk3128-pinctrl": for Rockchip RK3128 "rockchip,rk3188-pinctrl": for Rockchip RK3188 "rockchip,rk3228-pinctrl": for Rockchip RK3228 "rockchip,rk3288-pinctrl": for Rockchip RK3288 @@ -120,7 +121,6 @@ uart2: serial@20064000 { reg-shift = <2>; reg-io-width = <1>; clocks = <&mux_uart2>; - status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&uart2_xfer>; diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt new file mode 100644 index 0000000000000000000000000000000000000000..b1cea7a3a0715df1c954779331bbe94926c31946 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt @@ -0,0 +1,83 @@ +* Spreadtrum Pin Controller + +The Spreadtrum pin controller are organized in 3 blocks (types). + +The first block comprises some global control registers, and each +register contains several bit fields with one bit or several bits +to configure for some global common configuration, such as domain +pad driving level, system control select and so on ("domain pad +driving level": One pin can output 3.0v or 1.8v, depending on the +related domain pad driving selection, if the related domain pad +slect 3.0v, then the pin can output 3.0v. "system control" is used +to choose one function (like: UART0) for which system, since we +have several systems (AP/CP/CM4) on one SoC.). + +There are too much various configuration that we can not list all +of them, so we can not make every Spreadtrum-special configuration +as one generic configuration, and maybe it will add more strange +global configuration in future. Then we add one "sprd,control" to +set these various global control configuration, and we need use +magic number for this property. + +Moreover we recognise every fields comprising one bit or several +bits in one global control register as one pin, thus we should +record every pin's bit offset, bit width and register offset to +configure this field (pin). + +The second block comprises some common registers which have unified +register definition, and each register described one pin is used +to configure the pin sleep mode, function select and sleep related +configuration. + +Now we have 4 systems for sleep mode on SC9860 SoC: AP system, +PUBCP system, TGLDSP system and AGDSP system. And the pin sleep +related configuration are: +- input-enable +- input-disable +- output-high +- output-low +- bias-pull-up +- bias-pull-down + +In some situation we need set the pin sleep mode and pin sleep related +configuration, to set the pin sleep related configuration automatically +by hardware when the system specified by sleep mode goes into deep +sleep mode. For example, if we set the pin sleep mode as PUBCP_SLEEP +and set the pin sleep related configuration as "input-enable", which +means when PUBCP system goes into deep sleep mode, this pin will be set +input enable automatically. + +Moreover we can not use the "sleep" state, since some systems (like: +PUBCP system) do not run linux kernel OS (only AP system run linux +kernel on SC9860 platform), then we can not select "sleep" state +when the PUBCP system goes into deep sleep mode. Thus we introduce +"sprd,sleep-mode" property to set pin sleep mode. + +The last block comprises some misc registers which also have unified +register definition, and each register described one pin is used to +configure drive strength, pull up/down and so on. Especially for pull +up, we have two kind pull up resistor: 20K and 4.7K. + +Required properties for Spreadtrum pin controller: +- compatible: "sprd,-pinctrl" + Please refer to each sprd,-pinctrl.txt binding doc for supported SoCs. +- reg: The register address of pin controller device. +- pins : An array of pin names. + +Optional properties: +- function: Specified the function name. +- drive-strength: Drive strength in mA. +- input-schmitt-disable: Enable schmitt-trigger mode. +- input-schmitt-enable: Disable schmitt-trigger mode. +- bias-disable: Disable pin bias. +- bias-pull-down: Pull down on pin. +- bias-pull-up: Pull up on pin. +- input-enable: Enable pin input. +- input-disable: Enable pin output. +- output-high: Set the pin as an output level high. +- output-low: Set the pin as an output level low. +- sleep-hardware-state: Indicate these configs in this state are sleep related. +- sprd,control: Control values referring to databook for global control pins. +- sprd,sleep-mode: Sleep mode selection. + +Please refer to each sprd,-pinctrl.txt binding doc for supported values. diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt new file mode 100644 index 0000000000000000000000000000000000000000..5a628333d52f2466caaa4ebe0d7823040396e526 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt @@ -0,0 +1,70 @@ +* Spreadtrum SC9860 Pin Controller + +Please refer to sprd,pinctrl.txt in this directory for common binding part +and usage. + +Required properties: +- compatible: Must be "sprd,sc9860-pinctrl". +- reg: The register address of pin controller device. +- pins : An array of strings, each string containing the name of a pin. + +Optional properties: +- function: A string containing the name of the function, values must be + one of: "func1", "func2", "func3" and "func4". +- drive-strength: Drive strength in mA. Supported values: 2, 4, 6, 8, 10, + 12, 14, 16, 20, 21, 24, 25, 27, 29, 31 and 33. +- input-schmitt-disable: Enable schmitt-trigger mode. +- input-schmitt-enable: Disable schmitt-trigger mode. +- bias-disable: Disable pin bias. +- bias-pull-down: Pull down on pin. +- bias-pull-up: Pull up on pin. Supported values: 20000 for pull-up resistor + is 20K and 4700 for pull-up resistor is 4.7K. +- input-enable: Enable pin input. +- input-disable: Enable pin output. +- output-high: Set the pin as an output level high. +- output-low: Set the pin as an output level low. +- sleep-hardware-state: Indicate these configs in this state are sleep related. +- sprd,control: Control values referring to databook for global control pins. +- sprd,sleep-mode: Choose the pin sleep mode, and supported values are: + AP_SLEEP, PUBCP_SLEEP, TGLDSP_SLEEP and AGDSP_SLEEP. + +Pin sleep mode definition: +enum pin_sleep_mode { + AP_SLEEP = BIT(0), + PUBCP_SLEEP = BIT(1), + TGLDSP_SLEEP = BIT(2), + AGDSP_SLEEP = BIT(3), +}; + +Example: +pin_controller: pinctrl@402a0000 { + compatible = "sprd,sc9860-pinctrl"; + reg = <0x402a0000 0x10000>; + + grp1: sd0 { + pins = "SC9860_VIO_SD2_IRTE", "SC9860_VIO_SD0_IRTE"; + sprd,control = <0x1>; + }; + + grp2: rfctl_33 { + pins = "SC9860_RFCTL33"; + function = "func2"; + sprd,sleep-mode = ; + grp2_sleep_mode: rfctl_33_sleep { + pins = "SC9860_RFCTL33"; + sleep-hardware-state; + output-low; + } + }; + + grp3: rfctl_misc_20 { + pins = "SC9860_RFCTL20_MISC"; + drive-strength = <10>; + bias-pull-up = <4700>; + grp3_sleep_mode: rfctl_misc_sleep { + pins = "SC9860_RFCTL20_MISC"; + sleep-hardware-state; + bias-pull-up; + } + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt index d907a74f8dc0a5ee98d87118232fb20580c0fba3..33e3d3c475526e404a8b03c7769aa66d61b88e3e 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt @@ -180,5 +180,4 @@ pin-controller { &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/power/power-controller.txt b/Documentation/devicetree/bindings/power/power-controller.txt index 4f7a3bc9c4073cc501218a3b1fc474826813ceb2..e45affea80781292316c75ed387ba38402501c5b 100644 --- a/Documentation/devicetree/bindings/power/power-controller.txt +++ b/Documentation/devicetree/bindings/power/power-controller.txt @@ -13,6 +13,5 @@ Example: act8846: act8846@5 { compatible = "active-semi,act8846"; - status = "okay"; system-power-controller; } diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.txt b/Documentation/devicetree/bindings/power/renesas,apmu.txt index 84404c9edff73d97df9384fb0ce801343d780b0b..af21502e939c4b1f6866e80f7325342833b133c0 100644 --- a/Documentation/devicetree/bindings/power/renesas,apmu.txt +++ b/Documentation/devicetree/bindings/power/renesas,apmu.txt @@ -1,12 +1,13 @@ DT bindings for the Renesas Advanced Power Management Unit -Renesas R-Car line of SoCs utilize one or more APMU hardware units +Renesas R-Car and RZ/G1 SoCs utilize one or more APMU hardware units for CPU core power domain control including SMP boot and CPU Hotplug. Required properties: - compatible: Should be "renesas,-apmu", "renesas,apmu" as fallback. Examples with soctypes are: + - "renesas,r8a7743-apmu" (RZ/G1M) - "renesas,r8a7790-apmu" (R-Car H2) - "renesas,r8a7791-apmu" (R-Car M2-W) - "renesas,r8a7792-apmu" (R-Car V2H) diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index d91715bc8d52c22e7f159b6bca96f35fa5a68111..98cc8c09d02d5d857992250fd61a0199359e5933 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -17,6 +17,7 @@ Required properties: - "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7795-sysc" (R-Car H3) - "renesas,r8a7796-sysc" (R-Car M3-W) + - "renesas,r8a77995-sysc" (R-Car D3) - reg: Address start and address range for the device. - #power-domain-cells: Must be 1. diff --git a/Documentation/devicetree/bindings/power/reset/st-reset.txt b/Documentation/devicetree/bindings/power/reset/st-reset.txt index 83734dc3a389771ea061d9c71f4a00c7589e5fcf..b63948737d806913bd24bfe57d7650dae63f2caa 100644 --- a/Documentation/devicetree/bindings/power/reset/st-reset.txt +++ b/Documentation/devicetree/bindings/power/reset/st-reset.txt @@ -8,5 +8,4 @@ Example node: restart { compatible = "st,stih407-restart"; st,syscfg = <&syscfg_sbc_reg>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt index 43c21fb04564c1c19d10043d2425dfe8654b69ba..4a4766e9c254e1dae631de52cdf19b7b04454142 100644 --- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt +++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt @@ -39,6 +39,8 @@ Required properties: - "rockchip,rk3368-pmu-io-voltage-domain" for rk3368 pmu-domains - "rockchip,rk3399-io-voltage-domain" for rk3399 - "rockchip,rk3399-pmu-io-voltage-domain" for rk3399 pmu-domains + - "rockchip,rv1108-io-voltage-domain" for rv1108 + - "rockchip,rv1108-pmu-io-voltage-domain" for rv1108 pmu-domains Deprecated properties: - rockchip,grf: phandle to the syscon managing the "general register files" diff --git a/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt b/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt index de78d761ce44e1931aa060e34e085126143321e4..b86ecada4f84be501f8523d59fe9185df1499994 100644 --- a/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt @@ -29,7 +29,6 @@ Example: pmic@5b { compatible = "active-semi,act8945a"; reg = <0x5b>; - status = "okay"; charger { compatible = "active-semi,act8945a-charger"; @@ -43,6 +42,5 @@ Example: active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,precondition-timeout = <40>; active-semi,total-timeout = <3>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/power/supply/bq24190.txt b/Documentation/devicetree/bindings/power/supply/bq24190.txt new file mode 100644 index 0000000000000000000000000000000000000000..9e517d307070ab9a461d11996d575e72b991650a --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/bq24190.txt @@ -0,0 +1,51 @@ +TI BQ24190 Li-Ion Battery Charger + +Required properties: +- compatible: contains one of the following: + * "ti,bq24190" + * "ti,bq24192i" +- reg: integer, I2C address of the charger. +- interrupts[-extended]: configuration for charger INT pin. + +Optional properties: +- monitored-battery: phandle of battery characteristics devicetree node + The charger uses the following battery properties: + + precharge-current-microamp: maximum charge current during precharge + phase (typically 20% of battery capacity). + + charge-term-current-microamp: a charge cycle terminates when the + battery voltage is above recharge threshold, and the current is below + this setting (typically 10% of battery capacity). + See also Documentation/devicetree/bindings/power/supply/battery.txt +- ti,system-minimum-microvolt: when power is connected and the battery is below + minimum system voltage, the system will be regulated above this setting. + +Notes: +- Some circuit boards wire the chip's "OTG" pin high (enabling 500mA default + charge current on USB SDP ports, among other features). To simulate this on + boards that wire the pin to a GPIO, set a gpio-hog. + +Example: + + bat: battery { + compatible = "simple-battery"; + precharge-current-microamp = <256000>; + charge-term-current-microamp = <128000>; + // etc. + }; + + bq24190: charger@6a { + compatible = "ti,bq24190"; + reg = <0x6a>; + interrupts-extended = <&gpiochip 10 IRQ_TYPE_EDGE_FALLING>; + monitored-battery = <&bat>; + ti,system-minimum-microvolt = <3200000>; + }; + + &twl_gpio { + otg { + gpio-hog; + gpios = <6 0>; + output-high; + line-name = "otg-gpio"; + }; + }; diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt b/Documentation/devicetree/bindings/power/supply/ltc2941.txt index a9d7aa60558b739ca312f86826b72cb247b111c0..3b9ba147b04171c748cfd4aaac12c6d8692a85d0 100644 --- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt +++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt @@ -1,13 +1,14 @@ -binding for LTC2941 and LTC2943 battery gauges +binding for LTC2941, LTC2942, LTC2943 and LTC2944 battery gauges -Both the LTC2941 and LTC2943 measure battery capacity. -The LTC2943 is compatible with the LTC2941, it adds voltage and -temperature monitoring, and uses a slightly different conversion -formula for the charge counter. +All chips measure battery capacity. +The LTC2942 is pin compatible with the LTC2941, it adds voltage and +temperature monitoring, and is runtime detected. LTC2943 and LTC2944 +is software compatible, uses a slightly different conversion formula +for the charge counter and adds voltage, current and temperature monitoring. Required properties: -- compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also - indicates the type of I2C chip attached. +- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942", "lltc,ltc2943" + or "lltc,ltc2944" which also indicates the type of I2C chip attached. - reg: The 7-bit I2C address. - lltc,resistor-sense: The sense resistor value in milli-ohms. Can be a 32-bit negative value when the battery has been connected to the wrong end of the diff --git a/Documentation/devicetree/bindings/power/supply/max8903-charger.txt b/Documentation/devicetree/bindings/power/supply/max8903-charger.txt index f0f4e12b076ef8214688a292e6bbe34987b02f54..bab947fef025e5250a299934877800c1881c8799 100644 --- a/Documentation/devicetree/bindings/power/supply/max8903-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/max8903-charger.txt @@ -21,5 +21,4 @@ Example: flt-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; chg-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; cen-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt b/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt index e03e85ae657261f158ee719d4c3cc69336c81765..d6e8dfd0a581fee2005a80f92c5e717b21068a5d 100644 --- a/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt +++ b/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt @@ -12,7 +12,6 @@ Example: clock-frequency = <50000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; - status = "okay"; max14656@35 { compatible = "maxim,max14656"; diff --git a/Documentation/devicetree/bindings/power/wakeup-source.txt b/Documentation/devicetree/bindings/power/wakeup-source.txt index 963c6dfd484df2d7e898427f8d62459410cb78da..3c81f78b5c27d50bb809cf6bbf13766a779024f5 100644 --- a/Documentation/devicetree/bindings/power/wakeup-source.txt +++ b/Documentation/devicetree/bindings/power/wakeup-source.txt @@ -20,13 +20,12 @@ List of legacy properties and respective binding document 1. "enable-sdio-wakeup" Documentation/devicetree/bindings/mmc/mmc.txt 2. "gpio-key,wakeup" Documentation/devicetree/bindings/input/gpio-keys{,-polled}.txt 3. "has-tpo" Documentation/devicetree/bindings/rtc/rtc-opal.txt -4. "isil,irq2-can-wakeup-machine" Documentation/devicetree/bindings/rtc/isil,isl12057.txt -5. "linux,wakeup" Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt +4. "linux,wakeup" Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt Documentation/devicetree/bindings/mfd/tc3589x.txt Documentation/devicetree/bindings/input/ads7846.txt -6. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt -7. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt -8. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt +5. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt +6. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt +7. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt Examples -------- diff --git a/Documentation/devicetree/bindings/powerpc/ibm,vas.txt b/Documentation/devicetree/bindings/powerpc/ibm,vas.txt new file mode 100644 index 0000000000000000000000000000000000000000..bf11d2faf7b8c8029bffe0f6a512a6544c00732f --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/ibm,vas.txt @@ -0,0 +1,22 @@ +* IBM Powerpc Virtual Accelerator Switchboard (VAS) + +VAS is a hardware mechanism that allows kernel subsystems and user processes +to directly submit compression and other requests to Nest accelerators (NX) +or other coprocessors functions. + +Required properties: +- compatible : should be "ibm,vas". +- ibm,vas-id : A unique identifier for each instance of VAS in the system +- reg : Should contain 4 pairs of 64-bit fields specifying the Hypervisor + window context start and length, OS/User window context start and length, + "Paste address" start and length, "Paste window id" start bit and number + of bits) + +Example: + + vas@6019100000000 { + compatible = "ibm,vas", "ibm,power9-vas"; + reg = <0x6019100000000 0x2000000 0x6019000000000 0x100000000 0x8000000000000 0x100000000 0x20 0x10>; + name = "vas"; + ibm,vas-id = <0x1>; + }; diff --git a/Documentation/devicetree/bindings/powerpc/opal/sensor-groups.txt b/Documentation/devicetree/bindings/powerpc/opal/sensor-groups.txt new file mode 100644 index 0000000000000000000000000000000000000000..6ad881cbffdac9deca377804d2c9505245768c5d --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/opal/sensor-groups.txt @@ -0,0 +1,27 @@ +IBM OPAL Sensor Groups Binding +------------------------------- + +Node: /ibm,opal/sensor-groups + +Description: Contains sensor groups available in the Powernv P9 +servers. Each child node indicates a sensor group. + +- compatible : Should be "ibm,opal-sensor-group" + +Each child node contains below properties: + +- type : String to indicate the type of sensor-group + +- sensor-group-id: Abstract unique identifier provided by firmware of + type which is used for sensor-group + operations like clearing the min/max history of all + sensors belonging to the group. + +- ibm,chip-id : Chip ID + +- sensors : Phandle array of child nodes of /ibm,opal/sensor/ + belonging to this group + +- ops : Array of opal-call numbers indicating available operations on + sensor groups like clearing min/max, enabling/disabling sensor + group. diff --git a/Documentation/devicetree/bindings/pps/pps-gpio.txt b/Documentation/devicetree/bindings/pps/pps-gpio.txt index 40bf9c3564a552639cbf8c432b2c3c175d630601..0de23b79365729d376a97032d76231ad70aa9b38 100644 --- a/Documentation/devicetree/bindings/pps/pps-gpio.txt +++ b/Documentation/devicetree/bindings/pps/pps-gpio.txt @@ -13,8 +13,12 @@ Optional properties: Example: pps { - compatible = "pps-gpio"; - gpios = <&gpio2 6 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pps>; + gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; assert-falling-edge; + + compatible = "pps-gpio"; + status = "okay"; }; diff --git a/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt b/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt index 7c04e22a5d6af016fe8198d2d6d955011abc2173..6b1075ee8a3025f58c0609da564521afbec70ff7 100644 --- a/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt +++ b/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt @@ -16,5 +16,4 @@ Example: ptp: ptp-dte@180af650 { compatible = "brcm,iproc-ptp-dte", "brcm,ptp-dte"; reg = <0x180af650 0x10>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt index cf573e85b11d602877119319060b61fb926aa9bc..8cf87d1bfca53c7d896a3ca610c09e068f78f7eb 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt @@ -6,7 +6,7 @@ Required properties: - clocks: This clock defines the base clock frequency of the PWM hardware system, the period and the duty_cycle of the PWM signal is a multiple of the base period. -- #pwm-cells: Should be 2. See pwm.txt in this directory for a description of +- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of the cells format. Examples: @@ -15,7 +15,7 @@ pwm@2020c000 { compatible = "brcm,bcm2835-pwm"; reg = <0x2020c000 0x28>; clocks = <&clk_pwm>; - #pwm-cells = <2>; + #pwm-cells = <3>; }; clocks { diff --git a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt index 54c59b0560ad701f9542da665f845c3bb1add186..ef8bd3cb67abb6ee8e94e43541d5638fc894ad15 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt @@ -2,6 +2,8 @@ MediaTek PWM controller Required properties: - compatible: should be "mediatek,-pwm": + - "mediatek,mt2712-pwm": found on mt2712 SoC. + - "mediatek,mt7622-pwm": found on mt7622 SoC. - "mediatek,mt7623-pwm": found on mt7623 SoC. - reg: physical base address and length of the controller's registers. - #pwm-cells: must be 2. See pwm.txt in this directory for a description of @@ -10,7 +12,9 @@ Required properties: - clock-names: must contain the following: - "top": the top clock generator - "main": clock used by the PWM core - - "pwm1-5": the five per PWM clocks + - "pwm1-8": the eight per PWM clocks for mt2712 + - "pwm1-6": the six per PWM clocks for mt7622 + - "pwm1-5": the five per PWM clocks for mt7623 - pinctrl-names: Must contain a "default" entry. - pinctrl-0: One property must exist for each entry in pinctrl-names. See pinctrl/pinctrl-bindings.txt for details of the property values. diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt index 5b07bebbf6f7d9855733a4df0bacd6c057c1e87b..1ee81321c35e792ded427994001aef24be69f931 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-meson.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt @@ -19,7 +19,6 @@ Example: compatible = "amlogic,meson-gxbb-pwm"; reg = <0x0 0x08550 0x0 0x10>; #pwm-cells = <3>; - status = "disabled"; clocks = <&xtal>, <&xtal>; clock-names = "clkin0", "clkin1"; } diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt index b8be3d09ee26b7522fa373eefd1903aef8ce3d41..2c5e52a5bede2da427a91b5dbf8996462f393551 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt @@ -3,10 +3,17 @@ Rockchip PWM controller Required properties: - compatible: should be "rockchip,-pwm" "rockchip,rk2928-pwm": found on RK29XX,RK3066 and RK3188 SoCs - "rockchip,rk3288-pwm": found on RK3288 SoC + "rockchip,rk3288-pwm": found on RK3288 SOC + "rockchip,rv1108-pwm", "rockchip,rk3288-pwm": found on RV1108 SoC "rockchip,vop-pwm": found integrated in VOP on RK3288 SoC - reg: physical base address and length of the controller's registers - - clocks: phandle and clock specifier of the PWM reference clock + - clocks: See ../clock/clock-bindings.txt + - For older hardware (rk2928, rk3066, rk3188, rk3228, rk3288, rk3399): + - There is one clock that's used both to derive the functional clock + for the device and as the bus clock. + - For newer hardware (rk3328 and future socs): specified by name + - "pwm": This is used to derive the functional clock. + - "pclk": This is the APB bus clock. - #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory for a description of the cell format. diff --git a/Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt b/Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8338d11fd2b610c7fe3b1a540d0c74886eb97ee --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt @@ -0,0 +1,24 @@ +STMicroelectronics STM32 Low-Power Timer PWM + +STM32 Low-Power Timer provides single channel PWM. + +Must be a sub-node of an STM32 Low-Power Timer device tree node. +See ../mfd/stm32-lptimer.txt for details about the parent node. + +Required parameters: +- compatible: Must be "st,stm32-pwm-lp". + +Optional properties: +- pinctrl-names: Set to "default". +- pinctrl-0: Phandle pointing to pin configuration node for PWM. + +Example: + timer@40002400 { + compatible = "st,stm32-lptimer"; + ... + pwm { + compatible = "st,stm32-pwm-lp"; + pinctrl-names = "default"; + pinctrl-0 = <&lppwm1_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt index f1cbeefb30870c0e5ec5479c9582e88711ed5e21..c5171660eaf9823ec6704ee17a784807016e7e50 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt @@ -19,5 +19,4 @@ Example: reg = <0x01c20e00 0xc>; clocks = <&osc24M>; #pwm-cells = <3>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index 8007e839a716d414e5e98b2bc70c62e501a5fdc7..06a363d9ccef9069124ae813bfb449d8cab182c7 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -6,6 +6,7 @@ Required properties: for am4372 - compatible = "ti,am4372-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap"; + for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The PWM channel index ranges from 0 to 4. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt index 1a5d7b71db89ca07092c9b15e1ebed90fdbc4f6b..4633697fbda1f53a1e897663bfc53cf602cb8ad9 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt @@ -26,7 +26,6 @@ epwmss0: epwmss@48300000 { /* PWMSS for am33xx */ ti,hwmods = "epwmss0"; #address-cells = <1>; #size-cells = <1>; - status = "disabled"; ranges = <0x48300100 0x48300100 0x80 /* ECAP */ 0x48300180 0x48300180 0x80 /* EQEP */ 0x48300200 0x48300200 0x80>; /* EHRPWM */ @@ -40,7 +39,6 @@ epwmss0: epwmss@48300000 { /* PWMSS for am4372 */ ti,hwmods = "epwmss0"; #address-cells = <1>; #size-cells = <1>; - status = "disabled"; ranges = <0x48300100 0x48300100 0x80 /* ECAP */ 0x48300180 0x48300180 0x80 /* EQEP */ 0x48300200 0x48300200 0x80>; /* EHRPWM */ diff --git a/Documentation/devicetree/bindings/pwm/pwm-zx.txt b/Documentation/devicetree/bindings/pwm/pwm-zx.txt new file mode 100644 index 0000000000000000000000000000000000000000..a6bcc75c9164eb95786ab18c4b01581e83c89946 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-zx.txt @@ -0,0 +1,22 @@ +ZTE ZX PWM controller + +Required properties: + - compatible: Should be "zte,zx296718-pwm". + - reg: Physical base address and length of the controller's registers. + - clocks : The phandle and specifier referencing the controller's clocks. + - clock-names: "pclk" for PCLK, "wclk" for WCLK to the PWM controller. The + PCLK is for register access, while WCLK is the reference clock for + calculating period and duty cycles. + - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of + the cells format. + +Example: + + pwm: pwm@1439000 { + compatible = "zte,zx296718-pwm"; + reg = <0x1439000 0x1000>; + clocks = <&lsp1crm LSP1_PWM_PCLK>, + <&lsp1crm LSP1_PWM_WCLK>; + clock-names = "pclk", "wclk"; + #pwm-cells = <3>; + }; diff --git a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt index b067e84a94b5e92d0ecd9c0857bd2af793d51ebf..1aadc804dae4e30b2bbf40650c1edd0ac1600d1b 100644 --- a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt @@ -6,7 +6,6 @@ Required Properties: - "renesas,tpu-r8a73a4": for R8A77A4 (R-Mobile APE6) compatible PWM controller. - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller. - "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller. - - "renesas,tpu-sh7372": for SH7372 (SH-Mobile AP4) compatible PWM controller. - "renesas,tpu": for generic R-Car TPU PWM controller. - reg: Base address and length of each memory resource used by the PWM diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt index 6067d9830d07d4d21bd27ee715630d2e9ad7e073..3ae9f1088845ba4fecf43b90102256317f4b71e8 100644 --- a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt @@ -52,7 +52,6 @@ Example: compatible = "active-semi,act8865"; reg = <0x5b>; active-semi,vsel-high; - status = "disabled"; regulators { vcc_1v8_reg: DCDC_REG1 { diff --git a/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt b/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt index 5c80a7779552a18ca9d273207bf96cf571237acb..ac955dea00d16c50a89a75922672030dde122cbe 100644 --- a/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt @@ -23,7 +23,6 @@ Example: pmic@5b { compatible = "active-semi,act8945a"; reg = <0x5b>; - status = "okay"; active-semi,vsel-high; diff --git a/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt index 02649d8b3f5a372500fedfff7db12ae496a9dfba..84d544d8c1b1424546485a9619d45aa27e8de017 100644 --- a/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt @@ -1,4 +1,4 @@ -Mediatek MT6311 Regulator Driver +Mediatek MT6311 Regulator Required properties: - compatible: "mediatek,mt6311-regulator" diff --git a/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt index c35d878b0960415afe5680320fad177f9764edf3..a48749db4df36810961dbe1d74246487b7e3c26b 100644 --- a/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt @@ -1,4 +1,4 @@ -Mediatek MT6323 Regulator Driver +Mediatek MT6323 Regulator All voltage regulators are defined as subnodes of the regulators node. A list of regulators provided by this controller are defined as subnodes of the diff --git a/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt new file mode 100644 index 0000000000000000000000000000000000000000..0058441f16d2c9f0d955d58c009c666035f3212b --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt @@ -0,0 +1,89 @@ +MediaTek MT6380 Regulator + +All voltage regulators provided by the MT6380 PMIC are described as the +subnodes of the MT6380 regulators node. Each regulator is named according +to its regulator type, buck- and ldo-. The definition for each +of these nodes is defined using the standard binding for regulators at +Documentation/devicetree/bindings/regulator/regulator.txt. + +The valid names for regulators are: +BUCK: + buck-core1, buck-vcore, buck-vrf +LDO: + ldo-vm ,ldo-va , ldo-vphy, ldo-vddr, ldo-vt + +Example: + + regulators { + compatible = "mediatek,mt6380-regulator"; + + mt6380_vcpu_reg: buck-vcore1 { + regulator-name = "vcore1"; + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1393750>; + regulator-ramp-delay = <6250>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vcore_reg: buck-vcore { + regulator-name = "vcore"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + regulator-ramp-delay = <6250>; + }; + + mt6380_vrf_reg: buck-vrf { + regulator-name = "vrf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1575000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vm_reg: ldo-vm { + regulator-name = "vm"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1400000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_va_reg: ldo-va { + regulator-name = "va"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vphy_reg: ldo-vphy { + regulator-name = "vphy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vddr_reg: ldo-vddr { + regulator-name = "vddr"; + regulator-min-microvolt = <1240000>; + regulator-max-microvolt = <1840000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vt_reg: ldo-vt { + regulator-name = "vt"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt index a42b1d6e98638730773f49f0e46501925d90bf04..01141fb0087569a265832266ba8b23675d94359f 100644 --- a/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt @@ -1,4 +1,4 @@ -Mediatek MT6397 Regulator Driver +Mediatek MT6397 Regulator Required properties: - compatible: "mediatek,mt6397-regulator" diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt index bf85aa9ad6a7e43a8334fe042f8d39e042bf59db..3d78d507e29fee9390cdb9525549deff250db8a7 100644 --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt @@ -71,7 +71,7 @@ Continuous Voltage With Enable GPIO Example: * Inverted PWM logic, and the duty cycle range is limited * to 30%-70%. */ - pwm-dutycycle-range <700 300>; /* */ + pwm-dutycycle-range = <700 300>; /* */ }; Voltage Table Example: diff --git a/Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt b/Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt new file mode 100644 index 0000000000000000000000000000000000000000..3944ee3e731e216740196fc6c2f10944d45daf9f --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt @@ -0,0 +1,20 @@ +STM32 VREFBUF - Voltage reference buffer + +Some STM32 devices embed a voltage reference buffer which can be used as +voltage reference for ADCs, DACs and also as voltage reference for external +components through the dedicated VREF+ pin. + +Required properties: +- compatible: Must be "st,stm32-vrefbuf". +- reg: Offset and length of VREFBUF register set. +- clocks: Must contain an entry for peripheral clock. + +Example: + vrefbuf: regulator@58003C00 { + compatible = "st,stm32-vrefbuf"; + reg = <0x58003C00 0x8>; + clocks = <&rcc VREF_CK>; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2500000>; + vdda-supply = <&vdda>; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt new file mode 100644 index 0000000000000000000000000000000000000000..fbcefd965dc42c1d5a39c8f88d092561523fd788 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt @@ -0,0 +1,33 @@ +NXP iMX6SX/iMX7D Co-Processor Bindings +---------------------------------------- + +This binding provides support for ARM Cortex M4 Co-processor found on some +NXP iMX SoCs. + +Required properties: +- compatible Should be one of: + "fsl,imx7d-cm4" + "fsl,imx6sx-cm4" +- clocks Clock for co-processor (See: ../clock/clock-bindings.txt) +- syscon Phandle to syscon block which provide access to + System Reset Controller + +Optional properties: +- memory-region list of phandels to the reserved memory regions. + (See: ../reserved-memory/reserved-memory.txt) + +Example: + m4_reserved_sysmem1: cm4@80000000 { + reg = <0x80000000 0x80000>; + }; + + m4_reserved_sysmem2: cm4@81000000 { + reg = <0x81000000 0x80000>; + }; + + imx7d-cm4 { + compatible = "fsl,imx7d-cm4"; + memory-region = <&m4_reserved_sysmem1>, <&m4_reserved_sysmem2>; + syscon = <&src>; + clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt index 75ad7b8df0b1d782a2edce8ff80168a25a483556..728e4193f7a689e1cc406ba2cb29e29534c93283 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt @@ -63,9 +63,10 @@ on the Qualcomm ADSP Hexagon core. = SUBNODES -The adsp node may have an subnode named "smd-edge" that describes the SMD edge, -channels and devices related to the ADSP. See ../soc/qcom/qcom,smd.txt for -details on how to describe the SMD edge. +The adsp node may have an subnode named either "smd-edge" or "glink-edge" that +describes the communication edge, channels and devices related to the ADSP. +See ../soc/qcom/qcom,smd.txt and ../soc/qcom/qcom,glink.txt for details on how +to describe these. = EXAMPLE diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt index 92347fe6890e2b5d6f1e72f3b8ac43fd245d832a..7ff3f7903f267c9dd8d20983d461c7f344ca7ba6 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt @@ -90,6 +90,11 @@ the memory regions used by the Hexagon firmware. Each sub-node must contain: Value type: Definition: reference to the reserved-memory for the region +The Hexagon node may also have an subnode named either "smd-edge" or +"glink-edge" that describes the communication edge, channels and devices +related to the Hexagon. See ../soc/qcom/qcom,smd.txt and +../soc/qcom/qcom,glink.txt for details on how to describe these. + = EXAMPLE The following example describes the resources needed to boot control the Hexagon, as it is found on MSM8974 boards. diff --git a/Documentation/devicetree/bindings/remoteproc/ti,davinci-rproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,davinci-rproc.txt new file mode 100644 index 0000000000000000000000000000000000000000..e44a97e21164f9ca86266bafc3ff25e3d20d023a --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/ti,davinci-rproc.txt @@ -0,0 +1,86 @@ +TI Davinci DSP devices +======================= + +Binding status: Unstable - Subject to changes for DT representation of clocks + and resets + +The TI Davinci family of SoCs usually contains a TI DSP Core sub-system that +is used to offload some of the processor-intensive tasks or algorithms, for +achieving various system level goals. + +The processor cores in the sub-system usually contain additional sub-modules +like L1 and/or L2 caches/SRAMs, an Interrupt Controller, an external memory +controller, a dedicated local power/sleep controller etc. The DSP processor +core used in Davinci SoCs is usually a C674x DSP CPU. + +DSP Device Node: +================ +Each DSP Core sub-system is represented as a single DT node. + +Required properties: +-------------------- +The following are the mandatory properties: + +- compatible: Should be one of the following, + "ti,da850-dsp" for DSPs on OMAP-L138 SoCs + +- reg: Should contain an entry for each value in 'reg-names'. + Each entry should have the memory region's start address + and the size of the region, the representation matching + the parent node's '#address-cells' and '#size-cells' values. + +- reg-names: Should contain strings with the following names, each + representing a specific internal memory region or a + specific register space, + "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig_base" + +- interrupts: Should contain the interrupt number used to receive the + interrupts from the DSP. The value should follow the + interrupt-specifier format as dictated by the + 'interrupt-parent' node. + +- memory-region: phandle to the reserved memory node to be associated + with the remoteproc device. The reserved memory node + can be a CMA memory node, and should be defined as + per the bindings in + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt + +Optional properties: +-------------------- +- interrupt-parent: phandle to the interrupt controller node. This property + is needed if the device node hierarchy doesn't have an + interrupt controller. + + +Example: +-------- + + /* DSP Reserved Memory node */ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dsp_memory_region: dsp-memory@c3000000 { + compatible = "shared-dma-pool"; + reg = <0xc3000000 0x1000000>; + reusable; + }; + }; + + /* DSP node */ + { + dsp: dsp@11800000 { + compatible = "ti,da850-dsp"; + reg = <0x11800000 0x40000>, + <0x11e00000 0x8000>, + <0x11f00000 0x8000>, + <0x01c14044 0x4>, + <0x01c14174 0x8>; + reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", + "chipsig"; + interrupt-parent = <&intc>; + interrupts = <28>; + memory-region = <&dsp_memory_region>; + }; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt index 2aac1aa4123d8d22aa66b82db141038289df2f26..1eb72874130b8b72dd8228805988b197fd648055 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt +++ b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt @@ -26,6 +26,7 @@ The following are the mandatory properties: "ti,k2hk-dsp" for DSPs on Keystone 2 66AK2H/K SoCs "ti,k2l-dsp" for DSPs on Keystone 2 66AK2L SoCs "ti,k2e-dsp" for DSPs on Keystone 2 66AK2E SoCs + "ti,k2g-dsp" for DSPs on Keystone 2 66AK2G SoCs - reg: Should contain an entry for each value in 'reg-names'. Each entry should have the memory region's start address @@ -37,20 +38,18 @@ The following are the mandatory properties: should be defined in this order, "l2sram", "l1pram", "l1dram" -- clocks: Should contain the device's input clock, and should be - defined as per the bindings in, - Documentation/devicetree/bindings/clock/keystone-gate.txt - - ti,syscon-dev: Should be a pair of the phandle to the Keystone Device State Control node, and the register offset of the DSP boot address register within that node's address space. - resets: Should contain the phandle to the reset controller node managing the resets for this device, and a reset - specifier. Please refer to the following reset bindings - for the reset argument specifier as per SoC, + specifier. Please refer to either of the following reset + bindings for the reset argument specifier as per SoC, Documentation/devicetree/bindings/reset/ti-syscon-reset.txt - for 66AK2HK/66AK2L/66AK2E SoCs + for 66AK2HK/66AK2L/66AK2E SoCs or, + Documentation/devicetree/bindings/reset/ti,sci-reset.txt + for 66AK2G SoCs - interrupt-parent: Should contain a phandle to the Keystone 2 IRQ controller IP node that is used by the ARM CorePac processor to @@ -75,6 +74,22 @@ The following are the mandatory properties: The gpio device to be used is as per the bindings in, Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt +SoC-specific Required properties: +--------------------------------- +The following are mandatory properties for Keystone 2 66AK2HK, 66AK2L and 66AK2E +SoCs only: + +- clocks: Should contain the device's input clock, and should be + defined as per the bindings in, + Documentation/devicetree/bindings/clock/keystone-gate.txt + +The following are mandatory properties for Keystone 2 66AK2G SoCs only: + +- power-domains: Should contain a phandle to a PM domain provider node + and an args specifier containing the DSP device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + Optional properties: -------------------- @@ -85,8 +100,10 @@ Optional properties: Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt -Example: --------- +Examples: +--------- + +1. /* 66AK2H/K DSP aliases */ aliases { rproc0 = &dsp0; @@ -131,3 +148,41 @@ Example: }; }; + +2. + /* 66AK2G DSP alias */ + aliases { + rproc0 = &dsp0; + }; + + /* 66AK2G DSP memory node */ + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + }; + }; + + /* 66AK2G DSP node */ + soc { + dsp0: dsp@10800000 { + compatible = "ti,k2g-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + power-domains = <&k2g_pds 0x0046>; + ti,syscon-dev = <&devctrl 0x40>; + resets = <&k2g_reset 0x0046 0x1>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + memory-region = <&dsp_common_memory>; + }; + }; diff --git a/Documentation/devicetree/bindings/reset/lantiq,reset.txt b/Documentation/devicetree/bindings/reset/lantiq,reset.txt new file mode 100644 index 0000000000000000000000000000000000000000..c6aef36b7d150e4adf7ad2c2eae4041b2eef4e9f --- /dev/null +++ b/Documentation/devicetree/bindings/reset/lantiq,reset.txt @@ -0,0 +1,30 @@ +Lantiq XWAY SoC RCU reset controller binding +============================================ + +This binding describes a reset-controller found on the RCU module on Lantiq +XWAY SoCs. + +This node has to be a sub node of the Lantiq RCU block. + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,danube-reset" + "lantiq,xrx200-reset" +- reg : Defines the following sets of registers in the parent + syscon device + - Offset of the reset set register + - Offset of the reset status register +- #reset-cells : Specifies the number of cells needed to encode the + reset line, should be 2. + The first cell takes the reset set bit and the + second cell takes the status bit. + +------------------------------------------------------------------------------- +Example for the reset-controllers on the xRX200 SoCs: + reset0: reset-controller@10 { + compatible = "lantiq,xrx200-reset"; + reg <0x10 0x04>, <0x14 0x04>; + + #reset-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt index b4e96a27844527cc7bda3081d59a5fe61d5492d4..05d5be48dae44d39a165a257d915348c406a8008 100644 --- a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt +++ b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt @@ -80,5 +80,4 @@ mac: ethernet@40010000 { clock-names = "stmmaceth"; resets = <&rgu 22>; reset-names = "stmmaceth"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index fe5e0f37b3c935794428cbe950e50dde3628ac89..e5a03ffe04fb2af74ed41b7aa36aee284edc437a 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -26,6 +26,7 @@ Required properties: - "renesas,r8a7794-rst" (R-Car E2) - "renesas,r8a7795-rst" (R-Car H3) - "renesas,r8a7796-rst" (R-Car M3-W) + - "renesas,r8a77995-rst" (R-Car D3) - reg: Address start and address range for the device. diff --git a/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt b/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt new file mode 100644 index 0000000000000000000000000000000000000000..830069b1c37c4163f878f87a3780f135af4a2d7c --- /dev/null +++ b/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt @@ -0,0 +1,28 @@ +Binding for the Synopsys HSDK reset controller + +This binding uses the common reset binding[1]. + +[1] Documentation/devicetree/bindings/reset/reset.txt + +Required properties: +- compatible: should be "snps,hsdk-reset". +- reg: should always contain 2 pairs address - length: first for reset + configuration register and second for corresponding SW reset and status bits + register. +- #reset-cells: from common reset binding; Should always be set to 1. + +Example: + reset: reset@880 { + compatible = "snps,hsdk-reset"; + #reset-cells = <1>; + reg = <0x8A0 0x4>, <0xFF0 0x4>; + }; + +Specifying reset lines connected to IP modules: + ethernet@.... { + .... + resets = <&reset HSDK_V1_ETH_RESET>; + .... + }; + +The index could be found in diff --git a/Documentation/devicetree/bindings/reset/uniphier-reset.txt b/Documentation/devicetree/bindings/reset/uniphier-reset.txt index 83ab0f599c4090712bb4c8bd4f52d8a5d5701947..68a6f487c4092f205eb4cae09ca962195c15c06e 100644 --- a/Documentation/devicetree/bindings/reset/uniphier-reset.txt +++ b/Documentation/devicetree/bindings/reset/uniphier-reset.txt @@ -6,7 +6,6 @@ System reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-reset" - for sLD3 SoC "socionext,uniphier-ld4-reset" - for LD4 SoC "socionext,uniphier-pro4-reset" - for Pro4 SoC "socionext,uniphier-sld8-reset" - for sLD8 SoC @@ -37,7 +36,6 @@ Media I/O (MIO) reset, SD reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC "socionext,uniphier-ld4-mio-reset" - for LD4 SoC "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC @@ -92,3 +90,28 @@ Example: other nodes ... }; + + +Analog signal amplifier reset +----------------------------- + +Required properties: +- compatible: should be one of the following: + "socionext,uniphier-ld11-adamv-reset" - for LD11 SoC + "socionext,uniphier-ld20-adamv-reset" - for LD20 SoC +- #reset-cells: should be 1. + +Example: + + adamv@57920000 { + compatible = "socionext,uniphier-ld11-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld11-adamv-reset"; + #reset-cells = <1>; + }; + + other nodes ... + }; diff --git a/Documentation/devicetree/bindings/rng/imx-rngc.txt b/Documentation/devicetree/bindings/rng/imx-rngc.txt new file mode 100644 index 0000000000000000000000000000000000000000..93c7174a7bedc8b0e0bef80f40379f9017c3e61d --- /dev/null +++ b/Documentation/devicetree/bindings/rng/imx-rngc.txt @@ -0,0 +1,21 @@ +Freescale RNGC (Random Number Generator Version C) + +The driver also supports version B, which is mostly compatible +to version C. + +Required properties: +- compatible : should be one of + "fsl,imx25-rngb" + "fsl,imx35-rngc" +- reg : offset and length of the register set of this block +- interrupts : the interrupt number for the RNGC block +- clocks : the RNGC clk source + +Example: + +rng@53fb0000 { + compatible = "fsl,imx25-rngb"; + reg = <0x53fb0000 0x4000>; + interrupts = <22>; + clocks = <&trng_clk>; +}; diff --git a/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt b/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt new file mode 100644 index 0000000000000000000000000000000000000000..634312dd95ca7e84b7ac0b5624569d34256f98b5 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt @@ -0,0 +1,17 @@ +Android Goldfish RTC + +Android Goldfish RTC device used by Android emulator. + +Required properties: + +- compatible : should contain "google,goldfish-rtc" +- reg : +- interrupts : + +Example: + + goldfish_timer@9020000 { + compatible = "google,goldfish-rtc"; + reg = <0x9020000 0x1000>; + interrupts = <0x3>; + }; diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12057.txt b/Documentation/devicetree/bindings/rtc/isil,isl12057.txt index cf83e0940302cbf3b1795be0a06df1a8191220ef..fbbdd92e5af93142fcad51b58dd48d3387efac10 100644 --- a/Documentation/devicetree/bindings/rtc/isil,isl12057.txt +++ b/Documentation/devicetree/bindings/rtc/isil,isl12057.txt @@ -24,7 +24,6 @@ Optional properties: - "wakeup-source": mark the chip as a wakeup source, independently of the availability of an IRQ line connected to the SoC. - (Legacy property supported: "isil,irq2-can-wakeup-machine") - "interrupt-parent", "interrupts": for passing the interrupt line of the SoC connected to IRQ#2 of the RTC chip. diff --git a/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt b/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt new file mode 100644 index 0000000000000000000000000000000000000000..bbf1ccb5df318acd1eef28bff1e06b92402e7816 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt @@ -0,0 +1,16 @@ +Realtek RTD129x Real-Time Clock +=============================== + +Required properties: +- compatible : Should be "realtek,rtd1295-rtc" +- reg : Specifies the physical base address and size +- clocks : Specifies the clock gate + + +Example: + + rtc@9801b600 { + compatible = "realtek,rtd1295-clk"; + reg = <0x9801b600 0x100>; + clocks = <&clkc RTD1295_CLK_EN_MISC_RTC>; + }; diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt index 0a4c371a9b7a8ac46eb7db378da1ad1b117723d1..a66692a08acedd13b199bb7865542db6db20e425 100644 --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt @@ -45,5 +45,4 @@ Example: interrupts = <17 1>; interrupt-names = "alarm"; st,syscfg = <&pwrcfg>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt index 945934918b71fc127da6729f38b6498884ad5fca..d5e26d313f62624abb929c1334d2a9b1b77a73b2 100644 --- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt @@ -10,7 +10,7 @@ Required properties: Required properties for new device trees - clocks : phandle to the 32kHz external oscillator -- clock-output-names : name of the LOSC clock created +- clock-output-names : names of the LOSC and its external output clocks created - #clock-cells : must be equals to 1. The RTC provides two clocks: the LOSC and its external output, with index 0 and 1 respectively. @@ -21,7 +21,7 @@ rtc: rtc@01f00000 { compatible = "allwinner,sun6i-a31-rtc"; reg = <0x01f00000 0x54>; interrupts = <0 40 4>, <0 41 4>; - clock-output-names = "osc32k"; + clock-output-names = "osc32k", "osc32k-out"; clocks = <&ext_osc32k>; #clock-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt index 2a42a323fa1a20d1dd85fcde820166db5f976f91..b6a869f977152f37153cc871f4ac8fc7a4d84ba9 100644 --- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt @@ -85,5 +85,4 @@ Example: <366 1>,<367 1>/* cq30-31 */ <376 4>,/* fatal ecc */ <381 4>;/* fatal axi */ - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt b/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt index 3ad115efed1ef90179d094ed8cb8e765802af870..6a4e0d30d8c4bba28846702eda765237e72d8b18 100644 --- a/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt +++ b/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt @@ -19,7 +19,6 @@ Example (for ARM-based BeagleBoard xM with ST33ZP24 on I2C2): &i2c2 { - status = "okay"; st33zp24: st33zp24@13 { diff --git a/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt b/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt index 158b0165e01cb75f2b184bb0fd0e65b759b26307..604dce901b605f2e922f44fd4eee7cc0f98f1430 100644 --- a/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt +++ b/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt @@ -18,7 +18,6 @@ Example (for ARM-based BeagleBoard xM with ST33ZP24 on SPI4): &mcspi4 { - status = "okay"; st33zp24@0 { diff --git a/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt b/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt index 8cb638b7e89c399da1ad937e98720b0814b8c9e4..a65d7b71e81a2a22bfc23ab79ede461a25d2de37 100644 --- a/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt +++ b/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt @@ -8,6 +8,12 @@ Required properties: the firmware event log - linux,sml-size : size of the memory allocated for the firmware event log +Optional properties: + +- powered-while-suspended: present when the TPM is left powered on between + suspend and resume (makes the suspend/resume + callbacks do nothing). + Example (for OpenPower Systems with Nuvoton TPM 2.0 on I2C) ---------------------------------------------------------- @@ -17,5 +23,4 @@ tpm@57 { compatible = "nuvoton,npct650", "nuvoton,npct601"; linux,sml-base = <0x7f 0xfd450000>; linux,sml-size = <0x10000>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt b/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt index 85741cd468cce55a237f2f58e26145b5381dd47c..b800667da92b82555d74a194b65d201dda86da61 100644 --- a/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt +++ b/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt @@ -13,7 +13,6 @@ Example (for ARM-based BeagleBoard xM with TPM_TIS on SPI4): &mcspi4 { - status = "okay"; tpm_tis@0 { diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index 419ff6c0a47f8c9e3d7cbbc1800864042e762ebb..dad3b2ec66d45e8b8af037b2ef61b3770bec1256 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -14,6 +14,8 @@ Required properties: tegra132, or tegra210. - "nxp,lpc3220-uart" - "ralink,rt2880-uart" + - For MediaTek BTIF, must contain '"mediatek,-btif", + "mediatek,mtk-btif"' where is mt7622, mt7623. - "altr,16550-FIFO32" - "altr,16550-FIFO64" - "altr,16550-FIFO128" diff --git a/Documentation/devicetree/bindings/serial/arc-uart.txt b/Documentation/devicetree/bindings/serial/arc-uart.txt index 5cae2eb686f891026ff254098ee458032d12b9b3..256cc150ca7e55fb2c077f5c72db964dfeb891bb 100644 --- a/Documentation/devicetree/bindings/serial/arc-uart.txt +++ b/Documentation/devicetree/bindings/serial/arc-uart.txt @@ -15,7 +15,6 @@ arcuart0: serial@c0fc1000 { interrupts = <5>; clock-frequency = <80000000>; current-speed = <115200>; - status = "okay"; }; Note: Each port should have an alias correctly numbered in "aliases" node. diff --git a/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt b/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt index 51b3c9e80ad960e27efdc53ee0b85bab431185a4..048c3818c8262788745fdf6f30b21968b97be825 100644 --- a/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt +++ b/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt @@ -15,7 +15,6 @@ serial@b00260000 { compatible = "axis,etraxfs-uart"; reg = <0xb0026000 0x1000>; interrupts = <68>; - status = "disabled"; dtr-gpios = <&sysgpio 0 GPIO_ACTIVE_LOW>; dsr-gpios = <&sysgpio 1 GPIO_ACTIVE_LOW>; rng-gpios = <&sysgpio 2 GPIO_ACTIVE_LOW>; diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt index b6cf384597e1dabc5f5e090982235f0e0c56128a..f73abff3de43bcdb0ecdaabc0f4f23a470d7268d 100644 --- a/Documentation/devicetree/bindings/serial/mtk-uart.txt +++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt @@ -3,6 +3,7 @@ Required properties: - compatible should contain: * "mediatek,mt2701-uart" for MT2701 compatible UARTS + * "mediatek,mt2712-uart" for MT2712 compatible UARTS * "mediatek,mt6580-uart" for MT6580 compatible UARTS * "mediatek,mt6582-uart" for MT6582 compatible UARTS * "mediatek,mt6589-uart" for MT6589 compatible UARTS diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt index c93a2d1c1a654e3a618a4976086aa8d145903da1..d7edf732eb7f5716f8feb5e9d8398cb8a3ac1dbc 100644 --- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt @@ -33,5 +33,4 @@ serial@70006000 { reset-names = "serial"; dmas = <&apbdma 8>, <&apbdma 8>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt index d5f73b8f614fcc6d51d7d958fadd33f72dfecb3d..9d098cf73b533171be76b3caaa10ec4532f38cfd 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt @@ -72,13 +72,10 @@ Examples: }; uarta: serial@12490000 { - status = "ok"; }; uartb: serial@16340000 { - status = "ok"; }; uartc: serial@1a240000 { - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 8d27d1a603e7bf755c8451186cdb507dd1d50a58..cf504d0380aeb9d0749cc2ab1f90e2f35a781146 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -41,6 +41,10 @@ Required properties: - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. + - "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART. + - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART. + - "renesas,scif-r8a77995" for R8A77995 (R-Car D3) SCIF compatible UART. + - "renesas,hscif-r8a77995" for R8A77995 (R-Car D3) HSCIF compatible UART. - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, diff --git a/Documentation/devicetree/bindings/serial/rs485.txt b/Documentation/devicetree/bindings/serial/rs485.txt index 32b1fa1f2a5b8dec1eca195f1fea93528155728b..b8415936dfdbc59cdf8c6027337603579d3e9403 100644 --- a/Documentation/devicetree/bindings/serial/rs485.txt +++ b/Documentation/devicetree/bindings/serial/rs485.txt @@ -5,14 +5,13 @@ the built-in half-duplex mode. The properties described hereafter shall be given to a half-duplex capable UART node. -Required properties: +Optional properties: - rs485-rts-delay: prop-encoded-array where: * a is the delay between rts signal and beginning of data sent in milliseconds. it corresponds to the delay before sending data. * b is the delay between end of data sent and rts signal in milliseconds it corresponds to the delay after sending data and actual release of the line. - -Optional properties: + If this property is not specified, <0 0> is assumed. - linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485 feature at boot time. It can be disabled later with proper ioctl. - rs485-rx-during-tx: empty property that enables the receiving of data even diff --git a/Documentation/devicetree/bindings/serial/serial.txt b/Documentation/devicetree/bindings/serial/serial.txt index b542a0ecf06e897b4d4c87fdff1dab6dbd82c513..863c2893759e715161db4e00df15a2643031cf4b 100644 --- a/Documentation/devicetree/bindings/serial/serial.txt +++ b/Documentation/devicetree/bindings/serial/serial.txt @@ -43,7 +43,6 @@ Examples: rng-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; rts-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; - status = "okay"; }; scifa4: serial@e6c80000 { @@ -54,5 +53,4 @@ Examples: clock-names = "fck"; power-domains = <&pd_a3sp>; uart-has-rtscts; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt index 85ec5f2b19968a44ae80b039217c3786b199da24..3657f9f9d17a98302e873c7c75bbd0ee312e13b0 100644 --- a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt @@ -1,12 +1,19 @@ * STMicroelectronics STM32 USART Required properties: -- compatible: Can be either "st,stm32-usart", "st,stm32-uart", -"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether -the device supports synchronous mode and is compatible with -stm32(f4) or stm32f7. +- compatible: can be either: + - "st,stm32-usart", + - "st,stm32-uart", + - "st,stm32f7-usart", + - "st,stm32f7-uart", + - "st,stm32h7-usart" + - "st,stm32h7-uart". + depending on whether the device supports synchronous mode + and is compatible with stm32(f4), stm32f7 or stm32h7. - reg: The address and length of the peripheral registers space -- interrupts: The interrupt line of the USART instance +- interrupts: + - The interrupt line for the USART instance, + - An optional wake-up interrupt. - clocks: The input clock of the USART instance Optional properties: diff --git a/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt b/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt index 362a76925bcdfef2fac5a3e339dad92449d13199..f311472990a7e5f081dad3cdba160e2d5edc7abc 100644 --- a/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt +++ b/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt @@ -19,5 +19,4 @@ Example: reg = <0x01c2a000 0x400>; interrupts = <0 62 4>; clocks = <&apb1_gates 6>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/serio/ps2-gpio.txt b/Documentation/devicetree/bindings/serio/ps2-gpio.txt new file mode 100644 index 0000000000000000000000000000000000000000..7b7bc9cdf9861257f6886029c432b1b08ce1e52b --- /dev/null +++ b/Documentation/devicetree/bindings/serio/ps2-gpio.txt @@ -0,0 +1,23 @@ +Device-Tree binding for ps/2 gpio device + +Required properties: + - compatible = "ps2-gpio" + - data-gpios: the data pin + - clk-gpios: the clock pin + - interrupts: Should trigger on the falling edge of the clock line. + +Optional properties: + - write-enable: Indicates whether write function is provided + to serio device. Possibly providing the write fn will not work, because + of the tough timing requirements. + +Example nodes: + +ps2@0 { + compatible = "ps2-gpio"; + interrupt-parent = <&gpio>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; + data-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + clk-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + write-enable; +}; diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt index b1d165b4d4b31104e4c137c18ad8079ff66943e9..40056f7990f86f337296fe9bc13343c5c6b2f446 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt @@ -12,11 +12,13 @@ power/power_domain.txt. It provides the power domains defined in - include/dt-bindings/power/mt8173-power.h - include/dt-bindings/power/mt6797-power.h - include/dt-bindings/power/mt2701-power.h +- include/dt-bindings/power/mt7622-power.h Required properties: - compatible: Should be one of: - "mediatek,mt2701-scpsys" - "mediatek,mt6797-scpsys" + - "mediatek,mt7622-scpsys" - "mediatek,mt8173-scpsys" - #power-domain-cells: Must be 1 - reg: Address range of the SCPSYS unit @@ -26,6 +28,7 @@ Required properties: enabled before enabling certain power domains. Required clocks for MT2701: "mm", "mfg", "ethif" Required clocks for MT6797: "mm", "mfg", "vdec" + Required clocks for MT7622: "hif_sel" Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt" Optional properties: diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt index 50fc20c6ce91e9971e7c136c5b29bb3e143b856e..b277eca861f72a45c7fa0bbd2d6d35656d730d39 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt @@ -1,11 +1,12 @@ -Qualcomm RPM GLINK binding +Qualcomm GLINK edge binding -This binding describes the Qualcomm RPM GLINK, a fifo based mechanism for -communication with the Resource Power Management system on various Qualcomm -platforms. +This binding describes a Qualcomm GLINK edge, a fifo based mechanism for +communication between subsystem-pairs on various Qualcomm platforms. Two types +of edges can be described by the binding; the GLINK RPM edge and a SMEM based +edge. - compatible: - Usage: required + Usage: required for glink-rpm Value type: Definition: must be "qcom,glink-rpm" @@ -16,7 +17,7 @@ platforms. signal this processor about communication related events - qcom,rpm-msg-ram: - Usage: required + Usage: required for glink-rpm Value type: Definition: handle to RPM message memory resource diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt index 2f5ede39bea2d1d3cffacbcbe0ed103a7d2c708a..fe1855f09dcc36f765e3a48760001db0f9b79361 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt @@ -78,7 +78,6 @@ Example for APQ8064: interrupts = <0 152 0x0>; clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>; clock-names = "core", "iface"; - status = "ok"; }; }; diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.txt b/Documentation/devicetree/bindings/soc/rockchip/grf.txt index cc9f05d3cbc1a0b08a2a278364332b8114b027a3..7dc5ce858a0ee3a6659cc0be7a0d3194f7a6fa3e 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/grf.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/grf.txt @@ -21,6 +21,7 @@ Required Properties: - "rockchip,rk3328-grf", "syscon": for rk3328 - "rockchip,rk3368-grf", "syscon": for rk3368 - "rockchip,rk3399-grf", "syscon": for rk3399 + - "rockchip,rv1108-grf", "syscon": for rv1108 - compatible: PMUGRF should be one of the following: - "rockchip,rk3368-pmugrf", "syscon": for rk3368 - "rockchip,rk3399-pmugrf", "syscon": for rk3399 @@ -28,6 +29,8 @@ Required Properties: - "rockchip,rk3288-sgrf", "syscon": for rk3288 - compatible: USB2PHYGRF should be one of the followings - "rockchip,rk3328-usb2phy-grf", "syscon": for rk3328 +- compatible: USBGRF should be one of the following + - "rockchip,rv1108-usbgrf", "syscon": for rv1108 - reg: physical base address of the controller and length of memory mapped region. diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt index 01bfb6745fbd79d77251392beb719d22fe73aef2..301d2a9bc1b8bb2ab0e213e6656b03691c2c71e8 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt @@ -7,6 +7,7 @@ Required properties for power domain controller: - compatible: Should be one of the following. "rockchip,rk3288-power-controller" - for RK3288 SoCs. "rockchip,rk3328-power-controller" - for RK3328 SoCs. + "rockchip,rk3366-power-controller" - for RK3366 SoCs. "rockchip,rk3368-power-controller" - for RK3368 SoCs. "rockchip,rk3399-power-controller" - for RK3399 SoCs. - #power-domain-cells: Number of cells in a power-domain specifier. @@ -18,6 +19,7 @@ Required properties for power domain sub nodes: - reg: index of the power domain, should use macros in: "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain. + "include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain. "include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain. "include/dt-bindings/power/rk3399-power.h" - for RK3399 type power domain. - clocks (optional): phandles to clocks which need to be enabled while power domain @@ -93,6 +95,7 @@ power domain to use. The index should use macros in: "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. "include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain. + "include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain. "include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain. "include/dt-bindings/power/rk3399-power.h" - for rk3399 type power domain. diff --git a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt index c705db07d8206d74835c729cf6253d97a7227df0..66e6265fb0aa2f2af147c63a776c86bb9a52096f 100644 --- a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt @@ -46,12 +46,13 @@ Required Properties: - power-domains: phandle pointing to the corresponding PM domain node and an ID representing the device. -See dt-bindings/genpd/k2g.h for the list of valid identifiers for k2g. +See http://processors.wiki.ti.com/index.php/TISCI#66AK2G02_Data for the list +of valid identifiers for k2g. Example (K2G): -------------------- uart0: serial@02530c00 { compatible = "ns16550a"; ... - power-domains = <&k2g_pds K2G_DEV_UART0>; + power-domains = <&k2g_pds 0x002c>; }; diff --git a/Documentation/devicetree/bindings/sound/armada-370db-audio.txt b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt index bf984d238620c2cc30cbda20f48bf58135138d3f..953c092db72f044fb461f9f674e445db692e3478 100644 --- a/Documentation/devicetree/bindings/sound/armada-370db-audio.txt +++ b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt @@ -23,5 +23,4 @@ Example: compatible = "marvell,a370db-audio"; marvell,audio-controller = <&audio_controller>; marvell,audio-codec = <&audio_codec &spdif_out &spdif_in>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt index 549e701cb7a1c58620863fc0a5e5b08c313ff4ef..898551076382abef7941b3772cbbc5511a8ac476 100644 --- a/Documentation/devicetree/bindings/sound/atmel-classd.txt +++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt @@ -13,13 +13,11 @@ Required properties: Must be "tx". - clock-names Tuple listing input clock names. - Required elements: "pclk", "gclk" and "aclk". + Required elements: "pclk" and "gclk". - clocks Please refer to clock-bindings.txt. - assigned-clocks Should be <&classd_gclk>. -- assigned-clock-parents - Should be <&audio_pll_pmc>. Optional properties: - pinctrl-names, pinctrl-0 @@ -45,10 +43,9 @@ classd: classd@fc048000 { (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(47))>; dma-names = "tx"; - clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; - clock-names = "pclk", "gclk", "aclk"; + clocks = <&classd_clk>, <&classd_gclk>; + clock-names = "pclk", "gclk"; assigned-clocks = <&classd_gclk>; - assigned-clock-parents = <&audio_pll_pmc>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_classd_default>; diff --git a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt index fdb25b49251430f23d8efeb0ca43f62493e8b679..9d049d4bfd58f5ab6d1d56cf19956f7615668b6b 100644 --- a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt +++ b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt @@ -45,7 +45,6 @@ Example: &ssc0 { #sound-dai-cells = <0>; - status = "okay"; }; &i2c { diff --git a/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt b/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt index b139e66d2a1122a3f2dc0e38c9929bdba8cdeed7..630bf7c0344d1a459050ed3904de8a5f08f68904 100644 --- a/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt +++ b/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt @@ -47,21 +47,17 @@ Example: ssp0: ssp_port@0 { reg = <0>; - status = "okay"; }; ssp1: ssp_port@1 { reg = <1>; - status = "disabled"; }; ssp2: ssp_port@2 { reg = <2>; - status = "disabled"; }; spdif: spdif_port@3 { reg = <3>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/sound/cs43130.txt b/Documentation/devicetree/bindings/sound/cs43130.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b1dd5aeb00467bee506ea4f82420ab7672f8e53 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs43130.txt @@ -0,0 +1,67 @@ +CS43130 DAC + +Required properties: + + - compatible : "cirrus,cs43130", "cirrus,cs4399", "cirrus,cs43131", + "cirrus,cs43198" + + - reg : the I2C address of the device for I2C + + - VA-supply, VP-supply, VL-supply, VCP-supply, VD-supply: + power supplies for the device, as covered in + Documentation/devicetree/bindings/regulator/regulator.txt. + + +Optional properties: + + - reset-gpios : Active low GPIO used to reset the device + + - cirrus,xtal-ibias: + When external MCLK is generated by external crystal + oscillator, CS43130 can be used to provide bias current + for external crystal. Amount of bias current sent is + set as: + 1 = 7.5uA + 2 = 12.5uA + 3 = 15uA + + - cirrus,dc-measure: + Boolean, define to enable headphone DC impedance measurement. + + - cirrus,ac-measure: + Boolean, define to enable headphone AC impedance measurement. + DC impedance must also be enabled for AC impedance measurement. + + - cirrus,dc-threshold: + Define 2 DC impedance thresholds in ohms for HP output control. + Default values are 50 and 120 Ohms. + + - cirrus,ac-freq: + Define the frequencies at which to measure HP AC impedance. + Only used if "cirrus,dc-measure" is defined. + Exactly 10 frequencies must be defined. + If this properties is undefined, by default, + following frequencies are used: + <24 43 93 200 431 928 2000 4309 9283 20000> + The above frequencies are logarithmically equally spaced. + Log base is 10. + +Example: + +cs43130: audio-codec@30 { + compatible = "cirrus,cs43130"; + reg = <0x30>; + reset-gpios = <&axi_gpio 54 0>; + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; + VL-supply = <&dummy_vreg>; + VCP-supply = <&dummy_vreg>; + VD-supply = <&dummy_vreg>; + cirrus,xtal-ibias = <2>; + interrupt-parent = <&gpio0>; + interrupts = <55 8>; + cirrus,dc-measure; + cirrus,ac-measure; + cirrus,dc-threshold = /bits/ 16 <20 100>; + cirrus,ac-freq = /bits/ 16 <24 43 93 200 431 928 2000 4309 9283 20000>; +}; diff --git a/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt b/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt index e0b6165c9cfcec19051bf7f8e1c5873374f83a69..3ffc2562fb31a24165ed4ae374ef011b43317007 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt @@ -47,5 +47,4 @@ mcbsp0: mcbsp@1d10000 { dmas = <&edma0 3 1 &edma0 2 1>; dma-names = "tx", "rx"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/dmic.txt b/Documentation/devicetree/bindings/sound/dmic.txt new file mode 100644 index 0000000000000000000000000000000000000000..54c8ef6498a87d26b830cfe3ed69543c2b97ae12 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/dmic.txt @@ -0,0 +1,16 @@ +Device-Tree bindings for Digital microphone (DMIC) codec + +This device support generic PDM digital microphone. + +Required properties: + - compatible: should be "dmic-codec". + +Optional properties: + - dmicen-gpios: GPIO specifier for dmic to control start and stop + +Example node: + + dmic_codec: dmic@0 { + compatible = "dmic-codec"; + dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt index 3e26a9478e570279eeaf461a7ed675c6f3f013ed..65979b205893c791de5332fb84a23543720ee0b5 100644 --- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt +++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt @@ -61,5 +61,4 @@ asrc: asrc@02034000 { "txa", "txb", "txc"; fsl,asrc-rate = <48000>; fsl,asrc-width = <16>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt index cd3ee5d84f030f67df79de05b9561e1937dc6ce0..21c401e2ccda6e66bc2ef110b64d701a519b5d40 100644 --- a/Documentation/devicetree/bindings/sound/fsl,esai.txt +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt @@ -59,5 +59,4 @@ esai: esai@02024000 { fsl,fifo-depth = <128>; fsl,esai-synchronous; big-endian; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt index 4ca39ddc04172bcc4a56e41a193b7ea405ad82a7..0f97e54c3d436965eaff1e31e92db569170cb02f 100644 --- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt +++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt @@ -59,5 +59,4 @@ spdif: spdif@02004000 { "rxtx7"; big-endian; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/hdmi.txt b/Documentation/devicetree/bindings/sound/hdmi.txt index 31af7bca309979e1b26ce817700a4dab64d93afd..56407c30e954d507423500900908b1f0b9764f23 100644 --- a/Documentation/devicetree/bindings/sound/hdmi.txt +++ b/Documentation/devicetree/bindings/sound/hdmi.txt @@ -13,5 +13,4 @@ Example node: hdmi_audio: hdmi_audio@0 { compatible = "linux,hdmi-audio"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt index 9800a560e0c20586e4c7ba4ccbcddab44575b437..77a57f84bed486204f0a7caa3780d6e18416544a 100644 --- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt +++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt @@ -3,7 +3,8 @@ Mediatek AFE PCM controller for mt2701 Required properties: - compatible = "mediatek,mt2701-audio"; - reg: register location and size -- interrupts: Should contain AFE interrupt +- interrupts: should contain AFE and ASYS interrupts +- interrupt-names: should be "afe" and "asys" - power-domains: should define the power domain - clock-names: should have these clock names: "infra_sys_audio_clk", @@ -59,6 +60,7 @@ Example: <0 0x112A0000 0 0x20000>; interrupts = , ; + interrupt-names = "afe", "asys"; power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; clocks = <&infracfg CLK_INFRA_AUDIO>, <&topckgen CLK_TOP_AUD_MUX1_SEL>, diff --git a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt index ccb401cfef9da31b13d4ffbaec7909357c137b22..551ecab67efe89ba4f5f0f0da6951a605598f289 100644 --- a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt +++ b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt @@ -31,8 +31,22 @@ Required properties - vdd-cdc-io-supply: phandle to VDD_CDC_IO regulator DT node. - vdd-cdc-tx-rx-cx-supply: phandle to VDD_CDC_TX/RX/CX regulator DT node. - vdd-micbias-supply: phandle of VDD_MICBIAS supply's regulator DT node. - Optional Properties: + - qcom,mbhc-vthreshold-low: Array of 5 threshold voltages in mV for 5 buttons + detection on headset when the mbhc is powered up + by internal current source, this is a low power. + - qcom,mbhc-vthreshold-high: Array of 5 thresold voltages in mV for 5 buttons + detection on headset when mbhc is powered up + from micbias. +- qcom,micbias-lvl: Voltage (mV) for Mic Bias +- qcom,hphl-jack-type-normally-open: boolean, present if hphl pin on jack is a + NO (Normally Open). If not specified, then + its assumed that hphl pin on jack is NC + (Normally Closed). +- qcom,gnd-jack-type-normally-open: boolean, present if gnd pin on jack is + NO (Normally Open). If not specified, then + its assumed that gnd pin on jack is NC + (Normally Closed). - qcom,micbias1-ext-cap: boolean, present if micbias1 has external capacitor connected. - qcom,micbias2-ext-cap: boolean, present if micbias2 has external capacitor @@ -48,6 +62,8 @@ spmi_bus { reg-names = "pmic-codec-core"; clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; clock-names = "mclk"; + qcom,mbhc-vthreshold-low = <75 150 237 450 500>; + qcom,mbhc-vthreshold-high = <75 150 237 450 500>; interrupt-parent = <&spmi_bus>; interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>, <0x1 0xf0 0x1 IRQ_TYPE_NONE>, diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 7246bb268bf9bab6a49c78af481455a8fb744e42..085bec364caf6592539535d13a6e50a05515c888 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -199,10 +199,10 @@ Ex) sound { compatible = "simple-scu-audio-card"; ... - simple-audio-card,cpu@0 { + simple-audio-card,cpu-0 { sound-dai = <&rcar_sound 0>; }; - simple-audio-card,cpu@1 { + simple-audio-card,cpu-1 { sound-dai = <&rcar_sound 1>; }; simple-audio-card,codec { @@ -441,79 +441,79 @@ rcar_sound: sound@ec500000 { "clk_a", "clk_b", "clk_c", "clk_i"; rcar_sound,dvc { - dvc0: dvc@0 { + dvc0: dvc-0 { dmas = <&audma0 0xbc>; dma-names = "tx"; }; - dvc1: dvc@1 { + dvc1: dvc-1 { dmas = <&audma0 0xbe>; dma-names = "tx"; }; }; rcar_sound,mix { - mix0: mix@0 { }; - mix1: mix@1 { }; + mix0: mix-0 { }; + mix1: mix-1 { }; }; rcar_sound,ctu { - ctu00: ctu@0 { }; - ctu01: ctu@1 { }; - ctu02: ctu@2 { }; - ctu03: ctu@3 { }; - ctu10: ctu@4 { }; - ctu11: ctu@5 { }; - ctu12: ctu@6 { }; - ctu13: ctu@7 { }; + ctu00: ctu-0 { }; + ctu01: ctu-1 { }; + ctu02: ctu-2 { }; + ctu03: ctu-3 { }; + ctu10: ctu-4 { }; + ctu11: ctu-5 { }; + ctu12: ctu-6 { }; + ctu13: ctu-7 { }; }; rcar_sound,src { - src0: src@0 { + src0: src-0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; - src1: src@1 { + src1: src-1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; - src2: src@2 { + src2: src-2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; - src3: src@3 { + src3: src-3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; - src4: src@4 { + src4: src-4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; - src5: src@5 { + src5: src-5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; - src6: src@6 { + src6: src-6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; - src7: src@7 { + src7: src-7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; - src8: src@8 { + src8: src-8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; - src9: src@9 { + src9: src-9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; @@ -521,52 +521,52 @@ rcar_sound: sound@ec500000 { }; rcar_sound,ssi { - ssi0: ssi@0 { + ssi0: ssi-0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi1: ssi@1 { + ssi1: ssi-1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi2: ssi@2 { + ssi2: ssi-2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi3: ssi@3 { + ssi3: ssi-3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi4: ssi@4 { + ssi4: ssi-4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi5: ssi@5 { + ssi5: ssi-5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi6: ssi@6 { + ssi6: ssi-6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi7: ssi@7 { + ssi7: ssi-7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi8: ssi@8 { + ssi8: ssi-8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi9: ssi@9 { + ssi9: ssi-9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; @@ -621,7 +621,6 @@ Example: simple sound card /* Single DAI */ #sound-dai-cells = <0>; - status = "okay"; rcar_sound,dai { dai0 { @@ -667,7 +666,6 @@ Example: simple sound card for Multi channel /* Single DAI */ #sound-dai-cells = <0>; - status = "okay"; rcar_sound,dai { dai0 { diff --git a/Documentation/devicetree/bindings/sound/rockchip,pdm.txt b/Documentation/devicetree/bindings/sound/rockchip,pdm.txt index 921729de7346eb659f4bceba0a71f97d3922b577..47f164fbd1d72f80f8caedb7e6d62ad991351897 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,pdm.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,pdm.txt @@ -29,11 +29,13 @@ pdm: pdm@ff040000 { dma-names = "rx"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&pdmm0_clk - &pdmm0_fsync &pdmm0_sdi0 &pdmm0_sdi1 &pdmm0_sdi2 &pdmm0_sdi3>; - pinctrl-1 = <&pdmm0_sleep>; - status = "disabled"; + pinctrl-1 = <&pdmm0_clk_sleep + &pdmm0_sdi0_sleep + &pdmm0_sdi1_sleep + &pdmm0_sdi2_sleep + &pdmm0_sdi3_sleep>; }; diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt index eac91db07178891aff5bf2fb10102b9a6a9f24d0..72d3cf4c2606006ecaae21a126b6e2c2045a4ec0 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt @@ -4,7 +4,7 @@ Required properties: - compatible: "rockchip,rk3399-gru-sound" - rockchip,cpu: The phandle of the Rockchip I2S controller that's connected to the codecs -- rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs +- rockchip,codec: The phandle of the audio codecs Optional properties: - dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready. diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt index 206aba1b34bb5a3f44e528d874a7520e5882c3fc..b208a752576c1173669d2d408b60101d05b361ac 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt @@ -7,8 +7,12 @@ Required properties: - compatible: should be one of the following: - "rockchip,rk3066-i2s": for rk3066 + - "rockchip,rk3036-i2s", "rockchip,rk3066-i2s": for rk3036 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188 + - "rockchip,rk3228-i2s", "rockchip,rk3066-i2s": for rk3228 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288 + - "rockchip,rk3328-i2s", "rockchip,rk3066-i2s": for rk3328 + - "rockchip,rk3366-i2s", "rockchip,rk3066-i2s": for rk3366 - "rockchip,rk3368-i2s", "rockchip,rk3066-i2s": for rk3368 - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399 - reg: physical base address of the controller and length of memory mapped diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt index 4706b96d450bf502991ef58f6793b73f036617b4..0a1dc4e1815cb524faee4c228a14ddeeea626578 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt @@ -41,6 +41,5 @@ spdif: spdif@0x1011e000 { dma-names = "tx"; clock-names = "hclk", "mclk"; clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>; - status = "disabled"; #sound-dai-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/sound/rt274.txt b/Documentation/devicetree/bindings/sound/rt274.txt new file mode 100644 index 0000000000000000000000000000000000000000..e9a6178c78cfe09c56a303495ec4d207ed53b11b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt274.txt @@ -0,0 +1,33 @@ +RT274 audio CODEC + +This device supports I2C only. + +Required properties: + +- compatible : "realtek,rt274". + +- reg : The I2C address of the device. + +Optional properties: + +- interrupts : The CODEC's interrupt output. + + +Pins on the device (for linking into audio routes) for RT274: + + * DMIC1 Pin + * DMIC2 Pin + * MIC + * LINE1 + * LINE2 + * HPO Pin + * SPDIF + * LINE3 + +Example: + +codec: rt274@1c { + compatible = "realtek,rt274"; + reg = <0x1c>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; +}; diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt index 70eaeaed2b18c70675ad87cb9a2dfc397aad6916..ff381718c51755b5d3cb06ac7c0e3ae1a1c85f48 100644 --- a/Documentation/devicetree/bindings/sound/rt5663.txt +++ b/Documentation/devicetree/bindings/sound/rt5663.txt @@ -12,6 +12,14 @@ Required properties: Optional properties: +- "realtek,dc_offset_l_manual" +- "realtek,dc_offset_r_manual" +- "realtek,dc_offset_l_manual_mic" +- "realtek,dc_offset_r_manual_mic" + Based on the different PCB layout, add the manual offset value to + compensate the DC offset for each L and R channel, and they are different + between headphone and headset. + Pins on the device (for linking into audio routes) for RT5663: * IN1P diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.txt b/Documentation/devicetree/bindings/sound/samsung,odroid.txt index c30934dd975bd0bc4090370311bcbc49566c0a39..625b1b18fd027b110f9bcef0ddae383c5e710925 100644 --- a/Documentation/devicetree/bindings/sound/samsung,odroid.txt +++ b/Documentation/devicetree/bindings/sound/samsung,odroid.txt @@ -7,9 +7,6 @@ Required properties: - model - the user-visible name of this sound complex - clocks - should contain entries matching clock names in the clock-names property - - clock-names - should contain following entries: - - "epll" - indicating the EPLL output clock - - "i2s_rclk" - indicating the RCLK (root) clock of the I2S0 controller - samsung,audio-widgets - this property specifies off-codec audio elements like headphones or speakers, for details see widgets.txt - samsung,audio-routing - a list of the connections between audio @@ -46,9 +43,6 @@ sound { "IN1", "Mic Jack", "Mic Jack", "MICBIAS"; - clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>; - clock-names = "epll", "sclk_i2s"; - cpu { sound-dai = <&i2s0 0>; }; diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index c7a93931fad27c7d88069925ae5125434f3e8f74..166f2290233b2f55f11dabe42ea9362e0697e30d 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -86,6 +86,9 @@ Optional CPU/CODEC subnodes properties: in dai startup() and disabled with clk_disable_unprepare() in dai shutdown(). +- system-clock-direction-out : specifies clock direction as 'out' on + initialization. It is useful for some aCPUs with + fixed clocks. Example 1 - single DAI link: diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt index 327d229a51b27e126fad58678a75dd2c803fed54..32f8dbce5241d4a9ad612c7c47e0890fc3438625 100644 --- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt @@ -24,6 +24,7 @@ Optional subnode properties: - simple-audio-card,convert-rate : platform specified sampling rate convert - simple-audio-card,convert-channels : platform specified converted channel size (2 - 8 ch) - simple-audio-card,prefix : see routing +- simple-audio-card,widgets : Please refer to widgets.txt. - simple-audio-card,routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, the second being the connection's source. Valid names for sources. diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt index 745dc62f76ea320c5c192d3e9e6c40ef9743abda..40068ec0e9a561db3128fe37d581b1a4499b5ddf 100644 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt @@ -53,7 +53,6 @@ Example: sti_uni_player1: sti-uni-player@0x8D81000 { compatible = "st,stih407-uni-player-hdmi"; - status = "okay"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_PCM_1>; @@ -66,7 +65,6 @@ Example: sti_uni_player2: sti-uni-player@0x8D82000 { compatible = "st,stih407-uni-player-pcm-out"; - status = "okay"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_PCM_2>; @@ -78,7 +76,6 @@ Example: sti_uni_player3: sti-uni-player@0x8D85000 { compatible = "st,stih407-uni-player-spdif"; - status = "okay"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_SPDIFF>; @@ -90,7 +87,6 @@ Example: sti_uni_reader1: sti-uni-reader@0x8D84000 { compatible = "st,stih407-uni-reader-hdmi"; - status = "disabled"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; reg = <0x8D84000 0x158>; @@ -125,7 +121,6 @@ Example of audio card declaration: sound { compatible = "simple-audio-card"; simple-audio-card,name = "sti audio card"; - status = "okay"; simple-audio-card,dai-link@0 { /* DAC */ diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt index ee21da865771f303c9b21a288b5b1a293662aac7..fc5da6080759d26e0d65fc0c576f128c0bc70dfc 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt @@ -8,6 +8,7 @@ Required properties: - compatible: should be one of the following: - "allwinner,sun4i-a10-i2s" - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the I2S interrupt. @@ -22,6 +23,7 @@ Required properties: Required properties for the following compatibles: - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - resets: phandle to the reset line for this codec Example: diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt index fe0a65e6d629d407e6413054a8f7ac8e5dd6f026..70ee177901d3044ee1c4434f41c892d5db60ff9b 100644 --- a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt +++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt @@ -39,5 +39,4 @@ spdif: spdif@01c21000 { clock-names = "apb", "spdif"; dmas = <&dma 0 2>, <&dma 0 2>; dma-names = "rx", "tx"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/tas5720.txt b/Documentation/devicetree/bindings/sound/tas5720.txt index 806ea7381483b259748806a5cc275536d60cb9bd..40d94f82beb364c1056e75d9f8e089368f63951a 100644 --- a/Documentation/devicetree/bindings/sound/tas5720.txt +++ b/Documentation/devicetree/bindings/sound/tas5720.txt @@ -17,7 +17,6 @@ Required properties: Example: tas5720: tas5720@6c { - status = "okay"; compatible = "ti,tas5720"; reg = <0x6c>; dvdd-supply = <&vdd_3v3_reg>; diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt index 5e2741af27be5f1b07dc775b35db88cdfe57522c..ca75890f0d0722b68a581eb660f1ddd3acf69f0c 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -3,7 +3,9 @@ Texas Instruments - tlv320aic32x4 Codec module The tlv320aic32x4 serial control bus communicates through I2C protocols Required properties: - - compatible: Should be "ti,tlv320aic32x4" + - compatible - "string" - One of: + "ti,tlv320aic32x4" TLV320AIC3204 + "ti,tlv320aic32x6" TLV320AIC3206, TLV320AIC3256 - reg: I2C slave address - supply-*: Required supply regulators are: "iov" - digital IO power supply @@ -18,6 +20,8 @@ Optional properties: - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt - clocks/clock-names: Clock named 'mclk' for the master clock of the codec. See clock/clock-bindings.txt for information about the detailed format. + - aic32x4-gpio-func - + - Types are defined in include/sound/tlv320aic32x4.h Example: @@ -27,4 +31,11 @@ codec: tlv320aic32x4@18 { reg = <0x18>; clocks = <&clks 201>; clock-names = "mclk"; + aic32x4-gpio-func= < + 0xff /* AIC32X4_MFPX_DEFAULT_VALUE */ + 0xff /* AIC32X4_MFPX_DEFAULT_VALUE */ + 0x04 /* MFP3 AIC32X4_MFP3_GPIO_ENABLED */ + 0xff /* AIC32X4_MFPX_DEFAULT_VALUE */ + 0x08 /* MFP5 AIC32X4_MFP5_GPIO_INPUT */ + >; }; diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index 47a213c411ce922321e692ecca849390cbcd53e8..ba5b45c483f5da6c3b1ced1d3d43416fc0f1851e 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt @@ -26,6 +26,11 @@ Optional properties: 3 - MICBIAS output is connected to AVDD, If this node is not mentioned or if the value is incorrect, then MicBias is powered down. +- ai3x-ocmv - Output Common-Mode Voltage selection: + 0 - 1.35V, + 1 - 1.5V, + 2 - 1.65V, + 3 - 1.8V - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the device as covered in Documentation/devicetree/bindings/regulator/regulator.txt diff --git a/Documentation/devicetree/bindings/sound/wm8524.txt b/Documentation/devicetree/bindings/sound/wm8524.txt new file mode 100644 index 0000000000000000000000000000000000000000..20c62002cbcd45e3b200de1a44a0c515a96db6d4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8524.txt @@ -0,0 +1,16 @@ +WM8524 audio CODEC + +This device does not use I2C or SPI but a simple Hardware Control Interface. + +Required properties: + + - compatible : "wlf,wm8524" + + - wlf,mute-gpios: a GPIO spec for the MUTE pin. + +Example: + +codec: wm8524@0 { + compatible = "wlf,wm8524"; + wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; +}; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt index 292ad5083704b18cc7a982bf27430e52752f2553..3927251464f0619da76a6c43f2f24e978cf97d06 100644 --- a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt +++ b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt @@ -27,7 +27,6 @@ Example: interrupts = ; dmas = <&dma 5>, <&dma 6>; dma-names = "tx", "rx"; - status = "okay"; }; sound { diff --git a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt index 989544ea6eb5d80aa58e8bcc318f4b9236aa1be9..b5a5ca4502f9d4251414a978a1119e496929d99a 100644 --- a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt +++ b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt @@ -24,5 +24,4 @@ Example: interrupts = ; dmas = <&dma 4>; dma-names = "tx"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/spi/efm32-spi.txt b/Documentation/devicetree/bindings/spi/efm32-spi.txt index 750e29aff9bc529ba721a3c842fd85ec37e1e132..2c1e6a43930baa88426aa4822f6ec79ee8bbc10e 100644 --- a/Documentation/devicetree/bindings/spi/efm32-spi.txt +++ b/Documentation/devicetree/bindings/spi/efm32-spi.txt @@ -28,7 +28,6 @@ spi1: spi@0x4000c400 { /* USART1 */ clocks = <&cmu 20>; cs-gpios = <&gpio 51 1>; // D3 energymicro,location = <1>; - status = "ok"; ks8851@0 { compatible = "ks8851"; @@ -36,6 +35,5 @@ spi1: spi@0x4000c400 { /* USART1 */ reg = <0>; interrupt-parent = <&boardfpga>; interrupts = <4>; - status = "ok"; }; }; diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index 31b5b21598ff5755d3e12a50aac2abf51d6653f1..5bf13960f7f4a3c826c10b1e15a618df82d82403 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -9,6 +9,7 @@ Required properties: - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31 - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35 - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 + - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt - cs-gpios : Specifies the gpio pins to be used for chipselects. diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt index b785976fe98aff57a91f3c8f2d08a62dd2a606de..9ba7c5a273b4f39cfb912ff9df50e41d317f4677 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt @@ -38,5 +38,4 @@ spi@7000d600 { reset-names = "spi"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt index bdf08e6dec9bdf325fe9a992c2dfd611dbd46a92..c212491929b5b84832d7ddc06db6c1a9113fae69 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt @@ -34,5 +34,4 @@ spi@7000c380 { reset-names = "spi"; dmas = <&apbdma 11>, <&apbdma 11>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt index 5db9144a33c8beee16993c5f79100b59e8de669b..40d80b93e32799ee0a3cb14a206ec3232f1973f3 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt @@ -34,5 +34,4 @@ spi@7000d600 { reset-names = "spi"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/sh-hspi.txt b/Documentation/devicetree/bindings/spi/sh-hspi.txt index 319bad4af875862c9d1e862403500206817ce743..585fed90376ecc1ca243f57aedde6aa78af04f94 100644 --- a/Documentation/devicetree/bindings/spi/sh-hspi.txt +++ b/Documentation/devicetree/bindings/spi/sh-hspi.txt @@ -24,6 +24,5 @@ Example: interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index 64ee489571c42f88a13decf8e0a1679f635f636c..e865855726a2b973a201ab1c3babc4df70451007 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -6,6 +6,7 @@ Required properties: "renesas,msiof-r8a7792" (R-Car V2H) "renesas,msiof-r8a7793" (R-Car M2-N) "renesas,msiof-r8a7794" (R-Car E2) + "renesas,msiof-r8a7795" (R-Car H3) "renesas,msiof-r8a7796" (R-Car M3-W) "renesas,msiof-sh73a0" (SH-Mobile AG5) "renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device) @@ -78,5 +79,4 @@ Example: dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/spi-clps711x.txt b/Documentation/devicetree/bindings/spi/spi-clps711x.txt index 4c3ec13f423fdbd9b2a12fb328d9c8b15b2ecaae..5122dc7860af595a0e9393a22c320aef4b0c4be7 100644 --- a/Documentation/devicetree/bindings/spi/spi-clps711x.txt +++ b/Documentation/devicetree/bindings/spi/spi-clps711x.txt @@ -23,7 +23,6 @@ spi@80000500 { reg = <0x80000500 0x4>; interrupts = <15>; clocks = <&clks CLPS711X_CLK_SPI>; - status = "disabled"; }; syscon3: syscon@80002200 { diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index ff5893d275a2132e63f5f824f9a074d18e904865..13b1fcc8469e699412282d92c59c59328916dff8 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt @@ -39,7 +39,6 @@ dspi0@4002c000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dspi0_1>; big-endian; - status = "okay"; sflash: at26df081a@0 { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index e0318cf92d731c377a9be9dfc950dea4852f3a5e..236dcb0faf376238d9fe4452c5bcb5f686b87e37 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -57,5 +57,4 @@ spi: spi@1100a000 { clock-names = "parent-clk", "sel-clk", "spi-clk"; cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>; mediatek,pad-select = <1>, <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index 4f629cc7634a910757bc41d3d21740d6fe163909..df8ec31f2f076ae4dafe29950797bd5f2fe68526 100644 --- a/Documentation/devicetree/bindings/spi/spi-orion.txt +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt @@ -29,7 +29,6 @@ Example: cell-index = <0>; reg = <0x10600 0x28>; interrupts = <23>; - status = "disabled"; }; Example with SPI direct mode support (optionally): @@ -48,7 +47,6 @@ Example with SPI direct mode support (optionally): , /* CS6 */ ; /* CS7 */ interrupts = <23>; - status = "disabled"; }; To enable the direct mode, the board specific 'ranges' property in the diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt b/Documentation/devicetree/bindings/spi/spi-rockchip.txt index 83da4931d832688f51e19a56aaa03af8482e721a..6e3ffacbba320a756933255fe8100c0103e01cc6 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt @@ -6,6 +6,7 @@ and display controllers using the SPI communication interface. Required Properties: - compatible: should be one of the following. + "rockchip,rv1108-spi" for rv1108 SoCs. "rockchip,rk3036-spi" for rk3036 SoCS. "rockchip,rk3066-spi" for rk3066 SoCs. "rockchip,rk3188-spi" for rk3188 SoCs. diff --git a/Documentation/devicetree/bindings/spi/spi-sun4i.txt b/Documentation/devicetree/bindings/spi/spi-sun4i.txt index de827f5a301e49133df378e55e685f3d44eec9f9..484bbff5337e17a9d5976b3984734619e0f75296 100644 --- a/Documentation/devicetree/bindings/spi/spi-sun4i.txt +++ b/Documentation/devicetree/bindings/spi/spi-sun4i.txt @@ -18,7 +18,6 @@ spi1: spi@01c06000 { interrupts = <11>; clocks = <&ahb_gates 21>, <&spi1_clk>; clock-names = "ahb", "mod"; - status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/spi/spi-sun6i.txt b/Documentation/devicetree/bindings/spi/spi-sun6i.txt index 2ec99b86b62297ab9793e143e137982ca6b3c11d..ab1811354cce2ef8b1436d40cf7362423e9b2c7f 100644 --- a/Documentation/devicetree/bindings/spi/spi-sun6i.txt +++ b/Documentation/devicetree/bindings/spi/spi-sun6i.txt @@ -39,7 +39,6 @@ spi0: spi@01c68000 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; resets = <&ccu RST_BUS_SPI0>; - status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/spi/spi_atmel.txt b/Documentation/devicetree/bindings/spi/spi_atmel.txt index fb588b3e6a9a3de0bbe9223beef95372a18c7567..f99c733d75c12b6d393eb8b48f66c2cbdeaba56b 100644 --- a/Documentation/devicetree/bindings/spi/spi_atmel.txt +++ b/Documentation/devicetree/bindings/spi/spi_atmel.txt @@ -26,7 +26,6 @@ spi1: spi@fffcc000 { clock-names = "spi_clk"; cs-gpios = <&pioB 3 0>; atmel,fifo-size = <32>; - status = "okay"; mmc-slot@0 { compatible = "mmc-spi-slot"; diff --git a/Documentation/devicetree/bindings/sram/renesas,smp-sram.txt b/Documentation/devicetree/bindings/sram/renesas,smp-sram.txt new file mode 100644 index 0000000000000000000000000000000000000000..712d05e3e15eeb65faaed7de21f6533ab6bcbb47 --- /dev/null +++ b/Documentation/devicetree/bindings/sram/renesas,smp-sram.txt @@ -0,0 +1,27 @@ +* Renesas SMP SRAM + +Renesas R-Car Gen2 and RZ/G1 SoCs need a small piece of SRAM for the jump stub +for secondary CPU bringup and CPU hotplug. +This memory is reserved by adding a child node to a "mmio-sram" node, cfr. +Documentation/devicetree/bindings/sram/sram.txt. + +Required child node properties: + - compatible: Must be "renesas,smp-sram", + - reg: Address and length of the reserved SRAM. + The full physical (bus) address must be aligned to a 256 KiB boundary. + + +Example: + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; diff --git a/Documentation/devicetree/bindings/sram/sunxi-sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt index 8d5665468fe7e6919d3bf4f3e646e0ae571eeb5d..6bb92a1df753e5ae7b74f17b435a511210acbe19 100644 --- a/Documentation/devicetree/bindings/sram/sunxi-sram.txt +++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt @@ -9,7 +9,9 @@ Controller Node --------------- Required properties: -- compatible : "allwinner,sun4i-a10-sram-controller" +- compatible : should be: + - "allwinner,sun4i-a10-sram-controller" + - "allwinner,sun50i-a64-sram-controller" - reg : sram controller register offset + length SRAM nodes @@ -22,10 +24,13 @@ Each SRAM will have SRAM sections that are going to be handled by the SRAM controller as subnodes. These sections are represented following once again the representation described in the mmio-sram binding. -The valid sections compatible are: +The valid sections compatible for A10 are: - allwinner,sun4i-a10-sram-a3-a4 - allwinner,sun4i-a10-sram-d +The valid sections compatible for A64 are: + - allwinner,sun50i-a64-sram-c + Devices using SRAM sections --------------------------- @@ -59,7 +64,6 @@ sram-controller@01c00000 { emac_sram: sram-section@8000 { compatible = "allwinner,sun4i-a10-sram-a3-a4"; reg = <0x8000 0x4000>; - status = "disabled"; }; }; }; diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt index 4698e0edc205d92491ecbd00b56c1281db7ae05b..24aacf8948c51626a22d844ddd95f752da4206f3 100644 --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt @@ -20,5 +20,4 @@ Example: compatible = "marvell,armada370-thermal"; reg = <0xd0018300 0x4 0xd0018304 0x4>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt index 70b4c16c7ed8374098557aee923375e0e94714c1..9b4c7b017495bbf056f8d787b0726110789af5e6 100644 --- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt @@ -77,7 +77,6 @@ Example 1): interrupts = <2 4>; clocks = <&clock 383>; clock-names = "tmu_apbif"; - status = "disabled"; vtmu-supply = <&tmu_regulator_node>; #include "exynos4412-tmu-sensor-conf.dtsi" }; diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt index e2f494d74d8a3fba16c328a3237fd4621ba3caf0..0d73ea5e9c0c41da00f34d98fcb86ea5d27e200b 100644 --- a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt @@ -11,6 +11,7 @@ Required properties: - compatible: - "mediatek,mt8173-thermal" : For MT8173 family of SoCs - "mediatek,mt2701-thermal" : For MT2701 family of SoCs + - "mediatek,mt2712-thermal" : For MT2712 family of SoCs - reg: Address range of the thermal controller - interrupts: IRQ for the thermal controller - clocks, clock-names: Clocks needed for the thermal controller. required diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt index 07a9713ae6a75757f43139a9a4b75c22c95f7304..fdf5caa6229b4fffe95853e061e9c62c83307364 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt @@ -36,7 +36,6 @@ Example: clocks = <&cpg CPG_MOD 522>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; #thermal-sensor-cells = <1>; - status = "okay"; }; thermal-zones { diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt index 43003aec94bd15ccadc2faf3d57e3be6088c9fba..e3a6234fb1acdbf3efdbf61c233c5151a98adc4f 100644 --- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt @@ -4,6 +4,7 @@ Required properties: - compatible : should be "rockchip,-tsadc" "rockchip,rk3228-tsadc": found on RK3228 SoCs "rockchip,rk3288-tsadc": found on RK3288 SoCs + "rockchip,rk3328-tsadc": found on RK3328 SoCs "rockchip,rk3368-tsadc": found on RK3368 SoCs "rockchip,rk3399-tsadc": found on RK3399 SoCs - reg : physical base address of the controller and length of memory mapped diff --git a/Documentation/devicetree/bindings/thermal/uniphier-thermal.txt b/Documentation/devicetree/bindings/thermal/uniphier-thermal.txt new file mode 100644 index 0000000000000000000000000000000000000000..686c0b42ed3f6c7debe89e2a25d129226bd262b8 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/uniphier-thermal.txt @@ -0,0 +1,64 @@ +* UniPhier Thermal bindings + +This describes the devicetree bindings for thermal monitor supported by +PVT(Process, Voltage and Temperature) monitoring unit implemented on Socionext +UniPhier SoCs. + +Required properties: +- compatible : + - "socionext,uniphier-pxs2-thermal" : For UniPhier PXs2 SoC + - "socionext,uniphier-ld20-thermal" : For UniPhier LD20 SoC +- interrupts : IRQ for the temperature alarm +- #thermal-sensor-cells : Should be 0. See ./thermal.txt for details. + +Optional properties: +- socionext,tmod-calibration: A pair of calibrated values referred from PVT, + in case that the values aren't set on SoC, + like a reference board. + +Example: + + sysctrl@61840000 { + compatible = "socionext,uniphier-ld20-sysctrl", + "simple-mfd", "syscon"; + reg = <0x61840000 0x10000>; + ... + pvtctl: pvtctl { + compatible = "socionext,uniphier-ld20-thermal"; + interrupts = <0 3 1>; + #thermal-sensor-cells = <0>; + }; + ... + }; + + thermal-zones { + cpu_thermal { + polling-delay-passive = <250>; /* 250ms */ + polling-delay = <1000>; /* 1000ms */ + thermal-sensors = <&pvtctl>; + + trips { + cpu_crit: cpu_crit { + temperature = <110000>; /* 110C */ + hysteresis = <2000>; + type = "critical"; + }; + cpu_alert: cpu_alert { + temperature = <100000>; /* 100C */ + hysteresis = <2000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = <&cpu0 (-1) (-1)>; + }; + map1 { + trip = <&cpu_alert>; + cooling-device = <&cpu2 (-1) (-1)>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt b/Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt new file mode 100644 index 0000000000000000000000000000000000000000..b4aa7ddb5b134d9b8accdf625c18807ec4f13928 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt @@ -0,0 +1,28 @@ +NXP Low Power Timer/Pulse Width Modulation Module (TPM) + +The Timer/PWM Module (TPM) supports input capture, output compare, +and the generation of PWM signals to control electric motor and power +management applications. The counter, compare and capture registers +are clocked by an asynchronous clock that can remain enabled in low +power modes. TPM can support global counter bus where one TPM drives +the counter bus for the others, provided bit width is the same. + +Required properties: + +- compatible : should be "fsl,imx7ulp-tpm" +- reg : Specifies base physical address and size of the register sets + for the clock event device and clock source device. +- interrupts : Should be the clock event device interrupt. +- clocks : The clocks provided by the SoC to drive the timer, must contain + an entry for each entry in clock-names. +- clock-names : Must include the following entries: "igp" and "per". + +Example: +tpm5: tpm@40260000 { + compatible = "fsl,imx7ulp-tpm"; + reg = <0x40260000 0x1000>; + interrupts = ; + clocks = <&clks IMX7ULP_CLK_NIC1_BUS_DIV>, + <&clks IMX7ULP_CLK_LPTPM5>; + clock-names = "ipg", "per"; +}; diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt index 1a05c1b243c1d04834b56e591deb763ffdc52b58..6ca6b9e582a0e803ee85ef15972448a5be2cfda5 100644 --- a/Documentation/devicetree/bindings/timer/renesas,cmt.txt +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt @@ -12,46 +12,29 @@ datasheets. Required Properties: - compatible: must contain one or more of the following: - - "renesas,cmt-32-r8a7740" for the r8a7740 32-bit CMT - (CMT0) - - "renesas,cmt-32-sh7372" for the sh7372 32-bit CMT - (CMT0) - - "renesas,cmt-32-sh73a0" for the sh73a0 32-bit CMT - (CMT0) - - "renesas,cmt-32" for all 32-bit CMT without fast clock support - (CMT0 on sh7372, sh73a0 and r8a7740) - This is a fallback for the above renesas,cmt-32-* entries. - - - "renesas,cmt-32-fast-r8a7740" for the r8a7740 32-bit CMT with fast - clock support (CMT[234]) - - "renesas,cmt-32-fast-sh7372" for the sh7372 32-bit CMT with fast - clock support (CMT[234]) - - "renesas,cmt-32-fast-sh73a0" for the sh73A0 32-bit CMT with fast - clock support (CMT[234]) - - "renesas,cmt-32-fast" for all 32-bit CMT with fast clock support - (CMT[234] on sh7372, sh73a0 and r8a7740) - This is a fallback for the above renesas,cmt-32-fast-* entries. - - - "renesas,cmt-48-sh7372" for the sh7372 48-bit CMT - (CMT1) - "renesas,cmt-48-sh73a0" for the sh73A0 48-bit CMT (CMT1) - "renesas,cmt-48-r8a7740" for the r8a7740 48-bit CMT (CMT1) - "renesas,cmt-48" for all non-second generation 48-bit CMT - (CMT1 on sh7372, sh73a0 and r8a7740) + (CMT1 on sh73a0 and r8a7740) This is a fallback for the above renesas,cmt-48-* entries. - - "renesas,cmt-48-r8a73a4" for the r8a73a4 48-bit CMT - (CMT[01]) - - "renesas,cmt-48-r8a7790" for the r8a7790 48-bit CMT - (CMT[01]) - - "renesas,cmt-48-r8a7791" for the r8a7791 48-bit CMT - (CMT[01]) - - "renesas,cmt-48-gen2" for all second generation 48-bit CMT - (CMT[01] on r8a73a4, r8a7790 and r8a7791) - This is a fallback for the renesas,cmt-48-r8a73a4, - renesas,cmt-48-r8a7790 and renesas,cmt-48-r8a7791 entries. + - "renesas,cmt0-r8a73a4" for the 32-bit CMT0 device included in r8a73a4. + - "renesas,cmt1-r8a73a4" for the 48-bit CMT1 device included in r8a73a4. + - "renesas,cmt0-r8a7790" for the 32-bit CMT0 device included in r8a7790. + - "renesas,cmt1-r8a7790" for the 48-bit CMT1 device included in r8a7790. + - "renesas,cmt0-r8a7791" for the 32-bit CMT0 device included in r8a7791. + - "renesas,cmt1-r8a7791" for the 48-bit CMT1 device included in r8a7791. + - "renesas,cmt0-r8a7793" for the 32-bit CMT0 device included in r8a7793. + - "renesas,cmt1-r8a7793" for the 48-bit CMT1 device included in r8a7793. + - "renesas,cmt0-r8a7794" for the 32-bit CMT0 device included in r8a7794. + - "renesas,cmt1-r8a7794" for the 48-bit CMT1 device included in r8a7794. + + - "renesas,rcar-gen2-cmt0" for 32-bit CMT0 devices included in R-Car Gen2. + - "renesas,rcar-gen2-cmt1" for 48-bit CMT1 devices included in R-Car Gen2. + These are fallbacks for r8a73a4 and all the R-Car Gen2 + entries listed above. - reg: base address and length of the registers block for the timer module. - interrupts: interrupt-specifier for the timer, one per channel. @@ -59,21 +42,29 @@ Required Properties: in clock-names. - clock-names: must contain "fck" for the functional clock. - - renesas,channels-mask: bitmask of the available channels. - -Example: R8A7790 (R-Car H2) CMT0 node - - CMT0 on R8A7790 implements hardware channels 5 and 6 only and names - them channels 0 and 1 in the documentation. +Example: R8A7790 (R-Car H2) CMT0 and CMT1 nodes cmt0: timer@ffca0000 { - compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; + compatible = "renesas,cmt0-r8a7790", "renesas,rcar-gen2-cmt0"; reg = <0 0xffca0000 0 0x1004>; interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, <0 142 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp1_clks R8A7790_CLK_CMT0>; clock-names = "fck"; + }; - renesas,channels-mask = <0x60>; + cmt1: timer@e6130000 { + compatible = "renesas,cmt1-r8a7790", "renesas,rcar-gen2-cmt1"; + reg = <0 0xe6130000 0 0x1004>; + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, + <0 121 IRQ_TYPE_LEVEL_HIGH>, + <0 122 IRQ_TYPE_LEVEL_HIGH>, + <0 123 IRQ_TYPE_LEVEL_HIGH>, + <0 124 IRQ_TYPE_LEVEL_HIGH>, + <0 125 IRQ_TYPE_LEVEL_HIGH>, + <0 126 IRQ_TYPE_LEVEL_HIGH>, + <0 127 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_CMT1>; + clock-names = "fck"; }; diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt index 35f406dd86b6c191a9dd21cf7e1c3b5091d01dd4..af284fbd4d238e4ce5b77e5d55c989c99366c8b0 100644 --- a/Documentation/devicetree/bindings/trivial-devices.txt +++ b/Documentation/devicetree/bindings/trivial-devices.txt @@ -21,6 +21,16 @@ adi,adt7490 +/-1C TDM Extended Temp Range I.C adi,adxl345 Three-Axis Digital Accelerometer adi,adxl346 Three-Axis Digital Accelerometer (backward-compatibility value "adi,adxl345" must be listed too) ams,iaq-core AMS iAQ-Core VOC Sensor +amstaos,tsl2571 AMS/TAOS ALS and proximity sensor +amstaos,tsl2671 AMS/TAOS ALS and proximity sensor +amstaos,tmd2671 AMS/TAOS ALS and proximity sensor +amstaos,tsl2771 AMS/TAOS ALS and proximity sensor +amstaos,tmd2771 AMS/TAOS ALS and proximity sensor +amstaos,tsl2572 AMS/TAOS ALS and proximity sensor +amstaos,tsl2672 AMS/TAOS ALS and proximity sensor +amstaos,tmd2672 AMS/TAOS ALS and proximity sensor +amstaos,tsl2772 AMS/TAOS ALS and proximity sensor +amstaos,tmd2772 AMS/TAOS ALS and proximity sensor at,24c08 i2c serial eeprom (24cxx) atmel,at97sc3204t i2c trusted platform module (TPM) capella,cm32181 CM32181: Ambient Light Sensor @@ -36,7 +46,9 @@ dallas,ds1775 Tiny Digital Thermometer and Thermostat dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O dallas,ds75 Digital Thermometer and Thermostat +devantech,srf02 Devantech SRF02 ultrasonic ranger in I2C mode devantech,srf08 Devantech SRF08 ultrasonic ranger +devantech,srf10 Devantech SRF10 ultrasonic ranger dlg,da9053 DA9053: flexible system level PMIC with multicore support dlg,da9063 DA9063: system PMIC for quad-core application processors domintech,dmard09 DMARD09: 3-axis Accelerometer @@ -54,6 +66,7 @@ fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) +isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator @@ -168,6 +181,7 @@ st,m41t80 M41T80 - SERIAL ACCESS RTC WITH ALARMS taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface ti,ads7828 8-Channels, 12-bit ADC ti,ads7830 8-Channels, 8-bit ADC +ti,amc6821 Temperature Monitoring and Fan Control ti,tsc2003 I2C Touch-Screen Controller ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface ti,tmp103 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface diff --git a/Documentation/devicetree/bindings/unittest.txt b/Documentation/devicetree/bindings/unittest.txt index 3bf58c20fe94da71ecae272e7d86256bd42f0683..9a5b311f44342079d73ab7b5a4881d2d8c706c59 100644 --- a/Documentation/devicetree/bindings/unittest.txt +++ b/Documentation/devicetree/bindings/unittest.txt @@ -10,7 +10,6 @@ All other properties are optional. Example: unittest { compatible = "unittest"; - status = "okay"; }; 2) OF unittest i2c adapter platform device @@ -25,7 +24,6 @@ Children nodes contain unittest i2c devices. Example: unittest-i2c-bus { compatible = "unittest-i2c-bus"; - status = "okay"; }; 3) OF unittest i2c device @@ -40,7 +38,6 @@ All other properties are optional Example: unittest-i2c-dev { compatible = "unittest-i2c-dev"; - status = "okay"; }; 4) OF unittest i2c mux device @@ -55,7 +52,6 @@ Children nodes contain unittest i2c bus nodes per channel. Example: unittest-i2c-mux { compatible = "unittest-i2c-mux"; - status = "okay"; #address-cells = <1>; #size-cells = <0>; channel-0 { @@ -65,7 +61,6 @@ Example: i2c-dev { reg = <8>; compatible = "unittest-i2c-dev"; - status = "okay"; }; }; }; diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt index d9b42da016f3a209d76444ca764ec6d22ed08b7d..cb2bd83fa89aa9db0a9a8fac774fe8f8656f2efb 100644 --- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt +++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt @@ -25,5 +25,4 @@ Example: phys = <&usbphy 0>; phy-names = "usb"; extcon = <&usbphy 0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/usb/am33xx-usb.txt b/Documentation/devicetree/bindings/usb/am33xx-usb.txt index 20c2ff2ba07ebd3f8e7d4e2b438b69373cacfbba..16920d78e1b8b9d350189434a46d19037aca19e5 100644 --- a/Documentation/devicetree/bindings/usb/am33xx-usb.txt +++ b/Documentation/devicetree/bindings/usb/am33xx-usb.txt @@ -4,9 +4,9 @@ - reg: offset and length of the usbss register sets - ti,hwmods : must be "usb_otg_hs" -The glue layer contains multiple child nodes. It is required the have +The glue layer contains multiple child nodes. It is required to have at least a control module node, USB node and a PHY node. The second USB -node and its PHY node is optional. The DMA node is also optional. +node and its PHY node are optional. The DMA node is also optional. Reset module ~~~~~~~~~~~~ diff --git a/Documentation/devicetree/bindings/usb/brcm,bdc.txt b/Documentation/devicetree/bindings/usb/brcm,bdc.txt new file mode 100644 index 0000000000000000000000000000000000000000..63e63af3bf593926fb908861aad2718f43a77e16 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/brcm,bdc.txt @@ -0,0 +1,29 @@ +Broadcom USB Device Controller (BDC) +==================================== + +Required properties: + +- compatible: must be one of: + "brcm,bdc-v0.16" + "brcm,bdc" +- reg: the base register address and length +- interrupts: the interrupt line for this controller + +Optional properties: + +On Broadcom STB platforms, these properties are required: + +- phys: phandle to one or two USB PHY blocks + NOTE: Some SoC's have a single phy and some have + USB 2.0 and USB 3.0 phys +- clocks: phandle to the functional clock of this block + +Example: + + bdc@f0b02000 { + compatible = "brcm,bdc-v0.16"; + reg = <0xf0b02000 0xfc4>; + interrupts = <0x0 0x60 0x0>; + phys = <&usbphy_0 0x0>; + clocks = <&sw_usbd>; + }; diff --git a/Documentation/devicetree/bindings/usb/da8xx-usb.txt b/Documentation/devicetree/bindings/usb/da8xx-usb.txt index 717c5f6562373decc6eb91e7963d445b59739f59..9ce22551b2b3ea2aa7dff3d0819093114dc421a3 100644 --- a/Documentation/devicetree/bindings/usb/da8xx-usb.txt +++ b/Documentation/devicetree/bindings/usb/da8xx-usb.txt @@ -42,7 +42,6 @@ Example: usb_phy: usb-phy { compatible = "ti,da830-usb-phy"; #phy-cells = <0>; - status = "okay"; }; usb0: usb@200000 { compatible = "ti,da830-musb"; @@ -66,7 +65,6 @@ Example: "rx1", "rx2", "rx3", "rx4", "tx1", "tx2", "tx3", "tx4"; - status = "okay"; cppi41dma: dma-controller@201000 { compatible = "ti,da830-cppi41"; diff --git a/Documentation/devicetree/bindings/usb/dwc3-st.txt b/Documentation/devicetree/bindings/usb/dwc3-st.txt index 50dee3b44665e6495dff51ea4e1c9fd45cbcb7ac..df0e02e1ee43e7b8bf88486d26bea2ed92d8aeef 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-st.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-st.txt @@ -42,7 +42,6 @@ or "device". Example: st_dwc3: dwc3@8f94000 { - status = "disabled"; compatible = "st,stih407-dwc3"; reg = <0x08f94000 0x1000>, <0x110 0x4>; reg-names = "reg-glue", "syscfg-reg"; diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 30361b32a46024ef118a9fe5858eb1eb29288bf6..4aae5b2cef56e65d1d20f0a5a0960f19488a2001 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -18,7 +18,6 @@ Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; - status = "okay"; compatible = "xlnx,zynqmp-dwc3"; clock-names = "bus_clk" "ref_clk"; clocks = <&clk125>, <&clk125>; diff --git a/Documentation/devicetree/bindings/usb/ehci-st.txt b/Documentation/devicetree/bindings/usb/ehci-st.txt index 410d922cfdd713b59eacb8ff0f39950314a55334..9feea6c3e4d998cba087de49f608cba8ce445242 100644 --- a/Documentation/devicetree/bindings/usb/ehci-st.txt +++ b/Documentation/devicetree/bindings/usb/ehci-st.txt @@ -31,7 +31,6 @@ Example: clocks = <&clk_s_a1_ls 0>; phys = <&usb2_phy>; phy-names = "usb"; - status = "okay"; resets = <&powerdown STIH416_USB1_POWERDOWN>, <&softreset STIH416_USB1_SOFTRESET>; diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt index 78ebebb66dada6f088fdf003871542f9c9f71254..c97374315049ae874fd5c9aaa764bb254ca780d2 100644 --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -40,7 +40,6 @@ Example: port@0 { reg = <0>; phys = <&usb2phy 1>; - status = "disabled"; }; }; @@ -75,7 +74,6 @@ Example: port@0 { reg = <0>; phys = <&usb2phy 1>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/usb/fcs,fusb302.txt b/Documentation/devicetree/bindings/usb/fcs,fusb302.txt new file mode 100644 index 0000000000000000000000000000000000000000..472facfa5a719d3018e8425bb6779faeeb2c04f7 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/fcs,fusb302.txt @@ -0,0 +1,29 @@ +Fairchild FUSB302 Type-C Port controllers + +Required properties : +- compatible : "fcs,fusb302" +- reg : I2C slave address +- interrupts : Interrupt specifier + +Optional properties : +- fcs,max-sink-microvolt : Maximum voltage to negotiate when configured as sink +- fcs,max-sink-microamp : Maximum current to negotiate when configured as sink +- fcs,max-sink-microwatt : Maximum power to negotiate when configured as sink + If this is less then max-sink-microvolt * + max-sink-microamp then the configured current will + be clamped. +- fcs,operating-sink-microwatt : + Minimum amount of power accepted from a sink + when negotiating + +Example: + +fusb302: typec-portc@54 { + compatible = "fcs,fusb302"; + reg = <0x54>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + fcs,max-sink-microvolt = <12000000>; + fcs,max-sink-microamp = <3000000>; + fcs,max-sink-microwatt = <36000000>; +}; diff --git a/Documentation/devicetree/bindings/usb/isp1301.txt b/Documentation/devicetree/bindings/usb/isp1301.txt index 5405d99d9aaa92fe752abc9ae2a9b89b080df8fc..ecd607dacba553eb664d10681bac8baae47002ab 100644 --- a/Documentation/devicetree/bindings/usb/isp1301.txt +++ b/Documentation/devicetree/bindings/usb/isp1301.txt @@ -21,5 +21,4 @@ Example: interrupt-parent = <&mic>; interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>; transceiver = <&isp1301>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/usb/keystone-usb.txt b/Documentation/devicetree/bindings/usb/keystone-usb.txt index 60527d335b58557267c77ad4a9297b1922a4ae23..f96e09f784cc0c721dea4cb44dfa68debe27afb1 100644 --- a/Documentation/devicetree/bindings/usb/keystone-usb.txt +++ b/Documentation/devicetree/bindings/usb/keystone-usb.txt @@ -12,8 +12,21 @@ Required properties: MPU. - ranges: allows valid 1:1 translation between child's address space and parent's address space. - - clocks: Clock IDs array as required by the controller. - - clock-names: names of clocks correseponding to IDs in the clock property. + +SoC-specific Required Properties: +The following are mandatory properties for Keystone 2 66AK2HK, 66AK2L and 66AK2E +SoCs only: + +- clocks: Clock ID for USB functional clock. +- clock-names: Must be "usb". + + +The following are mandatory properties for Keystone 2 66AK2G SoCs only: + +- power-domains: Should contain a phandle to a PM domain provider node + and an args specifier containing the USB device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt Sub-nodes: The dwc3 core should be added as subnode to Keystone DWC3 glue. @@ -31,7 +44,6 @@ Example: clock-names = "usb"; interrupts = ; ranges; - status = "disabled"; dwc3@2690000 { compatible = "synopsys,dwc3"; diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt similarity index 85% rename from Documentation/devicetree/bindings/usb/mt8173-xhci.txt rename to Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt index 0acfc8acbea126395986e27a3e3ac6b44312e6a7..5611a2e4ddf0c9c334cd81d06b011a7715593312 100644 --- a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt @@ -11,7 +11,11 @@ into two parts. ------------------------------------------------------------------------ Required properties: - - compatible : should contain "mediatek,mt8173-xhci" + - compatible : should be "mediatek,-xhci", "mediatek,mtk-xhci", + soc-model is the name of SoC, such as mt8173, mt2712 etc, when using + "mediatek,mtk-xhci" compatible string, you need SoC specific ones in + addition, one of: + - "mediatek,mt8173-xhci" - reg : specifies physical base address and size of the registers - reg-names: should be "mac" for xHCI MAC and "ippc" for IP port control - interrupts : interrupt used by the controller @@ -68,10 +72,14 @@ usb30: usb@11270000 { In the case, xhci is added as subnode to mtu3. An example and the DT binding details of mtu3 can be found in: -Documentation/devicetree/bindings/usb/mt8173-mtu3.txt +Documentation/devicetree/bindings/usb/mediatek,mtu3.txt Required properties: - - compatible : should contain "mediatek,mt8173-xhci" + - compatible : should be "mediatek,-xhci", "mediatek,mtk-xhci", + soc-model is the name of SoC, such as mt8173, mt2712 etc, when using + "mediatek,mtk-xhci" compatible string, you need SoC specific ones in + addition, one of: + - "mediatek,mt8173-xhci" - reg : specifies physical base address and size of the registers - reg-names: should be "mac" for xHCI MAC - interrupts : interrupt used by the host controller diff --git a/Documentation/devicetree/bindings/usb/mt8173-mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt similarity index 91% rename from Documentation/devicetree/bindings/usb/mt8173-mtu3.txt rename to Documentation/devicetree/bindings/usb/mediatek,mtu3.txt index 1d7c3bc677f75c43bba01362952bfec648b43e35..49f54767cd214e8d6d4ada2dcd1e133aa6ede4cc 100644 --- a/Documentation/devicetree/bindings/usb/mt8173-mtu3.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt @@ -1,7 +1,11 @@ The device node for Mediatek USB3.0 DRD controller Required properties: - - compatible : should be "mediatek,mt8173-mtu3" + - compatible : should be "mediatek,-mtu3", "mediatek,mtu3", + soc-model is the name of SoC, such as mt8173, mt2712 etc, + when using "mediatek,mtu3" compatible string, you need SoC specific + ones in addition, one of: + - "mediatek,mt8173-mtu3" - reg : specifies physical base address and size of the registers - reg-names: should be "mac" for device IP and "ippc" for IP port control - interrupts : interrupt used by the device IP @@ -44,7 +48,7 @@ Optional properties: Sub-nodes: The xhci should be added as subnode to mtu3 as shown in the following example if host mode is enabled. The DT binding details of xhci can be found in: -Documentation/devicetree/bindings/usb/mt8173-xhci.txt +Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt Example: ssusb: usb@11271000 { @@ -71,7 +75,6 @@ ssusb: usb@11271000 { #address-cells = <2>; #size-cells = <2>; ranges; - status = "disabled"; usb_host: xhci@11270000 { compatible = "mediatek,mt8173-xhci"; @@ -82,6 +85,5 @@ ssusb: usb@11271000 { clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; clock-names = "sys_ck", "ref_ck"; vusb33-supply = <&mt6397_vusb_reg>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/usb/ohci-st.txt b/Documentation/devicetree/bindings/usb/ohci-st.txt index 6d8393748da28a0518a42eef1cd5409fa1c1ac0b..d893ec9131c3bdec4cd71e632b932ffd56dfbc9f 100644 --- a/Documentation/devicetree/bindings/usb/ohci-st.txt +++ b/Documentation/devicetree/bindings/usb/ohci-st.txt @@ -29,7 +29,6 @@ Example: clock-names = "ic", "clk48"; phys = <&usb2_phy>; phy-names = "usb"; - status = "okay"; resets = <&powerdown STIH416_USB0_POWERDOWN>, <&softreset STIH416_USB0_SOFTRESET>; diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt index 73cc0963e823dc2d78f3ec23a4931dcaf1cb0785..bc8a2fa5d2bfddaca308c7d9d6f9bcae7eb98b0f 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt @@ -29,7 +29,6 @@ Example device nodes: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; ss_phy: phy@100f8830 { @@ -39,7 +38,6 @@ Example device nodes: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; usb3_0: usb30@0 { @@ -51,7 +49,6 @@ Example device nodes: ranges; - status = "ok"; dwc3@10000000 { compatible = "snps,dwc3"; diff --git a/Documentation/devicetree/bindings/usb/renesas_usb3.txt b/Documentation/devicetree/bindings/usb/renesas_usb3.txt index 8d52766f07b907b187b27c336c02ba2a9bc6210d..e28025883b79fce3e814a12630f1022956dcaf79 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usb3.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt @@ -3,20 +3,30 @@ Renesas Electronics USB3.0 Peripheral driver Required properties: - compatible: Must contain one of the following: - "renesas,r8a7795-usb3-peri" + - "renesas,r8a7796-usb3-peri" + - "renesas,rcar-gen3-usb3-peri" for a generic R-Car Gen3 compatible + device + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + - reg: Base address and length of the register for the USB3.0 Peripheral - interrupts: Interrupt specifier for the USB3.0 Peripheral - clocks: clock phandle and specifier pair -Example: +Example of R-Car H3 ES1.x: usb3_peri0: usb@ee020000 { - compatible = "renesas,r8a7795-usb3-peri"; + compatible = "renesas,r8a7795-usb3-peri", + "renesas,rcar-gen3-usb3-peri"; reg = <0 0xee020000 0 0x400>; interrupts = ; clocks = <&cpg CPG_MOD 328>; }; usb3_peri1: usb@ee060000 { - compatible = "renesas,r8a7795-usb3-peri"; + compatible = "renesas,r8a7795-usb3-peri", + "renesas,rcar-gen3-usb3-peri"; reg = <0 0xee060000 0 0x400>; interrupts = ; clocks = <&cpg CPG_MOD 327>; diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt index 0536a938e3abe084fb83ab98d584dfeeee10e888..50a31536e975ef915defb7fd35db914f3b0d6cf6 100644 --- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt +++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt @@ -29,13 +29,11 @@ Example device nodes: #address-cells = <2>; #size-cells = <2>; ranges; - status = "disabled"; usbdrd_dwc3_0: dwc3@fe800000 { compatible = "snps,dwc3"; reg = <0x0 0xfe800000 0x0 0x100000>; interrupts = ; dr_mode = "otg"; - status = "disabled"; }; }; @@ -48,12 +46,10 @@ Example device nodes: #address-cells = <2>; #size-cells = <2>; ranges; - status = "disabled"; usbdrd_dwc3_1: dwc3@fe900000 { compatible = "snps,dwc3"; reg = <0x0 0xfe900000 0x0 0x100000>; interrupts = ; dr_mode = "otg"; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/usb/usb-device.txt b/Documentation/devicetree/bindings/usb/usb-device.txt index 1c35e7b665e1f8e9eb64dc6495f029a3d7c3ff64..ce02cebac26afdc80d99600725b3aaec24cb01e9 100644 --- a/Documentation/devicetree/bindings/usb/usb-device.txt +++ b/Documentation/devicetree/bindings/usb/usb-device.txt @@ -2,7 +2,7 @@ Generic USB Device Properties Usually, we only use device tree for hard wired USB device. The reference binding doc is from: -http://www.firmware.org/1275/bindings/usb/usb-1_0.ps +http://www.devicetree.org/open-firmware/bindings/usb/usb-1_0.ps Required properties: - compatible: usbVID,PID. The textual representation of VID, PID shall @@ -16,7 +16,6 @@ Required properties: Example: &usb1 { - status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index daf465bef75898c1b1960d456c82b666c4f9dca6..1afd298eddd73147ebf6a1dcbc56bf404559cff1 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -3,12 +3,13 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. This isn't an exhaustive list, but you should add new prefixes to it before using them to avoid name-space collisions. -abcn Abracon Corporation abilis Abilis Systems +abracon Abracon Corporation actions Actions Semiconductor Co., Ltd. active-semi Active-Semi International Inc ad Avionic Design GmbH adapteva Adapteva, Inc. +adaptrum Adaptrum, Inc. adh AD Holdings Plc. adi Analog Devices, Inc. advantech Advantech Corporation @@ -47,6 +48,7 @@ avic Shanghai AVIC Optoelectronics Co., Ltd. axentia Axentia Technologies AB axis Axis Communications AB bananapi BIPAI KEJI LIMITED +bhf Beckhoff Automation GmbH & Co. KG boe BOE Technology Group Co., Ltd. bosch Bosch Sensortec GmbH boundary Boundary Devices Inc. @@ -88,6 +90,7 @@ dlg Dialog Semiconductor dlink D-Link Corporation dmo Data Modul AG domintech Domintech Co., Ltd. +dongwoon Dongwoon Anatech dptechnics DPTechnics dragino Dragino Technology Co., Limited ea Embedded Artists AB @@ -175,6 +178,7 @@ kosagi Sutajio Ko-Usagi PTE Ltd. kyo Kyocera Corporation lacie LaCie lantiq Lantiq Semiconductor +lattice Lattice Semiconductor lego LEGO Systems A/S lenovo Lenovo Group Ltd. lg LG Corporation @@ -195,6 +199,7 @@ mediatek MediaTek Inc. megachips MegaChips melexis Melexis N.V. melfas MELFAS Inc. +mellanox Mellanox Technologies memsic MEMSIC Inc. merrii Merrii Technology Co., Ltd. micrel Micrel Inc. @@ -206,7 +211,7 @@ miramems MiraMEMS Sensing Technology Co., Ltd. mitsubishi Mitsubishi Electric Corporation mosaixtech Mosaix Technologies, Inc. motorola Motorola, Inc. -moxa Moxa +moxa Moxa Inc. mpl MPL AG mqmaker mqmaker Inc. msi Micro-Star International Co. Ltd. @@ -249,6 +254,7 @@ oxsemi Oxford Semiconductor, Ltd. panasonic Panasonic Corporation parade Parade Technologies Inc. pericom Pericom Technology Inc. +pervasive Pervasive Displays, Inc. phytec PHYTEC Messtechnik GmbH picochip Picochip Ltd pine64 Pine64 @@ -287,6 +293,7 @@ schindler Schindler seagate Seagate Technology PLC semtech Semtech Corporation sensirion Sensirion AG +sff Small Form Factor Committee sgx SGX Sensortech sharp Sharp Corporation si-en Si-En Technology Ltd. @@ -341,6 +348,7 @@ tpo TPO tronfy Tronfy tronsmart Tronsmart truly Truly Semiconductors Limited +tsd Theobroma Systems Design und Consulting GmbH tyan Tyan Computer Corporation ucrobotics uCRobotics udoo Udoo @@ -353,6 +361,7 @@ variscite Variscite Ltd. via VIA Technologies, Inc. virtio Virtual I/O Device Specification, developed by the OASIS consortium vivante Vivante Corporation +vocore VoCore Studio voipac Voipac Technologies s.r.o. wd Western Digital Corp. wetek WeTek Electronics, limited. diff --git a/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt b/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt index ecf42c07684d15e5374466a5c30e3aaad4f12dc2..cbaa6467ab2cc3f0892d0958cc87fb25739837da 100644 --- a/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt +++ b/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt @@ -15,5 +15,4 @@ owire: owire@63fa4000 { compatible = "fsl,imx53-owire", "fsl,imx21-owire"; reg = <0x63fa4000 0x4000>; clocks = <&clks 159>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt index c5e74d7b4406127735d42e9221a8fb3e417e8717..c5077a1f5cb3e4753fbf74bb3c905e8e8fce2c81 100644 --- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt @@ -8,9 +8,49 @@ Required properties: - reg: physical base address of the controller and length of memory mapped region +Optional properties: + + - aspeed,reset-type = "cpu|soc|system|none" + + Reset behavior - Whenever a timeout occurs the watchdog can be programmed + to generate one of three different, mutually exclusive, types of resets. + + Type "none" can be specified to indicate that no resets are to be done. + This is useful in situations where another watchdog engine on chip is + to perform the reset. + + If 'aspeed,reset-type=' is not specfied the default is to enable system + reset. + + Reset types: + + - cpu: Reset CPU on watchdog timeout + + - soc: Reset 'System on Chip' on watchdog timeout + + - system: Reset system on watchdog timeout + + - none: No reset is performed on timeout. Assumes another watchdog + engine is responsible for this. + + - aspeed,alt-boot: If property is present then boot from alternate block. + - aspeed,external-signal: If property is present then signal is sent to + external reset counter (only WDT1 and WDT2). If not + specified no external signal is sent. + - aspeed,ext-pulse-duration: External signal pulse duration in microseconds + +Optional properties for AST2500-compatible watchdogs: + - aspeed,ext-push-pull: If aspeed,external-signal is present, set the pin's + drive type to push-pull. The default is open-drain. + - aspeed,ext-active-high: If aspeed,external-signal is present and and the pin + is configured as push-pull, then set the pulse + polarity to active-high. The default is active-low. + Example: wdt1: watchdog@1e785000 { compatible = "aspeed,ast2400-wdt"; reg = <0x1e785000 0x1c>; + aspeed,reset-type = "system"; + aspeed,external-signal; }; diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt index f7cc7c0609107d6f94de076af38f84590f175896..4fec1e3725b44c1d3e9731a9040e884abe1df5c2 100644 --- a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt @@ -31,5 +31,4 @@ Example: atmel,watchdog-type = "hardware"; atmel,dbg-halt; atmel,idle-halt; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt index 86fa6de1019bdbfba3675efd6b4b02244c783809..711a880b3d3bf46ed5b5e67dc98ceed3f10d80b0 100644 --- a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt @@ -48,5 +48,4 @@ Example: atmel,idle-halt; atmel,max-heartbeat-sec = <16>; atmel,min-heartbeat-sec = <0>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt new file mode 100644 index 0000000000000000000000000000000000000000..18d4d83027026dd166b762bc87188fa475a186ac --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt @@ -0,0 +1,24 @@ +Lantiq WTD watchdog binding +============================ + +This describes the binding of the Lantiq watchdog driver. + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,wdt" + "lantiq,xrx100-wdt" + "lantiq,xrx200-wdt", "lantiq,xrx100-wdt" + "lantiq,falcon-wdt" +- reg : Address of the watchdog block +- lantiq,rcu : A phandle to the RCU syscon (required for + "lantiq,falcon-wdt" and "lantiq,xrx100-wdt") + +------------------------------------------------------------------------------- +Example for the watchdog on the xRX200 SoCs: + watchdog@803f0 { + compatible = "lantiq,xrx200-wdt", "lantiq,xrx100-wdt"; + reg = <0x803f0 0x10>; + + lantiq,rcu = <&rcu0>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt index 858ed9221ac4d65d77ddc8537c2761995527af52..c1b67a78f00c770109bdf0b80059e401413b80ef 100644 --- a/Documentation/devicetree/bindings/watchdog/marvel.txt +++ b/Documentation/devicetree/bindings/watchdog/marvel.txt @@ -41,6 +41,5 @@ Example: reg = <0x20300 0x28>, <0x20108 0x4>; interrupts = <3>; timeout-sec = <10>; - status = "okay"; clocks = <&gate_clk 7>; }; diff --git a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt index ae70185d96e645df9ad6a97b9d5e2faa45bd5743..8a6d84cb36c96521a74d3d8b12aae1f4fd1a97f6 100644 --- a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt @@ -2,7 +2,11 @@ Meson SoCs Watchdog timer Required properties: -- compatible : should be "amlogic,meson6-wdt" or "amlogic,meson8b-wdt" +- compatible : depending on the SoC this should be one of: + "amlogic,meson6-wdt" on Meson6 SoCs + "amlogic,meson8-wdt" and "amlogic,meson6-wdt" on Meson8 SoCs + "amlogic,meson8b-wdt" on Meson8b SoCs + "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs - reg : Specifies base physical address and size of the registers. Example: diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt index 6a00939a059a1185c5e4ece5bbcd388131bb4987..235de0683bb6f7e3ae557175d57d40cdfa17218d 100644 --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt @@ -3,9 +3,11 @@ Mediatek SoCs Watchdog timer Required properties: - compatible should contain: - * "mediatek,mt2701-wdt" for MT2701 compatible watchdog timers - * "mediatek,mt6589-wdt" for all compatible watchdog timers (MT2701, - MT6589) + "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701 + "mediatek,mt6589-wdt": for MT6589 + "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797 + "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622 + "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623 - reg : Specifies base physical address and size of the registers. diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt index 9e306afbbd49e91b689f6e7fbf63a47d6167dfaf..bf6d1ca58af7d1989deda93d037b57a23ffd426d 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt @@ -6,6 +6,7 @@ Required properties: Examples with soctypes are: - "renesas,r8a7795-wdt" (R-Car H3) - "renesas,r8a7796-wdt" (R-Car M3-W) + - "renesas,r8a77995-wdt" (R-Car D3) - "renesas,r7s72100-wdt" (RZ/A1) When compatible with the generic version, nodes must list the SoC-specific diff --git a/Documentation/devicetree/bindings/xilinx.txt b/Documentation/devicetree/bindings/xilinx.txt index 299d0923537b00438fa06df171021e77fdf4b7c1..1d11b9002ef81cd6d22fdc9b40699f116c9ddf96 100644 --- a/Documentation/devicetree/bindings/xilinx.txt +++ b/Documentation/devicetree/bindings/xilinx.txt @@ -281,6 +281,8 @@ capabilities of the underlying ICAP hardware differ between different families. May be 'virtex2p', 'virtex4', or 'virtex5'. + - compatible : should contain "xlnx,xps-hwicap-1.00.a" or + "xlnx,opb-hwicap-1.00.b". vi) Xilinx Uart 16550 diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index fb740445199fabc1227d6d3e6512c7e24f9f4e41..417f9111001042bcf5348decba7dc933016257b2 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt @@ -1282,7 +1282,7 @@ hierarchy and routing of interrupts in the hardware. The interrupt tree model is fully described in the document "Open Firmware Recommended Practice: Interrupt Mapping Version 0.9". The document is available at: - + 1) interrupts property ---------------------- diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt index e33bc1c8ed2c44fede97ee64ca5a2a7e48389c50..5dbe054a40adbdb2ecf48894c5bf7e9cbb06b99b 100644 --- a/Documentation/dmaengine/provider.txt +++ b/Documentation/dmaengine/provider.txt @@ -181,13 +181,6 @@ Currently, the types available are: - Used by the client drivers to register a callback that will be called on a regular basis through the DMA controller interrupt - * DMA_SG - - The device supports memory to memory scatter-gather - transfers. - - Even though a plain memcpy can look like a particular case of a - scatter-gather transfer, with a single chunk to transfer, it's a - distinct transaction type in the mem2mem transfers case - * DMA_PRIVATE - The devices only supports slave transfers, and as such isn't available for async transfers. @@ -395,6 +388,13 @@ where to put them) when DMA_CTRL_REUSE is already set - Terminating the channel + * DMA_PREP_CMD + - If set, the client driver tells DMA controller that passed data in DMA + API is command data. + - Interpretation of command data is DMA controller specific. It can be + used for issuing commands to other peripherals/register reads/register + writes for which the descriptor should be in different format from + normal data descriptors. General Design Notes -------------------- diff --git a/Documentation/doc-guide/sphinx.rst b/Documentation/doc-guide/sphinx.rst index 84e8e8a9cbdb0431ef2e67fca56b39475a633e5e..a2417633fdd82205566cffee6fdd13998e9338b5 100644 --- a/Documentation/doc-guide/sphinx.rst +++ b/Documentation/doc-guide/sphinx.rst @@ -19,6 +19,110 @@ Finally, there are thousands of plain text documentation files scattered around ``Documentation``. Some of these will likely be converted to reStructuredText over time, but the bulk of them will remain in plain text. +.. _sphinx_install: + +Sphinx Install +============== + +The ReST markups currently used by the Documentation/ files are meant to be +built with ``Sphinx`` version 1.3 or upper. If you're desiring to build +PDF outputs, it is recommended to use version 1.4.6 or upper. + +There's a script that checks for the Spinx requirements. Please see +:ref:`sphinx-pre-install` for further details. + +Most distributions are shipped with Sphinx, but its toolchain is fragile, +and it is not uncommon that upgrading it or some other Python packages +on your machine would cause the documentation build to break. + +A way to get rid of that is to use a different version than the one shipped +on your distributions. In order to do that, it is recommended to install +Sphinx inside a virtual environment, using ``virtualenv-3`` +or ``virtualenv``, depending on how your distribution packaged Python 3. + +.. note:: + + #) Sphinx versions below 1.5 don't work properly with Python's + docutils version 0.13.1 or upper. So, if you're willing to use + those versions, you should run ``pip install 'docutils==0.12'``. + + #) It is recommended to use the RTD theme for html output. Depending + on the Sphinx version, it should be installed in separate, + with ``pip install sphinx_rtd_theme``. + + #) Some ReST pages contain math expressions. Due to the way Sphinx work, + those expressions are written using LaTeX notation. It needs texlive + installed with amdfonts and amsmath in order to evaluate them. + +In summary, if you want to install Sphinx version 1.4.9, you should do:: + + $ virtualenv sphinx_1.4 + $ . sphinx_1.4/bin/activate + (sphinx_1.4) $ pip install -r Documentation/sphinx/requirements.txt + +After running ``. sphinx_1.4/bin/activate``, the prompt will change, +in order to indicate that you're using the new environment. If you +open a new shell, you need to rerun this command to enter again at +the virtual environment before building the documentation. + +Image output +------------ + +The kernel documentation build system contains an extension that +handles images on both GraphViz and SVG formats (see +:ref:`sphinx_kfigure`). + +For it to work, you need to install both GraphViz and ImageMagick +packages. If those packages are not installed, the build system will +still build the documentation, but won't include any images at the +output. + +PDF and LaTeX builds +-------------------- + +Such builds are currently supported only with Sphinx versions 1.4 and upper. + +For PDF and LaTeX output, you'll also need ``XeLaTeX`` version 3.14159265. + +Depending on the distribution, you may also need to install a series of +``texlive`` packages that provide the minimal set of functionalities +required for ``XeLaTeX`` to work. + +.. _sphinx-pre-install: + +Checking for Sphinx dependencies +-------------------------------- + +There's a script that automatically check for Sphinx dependencies. If it can +recognize your distribution, it will also give a hint about the install +command line options for your distro:: + + $ ./scripts/sphinx-pre-install + Checking if the needed tools for Fedora release 26 (Twenty Six) are available + Warning: better to also install "texlive-luatex85". + You should run: + + sudo dnf install -y texlive-luatex85 + /usr/bin/virtualenv sphinx_1.4 + . sphinx_1.4/bin/activate + pip install -r Documentation/sphinx/requirements.txt + + Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468. + +By default, it checks all the requirements for both html and PDF, including +the requirements for images, math expressions and LaTeX build, and assumes +that a virtual Python environment will be used. The ones needed for html +builds are assumed to be mandatory; the others to be optional. + +It supports two optional parameters: + +``--no-pdf`` + Disable checks for PDF; + +``--no-virtualenv`` + Use OS packaging for Sphinx instead of Python virtual environment. + + Sphinx Build ============ @@ -118,7 +222,7 @@ Here are some specific guidelines for the kernel documentation: the C domain ------------ -The `Sphinx C Domain`_ (name c) is suited for documentation of C API. E.g. a +The **Sphinx C Domain** (name c) is suited for documentation of C API. E.g. a function prototype: .. code-block:: rst @@ -229,6 +333,7 @@ Rendered as: - column 3 +.. _sphinx_kfigure: Figures & Images ================ diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 358b47c06ad4616e6990a2c7a8efd67f80a06840..2228fcc8e29f40ed02bfd0d1d5329f2e61d9b9a2 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -259,5 +259,4 @@ wakeup.bin wakeup.elf wakeup.lds zImage* -zconf.hash.c zoffset.h diff --git a/Documentation/driver-api/basics.rst b/Documentation/driver-api/basics.rst index ab82250c7727309d2aace9284c26316c770c1fb5..73fa7d42bbbaed3b52a52c0d59a2efb778751f66 100644 --- a/Documentation/driver-api/basics.rst +++ b/Documentation/driver-api/basics.rst @@ -4,7 +4,7 @@ Driver Basics Driver Entry and Exit points ---------------------------- -.. kernel-doc:: include/linux/init.h +.. kernel-doc:: include/linux/module.h :internal: Driver device table @@ -103,9 +103,6 @@ Kernel utility functions .. kernel-doc:: kernel/panic.c :export: -.. kernel-doc:: kernel/sys.c - :export: - .. kernel-doc:: kernel/rcu/tree.c :export: diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 31671b469627ff2b439f891d32a03b5be02403c1..dc384f2f7f34c7fde3b892d62aefebf87daab3d8 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -139,9 +139,6 @@ DMA Fences Seqno Hardware Fences ~~~~~~~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/dma-buf/seqno-fence.c - :export: - .. kernel-doc:: include/linux/seqno-fence.h :internal: diff --git a/Documentation/driver-api/firmware/request_firmware.rst b/Documentation/driver-api/firmware/request_firmware.rst index 1c2c4967cd4336046efa56d78a88d9c03b570661..cc0aea88082441a0a6625b76cf0012c8103a4137 100644 --- a/Documentation/driver-api/firmware/request_firmware.rst +++ b/Documentation/driver-api/firmware/request_firmware.rst @@ -44,17 +44,6 @@ request_firmware_nowait .. kernel-doc:: drivers/base/firmware_class.c :functions: request_firmware_nowait -Considerations for suspend and resume -===================================== - -During suspend and resume only the built-in firmware and the firmware cache -elements of the firmware API can be used. This is managed by fw_pm_notify(). - -fw_pm_notify ------------- -.. kernel-doc:: drivers/base/firmware_class.c - :functions: fw_pm_notify - request firmware API expected driver use ======================================== diff --git a/Documentation/driver-api/gpio.rst b/Documentation/driver-api/gpio.rst new file mode 100644 index 0000000000000000000000000000000000000000..6dd4aa647f27d6297dd5496be5f5695d2f11c639 --- /dev/null +++ b/Documentation/driver-api/gpio.rst @@ -0,0 +1,45 @@ +=================================== +General Purpose Input/Output (GPIO) +=================================== + +Core +==== + +.. kernel-doc:: include/linux/gpio/driver.h + :internal: + +.. kernel-doc:: drivers/gpio/gpiolib.c + :export: + +Legacy API +========== + +The functions listed in this section are deprecated. The GPIO descriptor based +API described above should be used in new code. + +.. kernel-doc:: drivers/gpio/gpiolib-legacy.c + :export: + +ACPI support +============ + +.. kernel-doc:: drivers/gpio/gpiolib-acpi.c + :export: + +Device tree support +=================== + +.. kernel-doc:: drivers/gpio/gpiolib-of.c + :export: + +Device-managed API +================== + +.. kernel-doc:: drivers/gpio/devres.c + :export: + +sysfs helpers +============= + +.. kernel-doc:: drivers/gpio/gpiolib-sysfs.c + :export: diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 7c94ab50afedda3197d91396ed28da2697920197..9c20624842b72fa3cc0248abdc441ef126a98dc8 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -44,6 +44,7 @@ available subsections can be seen below. uio-howto firmware/index pinctl + gpio misc_devices .. only:: subproject and html diff --git a/Documentation/driver-api/miscellaneous.rst b/Documentation/driver-api/miscellaneous.rst index 8da7d115bafcae2a81828cda2d27b43872068151..304ffb146cf9c195832cae3a998eb4712910488a 100644 --- a/Documentation/driver-api/miscellaneous.rst +++ b/Documentation/driver-api/miscellaneous.rst @@ -47,4 +47,3 @@ used by one consumer at a time. .. kernel-doc:: drivers/pwm/core.c :export: - diff --git a/Documentation/driver-api/mtdnand.rst b/Documentation/driver-api/mtdnand.rst index e9afa586d15ea9b52df9d45df726a3b31545f7ab..2a5191b6d4459fa76734bcdbad1f21e30278dcd9 100644 --- a/Documentation/driver-api/mtdnand.rst +++ b/Documentation/driver-api/mtdnand.rst @@ -516,7 +516,7 @@ mirrored table is performed. The most important field in the nand_bbt_descr structure is the options field. The options define most of the table properties. Use the -predefined constants from nand.h to define the options. +predefined constants from rawnand.h to define the options. - Number of bits per block @@ -843,7 +843,7 @@ Chip option constants Constants for chip id table ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These constants are defined in nand.h. They are OR-ed together to +These constants are defined in rawnand.h. They are OR-ed together to describe the chip functionality:: /* Buswitdh is 16 bit */ @@ -865,7 +865,7 @@ describe the chip functionality:: Constants for runtime options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These constants are defined in nand.h. They are OR-ed together to +These constants are defined in rawnand.h. They are OR-ed together to describe the functionality:: /* The hw ecc generator provides a syndrome instead a ecc value on read @@ -956,7 +956,7 @@ developer. Each struct member has a short description which is marked with an [XXX] identifier. See the chapter "Documentation hints" for an explanation. -.. kernel-doc:: include/linux/mtd/nand.h +.. kernel-doc:: include/linux/mtd/rawnand.h :internal: Public Functions Provided diff --git a/Documentation/driver-api/pm/devices.rst b/Documentation/driver-api/pm/devices.rst index bedd32388dac51d8a603dd1389c3b4de24807d7a..a0dc2879a152c89dbb9d5f715ec07fbfe6a4cd8e 100644 --- a/Documentation/driver-api/pm/devices.rst +++ b/Documentation/driver-api/pm/devices.rst @@ -675,7 +675,7 @@ sub-domain of the parent domain. Support for power domains is provided through the :c:member:`pm_domain` field of |struct device|. This field is a pointer to an object of type -|struct dev_pm_domain|, defined in :file:`include/linux/pm.h``, providing a set +|struct dev_pm_domain|, defined in :file:`include/linux/pm.h`, providing a set of power management callbacks analogous to the subsystem-level and device driver callbacks that are executed for the given device during all power transitions, instead of the respective subsystem-level callbacks. Specifically, if a diff --git a/Documentation/driver-api/s390-drivers.rst b/Documentation/driver-api/s390-drivers.rst index 7060da1360951b6747b704cb3cf3baf4c0bc4c08..ecf8851d35651161542f65a62c5c1d7ed631ffd8 100644 --- a/Documentation/driver-api/s390-drivers.rst +++ b/Documentation/driver-api/s390-drivers.rst @@ -75,7 +75,7 @@ The channel-measurement facility provides a means to collect measurement data which is made available by the channel subsystem for each channel attached device. -.. kernel-doc:: arch/s390/include/asm/cmb.h +.. kernel-doc:: arch/s390/include/uapi/asm/cmb.h :internal: .. kernel-doc:: drivers/s390/cio/cmf.c diff --git a/Documentation/driver-api/scsi.rst b/Documentation/driver-api/scsi.rst index 859fb672319f9ca728460a1076884cd551c45195..5a2aa7a377d9bd9fe08e5519cfa285d5fa5083f5 100644 --- a/Documentation/driver-api/scsi.rst +++ b/Documentation/driver-api/scsi.rst @@ -224,14 +224,6 @@ mid to lowlevel SCSI driver interface .. kernel-doc:: drivers/scsi/hosts.c :export: -drivers/scsi/constants.c -~~~~~~~~~~~~~~~~~~~~~~~~ - -mid to lowlevel SCSI driver interface - -.. kernel-doc:: drivers/scsi/constants.c - :export: - Transport classes ----------------- diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 30e04f7a690ddfc0d2d0c370163fe93adc59a168..69f08c0f23a8eb8706a35f43d338061cdaa61868 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -312,6 +312,7 @@ IRQ devm_irq_alloc_descs_from() devm_irq_alloc_generic_chip() devm_irq_setup_generic_chip() + devm_irq_sim_init() LED devm_led_classdev_register() diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index 4421135826a2e5fb8526288afa06473cb2137027..d661e6f7e6a0cb6b161e30ab1ad800bc8bd581f6 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -196,12 +196,13 @@ struct driver_attribute { }; Device drivers can export attributes via their sysfs directories. -Drivers can declare attributes using a DRIVER_ATTR macro that works -identically to the DEVICE_ATTR macro. +Drivers can declare attributes using a DRIVER_ATTR_RW and DRIVER_ATTR_RO +macro that works identically to the DEVICE_ATTR_RW and DEVICE_ATTR_RO +macros. Example: -DRIVER_ATTR(debug,0644,show_debug,store_debug); +DRIVER_ATTR_RW(debug); This is equivalent to declaring: diff --git a/Documentation/errseq.rst b/Documentation/errseq.rst new file mode 100644 index 0000000000000000000000000000000000000000..4c29bd5afbc57069e81bb98a0cccf40d2377b251 --- /dev/null +++ b/Documentation/errseq.rst @@ -0,0 +1,149 @@ +The errseq_t datatype +===================== +An errseq_t is a way of recording errors in one place, and allowing any +number of "subscribers" to tell whether it has changed since a previous +point where it was sampled. + +The initial use case for this is tracking errors for file +synchronization syscalls (fsync, fdatasync, msync and sync_file_range), +but it may be usable in other situations. + +It's implemented as an unsigned 32-bit value. The low order bits are +designated to hold an error code (between 1 and MAX_ERRNO). The upper bits +are used as a counter. This is done with atomics instead of locking so that +these functions can be called from any context. + +Note that there is a risk of collisions if new errors are being recorded +frequently, since we have so few bits to use as a counter. + +To mitigate this, the bit between the error value and counter is used as +a flag to tell whether the value has been sampled since a new value was +recorded. That allows us to avoid bumping the counter if no one has +sampled it since the last time an error was recorded. + +Thus we end up with a value that looks something like this:: + + bit: 31..13 12 11..0 + +-----------------+----+----------------+ + | counter | SF | errno | + +-----------------+----+----------------+ + +The general idea is for "watchers" to sample an errseq_t value and keep +it as a running cursor. That value can later be used to tell whether +any new errors have occurred since that sampling was done, and atomically +record the state at the time that it was checked. This allows us to +record errors in one place, and then have a number of "watchers" that +can tell whether the value has changed since they last checked it. + +A new errseq_t should always be zeroed out. An errseq_t value of all zeroes +is the special (but common) case where there has never been an error. An all +zero value thus serves as the "epoch" if one wishes to know whether there +has ever been an error set since it was first initialized. + +API usage +========= +Let me tell you a story about a worker drone. Now, he's a good worker +overall, but the company is a little...management heavy. He has to +report to 77 supervisors today, and tomorrow the "big boss" is coming in +from out of town and he's sure to test the poor fellow too. + +They're all handing him work to do -- so much he can't keep track of who +handed him what, but that's not really a big problem. The supervisors +just want to know when he's finished all of the work they've handed him so +far and whether he made any mistakes since they last asked. + +He might have made the mistake on work they didn't actually hand him, +but he can't keep track of things at that level of detail, all he can +remember is the most recent mistake that he made. + +Here's our worker_drone representation:: + + struct worker_drone { + errseq_t wd_err; /* for recording errors */ + }; + +Every day, the worker_drone starts out with a blank slate:: + + struct worker_drone wd; + + wd.wd_err = (errseq_t)0; + +The supervisors come in and get an initial read for the day. They +don't care about anything that happened before their watch begins:: + + struct supervisor { + errseq_t s_wd_err; /* private "cursor" for wd_err */ + spinlock_t s_wd_err_lock; /* protects s_wd_err */ + } + + struct supervisor su; + + su.s_wd_err = errseq_sample(&wd.wd_err); + spin_lock_init(&su.s_wd_err_lock); + +Now they start handing him tasks to do. Every few minutes they ask him to +finish up all of the work they've handed him so far. Then they ask him +whether he made any mistakes on any of it:: + + spin_lock(&su.su_wd_err_lock); + err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); + spin_unlock(&su.su_wd_err_lock); + +Up to this point, that just keeps returning 0. + +Now, the owners of this company are quite miserly and have given him +substandard equipment with which to do his job. Occasionally it +glitches and he makes a mistake. He sighs a heavy sigh, and marks it +down:: + + errseq_set(&wd.wd_err, -EIO); + +...and then gets back to work. The supervisors eventually poll again +and they each get the error when they next check. Subsequent calls will +return 0, until another error is recorded, at which point it's reported +to each of them once. + +Note that the supervisors can't tell how many mistakes he made, only +whether one was made since they last checked, and the latest value +recorded. + +Occasionally the big boss comes in for a spot check and asks the worker +to do a one-off job for him. He's not really watching the worker +full-time like the supervisors, but he does need to know whether a +mistake occurred while his job was processing. + +He can just sample the current errseq_t in the worker, and then use that +to tell whether an error has occurred later:: + + errseq_t since = errseq_sample(&wd.wd_err); + /* submit some work and wait for it to complete */ + err = errseq_check(&wd.wd_err, since); + +Since he's just going to discard "since" after that point, he doesn't +need to advance it here. He also doesn't need any locking since it's +not usable by anyone else. + +Serializing errseq_t cursor updates +=================================== +Note that the errseq_t API does not protect the errseq_t cursor during a +check_and_advance_operation. Only the canonical error code is handled +atomically. In a situation where more than one task might be using the +same errseq_t cursor at the same time, it's important to serialize +updates to that cursor. + +If that's not done, then it's possible for the cursor to go backward +in which case the same error could be reported more than once. + +Because of this, it's often advantageous to first do an errseq_check to +see if anything has changed, and only later do an +errseq_check_and_advance after taking the lock. e.g.:: + + if (errseq_check(&wd.wd_err, READ_ONCE(su.s_wd_err)) { + /* su.s_wd_err is protected by s_wd_err_lock */ + spin_lock(&su.s_wd_err_lock); + err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); + spin_unlock(&su.s_wd_err_lock); + } + +That avoids the spinlock in the common case where nothing has changed +since the last time it was checked. diff --git a/Documentation/features/core/tracehook/arch-support.txt b/Documentation/features/core/tracehook/arch-support.txt index 5e97a89420ef09ceaa6c8fb7d89c7ca771d955ef..dfb638c2f8421369ac73a71279024fb9a8587daa 100644 --- a/Documentation/features/core/tracehook/arch-support.txt +++ b/Documentation/features/core/tracehook/arch-support.txt @@ -25,7 +25,7 @@ | mn10300: | ok | | nios2: | ok | | openrisc: | ok | - | parisc: | TODO | + | parisc: | ok | | powerpc: | ok | | s390: | ok | | score: | TODO | diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index fe25787ff6d49748c3e1ecc494f17e401a60916a..75d2d57e2c4421122434aa855444e8a344c38f21 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -22,7 +22,7 @@ prototypes: struct vfsmount *(*d_automount)(struct path *path); int (*d_manage)(const struct path *, bool); struct dentry *(*d_real)(struct dentry *, const struct inode *, - unsigned int); + unsigned int, unsigned int); locking rules: rename_lock ->d_lock may block rcu-walk diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt index aed6b94160b1cec74face20a05f9c03f03a057f2..0eb31de3a2c1a7679855577f8e92e730ead9005e 100644 --- a/Documentation/filesystems/caching/netfs-api.txt +++ b/Documentation/filesystems/caching/netfs-api.txt @@ -151,8 +151,6 @@ To define an object, a structure of the following type should be filled out: void (*mark_pages_cached)(void *cookie_netfs_data, struct address_space *mapping, struct pagevec *cached_pvec); - - void (*now_uncached)(void *cookie_netfs_data); }; This has the following fields: diff --git a/Documentation/filesystems/cifs/AUTHORS b/Documentation/filesystems/cifs/AUTHORS index c98800df677fef0e18103415af6a0333e8c6a10a..9f4f87e1624036349533adf9534bfd3c4b08535d 100644 --- a/Documentation/filesystems/cifs/AUTHORS +++ b/Documentation/filesystems/cifs/AUTHORS @@ -41,6 +41,11 @@ Igor Mammedov (DFS support) Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code) Scott Lovenberg Pavel Shilovsky (for great work adding SMB2 support, and various SMB3 features) +Aurelien Aptel (for DFS SMB3 work and some key bug fixes) +Ronnie Sahlberg (for SMB3 xattr work and bug fixes) +Shirish Pargaonkar (for many ACL patches over the years) +Sachin Prabhu (many bug fixes, including for reconnect, copy offload and security) + Test case and Bug Report contributors ------------------------------------- diff --git a/Documentation/filesystems/cifs/README b/Documentation/filesystems/cifs/README index a54788405429dce03af2dd950f6dd817df0d9a56..a9da51553ba3e15049c17aecbad840eb607ef056 100644 --- a/Documentation/filesystems/cifs/README +++ b/Documentation/filesystems/cifs/README @@ -1,10 +1,14 @@ -The CIFS VFS support for Linux supports many advanced network filesystem -features such as hierarchical dfs like namespace, hardlinks, locking and more. +This module supports the SMB3 family of advanced network protocols (as well +as older dialects, originally called "CIFS" or SMB1). + +The CIFS VFS module for Linux supports many advanced network filesystem +features such as hierarchical DFS like namespace, hardlinks, locking and more. It was designed to comply with the SNIA CIFS Technical Reference (which supersedes the 1992 X/Open SMB Standard) as well as to perform best practice practical interoperability with Windows 2000, Windows XP, Samba and equivalent servers. This code was developed in participation with the Protocol Freedom -Information Foundation. +Information Foundation. CIFS and now SMB3 has now become a defacto +standard for interoperating between Macs and Windows and major NAS appliances. Please see http://protocolfreedom.org/ and @@ -15,30 +19,11 @@ for more details. For questions or bug reports please contact: sfrench@samba.org (sfrench@us.ibm.com) +See the project page at: https://wiki.samba.org/index.php/LinuxCIFS_utils + Build instructions: ================== -For Linux 2.4: -1) Get the kernel source (e.g.from http://www.kernel.org) -and download the cifs vfs source (see the project page -at http://us1.samba.org/samba/Linux_CIFS_client.html) -and change directory into the top of the kernel directory -then patch the kernel (e.g. "patch -p1 < cifs_24.patch") -to add the cifs vfs to your kernel configure options if -it has not already been added (e.g. current SuSE and UL -users do not need to apply the cifs_24.patch since the cifs vfs is -already in the kernel configure menu) and then -mkdir linux/fs/cifs and then copy the current cifs vfs files from -the cifs download to your kernel build directory e.g. - - cp /fs/cifs/* to /fs/cifs - -2) make menuconfig (or make xconfig) -3) select cifs from within the network filesystem choices -4) save and exit -5) make dep -6) make modules (or "make" if CIFS VFS not to be built as a module) - -For Linux 2.6: +For Linux: 1) Download the kernel (e.g. from http://www.kernel.org) and change directory into the top of the kernel directory tree (e.g. /usr/src/linux-2.5.73) @@ -61,16 +46,13 @@ would simply type "make install"). If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on the CIFS VFS web site) copy it to the same directory in which mount.smbfs and similar files reside (usually /sbin). Although the helper software is not -required, mount.cifs is recommended. Eventually the Samba 3.0 utility program -"net" may also be helpful since it may someday provide easier mount syntax for -users who are used to Windows e.g. - net use +required, mount.cifs is recommended. Most distros include a "cifs-utils" +package that includes this utility so it is recommended to install this. + Note that running the Winbind pam/nss module (logon service) on all of your Linux clients is useful in mapping Uids and Gids consistently across the domain to the proper network user. The mount.cifs mount helper can be -trivially built from Samba 3.0 or later source e.g. by executing: - - gcc samba/source/client/mount.cifs.c -o mount.cifs +found at cifs-utils.git on git.samba.org If cifs is built as a module, then the size and number of network buffers and maximum number of simultaneous requests to one server can be configured. @@ -79,6 +61,18 @@ Changing these from their defaults is not recommended. By executing modinfo on kernel/fs/cifs/cifs.ko the list of configuration changes that can be made at module initialization time (by running insmod cifs.ko) can be seen. +Recommendations +=============== +To improve security the SMB2.1 dialect or later (usually will get SMB3) is now +the new default. To use old dialects (e.g. to mount Windows XP) use "vers=1.0" +on mount (or vers=2.0 for Windows Vista). Note that the CIFS (vers=1.0) is +much older and less secure than the default dialect SMB3 which includes +many advanced security features such as downgrade attack detection +and encrypted shares and stronger signing and authentication algorithms. +There are additional mount options that may be helpful for SMB3 to get +improved POSIX behavior (NB: can use vers=3.0 to force only SMB3, never 2.1): + "mfsymlinks" and "cifsacl" and "idsfromsid" + Allowing User Mounts ==================== To permit users to mount and unmount over directories they own is possible @@ -98,9 +92,7 @@ and execution of suid programs on the remote target would be enabled by default. This can be changed, as with nfs and other filesystems, by simply specifying "nosuid" among the mount options. For user mounts though to be able to pass the suid flag to mount requires rebuilding -mount.cifs with the following flag: - - gcc samba/source/client/mount.cifs.c -DCIFS_ALLOW_USR_SUID -o mount.cifs +mount.cifs with the following flag: CIFS_ALLOW_USR_SUID There is a corresponding manual page for cifs mounting in the Samba 3.0 and later source tree in docs/manpages/mount.cifs.8 @@ -189,18 +181,18 @@ applications running on the same server as Samba. Use instructions: ================ Once the CIFS VFS support is built into the kernel or installed as a module -(cifs.o), you can use mount syntax like the following to access Samba or Windows -servers: +(cifs.ko), you can use mount syntax like the following to access Samba or +Mac or Windows servers: - mount -t cifs //9.53.216.11/e$ /mnt -o user=myname,pass=mypassword + mount -t cifs //9.53.216.11/e$ /mnt -o username=myname,password=mypassword Before -o the option -v may be specified to make the mount.cifs mount helper display the mount steps more verbosely. After -o the following commonly used cifs vfs specific options are supported: - user= - pass= + username= + password= domain= Other cifs mount options are described below. Use of TCP names (in addition to @@ -246,13 +238,16 @@ the Server's registry. Samba starting with version 3.10 will allow such filenames (ie those which contain valid Linux characters, which normally would be forbidden for Windows/CIFS semantics) as long as the server is configured for Unix Extensions (and the client has not disabled -/proc/fs/cifs/LinuxExtensionsEnabled). - +/proc/fs/cifs/LinuxExtensionsEnabled). In addition the mount option +"mapposix" can be used on CIFS (vers=1.0) to force the mapping of +illegal Windows/NTFS/SMB characters to a remap range (this mount parm +is the default for SMB3). This remap ("mapposix") range is also +compatible with Mac (and "Services for Mac" on some older Windows). CIFS VFS Mount Options ====================== A partial list of the supported mount options follows: - user The user name to use when trying to establish + username The user name to use when trying to establish the CIFS session. password The user password. If the mount helper is installed, the user will be prompted for password diff --git a/Documentation/filesystems/cifs/TODO b/Documentation/filesystems/cifs/TODO index 066ffddc3964917d75287198ffd178daacc1cac6..396ecfd6ff4a0da40f099dfef57ef6111ae8da71 100644 --- a/Documentation/filesystems/cifs/TODO +++ b/Documentation/filesystems/cifs/TODO @@ -1,4 +1,4 @@ -Version 2.03 August 1, 2014 +Version 2.04 September 13, 2017 A Partial List of Missing Features ================================== @@ -8,73 +8,69 @@ for visible, important contributions to this module. Here is a partial list of the known problems and missing features: a) SMB3 (and SMB3.02) missing optional features: - - RDMA + - RDMA (started) - multichannel (started) - directory leases (improved metadata caching) - T10 copy offload (copy chunk is only mechanism supported) - - encrypted shares b) improved sparse file support c) Directory entry caching relies on a 1 second timer, rather than -using FindNotify or equivalent. - (started) +using Directory Leases d) quota support (needs minor kernel change since quota calls to make it to network filesystems or deviceless filesystems) -e) improve support for very old servers (OS/2 and Win9x for example) -Including support for changing the time remotely (utimes command). +e) Better optimize open to reduce redundant opens (using reference +counts more) and to improve use of compounding in SMB3 to reduce +number of roundtrips. -f) hook lower into the sockets api (as NFS/SunRPC does) to avoid the -extra copy in/out of the socket buffers in some cases. - -g) Better optimize open (and pathbased setfilesize) to reduce the -oplock breaks coming from windows srv. Piggyback identical file -opens on top of each other by incrementing reference count rather -than resending (helps reduce server resource utilization and avoid -spurious oplock breaks). - -h) Add support for storing symlink info to Windows servers -in the Extended Attribute format their SFU clients would recognize. - -i) Finish inotify support so kde and gnome file list windows +f) Finish inotify support so kde and gnome file list windows will autorefresh (partially complete by Asser). Needs minor kernel vfs change to support removing D_NOTIFY on a file. -j) Add GUI tool to configure /proc/fs/cifs settings and for display of +g) Add GUI tool to configure /proc/fs/cifs settings and for display of the CIFS statistics (started) -k) implement support for security and trusted categories of xattrs +h) implement support for security and trusted categories of xattrs (requires minor protocol extension) to enable better support for SELINUX -l) Implement O_DIRECT flag on open (already supported on mount) +i) Implement O_DIRECT flag on open (already supported on mount) -m) Create UID mapping facility so server UIDs can be mapped on a per +j) Create UID mapping facility so server UIDs can be mapped on a per mount or a per server basis to client UIDs or nobody if no mapping -exists. This is helpful when Unix extensions are negotiated to -allow better permission checking when UIDs differ on the server -and client. Add new protocol request to the CIFS protocol -standard for asking the server for the corresponding name of a -particular uid. +exists. Also better integration with winbind for resolving SID owners + +k) Add tools to take advantage of more smb3 specific ioctls and features + +l) encrypted file support + +m) improved stats gathering, tools (perhaps integration with nfsometer?) -n) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) +n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed +file attribute via chflags) and improve user space tools for managing and +viewing them. -o) mount check for unmatched uids +o) mount helper GUI (to simplify the various configuration options on mount) -p) Add support for new vfs entry point for fallocate +p) autonegotiation of dialects (offering more than one dialect ie SMB3.02, +SMB3, SMB2.1 not just SMB3). -q) Add tools to take advantage of cifs/smb3 specific ioctls and features -such as "CopyChunk" (fast server side file copy) +q) Allow mount.cifs to be more verbose in reporting errors with dialect +or unsupported feature errors. -r) encrypted file support +r) updating cifs documentation, and user guid. -s) improved stats gathering, tools (perhaps integration with nfsometer?) +s) Addressing bugs found by running a broader set of xfstests in standard +file system xfstest suite. -t) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed -file attribute via chflags) +t) split cifs and smb3 support into separate modules so legacy (and less +secure) CIFS dialect can be disabled in environments that don't need it +and simplify the code. -u) mount helper GUI (to simplify the various configuration options on mount) +u) Finish up SMB3.1.1 dialect support +v) POSIX Extensions for SMB3.1.1 KNOWN BUGS ==================================== diff --git a/Documentation/filesystems/cifs/cifs.txt b/Documentation/filesystems/cifs/cifs.txt index 2fac91ac96cf7484aae9e148e5841755feba5f70..67756607246e767a9105bc06c00a7b97730abbb1 100644 --- a/Documentation/filesystems/cifs/cifs.txt +++ b/Documentation/filesystems/cifs/cifs.txt @@ -1,24 +1,28 @@ - This is the client VFS module for the Common Internet File System - (CIFS) protocol which is the successor to the Server Message Block + This is the client VFS module for the SMB3 NAS protocol as well + older dialects such as the Common Internet File System (CIFS) + protocol which was the successor to the Server Message Block (SMB) protocol, the native file sharing mechanism for most early PC operating systems. New and improved versions of CIFS are now called SMB2 and SMB3. These dialects are also supported by the CIFS VFS module. CIFS is fully supported by network - file servers such as Windows 2000, 2003, 2008 and 2012 + file servers such as Windows 2000, 2003, 2008, 2012 and 2016 as well by Samba (which provides excellent CIFS - server support for Linux and many other operating systems), so + server support for Linux and many other operating systems), Apple + systems, as well as most Network Attached Storage vendors, so this network filesystem client can mount to a wide variety of servers. The intent of this module is to provide the most advanced network - file system function for CIFS compliant servers, including better - POSIX compliance, secure per-user session establishment, high - performance safe distributed caching (oplock), optional packet + file system function for SMB3 compliant servers, including advanced + security features, excellent parallelized high performance i/o, better + POSIX compliance, secure per-user session establishment, encryption, + high performance safe distributed caching (leases/oplocks), optional packet signing, large files, Unicode support and other internationalization improvements. Since both Samba server and this filesystem client support - the CIFS Unix extensions, the combination can provide a reasonable - alternative to NFSv4 for fileserving in some Linux to Linux environments, - not just in Linux to Windows environments. + the CIFS Unix extensions (and in the future SMB3 POSIX extensions), + the combination can provide a reasonable alternative to other network and + cluster file systems for fileserving in some Linux to Linux environments, + not just in Linux to Windows (or Linux to Mac) environments. This filesystem has an mount utility (mount.cifs) that can be obtained from diff --git a/Documentation/filesystems/dax.txt b/Documentation/filesystems/dax.txt index a7e6e14aeb08f3eaba96c9cfa0a00ebd610d6573..3be3b266be41e8e537b2c2726eb7ad26a97b4dbe 100644 --- a/Documentation/filesystems/dax.txt +++ b/Documentation/filesystems/dax.txt @@ -63,9 +63,8 @@ Filesystem support consists of - implementing an mmap file operation for DAX files which sets the VM_MIXEDMAP and VM_HUGEPAGE flags on the VMA, and setting the vm_ops to include handlers for fault, pmd_fault, page_mkwrite, pfn_mkwrite. These - handlers should probably call dax_iomap_fault() (for fault and page_mkwrite - handlers), dax_iomap_pmd_fault(), dax_pfn_mkwrite() passing the appropriate - iomap operations. + handlers should probably call dax_iomap_fault() passing the appropriate + fault size and iomap operations. - calling iomap_zero_range() passing appropriate iomap operations instead of block_truncate_page() for DAX files - ensuring that there is sufficient locking between reads, writes, diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 273ccb26885e9c6ff6d1da17c655d6316cbefef8..13c2ff0343485f7595b66da41aa96475a4602bfd 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -164,6 +164,16 @@ io_bits=%u Set the bit size of write IO requests. It should be set with "mode=lfs". usrquota Enable plain user disk quota accounting. grpquota Enable plain group disk quota accounting. +prjquota Enable plain project quota accounting. +usrjquota= Appoint specified file and type during mount, so that quota +grpjquota= information can be properly updated during recovery flow, +prjjquota= : must be in root directory; +jqfmt= : [vfsold,vfsv0,vfsv1]. +offusrjquota Turn off user journelled quota. +offgrpjquota Turn off group journelled quota. +offprjjquota Turn off project journelled quota. +quota Enable plain user disk quota accounting. +noquota Disable all plain disk quota option. ================================================================================ DEBUGFS ENTRIES @@ -209,6 +219,15 @@ Files in /sys/fs/f2fs/ gc_idle = 1 will select the Cost Benefit approach & setting gc_idle = 2 will select the greedy approach. + gc_urgent This parameter controls triggering background GCs + urgently or not. Setting gc_urgent = 0 [default] + makes back to default behavior, while if it is set + to 1, background thread starts to do GC by given + gc_urgent_sleep_time interval. + + gc_urgent_sleep_time This parameter controls sleep time for gc_urgent. + 500 ms is set by default. See above gc_urgent. + reclaim_segments This parameter controls the number of prefree segments to be reclaimed. If the number of prefree segments is larger than the number of segments diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt index 1dfdec7909464650acd7786db4368e03223c0765..e2818b60a5c21739d65588cdcac350af0809e794 100644 --- a/Documentation/filesystems/orangefs.txt +++ b/Documentation/filesystems/orangefs.txt @@ -45,14 +45,11 @@ upstream version of the kernel client. BUILDING THE USERSPACE FILESYSTEM ON A SINGLE SERVER ==================================================== -When Orangefs is upstream, "--with-kernel" shouldn't be needed, but -until then the path to where the kernel with the Orangefs kernel client -patch was built is needed to ensure that pvfs2-client-core (the bridge -between kernel space and user space) will build properly. You can omit ---prefix if you don't care that things are sprinkled around in -/usr/local. +You can omit --prefix if you don't care that things are sprinkled around in +/usr/local. As of version 2.9.6, Orangefs uses Berkeley DB by default, we +will probably be changing the default to lmdb soon. -./configure --prefix=/opt/ofs --with-kernel=/path/to/orangefs/kernel +./configure --prefix=/opt/ofs --with-db-backend=lmdb make @@ -82,9 +79,6 @@ prove things are working with: /opt/osf/bin/pvfs2-ls /mymountpoint -You might not want to enforce selinux, it doesn't seem to matter by -linux 3.11... - If stuff seems to be working, turn on the client core: /opt/osf/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt index 36f528a7fdd64d18c7ee7b3a50849b45bc046ef3..8caa60734647f70a777b8a568ba9f2dd99182fb8 100644 --- a/Documentation/filesystems/overlayfs.txt +++ b/Documentation/filesystems/overlayfs.txt @@ -210,8 +210,11 @@ path as another overlay mount and it may use a lower layer path that is beneath or above the path of another overlay lower layer path. Using an upper layer path and/or a workdir path that are already used by -another overlay mount is not allowed and will fail with EBUSY. Using +another overlay mount is not allowed and may fail with EBUSY. Using partially overlapping paths is not allowed but will not fail with EBUSY. +If files are accessed from two overlayfs mounts which share or overlap the +upper layer and/or workdir path the behavior of the overlay is undefined, +though it will not result in a crash or deadlock. Mounting an overlay using an upper layer path, where the upper layer path was previously used by another mounted overlay in combination with a diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 5fb17f49f7a21907a2c446267cc952c749e42043..93e0a24045322b3e2417e024821520c9996eb6fc 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -228,7 +228,7 @@ anything from oops to silent memory corruption. --- [mandatory] - FS_NOMOUNT is gone. If you use it - just set MS_NOUSER in flags + FS_NOMOUNT is gone. If you use it - just set SB_NOUSER in flags (see rootfs for one kind of solution and bdev/socket/pipe for another). --- diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index 24da7b32c489fd65408dbd8b33f7bc0402ddba0b..9a3658cc399ed459f1e21d613dbf8e5b1b2bc647 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -366,7 +366,8 @@ struct driver_attribute { Declaring: -DRIVER_ATTR(_name, _mode, _show, _store) +DRIVER_ATTR_RO(_name) +DRIVER_ATTR_RW(_name) Creation/Removal: diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 73e7d91f03dce56266ad1806e056c2a4f7e5321e..5fd325df59e2233df60cbf6da6c92230aa0c26ef 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -829,9 +829,7 @@ struct address_space_operations { swap_activate: Called when swapon is used on a file to allocate space if necessary and pin the block lookup information in memory. A return value of zero indicates success, - in which case this file can be used to back swapspace. The - swapspace operations will be proxied to this address space's - ->swap_{out,in} methods. + in which case this file can be used to back swapspace. swap_deactivate: Called during swapoff on files where swap_activate was successful. @@ -990,7 +988,7 @@ struct dentry_operations { struct vfsmount *(*d_automount)(struct path *); int (*d_manage)(const struct path *, bool); struct dentry *(*d_real)(struct dentry *, const struct inode *, - unsigned int); + unsigned int, unsigned int); }; d_revalidate: called when the VFS needs to revalidate a dentry. This diff --git a/Documentation/gpio/drivers-on-gpio.txt b/Documentation/gpio/drivers-on-gpio.txt index 3065132517135c231d28d4a9d3be87fd3c81f27b..9a78d385b92e86661f38ad265e474f0e88945087 100644 --- a/Documentation/gpio/drivers-on-gpio.txt +++ b/Documentation/gpio/drivers-on-gpio.txt @@ -84,6 +84,11 @@ hardware descriptions such as device tree or ACPI: NAND flash MTD subsystem and provides chip access and partition parsing like any other NAND driving hardware. +- ps2-gpio: drivers/input/serio/ps2-gpio.c is used to drive a PS/2 (IBM) serio + bus, data and clock line, by bit banging two GPIO lines. It will appear as + any other serio bus to the system and makes it possible to connect drivers + for e.g. keyboards and other PS/2 protocol based devices. + Apart from this there are special GPIO drivers in subsystems like MMC/SD to read card detect and write protect GPIO lines, and in the TTY serial subsystem to emulate MCTRL (modem control) signals CTS/RTS by using two GPIO lines. The diff --git a/Documentation/gpio/gpio-legacy.txt b/Documentation/gpio/gpio-legacy.txt index b34fd94f70898a7f65c2a0313349588411eb8e81..5eacc147ea870c80bb06c38d43bd5b662c171194 100644 --- a/Documentation/gpio/gpio-legacy.txt +++ b/Documentation/gpio/gpio-legacy.txt @@ -459,7 +459,7 @@ pin controller? This is done by registering "ranges" of pins, which are essentially cross-reference tables. These are described in -Documentation/pinctrl.txt +Documentation/driver-api/pinctl.rst While the pin allocation is totally managed by the pinctrl subsystem, gpio (under gpiolib) is still maintained by gpio drivers. It may happen diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 0d936c67bf7d78a84a38d284681d142ad34031d4..5ee9674fb9e981db2c17c0b6f1a08402b5ab5290 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -201,6 +201,8 @@ drivers. Open/Close, File Operations and IOCTLs ====================================== +.. _drm_driver_fops: + File Operations --------------- diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 7c5e2549a58a61091b286e88c2171cbc9439668f..13dd237418cc4595159c2037ae2e9bbdfd41f0de 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -296,3 +296,12 @@ Auxiliary Modeset Helpers .. kernel-doc:: drivers/gpu/drm/drm_modeset_helper.c :export: + +Framebuffer GEM Helper Reference +================================ + +.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c + :export: diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 2d77c958016483ca294ffe9a58f5dbd72f2dbd0f..307284125d7aa964522f85ea6fb34247e67c9de2 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -523,9 +523,6 @@ Color Management Properties .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c :doc: overview -.. kernel-doc:: include/drm/drm_color_mgmt.h - :internal: - .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c :export: @@ -554,60 +551,8 @@ various modules/drivers. Vertical Blanking ================= -Vertical blanking plays a major role in graphics rendering. To achieve -tear-free display, users must synchronize page flips and/or rendering to -vertical blanking. The DRM API offers ioctls to perform page flips -synchronized to vertical blanking and wait for vertical blanking. - -The DRM core handles most of the vertical blanking management logic, -which involves filtering out spurious interrupts, keeping race-free -blanking counters, coping with counter wrap-around and resets and -keeping use counts. It relies on the driver to generate vertical -blanking interrupts and optionally provide a hardware vertical blanking -counter. Drivers must implement the following operations. - -- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void - (\*disable_vblank) (struct drm_device \*dev, int crtc); - Enable or disable vertical blanking interrupts for the given CRTC. - -- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); - Retrieve the value of the vertical blanking counter for the given - CRTC. If the hardware maintains a vertical blanking counter its value - should be returned. Otherwise drivers can use the - :c:func:`drm_vblank_count()` helper function to handle this - operation. - -Drivers must initialize the vertical blanking handling core with a call -to :c:func:`drm_vblank_init()` in their load operation. - -Vertical blanking interrupts can be enabled by the DRM core or by -drivers themselves (for instance to handle page flipping operations). -The DRM core maintains a vertical blanking use count to ensure that the -interrupts are not disabled while a user still needs them. To increment -the use count, drivers call :c:func:`drm_vblank_get()`. Upon -return vertical blanking interrupts are guaranteed to be enabled. - -To decrement the use count drivers call -:c:func:`drm_vblank_put()`. Only when the use count drops to zero -will the DRM core disable the vertical blanking interrupts after a delay -by scheduling a timer. The delay is accessible through the -vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global -variable and expressed in milliseconds. Its default value is 5000 ms. -Zero means never disable, and a negative value means disable -immediately. Drivers may override the behaviour by setting the -:c:type:`struct drm_device ` -vblank_disable_immediate flag, which when set causes vblank interrupts -to be disabled immediately regardless of the drm_vblank_offdelay -value. The flag should only be set if there's a properly working -hardware vblank counter present. - -When a vertical blanking interrupt occurs drivers only need to call the -:c:func:`drm_handle_vblank()` function to account for the -interrupt. - -Resources allocated by :c:func:`drm_vblank_init()` must be freed -with a call to :c:func:`drm_vblank_cleanup()` in the driver unload -operation handler. +.. kernel-doc:: drivers/gpu/drm/drm_vblank.c + :doc: vblank handling Vertical Blanking and Interrupt Handling Functions Reference ------------------------------------------------------------ diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 9412798645c1ae84e9d3d1a252d4ff9b0b12a1b3..b08e9dcd91771c39ab56216c506ece87ce755059 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -191,7 +191,7 @@ acquired and release by :c:func:`calling drm_gem_object_get()` and holding the lock. When the last reference to a GEM object is released the GEM core calls -the :c:type:`struct drm_driver ` gem_free_object +the :c:type:`struct drm_driver ` gem_free_object_unlocked operation. That operation is mandatory for GEM-enabled drivers and must free the GEM object and all associated resources. @@ -492,7 +492,7 @@ DRM Sync Objects :doc: Overview .. kernel-doc:: include/drm/drm_syncobj.h - :export: + :internal: .. kernel-doc:: drivers/gpu/drm/drm_syncobj.c :export: diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 858457567d3df7460ab7074de88d82e24b8fab8e..679373b4a03f2189e14cce4c30686bdc947eb5a1 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -160,6 +160,8 @@ other hand, a driver requires shared state between clients which is visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes. +.. _drm_driver_ioctl: + IOCTL Support on Device Nodes ============================= diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 9c7ed3e3f1e94007d3c1bd9aace282f8d8b96eba..2e7ee0313c1cd6c0377d2b4a3f4948641f9a84a2 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -417,6 +417,10 @@ integrate with drm/i915 and to handle the `DRM_I915_PERF_OPEN` ioctl. :functions: i915_perf_open_ioctl .. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c :functions: i915_perf_release +.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c + :functions: i915_perf_add_config_ioctl +.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c + :functions: i915_perf_remove_config_ioctl i915 Perf Stream ---------------- @@ -477,4 +481,16 @@ specific details than found in the more high-level sections. .. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c :internal: -.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/drm/i915/i915_irq.c +Style +===== + +The drm/i915 driver codebase has some style rules in addition to (and, in some +cases, deviating from) the kernel coding style. + +Register macro definition style +------------------------------- + +The style guide for ``i915_reg.h``. + +.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h + :doc: The i915 register macro definition style guide diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1ae42006deea7814ce88b9ad121cbf56d246714f..22af55d06ab8d6be092cf9d8699a9c4e09cd5260 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -108,8 +108,8 @@ This would be especially useful for tinydrm: crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in __drm_atomic_helper_crtc_duplicate_state(). -- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_ - prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this +- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm\_ + prefix ofc and using drm_fb\_. drm_framebuffer.c makes sense since this is a function useful to implement the fb->dirty function. - Create a new drm_fb_dirty function which does essentially what e.g. diff --git a/Documentation/hwmon/ftsteutates b/Documentation/hwmon/ftsteutates index 8c10a916de20d064a34fb43b121309b190eab98c..af54db92391bab26610150b2f2b20bcc081edc2d 100644 --- a/Documentation/hwmon/ftsteutates +++ b/Documentation/hwmon/ftsteutates @@ -18,6 +18,10 @@ enhancements. It can monitor up to 4 voltages, 16 temperatures and 8 fans. It also contains an integrated watchdog which is currently implemented in this driver. +To clear a temperature or fan alarm, execute the following command with the +correct path to the alarm file: + echo 0 >XXXX_alarm + Specification of the chip can be found here: ftp://ftp.ts.fujitsu.com/pub/Mainboard-OEM-Sales/Services/Software&Tools/Linux_SystemMonitoring&Watchdog&GPIO/BMC-Teutates_Specification_V1.21.pdf ftp://ftp.ts.fujitsu.com/pub/Mainboard-OEM-Sales/Services/Software&Tools/Linux_SystemMonitoring&Watchdog&GPIO/Fujitsu_mainboards-1-Sensors_HowTo-en-US.pdf diff --git a/Documentation/hwmon/ibm-cffps b/Documentation/hwmon/ibm-cffps new file mode 100644 index 0000000000000000000000000000000000000000..e05ecd8ecfcfa54b247233af709d8134f086c92f --- /dev/null +++ b/Documentation/hwmon/ibm-cffps @@ -0,0 +1,54 @@ +Kernel driver ibm-cffps +======================= + +Supported chips: + * IBM Common Form Factor power supply + +Author: Eddie James + +Description +----------- + +This driver supports IBM Common Form Factor (CFF) power supplies. This driver +is a client to the core PMBus driver. + +Usage Notes +----------- + +This driver does not auto-detect devices. You will have to instantiate the +devices explicitly. Please see Documentation/i2c/instantiating-devices for +details. + +Sysfs entries +------------- + +The following attributes are supported: + +curr1_alarm Output current over-current alarm. +curr1_input Measured output current in mA. +curr1_label "iout1" + +fan1_alarm Fan 1 warning. +fan1_fault Fan 1 fault. +fan1_input Fan 1 speed in RPM. +fan2_alarm Fan 2 warning. +fan2_fault Fan 2 fault. +fan2_input Fan 2 speed in RPM. + +in1_alarm Input voltage under-voltage alarm. +in1_input Measured input voltage in mV. +in1_label "vin" +in2_alarm Output voltage over-voltage alarm. +in2_input Measured output voltage in mV. +in2_label "vout1" + +power1_alarm Input fault or alarm. +power1_input Measured input power in uW. +power1_label "pin" + +temp1_alarm PSU inlet ambient temperature over-temperature alarm. +temp1_input Measured PSU inlet ambient temp in millidegrees C. +temp2_alarm Secondary rectifier temp over-temperature alarm. +temp2_input Measured secondary rectifier temp in millidegrees C. +temp3_alarm ORing FET temperature over-temperature alarm. +temp3_input Measured ORing FET temperature in millidegrees C. diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066 index 2cb20ebb234d4944956512992b1a2d1787c4cbef..3fa6bf820c888ddcd912681a106bfa626acf604d 100644 --- a/Documentation/hwmon/lm25066 +++ b/Documentation/hwmon/lm25066 @@ -29,6 +29,11 @@ Supported chips: Addresses scanned: - Datasheet: http://www.national.com/pf/LM/LM5066.html + * Texas Instruments LM5066I + Prefix: 'lm5066i' + Addresses scanned: - + Datasheet: + http://www.ti.com/product/LM5066I Author: Guenter Roeck @@ -37,8 +42,8 @@ Description ----------- This driver supports hardware monitoring for National Semiconductor / TI LM25056, -LM25063, LM25066, LM5064, and LM5066 Power Management, Monitoring, Control, and -Protection ICs. +LM25063, LM25066, LM5064, and LM5066/LM5066I Power Management, Monitoring, +Control, and Protection ICs. The driver is a client driver to the core PMBus driver. Please see Documentation/hwmon/pmbus for details on PMBus client drivers. diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 0500193434cb2957eec34124d621ccc176eac555..d477024569269ff741720537ef609cafb60166f2 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 @@ -36,6 +36,7 @@ Supported adapters: * Intel Gemini Lake (SOC) * Intel Cannon Lake-H (PCH) * Intel Cannon Lake-LP (PCH) + * Intel Cedar Fork (PCH) Datasheets: Publicly available at the Intel website On Intel Patsburg and later chipsets, both the normal host SMBus controller diff --git a/Documentation/i2c/i2c-topology b/Documentation/i2c/i2c-topology index 1a014fede0b72b442dbc04a93a184e1bdf5fe324..f74d78b53d4d98f11aa2537c5ff94b17864aaa09 100644 --- a/Documentation/i2c/i2c-topology +++ b/Documentation/i2c/i2c-topology @@ -42,6 +42,10 @@ i2c-arb-gpio-challenge Parent-locked i2c-mux-gpio Normally parent-locked, mux-locked iff all involved gpio pins are controlled by the same i2c root adapter that they mux. +i2c-mux-gpmux Normally parent-locked, mux-locked iff + specified in device-tree. +i2c-mux-ltc4306 Mux-locked +i2c-mux-mlxcpld Parent-locked i2c-mux-pca9541 Parent-locked i2c-mux-pca954x Parent-locked i2c-mux-pinctrl Normally parent-locked, mux-locked iff @@ -50,9 +54,11 @@ i2c-mux-pinctrl Normally parent-locked, mux-locked iff i2c-mux-reg Parent-locked In drivers/iio/ +gyro/mpu3050 Mux-locked imu/inv_mpu6050/ Mux-locked In drivers/media/ +dvb-frontends/lgdt3306a Mux-locked dvb-frontends/m88ds3103 Parent-locked dvb-frontends/rtl2830 Parent-locked dvb-frontends/rtl2832 Mux-locked diff --git a/Documentation/iio/ep93xx_adc.txt b/Documentation/iio/ep93xx_adc.txt new file mode 100644 index 0000000000000000000000000000000000000000..23053e7817bd908ddfa353538bbe1e7107f48437 --- /dev/null +++ b/Documentation/iio/ep93xx_adc.txt @@ -0,0 +1,29 @@ +Cirrus Logic EP93xx ADC driver. + +1. Overview + +The driver is intended to work on both low-end (EP9301, EP9302) devices with +5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel +touchscreen/ADC module. + +2. Channel numbering + +Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. +EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is +not defined. So the last three are numbered randomly, let's say. + +Assuming ep93xx_adc is IIO device0, you'd find the following entries under +/sys/bus/iio/devices/iio:device0/: + + +-----------------+---------------+ + | sysfs entry | ball/pin name | + +-----------------+---------------+ + | in_voltage0_raw | YM | + | in_voltage1_raw | SXP | + | in_voltage2_raw | SXM | + | in_voltage3_raw | SYP | + | in_voltage4_raw | SYM | + | in_voltage5_raw | XP | + | in_voltage6_raw | XM | + | in_voltage7_raw | YP | + +-----------------+---------------+ diff --git a/Documentation/infiniband/tag_matching.txt b/Documentation/infiniband/tag_matching.txt new file mode 100644 index 0000000000000000000000000000000000000000..d2a3bf81922603ac9d210baa7bee37aab3b9c426 --- /dev/null +++ b/Documentation/infiniband/tag_matching.txt @@ -0,0 +1,64 @@ +Tag matching logic + +The MPI standard defines a set of rules, known as tag-matching, for matching +source send operations to destination receives. The following parameters must +match the following source and destination parameters: +* Communicator +* User tag - wild card may be specified by the receiver +* Source rank – wild car may be specified by the receiver +* Destination rank – wild +The ordering rules require that when more than one pair of send and receive +message envelopes may match, the pair that includes the earliest posted-send +and the earliest posted-receive is the pair that must be used to satisfy the +matching operation. However, this doesn’t imply that tags are consumed in +the order they are created, e.g., a later generated tag may be consumed, if +earlier tags can’t be used to satisfy the matching rules. + +When a message is sent from the sender to the receiver, the communication +library may attempt to process the operation either after or before the +corresponding matching receive is posted. If a matching receive is posted, +this is an expected message, otherwise it is called an unexpected message. +Implementations frequently use different matching schemes for these two +different matching instances. + +To keep MPI library memory footprint down, MPI implementations typically use +two different protocols for this purpose: + +1. The Eager protocol- the complete message is sent when the send is +processed by the sender. A completion send is received in the send_cq +notifying that the buffer can be reused. + +2. The Rendezvous Protocol - the sender sends the tag-matching header, +and perhaps a portion of data when first notifying the receiver. When the +corresponding buffer is posted, the responder will use the information from +the header to initiate an RDMA READ operation directly to the matching buffer. +A fin message needs to be received in order for the buffer to be reused. + +Tag matching implementation + +There are two types of matching objects used, the posted receive list and the +unexpected message list. The application posts receive buffers through calls +to the MPI receive routines in the posted receive list and posts send messages +using the MPI send routines. The head of the posted receive list may be +maintained by the hardware, with the software expected to shadow this list. + +When send is initiated and arrives at the receive side, if there is no +pre-posted receive for this arriving message, it is passed to the software and +placed in the unexpected message list. Otherwise the match is processed, +including rendezvous processing, if appropriate, delivering the data to the +specified receive buffer. This allows overlapping receive-side MPI tag +matching with computation. + +When a receive-message is posted, the communication library will first check +the software unexpected message list for a matching receive. If a match is +found, data is delivered to the user buffer, using a software controlled +protocol. The UCX implementation uses either an eager or rendezvous protocol, +depending on data size. If no match is found, the entire pre-posted receive +list is maintained by the hardware, and there is space to add one more +pre-posted receive to this list, this receive is passed to the hardware. +Software is expected to shadow this list, to help with processing MPI cancel +operations. In addition, because hardware and software are not expected to be +tightly synchronized with respect to the tag-matching operation, this shadow +list is used to detect the case that a pre-posted receive is passed to the +hardware, as the matching unexpected message is being passed from the hardware +to the software. diff --git a/Documentation/input/input.rst b/Documentation/input/input.rst index 3b3a22975106987781eda18172728a3884c59da5..47f86a4bf16cadbf258ccc8078780486c86f4370 100644 --- a/Documentation/input/input.rst +++ b/Documentation/input/input.rst @@ -109,7 +109,7 @@ evdev nodes are created with minors starting with 256. keyboard ~~~~~~~~ -``keyboard`` is in-kernel input handler ad is a part of VT code. It +``keyboard`` is in-kernel input handler and is a part of VT code. It consumes keyboard keystrokes and handles user input for VT consoles. mousedev diff --git a/Documentation/input/joydev/index.rst b/Documentation/input/joydev/index.rst index 8d9666c7561c8bafdfaaa0cb07db36fd85a55daa..ebcff43056e2db641c702348cd42a27364caabe0 100644 --- a/Documentation/input/joydev/index.rst +++ b/Documentation/input/joydev/index.rst @@ -12,7 +12,6 @@ Linux Joystick support .. toctree:: :maxdepth: 3 - :numbered: joystick joystick-api diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 7003141a6d4f2657eea22f41f26ca3e961c33856..329e740adea70db91ac2c9cd9f671f79ca58790e 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -297,9 +297,9 @@ more details, with real examples. ccflags-y specifies options for compiling with $(CC). Example: - # drivers/acpi/Makefile - ccflags-y := -Os - ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT + # drivers/acpi/acpica/Makefile + ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA + ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT This variable is necessary because the top Makefile owns the variable $(KBUILD_CFLAGS) and uses it for compilation flags for the diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index ba2e7d2548429a249a2462cf58a24938245ee047..00b6dfed573cf595594714df451621eb2f991893 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -121,8 +121,9 @@ space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/. Sysfs device attributes for the sensors and fan are on the thinkpad_hwmon device's sysfs attribute space, but you should locate it looking for a hwmon device with the name attribute of "thinkpad", or -better yet, through libsensors. - +better yet, through libsensors. For 4.14+ sysfs attributes were moved to the +hwmon device (/sys/bus/platform/devices/thinkpad_hwmon/hwmon/hwmon? or +/sys/class/hwmon/hwmon?). Driver version -------------- @@ -1478,3 +1479,7 @@ Sysfs interface changelog: 0x020700: Support for mute-only mixers. Volume control in read-only mode by default. Marker for ALSA mixer support. + +0x030000: Thermal and fan sysfs attributes were moved to the hwmon + device instead of being attached to the backing platform + device. diff --git a/Documentation/locking/crossrelease.txt b/Documentation/locking/crossrelease.txt new file mode 100644 index 0000000000000000000000000000000000000000..bdf1423d5f99e9b5a65e293049fdf0af7675f3b7 --- /dev/null +++ b/Documentation/locking/crossrelease.txt @@ -0,0 +1,874 @@ +Crossrelease +============ + +Started by Byungchul Park + +Contents: + + (*) Background + + - What causes deadlock + - How lockdep works + + (*) Limitation + + - Limit lockdep + - Pros from the limitation + - Cons from the limitation + - Relax the limitation + + (*) Crossrelease + + - Introduce crossrelease + - Introduce commit + + (*) Implementation + + - Data structures + - How crossrelease works + + (*) Optimizations + + - Avoid duplication + - Lockless for hot paths + + (*) APPENDIX A: What lockdep does to work aggresively + + (*) APPENDIX B: How to avoid adding false dependencies + + +========== +Background +========== + +What causes deadlock +-------------------- + +A deadlock occurs when a context is waiting for an event to happen, +which is impossible because another (or the) context who can trigger the +event is also waiting for another (or the) event to happen, which is +also impossible due to the same reason. + +For example: + + A context going to trigger event C is waiting for event A to happen. + A context going to trigger event A is waiting for event B to happen. + A context going to trigger event B is waiting for event C to happen. + +A deadlock occurs when these three wait operations run at the same time, +because event C cannot be triggered if event A does not happen, which in +turn cannot be triggered if event B does not happen, which in turn +cannot be triggered if event C does not happen. After all, no event can +be triggered since any of them never meets its condition to wake up. + +A dependency might exist between two waiters and a deadlock might happen +due to an incorrect releationship between dependencies. Thus, we must +define what a dependency is first. A dependency exists between them if: + + 1. There are two waiters waiting for each event at a given time. + 2. The only way to wake up each waiter is to trigger its event. + 3. Whether one can be woken up depends on whether the other can. + +Each wait in the example creates its dependency like: + + Event C depends on event A. + Event A depends on event B. + Event B depends on event C. + + NOTE: Precisely speaking, a dependency is one between whether a + waiter for an event can be woken up and whether another waiter for + another event can be woken up. However from now on, we will describe + a dependency as if it's one between an event and another event for + simplicity. + +And they form circular dependencies like: + + -> C -> A -> B - + / \ + \ / + ---------------- + + where 'A -> B' means that event A depends on event B. + +Such circular dependencies lead to a deadlock since no waiter can meet +its condition to wake up as described. + +CONCLUSION + +Circular dependencies cause a deadlock. + + +How lockdep works +----------------- + +Lockdep tries to detect a deadlock by checking dependencies created by +lock operations, acquire and release. Waiting for a lock corresponds to +waiting for an event, and releasing a lock corresponds to triggering an +event in the previous section. + +In short, lockdep does: + + 1. Detect a new dependency. + 2. Add the dependency into a global graph. + 3. Check if that makes dependencies circular. + 4. Report a deadlock or its possibility if so. + +For example, consider a graph built by lockdep that looks like: + + A -> B - + \ + -> E + / + C -> D - + + where A, B,..., E are different lock classes. + +Lockdep will add a dependency into the graph on detection of a new +dependency. For example, it will add a dependency 'E -> C' when a new +dependency between lock E and lock C is detected. Then the graph will be: + + A -> B - + \ + -> E - + / \ + -> C -> D - \ + / / + \ / + ------------------ + + where A, B,..., E are different lock classes. + +This graph contains a subgraph which demonstrates circular dependencies: + + -> E - + / \ + -> C -> D - \ + / / + \ / + ------------------ + + where C, D and E are different lock classes. + +This is the condition under which a deadlock might occur. Lockdep +reports it on detection after adding a new dependency. This is the way +how lockdep works. + +CONCLUSION + +Lockdep detects a deadlock or its possibility by checking if circular +dependencies were created after adding each new dependency. + + +========== +Limitation +========== + +Limit lockdep +------------- + +Limiting lockdep to work on only typical locks e.g. spin locks and +mutexes, which are released within the acquire context, the +implementation becomes simple but its capacity for detection becomes +limited. Let's check pros and cons in next section. + + +Pros from the limitation +------------------------ + +Given the limitation, when acquiring a lock, locks in a held_locks +cannot be released if the context cannot acquire it so has to wait to +acquire it, which means all waiters for the locks in the held_locks are +stuck. It's an exact case to create dependencies between each lock in +the held_locks and the lock to acquire. + +For example: + + CONTEXT X + --------- + acquire A + acquire B /* Add a dependency 'A -> B' */ + release B + release A + + where A and B are different lock classes. + +When acquiring lock A, the held_locks of CONTEXT X is empty thus no +dependency is added. But when acquiring lock B, lockdep detects and adds +a new dependency 'A -> B' between lock A in the held_locks and lock B. +They can be simply added whenever acquiring each lock. + +And data required by lockdep exists in a local structure, held_locks +embedded in task_struct. Forcing to access the data within the context, +lockdep can avoid racy problems without explicit locks while handling +the local data. + +Lastly, lockdep only needs to keep locks currently being held, to build +a dependency graph. However, relaxing the limitation, it needs to keep +even locks already released, because a decision whether they created +dependencies might be long-deferred. + +To sum up, we can expect several advantages from the limitation: + + 1. Lockdep can easily identify a dependency when acquiring a lock. + 2. Races are avoidable while accessing local locks in a held_locks. + 3. Lockdep only needs to keep locks currently being held. + +CONCLUSION + +Given the limitation, the implementation becomes simple and efficient. + + +Cons from the limitation +------------------------ + +Given the limitation, lockdep is applicable only to typical locks. For +example, page locks for page access or completions for synchronization +cannot work with lockdep. + +Can we detect deadlocks below, under the limitation? + +Example 1: + + CONTEXT X CONTEXT Y CONTEXT Z + --------- --------- ---------- + mutex_lock A + lock_page B + lock_page B + mutex_lock A /* DEADLOCK */ + unlock_page B held by X + unlock_page B + mutex_unlock A + mutex_unlock A + + where A and B are different lock classes. + +No, we cannot. + +Example 2: + + CONTEXT X CONTEXT Y + --------- --------- + mutex_lock A + mutex_lock A + wait_for_complete B /* DEADLOCK */ + complete B + mutex_unlock A + mutex_unlock A + + where A is a lock class and B is a completion variable. + +No, we cannot. + +CONCLUSION + +Given the limitation, lockdep cannot detect a deadlock or its +possibility caused by page locks or completions. + + +Relax the limitation +-------------------- + +Under the limitation, things to create dependencies are limited to +typical locks. However, synchronization primitives like page locks and +completions, which are allowed to be released in any context, also +create dependencies and can cause a deadlock. So lockdep should track +these locks to do a better job. We have to relax the limitation for +these locks to work with lockdep. + +Detecting dependencies is very important for lockdep to work because +adding a dependency means adding an opportunity to check whether it +causes a deadlock. The more lockdep adds dependencies, the more it +thoroughly works. Thus Lockdep has to do its best to detect and add as +many true dependencies into a graph as possible. + +For example, considering only typical locks, lockdep builds a graph like: + + A -> B - + \ + -> E + / + C -> D - + + where A, B,..., E are different lock classes. + +On the other hand, under the relaxation, additional dependencies might +be created and added. Assuming additional 'FX -> C' and 'E -> GX' are +added thanks to the relaxation, the graph will be: + + A -> B - + \ + -> E -> GX + / + FX -> C -> D - + + where A, B,..., E, FX and GX are different lock classes, and a suffix + 'X' is added on non-typical locks. + +The latter graph gives us more chances to check circular dependencies +than the former. However, it might suffer performance degradation since +relaxing the limitation, with which design and implementation of lockdep +can be efficient, might introduce inefficiency inevitably. So lockdep +should provide two options, strong detection and efficient detection. + +Choosing efficient detection: + + Lockdep works with only locks restricted to be released within the + acquire context. However, lockdep works efficiently. + +Choosing strong detection: + + Lockdep works with all synchronization primitives. However, lockdep + suffers performance degradation. + +CONCLUSION + +Relaxing the limitation, lockdep can add additional dependencies giving +additional opportunities to check circular dependencies. + + +============ +Crossrelease +============ + +Introduce crossrelease +---------------------- + +In order to allow lockdep to handle additional dependencies by what +might be released in any context, namely 'crosslock', we have to be able +to identify those created by crosslocks. The proposed 'crossrelease' +feature provoides a way to do that. + +Crossrelease feature has to do: + + 1. Identify dependencies created by crosslocks. + 2. Add the dependencies into a dependency graph. + +That's all. Once a meaningful dependency is added into graph, then +lockdep would work with the graph as it did. The most important thing +crossrelease feature has to do is to correctly identify and add true +dependencies into the global graph. + +A dependency e.g. 'A -> B' can be identified only in the A's release +context because a decision required to identify the dependency can be +made only in the release context. That is to decide whether A can be +released so that a waiter for A can be woken up. It cannot be made in +other than the A's release context. + +It's no matter for typical locks because each acquire context is same as +its release context, thus lockdep can decide whether a lock can be +released in the acquire context. However for crosslocks, lockdep cannot +make the decision in the acquire context but has to wait until the +release context is identified. + +Therefore, deadlocks by crosslocks cannot be detected just when it +happens, because those cannot be identified until the crosslocks are +released. However, deadlock possibilities can be detected and it's very +worth. See 'APPENDIX A' section to check why. + +CONCLUSION + +Using crossrelease feature, lockdep can work with what might be released +in any context, namely crosslock. + + +Introduce commit +---------------- + +Since crossrelease defers the work adding true dependencies of +crosslocks until they are actually released, crossrelease has to queue +all acquisitions which might create dependencies with the crosslocks. +Then it identifies dependencies using the queued data in batches at a +proper time. We call it 'commit'. + +There are four types of dependencies: + +1. TT type: 'typical lock A -> typical lock B' + + Just when acquiring B, lockdep can see it's in the A's release + context. So the dependency between A and B can be identified + immediately. Commit is unnecessary. + +2. TC type: 'typical lock A -> crosslock BX' + + Just when acquiring BX, lockdep can see it's in the A's release + context. So the dependency between A and BX can be identified + immediately. Commit is unnecessary, too. + +3. CT type: 'crosslock AX -> typical lock B' + + When acquiring B, lockdep cannot identify the dependency because + there's no way to know if it's in the AX's release context. It has + to wait until the decision can be made. Commit is necessary. + +4. CC type: 'crosslock AX -> crosslock BX' + + When acquiring BX, lockdep cannot identify the dependency because + there's no way to know if it's in the AX's release context. It has + to wait until the decision can be made. Commit is necessary. + But, handling CC type is not implemented yet. It's a future work. + +Lockdep can work without commit for typical locks, but commit step is +necessary once crosslocks are involved. Introducing commit, lockdep +performs three steps. What lockdep does in each step is: + +1. Acquisition: For typical locks, lockdep does what it originally did + and queues the lock so that CT type dependencies can be checked using + it at the commit step. For crosslocks, it saves data which will be + used at the commit step and increases a reference count for it. + +2. Commit: No action is reauired for typical locks. For crosslocks, + lockdep adds CT type dependencies using the data saved at the + acquisition step. + +3. Release: No changes are required for typical locks. When a crosslock + is released, it decreases a reference count for it. + +CONCLUSION + +Crossrelease introduces commit step to handle dependencies of crosslocks +in batches at a proper time. + + +============== +Implementation +============== + +Data structures +--------------- + +Crossrelease introduces two main data structures. + +1. hist_lock + + This is an array embedded in task_struct, for keeping lock history so + that dependencies can be added using them at the commit step. Since + it's local data, it can be accessed locklessly in the owner context. + The array is filled at the acquisition step and consumed at the + commit step. And it's managed in circular manner. + +2. cross_lock + + One per lockdep_map exists. This is for keeping data of crosslocks + and used at the commit step. + + +How crossrelease works +---------------------- + +It's the key of how crossrelease works, to defer necessary works to an +appropriate point in time and perform in at once at the commit step. +Let's take a look with examples step by step, starting from how lockdep +works without crossrelease for typical locks. + + acquire A /* Push A onto held_locks */ + acquire B /* Push B onto held_locks and add 'A -> B' */ + acquire C /* Push C onto held_locks and add 'B -> C' */ + release C /* Pop C from held_locks */ + release B /* Pop B from held_locks */ + release A /* Pop A from held_locks */ + + where A, B and C are different lock classes. + + NOTE: This document assumes that readers already understand how + lockdep works without crossrelease thus omits details. But there's + one thing to note. Lockdep pretends to pop a lock from held_locks + when releasing it. But it's subtly different from the original pop + operation because lockdep allows other than the top to be poped. + +In this case, lockdep adds 'the top of held_locks -> the lock to acquire' +dependency every time acquiring a lock. + +After adding 'A -> B', a dependency graph will be: + + A -> B + + where A and B are different lock classes. + +And after adding 'B -> C', the graph will be: + + A -> B -> C + + where A, B and C are different lock classes. + +Let's performs commit step even for typical locks to add dependencies. +Of course, commit step is not necessary for them, however, it would work +well because this is a more general way. + + acquire A + /* + * Queue A into hist_locks + * + * In hist_locks: A + * In graph: Empty + */ + + acquire B + /* + * Queue B into hist_locks + * + * In hist_locks: A, B + * In graph: Empty + */ + + acquire C + /* + * Queue C into hist_locks + * + * In hist_locks: A, B, C + * In graph: Empty + */ + + commit C + /* + * Add 'C -> ?' + * Answer the following to decide '?' + * What has been queued since acquire C: Nothing + * + * In hist_locks: A, B, C + * In graph: Empty + */ + + release C + + commit B + /* + * Add 'B -> ?' + * Answer the following to decide '?' + * What has been queued since acquire B: C + * + * In hist_locks: A, B, C + * In graph: 'B -> C' + */ + + release B + + commit A + /* + * Add 'A -> ?' + * Answer the following to decide '?' + * What has been queued since acquire A: B, C + * + * In hist_locks: A, B, C + * In graph: 'B -> C', 'A -> B', 'A -> C' + */ + + release A + + where A, B and C are different lock classes. + +In this case, dependencies are added at the commit step as described. + +After commits for A, B and C, the graph will be: + + A -> B -> C + + where A, B and C are different lock classes. + + NOTE: A dependency 'A -> C' is optimized out. + +We can see the former graph built without commit step is same as the +latter graph built using commit steps. Of course the former way leads to +earlier finish for building the graph, which means we can detect a +deadlock or its possibility sooner. So the former way would be prefered +when possible. But we cannot avoid using the latter way for crosslocks. + +Let's look at how commit steps work for crosslocks. In this case, the +commit step is performed only on crosslock AX as real. And it assumes +that the AX release context is different from the AX acquire context. + + BX RELEASE CONTEXT BX ACQUIRE CONTEXT + ------------------ ------------------ + acquire A + /* + * Push A onto held_locks + * Queue A into hist_locks + * + * In held_locks: A + * In hist_locks: A + * In graph: Empty + */ + + acquire BX + /* + * Add 'the top of held_locks -> BX' + * + * In held_locks: A + * In hist_locks: A + * In graph: 'A -> BX' + */ + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + It must be guaranteed that the following operations are seen after + acquiring BX globally. It can be done by things like barrier. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + acquire C + /* + * Push C onto held_locks + * Queue C into hist_locks + * + * In held_locks: C + * In hist_locks: C + * In graph: 'A -> BX' + */ + + release C + /* + * Pop C from held_locks + * + * In held_locks: Empty + * In hist_locks: C + * In graph: 'A -> BX' + */ + acquire D + /* + * Push D onto held_locks + * Queue D into hist_locks + * Add 'the top of held_locks -> D' + * + * In held_locks: A, D + * In hist_locks: A, D + * In graph: 'A -> BX', 'A -> D' + */ + acquire E + /* + * Push E onto held_locks + * Queue E into hist_locks + * + * In held_locks: E + * In hist_locks: C, E + * In graph: 'A -> BX', 'A -> D' + */ + + release E + /* + * Pop E from held_locks + * + * In held_locks: Empty + * In hist_locks: D, E + * In graph: 'A -> BX', 'A -> D' + */ + release D + /* + * Pop D from held_locks + * + * In held_locks: A + * In hist_locks: A, D + * In graph: 'A -> BX', 'A -> D' + */ + commit BX + /* + * Add 'BX -> ?' + * What has been queued since acquire BX: C, E + * + * In held_locks: Empty + * In hist_locks: D, E + * In graph: 'A -> BX', 'A -> D', + * 'BX -> C', 'BX -> E' + */ + + release BX + /* + * In held_locks: Empty + * In hist_locks: D, E + * In graph: 'A -> BX', 'A -> D', + * 'BX -> C', 'BX -> E' + */ + release A + /* + * Pop A from held_locks + * + * In held_locks: Empty + * In hist_locks: A, D + * In graph: 'A -> BX', 'A -> D', + * 'BX -> C', 'BX -> E' + */ + + where A, BX, C,..., E are different lock classes, and a suffix 'X' is + added on crosslocks. + +Crossrelease considers all acquisitions after acqiuring BX are +candidates which might create dependencies with BX. True dependencies +will be determined when identifying the release context of BX. Meanwhile, +all typical locks are queued so that they can be used at the commit step. +And then two dependencies 'BX -> C' and 'BX -> E' are added at the +commit step when identifying the release context. + +The final graph will be, with crossrelease: + + -> C + / + -> BX - + / \ + A - -> E + \ + -> D + + where A, BX, C,..., E are different lock classes, and a suffix 'X' is + added on crosslocks. + +However, the final graph will be, without crossrelease: + + A -> D + + where A and D are different lock classes. + +The former graph has three more dependencies, 'A -> BX', 'BX -> C' and +'BX -> E' giving additional opportunities to check if they cause +deadlocks. This way lockdep can detect a deadlock or its possibility +caused by crosslocks. + +CONCLUSION + +We checked how crossrelease works with several examples. + + +============= +Optimizations +============= + +Avoid duplication +----------------- + +Crossrelease feature uses a cache like what lockdep already uses for +dependency chains, but this time it's for caching CT type dependencies. +Once that dependency is cached, the same will never be added again. + + +Lockless for hot paths +---------------------- + +To keep all locks for later use at the commit step, crossrelease adopts +a local array embedded in task_struct, which makes access to the data +lockless by forcing it to happen only within the owner context. It's +like how lockdep handles held_locks. Lockless implmentation is important +since typical locks are very frequently acquired and released. + + +================================================= +APPENDIX A: What lockdep does to work aggresively +================================================= + +A deadlock actually occurs when all wait operations creating circular +dependencies run at the same time. Even though they don't, a potential +deadlock exists if the problematic dependencies exist. Thus it's +meaningful to detect not only an actual deadlock but also its potential +possibility. The latter is rather valuable. When a deadlock occurs +actually, we can identify what happens in the system by some means or +other even without lockdep. However, there's no way to detect possiblity +without lockdep unless the whole code is parsed in head. It's terrible. +Lockdep does the both, and crossrelease only focuses on the latter. + +Whether or not a deadlock actually occurs depends on several factors. +For example, what order contexts are switched in is a factor. Assuming +circular dependencies exist, a deadlock would occur when contexts are +switched so that all wait operations creating the dependencies run +simultaneously. Thus to detect a deadlock possibility even in the case +that it has not occured yet, lockdep should consider all possible +combinations of dependencies, trying to: + +1. Use a global dependency graph. + + Lockdep combines all dependencies into one global graph and uses them, + regardless of which context generates them or what order contexts are + switched in. Aggregated dependencies are only considered so they are + prone to be circular if a problem exists. + +2. Check dependencies between classes instead of instances. + + What actually causes a deadlock are instances of lock. However, + lockdep checks dependencies between classes instead of instances. + This way lockdep can detect a deadlock which has not happened but + might happen in future by others but the same class. + +3. Assume all acquisitions lead to waiting. + + Although locks might be acquired without waiting which is essential + to create dependencies, lockdep assumes all acquisitions lead to + waiting since it might be true some time or another. + +CONCLUSION + +Lockdep detects not only an actual deadlock but also its possibility, +and the latter is more valuable. + + +================================================== +APPENDIX B: How to avoid adding false dependencies +================================================== + +Remind what a dependency is. A dependency exists if: + + 1. There are two waiters waiting for each event at a given time. + 2. The only way to wake up each waiter is to trigger its event. + 3. Whether one can be woken up depends on whether the other can. + +For example: + + acquire A + acquire B /* A dependency 'A -> B' exists */ + release B + release A + + where A and B are different lock classes. + +A depedency 'A -> B' exists since: + + 1. A waiter for A and a waiter for B might exist when acquiring B. + 2. Only way to wake up each is to release what it waits for. + 3. Whether the waiter for A can be woken up depends on whether the + other can. IOW, TASK X cannot release A if it fails to acquire B. + +For another example: + + TASK X TASK Y + ------ ------ + acquire AX + acquire B /* A dependency 'AX -> B' exists */ + release B + release AX held by Y + + where AX and B are different lock classes, and a suffix 'X' is added + on crosslocks. + +Even in this case involving crosslocks, the same rule can be applied. A +depedency 'AX -> B' exists since: + + 1. A waiter for AX and a waiter for B might exist when acquiring B. + 2. Only way to wake up each is to release what it waits for. + 3. Whether the waiter for AX can be woken up depends on whether the + other can. IOW, TASK X cannot release AX if it fails to acquire B. + +Let's take a look at more complicated example: + + TASK X TASK Y + ------ ------ + acquire B + release B + fork Y + acquire AX + acquire C /* A dependency 'AX -> C' exists */ + release C + release AX held by Y + + where AX, B and C are different lock classes, and a suffix 'X' is + added on crosslocks. + +Does a dependency 'AX -> B' exist? Nope. + +Two waiters are essential to create a dependency. However, waiters for +AX and B to create 'AX -> B' cannot exist at the same time in this +example. Thus the dependency 'AX -> B' cannot be created. + +It would be ideal if the full set of true ones can be considered. But +we can ensure nothing but what actually happened. Relying on what +actually happens at runtime, we can anyway add only true ones, though +they might be a subset of true ones. It's similar to how lockdep works +for typical locks. There might be more true dependencies than what +lockdep has detected in runtime. Lockdep has no choice but to rely on +what actually happens. Crossrelease also relies on it. + +CONCLUSION + +Relying on what actually happens, lockdep can avoid adding false +dependencies. diff --git a/Documentation/locking/rt-mutex-design.txt b/Documentation/locking/rt-mutex-design.txt index 8666070d31896eeb0c54f820189b14d95bd1833d..6c6e8c2410de390dafa0319d694a6df42000ed6b 100644 --- a/Documentation/locking/rt-mutex-design.txt +++ b/Documentation/locking/rt-mutex-design.txt @@ -97,9 +97,9 @@ waiter - A waiter is a struct that is stored on the stack of a blocked a process being blocked on the mutex, it is fine to allocate the waiter on the process's stack (local variable). This structure holds a pointer to the task, as well as the mutex that - the task is blocked on. It also has the plist node structures to - place the task in the waiter_list of a mutex as well as the - pi_list of a mutex owner task (described below). + the task is blocked on. It also has rbtree node structures to + place the task in the waiters rbtree of a mutex as well as the + pi_waiters rbtree of a mutex owner task (described below). waiter is sometimes used in reference to the task that is waiting on a mutex. This is the same as waiter->task. @@ -179,53 +179,34 @@ again. | F->L5-+ +If process G has the highest priority in the chain, then all the tasks up +the chain (A and B in this example), must have their priorities increased +to that of G. -Plist ------ - -Before I go further and talk about how the PI chain is stored through lists -on both mutexes and processes, I'll explain the plist. This is similar to -the struct list_head functionality that is already in the kernel. -The implementation of plist is out of scope for this document, but it is -very important to understand what it does. - -There are a few differences between plist and list, the most important one -being that plist is a priority sorted linked list. This means that the -priorities of the plist are sorted, such that it takes O(1) to retrieve the -highest priority item in the list. Obviously this is useful to store processes -based on their priorities. - -Another difference, which is important for implementation, is that, unlike -list, the head of the list is a different element than the nodes of a list. -So the head of the list is declared as struct plist_head and nodes that will -be added to the list are declared as struct plist_node. - - -Mutex Waiter List +Mutex Waiters Tree ----------------- -Every mutex keeps track of all the waiters that are blocked on itself. The mutex -has a plist to store these waiters by priority. This list is protected by -a spin lock that is located in the struct of the mutex. This lock is called -wait_lock. Since the modification of the waiter list is never done in -interrupt context, the wait_lock can be taken without disabling interrupts. +Every mutex keeps track of all the waiters that are blocked on itself. The +mutex has a rbtree to store these waiters by priority. This tree is protected +by a spin lock that is located in the struct of the mutex. This lock is called +wait_lock. -Task PI List +Task PI Tree ------------ -To keep track of the PI chains, each process has its own PI list. This is -a list of all top waiters of the mutexes that are owned by the process. -Note that this list only holds the top waiters and not all waiters that are +To keep track of the PI chains, each process has its own PI rbtree. This is +a tree of all top waiters of the mutexes that are owned by the process. +Note that this tree only holds the top waiters and not all waiters that are blocked on mutexes owned by the process. -The top of the task's PI list is always the highest priority task that +The top of the task's PI tree is always the highest priority task that is waiting on a mutex that is owned by the task. So if the task has inherited a priority, it will always be the priority of the task that is -at the top of this list. +at the top of this tree. -This list is stored in the task structure of a process as a plist called -pi_list. This list is protected by a spin lock also in the task structure, +This tree is stored in the task structure of a process as a rbtree called +pi_waiters. It is protected by a spin lock also in the task structure, called pi_lock. This lock may also be taken in interrupt context, so when locking the pi_lock, interrupts must be disabled. @@ -312,15 +293,12 @@ Mutex owner and flags The mutex structure contains a pointer to the owner of the mutex. If the mutex is not owned, this owner is set to NULL. Since all architectures -have the task structure on at least a four byte alignment (and if this is -not true, the rtmutex.c code will be broken!), this allows for the two -least significant bits to be used as flags. This part is also described -in Documentation/rt-mutex.txt, but will also be briefly described here. - -Bit 0 is used as the "Pending Owner" flag. This is described later. -Bit 1 is used as the "Has Waiters" flags. This is also described later - in more detail, but is set whenever there are waiters on a mutex. +have the task structure on at least a two byte alignment (and if this is +not true, the rtmutex.c code will be broken!), this allows for the least +significant bit to be used as a flag. Bit 0 is used as the "Has Waiters" +flag. It's set whenever there are waiters on a mutex. +See Documentation/locking/rt-mutex.txt for further details. cmpxchg Tricks -------------- @@ -359,40 +337,31 @@ Priority adjustments -------------------- The implementation of the PI code in rtmutex.c has several places that a -process must adjust its priority. With the help of the pi_list of a +process must adjust its priority. With the help of the pi_waiters of a process this is rather easy to know what needs to be adjusted. -The functions implementing the task adjustments are rt_mutex_adjust_prio, -__rt_mutex_adjust_prio (same as the former, but expects the task pi_lock -to already be taken), rt_mutex_getprio, and rt_mutex_setprio. +The functions implementing the task adjustments are rt_mutex_adjust_prio +and rt_mutex_setprio. rt_mutex_setprio is only used in rt_mutex_adjust_prio. -rt_mutex_getprio and rt_mutex_setprio are only used in __rt_mutex_adjust_prio. +rt_mutex_adjust_prio examines the priority of the task, and the highest +priority process that is waiting any of mutexes owned by the task. Since +the pi_waiters of a task holds an order by priority of all the top waiters +of all the mutexes that the task owns, we simply need to compare the top +pi waiter to its own normal/deadline priority and take the higher one. +Then rt_mutex_setprio is called to adjust the priority of the task to the +new priority. Note that rt_mutex_setprio is defined in kernel/sched/core.c +to implement the actual change in priority. -rt_mutex_getprio returns the priority that the task should have. Either the -task's own normal priority, or if a process of a higher priority is waiting on -a mutex owned by the task, then that higher priority should be returned. -Since the pi_list of a task holds an order by priority list of all the top -waiters of all the mutexes that the task owns, rt_mutex_getprio simply needs -to compare the top pi waiter to its own normal priority, and return the higher -priority back. +(Note: For the "prio" field in task_struct, the lower the number, the + higher the priority. A "prio" of 5 is of higher priority than a + "prio" of 10.) -(Note: if looking at the code, you will notice that the lower number of - prio is returned. This is because the prio field in the task structure - is an inverse order of the actual priority. So a "prio" of 5 is - of higher priority than a "prio" of 10.) - -__rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the -result does not equal the task's current priority, then rt_mutex_setprio -is called to adjust the priority of the task to the new priority. -Note that rt_mutex_setprio is defined in kernel/sched/core.c to implement the -actual change in priority. - -It is interesting to note that __rt_mutex_adjust_prio can either increase +It is interesting to note that rt_mutex_adjust_prio can either increase or decrease the priority of the task. In the case that a higher priority -process has just blocked on a mutex owned by the task, __rt_mutex_adjust_prio +process has just blocked on a mutex owned by the task, rt_mutex_adjust_prio would increase/boost the task's priority. But if a higher priority task were for some reason to leave the mutex (timeout or signal), this same function -would decrease/unboost the priority of the task. That is because the pi_list +would decrease/unboost the priority of the task. That is because the pi_waiters always contains the highest priority task that is waiting on a mutex owned by the task, so we only need to compare the priority of that top pi waiter to the normal priority of the given task. @@ -412,9 +381,10 @@ priorities. rt_mutex_adjust_prio_chain is called with a task to be checked for PI (de)boosting (the owner of a mutex that a process is blocking on), a flag to -check for deadlocking, the mutex that the task owns, and a pointer to a waiter +check for deadlocking, the mutex that the task owns, a pointer to a waiter that is the process's waiter struct that is blocked on the mutex (although this -parameter may be NULL for deboosting). +parameter may be NULL for deboosting), a pointer to the mutex on which the task +is blocked, and a top_task as the top waiter of the mutex. For this explanation, I will not mention deadlock detection. This explanation will try to stay at a high level. @@ -424,133 +394,14 @@ that the state of the owner and lock can change when entered into this function. Before this function is called, the task has already had rt_mutex_adjust_prio performed on it. This means that the task is set to the priority that it -should be at, but the plist nodes of the task's waiter have not been updated -with the new priorities, and that this task may not be in the proper locations -in the pi_lists and wait_lists that the task is blocked on. This function +should be at, but the rbtree nodes of the task's waiter have not been updated +with the new priorities, and this task may not be in the proper locations +in the pi_waiters and waiters trees that the task is blocked on. This function solves all that. -A loop is entered, where task is the owner to be checked for PI changes that -was passed by parameter (for the first iteration). The pi_lock of this task is -taken to prevent any more changes to the pi_list of the task. This also -prevents new tasks from completing the blocking on a mutex that is owned by this -task. - -If the task is not blocked on a mutex then the loop is exited. We are at -the top of the PI chain. - -A check is now done to see if the original waiter (the process that is blocked -on the current mutex) is the top pi waiter of the task. That is, is this -waiter on the top of the task's pi_list. If it is not, it either means that -there is another process higher in priority that is blocked on one of the -mutexes that the task owns, or that the waiter has just woken up via a signal -or timeout and has left the PI chain. In either case, the loop is exited, since -we don't need to do any more changes to the priority of the current task, or any -task that owns a mutex that this current task is waiting on. A priority chain -walk is only needed when a new top pi waiter is made to a task. - -The next check sees if the task's waiter plist node has the priority equal to -the priority the task is set at. If they are equal, then we are done with -the loop. Remember that the function started with the priority of the -task adjusted, but the plist nodes that hold the task in other processes -pi_lists have not been adjusted. - -Next, we look at the mutex that the task is blocked on. The mutex's wait_lock -is taken. This is done by a spin_trylock, because the locking order of the -pi_lock and wait_lock goes in the opposite direction. If we fail to grab the -lock, the pi_lock is released, and we restart the loop. - -Now that we have both the pi_lock of the task as well as the wait_lock of -the mutex the task is blocked on, we update the task's waiter's plist node -that is located on the mutex's wait_list. - -Now we release the pi_lock of the task. - -Next the owner of the mutex has its pi_lock taken, so we can update the -task's entry in the owner's pi_list. If the task is the highest priority -process on the mutex's wait_list, then we remove the previous top waiter -from the owner's pi_list, and replace it with the task. - -Note: It is possible that the task was the current top waiter on the mutex, - in which case the task is not yet on the pi_list of the waiter. This - is OK, since plist_del does nothing if the plist node is not on any - list. - -If the task was not the top waiter of the mutex, but it was before we -did the priority updates, that means we are deboosting/lowering the -task. In this case, the task is removed from the pi_list of the owner, -and the new top waiter is added. - -Lastly, we unlock both the pi_lock of the task, as well as the mutex's -wait_lock, and continue the loop again. On the next iteration of the -loop, the previous owner of the mutex will be the task that will be -processed. - -Note: One might think that the owner of this mutex might have changed - since we just grab the mutex's wait_lock. And one could be right. - The important thing to remember is that the owner could not have - become the task that is being processed in the PI chain, since - we have taken that task's pi_lock at the beginning of the loop. - So as long as there is an owner of this mutex that is not the same - process as the tasked being worked on, we are OK. - - Looking closely at the code, one might be confused. The check for the - end of the PI chain is when the task isn't blocked on anything or the - task's waiter structure "task" element is NULL. This check is - protected only by the task's pi_lock. But the code to unlock the mutex - sets the task's waiter structure "task" element to NULL with only - the protection of the mutex's wait_lock, which was not taken yet. - Isn't this a race condition if the task becomes the new owner? - - The answer is No! The trick is the spin_trylock of the mutex's - wait_lock. If we fail that lock, we release the pi_lock of the - task and continue the loop, doing the end of PI chain check again. - - In the code to release the lock, the wait_lock of the mutex is held - the entire time, and it is not let go when we grab the pi_lock of the - new owner of the mutex. So if the switch of a new owner were to happen - after the check for end of the PI chain and the grabbing of the - wait_lock, the unlocking code would spin on the new owner's pi_lock - but never give up the wait_lock. So the PI chain loop is guaranteed to - fail the spin_trylock on the wait_lock, release the pi_lock, and - try again. - - If you don't quite understand the above, that's OK. You don't have to, - unless you really want to make a proof out of it ;) - - -Pending Owners and Lock stealing --------------------------------- - -One of the flags in the owner field of the mutex structure is "Pending Owner". -What this means is that an owner was chosen by the process releasing the -mutex, but that owner has yet to wake up and actually take the mutex. - -Why is this important? Why can't we just give the mutex to another process -and be done with it? - -The PI code is to help with real-time processes, and to let the highest -priority process run as long as possible with little latencies and delays. -If a high priority process owns a mutex that a lower priority process is -blocked on, when the mutex is released it would be given to the lower priority -process. What if the higher priority process wants to take that mutex again. -The high priority process would fail to take that mutex that it just gave up -and it would need to boost the lower priority process to run with full -latency of that critical section (since the low priority process just entered -it). - -There's no reason a high priority process that gives up a mutex should be -penalized if it tries to take that mutex again. If the new owner of the -mutex has not woken up yet, there's no reason that the higher priority process -could not take that mutex away. - -To solve this, we introduced Pending Ownership and Lock Stealing. When a -new process is given a mutex that it was blocked on, it is only given -pending ownership. This means that it's the new owner, unless a higher -priority process comes in and tries to grab that mutex. If a higher priority -process does come along and wants that mutex, we let the higher priority -process "steal" the mutex from the pending owner (only if it is still pending) -and continue with the mutex. - +The main operation of this function is summarized by Thomas Gleixner in +rtmutex.c. See the 'Chain walk basics and protection scope' comment for further +details. Taking of a mutex (The walk through) ------------------------------------ @@ -563,14 +414,14 @@ done when we have CMPXCHG enabled (otherwise the fast taking automatically fails). Only when the owner field of the mutex is NULL can the lock be taken with the CMPXCHG and nothing else needs to be done. -If there is contention on the lock, whether it is owned or pending owner -we go about the slow path (rt_mutex_slowlock). +If there is contention on the lock, we go about the slow path +(rt_mutex_slowlock). The slow path function is where the task's waiter structure is created on the stack. This is because the waiter structure is only needed for the scope of this function. The waiter structure holds the nodes to store -the task on the wait_list of the mutex, and if need be, the pi_list of -the owner. +the task on the waiters tree of the mutex, and if need be, the pi_waiters +tree of the owner. The wait_lock of the mutex is taken since the slow path of unlocking the mutex also takes this lock. @@ -581,102 +432,45 @@ contention). try_to_take_rt_mutex is used every time the task tries to grab a mutex in the slow path. The first thing that is done here is an atomic setting of -the "Has Waiters" flag of the mutex's owner field. Yes, this could really -be false, because if the mutex has no owner, there are no waiters and -the current task also won't have any waiters. But we don't have the lock -yet, so we assume we are going to be a waiter. The reason for this is to -play nice for those architectures that do have CMPXCHG. By setting this flag -now, the owner of the mutex can't release the mutex without going into the -slow unlock path, and it would then need to grab the wait_lock, which this -code currently holds. So setting the "Has Waiters" flag forces the owner -to synchronize with this code. - -Now that we know that we can't have any races with the owner releasing the -mutex, we check to see if we can take the ownership. This is done if the -mutex doesn't have a owner, or if we can steal the mutex from a pending -owner. Let's look at the situations we have here. - - 1) Has owner that is pending - ---------------------------- - - The mutex has a owner, but it hasn't woken up and the mutex flag - "Pending Owner" is set. The first check is to see if the owner isn't the - current task. This is because this function is also used for the pending - owner to grab the mutex. When a pending owner wakes up, it checks to see - if it can take the mutex, and this is done if the owner is already set to - itself. If so, we succeed and leave the function, clearing the "Pending - Owner" bit. - - If the pending owner is not current, we check to see if the current priority is - higher than the pending owner. If not, we fail the function and return. - - There's also something special about a pending owner. That is a pending owner - is never blocked on a mutex. So there is no PI chain to worry about. It also - means that if the mutex doesn't have any waiters, there's no accounting needed - to update the pending owner's pi_list, since we only worry about processes - blocked on the current mutex. - - If there are waiters on this mutex, and we just stole the ownership, we need - to take the top waiter, remove it from the pi_list of the pending owner, and - add it to the current pi_list. Note that at this moment, the pending owner - is no longer on the list of waiters. This is fine, since the pending owner - would add itself back when it realizes that it had the ownership stolen - from itself. When the pending owner tries to grab the mutex, it will fail - in try_to_take_rt_mutex if the owner field points to another process. - - 2) No owner - ----------- - - If there is no owner (or we successfully stole the lock), we set the owner - of the mutex to current, and set the flag of "Has Waiters" if the current - mutex actually has waiters, or we clear the flag if it doesn't. See, it was - OK that we set that flag early, since now it is cleared. - - 3) Failed to grab ownership - --------------------------- - - The most interesting case is when we fail to take ownership. This means that - there exists an owner, or there's a pending owner with equal or higher - priority than the current task. - -We'll continue on the failed case. - -If the mutex has a timeout, we set up a timer to go off to break us out -of this mutex if we failed to get it after a specified amount of time. - -Now we enter a loop that will continue to try to take ownership of the mutex, or -fail from a timeout or signal. - -Once again we try to take the mutex. This will usually fail the first time -in the loop, since it had just failed to get the mutex. But the second time -in the loop, this would likely succeed, since the task would likely be -the pending owner. - -If the mutex is TASK_INTERRUPTIBLE a check for signals and timeout is done -here. - -The waiter structure has a "task" field that points to the task that is blocked -on the mutex. This field can be NULL the first time it goes through the loop -or if the task is a pending owner and had its mutex stolen. If the "task" -field is NULL then we need to set up the accounting for it. +the "Has Waiters" flag of the mutex's owner field. By setting this flag +now, the current owner of the mutex being contended for can't release the mutex +without going into the slow unlock path, and it would then need to grab the +wait_lock, which this code currently holds. So setting the "Has Waiters" flag +forces the current owner to synchronize with this code. + +The lock is taken if the following are true: + 1) The lock has no owner + 2) The current task is the highest priority against all other + waiters of the lock + +If the task succeeds to acquire the lock, then the task is set as the +owner of the lock, and if the lock still has waiters, the top_waiter +(highest priority task waiting on the lock) is added to this task's +pi_waiters tree. + +If the lock is not taken by try_to_take_rt_mutex(), then the +task_blocks_on_rt_mutex() function is called. This will add the task to +the lock's waiter tree and propagate the pi chain of the lock as well +as the lock's owner's pi_waiters tree. This is described in the next +section. Task blocks on mutex -------------------- The accounting of a mutex and process is done with the waiter structure of the process. The "task" field is set to the process, and the "lock" field -to the mutex. The plist nodes are initialized to the processes current -priority. +to the mutex. The rbtree node of waiter are initialized to the processes +current priority. Since the wait_lock was taken at the entry of the slow lock, we can safely -add the waiter to the wait_list. If the current process is the highest -priority process currently waiting on this mutex, then we remove the -previous top waiter process (if it exists) from the pi_list of the owner, -and add the current process to that list. Since the pi_list of the owner +add the waiter to the task waiter tree. If the current process is the +highest priority process currently waiting on this mutex, then we remove the +previous top waiter process (if it exists) from the pi_waiters of the owner, +and add the current process to that tree. Since the pi_waiter of the owner has changed, we call rt_mutex_adjust_prio on the owner to see if the owner should adjust its priority accordingly. -If the owner is also blocked on a lock, and had its pi_list changed +If the owner is also blocked on a lock, and had its pi_waiters changed (or deadlock checking is on), we unlock the wait_lock of the mutex and go ahead and run rt_mutex_adjust_prio_chain on the owner, as described earlier. @@ -686,30 +480,23 @@ mutex (waiter "task" field is not NULL), then we go to sleep (call schedule). Waking up in the loop --------------------- -The schedule can then wake up for a few reasons. - 1) we were given pending ownership of the mutex. - 2) we received a signal and was TASK_INTERRUPTIBLE - 3) we had a timeout and was TASK_INTERRUPTIBLE +The task can then wake up for a couple of reasons: + 1) The previous lock owner released the lock, and the task now is top_waiter + 2) we received a signal or timeout -In any of these cases, we continue the loop and once again try to grab the -ownership of the mutex. If we succeed, we exit the loop, otherwise we continue -and on signal and timeout, will exit the loop, or if we had the mutex stolen -we just simply add ourselves back on the lists and go back to sleep. +In both cases, the task will try again to acquire the lock. If it +does, then it will take itself off the waiters tree and set itself back +to the TASK_RUNNING state. -Note: For various reasons, because of timeout and signals, the steal mutex - algorithm needs to be careful. This is because the current process is - still on the wait_list. And because of dynamic changing of priorities, - especially on SCHED_OTHER tasks, the current process can be the - highest priority task on the wait_list. - -Failed to get mutex on Timeout or Signal ----------------------------------------- +In first case, if the lock was acquired by another task before this task +could get the lock, then it will go back to sleep and wait to be woken again. -If a timeout or signal occurred, the waiter's "task" field would not be -NULL and the task needs to be taken off the wait_list of the mutex and perhaps -pi_list of the owner. If this process was a high priority process, then -the rt_mutex_adjust_prio_chain needs to be executed again on the owner, -but this time it will be lowering the priorities. +The second case is only applicable for tasks that are grabbing a mutex +that can wake up before getting the lock, either due to a signal or +a timeout (i.e. rt_mutex_timed_futex_lock()). When woken, it will try to +take the lock again, if it succeeds, then the task will return with the +lock held, otherwise it will return with -EINTR if the task was woken +by a signal, or -ETIMEDOUT if it timed out. Unlocking the Mutex @@ -739,25 +526,12 @@ owner still needs to make this check. If there are no waiters then the mutex owner field is set to NULL, the wait_lock is released and nothing more is needed. -If there are waiters, then we need to wake one up and give that waiter -pending ownership. +If there are waiters, then we need to wake one up. On the wake up code, the pi_lock of the current owner is taken. The top -waiter of the lock is found and removed from the wait_list of the mutex -as well as the pi_list of the current owner. The task field of the new -pending owner's waiter structure is set to NULL, and the owner field of the -mutex is set to the new owner with the "Pending Owner" bit set, as well -as the "Has Waiters" bit if there still are other processes blocked on the -mutex. - -The pi_lock of the previous owner is released, and the new pending owner's -pi_lock is taken. Remember that this is the trick to prevent the race -condition in rt_mutex_adjust_prio_chain from adding itself as a waiter -on the mutex. - -We now clear the "pi_blocked_on" field of the new pending owner, and if -the mutex still has waiters pending, we add the new top waiter to the pi_list -of the pending owner. +waiter of the lock is found and removed from the waiters tree of the mutex +as well as the pi_waiters tree of the current owner. The "Has Waiters" bit is +marked to prevent lower priority tasks from stealing the lock. Finally we unlock the pi_lock of the pending owner and wake it up. @@ -772,10 +546,14 @@ Credits ------- Author: Steven Rostedt +Updated: Alex Shi - 7/6/2017 -Reviewers: Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and Randy Dunlap +Original Reviewers: Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and + Randy Dunlap +Update (7/6/2017) Reviewers: Steven Rostedt and Sebastian Siewior Updates ------- This document was originally written for 2.6.17-rc3-mm1 +was updated on 4.12 diff --git a/Documentation/locking/rt-mutex.txt b/Documentation/locking/rt-mutex.txt index 243393d882ee7ed5fc70ddb8679afa390c61dead..35793e003041dc7ec568b51bcfc9667c6db0e780 100644 --- a/Documentation/locking/rt-mutex.txt +++ b/Documentation/locking/rt-mutex.txt @@ -28,14 +28,13 @@ magic bullet for poorly designed applications, but it allows well-designed applications to use userspace locks in critical parts of an high priority thread, without losing determinism. -The enqueueing of the waiters into the rtmutex waiter list is done in +The enqueueing of the waiters into the rtmutex waiter tree is done in priority order. For same priorities FIFO order is chosen. For each rtmutex, only the top priority waiter is enqueued into the owner's -priority waiters list. This list too queues in priority order. Whenever +priority waiters tree. This tree too queues in priority order. Whenever the top priority waiter of a task changes (for example it timed out or -got a signal), the priority of the owner task is readjusted. [The -priority enqueueing is handled by "plists", see include/linux/plist.h -for more details.] +got a signal), the priority of the owner task is readjusted. The +priority enqueueing is handled by "pi_waiters". RT-mutexes are optimized for fastpath operations and have no internal locking overhead when locking an uncontended mutex or unlocking a mutex @@ -46,34 +45,29 @@ is used] The state of the rt-mutex is tracked via the owner field of the rt-mutex structure: -rt_mutex->owner holds the task_struct pointer of the owner. Bit 0 and 1 -are used to keep track of the "owner is pending" and "rtmutex has -waiters" state. +lock->owner holds the task_struct pointer of the owner. Bit 0 is used to +keep track of the "lock has waiters" state. - owner bit1 bit0 - NULL 0 0 mutex is free (fast acquire possible) - NULL 0 1 invalid state - NULL 1 0 Transitional state* - NULL 1 1 invalid state - taskpointer 0 0 mutex is held (fast release possible) - taskpointer 0 1 task is pending owner - taskpointer 1 0 mutex is held and has waiters - taskpointer 1 1 task is pending owner and mutex has waiters + owner bit0 + NULL 0 lock is free (fast acquire possible) + NULL 1 lock is free and has waiters and the top waiter + is going to take the lock* + taskpointer 0 lock is held (fast release possible) + taskpointer 1 lock is held and has waiters** -Pending-ownership handling is a performance optimization: -pending-ownership is assigned to the first (highest priority) waiter of -the mutex, when the mutex is released. The thread is woken up and once -it starts executing it can acquire the mutex. Until the mutex is taken -by it (bit 0 is cleared) a competing higher priority thread can "steal" -the mutex which puts the woken up thread back on the waiters list. +The fast atomic compare exchange based acquire and release is only +possible when bit 0 of lock->owner is 0. -The pending-ownership optimization is especially important for the -uninterrupted workflow of high-prio tasks which repeatedly -takes/releases locks that have lower-prio waiters. Without this -optimization the higher-prio thread would ping-pong to the lower-prio -task [because at unlock time we always assign a new owner]. +(*) It also can be a transitional state when grabbing the lock +with ->wait_lock is held. To prevent any fast path cmpxchg to the lock, +we need to set the bit0 before looking at the lock, and the owner may be +NULL in this small time, hence this can be a transitional state. -(*) The "mutex has waiters" bit gets set to take the lock. If the lock -doesn't already have an owner, this bit is quickly cleared if there are -no waiters. So this is a transitional state to synchronize with looking -at the owner field of the mutex and the mutex owner releasing the lock. +(**) There is a small time when bit 0 is set but there are no +waiters. This can happen when grabbing the lock in the slow path. +To prevent a cmpxchg of the owner releasing the lock, we need to +set this bit before looking at the lock. + +BTW, there is still technically a "Pending Owner", it's just not called +that anymore. The pending owner happens to be the top_waiter of a lock +that has no owner and has been woken up to grab the lock. diff --git a/Documentation/media/ca.h.rst.exceptions b/Documentation/media/ca.h.rst.exceptions index d7c9fed8c0044b650c7fc4b223e2557c52458632..553559cc6ad7de7148ec8ef84f3584b9c1760b2e 100644 --- a/Documentation/media/ca.h.rst.exceptions +++ b/Documentation/media/ca.h.rst.exceptions @@ -16,7 +16,6 @@ replace define CA_NDS :c:type:`ca_descr_info` replace define CA_DSS :c:type:`ca_descr_info` # some typedefs should point to struct/enums -replace typedef ca_pid_t :c:type:`ca_pid` replace typedef ca_slot_info_t :c:type:`ca_slot_info` replace typedef ca_descr_info_t :c:type:`ca_descr_info` replace typedef ca_caps_t :c:type:`ca_caps` diff --git a/Documentation/media/cec-drivers/index.rst b/Documentation/media/cec-drivers/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..7ef204823422659b4545e42239fbc338f7e3717f --- /dev/null +++ b/Documentation/media/cec-drivers/index.rst @@ -0,0 +1,34 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. include:: + +.. _cec-drivers: + +################################# +CEC driver-specific documentation +################################# + +**Copyright** |copy| 2017 : LinuxTV Developers + +This documentation is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +For more details see the file COPYING in the source distribution of Linux. + +.. only:: html + + .. class:: toc-title + + Table of Contents + +.. toctree:: + :maxdepth: 5 + :numbered: + + pulse8-cec diff --git a/Documentation/media/cec-drivers/pulse8-cec.rst b/Documentation/media/cec-drivers/pulse8-cec.rst new file mode 100644 index 0000000000000000000000000000000000000000..99551c6a9bc59f6a8d8ff3cc4f90801e2344eeb6 --- /dev/null +++ b/Documentation/media/cec-drivers/pulse8-cec.rst @@ -0,0 +1,11 @@ +Pulse-Eight CEC Adapter driver +============================== + +The pulse8-cec driver implements the following module option: + +``persistent_config`` +--------------------- + +By default this is off, but when set to 1 the driver will store the current +settings to the device's internal eeprom and restore it the next time the +device is connected to the USB port. diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions index 2fdb458564baf6043dde9cac1b6206364aeac4d5..629db384104a82dc733a4c98d0078c882c61f486 100644 --- a/Documentation/media/dmx.h.rst.exceptions +++ b/Documentation/media/dmx.h.rst.exceptions @@ -40,27 +40,17 @@ replace enum dmx_input :c:type:`dmx_input` replace symbol DMX_IN_FRONTEND :c:type:`dmx_input` replace symbol DMX_IN_DVR :c:type:`dmx_input` -# dmx_source_t symbols -replace enum dmx_source :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT0 :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT1 :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT2 :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT3 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR0 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR1 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR2 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR3 :c:type:`dmx_source` - - # Flags for struct dmx_sct_filter_params replace define DMX_CHECK_CRC :c:type:`dmx_sct_filter_params` replace define DMX_ONESHOT :c:type:`dmx_sct_filter_params` replace define DMX_IMMEDIATE_START :c:type:`dmx_sct_filter_params` -replace define DMX_KERNEL_CLIENT :c:type:`dmx_sct_filter_params` # some typedefs should point to struct/enums -replace typedef dmx_caps_t :c:type:`dmx_caps` replace typedef dmx_filter_t :c:type:`dmx_filter` replace typedef dmx_pes_type_t :c:type:`dmx_pes_type` replace typedef dmx_input_t :c:type:`dmx_input` -replace typedef dmx_source_t :c:type:`dmx_source` + +ignore symbol DMX_OUT_DECODER +ignore symbol DMX_OUT_TAP +ignore symbol DMX_OUT_TS_TAP +ignore symbol DMX_OUT_TSDEMUX_TAP diff --git a/Documentation/media/dvb-drivers/ci.rst b/Documentation/media/dvb-drivers/ci.rst index 69b07e9d18163f9de676686ab9cb29ff0121ea44..87f3748c49b94c204ac09e899e0a381a631c0bfa 100644 --- a/Documentation/media/dvb-drivers/ci.rst +++ b/Documentation/media/dvb-drivers/ci.rst @@ -143,7 +143,6 @@ All these ioctls are also valid for the High level CI interface #define CA_GET_MSG _IOR('o', 132, ca_msg_t) #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) #define CA_SET_DESCR _IOW('o', 134, ca_descr_t) -#define CA_SET_PID _IOW('o', 135, ca_pid_t) On querying the device, the device yields information thus: diff --git a/Documentation/media/dvb-drivers/index.rst b/Documentation/media/dvb-drivers/index.rst index ea0da6d63299918ab334cd8df1316d9c61c96380..376141143ae91d46a953b49bc9338fd7c9d9b203 100644 --- a/Documentation/media/dvb-drivers/index.rst +++ b/Documentation/media/dvb-drivers/index.rst @@ -19,7 +19,9 @@ more details. For more details see the file COPYING in the source distribution of Linux. -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/frontend.h.rst.exceptions b/Documentation/media/frontend.h.rst.exceptions index 7656770f19361f6e0329f3761e0cec90ff3b3327..f7c4df620a52b4e116949304b904b9964065c954 100644 --- a/Documentation/media/frontend.h.rst.exceptions +++ b/Documentation/media/frontend.h.rst.exceptions @@ -25,19 +25,9 @@ ignore define DTV_MAX_COMMAND ignore define MAX_DTV_STATS ignore define DTV_IOCTL_MAX_MSGS -# Stats enum is documented altogether -replace enum fecap_scale_params :ref:`frontend-stat-properties` -replace symbol FE_SCALE_COUNTER frontend-stat-properties -replace symbol FE_SCALE_DECIBEL frontend-stat-properties -replace symbol FE_SCALE_NOT_AVAILABLE frontend-stat-properties -replace symbol FE_SCALE_RELATIVE frontend-stat-properties - # the same reference is used for both get and set ioctls replace ioctl FE_SET_PROPERTY :c:type:`FE_GET_PROPERTY` -# Ignore struct used only internally at Kernel -ignore struct dtv_cmds_h - # Typedefs that use the enum reference replace typedef fe_sec_voltage_t :c:type:`fe_sec_voltage` @@ -45,3 +35,178 @@ replace typedef fe_sec_voltage_t :c:type:`fe_sec_voltage` replace define FE_TUNE_MODE_ONESHOT :c:func:`FE_SET_FRONTEND_TUNE_MODE` replace define LNA_AUTO dtv-lna replace define NO_STREAM_ID_FILTER dtv-stream-id + +# Those enums are defined at the frontend.h header, and not externally + +ignore symbol FE_IS_STUPID +ignore symbol FE_CAN_INVERSION_AUTO +ignore symbol FE_CAN_FEC_1_2 +ignore symbol FE_CAN_FEC_2_3 +ignore symbol FE_CAN_FEC_3_4 +ignore symbol FE_CAN_FEC_4_5 +ignore symbol FE_CAN_FEC_5_6 +ignore symbol FE_CAN_FEC_6_7 +ignore symbol FE_CAN_FEC_7_8 +ignore symbol FE_CAN_FEC_8_9 +ignore symbol FE_CAN_FEC_AUTO +ignore symbol FE_CAN_QPSK +ignore symbol FE_CAN_QAM_16 +ignore symbol FE_CAN_QAM_32 +ignore symbol FE_CAN_QAM_64 +ignore symbol FE_CAN_QAM_128 +ignore symbol FE_CAN_QAM_256 +ignore symbol FE_CAN_QAM_AUTO +ignore symbol FE_CAN_TRANSMISSION_MODE_AUTO +ignore symbol FE_CAN_BANDWIDTH_AUTO +ignore symbol FE_CAN_GUARD_INTERVAL_AUTO +ignore symbol FE_CAN_HIERARCHY_AUTO +ignore symbol FE_CAN_8VSB +ignore symbol FE_CAN_16VSB +ignore symbol FE_HAS_EXTENDED_CAPS +ignore symbol FE_CAN_MULTISTREAM +ignore symbol FE_CAN_TURBO_FEC +ignore symbol FE_CAN_2G_MODULATION +ignore symbol FE_NEEDS_BENDING +ignore symbol FE_CAN_RECOVER +ignore symbol FE_CAN_MUTE_TS + +ignore symbol QPSK +ignore symbol QAM_16 +ignore symbol QAM_32 +ignore symbol QAM_64 +ignore symbol QAM_128 +ignore symbol QAM_256 +ignore symbol QAM_AUTO +ignore symbol VSB_8 +ignore symbol VSB_16 +ignore symbol PSK_8 +ignore symbol APSK_16 +ignore symbol APSK_32 +ignore symbol DQPSK +ignore symbol QAM_4_NR + +ignore symbol SEC_VOLTAGE_13 +ignore symbol SEC_VOLTAGE_18 +ignore symbol SEC_VOLTAGE_OFF + +ignore symbol SEC_TONE_ON +ignore symbol SEC_TONE_OFF + +ignore symbol SEC_MINI_A +ignore symbol SEC_MINI_B + +ignore symbol FE_NONE +ignore symbol FE_HAS_SIGNAL +ignore symbol FE_HAS_CARRIER +ignore symbol FE_HAS_VITERBI +ignore symbol FE_HAS_SYNC +ignore symbol FE_HAS_LOCK +ignore symbol FE_REINIT +ignore symbol FE_TIMEDOUT + +ignore symbol FEC_NONE +ignore symbol FEC_1_2 +ignore symbol FEC_2_3 +ignore symbol FEC_3_4 +ignore symbol FEC_4_5 +ignore symbol FEC_5_6 +ignore symbol FEC_6_7 +ignore symbol FEC_7_8 +ignore symbol FEC_8_9 +ignore symbol FEC_AUTO +ignore symbol FEC_3_5 +ignore symbol FEC_9_10 +ignore symbol FEC_2_5 + +ignore symbol TRANSMISSION_MODE_AUTO +ignore symbol TRANSMISSION_MODE_1K +ignore symbol TRANSMISSION_MODE_2K +ignore symbol TRANSMISSION_MODE_8K +ignore symbol TRANSMISSION_MODE_4K +ignore symbol TRANSMISSION_MODE_16K +ignore symbol TRANSMISSION_MODE_32K +ignore symbol TRANSMISSION_MODE_C1 +ignore symbol TRANSMISSION_MODE_C3780 +ignore symbol TRANSMISSION_MODE_2K +ignore symbol TRANSMISSION_MODE_8K + +ignore symbol GUARD_INTERVAL_AUTO +ignore symbol GUARD_INTERVAL_1_128 +ignore symbol GUARD_INTERVAL_1_32 +ignore symbol GUARD_INTERVAL_1_16 +ignore symbol GUARD_INTERVAL_1_8 +ignore symbol GUARD_INTERVAL_1_4 +ignore symbol GUARD_INTERVAL_19_128 +ignore symbol GUARD_INTERVAL_19_256 +ignore symbol GUARD_INTERVAL_PN420 +ignore symbol GUARD_INTERVAL_PN595 +ignore symbol GUARD_INTERVAL_PN945 + +ignore symbol HIERARCHY_NONE +ignore symbol HIERARCHY_AUTO +ignore symbol HIERARCHY_1 +ignore symbol HIERARCHY_2 +ignore symbol HIERARCHY_4 + +ignore symbol INTERLEAVING_NONE +ignore symbol INTERLEAVING_AUTO +ignore symbol INTERLEAVING_240 +ignore symbol INTERLEAVING_720 + +ignore symbol PILOT_ON +ignore symbol PILOT_OFF +ignore symbol PILOT_AUTO + +ignore symbol ROLLOFF_35 +ignore symbol ROLLOFF_20 +ignore symbol ROLLOFF_25 +ignore symbol ROLLOFF_AUTO + +ignore symbol INVERSION_ON +ignore symbol INVERSION_OFF +ignore symbol INVERSION_AUTO + +ignore symbol SYS_UNDEFINED +ignore symbol SYS_DVBC_ANNEX_A +ignore symbol SYS_DVBC_ANNEX_B +ignore symbol SYS_DVBC_ANNEX_C +ignore symbol SYS_ISDBC +ignore symbol SYS_DVBT +ignore symbol SYS_DVBT2 +ignore symbol SYS_ISDBT +ignore symbol SYS_ATSC +ignore symbol SYS_ATSCMH +ignore symbol SYS_DTMB +ignore symbol SYS_DVBS +ignore symbol SYS_DVBS2 +ignore symbol SYS_TURBO +ignore symbol SYS_ISDBS +ignore symbol SYS_DAB +ignore symbol SYS_DSS +ignore symbol SYS_CMMB +ignore symbol SYS_DVBH + +ignore symbol ATSCMH_SCCC_BLK_SEP +ignore symbol ATSCMH_SCCC_BLK_COMB +ignore symbol ATSCMH_SCCC_BLK_RES + +ignore symbol ATSCMH_SCCC_CODE_HLF +ignore symbol ATSCMH_SCCC_CODE_QTR +ignore symbol ATSCMH_SCCC_CODE_RES + +ignore symbol ATSCMH_RSFRAME_ENS_PRI +ignore symbol ATSCMH_RSFRAME_ENS_SEC + +ignore symbol ATSCMH_RSFRAME_PRI_ONLY +ignore symbol ATSCMH_RSFRAME_PRI_SEC +ignore symbol ATSCMH_RSFRAME_RES + +ignore symbol ATSCMH_RSCODE_211_187 +ignore symbol ATSCMH_RSCODE_223_187 +ignore symbol ATSCMH_RSCODE_235_187 +ignore symbol ATSCMH_RSCODE_RES + +ignore symbol FE_SCALE_NOT_AVAILABLE +ignore symbol FE_SCALE_DECIBEL +ignore symbol FE_SCALE_RELATIVE +ignore symbol FE_SCALE_COUNTER diff --git a/Documentation/media/index.rst b/Documentation/media/index.rst index 7f8f0af620ceb281416462b88e332491ddbdaa98..1cf5316c8ff800b69ccbde624552066b52caef31 100644 --- a/Documentation/media/index.rst +++ b/Documentation/media/index.rst @@ -1,7 +1,11 @@ Linux Media Subsystem Documentation =================================== -Contents: +.. only:: html + + .. class:: toc-title + + Table of Contents .. toctree:: :maxdepth: 2 @@ -10,6 +14,7 @@ Contents: media_kapi dvb-drivers/index v4l-drivers/index + cec-drivers/index .. only:: subproject diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 8a65c69ed0712bc6c74d98456cc6f9c4cb01405d..28866259998c9f547e01fa2f5a52e03a681b8814 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -107,6 +107,7 @@ your driver: int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + void (*adap_free)(struct cec_adapter *adap); /* High-level callbacks */ ... @@ -184,6 +185,14 @@ To log the current CEC hardware status: This optional callback can be used to show the status of the CEC hardware. The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status +To free any resources when the adapter is deleted: + +.. c:function:: + void (*adap_free)(struct cec_adapter *adap); + +This optional callback can be used to free any resources that might have been +allocated by the driver. It's called from cec_delete_adapter. + Your adapter driver will also have to react to events (typically interrupt driven) by calling into the framework in the following situations: @@ -336,3 +345,34 @@ log_addrs->num_log_addrs set to 0. The block argument is ignored when unconfiguring. This function will just return if the physical address is invalid. Once the physical address becomes valid, then the framework will attempt to claim these logical addresses. + +CEC Pin framework +----------------- + +Most CEC hardware operates on full CEC messages where the software provides +the message and the hardware handles the low-level CEC protocol. But some +hardware only drives the CEC pin and software has to handle the low-level +CEC protocol. The CEC pin framework was created to handle such devices. + +Note that due to the close-to-realtime requirements it can never be guaranteed +to work 100%. This framework uses highres timers internally, but if a +timer goes off too late by more than 300 microseconds wrong results can +occur. In reality it appears to be fairly reliable. + +One advantage of this low-level implementation is that it can be used as +a cheap CEC analyser, especially if interrupts can be used to detect +CEC pin transitions from low to high or vice versa. + +.. kernel-doc:: include/media/cec-pin.h + +CEC Notifier framework +---------------------- + +Most drm HDMI implementations have an integrated CEC implementation and no +notifier support is needed. But some have independent CEC implementations +that have their own driver. This could be an IP block for an SoC or a +completely separate chip that deals with the CEC pin. For those cases a +drm driver can install a notifier and use the notifier to inform the +CEC driver about changes in the physical address. + +.. kernel-doc:: include/media/cec-notifier.h diff --git a/Documentation/media/kapi/csi2.rst b/Documentation/media/kapi/csi2.rst index e33fcb967922d460f41a865eb148ee46969427ac..0560100efca2e14f16cdd33cc45440c6f4d9afd6 100644 --- a/Documentation/media/kapi/csi2.rst +++ b/Documentation/media/kapi/csi2.rst @@ -51,6 +51,16 @@ not active. Some transmitters do this automatically but some have to be explicitly programmed to do so, and some are unable to do so altogether due to hardware constraints. +Stopping the transmitter +^^^^^^^^^^^^^^^^^^^^^^^^ + +A transmitter stops sending the stream of images as a result of +calling the ``.s_stream()`` callback. Some transmitters may stop the +stream at a frame boundary whereas others stop immediately, +effectively leaving the current frame unfinished. The receiver driver +should not make assumptions either way, but function properly in both +cases. + Receiver drivers ---------------- diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst index ff86bf0abeae9624c7dd2ae898bc4af464ddc6f9..de9a228aca8a862ff585b374a498bbc9d103ef1c 100644 --- a/Documentation/media/kapi/dtv-core.rst +++ b/Documentation/media/kapi/dtv-core.rst @@ -1,6 +1,31 @@ Digital TV (DVB) devices ------------------------ +Digital TV devices are implemented by several different drivers: + +- A bridge driver that is responsible to talk with the bus where the other + devices are connected (PCI, USB, SPI), bind to the other drivers and + implement the digital demux logic (either in software or in hardware); + +- Frontend drivers that are usually implemented as two separate drivers: + + - A tuner driver that implements the logic with commands the part of the + hardware with is reponsible to tune into a digital TV transponder or + physical channel. The output of a tuner is usually a baseband or + Intermediate Frequency (IF) signal; + + - A demodulator driver (a.k.a "demod") that implements the logic with + commands the digital TV decoding hardware. The output of a demod is + a digital stream, with multiple audio, video and data channels typically + multiplexed using MPEG Transport Stream [#f1]_. + +On most hardware, the frontend drivers talk with the bridge driver using an +I2C bus. + +.. [#f1] Some standards use TCP/IP for multiplexing data, like DVB-H (an + abandoned standard, not used anymore) and ATSC version 3.0 current + proposals. Currently, the DVB subsystem doesn't implement those standards. + Digital TV Common functions --------------------------- @@ -55,8 +80,141 @@ Digital TV Frontend The Digital TV Frontend kABI defines a driver-internal interface for registering low-level, hardware specific driver to a hardware independent frontend layer. It is only of interest for Digital TV device driver writers. -The header file for this API is named dvb_frontend.h and located in -drivers/media/dvb-core. +The header file for this API is named ``dvb_frontend.h`` and located in +``drivers/media/dvb-core``. + +Demodulator driver +^^^^^^^^^^^^^^^^^^ + +The demodulator driver is responsible to talk with the decoding part of the +hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with +tells what type of digital TV standards are supported, and points to a +series of functions that allow the DVB core to command the hardware via +the code under ``drivers/media/dvb-core/dvb_frontend.c``. + +A typical example of such struct in a driver ``foo`` is:: + + static struct dvb_frontend_ops foo_ops = { + .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, + .info = { + .name = "foo DVB-T/T2/C driver", + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS | + FE_CAN_2G_MODULATION, + .frequency_min = 42000000, /* Hz */ + .frequency_max = 1002000000, /* Hz */ + .symbol_rate_min = 870000, + .symbol_rate_max = 11700000 + }, + .init = foo_init, + .sleep = foo_sleep, + .release = foo_release, + .set_frontend = foo_set_frontend, + .get_frontend = foo_get_frontend, + .read_status = foo_get_status_and_stats, + .tune = foo_tune, + .i2c_gate_ctrl = foo_i2c_gate_ctrl, + .get_frontend_algo = foo_get_algo, + }; + +A typical example of such struct in a driver ``bar`` meant to be used on +Satellite TV reception is:: + + static const struct dvb_frontend_ops bar_ops = { + .delsys = { SYS_DVBS, SYS_DVBS2 }, + .info = { + .name = "Bar DVB-S/S2 demodulator", + .frequency_min = 500000, /* KHz */ + .frequency_max = 2500000, /* KHz */ + .frequency_stepsize = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 500, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK, + }, + .init = bar_init, + .sleep = bar_sleep, + .release = bar_release, + .set_frontend = bar_set_frontend, + .get_frontend = bar_get_frontend, + .read_status = bar_get_status_and_stats, + .i2c_gate_ctrl = bar_i2c_gate_ctrl, + .get_frontend_algo = bar_get_algo, + .tune = bar_tune, + + /* Satellite-specific */ + .diseqc_send_master_cmd = bar_send_diseqc_msg, + .diseqc_send_burst = bar_send_burst, + .set_tone = bar_set_tone, + .set_voltage = bar_set_voltage, + }; + +.. note:: + + #) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the + frequencies are specified in kHz, while, for terrestrial and cable + standards, they're specified in Hz. Due to that, if the same frontend + supports both types, you'll need to have two separate + :c:type:`dvb_frontend_ops` structures, one for each standard. + #) The ``.i2c_gate_ctrl`` field is present only when the hardware has + allows controlling an I2C gate (either directly of via some GPIO pin), + in order to remove the tuner from the I2C bus after a channel is + tuned. + #) All new drivers should implement the + :ref:`DVBv5 statistics ` via ``.read_status``. + Yet, there are a number of callbacks meant to get statistics for + signal strength, S/N and UCB. Those are there to provide backward + compatibility with legacy applications that don't support the DVBv5 + API. Implementing those callbacks are optional. Those callbacks may be + removed in the future, after we have all existing drivers supporting + DVBv5 stats. + #) Other callbacks are required for satellite TV standards, in order to + control LNBf and DiSEqC: ``.diseqc_send_master_cmd``, + ``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``. + +.. |delta| unicode:: U+00394 + +The ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is +responsible for tuning the device. It supports multiple algoritms to +detect a channel, as defined at enum :c:func:`dvbfe_algo`. + +The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver +doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to +``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning, +e. g. it will try first to use the specified center frequency ``f``, +then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|, +``f`` - 2 x |delta| and so on. + +If the hardware has internally a some sort of zigzag algorithm, you should +define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``. + +.. note:: + + The core frontend support also supports + a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to + define its own hardware-assisted algorithm. Very few hardware need to + use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other + function callbacks at struct :c:type:`dvb_frontend_ops`. + +Attaching frontend driver to the bridge driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Before using the Digital TV frontend core, the bridge driver should attach the frontend demod, tuner and SEC devices and call @@ -74,6 +232,287 @@ part of their handler for :c:type:`device_driver`.\ ``resume()``. A few other optional functions are provided to handle some special cases. +.. _dvbv5_stats: + +Digital TV Frontend statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Introduction +^^^^^^^^^^^^ + +Digital TV frontends provide a range of +:ref:`statistics ` meant to help tuning the device +and measuring the quality of service. + +For each statistics measurement, the driver should set the type of scale used, +or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given +time. Drivers should also provide the number of statistics for each type. +that's usually 1 for most video standards [#f2]_. + +Drivers should initialize each statistic counters with length and +scale at its init code. For example, if the frontend provides signal +strength, it should have, on its init code:: + + struct dtv_frontend_properties *c = &state->fe.dtv_property_cache; + + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + +And, when the statistics got updated, set the scale:: + + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].uvalue = strength; + +.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer + set of statistics. On such cases, len should be equal to 4. The first + value corresponds to the global stat; the other ones to each layer, e. g.: + + - c->cnr.stat[0] for global S/N carrier ratio, + - c->cnr.stat[1] for Layer A S/N carrier ratio, + - c->cnr.stat[2] for layer B S/N carrier ratio, + - c->cnr.stat[3] for layer C S/N carrier ratio. + +.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of + ``FE_SCALE_RELATIVE`` for signal strength and CNR measurements. + +Groups of statistics +^^^^^^^^^^^^^^^^^^^^ + +There are several groups of statistics currently supported: + +Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`) + - Measures the signal strength level at the analog part of the tuner or + demod. + + - Typically obtained from the gain applied to the tuner and/or frontend + in order to detect the carrier. When no carrier is detected, the gain is + at the maximum value (so, strength is on its minimal). + + - As the gain is visible through the set of registers that adjust the gain, + typically, this statistics is always available [#f3]_. + + - Drivers should try to make it available all the times, as this statistics + can be used when adjusting an antenna position and to check for troubles + at the cabling. + + .. [#f3] On a few devices, the gain keeps floating if no carrier. + On such devices, strength report should check first if carrier is + detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`), + and otherwise return the lowest possible value. + +Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`) + - Signal to Noise ratio for the main carrier. + + - Signal to Noise measurement depends on the device. On some hardware, is + available when the main carrier is detected. On those hardware, CNR + measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``, + see :c:type:`fe_status`). + + On other devices, it requires inner FEC decoding, + as the frontend measures it indirectly from other parameters (e. g. after + ``FE_HAS_VITERBI``, see :c:type:`fe_status`). + + Having it available after inner FEC is more common. + +Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`) + - Those counters measure the number of bits and bit errors errors after + the forward error correction (FEC) on the inner coding block + (after Viterbi, LDPC or other inner code). + + - Due to its nature, those statistics depend on full coding lock + (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``, + see :c:type:`fe_status`). + +Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`) + - Those counters measure the number of bits and bit errors errors before + the forward error correction (FEC) on the inner coding block + (before Viterbi, LDPC or other inner code). + + - Not all frontends provide this kind of statistics. + + - Due to its nature, those statistics depend on inner coding lock (e. g. + after ``FE_HAS_VITERBI``, see :c:type:`fe_status`). + +Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`) + - Those counters measure the number of blocks and block errors errors after + the forward error correction (FEC) on the inner coding block + (before Viterbi, LDPC or other inner code). + + - Due to its nature, those statistics depend on full coding lock + (e. g. after ``FE_HAS_SYNC`` or after + ``FE_HAS_LOCK``, see :c:type:`fe_status`). + +.. note:: All counters should be monotonically increased as they're + collected from the hardware. + +A typical example of the logic that handle status and statistics is:: + + static int foo_get_status_and_stats(struct dvb_frontend *fe) + { + struct foo_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + int rc; + enum fe_status *status; + + /* Both status and strength are always available */ + rc = foo_read_status(fe, &status); + if (rc < 0) + return rc; + + rc = foo_read_strength(fe); + if (rc < 0) + return rc; + + /* Check if CNR is available */ + if (!(fe->status & FE_HAS_CARRIER)) + return 0; + + rc = foo_read_cnr(fe); + if (rc < 0) + return rc; + + /* Check if pre-BER stats are available */ + if (!(fe->status & FE_HAS_VITERBI)) + return 0; + + rc = foo_get_pre_ber(fe); + if (rc < 0) + return rc; + + /* Check if post-BER stats are available */ + if (!(fe->status & FE_HAS_SYNC)) + return 0; + + rc = foo_get_post_ber(fe); + if (rc < 0) + return rc; + } + + static const struct dvb_frontend_ops ops = { + /* ... */ + .read_status = foo_get_status_and_stats, + }; + +Statistics collect +^^^^^^^^^^^^^^^^^^ + +On almost all frontend hardware, the bit and byte counts are stored by +the hardware after a certain amount of time or after the total bit/block +counter reaches a certain value (usually programable), for example, on +every 1000 ms or after receiving 1,000,000 bits. + +So, if you read the registers too soon, you'll end by reading the same +value as in the previous reading, causing the monotonic value to be +incremented too often. + +Drivers should take the responsibility to avoid too often reads. That +can be done using two approaches: + +if the driver have a bit that indicates when a collected data is ready +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Driver should check such bit before making the statistics available. + +An example of such behavior can be found at this code snippet (adapted +from mb86a20s driver's logic):: + + static int foo_get_pre_ber(struct dvb_frontend *fe) + { + struct foo_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int rc, bit_error; + + /* Check if the BER measures are already available */ + rc = foo_read_u8(state, 0x54); + if (rc < 0) + return rc; + + if (!rc) + return 0; + + /* Read Bit Error Count */ + bit_error = foo_read_u32(state, 0x55); + if (bit_error < 0) + return bit_error; + + /* Read Total Bit Count */ + rc = foo_read_u32(state, 0x51); + if (rc < 0) + return rc; + + c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->pre_bit_error.stat[0].uvalue += bit_error; + c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->pre_bit_count.stat[0].uvalue += rc; + + return 0; + } + +If the driver doesn't provide a statistics available check bit +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +A few devices, however, may not provide a way to check if the stats are +available (or the way to check it is unknown). They may not even provide +a way to directly read the total number of bits or blocks. + +On those devices, the driver need to ensure that it won't be reading from +the register too often and/or estimate the total number of bits/blocks. + +On such drivers, a typical routine to get statistics would be like +(adapted from dib8000 driver's logic):: + + struct foo_state { + /* ... */ + + unsigned long per_jiffies_stats; + } + + static int foo_get_pre_ber(struct dvb_frontend *fe) + { + struct foo_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int rc, bit_error; + u64 bits; + + /* Check if time for stats was elapsed */ + if (!time_after(jiffies, state->per_jiffies_stats)) + return 0; + + /* Next stat should be collected in 1000 ms */ + state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000); + + /* Read Bit Error Count */ + bit_error = foo_read_u32(state, 0x55); + if (bit_error < 0) + return bit_error; + + /* + * On this particular frontend, there's no register that + * would provide the number of bits per 1000ms sample. So, + * some function would calculate it based on DTV properties + */ + bits = get_number_of_bits_per_1000ms(fe); + + c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->pre_bit_error.stat[0].uvalue += bit_error; + c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->pre_bit_count.stat[0].uvalue += bits; + + return 0; + } + +Please notice that, on both cases, we're getting the statistics using the +:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that +the frontend core will automatically call this function periodically +(usually, 3 times per second, when the frontend is locked). + +That warrants that we won't miss to collect a counter and increment the +monotonic stats at the right time. + +Digital TV Frontend functions and types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + .. kernel-doc:: drivers/media/dvb-core/dvb_frontend.h diff --git a/Documentation/media/kapi/v4l2-event.rst b/Documentation/media/kapi/v4l2-event.rst index 9a5e31546ae3c822196d4b99970e1289ce39ec37..9938d21ef4d16a7109a57f1e12d276ea19d57c81 100644 --- a/Documentation/media/kapi/v4l2-event.rst +++ b/Documentation/media/kapi/v4l2-event.rst @@ -67,6 +67,8 @@ type). The ops argument allows the driver to specify a number of callbacks: +.. tabularcolumns:: |p{1.5cm}|p{16.0cm}| + ======== ============================================================== Callback Description ======== ============================================================== diff --git a/Documentation/media/media_kapi.rst b/Documentation/media/media_kapi.rst index bc0638956a43a4332da82a9848b6f0acb5752bab..83da736fad726c40de570f71eb599869bdd1f45c 100644 --- a/Documentation/media/media_kapi.rst +++ b/Documentation/media/media_kapi.rst @@ -20,7 +20,9 @@ more details. For more details see the file COPYING in the source distribution of Linux. -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/media_uapi.rst b/Documentation/media/media_uapi.rst index fd8ebe002cd200614722616cc0d1b089927b2877..28eb35a1f965cc84d902bf7e420b20a565a29f4b 100644 --- a/Documentation/media/media_uapi.rst +++ b/Documentation/media/media_uapi.rst @@ -14,7 +14,9 @@ any later version published by the Free Software Foundation. A copy of the license is included in the chapter entitled "GNU Free Documentation License". -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/typical_media_device.svg b/Documentation/media/typical_media_device.svg index 0c8abd69f39aff72e9ee732cb7c80410fbbe5778..d6fad90ec19987ad2be86387b72277094a677c3d 100644 --- a/Documentation/media/typical_media_device.svg +++ b/Documentation/media/typical_media_device.svg @@ -1,2948 +1,106 @@ - -image/svg+xmlAudio decoder -Video decoder -Audio encoder -Button Key/IR input logic -EEPROM -Sensor -System Bus -Demux -Conditional Access Module -Video encoder -Radio / Analog TV -Digital TV -PS.: picture is not complete: other blocks may be present -Webcam -Processing blocks -Smartcard -TunerFM/TV -Satellite Equipment Control (SEC) -Demod -I2C Bus (control bus) -Digital TV Frontend - -CPU -PCI, USB, SPI, I2C, ... -Bridge - DMA - \ No newline at end of file + +image/svg+xmlAudio decoder +Video decoder +Audio encoder +Button Key/IR input logic +EEPROM +Sensor +System Bus +Demux +Conditional Access Module +Video encoder +Radio / Analog TV +Digital TV +PS.: picture is not complete: other blocks may be present +Webcam +Processing blocks +Smartcard +TunerFM/TV +Satellite Equipment Control (SEC) +Demod +I2C Bus (control bus) +Digital TV Frontend + +CPU +PCI, USB, SPI, I2C, ... +Bridge + DMA + diff --git a/Documentation/media/uapi/cec/cec-api.rst b/Documentation/media/uapi/cec/cec-api.rst index bb018709970cf1ed504f44cc1854bf6643d0c0e1..b68ca9c1d2e03a9627b02c39eda039858bbc34ea 100644 --- a/Documentation/media/uapi/cec/cec-api.rst +++ b/Documentation/media/uapi/cec/cec-api.rst @@ -10,7 +10,10 @@ Part V - Consumer Electronics Control API This part describes the CEC: Consumer Electronics Control -.. class:: toc-title + +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/cec/cec-func-close.rst b/Documentation/media/uapi/cec/cec-func-close.rst index 895d9c2d1c04302f9452350b7fffe3678af1ee61..334358dfa72e442b98528368cd25359fc9441def 100644 --- a/Documentation/media/uapi/cec/cec-func-close.rst +++ b/Documentation/media/uapi/cec/cec-func-close.rst @@ -40,7 +40,7 @@ freed. The device configuration remain unchanged. Return Value ============ -:c:func:`close()` returns 0 on success. On error, -1 is returned, and +:c:func:`close() ` returns 0 on success. On error, -1 is returned, and ``errno`` is set appropriately. Possible error codes are: ``EBADF`` diff --git a/Documentation/media/uapi/cec/cec-func-ioctl.rst b/Documentation/media/uapi/cec/cec-func-ioctl.rst index 22fb6304a2df048c20a5fb8b9046d69d78df3493..e2b6260b00866198d1d14c828de0393422e719b9 100644 --- a/Documentation/media/uapi/cec/cec-func-ioctl.rst +++ b/Documentation/media/uapi/cec/cec-func-ioctl.rst @@ -39,7 +39,7 @@ Arguments Description =========== -The :c:func:`ioctl()` function manipulates cec device parameters. The +The :c:func:`ioctl() ` function manipulates cec device parameters. The argument ``fd`` must be an open file descriptor. The ioctl ``request`` code specifies the cec function to be called. It diff --git a/Documentation/media/uapi/cec/cec-func-open.rst b/Documentation/media/uapi/cec/cec-func-open.rst index 18dfb62f2efe7de04aa8812aa4d9f1bf0abf18fc..5d6663a649bd67e6a22dccbdea4a631aa49608f4 100644 --- a/Documentation/media/uapi/cec/cec-func-open.rst +++ b/Documentation/media/uapi/cec/cec-func-open.rst @@ -46,7 +46,7 @@ Arguments Description =========== -To open a cec device applications call :c:func:`open()` with the +To open a cec device applications call :c:func:`open() ` with the desired device name. The function has no side effects; the device configuration remain unchanged. @@ -58,7 +58,7 @@ EBADF. Return Value ============ -:c:func:`open()` returns the new file descriptor on success. On error, +:c:func:`open() ` returns the new file descriptor on success. On error, -1 is returned, and ``errno`` is set appropriately. Possible error codes include: diff --git a/Documentation/media/uapi/cec/cec-func-poll.rst b/Documentation/media/uapi/cec/cec-func-poll.rst index fa0abd8fb16056ac370e35ae1f0a964ee1ead020..d49f1ee0742ddeeb28d12c99ff6673ed8bcc95b3 100644 --- a/Documentation/media/uapi/cec/cec-func-poll.rst +++ b/Documentation/media/uapi/cec/cec-func-poll.rst @@ -39,10 +39,10 @@ Arguments Description =========== -With the :c:func:`poll()` function applications can wait for CEC +With the :c:func:`poll() ` function applications can wait for CEC events. -On success :c:func:`poll()` returns the number of file descriptors +On success :c:func:`poll() ` returns the number of file descriptors that have been selected (that is, file descriptors for which the ``revents`` field of the respective struct :c:type:`pollfd` is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in @@ -53,13 +53,13 @@ then the ``POLLPRI`` flag is set. When the function times out it returns a value of zero, on failure it returns -1 and the ``errno`` variable is set appropriately. -For more details see the :c:func:`poll()` manual page. +For more details see the :c:func:`poll() ` manual page. Return Value ============ -On success, :c:func:`poll()` returns the number structures which have +On success, :c:func:`poll() ` returns the number structures which have non-zero ``revents`` fields, or zero if the call timed out. On error -1 is returned, and the ``errno`` variable is set appropriately: diff --git a/Documentation/media/uapi/cec/cec-funcs.rst b/Documentation/media/uapi/cec/cec-funcs.rst index 5b7630f2e076f5046d2bdbe47ef848f883f26a08..6d696cead5cb58fe5f615960680c5ec44582bc61 100644 --- a/Documentation/media/uapi/cec/cec-funcs.rst +++ b/Documentation/media/uapi/cec/cec-funcs.rst @@ -7,7 +7,6 @@ Function Reference .. toctree:: :maxdepth: 1 - :numbered: cec-func-open cec-func-close diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst index 6d7bf7bef3eb628472c2725c28e248388a822da7..6c1f6efb822e3012527c9d18e53b0a39936351bd 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst @@ -21,7 +21,7 @@ Arguments ========= ``fd`` - File descriptor returned by :ref:`open() `. + File descriptor returned by :c:func:`open() `. ``argp`` @@ -121,6 +121,13 @@ returns the information to the application. The ioctl never fails. high. This makes it impossible to use CEC to wake up displays that set the HPD pin low when in standby mode, but keep the CEC bus alive. + * .. _`CEC-CAP-MONITOR-PIN`: + + - ``CEC_CAP_MONITOR_PIN`` + - 0x00000080 + - The CEC hardware can monitor CEC pin changes from low to high voltage + and vice versa. When in pin monitoring mode the application will + receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events. diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index fcf863ab6f4378343dc764f29c5baca37438f6f1..84f431a022ad84e6531bc496e3671a592ec707bd 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst @@ -48,7 +48,9 @@ can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE` the ``EBUSY`` error code will be returned. To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields -will be ignored in that case. The adapter will go to the unconfigured state. +will be ignored in that case. The adapter will go to the unconfigured state and the +``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default +values (CEC version 2.0, no vendor ID and an empty OSD name). If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `), then this ioctl will block until all requested logical @@ -63,7 +65,7 @@ logical address types are already defined will return with error ``EBUSY``. .. c:type:: cec_log_addrs -.. tabularcolumns:: |p{1.0cm}|p{7.5cm}|p{8.0cm}| +.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{7.5cm}| .. cssclass:: longtable @@ -146,6 +148,9 @@ logical address types are already defined will return with error ``EBUSY``. give the CEC framework more information about the device type, even though the framework won't use it directly in the CEC message. + +.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}| + .. _cec-log-addrs-flags: .. flat-table:: Flags for struct cec_log_addrs @@ -173,7 +178,7 @@ logical address types are already defined will return with error ``EBUSY``. to avoid trivial snooping of the keystrokes. * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`: - - `CEC_LOG_ADDRS_FL_CDC_ONLY` + - ``CEC_LOG_ADDRS_FL_CDC_ONLY`` - 4 - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices are CEC devices that can only handle CDC messages. @@ -181,7 +186,7 @@ logical address types are already defined will return with error ``EBUSY``. All other messages are ignored. -.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| +.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}| .. _cec-versions: diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index 4d3570c2e0b3662183743be39de726946a3b2595..a5c821809cc6c9ad4e92b143b499681db1d9b1f4 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -22,7 +22,7 @@ Arguments ========= ``fd`` - File descriptor returned by :ref:`open() `. + File descriptor returned by :c:func:`open() `. ``argp`` @@ -87,7 +87,7 @@ it is guaranteed that the state did change in between the two events. this is more than enough. -.. tabularcolumns:: |p{1.0cm}|p{4.2cm}|p{2.5cm}|p{8.8cm}| +.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}| .. c:type:: cec_event @@ -98,10 +98,11 @@ it is guaranteed that the state did change in between the two events. * - __u64 - ``ts`` - - :cspan:`1` Timestamp of the event in ns. + - :cspan:`1`\ Timestamp of the event in ns. - The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access - the same clock from userspace use :c:func:`clock_gettime`. + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. + + To access the same clock from userspace use :c:func:`clock_gettime`. * - __u32 - ``event`` - :cspan:`1` The CEC event type, see :ref:`cec-events`. @@ -146,6 +147,20 @@ it is guaranteed that the state did change in between the two events. - 2 - Generated if one or more CEC messages were lost because the application didn't dequeue CEC messages fast enough. + * .. _`CEC-EVENT-PIN-CEC-LOW`: + + - ``CEC_EVENT_PIN_CEC_LOW`` + - 3 + - Generated if the CEC pin goes from a high voltage to a low voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. + * .. _`CEC-EVENT-PIN-CEC-HIGH`: + + - ``CEC_EVENT_PIN_CEC_HIGH`` + - 4 + - Generated if the CEC pin goes from a low voltage to a high voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. .. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| @@ -165,6 +180,12 @@ it is guaranteed that the state did change in between the two events. opened. See the table above for which events do this. This allows applications to learn the initial state of the CEC adapter at open() time. + * .. _`CEC-EVENT-FL-DROPPED-EVENTS`: + + - ``CEC_EVENT_FL_DROPPED_EVENTS`` + - 2 + - Set if one or more events of the given event type have been dropped. + This is an indication that the application cannot keep up. diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst index 664f0d47bbcdc753a81587ce24b7bd4b4c1f3b30..508e2e3256834667801ca5256fc770548db2f6e5 100644 --- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst @@ -108,6 +108,8 @@ Available follower modes are: .. _cec-mode-follower_e: +.. cssclass:: longtable + .. flat-table:: Follower Modes :header-rows: 0 :stub-columns: 0 @@ -149,13 +151,28 @@ Available follower modes are: code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-MONITOR-PIN`: + + - ``CEC_MODE_MONITOR_PIN`` + - 0xd0 + - Put the file descriptor into pin monitoring mode. Can only be used in + combination with :ref:`CEC_MODE_NO_INITIATOR `, + otherwise the ``EINVAL`` error code will be returned. + This mode requires that the :ref:`CEC_CAP_MONITOR_PIN ` + capability is set, otherwise the ``EINVAL`` error code is returned. + While in pin monitoring mode this file descriptor can receive the + ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the + low-level CEC pin transitions. This is very useful for debugging. + This mode is only allowed if the process has the ``CAP_NET_ADMIN`` + capability. If that is not set, then the ``EPERM`` error code is returned. * .. _`CEC-MODE-MONITOR`: - ``CEC_MODE_MONITOR`` - 0xe0 - Put the file descriptor into monitor mode. Can only be used in - combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise EINVAL error - code will be returned. In monitor mode all messages this CEC + combination with :ref:`CEC_MODE_NO_INITIATOR `,i + otherwise the ``EINVAL`` error code will be returned. + In monitor mode all messages this CEC device transmits and all messages it receives (both broadcast messages and directed messages for one its logical addresses) will be reported. This is very useful for debugging. This is only @@ -191,55 +208,68 @@ Core message processing details: * .. _`CEC-MSG-GET-CEC-VERSION`: - ``CEC_MSG_GET_CEC_VERSION`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return the CEC version that was - set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + - The core will return the CEC version that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return the vendor ID that was - set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + - The core will return the vendor ID that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. * .. _`CEC-MSG-ABORT`: - ``CEC_MSG_ABORT`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return a feature refused - message as per the specification. + - The core will return a Feature Abort message with reason + 'Feature Refused' as per the specification, except when in + passthrough mode. In passthrough mode the core does nothing + and this message has to be handled by a follower instead. * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current physical - address. + - The core will report the current physical address, except when + in passthrough mode. In passthrough mode the core does nothing + and this message has to be handled by a follower instead. * .. _`CEC-MSG-GIVE-OSD-NAME`: - ``CEC_MSG_GIVE_OSD_NAME`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current OSD name as - was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + - The core will report the current OSD name that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. * .. _`CEC-MSG-GIVE-FEATURES`: - ``CEC_MSG_GIVE_FEATURES`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current features as - was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` - or the message is ignored if the CEC version was older than 2.0. + - The core will do nothing if the CEC version is older than 2.0, + otherwise it will report the current features that were set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing (for any CEC version) and this message has to be handled + by a follower instead. * .. _`CEC-MSG-USER-CONTROL-PRESSED`: - ``CEC_MSG_USER_CONTROL_PRESSED`` - - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key - press. This message is always passed on to userspace. + - If :ref:`CEC_CAP_RC ` is set and if + :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU ` + is set, then generate a remote control key + press. This message is always passed on to the follower(s). * .. _`CEC-MSG-USER-CONTROL-RELEASED`: - ``CEC_MSG_USER_CONTROL_RELEASED`` - - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key - release. This message is always passed on to userspace. + - If :ref:`CEC_CAP_RC ` is set and if + :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU ` + is set, then generate a remote control key + release. This message is always passed on to the follower(s). * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` - The CEC framework will make note of the reported physical address - and then just pass the message on to userspace. + and then just pass the message on to the follower(s). diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index 267044f7ac301244ffeae3d07439b6fc4470b534..0f397c535a4cde648d5e2e132d25021457cb1418 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -195,6 +195,8 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. +.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.3cm}| + .. _cec-msg-flags: .. flat-table:: Flags for struct cec_msg diff --git a/Documentation/media/uapi/dvb/audio-channel-select.rst b/Documentation/media/uapi/dvb/audio-channel-select.rst index 2ceb4efebdf0233bc3363d1205bbff7d68c86f10..8cab3d7abff538e2a304518500457dee8c1233a1 100644 --- a/Documentation/media/uapi/dvb/audio-channel-select.rst +++ b/Documentation/media/uapi/dvb/audio-channel-select.rst @@ -44,7 +44,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead. This ioctl call asks the Audio Device to select the requested channel if diff --git a/Documentation/media/uapi/dvb/audio-fclose.rst b/Documentation/media/uapi/dvb/audio-fclose.rst index 4df24c8d74ed3e153ee90ebba7352757634d5d5c..58d351a3af4b0d2ef28906c661bf4a0c1f3f0837 100644 --- a/Documentation/media/uapi/dvb/audio-fclose.rst +++ b/Documentation/media/uapi/dvb/audio-fclose.rst @@ -2,14 +2,14 @@ .. _audio_fclose: -================= -DVB audio close() -================= +======================== +Digital TV audio close() +======================== Name ---- -DVB audio close() +Digital TV audio close() .. attention:: This ioctl is deprecated diff --git a/Documentation/media/uapi/dvb/audio-fopen.rst b/Documentation/media/uapi/dvb/audio-fopen.rst index a802c2e0dc6a977173ed2a0acf1d74a9fbde08b8..4a174640bf119c23dd62cc3d9d6dc693ae7e054c 100644 --- a/Documentation/media/uapi/dvb/audio-fopen.rst +++ b/Documentation/media/uapi/dvb/audio-fopen.rst @@ -2,14 +2,14 @@ .. _audio_fopen: -================ -DVB audio open() -================ +======================= +Digital TV audio open() +======================= Name ---- -DVB audio open() +Digital TV audio open() .. attention:: This ioctl is deprecated diff --git a/Documentation/media/uapi/dvb/audio-fwrite.rst b/Documentation/media/uapi/dvb/audio-fwrite.rst index 8882cad7d165422a08443b3f0cba878a3803b690..4980ae7953ef382b3721f142c4b677ba1f1a83d9 100644 --- a/Documentation/media/uapi/dvb/audio-fwrite.rst +++ b/Documentation/media/uapi/dvb/audio-fwrite.rst @@ -2,14 +2,14 @@ .. _audio_fwrite: -================= -DVB audio write() -================= +========================= +Digital TV audio write() +========================= Name ---- -DVB audio write() +Digital TV audio write() .. attention:: This ioctl is deprecated diff --git a/Documentation/media/uapi/dvb/audio-set-av-sync.rst b/Documentation/media/uapi/dvb/audio-set-av-sync.rst index 0cef4917d2cf3af462b74ce34877e7e3ac630c33..cf621f3a30377e48143256da21430e434a67b8ad 100644 --- a/Documentation/media/uapi/dvb/audio-set-av-sync.rst +++ b/Documentation/media/uapi/dvb/audio-set-av-sync.rst @@ -38,7 +38,7 @@ Arguments - boolean state - - Tells the DVB subsystem if A/V synchronization shall be ON or OFF. + - Tells the Digital TV subsystem if A/V synchronization shall be ON or OFF. TRUE: AV-sync ON diff --git a/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst b/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst index b063c496c2eb528c229f488dd22368427321d8ca..f0db1fbdb0661eb63fcf270710188c83b9dbae53 100644 --- a/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst +++ b/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst @@ -38,7 +38,7 @@ Arguments - boolean mode - Enables or disables the decoding of the current Audio stream in - the DVB subsystem. + the Digital TV subsystem. TRUE: Bypass is disabled @@ -50,8 +50,8 @@ Description This ioctl call asks the Audio Device to bypass the Audio decoder and forward the stream without decoding. This mode shall be used if streams -that can’t be handled by the DVB system shall be decoded. Dolby -DigitalTM streams are automatically forwarded by the DVB subsystem if +that can’t be handled by the Digial TV system shall be decoded. Dolby +DigitalTM streams are automatically forwarded by the Digital TV subsystem if the hardware can handle it. diff --git a/Documentation/media/uapi/dvb/audio-set-mute.rst b/Documentation/media/uapi/dvb/audio-set-mute.rst index 897e7228f4d830b1854f2cbbfd3898ce271cf09d..0af105a8ddcc0785e854948b836e2a0e2510eaa4 100644 --- a/Documentation/media/uapi/dvb/audio-set-mute.rst +++ b/Documentation/media/uapi/dvb/audio-set-mute.rst @@ -48,7 +48,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` with the ``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead. diff --git a/Documentation/media/uapi/dvb/audio.rst b/Documentation/media/uapi/dvb/audio.rst index 155622185ea43fd58aec931ea19ed7a04a2024cb..e9f9e589c486d82c3a1bf3fe0ab7e421c4fc226c 100644 --- a/Documentation/media/uapi/dvb/audio.rst +++ b/Documentation/media/uapi/dvb/audio.rst @@ -2,15 +2,16 @@ .. _dvb_audio: -################ -DVB Audio Device -################ -The DVB audio device controls the MPEG2 audio decoder of the DVB -hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data +####################### +Digital TV Audio Device +####################### + +The Digital TV audio device controls the MPEG2 audio decoder of the Digital +TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data types and and ioctl definitions can be accessed by including ``linux/dvb/audio.h`` in your application. -Please note that some DVB cards don’t have their own MPEG decoder, which +Please note that some Digital TV cards don’t have their own MPEG decoder, which results in the omission of the audio and video device. These ioctls were also used by V4L2 to control MPEG decoders implemented diff --git a/Documentation/media/uapi/dvb/audio_h.rst b/Documentation/media/uapi/dvb/audio_h.rst deleted file mode 100644 index e00c3010fdf9916896bf81f19cd5100ba402063b..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/audio_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _audio_h: - -********************* -DVB Audio Header File -********************* - -.. kernel-include:: $BUILDDIR/audio.h.rst diff --git a/Documentation/media/uapi/dvb/ca-fclose.rst b/Documentation/media/uapi/dvb/ca-fclose.rst index 5ecefa4abc3d29ba5ca4892316cfcefc0e43357a..e84bbfcfa1846d946b0f82d4c02c751ed9b07c76 100644 --- a/Documentation/media/uapi/dvb/ca-fclose.rst +++ b/Documentation/media/uapi/dvb/ca-fclose.rst @@ -2,14 +2,14 @@ .. _ca_fclose: -============== -DVB CA close() -============== +===================== +Digital TV CA close() +===================== Name ---- -DVB CA close() +Digital TV CA close() Synopsis @@ -34,13 +34,10 @@ This system call closes a previously opened CA device. Return Value ------------ -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. - - .. row 1 - - - ``EBADF`` - - - fd is not a valid open file descriptor. +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-fopen.rst b/Documentation/media/uapi/dvb/ca-fopen.rst index 3d281975144670a8dac61e7fa7643fee43332c61..056c71b53a70a4d8a135952de6fc2cf2cddd55bb 100644 --- a/Documentation/media/uapi/dvb/ca-fopen.rst +++ b/Documentation/media/uapi/dvb/ca-fopen.rst @@ -2,14 +2,14 @@ .. _ca_fopen: -============= -DVB CA open() -============= +==================== +Digital TV CA open() +==================== Name ---- -DVB CA open() +Digital TV CA open() Synopsis @@ -23,25 +23,25 @@ Arguments --------- ``name`` - Name of specific DVB CA device. + Name of specific Digital TV CA device. ``flags`` A bit-wise OR of the following flags: +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| + .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - - - O_RDONLY + - - ``O_RDONLY`` - read-only access - - - - O_RDWR + - - ``O_RDWR`` - read/write access - - - - O_NONBLOCK + - - ``O_NONBLOCK`` - open in non-blocking mode (blocking mode is the default) @@ -49,50 +49,29 @@ Arguments Description ----------- -This system call opens a named ca device (e.g. /dev/ost/ca) for -subsequent use. +This system call opens a named ca device (e.g. ``/dev/dvb/adapter?/ca?``) +for subsequent use. -When an open() call has succeeded, the device will be ready for use. The +When an ``open()`` call has succeeded, the device will be ready for use. The significance of blocking or non-blocking mode is described in the documentation for functions where there is a difference. It does not -affect the semantics of the open() call itself. A device opened in +affect the semantics of the ``open()`` call itself. A device opened in blocking mode can later be put into non-blocking mode (and vice versa) -using the F_SETFL command of the fcntl system call. This is a standard -system call, documented in the Linux manual page for fcntl. Only one -user can open the CA Device in O_RDWR mode. All other attempts to open -the device in this mode will fail, and an error code will be returned. +using the ``F_SETFL`` command of the ``fcntl`` system call. This is a +standard system call, documented in the Linux manual page for fcntl. +Only one user can open the CA Device in ``O_RDWR`` mode. All other +attempts to open the device in this mode will fail, and an error code +will be returned. Return Value ------------ -.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| - -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - - - - .. row 1 - - - ``ENODEV`` - - - Device driver not loaded/available. - - - .. row 2 - - - ``EINTERNAL`` - - - Internal error. - - - .. row 3 - - - ``EBUSY`` - - - Device or resource busy. - - .. row 4 +On success 0 is returned. - - ``EINVAL`` +On error -1 is returned, and the ``errno`` variable is set +appropriately. - - Invalid argument. +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-cap.rst b/Documentation/media/uapi/dvb/ca-get-cap.rst index fbf7e359cb8a05e2d3b5229b2aa6b2d36cb545bd..d2d5c135539682733176ebde4f5c9f4702fd8385 100644 --- a/Documentation/media/uapi/dvb/ca-get-cap.rst +++ b/Documentation/media/uapi/dvb/ca-get-cap.rst @@ -28,43 +28,19 @@ Arguments ``caps`` Pointer to struct :c:type:`ca_caps`. -.. c:type:: struct ca_caps - -.. flat-table:: struct ca_caps - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - unsigned int - - slot_num - - total number of CA card and module slots - - - - unsigned int - - slot_type - - bitmask with all supported slot types - - - - unsigned int - - descr_num - - total number of descrambler slots (keys) - - - - unsigned int - - descr_type - - bit mask with all supported descr types - - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. - +Queries the Kernel for information about the available CA and descrambler +slots, and their types. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned and :c:type:`ca_caps` is filled. + +On error, -1 is returned and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-descr-info.rst b/Documentation/media/uapi/dvb/ca-get-descr-info.rst index 7bf327a3d0e3f52750e95eef680a86c11b1715ba..e564fbb8d5240522b5467d6aca3330e5d9f6f2e2 100644 --- a/Documentation/media/uapi/dvb/ca-get-descr-info.rst +++ b/Documentation/media/uapi/dvb/ca-get-descr-info.rst @@ -27,37 +27,16 @@ Arguments ``desc`` Pointer to struct :c:type:`ca_descr_info`. -.. c:type:: struct ca_descr_info - -.. flat-table:: struct ca_descr_info - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - - unsigned int - - num - - number of available descramblers (keys) - - - - unsigned int - - type - - type of supported scrambling system. Valid values are: - ``CA_ECD``, ``CA_NDS`` and ``CA_DSS``. - - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. - +Returns information about all descrambler slots. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set +On success 0 is returned, and :c:type:`ca_descr_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set appropriately. The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-msg.rst b/Documentation/media/uapi/dvb/ca-get-msg.rst index 121588da3ef1806176318037b0352c89a2087bb1..ceeda623ce9358d9b8bbfc3849b4be398979f9ab 100644 --- a/Documentation/media/uapi/dvb/ca-get-msg.rst +++ b/Documentation/media/uapi/dvb/ca-get-msg.rst @@ -28,47 +28,25 @@ Arguments ``msg`` Pointer to struct :c:type:`ca_msg`. +Description +----------- -.. c:type:: struct ca_msg - -.. flat-table:: struct ca_msg - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - unsigned int - - index - - - - - - - unsigned int - - type - - +Receives a message via a CI CA module. - - - - unsigned int - - length - - +.. note:: - - - - unsigned char - - msg[256] - - + Please notice that, on most drivers, this is done by reading from + the /dev/adapter?/ca? device node. -Description ------------ +Return Value +------------ -.. note:: This ioctl is undocumented. Documentation is welcome. +On success 0 is returned. -Return Value ------------- +On error -1 is returned, and the ``errno`` variable is set +appropriately. -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-slot-info.rst b/Documentation/media/uapi/dvb/ca-get-slot-info.rst index 54e5dc78a2dc434116d87cc6ab8e2b540c8ec6bd..1a1d6f0c71b99a799b9a081a87dbe5d3860d580a 100644 --- a/Documentation/media/uapi/dvb/ca-get-slot-info.rst +++ b/Documentation/media/uapi/dvb/ca-get-slot-info.rst @@ -26,100 +26,32 @@ Arguments File descriptor returned by a previous call to :c:func:`open() `. ``info`` - Pointer to struct c:type:`ca_slot_info`. + Pointer to struct :c:type:`ca_slot_info`. -.. _ca_slot_info_type: +Description +----------- -.. flat-table:: ca_slot_info types - :header-rows: 1 - :stub-columns: 0 +Returns information about a CA slot identified by +:c:type:`ca_slot_info`.slot_num. - - - - type - - name - - description - - - - CA_CI - - 1 - - CI high level interface - - - - - CA_CI_LINK - - 2 - - CI link layer level interface - - - - - CA_CI_PHYS - - 4 - - CI physical layer level interface - - - - - CA_DESCR - - 8 - - built-in descrambler - - - - - CA_SC - - 128 - - simple smart card interface - -.. _ca_slot_info_flag: - -.. flat-table:: ca_slot_info flags - :header-rows: 1 - :stub-columns: 0 - - - - type - - name - - description +Return Value +------------ - - - - CA_CI_MODULE_PRESENT - - 1 - - module (or card) inserted +On success 0 is returned, and :c:type:`ca_slot_info` is filled. - - - - CA_CI_MODULE_READY - - 2 - - +On error -1 is returned, and the ``errno`` variable is set +appropriately. -.. c:type:: ca_slot_info +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| -.. flat-table:: struct ca_slot_info - :header-rows: 1 +.. flat-table:: + :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - - - type - - name - - description - - - - - int - - num - - slot number - - - - - int - - type - - CA interface this slot supports, as defined at :ref:`ca_slot_info_type`. - - - - - unsigned int - - flags - - flags as defined at :ref:`ca_slot_info_flag`. - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - - -Return Value ------------- + - - ``ENODEV`` + - the slot is not available. -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-reset.rst b/Documentation/media/uapi/dvb/ca-reset.rst index 477313121a6508966f41600cd369c3a0d5ba0f3c..29788325f90e58363043ba3225a33c3004486785 100644 --- a/Documentation/media/uapi/dvb/ca-reset.rst +++ b/Documentation/media/uapi/dvb/ca-reset.rst @@ -28,12 +28,17 @@ Arguments Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +Puts the Conditional Access hardware on its initial state. It should +be called before start using the CA hardware. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-send-msg.rst b/Documentation/media/uapi/dvb/ca-send-msg.rst index 532ef5f9d6acf56610aad9d8e329042b87083e23..9e91287b7bbcbd7d314106947dabecfa6f65d9cd 100644 --- a/Documentation/media/uapi/dvb/ca-send-msg.rst +++ b/Documentation/media/uapi/dvb/ca-send-msg.rst @@ -32,12 +32,20 @@ Arguments Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +Sends a message via a CI CA module. +.. note:: + + Please notice that, on most drivers, this is done by writing + to the /dev/adapter?/ca? device node. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-set-descr.rst b/Documentation/media/uapi/dvb/ca-set-descr.rst index 70f7b3cf12addadcfea181a11a2f6380d6125afe..a6c47205ffd859514c881a2b38ec69b3cec0d42b 100644 --- a/Documentation/media/uapi/dvb/ca-set-descr.rst +++ b/Documentation/media/uapi/dvb/ca-set-descr.rst @@ -28,16 +28,19 @@ Arguments ``msg`` Pointer to struct :c:type:`ca_descr`. - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. - +CA_SET_DESCR is used for feeding descrambler CA slots with descrambling +keys (refered as control words). Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-set-pid.rst b/Documentation/media/uapi/dvb/ca-set-pid.rst deleted file mode 100644 index 891c1c72ef24ba2355a41ba155c671a6e0162757..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/ca-set-pid.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _CA_SET_PID: - -========== -CA_SET_PID -========== - -Name ----- - -CA_SET_PID - - -Synopsis --------- - -.. c:function:: int ioctl(fd, CA_SET_PID, struct ca_pid *pid) - :name: CA_SET_PID - - -Arguments ---------- - -``fd`` - File descriptor returned by a previous call to :c:func:`open() `. - -``pid`` - Pointer to struct :c:type:`ca_pid`. - -.. c:type:: ca_pid - -.. flat-table:: struct ca_pid - :header-rows: 1 - :stub-columns: 0 - - - - - unsigned int - - pid - - Program ID - - - - - int - - index - - PID index. Use -1 to disable. - - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca.rst b/Documentation/media/uapi/dvb/ca.rst index 14b14abda1aee663d352fe180ec562d4d8a04320..deac72d89e9313ad863ba0451763ba52bfaa48be 100644 --- a/Documentation/media/uapi/dvb/ca.rst +++ b/Documentation/media/uapi/dvb/ca.rst @@ -2,14 +2,20 @@ .. _dvb_ca: -############# -DVB CA Device -############# -The DVB CA device controls the conditional access hardware. It can be -accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl +#################### +Digital TV CA Device +#################### + +The Digital TV CA device controls the conditional access hardware. It +can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl definitions can be accessed by including ``linux/dvb/ca.h`` in your application. +.. note:: + + There are three ioctls at this API that aren't documented: + :ref:`CA_GET_MSG`, :ref:`CA_SEND_MSG` and :ref:`CA_SET_DESCR`. + Documentation for them are welcome. .. toctree:: :maxdepth: 1 diff --git a/Documentation/media/uapi/dvb/ca_data_types.rst b/Documentation/media/uapi/dvb/ca_data_types.rst index d9e27c77426cf9e94ad0365b801032cd7ab6d5d6..ac7cbd76ddd51c6f122e7d5dd4f38f9379de2a34 100644 --- a/Documentation/media/uapi/dvb/ca_data_types.rst +++ b/Documentation/media/uapi/dvb/ca_data_types.rst @@ -6,105 +6,4 @@ CA Data Types ************* - -.. c:type:: ca_slot_info - -ca_slot_info_t -============== - - -.. code-block:: c - - typedef struct ca_slot_info { - int num; /* slot number */ - - int type; /* CA interface this slot supports */ - #define CA_CI 1 /* CI high level interface */ - #define CA_CI_LINK 2 /* CI link layer level interface */ - #define CA_CI_PHYS 4 /* CI physical layer level interface */ - #define CA_DESCR 8 /* built-in descrambler */ - #define CA_SC 128 /* simple smart card interface */ - - unsigned int flags; - #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ - #define CA_CI_MODULE_READY 2 - } ca_slot_info_t; - - -.. c:type:: ca_descr_info - -ca_descr_info_t -=============== - - -.. code-block:: c - - typedef struct ca_descr_info { - unsigned int num; /* number of available descramblers (keys) */ - unsigned int type; /* type of supported scrambling system */ - #define CA_ECD 1 - #define CA_NDS 2 - #define CA_DSS 4 - } ca_descr_info_t; - - -.. c:type:: ca_caps - -ca_caps_t -========= - - -.. code-block:: c - - typedef struct ca_caps { - unsigned int slot_num; /* total number of CA card and module slots */ - unsigned int slot_type; /* OR of all supported types */ - unsigned int descr_num; /* total number of descrambler slots (keys) */ - unsigned int descr_type;/* OR of all supported types */ - } ca_cap_t; - - -.. c:type:: ca_msg - -ca_msg_t -======== - - -.. code-block:: c - - /* a message to/from a CI-CAM */ - typedef struct ca_msg { - unsigned int index; - unsigned int type; - unsigned int length; - unsigned char msg[256]; - } ca_msg_t; - - -.. c:type:: ca_descr - -ca_descr_t -========== - - -.. code-block:: c - - typedef struct ca_descr { - unsigned int index; - unsigned int parity; - unsigned char cw[8]; - } ca_descr_t; - - -.. c:type:: ca_pid - -ca-pid -====== - - -.. code-block:: c - - typedef struct ca_pid { - unsigned int pid; - int index; /* -1 == disable*/ - } ca_pid_t; +.. kernel-doc:: include/uapi/linux/dvb/ca.h diff --git a/Documentation/media/uapi/dvb/ca_function_calls.rst b/Documentation/media/uapi/dvb/ca_function_calls.rst index c085a0ebbc057cf7c4eeea85c0407e2aad63af9f..87d697851e82dbffd58f7512fcded351a7ad4710 100644 --- a/Documentation/media/uapi/dvb/ca_function_calls.rst +++ b/Documentation/media/uapi/dvb/ca_function_calls.rst @@ -18,4 +18,3 @@ CA Function Calls ca-get-msg ca-send-msg ca-set-descr - ca-set-pid diff --git a/Documentation/media/uapi/dvb/ca_h.rst b/Documentation/media/uapi/dvb/ca_h.rst deleted file mode 100644 index f513592ef52967d5121b536ae52686e8b994989c..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/ca_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _ca_h: - -********************************** -DVB Conditional Access Header File -********************************** - -.. kernel-include:: $BUILDDIR/ca.h.rst diff --git a/Documentation/media/uapi/dvb/demux.rst b/Documentation/media/uapi/dvb/demux.rst index b12b5a2dac94b21a5a8d7bc781d7c86ab05b557e..45c3d6405c46a7e8f9d7c0ce2d01336dc2f41d69 100644 --- a/Documentation/media/uapi/dvb/demux.rst +++ b/Documentation/media/uapi/dvb/demux.rst @@ -2,10 +2,15 @@ .. _dvb_demux: -################ -DVB Demux Device -################ -The DVB demux device controls the filters of the DVB hardware/software. +####################### +Digital TV Demux Device +####################### + +The Digital TV demux device controls the MPEG-TS filters for the +digital TV. If the driver and hardware supports, those filters are +implemented at the hardware. Otherwise, the Kernel provides a software +emulation. + It can be accessed through ``/dev/adapter?/demux?``. Data types and and ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in your application. diff --git a/Documentation/media/uapi/dvb/dmx-add-pid.rst b/Documentation/media/uapi/dvb/dmx-add-pid.rst index 689cd1fc9142e73df6a4eed18995fb741789c2d1..4d5632dfb43e958d2fc9a8cfc9bb2b84f890f112 100644 --- a/Documentation/media/uapi/dvb/dmx-add-pid.rst +++ b/Documentation/media/uapi/dvb/dmx-add-pid.rst @@ -33,13 +33,17 @@ Description ----------- This ioctl call allows to add multiple PIDs to a transport stream filter -previously set up with DMX_SET_PES_FILTER and output equal to -DMX_OUT_TSDEMUX_TAP. +previously set up with :ref:`DMX_SET_PES_FILTER` and output equal to +:c:type:`DMX_OUT_TSDEMUX_TAP `. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fclose.rst b/Documentation/media/uapi/dvb/dmx-fclose.rst index ca93c23cde6db2b1bf01ca22a6aa23414161bebc..578e929f4bde9305e63f1f3d23b2edfc801ba782 100644 --- a/Documentation/media/uapi/dvb/dmx-fclose.rst +++ b/Documentation/media/uapi/dvb/dmx-fclose.rst @@ -2,14 +2,14 @@ .. _dmx_fclose: -================= -DVB demux close() -================= +======================== +Digital TV demux close() +======================== Name ---- -DVB demux close() +Digital TV demux close() Synopsis @@ -23,25 +23,23 @@ Arguments --------- ``fd`` - File descriptor returned by a previous call to :c:func:`open() `. + File descriptor returned by a previous call to + :c:func:`open() `. Description ----------- This system call deactivates and deallocates a filter that was -previously allocated via the open() call. +previously allocated via the :c:func:`open() ` call. Return Value ------------ -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 +On success 0 is returned. +On error, -1 is returned and the ``errno`` variable is set +appropriately. - - .. row 1 - - - ``EBADF`` - - - fd is not a valid open file descriptor. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fopen.rst b/Documentation/media/uapi/dvb/dmx-fopen.rst index a697e33c32ea50726e158e66bb5c5631e592c06a..55628a18ba67245c6e7d23b5c19851b1bfa81027 100644 --- a/Documentation/media/uapi/dvb/dmx-fopen.rst +++ b/Documentation/media/uapi/dvb/dmx-fopen.rst @@ -2,14 +2,14 @@ .. _dmx_fopen: -================ -DVB demux open() -================ +======================= +Digital TV demux open() +======================= Name ---- -DVB demux open() +Digital TV demux open() Synopsis @@ -22,25 +22,28 @@ Arguments --------- ``name`` - Name of specific DVB demux device. + Name of specific Digital TV demux device. ``flags`` A bit-wise OR of the following flags: +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| + .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - - O_RDONLY + - ``O_RDONLY`` - read-only access - - - O_RDWR + - ``O_RDWR`` - read/write access - - - O_NONBLOCK + - ``O_NONBLOCK`` - open in non-blocking mode (blocking mode is the default) @@ -48,52 +51,41 @@ Arguments Description ----------- -This system call, used with a device name of /dev/dvb/adapter0/demux0, +This system call, used with a device name of ``/dev/dvb/adapter?/demux?``, allocates a new filter and returns a handle which can be used for subsequent control of that filter. This call has to be made for each filter to be used, i.e. every returned file descriptor is a reference to -a single filter. /dev/dvb/adapter0/dvr0 is a logical device to be used +a single filter. ``/dev/dvb/adapter?/dvr?`` is a logical device to be used for retrieving Transport Streams for digital video recording. When reading from this device a transport stream containing the packets from all PES filters set in the corresponding demux device -(/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A -recorded Transport Stream is replayed by writing to this device. +(``/dev/dvb/adapter?/demux?``) having the output set to ``DMX_OUT_TS_TAP``. +A recorded Transport Stream is replayed by writing to this device. The significance of blocking or non-blocking mode is described in the documentation for functions where there is a difference. It does not -affect the semantics of the open() call itself. A device opened in -blocking mode can later be put into non-blocking mode (and vice versa) -using the F_SETFL command of the fcntl system call. +affect the semantics of the ``open()`` call itself. A device opened +in blocking mode can later be put into non-blocking mode (and vice versa) +using the ``F_SETFL`` command of the fcntl system call. Return Value ------------ -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - - - - .. row 1 - - - ``ENODEV`` - - - Device driver not loaded/available. +On success 0 is returned. - - .. row 2 +On error -1 is returned, and the ``errno`` variable is set +appropriately. - - ``EINVAL`` +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| - - Invalid argument. - - - .. row 3 - - - ``EMFILE`` +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 16 + - - ``EMFILE`` - “Too many open filesâ€, i.e. no more filters available. - - .. row 4 - - - ``ENOMEM`` - - - The driver failed to allocate enough memory. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fread.rst b/Documentation/media/uapi/dvb/dmx-fread.rst index e8c7f4db353f001decf923f6d58539de6884ef08..488bdc4ba178a90c37758e42d1b8a049f20a36b8 100644 --- a/Documentation/media/uapi/dvb/dmx-fread.rst +++ b/Documentation/media/uapi/dvb/dmx-fread.rst @@ -2,14 +2,14 @@ .. _dmx_fread: -================ -DVB demux read() -================ +======================= +Digital TV demux read() +======================= Name ---- -DVB demux read() +Digital TV demux read() Synopsis @@ -33,62 +33,48 @@ Arguments Description ----------- -This system call returns filtered data, which might be section or PES -data. The filtered data is transferred from the driver’s internal -circular buffer to buf. The maximum amount of data to be transferred is -implied by count. +This system call returns filtered data, which might be section or Packetized +Elementary Stream (PES) data. The filtered data is transferred from +the driver’s internal circular buffer to ``buf``. The maximum amount of data +to be transferred is implied by count. + +.. note:: + + if a section filter created with + :c:type:`DMX_CHECK_CRC ` flag set, + data that fails on CRC check will be silently ignored. + Return Value ------------ +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 + - - ``EWOULDBLOCK`` + - No data to return and ``O_NONBLOCK`` was specified. - - .. row 1 - - - ``EWOULDBLOCK`` - - - No data to return and O_NONBLOCK was specified. - - - .. row 2 - - - ``EBADF`` - - - fd is not a valid open file descriptor. - - - .. row 3 - - - ``ECRC`` - - - Last section had a CRC error - no data returned. The buffer is - flushed. - - - .. row 4 - - - ``EOVERFLOW`` - - - - - - .. row 5 - - - + - - ``EOVERFLOW`` - The filtered data was not read from the buffer in due time, resulting in non-read data being lost. The buffer is flushed. - - .. row 6 - - - ``ETIMEDOUT`` - - - The section was not loaded within the stated timeout period. See - ioctl DMX_SET_FILTER for how to set a timeout. + - - ``ETIMEDOUT`` + - The section was not loaded within the stated timeout period. + See ioctl :ref:`DMX_SET_FILTER` for how to set a timeout. - - .. row 7 + - - ``EFAULT`` + - The driver failed to write to the callers buffer due to an + invalid \*buf pointer. - - ``EFAULT`` - - The driver failed to write to the callers buffer due to an invalid - \*buf pointer. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fwrite.rst b/Documentation/media/uapi/dvb/dmx-fwrite.rst index 8a90dfe2830756474b570f88c6ee751583379952..519e5733e53b06f512d64f90c8d78095e11f6660 100644 --- a/Documentation/media/uapi/dvb/dmx-fwrite.rst +++ b/Documentation/media/uapi/dvb/dmx-fwrite.rst @@ -2,14 +2,14 @@ .. _dmx_fwrite: -================= -DVB demux write() -================= +======================== +Digital TV demux write() +======================== Name ---- -DVB demux write() +Digital TV demux write() Synopsis @@ -34,42 +34,39 @@ Description ----------- This system call is only provided by the logical device -/dev/dvb/adapter0/dvr0, associated with the physical demux device that +``/dev/dvb/adapter?/dvr?``, associated with the physical demux device that provides the actual DVR functionality. It is used for replay of a digitally recorded Transport Stream. Matching filters have to be defined -in the corresponding physical demux device, /dev/dvb/adapter0/demux0. +in the corresponding physical demux device, ``/dev/dvb/adapter?/demux?``. The amount of data to be transferred is implied by count. Return Value ------------ +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - .. row 1 - - - ``EWOULDBLOCK`` - - - No data was written. This might happen if O_NONBLOCK was + - - ``EWOULDBLOCK`` + - No data was written. This might happen if ``O_NONBLOCK`` was specified and there is no more buffer space available (if - O_NONBLOCK is not specified the function will block until buffer + ``O_NONBLOCK`` is not specified the function will block until buffer space is available). - - .. row 2 - - - ``EBUSY`` - + - - ``EBUSY`` - This error code indicates that there are conflicting requests. The corresponding demux device is setup to receive data from the front- end. Make sure that these filters are stopped and that the - filters with input set to DMX_IN_DVR are started. - - - .. row 3 - - - ``EBADF`` + filters with input set to ``DMX_IN_DVR`` are started. - - fd is not a valid open file descriptor. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-get-caps.rst b/Documentation/media/uapi/dvb/dmx-get-caps.rst deleted file mode 100644 index 145fb520d779f944972fb35a6c0fbac1c3e8ef34..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dmx-get-caps.rst +++ /dev/null @@ -1,41 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _DMX_GET_CAPS: - -============ -DMX_GET_CAPS -============ - -Name ----- - -DMX_GET_CAPS - - -Synopsis --------- - -.. c:function:: int ioctl(fd, DMX_GET_CAPS, struct dmx_caps *caps) - :name: DMX_GET_CAPS - -Arguments ---------- - -``fd`` - File descriptor returned by :c:func:`open() `. - -``caps`` - Pointer to struct :c:type:`dmx_caps` - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-get-event.rst b/Documentation/media/uapi/dvb/dmx-get-event.rst deleted file mode 100644 index 8be626c29158f300b3ffcb6da116a5cdd822ccb4..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dmx-get-event.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _DMX_GET_EVENT: - -============= -DMX_GET_EVENT -============= - -Name ----- - -DMX_GET_EVENT - - -Synopsis --------- - -.. c:function:: int ioctl( int fd, DMX_GET_EVENT, struct dmx_event *ev) - :name: DMX_GET_EVENT - - -Arguments ---------- - -``fd`` - File descriptor returned by :c:func:`open() `. - -``ev`` - Pointer to the location where the event is to be stored. - - -Description ------------ - -This ioctl call returns an event if available. If an event is not -available, the behavior depends on whether the device is in blocking or -non-blocking mode. In the latter case, the call fails immediately with -errno set to ``EWOULDBLOCK``. In the former case, the call blocks until an -event becomes available. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. - - - -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - - - - .. row 1 - - - ``EWOULDBLOCK`` - - - There is no event pending, and the device is in non-blocking mode. diff --git a/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst b/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst index b31634a1cca4722e941e266e9b419a19ed88304d..fbdbc12869d1c7b88433e1226403df58944a510b 100644 --- a/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst +++ b/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst @@ -25,18 +25,40 @@ Arguments File descriptor returned by :c:func:`open() `. ``pids`` - Undocumented. + Array used to store 5 Program IDs. Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +This ioctl allows to query a DVB device to return the first PID used +by audio, video, textext, subtitle and PCR programs on a given service. +They're stored as: + +======================= ======== ======================================= +PID element position content +======================= ======== ======================================= +pids[DMX_PES_AUDIO] 0 first audio PID +pids[DMX_PES_VIDEO] 1 first video PID +pids[DMX_PES_TELETEXT] 2 first teletext PID +pids[DMX_PES_SUBTITLE] 3 first subtitle PID +pids[DMX_PES_PCR] 4 first Program Clock Reference PID +======================= ======== ======================================= + + +.. note:: + + A value equal to 0xffff means that the PID was not filled by the + Kernel. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-get-stc.rst b/Documentation/media/uapi/dvb/dmx-get-stc.rst index 9fc501e8128a1654961c3998fd566699243c1b71..604031f7904b0b06a67913e8f24182e47d950442 100644 --- a/Documentation/media/uapi/dvb/dmx-get-stc.rst +++ b/Documentation/media/uapi/dvb/dmx-get-stc.rst @@ -25,34 +25,42 @@ Arguments File descriptor returned by :c:func:`open() `. ``stc`` - Pointer to the location where the stc is to be stored. + Pointer to :c:type:`dmx_stc` where the stc data is to be stored. Description ----------- This ioctl call returns the current value of the system time counter -(which is driven by a PES filter of type DMX_PES_PCR). Some hardware -supports more than one STC, so you must specify which one by setting the -num field of stc before the ioctl (range 0...n). The result is returned -in form of a ratio with a 64 bit numerator and a 32 bit denominator, so -the real 90kHz STC value is stc->stc / stc->base . +(which is driven by a PES filter of type :c:type:`DMX_PES_PCR `). +Some hardware supports more than one STC, so you must specify which one by +setting the :c:type:`num ` field of stc before the ioctl (range 0...n). +The result is returned in form of a ratio with a 64 bit numerator +and a 32 bit denominator, so the real 90kHz STC value is +``stc->stc / stc->base``. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 - + :widths: 1 16 - .. row 1 - ``EINVAL`` - Invalid stc number. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-remove-pid.rst b/Documentation/media/uapi/dvb/dmx-remove-pid.rst index e411495c619ca1fad6aa9a34f7409954ea668f78..456cc2ded2c053ac1f3f64b37847b7bebb59c31b 100644 --- a/Documentation/media/uapi/dvb/dmx-remove-pid.rst +++ b/Documentation/media/uapi/dvb/dmx-remove-pid.rst @@ -34,13 +34,17 @@ Description This ioctl call allows to remove a PID when multiple PIDs are set on a transport stream filter, e. g. a filter previously set up with output -equal to DMX_OUT_TSDEMUX_TAP, created via either -DMX_SET_PES_FILTER or DMX_ADD_PID. +equal to :c:type:`DMX_OUT_TSDEMUX_TAP `, created via either +:ref:`DMX_SET_PES_FILTER` or :ref:`DMX_ADD_PID`. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst b/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst index f2f7379f29edc67bae1b91ad04aa366b38095fbd..74fd076a9b901581cd2c43c9ab3d8902ec33700d 100644 --- a/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst +++ b/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst @@ -33,13 +33,18 @@ Description This ioctl call is used to set the size of the circular buffer used for filtered data. The default size is two maximum sized sections, i.e. if -this function is not called a buffer size of 2 \* 4096 bytes will be +this function is not called a buffer size of ``2 * 4096`` bytes will be used. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the + +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-filter.rst b/Documentation/media/uapi/dvb/dmx-set-filter.rst index 1d50c803d69a213bd2b205f832a5f28d8ba57c1c..88594b8d3846f6725503b62e7acc8cde47e1ce15 100644 --- a/Documentation/media/uapi/dvb/dmx-set-filter.rst +++ b/Documentation/media/uapi/dvb/dmx-set-filter.rst @@ -40,13 +40,18 @@ state whether a section should be CRC-checked, whether the filter should be a â€one-shot†filter, i.e. if the filtering operation should be stopped after the first section is received, and whether the filtering operation should be started immediately (without waiting for a -DMX_START ioctl call). If a filter was previously set-up, this filter -will be canceled, and the receive buffer will be flushed. +:ref:`DMX_START` ioctl call). If a filter was previously set-up, this +filter will be canceled, and the receive buffer will be flushed. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the + +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst b/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst index 145451d04f7dd4680d8c0970962c9fd9c5d9adfd..d70e7bf96a41c36c8557f8a2b800164de17d34a8 100644 --- a/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst +++ b/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst @@ -42,15 +42,17 @@ capability is supported. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - .. row 1 @@ -61,3 +63,7 @@ appropriately. The generic error codes are described at the There are active filters filtering data from another input source. Make sure that these filters are stopped before starting this filter. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-source.rst b/Documentation/media/uapi/dvb/dmx-set-source.rst deleted file mode 100644 index ac7f77b25e06446b2fcb694223bacbe8f489fc32..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dmx-set-source.rst +++ /dev/null @@ -1,44 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _DMX_SET_SOURCE: - -============== -DMX_SET_SOURCE -============== - -Name ----- - -DMX_SET_SOURCE - - -Synopsis --------- - -.. c:function:: int ioctl(fd, DMX_SET_SOURCE, struct dmx_source *src) - :name: DMX_SET_SOURCE - - -Arguments ---------- - - -``fd`` - File descriptor returned by :c:func:`open() `. - -``src`` - Undocumented. - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-start.rst b/Documentation/media/uapi/dvb/dmx-start.rst index 641f3e017fb19f152beb5858e864b7ce6c20b21d..36700e7752967209661d8036668226eed478c4ff 100644 --- a/Documentation/media/uapi/dvb/dmx-start.rst +++ b/Documentation/media/uapi/dvb/dmx-start.rst @@ -29,15 +29,16 @@ Description ----------- This ioctl call is used to start the actual filtering operation defined -via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER. +via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER`. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| @@ -51,7 +52,7 @@ appropriately. The generic error codes are described at the - ``EINVAL`` - Invalid argument, i.e. no filtering parameters provided via the - DMX_SET_FILTER or DMX_SET_PES_FILTER functions. + :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` ioctls. - .. row 2 @@ -61,3 +62,7 @@ appropriately. The generic error codes are described at the There are active filters filtering data from another input source. Make sure that these filters are stopped before starting this filter. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-stop.rst b/Documentation/media/uapi/dvb/dmx-stop.rst index 569a3df44923f55b33d544bff4df9d26705ac26b..6d9c927bcd5f995e110bc12ef476db312ed6b439 100644 --- a/Documentation/media/uapi/dvb/dmx-stop.rst +++ b/Documentation/media/uapi/dvb/dmx-stop.rst @@ -29,13 +29,17 @@ Description ----------- This ioctl call is used to stop the actual filtering operation defined -via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and -started via the DMX_START command. +via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` and +started via the :ref:`DMX_START` command. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx_fcalls.rst b/Documentation/media/uapi/dvb/dmx_fcalls.rst index 77a1554d9834ae0e216315347a8b70721943edc2..a17289143220396c8a6fcbbae9e640d4effaff1d 100644 --- a/Documentation/media/uapi/dvb/dmx_fcalls.rst +++ b/Documentation/media/uapi/dvb/dmx_fcalls.rst @@ -18,10 +18,7 @@ Demux Function Calls dmx-set-filter dmx-set-pes-filter dmx-set-buffer-size - dmx-get-event dmx-get-stc dmx-get-pes-pids - dmx-get-caps - dmx-set-source dmx-add-pid dmx-remove-pid diff --git a/Documentation/media/uapi/dvb/dmx_h.rst b/Documentation/media/uapi/dvb/dmx_h.rst deleted file mode 100644 index 4fd1704a0833cb2f1538b70ea5fa3c840a3d824b..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dmx_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _dmx_h: - -********************* -DVB Demux Header File -********************* - -.. kernel-include:: $BUILDDIR/dmx.h.rst diff --git a/Documentation/media/uapi/dvb/dmx_types.rst b/Documentation/media/uapi/dvb/dmx_types.rst index 80dd659860d7c549d1f2a3b67034b68ed45dded0..2a023a4f516c75bb39ecf521b27d7b196f6bc2ad 100644 --- a/Documentation/media/uapi/dvb/dmx_types.rst +++ b/Documentation/media/uapi/dvb/dmx_types.rst @@ -6,227 +6,4 @@ Demux Data Types **************** -Output for the demux -==================== - -.. c:type:: dmx_output - -.. tabularcolumns:: |p{5.0cm}|p{12.5cm}| - -.. flat-table:: enum dmx_output - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _DMX-OUT-DECODER: - - DMX_OUT_DECODER - - - Streaming directly to decoder. - - - .. row 3 - - - .. _DMX-OUT-TAP: - - DMX_OUT_TAP - - - Output going to a memory buffer (to be retrieved via the read - command). Delivers the stream output to the demux device on which - the ioctl is called. - - - .. row 4 - - - .. _DMX-OUT-TS-TAP: - - DMX_OUT_TS_TAP - - - Output multiplexed into a new TS (to be retrieved by reading from - the logical DVR device). Routes output to the logical DVR device - ``/dev/dvb/adapter?/dvr?``, which delivers a TS multiplexed from - all filters for which ``DMX_OUT_TS_TAP`` was specified. - - - .. row 5 - - - .. _DMX-OUT-TSDEMUX-TAP: - - DMX_OUT_TSDEMUX_TAP - - - Like :ref:`DMX_OUT_TS_TAP ` but retrieved - from the DMX device. - - -dmx_input_t -=========== - -.. c:type:: dmx_input - -.. code-block:: c - - typedef enum - { - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ - } dmx_input_t; - - -dmx_pes_type_t -============== - -.. c:type:: dmx_pes_type - - -.. code-block:: c - - typedef enum - { - DMX_PES_AUDIO0, - DMX_PES_VIDEO0, - DMX_PES_TELETEXT0, - DMX_PES_SUBTITLE0, - DMX_PES_PCR0, - - DMX_PES_AUDIO1, - DMX_PES_VIDEO1, - DMX_PES_TELETEXT1, - DMX_PES_SUBTITLE1, - DMX_PES_PCR1, - - DMX_PES_AUDIO2, - DMX_PES_VIDEO2, - DMX_PES_TELETEXT2, - DMX_PES_SUBTITLE2, - DMX_PES_PCR2, - - DMX_PES_AUDIO3, - DMX_PES_VIDEO3, - DMX_PES_TELETEXT3, - DMX_PES_SUBTITLE3, - DMX_PES_PCR3, - - DMX_PES_OTHER - } dmx_pes_type_t; - - -struct dmx_filter -================= - -.. c:type:: dmx_filter - -.. code-block:: c - - typedef struct dmx_filter - { - __u8 filter[DMX_FILTER_SIZE]; - __u8 mask[DMX_FILTER_SIZE]; - __u8 mode[DMX_FILTER_SIZE]; - } dmx_filter_t; - - -.. c:type:: dmx_sct_filter_params - -struct dmx_sct_filter_params -============================ - - -.. code-block:: c - - struct dmx_sct_filter_params - { - __u16 pid; - dmx_filter_t filter; - __u32 timeout; - __u32 flags; - #define DMX_CHECK_CRC 1 - #define DMX_ONESHOT 2 - #define DMX_IMMEDIATE_START 4 - #define DMX_KERNEL_CLIENT 0x8000 - }; - - -struct dmx_pes_filter_params -============================ - -.. c:type:: dmx_pes_filter_params - -.. code-block:: c - - struct dmx_pes_filter_params - { - __u16 pid; - dmx_input_t input; - dmx_output_t output; - dmx_pes_type_t pes_type; - __u32 flags; - }; - - -struct dmx_event -================ - -.. c:type:: dmx_event - -.. code-block:: c - - struct dmx_event - { - dmx_event_t event; - time_t timeStamp; - union - { - dmx_scrambling_status_t scrambling; - } u; - }; - - -struct dmx_stc -============== - -.. c:type:: dmx_stc - -.. code-block:: c - - struct dmx_stc { - unsigned int num; /* input : which STC? 0..N */ - unsigned int base; /* output: divisor for stc to get 90 kHz clock */ - __u64 stc; /* output: stc in 'base'*90 kHz units */ - }; - - -struct dmx_caps -=============== - -.. c:type:: dmx_caps - -.. code-block:: c - - typedef struct dmx_caps { - __u32 caps; - int num_decoders; - } dmx_caps_t; - - -enum dmx_source -=============== - -.. c:type:: dmx_source - -.. code-block:: c - - typedef enum dmx_source { - DMX_SOURCE_FRONT0 = 0, - DMX_SOURCE_FRONT1, - DMX_SOURCE_FRONT2, - DMX_SOURCE_FRONT3, - DMX_SOURCE_DVR0 = 16, - DMX_SOURCE_DVR1, - DMX_SOURCE_DVR2, - DMX_SOURCE_DVR3 - } dmx_source_t; +.. kernel-doc:: include/uapi/linux/dvb/dmx.h diff --git a/Documentation/media/uapi/dvb/dtv-fe-stats.rst b/Documentation/media/uapi/dvb/dtv-fe-stats.rst deleted file mode 100644 index e8a02a1f138d328e5ef45a39a97d6c85186dbbf4..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dtv-fe-stats.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_fe_stats - -******************* -struct dtv_fe_stats -******************* - - -.. code-block:: c - - #define MAX_DTV_STATS 4 - - struct dtv_fe_stats { - __u8 len; - struct dtv_stats stat[MAX_DTV_STATS]; - } __packed; diff --git a/Documentation/media/uapi/dvb/dtv-properties.rst b/Documentation/media/uapi/dvb/dtv-properties.rst deleted file mode 100644 index 48c4e834ad11513b89cbd16a52eb00de5090d59b..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dtv-properties.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_properties - -********************* -struct dtv_properties -********************* - - -.. code-block:: c - - struct dtv_properties { - __u32 num; - struct dtv_property *props; - }; diff --git a/Documentation/media/uapi/dvb/dtv-property.rst b/Documentation/media/uapi/dvb/dtv-property.rst deleted file mode 100644 index 3ddc3474b00ee3a19ef405b7a801c945c957a131..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dtv-property.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_property - -******************* -struct dtv_property -******************* - - -.. code-block:: c - - /* Reserved fields should be set to 0 */ - - struct dtv_property { - __u32 cmd; - __u32 reserved[3]; - union { - __u32 data; - struct dtv_fe_stats st; - struct { - __u8 data[32]; - __u32 len; - __u32 reserved1[3]; - void *reserved2; - } buffer; - } u; - int result; - } __attribute__ ((packed)); - - /* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ - #define DTV_IOCTL_MAX_MSGS 64 diff --git a/Documentation/media/uapi/dvb/dtv-stats.rst b/Documentation/media/uapi/dvb/dtv-stats.rst deleted file mode 100644 index 35239e72bf74d29e1ce981736c743969e40a9a70..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dtv-stats.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_stats - -**************** -struct dtv_stats -**************** - - -.. code-block:: c - - struct dtv_stats { - __u8 scale; /* enum fecap_scale_params type */ - union { - __u64 uvalue; /* for counters and relative scales */ - __s64 svalue; /* for 1/1000 dB measures */ - }; - } __packed; diff --git a/Documentation/media/uapi/dvb/dvb-fe-read-status.rst b/Documentation/media/uapi/dvb/dvb-fe-read-status.rst index 76c20612b274d03c02ad90d92fca65892da28bbf..212f032cad8bd5c405ac5d09364f9de63416338a 100644 --- a/Documentation/media/uapi/dvb/dvb-fe-read-status.rst +++ b/Documentation/media/uapi/dvb/dvb-fe-read-status.rst @@ -20,6 +20,6 @@ Signal statistics are provided via .. note:: Most statistics require the demodulator to be fully locked - (e. g. with FE_HAS_LOCK bit set). See + (e. g. with :c:type:`FE_HAS_LOCK ` bit set). See :ref:`Frontend statistics indicators ` for more details. diff --git a/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst b/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst index 899fd5c3545ee268e8950db257d9d092e29443ff..b152166f8fa7efc24e99cecadebcea9ff0d9c1ea 100644 --- a/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst +++ b/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst @@ -24,7 +24,7 @@ instead, in order to be able to support the newer System Delivery like DVB-S2, DVB-T2, DVB-C2, ISDB, etc. All kinds of parameters are combined as a union in the -FrontendParameters structure: +``dvb_frontend_parameters`` structure: .. code-block:: c diff --git a/Documentation/media/uapi/dvb/dvbapi.rst b/Documentation/media/uapi/dvb/dvbapi.rst index 37680137e3f276f0c5c3aec1b5b0ab63409ac91a..18c86b3a3af1ecc1d81d7d46ca4a3b37db1dd9fd 100644 --- a/Documentation/media/uapi/dvb/dvbapi.rst +++ b/Documentation/media/uapi/dvb/dvbapi.rst @@ -10,12 +10,27 @@ Part II - Digital TV API .. note:: - This API is also known as **DVB API**, although it is generic - enough to support all digital TV standards. + This API is also known as Linux **DVB API**. + + It it was originally written to support the European digital TV + standard (DVB), and later extended to support all digital TV standards. + + In order to avoid confusion, within this document, it was opted to refer to + it, and to associated hardware as **Digital TV**. + + The word **DVB** is reserved to be used for: + + - the Digital TV API version + (e. g. DVB API version 3 or DVB API version 5); + - digital TV data types (enums, structs, defines, etc); + - digital TV device nodes (``/dev/dvb/...``); + - the European DVB standard. **Version 5.10** -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents @@ -30,12 +45,7 @@ Part II - Digital TV API net legacy_dvb_apis examples - audio_h - ca_h - dmx_h - frontend_h - net_h - video_h + headers ********************** @@ -46,11 +56,11 @@ Authors: - J. K. Metzler, Ralph - - Original author of the DVB API documentation. + - Original author of the Digital TV API documentation. - O. C. Metzler, Marcus - - Original author of the DVB API documentation. + - Original author of the Digital TV API documentation. - Carvalho Chehab, Mauro @@ -58,21 +68,26 @@ Authors: **Copyright** |copy| 2002-2003 : Convergence GmbH -**Copyright** |copy| 2009-2016 : Mauro Carvalho Chehab +**Copyright** |copy| 2009-2017 : Mauro Carvalho Chehab **************** Revision History **************** +:revision: 2.2.0 / 2017-09-01 (*mcc*) + +Most gaps between the uAPI document and the Kernel implementation +got fixed for the non-legacy API. + :revision: 2.1.0 / 2015-05-29 (*mcc*) DocBook improvements and cleanups, in order to document the system calls on a more standard way and provide more description about the current -DVB API. +Digital TV API. :revision: 2.0.4 / 2011-05-06 (*mcc*) -Add more information about DVB APIv5, better describing the frontend +Add more information about DVBv5 API, better describing the frontend GET/SET props ioctl's. diff --git a/Documentation/media/uapi/dvb/dvbproperty-006.rst b/Documentation/media/uapi/dvb/dvbproperty-006.rst deleted file mode 100644 index 3343a0f306fe2df57584e8fe865325e6c2a6872c..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/dvbproperty-006.rst +++ /dev/null @@ -1,12 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -************** -Property types -************** - -On :ref:`FE_GET_PROPERTY and FE_SET_PROPERTY `, -the actual action is determined by the dtv_property cmd/data pairs. -With one single ioctl, is possible to get/set up to 64 properties. The -actual meaning of each property is described on the next sections. - -The available frontend property types are shown on the next section. diff --git a/Documentation/media/uapi/dvb/dvbproperty.rst b/Documentation/media/uapi/dvb/dvbproperty.rst index dd2d71ce43fa2946d48e63187009a48855ddfca7..1a56c1724e595b849720c9f17b980fa01aec028b 100644 --- a/Documentation/media/uapi/dvb/dvbproperty.rst +++ b/Documentation/media/uapi/dvb/dvbproperty.rst @@ -2,63 +2,76 @@ .. _frontend-properties: -DVB Frontend properties -======================= +************** +Property types +************** Tuning into a Digital TV physical channel and starting decoding it requires changing a set of parameters, in order to control the tuner, the demodulator, the Linear Low-noise Amplifier (LNA) and to set the -antenna subsystem via Satellite Equipment Control (SEC), on satellite -systems. The actual parameters are specific to each particular digital +antenna subsystem via Satellite Equipment Control - SEC (on satellite +systems). The actual parameters are specific to each particular digital TV standards, and may change as the digital TV specs evolves. -In the past, the strategy used was to have a union with the parameters -needed to tune for DVB-S, DVB-C, DVB-T and ATSC delivery systems grouped -there. The problem is that, as the second generation standards appeared, -those structs were not big enough to contain the additional parameters. -Also, the union didn't have any space left to be expanded without -breaking userspace. So, the decision was to deprecate the legacy -union/struct based approach, in favor of a properties set approach. +In the past (up to DVB API version 3 - DVBv3), the strategy used was to have a +union with the parameters needed to tune for DVB-S, DVB-C, DVB-T and +ATSC delivery systems grouped there. The problem is that, as the second +generation standards appeared, the size of such union was not big +enough to group the structs that would be required for those new +standards. Also, extending it would break userspace. + +So, the legacy union/struct based approach was deprecated, in favor +of a properties set approach. On such approach, +:ref:`FE_GET_PROPERTY and FE_SET_PROPERTY ` are used +to setup the frontend and read its status. + +The actual action is determined by a set of dtv_property cmd/data pairs. +With one single ioctl, is possible to get/set up to 64 properties. + +This section describes the new and recommended way to set the frontend, +with supports all digital TV delivery systems. .. note:: - On Linux DVB API version 3, setting a frontend were done via - struct :c:type:`dvb_frontend_parameters`. - This got replaced on version 5 (also called "S2API", as this API were - added originally_enabled to provide support for DVB-S2), because the - old API has a very limited support to new standards and new hardware. - This section describes the new and recommended way to set the frontend, - with suppports all digital TV delivery systems. - -Example: with the properties based approach, in order to set the tuner -to a DVB-C channel at 651 kHz, modulated with 256-QAM, FEC 3/4 and -symbol rate of 5.217 Mbauds, those properties should be sent to + 1. On Linux DVB API version 3, setting a frontend was done via + struct :c:type:`dvb_frontend_parameters`. + + 2. Don't use DVB API version 3 calls on hardware with supports + newer standards. Such API provides no suport or a very limited + support to new standards and/or new hardware. + + 3. Nowadays, most frontends support multiple delivery systems. + Only with DVB API version 5 calls it is possible to switch between + the multiple delivery systems supported by a frontend. + + 4. DVB API version 5 is also called *S2API*, as the first + new standard added to it was DVB-S2. + +**Example**: in order to set the hardware to tune into a DVB-C channel +at 651 kHz, modulated with 256-QAM, FEC 3/4 and symbol rate of 5.217 +Mbauds, those properties should be sent to :ref:`FE_SET_PROPERTY ` ioctl: -- :ref:`DTV_DELIVERY_SYSTEM ` = - SYS_DVBC_ANNEX_A + :ref:`DTV_DELIVERY_SYSTEM ` = SYS_DVBC_ANNEX_A -- :ref:`DTV_FREQUENCY ` = 651000000 + :ref:`DTV_FREQUENCY ` = 651000000 -- :ref:`DTV_MODULATION ` = QAM_256 + :ref:`DTV_MODULATION ` = QAM_256 -- :ref:`DTV_INVERSION ` = INVERSION_AUTO + :ref:`DTV_INVERSION ` = INVERSION_AUTO -- :ref:`DTV_SYMBOL_RATE ` = 5217000 + :ref:`DTV_SYMBOL_RATE ` = 5217000 -- :ref:`DTV_INNER_FEC ` = FEC_3_4 + :ref:`DTV_INNER_FEC ` = FEC_3_4 -- :ref:`DTV_TUNE ` + :ref:`DTV_TUNE ` The code that would that would do the above is show in :ref:`dtv-prop-example`. -.. _dtv-prop-example: - -Example: Setting digital TV frontend properties -=============================================== - .. code-block:: c + :caption: Example: Setting digital TV frontend properties + :name: dtv-prop-example #include #include @@ -102,17 +115,12 @@ Example: Setting digital TV frontend properties provides methods for usual operations like program scanning and to read/write channel descriptor files. - .. toctree:: :maxdepth: 1 - dtv-stats - dtv-fe-stats - dtv-property - dtv-properties - dvbproperty-006 fe_property_parameters frontend-stat-properties frontend-property-terrestrial-systems frontend-property-cable-systems frontend-property-satellite-systems + frontend-header diff --git a/Documentation/media/uapi/dvb/dvbstb.svg b/Documentation/media/uapi/dvb/dvbstb.svg index c4140fb518afc91cd5e84245d14b8313a498231a..f6fe2f8373737410ee0556dfa814a658cd2b4aad 100644 --- a/Documentation/media/uapi/dvb/dvbstb.svg +++ b/Documentation/media/uapi/dvb/dvbstb.svg @@ -1,651 +1,16 @@ - -image/svg+xmlAntena -Frontend -CA -Demux -SEC -Audio -Video -TV - \ No newline at end of file + +image/svg+xmlAntena +Frontend +CA +Demux +SEC +Audio +Video +TV +Decoder +Decoder + diff --git a/Documentation/media/uapi/dvb/examples.rst b/Documentation/media/uapi/dvb/examples.rst index 1a94966312c05fe2888c3b9a4990852924ca7927..e0f627ca2e4dd73c3dfe4b3922749e763cda5d06 100644 --- a/Documentation/media/uapi/dvb/examples.rst +++ b/Documentation/media/uapi/dvb/examples.rst @@ -6,8 +6,8 @@ Examples ******** -In this section we would like to present some examples for using the DVB -API. +In this section we would like to present some examples for using the Digital +TV API. .. note:: diff --git a/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst b/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst index 302db2857f90b4fdde80e94dec5595c80ae1ca54..f220ee351e15fc1085c51e42e929bf082395144a 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst @@ -26,8 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - pointer to struct - :c:type:`dvb_diseqc_slave_reply` + pointer to struct :c:type:`dvb_diseqc_slave_reply`. Description @@ -35,46 +34,15 @@ Description Receives reply from a DiSEqC 2.0 command. -.. c:type:: dvb_diseqc_slave_reply - -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| - -.. flat-table:: struct dvb_diseqc_slave_reply - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - - - .. row 1 - - - uint8_t - - - msg[4] - - - DiSEqC message (framing, data[3]) - - - .. row 2 - - - uint8_t - - - msg_len - - - Length of the DiSEqC message. Valid values are 0 to 4, where 0 - means no msg - - - .. row 3 - - - int - - - timeout - - - Return from ioctl after timeout ms with errorcode when no message - was received - +The received message is stored at the buffer pointed by ``argp``. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst b/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst index 75116f283faf2798afe50a7c5a0b51090703672f..78476c1c7bf5568094621c28a0f0753c8e61ad07 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst @@ -31,12 +31,16 @@ Description If the bus has been automatically powered off due to power overload, this ioctl call restores the power to the bus. The call requires read/write access to the device. This call has no effect if the device -is manually powered off. Not all DVB adapters support this ioctl. +is manually powered off. Not all Digital TV adapters support this ioctl. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst b/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst index e962f6ec5aaf076115b34590248ec4be29b3620f..a7e05914efae534e02c635ac8a31342b0983799c 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst @@ -26,7 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``tone`` - an integer enumered value described at :c:type:`fe_sec_mini_cmd` + An integer enumered value described at :c:type:`fe_sec_mini_cmd`. Description @@ -39,39 +39,14 @@ read/write permissions. It provides support for what's specified at `Digital Satellite Equipment Control (DiSEqC) - Simple "ToneBurst" Detection Circuit specification. `__ -.. c:type:: fe_sec_mini_cmd - -.. flat-table:: enum fe_sec_mini_cmd - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SEC-MINI-A: - - ``SEC_MINI_A`` - - - Sends a mini-DiSEqC 22kHz '0' Tone Burst to select satellite-A - - - .. row 3 - - - .. _SEC-MINI-B: - - ``SEC_MINI_B`` - - - Sends a mini-DiSEqC 22kHz '1' Data Burst to select satellite-B - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst b/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst index bbcab3df39b516d903c933d2fcc384b2fc6e5421..6bd3994edfc2c010db18294ef16e1b1d87b7bdf5 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst @@ -33,39 +33,17 @@ Arguments Description =========== -Sends a DiSEqC command to the antenna subsystem. - - -.. c:type:: dvb_diseqc_master_cmd - -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| - -.. flat-table:: struct dvb_diseqc_master_cmd - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - - - .. row 1 - - - uint8_t - - - msg[6] - - - DiSEqC message (framing, address, command, data[3]) - - - .. row 2 - - - uint8_t - - - msg_len - - - Length of the DiSEqC message. Valid values are 3 to 6 +Sends the DiSEqC command pointed by :c:type:`dvb_diseqc_master_cmd` +to the antenna subsystem. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst b/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst index f41371f124562bb189942ff7cb7a66d630dfbfb4..dcf2d20d460fc79444921ecf12cdb1d13ed9bd7b 100644 --- a/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst +++ b/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst @@ -46,6 +46,10 @@ dishes were already legacy in 2004. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst b/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst index bacafbc462d2aa5d1b2129ab9259cb0b7056c881..b20cb360fe37962a6c75c60c4e7802fcadbfb6cc 100644 --- a/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst +++ b/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst @@ -45,6 +45,10 @@ voltages. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-event.rst b/Documentation/media/uapi/dvb/fe-get-event.rst index 8a719c33073d3eda33503ee24a8e3ec6e0f82db1..505db94bf1835619478cb392d8773bcab9635a77 100644 --- a/Documentation/media/uapi/dvb/fe-get-event.rst +++ b/Documentation/media/uapi/dvb/fe-get-event.rst @@ -44,10 +44,10 @@ an event becomes available. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. flat-table:: @@ -66,3 +66,6 @@ appropriately. The generic error codes are described at the - ``EOVERFLOW`` - Overflow in event queue - one or more events were lost. + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-frontend.rst b/Documentation/media/uapi/dvb/fe-get-frontend.rst index d53a3f8237c334e28d9eead08e1b831eb133f0c3..5db552cedd703019e12f5515a36c72ef924f8b1e 100644 --- a/Documentation/media/uapi/dvb/fe-get-frontend.rst +++ b/Documentation/media/uapi/dvb/fe-get-frontend.rst @@ -42,11 +42,10 @@ this command, read-only access to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. - +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. flat-table:: :header-rows: 0 @@ -58,3 +57,6 @@ appropriately. The generic error codes are described at the - ``EINVAL`` - Maximum supported symbol rate reached. + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-info.rst b/Documentation/media/uapi/dvb/fe-get-info.rst index e3d64b251f61f4365587ad2526c9b15309a2549f..49307c0abfee1d96cb83730ce5311c0444a04308 100644 --- a/Documentation/media/uapi/dvb/fe-get-info.rst +++ b/Documentation/media/uapi/dvb/fe-get-info.rst @@ -9,7 +9,8 @@ ioctl FE_GET_INFO Name ==== -FE_GET_INFO - Query DVB frontend capabilities and returns information about the - front-end. This call only requires read-only access to the device +FE_GET_INFO - Query Digital TV frontend capabilities and returns information +about the - front-end. This call only requires read-only access to the device. Synopsis @@ -33,119 +34,13 @@ Arguments Description =========== -All DVB frontend devices support the ``FE_GET_INFO`` ioctl. It is used -to identify kernel devices compatible with this specification and to +All Digital TV frontend devices support the :ref:`FE_GET_INFO` ioctl. It is +used to identify kernel devices compatible with this specification and to obtain information about driver and hardware capabilities. The ioctl takes a pointer to dvb_frontend_info which is filled by the driver. When the driver is not compatible with this specification the ioctl returns an error. -.. c:type:: dvb_frontend_info - -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| - -.. flat-table:: struct dvb_frontend_info - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - - - .. row 1 - - - char - - - name[128] - - - Name of the frontend - - - .. row 2 - - - fe_type_t - - - type - - - **DEPRECATED**. DVBv3 type. Should not be used on modern programs, - as a frontend may have more than one type. So, the DVBv5 API - should be used instead to enumerate and select the frontend type. - - - .. row 3 - - - uint32_t - - - frequency_min - - - Minimal frequency supported by the frontend - - - .. row 4 - - - uint32_t - - - frequency_max - - - Maximal frequency supported by the frontend - - - .. row 5 - - - uint32_t - - - frequency_stepsize - - - Frequency step - all frequencies are multiple of this value - - - .. row 6 - - - uint32_t - - - frequency_tolerance - - - Tolerance of the frequency - - - .. row 7 - - - uint32_t - - - symbol_rate_min - - - Minimal symbol rate (for Cable/Satellite systems), in bauds - - - .. row 8 - - - uint32_t - - - symbol_rate_max - - - Maximal symbol rate (for Cable/Satellite systems), in bauds - - - .. row 9 - - - uint32_t - - - symbol_rate_tolerance - - - Maximal symbol rate tolerance, in ppm - - - .. row 10 - - - uint32_t - - - notifier_delay - - - **DEPRECATED**. Not used by any driver. - - - .. row 11 - - - enum :c:type:`fe_caps` - - - caps - - - Capabilities supported by the frontend - - -.. note:: - - The frequencies are specified in Hz for Terrestrial and Cable - systems. They're specified in kHz for Satellite systems - frontend capabilities ===================== @@ -153,274 +48,16 @@ frontend capabilities Capabilities describe what a frontend can do. Some capabilities are supported only on some specific frontend types. -.. c:type:: fe_caps - -.. tabularcolumns:: |p{6.5cm}|p{11.0cm}| - -.. flat-table:: enum fe_caps - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _FE-IS-STUPID: - - ``FE_IS_STUPID`` - - - There's something wrong at the frontend, and it can't report its - capabilities - - - .. row 3 - - - .. _FE-CAN-INVERSION-AUTO: - - ``FE_CAN_INVERSION_AUTO`` - - - The frontend is capable of auto-detecting inversion - - - .. row 4 - - - .. _FE-CAN-FEC-1-2: - - ``FE_CAN_FEC_1_2`` - - - The frontend supports FEC 1/2 - - - .. row 5 - - - .. _FE-CAN-FEC-2-3: - - ``FE_CAN_FEC_2_3`` - - - The frontend supports FEC 2/3 - - - .. row 6 - - - .. _FE-CAN-FEC-3-4: - - ``FE_CAN_FEC_3_4`` - - - The frontend supports FEC 3/4 - - - .. row 7 - - - .. _FE-CAN-FEC-4-5: - - ``FE_CAN_FEC_4_5`` - - - The frontend supports FEC 4/5 - - - .. row 8 - - - .. _FE-CAN-FEC-5-6: - - ``FE_CAN_FEC_5_6`` - - - The frontend supports FEC 5/6 - - - .. row 9 - - - .. _FE-CAN-FEC-6-7: - - ``FE_CAN_FEC_6_7`` - - - The frontend supports FEC 6/7 - - - .. row 10 - - - .. _FE-CAN-FEC-7-8: - - ``FE_CAN_FEC_7_8`` - - - The frontend supports FEC 7/8 - - - .. row 11 - - - .. _FE-CAN-FEC-8-9: - - ``FE_CAN_FEC_8_9`` - - - The frontend supports FEC 8/9 - - - .. row 12 - - - .. _FE-CAN-FEC-AUTO: - - ``FE_CAN_FEC_AUTO`` - - - The frontend can autodetect FEC. - - - .. row 13 - - - .. _FE-CAN-QPSK: - - ``FE_CAN_QPSK`` - - - The frontend supports QPSK modulation - - - .. row 14 - - - .. _FE-CAN-QAM-16: - - ``FE_CAN_QAM_16`` - - - The frontend supports 16-QAM modulation - - - .. row 15 - - - .. _FE-CAN-QAM-32: - - ``FE_CAN_QAM_32`` - - - The frontend supports 32-QAM modulation - - - .. row 16 - - - .. _FE-CAN-QAM-64: - - ``FE_CAN_QAM_64`` - - - The frontend supports 64-QAM modulation - - - .. row 17 - - - .. _FE-CAN-QAM-128: - - ``FE_CAN_QAM_128`` - - - The frontend supports 128-QAM modulation - - - .. row 18 - - - .. _FE-CAN-QAM-256: - - ``FE_CAN_QAM_256`` - - - The frontend supports 256-QAM modulation - - - .. row 19 - - - .. _FE-CAN-QAM-AUTO: - - ``FE_CAN_QAM_AUTO`` - - - The frontend can autodetect modulation - - - .. row 20 - - - .. _FE-CAN-TRANSMISSION-MODE-AUTO: - - ``FE_CAN_TRANSMISSION_MODE_AUTO`` - - - The frontend can autodetect the transmission mode - - - .. row 21 - - - .. _FE-CAN-BANDWIDTH-AUTO: - - ``FE_CAN_BANDWIDTH_AUTO`` - - - The frontend can autodetect the bandwidth - - - .. row 22 - - - .. _FE-CAN-GUARD-INTERVAL-AUTO: - - ``FE_CAN_GUARD_INTERVAL_AUTO`` - - - The frontend can autodetect the guard interval - - - .. row 23 - - - .. _FE-CAN-HIERARCHY-AUTO: - - ``FE_CAN_HIERARCHY_AUTO`` - - - The frontend can autodetect hierarch - - - .. row 24 - - - .. _FE-CAN-8VSB: - - ``FE_CAN_8VSB`` - - - The frontend supports 8-VSB modulation - - - .. row 25 - - - .. _FE-CAN-16VSB: - - ``FE_CAN_16VSB`` - - - The frontend supports 16-VSB modulation - - - .. row 26 - - - .. _FE-HAS-EXTENDED-CAPS: - - ``FE_HAS_EXTENDED_CAPS`` - - - Currently, unused - - - .. row 27 - - - .. _FE-CAN-MULTISTREAM: - - ``FE_CAN_MULTISTREAM`` - - - The frontend supports multistream filtering - - - .. row 28 - - - .. _FE-CAN-TURBO-FEC: - - ``FE_CAN_TURBO_FEC`` - - - The frontend supports turbo FEC modulation - - - .. row 29 - - - .. _FE-CAN-2G-MODULATION: - - ``FE_CAN_2G_MODULATION`` - - - The frontend supports "2nd generation modulation" (DVB-S2/T2)> - - - .. row 30 - - - .. _FE-NEEDS-BENDING: - - ``FE_NEEDS_BENDING`` - - - Not supported anymore, don't use it - - - .. row 31 - - - .. _FE-CAN-RECOVER: - - ``FE_CAN_RECOVER`` - - - The frontend can recover from a cable unplug automatically - - - .. row 32 - - - .. _FE-CAN-MUTE-TS: - - ``FE_CAN_MUTE_TS`` - - - The frontend can stop spurious TS data output +The frontend capabilities are described at :c:type:`fe_caps`. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-property.rst b/Documentation/media/uapi/dvb/fe-get-property.rst index 015d4db597b58a5e5db60539727e743c64bbb552..948d2ba84f2ce0991231f90f2529979802cbc974 100644 --- a/Documentation/media/uapi/dvb/fe-get-property.rst +++ b/Documentation/media/uapi/dvb/fe-get-property.rst @@ -29,13 +29,13 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - pointer to struct :c:type:`dtv_properties` + Pointer to struct :c:type:`dtv_properties`. Description =========== -All DVB frontend devices support the ``FE_SET_PROPERTY`` and +All Digital TV frontend devices support the ``FE_SET_PROPERTY`` and ``FE_GET_PROPERTY`` ioctls. The supported properties and statistics depends on the delivery system and on the device: @@ -64,6 +64,10 @@ depends on the delivery system and on the device: Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-ber.rst b/Documentation/media/uapi/dvb/fe-read-ber.rst index e54972ad52505587a78ecb9f8fc51eede53f6e4a..1e6a79567a4cdf94009b728b65974bc74ca43542 100644 --- a/Documentation/media/uapi/dvb/fe-read-ber.rst +++ b/Documentation/media/uapi/dvb/fe-read-ber.rst @@ -41,6 +41,10 @@ access to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-signal-strength.rst b/Documentation/media/uapi/dvb/fe-read-signal-strength.rst index 4b13c47577442143a982610f92ca16531d7fa6b4..198f6dfb53a17bc0a2086ca3d6e3ef3d05482535 100644 --- a/Documentation/media/uapi/dvb/fe-read-signal-strength.rst +++ b/Documentation/media/uapi/dvb/fe-read-signal-strength.rst @@ -41,6 +41,10 @@ to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-snr.rst b/Documentation/media/uapi/dvb/fe-read-snr.rst index 2aed487f5c993612151d334bb6fcbdffa07b9cb0..6db22c043512554359bd08e6a5f47422c5e52b9d 100644 --- a/Documentation/media/uapi/dvb/fe-read-snr.rst +++ b/Documentation/media/uapi/dvb/fe-read-snr.rst @@ -41,6 +41,10 @@ to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-status.rst b/Documentation/media/uapi/dvb/fe-read-status.rst index 812f086c20f51a78352c38c5722d6dec0bc0ad98..4adb52f084ffc70bab03ffd7b496fbe2917903e0 100644 --- a/Documentation/media/uapi/dvb/fe-read-status.rst +++ b/Documentation/media/uapi/dvb/fe-read-status.rst @@ -33,7 +33,7 @@ Arguments Description =========== -All DVB frontend devices support the ``FE_READ_STATUS`` ioctl. It is +All Digital TV frontend devices support the ``FE_READ_STATUS`` ioctl. It is used to check about the locking status of the frontend after being tuned. The ioctl takes a pointer to an integer where the status will be written. @@ -52,85 +52,14 @@ The fe_status parameter is used to indicate the current state and/or state changes of the frontend hardware. It is produced using the enum :c:type:`fe_status` values on a bitmask -.. c:type:: fe_status - -.. tabularcolumns:: |p{3.5cm}|p{14.0cm}| - -.. _fe-status: - -.. flat-table:: enum fe_status - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _FE-HAS-SIGNAL: - - ``FE_HAS_SIGNAL`` - - - The frontend has found something above the noise level - - - .. row 3 - - - .. _FE-HAS-CARRIER: - - ``FE_HAS_CARRIER`` - - - The frontend has found a DVB signal - - - .. row 4 - - - .. _FE-HAS-VITERBI: - - ``FE_HAS_VITERBI`` - - - The frontend FEC inner coding (Viterbi, LDPC or other inner code) - is stable - - - .. row 5 - - - .. _FE-HAS-SYNC: - - ``FE_HAS_SYNC`` - - - Synchronization bytes was found - - - .. row 6 - - - .. _FE-HAS-LOCK: - - ``FE_HAS_LOCK`` - - - The DVB were locked and everything is working - - - .. row 7 - - - .. _FE-TIMEDOUT: - - ``FE_TIMEDOUT`` - - - no lock within the last about 2 seconds - - - .. row 8 - - - .. _FE-REINIT: - - ``FE_REINIT`` - - - The frontend was reinitialized, application is recommended to - reset DiSEqC, tone and parameters - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst b/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst index 46687c123402e2b9f7dfdb226e5766c2f116f0d3..f2c688bcacb3545652f980b812be5e54006cf9ce 100644 --- a/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst +++ b/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst @@ -43,6 +43,10 @@ sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst b/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst index 1d5878da2f414caf45d4cac4cdaa98b0cff58687..3c4bc179b31368b396f614d87c1229273c1df238 100644 --- a/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst +++ b/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst @@ -30,7 +30,7 @@ Arguments - 0 - normal tune mode - - FE_TUNE_MODE_ONESHOT - When set, this flag will disable any + - ``FE_TUNE_MODE_ONESHOT`` - When set, this flag will disable any zigzagging or other "normal" tuning behaviour. Additionally, there will be no automatic monitoring of the lock status, and hence no frontend events will be generated. If a frontend device @@ -42,12 +42,16 @@ Description =========== Allow setting tuner mode flags to the frontend, between 0 (normal) or -FE_TUNE_MODE_ONESHOT mode +``FE_TUNE_MODE_ONESHOT`` mode Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-frontend.rst b/Documentation/media/uapi/dvb/fe-set-frontend.rst index 7f97dce9aee6b70acd3170b751def64c5adef017..4f3dcf338254a248a65bd76388ec8deaf97a358a 100644 --- a/Documentation/media/uapi/dvb/fe-set-frontend.rst +++ b/Documentation/media/uapi/dvb/fe-set-frontend.rst @@ -48,17 +48,24 @@ requires read/write access to the device. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 - + :widths: 1 16 - .. row 1 - ``EINVAL`` - Maximum supported symbol rate reached. + + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-tone.rst b/Documentation/media/uapi/dvb/fe-set-tone.rst index 84e4da3fd4c97f417e10062398d4aedae97267c9..758efa11014cf550dad08baf6ef0c2ca32889535 100644 --- a/Documentation/media/uapi/dvb/fe-set-tone.rst +++ b/Documentation/media/uapi/dvb/fe-set-tone.rst @@ -45,40 +45,14 @@ this is done using the DiSEqC ioctls. capability of selecting the band. So, it is recommended that applications would change to SEC_TONE_OFF when the device is not used. -.. c:type:: fe_sec_tone_mode - -.. flat-table:: enum fe_sec_tone_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SEC-TONE-ON: - - ``SEC_TONE_ON`` - - - Sends a 22kHz tone burst to the antenna - - - .. row 3 - - - .. _SEC-TONE-OFF: - - ``SEC_TONE_OFF`` - - - Don't send a 22kHz tone to the antenna (except if the - FE_DISEQC_* ioctls are called) - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-voltage.rst b/Documentation/media/uapi/dvb/fe-set-voltage.rst index 052f316bb4a3d81485abf9fcfff3f7d8012f335c..38d4485290a05b1ecbc908d463ab31a5f02836d7 100644 --- a/Documentation/media/uapi/dvb/fe-set-voltage.rst +++ b/Documentation/media/uapi/dvb/fe-set-voltage.rst @@ -53,6 +53,10 @@ power up the LNBf. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-type-t.rst b/Documentation/media/uapi/dvb/fe-type-t.rst index 548b965188d027b871395d8e7afd6646303199d1..dee32ae104d735d3bd19f67251ee6356b88d703a 100644 --- a/Documentation/media/uapi/dvb/fe-type-t.rst +++ b/Documentation/media/uapi/dvb/fe-type-t.rst @@ -78,7 +78,7 @@ parameter. In the old days, struct :c:type:`dvb_frontend_info` used to contain ``fe_type_t`` field to indicate the delivery systems, -filled with either FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC. While this +filled with either ``FE_QPSK, FE_QAM, FE_OFDM`` or ``FE_ATSC``. While this is still filled to keep backward compatibility, the usage of this field is deprecated, as it can report just one delivery system, but some devices support multiple delivery systems. Please use diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst index 7bb7559c450042f3adb17b46317406653a44fc95..6eef507fea5063d81eca50d737d8dbb3bd0ee632 100644 --- a/Documentation/media/uapi/dvb/fe_property_parameters.rst +++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst @@ -6,6 +6,11 @@ Digital TV property parameters ****************************** +There are several different Digital TV parameters that can be used by +:ref:`FE_SET_PROPERTY and FE_GET_PROPERTY ioctls`. +This section describes each of them. Please notice, however, that only +a subset of them are needed to setup a frontend. + .. _DTV-UNDEFINED: @@ -67,1711 +72,831 @@ DTV_MODULATION ============== Specifies the frontend modulation type for delivery systems that -supports more than one modulation type. The modulation can be one of the -types defined by enum :c:type:`fe_modulation`. - +supports more multiple modulations. + +The modulation can be one of the types defined by enum :c:type:`fe_modulation`. + +Most of the digital TV standards offers more than one possible +modulation type. + +The table below presents a summary of the types of modulation types +supported by each delivery system, as currently defined by specs. + +======================= ======================================================= +Standard Modulation types +======================= ======================================================= +ATSC (version 1) 8-VSB and 16-VSB. +DMTB 4-QAM, 16-QAM, 32-QAM, 64-QAM and 4-QAM-NR. +DVB-C Annex A/C 16-QAM, 32-QAM, 64-QAM and 256-QAM. +DVB-C Annex B 64-QAM. +DVB-T QPSK, 16-QAM and 64-QAM. +DVB-T2 QPSK, 16-QAM, 64-QAM and 256-QAM. +DVB-S No need to set. It supports only QPSK. +DVB-S2 QPSK, 8-PSK, 16-APSK and 32-APSK. +ISDB-T QPSK, DQPSK, 16-QAM and 64-QAM. +ISDB-S 8-PSK, QPSK and BPSK. +======================= ======================================================= -.. c:type:: fe_modulation +.. note:: -Modulation property -------------------- + Please notice that some of the above modulation types may not be + defined currently at the Kernel. The reason is simple: no driver + needed such definition yet. -Most of the digital TV standards currently offers more than one possible -modulation (sometimes called as "constellation" on some standards). This -enum contains the values used by the Kernel. Please note that not all -modulations are supported by a given standard. +.. _DTV-BANDWIDTH-HZ: -.. flat-table:: enum fe_modulation - :header-rows: 1 - :stub-columns: 0 +DTV_BANDWIDTH_HZ +================ +Bandwidth for the channel, in HZ. - - .. row 1 +Should be set only for terrestrial delivery systems. - - ID +Possible values: ``1712000``, ``5000000``, ``6000000``, ``7000000``, +``8000000``, ``10000000``. - - Description +======================= ======================================================= +Terrestrial Standard Possible values for bandwidth +======================= ======================================================= +ATSC (version 1) No need to set. It is always 6MHz. +DMTB No need to set. It is always 8MHz. +DVB-T 6MHz, 7MHz and 8MHz. +DVB-T2 1.172 MHz, 5MHz, 6MHz, 7MHz, 8MHz and 10MHz +ISDB-T 5MHz, 6MHz, 7MHz and 8MHz, although most places + use 6MHz. +======================= ======================================================= - - .. row 2 - - .. _QPSK: +.. note:: - ``QPSK`` - - QPSK modulation + #. For ISDB-Tsb, the bandwidth can vary depending on the number of + connected segments. - - .. row 3 + It can be easily derived from other parameters + (DTV_ISDBT_SB_SEGMENT_IDX, DTV_ISDBT_SB_SEGMENT_COUNT). - - .. _QAM-16: + #. On Satellite and Cable delivery systems, the bandwidth depends on + the symbol rate. So, the Kernel will silently ignore any setting + :ref:`DTV-BANDWIDTH-HZ`. I will however fill it back with a + bandwidth estimation. - ``QAM_16`` + Such bandwidth estimation takes into account the symbol rate set with + :ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for + DVB-C and DVB-S. - - 16-QAM modulation + For DVB-S2, the rolloff should also be set via :ref:`DTV-ROLLOFF`. - - .. row 4 - - .. _QAM-32: +.. _DTV-INVERSION: - ``QAM_32`` +DTV_INVERSION +============= - - 32-QAM modulation +Specifies if the frontend should do spectral inversion or not. - - .. row 5 +The acceptable values are defined by :c:type:`fe_spectral_inversion`. - - .. _QAM-64: - ``QAM_64`` +.. _DTV-DISEQC-MASTER: - - 64-QAM modulation +DTV_DISEQC_MASTER +================= - - .. row 6 +Currently not implemented. - - .. _QAM-128: - ``QAM_128`` +.. _DTV-SYMBOL-RATE: - - 128-QAM modulation +DTV_SYMBOL_RATE +=============== - - .. row 7 +Used on cable and satellite delivery systems. - - .. _QAM-256: +Digital TV symbol rate, in bauds (symbols/second). - ``QAM_256`` - - 256-QAM modulation +.. _DTV-INNER-FEC: - - .. row 8 +DTV_INNER_FEC +============= - - .. _QAM-AUTO: +Used on cable and satellite delivery systems. - ``QAM_AUTO`` +The acceptable values are defined by :c:type:`fe_code_rate`. - - Autodetect QAM modulation - - .. row 9 +.. _DTV-VOLTAGE: - - .. _VSB-8: +DTV_VOLTAGE +=========== - ``VSB_8`` +Used on satellite delivery systems. - - 8-VSB modulation +The voltage is usually used with non-DiSEqC capable LNBs to switch the +polarzation (horizontal/vertical). When using DiSEqC epuipment this +voltage has to be switched consistently to the DiSEqC commands as +described in the DiSEqC spec. - - .. row 10 +The acceptable values are defined by :c:type:`fe_sec_voltage`. - - .. _VSB-16: - ``VSB_16`` +.. _DTV-TONE: - - 16-VSB modulation +DTV_TONE +======== - - .. row 11 +Currently not used. - - .. _PSK-8: - ``PSK_8`` +.. _DTV-PILOT: - - 8-PSK modulation +DTV_PILOT +========= - - .. row 12 +Used on DVB-S2. - - .. _APSK-16: +Sets DVB-S2 pilot. - ``APSK_16`` +The acceptable values are defined by :c:type:`fe_pilot`. - - 16-APSK modulation - - .. row 13 +.. _DTV-ROLLOFF: - - .. _APSK-32: +DTV_ROLLOFF +=========== - ``APSK_32`` +Used on DVB-S2. - - 32-APSK modulation +Sets DVB-S2 rolloff. - - .. row 14 +The acceptable values are defined by :c:type:`fe_rolloff`. - - .. _DQPSK: - ``DQPSK`` +.. _DTV-DISEQC-SLAVE-REPLY: - - DQPSK modulation +DTV_DISEQC_SLAVE_REPLY +====================== - - .. row 15 +Currently not implemented. - - .. _QAM-4-NR: - ``QAM_4_NR`` +.. _DTV-FE-CAPABILITY-COUNT: - - 4-QAM-NR modulation +DTV_FE_CAPABILITY_COUNT +======================= +Currently not implemented. -.. _DTV-BANDWIDTH-HZ: +.. _DTV-FE-CAPABILITY: -DTV_BANDWIDTH_HZ -================ +DTV_FE_CAPABILITY +================= -Bandwidth for the channel, in HZ. +Currently not implemented. -Possible values: ``1712000``, ``5000000``, ``6000000``, ``7000000``, -``8000000``, ``10000000``. -.. note:: +.. _DTV-DELIVERY-SYSTEM: - #. DVB-T supports 6, 7 and 8MHz. +DTV_DELIVERY_SYSTEM +=================== - #. DVB-T2 supports 1.172, 5, 6, 7, 8 and 10MHz. +Specifies the type of the delivery system. - #. ISDB-T supports 5MHz, 6MHz, 7MHz and 8MHz, although most - places use 6MHz. +The acceptable values are defined by :c:type:`fe_delivery_system`. - #. On DVB-C and DVB-S/S2, the bandwidth depends on the symbol rate. - So, the Kernel will silently ignore setting :ref:`DTV-BANDWIDTH-HZ`. - #. For DVB-C and DVB-S/S2, the Kernel will return an estimation of the - bandwidth, calculated from :ref:`DTV-SYMBOL-RATE` and from - the rolloff, with is fixed for DVB-C and DVB-S. +.. _DTV-ISDBT-PARTIAL-RECEPTION: - #. For DVB-S2, the bandwidth estimation will use :ref:`DTV-ROLLOFF`. +DTV_ISDBT_PARTIAL_RECEPTION +=========================== - #. For ISDB-Tsb, it can vary depending on the number of connected - segments. +Used only on ISDB. - #. Bandwidth in ISDB-Tsb can be easily derived from other parameters - (DTV_ISDBT_SB_SEGMENT_IDX, DTV_ISDBT_SB_SEGMENT_COUNT). +If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents +whether the channel is in partial reception mode or not. +If '1' ``DTV_ISDBT_LAYERA_*`` values are assigned to the center segment +and ``DTV_ISDBT_LAYERA_SEGMENT_COUNT`` has to be '1'. -.. _DTV-INVERSION: +If in addition ``DTV_ISDBT_SOUND_BROADCASTING`` is '1' +``DTV_ISDBT_PARTIAL_RECEPTION`` represents whether this ISDB-Tsb channel +is consisting of one segment and layer or three segments and two layers. -DTV_INVERSION -============= +Possible values: 0, 1, -1 (AUTO) -Specifies if the frontend should do spectral inversion or not. -.. c:type:: fe_spectral_inversion +.. _DTV-ISDBT-SOUND-BROADCASTING: -enum fe_modulation: Frontend spectral inversion ------------------------------------------------ +DTV_ISDBT_SOUND_BROADCASTING +============================ -This parameter indicates if spectral inversion should be presumed or -not. In the automatic setting (``INVERSION_AUTO``) the hardware will try -to figure out the correct setting by itself. If the hardware doesn't -support, the DVB core will try to lock at the carrier first with -inversion off. If it fails, it will try to enable inversion. +Used only on ISDB. +This field represents whether the other DTV_ISDBT_*-parameters are +referring to an ISDB-T and an ISDB-Tsb channel. (See also +``DTV_ISDBT_PARTIAL_RECEPTION``). -.. flat-table:: enum fe_modulation - :header-rows: 1 - :stub-columns: 0 +Possible values: 0, 1, -1 (AUTO) - - .. row 1 +.. _DTV-ISDBT-SB-SUBCHANNEL-ID: - - ID +DTV_ISDBT_SB_SUBCHANNEL_ID +========================== - - Description +Used only on ISDB. - - .. row 2 +This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. - - .. _INVERSION-OFF: +(Note of the author: This might not be the correct description of the +``SUBCHANNEL-ID`` in all details, but it is my understanding of the +technical background needed to program a device) - ``INVERSION_OFF`` +An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a +set of connected ISDB-Tsb channels. In this set of channels every +channel can be received independently. The number of connected ISDB-Tsb +segment can vary, e.g. depending on the frequency spectrum bandwidth +available. - - Don't do spectral band inversion. +Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The +broadcaster has several possibilities to put those channels in the air: +Assuming a normal 13-segment ISDB-T spectrum he can align the 8 segments +from position 1-8 to 5-13 or anything in between. - - .. row 3 +The underlying layer of segments are subchannels: each segment is +consisting of several subchannels with a predefined IDs. A sub-channel +is used to help the demodulator to synchronize on the channel. - - .. _INVERSION-ON: +An ISDB-T channel is always centered over all sub-channels. As for the +example above, in ISDB-Tsb it is no longer as simple as that. - ``INVERSION_ON`` +``The DTV_ISDBT_SB_SUBCHANNEL_ID`` parameter is used to give the +sub-channel ID of the segment to be demodulated. - - Do spectral band inversion. +Possible values: 0 .. 41, -1 (AUTO) - - .. row 4 - - .. _INVERSION-AUTO: +.. _DTV-ISDBT-SB-SEGMENT-IDX: - ``INVERSION_AUTO`` +DTV_ISDBT_SB_SEGMENT_IDX +======================== - - Autodetect spectral band inversion. +Used only on ISDB. +This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. +``DTV_ISDBT_SB_SEGMENT_IDX`` gives the index of the segment to be +demodulated for an ISDB-Tsb channel where several of them are +transmitted in the connected manner. -.. _DTV-DISEQC-MASTER: +Possible values: 0 .. ``DTV_ISDBT_SB_SEGMENT_COUNT`` - 1 -DTV_DISEQC_MASTER -================= +Note: This value cannot be determined by an automatic channel search. -Currently not implemented. +.. _DTV-ISDBT-SB-SEGMENT-COUNT: -.. _DTV-SYMBOL-RATE: +DTV_ISDBT_SB_SEGMENT_COUNT +========================== -DTV_SYMBOL_RATE -=============== +Used only on ISDB. -Digital TV symbol rate, in bauds (symbols/second). Used on cable -standards. +This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. +``DTV_ISDBT_SB_SEGMENT_COUNT`` gives the total count of connected +ISDB-Tsb channels. -.. _DTV-INNER-FEC: +Possible values: 1 .. 13 -DTV_INNER_FEC -============= +Note: This value cannot be determined by an automatic channel search. -Used cable/satellite transmissions. The acceptable values are: -.. c:type:: fe_code_rate +.. _isdb-hierq-layers: -enum fe_code_rate: type of the Forward Error Correction. --------------------------------------------------------- +DTV-ISDBT-LAYER[A-C] parameters +=============================== -.. flat-table:: enum fe_code_rate - :header-rows: 1 - :stub-columns: 0 +Used only on ISDB. +ISDB-T channels can be coded hierarchically. As opposed to DVB-T in +ISDB-T hierarchical layers can be decoded simultaneously. For that +reason a ISDB-T demodulator has 3 Viterbi and 3 Reed-Solomon decoders. - - .. row 1 +ISDB-T has 3 hierarchical layers which each can use a part of the +available segments. The total number of segments over all layers has to +13 in ISDB-T. - - ID +There are 3 parameter sets, for Layers A, B and C. - - Description - - .. row 2 +.. _DTV-ISDBT-LAYER-ENABLED: - - .. _FEC-NONE: +DTV_ISDBT_LAYER_ENABLED +----------------------- - ``FEC_NONE`` +Used only on ISDB. - - No Forward Error Correction Code +Hierarchical reception in ISDB-T is achieved by enabling or disabling +layers in the decoding process. Setting all bits of +``DTV_ISDBT_LAYER_ENABLED`` to '1' forces all layers (if applicable) to +be demodulated. This is the default. - - .. row 3 +If the channel is in the partial reception mode +(``DTV_ISDBT_PARTIAL_RECEPTION`` = 1) the central segment can be decoded +independently of the other 12 segments. In that mode layer A has to have +a ``SEGMENT_COUNT`` of 1. - - .. _FEC-AUTO: +In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb according +to ``DTV_ISDBT_PARTIAL_RECEPTION``. ``SEGMENT_COUNT`` must be filled +accordingly. - ``FEC_AUTO`` +Only the values of the first 3 bits are used. Other bits will be silently ignored: - - Autodetect Error Correction Code +``DTV_ISDBT_LAYER_ENABLED`` bit 0: layer A enabled - - .. row 4 +``DTV_ISDBT_LAYER_ENABLED`` bit 1: layer B enabled - - .. _FEC-1-2: +``DTV_ISDBT_LAYER_ENABLED`` bit 2: layer C enabled - ``FEC_1_2`` +``DTV_ISDBT_LAYER_ENABLED`` bits 3-31: unused - - Forward Error Correction Code 1/2 - - .. row 5 +.. _DTV-ISDBT-LAYER-FEC: - - .. _FEC-2-3: +DTV_ISDBT_LAYER[A-C]_FEC +------------------------ - ``FEC_2_3`` +Used only on ISDB. - - Forward Error Correction Code 2/3 +The Forward Error Correction mechanism used by a given ISDB Layer, as +defined by :c:type:`fe_code_rate`. - - .. row 6 - - .. _FEC-3-4: +Possible values are: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``, +``FEC_5_6``, ``FEC_7_8`` - ``FEC_3_4`` - - Forward Error Correction Code 3/4 +.. _DTV-ISDBT-LAYER-MODULATION: - - .. row 7 +DTV_ISDBT_LAYER[A-C]_MODULATION +------------------------------- - - .. _FEC-4-5: +Used only on ISDB. - ``FEC_4_5`` +The modulation used by a given ISDB Layer, as defined by +:c:type:`fe_modulation`. - - Forward Error Correction Code 4/5 +Possible values are: ``QAM_AUTO``, ``QPSK``, ``QAM_16``, ``QAM_64``, ``DQPSK`` - - .. row 8 +.. note:: - - .. _FEC-5-6: + #. If layer C is ``DQPSK``, then layer B has to be ``DQPSK``. - ``FEC_5_6`` + #. If layer B is ``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ = 0, + then layer has to be ``DQPSK``. - - Forward Error Correction Code 5/6 - - .. row 9 +.. _DTV-ISDBT-LAYER-SEGMENT-COUNT: - - .. _FEC-6-7: +DTV_ISDBT_LAYER[A-C]_SEGMENT_COUNT +---------------------------------- - ``FEC_6_7`` +Used only on ISDB. - - Forward Error Correction Code 6/7 +Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO) - - .. row 10 +Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and +``DTV_ISDBT_PARTIAL_RECEPTION`` and ``LAYER[A-C]_SEGMENT_COUNT`` - - .. _FEC-7-8: +.. _isdbt-layer_seg-cnt-table: - ``FEC_7_8`` +.. flat-table:: Truth table for ISDB-T Sound Broadcasting + :header-rows: 1 + :stub-columns: 0 - - Forward Error Correction Code 7/8 - - .. row 11 + - .. row 1 - - .. _FEC-8-9: + - Partial Reception - ``FEC_8_9`` + - Sound Broadcasting - - Forward Error Correction Code 8/9 + - Layer A width - - .. row 12 + - Layer B width - - .. _FEC-9-10: + - Layer C width - ``FEC_9_10`` + - total width - - Forward Error Correction Code 9/10 + - .. row 2 - - .. row 13 + - 0 - - .. _FEC-2-5: + - 0 - ``FEC_2_5`` + - 1 .. 13 - - Forward Error Correction Code 2/5 + - 1 .. 13 - - .. row 14 + - 1 .. 13 - - .. _FEC-3-5: + - 13 - ``FEC_3_5`` + - .. row 3 - - Forward Error Correction Code 3/5 + - 1 + - 0 + - 1 -.. _DTV-VOLTAGE: + - 1 .. 13 -DTV_VOLTAGE -=========== + - 1 .. 13 -The voltage is usually used with non-DiSEqC capable LNBs to switch the -polarzation (horizontal/vertical). When using DiSEqC epuipment this -voltage has to be switched consistently to the DiSEqC commands as -described in the DiSEqC spec. + - 13 + - .. row 4 -.. c:type:: fe_sec_voltage + - 0 -.. flat-table:: enum fe_sec_voltage - :header-rows: 1 - :stub-columns: 0 + - 1 + - 1 - - .. row 1 + - 0 - - ID + - 0 - - Description + - 1 - - .. row 2 + - .. row 5 - - .. _SEC-VOLTAGE-13: + - 1 - ``SEC_VOLTAGE_13`` + - 1 - - Set DC voltage level to 13V + - 1 - - .. row 3 + - 2 - - .. _SEC-VOLTAGE-18: + - 0 - ``SEC_VOLTAGE_18`` + - 13 - - Set DC voltage level to 18V - - .. row 4 - - .. _SEC-VOLTAGE-OFF: +.. _DTV-ISDBT-LAYER-TIME-INTERLEAVING: - ``SEC_VOLTAGE_OFF`` +DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING +-------------------------------------- - - Don't send any voltage to the antenna +Used only on ISDB. +Valid values: 0, 1, 2, 4, -1 (AUTO) +when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid. -.. _DTV-TONE: - -DTV_TONE -======== - -Currently not used. - - -.. _DTV-PILOT: - -DTV_PILOT -========= - -Sets DVB-S2 pilot - - -.. c:type:: fe_pilot - -fe_pilot type -------------- - - -.. flat-table:: enum fe_pilot - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _PILOT-ON: - - ``PILOT_ON`` - - - Pilot tones enabled - - - .. row 3 - - - .. _PILOT-OFF: - - ``PILOT_OFF`` - - - Pilot tones disabled - - - .. row 4 - - - .. _PILOT-AUTO: - - ``PILOT_AUTO`` - - - Autodetect pilot tones - - - -.. _DTV-ROLLOFF: - -DTV_ROLLOFF -=========== - -Sets DVB-S2 rolloff - - -.. c:type:: fe_rolloff - -fe_rolloff type ---------------- - - -.. flat-table:: enum fe_rolloff - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ROLLOFF-35: - - ``ROLLOFF_35`` - - - Roloff factor: α=35% - - - .. row 3 - - - .. _ROLLOFF-20: - - ``ROLLOFF_20`` - - - Roloff factor: α=20% - - - .. row 4 - - - .. _ROLLOFF-25: - - ``ROLLOFF_25`` - - - Roloff factor: α=25% - - - .. row 5 - - - .. _ROLLOFF-AUTO: - - ``ROLLOFF_AUTO`` - - - Auto-detect the roloff factor. - - - -.. _DTV-DISEQC-SLAVE-REPLY: - -DTV_DISEQC_SLAVE_REPLY -====================== - -Currently not implemented. - - -.. _DTV-FE-CAPABILITY-COUNT: - -DTV_FE_CAPABILITY_COUNT -======================= - -Currently not implemented. - - -.. _DTV-FE-CAPABILITY: - -DTV_FE_CAPABILITY -================= - -Currently not implemented. - - -.. _DTV-DELIVERY-SYSTEM: - -DTV_DELIVERY_SYSTEM -=================== - -Specifies the type of Delivery system - - -.. c:type:: fe_delivery_system - -fe_delivery_system type ------------------------ - -Possible values: - - -.. flat-table:: enum fe_delivery_system - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SYS-UNDEFINED: - - ``SYS_UNDEFINED`` - - - Undefined standard. Generally, indicates an error - - - .. row 3 - - - .. _SYS-DVBC-ANNEX-A: - - ``SYS_DVBC_ANNEX_A`` - - - Cable TV: DVB-C following ITU-T J.83 Annex A spec - - - .. row 4 - - - .. _SYS-DVBC-ANNEX-B: - - ``SYS_DVBC_ANNEX_B`` - - - Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM) - - - .. row 5 - - - .. _SYS-DVBC-ANNEX-C: - - ``SYS_DVBC_ANNEX_C`` - - - Cable TV: DVB-C following ITU-T J.83 Annex C spec - - - .. row 6 - - - .. _SYS-ISDBC: - - ``SYS_ISDBC`` - - - Cable TV: ISDB-C (no drivers yet) - - - .. row 7 - - - .. _SYS-DVBT: - - ``SYS_DVBT`` - - - Terrestral TV: DVB-T - - - .. row 8 - - - .. _SYS-DVBT2: - - ``SYS_DVBT2`` - - - Terrestral TV: DVB-T2 - - - .. row 9 - - - .. _SYS-ISDBT: - - ``SYS_ISDBT`` - - - Terrestral TV: ISDB-T - - - .. row 10 - - - .. _SYS-ATSC: - - ``SYS_ATSC`` - - - Terrestral TV: ATSC - - - .. row 11 - - - .. _SYS-ATSCMH: - - ``SYS_ATSCMH`` - - - Terrestral TV (mobile): ATSC-M/H - - - .. row 12 - - - .. _SYS-DTMB: - - ``SYS_DTMB`` - - - Terrestrial TV: DTMB - - - .. row 13 - - - .. _SYS-DVBS: - - ``SYS_DVBS`` - - - Satellite TV: DVB-S - - - .. row 14 - - - .. _SYS-DVBS2: - - ``SYS_DVBS2`` - - - Satellite TV: DVB-S2 - - - .. row 15 - - - .. _SYS-TURBO: - - ``SYS_TURBO`` - - - Satellite TV: DVB-S Turbo - - - .. row 16 - - - .. _SYS-ISDBS: - - ``SYS_ISDBS`` - - - Satellite TV: ISDB-S - - - .. row 17 - - - .. _SYS-DAB: - - ``SYS_DAB`` - - - Digital audio: DAB (not fully supported) - - - .. row 18 - - - .. _SYS-DSS: - - ``SYS_DSS`` - - - Satellite TV:"DSS (not fully supported) - - - .. row 19 - - - .. _SYS-CMMB: - - ``SYS_CMMB`` - - - Terrestral TV (mobile):CMMB (not fully supported) - - - .. row 20 - - - .. _SYS-DVBH: - - ``SYS_DVBH`` - - - Terrestral TV (mobile): DVB-H (standard deprecated) - - - -.. _DTV-ISDBT-PARTIAL-RECEPTION: - -DTV_ISDBT_PARTIAL_RECEPTION -=========================== - -If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents -whether the channel is in partial reception mode or not. - -If '1' ``DTV_ISDBT_LAYERA_*`` values are assigned to the center segment -and ``DTV_ISDBT_LAYERA_SEGMENT_COUNT`` has to be '1'. - -If in addition ``DTV_ISDBT_SOUND_BROADCASTING`` is '1' -``DTV_ISDBT_PARTIAL_RECEPTION`` represents whether this ISDB-Tsb channel -is consisting of one segment and layer or three segments and two layers. - -Possible values: 0, 1, -1 (AUTO) - - -.. _DTV-ISDBT-SOUND-BROADCASTING: - -DTV_ISDBT_SOUND_BROADCASTING -============================ - -This field represents whether the other DTV_ISDBT_*-parameters are -referring to an ISDB-T and an ISDB-Tsb channel. (See also -``DTV_ISDBT_PARTIAL_RECEPTION``). - -Possible values: 0, 1, -1 (AUTO) - - -.. _DTV-ISDBT-SB-SUBCHANNEL-ID: - -DTV_ISDBT_SB_SUBCHANNEL_ID -========================== - -This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. - -(Note of the author: This might not be the correct description of the -``SUBCHANNEL-ID`` in all details, but it is my understanding of the -technical background needed to program a device) - -An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a -set of connected ISDB-Tsb channels. In this set of channels every -channel can be received independently. The number of connected ISDB-Tsb -segment can vary, e.g. depending on the frequency spectrum bandwidth -available. - -Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The -broadcaster has several possibilities to put those channels in the air: -Assuming a normal 13-segment ISDB-T spectrum he can align the 8 segments -from position 1-8 to 5-13 or anything in between. - -The underlying layer of segments are subchannels: each segment is -consisting of several subchannels with a predefined IDs. A sub-channel -is used to help the demodulator to synchronize on the channel. - -An ISDB-T channel is always centered over all sub-channels. As for the -example above, in ISDB-Tsb it is no longer as simple as that. - -``The DTV_ISDBT_SB_SUBCHANNEL_ID`` parameter is used to give the -sub-channel ID of the segment to be demodulated. - -Possible values: 0 .. 41, -1 (AUTO) - - -.. _DTV-ISDBT-SB-SEGMENT-IDX: - -DTV_ISDBT_SB_SEGMENT_IDX -======================== - -This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. - -``DTV_ISDBT_SB_SEGMENT_IDX`` gives the index of the segment to be -demodulated for an ISDB-Tsb channel where several of them are -transmitted in the connected manner. - -Possible values: 0 .. ``DTV_ISDBT_SB_SEGMENT_COUNT`` - 1 - -Note: This value cannot be determined by an automatic channel search. - - -.. _DTV-ISDBT-SB-SEGMENT-COUNT: - -DTV_ISDBT_SB_SEGMENT_COUNT -========================== - -This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. - -``DTV_ISDBT_SB_SEGMENT_COUNT`` gives the total count of connected -ISDB-Tsb channels. - -Possible values: 1 .. 13 - -Note: This value cannot be determined by an automatic channel search. - - -.. _isdb-hierq-layers: - -DTV-ISDBT-LAYER[A-C] parameters -=============================== - -ISDB-T channels can be coded hierarchically. As opposed to DVB-T in -ISDB-T hierarchical layers can be decoded simultaneously. For that -reason a ISDB-T demodulator has 3 Viterbi and 3 Reed-Solomon decoders. - -ISDB-T has 3 hierarchical layers which each can use a part of the -available segments. The total number of segments over all layers has to -13 in ISDB-T. - -There are 3 parameter sets, for Layers A, B and C. - - -.. _DTV-ISDBT-LAYER-ENABLED: - -DTV_ISDBT_LAYER_ENABLED ------------------------ - -Hierarchical reception in ISDB-T is achieved by enabling or disabling -layers in the decoding process. Setting all bits of -``DTV_ISDBT_LAYER_ENABLED`` to '1' forces all layers (if applicable) to -be demodulated. This is the default. - -If the channel is in the partial reception mode -(``DTV_ISDBT_PARTIAL_RECEPTION`` = 1) the central segment can be decoded -independently of the other 12 segments. In that mode layer A has to have -a ``SEGMENT_COUNT`` of 1. - -In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb according -to ``DTV_ISDBT_PARTIAL_RECEPTION``. ``SEGMENT_COUNT`` must be filled -accordingly. - -Only the values of the first 3 bits are used. Other bits will be silently ignored: - -``DTV_ISDBT_LAYER_ENABLED`` bit 0: layer A enabled - -``DTV_ISDBT_LAYER_ENABLED`` bit 1: layer B enabled - -``DTV_ISDBT_LAYER_ENABLED`` bit 2: layer C enabled - -``DTV_ISDBT_LAYER_ENABLED`` bits 3-31: unused - - -.. _DTV-ISDBT-LAYER-FEC: - -DTV_ISDBT_LAYER[A-C]_FEC ------------------------- - -Possible values: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``, -``FEC_5_6``, ``FEC_7_8`` - - -.. _DTV-ISDBT-LAYER-MODULATION: - -DTV_ISDBT_LAYER[A-C]_MODULATION -------------------------------- - -Possible values: ``QAM_AUTO``, QP\ ``SK, QAM_16``, ``QAM_64``, ``DQPSK`` - -Note: If layer C is ``DQPSK`` layer B has to be ``DQPSK``. If layer B is -``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ =0 layer has to be -``DQPSK``. - - -.. _DTV-ISDBT-LAYER-SEGMENT-COUNT: - -DTV_ISDBT_LAYER[A-C]_SEGMENT_COUNT ----------------------------------- - -Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO) - -Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and -``DTV_ISDBT_PARTIAL_RECEPTION`` and ``LAYER[A-C]_SEGMENT_COUNT`` - -.. _isdbt-layer_seg-cnt-table: - -.. flat-table:: Truth table for ISDB-T Sound Broadcasting - :header-rows: 0 - :stub-columns: 0 - - - - .. row 1 - - - PR - - - SB - - - Layer A width - - - Layer B width - - - Layer C width - - - total width - - - .. row 2 - - - 0 - - - 0 - - - 1 .. 13 - - - 1 .. 13 - - - 1 .. 13 - - - 13 - - - .. row 3 - - - 1 - - - 0 - - - 1 - - - 1 .. 13 - - - 1 .. 13 - - - 13 - - - .. row 4 - - - 0 - - - 1 - - - 1 - - - 0 - - - 0 - - - 1 - - - .. row 5 - - - 1 - - - 1 - - - 1 - - - 2 - - - 0 - - - 13 - - - -.. _DTV-ISDBT-LAYER-TIME-INTERLEAVING: - -DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING --------------------------------------- - -Valid values: 0, 1, 2, 4, -1 (AUTO) - -when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid. - -Note: The real time interleaving length depends on the mode (fft-size). -The values here are referring to what can be found in the -TMCC-structure, as shown in the table below. - - -.. c:type:: isdbt_layer_interleaving_table - -.. flat-table:: ISDB-T time interleaving modes - :header-rows: 0 - :stub-columns: 0 - - - - .. row 1 - - - ``DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING`` - - - Mode 1 (2K FFT) - - - Mode 2 (4K FFT) - - - Mode 3 (8K FFT) - - - .. row 2 - - - 0 - - - 0 - - - 0 - - - 0 - - - .. row 3 - - - 1 - - - 4 - - - 2 - - - 1 - - - .. row 4 - - - 2 - - - 8 - - - 4 - - - 2 - - - .. row 5 - - - 4 - - - 16 - - - 8 - - - 4 - - - -.. _DTV-ATSCMH-FIC-VER: - -DTV_ATSCMH_FIC_VER ------------------- - -Version number of the FIC (Fast Information Channel) signaling data. - -FIC is used for relaying information to allow rapid service acquisition -by the receiver. - -Possible values: 0, 1, 2, 3, ..., 30, 31 - - -.. _DTV-ATSCMH-PARADE-ID: - -DTV_ATSCMH_PARADE_ID --------------------- - -Parade identification number - -A parade is a collection of up to eight MH groups, conveying one or two -ensembles. - -Possible values: 0, 1, 2, 3, ..., 126, 127 - - -.. _DTV-ATSCMH-NOG: - -DTV_ATSCMH_NOG --------------- - -Number of MH groups per MH subframe for a designated parade. - -Possible values: 1, 2, 3, 4, 5, 6, 7, 8 - - -.. _DTV-ATSCMH-TNOG: - -DTV_ATSCMH_TNOG ---------------- - -Total number of MH groups including all MH groups belonging to all MH -parades in one MH subframe. - -Possible values: 0, 1, 2, 3, ..., 30, 31 - - -.. _DTV-ATSCMH-SGN: - -DTV_ATSCMH_SGN --------------- - -Start group number. - -Possible values: 0, 1, 2, 3, ..., 14, 15 - - -.. _DTV-ATSCMH-PRC: - -DTV_ATSCMH_PRC --------------- - -Parade repetition cycle. - -Possible values: 1, 2, 3, 4, 5, 6, 7, 8 - - -.. _DTV-ATSCMH-RS-FRAME-MODE: - -DTV_ATSCMH_RS_FRAME_MODE ------------------------- - -Reed Solomon (RS) frame mode. - -Possible values are: - -.. tabularcolumns:: |p{5.0cm}|p{12.5cm}| - -.. c:type:: atscmh_rs_frame_mode - -.. flat-table:: enum atscmh_rs_frame_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-RSFRAME-PRI-ONLY: - - ``ATSCMH_RSFRAME_PRI_ONLY`` - - - Single Frame: There is only a primary RS Frame for all Group - Regions. - - - .. row 3 - - - .. _ATSCMH-RSFRAME-PRI-SEC: - - ``ATSCMH_RSFRAME_PRI_SEC`` - - - Dual Frame: There are two separate RS Frames: Primary RS Frame for - Group Region A and B and Secondary RS Frame for Group Region C and - D. - - - -.. _DTV-ATSCMH-RS-FRAME-ENSEMBLE: - -DTV_ATSCMH_RS_FRAME_ENSEMBLE ----------------------------- - -Reed Solomon(RS) frame ensemble. - -Possible values are: - - -.. c:type:: atscmh_rs_frame_ensemble - -.. flat-table:: enum atscmh_rs_frame_ensemble - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-RSFRAME-ENS-PRI: - - ``ATSCMH_RSFRAME_ENS_PRI`` - - - Primary Ensemble. - - - .. row 3 - - - .. _ATSCMH-RSFRAME-ENS-SEC: - - ``AATSCMH_RSFRAME_PRI_SEC`` - - - Secondary Ensemble. - - - .. row 4 - - - .. _ATSCMH-RSFRAME-RES: - - ``AATSCMH_RSFRAME_RES`` - - - Reserved. Shouldn't be used. - - - -.. _DTV-ATSCMH-RS-CODE-MODE-PRI: - -DTV_ATSCMH_RS_CODE_MODE_PRI ---------------------------- - -Reed Solomon (RS) code mode (primary). - -Possible values are: - - -.. c:type:: atscmh_rs_code_mode - -.. flat-table:: enum atscmh_rs_code_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-RSCODE-211-187: - - ``ATSCMH_RSCODE_211_187`` - - - Reed Solomon code (211,187). - - - .. row 3 - - - .. _ATSCMH-RSCODE-223-187: - - ``ATSCMH_RSCODE_223_187`` - - - Reed Solomon code (223,187). - - - .. row 4 - - - .. _ATSCMH-RSCODE-235-187: - - ``ATSCMH_RSCODE_235_187`` - - - Reed Solomon code (235,187). - - - .. row 5 - - - .. _ATSCMH-RSCODE-RES: - - ``ATSCMH_RSCODE_RES`` - - - Reserved. Shouldn't be used. - - - -.. _DTV-ATSCMH-RS-CODE-MODE-SEC: - -DTV_ATSCMH_RS_CODE_MODE_SEC ---------------------------- - -Reed Solomon (RS) code mode (secondary). - -Possible values are the same as documented on enum -:c:type:`atscmh_rs_code_mode`: - - -.. _DTV-ATSCMH-SCCC-BLOCK-MODE: - -DTV_ATSCMH_SCCC_BLOCK_MODE --------------------------- - -Series Concatenated Convolutional Code Block Mode. - -Possible values are: - -.. tabularcolumns:: |p{4.5cm}|p{13.0cm}| - -.. c:type:: atscmh_sccc_block_mode - -.. flat-table:: enum atscmh_scc_block_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-SCCC-BLK-SEP: - - ``ATSCMH_SCCC_BLK_SEP`` - - - Separate SCCC: the SCCC outer code mode shall be set independently - for each Group Region (A, B, C, D) - - - .. row 3 - - - .. _ATSCMH-SCCC-BLK-COMB: - - ``ATSCMH_SCCC_BLK_COMB`` - - - Combined SCCC: all four Regions shall have the same SCCC outer - code mode. - - - .. row 4 - - - .. _ATSCMH-SCCC-BLK-RES: - - ``ATSCMH_SCCC_BLK_RES`` - - - Reserved. Shouldn't be used. - - - -.. _DTV-ATSCMH-SCCC-CODE-MODE-A: - -DTV_ATSCMH_SCCC_CODE_MODE_A ---------------------------- - -Series Concatenated Convolutional Code Rate. - -Possible values are: +Note: The real time interleaving length depends on the mode (fft-size). +The values here are referring to what can be found in the +TMCC-structure, as shown in the table below. -.. c:type:: atscmh_sccc_code_mode +.. c:type:: isdbt_layer_interleaving_table -.. flat-table:: enum atscmh_sccc_code_mode +.. flat-table:: ISDB-T time interleaving modes :header-rows: 1 :stub-columns: 0 - .. row 1 - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-SCCC-CODE-HLF: - - ``ATSCMH_SCCC_CODE_HLF`` - - - The outer code rate of a SCCC Block is 1/2 rate. - - - .. row 3 - - - .. _ATSCMH-SCCC-CODE-QTR: - - ``ATSCMH_SCCC_CODE_QTR`` - - - The outer code rate of a SCCC Block is 1/4 rate. - - - .. row 4 - - - .. _ATSCMH-SCCC-CODE-RES: + - ``DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING`` - ``ATSCMH_SCCC_CODE_RES`` + - Mode 1 (2K FFT) - - to be documented. + - Mode 2 (4K FFT) + - Mode 3 (8K FFT) + - .. row 2 -.. _DTV-ATSCMH-SCCC-CODE-MODE-B: + - 0 -DTV_ATSCMH_SCCC_CODE_MODE_B ---------------------------- + - 0 -Series Concatenated Convolutional Code Rate. + - 0 -Possible values are the same as documented on enum -:c:type:`atscmh_sccc_code_mode`. + - 0 + - .. row 3 -.. _DTV-ATSCMH-SCCC-CODE-MODE-C: + - 1 -DTV_ATSCMH_SCCC_CODE_MODE_C ---------------------------- + - 4 -Series Concatenated Convolutional Code Rate. + - 2 -Possible values are the same as documented on enum -:c:type:`atscmh_sccc_code_mode`. + - 1 + - .. row 4 -.. _DTV-ATSCMH-SCCC-CODE-MODE-D: + - 2 -DTV_ATSCMH_SCCC_CODE_MODE_D ---------------------------- + - 8 -Series Concatenated Convolutional Code Rate. + - 4 -Possible values are the same as documented on enum -:c:type:`atscmh_sccc_code_mode`. + - 2 + - .. row 5 -.. _DTV-API-VERSION: + - 4 -DTV_API_VERSION -=============== + - 16 -Returns the major/minor version of the DVB API + - 8 + - 4 -.. _DTV-CODE-RATE-HP: -DTV_CODE_RATE_HP -================ -Used on terrestrial transmissions. The acceptable values are the ones -described at :c:type:`fe_transmit_mode`. +.. _DTV-ATSCMH-FIC-VER: +DTV_ATSCMH_FIC_VER +------------------ -.. _DTV-CODE-RATE-LP: +Used only on ATSC-MH. -DTV_CODE_RATE_LP -================ +Version number of the FIC (Fast Information Channel) signaling data. -Used on terrestrial transmissions. The acceptable values are the ones -described at :c:type:`fe_transmit_mode`. +FIC is used for relaying information to allow rapid service acquisition +by the receiver. +Possible values: 0, 1, 2, 3, ..., 30, 31 -.. _DTV-GUARD-INTERVAL: -DTV_GUARD_INTERVAL -================== +.. _DTV-ATSCMH-PARADE-ID: -Possible values are: +DTV_ATSCMH_PARADE_ID +-------------------- +Used only on ATSC-MH. -.. c:type:: fe_guard_interval +Parade identification number -Modulation guard interval -------------------------- +A parade is a collection of up to eight MH groups, conveying one or two +ensembles. +Possible values: 0, 1, 2, 3, ..., 126, 127 -.. flat-table:: enum fe_guard_interval - :header-rows: 1 - :stub-columns: 0 +.. _DTV-ATSCMH-NOG: - - .. row 1 +DTV_ATSCMH_NOG +-------------- - - ID +Used only on ATSC-MH. - - Description +Number of MH groups per MH subframe for a designated parade. - - .. row 2 +Possible values: 1, 2, 3, 4, 5, 6, 7, 8 - - .. _GUARD-INTERVAL-AUTO: - ``GUARD_INTERVAL_AUTO`` +.. _DTV-ATSCMH-TNOG: - - Autodetect the guard interval +DTV_ATSCMH_TNOG +--------------- - - .. row 3 +Used only on ATSC-MH. - - .. _GUARD-INTERVAL-1-128: +Total number of MH groups including all MH groups belonging to all MH +parades in one MH subframe. - ``GUARD_INTERVAL_1_128`` +Possible values: 0, 1, 2, 3, ..., 30, 31 - - Guard interval 1/128 - - .. row 4 +.. _DTV-ATSCMH-SGN: - - .. _GUARD-INTERVAL-1-32: +DTV_ATSCMH_SGN +-------------- - ``GUARD_INTERVAL_1_32`` +Used only on ATSC-MH. - - Guard interval 1/32 +Start group number. - - .. row 5 +Possible values: 0, 1, 2, 3, ..., 14, 15 - - .. _GUARD-INTERVAL-1-16: - ``GUARD_INTERVAL_1_16`` +.. _DTV-ATSCMH-PRC: - - Guard interval 1/16 +DTV_ATSCMH_PRC +-------------- - - .. row 6 +Used only on ATSC-MH. - - .. _GUARD-INTERVAL-1-8: +Parade repetition cycle. - ``GUARD_INTERVAL_1_8`` +Possible values: 1, 2, 3, 4, 5, 6, 7, 8 - - Guard interval 1/8 - - .. row 7 +.. _DTV-ATSCMH-RS-FRAME-MODE: - - .. _GUARD-INTERVAL-1-4: +DTV_ATSCMH_RS_FRAME_MODE +------------------------ - ``GUARD_INTERVAL_1_4`` +Used only on ATSC-MH. - - Guard interval 1/4 +Reed Solomon (RS) frame mode. - - .. row 8 +The acceptable values are defined by :c:type:`atscmh_rs_frame_mode`. - - .. _GUARD-INTERVAL-19-128: - ``GUARD_INTERVAL_19_128`` +.. _DTV-ATSCMH-RS-FRAME-ENSEMBLE: - - Guard interval 19/128 +DTV_ATSCMH_RS_FRAME_ENSEMBLE +---------------------------- - - .. row 9 +Used only on ATSC-MH. - - .. _GUARD-INTERVAL-19-256: +Reed Solomon(RS) frame ensemble. - ``GUARD_INTERVAL_19_256`` +The acceptable values are defined by :c:type:`atscmh_rs_frame_ensemble`. - - Guard interval 19/256 - - .. row 10 +.. _DTV-ATSCMH-RS-CODE-MODE-PRI: - - .. _GUARD-INTERVAL-PN420: +DTV_ATSCMH_RS_CODE_MODE_PRI +--------------------------- - ``GUARD_INTERVAL_PN420`` +Used only on ATSC-MH. - - PN length 420 (1/4) +Reed Solomon (RS) code mode (primary). - - .. row 11 +The acceptable values are defined by :c:type:`atscmh_rs_code_mode`. - - .. _GUARD-INTERVAL-PN595: - ``GUARD_INTERVAL_PN595`` +.. _DTV-ATSCMH-RS-CODE-MODE-SEC: - - PN length 595 (1/6) +DTV_ATSCMH_RS_CODE_MODE_SEC +--------------------------- - - .. row 12 +Used only on ATSC-MH. - - .. _GUARD-INTERVAL-PN945: +Reed Solomon (RS) code mode (secondary). - ``GUARD_INTERVAL_PN945`` +The acceptable values are defined by :c:type:`atscmh_rs_code_mode`. - - PN length 945 (1/9) +.. _DTV-ATSCMH-SCCC-BLOCK-MODE: -Notes: +DTV_ATSCMH_SCCC_BLOCK_MODE +-------------------------- -1) If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the -hardware will try to find the correct guard interval (if capable) and -will use TMCC to fill in the missing parameters. +Used only on ATSC-MH. -2) Intervals 1/128, 19/128 and 19/256 are used only for DVB-T2 at -present +Series Concatenated Convolutional Code Block Mode. -3) DTMB specifies PN420, PN595 and PN945. +The acceptable values are defined by :c:type:`atscmh_sccc_block_mode`. -.. _DTV-TRANSMISSION-MODE: +.. _DTV-ATSCMH-SCCC-CODE-MODE-A: -DTV_TRANSMISSION_MODE -===================== +DTV_ATSCMH_SCCC_CODE_MODE_A +--------------------------- -Specifies the number of carriers used by the standard. This is used only -on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB +Used only on ATSC-MH. +Series Concatenated Convolutional Code Rate. -.. c:type:: fe_transmit_mode +The acceptable values are defined by :c:type:`atscmh_sccc_code_mode`. -enum fe_transmit_mode: Number of carriers per channel ------------------------------------------------------ +.. _DTV-ATSCMH-SCCC-CODE-MODE-B: -.. tabularcolumns:: |p{5.0cm}|p{12.5cm}| +DTV_ATSCMH_SCCC_CODE_MODE_B +--------------------------- -.. flat-table:: enum fe_transmit_mode - :header-rows: 1 - :stub-columns: 0 +Used only on ATSC-MH. +Series Concatenated Convolutional Code Rate. - - .. row 1 +Possible values are the same as documented on enum +:c:type:`atscmh_sccc_code_mode`. - - ID - - Description +.. _DTV-ATSCMH-SCCC-CODE-MODE-C: - - .. row 2 +DTV_ATSCMH_SCCC_CODE_MODE_C +--------------------------- - - .. _TRANSMISSION-MODE-AUTO: +Used only on ATSC-MH. - ``TRANSMISSION_MODE_AUTO`` +Series Concatenated Convolutional Code Rate. - - Autodetect transmission mode. The hardware will try to find the - correct FFT-size (if capable) to fill in the missing parameters. +Possible values are the same as documented on enum +:c:type:`atscmh_sccc_code_mode`. - - .. row 3 - - .. _TRANSMISSION-MODE-1K: +.. _DTV-ATSCMH-SCCC-CODE-MODE-D: - ``TRANSMISSION_MODE_1K`` +DTV_ATSCMH_SCCC_CODE_MODE_D +--------------------------- - - Transmission mode 1K +Used only on ATSC-MH. - - .. row 4 +Series Concatenated Convolutional Code Rate. - - .. _TRANSMISSION-MODE-2K: +Possible values are the same as documented on enum +:c:type:`atscmh_sccc_code_mode`. - ``TRANSMISSION_MODE_2K`` - - Transmission mode 2K +.. _DTV-API-VERSION: - - .. row 5 +DTV_API_VERSION +=============== - - .. _TRANSMISSION-MODE-8K: +Returns the major/minor version of the Digital TV API - ``TRANSMISSION_MODE_8K`` - - Transmission mode 8K +.. _DTV-CODE-RATE-HP: - - .. row 6 +DTV_CODE_RATE_HP +================ - - .. _TRANSMISSION-MODE-4K: +Used on terrestrial transmissions. - ``TRANSMISSION_MODE_4K`` +The acceptable values are defined by :c:type:`fe_transmit_mode`. - - Transmission mode 4K - - .. row 7 +.. _DTV-CODE-RATE-LP: - - .. _TRANSMISSION-MODE-16K: +DTV_CODE_RATE_LP +================ - ``TRANSMISSION_MODE_16K`` +Used on terrestrial transmissions. - - Transmission mode 16K +The acceptable values are defined by :c:type:`fe_transmit_mode`. - - .. row 8 - - .. _TRANSMISSION-MODE-32K: +.. _DTV-GUARD-INTERVAL: - ``TRANSMISSION_MODE_32K`` +DTV_GUARD_INTERVAL +================== - - Transmission mode 32K +The acceptable values are defined by :c:type:`fe_guard_interval`. - - .. row 9 +.. note:: - - .. _TRANSMISSION-MODE-C1: + #. If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the + hardware will try to find the correct guard interval (if capable) and + will use TMCC to fill in the missing parameters. + #. Intervals ``GUARD_INTERVAL_1_128``, ``GUARD_INTERVAL_19_128`` + and ``GUARD_INTERVAL_19_256`` are used only for DVB-T2 at + present. + #. Intervals ``GUARD_INTERVAL_PN420``, ``GUARD_INTERVAL_PN595`` and + ``GUARD_INTERVAL_PN945`` are used only for DMTB at the present. + On such standard, only those intervals and ``GUARD_INTERVAL_AUTO`` + are valid. - ``TRANSMISSION_MODE_C1`` +.. _DTV-TRANSMISSION-MODE: - - Single Carrier (C=1) transmission mode (DTMB) +DTV_TRANSMISSION_MODE +===================== - - .. row 10 - - .. _TRANSMISSION-MODE-C3780: +Used only on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB. - ``TRANSMISSION_MODE_C3780`` +Specifies the FFT size (with corresponds to the approximate number of +carriers) used by the standard. - - Multi Carrier (C=3780) transmission mode (DTMB) +The acceptable values are defined by :c:type:`fe_transmit_mode`. +.. note:: -Notes: + #. ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called + **mode** on such standard, and are numbered from 1 to 3: -1) ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called -'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K + ==== ======== ======================== + Mode FFT size Transmission mode + ==== ======== ======================== + 1 2K ``TRANSMISSION_MODE_2K`` + 2 4K ``TRANSMISSION_MODE_4K`` + 3 8K ``TRANSMISSION_MODE_8K`` + ==== ======== ======================== -2) If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO`` -the hardware will try to find the correct FFT-size (if capable) and will -use TMCC to fill in the missing parameters. + #. If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO`` + the hardware will try to find the correct FFT-size (if capable) and + will use TMCC to fill in the missing parameters. -3) DVB-T specifies 2K and 8K as valid sizes. + #. DVB-T specifies 2K and 8K as valid sizes. -4) DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K. + #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K. -5) DTMB specifies C1 and C3780. + #. DTMB specifies C1 and C3780. .. _DTV-HIERARCHY: @@ -1779,66 +904,11 @@ use TMCC to fill in the missing parameters. DTV_HIERARCHY ============= -Frontend hierarchy - - -.. c:type:: fe_hierarchy - -Frontend hierarchy ------------------- - - -.. flat-table:: enum fe_hierarchy - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _HIERARCHY-NONE: - - ``HIERARCHY_NONE`` - - - No hierarchy - - - .. row 3 - - - .. _HIERARCHY-AUTO: - - ``HIERARCHY_AUTO`` - - - Autodetect hierarchy (if supported) - - - .. row 4 - - - .. _HIERARCHY-1: - - ``HIERARCHY_1`` - - - Hierarchy 1 - - - .. row 5 - - - .. _HIERARCHY-2: - - ``HIERARCHY_2`` - - - Hierarchy 2 - - - .. row 6 - - - .. _HIERARCHY-4: - - ``HIERARCHY_4`` +Used only on DVB-T and DVB-T2. - - Hierarchy 4 +Frontend hierarchy. +The acceptable values are defined by :c:type:`fe_hierarchy`. .. _DTV-STREAM-ID: @@ -1846,8 +916,10 @@ Frontend hierarchy DTV_STREAM_ID ============= +Used on DVB-S2, DVB-T2 and ISDB-S. + DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on -a single transport stream. This property enables the DVB driver to +a single transport stream. This property enables the digital TV driver to handle substream filtering, when supported by the hardware. By default, substream filtering is disabled. @@ -1884,60 +956,17 @@ with it, rather than trying to use FE_GET_INFO. In the case of a legacy frontend, the result is just the same as with FE_GET_INFO, but in a more structured format +The acceptable values are defined by :c:type:`fe_delivery_system`. + .. _DTV-INTERLEAVING: DTV_INTERLEAVING ================ -Time interleaving to be used. Currently, used only on DTMB. - - -.. c:type:: fe_interleaving - -.. flat-table:: enum fe_interleaving - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _INTERLEAVING-NONE: - - ``INTERLEAVING_NONE`` - - - No interleaving. - - - .. row 3 - - - .. _INTERLEAVING-AUTO: - - ``INTERLEAVING_AUTO`` - - - Auto-detect interleaving. - - - .. row 4 - - - .. _INTERLEAVING-240: - - ``INTERLEAVING_240`` - - - Interleaving of 240 symbols. - - - .. row 5 - - - .. _INTERLEAVING-720: - - ``INTERLEAVING_720`` - - - Interleaving of 720 symbols. +Time interleaving to be used. +The acceptable values are defined by :c:type:`fe_interleaving`. .. _DTV-LNA: diff --git a/Documentation/media/uapi/dvb/frontend-header.rst b/Documentation/media/uapi/dvb/frontend-header.rst new file mode 100644 index 0000000000000000000000000000000000000000..8d8433cf1e129959e2030bf7ba1c9256c6c774c7 --- /dev/null +++ b/Documentation/media/uapi/dvb/frontend-header.rst @@ -0,0 +1,4 @@ +Frontend uAPI data types +======================== + +.. kernel-doc:: include/uapi/linux/dvb/frontend.h diff --git a/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst b/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst index dbc717cad9eebad5f237d1b30c8db850059849b1..0beb5cb3d7293d299d4e8ca57d3ae756fbeeb10c 100644 --- a/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst +++ b/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst @@ -100,7 +100,7 @@ to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible that some very sophisticated devices won't need certain parameters to tune. The information given here should help application writers to know how -to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API. +to handle ISDB-T and ISDB-Tsb hardware using the Linux Digital TV API. The details given here about ISDB-T and ISDB-Tsb are just enough to basically show the dependencies between the needed parameter values, but diff --git a/Documentation/media/uapi/dvb/frontend.rst b/Documentation/media/uapi/dvb/frontend.rst index e051a90125400703ab390785b23ee34cc4def94c..4967c48d46ce3513c29ad0a3c7f7cba778987f20 100644 --- a/Documentation/media/uapi/dvb/frontend.rst +++ b/Documentation/media/uapi/dvb/frontend.rst @@ -2,20 +2,22 @@ .. _dvb_frontend: -################ -DVB Frontend API -################ -The DVB frontend API was designed to support three types of delivery -systems: +####################### +Digital TV Frontend API +####################### + +The Digital TV frontend API was designed to support three groups of delivery +systems: Terrestrial, cable and Satellite. Currently, the following +delivery systems are supported: - Terrestrial systems: DVB-T, DVB-T2, ATSC, ATSC M/H, ISDB-T, DVB-H, DTMB, CMMB -- Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B), ISDB-C +- Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B) - Satellite systems: DVB-S, DVB-S2, DVB Turbo, ISDB-S, DSS -The DVB frontend controls several sub-devices including: +The Digital TV frontend controls several sub-devices including: - Tuner @@ -23,7 +25,7 @@ The DVB frontend controls several sub-devices including: - Low noise amplifier (LNA) -- Satellite Equipment Control (SEC) hardware (only for Satellite). +- Satellite Equipment Control (SEC) [#f1]_. The frontend can be accessed through ``/dev/dvb/adapter?/frontend?``. Data types and ioctl definitions can be accessed by including @@ -31,16 +33,18 @@ Data types and ioctl definitions can be accessed by including .. note:: - Transmission via the internet (DVB-IP) is not yet handled by this - API but a future extension is possible. + Transmission via the internet (DVB-IP) and MMT (MPEG Media Transport) + is not yet handled by this API but a future extension is possible. + +.. [#f1] -On Satellite systems, the API support for the Satellite Equipment -Control (SEC) allows to power control and to send/receive signals to -control the antenna subsystem, selecting the polarization and choosing -the Intermediate Frequency IF) of the Low Noise Block Converter Feed -Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC -(digital SEC) specification is available at -`Eutelsat `__. + On Satellite systems, the API support for the Satellite Equipment + Control (SEC) allows to power control and to send/receive signals to + control the antenna subsystem, selecting the polarization and choosing + the Intermediate Frequency IF) of the Low Noise Block Converter Feed + Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC + (digital SEC) specification is available at + `Eutelsat `__. .. toctree:: @@ -50,4 +54,3 @@ Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC dvb-fe-read-status dvbproperty frontend_fcalls - frontend_legacy_dvbv3_api diff --git a/Documentation/media/uapi/dvb/frontend_f_close.rst b/Documentation/media/uapi/dvb/frontend_f_close.rst index f3b04b60246c277ac20915982c578d90c8995657..67958d73cf348092a88d00b82e2c09e7d6c72a38 100644 --- a/Documentation/media/uapi/dvb/frontend_f_close.rst +++ b/Documentation/media/uapi/dvb/frontend_f_close.rst @@ -2,9 +2,9 @@ .. _frontend_f_close: -******************** -DVB frontend close() -******************** +*************************** +Digital TV frontend close() +*************************** Name ==== @@ -41,8 +41,10 @@ down automatically. Return Value ============ -The function returns 0 on success, -1 on failure and the ``errno`` is -set appropriately. Possible error codes: +On success 0 is returned. -EBADF - ``fd`` is not a valid open file descriptor. +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/frontend_f_open.rst b/Documentation/media/uapi/dvb/frontend_f_open.rst index 690eb375bdc1eeb77c063fa7d3be2fcdb9a466e7..8e8cb466c24badad5893d754c9b39b90b2948b28 100644 --- a/Documentation/media/uapi/dvb/frontend_f_open.rst +++ b/Documentation/media/uapi/dvb/frontend_f_open.rst @@ -2,9 +2,9 @@ .. _frontend_f_open: -******************* -DVB frontend open() -******************* +*************************** +Digital TV frontend open() +*************************** Name ==== @@ -79,24 +79,32 @@ On error, -1 is returned, and the ``errno`` variable is set appropriately. Possible error codes are: -EACCES - The caller has no permission to access the device. -EBUSY - The the device driver is already in use. +On success 0 is returned, and :c:type:`ca_slot_info` is filled. -ENXIO - No device corresponding to this device special file exists. +On error -1 is returned, and the ``errno`` variable is set +appropriately. -ENOMEM - Not enough kernel memory was available to complete the request. +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| -EMFILE - The process already has the maximum number of files open. +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 16 -ENFILE - The limit on the total number of files open on the system has been - reached. + - - ``EPERM`` + - The caller has no permission to access the device. -ENODEV - The device got removed. + - - ``EBUSY`` + - The the device driver is already in use. + + - - ``EMFILE`` + - The process already has the maximum number of files open. + + - - ``ENFILE`` + - The limit on the total number of files open on the system has been + reached. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/frontend_h.rst b/Documentation/media/uapi/dvb/frontend_h.rst deleted file mode 100644 index 15fca04d1c3207062144424df88b2b055845045a..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/frontend_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _frontend_h: - -************************ -DVB Frontend Header File -************************ - -.. kernel-include:: $BUILDDIR/frontend.h.rst diff --git a/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst b/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst index 7d4a091b7d7fcefe1edd5bc9646ee269a7d9fc17..a4d5319cb76bc112605d51d7a0603ff7aca55807 100644 --- a/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst +++ b/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst @@ -2,9 +2,9 @@ .. _frontend_legacy_dvbv3_api: -**************************************** -DVB Frontend legacy API (a. k. a. DVBv3) -**************************************** +*********************************************** +Digital TV Frontend legacy API (a. k. a. DVBv3) +*********************************************** The usage of this API is deprecated, as it doesn't support all digital TV standards, doesn't provide good statistics measurements and provides diff --git a/Documentation/media/uapi/dvb/headers.rst b/Documentation/media/uapi/dvb/headers.rst new file mode 100644 index 0000000000000000000000000000000000000000..c13fd537fbff470fc300fec9becf72fce4795ddc --- /dev/null +++ b/Documentation/media/uapi/dvb/headers.rst @@ -0,0 +1,21 @@ +**************************** +Digital TV uAPI header files +**************************** + +Digital TV uAPI headers +*********************** + +.. kernel-include:: $BUILDDIR/frontend.h.rst + +.. kernel-include:: $BUILDDIR/dmx.h.rst + +.. kernel-include:: $BUILDDIR/ca.h.rst + +.. kernel-include:: $BUILDDIR/net.h.rst + +Legacy uAPI +*********** + +.. kernel-include:: $BUILDDIR/audio.h.rst + +.. kernel-include:: $BUILDDIR/video.h.rst diff --git a/Documentation/media/uapi/dvb/intro.rst b/Documentation/media/uapi/dvb/intro.rst index 652c4aacd2c6da91b010e041c780c3bcb7f9ae17..79b4d0e4e920296a07a6acbeffb0da7a4d86dfa5 100644 --- a/Documentation/media/uapi/dvb/intro.rst +++ b/Documentation/media/uapi/dvb/intro.rst @@ -13,15 +13,18 @@ What you need to know ===================== The reader of this document is required to have some knowledge in the -area of digital video broadcasting (DVB) and should be familiar with +area of digital video broadcasting (Digital TV) and should be familiar with part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e you should know what a program/transport stream (PS/TS) is and what is meant by a packetized elementary stream (PES) or an I-frame. -Various DVB standards documents are available from http://www.dvb.org -and/or http://www.etsi.org. +Various Digital TV standards documents are available for download at: -It is also necessary to know how to access unix/linux devices and how to +- European standards (DVB): http://www.dvb.org and/or http://www.etsi.org. +- American standards (ATSC): https://www.atsc.org/standards/ +- Japanese standards (ISDB): http://www.dibeg.org/ + +It is also necessary to know how to access Linux devices and how to use ioctl calls. This also includes the knowledge of C or C++. @@ -30,21 +33,25 @@ use ioctl calls. This also includes the knowledge of C or C++. History ======= -The first API for DVB cards we used at Convergence in late 1999 was an +The first API for Digital TV cards we used at Convergence in late 1999 was an extension of the Video4Linux API which was primarily developed for frame -grabber cards. As such it was not really well suited to be used for DVB -cards and their new features like recording MPEG streams and filtering +grabber cards. As such it was not really well suited to be used for Digital +TV cards and their new features like recording MPEG streams and filtering several section and PES data streams at the same time. -In early 2000, we were approached by Nokia with a proposal for a new -standard Linux DVB API. As a commitment to the development of terminals +In early 2000, Convergence was approached by Nokia with a proposal for a new +standard Linux Digital TV API. As a commitment to the development of terminals based on open standards, Nokia and Convergence made it available to all Linux developers and published it on https://linuxtv.org in September -2000. Convergence is the maintainer of the Linux DVB API. Together with -the LinuxTV community (i.e. you, the reader of this document), the Linux -DVB API will be constantly reviewed and improved. With the Linux driver -for the Siemens/Hauppauge DVB PCI card Convergence provides a first -implementation of the Linux DVB API. +2000. With the Linux driver for the Siemens/Hauppauge DVB PCI card, +Convergence provided a first implementation of the Linux Digital TV API. +Convergence was the maintainer of the Linux Digital TV API in the early +days. + +Now, the API is maintained by the LinuxTV community (i.e. you, the reader +of this document). The Linux Digital TV API is constantly reviewed and +improved together with the improvements at the subsystem's core at the +Kernel. .. _overview: @@ -59,61 +66,65 @@ Overview :alt: dvbstb.svg :align: center - Components of a DVB card/STB + Components of a Digital TV card/STB -A DVB PCI card or DVB set-top-box (STB) usually consists of the +A Digital TV card or set-top-box (STB) usually consists of the following main hardware components: -- Frontend consisting of tuner and DVB demodulator - - Here the raw signal reaches the DVB hardware from a satellite dish or +Frontend consisting of tuner and digital TV demodulator + Here the raw signal reaches the digital TV hardware from a satellite dish or antenna or directly from cable. The frontend down-converts and demodulates this signal into an MPEG transport stream (TS). In case of a satellite frontend, this includes a facility for satellite equipment control (SEC), which allows control of LNB polarization, multi feed switches or dish rotors. -- Conditional Access (CA) hardware like CI adapters and smartcard slots - +Conditional Access (CA) hardware like CI adapters and smartcard slots The complete TS is passed through the CA hardware. Programs to which the user has access (controlled by the smart card) are decoded in real time and re-inserted into the TS. -- Demultiplexer which filters the incoming DVB stream + .. note:: + Not every digital TV hardware provides conditional access hardware. + +Demultiplexer which filters the incoming Digital TV MPEG-TS stream The demultiplexer splits the TS into its components like audio and video streams. Besides usually several of such audio and video streams it also contains data streams with information about the programs offered in this or other streams of the same provider. -- MPEG2 audio and video decoder +Audio and video decoder + The main targets of the demultiplexer are audio and video + decoders. After decoding, they pass on the uncompressed audio and + video to the computer screen or to a TV set. + + .. note:: - The main targets of the demultiplexer are the MPEG2 audio and video - decoders. After decoding they pass on the uncompressed audio and - video to the computer screen or (through a PAL/NTSC encoder) to a TV - set. + Modern hardware usually doesn't have a separate decoder hardware, as + such functionality can be provided by the main CPU, by the graphics + adapter of the system or by a signal processing hardware embedded on + a Systems on a Chip (SoC) integrated circuit. + + It may also not be needed for certain usages (e.g. for data-only + uses like “internet over satelliteâ€). :ref:`stb_components` shows a crude schematic of the control and data flow between those components. -On a DVB PCI card not all of these have to be present since some -functionality can be provided by the main CPU of the PC (e.g. MPEG -picture and sound decoding) or is not needed (e.g. for data-only uses -like “internet over satelliteâ€). Also not every card or STB provides -conditional access hardware. .. _dvb_devices: -Linux DVB Devices -================= +Linux Digital TV Devices +======================== -The Linux DVB API lets you control these hardware components through +The Linux Digital TV API lets you control these hardware components through currently six Unix-style character devices for video, audio, frontend, demux, CA and IP-over-DVB networking. The video and audio devices control the MPEG2 decoder hardware, the frontend device the tuner and -the DVB demodulator. The demux device gives you control over the PES and -section filters of the hardware. If the hardware does not support +the Digital TV demodulator. The demux device gives you control over the PES +and section filters of the hardware. If the hardware does not support filtering these filters can be implemented in software. Finally, the CA device controls all the conditional access capabilities of the hardware. It can depend on the individual security requirements of the platform, @@ -137,9 +148,9 @@ individual devices are called: - ``/dev/dvb/adapterN/caM``, -where N enumerates the DVB PCI cards in a system starting from 0, and M -enumerates the devices of each type within each adapter, starting -from 0, too. We will omit the “ ``/dev/dvb/adapterN/``\ †in the further +where ``N`` enumerates the Digital TV cards in a system starting from 0, and +``M`` enumerates the devices of each type within each adapter, starting +from 0, too. We will omit the “``/dev/dvb/adapterN/``\ †in the further discussion of these devices. More details about the data structures and function calls of all the @@ -151,8 +162,8 @@ devices are described in the following chapters. API include files ================= -For each of the DVB devices a corresponding include file exists. The DVB -API include files should be included in application sources with a +For each of the Digital TV devices a corresponding include file exists. The +Digital TV API include files should be included in application sources with a partial path like: diff --git a/Documentation/media/uapi/dvb/legacy_dvb_apis.rst b/Documentation/media/uapi/dvb/legacy_dvb_apis.rst index 2957f5a988b03819fa62099fc0b68348022f1ad8..e1b2c9c7b620b3e6d29e663f5e77631c55e48496 100644 --- a/Documentation/media/uapi/dvb/legacy_dvb_apis.rst +++ b/Documentation/media/uapi/dvb/legacy_dvb_apis.rst @@ -2,19 +2,31 @@ .. _legacy_dvb_apis: -******************* -DVB Deprecated APIs -******************* +*************************** +Digital TV Deprecated APIs +*************************** -The APIs described here are kept only for historical reasons. There's -just one driver for a very legacy hardware that uses this API. No modern -drivers should use it. Instead, audio and video should be using the V4L2 -and ALSA APIs, and the pipelines should be set using the Media -Controller API +The APIs described here **should not** be used on new drivers or applications. + +The DVBv3 frontend API has issues with new delivery systems, including +DVB-S2, DVB-T2, ISDB, etc. + +There's just one driver for a very legacy hardware using the Digital TV +audio and video APIs. No modern drivers should use it. Instead, audio and +video should be using the V4L2 and ALSA APIs, and the pipelines should +be set via the Media Controller API. + +.. attention:: + + The APIs described here doesn't necessarily reflect the current + code implementation, as this section of the document was written + for DVB version 1, while the code reflects DVB version 3 + implementation. .. toctree:: :maxdepth: 1 + frontend_legacy_dvbv3_api video audio diff --git a/Documentation/media/uapi/dvb/net-add-if.rst b/Documentation/media/uapi/dvb/net-add-if.rst index 82ce2438213fbbb49520dffe1a9eaaf56decd489..6749b70246c5269916019327fd4c746c1d239c9a 100644 --- a/Documentation/media/uapi/dvb/net-add-if.rst +++ b/Documentation/media/uapi/dvb/net-add-if.rst @@ -41,43 +41,13 @@ created. The struct :c:type:`dvb_net_if`::ifnum field will be filled with the number of the created interface. -.. c:type:: dvb_net_if - -.. flat-table:: struct dvb_net_if - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - pid - - - Packet ID (PID) of the MPEG-TS that contains data - - - .. row 3 - - - ifnum - - - number of the DVB interface. - - - .. row 4 - - - feedtype - - - Encapsulation type of the feed. It can be: - ``DVB_NET_FEEDTYPE_MPE`` for MPE encoding or - ``DVB_NET_FEEDTYPE_ULE`` for ULE encoding. - - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/net-get-if.rst b/Documentation/media/uapi/dvb/net-get-if.rst index 1bb8ee0cbced1bf5f75c7be2c5bb9170c7f82fce..3733b34da9db8132ff6d8f8924914d6211150b4c 100644 --- a/Documentation/media/uapi/dvb/net-get-if.rst +++ b/Documentation/media/uapi/dvb/net-get-if.rst @@ -43,6 +43,10 @@ the ``errno`` with ``EINVAL`` error code. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/net-remove-if.rst b/Documentation/media/uapi/dvb/net-remove-if.rst index 646af23a925ae96839a1c9854091aece17bed1bd..4ebe07a6b79a6eb03705b30396bc2f2a3047c51b 100644 --- a/Documentation/media/uapi/dvb/net-remove-if.rst +++ b/Documentation/media/uapi/dvb/net-remove-if.rst @@ -39,6 +39,10 @@ The NET_REMOVE_IF ioctl deletes an interface previously created via Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/net-types.rst b/Documentation/media/uapi/dvb/net-types.rst new file mode 100644 index 0000000000000000000000000000000000000000..e1177bdcd623be66c8951337be9eacf9040947ad --- /dev/null +++ b/Documentation/media/uapi/dvb/net-types.rst @@ -0,0 +1,9 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dmx_types: + +************** +Net Data Types +************** + +.. kernel-doc:: include/uapi/linux/dvb/net.h diff --git a/Documentation/media/uapi/dvb/net.rst b/Documentation/media/uapi/dvb/net.rst index eca42dd5326173f07c000bb1e6be1564e28afd12..e0cd4e402627ef84faeaa43a0ae55f344219cc13 100644 --- a/Documentation/media/uapi/dvb/net.rst +++ b/Documentation/media/uapi/dvb/net.rst @@ -2,10 +2,11 @@ .. _net: -############### -DVB Network API -############### -The DVB net device controls the mapping of data packages that are part +###################### +Digital TV Network API +###################### + +The Digital TV net device controls the mapping of data packages that are part of a transport stream to be mapped into a virtual network interface, visible through the standard Linux network protocol stack. @@ -28,13 +29,13 @@ header. .. _net_fcalls: -###################### -DVB net Function Calls -###################### +Digital TV net Function Calls +############################# .. toctree:: :maxdepth: 1 + net-types net-add-if net-remove-if net-get-if diff --git a/Documentation/media/uapi/dvb/net_h.rst b/Documentation/media/uapi/dvb/net_h.rst deleted file mode 100644 index 7bcf5ba9d1ebbee19fe58422d2ad7bb9d0186892..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/net_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _net_h: - -*********************** -DVB Network Header File -*********************** - -.. kernel-include:: $BUILDDIR/net.h.rst diff --git a/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst b/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst index 81cd9b92a36c01d5dad83711839c6996391057b9..51ec0b04b496cc806525e09cdbcb49c9180cd94c 100644 --- a/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst +++ b/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst @@ -9,5 +9,5 @@ Querying frontend information Usually, the first thing to do when the frontend is opened is to check the frontend capabilities. This is done using :ref:`FE_GET_INFO`. This ioctl will enumerate the -DVB API version and other characteristics about the frontend, and can be -opened either in read only or read/write mode. +Digital TV API version and other characteristics about the frontend, and can +be opened either in read only or read/write mode. diff --git a/Documentation/media/uapi/dvb/video-continue.rst b/Documentation/media/uapi/dvb/video-continue.rst index 030c2ec98869010ee84dbd09ad4f0ea08bfe7c55..e65e600be6322eb1ea7987558f8c4c6111104cea 100644 --- a/Documentation/media/uapi/dvb/video-continue.rst +++ b/Documentation/media/uapi/dvb/video-continue.rst @@ -44,7 +44,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call restarts decoding and playing processes of the video diff --git a/Documentation/media/uapi/dvb/video-freeze.rst b/Documentation/media/uapi/dvb/video-freeze.rst index 9cef65a02e8d4562c13bb8ab1e1ea648e2a56926..5a28bdc8badd2467cd15c10a0665980de5b0858d 100644 --- a/Documentation/media/uapi/dvb/video-freeze.rst +++ b/Documentation/media/uapi/dvb/video-freeze.rst @@ -44,14 +44,14 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call suspends the live video stream being played. Decoding and playing are frozen. It is then possible to restart the decoding and playing process of the video stream using the VIDEO_CONTINUE command. If VIDEO_SOURCE_MEMORY is selected in the ioctl call -VIDEO_SELECT_SOURCE, the DVB subsystem will not decode any more data +VIDEO_SELECT_SOURCE, the Digital TV subsystem will not decode any more data until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed. diff --git a/Documentation/media/uapi/dvb/video-get-event.rst b/Documentation/media/uapi/dvb/video-get-event.rst index 6ad14cdb894a0fc5dc46073e77b18bb1369f4f66..b4f53616db9a4969b02959ee4de9d92ce6d06aba 100644 --- a/Documentation/media/uapi/dvb/video-get-event.rst +++ b/Documentation/media/uapi/dvb/video-get-event.rst @@ -50,7 +50,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To get events from a V4L2 decoder +This ioctl is for Digital TV devices only. To get events from a V4L2 decoder use the V4L2 :ref:`VIDIOC_DQEVENT` ioctl instead. This ioctl call returns an event of type video_event if available. If diff --git a/Documentation/media/uapi/dvb/video-play.rst b/Documentation/media/uapi/dvb/video-play.rst index 3f66ae3b7e35eccd4d18d106295287d8ac7c85d7..2124120aec2205fa827afd20143ad6e2f3428cb9 100644 --- a/Documentation/media/uapi/dvb/video-play.rst +++ b/Documentation/media/uapi/dvb/video-play.rst @@ -44,7 +44,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call asks the Video Device to start playing a video stream diff --git a/Documentation/media/uapi/dvb/video-select-source.rst b/Documentation/media/uapi/dvb/video-select-source.rst index 2f4fbf4b490c4cc119a725bba7e105150dfa3a49..cde6542723ca2eddcabddddfb9f920927fdd1c52 100644 --- a/Documentation/media/uapi/dvb/video-select-source.rst +++ b/Documentation/media/uapi/dvb/video-select-source.rst @@ -50,7 +50,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. This ioctl was also supported by the +This ioctl is for Digital TV devices only. This ioctl was also supported by the V4L2 ivtv driver, but that has been replaced by the ivtv-specific ``IVTV_IOC_PASSTHROUGH_MODE`` ioctl. diff --git a/Documentation/media/uapi/dvb/video-stop.rst b/Documentation/media/uapi/dvb/video-stop.rst index fb827effb276594aa6d8bfc39f298fa1d4e49b73..474309ad31c2b62fa916c4a7d7edab6df759de78 100644 --- a/Documentation/media/uapi/dvb/video-stop.rst +++ b/Documentation/media/uapi/dvb/video-stop.rst @@ -60,7 +60,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call asks the Video Device to stop playing the current diff --git a/Documentation/media/uapi/dvb/video.rst b/Documentation/media/uapi/dvb/video.rst index 60d43fb7ce22e9a5bc8f767ffc7f5ae8f174dd93..e7d68cd0cf23e4d50365f81bf6137aa2686fa0e4 100644 --- a/Documentation/media/uapi/dvb/video.rst +++ b/Documentation/media/uapi/dvb/video.rst @@ -2,20 +2,21 @@ .. _dvb_video: -################ -DVB Video Device -################ -The DVB video device controls the MPEG2 video decoder of the DVB -hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data +####################### +Digital TV Video Device +####################### + +The Digital TV video device controls the MPEG2 video decoder of the Digital +TV hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data types and and ioctl definitions can be accessed by including **linux/dvb/video.h** in your application. -Note that the DVB video device only controls decoding of the MPEG video +Note that the Digital TV video device only controls decoding of the MPEG video stream, not its presentation on the TV or computer screen. On PCs this is typically handled by an associated video4linux device, e.g. **/dev/video**, which allows scaling and defining output windows. -Some DVB cards don’t have their own MPEG decoder, which results in the +Some Digital TV cards don’t have their own MPEG decoder, which results in the omission of the audio and video device as well as the video4linux device. diff --git a/Documentation/media/uapi/dvb/video_h.rst b/Documentation/media/uapi/dvb/video_h.rst deleted file mode 100644 index 3f39b0c4879c2ae5615f3f64ff586c3094fe55be..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/dvb/video_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _video_h: - -********************* -DVB Video Header File -********************* - -.. kernel-include:: $BUILDDIR/video.h.rst diff --git a/Documentation/media/uapi/gen-errors.rst b/Documentation/media/uapi/gen-errors.rst index d39e34d1b19dd09e3e994927341294c52dc688b1..689d3b101ede2b28e72e95a307c751c500babdee 100644 --- a/Documentation/media/uapi/gen-errors.rst +++ b/Documentation/media/uapi/gen-errors.rst @@ -17,9 +17,7 @@ Generic Error Codes :widths: 1 16 - - .. row 1 - - - ``EAGAIN`` (aka ``EWOULDBLOCK``) + - - ``EAGAIN`` (aka ``EWOULDBLOCK``) - The ioctl can't be handled because the device is in state where it can't perform it. This could happen for example in case where @@ -27,15 +25,11 @@ Generic Error Codes is also returned when the ioctl would need to wait for an event, but the device was opened in non-blocking mode. - - .. row 2 - - - ``EBADF`` + - - ``EBADF`` - The file descriptor is not a valid. - - .. row 3 - - - ``EBUSY`` + - - ``EBUSY`` - The ioctl can't be handled because the device is busy. This is typically return while device is streaming, and an ioctl tried to @@ -44,64 +38,53 @@ Generic Error Codes ioctl must not be retried without performing another action to fix the problem first (typically: stop the stream before retrying). - - .. row 4 - - - ``EFAULT`` + - - ``EFAULT`` - There was a failure while copying data from/to userspace, probably caused by an invalid pointer reference. - - .. row 5 - - - ``EINVAL`` + - - ``EINVAL`` - One or more of the ioctl parameters are invalid or out of the allowed range. This is a widely used error code. See the individual ioctl requests for specific causes. - - .. row 6 - - - ``ENODEV`` + - - ``ENODEV`` - Device not found or was removed. - - .. row 7 - - - ``ENOMEM`` + - - ``ENOMEM`` - There's not enough memory to handle the desired operation. - - .. row 8 - - - ``ENOTTY`` + - - ``ENOTTY`` - The ioctl is not supported by the driver, actually meaning that the required functionality is not available, or the file descriptor is not for a media device. - - .. row 9 - - - ``ENOSPC`` + - - ``ENOSPC`` - On USB devices, the stream ioctl's can return this error, meaning that this request would overcommit the usb bandwidth reserved for periodic transfers (up to 80% of the USB bandwidth). - - .. row 10 - - - ``EPERM`` + - - ``EPERM`` - Permission denied. Can be returned if the device needs write permission, or some special capabilities is needed (e. g. root) - - .. row 11 - - - ``EIO`` + - - ``EIO`` - I/O error. Typically used when there are problems communicating with a hardware device. This could indicate broken or flaky hardware. It's a 'Something is wrong, I give up!' type of error. + - - ``ENXIO`` + + - No device corresponding to this device special file exists. + + .. note:: #. This list is not exhaustive; ioctls may return other error codes. diff --git a/Documentation/media/uapi/mediactl/media-controller.rst b/Documentation/media/uapi/mediactl/media-controller.rst index 7ae38d48969ea93300eed8a4f386e5a33787b91d..0eea4f9a07d5409fc4496f3382c68ada3a6ab37f 100644 --- a/Documentation/media/uapi/mediactl/media-controller.rst +++ b/Documentation/media/uapi/mediactl/media-controller.rst @@ -8,7 +8,9 @@ Part IV - Media Controller API ############################## -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst index 0fd329279befeaa3c6d981fce2ab881a3447f21b..b59ce149efb5dc626fab9703730ea9ffa3d95c7a 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst @@ -51,7 +51,7 @@ id's until they get an error. .. c:type:: media_entity_desc -.. tabularcolumns:: |p{1.5cm}|p{1.5cm}|p{1.5cm}|p{1.5cm}|p{11.5cm}| +.. tabularcolumns:: |p{1.5cm}|p{1.7cm}|p{1.6cm}|p{1.5cm}|p{11.2cm}| .. flat-table:: struct media_entity_desc :header-rows: 0 diff --git a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst index add8281494f88976e0fcf5a9124beab336234294..997e6b17440dc1383be856749481a29a7b6bc2ca 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst @@ -46,7 +46,7 @@ other values untouched. If the ``topology_version`` remains the same, the ioctl should fill the desired arrays with the media graph elements. -.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}| +.. tabularcolumns:: |p{1.6cm}|p{3.4cm}|p{12.5cm}| .. c:type:: media_v2_topology diff --git a/Documentation/media/uapi/mediactl/media-types.rst b/Documentation/media/uapi/mediactl/media-types.rst index 71078565d6444d5a7faa57ef93d6d6af0eb1bcd7..8d64b0c06ebc3fcb0cd4a79fe2285ef89bd50243 100644 --- a/Documentation/media/uapi/mediactl/media-types.rst +++ b/Documentation/media/uapi/mediactl/media-types.rst @@ -5,7 +5,7 @@ Types and flags used to represent the media graph elements ========================================================== -.. tabularcolumns:: |p{8.0cm}|p{10.5cm}| +.. tabularcolumns:: |p{8.2cm}|p{10.3cm}| .. _media-entity-type: diff --git a/Documentation/media/uapi/rc/rc-sysfs-nodes.rst b/Documentation/media/uapi/rc/rc-sysfs-nodes.rst index 3476ae29708f7e4068bbb5166c5d6ee66ef29e16..2d01358d5504513f1bdcd3efc5f42e1ee23e1c26 100644 --- a/Documentation/media/uapi/rc/rc-sysfs-nodes.rst +++ b/Documentation/media/uapi/rc/rc-sysfs-nodes.rst @@ -34,9 +34,9 @@ receiver device where N is the number of the receiver. /sys/class/rc/rcN/protocols =========================== -Reading this file returns a list of available protocols, something like: +Reading this file returns a list of available protocols, something like:: -``rc5 [rc6] nec jvc [sony]`` + rc5 [rc6] nec jvc [sony] Enabled protocols are shown in [] brackets. @@ -90,11 +90,11 @@ This value may be reset to 0 if the current protocol is altered. ================================== Reading this file returns a list of available protocols to use for the -wakeup filter, something like: +wakeup filter, something like:: -``rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce`` + rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce -Note that protocol variants are listed, so "nec", "sony", "rc-5", "rc-6" +Note that protocol variants are listed, so ``nec``, ``sony``, ``rc-5``, ``rc-6`` have their different bit length encodings listed if available. Note that all protocol variants are listed. diff --git a/Documentation/media/uapi/rc/remote_controllers.rst b/Documentation/media/uapi/rc/remote_controllers.rst index 3e25cc9f65e0a19638bdcccec5390d0c287c3d5c..46a8acb82125d3b9a4d6e43e74cd2386ca0c0865 100644 --- a/Documentation/media/uapi/rc/remote_controllers.rst +++ b/Documentation/media/uapi/rc/remote_controllers.rst @@ -8,7 +8,9 @@ Part III - Remote Controller API ################################ -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/v4l/bayer.svg b/Documentation/media/uapi/v4l/bayer.svg index fbd4cfb5e6bffb7a7d13c3f4fd6580e28e83b152..c395113d1876b4daefd5eb222c15286f491bcaaf 100644 --- a/Documentation/media/uapi/v4l/bayer.svg +++ b/Documentation/media/uapi/v4l/bayer.svg @@ -1,984 +1,29 @@ - -image/svg+xmlB -G -G -R -BGGR -B -G -G -R -GBRG -B -G -G -R -RGGB -B -G -G -R -GRBG - \ No newline at end of file + +image/svg+xmlB +G +G +R +BGGR +B +G +G +R +GBRG +B +G +G +R +RGGB +B +G +G +R +GRBG + diff --git a/Documentation/media/uapi/v4l/pixfmt-006.rst b/Documentation/media/uapi/v4l/colorspaces-defs.rst similarity index 98% rename from Documentation/media/uapi/v4l/pixfmt-006.rst rename to Documentation/media/uapi/v4l/colorspaces-defs.rst index 7ae7dcf73f63ce2ea12bfd924d27450e685543ee..410907fe9415e729be39d6ee9bfc978ea9278b33 100644 --- a/Documentation/media/uapi/v4l/pixfmt-006.rst +++ b/Documentation/media/uapi/v4l/colorspaces-defs.rst @@ -76,6 +76,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum .. c:type:: v4l2_xfer_func +.. tabularcolumns:: |p{5.5cm}|p{12.0cm}| + .. flat-table:: V4L2 Transfer Function :header-rows: 1 :stub-columns: 0 @@ -97,7 +99,7 @@ whole range, 0-255, dividing the angular value by 1.41. The enum * - ``V4L2_XFER_FUNC_DCI_P3`` - Use the DCI-P3 transfer function. * - ``V4L2_XFER_FUNC_SMPTE2084`` - - Use the SMPTE 2084 transfer function. + - Use the SMPTE 2084 transfer function. See :ref:`xf-smpte-2084`. diff --git a/Documentation/media/uapi/v4l/pixfmt-007.rst b/Documentation/media/uapi/v4l/colorspaces-details.rst similarity index 92% rename from Documentation/media/uapi/v4l/pixfmt-007.rst rename to Documentation/media/uapi/v4l/colorspaces-details.rst index 0c30ee2577d3228ce31d22035009a7f9e13cb2a2..b5d551b9cc8f819fc7ee8c70299da3b307eed686 100644 --- a/Documentation/media/uapi/v4l/pixfmt-007.rst +++ b/Documentation/media/uapi/v4l/colorspaces-details.rst @@ -418,6 +418,11 @@ Inverse Transfer function: L = \left( \frac{L' + 0.099}{1.099}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081 +Please note that while Rec. 709 is defined as the default transfer function +by the :ref:`itu2020` standard, in practice this colorspace is often used +with the :ref:`xf-smpte-2084`. In particular Ultra HD Blu-ray discs use +this combination. + The luminance (Y') and color difference (Cb and Cr) are obtained with the following ``V4L2_YCBCR_ENC_BT2020`` encoding: @@ -758,3 +763,45 @@ scaled to [-128…128] and then clipped to [-128…127]. ``V4L2_COLORSPACE_JPEG`` can be considered to be an abbreviation for ``V4L2_COLORSPACE_SRGB``, ``V4L2_YCBCR_ENC_601`` and ``V4L2_QUANTIZATION_FULL_RANGE``. + +*************************************** +Detailed Transfer Function Descriptions +*************************************** + +.. _xf-smpte-2084: + +Transfer Function SMPTE 2084 (V4L2_XFER_FUNC_SMPTE2084) +======================================================= + +The :ref:`smpte2084` standard defines the transfer function used by +High Dynamic Range content. + +Constants: + m1 = (2610 / 4096) / 4 + + m2 = (2523 / 4096) * 128 + + c1 = 3424 / 4096 + + c2 = (2413 / 4096) * 32 + + c3 = (2392 / 4096) * 32 + +Transfer function: + L' = ((c1 + c2 * L\ :sup:`m1`) / (1 + c3 * L\ :sup:`m1`))\ :sup:`m2` + +Inverse Transfer function: + L = (max(L':sup:`1/m2` - c1, 0) / (c2 - c3 * + L'\ :sup:`1/m2`))\ :sup:`1/m1` + +Take care when converting between this transfer function and non-HDR transfer +functions: the linear RGB values [0…1] of HDR content map to a luminance range +of 0 to 10000 cd/m\ :sup:`2` whereas the linear RGB values of non-HDR (aka +Standard Dynamic Range or SDR) map to a luminance range of 0 to 100 cd/m\ :sup:`2`. + +To go from SDR to HDR you will have to divide L by 100 first. To go in the other +direction you will have to multiply L by 100. Of course, this clamps all +luminance values over 100 cd/m\ :sup:`2` to 100 cd/m\ :sup:`2`. + +There are better methods, see e.g. :ref:`colimg` for more in-depth information +about this. diff --git a/Documentation/media/uapi/v4l/constraints.svg b/Documentation/media/uapi/v4l/constraints.svg index f710ee46b1f8b2d5dbaf5b9fe39ee711375fdc6a..7e5d7185ca49ddbd40d4666d5f1dbaa0858ad0f2 100644 --- a/Documentation/media/uapi/v4l/constraints.svg +++ b/Documentation/media/uapi/v4l/constraints.svg @@ -1,346 +1,10 @@ - -image/svg+xmlV4L2_SEL_FLAG_GE -ORIGINAL -V4L2_SEL_FLAG_LE - \ No newline at end of file + +image/svg+xmlV4L2_SEL_FLAG_GE +ORIGINAL +V4L2_SEL_FLAG_LE + diff --git a/Documentation/media/uapi/v4l/crop.svg b/Documentation/media/uapi/v4l/crop.svg index dc9a471bae6b6bca8ba17dbe2f3c7417291f1ceb..3878fe4c49e99736e703903411eb9e04c89ec87d 100644 --- a/Documentation/media/uapi/v4l/crop.svg +++ b/Documentation/media/uapi/v4l/crop.svg @@ -18,33 +18,34 @@ viewBox="0 0 739.11388 339.6584" sodipodi:docname="crop.svg">image/svg+xmlimage/svg+xmlv4l2_cropcap.bounds + transform="matrix(1,0,0,-1,204.52,9.07751)" + style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#d10000;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="text122">v4l2_cropcap.bounds v4l2_cropcap.defrect + transform="matrix(1,0,0,-1,58.5175,166.42)" + style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#0000d1;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="text128">v4l2_cropcap.defrect v4l2_crop.c + transform="matrix(1,0,0,-1,153.49,152.245)" + style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#008f00;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="text134">v4l2_crop.c v4l2_format + transform="matrix(1,0,0,-1,309.415,30.34)" + style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#b000b0;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="text140">v4l2_format + sodipodi:role="line" + id="tspan3398" + x="-99.291145" + y="-239.49893"> diff --git a/Documentation/media/uapi/v4l/dev-meta.rst b/Documentation/media/uapi/v4l/dev-meta.rst index 62518adfe37b6a60644294b55812976437dd6b98..f7ac8d0d3af14a1a6d951df74847972220711133 100644 --- a/Documentation/media/uapi/v4l/dev-meta.rst +++ b/Documentation/media/uapi/v4l/dev-meta.rst @@ -42,6 +42,8 @@ the :c:type:`v4l2_format` structure to 0. .. _v4l2-meta-format: +.. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}| + .. flat-table:: struct v4l2_meta_format :header-rows: 0 :stub-columns: 0 diff --git a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst index 5f6d534ea73b0810de94322710ad90fe42936652..9d6c860271cb58c443f3d46b2c48997fa45f8c85 100644 --- a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst +++ b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst @@ -105,7 +105,13 @@ which may return ``EBUSY`` can be the struct v4l2_sliced_vbi_format ----------------------------- -.. tabularcolumns:: |p{1.0cm}|p{4.5cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}| +.. raw:: latex + + \begingroup + \scriptsize + \setlength{\tabcolsep}{2pt} + +.. tabularcolumns:: |p{.75cm}|p{3.3cm}|p{3.4cm}|p{3.4cm}|p{3.4cm}| .. cssclass:: longtable @@ -199,6 +205,9 @@ struct v4l2_sliced_vbi_format Applications and drivers must set it to zero. +.. raw:: latex + + \endgroup .. _vbi-services2: @@ -207,9 +216,9 @@ Sliced VBI services .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \footnotesize -.. tabularcolumns:: |p{5.0cm}|p{1.4cm}|p{3.0cm}|p{2.5cm}|p{9.0cm}| +.. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{2.4cm}|p{2.0cm}|p{7.3cm}| .. flat-table:: :header-rows: 1 @@ -263,7 +272,7 @@ Sliced VBI services .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Drivers may return an ``EINVAL`` error code when applications attempt to @@ -457,7 +466,7 @@ number). struct v4l2_mpeg_vbi_fmt_ivtv ----------------------------- -.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{1.0cm}|p{11.5cm}| +.. tabularcolumns:: |p{1.0cm}|p{3.8cm}|p{1.0cm}|p{11.2cm}| .. flat-table:: :header-rows: 0 @@ -525,7 +534,7 @@ Magic Constants for struct v4l2_mpeg_vbi_fmt_ivtv magic field structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 ------------------------------------------------- -.. tabularcolumns:: |p{4.4cm}|p{2.4cm}|p{10.7cm}| +.. tabularcolumns:: |p{4.9cm}|p{2.4cm}|p{10.2cm}| .. flat-table:: :header-rows: 0 @@ -574,7 +583,7 @@ structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 struct v4l2_mpeg_vbi_ITV0 ------------------------- -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| +.. tabularcolumns:: |p{4.9cm}|p{4.4cm}|p{8.2cm}| .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/dev-subdev.rst b/Documentation/media/uapi/v4l/dev-subdev.rst index f0e76216773087bcf60fd0457bde43d1d37ab278..d20d945803a78bdb2fc348eff6ce6d404ac189b1 100644 --- a/Documentation/media/uapi/v4l/dev-subdev.rst +++ b/Documentation/media/uapi/v4l/dev-subdev.rst @@ -204,9 +204,9 @@ list entity names and pad numbers). .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \tiny -.. tabularcolumns:: |p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}| +.. tabularcolumns:: |p{2.0cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}| .. _sample-pipeline-config: @@ -253,7 +253,7 @@ list entity names and pad numbers). .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize 1. Initial state. The sensor source pad format is set to its native 3MP size and V4L2_MBUS_FMT_SGRBG8_1X8 media bus code. Formats on the @@ -370,7 +370,7 @@ circumstances. This may also cause the accessed rectangle to be adjusted by the driver, depending on the properties of the underlying hardware. The coordinates to a step always refer to the actual size of the -previous step. The exception to this rule is the source compose +previous step. The exception to this rule is the sink compose rectangle, which refers to the sink compose bounds rectangle --- if it is supported by the hardware. diff --git a/Documentation/media/uapi/v4l/driver.rst b/Documentation/media/uapi/v4l/driver.rst deleted file mode 100644 index 2319b383f0a4efd4f6c3e40240915210c162e8eb..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/v4l/driver.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _driver: - -*********************** -V4L2 Driver Programming -*********************** - -to do diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index 9acc9cad49e2532636ebd52fdc18de4cdd3a8473..a3e81c1d276b2e73150d929b41a37a356e143244 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst @@ -942,21 +942,21 @@ enum v4l2_mpeg_video_mpeg4_level - :header-rows: 0 :stub-columns: 0 - * - ``V4L2_MPEG_VIDEO_LEVEL_0`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0`` - Level 0 - * - ``V4L2_MPEG_VIDEO_LEVEL_0B`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B`` - Level 0b - * - ``V4L2_MPEG_VIDEO_LEVEL_1`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_1`` - Level 1 - * - ``V4L2_MPEG_VIDEO_LEVEL_2`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_2`` - Level 2 - * - ``V4L2_MPEG_VIDEO_LEVEL_3`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3`` - Level 3 - * - ``V4L2_MPEG_VIDEO_LEVEL_3B`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B`` - Level 3b - * - ``V4L2_MPEG_VIDEO_LEVEL_4`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_4`` - Level 4 - * - ``V4L2_MPEG_VIDEO_LEVEL_5`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_5`` - Level 5 @@ -1028,15 +1028,15 @@ enum v4l2_mpeg_video_mpeg4_profile - :header-rows: 0 :stub-columns: 0 - * - ``V4L2_MPEG_VIDEO_PROFILE_SIMPLE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE`` - Simple profile - * - ``V4L2_MPEG_VIDEO_PROFILE_ADVANCED_SIMPLE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE`` - Advanced Simple profile - * - ``V4L2_MPEG_VIDEO_PROFILE_CORE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE`` - Core profile - * - ``V4L2_MPEG_VIDEO_PROFILE_SIMPLE_SCALABLE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE`` - Simple Scalable profile - * - ``V4L2_MPEG_VIDEO_PROFILE_ADVANCED_CODING_EFFICIENCY`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY`` - @@ -1922,9 +1922,9 @@ enum v4l2_vp8_golden_frame_sel - .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \footnotesize -.. tabularcolumns:: |p{11.0cm}|p{10.0cm}| +.. tabularcolumns:: |p{9.0cm}|p{8.0cm}| .. flat-table:: :header-rows: 0 @@ -1940,7 +1940,7 @@ enum v4l2_vp8_golden_frame_sel - .. raw:: latex - \end{adjustbox} + \normalsize ``V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (integer)`` diff --git a/Documentation/media/uapi/v4l/fieldseq_bt.svg b/Documentation/media/uapi/v4l/fieldseq_bt.svg index b195301771ce0f10d4f65d55a22e851e305ce209..909d758f8543fea33e710deb77ad8c6c461a2c6e 100644 --- a/Documentation/media/uapi/v4l/fieldseq_bt.svg +++ b/Documentation/media/uapi/v4l/fieldseq_bt.svg @@ -42,15 +42,15 @@ inkscape:window-maximized="1" inkscape:current-layer="g3627" />image/svg+xmlimage/svg+xmlV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_ALTERNATE + id="tspan4843" + sodipodi:role="line" + y="-533.07098" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_ALTERNATE V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMv4l2_buffer.field: + id="tspan4851" + sodipodi:role="line" + y="-316.23969" + x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMv4l2_buffer.field: Temporal order, bottom field first transmitted (e.g. M/NTSC) + id="tspan4857" + sodipodi:role="line" + y="-592.59381" + x="5.8034 13.134789 19.806232 29.801399 36.472843 43.144287 47.139954 53.811398 56.475174 59.810898 66.482346 70.478004 77.149452 83.820892 87.816566 91.152283 94.488007 101.15945 107.83089 111.16662 114.50233 121.17377 131.16895 134.50468 137.84041 140.50418 147.17563 149.8394 156.51085 159.84657 163.1823 165.84607 169.84174 175.84123 179.17696 182.51268 185.8484 189.84407 196.51552 203.18695 209.18646 219.18163 221.8454 225.18112 228.51685 235.18829 241.85973 245.19545 249.19112 255.86256 259.19827 265.86972 269.20544 272.54117 282.53635 285.87207 294.53534 301.86673 309.87006 318.53336">Temporal order, bottom field first transmitted (e.g. M/NTSC) V4L2_FIELD_TOPV4L2_FIELD_TOP + id="tspan4861" + sodipodi:role="line" + y="-316.23981" + x="290.6604 296.16284 300.74957 305.3363 309.92303 314.50977 319.55023 321.8436 327.34601 331.93274 337.88889 342.47565 347.51608 353.9342 477.73062 483.23306 487.81979 492.40652 496.99326 501.57999 506.62045 508.91382 514.41626 519.00299 524.95911 529.5459 534.5863 541.00446">V4L2_FIELD_TOPV4L2_FIELD_TOP V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BTV4L2_FIELD_INTERLACED_TB (misaligned)V4L2_FIELD_SEQ_BT + id="tspan4865" + sodipodi:role="line" + y="-299.23349" + x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BTV4L2_FIELD_INTERLACED_TB (misaligned)V4L2_FIELD_SEQ_BT V4L2_FIELD_TOP + id="tspan4594" + sodipodi:role="line" + y="-533.07098" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP V4L2_FIELD_BOTTOM + id="tspan4598" + sodipodi:role="line" + y="-465.04559" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM V4L2_FIELD_ALTERNATE + id="tspan4602" + sodipodi:role="line" + y="-397.0202" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT + id="tspan5864" + sodipodi:role="line" + y="-299.23349" + x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT V4L2_FIELD_INTERLACED_TB (misaligned) + id="tspan5868" + sodipodi:role="line" + y="-192.9435" + x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned) V4L2_FIELD_SEQ_BT + id="tspan5872" + sodipodi:role="line" + y="-86.653496" + x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM + id="tspan7146" + sodipodi:role="line" + y="-316.23969" + x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM v4l2_buffer.field: + id="tspan7150" + sodipodi:role="line" + y="-328.99481" + x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field: \ No newline at end of file diff --git a/Documentation/media/uapi/v4l/fieldseq_tb.svg b/Documentation/media/uapi/v4l/fieldseq_tb.svg index 6a7b10ad4ab80b0f04db7594aae1aea95620384b..7c74344e770fa64658d20b86d3e7be42743b91ab 100644 --- a/Documentation/media/uapi/v4l/fieldseq_tb.svg +++ b/Documentation/media/uapi/v4l/fieldseq_tb.svg @@ -42,15 +42,15 @@ inkscape:window-maximized="1" inkscape:current-layer="g5551" />image/svg+xmlimage/svg+xmlV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_ALTERNATE + id="tspan6767" + sodipodi:role="line" + y="-528.771" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_ALTERNATE v4l2_buffer.field:V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM + id="tspan6775" + sodipodi:role="line" + y="-324.69479" + x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM Temporal order, top field first transmitted (e.g. BG/PAL)V4L2_FIELD_SEQ_TBV4L2_FIELD_INTERLACED_BT (misaligned)V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB + id="tspan6781" + sodipodi:role="line" + y="-588.2937" + x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)V4L2_FIELD_SEQ_TBV4L2_FIELD_INTERLACED_BT (misaligned)V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB V4L2_FIELD_TOP + id="tspan4585" + sodipodi:role="line" + y="-528.771" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP V4L2_FIELD_BOTTOM + id="tspan4589" + sodipodi:role="line" + y="-460.74561" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM V4L2_FIELD_ALTERNATE + id="tspan4593" + sodipodi:role="line" + y="-392.72021" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE Temporal order, top field first transmitted (e.g. BG/PAL) + id="tspan5849" + sodipodi:role="line" + y="-588.2937" + x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL) V4L2_FIELD_SEQ_TB + id="tspan5853" + sodipodi:role="line" + y="-86.604706" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB V4L2_FIELD_INTERLACED_BT (misaligned) + id="tspan5857" + sodipodi:role="line" + y="-192.89471" + x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned) V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB + id="tspan5861" + sodipodi:role="line" + y="-294.93271" + x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB v4l2_buffer.field: + id="tspan7133" + sodipodi:role="line" + y="-324.69479" + x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field: V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM + id="tspan7137" + sodipodi:role="line" + y="-311.9397" + x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338 +538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM \ No newline at end of file diff --git a/Documentation/media/uapi/v4l/format.rst b/Documentation/media/uapi/v4l/format.rst index 452c6d59cad53dbabca79d81aa51b275fad4162e..3e3efb0e349e60930f5ca30575b3385ef886a59e 100644 --- a/Documentation/media/uapi/v4l/format.rst +++ b/Documentation/media/uapi/v4l/format.rst @@ -78,7 +78,7 @@ output devices is available. [#f1]_ The :ref:`VIDIOC_ENUM_FMT` ioctl must be supported by all drivers exchanging image data with applications. - **Important** +.. important:: Drivers are not supposed to convert image formats in kernel space. They must enumerate only formats directly supported by the hardware. diff --git a/Documentation/media/uapi/v4l/nv12mt.svg b/Documentation/media/uapi/v4l/nv12mt.svg index 21fcccda9723724c425ef16ce3a8f7a2fcffb469..65d05606c04cdb360aab9a29b4684e235c0c4344 100644 --- a/Documentation/media/uapi/v4l/nv12mt.svg +++ b/Documentation/media/uapi/v4l/nv12mt.svg @@ -18,8 +18,8 @@ sodipodi:docname="nv12mt.svg" style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round">image/svg+xmlimage/svg+xml0 + id="id1" + class="Slide" + clip-path="url(#presentation_clip_path)">0 6 + class="com.sun.star.drawing.CustomShape" + id="g199">6 1 + class="com.sun.star.drawing.CustomShape" + id="g221">1 7 + class="com.sun.star.drawing.CustomShape" + id="g236">7 2 + class="com.sun.star.drawing.CustomShape" + id="g251">2 4 + class="com.sun.star.drawing.CustomShape" + id="g266">4 3 + class="com.sun.star.drawing.CustomShape" + id="g288">3 5 + class="com.sun.star.drawing.CustomShape" + id="g303">5 + class="com.sun.star.drawing.LineShape" + id="g318"> diff --git a/Documentation/media/uapi/v4l/nv12mt_example.svg b/Documentation/media/uapi/v4l/nv12mt_example.svg index d65d989ee73b09e455dd9d1d6e7e1353283c34f0..fc51fe8fda8b677e3a74969009e31ac197851124 100644 --- a/Documentation/media/uapi/v4l/nv12mt_example.svg +++ b/Documentation/media/uapi/v4l/nv12mt_example.svg @@ -18,8 +18,8 @@ sodipodi:docname="nv12mt_example.svg" style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round">image/svg+xmlimage/svg+xml0 + class="BoundingBox" + x="3299" + y="3199" + width="2403" + height="1403" + id="rect191" + style="fill:none;stroke:none" />0 6 + class="BoundingBox" + x="8099" + y="3199" + width="2403" + height="1403" + id="rect213" + style="fill:none;stroke:none" />6 1 + class="BoundingBox" + x="5699" + y="3199" + width="2403" + height="1403" + id="rect228" + style="fill:none;stroke:none" />1 7 + class="BoundingBox" + x="10499" + y="3199" + width="2403" + height="1403" + id="rect243" + style="fill:none;stroke:none" />7 9 + class="BoundingBox" + x="15299" + y="3199" + width="2403" + height="1403" + id="rect265" + style="fill:none;stroke:none" />9 8 + class="BoundingBox" + x="12899" + y="3199" + width="2403" + height="1403" + id="rect280" + style="fill:none;stroke:none" />8 2 + class="BoundingBox" + x="3299" + y="4599" + width="2403" + height="1403" + id="rect295" + style="fill:none;stroke:none" />2 4 + class="BoundingBox" + x="8099" + y="4599" + width="2403" + height="1403" + id="rect317" + style="fill:none;stroke:none" />4 3 + class="BoundingBox" + x="5699" + y="4599" + width="2403" + height="1403" + id="rect332" + style="fill:none;stroke:none" />3 5 + class="BoundingBox" + x="10499" + y="4599" + width="2403" + height="1403" + id="rect347" + style="fill:none;stroke:none" />5 11 + class="BoundingBox" + x="15299" + y="4599" + width="2403" + height="1403" + id="rect369" + style="fill:none;stroke:none" />11 10 + class="BoundingBox" + x="12899" + y="4599" + width="2403" + height="1403" + id="rect384" + style="fill:none;stroke:none" />10 12 + class="BoundingBox" + x="3299" + y="5999" + width="2403" + height="1403" + id="rect399" + style="fill:none;stroke:none" />12 18 + class="BoundingBox" + x="8099" + y="5999" + width="2403" + height="1403" + id="rect421" + style="fill:none;stroke:none" />18 13 + class="BoundingBox" + x="5699" + y="5999" + width="2403" + height="1403" + id="rect436" + style="fill:none;stroke:none" />13 19 + class="BoundingBox" + x="10499" + y="5999" + width="2403" + height="1403" + id="rect451" + style="fill:none;stroke:none" />19 21 + class="BoundingBox" + x="15299" + y="5999" + width="2403" + height="1403" + id="rect473" + style="fill:none;stroke:none" />21 20 + class="BoundingBox" + x="12899" + y="5999" + width="2403" + height="1403" + id="rect488" + style="fill:none;stroke:none" />20 14 + class="BoundingBox" + x="3299" + y="7399" + width="2403" + height="1403" + id="rect503" + style="fill:none;stroke:none" />14 16 + class="BoundingBox" + x="8099" + y="7399" + width="2403" + height="1403" + id="rect525" + style="fill:none;stroke:none" />16 15 + class="BoundingBox" + x="5699" + y="7399" + width="2403" + height="1403" + id="rect540" + style="fill:none;stroke:none" />15 17 + class="BoundingBox" + x="10499" + y="7399" + width="2403" + height="1403" + id="rect555" + style="fill:none;stroke:none" />17 23 + class="BoundingBox" + x="15299" + y="7399" + width="2403" + height="1403" + id="rect577" + style="fill:none;stroke:none" />23 22 + class="BoundingBox" + x="12899" + y="7399" + width="2403" + height="1403" + id="rect592" + style="fill:none;stroke:none" />22 24 + class="BoundingBox" + x="3299" + y="8799" + width="2403" + height="1403" + id="rect607" + style="fill:none;stroke:none" />24 26 + class="BoundingBox" + x="8099" + y="8799" + width="2403" + height="1403" + id="rect629" + style="fill:none;stroke:none" />26 25 + class="BoundingBox" + x="5699" + y="8799" + width="2403" + height="1403" + id="rect644" + style="fill:none;stroke:none" />25 27 + class="BoundingBox" + x="10499" + y="8799" + width="2403" + height="1403" + id="rect659" + style="fill:none;stroke:none" />27 29 + class="BoundingBox" + x="15299" + y="8799" + width="2403" + height="1403" + id="rect681" + style="fill:none;stroke:none" />29 28 + class="BoundingBox" + x="12899" + y="8799" + width="2403" + height="1403" + id="rect696" + style="fill:none;stroke:none" />28 + class="BoundingBox" + x="14799" + y="9450" + width="1202" + height="301" + id="rect945" + style="fill:none;stroke:none" /> diff --git a/Documentation/media/uapi/v4l/pixfmt-008.rst b/Documentation/media/uapi/v4l/pixfmt-008.rst deleted file mode 100644 index 4bec79784bddc1c7da262719b44dd5a064e3a144..0000000000000000000000000000000000000000 --- a/Documentation/media/uapi/v4l/pixfmt-008.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -*************************************** -Detailed Transfer Function Descriptions -*************************************** - - -.. _xf-smpte-2084: - -Transfer Function SMPTE 2084 (V4L2_XFER_FUNC_SMPTE2084) -======================================================= - -The :ref:`smpte2084` standard defines the transfer function used by -High Dynamic Range content. - -Constants: - m1 = (2610 / 4096) / 4 - - m2 = (2523 / 4096) * 128 - - c1 = 3424 / 4096 - - c2 = (2413 / 4096) * 32 - - c3 = (2392 / 4096) * 32 - -Transfer function: - L' = ((c1 + c2 * L\ :sup:`m1`) / (1 + c3 * L\ :sup:`m1`))\ :sup:`m2` - -Inverse Transfer function: - L = (max(L':sup:`1/m2` - c1, 0) / (c2 - c3 * - L'\ :sup:`1/m2`))\ :sup:`1/m1` diff --git a/Documentation/media/uapi/v4l/pixfmt-013.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-013.rst rename to Documentation/media/uapi/v4l/pixfmt-compressed.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-004.rst b/Documentation/media/uapi/v4l/pixfmt-intro.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-004.rst rename to Documentation/media/uapi/v4l/pixfmt-intro.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-inzi.rst b/Documentation/media/uapi/v4l/pixfmt-inzi.rst index 9849e799f2053e8edb1aa0ec98d8a30d12baf083..75272f80bc8a9d3b91094cbeddaa71967bd568b8 100644 --- a/Documentation/media/uapi/v4l/pixfmt-inzi.rst +++ b/Documentation/media/uapi/v4l/pixfmt-inzi.rst @@ -34,11 +34,12 @@ The second plane provides 16-bit per-pixel Depth data arranged in Each cell is a 16-bit word with more significant data stored at higher memory address (byte order is little-endian). + .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \small -.. tabularcolumns:: |p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}| +.. tabularcolumns:: |p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}| .. flat-table:: :header-rows: 0 @@ -78,4 +79,4 @@ memory address (byte order is little-endian). .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize diff --git a/Documentation/media/uapi/v4l/pixfmt-m420.rst b/Documentation/media/uapi/v4l/pixfmt-m420.rst index 7dd47c071e2f1243a34b991cd8c64b73f9ac0d24..6703f4079c3ee07b83acbb12b5d1dd48f002f218 100644 --- a/Documentation/media/uapi/v4l/pixfmt-m420.rst +++ b/Documentation/media/uapi/v4l/pixfmt-m420.rst @@ -66,7 +66,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12.rst b/Documentation/media/uapi/v4l/pixfmt-nv12.rst index 5b45a6d2ac9554eb03a0fe1893b024478e0aef30..2776b41377d5d118f0c0c7096da1d0cdb86b8b78 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv12.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv12.rst @@ -71,7 +71,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12m.rst b/Documentation/media/uapi/v4l/pixfmt-nv12m.rst index de3051fd6b5070df8f30a7bc8c0a8a4a2f69ef66..c1a2779f604c474b83ca899dda7413ef3c2a96e3 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv12m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv12m.rst @@ -83,7 +83,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-nv16.rst b/Documentation/media/uapi/v4l/pixfmt-nv16.rst index 8ceba79ff636491aa2cc116534385493c683542e..f0fdad3006cfcba5e29b627fb46860cead8ac6f7 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv16.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv16.rst @@ -79,7 +79,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-nv16m.rst b/Documentation/media/uapi/v4l/pixfmt-nv16m.rst index 4d46ab39f9f10ce634bb09893cf147388226c63f..c45f036763e7b3233d956c353a8567be9bca04aa 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv16m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv16m.rst @@ -83,7 +83,7 @@ Each cell is one byte. - Cr\ :sub:`32` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst index 3fdb34ce2f095eaf6b6040f8fee44686b043479f..8edf65c80660cf1139ad6abb0a25e4482d9a5bf6 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst @@ -17,11 +17,14 @@ cylinder: 0 being the smallest value and 255 the maximum. The values are packed in 24 or 32 bit formats. + .. raw:: latex - \newline\begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{4.2cm}|p{1.0cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| +.. tabularcolumns:: |p{2.0cm}|p{0.54cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _packed-hsv-formats: @@ -33,11 +36,8 @@ The values are packed in 24 or 32 bit formats. - Code - - :cspan:`7` Byte 0 in memory - - - :cspan:`7` Byte 1 - - - :cspan:`7` Byte 2 - - - :cspan:`7` Byte 3 * - - @@ -50,7 +50,7 @@ The values are packed in 24 or 32 bit formats. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -59,7 +59,7 @@ The values are packed in 24 or 32 bit formats. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -68,7 +68,7 @@ The values are packed in 24 or 32 bit formats. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -90,7 +90,7 @@ The values are packed in 24 or 32 bit formats. - - - - - + - h\ :sub:`7` - h\ :sub:`6` - h\ :sub:`5` @@ -99,7 +99,7 @@ The values are packed in 24 or 32 bit formats. - h\ :sub:`2` - h\ :sub:`1` - h\ :sub:`0` - - + - s\ :sub:`7` - s\ :sub:`6` - s\ :sub:`5` @@ -108,7 +108,7 @@ The values are packed in 24 or 32 bit formats. - s\ :sub:`2` - s\ :sub:`1` - s\ :sub:`0` - - + - v\ :sub:`7` - v\ :sub:`6` - v\ :sub:`5` @@ -130,7 +130,7 @@ The values are packed in 24 or 32 bit formats. - h\ :sub:`2` - h\ :sub:`1` - h\ :sub:`0` - - + - s\ :sub:`7` - s\ :sub:`6` - s\ :sub:`5` @@ -139,7 +139,7 @@ The values are packed in 24 or 32 bit formats. - s\ :sub:`2` - s\ :sub:`1` - s\ :sub:`0` - - + - v\ :sub:`7` - v\ :sub:`6` - v\ :sub:`5` @@ -149,9 +149,9 @@ The values are packed in 24 or 32 bit formats. - v\ :sub:`1` - v\ :sub:`0` - - - + .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup Bit 7 is the most significant bit. diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst index 84fcbcb741711e40706ced242d5021e43265de3a..4938d9655a41fee032ec0e6fbf60d597335bbafb 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst @@ -16,9 +16,12 @@ next to each other in memory. .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} + +.. tabularcolumns:: |p{2.3cm}|p{1.6cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| -.. tabularcolumns:: |p{4.5cm}|p{3.3cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| .. _rgb-formats: @@ -28,17 +31,12 @@ next to each other in memory. * - Identifier - Code - - - :cspan:`7` Byte 0 in memory - - - :cspan:`7` Byte 1 - - - :cspan:`7` Byte 2 - - - :cspan:`7` Byte 3 * - - - - Bit - 7 - 6 - 5 @@ -47,7 +45,7 @@ next to each other in memory. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -56,7 +54,7 @@ next to each other in memory. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -65,7 +63,7 @@ next to each other in memory. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -78,7 +76,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_RGB332`` - 'RGB1' - - + - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` @@ -87,11 +85,12 @@ next to each other in memory. - g\ :sub:`0` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-ARGB444: - ``V4L2_PIX_FMT_ARGB444`` - 'AR12' - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -100,7 +99,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a\ :sub:`3` - a\ :sub:`2` - a\ :sub:`1` @@ -109,11 +108,12 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-XRGB444: - ``V4L2_PIX_FMT_XRGB444`` - 'XR12' - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -122,7 +122,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - - - @@ -131,11 +131,12 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-ARGB555: - ``V4L2_PIX_FMT_ARGB555`` - 'AR15' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -144,7 +145,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -153,11 +154,12 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-XRGB555: - ``V4L2_PIX_FMT_XRGB555`` - 'XR15' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -166,7 +168,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - - r\ :sub:`4` - r\ :sub:`3` @@ -175,11 +177,12 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-RGB565: - ``V4L2_PIX_FMT_RGB565`` - 'RGBP' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -188,7 +191,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - r\ :sub:`4` - r\ :sub:`3` - r\ :sub:`2` @@ -197,11 +200,12 @@ next to each other in memory. - g\ :sub:`5` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-ARGB555X: - ``V4L2_PIX_FMT_ARGB555X`` - 'AR15' | (1 << 31) - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -210,7 +214,7 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -219,11 +223,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-XRGB555X: - ``V4L2_PIX_FMT_XRGB555X`` - 'XR15' | (1 << 31) - - + - - r\ :sub:`4` - r\ :sub:`3` @@ -232,7 +237,7 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -241,11 +246,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-RGB565X: - ``V4L2_PIX_FMT_RGB565X`` - 'RGBR' - - + - r\ :sub:`4` - r\ :sub:`3` - r\ :sub:`2` @@ -254,7 +260,7 @@ next to each other in memory. - g\ :sub:`5` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -263,11 +269,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-BGR24: - ``V4L2_PIX_FMT_BGR24`` - 'BGR3' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -276,7 +283,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -285,7 +292,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -294,11 +301,12 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-RGB24: - ``V4L2_PIX_FMT_RGB24`` - 'RGB3' - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -307,7 +315,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -316,7 +324,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -325,11 +333,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-BGR666: - ``V4L2_PIX_FMT_BGR666`` - 'BGRH' - - + - b\ :sub:`5` - b\ :sub:`4` - b\ :sub:`3` @@ -338,7 +347,7 @@ next to each other in memory. - b\ :sub:`0` - g\ :sub:`5` - g\ :sub:`4` - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -347,7 +356,7 @@ next to each other in memory. - r\ :sub:`4` - r\ :sub:`3` - r\ :sub:`2` - - + - r\ :sub:`1` - r\ :sub:`0` - @@ -356,7 +365,7 @@ next to each other in memory. - - - - - + - - - @@ -369,7 +378,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_ABGR32`` - 'AR24' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -378,7 +387,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -387,7 +396,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -396,7 +405,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -409,7 +418,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_XBGR32`` - 'XR24' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -418,7 +427,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -427,7 +436,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -436,7 +445,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - - - @@ -449,7 +458,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_ARGB32`` - 'BA24' - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -458,7 +467,7 @@ next to each other in memory. - a\ :sub:`2` - a\ :sub:`1` - a\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -467,7 +476,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -476,7 +485,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -489,6 +498,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_XRGB32`` - 'BX24' + - - - @@ -497,8 +507,7 @@ next to each other in memory. - - - - - - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -507,7 +516,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -516,7 +525,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -528,7 +537,7 @@ next to each other in memory. .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup .. note:: Bit 7 is the most significant bit. @@ -562,9 +571,9 @@ Each cell is one byte. .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \small -.. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.3cm}| +.. tabularcolumns:: |p{3.1cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}| .. flat-table:: RGB byte order :header-rows: 0 @@ -626,19 +635,21 @@ Each cell is one byte. .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Formats defined in :ref:`rgb-formats-deprecated` are deprecated and must not be used by new drivers. They are documented here for reference. -The meaning of their alpha bits (a) is ill-defined and interpreted as in +The meaning of their alpha bits ``(a)`` are ill-defined and interpreted as in either the corresponding ARGB or XRGB format, depending on the driver. .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{4.2cm}|p{1.0cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| +.. tabularcolumns:: |p{2.2cm}|p{0.60cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _rgb-formats-deprecated: @@ -648,17 +659,15 @@ either the corresponding ARGB or XRGB format, depending on the driver. * - Identifier - Code - - - :cspan:`7` Byte 0 in memory - - + - :cspan:`7` Byte 1 - - + - :cspan:`7` Byte 2 - - + - :cspan:`7` Byte 3 * - - - - Bit - 7 - 6 - 5 @@ -667,7 +676,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -676,7 +685,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -685,7 +694,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -698,7 +707,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - ``V4L2_PIX_FMT_RGB444`` - 'R444' - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -707,7 +716,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a\ :sub:`3` - a\ :sub:`2` - a\ :sub:`1` @@ -716,11 +725,12 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-RGB555: - ``V4L2_PIX_FMT_RGB555`` - 'RGBO' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -729,7 +739,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -738,11 +748,12 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-RGB555X: - ``V4L2_PIX_FMT_RGB555X`` - 'RGBQ' - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -751,7 +762,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -760,11 +771,12 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-BGR32: - ``V4L2_PIX_FMT_BGR32`` - 'BGR4' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -773,7 +785,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -782,7 +794,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -791,7 +803,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -804,7 +816,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - ``V4L2_PIX_FMT_RGB32`` - 'RGB4' - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -813,7 +825,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - a\ :sub:`2` - a\ :sub:`1` - a\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -822,7 +834,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -831,7 +843,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -843,7 +855,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup A test utility to determine which RGB formats a driver actually supports is available from the LinuxTV v4l-dvb repository. See diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst index ebc8fcc937add2bcfba5db160af55f7bed05eebb..d7644b411cccaaee242271dd15e9f3faf968c505 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst @@ -12,13 +12,16 @@ Description Similar to the packed RGB formats these formats store the Y, Cb and Cr component of each pixel in one 16 or 32 bit word. + .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} .. _packed-yuv-formats: -.. tabularcolumns:: |p{4.5cm}|p{3.3cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| +.. tabularcolumns:: |p{2.0cm}|p{0.67cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}| .. flat-table:: Packed YUV Image Formats :header-rows: 2 @@ -26,17 +29,16 @@ component of each pixel in one 16 or 32 bit word. * - Identifier - Code - - + - :cspan:`7` Byte 0 in memory - - + - :cspan:`7` Byte 1 - - + - :cspan:`7` Byte 2 - - + - :cspan:`7` Byte 3 * - - - - Bit - 7 - 6 - 5 @@ -45,7 +47,7 @@ component of each pixel in one 16 or 32 bit word. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -54,7 +56,7 @@ component of each pixel in one 16 or 32 bit word. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -63,7 +65,7 @@ component of each pixel in one 16 or 32 bit word. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -76,7 +78,7 @@ component of each pixel in one 16 or 32 bit word. - ``V4L2_PIX_FMT_YUV444`` - 'Y444' - - + - Cb\ :sub:`3` - Cb\ :sub:`2` - Cb\ :sub:`1` @@ -85,7 +87,7 @@ component of each pixel in one 16 or 32 bit word. - Cr\ :sub:`2` - Cr\ :sub:`1` - Cr\ :sub:`0` - - + - a\ :sub:`3` - a\ :sub:`2` - a\ :sub:`1` @@ -94,11 +96,12 @@ component of each pixel in one 16 or 32 bit word. - Y'\ :sub:`2` - Y'\ :sub:`1` - Y'\ :sub:`0` + - * .. _V4L2-PIX-FMT-YUV555: - ``V4L2_PIX_FMT_YUV555`` - 'YUVO' - - + - Cb\ :sub:`2` - Cb\ :sub:`1` - Cb\ :sub:`0` @@ -107,7 +110,7 @@ component of each pixel in one 16 or 32 bit word. - Cr\ :sub:`2` - Cr\ :sub:`1` - Cr\ :sub:`0` - - + - a - Y'\ :sub:`4` - Y'\ :sub:`3` @@ -116,11 +119,12 @@ component of each pixel in one 16 or 32 bit word. - Y'\ :sub:`0` - Cb\ :sub:`4` - Cb\ :sub:`3` + - * .. _V4L2-PIX-FMT-YUV565: - ``V4L2_PIX_FMT_YUV565`` - 'YUVP' - - + - Cb\ :sub:`2` - Cb\ :sub:`1` - Cb\ :sub:`0` @@ -129,7 +133,7 @@ component of each pixel in one 16 or 32 bit word. - Cr\ :sub:`2` - Cr\ :sub:`1` - Cr\ :sub:`0` - - + - Y'\ :sub:`4` - Y'\ :sub:`3` - Y'\ :sub:`2` @@ -138,11 +142,12 @@ component of each pixel in one 16 or 32 bit word. - Cb\ :sub:`5` - Cb\ :sub:`4` - Cb\ :sub:`3` + - * .. _V4L2-PIX-FMT-YUV32: - ``V4L2_PIX_FMT_YUV32`` - 'YUV4' - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -151,7 +156,7 @@ component of each pixel in one 16 or 32 bit word. - a\ :sub:`2` - a\ :sub:`1` - a\ :sub:`0` - - + - Y'\ :sub:`7` - Y'\ :sub:`6` - Y'\ :sub:`5` @@ -160,7 +165,7 @@ component of each pixel in one 16 or 32 bit word. - Y'\ :sub:`2` - Y'\ :sub:`1` - Y'\ :sub:`0` - - + - Cb\ :sub:`7` - Cb\ :sub:`6` - Cb\ :sub:`5` @@ -169,7 +174,7 @@ component of each pixel in one 16 or 32 bit word. - Cb\ :sub:`2` - Cb\ :sub:`1` - Cb\ :sub:`0` - - + - Cr\ :sub:`7` - Cr\ :sub:`6` - Cr\ :sub:`5` @@ -181,7 +186,7 @@ component of each pixel in one 16 or 32 bit word. .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup .. note:: diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst index b0f35136021e2a2419e8da2b4b29f2444d06eee6..4cc27195dc797be0ccc334df4381525199f99223 100644 --- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst @@ -17,4 +17,5 @@ RGB Formats pixfmt-srggb10alaw8 pixfmt-srggb10dpcm8 pixfmt-srggb12 + pixfmt-srggb12p pixfmt-srggb16 diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst index b6d426c70ccd82d1b4777065c692008e18823944..d9e07a4b8b314b016243c86b2a96bbbf98ed6a86 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst @@ -33,11 +33,7 @@ of a small V4L2_PIX_FMT_SBGGR10P image: **Byte Order.** Each cell is one byte. -.. raw:: latex - - \newline\newline\begin{adjustbox}{width=\columnwidth} - -.. tabularcolumns:: |p{2.0cm}|p{1.3cm}|p{1.3cm}|p{1.3cm}|p{1.3cm}|p{10.9cm}| +.. tabularcolumns:: |p{2.0cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{5.4cm}| .. flat-table:: :header-rows: 0 @@ -50,6 +46,7 @@ Each cell is one byte. - B\ :sub:`02high` - G\ :sub:`03high` - G\ :sub:`03low`\ (bits 7--6) B\ :sub:`02low`\ (bits 5--4) + G\ :sub:`01low`\ (bits 3--2) B\ :sub:`00low`\ (bits 1--0) * - start + 5: - G\ :sub:`10high` @@ -57,6 +54,7 @@ Each cell is one byte. - G\ :sub:`12high` - R\ :sub:`13high` - R\ :sub:`13low`\ (bits 7--6) G\ :sub:`12low`\ (bits 5--4) + R\ :sub:`11low`\ (bits 3--2) G\ :sub:`10low`\ (bits 1--0) * - start + 10: - B\ :sub:`20high` @@ -64,6 +62,7 @@ Each cell is one byte. - B\ :sub:`22high` - G\ :sub:`23high` - G\ :sub:`23low`\ (bits 7--6) B\ :sub:`22low`\ (bits 5--4) + G\ :sub:`21low`\ (bits 3--2) B\ :sub:`20low`\ (bits 1--0) * - start + 15: - G\ :sub:`30high` @@ -71,8 +70,5 @@ Each cell is one byte. - G\ :sub:`32high` - R\ :sub:`33high` - R\ :sub:`33low`\ (bits 7--6) G\ :sub:`32low`\ (bits 5--4) - R\ :sub:`31low`\ (bits 3--2) G\ :sub:`30low`\ (bits 1--0) -.. raw:: latex - - \end{adjustbox}\newline\newline + R\ :sub:`31low`\ (bits 3--2) G\ :sub:`30low`\ (bits 1--0) diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst new file mode 100644 index 0000000000000000000000000000000000000000..59918a7913fe5d613cd0bfb579f729512af57564 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst @@ -0,0 +1,86 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-SRGGB12P: +.. _v4l2-pix-fmt-sbggr12p: +.. _v4l2-pix-fmt-sgbrg12p: +.. _v4l2-pix-fmt-sgrbg12p: + +******************************************************************************************************************************* +V4L2_PIX_FMT_SRGGB12P ('pRAA'), V4L2_PIX_FMT_SGRBG12P ('pgAA'), V4L2_PIX_FMT_SGBRG12P ('pGAA'), V4L2_PIX_FMT_SBGGR12P ('pBAA'), +******************************************************************************************************************************* + + +12-bit packed Bayer formats + + +Description +=========== + +These four pixel formats are packed raw sRGB / Bayer formats with 12 +bits per colour. Every two consecutive samples are packed into three +bytes. Each of the first two bytes contain the 8 high order bits of +the pixels, and the third byte contains the four least significants +bits of each pixel, in the same order. + +Each n-pixel row contains n/2 green samples and n/2 blue or red +samples, with alternating green-red and green-blue rows. They are +conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. +Below is an example of a small V4L2_PIX_FMT_SBGGR12P image: + +**Byte Order.** +Each cell is one byte. + +.. tabularcolumns:: |p{2.0cm}|p{1.0cm}|p{1.0cm}|p{2.7cm}|p{1.0cm}|p{1.0cm}|p{2.7cm}| + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 2 1 1 1 1 1 1 + + + - - start + 0: + - B\ :sub:`00high` + - G\ :sub:`01high` + - G\ :sub:`01low`\ (bits 7--4) + + B\ :sub:`00low`\ (bits 3--0) + - B\ :sub:`02high` + - G\ :sub:`03high` + - G\ :sub:`03low`\ (bits 7--4) + + B\ :sub:`02low`\ (bits 3--0) + + - - start + 6: + - G\ :sub:`10high` + - R\ :sub:`11high` + - R\ :sub:`11low`\ (bits 7--4) + + G\ :sub:`10low`\ (bits 3--0) + - G\ :sub:`12high` + - R\ :sub:`13high` + - R\ :sub:`13low`\ (bits 3--2) + + G\ :sub:`12low`\ (bits 3--0) + - - start + 12: + - B\ :sub:`20high` + - G\ :sub:`21high` + - G\ :sub:`21low`\ (bits 7--4) + + B\ :sub:`20low`\ (bits 3--0) + - B\ :sub:`22high` + - G\ :sub:`23high` + - G\ :sub:`23low`\ (bits 7--4) + + B\ :sub:`22low`\ (bits 3--0) + - - start + 18: + - G\ :sub:`30high` + - R\ :sub:`31high` + - R\ :sub:`31low`\ (bits 7--4) + + G\ :sub:`30low`\ (bits 3--0) + - G\ :sub:`32high` + - R\ :sub:`33high` + - R\ :sub:`33low`\ (bits 3--2) + + G\ :sub:`32low`\ (bits 3--0) diff --git a/Documentation/media/uapi/v4l/pixfmt-uyvy.rst b/Documentation/media/uapi/v4l/pixfmt-uyvy.rst index 30660e04dd0e1ac9bd0775f14832d72245beb978..ecdc2d94c209cb5325d980a696ae3ab6ea0131c8 100644 --- a/Documentation/media/uapi/v4l/pixfmt-uyvy.rst +++ b/Documentation/media/uapi/v4l/pixfmt-uyvy.rst @@ -65,7 +65,7 @@ Each cell is one byte. - Y'\ :sub:`33` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-003.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-003.rst rename to Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-002.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-002.rst rename to Documentation/media/uapi/v4l/pixfmt-v4l2.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-vyuy.rst b/Documentation/media/uapi/v4l/pixfmt-vyuy.rst index a3f61f280b94b933f2479e07a49b69808bc6b48a..670c339c1714dac5adecbeabd3f6cbe71edd1906 100644 --- a/Documentation/media/uapi/v4l/pixfmt-vyuy.rst +++ b/Documentation/media/uapi/v4l/pixfmt-vyuy.rst @@ -65,7 +65,7 @@ Each cell is one byte. - Y'\ :sub:`33` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt-y41p.rst b/Documentation/media/uapi/v4l/pixfmt-y41p.rst index 05d040c46a47b9b7f225bd5137362377238d10f0..e1fe548807a4ddb6aeed7285536a9063c18bb2b1 100644 --- a/Documentation/media/uapi/v4l/pixfmt-y41p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-y41p.rst @@ -88,7 +88,7 @@ Each cell is one byte. - Y'\ :sub:`37` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv410.rst b/Documentation/media/uapi/v4l/pixfmt-yuv410.rst index 0c49915af8503115b99b127f6fbea71693593509..b51a0d1c6108940ff0b8221bf760f98575c07855 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv410.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv410.rst @@ -67,7 +67,7 @@ Each cell is one byte. - Cb\ :sub:`00` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst b/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst index 2cf33fad7254b40d6c758e88b292368077b303b3..2582341972db5fc2f0a50d33f9b6e3de2029bc8d 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst @@ -75,7 +75,7 @@ Each cell is one byte. - Cr\ :sub:`30` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv420.rst b/Documentation/media/uapi/v4l/pixfmt-yuv420.rst index fd98904058ed90cfdfbf0a9346cd4050efa2b9be..a9b85c4b1dbc721e55db275ecaffbeb7716df56c 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv420.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv420.rst @@ -76,7 +76,7 @@ Each cell is one byte. - Cb\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst index cce8c477fdfc5118d47eaa3da2314e746dccc113..32c68c33f2b17f20dce14aefb429a1bf326e855f 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst @@ -85,7 +85,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst index d986393aa9344e7918447c22621740dab14098a8..9e7028c4967c8edb662136ca714bc4d908d1866b 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst @@ -96,7 +96,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst b/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst index e6f5de546dba625b2c51994fdde4c38c9284eb7b..a96f836c7fa5228d9357487c8669a8be35cb9c83 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst @@ -84,7 +84,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst index 830fbf6fcd1dbf92d0f8dc1e9cb71212b39e42bb..8605bfaee1120768f0bc472ea522af1ace322250 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst @@ -106,7 +106,7 @@ Each cell is one byte. - Cr\ :sub:`33` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuyv.rst b/Documentation/media/uapi/v4l/pixfmt-yuyv.rst index e1bdd6b1aefc36503e11d864f5cab526bab5aba7..53e876d053fb2af50a529f6c39d627385d3ddf12 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuyv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuyv.rst @@ -68,7 +68,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yvyu.rst b/Documentation/media/uapi/v4l/pixfmt-yvyu.rst index 0244ce6741a690d9a113f59aeb9adcdb553a3551..b9c31746e5652bb842890fdc030eeef622c50ce3 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yvyu.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yvyu.rst @@ -65,7 +65,7 @@ Each cell is one byte. - Cb\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt.rst b/Documentation/media/uapi/v4l/pixfmt.rst index 00737152497b9c0cb233cadb9299b36a38a22332..2aa449e2da67246175f9c83b6a5df4d104cbd9e6 100644 --- a/Documentation/media/uapi/v4l/pixfmt.rst +++ b/Documentation/media/uapi/v4l/pixfmt.rst @@ -19,20 +19,19 @@ see also :ref:`VIDIOC_G_FBUF `.) .. toctree:: :maxdepth: 1 - pixfmt-002 - pixfmt-003 - pixfmt-004 - colorspaces - pixfmt-006 - pixfmt-007 - pixfmt-008 + pixfmt-v4l2 + pixfmt-v4l2-mplane + pixfmt-intro pixfmt-indexed pixfmt-rgb yuv-formats hsv-formats depth-formats - pixfmt-013 + pixfmt-compressed sdr-formats tch-formats meta-formats pixfmt-reserved + colorspaces + colorspaces-defs + colorspaces-details diff --git a/Documentation/media/uapi/v4l/selection.svg b/Documentation/media/uapi/v4l/selection.svg index d309187af967b107515b34e82a7d49a1ab5e038a..a93e3b59786db3b3677dd40e2fb446406d890a0f 100644 --- a/Documentation/media/uapi/v4l/selection.svg +++ b/Documentation/media/uapi/v4l/selection.svg @@ -1,5812 +1,1151 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - CROP_DEFAULT - COMPOSE_PADDED - COMPOSE_ACTIVE - COMPOSE_DEFAULT - COMPOSE_PADDED - COMPOSE_BONDS - CROP_BONDS - overscan area - CROP_ACTIVE - DATA SOURCE - DATA SINK - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CROP_DEFAULT + + + + COMPOSE_PADDED + + + COMPOSE_ACTIVE + + + COMPOSE_DEFAULT + + + COMPOSE_PADDED + + + + COMPOSE_BONDS + + + + CROP_BONDS + + + overscan area + + + CROP_ACTIVE + + + DATA SOURCE + + + + DATA SINK + + diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 8e73bb00c0d52efcc0735fe2522a696d968b3491..b1eea44550e1f4562bc1fc90d87702dde27302d7 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -1586,7 +1586,7 @@ JEIDA defined bit mapping will be named .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \tiny .. _v4l2-mbus-pixelcode-rgb-lvds: @@ -1784,7 +1784,7 @@ JEIDA defined bit mapping will be named .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Bayer Formats @@ -7321,11 +7321,14 @@ following information. The following table lists existing HSV/HSL formats. + .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{6.2cm}|p{1.6cm}|p{0.7cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}| +.. tabularcolumns:: |p{3.0cm}|p{0.60cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _v4l2-mbus-pixelcode-hsv: @@ -7413,7 +7416,7 @@ The following table lists existing HSV/HSL formats. .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize JPEG Compressed Formats @@ -7435,7 +7438,7 @@ The following table lists existing JPEG compressed formats. .. _v4l2-mbus-pixelcode-jpeg: -.. tabularcolumns:: |p{5.6cm}|p{1.2cm}|p{10.7cm}| +.. tabularcolumns:: |p{5.4cm}|p{1.4cm}|p{10.7cm}| .. flat-table:: JPEG Formats :header-rows: 1 @@ -7468,7 +7471,7 @@ formats. .. _v4l2-mbus-pixelcode-vendor-specific: -.. tabularcolumns:: |p{6.6cm}|p{1.2cm}|p{9.7cm}| +.. tabularcolumns:: |p{6.8cm}|p{1.4cm}|p{9.3cm}| .. flat-table:: Vendor and device specific formats :header-rows: 1 diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg b/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg index 1903dd3846c2942a9d6083223ba297a589426e49..ee1df49f83e8078c6ce4eced10d910be86db3bec 100644 --- a/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg +++ b/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg @@ -18,11 +18,11 @@ id="metadata100"> - image/svg+xml - - + rdf:about=""> + image/svg+xml + + diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-full.svg b/Documentation/media/uapi/v4l/subdev-image-processing-full.svg index 91cf51832c1205b9b7f93ed19c2816cc8087340c..c10d222b9ea963a82ed7451e3575b1a59e4af4f3 100644 --- a/Documentation/media/uapi/v4l/subdev-image-processing-full.svg +++ b/Documentation/media/uapi/v4l/subdev-image-processing-full.svg @@ -18,11 +18,11 @@ id="metadata260"> - image/svg+xml - - + rdf:about=""> + image/svg+xml + + diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg b/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg index cedcbf59892379f393c1f5643b5e98ac60ece79f..3cb68bf9fc047fb12ba331615bc62043336270c0 100644 --- a/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg +++ b/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg @@ -18,11 +18,11 @@ id="metadata186"> - image/svg+xml - - + rdf:about=""> + image/svg+xml + + diff --git a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst index cab07de6f4dae7846a5ab028bc246cbf9845a4af..87433ec76c6bfa1cbb1b333d7ebc8b0aad42d480 100644 --- a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst +++ b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst @@ -12,7 +12,7 @@ of the two interfaces they are used. .. _v4l2-selection-targets-table: -.. tabularcolumns:: |p{5.8cm}|p{1.4cm}|p{6.5cm}|p{1.2cm}|p{1.6cm}| +.. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{7.4cm}|p{1.2cm}|p{1.4cm}| .. flat-table:: Selection target definitions :header-rows: 1 diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst index f52a11c949d31b28bfd7270944d32529957a2f60..2128717299b3b2250fb7334a4aa7077229fefaae 100644 --- a/Documentation/media/uapi/v4l/v4l2.rst +++ b/Documentation/media/uapi/v4l/v4l2.rst @@ -11,7 +11,9 @@ This part describes the Video for Linux API version 2 (V4L2 API) specification. **Revision 4.5** -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents @@ -23,7 +25,6 @@ This part describes the Video for Linux API version 2 (V4L2 API) specification. pixfmt io devices - driver libv4l compat user-func diff --git a/Documentation/media/uapi/v4l/vbi_525.svg b/Documentation/media/uapi/v4l/vbi_525.svg index b05f7777ccf86124fa1e56574f7bb28a040d62a9..643aec8d0ba2cd093ebe54d59b45fcefc969fac2 100644 --- a/Documentation/media/uapi/v4l/vbi_525.svg +++ b/Documentation/media/uapi/v4l/vbi_525.svg @@ -42,19 +42,21 @@ inkscape:current-layer="g10" units="mm" />image/svg+xmlimage/svg+xml(1) + id="tspan270" + sodipodi:role="line" + y="-4035.6582" + x="1621.9453 1642.3999 1676.5522">(1) 8745691012113226312622712702672682692722732752742662652632642624923156101112784923156101112785242615252622222232328522286231st field2nd field + id="tspan274" + sodipodi:role="line" + y="-4127.7959" + x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">8745691012113226312622712702672682692722732752742662652632642624923156101112784923156101112785242615252622222232328522286231st field2nd field 874569101211322631262 + id="tspan3634" + sodipodi:role="line" + y="-4127.7959" + x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262 271270267268269272273275274266265263264262 + id="tspan3638" + sodipodi:role="line" + y="-4238.3613" + x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262 492315610111278 + id="tspan3642" + sodipodi:role="line" + y="-5049.1729" + x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278 492315610111278 + id="tspan3646" + sodipodi:role="line" + y="-4938.6074" + x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278 524 + id="tspan3650" + sodipodi:role="line" + y="-5049.1729" + x="841.81781 882.8006 923.78326">524 261 + id="tspan3654" + sodipodi:role="line" + y="-4938.6074" + x="841.81781 882.8006 923.78326">261 525 + id="tspan3658" + sodipodi:role="line" + y="-5049.1729" + x="1210.3684 1251.3512 1292.3342">525 262 + id="tspan3662" + sodipodi:role="line" + y="-4938.6074" + x="1210.3684 1251.3512 1292.3342">262 22 + id="tspan3666" + sodipodi:role="line" + y="-5049.1729" + x="6022.0161 6062.999">22 22 + id="tspan3670" + sodipodi:role="line" + y="-4938.6074" + x="6022.0161 6062.999">22 23 + id="tspan3674" + sodipodi:role="line" + y="-5049.1729" + x="6390.5669 6431.5498">23 23 + id="tspan3678" + sodipodi:role="line" + y="-4938.6074" + x="6390.5669 6431.5498">23 285 + id="tspan3682" + sodipodi:role="line" + y="-4238.3623" + x="6001.5244 6042.5068 6083.4902">285 22 + id="tspan3686" + sodipodi:role="line" + y="-4127.7964" + x="6022.0156 6062.9985">22 286 + id="tspan3690" + sodipodi:role="line" + y="-4238.3623" + x="6370.0747 6411.0571 6452.04">286 23 + id="tspan3694" + sodipodi:role="line" + y="-4127.7964" + x="6390.5664 6431.5493">23 1st field + id="tspan3698" + sodipodi:role="line" + y="-4459.4922" + x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field 2nd field + id="tspan3702" + sodipodi:role="line" + y="-3648.6809" + x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field \ No newline at end of file diff --git a/Documentation/media/uapi/v4l/vbi_625.svg b/Documentation/media/uapi/v4l/vbi_625.svg index c117ddb7bf7ee8798c47e0e7616aab474a047d5d..9b18243c0a066e931e5cd856a196aff406eb83c6 100644 --- a/Documentation/media/uapi/v4l/vbi_625.svg +++ b/Documentation/media/uapi/v4l/vbi_625.svg @@ -42,19 +42,21 @@ inkscape:current-layer="g10" units="mm" />image/svg+xmlimage/svg+xml1st field145678323123113102214567832625624623223086213096222nd field + x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895" + y="-4462.3472" + sodipodi:role="line" + id="tspan278">1st field145678323123113102214567832625624623223086213096222nd field (1) + x="2734.751 2755.2776 2789.5503" + y="-4037.021" + sodipodi:role="line" + id="tspan296">(1) 7654323133123113363353213203193183173163153143133123111822233093093103102433723232424 + x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563" + y="-4129.4834" + sodipodi:role="line" + id="tspan300">7654323133123113363353213203193183173163153143133123111822233093093103102433723232424 1st field + x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895" + y="-4462.3472" + sodipodi:role="line" + id="tspan3673">1st field 1456783231231131022 + x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337" + y="-4943.1509" + sodipodi:role="line" + id="tspan3677">1456783231231131022 1456783262562462322 + x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269" + y="-5054.1064" + sodipodi:role="line" + id="tspan3681">1456783262562462322 308 + x="842.29962 883.42694 924.55408" + y="-4943.1509" + sodipodi:role="line" + id="tspan3685">308 621 + x="842.29962 883.42694 924.55408" + y="-5054.1064" + sodipodi:role="line" + id="tspan3689">621 309 + x="1212.1489 1253.276 1294.4033" + y="-4943.1509" + sodipodi:role="line" + id="tspan3693">309 622 + x="1212.1489 1253.276 1294.4033" + y="-5054.1064" + sodipodi:role="line" + id="tspan3697">622 2nd field + x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422" + y="-3648.6792" + sodipodi:role="line" + id="tspan3701">2nd field 765432313312311 + x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563" + y="-4129.4834" + sodipodi:role="line" + id="tspan4085">765432313312311 336335321320319318317316315314313312311 + x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563" + y="-4240.4385" + sodipodi:role="line" + id="tspan4089">336335321320319318317316315314313312311 182223309 + x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055" + y="-4129.4834" + sodipodi:role="line" + id="tspan4093">182223309 309 + x="842.30634 883.43323 924.56055" + y="-4240.4385" + sodipodi:role="line" + id="tspan4097">309 310 + x="1212.1553 1253.2826 1294.4099" + y="-4129.4834" + sodipodi:role="line" + id="tspan4101">310 310 + x="1212.1553 1253.2826 1294.4099" + y="-4240.4385" + sodipodi:role="line" + id="tspan4105">310 24 + x="6410.605 6451.7319" + y="-4129.4834" + sodipodi:role="line" + id="tspan4109">24 337 + x="6390.041 6431.1685 6472.2954" + y="-4240.4385" + sodipodi:role="line" + id="tspan4113">337 23 + x="6040.7559 6081.8833" + y="-4943.1504" + sodipodi:role="line" + id="tspan4117">23 23 + x="6040.7559 6081.8833" + y="-5054.106" + sodipodi:role="line" + id="tspan4121">23 24 + x="6410.605 6451.7324" + y="-4943.1504" + sodipodi:role="line" + id="tspan4125">24 24 + x="6410.605 6451.7324" + y="-5054.106" + sodipodi:role="line" + id="tspan4129">24 \ No newline at end of file diff --git a/Documentation/media/uapi/v4l/vbi_hsync.svg b/Documentation/media/uapi/v4l/vbi_hsync.svg index 4d5c0b4f146e3f533fed3fc9d0066209f2254a38..e17ff8314e7b12ce4c0cf136767384f38a7c3fb6 100644 --- a/Documentation/media/uapi/v4l/vbi_hsync.svg +++ b/Documentation/media/uapi/v4l/vbi_hsync.svg @@ -42,27 +42,27 @@ fit-margin-right="0" fit-margin-bottom="0" />image/svg+xmlimage/svg+xmlBlack LevelSync LevelWhite Level + id="tspan114" + sodipodi:role="line" + y="-187.28558" + x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black LevelSync LevelWhite Level offset + id="tspan122" + sodipodi:role="line" + y="-270.63647" + x="159.88258 172.61443 179.55339 186.49236 198.07812 209.66391">offset Line synchr. pulseLine blanking + id="tspan126" + sodipodi:role="line" + y="-46.630745" + x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulseLine blanking Line synchr. pulse + id="tspan3475" + sodipodi:role="line" + y="-46.630745" + x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse Line blanking + id="tspan3479" + sodipodi:role="line" + y="-4.9552913" + x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking Black Level + id="tspan3609" + sodipodi:role="line" + y="-187.28558" + x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level Sync Level + id="tspan3613" + sodipodi:role="line" + y="-83.096947" + x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level White Level + id="tspan3617" + sodipodi:role="line" + y="-395.66284" + x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level \ No newline at end of file diff --git a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst index aaca12fca06e8b51a8161f9d2c4767c809a8cbd3..a39e18d69511ff3b995452db4803838974df03ed 100644 --- a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst +++ b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_create_buffers`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-cropcap.rst b/Documentation/media/uapi/v4l/vidioc-cropcap.rst index 0f80d5ca2643af3dea85745873f1e48dfdf9ab47..a65dbec6b20b843ffcc019b76b86e5bd83027b67 100644 --- a/Documentation/media/uapi/v4l/vidioc-cropcap.rst +++ b/Documentation/media/uapi/v4l/vidioc-cropcap.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_cropcap`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst b/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst index e1e5507e79ff7f097674dfe6f0cde32e1ea2eee1..7709852282c258a8bff350f786c4c91efed0fa36 100644 --- a/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst +++ b/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dbg_chip_info`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst b/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst index 5960a6547f4141114a9ebce617a737077e575fe9..f4e8dd5f7889e2dd6c9f3128afa4e34a98d22c77 100644 --- a/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst +++ b/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dbg_register`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-dqevent.rst b/Documentation/media/uapi/v4l/vidioc-dqevent.rst index 8d663a73818edceea82c12bf0399b51453c35ddc..cb3565f367933f0b983f2d292400856ac6f50fd2 100644 --- a/Documentation/media/uapi/v4l/vidioc-dqevent.rst +++ b/Documentation/media/uapi/v4l/vidioc-dqevent.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_event`. Description @@ -38,7 +39,7 @@ exceptions which the application may get by e.g. using the select system call. -.. tabularcolumns:: |p{3.0cm}|p{4.3cm}|p{2.5cm}|p{7.7cm}| +.. tabularcolumns:: |p{3.0cm}|p{4.4cm}|p{2.4cm}|p{7.7cm}| .. c:type:: v4l2_event diff --git a/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst b/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst index 424f3a1c7f568fa239ba917f34973a0b5a87a323..63ead6b7a11503422a4f475988861df4aa7c29cd 100644 --- a/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst +++ b/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dv_timings_cap`. Description @@ -97,7 +98,7 @@ that doesn't support them will return an ``EINVAL`` error code. -.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{3.5cm}|p{9.5cm}| +.. tabularcolumns:: |p{1.0cm}|p{4.0cm}|p{3.5cm}|p{9.2cm}| .. c:type:: v4l2_dv_timings_cap diff --git a/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst b/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst index ae20ee573757b3f1550f4bfaf9f2697622ed5746..5ae8c933b1b9c7bc4151eb93744db06f2136d201 100644 --- a/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst +++ b/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst @@ -29,7 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - + Pointer to struct :c:type:`v4l2_encoder_cmd`. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst index 3e9d0f69cc73c135e6d9814300a1569de96bc530..63dca65f49e4db1126089cac9b279a51fb298189 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_enum_dv_timings`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst index a2adaa4bd4ddbddc5c9934d9269e8c2c0546845a..019c513df217a27e81628879c30651df5cf9ec25 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_fmtdesc`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst b/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst index 39492453f02d9746a56585983b713cd02cb154bc..fea7dc3c879d046a7692533dfd92c1e2b1da7b12 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst @@ -26,9 +26,8 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - Pointer to a struct :c:type:`v4l2_frmivalenum` - structure that contains a pixel format and size and receives a frame - interval. + Pointer to struct :c:type:`v4l2_frmivalenum` + that contains a pixel format and size and receives a frame interval. Description @@ -124,6 +123,8 @@ application should zero out all members except for the *IN* fields. .. c:type:: v4l2_frmivalenum +.. tabularcolumns:: |p{1.8cm}|p{4.4cm}|p{2.4cm}|p{8.9cm}| + .. flat-table:: struct v4l2_frmivalenum :header-rows: 0 :stub-columns: 0 diff --git a/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst b/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst index 628f1aa66338a205acb5da745bf27f36126a5112..6de117f163e00d2e53f227041a10214b91d09e9d 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst @@ -26,7 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - Pointer to a struct :c:type:`v4l2_frmsizeenum` + Pointer to struct :c:type:`v4l2_frmsizeenum` that contains an index and pixel format and receives a frame width and height. @@ -140,6 +140,8 @@ application should zero out all members except for the *IN* fields. .. c:type:: v4l2_frmsizeenum +.. tabularcolumns:: |p{1.4cm}|p{5.9cm}|p{2.3cm}|p{8.0cm}| + .. flat-table:: struct v4l2_frmsizeenum :header-rows: 0 :stub-columns: 0 diff --git a/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst b/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst index 4e5f5e5bf632b9cef31520883acab82790918213..195cf45f3c3217292ee7e60c59ba04409852cee0 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_frequency_band`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumaudio.rst b/Documentation/media/uapi/v4l/vidioc-enumaudio.rst index 74bc3ed0bdd8f838556e342fbfbc65ceebd53e97..8e5193e8696f0966dfb6b64a4304b605c7ab5e9b 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumaudio.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumaudio.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audio`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst b/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst index 4470a1ece5cf93aaff81915246f40ef8d829e7da..6d2b4f6e78b0e6989177fb2544767a8ca14d2de4 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audioout`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enuminput.rst b/Documentation/media/uapi/v4l/vidioc-enuminput.rst index 266e48ab237f4b8f688677a0a36e449c4686f52a..0350069a56c551e0920a9f80e0107f12f508cc24 100644 --- a/Documentation/media/uapi/v4l/vidioc-enuminput.rst +++ b/Documentation/media/uapi/v4l/vidioc-enuminput.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_input`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumoutput.rst b/Documentation/media/uapi/v4l/vidioc-enumoutput.rst index 93a2cf3b310c69e8cc0d1fd3ddbcfb04b34f3a66..697dcd186ae30406d992a870bda4bc46aec730f1 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumoutput.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumoutput.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_output`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumstd.rst b/Documentation/media/uapi/v4l/vidioc-enumstd.rst index f2bdd45cfa0d6e9f6e6f8833e4d2c794d01a45fc..b7fda29f46a139a0b15330f5315f417f7b6729e6 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumstd.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumstd.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_standard`. Description @@ -224,12 +225,15 @@ support digital TV. See also the Linux DVB API at #define V4L2_STD_ALL (V4L2_STD_525_60 | V4L2_STD_625_50) + .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} .. NTSC/M PAL/M /N /B /D /H /I SECAM/B /D /K1 /L -.. tabularcolumns:: |p{2.7cm}|p{2.6cm}|p{3.0cm}|p{3.2cm}|p{3.2cm}|p{2.2cm}|p{1.2cm}|p{3.2cm}|p{3.0cm}|p{2.0cm}|p{2.0cm}|p{2.0cm}| +.. tabularcolumns:: |p{1.43cm}|p{1.38cm}|p{1.59cm}|p{1.7cm}|p{1.7cm}|p{1.17cm}|p{0.64cm}|p{1.71cm}|p{1.6cm}|p{1.07cm}|p{1.07cm}|p{1.07cm}| .. _video-standards: @@ -293,7 +297,7 @@ support digital TV. See also the Linux DVB API at .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup diff --git a/Documentation/media/uapi/v4l/vidioc-expbuf.rst b/Documentation/media/uapi/v4l/vidioc-expbuf.rst index 246e48028d40a2d36741432289c5bc273415fb7f..226e83eb28a9c56c25cd5513bac508d592332c60 100644 --- a/Documentation/media/uapi/v4l/vidioc-expbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-expbuf.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_exportbuffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-audio.rst b/Documentation/media/uapi/v4l/vidioc-g-audio.rst index 5b67e81a0db6a3a877f421b2448424acce4f804f..290851f993863e398ffa1f05c377650135f2b7a9 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-audio.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-audio.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audio`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-audioout.rst b/Documentation/media/uapi/v4l/vidioc-g-audioout.rst index d16ecbaddc5985a7e8db2c4f7755dbe63623569a..1c98af33ee70682e992ebb92f4865318c4500baa 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-audioout.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-audioout.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audioout`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-g-crop.rst index 13771ee3e94a9051e1f37904b9dfb6dee407039b..a6ed43ba9ca398090af3e017e405fd5fe35d410c 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-crop.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-crop.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_crop`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst b/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst index d8a379182a34318a99b52e0707d2e452b26f72bb..299b9aabbac235c805e0db90c4a2bad74293feff 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_control`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst index e573c74138dee05afff4493891d9b54ed5baa13c..2696380626d4696a816887944a86e2aa4c708fee 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst @@ -35,6 +35,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dv_timings`. Description @@ -208,7 +209,7 @@ EBUSY - 0 - BT.656/1120 timings - +.. tabularcolumns:: |p{4.5cm}|p{12.8cm}| .. _dv-bt-standards: @@ -231,7 +232,7 @@ EBUSY There are no horizontal syncs/porches at all in this format. Total blanking timings must be set in hsync or vsync fields only. -.. tabularcolumns:: |p{6.0cm}|p{11.5cm}| +.. tabularcolumns:: |p{7.0cm}|p{10.5cm}| .. _dv-bt-flags: diff --git a/Documentation/media/uapi/v4l/vidioc-g-edid.rst b/Documentation/media/uapi/v4l/vidioc-g-edid.rst index a16a193a1cbf8c7fcfe05cac0bc09f0fc316e880..acab90f06e5a0f691e0529e061e2ae244ac46f88 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-edid.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-edid.rst @@ -36,6 +36,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_edid`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst b/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst index 418e886fd44b32fb4201346a31d9a97536955154..9dfe64fc21a42e64197d794420961ebdf4a2a86b 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_enc_idx`. Description @@ -55,7 +56,7 @@ Currently this ioctl is only defined for MPEG-2 program streams and video elementary streams. -.. tabularcolumns:: |p{3.5cm}|p{5.6cm}|p{8.4cm}| +.. tabularcolumns:: |p{3.8cm}|p{5.6cm}|p{8.1cm}| .. c:type:: v4l2_enc_idx diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index 5ab8d2ac27b9b5575268e920a769c61831ed5378..2011c2b2ee675e1b94e9763a736f9c990e790968 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -34,6 +34,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_ext_controls`. Description @@ -180,7 +181,7 @@ still cause this situation. ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set for this control. -.. tabularcolumns:: |p{4.0cm}|p{2.0cm}|p{2.0cm}|p{8.5cm}| +.. tabularcolumns:: |p{4.0cm}|p{2.2cm}|p{2.1cm}|p{8.2cm}| .. c:type:: v4l2_ext_controls diff --git a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst index 4a6a03d158cad61c71e9c398cd117f4ca5148758..fc73bf0f60528405b245529d28659773f0c515c2 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_framebuffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst index b853e48312e2bcaf41a4b182af3b28a96b69cb07..3ead350e099f97a6146ff98bf0126a8388149883 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst @@ -31,6 +31,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_format`. Description @@ -87,7 +88,7 @@ The format as returned by :ref:`VIDIOC_TRY_FMT ` must be identical .. c:type:: v4l2_format -.. tabularcolumns:: |p{1.2cm}|p{4.3cm}|p{3.0cm}|p{9.0cm}| +.. tabularcolumns:: |p{1.2cm}|p{4.6cm}|p{3.0cm}|p{8.6cm}| .. flat-table:: struct v4l2_format :header-rows: 0 @@ -147,3 +148,9 @@ appropriately. The generic error codes are described at the EINVAL The struct :c:type:`v4l2_format` ``type`` field is invalid or the requested buffer type not supported. + +EBUSY + The device is busy and cannot change the format. This could be + because or the device is streaming or buffers are allocated or + queued to the driver. Relevant for :ref:`VIDIOC_S_FMT + ` only. diff --git a/Documentation/media/uapi/v4l/vidioc-g-frequency.rst b/Documentation/media/uapi/v4l/vidioc-g-frequency.rst index 46ab276f412b5ff45e56e67bb5d5b0e78094b19c..c1cccb1446600f6c9390f8bc62632d5fae7a5322 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-frequency.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-frequency.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_frequency`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-input.rst b/Documentation/media/uapi/v4l/vidioc-g-input.rst index 1364a918fbce728fca4dbb289536f6f7acd3e97c..1dcef44eef02bcd4568ee0a79acb5c338cbcffc4 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-input.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-input.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer an integer with input index. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst b/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst index 8ba353067b3392ffd3765d81c16cb59b039c590d..a1773ea9543e71f9663a2ad67de95be82575e4fd 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_jpegcompression`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-modulator.rst b/Documentation/media/uapi/v4l/vidioc-g-modulator.rst index 77d017eb3fccf6f296fdb258757c104c5cfb53b3..a47b6a15cfbe8ef8a14b2ee6b80d97c744954fb9 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-modulator.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-modulator.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_modulator`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-output.rst b/Documentation/media/uapi/v4l/vidioc-g-output.rst index 7750948fc61bac1b3a7baf8e6dbb616ab254a7db..3e0093f668343d657ca1feb947d9dbea943f64f2 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-output.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-output.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to an integer with output index. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-parm.rst b/Documentation/media/uapi/v4l/vidioc-g-parm.rst index 3b2e6e59a3346f8e913c6c4331975170e0c84396..616a5ea3f8face4a2a67c3702841b0ed0a8c001b 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-parm.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-parm.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_streamparm`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-priority.rst b/Documentation/media/uapi/v4l/vidioc-g-priority.rst index a763988f64e46f9eff9abee8535afb58db3d5df2..c28996b4a45c04cff1348ef96f4cd980f2b26385 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-priority.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-priority.rst @@ -29,7 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - Pointer to an enum v4l2_priority type. + Pointer to an enum :c:type:`v4l2_priority` type. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-selection.rst b/Documentation/media/uapi/v4l/vidioc-g-selection.rst index c1ee864729180a64734a76af00cc757444381522..f1d9df029e0d43028c6a40628b9e4408243f6575 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-selection.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-selection.rst @@ -29,11 +29,8 @@ Arguments ``fd`` File descriptor returned by :ref:`open() `. -``request`` - VIDIOC_G_SELECTION, VIDIOC_S_SELECTION - ``argp`` - + Pointer to struct :c:type:`v4l2_selection`. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst b/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst index d7e2b2fa8b88f6fed920af090ecc4a914b1b7590..a9633cae76c5df96d220fdf943ecdb87d461c141 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_sliced_vbi_cap`. Description @@ -122,9 +123,9 @@ the sliced VBI API is unsupported or ``type`` is invalid. .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \scriptsize -.. tabularcolumns:: |p{5.0cm}|p{1.4cm}|p{3.0cm}|p{2.5cm}|p{9.0cm}| +.. tabularcolumns:: |p{3.5cm}|p{1.0cm}|p{2.0cm}|p{2.0cm}|p{8.0cm}| .. _vbi-services: @@ -180,7 +181,7 @@ the sliced VBI API is unsupported or ``type`` is invalid. .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Return Value diff --git a/Documentation/media/uapi/v4l/vidioc-g-std.rst b/Documentation/media/uapi/v4l/vidioc-g-std.rst index cd856ad21a289e5fd4fa982ec45c391bda3ba0ba..90791ab51a5371b8b9794f9abc7346241080f3b8 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-std.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-std.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to :c:type:`v4l2_std_id`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst index 57c79fa438669dd9dc2c87af1c52676d4e9d84b3..acdd15901a51d44e21cd32247b3121148042b4a1 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_tuner`. Description @@ -392,22 +393,25 @@ To change the radio frequency the .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \scriptsize + +.. tabularcolumns:: |p{1.5cm}|p{1.5cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}| .. _tuner-matrix: .. flat-table:: Tuner Audio Matrix :header-rows: 2 :stub-columns: 0 + :widths: 7 7 14 14 14 14 * - - - :cspan:`5` Selected ``V4L2_TUNER_MODE_`` + - :cspan:`4` Selected ``V4L2_TUNER_MODE_`` * - Received ``V4L2_TUNER_SUB_`` - ``MONO`` - ``STEREO`` - ``LANG1`` - ``LANG2 = SAP`` - - ``LANG1_LANG2``\ [#f1]_ + - ``LANG1_LANG2``\ [#f1]_ * - ``MONO`` - Mono - Mono/Mono @@ -434,14 +438,14 @@ To change the radio frequency the - L+R/SAP (preferred) or L/R or L+R/L+R * - ``LANG1 | LANG2`` - Language 1 - - Lang1/Lang2 (deprecated [#f2]_) or Lang1/Lang1 + - Lang1/Lang2 (deprecated\ [#f2]_) or Lang1/Lang1 - Language 1 - Language 2 - Lang1/Lang2 (preferred) or Lang1/Lang1 .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Return Value ============ diff --git a/Documentation/media/uapi/v4l/vidioc-overlay.rst b/Documentation/media/uapi/v4l/vidioc-overlay.rst index cd7b62ebc53b501c4b40305997368eea60edbe1c..1383e3db25fcee4c3ef8ffe933ffd3c1668790b6 100644 --- a/Documentation/media/uapi/v4l/vidioc-overlay.rst +++ b/Documentation/media/uapi/v4l/vidioc-overlay.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to an integer. Description diff --git a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst index bdcfd9fe550df2afc1b545b535f63b1378a54ffa..70687a86ae385c7481d066e6676b9d7dffcc6bf3 100644 --- a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst +++ b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_buffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index 1f361263720028a6ac3c6400138897eeb47f242c..9e448a4aa3aa917df34192b1a00089f8d37de37b 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_buffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst index 0d16853b1b5170af347d6c3d24cc7c553f14b14a..6c82eafd28bbc23fed02fb606cd6d3084d5cae23 100644 --- a/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dv_timings`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-querybuf.rst b/Documentation/media/uapi/v4l/vidioc-querybuf.rst index 0bdc8e0abddc661b0f741f967cad7245dc43e2ff..dd54747fabc9ad7ac1b0805d7eed0745806b05d2 100644 --- a/Documentation/media/uapi/v4l/vidioc-querybuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-querybuf.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_buffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst b/Documentation/media/uapi/v4l/vidioc-querycap.rst index 12e0d9a63cd8a9efc8e8bf855dc14706e4d9d9ce..66fb1b3d6e6efe52b07402855bacab3ff9299fb5 100644 --- a/Documentation/media/uapi/v4l/vidioc-querycap.rst +++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_capability`. Description @@ -91,12 +92,13 @@ specification the ioctl returns an ``EINVAL`` error code. stack from a newer kernel. The version number is formatted using the ``KERNEL_VERSION()`` - macro: + macro. For example if the media stack corresponds to the V4L2 + version shipped with Kernel 4.14, it would be equivalent to: * - :cspan:`2` ``#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))`` - ``__u32 version = KERNEL_VERSION(0, 8, 1);`` + ``__u32 version = KERNEL_VERSION(4, 14, 0);`` ``printf ("Version: %u.%u.%u\\n",`` @@ -131,7 +133,7 @@ specification the ioctl returns an ``EINVAL`` error code. -.. tabularcolumns:: |p{6cm}|p{2.2cm}|p{8.8cm}| +.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}| .. _device-capabilities: diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst index 41c5744a1239726aa98f8bde348c470befa111a4..5bd26e8c9a1a0ef2cba6e6b6d5d2e05a2236b598 100644 --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst @@ -32,6 +32,8 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_queryctl`, :c:type:`v4l2_query_ext_ctrl` + or :c:type`v4l2_querymenu` (depending on the ioctl). Description @@ -274,7 +276,7 @@ See also the examples in :ref:`control`. -.. tabularcolumns:: |p{1.2cm}|p{0.6cm}|p{1.6cm}|p{13.5cm}| +.. tabularcolumns:: |p{1.2cm}|p{1.0cm}|p{1.7cm}|p{13.0cm}| .. _v4l2-querymenu: diff --git a/Documentation/media/uapi/v4l/vidioc-querystd.rst b/Documentation/media/uapi/v4l/vidioc-querystd.rst index 3ef9ab37f58294dcfb367612c2f8d353893746d8..cf40bca19b9f86659866ae50f0bb588cc3345d2a 100644 --- a/Documentation/media/uapi/v4l/vidioc-querystd.rst +++ b/Documentation/media/uapi/v4l/vidioc-querystd.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to :c:type:`v4l2_std_id`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst index a4180d576ee5bb1bc7772958c26152510f7b22fa..316f52c8a310b2c6f7fe3a4892b21035681af87a 100644 --- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst +++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst @@ -26,7 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - + Pointer to struct :c:type:`v4l2_requestbuffers`. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst b/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst index 5672ca48d2bd532c89613ed7844ac21e55a4cf98..b318cb8e1df3a07fc392c1599f8010546b6d8541 100644 --- a/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst +++ b/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_hw_freq_seek`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-streamon.rst b/Documentation/media/uapi/v4l/vidioc-streamon.rst index 972d5b3c74aaf3e515aeeba350e466d0a503c824..e851a6961b78e197ff7f1c7953aa168d314d4e97 100644 --- a/Documentation/media/uapi/v4l/vidioc-streamon.rst +++ b/Documentation/media/uapi/v4l/vidioc-streamon.rst @@ -29,7 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - + Pointer to an integer. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst index 1a02c935c8b50352782340a505c2475476ef190b..1bfe3865dcc241fd05b42ea61dd295548b1c3e75 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_frame_interval_enum`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst index 746c24ed97a054961c40375683b82e6bc2bf42e0..33fdc3ac9316473d9187a677dfae4b9eb596d829 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_frame_size_enum`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst index 0dfee3829ee2668be899f6c8da6e06b5547c088b..4e4291798e4be1d8d08c57fc99f94650c22ab373 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_mbus_code_enum`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst index 000e8fcd3f257b270b4facdd4611691bbd55476e..69b2ae8e7c150c487d2ecb55e99907df2eaf3dd6 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_crop`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst index b352456dfe2c9ee70d9b80d2e92889272f767ead..81c5d331af9a71be93c136f72d443f7f0e5e0d9a 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_format`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst index 46159dcfce30b9cf844f11e3d804725a567788a5..5af0a7179941668bb1fd9955f10330c75ee1443c 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_frame_interval`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst index 071d9c033db6b4af30ba4f0b9baea4aa14e12d42..b1d3dbbef42a89d07d69ac6f1a3564d76b0b5e75 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_selection`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst b/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst index e4a51431032cb3a03073f73fd0d634eb12d99097..b521efa53ceb8aeddabe49193b85507c75e91241 100644 --- a/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst +++ b/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst @@ -30,6 +30,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_event_subscription`. Description @@ -39,7 +40,7 @@ Subscribe or unsubscribe V4L2 event. Subscribed events are dequeued by using the :ref:`VIDIOC_DQEVENT` ioctl. -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| +.. tabularcolumns:: |p{4.6cm}|p{4.4cm}|p{8.7cm}| .. c:type:: v4l2_event_subscription @@ -72,7 +73,7 @@ using the :ref:`VIDIOC_DQEVENT` ioctl. -.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| +.. tabularcolumns:: |p{6.8cm}|p{2.2cm}|p{8.5cm}| .. _event-flags: diff --git a/Documentation/media/v4l-drivers/au0828-cardlist.rst b/Documentation/media/v4l-drivers/au0828-cardlist.rst index 82d2567bc7c1ae77a1fe510277975cca0fafe92e..bb87b7b36a838ba02d5486300197452515603c47 100644 --- a/Documentation/media/v4l-drivers/au0828-cardlist.rst +++ b/Documentation/media/v4l-drivers/au0828-cardlist.rst @@ -1,13 +1,37 @@ AU0828 cards list ================= -=========== ========================== ======================================================================================================================= -Card number Card name USB IDs -=========== ========================== ======================================================================================================================= -0 Unknown board -1 Hauppauge HVR950Q 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270 -2 Hauppauge HVR850 2040:7240 -3 DViCO FusionHDTV USB 0fe9:d620 -4 Hauppauge HVR950Q rev xxF8 2040:7201, 2040:7211, 2040:7281 -5 Hauppauge Woodbury 05e1:0480, 2040:8200 -=========== ========================== ======================================================================================================================= +.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{10.0cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - USB IDs + + * - 0 + - Unknown board + - + + * - 1 + - Hauppauge HVR950Q + - 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270 + + * - 2 + - Hauppauge HVR850 + - 2040:7240 + + * - 3 + - DViCO FusionHDTV USB + - 0fe9:d620 + + * - 4 + - Hauppauge HVR950Q rev xxF8 + - 2040:7201, 2040:7211, 2040:7281 + + * - 5 + - Hauppauge Woodbury + - 05e1:0480, 2040:8200 diff --git a/Documentation/media/v4l-drivers/bttv-cardlist.rst b/Documentation/media/v4l-drivers/bttv-cardlist.rst index 28a01cd6cf2e4489354f7aaceadb1a670d84a459..8da27b924e016c21d91d9cd118027f72729a6543 100644 --- a/Documentation/media/v4l-drivers/bttv-cardlist.rst +++ b/Documentation/media/v4l-drivers/bttv-cardlist.rst @@ -1,174 +1,681 @@ BTTV cards list =============== -=========== ================================================================================= ============================================================================================================================================================================== -Card number Card name PCI IDs -=========== ================================================================================= ============================================================================================================================================================================== -0 *** UNKNOWN/GENERIC *** -1 MIRO PCTV -2 Hauppauge (bt848) -3 STB, Gateway P/N 6000699 (bt848) -4 Intel Create and Share PCI/ Smart Video Recorder III -5 Diamond DTV2000 -6 AVerMedia TVPhone -7 MATRIX-Vision MV-Delta -8 Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 -9 IMS/IXmicro TurboTV -10 Hauppauge (bt878) 0070:13eb, 0070:3900, 2636:10b4 -11 MIRO PCTV pro -12 ADS Technologies Channel Surfer TV (bt848) -13 AVerMedia TVCapture 98 1461:0002, 1461:0004, 1461:0300 -14 Aimslab Video Highway Xtreme (VHX) -15 Zoltrix TV-Max a1a0:a0fc -16 Prolink Pixelview PlayTV (bt878) -17 Leadtek WinView 601 -18 AVEC Intercapture -19 Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) -20 CEI Raffles Card -21 Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 -22 Askey CPH050/ Phoebe Tv Master + FM 14ff:3002 -23 Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 14c7:0101 -24 Askey CPH05X/06X (bt878) [many vendors] 144f:3002, 144f:3005, 144f:5000, 14ff:3000 -25 Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar -26 Hauppauge WinCam newer (bt878) -27 Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 -28 Terratec TerraTV+ Version 1.1 (bt878) 153b:1127, 1852:1852 -29 Imagenation PXC200 1295:200a -30 Lifeview FlyVideo 98 LR50 1f7f:1850 -31 Formac iProTV, Formac ProTV I (bt848) -32 Intel Create and Share PCI/ Smart Video Recorder III -33 Terratec TerraTValue Version Bt878 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018 -34 Leadtek WinFast 2000/ WinFast 2000 XP 107d:6606, 107d:6609, 6606:217d, f6ff:fff6 -35 Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II 1851:1850, 1851:a050 -36 Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner 1852:1852 -37 Prolink PixelView PlayTV pro -38 Askey CPH06X TView99 144f:3000, 144f:a005, a04f:a0fc -39 Pinnacle PCTV Studio/Rave 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12 -40 STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 10b4:2636, 10b4:2645, 121a:3060 -41 AVerMedia TVPhone 98 1461:0001, 1461:0003 -42 ProVideo PV951 aa0c:146c -43 Little OnAir TV -44 Sigma TVII-FM -45 MATRIX-Vision MV-Delta 2 -46 Zoltrix Genie TV/FM 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016 -47 Terratec TV/Radio+ 153b:1123 -48 Askey CPH03x/ Dynalink Magic TView -49 IODATA GV-BCTV3/PCI 10fc:4020 -50 Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP -51 Eagle Wireless Capricorn2 (bt878A) -52 Pinnacle PCTV Studio Pro -53 Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS -54 Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] -55 Askey CPH031/ BESTBUY Easy TV -56 Lifeview FlyVideo 98FM LR50 a051:41a0 -57 GrandTec 'Grand Video Capture' (Bt848) 4344:4142 -58 Askey CPH060/ Phoebe TV Master Only (No FM) -59 Askey CPH03x TV Capturer -60 Modular Technology MM100PCTV -61 AG Electronics GMV1 15cb:0101 -62 Askey CPH061/ BESTBUY Easy TV (bt878) -63 ATI TV-Wonder 1002:0001 -64 ATI TV-Wonder VE 1002:0003 -65 Lifeview FlyVideo 2000S LR90 -66 Terratec TValueRadio 153b:1135, 153b:ff3b -67 IODATA GV-BCTV4/PCI 10fc:4050 -68 3Dfx VoodooTV FM (Euro) 10b4:2637 -69 Active Imaging AIMMS -70 Prolink Pixelview PV-BT878P+ (Rev.4C,8E) -71 Lifeview FlyVideo 98EZ (capture only) LR51 1851:1851 -72 Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) 1554:4011 -73 Sensoray 311/611 6000:0311, 6000:0611 -74 RemoteVision MX (RV605) -75 Powercolor MTV878/ MTV878R/ MTV878F -76 Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) 0e11:0079 -77 GrandTec Multi Capture Card (Bt878) -78 Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF 0a01:17de -79 DSP Design TCVIDEO -80 Hauppauge WinTV PVR 0070:4500 -81 IODATA GV-BCTV5/PCI 10fc:4070, 10fc:d018 -82 Osprey 100/150 (878) 0070:ff00 -83 Osprey 100/150 (848) -84 Osprey 101 (848) -85 Osprey 101/151 -86 Osprey 101/151 w/ svid -87 Osprey 200/201/250/251 -88 Osprey 200/250 0070:ff01 -89 Osprey 210/220/230 -90 Osprey 500 0070:ff02 -91 Osprey 540 0070:ff04 -92 Osprey 2000 0070:ff03 -93 IDS Eagle -94 Pinnacle PCTV Sat 11bd:001c -95 Formac ProTV II (bt878) -96 MachTV -97 Euresys Picolo -98 ProVideo PV150 aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467 -99 AD-TVK503 -100 Hercules Smart TV Stereo -101 Pace TV & Radio Card -102 IVC-200 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155 -103 Grand X-Guard / Trust 814PCI 0304:0102 -104 Nebula Electronics DigiTV 0071:0101 -105 ProVideo PV143 aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433 -106 PHYTEC VD-009-X1 VD-011 MiniDIN (bt878) -107 PHYTEC VD-009-X1 VD-011 Combi (bt878) -108 PHYTEC VD-009 MiniDIN (bt878) -109 PHYTEC VD-009 Combi (bt878) -110 IVC-100 ff00:a132 -111 IVC-120G ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182 -112 pcHDTV HD-2000 TV 7063:2000 -113 Twinhan DST + clones 11bd:0026, 1822:0001, 270f:fc00, 1822:0026 -114 Winfast VC100 107d:6607 -115 Teppro TEV-560/InterVision IV-560 -116 SIMUS GVC1100 aa6a:82b2 -117 NGS NGSTV+ -118 LMLBT4 -119 Tekram M205 PRO -120 Conceptronic CONTVFMi -121 Euresys Picolo Tetra 1805:0105, 1805:0106, 1805:0107, 1805:0108 -122 Spirit TV Tuner -123 AVerMedia AVerTV DVB-T 771 1461:0771 -124 AverMedia AverTV DVB-T 761 1461:0761 -125 MATRIX Vision Sigma-SQ -126 MATRIX Vision Sigma-SLC -127 APAC Viewcomp 878(AMAX) -128 DViCO FusionHDTV DVB-T Lite 18ac:db10, 18ac:db11 -129 V-Gear MyVCD -130 Super TV Tuner -131 Tibet Systems 'Progress DVR' CS16 -132 Kodicom 4400R (master) -133 Kodicom 4400R (slave) -134 Adlink RTV24 -135 DViCO FusionHDTV 5 Lite 18ac:d500 -136 Acorp Y878F 9511:1540 -137 Conceptronic CTVFMi v2 036e:109e -138 Prolink Pixelview PV-BT878P+ (Rev.2E) -139 Prolink PixelView PlayTV MPEG2 PV-M4900 -140 Osprey 440 0070:ff07 -141 Asound Skyeye PCTV -142 Sabrent TV-FM (bttv version) -143 Hauppauge ImpactVCB (bt878) 0070:13eb -144 MagicTV -145 SSAI Security Video Interface 4149:5353 -146 SSAI Ultrasound Video Interface 414a:5353 -147 VoodooTV 200 (USA) 121a:3000 -148 DViCO FusionHDTV 2 dbc0:d200 -149 Typhoon TV-Tuner PCI (50684) -150 Geovision GV-600 008a:763c -151 Kozumi KTV-01C -152 Encore ENL TV-FM-2 1000:1801 -153 PHYTEC VD-012 (bt878) -154 PHYTEC VD-012-X1 (bt878) -155 PHYTEC VD-012-X2 (bt878) -156 IVCE-8784 0000:f050, 0001:f050, 0002:f050, 0003:f050 -157 Geovision GV-800(S) (master) 800a:763d -158 Geovision GV-800(S) (slave) 800b:763d, 800c:763d, 800d:763d -159 ProVideo PV183 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540 -160 Tongwei Video Technology TD-3116 f200:3116 -161 Aposonic W-DVR 0279:0228 -162 Adlink MPG24 -163 Bt848 Capture 14MHz -164 CyberVision CV06 (SV) -165 Kworld V-Stream Xpert TV PVR878 -166 PCI-8604PW -=========== ================================================================================= ============================================================================================================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - *** UNKNOWN/GENERIC *** + - + + * - 1 + - MIRO PCTV + - + + * - 2 + - Hauppauge (bt848) + - + + * - 3 + - STB, Gateway P/N 6000699 (bt848) + - + + * - 4 + - Intel Create and Share PCI/ Smart Video Recorder III + - + + * - 5 + - Diamond DTV2000 + - + + * - 6 + - AVerMedia TVPhone + - + + * - 7 + - MATRIX-Vision MV-Delta + - + + * - 8 + - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 + - + + * - 9 + - IMS/IXmicro TurboTV + - + + * - 10 + - Hauppauge (bt878) + - 0070:13eb, 0070:3900, 2636:10b4 + + * - 11 + - MIRO PCTV pro + - + + * - 12 + - ADS Technologies Channel Surfer TV (bt848) + - + + * - 13 + - AVerMedia TVCapture 98 + - 1461:0002, 1461:0004, 1461:0300 + + * - 14 + - Aimslab Video Highway Xtreme (VHX) + - + + * - 15 + - Zoltrix TV-Max + - a1a0:a0fc + + * - 16 + - Prolink Pixelview PlayTV (bt878) + - + + * - 17 + - Leadtek WinView 601 + - + + * - 18 + - AVEC Intercapture + - + + * - 19 + - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) + - + + * - 20 + - CEI Raffles Card + - + + * - 21 + - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 + - + + * - 22 + - Askey CPH050/ Phoebe Tv Master + FM + - 14ff:3002 + + * - 23 + - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 + - 14c7:0101 + + * - 24 + - Askey CPH05X/06X (bt878) [many vendors] + - 144f:3002, 144f:3005, 144f:5000, 14ff:3000 + + * - 25 + - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar + - + + * - 26 + - Hauppauge WinCam newer (bt878) + - + + * - 27 + - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 + - + + * - 28 + - Terratec TerraTV+ Version 1.1 (bt878) + - 153b:1127, 1852:1852 + + * - 29 + - Imagenation PXC200 + - 1295:200a + + * - 30 + - Lifeview FlyVideo 98 LR50 + - 1f7f:1850 + + * - 31 + - Formac iProTV, Formac ProTV I (bt848) + - + + * - 32 + - Intel Create and Share PCI/ Smart Video Recorder III + - + + * - 33 + - Terratec TerraTValue Version Bt878 + - 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018 + + * - 34 + - Leadtek WinFast 2000/ WinFast 2000 XP + - 107d:6606, 107d:6609, 6606:217d, f6ff:fff6 + + * - 35 + - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II + - 1851:1850, 1851:a050 + + * - 36 + - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner + - 1852:1852 + + * - 37 + - Prolink PixelView PlayTV pro + - + + * - 38 + - Askey CPH06X TView99 + - 144f:3000, 144f:a005, a04f:a0fc + + * - 39 + - Pinnacle PCTV Studio/Rave + - 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12 + + * - 40 + - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 + - 10b4:2636, 10b4:2645, 121a:3060 + + * - 41 + - AVerMedia TVPhone 98 + - 1461:0001, 1461:0003 + + * - 42 + - ProVideo PV951 + - aa0c:146c + + * - 43 + - Little OnAir TV + - + + * - 44 + - Sigma TVII-FM + - + + * - 45 + - MATRIX-Vision MV-Delta 2 + - + + * - 46 + - Zoltrix Genie TV/FM + - 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016 + + * - 47 + - Terratec TV/Radio+ + - 153b:1123 + + * - 48 + - Askey CPH03x/ Dynalink Magic TView + - + + * - 49 + - IODATA GV-BCTV3/PCI + - 10fc:4020 + + * - 50 + - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP + - + + * - 51 + - Eagle Wireless Capricorn2 (bt878A) + - + + * - 52 + - Pinnacle PCTV Studio Pro + - + + * - 53 + - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS + - + + * - 54 + - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] + - + + * - 55 + - Askey CPH031/ BESTBUY Easy TV + - + + * - 56 + - Lifeview FlyVideo 98FM LR50 + - a051:41a0 + + * - 57 + - GrandTec 'Grand Video Capture' (Bt848) + - 4344:4142 + + * - 58 + - Askey CPH060/ Phoebe TV Master Only (No FM) + - + + * - 59 + - Askey CPH03x TV Capturer + - + + * - 60 + - Modular Technology MM100PCTV + - + + * - 61 + - AG Electronics GMV1 + - 15cb:0101 + + * - 62 + - Askey CPH061/ BESTBUY Easy TV (bt878) + - + + * - 63 + - ATI TV-Wonder + - 1002:0001 + + * - 64 + - ATI TV-Wonder VE + - 1002:0003 + + * - 65 + - Lifeview FlyVideo 2000S LR90 + - + + * - 66 + - Terratec TValueRadio + - 153b:1135, 153b:ff3b + + * - 67 + - IODATA GV-BCTV4/PCI + - 10fc:4050 + + * - 68 + - 3Dfx VoodooTV FM (Euro) + - 10b4:2637 + + * - 69 + - Active Imaging AIMMS + - + + * - 70 + - Prolink Pixelview PV-BT878P+ (Rev.4C,8E) + - + + * - 71 + - Lifeview FlyVideo 98EZ (capture only) LR51 + - 1851:1851 + + * - 72 + - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) + - 1554:4011 + + * - 73 + - Sensoray 311/611 + - 6000:0311, 6000:0611 + + * - 74 + - RemoteVision MX (RV605) + - + + * - 75 + - Powercolor MTV878/ MTV878R/ MTV878F + - + + * - 76 + - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) + - 0e11:0079 + + * - 77 + - GrandTec Multi Capture Card (Bt878) + - + + * - 78 + - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF + - 0a01:17de + + * - 79 + - DSP Design TCVIDEO + - + + * - 80 + - Hauppauge WinTV PVR + - 0070:4500 + + * - 81 + - IODATA GV-BCTV5/PCI + - 10fc:4070, 10fc:d018 + + * - 82 + - Osprey 100/150 (878) + - 0070:ff00 + + * - 83 + - Osprey 100/150 (848) + - + + * - 84 + - Osprey 101 (848) + - + + * - 85 + - Osprey 101/151 + - + + * - 86 + - Osprey 101/151 w/ svid + - + + * - 87 + - Osprey 200/201/250/251 + - + + * - 88 + - Osprey 200/250 + - 0070:ff01 + + * - 89 + - Osprey 210/220/230 + - + + * - 90 + - Osprey 500 + - 0070:ff02 + + * - 91 + - Osprey 540 + - 0070:ff04 + + * - 92 + - Osprey 2000 + - 0070:ff03 + + * - 93 + - IDS Eagle + - + + * - 94 + - Pinnacle PCTV Sat + - 11bd:001c + + * - 95 + - Formac ProTV II (bt878) + - + + * - 96 + - MachTV + - + + * - 97 + - Euresys Picolo + - + + * - 98 + - ProVideo PV150 + - aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467 + + * - 99 + - AD-TVK503 + - + + * - 100 + - Hercules Smart TV Stereo + - + + * - 101 + - Pace TV & Radio Card + - + + * - 102 + - IVC-200 + - 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155 + + * - 103 + - Grand X-Guard / Trust 814PCI + - 0304:0102 + + * - 104 + - Nebula Electronics DigiTV + - 0071:0101 + + * - 105 + - ProVideo PV143 + - aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433 + + * - 106 + - PHYTEC VD-009-X1 VD-011 MiniDIN (bt878) + - + + * - 107 + - PHYTEC VD-009-X1 VD-011 Combi (bt878) + - + + * - 108 + - PHYTEC VD-009 MiniDIN (bt878) + - + + * - 109 + - PHYTEC VD-009 Combi (bt878) + - + + * - 110 + - IVC-100 + - ff00:a132 + + * - 111 + - IVC-120G + - ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182 + + * - 112 + - pcHDTV HD-2000 TV + - 7063:2000 + + * - 113 + - Twinhan DST + clones + - 11bd:0026, 1822:0001, 270f:fc00, 1822:0026 + + * - 114 + - Winfast VC100 + - 107d:6607 + + * - 115 + - Teppro TEV-560/InterVision IV-560 + - + + * - 116 + - SIMUS GVC1100 + - aa6a:82b2 + + * - 117 + - NGS NGSTV+ + - + + * - 118 + - LMLBT4 + - + + * - 119 + - Tekram M205 PRO + - + + * - 120 + - Conceptronic CONTVFMi + - + + * - 121 + - Euresys Picolo Tetra + - 1805:0105, 1805:0106, 1805:0107, 1805:0108 + + * - 122 + - Spirit TV Tuner + - + + * - 123 + - AVerMedia AVerTV DVB-T 771 + - 1461:0771 + + * - 124 + - AverMedia AverTV DVB-T 761 + - 1461:0761 + + * - 125 + - MATRIX Vision Sigma-SQ + - + + * - 126 + - MATRIX Vision Sigma-SLC + - + + * - 127 + - APAC Viewcomp 878(AMAX) + - + + * - 128 + - DViCO FusionHDTV DVB-T Lite + - 18ac:db10, 18ac:db11 + + * - 129 + - V-Gear MyVCD + - + + * - 130 + - Super TV Tuner + - + + * - 131 + - Tibet Systems 'Progress DVR' CS16 + - + + * - 132 + - Kodicom 4400R (master) + - + + * - 133 + - Kodicom 4400R (slave) + - + + * - 134 + - Adlink RTV24 + - + + * - 135 + - DViCO FusionHDTV 5 Lite + - 18ac:d500 + + * - 136 + - Acorp Y878F + - 9511:1540 + + * - 137 + - Conceptronic CTVFMi v2 + - 036e:109e + + * - 138 + - Prolink Pixelview PV-BT878P+ (Rev.2E) + - + + * - 139 + - Prolink PixelView PlayTV MPEG2 PV-M4900 + - + + * - 140 + - Osprey 440 + - 0070:ff07 + + * - 141 + - Asound Skyeye PCTV + - + + * - 142 + - Sabrent TV-FM (bttv version) + - + + * - 143 + - Hauppauge ImpactVCB (bt878) + - 0070:13eb + + * - 144 + - MagicTV + - + + * - 145 + - SSAI Security Video Interface + - 4149:5353 + + * - 146 + - SSAI Ultrasound Video Interface + - 414a:5353 + + * - 147 + - VoodooTV 200 (USA) + - 121a:3000 + + * - 148 + - DViCO FusionHDTV 2 + - dbc0:d200 + + * - 149 + - Typhoon TV-Tuner PCI (50684) + - + + * - 150 + - Geovision GV-600 + - 008a:763c + + * - 151 + - Kozumi KTV-01C + - + + * - 152 + - Encore ENL TV-FM-2 + - 1000:1801 + + * - 153 + - PHYTEC VD-012 (bt878) + - + + * - 154 + - PHYTEC VD-012-X1 (bt878) + - + + * - 155 + - PHYTEC VD-012-X2 (bt878) + - + + * - 156 + - IVCE-8784 + - 0000:f050, 0001:f050, 0002:f050, 0003:f050 + + * - 157 + - Geovision GV-800(S) (master) + - 800a:763d + + * - 158 + - Geovision GV-800(S) (slave) + - 800b:763d, 800c:763d, 800d:763d + + * - 159 + - ProVideo PV183 + - 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540 + + * - 160 + - Tongwei Video Technology TD-3116 + - f200:3116 + + * - 161 + - Aposonic W-DVR + - 0279:0228 + + * - 162 + - Adlink MPG24 + - + + * - 163 + - Bt848 Capture 14MHz + - + + * - 164 + - CyberVision CV06 (SV) + - + + * - 165 + - Kworld V-Stream Xpert TV PVR878 + - + + * - 166 + - PCI-8604PW + - diff --git a/Documentation/media/v4l-drivers/cx23885-cardlist.rst b/Documentation/media/v4l-drivers/cx23885-cardlist.rst index fd20b50d2c1d963dbdef04298d779a42d694e975..3129ef04ddd3988b1a0e12971e4f8f2f6223f324 100644 --- a/Documentation/media/v4l-drivers/cx23885-cardlist.rst +++ b/Documentation/media/v4l-drivers/cx23885-cardlist.rst @@ -1,65 +1,245 @@ cx23885 cards list ================== -=========== ==================================== ====================================================================================== -Card number Card name PCI IDs -=========== ==================================== ====================================================================================== -0 UNKNOWN/GENERIC 0070:3400 -1 Hauppauge WinTV-HVR1800lp 0070:7600 -2 Hauppauge WinTV-HVR1800 0070:7800, 0070:7801, 0070:7809 -3 Hauppauge WinTV-HVR1250 0070:7911 -4 DViCO FusionHDTV5 Express 18ac:d500 -5 Hauppauge WinTV-HVR1500Q 0070:7790, 0070:7797 -6 Hauppauge WinTV-HVR1500 0070:7710, 0070:7717 -7 Hauppauge WinTV-HVR1200 0070:71d1, 0070:71d3 -8 Hauppauge WinTV-HVR1700 0070:8101 -9 Hauppauge WinTV-HVR1400 0070:8010 -10 DViCO FusionHDTV7 Dual Express 18ac:d618 -11 DViCO FusionHDTV DVB-T Dual Express 18ac:db78 -12 Leadtek Winfast PxDVR3200 H 107d:6681 -13 Compro VideoMate E650F 185b:e800 -14 TurboSight TBS 6920 6920:8888 -15 TeVii S470 d470:9022 -16 DVBWorld DVB-S2 2005 0001:2005 -17 NetUP Dual DVB-S2 CI 1b55:2a2c -18 Hauppauge WinTV-HVR1270 0070:2211 -19 Hauppauge WinTV-HVR1275 0070:2215, 0070:221d, 0070:22f2 -20 Hauppauge WinTV-HVR1255 0070:2251, 0070:22f1 -21 Hauppauge WinTV-HVR1210 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5 -22 Mygica X8506 DMB-TH 14f1:8651 -23 Magic-Pro ProHDTV Extreme 2 14f1:8657 -24 Hauppauge WinTV-HVR1850 0070:8541 -25 Compro VideoMate E800 1858:e800 -26 Hauppauge WinTV-HVR1290 0070:8551 -27 Mygica X8558 PRO DMB-TH 14f1:8578 -28 LEADTEK WinFast PxTV1200 107d:6f22 -29 GoTView X5 3D Hybrid 5654:2390 -30 NetUP Dual DVB-T/C-CI RF 1b55:e2e4 -31 Leadtek Winfast PxDVR3200 H XC4000 107d:6f39 -32 MPX-885 -33 Mygica X8502/X8507 ISDB-T 14f1:8502 -34 TerraTec Cinergy T PCIe Dual 153b:117e -35 TeVii S471 d471:9022 -36 Hauppauge WinTV-HVR1255 0070:2259 -37 Prof Revolution DVB-S2 8000 8000:3034 -38 Hauppauge WinTV-HVR4400/HVR5500 0070:c108, 0070:c138, 0070:c1f8 -39 AVerTV Hybrid Express Slim HC81R 1461:d939 -40 TurboSight TBS 6981 6981:8888 -41 TurboSight TBS 6980 6980:8888 -42 Leadtek Winfast PxPVR2200 107d:6f21 -43 Hauppauge ImpactVCB-e 0070:7133 -44 DViCO FusionHDTV DVB-T Dual Express2 18ac:db98 -45 DVBSky T9580 4254:9580 -46 DVBSky T980C 4254:980c -47 DVBSky S950C 4254:950c -48 Technotrend TT-budget CT2-4500 CI 13c2:3013 -49 DVBSky S950 4254:0950 -50 DVBSky S952 4254:0952 -51 DVBSky T982 4254:0982 -52 Hauppauge WinTV-HVR5525 0070:f038 -53 Hauppauge WinTV Starburst 0070:c12a -54 ViewCast 260e 1576:0260 -55 ViewCast 460e 1576:0460 -56 Hauppauge WinTV-QuadHD-DVB 0070:6a28, 0070:6b28 -57 Hauppauge WinTV-QuadHD-ATSC 0070:6a18, 0070:6b18 -=========== ==================================== ====================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - UNKNOWN/GENERIC + - 0070:3400 + + * - 1 + - Hauppauge WinTV-HVR1800lp + - 0070:7600 + + * - 2 + - Hauppauge WinTV-HVR1800 + - 0070:7800, 0070:7801, 0070:7809 + + * - 3 + - Hauppauge WinTV-HVR1250 + - 0070:7911 + + * - 4 + - DViCO FusionHDTV5 Express + - 18ac:d500 + + * - 5 + - Hauppauge WinTV-HVR1500Q + - 0070:7790, 0070:7797 + + * - 6 + - Hauppauge WinTV-HVR1500 + - 0070:7710, 0070:7717 + + * - 7 + - Hauppauge WinTV-HVR1200 + - 0070:71d1, 0070:71d3 + + * - 8 + - Hauppauge WinTV-HVR1700 + - 0070:8101 + + * - 9 + - Hauppauge WinTV-HVR1400 + - 0070:8010 + + * - 10 + - DViCO FusionHDTV7 Dual Express + - 18ac:d618 + + * - 11 + - DViCO FusionHDTV DVB-T Dual Express + - 18ac:db78 + + * - 12 + - Leadtek Winfast PxDVR3200 H + - 107d:6681 + + * - 13 + - Compro VideoMate E650F + - 185b:e800 + + * - 14 + - TurboSight TBS 6920 + - 6920:8888 + + * - 15 + - TeVii S470 + - d470:9022 + + * - 16 + - DVBWorld DVB-S2 2005 + - 0001:2005 + + * - 17 + - NetUP Dual DVB-S2 CI + - 1b55:2a2c + + * - 18 + - Hauppauge WinTV-HVR1270 + - 0070:2211 + + * - 19 + - Hauppauge WinTV-HVR1275 + - 0070:2215, 0070:221d, 0070:22f2 + + * - 20 + - Hauppauge WinTV-HVR1255 + - 0070:2251, 0070:22f1 + + * - 21 + - Hauppauge WinTV-HVR1210 + - 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5 + + * - 22 + - Mygica X8506 DMB-TH + - 14f1:8651 + + * - 23 + - Magic-Pro ProHDTV Extreme 2 + - 14f1:8657 + + * - 24 + - Hauppauge WinTV-HVR1850 + - 0070:8541 + + * - 25 + - Compro VideoMate E800 + - 1858:e800 + + * - 26 + - Hauppauge WinTV-HVR1290 + - 0070:8551 + + * - 27 + - Mygica X8558 PRO DMB-TH + - 14f1:8578 + + * - 28 + - LEADTEK WinFast PxTV1200 + - 107d:6f22 + + * - 29 + - GoTView X5 3D Hybrid + - 5654:2390 + + * - 30 + - NetUP Dual DVB-T/C-CI RF + - 1b55:e2e4 + + * - 31 + - Leadtek Winfast PxDVR3200 H XC4000 + - 107d:6f39 + + * - 32 + - MPX-885 + - + + * - 33 + - Mygica X8502/X8507 ISDB-T + - 14f1:8502 + + * - 34 + - TerraTec Cinergy T PCIe Dual + - 153b:117e + + * - 35 + - TeVii S471 + - d471:9022 + + * - 36 + - Hauppauge WinTV-HVR1255 + - 0070:2259 + + * - 37 + - Prof Revolution DVB-S2 8000 + - 8000:3034 + + * - 38 + - Hauppauge WinTV-HVR4400/HVR5500 + - 0070:c108, 0070:c138, 0070:c1f8 + + * - 39 + - AVerTV Hybrid Express Slim HC81R + - 1461:d939 + + * - 40 + - TurboSight TBS 6981 + - 6981:8888 + + * - 41 + - TurboSight TBS 6980 + - 6980:8888 + + * - 42 + - Leadtek Winfast PxPVR2200 + - 107d:6f21 + + * - 43 + - Hauppauge ImpactVCB-e + - 0070:7133 + + * - 44 + - DViCO FusionHDTV DVB-T Dual Express2 + - 18ac:db98 + + * - 45 + - DVBSky T9580 + - 4254:9580 + + * - 46 + - DVBSky T980C + - 4254:980c + + * - 47 + - DVBSky S950C + - 4254:950c + + * - 48 + - Technotrend TT-budget CT2-4500 CI + - 13c2:3013 + + * - 49 + - DVBSky S950 + - 4254:0950 + + * - 50 + - DVBSky S952 + - 4254:0952 + + * - 51 + - DVBSky T982 + - 4254:0982 + + * - 52 + - Hauppauge WinTV-HVR5525 + - 0070:f038 + + * - 53 + - Hauppauge WinTV Starburst + - 0070:c12a + + * - 54 + - ViewCast 260e + - 1576:0260 + + * - 55 + - ViewCast 460e + - 1576:0460 + + * - 56 + - Hauppauge WinTV-QuadHD-DVB + - 0070:6a28, 0070:6b28 + + * - 57 + - Hauppauge WinTV-QuadHD-ATSC + - 0070:6a18, 0070:6b18 diff --git a/Documentation/media/v4l-drivers/cx88-cardlist.rst b/Documentation/media/v4l-drivers/cx88-cardlist.rst index 8cc1cea170353d460f9507f6d776f92820b22636..21648b8c2e8341abc6bf711a746b1e750e3f8d6f 100644 --- a/Documentation/media/v4l-drivers/cx88-cardlist.rst +++ b/Documentation/media/v4l-drivers/cx88-cardlist.rst @@ -1,98 +1,377 @@ CX88 cards list =============== -=========== =================================================== ====================================================================================== -Card number Card name PCI IDs -=========== =================================================== ====================================================================================== -0 UNKNOWN/GENERIC -1 Hauppauge WinTV 34xxx models 0070:3400, 0070:3401 -2 GDI Black Gold 14c7:0106, 14c7:0107 -3 PixelView 1554:4811 -4 ATI TV Wonder Pro 1002:00f8, 1002:00f9 -5 Leadtek Winfast 2000XP Expert 107d:6611, 107d:6613 -6 AverTV Studio 303 (M126) 1461:000b -7 MSI TV-@nywhere Master 1462:8606 -8 Leadtek Winfast DV2000 107d:6620, 107d:6621 -9 Leadtek PVR 2000 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d -10 IODATA GV-VCP3/PCI 10fc:d003 -11 Prolink PlayTV PVR -12 ASUS PVR-416 1043:4823, 1461:c111 -13 MSI TV-@nywhere -14 KWorld/VStream XPert DVB-T 17de:08a6 -15 DViCO FusionHDTV DVB-T1 18ac:db00 -16 KWorld LTV883RF -17 DViCO FusionHDTV 3 Gold-Q 18ac:d810, 18ac:d800 -18 Hauppauge Nova-T DVB-T 0070:9002, 0070:9001, 0070:9000 -19 Conexant DVB-T reference design 14f1:0187 -20 Provideo PV259 1540:2580 -21 DViCO FusionHDTV DVB-T Plus 18ac:db10, 18ac:db11 -22 pcHDTV HD3000 HDTV 7063:3000 -23 digitalnow DNTV Live! DVB-T 17de:a8a6 -24 Hauppauge WinTV 28xxx (Roslyn) models 0070:2801 -25 Digital-Logic MICROSPACE Entertainment Center (MEC) 14f1:0342 -26 IODATA GV/BCTV7E 10fc:d035 -27 PixelView PlayTV Ultra Pro (Stereo) -28 DViCO FusionHDTV 3 Gold-T 18ac:d820 -29 ADS Tech Instant TV DVB-T PCI 1421:0334 -30 TerraTec Cinergy 1400 DVB-T 153b:1166 -31 DViCO FusionHDTV 5 Gold 18ac:d500 -32 AverMedia UltraTV Media Center PCI 550 1461:8011 -33 Kworld V-Stream Xpert DVD -34 ATI HDTV Wonder 1002:a101 -35 WinFast DTV1000-T 107d:665f -36 AVerTV 303 (M126) 1461:000a -37 Hauppauge Nova-S-Plus DVB-S 0070:9201, 0070:9202 -38 Hauppauge Nova-SE2 DVB-S 0070:9200 -39 KWorld DVB-S 100 17de:08b2, 1421:0341 -40 Hauppauge WinTV-HVR1100 DVB-T/Hybrid 0070:9400, 0070:9402 -41 Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) 0070:9800, 0070:9802 -42 digitalnow DNTV Live! DVB-T Pro 1822:0025, 1822:0019 -43 KWorld/VStream XPert DVB-T with cx22702 17de:08a1, 12ab:2300 -44 DViCO FusionHDTV DVB-T Dual Digital 18ac:db50, 18ac:db54 -45 KWorld HardwareMpegTV XPert 17de:0840, 1421:0305 -46 DViCO FusionHDTV DVB-T Hybrid 18ac:db40, 18ac:db44 -47 pcHDTV HD5500 HDTV 7063:5500 -48 Kworld MCE 200 Deluxe 17de:0841 -49 PixelView PlayTV P7000 1554:4813 -50 NPG Tech Real TV FM Top 10 14f1:0842 -51 WinFast DTV2000 H 107d:665e -52 Geniatech DVB-S 14f1:0084 -53 Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T 0070:1404, 0070:1400, 0070:1401, 0070:1402 -54 Norwood Micro TV Tuner -55 Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM c180:c980 -56 Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder 0070:9600, 0070:9601, 0070:9602 -57 ADS Tech Instant Video PCI 1421:0390 -58 Pinnacle PCTV HD 800i 11bd:0051 -59 DViCO FusionHDTV 5 PCI nano 18ac:d530 -60 Pinnacle Hybrid PCTV 12ab:1788 -61 Leadtek TV2000 XP Global 107d:6f18, 107d:6618, 107d:6619 -62 PowerColor RA330 14f1:ea3d -63 Geniatech X8000-MT DVBT 14f1:8852 -64 DViCO FusionHDTV DVB-T PRO 18ac:db30 -65 DViCO FusionHDTV 7 Gold 18ac:d610 -66 Prolink Pixelview MPEG 8000GT 1554:4935 -67 Kworld PlusTV HD PCI 120 (ATSC 120) 17de:08c1 -68 Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid 0070:6900, 0070:6904, 0070:6902 -69 Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 0070:6905, 0070:6906 -70 TeVii S460 DVB-S/S2 d460:9022 -71 Omicom SS4 DVB-S/S2 PCI A044:2011 -72 TBS 8920 DVB-S/S2 8920:8888 -73 TeVii S420 DVB-S d420:9022 -74 Prolink Pixelview Global Extreme 1554:4976 -75 PROF 7300 DVB-S/S2 B033:3033 -76 SATTRADE ST4200 DVB-S/S2 b200:4200 -77 TBS 8910 DVB-S 8910:8888 -78 Prof 6200 DVB-S b022:3022 -79 Terratec Cinergy HT PCI MKII 153b:1177 -80 Hauppauge WinTV-IR Only 0070:9290 -81 Leadtek WinFast DTV1800 Hybrid 107d:6654 -82 WinFast DTV2000 H rev. J 107d:6f2b -83 Prof 7301 DVB-S/S2 b034:3034 -84 Samsung SMT 7020 DVB-S 18ac:dc00, 18ac:dccd -85 Twinhan VP-1027 DVB-S 1822:0023 -86 TeVii S464 DVB-S/S2 d464:9022 -87 Leadtek WinFast DTV2000 H PLUS 107d:6f42 -88 Leadtek WinFast DTV1800 H (XC4000) 107d:6f38 -89 Leadtek TV2000 XP Global (SC4100) 107d:6f36 -90 Leadtek TV2000 XP Global (XC4100) 107d:6f43 -=========== =================================================== ====================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - UNKNOWN/GENERIC + - + + * - 1 + - Hauppauge WinTV 34xxx models + - 0070:3400, 0070:3401 + + * - 2 + - GDI Black Gold + - 14c7:0106, 14c7:0107 + + * - 3 + - PixelView + - 1554:4811 + + * - 4 + - ATI TV Wonder Pro + - 1002:00f8, 1002:00f9 + + * - 5 + - Leadtek Winfast 2000XP Expert + - 107d:6611, 107d:6613 + + * - 6 + - AverTV Studio 303 (M126) + - 1461:000b + + * - 7 + - MSI TV-@nywhere Master + - 1462:8606 + + * - 8 + - Leadtek Winfast DV2000 + - 107d:6620, 107d:6621 + + * - 9 + - Leadtek PVR 2000 + - 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d + + * - 10 + - IODATA GV-VCP3/PCI + - 10fc:d003 + + * - 11 + - Prolink PlayTV PVR + - + + * - 12 + - ASUS PVR-416 + - 1043:4823, 1461:c111 + + * - 13 + - MSI TV-@nywhere + - + + * - 14 + - KWorld/VStream XPert DVB-T + - 17de:08a6 + + * - 15 + - DViCO FusionHDTV DVB-T1 + - 18ac:db00 + + * - 16 + - KWorld LTV883RF + - + + * - 17 + - DViCO FusionHDTV 3 Gold-Q + - 18ac:d810, 18ac:d800 + + * - 18 + - Hauppauge Nova-T DVB-T + - 0070:9002, 0070:9001, 0070:9000 + + * - 19 + - Conexant DVB-T reference design + - 14f1:0187 + + * - 20 + - Provideo PV259 + - 1540:2580 + + * - 21 + - DViCO FusionHDTV DVB-T Plus + - 18ac:db10, 18ac:db11 + + * - 22 + - pcHDTV HD3000 HDTV + - 7063:3000 + + * - 23 + - digitalnow DNTV Live! DVB-T + - 17de:a8a6 + + * - 24 + - Hauppauge WinTV 28xxx (Roslyn) models + - 0070:2801 + + * - 25 + - Digital-Logic MICROSPACE Entertainment Center (MEC) + - 14f1:0342 + + * - 26 + - IODATA GV/BCTV7E + - 10fc:d035 + + * - 27 + - PixelView PlayTV Ultra Pro (Stereo) + - + + * - 28 + - DViCO FusionHDTV 3 Gold-T + - 18ac:d820 + + * - 29 + - ADS Tech Instant TV DVB-T PCI + - 1421:0334 + + * - 30 + - TerraTec Cinergy 1400 DVB-T + - 153b:1166 + + * - 31 + - DViCO FusionHDTV 5 Gold + - 18ac:d500 + + * - 32 + - AverMedia UltraTV Media Center PCI 550 + - 1461:8011 + + * - 33 + - Kworld V-Stream Xpert DVD + - + + * - 34 + - ATI HDTV Wonder + - 1002:a101 + + * - 35 + - WinFast DTV1000-T + - 107d:665f + + * - 36 + - AVerTV 303 (M126) + - 1461:000a + + * - 37 + - Hauppauge Nova-S-Plus DVB-S + - 0070:9201, 0070:9202 + + * - 38 + - Hauppauge Nova-SE2 DVB-S + - 0070:9200 + + * - 39 + - KWorld DVB-S 100 + - 17de:08b2, 1421:0341 + + * - 40 + - Hauppauge WinTV-HVR1100 DVB-T/Hybrid + - 0070:9400, 0070:9402 + + * - 41 + - Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) + - 0070:9800, 0070:9802 + + * - 42 + - digitalnow DNTV Live! DVB-T Pro + - 1822:0025, 1822:0019 + + * - 43 + - KWorld/VStream XPert DVB-T with cx22702 + - 17de:08a1, 12ab:2300 + + * - 44 + - DViCO FusionHDTV DVB-T Dual Digital + - 18ac:db50, 18ac:db54 + + * - 45 + - KWorld HardwareMpegTV XPert + - 17de:0840, 1421:0305 + + * - 46 + - DViCO FusionHDTV DVB-T Hybrid + - 18ac:db40, 18ac:db44 + + * - 47 + - pcHDTV HD5500 HDTV + - 7063:5500 + + * - 48 + - Kworld MCE 200 Deluxe + - 17de:0841 + + * - 49 + - PixelView PlayTV P7000 + - 1554:4813 + + * - 50 + - NPG Tech Real TV FM Top 10 + - 14f1:0842 + + * - 51 + - WinFast DTV2000 H + - 107d:665e + + * - 52 + - Geniatech DVB-S + - 14f1:0084 + + * - 53 + - Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T + - 0070:1404, 0070:1400, 0070:1401, 0070:1402 + + * - 54 + - Norwood Micro TV Tuner + - + + * - 55 + - Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM + - c180:c980 + + * - 56 + - Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder + - 0070:9600, 0070:9601, 0070:9602 + + * - 57 + - ADS Tech Instant Video PCI + - 1421:0390 + + * - 58 + - Pinnacle PCTV HD 800i + - 11bd:0051 + + * - 59 + - DViCO FusionHDTV 5 PCI nano + - 18ac:d530 + + * - 60 + - Pinnacle Hybrid PCTV + - 12ab:1788 + + * - 61 + - Leadtek TV2000 XP Global + - 107d:6f18, 107d:6618, 107d:6619 + + * - 62 + - PowerColor RA330 + - 14f1:ea3d + + * - 63 + - Geniatech X8000-MT DVBT + - 14f1:8852 + + * - 64 + - DViCO FusionHDTV DVB-T PRO + - 18ac:db30 + + * - 65 + - DViCO FusionHDTV 7 Gold + - 18ac:d610 + + * - 66 + - Prolink Pixelview MPEG 8000GT + - 1554:4935 + + * - 67 + - Kworld PlusTV HD PCI 120 (ATSC 120) + - 17de:08c1 + + * - 68 + - Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid + - 0070:6900, 0070:6904, 0070:6902 + + * - 69 + - Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 + - 0070:6905, 0070:6906 + + * - 70 + - TeVii S460 DVB-S/S2 + - d460:9022 + + * - 71 + - Omicom SS4 DVB-S/S2 PCI + - A044:2011 + + * - 72 + - TBS 8920 DVB-S/S2 + - 8920:8888 + + * - 73 + - TeVii S420 DVB-S + - d420:9022 + + * - 74 + - Prolink Pixelview Global Extreme + - 1554:4976 + + * - 75 + - PROF 7300 DVB-S/S2 + - B033:3033 + + * - 76 + - SATTRADE ST4200 DVB-S/S2 + - b200:4200 + + * - 77 + - TBS 8910 DVB-S + - 8910:8888 + + * - 78 + - Prof 6200 DVB-S + - b022:3022 + + * - 79 + - Terratec Cinergy HT PCI MKII + - 153b:1177 + + * - 80 + - Hauppauge WinTV-IR Only + - 0070:9290 + + * - 81 + - Leadtek WinFast DTV1800 Hybrid + - 107d:6654 + + * - 82 + - WinFast DTV2000 H rev. J + - 107d:6f2b + + * - 83 + - Prof 7301 DVB-S/S2 + - b034:3034 + + * - 84 + - Samsung SMT 7020 DVB-S + - 18ac:dc00, 18ac:dccd + + * - 85 + - Twinhan VP-1027 DVB-S + - 1822:0023 + + * - 86 + - TeVii S464 DVB-S/S2 + - d464:9022 + + * - 87 + - Leadtek WinFast DTV2000 H PLUS + - 107d:6f42 + + * - 88 + - Leadtek WinFast DTV1800 H (XC4000) + - 107d:6f38 + + * - 89 + - Leadtek TV2000 XP Global (SC4100) + - 107d:6f36 + + * - 90 + - Leadtek TV2000 XP Global (XC4100) + - 107d:6f43 diff --git a/Documentation/media/v4l-drivers/em28xx-cardlist.rst b/Documentation/media/v4l-drivers/em28xx-cardlist.rst index 76b1d301754cc87e2543d94c9832bd7102335305..ec938c08f43d828a34c22af14b5021178039dd3c 100644 --- a/Documentation/media/v4l-drivers/em28xx-cardlist.rst +++ b/Documentation/media/v4l-drivers/em28xx-cardlist.rst @@ -1,107 +1,422 @@ EM28xx cards list ================= -=========== ==================================================================== ================ ================================================================================================================================== -Card number Card name Empia Chip USB IDs -=========== ==================================================================== ================ ================================================================================================================================== -0 Unknown EM2800 video grabber em2800 eb1a:2800 -1 Unknown EM2750/28xx video grabber em2820 or em2840 eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875 -2 Terratec Cinergy 250 USB em2820 or em2840 0ccd:0036 -3 Pinnacle PCTV USB 2 em2820 or em2840 2304:0208 -4 Hauppauge WinTV USB 2 em2820 or em2840 2040:4200, 2040:4201 -5 MSI VOX USB 2.0 em2820 or em2840 -6 Terratec Cinergy 200 USB em2800 -7 Leadtek Winfast USB II em2800 0413:6023 -8 Kworld USB2800 em2800 -9 Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker em2820 or em2840 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003 -10 Hauppauge WinTV HVR 900 em2880 2040:6500 -11 Terratec Hybrid XS em2880 -12 Kworld PVR TV 2800 RF em2820 or em2840 -13 Terratec Prodigy XS em2880 -14 SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 em2820 or em2840 -15 V-Gear PocketTV em2800 -16 Hauppauge WinTV HVR 950 em2883 2040:6513, 2040:6517, 2040:651b -17 Pinnacle PCTV HD Pro Stick em2880 2304:0227 -18 Hauppauge WinTV HVR 900 (R2) em2880 2040:6502 -19 EM2860/SAA711X Reference Design em2860 -20 AMD ATI TV Wonder HD 600 em2880 0438:b002 -21 eMPIA Technology, Inc. GrabBeeX+ Video Encoder em2800 eb1a:2801 -22 EM2710/EM2750/EM2751 webcam grabber em2750 eb1a:2750, eb1a:2751 -23 Huaqi DLCW-130 em2750 -24 D-Link DUB-T210 TV Tuner em2820 or em2840 2001:f112 -25 Gadmei UTV310 em2820 or em2840 -26 Hercules Smart TV USB 2.0 em2820 or em2840 -27 Pinnacle PCTV USB 2 (Philips FM1216ME) em2820 or em2840 -28 Leadtek Winfast USB II Deluxe em2820 or em2840 -29 EM2860/TVP5150 Reference Design em2860 -30 Videology 20K14XUSB USB2.0 em2820 or em2840 -31 Usbgear VD204v9 em2821 -32 Supercomp USB 2.0 TV em2821 -33 Elgato Video Capture em2860 0fd9:0033 -34 Terratec Cinergy A Hybrid XS em2860 0ccd:004f -35 Typhoon DVD Maker em2860 -36 NetGMBH Cam em2860 -37 Gadmei UTV330 em2860 eb1a:50a6 -38 Yakumo MovieMixer em2861 -39 KWorld PVRTV 300U em2861 eb1a:e300 -40 Plextor ConvertX PX-TV100U em2861 093b:a005 -41 Kworld 350 U DVB-T em2870 eb1a:e350 -42 Kworld 355 U DVB-T em2870 eb1a:e355, eb1a:e357, eb1a:e359 -43 Terratec Cinergy T XS em2870 -44 Terratec Cinergy T XS (MT2060) em2870 0ccd:0043 -45 Pinnacle PCTV DVB-T em2870 -46 Compro, VideoMate U3 em2870 185b:2870 -47 KWorld DVB-T 305U em2880 eb1a:e305 -48 KWorld DVB-T 310U em2880 -49 MSI DigiVox A/D em2880 eb1a:e310 -50 MSI DigiVox A/D II em2880 eb1a:e320 -51 Terratec Hybrid XS Secam em2880 0ccd:004c -52 DNT DA2 Hybrid em2881 -53 Pinnacle Hybrid Pro em2881 -54 Kworld VS-DVB-T 323UR em2882 eb1a:e323 -55 Terratec Cinnergy Hybrid T USB XS (em2882) em2882 0ccd:005e, 0ccd:0042 -56 Pinnacle Hybrid Pro (330e) em2882 2304:0226 -57 Kworld PlusTV HD Hybrid 330 em2883 eb1a:a316 -58 Compro VideoMate ForYou/Stereo em2820 or em2840 185b:2041 -59 Pinnacle PCTV HD Mini em2874 2304:023f -60 Hauppauge WinTV HVR 850 em2883 2040:651f -61 Pixelview PlayTV Box 4 USB 2.0 em2820 or em2840 -62 Gadmei TVR200 em2820 or em2840 -63 Kaiomy TVnPC U2 em2860 eb1a:e303 -64 Easy Cap Capture DC-60 em2860 1b80:e309 -65 IO-DATA GV-MVP/SZ em2820 or em2840 04bb:0515 -66 Empire dual TV em2880 -67 Terratec Grabby em2860 0ccd:0096, 0ccd:10AF -68 Terratec AV350 em2860 0ccd:0084 -69 KWorld ATSC 315U HDTV TV Box em2882 eb1a:a313 -70 Evga inDtube em2882 -71 Silvercrest Webcam 1.3mpix em2820 or em2840 -72 Gadmei UTV330+ em2861 -73 Reddo DVB-C USB TV Box em2870 -74 Actionmaster/LinXcel/Digitus VC211A em2800 -75 Dikom DK300 em2882 -76 KWorld PlusTV 340U or UB435-Q (ATSC) em2870 1b80:a340 -77 EM2874 Leadership ISDBT em2874 -78 PCTV nanoStick T2 290e em28174 2013:024f -79 Terratec Cinergy H5 em2884 eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6 -80 PCTV DVB-S2 Stick (460e) em28174 2013:024c -81 Hauppauge WinTV HVR 930C em2884 2040:1605 -82 Terratec Cinergy HTC Stick em2884 0ccd:00b2 -83 Honestech Vidbox NW03 em2860 eb1a:5006 -84 MaxMedia UB425-TC em2874 1b80:e425 -85 PCTV QuatroStick (510e) em2884 2304:0242 -86 PCTV QuatroStick nano (520e) em2884 2013:0251 -87 Terratec Cinergy HTC USB XS em2884 0ccd:008e, 0ccd:00ac -88 C3 Tech Digital Duo HDTV/SDTV USB em2884 1b80:e755 -89 Delock 61959 em2874 1b80:e1cc -90 KWorld USB ATSC TV Stick UB435-Q V2 em2874 1b80:e346 -91 SpeedLink Vicious And Devine Laplace webcam em2765 1ae7:9003, 1ae7:9004 -92 PCTV DVB-S2 Stick (461e) em28178 2013:0258 -93 KWorld USB ATSC TV Stick UB435-Q V3 em2874 1b80:e34c -94 PCTV tripleStick (292e) em28178 2013:025f, 2040:0264 -95 Leadtek VC100 em2861 0413:6f07 -96 Terratec Cinergy T2 Stick HD em28178 eb1a:8179 -97 Elgato EyeTV Hybrid 2008 INT em2884 0fd9:0018 -98 PLEX PX-BCUD em28178 3275:0085 -99 Hauppauge WinTV-dualHD DVB em28174 2040:0265 -=========== ==================================================================== ================ ================================================================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{10.0cm}|p{1.9cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 12 3 16 + :stub-columns: 0 + + * - Card number + - Card name + - Empia Chip + - USB IDs + * - 0 + - Unknown EM2800 video grabber + - em2800 + - eb1a:2800 + * - 1 + - Unknown EM2750/28xx video grabber + - em2820 or em2840 + - eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875 + * - 2 + - Terratec Cinergy 250 USB + - em2820 or em2840 + - 0ccd:0036 + * - 3 + - Pinnacle PCTV USB 2 + - em2820 or em2840 + - 2304:0208 + * - 4 + - Hauppauge WinTV USB 2 + - em2820 or em2840 + - 2040:4200, 2040:4201 + * - 5 + - MSI VOX USB 2.0 + - em2820 or em2840 + - + * - 6 + - Terratec Cinergy 200 USB + - em2800 + - + * - 7 + - Leadtek Winfast USB II + - em2800 + - 0413:6023 + * - 8 + - Kworld USB2800 + - em2800 + - + * - 9 + - Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U + - em2820 or em2840 + - 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003 + * - 10 + - Hauppauge WinTV HVR 900 + - em2880 + - 2040:6500 + * - 11 + - Terratec Hybrid XS + - em2880 + - + * - 12 + - Kworld PVR TV 2800 RF + - em2820 or em2840 + - + * - 13 + - Terratec Prodigy XS + - em2880 + - + * - 14 + - SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 + - em2820 or em2840 + - + * - 15 + - V-Gear PocketTV + - em2800 + - + * - 16 + - Hauppauge WinTV HVR 950 + - em2883 + - 2040:6513, 2040:6517, 2040:651b + * - 17 + - Pinnacle PCTV HD Pro Stick + - em2880 + - 2304:0227 + * - 18 + - Hauppauge WinTV HVR 900 (R2) + - em2880 + - 2040:6502 + * - 19 + - EM2860/SAA711X Reference Design + - em2860 + - + * - 20 + - AMD ATI TV Wonder HD 600 + - em2880 + - 0438:b002 + * - 21 + - eMPIA Technology, Inc. GrabBeeX+ Video Encoder + - em2800 + - eb1a:2801 + * - 22 + - EM2710/EM2750/EM2751 webcam grabber + - em2750 + - eb1a:2750, eb1a:2751 + * - 23 + - Huaqi DLCW-130 + - em2750 + - + * - 24 + - D-Link DUB-T210 TV Tuner + - em2820 or em2840 + - 2001:f112 + * - 25 + - Gadmei UTV310 + - em2820 or em2840 + - + * - 26 + - Hercules Smart TV USB 2.0 + - em2820 or em2840 + - + * - 27 + - Pinnacle PCTV USB 2 (Philips FM1216ME) + - em2820 or em2840 + - + * - 28 + - Leadtek Winfast USB II Deluxe + - em2820 or em2840 + - + * - 29 + - EM2860/TVP5150 Reference Design + - em2860 + - eb1a:5051 + * - 30 + - Videology 20K14XUSB USB2.0 + - em2820 or em2840 + - + * - 31 + - Usbgear VD204v9 + - em2821 + - + * - 32 + - Supercomp USB 2.0 TV + - em2821 + - + * - 33 + - Elgato Video Capture + - em2860 + - 0fd9:0033 + * - 34 + - Terratec Cinergy A Hybrid XS + - em2860 + - 0ccd:004f + * - 35 + - Typhoon DVD Maker + - em2860 + - + * - 36 + - NetGMBH Cam + - em2860 + - + * - 37 + - Gadmei UTV330 + - em2860 + - eb1a:50a6 + * - 38 + - Yakumo MovieMixer + - em2861 + - + * - 39 + - KWorld PVRTV 300U + - em2861 + - eb1a:e300 + * - 40 + - Plextor ConvertX PX-TV100U + - em2861 + - 093b:a005 + * - 41 + - Kworld 350 U DVB-T + - em2870 + - eb1a:e350 + * - 42 + - Kworld 355 U DVB-T + - em2870 + - eb1a:e355, eb1a:e357, eb1a:e359 + * - 43 + - Terratec Cinergy T XS + - em2870 + - + * - 44 + - Terratec Cinergy T XS (MT2060) + - em2870 + - 0ccd:0043 + * - 45 + - Pinnacle PCTV DVB-T + - em2870 + - + * - 46 + - Compro, VideoMate U3 + - em2870 + - 185b:2870 + * - 47 + - KWorld DVB-T 305U + - em2880 + - eb1a:e305 + * - 48 + - KWorld DVB-T 310U + - em2880 + - + * - 49 + - MSI DigiVox A/D + - em2880 + - eb1a:e310 + * - 50 + - MSI DigiVox A/D II + - em2880 + - eb1a:e320 + * - 51 + - Terratec Hybrid XS Secam + - em2880 + - 0ccd:004c + * - 52 + - DNT DA2 Hybrid + - em2881 + - + * - 53 + - Pinnacle Hybrid Pro + - em2881 + - + * - 54 + - Kworld VS-DVB-T 323UR + - em2882 + - eb1a:e323 + * - 55 + - Terratec Cinnergy Hybrid T USB XS (em2882) + - em2882 + - 0ccd:005e, 0ccd:0042 + * - 56 + - Pinnacle Hybrid Pro (330e) + - em2882 + - 2304:0226 + * - 57 + - Kworld PlusTV HD Hybrid 330 + - em2883 + - eb1a:a316 + * - 58 + - Compro VideoMate ForYou/Stereo + - em2820 or em2840 + - 185b:2041 + * - 59 + - Pinnacle PCTV HD Mini + - em2874 + - 2304:023f + * - 60 + - Hauppauge WinTV HVR 850 + - em2883 + - 2040:651f + * - 61 + - Pixelview PlayTV Box 4 USB 2.0 + - em2820 or em2840 + - + * - 62 + - Gadmei TVR200 + - em2820 or em2840 + - + * - 63 + - Kaiomy TVnPC U2 + - em2860 + - eb1a:e303 + * - 64 + - Easy Cap Capture DC-60 + - em2860 + - 1b80:e309 + * - 65 + - IO-DATA GV-MVP/SZ + - em2820 or em2840 + - 04bb:0515 + * - 66 + - Empire dual TV + - em2880 + - + * - 67 + - Terratec Grabby + - em2860 + - 0ccd:0096, 0ccd:10AF + * - 68 + - Terratec AV350 + - em2860 + - 0ccd:0084 + * - 69 + - KWorld ATSC 315U HDTV TV Box + - em2882 + - eb1a:a313 + * - 70 + - Evga inDtube + - em2882 + - + * - 71 + - Silvercrest Webcam 1.3mpix + - em2820 or em2840 + - + * - 72 + - Gadmei UTV330+ + - em2861 + - + * - 73 + - Reddo DVB-C USB TV Box + - em2870 + - + * - 74 + - Actionmaster/LinXcel/Digitus VC211A + - em2800 + - + * - 75 + - Dikom DK300 + - em2882 + - + * - 76 + - KWorld PlusTV 340U or UB435-Q (ATSC) + - em2870 + - 1b80:a340 + * - 77 + - EM2874 Leadership ISDBT + - em2874 + - + * - 78 + - PCTV nanoStick T2 290e + - em28174 + - 2013:024f + * - 79 + - Terratec Cinergy H5 + - em2884 + - eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6 + * - 80 + - PCTV DVB-S2 Stick (460e) + - em28174 + - 2013:024c + * - 81 + - Hauppauge WinTV HVR 930C + - em2884 + - 2040:1605 + * - 82 + - Terratec Cinergy HTC Stick + - em2884 + - 0ccd:00b2 + * - 83 + - Honestech Vidbox NW03 + - em2860 + - eb1a:5006 + * - 84 + - MaxMedia UB425-TC + - em2874 + - 1b80:e425 + * - 85 + - PCTV QuatroStick (510e) + - em2884 + - 2304:0242 + * - 86 + - PCTV QuatroStick nano (520e) + - em2884 + - 2013:0251 + * - 87 + - Terratec Cinergy HTC USB XS + - em2884 + - 0ccd:008e, 0ccd:00ac + * - 88 + - C3 Tech Digital Duo HDTV/SDTV USB + - em2884 + - 1b80:e755 + * - 89 + - Delock 61959 + - em2874 + - 1b80:e1cc + * - 90 + - KWorld USB ATSC TV Stick UB435-Q V2 + - em2874 + - 1b80:e346 + * - 91 + - SpeedLink Vicious And Devine Laplace webcam + - em2765 + - 1ae7:9003, 1ae7:9004 + * - 92 + - PCTV DVB-S2 Stick (461e) + - em28178 + - 2013:0258 + * - 93 + - KWorld USB ATSC TV Stick UB435-Q V3 + - em2874 + - 1b80:e34c + * - 94 + - PCTV tripleStick (292e) + - em28178 + - 2013:025f, 2040:0264 + * - 95 + - Leadtek VC100 + - em2861 + - 0413:6f07 + * - 96 + - Terratec Cinergy T2 Stick HD + - em28178 + - eb1a:8179 + * - 97 + - Elgato EyeTV Hybrid 2008 INT + - em2884 + - 0fd9:0018 + * - 98 + - PLEX PX-BCUD + - em28178 + - 3275:0085 + * - 99 + - Hauppauge WinTV-dualHD DVB + - em28174 + - 2040:0265 + * - 100 + - Hauppauge WinTV-dualHD 01595 ATSC/QAM + - em28174 + - 2040:026d + * - 101 + - Terratec Cinergy H6 rev. 2 + - em2884 + - 0ccd:10b2 diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst index e0ee0f1aeb05b499ee3254878698bf2b86ac107f..3c4f58bda178448c03702b9a4ed9b5a9faca0db8 100644 --- a/Documentation/media/v4l-drivers/imx.rst +++ b/Documentation/media/v4l-drivers/imx.rst @@ -607,8 +607,9 @@ References Authors ------- -Steve Longerbeam -Philipp Zabel -Russell King + +- Steve Longerbeam +- Philipp Zabel +- Russell King Copyright (C) 2012-2017 Mentor Graphics Inc. diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index 2e24d680605229d86f81b8089af35f72c0499dfa..679238e786a77b8bd1b310b1795804aabfffdf3d 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst @@ -21,7 +21,9 @@ more details. For more details see the file COPYING in the source distribution of Linux. -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents @@ -41,6 +43,7 @@ For more details see the file COPYING in the source distribution of Linux. cx88 davinci-vpbe fimc + imx ivtv max2175 meye @@ -49,6 +52,7 @@ For more details see the file COPYING in the source distribution of Linux. philips pvrusb2 pxa_camera + qcom_camss radiotrack rcar-fdp1 saa7134 diff --git a/Documentation/media/v4l-drivers/ivtv-cardlist.rst b/Documentation/media/v4l-drivers/ivtv-cardlist.rst index 754ffa820b4c14798d3b59ad3ecd759676777600..022dca80c2c8717befff64a5ee234e33a571d388 100644 --- a/Documentation/media/v4l-drivers/ivtv-cardlist.rst +++ b/Documentation/media/v4l-drivers/ivtv-cardlist.rst @@ -1,38 +1,137 @@ IVTV cards list =============== -=========== ============================================================= ==================================================== -Card number Card name PCI IDs -=========== ============================================================= ==================================================== -0 Hauppauge WinTV PVR-250 IVTV16 104d:813d -1 Hauppauge WinTV PVR-350 IVTV16 104d:813d -2 Hauppauge WinTV PVR-150 IVTV16 104d:813d -3 AVerMedia M179 IVTV15 1461:a3cf, IVTV15 1461:a3ce -4 Yuan MPG600, Kuroutoshikou ITVC16-STVLP IVTV16 12ab:fff3, IVTV16 12ab:ffff -5 YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI IVTV15 10fc:40a0 -6 Yuan PG600, Diamond PVR-550 IVTV16 ff92:0070, IVTV16 ffab:0600 -7 Adaptec VideOh! AVC-2410 IVTV16 9005:0093 -8 Adaptec VideOh! AVC-2010 IVTV16 9005:0092 -9 Nagase Transgear 5000TV IVTV16 1461:bfff -10 AOpen VA2000MAX-SNT6 IVTV16 0000:ff5f -11 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523 -12 I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039 -13 I/O Data GV-MVP/RX2E IVTV16 10fc:d025 -14 GotView PCI DVD IVTV16 12ab:0600 -15 GotView PCI DVD2 Deluxe IVTV16 ffac:0600 -16 Yuan MPC622 IVTV16 ff01:d998 -17 Digital Cowboy DCT-MTVP1 IVTV16 1461:bfff -18 Yuan PG600-2, GotView PCI DVD Lite IVTV16 ffab:0600, IVTV16 ffad:0600 -19 Club3D ZAP-TV1x01 IVTV16 ffab:0600 -20 AVerTV MCE 116 Plus IVTV16 1461:c439 -21 ASUS Falcon2 IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e -22 AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner IVTV16 1461:c034, IVTV16 1461:c035 -23 AVerMedia EZMaker PCI Deluxe IVTV16 1461:c03f -24 AVerMedia M104 IVTV16 1461:c136 -25 Buffalo PC-MV5L/PCI IVTV16 1154:052b -26 AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner IVTV16 1461:c019, IVTV16 1461:c01b -27 Sony VAIO Giga Pocket (ENX Kikyou) IVTV16 104d:813d -28 Hauppauge WinTV PVR-350 (V1) IVTV16 104d:813d -29 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR) IVTV16 104d:813d -30 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS) IVTV16 104d:813d -=========== ============================================================= ==================================================== +.. tabularcolumns:: |p{1.4cm}|p{12.7cm}|p{3.4cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - Hauppauge WinTV PVR-250 + - IVTV16 104d:813d + + * - 1 + - Hauppauge WinTV PVR-350 + - IVTV16 104d:813d + + * - 2 + - Hauppauge WinTV PVR-150 + - IVTV16 104d:813d + + * - 3 + - AVerMedia M179 + - IVTV15 1461:a3cf, IVTV15 1461:a3ce + + * - 4 + - Yuan MPG600, Kuroutoshikou ITVC16-STVLP + - IVTV16 12ab:fff3, IVTV16 12ab:ffff + + * - 5 + - YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI + - IVTV15 10fc:40a0 + + * - 6 + - Yuan PG600, Diamond PVR-550 + - IVTV16 ff92:0070, IVTV16 ffab:0600 + + * - 7 + - Adaptec VideOh! AVC-2410 + - IVTV16 9005:0093 + + * - 8 + - Adaptec VideOh! AVC-2010 + - IVTV16 9005:0092 + + * - 9 + - Nagase Transgear 5000TV + - IVTV16 1461:bfff + + * - 10 + - AOpen VA2000MAX-SNT6 + - IVTV16 0000:ff5f + + * - 11 + - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP + - IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523 + + * - 12 + - I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) + - IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039 + + * - 13 + - I/O Data GV-MVP/RX2E + - IVTV16 10fc:d025 + + * - 14 + - GotView PCI DVD + - IVTV16 12ab:0600 + + * - 15 + - GotView PCI DVD2 Deluxe + - IVTV16 ffac:0600 + + * - 16 + - Yuan MPC622 + - IVTV16 ff01:d998 + + * - 17 + - Digital Cowboy DCT-MTVP1 + - IVTV16 1461:bfff + + * - 18 + - Yuan PG600-2, GotView PCI DVD Lite + - IVTV16 ffab:0600, IVTV16 ffad:0600 + + * - 19 + - Club3D ZAP-TV1x01 + - IVTV16 ffab:0600 + + * - 20 + - AVerTV MCE 116 Plus + - IVTV16 1461:c439 + + * - 21 + - ASUS Falcon2 + - IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e + + * - 22 + - AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner + - IVTV16 1461:c034, IVTV16 1461:c035 + + * - 23 + - AVerMedia EZMaker PCI Deluxe + - IVTV16 1461:c03f + + * - 24 + - AVerMedia M104 + - IVTV16 1461:c136 + + * - 25 + - Buffalo PC-MV5L/PCI + - IVTV16 1154:052b + + * - 26 + - AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner + - IVTV16 1461:c019, IVTV16 1461:c01b + + * - 27 + - Sony VAIO Giga Pocket (ENX Kikyou) + - IVTV16 104d:813d + + * - 28 + - Hauppauge WinTV PVR-350 (V1) + - IVTV16 104d:813d + + * - 29 + - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR) + - IVTV16 104d:813d + + * - 30 + - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS) + - IVTV16 104d:813d diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst new file mode 100644 index 0000000000000000000000000000000000000000..9e66b7b5770ff556a364bdf5129217a51e27baad --- /dev/null +++ b/Documentation/media/v4l-drivers/qcom_camss.rst @@ -0,0 +1,156 @@ +.. include:: + +Qualcomm Camera Subsystem driver +================================ + +Introduction +------------ + +This file documents the Qualcomm Camera Subsystem driver located under +drivers/media/platform/qcom/camss-8x16. + +The current version of the driver supports the Camera Subsystem found on +Qualcomm MSM8916 and APQ8016 processors. + +The driver implements V4L2, Media controller and V4L2 subdev interfaces. +Camera sensor using V4L2 subdev interface in the kernel is supported. + +The driver is implemented using as a reference the Qualcomm Camera Subsystem +driver for Android as found in Code Aurora [#f1]_. + + +Qualcomm Camera Subsystem hardware +---------------------------------- + +The Camera Subsystem hardware found on 8x16 processors and supported by the +driver consists of: + +- 2 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. + A separate camera sensor can be connected to each of the CSIPHY module; +- 2 CSID (CSI Decoder) modules. They handle the Protocol and Application layer + of the CSI2 receivers. A CSID can decode data stream from any of the CSIPHY. + Each CSID also contains a TG (Test Generator) block which can generate + artificial input data for test purposes; +- ISPIF (ISP Interface) module. Handles the routing of the data streams from + the CSIDs to the inputs of the VFE; +- VFE (Video Front End) module. Contains a pipeline of image processing hardware + blocks. The VFE has different input interfaces. The PIX (Pixel) input + interface feeds the input data to the image processing pipeline. The image + processing pipeline contains also a scale and crop module at the end. Three + RDI (Raw Dump Interface) input interfaces bypass the image processing + pipeline. The VFE also contains the AXI bus interface which writes the output + data to memory. + + +Supported functionality +----------------------- + +The current version of the driver supports: + +- Input from camera sensor via CSIPHY; +- Generation of test input data by the TG in CSID; +- RDI interface of VFE - raw dump of the input data to memory. + + Supported formats: + + - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / + V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY); + - MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 / + V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8); + - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / + V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P); + - MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P / + V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P). + +- PIX interface of VFE + + - Format conversion of the input data. + + Supported input formats: + + - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / + V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY). + + Supported output formats: + + - NV12/NV21 (two plane YUV 4:2:0 - V4L2_PIX_FMT_NV12 / V4L2_PIX_FMT_NV21); + - NV16/NV61 (two plane YUV 4:2:2 - V4L2_PIX_FMT_NV16 / V4L2_PIX_FMT_NV61). + + - Scaling support. Configuration of the VFE Encoder Scale module + for downscalling with ratio up to 16x. + + - Cropping support. Configuration of the VFE Encoder Crop module. + +- Concurrent and independent usage of two data inputs - could be camera sensors + and/or TG. + + +Driver Architecture and Design +------------------------------ + +The driver implements the V4L2 subdev interface. With the goal to model the +hardware links between the modules and to expose a clean, logical and usable +interface, the driver is split into V4L2 sub-devices as follows: + +- 2 CSIPHY sub-devices - each CSIPHY is represented by a single sub-device; +- 2 CSID sub-devices - each CSID is represented by a single sub-device; +- 2 ISPIF sub-devices - ISPIF is represented by a number of sub-devices equal + to the number of CSID sub-devices; +- 4 VFE sub-devices - VFE is represented by a number of sub-devices equal to + the number of the input interfaces (3 RDI and 1 PIX). + +The considerations to split the driver in this particular way are as follows: + +- representing CSIPHY and CSID modules by a separate sub-device for each module + allows to model the hardware links between these modules; +- representing VFE by a separate sub-devices for each input interface allows + to use the input interfaces concurently and independently as this is + supported by the hardware; +- representing ISPIF by a number of sub-devices equal to the number of CSID + sub-devices allows to create linear media controller pipelines when using two + cameras simultaneously. This avoids branches in the pipelines which otherwise + will require a) userspace and b) media framework (e.g. power on/off + operations) to make assumptions about the data flow from a sink pad to a + source pad on a single media entity. + +Each VFE sub-device is linked to a separate video device node. + +The media controller pipeline graph is as follows (with connected two OV5645 +camera sensors): + +.. _qcom_camss_graph: + +.. kernel-figure:: qcom_camss_graph.dot + :alt: qcom_camss_graph.dot + :align: center + + Media pipeline graph + + +Implementation +-------------- + +Runtime configuration of the hardware (updating settings while streaming) is +not required to implement the currently supported functionality. The complete +configuration on each hardware module is applied on STREAMON ioctl based on +the current active media links, formats and controls set. + +The output size of the scaler module in the VFE is configured with the actual +compose selection rectangle on the sink pad of the 'msm_vfe0_pix' entity. + +The crop output area of the crop module in the VFE is configured with the actual +crop selection rectangle on the source pad of the 'msm_vfe0_pix' entity. + + +Documentation +------------- + +APQ8016 Specification: +https://developer.qualcomm.com/download/sd410/snapdragon-410-processor-device-specification.pdf +Referenced 2016-11-24. + + +References +---------- + +.. [#f1] https://source.codeaurora.org/quic/la/kernel/msm-3.10/ diff --git a/Documentation/media/v4l-drivers/qcom_camss_graph.dot b/Documentation/media/v4l-drivers/qcom_camss_graph.dot new file mode 100644 index 0000000000000000000000000000000000000000..827fc7112c1eeb0f69280c8e7ac99f9f65118a9e --- /dev/null +++ b/Documentation/media/v4l-drivers/qcom_camss_graph.dot @@ -0,0 +1,41 @@ +digraph board { + rankdir=TB + n00000001 [label="{{ 0} | msm_csiphy0\n/dev/v4l-subdev0 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000001:port1 -> n00000007:port0 [style=dashed] + n00000001:port1 -> n0000000a:port0 [style=dashed] + n00000004 [label="{{ 0} | msm_csiphy1\n/dev/v4l-subdev1 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000004:port1 -> n00000007:port0 [style=dashed] + n00000004:port1 -> n0000000a:port0 [style=dashed] + n00000007 [label="{{ 0} | msm_csid0\n/dev/v4l-subdev2 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000007:port1 -> n0000000d:port0 [style=dashed] + n00000007:port1 -> n00000010:port0 [style=dashed] + n0000000a [label="{{ 0} | msm_csid1\n/dev/v4l-subdev3 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000000a:port1 -> n0000000d:port0 [style=dashed] + n0000000a:port1 -> n00000010:port0 [style=dashed] + n0000000d [label="{{ 0} | msm_ispif0\n/dev/v4l-subdev4 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000000d:port1 -> n00000013:port0 [style=dashed] + n0000000d:port1 -> n0000001c:port0 [style=dashed] + n0000000d:port1 -> n00000025:port0 [style=dashed] + n0000000d:port1 -> n0000002e:port0 [style=dashed] + n00000010 [label="{{ 0} | msm_ispif1\n/dev/v4l-subdev5 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000010:port1 -> n00000013:port0 [style=dashed] + n00000010:port1 -> n0000001c:port0 [style=dashed] + n00000010:port1 -> n00000025:port0 [style=dashed] + n00000010:port1 -> n0000002e:port0 [style=dashed] + n00000013 [label="{{ 0} | msm_vfe0_rdi0\n/dev/v4l-subdev6 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000013:port1 -> n00000016 [style=bold] + n00000016 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow] + n0000001c [label="{{ 0} | msm_vfe0_rdi1\n/dev/v4l-subdev7 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000001c:port1 -> n0000001f [style=bold] + n0000001f [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow] + n00000025 [label="{{ 0} | msm_vfe0_rdi2\n/dev/v4l-subdev8 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000025:port1 -> n00000028 [style=bold] + n00000028 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow] + n0000002e [label="{{ 0} | msm_vfe0_pix\n/dev/v4l-subdev9 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000002e:port1 -> n00000031 [style=bold] + n00000031 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow] + n00000057 [label="{{} | ov5645 1-0076\n/dev/v4l-subdev10 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000057:port0 -> n00000001:port0 [style=bold] + n00000059 [label="{{} | ov5645 1-0074\n/dev/v4l-subdev11 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000059:port0 -> n00000004:port0 [style=bold] +} diff --git a/Documentation/media/v4l-drivers/saa7134-cardlist.rst b/Documentation/media/v4l-drivers/saa7134-cardlist.rst index a5efa8f4b8e46869fc937ab9847cb5afee08b11c..6e4c35cbaabf11d267dc7d1a15cba10e7bc934d3 100644 --- a/Documentation/media/v4l-drivers/saa7134-cardlist.rst +++ b/Documentation/media/v4l-drivers/saa7134-cardlist.rst @@ -1,204 +1,801 @@ SAA7134 cards list ================== -=========== ======================================================= ================================================================ -Card number Card name PCI IDs -=========== ======================================================= ================================================================ -0 UNKNOWN/GENERIC -1 Proteus Pro [philips reference design] 1131:2001, 1131:2001 -2 LifeView FlyVIDEO3000 5168:0138, 4e42:0138 -3 LifeView/Typhoon FlyVIDEO2000 5168:0138, 4e42:0138 -4 EMPRESS 1131:6752 -5 SKNet Monster TV 1131:4e85 -6 Tevion MD 9717 -7 KNC One TV-Station RDS / Typhoon TV Tuner RDS 1131:fe01, 1894:fe01 -8 Terratec Cinergy 400 TV 153b:1142 -9 Medion 5044 -10 Kworld/KuroutoShikou SAA7130-TVPCI -11 Terratec Cinergy 600 TV 153b:1143 -12 Medion 7134 16be:0003, 16be:5000 -13 Typhoon TV+Radio 90031 -14 ELSA EX-VISION 300TV 1048:226b -15 ELSA EX-VISION 500TV 1048:226a -16 ASUS TV-FM 7134 1043:4842, 1043:4830, 1043:4840 -17 AOPEN VA1000 POWER 1131:7133 -18 BMK MPEX No Tuner -19 Compro VideoMate TV 185b:c100 -20 Matrox CronosPlus 102B:48d0 -21 10MOONS PCI TV CAPTURE CARD 1131:2001 -22 AverMedia M156 / Medion 2819 1461:a70b -23 BMK MPEX Tuner -24 KNC One TV-Station DVR 1894:a006 -25 ASUS TV-FM 7133 1043:4843 -26 Pinnacle PCTV Stereo (saa7134) 11bd:002b -27 Manli MuchTV M-TV002 -28 Manli MuchTV M-TV001 -29 Nagase Sangyo TransGear 3000TV 1461:050c -30 Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) 1019:4cb4 -31 Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) 1019:4cb5 -32 AVACS SmartTV -33 AVerMedia DVD EZMaker 1461:10ff -34 Noval Prime TV 7133 -35 AverMedia AverTV Studio 305 1461:2115 -36 UPMOST PURPLE TV 12ab:0800 -37 Items MuchTV Plus / IT-005 -38 Terratec Cinergy 200 TV 153b:1152 -39 LifeView FlyTV Platinum Mini 5168:0212, 4e42:0212, 5169:1502 -40 Compro VideoMate TV PVR/FM 185b:c100 -41 Compro VideoMate TV Gold+ 185b:c100 -42 Sabrent SBT-TVFM (saa7130) -43 :Zolid Xpert TV7134 -44 Empire PCI TV-Radio LE -45 Avermedia AVerTV Studio 307 1461:9715 -46 AVerMedia Cardbus TV/Radio (E500) 1461:d6ee -47 Terratec Cinergy 400 mobile 153b:1162 -48 Terratec Cinergy 600 TV MK3 153b:1158 -49 Compro VideoMate Gold+ Pal 185b:c200 -50 Pinnacle PCTV 300i DVB-T + PAL 11bd:002d -51 ProVideo PV952 1540:9524 -52 AverMedia AverTV/305 1461:2108 -53 ASUS TV-FM 7135 1043:4845 -54 LifeView FlyTV Platinum FM / Gold 5168:0214, 5168:5214, 1489:0214, 5168:0304 -55 LifeView FlyDVB-T DUO / MSI TV@nywhere Duo 5168:0306, 4E42:0306 -56 Avermedia AVerTV 307 1461:a70a -57 Avermedia AVerTV GO 007 FM 1461:f31f -58 ADS Tech Instant TV (saa7135) 1421:0350, 1421:0351, 1421:0370, 1421:1370 -59 Kworld/Tevion V-Stream Xpert TV PVR7134 -60 LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus 5168:0502, 4e42:0502, 1489:0502 -61 Philips TOUGH DVB-T reference design 1131:2004 -62 Compro VideoMate TV Gold+II -63 Kworld Xpert TV PVR7134 -64 FlyTV mini Asus Digimatrix 1043:0210 -65 V-Stream Studio TV Terminator -66 Yuan TUN-900 (saa7135) -67 Beholder BeholdTV 409 FM 0000:4091 -68 GoTView 7135 PCI 5456:7135 -69 Philips EUROPA V3 reference design 1131:2004 -70 Compro Videomate DVB-T300 185b:c900 -71 Compro Videomate DVB-T200 185b:c901 -72 RTD Embedded Technologies VFG7350 1435:7350 -73 RTD Embedded Technologies VFG7330 1435:7330 -74 LifeView FlyTV Platinum Mini2 14c0:1212 -75 AVerMedia AVerTVHD MCE A180 1461:1044 -76 SKNet MonsterTV Mobile 1131:4ee9 -77 Pinnacle PCTV 40i/50i/110i (saa7133) 11bd:002e -78 ASUSTeK P7131 Dual 1043:4862 -79 Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) -80 ASUS Digimatrix TV 1043:0210 -81 Philips Tiger reference design 1131:2018 -82 MSI TV@Anywhere plus 1462:6231, 1462:8624 -83 Terratec Cinergy 250 PCI TV 153b:1160 -84 LifeView FlyDVB Trio 5168:0319 -85 AverTV DVB-T 777 1461:2c05, 1461:2c05 -86 LifeView FlyDVB-T / Genius VideoWonder DVB-T 5168:0301, 1489:0301 -87 ADS Instant TV Duo Cardbus PTV331 0331:1421 -88 Tevion/KWorld DVB-T 220RF 17de:7201 -89 ELSA EX-VISION 700TV 1048:226c -90 Kworld ATSC110/115 17de:7350, 17de:7352 -91 AVerMedia A169 B 1461:7360 -92 AVerMedia A169 B1 1461:6360 -93 Medion 7134 Bridge #2 16be:0005 -94 LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB 5168:3306, 5168:3502, 5168:3307, 4e42:3502 -95 LifeView FlyVIDEO3000 (NTSC) 5169:0138 -96 Medion Md8800 Quadro 16be:0007, 16be:0008, 16be:000d -97 LifeView FlyDVB-S /Acorp TV134DS 5168:0300, 4e42:0300 -98 Proteus Pro 2309 0919:2003 -99 AVerMedia TV Hybrid A16AR 1461:2c00 -100 Asus Europa2 OEM 1043:4860 -101 Pinnacle PCTV 310i 11bd:002f -102 Avermedia AVerTV Studio 507 1461:9715 -103 Compro Videomate DVB-T200A -104 Hauppauge WinTV-HVR1110 DVB-T/Hybrid 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705 -105 Terratec Cinergy HT PCMCIA 153b:1172 -106 Encore ENLTV 1131:2342, 1131:2341, 3016:2344 -107 Encore ENLTV-FM 1131:230f -108 Terratec Cinergy HT PCI 153b:1175 -109 Philips Tiger - S Reference design -110 Avermedia M102 1461:f31e -111 ASUS P7131 4871 1043:4871 -112 ASUSTeK P7131 Hybrid 1043:4876 -113 Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) 1019:4cb6 -114 KWorld DVB-T 210 17de:7250 -115 Sabrent PCMCIA TV-PCB05 0919:2003 -116 10MOONS TM300 TV Card 1131:2304 -117 Avermedia Super 007 1461:f01d -118 Beholder BeholdTV 401 0000:4016 -119 Beholder BeholdTV 403 0000:4036 -120 Beholder BeholdTV 403 FM 0000:4037 -121 Beholder BeholdTV 405 0000:4050 -122 Beholder BeholdTV 405 FM 0000:4051 -123 Beholder BeholdTV 407 0000:4070 -124 Beholder BeholdTV 407 FM 0000:4071 -125 Beholder BeholdTV 409 0000:4090 -126 Beholder BeholdTV 505 FM 5ace:5050 -127 Beholder BeholdTV 507 FM / BeholdTV 509 FM 5ace:5070, 5ace:5090 -128 Beholder BeholdTV Columbus TV/FM 0000:5201 -129 Beholder BeholdTV 607 FM 5ace:6070 -130 Beholder BeholdTV M6 5ace:6190 -131 Twinhan Hybrid DTV-DVB 3056 PCI 1822:0022 -132 Genius TVGO AM11MCE -133 NXP Snake DVB-S reference design -134 Medion/Creatix CTX953 Hybrid 16be:0010 -135 MSI TV@nywhere A/D v1.1 1462:8625 -136 AVerMedia Cardbus TV/Radio (E506R) 1461:f436 -137 AVerMedia Hybrid TV/Radio (A16D) 1461:f936 -138 Avermedia M115 1461:a836 -139 Compro VideoMate T750 185b:c900 -140 Avermedia DVB-S Pro A700 1461:a7a1 -141 Avermedia DVB-S Hybrid+FM A700 1461:a7a2 -142 Beholder BeholdTV H6 5ace:6290 -143 Beholder BeholdTV M63 5ace:6191 -144 Beholder BeholdTV M6 Extra 5ace:6193 -145 AVerMedia MiniPCI DVB-T Hybrid M103 1461:f636, 1461:f736 -146 ASUSTeK P7131 Analog -147 Asus Tiger 3in1 1043:4878 -148 Encore ENLTV-FM v5.3 1a7f:2008 -149 Avermedia PCI pure analog (M135A) 1461:f11d -150 Zogis Real Angel 220 -151 ADS Tech Instant HDTV 1421:0380 -152 Asus Tiger Rev:1.00 1043:4857 -153 Kworld Plus TV Analog Lite PCI 17de:7128 -154 Avermedia AVerTV GO 007 FM Plus 1461:f31d -155 Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid 0070:6706, 0070:6708 -156 Hauppauge WinTV-HVR1120 DVB-T/Hybrid 0070:6707, 0070:6709, 0070:670a -157 Avermedia AVerTV Studio 507UA 1461:a11b -158 AVerMedia Cardbus TV/Radio (E501R) 1461:b7e9 -159 Beholder BeholdTV 505 RDS 0000:505B -160 Beholder BeholdTV 507 RDS 0000:5071 -161 Beholder BeholdTV 507 RDS 0000:507B -162 Beholder BeholdTV 607 FM 5ace:6071 -163 Beholder BeholdTV 609 FM 5ace:6090 -164 Beholder BeholdTV 609 FM 5ace:6091 -165 Beholder BeholdTV 607 RDS 5ace:6072 -166 Beholder BeholdTV 607 RDS 5ace:6073 -167 Beholder BeholdTV 609 RDS 5ace:6092 -168 Beholder BeholdTV 609 RDS 5ace:6093 -169 Compro VideoMate S350/S300 185b:c900 -170 AverMedia AverTV Studio 505 1461:a115 -171 Beholder BeholdTV X7 5ace:7595 -172 RoverMedia TV Link Pro FM 19d1:0138 -173 Zolid Hybrid TV Tuner PCI 1131:2004 -174 Asus Europa Hybrid OEM 1043:4847 -175 Leadtek Winfast DTV1000S 107d:6655 -176 Beholder BeholdTV 505 RDS 0000:5051 -177 Hawell HW-404M7 -178 Beholder BeholdTV H7 5ace:7190 -179 Beholder BeholdTV A7 5ace:7090 -180 Avermedia PCI M733A 1461:4155, 1461:4255 -181 TechoTrend TT-budget T-3000 13c2:2804 -182 Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid 17de:b136 -183 Compro VideoMate Vista M1F 185b:c900 -184 Encore ENLTV-FM 3 1a7f:2108 -185 MagicPro ProHDTV Pro2 DMB-TH/Hybrid 17de:d136 -186 Beholder BeholdTV 501 5ace:5010 -187 Beholder BeholdTV 503 FM 5ace:5030 -188 Sensoray 811/911 6000:0811, 6000:0911 -189 Kworld PC150-U 17de:a134 -190 Asus My Cinema PS3-100 1043:48cd -191 Hawell HW-9004V1 -192 AverMedia AverTV Satellite Hybrid+FM A706 1461:2055 -193 WIS Voyager or compatible 1905:7007 -194 AverMedia AverTV/505 1461:a10a -195 Leadtek Winfast TV2100 FM 107d:6f3a -196 SnaZio* TVPVR PRO 1779:13cf -=========== ======================================================= ================================================================ +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - UNKNOWN/GENERIC + - + + * - 1 + - Proteus Pro [philips reference design] + - 1131:2001, 1131:2001 + + * - 2 + - LifeView FlyVIDEO3000 + - 5168:0138, 4e42:0138 + + * - 3 + - LifeView/Typhoon FlyVIDEO2000 + - 5168:0138, 4e42:0138 + + * - 4 + - EMPRESS + - 1131:6752 + + * - 5 + - SKNet Monster TV + - 1131:4e85 + + * - 6 + - Tevion MD 9717 + - + + * - 7 + - KNC One TV-Station RDS / Typhoon TV Tuner RDS + - 1131:fe01, 1894:fe01 + + * - 8 + - Terratec Cinergy 400 TV + - 153b:1142 + + * - 9 + - Medion 5044 + - + + * - 10 + - Kworld/KuroutoShikou SAA7130-TVPCI + - + + * - 11 + - Terratec Cinergy 600 TV + - 153b:1143 + + * - 12 + - Medion 7134 + - 16be:0003, 16be:5000 + + * - 13 + - Typhoon TV+Radio 90031 + - + + * - 14 + - ELSA EX-VISION 300TV + - 1048:226b + + * - 15 + - ELSA EX-VISION 500TV + - 1048:226a + + * - 16 + - ASUS TV-FM 7134 + - 1043:4842, 1043:4830, 1043:4840 + + * - 17 + - AOPEN VA1000 POWER + - 1131:7133 + + * - 18 + - BMK MPEX No Tuner + - + + * - 19 + - Compro VideoMate TV + - 185b:c100 + + * - 20 + - Matrox CronosPlus + - 102B:48d0 + + * - 21 + - 10MOONS PCI TV CAPTURE CARD + - 1131:2001 + + * - 22 + - AverMedia M156 / Medion 2819 + - 1461:a70b + + * - 23 + - BMK MPEX Tuner + - + + * - 24 + - KNC One TV-Station DVR + - 1894:a006 + + * - 25 + - ASUS TV-FM 7133 + - 1043:4843 + + * - 26 + - Pinnacle PCTV Stereo (saa7134) + - 11bd:002b + + * - 27 + - Manli MuchTV M-TV002 + - + + * - 28 + - Manli MuchTV M-TV001 + - + + * - 29 + - Nagase Sangyo TransGear 3000TV + - 1461:050c + + * - 30 + - Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) + - 1019:4cb4 + + * - 31 + - Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) + - 1019:4cb5 + + * - 32 + - AVACS SmartTV + - + + * - 33 + - AVerMedia DVD EZMaker + - 1461:10ff + + * - 34 + - Noval Prime TV 7133 + - + + * - 35 + - AverMedia AverTV Studio 305 + - 1461:2115 + + * - 36 + - UPMOST PURPLE TV + - 12ab:0800 + + * - 37 + - Items MuchTV Plus / IT-005 + - + + * - 38 + - Terratec Cinergy 200 TV + - 153b:1152 + + * - 39 + - LifeView FlyTV Platinum Mini + - 5168:0212, 4e42:0212, 5169:1502 + + * - 40 + - Compro VideoMate TV PVR/FM + - 185b:c100 + + * - 41 + - Compro VideoMate TV Gold+ + - 185b:c100 + + * - 42 + - Sabrent SBT-TVFM (saa7130) + - + + * - 43 + - :Zolid Xpert TV7134 + - + + * - 44 + - Empire PCI TV-Radio LE + - + + * - 45 + - Avermedia AVerTV Studio 307 + - 1461:9715 + + * - 46 + - AVerMedia Cardbus TV/Radio (E500) + - 1461:d6ee + + * - 47 + - Terratec Cinergy 400 mobile + - 153b:1162 + + * - 48 + - Terratec Cinergy 600 TV MK3 + - 153b:1158 + + * - 49 + - Compro VideoMate Gold+ Pal + - 185b:c200 + + * - 50 + - Pinnacle PCTV 300i DVB-T + PAL + - 11bd:002d + + * - 51 + - ProVideo PV952 + - 1540:9524 + + * - 52 + - AverMedia AverTV/305 + - 1461:2108 + + * - 53 + - ASUS TV-FM 7135 + - 1043:4845 + + * - 54 + - LifeView FlyTV Platinum FM / Gold + - 5168:0214, 5168:5214, 1489:0214, 5168:0304 + + * - 55 + - LifeView FlyDVB-T DUO / MSI TV@nywhere Duo + - 5168:0306, 4E42:0306 + + * - 56 + - Avermedia AVerTV 307 + - 1461:a70a + + * - 57 + - Avermedia AVerTV GO 007 FM + - 1461:f31f + + * - 58 + - ADS Tech Instant TV (saa7135) + - 1421:0350, 1421:0351, 1421:0370, 1421:1370 + + * - 59 + - Kworld/Tevion V-Stream Xpert TV PVR7134 + - + + * - 60 + - LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus + - 5168:0502, 4e42:0502, 1489:0502 + + * - 61 + - Philips TOUGH DVB-T reference design + - 1131:2004 + + * - 62 + - Compro VideoMate TV Gold+II + - + + * - 63 + - Kworld Xpert TV PVR7134 + - + + * - 64 + - FlyTV mini Asus Digimatrix + - 1043:0210 + + * - 65 + - V-Stream Studio TV Terminator + - + + * - 66 + - Yuan TUN-900 (saa7135) + - + + * - 67 + - Beholder BeholdTV 409 FM + - 0000:4091 + + * - 68 + - GoTView 7135 PCI + - 5456:7135 + + * - 69 + - Philips EUROPA V3 reference design + - 1131:2004 + + * - 70 + - Compro Videomate DVB-T300 + - 185b:c900 + + * - 71 + - Compro Videomate DVB-T200 + - 185b:c901 + + * - 72 + - RTD Embedded Technologies VFG7350 + - 1435:7350 + + * - 73 + - RTD Embedded Technologies VFG7330 + - 1435:7330 + + * - 74 + - LifeView FlyTV Platinum Mini2 + - 14c0:1212 + + * - 75 + - AVerMedia AVerTVHD MCE A180 + - 1461:1044 + + * - 76 + - SKNet MonsterTV Mobile + - 1131:4ee9 + + * - 77 + - Pinnacle PCTV 40i/50i/110i (saa7133) + - 11bd:002e + + * - 78 + - ASUSTeK P7131 Dual + - 1043:4862 + + * - 79 + - Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) + - + + * - 80 + - ASUS Digimatrix TV + - 1043:0210 + + * - 81 + - Philips Tiger reference design + - 1131:2018 + + * - 82 + - MSI TV@Anywhere plus + - 1462:6231, 1462:8624 + + * - 83 + - Terratec Cinergy 250 PCI TV + - 153b:1160 + + * - 84 + - LifeView FlyDVB Trio + - 5168:0319 + + * - 85 + - AverTV DVB-T 777 + - 1461:2c05, 1461:2c05 + + * - 86 + - LifeView FlyDVB-T / Genius VideoWonder DVB-T + - 5168:0301, 1489:0301 + + * - 87 + - ADS Instant TV Duo Cardbus PTV331 + - 0331:1421 + + * - 88 + - Tevion/KWorld DVB-T 220RF + - 17de:7201 + + * - 89 + - ELSA EX-VISION 700TV + - 1048:226c + + * - 90 + - Kworld ATSC110/115 + - 17de:7350, 17de:7352 + + * - 91 + - AVerMedia A169 B + - 1461:7360 + + * - 92 + - AVerMedia A169 B1 + - 1461:6360 + + * - 93 + - Medion 7134 Bridge #2 + - 16be:0005 + + * - 94 + - LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB + - 5168:3306, 5168:3502, 5168:3307, 4e42:3502 + + * - 95 + - LifeView FlyVIDEO3000 (NTSC) + - 5169:0138 + + * - 96 + - Medion Md8800 Quadro + - 16be:0007, 16be:0008, 16be:000d + + * - 97 + - LifeView FlyDVB-S /Acorp TV134DS + - 5168:0300, 4e42:0300 + + * - 98 + - Proteus Pro 2309 + - 0919:2003 + + * - 99 + - AVerMedia TV Hybrid A16AR + - 1461:2c00 + + * - 100 + - Asus Europa2 OEM + - 1043:4860 + + * - 101 + - Pinnacle PCTV 310i + - 11bd:002f + + * - 102 + - Avermedia AVerTV Studio 507 + - 1461:9715 + + * - 103 + - Compro Videomate DVB-T200A + - + + * - 104 + - Hauppauge WinTV-HVR1110 DVB-T/Hybrid + - 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705 + + * - 105 + - Terratec Cinergy HT PCMCIA + - 153b:1172 + + * - 106 + - Encore ENLTV + - 1131:2342, 1131:2341, 3016:2344 + + * - 107 + - Encore ENLTV-FM + - 1131:230f + + * - 108 + - Terratec Cinergy HT PCI + - 153b:1175 + + * - 109 + - Philips Tiger - S Reference design + - + + * - 110 + - Avermedia M102 + - 1461:f31e + + * - 111 + - ASUS P7131 4871 + - 1043:4871 + + * - 112 + - ASUSTeK P7131 Hybrid + - 1043:4876 + + * - 113 + - Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) + - 1019:4cb6 + + * - 114 + - KWorld DVB-T 210 + - 17de:7250 + + * - 115 + - Sabrent PCMCIA TV-PCB05 + - 0919:2003 + + * - 116 + - 10MOONS TM300 TV Card + - 1131:2304 + + * - 117 + - Avermedia Super 007 + - 1461:f01d + + * - 118 + - Beholder BeholdTV 401 + - 0000:4016 + + * - 119 + - Beholder BeholdTV 403 + - 0000:4036 + + * - 120 + - Beholder BeholdTV 403 FM + - 0000:4037 + + * - 121 + - Beholder BeholdTV 405 + - 0000:4050 + + * - 122 + - Beholder BeholdTV 405 FM + - 0000:4051 + + * - 123 + - Beholder BeholdTV 407 + - 0000:4070 + + * - 124 + - Beholder BeholdTV 407 FM + - 0000:4071 + + * - 125 + - Beholder BeholdTV 409 + - 0000:4090 + + * - 126 + - Beholder BeholdTV 505 FM + - 5ace:5050 + + * - 127 + - Beholder BeholdTV 507 FM / BeholdTV 509 FM + - 5ace:5070, 5ace:5090 + + * - 128 + - Beholder BeholdTV Columbus TV/FM + - 0000:5201 + + * - 129 + - Beholder BeholdTV 607 FM + - 5ace:6070 + + * - 130 + - Beholder BeholdTV M6 + - 5ace:6190 + + * - 131 + - Twinhan Hybrid DTV-DVB 3056 PCI + - 1822:0022 + + * - 132 + - Genius TVGO AM11MCE + - + + * - 133 + - NXP Snake DVB-S reference design + - + + * - 134 + - Medion/Creatix CTX953 Hybrid + - 16be:0010 + + * - 135 + - MSI TV@nywhere A/D v1.1 + - 1462:8625 + + * - 136 + - AVerMedia Cardbus TV/Radio (E506R) + - 1461:f436 + + * - 137 + - AVerMedia Hybrid TV/Radio (A16D) + - 1461:f936 + + * - 138 + - Avermedia M115 + - 1461:a836 + + * - 139 + - Compro VideoMate T750 + - 185b:c900 + + * - 140 + - Avermedia DVB-S Pro A700 + - 1461:a7a1 + + * - 141 + - Avermedia DVB-S Hybrid+FM A700 + - 1461:a7a2 + + * - 142 + - Beholder BeholdTV H6 + - 5ace:6290 + + * - 143 + - Beholder BeholdTV M63 + - 5ace:6191 + + * - 144 + - Beholder BeholdTV M6 Extra + - 5ace:6193 + + * - 145 + - AVerMedia MiniPCI DVB-T Hybrid M103 + - 1461:f636, 1461:f736 + + * - 146 + - ASUSTeK P7131 Analog + - + + * - 147 + - Asus Tiger 3in1 + - 1043:4878 + + * - 148 + - Encore ENLTV-FM v5.3 + - 1a7f:2008 + + * - 149 + - Avermedia PCI pure analog (M135A) + - 1461:f11d + + * - 150 + - Zogis Real Angel 220 + - + + * - 151 + - ADS Tech Instant HDTV + - 1421:0380 + + * - 152 + - Asus Tiger Rev:1.00 + - 1043:4857 + + * - 153 + - Kworld Plus TV Analog Lite PCI + - 17de:7128 + + * - 154 + - Avermedia AVerTV GO 007 FM Plus + - 1461:f31d + + * - 155 + - Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid + - 0070:6706, 0070:6708 + + * - 156 + - Hauppauge WinTV-HVR1120 DVB-T/Hybrid + - 0070:6707, 0070:6709, 0070:670a + + * - 157 + - Avermedia AVerTV Studio 507UA + - 1461:a11b + + * - 158 + - AVerMedia Cardbus TV/Radio (E501R) + - 1461:b7e9 + + * - 159 + - Beholder BeholdTV 505 RDS + - 0000:505B + + * - 160 + - Beholder BeholdTV 507 RDS + - 0000:5071 + + * - 161 + - Beholder BeholdTV 507 RDS + - 0000:507B + + * - 162 + - Beholder BeholdTV 607 FM + - 5ace:6071 + + * - 163 + - Beholder BeholdTV 609 FM + - 5ace:6090 + + * - 164 + - Beholder BeholdTV 609 FM + - 5ace:6091 + + * - 165 + - Beholder BeholdTV 607 RDS + - 5ace:6072 + + * - 166 + - Beholder BeholdTV 607 RDS + - 5ace:6073 + + * - 167 + - Beholder BeholdTV 609 RDS + - 5ace:6092 + + * - 168 + - Beholder BeholdTV 609 RDS + - 5ace:6093 + + * - 169 + - Compro VideoMate S350/S300 + - 185b:c900 + + * - 170 + - AverMedia AverTV Studio 505 + - 1461:a115 + + * - 171 + - Beholder BeholdTV X7 + - 5ace:7595 + + * - 172 + - RoverMedia TV Link Pro FM + - 19d1:0138 + + * - 173 + - Zolid Hybrid TV Tuner PCI + - 1131:2004 + + * - 174 + - Asus Europa Hybrid OEM + - 1043:4847 + + * - 175 + - Leadtek Winfast DTV1000S + - 107d:6655 + + * - 176 + - Beholder BeholdTV 505 RDS + - 0000:5051 + + * - 177 + - Hawell HW-404M7 + - + + * - 178 + - Beholder BeholdTV H7 + - 5ace:7190 + + * - 179 + - Beholder BeholdTV A7 + - 5ace:7090 + + * - 180 + - Avermedia PCI M733A + - 1461:4155, 1461:4255 + + * - 181 + - TechoTrend TT-budget T-3000 + - 13c2:2804 + + * - 182 + - Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid + - 17de:b136 + + * - 183 + - Compro VideoMate Vista M1F + - 185b:c900 + + * - 184 + - Encore ENLTV-FM 3 + - 1a7f:2108 + + * - 185 + - MagicPro ProHDTV Pro2 DMB-TH/Hybrid + - 17de:d136 + + * - 186 + - Beholder BeholdTV 501 + - 5ace:5010 + + * - 187 + - Beholder BeholdTV 503 FM + - 5ace:5030 + + * - 188 + - Sensoray 811/911 + - 6000:0811, 6000:0911 + + * - 189 + - Kworld PC150-U + - 17de:a134 + + * - 190 + - Asus My Cinema PS3-100 + - 1043:48cd + + * - 191 + - Hawell HW-9004V1 + - + + * - 192 + - AverMedia AverTV Satellite Hybrid+FM A706 + - 1461:2055 + + * - 193 + - WIS Voyager or compatible + - 1905:7007 + + * - 194 + - AverMedia AverTV/505 + - 1461:a10a + + * - 195 + - Leadtek Winfast TV2100 FM + - 107d:6f3a + + * - 196 + - SnaZio* TVPVR PRO + - 1779:13cf diff --git a/Documentation/media/v4l-drivers/saa7164-cardlist.rst b/Documentation/media/v4l-drivers/saa7164-cardlist.rst index 7d17d38df3bce3a2911ba62dda7fd543cf2b0df1..e28382ba82e67352ccaad4f5cd6f4492b8fd109e 100644 --- a/Documentation/media/v4l-drivers/saa7164-cardlist.rst +++ b/Documentation/media/v4l-drivers/saa7164-cardlist.rst @@ -1,21 +1,69 @@ SAA7164 cards list ================== -=========== ==================================== ==================== -Card number Card name PCI IDs -=========== ==================================== ==================== -0 Unknown -1 Generic Rev2 -2 Generic Rev3 -3 Hauppauge WinTV-HVR2250 0070:8880, 0070:8810 -4 Hauppauge WinTV-HVR2200 0070:8980 -5 Hauppauge WinTV-HVR2200 0070:8900 -6 Hauppauge WinTV-HVR2200 0070:8901 -7 Hauppauge WinTV-HVR2250 0070:8891, 0070:8851 -8 Hauppauge WinTV-HVR2250 0070:88A1 -9 Hauppauge WinTV-HVR2200 0070:8940 -10 Hauppauge WinTV-HVR2200 0070:8953 -11 Hauppauge WinTV-HVR2255(proto) 0070:f111 -12 Hauppauge WinTV-HVR2255 0070:f111 -13 Hauppauge WinTV-HVR2205 0070:f123, 0070:f120 -=========== ==================================== ==================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - Unknown + - + + * - 1 + - Generic Rev2 + - + + * - 2 + - Generic Rev3 + - + + * - 3 + - Hauppauge WinTV-HVR2250 + - 0070:8880, 0070:8810 + + * - 4 + - Hauppauge WinTV-HVR2200 + - 0070:8980 + + * - 5 + - Hauppauge WinTV-HVR2200 + - 0070:8900 + + * - 6 + - Hauppauge WinTV-HVR2200 + - 0070:8901 + + * - 7 + - Hauppauge WinTV-HVR2250 + - 0070:8891, 0070:8851 + + * - 8 + - Hauppauge WinTV-HVR2250 + - 0070:88A1 + + * - 9 + - Hauppauge WinTV-HVR2200 + - 0070:8940 + + * - 10 + - Hauppauge WinTV-HVR2200 + - 0070:8953 + + * - 11 + - Hauppauge WinTV-HVR2255(proto) + - 0070:f111 + + * - 12 + - Hauppauge WinTV-HVR2255 + - 0070:f111 + + * - 13 + - Hauppauge WinTV-HVR2205 + - 0070:f123, 0070:f120 diff --git a/Documentation/media/v4l-drivers/tm6000-cardlist.rst b/Documentation/media/v4l-drivers/tm6000-cardlist.rst index ae2952683ccf4ca80550431f891199a969224d56..6bd083544457aaf427c91efc91422e93bbee8ee2 100644 --- a/Documentation/media/v4l-drivers/tm6000-cardlist.rst +++ b/Documentation/media/v4l-drivers/tm6000-cardlist.rst @@ -1,24 +1,81 @@ TM6000 cards list ================= -=========== ================================================= ========================================== -Card number Card name USB IDs -=========== ================================================= ========================================== -0 Unknown tm6000 video grabber -1 Generic tm5600 board 6000:0001 -2 Generic tm6000 board -3 Generic tm6010 board 6000:0002 -4 10Moons UT 821 -5 10Moons UT 330 -6 ADSTECH Dual TV USB 06e1:f332 -7 Freecom Hybrid Stick / Moka DVB-T Receiver Dual 14aa:0620 -8 ADSTECH Mini Dual TV USB 06e1:b339 -9 Hauppauge WinTV HVR-900H / WinTV USB2-Stick 2040:6600, 2040:6601, 2040:6610, 2040:6611 -10 Beholder Wander DVB-T/TV/FM USB2.0 6000:dec0 -11 Beholder Voyager TV/FM USB2.0 6000:dec1 -12 Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick 0ccd:0086, 0ccd:00A5 -13 Twinhan TU501(704D1) 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264 -14 Beholder Wander Lite DVB-T/TV/FM USB2.0 6000:dec2 -15 Beholder Voyager Lite TV/FM USB2.0 6000:dec3 -16 Terratec Grabster AV 150/250 MX 0ccd:0079 -=========== ================================================= ========================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - USB IDs + + * - 0 + - Unknown tm6000 video grabber + - + + * - 1 + - Generic tm5600 board + - 6000:0001 + + * - 2 + - Generic tm6000 board + - + + * - 3 + - Generic tm6010 board + - 6000:0002 + + * - 4 + - 10Moons UT 821 + - + + * - 5 + - 10Moons UT 330 + - + + * - 6 + - ADSTECH Dual TV USB + - 06e1:f332 + + * - 7 + - Freecom Hybrid Stick / Moka DVB-T Receiver Dual + - 14aa:0620 + + * - 8 + - ADSTECH Mini Dual TV USB + - 06e1:b339 + + * - 9 + - Hauppauge WinTV HVR-900H / WinTV USB2-Stick + - 2040:6600, 2040:6601, 2040:6610, 2040:6611 + + * - 10 + - Beholder Wander DVB-T/TV/FM USB2.0 + - 6000:dec0 + + * - 11 + - Beholder Voyager TV/FM USB2.0 + - 6000:dec1 + + * - 12 + - Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick + - 0ccd:0086, 0ccd:00A5 + + * - 13 + - Twinhan TU501(704D1) + - 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264 + + * - 14 + - Beholder Wander Lite DVB-T/TV/FM USB2.0 + - 6000:dec2 + + * - 15 + - Beholder Voyager Lite TV/FM USB2.0 + - 6000:dec3 + + * - 16 + - Terratec Grabster AV 150/250 MX + - 0ccd:0079 diff --git a/Documentation/media/v4l-drivers/usbvision-cardlist.rst b/Documentation/media/v4l-drivers/usbvision-cardlist.rst index 44d53dff098472224e70c200e482d6e76fe3ecf0..5a8ffbfc204e18755114208fc6e3eb51ebfcd93c 100644 --- a/Documentation/media/v4l-drivers/usbvision-cardlist.rst +++ b/Documentation/media/v4l-drivers/usbvision-cardlist.rst @@ -1,74 +1,281 @@ USBvision cards list ==================== -=========== ======================================================== ========= -Card number Card name USB IDs -=========== ======================================================== ========= -0 Xanboo 0a6f:0400 -1 Belkin USB VideoBus II Adapter 050d:0106 -2 Belkin Components USB VideoBus 050d:0207 -3 Belkin USB VideoBus II 050d:0208 -4 echoFX InterView Lite 0571:0002 -5 USBGear USBG-V1 resp. HAMA USB 0573:0003 -6 D-Link V100 0573:0400 -7 X10 USB Camera 0573:2000 -8 Hauppauge WinTV USB Live (PAL B/G) 0573:2d00 -9 Hauppauge WinTV USB Live Pro (NTSC M/N) 0573:2d01 -10 Zoran Co. PMD (Nogatech) AV-grabber Manhattan 0573:2101 -11 Nogatech USB-TV (NTSC) FM 0573:4100 -12 PNY USB-TV (NTSC) FM 0573:4110 -13 PixelView PlayTv-USB PRO (PAL) FM 0573:4450 -14 ZTV ZT-721 2.4GHz USB A/V Receiver 0573:4550 -15 Hauppauge WinTV USB (NTSC M/N) 0573:4d00 -16 Hauppauge WinTV USB (PAL B/G) 0573:4d01 -17 Hauppauge WinTV USB (PAL I) 0573:4d02 -18 Hauppauge WinTV USB (PAL/SECAM L) 0573:4d03 -19 Hauppauge WinTV USB (PAL D/K) 0573:4d04 -20 Hauppauge WinTV USB (NTSC FM) 0573:4d10 -21 Hauppauge WinTV USB (PAL B/G FM) 0573:4d11 -22 Hauppauge WinTV USB (PAL I FM) 0573:4d12 -23 Hauppauge WinTV USB (PAL D/K FM) 0573:4d14 -24 Hauppauge WinTV USB Pro (NTSC M/N) 0573:4d2a -25 Hauppauge WinTV USB Pro (NTSC M/N) V2 0573:4d2b -26 Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) 0573:4d2c -27 Hauppauge WinTV USB Pro (NTSC M/N) V3 0573:4d20 -28 Hauppauge WinTV USB Pro (PAL B/G) 0573:4d21 -29 Hauppauge WinTV USB Pro (PAL I) 0573:4d22 -30 Hauppauge WinTV USB Pro (PAL/SECAM L) 0573:4d23 -31 Hauppauge WinTV USB Pro (PAL D/K) 0573:4d24 -32 Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) 0573:4d25 -33 Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 0573:4d26 -34 Hauppauge WinTV USB Pro (PAL B/G) V2 0573:4d27 -35 Hauppauge WinTV USB Pro (PAL B/G,D/K) 0573:4d28 -36 Hauppauge WinTV USB Pro (PAL I,D/K) 0573:4d29 -37 Hauppauge WinTV USB Pro (NTSC M/N FM) 0573:4d30 -38 Hauppauge WinTV USB Pro (PAL B/G FM) 0573:4d31 -39 Hauppauge WinTV USB Pro (PAL I FM) 0573:4d32 -40 Hauppauge WinTV USB Pro (PAL D/K FM) 0573:4d34 -41 Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) 0573:4d35 -42 Hauppauge WinTV USB Pro (Temic PAL B/G FM) 0573:4d36 -43 Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) 0573:4d37 -44 Hauppauge WinTV USB Pro (NTSC M/N FM) V2 0573:4d38 -45 Camtel Technology USB TV Genie Pro FM Model TVB330 0768:0006 -46 Digital Video Creator I 07d0:0001 -47 Global Village GV-007 (NTSC) 07d0:0002 -48 Dazzle Fusion Model DVC-50 Rev 1 (NTSC) 07d0:0003 -49 Dazzle Fusion Model DVC-80 Rev 1 (PAL) 07d0:0004 -50 Dazzle Fusion Model DVC-90 Rev 1 (SECAM) 07d0:0005 -51 Eskape Labs MyTV2Go 07f8:9104 -52 Pinnacle Studio PCTV USB (PAL) 2304:010d -53 Pinnacle Studio PCTV USB (SECAM) 2304:0109 -54 Pinnacle Studio PCTV USB (PAL) FM 2304:0110 -55 Miro PCTV USB 2304:0111 -56 Pinnacle Studio PCTV USB (NTSC) FM 2304:0112 -57 Pinnacle Studio PCTV USB (PAL) FM V2 2304:0210 -58 Pinnacle Studio PCTV USB (NTSC) FM V2 2304:0212 -59 Pinnacle Studio PCTV USB (PAL) FM V3 2304:0214 -60 Pinnacle Studio Linx Video input cable (NTSC) 2304:0300 -61 Pinnacle Studio Linx Video input cable (PAL) 2304:0301 -62 Pinnacle PCTV Bungee USB (PAL) FM 2304:0419 -63 Hauppauge WinTv-USB 2400:4200 -64 Pinnacle Studio PCTV USB (NTSC) FM V3 2304:0113 -65 Nogatech USB MicroCam NTSC (NV3000N) 0573:3000 -66 Nogatech USB MicroCam PAL (NV3001P) 0573:3001 -=========== ======================================================== ========= +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - USB IDs + + * - 0 + - Xanboo + - 0a6f:0400 + + * - 1 + - Belkin USB VideoBus II Adapter + - 050d:0106 + + * - 2 + - Belkin Components USB VideoBus + - 050d:0207 + + * - 3 + - Belkin USB VideoBus II + - 050d:0208 + + * - 4 + - echoFX InterView Lite + - 0571:0002 + + * - 5 + - USBGear USBG-V1 resp. HAMA USB + - 0573:0003 + + * - 6 + - D-Link V100 + - 0573:0400 + + * - 7 + - X10 USB Camera + - 0573:2000 + + * - 8 + - Hauppauge WinTV USB Live (PAL B/G) + - 0573:2d00 + + * - 9 + - Hauppauge WinTV USB Live Pro (NTSC M/N) + - 0573:2d01 + + * - 10 + - Zoran Co. PMD (Nogatech) AV-grabber Manhattan + - 0573:2101 + + * - 11 + - Nogatech USB-TV (NTSC) FM + - 0573:4100 + + * - 12 + - PNY USB-TV (NTSC) FM + - 0573:4110 + + * - 13 + - PixelView PlayTv-USB PRO (PAL) FM + - 0573:4450 + + * - 14 + - ZTV ZT-721 2.4GHz USB A/V Receiver + - 0573:4550 + + * - 15 + - Hauppauge WinTV USB (NTSC M/N) + - 0573:4d00 + + * - 16 + - Hauppauge WinTV USB (PAL B/G) + - 0573:4d01 + + * - 17 + - Hauppauge WinTV USB (PAL I) + - 0573:4d02 + + * - 18 + - Hauppauge WinTV USB (PAL/SECAM L) + - 0573:4d03 + + * - 19 + - Hauppauge WinTV USB (PAL D/K) + - 0573:4d04 + + * - 20 + - Hauppauge WinTV USB (NTSC FM) + - 0573:4d10 + + * - 21 + - Hauppauge WinTV USB (PAL B/G FM) + - 0573:4d11 + + * - 22 + - Hauppauge WinTV USB (PAL I FM) + - 0573:4d12 + + * - 23 + - Hauppauge WinTV USB (PAL D/K FM) + - 0573:4d14 + + * - 24 + - Hauppauge WinTV USB Pro (NTSC M/N) + - 0573:4d2a + + * - 25 + - Hauppauge WinTV USB Pro (NTSC M/N) V2 + - 0573:4d2b + + * - 26 + - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) + - 0573:4d2c + + * - 27 + - Hauppauge WinTV USB Pro (NTSC M/N) V3 + - 0573:4d20 + + * - 28 + - Hauppauge WinTV USB Pro (PAL B/G) + - 0573:4d21 + + * - 29 + - Hauppauge WinTV USB Pro (PAL I) + - 0573:4d22 + + * - 30 + - Hauppauge WinTV USB Pro (PAL/SECAM L) + - 0573:4d23 + + * - 31 + - Hauppauge WinTV USB Pro (PAL D/K) + - 0573:4d24 + + * - 32 + - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) + - 0573:4d25 + + * - 33 + - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 + - 0573:4d26 + + * - 34 + - Hauppauge WinTV USB Pro (PAL B/G) V2 + - 0573:4d27 + + * - 35 + - Hauppauge WinTV USB Pro (PAL B/G,D/K) + - 0573:4d28 + + * - 36 + - Hauppauge WinTV USB Pro (PAL I,D/K) + - 0573:4d29 + + * - 37 + - Hauppauge WinTV USB Pro (NTSC M/N FM) + - 0573:4d30 + + * - 38 + - Hauppauge WinTV USB Pro (PAL B/G FM) + - 0573:4d31 + + * - 39 + - Hauppauge WinTV USB Pro (PAL I FM) + - 0573:4d32 + + * - 40 + - Hauppauge WinTV USB Pro (PAL D/K FM) + - 0573:4d34 + + * - 41 + - Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) + - 0573:4d35 + + * - 42 + - Hauppauge WinTV USB Pro (Temic PAL B/G FM) + - 0573:4d36 + + * - 43 + - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) + - 0573:4d37 + + * - 44 + - Hauppauge WinTV USB Pro (NTSC M/N FM) V2 + - 0573:4d38 + + * - 45 + - Camtel Technology USB TV Genie Pro FM Model TVB330 + - 0768:0006 + + * - 46 + - Digital Video Creator I + - 07d0:0001 + + * - 47 + - Global Village GV-007 (NTSC) + - 07d0:0002 + + * - 48 + - Dazzle Fusion Model DVC-50 Rev 1 (NTSC) + - 07d0:0003 + + * - 49 + - Dazzle Fusion Model DVC-80 Rev 1 (PAL) + - 07d0:0004 + + * - 50 + - Dazzle Fusion Model DVC-90 Rev 1 (SECAM) + - 07d0:0005 + + * - 51 + - Eskape Labs MyTV2Go + - 07f8:9104 + + * - 52 + - Pinnacle Studio PCTV USB (PAL) + - 2304:010d + + * - 53 + - Pinnacle Studio PCTV USB (SECAM) + - 2304:0109 + + * - 54 + - Pinnacle Studio PCTV USB (PAL) FM + - 2304:0110 + + * - 55 + - Miro PCTV USB + - 2304:0111 + + * - 56 + - Pinnacle Studio PCTV USB (NTSC) FM + - 2304:0112 + + * - 57 + - Pinnacle Studio PCTV USB (PAL) FM V2 + - 2304:0210 + + * - 58 + - Pinnacle Studio PCTV USB (NTSC) FM V2 + - 2304:0212 + + * - 59 + - Pinnacle Studio PCTV USB (PAL) FM V3 + - 2304:0214 + + * - 60 + - Pinnacle Studio Linx Video input cable (NTSC) + - 2304:0300 + + * - 61 + - Pinnacle Studio Linx Video input cable (PAL) + - 2304:0301 + + * - 62 + - Pinnacle PCTV Bungee USB (PAL) FM + - 2304:0419 + + * - 63 + - Hauppauge WinTv-USB + - 2400:4200 + + * - 64 + - Pinnacle Studio PCTV USB (NTSC) FM V3 + - 2304:0113 + + * - 65 + - Nogatech USB MicroCam NTSC (NV3000N) + - 0573:3000 + + * - 66 + - Nogatech USB MicroCam PAL (NV3001P) + - 0573:3001 diff --git a/Documentation/media/v4l-drivers/vivid.rst b/Documentation/media/v4l-drivers/vivid.rst index 3e44b2217f2d33dbd1a57d3aa675a99fc4741e62..089595ce11c5fdfa44de69c4439df955dd92c973 100644 --- a/Documentation/media/v4l-drivers/vivid.rst +++ b/Documentation/media/v4l-drivers/vivid.rst @@ -829,6 +829,7 @@ The following two controls are only valid for video and vbi capture. The following two controls are only valid for video capture. - DV Timings Signal Mode: + selects the behavior of VIDIOC_QUERY_DV_TIMINGS: what should it return? diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index c4ddfcd5ee3265788f37061e6b739b99b707df16..b759a60624fd3d195981cf4e7d4cd9acc60f3c0d 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -498,11 +498,11 @@ And a couple of implicit varieties: This means that ACQUIRE acts as a minimal "acquire" operation and RELEASE acts as a minimal "release" operation. -A subset of the atomic operations described in core-api/atomic_ops.rst have -ACQUIRE and RELEASE variants in addition to fully-ordered and relaxed (no -barrier semantics) definitions. For compound atomics performing both a load -and a store, ACQUIRE semantics apply only to the load and RELEASE semantics -apply only to the store portion of the operation. +A subset of the atomic operations described in atomic_t.txt have ACQUIRE and +RELEASE variants in addition to fully-ordered and relaxed (no barrier +semantics) definitions. For compound atomics performing both a load and a +store, ACQUIRE semantics apply only to the load and RELEASE semantics apply +only to the store portion of the operation. Memory barriers are only required where there's a possibility of interaction between two CPUs or between a CPU and a device. If it can be guaranteed that @@ -594,7 +594,24 @@ between the address load and the data load: This enforces the occurrence of one of the two implications, and prevents the third possibility from arising. -A data-dependency barrier must also order against dependent writes: + +[!] Note that this extremely counterintuitive situation arises most easily on +machines with split caches, so that, for example, one cache bank processes +even-numbered cache lines and the other bank processes odd-numbered cache +lines. The pointer P might be stored in an odd-numbered cache line, and the +variable B might be stored in an even-numbered cache line. Then, if the +even-numbered bank of the reading CPU's cache is extremely busy while the +odd-numbered bank is idle, one can see the new value of the pointer P (&B), +but the old value of the variable B (2). + + +A data-dependency barrier is not required to order dependent writes +because the CPUs that the Linux kernel supports don't do writes +until they are certain (1) that the write will actually happen, (2) +of the location of the write, and (3) of the value to be written. +But please carefully read the "CONTROL DEPENDENCIES" section and the +Documentation/RCU/rcu_dereference.txt file: The compiler can and does +break dependencies in a great many highly creative ways. CPU 1 CPU 2 =============== =============== @@ -603,29 +620,19 @@ A data-dependency barrier must also order against dependent writes: WRITE_ONCE(P, &B); Q = READ_ONCE(P); - - *Q = 5; + WRITE_ONCE(*Q, 5); -The data-dependency barrier must order the read into Q with the store -into *Q. This prohibits this outcome: +Therefore, no data-dependency barrier is required to order the read into +Q with the store into *Q. In other words, this outcome is prohibited, +even without a data-dependency barrier: (Q == &B) && (B == 4) Please note that this pattern should be rare. After all, the whole point of dependency ordering is to -prevent- writes to the data structure, along with the expensive cache misses associated with those writes. This pattern -can be used to record rare error conditions and the like, and the ordering -prevents such records from being lost. - - -[!] Note that this extremely counterintuitive situation arises most easily on -machines with split caches, so that, for example, one cache bank processes -even-numbered cache lines and the other bank processes odd-numbered cache -lines. The pointer P might be stored in an odd-numbered cache line, and the -variable B might be stored in an even-numbered cache line. Then, if the -even-numbered bank of the reading CPU's cache is extremely busy while the -odd-numbered bank is idle, one can see the new value of the pointer P (&B), -but the old value of the variable B (2). +can be used to record rare error conditions and the like, and the CPUs' +naturally occurring ordering prevents such records from being lost. The data dependency barrier is very important to the RCU system, @@ -1876,8 +1883,7 @@ There are some more advanced barrier functions: This makes sure that the death mark on the object is perceived to be set *before* the reference counter is decremented. - See Documentation/core-api/atomic_ops.rst for more information. See the - "Atomic operations" subsection for information on where to use these. + See Documentation/atomic_{t,bitops}.txt for more information. (*) lockless_dereference(); @@ -1982,10 +1988,7 @@ for each construct. These operations all imply certain barriers: ACQUIRE operation has completed. Memory operations issued before the ACQUIRE may be completed after - the ACQUIRE operation has completed. An smp_mb__before_spinlock(), - combined with a following ACQUIRE, orders prior stores against - subsequent loads and stores. Note that this is weaker than smp_mb()! - The smp_mb__before_spinlock() primitive is free on many architectures. + the ACQUIRE operation has completed. (2) RELEASE operation implication: @@ -2503,88 +2506,7 @@ operations are noted specially as some of them imply full memory barriers and some don't, but they're very heavily relied on as a group throughout the kernel. -Any atomic operation that modifies some state in memory and returns information -about the state (old or new) implies an SMP-conditional general memory barrier -(smp_mb()) on each side of the actual operation (with the exception of -explicit lock operations, described later). These include: - - xchg(); - atomic_xchg(); atomic_long_xchg(); - atomic_inc_return(); atomic_long_inc_return(); - atomic_dec_return(); atomic_long_dec_return(); - atomic_add_return(); atomic_long_add_return(); - atomic_sub_return(); atomic_long_sub_return(); - atomic_inc_and_test(); atomic_long_inc_and_test(); - atomic_dec_and_test(); atomic_long_dec_and_test(); - atomic_sub_and_test(); atomic_long_sub_and_test(); - atomic_add_negative(); atomic_long_add_negative(); - test_and_set_bit(); - test_and_clear_bit(); - test_and_change_bit(); - - /* when succeeds */ - cmpxchg(); - atomic_cmpxchg(); atomic_long_cmpxchg(); - atomic_add_unless(); atomic_long_add_unless(); - -These are used for such things as implementing ACQUIRE-class and RELEASE-class -operations and adjusting reference counters towards object destruction, and as -such the implicit memory barrier effects are necessary. - - -The following operations are potential problems as they do _not_ imply memory -barriers, but might be used for implementing such things as RELEASE-class -operations: - - atomic_set(); - set_bit(); - clear_bit(); - change_bit(); - -With these the appropriate explicit memory barrier should be used if necessary -(smp_mb__before_atomic() for instance). - - -The following also do _not_ imply memory barriers, and so may require explicit -memory barriers under some circumstances (smp_mb__before_atomic() for -instance): - - atomic_add(); - atomic_sub(); - atomic_inc(); - atomic_dec(); - -If they're used for statistics generation, then they probably don't need memory -barriers, unless there's a coupling between statistical data. - -If they're used for reference counting on an object to control its lifetime, -they probably don't need memory barriers because either the reference count -will be adjusted inside a locked section, or the caller will already hold -sufficient references to make the lock, and thus a memory barrier unnecessary. - -If they're used for constructing a lock of some description, then they probably -do need memory barriers as a lock primitive generally has to do things in a -specific order. - -Basically, each usage case has to be carefully considered as to whether memory -barriers are needed or not. - -The following operations are special locking primitives: - - test_and_set_bit_lock(); - clear_bit_unlock(); - __clear_bit_unlock(); - -These implement ACQUIRE-class and RELEASE-class operations. These should be -used in preference to other operations when implementing locking primitives, -because their implementations can be optimised on many architectures. - -[!] Note that special memory barrier primitives are available for these -situations because on some CPUs the atomic instructions used imply full memory -barriers, and so barrier instructions are superfluous in conjunction with them, -and in such cases the special barrier primitives will be no-ops. - -See Documentation/core-api/atomic_ops.rst for more information. +See Documentation/atomic_t.txt for more information. ACCESSING DEVICES diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index c6beb5f1637f9606475bb22746944333e5345b92..7a79b3587dd3237fec7d5928b5cf97880cabc816 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -30,8 +30,6 @@ atm.txt - info on where to get ATM programs and support for Linux. ax25.txt - info on using AX.25 and NET/ROM code for Linux -batman-adv.txt - - B.A.T.M.A.N routing protocol on top of layer 2 Ethernet Frames. baycom.txt - info on the driver for Baycom style amateur radio modems bonding.txt diff --git a/Documentation/networking/batman-adv.rst b/Documentation/networking/batman-adv.rst new file mode 100644 index 0000000000000000000000000000000000000000..a342b2cc3dc64037e4c47a2ea4a2d12f47702c8d --- /dev/null +++ b/Documentation/networking/batman-adv.rst @@ -0,0 +1,220 @@ +========== +batman-adv +========== + +Batman advanced is a new approach to wireless networking which does no longer +operate on the IP basis. Unlike the batman daemon, which exchanges information +using UDP packets and sets routing tables, batman-advanced operates on ISO/OSI +Layer 2 only and uses and routes (or better: bridges) Ethernet Frames. It +emulates a virtual network switch of all nodes participating. Therefore all +nodes appear to be link local, thus all higher operating protocols won't be +affected by any changes within the network. You can run almost any protocol +above batman advanced, prominent examples are: IPv4, IPv6, DHCP, IPX. + +Batman advanced was implemented as a Linux kernel driver to reduce the overhead +to a minimum. It does not depend on any (other) network driver, and can be used +on wifi as well as ethernet lan, vpn, etc ... (anything with ethernet-style +layer 2). + + +Configuration +============= + +Load the batman-adv module into your kernel:: + + $ insmod batman-adv.ko + +The module is now waiting for activation. You must add some interfaces on which +batman can operate. After loading the module batman advanced will scan your +systems interfaces to search for compatible interfaces. Once found, it will +create subfolders in the ``/sys`` directories of each supported interface, +e.g.:: + + $ ls /sys/class/net/eth0/batman_adv/ + elp_interval iface_status mesh_iface throughput_override + +If an interface does not have the ``batman_adv`` subfolder, it probably is not +supported. Not supported interfaces are: loopback, non-ethernet and batman's +own interfaces. + +Note: After the module was loaded it will continuously watch for new +interfaces to verify the compatibility. There is no need to reload the module +if you plug your USB wifi adapter into your machine after batman advanced was +initially loaded. + +The batman-adv soft-interface can be created using the iproute2 tool ``ip``:: + + $ ip link add name bat0 type batadv + +To activate a given interface simply attach it to the ``bat0`` interface:: + + $ ip link set dev eth0 master bat0 + +Repeat this step for all interfaces you wish to add. Now batman starts +using/broadcasting on this/these interface(s). + +By reading the "iface_status" file you can check its status:: + + $ cat /sys/class/net/eth0/batman_adv/iface_status + active + +To deactivate an interface you have to detach it from the "bat0" interface:: + + $ ip link set dev eth0 nomaster + + +All mesh wide settings can be found in batman's own interface folder:: + + $ ls /sys/class/net/bat0/mesh/ + aggregated_ogms fragmentation isolation_mark routing_algo + ap_isolation gw_bandwidth log_level vlan0 + bonding gw_mode multicast_mode + bridge_loop_avoidance gw_sel_class network_coding + distributed_arp_table hop_penalty orig_interval + +There is a special folder for debugging information:: + + $ ls /sys/kernel/debug/batman_adv/bat0/ + bla_backbone_table log neighbors transtable_local + bla_claim_table mcast_flags originators + dat_cache nc socket + gateways nc_nodes transtable_global + +Some of the files contain all sort of status information regarding the mesh +network. For example, you can view the table of originators (mesh +participants) with:: + + $ cat /sys/kernel/debug/batman_adv/bat0/originators + +Other files allow to change batman's behaviour to better fit your requirements. +For instance, you can check the current originator interval (value in +milliseconds which determines how often batman sends its broadcast packets):: + + $ cat /sys/class/net/bat0/mesh/orig_interval + 1000 + +and also change its value:: + + $ echo 3000 > /sys/class/net/bat0/mesh/orig_interval + +In very mobile scenarios, you might want to adjust the originator interval to a +lower value. This will make the mesh more responsive to topology changes, but +will also increase the overhead. + + +Usage +===== + +To make use of your newly created mesh, batman advanced provides a new +interface "bat0" which you should use from this point on. All interfaces added +to batman advanced are not relevant any longer because batman handles them for +you. Basically, one "hands over" the data by using the batman interface and +batman will make sure it reaches its destination. + +The "bat0" interface can be used like any other regular interface. It needs an +IP address which can be either statically configured or dynamically (by using +DHCP or similar services):: + + NodeA: ip link set up dev bat0 + NodeA: ip addr add 192.168.0.1/24 dev bat0 + + NodeB: ip link set up dev bat0 + NodeB: ip addr add 192.168.0.2/24 dev bat0 + NodeB: ping 192.168.0.1 + +Note: In order to avoid problems remove all IP addresses previously assigned to +interfaces now used by batman advanced, e.g.:: + + $ ip addr flush dev eth0 + + +Logging/Debugging +================= + +All error messages, warnings and information messages are sent to the kernel +log. Depending on your operating system distribution this can be read in one of +a number of ways. Try using the commands: ``dmesg``, ``logread``, or looking in +the files ``/var/log/kern.log`` or ``/var/log/syslog``. All batman-adv messages +are prefixed with "batman-adv:" So to see just these messages try:: + + $ dmesg | grep batman-adv + +When investigating problems with your mesh network, it is sometimes necessary to +see more detail debug messages. This must be enabled when compiling the +batman-adv module. When building batman-adv as part of kernel, use "make +menuconfig" and enable the option ``B.A.T.M.A.N. debugging`` +(``CONFIG_BATMAN_ADV_DEBUG=y``). + +Those additional debug messages can be accessed using a special file in +debugfs:: + + $ cat /sys/kernel/debug/batman_adv/bat0/log + +The additional debug output is by default disabled. It can be enabled during +run time. Following log_levels are defined: + +.. flat-table:: + + * - 0 + - All debug output disabled + * - 1 + - Enable messages related to routing / flooding / broadcasting + * - 2 + - Enable messages related to route added / changed / deleted + * - 4 + - Enable messages related to translation table operations + * - 8 + - Enable messages related to bridge loop avoidance + * - 16 + - Enable messages related to DAT, ARP snooping and parsing + * - 32 + - Enable messages related to network coding + * - 64 + - Enable messages related to multicast + * - 128 + - Enable messages related to throughput meter + * - 255 + - Enable all messages + +The debug output can be changed at runtime using the file +``/sys/class/net/bat0/mesh/log_level``. e.g.:: + + $ echo 6 > /sys/class/net/bat0/mesh/log_level + +will enable debug messages for when routes change. + +Counters for different types of packets entering and leaving the batman-adv +module are available through ethtool:: + + $ ethtool --statistics bat0 + + +batctl +====== + +As batman advanced operates on layer 2, all hosts participating in the virtual +switch are completely transparent for all protocols above layer 2. Therefore +the common diagnosis tools do not work as expected. To overcome these problems, +batctl was created. At the moment the batctl contains ping, traceroute, tcpdump +and interfaces to the kernel module settings. + +For more information, please see the manpage (``man batctl``). + +batctl is available on https://www.open-mesh.org/ + + +Contact +======= + +Please send us comments, experiences, questions, anything :) + +IRC: + #batman on irc.freenode.org +Mailing-list: + b.a.t.m.a.n@open-mesh.org (optional subscription at + https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) + +You can also contact the Authors: + +* Marek Lindner +* Simon Wunderlich diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt deleted file mode 100644 index ccf94677b240973f35c4cd9e948c96b92163037e..0000000000000000000000000000000000000000 --- a/Documentation/networking/batman-adv.txt +++ /dev/null @@ -1,215 +0,0 @@ -BATMAN-ADV ----------- - -Batman advanced is a new approach to wireless networking which -does no longer operate on the IP basis. Unlike the batman daemon, -which exchanges information using UDP packets and sets routing -tables, batman-advanced operates on ISO/OSI Layer 2 only and uses -and routes (or better: bridges) Ethernet Frames. It emulates a -virtual network switch of all nodes participating. Therefore all -nodes appear to be link local, thus all higher operating proto- -cols won't be affected by any changes within the network. You can -run almost any protocol above batman advanced, prominent examples -are: IPv4, IPv6, DHCP, IPX. - -Batman advanced was implemented as a Linux kernel driver to re- -duce the overhead to a minimum. It does not depend on any (other) -network driver, and can be used on wifi as well as ethernet lan, -vpn, etc ... (anything with ethernet-style layer 2). - - -CONFIGURATION -------------- - -Load the batman-adv module into your kernel: - -# insmod batman-adv.ko - -The module is now waiting for activation. You must add some in- -terfaces on which batman can operate. After loading the module -batman advanced will scan your systems interfaces to search for -compatible interfaces. Once found, it will create subfolders in -the /sys directories of each supported interface, e.g. - -# ls /sys/class/net/eth0/batman_adv/ -# elp_interval iface_status mesh_iface throughput_override - -If an interface does not have the "batman_adv" subfolder it prob- -ably is not supported. Not supported interfaces are: loopback, -non-ethernet and batman's own interfaces. - -Note: After the module was loaded it will continuously watch for -new interfaces to verify the compatibility. There is no need to -reload the module if you plug your USB wifi adapter into your ma- -chine after batman advanced was initially loaded. - -The batman-adv soft-interface can be created using the iproute2 -tool "ip" - -# ip link add name bat0 type batadv - -To activate a given interface simply attach it to the "bat0" -interface - -# ip link set dev eth0 master bat0 - -Repeat this step for all interfaces you wish to add. Now batman -starts using/broadcasting on this/these interface(s). - -By reading the "iface_status" file you can check its status: - -# cat /sys/class/net/eth0/batman_adv/iface_status -# active - -To deactivate an interface you have to detach it from the -"bat0" interface: - -# ip link set dev eth0 nomaster - - -All mesh wide settings can be found in batman's own interface -folder: - -# ls /sys/class/net/bat0/mesh/ -# aggregated_ogms fragmentation isolation_mark routing_algo -# ap_isolation gw_bandwidth log_level vlan0 -# bonding gw_mode multicast_mode -# bridge_loop_avoidance gw_sel_class network_coding -# distributed_arp_table hop_penalty orig_interval - -There is a special folder for debugging information: - -# ls /sys/kernel/debug/batman_adv/bat0/ -# bla_backbone_table log neighbors transtable_local -# bla_claim_table mcast_flags originators -# dat_cache nc socket -# gateways nc_nodes transtable_global - -Some of the files contain all sort of status information regard- -ing the mesh network. For example, you can view the table of -originators (mesh participants) with: - -# cat /sys/kernel/debug/batman_adv/bat0/originators - -Other files allow to change batman's behaviour to better fit your -requirements. For instance, you can check the current originator -interval (value in milliseconds which determines how often batman -sends its broadcast packets): - -# cat /sys/class/net/bat0/mesh/orig_interval -# 1000 - -and also change its value: - -# echo 3000 > /sys/class/net/bat0/mesh/orig_interval - -In very mobile scenarios, you might want to adjust the originator -interval to a lower value. This will make the mesh more respon- -sive to topology changes, but will also increase the overhead. - - -USAGE ------ - -To make use of your newly created mesh, batman advanced provides -a new interface "bat0" which you should use from this point on. -All interfaces added to batman advanced are not relevant any -longer because batman handles them for you. Basically, one "hands -over" the data by using the batman interface and batman will make -sure it reaches its destination. - -The "bat0" interface can be used like any other regular inter- -face. It needs an IP address which can be either statically con- -figured or dynamically (by using DHCP or similar services): - -# NodeA: ip link set up dev bat0 -# NodeA: ip addr add 192.168.0.1/24 dev bat0 - -# NodeB: ip link set up dev bat0 -# NodeB: ip addr add 192.168.0.2/24 dev bat0 -# NodeB: ping 192.168.0.1 - -Note: In order to avoid problems remove all IP addresses previ- -ously assigned to interfaces now used by batman advanced, e.g. - -# ip addr flush dev eth0 - - -LOGGING/DEBUGGING ------------------ - -All error messages, warnings and information messages are sent to -the kernel log. Depending on your operating system distribution -this can be read in one of a number of ways. Try using the com- -mands: dmesg, logread, or looking in the files /var/log/kern.log -or /var/log/syslog. All batman-adv messages are prefixed with -"batman-adv:" So to see just these messages try - -# dmesg | grep batman-adv - -When investigating problems with your mesh network it is some- -times necessary to see more detail debug messages. This must be -enabled when compiling the batman-adv module. When building bat- -man-adv as part of kernel, use "make menuconfig" and enable the -option "B.A.T.M.A.N. debugging". - -Those additional debug messages can be accessed using a special -file in debugfs - -# cat /sys/kernel/debug/batman_adv/bat0/log - -The additional debug output is by default disabled. It can be en- -abled during run time. Following log_levels are defined: - - 0 - All debug output disabled - 1 - Enable messages related to routing / flooding / broadcasting - 2 - Enable messages related to route added / changed / deleted - 4 - Enable messages related to translation table operations - 8 - Enable messages related to bridge loop avoidance - 16 - Enable messages related to DAT, ARP snooping and parsing - 32 - Enable messages related to network coding - 64 - Enable messages related to multicast -128 - Enable messages related to throughput meter -255 - Enable all messages - -The debug output can be changed at runtime using the file -/sys/class/net/bat0/mesh/log_level. e.g. - -# echo 6 > /sys/class/net/bat0/mesh/log_level - -will enable debug messages for when routes change. - -Counters for different types of packets entering and leaving the -batman-adv module are available through ethtool: - -# ethtool --statistics bat0 - - -BATCTL ------- - -As batman advanced operates on layer 2 all hosts participating in -the virtual switch are completely transparent for all protocols -above layer 2. Therefore the common diagnosis tools do not work -as expected. To overcome these problems batctl was created. At -the moment the batctl contains ping, traceroute, tcpdump and -interfaces to the kernel module settings. - -For more information, please see the manpage (man batctl). - -batctl is available on https://www.open-mesh.org/ - - -CONTACT -------- - -Please send us comments, experiences, questions, anything :) - -IRC: #batman on irc.freenode.org -Mailing-list: b.a.t.m.a.n@open-mesh.org (optional subscription - at https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) - -You can also contact the Authors: - -Marek Lindner -Simon Wunderlich diff --git a/Documentation/networking/dpaa.txt b/Documentation/networking/dpaa.txt index 76e016d4d3449655680a9f3c7e241472c2d32938..f88194f71c5465fd77fd8cbc5a71d60172e46a79 100644 --- a/Documentation/networking/dpaa.txt +++ b/Documentation/networking/dpaa.txt @@ -13,6 +13,7 @@ Contents - Configuring DPAA Ethernet in your kernel - DPAA Ethernet Frame Processing - DPAA Ethernet Features + - DPAA IRQ Affinity and Receive Side Scaling - Debugging DPAA Ethernet Overview @@ -147,7 +148,10 @@ gradually. The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx checksum offload feature is enabled by default and cannot be controlled through -ethtool. +ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS +provides a big performance boost for the forwarding scenarios, allowing +different traffic flows received by one interface to be processed by different +CPUs in parallel. The driver has support for multiple prioritized Tx traffic classes. Priorities range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with @@ -166,6 +170,68 @@ classes as follows: tc qdisc add dev root handle 1: \ mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1 +DPAA IRQ Affinity and Receive Side Scaling +========================================== + +Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation +queues is seen by the CPU as ingress traffic on a certain portal. +The DPAA QMan portal interrupts are affined each to a certain CPU. +The same portal interrupt services all the QMan portal consumers. + +By default the DPAA Ethernet driver enables RSS, making use of the +DPAA FMan Parser and Keygen blocks to distribute traffic on 128 +hardware frame queues using a hash on IP v4/v6 source and destination +and L4 source and destination ports, in present in the received frame. +When RSS is disabled, all traffic received by a certain interface is +received on the default Rx frame queue. The default DPAA Rx frame +queues are configured to put the received traffic into a pool channel +that allows any available CPU portal to dequeue the ingress traffic. +The default frame queues have the HOLDACTIVE option set, ensuring that +traffic bursts from a certain queue are serviced by the same CPU. +This ensures a very low rate of frame reordering. A drawback of this +is that only one CPU at a time can service the traffic received by a +certain interface when RSS is not enabled. + +To implement RSS, the DPAA Ethernet driver allocates an extra set of +128 Rx frame queues that are configured to dedicated channels, in a +round-robin manner. The mapping of the frame queues to CPUs is now +hardcoded, there is no indirection table to move traffic for a certain +FQ (hash result) to another CPU. The ingress traffic arriving on one +of these frame queues will arrive at the same portal and will always +be processed by the same CPU. This ensures intra-flow order preservation +and workload distribution for multiple traffic flows. + +RSS can be turned off for a certain interface using ethtool, i.e. + + # ethtool -N fm1-mac9 rx-flow-hash tcp4 "" + +To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6: + + # ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn + +There is no independent control for individual protocols, any command +run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is +going to control the rx-flow-hashing for all protocols on that interface. + +Besides using the FMan Keygen computed hash for spreading traffic on the +128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when +the NETIF_F_RXHASH feature is on (active by default). This can be turned +on or off through ethtool, i.e.: + + # ethtool -K fm1-mac9 rx-hashing off + # ethtool -k fm1-mac9 | grep hash + receive-hashing: off + # ethtool -K fm1-mac9 rx-hashing on + Actual changes: + receive-hashing: on + # ethtool -k fm1-mac9 | grep hash + receive-hashing: on + +Please note that Rx hashing depends upon the rx-flow-hashing being on +for that interface - turning off rx-flow-hashing will also disable the +rx-hashing (without ethtool reporting it as off as that depends on the +NETIF_F_RXHASH feature flag). + Debugging ========= diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt index b69b205501dec6a7571489a51bd9718c65c4270d..87814859cfc21c5c6a64c1dfb83a1d6cff596731 100644 --- a/Documentation/networking/filter.txt +++ b/Documentation/networking/filter.txt @@ -45,7 +45,7 @@ in many more places. There's xt_bpf for netfilter, cls_bpf in the kernel qdisc layer, SECCOMP-BPF (SECure COMPuting [1]), and lots of other places such as team driver, PTP code, etc where BPF is being used. - [1] Documentation/prctl/seccomp_filter.txt + [1] Documentation/userspace-api/seccomp_filter.rst Original BPF paper: @@ -337,7 +337,7 @@ Examples for low-level BPF: jeq #14, good /* __NR_rt_sigprocmask */ jeq #13, good /* __NR_rt_sigaction */ jeq #35, good /* __NR_nanosleep */ - bad: ret #0 /* SECCOMP_RET_KILL */ + bad: ret #0 /* SECCOMP_RET_KILL_THREAD */ good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ The above example code can be placed into a file (here called "foo"), and @@ -596,8 +596,8 @@ skb pointer). All constraints and restrictions from bpf_check_classic() apply before a conversion to the new layout is being done behind the scenes! Currently, the classic BPF format is being used for JITing on most 32-bit -architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64 perform JIT -compilation from eBPF instruction set. +architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64, arm32 perform +JIT compilation from eBPF instruction set. Some core changes of the new internal format: @@ -793,7 +793,7 @@ Some core changes of the new internal format: bpf_exit After the call the registers R1-R5 contain junk values and cannot be read. - In the future an eBPF verifier can be used to validate internal BPF programs. + An in-kernel eBPF verifier is used to validate internal BPF programs. Also in the new design, eBPF is limited to 4096 insns, which means that any program will terminate quickly and will only call a fixed number of kernel @@ -906,6 +906,10 @@ If BPF_CLASS(code) == BPF_JMP, BPF_OP(code) is one of: BPF_JSGE 0x70 /* eBPF only: signed '>=' */ BPF_CALL 0x80 /* eBPF only: function call */ BPF_EXIT 0x90 /* eBPF only: function return */ + BPF_JLT 0xa0 /* eBPF only: unsigned '<' */ + BPF_JLE 0xb0 /* eBPF only: unsigned '<=' */ + BPF_JSLT 0xc0 /* eBPF only: signed '<' */ + BPF_JSLE 0xd0 /* eBPF only: signed '<=' */ So BPF_ADD | BPF_X | BPF_ALU means 32-bit addition in both classic BPF and eBPF. There are only two registers in classic BPF, so it means A += X. @@ -1017,7 +1021,7 @@ At the start of the program the register R1 contains a pointer to context and has type PTR_TO_CTX. If verifier sees an insn that does R2=R1, then R2 has now type PTR_TO_CTX as well and can be used on the right hand side of expression. -If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=UNKNOWN_VALUE, +If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=SCALAR_VALUE, since addition of two valid pointers makes invalid pointer. (In 'secure' mode verifier will reject any type of pointer arithmetic to make sure that kernel addresses don't leak to unprivileged users) @@ -1039,7 +1043,7 @@ is a correct program. If there was R1 instead of R6, it would have been rejected. load/store instructions are allowed only with registers of valid types, which -are PTR_TO_CTX, PTR_TO_MAP, FRAME_PTR. They are bounds and alignment checked. +are PTR_TO_CTX, PTR_TO_MAP, PTR_TO_STACK. They are bounds and alignment checked. For example: bpf_mov R1 = 1 bpf_mov R2 = 2 @@ -1058,7 +1062,7 @@ intends to load a word from address R6 + 8 and store it into R0 If R6=PTR_TO_CTX, via is_valid_access() callback the verifier will know that offset 8 of size 4 bytes can be accessed for reading, otherwise the verifier will reject the program. -If R6=FRAME_PTR, then access should be aligned and be within +If R6=PTR_TO_STACK, then access should be aligned and be within stack bounds, which are [-MAX_BPF_STACK, 0). In this example offset is 8, so it will fail verification, since it's out of bounds. @@ -1069,7 +1073,7 @@ For example: bpf_ld R0 = *(u32 *)(R10 - 4) bpf_exit is invalid program. -Though R10 is correct read-only register and has type FRAME_PTR +Though R10 is correct read-only register and has type PTR_TO_STACK and R10 - 4 is within stack bounds, there were no stores into that location. Pointer register spill/fill is tracked as well, since four (R6-R9) @@ -1094,6 +1098,71 @@ all use cases. See details of eBPF verifier in kernel/bpf/verifier.c +Register value tracking +----------------------- +In order to determine the safety of an eBPF program, the verifier must track +the range of possible values in each register and also in each stack slot. +This is done with 'struct bpf_reg_state', defined in include/linux/ +bpf_verifier.h, which unifies tracking of scalar and pointer values. Each +register state has a type, which is either NOT_INIT (the register has not been +written to), SCALAR_VALUE (some value which is not usable as a pointer), or a +pointer type. The types of pointers describe their base, as follows: + PTR_TO_CTX Pointer to bpf_context. + CONST_PTR_TO_MAP Pointer to struct bpf_map. "Const" because arithmetic + on these pointers is forbidden. + PTR_TO_MAP_VALUE Pointer to the value stored in a map element. + PTR_TO_MAP_VALUE_OR_NULL + Either a pointer to a map value, or NULL; map accesses + (see section 'eBPF maps', below) return this type, + which becomes a PTR_TO_MAP_VALUE when checked != NULL. + Arithmetic on these pointers is forbidden. + PTR_TO_STACK Frame pointer. + PTR_TO_PACKET skb->data. + PTR_TO_PACKET_END skb->data + headlen; arithmetic forbidden. +However, a pointer may be offset from this base (as a result of pointer +arithmetic), and this is tracked in two parts: the 'fixed offset' and 'variable +offset'. The former is used when an exactly-known value (e.g. an immediate +operand) is added to a pointer, while the latter is used for values which are +not exactly known. The variable offset is also used in SCALAR_VALUEs, to track +the range of possible values in the register. +The verifier's knowledge about the variable offset consists of: +* minimum and maximum values as unsigned +* minimum and maximum values as signed +* knowledge of the values of individual bits, in the form of a 'tnum': a u64 +'mask' and a u64 'value'. 1s in the mask represent bits whose value is unknown; +1s in the value represent bits known to be 1. Bits known to be 0 have 0 in both +mask and value; no bit should ever be 1 in both. For example, if a byte is read +into a register from memory, the register's top 56 bits are known zero, while +the low 8 are unknown - which is represented as the tnum (0x0; 0xff). If we +then OR this with 0x40, we get (0x40; 0xcf), then if we add 1 we get (0x0; +0x1ff), because of potential carries. +Besides arithmetic, the register state can also be updated by conditional +branches. For instance, if a SCALAR_VALUE is compared > 8, in the 'true' branch +it will have a umin_value (unsigned minimum value) of 9, whereas in the 'false' +branch it will have a umax_value of 8. A signed compare (with BPF_JSGT or +BPF_JSGE) would instead update the signed minimum/maximum values. Information +from the signed and unsigned bounds can be combined; for instance if a value is +first tested < 8 and then tested s> 4, the verifier will conclude that the value +is also > 4 and s< 8, since the bounds prevent crossing the sign boundary. +PTR_TO_PACKETs with a variable offset part have an 'id', which is common to all +pointers sharing that same variable offset. This is important for packet range +checks: after adding some variable to a packet pointer, if you then copy it to +another register and (say) add a constant 4, both registers will share the same +'id' but one will have a fixed offset of +4. Then if it is bounds-checked and +found to be less than a PTR_TO_PACKET_END, the other register is now known to +have a safe range of at least 4 bytes. See 'Direct packet access', below, for +more on PTR_TO_PACKET ranges. +The 'id' field is also used on PTR_TO_MAP_VALUE_OR_NULL, common to all copies of +the pointer returned from a map lookup. This means that when one copy is +checked and found to be non-NULL, all copies can become PTR_TO_MAP_VALUEs. +As well as range-checking, the tracked information is also used for enforcing +alignment of pointer accesses. For instance, on most systems the packet pointer +is 2 bytes after a 4-byte alignment. If a program adds 14 bytes to that to jump +over the Ethernet header, then reads IHL and addes (IHL * 4), the resulting +pointer will have a variable offset known to be 4n+2 for some n, so adding the 2 +bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through +that pointer are safe. + Direct packet access -------------------- In cls_bpf and act_bpf programs the verifier allows direct access to the packet @@ -1121,7 +1190,7 @@ it now points to 'skb->data + 14' and accessible range is [R5, R5 + 14 - 14) which is zero bytes. More complex packet access may look like: - R0=imm1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp + R0=inv1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp 6: r0 = *(u8 *)(r3 +7) /* load 7th byte from the packet */ 7: r4 = *(u8 *)(r3 +12) 8: r4 *= 14 @@ -1135,26 +1204,31 @@ More complex packet access may look like: 16: r2 += 8 17: r1 = *(u32 *)(r1 +80) /* load skb->data_end */ 18: if r2 > r1 goto pc+2 - R0=inv56 R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv52 R5=pkt(id=0,off=14,r=14) R10=fp + R0=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)) R5=pkt(id=0,off=14,r=14) R10=fp 19: r1 = *(u8 *)(r3 +4) The state of the register R3 is R3=pkt(id=2,off=0,r=8) id=2 means that two 'r3 += rX' instructions were seen, so r3 points to some offset within a packet and since the program author did 'if (r3 + 8 > r1) goto err' at insn #18, the safe range is [R3, R3 + 8). -The verifier only allows 'add' operation on packet registers. Any other -operation will set the register state to 'unknown_value' and it won't be +The verifier only allows 'add'/'sub' operations on packet registers. Any other +operation will set the register state to 'SCALAR_VALUE' and it won't be available for direct packet access. Operation 'r3 += rX' may overflow and become less than original skb->data, -therefore the verifier has to prevent that. So it tracks the number of -upper zero bits in all 'uknown_value' registers, so when it sees -'r3 += rX' instruction and rX is more than 16-bit value, it will error as: -"cannot add integer value with N upper zero bits to ptr_to_packet" +therefore the verifier has to prevent that. So when it sees 'r3 += rX' +instruction and rX is more than 16-bit value, any subsequent bounds-check of r3 +against skb->data_end will not give us 'range' information, so attempts to read +through the pointer will give "invalid access to packet" error. Ex. after insn 'r4 = *(u8 *)(r3 +12)' (insn #7 above) the state of r4 is -R4=inv56 which means that upper 56 bits on the register are guaranteed -to be zero. After insn 'r4 *= 14' the state becomes R4=inv52, since -multiplying 8-bit value by constant 14 will keep upper 52 bits as zero. -Similarly 'r2 >>= 48' will make R2=inv48, since the shift is not sign -extending. This logic is implemented in evaluate_reg_alu() function. +R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) which means that upper 56 bits +of the register are guaranteed to be zero, and nothing is known about the lower +8 bits. After insn 'r4 *= 14' the state becomes +R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)), since multiplying an 8-bit +value by constant 14 will keep upper 52 bits as zero, also the least significant +bit will be zero as 14 is even. Similarly 'r2 >>= 48' will make +R2=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff)), since the shift is not sign +extending. This logic is implemented in adjust_reg_min_max_vals() function, +which calls adjust_ptr_min_max_vals() for adding pointer to scalar (or vice +versa) and adjust_scalar_min_max_vals() for operations on two scalars. The end result is that bpf program author can access packet directly using normal C code as: @@ -1214,6 +1288,22 @@ The map is defined by: . key size in bytes . value size in bytes +Pruning +------- +The verifier does not actually walk all possible paths through the program. For +each new branch to analyse, the verifier looks at all the states it's previously +been in when at this instruction. If any of them contain the current state as a +subset, the branch is 'pruned' - that is, the fact that the previous state was +accepted implies the current state would be as well. For instance, if in the +previous state, r1 held a packet-pointer, and in the current state, r1 holds a +packet-pointer with a range as long or longer and at least as strict an +alignment, then r1 is safe. Similarly, if r2 was NOT_INIT before then it can't +have been used by any path from that point, so any value in r2 (including +another NOT_INIT) is safe. The implementation is in the function regsafe(). +Pruning considers not only the registers but also the stack (and any spilled +registers it may hold). They must all be safe for the branch to be pruned. +This is implemented in states_equal(). + Understanding eBPF verifier messages ------------------------------------ diff --git a/Documentation/networking/hinic.txt b/Documentation/networking/hinic.txt new file mode 100644 index 0000000000000000000000000000000000000000..989366a4039c80023d96d7ac574fbf1f5d0058bc --- /dev/null +++ b/Documentation/networking/hinic.txt @@ -0,0 +1,125 @@ +Linux Kernel Driver for Huawei Intelligent NIC(HiNIC) family +============================================================ + +Overview: +========= +HiNIC is a network interface card for the Data Center Area. + +The driver supports a range of link-speed devices (10GbE, 25GbE, 40GbE, etc.). +The driver supports also a negotiated and extendable feature set. + +Some HiNIC devices support SR-IOV. This driver is used for Physical Function +(PF). + +HiNIC devices support MSI-X interrupt vector for each Tx/Rx queue and +adaptive interrupt moderation. + +HiNIC devices support also various offload features such as checksum offload, +TCP Transmit Segmentation Offload(TSO), Receive-Side Scaling(RSS) and +LRO(Large Receive Offload). + + +Supported PCI vendor ID/device IDs: +=================================== + +19e5:1822 - HiNIC PF + + +Driver Architecture and Source Code: +==================================== + +hinic_dev - Implement a Logical Network device that is independent from +specific HW details about HW data structure formats. + +hinic_hwdev - Implement the HW details of the device and include the components +for accessing the PCI NIC. + +hinic_hwdev contains the following components: +=============================================== + +HW Interface: +============= + +The interface for accessing the pci device (DMA memory and PCI BARs). +(hinic_hw_if.c, hinic_hw_if.h) + +Configuration Status Registers Area that describes the HW Registers on the +configuration and status BAR0. (hinic_hw_csr.h) + +MGMT components: +================ + +Asynchronous Event Queues(AEQs) - The event queues for receiving messages from +the MGMT modules on the cards. (hinic_hw_eqs.c, hinic_hw_eqs.h) + +Application Programmable Interface commands(API CMD) - Interface for sending +MGMT commands to the card. (hinic_hw_api_cmd.c, hinic_hw_api_cmd.h) + +Management (MGMT) - the PF to MGMT channel that uses API CMD for sending MGMT +commands to the card and receives notifications from the MGMT modules on the +card by AEQs. Also set the addresses of the IO CMDQs in HW. +(hinic_hw_mgmt.c, hinic_hw_mgmt.h) + +IO components: +============== + +Completion Event Queues(CEQs) - The completion Event Queues that describe IO +tasks that are finished. (hinic_hw_eqs.c, hinic_hw_eqs.h) + +Work Queues(WQ) - Contain the memory and operations for use by CMD queues and +the Queue Pairs. The WQ is a Memory Block in a Page. The Block contains +pointers to Memory Areas that are the Memory for the Work Queue Elements(WQEs). +(hinic_hw_wq.c, hinic_hw_wq.h) + +Command Queues(CMDQ) - The queues for sending commands for IO management and is +used to set the QPs addresses in HW. The commands completion events are +accumulated on the CEQ that is configured to receive the CMDQ completion events. +(hinic_hw_cmdq.c, hinic_hw_cmdq.h) + +Queue Pairs(QPs) - The HW Receive and Send queues for Receiving and Transmitting +Data. (hinic_hw_qp.c, hinic_hw_qp.h, hinic_hw_qp_ctxt.h) + +IO - de/constructs all the IO components. (hinic_hw_io.c, hinic_hw_io.h) + +HW device: +========== + +HW device - de/constructs the HW Interface, the MGMT components on the +initialization of the driver and the IO components on the case of Interface +UP/DOWN Events. (hinic_hw_dev.c, hinic_hw_dev.h) + + +hinic_dev contains the following components: +=============================================== + +PCI ID table - Contains the supported PCI Vendor/Device IDs. +(hinic_pci_tbl.h) + +Port Commands - Send commands to the HW device for port management +(MAC, Vlan, MTU, ...). (hinic_port.c, hinic_port.h) + +Tx Queues - Logical Tx Queues that use the HW Send Queues for transmit. +The Logical Tx queue is not dependent on the format of the HW Send Queue. +(hinic_tx.c, hinic_tx.h) + +Rx Queues - Logical Rx Queues that use the HW Receive Queues for receive. +The Logical Rx queue is not dependent on the format of the HW Receive Queue. +(hinic_rx.c, hinic_rx.h) + +hinic_dev - de/constructs the Logical Tx and Rx Queues. +(hinic_main.c, hinic_dev.h) + + +Miscellaneous: +============= + +Common functions that are used by HW and Logical Device. +(hinic_common.c, hinic_common.h) + + +Support +======= + +If an issue is identified with the released source code on the supported kernel +with a supported adapter, email the specific information related to the issue to +aviad.krawczyk@huawei.com. diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt index c4114346f054512b28acaf3853a9cbc5768b2849..057e9fdbfac9d93f48b85159e3a5e7954b0a781a 100644 --- a/Documentation/networking/ieee802154.txt +++ b/Documentation/networking/ieee802154.txt @@ -84,17 +84,17 @@ Device drivers API ================== The include/net/mac802154.h defines following functions: - - struct ieee802154_dev *ieee802154_alloc_device - (size_t priv_size, struct ieee802154_ops *ops): - allocation of IEEE 802.15.4 compatible device + - struct ieee802154_hw * + ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops): + allocation of IEEE 802.15.4 compatible hardware device - - void ieee802154_free_device(struct ieee802154_dev *dev): - freeing allocated device + - void ieee802154_free_hw(struct ieee802154_hw *hw): + freeing allocated hardware device - - int ieee802154_register_device(struct ieee802154_dev *dev): - register PHY in the system + - int ieee802154_register_hw(struct ieee802154_hw *hw): + register PHY which is the allocated hardware device, in the system - - void ieee802154_unregister_device(struct ieee802154_dev *dev): + - void ieee802154_unregister_hw(struct ieee802154_hw *hw): freeing registered PHY Moreover IEEE 802.15.4 device operations structure should be filled. diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst index b5bd87e01f52e3f4de253060e9614beb6643bfe5..66e62086624501fe76c170f77efc1cbc0844032f 100644 --- a/Documentation/networking/index.rst +++ b/Documentation/networking/index.rst @@ -6,6 +6,7 @@ Contents: .. toctree:: :maxdepth: 2 + batman-adv kapi z8530book diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 974ab47ae53a81c27b2b57533db813288139fd7b..77f4de59dc9ceb3cdb36692d1ea41e1d861468b0 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -109,7 +109,10 @@ neigh/default/unres_qlen_bytes - INTEGER queued for each unresolved address by other network layers. (added in linux 3.3) Setting negative value is meaningless and will return error. - Default: 65536 Bytes(64KB) + Default: SK_WMEM_MAX, (same as net.core.wmem_default). + Exact value depends on architecture and kernel options, + but should be enough to allow queuing 256 packets + of medium size. neigh/default/unres_qlen - INTEGER The maximum number of packets which may be queued for each @@ -119,7 +122,7 @@ neigh/default/unres_qlen - INTEGER unexpected packet loss. The current default value is calculated according to default value of unres_qlen_bytes and true size of packet. - Default: 31 + Default: 101 mtu_expires - INTEGER Time, in seconds, that cached PMTU information is kept. @@ -353,12 +356,7 @@ tcp_l3mdev_accept - BOOLEAN compiled with CONFIG_NET_L3_MASTER_DEV. tcp_low_latency - BOOLEAN - If set, the TCP stack makes decisions that prefer lower - latency as opposed to higher throughput. By default, this - option is not set meaning that higher throughput is preferred. - An example of an application where this default should be - changed would be a Beowulf compute cluster. - Default: 0 + This is a legacy option, it has no effect anymore. tcp_max_orphans - INTEGER Maximal number of TCP sockets not attached to any user file handle, @@ -1291,8 +1289,7 @@ tag - INTEGER xfrm4_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv4 destination cache entries. At twice this value the system will - refuse new allocations. The value must be set below the flowcache - limit (4096 * number of online cpus) to take effect. + refuse new allocations. igmp_link_local_mcast_reports - BOOLEAN Enable IGMP reports for link local multicast groups in the @@ -1356,6 +1353,15 @@ flowlabel_state_ranges - BOOLEAN FALSE: disabled Default: true +flowlabel_reflect - BOOLEAN + Automatically reflect the flow label. Needed for Path MTU + Discovery to work with Equal Cost Multipath Routing in anycast + environments. See RFC 7690 and: + https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01 + TRUE: enabled + FALSE: disabled + Default: FALSE + anycast_src_echo_reply - BOOLEAN Controls the use of anycast addresses as source addresses for ICMPv6 echo reply @@ -1674,6 +1680,9 @@ accept_dad - INTEGER 2: Enable DAD, and disable IPv6 operation if MAC-based duplicate link-local address has been found. + DAD operation and mode on a given interface will be selected according + to the maximum value of conf/{all,interface}/accept_dad. + force_tllao - BOOLEAN Enable sending the target link-layer address option even when responding to a unicast neighbor solicitation. @@ -1721,16 +1730,23 @@ suppress_frag_ndisc - INTEGER optimistic_dad - BOOLEAN Whether to perform Optimistic Duplicate Address Detection (RFC 4429). - 0: disabled (default) - 1: enabled + 0: disabled (default) + 1: enabled + + Optimistic Duplicate Address Detection for the interface will be enabled + if at least one of conf/{all,interface}/optimistic_dad is set to 1, + it will be disabled otherwise. use_optimistic - BOOLEAN If enabled, do not classify optimistic addresses as deprecated during source address selection. Preferred addresses will still be chosen before optimistic addresses, subject to other ranking in the source address selection algorithm. - 0: disabled (default) - 1: enabled + 0: disabled (default) + 1: enabled + + This will be enabled if at least one of + conf/{all,interface}/use_optimistic is set to 1, disabled otherwise. stable_secret - IPv6 address This IPv6 address will be used as a secret to generate IPv6 @@ -1778,8 +1794,7 @@ ratelimit - INTEGER xfrm6_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv6 destination cache entries. At twice this value the system will - refuse new allocations. The value must be set below the flowcache - limit (4096 * number of online cpus) to take effect. + refuse new allocations. IPv6 Update by: diff --git a/Documentation/networking/msg_zerocopy.rst b/Documentation/networking/msg_zerocopy.rst new file mode 100644 index 0000000000000000000000000000000000000000..77f6d7e25cfda65ac36e0c47bb2f8bdacc2fee2a --- /dev/null +++ b/Documentation/networking/msg_zerocopy.rst @@ -0,0 +1,257 @@ + +============ +MSG_ZEROCOPY +============ + +Intro +===== + +The MSG_ZEROCOPY flag enables copy avoidance for socket send calls. +The feature is currently implemented for TCP sockets. + + +Opportunity and Caveats +----------------------- + +Copying large buffers between user process and kernel can be +expensive. Linux supports various interfaces that eschew copying, +such as sendpage and splice. The MSG_ZEROCOPY flag extends the +underlying copy avoidance mechanism to common socket send calls. + +Copy avoidance is not a free lunch. As implemented, with page pinning, +it replaces per byte copy cost with page accounting and completion +notification overhead. As a result, MSG_ZEROCOPY is generally only +effective at writes over around 10 KB. + +Page pinning also changes system call semantics. It temporarily shares +the buffer between process and network stack. Unlike with copying, the +process cannot immediately overwrite the buffer after system call +return without possibly modifying the data in flight. Kernel integrity +is not affected, but a buggy program can possibly corrupt its own data +stream. + +The kernel returns a notification when it is safe to modify data. +Converting an existing application to MSG_ZEROCOPY is not always as +trivial as just passing the flag, then. + + +More Info +--------- + +Much of this document was derived from a longer paper presented at +netdev 2.1. For more in-depth information see that paper and talk, +the excellent reporting over at LWN.net or read the original code. + + paper, slides, video + https://netdevconf.org/2.1/session.html?debruijn + + LWN article + https://lwn.net/Articles/726917/ + + patchset + [PATCH net-next v4 0/9] socket sendmsg MSG_ZEROCOPY + http://lkml.kernel.org/r/20170803202945.70750-1-willemdebruijn.kernel@gmail.com + + +Interface +========= + +Passing the MSG_ZEROCOPY flag is the most obvious step to enable copy +avoidance, but not the only one. + +Socket Setup +------------ + +The kernel is permissive when applications pass undefined flags to the +send system call. By default it simply ignores these. To avoid enabling +copy avoidance mode for legacy processes that accidentally already pass +this flag, a process must first signal intent by setting a socket option: + +:: + + if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one))) + error(1, errno, "setsockopt zerocopy"); + + +Transmission +------------ + +The change to send (or sendto, sendmsg, sendmmsg) itself is trivial. +Pass the new flag. + +:: + + ret = send(fd, buf, sizeof(buf), MSG_ZEROCOPY); + +A zerocopy failure will return -1 with errno ENOBUFS. This happens if +the socket option was not set, the socket exceeds its optmem limit or +the user exceeds its ulimit on locked pages. + + +Mixing copy avoidance and copying +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Many workloads have a mixture of large and small buffers. Because copy +avoidance is more expensive than copying for small packets, the +feature is implemented as a flag. It is safe to mix calls with the flag +with those without. + + +Notifications +------------- + +The kernel has to notify the process when it is safe to reuse a +previously passed buffer. It queues completion notifications on the +socket error queue, akin to the transmit timestamping interface. + +The notification itself is a simple scalar value. Each socket +maintains an internal unsigned 32-bit counter. Each send call with +MSG_ZEROCOPY that successfully sends data increments the counter. The +counter is not incremented on failure or if called with length zero. +The counter counts system call invocations, not bytes. It wraps after +UINT_MAX calls. + + +Notification Reception +~~~~~~~~~~~~~~~~~~~~~~ + +The below snippet demonstrates the API. In the simplest case, each +send syscall is followed by a poll and recvmsg on the error queue. + +Reading from the error queue is always a non-blocking operation. The +poll call is there to block until an error is outstanding. It will set +POLLERR in its output flags. That flag does not have to be set in the +events field. Errors are signaled unconditionally. + +:: + + pfd.fd = fd; + pfd.events = 0; + if (poll(&pfd, 1, -1) != 1 || pfd.revents & POLLERR == 0) + error(1, errno, "poll"); + + ret = recvmsg(fd, &msg, MSG_ERRQUEUE); + if (ret == -1) + error(1, errno, "recvmsg"); + + read_notification(msg); + +The example is for demonstration purpose only. In practice, it is more +efficient to not wait for notifications, but read without blocking +every couple of send calls. + +Notifications can be processed out of order with other operations on +the socket. A socket that has an error queued would normally block +other operations until the error is read. Zerocopy notifications have +a zero error code, however, to not block send and recv calls. + + +Notification Batching +~~~~~~~~~~~~~~~~~~~~~ + +Multiple outstanding packets can be read at once using the recvmmsg +call. This is often not needed. In each message the kernel returns not +a single value, but a range. It coalesces consecutive notifications +while one is outstanding for reception on the error queue. + +When a new notification is about to be queued, it checks whether the +new value extends the range of the notification at the tail of the +queue. If so, it drops the new notification packet and instead increases +the range upper value of the outstanding notification. + +For protocols that acknowledge data in-order, like TCP, each +notification can be squashed into the previous one, so that no more +than one notification is outstanding at any one point. + +Ordered delivery is the common case, but not guaranteed. Notifications +may arrive out of order on retransmission and socket teardown. + + +Notification Parsing +~~~~~~~~~~~~~~~~~~~~ + +The below snippet demonstrates how to parse the control message: the +read_notification() call in the previous snippet. A notification +is encoded in the standard error format, sock_extended_err. + +The level and type fields in the control data are protocol family +specific, IP_RECVERR or IPV6_RECVERR. + +Error origin is the new type SO_EE_ORIGIN_ZEROCOPY. ee_errno is zero, +as explained before, to avoid blocking read and write system calls on +the socket. + +The 32-bit notification range is encoded as [ee_info, ee_data]. This +range is inclusive. Other fields in the struct must be treated as +undefined, bar for ee_code, as discussed below. + +:: + + struct sock_extended_err *serr; + struct cmsghdr *cm; + + cm = CMSG_FIRSTHDR(msg); + if (cm->cmsg_level != SOL_IP && + cm->cmsg_type != IP_RECVERR) + error(1, 0, "cmsg"); + + serr = (void *) CMSG_DATA(cm); + if (serr->ee_errno != 0 || + serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) + error(1, 0, "serr"); + + printf("completed: %u..%u\n", serr->ee_info, serr->ee_data); + + +Deferred copies +~~~~~~~~~~~~~~~ + +Passing flag MSG_ZEROCOPY is a hint to the kernel to apply copy +avoidance, and a contract that the kernel will queue a completion +notification. It is not a guarantee that the copy is elided. + +Copy avoidance is not always feasible. Devices that do not support +scatter-gather I/O cannot send packets made up of kernel generated +protocol headers plus zerocopy user data. A packet may need to be +converted to a private copy of data deep in the stack, say to compute +a checksum. + +In all these cases, the kernel returns a completion notification when +it releases its hold on the shared pages. That notification may arrive +before the (copied) data is fully transmitted. A zerocopy completion +notification is not a transmit completion notification, therefore. + +Deferred copies can be more expensive than a copy immediately in the +system call, if the data is no longer warm in the cache. The process +also incurs notification processing cost for no benefit. For this +reason, the kernel signals if data was completed with a copy, by +setting flag SO_EE_CODE_ZEROCOPY_COPIED in field ee_code on return. +A process may use this signal to stop passing flag MSG_ZEROCOPY on +subsequent requests on the same socket. + + +Implementation +============== + +Loopback +-------- + +Data sent to local sockets can be queued indefinitely if the receive +process does not read its socket. Unbound notification latency is not +acceptable. For this reason all packets generated with MSG_ZEROCOPY +that are looped to a local socket will incur a deferred copy. This +includes looping onto packet sockets (e.g., tcpdump) and tun devices. + + +Testing +======= + +More realistic example code can be found in the kernel source under +tools/testing/selftests/net/msg_zerocopy.c. + +Be cognizant of the loopback constraint. The test can be run between +a pair of hosts. But if run between a local pair of processes, for +instance when run with msg_zerocopy.sh between a veth pair across +namespaces, the test will not show any improvement. For testing, the +loopback restriction can be temporarily relaxed by making +skb_orphan_frags_rx identical to skb_orphan_frags. diff --git a/Documentation/networking/netdev-FAQ.txt b/Documentation/networking/netdev-FAQ.txt index 247a30ba8e1797f93e22d9c4a54cc8ec81ec5e88..cfc66ea72329ba4d953da900bec39e3c0c19d70a 100644 --- a/Documentation/networking/netdev-FAQ.txt +++ b/Documentation/networking/netdev-FAQ.txt @@ -111,6 +111,14 @@ A: Generally speaking, the patches get triaged quickly (in less than 48h). patch is a good way to ensure your patch is ignored or pushed to the bottom of the priority list. +Q: I submitted multiple versions of the patch series, should I directly update + patchwork for the previous versions of these patch series? + +A: No, please don't interfere with the patch status on patchwork, leave it to + the maintainer to figure out what is the most recent and current version that + should be applied. If there is any doubt, the maintainer will reply and ask + what should be done. + Q: How can I tell what patches are queued up for backporting to the various stable releases? diff --git a/Documentation/networking/netvsc.txt b/Documentation/networking/netvsc.txt new file mode 100644 index 0000000000000000000000000000000000000000..93560fb1170a6cb77b7882a3105323dc0d7341b4 --- /dev/null +++ b/Documentation/networking/netvsc.txt @@ -0,0 +1,75 @@ +Hyper-V network driver +====================== + +Compatibility +============= + +This driver is compatible with Windows Server 2012 R2, 2016 and +Windows 10. + +Features +======== + + Checksum offload + ---------------- + The netvsc driver supports checksum offload as long as the + Hyper-V host version does. Windows Server 2016 and Azure + support checksum offload for TCP and UDP for both IPv4 and + IPv6. Windows Server 2012 only supports checksum offload for TCP. + + Receive Side Scaling + -------------------- + Hyper-V supports receive side scaling. For TCP, packets are + distributed among available queues based on IP address and port + number. + + For UDP, we can switch UDP hash level between L3 and L4 by ethtool + command. UDP over IPv4 and v6 can be set differently. The default + hash level is L4. We currently only allow switching TX hash level + from within the guests. + + On Azure, fragmented UDP packets have high loss rate with L4 + hashing. Using L3 hashing is recommended in this case. + + For example, for UDP over IPv4 on eth0: + To include UDP port numbers in hashing: + ethtool -N eth0 rx-flow-hash udp4 sdfn + To exclude UDP port numbers in hashing: + ethtool -N eth0 rx-flow-hash udp4 sd + To show UDP hash level: + ethtool -n eth0 rx-flow-hash udp4 + + Generic Receive Offload, aka GRO + -------------------------------- + The driver supports GRO and it is enabled by default. GRO coalesces + like packets and significantly reduces CPU usage under heavy Rx + load. + + SR-IOV support + -------------- + Hyper-V supports SR-IOV as a hardware acceleration option. If SR-IOV + is enabled in both the vSwitch and the guest configuration, then the + Virtual Function (VF) device is passed to the guest as a PCI + device. In this case, both a synthetic (netvsc) and VF device are + visible in the guest OS and both NIC's have the same MAC address. + + The VF is enslaved by netvsc device. The netvsc driver will transparently + switch the data path to the VF when it is available and up. + Network state (addresses, firewall, etc) should be applied only to the + netvsc device; the slave device should not be accessed directly in + most cases. The exceptions are if some special queue discipline or + flow direction is desired, these should be applied directly to the + VF slave device. + + Receive Buffer + -------------- + Packets are received into a receive area which is created when device + is probed. The receive area is broken into MTU sized chunks and each may + contain one or more packets. The number of receive sections may be changed + via ethtool Rx ring parameters. + + There is a similar send buffer which is used to aggregate packets for sending. + The send area is broken into chunks of 6144 bytes, each of section may + contain one or more packets. The send buffer is an optimization, the driver + will use slower method to handle very large packets or if the send buffer + area is exhausted. diff --git a/Documentation/networking/nf_conntrack-sysctl.txt b/Documentation/networking/nf_conntrack-sysctl.txt index 497d668288f95f98d15c3f0057656fb5a5726c30..433b6724797ad7e9476f041c7f0e2dcd77ca8579 100644 --- a/Documentation/networking/nf_conntrack-sysctl.txt +++ b/Documentation/networking/nf_conntrack-sysctl.txt @@ -96,17 +96,6 @@ nf_conntrack_max - INTEGER Size of connection tracking table. Default value is nf_conntrack_buckets value * 4. -nf_conntrack_default_on - BOOLEAN - 0 - don't register conntrack in new net namespaces - 1 - register conntrack in new net namespaces (default) - - This controls wheter newly created network namespaces have connection - tracking enabled by default. It will be enabled automatically - regardless of this setting if the new net namespace requires - connection tracking, e.g. when NAT rules are created. - This setting is only visible in initial user namespace, it has no - effect on existing namespaces. - nf_conntrack_tcp_be_liberal - BOOLEAN 0 - disabled (default) not 0 - enabled diff --git a/Documentation/networking/rmnet.txt b/Documentation/networking/rmnet.txt new file mode 100644 index 0000000000000000000000000000000000000000..6b341eaf206264b3db88d9cd1d28da756979719b --- /dev/null +++ b/Documentation/networking/rmnet.txt @@ -0,0 +1,82 @@ +1. Introduction + +rmnet driver is used for supporting the Multiplexing and aggregation +Protocol (MAP). This protocol is used by all recent chipsets using Qualcomm +Technologies, Inc. modems. + +This driver can be used to register onto any physical network device in +IP mode. Physical transports include USB, HSIC, PCIe and IP accelerator. + +Multiplexing allows for creation of logical netdevices (rmnet devices) to +handle multiple private data networks (PDN) like a default internet, tethering, +multimedia messaging service (MMS) or IP media subsystem (IMS). Hardware sends +packets with MAP headers to rmnet. Based on the multiplexer id, rmnet +routes to the appropriate PDN after removing the MAP header. + +Aggregation is required to achieve high data rates. This involves hardware +sending aggregated bunch of MAP frames. rmnet driver will de-aggregate +these MAP frames and send them to appropriate PDN's. + +2. Packet format + +a. MAP packet (data / control) + +MAP header has the same endianness of the IP packet. + +Packet format - + +Bit 0 1 2-7 8 - 15 16 - 31 +Function Command / Data Reserved Pad Multiplexer ID Payload length +Bit 32 - x +Function Raw Bytes + +Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command +or data packet. Control packet is used for transport level flow control. Data +packets are standard IP packets. + +Reserved bits are usually zeroed out and to be ignored by receiver. + +Padding is number of bytes to be added for 4 byte alignment if required by +hardware. + +Multiplexer ID is to indicate the PDN on which data has to be sent. + +Payload length includes the padding length but does not include MAP header +length. + +b. MAP packet (command specific) + +Bit 0 1 2-7 8 - 15 16 - 31 +Function Command Reserved Pad Multiplexer ID Payload length +Bit 32 - 39 40 - 45 46 - 47 48 - 63 +Function Command name Reserved Command Type Reserved +Bit 64 - 95 +Function Transaction ID +Bit 96 - 127 +Function Command data + +Command 1 indicates disabling flow while 2 is enabling flow + +Command types - +0 for MAP command request +1 is to acknowledge the receipt of a command +2 is for unsupported commands +3 is for error during processing of commands + +c. Aggregation + +Aggregation is multiple MAP packets (can be data or command) delivered to +rmnet in a single linear skb. rmnet will process the individual +packets and either ACK the MAP command or deliver the IP packet to the +network stack as needed + +MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding.... +MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad... + +3. Userspace configuration + +rmnet userspace configuration is done through netlink library librmnetctl +and command line utility rmnetcli. Utility is hosted in codeaurora forum git. +The driver uses rtnl_link_ops for communication. + +https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/dataservices/tree/rmnetctl diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt index 8c70ba5dee4d0072da0ac8666d987248758afa0f..810620153a44c0296f40dcffcb0196e571dc2a60 100644 --- a/Documentation/networking/rxrpc.txt +++ b/Documentation/networking/rxrpc.txt @@ -818,10 +818,15 @@ The kernel interface functions are as follows: (*) Send data through a call. + typedef void (*rxrpc_notify_end_tx_t)(struct sock *sk, + unsigned long user_call_ID, + struct sk_buff *skb); + int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, struct msghdr *msg, - size_t len); + size_t len, + rxrpc_notify_end_tx_t notify_end_rx); This is used to supply either the request part of a client call or the reply part of a server call. msg.msg_iovlen and msg.msg_iov specify the @@ -832,6 +837,11 @@ The kernel interface functions are as follows: The msg must not specify a destination address, control data or any flags other than MSG_MORE. len is the total amount of data to transmit. + notify_end_rx can be NULL or it can be used to specify a function to be + called when the call changes state to end the Tx phase. This function is + called with the call-state spinlock held to prevent any reply or final ACK + from being delivered first. + (*) Receive data from a call. int rxrpc_kernel_recv_data(struct socket *sock, @@ -965,6 +975,51 @@ The kernel interface functions are as follows: size should be set when the call is begun. tx_total_len may not be less than zero. + (*) Check to see the completion state of a call so that the caller can assess + whether it needs to be retried. + + enum rxrpc_call_completion { + RXRPC_CALL_SUCCEEDED, + RXRPC_CALL_REMOTELY_ABORTED, + RXRPC_CALL_LOCALLY_ABORTED, + RXRPC_CALL_LOCAL_ERROR, + RXRPC_CALL_NETWORK_ERROR, + }; + + int rxrpc_kernel_check_call(struct socket *sock, struct rxrpc_call *call, + enum rxrpc_call_completion *_compl, + u32 *_abort_code); + + On return, -EINPROGRESS will be returned if the call is still ongoing; if + it is finished, *_compl will be set to indicate the manner of completion, + *_abort_code will be set to any abort code that occurred. 0 will be + returned on a successful completion, -ECONNABORTED will be returned if the + client failed due to a remote abort and anything else will return an + appropriate error code. + + The caller should look at this information to decide if it's worth + retrying the call. + + (*) Retry a client call. + + int rxrpc_kernel_retry_call(struct socket *sock, + struct rxrpc_call *call, + struct sockaddr_rxrpc *srx, + struct key *key); + + This attempts to partially reinitialise a call and submit it again whilst + reusing the original call's Tx queue to avoid the need to repackage and + re-encrypt the data to be sent. call indicates the call to retry, srx the + new address to send it to and key the encryption key to use for signing or + encrypting the packets. + + For this to work, the first Tx data packet must still be in the transmit + queue, and currently this is only permitted for local and network errors + and the call must not have been aborted. Any partially constructed Tx + packet is left as is and can continue being filled afterwards. + + It returns 0 if the call was requeued and an error otherwise. + ======================= CONFIGURABLE PARAMETERS diff --git a/Documentation/networking/strparser.txt b/Documentation/networking/strparser.txt index a0bf573dfa618b2700603f4590ecd9cc72f35e52..13081b3decefa834824b544182d0986e83bc50b4 100644 --- a/Documentation/networking/strparser.txt +++ b/Documentation/networking/strparser.txt @@ -1,45 +1,107 @@ -Stream Parser -------------- +Stream Parser (strparser) + +Introduction +============ The stream parser (strparser) is a utility that parses messages of an -application layer protocol running over a TCP connection. The stream +application layer protocol running over a data stream. The stream parser works in conjunction with an upper layer in the kernel to provide kernel support for application layer messages. For instance, Kernel Connection Multiplexor (KCM) uses the Stream Parser to parse messages using a BPF program. +The strparser works in one of two modes: receive callback or general +mode. + +In receive callback mode, the strparser is called from the data_ready +callback of a TCP socket. Messages are parsed and delivered as they are +received on the socket. + +In general mode, a sequence of skbs are fed to strparser from an +outside source. Message are parsed and delivered as the sequence is +processed. This modes allows strparser to be applied to arbitrary +streams of data. + Interface ---------- +========= The API includes a context structure, a set of callbacks, utility -functions, and a data_ready function. The callbacks include -a parse_msg function that is called to perform parsing (e.g. -BPF parsing in case of KCM), and a rcv_msg function that is called -when a full message has been completed. +functions, and a data_ready function for receive callback mode. The +callbacks include a parse_msg function that is called to perform +parsing (e.g. BPF parsing in case of KCM), and a rcv_msg function +that is called when a full message has been completed. + +Functions +========= + +strp_init(struct strparser *strp, struct sock *sk, + const struct strp_callbacks *cb) + + Called to initialize a stream parser. strp is a struct of type + strparser that is allocated by the upper layer. sk is the TCP + socket associated with the stream parser for use with receive + callback mode; in general mode this is set to NULL. Callbacks + are called by the stream parser (the callbacks are listed below). + +void strp_pause(struct strparser *strp) + + Temporarily pause a stream parser. Message parsing is suspended + and no new messages are delivered to the upper layer. + +void strp_pause(struct strparser *strp) + + Unpause a paused stream parser. + +void strp_stop(struct strparser *strp); + + strp_stop is called to completely stop stream parser operations. + This is called internally when the stream parser encounters an + error, and it is called from the upper layer to stop parsing + operations. + +void strp_done(struct strparser *strp); + + strp_done is called to release any resources held by the stream + parser instance. This must be called after the stream processor + has been stopped. -A stream parser can be instantiated for a TCP connection. This is done -by: +int strp_process(struct strparser *strp, struct sk_buff *orig_skb, + unsigned int orig_offset, size_t orig_len, + size_t max_msg_size, long timeo) -strp_init(struct strparser *strp, struct sock *csk, - struct strp_callbacks *cb) + strp_process is called in general mode for a stream parser to + parse an sk_buff. The number of bytes processed or a negative + error number is returned. Note that strp_process does not + consume the sk_buff. max_msg_size is maximum size the stream + parser will parse. timeo is timeout for completing a message. -strp is a struct of type strparser that is allocated by the upper layer. -csk is the TCP socket associated with the stream parser. Callbacks are -called by the stream parser. +void strp_data_ready(struct strparser *strp); + + The upper layer calls strp_tcp_data_ready when data is ready on + the lower socket for strparser to process. This should be called + from a data_ready callback that is set on the socket. Note that + maximum messages size is the limit of the receive socket + buffer and message timeout is the receive timeout for the socket. + +void strp_check_rcv(struct strparser *strp); + + strp_check_rcv is called to check for new messages on the socket. + This is normally called at initialization of a stream parser + instance or after strp_unpause. Callbacks ---------- +========= -There are four callbacks: +There are six callbacks: int (*parse_msg)(struct strparser *strp, struct sk_buff *skb); parse_msg is called to determine the length of the next message in the stream. The upper layer must implement this function. It should parse the sk_buff as containing the headers for the - next application layer messages in the stream. + next application layer message in the stream. - The skb->cb in the input skb is a struct strp_rx_msg. Only + The skb->cb in the input skb is a struct strp_msg. Only the offset field is relevant in parse_msg and gives the offset where the message starts in the skb. @@ -50,26 +112,41 @@ int (*parse_msg)(struct strparser *strp, struct sk_buff *skb); -ESTRPIPE : current message should not be processed by the kernel, return control of the socket to userspace which can proceed to read the messages itself - other < 0 : Error is parsing, give control back to userspace + other < 0 : Error in parsing, give control back to userspace assuming that synchronization is lost and the stream is unrecoverable (application expected to close TCP socket) In the case that an error is returned (return value is less than - zero) the stream parser will set the error on TCP socket and wake - it up. If parse_msg returned -ESTRPIPE and the stream parser had - previously read some bytes for the current message, then the error - set on the attached socket is ENODATA since the stream is - unrecoverable in that case. + zero) and the parser is in receive callback mode, then it will set + the error on TCP socket and wake it up. If parse_msg returned + -ESTRPIPE and the stream parser had previously read some bytes for + the current message, then the error set on the attached socket is + ENODATA since the stream is unrecoverable in that case. + +void (*lock)(struct strparser *strp) + + The lock callback is called to lock the strp structure when + the strparser is performing an asynchronous operation (such as + processing a timeout). In receive callback mode the default + function is to lock_sock for the associated socket. In general + mode the callback must be set appropriately. + +void (*unlock)(struct strparser *strp) + + The unlock callback is called to release the lock obtained + by the lock callback. In receive callback mode the default + function is release_sock for the associated socket. In general + mode the callback must be set appropriately. void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); rcv_msg is called when a full message has been received and is queued. The callee must consume the sk_buff; it can call strp_pause to prevent any further messages from being - received in rcv_msg (see strp_pause below). This callback + received in rcv_msg (see strp_pause above). This callback must be set. - The skb->cb in the input skb is a struct strp_rx_msg. This + The skb->cb in the input skb is a struct strp_msg. This struct contains two fields: offset and full_len. Offset is where the message starts in the skb, and full_len is the the length of the message. skb->len - offset may be greater @@ -78,59 +155,53 @@ void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); int (*read_sock_done)(struct strparser *strp, int err); read_sock_done is called when the stream parser is done reading - the TCP socket. The stream parser may read multiple messages - in a loop and this function allows cleanup to occur when existing - the loop. If the callback is not set (NULL in strp_init) a - default function is used. + the TCP socket in receive callback mode. The stream parser may + read multiple messages in a loop and this function allows cleanup + to occur when exiting the loop. If the callback is not set (NULL + in strp_init) a default function is used. void (*abort_parser)(struct strparser *strp, int err); This function is called when stream parser encounters an error - in parsing. The default function stops the stream parser for the - TCP socket and sets the error in the socket. The default function - can be changed by setting the callback to non-NULL in strp_init. + in parsing. The default function stops the stream parser and + sets the error in the socket if the parser is in receive callback + mode. The default function can be changed by setting the callback + to non-NULL in strp_init. -Functions ---------- +Statistics +========== -The upper layer calls strp_tcp_data_ready when data is ready on the lower -socket for strparser to process. This should be called from a data_ready -callback that is set on the socket. +Various counters are kept for each stream parser instance. These are in +the strp_stats structure. strp_aggr_stats is a convenience structure for +accumulating statistics for multiple stream parser instances. +save_strp_stats and aggregate_strp_stats are helper functions to save +and aggregate statistics. -strp_stop is called to completely stop stream parser operations. This -is called internally when the stream parser encounters an error, and -it is called from the upper layer when unattaching a TCP socket. +Message assembly limits +======================= -strp_done is called to unattach the stream parser from the TCP socket. -This must be called after the stream processor has be stopped. +The stream parser provide mechanisms to limit the resources consumed by +message assembly. -strp_check_rcv is called to check for new messages on the socket. This -is normally called at initialization of the a stream parser instance -of after strp_unpause. +A timer is set when assembly starts for a new message. In receive +callback mode the message timeout is taken from rcvtime for the +associated TCP socket. In general mode, the timeout is passed as an +argument in strp_process. If the timer fires before assembly completes +the stream parser is aborted and the ETIMEDOUT error is set on the TCP +socket if in receive callback mode. -Statistics ----------- +In receive callback mode, message length is limited to the receive +buffer size of the associated TCP socket. If the length returned by +parse_msg is greater than the socket buffer size then the stream parser +is aborted with EMSGSIZE error set on the TCP socket. Note that this +makes the maximum size of receive skbuffs for a socket with a stream +parser to be 2*sk_rcvbuf of the TCP socket. -Various counters are kept for each stream parser for a TCP socket. -These are in the strp_stats structure. strp_aggr_stats is a convenience -structure for accumulating statistics for multiple stream parser -instances. save_strp_stats and aggregate_strp_stats are helper functions -to save and aggregate statistics. +In general mode the message length limit is passed in as an argument +to strp_process. -Message assembly limits ------------------------ +Author +====== -The stream parser provide mechanisms to limit the resources consumed by -message assembly. +Tom Herbert (tom@quantonium.net) -A timer is set when assembly starts for a new message. The message -timeout is taken from rcvtime for the associated TCP socket. If the -timer fires before assembly completes the stream parser is aborted -and the ETIMEDOUT error is set on the TCP socket. - -Message length is limited to the receive buffer size of the associated -TCP socket. If the length returned by parse_msg is greater than -the socket buffer size then the stream parser is aborted with -EMSGSIZE error set on the TCP socket. Note that this makes the -maximum size of receive skbuffs for a socket with a stream parser -to be 2*sk_rcvbuf of the TCP socket. diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt index 3e7b946dea2778441ce0599643535188699e16ca..82236a17b5e65198be004d2cdd6a7c5bd8a9b7d4 100644 --- a/Documentation/networking/switchdev.txt +++ b/Documentation/networking/switchdev.txt @@ -13,42 +13,42 @@ an example setup using a data-center-class switch ASIC chip. Other setups with SR-IOV or soft switches, such as OVS, are possible. -                             User-space tools - -       user space                   | -      +-------------------------------------------------------------------+ -       kernel                       | Netlink -                                    | -                     +--------------+-------------------------------+ -                     |         Network stack                        | -                     |           (Linux)                            | -                     |                                              | -                     +----------------------------------------------+ + User-space tools + + user space | + +-------------------------------------------------------------------+ + kernel | Netlink + | + +--------------+-------------------------------+ + | Network stack | + | (Linux) | + | | + +----------------------------------------------+ sw1p2 sw1p4 sw1p6 -                      sw1p1  + sw1p3 +  sw1p5 +         eth1 -                        +    |    +    |    +    |            + -                        |    |    |    |    |    |            | -                     +--+----+----+----+-+--+----+---+  +-----+-----+ -                     |         Switch driver         |  |    mgmt   | -                     |        (this document)        |  |   driver  | -                     |                               |  |           | -                     +--------------+----------------+  +-----------+ -                                    | -       kernel                       | HW bus (eg PCI) -      +-------------------------------------------------------------------+ -       hardware                     | -                     +--------------+---+------------+ -                     |         Switch device (sw1)   | -                     |  +----+                       +--------+ -                     |  |    v offloaded data path   | mgmt port -                     |  |    |                       | -                     +--|----|----+----+----+----+---+ -                        |    |    |    |    |    | -                        +    +    +    +    +    + -                       p1   p2   p3   p4   p5   p6 - -                             front-panel ports + sw1p1 + sw1p3 + sw1p5 + eth1 + + | + | + | + + | | | | | | | + +--+----+----+----+----+----+---+ +-----+-----+ + | Switch driver | | mgmt | + | (this document) | | driver | + | | | | + +--------------+----------------+ +-----------+ + | + kernel | HW bus (eg PCI) + +-------------------------------------------------------------------+ + hardware | + +--------------+----------------+ + | Switch device (sw1) | + | +----+ +--------+ + | | v offloaded data path | mgmt port + | | | | + +--|----|----+----+----+----+---+ + | | | | | | + + + + + + + + p1 p2 p3 p4 p5 p6 + + front-panel ports Fig 1. @@ -228,7 +228,7 @@ Learning on the device port should be enabled, as well as learning_sync: bridge link set dev DEV learning on self bridge link set dev DEV learning_sync on self -Learning_sync attribute enables syncing of the learned/forgotton FDB entry to +Learning_sync attribute enables syncing of the learned/forgotten FDB entry to the bridge's FDB. It's possible, but not optimal, to enable learning on the device port and on the bridge port, and disable learning_sync. @@ -245,7 +245,7 @@ the responsibility of the port driver/device to age out these entries. If the port device supports ageing, when the FDB entry expires, it will notify the driver which in turn will notify the bridge with SWITCHDEV_FDB_DEL. If the device does not support ageing, the driver can simulate ageing using a -garbage collection timer to monitor FBD entries. Expired entries will be +garbage collection timer to monitor FDB entries. Expired entries will be notified to the bridge using SWITCHDEV_FDB_DEL. See rocker driver for example of driver running ageing timer. diff --git a/Documentation/nvmem/nvmem.txt b/Documentation/nvmem/nvmem.txt index dbd40d879239456b6b17f815b6c1d86263d0c2e5..8d8d8f58f96fbd2420a8c2b00a9988259220700a 100644 --- a/Documentation/nvmem/nvmem.txt +++ b/Documentation/nvmem/nvmem.txt @@ -112,7 +112,7 @@ take nvmem_device as parameter. 5. Releasing a reference to the NVMEM ===================================== -When a consumers no longer needs the NVMEM, it has to release the reference +When a consumer no longer needs the NVMEM, it has to release the reference to the NVMEM it has obtained using the APIs mentioned in the above section. The NVMEM framework provides 2 APIs to release a reference to the NVMEM. diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 0fde3dcf077a302eb24ea6d8fd8df65c4b252d8e..625549d4c74a09642d72bce75387c15348406223 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -435,7 +435,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: PM status to 'suspended' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than - zero) + zero); it will fail and return an error code if the device has a child + which is active and the 'power.ignore_children' flag is unset bool pm_runtime_active(struct device *dev); - return true if the device's runtime PM status is 'active' or its diff --git a/Documentation/power/states.txt b/Documentation/power/states.txt deleted file mode 100644 index bc4548245a2431349b3d24655ab3b73794b7a10a..0000000000000000000000000000000000000000 --- a/Documentation/power/states.txt +++ /dev/null @@ -1,125 +0,0 @@ -System Power Management Sleep States - -(C) 2014 Intel Corp., Rafael J. Wysocki - -The kernel supports up to four system sleep states generically, although three -of them depend on the platform support code to implement the low-level details -for each state. - -The states are represented by strings that can be read or written to the -/sys/power/state file. Those strings may be "mem", "standby", "freeze" and -"disk", where the last three always represent Power-On Suspend (if supported), -Suspend-To-Idle and hibernation (Suspend-To-Disk), respectively. - -The meaning of the "mem" string is controlled by the /sys/power/mem_sleep file. -It contains strings representing the available modes of system suspend that may -be triggered by writing "mem" to /sys/power/state. These modes are "s2idle" -(Suspend-To-Idle), "shallow" (Power-On Suspend) and "deep" (Suspend-To-RAM). -The "s2idle" mode is always available, while the other ones are only available -if supported by the platform (if not supported, the strings representing them -are not present in /sys/power/mem_sleep). The string representing the suspend -mode to be used subsequently is enclosed in square brackets. Writing one of -the other strings present in /sys/power/mem_sleep to it causes the suspend mode -to be used subsequently to change to the one represented by that string. - -Consequently, there are two ways to cause the system to go into the -Suspend-To-Idle sleep state. The first one is to write "freeze" directly to -/sys/power/state. The second one is to write "s2idle" to /sys/power/mem_sleep -and then to write "mem" to /sys/power/state. Similarly, there are two ways -to cause the system to go into the Power-On Suspend sleep state (the strings to -write to the control files in that case are "standby" or "shallow" and "mem", -respectively) if that state is supported by the platform. In turn, there is -only one way to cause the system to go into the Suspend-To-RAM state (write -"deep" into /sys/power/mem_sleep and "mem" into /sys/power/state). - -The default suspend mode (ie. the one to be used without writing anything into -/sys/power/mem_sleep) is either "deep" (if Suspend-To-RAM is supported) or -"s2idle", but it can be overridden by the value of the "mem_sleep_default" -parameter in the kernel command line. - -The properties of all of the sleep states are described below. - - -State: Suspend-To-Idle -ACPI state: S0 -Label: "s2idle" ("freeze") - -This state is a generic, pure software, light-weight, system sleep state. -It allows more energy to be saved relative to runtime idle by freezing user -space and putting all I/O devices into low-power states (possibly -lower-power than available at run time), such that the processors can -spend more time in their idle states. - -This state can be used for platforms without Power-On Suspend/Suspend-to-RAM -support, or it can be used in addition to Suspend-to-RAM to provide reduced -resume latency. It is always supported. - - -State: Standby / Power-On Suspend -ACPI State: S1 -Label: "shallow" ("standby") - -This state, if supported, offers moderate, though real, power savings, while -providing a relatively low-latency transition back to a working system. No -operating state is lost (the CPU retains power), so the system easily starts up -again where it left off. - -In addition to freezing user space and putting all I/O devices into low-power -states, which is done for Suspend-To-Idle too, nonboot CPUs are taken offline -and all low-level system functions are suspended during transitions into this -state. For this reason, it should allow more energy to be saved relative to -Suspend-To-Idle, but the resume latency will generally be greater than for that -state. - - -State: Suspend-to-RAM -ACPI State: S3 -Label: "deep" - -This state, if supported, offers significant power savings as everything in the -system is put into a low-power state, except for memory, which should be placed -into the self-refresh mode to retain its contents. All of the steps carried out -when entering Power-On Suspend are also carried out during transitions to STR. -Additional operations may take place depending on the platform capabilities. In -particular, on ACPI systems the kernel passes control to the BIOS (platform -firmware) as the last step during STR transitions and that usually results in -powering down some more low-level components that aren't directly controlled by -the kernel. - -System and device state is saved and kept in memory. All devices are suspended -and put into low-power states. In many cases, all peripheral buses lose power -when entering STR, so devices must be able to handle the transition back to the -"on" state. - -For at least ACPI, STR requires some minimal boot-strapping code to resume the -system from it. This may be the case on other platforms too. - - -State: Suspend-to-disk -ACPI State: S4 -Label: "disk" - -This state offers the greatest power savings, and can be used even in -the absence of low-level platform support for power management. This -state operates similarly to Suspend-to-RAM, but includes a final step -of writing memory contents to disk. On resume, this is read and memory -is restored to its pre-suspend state. - -STD can be handled by the firmware or the kernel. If it is handled by -the firmware, it usually requires a dedicated partition that must be -setup via another operating system for it to use. Despite the -inconvenience, this method requires minimal work by the kernel, since -the firmware will also handle restoring memory contents on resume. - -For suspend-to-disk, a mechanism called 'swsusp' (Swap Suspend) is used -to write memory contents to free swap space. swsusp has some restrictive -requirements, but should work in most cases. Some, albeit outdated, -documentation can be found in Documentation/power/swsusp.txt. -Alternatively, userspace can do most of the actual suspend to disk work, -see userland-swsusp.txt. - -Once memory state is written to disk, the system may either enter a -low-power state (like ACPI S4), or it may simply power down. Powering -down offers greater savings, and allows this mechanism to work on any -system. However, entering a real low-power state allows the user to -trigger wake up events (e.g. pressing a key or opening a laptop lid). diff --git a/Documentation/pps/pps.txt b/Documentation/pps/pps.txt index 1fdbd544721639a6dc7a48576e0e3f1066873729..99f5d8c4c6525b6e2bd462f5f2b14150424d1c02 100644 --- a/Documentation/pps/pps.txt +++ b/Documentation/pps/pps.txt @@ -48,12 +48,12 @@ problem: time_pps_create(). This implies that the source has a /dev/... entry. This assumption is -ok for the serial and parallel port, where you can do something +OK for the serial and parallel port, where you can do something useful besides(!) the gathering of timestamps as it is the central -task for a PPS-API. But this assumption does not work for a single +task for a PPS API. But this assumption does not work for a single purpose GPIO line. In this case even basic file-related functionality (like read() and write()) makes no sense at all and should not be a -precondition for the use of a PPS-API. +precondition for the use of a PPS API. The problem can be simply solved if you consider that a PPS source is not always connected with a GPS data source. @@ -88,13 +88,13 @@ Coding example -------------- To register a PPS source into the kernel you should define a struct -pps_source_info_s as follows: +pps_source_info as follows: static struct pps_source_info pps_ktimer_info = { .name = "ktimer", .path = "", - .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \ - PPS_ECHOASSERT | \ + .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | + PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC, .echo = pps_ktimer_echo, .owner = THIS_MODULE, @@ -108,13 +108,13 @@ initialization routine as follows: The pps_register_source() prototype is: - int pps_register_source(struct pps_source_info_s *info, int default_params) + int pps_register_source(struct pps_source_info *info, int default_params) where "info" is a pointer to a structure that describes a particular PPS source, "default_params" tells the system what the initial default parameters for the device should be (it is obvious that these parameters must be a subset of ones defined in the struct -pps_source_info_s which describe the capabilities of the driver). +pps_source_info which describe the capabilities of the driver). Once you have registered a new PPS source into the system you can signal an assert event (for example in the interrupt handler routine) @@ -142,8 +142,10 @@ If the SYSFS filesystem is enabled in the kernel it provides a new class: Every directory is the ID of a PPS sources defined in the system and inside you find several files: - $ ls /sys/class/pps/pps0/ - assert clear echo mode name path subsystem@ uevent + $ ls -F /sys/class/pps/pps0/ + assert dev mode path subsystem@ + clear echo name power/ uevent + Inside each "assert" and "clear" file you can find the timestamp and a sequence number: @@ -154,32 +156,32 @@ sequence number: Where before the "#" is the timestamp in seconds; after it is the sequence number. Other files are: -* echo: reports if the PPS source has an echo function or not; + * echo: reports if the PPS source has an echo function or not; -* mode: reports available PPS functioning modes; + * mode: reports available PPS functioning modes; -* name: reports the PPS source's name; + * name: reports the PPS source's name; -* path: reports the PPS source's device path, that is the device the - PPS source is connected to (if it exists). + * path: reports the PPS source's device path, that is the device the + PPS source is connected to (if it exists). Testing the PPS support ----------------------- In order to test the PPS support even without specific hardware you can use -the ktimer driver (see the client subsection in the PPS configuration menu) +the pps-ktimer driver (see the client subsection in the PPS configuration menu) and the userland tools available in your distribution's pps-tools package, -http://linuxpps.org , or https://github.com/ago/pps-tools . +http://linuxpps.org , or https://github.com/redlab-i/pps-tools. -Once you have enabled the compilation of ktimer just modprobe it (if +Once you have enabled the compilation of pps-ktimer just modprobe it (if not statically compiled): - # modprobe ktimer + # modprobe pps-ktimer and the run ppstest as follow: - $ ./ppstest /dev/pps0 + $ ./ppstest /dev/pps1 trying PPS source "/dev/pps1" found PPS source "/dev/pps1" ok, found 1 source(s), now start fetching data... @@ -187,7 +189,7 @@ and the run ppstest as follow: source 0 - assert 1186592700.388931295, sequence: 365 - clear 0.000000000, sequence: 0 source 0 - assert 1186592701.389032765, sequence: 366 - clear 0.000000000, sequence: 0 -Please, note that to compile userland programs you need the file timepps.h . +Please note that to compile userland programs, you need the file timepps.h. This is available in the pps-tools repository mentioned above. diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 65ea5915178b4b9842474b7908d06660444aae34..361789df51ecf58d5083436792588d2f12faa7f2 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -58,20 +58,33 @@ Symbols/Function Pointers %ps versatile_init %pB prev_fn_of_versatile_init+0x88/0x88 -For printing symbols and function pointers. The ``S`` and ``s`` specifiers -result in the symbol name with (``S``) or without (``s``) offsets. Where -this is used on a kernel without KALLSYMS - the symbol address is -printed instead. +The ``F`` and ``f`` specifiers are for printing function pointers, +for example, f->func, &gettimeofday. They have the same result as +``S`` and ``s`` specifiers. But they do an extra conversion on +ia64, ppc64 and parisc64 architectures where the function pointers +are actually function descriptors. + +The ``S`` and ``s`` specifiers can be used for printing symbols +from direct addresses, for example, __builtin_return_address(0), +(void *)regs->ip. They result in the symbol name with (``S``) or +without (``s``) offsets. If KALLSYMS are disabled then the symbol +address is printed instead. The ``B`` specifier results in the symbol name with offsets and should be used when printing stack backtraces. The specifier takes into consideration the effect of compiler optimisations which may occur when tail-call``s are used and marked with the noreturn GCC attribute. -On ia64, ppc64 and parisc64 architectures function pointers are -actually function descriptors which must first be resolved. The ``F`` and -``f`` specifiers perform this resolution and then provide the same -functionality as the ``S`` and ``s`` specifiers. +Examples:: + + printk("Going to call: %pF\n", gettimeofday); + printk("Going to call: %pF\n", p->func); + printk("%s: called from %pS\n", __func__, (void *)_RET_IP_); + printk("%s: called from %pS\n", __func__, + (void *)__builtin_return_address(0)); + printk("Faulted at %pS\n", (void *)regs->ip); + printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack); + Kernel Pointers =============== diff --git a/Documentation/process/applying-patches.rst b/Documentation/process/applying-patches.rst index a0d058cc6d25a7c843c453e1d93147228b4f075e..dc2ddc3450442b5b8632b87ae21d8c6d43f46d10 100644 --- a/Documentation/process/applying-patches.rst +++ b/Documentation/process/applying-patches.rst @@ -6,9 +6,6 @@ Applying Patches To The Linux Kernel Original by: Jesper Juhl, August 2005 -Last update: - 2016-09-14 - .. note:: This document is obsolete. In most cases, rather than using ``patch`` @@ -344,7 +341,7 @@ possible. This is a good branch to run for people who want to help out testing development kernels but do not want to run some of the really experimental -stuff (such people should see the sections about -git and -mm kernels below). +stuff (such people should see the sections about -next and -mm kernels below). The -rc patches are not incremental, they apply to a base 4.x kernel, just like the 4.x.y patches described above. The kernel version before the -rcN @@ -380,44 +377,6 @@ Here are 3 examples of how to apply these patches:: $ mv linux-4.7.3 linux-4.8-rc5 # rename the kernel source dir -The -git kernels -================ - -These are daily snapshots of Linus' kernel tree (managed in a git -repository, hence the name). - -These patches are usually released daily and represent the current state of -Linus's tree. They are more experimental than -rc kernels since they are -generated automatically without even a cursory glance to see if they are -sane. - --git patches are not incremental and apply either to a base 4.x kernel or -a base 4.x-rc kernel -- you can see which from their name. -A patch named 4.7-git1 applies to the 4.7 kernel source and a patch -named 4.8-rc3-git2 applies to the source of the 4.8-rc3 kernel. - -Here are some examples of how to apply these patches:: - - # moving from 4.7 to 4.7-git1 - - $ cd ~/linux-4.7 # change to the kernel source dir - $ patch -p1 < ../patch-4.7-git1 # apply the 4.7-git1 patch - $ cd .. - $ mv linux-4.7 linux-4.7-git1 # rename the kernel source dir - - # moving from 4.7-git1 to 4.8-rc2-git3 - - $ cd ~/linux-4.7-git1 # change to the kernel source dir - $ patch -p1 -R < ../patch-4.7-git1 # revert the 4.7-git1 patch - # we now have a 4.7 kernel - $ patch -p1 < ../patch-4.8-rc2 # apply the 4.8-rc2 patch - # the kernel is now 4.8-rc2 - $ patch -p1 < ../patch-4.8-rc2-git3 # apply the 4.8-rc2-git3 patch - # the kernel is now 4.8-rc2-git3 - $ cd .. - $ mv linux-4.7-git1 linux-4.8-rc2-git3 # rename source dir - - The -mm patches and the linux-next tree ======================================= diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index adbb50ae52464b2879d4ed7efedfbd41123c85b9..560beaef5a7c83b99b69292943a1eb2732efccee 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -53,7 +53,7 @@ mcelog 0.6 mcelog --version iptables 1.4.2 iptables -V openssl & libcrypto 1.0.0 openssl version bc 1.06.95 bc --version -Sphinx\ [#f1]_ 1.2 sphinx-build --version +Sphinx\ [#f1]_ 1.3 sphinx-build --version ====================== =============== ======================================== .. [#f1] Sphinx is needed only to build the Kernel documentation @@ -309,18 +309,8 @@ Kernel documentation Sphinx ------ -The ReST markups currently used by the Documentation/ files are meant to be -built with ``Sphinx`` version 1.2 or upper. If you're desiring to build -PDF outputs, it is recommended to use version 1.4.6. - -.. note:: - - Please notice that, for PDF and LaTeX output, you'll also need ``XeLaTeX`` - version 3.14159265. Depending on the distribution, you may also need to - install a series of ``texlive`` packages that provide the minimal set of - functionalities required for ``XeLaTex`` to work. For PDF output you'll also - need ``convert(1)`` from ImageMagick (https://www.imagemagick.org). - +Please see :ref:`sphinx_install` in ``Documentation/doc-guide/sphinx.rst`` +for details about Sphinx requirements. Getting updated software ======================== diff --git a/Documentation/process/stable-kernel-rules.rst b/Documentation/process/stable-kernel-rules.rst index 61e9c78bd6d1d999033d11170ea6062337984a7e..36a2dded525b7a9b149c1f5d28d1bc19a46bceca 100644 --- a/Documentation/process/stable-kernel-rules.rst +++ b/Documentation/process/stable-kernel-rules.rst @@ -166,12 +166,12 @@ Trees - The queues of patches, for both completed versions and in progress versions can be found at: - http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git + https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git - The finalized and tagged releases of all stable kernels can be found in separate branches per version at: - http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git Review committee diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index 3e10719fee35d3795ba0baa2d1cf4efa5738b671..733478ade91b50efd098bbfd3cd6831cfa99fcc9 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -413,7 +413,7 @@ e-mail discussions. -11) Sign your work — the Developer's Certificate of Origin +11) Sign your work - the Developer's Certificate of Origin ---------------------------------------------------------- To improve tracking of who did what, especially with patches that can diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt index b8a8c70b0188d8fd8c45b554f5ca121a0f3f0654..c42a21b9904616859e9c706caf64423d9e9d7ef6 100644 --- a/Documentation/rbtree.txt +++ b/Documentation/rbtree.txt @@ -193,6 +193,39 @@ Example:: for (node = rb_first(&mytree); node; node = rb_next(node)) printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring); +Cached rbtrees +-------------- + +Computing the leftmost (smallest) node is quite a common task for binary +search trees, such as for traversals or users relying on a the particular +order for their own logic. To this end, users can use 'struct rb_root_cached' +to optimize O(logN) rb_first() calls to a simple pointer fetch avoiding +potentially expensive tree iterations. This is done at negligible runtime +overhead for maintanence; albeit larger memory footprint. + +Similar to the rb_root structure, cached rbtrees are initialized to be +empty via: + + struct rb_root_cached mytree = RB_ROOT_CACHED; + +Cached rbtree is simply a regular rb_root with an extra pointer to cache the +leftmost node. This allows rb_root_cached to exist wherever rb_root does, +which permits augmented trees to be supported as well as only a few extra +interfaces: + + struct rb_node *rb_first_cached(struct rb_root_cached *tree); + void rb_insert_color_cached(struct rb_node *, struct rb_root_cached *, bool); + void rb_erase_cached(struct rb_node *node, struct rb_root_cached *); + +Both insert and erase calls have their respective counterpart of augmented +trees: + + void rb_insert_augmented_cached(struct rb_node *node, struct rb_root_cached *, + bool, struct rb_augment_callbacks *); + void rb_erase_augmented_cached(struct rb_node *, struct rb_root_cached *, + struct rb_augment_callbacks *); + + Support for Augmented rbtrees ----------------------------- diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst index 1648fa80b3bfddb59a0b6248e4ffbac90bdbb402..1266eeae45f69caeed72902d2507c3131de9a08f 100644 --- a/Documentation/security/keys/core.rst +++ b/Documentation/security/keys/core.rst @@ -16,17 +16,7 @@ The key service can be configured on by enabling: This document has the following sections: - - Key overview - - Key service overview - - Key access permissions - - SELinux support - - New procfs files - - Userspace system call interface - - Kernel services - - Notes on accessing payload contents - - Defining a key type - - Request-key callback service - - Garbage collection +.. contents:: :local: Key Overview @@ -443,7 +433,7 @@ The main syscalls are: /sbin/request-key will be invoked in an attempt to obtain a key. The callout_info string will be passed as an argument to the program. - See also Documentation/security/keys-request-key.txt. + See also Documentation/security/keys/request-key.rst. The keyctl syscall functions are: @@ -973,7 +963,7 @@ payload contents" for more information. If successful, the key will have been attached to the default keyring for implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. - See also Documentation/security/keys-request-key.txt. + See also Documentation/security/keys/request-key.rst. * To search for a key, passing auxiliary data to the upcaller, call:: diff --git a/Documentation/security/keys/request-key.rst b/Documentation/security/keys/request-key.rst index aba32784174c4e96ce46febb8b60a133a657760e..b2d16abaa9e9c2a416658a4cde83fcb2bc73d8b8 100644 --- a/Documentation/security/keys/request-key.rst +++ b/Documentation/security/keys/request-key.rst @@ -3,7 +3,7 @@ Key Request Service =================== The key request service is part of the key retention service (refer to -Documentation/security/keys.txt). This document explains more fully how +Documentation/security/core.rst). This document explains more fully how the requesting algorithm works. The process starts by either the kernel requesting a service by calling diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst index 7b503831bdeaf0dd40e1f04f46e835a8d2fa0680..3bb24e09a33299c7aa2a940f2a999c78859804bb 100644 --- a/Documentation/security/keys/trusted-encrypted.rst +++ b/Documentation/security/keys/trusted-encrypted.rst @@ -172,4 +172,4 @@ Other uses for trusted and encrypted keys, such as for disk and file encryption are anticipated. In particular the new format 'ecryptfs' has been defined in in order to use encrypted keys to mount an eCryptfs filesystem. More details about the usage can be found in the file -``Documentation/security/keys-ecryptfs.txt``. +``Documentation/security/keys/ecryptfs.rst``. diff --git a/Documentation/sphinx-static/theme_overrides.css b/Documentation/sphinx-static/theme_overrides.css index d5764a4de5a2cc7702936d10853f49f633d1d938..522b6d4c49d4cf64e055b9ecf821f1883365f3af 100644 --- a/Documentation/sphinx-static/theme_overrides.css +++ b/Documentation/sphinx-static/theme_overrides.css @@ -4,6 +4,17 @@ * */ +/* Interim: Code-blocks with line nos - lines and line numbers don't line up. + * see: https://github.com/rtfd/sphinx_rtd_theme/issues/419 + */ + +div[class^="highlight"] pre { + line-height: normal; +} +.rst-content .highlight > pre { + line-height: normal; +} + @media screen { /* content column @@ -56,6 +67,12 @@ font-family: "Courier New", Courier, monospace } + /* fix bottom margin of lists items */ + + .rst-content .section ul li:last-child, .rst-content .section ul li p:last-child { + margin-bottom: 12px; + } + /* inline literal: drop the borderbox, padding and red color */ code, .rst-content tt, .rst-content code { diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py index d15e07f36881bc5d20dc85332198cb4df8aa3acc..39aa9e8697ccf8f1ad3e0d7210294eff20bd9cb0 100644 --- a/Documentation/sphinx/kerneldoc.py +++ b/Documentation/sphinx/kerneldoc.py @@ -27,6 +27,7 @@ # Please make sure this works on both python2 and python3. # +import codecs import os import subprocess import sys @@ -88,13 +89,10 @@ class KernelDocDirective(Directive): try: env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() - # python2 needs conversion to unicode. - # python3 with universal_newlines=True returns strings. - if sys.version_info.major < 3: - out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') + out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) diff --git a/Documentation/sphinx/requirements.txt b/Documentation/sphinx/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..742be3e126194e27c18633ab5e556c005e5679f2 --- /dev/null +++ b/Documentation/sphinx/requirements.txt @@ -0,0 +1,3 @@ +docutils==0.12 +Sphinx==1.4.9 +sphinx_rtd_theme diff --git a/Documentation/static-keys.txt b/Documentation/static-keys.txt index b83dfa1c060293571d2d200ea3f5d5cb2adacbcd..ab16efe0c79d95fce558832c97ada5573c576816 100644 --- a/Documentation/static-keys.txt +++ b/Documentation/static-keys.txt @@ -149,6 +149,26 @@ static_branch_inc(), will change the branch back to true. Likewise, if the key is initialized false, a 'static_branch_inc()', will change the branch to true. And then a 'static_branch_dec()', will again make the branch false. +The state and the reference count can be retrieved with 'static_key_enabled()' +and 'static_key_count()'. In general, if you use these functions, they +should be protected with the same mutex used around the enable/disable +or increment/decrement function. + +Note that switching branches results in some locks being taken, +particularly the CPU hotplug lock (in order to avoid races against +CPUs being brought in the kernel whilst the kernel is getting +patched). Calling the static key API from within a hotplug notifier is +thus a sure deadlock recipe. In order to still allow use of the +functionnality, the following functions are provided: + + static_key_enable_cpuslocked() + static_key_disable_cpuslocked() + static_branch_enable_cpuslocked() + static_branch_disable_cpuslocked() + +These functions are *not* general purpose, and must only be used when +you really know that you're in the above context, and no other. + Where an array of keys is required, it can be defined as:: DEFINE_STATIC_KEY_ARRAY_TRUE(keys, count); diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index bac23c198360507dbc00db7ef106498666826495..694968c7523cc28620c8ac51a28a33dc1b14336e 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -61,6 +61,7 @@ show up in /proc/sys/kernel: - perf_cpu_time_max_percent - perf_event_paranoid - perf_event_max_stack +- perf_event_mlock_kb - perf_event_max_contexts_per_stack - pid_max - powersave-nap [ PPC only ] @@ -74,6 +75,7 @@ show up in /proc/sys/kernel: - reboot-cmd [ SPARC only ] - rtsig-max - rtsig-nr +- seccomp/ ==> Documentation/userspace-api/seccomp_filter.rst - sem - sem_next_id [ sysv ipc ] - sg-big-buff [ generic SCSI device (sg) ] @@ -654,7 +656,9 @@ Controls use of the performance events system by unprivileged users (without CAP_SYS_ADMIN). The default value is 2. -1: Allow use of (almost) all events by all users ->=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK + Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK +>=0: Disallow ftrace function tracepoint by users without CAP_SYS_ADMIN + Disallow raw tracepoint access by users without CAP_SYS_ADMIN >=1: Disallow CPU event access by users without CAP_SYS_ADMIN >=2: Disallow kernel profiling by users without CAP_SYS_ADMIN @@ -673,6 +677,14 @@ The default value is 127. ============================================================== +perf_event_mlock_kb: + +Control size of per-cpu ring buffer not counted agains mlock limit. + +The default value is 512 + 1 page + +============================================================== + perf_event_max_contexts_per_stack: Controls maximum number of stack frame context entries for diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index 14db18c970b1b048c0ecc50d75e10efb674715ca..b67044a2575f51b9d24f85b1a58a2fe6075b3312 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt @@ -35,9 +35,34 @@ Table : Subdirectories in /proc/sys/net bpf_jit_enable -------------- -This enables Berkeley Packet Filter Just in Time compiler. -Currently supported on x86_64 architecture, bpf_jit provides a framework -to speed packet filtering, the one used by tcpdump/libpcap for example. +This enables the BPF Just in Time (JIT) compiler. BPF is a flexible +and efficient infrastructure allowing to execute bytecode at various +hook points. It is used in a number of Linux kernel subsystems such +as networking (e.g. XDP, tc), tracing (e.g. kprobes, uprobes, tracepoints) +and security (e.g. seccomp). LLVM has a BPF back end that can compile +restricted C into a sequence of BPF instructions. After program load +through bpf(2) and passing a verifier in the kernel, a JIT will then +translate these BPF proglets into native CPU instructions. There are +two flavors of JITs, the newer eBPF JIT currently supported on: + - x86_64 + - arm64 + - arm32 + - ppc64 + - sparc64 + - mips64 + - s390x + +And the older cBPF JIT supported on the following archs: + - mips + - ppc + - sparc + +eBPF JITs are a superset of cBPF JITs, meaning the kernel will +migrate cBPF instructions into eBPF instructions and then JIT +compile them transparently. Older cBPF JITs can only translate +tcpdump filters, seccomp rules, etc, but not mentioned eBPF +programs loaded through bpf(2). + Values : 0 - disable the JIT (default value) 1 - enable the JIT @@ -46,9 +71,9 @@ Values : bpf_jit_harden -------------- -This enables hardening for the Berkeley Packet Filter Just in Time compiler. -Supported are eBPF JIT backends. Enabling hardening trades off performance, -but can mitigate JIT spraying. +This enables hardening for the BPF JIT compiler. Supported are eBPF +JIT backends. Enabling hardening trades off performance, but can +mitigate JIT spraying. Values : 0 - disable JIT hardening (default value) 1 - enable JIT hardening for unprivileged users only @@ -57,11 +82,11 @@ Values : bpf_jit_kallsyms ---------------- -When Berkeley Packet Filter Just in Time compiler is enabled, then compiled -images are unknown addresses to the kernel, meaning they neither show up in -traces nor in /proc/kallsyms. This enables export of these addresses, which -can be used for debugging/tracing. If bpf_jit_harden is enabled, this feature -is disabled. +When BPF JIT compiler is enabled, then compiled images are unknown +addresses to the kernel, meaning they neither show up in traces nor +in /proc/kallsyms. This enables export of these addresses, which can +be used for debugging/tracing. If bpf_jit_harden is enabled, this +feature is disabled. Values : 0 - disable JIT kallsyms export (default value) 1 - enable JIT kallsyms export for privileged users only diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 48244c42ff5214176cf4dfc071f803e2aa8cd71f..9baf66a9ef4e7e57f24388d3da3130da83503195 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -572,7 +572,9 @@ See Documentation/nommu-mmap.txt for more information. numa_zonelist_order -This sysctl is only for NUMA. +This sysctl is only for NUMA and it is deprecated. Anything but +Node order will fail! + 'where the memory is allocated from' is controlled by zonelists. (This documentation ignores ZONE_HIGHMEM/ZONE_DMA32 for simple explanation. you may be able to read ZONE_DMA as ZONE_DMA32...) diff --git a/Documentation/trace/stm.txt b/Documentation/trace/stm.txt index 11cff47eecce6ae71c6e16761f625bf009dab9f5..03765750104b30e24cb450d6fea78f165e705539 100644 --- a/Documentation/trace/stm.txt +++ b/Documentation/trace/stm.txt @@ -83,7 +83,7 @@ by writing the name of the desired stm device there, for example: $ echo dummy_stm.0 > /sys/class/stm_source/console/stm_source_link For examples on how to use stm_source interface in the kernel, refer -to stm_console or stm_heartbeat drivers. +to stm_console, stm_heartbeat or stm_ftrace drivers. Each stm_source device will need to assume a master and a range of channels, depending on how many channels it requires. These are @@ -107,5 +107,16 @@ console in the STP stream, create a "console" policy entry (see the beginning of this text on how to do that). When initialized, it will consume one channel. +stm_ftrace +========== + +This is another "stm_source" device, once the stm_ftrace has been +linked with an stm device, and if "function" tracer is enabled, +function address and parent function address which Ftrace subsystem +would store into ring buffer will be exported via the stm device at +the same time. + +Currently only Ftrace "function" tracer is supported. + [1] https://software.intel.com/sites/default/files/managed/d3/3c/intel-th-developer-manual.pdf [2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0444b/index.html diff --git a/Documentation/translations/ko_KR/memory-barriers.txt b/Documentation/translations/ko_KR/memory-barriers.txt index 38310dcd66203b9a850c134e973af0b567ebecdc..a7a813258013e7812ad6197c5da62af6cd03dad7 100644 --- a/Documentation/translations/ko_KR/memory-barriers.txt +++ b/Documentation/translations/ko_KR/memory-barriers.txt @@ -523,11 +523,11 @@ CPU ì—게 기대할 수 있는 ìµœì†Œí•œì˜ ë³´ìž¥ì‚¬í•­ 몇가지가 있습니 즉, ACQUIRE 는 ìµœì†Œí•œì˜ "ì·¨ë“" ë™ìž‘처럼, 그리고 RELEASE 는 ìµœì†Œí•œì˜ "공개" 처럼 ë™ìž‘한다는 ì˜ë¯¸ìž…니다. -core-api/atomic_ops.rst ì—서 설명ë˜ëŠ” 어토믹 오í¼ë ˆì´ì…˜ë“¤ 중ì—는 완전히 -순서잡힌 것들과 (배리어를 사용하지 않는) ì™„í™”ëœ ìˆœì„œì˜ ê²ƒë“¤ ì™¸ì— ACQUIRE 와 -RELEASE ë¶€ë¥˜ì˜ ê²ƒë“¤ë„ ì¡´ìž¬í•©ë‹ˆë‹¤. 로드와 스토어를 ëª¨ë‘ ìˆ˜í–‰í•˜ëŠ” ì¡°í•©ëœ ì–´í† ë¯¹ -오í¼ë ˆì´ì…˜ì—서, ACQUIRE 는 해당 오í¼ë ˆì´ì…˜ì˜ 로드 부분ì—ë§Œ ì ìš©ë˜ê³  RELEASE 는 -해당 오í¼ë ˆì´ì…˜ì˜ 스토어 부분ì—ë§Œ ì ìš©ë©ë‹ˆë‹¤. +atomic_t.txt ì— ì„¤ëª…ëœ ì–´í† ë¯¹ 오í¼ë ˆì´ì…˜ë“¤ 중 ì¼ë¶€ëŠ” 완전히 순서잡힌 것들과 +(배리어를 사용하지 않는) ì™„í™”ëœ ìˆœì„œì˜ ê²ƒë“¤ ì™¸ì— ACQUIRE 와 RELEASE ë¶€ë¥˜ì˜ +ê²ƒë“¤ë„ ì¡´ìž¬í•©ë‹ˆë‹¤. 로드와 스토어를 ëª¨ë‘ ìˆ˜í–‰í•˜ëŠ” ì¡°í•©ëœ ì–´í† ë¯¹ 오í¼ë ˆì´ì…˜ì—서, +ACQUIRE 는 해당 오í¼ë ˆì´ì…˜ì˜ 로드 부분ì—ë§Œ ì ìš©ë˜ê³  RELEASE 는 해당 +오í¼ë ˆì´ì…˜ì˜ 스토어 부분ì—ë§Œ ì ìš©ë©ë‹ˆë‹¤. 메모리 ë°°ë¦¬ì–´ë“¤ì€ ë‘ CPU ê°„, ë˜ëŠ” CPU 와 디바ì´ìФ ê°„ì— ìƒí˜¸ìž‘ìš©ì˜ ê°€ëŠ¥ì„±ì´ ìžˆì„ ë•Œì—ë§Œ 필요합니다. 만약 ì–´ë–¤ ì½”ë“œì— ê·¸ëŸ° ìƒí˜¸ìž‘ìš©ì´ ì—†ì„ ê²ƒì´ ë³´ìž¥ëœë‹¤ë©´, 해당 @@ -617,7 +617,22 @@ RELEASE ë¶€ë¥˜ì˜ ê²ƒë“¤ë„ ì¡´ìž¬í•©ë‹ˆë‹¤. 로드와 스토어를 ëª¨ë‘ ìˆ˜ ì´ ë³€ê²½ì€ ì•žì˜ ì²˜ìŒ ë‘가지 ê²°ê³¼ 중 í•˜ë‚˜ë§Œì´ ë°œìƒí•  수 있고, ì„¸ë²ˆì§¸ì˜ ê²°ê³¼ëŠ” ë°œìƒí•  수 ì—†ë„ë¡ í•©ë‹ˆë‹¤. -ë°ì´í„° ì˜ì¡´ì„± 배리어는 ì˜ì¡´ì  ì“°ê¸°ì— ëŒ€í•´ì„œë„ ìˆœì„œë¥¼ 잡아ì¤ë‹ˆë‹¤: + +[!] ì´ ìƒë‹¹ížˆ ë°˜ì§ê´€ì ì¸ ìƒí™©ì€ ë¶„ë¦¬ëœ ìºì‹œë¥¼ 가지는 기계들ì—서 가장 잘 +ë°œìƒí•˜ëŠ”ë°, 예를 들면 한 ìºì‹œ ë±…í¬ëŠ” ì§ìˆ˜ ë²ˆí˜¸ì˜ ìºì‹œ ë¼ì¸ë“¤ì„ 처리하고, 다른 +ë±…í¬ëŠ” 홀수 ë²ˆí˜¸ì˜ ìºì‹œ ë¼ì¸ë“¤ì„ 처리하는 ê²½ìš°ìž„ì„ ì•Œì•„ë‘시기 ë°”ëžë‹ˆë‹¤. í¬ì¸í„° +P 는 ì§ìˆ˜ 번호 ìºì‹œ ë¼ì¸ì— 저장ë˜ì–´ 있고, 변수 B 는 홀수 번호 ìºì‹œ ë¼ì¸ì— +저장ë˜ì–´ ìžˆì„ ìˆ˜ 있습니다. 여기서 ê°’ì„ ì½ì–´ì˜¤ëŠ” CPU ì˜ ìºì‹œì˜ 홀수 번호 처리 +ë±…í¬ëŠ” 열심히 ì¼ê°ì„ ì²˜ë¦¬ì¤‘ì¸ ë°˜ë©´ 홀수 번호 처리 ë±…í¬ëŠ” í•  ì¼ ì—†ì´ í•œê°€í•œ +중ì´ë¼ë©´ í¬ì¸í„° P (&B) ì˜ ìƒˆë¡œìš´ ê°’ê³¼ 변수 B ì˜ ê¸°ì¡´ ê°’ (2) 를 ë³¼ 수 있습니다. + + +ì˜ì¡´ì  ì“°ê¸°ë“¤ì˜ ìˆœì„œë¥¼ 맞추는ë°ì—는 ë°ì´í„° ì˜ì¡´ì„± 배리어가 필요치 않ì€ë°, ì´ëŠ” +리눅스 커ë„ì´ ì§€ì›í•˜ëŠ” CPU ë“¤ì€ (1) 쓰기가 ì •ë§ë¡œ ì¼ì–´ë‚ ì§€, (2) 쓰기가 ì–´ë””ì— +ì´ë£¨ì–´ì§ˆì§€, 그리고 (3) 쓰여질 ê°’ì„ í™•ì‹¤ížˆ 알기 전까지는 쓰기를 수행하지 않기 +때문입니다. 하지만 "컨트롤 ì˜ì¡´ì„±" 섹션과 +Documentation/RCU/rcu_dereference.txt 파ì¼ì„ ì£¼ì˜ ê¹Šê²Œ ì½ì–´ 주시기 ë°”ëžë‹ˆë‹¤: +컴파ì¼ëŸ¬ëŠ” 매우 ì°½ì˜ì ì¸ ë§Žì€ ë°©ë²•ìœ¼ë¡œ 종ì†ì„±ì„ ê¹° 수 있습니다. CPU 1 CPU 2 =============== =============== @@ -626,28 +641,19 @@ RELEASE ë¶€ë¥˜ì˜ ê²ƒë“¤ë„ ì¡´ìž¬í•©ë‹ˆë‹¤. 로드와 스토어를 ëª¨ë‘ ìˆ˜ <쓰기 배리어> WRITE_ONCE(P, &B); Q = READ_ONCE(P); - <ë°ì´í„° ì˜ì¡´ì„± 배리어> - *Q = 5; + WRITE_ONCE(*Q, 5); -ì´ ë°ì´í„° ì˜ì¡´ì„± 배리어는 Q ë¡œì˜ ì½ê¸°ê°€ *Q ë¡œì˜ ìŠ¤í† ì–´ì™€ 순서를 맞추게 -í•´ì¤ë‹ˆë‹¤. ì´ëŠ” 다ìŒê³¼ ê°™ì€ ê²°ê³¼ë¥¼ 막습니다: +ë”°ë¼ì„œ, Q ë¡œì˜ ì½ê¸°ì™€ *Q ë¡œì˜ ì“°ê¸° 사ì´ì—는 ë°ì´í„° 종ì†ì„± 배리어가 필요치 +않습니다. 달리 ë§í•˜ë©´, ë°ì´í„° 종ì†ì„± 배리어가 ì—†ë”ë¼ë„ ë‹¤ìŒ ê²°ê³¼ëŠ” ìƒê¸°ì§€ +않습니다: (Q == &B) && (B == 4) ì´ëŸ° íŒ¨í„´ì€ ë“œë¬¼ê²Œ 사용ë˜ì–´ì•¼ í•¨ì„ ì•Œì•„ ë‘시기 ë°”ëžë‹ˆë‹¤. 무엇보다ë„, ì˜ì¡´ì„± 순서 ê·œì¹™ì˜ ì˜ë„는 쓰기 ìž‘ì—…ì„ -예방- 해서 그로 ì¸í•´ ë°œìƒí•˜ëŠ” 비싼 ìºì‹œ ë¯¸ìŠ¤ë„ ì—†ì• ë ¤ëŠ” 것입니다. ì´ íŒ¨í„´ì€ ë“œë¬¼ê²Œ ë°œìƒí•˜ëŠ” ì—러 ì¡°ê±´ ê°™ì€ê²ƒë“¤ì„ 기ë¡í•˜ëŠ”ë° -ì‚¬ìš©ë  ìˆ˜ 있고, ì´ë ‡ê²Œ 배리어를 사용해 순서를 지키게 í•¨ìœ¼ë¡œì¨ ê·¸ëŸ° 기ë¡ì´ -사ë¼ì§€ëŠ” ê²ƒì„ ë§‰ìŠµë‹ˆë‹¤. - - -[!] ìƒë‹¹ížˆ 비ì§ê´€ì ì¸ ì´ ìƒí™©ì€ ë¶„ë¦¬ëœ ìºì‹œë¥¼ 가진 기계, 예를 들어 한 ìºì‹œ -ë±…í¬ê°€ ì§ìˆ˜ë²ˆ ìºì‹œ ë¼ì¸ì„ 처리하고 다른 ë±…í¬ëŠ” 홀수번 ìºì‹œ ë¼ì¸ì„ 처리하는 기계 -등ì—서 가장 잘 ë°œìƒí•©ë‹ˆë‹¤. í¬ì¸í„° P 는 홀수 ë²ˆí˜¸ì˜ ìºì‹œ ë¼ì¸ì— 있고, 변수 B 는 -ì§ìˆ˜ 번호 ìºì‹œ ë¼ì¸ì— 있다고 ìƒê°í•´ 봅시다. 그런 ìƒíƒœì—서 ì½ê¸° ìž‘ì—…ì„ í•˜ëŠ” CPU -ì˜ ì§ìˆ˜ë²ˆ ë±…í¬ëŠ” í•  ì¼ì´ 쌓여 매우 ë°”ì˜ì§€ë§Œ 홀수번 ë±…í¬ëŠ” í•  ì¼ì´ 없어 아무 -ì¼ë„ 하지 않고 있었다면, í¬ì¸í„° P 는 새 ê°’ (&B) ì„, 그리고 변수 B 는 옛날 ê°’ -(2) ì„ ê°€ì§€ê³  있는 ìƒíƒœê°€ 보여질 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. +ì‚¬ìš©ë  ìˆ˜ 있으며, CPUì˜ ìžì—°ì ì¸ 순서 ë³´ìž¥ì´ ê·¸ëŸ° 기ë¡ë“¤ì„ 사ë¼ì§€ì§€ 않게 +í•´ì¤ë‹ˆë‹¤. ë°ì´í„° ì˜ì¡´ì„± 배리어는 매우 중요한ë°, 예를 들어 RCU 시스템ì—서 그렇습니다. @@ -1848,8 +1854,7 @@ Mandatory ë°°ë¦¬ì–´ë“¤ì€ SMP 시스템ì—ì„œë„ UP 시스템ì—ì„œë„ SMP 효 ì´ ì½”ë“œëŠ” ê°ì²´ì˜ ì—…ë°ì´íŠ¸ëœ death 마í¬ê°€ ë ˆí¼ëŸ°ìФ ì¹´ìš´í„° ê°ì†Œ ë™ìž‘ *ì „ì—* ë³´ì¼ ê²ƒì„ ë³´ìž¥í•©ë‹ˆë‹¤. - ë” ë§Žì€ ì •ë³´ë¥¼ 위해선 Documentation/core-api/atomic_ops.rst 문서를 참고하세요. - 어디서 ì´ê²ƒë“¤ì„ 사용해야 í• ì§€ ê¶ê¸ˆí•˜ë‹¤ë©´ "어토믹 오í¼ë ˆì´ì…˜" ì„œë¸Œì„¹ì…˜ì„ + ë” ë§Žì€ ì •ë³´ë¥¼ 위해선 Documentation/atomic_{t,bitops}.txt 문서를 참고하세요. @@ -1956,10 +1961,7 @@ MMIO 쓰기 배리어 ë’¤ì— ì™„ë£Œë©ë‹ˆë‹¤. ACQUIRE 앞ì—서 ìš”ì²­ëœ ë©”ëª¨ë¦¬ 오í¼ë ˆì´ì…˜ì€ ACQUIRE 오í¼ë ˆì´ì…˜ì´ ì™„ë£Œëœ í›„ì— - ì™„ë£Œë  ìˆ˜ 있습니다. smp_mb__before_spinlock() ë’¤ì— ACQUIRE ê°€ 실행ë˜ëŠ” - 코드 블ë¡ì€ ë¸”ë¡ ì•žì˜ ìŠ¤í† ì–´ë¥¼ ë¸”ë¡ ë’¤ì˜ ë¡œë“œì™€ ìŠ¤í† ì–´ì— ëŒ€í•´ 순서 - 맞춥니다. ì´ê±´ smp_mb() 보다 ì™„í™”ëœ ê²ƒìž„ì„ ê¸°ì–µí•˜ì„¸ìš”! ë§Žì€ ì•„í‚¤í…ì³ì—서 - smp_mb__before_spinlock() ì€ ì‚¬ì‹¤ 아무ì¼ë„ 하지 않습니다. + ì™„ë£Œë  ìˆ˜ 있습니다. (2) RELEASE 오í¼ë ˆì´ì…˜ì˜ ì˜í–¥: @@ -2471,86 +2473,7 @@ _않습니다_. ì „ì²´ 메모리 배리어를 ë‚´í¬í•˜ê³  ë˜ ì¼ë¶€ëŠ” ë‚´í¬í•˜ì§€ 않지만, 커ë„ì—서 ìƒë‹¹ížˆ ì˜ì¡´ì ìœ¼ë¡œ 사용하는 기능 중 하나입니다. -ë©”ëª¨ë¦¬ì˜ ì–´ë–¤ ìƒíƒœë¥¼ 수정하고 해당 ìƒíƒœì— 대한 (ì˜ˆì „ì˜ ë˜ëŠ” 최신ì˜) 정보를 -리턴하는 어토믹 오í¼ë ˆì´ì…˜ì€ ëª¨ë‘ SMP-ì¡°ê±´ì  ë²”ìš© 메모리 배리어(smp_mb())를 -실제 오í¼ë ˆì´ì…˜ì˜ 앞과 ë’¤ì— ë‚´í¬í•©ë‹ˆë‹¤. ì´ëŸ° 오í¼ë ˆì´ì…˜ì€ 다ìŒì˜ ê²ƒë“¤ì„ -í¬í•¨í•©ë‹ˆë‹¤: - - xchg(); - atomic_xchg(); atomic_long_xchg(); - atomic_inc_return(); atomic_long_inc_return(); - atomic_dec_return(); atomic_long_dec_return(); - atomic_add_return(); atomic_long_add_return(); - atomic_sub_return(); atomic_long_sub_return(); - atomic_inc_and_test(); atomic_long_inc_and_test(); - atomic_dec_and_test(); atomic_long_dec_and_test(); - atomic_sub_and_test(); atomic_long_sub_and_test(); - atomic_add_negative(); atomic_long_add_negative(); - test_and_set_bit(); - test_and_clear_bit(); - test_and_change_bit(); - - /* exchange ì¡°ê±´ì´ ì„±ê³µí•  때 */ - cmpxchg(); - atomic_cmpxchg(); atomic_long_cmpxchg(); - atomic_add_unless(); atomic_long_add_unless(); - -ì´ê²ƒë“¤ì€ 메모리 배리어 효과가 필요한 ACQUIRE 부류와 RELEASE 부류 오í¼ë ˆì´ì…˜ë“¤ì„ -구현할 때, 그리고 ê°ì²´ 해제를 위해 ë ˆí¼ëŸ°ìФ 카운터를 ì¡°ì •í•  때, ì•”ë¬µì  ë©”ëª¨ë¦¬ -배리어 효과가 필요한 ê³³ ë“±ì— ì‚¬ìš©ë©ë‹ˆë‹¤. - - -다ìŒì˜ 오í¼ë ˆì´ì…˜ë“¤ì€ 메모리 배리어를 ë‚´í¬í•˜ì§€ _않기_ ë•Œë¬¸ì— ë¬¸ì œê°€ ë  ìˆ˜ -있지만, RELEASE ë¶€ë¥˜ì˜ ì˜¤í¼ë ˆì´ì…˜ë“¤ê³¼ ê°™ì€ ê²ƒë“¤ì„ êµ¬í˜„í•  때 ì‚¬ìš©ë  ìˆ˜ë„ -있습니다: - - atomic_set(); - set_bit(); - clear_bit(); - change_bit(); - -ì´ê²ƒë“¤ì„ 사용할 때ì—는 필요하다면 ì ì ˆí•œ (예를 들면 smp_mb__before_atomic() -ê°™ì€) 메모리 배리어가 명시ì ìœ¼ë¡œ 함께 사용ë˜ì–´ì•¼ 합니다. - - -ì•„ëž˜ì˜ ê²ƒë“¤ë„ ë©”ëª¨ë¦¬ 배리어를 ë‚´í¬í•˜ì§€ _않기_ 때문ì—, ì¼ë¶€ 환경ì—서는 (예를 -들면 smp_mb__before_atomic() ê³¼ ê°™ì€) 명시ì ì¸ 메모리 배리어 ì‚¬ìš©ì´ í•„ìš”í•©ë‹ˆë‹¤. - - atomic_add(); - atomic_sub(); - atomic_inc(); - atomic_dec(); - -ì´ê²ƒë“¤ì´ 통계 ìƒì„±ì„ 위해 사용ëœë‹¤ë©´, 그리고 통계 ë°ì´í„° 사ì´ì— 관계가 존재하지 -않는다면 메모리 배리어는 필요치 ì•Šì„ ê²ë‹ˆë‹¤. - -ê°ì²´ì˜ ìˆ˜ëª…ì„ ê´€ë¦¬í•˜ê¸° 위해 ë ˆí¼ëŸ°ìФ 카운팅 목ì ìœ¼ë¡œ 사용ëœë‹¤ë©´, ë ˆí¼ëŸ°ìФ -카운터는 ë½ìœ¼ë¡œ 보호ë˜ëŠ” 섹션ì—서만 ì¡°ì •ë˜ê±°ë‚˜ 호출하는 ìª½ì´ ì´ë¯¸ 충분한 -ë ˆí¼ëŸ°ìŠ¤ë¥¼ 잡고 ìžˆì„ ê²ƒì´ê¸° ë•Œë¬¸ì— ë©”ëª¨ë¦¬ 배리어는 아마 í•„ìš” ì—†ì„ ê²ë‹ˆë‹¤. - -만약 ì–´ë–¤ ë½ì„ 구성하기 위해 사용ëœë‹¤ë©´, ë½ ê´€ë ¨ ë™ìž‘ì€ ì¼ë°˜ì ìœ¼ë¡œ ìž‘ì—…ì„ íŠ¹ì • -순서대로 진행해야 하므로 메모리 배리어가 필요할 수 있습니다. - -기본ì ìœ¼ë¡œ, ê° ì‚¬ìš©ì²˜ì—서는 메모리 배리어가 필요한지 아닌지 충분히 고려해야 -합니다. - -ì•„ëž˜ì˜ ì˜¤í¼ë ˆì´ì…˜ë“¤ì€ 특별한 ë½ ê´€ë ¨ ë™ìž‘들입니다: - - test_and_set_bit_lock(); - clear_bit_unlock(); - __clear_bit_unlock(); - -ì´ê²ƒë“¤ì€ ACQUIRE 류와 RELEASE ë¥˜ì˜ ì˜¤í¼ë ˆì´ì…˜ë“¤ì„ 구현합니다. ë½ ê´€ë ¨ ë„구를 -구현할 때ì—는 ì´ê²ƒë“¤ì„ 좀 ë” ì„ í˜¸í•˜ëŠ” íŽ¸ì´ ë‚˜ì€ë°, ì´ê²ƒë“¤ì˜ êµ¬í˜„ì€ ë§Žì€ -아키í…ì³ì—서 최ì í™” ë  ìˆ˜ 있기 때문입니다. - -[!] ì´ëŸ° ìƒí™©ì— 사용할 수 있는 특수한 메모리 배리어 ë„êµ¬ë“¤ì´ ìžˆìŠµë‹ˆë‹¤ë§Œ, ì¼ë¶€ -CPU ì—서는 사용ë˜ëŠ” 어토믹 ì¸ìŠ¤íŠ¸ëŸ­ì…˜ ìžì²´ì— 메모리 배리어가 ë‚´í¬ë˜ì–´ 있어서 -어토믹 오í¼ë ˆì´ì…˜ê³¼ 메모리 배리어를 함께 사용하는 게 불필요한 ì¼ì´ ë  ìˆ˜ -있는ë°, 그런 ê²½ìš°ì— ì´ íŠ¹ìˆ˜ 메모리 배리어 ë„êµ¬ë“¤ì€ no-op ì´ ë˜ì–´ 실질ì ìœ¼ë¡œ -아무ì¼ë„ 하지 않습니다. - -ë” ë§Žì€ ë‚´ìš©ì„ ìœ„í•´ì„  Documentation/core-api/atomic_ops.rst 를 참고하세요. +ë” ë§Žì€ ë‚´ìš©ì„ ìœ„í•´ì„  Documentation/atomic_t.txt 를 참고하세요. 디바ì´ìФ 액세스 diff --git a/Documentation/translations/zh_CN/HOWTO b/Documentation/translations/zh_CN/HOWTO index 11be075ba5fa42abe96564e5bc55dcd446ad7726..5f6d09edc9ac9d5ff57ca9716db225d7a57b8602 100644 --- a/Documentation/translations/zh_CN/HOWTO +++ b/Documentation/translations/zh_CN/HOWTO @@ -149,9 +149,7 @@ Linux内核代ç ä¸­åŒ…嫿œ‰å¤§é‡çš„æ–‡æ¡£ã€‚这些文档对于学习如何与 æ ¸æºç çš„主目录中使用以下ä¸åŒå‘½ä»¤å°†ä¼šåˆ†åˆ«ç”ŸæˆPDFã€Postscriptã€HTML和手册 页等ä¸åŒæ ¼å¼çš„æ–‡æ¡£ï¼š make pdfdocs - make psdocs make htmldocs - make mandocs 如何æˆä¸ºå†…核开å‘者 diff --git a/Documentation/userspace-api/seccomp_filter.rst b/Documentation/userspace-api/seccomp_filter.rst index f71eb5ef1f2df4154a0a31dd0307da00c5fde42f..099c412951d6b9dea515b08384e023e2c2d69025 100644 --- a/Documentation/userspace-api/seccomp_filter.rst +++ b/Documentation/userspace-api/seccomp_filter.rst @@ -87,11 +87,16 @@ Return values A seccomp filter may return any of the following values. If multiple filters exist, the return value for the evaluation of a given system call will always use the highest precedent value. (For example, -``SECCOMP_RET_KILL`` will always take precedence.) +``SECCOMP_RET_KILL_PROCESS`` will always take precedence.) In precedence order, they are: -``SECCOMP_RET_KILL``: +``SECCOMP_RET_KILL_PROCESS``: + Results in the entire process exiting immediately without executing + the system call. The exit status of the task (``status & 0x7f``) + will be ``SIGSYS``, not ``SIGKILL``. + +``SECCOMP_RET_KILL_THREAD``: Results in the task exiting immediately without executing the system call. The exit status of the task (``status & 0x7f``) will be ``SIGSYS``, not ``SIGKILL``. @@ -141,6 +146,15 @@ In precedence order, they are: allow use of ptrace, even of other sandboxed processes, without extreme care; ptracers can use this mechanism to escape.) +``SECCOMP_RET_LOG``: + Results in the system call being executed after it is logged. This + should be used by application developers to learn which syscalls their + application needs without having to iterate through multiple test and + development cycles to build the list. + + This action will only be logged if "log" is present in the + actions_logged sysctl string. + ``SECCOMP_RET_ALLOW``: Results in the system call being executed. @@ -169,7 +183,41 @@ The ``samples/seccomp/`` directory contains both an x86-specific example and a more generic example of a higher level macro interface for BPF program generation. +Sysctls +======= +Seccomp's sysctl files can be found in the ``/proc/sys/kernel/seccomp/`` +directory. Here's a description of each file in that directory: + +``actions_avail``: + A read-only ordered list of seccomp return values (refer to the + ``SECCOMP_RET_*`` macros above) in string form. The ordering, from + left-to-right, is the least permissive return value to the most + permissive return value. + + The list represents the set of seccomp return values supported + by the kernel. A userspace program may use this list to + determine if the actions found in the ``seccomp.h``, when the + program was built, differs from the set of actions actually + supported in the current running kernel. + +``actions_logged``: + A read-write ordered list of seccomp return values (refer to the + ``SECCOMP_RET_*`` macros above) that are allowed to be logged. Writes + to the file do not need to be in ordered form but reads from the file + will be ordered in the same way as the actions_avail sysctl. + + It is important to note that the value of ``actions_logged`` does not + prevent certain actions from being logged when the audit subsystem is + configured to audit a task. If the action is not found in + ``actions_logged`` list, the final decision on whether to audit the + action for that task is ultimately left up to the audit subsystem to + decide for all seccomp return values other than ``SECCOMP_RET_ALLOW``. + + The ``allow`` string is not accepted in the ``actions_logged`` sysctl + as it is not possible to log ``SECCOMP_RET_ALLOW`` actions. Attempting + to write ``allow`` to the sysctl will result in an EINVAL being + returned. Adding architecture support =========================== diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt index b2f60ca8b60cad64d9ffba81f61919bc4b8edacb..b3ce12643553f3edbe327029bbfe61ecaa8cc506 100644 --- a/Documentation/virtual/kvm/devices/arm-vgic.txt +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt @@ -83,6 +83,11 @@ Groups: Bits for undefined preemption levels are RAZ/WI. + Note that this differs from a CPU's view of the APRs on hardware in which + a GIC without the security extensions expose group 0 and group 1 active + priorities in separate register groups, whereas we show a combined view + similar to GICv2's GICH_APR. + For historical reasons and to provide ABI compatibility with userspace we export the GICC_PMR register in the format of the GICH_VMCR.VMPriMask field in the lower 5 bits of a word, meaning that userspace must always diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index 903fc926860b522bc92122a65c750d4f28be2d71..95ca68d663a4c111eb99b280e6d1d60c85461804 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt @@ -176,7 +176,8 @@ Architectures: s390 3.1. ATTRIBUTE: KVM_S390_VM_TOD_HIGH -Allows user space to set/get the TOD clock extension (u8). +Allows user space to set/get the TOD clock extension (u8) (superseded by +KVM_S390_VM_TOD_EXT). Parameters: address of a buffer in user space to store the data (u8) to Returns: -EFAULT if the given address is not accessible from kernel space @@ -190,6 +191,17 @@ the POP (u64). Parameters: address of a buffer in user space to store the data (u64) to Returns: -EFAULT if the given address is not accessible from kernel space +3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT +Allows user space to set/get bits 0-63 of the TOD clock register as defined in +the POP (u64). If the guest CPU model supports the TOD clock extension (u8), it +also allows user space to get/set it. If the guest CPU model does not support +it, it is stored as 0 and not allowed to be set to a value != 0. + +Parameters: address of a buffer in user space to store the data + (kvm_s390_vm_tod_clock) to +Returns: -EFAULT if the given address is not accessible from kernel space + -EINVAL if setting the TOD clock extension to != 0 is not supported + 4. GROUP: KVM_S390_VM_CRYPTO Architectures: s390 diff --git a/Documentation/vm/hmm.txt b/Documentation/vm/hmm.txt new file mode 100644 index 0000000000000000000000000000000000000000..4d3aac9f4a5dcbe86df5d81e41dcc70b82a819a4 --- /dev/null +++ b/Documentation/vm/hmm.txt @@ -0,0 +1,384 @@ +Heterogeneous Memory Management (HMM) + +Transparently allow any component of a program to use any memory region of said +program with a device without using device specific memory allocator. This is +becoming a requirement to simplify the use of advance heterogeneous computing +where GPU, DSP or FPGA are use to perform various computations. + +This document is divided as follow, in the first section i expose the problems +related to the use of a device specific allocator. The second section i expose +the hardware limitations that are inherent to many platforms. The third section +gives an overview of HMM designs. The fourth section explains how CPU page- +table mirroring works and what is HMM purpose in this context. Fifth section +deals with how device memory is represented inside the kernel. Finaly the last +section present the new migration helper that allow to leverage the device DMA +engine. + + +1) Problems of using device specific memory allocator: +2) System bus, device memory characteristics +3) Share address space and migration +4) Address space mirroring implementation and API +5) Represent and manage device memory from core kernel point of view +6) Migrate to and from device memory +7) Memory cgroup (memcg) and rss accounting + + +------------------------------------------------------------------------------- + +1) Problems of using device specific memory allocator: + +Device with large amount of on board memory (several giga bytes) like GPU have +historically manage their memory through dedicated driver specific API. This +creates a disconnect between memory allocated and managed by device driver and +regular application memory (private anonymous, share memory or regular file +back memory). From here on i will refer to this aspect as split address space. +I use share address space to refer to the opposite situation ie one in which +any memory region can be use by device transparently. + +Split address space because device can only access memory allocated through the +device specific API. This imply that all memory object in a program are not +equal from device point of view which complicate large program that rely on a +wide set of libraries. + +Concretly this means that code that wants to leverage device like GPU need to +copy object between genericly allocated memory (malloc, mmap private/share/) +and memory allocated through the device driver API (this still end up with an +mmap but of the device file). + +For flat dataset (array, grid, image, ...) this isn't too hard to achieve but +complex data-set (list, tree, ...) are hard to get right. Duplicating a complex +data-set need to re-map all the pointer relations between each of its elements. +This is error prone and program gets harder to debug because of the duplicate +data-set. + +Split address space also means that library can not transparently use data they +are getting from core program or other library and thus each library might have +to duplicate its input data-set using specific memory allocator. Large project +suffer from this and waste resources because of the various memory copy. + +Duplicating each library API to accept as input or output memory allocted by +each device specific allocator is not a viable option. It would lead to a +combinatorial explosions in the library entry points. + +Finaly with the advance of high level language constructs (in C++ but in other +language too) it is now possible for compiler to leverage GPU or other devices +without even the programmer knowledge. Some of compiler identified patterns are +only do-able with a share address. It is as well more reasonable to use a share +address space for all the other patterns. + + +------------------------------------------------------------------------------- + +2) System bus, device memory characteristics + +System bus cripple share address due to few limitations. Most system bus only +allow basic memory access from device to main memory, even cache coherency is +often optional. Access to device memory from CPU is even more limited, most +often than not it is not cache coherent. + +If we only consider the PCIE bus than device can access main memory (often +through an IOMMU) and be cache coherent with the CPUs. However it only allows +a limited set of atomic operation from device on main memory. This is worse +in the other direction the CPUs can only access a limited range of the device +memory and can not perform atomic operations on it. Thus device memory can not +be consider like regular memory from kernel point of view. + +Another crippling factor is the limited bandwidth (~32GBytes/s with PCIE 4.0 +and 16 lanes). This is 33 times less that fastest GPU memory (1 TBytes/s). +The final limitation is latency, access to main memory from the device has an +order of magnitude higher latency than when the device access its own memory. + +Some platform are developing new system bus or additions/modifications to PCIE +to address some of those limitations (OpenCAPI, CCIX). They mainly allow two +way cache coherency between CPU and device and allow all atomic operations the +architecture supports. Saddly not all platform are following this trends and +some major architecture are left without hardware solutions to those problems. + +So for share address space to make sense not only we must allow device to +access any memory memory but we must also permit any memory to be migrated to +device memory while device is using it (blocking CPU access while it happens). + + +------------------------------------------------------------------------------- + +3) Share address space and migration + +HMM intends to provide two main features. First one is to share the address +space by duplication the CPU page table into the device page table so same +address point to same memory and this for any valid main memory address in +the process address space. + +To achieve this, HMM offer a set of helpers to populate the device page table +while keeping track of CPU page table updates. Device page table updates are +not as easy as CPU page table updates. To update the device page table you must +allow a buffer (or use a pool of pre-allocated buffer) and write GPU specifics +commands in it to perform the update (unmap, cache invalidations and flush, +...). This can not be done through common code for all device. Hence why HMM +provides helpers to factor out everything that can be while leaving the gory +details to the device driver. + +The second mechanism HMM provide is a new kind of ZONE_DEVICE memory that does +allow to allocate a struct page for each page of the device memory. Those page +are special because the CPU can not map them. They however allow to migrate +main memory to device memory using exhisting migration mechanism and everything +looks like if page was swap out to disk from CPU point of view. Using a struct +page gives the easiest and cleanest integration with existing mm mechanisms. +Again here HMM only provide helpers, first to hotplug new ZONE_DEVICE memory +for the device memory and second to perform migration. Policy decision of what +and when to migrate things is left to the device driver. + +Note that any CPU access to a device page trigger a page fault and a migration +back to main memory ie when a page backing an given address A is migrated from +a main memory page to a device page then any CPU access to address A trigger a +page fault and initiate a migration back to main memory. + + +With this two features, HMM not only allow a device to mirror a process address +space and keeps both CPU and device page table synchronize, but also allow to +leverage device memory by migrating part of data-set that is actively use by a +device. + + +------------------------------------------------------------------------------- + +4) Address space mirroring implementation and API + +Address space mirroring main objective is to allow to duplicate range of CPU +page table into a device page table and HMM helps keeping both synchronize. A +device driver that want to mirror a process address space must start with the +registration of an hmm_mirror struct: + + int hmm_mirror_register(struct hmm_mirror *mirror, + struct mm_struct *mm); + int hmm_mirror_register_locked(struct hmm_mirror *mirror, + struct mm_struct *mm); + +The locked variant is to be use when the driver is already holding the mmap_sem +of the mm in write mode. The mirror struct has a set of callback that are use +to propagate CPU page table: + + struct hmm_mirror_ops { + /* sync_cpu_device_pagetables() - synchronize page tables + * + * @mirror: pointer to struct hmm_mirror + * @update_type: type of update that occurred to the CPU page table + * @start: virtual start address of the range to update + * @end: virtual end address of the range to update + * + * This callback ultimately originates from mmu_notifiers when the CPU + * page table is updated. The device driver must update its page table + * in response to this callback. The update argument tells what action + * to perform. + * + * The device driver must not return from this callback until the device + * page tables are completely updated (TLBs flushed, etc); this is a + * synchronous call. + */ + void (*update)(struct hmm_mirror *mirror, + enum hmm_update action, + unsigned long start, + unsigned long end); + }; + +Device driver must perform update to the range following action (turn range +read only, or fully unmap, ...). Once driver callback returns the device must +be done with the update. + + +When device driver wants to populate a range of virtual address it can use +either: + int hmm_vma_get_pfns(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns); + int hmm_vma_fault(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns, + bool write, + bool block); + +First one (hmm_vma_get_pfns()) will only fetch present CPU page table entry and +will not trigger a page fault on missing or non present entry. The second one +do trigger page fault on missing or read only entry if write parameter is true. +Page fault use the generic mm page fault code path just like a CPU page fault. + +Both function copy CPU page table into their pfns array argument. Each entry in +that array correspond to an address in the virtual range. HMM provide a set of +flags to help driver identify special CPU page table entries. + +Locking with the update() callback is the most important aspect the driver must +respect in order to keep things properly synchronize. The usage pattern is : + + int driver_populate_range(...) + { + struct hmm_range range; + ... + again: + ret = hmm_vma_get_pfns(vma, &range, start, end, pfns); + if (ret) + return ret; + take_lock(driver->update); + if (!hmm_vma_range_done(vma, &range)) { + release_lock(driver->update); + goto again; + } + + // Use pfns array content to update device page table + + release_lock(driver->update); + return 0; + } + +The driver->update lock is the same lock that driver takes inside its update() +callback. That lock must be call before hmm_vma_range_done() to avoid any race +with a concurrent CPU page table update. + +HMM implements all this on top of the mmu_notifier API because we wanted to a +simpler API and also to be able to perform optimization latter own like doing +concurrent device update in multi-devices scenario. + +HMM also serve as an impedence missmatch between how CPU page table update are +done (by CPU write to the page table and TLB flushes) from how device update +their own page table. Device update is a multi-step process, first appropriate +commands are write to a buffer, then this buffer is schedule for execution on +the device. It is only once the device has executed commands in the buffer that +the update is done. Creating and scheduling update command buffer can happen +concurrently for multiple devices. Waiting for each device to report commands +as executed is serialize (there is no point in doing this concurrently). + + +------------------------------------------------------------------------------- + +5) Represent and manage device memory from core kernel point of view + +Several differents design were try to support device memory. First one use +device specific data structure to keep information about migrated memory and +HMM hooked itself in various place of mm code to handle any access to address +that were back by device memory. It turns out that this ended up replicating +most of the fields of struct page and also needed many kernel code path to be +updated to understand this new kind of memory. + +Thing is most kernel code path never try to access the memory behind a page +but only care about struct page contents. Because of this HMM switchted to +directly using struct page for device memory which left most kernel code path +un-aware of the difference. We only need to make sure that no one ever try to +map those page from the CPU side. + +HMM provide a set of helpers to register and hotplug device memory as a new +region needing struct page. This is offer through a very simple API: + + struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, + struct device *device, + unsigned long size); + void hmm_devmem_remove(struct hmm_devmem *devmem); + +The hmm_devmem_ops is where most of the important things are: + + struct hmm_devmem_ops { + void (*free)(struct hmm_devmem *devmem, struct page *page); + int (*fault)(struct hmm_devmem *devmem, + struct vm_area_struct *vma, + unsigned long addr, + struct page *page, + unsigned flags, + pmd_t *pmdp); + }; + +The first callback (free()) happens when the last reference on a device page is +drop. This means the device page is now free and no longer use by anyone. The +second callback happens whenever CPU try to access a device page which it can +not do. This second callback must trigger a migration back to system memory. + + +------------------------------------------------------------------------------- + +6) Migrate to and from device memory + +Because CPU can not access device memory, migration must use device DMA engine +to perform copy from and to device memory. For this we need a new migration +helper: + + int migrate_vma(const struct migrate_vma_ops *ops, + struct vm_area_struct *vma, + unsigned long mentries, + unsigned long start, + unsigned long end, + unsigned long *src, + unsigned long *dst, + void *private); + +Unlike other migration function it works on a range of virtual address, there +is two reasons for that. First device DMA copy has a high setup overhead cost +and thus batching multiple pages is needed as otherwise the migration overhead +make the whole excersie pointless. The second reason is because driver trigger +such migration base on range of address the device is actively accessing. + +The migrate_vma_ops struct define two callbacks. First one (alloc_and_copy()) +control destination memory allocation and copy operation. Second one is there +to allow device driver to perform cleanup operation after migration. + + struct migrate_vma_ops { + void (*alloc_and_copy)(struct vm_area_struct *vma, + const unsigned long *src, + unsigned long *dst, + unsigned long start, + unsigned long end, + void *private); + void (*finalize_and_map)(struct vm_area_struct *vma, + const unsigned long *src, + const unsigned long *dst, + unsigned long start, + unsigned long end, + void *private); + }; + +It is important to stress that this migration helpers allow for hole in the +virtual address range. Some pages in the range might not be migrated for all +the usual reasons (page is pin, page is lock, ...). This helper does not fail +but just skip over those pages. + +The alloc_and_copy() might as well decide to not migrate all pages in the +range (for reasons under the callback control). For those the callback just +have to leave the corresponding dst entry empty. + +Finaly the migration of the struct page might fails (for file back page) for +various reasons (failure to freeze reference, or update page cache, ...). If +that happens then the finalize_and_map() can catch any pages that was not +migrated. Note those page were still copied to new page and thus we wasted +bandwidth but this is considered as a rare event and a price that we are +willing to pay to keep all the code simpler. + + +------------------------------------------------------------------------------- + +7) Memory cgroup (memcg) and rss accounting + +For now device memory is accounted as any regular page in rss counters (either +anonymous if device page is use for anonymous, file if device page is use for +file back page or shmem if device page is use for share memory). This is a +deliberate choice to keep existing application that might start using device +memory without knowing about it to keep runing unimpacted. + +Drawbacks is that OOM killer might kill an application using a lot of device +memory and not a lot of regular system memory and thus not freeing much system +memory. We want to gather more real world experience on how application and +system react under memory pressure in the presence of device memory before +deciding to account device memory differently. + + +Same decision was made for memory cgroup. Device memory page are accounted +against same memory cgroup a regular page would be accounted to. This does +simplify migration to and from device memory. This also means that migration +back from device memory to regular memory can not fail because it would +go above memory cgroup limit. We might revisit this choice latter on once we +get more experience in how device memory is use and its impact on memory +resource control. + + +Note that device memory can never be pin nor by device driver nor through GUP +and thus such memory is always free upon process exit. Or when last reference +is drop in case of share memory or file back memory. diff --git a/Documentation/vm/numa b/Documentation/vm/numa index a08f716477145164b2e7705336cbc797caca08ac..a31b85b9bb8872febe85c3a6c7225ced460d0067 100644 --- a/Documentation/vm/numa +++ b/Documentation/vm/numa @@ -79,11 +79,8 @@ memory, Linux must decide whether to order the zonelists such that allocations fall back to the same zone type on a different node, or to a different zone type on the same node. This is an important consideration because some zones, such as DMA or DMA32, represent relatively scarce resources. Linux chooses -a default zonelist order based on the sizes of the various zone types relative -to the total memory of the node and the total memory of the system. The -default zonelist order may be overridden using the numa_zonelist_order kernel -boot parameter or sysctl. [see Documentation/admin-guide/kernel-parameters.rst and -Documentation/sysctl/vm.txt] +a default Node ordered zonelist. This means it tries to fallback to other zones +from the same node before using remote nodes which are ordered by NUMA distance. By default, Linux will attempt to satisfy memory allocation requests from the node to which the CPU that executes the request is assigned. Specifically, diff --git a/Documentation/vm/swap_numa.txt b/Documentation/vm/swap_numa.txt new file mode 100644 index 0000000000000000000000000000000000000000..d5960c9124f5f3d99a3cee0a62a3ca1b88bb67b6 --- /dev/null +++ b/Documentation/vm/swap_numa.txt @@ -0,0 +1,69 @@ +Automatically bind swap device to numa node +------------------------------------------- + +If the system has more than one swap device and swap device has the node +information, we can make use of this information to decide which swap +device to use in get_swap_pages() to get better performance. + + +How to use this feature +----------------------- + +Swap device has priority and that decides the order of it to be used. To make +use of automatically binding, there is no need to manipulate priority settings +for swap devices. e.g. on a 2 node machine, assume 2 swap devices swapA and +swapB, with swapA attached to node 0 and swapB attached to node 1, are going +to be swapped on. Simply swapping them on by doing: +# swapon /dev/swapA +# swapon /dev/swapB + +Then node 0 will use the two swap devices in the order of swapA then swapB and +node 1 will use the two swap devices in the order of swapB then swapA. Note +that the order of them being swapped on doesn't matter. + +A more complex example on a 4 node machine. Assume 6 swap devices are going to +be swapped on: swapA and swapB are attached to node 0, swapC is attached to +node 1, swapD and swapE are attached to node 2 and swapF is attached to node3. +The way to swap them on is the same as above: +# swapon /dev/swapA +# swapon /dev/swapB +# swapon /dev/swapC +# swapon /dev/swapD +# swapon /dev/swapE +# swapon /dev/swapF + +Then node 0 will use them in the order of: +swapA/swapB -> swapC -> swapD -> swapE -> swapF +swapA and swapB will be used in a round robin mode before any other swap device. + +node 1 will use them in the order of: +swapC -> swapA -> swapB -> swapD -> swapE -> swapF + +node 2 will use them in the order of: +swapD/swapE -> swapA -> swapB -> swapC -> swapF +Similaly, swapD and swapE will be used in a round robin mode before any +other swap devices. + +node 3 will use them in the order of: +swapF -> swapA -> swapB -> swapC -> swapD -> swapE + + +Implementation details +---------------------- + +The current code uses a priority based list, swap_avail_list, to decide +which swap device to use and if multiple swap devices share the same +priority, they are used round robin. This change here replaces the single +global swap_avail_list with a per-numa-node list, i.e. for each numa node, +it sees its own priority based list of available swap devices. Swap +device's priority can be promoted on its matching node's swap_avail_list. + +The current swap device's priority is set as: user can set a >=0 value, +or the system will pick one starting from -1 then downwards. The priority +value in the swap_avail_list is the negated value of the swap device's +due to plist being sorted from low to high. The new policy doesn't change +the semantics for priority >=0 cases, the previous starting from -1 then +downwards now becomes starting from -2 then downwards and -1 is reserved +as the promoted value. So if multiple swap devices are attached to the same +node, they will all be promoted to priority -1 on that node's plist and will +be used round robin before any other swap devices. diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index b3526365ea8e340143edd1670bc9d89e3944152d..6f9d7b4189170f25143d852d9cf2699af211f997 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -117,7 +117,7 @@ nowayout: Watchdog cannot be stopped once started ------------------------------------------------- iTCO_wdt: heartbeat: Watchdog heartbeat in seconds. - (5<=heartbeat<=74 (TCO v1) or 1226 (TCO v2), default=30) + (2 - -Kernel can update microcode in early phase of boot time. Loading microcode early -can fix CPU issues before they are observed during kernel boot time. - -Microcode is stored in an initrd file. The microcode is read from the initrd -file and loaded to CPUs during boot time. - -The format of the combined initrd image is microcode in cpio format followed by -the initrd image (maybe compressed). Kernel parses the combined initrd image -during boot time. The microcode file in cpio name space is: -on Intel: kernel/x86/microcode/GenuineIntel.bin -on AMD : kernel/x86/microcode/AuthenticAMD.bin - -During BSP boot (before SMP starts), if the kernel finds the microcode file in -the initrd file, it parses the microcode and saves matching microcode in memory. -If matching microcode is found, it will be uploaded in BSP and later on in all -APs. - -The cached microcode patch is applied when CPUs resume from a sleep state. - -There are two legacy user space interfaces to load microcode, either through -/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file -in sysfs. - -In addition to these two legacy methods, the early loading method described -here is the third method with which microcode can be uploaded to a system's -CPUs. - -The following example script shows how to generate a new combined initrd file in -/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and -original initrd image /boot/initrd-3.5.0.img. - -mkdir initrd -cd initrd -mkdir -p kernel/x86/microcode -cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin) -find . | cpio -o -H newc >../ucode.cpio -cd .. -cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img - -Builtin microcode -================= - -We can also load builtin microcode supplied through the regular firmware -builtin method CONFIG_FIRMWARE_IN_KERNEL. Only 64-bit is currently -supported. - -Here's an example: - -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" -CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" - -This basically means, you have the following tree structure locally: - -/lib/firmware/ -|-- amd-ucode -... -| |-- microcode_amd_fam15h.bin -... -|-- intel-ucode -... -| |-- 06-3a-09 -... - -so that the build system can find those files and integrate them into -the final kernel image. The early loader finds them and applies them. diff --git a/Documentation/x86/intel_rdt_ui.txt b/Documentation/x86/intel_rdt_ui.txt index c491a1b82de22a74d9559a418023fb8c312ffed4..4d8848e4e224a8eb8207c8fb7469be57340f1671 100644 --- a/Documentation/x86/intel_rdt_ui.txt +++ b/Documentation/x86/intel_rdt_ui.txt @@ -6,8 +6,8 @@ Fenghua Yu Tony Luck Vikas Shivappa -This feature is enabled by the CONFIG_INTEL_RDT_A Kconfig and the -X86 /proc/cpuinfo flag bits "rdt", "cat_l3" and "cdp_l3". +This feature is enabled by the CONFIG_INTEL_RDT Kconfig and the +X86 /proc/cpuinfo flag bits "rdt", "cqm", "cat_l3" and "cdp_l3". To use the feature mount the file system: @@ -17,6 +17,13 @@ mount options are: "cdp": Enable code/data prioritization in L3 cache allocations. +RDT features are orthogonal. A particular system may support only +monitoring, only control, or both monitoring and control. + +The mount succeeds if either of allocation or monitoring is present, but +only those files and directories supported by the system will be created. +For more details on the behavior of the interface during monitoring +and allocation, see the "Resource alloc and monitor groups" section. Info directory -------------- @@ -24,7 +31,12 @@ Info directory The 'info' directory contains information about the enabled resources. Each resource has its own subdirectory. The subdirectory names reflect the resource names. -Cache resource(L3/L2) subdirectory contains the following files: + +Each subdirectory contains the following files with respect to +allocation: + +Cache resource(L3/L2) subdirectory contains the following files +related to allocation: "num_closids": The number of CLOSIDs which are valid for this resource. The kernel uses the smallest number of @@ -36,7 +48,15 @@ Cache resource(L3/L2) subdirectory contains the following files: "min_cbm_bits": The minimum number of consecutive bits which must be set when writing a mask. -Memory bandwitdh(MB) subdirectory contains the following files: +"shareable_bits": Bitmask of shareable resource with other executing + entities (e.g. I/O). User can use this when + setting up exclusive cache partitions. Note that + some platforms support devices that have their + own settings for cache use which can over-ride + these bits. + +Memory bandwitdh(MB) subdirectory contains the following files +with respect to allocation: "min_bandwidth": The minimum memory bandwidth percentage which user can request. @@ -52,48 +72,152 @@ Memory bandwitdh(MB) subdirectory contains the following files: non-linear. This field is purely informational only. -Resource groups ---------------- +If RDT monitoring is available there will be an "L3_MON" directory +with the following files: + +"num_rmids": The number of RMIDs available. This is the + upper bound for how many "CTRL_MON" + "MON" + groups can be created. + +"mon_features": Lists the monitoring events if + monitoring is enabled for the resource. + +"max_threshold_occupancy": + Read/write file provides the largest value (in + bytes) at which a previously used LLC_occupancy + counter can be considered for re-use. + + +Resource alloc and monitor groups +--------------------------------- + Resource groups are represented as directories in the resctrl file -system. The default group is the root directory. Other groups may be -created as desired by the system administrator using the "mkdir(1)" -command, and removed using "rmdir(1)". +system. The default group is the root directory which, immediately +after mounting, owns all the tasks and cpus in the system and can make +full use of all resources. + +On a system with RDT control features additional directories can be +created in the root directory that specify different amounts of each +resource (see "schemata" below). The root and these additional top level +directories are referred to as "CTRL_MON" groups below. + +On a system with RDT monitoring the root directory and other top level +directories contain a directory named "mon_groups" in which additional +directories can be created to monitor subsets of tasks in the CTRL_MON +group that is their ancestor. These are called "MON" groups in the rest +of this document. + +Removing a directory will move all tasks and cpus owned by the group it +represents to the parent. Removing one of the created CTRL_MON groups +will automatically remove all MON groups below it. + +All groups contain the following files: + +"tasks": + Reading this file shows the list of all tasks that belong to + this group. Writing a task id to the file will add a task to the + group. If the group is a CTRL_MON group the task is removed from + whichever previous CTRL_MON group owned the task and also from + any MON group that owned the task. If the group is a MON group, + then the task must already belong to the CTRL_MON parent of this + group. The task is removed from any previous MON group. + + +"cpus": + Reading this file shows a bitmask of the logical CPUs owned by + this group. Writing a mask to this file will add and remove + CPUs to/from this group. As with the tasks file a hierarchy is + maintained where MON groups may only include CPUs owned by the + parent CTRL_MON group. + -There are three files associated with each group: +"cpus_list": + Just like "cpus", only using ranges of CPUs instead of bitmasks. -"tasks": A list of tasks that belongs to this group. Tasks can be - added to a group by writing the task ID to the "tasks" file - (which will automatically remove them from the previous - group to which they belonged). New tasks created by fork(2) - and clone(2) are added to the same group as their parent. - If a pid is not in any sub partition, it is in root partition - (i.e. default partition). -"cpus": A bitmask of logical CPUs assigned to this group. Writing - a new mask can add/remove CPUs from this group. Added CPUs - are removed from their previous group. Removed ones are - given to the default (root) group. You cannot remove CPUs - from the default group. +When control is enabled all CTRL_MON groups will also contain: -"cpus_list": One or more CPU ranges of logical CPUs assigned to this - group. Same rules apply like for the "cpus" file. +"schemata": + A list of all the resources available to this group. + Each resource has its own line and format - see below for details. -"schemata": A list of all the resources available to this group. - Each resource has its own line and format - see below for - details. +When monitoring is enabled all MON groups will also contain: -When a task is running the following rules define which resources -are available to it: +"mon_data": + This contains a set of files organized by L3 domain and by + RDT event. E.g. on a system with two L3 domains there will + be subdirectories "mon_L3_00" and "mon_L3_01". Each of these + directories have one file per event (e.g. "llc_occupancy", + "mbm_total_bytes", and "mbm_local_bytes"). In a MON group these + files provide a read out of the current value of the event for + all tasks in the group. In CTRL_MON groups these files provide + the sum for all tasks in the CTRL_MON group and all tasks in + MON groups. Please see example section for more details on usage. + +Resource allocation rules +------------------------- +When a task is running the following rules define which resources are +available to it: 1) If the task is a member of a non-default group, then the schemata -for that group is used. + for that group is used. 2) Else if the task belongs to the default group, but is running on a -CPU that is assigned to some specific group, then the schemata for -the CPU's group is used. + CPU that is assigned to some specific group, then the schemata for the + CPU's group is used. 3) Otherwise the schemata for the default group is used. +Resource monitoring rules +------------------------- +1) If a task is a member of a MON group, or non-default CTRL_MON group + then RDT events for the task will be reported in that group. + +2) If a task is a member of the default CTRL_MON group, but is running + on a CPU that is assigned to some specific group, then the RDT events + for the task will be reported in that group. + +3) Otherwise RDT events for the task will be reported in the root level + "mon_data" group. + + +Notes on cache occupancy monitoring and control +----------------------------------------------- +When moving a task from one group to another you should remember that +this only affects *new* cache allocations by the task. E.g. you may have +a task in a monitor group showing 3 MB of cache occupancy. If you move +to a new group and immediately check the occupancy of the old and new +groups you will likely see that the old group is still showing 3 MB and +the new group zero. When the task accesses locations still in cache from +before the move, the h/w does not update any counters. On a busy system +you will likely see the occupancy in the old group go down as cache lines +are evicted and re-used while the occupancy in the new group rises as +the task accesses memory and loads into the cache are counted based on +membership in the new group. + +The same applies to cache allocation control. Moving a task to a group +with a smaller cache partition will not evict any cache lines. The +process may continue to use them from the old partition. + +Hardware uses CLOSid(Class of service ID) and an RMID(Resource monitoring ID) +to identify a control group and a monitoring group respectively. Each of +the resource groups are mapped to these IDs based on the kind of group. The +number of CLOSid and RMID are limited by the hardware and hence the creation of +a "CTRL_MON" directory may fail if we run out of either CLOSID or RMID +and creation of "MON" group may fail if we run out of RMIDs. + +max_threshold_occupancy - generic concepts +------------------------------------------ + +Note that an RMID once freed may not be immediately available for use as +the RMID is still tagged the cache lines of the previous user of RMID. +Hence such RMIDs are placed on limbo list and checked back if the cache +occupancy has gone down. If there is a time when system has a lot of +limbo RMIDs but which are not ready to be used, user may see an -EBUSY +during mkdir. + +max_threshold_occupancy is a user configurable value to determine the +occupancy at which an RMID can be freed. Schemata files - general concepts --------------------------------- @@ -143,22 +267,22 @@ SKUs. Using a high bandwidth and a low bandwidth setting on two threads sharing a core will result in both threads being throttled to use the low bandwidth. -L3 details (code and data prioritization disabled) --------------------------------------------------- +L3 schemata file details (code and data prioritization disabled) +---------------------------------------------------------------- With CDP disabled the L3 schemata format is: L3:=;=;... -L3 details (CDP enabled via mount option to resctrl) ----------------------------------------------------- +L3 schemata file details (CDP enabled via mount option to resctrl) +------------------------------------------------------------------ When CDP is enabled L3 control is split into two separate resources so you can specify independent masks for code and data like this: L3data:=;=;... L3code:=;=;... -L2 details ----------- +L2 schemata file details +------------------------ L2 cache does not support code and data prioritization, so the schemata format is always: @@ -185,6 +309,8 @@ L3CODE:0=fffff;1=fffff;2=fffff;3=fffff L3DATA:0=fffff;1=fffff;2=3c0;3=fffff L3CODE:0=fffff;1=fffff;2=fffff;3=fffff +Examples for RDT allocation usage: + Example 1 --------- On a two socket machine (one L3 cache per socket) with just four bits @@ -410,3 +536,124 @@ void main(void) /* code to read and write directory contents */ resctrl_release_lock(fd); } + +Examples for RDT Monitoring along with allocation usage: + +Reading monitored data +---------------------- +Reading an event file (for ex: mon_data/mon_L3_00/llc_occupancy) would +show the current snapshot of LLC occupancy of the corresponding MON +group or CTRL_MON group. + + +Example 1 (Monitor CTRL_MON group and subset of tasks in CTRL_MON group) +--------- +On a two socket machine (one L3 cache per socket) with just four bits +for cache bit masks + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir p0 p1 +# echo "L3:0=3;1=c" > /sys/fs/resctrl/p0/schemata +# echo "L3:0=3;1=3" > /sys/fs/resctrl/p1/schemata +# echo 5678 > p1/tasks +# echo 5679 > p1/tasks + +The default resource group is unmodified, so we have access to all parts +of all caches (its schemata file reads "L3:0=f;1=f"). + +Tasks that are under the control of group "p0" may only allocate from the +"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1. +Tasks in group "p1" use the "lower" 50% of cache on both sockets. + +Create monitor groups and assign a subset of tasks to each monitor group. + +# cd /sys/fs/resctrl/p1/mon_groups +# mkdir m11 m12 +# echo 5678 > m11/tasks +# echo 5679 > m12/tasks + +fetch data (data shown in bytes) + +# cat m11/mon_data/mon_L3_00/llc_occupancy +16234000 +# cat m11/mon_data/mon_L3_01/llc_occupancy +14789000 +# cat m12/mon_data/mon_L3_00/llc_occupancy +16789000 + +The parent ctrl_mon group shows the aggregated data. + +# cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy +31234000 + +Example 2 (Monitor a task from its creation) +--------- +On a two socket machine (one L3 cache per socket) + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir p0 p1 + +An RMID is allocated to the group once its created and hence the +below is monitored from its creation. + +# echo $$ > /sys/fs/resctrl/p1/tasks +# + +Fetch the data + +# cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy +31789000 + +Example 3 (Monitor without CAT support or before creating CAT groups) +--------- + +Assume a system like HSW has only CQM and no CAT support. In this case +the resctrl will still mount but cannot create CTRL_MON directories. +But user can create different MON groups within the root group thereby +able to monitor all tasks including kernel threads. + +This can also be used to profile jobs cache size footprint before being +able to allocate them to different allocation groups. + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir mon_groups/m01 +# mkdir mon_groups/m02 + +# echo 3478 > /sys/fs/resctrl/mon_groups/m01/tasks +# echo 2467 > /sys/fs/resctrl/mon_groups/m02/tasks + +Monitor the groups separately and also get per domain data. From the +below its apparent that the tasks are mostly doing work on +domain(socket) 0. + +# cat /sys/fs/resctrl/mon_groups/m01/mon_L3_00/llc_occupancy +31234000 +# cat /sys/fs/resctrl/mon_groups/m01/mon_L3_01/llc_occupancy +34555 +# cat /sys/fs/resctrl/mon_groups/m02/mon_L3_00/llc_occupancy +31234000 +# cat /sys/fs/resctrl/mon_groups/m02/mon_L3_01/llc_occupancy +32789 + + +Example 4 (Monitor real time tasks) +----------------------------------- + +A single socket system which has real time tasks running on cores 4-7 +and non real time tasks on other cpus. We want to monitor the cache +occupancy of the real time threads on these cores. + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir p1 + +Move the cpus 4-7 over to p1 +# echo f0 > p0/cpus + +View the llc occupancy snapshot + +# cat /sys/fs/resctrl/p1/mon_data/mon_L3_00/llc_occupancy +11234000 diff --git a/Documentation/x86/microcode.txt b/Documentation/x86/microcode.txt new file mode 100644 index 0000000000000000000000000000000000000000..f57e1b45e628377268a6c17c963a5098917a3a1c --- /dev/null +++ b/Documentation/x86/microcode.txt @@ -0,0 +1,137 @@ + The Linux Microcode Loader + +Authors: Fenghua Yu + Borislav Petkov + +The kernel has a x86 microcode loading facility which is supposed to +provide microcode loading methods in the OS. Potential use cases are +updating the microcode on platforms beyond the OEM End-Of-Life support, +and updating the microcode on long-running systems without rebooting. + +The loader supports three loading methods: + +1. Early load microcode +======================= + +The kernel can update microcode very early during boot. Loading +microcode early can fix CPU issues before they are observed during +kernel boot time. + +The microcode is stored in an initrd file. During boot, it is read from +it and loaded into the CPU cores. + +The format of the combined initrd image is microcode in (uncompressed) +cpio format followed by the (possibly compressed) initrd image. The +loader parses the combined initrd image during boot. + +The microcode files in cpio name space are: + +on Intel: kernel/x86/microcode/GenuineIntel.bin +on AMD : kernel/x86/microcode/AuthenticAMD.bin + +During BSP (BootStrapping Processor) boot (pre-SMP), the kernel +scans the microcode file in the initrd. If microcode matching the +CPU is found, it will be applied in the BSP and later on in all APs +(Application Processors). + +The loader also saves the matching microcode for the CPU in memory. +Thus, the cached microcode patch is applied when CPUs resume from a +sleep state. + +Here's a crude example how to prepare an initrd with microcode (this is +normally done automatically by the distribution, when recreating the +initrd, so you don't really have to do it yourself. It is documented +here for future reference only). + +--- + #!/bin/bash + + if [ -z "$1" ]; then + echo "You need to supply an initrd file" + exit 1 + fi + + INITRD="$1" + + DSTDIR=kernel/x86/microcode + TMPDIR=/tmp/initrd + + rm -rf $TMPDIR + + mkdir $TMPDIR + cd $TMPDIR + mkdir -p $DSTDIR + + if [ -d /lib/firmware/amd-ucode ]; then + cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin + fi + + if [ -d /lib/firmware/intel-ucode ]; then + cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin + fi + + find . | cpio -o -H newc >../ucode.cpio + cd .. + mv $INITRD $INITRD.orig + cat ucode.cpio $INITRD.orig > $INITRD + + rm -rf $TMPDIR +--- + +The system needs to have the microcode packages installed into +/lib/firmware or you need to fixup the paths above if yours are +somewhere else and/or you've downloaded them directly from the processor +vendor's site. + +2. Late loading +=============== + +There are two legacy user space interfaces to load microcode, either through +/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file +in sysfs. + +The /dev/cpu/microcode method is deprecated because it needs a special +userspace tool for that. + +The easier method is simply installing the microcode packages your distro +supplies and running: + +# echo 1 > /sys/devices/system/cpu/microcode/reload + +as root. + +The loading mechanism looks for microcode blobs in +/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation +packages already put them there. + +3. Builtin microcode +==================== + +The loader supports also loading of a builtin microcode supplied through +the regular firmware builtin method CONFIG_FIRMWARE_IN_KERNEL. Only +64-bit is currently supported. + +Here's an example: + +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" +CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" + +This basically means, you have the following tree structure locally: + +/lib/firmware/ +|-- amd-ucode +... +| |-- microcode_amd_fam15h.bin +... +|-- intel-ucode +... +| |-- 06-3a-09 +... + +so that the build system can find those files and integrate them into +the final kernel image. The early loader finds them and applies them. + +Needless to say, this method is not the most flexible one because it +requires rebuilding the kernel each time updated microcode from the CPU +vendor is available. diff --git a/Documentation/x86/orc-unwinder.txt b/Documentation/x86/orc-unwinder.txt new file mode 100644 index 0000000000000000000000000000000000000000..af0c9a4c65a6dab9d5b806dadb011209de718c33 --- /dev/null +++ b/Documentation/x86/orc-unwinder.txt @@ -0,0 +1,179 @@ +ORC unwinder +============ + +Overview +-------- + +The kernel CONFIG_ORC_UNWINDER option enables the ORC unwinder, which is +similar in concept to a DWARF unwinder. The difference is that the +format of the ORC data is much simpler than DWARF, which in turn allows +the ORC unwinder to be much simpler and faster. + +The ORC data consists of unwind tables which are generated by objtool. +They contain out-of-band data which is used by the in-kernel ORC +unwinder. Objtool generates the ORC data by first doing compile-time +stack metadata validation (CONFIG_STACK_VALIDATION). After analyzing +all the code paths of a .o file, it determines information about the +stack state at each instruction address in the file and outputs that +information to the .orc_unwind and .orc_unwind_ip sections. + +The per-object ORC sections are combined at link time and are sorted and +post-processed at boot time. The unwinder uses the resulting data to +correlate instruction addresses with their stack states at run time. + + +ORC vs frame pointers +--------------------- + +With frame pointers enabled, GCC adds instrumentation code to every +function in the kernel. The kernel's .text size increases by about +3.2%, resulting in a broad kernel-wide slowdown. Measurements by Mel +Gorman [1] have shown a slowdown of 5-10% for some workloads. + +In contrast, the ORC unwinder has no effect on text size or runtime +performance, because the debuginfo is out of band. So if you disable +frame pointers and enable the ORC unwinder, you get a nice performance +improvement across the board, and still have reliable stack traces. + +Ingo Molnar says: + + "Note that it's not just a performance improvement, but also an + instruction cache locality improvement: 3.2% .text savings almost + directly transform into a similarly sized reduction in cache + footprint. That can transform to even higher speedups for workloads + whose cache locality is borderline." + +Another benefit of ORC compared to frame pointers is that it can +reliably unwind across interrupts and exceptions. Frame pointer based +unwinds can sometimes skip the caller of the interrupted function, if it +was a leaf function or if the interrupt hit before the frame pointer was +saved. + +The main disadvantage of the ORC unwinder compared to frame pointers is +that it needs more memory to store the ORC unwind tables: roughly 2-4MB +depending on the kernel config. + + +ORC vs DWARF +------------ + +ORC debuginfo's advantage over DWARF itself is that it's much simpler. +It gets rid of the complex DWARF CFI state machine and also gets rid of +the tracking of unnecessary registers. This allows the unwinder to be +much simpler, meaning fewer bugs, which is especially important for +mission critical oops code. + +The simpler debuginfo format also enables the unwinder to be much faster +than DWARF, which is important for perf and lockdep. In a basic +performance test by Jiri Slaby [2], the ORC unwinder was about 20x +faster than an out-of-tree DWARF unwinder. (Note: That measurement was +taken before some performance tweaks were added, which doubled +performance, so the speedup over DWARF may be closer to 40x.) + +The ORC data format does have a few downsides compared to DWARF. ORC +unwind tables take up ~50% more RAM (+1.3MB on an x86 defconfig kernel) +than DWARF-based eh_frame tables. + +Another potential downside is that, as GCC evolves, it's conceivable +that the ORC data may end up being *too* simple to describe the state of +the stack for certain optimizations. But IMO this is unlikely because +GCC saves the frame pointer for any unusual stack adjustments it does, +so I suspect we'll really only ever need to keep track of the stack +pointer and the frame pointer between call frames. But even if we do +end up having to track all the registers DWARF tracks, at least we will +still be able to control the format, e.g. no complex state machines. + + +ORC unwind table generation +--------------------------- + +The ORC data is generated by objtool. With the existing compile-time +stack metadata validation feature, objtool already follows all code +paths, and so it already has all the information it needs to be able to +generate ORC data from scratch. So it's an easy step to go from stack +validation to ORC data generation. + +It should be possible to instead generate the ORC data with a simple +tool which converts DWARF to ORC data. However, such a solution would +be incomplete due to the kernel's extensive use of asm, inline asm, and +special sections like exception tables. + +That could be rectified by manually annotating those special code paths +using GNU assembler .cfi annotations in .S files, and homegrown +annotations for inline asm in .c files. But asm annotations were tried +in the past and were found to be unmaintainable. They were often +incorrect/incomplete and made the code harder to read and keep updated. +And based on looking at glibc code, annotating inline asm in .c files +might be even worse. + +Objtool still needs a few annotations, but only in code which does +unusual things to the stack like entry code. And even then, far fewer +annotations are needed than what DWARF would need, so they're much more +maintainable than DWARF CFI annotations. + +So the advantages of using objtool to generate ORC data are that it +gives more accurate debuginfo, with very few annotations. It also +insulates the kernel from toolchain bugs which can be very painful to +deal with in the kernel since we often have to workaround issues in +older versions of the toolchain for years. + +The downside is that the unwinder now becomes dependent on objtool's +ability to reverse engineer GCC code flow. If GCC optimizations become +too complicated for objtool to follow, the ORC data generation might +stop working or become incomplete. (It's worth noting that livepatch +already has such a dependency on objtool's ability to follow GCC code +flow.) + +If newer versions of GCC come up with some optimizations which break +objtool, we may need to revisit the current implementation. Some +possible solutions would be asking GCC to make the optimizations more +palatable, or having objtool use DWARF as an additional input, or +creating a GCC plugin to assist objtool with its analysis. But for now, +objtool follows GCC code quite well. + + +Unwinder implementation details +------------------------------- + +Objtool generates the ORC data by integrating with the compile-time +stack metadata validation feature, which is described in detail in +tools/objtool/Documentation/stack-validation.txt. After analyzing all +the code paths of a .o file, it creates an array of orc_entry structs, +and a parallel array of instruction addresses associated with those +structs, and writes them to the .orc_unwind and .orc_unwind_ip sections +respectively. + +The ORC data is split into the two arrays for performance reasons, to +make the searchable part of the data (.orc_unwind_ip) more compact. The +arrays are sorted in parallel at boot time. + +Performance is further improved by the use of a fast lookup table which +is created at runtime. The fast lookup table associates a given address +with a range of indices for the .orc_unwind table, so that only a small +subset of the table needs to be searched. + + +Etymology +--------- + +Orcs, fearsome creatures of medieval folklore, are the Dwarves' natural +enemies. Similarly, the ORC unwinder was created in opposition to the +complexity and slowness of DWARF. + +"Although Orcs rarely consider multiple solutions to a problem, they do +excel at getting things done because they are creatures of action, not +thought." [3] Similarly, unlike the esoteric DWARF unwinder, the +veracious ORC unwinder wastes no time or siloconic effort decoding +variable-length zero-extended unsigned-integer byte-coded +state-machine-based debug information entries. + +Similar to how Orcs frequently unravel the well-intentioned plans of +their adversaries, the ORC unwinder frequently unravels stacks with +brutal, unyielding efficiency. + +ORC stands for Oops Rewind Capability. + + +[1] https://lkml.kernel.org/r/20170602104048.jkkzssljsompjdwy@suse.de +[2] https://lkml.kernel.org/r/d2ca5435-6386-29b8-db87-7f227c2b713a@suse.cz +[3] http://dustin.wikidot.com/half-orcs-and-orcs diff --git a/Documentation/x86/protection-keys.txt b/Documentation/x86/protection-keys.txt index b643045408218669de1af81b9a9a661c035ffc70..fa46dcb347bc1d2ac60901c4621bd3bad81de601 100644 --- a/Documentation/x86/protection-keys.txt +++ b/Documentation/x86/protection-keys.txt @@ -34,7 +34,7 @@ with a key. In this example WRPKRU is wrapped by a C function called pkey_set(). int real_prot = PROT_READ|PROT_WRITE; - pkey = pkey_alloc(0, PKEY_DENY_WRITE); + pkey = pkey_alloc(0, PKEY_DISABLE_WRITE); ptr = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); ret = pkey_mprotect(ptr, PAGE_SIZE, real_prot, pkey); ... application runs here @@ -42,9 +42,9 @@ called pkey_set(). Now, if the application needs to update the data at 'ptr', it can gain access, do the update, then remove its write access: - pkey_set(pkey, 0); // clear PKEY_DENY_WRITE + pkey_set(pkey, 0); // clear PKEY_DISABLE_WRITE *ptr = foo; // assign something - pkey_set(pkey, PKEY_DENY_WRITE); // set PKEY_DENY_WRITE again + pkey_set(pkey, PKEY_DISABLE_WRITE); // set PKEY_DISABLE_WRITE again Now when it frees the memory, it will also free the pkey since it is no longer in use: diff --git a/Documentation/x86/x86_64/5level-paging.txt b/Documentation/x86/x86_64/5level-paging.txt new file mode 100644 index 0000000000000000000000000000000000000000..087251a0d99cbd6ea2a76a1da687c3fbe528e769 --- /dev/null +++ b/Documentation/x86/x86_64/5level-paging.txt @@ -0,0 +1,64 @@ +== Overview == + +Original x86-64 was limited by 4-level paing to 256 TiB of virtual address +space and 64 TiB of physical address space. We are already bumping into +this limit: some vendors offers servers with 64 TiB of memory today. + +To overcome the limitation upcoming hardware will introduce support for +5-level paging. It is a straight-forward extension of the current page +table structure adding one more layer of translation. + +It bumps the limits to 128 PiB of virtual address space and 4 PiB of +physical address space. This "ought to be enough for anybody" ©. + +QEMU 2.9 and later support 5-level paging. + +Virtual memory layout for 5-level paging is described in +Documentation/x86/x86_64/mm.txt + +== Enabling 5-level paging == + +CONFIG_X86_5LEVEL=y enables the feature. + +So far, a kernel compiled with the option enabled will be able to boot +only on machines that supports the feature -- see for 'la57' flag in +/proc/cpuinfo. + +The plan is to implement boot-time switching between 4- and 5-level paging +in the future. + +== User-space and large virtual address space == + +On x86, 5-level paging enables 56-bit userspace virtual address space. +Not all user space is ready to handle wide addresses. It's known that +at least some JIT compilers use higher bits in pointers to encode their +information. It collides with valid pointers with 5-level paging and +leads to crashes. + +To mitigate this, we are not going to allocate virtual address space +above 47-bit by default. + +But userspace can ask for allocation from full address space by +specifying hint address (with or without MAP_FIXED) above 47-bits. + +If hint address set above 47-bit, but MAP_FIXED is not specified, we try +to look for unmapped area by specified address. If it's already +occupied, we look for unmapped area in *full* address space, rather than +from 47-bit window. + +A high hint address would only affect the allocation in question, but not +any future mmap()s. + +Specifying high hint address on older kernel or on machine without 5-level +paging support is safe. The hint will be ignored and kernel will fall back +to allocation from 47-bit address space. + +This approach helps to easily make application's memory allocator aware +about large address space without manually tracking allocated virtual +address space. + +One important case we need to handle here is interaction with MPX. +MPX (without MAWA extension) cannot handle addresses above 47-bit, so we +need to make sure that MPX cannot be enabled we already have VMA above +the boundary and forbid creating such VMAs once MPX is enabled. + diff --git a/MAINTAINERS b/MAINTAINERS index f66488dfdbc9cc59fc744ce9f8349b9b69bd945c..2d3d750b19c0cddf8af39786faed78709f7bbba1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -301,6 +301,7 @@ S: Supported F: drivers/acpi/ F: drivers/pnp/pnpacpi/ F: include/linux/acpi.h +F: include/linux/fwnode.h F: include/acpi/ F: Documentation/acpi/ F: Documentation/ABI/testing/sysfs-bus-acpi @@ -310,6 +311,14 @@ F: drivers/pci/*/*acpi* F: drivers/pci/*/*/*acpi* F: tools/power/acpi/ +ACPI APEI +M: "Rafael J. Wysocki" +M: Len Brown +L: linux-acpi@vger.kernel.org +R: Tony Luck +R: Borislav Petkov +F: drivers/acpi/apei/ + ACPI COMPONENT ARCHITECTURE (ACPICA) M: Robert Moore M: Lv Zheng @@ -343,6 +352,18 @@ L: linux-acpi@vger.kernel.org S: Maintained F: drivers/acpi/arm64 +ACPI PMIC DRIVERS +M: "Rafael J. Wysocki" +M: Len Brown +R: Andy Shevchenko +R: Mika Westerberg +L: linux-acpi@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-acpi/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm +B: https://bugzilla.kernel.org +S: Supported +F: drivers/acpi/pmic/ + ACPI THERMAL DRIVER M: Zhang Rui L: linux-acpi@vger.kernel.org @@ -635,6 +656,11 @@ ALPS PS/2 TOUCHPAD DRIVER R: Pali Rohár F: drivers/input/mouse/alps.* +ALTERA I2C CONTROLLER DRIVER +M: Thor Thayer +S: Maintained +F: drivers/i2c/busses/i2c-altera.c + ALTERA MAILBOX DRIVER M: Ley Foon Tan L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) @@ -769,6 +795,12 @@ W: http://ez.analog.com/community/linux-device-drivers S: Supported F: drivers/media/i2c/adv7180.c +ANALOG DEVICES INC ADV748X DRIVER +M: Kieran Bingham +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/i2c/adv748x/* + ANALOG DEVICES INC ADV7511 DRIVER M: Hans Verkuil L: linux-media@vger.kernel.org @@ -840,6 +872,12 @@ S: Supported F: drivers/android/ F: drivers/staging/android/ +ANDROID GOLDFISH RTC DRIVER +M: Miodrag Dinic +S: Supported +F: Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt +F: drivers/rtc/rtc-goldfish.c + ANDROID ION DRIVER M: Laura Abbott M: Sumit Semwal @@ -1153,6 +1191,7 @@ L: linux-arm-kernel@axis.com F: arch/arm/mach-artpec F: arch/arm/boot/dts/artpec6* F: drivers/clk/axis +F: drivers/crypto/axis F: drivers/pinctrl/pinctrl-artpec* F: Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt @@ -1161,7 +1200,7 @@ M: Brendan Higgins R: Benjamin Herrenschmidt R: Joel Stanley L: linux-i2c@vger.kernel.org -L: openbmc@lists.ozlabs.org +L: openbmc@lists.ozlabs.org (moderated for non-subscribers) S: Maintained F: drivers/irqchip/irq-aspeed-i2c-ic.c F: drivers/i2c/busses/i2c-aspeed.c @@ -1282,10 +1321,15 @@ S: Maintained ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE M: Hans Ulli Kroll +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/ulli-kroll/linux.git S: Maintained +F: Documentation/devicetree/bindings/arm/gemini.txt +F: Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt +F: Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt F: arch/arm/mach-gemini/ +F: drivers/pinctrl/pinctrl-gemini.c F: drivers/rtc/rtc-ftrtc010.c ARM/CSR SIRFPRIMA2 MACHINE SUPPORT @@ -1570,7 +1614,7 @@ M: Chunfeng Yun L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: drivers/phy/phy-mt65xx-usb3.c +F: drivers/phy/mediatek/phy-mtk-tphy.c ARM/MICREL KS8695 ARCHITECTURE M: Greg Ungerer @@ -1993,6 +2037,7 @@ F: arch/arm64/boot/dts/socionext/ F: drivers/bus/uniphier-system-bus.c F: drivers/clk/uniphier/ F: drivers/i2c/busses/i2c-uniphier* +F: drivers/irqchip/irq-uniphier-aidet.c F: drivers/pinctrl/uniphier/ F: drivers/reset/reset-uniphier.c F: drivers/tty/serial/8250/8250_uniphier.c @@ -2079,17 +2124,38 @@ F: arch/arm/mach-pxa/include/mach/z2.h ARM/ZTE ARCHITECTURE M: Jun Nie M: Baoyou Xie +M: Shawn Guo L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +F: arch/arm/boot/dts/zx2967* F: arch/arm/mach-zx/ +F: arch/arm64/boot/dts/zte/ F: drivers/clk/zte/ +F: drivers/dma/zx_dma.c +F: drivers/gpio/gpio-zx.c +F: drivers/i2c/busses/i2c-zx2967.c +F: drivers/mmc/host/dw_mmc-zx.* +F: drivers/pinctrl/zte/ F: drivers/reset/reset-zx2967.c F: drivers/soc/zte/ +F: drivers/thermal/zx2967_thermal.c +F: drivers/watchdog/zx2967_wdt.c F: Documentation/devicetree/bindings/arm/zte.txt -F: Documentation/devicetree/bindings/clock/zx296702-clk.txt +F: Documentation/devicetree/bindings/clock/zx2967*.txt +F: Documentation/devicetree/bindings/dma/zxdma.txt +F: Documentation/devicetree/bindings/gpio/zx296702-gpio.txt +F: Documentation/devicetree/bindings/i2c/i2c-zx2967.txt +F: Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt +F: Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt F: Documentation/devicetree/bindings/soc/zte/ -F: include/dt-bindings/soc/zx*.h +F: Documentation/devicetree/bindings/sound/zte,*.txt +F: Documentation/devicetree/bindings/thermal/zx2967-thermal.txt +F: Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt +F: include/dt-bindings/clock/zx2967*.h +F: include/dt-bindings/soc/zte,*.h +F: sound/soc/codecs/zx_aud96p22.c +F: sound/soc/zte/ ARM/ZYNQ ARCHITECTURE M: Michal Simek @@ -2117,6 +2183,12 @@ S: Maintained F: arch/arm64/ F: Documentation/arm64/ +AS3645A LED FLASH CONTROLLER DRIVER +M: Sakari Ailus +L: linux-leds@vger.kernel.org +S: Maintained +F: drivers/leds/leds-as3645a.c + AS3645A LED FLASH CONTROLLER DRIVER M: Laurent Pinchart L: linux-media@vger.kernel.org @@ -2385,9 +2457,10 @@ AUDIT SUBSYSTEM M: Paul Moore M: Eric Paris L: linux-audit@redhat.com (moderated for non-subscribers) -W: http://people.redhat.com/sgrubb/audit/ -T: git git://git.infradead.org/users/pcmoore/audit -S: Maintained +W: https://github.com/linux-audit +W: https://people.redhat.com/sgrubb/audit +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git +S: Supported F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -2477,7 +2550,7 @@ Q: https://patchwork.open-mesh.org/project/batman/list/ S: Maintained F: Documentation/ABI/testing/sysfs-class-net-batman-adv F: Documentation/ABI/testing/sysfs-class-net-mesh -F: Documentation/networking/batman-adv.txt +F: Documentation/networking/batman-adv.rst F: include/uapi/linux/batman_adv.h F: net/batman-adv/ @@ -2546,13 +2619,6 @@ W: http://blackfin.uclinux.org S: Supported F: drivers/net/ethernet/adi/ -BLACKFIN I2C TWI DRIVER -M: Sonic Zhang -L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) -W: http://blackfin.uclinux.org/ -S: Supported -F: drivers/i2c/busses/i2c-bfin-twi.c - BLACKFIN MEDIA DRIVER M: Scott Jiang L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) @@ -2569,14 +2635,12 @@ S: Supported F: drivers/rtc/rtc-bfin.c BLACKFIN SDH DRIVER -M: Sonic Zhang L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://blackfin.uclinux.org S: Supported F: drivers/mmc/host/bfin_sdh.c BLACKFIN SERIAL DRIVER -M: Sonic Zhang L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://blackfin.uclinux.org S: Supported @@ -2801,7 +2865,6 @@ S: Supported F: drivers/scsi/bnx2i/ BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER -M: Yuval Mintz M: Ariel Elior M: everest-linux-l2@cavium.com L: netdev@vger.kernel.org @@ -3155,6 +3218,7 @@ S: Supported F: drivers/crypto/cavium/cpt/ CAVIUM THUNDERX2 ARM64 SOC +M: Robert Richter M: Jayachandran C L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained @@ -4108,7 +4172,9 @@ F: include/linux/dax.h F: include/trace/events/fs_dax.h DIRECTORY NOTIFICATION (DNOTIFY) -M: Eric Paris +M: Jan Kara +R: Amir Goldstein +L: linux-fsdevel@vger.kernel.org S: Maintained F: Documentation/filesystems/dnotify.txt F: fs/notify/dnotify/ @@ -4175,7 +4241,7 @@ DMA MAPPING HELPERS M: Christoph Hellwig M: Marek Szyprowski R: Robin Murphy -L: linux-kernel@vger.kernel.org +L: iommu@lists.linux-foundation.org T: git git://git.infradead.org/users/hch/dma-mapping.git W: http://git.infradead.org/users/hch/dma-mapping.git S: Supported @@ -4341,6 +4407,12 @@ S: Supported F: drivers/gpu/drm/nouveau/ F: include/uapi/drm/nouveau_drm.h +DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS +M: Noralf Trønnes +S: Maintained +F: drivers/gpu/drm/tinydrm/repaper.c +F: Documentation/devicetree/bindings/display/repaper.txt + DRM DRIVER FOR QEMU'S CIRRUS DEVICE M: Dave Airlie M: Gerd Hoffmann @@ -4374,6 +4446,12 @@ S: Orphan / Obsolete F: drivers/gpu/drm/sis/ F: include/uapi/drm/sis_drm.h +DRM DRIVER FOR SITRONIX ST7586 PANELS +M: David Lechner +S: Maintained +F: drivers/gpu/drm/tinydrm/st7586.c +F: Documentation/devicetree/bindings/display/st7586.txt + DRM DRIVER FOR TDFX VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/tdfx/ @@ -4622,6 +4700,14 @@ F: drivers/gpu/drm/panel/ F: include/drm/drm_panel.h F: Documentation/devicetree/bindings/display/panel/ +DRM TINYDRM DRIVERS +M: Noralf Trønnes +W: https://github.com/notro/tinydrm/wiki/Development +T: git git://anongit.freedesktop.org/drm/drm-misc +S: Maintained +F: drivers/gpu/drm/tinydrm/ +F: include/drm/tinydrm/ + DSBR100 USB FM RADIO DRIVER M: Alexey Klimov L: linux-media@vger.kernel.org @@ -5090,12 +5176,21 @@ M: Andrew Lunn M: Florian Fainelli L: netdev@vger.kernel.org S: Maintained -F: include/linux/phy.h -F: include/linux/phy_fixed.h -F: drivers/net/phy/ +F: Documentation/ABI/testing/sysfs-bus-mdio +F: Documentation/devicetree/bindings/net/mdio* F: Documentation/networking/phy.txt +F: drivers/net/phy/ F: drivers/of/of_mdio.c F: drivers/of/of_net.c +F: include/linux/*mdio*.h +F: include/linux/of_net.h +F: include/linux/phy.h +F: include/linux/phy_fixed.h +F: include/linux/platform_data/mdio-gpio.h +F: include/linux/platform_data/mdio-bcm-unimac.h +F: include/trace/events/mdio.h +F: include/uapi/linux/mdio.h +F: include/uapi/linux/mii.h EXT2 FILE SYSTEM M: Jan Kara @@ -5164,7 +5259,8 @@ S: Maintained F: drivers/iommu/exynos-iommu.c EZchip NPS platform support -M: Noam Camus +M: Elad Kanfi +M: Vineet Gupta S: Supported F: arch/arc/plat-eznps F: arch/arc/boot/dts/eznps.dts @@ -5190,7 +5286,9 @@ F: Documentation/hwmon/f71805f F: drivers/hwmon/f71805f.c FANOTIFY -M: Eric Paris +M: Jan Kara +R: Amir Goldstein +L: linux-fsdevel@vger.kernel.org S: Maintained F: fs/notify/fanotify/ F: include/linux/fanotify.h @@ -5333,10 +5431,11 @@ K: fmc_d.*register FPGA MANAGER FRAMEWORK M: Alan Tull -R: Moritz Fischer +R: Moritz Fischer L: linux-fpga@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git +Q: http://patchwork.kernel.org/project/linux-fpga/list/ F: Documentation/fpga/ F: Documentation/devicetree/bindings/fpga/ F: drivers/fpga/ @@ -5755,6 +5854,12 @@ S: Maintained F: Documentation/acpi/gpio-properties.txt F: drivers/gpio/gpiolib-acpi.c +GPIO IR Transmitter +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/gpio-ir-tx.c + GPIO MOCKUP DRIVER M: Bamvor Jian Zhang L: linux-gpio@vger.kernel.org @@ -5826,7 +5931,7 @@ F: drivers/staging/greybus/spi.c F: drivers/staging/greybus/spilib.c F: drivers/staging/greybus/spilib.h -GREYBUS LOOBACK/TIME PROTOCOLS DRIVERS +GREYBUS LOOPBACK/TIME PROTOCOLS DRIVERS M: Bryan O'Donoghue S: Maintained F: drivers/staging/greybus/loopback.c @@ -6024,16 +6129,6 @@ F: drivers/scsi/hpsa*.[ch] F: include/linux/cciss*.h F: include/uapi/linux/cciss*.h -HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) -M: Don Brace -L: esc.storagedev@microsemi.com -L: linux-scsi@vger.kernel.org -S: Supported -F: Documentation/blockdev/cciss.txt -F: drivers/block/cciss* -F: include/linux/cciss_ioctl.h -F: include/uapi/linux/cciss_ioctl.h - HFI1 DRIVER M: Mike Marciniszyn M: Dennis Dalessandro @@ -6130,6 +6225,14 @@ F: include/uapi/linux/if_hippi.h F: net/802/hippi.c F: drivers/net/hippi/ +HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) +M: Yisen Zhuang +M: Salil Mehta +L: netdev@vger.kernel.org +W: http://www.hisilicon.com +S: Maintained +F: drivers/net/ethernet/hisilicon/hns3/ + HISILICON NETWORK SUBSYSTEM DRIVER M: Yisen Zhuang M: Salil Mehta @@ -6154,6 +6257,13 @@ S: Supported F: drivers/scsi/hisi_sas/ F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +HMM - Heterogeneous Memory Management +M: Jérôme Glisse +L: linux-mm@kvack.org +S: Maintained +F: mm/hmm* +F: include/linux/hmm* + HOST AP DRIVER M: Jouni Malinen L: linux-wireless@vger.kernel.org @@ -6223,6 +6333,13 @@ L: linux-input@vger.kernel.org S: Maintained F: drivers/input/touchscreen/htcpen.c +HUAWEI ETHERNET DRIVER +M: Aviad Krawczyk +L: netdev@vger.kernel.org +S: Supported +F: Documentation/networking/hinic.txt +F: drivers/net/ethernet/huawei/hinic/ + HUGETLB FILESYSTEM M: Nadia Yvette Chambers S: Maintained @@ -6249,7 +6366,9 @@ M: Haiyang Zhang M: Stephen Hemminger L: devel@linuxdriverproject.org S: Maintained +F: Documentation/networking/netvsc.txt F: arch/x86/include/asm/mshyperv.h +F: arch/x86/include/asm/trace/hyperv.h F: arch/x86/include/uapi/asm/hyperv.h F: arch/x86/kernel/cpu/mshyperv.c F: arch/x86/hyperv @@ -6261,7 +6380,9 @@ F: drivers/net/hyperv/ F: drivers/scsi/storvsc_drv.c F: drivers/uio/uio_hv_generic.c F: drivers/video/fbdev/hyperv_fb.c +F: net/vmw_vsock/hyperv_transport.c F: include/linux/hyperv.h +F: include/uapi/linux/hyperv.h F: tools/hv/ F: Documentation/ABI/stable/sysfs-bus-vmbus @@ -6363,6 +6484,12 @@ F: drivers/i2c/busses/i2c-sis96x.c F: drivers/i2c/busses/i2c-via.c F: drivers/i2c/busses/i2c-viapro.c +I2C/SMBUS INTEL CHT WHISKEY COVE PMIC DRIVER +M: Hans de Goede +L: linux-i2c@vger.kernel.org +S: Maintained +F: drivers/i2c/busses/i2c-cht-wc.c + I2C/SMBUS ISMT DRIVER M: Seth Heasley M: Neil Horman @@ -6429,6 +6556,15 @@ L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/ibm/ibmvnic.* +IBM Power Virtual Accelerator Switchboard +M: Sukadev Bhattiprolu +L: linuxppc-dev@lists.ozlabs.org +S: Supported +F: arch/powerpc/platforms/powernv/vas* +F: arch/powerpc/platforms/powernv/copy-paste.h +F: arch/powerpc/include/asm/vas.h +F: arch/powerpc/include/uapi/asm/vas.h + IBM Power Virtual Ethernet Device Driver M: Thomas Falcon L: netdev@vger.kernel.org @@ -6519,8 +6655,8 @@ M: Alexander Aring M: Stefan Schmidt L: linux-wpan@vger.kernel.org W: http://wpan.cakelab.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git S: Maintained F: net/ieee802154/ F: net/mac802154/ @@ -6603,7 +6739,7 @@ F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt F: drivers/auxdisplay/img-ascii-lcd.c IMGTEC IR DECODER DRIVER -M: James Hogan +M: James Hogan S: Maintained F: drivers/media/rc/img-ir/ @@ -6665,9 +6801,9 @@ S: Maintained F: drivers/mtd/nand/jz4780_* INOTIFY -M: John McCutchan -M: Robert Love -M: Eric Paris +M: Jan Kara +R: Amir Goldstein +L: linux-fsdevel@vger.kernel.org S: Maintained F: Documentation/filesystems/inotify.txt F: fs/notify/inotify/ @@ -6736,8 +6872,9 @@ S: Supported F: drivers/scsi/isci/ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) -M: Daniel Vetter M: Jani Nikula +M: Joonas Lahtinen +M: Rodrigo Vivi L: intel-gfx@lists.freedesktop.org W: https://01.org/linuxgraphics/ B: https://01.org/linuxgraphics/documentation/how-report-bugs @@ -7075,9 +7212,7 @@ W: http://irda.sourceforge.net/ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git F: Documentation/networking/irda.txt -F: drivers/net/irda/ -F: include/net/irda/ -F: net/irda/ +F: drivers/staging/irda/ IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) M: Marc Zyngier @@ -7102,7 +7237,6 @@ M: Marc Zyngier L: linux-kernel@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core -T: git git://git.infradead.org/users/jcooper/linux.git irqchip/core F: Documentation/devicetree/bindings/interrupt-controller/ F: drivers/irqchip/ @@ -7372,6 +7506,13 @@ S: Maintained F: tools/testing/selftests/ F: Documentation/dev-tools/kselftest* +KERNEL USERMODE HELPER +M: "Luis R. Rodriguez" +L: linux-kernel@vger.kernel.org +S: Maintained +F: kernel/umh.c +F: include/linux/umh.h + KERNEL VIRTUAL MACHINE (KVM) M: Paolo Bonzini M: Radim KrÄmář @@ -7379,18 +7520,17 @@ L: kvm@vger.kernel.org W: http://www.linux-kvm.org T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git S: Supported -F: Documentation/*/kvm*.txt F: Documentation/virtual/kvm/ -F: arch/*/kvm/ -F: arch/x86/kernel/kvm.c -F: arch/x86/kernel/kvmclock.c -F: arch/*/include/asm/kvm* -F: include/linux/kvm* +F: include/trace/events/kvm.h +F: include/uapi/asm-generic/kvm* F: include/uapi/linux/kvm* -F: virt/kvm/ +F: include/asm-generic/kvm* +F: include/linux/kvm* +F: include/kvm/iodev.h +F: virt/kvm/* F: tools/kvm/ -KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V +KERNEL VIRTUAL MACHINE FOR AMD-V (KVM/amd) M: Joerg Roedel L: kvm@vger.kernel.org W: http://www.linux-kvm.org/ @@ -7398,7 +7538,7 @@ S: Maintained F: arch/x86/include/asm/svm.h F: arch/x86/kvm/svm.c -KERNEL VIRTUAL MACHINE (KVM) FOR ARM +KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm) M: Christoffer Dall M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -7412,15 +7552,6 @@ F: arch/arm/kvm/ F: virt/kvm/arm/ F: include/kvm/arm_* -KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC -M: Alexander Graf -L: kvm-ppc@vger.kernel.org -W: http://www.linux-kvm.org/ -T: git git://github.com/agraf/linux-2.6.git -S: Supported -F: arch/powerpc/include/asm/kvm* -F: arch/powerpc/kvm/ - KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) M: Christoffer Dall M: Marc Zyngier @@ -7432,13 +7563,24 @@ F: arch/arm64/include/asm/kvm* F: arch/arm64/kvm/ KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips) -M: James Hogan +M: James Hogan L: linux-mips@linux-mips.org S: Supported F: arch/mips/include/uapi/asm/kvm* F: arch/mips/include/asm/kvm* F: arch/mips/kvm/ +KERNEL VIRTUAL MACHINE FOR POWERPC (KVM/powerpc) +M: Alexander Graf +L: kvm-ppc@vger.kernel.org +W: http://www.linux-kvm.org/ +T: git git://github.com/agraf/linux-2.6.git +S: Supported +F: arch/powerpc/include/uapi/asm/kvm* +F: arch/powerpc/include/asm/kvm* +F: arch/powerpc/kvm/ +F: arch/powerpc/kernel/kvm* + KERNEL VIRTUAL MACHINE for s390 (KVM/s390) M: Christian Borntraeger M: Cornelia Huck @@ -7446,11 +7588,25 @@ L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git S: Supported -F: Documentation/s390/kvm.txt +F: arch/s390/include/uapi/asm/kvm* +F: arch/s390/include/asm/gmap.h F: arch/s390/include/asm/kvm* F: arch/s390/kvm/ F: arch/s390/mm/gmap.c +KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) +M: Paolo Bonzini +M: Radim KrÄmář +L: kvm@vger.kernel.org +W: http://www.linux-kvm.org +T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git +S: Supported +F: arch/x86/kvm/ +F: arch/x86/include/uapi/asm/kvm* +F: arch/x86/include/asm/kvm* +F: arch/x86/kernel/kvm.c +F: arch/x86/kernel/kvmclock.c + KERNFS M: Greg Kroah-Hartman M: Tejun Heo @@ -7532,7 +7688,7 @@ F: include/linux/kmemleak.h F: mm/kmemleak.c F: mm/kmemleak-test.c -KMOD MODULE USERMODE HELPER +KMOD KERNEL MODULE LOADER - USERMODE HELPER M: "Luis R. Rodriguez" L: linux-kernel@vger.kernel.org S: Maintained @@ -7573,6 +7729,7 @@ M: John Crispin L: linux-mips@linux-mips.org S: Maintained F: arch/mips/lantiq +F: drivers/soc/lantiq LAPB module L: linux-x25@vger.kernel.org @@ -7632,17 +7789,6 @@ T: git git://linuxtv.org/mkrufky/tuners.git S: Maintained F: drivers/media/dvb-frontends/lgdt3305.* -LGUEST -M: Rusty Russell -L: lguest@lists.ozlabs.org -W: http://lguest.ozlabs.org/ -S: Odd Fixes -F: arch/x86/include/asm/lguest*.h -F: arch/x86/lguest/ -F: drivers/lguest/ -F: include/linux/lguest*.h -F: tools/lguest/ - LIBATA PATA ARASAN COMPACT FLASH CONTROLLER M: Viresh Kumar L: linux-ide@vger.kernel.org @@ -7778,6 +7924,7 @@ F: drivers/pci/hotplug/rpa* F: drivers/rtc/rtc-opal.c F: drivers/scsi/ibmvscsi/ F: drivers/tty/hvc/hvc_opal.c +F: drivers/watchdog/wdrtas.c F: tools/testing/selftests/powerpc N: /pmac N: powermac @@ -8118,6 +8265,12 @@ L: libertas-dev@lists.infradead.org S: Orphan F: drivers/net/wireless/marvell/libertas/ +MARVELL MACCHIATOBIN SUPPORT +M: Russell King +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts + MARVELL MV643XX ETHERNET DRIVER M: Sebastian Hesselbarth L: netdev@vger.kernel.org @@ -8294,6 +8447,14 @@ T: git git://linuxtv.org/media_tree.git S: Supported F: drivers/media/dvb-frontends/cxd2841er* +MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/pci/ddbridge/* + MEDIA DRIVERS FOR FREESCALE IMX M: Steve Longerbeam M: Philipp Zabel @@ -8335,6 +8496,14 @@ T: git git://linuxtv.org/media_tree.git S: Supported F: drivers/media/dvb-frontends/lnbh25* +MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/mxl5xx* + MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices M: Sergey Kozlov M: Abylay Ospan @@ -8391,6 +8560,22 @@ S: Supported F: Documentation/devicetree/bindings/media/renesas,vsp1.txt F: drivers/media/platform/vsp1/ +MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/stv0910* + +MEDIA DRIVERS FOR ST STV6111 TUNER ICs +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/stv6111* + MEDIA INPUT INFRASTRUCTURE (V4L/DVB) M: Mauro Carvalho Chehab M: Mauro Carvalho Chehab @@ -8414,9 +8599,22 @@ F: include/uapi/linux/meye.h F: include/uapi/linux/ivtv* F: include/uapi/linux/uvcvideo.h +MEDIATEK CIR DRIVER +M: Sean Wang +S: Maintained +F: drivers/media/rc/mtk-cir.c + +MEDIATEK PMIC LED DRIVER +M: Sean Wang +S: Maintained +F: drivers/leds/leds-mt6323.c +F: Documentation/devicetree/bindings/leds/leds-mt6323.txt + MEDIATEK ETHERNET DRIVER M: Felix Fietkau -M: John Crispin +M: John Crispin +M: Sean Wang +M: Nelson Chang L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/mediatek/ @@ -8457,6 +8655,14 @@ M: Sean Wang S: Maintained F: drivers/char/hw_random/mtk-rng.c +MEDIATEK USB3 DRD IP DRIVER +M: Chunfeng Yun +L: linux-usb@vger.kernel.org (moderated for non-subscribers) +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: drivers/usb/mtu3/ + MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES M: Peter Senna Tschudin M: Martin Donnelly @@ -8621,7 +8827,7 @@ M: Mathieu Desnoyers M: "Paul E. McKenney" L: linux-kernel@vger.kernel.org S: Supported -F: kernel/membarrier.c +F: kernel/sched/membarrier.c F: include/uapi/linux/membarrier.h MEMORY MANAGEMENT @@ -8675,8 +8881,18 @@ F: drivers/leds/leds-menf21bmc.c F: drivers/hwmon/menf21bmc_hwmon.c F: Documentation/hwmon/menf21bmc +MESON AO CEC DRIVER FOR AMLOGIC SOCS +M: Neil Armstrong +L: linux-media@lists.freedesktop.org +L: linux-amlogic@lists.infradead.org +W: http://linux-meson.com/ +S: Supported +F: drivers/media/platform/meson/ao-cec.c +F: Documentation/devicetree/bindings/media/meson-ao-cec.txt +T: git git://linuxtv.org/media_tree.git + METAG ARCHITECTURE -M: James Hogan +M: James Hogan L: linux-metag@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git S: Odd Fixes @@ -8711,6 +8927,12 @@ F: drivers/dma/at_hdmac.c F: drivers/dma/at_hdmac_regs.h F: include/linux/platform_data/dma-atmel.h +MICROCHIP / ATMEL ECC DRIVER +M: Tudor Ambarus +L: linux-crypto@vger.kernel.org +S: Maintained +F: drivers/crypto/atmel-ecc.* + MICROCHIP / ATMEL ISC DRIVER M: Songjun Wu L: linux-media@vger.kernel.org @@ -8785,6 +9007,7 @@ M: Paul Burton L: linux-mips@linux-mips.org S: Supported F: arch/mips/generic/ +F: arch/mips/tools/generic-board-config.sh MIPS/LOONGSON1 ARCHITECTURE M: Keguang Zhang @@ -8795,6 +9018,13 @@ F: arch/mips/include/asm/mach-loongson32/ F: drivers/*/*loongson1* F: drivers/*/*/*loongson1* +MIPS RINT INSTRUCTION EMULATION +M: Aleksandar Markovic +L: linux-mips@linux-mips.org +S: Supported +F: arch/mips/math-emu/sp_rint.c +F: arch/mips/math-emu/dp_rint.c + MIROSOUND PCM20 FM RADIO RECEIVER DRIVER M: Hans Verkuil L: linux-media@vger.kernel.org @@ -9020,7 +9250,7 @@ T: git git://git.infradead.org/linux-mtd.git nand/fixes T: git git://git.infradead.org/l2-mtd.git nand/next S: Maintained F: drivers/mtd/nand/ -F: include/linux/mtd/nand*.h +F: include/linux/mtd/*nand*.h NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER M: Daniel Mack @@ -9112,15 +9342,6 @@ F: net/*/netfilter/ F: net/netfilter/ F: net/bridge/br_netfilter*.c -NETLABEL -M: Paul Moore -W: http://netlabel.sf.net -L: netdev@vger.kernel.org -S: Maintained -F: Documentation/netlabel/ -F: include/net/netlabel.h -F: net/netlabel/ - NETROM NETWORK LAYER M: Ralf Baechle L: linux-hams@vger.kernel.org @@ -9140,7 +9361,7 @@ NETWORK BLOCK DEVICE (NBD) M: Josef Bacik S: Maintained L: linux-block@vger.kernel.org -L: nbd-general@lists.sourceforge.net +L: nbd@other.debian.org F: Documentation/blockdev/nbd.txt F: drivers/block/nbd.c F: include/uapi/linux/nbd.h @@ -9248,10 +9469,23 @@ F: net/ipv6/ F: include/net/ip* F: arch/x86/net/* -NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) +NETWORKING [LABELED] (NetLabel, Labeled IPsec, SECMARK) M: Paul Moore +W: https://github.com/netlabel L: netdev@vger.kernel.org +L: linux-security-module@vger.kernel.org S: Maintained +F: Documentation/netlabel/ +F: include/net/calipso.h +F: include/net/cipso_ipv4.h +F: include/net/netlabel.h +F: include/uapi/linux/netfilter/xt_SECMARK.h +F: include/uapi/linux/netfilter/xt_CONNSECMARK.h +F: net/netlabel/ +F: net/ipv4/cipso_ipv4.c +F: net/ipv6/calipso.c +F: net/netfilter/xt_CONNSECMARK.c +F: net/netfilter/xt_SECMARK.c NETWORKING [TLS] M: Ilya Lesokhin @@ -9458,6 +9692,7 @@ M: Srinivas Kandagatla S: Maintained F: drivers/nvmem/ F: Documentation/devicetree/bindings/nvmem/ +F: Documentation/ABI/stable/sysfs-bus-nvmem F: include/linux/nvmem-consumer.h F: include/linux/nvmem-provider.h @@ -9667,6 +9902,12 @@ F: drivers/regulator/twl-regulator.c F: drivers/regulator/twl6030-regulator.c F: include/linux/i2c-omap.h +ONION OMEGA2+ BOARD +M: Harvey Hunt +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/boot/dts/ralink/omega2p.dts + OMFS FILESYSTEM M: Bob Copeland L: linux-karma-devel@lists.sourceforge.net @@ -9701,7 +9942,7 @@ S: Maintained F: drivers/media/i2c/ov5640.c OMNIVISION OV5647 SENSOR DRIVER -M: Ramiro Oliveira +M: Luis Oliveira L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained @@ -9938,7 +10179,7 @@ F: include/uapi/linux/ppdev.h F: Documentation/parport*.txt PARAVIRT_OPS INTERFACE -M: Jeremy Fitzhardinge +M: Juergen Gross M: Chris Wright M: Alok Kataria M: Rusty Russell @@ -9946,7 +10187,7 @@ L: virtualization@lists.linux-foundation.org S: Supported F: Documentation/virtual/paravirt_ops.txt F: arch/*/kernel/paravirt* -F: arch/*/include/asm/paravirt.h +F: arch/*/include/asm/paravirt*.h F: include/linux/hypervisor.h PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES @@ -10090,6 +10331,7 @@ F: drivers/pci/dwc/*imx6* PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) M: Keith Busch +M: Jonathan Derrick L: linux-pci@vger.kernel.org S: Supported F: drivers/pci/host/vmd.c @@ -10136,7 +10378,7 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained F: drivers/pci/dwc/pci-exynos.c -PCI DRIVER FOR SYNOPSIS DESIGNWARE +PCI DRIVER FOR SYNOPSYS DESIGNWARE M: Jingoo Han M: Joao Pinto L: linux-pci@vger.kernel.org @@ -10375,7 +10617,7 @@ L: linux-gpio@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git S: Maintained F: Documentation/devicetree/bindings/pinctrl/ -F: Documentation/pinctrl.txt +F: Documentation/driver-api/pinctl.rst F: drivers/pinctrl/ F: include/linux/pinctrl/ @@ -10572,8 +10814,11 @@ W: http://wiki.enneenne.com/index.php/LinuxPPS_support L: linuxpps@ml.enneenne.com (subscribers-only) S: Maintained F: Documentation/pps/ +F: Documentation/devicetree/bindings/pps/pps-gpio.txt +F: Documentation/ABI/testing/sysfs-pps F: drivers/pps/ F: include/linux/pps*.h +F: include/uapi/linux/pps.h PPTP DRIVER M: Dmitry Kozlov @@ -10699,6 +10944,7 @@ L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained F: drivers/media/usb/pulse8-cec/* +F: Documentation/media/cec-drivers/pulse8-cec.rst PVRUSB2 VIDEO4LINUX DRIVER M: Mike Isely @@ -10726,6 +10972,12 @@ F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt F: Documentation/hwmon/pwm-fan F: drivers/hwmon/pwm-fan.c +PWM IR Transmitter +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/pwm-ir-tx.c + PWM SUBSYSTEM M: Thierry Reding L: linux-pwm@vger.kernel.org @@ -10819,7 +11071,6 @@ S: Supported F: drivers/scsi/qedi/ QLOGIC QL4xxx ETHERNET DRIVER -M: Yuval Mintz M: Ariel Elior M: everest-linux-l2@cavium.com L: netdev@vger.kernel.org @@ -10920,6 +11171,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k S: Supported F: drivers/net/wireless/ath/ath9k/ +QUALCOMM CAMERA SUBSYSTEM DRIVER +M: Todor Tomov +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/qcom,camss.txt +F: Documentation/media/v4l-drivers/qcom_camss.rst +F: drivers/media/platform/qcom/camss-8x16/ + QUALCOMM EMAC GIGABIT ETHERNET DRIVER M: Timur Tabi L: netdev@vger.kernel.org @@ -10933,6 +11192,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel.g S: Supported F: arch/hexagon/ +QUALCOMM IOMMU +M: Rob Clark +L: iommu@lists.linux-foundation.org +L: linux-arm-msm@vger.kernel.org +S: Maintained +F: drivers/iommu/qcom_iommu.c + QUALCOMM VENUS VIDEO ACCELERATOR DRIVER M: Stanimir Varbanov L: linux-media@vger.kernel.org @@ -11103,7 +11369,7 @@ M: Fenghua Yu L: linux-kernel@vger.kernel.org S: Supported F: arch/x86/kernel/cpu/intel_rdt* -F: arch/x86/include/asm/intel_rdt* +F: arch/x86/include/asm/intel_rdt_sched.h F: Documentation/x86/intel_rdt* READ-COPY UPDATE (RCU) @@ -11192,6 +11458,8 @@ RENESAS ETHERNET DRIVERS R: Sergei Shtylyov L: netdev@vger.kernel.org L: linux-renesas-soc@vger.kernel.org +F: Documentation/devicetree/bindings/net/renesas,*.txt +F: Documentation/devicetree/bindings/net/sh_eth.txt F: drivers/net/ethernet/renesas/ F: include/linux/sh_eth.h @@ -11273,6 +11541,17 @@ L: linux-serial@vger.kernel.org S: Odd Fixes F: drivers/tty/serial/rp2.* +ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS +M: Marek Vasut +L: linux-kernel@vger.kernel.org +L: linux-renesas-soc@vger.kernel.org +S: Supported +F: drivers/mfd/bd9571mwv.c +F: drivers/regulator/bd9571mwv-regulator.c +F: drivers/gpio/gpio-bd9571mwv.c +F: include/linux/mfd/bd9571mwv.h +F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt + ROSE NETWORK LAYER M: Ralf Baechle L: linux-hams@vger.kernel.org @@ -11434,6 +11713,7 @@ F: drivers/s390/crypto/ S390 ZFCP DRIVER M: Steffen Maier +M: Benjamin Block L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ S: Supported @@ -11798,8 +12078,9 @@ M: Paul Moore M: Stephen Smalley M: Eric Paris L: selinux@tycho.nsa.gov (moderated for non-subscribers) -W: http://selinuxproject.org -T: git git://git.infradead.org/users/pcmoore/selinux +W: https://selinuxproject.org +W: https://github.com/SELinuxProject +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git S: Supported F: include/linux/selinux* F: security/selinux/ @@ -12286,6 +12567,7 @@ F: drivers/tty/serial/sunsab.h F: drivers/tty/serial/sunsu.c F: drivers/tty/serial/sunzilog.c F: drivers/tty/serial/sunzilog.h +F: drivers/tty/vcc.c SPARSE CHECKER M: "Christopher Li" @@ -12482,6 +12764,12 @@ M: Ion Badulescu S: Odd Fixes F: drivers/net/ethernet/adaptec/starfire* +STEC S1220 SKD DRIVER +M: Bart Van Assche +L: linux-block@vger.kernel.org +S: Maintained +F: drivers/block/skd*[ch] + STI CEC DRIVER M: Benjamin Gaignard S: Maintained @@ -12599,6 +12887,18 @@ F: drivers/clocksource/arc_timer.c F: drivers/tty/serial/arc_uart.c T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git +SYNOPSYS ARC HSDK SDP pll clock driver +M: Eugeniy Paltsev +S: Supported +F: drivers/clk/clk-hsdk-pll.c +F: Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt + +SYNOPSYS ARC SDP clock driver +M: Eugeniy Paltsev +S: Supported +F: drivers/clk/axs10x/* +F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt + SYNOPSYS ARC SDP platform support M: Alexey Brodkin S: Supported @@ -12635,6 +12935,13 @@ L: linux-mmc@vger.kernel.org S: Maintained F: drivers/mmc/host/dw_mmc* +SYNOPSYS HSDK RESET CONTROLLER DRIVER +M: Eugeniy Paltsev +S: Supported +F: drivers/reset/reset-hsdk.c +F: include/dt-bindings/reset/snps,hsdk-reset.h +F: Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt + SYSTEM CONFIGURATION (SYSCON) M: Lee Jones M: Arnd Bergmann @@ -12985,6 +13292,11 @@ M: Yehezkel Bernat S: Maintained F: drivers/thunderbolt/ +THUNDERX GPIO DRIVER +M: David Daney +S: Maintained +F: drivers/gpio/gpio-thunderx.c + TI AM437X VPFE DRIVER M: "Lad, Prabhakar" L: linux-media@vger.kernel.org @@ -13509,8 +13821,7 @@ F: Documentation/scsi/ufs.txt F: drivers/scsi/ufs/ UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS -M: Manjunath M Bettegowda -M: Prabu Thangamuthu +M: Joao Pinto L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/ufs/*dwc* @@ -13996,6 +14307,7 @@ F: drivers/block/virtio_blk.c F: include/linux/virtio*.h F: include/uapi/linux/virtio_*.h F: drivers/crypto/virtio/ +F: mm/balloon_compaction.c VIRTIO CRYPTO DRIVER M: Gonglei @@ -14118,6 +14430,12 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/vmxnet3/ +VOCORE VOCORE2 BOARD +M: Harvey Hunt +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/boot/dts/ralink/vocore2.dts + VOLTAGE AND CURRENT REGULATOR FRAMEWORK M: Liam Girdwood M: Mark Brown @@ -14210,6 +14528,12 @@ F: drivers/watchdog/ F: include/linux/watchdog.h F: include/uapi/linux/watchdog.h +WHISKEYCOVE PMIC GPIO DRIVER +M: Kuppuswamy Sathyanarayanan +L: linux-gpio@vger.kernel.org +S: Maintained +F: drivers/gpio/gpio-wcove.c + WIIMOTE HID DRIVER M: David Herrmann L: linux-input@vger.kernel.org diff --git a/Makefile b/Makefile index 37087b4657b7bdb9a13d1dac4ac62e48cf3ac517..2835863bdd5a44d75e4b48820caedcfb5ee31ef2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 -PATCHLEVEL = 13 +PATCHLEVEL = 14 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Fearless Coyote # *DOCUMENTATION* @@ -130,8 +130,8 @@ endif ifneq ($(KBUILD_OUTPUT),) # check that the output directory actually exists saved-output := $(KBUILD_OUTPUT) -KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \ - && /bin/pwd) +$(shell [ -d $(KBUILD_OUTPUT) ] || mkdir -p $(KBUILD_OUTPUT)) +KBUILD_OUTPUT := $(realpath $(KBUILD_OUTPUT)) $(if $(KBUILD_OUTPUT),, \ $(error failed to create output directory "$(saved-output)")) @@ -396,7 +396,7 @@ LINUXINCLUDE := \ KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -fno-common \ + -fno-strict-aliasing -fno-common -fshort-wchar \ -Werror-implicit-function-declaration \ -Wno-format-security \ -std=gnu89 $(call cc-option,-fno-PIE) @@ -442,7 +442,7 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \ # =========================================================================== # Rules shared between *config targets and build targets -# Basic helpers built in scripts/ +# Basic helpers built in scripts/basic/ PHONY += scripts_basic scripts_basic: $(Q)$(MAKE) $(build)=scripts/basic @@ -505,7 +505,7 @@ ifeq ($(KBUILD_EXTMOD),) endif endif endif -# install and module_install need also be processed one by one +# install and modules_install need also be processed one by one ifneq ($(filter install,$(MAKECMDGOALS)),) ifneq ($(filter modules_install,$(MAKECMDGOALS)),) mixed-targets := 1 @@ -964,7 +964,7 @@ export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(net-y) $(virt- export KBUILD_VMLINUX_LIBS := $(libs-y1) export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds export LDFLAGS_vmlinux -# used by scripts/pacmage/Makefile +# used by scripts/package/Makefile export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools) vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS) @@ -978,7 +978,7 @@ ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check endif ifdef CONFIG_GDB_SCRIPTS - $(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.py + $(Q)ln -fsn $(abspath $(srctree)/scripts/gdb/vmlinux-gdb.py) endif ifdef CONFIG_TRIM_UNUSED_KSYMS $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ @@ -992,8 +992,8 @@ include/generated/autoksyms.h: FORCE ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link - cmd_link-vmlinux = \ - $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ; \ +cmd_link-vmlinux = \ + $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) vmlinux: scripts/link-vmlinux.sh vmlinux_prereq $(vmlinux-deps) FORCE @@ -1128,16 +1128,6 @@ headerdep: $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \ $(srctree)/scripts/headerdep.pl -I$(srctree)/include -# --------------------------------------------------------------------------- -# Firmware install -INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware -export INSTALL_FW_PATH - -PHONY += firmware_install -firmware_install: - @mkdir -p $(objtree)/firmware - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install - # --------------------------------------------------------------------------- # Kernel headers @@ -1182,10 +1172,11 @@ headers_check: headers_install PHONY += kselftest kselftest: - $(Q)$(MAKE) -C tools/testing/selftests run_tests + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests +PHONY += kselftest-clean kselftest-clean: - $(Q)$(MAKE) -C tools/testing/selftests clean + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests clean PHONY += kselftest-merge kselftest-merge: @@ -1215,7 +1206,6 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin @@ -1237,7 +1227,7 @@ _modinst_: @rm -rf $(MODLIB)/kernel @rm -f $(MODLIB)/source @mkdir -p $(MODLIB)/kernel - @ln -s `cd $(srctree) && /bin/pwd` $(MODLIB)/source + @ln -s $(abspath $(srctree)) $(MODLIB)/source @if [ ! $(objtree) -ef $(MODLIB)/build ]; then \ rm -f $(MODLIB)/build ; \ ln -s $(CURDIR) $(MODLIB)/build ; \ @@ -1251,7 +1241,6 @@ _modinst_: # boot script depmod is the master version. PHONY += _modinst_post _modinst_post: _modinst_ - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst $(call cmd,depmod) ifeq ($(CONFIG_MODULE_SIG), y) @@ -1374,8 +1363,6 @@ help: @echo '* vmlinux - Build the bare kernel' @echo '* modules - Build all modules' @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)' - @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH' - @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)' @echo ' dir/ - Build all files in dir and below' @echo ' dir/file.[ois] - Build specified target only' @echo ' dir/file.ll - Build the LLVM assembly file' @@ -1467,7 +1454,7 @@ $(help-board-dirs): help-%: # Documentation targets # --------------------------------------------------------------------------- -DOC_TARGETS := xmldocs sgmldocs psdocs latexdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs linkcheckdocs +DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs linkcheckdocs PHONY += $(DOC_TARGETS) $(DOC_TARGETS): scripts_basic FORCE $(Q)$(MAKE) $(build)=Documentation $@ @@ -1629,11 +1616,11 @@ image_name: # Clear a bunch of variables before executing the submake tools/: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ tools/%: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $* + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/arch/Kconfig b/arch/Kconfig index 21d0089117fe957be2e32f97d5ab92b3086abd1c..1aafb4efbb51dfea8c5639f2bd68379c930825d4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -458,6 +458,13 @@ config GCC_PLUGIN_STRUCTLEAK * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL + bool "Force initialize all struct type variables passed by reference" + depends on GCC_PLUGIN_STRUCTLEAK + help + Zero initialize any struct type local variable that may be passed by + reference without having been initialized. + config GCC_PLUGIN_STRUCTLEAK_VERBOSE bool "Report forcefully initialized variables" depends on GCC_PLUGIN_STRUCTLEAK @@ -473,11 +480,13 @@ config GCC_PLUGIN_RANDSTRUCT depends on GCC_PLUGINS select MODVERSIONS if MODULES help - If you say Y here, the layouts of structures explicitly - marked by __randomize_layout will be randomized at - compile-time. This can introduce the requirement of an - additional information exposure vulnerability for exploits - targeting these structure types. + If you say Y here, the layouts of structures that are entirely + function pointers (and have not been manually annotated with + __no_randomize_layout), or structures that have been explicitly + marked with __randomize_layout, will be randomized at compile-time. + This can introduce the requirement of an additional information + exposure vulnerability for exploits targeting these structure + types. Enabling this feature will introduce some performance impact, slightly increase memory usage, and prevent the use of forensic @@ -931,6 +940,18 @@ config STRICT_MODULE_RWX config ARCH_WANT_RELAX_ORDER bool +config ARCH_HAS_REFCOUNT + bool + help + An architecture selects this when it has implemented refcount_t + using open coded assembly primitives that provide an optimized + refcount_t implementation, possibly at the expense of some full + refcount state checks of CONFIG_REFCOUNT_FULL=y. + + The refcount overflow check behavior, however, must be retained. + Catching overflows is the primary security concern for protecting + against bugs in reference counts. + config REFCOUNT_FULL bool "Perform full reference count validation at the expense of speed" help diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 539e8b5a6cbd7e027530da490fb1e870a7238d7b..f4ec420d7f2dfb252397faa010281caf51f89549 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -19,7 +19,6 @@ CONFIG_INET_AH=m CONFIG_INET_ESP=m # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_FILTER=m CONFIG_VLAN_8021Q=m @@ -57,7 +56,6 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_RTC=y CONFIG_EXT2_FS=y CONFIG_REISERFS_FS=m -CONFIG_AUTOFS_FS=m CONFIG_ISO9660_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index d103db5af5ffdd19fbbc897e6050171b884e6d32..5b974ab8425c8606d1c46420350b55bf67cfccf1 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -3,6 +3,7 @@ generic-y += clkdev.h generic-y += exec.h generic-y += export.h +generic-y += fb.h generic-y += irq_work.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/alpha/include/asm/asm-prototypes.h b/arch/alpha/include/asm/asm-prototypes.h new file mode 100644 index 0000000000000000000000000000000000000000..d12c68ea340bbde97d31b9771ad21e1356f87adf --- /dev/null +++ b/arch/alpha/include/asm/asm-prototypes.h @@ -0,0 +1,18 @@ +#include + +#include +#include +#include +#include +#include + +#include + +extern void __divl(void); +extern void __reml(void); +extern void __divq(void); +extern void __remq(void); +extern void __divlu(void); +extern void __remlu(void); +extern void __divqu(void); +extern void __remqu(void); diff --git a/arch/alpha/include/asm/core_marvel.h b/arch/alpha/include/asm/core_marvel.h index dad300fa14ce3778d3e89419d34fbb8498bdbd64..8dcf9dbda618e6587b7d6870a7633642a49e7a5a 100644 --- a/arch/alpha/include/asm/core_marvel.h +++ b/arch/alpha/include/asm/core_marvel.h @@ -312,7 +312,7 @@ struct io7 { io7_port7_csrs *csrs; struct io7_port ports[IO7_NUM_PORTS]; - spinlock_t irq_lock; + raw_spinlock_t irq_lock; }; #ifndef __EXTERN_INLINE diff --git a/arch/alpha/include/asm/fb.h b/arch/alpha/include/asm/fb.h deleted file mode 100644 index fa9bbb96b2b3d49f6a16ae41dddf95c5add8cb66..0000000000000000000000000000000000000000 --- a/arch/alpha/include/asm/fb.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ -#include - -/* Caching is off in the I/O space quadrant by design. */ -#define fb_pgprotect(...) do {} while (0) - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h index fb01dfb760c283e5c545121e93d07e52c0d8cd5b..05a70edd57b66fe634021b0e9451f858fcf06ca0 100644 --- a/arch/alpha/include/asm/futex.h +++ b/arch/alpha/include/asm/futex.h @@ -25,18 +25,10 @@ : "r" (uaddr), "r"(oparg) \ : "memory") -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -62,17 +54,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h index ff4049155c840c2fc4bc9e8015b5282dadb57469..4d61d2a50c525aab2531e3bf670227cbd5e66bca 100644 --- a/arch/alpha/include/asm/io.h +++ b/arch/alpha/include/asm/io.h @@ -299,6 +299,7 @@ static inline void __iomem * ioremap_nocache(unsigned long offset, return ioremap(offset, size); } +#define ioremap_wc ioremap_nocache #define ioremap_uc ioremap_nocache static inline void iounmap(volatile void __iomem *addr) diff --git a/arch/alpha/include/asm/mmu_context.h b/arch/alpha/include/asm/mmu_context.h index 384bd47b5187179f4e40ee63399117c14f40eb0d..45c020a0fe76114688c4a77f1a1f574049821341 100644 --- a/arch/alpha/include/asm/mmu_context.h +++ b/arch/alpha/include/asm/mmu_context.h @@ -8,6 +8,7 @@ */ #include +#include #include #include diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h index a40b9fc0c6c3cafbffbf61fdde57c47afb68250d..718ac0b64adf78ce770e1e1e56f82694550e24c9 100644 --- a/arch/alpha/include/asm/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h @@ -16,11 +16,6 @@ #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define arch_spin_is_locked(x) ((x)->lock != 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - static inline int arch_spin_value_unlocked(arch_spinlock_t lock) { return lock.lock == 0; diff --git a/arch/alpha/include/asm/string.h b/arch/alpha/include/asm/string.h index c2911f5917041abd49dea5f14855ac9691d1aec0..9eb9933d845fb8dc82f321e1a049641a4cd4c125 100644 --- a/arch/alpha/include/asm/string.h +++ b/arch/alpha/include/asm/string.h @@ -65,13 +65,14 @@ extern void * memchr(const void *, int, size_t); aligned values. The DEST and COUNT parameters must be even for correct operation. */ -#define __HAVE_ARCH_MEMSETW -extern void * __memsetw(void *dest, unsigned short, size_t count); - -#define memsetw(s, c, n) \ -(__builtin_constant_p(c) \ - ? __constant_c_memset((s),0x0001000100010001UL*(unsigned short)(c),(n)) \ - : __memsetw((s),(c),(n))) +#define __HAVE_ARCH_MEMSET16 +extern void * __memset16(void *dest, unsigned short, size_t count); +static inline void *memset16(uint16_t *p, uint16_t v, size_t n) +{ + if (__builtin_constant_p(v)) + return __constant_c_memset(p, 0x0001000100010001UL * v, n * 2); + return __memset16(p, v, n * 2); +} #endif /* __KERNEL__ */ diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h index 4cb4b6d3452c0b3439c3aa3c0f928f74de09fb3a..0bc66e1d3a7e9c81f1cca84943f60cd91d85a625 100644 --- a/arch/alpha/include/asm/types.h +++ b/arch/alpha/include/asm/types.h @@ -1,6 +1,6 @@ #ifndef _ALPHA_TYPES_H #define _ALPHA_TYPES_H -#include +#include #endif /* _ALPHA_TYPES_H */ diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index b37153ecf2ac33e19b7df4b061afddf4238f7ebb..db7fc0f511e2ae9cc905a6bae64f9195562c013f 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -3,7 +3,7 @@ #include -#define NR_SYSCALLS 514 +#define NR_SYSCALLS 523 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/arch/alpha/include/asm/vga.h b/arch/alpha/include/asm/vga.h index c00106bac52146745a5b128e7e05b1e1480e8400..3c1c2b6128e77f41a714649bb4dbee92205f0c38 100644 --- a/arch/alpha/include/asm/vga.h +++ b/arch/alpha/include/asm/vga.h @@ -34,7 +34,7 @@ static inline void scr_memsetw(u16 *s, u16 c, unsigned int count) if (__is_ioaddr(s)) memsetw_io((u16 __iomem *) s, c, count); else - memsetw(s, c, count); + memset16(s, c, count / 2); } /* Do not trust that the usage will be correct; analyze the arguments. */ diff --git a/arch/alpha/include/uapi/asm/mman.h b/arch/alpha/include/uapi/asm/mman.h index 02760f6e6ca443547eb2bfbf248fe41fefc49be7..3b26cc62dadb08d64b2d91780a92fd5458da76b6 100644 --- a/arch/alpha/include/uapi/asm/mman.h +++ b/arch/alpha/include/uapi/asm/mman.h @@ -64,20 +64,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/arch/alpha/include/uapi/asm/siginfo.h b/arch/alpha/include/uapi/asm/siginfo.h index 9822362a842461a178dcb51fbaf7f922165442f8..70494d1d8f297e17f59f319570067c08a15b9271 100644 --- a/arch/alpha/include/uapi/asm/siginfo.h +++ b/arch/alpha/include/uapi/asm/siginfo.h @@ -6,4 +6,18 @@ #include +/* + * SIGFPE si_codes + */ +#ifdef __KERNEL__ +#define FPE_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ + +/* + * SIGTRAP si_codes + */ +#ifdef __KERNEL__ +#define TRAP_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ + #endif diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 7b285dd4fe05b3647b87879eea0785c6ebbe1947..c6133a045352828f24c970f3d37fd9831df86d67 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -109,4 +109,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/alpha/include/uapi/asm/types.h b/arch/alpha/include/uapi/asm/types.h index 9fd3cd459777767e7c80c4c761ee88278f62b17d..8d1024d7be0546bc744adf163e87f9dc723539fe 100644 --- a/arch/alpha/include/uapi/asm/types.h +++ b/arch/alpha/include/uapi/asm/types.h @@ -9,8 +9,18 @@ * need to be careful to avoid a name clashes. */ -#ifndef __KERNEL__ +/* + * This is here because we used to use l64 for alpha + * and we don't want to impact user mode with our change to ll64 + * in the kernel. + * + * However, some user programs are fine with this. They can + * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here. + */ +#if !defined(__SANE_USERSPACE_TYPES__) && !defined(__KERNEL__) #include +#else +#include #endif #endif /* _UAPI_ALPHA_TYPES_H */ diff --git a/arch/alpha/include/uapi/asm/unistd.h b/arch/alpha/include/uapi/asm/unistd.h index aa33bf5aacb6c1666203e38700939750c90cb5c5..53de540e39a79c9197d11de2ba7bb7e6935558a8 100644 --- a/arch/alpha/include/uapi/asm/unistd.h +++ b/arch/alpha/include/uapi/asm/unistd.h @@ -366,11 +366,6 @@ #define __NR_epoll_create 407 #define __NR_epoll_ctl 408 #define __NR_epoll_wait 409 -/* Feb 2007: These three sys_epoll defines shouldn't be here but culling - * them would break userspace apps ... we'll kill them off in 2010 :) */ -#define __NR_sys_epoll_create __NR_epoll_create -#define __NR_sys_epoll_ctl __NR_epoll_ctl -#define __NR_sys_epoll_wait __NR_epoll_wait #define __NR_remap_file_pages 410 #define __NR_set_tid_address 411 #define __NR_restart_syscall 412 @@ -475,5 +470,19 @@ #define __NR_getrandom 511 #define __NR_memfd_create 512 #define __NR_execveat 513 +#define __NR_seccomp 514 +#define __NR_bpf 515 +#define __NR_userfaultfd 516 +#define __NR_membarrier 517 +#define __NR_mlock2 518 +#define __NR_copy_file_range 519 +#define __NR_preadv2 520 +#define __NR_pwritev2 521 +#define __NR_statx 522 + +/* Alpha doesn't have protection keys. */ +#define __IGNORE_pkey_mprotect +#define __IGNORE_pkey_alloc +#define __IGNORE_pkey_free #endif /* _UAPI_ALPHA_UNISTD_H */ diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index d5f0580746a5d632452816b00427c212230b0810..b10c316475dde2082abd33e8933fe5c0b566a392 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -118,7 +118,7 @@ alloc_io7(unsigned int pe) io7 = alloc_bootmem(sizeof(*io7)); io7->pe = pe; - spin_lock_init(&io7->irq_lock); + raw_spin_lock_init(&io7->irq_lock); for (h = 0; h < 4; h++) { io7->ports[h].io7 = io7; @@ -351,7 +351,7 @@ marvel_init_io7(struct io7 *io7) } } -void +void __init marvel_io7_present(gct6_node *node) { int pe; @@ -369,6 +369,7 @@ marvel_io7_present(gct6_node *node) static void __init marvel_find_console_vga_hose(void) { +#ifdef CONFIG_VGA_HOSE u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); if (pu64[7] == 3) { /* TERM_TYPE == graphics */ @@ -402,9 +403,10 @@ marvel_find_console_vga_hose(void) pci_vga_hose = hose; } } +#endif } -gct6_search_struct gct_wanted_node_list[] = { +gct6_search_struct gct_wanted_node_list[] __initdata = { { GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present }, { 0, 0, NULL } }; diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index 219bf271c0ba2e5f2d668af707df57fbbd00ccfd..b532d925443d50b02f3a54481de122c36d948f79 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c @@ -461,6 +461,7 @@ titan_ioremap(unsigned long addr, unsigned long size) unsigned long *ptes; unsigned long pfn; +#ifdef CONFIG_VGA_HOSE /* * Adjust the address and hose, if necessary. */ @@ -468,6 +469,7 @@ titan_ioremap(unsigned long addr, unsigned long size) h = pci_vga_hose->index; addr += pci_vga_hose->mem_space->start; } +#endif /* * Find the hose. diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index 936bc8f89a679f2f8aeb2f7e3cb41f11190a2d77..47632fa8c24e02418cdbac8d5c139f101aa51945 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -181,6 +181,9 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab, switch (r_type) { case R_ALPHA_NONE: break; + case R_ALPHA_REFLONG: + *(u32 *)location = value; + break; case R_ALPHA_REFQUAD: /* BUG() can produce misaligned relocations. */ ((u32 *)location)[0] = value; diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index ffbdb3fb672f6b6d6e4f23a5d47fc519fb07203e..676bab6e31235db014dc1d09d741b18bd8bb8dc4 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -42,11 +42,7 @@ alloc_pci_controller(void) struct resource * __init alloc_resource(void) { - struct resource *res; - - res = alloc_bootmem(sizeof(*res)); - - return res; + return alloc_bootmem(sizeof(struct resource)); } asmlinkage long diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 92c0d460815b1b3f263634333aae2bf4ab4af1ba..cbecd527c696c7a0b508c8e67e54399d8a54c38d 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -38,7 +38,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, unsigned long nr, start, size; int shift = sparse ? 5 : 0; - nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + nr = vma_pages(vma); start = vma->vm_pgoff; size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1; @@ -64,8 +64,7 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { - struct pci_dev *pdev = to_pci_dev(container_of(kobj, - struct device, kobj)); + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); struct resource *res = attr->private; enum pci_mmap_state mmap_type; struct pci_bus_region bar; @@ -255,7 +254,7 @@ static int __legacy_mmap_fits(struct pci_controller *hose, { unsigned long nr, start, size; - nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + nr = vma_pages(vma); start = vma->vm_pgoff; size = ((res_size - 1) >> PAGE_SHIFT) + 1; diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 5f387ee5b5c5e0a69fb4817e9437cef5cf0c7cdd..564114eb85e143f384d1b814cc29df48150ed933 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -312,8 +312,9 @@ common_init_pci(void) { struct pci_controller *hose; struct list_head resources; + struct pci_host_bridge *bridge; struct pci_bus *bus; - int next_busno; + int ret, next_busno; int need_domain_info = 0; u32 pci_mem_end; u32 sg_base; @@ -336,11 +337,25 @@ common_init_pci(void) pci_add_resource_offset(&resources, hose->mem_space, hose->mem_space->start); - bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, - hose, &resources); - if (!bus) + bridge = pci_alloc_host_bridge(0); + if (!bridge) continue; - hose->bus = bus; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = alpha_mv.pci_ops; + bridge->swizzle_irq = alpha_mv.pci_swizzle; + bridge->map_irq = alpha_mv.pci_map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + continue; + } + + bus = hose->bus = bridge->bus; hose->need_domain_info = need_domain_info; next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - @@ -354,7 +369,6 @@ common_init_pci(void) pcibios_claim_console_setup(); pci_assign_unassigned_resources(); - pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); for (hose = hose_head; hose; hose = hose->next) { bus = hose->bus; if (bus) @@ -362,7 +376,6 @@ common_init_pci(void) } } - struct pci_controller * __init alloc_pci_controller(void) { @@ -379,11 +392,7 @@ alloc_pci_controller(void) struct resource * __init alloc_resource(void) { - struct resource *res; - - res = alloc_bootmem(sizeof(*res)); - - return res; + return alloc_bootmem(sizeof(struct resource)); } diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 491e6a604e82ac468ffc1e2212080fd381f894c8..249229ab49424fcefb9d38830280b81151a7a9db 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -1094,8 +1094,9 @@ get_sysnames(unsigned long type, unsigned long variation, unsigned long cpu, default: /* default to variation "0" for now */ break; case ST_DEC_EB164: - if (member < ARRAY_SIZE(eb164_indices)) - *variation_name = eb164_names[eb164_indices[member]]; + if (member >= ARRAY_SIZE(eb164_indices)) + break; + *variation_name = eb164_names[eb164_indices[member]]; /* PC164 may show as EB164 variation, but with EV56 CPU, so, since no true EB164 had anything but EV5... */ if (eb164_indices[member] == 0 && cpu == EV56_CPU) diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c index c803fc76ae4f40a04665e5624ee8eaf823334d7b..4dbd4e41504159322ff13dbc335a7e1daea6efec 100644 --- a/arch/alpha/kernel/smc37c669.c +++ b/arch/alpha/kernel/smc37c669.c @@ -2007,11 +2007,8 @@ static void __init SMC37c669_config_mode( static unsigned char __init SMC37c669_read_config( unsigned char index ) { - unsigned char data; - - wb( &SMC37c669->index_port, index ); - data = rb( &SMC37c669->data_port ); - return data; + wb(&SMC37c669->index_port, index); + return rb(&SMC37c669->data_port); } /* diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 9fc560459ebd64ad3735f9b4dcd5ce6596b7bfee..f6726a74642703381c2151e9d927e267fcba0975 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -115,7 +115,7 @@ wait_boot_cpu_to_stop(int cpuid) /* * Where secondaries begin a life of C. */ -void +void __init smp_callin(void) { int cpuid = hard_smp_processor_id(); diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 24e41bd7d3c99060a7411c1c5774941249c89d72..3e533920371fe1e90ffa663295f46e1c1b825273 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -115,11 +115,11 @@ io7_enable_irq(struct irq_data *d) return; } - spin_lock(&io7->irq_lock); + raw_spin_lock(&io7->irq_lock); *ctl |= 1UL << 24; mb(); *ctl; - spin_unlock(&io7->irq_lock); + raw_spin_unlock(&io7->irq_lock); } static void @@ -136,11 +136,11 @@ io7_disable_irq(struct irq_data *d) return; } - spin_lock(&io7->irq_lock); + raw_spin_lock(&io7->irq_lock); *ctl &= ~(1UL << 24); mb(); *ctl; - spin_unlock(&io7->irq_lock); + raw_spin_unlock(&io7->irq_lock); } static void @@ -263,7 +263,7 @@ init_io7_irqs(struct io7 *io7, */ printk(" Interrupts reported to CPU at PE %u\n", boot_cpuid); - spin_lock(&io7->irq_lock); + raw_spin_lock(&io7->irq_lock); /* set up the error irqs */ io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, boot_cpuid); @@ -295,7 +295,7 @@ init_io7_irqs(struct io7 *io7, for (i = 0; i < 16; ++i) init_one_io7_msi(io7, i, boot_cpuid); - spin_unlock(&io7->irq_lock); + raw_spin_unlock(&io7->irq_lock); } static void __init diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 2cfaa0e5c5777b2f0c49c5e0688d38cad512d840..8ae04a121186e2b090256956b3e7e425a571e1c4 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -194,22 +194,46 @@ static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, }; +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; void __init nautilus_init_pci(void) { struct pci_controller *hose = hose_head; + struct pci_host_bridge *bridge; struct pci_bus *bus; struct pci_dev *irongate; unsigned long bus_align, bus_size, pci_mem; unsigned long memtop = max_low_pfn << PAGE_SHIFT; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; + + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = 0; + bridge->ops = alpha_mv.pci_ops; + bridge->swizzle_irq = alpha_mv.pci_swizzle; + bridge->map_irq = alpha_mv.pci_map_irq; /* Scan our single hose. */ - bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); - if (!bus) + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); return; + } - hose->bus = bus; + bus = hose->bus = bridge->bus; pcibios_claim_one_bus(bus); irongate = pci_get_bus_and_slot(0, 0); @@ -254,7 +278,6 @@ nautilus_init_pci(void) /* pci_common_swizzle() relies on bus->self being NULL for the root bus, so just clear it. */ bus->self = NULL; - pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); pci_bus_add_devices(bus); } diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 9b62e3fd4f038a925657beb15de3de89f8548473..5b4514abb23450998515530ebc824ae1857f27b9 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -532,6 +532,15 @@ sys_call_table: .quad sys_getrandom .quad sys_memfd_create .quad sys_execveat + .quad sys_seccomp + .quad sys_bpf /* 515 */ + .quad sys_userfaultfd + .quad sys_membarrier + .quad sys_mlock2 + .quad sys_copy_file_range + .quad sys_preadv2 /* 520 */ + .quad sys_pwritev2 + .quad sys_statx .size sys_call_table, . - sys_call_table .type sys_call_table, @object diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 65bb102d985bb05141b0f294bbd7e2bbfb0ac6ae..49d3b1e63ce5e2cd0423dff25728ed54c2592de1 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -193,8 +193,10 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15) static long dummy_emul(void) { return 0; } long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask) = (void *)dummy_emul; +EXPORT_SYMBOL_GPL(alpha_fp_emul_imprecise); long (*alpha_fp_emul) (unsigned long pc) = (void *)dummy_emul; +EXPORT_SYMBOL_GPL(alpha_fp_emul); #else long alpha_fp_emul_imprecise(struct pt_regs *regs, unsigned long writemask); long alpha_fp_emul (unsigned long pc); @@ -278,7 +280,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) case 1: /* bugcheck */ info.si_signo = SIGTRAP; info.si_errno = 0; - info.si_code = __SI_FAULT; + info.si_code = TRAP_FIXME; info.si_addr = (void __user *) regs->pc; info.si_trapno = 0; send_sig_info(SIGTRAP, &info, current); @@ -318,7 +320,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) break; case GEN_ROPRAND: signo = SIGFPE; - code = __SI_FAULT; + code = FPE_FIXME; break; case GEN_DECOVF: @@ -340,7 +342,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) case GEN_SUBRNG7: default: signo = SIGTRAP; - code = __SI_FAULT; + code = TRAP_FIXME; break; } diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index 7083434dd2419b7b3ef6ef8e74c204522d4a3257..a8081596036457af2149b37d356c64f2f1e7acc6 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile @@ -20,12 +20,8 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \ checksum.o \ csum_partial_copy.o \ $(ev67-y)strlen.o \ - $(ev67-y)strcat.o \ - strcpy.o \ - $(ev67-y)strncat.o \ - strncpy.o \ - $(ev6-y)stxcpy.o \ - $(ev6-y)stxncpy.o \ + stycpy.o \ + styncpy.o \ $(ev67-y)strchr.o \ $(ev67-y)strrchr.o \ $(ev6-y)memchr.o \ @@ -49,3 +45,17 @@ AFLAGS___remlu.o = -DREM -DINTSIZE $(addprefix $(obj)/,__divqu.o __remqu.o __divlu.o __remlu.o): \ $(src)/$(ev6-y)divide.S FORCE $(call if_changed_rule,as_o_S) + +# There are direct branches between {str*cpy,str*cat} and stx*cpy. +# Ensure the branches are within range by merging these objects. + +LDFLAGS_stycpy.o := -r +LDFLAGS_styncpy.o := -r + +$(obj)/stycpy.o: $(obj)/strcpy.o $(obj)/$(ev67-y)strcat.o \ + $(obj)/$(ev6-y)stxcpy.o FORCE + $(call if_changed,ld) + +$(obj)/styncpy.o: $(obj)/strncpy.o $(obj)/$(ev67-y)strncat.o \ + $(obj)/$(ev6-y)stxncpy.o FORCE + $(call if_changed,ld) diff --git a/arch/alpha/lib/copy_user.S b/arch/alpha/lib/copy_user.S index 159f1b7e6e495f098a28dc818c7c383ede2dda76..c277a1a4383e5fbb4bbb76b8c2c7802b8bbd6a26 100644 --- a/arch/alpha/lib/copy_user.S +++ b/arch/alpha/lib/copy_user.S @@ -34,7 +34,7 @@ .ent __copy_user __copy_user: .prologue 0 - and $18,$18,$0 + mov $18,$0 and $16,7,$3 beq $0,$35 beq $3,$36 diff --git a/arch/alpha/lib/ev6-copy_user.S b/arch/alpha/lib/ev6-copy_user.S index 35e6710d070054b1c9987d0f5c10f1c29510b1a2..954ca03ebebef371a4e1dd873efce4493de53309 100644 --- a/arch/alpha/lib/ev6-copy_user.S +++ b/arch/alpha/lib/ev6-copy_user.S @@ -45,9 +45,10 @@ # Pipeline info: Slotting & Comments __copy_user: .prologue 0 - andq $18, $18, $0 - subq $18, 32, $1 # .. E .. .. : Is this going to be a small copy? - beq $0, $zerolength # U .. .. .. : U L U L + mov $18, $0 # .. .. .. E + subq $18, 32, $1 # .. .. E. .. : Is this going to be a small copy? + nop # .. E .. .. + beq $18, $zerolength # U .. .. .. : U L U L and $16,7,$3 # .. .. .. E : is leading dest misalignment ble $1, $onebyteloop # .. .. U .. : 1st branch : small amount of data diff --git a/arch/alpha/lib/memset.S b/arch/alpha/lib/memset.S index 89a26f5e89de3db904cbfabb1ff735464d6ca3cb..f824969e9e77a61eb2750cf82c41c8da3d0e2557 100644 --- a/arch/alpha/lib/memset.S +++ b/arch/alpha/lib/memset.S @@ -20,7 +20,7 @@ .globl memset .globl __memset .globl ___memset - .globl __memsetw + .globl __memset16 .globl __constant_c_memset .ent ___memset @@ -110,8 +110,8 @@ EXPORT_SYMBOL(___memset) EXPORT_SYMBOL(__constant_c_memset) .align 5 - .ent __memsetw -__memsetw: + .ent __memset16 +__memset16: .prologue 0 inswl $17,0,$1 /* E0 */ @@ -123,8 +123,8 @@ __memsetw: or $1,$4,$17 /* E0 */ br __constant_c_memset /* .. E1 */ - .end __memsetw -EXPORT_SYMBOL(__memsetw) + .end __memset16 +EXPORT_SYMBOL(__memset16) memset = ___memset __memset = ___memset diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c index d17d705f65453c6306067fabdc4e751358faa37e..1c2d456da7f2258de6eafa4f69ecc7fbfcf3f98e 100644 --- a/arch/alpha/math-emu/math.c +++ b/arch/alpha/math-emu/math.c @@ -53,6 +53,7 @@ extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val); #ifdef MODULE MODULE_DESCRIPTION("FP Software completion module"); +MODULE_LICENSE("GPL v2"); extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long); extern long (*alpha_fp_emul) (unsigned long pc); diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index a5459698f0ee3762917c82c8cbf133e34643f021..c84e67fdea095cbed225edac052f4ce07007abb9 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -24,7 +24,7 @@ config ARC select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK - select HAVE_FUTEX_CMPXCHG + select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_IOREMAP_PROT select HAVE_KPROBES select HAVE_KRETPROBES @@ -96,11 +96,11 @@ menu "ARC Architecture Configuration" menu "ARC Platform/SoC/Board" -source "arch/arc/plat-sim/Kconfig" source "arch/arc/plat-tb10x/Kconfig" source "arch/arc/plat-axs10x/Kconfig" #New platform adds here source "arch/arc/plat-eznps/Kconfig" +source "arch/arc/plat-hsdk/Kconfig" endmenu @@ -419,7 +419,7 @@ endif # ISA_ARCV2 endmenu # "ARC CPU Configuration" config LINUX_LINK_BASE - hex "Linux Link Address" + hex "Kernel link address" default "0x80000000" help ARC700 divides the 32 bit phy address space into two equal halves @@ -432,6 +432,14 @@ config LINUX_LINK_BASE If you don't know what the above means, leave this setting alone. This needs to match memory start address specified in Device Tree +config LINUX_RAM_BASE + hex "RAM base address" + default LINUX_LINK_BASE + help + By default Linux is linked at base of RAM. However in some special + cases (such as HSDK), Linux can't be linked at start of DDR, hence + this option. + config HIGHMEM bool "High Memory Support" select ARCH_DISCONTIGMEM_ENABLE diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 44ef35d339564623b2beb4a380a81da6a7790087..d37f49d6a27f40f65d3e34bd3e2df5343a97d1e4 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -6,8 +6,6 @@ # published by the Free Software Foundation. # -UTS_MACHINE := arc - ifeq ($(CROSS_COMPILE),) ifndef CONFIG_CPU_BIG_ENDIAN CROSS_COMPILE := arc-linux- @@ -107,10 +105,11 @@ core-y += arch/arc/ # w/o this dtb won't embed into kernel binary core-y += arch/arc/boot/dts/ -core-$(CONFIG_ARC_PLAT_SIM) += arch/arc/plat-sim/ +core-y += arch/arc/plat-sim/ core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ core-$(CONFIG_ARC_PLAT_EZNPS) += arch/arc/plat-eznps/ +core-$(CONFIG_ARC_SOC_HSDK) += arch/arc/plat-hsdk/ ifdef CONFIG_ARC_PLAT_EZNPS KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include diff --git a/arch/arc/boot/dts/axc001.dtsi b/arch/arc/boot/dts/axc001.dtsi index 53ce226f77a59857615f8fc53fca3ba1c4f09749..fdc266504ada273e6efaf72c18cc8c2e2f48edf2 100644 --- a/arch/arc/boot/dts/axc001.dtsi +++ b/arch/arc/boot/dts/axc001.dtsi @@ -15,15 +15,15 @@ / { compatible = "snps,arc"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; cpu_card { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x00000000 0xf0000000 0x10000000>; + ranges = <0x00000000 0x0 0xf0000000 0x10000000>; core_clk: core_clk { #clock-cells = <0>; @@ -91,23 +91,21 @@ mb_intc: dw-apb-ictl@0xe0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; - reg = < 0xe0012000 0x200 >; + reg = < 0x0 0xe0012000 0x0 0x200 >; interrupt-controller; interrupt-parent = <&core_intc>; interrupts = < 7 >; }; memory { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x00000000 0x80000000 0x20000000>; device_type = "memory"; - reg = <0x80000000 0x1b000000>; /* (512 - 32) MiB */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ + reg = <0x0 0x80000000 0x0 0x1b000000>; /* (512 - 32) MiB */ }; reserved-memory { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; /* * We just move frame buffer area to the very end of @@ -118,7 +116,7 @@ */ frame_buffer: frame_buffer@9e000000 { compatible = "shared-dma-pool"; - reg = <0x9e000000 0x2000000>; + reg = <0x0 0x9e000000 0x0 0x2000000>; no-map; }; }; diff --git a/arch/arc/boot/dts/axc003.dtsi b/arch/arc/boot/dts/axc003.dtsi index 14df46f141bf3450b8df0660bc0f248beef4669b..4e6e9f57e790ac0cefcade55664124c9351e830e 100644 --- a/arch/arc/boot/dts/axc003.dtsi +++ b/arch/arc/boot/dts/axc003.dtsi @@ -14,20 +14,27 @@ / { compatible = "snps,arc"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; cpu_card { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x00000000 0xf0000000 0x10000000>; + ranges = <0x00000000 0x0 0xf0000000 0x10000000>; - core_clk: core_clk { + input_clk: input-clk { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <90000000>; + clock-frequency = <33333333>; + }; + + core_clk: core-clk@80 { + compatible = "snps,axs10x-arc-pll-clock"; + reg = <0x80 0x10>, <0x100 0x10>; + #clock-cells = <0>; + clocks = <&input_clk>; }; core_intc: archs-intc@cpu { @@ -94,30 +101,29 @@ mb_intc: dw-apb-ictl@0xe0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; - reg = < 0xe0012000 0x200 >; + reg = < 0x0 0xe0012000 0x0 0x200 >; interrupt-controller; interrupt-parent = <&core_intc>; interrupts = < 24 >; }; memory { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x00000000 0x80000000 0x40000000>; device_type = "memory"; - reg = <0x80000000 0x20000000>; /* 512MiB */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ + reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MiB low mem */ + 0x1 0xc0000000 0x0 0x40000000>; /* 1 GiB highmem */ }; reserved-memory { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; /* * Move frame buffer out of IOC aperture (0x8z-0xAz). */ frame_buffer: frame_buffer@be000000 { compatible = "shared-dma-pool"; - reg = <0xbe000000 0x2000000>; + reg = <0x0 0xbe000000 0x0 0x2000000>; no-map; }; }; diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi index 695f9fa1996bcbb2689e1bf98dc8fa661cc1c216..63954a8b0100ebf5746394fedb62b4825048d903 100644 --- a/arch/arc/boot/dts/axc003_idu.dtsi +++ b/arch/arc/boot/dts/axc003_idu.dtsi @@ -14,20 +14,27 @@ / { compatible = "snps,arc"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; cpu_card { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x00000000 0xf0000000 0x10000000>; + ranges = <0x00000000 0x0 0xf0000000 0x10000000>; - core_clk: core_clk { + input_clk: input-clk { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <100000000>; + clock-frequency = <33333333>; + }; + + core_clk: core-clk@80 { + compatible = "snps,axs10x-arc-pll-clock"; + reg = <0x80 0x10>, <0x100 0x10>; + #clock-cells = <0>; + clocks = <&input_clk>; }; core_intc: archs-intc@cpu { @@ -100,30 +107,29 @@ mb_intc: dw-apb-ictl@0xe0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; - reg = < 0xe0012000 0x200 >; + reg = < 0x0 0xe0012000 0x0 0x200 >; interrupt-controller; interrupt-parent = <&idu_intc>; interrupts = <0>; }; memory { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x00000000 0x80000000 0x40000000>; device_type = "memory"; - reg = <0x80000000 0x20000000>; /* 512MiB */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ + reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MiB low mem */ + 0x1 0xc0000000 0x0 0x40000000>; /* 1 GiB highmem */ }; reserved-memory { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; /* * Move frame buffer out of IOC aperture (0x8z-0xAz). */ frame_buffer: frame_buffer@be000000 { compatible = "shared-dma-pool"; - reg = <0xbe000000 0x2000000>; + reg = <0x0 0xbe000000 0x0 0x2000000>; no-map; }; }; diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index 41cfb29b62c142ca48193359e8fedf20151cc9bf..e114000a84f56c9e07ddd3a2e623c4dfeb3df6a2 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -13,7 +13,7 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x00000000 0xe0000000 0x10000000>; + ranges = <0x00000000 0x0 0xe0000000 0x10000000>; interrupt-parent = <&mb_intc>; i2sclk: i2sclk@100a0 { @@ -44,7 +44,14 @@ mmcclk: mmcclk { compatible = "fixed-clock"; - clock-frequency = <50000000>; + /* + * DW sdio controller has external ciu clock divider + * controlled via register in SDIO IP. It divides + * sdio_ref_clk (which comes from CGU) by 16 for + * default. So default mmcclk clock (which comes + * to sdk_in) is 25000000 Hz. + */ + clock-frequency = <25000000>; #clock-cells = <0>; }; @@ -101,7 +108,6 @@ mmc@0x15000 { compatible = "altr,socfpga-dw-mshc"; reg = < 0x15000 0x400 >; - num-slots = < 1 >; fifo-depth = < 16 >; card-detect-delay = < 200 >; clocks = <&apbclk>, <&mmcclk>; diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts new file mode 100644 index 0000000000000000000000000000000000000000..8adde1b492f14e833279ff75f448b7c0bb350781 --- /dev/null +++ b/arch/arc/boot/dts/hsdk.dts @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * Device Tree for ARC HS Development Kit + */ +/dts-v1/; + +#include +#include + +/ { + model = "snps,hsdk"; + compatible = "snps,hsdk"; + + #address-cells = <1>; + #size-cells = <1>; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xf0005000,115200n8 console=ttyS0,115200n8 debug print-fatal-signals=1"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <0>; + clocks = <&core_clk>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <1>; + clocks = <&core_clk>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <2>; + clocks = <&core_clk>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <3>; + clocks = <&core_clk>; + }; + }; + + input_clk: input-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <33333333>; + }; + + cpu_intc: cpu-interrupt-controller { + compatible = "snps,archs-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + + idu_intc: idu-interrupt-controller { + compatible = "snps,archs-idu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&cpu_intc>; + }; + + arcpct: pct { + compatible = "snps,archs-pct"; + }; + + /* TIMER0 with interrupt for clockevent */ + timer { + compatible = "snps,arc-timer"; + interrupts = <16>; + interrupt-parent = <&cpu_intc>; + clocks = <&core_clk>; + }; + + /* 64-bit Global Free Running Counter */ + gfrc { + compatible = "snps,archs-timer-gfrc"; + clocks = <&core_clk>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&idu_intc>; + + ranges = <0x00000000 0xf0000000 0x10000000>; + + cgu_rst: reset-controller@8a0 { + compatible = "snps,hsdk-reset"; + #reset-cells = <1>; + reg = <0x8A0 0x4>, <0xFF0 0x4>; + }; + + core_clk: core-clk@0 { + compatible = "snps,hsdk-core-pll-clock"; + reg = <0x00 0x10>, <0x14B8 0x4>; + #clock-cells = <0>; + clocks = <&input_clk>; + }; + + serial: serial@5000 { + compatible = "snps,dw-apb-uart"; + reg = <0x5000 0x100>; + clock-frequency = <33330000>; + interrupts = <6>; + baud = <115200>; + reg-shift = <2>; + reg-io-width = <4>; + }; + + gmacclk: gmacclk { + compatible = "fixed-clock"; + clock-frequency = <400000000>; + #clock-cells = <0>; + }; + + mmcclk_ciu: mmcclk-ciu { + compatible = "fixed-clock"; + /* + * DW sdio controller has external ciu clock divider + * controlled via register in SDIO IP. Due to its + * unexpected default value (it should devide by 1 + * but it devides by 8) SDIO IP uses wrong clock and + * works unstable (see STAR 9001204800) + * So add temporary fix and change clock frequency + * from 100000000 to 12500000 Hz until we fix dw sdio + * driver itself. + */ + clock-frequency = <12500000>; + #clock-cells = <0>; + }; + + mmcclk_biu: mmcclk-biu { + compatible = "fixed-clock"; + clock-frequency = <400000000>; + #clock-cells = <0>; + }; + + ethernet@8000 { + #interrupt-cells = <1>; + compatible = "snps,dwmac"; + reg = <0x8000 0x2000>; + interrupts = <10>; + interrupt-names = "macirq"; + phy-mode = "rgmii"; + snps,pbl = <32>; + clocks = <&gmacclk>; + clock-names = "stmmaceth"; + phy-handle = <&phy0>; + resets = <&cgu_rst HSDK_ETH_RESET>; + reset-names = "stmmaceth"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@0 { + reg = <0>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + }; + }; + }; + + ohci@60000 { + compatible = "snps,hsdk-v1.0-ohci", "generic-ohci"; + reg = <0x60000 0x100>; + interrupts = <15>; + }; + + ehci@40000 { + compatible = "snps,hsdk-v1.0-ehci", "generic-ehci"; + reg = <0x40000 0x100>; + interrupts = <15>; + }; + + mmc@a000 { + compatible = "altr,socfpga-dw-mshc"; + reg = <0xa000 0x400>; + num-slots = <1>; + fifo-depth = <16>; + card-detect-delay = <200>; + clocks = <&mmcclk_biu>, <&mmcclk_ciu>; + clock-names = "biu", "ciu"; + interrupts = <12>; + bus-width = <4>; + }; + }; + + memory@80000000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "memory"; + reg = <0x80000000 0x40000000>; /* 1 GiB */ + }; +}; diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts index 3772c40c245ecaf546de55aac1a48e7fdff0ca85..8d787b251f73746191cfea3bd176bfb2869eccce 100644 --- a/arch/arc/boot/dts/nsim_hs.dts +++ b/arch/arc/boot/dts/nsim_hs.dts @@ -18,7 +18,7 @@ memory { device_type = "memory"; - /* CONFIG_LINUX_LINK_BASE needs to match low mem start */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MB low mem */ 0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */ }; diff --git a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi index 459fc656b759aee977c560dcbbc996c6deed0cd3..48bb4b4cd234ed65a8b4002dbf060f3bc09b7e0d 100644 --- a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi +++ b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi @@ -104,7 +104,6 @@ mmc@0x15000 { compatible = "snps,dw-mshc"; reg = <0x15000 0x400>; - num-slots = <1>; fifo-depth = <1024>; card-detect-delay = <200>; clocks = <&apbclk>, <&mmcclk>; diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index 6980b966a36403b6170130fa1389ea9fb66095b8..ec7c849a5c8e9887fbd60acf176f194cc0c4ba03 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -105,7 +105,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index 2233f5777a71f82cb5defb9ae99bbfc11772fdac..63d3cf69e0b02efe45fca035649951836fc1e948 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -104,7 +104,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index 30a3d4cf53d20af6f202a61e3f5a980e7f1e7c2e..f613ecac14a750e6008dc817d3a06727a4631989 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -107,7 +107,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/haps_hs_defconfig b/arch/arc/configs/haps_hs_defconfig index 57b3e599322f83d5babd0014c7d9ccf3a03578eb..db04ea4dd2d97237b843fd4b90706f2e0c8ef6d9 100644 --- a/arch/arc/configs/haps_hs_defconfig +++ b/arch/arc/configs/haps_hs_defconfig @@ -21,7 +21,6 @@ CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs" CONFIG_PREEMPT=y diff --git a/arch/arc/configs/haps_hs_smp_defconfig b/arch/arc/configs/haps_hs_smp_defconfig index f85985adebb245981d8a4130e8c0b91a45abe7dd..3507be2af6fe3684f4acca6de7009903da82b97e 100644 --- a/arch/arc/configs/haps_hs_smp_defconfig +++ b/arch/arc/configs/haps_hs_smp_defconfig @@ -23,7 +23,6 @@ CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu" @@ -85,5 +84,5 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/hsdk_defconfig b/arch/arc/configs/hsdk_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..15f0f6b5fec1ae6f8e0c1bfb4fa6c970915e1713 --- /dev/null +++ b/arch/arc/configs/hsdk_defconfig @@ -0,0 +1,81 @@ +CONFIG_DEFAULT_HOSTNAME="ARCLinux" +CONFIG_SYSVIPC=y +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/" +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_ARC_SOC_HSDK=y +CONFIG_ISA_ARCV2=y +CONFIG_SMP=y +CONFIG_LINUX_LINK_BASE=0x90000000 +CONFIG_LINUX_RAM_BASE=0x80000000 +CONFIG_ARC_BUILTIN_DTB_NAME="hsdk" +CONFIG_PREEMPT=y +# CONFIG_COMPACTION is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +CONFIG_MICREL_PHY=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +CONFIG_FB=y +CONFIG_FB_UDL=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_DW=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_RESET_HSDK=y +CONFIG_EXT3_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_STRIP_ASM_SYMS=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_ECHAINIV=y diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig index ede625c76216616b097365a3274e09ccea97d3d6..7c9c706ae7f66eb29d4cf48ca0b95d5dd44630f5 100644 --- a/arch/arc/configs/nps_defconfig +++ b/arch/arc/configs/nps_defconfig @@ -39,7 +39,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig index b0066a749d4c49d8a23e3bd33b4a52789789c913..6dff83a238b8591ba08f889e7d7013734ff587db 100644 --- a/arch/arc/configs/nsim_700_defconfig +++ b/arch/arc/configs/nsim_700_defconfig @@ -23,7 +23,6 @@ CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ARC_BUILTIN_DTB_NAME="nsim_700" CONFIG_PREEMPT=y # CONFIG_COMPACTION is not set diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig index ebe9ebb92933302af79f98dae000e8567b86ec6b..31ee51b987e7c5b97c2f044794f9d1c5b4eea73e 100644 --- a/arch/arc/configs/nsim_hs_defconfig +++ b/arch/arc/configs/nsim_hs_defconfig @@ -26,7 +26,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs" CONFIG_PREEMPT=y diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig index 4bde43278be6757c5c739bfd58a9f030a80c7568..8d3b1f67cae421c423e55c2622b5a78ea3d67794 100644 --- a/arch/arc/configs/nsim_hs_smp_defconfig +++ b/arch/arc/configs/nsim_hs_smp_defconfig @@ -24,7 +24,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs_idu" diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig index f6fb3d26557eb7c63b2f77263acfed80f0b45387..6168ce2ac2efdd869705a8a75e78f7f9b9c55af4 100644 --- a/arch/arc/configs/nsimosci_defconfig +++ b/arch/arc/configs/nsimosci_defconfig @@ -23,7 +23,6 @@ CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" # CONFIG_COMPACTION is not set CONFIG_NET=y diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig index b9f0fe00044b6c44d62a81a91064583cd9badee3..a70bdeb2b3fd03bdefd10388e69cd8e5b120ac0f 100644 --- a/arch/arc/configs/nsimosci_hs_defconfig +++ b/arch/arc/configs/nsimosci_hs_defconfig @@ -23,7 +23,6 @@ CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs" # CONFIG_COMPACTION is not set diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig index 155add7761ed63080bd81e830c819483fb55ee61..ef96406c446e823d4706e5c84b6ac0626d4b5812 100644 --- a/arch/arc/configs/nsimosci_hs_smp_defconfig +++ b/arch/arc/configs/nsimosci_hs_smp_defconfig @@ -18,7 +18,6 @@ CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y # CONFIG_ARC_TIMERS_64BIT is not set diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig index 4c5118384eb5f1c393208cde601fddc1be773494..f3018254939508e373662a2ae98f9d08be9425a2 100644 --- a/arch/arc/configs/tb10x_defconfig +++ b/arch/arc/configs/tb10x_defconfig @@ -38,7 +38,6 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig index c0d6a010751a9f80e4139fa6a9b833de4b24b6a8..4fcf4f2503f61a9e802b82e2cbb4aad9617725d8 100644 --- a/arch/arc/configs/vdk_hs38_defconfig +++ b/arch/arc/configs/vdk_hs38_defconfig @@ -94,7 +94,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_SHIRQ=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index 5c0971787acf4c18066c4bc537f36c1dae37232f..7b71464f6c2f2904e18893d8ba80c65471fc4ef5 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -98,7 +98,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_SHIRQ=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index ba8e802dba80bd0776508ff70945e6e8b54ea43e..b1c56d35f2a938e59c9677454499aeecb1da4f7e 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -98,6 +98,7 @@ /* Auxiliary registers */ #define AUX_IDENTITY 4 +#define AUX_EXEC_CTRL 8 #define AUX_INTR_VEC_BASE 0x25 #define AUX_VOL 0x5e @@ -135,12 +136,12 @@ struct bcr_identity { #endif }; -struct bcr_isa { +struct bcr_isa_arcv2 { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int div_rem:4, pad2:4, ldd:1, unalign:1, atomic:1, be:1, - pad1:11, atomic1:1, ver:8; + pad1:12, ver:8; #else - unsigned int ver:8, atomic1:1, pad1:11, be:1, atomic:1, unalign:1, + unsigned int ver:8, pad1:12, be:1, atomic:1, unalign:1, ldd:1, pad2:4, div_rem:4; #endif }; @@ -263,13 +264,13 @@ struct cpuinfo_arc { struct cpuinfo_arc_mmu mmu; struct cpuinfo_arc_bpu bpu; struct bcr_identity core; - struct bcr_isa isa; + struct bcr_isa_arcv2 isa; const char *details, *name; unsigned int vec_base; struct cpuinfo_arc_ccm iccm, dccm; struct { unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2, - fpu_sp:1, fpu_dp:1, pad2:6, + fpu_sp:1, fpu_dp:1, dual_iss_enb:1, dual_iss_exist:1, pad2:4, debug:1, ap:1, smart:1, rtt:1, pad3:4, timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4; } extn; diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 54b54da6384c197a93848e05ef292c224f5c0f91..11859287c52af55df317e7a6d3ab9403706bd172 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -123,6 +123,8 @@ static inline void atomic_set(atomic_t *v, int i) atomic_ops_unlock(flags); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + #endif /* diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 19ebddffb279db05ca8e53e2c4753665376cc9ad..8486f328cc5d2aea087812ab19be949001e64b73 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -47,7 +47,8 @@ : "r"(data), "r"(ptr)); \ }) -#define ARCH_DMA_MINALIGN L1_CACHE_BYTES +/* Largest line length for either L1 or L2 is 128 bytes */ +#define ARCH_DMA_MINALIGN 128 extern void arc_cache_init(void); extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); @@ -95,8 +96,12 @@ extern unsigned long perip_base, perip_end; #define ARC_REG_SLC_CTRL 0x903 #define ARC_REG_SLC_FLUSH 0x904 #define ARC_REG_SLC_INVALIDATE 0x905 +#define ARC_AUX_SLC_IVDL 0x910 +#define ARC_AUX_SLC_FLDL 0x912 #define ARC_REG_SLC_RGN_START 0x914 +#define ARC_REG_SLC_RGN_START1 0x915 #define ARC_REG_SLC_RGN_END 0x916 +#define ARC_REG_SLC_RGN_END1 0x917 /* Bit val in SLC_CONTROL */ #define SLC_CTRL_DIS 0x001 diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index 14c310f2e0b198ecac4d4d9f19a33d80b258005b..ec36d5b6d435bfca7a05148e05cd1f801c5cdecf 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -192,6 +192,12 @@ PUSHAX lp_start PUSHAX erbta +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + PUSHAX CTOP_AUX_GPA1 + PUSHAX CTOP_AUX_EFLAGS +#endif + lr r9, [ecr] st r9, [sp, PT_event] /* EV_Trap expects r9 to have ECR */ .endm @@ -208,6 +214,12 @@ * by hardware and that is not good. *-------------------------------------------------------------*/ .macro EXCEPTION_EPILOGUE +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + POPAX CTOP_AUX_EFLAGS + POPAX CTOP_AUX_GPA1 +#endif + POPAX erbta POPAX lp_start POPAX lp_end @@ -265,6 +277,12 @@ PUSHAX lp_end PUSHAX lp_start PUSHAX bta_l\LVL\() + +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + PUSHAX CTOP_AUX_GPA1 + PUSHAX CTOP_AUX_EFLAGS +#endif .endm /*-------------------------------------------------------------- @@ -277,6 +295,12 @@ * by hardware and that is not good. *-------------------------------------------------------------*/ .macro INTERRUPT_EPILOGUE LVL +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + POPAX CTOP_AUX_EFLAGS + POPAX CTOP_AUX_GPA1 +#endif + POPAX bta_l\LVL\() POPAX lp_start POPAX lp_end diff --git a/arch/arc/include/asm/futex.h b/arch/arc/include/asm/futex.h index 11e1b1f3acda7fb0a741dcf2d3aed5ae55d79de1..eb887dd13e74862b9bfbba21c2d2d9f09e3b113c 100644 --- a/arch/arc/include/asm/futex.h +++ b/arch/arc/include/asm/futex.h @@ -73,20 +73,11 @@ #endif -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - #ifndef CONFIG_ARC_HAS_LLSC preempt_disable(); /* to guarantee atomic r-m-w of futex op */ #endif @@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h index a64c447b0337804568c69cf2e15998deabdd9b40..8a4f77ea3238e6f017ae24ab6b55e2952637fe04 100644 --- a/arch/arc/include/asm/irqflags-arcv2.h +++ b/arch/arc/include/asm/irqflags-arcv2.h @@ -47,9 +47,6 @@ #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ (ARCV2_IRQ_DEF_PRIO << 1)) -/* SLEEP needs default irq priority (<=) which can interrupt the doze */ -#define ISA_SLEEP_ARG (0x10 | ARCV2_IRQ_DEF_PRIO) - #ifndef __ASSEMBLY__ /* diff --git a/arch/arc/include/asm/irqflags-compact.h b/arch/arc/include/asm/irqflags-compact.h index 4c6eed80cd8ba3bd935e60b30ffadf147326aeca..fcb80171fc346252c55d1593ac9198862daf5b15 100644 --- a/arch/arc/include/asm/irqflags-compact.h +++ b/arch/arc/include/asm/irqflags-compact.h @@ -43,8 +43,6 @@ #define ISA_INIT_STATUS_BITS STATUS_IE_MASK -#define ISA_SLEEP_ARG 0x3 - #ifndef __ASSEMBLY__ /****************************************************************** diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h index db7319e9b506e9ece826fde788aba60adada59cb..efb79fafff1d12214dc41923a75b237a969214f5 100644 --- a/arch/arc/include/asm/mmu.h +++ b/arch/arc/include/asm/mmu.h @@ -94,6 +94,8 @@ static inline int is_pae40_enabled(void) return IS_ENABLED(CONFIG_ARC_HAS_PAE40); } +extern int pae40_exist_but_not_enab(void); + #endif /* !__ASSEMBLY__ */ #endif diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 296c3426a6ad3589df2926c50c26832960a48ab8..109baa06831cecc38cf1d9f11ba447a31c0c4b14 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -85,7 +85,7 @@ typedef pte_t * pgtable_t; */ #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) +#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_RAM_BASE) #ifdef CONFIG_FLATMEM #define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 4104a08392146f6c479710557010135aa4774a15..8ee41e9881690b648bf1d4e5c385ddeef0a860c2 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -27,6 +27,13 @@ struct arc_fpu { }; #endif +#ifdef CONFIG_ARC_PLAT_EZNPS +struct eznps_dp { + unsigned int eflags; + unsigned int gpa1; +}; +#endif + /* Arch specific stuff which needs to be saved per task. * However these items are not so important so as to earn a place in * struct thread_info @@ -38,6 +45,9 @@ struct thread_struct { #ifdef CONFIG_ARC_FPU_SAVE_RESTORE struct arc_fpu fpu; #endif +#ifdef CONFIG_ARC_PLAT_EZNPS + struct eznps_dp dp; +#endif }; #define INIT_THREAD { \ @@ -68,9 +78,6 @@ struct task_struct; #endif -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 5297faa8a37803fd702da4270a7e23f5d6ba4f2b..5a8cb22724a1ef21a5043c6954aeed22c7904ff7 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -19,6 +19,11 @@ #ifdef CONFIG_ISA_ARCOMPACT struct pt_regs { +#ifdef CONFIG_ARC_PLAT_EZNPS + unsigned long eflags; /* Extended FLAGS */ + unsigned long gpa1; /* General Purpose Aux */ +#endif + /* Real registers */ unsigned long bta; /* bta_l1, bta_l2, erbta */ diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h index 233d5ffe6ec779eb376e5beaf5a031fce6fa97c1..47efc8451b7034b752337e0958af0d653470bc57 100644 --- a/arch/arc/include/asm/spinlock.h +++ b/arch/arc/include/asm/spinlock.h @@ -16,11 +16,6 @@ #define arch_spin_is_locked(x) ((x)->slock != __ARCH_SPIN_LOCK_UNLOCKED__) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, !VAL); -} - #ifdef CONFIG_ARC_HAS_LLSC static inline void arch_spin_lock(arch_spinlock_t *lock) @@ -252,9 +247,15 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) __asm__ __volatile__( "1: ex %0, [%1] \n" +#ifdef CONFIG_EZNPS_MTM_EXT + " .word %3 \n" +#endif " breq %0, %2, 1b \n" : "+&r" (val) : "r"(&(lock->slock)), "ir"(__ARCH_SPIN_LOCK_LOCKED__) +#ifdef CONFIG_EZNPS_MTM_EXT + , "i"(CTOP_INST_SCHD_RW) +#endif : "memory"); /* @@ -296,6 +297,12 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) */ smp_mb(); + /* + * EX is not really required here, a simple STore of 0 suffices. + * However this causes tasklist livelocks in SystemC based SMP virtual + * platforms where the systemc core scheduler uses EX as a cue for + * moving to next core. Do a git log of this file for details + */ __asm__ __volatile__( " ex %0, [%1] \n" : "+r" (val) diff --git a/arch/arc/include/asm/switch_to.h b/arch/arc/include/asm/switch_to.h index 1b171ab5fec0523f5dec5b1732b3d1c97f1243d8..f7d07feeea61593786682e0e81a7ce7236ee6016 100644 --- a/arch/arc/include/asm/switch_to.h +++ b/arch/arc/include/asm/switch_to.h @@ -26,10 +26,19 @@ extern void fpu_save_restore(struct task_struct *p, struct task_struct *n); #endif /* !CONFIG_ARC_FPU_SAVE_RESTORE */ +#ifdef CONFIG_ARC_PLAT_EZNPS +extern void dp_save_restore(struct task_struct *p, struct task_struct *n); +#define ARC_EZNPS_DP_PREV(p, n) dp_save_restore(p, n) +#else +#define ARC_EZNPS_DP_PREV(p, n) + +#endif /* !CONFIG_ARC_PLAT_EZNPS */ + struct task_struct *__switch_to(struct task_struct *p, struct task_struct *n); #define switch_to(prev, next, last) \ do { \ + ARC_EZNPS_DP_PREV(prev, next); \ ARC_FPU_PREV(prev, next); \ last = __switch_to(prev, next);\ ARC_FPU_NEXT(next); \ diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 8942c5c3b4c519eed7227200eaaa54cc4468698e..2dc5f4296d44afdb43aa20627e498f5364818c95 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -12,7 +12,6 @@ obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o -obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += arcksyms.o module.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index 3b67f538f1425699219fb2cd481be592ba047731..521ef3521a1cc932b8ae71f74bda9ce1491c3d98 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -29,8 +29,9 @@ static void __init arc_set_early_base_baud(unsigned long dt_root) { if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x")) arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */ - else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) - arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ + else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp") || + of_flat_dt_is_compatible(dt_root, "snps,hsdk")) + arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x & HSDK) */ else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps")) arc_base_baud = 800000000; /* Fixed 800MHz clk (NPS) */ else diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 9211707634dcf57e1aa0ac13fa4a6bbc79b99eeb..f285dbb280666cc1d9094d4175913e42b2b44587 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -25,12 +25,12 @@ * * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK) * -do_signal()invoked upon TIF_RESTORE_SIGMASK as well - * -Wrappers for sys_{,rt_}sigsuspend() nolonger needed as they don't + * -Wrappers for sys_{,rt_}sigsuspend() no longer needed as they don't * need ptregs anymore * * Vineetg: Oct 2009 * -In a rare scenario, Process gets a Priv-V exception and gets scheduled - * out. Since we don't do FAKE RTIE for Priv-V, CPU excpetion state remains + * out. Since we don't do FAKE RTIE for Priv-V, CPU exception state remains * active (AE bit enabled). This causes a double fault for a subseq valid * exception. Thus FAKE RTIE needed in low level Priv-Violation handler. * Instr Error could also cause similar scenario, so same there as well. @@ -59,7 +59,7 @@ */ #include -#include /* {EXTRY,EXIT} */ +#include /* {ENTRY,EXIT} */ #include #include @@ -80,8 +80,8 @@ .align 4 /* Each entry in the vector table must occupy 2 words. Since it is a jump - * across sections (.vector to .text) we are gauranteed that 'j somewhere' - * will use the 'j limm' form of the intrsuction as long as somewhere is in + * across sections (.vector to .text) we are guaranteed that 'j somewhere' + * will use the 'j limm' form of the instruction as long as somewhere is in * a section other than .vector. */ @@ -105,13 +105,13 @@ VECTOR handle_interrupt_level1 ; Other devices ; ******************** Exceptions ********************** VECTOR EV_MachineCheck ; 0x100, Fatal Machine check (0x20) -VECTOR EV_TLBMissI ; 0x108, Intruction TLB miss (0x21) +VECTOR EV_TLBMissI ; 0x108, Instruction TLB miss (0x21) VECTOR EV_TLBMissD ; 0x110, Data TLB miss (0x22) VECTOR EV_TLBProtV ; 0x118, Protection Violation (0x23) ; or Misaligned Access VECTOR EV_PrivilegeV ; 0x120, Privilege Violation (0x24) VECTOR EV_Trap ; 0x128, Trap exception (0x25) -VECTOR EV_Extension ; 0x130, Extn Intruction Excp (0x26) +VECTOR EV_Extension ; 0x130, Extn Instruction Excp (0x26) .rept 24 VECTOR reserved ; Reserved Exceptions @@ -199,7 +199,7 @@ END(handle_interrupt_level2) ; --------------------------------------------- ; User Mode Memory Bus Error Interrupt Handler -; (Kernel mode memory errors handled via seperate exception vectors) +; (Kernel mode memory errors handled via separate exception vectors) ; --------------------------------------------- ENTRY(mem_service) @@ -273,7 +273,7 @@ ENTRY(EV_TLBProtV) ;------ (5) Type of Protection Violation? ---------- ; ; ProtV Hardware Exception is triggered for Access Faults of 2 types - ; -Access Violaton : 00_23_(00|01|02|03)_00 + ; -Access Violation : 00_23_(00|01|02|03)_00 ; x r w r+w ; -Unaligned Access : 00_23_04_00 ; @@ -327,7 +327,7 @@ END(call_do_page_fault) .Lrestore_regs: - # Interrpts are actually disabled from this point on, but will get + # Interrupts are actually disabled from this point on, but will get # reenabled after we return from interrupt/exception. # But irq tracer needs to be told now... TRACE_ASM_IRQ_ENABLE @@ -335,7 +335,7 @@ END(call_do_page_fault) lr r10, [status32] ; Restore REG File. In case multiple Events outstanding, - ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None + ; use the same priority as rtie: EXCPN, L2 IRQ, L1 IRQ, None ; Note that we use realtime STATUS32 (not pt_regs->status32) to ; decide that. diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 1eea99beecc3b016c0f9d13129da65c26d333c30..85d9ea4a0acccc937a1cf51b29fc0480afa4010d 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -92,6 +92,12 @@ ENTRY(EV_MachineCheck) lr r0, [efa] mov r1, sp + ; hardware auto-disables MMU, re-enable it to allow kernel vaddr + ; access for say stack unwinding of modules for crash dumps + lr r3, [ARC_REG_PID] + or r3, r3, MMU_ENABLE + sr r3, [ARC_REG_PID] + lsr r3, r2, 8 bmsk r3, r3, 7 brne r3, ECR_C_MCHK_DUP_TLB, 1f diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index f928795fd07a813e9f6f3e6d86f325b45561b3dc..067ea362fb3efc3bc3a9217aaf197763eafb275e 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -75,10 +75,20 @@ void arc_init_IRQ(void) * Set a default priority for all available interrupts to prevent * switching of register banks if Fast IRQ and multiple register banks * are supported by CPU. + * Also disable private-per-core IRQ lines so faulty external HW won't + * trigger interrupt that kernel is not ready to handle. */ for (i = NR_EXCEPTIONS; i < irq_bcr.irqs + NR_EXCEPTIONS; i++) { write_aux_reg(AUX_IRQ_SELECT, i); write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO); + + /* + * Only mask cpu private IRQs here. + * "common" interrupts are masked at IDU, otherwise it would + * need to be unmasked at each cpu, with IPIs + */ + if (i < FIRST_EXT_IRQ) + write_aux_reg(AUX_IRQ_ENABLE, 0); } /* setup status32, don't enable intr yet as kernel doesn't want */ diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 7e608c6b0a018697fb22c52c7fb4ac46a45fe2f0..47b421fa0147be9604b1c808d378a0108f735b34 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -27,7 +27,7 @@ */ void arc_init_IRQ(void) { - int level_mask = 0; + unsigned int level_mask = 0, i; /* Is timer high priority Interrupt (Level2 in ARCompact jargon) */ level_mask |= IS_ENABLED(CONFIG_ARC_COMPACT_IRQ_LEVELS) << TIMER0_IRQ; @@ -40,6 +40,18 @@ void arc_init_IRQ(void) if (level_mask) pr_info("Level-2 interrupts bitset %x\n", level_mask); + + /* + * Disable all IRQ lines so faulty external hardware won't + * trigger interrupt that kernel is not ready to handle. + */ + for (i = TIMER0_IRQ; i < NR_CPU_IRQS; i++) { + unsigned int ienb; + + ienb = read_aux_reg(AUX_IENABLE); + ienb &= ~(1 << i); + write_aux_reg(AUX_IENABLE, ienb); + } } /* diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c deleted file mode 100644 index 72e1d73d0bd6241a0f294387f3b3f330435cbb00..0000000000000000000000000000000000000000 --- a/arch/arc/kernel/pcibios.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -/* - * We don't have to worry about legacy ISA devices, so nothing to do here - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 2a018de6d6cdbce2abc9f02b9671c41136c9ffb7..5ac3b547453fd5b4b5393fdc10dfff34a047941f 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -79,15 +79,40 @@ SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new) return uval; } +#ifdef CONFIG_ISA_ARCV2 + void arch_cpu_idle(void) { - /* sleep, but enable all interrupts before committing */ + /* Re-enable interrupts <= default irq priority before commiting SLEEP */ + const unsigned int arg = 0x10 | ARCV2_IRQ_DEF_PRIO; + __asm__ __volatile__( "sleep %0 \n" : - :"I"(ISA_SLEEP_ARG)); /* can't be "r" has to be embedded const */ + :"I"(arg)); /* can't be "r" has to be embedded const */ +} + +#elif defined(CONFIG_EZNPS_MTM_EXT) /* ARC700 variant in NPS */ + +void arch_cpu_idle(void) +{ + /* only the calling HW thread needs to sleep */ + __asm__ __volatile__( + ".word %0 \n" + : + :"i"(CTOP_INST_HWSCHD_WFT_IE12)); +} + +#else /* ARC700 */ + +void arch_cpu_idle(void) +{ + /* sleep, but enable both set E1/E2 (levels of interrutps) before committing */ + __asm__ __volatile__("sleep 0x3 \n"); } +#endif + asmlinkage void ret_from_fork(void); /* @@ -209,6 +234,10 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp) */ regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS; +#ifdef CONFIG_EZNPS_MTM_EXT + regs->eflags = 0; +#endif + /* bogus seed values for debugging */ regs->lp_start = 0x10; regs->lp_end = 0x80; diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 666613fde91d09cb48f76370dc5b9ff0bd91feae..fb83844daeea3550aacd27de2525711a6aa5fddc 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -51,6 +51,7 @@ static const struct id_to_str arc_cpu_rel[] = { { 0x51, "R2.0" }, { 0x52, "R2.1" }, { 0x53, "R3.0" }, + { 0x54, "R4.0" }, #endif { 0x00, NULL } }; @@ -62,6 +63,7 @@ static const struct id_to_str arc_cpu_nm[] = { #else { 0x40, "ARC EM" }, { 0x50, "ARC HS38" }, + { 0x54, "ARC HS48" }, #endif { 0x00, "Unknown" } }; @@ -119,11 +121,11 @@ static void read_arc_build_cfg_regs(void) struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; const struct id_to_str *tbl; + struct bcr_isa_arcv2 isa; FIX_PTR(cpu); READ_BCR(AUX_IDENTITY, cpu->core); - READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa); for (tbl = &arc_cpu_rel[0]; tbl->id != 0; tbl++) { if (cpu->core.family == tbl->id) { @@ -133,7 +135,7 @@ static void read_arc_build_cfg_regs(void) } for (tbl = &arc_cpu_nm[0]; tbl->id != 0; tbl++) { - if ((cpu->core.family & 0xF0) == tbl->id) + if ((cpu->core.family & 0xF4) == tbl->id) break; } cpu->name = tbl->str; @@ -192,6 +194,14 @@ static void read_arc_build_cfg_regs(void) cpu->bpu.full = bpu.ft; cpu->bpu.num_cache = 256 << bpu.bce; cpu->bpu.num_pred = 2048 << bpu.pte; + + if (cpu->core.family >= 0x54) { + unsigned int exec_ctrl; + + READ_BCR(AUX_EXEC_CTRL, exec_ctrl); + cpu->extn.dual_iss_exist = 1; + cpu->extn.dual_iss_enb = exec_ctrl & 1; + } } READ_BCR(ARC_REG_AP_BCR, bcr); @@ -205,18 +215,25 @@ static void read_arc_build_cfg_regs(void) cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt; + READ_BCR(ARC_REG_ISA_CFG_BCR, isa); + /* some hacks for lack of feature BCR info in old ARC700 cores */ if (is_isa_arcompact()) { - if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ + if (!isa.ver) /* ISA BCR absent, use Kconfig info */ cpu->isa.atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); - else - cpu->isa.atomic = cpu->isa.atomic1; + else { + /* ARC700_BUILD only has 2 bits of isa info */ + struct bcr_generic bcr = *(struct bcr_generic *)&isa; + cpu->isa.atomic = bcr.info & 1; + } cpu->isa.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); /* there's no direct way to distinguish 750 vs. 770 */ if (unlikely(cpu->core.family < 0x34 || cpu->mmu.ver < 3)) cpu->name = "ARC750"; + } else { + cpu->isa = isa; } } @@ -232,10 +249,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", core->family, core->cpu_id, core->chip_id); - n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s\n", + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", cpu_id, cpu->name, cpu->details, is_isa_arcompact() ? "ARCompact" : "ARCv2", - IS_AVAIL1(cpu->isa.be, "[Big-Endian]")); + IS_AVAIL1(cpu->isa.be, "[Big-Endian]"), + IS_AVAIL3(cpu->extn.dual_iss_exist, cpu->extn.dual_iss_enb, " Dual-Issue")); n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ", IS_AVAIL1(cpu->extn.timer0, "Timer0 "), @@ -385,13 +403,13 @@ void setup_processor(void) read_arc_build_cfg_regs(); arc_init_IRQ(); - printk(arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); + pr_info("%s", arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); arc_mmu_init(); arc_cache_init(); - printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); - printk(arc_platform_smp_cpuinfo()); + pr_info("%s", arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); + pr_info("%s", arc_platform_smp_cpuinfo()); arc_chk_core_config(); } @@ -510,7 +528,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) goto done; } - str = (char *)__get_free_page(GFP_TEMPORARY); + str = (char *)__get_free_page(GFP_KERNEL); if (!str) goto done; diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index ff83e78d0cfb5583eb44e874c0fd290cdeb24926..bcd7c9fc5d0fc9868c04ff98d08b2e1492d50bb8 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -80,7 +80,7 @@ int name(unsigned long address, struct pt_regs *regs) \ DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", do_privilege_fault, ILL_PRVOPC) DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC) DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC) -DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR) +DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", __weak do_memory_error, BUS_ADRERR) DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN) @@ -103,7 +103,7 @@ int do_misaligned_access(unsigned long address, struct pt_regs *regs, */ void do_machine_check_fault(unsigned long address, struct pt_regs *regs) { - die("Machine Check Exception", regs, address); + die("Unhandled Machine Check Exception", regs, address); } diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index f9caf79186d42dac848e2ca4ed8bd728bb659279..7d8c1d6c2f60f918e95f2cafc81c90c028684b9a 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -140,7 +140,7 @@ static void show_ecr_verbose(struct pt_regs *regs) } else if (vec == ECR_V_ITLB_MISS) { pr_cont("Insn could not be fetched\n"); } else if (vec == ECR_V_MACH_CHK) { - pr_cont("%s\n", (cause_code == 0x0) ? + pr_cont("Machine Check (%s)\n", (cause_code == 0x0) ? "Double Fault" : "Other Fatal Err"); } else if (vec == ECR_V_PROTV) { @@ -178,7 +178,7 @@ void show_regs(struct pt_regs *regs) struct callee_regs *cregs; char *buf; - buf = (char *)__get_free_page(GFP_TEMPORARY); + buf = (char *)__get_free_page(GFP_KERNEL); if (!buf) return; @@ -233,6 +233,9 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs, { current->thread.fault_address = address; + /* Show fault description */ + pr_info("\n%s\n", str); + /* Caller and Callee regs */ show_regs(regs); diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index a867575a758b9845c09a84fb4515f17f08f1272b..eee924dfffa6e1baf08221ee5e7e2cd23937d782 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -652,7 +652,7 @@ static void __ic_line_inv_vaddr(phys_addr_t paddr, unsigned long vaddr, #endif /* CONFIG_ARC_HAS_ICACHE */ -noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op) +noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op) { #ifdef CONFIG_ISA_ARCV2 /* @@ -665,6 +665,7 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op) static DEFINE_SPINLOCK(lock); unsigned long flags; unsigned int ctrl; + phys_addr_t end; spin_lock_irqsave(&lock, flags); @@ -694,8 +695,19 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op) * END needs to be setup before START (latter triggers the operation) * END can't be same as START, so add (l2_line_sz - 1) to sz */ - write_aux_reg(ARC_REG_SLC_RGN_END, (paddr + sz + l2_line_sz - 1)); - write_aux_reg(ARC_REG_SLC_RGN_START, paddr); + end = paddr + sz + l2_line_sz - 1; + if (is_pae40_enabled()) + write_aux_reg(ARC_REG_SLC_RGN_END1, upper_32_bits(end)); + + write_aux_reg(ARC_REG_SLC_RGN_END, lower_32_bits(end)); + + if (is_pae40_enabled()) + write_aux_reg(ARC_REG_SLC_RGN_START1, upper_32_bits(paddr)); + + write_aux_reg(ARC_REG_SLC_RGN_START, lower_32_bits(paddr)); + + /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */ + read_aux_reg(ARC_REG_SLC_CTRL); while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY); @@ -703,6 +715,58 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op) #endif } +noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op) +{ +#ifdef CONFIG_ISA_ARCV2 + /* + * SLC is shared between all cores and concurrent aux operations from + * multiple cores need to be serialized using a spinlock + * A concurrent operation can be silently ignored and/or the old/new + * operation can remain incomplete forever (lockup in SLC_CTRL_BUSY loop + * below) + */ + static DEFINE_SPINLOCK(lock); + + const unsigned long SLC_LINE_MASK = ~(l2_line_sz - 1); + unsigned int ctrl, cmd; + unsigned long flags; + int num_lines; + + spin_lock_irqsave(&lock, flags); + + ctrl = read_aux_reg(ARC_REG_SLC_CTRL); + + /* Don't rely on default value of IM bit */ + if (!(op & OP_FLUSH)) /* i.e. OP_INV */ + ctrl &= ~SLC_CTRL_IM; /* clear IM: Disable flush before Inv */ + else + ctrl |= SLC_CTRL_IM; + + write_aux_reg(ARC_REG_SLC_CTRL, ctrl); + + cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL; + + sz += paddr & ~SLC_LINE_MASK; + paddr &= SLC_LINE_MASK; + + num_lines = DIV_ROUND_UP(sz, l2_line_sz); + + while (num_lines-- > 0) { + write_aux_reg(cmd, paddr); + paddr += l2_line_sz; + } + + /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */ + read_aux_reg(ARC_REG_SLC_CTRL); + + while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY); + + spin_unlock_irqrestore(&lock, flags); +#endif +} + +#define slc_op(paddr, sz, op) slc_op_rgn(paddr, sz, op) + noinline static void slc_entire_op(const int op) { unsigned int ctrl, r = ARC_REG_SLC_CTRL; @@ -1083,7 +1147,7 @@ SYSCALL_DEFINE3(cacheflush, uint32_t, start, uint32_t, sz, uint32_t, flags) */ noinline void __init arc_ioc_setup(void) { - unsigned int ap_sz; + unsigned int ioc_base, mem_sz; /* Flush + invalidate + disable L1 dcache */ __dc_disable(); @@ -1092,18 +1156,29 @@ noinline void __init arc_ioc_setup(void) if (read_aux_reg(ARC_REG_SLC_BCR)) slc_entire_op(OP_FLUSH_N_INV); - /* IOC Aperture start: TDB: handle non default CONFIG_LINUX_LINK_BASE */ - write_aux_reg(ARC_REG_IO_COH_AP0_BASE, 0x80000); - /* - * IOC Aperture size: - * decoded as 2 ^ (SIZE + 2) KB: so setting 0x11 implies 512M + * currently IOC Aperture covers entire DDR * TBD: fix for PGU + 1GB of low mem * TBD: fix for PAE */ - ap_sz = order_base_2(arc_get_mem_sz()/1024) - 2; - write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, ap_sz); + mem_sz = arc_get_mem_sz(); + + if (!is_power_of_2(mem_sz) || mem_sz < 4096) + panic("IOC Aperture size must be power of 2 larger than 4KB"); + + /* + * IOC Aperture size decoded as 2 ^ (SIZE + 2) KB, + * so setting 0x11 implies 512MB, 0x12 implies 1GB... + */ + write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, order_base_2(mem_sz >> 10) - 2); + + /* for now assume kernel base is start of IOC aperture */ + ioc_base = CONFIG_LINUX_RAM_BASE; + + if (ioc_base % mem_sz != 0) + panic("IOC Aperture start must be aligned to the size of the aperture"); + write_aux_reg(ARC_REG_IO_COH_AP0_BASE, ioc_base >> 12); write_aux_reg(ARC_REG_IO_COH_PARTIAL, 1); write_aux_reg(ARC_REG_IO_COH_ENABLE, 1); @@ -1111,6 +1186,13 @@ noinline void __init arc_ioc_setup(void) __dc_enable(); } +/* + * Cache related boot time checks/setups only needed on master CPU: + * - Geometry checks (kernel build and hardware agree: e.g. L1_CACHE_BYTES) + * Assume SMP only, so all cores will have same cache config. A check on + * one core suffices for all + * - IOC setup / dma callbacks only need to be done once + */ void __init arc_cache_init_master(void) { unsigned int __maybe_unused cpu = smp_processor_id(); @@ -1188,14 +1270,29 @@ void __ref arc_cache_init(void) unsigned int __maybe_unused cpu = smp_processor_id(); char str[256]; - printk(arc_cache_mumbojumbo(0, str, sizeof(str))); + pr_info("%s", arc_cache_mumbojumbo(0, str, sizeof(str))); - /* - * Only master CPU needs to execute rest of function: - * - Assume SMP so all cores will have same cache config so - * any geomtry checks will be same for all - * - IOC setup / dma callbacks only need to be setup once - */ if (!cpu) arc_cache_init_master(); + + /* + * In PAE regime, TLB and cache maintenance ops take wider addresses + * And even if PAE is not enabled in kernel, the upper 32-bits still need + * to be zeroed to keep the ops sane. + * As an optimization for more common !PAE enabled case, zero them out + * once at init, rather than checking/setting to 0 for every runtime op + */ + if (is_isa_arcv2() && pae40_exist_but_not_enab()) { + + if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) + write_aux_reg(ARC_REG_IC_PTAG_HI, 0); + + if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) + write_aux_reg(ARC_REG_DC_PTAG_HI, 0); + + if (l2_line_sz) { + write_aux_reg(ARC_REG_SLC_RGN_END1, 0); + write_aux_reg(ARC_REG_SLC_RGN_START1, 0); + } + } } diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 71d3efff99d35c56c6f30bea8a6ab1cf1702d753..e9d93604ad0ff7b76a5458235b3ab4d0ef18aefb 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -153,6 +153,19 @@ static void _dma_cache_sync(phys_addr_t paddr, size_t size, } } +/* + * arc_dma_map_page - map a portion of a page for streaming DMA + * + * Ensure that any data held in the cache is appropriately discarded + * or written back. + * + * The device owns this memory once this call has completed. The CPU + * can regain ownership by calling dma_unmap_page(). + * + * Note: while it takes struct page as arg, caller can "abuse" it to pass + * a region larger than PAGE_SIZE, provided it is physically contiguous + * and this still works correctly + */ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, unsigned long attrs) @@ -165,6 +178,24 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page, return plat_phys_to_dma(dev, paddr); } +/* + * arc_dma_unmap_page - unmap a buffer previously mapped through dma_map_page() + * + * After this call, reads by the CPU to the buffer are guaranteed to see + * whatever the device wrote there. + * + * Note: historically this routine was not implemented for ARC + */ +static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, + unsigned long attrs) +{ + phys_addr_t paddr = plat_dma_to_phys(dev, handle); + + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + _dma_cache_sync(paddr, size, dir); +} + static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs) { @@ -178,6 +209,18 @@ static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, return nents; } +static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct scatterlist *s; + int i; + + for_each_sg(sg, s, nents, i) + arc_dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, + attrs); +} + static void arc_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { @@ -223,7 +266,9 @@ const struct dma_map_ops arc_dma_ops = { .free = arc_dma_free, .mmap = arc_dma_mmap, .map_page = arc_dma_map_page, + .unmap_page = arc_dma_unmap_page, .map_sg = arc_dma_map_sg, + .unmap_sg = arc_dma_unmap_sg, .sync_single_for_device = arc_dma_sync_single_for_device, .sync_single_for_cpu = arc_dma_sync_single_for_cpu, .sync_sg_for_cpu = arc_dma_sync_sg_for_cpu, diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index 162c975288725167a02ab369cc5c5445dd1ac5db..a0b7bd6d030d698594b844886768f5ddc690b04b 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c @@ -207,7 +207,7 @@ void do_page_fault(unsigned long address, struct pt_regs *regs) /* Are we prepared to handle this kernel fault? * * (The kernel has valid exception-points in the source - * when it acesses user-memory. When it fails in one + * when it accesses user-memory. When it fails in one * of those points, we find it in a table and do a jump * to some fixup code that loads an appropriate error * code) diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 8c9415ed62804d0a8b4a35df176f1b43e6c1be44..ba145065c579bfff5af1d0ca4e569a8b8c49da32 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -26,7 +26,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE); char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE); EXPORT_SYMBOL(empty_zero_page); -static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; +static const unsigned long low_mem_start = CONFIG_LINUX_RAM_BASE; static unsigned long low_mem_sz; #ifdef CONFIG_HIGHMEM @@ -63,7 +63,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) if (!low_mem_sz) { if (base != low_mem_start) - panic("CONFIG_LINUX_LINK_BASE != DT memory { }"); + panic("CONFIG_LINUX_RAM_BASE != DT memory { }"); low_mem_sz = size; in_use = 1; @@ -161,7 +161,7 @@ void __init setup_arch_memory(void) * We can't use the helper free_area_init(zones[]) because it uses * PAGE_OFFSET to compute the @min_low_pfn which would be wrong * when our kernel doesn't start at PAGE_OFFSET, i.e. - * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE + * PAGE_OFFSET != CONFIG_LINUX_RAM_BASE */ free_area_init_node(0, /* node-id */ zones_size, /* num pages per zone */ diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index d0126fdfe2d8546d62883cbef419e4b76589cf18..8ceefbf72fb0f8b0d1ce9ca1516bb7edd487cc9a 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -104,6 +104,8 @@ /* A copy of the ASID from the PID reg is kept in asid_cache */ DEFINE_PER_CPU(unsigned int, asid_cache) = MM_CTXT_FIRST_CYCLE; +static int __read_mostly pae_exists; + /* * Utility Routine to erase a J-TLB entry * Caller needs to setup Index Reg (manually or via getIndex) @@ -784,7 +786,7 @@ void read_decode_mmu_bcr(void) mmu->u_dtlb = mmu4->u_dtlb * 4; mmu->u_itlb = mmu4->u_itlb * 4; mmu->sasid = mmu4->sasid; - mmu->pae = mmu4->pae; + pae_exists = mmu->pae = mmu4->pae; } } @@ -809,12 +811,17 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) return buf; } +int pae40_exist_but_not_enab(void) +{ + return pae_exists && !is_pae40_enabled(); +} + void arc_mmu_init(void) { char str[256]; struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; - printk(arc_mmu_mumbojumbo(0, str, sizeof(str))); + pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); /* * Can't be done in processor.h due to header include depenedencies @@ -859,6 +866,9 @@ void arc_mmu_init(void) /* swapper_pg_dir is the pgd for the kernel, used by vmalloc */ write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir); #endif + + if (pae40_exist_but_not_enab()) + write_aux_reg(ARC_REG_TLBPD1HI, 0); } /* @@ -898,9 +908,6 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, local_irq_save(flags); - /* re-enable the MMU */ - write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID)); - /* loop thru all sets of TLB */ for (set = 0; set < mmu->sets; set++) { diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index b30e4e36bb00dd3c5feaa685fe08dd0629404119..0e1e47a67c73617232c4ed62ca96c2ac74286975 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -274,6 +274,13 @@ ex_saved_reg1: .macro COMMIT_ENTRY_TO_MMU #if (CONFIG_ARC_MMU_VER < 4) +#ifdef CONFIG_EZNPS_MTM_EXT + /* verify if entry for this vaddr+ASID already exists */ + sr TLBProbe, [ARC_REG_TLBCOMMAND] + lr r0, [ARC_REG_TLBINDEX] + bbit0 r0, 31, 88f +#endif + /* Get free TLB slot: Set = computed from vaddr, way = random */ sr TLBGetIndex, [ARC_REG_TLBCOMMAND] @@ -287,6 +294,8 @@ ex_saved_reg1: #else sr TLBInsertEntry, [ARC_REG_TLBCOMMAND] #endif + +88: .endm diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c index 38ff349d7f2a79331fbaac9e33bb4ba2325aef1a..cf14ebc36916a2a0eca39728c0cc0f315d58bbeb 100644 --- a/arch/arc/plat-axs10x/axs10x.c +++ b/arch/arc/plat-axs10x/axs10x.c @@ -80,22 +80,6 @@ static void __init axs10x_enable_gpio_intc_wire(void) iowrite32(1 << MB_TO_GPIO_IRQ, (void __iomem *) GPIO_INTEN); } -static inline void __init -write_cgu_reg(uint32_t value, void __iomem *reg, void __iomem *lock_reg) -{ - unsigned int loops = 128 * 1024, ctr; - - iowrite32(value, reg); - - ctr = loops; - while (((ioread32(lock_reg) & 1) == 1) && ctr--) /* wait for unlock */ - cpu_relax(); - - ctr = loops; - while (((ioread32(lock_reg) & 1) == 0) && ctr--) /* wait for re-lock */ - cpu_relax(); -} - static void __init axs10x_print_board_ver(unsigned int creg, const char *str) { union ver { @@ -127,6 +111,13 @@ static void __init axs10x_early_init(void) axs10x_enable_gpio_intc_wire(); + /* + * Reset ethernet IP core. + * TODO: get rid of this quirk after axs10x reset driver (or simple + * reset driver) will be available in upstream. + */ + iowrite32((1 << 5), (void __iomem *) CREG_MB_SW_RESET); + scnprintf(mb, 32, "MainBoard v%d", mb_rev); axs10x_print_board_ver(CREG_MB_VER, mb); } @@ -314,7 +305,6 @@ static void __init axs101_early_init(void) #ifdef CONFIG_AXS103 -#define AXC003_CGU 0xF0000000 #define AXC003_CREG 0xF0001000 #define AXC003_MST_AXI_TUNNEL 0 #define AXC003_MST_HS38 1 @@ -324,131 +314,38 @@ static void __init axs101_early_init(void) #define CREG_CPU_TUN_IO_CTRL (AXC003_CREG + 0x494) -union pll_reg { - struct { -#ifdef CONFIG_CPU_BIG_ENDIAN - unsigned int pad:17, noupd:1, bypass:1, edge:1, high:6, low:6; -#else - unsigned int low:6, high:6, edge:1, bypass:1, noupd:1, pad:17; -#endif - }; - unsigned int val; -}; - -static unsigned int __init axs103_get_freq(void) -{ - union pll_reg idiv, fbdiv, odiv; - unsigned int f = 33333333; - - idiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 0); - fbdiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 4); - odiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 8); - - if (idiv.bypass != 1) - f = f / (idiv.low + idiv.high); - - if (fbdiv.bypass != 1) - f = f * (fbdiv.low + fbdiv.high); - - if (odiv.bypass != 1) - f = f / (odiv.low + odiv.high); - - f = (f + 500000) / 1000000; /* Rounding */ - return f; -} - -static inline unsigned int __init encode_div(unsigned int id, int upd) -{ - union pll_reg div; - - div.val = 0; - - div.noupd = !upd; - div.bypass = id == 1 ? 1 : 0; - div.edge = (id%2 == 0) ? 0 : 1; /* 0 = rising */ - div.low = (id%2 == 0) ? id >> 1 : (id >> 1)+1; - div.high = id >> 1; - - return div.val; -} - -noinline static void __init -axs103_set_freq(unsigned int id, unsigned int fd, unsigned int od) -{ - write_cgu_reg(encode_div(id, 0), - (void __iomem *)AXC003_CGU + 0x80 + 0, - (void __iomem *)AXC003_CGU + 0x110); - - write_cgu_reg(encode_div(fd, 0), - (void __iomem *)AXC003_CGU + 0x80 + 4, - (void __iomem *)AXC003_CGU + 0x110); - - write_cgu_reg(encode_div(od, 1), - (void __iomem *)AXC003_CGU + 0x80 + 8, - (void __iomem *)AXC003_CGU + 0x110); -} - static void __init axs103_early_init(void) { - int offset = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk"); - const struct fdt_property *prop = fdt_get_property(initial_boot_params, - offset, - "clock-frequency", - NULL); - u32 freq = be32_to_cpu(*(u32*)(prop->data)) / 1000000, orig = freq; - +#ifdef CONFIG_ARC_MCIP /* * AXS103 configurations for SMP/QUAD configurations share device tree - * which defaults to 90 MHz. However recent failures of Quad config + * which defaults to 100 MHz. However recent failures of Quad config * revealed P&R timing violations so clamp it down to safe 50 MHz * Instead of duplicating defconfig/DT for SMP/QUAD, add a small hack - * - * This hack is really hacky as of now. Fix it properly by getting the - * number of cores as return value of platform's early SMP callback + * of fudging the freq in DT */ -#ifdef CONFIG_ARC_MCIP unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F; - if (num_cores > 2) - freq = 50; -#endif - - switch (freq) { - case 33: - axs103_set_freq(1, 1, 1); - break; - case 50: - axs103_set_freq(1, 30, 20); - break; - case 75: - axs103_set_freq(2, 45, 10); - break; - case 90: - axs103_set_freq(2, 54, 10); - break; - case 100: - axs103_set_freq(1, 30, 10); - break; - case 125: - axs103_set_freq(2, 45, 6); - break; - default: + if (num_cores > 2) { + u32 freq = 50, orig; /* - * In this case, core_frequency derived from - * DT "clock-frequency" might not match with board value. - * Hence update it to match the board value. + * TODO: use cpu node "cpu-freq" param instead of platform-specific + * "/cpu_card/core_clk" as it works only if we use fixed-clock for cpu. */ - freq = axs103_get_freq(); - break; - } - - pr_info("Freq is %dMHz\n", freq); - - /* Patching .dtb in-place with new core clock value */ - if (freq != orig ) { - freq = cpu_to_be32(freq * 1000000); - fdt_setprop_inplace(initial_boot_params, offset, - "clock-frequency", &freq, sizeof(freq)); + int off = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk"); + const struct fdt_property *prop; + + prop = fdt_get_property(initial_boot_params, off, + "clock-frequency", NULL); + orig = be32_to_cpu(*(u32*)(prop->data)) / 1000000; + + /* Patching .dtb in-place with new core clock value */ + if (freq != orig ) { + freq = cpu_to_be32(freq * 1000000); + fdt_setprop_inplace(initial_boot_params, off, + "clock-frequency", &freq, sizeof(freq)); + } } +#endif /* Memory maps already config in pre-bootloader */ diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig index 1595a38e50cd86f841639702b2b707243c64f5d8..e151e2067886ea52ec75d151210c9e71a4ec0a81 100644 --- a/arch/arc/plat-eznps/Kconfig +++ b/arch/arc/plat-eznps/Kconfig @@ -12,8 +12,8 @@ menuconfig ARC_PLAT_EZNPS help Support for EZchip development platforms, based on ARC700 cores. - We handle few flavours: - - Hardware Emulator AKA HE which is FPGA based chasis + We handle few flavors: + - Hardware Emulator AKA HE which is FPGA based chassis - Simulator based on MetaWare nSIM - NPS400 chip based on ASIC @@ -32,3 +32,25 @@ config EZNPS_MTM_EXT any of them seem like CPU from Linux point of view. All threads within same core share the execution unit of the core and HW scheduler round robin between them. + +config EZNPS_MEM_ERROR_ALIGN + bool "ARC-EZchip Memory error as an exception" + depends on EZNPS_MTM_EXT + default n + help + On the real chip of the NPS, user memory errors are handled + as a machine check exception, which is fatal, whereas on + simulator platform for NPS, is handled as a Level 2 interrupt + (just a stock ARC700) which is recoverable. This option makes + simulator behave like hardware. + +config EZNPS_SHARED_AUX_REGS + bool "ARC-EZchip Shared Auxiliary Registers Per Core" + depends on ARC_PLAT_EZNPS + default y + help + On the real chip of the NPS, auxiliary registers are shared between + all the cpus of the core, whereas on simulator platform for NPS, + each cpu has a different set of auxiliary registers. Configuration + should be unset if auxiliary registers are not shared between the cpus + of the core, so there will be a need to initialize them per cpu. diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile index 21091b199df025141c76b8c8fcac2e62fc5d6115..8d4371706b2fcc6d1c3d7c4487c9d7c2237dbbd3 100644 --- a/arch/arc/plat-eznps/Makefile +++ b/arch/arc/plat-eznps/Makefile @@ -2,6 +2,6 @@ # Makefile for the linux kernel. # -obj-y := entry.o platform.o +obj-y := entry.o platform.o ctop.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o diff --git a/arch/arc/plat-eznps/ctop.c b/arch/arc/plat-eznps/ctop.c new file mode 100644 index 0000000000000000000000000000000000000000..030bcd070a1b445f270348c2dea5660ad78928ad --- /dev/null +++ b/arch/arc/plat-eznps/ctop.c @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#include +#include +#include + +void dp_save_restore(struct task_struct *prev, struct task_struct *next) +{ + struct eznps_dp *prev_task_dp = &prev->thread.dp; + struct eznps_dp *next_task_dp = &next->thread.dp; + + /* Here we save all Data Plane related auxiliary registers */ + prev_task_dp->eflags = read_aux_reg(CTOP_AUX_EFLAGS); + write_aux_reg(CTOP_AUX_EFLAGS, next_task_dp->eflags); + + prev_task_dp->gpa1 = read_aux_reg(CTOP_AUX_GPA1); + write_aux_reg(CTOP_AUX_GPA1, next_task_dp->gpa1); +} diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S index 328261c27cdac008543898c8f115da9c24f95e09..091c92c32ab65c24d8a8f79ca444e4b9d1408c19 100644 --- a/arch/arc/plat-eznps/entry.S +++ b/arch/arc/plat-eznps/entry.S @@ -27,7 +27,7 @@ .align 1024 ; HW requierment for restart first PC ENTRY(res_service) -#ifdef CONFIG_EZNPS_MTM_EXT +#if defined(CONFIG_EZNPS_MTM_EXT) && defined(CONFIG_EZNPS_SHARED_AUX_REGS) ; There is no work for HW thread id != 0 lr r3, [CTOP_AUX_THREAD_ID] cmp r3, 0 diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h index ee2e32df5e90d5d77090a415335ac6f4708e161b..0c7d11022d0f8875256e64162d2ee0f1f0aa85e1 100644 --- a/arch/arc/plat-eznps/include/plat/ctop.h +++ b/arch/arc/plat-eznps/include/plat/ctop.h @@ -39,6 +39,7 @@ #define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018) #define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020) #define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024) +#define CTOP_AUX_DPC (CTOP_AUX_BASE + 0x02C) #define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030) #define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080) #define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088) @@ -46,6 +47,7 @@ #define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300) /* EZchip core instructions */ +#define CTOP_INST_HWSCHD_WFT_IE12 0x3E6F7344 #define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF #define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103 #define CTOP_INST_SCHD_RW 0x3E6F7004 diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c index aaaaffd3d94052fbbbd65da8b7eb509b72eb01d5..2388de3d09ef9e71f710ec4625e20a9e85cbdc1e 100644 --- a/arch/arc/plat-eznps/mtm.c +++ b/arch/arc/plat-eznps/mtm.c @@ -21,10 +21,22 @@ #include #include -#define MT_CTRL_HS_CNT 0xFF +#define MT_HS_CNT_MIN 0x01 +#define MT_HS_CNT_MAX 0xFF #define MT_CTRL_ST_CNT 0xF #define NPS_NUM_HW_THREADS 0x10 +static int mtm_hs_ctr = MT_HS_CNT_MAX; + +#ifdef CONFIG_EZNPS_MEM_ERROR_ALIGN +int do_memory_error(unsigned long address, struct pt_regs *regs) +{ + die("Invalid Mem Access", regs, address); + + return 1; +} +#endif + static void mtm_init_nat(int cpu) { struct nps_host_reg_mtm_cfg mtm_cfg; @@ -98,6 +110,18 @@ void mtm_enable_core(unsigned int cpu) int i; struct nps_host_reg_aux_mt_ctrl mt_ctrl; struct nps_host_reg_mtm_cfg mtm_cfg; + struct nps_host_reg_aux_dpc dpc; + + /* + * Initializing dpc register in each CPU. + * Overwriting the init value of the DPC + * register so that CMEM and FMT virtual address + * spaces are accessible, and Data Plane HW + * facilities are enabled. + */ + dpc.ien = 1; + dpc.men = 1; + write_aux_reg(CTOP_AUX_DPC, dpc.value); if (NPS_CPU_TO_THREAD_NUM(cpu) != 0) return; @@ -118,9 +142,7 @@ void mtm_enable_core(unsigned int cpu) /* Enable HW schedule, stall counter, mtm */ mt_ctrl.value = 0; mt_ctrl.hsen = 1; - mt_ctrl.hs_cnt = MT_CTRL_HS_CNT; - mt_ctrl.sten = 1; - mt_ctrl.st_cnt = MT_CTRL_ST_CNT; + mt_ctrl.hs_cnt = mtm_hs_ctr; mt_ctrl.mten = 1; write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value); @@ -131,3 +153,23 @@ void mtm_enable_core(unsigned int cpu) */ cpu_relax(); } + +/* Verify and set the value of the mtm hs counter */ +static int __init set_mtm_hs_ctr(char *ctr_str) +{ + long hs_ctr; + int ret; + + ret = kstrtol(ctr_str, 0, &hs_ctr); + + if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) { + pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n", + hs_ctr, MT_HS_CNT_MIN, MT_HS_CNT_MAX); + return -EINVAL; + } + + mtm_hs_ctr = hs_ctr; + + return 0; +} +early_param("nps_mtm_hs_ctr", set_mtm_hs_ctr); diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bd08de4be75e7edc4ce8875c8af7f1723f0f5b01 --- /dev/null +++ b/arch/arc/plat-hsdk/Kconfig @@ -0,0 +1,10 @@ +# Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +menuconfig ARC_SOC_HSDK + bool "ARC HS Development Kit SOC" + select CLK_HSDK diff --git a/arch/arc/plat-hsdk/Makefile b/arch/arc/plat-hsdk/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9a50c511a672d89c96e4d31a06ba37b858a2de9c --- /dev/null +++ b/arch/arc/plat-hsdk/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +obj-y := platform.o diff --git a/arch/arc/plat-hsdk/platform.c b/arch/arc/plat-hsdk/platform.c new file mode 100644 index 0000000000000000000000000000000000000000..744e62e5878898b21f49c58c588ddb167523cc60 --- /dev/null +++ b/arch/arc/plat-hsdk/platform.c @@ -0,0 +1,108 @@ +/* + * ARC HSDK Platform support code + * + * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define ARC_CCM_UNUSED_ADDR 0x60000000 + +static void __init hsdk_init_per_cpu(unsigned int cpu) +{ + /* + * By default ICCM is mapped to 0x7z while this area is used for + * kernel virtual mappings, so move it to currently unused area. + */ + if (cpuinfo_arc700[cpu].iccm.sz) + write_aux_reg(ARC_REG_AUX_ICCM, ARC_CCM_UNUSED_ADDR); + + /* + * By default DCCM is mapped to 0x8z while this area is used by kernel, + * so move it to currently unused area. + */ + if (cpuinfo_arc700[cpu].dccm.sz) + write_aux_reg(ARC_REG_AUX_DCCM, ARC_CCM_UNUSED_ADDR); +} + +#define ARC_PERIPHERAL_BASE 0xf0000000 +#define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000) +#define CREG_PAE (CREG_BASE + 0x180) +#define CREG_PAE_UPDATE (CREG_BASE + 0x194) + +#define CREG_CORE_IF_CLK_DIV (CREG_BASE + 0x4B8) +#define CREG_CORE_IF_CLK_DIV_2 0x1 +#define CGU_BASE ARC_PERIPHERAL_BASE +#define CGU_PLL_STATUS (ARC_PERIPHERAL_BASE + 0x4) +#define CGU_PLL_CTRL (ARC_PERIPHERAL_BASE + 0x0) +#define CGU_PLL_STATUS_LOCK BIT(0) +#define CGU_PLL_STATUS_ERR BIT(1) +#define CGU_PLL_CTRL_1GHZ 0x3A10 +#define HSDK_PLL_LOCK_TIMEOUT 500 + +#define HSDK_PLL_LOCKED() \ + !!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK) + +#define HSDK_PLL_ERR() \ + !!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR) + +static void __init hsdk_set_cpu_freq_1ghz(void) +{ + u32 timeout = HSDK_PLL_LOCK_TIMEOUT; + + /* + * As we set cpu clock which exceeds 500MHz, the divider for the interface + * clock must be programmed to div-by-2. + */ + iowrite32(CREG_CORE_IF_CLK_DIV_2, (void __iomem *) CREG_CORE_IF_CLK_DIV); + + /* Set cpu clock to 1GHz */ + iowrite32(CGU_PLL_CTRL_1GHZ, (void __iomem *) CGU_PLL_CTRL); + + while (!HSDK_PLL_LOCKED() && timeout--) + cpu_relax(); + + if (!HSDK_PLL_LOCKED() || HSDK_PLL_ERR()) + pr_err("Failed to setup CPU frequency to 1GHz!"); +} + +static void __init hsdk_init_early(void) +{ + /* + * PAE remapping for DMA clients does not work due to an RTL bug, so + * CREG_PAE register must be programmed to all zeroes, otherwise it + * will cause problems with DMA to/from peripherals even if PAE40 is + * not used. + */ + + /* Default is 1, which means "PAE offset = 4GByte" */ + writel_relaxed(0, (void __iomem *) CREG_PAE); + + /* Really apply settings made above */ + writel(1, (void __iomem *) CREG_PAE_UPDATE); + + /* + * Setup CPU frequency to 1GHz. + * TODO: remove it after smart hsdk pll driver will be introduced. + */ + hsdk_set_cpu_freq_1ghz(); +} + +static const char *hsdk_compat[] __initconst = { + "snps,hsdk", + NULL, +}; + +MACHINE_START(SIMULATION, "hsdk") + .dt_compat = hsdk_compat, + .init_early = hsdk_init_early, + .init_per_cpu = hsdk_init_per_cpu, +MACHINE_END diff --git a/arch/arc/plat-sim/Kconfig b/arch/arc/plat-sim/Kconfig deleted file mode 100644 index ac6af96a82f3208980f80e07d488a02761ede1a5..0000000000000000000000000000000000000000 --- a/arch/arc/plat-sim/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# - -menuconfig ARC_PLAT_SIM - bool "ARC nSIM based simulation virtual platforms" - help - Support for nSIM based ARC simulation platforms - This includes the standalone nSIM (uart only) vs. System C OSCI VP diff --git a/arch/arc/plat-sim/platform.c b/arch/arc/plat-sim/platform.c index aea87389e44bd517b196ec87de0edb4c0216b4b1..5cda56b1a2ead7bc54ca1ac63296fcd1f54fc43f 100644 --- a/arch/arc/plat-sim/platform.c +++ b/arch/arc/plat-sim/platform.c @@ -20,11 +20,14 @@ */ static const char *simulation_compat[] __initconst = { +#ifdef CONFIG_ISA_ARCOMPACT "snps,nsim", - "snps,nsim_hs", "snps,nsimosci", +#else + "snps,nsim_hs", "snps,nsimosci_hs", "snps,zebu_hs", +#endif NULL, }; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a208bfe367b55574e2ca4a901de8b3a2862aee2e..7888c9803eb00b3ad1d166923182d5d1f4294bda 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -50,7 +50,7 @@ config ARM select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) select HAVE_ARCH_TRACEHOOK select HAVE_ARM_SMCCC if CPU_V7 - select HAVE_CBPF_JIT + select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 select HAVE_CC_STACKPROTECTOR select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT @@ -380,7 +380,7 @@ config ARCH_EP93XX bool "EP93xx-based" select ARCH_HAS_HOLES_MEMORYMODEL select ARM_AMBA - select ARM_PATCH_PHYS_VIRT + imply ARM_PATCH_PHYS_VIRT select ARM_VIC select AUTO_ZRELADDR select CLKDEV_LOOKUP @@ -1531,7 +1531,6 @@ config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K default y if CPU_THUMBONLY - select AEABI select ARM_ASM_UNIFIED select ARM_UNWIND help @@ -1594,7 +1593,8 @@ config ARM_PATCH_IDIV code to do integer division. config AEABI - bool "Use the ARM EABI to compile the kernel" + bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && !CPU_V7M && !CPU_V6 && !CPU_V6K + default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K help This option allows for the kernel to be compiled using the latest ARM ABI (aka EABI). This is only useful if you are using a user diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 447629d89884fd1ed600227a676b339fd9c256e1..6dcea8e8e941eabe79790f97e3e8f69ccd3220e9 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -646,7 +646,7 @@ choice config DEBUG_OMAP2UART1 bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 help This covers at least h4, 2430sdp, 3430sdp, 3630sdp, omap3 torpedo and 3530 lv som. @@ -654,17 +654,17 @@ choice config DEBUG_OMAP2UART2 bool "Kernel low-level debugging messages via OMAP2/3/4 UART2" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP2UART3 bool "Kernel low-level debugging messages via OMAP2 UART3 (n8x0)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP3UART3 bool "Kernel low-level debugging messages via OMAP3 UART3 (most omap3 boards)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 help This covers at least cm_t3x, beagle, crane, devkit8000, igep00x0, ldp, n900, n9(50), pandora, overo, touchbook, @@ -673,17 +673,17 @@ choice config DEBUG_OMAP4UART3 bool "Kernel low-level debugging messages via OMAP4/5 UART3 (omap4 blaze, panda, omap5 sevm)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP3UART4 bool "Kernel low-level debugging messages via OMAP36XX UART4" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP4UART4 bool "Kernel low-level debugging messages via OMAP4/5 UART4" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP7XXUART1 bool "Kernel low-level debugging via OMAP730 UART1" @@ -712,22 +712,22 @@ choice config DEBUG_TI81XXUART1 bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_TI81XXUART2 bool "Kernel low-level debugging messages via TI81XX UART2" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_TI81XXUART3 bool "Kernel low-level debugging messages via TI81XX UART3 (ti8168evm)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_AM33XXUART1 bool "Kernel low-level debugging messages via AM33XX UART1" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_ZOOM_UART bool "Kernel low-level debugging messages via Zoom2/3 UART" @@ -896,12 +896,13 @@ choice via SCIF2 on Renesas R-Car H1 (R8A7779). config DEBUG_RCAR_GEN2_SCIF0 - bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7792/R8A7793" - depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7792 || ARCH_R8A7793 + bool "Kernel low-level debugging messages via SCIF0 on R-Car Gen2 and RZ/G1" + depends on ARCH_R8A7743 || ARCH_R8A7790 || ARCH_R8A7791 || \ + ARCH_R8A7792 || ARCH_R8A7793 help Say Y here if you want kernel low-level debugging support - via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), V2H - (R8A7792), or M2-N (R8A7793). + via SCIF0 on Renesas RZ/G1M (R8A7743), R-Car H2 (R8A7790), + M2-W (R8A7791), V2H (R8A7792), or M2-N (R8A7793). config DEBUG_RCAR_GEN2_SCIF2 bool "Kernel low-level debugging messages via SCIF2 on R8A7794" @@ -1523,6 +1524,17 @@ config DEBUG_UART_PHYS default 0x40090000 if DEBUG_LPC32XX default 0x40100000 if DEBUG_PXA_UART1 default 0x42000000 if DEBUG_GEMINI + default 0x44e09000 if DEBUG_AM33XXUART1 + default 0x48020000 if DEBUG_OMAP4UART3 || DEBUG_TI81XXUART1 + default 0x48022000 if DEBUG_TI81XXUART2 + default 0x48024000 if DEBUG_TI81XXUART3 + default 0x4806a000 if DEBUG_OMAP2UART1 || DEBUG_OMAP3UART1 || \ + DEBUG_OMAP4UART1 || DEBUG_OMAP5UART1 + default 0x4806c000 if DEBUG_OMAP2UART2 || DEBUG_OMAP3UART2 || \ + DEBUG_OMAP4UART2 || DEBUG_OMAP5UART2 + default 0x4806e000 if DEBUG_OMAP2UART3 || DEBUG_OMAP4UART4 + default 0x49020000 if DEBUG_OMAP3UART3 + default 0x49042000 if DEBUG_OMAP3UART4 default 0x50000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ DEBUG_S3C2410_UART0) default 0x50004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \ @@ -1641,10 +1653,21 @@ config DEBUG_UART_VIRT default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 default 0xf8ffee00 if DEBUG_AT91_SAM9263_DBGU default 0xf8fff200 if DEBUG_AT91_RM9200_DBGU + default 0xf9e09000 if DEBUG_AM33XXUART1 + default 0xfa020000 if DEBUG_OMAP4UART3 || DEBUG_TI81XXUART1 + default 0xfa022000 if DEBUG_TI81XXUART2 + default 0xfa024000 if DEBUG_TI81XXUART3 + default 0xfa06a000 if DEBUG_OMAP2UART1 || DEBUG_OMAP3UART1 || \ + DEBUG_OMAP4UART1 || DEBUG_OMAP5UART1 + default 0xfa06c000 if DEBUG_OMAP2UART2 || DEBUG_OMAP3UART2 || \ + DEBUG_OMAP4UART2 || DEBUG_OMAP5UART2 + default 0xfa06e000 if DEBUG_OMAP2UART3 || DEBUG_OMAP4UART4 default 0xfa71e000 if DEBUG_QCOM_UARTDM default 0xfb002000 if DEBUG_CNS3XXX default 0xfb009000 if DEBUG_REALVIEW_STD_PORT default 0xfb00c000 if DEBUG_AT91_SAMA5D4_USART3 + default 0xfb020000 if DEBUG_OMAP3UART3 + default 0xfb042000 if DEBUG_OMAP3UART4 default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT default 0xfc705000 if DEBUG_ZTE_ZX default 0xfcfe8600 if DEBUG_BCM63XX_UART diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S index a17ca8d78656d1012910ffb8a37b3433720a8d44..c94a88ae834dc3b28418279e188fdbfb8ac7da2c 100644 --- a/arch/arm/boot/compressed/efi-header.S +++ b/arch/arm/boot/compressed/efi-header.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2015 Linaro Ltd + * Copyright (C) 2013-2017 Linaro Ltd * Authors: Roy Franz * Ard Biesheuvel * @@ -8,6 +8,9 @@ * published by the Free Software Foundation. */ +#include +#include + .macro __nop #ifdef CONFIG_EFI_STUB @ This is almost but not quite a NOP, since it does clobber the @@ -15,7 +18,7 @@ @ PE/COFF expects the magic string "MZ" at offset 0, while the @ ARM/Linux boot protocol expects an executable instruction @ there. - .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000 + .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000 #else AR_CLASS( mov r0, r0 ) M_CLASS( nop.w ) @@ -34,96 +37,97 @@ @ The only 2 fields of the MSDOS header that are used are this @ PE/COFF offset, and the "MZ" bytes at offset 0x0. @ - .long pe_header - start @ Offset to the PE header. + .long pe_header - start @ Offset to the PE header. pe_header: - .ascii "PE\0\0" + .long PE_MAGIC coff_header: - .short 0x01c2 @ ARM or Thumb - .short 2 @ nr_sections - .long 0 @ TimeDateStamp - .long 0 @ PointerToSymbolTable - .long 1 @ NumberOfSymbols - .short section_table - optional_header - @ SizeOfOptionalHeader - .short 0x306 @ Characteristics. - @ IMAGE_FILE_32BIT_MACHINE | - @ IMAGE_FILE_DEBUG_STRIPPED | - @ IMAGE_FILE_EXECUTABLE_IMAGE | - @ IMAGE_FILE_LINE_NUMS_STRIPPED + .short IMAGE_FILE_MACHINE_THUMB @ Machine + .short section_count @ NumberOfSections + .long 0 @ TimeDateStamp + .long 0 @ PointerToSymbolTable + .long 0 @ NumberOfSymbols + .short section_table - optional_header @ SizeOfOptionalHeader + .short IMAGE_FILE_32BIT_MACHINE | \ + IMAGE_FILE_DEBUG_STRIPPED | \ + IMAGE_FILE_EXECUTABLE_IMAGE | \ + IMAGE_FILE_LINE_NUMS_STRIPPED @ Characteristics + +#define __pecoff_code_size (__pecoff_data_start - __efi_start) optional_header: - .short 0x10b @ PE32 format - .byte 0x02 @ MajorLinkerVersion - .byte 0x14 @ MinorLinkerVersion - .long _end - __efi_start @ SizeOfCode - .long 0 @ SizeOfInitializedData - .long 0 @ SizeOfUninitializedData - .long efi_stub_entry - start @ AddressOfEntryPoint - .long start_offset @ BaseOfCode - .long 0 @ data + .short PE_OPT_MAGIC_PE32 @ PE32 format + .byte 0x02 @ MajorLinkerVersion + .byte 0x14 @ MinorLinkerVersion + .long __pecoff_code_size @ SizeOfCode + .long __pecoff_data_size @ SizeOfInitializedData + .long 0 @ SizeOfUninitializedData + .long efi_stub_entry - start @ AddressOfEntryPoint + .long start_offset @ BaseOfCode + .long __pecoff_data_start - start @ BaseOfData extra_header_fields: - .long 0 @ ImageBase - .long 0x200 @ SectionAlignment - .long 0x200 @ FileAlignment - .short 0 @ MajorOperatingSystemVersion - .short 0 @ MinorOperatingSystemVersion - .short 0 @ MajorImageVersion - .short 0 @ MinorImageVersion - .short 0 @ MajorSubsystemVersion - .short 0 @ MinorSubsystemVersion - .long 0 @ Win32VersionValue + .long 0 @ ImageBase + .long SZ_4K @ SectionAlignment + .long SZ_512 @ FileAlignment + .short 0 @ MajorOsVersion + .short 0 @ MinorOsVersion + .short 0 @ MajorImageVersion + .short 0 @ MinorImageVersion + .short 0 @ MajorSubsystemVersion + .short 0 @ MinorSubsystemVersion + .long 0 @ Win32VersionValue - .long _end - start @ SizeOfImage - .long start_offset @ SizeOfHeaders - .long 0 @ CheckSum - .short 0xa @ Subsystem (EFI application) - .short 0 @ DllCharacteristics - .long 0 @ SizeOfStackReserve - .long 0 @ SizeOfStackCommit - .long 0 @ SizeOfHeapReserve - .long 0 @ SizeOfHeapCommit - .long 0 @ LoaderFlags - .long 0x6 @ NumberOfRvaAndSizes + .long __pecoff_end - start @ SizeOfImage + .long start_offset @ SizeOfHeaders + .long 0 @ CheckSum + .short IMAGE_SUBSYSTEM_EFI_APPLICATION @ Subsystem + .short 0 @ DllCharacteristics + .long 0 @ SizeOfStackReserve + .long 0 @ SizeOfStackCommit + .long 0 @ SizeOfHeapReserve + .long 0 @ SizeOfHeapCommit + .long 0 @ LoaderFlags + .long (section_table - .) / 8 @ NumberOfRvaAndSizes - .quad 0 @ ExportTable - .quad 0 @ ImportTable - .quad 0 @ ResourceTable - .quad 0 @ ExceptionTable - .quad 0 @ CertificationTable - .quad 0 @ BaseRelocationTable + .quad 0 @ ExportTable + .quad 0 @ ImportTable + .quad 0 @ ResourceTable + .quad 0 @ ExceptionTable + .quad 0 @ CertificationTable + .quad 0 @ BaseRelocationTable section_table: - @ - @ The EFI application loader requires a relocation section - @ because EFI applications must be relocatable. This is a - @ dummy section as far as we are concerned. - @ - .ascii ".reloc\0\0" - .long 0 @ VirtualSize - .long 0 @ VirtualAddress - .long 0 @ SizeOfRawData - .long 0 @ PointerToRawData - .long 0 @ PointerToRelocations - .long 0 @ PointerToLineNumbers - .short 0 @ NumberOfRelocations - .short 0 @ NumberOfLineNumbers - .long 0x42100040 @ Characteristics - .ascii ".text\0\0\0" - .long _end - __efi_start @ VirtualSize - .long __efi_start @ VirtualAddress - .long _edata - __efi_start @ SizeOfRawData - .long __efi_start @ PointerToRawData - .long 0 @ PointerToRelocations - .long 0 @ PointerToLineNumbers - .short 0 @ NumberOfRelocations - .short 0 @ NumberOfLineNumbers - .long 0xe0500020 @ Characteristics + .long __pecoff_code_size @ VirtualSize + .long __efi_start @ VirtualAddress + .long __pecoff_code_size @ SizeOfRawData + .long __efi_start @ PointerToRawData + .long 0 @ PointerToRelocations + .long 0 @ PointerToLineNumbers + .short 0 @ NumberOfRelocations + .short 0 @ NumberOfLineNumbers + .long IMAGE_SCN_CNT_CODE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE @ Characteristics + + .ascii ".data\0\0\0" + .long __pecoff_data_size @ VirtualSize + .long __pecoff_data_start - start @ VirtualAddress + .long __pecoff_data_rawsize @ SizeOfRawData + .long __pecoff_data_start - start @ PointerToRawData + .long 0 @ PointerToRelocations + .long 0 @ PointerToLineNumbers + .short 0 @ NumberOfRelocations + .short 0 @ NumberOfLineNumbers + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE @ Characteristics + + .set section_count, (. - section_table) / 40 - .align 9 + .align 12 __efi_start: #endif .endm diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S index 81c493156ce87e12a4719268076c861da18e7a53..7a4c59154361d00ee88c2d03cb6af5aa8cace7e7 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.S +++ b/arch/arm/boot/compressed/vmlinux.lds.S @@ -48,13 +48,6 @@ SECTIONS *(.rodata) *(.rodata.*) } - .data : { - /* - * The EFI stub always executes from RAM, and runs strictly before the - * decompressor, so we can make an exception for its r/w data, and keep it - */ - *(.data.efistub) - } .piggydata : { *(.piggydata) } @@ -70,6 +63,26 @@ SECTIONS /* ensure the zImage file size is always a multiple of 64 bits */ /* (without a dummy byte, ld just ignores the empty section) */ .pad : { BYTE(0); . = ALIGN(8); } + +#ifdef CONFIG_EFI_STUB + .data : ALIGN(4096) { + __pecoff_data_start = .; + /* + * The EFI stub always executes from RAM, and runs strictly before the + * decompressor, so we can make an exception for its r/w data, and keep it + */ + *(.data.efistub) + __pecoff_data_end = .; + + /* + * PE/COFF mandates a file size which is a multiple of 512 bytes if the + * section size equals or exceeds 4 KB + */ + . = ALIGN(512); + } + __pecoff_data_rawsize = . - ADDR(.data); +#endif + _edata = .; _magic_sig = ZIMAGE_MAGIC(0x016f2818); @@ -84,6 +97,9 @@ SECTIONS . = ALIGN(8); /* the stack must be 64-bit aligned */ .stack : { *(.stack) } + PROVIDE(__pecoff_data_size = ALIGN(512) - ADDR(.data)); + PROVIDE(__pecoff_end = ALIGN(512)); + .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4b17f35dc9a7167bcce9b5c9c9b35b7375add15c..faf46abaa4a2773721a0c30b012a2ae52308daae 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -46,6 +46,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \ at91sam9x35ek.dtb dtb-$(CONFIG_SOC_SAM_V7) += \ at91-kizbox2.dtb \ + at91-sama5d27_som1_ek.dtb \ at91-sama5d2_xplained.dtb \ at91-sama5d3_xplained.dtb \ at91-tse850-3.dtb \ @@ -73,7 +74,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2835-rpi-a-plus.dtb \ bcm2836-rpi-2-b.dtb \ bcm2837-rpi-3-b.dtb \ - bcm2835-rpi-zero.dtb + bcm2835-rpi-zero.dtb \ + bcm2835-rpi-zero-w.dtb dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm4708-asus-rt-ac56u.dtb \ bcm4708-asus-rt-ac68u.dtb \ @@ -106,7 +108,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm953012hr.dtb \ bcm953012k.dtb dtb-$(CONFIG_ARCH_BCM_53573) += \ - bcm47189-tenda-ac9.dtb + bcm47189-tenda-ac9.dtb \ + bcm947189acdbmr.dtb dtb-$(CONFIG_ARCH_BCM_63XX) += \ bcm963138dvt.dtb dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \ @@ -180,6 +183,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \ exynos5440-ssdk5440.dtb \ exynos5800-peach-pi.dtb dtb-$(CONFIG_ARCH_GEMINI) += \ + gemini-dlink-dir-685.dtb \ gemini-nas4220b.dtb \ gemini-rut1xx.dtb \ gemini-sq201.dtb \ @@ -340,6 +344,7 @@ dtb-$(CONFIG_SOC_IMX51) += \ imx51-ts4800.dtb dtb-$(CONFIG_SOC_IMX53) += \ imx53-ard.dtb \ + imx53-cx9020.dtb \ imx53-m53evk.dtb \ imx53-mba53.dtb \ imx53-qsb.dtb \ @@ -391,7 +396,9 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-udoo.dtb \ imx6dl-wandboard.dtb \ imx6dl-wandboard-revb1.dtb \ + imx6q-apalis-eval.dtb \ imx6q-apalis-ixora.dtb \ + imx6q-apalis-ixora-v1.1.dtb \ imx6q-apf6dev.dtb \ imx6q-arm2.dtb \ imx6q-b450v3.dtb \ @@ -466,7 +473,7 @@ dtb-$(CONFIG_SOC_IMX6SX) += \ imx6sx-udoo-neo-full.dtb dtb-$(CONFIG_SOC_IMX6UL) += \ imx6ul-14x14-evk.dtb \ - imx6ul-geam-kit.dtb \ + imx6ul-geam.dtb \ imx6ul-isiot-emmc.dtb \ imx6ul-isiot-nand.dtb \ imx6ul-liteboard.dtb \ @@ -617,6 +624,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \ am335x-evmsk.dtb \ am335x-icev2.dtb \ am335x-lxm.dtb \ + am335x-moxa-uc-8100-me-t.dtb \ am335x-nano.dtb \ am335x-pepper.dtb \ am335x-phycore-rdk.dtb \ @@ -650,6 +658,7 @@ dtb-$(CONFIG_SOC_OMAP5) += \ dtb-$(CONFIG_SOC_DRA7XX) += \ am57xx-beagle-x15.dtb \ am57xx-beagle-x15-revb1.dtb \ + am57xx-beagle-x15-revc.dtb \ am57xx-cl-som-am57x.dtb \ am57xx-sbc-am57x.dtb \ am572x-idk.dtb \ @@ -657,7 +666,8 @@ dtb-$(CONFIG_SOC_DRA7XX) += \ dra7-evm.dtb \ dra72-evm.dtb \ dra72-evm-revc.dtb \ - dra71-evm.dtb + dra71-evm.dtb \ + dra76-evm.dtb dtb-$(CONFIG_ARCH_ORION5X) += \ orion5x-kuroboxpro.dtb \ orion5x-lacie-d2-network.dtb \ @@ -903,6 +913,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb \ sun8i-a83t-allwinner-h8homlet-v2.dtb \ + sun8i-a83t-bananapi-m3.dtb \ sun8i-a83t-cubietruck-plus.dtb \ sun8i-h2-plus-orangepi-zero.dtb \ sun8i-h3-bananapi-m2-plus.dtb \ @@ -918,6 +929,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-h3-orangepi-pc-plus.dtb \ sun8i-h3-orangepi-plus.dtb \ sun8i-h3-orangepi-plus2e.dtb \ + sun8i-r16-bananapi-m2m.dtb \ sun8i-r16-parrot.dtb \ sun8i-v3s-licheepi-zero.dtb \ sun8i-v3s-licheepi-zero-dock.dtb @@ -970,7 +982,6 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-pro4-sanji.dtb \ uniphier-pxs2-gentil.dtb \ uniphier-pxs2-vodka.dtb \ - uniphier-sld3-ref.dtb \ uniphier-sld8-ref.dtb dtb-$(CONFIG_ARCH_VERSATILE) += \ versatile-ab.dtb \ @@ -1049,7 +1060,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt6580-evbp1.dtb \ mt6589-aquaris5.dtb \ mt6592-evb.dtb \ - mt7623-evb.dtb \ + mt7623n-rfb-nand.dtb \ + mt7623n-bananapi-bpi-r2.dtb \ mt8127-moose.dtb \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 1d154444dfef245bf60e6336da038d1ff766512e..48a15fc641f22e40301c505625fc331efc4610e9 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -319,13 +319,10 @@ ti,pmic-shutdown-controller; charger { - interrupts = <0>, <1>; - interrupt-names = "USB", "AC"; status = "okay"; }; pwrbutton { - interrupts = <2>; status = "okay"; }; diff --git a/arch/arm/boot/dts/am335x-chiliboard.dts b/arch/arm/boot/dts/am335x-chiliboard.dts index d8769799772ea6cdacb0693427648cf61e0f0879..59431b23594489dd3f211c0be1a93c031d3c0c46 100644 --- a/arch/arm/boot/dts/am335x-chiliboard.dts +++ b/arch/arm/boot/dts/am335x-chiliboard.dts @@ -191,13 +191,10 @@ interrupts = <7>; /* NNMI */ charger { - interrupts = <0>, <1>; - interrupt-names = "USB", "AC"; status = "okay"; }; pwrbutton { - interrupts = <2>; status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 1c37a7c1ea17dd76fc2686c1bd9dd17acc250d99..ddd897556e035b6306306ca33eccc65c7ed45e3b 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -531,6 +531,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <8>; diff --git a/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts b/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts new file mode 100644 index 0000000000000000000000000000000000000000..f82233cd18e0bf5b7ddd9c673a15bd28dd7d1994 --- /dev/null +++ b/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2017 MOXA Inc. - https://www.moxa.com/ + * + * Author: SZ Lin (林上智) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/dts-v1/; + +#include "am33xx.dtsi" + +/ { + model = "Moxa UC-8100-ME-T"; + compatible = "moxa,uc-8100-me-t", "ti,am33xx"; + + cpus { + cpu@0 { + cpu0-supply = <&vdd1_reg>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + + vbat: vbat-regulator { + compatible = "regulator-fixed"; + }; + + /* Power supply provides a fixed 3.3V @3A */ + vmmcsd_fixed: vmmcsd-regulator { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + leds { + compatible = "gpio-leds"; + led1 { + label = "uc8100me:CEL1"; + gpios = <&gpio_xten 8 0>; + default-state = "off"; + }; + + led2 { + label = "uc8100me:CEL2"; + gpios = <&gpio_xten 9 0>; + default-state = "off"; + }; + + led3 { + label = "uc8100me:CEL3"; + gpios = <&gpio_xten 10 0>; + default-state = "off"; + }; + + led4 { + label = "uc8100me:DIA1"; + gpios = <&gpio_xten 11 0>; + default-state = "off"; + }; + led5 { + label = "uc8100me:DIA2"; + gpios = <&gpio_xten 12 0>; + default-state = "off"; + }; + led6 { + label = "uc8100me:DIA3"; + gpios = <&gpio_xten 13 0>; + default-state = "off"; + }; + led7 { + label = "uc8100me:SD"; + gpios = <&gpio_xten 14 0>; + default-state = "off"; + }; + led8 { + label = "uc8100me:USB"; + gpios = <&gpio_xten 15 0>; + default-state = "off"; + }; + led9 { + label = "uc8100me:USER"; + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + buttons: push_button { + compatible = "gpio-keys"; + }; + +}; + +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&minipcie_pins>; + + minipcie_pins: pinmux_minipcie { + pinctrl-single,pins = < + AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.gpio2_24 */ + AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_ac_bias_en.gpio2_25 */ + AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_vsync.gpio2_22 Power off PIN*/ + >; + }; + + push_button_pins: pinmux_push_button { + pinctrl-single,pins = < + AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahcklx.gpio3_21 */ + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x968, PIN_INPUT_PULLUP | MUX_MODE3) /* uart0_ctsn.i2c1_sda */ + AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE3) /* uart0_rtsn.i2c1_scl */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */ + AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */ + AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */ + AM33XX_IOPAD(0x984, PIN_OUTPUT | MUX_MODE0) /* uart1_txd.uart1_txd */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x8d8, PIN_INPUT | MUX_MODE6) /* lcd_data14.uart5_ctsn */ + AM33XX_IOPAD(0x8dc, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* lcd_data15.uart5_rtsn */ + AM33XX_IOPAD(0x8c4, PIN_INPUT_PULLUP | MUX_MODE4) /* lcd_data9.uart5_rxd */ + AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE4) /* lcd_data8.uart5_txd */ + >; + }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */ + AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */ + AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */ + AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */ + AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */ + AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */ + AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */ + AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mii1_refclk.rmii1_refclk */ + + /* Slave 2 */ + AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_crs_dv */ + AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rxer */ + AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_txen */ + AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td1 */ + AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td0 */ + AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd1 */ + AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd0 */ + AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii2_refclk */ + + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; + + mmc0_pins_default: pinmux_mmc0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3 */ + AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2 */ + AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1 */ + AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0 */ + AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk */ + AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd */ + AM33XX_IOPAD(0x990, PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkx.gpio3_14 */ + AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkx.gpio3_18 */ + >; + }; + + mmc2_pins_default: pinmux_mmc2_pins { + pinctrl-single,pins = < + /* eMMC */ + AM33XX_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad12.mmc2_dat0 */ + AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad13.mmc2_dat1 */ + AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad14.mmc2_dat2 */ + AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad15.mmc2_dat3 */ + AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad8.mmc2_dat4 */ + AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad9.mmc2_dat5 */ + AM33XX_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad10.mmc2_dat6 */ + AM33XX_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad11.mmc2_dat7 */ + AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd */ + AM33XX_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk */ + >; + }; + + spi0_pins: pinmux_spi0 { + pinctrl-single,pins = < + AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */ + AM33XX_IOPAD(0x95C, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */ + AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */ + AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */ + >; + }; + +}; + +&uart0 { + /* Console */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +}; + +&uart1 { + /* UART 1 setting */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart5 { + /* UART 2 setting */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tpm: tpm@20 { + compatible = "infineon,slb9645tt"; + reg = <0x20>; + }; + + tps: tps@2d { + compatible = "ti,tps65910"; + reg = <0x2d>; + }; + + eeprom: eeprom@50 { + compatible = "atmel,24c16"; + pagesize = <16>; + reg = <0x50>; + }; + + rtc_wdt: rtc_wdt@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + status = "okay"; + clock-frequency = <400000>; + gpio_xten: gpio_xten@27 { + compatible = "nxp,pca9535"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x27>; + }; +}; + +&usb { + status = "okay"; +}; + +&usb_ctrl_mod { + status = "okay"; +}; + +&usb0_phy { + status = "okay"; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&cppi41dma { + status = "okay"; +}; + +#include "tps65910.dtsi" + +&tps { + vcc1-supply = <&vbat>; + vcc2-supply = <&vbat>; + vcc3-supply = <&vbat>; + vcc4-supply = <&vbat>; + vcc5-supply = <&vbat>; + vcc6-supply = <&vbat>; + vcc7-supply = <&vbat>; + vccio-supply = <&vbat>; + + regulators { + vrtc_reg: regulator@0 { + regulator-always-on; + }; + + vio_reg: regulator@1 { + regulator-always-on; + }; + + vdd1_reg: regulator@2 { + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1378000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd2_reg: regulator@3 { + /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ + regulator-name = "vdd_core"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd3_reg: regulator@4 { + regulator-always-on; + }; + + vdig1_reg: regulator@5 { + regulator-always-on; + }; + + vdig2_reg: regulator@6 { + regulator-always-on; + }; + + vpll_reg: regulator@7 { + regulator-always-on; + }; + + vdac_reg: regulator@8 { + regulator-always-on; + }; + + vaux1_reg: regulator@9 { + regulator-always-on; + }; + + vaux2_reg: regulator@10 { + regulator-always-on; + }; + + vaux33_reg: regulator@11 { + regulator-always-on; + }; + + vmmc_reg: regulator@12 { + compatible = "regulator-fixed"; + regulator-name = "vmmc_reg"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +}; + +/* Power */ +&vbat { + regulator-name = "vbat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +}; + +&mac { + pinctrl-names = "default"; + pinctrl-0 = <&cpsw_default>; + dual_emac = <1>; + status = "okay"; +}; + +&davinci_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&davinci_mdio_default>; + status = "okay"; +}; + +&cpsw_emac0 { + status = "okay"; + phy_id = <&davinci_mdio>, <4>; + phy-mode = "rmii"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + status = "okay"; + phy_id = <&davinci_mdio>, <5>; + phy-mode = "rmii"; + dual_emac_res_vlan = <2>; +}; + +&phy_sel { + reg= <0x44e10650 0xf5>; + rmii-clock-ext; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&gpio0 { + ti,no-reset-on-init; +}; + +&mmc1 { + pinctrl-names = "default"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <4>; + pinctrl-0 = <&mmc0_pins_default>; + cd-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&mmc3 { + dmas = <&edma_xbar 12 0 1 + &edma_xbar 13 0 2>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <8>; + pinctrl-0 = <&mmc2_pins_default>; + ti,non-removable; + status = "okay"; +}; + +&buttons { + pinctrl-names = "default"; + pinctrl-0 = <&push_button_pins>; + #address-cells = <1>; + #size-cells = <0>; + + button@0 { + label = "push_button"; + linux,code = <0x100>; + gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; + }; +}; + +/* SPI Busses */ +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + + m25p80@0 { + compatible = "mx25l6405d"; + spi-max-frequency = <40000000>; + + reg = <0>; + spi-cpol; + spi-cpha; + #address-cells = <1>; + #size-cells = <1>; + + /* reg : The partition's offset and size within the mtd bank. */ + partitions@0 { + label = "MLO"; + reg = <0x0 0x80000>; + }; + + partitions@1 { + label = "U-Boot"; + reg = <0x80000 0x100000>; + }; + + partitions@2 { + label = "U-Boot Env"; + reg = <0x180000 0x20000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 7d7ca054c557b4b66e5da847c53e6c20fd36cd5b..e58fab8aec5df2a885ea8c04f9eefda09cf2d307 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -36,6 +36,8 @@ phy1 = &usb1_phy; ethernet0 = &cpsw_emac0; ethernet1 = &cpsw_emac1; + spi0 = &spi0; + spi1 = &spi1; }; cpus { diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index 29a538ecd405db81959e839768dc2731d10a63aa..afb8eb0a0a16ee63ea1ece64e694ac847c249067 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -149,6 +149,13 @@ system-clock-frequency = <12000000>; }; }; + + beeper: beeper { + compatible = "gpio-beeper"; + pinctrl-names = "default"; + pinctrl-0 = <&beeper_pins>; + gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; + }; }; &am43xx_pinmux { @@ -510,6 +517,13 @@ AM4372_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ >; }; + + beeper_pins: beeper_pins { + pinctrl-single,pins = < + AM4372_IOPAD(0x9e0, PIN_OUTPUT_PULLUP | MUX_MODE7) /* cam1_field.gpio4_12 */ + >; + }; + }; &uart0 { @@ -842,6 +856,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch16"; ti,elm-id = <&elm>; nand-bus-width = <8>; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 54f40f370011c211664a6583a845146b50b996af..081fa68b6f98049ad2edb1c9c6d579c0958a7a2d 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -388,6 +388,7 @@ pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; + slaves = <1>; }; &davinci_mdio { @@ -402,11 +403,6 @@ phy-mode = "rmii"; }; -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; - phy-mode = "rmii"; -}; - &phy_sel { rmii-clock-ext; }; @@ -564,6 +560,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch16"; ti,elm-id = <&elm>; nand-bus-width = <8>; diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts index 7b207835b2d161244fc8e09126fe384bf7eae9fa..debf9464403ef52a5c4b7e27135b1a5ed5778fd2 100644 --- a/arch/arm/boot/dts/am571x-idk.dts +++ b/arch/arm/boot/dts/am571x-idk.dts @@ -11,6 +11,7 @@ #include #include #include "am57xx-idk-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" / { model = "TI AM5718 IDK"; @@ -64,13 +65,6 @@ }; }; -&mmc1 { - status = "okay"; - vmmc-supply = <&ldo1_reg>; - bus-width = <4>; - cd-gpios = <&gpio6 27 0>; /* gpio 219 */ -}; - &omap_dwc3_2 { extcon = <&extcon_usb2>; }; @@ -96,3 +90,30 @@ status = "okay"; }; }; + +&pcie1_rc { + status = "okay"; + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; + +&pcie1_ep { + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; +}; diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts index 9da6d83ca185e52c79ea4ebd180fb1d21144280c..a578fe97ba3bd9ec210df3f1827cc936a748d2bd 100644 --- a/arch/arm/boot/dts/am572x-idk.dts +++ b/arch/arm/boot/dts/am572x-idk.dts @@ -12,6 +12,7 @@ #include #include #include "am57xx-idk-common.dtsi" +#include "dra74x-mmc-iodelay.dtsi" / { model = "TI AM5728 IDK"; @@ -67,6 +68,24 @@ }; }; +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20>; +}; + &omap_dwc3_2 { extcon = <&extcon_usb2>; }; @@ -76,19 +95,16 @@ vbus-gpio = <&gpio3 26 GPIO_ACTIVE_HIGH>; }; -&mmc1 { - status = "okay"; - vmmc-supply = <&v3_3d>; - vmmc_aux-supply = <&ldo1_reg>; - bus-width = <4>; - cd-gpios = <&gpio6 27 0>; /* gpio 219 */ -}; - &sn65hvs882 { load-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; }; -&pcie1 { +&pcie1_rc { + status = "okay"; + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; + +&pcie1_ep { gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; }; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi index fdfe5b16b806298a1aac3a136a873dfc2ab891df..49aeecd312b4b10af2cb3badd68a4982fa8a921d 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi +++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi @@ -9,6 +9,7 @@ #include "dra74x.dtsi" #include "am57xx-commercial-grade.dtsi" +#include "dra74x-mmc-iodelay.dtsi" #include #include @@ -166,34 +167,6 @@ }; }; -&dra7_pmx_core { - mmc1_pins_default: mmc1_pins_default { - pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */ - DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ - DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ - DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ - DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ - DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ - DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ - >; - }; - - mmc2_pins_default: mmc2_pins_default { - pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ - DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ - DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ - DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ - DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ - DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ - DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ - DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ - DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ - DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ - >; - }; -}; &i2c1 { status = "okay"; clock-frequency = <400000>; @@ -570,7 +543,12 @@ }; }; -&pcie1 { +&pcie1_rc { + status = "ok"; + gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; +}; + +&pcie1_ep { gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; }; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts b/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts index 39a92aff0a0dc5338d29c13949001e2558f17474..5a77b334923d051f6943730b8d51849fe6161596 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts @@ -19,8 +19,23 @@ }; &mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev11_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev11_conf>; vmmc-supply = <&vdd_3v3>; - vmmc-aux-supply = <&ldo1_reg>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_3_3v_rev11 &mmc2_iodelay_ddr_3_3v_rev11_conf>; }; /* errata i880 "Ethernet RGMII2 Limited to 10/100 Mbps" */ diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-revc.dts b/arch/arm/boot/dts/am57xx-beagle-x15-revc.dts new file mode 100644 index 0000000000000000000000000000000000000000..17c41da3b55f1c7d94460f98647f0fdb084a9dbe --- /dev/null +++ b/arch/arm/boot/dts/am57xx-beagle-x15-revc.dts @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "am57xx-beagle-x15-common.dtsi" + +/ { + model = "TI AM5728 BeagleBoard-X15 rev C"; +}; + +&tpd12s015 { + gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>, /* gpio7_10, CT CP HPD */ + <&gpio2 30 GPIO_ACTIVE_HIGH>, /* gpio2_30, LS OE */ + <&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */ +}; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; + vmmc-supply = <&vdd_3v3>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20>; +}; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 19a60a11c19890d49f608e12c4a4c3a5d3c822bc..d6689106d2a83935ea6ac98fd89f42ce06132879 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -20,9 +20,20 @@ }; &mmc1 { + pinctrl-names = "default", "hs"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + vmmc-supply = <&ldo1_reg>; }; +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_3_3v_rev11 &mmc2_iodelay_ddr_3_3v_rev11_conf>; +}; + /* errata i880 "Ethernet RGMII2 Limited to 10/100 Mbps" */ &phy1 { max-speed = <100>; diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi index c536b2f5389f2786930a48eb0f7446311c622121..97aa8e6a56da8f7c8722f5243e01fca0e944f629 100644 --- a/arch/arm/boot/dts/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi @@ -399,6 +399,14 @@ dr_mode = "peripheral"; }; +&mmc1 { + status = "okay"; + vmmc-supply = <&v3_3d>; + vqmmc-supply = <&ldo1_reg>; + bus-width = <4>; + cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */ +}; + &mmc2 { status = "okay"; vmmc-supply = <&v3_3d>; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index f9cf1273f35e0ae65dd4398037f9662bcf4ff28e..b1cf5a26f3c2a460b7b9d8fc41127c30cf2cc533 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -72,7 +72,7 @@ reg = ; }; - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -100,6 +100,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -117,6 +118,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 50c5e8417802cd42c3beee13bcf9a23b3a127791..7225c7ce9a8dbca5cb909c0c1b55376072c2e263 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -582,7 +582,7 @@ }; }; - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -610,6 +610,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -627,6 +628,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi index e392f6036f3956a7b2494d7fb502f5b5a3a99349..132596fd08603e68d458cb264ae23ca48c0c7929 100644 --- a/arch/arm/boot/dts/armada-380.dtsi +++ b/arch/arm/boot/dts/armada-380.dtsi @@ -71,7 +71,7 @@ }; }; - pcie-controller { + pcie { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -104,6 +104,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -122,6 +123,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <1>; @@ -140,6 +142,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <2>; diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index db5b9f6b615d8f8ea430f7ae790bc82858add8e8..25d2d720dc0e2cacc98b402e609e0fe78eb01acb 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -209,7 +209,7 @@ status = "okay"; }; - pcie-controller { + pcie { status = "okay"; /* diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts index be16ce39fb3d659f4833722063a26aa043bace11..06831e1e3f808b8419b299e72d8dfbd94568de3f 100644 --- a/arch/arm/boot/dts/armada-385-turris-omnia.dts +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts @@ -96,7 +96,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; pcie@1,0 { diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi index 7fcc4c4885cffa9b51fe8c1c9911e4ea3cfcc138..74863aff01c6e0259576403ae22ece1cc12a7d4d 100644 --- a/arch/arm/boot/dts/armada-385.dtsi +++ b/arch/arm/boot/dts/armada-385.dtsi @@ -70,7 +70,7 @@ }; soc { - pciec: pcie-controller { + pciec: pcie { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -109,6 +109,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -127,6 +128,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <1>; @@ -145,6 +147,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <2>; @@ -166,6 +169,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <3>; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts index 0d5f1f06227568389c072194bf7da8ae6957012d..ee7b0089eff035a7f0fda7ed43b6878183c6c53a 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dts +++ b/arch/arm/boot/dts/armada-388-clearfog.dts @@ -62,7 +62,7 @@ }; }; - pcie-controller { + pcie { pcie@3,0 { /* Port 2, Lane 0. CON2, nearest CPU. */ reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dtsi b/arch/arm/boot/dts/armada-388-clearfog.dtsi index 0f5938bede53c30ce84f24a9a9b733517cc52118..68acfc9687069bf141c01309608b8806920bb446 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dtsi +++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi @@ -104,7 +104,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* * The two PCIe units are accessible through diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts index 1ac923826445495edd6f725b44ce9c2134a5382f..a4ec1fa3752979fd30a1c9870a072d217c374b18 100644 --- a/arch/arm/boot/dts/armada-388-db.dts +++ b/arch/arm/boot/dts/armada-388-db.dts @@ -172,7 +172,7 @@ status = "okay"; }; - pcie-controller { + pcie { status = "okay"; /* * The two PCIe units are accessible through diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index 895fa6cfa15a9ee1c56c5827f5f5fe2f8e512196..f503955dbd3b810db157344e3f9cf48dadd4b1ca 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -75,7 +75,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pca0_pins>; interrupt-parent = <&gpio0>; - interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -87,7 +87,7 @@ compatible = "nxp,pca9555"; pinctrl-names = "default"; interrupt-parent = <&gpio0>; - interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -240,7 +240,7 @@ status = "okay"; }; - pcie-controller { + pcie { status = "okay"; /* * One PCIe units is accessible through diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts index af82f275eac248791a2286b49c87bfd7c536db08..9cc3ca0376b934e10c863735f3e9a14ee72c0ee1 100644 --- a/arch/arm/boot/dts/armada-388-rd.dts +++ b/arch/arm/boot/dts/armada-388-rd.dts @@ -117,7 +117,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* * One PCIe units is accessible through diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index af31f5d6c0e571f607fa47eb7aa00094d3ffdcb9..7ff0811e61db3ad73be8f0c9ea8f79ebde1681c7 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -154,6 +154,13 @@ reg = <0xc000 0x58>; }; + timer@c200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0xc200 0x20>; + interrupts = ; + clocks = <&coreclk 2>; + }; + timer@c600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xc600 0x20>; diff --git a/arch/arm/boot/dts/armada-390-db.dts b/arch/arm/boot/dts/armada-390-db.dts index 2afed2ce47412dce518785bdc1092c27b08766fb..c718a5242595f4157215ea476fccc998372bbccf 100644 --- a/arch/arm/boot/dts/armada-390-db.dts +++ b/arch/arm/boot/dts/armada-390-db.dts @@ -123,7 +123,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* CON30 */ diff --git a/arch/arm/boot/dts/armada-395-gp.dts b/arch/arm/boot/dts/armada-395-gp.dts index 2cdbba804c1eaedf2034902e038e1696850c42f3..ef491b524fd6c4c39b391d4c022210c4744f9e37 100644 --- a/arch/arm/boot/dts/armada-395-gp.dts +++ b/arch/arm/boot/dts/armada-395-gp.dts @@ -139,7 +139,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* diff --git a/arch/arm/boot/dts/armada-398-db.dts b/arch/arm/boot/dts/armada-398-db.dts index e8604281c3c9916522d496937c73c1b31c6f22c9..f0e0379f7619220d39defb0f72887623ba850768 100644 --- a/arch/arm/boot/dts/armada-398-db.dts +++ b/arch/arm/boot/dts/armada-398-db.dts @@ -118,7 +118,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; pcie@1,0 { diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi index 60fbfd5907c71049e75935cba303f795be38ad72..ea657071e27888c49294556e047f556d499f6300 100644 --- a/arch/arm/boot/dts/armada-39x.dtsi +++ b/arch/arm/boot/dts/armada-39x.dtsi @@ -442,7 +442,7 @@ }; }; - pcie-controller { + pcie { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -481,6 +481,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -499,6 +500,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <1>; @@ -517,6 +519,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <2>; @@ -538,6 +541,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <3>; diff --git a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi index be22ec5236acfe5f11626a7f50447944564fda60..bdd4c7a45fbf43995f899982c499d9e9c99da5c5 100644 --- a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi +++ b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi @@ -91,7 +91,7 @@ /* * 98DX3236 has 1 x1 PCIe unit Gen2.0 */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -116,6 +116,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index a33974254d8cddb36ee6538bc1eec767c0ce756d..065282c217897fdfdab6ecb0dd365614a6478468 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -242,7 +242,7 @@ /* Port 2, Lane 0 */ status = "okay"; }; - pcie@10,0 { + pcie@a,0 { /* Port 3, Lane 0 */ status = "okay"; }; diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index d62bf7bea1df4db579d8d22311d40ef8f0eaa25e..ac9eab8ac186c78ba88e0e03907f429886953e04 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -227,7 +227,7 @@ /* Port 2, Lane 0 */ status = "okay"; }; - pcie@10,0 { + pcie@a,0 { /* Port 3, Lane 0 */ status = "okay"; }; diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi index 9f25814077f2b446f9c54ab22ee277a10288fae6..129738f7973d4b4c90cdd79d14864b8e34de76db 100644 --- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -86,7 +86,7 @@ * configured as x4 or quad x1 lanes. One unit is * x1 only. */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -123,6 +123,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -140,6 +141,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -157,6 +159,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -174,6 +177,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -191,6 +195,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 2bfe07aebf1aefae7611c2b7899b824c1527306a..e58d597e37b98a414aa430f4d2635c90315b3a82 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -87,7 +87,7 @@ * configured as x4 or quad x1 lanes. One unit is * x4 only. */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -138,6 +138,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -155,6 +156,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -172,6 +174,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -189,6 +192,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -206,6 +210,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; @@ -223,6 +228,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 0x81000000 0 0 0x81000000 0x6 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 63>; marvell,pcie-port = <1>; @@ -240,6 +246,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 0x81000000 0 0 0x81000000 0x7 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 64>; marvell,pcie-port = <1>; @@ -257,6 +264,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 0x81000000 0 0 0x81000000 0x8 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 65>; marvell,pcie-port = <1>; @@ -274,6 +282,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 0x81000000 0 0 0x81000000 0x9 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 99>; marvell,pcie-port = <2>; diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi index 6c33935f7074730e193781173661ad717a202e32..a5c961cee7de3856d33046ca365d5d0f998d993c 100644 --- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -104,7 +104,7 @@ * configured as x4 or quad x1 lanes. Two units are * x4/x1. */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -159,6 +159,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -176,6 +177,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -193,6 +195,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -210,6 +213,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -227,6 +231,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; @@ -244,6 +249,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 0x81000000 0 0 0x81000000 0x6 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 63>; marvell,pcie-port = <1>; @@ -261,6 +267,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 0x81000000 0 0 0x81000000 0x7 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 64>; marvell,pcie-port = <1>; @@ -278,6 +285,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 0x81000000 0 0 0x81000000 0x8 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 65>; marvell,pcie-port = <1>; @@ -295,6 +303,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 0x81000000 0 0 0x81000000 0x9 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 99>; marvell,pcie-port = <2>; @@ -303,7 +312,7 @@ status = "disabled"; }; - pcie10: pcie@10,0 { + pcie10: pcie@a,0 { device_type = "pci"; assigned-addresses = <0x82005000 0 0x82000 0 0x2000>; reg = <0x5000 0 0 0 0>; @@ -312,6 +321,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0 0x81000000 0 0 0x81000000 0xa 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 103>; marvell,pcie-port = <3>; diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 8a04c7e2d8185c9a72ea7824785ac93009672561..22b958537d31ada6dac768be3de7e2eddf31bfdb 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -26,7 +26,7 @@ fmc: flash-controller@1e620000 { reg = < 0x1e620000 0x94 - 0x20000000 0x02000000 >; + 0x20000000 0x10000000 >; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2400-fmc"; @@ -41,7 +41,7 @@ spi: flash-controller@1e630000 { reg = < 0x1e630000 0x18 - 0x30000000 0x02000000 >; + 0x30000000 0x10000000 >; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2400-spi"; diff --git a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..63a5af8981659fb7f3162323be34e55dbcc345d6 --- /dev/null +++ b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi @@ -0,0 +1,102 @@ +/* + * at91-sama5d27_som1.dtsi - Device Tree file for SAMA5D27 SoM1 board + * + * Copyright (c) 2017, Microchip Technology Inc. + * 2017 Cristian Birsan + * 2017 Claudiu Beznea + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "sama5d2.dtsi" +#include "sama5d2-pinfunc.h" + +/ { + model = "Atmel SAMA5D27 SoM1"; + compatible = "atmel,sama5d27-som1", "atmel,sama5d27", "atmel,sama5d2", "atmel,sama5"; + + clocks { + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <24000000>; + }; + }; + + ahb { + apb { + macb0: ethernet@f8008000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_default>; + phy-mode = "rmii"; + + ethernet-phy@1 { + reg = <0x1>; + interrupt-parent = <&pioA>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_phy_irq>; + }; + }; + + pinctrl@fc038000 { + + pinctrl_macb0_default: macb0_default { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; + + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts new file mode 100644 index 0000000000000000000000000000000000000000..60cb084a8d927e40303a377a40fd283d2eb29f45 --- /dev/null +++ b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts @@ -0,0 +1,540 @@ +/* + * at91-sama5d27_som1_ek.dts - Device Tree file for SAMA5D27-SOM1-EK board + * + * Copyright (c) 2017, Microchip Technology Inc. + * 2016 Nicolas Ferre + * 2017 Cristian Birsan + * 2017 Claudiu Beznea + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/dts-v1/; +#include "at91-sama5d27_som1.dtsi" +#include +#include + +/ { + model = "Atmel SAMA5D27 SOM1 EK"; + compatible = "atmel,sama5d27-som1-ek", "atmel,sama5d27-som1", "atmel,sama5d27", "atmel,sama5d2", "atmel,sama5"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + ahb { + usb0: gadget@00300000 { + atmel,vbus-gpio = <&pioA PIN_PD20 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00400000 { + num-ports = <3>; + atmel,vbus-gpio = <0 /* &pioA PIN_PD20 GPIO_ACTIVE_HIGH */ + &pioA PIN_PA27 GPIO_ACTIVE_HIGH + 0 + >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; + status = "okay"; + }; + + usb2: ehci@00500000 { + status = "okay"; + }; + + sdmmc0: sdio-host@a0000000 { + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdmmc0_default>; + status = "okay"; + }; + + sdmmc1: sdio-host@b0000000 { + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdmmc1_default>; + status = "okay"; + }; + + apb { + isc: isc@f0008000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isc_base &pinctrl_isc_data_8bit &pinctrl_isc_data_9_10 &pinctrl_isc_data_11_12>; + status = "okay"; + }; + + spi0: spi@f8000000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0_default>; + status = "okay"; + }; + + macb0: ethernet@f8008000 { + status = "okay"; + }; + + uart1: serial@f8020000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "okay"; + }; + + uart2: serial@f8024000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus2_uart>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "okay"; + }; + + pwm0: pwm@f802c000 { + status = "okay"; + }; + + flx1: flexcom@f8038000 { + atmel,flexcom-mode = ; + status = "disabled"; + + i2c2: i2c@600 { + compatible = "atmel,sama5d2-i2c"; + reg = <0x600 0x200>; + interrupts = <20 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <0>, <0>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx1_clk>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus_i2c>; + atmel,fifo-size = <16>; + status = "disabled"; + }; + }; + + shdwc@f8048010 { + atmel,shdwc-debouncer = <976>; + atmel,wakeup-rtc-timer; + + input@0 { + reg = <0>; + atmel,wakeup-type = "low"; + }; + }; + + watchdog@f8048040 { + status = "okay"; + }; + + can0: can@f8054000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_default>; + }; + + uart3: serial@fc008000 { + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3_default>; + status = "disabled"; + }; + + uart4: serial@fc00c000 { + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus1_uart>; + status = "okay"; + }; + + flx3: flexcom@fc014000 { + atmel,flexcom-mode = ; + status = "disabled"; + + uart7: serial@200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0x200 0x200>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx3_clk>; + clock-names = "usart"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx3_default>; + atmel,fifo-size = <32>; + status = "disabled"; + }; + + spi2: spi@400 { + compatible = "atmel,at91rm9200-spi"; + reg = <0x400 0x200>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx3_clk>; + clock-names = "spi_clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx3_default>; + atmel,fifo-size = <16>; + status = "disabled"; + }; + }; + + flx4: flexcom@fc018000 { + atmel,flexcom-mode = ; + status = "okay"; + + uart6: serial@200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0x200 0x200>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx4_clk>; + clock-names = "usart"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx4_default>; + atmel,fifo-size = <32>; + status = "disabled"; + }; + + spi3: spi@400 { + compatible = "atmel,at91rm9200-spi"; + reg = <0x400 0x200>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx4_clk>; + clock-names = "spi_clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus_spi &pinctrl_mikrobus1_spi_cs &pinctrl_mikrobus2_spi_cs>; + atmel,fifo-size = <16>; + status = "okay"; + }; + + i2c3: i2c@600 { + compatible = "atmel,sama5d2-i2c"; + reg = <0x600 0x200>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <0>, <0>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx4_clk>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx4_default>; + atmel,fifo-size = <16>; + status = "disabled"; + }; + }; + + i2c1: i2c@fc028000 { + dmas = <0>, <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_default>; + status = "okay"; + }; + + pinctrl@fc038000 { + + pinctrl_can0_default: can0_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_can1_default: can1_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_flx3_default: flx3_default { + pinmux = , + , + , + , + ; + bias-disable; + }; + + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_isc_base: isc_base { + pinmux = , + , + , + ; + bias-disable; + }; + + pinctrl_isc_data_8bit: isc_data_8bit { + pinmux = , + , + , + , + , + , + , + ; + bias-disable; + }; + + pinctrl_isc_data_9_10: isc_data_9_10 { + pinmux = , + ; + bias-disable; + }; + + pinctrl_isc_data_11_12: isc_data_11_12 { + pinmux = , + ; + bias-disable; + }; + + pinctrl_key_gpio_default: key_gpio_default { + pinmux = ; + bias-pull-up; + }; + + pinctrl_led_gpio_default: led_gpio_default { + pinmux = , + , + ; + bias-pull-up; + }; + + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_data { + pinmux = , + , + , + , + , + , + , + , + ; + bias-pull-up; + }; + + ck_cd_vddsel { + pinmux = , + , + ; + bias-disable; + }; + }; + + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_data { + pinmux = , + , + , + , + ; + bias-pull-up; + }; + + conf-ck_cd { + pinmux = , + ; + bias-disable; + }; + }; + + pinctrl_spi0_default: spi0_default { + pinmux = , + , + , + ; + bias-disable; + }; + + pinctrl_uart1_default: uart1_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_uart3_default: uart3_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_usb_default: usb_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_an: mikrobus1_an { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_an: mikrobus2_an { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_rst: mikrobus1_rst { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_rst: mikrobus2_rst { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_spi_cs: mikrobus1_spi_cs { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_spi_cs: mikrobus2_spi_cs { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus_spi: mikrobus_spi { + pinmux = , + , + ; + bias-disable; + }; + + pinctrl_mikrobus1_pwm: mikrobus1_pwm { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_pwm: mikrobus2_pwm { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_int: mikrobus1_int { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_int: mikrobus2_int { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_uart: mikrobus1_uart { + pinmux = , + ; + bias-disable; + }; + + pinctrl_mikrobus2_uart: mikrobus2_uart { + pinmux = , + ; + bias-disable; + }; + + pinctrl_mikrobus_i2c: mikrobus1_i2c { + pinmux = , + ; + bias-disable; + }; + + pinctrl_flx4_default: flx4_uart_default { + pinmux = , + , + , + , + ; + bias-disable; + }; + }; + + can1: can@fc050000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1_default>; + status = "okay"; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio_default>; + + pb4 { + label = "USER"; + gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>; + linux,code = <0x104>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led_gpio_default>; + status = "okay"; + + red { + label = "red"; + gpios = <&pioA PIN_PA10 GPIO_ACTIVE_HIGH>; + }; + + green { + label = "green"; + gpios = <&pioA PIN_PB1 GPIO_ACTIVE_HIGH>; + }; + + blue { + label = "blue"; + gpios = <&pioA PIN_PA31 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 2e2c3d1a1fa28a36111ae9725b68c4120a1b0609..c7e9ccf2bc8724304f44c574bc901b3e9b3999af 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -68,7 +68,7 @@ ahb { usb0: gadget@00300000 { - atmel,vbus-gpio = <&pioA 31 GPIO_ACTIVE_HIGH>; + atmel,vbus-gpio = <&pioA PIN_PA31 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usba_vbus>; status = "okay"; @@ -76,8 +76,8 @@ usb1: ohci@00400000 { num-ports = <3>; - atmel,vbus-gpio = <0 /* &pioA 41 GPIO_ACTIVE_HIGH */ - &pioA 42 GPIO_ACTIVE_HIGH + atmel,vbus-gpio = <0 /* &pioA PIN_PB9 GPIO_ACTIVE_HIGH */ + &pioA PIN_PB10 GPIO_ACTIVE_HIGH 0 >; pinctrl-names = "default"; @@ -127,7 +127,7 @@ ethernet-phy@1 { reg = <0x1>; interrupt-parent = <&pioA>; - interrupts = <73 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; }; @@ -160,9 +160,9 @@ compatible = "active-semi,act8945a"; reg = <0x5b>; active-semi,vsel-high; - active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>; - active-semi,lbo-gpios = <&pioA 72 GPIO_ACTIVE_LOW>; - active-semi,irq_gpios = <&pioA 45 GPIO_ACTIVE_LOW>; + active-semi,chglev-gpios = <&pioA PIN_PA12 GPIO_ACTIVE_HIGH>; + active-semi,lbo-gpios = <&pioA PIN_PC8 GPIO_ACTIVE_LOW>; + active-semi,irq_gpios = <&pioA PIN_PB13 GPIO_ACTIVE_LOW>; active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,precondition-timeout = <40>; active-semi,total-timeout = <3>; @@ -355,6 +355,14 @@ bias-pull-up; }; + pinctrl_classd_default: classd_default { + pinmux = , + , + , + ; + bias-pull-up; + }; + pinctrl_flx0_default: flx0_default { pinmux = , ; @@ -488,6 +496,14 @@ }; + classd: classd@fc048000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_classd_default>; + atmel,pwm-type = "diff"; + atmel,non-overlap-time = <10>; + status = "okay"; + }; + can1: can@fc050000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_can1_default>; @@ -504,7 +520,7 @@ bp1 { label = "PB_USER"; - gpios = <&pioA 41 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB9 GPIO_ACTIVE_LOW>; linux,code = <0x104>; }; }; @@ -517,17 +533,18 @@ red { label = "red"; - gpios = <&pioA 38 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB6 GPIO_ACTIVE_LOW>; }; + green { label = "green"; - gpios = <&pioA 37 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB5 GPIO_ACTIVE_LOW>; }; blue { label = "blue"; - gpios = <&pioA 32 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB0 GPIO_ACTIVE_LOW>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index a4808c4fbc05897983df72024fc0f7667d75fbac..64fa3f9a39d3353ea18eb806a62b2498045a4d81 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -455,6 +455,16 @@ >; /* shared pinctrl settings */ + ac97 { + pinctrl_ac97: ac97-0 { + atmel,pins = + ; /* AC97CK */ + }; + }; + adc0 { pinctrl_adc0_adtrg: adc0_adtrg { atmel,pins = ; @@ -1043,6 +1053,17 @@ status = "disabled"; }; + ac97: sound@fffac000 { + compatible = "atmel,at91sam9263-ac97c"; + reg = <0xfffac000 0x4000>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ac97>; + clocks = <&ac97_clk>; + clock-names = "ac97_clk"; + status = "disabled"; + }; + adc0: adc@fffb0000 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 2522c330830561989dd31d985b1349cc50062d27..94c52c555f832d69cab669b64204f614fd00bced 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -166,6 +166,10 @@ status = "okay"; }; + ac97: sound@fffac000 { + status = "okay"; + }; + adc0: adc@fffb0000 { pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index bf8c838157539e697e3b5e875ac05f59325c3b3e..7c957ea06c66ce6b603277e452584dc8df05e5ef 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -55,6 +55,11 @@ /include/ "bcm-cygnus-clock.dtsi" + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = ; + }; + core { compatible = "simple-bus"; ranges = <0x00000000 0x19000000 0x1000000>; @@ -119,6 +124,21 @@ compatible = "brcm,cygnus-pinmux"; reg = <0x0301d0c8 0x30>, <0x0301d24c 0x2c>; + + spi_0: spi_0 { + function = "spi0"; + groups = "spi0_grp"; + }; + + spi_1: spi_1 { + function = "spi1"; + groups = "spi1_grp"; + }; + + spi_2: spi_2 { + function = "spi2"; + groups = "spi2_grp"; + }; }; mailbox: mailbox@03024024 { @@ -300,6 +320,23 @@ }; }; + dma0: dma@18018000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x18018000 0x1000>; + interrupts = , + , + , + , + , + , + , + , + ; + clocks = <&apb_clk>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + }; + uart0: serial@18020000 { compatible = "snps,dw-apb-uart"; reg = <0x18020000 0x100>; @@ -324,7 +361,7 @@ uart2: serial@18022000 { compatible = "snps,dw-apb-uart"; - reg = <0x18020000 0x100>; + reg = <0x18022000 0x100>; reg-shift = <2>; reg-io-width = <4>; interrupts = ; @@ -344,6 +381,52 @@ status = "disabled"; }; + spi0: spi@18028000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x18028000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + pinctrl-0 = <&spi_0>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + spi1: spi@18029000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x18029000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + pinctrl-0 = <&spi_1>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + spi2: spi@1802a000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x1802a000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + pinctrl-0 = <&spi_2>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + sdhci0: sdhci@18041000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x18041000 0x100>; + interrupts = ; + clocks = <&lcpll0 BCM_CYGNUS_LCPLL0_SDIO_CLK>; + bus-width = <4>; + sdhci,auto-cmd12; + status = "disabled"; + }; + eth0: ethernet@18042000 { compatible = "brcm,amac"; reg = <0x18042000 0x1000>, @@ -353,6 +436,16 @@ status = "disabled"; }; + sdhci1: sdhci@18043000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x18043000 0x100>; + interrupts = ; + clocks = <&lcpll0 BCM_CYGNUS_LCPLL0_SDIO_CLK>; + bus-width = <4>; + sdhci,auto-cmd12; + status = "disabled"; + }; + nand: nand@18046000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x18046000 0x600>, <0xf8105408 0x600>, @@ -366,6 +459,33 @@ brcm,nand-has-wp; }; + ehci0: usb@18048000 { + compatible = "generic-ehci"; + reg = <0x18048000 0x100>; + interrupts = ; + status = "disabled"; + }; + + ohci0: usb@18048800 { + compatible = "generic-ohci"; + reg = <0x18048800 0x100>; + interrupts = ; + status = "disabled"; + }; + + v3d: v3d@180a2000 { + compatible = "brcm,cygnus-v3d"; + reg = <0x180a2000 0x1000>; + clocks = <&mipipll BCM_CYGNUS_MIPIPLL_CH2_V3D>; + clock-names = "v3d_clk"; + interrupts = ; + status = "disabled"; + }; + + vc4: gpu { + compatible = "brcm,cygnus-vc4"; + }; + gpio_asiu: gpio@180a5000 { compatible = "brcm,cygnus-asiu-gpio"; reg = <0x180a5000 0x668>; @@ -444,19 +564,6 @@ status = "disabled"; }; - v3d: v3d@180a2000 { - compatible = "brcm,cygnus-v3d"; - reg = <0x180a2000 0x1000>; - clocks = <&mipipll BCM_CYGNUS_MIPIPLL_CH2_V3D>; - clock-names = "v3d_clk"; - interrupts = ; - status = "disabled"; - }; - - vc4: gpu { - compatible = "brcm,cygnus-vc4"; - }; - adc: adc@180a6000 { compatible = "brcm,iproc-static-adc"; #io-channel-cells = <1>; @@ -467,5 +574,19 @@ interrupts = ; status = "disabled"; }; + + keypad: keypad@180ac000 { + compatible = "brcm,bcm-keypad"; + reg = <0x180ac000 0x14c>; + interrupts = ; + clocks = <&asiu_clks BCM_CYGNUS_ASIU_KEYPAD_CLK>; + clock-names = "peri_clk"; + clock-frequency = <31250>; + pull-up-enabled; + col-debounce-filter-period = <0>; + status-debounce-filter-period = <0>; + row-output-enabled; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index 7204d1def23df1c5712bc9a559a599392ffef4b7..dff66974feeda575c06f38c38ddff3e4ecdf41ce 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -215,6 +215,7 @@ interrupts = ; sdhci,auto-cmd12; clocks = <&lcpll0 BCM_NSP_LCPLL0_SDIO_CLK>; + dma-coherent; status = "disabled"; }; @@ -224,6 +225,7 @@ <0x110000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; + dma-coherent; status = "disabled"; }; @@ -233,6 +235,7 @@ <0x111000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; + dma-coherent; status = "disabled"; }; @@ -242,6 +245,7 @@ <0x112000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; + dma-coherent; status = "disabled"; }; @@ -252,6 +256,7 @@ #mbox-cells = <1>; brcm,rx-status-len = <32>; brcm,use-bcm-hdr; + dma-coherent; }; nand: nand@26000 { @@ -297,6 +302,32 @@ #size-cells = <0>; }; + xhci: usb@29000 { + compatible = "generic-xhci"; + reg = <0x29000 0x1000>; + interrupts = ; + phys = <&usb3_phy>; + phy-names = "usb3-phy"; + dma-coherent; + status = "disabled"; + }; + + ehci0: usb@2a000 { + compatible = "generic-ehci"; + reg = <0x2a000 0x100>; + interrupts = ; + dma-coherent; + status = "disabled"; + }; + + ohci0: usb@2b000 { + compatible = "generic-ohci"; + reg = <0x2b000 0x100>; + interrupts = ; + dma-coherent; + status = "disabled"; + }; + crypto@2f000 { compatible = "brcm,spum-nsp-crypto"; reg = <0x2f000 0x900>; @@ -321,20 +352,6 @@ status = "disabled"; }; - ehci0: usb@2a000 { - compatible = "generic-ehci"; - reg = <0x2a000 0x100>; - interrupts = ; - status = "disabled"; - }; - - ohci0: usb@2b000 { - compatible = "generic-ohci"; - reg = <0x2b000 0x100>; - interrupts = ; - status = "disabled"; - }; - rng: rng@33000 { compatible = "brcm,bcm-nsp-rng"; reg = <0x33000 0x14>; @@ -376,6 +393,7 @@ #size-cells = <0>; interrupts = ; clock-frequency = <100000>; + dma-coherent; status = "disabled"; }; @@ -446,6 +464,7 @@ interrupts = ; #address-cells = <1>; #size-cells = <0>; + dma-coherent; status = "disabled"; sata0: sata-port@0 { @@ -460,6 +479,15 @@ phy-names = "sata-phy"; }; }; + + usb3_phy: usb3-phy@104000 { + compatible = "brcm,ns-bx-usb3-phy"; + reg = <0x104000 0x1000>, + <0x032000 0x1000>; + reg-names = "dmp", "ccb-mii"; + #phy-cells = <0>; + status = "disabled"; + }; }; pcie0: pcie@18012000 { @@ -483,6 +511,7 @@ */ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x8000000>; + dma-coherent; status = "disabled"; msi-parent = <&msi0>; @@ -519,6 +548,7 @@ */ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x8000000>; + dma-coherent; status = "disabled"; msi-parent = <&msi1>; @@ -555,6 +585,7 @@ */ ranges = <0x82000000 0 0x48000000 0x48000000 0 0x8000000>; + dma-coherent; status = "disabled"; msi-parent = <&msi2>; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts index d0704540db6b3cc136bd92dfb3038077d8083312..9f866491efdf5ac6c3bad1f785a9837fce33073c 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts @@ -99,3 +99,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts index 46d078e29017eeda2ea5d92c6d0c21d1ce9deccd..4b1af06c8dc03157113781ab27e9085346cd59d9 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-a.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts @@ -94,3 +94,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts index 432088ebb0a19a97e5390a3c90f88af9f796476d..a846f1e781d8a30e2e0afeaed5e67c32005f9b97 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts @@ -101,3 +101,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts index 4133bc2cd9be309a3885e6d002b767fe2c4d0458..e860964e39fa9ce61fee3f858924019df37fdf81 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts @@ -94,3 +94,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts index 4d56fe3006b0c38b652d88b36af09306ea455b2e..5d77f3f8c4c58475fcf5948af3d5815f7b6cd728 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts @@ -89,3 +89,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts new file mode 100644 index 0000000000000000000000000000000000000000..82651c3eb682a749652a31eadbb4f910961151f7 --- /dev/null +++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2017 Stefan Wahren + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "bcm2835.dtsi" +#include "bcm2835-rpi.dtsi" +#include "bcm283x-rpi-usb-host.dtsi" + +/ { + compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; + model = "Raspberry Pi Zero W"; + + /* Needed by firmware to properly init UARTs */ + aliases { + uart0 = "/soc/serial@7e201000"; + uart1 = "/soc/serial@7e215040"; + serial0 = "/soc/serial@7e201000"; + serial1 = "/soc/serial@7e215040"; + }; + + leds { + act { + gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + }; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wl_on>; + reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>; + }; +}; + +&gpio { + /* + * This is based on the official GPU firmware DT blob. + * + * Legend: + * "NC" = not connected (no rail from the SoC) + * "FOO" = GPIO line named "FOO" on the schematic + * "FOO_N" = GPIO line named "FOO" on schematic, active low + */ + gpio-line-names = "GPIO0", + "GPIO1", + "SDA1", + "SCL1", + "GPIO_GCLK", + "GPIO5", + "GPIO6", + "SPI_CE1_N", + "SPI_CE0_N", + "SPI_MISO", + "SPI_MOSI", + "SPI_SCLK", + "GPIO12", + "GPIO13", + /* Serial port */ + "TXD0", + "RXD0", + "GPIO16", + "GPIO17", + "GPIO18", + "GPIO19", + "GPIO20", + "GPIO21", + "GPIO22", + "GPIO23", + "GPIO24", + "GPIO25", + "GPIO26", + "GPIO27", + "SDA0", + "SCL0", + "NC", /* GPIO30 */ + "NC", /* GPIO31 */ + "NC", /* GPIO32 */ + "NC", /* GPIO33 */ + "NC", /* GPIO34 */ + "NC", /* GPIO35 */ + "NC", /* GPIO36 */ + "NC", /* GPIO37 */ + "NC", /* GPIO38 */ + "NC", /* GPIO39 */ + "CAM_GPIO1", /* GPIO40 */ + "WL_ON", /* GPIO41 */ + "NC", /* GPIO42 */ + "WIFI_CLK", /* GPIO43 */ + "CAM_GPIO0", /* GPIO44 */ + "BT_ON", /* GPIO45 */ + "HDMI_HPD_N", + "STATUS_LED_N", + /* Used by SD Card */ + "SD_CLK_R", + "SD_CMD_R", + "SD_DATA0_R", + "SD_DATA1_R", + "SD_DATA2_R", + "SD_DATA3_R"; + + pinctrl-0 = <&gpioout &alt0>; + + wl_on: wl-on { + brcm,pins = <41>; + brcm,function = ; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; +}; + +&sdhci { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>; + mmc-pwrseq = <&wifi_pwrseq>; + non-removable; + status = "okay"; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero.dts b/arch/arm/boot/dts/bcm2835-rpi-zero.dts index 79a20d5209310b2cfd912a9dbf1e67bc5b804b4d..70362405c59522fb7835a7b4b13ebb43592edfc4 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-zero.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-zero.dts @@ -103,3 +103,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index e55b362b9d6e92124a22d6e5718adf1f63be3818..e36c392a2b8fdfe36dab81b0128e85dfd422ab7b 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -39,7 +39,7 @@ }; alt0: alt0 { - brcm,pins = <4 5 7 8 9 10 11 14 15>; + brcm,pins = <4 5 7 8 9 10 11>; brcm,function = ; }; }; diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts index bf19e8cfb9e63cc9cd0a1c26e69a286b9a3c4bdf..e8de41444b68eed33efa16e92ddf29e3ace5fd1c 100644 --- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts @@ -39,3 +39,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi index da3deeb42592926f36b49770b50b549abcb6ece7..2c26d0be8b0316792188890ed677e87fc1fb13ea 100644 --- a/arch/arm/boot/dts/bcm2836.dtsi +++ b/arch/arm/boot/dts/bcm2836.dtsi @@ -36,6 +36,7 @@ cpus: cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "brcm,bcm2836-smp"; v7_cpu0: cpu@0 { device_type = "cpu"; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts index c72a27d908b6f191b6be47c305221b2ee242e3be..20725ca487f30afd5e84059fbcb1513d3399cfa8 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -1 +1,51 @@ -#include "arm64/broadcom/bcm2837-rpi-3-b.dts" +/dts-v1/; +#include "bcm2837.dtsi" +#include "bcm2835-rpi.dtsi" +#include "bcm283x-rpi-smsc9514.dtsi" +#include "bcm283x-rpi-usb-host.dtsi" + +/ { + compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B"; + + memory { + reg = <0 0x40000000>; + }; + + leds { + act { + gpios = <&gpio 47 0>; + }; + }; +}; + +/* uart0 communicates with the BT module */ +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio32 &gpclk2_gpio43>; + status = "okay"; +}; + +/* uart1 is mapped to the pin header */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_gpio14>; + status = "okay"; +}; + +/* SDHCI is used to control the SDIO for wireless */ +&sdhci { + pinctrl-names = "default"; + pinctrl-0 = <&emmc_gpio34>; + status = "okay"; + bus-width = <4>; + non-removable; +}; + +/* SDHOST is used to drive the SD card */ +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + status = "okay"; + bus-width = <4>; +}; diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi similarity index 96% rename from arch/arm64/boot/dts/broadcom/bcm2837.dtsi rename to arch/arm/boot/dts/bcm2837.dtsi index 2d5de6f0f78d5be78559477f18f0940bba3e5a15..bc1cca5cf43c41b8dad3902ce1a627b625883cb3 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi +++ b/arch/arm/boot/dts/bcm2837.dtsi @@ -30,6 +30,7 @@ cpus: cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit cpu0: cpu@0 { device_type = "cpu"; diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts index 62e1427b3f1076072301e14b6c26aead71235bd4..8b64caabaad8401876706da9b2ebf521b3401e6c 100644 --- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts +++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts @@ -52,6 +52,10 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&hc595 0 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>, <&ohci_port2>, + <&ehci_port2>; + linux,default-trigger = "usbport"; }; power0 { diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts index a5647efe41187eaa2e0dc70d9bfc125856562f45..d7c34fa72b4b7525303ba5e06b93e0c9c00b4b82 100644 --- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts +++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts @@ -48,6 +48,9 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; wireless { diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts index 19ee924d7d53fa0c1b86bbbbf0d3787ea8a0bbfa..83a4c60bb431233a715140e46db00548f1ce0a7d 100644 --- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts +++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts @@ -42,16 +42,22 @@ usb2 { label = "bcm53xx:white:usb2"; gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port2>, <&ehci_port2>; + linux,default-trigger = "usbport"; }; usb3-white { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; + trigger-sources = <&xhci_port1>; + linux,default-trigger = "usbport"; }; usb3-green { label = "bcm53xx:green:usb3"; gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; }; wps { diff --git a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts index a854a5174b7fd95e3ca00d585a7b0f630ead2981..3ed8de42cb4877bb78f022efd470640b43cef18f 100644 --- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts +++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts @@ -36,6 +36,8 @@ usb2-port1 { label = "bcm53xx:green:usb2-port1"; gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; }; power { @@ -67,6 +69,8 @@ usb2-port2 { label = "bcm53xx:green:usb2-port2"; gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port2>, <&ehci_port2>; + linux,default-trigger = "usbport"; }; }; diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts index 97aa5d59a1d805f155846fad9fec15deaf6765b0..ec4a50e440f6bc4e831be87c2c5b848070925d26 100644 --- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts +++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts @@ -46,11 +46,16 @@ usb3 { label = "bcm53xx:blue:usb3"; gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; usb2 { label = "bcm53xx:blue:usb2"; gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port2>, <&ehci_port2>; + linux,default-trigger = "usbport"; }; wan-blue { diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts index 51b0641b5f79c9f0a2cff8e1a9b94233d2fc4dac..7cc7d344fe5b69fd4699b946c5f62961dd2a9450 100644 --- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts +++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts @@ -71,6 +71,9 @@ usb3-white { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; 2ghz { diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts index 5f8621d00c5003282eaf68608ab24d3c02d5b94e..bc1d1e10d4acc460f76953bc36d033b6610e567d 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts @@ -59,6 +59,9 @@ usb3 { label = "bcm53xx:green:usb3"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; status { diff --git a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts index 34417dac1cd0937292469da3b86b54f2e8cfff1c..19e61b5b066c574d8ee464a6fe91d564c1436e86 100644 --- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts +++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts @@ -26,6 +26,8 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; }; wps { diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index 98647d22b291f100399290adf1d2ed67b31fe0e7..045b9bb857f9a030491bc3bdbf82ae67bb841b73 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -272,6 +272,19 @@ reg = <0x00021000 0x1000>; interrupts = ; phys = <&usb2_phy>; + + #address-cells = <1>; + #size-cells = <0>; + + ehci_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + + ehci_port2: port@2 { + reg = <2>; + #trigger-source-cells = <0>; + }; }; ohci: ohci@22000 { @@ -280,6 +293,19 @@ compatible = "generic-ohci"; reg = <0x00022000 0x1000>; interrupts = ; + + #address-cells = <1>; + #size-cells = <0>; + + ohci_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + + ohci_port2: port@2 { + reg = <2>; + #trigger-source-cells = <0>; + }; }; }; @@ -300,6 +326,14 @@ interrupts = ; phys = <&usb3_phy>; phy-names = "usb"; + + #address-cells = <1>; + #size-cells = <0>; + + xhci_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi index eae623f7640138abb794f52cfc2604321947308e..c698a565b8ae9e2134c36fc796e983159b686a67 100644 --- a/arch/arm/boot/dts/bcm53573.dtsi +++ b/arch/arm/boot/dts/bcm53573.dtsi @@ -138,10 +138,12 @@ ehci_port1: port@1 { reg = <1>; + #trigger-source-cells = <0>; }; ehci_port2: port@2 { reg = <2>; + #trigger-source-cells = <0>; }; }; @@ -158,10 +160,12 @@ ohci_port1: port@1 { reg = <1>; + #trigger-source-cells = <0>; }; ohci_port2: port@2 { reg = <2>; + #trigger-source-cells = <0>; }; }; }; diff --git a/arch/arm/boot/dts/bcm911360_entphn.dts b/arch/arm/boot/dts/bcm911360_entphn.dts index 000f5f19215e0cef9adea11ead762a3e027d5ed7..53f990defd6ae9f7af35eac9e1a04a16ae47c048 100644 --- a/arch/arm/boot/dts/bcm911360_entphn.dts +++ b/arch/arm/boot/dts/bcm911360_entphn.dts @@ -39,9 +39,12 @@ model = "Cygnus Enterprise Phone (BCM911360_ENTPHN)"; compatible = "brcm,bcm11360", "brcm,cygnus"; + aliases { + serial0 = &uart3; + }; + chosen { - stdout-path = &uart3; - bootargs = "console=ttyS0,115200"; + stdout-path = "serial0:115200n8"; }; gpio_keys { diff --git a/arch/arm/boot/dts/bcm947189acdbmr.dts b/arch/arm/boot/dts/bcm947189acdbmr.dts new file mode 100644 index 0000000000000000000000000000000000000000..ef263412fea513068a67a11ef80dff18d863802a --- /dev/null +++ b/arch/arm/boot/dts/bcm947189acdbmr.dts @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 Broadcom + * Author: Florian Fainelli + * + * Licensed under the ISC license. + */ + +/dts-v1/; + +#include "bcm53573.dtsi" + +/ { + compatible = "brcm,bcm947189acdbmr", "brcm,bcm47189", "brcm,bcm53573"; + model = "Broadcom BCM947189ACDBMR"; + + chosen { + bootargs = "console=ttyS0,115200 earlycon"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + leds { + compatible = "gpio-leds"; + + wps { + label = "bcm53xx:blue:wps"; + gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>; + }; + + 5ghz { + label = "bcm53xx:blue:5ghz"; + gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>; + }; + + 2ghz { + label = "bcm53xx:blue:2ghz"; + gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>; + }; + }; + + spi { + compatible = "spi-gpio"; + num-chipselects = <1>; + gpio-sck = <&chipcommon 21 0>; + gpio-miso = <&chipcommon 22 0>; + gpio-mosi = <&chipcommon 23 0>; + cs-gpios = <&chipcommon 24 0>; + #address-cells = <1>; + #size-cells = <0>; + + /* External BCM6802 MoCA chip is connected */ + }; +}; + +&pcie0 { + ranges = <0x00000000 0 0 0 0 0x00100000>; + #address-cells = <3>; + #size-cells = <2>; + + bridge@0,0,0 { + reg = <0x0000 0 0 0 0>; + ranges = <0x00000000 0 0 0 0 0 0 0x00100000>; + #address-cells = <3>; + #size-cells = <2>; + + wifi@0,1,0 { + reg = <0x0000 0 0 0 0>; + ranges = <0x00000000 0 0 0 0x00100000>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; +}; + +&usb2 { + vcc-gpio = <&chipcommon 8 GPIO_ACTIVE_HIGH>; +}; diff --git a/arch/arm/boot/dts/bcm958522er.dts b/arch/arm/boot/dts/bcm958522er.dts index f5c42962c20131dcb1c3bdeef6614c5a36456c36..f9dd342cc2ae499340529c4e842a0da6a1a133b6 100644 --- a/arch/arm/boot/dts/bcm958522er.dts +++ b/arch/arm/boot/dts/bcm958522er.dts @@ -170,3 +170,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958525er.dts b/arch/arm/boot/dts/bcm958525er.dts index efcb1f67bdadf7abcb71f625ec7a12aec56e4d9d..374508a9cfbfb2820d503c65cfa527066163034c 100644 --- a/arch/arm/boot/dts/bcm958525er.dts +++ b/arch/arm/boot/dts/bcm958525er.dts @@ -182,3 +182,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958525xmc.dts b/arch/arm/boot/dts/bcm958525xmc.dts index b335ce02e32f9cdda5282cd5180121daa33ea457..403250c5ad8e7b462198185a5add47b2b611e068 100644 --- a/arch/arm/boot/dts/bcm958525xmc.dts +++ b/arch/arm/boot/dts/bcm958525xmc.dts @@ -202,3 +202,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958622hr.dts b/arch/arm/boot/dts/bcm958622hr.dts index 16ab2d82a14ba63bf98577786b844795e8a02ed9..fd8b8c689ffe99f3421ae6f02b1a46a2ee3c3b72 100644 --- a/arch/arm/boot/dts/bcm958622hr.dts +++ b/arch/arm/boot/dts/bcm958622hr.dts @@ -219,3 +219,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts index 9b921c6aa8f8de19807c9a29d8f72eb404af6a49..3bc50849d013ff0442f559dce24274972202f5f2 100644 --- a/arch/arm/boot/dts/bcm958623hr.dts +++ b/arch/arm/boot/dts/bcm958623hr.dts @@ -227,3 +227,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts index 006b08e41a3ba0187412c99108e707df11380dd5..d94d14b3c745a0d01c031b6d9b9e6426e0e7b2ec 100644 --- a/arch/arm/boot/dts/bcm958625hr.dts +++ b/arch/arm/boot/dts/bcm958625hr.dts @@ -229,3 +229,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts index 64740f85cf4c906a9ea1d9397087c1515e3024db..2cf2392483b2af6269093f6edaf842bb4e12e776 100644 --- a/arch/arm/boot/dts/bcm958625k.dts +++ b/arch/arm/boot/dts/bcm958625k.dts @@ -264,3 +264,11 @@ &uart1 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts index a423e8ebfb3758057d41a4e9f77505df5dc1d783..c75507922f7d7998ee0e45bb875b8b6495b3d8d7 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -15,6 +15,13 @@ compatible = "ti,da850-evm", "ti,da850"; model = "DA850/AM1808/OMAP-L138 EVM"; + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + ethernet0 = ð0; + }; + soc@1c00000 { pmx_core: pinmux@14120 { status = "okay"; @@ -301,25 +308,4 @@ pinctrl-names = "default"; pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>; status = "okay"; - - /* VPIF capture port */ - port@0 { - vpif_input_ch0: endpoint@0 { - reg = <0>; - bus-width = <8>; - }; - - vpif_input_ch1: endpoint@1 { - reg = <1>; - bus-width = <8>; - data-shift = <8>; - }; - }; - - /* VPIF display port */ - port@1 { - vpif_output_ch0: endpoint { - bus-width = <8>; - }; - }; }; diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts index b837fec70eec8cb7d241d14559c8fad9c0cbb909..a0f0916156e66d83949716c4b571184695fbef3b 100644 --- a/arch/arm/boot/dts/da850-lcdk.dts +++ b/arch/arm/boot/dts/da850-lcdk.dts @@ -318,11 +318,4 @@ pinctrl-names = "default"; pinctrl-0 = <&vpif_capture_pins>; status = "okay"; - - /* VPIF capture port */ - port { - vpif_ch0: endpoint { - bus-width = <8>; - }; - }; }; diff --git a/arch/arm/boot/dts/da850-lego-ev3.dts b/arch/arm/boot/dts/da850-lego-ev3.dts index 45983c04a8a71e7967fb99b54e1a02a8602080d0..413dbd5d9f6442b8dae4b7f132b35e5f816cf798 100644 --- a/arch/arm/boot/dts/da850-lego-ev3.dts +++ b/arch/arm/boot/dts/da850-lego-ev3.dts @@ -249,6 +249,15 @@ 0x4c 0x00000080 0x000000f0 >; }; + + ev3_lcd_pins: pinmux_lcd { + pinctrl-single,bits = < + /* SIMO, GP2[11], GP2[12], CLK */ + 0x14 0x00188100 0x00ffff00 + /* GP5[0] */ + 0x30 0x80000000 0xf0000000 + >; + }; }; &pinconf { @@ -357,6 +366,21 @@ }; }; +&spi1 { + status = "okay"; + pinctrl-0 = <&ev3_lcd_pins>; + pinctrl-names = "default"; + cs-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + + display@0{ + compatible = "lego,ev3-lcd"; + reg = <0>; + spi-max-frequency = <10000000>; + a0-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; + }; +}; + &ehrpwm0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts index 1865976db5f9a3e11aad03cdd951d2f3af83c78d..c72a2132aa823b053c5ab9450a92faf266c85878 100644 --- a/arch/arm/boot/dts/dm8168-evm.dts +++ b/arch/arm/boot/dts/dm8168-evm.dts @@ -68,6 +68,34 @@ DM816X_IOPAD(0x0d08, MUX_MODE0) /* USB1_DRVVBUS */ >; }; + + nandflash_pins: nandflash_pins { + pinctrl-single,pins = < + DM816X_IOPAD(0x0b38, PULL_UP | MUX_MODE0) /* PINCTRL207 GPMC_CS0*/ + DM816X_IOPAD(0x0b60, PULL_ENA | MUX_MODE0) /* PINCTRL217 GPMC_ADV_ALE */ + DM816X_IOPAD(0x0b54, PULL_UP | PULL_ENA | MUX_MODE0) /* PINCTRL214 GPMC_OE_RE */ + DM816X_IOPAD(0x0b58, PULL_ENA | MUX_MODE0) /* PINCTRL215 GPMC_BE0_CLE */ + DM816X_IOPAD(0x0b50, PULL_UP | MUX_MODE0) /* PINCTRL213 GPMC_WE */ + DM816X_IOPAD(0x0b6c, MUX_MODE0) /* PINCTRL220 GPMC_WAIT */ + DM816X_IOPAD(0x0be4, PULL_ENA | MUX_MODE0) /* PINCTRL250 GPMC_CLK */ + DM816X_IOPAD(0x0ba4, MUX_MODE0) /* PINCTRL234 GPMC_D0 */ + DM816X_IOPAD(0x0ba8, MUX_MODE0) /* PINCTRL234 GPMC_D1 */ + DM816X_IOPAD(0x0bac, MUX_MODE0) /* PINCTRL234 GPMC_D2 */ + DM816X_IOPAD(0x0bb0, MUX_MODE0) /* PINCTRL234 GPMC_D3 */ + DM816X_IOPAD(0x0bb4, MUX_MODE0) /* PINCTRL234 GPMC_D4 */ + DM816X_IOPAD(0x0bb8, MUX_MODE0) /* PINCTRL234 GPMC_D5 */ + DM816X_IOPAD(0x0bbc, MUX_MODE0) /* PINCTRL234 GPMC_D6 */ + DM816X_IOPAD(0x0bc0, MUX_MODE0) /* PINCTRL234 GPMC_D7 */ + DM816X_IOPAD(0x0bc4, MUX_MODE0) /* PINCTRL234 GPMC_D8 */ + DM816X_IOPAD(0x0bc8, MUX_MODE0) /* PINCTRL234 GPMC_D9 */ + DM816X_IOPAD(0x0bcc, MUX_MODE0) /* PINCTRL234 GPMC_D10 */ + DM816X_IOPAD(0x0bd0, MUX_MODE0) /* PINCTRL234 GPMC_D11 */ + DM816X_IOPAD(0x0bd4, MUX_MODE0) /* PINCTRL234 GPMC_D12 */ + DM816X_IOPAD(0x0bd8, MUX_MODE0) /* PINCTRL234 GPMC_D13 */ + DM816X_IOPAD(0x0bdc, MUX_MODE0) /* PINCTRL234 GPMC_D14 */ + DM816X_IOPAD(0x0be0, MUX_MODE0) /* PINCTRL234 GPMC_D15 */ + >; + }; }; &i2c1 { @@ -90,6 +118,8 @@ &gpmc { ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */ + pinctrl-names = "default"; + pinctrl-0 = <&nandflash_pins>; nand@0,0 { compatible = "ti,omap2-nand"; @@ -98,9 +128,11 @@ interrupt-parent = <&gpmc>; interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ + rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ #address-cells = <1>; #size-cells = <1>; ti,nand-ecc-opt = "bch8"; + ti,elm-id = <&elm>; nand-bus-width = <16>; gpmc,device-width = <2>; gpmc,sync-clk-ps = <0>; @@ -164,7 +196,7 @@ vmmc-supply = <&vmmcsd_fixed>; bus-width = <4>; cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; }; /* At least dm8168-evm rev c won't support multipoint, later may */ diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index 59cbf958fcc3178c4b56aad647c340e40a63c098..566b2a8c8b96853da331571c233dc786d8adc187 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi @@ -145,7 +145,7 @@ }; elm: elm@48080000 { - compatible = "ti,816-elm"; + compatible = "ti,am3352-elm"; ti,hwmods = "elm"; reg = <0x48080000 0x2000>; interrupts = <4>; diff --git a/arch/arm/boot/dts/dove-d3plug.dts b/arch/arm/boot/dts/dove-d3plug.dts index f5f59bb5a53464eb9bcaeb7d035a28236790abc1..e88ff83f1dec8eb6a67332aedbb4e46cd4c4d957 100644 --- a/arch/arm/boot/dts/dove-d3plug.dts +++ b/arch/arm/boot/dts/dove-d3plug.dts @@ -88,7 +88,7 @@ &pcie { status = "okay"; /* Fresco Logic USB3.0 xHCI controller */ - pcie-port@0 { + pcie@1 { status = "okay"; reset-gpios = <&gpio0 26 1>; reset-delay-us = <20000>; @@ -96,7 +96,7 @@ pinctrl-names = "default"; }; /* Mini-PCIe slot */ - pcie-port@1 { + pcie@2 { status = "okay"; reset-gpios = <&gpio0 25 1>; }; diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 698d58cea20d2e8c1a3c7d8e7a4dadb717847624..1475d3672e56343e286f0883efbf1ed49fdb2e72 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi @@ -89,7 +89,7 @@ MBUS_ID(0x03, 0x01) 0 0xc8000000 0x0100000 /* CESA SRAM 1M */ MBUS_ID(0x0d, 0x00) 0 0xf0000000 0x0100000>; /* PMU SRAM 1M */ - pcie: pcie-controller { + pcie: pcie { compatible = "marvell,dove-pcie"; status = "disabled"; device_type = "pci"; @@ -106,7 +106,7 @@ 0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 Mem */ 0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */ - pcie0: pcie-port@0 { + pcie0: pcie@1 { device_type = "pci"; status = "disabled"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; @@ -118,13 +118,14 @@ #size-cells = <2>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 16>; }; - pcie1: pcie-port@1 { + pcie1: pcie@2 { device_type = "pci"; status = "disabled"; assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; @@ -136,6 +137,7 @@ #size-cells = <2>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; diff --git a/arch/arm/boot/dts/dra7-evm-common.dtsi b/arch/arm/boot/dts/dra7-evm-common.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..343e95f9a00144203b30e4e0beceee5e8bbbbbc7 --- /dev/null +++ b/arch/arm/boot/dts/dra7-evm-common.dtsi @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +/ { + chosen { + stdout-path = &uart1; + }; + + extcon_usb1: extcon_usb1 { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>; + }; + + sound0: sound0 { + compatible = "simple-audio-card"; + simple-audio-card,name = "DRA7xx-EVM"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line Out", + "Microphone", "Mic Jack", + "Line", "Line In"; + simple-audio-card,routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + simple-audio-card,format = "dsp_b"; + simple-audio-card,bitclock-master = <&sound0_master>; + simple-audio-card,frame-master = <&sound0_master>; + simple-audio-card,bitclock-inversion; + + sound0_master: simple-audio-card,cpu { + sound-dai = <&mcasp3>; + system-clock-frequency = <5644800>; + }; + + simple-audio-card,codec { + sound-dai = <&tlv320aic3106>; + clocks = <&atl_clkin2_ck>; + }; + }; + + leds { + compatible = "gpio-leds"; + led0 { + label = "dra7:usr1"; + gpios = <&pcf_lcd 4 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led1 { + label = "dra7:usr2"; + gpios = <&pcf_lcd 5 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led2 { + label = "dra7:usr3"; + gpios = <&pcf_lcd 6 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led3 { + label = "dra7:usr4"; + gpios = <&pcf_lcd 7 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + USER1 { + label = "btnUser1"; + linux,code = ; + gpios = <&pcf_lcd 2 GPIO_ACTIVE_LOW>; + }; + + USER2 { + label = "btnUser2"; + linux,code = ; + gpios = <&pcf_lcd 3 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c3 { + status = "okay"; + clock-frequency = <400000>; +}; + +&mcspi1 { + status = "okay"; +}; + +&mcspi2 { + status = "okay"; +}; + +&uart1 { + status = "okay"; + interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, + <&dra7_pmx_core 0x3e0>; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&qspi { + status = "okay"; + + spi-max-frequency = <76800000>; + m25p80@0 { + compatible = "s25fl256s1"; + spi-max-frequency = <76800000>; + reg = <0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + + /* MTD partition table. + * The ROM checks the first four physical blocks + * for a valid file to boot and the flash here is + * 64KiB block size. + */ + partition@0 { + label = "QSPI.SPL"; + reg = <0x00000000 0x000010000>; + }; + partition@1 { + label = "QSPI.SPL.backup1"; + reg = <0x00010000 0x00010000>; + }; + partition@2 { + label = "QSPI.SPL.backup2"; + reg = <0x00020000 0x00010000>; + }; + partition@3 { + label = "QSPI.SPL.backup3"; + reg = <0x00030000 0x00010000>; + }; + partition@4 { + label = "QSPI.u-boot"; + reg = <0x00040000 0x00100000>; + }; + partition@5 { + label = "QSPI.u-boot-spl-os"; + reg = <0x00140000 0x00080000>; + }; + partition@6 { + label = "QSPI.u-boot-env"; + reg = <0x001c0000 0x00010000>; + }; + partition@7 { + label = "QSPI.u-boot-env.backup1"; + reg = <0x001d0000 0x0010000>; + }; + partition@8 { + label = "QSPI.kernel"; + reg = <0x001e0000 0x0800000>; + }; + partition@9 { + label = "QSPI.file-system"; + reg = <0x009e0000 0x01620000>; + }; + }; +}; + +&omap_dwc3_1 { + extcon = <&extcon_usb1>; +}; + +&usb1 { + dr_mode = "otg"; + extcon = <&extcon_usb1>; +}; + +&usb2 { + dr_mode = "host"; +}; + +&atl { + assigned-clocks = <&abe_dpll_sys_clk_mux>, + <&atl_gfclk_mux>, + <&dpll_abe_ck>, + <&dpll_abe_m2x2_ck>, + <&atl_clkin2_ck>; + assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>; + assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>; + + status = "okay"; + + atl2 { + bws = ; + aws = ; + }; +}; + +&mcasp3 { + #sound-dai-cells = <0>; + + assigned-clocks = <&mcasp3_ahclkx_mux>; + assigned-clock-parents = <&atl_clkin2_ck>; + + status = "okay"; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 4 serializer */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 1 2 0 0 + >; + tx-num-evt = <32>; + rx-num-evt = <32>; +}; + +&mailbox5 { + status = "okay"; + mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + status = "okay"; + }; + mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + status = "okay"; + }; +}; + +&mailbox6 { + status = "okay"; + mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + status = "okay"; + }; + mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index f47fc4daf0628a43278a5dcb4cdcf81c34fc56c9..aa426dabb6c349d9f1b5a4a0173ae30ad3b7cc58 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -8,9 +8,8 @@ /dts-v1/; #include "dra74x.dtsi" -#include -#include -#include +#include "dra7-evm-common.dtsi" +#include "dra74x-mmc-iodelay.dtsi" / { model = "TI DRA742"; @@ -21,8 +20,12 @@ reg = <0x0 0x80000000 0x0 0x60000000>; /* 1536 MB */ }; - chosen { - stdout-path = &uart1; + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + vin-supply = <&smps9_reg>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; evm_3v3_sd: fixedregulator-sd { @@ -51,11 +54,6 @@ regulator-max-microvolt = <1800000>; }; - extcon_usb1: extcon_usb1 { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>; - }; - extcon_usb2: extcon_usb2 { compatible = "linux,extcon-usb-gpio"; id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>; @@ -73,85 +71,6 @@ gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>; }; - sound0: sound0 { - compatible = "simple-audio-card"; - simple-audio-card,name = "DRA7xx-EVM"; - simple-audio-card,widgets = - "Headphone", "Headphone Jack", - "Line", "Line Out", - "Microphone", "Mic Jack", - "Line", "Line In"; - simple-audio-card,routing = - "Headphone Jack", "HPLOUT", - "Headphone Jack", "HPROUT", - "Line Out", "LLOUT", - "Line Out", "RLOUT", - "MIC3L", "Mic Jack", - "MIC3R", "Mic Jack", - "Mic Jack", "Mic Bias", - "LINE1L", "Line In", - "LINE1R", "Line In"; - simple-audio-card,format = "dsp_b"; - simple-audio-card,bitclock-master = <&sound0_master>; - simple-audio-card,frame-master = <&sound0_master>; - simple-audio-card,bitclock-inversion; - - sound0_master: simple-audio-card,cpu { - sound-dai = <&mcasp3>; - system-clock-frequency = <5644800>; - }; - - simple-audio-card,codec { - sound-dai = <&tlv320aic3106>; - clocks = <&atl_clkin2_ck>; - }; - }; - - leds { - compatible = "gpio-leds"; - led0 { - label = "dra7:usr1"; - gpios = <&pcf_lcd 4 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led1 { - label = "dra7:usr2"; - gpios = <&pcf_lcd 5 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led2 { - label = "dra7:usr3"; - gpios = <&pcf_lcd 6 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led3 { - label = "dra7:usr4"; - gpios = <&pcf_lcd 7 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - autorepeat; - - USER1 { - label = "btnUser1"; - linux,code = ; - gpios = <&pcf_lcd 2 GPIO_ACTIVE_LOW>; - }; - - USER2 { - label = "btnUser2"; - linux,code = ; - gpios = <&pcf_lcd 3 GPIO_ACTIVE_LOW>; - }; - }; }; &dra7_pmx_core { @@ -406,137 +325,49 @@ }; }; -&i2c3 { - status = "okay"; - clock-frequency = <400000>; -}; - -&mcspi1 { - status = "okay"; -}; - -&mcspi2 { - status = "okay"; -}; - -&uart1 { - status = "okay"; - interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, - <&dra7_pmx_core 0x3e0>; -}; - -&uart2 { - status = "okay"; -}; - -&uart3 { - status = "okay"; -}; - &mmc1 { status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mmc1_pins_default>; vmmc-supply = <&evm_3v3_sd>; - vmmc_aux-supply = <&ldo1_reg>; + vqmmc-supply = <&ldo1_reg>; bus-width = <4>; /* * SDCD signal is not being used here - using the fact that GPIO mode * is always hardwired. */ cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50-rev11", "sdr104-rev11", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev11_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev11_conf>; + pinctrl-7 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>; + pinctrl-8 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; }; &mmc2 { status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mmc2_pins_default>; - vmmc-supply = <&evm_3v3_sw>; + vmmc-supply = <&evm_1v8_sw>; bus-width = <8>; + pinctrl-names = "default", "hs", "ddr_1_8v-rev11", "ddr_1_8v", "hs200_1_8v-rev11", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_1_8v_rev11 &mmc2_iodelay_ddr_1_8v_rev11_conf>; + pinctrl-3 = <&mmc2_pins_ddr_rev20>; + pinctrl-4 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev11_conf>; + pinctrl-5 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev20_conf>; }; &cpu0 { cpu0-supply = <&smps123_reg>; }; -&qspi { - status = "okay"; - - spi-max-frequency = <76800000>; - m25p80@0 { - compatible = "s25fl256s1"; - spi-max-frequency = <76800000>; - reg = <0>; - spi-tx-bus-width = <1>; - spi-rx-bus-width = <4>; - #address-cells = <1>; - #size-cells = <1>; - - /* MTD partition table. - * The ROM checks the first four physical blocks - * for a valid file to boot and the flash here is - * 64KiB block size. - */ - partition@0 { - label = "QSPI.SPL"; - reg = <0x00000000 0x000010000>; - }; - partition@1 { - label = "QSPI.SPL.backup1"; - reg = <0x00010000 0x00010000>; - }; - partition@2 { - label = "QSPI.SPL.backup2"; - reg = <0x00020000 0x00010000>; - }; - partition@3 { - label = "QSPI.SPL.backup3"; - reg = <0x00030000 0x00010000>; - }; - partition@4 { - label = "QSPI.u-boot"; - reg = <0x00040000 0x00100000>; - }; - partition@5 { - label = "QSPI.u-boot-spl-os"; - reg = <0x00140000 0x00080000>; - }; - partition@6 { - label = "QSPI.u-boot-env"; - reg = <0x001c0000 0x00010000>; - }; - partition@7 { - label = "QSPI.u-boot-env.backup1"; - reg = <0x001d0000 0x0010000>; - }; - partition@8 { - label = "QSPI.kernel"; - reg = <0x001e0000 0x0800000>; - }; - partition@9 { - label = "QSPI.file-system"; - reg = <0x009e0000 0x01620000>; - }; - }; -}; - -&omap_dwc3_1 { - extcon = <&extcon_usb1>; -}; - &omap_dwc3_2 { extcon = <&extcon_usb2>; }; -&usb1 { - dr_mode = "otg"; - extcon = <&extcon_usb1>; -}; - -&usb2 { - dr_mode = "host"; -}; - &elm { status = "okay"; }; @@ -556,6 +387,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <16>; @@ -666,57 +498,6 @@ pinctrl-2 = <&dcan1_pins_default>; }; -&atl { - assigned-clocks = <&abe_dpll_sys_clk_mux>, - <&atl_gfclk_mux>, - <&dpll_abe_ck>, - <&dpll_abe_m2x2_ck>, - <&atl_clkin2_ck>; - assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>; - assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>; - - status = "okay"; - - atl2 { - bws = ; - aws = ; - }; -}; - -&mcasp3 { - #sound-dai-cells = <0>; - - assigned-clocks = <&mcasp3_ahclkx_mux>; - assigned-clock-parents = <&atl_clkin2_ck>; - - status = "okay"; - - op-mode = <0>; /* MCASP_IIS_MODE */ - tdm-slots = <2>; - /* 4 serializer */ - serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ - 1 2 0 0 - >; - tx-num-evt = <32>; - rx-num-evt = <32>; -}; - -&mailbox5 { +&pcie1_rc { status = "okay"; - mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { - status = "okay"; - }; - mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { - status = "okay"; - }; -}; - -&mailbox6 { - status = "okay"; - mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { - status = "okay"; - }; - mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { - status = "okay"; - }; }; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 0f0f6f58bd187db819701d3bafcd68ae7bb7c46e..02a136a4661aa1ed172e4926a7a8dabad9e271b9 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -196,6 +196,7 @@ scm_conf1: scm_conf@1c04 { compatible = "syscon"; reg = <0x1c04 0x0020>; + #syscon-cells = <2>; }; scm_conf_pcie: scm_conf@1c24 { @@ -287,7 +288,11 @@ #address-cells = <1>; ranges = <0x51000000 0x51000000 0x3000 0x0 0x20000000 0x10000000>; - pcie1: pcie@51000000 { + /** + * To enable PCI endpoint mode, disable the pcie1_rc + * node and enable pcie1_ep mode. + */ + pcie1_rc: pcie@51000000 { compatible = "ti,dra7-pcie"; reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>; reg-names = "rc_dbics", "ti_conf", "config"; @@ -309,12 +314,28 @@ <0 0 0 2 &pcie1_intc 2>, <0 0 0 3 &pcie1_intc 3>, <0 0 0 4 &pcie1_intc 4>; + status = "disabled"; pcie1_intc: interrupt-controller { interrupt-controller; #address-cells = <0>; #interrupt-cells = <1>; }; }; + + pcie1_ep: pcie_ep@51000000 { + compatible = "ti,dra7-pcie-ep"; + reg = <0x51000000 0x28>, <0x51002000 0x14c>, <0x51001000 0x28>, <0x1000 0x10000000>; + reg-names = "ep_dbics", "ti_conf", "ep_dbics2", "addr_space"; + interrupts = <0 232 0x4>; + num-lanes = <1>; + num-ib-windows = <4>; + num-ob-windows = <16>; + ti,hwmods = "pcie1"; + phys = <&pcie1_phy>; + phy-names = "pcie-phy0"; + ti,syscon-unaligned-access = <&scm_conf1 0x14 2>; + status = "disabled"; + }; }; axi@1 { @@ -418,6 +439,14 @@ reg = <0x40d00000 0x100>; }; + dra7_iodelay_core: padconf@4844a000 { + compatible = "ti,dra7-iodelay"; + reg = <0x4844a000 0x0d1c>; + #address-cells = <1>; + #size-cells = <0>; + #pinctrl-cells = <2>; + }; + sdma: dma-controller@4a056000 { compatible = "ti,omap4430-sdma"; reg = <0x4a056000 0x1000>; @@ -1037,6 +1066,7 @@ dma-names = "tx", "rx"; status = "disabled"; pbias-supply = <&pbias_mmc_reg>; + max-frequency = <192000000>; }; mmc2: mmc@480b4000 { @@ -1048,6 +1078,7 @@ dmas = <&sdma_xbar 47>, <&sdma_xbar 48>; dma-names = "tx", "rx"; status = "disabled"; + max-frequency = <192000000>; }; mmc3: mmc@480ad000 { @@ -1059,6 +1090,8 @@ dmas = <&sdma_xbar 77>, <&sdma_xbar 78>; dma-names = "tx", "rx"; status = "disabled"; + /* Errata i887 limits max-frequency of MMC3 to 64 MHz */ + max-frequency = <64000000>; }; mmc4: mmc@480d1000 { @@ -1070,6 +1103,7 @@ dmas = <&sdma_xbar 57>, <&sdma_xbar 58>; dma-names = "tx", "rx"; status = "disabled"; + max-frequency = <192000000>; }; mmu0_dsp1: mmu@40d01000 { diff --git a/arch/arm/boot/dts/dra71-evm.dts b/arch/arm/boot/dts/dra71-evm.dts index 4d57a55473afd1f563667d948b49269e11028697..41c9132eb550d07dd686a85eda0296bbfad0b6f7 100644 --- a/arch/arm/boot/dts/dra71-evm.dts +++ b/arch/arm/boot/dts/dra71-evm.dts @@ -7,6 +7,7 @@ */ #include "dra72-evm-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" #include / { @@ -32,6 +33,16 @@ 3000000 0x1>; }; + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&lp8732_buck0_reg>; + regulator-always-on; + regulator-boot-on; + }; + poweroff: gpio-poweroff { compatible = "gpio-poweroff"; gpios = <&gpio7 30 GPIO_ACTIVE_HIGH>; @@ -162,7 +173,24 @@ }; &mmc1 { - vmmc_aux-supply = <&vpo_sd_1v8_3v3>; + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; + vqmmc-supply = <&vpo_sd_1v8_3v3>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; + pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev20_conf>; + vmmc-supply = <&evm_1v8_sw>; }; &mac { @@ -190,7 +218,8 @@ ti,rx-internal-delay = ; ti,tx-internal-delay = ; ti,fifo-depth = ; - ti,impedance-control = <0x1f>; + ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; }; dp83867_1: ethernet-phy@3 { @@ -198,7 +227,8 @@ ti,rx-internal-delay = ; ti,tx-internal-delay = ; ti,fifo-depth = ; - ti,impedance-control = <0x1f>; + ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; }; }; diff --git a/arch/arm/boot/dts/dra72-evm-common.dtsi b/arch/arm/boot/dts/dra72-evm-common.dtsi index 85780549bc26359269b5f5bd05023364b0143905..2e485a13dfd7e1fe470f071022ac4332e1445ea1 100644 --- a/arch/arm/boot/dts/dra72-evm-common.dtsi +++ b/arch/arm/boot/dts/dra72-evm-common.dtsi @@ -311,6 +311,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <16>; @@ -419,8 +420,6 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins_default>; - - vmmc-supply = <&evm_3v3_sw>; bus-width = <8>; ti,non-removable; max-frequency = <192000000>; @@ -564,3 +563,7 @@ status = "okay"; }; }; + +&pcie1_rc { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/dra72-evm-revc.dts b/arch/arm/boot/dts/dra72-evm-revc.dts index 3ecac56bf504de779a954208a4b7318a8ae4437c..bf588d00728d1973c3426f09421dc5c2bbb5bbe0 100644 --- a/arch/arm/boot/dts/dra72-evm-revc.dts +++ b/arch/arm/boot/dts/dra72-evm-revc.dts @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ #include "dra72-evm-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" #include / { @@ -15,6 +16,16 @@ device_type = "memory"; reg = <0x0 0x80000000 0x0 0x80000000>; /* 2GB */ }; + + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&smps4_reg>; + regulator-always-on; + regulator-boot-on; + }; }; &i2c1 { @@ -70,6 +81,7 @@ ti,min-output-impedance; interrupt-parent = <&gpio6>; interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + ti,dp83867-rxctrl-strap-quirk; }; dp83867_1: ethernet-phy@3 { @@ -80,5 +92,27 @@ ti,min-output-impedance; interrupt-parent = <&gpio6>; interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + ti,dp83867-rxctrl-strap-quirk; }; }; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; + pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev20_conf>; + vmmc-supply = <&evm_1v8_sw>; +}; diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi index e6df676886c0c35052921669039ae31fd446ccbf..57bfe5caf5e4f12c6468575abe646ca78e19a01e 100644 --- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi +++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi @@ -146,5 +146,5 @@ }; &mmc1 { - vmmc_aux-supply = <&ldo1_reg>; + vqmmc-supply = <&ldo1_reg>; }; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index cd9c4ff12654ce00ae443c654a888dc14b4a66c6..c572693b16657b69565b3581ac39c9bd8298cba2 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ #include "dra72-evm-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" / { model = "TI DRA722"; @@ -13,6 +14,16 @@ device_type = "memory"; reg = <0x0 0x80000000 0x0 0x40000000>; /* 1024 MB */ }; + + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&smps4_reg>; + regulator-always-on; + regulator-boot-on; + }; }; &i2c1 { @@ -43,3 +54,24 @@ phy_id = <&davinci_mdio>, <3>; phy-mode = "rgmii"; }; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev10>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev10_conf>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev10>; + pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev10_conf>; + vmmc-supply = <&evm_1v8_sw>; +}; diff --git a/arch/arm/boot/dts/dra72x-mmc-iodelay.dtsi b/arch/arm/boot/dts/dra72x-mmc-iodelay.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..088013c6dc6ed4bdb9665179ae267f84700dc272 --- /dev/null +++ b/arch/arm/boot/dts/dra72x-mmc-iodelay.dtsi @@ -0,0 +1,350 @@ +/* + * MMC IOdelay values for TI's DRA72x, DRA71x and AM571x SoCs. + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Rules for modifying this file: + * a) Update of this file should typically correspond to a datamanual revision. + * Datamanual revision that was used should be updated in comment below. + * If there is no update to datamanual, do not update the values. If you + * need to use values different from that recommended by the datamanual + * for your design, then you should consider adding values to the device- + * -tree file for your board directly. + * b) We keep the mode names as close to the datamanual as possible. So + * if the manual calls a mode, DDR50, or DDR or DDR 1.8v or DDR 3.3v, + * we follow that in code too. + * c) If the values change between multiple revisions of silicon, we add + * a revision tag to both the new and old entry. Use 'rev10' for PG 1.0, + * 'rev20' for PG 2.0 and so on. + * d) The node name and node label should be the exact same string. This is + * to curb naming creativity and achieve consistency. + * e) If in future, DRA71x and DRA72x values differ, then add 'dra71_' and + * 'dra72_' tag to entries. Both the new and old entries should gain a tag. + * + * Datamanual Revisions: + * + * AM571x Silicon Revision 2.0: SPRS957D, Revised January 2017 + * AM571x Silicon Revision 1.0: SPRS919M, Revised November 2017 + * DRA71x : SPRS960B, Revised February 2017 + */ + +&dra7_pmx_core { + mmc1_pins_default: mmc1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr12: mmc1_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_hs: mmc1_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr25: mmc1_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr50: mmc1_pins_sdr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_ddr50_rev10: mmc1_pins_ddr50_rev10 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_clk.mmc1_clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_cmd.mmc1_cmd */ + DRA7XX_CORE_IOPAD(0x375C, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat0.mmc1_dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat1.mmc1_dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat2.mmc1_dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 */ + >; + }; + + mmc1_pins_ddr50_rev20: mmc1_pins_ddr50_rev20 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr104: mmc1_pins_sdr104 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc2_pins_default: mmc2_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs: mmc2_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_rev10: mmc2_pins_ddr_rev10 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + >; + }; + + mmc2_pins_ddr_rev20: mmc2_pins_ddr_rev20 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs200: mmc2_pins_hs200 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; +}; + +&dra7_iodelay_core { + + /* Corresponds to MMC1_MANUAL1 in datamanual */ + mmc1_iodelay_ddr50_conf: mmc1_iodelay_ddr50_conf { + pinctrl-pin-array = < + 0x618 A_DELAY_PS(588) G_DELAY_PS(0) /* CFG_MMC1_CLK_IN */ + 0x624 A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_CMD_IN */ + 0x630 A_DELAY_PS(1375) G_DELAY_PS(0) /* CFG_MMC1_DAT0_IN */ + 0x63C A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_DAT1_IN */ + 0x648 A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_DAT2_IN */ + 0x654 A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_DAT3_IN */ + 0x620 A_DELAY_PS(1230) G_DELAY_PS(0) /* CFG_MMC1_CLK_OUT */ + 0x62C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x638 A_DELAY_PS(56) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x644 A_DELAY_PS(76) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x650 A_DELAY_PS(91) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x65C A_DELAY_PS(99) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x64C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + >; + }; + + /* Corresponds to MMC1_MANUAL2 in datamanual */ + mmc1_iodelay_sdr104_rev10_conf: mmc1_iodelay_sdr104_rev10_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(560) G_DELAY_PS(365) /* CFG_MMC1_CLK_OUT */ + 0x62c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x638 A_DELAY_PS(29) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x650 A_DELAY_PS(47) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x65c A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + 0x628 A_DELAY_PS(125) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x634 A_DELAY_PS(43) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x640 A_DELAY_PS(433) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x64c A_DELAY_PS(287) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x658 A_DELAY_PS(351) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + >; + }; + + /* Corresponds to MMC1_MANUAL2 in datamanual */ + mmc1_iodelay_sdr104_rev20_conf: mmc1_iodelay_sdr104_rev20_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(520) G_DELAY_PS(320) /* CFG_MMC1_CLK_OUT */ + 0x62c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x638 A_DELAY_PS(40) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x644 A_DELAY_PS(83) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x650 A_DELAY_PS(98) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x65c A_DELAY_PS(106) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + 0x628 A_DELAY_PS(51) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x640 A_DELAY_PS(363) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x64c A_DELAY_PS(199) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x658 A_DELAY_PS(273) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + >; + }; + + /* Corresponds to MMC2_MANUAL1 in datamanual */ + mmc2_iodelay_ddr_conf: mmc2_iodelay_ddr_conf { + pinctrl-pin-array = < + 0x18c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_IN */ + 0x1a4 A_DELAY_PS(119) G_DELAY_PS(0) /* CFG_GPMC_A20_IN */ + 0x1b0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_IN */ + 0x1bc A_DELAY_PS(18) G_DELAY_PS(0) /* CFG_GPMC_A22_IN */ + 0x1c8 A_DELAY_PS(894) G_DELAY_PS(0) /* CFG_GPMC_A23_IN */ + 0x1d4 A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_GPMC_A24_IN */ + 0x1e0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_IN */ + 0x1ec A_DELAY_PS(23) G_DELAY_PS(0) /* CFG_GPMC_A26_IN */ + 0x1f8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_IN */ + 0x360 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_IN */ + 0x194 A_DELAY_PS(152) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1ac A_DELAY_PS(206) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b8 A_DELAY_PS(78) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c4 A_DELAY_PS(2) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(266) G_DELAY_PS(0) /* CFG_GPMC_A23_OUT */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f4 A_DELAY_PS(43) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x368 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x1a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1b4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1c0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1d8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1f0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x364 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + >; + }; + + /* Corresponds to MMC2_MANUAL3 in datamanual */ + mmc2_iodelay_hs200_rev10_conf: mmc2_iodelay_hs200_rev10_conf { + pinctrl-pin-array = < + 0x194 A_DELAY_PS(150) G_DELAY_PS(95) /* CFG_GPMC_A19_OUT */ + 0x1ac A_DELAY_PS(250) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b8 A_DELAY_PS(125) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c4 A_DELAY_PS(100) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(870) G_DELAY_PS(415) /* CFG_GPMC_A23_OUT */ + 0x1dc A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e8 A_DELAY_PS(200) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f4 A_DELAY_PS(200) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x368 A_DELAY_PS(240) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(695) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x1a8 A_DELAY_PS(924) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1b4 A_DELAY_PS(719) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1c0 A_DELAY_PS(824) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1d8 A_DELAY_PS(877) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1e4 A_DELAY_PS(446) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1f0 A_DELAY_PS(847) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1fc A_DELAY_PS(586) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x364 A_DELAY_PS(1039) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + >; + }; + + /* Corresponds to MMC2_MANUAL3 in datamanual */ + mmc2_iodelay_hs200_rev20_conf: mmc2_iodelay_hs200_rev20_conf { + pinctrl-pin-array = < + 0x194 A_DELAY_PS(285) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1ac A_DELAY_PS(189) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b8 A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A21_OUT */ + 0x1c4 A_DELAY_PS(0) G_DELAY_PS(70) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(730) G_DELAY_PS(360) /* CFG_GPMC_A23_OUT */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f4 A_DELAY_PS(70) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x368 A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x1a8 A_DELAY_PS(231) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1b4 A_DELAY_PS(39) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1c0 A_DELAY_PS(91) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1d8 A_DELAY_PS(176) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1f0 A_DELAY_PS(101) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x364 A_DELAY_PS(360) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + >; + }; +}; diff --git a/arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi b/arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..28ebb4eb884a9450f51508c576e2b37d3d8a0808 --- /dev/null +++ b/arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi @@ -0,0 +1,647 @@ +/* + * MMC IOdelay values for TI's DRA74x, DRA75x and AM572x SoCs. + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Rules for modifying this file: + * a) Update of this file should typically correspond to a datamanual revision. + * Datamanual revision that was used should be updated in comment below. + * If there is no update to datamanual, do not update the values. If you + * need to use values different from that recommended by the datamanual + * for your design, then you should consider adding values to the device- + * -tree file for your board directly. + * b) We keep the mode names as close to the datamanual as possible. So + * if the manual calls a mode, DDR50, or DDR or DDR 1.8v or DDR 3.3v, + * we follow that in code too. + * c) If the values change between multiple revisions of silicon, we add + * a revision tag to both the new and old entry. Use 'rev11' for PG 1.1, + * 'rev20' for PG 2.0 and so on. + * d) The node name and node label should be the exact same string. This is + * to curb naming creativity and achieve consistency. + * + * Datamanual Revisions: + * + * AM572x Silicon Revision 2.0: SPRS953B, Revised November 2016 + * AM572x Silicon Revision 1.1: SPRS915R, Revised November 2016 + * + */ + +&dra7_pmx_core { + mmc1_pins_default: mmc1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr12: mmc1_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_hs: mmc1_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr25: mmc1_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr50: mmc1_pins_sdr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_ddr50: mmc1_pins_ddr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr104: mmc1_pins_sdr104 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc2_pins_default: mmc2_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs: mmc2_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_3_3v_rev11: mmc2_pins_ddr_3_3v_rev11 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_1_8v_rev11: mmc2_pins_ddr_1_8v_rev11 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_rev20: mmc2_pins_ddr_rev20 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs200: mmc2_pins_hs200 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc4_pins_default: mmc4_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; + + mmc4_pins_hs: mmc4_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; + + mmc3_pins_default: mmc3_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_hs: mmc3_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_sdr12: mmc3_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_sdr25: mmc3_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_sdr50: mmc3_pins_sdr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc4_pins_sdr12: mmc4_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; + + mmc4_pins_sdr25: mmc4_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; +}; + +&dra7_iodelay_core { + + /* Corresponds to MMC1_DDR_MANUAL1 in datamanual */ + mmc1_iodelay_ddr_rev11_conf: mmc1_iodelay_ddr_rev11_conf { + pinctrl-pin-array = < + 0x618 A_DELAY_PS(572) G_DELAY_PS(540) /* CFG_MMC1_CLK_IN */ + 0x620 A_DELAY_PS(1525) G_DELAY_PS(0) /* CFG_MMC1_CLK_OUT */ + 0x624 A_DELAY_PS(0) G_DELAY_PS(600) /* CFG_MMC1_CMD_IN */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62c A_DELAY_PS(55) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x630 A_DELAY_PS(403) G_DELAY_PS(120) /* CFG_MMC1_DAT0_IN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x63c A_DELAY_PS(23) G_DELAY_PS(60) /* CFG_MMC1_DAT1_IN */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x648 A_DELAY_PS(25) G_DELAY_PS(60) /* CFG_MMC1_DAT2_IN */ + 0x64c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x654 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_IN */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC1_DDR_MANUAL1 in datamanual */ + mmc1_iodelay_ddr_rev20_conf: mmc1_iodelay_ddr50_rev20_conf { + pinctrl-pin-array = < + 0x618 A_DELAY_PS(1076) G_DELAY_PS(330) /* CFG_MMC1_CLK_IN */ + 0x620 A_DELAY_PS(1271) G_DELAY_PS(0) /* CFG_MMC1_CLK_OUT */ + 0x624 A_DELAY_PS(722) G_DELAY_PS(0) /* CFG_MMC1_CMD_IN */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x630 A_DELAY_PS(751) G_DELAY_PS(0) /* CFG_MMC1_DAT0_IN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(20) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x63C A_DELAY_PS(256) G_DELAY_PS(0) /* CFG_MMC1_DAT1_IN */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x648 A_DELAY_PS(263) G_DELAY_PS(0) /* CFG_MMC1_DAT2_IN */ + 0x64C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x654 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_IN */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC1_SDR104_MANUAL1 in datamanual */ + mmc1_iodelay_sdr104_rev11_conf: mmc1_iodelay_sdr104_rev11_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(1063) G_DELAY_PS(17) /* CFG_MMC1_CLK_OUT */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62c A_DELAY_PS(23) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(2) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x64c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC1_SDR104_MANUAL1 in datamanual */ + mmc1_iodelay_sdr104_rev20_conf: mmc1_iodelay_sdr104_rev20_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(600) G_DELAY_PS(400) /* CFG_MMC1_CLK_OUT */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x64c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC2_HS200_MANUAL1 in datamanual */ + mmc2_iodelay_hs200_rev11_conf: mmc2_iodelay_hs200_rev11_conf { + pinctrl-pin-array = < + 0x190 A_DELAY_PS(621) G_DELAY_PS(600) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(300) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a8 A_DELAY_PS(739) G_DELAY_PS(600) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(240) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b4 A_DELAY_PS(812) G_DELAY_PS(600) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(240) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c0 A_DELAY_PS(954) G_DELAY_PS(600) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(60) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(1340) G_DELAY_PS(420) /* CFG_GPMC_A23_OUT */ + 0x1d8 A_DELAY_PS(935) G_DELAY_PS(600) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e4 A_DELAY_PS(525) G_DELAY_PS(600) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(120) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f0 A_DELAY_PS(767) G_DELAY_PS(600) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(225) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1fc A_DELAY_PS(565) G_DELAY_PS(600) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(60) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x364 A_DELAY_PS(969) G_DELAY_PS(600) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(180) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Corresponds to MMC2_HS200_MANUAL1 in datamanual */ + mmc2_iodelay_hs200_rev20_conf: mmc2_iodelay_hs200_rev20_conf { + pinctrl-pin-array = < + 0x190 A_DELAY_PS(274) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(162) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a8 A_DELAY_PS(401) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(73) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b4 A_DELAY_PS(465) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(115) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c0 A_DELAY_PS(633) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(47) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(935) G_DELAY_PS(280) /* CFG_GPMC_A23_OUT */ + 0x1d8 A_DELAY_PS(621) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e4 A_DELAY_PS(183) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f0 A_DELAY_PS(467) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1fc A_DELAY_PS(262) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(46) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x364 A_DELAY_PS(684) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(76) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Correspnds to MMC2_DDR_3V3_MANUAL1 in datamanual */ + mmc2_iodelay_ddr_3_3v_rev11_conf: mmc2_iodelay_ddr_3_3v_rev11_conf { + pinctrl-pin-array = < + 0x18c A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A19_IN */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(174) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a4 A_DELAY_PS(265) G_DELAY_PS(360) /* CFG_GPMC_A20_IN */ + 0x1a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(168) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b0 A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A21_IN */ + 0x1b4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(136) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1bc A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A22_IN */ + 0x1c0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1c8 A_DELAY_PS(287) G_DELAY_PS(420) /* CFG_GPMC_A23_IN */ + 0x1d0 A_DELAY_PS(879) G_DELAY_PS(0) /* CFG_GPMC_A23_OUT */ + 0x1d4 A_DELAY_PS(144) G_DELAY_PS(240) /* CFG_GPMC_A24_IN */ + 0x1d8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_IN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(34) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1ec A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A26_IN */ + 0x1f0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(120) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1f8 A_DELAY_PS(120) G_DELAY_PS(180) /* CFG_GPMC_A27_IN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x360 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_IN */ + 0x364 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(11) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Corresponds to MMC2_DDR_1V8_MANUAL1 in datamanual */ + mmc2_iodelay_ddr_1_8v_rev11_conf: mmc2_iodelay_ddr_1_8v_rev11_conf { + pinctrl-pin-array = < + 0x18c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_IN */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(174) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a4 A_DELAY_PS(274) G_DELAY_PS(240) /* CFG_GPMC_A20_IN */ + 0x1a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(168) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b0 A_DELAY_PS(0) G_DELAY_PS(60) /* CFG_GPMC_A21_IN */ + 0x1b4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(136) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1bc A_DELAY_PS(0) G_DELAY_PS(60) /* CFG_GPMC_A22_IN */ + 0x1c0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1c8 A_DELAY_PS(514) G_DELAY_PS(360) /* CFG_GPMC_A23_IN */ + 0x1d0 A_DELAY_PS(879) G_DELAY_PS(0) /* CFG_GPMC_A23_OUT */ + 0x1d4 A_DELAY_PS(187) G_DELAY_PS(120) /* CFG_GPMC_A24_IN */ + 0x1d8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_IN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(34) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1ec A_DELAY_PS(0) G_DELAY_PS(60) /* CFG_GPMC_A26_IN */ + 0x1f0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(120) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1f8 A_DELAY_PS(121) G_DELAY_PS(60) /* CFG_GPMC_A27_IN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x360 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_IN */ + 0x364 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(11) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Corresponds to MMC3_MANUAL1 in datamanual */ + mmc3_iodelay_manual1_rev20_conf: mmc3_iodelay_manual1_conf { + pinctrl-pin-array = < + 0x678 A_DELAY_PS(0) G_DELAY_PS(386) /* CFG_MMC3_CLK_IN */ + 0x680 A_DELAY_PS(605) G_DELAY_PS(0) /* CFG_MMC3_CLK_OUT */ + 0x684 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_IN */ + 0x688 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OEN */ + 0x68c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OUT */ + 0x690 A_DELAY_PS(171) G_DELAY_PS(0) /* CFG_MMC3_DAT0_IN */ + 0x694 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OEN */ + 0x698 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OUT */ + 0x69c A_DELAY_PS(221) G_DELAY_PS(0) /* CFG_MMC3_DAT1_IN */ + 0x6a0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OEN */ + 0x6a4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OUT */ + 0x6a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_IN */ + 0x6ac A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OEN */ + 0x6b0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OUT */ + 0x6b4 A_DELAY_PS(474) G_DELAY_PS(0) /* CFG_MMC3_DAT3_IN */ + 0x6b8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OEN */ + 0x6bc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC3_MANUAL1 in datamanual */ + mmc3_iodelay_manual1_rev11_conf: mmc3_iodelay_manual1_conf { + pinctrl-pin-array = < + 0x678 A_DELAY_PS(406) G_DELAY_PS(0) /* CFG_MMC3_CLK_IN */ + 0x680 A_DELAY_PS(659) G_DELAY_PS(0) /* CFG_MMC3_CLK_OUT */ + 0x684 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_IN */ + 0x688 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OEN */ + 0x68c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OUT */ + 0x690 A_DELAY_PS(130) G_DELAY_PS(0) /* CFG_MMC3_DAT0_IN */ + 0x694 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OEN */ + 0x698 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OUT */ + 0x69c A_DELAY_PS(169) G_DELAY_PS(0) /* CFG_MMC3_DAT1_IN */ + 0x6a0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OEN */ + 0x6a4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OUT */ + 0x6a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_IN */ + 0x6ac A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OEN */ + 0x6b0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OUT */ + 0x6b4 A_DELAY_PS(457) G_DELAY_PS(0) /* CFG_MMC3_DAT3_IN */ + 0x6b8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OEN */ + 0x6bc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC4_DS_MANUAL1 in datamanual */ + mmc4_iodelay_ds_rev11_conf: mmc4_iodelay_ds_rev11_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(96) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(582) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(391) G_DELAY_PS(0) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(561) G_DELAY_PS(0) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(588) G_DELAY_PS(0) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; + + /* Corresponds to MMC4_DS_MANUAL1 in datamanual */ + mmc4_iodelay_ds_rev20_conf: mmc4_iodelay_ds_rev20_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(307) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(785) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(613) G_DELAY_PS(0) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(683) G_DELAY_PS(0) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(835) G_DELAY_PS(0) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; + + /* Corresponds to MMC4_MANUAL1 in datamanual */ + mmc4_iodelay_sdr12_hs_sdr25_rev11_conf: mmc4_iodelay_sdr12_hs_sdr25_rev11_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(2651) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(1572) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(1913) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(1721) G_DELAY_PS(0) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(1891) G_DELAY_PS(0) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(1919) G_DELAY_PS(0) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; + + /* Corresponds to MMC4_MANUAL1 in datamanual */ + mmc4_iodelay_sdr12_hs_sdr25_rev20_conf: mmc4_iodelay_sdr12_hs_sdr25_rev20_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(1147) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(1834) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(2165) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(1929) G_DELAY_PS(64) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(1935) G_DELAY_PS(128) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(2172) G_DELAY_PS(44) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; +}; diff --git a/arch/arm/boot/dts/dra76-evm.dts b/arch/arm/boot/dts/dra76-evm.dts new file mode 100644 index 0000000000000000000000000000000000000000..b024a65c6e2711abb4beeb288556860841ea22c0 --- /dev/null +++ b/arch/arm/boot/dts/dra76-evm.dts @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "dra76x.dtsi" +#include "dra7-evm-common.dtsi" +#include + +/ { + model = "TI DRA762 EVM"; + compatible = "ti,dra76-evm", "ti,dra762", "ti,dra7"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x80000000>; + }; + + vsys_12v0: fixedregulator-vsys12v0 { + /* main supply */ + compatible = "regulator-fixed"; + regulator-name = "vsys_12v0"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + regulator-boot-on; + }; + + vsys_5v0: fixedregulator-vsys5v0 { + /* Output of Cntlr B of TPS43351-Q1 on dra76-evm */ + compatible = "regulator-fixed"; + regulator-name = "vsys_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vsys_12v0>; + regulator-always-on; + regulator-boot-on; + }; + + vsys_3v3: fixedregulator-vsys3v3 { + /* Output of Cntlr A of TPS43351-Q1 on dra76-evm */ + compatible = "regulator-fixed"; + regulator-name = "vsys_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vsys_12v0>; + regulator-always-on; + regulator-boot-on; + }; + + vio_3v3: fixedregulator-vio_3v3 { + compatible = "regulator-fixed"; + regulator-name = "vio_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vsys_3v3>; + regulator-always-on; + regulator-boot-on; + }; + + vio_3v3_sd: fixedregulator-sd { + compatible = "regulator-fixed"; + regulator-name = "vio_3v3_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vio_3v3>; + enable-active-high; + gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; + }; + + vio_1v8: fixedregulator-vio_1v8 { + compatible = "regulator-fixed"; + regulator-name = "vio_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&smps5_reg>; + }; + + vtt_fixed: fixedregulator-vtt { + compatible = "regulator-fixed"; + regulator-name = "vtt_fixed"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + vin-supply = <&vsys_3v3>; + regulator-always-on; + regulator-boot-on; + }; + + aic_dvdd: fixedregulator-aic_dvdd { + /* TPS77018DBVT */ + compatible = "regulator-fixed"; + regulator-name = "aic_dvdd"; + vin-supply = <&vio_3v3>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; +}; + +&dra7_pmx_core { + mmc1_pins_default: mmc1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */ + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr12: pinmux_mmc1_sdr12_pins { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc2_pins_default: mmc2_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + + tps65917: tps65917@58 { + compatible = "ti,tps65917"; + reg = <0x58>; + ti,system-power-controller; + interrupt-controller; + #interrupt-cells = <2>; + + tps65917_pmic { + compatible = "ti,tps65917-pmic"; + + smps12-in-supply = <&vsys_3v3>; + smps3-in-supply = <&vsys_3v3>; + smps4-in-supply = <&vsys_3v3>; + smps5-in-supply = <&vsys_3v3>; + ldo1-in-supply = <&vsys_3v3>; + ldo2-in-supply = <&vsys_3v3>; + ldo3-in-supply = <&vsys_5v0>; + ldo4-in-supply = <&vsys_5v0>; + ldo5-in-supply = <&vsys_3v3>; + + tps65917_regulators: regulators { + smps12_reg: smps12 { + /* VDD_DSPEVE */ + regulator-name = "smps12"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + smps3_reg: smps3 { + /* VDD_CORE */ + regulator-name = "smps3"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-boot-on; + regulator-always-on; + }; + + smps4_reg: smps4 { + /* VDD_IVA */ + regulator-name = "smps4"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + smps5_reg: smps5 { + /* VDDS1V8 */ + regulator-name = "smps5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: ldo1 { + /* LDO1_OUT --> VDA_PHY1_1V8 */ + regulator-name = "ldo1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-allow-bypass; + }; + + ldo2_reg: ldo2 { + /* LDO2_OUT --> VDA_PHY2_1V8 */ + regulator-name = "ldo2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-bypass; + regulator-always-on; + }; + + ldo3_reg: ldo3 { + /* VDA_USB_3V3 */ + regulator-name = "ldo3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5_reg: ldo5 { + /* VDDA_1V8_PLL */ + regulator-name = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo4_reg: ldo4 { + /* VDD_SDIO_DV */ + regulator-name = "ldo4"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + tps65917_power_button { + compatible = "ti,palmas-pwrbutton"; + interrupt-parent = <&tps65917>; + interrupts = <1 IRQ_TYPE_NONE>; + wakeup-source; + ti,palmas-long-press-seconds = <6>; + }; + }; + + lp87565: lp87565@60 { + compatible = "ti,lp87565-q1"; + reg = <0x60>; + + buck10-in-supply =<&vsys_3v3>; + buck23-in-supply =<&vsys_3v3>; + + regulators: regulators { + buck10_reg: buck10 { + /*VDD_MPU*/ + regulator-name = "buck10"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + buck23_reg: buck23 { + /* VDD_GPU*/ + regulator-name = "buck23"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + pcf_lcd: pcf8757@20 { + compatible = "ti,pcf8575", "nxp,pcf8575"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + }; + + pcf_gpio_21: pcf8757@21 { + compatible = "ti,pcf8575", "nxp,pcf8575"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pcf_hdmi: pcf8575@26 { + compatible = "ti,pcf8575", "nxp,pcf8575"; + reg = <0x26>; + gpio-controller; + #gpio-cells = <2>; + p1 { + /* vin6_sel_s0: high: VIN6, low: audio */ + gpio-hog; + gpios = <1 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "vin6_sel_s0"; + }; + }; + + tlv320aic3106: tlv320aic3106@19 { + #sound-dai-cells = <0>; + compatible = "ti,tlv320aic3106"; + reg = <0x19>; + adc-settle-ms = <40>; + ai3x-micbias-vg = <1>; /* 2.0V */ + status = "okay"; + + /* Regulators */ + AVDD-supply = <&vio_3v3>; + IOVDD-supply = <&vio_3v3>; + DRVDD-supply = <&vio_3v3>; + DVDD-supply = <&aic_dvdd>; + }; +}; + +&cpu0 { + vdd-supply = <&buck10_reg>; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vio_3v3_sd>; + vmmc_aux-supply = <&ldo4_reg>; + bus-width = <4>; + /* + * SDCD signal is not being used here - using the fact that GPIO mode + * is always hardwired. + */ + cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_default>; +}; + +&mmc2 { + status = "okay"; + vmmc-supply = <&vio_1v8>; + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins_default>; +}; + +/* No RTC on this device */ +&rtc { + status = "disabled"; +}; + +&mac { + status = "okay"; + + dual_emac; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <2>; + phy-mode = "rgmii-id"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <3>; + phy-mode = "rgmii-id"; + dual_emac_res_vlan = <2>; +}; + +&davinci_mdio { + dp83867_0: ethernet-phy@2 { + reg = <2>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; + }; + + dp83867_1: ethernet-phy@3 { + reg = <3>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; + }; +}; + +&usb2_phy1 { + phy-supply = <&ldo3_reg>; +}; + +&usb2_phy2 { + phy-supply = <&ldo3_reg>; +}; + +&qspi { + spi-max-frequency = <96000000>; + m25p80@0 { + spi-max-frequency = <96000000>; + }; +}; diff --git a/arch/arm/boot/dts/dra76x.dtsi b/arch/arm/boot/dts/dra76x.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..1c88c581ff18879a4991f3a77634e3b998d56b3d --- /dev/null +++ b/arch/arm/boot/dts/dra76x.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "dra74x.dtsi" + +/ { + compatible = "ti,dra762", "ti,dra7"; + +}; + +/* MCAN interrupts are hard-wired to irqs 67, 68 */ +&crossbar_mpu { + ti,irqs-skip = <10 67 68 133 139 140>; +}; diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index cf229dfabf6173872d23ea380a436109b5424caf..e62b62875cbad7ed97dd7f23c0f290a38839d3be 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -1817,6 +1817,8 @@ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; ti,bit-shift = <24>; reg = <0x1868>; + assigned-clocks = <&mcasp3_ahclkx_mux>; + assigned-clock-parents = <&abe_24m_fclk>; }; mcasp3_aux_gfclk_mux: mcasp3_aux_gfclk_mux@1868 { diff --git a/arch/arm/boot/dts/exynos3250-artik5-eval.dts b/arch/arm/boot/dts/exynos3250-artik5-eval.dts index 4bd2ee87124eab05014568fdbc24d308611bdf16..4cbfa09c6c4e46fb25bfea03996aee13dcddc662 100644 --- a/arch/arm/boot/dts/exynos3250-artik5-eval.dts +++ b/arch/arm/boot/dts/exynos3250-artik5-eval.dts @@ -22,7 +22,6 @@ }; &mshc_2 { - num-slots = <1>; cap-sd-highspeed; disable-wp; vqmmc-supply = <&ldo3_reg>; diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi index 59c89d7662a8004b03f52cbdab7d3f9903bf9326..639c2e605f3c99a4c5478b85c4ac69c236f8bfba 100644 --- a/arch/arm/boot/dts/exynos3250-artik5.dtsi +++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi @@ -304,7 +304,6 @@ }; &mshc_0 { - num-slots = <1>; non-removable; cap-mmc-highspeed; card-detect-delay = <200>; diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index accee81da266e3c1e9a3cb7e55998c658f1017a7..bbdfcbc6e7d29a5cdbb854ba030f1d77cae048ad 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -426,7 +426,6 @@ &mshc_0 { #address-cells = <1>; #size-cells = <0>; - num-slots = <1>; broken-cd; non-removable; cap-mmc-highspeed; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 443e0c98dc73089213ce3aca04a0bdb44dfc64ed..0b45467d77a8f53d5b21ce910cadfd2d1226565e 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -220,21 +220,6 @@ samsung,pll-clock-frequency = <24000000>; status = "okay"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - remote-endpoint = <&dsi_in>; - samsung,burst-clock-frequency = <250000000>; - samsung,esc-clock-frequency = <20000000>; - }; - }; - }; - panel@0 { compatible = "samsung,s6e63j0x03"; reg = <0>; @@ -264,12 +249,6 @@ vsync-len = <2>; }; }; - - port { - dsi_in: endpoint { - remote-endpoint = <&dsi_out>; - }; - }; }; }; @@ -642,7 +621,6 @@ &mshc_0 { #address-cells = <1>; #size-cells = <0>; - num-slots = <1>; broken-cd; non-removable; cap-mmc-highspeed; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 497a9470c8881bca6e49800f90c0f5d20dd3d84a..5739389f5bb877ef7b29455a1bcd47328d7223ed 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -59,6 +59,9 @@ compatible = "samsung,exynos4210-audss-clock"; reg = <0x03810000 0x0C>; #clock-cells = <1>; + clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>, + <&clock CLK_SCLK_AUDIO0>, <&clock CLK_SCLK_AUDIO0>; + clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in"; }; i2s0: i2s@03830000 { diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index 645feffb9239d2465782ea04989ce063b6ae2b97..7b6ab726511053d008789a3270d7eb84b421dbd1 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -202,21 +202,6 @@ samsung,pll-clock-frequency = <24000000>; status = "okay"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - remote-endpoint = <&dsi_in>; - samsung,burst-clock-frequency = <500000000>; - samsung,esc-clock-frequency = <20000000>; - }; - }; - }; - panel@0 { reg = <0>; compatible = "samsung,s6e8aa0"; @@ -244,12 +229,6 @@ vsync-len = <2>; }; }; - - port { - dsi_in: endpoint { - remote-endpoint = <&dsi_out>; - }; - }; }; }; diff --git a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi index 4cd62487bb16f28a2b1303ac4ce3486a552a7214..14ce2c69bc0b4972d4cb4817fcfaaca0b8b953d4 100644 --- a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi +++ b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi @@ -466,7 +466,6 @@ pinctrl-names = "default"; status = "okay"; vmmc-supply = <&buck9_reg>; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 219d587c5a85059f9bd44ac69a794cae25a21bf7..102acd78be15a9a972a2334cb520021424045ba0 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -516,7 +516,6 @@ mmc-pwrseq = <&emmc_pwrseq>; status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 7a83e2df18a606a8247859647aa0fa5f7e172236..8a89eb893d644d46ad79d7f3e7161edb2d0eccf0 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -488,7 +488,6 @@ pinctrl-names = "default"; status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94b86b8d6853e919574fec8d486543061c8..bceb919ac6379ad8d5034913b32ecdfd436a7030 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -390,21 +390,6 @@ samsung,pll-clock-frequency = <24000000>; status = "okay"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - remote-endpoint = <&dsi_in>; - samsung,burst-clock-frequency = <500000000>; - samsung,esc-clock-frequency = <20000000>; - }; - }; - }; - panel@0 { compatible = "samsung,s6e8aa0"; reg = <0>; @@ -432,12 +417,6 @@ vsync-len = <2>; }; }; - - port { - dsi_in: endpoint { - remote-endpoint = <&dsi_out>; - }; - }; }; }; @@ -901,7 +880,6 @@ }; &mshc_0 { - num-slots = <1>; broken-cd; non-removable; card-detect-delay = <200>; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 6a432460eb77b910d58c3d174ae22c03b7adbae4..18a7f396ac5f727b4daa0c15b2723b3ca89035d2 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -518,7 +518,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -533,7 +532,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 6632f657394e6d4ee44774573487a77c08acae5b..062cba4c2c310b28846634d354b10fe4d07e786c 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -346,7 +346,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -360,7 +359,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi index e1d293dbbe5d95623ddd8b26a951c5e3360afb24..8788880e459d3e1dde6bfddbe80ae3c631693d89 100644 --- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -530,7 +530,6 @@ /* eMMC flash */ &mmc_0 { status = "okay"; - num-slots = <1>; non-removable; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -544,7 +543,6 @@ /* uSD card */ &mmc_2 { status = "okay"; - num-slots = <1>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -564,7 +562,6 @@ */ &mmc_3 { status = "okay"; - num-slots = <1>; non-removable; cap-sdio-irq; keep-power-in-suspend; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index 95c3bcace9dcbe8fcc233a17d88320f3ffd73fd6..d53bfcbeb39c42f3789514953f152413418d0d49 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -427,7 +427,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -445,7 +444,6 @@ */ &mmc_1 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts index d0cc300cfb4b6ae185677e9971e537f31f560559..73b7cdd5f5223cafaa99c7181d23586061f1b189 100644 --- a/arch/arm/boot/dts/exynos5260-xyref5260.dts +++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts @@ -67,7 +67,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; bypass-smu; cap-mmc-highspeed; @@ -83,7 +82,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index 6cc74d97daaea595d8b6d0ece1d10c773a71f720..9cb7726ef8d0dbc1f4bb6964acc64bc34abd566e 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -41,7 +41,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; cap-mmc-highspeed; broken-cd; card-detect-delay = <200>; @@ -53,7 +52,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index f9a75bfd3f2bfdc45575c5947f6107024d15e42a..683a4cfb4a23d469ba91670f414e27ea03d57f5a 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -699,7 +699,6 @@ /* eMMC flash */ &mmc_0 { status = "okay"; - num-slots = <1>; mmc-hs200-1_8v; cap-mmc-highspeed; non-removable; @@ -717,7 +716,6 @@ /* WiFi SDIO module */ &mmc_1 { status = "okay"; - num-slots = <1>; non-removable; cap-sdio-irq; keep-power-in-suspend; @@ -737,7 +735,6 @@ /* uSD card */ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index f92f957412073279a3be9713794bb2336dbf4752..a183b56283f8ff9e9d41d616edfc00a82d200267 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -266,6 +266,7 @@ &hdmicec { status = "okay"; + needs-hpd; }; &hsi2c_4 { diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index bc4954e69f7b148c3e33dd624e039726f0f0026a..7a00be7ea6d716e38bf979a6d9e4da7397f7dfd1 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi @@ -317,6 +317,7 @@ phys = <&pcie_phy0>; ranges = <0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0x0 0 &gic 53>; @@ -339,6 +340,7 @@ phys = <&pcie_phy1>; ranges = <0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0x0 0 &gic 56>; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 953dc8677dc888d21f4207d27de2d8268d812198..b2b95ff205e81ba9248f3f29416001459e3c3d77 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -667,7 +667,6 @@ /* eMMC flash */ &mmc_0 { status = "okay"; - num-slots = <1>; mmc-hs200-1_8v; mmc-hs400-1_8v; cap-mmc-highspeed; @@ -686,7 +685,6 @@ /* WiFi SDIO module */ &mmc_1 { status = "okay"; - num-slots = <1>; non-removable; cap-sdio-irq; keep-power-in-suspend; @@ -706,7 +704,6 @@ /* uSD card */ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts new file mode 100644 index 0000000000000000000000000000000000000000..e75e2d44371cdd7bf719ab8ac2504717f1a742b3 --- /dev/null +++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts @@ -0,0 +1,246 @@ +/* + * Device Tree file for D-Link DIR-685 Xtreme N Storage Router + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "D-Link DIR-685 Xtreme N Storage Router"; + compatible = "dlink,dir-685", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + /* 128 MB SDRAM in 2 x Hynix HY5DU121622DTP-D43 */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + stdout-path = "uart0:115200n8"; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + button-esc { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "reset"; + /* Collides with LPC_LAD[0], UART DCD, SSP 97RST */ + gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; + }; + button-eject { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "unmount"; + /* Collides with LPC LFRAME, UART RTS, SSP TXD */ + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + led-wps { + label = "dir685:blue:WPS"; + /* Collides with ICE */ + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + /* + * These two LEDs are on the side of the device. + * For electrical reasons, both LEDs cannot be active + * at the same time so only blue or orange can on at + * one time. Enabling both makes the LED go dark. + * The LEDs both sit inside the unmount button and the + * label on the case says "unmount". + */ + led-blue-hd { + label = "dir685:blue:HD"; + /* Collides with LPC_SERIRQ, UART DTR, SSP FSC pins */ + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led-orange-hd { + label = "dir685:orange:HD"; + /* Collides with LPC_LAD[2], UART DSR, SSP ECLK pins */ + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + /* + * This is a Sunon Maglev GM0502PFV2-8 cooling fan @10000 RPM. + * Since the platform has no temperature sensor, this is controlled + * from userspace by using the hard disks S.M.A.R.T. temperature + * sensor. It is turned on when the temperature exceeds 46 degrees + * and turned off when the temperatures goes below 41 degrees + * (celsius). + */ + gpio-fan { + compatible = "gpio-fan"; + /* Collides with IDE */ + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + gpio-fan,speed-map = <0 0>, <10000 1>; + #cooling-cells = <2>; + }; + + /* + * The touchpad input is connected to a GPIO bit-banged + * I2C bus. + */ + gpio-i2c { + compatible = "i2c-gpio"; + /* Collides with ICE */ + gpios = <&gpio0 5 0>, /* SDA */ + <&gpio0 6 0>; /* SCL */ + #address-cells = <1>; + #size-cells = <0>; + + touchkeys@26 { + compatible = "dlink,dir685-touchkeys"; + reg = <0x26>; + interrupt-parent = <&gpio0>; + /* Collides with NAND flash */ + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 32MB of flash */ + reg = <0x30000000 0x02000000>; + + /* + * This "RedBoot" is the Storlink derivative. + */ + partition@0 { + label = "RedBoot"; + reg = <0x00000000 0x00040000>; + read-only; + }; + /* + * Between the boot loader and the rootfs is the kernel + * in a custom Storlink format flashed from the boot + * menu. The rootfs is in squashfs format. + */ + partition@1800c0 { + label = "rootfs"; + reg = <0x001800c0 0x01dbff40>; + read-only; + }; + partition@1f40000 { + label = "upgrade"; + reg = <0x01f40000 0x00040000>; + read-only; + }; + partition@1f80000 { + label = "rgdb"; + reg = <0x01f80000 0x00040000>; + read-only; + }; + /* + * This partition contains MAC addresses for WAN, + * WLAN and LAN, and the country code (for wireless + * I guess). + */ + partition@1fc0000 { + label = "nvram"; + reg = <0x01fc0000 0x00020000>; + read-only; + }; + partition@1fe0000 { + label = "LangPack"; + reg = <0x01fe0000 0x00020000>; + read-only; + }; + }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0bgrp cover line 5, 6 used by TK I2C + * gpio0bgrp cover line 7 used by WPS LED + * gpio0cgrp cover line 8, 13 used by keys + * and 11, 12 used by the HD LEDs + * gpio0egrp cover line 16 used by VDISP + * gpio0fgrp cover line 17 used by TK IRQ + * gpio0ggrp cover line 20 used by panel CS + * gpio0hgrp cover line 21,22 used by RTL8366RB + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0bgrp", + "gpio0cgrp", + "gpio0egrp", + "gpio0fgrp", + "gpio0ggrp", + "gpio0hgrp"; + }; + }; + /* + * gpio1bgrp cover line 5,8,7 used by panel SPI + * also line 6 used by the fan + * + */ + gpio1_default_pins: pinctrl-gpio1 { + mux { + function = "gpio1"; + groups = "gpio1bgrp"; + }; + }; + }; + }; + + sata: sata@46000000 { + cortina,gemini-ata-muxmode = <0>; + cortina,gemini-enable-sata-bridge; + status = "okay"; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; + + gpio1: gpio@4e000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; + + pci@50000000 { + status = "okay"; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = + <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */ + <0x4800 0 0 2 &pci_intc 1>, + <0x4800 0 0 3 &pci_intc 2>, + <0x4800 0 0 4 &pci_intc 3>, + <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */ + <0x5000 0 0 2 &pci_intc 2>, + <0x5000 0 0 3 &pci_intc 3>, + <0x5000 0 0 4 &pci_intc 0>, + <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */ + <0x5800 0 0 2 &pci_intc 3>, + <0x5800 0 0 3 &pci_intc 0>, + <0x5800 0 0 4 &pci_intc 1>, + <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */ + <0x6000 0 0 2 &pci_intc 0>, + <0x6000 0 0 3 &pci_intc 1>, + <0x6000 0 0 4 &pci_intc 2>; + }; + + ata@63000000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts index 55f6a4f1f8016754274af65ed6895b7e8ab47a3f..b4fc58c8cf8d7b855a5a686beb2dfedede1add50 100644 --- a/arch/arm/boot/dts/gemini-nas4220b.dts +++ b/arch/arm/boot/dts/gemini-nas4220b.dts @@ -33,6 +33,7 @@ wakeup-source; linux,code = ; label = "Backup button"; + /* Conflict with TVC */ gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; }; button@31 { @@ -40,6 +41,7 @@ wakeup-source; linux,code = ; label = "Softreset button"; + /* Conflict with TVC */ gpios = <&gpio1 31 GPIO_ACTIVE_LOW>; }; }; @@ -48,11 +50,13 @@ compatible = "gpio-leds"; led@28 { label = "nas4220b:orange:hdd"; + /* Conflict with TVC */ gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; default-state = "on"; }; led@30 { label = "nas4220b:green:os"; + /* Conflict with TVC */ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; @@ -99,12 +103,32 @@ }; }; + syscon: syscon@40000000 { + pinctrl { + /* + * gpio1dgrp cover line 28-31 otherwise used + * by TVC. + */ + gpio1_default_pins: pinctrl-gpio1 { + mux { + function = "gpio1"; + groups = "gpio1dgrp"; + }; + }; + }; + }; + sata: sata@46000000 { cortina,gemini-ata-muxmode = <0>; cortina,gemini-enable-sata-bridge; status = "okay"; }; + gpio1: gpio@4e000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; + ata@63000000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts index 7b920bfbda32cfcf01b63e022c8787cff60cdcba..3613b264f45faff79459cb5d9daf76f158406e08 100644 --- a/arch/arm/boot/dts/gemini-rut1xx.dts +++ b/arch/arm/boot/dts/gemini-rut1xx.dts @@ -33,6 +33,7 @@ wakeup-source; linux,code = ; label = "Reset to defaults"; + /* Conflict with TVC */ gpios = <&gpio1 28 GPIO_ACTIVE_LOW>; }; }; @@ -42,12 +43,14 @@ led@7 { /* FIXME: add the LED color */ label = "rut1xx::gsm"; + /* Conflict with ICE */ gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; default-state = "on"; }; led@31 { /* FIXME: add the LED color */ label = "rut1xx::power"; + /* Conflict with NAND CE0 */ gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; default-state = "off"; linux,default-trigger = "heartbeat"; @@ -61,5 +64,41 @@ reg = <0x30000000 0x00800000>; /* TODO: add flash partitions here */ }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0bgrp cover line 7 used by GSM LED + * gpio0fgrp cover line 17 used by power LED + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0bgrp", + "gpio0fgrp"; + }; + }; + /* + * gpio1dgrp cover line 28-31 otherwise used + * by TVC. + */ + gpio1_default_pins: pinctrl-gpio1 { + mux { + function = "gpio1"; + groups = "gpio1dgrp"; + }; + }; + }; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; + + gpio1: gpio@4e000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; }; }; diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts index 4d200f0bcd451ac780b23ec1f181c056befcc057..7cfa9caf47d4e642031a2315bd41f743ace7a75b 100644 --- a/arch/arm/boot/dts/gemini-sq201.dts +++ b/arch/arm/boot/dts/gemini-sq201.dts @@ -33,6 +33,7 @@ wakeup-source; linux,code = ; label = "factory reset"; + /* Conflict with NAND flash */ gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; }; }; @@ -41,12 +42,14 @@ compatible = "gpio-leds"; led@20 { label = "sq201:green:info"; + /* Conflict with parallel flash */ gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; }; led@31 { label = "sq201:green:usb"; + /* Conflict with parallel and NAND flash */ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; default-state = "off"; linux,default-trigger = "usb-host"; @@ -55,7 +58,15 @@ soc { flash@30000000 { - status = "okay"; + /* + * Flash access can be enabled, with the side effect + * of disabling access to GPIO LED on GPIO0[20] which + * reuse one of the parallel flash chip select lines. + * Also the default firmware on the machine has the + * problem that since it uses the flash, the two LEDS + * on the right become numb. + */ + /* status = "okay"; */ /* 16MB of flash */ reg = <0x30000000 0x01000000>; @@ -93,12 +104,35 @@ }; }; + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0fgrp cover line 18 used by reset button + * gpio0ggrp cover line 20 used by info LED + * gpio0kgrp cover line 31 used by USB LED + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0fgrp", + "gpio0ggrp", + "gpio0kgrp"; + }; + }; + }; + }; + sata: sata@46000000 { cortina,gemini-ata-muxmode = <0>; cortina,gemini-enable-sata-bridge; status = "okay"; }; + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; + pci@50000000 { status = "okay"; interrupt-map-mask = <0xf800 0 0 7>; diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts index 63b756e3bf5a2fcdd42eb8a3fe6760e36878be85..38a49e7504785077bd809a078d082fd51a2f4dbf 100644 --- a/arch/arm/boot/dts/gemini-wbd111.dts +++ b/arch/arm/boot/dts/gemini-wbd111.dts @@ -33,6 +33,7 @@ wakeup-source; linux,code = ; label = "reset"; + /* Conflict with ICE */ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; }; }; @@ -42,21 +43,25 @@ led@1 { label = "wbd111:red:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@2 { label = "wbd111:green:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@3 { label = "wbd111:red:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@5 { label = "wbd111:green:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; @@ -98,5 +103,26 @@ read-only; }; }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0agrp cover line 0-4 + * gpio0bgrp cover line 5 + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0agrp", + "gpio0bgrp"; + }; + }; + }; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; }; }; diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts index 9747f5a47807b4679f7cdd8476c9da58c5b78b9c..f77e34e0df0bcdead3b341dd1e155deaee10b37b 100644 --- a/arch/arm/boot/dts/gemini-wbd222.dts +++ b/arch/arm/boot/dts/gemini-wbd222.dts @@ -33,6 +33,7 @@ wakeup-source; linux,code = ; label = "reset"; + /* Conflict with ICE */ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; }; }; @@ -42,21 +43,25 @@ led@1 { label = "wbd111:red:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@2 { label = "wbd111:green:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@3 { label = "wbd111:red:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@5 { label = "wbd111:green:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; @@ -98,5 +103,26 @@ read-only; }; }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0agrp cover line 0-4 + * gpio0bgrp cover line 5 + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0agrp", + "gpio0bgrp"; + }; + }; + }; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; }; }; diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi index 141d8d3a1d07bfab1c0df4e5f559ac2075828793..c68e8d430234c3824198d46b336f0d689cf38611 100644 --- a/arch/arm/boot/dts/gemini.dtsi +++ b/arch/arm/boot/dts/gemini.dtsi @@ -5,6 +5,8 @@ /include/ "skeleton.dtsi" #include +#include +#include #include / { @@ -18,6 +20,8 @@ flash@30000000 { compatible = "cortina,gemini-flash", "cfi-flash"; syscon = <&syscon>; + pinctrl-names = "default"; + pinctrl-0 = <&pflash_default_pins>; bank-width = <2>; #address-cells = <1>; #size-cells = <1>; @@ -39,22 +43,123 @@ /* RESET_GLOBAL | RESET_CPU1 */ mask = <0xC0000000>; }; + + pinctrl { + compatible = "cortina,gemini-pinctrl"; + regmap = <&syscon>; + /* Hog the DRAM pins */ + pinctrl-names = "default"; + pinctrl-0 = <&dram_default_pins>, <&system_default_pins>, + <&vcontrol_default_pins>; + + dram_default_pins: pinctrl-dram { + mux { + function = "dram"; + groups = "dramgrp"; + }; + }; + rtc_default_pins: pinctrl-rtc { + mux { + function = "rtc"; + groups = "rtcgrp"; + }; + }; + power_default_pins: pinctrl-power { + mux { + function = "power"; + groups = "powergrp"; + }; + }; + cir_default_pins: pinctrl-cir { + mux { + function = "cir"; + groups = "cirgrp"; + }; + }; + system_default_pins: pinctrl-system { + mux { + function = "system"; + groups = "systemgrp"; + }; + }; + vcontrol_default_pins: pinctrl-vcontrol { + mux { + function = "vcontrol"; + groups = "vcontrolgrp"; + }; + }; + ice_default_pins: pinctrl-ice { + mux { + function = "ice"; + groups = "icegrp"; + }; + }; + uart_default_pins: pinctrl-uart { + mux { + function = "uart"; + groups = "uartrxtxgrp"; + }; + }; + pflash_default_pins: pinctrl-pflash { + mux { + function = "pflash"; + groups = "pflashgrp"; + }; + }; + usb_default_pins: pinctrl-usb { + mux { + function = "usb"; + groups = "usbgrp"; + }; + }; + gmii_default_pins: pinctrl-gmii { + mux { + function = "gmii"; + groups = "gmiigrp"; + }; + }; + pci_default_pins: pinctrl-pci { + mux { + function = "pci"; + groups = "pcigrp"; + }; + }; + sata_default_pins: pinctrl-sata { + mux { + function = "sata"; + groups = "satagrp"; + }; + }; + /* Activate both groups of pins for this state */ + sata_and_ide_pins: pinctrl-sata-ide { + mux0 { + function = "sata"; + groups = "satagrp"; + }; + mux1 { + function = "ide"; + groups = "idegrp"; + }; + }; + }; }; watchdog@41000000 { compatible = "cortina,gemini-watchdog"; reg = <0x41000000 0x1000>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 23>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_WDOG>; + clocks = <&syscon GEMINI_CLK_APB>; }; uart0: serial@42000000 { compatible = "ns16550a"; reg = <0x42000000 0x100>; - resets = <&syscon 18>; - clocks = <&syscon 6>; + resets = <&syscon GEMINI_RESET_UART>; + clocks = <&syscon GEMINI_CLK_UART>; interrupts = <18 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart_default_pins>; reg-shift = <2>; }; @@ -65,9 +170,9 @@ interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */ <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */ <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */ - resets = <&syscon 17>; + resets = <&syscon GEMINI_RESET_TIMER>; /* APB clock or RTC clock */ - clocks = <&syscon 2>, <&syscon 0>; + clocks = <&syscon GEMINI_CLK_APB>, <&syscon GEMINI_CLK_RTC>; clock-names = "PCLK", "EXTCLK"; syscon = <&syscon>; }; @@ -76,20 +181,30 @@ compatible = "cortina,gemini-rtc"; reg = <0x45000000 0x100>; interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 16>; - clocks = <&syscon 2>, <&syscon 0>; + resets = <&syscon GEMINI_RESET_RTC>; + clocks = <&syscon GEMINI_CLK_APB>, <&syscon GEMINI_CLK_RTC>; clock-names = "PCLK", "EXTCLK"; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_default_pins>; }; sata: sata@46000000 { compatible = "cortina,gemini-sata-bridge"; reg = <0x46000000 0x100>; - resets = <&syscon 26>, - <&syscon 27>; + resets = <&syscon GEMINI_RESET_SATA0>, + <&syscon GEMINI_RESET_SATA1>; reset-names = "sata0", "sata1"; - clocks = <&syscon 10>, - <&syscon 11>; + clocks = <&syscon GEMINI_CLK_GATE_SATA0>, + <&syscon GEMINI_CLK_GATE_SATA1>; clock-names = "SATA0_PCLK", "SATA1_PCLK"; + /* + * This defines the special "ide" state that needs + * to be explicitly enabled to enable the IDE pins, + * as these pins are normally used for other things. + */ + pinctrl-names = "default", "ide"; + pinctrl-0 = <&sata_default_pins>; + pinctrl-1 = <&sata_and_ide_pins>; syscon = <&syscon>; status = "disabled"; }; @@ -97,7 +212,7 @@ intcon: interrupt-controller@48000000 { compatible = "faraday,ftintc010"; reg = <0x48000000 0x1000>; - resets = <&syscon 14>; + resets = <&syscon GEMINI_RESET_INTCON0>; interrupt-controller; #interrupt-cells = <2>; }; @@ -106,14 +221,16 @@ compatible = "cortina,gemini-power-controller"; reg = <0x4b000000 0x100>; interrupts = <26 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&power_default_pins>; }; gpio0: gpio@4d000000 { compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4d000000 0x100>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 20>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_GPIO0>; + clocks = <&syscon GEMINI_CLK_APB>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -124,8 +241,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4e000000 0x100>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 21>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_GPIO1>; + clocks = <&syscon GEMINI_CLK_APB>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -136,8 +253,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4f000000 0x100>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 22>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_GPIO2>; + clocks = <&syscon GEMINI_CLK_APB>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -151,9 +268,11 @@ * to configure the host bridge. */ reg = <0x50000000 0x100>; - resets = <&syscon 7>; - clocks = <&syscon 15>, <&syscon 4>; + resets = <&syscon GEMINI_RESET_PCI>; + clocks = <&syscon GEMINI_CLK_GATE_PCI>, <&syscon GEMINI_CLK_PCI>; clock-names = "PCLK", "PCICLK"; + pinctrl-names = "default"; + pinctrl-0 = <&pci_default_pins>; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; @@ -193,8 +312,8 @@ compatible = "cortina,gemini-pata", "faraday,ftide010"; reg = <0x63000000 0x1000>; interrupts = <4 IRQ_TYPE_EDGE_RISING>; - resets = <&syscon 2>; - clocks = <&syscon 14>; + resets = <&syscon GEMINI_RESET_IDE>; + clocks = <&syscon GEMINI_CLK_GATE_IDE>; clock-names = "PCLK"; sata = <&sata>; status = "disabled"; @@ -204,8 +323,8 @@ compatible = "cortina,gemini-pata", "faraday,ftide010"; reg = <0x63400000 0x1000>; interrupts = <5 IRQ_TYPE_EDGE_RISING>; - resets = <&syscon 2>; - clocks = <&syscon 14>; + resets = <&syscon GEMINI_RESET_IDE>; + clocks = <&syscon GEMINI_CLK_GATE_IDE>; clock-names = "PCLK"; sata = <&sata>; status = "disabled"; @@ -217,8 +336,8 @@ arm,primecell-periphid = <0x0003b080>; reg = <0x67000000 0x1000>; interrupts = <9 IRQ_TYPE_EDGE_RISING>; - resets = <&syscon 10>; - clocks = <&syscon 1>; + resets = <&syscon GEMINI_RESET_DMAC>; + clocks = <&syscon GEMINI_CLK_AHB>; clock-names = "apb_pclk"; /* Bus interface AHB1 (AHB0) is totally tilted */ lli-bus-interface-ahb2; diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index dfcc8e00cf1c53a753dc753c2c5598b220b480a1..09ce8b81fafa477b7d04a0e382dee57125088b20 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -297,6 +297,7 @@ #address-cells = <1>; #size-cells = <1>; status = "disabled"; + ranges; adc: adc@50030800 { compatible = "fsl,imx25-gcq"; @@ -451,6 +452,13 @@ interrupt-names = "scm", "smn"; }; + rngb: rngb@53fb0000 { + compatible = "fsl,imx25-rngb"; + reg = <0x53fb0000 0x4000>; + clocks = <&clks 109>; + interrupts = <22>; + }; + esdhc1: esdhc@53fb4000 { compatible = "fsl,imx25-esdhc"; reg = <0x53fb4000 0x4000>; diff --git a/arch/arm/boot/dts/imx53-cx9020.dts b/arch/arm/boot/dts/imx53-cx9020.dts new file mode 100644 index 0000000000000000000000000000000000000000..4f54fd4418a33e05bafbbca05827ca554d9b8feb --- /dev/null +++ b/arch/arm/boot/dts/imx53-cx9020.dts @@ -0,0 +1,297 @@ +/* + * Copyright 2017 Beckhoff Automation GmbH & Co. KG + * based on imx53-qsb.dts + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx53.dtsi" + +/ { + model = "Beckhoff CX9020 Embedded PC"; + compatible = "bhf,cx9020", "fsl,imx53"; + + chosen { + stdout-path = &uart2; + }; + + memory { + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; + }; + + display-0 { + #address-cells =<1>; + #size-cells = <0>; + compatible = "fsl,imx-parallel-display"; + interface-pix-fmt = "rgb24"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu_disp0>; + + port@0 { + reg = <0>; + + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; + + port@1 { + reg = <1>; + + display0_out: endpoint { + remote-endpoint = <&tfp410_in>; + }; + }; + }; + + dvi-connector { + compatible = "dvi-connector"; + ddc-i2c-bus = <&i2c2>; + digital; + + port { + dvi_connector_in: endpoint { + remote-endpoint = <&tfp410_out>; + }; + }; + }; + + dvi-converter { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ti,tfp410"; + + port@0 { + reg = <0>; + + tfp410_in: endpoint { + remote-endpoint = <&display0_out>; + }; + }; + + port@1 { + reg = <1>; + + tfp410_out: endpoint { + remote-endpoint = <&dvi_connector_in>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pwr-r { + gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + pwr-g { + gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + pwr-b { + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + sd1-b { + linux,default-trigger = "mmc0"; + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + }; + + sd2-b { + linux,default-trigger = "mmc1"; + gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>; + }; + }; + + regulator-3p2v { + compatible = "regulator-fixed"; + regulator-name = "3P2V"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-always-on; + }; + + reg_usb_vbus: regulator-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&esdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_esdhc1>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + bus-width = <4>; + status = "okay"; +}; + +&esdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_esdhc2>; + cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + bus-width = <4>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec>; + phy-mode = "rmii"; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + fsl,dte-mode; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_vbus>; + phy_type = "utmi"; + status = "okay"; +}; + +&usbotg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hoggrp { + fsl,pins = < + MX53_PAD_GPIO_0__CCM_CLKO 0x1c4 + MX53_PAD_GPIO_16__I2C3_SDA 0x1c4 + MX53_PAD_EIM_D22__GPIO3_22 0x1c4 + MX53_PAD_EIM_D23__GPIO3_23 0x1e4 + MX53_PAD_EIM_D24__GPIO3_24 0x1e4 + >; + }; + + pinctrl_esdhc1: esdhc1grp { + fsl,pins = < + MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5 + MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5 + MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5 + MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5 + MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5 + MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5 + MX53_PAD_GPIO_1__ESDHC1_CD 0x1c4 + MX53_PAD_EIM_D17__GPIO3_17 0x1e4 + MX53_PAD_GPIO_3__GPIO1_3 0x1c4 + >; + }; + + pinctrl_esdhc2: esdhc2grp { + fsl,pins = < + MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5 + MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5 + MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5 + MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5 + MX53_PAD_SD2_CMD__ESDHC2_CMD 0x1d5 + MX53_PAD_SD2_CLK__ESDHC2_CLK 0x1d5 + MX53_PAD_GPIO_4__ESDHC2_CD 0x1e4 + MX53_PAD_EIM_D20__GPIO3_20 0x1e4 + MX53_PAD_GPIO_8__GPIO1_8 0x1c4 + >; + }; + + pinctrl_fec: fecgrp { + fsl,pins = < + MX53_PAD_FEC_MDC__FEC_MDC 0x4 + MX53_PAD_FEC_MDIO__FEC_MDIO 0x1fc + MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x180 + MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x180 + MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x180 + MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x180 + MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x180 + MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x4 + MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x4 + MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x4 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000 + MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000 + >; + }; + + pinctrl_ipu_disp0: ipudisp0grp { + fsl,pins = < + MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5 + MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 0x5 + MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 0x5 + MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 0x5 + MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 0x5 + MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 0x5 + MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 0x5 + MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 0x5 + MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 0x5 + MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 0x5 + MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 0x5 + MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 0x5 + MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 0x5 + MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 0x5 + MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 0x5 + MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 0x5 + MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 0x5 + MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 0x5 + MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 0x5 + MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 0x5 + MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 0x5 + MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 0x5 + MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 0x5 + MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 0x5 + MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 0x5 + MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 0x5 + MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 0x5 + MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 0x5 + MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 0x5 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX53_PAD_EIM_D26__UART2_RXD_MUX 0x1e4 + MX53_PAD_EIM_D27__UART2_TXD_MUX 0x1e4 + MX53_PAD_EIM_D28__UART2_RTS 0x1e4 + MX53_PAD_EIM_D29__UART2_CTS 0x1e4 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx53-pinfunc.h b/arch/arm/boot/dts/imx53-pinfunc.h index aec406bc65eb70ce2a0980a9779d7e6e6913e26f..59f9c29e3fe2ff37a626a2bdf51bdbff44d844cf 100644 --- a/arch/arm/boot/dts/imx53-pinfunc.h +++ b/arch/arm/boot/dts/imx53-pinfunc.h @@ -524,6 +524,7 @@ #define MX53_PAD_EIM_D25__UART1_DSR 0x140 0x488 0x000 0x7 0x0 #define MX53_PAD_EIM_D26__EMI_WEIM_D_26 0x144 0x48c 0x000 0x0 0x0 #define MX53_PAD_EIM_D26__GPIO3_26 0x144 0x48c 0x000 0x1 0x0 +#define MX53_PAD_EIM_D26__UART2_RXD_MUX 0x144 0x48c 0x880 0x2 0x0 #define MX53_PAD_EIM_D26__UART2_TXD_MUX 0x144 0x48c 0x000 0x2 0x0 #define MX53_PAD_EIM_D26__FIRI_RXD 0x144 0x48c 0x80c 0x3 0x0 #define MX53_PAD_EIM_D26__IPU_CSI0_D_1 0x144 0x48c 0x000 0x4 0x0 @@ -533,6 +534,7 @@ #define MX53_PAD_EIM_D27__EMI_WEIM_D_27 0x148 0x490 0x000 0x0 0x0 #define MX53_PAD_EIM_D27__GPIO3_27 0x148 0x490 0x000 0x1 0x0 #define MX53_PAD_EIM_D27__UART2_RXD_MUX 0x148 0x490 0x880 0x2 0x1 +#define MX53_PAD_EIM_D27__UART2_TXD_MUX 0x148 0x490 0x000 0x2 0x0 #define MX53_PAD_EIM_D27__FIRI_TXD 0x148 0x490 0x000 0x3 0x0 #define MX53_PAD_EIM_D27__IPU_CSI0_D_0 0x148 0x490 0x000 0x4 0x0 #define MX53_PAD_EIM_D27__IPU_DI1_PIN13 0x148 0x490 0x000 0x5 0x0 @@ -541,6 +543,7 @@ #define MX53_PAD_EIM_D28__EMI_WEIM_D_28 0x14c 0x494 0x000 0x0 0x0 #define MX53_PAD_EIM_D28__GPIO3_28 0x14c 0x494 0x000 0x1 0x0 #define MX53_PAD_EIM_D28__UART2_CTS 0x14c 0x494 0x000 0x2 0x0 +#define MX53_PAD_EIM_D28__UART2_RTS 0x14c 0x494 0x87c 0x2 0x0 #define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO 0x14c 0x494 0x82c 0x3 0x1 #define MX53_PAD_EIM_D28__CSPI_MOSI 0x14c 0x494 0x788 0x4 0x1 #define MX53_PAD_EIM_D28__I2C1_SDA 0x14c 0x494 0x818 0x5 0x1 @@ -548,6 +551,7 @@ #define MX53_PAD_EIM_D28__IPU_DI0_PIN13 0x14c 0x494 0x000 0x7 0x0 #define MX53_PAD_EIM_D29__EMI_WEIM_D_29 0x150 0x498 0x000 0x0 0x0 #define MX53_PAD_EIM_D29__GPIO3_29 0x150 0x498 0x000 0x1 0x0 +#define MX53_PAD_EIM_D29__UART2_CTS 0x150 0x498 0x000 0x2 0x0 #define MX53_PAD_EIM_D29__UART2_RTS 0x150 0x498 0x87c 0x2 0x1 #define MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS 0x150 0x498 0x000 0x3 0x0 #define MX53_PAD_EIM_D29__CSPI_SS0 0x150 0x498 0x78c 0x4 0x2 diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 2e516f4985e4cd2e470f8ddb0195a34821a1d09d..8bf0d89cdd355cf0c9484335476e08fb0fca1b5e 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -433,6 +433,15 @@ clock-names = "ipg", "per"; }; + srtc: srtc@53fa4000 { + compatible = "fsl,imx53-rtc", "fsl,imx25-rtc"; + reg = <0x53fa4000 0x4000>; + interrupts = <24>; + interrupt-parent = <&tzic>; + clocks = <&clks IMX5_CLK_SRTC_GATE>; + clock-names = "ipg"; + }; + iomuxc: iomuxc@53fa8000 { compatible = "fsl,imx53-iomuxc"; reg = <0x53fa8000 0x4000>; diff --git a/arch/arm/boot/dts/imx6dl-gw52xx.dts b/arch/arm/boot/dts/imx6dl-gw52xx.dts index a2e0b73fdd4a78440aac51149d9b251fc04707af..5f9f8948100deb2440ccf487d022d2ec75f1b736 100644 --- a/arch/arm/boot/dts/imx6dl-gw52xx.dts +++ b/arch/arm/boot/dts/imx6dl-gw52xx.dts @@ -17,3 +17,61 @@ model = "Gateworks Ventana i.MX6 DualLite/Solo GW52XX"; compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl"; }; + +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi1_from_ipu1_csi1_mux { + bus-width = <8>; +}; + +&ipu1_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi1_mux>; + bus-width = <8>; +}; + +&ipu1_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu1_csi1: ipu1_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-gw53xx.dts b/arch/arm/boot/dts/imx6dl-gw53xx.dts index 6844b708d2f89ec09b6da02f0965fad905ed0b3d..9bfc620d37bd0601d925b0dc7faa9e9d0aa3f032 100644 --- a/arch/arm/boot/dts/imx6dl-gw53xx.dts +++ b/arch/arm/boot/dts/imx6dl-gw53xx.dts @@ -17,3 +17,61 @@ model = "Gateworks Ventana i.MX6 DualLite/Solo GW53XX"; compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl"; }; + +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi1_from_ipu1_csi1_mux { + bus-width = <8>; +}; + +&ipu1_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi1_mux>; + bus-width = <8>; +}; + +&ipu1_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu1_csi1: ipu1_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-gw54xx.dts b/arch/arm/boot/dts/imx6dl-gw54xx.dts index be915412f852ea5af34121808ecc22b04c592b4e..b909bdf9a2efcc2c1e8ff89a0a57fc79638e1f14 100644 --- a/arch/arm/boot/dts/imx6dl-gw54xx.dts +++ b/arch/arm/boot/dts/imx6dl-gw54xx.dts @@ -17,3 +17,61 @@ model = "Gateworks Ventana i.MX6 DualLite/Solo GW54XX"; compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl"; }; + +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi1_from_ipu1_csi1_mux { + bus-width = <8>; +}; + +&ipu1_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi1_mux>; + bus-width = <8>; +}; + +&ipu1_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu1_csi1: ipu1_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts index 29b45f2e64e0ad1073a9289588601cbcfb358719..275c6c05219dbdc54ba4c994459a45506608e65b 100644 --- a/arch/arm/boot/dts/imx6dl-riotboard.dts +++ b/arch/arm/boot/dts/imx6dl-riotboard.dts @@ -101,6 +101,51 @@ status = "okay"; }; +&gpio1 { + gpio-line-names = + "", "", "SD2_WP", "", "SD2_CD", "I2C3_SCL", + "I2C3_SDA", "I2C4_SCL", + "I2C4_SDA", "", "", "", "", "", "", "", + "", "PWM3", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "USB_OTG_VBUS", "", + "UART3_TXD", "UART3_RXD", "", "", "EIM_D28", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "", "UART4_TXD", "UART4_RXD", + "UART5_TXD", "UART5_RXD", "", "", "", "", "", "", + "GPIO4_16", "GPIO4_17", "GPIO4_18", "GPIO4_19", "", + "CSPI3_CLK", "CSPI3_MOSI", "CSPI3_MISO", + "CSPI3_CS0", "CSPI3_CS1", "GPIO4_26", "GPIO4_27", + "CSPI3_RDY", "PWM1", "PWM2", "GPIO4_31"; +}; + +&gpio5 { + gpio-line-names = + "", "", "EIM_A25", "", "", "GPIO5_05", "GPIO5_06", + "GPIO5_07", + "GPIO5_08", "CSPI2_CS1", "CSPI2_MOSI", "CSPI2_MISO", + "CSPI2_CS0", "CSPI2_CLK", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio7 { + gpio-line-names = + "SD3_CD", "SD3_WP", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + &hdmi { ddc-i2c-bus = <&i2c2>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-apalis-eval.dts b/arch/arm/boot/dts/imx6q-apalis-eval.dts new file mode 100644 index 0000000000000000000000000000000000000000..4bbfe3d6102756178a14e76a4b60b1c02dfead96 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-apalis-eval.dts @@ -0,0 +1,278 @@ +/* + * Copyright 2014-2017 Toradex AG + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include +#include +#include "imx6q.dtsi" +#include "imx6qdl-apalis.dtsi" + +/ { + model = "Toradex Apalis iMX6Q/D Module on Apalis Evaluation Board"; + compatible = "toradex,apalis_imx6q-eval", "toradex,apalis_imx6q", + "fsl,imx6q"; + + aliases { + i2c0 = &i2c1; + i2c1 = &i2c3; + i2c2 = &i2c2; + rtc0 = &rtc_i2c; + rtc1 = &snvs_rtc; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + wakeup { + label = "Wake-Up"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + lcd_display: display@di0 { + compatible = "fsl,imx-parallel-display"; + #address-cells = <1>; + #size-cells = <0>; + interface-pix-fmt = "rgb24"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_lcdif>; + status = "okay"; + + port@0 { + reg = <0>; + + lcd_display_in: endpoint { + remote-endpoint = <&ipu1_di1_disp1>; + }; + }; + + port@1 { + reg = <1>; + + lcd_display_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; + }; + + panel: panel { + /* + * edt,et057090dhu: EDT 5.7" LCD TFT + * edt,et070080dh6: EDT 7.0" LCD TFT + */ + compatible = "edt,et057090dhu"; + backlight = <&backlight>; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcd_display_out>; + }; + }; + }; + + reg_pcie_switch: regulator-pcie-switch { + compatible = "regulator-fixed"; + regulator-name = "pcie_switch"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; + startup-delay-us = <100000>; + enable-active-high; + status = "okay"; + }; +}; + +&backlight { + brightness-levels = <0 127 191 223 239 247 251 255>; + default-brightness-level = <1>; + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&can2 { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +&i2c1 { + status = "okay"; + + pcie-switch@58 { + compatible = "plx,pex8605"; + reg = <0x58>; + }; + + /* M41T0M6 real time clock on carrier board */ + rtc_i2c: rtc@68 { + compatible = "st,m41t00"; + reg = <0x68>; + }; +}; + +/* + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) + */ +&i2c3 { + status = "okay"; +}; + +&ipu1_di1_disp1 { + remote-endpoint = <&lcd_display_in>; +}; + +&ldb { + status = "okay"; +}; + +&pcie { + /* active-high meaning opposite of regular PERST# active-low polarity */ + reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + reset-gpio-active-high; + vpcie-supply = <®_pcie_switch>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +®_usb_otg_vbus { + status = "okay"; +}; + +®_usb_host_vbus { + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&sound_spdif { + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + status = "okay"; +}; + +/* MMC1 */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit &pinctrl_mmc_cd>; + cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +/* SD1 */ +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_sd_cd>; + cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&iomuxc { + /* + * Mux the Apalis GPIOs + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 + &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 + &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6 + &pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8 + >; +}; diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts new file mode 100644 index 0000000000000000000000000000000000000000..a35c7a54ad3b5484be85987024d771e42fb01bb1 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts @@ -0,0 +1,291 @@ +/* + * Copyright 2014-2017 Toradex AG + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include +#include +#include "imx6q.dtsi" +#include "imx6qdl-apalis.dtsi" + +/ { + model = "Toradex Apalis iMX6Q/D Module on Ixora Carrier Board V1.1"; + compatible = "toradex,apalis_imx6q-ixora-v1.1", + "toradex,apalis_imx6q-ixora", "toradex,apalis_imx6q", + "fsl,imx6q"; + + aliases { + i2c0 = &i2c1; + i2c1 = &i2c3; + i2c2 = &i2c2; + rtc0 = &rtc_i2c; + rtc1 = &snvs_rtc; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + wakeup { + label = "Wake-Up"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + lcd_display: display@di0 { + compatible = "fsl,imx-parallel-display"; + #address-cells = <1>; + #size-cells = <0>; + interface-pix-fmt = "rgb24"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_lcdif>; + status = "okay"; + + port@0 { + reg = <0>; + + lcd_display_in: endpoint { + remote-endpoint = <&ipu1_di1_disp1>; + }; + }; + + port@1 { + reg = <1>; + + lcd_display_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; + }; + + panel: panel { + /* + * edt,et057090dhu: EDT 5.7" LCD TFT + * edt,et070080dh6: EDT 7.0" LCD TFT + */ + compatible = "edt,et057090dhu"; + backlight = <&backlight>; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcd_display_out>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds_ixora>; + + led4-green { + label = "LED_4_GREEN"; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + + led4-red { + label = "LED_4_RED"; + gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; + }; + + led5-green { + label = "LED_5_GREEN"; + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + }; + + led5-red { + label = "LED_5_RED"; + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&backlight { + brightness-levels = <0 127 191 223 239 247 251 255>; + default-brightness-level = <1>; + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&can2 { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +&i2c1 { + status = "okay"; + + /* M41T0M6 real time clock on carrier board */ + rtc_i2c: rtc@68 { + compatible = "st,m41t00"; + reg = <0x68>; + }; +}; + +/* + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) + */ +&i2c3 { + status = "okay"; +}; + +&ipu1_di1_disp1 { + remote-endpoint = <&lcd_display_in>; +}; + +&ldb { + status = "okay"; +}; + +&pcie { + /* active-high meaning opposite of regular PERST# active-low polarity */ + reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + reset-gpio-active-high; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +®_usb_otg_vbus { + status = "okay"; +}; + +®_usb_host_vbus { + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&sound_spdif { + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + status = "okay"; +}; + +/* MMC1 */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_mmc_cd>; + cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>; + bus-width = <4>; + status = "okay"; +}; + +&iomuxc { + /* + * Mux the Apalis GPIOs + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 + &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 + &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6 + &pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8 + >; + + pinctrl_leds_ixora: ledsixoragrp { + fsl,pins = < + MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0 + MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0 + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts index 88cc7f51a4e902fb323a7c8956acaee442d2e425..60d33e99de76037cf546c8000ade4304c959c1c6 100644 --- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts +++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 Toradex AG + * Copyright 2014-2017 Toradex AG * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * @@ -55,13 +55,9 @@ "fsl,imx6q"; aliases { - i2c0 = &i2cddc; - i2c1 = &i2c1; + i2c0 = &i2c1; + i2c1 = &i2c3; i2c2 = &i2c2; - i2c3 = &i2c3; - }; - - aliases { rtc0 = &rtc_i2c; rtc1 = &snvs_rtc; }; @@ -164,15 +160,10 @@ }; &hdmi { - ddc-i2c-bus = <&i2cddc>; - status = "okay"; -}; - -&i2cddc { status = "okay"; }; -/* GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ &i2c1 { status = "okay"; @@ -188,6 +179,14 @@ }; }; +/* + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) + */ +&i2c3 { + status = "okay"; +}; + &ipu1_di1_disp1 { remote-endpoint = <&lcd_display_in>; }; @@ -268,16 +267,13 @@ /* SD1 */ &usdhc2 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sd_cd>; + pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_sd_cd>; cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; status = "okay"; }; &iomuxc { - /* - * Mux the Apalis GPIOs - * GPIO5, 6 used by optional fusion_F0710A kernel module - */ + /* Mux the Apalis GPIOs */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts index 2c1e98e0cf7bf469593f0d28f9a830b73deb35bb..46bdc67227157cfd146986d0237abdf4c5cf2226 100644 --- a/arch/arm/boot/dts/imx6q-b850v3.dts +++ b/arch/arm/boot/dts/imx6q-b850v3.dts @@ -57,7 +57,7 @@ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, - <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>; + <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>; assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi index c90b26f00e24c8395b3ebd2d0d20f1a2481e0a33..1015e55ca8f7bd9eaa2edf68ed499f577fbac083 100644 --- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi +++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -111,6 +111,11 @@ }; &i2c1 { + pinctrl-names = "default", "gpio"; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; + pca9547: mux@70 { compatible = "nxp,pca9547"; reg = <0x70>; @@ -261,6 +266,43 @@ }; }; +&i2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + sda-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; +}; + +&i2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + sda-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; +}; + +&iomuxc { + pinctrl_i2c1_gpio: i2c1gpiogrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x1b0b0 + MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x1b0b0 + >; + }; + + pinctrl_i2c2_gpio: i2c2gpiogrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x1b0b0 + MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x1b0b0 + >; + }; + + pinctrl_i2c3_gpio: i2c3gpiogrp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x1b0b0 + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1b0b0 + >; + }; +}; + &usdhc4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc4>; diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts index 1f0f950dc11efa7ba344fa2ec02f7217b3a3294f..e0aea782c6662208750ad97715a2bf516fd1f250 100644 --- a/arch/arm/boot/dts/imx6q-evi.dts +++ b/arch/arm/boot/dts/imx6q-evi.dts @@ -94,6 +94,15 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1cs>; status = "okay"; + + fpga: fpga@0 { + compatible = "altr,fpga-passive-serial"; + spi-max-frequency = <20000000>; + reg = <0>; + pinctrl-0 = <&pinctrl_fpgaspi>; + nconfig-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + nstat-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + }; }; &ecspi3 { @@ -319,6 +328,13 @@ >; }; + pinctrl_fpgaspi: fpgaspigrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x1b0b0 + MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0 + >; + }; + pinctrl_gpminand: gpminandgrp { fsl,pins = < MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 diff --git a/arch/arm/boot/dts/imx6q-gw52xx.dts b/arch/arm/boot/dts/imx6q-gw52xx.dts index a12c47e5ee059fbf45216ee6a9e65ce06f2f97b0..0b8ae007ad73fc08640c72a8cde3e902bf74d1a4 100644 --- a/arch/arm/boot/dts/imx6q-gw52xx.dts +++ b/arch/arm/boot/dts/imx6q-gw52xx.dts @@ -18,6 +18,64 @@ compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q"; }; +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu2_csi1_from_ipu2_csi1_mux { + bus-width = <8>; +}; + +&ipu2_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu2_csi1_mux>; + bus-width = <8>; +}; + +&ipu2_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu2_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu2_csi1: ipu2_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; + &sata { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6q-gw53xx.dts b/arch/arm/boot/dts/imx6q-gw53xx.dts index d76aaa83dad070ade4861a599dee1168da69c5cf..a56ef77eff3f9fb0aa2706aa027825311d14dece 100644 --- a/arch/arm/boot/dts/imx6q-gw53xx.dts +++ b/arch/arm/boot/dts/imx6q-gw53xx.dts @@ -18,6 +18,64 @@ compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q"; }; +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu2_csi1_from_ipu2_csi1_mux { + bus-width = <8>; +}; + +&ipu2_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu2_csi1_mux>; + bus-width = <8>; +}; + +&ipu2_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu2_csi1>; +}; + &sata { status = "okay"; }; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu2_csi1: ipu2_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-gw54xx.dts b/arch/arm/boot/dts/imx6q-gw54xx.dts index 6e8f53e92a2d24d49d4d1fb15788a4237fe08890..56e5b5050fcfcc2e5f093593c95c5f7c944e1ad1 100644 --- a/arch/arm/boot/dts/imx6q-gw54xx.dts +++ b/arch/arm/boot/dts/imx6q-gw54xx.dts @@ -18,6 +18,64 @@ compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q"; }; +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu2_csi1_from_ipu2_csi1_mux { + bus-width = <8>; +}; + +&ipu2_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu2_csi1_mux>; + bus-width = <8>; +}; + +&ipu2_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu2_csi1>; +}; + &sata { status = "okay"; }; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu2_csi1: ipu2_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi index ba01dd76d8874fc6df4a87efa48c3bcc5ddff163..ea339fa58f4a5a99f1834778e926ce022f139cdd 100644 --- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 Toradex AG + * Copyright 2014-2017 Toradex AG * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * @@ -56,18 +56,6 @@ status = "disabled"; }; - /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */ - i2cddc: i2c@0 { - compatible = "i2c-gpio"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c_ddc>; - gpios = <&gpio3 16 GPIO_ACTIVE_HIGH /* sda */ - &gpio2 30 GPIO_ACTIVE_HIGH /* scl */ - >; - i2c-gpio,delay-us = <2>; /* ~100 kHz */ - status = "disabled"; - }; - reg_1p8v: regulator-1p8v { compatible = "regulator-fixed"; regulator-name = "1P8V"; @@ -210,10 +198,13 @@ }; }; -/* - * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier - * board) - */ +&hdmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmi_ddc>; + status = "disabled"; +}; + +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ &i2c1 { clock-frequency = <100000>; pinctrl-names = "default"; @@ -374,7 +365,8 @@ }; /* - * GEN2_I2C, CAM: I2C3_SDA/SCL on MXM3 201/203 (unused) + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) */ &i2c3 { clock-frequency = <100000>; @@ -460,7 +452,7 @@ /* MMC1 */ &usdhc1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit>; vqmmc-supply = <®_3p3v>; bus-width = <8>; voltage-ranges = <3300 3300>; @@ -640,11 +632,10 @@ >; }; - pinctrl_i2c_ddc: gpioi2cddcgrp { + pinctrl_hdmi_ddc: hdmiddcgrp { fsl,pins = < - /* DDC bitbang */ - MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 - MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0 + MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1 >; }; @@ -912,7 +903,7 @@ >; }; - pinctrl_usdhc1: usdhc1grp { + pinctrl_usdhc1_4bit: usdhc1grp_4bit { fsl,pins = < MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 @@ -920,6 +911,11 @@ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + >; + }; + + pinctrl_usdhc1_8bit: usdhc1grp_8bit { + fsl,pins = < MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17071 MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17071 MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17071 diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi index e8c1edc82e6ef122a7fb68ee568d50d0f59a3d11..885556260bd0737b2164967dcad8af83d44ef066 100644 --- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi @@ -231,6 +231,37 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; + + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi0_mux>; + bus-width = <8>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; }; &pcie { @@ -302,6 +333,13 @@ &iomuxc { imx6qdl-gw51xx { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x0001b0b0 + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x4001b0b0 + >; + }; + pinctrl_enet: enetgrp { fsl,pins = < MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 @@ -372,6 +410,22 @@ >; }; + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + >; + }; + pinctrl_pcie: pciegrp { fsl,pins = < MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 91991d63a69c9a9af6aac4772be2b21014a8a493..115d706228eff5067f6a536e049e07183a778631 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -377,7 +377,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index 5bc6ed1a5b35ad1240cd7e6ae560c6d2f666a267..24be7965056c13d898d026eb852ba30db284b206 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -368,7 +368,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index 66fcf838e964502329391f457a2c5e9801ace1a4..4594b22791695436df2cd9ff372f332db74ad5c4 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -416,7 +416,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi index 57374dddf98d129c8019b4e0b14d63acd546766c..1a0faa1a14c8a4942d72ed1e3b1f6ef97a9b6c48 100644 --- a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi @@ -261,6 +261,37 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; + + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi0_mux>; + bus-width = <8>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; }; &pcie { @@ -340,6 +371,13 @@ }; &iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x0001b0b0 + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x4001b0b0 + >; + }; + pinctrl_gpmi_nand: gpminandgrp { fsl,pins = < MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 @@ -387,6 +425,22 @@ >; }; + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + >; + }; + pinctrl_gpio_leds: gpioledsgrp { fsl,pins = < MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0 diff --git a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi index 5fab5be414feb729fb3458fab43852c2644d0969..7ca291e9dbdb234b253d09b72fd1cb2a3f5aac71 100644 --- a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi +++ b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi @@ -184,7 +184,6 @@ }; &ssi1 { - fsl,mode = "i2s-slave"; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi index aeaa5a6e4fcf462bc8a381ab20ba85c3579dea5c..a24e4f1911abe77917726d8ff8342f7dcb88dab2 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi @@ -507,7 +507,7 @@ pinctrl_pcie: pciegrp { fsl,pins = < /* PCIe reset */ - MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x030b0 + MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x030b0 MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x030b0 >; }; @@ -668,7 +668,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; - reset-gpio = <&gpio6 31 GPIO_ACTIVE_LOW>; + reset-gpio = <&gpio3 0 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi index f22e5879340bc41c7f722c9d3314a41935070a11..d309a4d0eb08b38c0ba551ee3652549421538eb5 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi @@ -108,6 +108,18 @@ startup-delay-us = <70000>; enable-active-high; }; + + reg_usb_h1_vbus: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -515,6 +527,12 @@ >; }; + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x030b0 + >; + }; + pinctrl_usbotg: usbotggrp { fsl,pins = < MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 @@ -629,6 +647,7 @@ }; &usbh1 { + vbus-supply = <®_usb_h1_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi index afe7449c47da2d0b67ffc2628d323feaa4e00ea5..756c5054f047724f7e12a1fad1ca98fde09f50c2 100644 --- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi @@ -123,6 +123,18 @@ regulator-max-microvolt = <2800000>; regulator-always-on; }; + + reg_usb_h1_vbus: regulator@7 { + compatible = "regulator-fixed"; + reg = <7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; mipi_xclk: mipi_xclk { @@ -610,6 +622,12 @@ >; }; + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x030b0 + >; + }; + pinctrl_usbotg: usbotggrp { fsl,pins = < MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 @@ -705,6 +723,7 @@ }; &usbh1 { + vbus-supply = <®_usb_h1_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi index 5d94b5ee6aa0c992cdfc09bc0a4fe1a3a7a9aa2a..eeb7679fd348a4932d123a8bd7ec76fb5107cc63 100644 --- a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi @@ -59,6 +59,14 @@ pinctrl-0 = <&pinctrl_mdio1>; gpios = <&gpio6 5 GPIO_ACTIVE_HIGH &gpio6 4 GPIO_ACTIVE_HIGH>; + + phy: ethernet-phy@0 { + pinctrl-0 = <&pinctrl_rmii_phy_irq>; + pinctrl-names = "default"; + reg = <0>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + }; }; reg_28p0v: regulator-28p0v { @@ -615,14 +623,106 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rmii"; + phy-handle = <&phy>; phy-reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; phy-supply = <®_3p3v>; status = "okay"; - fixed-link { - speed = <100>; - full-duplex; + mdio { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + switch: switch@0 { + compatible = "marvell,mv88e6085"; + pinctrl-0 = <&pinctrl_switch_irq>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + dsa,member = <0 0>; + eeprom-length = <512>; + interrupt-parent = <&gpio6>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "gigabit_proc"; + phy-handle = <&switchphy0>; + }; + + port@1 { + reg = <1>; + label = "netaux"; + phy-handle = <&switchphy1>; + }; + + port@2 { + reg = <2>; + label = "cpu"; + ethernet = <&fec>; + + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + port@3 { + reg = <3>; + label = "netright"; + phy-handle = <&switchphy3>; + }; + + port@4 { + reg = <4>; + label = "netleft"; + phy-handle = <&switchphy4>; + }; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switchphy0: switchphy@0 { + reg = <0>; + interrupt-parent = <&switch>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy1: switchphy@1 { + reg = <1>; + interrupt-parent = <&switch>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy2: switchphy@2 { + reg = <2>; + interrupt-parent = <&switch>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy3: switchphy@3 { + reg = <3>; + interrupt-parent = <&switch>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy4: switchphy@4 { + reg = <4>; + interrupt-parent = <&switch>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + }; }; }; @@ -840,6 +940,12 @@ >; }; + pinctrl_switch_irq: switchgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x4001b000 + >; + }; + pinctrl_tc358767: tc358767grp { fsl,pins = < MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x10 diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index a9723b94bafa2e1eae8bad3206d79c76ffc0397a..8884b4a3cafb6f979189ba4be89295ad3777bfee 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -769,6 +769,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 3243af4a99844b30075f2c3e2ac7c2872d7a9310..3f76f980947ed6ecd88cb5a8b48cbfc3dc5bd63b 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -655,6 +655,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index f16b9df9d0c60a7f17c35627c458ab43906424aa..6c7eb54be9e2a4912d27cd4dcc2803a338390323 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -710,6 +710,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts index d2be8aa3370b7840e014964c147a4742d5ca87e8..9c23e017d86ad9194d48d7ef3bdb767210fd8dee 100644 --- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts +++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts @@ -22,7 +22,7 @@ reg = <0x80000000 0x20000000>; }; - backlight { + backlight_display: backlight-display { compatible = "pwm-backlight"; pwms = <&pwm1 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; @@ -78,6 +78,17 @@ clocks = <&clks IMX6UL_CLK_SAI2>; }; }; + + panel { + compatible = "innolux,at043tn24"; + backlight = <&backlight_display>; + + port { + panel_in: endpoint { + remote-endpoint = <&display_out>; + }; + }; + }; }; &clks { @@ -139,31 +150,11 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; - display = <&display0>; status = "okay"; - display0: display { - bits-per-pixel = <16>; - bus-width = <24>; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <9200000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <8>; - hback-porch = <4>; - hsync-len = <41>; - vback-porch = <2>; - vfront-porch = <4>; - vsync-len = <10>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; + port { + display_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; @@ -316,7 +307,6 @@ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0 MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031 - MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059 >; }; diff --git a/arch/arm/boot/dts/imx6ul-geam.dtsi b/arch/arm/boot/dts/imx6ul-geam.dts similarity index 87% rename from arch/arm/boot/dts/imx6ul-geam.dtsi rename to arch/arm/boot/dts/imx6ul-geam.dts index eb94d956808bb21d05d190d11a6a652bb9f84ff9..571eea7f1c6b47a962d66142adf5e954b5ac604d 100644 --- a/arch/arm/boot/dts/imx6ul-geam.dtsi +++ b/arch/arm/boot/dts/imx6ul-geam.dts @@ -40,11 +40,16 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +/dts-v1/; + #include #include #include "imx6ul.dtsi" / { + model = "Engicam GEAM6UL Starter Kit"; + compatible = "engicam,imx6ul-geam", "fsl,imx6ul"; + memory { reg = <0x80000000 0x08000000>; }; @@ -87,18 +92,46 @@ regulator-always-on; regulator-boot-on; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6ul-geam-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&sgtl5000>; + clocks = <&clks IMX6UL_CLK_SAI2>; + }; + }; }; &can1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan1>; xceiver-supply = <®_3p3v>; + status = "okay"; }; &can2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan2>; xceiver-supply = <®_3p3v>; + status = "okay"; }; &fec1 { @@ -144,6 +177,16 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6UL_CLK_OSC>; + clock-names = "mclk"; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + VDDD-supply = <®_1p8v>; + }; }; &i2c2 { @@ -158,6 +201,31 @@ pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <28000000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <30>; + hback-porch = <30>; + hsync-len = <64>; + vback-porch = <5>; + vfront-porch = <5>; + vsync-len = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; &pwm8 { @@ -178,6 +246,12 @@ status = "okay"; }; +&tsc { + measure-delay-time = <0x1ffff>; + pre-charge-time = <0x1fff>; + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/imx6ul-isiot-common.dtsi b/arch/arm/boot/dts/imx6ul-isiot-common.dtsi deleted file mode 100644 index 2beaab6e272e51df5e71a602eeceaa6bdd185ccf..0000000000000000000000000000000000000000 --- a/arch/arm/boot/dts/imx6ul-isiot-common.dtsi +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2016 Amarula Solutions B.V. - * Copyright (C) 2016 Engicam S.r.l. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -&i2c1 { - stmpe811: gpio-expander@44 { - compatible = "st,stmpe811"; - reg = <0x44>; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_stmpe>; - interrupt-parent = <&gpio1>; - interrupts = <18 IRQ_TYPE_EDGE_FALLING>; - interrupt-controller; - #interrupt-cells = <2>; - - stmpe: touchscreen { - compatible = "st,stmpe-ts"; - st,sample-time = <4>; - st,mod-12b = <1>; - st,ref-sel = <0>; - st,adc-freq = <1>; - st,ave-ctrl = <1>; - st,touch-det-delay = <2>; - st,settling = <2>; - st,fraction-z = <7>; - st,i-drive = <1>; - }; - }; -}; - -&lcdif { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_lcdif_dat - &pinctrl_lcdif_ctrl>; - display = <&display0>; - status = "okay"; - - display0: display { - bits-per-pixel = <16>; - bus-width = <18>; - - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <28000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <30>; - hback-porch = <30>; - hsync-len = <64>; - vback-porch = <5>; - vfront-porch = <5>; - vsync-len = <20>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; - }; - }; -}; - -&iomuxc { - pinctrl_lcdif_ctrl: lcdifctrlgrp { - fsl,pins = < - MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 - MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 - MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 - MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 - >; - }; - - pinctrl_lcdif_dat: lcdifdatgrp { - fsl,pins = < - MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 - MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 - MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 - MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 - MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 - MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 - MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 - MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 - MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 - MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 - MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 - MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 - MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 - MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 - MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 - MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 - MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 - MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 - >; - }; - - pinctrl_stmpe: stmpegrp { - fsl,pins = < - MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b0 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6ul-isiot-emmc.dts b/arch/arm/boot/dts/imx6ul-isiot-emmc.dts index 73a1d0f0b9d543b18d498a0c4c38becef68831b9..f5b422898e61dd22ed1c13a3357a62fb2209f8f1 100644 --- a/arch/arm/boot/dts/imx6ul-isiot-emmc.dts +++ b/arch/arm/boot/dts/imx6ul-isiot-emmc.dts @@ -43,7 +43,6 @@ /dts-v1/; #include "imx6ul-isiot.dtsi" -#include "imx6ul-isiot-common.dtsi" / { model = "Engicam Is.IoT MX6UL eMMC Starter kit"; diff --git a/arch/arm/boot/dts/imx6ul-isiot-nand.dts b/arch/arm/boot/dts/imx6ul-isiot-nand.dts index da29a86eb6a8f83dc9e3fc64bf50f4b6d0cd2b74..de15e1c75dd1ddf606976d0f3571fdf6bb1c10e7 100644 --- a/arch/arm/boot/dts/imx6ul-isiot-nand.dts +++ b/arch/arm/boot/dts/imx6ul-isiot-nand.dts @@ -43,7 +43,6 @@ /dts-v1/; #include "imx6ul-isiot.dtsi" -#include "imx6ul-isiot-common.dtsi" / { model = "Engicam Is.IoT MX6UL NAND Starter kit"; diff --git a/arch/arm/boot/dts/imx6ul-isiot.dtsi b/arch/arm/boot/dts/imx6ul-isiot.dtsi index ea30380ad7a4bef0e1261bdc7788b9257579b2ec..950fb28b630a4dc88ee1f28840dab90317f01c83 100644 --- a/arch/arm/boot/dts/imx6ul-isiot.dtsi +++ b/arch/arm/boot/dts/imx6ul-isiot.dtsi @@ -69,6 +69,68 @@ 100>; default-brightness-level = <100>; }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6ul-isiot-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&sgtl5000>; + clocks = <&clks IMX6UL_CLK_SAI2>; + }; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet1>; + phy-mode = "rmii"; + phy-handle = <ðphy0>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; }; &i2c1 { @@ -76,6 +138,42 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6UL_CLK_OSC>; + clock-names = "mclk"; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + VDDD-supply = <®_1p8v>; + }; + + stmpe811: gpio-expander@44 { + compatible = "st,stmpe811"; + reg = <0x44>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_stmpe>; + interrupt-parent = <&gpio1>; + interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + stmpe: touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <1>; + }; + }; }; &i2c2 { @@ -85,6 +183,38 @@ status = "okay"; }; +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif_dat + &pinctrl_lcdif_ctrl>; + display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <28000000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <30>; + hback-porch = <30>; + hsync-len = <64>; + vback-porch = <5>; + vfront-porch = <5>; + vsync-len = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; +}; + &pwm8 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm8>; @@ -115,6 +245,21 @@ }; &iomuxc { + pinctrl_enet1: enet1grp { + fsl,pins = < + MX6UL_PAD_ENET2_RX_DATA0__ENET1_MDIO 0x1b0b0 + MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC 0x1b0b0 + MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0 + MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0 + MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0 + MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0 + MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0 + MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0 + MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031 + MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10 0x1b0b0 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 @@ -129,6 +274,38 @@ >; }; + pinctrl_lcdif_ctrl: lcdifctrlgrp { + fsl,pins = < + MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 + MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 + MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 + MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 + >; + }; + + pinctrl_lcdif_dat: lcdifdatgrp { + fsl,pins = < + MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 + MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 + MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 + MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 + MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 + MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 + MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 + MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 + MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 + MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 + MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 + MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 + MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 + MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 + MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 + MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 + MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 + MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 + >; + }; + pinctrl_pwm8: pwm8grp { fsl,pins = < MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x110b0 @@ -145,6 +322,12 @@ >; }; + pinctrl_stmpe: stmpegrp { + fsl,pins = < + MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b0 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1 diff --git a/arch/arm/boot/dts/imx6ul-liteboard.dts b/arch/arm/boot/dts/imx6ul-liteboard.dts index ed1d891d6a8953dde12c99e0b675bf033471e948..1d863a16bcf09c54ed76650edf2591b1be56ac52 100644 --- a/arch/arm/boot/dts/imx6ul-liteboard.dts +++ b/arch/arm/boot/dts/imx6ul-liteboard.dts @@ -124,6 +124,10 @@ }; }; +&snvs_poweroff { + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 6da2b77edd460ff7a6b592d887c98ccb3449f8c8..f11a241a340d52b6cf95b184b69696e13e29c88d 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -614,6 +614,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index d7753f79937a7f543148dd982dbc8ae3931a1c8f..0a3915868aa328fc4bafa4650ecf9085ce85b8df 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -106,6 +106,15 @@ fsl,magic-packet; }; +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + fsl,use-minimum-ecc; + nand-on-flash-bbt; + nand-ecc-mode = "hw"; + status = "okay"; +}; + &i2c1 { clock-frequency = <100000>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index 54c45402286b10dc06240aef9ec7d015a3fd5a58..44637cabcc566d402847992607984f9736db5a27 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -117,6 +117,37 @@ regulator-max-microvolt = <3300000>; startup-delay-us = <200000>; }; + + reg_lcd_3v3: regulator-lcd-3v3 { + compatible = "regulator-fixed"; + regulator-name = "lcd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&extended_io 7 GPIO_ACTIVE_LOW>; + }; + + reg_can2_3v3: regulator-can2-3v3 { + compatible = "regulator-fixed"; + regulator-name = "can2-3v3"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2_reg>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 14 GPIO_ACTIVE_LOW>; + }; + + panel { + compatible = "innolux,at043tn24"; + pinctrl-0 = <&pinctrl_backlight>; + enable-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + power-supply = <®_lcd_3v3>; + + port { + panel_in: endpoint { + remote-endpoint = <&display_out>; + }; + }; + }; }; &adc1 { @@ -168,6 +199,7 @@ phy-mode = "rgmii"; phy-handle = <ðphy0>; fsl,magic-packet; + phy-reset-gpios = <&extended_io 5 GPIO_ACTIVE_LOW>; status = "okay"; mdio { @@ -197,6 +229,13 @@ status = "okay"; }; +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + xceiver-supply = <®_can2_3v3>; + status = "okay"; +}; + &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; @@ -285,8 +324,8 @@ }; vgen6_reg: vldo4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; regulator-always-on; }; }; @@ -322,31 +361,11 @@ &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif>; - display = <&display0>; status = "okay"; - display0: display { - bits-per-pixel = <16>; - bus-width = <24>; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <9200000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <8>; - hback-porch = <4>; - hsync-len = <41>; - vback-porch = <2>; - vfront-porch = <4>; - vsync-len = <10>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; + port { + display_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; @@ -356,12 +375,6 @@ status = "okay"; }; -&pwm1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm1>; - status = "okay"; -}; - &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -488,6 +501,20 @@ >; }; + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x59 + MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x59 + >; + }; + + pinctrl_flexcan2_reg: flexcan2reggrp { + fsl,pins = < + MX7D_PAD_EPDC_DATA14__GPIO2_IO14 0x59 /* CAN_STBY */ + >; + }; + + pinctrl_hog: hoggrp { fsl,pins = < MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 @@ -557,6 +584,14 @@ >; }; + pinctrl_spi4: spi4grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59 + MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59 + MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59 + >; + }; + pinctrl_tsc2046_pendown: tsc2046_pendown { fsl,pins = < MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x59 @@ -693,17 +728,9 @@ >; }; - pinctrl_pwm1: pwm1grp { + pinctrl_backlight: backlightgrp { fsl,pins = < - MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x110b0 + MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x110b0 >; - - pinctrl_spi4: spi4grp { - fsl,pins = < - MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59 - MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59 - MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59 - >; - }; }; }; diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 4cf6c458b583f68a45e78301734b317db39bbac5..82ad26e766eb71b7191afd9b7334ea4ac3b80480 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -540,6 +540,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; }; @@ -1021,5 +1022,36 @@ status = "disabled"; }; }; + + dma_apbh: dma-apbh@33000000 { + compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh"; + reg = <0x33000000 0x2000>; + interrupts = , + , + , + ; + interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; + }; + + gpmi: gpmi-nand@33002000{ + compatible = "fsl,imx7d-gpmi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x33002000 0x2000>, <0x33004000 0x4000>; + reg-names = "gpmi-nand", "bch"; + interrupts = ; + interrupt-names = "bch"; + clocks = <&clks IMX7D_NAND_RAWNAND_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; + clock-names = "gpmi_io", "gpmi_bch_apb"; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; + status = "disabled"; + assigned-clocks = <&clks IMX7D_NAND_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_500M_CLK>; + }; }; }; diff --git a/arch/arm/boot/dts/imx7ulp-pinfunc.h b/arch/arm/boot/dts/imx7ulp-pinfunc.h new file mode 100644 index 0000000000000000000000000000000000000000..fe511775b518cea36ce072d7817f607d366d4908 --- /dev/null +++ b/arch/arm/boot/dts/imx7ulp-pinfunc.h @@ -0,0 +1,468 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __DTS_IMX7ULP_PINFUNC_H +#define __DTS_IMX7ULP_PINFUNC_H + +/* + * The pin function ID is a tuple of + * + */ + +#define IMX7ULP_PAD_PTC0__PTC0 0x0000 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC0__TRACE_D15 0x0000 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC0__LPUART4_CTS_B 0x0000 0x0244 0x4 0x1 +#define IMX7ULP_PAD_PTC0__LPI2C4_SCL 0x0000 0x0278 0x5 0x1 +#define IMX7ULP_PAD_PTC0__TPM4_CLKIN 0x0000 0x0298 0x6 0x1 +#define IMX7ULP_PAD_PTC0__FB_AD0 0x0000 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC1__PTC1 0x0004 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC1__TRACE_D14 0x0004 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC1__LPUART4_RTS_B 0x0004 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC1__LPI2C4_SDA 0x0004 0x027c 0x5 0x1 +#define IMX7ULP_PAD_PTC1__TPM4_CH0 0x0004 0x0280 0x6 0x1 +#define IMX7ULP_PAD_PTC1__FB_AD1 0x0004 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC2__PTC2 0x0008 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC2__TRACE_D13 0x0008 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC2__LPUART4_TX 0x0008 0x024c 0x4 0x1 +#define IMX7ULP_PAD_PTC2__LPI2C4_HREQ 0x0008 0x0274 0x5 0x1 +#define IMX7ULP_PAD_PTC2__TPM4_CH1 0x0008 0x0284 0x6 0x1 +#define IMX7ULP_PAD_PTC2__FB_AD2 0x0008 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC3__PTC3 0x000c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC3__TRACE_D12 0x000c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC3__LPUART4_RX 0x000c 0x0248 0x4 0x1 +#define IMX7ULP_PAD_PTC3__TPM4_CH2 0x000c 0x0288 0x6 0x1 +#define IMX7ULP_PAD_PTC3__FB_AD3 0x000c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC4__PTC4 0x0010 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC4__TRACE_D11 0x0010 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC4__FXIO1_D0 0x0010 0x0204 0x2 0x1 +#define IMX7ULP_PAD_PTC4__LPSPI2_PCS1 0x0010 0x02a0 0x3 0x1 +#define IMX7ULP_PAD_PTC4__LPUART5_CTS_B 0x0010 0x0250 0x4 0x1 +#define IMX7ULP_PAD_PTC4__LPI2C5_SCL 0x0010 0x02bc 0x5 0x1 +#define IMX7ULP_PAD_PTC4__TPM4_CH3 0x0010 0x028c 0x6 0x1 +#define IMX7ULP_PAD_PTC4__FB_AD4 0x0010 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC5__PTC5 0x0014 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC5__TRACE_D10 0x0014 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC5__FXIO1_D1 0x0014 0x0208 0x2 0x1 +#define IMX7ULP_PAD_PTC5__LPSPI2_PCS2 0x0014 0x02a4 0x3 0x1 +#define IMX7ULP_PAD_PTC5__LPUART5_RTS_B 0x0014 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC5__LPI2C5_SDA 0x0014 0x02c0 0x5 0x1 +#define IMX7ULP_PAD_PTC5__TPM4_CH4 0x0014 0x0290 0x6 0x1 +#define IMX7ULP_PAD_PTC5__FB_AD5 0x0014 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC6__PTC6 0x0018 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC6__TRACE_D9 0x0018 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC6__FXIO1_D2 0x0018 0x020c 0x2 0x1 +#define IMX7ULP_PAD_PTC6__LPSPI2_PCS3 0x0018 0x02a8 0x3 0x1 +#define IMX7ULP_PAD_PTC6__LPUART5_TX 0x0018 0x0258 0x4 0x1 +#define IMX7ULP_PAD_PTC6__LPI2C5_HREQ 0x0018 0x02b8 0x5 0x1 +#define IMX7ULP_PAD_PTC6__TPM4_CH5 0x0018 0x0294 0x6 0x1 +#define IMX7ULP_PAD_PTC6__FB_AD6 0x0018 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC7__PTC7 0x001c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC7__TRACE_D8 0x001c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC7__FXIO1_D3 0x001c 0x0210 0x2 0x1 +#define IMX7ULP_PAD_PTC7__LPUART5_RX 0x001c 0x0254 0x4 0x1 +#define IMX7ULP_PAD_PTC7__TPM5_CH1 0x001c 0x02c8 0x6 0x1 +#define IMX7ULP_PAD_PTC7__FB_AD7 0x001c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC8__PTC8 0x0020 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC8__TRACE_D7 0x0020 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC8__FXIO1_D4 0x0020 0x0214 0x2 0x1 +#define IMX7ULP_PAD_PTC8__LPSPI2_SIN 0x0020 0x02b0 0x3 0x1 +#define IMX7ULP_PAD_PTC8__LPUART6_CTS_B 0x0020 0x025c 0x4 0x1 +#define IMX7ULP_PAD_PTC8__LPI2C6_SCL 0x0020 0x02fc 0x5 0x1 +#define IMX7ULP_PAD_PTC8__TPM5_CLKIN 0x0020 0x02cc 0x6 0x1 +#define IMX7ULP_PAD_PTC8__FB_AD8 0x0020 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC9__PTC9 0x0024 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC9__TRACE_D6 0x0024 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC9__FXIO1_D5 0x0024 0x0218 0x2 0x1 +#define IMX7ULP_PAD_PTC9__LPSPI2_SOUT 0x0024 0x02b4 0x3 0x1 +#define IMX7ULP_PAD_PTC9__LPUART6_RTS_B 0x0024 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC9__LPI2C6_SDA 0x0024 0x0300 0x5 0x1 +#define IMX7ULP_PAD_PTC9__TPM5_CH0 0x0024 0x02c4 0x6 0x1 +#define IMX7ULP_PAD_PTC9__FB_AD9 0x0024 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC10__PTC10 0x0028 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC10__TRACE_D5 0x0028 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC10__FXIO1_D6 0x0028 0x021c 0x2 0x1 +#define IMX7ULP_PAD_PTC10__LPSPI2_SCK 0x0028 0x02ac 0x3 0x1 +#define IMX7ULP_PAD_PTC10__LPUART6_TX 0x0028 0x0264 0x4 0x1 +#define IMX7ULP_PAD_PTC10__LPI2C6_HREQ 0x0028 0x02f8 0x5 0x1 +#define IMX7ULP_PAD_PTC10__TPM7_CH3 0x0028 0x02e8 0x6 0x1 +#define IMX7ULP_PAD_PTC10__FB_AD10 0x0028 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC11__PTC11 0x002c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC11__TRACE_D4 0x002c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC11__FXIO1_D7 0x002c 0x0220 0x2 0x1 +#define IMX7ULP_PAD_PTC11__LPSPI2_PCS0 0x002c 0x029c 0x3 0x1 +#define IMX7ULP_PAD_PTC11__LPUART6_RX 0x002c 0x0260 0x4 0x1 +#define IMX7ULP_PAD_PTC11__TPM7_CH4 0x002c 0x02ec 0x6 0x1 +#define IMX7ULP_PAD_PTC11__FB_AD11 0x002c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC12__PTC12 0x0030 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC12__TRACE_D3 0x0030 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC12__FXIO1_D8 0x0030 0x0224 0x2 0x1 +#define IMX7ULP_PAD_PTC12__LPSPI3_PCS1 0x0030 0x0314 0x3 0x1 +#define IMX7ULP_PAD_PTC12__LPUART7_CTS_B 0x0030 0x0268 0x4 0x1 +#define IMX7ULP_PAD_PTC12__LPI2C7_SCL 0x0030 0x0308 0x5 0x1 +#define IMX7ULP_PAD_PTC12__TPM7_CH5 0x0030 0x02f0 0x6 0x1 +#define IMX7ULP_PAD_PTC12__FB_AD12 0x0030 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC13__PTC13 0x0034 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC13__TRACE_D2 0x0034 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC13__FXIO1_D9 0x0034 0x0228 0x2 0x1 +#define IMX7ULP_PAD_PTC13__LPSPI3_PCS2 0x0034 0x0318 0x3 0x1 +#define IMX7ULP_PAD_PTC13__LPUART7_RTS_B 0x0034 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC13__LPI2C7_SDA 0x0034 0x030c 0x5 0x1 +#define IMX7ULP_PAD_PTC13__TPM7_CLKIN 0x0034 0x02f4 0x6 0x1 +#define IMX7ULP_PAD_PTC13__FB_AD13 0x0034 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC14__PTC14 0x0038 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC14__TRACE_D1 0x0038 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC14__FXIO1_D10 0x0038 0x022c 0x2 0x1 +#define IMX7ULP_PAD_PTC14__LPSPI3_PCS3 0x0038 0x031c 0x3 0x1 +#define IMX7ULP_PAD_PTC14__LPUART7_TX 0x0038 0x0270 0x4 0x1 +#define IMX7ULP_PAD_PTC14__LPI2C7_HREQ 0x0038 0x0304 0x5 0x1 +#define IMX7ULP_PAD_PTC14__TPM7_CH0 0x0038 0x02dc 0x6 0x1 +#define IMX7ULP_PAD_PTC14__FB_AD14 0x0038 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC15__PTC15 0x003c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC15__TRACE_D0 0x003c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC15__FXIO1_D11 0x003c 0x0230 0x2 0x1 +#define IMX7ULP_PAD_PTC15__LPUART7_RX 0x003c 0x026c 0x4 0x1 +#define IMX7ULP_PAD_PTC15__TPM7_CH1 0x003c 0x02e0 0x6 0x1 +#define IMX7ULP_PAD_PTC15__FB_AD15 0x003c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC16__PTC16 0x0040 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC16__TRACE_CLKOUT 0x0040 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC16__FXIO1_D12 0x0040 0x0234 0x2 0x1 +#define IMX7ULP_PAD_PTC16__LPSPI3_SIN 0x0040 0x0324 0x3 0x1 +#define IMX7ULP_PAD_PTC16__TPM7_CH2 0x0040 0x02e4 0x6 0x1 +#define IMX7ULP_PAD_PTC16__FB_ALE_FB_CS1_B_FB_TS_B 0x0040 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC17__PTC17 0x0044 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC17__FXIO1_D13 0x0044 0x0238 0x2 0x1 +#define IMX7ULP_PAD_PTC17__LPSPI3_SOUT 0x0044 0x0328 0x3 0x1 +#define IMX7ULP_PAD_PTC17__TPM6_CLKIN 0x0044 0x02d8 0x6 0x1 +#define IMX7ULP_PAD_PTC17__FB_CS0_B 0x0044 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC18__PTC18 0x0048 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC18__FXIO1_D14 0x0048 0x023c 0x2 0x1 +#define IMX7ULP_PAD_PTC18__LPSPI3_SCK 0x0048 0x0320 0x3 0x1 +#define IMX7ULP_PAD_PTC18__TPM6_CH0 0x0048 0x02d0 0x6 0x1 +#define IMX7ULP_PAD_PTC18__FB_OE_B 0x0048 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC19__PTC19 0x004c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC19__FXIO1_D15 0x004c 0x0240 0x2 0x1 +#define IMX7ULP_PAD_PTC19__LPSPI3_PCS0 0x004c 0x0310 0x3 0x1 +#define IMX7ULP_PAD_PTC19__TPM6_CH1 0x004c 0x02d4 0x6 0x1 +#define IMX7ULP_PAD_PTC19__FB_A16 0x004c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTD0__PTD0 0x0080 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD0__SDHC0_RESET_B 0x0080 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD1__PTD1 0x0084 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD1__SDHC0_CMD 0x0084 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD2__PTD2 0x0088 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD2__SDHC0_CLK 0x0088 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD3__PTD3 0x008c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD3__SDHC0_D7 0x008c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD4__PTD4 0x0090 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD4__SDHC0_D6 0x0090 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD5__PTD5 0x0094 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD5__SDHC0_D5 0x0094 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD6__PTD6 0x0098 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD6__SDHC0_D4 0x0098 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD7__PTD7 0x009c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD7__SDHC0_D3 0x009c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD8__PTD8 0x00a0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD8__TPM4_CLKIN 0x00a0 0x0298 0x6 0x2 +#define IMX7ULP_PAD_PTD8__SDHC0_D2 0x00a0 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD9__PTD9 0x00a4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD9__TPM4_CH0 0x00a4 0x0280 0x6 0x2 +#define IMX7ULP_PAD_PTD9__SDHC0_D1 0x00a4 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD10__PTD10 0x00a8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD10__TPM4_CH1 0x00a8 0x0284 0x6 0x2 +#define IMX7ULP_PAD_PTD10__SDHC0_D0 0x00a8 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD11__PTD11 0x00ac 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD11__TPM4_CH2 0x00ac 0x0288 0x6 0x2 +#define IMX7ULP_PAD_PTD11__SDHC0_DQS 0x00ac 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE0__PTE0 0x0100 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE0__FXIO1_D31 0x0100 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE0__LPSPI2_PCS1 0x0100 0x02a0 0x3 0x2 +#define IMX7ULP_PAD_PTE0__LPUART4_CTS_B 0x0100 0x0244 0x4 0x2 +#define IMX7ULP_PAD_PTE0__LPI2C4_SCL 0x0100 0x0278 0x5 0x2 +#define IMX7ULP_PAD_PTE0__SDHC1_D1 0x0100 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE0__FB_A25 0x0100 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE1__PTE1 0x0104 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE1__FXIO1_D30 0x0104 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE1__LPSPI2_PCS2 0x0104 0x02a4 0x3 0x2 +#define IMX7ULP_PAD_PTE1__LPUART4_RTS_B 0x0104 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE1__LPI2C4_SDA 0x0104 0x027c 0x5 0x2 +#define IMX7ULP_PAD_PTE1__SDHC1_D0 0x0104 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE1__FB_A26 0x0104 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE2__PTE2 0x0108 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE2__FXIO1_D29 0x0108 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE2__LPSPI2_PCS3 0x0108 0x02a8 0x3 0x2 +#define IMX7ULP_PAD_PTE2__LPUART4_TX 0x0108 0x024c 0x4 0x2 +#define IMX7ULP_PAD_PTE2__LPI2C4_HREQ 0x0108 0x0274 0x5 0x2 +#define IMX7ULP_PAD_PTE2__SDHC1_CLK 0x0108 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE3__PTE3 0x010c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE3__FXIO1_D28 0x010c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE3__LPUART4_RX 0x010c 0x0248 0x4 0x2 +#define IMX7ULP_PAD_PTE3__TPM5_CH1 0x010c 0x02c8 0x6 0x2 +#define IMX7ULP_PAD_PTE3__SDHC1_CMD 0x010c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE4__PTE4 0x0110 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE4__FXIO1_D27 0x0110 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE4__LPSPI2_SIN 0x0110 0x02b0 0x3 0x2 +#define IMX7ULP_PAD_PTE4__LPUART5_CTS_B 0x0110 0x0250 0x4 0x2 +#define IMX7ULP_PAD_PTE4__LPI2C5_SCL 0x0110 0x02bc 0x5 0x2 +#define IMX7ULP_PAD_PTE4__TPM5_CLKIN 0x0110 0x02cc 0x6 0x2 +#define IMX7ULP_PAD_PTE4__SDHC1_D3 0x0110 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE5__PTE5 0x0114 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE5__FXIO1_D26 0x0114 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE5__LPSPI2_SOUT 0x0114 0x02b4 0x3 0x2 +#define IMX7ULP_PAD_PTE5__LPUART5_RTS_B 0x0114 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE5__LPI2C5_SDA 0x0114 0x02c0 0x5 0x2 +#define IMX7ULP_PAD_PTE5__TPM5_CH0 0x0114 0x02c4 0x6 0x2 +#define IMX7ULP_PAD_PTE5__SDHC1_D2 0x0114 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE6__PTE6 0x0118 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE6__FXIO1_D25 0x0118 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE6__LPSPI2_SCK 0x0118 0x02ac 0x3 0x2 +#define IMX7ULP_PAD_PTE6__LPUART5_TX 0x0118 0x0258 0x4 0x2 +#define IMX7ULP_PAD_PTE6__LPI2C5_HREQ 0x0118 0x02b8 0x5 0x2 +#define IMX7ULP_PAD_PTE6__TPM7_CH3 0x0118 0x02e8 0x6 0x2 +#define IMX7ULP_PAD_PTE6__SDHC1_D4 0x0118 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE6__FB_A17 0x0118 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE7__PTE7 0x011c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE7__TRACE_D7 0x011c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE7__VIU_FID 0x011c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE7__FXIO1_D24 0x011c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE7__LPSPI2_PCS0 0x011c 0x029c 0x3 0x2 +#define IMX7ULP_PAD_PTE7__LPUART5_RX 0x011c 0x0254 0x4 0x2 +#define IMX7ULP_PAD_PTE7__TPM7_CH4 0x011c 0x02ec 0x6 0x2 +#define IMX7ULP_PAD_PTE7__SDHC1_D5 0x011c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE7__FB_A18 0x011c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE8__PTE8 0x0120 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE8__TRACE_D6 0x0120 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE8__VIU_D16 0x0120 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE8__FXIO1_D23 0x0120 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE8__LPSPI3_PCS1 0x0120 0x0314 0x3 0x2 +#define IMX7ULP_PAD_PTE8__LPUART6_CTS_B 0x0120 0x025c 0x4 0x2 +#define IMX7ULP_PAD_PTE8__LPI2C6_SCL 0x0120 0x02fc 0x5 0x2 +#define IMX7ULP_PAD_PTE8__TPM7_CH5 0x0120 0x02f0 0x6 0x2 +#define IMX7ULP_PAD_PTE8__SDHC1_WP 0x0120 0x0200 0x7 0x1 +#define IMX7ULP_PAD_PTE8__SDHC1_D6 0x0120 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE8__FB_CS3_B_FB_BE7_0_BLS31_24_B 0x0120 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE9__PTE9 0x0124 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE9__TRACE_D5 0x0124 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE9__VIU_D17 0x0124 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE9__FXIO1_D22 0x0124 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE9__LPSPI3_PCS2 0x0124 0x0318 0x3 0x2 +#define IMX7ULP_PAD_PTE9__LPUART6_RTS_B 0x0124 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE9__LPI2C6_SDA 0x0124 0x0300 0x5 0x2 +#define IMX7ULP_PAD_PTE9__TPM7_CLKIN 0x0124 0x02f4 0x6 0x2 +#define IMX7ULP_PAD_PTE9__SDHC1_CD 0x0124 0x032c 0x7 0x1 +#define IMX7ULP_PAD_PTE9__SDHC1_D7 0x0124 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE9__FB_TBST_B_FB_CS2_B_FB_BE15_8_BLS23_16_B 0x0124 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE10__PTE10 0x0128 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE10__TRACE_D4 0x0128 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE10__VIU_D18 0x0128 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE10__FXIO1_D21 0x0128 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE10__LPSPI3_PCS3 0x0128 0x031c 0x3 0x2 +#define IMX7ULP_PAD_PTE10__LPUART6_TX 0x0128 0x0264 0x4 0x2 +#define IMX7ULP_PAD_PTE10__LPI2C6_HREQ 0x0128 0x02f8 0x5 0x2 +#define IMX7ULP_PAD_PTE10__TPM7_CH0 0x0128 0x02dc 0x6 0x2 +#define IMX7ULP_PAD_PTE10__SDHC1_VS 0x0128 0x0000 0x7 0x0 +#define IMX7ULP_PAD_PTE10__SDHC1_DQS 0x0128 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE10__FB_A19 0x0128 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE11__PTE11 0x012c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE11__TRACE_D3 0x012c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE11__VIU_D19 0x012c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE11__FXIO1_D20 0x012c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE11__LPUART6_RX 0x012c 0x0260 0x4 0x2 +#define IMX7ULP_PAD_PTE11__TPM7_CH1 0x012c 0x02e0 0x6 0x2 +#define IMX7ULP_PAD_PTE11__SDHC1_RESET_B 0x012c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE11__FB_A20 0x012c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE12__PTE12 0x0130 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE12__TRACE_D2 0x0130 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE12__VIU_D20 0x0130 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE12__FXIO1_D19 0x0130 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE12__LPSPI3_SIN 0x0130 0x0324 0x3 0x2 +#define IMX7ULP_PAD_PTE12__LPUART7_CTS_B 0x0130 0x0268 0x4 0x2 +#define IMX7ULP_PAD_PTE12__LPI2C7_SCL 0x0130 0x0308 0x5 0x2 +#define IMX7ULP_PAD_PTE12__TPM7_CH2 0x0130 0x02e4 0x6 0x2 +#define IMX7ULP_PAD_PTE12__SDHC1_WP 0x0130 0x0200 0x8 0x2 +#define IMX7ULP_PAD_PTE12__FB_A21 0x0130 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE13__PTE13 0x0134 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE13__TRACE_D1 0x0134 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE13__VIU_D21 0x0134 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE13__FXIO1_D18 0x0134 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE13__LPSPI3_SOUT 0x0134 0x0328 0x3 0x2 +#define IMX7ULP_PAD_PTE13__LPUART7_RTS_B 0x0134 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE13__LPI2C7_SDA 0x0134 0x030c 0x5 0x2 +#define IMX7ULP_PAD_PTE13__TPM6_CLKIN 0x0134 0x02d8 0x6 0x2 +#define IMX7ULP_PAD_PTE13__SDHC1_CD 0x0134 0x032c 0x8 0x2 +#define IMX7ULP_PAD_PTE13__FB_A22 0x0134 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE14__PTE14 0x0138 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE14__TRACE_D0 0x0138 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE14__VIU_D22 0x0138 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE14__FXIO1_D17 0x0138 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE14__LPSPI3_SCK 0x0138 0x0320 0x3 0x2 +#define IMX7ULP_PAD_PTE14__LPUART7_TX 0x0138 0x0270 0x4 0x2 +#define IMX7ULP_PAD_PTE14__LPI2C7_HREQ 0x0138 0x0304 0x5 0x2 +#define IMX7ULP_PAD_PTE14__TPM6_CH0 0x0138 0x02d0 0x6 0x2 +#define IMX7ULP_PAD_PTE14__SDHC1_VS 0x0138 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE14__FB_A23 0x0138 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE15__PTE15 0x013c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE15__TRACE_CLKOUT 0x013c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE15__VIU_D23 0x013c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE15__FXIO1_D16 0x013c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE15__LPSPI3_PCS0 0x013c 0x0310 0x3 0x2 +#define IMX7ULP_PAD_PTE15__LPUART7_RX 0x013c 0x026c 0x4 0x2 +#define IMX7ULP_PAD_PTE15__TPM6_CH1 0x013c 0x02d4 0x6 0x2 +#define IMX7ULP_PAD_PTE15__FB_A24 0x013c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF0__PTF0 0x0180 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF0__VIU_DE 0x0180 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF0__LPUART4_CTS_B 0x0180 0x0244 0x4 0x3 +#define IMX7ULP_PAD_PTF0__LPI2C4_SCL 0x0180 0x0278 0x5 0x3 +#define IMX7ULP_PAD_PTF0__TPM4_CLKIN 0x0180 0x0298 0x6 0x3 +#define IMX7ULP_PAD_PTF0__FB_RW_B 0x0180 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF1__PTF1 0x0184 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF1__VIU_HSYNC 0x0184 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF1__LPUART4_RTS_B 0x0184 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF1__LPI2C4_SDA 0x0184 0x027c 0x5 0x3 +#define IMX7ULP_PAD_PTF1__TPM4_CH0 0x0184 0x0280 0x6 0x3 +#define IMX7ULP_PAD_PTF1__CLKOUT 0x0184 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF2__PTF2 0x0188 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF2__VIU_VSYNC 0x0188 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF2__LPUART4_TX 0x0188 0x024c 0x4 0x3 +#define IMX7ULP_PAD_PTF2__LPI2C4_HREQ 0x0188 0x0274 0x5 0x3 +#define IMX7ULP_PAD_PTF2__TPM4_CH1 0x0188 0x0284 0x6 0x3 +#define IMX7ULP_PAD_PTF2__FB_TSIZ1_FB_CS5_B_FB_BE23_16_BLS15_8_B 0x0188 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF3__PTF3 0x018c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF3__VIU_PCLK 0x018c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF3__LPUART4_RX 0x018c 0x0248 0x4 0x3 +#define IMX7ULP_PAD_PTF3__TPM4_CH2 0x018c 0x0288 0x6 0x3 +#define IMX7ULP_PAD_PTF3__FB_AD16 0x018c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF4__PTF4 0x0190 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF4__VIU_D0 0x0190 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF4__FXIO1_D0 0x0190 0x0204 0x2 0x2 +#define IMX7ULP_PAD_PTF4__LPSPI2_PCS1 0x0190 0x02a0 0x3 0x3 +#define IMX7ULP_PAD_PTF4__LPUART5_CTS_B 0x0190 0x0250 0x4 0x3 +#define IMX7ULP_PAD_PTF4__LPI2C5_SCL 0x0190 0x02bc 0x5 0x3 +#define IMX7ULP_PAD_PTF4__TPM4_CH3 0x0190 0x028c 0x6 0x2 +#define IMX7ULP_PAD_PTF4__FB_AD17 0x0190 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF5__PTF5 0x0194 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF5__VIU_D1 0x0194 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF5__FXIO1_D1 0x0194 0x0208 0x2 0x2 +#define IMX7ULP_PAD_PTF5__LPSPI2_PCS2 0x0194 0x02a4 0x3 0x3 +#define IMX7ULP_PAD_PTF5__LPUART5_RTS_B 0x0194 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF5__LPI2C5_SDA 0x0194 0x02c0 0x5 0x3 +#define IMX7ULP_PAD_PTF5__TPM4_CH4 0x0194 0x0290 0x6 0x2 +#define IMX7ULP_PAD_PTF5__FB_AD18 0x0194 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF6__PTF6 0x0198 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF6__VIU_D2 0x0198 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF6__FXIO1_D2 0x0198 0x020c 0x2 0x2 +#define IMX7ULP_PAD_PTF6__LPSPI2_PCS3 0x0198 0x02a8 0x3 0x3 +#define IMX7ULP_PAD_PTF6__LPUART5_TX 0x0198 0x0258 0x4 0x3 +#define IMX7ULP_PAD_PTF6__LPI2C5_HREQ 0x0198 0x02b8 0x5 0x3 +#define IMX7ULP_PAD_PTF6__TPM4_CH5 0x0198 0x0294 0x6 0x2 +#define IMX7ULP_PAD_PTF6__FB_AD19 0x0198 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF7__PTF7 0x019c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF7__VIU_D3 0x019c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF7__FXIO1_D3 0x019c 0x0210 0x2 0x2 +#define IMX7ULP_PAD_PTF7__LPUART5_RX 0x019c 0x0254 0x4 0x3 +#define IMX7ULP_PAD_PTF7__TPM5_CH1 0x019c 0x02c8 0x6 0x3 +#define IMX7ULP_PAD_PTF7__FB_AD20 0x019c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF8__PTF8 0x01a0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF8__USB1_ULPI_CLK 0x01a0 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF8__VIU_D4 0x01a0 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF8__FXIO1_D4 0x01a0 0x0214 0x2 0x2 +#define IMX7ULP_PAD_PTF8__LPSPI2_SIN 0x01a0 0x02b0 0x3 0x3 +#define IMX7ULP_PAD_PTF8__LPUART6_CTS_B 0x01a0 0x025c 0x4 0x3 +#define IMX7ULP_PAD_PTF8__LPI2C6_SCL 0x01a0 0x02fc 0x5 0x3 +#define IMX7ULP_PAD_PTF8__TPM5_CLKIN 0x01a0 0x02cc 0x6 0x3 +#define IMX7ULP_PAD_PTF8__FB_AD21 0x01a0 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF9__PTF9 0x01a4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF9__USB1_ULPI_NXT 0x01a4 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF9__VIU_D5 0x01a4 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF9__FXIO1_D5 0x01a4 0x0218 0x2 0x2 +#define IMX7ULP_PAD_PTF9__LPSPI2_SOUT 0x01a4 0x02b4 0x3 0x3 +#define IMX7ULP_PAD_PTF9__LPUART6_RTS_B 0x01a4 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF9__LPI2C6_SDA 0x01a4 0x0300 0x5 0x3 +#define IMX7ULP_PAD_PTF9__TPM5_CH0 0x01a4 0x02c4 0x6 0x3 +#define IMX7ULP_PAD_PTF9__FB_AD22 0x01a4 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF10__PTF10 0x01a8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF10__USB1_ULPI_STP 0x01a8 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF10__VIU_D6 0x01a8 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF10__FXIO1_D6 0x01a8 0x021c 0x2 0x2 +#define IMX7ULP_PAD_PTF10__LPSPI2_SCK 0x01a8 0x02ac 0x3 0x3 +#define IMX7ULP_PAD_PTF10__LPUART6_TX 0x01a8 0x0264 0x4 0x3 +#define IMX7ULP_PAD_PTF10__LPI2C6_HREQ 0x01a8 0x02f8 0x5 0x3 +#define IMX7ULP_PAD_PTF10__TPM7_CH3 0x01a8 0x02e8 0x6 0x3 +#define IMX7ULP_PAD_PTF10__FB_AD23 0x01a8 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF11__PTF11 0x01ac 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF11__USB1_ULPI_DIR 0x01ac 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF11__VIU_D7 0x01ac 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF11__FXIO1_D7 0x01ac 0x0220 0x2 0x2 +#define IMX7ULP_PAD_PTF11__LPSPI2_PCS0 0x01ac 0x029c 0x3 0x3 +#define IMX7ULP_PAD_PTF11__LPUART6_RX 0x01ac 0x0260 0x4 0x3 +#define IMX7ULP_PAD_PTF11__TPM7_CH4 0x01ac 0x02ec 0x6 0x3 +#define IMX7ULP_PAD_PTF11__FB_CS4_B_FB_TSIZ0_FB_BE31_24_BLS7_0_B 0x01ac 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF12__PTF12 0x01b0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF12__USB1_ULPI_DATA0 0x01b0 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF12__VIU_D8 0x01b0 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF12__FXIO1_D8 0x01b0 0x0224 0x2 0x2 +#define IMX7ULP_PAD_PTF12__LPSPI3_PCS1 0x01b0 0x0314 0x3 0x3 +#define IMX7ULP_PAD_PTF12__LPUART7_CTS_B 0x01b0 0x0268 0x4 0x3 +#define IMX7ULP_PAD_PTF12__LPI2C7_SCL 0x01b0 0x0308 0x5 0x3 +#define IMX7ULP_PAD_PTF12__TPM7_CH5 0x01b0 0x02f0 0x6 0x3 +#define IMX7ULP_PAD_PTF12__FB_AD24 0x01b0 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF13__PTF13 0x01b4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF13__USB1_ULPI_DATA1 0x01b4 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF13__VIU_D9 0x01b4 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF13__FXIO1_D9 0x01b4 0x0228 0x2 0x2 +#define IMX7ULP_PAD_PTF13__LPSPI3_PCS2 0x01b4 0x0318 0x3 0x3 +#define IMX7ULP_PAD_PTF13__LPUART7_RTS_B 0x01b4 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF13__LPI2C7_SDA 0x01b4 0x030c 0x5 0x3 +#define IMX7ULP_PAD_PTF13__TPM7_CLKIN 0x01b4 0x02f4 0x6 0x3 +#define IMX7ULP_PAD_PTF13__FB_AD25 0x01b4 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF14__PTF14 0x01b8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF14__USB1_ULPI_DATA2 0x01b8 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF14__VIU_D10 0x01b8 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF14__FXIO1_D10 0x01b8 0x022c 0x2 0x2 +#define IMX7ULP_PAD_PTF14__LPSPI3_PCS3 0x01b8 0x031c 0x3 0x3 +#define IMX7ULP_PAD_PTF14__LPUART7_TX 0x01b8 0x0270 0x4 0x3 +#define IMX7ULP_PAD_PTF14__LPI2C7_HREQ 0x01b8 0x0304 0x5 0x3 +#define IMX7ULP_PAD_PTF14__TPM7_CH0 0x01b8 0x02dc 0x6 0x3 +#define IMX7ULP_PAD_PTF14__FB_AD26 0x01b8 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF15__PTF15 0x01bc 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF15__USB1_ULPI_DATA3 0x01bc 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF15__VIU_D11 0x01bc 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF15__FXIO1_D11 0x01bc 0x0230 0x2 0x2 +#define IMX7ULP_PAD_PTF15__LPUART7_RX 0x01bc 0x026c 0x4 0x3 +#define IMX7ULP_PAD_PTF15__TPM7_CH1 0x01bc 0x02e0 0x6 0x3 +#define IMX7ULP_PAD_PTF15__FB_AD27 0x01bc 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF16__PTF16 0x01c0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF16__USB1_ULPI_DATA4 0x01c0 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF16__VIU_D12 0x01c0 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF16__FXIO1_D12 0x01c0 0x0234 0x2 0x2 +#define IMX7ULP_PAD_PTF16__LPSPI3_SIN 0x01c0 0x0324 0x3 0x3 +#define IMX7ULP_PAD_PTF16__TPM7_CH2 0x01c0 0x02e4 0x6 0x3 +#define IMX7ULP_PAD_PTF16__FB_AD28 0x01c0 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF17__PTF17 0x01c4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF17__USB1_ULPI_DATA5 0x01c4 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF17__VIU_D13 0x01c4 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF17__FXIO1_D13 0x01c4 0x0238 0x2 0x2 +#define IMX7ULP_PAD_PTF17__LPSPI3_SOUT 0x01c4 0x0328 0x3 0x3 +#define IMX7ULP_PAD_PTF17__TPM6_CLKIN 0x01c4 0x02d8 0x6 0x3 +#define IMX7ULP_PAD_PTF17__FB_AD29 0x01c4 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF18__PTF18 0x01c8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF18__USB1_ULPI_DATA6 0x01c8 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF18__VIU_D14 0x01c8 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF18__FXIO1_D14 0x01c8 0x023c 0x2 0x2 +#define IMX7ULP_PAD_PTF18__LPSPI3_SCK 0x01c8 0x0320 0x3 0x3 +#define IMX7ULP_PAD_PTF18__TPM6_CH0 0x01c8 0x02d0 0x6 0x3 +#define IMX7ULP_PAD_PTF18__FB_AD30 0x01c8 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF19__PTF19 0x01cc 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF19__USB1_ULPI_DATA7 0x01cc 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF19__VIU_D15 0x01cc 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF19__FXIO1_D15 0x01cc 0x0240 0x2 0x2 +#define IMX7ULP_PAD_PTF19__LPSPI3_PCS0 0x01cc 0x0310 0x3 0x3 +#define IMX7ULP_PAD_PTF19__TPM6_CH1 0x01cc 0x02d4 0x6 0x3 +#define IMX7ULP_PAD_PTF19__FB_AD31 0x01cc 0x0000 0x9 0x0 + +#endif /* __DTS_IMX7ULP_PINFUNC_H */ diff --git a/arch/arm/boot/dts/keystone-k2e-evm.dts b/arch/arm/boot/dts/keystone-k2e-evm.dts index ae1ebe7ee0217e8a44d0e607149ced326a6070dc..f1f32c54e72fe7846d09de647a0d5ea8703f5f74 100644 --- a/arch/arm/boot/dts/keystone-k2e-evm.dts +++ b/arch/arm/boot/dts/keystone-k2e-evm.dts @@ -16,6 +16,19 @@ compatible = "ti,k2e-evm", "ti,k2e", "ti,keystone"; model = "Texas Instruments Keystone 2 Edison EVM"; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + soc { clocks { @@ -160,3 +173,8 @@ reg = <1>; }; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2e.dtsi b/arch/arm/boot/dts/keystone-k2e.dtsi index 0dd4cdd6d40c8afe9f15f355b8ec493844154d0f..819ab83459163963a80c9471c1b61c7eca422311 100644 --- a/arch/arm/boot/dts/keystone-k2e.dtsi +++ b/arch/arm/boot/dts/keystone-k2e.dtsi @@ -45,6 +45,10 @@ }; }; + aliases { + rproc0 = &dsp0; + }; + soc { /include/ "keystone-k2e-clocks.dtsi" @@ -114,6 +118,22 @@ gpio,syscon-dev = <&devctrl 0x240>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2e-dsp"; + reg = <0x10800000 0x00080000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem0>; + ti,syscon-dev = <&devctrl 0x844>; + resets = <&pscrst 0>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + pcie1: pcie@21020000 { compatible = "ti,keystone-pcie","snps,dw-pcie"; clocks = <&clkpcie1>; diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts index 61883cb969d2131323f0c191a5c938b9c9f3923e..f462f1043531682f2c00dcc9f287dad5df8dd03e 100644 --- a/arch/arm/boot/dts/keystone-k2g-evm.dts +++ b/arch/arm/boot/dts/keystone-k2g-evm.dts @@ -25,6 +25,26 @@ reg = <0x00000008 0x00000000 0x00000000 0x80000000>; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + + vcc3v3_dcin_reg: fixedregulator-vcc3v3-dcin { + compatible = "regulator-fixed"; + regulator-name = "mmc0_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; }; &k2g_pinctrl { @@ -34,6 +54,33 @@ K2G_CORE_IOPAD(0x11d0) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ >; }; + + mmc0_pins: pinmux_mmc0_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x1300) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat3.mmc0_dat3 */ + K2G_CORE_IOPAD(0x1304) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat2.mmc0_dat2 */ + K2G_CORE_IOPAD(0x1308) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat1.mmc0_dat1 */ + K2G_CORE_IOPAD(0x130c) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat0.mmc0_dat0 */ + K2G_CORE_IOPAD(0x1310) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_clk.mmc0_clk */ + K2G_CORE_IOPAD(0x1314) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_cmd.mmc0_cmd */ + K2G_CORE_IOPAD(0x12ec) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE3) /* mmc0_sdcd.gpio1_12 */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x10ec) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat7.mmc1_dat7 */ + K2G_CORE_IOPAD(0x10f0) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat6.mmc1_dat6 */ + K2G_CORE_IOPAD(0x10f4) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat5.mmc1_dat5 */ + K2G_CORE_IOPAD(0x10f8) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat4.mmc1_dat4 */ + K2G_CORE_IOPAD(0x10fc) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 */ + K2G_CORE_IOPAD(0x1100) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat2.mmc1_dat2 */ + K2G_CORE_IOPAD(0x1104) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat1.mmc1_dat1 */ + K2G_CORE_IOPAD(0x1108) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat0.mmc1_dat0 */ + K2G_CORE_IOPAD(0x110c) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_clk.mmc1_clk */ + K2G_CORE_IOPAD(0x1110) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_cmd.mmc1_cmd */ + >; + }; }; &uart0 { @@ -41,3 +88,27 @@ pinctrl-0 = <&uart0_pins>; status = "okay"; }; + +&gpio1 { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <&vcc3v3_dcin_reg>; + cd-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vcc3v3_dcin_reg>; /* VCC3V3_EMMC is connected to VCC3V3_DCIN */ + status = "okay"; +}; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2g-ice.dts b/arch/arm/boot/dts/keystone-k2g-ice.dts index d820d37b5148ec9f83985e55604b9f3ed2014d6d..78692745e0af2e5562f0f215b879e73f1c6df678 100644 --- a/arch/arm/boot/dts/keystone-k2g-ice.dts +++ b/arch/arm/boot/dts/keystone-k2g-ice.dts @@ -17,6 +17,19 @@ device_type = "memory"; reg = <0x00000008 0x00000000 0x00000000 0x20000000>; }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; }; &k2g_pinctrl { @@ -33,3 +46,8 @@ pinctrl-0 = <&uart0_pins>; status = "okay"; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi index a789f75a1ed522e57b8a23f5306674d19e4db6ee..826b286665e62491bc85dccf65f0528cc425512c 100644 --- a/arch/arm/boot/dts/keystone-k2g.dtsi +++ b/arch/arm/boot/dts/keystone-k2g.dtsi @@ -15,6 +15,7 @@ #include #include +#include / { compatible = "ti,k2g","ti,keystone"; @@ -27,6 +28,7 @@ aliases { serial0 = &uart0; + rproc0 = &dsp0; }; cpus { @@ -113,6 +115,24 @@ status = "disabled"; }; + dcan0: can@0260B200 { + compatible = "ti,am4372-d_can", "ti,am3352-d_can"; + reg = <0x0260B200 0x200>; + interrupts = ; + status = "disabled"; + power-domains = <&k2g_pds 0x0008>; + clocks = <&k2g_clks 0x0008 1>; + }; + + dcan1: can@0260B400 { + compatible = "ti,am4372-d_can", "ti,am3352-d_can"; + reg = <0x0260B400 0x200>; + interrupts = ; + status = "disabled"; + power-domains = <&k2g_pds 0x0009>; + clocks = <&k2g_clks 0x0009 1>; + }; + kirq0: keystone_irq@026202a0 { compatible = "ti,keystone-irq"; interrupts = ; @@ -128,6 +148,22 @@ gpio,syscon-dev = <&devctrl 0x240>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2g-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + power-domains = <&k2g_pds 0x0046>; + ti,syscon-dev = <&devctrl 0x844>; + resets = <&k2g_reset 0x0046 0x1>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + msgmgr: msgmgr@02a00000 { compatible = "ti,k2g-message-manager"; #mbox-cells = <2>; @@ -139,5 +175,173 @@ interrupts = , ; }; + + pmmc: pmmc@02921c00 { + compatible = "ti,k2g-sci"; + /* + * In case of rare platforms that does not use k2g as + * system master, use /delete-property/ + */ + ti,system-reboot-controller; + mbox-names = "rx", "tx"; + mboxes= <&msgmgr 5 2>, + <&msgmgr 0 0>; + reg-names = "debug_messages"; + reg = <0x02921c00 0x400>; + + k2g_pds: power-controller { + compatible = "ti,sci-pm-domain"; + #power-domain-cells = <1>; + }; + + k2g_clks: clocks { + compatible = "ti,k2g-sci-clk"; + #clock-cells = <2>; + }; + + k2g_reset: reset-controller { + compatible = "ti,sci-reset"; + #reset-cells = <2>; + }; + }; + + gpio0: gpio@2603000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x02603000 0x100>; + gpio-controller; + #gpio-cells = <2>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k2g_clks 0x001b 0x0>; + clock-names = "gpio"; + }; + + gpio1: gpio@260a000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x0260a000 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupts = , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + ti,ngpio = <68>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k2g_clks 0x001c 0x0>; + clock-names = "gpio"; + }; + + edma0: edma@02700000 { + compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; + reg = <0x02700000 0x8000>; + reg-names = "edma3_cc"; + interrupts = , + , + ; + interrupt-names = "edma3_ccint", "emda3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>; + + ti,edma-memcpy-channels = <32 33 34 35>; + + power-domains = <&k2g_pds 0x3f>; + }; + + edma0_tptc0: tptc@02760000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x02760000 0x400>; + power-domains = <&k2g_pds 0x3f>; + }; + + edma0_tptc1: tptc@02768000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x02768000 0x400>; + power-domains = <&k2g_pds 0x3f>; + }; + + edma1: edma@02728000 { + compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; + reg = <0x02728000 0x8000>; + reg-names = "edma3_cc"; + interrupts = , + , + ; + interrupt-names = "edma3_ccint", "emda3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma1_tptc0 7>, <&edma1_tptc1 0>; + + /* + * memcpy is disabled, can be enabled with: + * ti,edma-memcpy-channels = <12 13 14 15>; + * for example. + */ + + power-domains = <&k2g_pds 0x4f>; + }; + + edma1_tptc0: tptc@027b0000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b0000 0x400>; + power-domains = <&k2g_pds 0x4f>; + }; + + edma1_tptc1: tptc@027b8000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b8000 0x400>; + power-domains = <&k2g_pds 0x4f>; + }; + + mmc0: mmc@23000000 { + compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc"; + reg = <0x23000000 0x400>; + interrupts = ; + dmas = <&edma1 24 0>, <&edma1 25 0>; + dma-names = "tx", "rx"; + bus-width = <4>; + ti,needs-special-reset; + no-1-8-v; + max-frequency = <96000000>; + power-domains = <&k2g_pds 0xb>; + clocks = <&k2g_clks 0xb 1>, <&k2g_clks 0xb 2>; + clock-names = "fck", "mmchsdb_fck"; + status = "disabled"; + }; + + mmc1: mmc@23100000 { + compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc"; + reg = <0x23100000 0x400>; + interrupts = ; + dmas = <&edma1 26 0>, <&edma1 27 0>; + dma-names = "tx", "rx"; + bus-width = <8>; + ti,needs-special-reset; + ti,non-removable; + max-frequency = <96000000>; + power-domains = <&k2g_pds 0xc>; + clocks = <&k2g_clks 0xc 1>, <&k2g_clks 0xc 2>; + clock-names = "fck", "mmchsdb_fck"; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/keystone-k2hk-evm.dts b/arch/arm/boot/dts/keystone-k2hk-evm.dts index 2156ff92d08f1a93608ef33a5c129b44775689a0..6dd13b98aababd4f10676f9f49ce647c607c9e17 100644 --- a/arch/arm/boot/dts/keystone-k2hk-evm.dts +++ b/arch/arm/boot/dts/keystone-k2hk-evm.dts @@ -16,6 +16,19 @@ compatible = "ti,k2hk-evm", "ti,k2hk", "ti,keystone"; model = "Texas Instruments Keystone 2 Kepler/Hawking EVM"; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + soc { clocks { refclksys: refclksys { @@ -184,3 +197,43 @@ reg = <1>; }; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp1 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp2 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp3 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp4 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp5 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp6 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp7 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2hk.dtsi b/arch/arm/boot/dts/keystone-k2hk.dtsi index 69d449430511a45b2d2d242771b1ac9b7402792a..31dc00e4e5fd8ce1124c48e575b9772804a0798f 100644 --- a/arch/arm/boot/dts/keystone-k2hk.dtsi +++ b/arch/arm/boot/dts/keystone-k2hk.dtsi @@ -45,6 +45,17 @@ }; }; + aliases { + rproc0 = &dsp0; + rproc1 = &dsp1; + rproc2 = &dsp2; + rproc3 = &dsp3; + rproc4 = &dsp4; + rproc5 = &dsp5; + rproc6 = &dsp6; + rproc7 = &dsp7; + }; + soc { /include/ "keystone-k2hk-clocks.dtsi" @@ -134,6 +145,134 @@ gpio,syscon-dev = <&devctrl 0x25c>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem0>; + ti,syscon-dev = <&devctrl 0x40>; + resets = <&pscrst 0>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + + dsp1: dsp@11800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x11800000 0x00100000>, + <0x11e00000 0x00008000>, + <0x11f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem1>; + ti,syscon-dev = <&devctrl 0x44>; + resets = <&pscrst 1>; + interrupt-parent = <&kirq0>; + interrupts = <1 9>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio1 27 0>; + status = "disabled"; + }; + + dsp2: dsp@12800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x12800000 0x00100000>, + <0x12e00000 0x00008000>, + <0x12f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem2>; + ti,syscon-dev = <&devctrl 0x48>; + resets = <&pscrst 2>; + interrupt-parent = <&kirq0>; + interrupts = <2 10>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio2 27 0>; + status = "disabled"; + }; + + dsp3: dsp@13800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x13800000 0x00100000>, + <0x13e00000 0x00008000>, + <0x13f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem3>; + ti,syscon-dev = <&devctrl 0x4c>; + resets = <&pscrst 3>; + interrupt-parent = <&kirq0>; + interrupts = <3 11>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio3 27 0>; + status = "disabled"; + }; + + dsp4: dsp@14800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x14800000 0x00100000>, + <0x14e00000 0x00008000>, + <0x14f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem4>; + ti,syscon-dev = <&devctrl 0x50>; + resets = <&pscrst 4>; + interrupt-parent = <&kirq0>; + interrupts = <4 12>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio4 27 0>; + status = "disabled"; + }; + + dsp5: dsp@15800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x15800000 0x00100000>, + <0x15e00000 0x00008000>, + <0x15f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem5>; + ti,syscon-dev = <&devctrl 0x54>; + resets = <&pscrst 5>; + interrupt-parent = <&kirq0>; + interrupts = <5 13>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio5 27 0>; + status = "disabled"; + }; + + dsp6: dsp@16800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x16800000 0x00100000>, + <0x16e00000 0x00008000>, + <0x16f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem6>; + ti,syscon-dev = <&devctrl 0x58>; + resets = <&pscrst 6>; + interrupt-parent = <&kirq0>; + interrupts = <6 14>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio6 27 0>; + status = "disabled"; + }; + + dsp7: dsp@17800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x17800000 0x00100000>, + <0x17e00000 0x00008000>, + <0x17f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem7>; + ti,syscon-dev = <&devctrl 0x5c>; + resets = <&pscrst 7>; + interrupt-parent = <&kirq0>; + interrupts = <7 15>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio7 27 0>; + status = "disabled"; + }; + mdio: mdio@02090300 { compatible = "ti,keystone_mdio", "ti,davinci_mdio"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/keystone-k2l-evm.dts b/arch/arm/boot/dts/keystone-k2l-evm.dts index 056b42f99d7acabdf531af6654d282979ddebae7..528667618db45ee625916eb6d72d116a8e9e4aed 100644 --- a/arch/arm/boot/dts/keystone-k2l-evm.dts +++ b/arch/arm/boot/dts/keystone-k2l-evm.dts @@ -16,6 +16,19 @@ compatible = "ti,k2l-evm", "ti,k2l", "ti,keystone"; model = "Texas Instruments Keystone 2 Lamarr EVM"; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + soc { clocks { refclksys: refclksys { @@ -133,3 +146,23 @@ reg = <1>; }; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp1 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp2 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp3 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi index 148650406cf701cd7ffc5ac92d9054d606e97bfd..4431310bc922bf3c6e4de97f4bcd0dc2ee262056 100644 --- a/arch/arm/boot/dts/keystone-k2l.dtsi +++ b/arch/arm/boot/dts/keystone-k2l.dtsi @@ -33,6 +33,13 @@ }; }; + aliases { + rproc0 = &dsp0; + rproc1 = &dsp1; + rproc2 = &dsp2; + rproc3 = &dsp3; + }; + soc { /include/ "keystone-k2l-clocks.dtsi" @@ -268,6 +275,70 @@ gpio,syscon-dev = <&devctrl 0x24c>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2l-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem0>; + ti,syscon-dev = <&devctrl 0x844>; + resets = <&pscrst 0>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + + dsp1: dsp@11800000 { + compatible = "ti,k2l-dsp"; + reg = <0x11800000 0x00100000>, + <0x11e00000 0x00008000>, + <0x11f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem1>; + ti,syscon-dev = <&devctrl 0x848>; + resets = <&pscrst 1>; + interrupt-parent = <&kirq0>; + interrupts = <1 9>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio1 27 0>; + status = "disabled"; + }; + + dsp2: dsp@12800000 { + compatible = "ti,k2l-dsp"; + reg = <0x12800000 0x00100000>, + <0x12e00000 0x00008000>, + <0x12f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem2>; + ti,syscon-dev = <&devctrl 0x84c>; + resets = <&pscrst 2>; + interrupt-parent = <&kirq0>; + interrupts = <2 10>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio2 27 0>; + status = "disabled"; + }; + + dsp3: dsp@13800000 { + compatible = "ti,k2l-dsp"; + reg = <0x13800000 0x00100000>, + <0x13e00000 0x00008000>, + <0x13f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem3>; + ti,syscon-dev = <&devctrl 0x850>; + resets = <&pscrst 3>; + interrupt-parent = <&kirq0>; + interrupts = <3 11>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio3 27 0>; + status = "disabled"; + }; + mdio: mdio@26200f00 { compatible = "ti,keystone_mdio", "ti,davinci_mdio"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/kirkwood-6192.dtsi b/arch/arm/boot/dts/kirkwood-6192.dtsi index d573e03f3134b709f8d6c8ef6ca37c4d7dc9b9c4..f003f3f1bd659d39139f03890565162cc6e321b6 100644 --- a/arch/arm/boot/dts/kirkwood-6192.dtsi +++ b/arch/arm/boot/dts/kirkwood-6192.dtsi @@ -1,6 +1,6 @@ / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -24,6 +24,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/kirkwood-6281.dtsi b/arch/arm/boot/dts/kirkwood-6281.dtsi index 748d0b62f233348f4e0c01216053087932a327b0..47d4b3d3d9e969ee5ca47dd32fb0c53035c8e700 100644 --- a/arch/arm/boot/dts/kirkwood-6281.dtsi +++ b/arch/arm/boot/dts/kirkwood-6281.dtsi @@ -1,6 +1,6 @@ / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -24,6 +24,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/kirkwood-6282.dtsi b/arch/arm/boot/dts/kirkwood-6282.dtsi index bb63d2d50fc533f9f264b16ef7fe8b6b3ba441ac..a13dad0a7c080b84db015d36d949daa544bcb05f 100644 --- a/arch/arm/boot/dts/kirkwood-6282.dtsi +++ b/arch/arm/boot/dts/kirkwood-6282.dtsi @@ -1,6 +1,6 @@ / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -28,6 +28,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; @@ -45,6 +46,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 10>; marvell,pcie-port = <1>; diff --git a/arch/arm/boot/dts/kirkwood-98dx4122.dtsi b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi index 720c210d491dc80e25241dac26506dd52533010e..90d4d71b6683cbaa196a9fe16581dce41ef44ea1 100644 --- a/arch/arm/boot/dts/kirkwood-98dx4122.dtsi +++ b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi @@ -1,6 +1,6 @@ / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -24,6 +24,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts index 43e9364083de84383a34815c04a6bd1021b3baa0..b4575bbaf0852a4cfff98f5bae93f8eb93c4d6ef 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts @@ -192,7 +192,7 @@ interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins &mmc1_cd>; - cd-gpios = <&gpio4 31 IRQ_TYPE_LEVEL_LOW>; /* gpio127 */ + cd-gpios = <&gpio4 31 GPIO_ACTIVE_LOW>; /* gpio127 */ vmmc-supply = <&vmmc1>; bus-width = <4>; cap-power-off-card; diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 7bb9df2c1460e510cf58b35c6d6a39818e821e69..9319e1f0f1d8f8360ad11513b178bca7cc71d9fe 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -129,14 +129,14 @@ }; msi1: msi-controller@1570e00 { - compatible = "fsl,1s1021a-msi"; + compatible = "fsl,ls1021a-msi"; reg = <0x0 0x1570e00 0x0 0x8>; msi-controller; interrupts = ; }; msi2: msi-controller@1570e08 { - compatible = "fsl,1s1021a-msi"; + compatible = "fsl,ls1021a-msi"; reg = <0x0 0x1570e08 0x0 0x8>; msi-controller; interrupts = ; @@ -699,7 +699,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi1>; + msi-parent = <&msi1>, <&msi2>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, @@ -722,7 +722,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi2>; + msi-parent = <&msi1>, <&msi2>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi index 15204e44161da6c98e8528488c8bf2be3a46ca6a..cd6ad072e72c17ebe287b72d3f26657a402a97ba 100644 --- a/arch/arm/boot/dts/meson.dtsi +++ b/arch/arm/boot/dts/meson.dtsi @@ -86,14 +86,14 @@ }; uart_A: serial@84c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; reg = <0x84c0 0x18>; interrupts = ; status = "disabled"; }; uart_B: serial@84dc { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; reg = <0x84dc 0x18>; interrupts = ; status = "disabled"; @@ -108,6 +108,20 @@ status = "disabled"; }; + pwm_ab: pwm@8550 { + compatible = "amlogic,meson-pwm"; + reg = <0x8550 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_cd: pwm@8650 { + compatible = "amlogic,meson-pwm"; + reg = <0x8650 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + saradc: adc@8680 { compatible = "amlogic,meson-saradc"; reg = <0x8680 0x34>; @@ -117,7 +131,7 @@ }; uart_C: serial@8700 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; reg = <0x8700 0x18>; interrupts = ; status = "disabled"; @@ -182,7 +196,7 @@ }; uart_AO: serial@4c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; reg = <0x4c0 0x18>; interrupts = ; status = "disabled"; @@ -230,5 +244,13 @@ interrupt-names = "macirq"; status = "disabled"; }; + + ahb_sram: sram@d9000000 { + compatible = "mmio-sram"; + reg = <0xd9000000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xd9000000 0x20000>; + }; }; }; /* end of / */ diff --git a/arch/arm/boot/dts/meson6.dtsi b/arch/arm/boot/dts/meson6.dtsi index 8557b6117a4b97f23bf2359d585d1e6c2c787d49..ef281d2900527703af28b49f425df50415d1bd2d 100644 --- a/arch/arm/boot/dts/meson6.dtsi +++ b/arch/arm/boot/dts/meson6.dtsi @@ -70,9 +70,37 @@ }; }; + xtal: xtal-clk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xtal"; + #clock-cells = <0>; + }; + clk81: clk@0 { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <200000000>; }; }; /* end of / */ + + +&uart_AO { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_A { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_B { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_C { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index cada35828931e49a4e37d750bfbe837064488262..b98d44fde6b60bc9301a3b23cb65f2ccd0d8e64c 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -168,10 +168,18 @@ &cbus { clkc: clock-controller@4000 { #clock-cells = <1>; + #reset-cells = <1>; compatible = "amlogic,meson8-clkc"; reg = <0x8000 0x4>, <0x4000 0x460>; }; + pwm_ef: pwm@86c0 { + compatible = "amlogic,meson8-pwm", "amlogic,meson8b-pwm"; + reg = <0x86c0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + pinctrl_cbus: pinctrl@9880 { compatible = "amlogic,meson8-cbus-pinctrl"; reg = <0x9880 0x10>; @@ -270,6 +278,14 @@ arm,filter-ranges = <0x100000 0xc0000000>; }; +&pwm_ab { + compatible = "amlogic,meson8-pwm", "amlogic,meson8b-pwm"; +}; + +&pwm_cd { + compatible = "amlogic,meson8-pwm", "amlogic,meson8b-pwm"; +}; + &saradc { compatible = "amlogic,meson8-saradc", "amlogic,meson-saradc"; clocks = <&clkc CLKID_XTAL>, diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 72e4f425f190d03902713831eb8ba5b1a6373c77..bc278da7df0d93b260eb36d0080b64de2711c592 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -119,6 +119,7 @@ &cbus { clkc: clock-controller@4000 { #clock-cells = <1>; + #reset-cells = <1>; compatible = "amlogic,meson8b-clkc"; reg = <0x8000 0x4>, <0x4000 0x460>; }; @@ -129,20 +130,6 @@ #reset-cells = <1>; }; - pwm_ab: pwm@8550 { - compatible = "amlogic,meson8b-pwm"; - reg = <0x8550 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pwm_cd: pwm@8650 { - compatible = "amlogic,meson8b-pwm"; - reg = <0x8650 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - pwm_ef: pwm@86c0 { compatible = "amlogic,meson8b-pwm"; reg = <0x86c0 0x10>; @@ -150,12 +137,6 @@ status = "disabled"; }; - wdt: watchdog@9900 { - compatible = "amlogic,meson8b-wdt"; - reg = <0x9900 0x8>; - interrupts = <0 0 1>; - }; - pinctrl_cbus: pinctrl@9880 { compatible = "amlogic,meson8b-cbus-pinctrl"; reg = <0x9880 0x10>; @@ -193,6 +174,14 @@ arm,filter-ranges = <0x100000 0xc0000000>; }; +&pwm_ab { + compatible = "amlogic,meson8b-pwm"; +}; + +&pwm_cd { + compatible = "amlogic,meson8b-pwm"; +}; + &saradc { compatible = "amlogic,meson8b-saradc", "amlogic,meson-saradc"; clocks = <&clkc CLKID_XTAL>, @@ -242,3 +231,7 @@ clock-names = "usb_general", "usb"; resets = <&reset RESET_USB_OTG>; }; + +&wdt { + compatible = "amlogic,meson8b-wdt"; +}; diff --git a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi index 1eb5da1dc8f0a9fd2ee02195678b56aa67ddf23a..4d61e5b1334a632b984016bada159e94ce34e1a2 100644 --- a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi +++ b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi @@ -255,5 +255,6 @@ regulator-min-microvolt = <2775000>; regulator-max-microvolt = <2775000>; regulator-enable-ramp-delay = <1000>; + regulator-initial-mode = <0x00>; /* NORMAL */ }; }; diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index f1efdc63656a52bb271aa3d8ac554aede0e74d68..afe12e5b51f95374e2f8f5f91b91f2bbc189e193 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -533,6 +534,7 @@ compatible = "mediatek,mt2701-smi-larb"; reg = <0 0x14010000 0 0x1000>; mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; clocks = <&mmsys CLK_MM_SMI_LARB0>, <&mmsys CLK_MM_SMI_LARB0>; clock-names = "apb", "smi"; @@ -549,6 +551,7 @@ compatible = "mediatek,mt2701-smi-larb"; reg = <0 0x15001000 0 0x1000>; mediatek,smi = <&smi_common>; + mediatek,larb-id = <2>; clocks = <&imgsys CLK_IMG_SMI_COMM>, <&imgsys CLK_IMG_SMI_COMM>; clock-names = "apb", "smi"; @@ -579,6 +582,7 @@ compatible = "mediatek,mt2701-smi-larb"; reg = <0 0x16010000 0 0x1000>; mediatek,smi = <&smi_common>; + mediatek,larb-id = <1>; clocks = <&vdecsys CLK_VDEC_CKGEN>, <&vdecsys CLK_VDEC_LARB>; clock-names = "apb", "smi"; @@ -591,12 +595,114 @@ #clock-cells = <1>; }; + usb0: usb@1a1c0000 { + compatible = "mediatek,mt8173-xhci"; + reg = <0 0x1a1c0000 0 0x1000>, + <0 0x1a1c4700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + clocks = <&hifsys CLK_HIFSYS_USB0PHY>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "sys_ck", "ref_ck"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>; + status = "disabled"; + }; + + u3phy0: usb-phy@1a1c4000 { + compatible = "mediatek,mt2701-u3phy"; + reg = <0 0x1a1c4000 0 0x0700>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port0: usb-phy@1a1c4800 { + reg = <0 0x1a1c4800 0 0x0100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port0: usb-phy@1a1c4900 { + reg = <0 0x1a1c4900 0 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + + usb1: usb@1a240000 { + compatible = "mediatek,mt8173-xhci"; + reg = <0 0x1a240000 0 0x1000>, + <0 0x1a244700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + clocks = <&hifsys CLK_HIFSYS_USB1PHY>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "sys_ck", "ref_ck"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>; + status = "disabled"; + }; + + u3phy1: usb-phy@1a244000 { + compatible = "mediatek,mt2701-u3phy"; + reg = <0 0x1a244000 0 0x0700>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port1: usb-phy@1a244800 { + reg = <0 0x1a244800 0 0x0100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port1: usb-phy@1a244900 { + reg = <0 0x1a244900 0 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + ethsys: syscon@1b000000 { compatible = "mediatek,mt2701-ethsys", "syscon"; reg = <0 0x1b000000 0 0x1000>; #clock-cells = <1>; }; + eth: ethernet@1b100000 { + compatible = "mediatek,mt2701-eth", "syscon"; + reg = <0 0x1b100000 0 0x20000>; + interrupts = , + , + ; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <ðsys CLK_ETHSYS_ESW>, + <ðsys CLK_ETHSYS_GP1>, + <ðsys CLK_ETHSYS_GP2>, + <&apmixedsys CLK_APMIXED_TRGPLL>; + clock-names = "ethif", "esw", "gp1", "gp2", "trgpll"; + resets = <ðsys MT2701_ETHSYS_FE_RST>, + <ðsys MT2701_ETHSYS_GMAC_RST>, + <ðsys MT2701_ETHSYS_PPE_RST>; + reset-names = "fe", "gmac", "ppe"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; + mediatek,ethsys = <ðsys>; + mediatek,pctl = <&syscfg_pctl_a>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + bdpsys: syscon@1c000000 { compatible = "mediatek,mt2701-bdpsys", "syscon"; reg = <0 0x1c000000 0 0x1000>; diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7c783d6c750e31e232828276471844340be111a4 --- /dev/null +++ b/arch/arm/boot/dts/mt6323.dtsi @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: John Crispin + * Sean Wang + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&pwrap { + pmic: mt6323 { + compatible = "mediatek,mt6323"; + interrupt-parent = <&pio>; + interrupts = <150 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <2>; + + mt6323regulator: mt6323regulator{ + compatible = "mediatek,mt6323-regulator"; + + mt6323_vproc_reg: buck_vproc{ + regulator-name = "vproc"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vsys_reg: buck_vsys{ + regulator-name = "vsys"; + regulator-min-microvolt = <1400000>; + regulator-max-microvolt = <2987500>; + regulator-ramp-delay = <25000>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vpa_reg: buck_vpa{ + regulator-name = "vpa"; + regulator-min-microvolt = < 500000>; + regulator-max-microvolt = <3650000>; + }; + + mt6323_vtcxo_reg: ldo_vtcxo{ + regulator-name = "vtcxo"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <90>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcn28_reg: ldo_vcn28{ + regulator-name = "vcn28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <185>; + }; + + mt6323_vcn33_bt_reg: ldo_vcn33_bt{ + regulator-name = "vcn33_bt"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3600000>; + regulator-enable-ramp-delay = <185>; + }; + + mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{ + regulator-name = "vcn33_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3600000>; + regulator-enable-ramp-delay = <185>; + }; + + mt6323_va_reg: ldo_va{ + regulator-name = "va"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcama_reg: ldo_vcama{ + regulator-name = "vcama"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vio28_reg: ldo_vio28{ + regulator-name = "vio28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vusb_reg: ldo_vusb{ + regulator-name = "vusb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <216>; + regulator-boot-on; + }; + + mt6323_vmc_reg: ldo_vmc{ + regulator-name = "vmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + regulator-boot-on; + }; + + mt6323_vmch_reg: ldo_vmch{ + regulator-name = "vmch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + regulator-boot-on; + }; + + mt6323_vemc3v3_reg: ldo_vemc3v3{ + regulator-name = "vemc3v3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + regulator-boot-on; + }; + + mt6323_vgp1_reg: ldo_vgp1{ + regulator-name = "vgp1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vgp2_reg: ldo_vgp2{ + regulator-name = "vgp2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vgp3_reg: ldo_vgp3{ + regulator-name = "vgp3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vcn18_reg: ldo_vcn18{ + regulator-name = "vcn18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vsim1_reg: ldo_vsim1{ + regulator-name = "vsim1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vsim2_reg: ldo_vsim2{ + regulator-name = "vsim2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vrtc_reg: ldo_vrtc{ + regulator-name = "vrtc"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcamaf_reg: ldo_vcamaf{ + regulator-name = "vcamaf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vibr_reg: ldo_vibr{ + regulator-name = "vibr"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + }; + + mt6323_vrf18_reg: ldo_vrf18{ + regulator-name = "vrf18"; + regulator-min-microvolt = <1825000>; + regulator-max-microvolt = <1825000>; + regulator-enable-ramp-delay = <187>; + }; + + mt6323_vm_reg: ldo_vm{ + regulator-name = "vm"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vio18_reg: ldo_vio18{ + regulator-name = "vio18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcamd_reg: ldo_vcamd{ + regulator-name = "vcamd"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vcamio_reg: ldo_vcamio{ + regulator-name = "vcamio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi index d81158b2b02f00cba1446bbba3e62139481f0d89..ec8a07415cb38816db5990aa240744b9d9b27e64 100644 --- a/arch/arm/boot/dts/mt7623.dtsi +++ b/arch/arm/boot/dts/mt7623.dtsi @@ -21,36 +21,99 @@ #include #include #include +#include #include "skeleton64.dtsi" / { compatible = "mediatek,mt7623"; interrupt-parent = <&sysirq>; + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-98000000 { + opp-hz = /bits/ 64 <98000000>; + opp-microvolt = <1050000>; + }; + + opp-198000000 { + opp-hz = /bits/ 64 <198000000>; + opp-microvolt = <1050000>; + }; + + opp-398000000 { + opp-hz = /bits/ 64 <398000000>; + opp-microvolt = <1050000>; + }; + + opp-598000000 { + opp-hz = /bits/ 64 <598000000>; + opp-microvolt = <1050000>; + }; + + opp-747500000 { + opp-hz = /bits/ 64 <747500000>; + opp-microvolt = <1050000>; + }; + + opp-1040000000 { + opp-hz = /bits/ 64 <1040000000>; + opp-microvolt = <1150000>; + }; + + opp-1196000000 { + opp-hz = /bits/ 64 <1196000000>; + opp-microvolt = <1200000>; + }; + + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1300000>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; enable-method = "mediatek,mt6589-smp"; - cpu@0 { + cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x0>; + clocks = <&infracfg CLK_INFRA_CPUSEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + cooling-min-level = <0>; + cooling-max-level = <7>; + clock-frequency = <1300000000>; }; - cpu@1 { + + cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + clock-frequency = <1300000000>; }; - cpu@2 { + + cpu2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x2>; + operating-points-v2 = <&cpu_opp_table>; + clock-frequency = <1300000000>; }; - cpu@3 { + + cpu3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x3>; + operating-points-v2 = <&cpu_opp_table>; + clock-frequency = <1300000000>; }; }; @@ -74,6 +137,58 @@ clock-output-names = "clk26m"; }; + thermal-zones { + cpu_thermal: cpu_thermal { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = <&thermal 0>; + + trips { + cpu_passive: cpu_passive { + temperature = <47000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_active: cpu_active { + temperature = <67000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_hot: cpu_hot { + temperature = <87000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu_crit { + temperature = <107000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_passive>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&cpu_active>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map2 { + trip = <&cpu_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupt-parent = <&gic>; @@ -172,7 +287,7 @@ clock-names = "spi", "wrap"; }; - cir: cir@0x10013000 { + cir: cir@10013000 { compatible = "mediatek,mt7623-cir"; reg = <0 0x10013000 0 0x1000>; interrupts = ; @@ -193,7 +308,7 @@ efuse: efuse@10206000 { compatible = "mediatek,mt7623-efuse", "mediatek,mt8173-efuse"; - reg = <0 0x10206000 0 0x1000>; + reg = <0 0x10206000 0 0x1000>; #address-cells = <1>; #size-cells = <1>; thermal_calibration_data: calib@424 { @@ -371,6 +486,31 @@ nvmem-cell-names = "calibration-data"; }; + nandc: nfi@1100d000 { + compatible = "mediatek,mt7623-nfc", + "mediatek,mt2701-nfc"; + reg = <0 0x1100d000 0 0x1000>; + interrupts = ; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + clocks = <&pericfg CLK_PERI_NFI>, + <&pericfg CLK_PERI_NFI_PAD>; + clock-names = "nfi_clk", "pad_clk"; + status = "disabled"; + ecc-engine = <&bch>; + #address-cells = <1>; + #size-cells = <0>; + }; + + bch: ecc@1100e000 { + compatible = "mediatek,mt7623-ecc", + "mediatek,mt2701-ecc"; + reg = <0 0x1100e000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_NFI_ECC>; + clock-names = "nfiecc_clk"; + status = "disabled"; + }; + spi1: spi@11016000 { compatible = "mediatek,mt7623-spi", "mediatek,mt2701-spi"; @@ -399,31 +539,6 @@ status = "disabled"; }; - nandc: nfi@1100d000 { - compatible = "mediatek,mt7623-nfc", - "mediatek,mt2701-nfc"; - reg = <0 0x1100d000 0 0x1000>; - interrupts = ; - power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; - clocks = <&pericfg CLK_PERI_NFI>, - <&pericfg CLK_PERI_NFI_PAD>; - clock-names = "nfi_clk", "pad_clk"; - status = "disabled"; - ecc-engine = <&bch>; - #address-cells = <1>; - #size-cells = <0>; - }; - - bch: ecc@1100e000 { - compatible = "mediatek,mt7623-ecc", - "mediatek,mt2701-ecc"; - reg = <0 0x1100e000 0 0x1000>; - interrupts = ; - clocks = <&pericfg CLK_PERI_NFI_ECC>; - clock-names = "nfiecc_clk"; - status = "disabled"; - }; - afe: audio-controller@11220000 { compatible = "mediatek,mt7623-audio", "mediatek,mt2701-audio"; @@ -538,13 +653,22 @@ compatible = "mediatek,mt7623-mmc", "mediatek,mt8135-mmc"; reg = <0 0x11240000 0 0x1000>; - interrupts = ; + interrupts = ; clocks = <&pericfg CLK_PERI_MSDC30_1>, <&topckgen CLK_TOP_MSDC30_1_SEL>; clock-names = "source", "hclk"; status = "disabled"; }; + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + usb1: usb@1a1c0000 { compatible = "mediatek,mt7623-xhci", "mediatek,mt8173-xhci"; @@ -561,7 +685,8 @@ }; u3phy1: usb-phy@1a1c4000 { - compatible = "mediatek,mt7623-u3phy", "mediatek,mt2701-u3phy"; + compatible = "mediatek,mt7623-u3phy", + "mediatek,mt2701-u3phy"; reg = <0 0x1a1c4000 0 0x0700>; clocks = <&clk26m>; clock-names = "u3phya_ref"; @@ -599,7 +724,8 @@ }; u3phy2: usb-phy@1a244000 { - compatible = "mediatek,mt7623-u3phy", "mediatek,mt2701-u3phy"; + compatible = "mediatek,mt7623-u3phy", + "mediatek,mt2701-u3phy"; reg = <0 0x1a244000 0 0x0700>; clocks = <&clk26m>; clock-names = "u3phya_ref"; @@ -621,15 +747,6 @@ }; }; - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", - "syscon"; - reg = <0 0x1a000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", @@ -639,7 +756,9 @@ }; eth: ethernet@1b100000 { - compatible = "mediatek,mt2701-eth", "syscon"; + compatible = "mediatek,mt7623-eth", + "mediatek,mt2701-eth", + "syscon"; reg = <0 0x1b100000 0 0x20000>; interrupts = , , @@ -650,6 +769,10 @@ <ðsys CLK_ETHSYS_GP2>, <&apmixedsys CLK_APMIXED_TRGPLL>; clock-names = "ethif", "esw", "gp1", "gp2", "trgpll"; + resets = <ðsys MT2701_ETHSYS_FE_RST>, + <ðsys MT2701_ETHSYS_GMAC_RST>, + <ðsys MT2701_ETHSYS_PPE_RST>; + reset-names = "fe", "gmac", "ppe"; power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; mediatek,ethsys = <ðsys>; mediatek,pctl = <&syscfg_pctl_a>; diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts new file mode 100644 index 0000000000000000000000000000000000000000..688a86378ceef8148526c5f1c68ed0f87c99b967 --- /dev/null +++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts @@ -0,0 +1,487 @@ +/* + * Copyright 2017 Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include +#include "mt7623.dtsi" +#include "mt6323.dtsi" + +/ { + model = "Bananapi BPI-R2"; + compatible = "bananapi,bpi-r2", "mediatek,mt7623"; + + aliases { + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@1 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@2 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@3 { + proc-supply = <&mt6323_vproc_reg>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&key_pins_a>; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 256 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 257 GPIO_ACTIVE_HIGH>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_a>; + + blue { + label = "bpi-r2:pio:blue"; + gpios = <&pio 241 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + green { + label = "bpi-r2:pio:green"; + gpios = <&pio 240 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red { + label = "bpi-r2:pio:red"; + gpios = <&pio 239 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + memory@80000000 { + reg = <0 0x80000000 0 0x40000000>; + }; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; + status = "okay"; +}; + +&crypto { + status = "okay"; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7530"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + pinctrl-names = "default"; + reset-gpios = <&pio 33 0>; + core-supply = <&mt6323_vpa_reg>; + io-supply = <&mt6323_vemc3v3_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + port@0 { + reg = <0>; + label = "wan"; + }; + + port@1 { + reg = <1>; + label = "lan0"; + }; + + port@2 { + reg = <2>; + label = "lan1"; + }; + + port@3 { + reg = <3>; + label = "lan2"; + }; + + port@4 { + reg = <4>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_default>; + pinctrl-1 = <&mmc0_pins_uhs>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + vmmc-supply = <&mt6323_vemc3v3_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; + non-removable; +}; + +&mmc1 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_uhs>; + status = "okay"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + cd-gpios = <&pio 261 0>; + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; +}; + +&pio { + cir_pins_a:cir@0 { + pins_cir { + pinmux = ; + bias-disable; + }; + }; + + i2c0_pins_a: i2c@0 { + pins_i2c0 { + pinmux = , + ; + bias-disable; + }; + }; + + i2c1_pins_a: i2c@1 { + pin_i2c1 { + pinmux = , + ; + bias-disable; + }; + }; + + i2s0_pins_a: i2s@0 { + pin_i2s0 { + pinmux = , + , + , + , + ; + drive-strength = ; + bias-pull-down; + }; + }; + + i2s1_pins_a: i2s@1 { + pin_i2s1 { + pinmux = , + , + , + , + ; + drive-strength = ; + bias-pull-down; + }; + }; + + key_pins_a: keys@0 { + pins_keys { + pinmux = , + ; + input-enable; + }; + }; + + led_pins_a: leds@0 { + pins_leds { + pinmux = , + , + ; + }; + }; + + mmc0_pins_default: mmc0default { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + bias-pull-up; + }; + + pins_clk { + pinmux = ; + bias-pull-down; + }; + + pins_rst { + pinmux = ; + bias-pull-up; + }; + }; + + mmc0_pins_uhs: mmc0 { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + + pins_rst { + pinmux = ; + bias-pull-up; + }; + }; + + mmc1_pins_default: mmc1default { + pins_cmd_dat { + pinmux = , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + bias-pull-down; + drive-strength = ; + }; + + pins_wp { + pinmux = ; + input-enable; + bias-pull-up; + }; + + pins_insert { + pinmux = ; + bias-pull-up; + }; + }; + + mmc1_pins_uhs: mmc1 { + pins_cmd_dat { + pinmux = , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + }; + + pwm_pins_a: pwm@0 { + pins_pwm { + pinmux = , + , + , + , + ; + }; + }; + + spi0_pins_a: spi@0 { + pins_spi { + pinmux = , + , + , + ; + bias-disable; + }; + }; + + uart0_pins_a: uart@0 { + pins_dat { + pinmux = , + ; + }; + }; + + uart1_pins_a: uart@1 { + pins_dat { + pinmux = , + ; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins_a>; + status = "okay"; +}; + +&pwrap { + mt6323 { + mt6323led: led { + compatible = "mediatek,mt6323-led"; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + label = "bpi-r2:isink:green"; + default-state = "off"; + }; + + led@1 { + reg = <1>; + label = "bpi-r2:isink:red"; + default-state = "off"; + }; + + led@2 { + reg = <2>; + label = "bpi-r2:isink:blue"; + default-state = "off"; + }; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins_a>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "disabled"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_a>; + status = "disabled"; +}; + +&uart2 { + status = "okay"; +}; + +&usb1 { + vusb33-supply = <&mt6323_vusb_reg>; + status = "okay"; +}; + +&usb2 { + vusb33-supply = <&mt6323_vusb_reg>; + status = "okay"; +}; + +&u3phy1 { + status = "okay"; +}; + +&u3phy2 { + status = "okay"; +}; + diff --git a/arch/arm/boot/dts/mt7623n-rfb-nand.dts b/arch/arm/boot/dts/mt7623n-rfb-nand.dts new file mode 100644 index 0000000000000000000000000000000000000000..17c578f0d261b255c34e45930d90911aba26932e --- /dev/null +++ b/arch/arm/boot/dts/mt7623n-rfb-nand.dts @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: John Crispin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +#include "mt7623n-rfb.dtsi" + +/ { + model = "MediaTek MT7623N NAND reference board"; + compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623"; +}; + +&bch { + status = "okay"; +}; + +&nandc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&nand_pins_default>; + + nand@0 { + reg = <0>; + spare_per_sector = <64>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <12>; + nand-ecc-step-size = <1024>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "preloader"; + reg = <0x0 0x40000>; + }; + + partition@40000 { + label = "uboot"; + reg = <0x40000 0x80000>; + }; + + partition@C0000 { + label = "uboot-env"; + reg = <0xC0000 0x40000>; + }; + + partition@140000 { + label = "bootimg"; + reg = <0x140000 0x2000000>; + }; + + partition@2140000 { + label = "recovery"; + reg = <0x2140000 0x2000000>; + }; + + partition@4140000 { + label = "rootfs"; + reg = <0x4140000 0x1000000>; + }; + + partition@5140000 { + label = "usrdata"; + reg = <0x5140000 0x1000000>; + }; + }; + }; +}; + +&pio { + nand_pins_default: nanddefault { + pins_ale { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + + pins_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up; + }; + + pins_we { + pinmux = ; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; diff --git a/arch/arm/boot/dts/mt7623n-rfb.dtsi b/arch/arm/boot/dts/mt7623n-rfb.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..256c5fd947bf4344bc6fbd42156ca523a52c3489 --- /dev/null +++ b/arch/arm/boot/dts/mt7623n-rfb.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: John Crispin + * Sean Wang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +#include "mt7623.dtsi" +#include "mt6323.dtsi" + +/ { + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + cpus { + cpu0 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu1 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu2 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu3 { + proc-supply = <&mt6323_vproc_reg>; + }; + }; + + memory@80000000 { + reg = <0 0x80000000 0 0x40000000>; + }; + + usb_p1_vbus: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 135 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&mmc0 { + vmmc-supply = <&mt6323_vemc3v3_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; +}; + +&mmc1 { + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vmc_reg>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb1 { + vbus-supply = <&usb_p1_vbus>; + status = "okay"; +}; + +&u3phy1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi index 7e5ffc583c90ab565d05b0d3850ae82bdbe16074..91886231e5a87217acdb6266285e67c2dc581eb7 100644 --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi @@ -15,8 +15,8 @@ >; #address-cells = <1>; #size-cells = <0>; - retu_mfd: retu@1 { - compatible = "retu-mfd"; + retu: retu@1 { + compatible = "nokia,retu"; interrupt-parent = <&gpio4>; interrupts = <12 IRQ_TYPE_EDGE_RISING>; reg = <0x1>; diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 673cee2234b2979f4102236b3296b13fb9aed244..683b96a8f73e01248349440d1caab8fd7ffeb7cc 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -299,7 +299,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 4be85ce59dd14eea19c95dc0cea5ff12748177bc..4d2eaf843fa960190514dffb06b24d46056adb3e 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -283,7 +283,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts index 53ae04f9104d6b92f6bce75c337d5fba1c77ae53..3d293b345e9940e31f525f38ea46153a170aa50b 100644 --- a/arch/arm/boot/dts/omap3-cm-t3517.dts +++ b/arch/arm/boot/dts/omap3-cm-t3517.dts @@ -129,7 +129,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&wl12xx_vmmc2>; - vmmc_aux-supply = <&wl12xx_vaux2>; + vqmmc-supply = <&wl12xx_vaux2>; non-removable; bus-width = <4>; cap-power-off-card; diff --git a/arch/arm/boot/dts/omap3-cm-t3730.dts b/arch/arm/boot/dts/omap3-cm-t3730.dts index 2294f5b0aa102d9195aa93b33a9e298ac91cba26..bdf4b7fdda39c1c64e2493ecd8d00cfc4f106985 100644 --- a/arch/arm/boot/dts/omap3-cm-t3730.dts +++ b/arch/arm/boot/dts/omap3-cm-t3730.dts @@ -69,7 +69,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&wl12xx_vmmc2>; - vmmc_aux-supply = <&wl12xx_vaux2>; + vqmmc-supply = <&wl12xx_vaux2>; non-removable; bus-width = <4>; cap-power-off-card; diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi index 82aa9c4a0f1c331f54c70409993ee17bdc493d00..0c0bb1b01b0ba004af0afbb5c5b4fca099a57055 100644 --- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi +++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi @@ -149,7 +149,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi index 2b1d6977a53572ead16e74ff97310fbd3cf7fcc3..ff35803088e3455b2fa116e4e7e41872590f053b 100644 --- a/arch/arm/boot/dts/omap3-evm-common.dtsi +++ b/arch/arm/boot/dts/omap3-evm-common.dtsi @@ -115,7 +115,7 @@ &mmc1 { interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>; vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 49f37084e43507b1f2b87b11d79eecacfe0599dc..4acd32a1c4ef7c8801bbd516f2f317d50db21218 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -164,6 +164,29 @@ }; }; +&isp { + vdds_csib-supply = <&vaux2>; + + pinctrl-names = "default"; + pinctrl-0 = <&camera_pins>; + + ports { + port@1 { + reg = <1>; + + csi_isp: endpoint { + remote-endpoint = <&csi_cam1>; + bus-type = <3>; /* CCP2 */ + clock-lanes = <1>; + data-lanes = <0>; + lane-polarity = <0 0>; + /* Select strobe = <1> for back camera, <0> for front camera */ + strobe = <1>; + }; + }; + }; +}; + &omap3_pmx_core { pinctrl-names = "default"; @@ -328,6 +351,22 @@ OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* gpio 157 => cmt_bsi */ >; }; + + camera_pins: pinmux_camera { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x210c, PIN_OUTPUT | MUX_MODE7) /* cam_hs */ + OMAP3_CORE1_IOPAD(0x210e, PIN_OUTPUT | MUX_MODE7) /* cam_vs */ + OMAP3_CORE1_IOPAD(0x2110, PIN_OUTPUT | MUX_MODE0) /* cam_xclka */ + OMAP3_CORE1_IOPAD(0x211e, PIN_OUTPUT | MUX_MODE7) /* cam_d4 */ + OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE0) /* cam_d6 */ + OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE0) /* cam_d7 */ + OMAP3_CORE1_IOPAD(0x2126, PIN_INPUT | MUX_MODE0) /* cam_d8 */ + OMAP3_CORE1_IOPAD(0x2128, PIN_INPUT | MUX_MODE0) /* cam_d9 */ + OMAP3_CORE1_IOPAD(0x212a, PIN_OUTPUT | MUX_MODE7) /* cam_d10 */ + OMAP3_CORE1_IOPAD(0x212e, PIN_OUTPUT | MUX_MODE7) /* cam_xclkb */ + OMAP3_CORE1_IOPAD(0x2132, PIN_OUTPUT | MUX_MODE0) /* cam_strobe */ + >; + }; }; &i2c1 { @@ -726,6 +765,40 @@ st,max-limit-y = <32>; st,max-limit-z = <32>; }; + + cam1: camera@3e { + compatible = "toshiba,et8ek8"; + reg = <0x3e>; + + vana-supply = <&vaux4>; + + clocks = <&isp 0>; + clock-names = "extclk"; + clock-frequency = <9600000>; + + reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */ + + port { + csi_cam1: endpoint { + bus-type = <3>; /* CCP2 */ + strobe = <1>; + clock-inv = <0>; + crc = <1>; + + remote-endpoint = <&csi_isp>; + }; + }; + }; + + /* D/A converter for auto-focus */ + ad5820: dac@0c { + compatible = "adi,ad5820"; + reg = <0x0c>; + + VANA-supply = <&vaux4>; + + #io-channel-cells = <0>; + }; }; &mmc1 { @@ -733,6 +806,9 @@ pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; bus-width = <4>; + /* For debugging, it is often good idea to remove this GPIO. + It means you can remove back cover (to reboot by removing + battery) and still use the MMC card. */ cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */ }; @@ -741,7 +817,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&vaux3>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; non-removable; no-sdio; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index df3366fa5409be2813086f11d757740c47d2491a..1b0bd72945f21337d1e89c3e1636bbfb5cabeecd 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -265,6 +265,24 @@ &i2c2 { clock-frequency = <400000>; + + as3645a@30 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30>; + compatible = "ams,as3645a"; + flash@0 { + reg = <0x0>; + flash-timeout-us = <150000>; + flash-max-microamp = <320000>; + led-max-microamp = <60000>; + ams,input-max-microamp = <1750000>; + }; + indicator@1 { + reg = <0x1>; + led-max-microamp = <10000>; + }; + }; }; &i2c3 { diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi index cd220342a805aa2844613b171a31279a651407b1..f25e158e7163b23201ca8e643f557b3965fc959d 100644 --- a/arch/arm/boot/dts/omap3-overo-base.dtsi +++ b/arch/arm/boot/dts/omap3-overo-base.dtsi @@ -181,7 +181,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&w3cbw003c_npoweron>; - vmmc_aux-supply = <&w3cbw003c_wifi_nreset>; + vqmmc-supply = <&w3cbw003c_wifi_nreset>; bus-width = <4>; cap-sdio-irq; non-removable; diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi index 06ac0f80bcf083ad0b4ed6a0cb30bcf64b22e7c5..9a601d15247bef5da1519db88b1680b119381b6d 100644 --- a/arch/arm/boot/dts/omap3-tao3530.dtsi +++ b/arch/arm/boot/dts/omap3-tao3530.dtsi @@ -223,7 +223,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts index 45e2ce0803dec8a01d20c92a98a3b1f3b95735d1..96d0301a336a9b819828c9f0aef3cfe34d8bb5af 100644 --- a/arch/arm/boot/dts/omap3-zoom3.dts +++ b/arch/arm/boot/dts/omap3-zoom3.dts @@ -174,7 +174,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <4>; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index a3ff4933dbc173936bbec5a222aba6642e70564d..bdaf30c8c405716ad2f1e434ac8abbd40bcdb786 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -713,14 +713,12 @@ usbhsohci: ohci@48064400 { compatible = "ti,ohci-omap3"; reg = <0x48064400 0x400>; - interrupt-parent = <&intc>; interrupts = <76>; }; usbhsehci: ehci@48064800 { compatible = "ti,ehci-omap"; reg = <0x48064800 0x400>; - interrupt-parent = <&intc>; interrupts = <77>; }; }; @@ -831,7 +829,6 @@ reg-names = "tx", "rx"; - interrupt-parent = <&intc>; interrupts = <67>, <68>; }; @@ -844,7 +841,6 @@ reg-names = "tx", "rx"; - interrupt-parent = <&intc>; interrupts = <69>, <70>; }; diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index abd6921143beb328aad5e84d60d209d98147854f..908951eb5943ec4f938ee294f811fc0577236890 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -33,7 +33,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; /* * S6-3 must be in ON position for 8 bit mode to function * Else, use 4 bit mode diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index 10ca1c174995280f33facc0ffabdaf7514c481f4..8b93d37310f28ba4c10ad81d35f8419914ef4633 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -129,6 +129,34 @@ output-high; line-name = "touchscreen-reset"; }; + + pwm8: dmtimer-pwm-8 { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_direction_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer8>; + ti,clock-source = <0x01>; + }; + + pwm9: dmtimer-pwm-9 { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_enable_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer9>; + ti,clock-source = <0x01>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm9 0 10000000 0>, <&pwm8 0 10000000 0>; + pwm-names = "enable", "direction"; + direction-duty-cycle-ns = <10000000>; + }; + }; &dsi1 { @@ -373,7 +401,7 @@ /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) >; @@ -488,6 +516,18 @@ OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3) >; }; + + vibrator_direction_pin: pinmux_vibrator_direction_pin { + pinctrl-single,pins = < + OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE1) /* dmtimer8_pwm_evt (gpio_27) */ + >; + }; + + vibrator_enable_pin: pinmux_vibrator_enable_pin { + pinctrl-single,pins = < + OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1) /* dmtimer9_pwm_evt (gpio_28) */ + >; + }; }; &uart3 { diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts index 1b825128a7b952568610e0b283415eebd3320724..a9a584b5b9558d737c337806ae7f2d2f34840c7d 100644 --- a/arch/arm/boot/dts/omap4-duovero-parlor.dts +++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts @@ -100,7 +100,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) /* hdmi_hpd.gpio_63 */ - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */ >; diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index edbc4090297ddcd3d5e7cf035261156898271196..2b48e51c372ab70122e13ee13d4f4a11722cd632 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -267,7 +267,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-sdp-es23plus.dts b/arch/arm/boot/dts/omap4-sdp-es23plus.dts index b4d19a7ae39304e93c2d741a2bbd4830674eb663..3d3140fd9659463829e979069dcf81cb9c169055 100644 --- a/arch/arm/boot/dts/omap4-sdp-es23plus.dts +++ b/arch/arm/boot/dts/omap4-sdp-es23plus.dts @@ -10,7 +10,7 @@ /* SDP boards with 4430 ES2.3+ or 4460 have external pullups on SCL & SDA */ &dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index d728ec96311114cd71c0c1bd752be925d14c995f..280d92d42bf13b12983fca36e7786c13eadaa8cd 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -290,7 +290,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi index 74940b6d7719ed28ed6f2a34cf83f033bb18aa72..676d8dd0624a63dc56513e68edb35358c49cac2b 100644 --- a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi +++ b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi @@ -122,7 +122,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 4caadb25324977e67c40d4ebde2929cd6782cbf8..7824b2631cb6b3f93ffaedbaff5ebc65d6064292 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -290,7 +290,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP5_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP5_IOPAD(0x13c, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP5_IOPAD(0x140, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */ OMAP5_IOPAD(0x142, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */ >; diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts index 78397f66d0b2d5611cf665ffbf72f2ac02035413..552a5c4c594254aceecbc36281edd0bcdfeebd0a 100644 --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -266,7 +266,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP5_IOPAD(0x013c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec */ + OMAP5_IOPAD(0x013c, PIN_INPUT | MUX_MODE0) /* hdmi_cec */ OMAP5_IOPAD(0x0140, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl */ OMAP5_IOPAD(0x0142, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda */ >; diff --git a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi index b9457dd21a695ddca61268a4262cae05fdd0aa58..e413b21ee3319be02927dca42aeef0c837698d00 100644 --- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi @@ -20,27 +20,12 @@ model = "Qualcomm Technologies, Inc. IPQ4019/AP-DK01.1"; compatible = "qcom,ipq4019"; - clocks { - xo: xo { - compatible = "fixed-clock"; - clock-frequency = <48000000>; - #clock-cells = <0>; - }; - }; - soc { - - - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 2 0xf08>, - <1 3 0xf08>, - <1 4 0xf08>, - <1 1 0xf08>; - clock-frequency = <48000000>; + rng@22000 { + status = "ok"; }; - pinctrl@0x01000000 { + pinctrl@1000000 { serial_pins: serial_pinmux { mux { pins = "gpio60", "gpio61"; @@ -108,5 +93,13 @@ watchdog@b017000 { status = "ok"; }; + + wifi@a000000 { + status = "ok"; + }; + + wifi@a800000 { + status = "ok"; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi index 4b7d97275c621af5a219856d38f489a3e704b2e7..10d112a4078ecef3c1a70dc3482de7a7511e599b 100644 --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -96,6 +96,21 @@ clock-frequency = <32768>; #clock-cells = <0>; }; + + xo: xo { + compatible = "fixed-clock"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 2 0xf08>, + <1 3 0xf08>, + <1 4 0xf08>, + <1 1 0xf08>; + clock-frequency = <48000000>; }; soc { @@ -119,7 +134,15 @@ reg = <0x1800000 0x60000>; }; - tlmm: pinctrl@0x01000000 { + rng@22000 { + compatible = "qcom,prng"; + reg = <0x22000 0x140>; + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "core"; + status = "disabled"; + }; + + tlmm: pinctrl@1000000 { compatible = "qcom,ipq4019-pinctrl"; reg = <0x01000000 0x300000>; gpio-controller; @@ -269,5 +292,89 @@ compatible = "qcom,pshold"; reg = <0x4ab000 0x4>; }; + + wifi0: wifi@a000000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa000000 0x200000>; + resets = <&gcc WIFI0_CPU_INIT_RESET>, + <&gcc WIFI0_RADIO_SRIF_RESET>, + <&gcc WIFI0_RADIO_WARM_RESET>, + <&gcc WIFI0_RADIO_COLD_RESET>, + <&gcc WIFI0_CORE_WARM_RESET>, + <&gcc WIFI0_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", "wifi_radio_srif", + "wifi_radio_warm", "wifi_radio_cold", + "wifi_core_warm", "wifi_core_cold"; + clocks = <&gcc GCC_WCSS2G_CLK>, + <&gcc GCC_WCSS2G_REF_CLK>, + <&gcc GCC_WCSS2G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc"; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", + "msi12", "msi13", "msi14", "msi15", + "legacy"; + status = "disabled"; + }; + + wifi1: wifi@a800000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa800000 0x200000>; + resets = <&gcc WIFI1_CPU_INIT_RESET>, + <&gcc WIFI1_RADIO_SRIF_RESET>, + <&gcc WIFI1_RADIO_WARM_RESET>, + <&gcc WIFI1_RADIO_COLD_RESET>, + <&gcc WIFI1_CORE_WARM_RESET>, + <&gcc WIFI1_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", "wifi_radio_srif", + "wifi_radio_warm", "wifi_radio_cold", + "wifi_core_warm", "wifi_core_cold"; + clocks = <&gcc GCC_WCSS5G_CLK>, + <&gcc GCC_WCSS5G_REF_CLK>, + <&gcc GCC_WCSS5G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc"; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", + "msi12", "msi13", "msi14", "msi15", + "legacy"; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index c5ee68a3f7f5c28f4fe02f842f4a89a9134252e6..a39207625354cb947ba3ab509552034c76afba19 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -779,7 +779,7 @@ }; replicator@fc31c000 { - compatible = "qcom,coresight-replicator1x", "arm,primecell"; + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0xfc31c000 0x1000>; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts index 52a7b586bac72277f411ccb306fe0c0d719aaa5d..cd4d5ff7749eaf535f5e72d43238d9778d07a8b7 100644 --- a/arch/arm/boot/dts/r7s72100-genmai.dts +++ b/arch/arm/boot/dts/r7s72100-genmai.dts @@ -11,6 +11,8 @@ /dts-v1/; #include "r7s72100.dtsi" +#include +#include / { model = "Genmai"; @@ -34,6 +36,54 @@ #address-cells = <1>; #size-cells = <1>; }; + + leds { + status = "okay"; + compatible = "gpio-leds"; + + led1 { + gpios = <&port4 10 GPIO_ACTIVE_LOW>; + }; + + led2 { + gpios = <&port4 11 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&pinctrl { + + scif2_pins: serial2 { + /* P3_0 as TxD2; P3_2 as RxD2 */ + pinmux = , ; + }; + + i2c2_pins: i2c2 { + /* RIIC2: P1_4 as SCL, P1_5 as SDA */ + pinmux = , ; + }; + + ether_pins: ether { + /* Ethernet on Ports 1,2,3,5 */ + pinmux = ,/* P1_14 = ET_COL */ + , /* P5_9 = ET_MDC */ + , /* P3_3 = ET_MDIO */ + , /* P3_4 = ET_RXCLK */ + , /* P3_5 = ET_RXER */ + , /* P3_6 = ET_RXDV */ + , /* P2_0 = ET_TXCLK */ + , /* P2_1 = ET_TXER */ + , /* P2_2 = ET_TXEN */ + , /* P2_3 = ET_CRS */ + , /* P2_4 = ET_TXD0 */ + , /* P2_5 = ET_TXD1 */ + , /* P2_6 = ET_TXD2 */ + , /* P2_7 = ET_TXD3 */ + , /* P2_8 = ET_RXD0 */ + , /* P2_9 = ET_RXD1 */ + ,/* P2_10 = ET_RXD2 */ + ;/* P2_11 = ET_RXD3 */ + }; }; &extal_clk { @@ -52,12 +102,28 @@ status = "okay"; }; +ðer { + pinctrl-names = "default"; + pinctrl-0 = <ðer_pins>; + + status = "okay"; + + renesas,no-ether-link; + phy-handle = <&phy0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + &i2c2 { status = "okay"; clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + eeprom@50 { - compatible = "renesas,24c128"; + compatible = "renesas,24c128", "atmel,24c128"; reg = <0x50>; pagesize = <64>; }; @@ -68,6 +134,9 @@ }; &scif2 { + pinctrl-names = "default"; + pinctrl-0 = <&scif2_pins>; + status = "okay"; }; diff --git a/arch/arm/boot/dts/r7s72100-rskrza1.dts b/arch/arm/boot/dts/r7s72100-rskrza1.dts index 72df20a04320e7ac61dccde306f5799bdf1bd78c..5dcaaf131d2788ac55be89d3d4d9f9ced9beac9e 100644 --- a/arch/arm/boot/dts/r7s72100-rskrza1.dts +++ b/arch/arm/boot/dts/r7s72100-rskrza1.dts @@ -10,6 +10,8 @@ /dts-v1/; #include "r7s72100.dtsi" +#include +#include / { model = "RSKRZA1"; @@ -33,6 +35,15 @@ #address-cells = <1>; #size-cells = <1>; }; + + leds { + status = "okay"; + compatible = "gpio-leds"; + + led0 { + gpios = <&port7 1 GPIO_ACTIVE_LOW>; + }; + }; }; &extal_clk { @@ -47,11 +58,57 @@ clock-frequency = <32768>; }; +&pinctrl { + + /* Serial Console */ + scif2_pins: serial2 { + pinmux = , /* TxD2 */ + ; /* RxD2 */ + }; + + /* Ethernet */ + ether_pins: ether { + /* Ethernet on Ports 1,2,3,5 */ + pinmux = , /* ET_COL */ + , /* ET_MDC */ + , /* ET_MDIO */ + , /* ET_RXCLK */ + , /* ET_RXER */ + , /* ET_RXDV */ + , /* ET_TXCLK */ + , /* ET_TXER */ + , /* ET_TXEN */ + , /* ET_CRS */ + , /* ET_TXD0 */ + , /* ET_TXD1 */ + , /* ET_TXD2 */ + , /* ET_TXD3 */ + , /* ET_RXD0 */ + , /* ET_RXD1 */ + , /* ET_RXD2 */ + ; /* ET_RXD3 */ + }; + + /* SDHI ch1 on CN1 */ + sdhi1_pins: sdhi1 { + pinmux = , /* SD_CD_1 */ + , /* SD_WP_1 */ + , /* SD_D1_1 */ + , /* SD_D0_1 */ + , /* SD_CLK_1 */ + , /* SD_CMD_1 */ + , /* SD_D3_1 */ + ; /* SD_D2_1 */ + }; +}; + &mtu2 { status = "okay"; }; ðer { + pinctrl-names = "default"; + pinctrl-0 = <ðer_pins>; status = "okay"; renesas,no-ether-link; phy-handle = <&phy0>; @@ -61,6 +118,8 @@ }; &sdhi1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdhi1_pins>; bus-width = <4>; status = "okay"; }; @@ -78,5 +137,7 @@ }; &scif2 { + pinctrl-names = "default"; + pinctrl-0 = <&scif2_pins>; status = "okay"; }; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 5cf53e9943af705726572c5504e37da7cbd7d45d..4ed12a4d9d51382143357585358f20081e216b35 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -207,6 +207,84 @@ }; }; + pinctrl: pin-controller@fcfe3000 { + compatible = "renesas,r7s72100-ports"; + + reg = <0xfcfe3000 0x4230>; + + port0: gpio-0 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 0 6>; + }; + + port1: gpio-1 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 16 16>; + }; + + port2: gpio-2 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 32 16>; + }; + + port3: gpio-3 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 48 16>; + }; + + port4: gpio-4 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 64 16>; + }; + + port5: gpio-5 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 80 11>; + }; + + port6: gpio-6 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 96 16>; + }; + + port7: gpio-7 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 112 16>; + }; + + port8: gpio-8 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 128 16>; + }; + + port9: gpio-9 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 144 8>; + }; + + port10: gpio-10 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 160 16>; + }; + + port11: gpio-11 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 176 16>; + }; + }; + scif0: serial@e8007000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007000 64>; diff --git a/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts b/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts index 9b54783cc2a53977546c61ebaf1a4d3722178c13..081af01928519e333deef4ac6ab1e579419aa08a 100644 --- a/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts +++ b/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts @@ -17,9 +17,40 @@ aliases { serial0 = &scif0; + ethernet0 = &avb; + }; +}; + +&pfc { + scif0_pins: scif0 { + groups = "scif0_data_d"; + function = "scif0"; + }; + + avb_pins: avb { + groups = "avb_mdio", "avb_gmii"; + function = "avb"; }; }; &scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; }; + +&avb { + pinctrl-0 = <&avb_pins>; + pinctrl-names = "default"; + + phy-handle = <&phy3>; + phy-mode = "gmii"; + renesas,no-ether-link; + status = "okay"; + + phy3: ethernet-phy@3 { + reg = <3>; + micrel,led-mode = <1>; + }; +}; diff --git a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi index 001ca9144f4b0dc951fd97ce5d97285ccdcb341b..ff799381863763decedb115e645980670d973b5b 100644 --- a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi +++ b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi @@ -22,8 +22,34 @@ device_type = "memory"; reg = <2 0x00000000 0 0x20000000>; }; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; }; &extal_clk { clock-frequency = <20000000>; }; + +&pfc { + mmcif0_pins: mmc { + groups = "mmc_data8_b", "mmc_ctrl"; + function = "mmc"; + }; +}; + +&mmcif0 { + pinctrl-0 = <&mmcif0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <®_3p3v>; + bus-width = <8>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts b/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts index 3a22538208f25117ea008e45a45d52c03c9b4ba5..3d918d106593d2684eaa7e6e8f95de8695c3efbc 100644 --- a/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts +++ b/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for the SK-RZG1M board * - * Copyright (C) 2016 Cogent Embedded, Inc. + * Copyright (C) 2016-2017 Cogent Embedded, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -39,11 +39,34 @@ clock-frequency = <20000000>; }; +&pfc { + scif0_pins: scif0 { + groups = "scif0_data_d"; + function = "scif0"; + }; + + ether_pins: ether { + groups = "eth_link", "eth_mdio", "eth_rmii"; + function = "eth"; + }; + + phy1_pins: phy1 { + groups = "intc_irq0"; + function = "intc"; + }; +}; + &scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; }; ðer { + pinctrl-0 = <ðer_pins &phy1_pins>; + pinctrl-names = "default"; + phy-handle = <&phy1>; renesas,ether-link-active-low; status = "okay"; diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index 0ddac81742e4cdc7dc93be53fd019db00de98faa..14222c72f0e0f7d5ad95a46d68b310df76fff6cc 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Source for the r8a7743 SoC * - * Copyright (C) 2016 Cogent Embedded Inc. + * Copyright (C) 2016-2017 Cogent Embedded Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -18,9 +18,19 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + }; + cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "renesas,apmu"; cpu0: cpu@0 { device_type = "cpu"; @@ -28,8 +38,26 @@ reg = <0>; clock-frequency = <1500000000>; clocks = <&cpg CPG_CORE R8A7743_CLK_Z>; + clock-latency = <300000>; /* 300 us */ power-domains = <&sysc R8A7743_PD_CA15_CPU0>; next-level-cache = <&L2_CA15>; + + /* kHz - uV - OPPs unknown yet */ + operating-points = <1500000 1000000>, + <1312500 1000000>, + <1125000 1000000>, + < 937500 1000000>, + < 750000 1000000>, + < 375000 1000000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + clock-frequency = <1500000000>; + power-domains = <&sysc R8A7743_PD_CA15_CPU1>; + next-level-cache = <&L2_CA15>; }; L2_CA15: cache-controller-0 { @@ -48,6 +76,12 @@ #size-cells = <2>; ranges; + apmu@e6152000 { + compatible = "renesas,r8a7743-apmu", "renesas,apmu"; + reg = <0 0xe6152000 0 0x188>; + cpus = <&cpu0 &cpu1>; + }; + gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -65,6 +99,126 @@ resets = <&cpg 408>; }; + gpio0: gpio@e6050000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6050000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 0 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 912>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 912>; + }; + + gpio1: gpio@e6051000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6051000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 32 26>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 911>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 911>; + }; + + gpio2: gpio@e6052000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6052000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 64 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 910>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 910>; + }; + + gpio3: gpio@e6053000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6053000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 96 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 909>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 909>; + }; + + gpio4: gpio@e6054000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6054000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 128 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 908>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 908>; + }; + + gpio5: gpio@e6055000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6055000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 160 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 907>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 907>; + }; + + gpio6: gpio@e6055400 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6055400 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 192 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 905>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 905>; + }; + + gpio7: gpio@e6055800 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6055800 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 224 26>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 904>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 904>; + }; + irqc: interrupt-controller@e61c0000 { compatible = "renesas,irqc-r8a7743", "renesas,irqc"; #interrupt-cells = <2>; @@ -123,6 +277,11 @@ #power-domain-cells = <1>; }; + pfc: pin-controller@e6060000 { + compatible = "renesas,pfc-r8a7743"; + reg = <0 0xe6060000 0 0x250>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7743", "renesas,rcar-dmac"; @@ -189,6 +348,94 @@ dma-channels = <15>; }; + /* The memory map in the User's Manual maps the cores to bus + * numbers + */ + i2c0: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6508000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 931>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 931>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c1: i2c@e6518000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6518000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 930>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 930>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c2: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6530000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 929>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 929>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c3: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6540000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 928>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 928>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c4: i2c@e6520000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6520000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 927>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 927>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c5: i2c@e6528000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6528000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 925>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 925>; + i2c-scl-internal-delay-ns = <110>; + status = "disabled"; + }; + scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7743", "renesas,rcar-gen2-scifa", "renesas,scifa"; @@ -468,6 +715,29 @@ status = "disabled"; }; + icram2: sram@e6300000 { + compatible = "mmio-sram"; + reg = <0 0xe6300000 0 0x40000>; + }; + + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7743"; reg = <0 0xee700000 0 0x400>; @@ -480,6 +750,35 @@ #size-cells = <0>; status = "disabled"; }; + + avb: ethernet@e6800000 { + compatible = "renesas,etheravb-r8a7743", + "renesas,etheravb-rcar-gen2"; + reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 812>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 812>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mmcif0: mmc@ee200000 { + compatible = "renesas,mmcif-r8a7743", + "renesas,sh-mmcif"; + reg = <0 0xee200000 0 0x80>; + interrupts = ; + clocks = <&cpg CPG_MOD 315>; + dmas = <&dmac0 0xd1>, <&dmac0 0xd2>, + <&dmac1 0xd1>, <&dmac1 0xd2>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 315>; + reg-io-width = <4>; + max-frequency = <97500000>; + status = "disabled"; + }; }; /* External root clock */ diff --git a/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts b/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts index 97840b3401976095c5dbecc7928773756551b648..b4d679b04ad618a98337b9839b314a2d6ace4474 100644 --- a/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts +++ b/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for the SK-RZG1E board * - * Copyright (C) 2016 Cogent Embedded, Inc. + * Copyright (C) 2016-2017 Cogent Embedded, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -34,11 +34,34 @@ clock-frequency = <20000000>; }; +&pfc { + scif2_pins: scif2 { + groups = "scif2_data"; + function = "scif2"; + }; + + ether_pins: ether { + groups = "eth_link", "eth_mdio", "eth_rmii"; + function = "eth"; + }; + + phy1_pins: phy1 { + groups = "intc_irq8"; + function = "intc"; + }; +}; + &scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + status = "okay"; }; ðer { + pinctrl-0 = <ðer_pins &phy1_pins>; + pinctrl-names = "default"; + phy-handle = <&phy1>; renesas,ether-link-active-low; status = "okay"; diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index 2feb0084bb3b1b5149afe1efd3f50aeeb6984117..aff90dfb8b32169c1cf0c4cf98adc7a090ce5419 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Source for the r8a7745 SoC * - * Copyright (C) 2016 Cogent Embedded Inc. + * Copyright (C) 2016-2017 Cogent Embedded Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -123,6 +123,11 @@ #power-domain-cells = <1>; }; + pfc: pin-controller@e6060000 { + compatible = "renesas,pfc-r8a7745"; + reg = <0 0xe6060000 0 0x11c>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7745", "renesas,rcar-dmac"; @@ -468,6 +473,29 @@ status = "disabled"; }; + icram2: sram@e6300000 { + compatible = "mmio-sram"; + reg = <0 0xe6300000 0 0x40000>; + }; + + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7745"; reg = <0 0xee700000 0 0x400>; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 2805a8608d4ba007693b129dddb4d5d1600fa353..16358bf8d1dbffdceceeb53124bf45dea8ae31ec 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -830,6 +830,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7790"; reg = <0 0xee700000 0 0x400>; @@ -855,7 +873,7 @@ }; sata0: sata@ee300000 { - compatible = "renesas,sata-r8a7790"; + compatible = "renesas,sata-r8a7790", "renesas,rcar-gen2-sata"; reg = <0 0xee300000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA0>; @@ -864,7 +882,7 @@ }; sata1: sata@ee500000 { - compatible = "renesas,sata-r8a7790"; + compatible = "renesas,sata-r8a7790", "renesas,rcar-gen2-sata"; reg = <0 0xee500000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA1>; @@ -909,7 +927,7 @@ }; vin0: video@e6ef0000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef0000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN0>; @@ -918,7 +936,7 @@ }; vin1: video@e6ef1000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef1000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN1>; @@ -927,7 +945,7 @@ }; vin2: video@e6ef2000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef2000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN2>; @@ -936,7 +954,7 @@ }; vin3: video@e6ef3000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef3000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN3>; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 001e6116c47c7c3bd9a22eb0106e369e47dedcae..0ce0b278e1cbe2bf44113586460953edd6ab5f7d 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -642,11 +642,19 @@ }; }; + cec_clock: cec-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12000000>; + }; + hdmi@39 { compatible = "adi,adv7511w"; reg = <0x39>; interrupt-parent = <&gpio3>; interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + clocks = <&cec_clock>; + clock-names = "cec"; adi,input-depth = <8>; adi,input-colorspace = "rgb"; @@ -702,7 +710,7 @@ }; eeprom@50 { - compatible = "renesas,24c02"; + compatible = "renesas,24c02", "atmel,24c02"; reg = <0x50>; pagesize = <16>; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index bd93f699ad84098762e99082cfa027dfa4abc088..f1d1a977215308e6cc831a6062780810c150b8a8 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -890,6 +890,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7791"; reg = <0 0xee700000 0 0x400>; @@ -915,7 +933,7 @@ }; sata0: sata@ee300000 { - compatible = "renesas,sata-r8a7791"; + compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata"; reg = <0 0xee300000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA0>; @@ -924,7 +942,7 @@ }; sata1: sata@ee500000 { - compatible = "renesas,sata-r8a7791"; + compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata"; reg = <0 0xee500000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA1>; @@ -969,7 +987,7 @@ }; vin0: video@e6ef0000 { - compatible = "renesas,vin-r8a7791"; + compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef0000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN0>; @@ -978,7 +996,7 @@ }; vin1: video@e6ef1000 { - compatible = "renesas,vin-r8a7791"; + compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef1000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN1>; @@ -987,7 +1005,7 @@ }; vin2: video@e6ef2000 { - compatible = "renesas,vin-r8a7791"; + compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef2000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN2>; diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi index 0efecb232ee52ce0d75c189b1e378fbb274cc836..2623f39bed2b73bb6f180a72e89586702a90f2cc 100644 --- a/arch/arm/boot/dts/r8a7792.dtsi +++ b/arch/arm/boot/dts/r8a7792.dtsi @@ -465,6 +465,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7792"; reg = <0 0xee100000 0 0x328>; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 13b980f27bbc885f2a36b26361562e941fe9291a..497716b6fbe2416423b53b2fd3be3303bc60c92c 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -848,6 +848,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7793"; reg = <0 0xee700000 0 0x400>; diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 7d9a81d970d87c6b0ebae4df4bd460305fb0cfa5..26535414203a0b1e43bab73a12ec16238c8b3b1b 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -588,6 +588,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7794"; reg = <0 0xee700000 0 0x400>; @@ -783,7 +801,7 @@ }; vin0: video@e6ef0000 { - compatible = "renesas,vin-r8a7794"; + compatible = "renesas,vin-r8a7794", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef0000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN0>; @@ -792,7 +810,7 @@ }; vin1: video@e6ef1000 { - compatible = "renesas,vin-r8a7794"; + compatible = "renesas,vin-r8a7794", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef1000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN1>; diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 5726135b7f8a89e1ff0620205c667baaef7f5ea7..fdb1570bc7d3137fcfed7acf2fb970ca4ff1a75a 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -357,7 +357,6 @@ keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; sd-uhs-sdr12; @@ -372,7 +371,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; }; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index ec91325d3b6ebeb50da67b44607c600a88cf64bc..4916c65e0ace7ca0b9ec68cddaca34b55c39d932 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -287,7 +287,6 @@ fifo-depth = <0x100>; mmc-ddr-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; resets = <&cru SRST_EMMC>; @@ -599,7 +598,7 @@ rockchip,pins = <1 15 RK_FUNC_1 &pcfg_pull_default>; }; - sdmmc_cd: sdmcc-cd { + sdmmc_cd: sdmmc-cd { rockchip,pins = <1 17 RK_FUNC_1 &pcfg_pull_default>; }; diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index e1f5198723b22de9dc2cb47a9b46a1a72f11a134..ef1eabf2512c5eec210b8694ca50e1072ba85960 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -190,7 +190,6 @@ #include "tps65910.dtsi" &mmc0 { /* sdmmc */ - num-slots = <1>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; @@ -202,7 +201,6 @@ }; &mmc1 { /* wifi */ - num-slots = <1>; status = "okay"; non-removable; diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts index 7ca1cf5241e036c9a5b56f8b6988bef1fd043c0a..13e285c53defd633967f3058b4b3ce12e673dfa7 100644 --- a/arch/arm/boot/dts/rk3066a-mk808.dts +++ b/arch/arm/boot/dts/rk3066a-mk808.dts @@ -132,7 +132,6 @@ bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; - num-slots = <1>; vmmc-supply = <&vcc_sd>; status = "okay"; }; @@ -141,7 +140,6 @@ bus-width = <4>; disable-wp; non-removable; - num-slots = <1>; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>; pinctrl-names = "default"; vmmc-supply = <&vcc_wifi>; diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index 8907deaab18e30038fc094607bfcc1b6faf1044f..400cbf9609e3707b7792139bba326c947df81fe8 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -185,7 +185,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>; vmmc-supply = <&vcc_emmc>; @@ -336,7 +335,6 @@ &mmc0 { bus-width = <4>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; vmmc-supply = <&vcc_sd>; @@ -349,7 +347,6 @@ bus-width = <4>; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; vmmc-supply = <&vccio_wl>; diff --git a/arch/arm/boot/dts/rk3188-px3-evb.dts b/arch/arm/boot/dts/rk3188-px3-evb.dts index 5b2a0b6885cd0790d663ab3ba2d87927b9b32742..8ba9e06062f3e05434cf954fa1027146abbdb3d6 100644 --- a/arch/arm/boot/dts/rk3188-px3-evb.dts +++ b/arch/arm/boot/dts/rk3188-px3-evb.dts @@ -89,7 +89,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>; status = "okay"; @@ -256,7 +255,6 @@ }; &mmc0 { - num-slots = <1>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index ca0a1c4bc15cdd3fea84d305eba5cf219969a00f..53d6fc2fdbce89fb2118c30e2115c05bc29eebcd 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -296,7 +296,6 @@ }; &mmc0 { - num-slots = <1>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts index 58834330a5bae547e3146b90d0b4884956fd69eb..1be9daacc4f91448ad9f467376922f065385ab53 100644 --- a/arch/arm/boot/dts/rk3228-evb.dts +++ b/arch/arm/boot/dts/rk3228-evb.dts @@ -50,6 +50,16 @@ device_type = "memory"; reg = <0x60000000 0x40000000>; }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + enable-active-high; + regulator-name = "vcc_phy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; }; &emmc { @@ -60,6 +70,30 @@ status = "okay"; }; +&gmac { + assigned-clocks = <&cru SCLK_MAC_SRC>; + assigned-clock-rates = <50000000>; + clock_in_out = "output"; + phy-supply = <&vcc_phy>; + phy-mode = "rmii"; + phy-handle = <&phy>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + phy: phy@0 { + compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + clocks = <&cru SCLK_MAC_PHY>; + resets = <&cru SRST_MACPHY>; + phy-is-integrated; + }; + }; +}; + &tsadc { status = "okay"; diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts index 1b55192b7d04683ce464eb824f45cee43fd4c486..73e38458575541d4571758989d4ecb073eac7d23 100644 --- a/arch/arm/boot/dts/rk3229-evb.dts +++ b/arch/arm/boot/dts/rk3229-evb.dts @@ -40,7 +40,8 @@ /dts-v1/; -#include "rk322x.dtsi" +#include +#include "rk3229.dtsi" / { model = "Rockchip RK3229 Evaluation board"; @@ -51,6 +52,15 @@ reg = <0x60000000 0x40000000>; }; + dc_12v: dc-12v-regulator { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + ext_gmac: ext_gmac { compatible = "fixed-clock"; clock-frequency = <125000000>; @@ -67,6 +77,7 @@ regulator-name = "vcc_host"; regulator-always-on; regulator-boot-on; + vin-supply = <&vcc_sys>; }; vcc_phy: vcc-phy-regulator { @@ -77,9 +88,98 @@ regulator-max-microvolt = <1800000>; regulator-always-on; regulator-boot-on; + vin-supply = <&vccio_1v8>; + }; + + vcc_sys: vcc-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vccio_1v8: vccio-1v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vccio_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vccio_3v3: vccio-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vccio_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vdd_arm: vdd-arm-regulator { + compatible = "pwm-regulator"; + pwms = <&pwm1 0 25000 1>; + pwm-supply = <&vcc_sys>; + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_log: vdd-log-regulator { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + pwm-supply = <&vcc_sys>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + }; + + gpio_keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_key>; + + power_key: power-key { + label = "GPIO Key Power"; + gpios = <&gpio3 23 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <100>; + wakeup-source; + }; }; }; +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + cap-mmc-highspeed; + disable-wp; + non-removable; + status = "okay"; +}; + &gmac { assigned-clocks = <&cru SCLK_MAC_EXTCLK>, <&cru SCLK_MAC>; assigned-clock-parents = <&ext_gmac>, <&cru SCLK_MAC_EXTCLK>; @@ -96,7 +196,21 @@ status = "okay"; }; +&io_domains { + status = "okay"; + + vccio1-supply = <&vccio_3v3>; + vccio2-supply = <&vccio_1v8>; + vccio4-supply = <&vccio_3v3>; +}; + &pinctrl { + keys { + pwr_key: pwr-key { + rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + usb { host_vbus_drv: host-vbus-drv { rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; @@ -104,6 +218,19 @@ }; }; +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ + status = "okay"; +}; + &uart2 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3229.dtsi b/arch/arm/boot/dts/rk3229.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..6fe6c15fc13a348369ad9358f3940621538c0ab8 --- /dev/null +++ b/arch/arm/boot/dts/rk3229.dtsi @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "rk322x.dtsi" + +/ { + compatible = "rockchip,rk3229"; + + /delete-node/ opp-table0; + + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <975000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1000000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1175000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1275000>; + }; + opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1325000>; + }; + opp-1392000000 { + opp-hz = /bits/ 64 <1392000000>; + opp-microvolt = <1375000>; + }; + opp-1464000000 { + opp-hz = /bits/ 64 <1464000000>; + opp-microvolt = <1400000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi index f3e4ffd9f8180bfaade6a9ecfb0e7abaa502f0d1..06814421eed2ef9c41fd5db803bc60f91ee85bed 100644 --- a/arch/arm/boot/dts/rk322x.dtsi +++ b/arch/arm/boot/dts/rk322x.dtsi @@ -55,6 +55,7 @@ serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; + spi0 = &spi0; }; cpus { @@ -70,6 +71,7 @@ #cooling-cells = <2>; /* min followed by max */ clock-latency = <40000>; clocks = <&cru ARMCLK>; + enable-method = "psci"; }; cpu1: cpu@f01 { @@ -78,6 +80,7 @@ reg = <0xf01>; resets = <&cru SRST_CORE1>; operating-points-v2 = <&cpu0_opp_table>; + enable-method = "psci"; }; cpu2: cpu@f02 { @@ -86,6 +89,7 @@ reg = <0xf02>; resets = <&cru SRST_CORE2>; operating-points-v2 = <&cpu0_opp_table>; + enable-method = "psci"; }; cpu3: cpu@f03 { @@ -94,6 +98,7 @@ reg = <0xf03>; resets = <&cru SRST_CORE3>; operating-points-v2 = <&cpu0_opp_table>; + enable-method = "psci"; }; }; @@ -151,6 +156,11 @@ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + timer { compatible = "arm,armv7-timer"; arm,cpu-registers-not-fw-configured; @@ -196,6 +206,19 @@ status = "disabled"; }; + spdif: spdif@100d0000 { + compatible = "rockchip,rk3228-spdif"; + reg = <0x100d0000 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF_8CH>; + clock-names = "mclk", "hclk"; + dmas = <&pdma 10>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; + status = "disabled"; + }; + i2s2: i2s2@100e0000 { compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100e0000 0x4000>; @@ -215,6 +238,11 @@ #address-cells = <1>; #size-cells = <1>; + io_domains: io-domains { + compatible = "rockchip,rk3228-io-voltage-domain"; + status = "disabled"; + }; + u2phy0: usb2-phy@760 { compatible = "rockchip,rk3228-usb2phy"; reg = <0x0760 0x0c>; @@ -309,6 +337,23 @@ status = "disabled"; }; + efuse: efuse@11040000 { + compatible = "rockchip,rk3228-efuse"; + reg = <0x11040000 0x20>; + clocks = <&cru PCLK_EFUSE_256>; + clock-names = "pclk_efuse"; + #address-cells = <1>; + #size-cells = <1>; + + /* Data cells */ + efuse_id: id@7 { + reg = <0x7 0x10>; + }; + cpu_leakage: cpu_leakage@17 { + reg = <0x17 0x1>; + }; + }; + i2c0: i2c@11050000 { compatible = "rockchip,rk3228-i2c"; reg = <0x11050000 0x1000>; @@ -361,6 +406,19 @@ status = "disabled"; }; + spi0: spi@11090000 { + compatible = "rockchip,rk3228-spi"; + reg = <0x11090000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; + clock-names = "spiclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0 &spi0_cs1>; + status = "disabled"; + }; + wdt: watchdog@110a0000 { compatible = "snps,dw-wdt"; reg = <0x110a0000 0x100>; @@ -500,8 +558,70 @@ status = "disabled"; }; + vpu_mmu: iommu@20020800 { + compatible = "rockchip,iommu"; + reg = <0x20020800 0x100>; + interrupts = ; + interrupt-names = "vpu_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + vdec_mmu: iommu@20030480 { + compatible = "rockchip,iommu"; + reg = <0x20030480 0x40>, <0x200304c0 0x40>; + interrupts = ; + interrupt-names = "vdec_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + vop_mmu: iommu@20053f00 { + compatible = "rockchip,iommu"; + reg = <0x20053f00 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + iep_mmu: iommu@20070800 { + compatible = "rockchip,iommu"; + reg = <0x20070800 0x100>; + interrupts = ; + interrupt-names = "iep_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + sdmmc: dwmmc@30000000 { + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x30000000 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + status = "disabled"; + }; + + sdio: dwmmc@30010000 { + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x30010000 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; + status = "disabled"; + }; + emmc: dwmmc@30020000 { - compatible = "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x30020000 0x4000>; interrupts = ; clock-frequency = <37500000>; @@ -511,7 +631,6 @@ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; bus-width = <8>; default-sample-phase = <158>; - num-slots = <1>; fifo-depth = <0x100>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; @@ -710,6 +829,40 @@ drive-strength = <12>; }; + sdmmc { + sdmmc_clk: sdmmc-clk { + rockchip,pins = <1 RK_PC0 1 &pcfg_pull_none_drv_12ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <1 RK_PB7 1 &pcfg_pull_none_drv_12ma>; + }; + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <1 RK_PC2 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC3 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC4 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC5 1 &pcfg_pull_none_drv_12ma>; + }; + }; + + sdio { + sdio_clk: sdio-clk { + rockchip,pins = <3 RK_PA0 1 &pcfg_pull_none_drv_12ma>; + }; + + sdio_cmd: sdio-cmd { + rockchip,pins = <3 RK_PA1 1 &pcfg_pull_none_drv_12ma>; + }; + + sdio_bus4: sdio-bus4 { + rockchip,pins = <3 RK_PA2 1 &pcfg_pull_none_drv_12ma>, + <3 RK_PA3 1 &pcfg_pull_none_drv_12ma>, + <3 RK_PA4 1 &pcfg_pull_none_drv_12ma>, + <3 RK_PA5 1 &pcfg_pull_none_drv_12ma>; + }; + }; + emmc { emmc_clk: emmc-clk { rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_none>; @@ -797,6 +950,42 @@ }; }; + spi-0 { + spi0_clk: spi0-clk { + rockchip,pins = <0 9 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_cs0: spi0-cs0 { + rockchip,pins = <0 14 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_tx: spi0-tx { + rockchip,pins = <0 11 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_rx: spi0-rx { + rockchip,pins = <0 13 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_cs1: spi0-cs1 { + rockchip,pins = <1 12 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + spi-1 { + spi1_clk: spi1-clk { + rockchip,pins = <0 23 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_cs0: spi1-cs0 { + rockchip,pins = <2 2 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_rx: spi1-rx { + rockchip,pins = <2 0 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_tx: spi1-tx { + rockchip,pins = <2 1 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_cs1: spi1-cs1 { + rockchip,pins = <2 3 RK_FUNC_2 &pcfg_pull_up>; + }; + }; + i2s1 { i2s1_bus: i2s1-bus { rockchip,pins = <0 8 RK_FUNC_1 &pcfg_pull_none>, @@ -835,6 +1024,12 @@ }; }; + spdif { + spdif_tx: spdif-tx { + rockchip,pins = <3 31 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + tsadc { otp_gpio: otp-gpio { rockchip,pins = <0 24 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 0dec94c3583b4523d44defc903821beaa810116f..39b61dce97ad344e0884a02f87ff66c6155eb51d 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -45,7 +45,44 @@ / { memory@0 { device_type = "memory"; - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + + button-up { + label = "Volume Up"; + linux,code = ; + press-threshold-microvolt = <100000>; + }; + + button-down { + label = "Volume Down"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + + menu { + label = "Menu"; + linux,code = ; + press-threshold-microvolt = <640000>; + }; + + esc { + label = "Esc"; + linux,code = ; + press-threshold-microvolt = <1000000>; + }; + + home { + label = "Home"; + linux,code = ; + press-threshold-microvolt = <1300000>; + }; }; backlight: backlight { @@ -212,19 +249,22 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; status = "okay"; }; +&saradc { + vref-supply = <&vcc_18>; + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; status = "okay"; @@ -248,6 +288,11 @@ status = "ok"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3288-fennec.dts b/arch/arm/boot/dts/rk3288-fennec.dts index 61d1c1028317818e1e8b59ac2007f1197a00f8c4..41405974253a4ba945362ecac43d8eb61484538c 100644 --- a/arch/arm/boot/dts/rk3288-fennec.dts +++ b/arch/arm/boot/dts/rk3288-fennec.dts @@ -47,7 +47,7 @@ compatible = "rockchip,rk3288-fennec", "rockchip,rk3288"; memory@0 { - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; device_type = "memory"; }; @@ -77,7 +77,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; status = "okay"; @@ -99,6 +98,11 @@ status = "okay"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi index 813496618d08ecaad55b250e40cf472efd10b84c..5f05815f47e09278bdc9eb7870d25ab0c504e549 100644 --- a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi @@ -47,7 +47,7 @@ / { memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -78,7 +78,6 @@ mmc-ddr-1_8v; mmc-hs200-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; diff --git a/arch/arm/boot/dts/rk3288-firefly-reload.dts b/arch/arm/boot/dts/rk3288-firefly-reload.dts index b11a282c334c4d03cc1fdc1e1665029fc0f1de18..7da0947ababbc4a1cda11e6f5b4190ee9f803a88 100644 --- a/arch/arm/boot/dts/rk3288-firefly-reload.dts +++ b/arch/arm/boot/dts/rk3288-firefly-reload.dts @@ -269,7 +269,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; vmmc-supply = <&vcc_sd>; @@ -284,7 +283,6 @@ disable-wp; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>, <&sdio0_int>; sd-uhs-sdr12; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 32dabae12e673778303e1e91f7fed02af4eeee08..b9e6f3a97240c4a8e422cc44052604e05893fcdc 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -46,7 +46,7 @@ / { memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; adc-keys { @@ -208,7 +208,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -527,7 +526,6 @@ bus-width = <4>; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>; vmmc-supply = <&vbat_wl>; @@ -541,7 +539,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts index 30e93f694ae86699194fb830a45f7d5644d6d23f..4d923aa6ed1196395897cd6abefa56dc557ff5a4 100644 --- a/arch/arm/boot/dts/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rk3288-miqi.dts @@ -54,7 +54,7 @@ memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -126,7 +126,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -404,7 +403,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm/boot/dts/rk3288-phycore-rdk.dts b/arch/arm/boot/dts/rk3288-phycore-rdk.dts index 3dda79579b5192402f3ecc37f2969bbb2706af82..1241cbcfc16fae404a269917abe86f03b8f17c0f 100644 --- a/arch/arm/boot/dts/rk3288-phycore-rdk.dts +++ b/arch/arm/boot/dts/rk3288-phycore-rdk.dts @@ -263,7 +263,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vdd_io_sd>; diff --git a/arch/arm/boot/dts/rk3288-phycore-som.dtsi b/arch/arm/boot/dts/rk3288-phycore-som.dtsi index 26cd3ad45160714351993413a4180107ff670339..99cfae875e12e6e3ec9e333c7534a058bbe0a3e8 100644 --- a/arch/arm/boot/dts/rk3288-phycore-som.dtsi +++ b/arch/arm/boot/dts/rk3288-phycore-som.dtsi @@ -55,7 +55,7 @@ */ memory { device_type = "memory"; - reg = <0 0x8000000>; + reg = <0x0 0x0 0x0 0x8000000>; }; aliases { @@ -136,7 +136,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; vmmc-supply = <&vdd_3v3_io>; diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts index aa1f9ecff23109b7671e81d0afd62f217a563b18..f084e0c8dcb350726949d698cd8021c0168d8a9e 100644 --- a/arch/arm/boot/dts/rk3288-popmetal.dts +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -50,7 +50,7 @@ memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -150,7 +150,6 @@ mmc-ddr-1_8v; mmc-hs200-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -164,7 +163,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; sd-uhs-sdr12; diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index 1145b62edde7fb8ddf3aee9b1674dad07afb1568..e95215c9788b38376a78cc8d2567798662d0d51f 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -50,7 +50,7 @@ memory@0 { device_type = "memory"; - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -354,7 +354,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc_sdmmc>; diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index 749a9b86e6e27c9a1d7d5e50786022d6804d24e5..b9c471fcbd42b080305e2c89318dd2bea4036603 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -43,7 +43,7 @@ / { memory@0 { - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; device_type = "memory"; }; @@ -89,7 +89,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; mmc-pwrseq = <&emmc_pwrseq>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index 8ed25e9f60bc480309765ab26c10426a5965e2cd..0e084b8a86acb01fb53fa2aca461fc727d6c7544 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -147,7 +147,6 @@ disable-wp; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk &sdio0_int>; vmmc-supply = <&vcc_io>; @@ -161,7 +160,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm/boot/dts/rk3288-tinker.dts b/arch/arm/boot/dts/rk3288-tinker.dts index f601c78386a92f67e780b18a7aaf6c08cf4f25bd..346b0d8b474d9995f000d0dd3fedca46cff755cf 100644 --- a/arch/arm/boot/dts/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rk3288-tinker.dts @@ -50,7 +50,7 @@ compatible = "asus,rk3288-tinker", "rockchip,rk3288"; memory { - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; device_type = "memory"; }; @@ -156,6 +156,11 @@ status = "ok"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; @@ -465,7 +470,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi index aef07101e9abaa549cc6e2fa3c311c4f5dbd47b2..95e9bee8bca2bd0c6c619dcd58670a298661548c 100644 --- a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi @@ -117,7 +117,6 @@ card-detect-delay = <200>; cd-gpios = <&gpio7 RK_PA5 GPIO_ACTIVE_LOW>; rockchip,default-sample-phase = <90>; - num-slots = <1>; sd-uhs-sdr12; sd-uhs-sdr25; sd-uhs-sdr50; diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index d709fa1847f9a8ca2f435a95ecc7b78536af1ffb..6e5bd8974f22dc9aac0fdf7daeeae8ca490f82d0 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -49,7 +49,7 @@ / { memory@0 { device_type = "memory"; - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; gpio_keys: gpio-keys { @@ -156,7 +156,6 @@ mmc-hs200-1_8v; mmc-pwrseq = <&emmc_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; }; @@ -372,7 +371,6 @@ keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>; sd-uhs-sdr12; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 2484f11761ea24f3bfa44a81e7309442399367d9..356ed1e624525224c8e797da0990f83a75823008 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -49,8 +49,8 @@ #include / { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; compatible = "rockchip,rk3288"; @@ -139,13 +139,13 @@ amba { compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; dmac_peri: dma-controller@ff250000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0xff250000 0x4000>; + reg = <0x0 0xff250000 0x0 0x4000>; interrupts = , ; #dma-cells = <1>; @@ -156,7 +156,7 @@ dmac_bus_ns: dma-controller@ff600000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0xff600000 0x4000>; + reg = <0x0 0xff600000 0x0 0x4000>; interrupts = , ; #dma-cells = <1>; @@ -168,7 +168,7 @@ dmac_bus_s: dma-controller@ffb20000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0xffb20000 0x4000>; + reg = <0x0 0xffb20000 0x0 0x4000>; interrupts = , ; #dma-cells = <1>; @@ -179,8 +179,8 @@ }; reserved-memory { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; /* @@ -194,7 +194,7 @@ * is found. */ dma-unusable@fe000000 { - reg = <0xfe000000 0x1000000>; + reg = <0x0 0xfe000000 0x0 0x1000000>; }; }; @@ -217,7 +217,7 @@ timer: timer@ff810000 { compatible = "rockchip,rk3288-timer"; - reg = <0xff810000 0x20>; + reg = <0x0 0xff810000 0x0 0x20>; interrupts = ; clocks = <&xin24m>, <&cru PCLK_TIMER>; clock-names = "timer", "pclk"; @@ -236,7 +236,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0c0000 0x4000>; + reg = <0x0 0xff0c0000 0x0 0x4000>; resets = <&cru SRST_MMC0>; reset-names = "reset"; status = "disabled"; @@ -250,7 +250,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0d0000 0x4000>; + reg = <0x0 0xff0d0000 0x0 0x4000>; resets = <&cru SRST_SDIO0>; reset-names = "reset"; status = "disabled"; @@ -264,7 +264,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0e0000 0x4000>; + reg = <0x0 0xff0e0000 0x0 0x4000>; resets = <&cru SRST_SDIO1>; reset-names = "reset"; status = "disabled"; @@ -278,7 +278,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0f0000 0x4000>; + reg = <0x0 0xff0f0000 0x0 0x4000>; resets = <&cru SRST_EMMC>; reset-names = "reset"; status = "disabled"; @@ -286,7 +286,7 @@ saradc: saradc@ff100000 { compatible = "rockchip,saradc"; - reg = <0xff100000 0x100>; + reg = <0x0 0xff100000 0x0 0x100>; interrupts = ; #io-channel-cells = <1>; clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; @@ -305,7 +305,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>; - reg = <0xff110000 0x1000>; + reg = <0x0 0xff110000 0x0 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -320,7 +320,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>; - reg = <0xff120000 0x1000>; + reg = <0x0 0xff120000 0x0 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -335,7 +335,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>; - reg = <0xff130000 0x1000>; + reg = <0x0 0xff130000 0x0 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -343,7 +343,7 @@ i2c1: i2c@ff140000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff140000 0x1000>; + reg = <0x0 0xff140000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -356,7 +356,7 @@ i2c3: i2c@ff150000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff150000 0x1000>; + reg = <0x0 0xff150000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -369,7 +369,7 @@ i2c4: i2c@ff160000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff160000 0x1000>; + reg = <0x0 0xff160000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -382,7 +382,7 @@ i2c5: i2c@ff170000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff170000 0x1000>; + reg = <0x0 0xff170000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -395,7 +395,7 @@ uart0: serial@ff180000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff180000 0x100>; + reg = <0x0 0xff180000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -408,7 +408,7 @@ uart1: serial@ff190000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff190000 0x100>; + reg = <0x0 0xff190000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -421,7 +421,7 @@ uart2: serial@ff690000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff690000 0x100>; + reg = <0x0 0xff690000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -434,7 +434,7 @@ uart3: serial@ff1b0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff1b0000 0x100>; + reg = <0x0 0xff1b0000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -447,7 +447,7 @@ uart4: serial@ff1c0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff1c0000 0x100>; + reg = <0x0 0xff1c0000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -535,7 +535,7 @@ tsadc: tsadc@ff280000 { compatible = "rockchip,rk3288-tsadc"; - reg = <0xff280000 0x100>; + reg = <0x0 0xff280000 0x0 0x100>; interrupts = ; clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; clock-names = "tsadc", "apb_pclk"; @@ -552,7 +552,7 @@ gmac: ethernet@ff290000 { compatible = "rockchip,rk3288-gmac"; - reg = <0xff290000 0x10000>; + reg = <0x0 0xff290000 0x0 0x10000>; interrupts = , ; interrupt-names = "macirq", "eth_wake_irq"; @@ -572,7 +572,7 @@ usb_host0_ehci: usb@ff500000 { compatible = "generic-ehci"; - reg = <0xff500000 0x100>; + reg = <0x0 0xff500000 0x0 0x100>; interrupts = ; clocks = <&cru HCLK_USBHOST0>; clock-names = "usbhost"; @@ -586,7 +586,7 @@ usb_host1: usb@ff540000 { compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2"; - reg = <0xff540000 0x40000>; + reg = <0x0 0xff540000 0x0 0x40000>; interrupts = ; clocks = <&cru HCLK_USBHOST1>; clock-names = "otg"; @@ -599,7 +599,7 @@ usb_otg: usb@ff580000 { compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2"; - reg = <0xff580000 0x40000>; + reg = <0x0 0xff580000 0x0 0x40000>; interrupts = ; clocks = <&cru HCLK_OTG0>; clock-names = "otg"; @@ -614,7 +614,7 @@ usb_hsic: usb@ff5c0000 { compatible = "generic-ehci"; - reg = <0xff5c0000 0x100>; + reg = <0x0 0xff5c0000 0x0 0x100>; interrupts = ; clocks = <&cru HCLK_HSIC>; clock-names = "usbhost"; @@ -623,7 +623,7 @@ i2c0: i2c@ff650000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff650000 0x1000>; + reg = <0x0 0xff650000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -636,7 +636,7 @@ i2c2: i2c@ff660000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff660000 0x1000>; + reg = <0x0 0xff660000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -649,7 +649,7 @@ pwm0: pwm@ff680000 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680000 0x10>; + reg = <0x0 0xff680000 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; @@ -660,7 +660,7 @@ pwm1: pwm@ff680010 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680010 0x10>; + reg = <0x0 0xff680010 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm1_pin>; @@ -671,7 +671,7 @@ pwm2: pwm@ff680020 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680020 0x10>; + reg = <0x0 0xff680020 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm2_pin>; @@ -682,7 +682,7 @@ pwm3: pwm@ff680030 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680030 0x10>; + reg = <0x0 0xff680030 0x0 0x10>; #pwm-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&pwm3_pin>; @@ -693,10 +693,10 @@ bus_intmem@ff700000 { compatible = "mmio-sram"; - reg = <0xff700000 0x18000>; + reg = <0x0 0xff700000 0x0 0x18000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0 0xff700000 0x18000>; + ranges = <0 0x0 0xff700000 0x18000>; smp-sram@0 { compatible = "rockchip,rk3066-smp-sram"; reg = <0x00 0x10>; @@ -705,12 +705,12 @@ sram@ff720000 { compatible = "rockchip,rk3288-pmu-sram", "mmio-sram"; - reg = <0xff720000 0x1000>; + reg = <0x0 0xff720000 0x0 0x1000>; }; pmu: power-management@ff730000 { compatible = "rockchip,rk3288-pmu", "syscon", "simple-mfd"; - reg = <0xff730000 0x100>; + reg = <0x0 0xff730000 0x0 0x100>; power: power-controller { compatible = "rockchip,rk3288-power-controller"; @@ -831,12 +831,12 @@ sgrf: syscon@ff740000 { compatible = "rockchip,rk3288-sgrf", "syscon"; - reg = <0xff740000 0x1000>; + reg = <0x0 0xff740000 0x0 0x1000>; }; cru: clock-controller@ff760000 { compatible = "rockchip,rk3288-cru"; - reg = <0xff760000 0x1000>; + reg = <0x0 0xff760000 0x0 0x1000>; rockchip,grf = <&grf>; #clock-cells = <1>; #reset-cells = <1>; @@ -854,7 +854,7 @@ grf: syscon@ff770000 { compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd"; - reg = <0xff770000 0x1000>; + reg = <0x0 0xff770000 0x0 0x1000>; edp_phy: edp-phy { compatible = "rockchip,rk3288-dp-phy"; @@ -903,7 +903,7 @@ wdt: watchdog@ff800000 { compatible = "rockchip,rk3288-wdt", "snps,dw-wdt"; - reg = <0xff800000 0x100>; + reg = <0x0 0xff800000 0x0 0x100>; clocks = <&cru PCLK_WDT>; interrupts = ; status = "disabled"; @@ -911,7 +911,7 @@ spdif: sound@ff88b0000 { compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif"; - reg = <0xff8b0000 0x10000>; + reg = <0x0 0xff8b0000 0x0 0x10000>; #sound-dai-cells = <0>; clock-names = "hclk", "mclk"; clocks = <&cru HCLK_SPDIF8CH>, <&cru SCLK_SPDIF8CH>; @@ -926,7 +926,7 @@ i2s: i2s@ff890000 { compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; - reg = <0xff890000 0x10000>; + reg = <0x0 0xff890000 0x0 0x10000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -943,7 +943,7 @@ crypto: cypto-controller@ff8a0000 { compatible = "rockchip,rk3288-crypto"; - reg = <0xff8a0000 0x4000>; + reg = <0x0 0xff8a0000 0x0 0x4000>; interrupts = ; clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>, <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>; @@ -953,9 +953,28 @@ status = "okay"; }; + iep_mmu: iommu@ff900800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff900800 0x0 0x40>; + interrupts = ; + interrupt-names = "iep_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + isp_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + vopb: vop@ff930000 { compatible = "rockchip,rk3288-vop"; - reg = <0xff930000 0x19c>; + reg = <0x0 0xff930000 0x0 0x19c>; interrupts = ; clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; @@ -988,7 +1007,7 @@ vopb_mmu: iommu@ff930300 { compatible = "rockchip,iommu"; - reg = <0xff930300 0x100>; + reg = <0x0 0xff930300 0x0 0x100>; interrupts = ; interrupt-names = "vopb_mmu"; power-domains = <&power RK3288_PD_VIO>; @@ -998,7 +1017,7 @@ vopl: vop@ff940000 { compatible = "rockchip,rk3288-vop"; - reg = <0xff940000 0x19c>; + reg = <0x0 0xff940000 0x0 0x19c>; interrupts = ; clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; @@ -1031,7 +1050,7 @@ vopl_mmu: iommu@ff940300 { compatible = "rockchip,iommu"; - reg = <0xff940300 0x100>; + reg = <0x0 0xff940300 0x0 0x100>; interrupts = ; interrupt-names = "vopl_mmu"; power-domains = <&power RK3288_PD_VIO>; @@ -1041,7 +1060,7 @@ mipi_dsi: mipi@ff960000 { compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"; - reg = <0xff960000 0x4000>; + reg = <0x0 0xff960000 0x0 0x4000>; interrupts = ; clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_MIPI_DSI0>; clock-names = "ref", "pclk"; @@ -1069,7 +1088,7 @@ edp: dp@ff970000 { compatible = "rockchip,rk3288-dp"; - reg = <0xff970000 0x4000>; + reg = <0x0 0xff970000 0x0 0x4000>; interrupts = ; clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>; clock-names = "dp", "pclk"; @@ -1101,7 +1120,7 @@ hdmi: hdmi@ff980000 { compatible = "rockchip,rk3288-dw-hdmi"; - reg = <0xff980000 0x20000>; + reg = <0x0 0xff980000 0x0 0x20000>; reg-io-width = <4>; rockchip,grf = <&grf>; interrupts = ; @@ -1126,9 +1145,27 @@ }; }; - gpu: mali@ffa30000 { - compatible = "rockchip,rk3288-mali", "arm,mali-t760", "arm,mali-midgard"; - reg = <0xffa30000 0x10000>; + vpu_mmu: iommu@ff9a0800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9a0800 0x0 0x100>; + interrupts = ; + interrupt-names = "vpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + hevc_mmu: iommu@ff9c0440 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>; + interrupts = ; + interrupt-names = "hevc_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + gpu: gpu@ffa30000 { + compatible = "rockchip,rk3288-mali", "arm,mali-t760"; + reg = <0x0 0xffa30000 0x0 0x10000>; interrupts = , , ; @@ -1170,72 +1207,72 @@ qos_gpu_r: qos@ffaa0000 { compatible = "syscon"; - reg = <0xffaa0000 0x20>; + reg = <0x0 0xffaa0000 0x0 0x20>; }; qos_gpu_w: qos@ffaa0080 { compatible = "syscon"; - reg = <0xffaa0080 0x20>; + reg = <0x0 0xffaa0080 0x0 0x20>; }; qos_vio1_vop: qos@ffad0000 { compatible = "syscon"; - reg = <0xffad0000 0x20>; + reg = <0x0 0xffad0000 0x0 0x20>; }; qos_vio1_isp_w0: qos@ffad0100 { compatible = "syscon"; - reg = <0xffad0100 0x20>; + reg = <0x0 0xffad0100 0x0 0x20>; }; qos_vio1_isp_w1: qos@ffad0180 { compatible = "syscon"; - reg = <0xffad0180 0x20>; + reg = <0x0 0xffad0180 0x0 0x20>; }; qos_vio0_vop: qos@ffad0400 { compatible = "syscon"; - reg = <0xffad0400 0x20>; + reg = <0x0 0xffad0400 0x0 0x20>; }; qos_vio0_vip: qos@ffad0480 { compatible = "syscon"; - reg = <0xffad0480 0x20>; + reg = <0x0 0xffad0480 0x0 0x20>; }; qos_vio0_iep: qos@ffad0500 { compatible = "syscon"; - reg = <0xffad0500 0x20>; + reg = <0x0 0xffad0500 0x0 0x20>; }; qos_vio2_rga_r: qos@ffad0800 { compatible = "syscon"; - reg = <0xffad0800 0x20>; + reg = <0x0 0xffad0800 0x0 0x20>; }; qos_vio2_rga_w: qos@ffad0880 { compatible = "syscon"; - reg = <0xffad0880 0x20>; + reg = <0x0 0xffad0880 0x0 0x20>; }; qos_vio1_isp_r: qos@ffad0900 { compatible = "syscon"; - reg = <0xffad0900 0x20>; + reg = <0x0 0xffad0900 0x0 0x20>; }; qos_video: qos@ffae0000 { compatible = "syscon"; - reg = <0xffae0000 0x20>; + reg = <0x0 0xffae0000 0x0 0x20>; }; qos_hevc_r: qos@ffaf0000 { compatible = "syscon"; - reg = <0xffaf0000 0x20>; + reg = <0x0 0xffaf0000 0x0 0x20>; }; qos_hevc_w: qos@ffaf0080 { compatible = "syscon"; - reg = <0xffaf0080 0x20>; + reg = <0x0 0xffaf0080 0x0 0x20>; }; gic: interrupt-controller@ffc01000 { @@ -1244,16 +1281,16 @@ #interrupt-cells = <3>; #address-cells = <0>; - reg = <0xffc01000 0x1000>, - <0xffc02000 0x2000>, - <0xffc04000 0x2000>, - <0xffc06000 0x2000>; + reg = <0x0 0xffc01000 0x0 0x1000>, + <0x0 0xffc02000 0x0 0x2000>, + <0x0 0xffc04000 0x0 0x2000>, + <0x0 0xffc06000 0x0 0x2000>; interrupts = ; }; efuse: efuse@ffb40000 { compatible = "rockchip,rk3288-efuse"; - reg = <0xffb40000 0x20>; + reg = <0x0 0xffb40000 0x0 0x20>; #address-cells = <1>; #size-cells = <1>; clocks = <&cru PCLK_EFUSE256>; @@ -1268,13 +1305,13 @@ compatible = "rockchip,rk3288-pinctrl"; rockchip,grf = <&grf>; rockchip,pmu = <&pmu>; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; gpio0: gpio0@ff750000 { compatible = "rockchip,gpio-bank"; - reg = <0xff750000 0x100>; + reg = <0x0 0xff750000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO0>; @@ -1287,7 +1324,7 @@ gpio1: gpio1@ff780000 { compatible = "rockchip,gpio-bank"; - reg = <0xff780000 0x100>; + reg = <0x0 0xff780000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO1>; @@ -1300,7 +1337,7 @@ gpio2: gpio2@ff790000 { compatible = "rockchip,gpio-bank"; - reg = <0xff790000 0x100>; + reg = <0x0 0xff790000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO2>; @@ -1313,7 +1350,7 @@ gpio3: gpio3@ff7a0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7a0000 0x100>; + reg = <0x0 0xff7a0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO3>; @@ -1326,7 +1363,7 @@ gpio4: gpio4@ff7b0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7b0000 0x100>; + reg = <0x0 0xff7b0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO4>; @@ -1339,7 +1376,7 @@ gpio5: gpio5@ff7c0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7c0000 0x100>; + reg = <0x0 0xff7c0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO5>; @@ -1352,7 +1389,7 @@ gpio6: gpio6@ff7d0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7d0000 0x100>; + reg = <0x0 0xff7d0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO6>; @@ -1365,7 +1402,7 @@ gpio7: gpio7@ff7e0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7e0000 0x100>; + reg = <0x0 0xff7e0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO7>; @@ -1378,7 +1415,7 @@ gpio8: gpio8@ff7f0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7f0000 0x100>; + reg = <0x0 0xff7f0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO8>; diff --git a/arch/arm/boot/dts/rv1108-evb.dts b/arch/arm/boot/dts/rv1108-evb.dts index 58cf4ac079c3dea6b307148bca9311bda36162a3..86a57f823616185a14ede94aebdcf853e6edfa16 100644 --- a/arch/arm/boot/dts/rv1108-evb.dts +++ b/arch/arm/boot/dts/rv1108-evb.dts @@ -54,6 +54,184 @@ chosen { stdout-path = "serial2:1500000n8"; }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + pwms = <&pwm0 0 25000 0>; + }; + + vcc_sys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vsys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_core>; +}; + +&i2c0 { + status = "okay"; + i2c-scl-rising-time-ns = <275>; + i2c-scl-falling-time-ns = <16>; + clock-frequency = <400000>; + + rk805: pmic@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio0>; + interrupts = ; + rockchip,system-power-controller; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + + regulators { + vdd_core: DCDC_REG1 { + regulator-name= "vdd_core"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + regulator-state-uv = <900000>; + }; + }; + + vdd_cam: DCDC_REG2 { + regulator-name= "vdd_cam"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <2000000>; + regulator-state-mem { + regulator-state-disabled; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name= "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name= "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + regulator-state-uv = <3300000>; + }; + }; + + vdd_10: LDO_REG1 { + regulator-name= "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-disabled; + }; + }; + + vcc_18: LDO_REG2 { + regulator-name= "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-disabled; + }; + }; + + vdd10_pmu: LDO_REG3 { + regulator-name= "vdd10_pmu"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + regulator-state-uv = <1000000>; + }; + }; + }; + }; + + bma250: accelerometer@19 { + compatible = "bosch,bma250e"; + reg = <0x19>; + interrupt-parent = <&gpio0>; + interrupts = ; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&sdmmc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; }; &uart0 { @@ -67,3 +245,15 @@ &uart2 { status = "okay"; }; + +&usb_host_ehci { + status = "okay"; +}; + +&usb_host_ohci { + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi index 437098b556eb8b9119f2fbbda79f35ce664e7920..e7cd1315db1b7bc08c688867dd77c4687396fe92 100644 --- a/arch/arm/boot/dts/rv1108.dtsi +++ b/arch/arm/boot/dts/rv1108.dtsi @@ -52,6 +52,10 @@ interrupt-parent = <&gic>; aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -65,6 +69,33 @@ device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0xf00>; + clocks = <&cru ARMCLK>; + operating-points-v2 = <&cpu_opp_table>; + }; + }; + + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <975000>; + clock-latency-ns = <40000>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <975000>; + clock-latency-ns = <40000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1025000>; + clock-latency-ns = <40000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1150000>; + clock-latency-ns = <40000>; }; }; @@ -154,9 +185,221 @@ status = "disabled"; }; + i2c1: i2c@10240000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x10240000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + i2c2: i2c@10250000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x10250000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2m1_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + i2c3: i2c@10260000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x10260000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + spi: spi@10270000 { + compatible = "rockchip,rv1108-spi"; + reg = <0x10270000 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&pdma 8>, <&pdma 9>; + #dma-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm4: pwm@10280000 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280000 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm4_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm@10280010 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280010 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm5_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm@10280020 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280020 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm6_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm@10280030 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280030 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + grf: syscon@10300000 { - compatible = "rockchip,rv1108-grf", "syscon"; + compatible = "rockchip,rv1108-grf", "syscon", "simple-mfd"; reg = <0x10300000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy: usb2-phy@100 { + compatible = "rockchip,rv1108-usb2phy"; + reg = <0x100 0x0c>; + clocks = <&cru SCLK_USBPHY>; + clock-names = "phyclk"; + #clock-cells = <0>; + clock-output-names = "usbphy"; + rockchip,usbgrf = <&usbgrf>; + status = "disabled"; + + u2phy_otg: otg-port { + interrupts = ; + interrupt-names = "otg-mux"; + #phy-cells = <0>; + status = "disabled"; + }; + + u2phy_host: host-port { + interrupts = ; + interrupt-names = "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + }; + }; + + watchdog: wdt@10360000 { + compatible = "snps,dw-wdt"; + reg = <0x10360000 0x100>; + interrupts = ; + clocks = <&cru PCLK_WDT>; + clock-names = "pclk_wdt"; + status = "disabled"; + }; + + adc: adc@1038c000 { + compatible = "rockchip,rv1108-saradc", "rockchip,rk3399-saradc"; + reg = <0x1038c000 0x100>; + interrupts = ; + #io-channel-cells = <1>; + clock-frequency = <1000000>; + clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + status = "disabled"; + }; + + i2c0: i2c@20000000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x20000000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C0_PMU>, <&cru PCLK_I2C0_PMU>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + pwm0: pwm@20040000 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040000 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@20040010 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040010 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@20040020 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040020 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm2_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@20040030 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040030 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pin>; + #pwm-cells = <3>; + status = "disabled"; }; pmugrf: syscon@20060000 { @@ -164,6 +407,11 @@ reg = <0x20060000 0x1000>; }; + usbgrf: syscon@202a0000 { + compatible = "rockchip,rv1108-usbgrf", "syscon"; + reg = <0x202a0000 0x1000>; + }; + cru: clock-controller@20200000 { compatible = "rockchip,rv1108-cru"; reg = <0x20200000 0x1000>; @@ -174,37 +422,78 @@ emmc: dwmmc@30110000 { compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - clock-freq-min-max = <400000 150000000>; + reg = <0x30110000 0x4000>; + interrupts = ; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; - interrupts = ; - reg = <0x30110000 0x4000>; + max-frequency = <150000000>; status = "disabled"; }; sdio: dwmmc@30120000 { compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - clock-freq-min-max = <400000 150000000>; + reg = <0x30120000 0x4000>; + interrupts = ; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; - interrupts = ; - reg = <0x30120000 0x4000>; + max-frequency = <150000000>; status = "disabled"; }; sdmmc: dwmmc@30130000 { compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - clock-freq-min-max = <400000 100000000>; + reg = <0x30130000 0x4000>; + interrupts = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; - interrupts = ; - reg = <0x30130000 0x4000>; + max-frequency = <100000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + status = "disabled"; + }; + + usb_host_ehci: usb@30140000 { + compatible = "generic-ehci"; + reg = <0x30140000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host_ohci: usb@30160000 { + compatible = "generic-ohci"; + reg = <0x30160000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_otg: usb@30180000 { + compatible = "rockchip,rv1108-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0x30180000 0x40000>; + interrupts = ; + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; + dr_mode = "otg"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; + g-use-dma; + phys = <&u2phy_otg>; + phy-names = "usb2-phy"; status = "disabled"; }; @@ -301,6 +590,11 @@ drive-strength = <12>; }; + pcfg_pull_none_smt: pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + }; + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { bias-pull-up; drive-strength = <8>; @@ -328,6 +622,13 @@ input-enable; }; + i2c0 { + i2c0_xfer: i2c0-xfer { + rockchip,pins = <0 RK_PB1 RK_FUNC_1 &pcfg_pull_none_smt>, + <0 RK_PB2 RK_FUNC_1 &pcfg_pull_none_smt>; + }; + }; + i2c1 { i2c1_xfer: i2c1-xfer { rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>, @@ -366,6 +667,54 @@ }; }; + pwm0 { + pwm0_pin: pwm0-pin { + rockchip,pins = <0 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm1 { + pwm1_pin: pwm1-pin { + rockchip,pins = <0 RK_PC4 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm2 { + pwm2_pin: pwm2-pin { + rockchip,pins = <0 RK_PC6 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm3 { + pwm3_pin: pwm3-pin { + rockchip,pins = <0 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm4 { + pwm4_pin: pwm4-pin { + rockchip,pins = <1 RK_PC1 RK_FUNC_3 &pcfg_pull_none>; + }; + }; + + pwm5 { + pwm5_pin: pwm5-pin { + rockchip,pins = <1 RK_PA7 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + pwm6 { + pwm6_pin: pwm6-pin { + rockchip,pins = <1 RK_PB0 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + pwm7 { + pwm7_pin: pwm7-pin { + rockchip,pins = <1 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + sdmmc { sdmmc_clk: sdmmc-clk { rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>; diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index cc06da3943668415e9b6379dbe38d2fde36518ec..38d2216c7ead9ff422cce1e740a820e47977a700 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -303,7 +303,7 @@ #size-cells = <1>; atmel,smc = <&hsmc>; reg = <0x10000000 0x10000000 - 0x40000000 0x30000000>; + 0x60000000 0x30000000>; ranges = <0x0 0x0 0x10000000 0x10000000 0x1 0x0 0x60000000 0x10000000 0x2 0x0 0x70000000 0x10000000 @@ -416,6 +416,17 @@ }; }; + isc: isc@f0008000 { + compatible = "atmel,sama5d2-isc"; + reg = <0xf0008000 0x4000>; + interrupts = <46 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&isc_clk>, <&iscck>, <&isc_gclk>; + clock-names = "hclock", "iscck", "gck"; + #clock-cells = <0>; + clock-output-names = "isc-mck"; + status = "disabled"; + }; + ramc0: ramc@f000c000 { compatible = "atmel,sama5d3-ddramc"; reg = <0xf000c000 0x200>; @@ -494,6 +505,24 @@ clocks = <&plla>; }; + audio_pll_frac: audiopll_fracck { + compatible = "atmel,sama5d2-clk-audio-pll-frac"; + #clock-cells = <0>; + clocks = <&main>; + }; + + audio_pll_pad: audiopll_padck { + compatible = "atmel,sama5d2-clk-audio-pll-pad"; + #clock-cells = <0>; + clocks = <&audio_pll_frac>; + }; + + audio_pll_pmc: audiopll_pmcck { + compatible = "atmel,sama5d2-clk-audio-pll-pmc"; + #clock-cells = <0>; + clocks = <&audio_pll_frac>; + }; + utmi: utmick { compatible = "atmel,at91sam9x5-clk-utmi"; #clock-cells = <0>; @@ -895,7 +924,7 @@ #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&pmc>; - clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>; + clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>; sdmmc0_gclk: sdmmc0_gclk { #clock-cells = <0>; @@ -925,6 +954,11 @@ atmel,clk-output-range = <0 83000000>; }; + isc_gclk: isc_gclk { + #clock-cells = <0>; + reg = <46>; + }; + pdmic_gclk: pdmic_gclk { #clock-cells = <0>; reg = <48>; @@ -951,9 +985,37 @@ reg = <57>; atmel,clk-output-range = <0 80000000>; }; + + classd_gclk: classd_gclk { + #clock-cells = <0>; + reg = <59>; + atmel,clk-output-range = <0 100000000>; + }; }; }; + qspi0: spi@f0020000 { + compatible = "atmel,sama5d2-qspi"; + reg = <0xf0020000 0x100>, <0xd0000000 0x08000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&qspi0_clk>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + qspi1: spi@f0024000 { + compatible = "atmel,sama5d2-qspi"; + reg = <0xf0024000 0x100>, <0xd8000000 0x08000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <53 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&qspi1_clk>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + sha@f0028000 { compatible = "atmel,at91sam9g46-sha"; reg = <0xf0028000 0x100>; @@ -1048,18 +1110,18 @@ }; hsmc: hsmc@f8014000 { - compatible = "atmel,sama5d3-smc", "syscon", "simple-mfd"; + compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd"; reg = <0xf8014000 0x1000>; - interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>; clocks = <&hsmc_clk>; #address-cells = <1>; #size-cells = <1>; ranges; - pmecc: ecc-engine@ffffc070 { + pmecc: ecc-engine@f8014070 { compatible = "atmel,sama5d2-pmecc"; - reg = <0xffffc070 0x490>, - <0xffffc500 0x100>; + reg = <0xf8014070 0x490>, + <0xf8014500 0x100>; }; }; @@ -1406,6 +1468,19 @@ status = "okay"; }; + classd: classd@fc048000 { + compatible = "atmel,sama5d2-classd"; + reg = <0xfc048000 0x100>; + interrupts = <59 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(47))>; + dma-names = "tx"; + clocks = <&classd_clk>, <&classd_gclk>; + clock-names = "pclk", "gclk"; + status = "disabled"; + }; + can1: can@fc050000 { compatible = "bosch,m_can"; reg = <0xfc050000 0x4000>, <0x210000 0x4000>; diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 54bc6d3cf2903e8d710aaa0ea178232d3be09942..40f4ad3c34c6e5e496622a99936c0b3bdfc1830c 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -98,6 +98,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; @@ -116,6 +117,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x90020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; @@ -134,6 +136,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0xc0020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index df2232d767ed2ea7ffca8383e258cecb768dc679..5f347054527def7bc99e5a62575e986d0d5b067a 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -63,6 +63,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 6c5affe2d0f556eab1d3415718bd5e8fcf36842a..2310a4e97768c222ca19fe8f125c5aede36be8d1 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -37,6 +37,14 @@ device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <0x300>; + /* cpufreq controls */ + operating-points = <998400 0 + 800000 0 + 400000 0 + 200000 0>; + clocks = <&prcmu_clk PRCMU_ARMSS>; + clock-names = "cpu"; + clock-latency = <20000>; }; CPU1: cpu@301 { device_type = "cpu"; @@ -494,13 +502,6 @@ reg = <0x80157450 0xC>; }; - cpufreq { - compatible = "stericsson,cpufreq-ux500"; - clocks = <&prcmu_clk PRCMU_ARMSS>; - clock-names = "armss"; - status = "disabled"; - }; - thermal@801573c0 { compatible = "stericsson,db8500-thermal"; reg = <0x801573c0 0x40>; diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi index 5882a2606ac3b38d37bb629469955bc949bbd7ce..3f14b4df69b4e4d1ab27bd821eaeeb8d819ef40f 100644 --- a/arch/arm/boot/dts/ste-hrefprev60.dtsi +++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi @@ -30,7 +30,7 @@ i2c@80004000 { tps61052@33 { - compatible = "tps61052"; + compatible = "ti,tps61052"; reg = <0x33>; }; diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index dcda0bbefe5b5a532df6a00f9c8a1083747acefe..293ecb95722715d6ec4dc36da07496134f51a631 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -47,6 +47,7 @@ /dts-v1/; #include "stm32f429.dtsi" +#include "stm32f429-pinctrl.dtsi" #include #include @@ -55,7 +56,7 @@ compatible = "st,stm32429i-eval", "st,stm32f429"; chosen { - bootargs = "root=/dev/ram rdinit=/linuxrc"; + bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; }; @@ -202,10 +203,8 @@ stmpe1600: stmpe1600@42 { compatible = "st,stmpe1600"; reg = <0x42>; - irq-gpio = <&gpioi 8 0>; - irq-trigger = <3>; interrupts = <8 3>; - interrupt-parent = <&exti>; + interrupt-parent = <&gpioi>; interrupt-controller; wakeup-source; diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7f3560c0211dd8972f06a89e34d54c5c00d9fbfa --- /dev/null +++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi @@ -0,0 +1,343 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/ { + soc { + pinctrl: pin-controller { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x40020000 0x3000>; + interrupt-parent = <&exti>; + st,syscfg = <&syscfg 0x8>; + pins-are-numbered; + + gpioa: gpio@40020000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x0 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; + st,bank-name = "GPIOA"; + }; + + gpiob: gpio@40020400 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x400 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; + st,bank-name = "GPIOB"; + }; + + gpioc: gpio@40020800 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x800 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; + st,bank-name = "GPIOC"; + }; + + gpiod: gpio@40020c00 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0xc00 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; + st,bank-name = "GPIOD"; + }; + + gpioe: gpio@40021000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1000 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; + st,bank-name = "GPIOE"; + }; + + gpiof: gpio@40021400 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1400 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; + st,bank-name = "GPIOF"; + }; + + gpiog: gpio@40021800 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1800 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; + st,bank-name = "GPIOG"; + }; + + gpioh: gpio@40021c00 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1c00 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; + st,bank-name = "GPIOH"; + }; + + gpioi: gpio@40022000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2000 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; + st,bank-name = "GPIOI"; + }; + + gpioj: gpio@40022400 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2400 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; + st,bank-name = "GPIOJ"; + }; + + gpiok: gpio@40022800 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2800 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; + st,bank-name = "GPIOK"; + }; + + usart1_pins_a: usart1@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; + + usart3_pins_a: usart3@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; + + usbotg_fs_pins_a: usbotg_fs@0 { + pins { + pinmux = , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + usbotg_fs_pins_b: usbotg_fs@1 { + pins { + pinmux = , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + usbotg_hs_pins_a: usbotg_hs@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + ethernet_mii: mii@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + + adc3_in8_pin: adc@200 { + pins { + pinmux = ; + }; + }; + + pwm1_pins: pwm@1 { + pins { + pinmux = , + , + ; + }; + }; + + pwm3_pins: pwm@3 { + pins { + pinmux = , + ; + }; + }; + + i2c1_pins: i2c1@0 { + pins { + pinmux = , + ; + bias-disable; + drive-open-drain; + slew-rate = <3>; + }; + }; + + ltdc_pins: ltdc@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + + dcmi_pins: dcmi@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts index ae47cde7952f6bb16fe13b435a0f704cda7fbc8a..5ceb2cf3777ff425a41a59da6dc90fe08adc257e 100644 --- a/arch/arm/boot/dts/stm32f429-disco.dts +++ b/arch/arm/boot/dts/stm32f429-disco.dts @@ -47,6 +47,7 @@ /dts-v1/; #include "stm32f429.dtsi" +#include "stm32f429-pinctrl.dtsi" #include / { @@ -54,7 +55,7 @@ compatible = "st,stm32f429i-disco", "st,stm32f429"; chosen { - bootargs = "root=/dev/ram rdinit=/linuxrc"; + bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/imx6ul-geam-kit.dts b/arch/arm/boot/dts/stm32f429-pinctrl.dtsi similarity index 63% rename from arch/arm/boot/dts/imx6ul-geam-kit.dts rename to arch/arm/boot/dts/stm32f429-pinctrl.dtsi index 142e60cab65f509e14909033822645785dea17b2..3e7a17d9112e1cf90d7284f6f048a99bc88e0994 100644 --- a/arch/arm/boot/dts/imx6ul-geam-kit.dts +++ b/arch/arm/boot/dts/stm32f429-pinctrl.dtsi @@ -1,6 +1,5 @@ /* - * Copyright (C) 2016 Amarula Solutions B.V. - * Copyright (C) 2016 Engicam S.r.l. + * Copyright 2017 - Alexandre Torgue * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -8,8 +7,9 @@ * whole. * * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -40,62 +40,56 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/dts-v1/; - -#include -#include "imx6ul-geam.dtsi" +#include "stm32f4-pinctrl.dtsi" / { - model = "Engicam GEAM6UL"; - compatible = "engicam,imx6ul-geam", "fsl,imx6ul"; -}; + soc { + pinctrl: pin-controller { + compatible = "st,stm32f429-pinctrl"; -&can1 { - status = "okay"; -}; + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; -&can2 { - status = "okay"; -}; + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; -&lcdif { - display = <&display0>; - status = "okay"; + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; - display0: display { - bits-per-pixel = <16>; - bus-width = <18>; - status = "okay"; + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <28000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <30>; - hback-porch = <30>; - hsync-len = <64>; - vback-porch = <5>; - vfront-porch = <5>; - vsync-len = <20>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; }; - }; - }; -}; -&usdhc1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; - status = "okay"; -}; + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; + + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; + + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; + + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; + + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 16>; + }; -&tsc { - measure-delay-time = <0x1ffff>; - pre-charge-time = <0x1fff>; - status = "okay"; + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 0 160 8>; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index a8113dc879cfeed36a67eb32417764374cfd23e1..5b36eb114ddc953067904afbd08497b2286c3785 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -47,7 +47,6 @@ #include "skeleton.dtsi" #include "armv7-m.dtsi" -#include #include #include @@ -361,6 +360,31 @@ status = "disabled"; }; + dac: dac@40007400 { + compatible = "st,stm32f4-dac-core"; + reg = <0x40007400 0x400>; + resets = <&rcc STM32F4_APB1_RESET(DAC)>; + clocks = <&rcc 0 STM32F4_APB1_CLOCK(DAC)>; + clock-names = "pclk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + dac1: dac@1 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <1>; + status = "disabled"; + }; + + dac2: dac@2 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <2>; + status = "disabled"; + }; + }; + usart7: serial@40007800 { compatible = "st,stm32-usart", "st,stm32-uart"; reg = <0x40007800 0x400>; @@ -566,302 +590,6 @@ status = "disabled"; }; - pinctrl: pin-controller { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,stm32f429-pinctrl"; - ranges = <0 0x40020000 0x3000>; - interrupt-parent = <&exti>; - st,syscfg = <&syscfg 0x8>; - pins-are-numbered; - - gpioa: gpio@40020000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x0 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; - st,bank-name = "GPIOA"; - }; - - gpiob: gpio@40020400 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x400 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; - st,bank-name = "GPIOB"; - }; - - gpioc: gpio@40020800 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x800 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; - st,bank-name = "GPIOC"; - }; - - gpiod: gpio@40020c00 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0xc00 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; - st,bank-name = "GPIOD"; - }; - - gpioe: gpio@40021000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1000 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; - st,bank-name = "GPIOE"; - }; - - gpiof: gpio@40021400 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1400 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; - st,bank-name = "GPIOF"; - }; - - gpiog: gpio@40021800 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1800 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; - st,bank-name = "GPIOG"; - }; - - gpioh: gpio@40021c00 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1c00 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; - st,bank-name = "GPIOH"; - }; - - gpioi: gpio@40022000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2000 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; - st,bank-name = "GPIOI"; - }; - - gpioj: gpio@40022400 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2400 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; - st,bank-name = "GPIOJ"; - }; - - gpiok: gpio@40022800 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2800 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; - st,bank-name = "GPIOK"; - }; - - usart1_pins_a: usart1@0 { - pins1 { - pinmux = ; - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; - bias-disable; - }; - }; - - usart3_pins_a: usart3@0 { - pins1 { - pinmux = ; - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; - bias-disable; - }; - }; - - usbotg_fs_pins_a: usbotg_fs@0 { - pins { - pinmux = , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - }; - - usbotg_fs_pins_b: usbotg_fs@1 { - pins { - pinmux = , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - }; - - usbotg_hs_pins_a: usbotg_hs@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - }; - - ethernet_mii: mii@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - ; - slew-rate = <2>; - }; - }; - - adc3_in8_pin: adc@200 { - pins { - pinmux = ; - }; - }; - - pwm1_pins: pwm@1 { - pins { - pinmux = , - , - ; - }; - }; - - pwm3_pins: pwm@3 { - pins { - pinmux = , - ; - }; - }; - - i2c1_pins: i2c1@0 { - pins { - pinmux = , - ; - bias-disable; - drive-open-drain; - slew-rate = <3>; - }; - }; - - ltdc_pins: ltdc@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - slew-rate = <2>; - }; - }; - - dcmi_pins: dcmi@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <3>; - }; - }; - }; - crc: crc@40023000 { compatible = "st,stm32f4-crc"; reg = <0x40023000 0x400>; diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts index 75470c34b92cb36c5f1f6eb61c3c0f31e94a84bf..c18acbe4cf4e2448b085331fca86a72710eeb613 100644 --- a/arch/arm/boot/dts/stm32f469-disco.dts +++ b/arch/arm/boot/dts/stm32f469-disco.dts @@ -47,13 +47,14 @@ /dts-v1/; #include "stm32f429.dtsi" +#include "stm32f469-pinctrl.dtsi" / { model = "STMicroelectronics STM32F469i-DISCO board"; compatible = "st,stm32f469i-disco", "st,stm32f469"; chosen { - bootargs = "root=/dev/ram rdinit=/linuxrc"; + bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/stm32f469-pinctrl.dtsi b/arch/arm/boot/dts/stm32f469-pinctrl.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..fff542662eeaa3a917e95b628a58af0e39f81f0c --- /dev/null +++ b/arch/arm/boot/dts/stm32f469-pinctrl.dtsi @@ -0,0 +1,96 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "stm32f4-pinctrl.dtsi" + +/ { + soc { + pinctrl: pin-controller { + compatible = "st,stm32f469-pinctrl"; + + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; + + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; + + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; + + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; + + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; + + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; + + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; + + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; + + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 6>, + <&pinctrl 12 156 4>; + }; + + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 3 163 5>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi index 4506eb97a4ab47baf45cda13f851083a951cb440..5633860037d23397379b092a4cf5bba353abb367 100644 --- a/arch/arm/boot/dts/stm32f746.dtsi +++ b/arch/arm/boot/dts/stm32f746.dtsi @@ -167,6 +167,15 @@ status = "disabled"; }; + cec: cec@40006c00 { + compatible = "st,stm32-cec"; + reg = <0x40006C00 0x400>; + interrupts = <94>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(CEC)>, <&rcc 1 CLK_HDMI_CEC>; + clock-names = "cec", "hdmi-cec"; + status = "disabled"; + }; + usart7: serial@40007800 { compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40007800 0x400>; @@ -336,6 +345,15 @@ st,bank-name = "GPIOK"; }; + cec_pins_a: cec@0 { + pins { + pinmux = ; + slew-rate = <0>; + drive-open-drain; + bias-disable; + }; + }; + usart1_pins_a: usart1@0 { pins1 { pinmux = ; @@ -380,6 +398,39 @@ assigned-clocks = <&rcc 1 CLK_HSE_RTC>; assigned-clock-rates = <1000000>; }; + + dma1: dma@40026000 { + compatible = "st,stm32-dma"; + reg = <0x40026000 0x400>; + interrupts = <11>, + <12>, + <13>, + <14>, + <15>, + <16>, + <17>, + <47>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(DMA1)>; + #dma-cells = <4>; + status = "disabled"; + }; + + dma2: dma@40026400 { + compatible = "st,stm32-dma"; + reg = <0x40026400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(DMA2)>; + #dma-cells = <4>; + st,mem2mem; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts index 166728aeb16669f5a1086e9ace525a1d17490328..4463ca13a740e8ce0c568a6d0e8ece07f962d80c 100644 --- a/arch/arm/boot/dts/stm32f769-disco.dts +++ b/arch/arm/boot/dts/stm32f769-disco.dts @@ -63,6 +63,12 @@ }; +&cec { + pinctrl-0 = <&cec_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; + &clk_hse { clock-frequency = <25000000>; }; diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi index 36a99db0a3b4cd08a1e8388ad5c8d832efeb8781..58ec2275181ef7c196087ba8ba2ac6d05da6524a 100644 --- a/arch/arm/boot/dts/stm32h743.dtsi +++ b/arch/arm/boot/dts/stm32h743.dtsi @@ -59,6 +59,45 @@ }; soc { + timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; + clocks = <&timer_clk>; + }; + + usart2: serial@40004400 { + compatible = "st,stm32f7-usart", "st,stm32f7-uart"; + reg = <0x40004400 0x400>; + interrupts = <38>; + status = "disabled"; + clocks = <&timer_clk>; + }; + + dac: dac@40007400 { + compatible = "st,stm32h7-dac-core"; + reg = <0x40007400 0x400>; + clocks = <&timer_clk>; + clock-names = "pclk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + dac1: dac@1 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <1>; + status = "disabled"; + }; + + dac2: dac@2 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <2>; + status = "disabled"; + }; + }; + usart1: serial@40011000 { compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40011000 0x400>; @@ -68,19 +107,91 @@ }; - usart2: serial@40004400 { - compatible = "st,stm32f7-usart", "st,stm32f7-uart"; - reg = <0x40004400 0x400>; - interrupts = <38>; + dma1: dma@40020000 { + compatible = "st,stm32-dma"; + reg = <0x40020000 0x400>; + interrupts = <11>, + <12>, + <13>, + <14>, + <15>, + <16>, + <17>, + <47>; + clocks = <&timer_clk>; + #dma-cells = <4>; + st,mem2mem; status = "disabled"; + }; + + dma2: dma@40020400 { + compatible = "st,stm32-dma"; + reg = <0x40020400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; clocks = <&timer_clk>; + #dma-cells = <4>; + st,mem2mem; + status = "disabled"; }; - timer5: timer@40000c00 { - compatible = "st,stm32-timer"; - reg = <0x40000c00 0x400>; - interrupts = <50>; + adc_12: adc@40022000 { + compatible = "st,stm32h7-adc-core"; + reg = <0x40022000 0x400>; + interrupts = <18>; + clocks = <&timer_clk>; + clock-names = "bus"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + adc1: adc@0 { + compatible = "st,stm32h7-adc"; + #io-channel-cells = <1>; + reg = <0x0>; + interrupt-parent = <&adc_12>; + interrupts = <0>; + status = "disabled"; + }; + + adc2: adc@100 { + compatible = "st,stm32h7-adc"; + #io-channel-cells = <1>; + reg = <0x100>; + interrupt-parent = <&adc_12>; + interrupts = <1>; + status = "disabled"; + }; + }; + + adc_3: adc@58026000 { + compatible = "st,stm32h7-adc-core"; + reg = <0x58026000 0x400>; + interrupts = <127>; clocks = <&timer_clk>; + clock-names = "bus"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + adc3: adc@0 { + compatible = "st,stm32h7-adc"; + #io-channel-cells = <1>; + reg = <0x0>; + interrupt-parent = <&adc_3>; + interrupts = <0>; + status = "disabled"; + }; }; }; }; diff --git a/arch/arm/boot/dts/stm32h743i-eval.dts b/arch/arm/boot/dts/stm32h743i-eval.dts index c6effbb36e4a8983131998ef00780b465c6327ff..6c07786e7ddb9195fc88108d5d1906deb13f6c12 100644 --- a/arch/arm/boot/dts/stm32h743i-eval.dts +++ b/arch/arm/boot/dts/stm32h743i-eval.dts @@ -60,6 +60,24 @@ aliases { serial0 = &usart1; }; + + vdda: regulator-vdda { + compatible = "regulator-fixed"; + regulator-name = "vdda"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; +}; + +&adc_12 { + vref-supply = <&vdda>; + status = "okay"; + adc1: adc@0 { + /* potentiometer */ + st,adc-channels = <0>; + status = "okay"; + }; }; &clk_hse { diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index aebc3f9dc7b679da02f85e96a26f74719182ead4..b147cb0dc14b26ce92db7ea70bba2a8f77bd0d38 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -1155,11 +1155,11 @@ ; }; - nmi_intc: interrupt-controller@01f00c0c { - compatible = "allwinner,sun6i-a31-sc-nmi"; + nmi_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun6i-a31-r-intc"; interrupt-controller; #interrupt-cells = <2>; - reg = <0x01f00c0c 0x38>; + reg = <0x01f00c00 0x400>; interrupts = ; }; diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts index bb510187602c1c2e43c01d43a210430f3317b70b..852a0aa24dcee6c577b167c9d36d9c01b9a59403 100644 --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts @@ -271,6 +271,10 @@ status = "okay"; }; +&battery_power_supply { + status = "okay"; +}; + ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi index a8b978d0f35b5f68b6621fa5e4ac71c3e3395dce..ea50dda75adceba97c0d9f16ff4f90eab366c3d9 100644 --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi @@ -519,11 +519,11 @@ #clock-cells = <1>; }; - nmi_intc: interrupt-controller@01f00c0c { - compatible = "allwinner,sun6i-a31-sc-nmi"; + nmi_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun6i-a31-r-intc"; interrupt-controller; #interrupt-cells = <2>; - reg = <0x01f00c0c 0x38>; + reg = <0x01f00c00 0x400>; interrupts = ; }; diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts index aecdeeb368ed85e0c5e59c47f7aeebcd5cbf9a70..1f0d60afb25b695c44523c70d80677f1dd753ecb 100644 --- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -43,6 +43,7 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" / { model = "Allwinner A83T H8Homlet Proto Dev Board v2.0"; @@ -57,8 +58,92 @@ }; }; +&ehci0 { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v0>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + bus-width = <4>; + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v0>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +®_usb0_vbus { + gpio = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 */ + status = "okay"; +}; + +®_usb1_vbus { + gpio = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp81x: pmic@3a3 { + compatible = "x-powers,axp818", "x-powers,axp813"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; + + ac100: codec@e89 { + compatible = "x-powers,ac100"; + reg = <0xe89>; + + ac100_codec: codec { + compatible = "x-powers,ac100-codec"; + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_LEVEL_LOW>; /* PL11 */ + #clock-cells = <0>; + clock-output-names = "4M_adda"; + }; + + ac100_rtc: rtc { + compatible = "x-powers,ac100-rtc"; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + clocks = <&ac100_codec>; + #clock-cells = <1>; + clock-output-names = "cko1_rtc", + "cko2_rtc", + "cko3_rtc"; + }; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; + +&usbphy { + usb0_vbus-supply = <®_usb0_vbus>; + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts new file mode 100644 index 0000000000000000000000000000000000000000..2bafd7e99ef7f2d0d83cfcd155240492059e5d91 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts @@ -0,0 +1,148 @@ +/* + * Copyright 2017 Chen-Yu Tsai + * + * Chen-Yu Tsai + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include + +/ { + model = "Banana Pi BPI-M3"; + compatible = "sinovoip,bpi-m3", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + /* Terminus Tech FE 1.1s 4-port USB 2.0 hub here */ + status = "okay"; + + /* TODO GL830 USB-to-SATA bridge downstream w/ GPIO power controls */ +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp81x: pmic@3a3 { + compatible = "x-powers,axp813"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; + + ac100: codec@e89 { + compatible = "x-powers,ac100"; + reg = <0xe89>; + + ac100_codec: codec { + compatible = "x-powers,ac100-codec"; + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_LEVEL_LOW>; /* PL11 */ + #clock-cells = <0>; + clock-output-names = "4M_adda"; + }; + + ac100_rtc: rtc { + compatible = "x-powers,ac100-rtc"; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + clocks = <&ac100_codec>; + #clock-cells = <1>; + clock-output-names = "cko1_rtc", + "cko2_rtc", + "cko3_rtc"; + }; + }; +}; + +®_usb1_vbus { + gpio = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ + status = "okay"; +}; + +®_vcc3v0 { + status = "disabled"; +}; + +®_vcc5v0 { + status = "disabled"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts index cff33454fc2458bf0e1fee5110ab8dd86c88cc21..716a205c6dbbeca282efbe4498742634205ad8bd 100644 --- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -44,6 +44,7 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" #include @@ -83,6 +84,17 @@ }; }; + usb-hub { + /* I2C is not connected */ + compatible = "smsc,usb3503"; + initial-mode = <1>; /* initialize in HUB mode */ + disabled-ports = <1>; + intn-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + reset-gpios = <&pio 4 16 GPIO_ACTIVE_HIGH>; /* PE16 */ + connect-gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */ + refclk-frequency = <19200000>; + }; + sound { compatible = "simple-audio-card"; simple-audio-card,name = "On-board SPDIF"; @@ -102,6 +114,89 @@ }; }; +&ehci0 { + /* GL830 USB-to-SATA bridge here */ + status = "okay"; +}; + +&ehci1 { + /* USB3503 HSIC USB 2.0 hub here */ + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp81x: pmic@3a3 { + compatible = "x-powers,axp818", "x-powers,axp813"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; + + ac100: codec@e89 { + compatible = "x-powers,ac100"; + reg = <0xe89>; + + ac100_codec: codec { + compatible = "x-powers,ac100-codec"; + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_LEVEL_LOW>; /* PL11 */ + #clock-cells = <0>; + clock-output-names = "4M_adda"; + }; + + ac100_rtc: rtc { + compatible = "x-powers,ac100-rtc"; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + clocks = <&ac100_codec>; + #clock-cells = <1>; + clock-output-names = "cko1_rtc", + "cko2_rtc", + "cko3_rtc"; + }; + }; +}; + +®_usb1_vbus { + gpio = <&pio 3 29 GPIO_ACTIVE_HIGH>; /* PD29 */ + status = "okay"; +}; + +®_usb2_vbus { + gpio = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + status = "okay"; +}; + +®_vcc3v0 { + status = "disabled"; +}; + +®_vcc5v0 { + status = "disabled"; +}; + &spdif { status = "okay"; }; @@ -111,3 +206,9 @@ pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 8923ba625b76f156f27fde9c66f1f72ad044405a..f996bd343e50ca156830b373048f3d51a0234116 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -44,7 +44,10 @@ #include +#include #include +#include +#include / { interrupt-parent = <&gic>; @@ -175,11 +178,146 @@ compatible = "allwinner,sun8i-a83t-dma"; reg = <0x01c02000 0x1000>; interrupts = ; - clocks = <&ccu 21>; - resets = <&ccu 7>; + clocks = <&ccu CLK_BUS_DMA>; + resets = <&ccu RST_BUS_DMA>; #dma-cells = <1>; }; + mmc0: mmc@1c0f000 { + compatible = "allwinner,sun8i-a83t-mmc", + "allwinner,sun7i-a20-mmc"; + reg = <0x01c0f000 0x1000>; + clocks = <&ccu CLK_BUS_MMC0>, + <&ccu CLK_MMC0>, + <&ccu CLK_MMC0_OUTPUT>, + <&ccu CLK_MMC0_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@1c10000 { + compatible = "allwinner,sun8i-a83t-mmc", + "allwinner,sun7i-a20-mmc"; + reg = <0x01c10000 0x1000>; + clocks = <&ccu CLK_BUS_MMC1>, + <&ccu CLK_MMC1>, + <&ccu CLK_MMC1_OUTPUT>, + <&ccu CLK_MMC1_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@1c11000 { + compatible = "allwinner,sun8i-a83t-emmc"; + reg = <0x01c11000 0x1000>; + clocks = <&ccu CLK_BUS_MMC2>, + <&ccu CLK_MMC2>, + <&ccu CLK_MMC2_OUTPUT>, + <&ccu CLK_MMC2_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC2>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + usb_otg: usb@01c19000 { + compatible = "allwinner,sun8i-a83t-musb", + "allwinner,sun8i-a33-musb"; + reg = <0x01c19000 0x0400>; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; + interrupts = ; + interrupt-names = "mc"; + phys = <&usbphy 0>; + phy-names = "usb"; + extcon = <&usbphy 0>; + status = "disabled"; + }; + + usbphy: phy@1c19400 { + compatible = "allwinner,sun8i-a83t-usb-phy"; + reg = <0x01c19400 0x10>, + <0x01c1a800 0x14>, + <0x01c1b800 0x14>; + reg-names = "phy_ctrl", + "pmu1", + "pmu2"; + clocks = <&ccu CLK_USB_PHY0>, + <&ccu CLK_USB_PHY1>, + <&ccu CLK_USB_HSIC>, + <&ccu CLK_USB_HSIC_12M>; + clock-names = "usb0_phy", + "usb1_phy", + "usb2_phy", + "usb2_hsic_12M"; + resets = <&ccu RST_USB_PHY0>, + <&ccu RST_USB_PHY1>, + <&ccu RST_USB_HSIC>; + reset-names = "usb0_reset", + "usb1_reset", + "usb2_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci0: usb@1c1a000 { + compatible = "allwinner,sun8i-a83t-ehci", + "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI0>; + resets = <&ccu RST_BUS_EHCI0>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci0: usb@1c1a400 { + compatible = "allwinner,sun8i-a83t-ohci", + "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_OHCI0>, <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci1: usb@1c1b000 { + compatible = "allwinner,sun8i-a83t-ehci", + "generic-ehci"; + reg = <0x01c1b000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI1>; + resets = <&ccu RST_BUS_EHCI1>; + phys = <&usbphy 2>; + phy-names = "usb"; + status = "disabled"; + }; + ccu: clock@1c20000 { compatible = "allwinner,sun8i-a83t-ccu"; reg = <0x01c20000 0x400>; @@ -195,7 +333,7 @@ , ; reg = <0x01c20800 0x400>; - clocks = <&ccu 45>, <&osc24M>, <&osc16Md512>; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc16Md512>; clock-names = "apb", "hosc", "losc"; gpio-controller; interrupt-controller; @@ -210,6 +348,15 @@ bias-pull-up; }; + mmc2_8bit_emmc_pins: mmc2-8bit-emmc-pins { + pins = "PC5", "PC6", "PC8", "PC9", + "PC10", "PC11", "PC12", "PC13", + "PC14", "PC15", "PC16"; + function = "mmc2"; + drive-strength = <30>; + bias-pull-up; + }; + spdif_tx_pin: spdif-tx-pin { pins = "PE18"; function = "spdif"; @@ -247,8 +394,8 @@ "allwinner,sun8i-h3-spdif"; reg = <0x01c21000 0x400>; interrupts = ; - clocks = <&ccu 44>, <&ccu 76>; - resets = <&ccu 32>; + clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>; + resets = <&ccu RST_BUS_SPDIF>; clock-names = "apb", "spdif"; dmas = <&dma 2>; dma-names = "tx"; @@ -263,8 +410,8 @@ interrupts = ; reg-shift = <2>; reg-io-width = <4>; - clocks = <&ccu 53>; - resets = <&ccu 40>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; status = "disabled"; }; @@ -279,6 +426,15 @@ interrupts = ; }; + r_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun8i-a83t-r-intc", + "allwinner,sun6i-a31-r-intc"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x01f00c00 0x400>; + interrupts = ; + }; + r_ccu: clock@1f01400 { compatible = "allwinner,sun8i-a83t-r-ccu"; reg = <0x01f01400 0x400>; @@ -300,6 +456,28 @@ #gpio-cells = <3>; interrupt-controller; #interrupt-cells = <3>; + + r_rsb_pins: r-rsb-pins { + pins = "PL0", "PL1"; + function = "s_rsb"; + drive-strength = <20>; + bias-pull-up; + }; + }; + + r_rsb: rsb@1f03400 { + compatible = "allwinner,sun8i-a83t-rsb", + "allwinner,sun8i-a23-rsb"; + reg = <0x01f03400 0x400>; + interrupts = ; + clocks = <&r_ccu CLK_APB0_RSB>; + clock-frequency = <3000000>; + resets = <&r_ccu RST_APB0_RSB>; + pinctrl-names = "default"; + pinctrl-0 = <&r_rsb_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; }; }; diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts index 6713d0f2b3f4d3f3f62231bf6a74bf35828ce8b0..b1502df7b50923a70d996847d1cd258d92cda73c 100644 --- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts +++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts @@ -56,8 +56,6 @@ aliases { serial0 = &uart0; - /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */ - ethernet0 = &emac; ethernet1 = &xr819; }; @@ -104,13 +102,6 @@ status = "okay"; }; -&emac { - phy-handle = <&int_mii_phy>; - phy-mode = "mii"; - allwinner,leds-active-low; - status = "okay"; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>; diff --git a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts index d756ff825116029557ec53f022f63e6ab2ed0f25..a337af1de32246b69807f4ee3b65e04e63231967 100644 --- a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts @@ -52,7 +52,6 @@ compatible = "sinovoip,bpi-m2-plus", "allwinner,sun8i-h3"; aliases { - ethernet0 = &emac; serial0 = &uart0; serial1 = &uart1; }; @@ -115,30 +114,12 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; - - allwinner,leds-active-low; - status = "okay"; -}; - &ir { pinctrl-names = "default"; pinctrl-0 = <&ir_pins_a>; status = "okay"; }; -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; - }; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts index e7fae65eb5d3dd88b478c4e4f81050c1790e5568..10da56e86ab800809e9f28b72bd9b94edf02a547 100644 --- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts +++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts @@ -100,6 +100,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -147,10 +151,19 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; +®_usb0_vbus { + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; +}; + &spdif { pinctrl-names = "default"; pinctrl-0 = <&spdif_tx_pins_a>; @@ -163,7 +176,14 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { - /* USB VBUS is on as long as VCC-IO is on */ + /* USB VBUS is always on except for the OTG port */ status = "okay"; + usb0_id_det-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */ + usb0_vbus-supply = <®_usb0_vbus>; }; diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts index 78f6c24952dd128249fd3010d212222832bb060a..8d2cc6e9a03faff3cc71965493e5c54c1359e9f3 100644 --- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts @@ -46,10 +46,3 @@ model = "FriendlyARM NanoPi NEO"; compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3"; }; - -&emac { - phy-handle = <&int_mii_phy>; - phy-mode = "mii"; - allwinner,leds-active-low; - status = "okay"; -}; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts index 17cdeae19c6f0f297d680c5c4f1c09e36071cfda..8ff71b1bb45b1c918d71e686ef4da4de7250306a 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts @@ -54,7 +54,6 @@ aliases { serial0 = &uart0; /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */ - ethernet0 = &emac; ethernet1 = &rtl8189; }; @@ -118,13 +117,6 @@ status = "okay"; }; -&emac { - phy-handle = <&int_mii_phy>; - phy-mode = "mii"; - allwinner,leds-active-low; - status = "okay"; -}; - &ir { pinctrl-names = "default"; pinctrl-0 = <&ir_pins_a>; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts index 6880268e8b87b0d7385e73dc95c23aaa8f25bd9a..5fea430e0eb1006120dd9b98dd904cdd7af14b67 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts @@ -52,7 +52,6 @@ compatible = "xunlong,orangepi-one", "allwinner,sun8i-h3"; aliases { - ethernet0 = &emac; serial0 = &uart0; }; @@ -98,13 +97,6 @@ status = "okay"; }; -&emac { - phy-handle = <&int_mii_phy>; - phy-mode = "mii"; - allwinner,leds-active-low; - status = "okay"; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts index a10281b455f50ccad1f26087ae14884600c19c90..8b93f5c781a70b565ed0012d2c29b35f04987dcd 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts @@ -53,11 +53,6 @@ }; }; -&emac { - /* LEDs changed to active high on the plus */ - /delete-property/ allwinner,leds-active-low; -}; - &mmc1 { pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins_a>; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts index 998b60f8d295e85fe09e184943ffafd45eb1da33..1a044b17d6c61e5cc391782c5e06aa3df7322548 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts @@ -52,7 +52,6 @@ compatible = "xunlong,orangepi-pc", "allwinner,sun8i-h3"; aliases { - ethernet0 = &emac; serial0 = &uart0; }; @@ -114,13 +113,6 @@ status = "okay"; }; -&emac { - phy-handle = <&int_mii_phy>; - phy-mode = "mii"; - allwinner,leds-active-low; - status = "okay"; -}; - &ir { pinctrl-names = "default"; pinctrl-0 = <&ir_pins_a>; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts index 331ed683ac62cb861e17971038774bda0209f461..828ae7a526d924955e666a4ad110f565aa931bf5 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts @@ -47,10 +47,6 @@ model = "Xunlong Orange Pi Plus / Plus 2"; compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3"; - aliases { - ethernet0 = &emac; - }; - reg_gmac_3v3: gmac-3v3 { compatible = "regulator-fixed"; regulator-name = "gmac-3v3"; @@ -78,24 +74,6 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; - - allwinner,leds-active-low; - status = "okay"; -}; - -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; - }; -}; - &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_8bit_pins>; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts index 80026f3caafc8928043baf01c3d0387301562292..97920b12a944526f3c5dd15de7435f5e30195a3c 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts @@ -61,19 +61,3 @@ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ }; }; - -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; - status = "okay"; -}; - -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; diff --git a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts new file mode 100644 index 0000000000000000000000000000000000000000..eaf09666720dcadfb2a008c590eaa4daf355ee04 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2017 Free Electrons + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a33.dtsi" + +#include + +/ { + model = "BananaPi M2 Magic"; + compatible = "sinovoip,bananapi-m2m", "allwinner,sun8i-a33"; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + serial0 = &uart0; + serial1 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "bpi-m2m:blue:usr"; + gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; + }; + + green { + label = "bpi-m2m:green:usr"; + gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; + }; + + red { + label = "bpi-m2m:red:power"; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; + + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL06 */ + }; +}; + +&codec { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc3>; +}; + +&cpu0_opp_table { + opp@1104000000 { + opp-hz = /bits/ 64 <1104000000>; + opp-microvolt = <1320000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1320000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; +}; + +&dai { + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +/* This is the i2c bus exposed on the DSI connector for the touch panel */ +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "disabled"; +}; + +/* This is the i2c bus exposed on the GPIO header */ +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "disabled"; +}; + +/* This is the i2c bus exposed on the CSI connector to control the sensor */ +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>; + vmmc-supply = <®_dcdc1>; + bus-width = <4>; + cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ + cd-inverted; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_a>; + vmmc-supply = <®_aldo1>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_dcdc1>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp22x: pmic@3a3 { + compatible = "x-powers,axp223"; + reg = <0x3a3>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + eldoin-supply = <®_dcdc1>; + x-powers,drive-vbus-en; + }; +}; + +#include "axp223.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-io"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-name = "vdd-dll"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-lcd"; +}; + +®_dc5ldo { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpus"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-3v0"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-sys"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +/* + * Our WiFi chip needs both DLDO1 and DLDO2 to be powered at the same + * time, with the two being in sync. Since this is not really + * supported right now, just use the two as always on, and we will fix + * it later. + */ +®_dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi0"; +}; + +®_dldo2 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi1"; +}; + +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&sound { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_a>, <&uart1_pins_cts_rts_a>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>; /* PH8 */ + usb0_vbus_power-supply = <&usb_power_supply>; + usb0_vbus-supply = <®_drivevbus>; + usb1_vbus-supply = <®_vcc5v0>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 6f2162608006770896df2adcc258a4ed2a3b63a9..11240a8313c266a33ec7ad1233aca2a976d4af3f 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -391,32 +391,6 @@ clocks = <&osc24M>; }; - emac: ethernet@1c30000 { - compatible = "allwinner,sun8i-h3-emac"; - syscon = <&syscon>; - reg = <0x01c30000 0x104>; - interrupts = ; - interrupt-names = "macirq"; - resets = <&ccu RST_BUS_EMAC>; - reset-names = "stmmaceth"; - clocks = <&ccu CLK_BUS_EMAC>; - clock-names = "stmmaceth"; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - mdio: mdio { - #address-cells = <1>; - #size-cells = <0>; - int_mii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - clocks = <&ccu CLK_BUS_EPHY>; - resets = <&ccu RST_BUS_EPHY>; - }; - }; - }; - spi0: spi@01c68000 { compatible = "allwinner,sun8i-h3-spi"; reg = <0x01c68000 0x1000>; diff --git a/arch/arm/boot/dts/tango4-smp8758.dtsi b/arch/arm/boot/dts/tango4-smp8758.dtsi index d2e65c46bcc7a56048e8892fc9cfc5d5f100f0ce..eca33d56869011b69878d33c115150f52e59bf92 100644 --- a/arch/arm/boot/dts/tango4-smp8758.dtsi +++ b/arch/arm/boot/dts/tango4-smp8758.dtsi @@ -13,7 +13,6 @@ reg = <0>; clocks = <&clkgen CPU_CLK>; clock-latency = <1>; - operating-points = <1215000 0 607500 0 405000 0 243000 0 135000 0>; }; cpu1: cpu@1 { diff --git a/arch/arm/boot/dts/tango4-vantage-1172.dts b/arch/arm/boot/dts/tango4-vantage-1172.dts index 86d8df98802fdf66a651adb04de5c4be49af3fcc..13bcc460bcb2adf2ab17775bc0aa2c01bc694aed 100644 --- a/arch/arm/boot/dts/tango4-vantage-1172.dts +++ b/arch/arm/boot/dts/tango4-vantage-1172.dts @@ -22,7 +22,7 @@ }; ð0 { - phy-connection-type = "rgmii"; + phy-connection-type = "rgmii-id"; phy-handle = <ð0_phy>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index 1444fbd543e724e367b0091669a7642724023ed1..5af4dd3219520d265f4046d84b9c8cb64c73a000 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts @@ -1122,6 +1122,16 @@ non-removable; }; + usb@7d000000 { + compatible = "nvidia,tegra114-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@7d000000 { + status = "okay"; + }; + usb@7d008000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 7bacb2954f586357bb689dbbd4c51895a4f5653d..61873d642a45b207ef33c885b76469f9d9ed084b 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts @@ -1722,7 +1722,7 @@ lanes { usb2-0 { - nvidia,function = "xusb"; + nvidia,function = "snps"; status = "okay"; }; @@ -1829,6 +1829,16 @@ }; }; + usb@7d000000 { + compatible = "nvidia,tegra124-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@7d000000 { + status = "okay"; + }; + /* mini-PCIe USB */ usb@7d004000 { status = "okay"; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 1b10b14a6abdff8af2442412c87738c0eca85d27..8baf00b89efb98d1693505aa3a8251f1e0a10ac8 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -87,6 +87,7 @@ clocks = <&tegra_car TEGRA124_CLK_HOST1X>; resets = <&tegra_car 28>; reset-names = "host1x"; + iommus = <&mc TEGRA_SWGROUP_HC>; #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index b4bfa5586c233a48b3aeba14b53c3187e245b753..bfa9421fcf94a0ea433c4f2ec2da08665a5193f1 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts @@ -452,7 +452,9 @@ }; usb@c5000000 { + compatible = "nvidia,tegra20-udc"; status = "okay"; + dr_mode = "peripheral"; }; usb-phy@c5000000 { diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts index 4f41b18d95476b7e2db95b3cd9148bf0d8e6626a..3e104ddeb220528c1ec984c428d4f64688e84b00 100644 --- a/arch/arm/boot/dts/tegra30-beaver.dts +++ b/arch/arm/boot/dts/tegra30-beaver.dts @@ -1927,6 +1927,16 @@ non-removable; }; + usb@7d000000 { + compatible = "nvidia,tegra30-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@7d000000 { + status = "okay"; + }; + usb@7d004000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/tps65217.dtsi b/arch/arm/boot/dts/tps65217.dtsi index 02de56b55823e78fd82fa6d4ad39d103a8e28fa1..399baaa0a2abe1d3e17bac5d8543f29d06fc6b42 100644 --- a/arch/arm/boot/dts/tps65217.dtsi +++ b/arch/arm/boot/dts/tps65217.dtsi @@ -18,11 +18,14 @@ charger { compatible = "ti,tps65217-charger"; + interrupts = <0>, <1>; + interrupt-names = "USB", "AC"; status = "disabled"; }; pwrbutton { compatible = "ti,tps65217-pwrbutton"; + interrupts = <2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/uniphier-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ld4-ref.dts index 4817ebb28eb2ef81ab2ae92888e003fac77557db..b3aaab354f3e0e8ff842db3549f865e7c1c60e10 100644 --- a/arch/arm/boot/dts/uniphier-ld4-ref.dts +++ b/arch/arm/boot/dts/uniphier-ld4-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld4.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld4.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD4 Reference Board"; @@ -64,3 +64,7 @@ &usb1 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-ld4.dtsi b/arch/arm/boot/dts/uniphier-ld4.dtsi index fb2fd9605b9de640c8caed33a0ecfeb7f7f57814..79183db5b386895781b21635407bce3fa7efb8ac 100644 --- a/arch/arm/boot/dts/uniphier-ld4.dtsi +++ b/arch/arm/boot/dts/uniphier-ld4.dtsi @@ -270,6 +270,13 @@ interrupt-controller; }; + aidet: aidet@61830000 { + compatible = "socionext,uniphier-ld4-aidet"; + reg = <0x61830000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + sysctrl@61840000 { compatible = "socionext,uniphier-ld4-sysctrl", "simple-mfd", "syscon"; @@ -285,7 +292,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5a"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ld6b-ref.dts index 96db4abc02c3eb1835e76db9a018680c2a4d0c7c..2188d114d79b06c9b9b1bfde5d8cee1bc82e02df 100644 --- a/arch/arm/boot/dts/uniphier-ld6b-ref.dts +++ b/arch/arm/boot/dts/uniphier-ld6b-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld6b.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld6b.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD6b Reference Board"; @@ -58,3 +58,7 @@ &i2c0 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-ld6b.dtsi b/arch/arm/boot/dts/uniphier-ld6b.dtsi index 8b9a79731bd33cf5f75ac03e626de878efed3542..9a7b25cc8233accb08c4720d66cfb792ebfb8bbb 100644 --- a/arch/arm/boot/dts/uniphier-ld6b.dtsi +++ b/arch/arm/boot/dts/uniphier-ld6b.dtsi @@ -12,7 +12,7 @@ * The D-chip (digital chip) is the same as the PXs2 die. * Reuse the PXs2 device tree with some properties overridden. */ -/include/ "uniphier-pxs2.dtsi" +#include "uniphier-pxs2.dtsi" / { compatible = "socionext,uniphier-ld6b"; diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi b/arch/arm/boot/dts/uniphier-pinctrl.dtsi index 246f35ffb638119fc81c9e159afe870fb7e72a48..be82cddc407245b82cfde6b02cbcc970576e6e0d 100644 --- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi +++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi @@ -4,51 +4,35 @@ * Copyright (C) 2015-2017 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ &pinctrl { + pinctrl_aout: aout_grp { + groups = "aout"; + function = "aout"; + }; + pinctrl_emmc: emmc_grp { groups = "emmc", "emmc_dat8"; function = "emmc"; }; + pinctrl_ether_mii: ether_mii_grp { + groups = "ether_mii"; + function = "ether_mii"; + }; + + pinctrl_ether_rgmii: ether_rgmii_grp { + groups = "ether_rgmii"; + function = "ether_rgmii"; + }; + + pinctrl_ether_rmii: ether_rmii_grp { + groups = "ether_rmii"; + function = "ether_rmii"; + }; + pinctrl_i2c0: i2c0_grp { groups = "i2c0"; function = "i2c0"; diff --git a/arch/arm/boot/dts/uniphier-pro4-ace.dts b/arch/arm/boot/dts/uniphier-pro4-ace.dts index 11690b57931cef20c2e34ef0ae328ada08c9d35b..089419cee273ea29341d9d0878afe5c0bf1bbffd 100644 --- a/arch/arm/boot/dts/uniphier-pro4-ace.dts +++ b/arch/arm/boot/dts/uniphier-pro4-ace.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pro4.dtsi" +#include "uniphier-pro4.dtsi" / { model = "UniPhier Pro4 Ace Board"; diff --git a/arch/arm/boot/dts/uniphier-pro4-ref.dts b/arch/arm/boot/dts/uniphier-pro4-ref.dts index 4cf539245f2e75c40c3cdeeb5ea24ea6a4182307..903df6348e77db51d2bcc86d2aa1d32a0cf3dece 100644 --- a/arch/arm/boot/dts/uniphier-pro4-ref.dts +++ b/arch/arm/boot/dts/uniphier-pro4-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-pro4.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-pro4.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier Pro4 Reference Board"; @@ -66,3 +66,7 @@ &usb3 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-pro4-sanji.dts b/arch/arm/boot/dts/uniphier-pro4-sanji.dts index 2763cebcd76ace8f0c8e4570c7c0d5f15b73b65a..adef212b45b2b01c21cf4098fb9762924c72d198 100644 --- a/arch/arm/boot/dts/uniphier-pro4-sanji.dts +++ b/arch/arm/boot/dts/uniphier-pro4-sanji.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pro4.dtsi" +#include "uniphier-pro4.dtsi" / { model = "UniPhier Pro4 Sanji Board"; diff --git a/arch/arm/boot/dts/uniphier-pro4.dtsi b/arch/arm/boot/dts/uniphier-pro4.dtsi index 37400becf4baaafa1e39bf4767de74daa540f5d2..b3dbbd9b6e3955f3330cb3cb4bb5d71c617f4f9a 100644 --- a/arch/arm/boot/dts/uniphier-pro4.dtsi +++ b/arch/arm/boot/dts/uniphier-pro4.dtsi @@ -268,6 +268,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pro4-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + timer@60000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x60000200 0x20>; @@ -305,7 +312,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5a"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi b/arch/arm/boot/dts/uniphier-pro5.dtsi index 9577769a0add6cfe9fd39e68fb1110a90602e31f..b026bcd42a069351b1786959be0af090eaef21d3 100644 --- a/arch/arm/boot/dts/uniphier-pro5.dtsi +++ b/arch/arm/boot/dts/uniphier-pro5.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -328,7 +292,7 @@ sdctrl@59810000 { compatible = "socionext,uniphier-pro5-sdctrl", "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; + reg = <0x59810000 0x400>; sd_clk: clock { compatible = "socionext,uniphier-pro5-sd-clock"; @@ -367,6 +331,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pro5-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + timer@60000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x60000200 0x20>; @@ -404,7 +375,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts index 81560f75bfa79511c3957405698db2ebc9d6bc35..7dfae2667f5066baa2b5e4424157a85411399166 100644 --- a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts +++ b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pxs2.dtsi" +#include "uniphier-pxs2.dtsi" / { model = "UniPhier PXs2 Gentil Board"; diff --git a/arch/arm/boot/dts/uniphier-pxs2-vodka.dts b/arch/arm/boot/dts/uniphier-pxs2-vodka.dts index dc2d0579c666126ce61a14fcf6b602d80bd19256..0cf615463a82fcbc20941410bb99cfa55b614caf 100644 --- a/arch/arm/boot/dts/uniphier-pxs2-vodka.dts +++ b/arch/arm/boot/dts/uniphier-pxs2-vodka.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pxs2.dtsi" +#include "uniphier-pxs2.dtsi" / { model = "UniPhier PXs2 Vodka Board"; diff --git a/arch/arm/boot/dts/uniphier-pxs2.dtsi b/arch/arm/boot/dts/uniphier-pxs2.dtsi index bace751d40239e9a477d5af51f11161664c7df06..90b020c950837d5d0c9d2a43d74d4a2c208b7463 100644 --- a/arch/arm/boot/dts/uniphier-pxs2.dtsi +++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi @@ -276,7 +276,7 @@ sdctrl@59810000 { compatible = "socionext,uniphier-pxs2-sdctrl", "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; + reg = <0x59810000 0x400>; sd_clk: clock { compatible = "socionext,uniphier-pxs2-sd-clock"; @@ -315,6 +315,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pxs2-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + timer@60000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x60000200 0x20>; @@ -352,7 +359,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-sld3-ref.dts b/arch/arm/boot/dts/uniphier-sld3-ref.dts deleted file mode 100644 index 70cda39a3dd2d41962160a47f6266d2e9e4330c1..0000000000000000000000000000000000000000 --- a/arch/arm/boot/dts/uniphier-sld3-ref.dts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Device Tree Source for UniPhier sLD3 Reference Board - * - * Copyright (C) 2015-2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) - */ - -/dts-v1/; -/include/ "uniphier-sld3.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" - -/ { - model = "UniPhier sLD3 Reference Board"; - compatible = "socionext,uniphier-sld3-ref", "socionext,uniphier-sld3"; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - aliases { - serial0 = &serial0; - serial1 = &serial1; - serial2 = &serial2; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2c2 = &i2c2; - i2c3 = &i2c3; - i2c4 = &i2c4; - }; - - memory@8000000 { - device_type = "memory"; - reg = <0x80000000 0x20000000 - 0xc0000000 0x20000000>; - }; -}; - -ðsc { - interrupts = <0 49 4>; -}; - -&serial0 { - status = "okay"; -}; - -&serial1 { - status = "okay"; -}; - -&serial2 { - status = "okay"; -}; - -&i2c0 { - status = "okay"; -}; - -&usb0 { - status = "okay"; -}; - -&usb1 { - status = "okay"; -}; - -&usb2 { - status = "okay"; -}; - -&usb3 { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/uniphier-sld3.dtsi b/arch/arm/boot/dts/uniphier-sld3.dtsi deleted file mode 100644 index 408287936613c78684a719a9af8596c78338c4d6..0000000000000000000000000000000000000000 --- a/arch/arm/boot/dts/uniphier-sld3.dtsi +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Device Tree Source for UniPhier sLD3 SoC - * - * Copyright (C) 2015-2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) - */ - -/ { - compatible = "socionext,uniphier-sld3"; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a9"; - reg = <0>; - enable-method = "psci"; - next-level-cache = <&l2>; - }; - - cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a9"; - reg = <1>; - enable-method = "psci"; - next-level-cache = <&l2>; - }; - }; - - psci { - compatible = "arm,psci-0.2"; - method = "smc"; - }; - - clocks { - refclk: ref { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <24576000>; - }; - - arm_timer_clk: arm_timer_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <50000000>; - }; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - interrupt-parent = <&intc>; - - timer@20000200 { - compatible = "arm,cortex-a9-global-timer"; - reg = <0x20000200 0x20>; - interrupts = <1 11 0x304>; - clocks = <&arm_timer_clk>; - }; - - timer@20000600 { - compatible = "arm,cortex-a9-twd-timer"; - reg = <0x20000600 0x20>; - interrupts = <1 13 0x304>; - clocks = <&arm_timer_clk>; - }; - - intc: interrupt-controller@20001000 { - compatible = "arm,cortex-a9-gic"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x20001000 0x1000>, - <0x20000100 0x100>; - }; - - l2: l2-cache@500c0000 { - compatible = "socionext,uniphier-system-cache"; - reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, - <0x506c0000 0x400>; - interrupts = <0 174 4>, <0 175 4>; - cache-unified; - cache-size = <(512 * 1024)>; - cache-sets = <256>; - cache-line-size = <128>; - cache-level = <2>; - }; - - serial0: serial@54006800 { - compatible = "socionext,uniphier-uart"; - status = "disabled"; - reg = <0x54006800 0x40>; - interrupts = <0 33 4>; - clocks = <&sys_clk 0>; - }; - - serial1: serial@54006900 { - compatible = "socionext,uniphier-uart"; - status = "disabled"; - reg = <0x54006900 0x40>; - interrupts = <0 35 4>; - clocks = <&sys_clk 0>; - }; - - serial2: serial@54006a00 { - compatible = "socionext,uniphier-uart"; - status = "disabled"; - reg = <0x54006a00 0x40>; - interrupts = <0 37 4>; - clocks = <&sys_clk 0>; - }; - - i2c0: i2c@58400000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58400000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 41 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - i2c1: i2c@58480000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58480000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 42 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - i2c2: i2c@58500000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58500000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 43 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - i2c3: i2c@58580000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58580000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 44 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - /* chip-internal connection for DMD */ - i2c4: i2c@58600000 { - compatible = "socionext,uniphier-i2c"; - reg = <0x58600000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 45 1>; - clocks = <&sys_clk 1>; - clock-frequency = <400000>; - }; - - system_bus: system-bus@58c00000 { - compatible = "socionext,uniphier-system-bus"; - status = "disabled"; - reg = <0x58c00000 0x400>; - #address-cells = <2>; - #size-cells = <1>; - }; - - smpctrl@59801000 { - compatible = "socionext,uniphier-smpctrl"; - reg = <0x59801000 0x400>; - }; - - mioctrl@59810000 { - compatible = "socionext,uniphier-sld3-mioctrl", - "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; - - mio_clk: clock { - compatible = "socionext,uniphier-sld3-mio-clock"; - #clock-cells = <1>; - }; - - mio_rst: reset { - compatible = "socionext,uniphier-sld3-mio-reset"; - #reset-cells = <1>; - }; - }; - - usb0: usb@5a800100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a800100 0x100>; - interrupts = <0 80 4>; - clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, - <&mio_rst 12>; - }; - - usb1: usb@5a810100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a810100 0x100>; - interrupts = <0 81 4>; - clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, - <&mio_rst 13>; - }; - - usb2: usb@5a820100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a820100 0x100>; - interrupts = <0 82 4>; - clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>, - <&mio_rst 14>; - }; - - usb3: usb@5a830100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a830100 0x100>; - interrupts = <0 83 4>; - clocks = <&mio_clk 7>, <&mio_clk 11>, <&mio_clk 15>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 11>, - <&mio_rst 15>; - }; - - sysctrl@f1840000 { - compatible = "socionext,uniphier-sld3-sysctrl", - "simple-mfd", "syscon"; - reg = <0xf1840000 0x10000>; - - sys_clk: clock { - compatible = "socionext,uniphier-sld3-clock"; - #clock-cells = <1>; - }; - - sys_rst: reset { - compatible = "socionext,uniphier-sld3-reset"; - #reset-cells = <1>; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/uniphier-sld8-ref.dts b/arch/arm/boot/dts/uniphier-sld8-ref.dts index 4536d5b7129796f188dd95c0f68a28aca3cb2b5f..5accd3cc76e4aaee7471f0ce7542bfc7eb6d1ac9 100644 --- a/arch/arm/boot/dts/uniphier-sld8-ref.dts +++ b/arch/arm/boot/dts/uniphier-sld8-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-sld8.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-sld8.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier sLD8 Reference Board"; @@ -68,3 +68,7 @@ &usb2 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-sld8.dtsi b/arch/arm/boot/dts/uniphier-sld8.dtsi index 9fb9167f2db43d9e8a99adc679003847d38646e5..b0839033297169272ed3688cb352385920a41ea1 100644 --- a/arch/arm/boot/dts/uniphier-sld8.dtsi +++ b/arch/arm/boot/dts/uniphier-sld8.dtsi @@ -270,6 +270,13 @@ interrupt-controller; }; + aidet: aidet@61830000 { + compatible = "socionext,uniphier-sld8-aidet"; + reg = <0x61830000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + sysctrl@61840000 { compatible = "socionext,uniphier-sld8-sysctrl", "simple-mfd", "syscon"; @@ -285,7 +292,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5a"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index 06e2331f666d45fb2a2432ac1ef5401c3c50e37d..9abe26028c8b835b987892445157d148f0b24c57 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -39,7 +39,7 @@ clock-names = "apb_pclk"; }; - pci-controller@10001000 { + pci@10001000 { compatible = "arm,versatile-pci"; device_type = "pci"; reg = <0x10001000 0x1000 diff --git a/arch/arm/boot/dts/zx296702-ad1.dts b/arch/arm/boot/dts/zx296702-ad1.dts index 081f980cfbe628426e1d2c6b5efb8a272fe766e8..b0183c3a1d7c4627b008278e6290fbe908d0c6df 100644 --- a/arch/arm/boot/dts/zx296702-ad1.dts +++ b/arch/arm/boot/dts/zx296702-ad1.dts @@ -18,7 +18,6 @@ }; &mmc0 { - num-slots = <1>; supports-highspeed; non-removable; disable-wp; @@ -31,7 +30,6 @@ }; &mmc1 { - num-slots = <1>; supports-highspeed; non-removable; disable-wp; diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index f3ac9bfe580ea27a1e82a3d360c05f89490c3161..0f79fe1ccd9d99e5fae27d275e94ae3c214ef77a 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -42,6 +42,14 @@ }; }; + fpga_full: fpga-full { + compatible = "fpga-region"; + fpga-mgr = <&devcfg>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + }; + pmu@f8891000 { compatible = "arm,cortex-a9-pmu"; interrupts = <0 5 4>, <0 6 4>; diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts index 64a6390fc5017bdd111a88947e736fd1364b85ef..0144acfa97936e1c829c539d6c148df3d423ce3d 100644 --- a/arch/arm/boot/dts/zynq-parallella.dts +++ b/arch/arm/boot/dts/zynq-parallella.dts @@ -34,7 +34,7 @@ }; chosen { - bootargs = "earlycon root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"; + bootargs = "root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"; stdout-path = "serial0:115200n8"; }; }; @@ -54,6 +54,7 @@ compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22"; reg = <0>; + device_type = "ethernet-phy"; marvell,reg-init = <0x3 0x10 0xff00 0x1e>, <0x3 0x11 0xfff0 0xa>; }; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index 0cdad2cc8b78678c63b1ca06a5dec22f76527ae0..34e8277fce0d36a875cccb1278a9c016236b53d0 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq ZC702 Development Board"; @@ -30,7 +30,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -97,6 +97,7 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; + device_type = "ethernet-phy"; }; }; @@ -131,6 +132,21 @@ }; }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + adv7511: hdmi-tx@39 { + compatible = "adi,adv7511"; + reg = <0x39>; + adi,input-depth = <8>; + adi,input-colorspace = "yuv422"; + adi,input-clock = "1x"; + adi,input-style = <3>; + adi,input-justification = "right"; + }; + }; + i2c@2 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts index ad4bb06dba251d15bd282b9d7ee7a04185c7d201..7ebc8c5ae39dce63ce99add3fea8e4eea121d924 100644 --- a/arch/arm/boot/dts/zynq-zc706.dts +++ b/arch/arm/boot/dts/zynq-zc706.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq ZC706 Development Board"; @@ -30,7 +30,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -53,6 +53,7 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; + device_type = "ethernet-phy"; }; }; @@ -87,6 +88,21 @@ }; }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + adv7511: hdmi-tx@39 { + compatible = "adi,adv7511"; + reg = <0x39>; + adi,input-depth = <8>; + adi,input-colorspace = "yuv422"; + adi,input-clock = "1x"; + adi,input-style = <3>; + adi,input-justification = "evenly"; + }; + }; + i2c@2 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts index 325379f7983cd386af42aeafb758a1c22895d622..5e44dc12fd60a5d00a622d079e6776d100de05dd 100644 --- a/arch/arm/boot/dts/zynq-zed.dts +++ b/arch/arm/boot/dts/zynq-zed.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq Zed Development Board"; @@ -29,7 +29,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -50,6 +50,7 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; + device_type = "ethernet-phy"; }; }; diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts index 590ec24b8749649d1d4e6660c887e2d3448161af..e40cafc5ee5b638c7371709d51241bc5d8a1c5fe 100644 --- a/arch/arm/boot/dts/zynq-zybo.dts +++ b/arch/arm/boot/dts/zynq-zybo.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq ZYBO Development Board"; @@ -29,7 +29,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -51,6 +51,7 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; + device_type = "ethernet-phy"; }; }; diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig index cfc2465e8b7791dde460c45beb8a019ee8b960c2..d23b9d56a88b2bf91b9183c29b98b815a080aa21 100644 --- a/arch/arm/configs/aspeed_g4_defconfig +++ b/arch/arm/configs/aspeed_g4_defconfig @@ -24,6 +24,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_ASPEED=y CONFIG_MACH_ASPEED_G4=y +CONFIG_VMSPLIT_2G=y CONFIG_AEABI=y # CONFIG_CPU_SW_DOMAIN_PAN is not set # CONFIG_COMPACTION is not set @@ -64,6 +65,7 @@ CONFIG_MTD_UBI_FASTMAP=y CONFIG_MTD_UBI_BLOCK=y CONFIG_BLK_DEV_RAM=y CONFIG_ASPEED_LPC_CTRL=y +CONFIG_ASPEED_LPC_SNOOP=y CONFIG_EEPROM_AT24=y CONFIG_NETDEVICES=y CONFIG_NETCONSOLE=y @@ -104,6 +106,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_RUNTIME_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_ASPEED_VUART=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_ASPEED_BT_IPMI_BMC=y @@ -114,6 +117,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_ASPEED=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ASPEED=y @@ -166,7 +170,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y -CONFIG_LOCKUP_DETECTOR=y CONFIG_WQ_WATCHDOG=y CONFIG_PANIC_TIMEOUT=-1 # CONFIG_SCHED_DEBUG is not set diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig index 3c20d93de389f3b249dd2e71363ef439a595ab92..c0ad7b82086bd5b5676d8ce7b332d603831a0cd1 100644 --- a/arch/arm/configs/aspeed_g5_defconfig +++ b/arch/arm/configs/aspeed_g5_defconfig @@ -67,6 +67,7 @@ CONFIG_MTD_UBI_FASTMAP=y CONFIG_MTD_UBI_BLOCK=y CONFIG_BLK_DEV_RAM=y CONFIG_ASPEED_LPC_CTRL=y +CONFIG_ASPEED_LPC_SNOOP=y CONFIG_EEPROM_AT24=y CONFIG_NETDEVICES=y CONFIG_NETCONSOLE=y @@ -107,6 +108,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_RUNTIME_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_ASPEED_VUART=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_ASPEED_BT_IPMI_BMC=y @@ -117,6 +119,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_ASPEED=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ASPEED=y @@ -169,7 +172,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y -CONFIG_LOCKUP_DETECTOR=y CONFIG_WQ_WATCHDOG=y CONFIG_PANIC_TIMEOUT=-1 # CONFIG_SCHED_DEBUG is not set diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 3ee9d78c412aa378b8c41705294222b2a08c479e..43dab4890ad37cabb06422a69dadc992bedfefec 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -55,6 +55,7 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=32 CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_CONSTANTS=y @@ -62,9 +63,15 @@ CONFIG_SCSI_SCAN_ASYNC=y CONFIG_NETDEVICES=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y +CONFIG_BRCMFMAC=m CONFIG_ZD1211RW=y CONFIG_INPUT_EVDEV=y # CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_TTY_PRINTK=y diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index 06e2e2a1a9be930faeda2f1a14f2ee72c2c15409..27d9720f7207b89728cf908cea4441adddf2aaad 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -143,6 +143,8 @@ CONFIG_VIDEO_ADV7343=m CONFIG_DRM=m CONFIG_DRM_TILCDC=m CONFIG_DRM_DUMB_VGA_DAC=m +CONFIG_DRM_TINYDRM=m +CONFIG_TINYDRM_ST7586=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_DA8XX=y diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 25325ed9319edfcfd05188e73438f54aafbd9265..8c2a2619971b1e45326392cfdf31a0a3845790ed 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -3,7 +3,6 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y -CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y @@ -48,7 +47,43 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_LEDS=y +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m CONFIG_CFG80211=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y +CONFIG_NFC=y +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=y +CONFIG_NFC_NCI_SPI=m +CONFIG_NFC_NCI_UART=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y +CONFIG_NFC_S3FWRN5_I2C=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_DMA_CMA=y @@ -65,7 +100,9 @@ CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=m CONFIG_NETDEVICES=y CONFIG_SMSC911X=y +CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=m CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y @@ -189,7 +226,25 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_EXYNOS=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_EXYNOS=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_UAS=m CONFIG_USB_DWC3=y CONFIG_USB_DWC2=y CONFIG_USB_HSIC_USB3503=y @@ -209,7 +264,6 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_MAX77693=y CONFIG_LEDS_MAX8997=y -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MAX8997=y @@ -253,18 +307,30 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y -CONFIG_LOCKUP_DETECTOR=y -CONFIG_DEBUG_RT_MUTEXES=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_PROVE_LOCKING=y +CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_USER=y +CONFIG_CRYPTO_RSA=m +CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_SHA3=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m @@ -276,6 +342,7 @@ CONFIG_CRYPTO_SHA1_ARM_NEON=m CONFIG_CRYPTO_SHA256_ARM=m CONFIG_CRYPTO_SHA512_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRC_CCITT=y CONFIG_FONTS=y CONFIG_FONT_7x14=y diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index 23660f3d0f7fc284610445abb5d799b40e2cb0e9..484e51fbd4a6320b23df4b5978b6fba7cdbfa09e 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -27,7 +27,6 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug" CONFIG_KEXEC=y CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEBUG=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_USERSPACE=m CONFIG_CPU_FREQ_GOV_ONDEMAND=m diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig index d2d75fa664a64338bc6bf0af3c3c65e3de0926f4..2a63fa10c813042bf2b98261964c7b6cd9f03790 100644 --- a/arch/arm/configs/gemini_defconfig +++ b/arch/arm/configs/gemini_defconfig @@ -32,6 +32,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_ATA=y +CONFIG_PATA_FTIDE010=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set @@ -55,8 +56,8 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_GEMINI=y CONFIG_DMADEVICES=y +CONFIG_AMBA_PL08X=y # CONFIG_DNOTIFY is not set CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index e74de69caeabb675908cb1672c8843cc939fd8d9..32acac9ab81aad5be59676e09aa4c422cb598d6e 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -51,6 +51,7 @@ CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y CONFIG_HIGHMEM=y CONFIG_CMA=y +CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200" CONFIG_KEXEC=y CONFIG_CPU_FREQ=y @@ -186,6 +187,7 @@ CONFIG_SERIAL_FSL_LPUART=y CONFIG_SERIAL_FSL_LPUART_CONSOLE=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y CONFIG_I2C_MUX_GPIO=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_I2C_ALGOPCF=m @@ -193,12 +195,14 @@ CONFIG_I2C_ALGOPCA=m CONFIG_I2C_GPIO=y CONFIG_I2C_IMX=y CONFIG_SPI=y +CONFIG_SPI_GPIO=y CONFIG_SPI_IMX=y CONFIG_SPI_FSL_DSPI=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_MC9S08DZ60=y CONFIG_GPIO_PCA953X=y CONFIG_GPIO_STMPE=y +CONFIG_GPIO_74X164=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_IMX=y CONFIG_POWER_RESET_SYSCON=y @@ -226,15 +230,21 @@ CONFIG_REGULATOR_MC13892=y CONFIG_REGULATOR_PFUZE100=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_RC_DEVICES=y CONFIG_IR_GPIO_CIR=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_MUX=y CONFIG_SOC_CAMERA=y CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_CODA=y +CONFIG_VIDEO_CODA=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_ADV7180=m +CONFIG_VIDEO_OV5640=m CONFIG_SOC_CAMERA_OV2640=y CONFIG_IMX_IPUV3_CORE=y CONFIG_DRM=y @@ -344,6 +354,9 @@ CONFIG_FSL_EDMA=y CONFIG_IMX_SDMA=y CONFIG_MXS_DMA=y CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_IMX_MEDIA=y +CONFIG_COMMON_CLK_PWM=y CONFIG_IIO=y CONFIG_IMX7D_ADC=y CONFIG_VF610_ADC=y diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index c8378da71913b577d6e68e807b5ff19d526a1b26..8c3c99cd6de950dc79efc91257b1c196dd62c933 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -81,12 +81,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 1331f6dc456adc6b5b2edc52810adb2434b29fb2..f907869e0ddcdf348da68b2d5f89f6d139003040 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig @@ -112,6 +112,9 @@ CONFIG_IP_NF_ARP_MANGLE=y CONFIG_IP6_NF_IPTABLES=m CONFIG_IP_SCTP=y CONFIG_VLAN_8021Q=y +CONFIG_CAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -156,6 +159,8 @@ CONFIG_POWER_RESET_KEYSTONE=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_DAVINCI_WATCHDOG=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y @@ -164,6 +169,8 @@ CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y CONFIG_NOP_USB_XCEIV=y CONFIG_KEYSTONE_USB_PHY=y +CONFIG_MMC=y +CONFIG_MMC_OMAP_HS=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y @@ -174,12 +181,18 @@ CONFIG_LEDS_TRIGGER_BACKLIGHT=y CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_DMADEVICES=y CONFIG_TI_EDMA=y +CONFIG_MAILBOX=y +CONFIG_TI_MESSAGE_MANAGER=y CONFIG_SOC_TI=y CONFIG_KEYSTONE_NAVIGATOR_QMSS=y CONFIG_KEYSTONE_NAVIGATOR_DMA=y +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_MEMORY=y CONFIG_TI_AEMIF=y CONFIG_KEYSTONE_IRQ=y +CONFIG_RESET_TI_SCI=m +CONFIG_RESET_TI_SYSCON=m +CONFIG_TI_SCI_PROTOCOL=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_FANOTIFY=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 4d19c1b4b8e7c1e8808695d91cdebbaea8772e19..0cacdbf84a7170083c8900f0f83fb680ba861b08 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -104,13 +104,11 @@ CONFIG_ARCH_TEGRA_2x_SOC=y CONFIG_ARCH_TEGRA_3x_SOC=y CONFIG_ARCH_TEGRA_114_SOC=y CONFIG_ARCH_TEGRA_124_SOC=y -CONFIG_TEGRA_EMC_SCALING_ENABLE=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_U8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_ARCH_VEXPRESS=y -CONFIG_ARCH_VEXPRESS_CA9X4=y CONFIG_ARCH_VEXPRESS_TC2_PM=y CONFIG_ARCH_WM8850=y CONFIG_ARCH_ZYNQ=y @@ -270,6 +268,7 @@ CONFIG_ICPLUS_PHY=y CONFIG_REALTEK_PHY=y CONFIG_MICREL_PHY=y CONFIG_FIXED_PHY=y +CONFIG_ROCKCHIP_PHY=y CONFIG_USB_PEGASUS=y CONFIG_USB_RTL8152=m CONFIG_USB_USBNET=y @@ -330,6 +329,7 @@ CONFIG_SERIAL_IMX_CONSOLE=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=20 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_VT8500=y @@ -455,6 +455,7 @@ CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_INA2XX=m CONFIG_CPU_THERMAL=y +CONFIG_BRCMSTB_THERMAL=m CONFIG_ROCKCHIP_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_ARMADA_THERMAL=y @@ -584,6 +585,7 @@ CONFIG_VIDEO_ADV7180=m CONFIG_VIDEO_ML86V7667=m CONFIG_DRM=y CONFIG_DRM_I2C_ADV7511=m +CONFIG_DRM_I2C_ADV7511_AUDIO=y # CONFIG_DRM_I2C_CH7006 is not set # CONFIG_DRM_I2C_SIL164 is not set CONFIG_DRM_DUMB_VGA_DAC=m @@ -603,7 +605,6 @@ CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_DRM_ATMEL_HLCDC=m CONFIG_DRM_RCAR_DU=m -CONFIG_DRM_RCAR_HDMI=y CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_SUN4I=m CONFIG_DRM_TEGRA=y @@ -650,9 +651,11 @@ CONFIG_SND_SOC_SMDK_WM8994_PCM=m CONFIG_SND_SOC_SNOW=m CONFIG_SND_SOC_SH4_FSI=m CONFIG_SND_SOC_RCAR=m -CONFIG_SND_SOC_RSRC_CARD=m +CONFIG_SND_SIMPLE_SCU_CARD=m CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SOC_TEGRA=m +CONFIG_SND_SOC_TEGRA20_I2S=m +CONFIG_SND_SOC_TEGRA30_I2S=m CONFIG_SND_SOC_TEGRA_RT5640=m CONFIG_SND_SOC_TEGRA_WM8753=m CONFIG_SND_SOC_TEGRA_WM8903=m @@ -695,7 +698,6 @@ CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_AB8500_USB=y CONFIG_KEYSTONE_USB_PHY=y -CONFIG_OMAP_USB3=y CONFIG_USB_GPIO_VBUS=y CONFIG_USB_ISP1301=y CONFIG_USB_MSM_OTG=m @@ -711,7 +713,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y CONFIG_MMC_SDHCI_OF_AT91=y -CONFIG_MMC_SDHCI_OF_ESDHC=m +CONFIG_MMC_SDHCI_OF_ESDHC=y CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_MMC_SDHCI_DOVE=y CONFIG_MMC_SDHCI_TEGRA=y @@ -728,7 +730,6 @@ CONFIG_MMC_SDHCI_MSM=y CONFIG_MMC_MVSDIO=y CONFIG_MMC_SDHI=y CONFIG_MMC_DW=y -CONFIG_MMC_DW_IDMAC=y CONFIG_MMC_DW_PLTFM=y CONFIG_MMC_DW_EXYNOS=y CONFIG_MMC_DW_ROCKCHIP=y @@ -825,7 +826,6 @@ CONFIG_BCMA_DRIVER_GPIO=y CONFIG_QCOM_GSBI=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y -CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y CONFIG_QCOM_SMP2P=y CONFIG_QCOM_SMSM=y @@ -837,7 +837,6 @@ CONFIG_CHROME_PLATFORMS=y CONFIG_STAGING_BOARD=y CONFIG_CROS_EC_CHARDEV=m CONFIG_COMMON_CLK_MAX77686=y -CONFIG_COMMON_CLK_MAX77802=m CONFIG_COMMON_CLK_RK808=m CONFIG_COMMON_CLK_S2MPS11=m CONFIG_APQ_MMCC_8084=y @@ -933,7 +932,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOCKUP_DETECTOR=y -CONFIG_CRYPTO_DEV_TEGRA_AES=y CONFIG_CPUFREQ_DT=y CONFIG_KEYSTONE_IRQ=y CONFIG_HW_RANDOM=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index a120ae81626003378ebab8afabe4c8358c789d3b..7b97200c1d64cee6937fe60d51fce8cbddd30ddc 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -170,6 +170,7 @@ CONFIG_TI_CPTS=y # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_AT803X_PHY=y CONFIG_DP83848_PHY=y +CONFIG_DP83867_PHY=y CONFIG_MICREL_PHY=y CONFIG_SMSC_PHY=y CONFIG_PPP=m @@ -250,6 +251,7 @@ CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_PCA953X=m CONFIG_GPIO_PCF857X=y +CONFIG_GPIO_LP87565=y CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TWL4030=y CONFIG_W1=m @@ -284,6 +286,7 @@ CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65217=y CONFIG_MFD_TI_LP873X=y +CONFIG_MFD_TI_LP87565=y CONFIG_MFD_TPS65218=y CONFIG_MFD_TPS65910=y CONFIG_TWL6040_CORE=y @@ -292,6 +295,7 @@ CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_LM363X=m CONFIG_REGULATOR_LP872X=y CONFIG_REGULATOR_LP873X=y +CONFIG_REGULATOR_LP87565=y CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_TI_ABB=y @@ -304,7 +308,7 @@ CONFIG_REGULATOR_TPS65910=y CONFIG_REGULATOR_TWL4030=y CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=m CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_LIRC=m diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 64e3a2a8cedec353203694d6f9f74b4fa09f962f..d5e1370ec303d5440c4572262f6918d4a047a170 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -471,7 +471,7 @@ CONFIG_LCD_PLATFORM=m CONFIG_LCD_TOSA=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_TOSA=m -CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y CONFIG_SOUND=m diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index b02039c712c39e2eaf8c4977a2efd13676edfd74..879159e4ab58c9cecc9a6ada8b2a3cf6ce2b90ca 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -199,7 +199,6 @@ CONFIG_QCOM_WCNSS_PIL=y CONFIG_QCOM_GSBI=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y -CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y CONFIG_QCOM_SMP2P=y CONFIG_QCOM_SMSM=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 3c66a422fb4df5678ac362a1c944a070403697d2..7b4fc01431483f217a97e69a93987e86ecc67c4f 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -27,6 +27,7 @@ CONFIG_ARCH_SH73A0=y CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_ERRATA_754322=y CONFIG_PCI=y +CONFIG_PCI_MSI=y CONFIG_PCI_RCAR_GEN2=y CONFIG_PCIE_RCAR=y CONFIG_SMP=y @@ -83,14 +84,14 @@ CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set CONFIG_SH_ETH=y +CONFIG_RAVB=y # CONFIG_NET_VENDOR_SEEQ is not set CONFIG_SMSC911X=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_SMSC_PHY=y CONFIG_MICREL_PHY=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_SMSC_PHY=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set @@ -105,6 +106,7 @@ CONFIG_SERIAL_8250_EM=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=20 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_DEMUX_PINCTRL=y @@ -121,9 +123,9 @@ CONFIG_SPI_SH_HSPI=y CONFIG_GPIO_EM=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_PCF857X=y -CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_RMOBILE=y +CONFIG_POWER_SUPPLY=y # CONFIG_HWMON is not set CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y @@ -153,10 +155,11 @@ CONFIG_VIDEO_ADV7180=y CONFIG_VIDEO_ADV7604=y CONFIG_VIDEO_ML86V7667=y CONFIG_DRM=y -CONFIG_DRM_I2C_ADV7511=y CONFIG_DRM_RCAR_DU=y -CONFIG_DRM_RCAR_HDMI=y CONFIG_DRM_RCAR_LVDS=y +CONFIG_DRM_DUMB_VGA_DAC=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_FB_SH_MOBILE_LCDC=y CONFIG_FB_SH_MOBILE_MERAM=y # CONFIG_LCD_CLASS_DEVICE is not set @@ -169,12 +172,12 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_SOC_SH4_FSI=y CONFIG_SND_SOC_RCAR=y -CONFIG_SND_SOC_RSRC_CARD=y CONFIG_SND_SOC_AK4642=y CONFIG_SND_SOC_WM8978=y +CONFIG_SND_SIMPLE_SCU_CARD=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_RCAR=y +CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_R8A66597_HCD=y @@ -190,6 +193,7 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RS5C372=y +CONFIG_RTC_DRV_BQ32K=y CONFIG_RTC_DRV_S35390A=y CONFIG_RTC_DRV_RX8581=y CONFIG_RTC_DRV_DA9063=y diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 0ec1d1ec130fabcfbc106b3e0f2a8c32d4cea546..5caaf971fb500c8265bfd75350578cf3071ca90b 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -1,4 +1,3 @@ -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_CGROUPS=y @@ -56,7 +55,6 @@ CONFIG_STMMAC_ETH=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_SUN4I_LRADC=y # CONFIG_INPUT_MOUSE is not set @@ -71,7 +69,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=8 CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MV64XXX=y CONFIG_I2C_SUN6I_P2WI=y @@ -80,14 +77,14 @@ CONFIG_SPI_SUN4I=y CONFIG_SPI_SUN6I=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY=y +CONFIG_CHARGER_AXP20X=y +CONFIG_BATTERY_AXP20X=y CONFIG_AXP20X_POWER=y CONFIG_THERMAL=y -CONFIG_THERMAL_OF=y CONFIG_CPU_THERMAL=y CONFIG_WATCHDOG=y CONFIG_SUNXI_WATCHDOG=y CONFIG_MFD_AC100=y -CONFIG_MFD_AXP20X=y CONFIG_MFD_AXP20X_I2C=y CONFIG_MFD_AXP20X_RSB=y CONFIG_REGULATOR=y @@ -95,16 +92,13 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y CONFIG_RC_DEVICES=y CONFIG_IR_SUNXI=y CONFIG_DRM=y -CONFIG_DRM_DUMB_VGA_DAC=y CONFIG_DRM_SUN4I=y -CONFIG_FB=y +CONFIG_DRM_DUMB_VGA_DAC=y CONFIG_FB_SIMPLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y @@ -130,12 +124,13 @@ CONFIG_RTC_CLASS=y # CONFIG_RTC_INTF_SYSFS is not set # CONFIG_RTC_INTF_PROC is not set CONFIG_RTC_DRV_AC100=y -CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y CONFIG_DMADEVICES=y CONFIG_DMA_SUN6I=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXTCON=y +CONFIG_IIO=y +CONFIG_AXP20X_ADC=y CONFIG_PWM=y CONFIG_PWM_SUN4I=y CONFIG_PHY_SUN4I_USB=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index f0efc854b5a2c7bef7fa74584f69c9a7c9cdefe4..6678f2929356eda4f39dab553758d434c3f0a637 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -121,7 +121,6 @@ CONFIG_TOUCHSCREEN_WM97XX=y CONFIG_TOUCHSCREEN_STMPE=y CONFIG_INPUT_MISC=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y @@ -202,6 +201,8 @@ CONFIG_SND_HDA_CODEC_HDMI=y # CONFIG_SND_USB is not set CONFIG_SND_SOC=y CONFIG_SND_SOC_TEGRA=y +CONFIG_SND_SOC_TEGRA20_I2S=y +CONFIG_SND_SOC_TEGRA30_I2S=y CONFIG_SND_SOC_TEGRA_RT5640=y CONFIG_SND_SOC_TEGRA_WM8753=y CONFIG_SND_SOC_TEGRA_WM8903=y @@ -218,6 +219,9 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_ACM=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_GADGET=y CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=16 CONFIG_MMC_SDHCI=y @@ -247,8 +251,6 @@ CONFIG_RTC_DRV_TEGRA=y CONFIG_DMADEVICES=y CONFIG_TEGRA20_APB_DMA=y CONFIG_STAGING=y -CONFIG_SENSORS_ISL29018=y -CONFIG_SENSORS_ISL29028=y CONFIG_MFD_NVEC=y CONFIG_KEYBOARD_NVEC=y CONFIG_SERIO_NVEC_PS2=y @@ -263,6 +265,8 @@ CONFIG_ARCH_TEGRA_124_SOC=y CONFIG_MEMORY=y CONFIG_IIO=y CONFIG_MPU3050_I2C=y +CONFIG_SENSORS_ISL29018=y +CONFIG_SENSORS_ISL29028=y CONFIG_AK8975=y CONFIG_PWM=y CONFIG_PWM_TEGRA=y @@ -288,13 +292,11 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_SLAB=y CONFIG_DEBUG_VM=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_SG=y diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig index 0fa0ed577b1551b5776b5b3599c6d1ed24cc9eee..edae1c58fe804b10d9c5778a42e8eb3df4a22e60 100644 --- a/arch/arm/configs/vexpress_defconfig +++ b/arch/arm/configs/vexpress_defconfig @@ -19,7 +19,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_VEXPRESS=y -CONFIG_ARCH_VEXPRESS_CA9X4=y CONFIG_ARCH_VEXPRESS_DCSCB=y CONFIG_ARCH_VEXPRESS_TC2_PM=y # CONFIG_SWP_EMULATE is not set diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index 44d4fa57ba0a346cde5f53d099a3be61b42d841a..070e5074f1ee5b118ed35612c9cd09d65f611255 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -113,7 +113,7 @@ CONFIG_FB_PXA_PARAMETERS=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_PWM=m # CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig index 8d4c0c926c344d9f654a87d179488eb5bfff7096..09e7050d56532dabd512cc99e1038a6dae525d69 100644 --- a/arch/arm/configs/zeus_defconfig +++ b/arch/arm/configs/zeus_defconfig @@ -112,7 +112,7 @@ CONFIG_FB_PXA=m CONFIG_FB_PXA_PARAMETERS=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig index b9adedcc5b2e2d58b43be91b803f7ed8a61ed8a4..ec72752d5668eb3bbe1e013ecf5f2b9f9406b69a 100644 --- a/arch/arm/crypto/Kconfig +++ b/arch/arm/crypto/Kconfig @@ -94,14 +94,15 @@ config CRYPTO_AES_ARM_CE ARMv8 Crypto Extensions config CRYPTO_GHASH_ARM_CE - tristate "PMULL-accelerated GHASH using ARMv8 Crypto Extensions" + tristate "PMULL-accelerated GHASH using NEON/ARMv8 Crypto Extensions" depends on KERNEL_MODE_NEON select CRYPTO_HASH select CRYPTO_CRYPTD help Use an implementation of GHASH (used by the GCM AEAD chaining mode) that uses the 64x64 to 128 bit polynomial multiplication (vmull.p64) - that is part of the ARMv8 Crypto Extensions + that is part of the ARMv8 Crypto Extensions, or a slower variant that + uses the vmull.p8 instruction that is part of the basic NEON ISA. config CRYPTO_CRCT10DIF_ARM_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c index 0f966a8ca1cef5f9b122530652d38b9a784e7876..d0a9cec73707b7be885b509e5befe393e90b902f 100644 --- a/arch/arm/crypto/aes-ce-glue.c +++ b/arch/arm/crypto/aes-ce-glue.c @@ -285,9 +285,7 @@ static int ctr_encrypt(struct skcipher_request *req) ce_aes_ctr_encrypt(tail, NULL, (u8 *)ctx->key_enc, num_rounds(ctx), blocks, walk.iv); - if (tdst != tsrc) - memcpy(tdst, tsrc, nbytes); - crypto_xor(tdst, tail, nbytes); + crypto_xor_cpy(tdst, tsrc, tail, nbytes); err = skcipher_walk_done(&walk, 0); } kernel_neon_end(); diff --git a/arch/arm/crypto/aes-cipher-core.S b/arch/arm/crypto/aes-cipher-core.S index c817a86c4ca89e1472a15b0ede4ba6e654b4c399..54b384084637b7e574a1d15a52d16ffc572b815e 100644 --- a/arch/arm/crypto/aes-cipher-core.S +++ b/arch/arm/crypto/aes-cipher-core.S @@ -10,6 +10,7 @@ */ #include +#include .text .align 5 @@ -32,19 +33,19 @@ .endif .endm - .macro __load, out, in, idx + .macro __load, out, in, idx, sz, op .if __LINUX_ARM_ARCH__ < 7 && \idx > 0 - ldr \out, [ttab, \in, lsr #(8 * \idx) - 2] + ldr\op \out, [ttab, \in, lsr #(8 * \idx) - \sz] .else - ldr \out, [ttab, \in, lsl #2] + ldr\op \out, [ttab, \in, lsl #\sz] .endif .endm - .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc + .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op __select \out0, \in0, 0 __select t0, \in1, 1 - __load \out0, \out0, 0 - __load t0, t0, 1 + __load \out0, \out0, 0, \sz, \op + __load t0, t0, 1, \sz, \op .if \enc __select \out1, \in1, 0 @@ -53,10 +54,10 @@ __select \out1, \in3, 0 __select t1, \in0, 1 .endif - __load \out1, \out1, 0 + __load \out1, \out1, 0, \sz, \op __select t2, \in2, 2 - __load t1, t1, 1 - __load t2, t2, 2 + __load t1, t1, 1, \sz, \op + __load t2, t2, 2, \sz, \op eor \out0, \out0, t0, ror #24 @@ -68,9 +69,9 @@ __select \t3, \in1, 2 __select \t4, \in2, 3 .endif - __load \t3, \t3, 2 - __load t0, t0, 3 - __load \t4, \t4, 3 + __load \t3, \t3, 2, \sz, \op + __load t0, t0, 3, \sz, \op + __load \t4, \t4, 3, \sz, \op eor \out1, \out1, t1, ror #24 eor \out0, \out0, t2, ror #16 @@ -82,14 +83,14 @@ eor \out1, \out1, t2 .endm - .macro fround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1 - __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1 + .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op + __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op .endm - .macro iround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0 - __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0 + .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op + __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op .endm .macro __rev, out, in @@ -114,7 +115,7 @@ .endif .endm - .macro do_crypt, round, ttab, ltab + .macro do_crypt, round, ttab, ltab, bsz push {r3-r11, lr} ldr r4, [in] @@ -146,9 +147,12 @@ 1: subs rounds, rounds, #4 \round r8, r9, r10, r11, r4, r5, r6, r7 - __adrl ttab, \ltab, ls + bls 2f \round r4, r5, r6, r7, r8, r9, r10, r11 - bhi 0b + b 0b + +2: __adrl ttab, \ltab + \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b #ifdef CONFIG_CPU_BIG_ENDIAN __rev r4, r4 @@ -170,10 +174,48 @@ .ltorg .endm + .align L1_CACHE_SHIFT + .type __aes_arm_inverse_sbox, %object +__aes_arm_inverse_sbox: + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + .size __aes_arm_inverse_sbox, . - __aes_arm_inverse_sbox + ENTRY(__aes_arm_encrypt) - do_crypt fround, crypto_ft_tab, crypto_fl_tab + do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 ENDPROC(__aes_arm_encrypt) + .align 5 ENTRY(__aes_arm_decrypt) - do_crypt iround, crypto_it_tab, crypto_il_tab + do_crypt iround, crypto_it_tab, __aes_arm_inverse_sbox, 0 ENDPROC(__aes_arm_decrypt) diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c index c763779614442c22cbb303b9d095d30d470092ed..18768f3304495157f1ccdc411901f3ebdb4dd635 100644 --- a/arch/arm/crypto/aes-neonbs-glue.c +++ b/arch/arm/crypto/aes-neonbs-glue.c @@ -221,9 +221,8 @@ static int ctr_encrypt(struct skcipher_request *req) u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; - if (dst != src) - memcpy(dst, src, walk.total % AES_BLOCK_SIZE); - crypto_xor(dst, final, walk.total % AES_BLOCK_SIZE); + crypto_xor_cpy(dst, src, final, + walk.total % AES_BLOCK_SIZE); err = skcipher_walk_done(&walk, 0); break; diff --git a/arch/arm/crypto/ghash-ce-core.S b/arch/arm/crypto/ghash-ce-core.S index f6ab8bcc9efe7f1b8e11b1b42f2530a55dd25b1b..2f78c10b188152f80409869a5062c63a751b9442 100644 --- a/arch/arm/crypto/ghash-ce-core.S +++ b/arch/arm/crypto/ghash-ce-core.S @@ -1,7 +1,7 @@ /* - * Accelerated GHASH implementation with ARMv8 vmull.p64 instructions. + * Accelerated GHASH implementation with NEON/ARMv8 vmull.p8/64 instructions. * - * Copyright (C) 2015 Linaro Ltd. + * Copyright (C) 2015 - 2017 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -12,40 +12,162 @@ #include SHASH .req q0 - SHASH2 .req q1 - T1 .req q2 - T2 .req q3 - MASK .req q4 - XL .req q5 - XM .req q6 - XH .req q7 - IN1 .req q7 + T1 .req q1 + XL .req q2 + XM .req q3 + XH .req q4 + IN1 .req q4 SHASH_L .req d0 SHASH_H .req d1 - SHASH2_L .req d2 - T1_L .req d4 - MASK_L .req d8 - XL_L .req d10 - XL_H .req d11 - XM_L .req d12 - XM_H .req d13 - XH_L .req d14 + T1_L .req d2 + T1_H .req d3 + XL_L .req d4 + XL_H .req d5 + XM_L .req d6 + XM_H .req d7 + XH_L .req d8 + + t0l .req d10 + t0h .req d11 + t1l .req d12 + t1h .req d13 + t2l .req d14 + t2h .req d15 + t3l .req d16 + t3h .req d17 + t4l .req d18 + t4h .req d19 + + t0q .req q5 + t1q .req q6 + t2q .req q7 + t3q .req q8 + t4q .req q9 + T2 .req q9 + + s1l .req d20 + s1h .req d21 + s2l .req d22 + s2h .req d23 + s3l .req d24 + s3h .req d25 + s4l .req d26 + s4h .req d27 + + MASK .req d28 + SHASH2_p8 .req d28 + + k16 .req d29 + k32 .req d30 + k48 .req d31 + SHASH2_p64 .req d31 .text .fpu crypto-neon-fp-armv8 + .macro __pmull_p64, rd, rn, rm, b1, b2, b3, b4 + vmull.p64 \rd, \rn, \rm + .endm + /* - * void pmull_ghash_update(int blocks, u64 dg[], const char *src, - * struct ghash_key const *k, const char *head) + * This implementation of 64x64 -> 128 bit polynomial multiplication + * using vmull.p8 instructions (8x8 -> 16) is taken from the paper + * "Fast Software Polynomial Multiplication on ARM Processors Using + * the NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and + * Ricardo Dahab (https://hal.inria.fr/hal-01506572) + * + * It has been slightly tweaked for in-order performance, and to allow + * 'rq' to overlap with 'ad' or 'bd'. */ -ENTRY(pmull_ghash_update) - vld1.64 {SHASH}, [r3] + .macro __pmull_p8, rq, ad, bd, b1=t4l, b2=t3l, b3=t4l, b4=t3l + vext.8 t0l, \ad, \ad, #1 @ A1 + .ifc \b1, t4l + vext.8 t4l, \bd, \bd, #1 @ B1 + .endif + vmull.p8 t0q, t0l, \bd @ F = A1*B + vext.8 t1l, \ad, \ad, #2 @ A2 + vmull.p8 t4q, \ad, \b1 @ E = A*B1 + .ifc \b2, t3l + vext.8 t3l, \bd, \bd, #2 @ B2 + .endif + vmull.p8 t1q, t1l, \bd @ H = A2*B + vext.8 t2l, \ad, \ad, #3 @ A3 + vmull.p8 t3q, \ad, \b2 @ G = A*B2 + veor t0q, t0q, t4q @ L = E + F + .ifc \b3, t4l + vext.8 t4l, \bd, \bd, #3 @ B3 + .endif + vmull.p8 t2q, t2l, \bd @ J = A3*B + veor t0l, t0l, t0h @ t0 = (L) (P0 + P1) << 8 + veor t1q, t1q, t3q @ M = G + H + .ifc \b4, t3l + vext.8 t3l, \bd, \bd, #4 @ B4 + .endif + vmull.p8 t4q, \ad, \b3 @ I = A*B3 + veor t1l, t1l, t1h @ t1 = (M) (P2 + P3) << 16 + vmull.p8 t3q, \ad, \b4 @ K = A*B4 + vand t0h, t0h, k48 + vand t1h, t1h, k32 + veor t2q, t2q, t4q @ N = I + J + veor t0l, t0l, t0h + veor t1l, t1l, t1h + veor t2l, t2l, t2h @ t2 = (N) (P4 + P5) << 24 + vand t2h, t2h, k16 + veor t3l, t3l, t3h @ t3 = (K) (P6 + P7) << 32 + vmov.i64 t3h, #0 + vext.8 t0q, t0q, t0q, #15 + veor t2l, t2l, t2h + vext.8 t1q, t1q, t1q, #14 + vmull.p8 \rq, \ad, \bd @ D = A*B + vext.8 t2q, t2q, t2q, #13 + vext.8 t3q, t3q, t3q, #12 + veor t0q, t0q, t1q + veor t2q, t2q, t3q + veor \rq, \rq, t0q + veor \rq, \rq, t2q + .endm + + // + // PMULL (64x64->128) based reduction for CPUs that can do + // it in a single instruction. + // + .macro __pmull_reduce_p64 + vmull.p64 T1, XL_L, MASK + + veor XH_L, XH_L, XM_H + vext.8 T1, T1, T1, #8 + veor XL_H, XL_H, XM_L + veor T1, T1, XL + + vmull.p64 XL, T1_H, MASK + .endm + + // + // Alternative reduction for CPUs that lack support for the + // 64x64->128 PMULL instruction + // + .macro __pmull_reduce_p8 + veor XL_H, XL_H, XM_L + veor XH_L, XH_L, XM_H + + vshl.i64 T1, XL, #57 + vshl.i64 T2, XL, #62 + veor T1, T1, T2 + vshl.i64 T2, XL, #63 + veor T1, T1, T2 + veor XL_H, XL_H, T1_L + veor XH_L, XH_L, T1_H + + vshr.u64 T1, XL, #1 + veor XH, XH, XL + veor XL, XL, T1 + vshr.u64 T1, T1, #6 + vshr.u64 XL, XL, #1 + .endm + + .macro ghash_update, pn vld1.64 {XL}, [r1] - vmov.i8 MASK, #0xe1 - vext.8 SHASH2, SHASH, SHASH, #8 - vshl.u64 MASK, MASK, #57 - veor SHASH2, SHASH2, SHASH /* do the head block first, if supplied */ ldr ip, [sp] @@ -62,33 +184,59 @@ ENTRY(pmull_ghash_update) #ifndef CONFIG_CPU_BIG_ENDIAN vrev64.8 T1, T1 #endif - vext.8 T2, XL, XL, #8 vext.8 IN1, T1, T1, #8 - veor T1, T1, T2 + veor T1_L, T1_L, XL_H veor XL, XL, IN1 - vmull.p64 XH, SHASH_H, XL_H @ a1 * b1 + __pmull_\pn XH, XL_H, SHASH_H, s1h, s2h, s3h, s4h @ a1 * b1 veor T1, T1, XL - vmull.p64 XL, SHASH_L, XL_L @ a0 * b0 - vmull.p64 XM, SHASH2_L, T1_L @ (a1 + a0)(b1 + b0) + __pmull_\pn XL, XL_L, SHASH_L, s1l, s2l, s3l, s4l @ a0 * b0 + __pmull_\pn XM, T1_L, SHASH2_\pn @ (a1+a0)(b1+b0) - vext.8 T1, XL, XH, #8 - veor T2, XL, XH + veor T1, XL, XH veor XM, XM, T1 - veor XM, XM, T2 - vmull.p64 T2, XL_L, MASK_L - vmov XH_L, XM_H - vmov XM_H, XL_L + __pmull_reduce_\pn - veor XL, XM, T2 - vext.8 T2, XL, XL, #8 - vmull.p64 XL, XL_L, MASK_L - veor T2, T2, XH - veor XL, XL, T2 + veor T1, T1, XH + veor XL, XL, T1 bne 0b vst1.64 {XL}, [r1] bx lr -ENDPROC(pmull_ghash_update) + .endm + + /* + * void pmull_ghash_update(int blocks, u64 dg[], const char *src, + * struct ghash_key const *k, const char *head) + */ +ENTRY(pmull_ghash_update_p64) + vld1.64 {SHASH}, [r3] + veor SHASH2_p64, SHASH_L, SHASH_H + + vmov.i8 MASK, #0xe1 + vshl.u64 MASK, MASK, #57 + + ghash_update p64 +ENDPROC(pmull_ghash_update_p64) + +ENTRY(pmull_ghash_update_p8) + vld1.64 {SHASH}, [r3] + veor SHASH2_p8, SHASH_L, SHASH_H + + vext.8 s1l, SHASH_L, SHASH_L, #1 + vext.8 s2l, SHASH_L, SHASH_L, #2 + vext.8 s3l, SHASH_L, SHASH_L, #3 + vext.8 s4l, SHASH_L, SHASH_L, #4 + vext.8 s1h, SHASH_H, SHASH_H, #1 + vext.8 s2h, SHASH_H, SHASH_H, #2 + vext.8 s3h, SHASH_H, SHASH_H, #3 + vext.8 s4h, SHASH_H, SHASH_H, #4 + + vmov.i64 k16, #0xffff + vmov.i64 k32, #0xffffffff + vmov.i64 k48, #0xffffffffffff + + ghash_update p8 +ENDPROC(pmull_ghash_update_p8) diff --git a/arch/arm/crypto/ghash-ce-glue.c b/arch/arm/crypto/ghash-ce-glue.c index 6bac8bea9f1e8e95a9ca80892bcdf03b02b8f48b..d9bb52cae2ac9246fab3626bc5d8438639e97fbc 100644 --- a/arch/arm/crypto/ghash-ce-glue.c +++ b/arch/arm/crypto/ghash-ce-glue.c @@ -22,6 +22,7 @@ MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("ghash"); #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -41,8 +42,17 @@ struct ghash_async_ctx { struct cryptd_ahash *cryptd_tfm; }; -asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src, - struct ghash_key const *k, const char *head); +asmlinkage void pmull_ghash_update_p64(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +asmlinkage void pmull_ghash_update_p8(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +static void (*pmull_ghash_update)(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); static int ghash_init(struct shash_desc *desc) { @@ -312,6 +322,14 @@ static int __init ghash_ce_mod_init(void) { int err; + if (!(elf_hwcap & HWCAP_NEON)) + return -ENODEV; + + if (elf_hwcap2 & HWCAP2_PMULL) + pmull_ghash_update = pmull_ghash_update_p64; + else + pmull_ghash_update = pmull_ghash_update_p8; + err = crypto_register_shash(&ghash_alg); if (err) return err; @@ -332,5 +350,5 @@ static void __exit ghash_ce_mod_exit(void) crypto_unregister_shash(&ghash_alg); } -module_cpu_feature_match(PMULL, ghash_ce_mod_init); +module_init(ghash_ce_mod_init); module_exit(ghash_ce_mod_exit); diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h index 27475904e0966f1caafffb23b199d4d4c2bb920e..eee269321923b8375e043ad50148031aa00407db 100644 --- a/arch/arm/include/asm/arch_gicv3.h +++ b/arch/arm/include/asm/arch_gicv3.h @@ -275,6 +275,12 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr) #define gicr_read_pendbaser(c) __gic_readq_nonatomic(c) #define gicr_write_pendbaser(v, c) __gic_writeq_nonatomic(v, c) +/* + * GICR_xLPIR - only the lower bits are significant + */ +#define gic_read_lpir(c) readl_relaxed(c) +#define gic_write_lpir(v, c) writel_relaxed(lower_32_bits(v), c) + /* * GITS_TYPER is an ID register and doesn't need atomicity. */ @@ -291,5 +297,33 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr) */ #define gits_write_cwriter(v, c) __gic_writeq_nonatomic(v, c) +/* + * GITS_VPROPBASER - hi and lo bits may be accessed independently. + */ +#define gits_write_vpropbaser(v, c) __gic_writeq_nonatomic(v, c) + +/* + * GITS_VPENDBASER - the Valid bit must be cleared before changing + * anything else. + */ +static inline void gits_write_vpendbaser(u64 val, void * __iomem addr) +{ + u32 tmp; + + tmp = readl_relaxed(addr + 4); + if (tmp & (GICR_VPENDBASER_Valid >> 32)) { + tmp &= ~(GICR_VPENDBASER_Valid >> 32); + writel_relaxed(tmp, addr + 4); + } + + /* + * Use the fact that __gic_writeq_nonatomic writes the second + * half of the 64bit quantity after the first. + */ + __gic_writeq_nonatomic(val, addr); +} + +#define gits_read_vpendbaser(c) __gic_readq_nonatomic(c) + #endif /* !__ASSEMBLY__ */ #endif /* !__ASM_ARCH_GICV3_H */ diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 6795368ad0238068c55fa4c8b56e0d67d9b9a5cf..cc414382dab4b47613619293a0e6e9033e480ec6 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -128,20 +128,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #endif /* !SMP */ static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - #ifndef CONFIG_SMP preempt_disable(); #endif @@ -172,17 +162,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index ebf020b02bc8ff60623ccccfd100f7f0addeeb97..c8781450905be94995e0df72aeb3cc722afd1b60 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -227,7 +227,6 @@ #define HSR_DABT_S1PTW (_AC(1, UL) << 7) #define HSR_DABT_CM (_AC(1, UL) << 8) -#define HSR_DABT_EA (_AC(1, UL) << 9) #define kvm_arm_exception_type \ {0, "RESET" }, \ diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index 9a8a45aaf19a4d4eeeece7d2616833644fe35090..98089ffd91bb602649cc7724adafe5ce045b9c8a 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -149,11 +149,6 @@ static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu) return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT; } -static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) -{ - return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA; -} - static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW; @@ -206,6 +201,25 @@ static inline u8 kvm_vcpu_trap_get_fault_type(struct kvm_vcpu *vcpu) return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE; } +static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) +{ + switch (kvm_vcpu_trap_get_fault_type(vcpu)) { + case FSC_SEA: + case FSC_SEA_TTW0: + case FSC_SEA_TTW1: + case FSC_SEA_TTW2: + case FSC_SEA_TTW3: + case FSC_SECC: + case FSC_SECC_TTW0: + case FSC_SECC_TTW1: + case FSC_SECC_TTW2: + case FSC_SECC_TTW3: + return true; + default: + return false; + } +} + static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK; diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 127e2dd2e21ce12c7daa21e682ce72d36f6b1afd..4a879f6ff13bea92d189eec9370be73cd616705c 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -225,12 +225,6 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); -/* We do not have shadow page tables, hence the empty hooks */ -static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, - unsigned long address) -{ -} - struct kvm_vcpu *kvm_arm_get_running_vcpu(void); struct kvm_vcpu __percpu **kvm_get_running_vcpus(void); void kvm_arm_halt_guest(struct kvm *kvm); diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h index bfe163c40024de7d6ccc81097451cfc409cc42c8..5983f6bc62d57784b007f3ccad4e80cad47e5828 100644 --- a/arch/arm/include/asm/smp_scu.h +++ b/arch/arm/include/asm/smp_scu.h @@ -7,6 +7,7 @@ #ifndef __ASSEMBLER__ +#include #include static inline bool scu_a9_has_base(void) diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index 4bec4544207243d477b2e326b50119cc842526fe..c030143c18c6ea9709a5b42c44112549bd4503fc 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -52,22 +52,6 @@ static inline void dsb_sev(void) * memory. */ -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - u16 owner = READ_ONCE(lock->tickets.owner); - - for (;;) { - arch_spinlock_t tmp = READ_ONCE(*lock); - - if (tmp.tickets.owner == tmp.tickets.next || - tmp.tickets.owner != owner) - break; - - wfe(); - } - smp_acquire__after_ctrl_dep(); -} - #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) static inline void arch_spin_lock(arch_spinlock_t *lock) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aad0fc1c2154c6cf3839ff21bb1c46d6499..fe1c6af3a1b1a4cab35c6d125b43262d3d21fd85 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -24,6 +24,20 @@ extern void * memchr(const void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); +#define __HAVE_ARCH_MEMSET32 +extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); +static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n) +{ + return __memset32(p, v, n * 4); +} + +#define __HAVE_ARCH_MEMSET64 +extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi); +static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) +{ + return __memset64(p, v, n * 8, v >> 32); +} + extern void __memzero(void *ptr, __kernel_size_t n); #define memset(p,v,n) \ diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h index 6c7182f32cefeb247068e80af9944b4ff01e3727..a61905c86732973665f101be08cffac5a7d4c946 100644 --- a/arch/arm/include/asm/suspend.h +++ b/arch/arm/include/asm/suspend.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARM_SUSPEND_H #define __ASM_ARM_SUSPEND_H +#include + struct sleep_save_sp { u32 *save_ptr_stash; u32 save_ptr_stash_phys; diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 3f2eb76243e3c5f9d387959acae740ce871e5afa..d5562f9ce60079139d360e5d6afac59469051454 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -148,7 +148,8 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb) } static inline void -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) +arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) { tlb->mm = mm; tlb->fullmm = !(start | (end+1)); @@ -166,8 +167,14 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start } static inline void -tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force) { + if (force) { + tlb->range_start = start; + tlb->range_end = end; + } + tlb_flush_mmu(tlb); /* keep the page table cache within bounds */ diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index f555bb3664dcaa2dbee6ab4e1f486d24e360ba8f..683d9230984a51c33a89dac39ae8e7904c7017f9 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h @@ -18,7 +18,6 @@ struct undef_hook { void register_undef_hook(struct undef_hook *hook); void unregister_undef_hook(struct undef_hook *hook); -#ifdef CONFIG_FUNCTION_GRAPH_TRACER static inline int __in_irqentry_text(unsigned long ptr) { extern char __irqentry_text_start[]; @@ -27,12 +26,6 @@ static inline int __in_irqentry_text(unsigned long ptr) return ptr >= (unsigned long)&__irqentry_text_start && ptr < (unsigned long)&__irqentry_text_end; } -#else -static inline int __in_irqentry_text(unsigned long ptr) -{ - return 0; -} -#endif static inline int in_exception_text(unsigned long ptr) { diff --git a/arch/arm/include/debug/omap2plus.S b/arch/arm/include/debug/omap2plus.S index 6d867aef18eb097566187ae6b7c925f02af17b98..192a7583999ce7c5ebc26f012342e831d7d657fb 100644 --- a/arch/arm/include/debug/omap2plus.S +++ b/arch/arm/include/debug/omap2plus.S @@ -12,43 +12,6 @@ #include -/* OMAP2 serial ports */ -#define OMAP2_UART1_BASE 0x4806a000 -#define OMAP2_UART2_BASE 0x4806c000 -#define OMAP2_UART3_BASE 0x4806e000 - -/* OMAP3 serial ports */ -#define OMAP3_UART1_BASE OMAP2_UART1_BASE -#define OMAP3_UART2_BASE OMAP2_UART2_BASE -#define OMAP3_UART3_BASE 0x49020000 -#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */ -#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */ - -/* OMAP4 serial ports */ -#define OMAP4_UART1_BASE OMAP2_UART1_BASE -#define OMAP4_UART2_BASE OMAP2_UART2_BASE -#define OMAP4_UART3_BASE 0x48020000 -#define OMAP4_UART4_BASE 0x4806e000 - -/* TI81XX serial ports */ -#define TI81XX_UART1_BASE 0x48020000 -#define TI81XX_UART2_BASE 0x48022000 -#define TI81XX_UART3_BASE 0x48024000 - -/* AM3505/3517 UART4 */ -#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ - -/* AM33XX serial port */ -#define AM33XX_UART1_BASE 0x44E09000 - -/* OMAP5 serial ports */ -#define OMAP5_UART1_BASE OMAP2_UART1_BASE -#define OMAP5_UART2_BASE OMAP2_UART2_BASE -#define OMAP5_UART3_BASE OMAP4_UART3_BASE -#define OMAP5_UART4_BASE OMAP4_UART4_BASE -#define OMAP5_UART5_BASE 0x48066000 -#define OMAP5_UART6_BASE 0x48068000 - /* External port on Zoom2/3 */ #define ZOOM_UART_BASE 0x10000000 #define ZOOM_UART_VIRT 0xfa400000 @@ -59,6 +22,7 @@ #define UART_OFFSET(addr) ((addr) & 0x00ffffff) .pushsection .data + .align 2 omap_uart_phys: .word 0 omap_uart_virt: .word 0 omap_uart_lsr: .word 0 @@ -79,55 +43,6 @@ omap_uart_lsr: .word 0 bne 100f @ already configured /* Configure the UART offset from the phys/virt base */ -#ifdef CONFIG_DEBUG_OMAP2UART1 - mov \rp, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4 - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP2UART2 - mov \rp, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4 - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP2UART3 - mov \rp, #UART_OFFSET(OMAP2_UART3_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP3UART3 - mov \rp, #UART_OFFSET(OMAP3_UART1_BASE) - add \rp, \rp, #0x00fb0000 - add \rp, \rp, #0x00006000 @ OMAP3_UART3_BASE - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP4UART3 - mov \rp, #UART_OFFSET(OMAP4_UART3_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP3UART4 - mov \rp, #UART_OFFSET(OMAP3_UART1_BASE) - add \rp, \rp, #0x00fb0000 - add \rp, \rp, #0x00028000 @ OMAP3_UART4_BASE - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP4UART4 - mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_TI81XXUART1 - mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_TI81XXUART2 - mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_TI81XXUART3 - mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_AM33XXUART1 - ldr \rp, =AM33XX_UART1_BASE - and \rp, \rp, #0x00ffffff - b 97f -#endif #ifdef CONFIG_DEBUG_ZOOM_UART ldr \rp, =ZOOM_UART_BASE str \rp, [\tmp, #0] @ omap_uart_phys @@ -138,28 +53,6 @@ omap_uart_lsr: .word 0 #endif b 10b - /* AM33XX: Store both phys and virt address for the uart */ -97: add \rp, \rp, #0x44000000 @ phys base - str \rp, [\tmp, #0] @ omap_uart_phys - sub \rp, \rp, #0x44000000 @ phys base - add \rp, \rp, #0xf9000000 @ virt base - str \rp, [\tmp, #4] @ omap_uart_virt - mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) - str \rp, [\tmp, #8] @ omap_uart_lsr - - b 10b - - /* Store both phys and virt address for the uart */ -98: add \rp, \rp, #0x48000000 @ phys base - str \rp, [\tmp, #0] @ omap_uart_phys - sub \rp, \rp, #0x48000000 @ phys base - add \rp, \rp, #0xfa000000 @ virt base - str \rp, [\tmp, #4] @ omap_uart_virt - mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) - str \rp, [\tmp, #8] @ omap_uart_lsr - - b 10b - .align 99: .word . .word omap_uart_phys diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 8e8d20cdbce736b251c93f3822f741893dd9824c..5266fd9ad6b41402dceafcdf1991776f39fbe57b 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -87,6 +87,8 @@ EXPORT_SYMBOL(__raw_writesl); EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(__memset32); +EXPORT_SYMBOL(__memset64); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memchr); diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index a3308ad1a02477d4fbe0fb196d940c53e44a6681..fda5579123a8b2ce7c09cd359421a7dfcfd48392 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -101,8 +101,8 @@ static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) ops = arm_cpuidle_get_ops(enable_method); if (!ops) { - pr_warn("%s: unsupported enable-method property: %s\n", - dn->full_name, enable_method); + pr_warn("%pOF: unsupported enable-method property: %s\n", + dn, enable_method); return -EOPNOTSUPP; } diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index f676febbb2706caaaa2856691032e415b4aa8d46..ecaa68dd1af52c9e1afd994978d70ddad7400b75 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -95,7 +95,7 @@ void __init arm_dt_init_cpu_maps(void) if (of_node_cmp(cpu->type, "cpu")) continue; - pr_debug(" * %s...\n", cpu->full_name); + pr_debug(" * %pOF...\n", cpu); /* * A device tree containing CPU nodes with missing "reg" * properties is considered invalid to build the @@ -103,8 +103,7 @@ void __init arm_dt_init_cpu_maps(void) */ cell = of_get_property(cpu, "reg", &prop_bytes); if (!cell || prop_bytes < sizeof(*cell)) { - pr_debug(" * %s missing reg property\n", - cpu->full_name); + pr_debug(" * %pOF missing reg property\n", cpu); of_node_put(cpu); return; } diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index c731f0d2b2af1549dea68dcce2035ce398b81604..fbc707626b3e9e6794400e41ba1b08916cdf8d4a 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -721,6 +721,7 @@ do_fpe: */ .pushsection .data + .align 2 ENTRY(fp_enter) .word no_fp .popsection @@ -1224,6 +1225,7 @@ vector_addrexcptn: W(b) vector_fiq .data + .align 2 .globl cr_alignment cr_alignment: diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index eb5cd77bf1d8326aa69fe05ff7dc223aa5eb707a..99c908226065cf6331324309edeadfa618597874 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_AEABI #include #endif @@ -27,6 +28,14 @@ #include "entry-header.S" +saved_psr .req r8 +#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) +saved_pc .req r9 +#define TRACE(x...) x +#else +saved_pc .req lr +#define TRACE(x...) +#endif .align 5 #if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING)) @@ -40,10 +49,14 @@ ret_fast_syscall: UNWIND(.fnstart ) UNWIND(.cantunwind ) disable_irq_notrace @ disable interrupts + ldr r2, [tsk, #TI_ADDR_LIMIT] + cmp r2, #TASK_SIZE + blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK bne fast_work_pending + /* perform architecture specific actions before user return */ arch_ret_to_user r1, lr @@ -66,6 +79,9 @@ ret_fast_syscall: UNWIND(.cantunwind ) str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 disable_irq_notrace @ disable interrupts + ldr r2, [tsk, #TI_ADDR_LIMIT] + cmp r2, #TASK_SIZE + blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK beq no_work_pending @@ -98,6 +114,9 @@ ENTRY(ret_to_user) ret_slow_syscall: disable_irq_notrace @ disable interrupts ENTRY(ret_to_user_from_irq) + ldr r2, [tsk, #TI_ADDR_LIMIT] + cmp r2, #TASK_SIZE + blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] tst r1, #_TIF_WORK_MASK bne slow_work_pending @@ -141,16 +160,17 @@ ENTRY(vector_swi) ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr THUMB( mov r8, sp ) THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr - mrs r8, spsr @ called from non-FIQ mode, so ok. - str lr, [sp, #S_PC] @ Save calling PC - str r8, [sp, #S_PSR] @ Save CPSR + mrs saved_psr, spsr @ called from non-FIQ mode, so ok. + TRACE( mov saved_pc, lr ) + str saved_pc, [sp, #S_PC] @ Save calling PC + str saved_psr, [sp, #S_PSR] @ Save CPSR str r0, [sp, #S_OLD_R0] @ Save OLD_R0 #endif zero_fp alignment_trap r10, ip, __cr_alignment - enable_irq - ct_user_exit - get_thread_info tsk + asm_trace_hardirqs_on save=0 + enable_irq_notrace + ct_user_exit save=0 /* * Get the system call number. @@ -163,11 +183,11 @@ ENTRY(vector_swi) * value to determine if it is an EABI or an old ABI call. */ #ifdef CONFIG_ARM_THUMB - tst r8, #PSR_T_BIT + tst saved_psr, #PSR_T_BIT movne r10, #0 @ no thumb OABI emulation - USER( ldreq r10, [lr, #-4] ) @ get SWI instruction + USER( ldreq r10, [saved_pc, #-4] ) @ get SWI instruction #else - USER( ldr r10, [lr, #-4] ) @ get SWI instruction + USER( ldr r10, [saved_pc, #-4] ) @ get SWI instruction #endif ARM_BE8(rev r10, r10) @ little endian instruction @@ -178,15 +198,17 @@ ENTRY(vector_swi) */ #elif defined(CONFIG_ARM_THUMB) /* Legacy ABI only, possibly thumb mode. */ - tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs + tst saved_psr, #PSR_T_BIT @ this is SPSR from save_user_regs addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in - USER( ldreq scno, [lr, #-4] ) + USER( ldreq scno, [saved_pc, #-4] ) #else /* Legacy ABI only. */ - USER( ldr scno, [lr, #-4] ) @ get SWI instruction + USER( ldr scno, [saved_pc, #-4] ) @ get SWI instruction #endif + /* saved_psr and saved_pc are now dead */ + uaccess_disable tbl adr tbl, sys_call_table @ load syscall table pointer @@ -205,6 +227,12 @@ ENTRY(vector_swi) bic scno, scno, #0xff000000 @ mask off SWI op-code eor scno, scno, #__NR_SYSCALL_BASE @ check OS number #endif + get_thread_info tsk + /* + * Reload the registers that may have been corrupted on entry to + * the syscall assembly (by tracing or context tracking.) + */ + TRACE( ldmia sp, {r0 - r3} ) local_restart: ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing @@ -234,8 +262,9 @@ local_restart: * current task. */ 9001: - sub lr, lr, #4 + sub lr, saved_pc, #4 str lr, [sp, #S_PC] + get_thread_info tsk b ret_fast_syscall #endif ENDPROC(vector_swi) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04286fd9e09ce7a27259c4d375a05a965e3be0ea..6b1148cafffdbe09070f996343287a4db9bb1baa 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -556,6 +556,7 @@ ENDPROC(__fixup_smp) .word __smpalt_end .pushsection .data + .align 2 .globl smp_on_up smp_on_up: ALT_SMP(.long 1) @@ -716,6 +717,7 @@ ENTRY(fixup_pv_table) ENDPROC(fixup_pv_table) .data + .align 2 .globl __pv_phys_pfn_offset .type __pv_phys_pfn_offset, %object __pv_phys_pfn_offset: diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index ec7e7377d423ddd5fa9d0bd3be0b2eb45a26209f..60146e32619a5912bf12b5277397f2e19213b2a8 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S @@ -31,6 +31,7 @@ * zeroing of .bss would clobber it. */ .data + .align 2 ENTRY(__boot_cpu_mode) .long 0 .text diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index 49fadbda8c63ab336d205d6fd538a13dc269fb79..81cd4d43b3ec8eded3415dce5e6c5c5d591d9d36 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -367,6 +367,7 @@ ENTRY(iwmmxt_task_release) ENDPROC(iwmmxt_task_release) .data + .align 2 concan_owner: .word 0 diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 5814298ef0b701e61e4de018aa216009c9445d30..b67ae12503f30c3ba113f1d8c7a943d17e9db717 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -673,3 +674,9 @@ struct page *get_signal_page(void) return page; } + +/* Defer to generic check */ +asmlinkage void addr_limit_check_failed(void) +{ + addr_limit_user_check(); +} diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 0f6c1000582c359881b6985c57d010037cb4ac17..9f08d214d05a91c216abe7542a9bf6340dc0f812 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -171,6 +171,7 @@ mpidr_hash_ptr: .long mpidr_hash - . @ mpidr_hash struct offset .data + .align 2 .type sleep_save_sp, #object ENTRY(sleep_save_sp) .space SLEEP_SAVE_SP_SZ @ struct sleep_save_sp diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 3a2fa203637a99d8da93962da8e151f07d1bf0fc..65228bf4c6dfee221e4e3a38112c0d59ecda65f9 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -171,6 +171,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { __save_stack_trace(tsk, trace, 1); } +EXPORT_SYMBOL(save_stack_trace_tsk); void save_stack_trace(struct stack_trace *trace) { diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index bf949a763dbe5b1b38b0e75ea24e62b051570d64..24ac3cab411d94a186390aa1fedb16b53e1d3a73 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -127,8 +127,7 @@ static void __init parse_dt_topology(void) rate = of_get_property(cn, "clock-frequency", &len); if (!rate || len != 4) { - pr_err("%s missing clock-frequency property\n", - cn->full_name); + pr_err("%pOF missing clock-frequency property\n", cn); continue; } diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c index 54442e3753542e342d8ba8b2c227ec4f31910175..cf8bf6bf87c4b822ff6f19f0206602baca519479 100644 --- a/arch/arm/kvm/handle_exit.c +++ b/arch/arm/kvm/handle_exit.c @@ -67,7 +67,7 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE) { trace_kvm_wfx(*vcpu_pc(vcpu), true); vcpu->stat.wfe_exit_stat++; - kvm_vcpu_on_spin(vcpu); + kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu)); } else { trace_kvm_wfx(*vcpu_pc(vcpu), false); vcpu->stat.wfi_exit_stat++; diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index 3c65e3bd790fe1f7aec59d9568cb4c0799be0e9a..ed6d35d9cdb5a6288f70d116e6914f803455006e 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -28,7 +28,7 @@ UNWIND( .fnstart ) 1: orr r1, r1, r1, lsl #8 orr r1, r1, r1, lsl #16 mov r3, r1 - cmp r2, #16 +7: cmp r2, #16 blt 4f #if ! CALGN(1)+0 @@ -41,7 +41,7 @@ UNWIND( .fnend ) UNWIND( .fnstart ) UNWIND( .save {r8, lr} ) mov r8, r1 - mov lr, r1 + mov lr, r3 2: subs r2, r2, #64 stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. @@ -73,11 +73,11 @@ UNWIND( .fnend ) UNWIND( .fnstart ) UNWIND( .save {r4-r8, lr} ) mov r4, r1 - mov r5, r1 + mov r5, r3 mov r6, r1 - mov r7, r1 + mov r7, r3 mov r8, r1 - mov lr, r1 + mov lr, r3 cmp r2, #96 tstgt ip, #31 @@ -114,7 +114,7 @@ UNWIND( .fnstart ) tst r2, #4 strne r1, [ip], #4 /* - * When we get here, we've got less than 4 bytes to zero. We + * When we get here, we've got less than 4 bytes to set. We * may have an unaligned pointer as well. */ 5: tst r2, #2 @@ -135,3 +135,15 @@ UNWIND( .fnstart ) UNWIND( .fnend ) ENDPROC(memset) ENDPROC(mmioset) + +ENTRY(__memset32) +UNWIND( .fnstart ) + mov r3, r1 @ copy r1 to r3 and fall into memset64 +UNWIND( .fnend ) +ENDPROC(__memset32) +ENTRY(__memset64) +UNWIND( .fnstart ) + mov ip, r0 @ preserve r0 as return value + b 7b @ jump into the middle of memset +UNWIND( .fnend ) +ENDPROC(__memset64) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index d735e5fc47727b0536c943b6fdb15223d7394360..6d870421a7a64d2e3aa615746307e4d4254058f8 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -1,7 +1,7 @@ menuconfig ARCH_AT91 bool "Atmel SoCs" depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND if PM && ARCH_MULTI_V7 select COMMON_CLK_AT91 select GPIOLIB select PINCTRL @@ -26,6 +26,7 @@ config SOC_SAMA5D2 select HAVE_AT91_USB_CLK select HAVE_AT91_H32MX select HAVE_AT91_GENERATED_CLK + select HAVE_AT91_AUDIO_PLL select PINCTRL_AT91PIO4 help Select this if ou are using one of Atmel's SAMA5D2 family SoC. @@ -125,6 +126,9 @@ config HAVE_AT91_H32MX config HAVE_AT91_GENERATED_CLK bool +config HAVE_AT91_AUDIO_PLL + bool + config SOC_SAM_V4_V5 bool diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 667fddac38561eff3f25788ccbf9e05ac8214d84..849014c01cf4d62a465ec6e54b829d4ff45f05a6 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -533,8 +533,8 @@ static void __init at91_pm_backup_init(void) } pm_bu->suspended = 0; - pm_bu->canary = virt_to_phys(&canary); - pm_bu->resume = virt_to_phys(cpu_resume); + pm_bu->canary = __pa_symbol(&canary); + pm_bu->resume = __pa_symbol(cpu_resume); return; @@ -608,6 +608,9 @@ static void __init at91_pm_init(void (*pm_idle)(void)) void __init at91rm9200_pm_init(void) { + if (!IS_ENABLED(CONFIG_SOC_AT91RM9200)) + return; + at91_dt_ramc(); /* @@ -620,18 +623,27 @@ void __init at91rm9200_pm_init(void) void __init at91sam9_pm_init(void) { + if (!IS_ENABLED(CONFIG_SOC_AT91SAM9)) + return; + at91_dt_ramc(); at91_pm_init(at91sam9_idle); } void __init sama5_pm_init(void) { + if (!IS_ENABLED(CONFIG_SOC_SAMA5)) + return; + at91_dt_ramc(); at91_pm_init(NULL); } void __init sama5d2_pm_init(void) { + if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) + return; + at91_pm_backup_init(); sama5_pm_init(); } diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index b5625d0092881bbbbb1022de2664c51f2a304844..cbde0030c092fe1213c4cddb6ffe19383d200e3c 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -1166,7 +1166,7 @@ static struct tvp514x_platform_data tvp5146_pdata = { #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) -static const struct vpif_input da850_ch0_inputs[] = { +static struct vpif_input da850_ch0_inputs[] = { { .input = { .index = 0, @@ -1181,7 +1181,7 @@ static const struct vpif_input da850_ch0_inputs[] = { }, }; -static const struct vpif_input da850_ch1_inputs[] = { +static struct vpif_input da850_ch1_inputs[] = { { .input = { .index = 0, diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 18296a99c4d281b2e89b60d1f98ccbcac5805c41..62e7bc3018f07f0ba13dbc4910fca27601dca5f1 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 284ff27c1b32228d7b9cdcf1dd6cade90b8bd65d..be997243447b949699fd116970ec0aacaffbf444 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 0464999b71377e1078c80462dd63113695cb6e2e..e75741fb2c1da095bd59ba4e0f411a6274ce6255 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 70e00dbeec9694f819ff957014ccbff9841e2ac3..b07c9b18d427cd3cc97a3555858e88c9fc9e9e12 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 1d76e7480a422cd7a6a00ed19b0ddd3ae763453c..cb0a41e835829edb14a25ddb17c28cccf9df85d2 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 41c7c961579133d9a80070a2c46ce56c07f1d8d9..d85accf7f7608a367eb6361cb8da06803c8d7da8 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index f5dce9b4e617df833cd210bac2fe65ac4a93b788..f77a4f7660505fe949af782e50b99c08b12a5570 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -218,6 +218,15 @@ int clk_set_parent(struct clk *clk, struct clk *parent) } EXPORT_SYMBOL(clk_set_parent); +struct clk *clk_get_parent(struct clk *clk) +{ + if (!clk) + return NULL; + + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + int clk_register(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c index bcb678fd24153321bf8b22726ae0c36c1203fc36..8971c3c0f0fe829360440c71c87c7e964db7f5b9 100644 --- a/arch/arm/mach-dove/dove-db-setup.c +++ b/arch/arm/mach-dove/dove-db-setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 39ef3b613912f8888013c30d591e4ad4f0cd8095..d2eee707d27f8e94bf9cb0bf7a7eb70c93dba2ab 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -98,6 +98,13 @@ static struct clk clk_keypad = { .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, .set_rate = set_keytchclk_rate, }; +static struct clk clk_adc = { + .parent = &clk_xtali, + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, + .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_TSEN, + .set_rate = set_keytchclk_rate, +}; static struct clk clk_spi = { .parent = &clk_xtali, .rate = EP93XX_EXT_CLK_RATE, @@ -214,6 +221,7 @@ static struct clk_lookup clocks[] = { INIT_CK(NULL, "pll2", &clk_pll2), INIT_CK("ohci-platform", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), + INIT_CK("ep93xx-adc", NULL, &clk_adc), INIT_CK("ep93xx-fb", NULL, &clk_video), INIT_CK("ep93xx-spi.0", NULL, &clk_spi), INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk), @@ -475,6 +483,26 @@ int clk_set_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL(clk_set_rate); +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + WARN_ON(clk); + return 0; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + WARN_ON(clk); + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index c393b1b0310df78e3cbbea8ef9d7336de7f82d19..f53c6181399868ad232f3dcea8173349d6e76a93 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -820,6 +820,30 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev) } EXPORT_SYMBOL(ep93xx_ide_release_gpio); +/************************************************************************* + * EP93xx ADC + *************************************************************************/ +static struct resource ep93xx_adc_resources[] = { + DEFINE_RES_MEM(EP93XX_ADC_PHYS_BASE, 0x28), + DEFINE_RES_IRQ(IRQ_EP93XX_TOUCH), +}; + +static struct platform_device ep93xx_adc_device = { + .name = "ep93xx-adc", + .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_adc_resources), + .resource = ep93xx_adc_resources, +}; + +void __init ep93xx_register_adc(void) +{ + /* Power up ADC, deactivate Touch Screen Controller */ + ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_TIN, + EP93XX_SYSCON_DEVCFG_ADCPD); + + platform_device_register(&ep93xx_adc_device); +} + /************************************************************************* * EP93xx Security peripheral *************************************************************************/ diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index 0ac176386789428be26631ad1c9f75ad343e8951..7a7f280b07d75af54b6fec1e32b84384a3c6ad25 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -245,6 +245,7 @@ static void __init edb93xx_init_machine(void) edb93xx_register_pwm(); edb93xx_register_fb(); edb93xx_register_ide(); + ep93xx_register_adc(); } diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 4c0bbd97f741c7a6ab90de0260a77e9c4877fb82..db0839691ef5e883fd5f4ea0748f2698332e4d6a 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -52,6 +52,7 @@ int ep93xx_i2s_acquire(void); void ep93xx_i2s_release(void); void ep93xx_register_ac97(void); void ep93xx_register_ide(void); +void ep93xx_register_adc(void); int ep93xx_ide_acquire_gpio(struct platform_device *pdev); void ep93xx_ide_release_gpio(struct platform_device *pdev); diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index b2db791b3b38b0adb69e64ea0cd596356184b483..8b29398f4dc7c78e76d25a092159a8ba59cc539a 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h index 7bf7ff8beae73f28aec97693a9cda48c6a8212bf..d20e631164cfd2dfcd1c638754691d47b0ffbb87 100644 --- a/arch/arm/mach-ep93xx/soc.h +++ b/arch/arm/mach-ep93xx/soc.h @@ -95,6 +95,7 @@ #define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000) #define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) +#define EP93XX_ADC_PHYS_BASE EP93XX_APB_PHYS(0x00100000) #define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) #define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 55b186ef863a64ec31f1a367469e3d9352a11e36..8745162ec05d3a887f940ecd84a0d90d2e736eca 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S index cf950790fbdceb470643b5e8c152394deb2d46e5..4292cae43f3c3ce564dcd1d4a6a8a74cd8239a6e 100644 --- a/arch/arm/mach-exynos/sleep.S +++ b/arch/arm/mach-exynos/sleep.S @@ -124,6 +124,7 @@ _cp15_save_diag: #endif /* CONFIG_CACHE_L2X0 */ .data + .align 2 .globl cp15_save_diag cp15_save_diag: .long 0 @ cp15 diagnostic diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 748cfb8d521247c2073b8cc064d963c1f7ab9eeb..b529ba04ed16656aeefc80eb5a4bb95119b6753d 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -187,21 +187,20 @@ static int __init exynos_pmu_irq_init(struct device_node *node, struct irq_domain *parent_domain, *domain; if (!parent) { - pr_err("%s: no parent, giving up\n", node->full_name); + pr_err("%pOF: no parent, giving up\n", node); return -ENODEV; } parent_domain = irq_find_host(parent); if (!parent_domain) { - pr_err("%s: unable to obtain parent domain\n", node->full_name); + pr_err("%pOF: unable to obtain parent domain\n", node); return -ENXIO; } pmu_base_addr = of_iomap(node, 0); if (!pmu_base_addr) { - pr_err("%s: failed to find exynos pmu register\n", - node->full_name); + pr_err("%pOF: failed to find exynos pmu register\n", node); return -ENOMEM; } diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig index 06c8b095154c5dd39b0c052728d9781ebead099d..70106b67631ca8268b788eaca4dac9eedd547a2c 100644 --- a/arch/arm/mach-gemini/Kconfig +++ b/arch/arm/mach-gemini/Kconfig @@ -1,11 +1,16 @@ menuconfig ARCH_GEMINI bool "Cortina Systems Gemini" depends on ARCH_MULTI_V4 + select ARCH_HAS_RESET_CONTROLLER + select ARM_AMBA select ARM_APPENDED_DTB # Old Redboot bootloaders deployed + select COMMON_CLK_GEMINI select FARADAY_FTINTC010 select FTTMR010_TIMER select GPIO_FTGPIO010 select GPIOLIB + select PINCTRL + select PINCTRL_GEMINI select POWER_RESET select POWER_RESET_GEMINI_POWEROFF select POWER_RESET_SYSCON diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig index a3b091a4d344a43d2a903b5ffaaa672bf742db4a..65a048fa08ec72dbe4b5635853ea0a72c8a6c594 100644 --- a/arch/arm/mach-hisi/Kconfig +++ b/arch/arm/mach-hisi/Kconfig @@ -39,6 +39,7 @@ config ARCH_HIP04 select HAVE_ARM_ARCH_TIMER select MCPM if SMP select MCPM_QUAD_CLUSTER if SMP + select GENERIC_IRQ_EFFECTIVE_AFF_MASK help Support for Hisilicon HiP04 SoC family diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index 91bb02dec20f15a63f438f3ab65fe5dc62a40af7..da5689ababf7b933516f46d70436ad2be44a33b9 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c @@ -109,7 +109,7 @@ static void hix5hd2_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_a virt = ioremap(start_addr, PAGE_SIZE); - writel_relaxed(0xe51ff004, virt); /* ldr pc, [rc, #-4] */ + writel_relaxed(0xe51ff004, virt); /* ldr pc, [pc, #-4] */ writel_relaxed(jump_addr, virt + 4); /* pc jump phy address */ iounmap(virt); } diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 93f584ba0130eb480b001d98946d9981da19d34c..de535cb679b36d58d6cb88106656e1e260c490c0 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -224,13 +224,13 @@ static int __init imx_gpc_init(struct device_node *node, int i; if (!parent) { - pr_err("%s: no parent, giving up\n", node->full_name); + pr_err("%pOF: no parent, giving up\n", node); return -ENODEV; } parent_domain = irq_find_host(parent); if (!parent_domain) { - pr_err("%s: unable to obtain parent domain\n", node->full_name); + pr_err("%pOF: unable to obtain parent domain\n", node); return -ENXIO; } diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index dd75a4756761f347a60fc6107cb9a198db9174e2..5169dfba97185b5037743d2d277d8bb74e063dfa 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -245,7 +245,6 @@ static phys_addr_t mx2_camera_base __initdata; static void __init visstrim_analog_camera_init(void) { struct platform_device *pdev; - int dma; gpio_set_value(TVP5150_PWDN, 1); ndelay(1); @@ -258,12 +257,9 @@ static void __init visstrim_analog_camera_init(void) if (IS_ERR(pdev)) return; - dma = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base, mx2_camera_base, - MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) - return; + dma_declare_coherent_memory(&pdev->dev, mx2_camera_base, + mx2_camera_base, MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); } static void __init visstrim_reserve(void) @@ -444,16 +440,13 @@ static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = { static void __init visstrim_coda_init(void) { struct platform_device *pdev; - int dma; pdev = imx27_add_coda(); - dma = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base + MX2_CAMERA_BUF_SIZE, - mx2_camera_base + MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) - return; + dma_declare_coherent_memory(&pdev->dev, + mx2_camera_base + MX2_CAMERA_BUF_SIZE, + mx2_camera_base + MX2_CAMERA_BUF_SIZE, + MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); } /* DMA deinterlace */ @@ -466,24 +459,21 @@ static void __init visstrim_deinterlace_init(void) { int ret = -ENOMEM; struct platform_device *pdev = &visstrim_deinterlace; - int dma; ret = platform_device_register(pdev); - dma = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, - mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) - return; + dma_declare_coherent_memory(&pdev->dev, + mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, + mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, + MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); } /* Emma-PrP for format conversion */ static void __init visstrim_emmaprp_init(void) { struct platform_device *pdev; - int dma; + int ret; pdev = imx27_add_mx2_emmaprp(); if (IS_ERR(pdev)) @@ -493,11 +483,11 @@ static void __init visstrim_emmaprp_init(void) * Use the same memory area as the analog camera since both * devices are, by nature, exclusive. */ - dma = dma_declare_coherent_memory(&pdev->dev, + ret = dma_declare_coherent_memory(&pdev->dev, mx2_camera_base, mx2_camera_base, MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) + DMA_MEMORY_EXCLUSIVE); + if (ret) pr_err("Failed to declare memory for emmaprp\n"); } diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index bde9a9af67142ad2c3867b998aaee5d0426fda4e..7716f83aecdda1d5f6a35677d40d9446b5d8a0cf 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -475,7 +475,7 @@ static phys_addr_t mx3_camera_base __initdata; static int __init mx31moboard_init_cam(void) { - int dma, ret = -ENOMEM; + int ret; struct platform_device *pdev; imx31_add_ipu_core(); @@ -484,11 +484,11 @@ static int __init mx31moboard_init_cam(void) if (IS_ERR(pdev)) return PTR_ERR(pdev); - dma = dma_declare_coherent_memory(&pdev->dev, - mx3_camera_base, mx3_camera_base, - MX3_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) + ret = dma_declare_coherent_memory(&pdev->dev, + mx3_camera_base, mx3_camera_base, + MX3_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); + if (ret) goto err; ret = platform_device_add(pdev); diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 8c2cbd693d21642be33ae430b2a285ad2a2c694c..42a700053103ebf57b9682a5e6dc9da05629d8a7 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h index 7a0c13bf42694b724e0fcb35439070eefde0a646..844e8ac593e270125980df3ecced92b6d6322f5e 100644 --- a/arch/arm/mach-ixp4xx/include/mach/io.h +++ b/arch/arm/mach-ixp4xx/include/mach/io.h @@ -95,8 +95,10 @@ static inline void __indirect_writeb(u8 value, volatile void __iomem *p) } static inline void __indirect_writesb(volatile void __iomem *bus_addr, - const u8 *vaddr, int count) + const void *p, int count) { + const u8 *vaddr = p; + while (count--) writeb(*vaddr++, bus_addr); } @@ -118,8 +120,10 @@ static inline void __indirect_writew(u16 value, volatile void __iomem *p) } static inline void __indirect_writesw(volatile void __iomem *bus_addr, - const u16 *vaddr, int count) + const void *p, int count) { + const u16 *vaddr = p; + while (count--) writew(*vaddr++, bus_addr); } @@ -137,8 +141,9 @@ static inline void __indirect_writel(u32 value, volatile void __iomem *p) } static inline void __indirect_writesl(volatile void __iomem *bus_addr, - const u32 *vaddr, int count) + const void *p, int count) { + const u32 *vaddr = p; while (count--) writel(*vaddr++, bus_addr); } @@ -160,8 +165,10 @@ static inline u8 __indirect_readb(const volatile void __iomem *p) } static inline void __indirect_readsb(const volatile void __iomem *bus_addr, - u8 *vaddr, u32 count) + void *p, u32 count) { + u8 *vaddr = p; + while (count--) *vaddr++ = readb(bus_addr); } @@ -183,8 +190,10 @@ static inline u16 __indirect_readw(const volatile void __iomem *p) } static inline void __indirect_readsw(const volatile void __iomem *bus_addr, - u16 *vaddr, u32 count) + void *p, u32 count) { + u16 *vaddr = p; + while (count--) *vaddr++ = readw(bus_addr); } @@ -204,8 +213,10 @@ static inline u32 __indirect_readl(const volatile void __iomem *p) } static inline void __indirect_readsl(const volatile void __iomem *bus_addr, - u32 *vaddr, u32 count) + void *p, u32 count) { + u32 *vaddr = p; + while (count--) *vaddr++ = readl(bus_addr); } @@ -523,8 +534,15 @@ static inline void iowrite32_rep(void __iomem *addr, const void *vaddr, #endif } -#define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET)) -#define ioport_unmap(addr) +#define ioport_map(port, nr) ioport_map(port, nr) +static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return ((void __iomem*)((port) + PIO_OFFSET)); +} +#define ioport_unmap(addr) ioport_unmap(addr) +static inline void ioport_unmap(void __iomem *addr) +{ +} #endif /* CONFIG_PCI */ #endif /* __ASM_ARM_ARCH_IO_H */ diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 508c2d7786e2ec8389f97bb55bf446d3e323d198..93b89291c06be2baa7b981c6d493c290c48ab73b 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c index c3cf215773b2de6228abbd27cc89ca234512f7f8..6910b4e0d913bc9f3e02a7f846c42d32676306bd 100644 --- a/arch/arm/mach-mediatek/mediatek.c +++ b/arch/arm/mach-mediatek/mediatek.c @@ -30,6 +30,7 @@ static void __init mediatek_timer_init(void) if (of_machine_is_compatible("mediatek,mt6589") || of_machine_is_compatible("mediatek,mt7623") || + of_machine_is_compatible("mediatek,mt7623a") || of_machine_is_compatible("mediatek,mt8135") || of_machine_is_compatible("mediatek,mt8127")) { /* turn on GPT6 which ungates arch timer clocks */ @@ -49,6 +50,7 @@ static const char * const mediatek_board_dt_compat[] = { "mediatek,mt6589", "mediatek,mt6592", "mediatek,mt7623", + "mediatek,mt7623a", "mediatek,mt8127", "mediatek,mt8135", NULL, diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index 726eb69bb655decfbd7a817bdddcb8946c761dc4..27d78c945cafc60c87b4e9913d749855f7bfdba1 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -59,6 +59,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { static const struct of_device_id mtk_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, + { .compatible = "mediatek,mt7623a", .data = &mtk_mt7623_boot }, }; static void __iomem *mtk_smp_base; diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 5db0edf716dd1265accce7aa3017adbac538ab1d..d2283009a5ff1a0b09a9b200ecb2ed1d490ed1be 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c index 3330ac7cfbefc78388b78ad06a47ab102a9d9a79..671c7a09ab3d65a43b1effae5fd3bffbcb9c22cb 100644 --- a/arch/arm/mach-mmp/devices.c +++ b/arch/arm/mach-mmp/devices.c @@ -238,7 +238,7 @@ void pxa_usb_phy_deinit(void __iomem *phy_reg) #endif #if IS_ENABLED(CONFIG_USB_SUPPORT) -static u64 usb_dma_mask = ~(u32)0; +static u64 __maybe_unused usb_dma_mask = ~(u32)0; #if IS_ENABLED(CONFIG_USB_MV_UDC) struct resource pxa168_u2o_resources[] = { diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 541647f5719255cfd755a22b0435f97426e92612..9b49867154bfba3f3a2a5d589219c48fd381669a 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -60,6 +60,8 @@ config MACH_ARMADA_38X select ARM_ERRATA_720789 select ARM_ERRATA_753970 select ARM_GIC + select ARM_GLOBAL_TIMER + select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK select ARMADA_370_XP_IRQ select ARMADA_38X_CLK select HAVE_ARM_SCU diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c index 7d9f2fd9e450512ebd798eaa56ba6841b690fec4..0aa88105d46e5423c1d98d29ca0f65ab7968f143 100644 --- a/arch/arm/mach-mvebu/kirkwood.c +++ b/arch/arm/mach-mvebu/kirkwood.c @@ -107,8 +107,7 @@ static void __init kirkwood_dt_eth_fixup(void) clk_prepare_enable(clk); /* store MAC address register contents in local-mac-address */ - pr_err(FW_INFO "%s: local-mac-address is not set\n", - np->full_name); + pr_err(FW_INFO "%pOF: local-mac-address is not set\n", np); pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); if (!pmac) diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index e62273aacb43681f2bd8ab0c7e95d82d2c32020f..4ffbbd217e8286e18181fac98487a8860ead6372 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -211,7 +211,7 @@ static int mv98dx3236_resume_set_cpu_boot_addr(int hw_cpu, void *boot_addr) return PTR_ERR(base); writel(0, base + MV98DX3236_CPU_RESUME_CTRL_REG); - writel(virt_to_phys(boot_addr), base + MV98DX3236_CPU_RESUME_ADDR_REG); + writel(__pa_symbol(boot_addr), base + MV98DX3236_CPU_RESUME_ADDR_REG); iounmap(base); diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 6613a6ff5dbc9e35512ac94fd84904ddf2a63ee1..6cbc69c92913dbc4074a65e269bb5243e9193cdb 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -510,6 +510,7 @@ static void __init ams_delta_init(void) static void modem_pm(struct uart_port *port, unsigned int state, unsigned old) { struct modem_private_data *priv = port->private_data; + int ret; if (IS_ERR(priv->regulator)) return; @@ -518,9 +519,16 @@ static void modem_pm(struct uart_port *port, unsigned int state, unsigned old) return; if (state == 0) - regulator_enable(priv->regulator); + ret = regulator_enable(priv->regulator); else if (old == 0) - regulator_disable(priv->regulator); + ret = regulator_disable(priv->regulator); + else + ret = 0; + + if (ret) + dev_warn(port->dev, + "ams_delta modem_pm: failed to %sable regulator: %d\n", + state ? "dis" : "en", ret); } static struct plat_serial8250_port ams_delta_modem_ports[] = { diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index fad95b74bb65db16ed09aa21f4f0634cf445b937..b93ad58b0a63fc3f5694d2e7fe76e0240f66e8ca 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c index 357be2debc9da8334d232c49fc75f82c1bd3a23a..91bda9c802ff38047832cbcb7e5dcf355265bb46 100644 --- a/arch/arm/mach-omap1/board-h2-mmc.c +++ b/arch/arm/mach-omap1/board-h2-mmc.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "board-h2.h" #include "mmc.h" diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 675254ee4b1e936365fde71402bd9f4a256f74e5..6a38c76030644362019375e3195333cd627ef396 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -24,11 +24,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c index 4f58bfa5e7549ec8eeb3188f932b1b9d3287a9ed..692c267a9a9052dab5a544d24ce7ccdcc8e3cdae 100644 --- a/arch/arm/mach-omap1/board-h3-mmc.c +++ b/arch/arm/mach-omap1/board-h3-mmc.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include "common.h" #include "board-h3.h" diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index e62f9d454f100546ccd02fbf0fbcd5bcf30a0208..302260583e8ea5d8b50ad9b0ae820679fa422b31 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -23,12 +23,12 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-nand.c b/arch/arm/mach-omap1/board-nand.c index 7684f9203474386eafbd3d974dbcfa5a30b24989..1bffbb4e050f2c1823cfaa18c7829deecad3c634 100644 --- a/arch/arm/mach-omap1/board-nand.c +++ b/arch/arm/mach-omap1/board-nand.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index ee8d9f553db448d2770d12c4afd04ed6b1f92904..06243c0b12d2fe18a69c874fb1e40a3688e0552a 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -233,10 +233,10 @@ static struct platform_device nokia770_cbus_device = { static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = { { - I2C_BOARD_INFO("retu-mfd", 0x01), + I2C_BOARD_INFO("retu", 0x01), }, { - I2C_BOARD_INFO("tahvo-mfd", 0x02), + I2C_BOARD_INFO("tahvo", 0x02), }, }; diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 4dfb995048103b8bff965b6119f3665e54887a40..d579f4e04137433a1413f039e2432fd2f4c92b25 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -441,13 +441,11 @@ static struct spi_board_info __initdata mistral_boardinfo[] = { { .chip_select = 0, } }; -#ifdef CONFIG_PM static irqreturn_t osk_mistral_wake_interrupt(int irq, void *ignored) { return IRQ_HANDLED; } -#endif static void __init osk_mistral_init(void) { @@ -515,7 +513,6 @@ static void __init osk_mistral_init(void) gpio_direction_input(OMAP_MPUIO(2)); irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); -#ifdef CONFIG_PM /* share the IRQ in case someone wants to use the * button for more than wakeup from system sleep. */ @@ -529,7 +526,6 @@ static void __init osk_mistral_init(void) ret); } else enable_irq_wake(irq); -#endif } else printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n"); diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 150b57ba42bfcd8d4a584a6d780f0456e842a608..e994a78bdd09a92954ef3e0bd3354f497b7d5715 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 0465338183c706721d94d356683fad3fa17a4435..e31a5a22e1716379a7d1fdd564ecb6702361dc6b 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -87,6 +87,7 @@ config SOC_DRA7XX select OMAP_INTERCONNECT_BARRIER select PM_OPP if PM select ZONE_DMA if ARM_LPAE + select PINCTRL_TI_IODELAY if OF && PINCTRL config ARCH_OMAP2PLUS bool diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 779fb1f680b339dd9e4fb88826fffb5127d00dd2..b3b3b3a19183507f736669ebc4f6a55302dfb571 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -8,7 +8,7 @@ ccflags-y := -I$(srctree)/$(src)/include \ # Common support obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \ common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ - omap_device.o omap-headsmp.o sram.o drm.o + omap_device.o omap-headsmp.o sram.o hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ omap_hwmod_common_data.o diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index dc9e34e670a26f280bdfe7947fa8709ee750465f..6c61ecc62905a37021979b0f1c3074b98bd532ca 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -28,11 +28,12 @@ static const struct of_device_id omap_dt_match_table[] __initconst = { { } }; -static void __init omap_generic_init(void) +static void __init __maybe_unused omap_generic_init(void) { pdata_quirks_init(omap_dt_match_table); omapdss_init_of(); + omap_soc_device_init(); } #ifdef CONFIG_SOC_OMAP2420 @@ -312,6 +313,7 @@ MACHINE_END #ifdef CONFIG_SOC_DRA7XX static const char *const dra74x_boards_compat[] __initconst = { + "ti,dra762", "ti,am5728", "ti,am5726", "ti,dra742", diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 8cc6338fcb1288022854d7bb3347b9e000139c76..b5ad7fcb80ed24e06e1a84528bdbe4960b77c64b 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 8fa01c0ecdb29ab9b3a9057a23bf610ce3070447..b3f6eb5d04a260226eaa46e17b476e11ecb6e274 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -66,6 +66,7 @@ */ #define FRAMEDONE_IRQ_TIMEOUT 100 +#if defined(CONFIG_FB_OMAP2) static struct platform_device omap_display_device = { .name = "omapdss", .id = -1, @@ -163,6 +164,65 @@ static enum omapdss_version __init omap_display_get_version(void) return OMAPDSS_VER_UNKNOWN; } +static int __init omapdss_init_fbdev(void) +{ + static struct omap_dss_board_info board_data = { + .dsi_enable_pads = omap_dsi_enable_pads, + .dsi_disable_pads = omap_dsi_disable_pads, + .set_min_bus_tput = omap_dss_set_min_bus_tput, + }; + struct device_node *node; + int r; + + board_data.version = omap_display_get_version(); + if (board_data.version == OMAPDSS_VER_UNKNOWN) { + pr_err("DSS not supported on this SoC\n"); + return -ENODEV; + } + + omap_display_device.dev.platform_data = &board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) { + pr_err("Unable to register omapdss device\n"); + return r; + } + + /* create vrfb device */ + r = omap_init_vrfb(); + if (r < 0) { + pr_err("Unable to register omapvrfb device\n"); + return r; + } + + /* create FB device */ + r = omap_init_fb(); + if (r < 0) { + pr_err("Unable to register omapfb device\n"); + return r; + } + + /* create V4L2 display device */ + r = omap_init_vout(); + if (r < 0) { + pr_err("Unable to register omap_vout device\n"); + return r; + } + + /* add DSI info for omap4 */ + node = of_find_node_by_name(NULL, "omap4_padconf_global"); + if (node) + omap4_dsi_mux_syscon = syscon_node_to_regmap(node); + + return 0; +} +#else +static inline int omapdss_init_fbdev(void) +{ + return 0; +} +#endif /* CONFIG_FB_OMAP2 */ + static void dispc_disable_outputs(void) { u32 v, irq_mask = 0; @@ -335,16 +395,9 @@ static struct device_node * __init omapdss_find_dss_of_node(void) int __init omapdss_init_of(void) { int r; - enum omapdss_version ver; struct device_node *node; struct platform_device *pdev; - static struct omap_dss_board_info board_data = { - .dsi_enable_pads = omap_dsi_enable_pads, - .dsi_disable_pads = omap_dsi_disable_pads, - .set_min_bus_tput = omap_dss_set_min_bus_tput, - }; - /* only create dss helper devices if dss is enabled in the .dts */ node = omapdss_find_dss_of_node(); @@ -354,13 +407,6 @@ int __init omapdss_init_of(void) if (!of_device_is_available(node)) return 0; - ver = omap_display_get_version(); - - if (ver == OMAPDSS_VER_UNKNOWN) { - pr_err("DSS not supported on this SoC\n"); - return -ENODEV; - } - pdev = of_find_device_by_node(node); if (!pdev) { @@ -374,48 +420,5 @@ int __init omapdss_init_of(void) return r; } - board_data.version = ver; - - omap_display_device.dev.platform_data = &board_data; - - r = platform_device_register(&omap_display_device); - if (r < 0) { - pr_err("Unable to register omapdss device\n"); - return r; - } - - /* create DRM device */ - r = omap_init_drm(); - if (r < 0) { - pr_err("Unable to register omapdrm device\n"); - return r; - } - - /* create vrfb device */ - r = omap_init_vrfb(); - if (r < 0) { - pr_err("Unable to register omapvrfb device\n"); - return r; - } - - /* create FB device */ - r = omap_init_fb(); - if (r < 0) { - pr_err("Unable to register omapfb device\n"); - return r; - } - - /* create V4L2 display device */ - r = omap_init_vout(); - if (r < 0) { - pr_err("Unable to register omap_vout device\n"); - return r; - } - - /* add DSI info for omap4 */ - node = of_find_node_by_name(NULL, "omap4_padconf_global"); - if (node) - omap4_dsi_mux_syscon = syscon_node_to_regmap(node); - - return 0; + return omapdss_init_fbdev(); } diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h index 9a39646d43160c2152a2bea1a5b39ac6b7ede63f..42ec2e99a2f4830193af2e6ceb5415c24698f417 100644 --- a/arch/arm/mach-omap2/display.h +++ b/arch/arm/mach-omap2/display.h @@ -26,7 +26,6 @@ struct omap_dss_dispc_dev_attr { bool has_framedonetv_irq; }; -int omap_init_drm(void); int omap_init_vrfb(void); int omap_init_fb(void); int omap_init_vout(void); diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 0b77a01760184edf3694e208b6e526a2352c144a..694ce0939d50f2e8182fbf5c12cf90220d544d45 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -204,61 +204,6 @@ static unsigned configure_dma_errata(void) return errata; } -static const struct dma_slave_map omap24xx_sdma_map[] = { - { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, - { "omap-aes", "tx", SDMA_FILTER_PARAM(9) }, - { "omap-aes", "rx", SDMA_FILTER_PARAM(10) }, - { "omap-sham", "rx", SDMA_FILTER_PARAM(13) }, - { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, - { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, - { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, - { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, - { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, - { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, - { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, - { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, - { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, - { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, - { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, - { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, - { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, - { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, - { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, - { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, - { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, - { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, - { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, - { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, - { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, - { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, - { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, - { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, - { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, - { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, - { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, - { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, - { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, - { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, - { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, - { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, - { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, - { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, - { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, - { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, - { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, - { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, - { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, - { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, - - /* external DMA requests when tusb6010 is used */ - { "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) }, - { "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) }, - { "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */ - { "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */ - { "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */ - { "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ -}; - static const struct dma_slave_map omap24xx_sdma_dt_map[] = { /* external DMA requests when tusb6010 is used */ { "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) }, @@ -269,61 +214,6 @@ static const struct dma_slave_map omap24xx_sdma_dt_map[] = { { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ }; -static const struct dma_slave_map omap3xxx_sdma_map[] = { - { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, - { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, - { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, - { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, - { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, - { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, - { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, - { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, - { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, - { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, - { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, - { "omap_i2c.3", "tx", SDMA_FILTER_PARAM(25) }, - { "omap_i2c.3", "rx", SDMA_FILTER_PARAM(26) }, - { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, - { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, - { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, - { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, - { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, - { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, - { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, - { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, - { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, - { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, - { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, - { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, - { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, - { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, - { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, - { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, - { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, - { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, - { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, - { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, - { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, - { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, - { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, - { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, - { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, - { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, - { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, - { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, - { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, - { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, - { "omap-aes", "tx", SDMA_FILTER_PARAM(65) }, - { "omap-aes", "rx", SDMA_FILTER_PARAM(66) }, - { "omap-sham", "rx", SDMA_FILTER_PARAM(69) }, - { "omap2_mcspi.3", "tx0", SDMA_FILTER_PARAM(70) }, - { "omap2_mcspi.3", "rx0", SDMA_FILTER_PARAM(71) }, - { "omap_hsmmc.2", "tx", SDMA_FILTER_PARAM(77) }, - { "omap_hsmmc.2", "rx", SDMA_FILTER_PARAM(78) }, - { "omap_uart.3", "tx", SDMA_FILTER_PARAM(81) }, - { "omap_uart.3", "rx", SDMA_FILTER_PARAM(82) }, -}; - static struct omap_system_dma_plat_info dma_plat_info __initdata = { .reg_map = reg_map, .channel_stride = 0x60, @@ -352,24 +242,10 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; p.errata = configure_dma_errata(); - if (!of_have_populated_dt()) { - if (soc_is_omap24xx()) { - p.slave_map = omap24xx_sdma_map; - p.slavecnt = ARRAY_SIZE(omap24xx_sdma_map); - } else if (soc_is_omap34xx() || soc_is_omap3630()) { - p.slave_map = omap3xxx_sdma_map; - p.slavecnt = ARRAY_SIZE(omap3xxx_sdma_map); - } else { - pr_err("%s: The legacy DMA map is not provided!\n", - __func__); - return -ENODEV; - } - } else { - if (soc_is_omap24xx()) { - /* DMA slave map for drivers not yet converted to DT */ - p.slave_map = omap24xx_sdma_dt_map; - p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map); - } + if (soc_is_omap24xx()) { + /* DMA slave map for drivers not yet converted to DT */ + p.slave_map = omap24xx_sdma_dt_map; + p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map); } pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); @@ -413,21 +289,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) static int __init omap2_system_dma_init(void) { - struct platform_device *pdev; - int res; - - res = omap_hwmod_for_each_by_class("dma", + return omap_hwmod_for_each_by_class("dma", omap2_system_dma_init_dev, NULL); - if (res) - return res; - - if (of_have_populated_dt()) - return res; - - pdev = platform_device_register_full(&omap_dma_dev_info); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - return res; } omap_arch_initcall(omap2_system_dma_init); diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c deleted file mode 100644 index 44fef961bb70d8baddb9560de32f975753989e26..0000000000000000000000000000000000000000 --- a/arch/arm/mach-omap2/drm.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * DRM/KMS device registration for TI OMAP platforms - * - * Copyright (C) 2012 Texas Instruments - * Author: Rob Clark - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "soc.h" -#include "display.h" - -#if IS_ENABLED(CONFIG_DRM_OMAP) - -static struct omap_drm_platform_data platform_data; - -static struct platform_device omap_drm_device = { - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &platform_data, - }, - .name = "omapdrm", - .id = 0, -}; - -int __init omap_init_drm(void) -{ - platform_data.omaprev = GET_OMAP_TYPE; - - return platform_device_register(&omap_drm_device); - -} -#else -int __init omap_init_drm(void) { return 0; } -#endif diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 5b614388d72f4b7ca8be1c851f1369f719ce2c29..6d28aa20a7d32c4142dba9a52cbaa06fc6c387f1 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -58,10 +58,10 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) struct platform_device *pdev; int res; - if (omap_hsmmc_done != 1) + if (omap_hsmmc_done) return; - omap_hsmmc_done++; + omap_hsmmc_done = 1; for (; c->mmc; c++) { pdev = c->pdev; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index e2274a162b74d688d56a4a6b67823db04345179d..16cb1c195fd8ef775c328b1273507875a9e6806b 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -663,6 +663,15 @@ void __init dra7xxx_check_revision(void) hawkeye = (idcode >> 12) & 0xffff; rev = (idcode >> 28) & 0xff; switch (hawkeye) { + case 0xbb50: + switch (rev) { + case 0: + default: + omap_revision = DRA762_REV_ES1_0; + break; + } + break; + case 0xb990: switch (rev) { case 0: diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 1d739d1a0a657aec9ee73450154ff5b5197f8939..cb5d7314cf996a3c844c476de84715bdb794328e 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -410,7 +410,7 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); } -static void __init omap_hwmod_init_postsetup(void) +static void __init __maybe_unused omap_hwmod_init_postsetup(void) { u8 postsetup_state; @@ -428,7 +428,6 @@ static void __init omap_hwmod_init_postsetup(void) static void __init __maybe_unused omap_common_late_init(void) { omap2_common_pm_late_init(); - omap_soc_device_init(); } #ifdef CONFIG_SOC_OMAP2420 diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 33e4953c61a8843b5dde41994b30ea41c52a0abf..69df3620eca5ce1720f88ab86cf5a36df891d7e7 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -342,7 +342,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) c = &omap443x_cfg; else if (soc_is_omap446x()) c = &omap446x_cfg; - else if (soc_is_dra74x() || soc_is_omap54xx()) + else if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x()) c = &omap5_cfg; if (!c) { @@ -355,7 +355,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) cfg.startup_addr = c->startup_addr; cfg.wakeupgen_base = omap_get_wakeupgen_base(); - if (soc_is_dra74x() || soc_is_omap54xx()) { + if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x()) { if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) cfg.startup_addr = omap5_secondary_hyp_startup; omap5_erratum_workaround_801819(); diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 33ed5d53fa459d718d7fac0690846f50f8c1a144..4bb6751864a50e046e74c0952ad75571e1d979d0 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -522,13 +522,13 @@ static int __init wakeupgen_init(struct device_node *node, u32 val; if (!parent) { - pr_err("%s: no parent, giving up\n", node->full_name); + pr_err("%pOF: no parent, giving up\n", node); return -ENODEV; } parent_domain = irq_find_host(parent); if (!parent_domain) { - pr_err("%s: unable to obtain parent domain\n", node->full_name); + pr_err("%pOF: unable to obtain parent domain\n", node); return -ENXIO; } /* Not supported on OMAP4 ES1.0 silicon */ diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index ef9ffb8ac9126d6cc744475d9a12f2f90994404e..acbede082b5b54f29a36e2cfd08f9bd23d1d7246 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -672,7 +672,6 @@ static int _od_suspend_noirq(struct device *dev) if (!ret && !pm_runtime_status_suspended(dev)) { if (pm_generic_runtime_suspend(dev) == 0) { - pm_runtime_set_suspended(dev); omap_device_idle(pdev); od->flags |= OMAP_DEVICE_SUSPENDED; } @@ -689,15 +688,6 @@ static int _od_resume_noirq(struct device *dev) if (od->flags & OMAP_DEVICE_SUSPENDED) { od->flags &= ~OMAP_DEVICE_SUSPENDED; omap_device_enable(pdev); - /* - * XXX: we run before core runtime pm has resumed itself. At - * this point in time, we just restore the runtime pm state and - * considering symmetric operations in resume, we donot expect - * to fail. If we failed, something changed in core runtime_pm - * framework OR some device driver messed things up, hence, WARN - */ - WARN(pm_runtime_set_active(dev), - "Could not set %s runtime state active\n", dev_name(dev)); pm_generic_runtime_resume(dev); } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 3b47ded5fa0cb768617aea1d73429951ac061eaa..2dbd63239c5486fcba38476ed00f4c208448e899 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2417,8 +2417,8 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, if (mem) pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); else - pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n", - oh->name, index, np->full_name); + pr_err("omap_hwmod: %s: Missing dt reg%i for %pOF\n", + oh->name, index, np); return -ENXIO; } diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index b3abb8d8b2f6add6af321ecadc1a7ed9ca158cca..2f4f7002f38d0138e9d8cb9cb2d3cb9d97237675 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -839,6 +839,7 @@ static struct omap_hwmod dra7xx_gpio1_hwmod = { .name = "gpio1", .class = &dra7xx_gpio_hwmod_class, .clkdm_name = "wkupaon_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .main_clk = "wkupaon_iclk_mux", .prcm = { .omap4 = { @@ -4070,6 +4071,11 @@ static struct omap_hwmod_ocp_if *dra7xx_gp_hwmod_ocp_ifs[] __initdata = { }; /* SoC variant specific hwmod links */ +static struct omap_hwmod_ocp_if *dra76x_hwmod_ocp_ifs[] __initdata = { + &dra7xx_l4_per3__usb_otg_ss4, + NULL, +}; + static struct omap_hwmod_ocp_if *dra74x_hwmod_ocp_ifs[] __initdata = { &dra7xx_l4_per3__usb_otg_ss4, NULL, @@ -4095,12 +4101,14 @@ int __init dra7xx_hwmod_init(void) ret = omap_hwmod_register_links(dra74x_hwmod_ocp_ifs); else if (!ret && soc_is_dra72x()) ret = omap_hwmod_register_links(dra72x_hwmod_ocp_ifs); + else if (!ret && soc_is_dra76x()) + ret = omap_hwmod_register_links(dra76x_hwmod_ocp_ifs); if (!ret && omap_type() == OMAP2_DEVICE_TYPE_GP) ret = omap_hwmod_register_links(dra7xx_gp_hwmod_ocp_ifs); - /* now for the IPs *NOT* in dra71 */ - if (!ret && !of_machine_is_compatible("ti,dra718")) + /* now for the IPs available only in dra74 and dra72 */ + if (!ret && !of_machine_is_compatible("ti,dra718") && !soc_is_dra76x()) ret = omap_hwmod_register_links(dra74x_dra72x_hwmod_ocp_ifs); return ret; diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 1346b3ab34a5e39b319dcbb718fec2cfb2423d9a..295124b248ae3f6e7f0de9495954478cfa3b23db 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "soc.h" #include "voltage.h" diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 9700a8ef0f1676bafe1405bddbc25b2076df4e05..6b433fce65a5beaaab3b3cd0e1d23853ac0d26d0 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -434,6 +434,26 @@ static void __init omap5_uevm_legacy_init(void) } #endif +#ifdef CONFIG_SOC_DRA7XX +static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1; +static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2; +static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3; + +static void __init dra7x_evm_mmc_quirk(void) +{ + if (omap_rev() == DRA752_REV_ES1_1 || omap_rev() == DRA752_REV_ES1_0) { + dra7_hsmmc_data_mmc1.version = "rev11"; + dra7_hsmmc_data_mmc1.max_freq = 96000000; + + dra7_hsmmc_data_mmc2.version = "rev11"; + dra7_hsmmc_data_mmc2.max_freq = 48000000; + + dra7_hsmmc_data_mmc3.version = "rev11"; + dra7_hsmmc_data_mmc3.max_freq = 48000000; + } +} +#endif + static struct pcs_pdata pcs_pdata; void omap_pcs_legacy_init(int irq, void (*rearm)(void)) @@ -560,6 +580,14 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { &omap4_iommu_pdata), OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu", &omap4_iommu_pdata), +#endif +#ifdef CONFIG_SOC_DRA7XX + OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x4809c000, "4809c000.mmc", + &dra7_hsmmc_data_mmc1), + OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480b4000, "480b4000.mmc", + &dra7_hsmmc_data_mmc2), + OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480ad000, "480ad000.mmc", + &dra7_hsmmc_data_mmc3), #endif /* Common auxdata */ OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata), @@ -589,6 +617,9 @@ static struct pdata_init pdata_quirks[] __initdata = { #endif #ifdef CONFIG_SOC_OMAP5 { "ti,omap5-uevm", omap5_uevm_legacy_init, }, +#endif +#ifdef CONFIG_SOC_DRA7XX + { "ti,dra7-evm", dra7x_evm_mmc_quirk, }, #endif { /* sentinel */ }, }; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index d44e0e2f11063134e9dd031c0a55b523dd76befa..841ba19d64a69b153a38ef594220d1a4054d7e59 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -486,7 +486,6 @@ int __init omap3_pm_init(void) ret = request_irq(omap_prcm_event_to_irq("io"), _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io", omap3_pm_init); - enable_irq(omap_prcm_event_to_irq("io")); if (ret) { pr_err("pm: Failed to request pm_io irq\n"); diff --git a/arch/arm/mach-omap2/powerdomains7xx_data.c b/arch/arm/mach-omap2/powerdomains7xx_data.c index eb350a67313367ca8c3fe405f0119c7225832180..f50963916a211382aea622c9a26f755f4fad08ad 100644 --- a/arch/arm/mach-omap2/powerdomains7xx_data.c +++ b/arch/arm/mach-omap2/powerdomains7xx_data.c @@ -29,6 +29,7 @@ #include "prcm44xx.h" #include "prm7xx.h" #include "prcm_mpu7xx.h" +#include "soc.h" /* iva_7xx_pwrdm: IVA-HD power domain */ static struct powerdomain iva_7xx_pwrdm = { @@ -63,6 +64,14 @@ static struct powerdomain custefuse_7xx_pwrdm = { .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; +/* custefuse_aon_7xx_pwrdm: Customer efuse controller power domain */ +static struct powerdomain custefuse_aon_7xx_pwrdm = { + .name = "custefuse_pwrdm", + .prcm_offs = DRA7XX_PRM_CUSTEFUSE_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + /* ipu_7xx_pwrdm: Audio back end power domain */ static struct powerdomain ipu_7xx_pwrdm = { .name = "ipu_pwrdm", @@ -350,7 +359,6 @@ static struct powerdomain eve1_7xx_pwrdm = { static struct powerdomain *powerdomains_dra7xx[] __initdata = { &iva_7xx_pwrdm, &rtc_7xx_pwrdm, - &custefuse_7xx_pwrdm, &ipu_7xx_pwrdm, &dss_7xx_pwrdm, &l4per_7xx_pwrdm, @@ -374,9 +382,32 @@ static struct powerdomain *powerdomains_dra7xx[] __initdata = { NULL }; +static struct powerdomain *powerdomains_dra76x[] __initdata = { + &custefuse_aon_7xx_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_dra74x[] __initdata = { + &custefuse_7xx_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_dra72x[] __initdata = { + &custefuse_aon_7xx_pwrdm, + NULL +}; + void __init dra7xx_powerdomains_init(void) { pwrdm_register_platform_funcs(&omap4_pwrdm_operations); pwrdm_register_pwrdms(powerdomains_dra7xx); + + if (soc_is_dra76x()) + pwrdm_register_pwrdms(powerdomains_dra76x); + else if (soc_is_dra74x()) + pwrdm_register_pwrdms(powerdomains_dra74x); + else if (soc_is_dra72x()) + pwrdm_register_pwrdms(powerdomains_dra72x); + pwrdm_complete_init(); } diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 382e236fbfd9a188a91aba9e731436dfca86dd02..a2dd13217c891d269d6832ab014130ad66e1b986 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -692,7 +692,6 @@ static int omap3xxx_prm_late_init(void) { struct device_node *np; int irq_num; - int ret; if (!(prm_features & PRM_HAS_IO_WAKEUP)) return 0; @@ -707,17 +706,13 @@ static int omap3xxx_prm_late_init(void) np = of_find_matching_node(NULL, omap3_prm_dt_match_table); if (np) { irq_num = of_irq_get(np, 0); - if (irq_num >= 0) + if (irq_num > 0) omap3_prcm_irq_setup.irq = irq_num; } omap3xxx_prm_enable_io_wakeup(); - ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); - if (!ret) - irq_set_status_flags(omap_prcm_event_to_irq("io"), - IRQ_NOAUTOEN); - return ret; + return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); } static void __exit omap3xxx_prm_exit(void) diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 87e86a4a9eadd7f6a544fb04e228a791268e6d73..1c0c1663f078ae583c0b43350c01c2379c85e276 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -336,6 +336,27 @@ static void omap44xx_prm_reconfigure_io_chain(void) return; } +/** + * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches + * + * Activates the I/O wakeup event latches and allows events logged by + * those latches to signal a wakeup event to the PRCM. For I/O wakeups + * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and + * omap44xx_prm_reconfigure_io_chain() must be called. No return value. + */ +static void __init omap44xx_prm_enable_io_wakeup(void) +{ + s32 inst = omap4_prmst_get_prm_dev_inst(); + + if (inst == PRM_INSTANCE_UNKNOWN) + return; + + omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_GLOBAL_WUEN_MASK, + inst, + omap4_prcm_irq_setup.pm_ctrl); +} + /** * omap44xx_prm_read_reset_sources - return the last SoC reset source * @@ -668,6 +689,8 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_has_voltdm = omap4_check_vcvp, }; +static int omap44xx_prm_late_init(void); + /* * XXX document */ @@ -675,6 +698,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = { .read_reset_sources = &omap44xx_prm_read_reset_sources, .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, + .late_init = &omap44xx_prm_late_init, .assert_hardreset = omap4_prminst_assert_hardreset, .deassert_hardreset = omap4_prminst_deassert_hardreset, .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, @@ -711,6 +735,37 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data) return prm_register(&omap44xx_prm_ll_data); } +static int omap44xx_prm_late_init(void) +{ + int irq_num; + + if (!(prm_features & PRM_HAS_IO_WAKEUP)) + return 0; + + irq_num = of_irq_get(prm_init_data->np, 0); + /* + * Already have OMAP4 IRQ num. For all other platforms, we need + * IRQ numbers from DT + */ + if (irq_num <= 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) { + if (irq_num == -EPROBE_DEFER) + return irq_num; + + /* Have nothing to do */ + return 0; + } + + /* Once OMAP4 DT is filled as well */ + if (irq_num > 0) { + omap4_prcm_irq_setup.irq = irq_num; + omap4_prcm_irq_setup.xlate_irq = NULL; + } + + omap44xx_prm_enable_io_wakeup(); + + return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); +} + static void __exit omap44xx_prm_exit(void) { prm_unregister(&omap44xx_prm_ll_data); diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 1b9f0520dea9154afa31f9668241e03f211fdc6a..fa5fd24f524c5cb233dfb72d73c23929084d7caa 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -530,10 +530,12 @@ l2dis_3630_offset: .long l2dis_3630 - . .data + .align 2 l2dis_3630: .word 0 .data + .align 2 l2_inv_api_params: .word 0x1, 0x00 diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index c7a3b4aab4b5441249ddd9a7fdc362ef9370d737..56dfa2d5d0a8fc2b1f6c251f762aec2385464423 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -385,6 +385,7 @@ ppa_zero_params_offset: ENDPROC(omap_do_wfi) .data + .align 2 ppa_zero_params: .word 0 diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 2aa01c270898fe64e1fc262efeb1090654b6530c..754cd0fc0e7b5302bb283033784319f85df65da8 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -167,6 +167,7 @@ IS_TI_SUBCLASS(816x, 0x816) IS_TI_SUBCLASS(814x, 0x814) IS_AM_SUBCLASS(335x, 0x335) IS_AM_SUBCLASS(437x, 0x437) +IS_DRA_SUBCLASS(76x, 0x76) IS_DRA_SUBCLASS(75x, 0x75) IS_DRA_SUBCLASS(72x, 0x72) @@ -185,6 +186,7 @@ IS_DRA_SUBCLASS(72x, 0x72) #define soc_is_omap54xx() 0 #define soc_is_omap543x() 0 #define soc_is_dra7xx() 0 +#define soc_is_dra76x() 0 #define soc_is_dra74x() 0 #define soc_is_dra72x() 0 @@ -314,9 +316,11 @@ IS_OMAP_TYPE(3430, 0x3430) #if defined(CONFIG_SOC_DRA7XX) #undef soc_is_dra7xx +#undef soc_is_dra76x #undef soc_is_dra74x #undef soc_is_dra72x #define soc_is_dra7xx() is_dra7xx() +#define soc_is_dra76x() is_dra76x() #define soc_is_dra74x() is_dra75x() #define soc_is_dra72x() is_dra72x() #endif @@ -386,6 +390,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) #define DRA7XX_CLASS 0x07000000 +#define DRA762_REV_ES1_0 (DRA7XX_CLASS | (0x62 << 16) | (0x10 << 8)) #define DRA752_REV_ES1_0 (DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8)) #define DRA752_REV_ES1_1 (DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8)) #define DRA752_REV_ES2_0 (DRA7XX_CLASS | (0x52 << 16) | (0x20 << 8)) diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index 12f74b46e2ffc2dc8da8245b3b65593fd4ea9cc0..3f5863de766acbdbe4189f4fe53a23f648710995 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index 9dc3f59bed9ca13831ff61dd4e73020436a3f028..83d43cff4bd77195e19b62141f2170c78fc0c76c 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 7bd671b2854c1773136379bbea7bd622250130a7..0c315515dd2d97c031cfd9a94d52285634bbce31 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 7ef80a8304c0c3ce96f3120e285914fce49b89e8..94778739e38f0cbf85535525c478a19b2c12fbad 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c index 8cadb302a7d2f54a3bbcddaf7296606293d69e4e..ffe05c27087e88340c40f3a302f87aae19e1d81e 100644 --- a/arch/arm/mach-prima2/common.c +++ b/arch/arm/mach-prima2/common.c @@ -15,7 +15,7 @@ #include #include "common.h" -static void __init sirfsoc_init_late(void) +static void __init __maybe_unused sirfsoc_init_late(void) { sirfsoc_pm_init(); } diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 76fbc115ec33f7bc620e462a01f80fd915e864c1..ce7d97babb0f9428803df53cae836e437ed08118 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -566,6 +566,7 @@ config MACH_ICONTROL config ARCH_PXA_ESERIES bool "PXA based Toshiba e-series PDAs" select FB_W100 + select FB select PXA25x config MACH_E330 diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 1467c1d1e5419404ea07e921ca74e37b7a63d50b..d6d92f388f1455e5e556333ee033b1bc7389b2a4 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 811a7317f3eaa475604d349737cb176c0cd7c61f..6d28035ebba57d060b8f950b778e6c194da87055 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index fa9d71d194f01f44fb5bccf065a8a362838f6b3a..91f7c3e4006559e81210141bfc44472b17ab7326 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/include/mach/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h index 990d2bf2fb45e6451226afe25a4699a14ff5f53a..9bf4ea6a6f7446b830a6bfadf5156ff9cf5aed0c 100644 --- a/arch/arm/mach-pxa/include/mach/mtd-xip.h +++ b/arch/arm/mach-pxa/include/mach/mtd-xip.h @@ -17,11 +17,15 @@ #include -#define xip_irqpending() (ICIP & ICMR) +/* restored July 2017, this did not build since 2011! */ + +#define ICIP io_p2v(0x40d00000) +#define ICMR io_p2v(0x40d00004) +#define xip_irqpending() (readl(ICIP) & readl(ICMR)) /* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */ -#define xip_currtime() (OSCR) -#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4) +#define xip_currtime() readl(OSCR) +#define xip_elapsed_since(x) (signed)((readl(OSCR) - (x)) / 4) /* * xip_cpu_idle() is used when waiting for a delay equal or larger than diff --git a/arch/arm/mach-pxa/mioa701_bootresume.S b/arch/arm/mach-pxa/mioa701_bootresume.S index 81591491ab947b09f7128fc12e66e14d3d17d77b..42d93f40a59fa9c78a58d365d87fd2d56700174e 100644 --- a/arch/arm/mach-pxa/mioa701_bootresume.S +++ b/arch/arm/mach-pxa/mioa701_bootresume.S @@ -16,6 +16,7 @@ * insist on it to be truly read-only. */ .data + .align 2 ENTRY(mioa701_bootstrap) 0: b 1f @@ -34,4 +35,5 @@ ENTRY(mioa701_jumpaddr) ENTRY(mioa701_bootstrap_lg) .data + .align 2 .word 2b-0b diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 36646975b5d2b54637c79cb8fd82b8e7e7dc8fd6..47e3e38e9becd229ad88b38ce90dcbeff1fa6035 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index e2c97728b3c6b2890431cdd017e118c4f2ce7e57..9d662fed03ec7ae7fbf05bd22775185b00e571b6 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -377,7 +377,7 @@ static struct gpiod_lookup_table raumfeld_rotary_gpios_table = { }, }; -static struct property_entry raumfeld_rotary_properties[] = { +static const struct property_entry raumfeld_rotary_properties[] __initconst = { PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24), PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X), PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1), diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 13de6602966fea23dbfaad47c2ae616aa91cbe7a..6a386fd6363ea7e03b83216443dd1dcb40554df0 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 9ad84cd01ba01e6c213ba4936ce14719327cc908..a4065966881ae44d318ec4193d7091269541970c 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -3,6 +3,7 @@ config ARCH_ROCKCHIP depends on ARCH_MULTI_V7 select PINCTRL select PINCTRL_ROCKCHIP + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_HAS_RESET_CONTROLLER select ARM_AMBA select ARM_GIC @@ -16,6 +17,7 @@ config ARCH_ROCKCHIP select ROCKCHIP_TIMER select ARM_GLOBAL_TIMER select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK + select ZONE_DMA if ARM_LPAE help Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs containing the RK2928, RK30xx and RK31xx series. diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 3abafdbdd7f4a24d7afed4aa53f196aab838ac92..ecec340ca3457ed4e0edee89e86ee9a1778e65dd 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -67,7 +67,7 @@ static struct reset_control *rockchip_get_core_reset(int cpu) else np = of_get_cpu_node(cpu, NULL); - return of_reset_control_get(np, NULL); + return of_reset_control_get_exclusive(np, NULL); } static int pmu_set_power_domain(int pd, bool on) @@ -182,8 +182,8 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node) ret = of_address_to_resource(node, 0, &res); if (ret < 0) { - pr_err("%s: could not get address for node %s\n", - __func__, node->full_name); + pr_err("%s: could not get address for node %pOF\n", + __func__, node); return ret; } diff --git a/arch/arm/mach-rockchip/sleep.S b/arch/arm/mach-rockchip/sleep.S index 2eec9a341f05b0a82c73a7d0ec7c16d8f744d39f..9927f06f52fef64263bd1b34c35e5fd856646fda 100644 --- a/arch/arm/mach-rockchip/sleep.S +++ b/arch/arm/mach-rockchip/sleep.S @@ -23,7 +23,7 @@ * ddr to sram for system resumeing. * so it is ".data section". */ -.align + .align 2 ENTRY(rockchip_slp_cpu_resume) setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set svc, irqs off diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h index aa79fa47373ac8d3e605592cbe40e574cc9b3966..622d4e5df0293b48c697bb355a52a11613e7a629 100644 --- a/arch/arm/mach-rpc/include/mach/hardware.h +++ b/arch/arm/mach-rpc/include/mach/hardware.h @@ -25,8 +25,8 @@ * *_SIZE is the size of the region * *_BASE is the virtual address */ -#define RAM_SIZE 0x10000000 -#define RAM_START 0x10000000 +#define RPC_RAM_SIZE 0x10000000 +#define RPC_RAM_START 0x10000000 #define EASI_SIZE 0x08000000 /* EASI I/O */ #define EASI_START 0x08000000 diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index f07da82ebfea8171de6dac3c21c471ed1ae0514c..b198be7d32b67595805f4ec832eac98bef8377a7 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -229,7 +229,7 @@ config ARCH_H1940 config H1940BT tristate "Control the state of H1940 bluetooth chip" depends on ARCH_H1940 - select RFKILL + depends on RFKILL help This is a simple driver that is able to control the state of built in bluetooth chip on h1940. diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c index 9e0bc46e90ecf54ad7ee0c42ea2326eec3992b3a..0e116c92bf01db304645015a68ffb58b494a5535 100644 --- a/arch/arm/mach-s3c24xx/common-smdk.c +++ b/arch/arm/mach-s3c24xx/common-smdk.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index b59f4f4f256f2bd6785b086c40bbefb0bb68315c..5b6b94ef41e28418a843562138fafce4b792879b 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -173,7 +173,7 @@ static unsigned long s3c24xx_read_idcode_v5(void) return gs; #endif -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#if defined(CONFIG_CPU_S3C2412) return __raw_readl(S3C2412_GSTATUS1); #else return 1UL; /* don't look like an 2400 */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h index 3db6c10de023f44dd14323b60a7c3f248d9e3829..ae4a3e0f3ba20bd8d0437fdd0122b6b00f22a186 100644 --- a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h @@ -77,7 +77,7 @@ #endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */ -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#if defined(CONFIG_CPU_S3C2412) #define S3C2412_OSCSET S3C2410_CLKREG(0x18) #define S3C2412_CLKSRC S3C2410_CLKREG(0x1C) @@ -141,7 +141,7 @@ #define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12) #define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14) -#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ +#endif /* CONFIG_CPU_S3C2412 */ #define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28) diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c index 029ef1b58925499bbe657c267dab534a657e2d0b..c14cab36192264e78189abed5a9f77288905503d 100644 --- a/arch/arm/mach-s3c24xx/mach-anubis.c +++ b/arch/arm/mach-s3c24xx/mach-anubis.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c index 7b28eb623fc1ff745baf5d88fc138179c174855c..ebdbafb9382a6840c67bdd079d135603fbcb8e53 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c index 5185036765db2d096ee057774dbeadaafff11304..704dc84b34808204d77f2969038b0bd6ace5080c 100644 --- a/arch/arm/mach-s3c24xx/mach-bast.c +++ b/arch/arm/mach-s3c24xx/mach-bast.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index b0ed401da3a3aaa4a901c92159cfe585cf054284..afe18baf0c84c74e5a859dc342d2709884e5d1c4 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index f5b5c49b56ac0b561576ac64acef9c1846fa6020..17821976f769bbb4d7479b50bc185bb3d2ef98b8 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 71af8d2fd3201ffd95fa8588a440905d6a44abad..04c9f488c4981b044e3fe91f087fb00f2e63f942 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include @@ -287,7 +287,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = { .nr_sets = ARRAY_SIZE(mini2440_nand_sets), .sets = mini2440_nand_sets, .ignore_unset_ecc = 1, - .ecc_mode = NAND_ECC_SOFT, + .ecc_mode = NAND_ECC_HW, }; /* DM9000AEP 10/100 ethernet controller */ diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c index 262ab07447483aa810dda25b139cd81be61d2d68..6cac7da15e2b0d369f7a8fa4c3a0c214ede421df 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c +++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c index 70b0eb7d31347f8fbb6371148bbcc8de89a2aae0..ed3b22ceef06c75cbca69a8f2e5cef72183a3a47 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris.c +++ b/arch/arm/mach-s3c24xx/mach-osiris.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c index 868c8208740396f649163882c238469e6a45ee7a..84e3a9c53184a479ea1ac31303c62685e5e5bd5a 100644 --- a/arch/arm/mach-s3c24xx/mach-qt2410.c +++ b/arch/arm/mach-s3c24xx/mach-qt2410.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c index a39fb9780dd30649aaf7a9890c46083914f0e6ba..b5ba615cf9ddf3406145be77109214736b2234ef 100644 --- a/arch/arm/mach-s3c24xx/mach-rx3715.c +++ b/arch/arm/mach-s3c24xx/mach-rx3715.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c index 87fe5c5b80739fb9c36627943e813260a619406f..474cd81aa8ad58bd261e1fc0371ea8a19bf30369 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2443.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c @@ -111,9 +111,6 @@ static struct platform_device *smdk2443_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_hsmmc1, -#ifdef CONFIG_SND_SOC_SMDK2443_WM9710 - &s3c_device_ac97, -#endif &s3c2443_device_dma, }; @@ -133,11 +130,6 @@ static void __init smdk2443_init_time(void) static void __init smdk2443_machine_init(void) { s3c_i2c0_set_platdata(NULL); - -#ifdef CONFIG_SND_SOC_SMDK2443_WM9710 - s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0); -#endif - platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices)); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index f5e6322145fa9343d2a04d8d9aa9a088423054c0..1adc957edf0f9b8a004e552b86cc9ea84539dcfd 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c24xx/sleep.S b/arch/arm/mach-s3c24xx/sleep.S index d833d616bd2ed0177d7e7342f6a1673e7051c322..b859268fa8da1f1bb692167a5ba7c209206a4c5e 100644 --- a/arch/arm/mach-s3c24xx/sleep.S +++ b/arch/arm/mach-s3c24xx/sleep.S @@ -33,10 +33,11 @@ #include #include -/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not +/* + * S3C24XX_DEBUG_RESUME is dangerous if your bootloader does not * reset the UART configuration, only enable if you really need this! -*/ -//#define CONFIG_DEBUG_RESUME + */ +//#define S3C24XX_DEBUG_RESUME .text @@ -71,13 +72,13 @@ ENTRY(s3c_cpu_resume) str r12, [ r14, #0x54 ] #endif -#ifdef CONFIG_DEBUG_RESUME +#ifdef S3C24XX_DEBUG_RESUME mov r3, #'L' strb r3, [ r2, #S3C2410_UTXH ] 1001: ldrb r14, [ r3, #S3C2410_UTRSTAT ] tst r14, #S3C2410_UTRSTAT_TXE beq 1001b -#endif /* CONFIG_DEBUG_RESUME */ +#endif /* S3C24XX_DEBUG_RESUME */ b cpu_resume diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index 0db46895c82a4729d40b6c94c62482cd00ae1c9b..7d52cd97d96e4091adbcff105f9a0dc8db86c83e 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c @@ -35,6 +35,31 @@ struct clk clk_##_name = { \ static DEFINE_SPINLOCK(clocks_lock); +/* Dummy clk routine to build generic kernel parts that may be using them */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return clk_get_rate(clk); +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + return NULL; +} +EXPORT_SYMBOL(clk_get_parent); + static void clk_gpio27_enable(struct clk *clk) { /* diff --git a/arch/arm/mach-sa1100/include/mach/mtd-xip.h b/arch/arm/mach-sa1100/include/mach/mtd-xip.h index b3d684098fbf545c033e56793935cee7da3e2bf0..cb76096a2e36b4ea4ccf02f983244a97919ff243 100644 --- a/arch/arm/mach-sa1100/include/mach/mtd-xip.h +++ b/arch/arm/mach-sa1100/include/mach/mtd-xip.h @@ -20,7 +20,7 @@ #define xip_irqpending() (ICIP & ICMR) /* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */ -#define xip_currtime() (OSCR) -#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4) +#define xip_currtime() readl_relaxed(OSCR) +#define xip_elapsed_since(x) (signed)((readl_relaxed(OSCR) - (x)) / 4) #endif /* __ARCH_SA1100_MTD_XIP_H__ */ diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index ad7d604ff0013268eab461bd2f37ddc8d019879a..280e7312a9e1b300d07124239118de2735e2df04 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -1,9 +1,6 @@ config ARCH_SHMOBILE bool -config ARCH_SHMOBILE_MULTI - bool - config PM_RMOBILE bool select PM @@ -34,7 +31,6 @@ menuconfig ARCH_RENESAS depends on ARCH_MULTI_V7 && MMU select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_SHMOBILE - select ARCH_SHMOBILE_MULTI select ARM_GIC select GPIOLIB select HAVE_ARM_SCU if SMP diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index 0178da7ace82dcbd65b08b3eed9192dc6078ff81..e5f215c8b218100af7cc5f2ca079d78420b24571 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -11,7 +11,9 @@ */ #include +#include #include +#include #include #include #include @@ -69,8 +71,9 @@ void __init rcar_gen2_pm_init(void) struct device_node *np, *cpus; bool has_a7 = false; bool has_a15 = false; - phys_addr_t boot_vector_addr = ICRAM1; + struct resource res; u32 syscier = 0; + int error; if (once++) return; @@ -91,14 +94,38 @@ void __init rcar_gen2_pm_init(void) else if (of_machine_is_compatible("renesas,r8a7791")) syscier = 0x00111003; + np = of_find_compatible_node(NULL, NULL, "renesas,smp-sram"); + if (!np) { + /* No smp-sram in DT, fall back to hardcoded address */ + res = (struct resource)DEFINE_RES_MEM(ICRAM1, + shmobile_boot_size); + goto map; + } + + error = of_address_to_resource(np, 0, &res); + if (error) { + pr_err("Failed to get smp-sram address: %d\n", error); + return; + } + +map: /* RAM for jump stub, because BAR requires 256KB aligned address */ - p = ioremap_nocache(boot_vector_addr, shmobile_boot_size); + if (res.start & (256 * 1024 - 1) || + resource_size(&res) < shmobile_boot_size) { + pr_err("Invalid smp-sram region\n"); + return; + } + + p = ioremap(res.start, resource_size(&res)); + if (!p) + return; + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); iounmap(p); /* setup reset vectors */ p = ioremap_nocache(RST, 0x63); - bar = phys_to_sbar(boot_vector_addr); + bar = phys_to_sbar(res.start); if (has_a15) { writel_relaxed(bar, p + CA15BAR); writel_relaxed(bar | SBAR_BAREN, p + CA15BAR); diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 699429f28b737e9e7ad7105f7809fdb34f200e41..3a4ed4c33a68e51e0f213c9c6407a618eb4c4507 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -195,8 +195,7 @@ static void __init add_special_pd(struct device_node *np, enum pd_types type) return; } - pr_debug("Special PM domain %s type %d for %s\n", pd->name, type, - np->full_name); + pr_debug("Special PM domain %s type %d for %pOF\n", pd->name, type, np); special_pds[num_special_pds].pd = pd; special_pds[num_special_pds].type = type; @@ -331,13 +330,13 @@ static int __init rmobile_init_pm_domains(void) for_each_compatible_node(np, NULL, "renesas,sysc-rmobile") { base = of_iomap(np, 0); if (!base) { - pr_warn("%s cannot map reg 0\n", np->full_name); + pr_warn("%pOF cannot map reg 0\n", np); continue; } pmd = of_get_child_by_name(np, "pm-domains"); if (!pmd) { - pr_warn("%s lacks pm-domains node\n", np->full_name); + pr_warn("%pOF lacks pm-domains node\n", np); continue; } diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 73e3adbc133096eca9cdf652d37ff110f5e35850..44438f344dc80f9c5073502fbe2019270d8df24a 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -67,8 +67,12 @@ static int regulator_quirk_notify(struct notifier_block *nb, { struct device *dev = data; struct i2c_client *client; + static bool done; u32 mon; + if (done) + return 0; + mon = ioread32(irqc + IRQC_MONITOR); dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon); if (mon & REGULATOR_IRQ_MASK) @@ -99,7 +103,7 @@ static int regulator_quirk_notify(struct notifier_block *nb, remove: dev_info(dev, "IRQ2 is not asserted, removing quirk\n"); - bus_unregister_notifier(&i2c_bus_type, nb); + done = true; iounmap(irqc); return 0; } diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index a6e74f481dea2005dd0cfaf975e3a00095228c80..7ab1690fab8299ebdc5d01221b5026422b2ddff5 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -29,17 +29,29 @@ #include "common.h" #include "rcar-gen2.h" +static const struct of_device_id cpg_matches[] __initconst = { + { .compatible = "renesas,rcar-gen2-cpg-clocks", }, + { .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" }, + { /* sentinel */ } +}; + static unsigned int __init get_extal_freq(void) { + const struct of_device_id *match; struct device_node *cpg, *extal; u32 freq = 20000000; + int idx = 0; - cpg = of_find_compatible_node(NULL, NULL, - "renesas,rcar-gen2-cpg-clocks"); + cpg = of_find_matching_node_and_match(NULL, cpg_matches, &match); if (!cpg) return freq; - extal = of_parse_phandle(cpg, "clocks", 0); + if (match->data) + idx = of_property_match_string(cpg, "clock-names", match->data); + extal = of_parse_phandle(cpg, "clocks", idx); of_node_put(cpg); if (!extal) return freq; @@ -58,7 +70,8 @@ void __init rcar_gen2_timer_init(void) void __iomem *base; u32 freq; - if (of_machine_is_compatible("renesas,r8a7792") || + if (of_machine_is_compatible("renesas,r8a7745") || + of_machine_is_compatible("renesas,r8a7792") || of_machine_is_compatible("renesas,r8a7794")) { freq = 260000000 / 8; /* ZS / 8 */ /* CNTVOFF has to be initialized either from non-secure diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 329f01c5b6f89cf0f58849392e943eff10cf4ba7..c8368d64774178ff6d2723c5d6a63a3256a483cb 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -13,5 +13,7 @@ menuconfig ARCH_TEGRA select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER select SOC_BUS + select ZONE_DMA if ARM_LPAE + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE help This enables support for NVIDIA Tegra based systems. diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c index d3aa9be16621faa1f6a1e98a4b7f26cb6fe89ce6..e3fbcfedf845937436011fd20325cbe073097fc3 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c @@ -60,7 +60,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, return index; } -static void tegra114_idle_enter_freeze(struct cpuidle_device *dev, +static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { @@ -77,7 +77,7 @@ static struct cpuidle_driver tegra_idle_driver = { #ifdef CONFIG_PM_SLEEP [1] = { .enter = tegra114_idle_power_down, - .enter_freeze = tegra114_idle_enter_freeze, + .enter_s2idle = tegra114_idle_enter_s2idle, .exit_latency = 500, .target_residency = 1000, .flags = CPUIDLE_FLAG_TIMER_STOP, diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 649e9e8c7bccdf2e566ec0ad05c52c8a85a4fc04..02e712d2ea300b2040efefbfab43cc8cd9cab2e0 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -84,35 +84,8 @@ static void __init tegra_dt_init_irq(void) static void __init tegra_dt_init(void) { - struct soc_device_attribute *soc_dev_attr; - struct soc_device *soc_dev; - struct device *parent = NULL; + struct device *parent = tegra_soc_device_register(); - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); - if (!soc_dev_attr) - goto out; - - soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", - tegra_sku_info.revision); - soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); - - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - kfree(soc_dev_attr->family); - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr->soc_id); - kfree(soc_dev_attr); - goto out; - } - - parent = soc_device_to_device(soc_dev); - - /* - * Finished with the static registrations now; fill in the missing - * devices - */ -out: of_platform_default_populate(NULL, NULL, parent); } diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c index ac6fd1a2cb59fb43897d00581d18e53aa354ca80..3f93fac98d973dc9a952d40a98f33b9343545e8e 100644 --- a/arch/arm/mach-w90x900/clock.c +++ b/arch/arm/mach-w90x900/clock.c @@ -93,3 +93,32 @@ void nuc900_subclk_enable(struct clk *clk, int enable) __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK); } + +/* dummy functions, should not be called */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + WARN_ON(clk); + return 0; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + WARN_ON(clk); + return 0; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + WARN_ON(clk); + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + WARN_ON(clk); + return NULL; +} +EXPORT_SYMBOL(clk_get_parent); diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 2522f8c8fbb17278195ee0802a821d7aea7e3995..a5084ec70c6e67d75ccad63f8dd255ba0f275e68 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -47,6 +47,7 @@ #define CACHE_DLIMIT (CACHE_DSIZE * 4) .data + .align 2 flush_base: .long FLUSH_BASE .text diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index ff8b0aa2dfde887f7c48065f84c581c06fe1c4b8..42f585379e19c97fcb6abe1004d9b469f90215ce 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -315,8 +315,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * signal first. We do not need to release the mmap_sem because * it would already be released in __lock_page_or_retry in * mm/filemap.c. */ - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { + if (!user_mode(regs)) + goto no_context; return 0; + } /* * Major/minor page fault accounting is only done on the diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S index 5e5720e8bc5f219ebaa138eae369c32cba5b1615..7d16bbc4102bd22569062a50444901a879af2203 100644 --- a/arch/arm/mm/proc-v7-3level.S +++ b/arch/arm/mm/proc-v7-3level.S @@ -129,8 +129,7 @@ ENDPROC(cpu_v7_set_pte_ext) .macro v7_ttb_setup, zero, ttbr0l, ttbr0h, ttbr1, tmp ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address cmp \ttbr1, \tmp, lsr #12 @ PHYS_OFFSET > PAGE_OFFSET? - mrc p15, 0, \tmp, c2, c0, 2 @ TTB control egister - orr \tmp, \tmp, #TTB_EAE + mov \tmp, #TTB_EAE @ for TTB control egister ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP) ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP) ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16) diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index b6bbfdb6dfdc3d1681a562ef4eb96f95d33d6b03..3d75b7972fd13500baee28f30c48817428f286e9 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -104,6 +104,7 @@ .endm .data + .align 2 clean_addr: .word CLEAN_ADDR .text diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index d5b9fa19b684b69758661ef9fbd8d023e04d1d68..c199990e12b620fe40f34215abf2d577e6f90c70 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1,6 +1,7 @@ /* - * Just-In-Time compiler for BPF filters on 32bit ARM + * Just-In-Time compiler for eBPF filters on 32bit ARM * + * Copyright (c) 2017 Shubham Bansal * Copyright (c) 2011 Mircea Gherzan * * This program is free software; you can redistribute it and/or modify it @@ -8,6 +9,7 @@ * Free Software Foundation; version 2 of the License. */ +#include #include #include #include @@ -18,54 +20,101 @@ #include #include -#include #include #include #include "bpf_jit_32.h" +int bpf_jit_enable __read_mostly; + +#define STACK_OFFSET(k) (k) +#define TMP_REG_1 (MAX_BPF_JIT_REG + 0) /* TEMP Register 1 */ +#define TMP_REG_2 (MAX_BPF_JIT_REG + 1) /* TEMP Register 2 */ +#define TCALL_CNT (MAX_BPF_JIT_REG + 2) /* Tail Call Count */ + +/* Flags used for JIT optimization */ +#define SEEN_CALL (1 << 0) + +#define FLAG_IMM_OVERFLOW (1 << 0) + /* - * ABI: + * Map eBPF registers to ARM 32bit registers or stack scratch space. + * + * 1. First argument is passed using the arm 32bit registers and rest of the + * arguments are passed on stack scratch space. + * 2. First callee-saved arugument is mapped to arm 32 bit registers and rest + * arguments are mapped to scratch space on stack. + * 3. We need two 64 bit temp registers to do complex operations on eBPF + * registers. + * + * As the eBPF registers are all 64 bit registers and arm has only 32 bit + * registers, we have to map each eBPF registers with two arm 32 bit regs or + * scratch memory space and we have to build eBPF 64 bit register from those. * - * r0 scratch register - * r4 BPF register A - * r5 BPF register X - * r6 pointer to the skb - * r7 skb->data - * r8 skb_headlen(skb) */ +static const u8 bpf2a32[][2] = { + /* return value from in-kernel function, and exit value from eBPF */ + [BPF_REG_0] = {ARM_R1, ARM_R0}, + /* arguments from eBPF program to in-kernel function */ + [BPF_REG_1] = {ARM_R3, ARM_R2}, + /* Stored on stack scratch space */ + [BPF_REG_2] = {STACK_OFFSET(0), STACK_OFFSET(4)}, + [BPF_REG_3] = {STACK_OFFSET(8), STACK_OFFSET(12)}, + [BPF_REG_4] = {STACK_OFFSET(16), STACK_OFFSET(20)}, + [BPF_REG_5] = {STACK_OFFSET(24), STACK_OFFSET(28)}, + /* callee saved registers that in-kernel function will preserve */ + [BPF_REG_6] = {ARM_R5, ARM_R4}, + /* Stored on stack scratch space */ + [BPF_REG_7] = {STACK_OFFSET(32), STACK_OFFSET(36)}, + [BPF_REG_8] = {STACK_OFFSET(40), STACK_OFFSET(44)}, + [BPF_REG_9] = {STACK_OFFSET(48), STACK_OFFSET(52)}, + /* Read only Frame Pointer to access Stack */ + [BPF_REG_FP] = {STACK_OFFSET(56), STACK_OFFSET(60)}, + /* Temporary Register for internal BPF JIT, can be used + * for constant blindings and others. + */ + [TMP_REG_1] = {ARM_R7, ARM_R6}, + [TMP_REG_2] = {ARM_R10, ARM_R8}, + /* Tail call count. Stored on stack scratch space. */ + [TCALL_CNT] = {STACK_OFFSET(64), STACK_OFFSET(68)}, + /* temporary register for blinding constants. + * Stored on stack scratch space. + */ + [BPF_REG_AX] = {STACK_OFFSET(72), STACK_OFFSET(76)}, +}; -#define r_scratch ARM_R0 -/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */ -#define r_off ARM_R1 -#define r_A ARM_R4 -#define r_X ARM_R5 -#define r_skb ARM_R6 -#define r_skb_data ARM_R7 -#define r_skb_hl ARM_R8 - -#define SCRATCH_SP_OFFSET 0 -#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + 4 * (k)) - -#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1) -#define SEEN_MEM_WORD(k) (1 << (k)) -#define SEEN_X (1 << BPF_MEMWORDS) -#define SEEN_CALL (1 << (BPF_MEMWORDS + 1)) -#define SEEN_SKB (1 << (BPF_MEMWORDS + 2)) -#define SEEN_DATA (1 << (BPF_MEMWORDS + 3)) +#define dst_lo dst[1] +#define dst_hi dst[0] +#define src_lo src[1] +#define src_hi src[0] -#define FLAG_NEED_X_RESET (1 << 0) -#define FLAG_IMM_OVERFLOW (1 << 1) +/* + * JIT Context: + * + * prog : bpf_prog + * idx : index of current last JITed instruction. + * prologue_bytes : bytes used in prologue. + * epilogue_offset : offset of epilogue starting. + * seen : bit mask used for JIT optimization. + * offsets : array of eBPF instruction offsets in + * JITed code. + * target : final JITed code. + * epilogue_bytes : no of bytes used in epilogue. + * imm_count : no of immediate counts used for global + * variables. + * imms : array of global variable addresses. + */ struct jit_ctx { - const struct bpf_prog *skf; - unsigned idx; - unsigned prologue_bytes; - int ret0_fp_idx; + const struct bpf_prog *prog; + unsigned int idx; + unsigned int prologue_bytes; + unsigned int epilogue_offset; u32 seen; u32 flags; u32 *offsets; u32 *target; + u32 stack_size; #if __LINUX_ARM_ARCH__ < 7 u16 epilogue_bytes; u16 imm_count; @@ -73,68 +122,16 @@ struct jit_ctx { #endif }; -int bpf_jit_enable __read_mostly; - -static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret, - unsigned int size) -{ - void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size); - - if (!ptr) - return -EFAULT; - memcpy(ret, ptr, size); - return 0; -} - -static u64 jit_get_skb_b(struct sk_buff *skb, int offset) -{ - u8 ret; - int err; - - if (offset < 0) - err = call_neg_helper(skb, offset, &ret, 1); - else - err = skb_copy_bits(skb, offset, &ret, 1); - - return (u64)err << 32 | ret; -} - -static u64 jit_get_skb_h(struct sk_buff *skb, int offset) -{ - u16 ret; - int err; - - if (offset < 0) - err = call_neg_helper(skb, offset, &ret, 2); - else - err = skb_copy_bits(skb, offset, &ret, 2); - - return (u64)err << 32 | ntohs(ret); -} - -static u64 jit_get_skb_w(struct sk_buff *skb, int offset) -{ - u32 ret; - int err; - - if (offset < 0) - err = call_neg_helper(skb, offset, &ret, 4); - else - err = skb_copy_bits(skb, offset, &ret, 4); - - return (u64)err << 32 | ntohl(ret); -} - /* * Wrappers which handle both OABI and EABI and assures Thumb2 interworking * (where the assembly routines like __aeabi_uidiv could cause problems). */ -static u32 jit_udiv(u32 dividend, u32 divisor) +static u32 jit_udiv32(u32 dividend, u32 divisor) { return dividend / divisor; } -static u32 jit_mod(u32 dividend, u32 divisor) +static u32 jit_mod32(u32 dividend, u32 divisor) { return dividend % divisor; } @@ -158,36 +155,22 @@ static inline void emit(u32 inst, struct jit_ctx *ctx) _emit(ARM_COND_AL, inst, ctx); } -static u16 saved_regs(struct jit_ctx *ctx) +/* + * Checks if immediate value can be converted to imm12(12 bits) value. + */ +static int16_t imm8m(u32 x) { - u16 ret = 0; - - if ((ctx->skf->len > 1) || - (ctx->skf->insns[0].code == (BPF_RET | BPF_A))) - ret |= 1 << r_A; - -#ifdef CONFIG_FRAME_POINTER - ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC); -#else - if (ctx->seen & SEEN_CALL) - ret |= 1 << ARM_LR; -#endif - if (ctx->seen & (SEEN_DATA | SEEN_SKB)) - ret |= 1 << r_skb; - if (ctx->seen & SEEN_DATA) - ret |= (1 << r_skb_data) | (1 << r_skb_hl); - if (ctx->seen & SEEN_X) - ret |= 1 << r_X; - - return ret; -} + u32 rot; -static inline int mem_words_used(struct jit_ctx *ctx) -{ - /* yes, we do waste some stack space IF there are "holes" in the set" */ - return fls(ctx->seen & SEEN_MEM); + for (rot = 0; rot < 16; rot++) + if ((x & ~ror32(0xff, 2 * rot)) == 0) + return rol32(x, 2 * rot) | (rot << 8); + return -1; } +/* + * Initializes the JIT space with undefined instructions. + */ static void jit_fill_hole(void *area, unsigned int size) { u32 *ptr; @@ -196,88 +179,34 @@ static void jit_fill_hole(void *area, unsigned int size) *ptr++ = __opcode_to_mem_arm(ARM_INST_UDF); } -static void build_prologue(struct jit_ctx *ctx) -{ - u16 reg_set = saved_regs(ctx); - u16 off; - -#ifdef CONFIG_FRAME_POINTER - emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx); - emit(ARM_PUSH(reg_set), ctx); - emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx); -#else - if (reg_set) - emit(ARM_PUSH(reg_set), ctx); -#endif - - if (ctx->seen & (SEEN_DATA | SEEN_SKB)) - emit(ARM_MOV_R(r_skb, ARM_R0), ctx); - - if (ctx->seen & SEEN_DATA) { - off = offsetof(struct sk_buff, data); - emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx); - /* headlen = len - data_len */ - off = offsetof(struct sk_buff, len); - emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx); - off = offsetof(struct sk_buff, data_len); - emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); - emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx); - } - - if (ctx->flags & FLAG_NEED_X_RESET) - emit(ARM_MOV_I(r_X, 0), ctx); - - /* do not leak kernel data to userspace */ - if (bpf_needs_clear_a(&ctx->skf->insns[0])) - emit(ARM_MOV_I(r_A, 0), ctx); - - /* stack space for the BPF_MEM words */ - if (ctx->seen & SEEN_MEM) - emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); -} - -static void build_epilogue(struct jit_ctx *ctx) -{ - u16 reg_set = saved_regs(ctx); - - if (ctx->seen & SEEN_MEM) - emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); - - reg_set &= ~(1 << ARM_LR); +/* Stack must be multiples of 16 Bytes */ +#define STACK_ALIGN(sz) (((sz) + 3) & ~3) -#ifdef CONFIG_FRAME_POINTER - /* the first instruction of the prologue was: mov ip, sp */ - reg_set &= ~(1 << ARM_IP); - reg_set |= (1 << ARM_SP); - emit(ARM_LDM(ARM_SP, reg_set), ctx); -#else - if (reg_set) { - if (ctx->seen & SEEN_CALL) - reg_set |= 1 << ARM_PC; - emit(ARM_POP(reg_set), ctx); - } +/* Stack space for BPF_REG_2, BPF_REG_3, BPF_REG_4, + * BPF_REG_5, BPF_REG_7, BPF_REG_8, BPF_REG_9, + * BPF_REG_FP and Tail call counts. + */ +#define SCRATCH_SIZE 80 - if (!(ctx->seen & SEEN_CALL)) - emit(ARM_BX(ARM_LR), ctx); -#endif -} +/* total stack size used in JITed code */ +#define _STACK_SIZE \ + (ctx->prog->aux->stack_depth + \ + + SCRATCH_SIZE + \ + + 4 /* extra for skb_copy_bits buffer */) -static int16_t imm8m(u32 x) -{ - u32 rot; +#define STACK_SIZE STACK_ALIGN(_STACK_SIZE) - for (rot = 0; rot < 16; rot++) - if ((x & ~ror32(0xff, 2 * rot)) == 0) - return rol32(x, 2 * rot) | (rot << 8); +/* Get the offset of eBPF REGISTERs stored on scratch space. */ +#define STACK_VAR(off) (STACK_SIZE-off-4) - return -1; -} +/* Offset of skb_copy_bits buffer */ +#define SKB_BUFFER STACK_VAR(SCRATCH_SIZE) #if __LINUX_ARM_ARCH__ < 7 static u16 imm_offset(u32 k, struct jit_ctx *ctx) { - unsigned i = 0, offset; + unsigned int i = 0, offset; u16 imm; /* on the "fake" run we just count them (duplicates included) */ @@ -296,7 +225,7 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx) ctx->imms[i] = k; /* constants go just after the epilogue */ - offset = ctx->offsets[ctx->skf->len]; + offset = ctx->offsets[ctx->prog->len - 1] * 4; offset += ctx->prologue_bytes; offset += ctx->epilogue_bytes; offset += i * 4; @@ -320,10 +249,22 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx) #endif /* __LINUX_ARM_ARCH__ */ +static inline int bpf2a32_offset(int bpf_to, int bpf_from, + const struct jit_ctx *ctx) { + int to, from; + + if (ctx->target == NULL) + return 0; + to = ctx->offsets[bpf_to]; + from = ctx->offsets[bpf_from]; + + return to - from - 1; +} + /* * Move an immediate that's not an imm8m to a core register. */ -static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx) +static inline void emit_mov_i_no8m(const u8 rd, u32 val, struct jit_ctx *ctx) { #if __LINUX_ARM_ARCH__ < 7 emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx); @@ -334,7 +275,7 @@ static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx) #endif } -static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx) +static inline void emit_mov_i(const u8 rd, u32 val, struct jit_ctx *ctx) { int imm12 = imm8m(val); @@ -344,676 +285,1594 @@ static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx) emit_mov_i_no8m(rd, val, ctx); } -#if __LINUX_ARM_ARCH__ < 6 - -static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx) { - _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx); - _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); - _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx); - _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx); - _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx); - _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx); - _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx); - _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx); + ctx->seen |= SEEN_CALL; +#if __LINUX_ARM_ARCH__ < 5 + emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx); + + if (elf_hwcap & HWCAP_THUMB) + emit(ARM_BX(tgt_reg), ctx); + else + emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx); +#else + emit(ARM_BLX_R(tgt_reg), ctx); +#endif } -static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +static inline int epilogue_offset(const struct jit_ctx *ctx) { - _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); - _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx); - _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx); + int to, from; + /* No need for 1st dummy run */ + if (ctx->target == NULL) + return 0; + to = ctx->epilogue_offset; + from = ctx->idx; + + return to - from - 2; } -static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx) +static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) { - /* r_dst = (r_src << 8) | (r_src >> 8) */ - emit(ARM_LSL_I(ARM_R1, r_src, 8), ctx); - emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSR, 8), ctx); + const u8 *tmp = bpf2a32[TMP_REG_1]; + s32 jmp_offset; + + /* checks if divisor is zero or not. If it is, then + * exit directly. + */ + emit(ARM_CMP_I(rn, 0), ctx); + _emit(ARM_COND_EQ, ARM_MOV_I(ARM_R0, 0), ctx); + jmp_offset = epilogue_offset(ctx); + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); +#if __LINUX_ARM_ARCH__ == 7 + if (elf_hwcap & HWCAP_IDIVA) { + if (op == BPF_DIV) + emit(ARM_UDIV(rd, rm, rn), ctx); + else { + emit(ARM_UDIV(ARM_IP, rm, rn), ctx); + emit(ARM_MLS(rd, rn, ARM_IP, rm), ctx); + } + return; + } +#endif /* - * we need to mask out the bits set in r_dst[23:16] due to - * the first shift instruction. - * - * note that 0x8ff is the encoded immediate 0x00ff0000. + * For BPF_ALU | BPF_DIV | BPF_K instructions + * As ARM_R1 and ARM_R0 contains 1st argument of bpf + * function, we need to save it on caller side to save + * it from getting destroyed within callee. + * After the return from the callee, we restore ARM_R0 + * ARM_R1. */ - emit(ARM_BIC_I(r_dst, r_dst, 0x8ff), ctx); -} + if (rn != ARM_R1) { + emit(ARM_MOV_R(tmp[0], ARM_R1), ctx); + emit(ARM_MOV_R(ARM_R1, rn), ctx); + } + if (rm != ARM_R0) { + emit(ARM_MOV_R(tmp[1], ARM_R0), ctx); + emit(ARM_MOV_R(ARM_R0, rm), ctx); + } -#else /* ARMv6+ */ + /* Call appropriate function */ + ctx->seen |= SEEN_CALL; + emit_mov_i(ARM_IP, op == BPF_DIV ? + (u32)jit_udiv32 : (u32)jit_mod32, ctx); + emit_blx_r(ARM_IP, ctx); -static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) -{ - _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx); -#ifdef __LITTLE_ENDIAN - _emit(cond, ARM_REV(r_res, r_res), ctx); -#endif + /* Save return value */ + if (rd != ARM_R0) + emit(ARM_MOV_R(rd, ARM_R0), ctx); + + /* Restore ARM_R0 and ARM_R1 */ + if (rn != ARM_R1) + emit(ARM_MOV_R(ARM_R1, tmp[0]), ctx); + if (rm != ARM_R0) + emit(ARM_MOV_R(ARM_R0, tmp[1]), ctx); } -static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +/* Checks whether BPF register is on scratch stack space or not. */ +static inline bool is_on_stack(u8 bpf_reg) { - _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx); -#ifdef __LITTLE_ENDIAN - _emit(cond, ARM_REV16(r_res, r_res), ctx); -#endif + static u8 stack_regs[] = {BPF_REG_AX, BPF_REG_3, BPF_REG_4, BPF_REG_5, + BPF_REG_7, BPF_REG_8, BPF_REG_9, TCALL_CNT, + BPF_REG_2, BPF_REG_FP}; + int i, reg_len = sizeof(stack_regs); + + for (i = 0 ; i < reg_len ; i++) { + if (bpf_reg == stack_regs[i]) + return true; + } + return false; } -static inline void emit_swap16(u8 r_dst __maybe_unused, - u8 r_src __maybe_unused, - struct jit_ctx *ctx __maybe_unused) +static inline void emit_a32_mov_i(const u8 dst, const u32 val, + bool dstk, struct jit_ctx *ctx) { -#ifdef __LITTLE_ENDIAN - emit(ARM_REV16(r_dst, r_src), ctx); -#endif + const u8 *tmp = bpf2a32[TMP_REG_1]; + + if (dstk) { + emit_mov_i(tmp[1], val, ctx); + emit(ARM_STR_I(tmp[1], ARM_SP, STACK_VAR(dst)), ctx); + } else { + emit_mov_i(dst, val, ctx); + } } -#endif /* __LINUX_ARM_ARCH__ < 6 */ +/* Sign extended move */ +static inline void emit_a32_mov_i64(const bool is64, const u8 dst[], + const u32 val, bool dstk, + struct jit_ctx *ctx) { + u32 hi = 0; + if (is64 && (val & (1<<31))) + hi = (u32)~0; + emit_a32_mov_i(dst_lo, val, dstk, ctx); + emit_a32_mov_i(dst_hi, hi, dstk, ctx); +} -/* Compute the immediate value for a PC-relative branch. */ -static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx) -{ - u32 imm; +static inline void emit_a32_add_r(const u8 dst, const u8 src, + const bool is64, const bool hi, + struct jit_ctx *ctx) { + /* 64 bit : + * adds dst_lo, dst_lo, src_lo + * adc dst_hi, dst_hi, src_hi + * 32 bit : + * add dst_lo, dst_lo, src_lo + */ + if (!hi && is64) + emit(ARM_ADDS_R(dst, dst, src), ctx); + else if (hi && is64) + emit(ARM_ADC_R(dst, dst, src), ctx); + else + emit(ARM_ADD_R(dst, dst, src), ctx); +} - if (ctx->target == NULL) - return 0; - /* - * BPF allows only forward jumps and the offset of the target is - * still the one computed during the first pass. +static inline void emit_a32_sub_r(const u8 dst, const u8 src, + const bool is64, const bool hi, + struct jit_ctx *ctx) { + /* 64 bit : + * subs dst_lo, dst_lo, src_lo + * sbc dst_hi, dst_hi, src_hi + * 32 bit : + * sub dst_lo, dst_lo, src_lo */ - imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8); + if (!hi && is64) + emit(ARM_SUBS_R(dst, dst, src), ctx); + else if (hi && is64) + emit(ARM_SBC_R(dst, dst, src), ctx); + else + emit(ARM_SUB_R(dst, dst, src), ctx); +} - return imm >> 2; +static inline void emit_alu_r(const u8 dst, const u8 src, const bool is64, + const bool hi, const u8 op, struct jit_ctx *ctx){ + switch (BPF_OP(op)) { + /* dst = dst + src */ + case BPF_ADD: + emit_a32_add_r(dst, src, is64, hi, ctx); + break; + /* dst = dst - src */ + case BPF_SUB: + emit_a32_sub_r(dst, src, is64, hi, ctx); + break; + /* dst = dst | src */ + case BPF_OR: + emit(ARM_ORR_R(dst, dst, src), ctx); + break; + /* dst = dst & src */ + case BPF_AND: + emit(ARM_AND_R(dst, dst, src), ctx); + break; + /* dst = dst ^ src */ + case BPF_XOR: + emit(ARM_EOR_R(dst, dst, src), ctx); + break; + /* dst = dst * src */ + case BPF_MUL: + emit(ARM_MUL(dst, dst, src), ctx); + break; + /* dst = dst << src */ + case BPF_LSH: + emit(ARM_LSL_R(dst, dst, src), ctx); + break; + /* dst = dst >> src */ + case BPF_RSH: + emit(ARM_LSR_R(dst, dst, src), ctx); + break; + /* dst = dst >> src (signed)*/ + case BPF_ARSH: + emit(ARM_MOV_SR(dst, dst, SRTYPE_ASR, src), ctx); + break; + } } -#define OP_IMM3(op, r1, r2, imm_val, ctx) \ - do { \ - imm12 = imm8m(imm_val); \ - if (imm12 < 0) { \ - emit_mov_i_no8m(r_scratch, imm_val, ctx); \ - emit(op ## _R((r1), (r2), r_scratch), ctx); \ - } else { \ - emit(op ## _I((r1), (r2), imm12), ctx); \ - } \ - } while (0) - -static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx) -{ - if (ctx->ret0_fp_idx >= 0) { - _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx); - /* NOP to keep the size constant between passes */ - emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx); +/* ALU operation (32 bit) + * dst = dst (op) src + */ +static inline void emit_a32_alu_r(const u8 dst, const u8 src, + bool dstk, bool sstk, + struct jit_ctx *ctx, const bool is64, + const bool hi, const u8 op) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rn = sstk ? tmp[1] : src; + + if (sstk) + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src)), ctx); + + /* ALU operation */ + if (dstk) { + emit(ARM_LDR_I(tmp[0], ARM_SP, STACK_VAR(dst)), ctx); + emit_alu_r(tmp[0], rn, is64, hi, op, ctx); + emit(ARM_STR_I(tmp[0], ARM_SP, STACK_VAR(dst)), ctx); } else { - _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx); - _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx); + emit_alu_r(dst, rn, is64, hi, op, ctx); } } -static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx) -{ -#if __LINUX_ARM_ARCH__ < 5 - emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx); +/* ALU operation (64 bit) */ +static inline void emit_a32_alu_r64(const bool is64, const u8 dst[], + const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx, + const u8 op) { + emit_a32_alu_r(dst_lo, src_lo, dstk, sstk, ctx, is64, false, op); + if (is64) + emit_a32_alu_r(dst_hi, src_hi, dstk, sstk, ctx, is64, true, op); + else + emit_a32_mov_i(dst_hi, 0, dstk, ctx); +} - if (elf_hwcap & HWCAP_THUMB) - emit(ARM_BX(tgt_reg), ctx); +/* dst = imm (4 bytes)*/ +static inline void emit_a32_mov_r(const u8 dst, const u8 src, + bool dstk, bool sstk, + struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rt = sstk ? tmp[0] : src; + + if (sstk) + emit(ARM_LDR_I(tmp[0], ARM_SP, STACK_VAR(src)), ctx); + if (dstk) + emit(ARM_STR_I(rt, ARM_SP, STACK_VAR(dst)), ctx); else - emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx); -#else - emit(ARM_BLX_R(tgt_reg), ctx); -#endif + emit(ARM_MOV_R(dst, rt), ctx); } -static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, - int bpf_op) -{ -#if __LINUX_ARM_ARCH__ == 7 - if (elf_hwcap & HWCAP_IDIVA) { - if (bpf_op == BPF_DIV) - emit(ARM_UDIV(rd, rm, rn), ctx); - else { - emit(ARM_UDIV(ARM_R3, rm, rn), ctx); - emit(ARM_MLS(rd, rn, ARM_R3, rm), ctx); - } - return; +/* dst = src */ +static inline void emit_a32_mov_r64(const bool is64, const u8 dst[], + const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + emit_a32_mov_r(dst_lo, src_lo, dstk, sstk, ctx); + if (is64) { + /* complete 8 byte move */ + emit_a32_mov_r(dst_hi, src_hi, dstk, sstk, ctx); + } else { + /* Zero out high 4 bytes */ + emit_a32_mov_i(dst_hi, 0, dstk, ctx); } -#endif +} - /* - * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4 - * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into - * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm - * before using it as a source for ARM_R1. - * - * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is - * ARM_R5 (r_X) so there is no particular register overlap - * issues. - */ - if (rn != ARM_R1) - emit(ARM_MOV_R(ARM_R1, rn), ctx); - if (rm != ARM_R0) - emit(ARM_MOV_R(ARM_R0, rm), ctx); +/* Shift operations */ +static inline void emit_a32_alu_i(const u8 dst, const u32 val, bool dstk, + struct jit_ctx *ctx, const u8 op) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[0] : dst; + + if (dstk) + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); + + /* Do shift operation */ + switch (op) { + case BPF_LSH: + emit(ARM_LSL_I(rd, rd, val), ctx); + break; + case BPF_RSH: + emit(ARM_LSR_I(rd, rd, val), ctx); + break; + case BPF_NEG: + emit(ARM_RSB_I(rd, rd, val), ctx); + break; + } + if (dstk) + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); +} + +/* dst = ~dst (64 bit) */ +static inline void emit_a32_neg64(const u8 dst[], bool dstk, + struct jit_ctx *ctx){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[1] : dst[1]; + u8 rm = dstk ? tmp[0] : dst[0]; + + /* Setup Operand */ + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do Negate Operation */ + emit(ARM_RSBS_I(rd, rd, 0), ctx); + emit(ARM_RSC_I(rm, rm, 0), ctx); + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +/* dst = dst << src */ +static inline void emit_a32_lsh_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + + /* Setup Operands */ + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSH operation */ + emit(ARM_SUB_I(ARM_IP, rt, 32), ctx); + emit(ARM_RSB_I(tmp2[0], rt, 32), ctx); + /* As we are using ARM_LR */ ctx->seen |= SEEN_CALL; - emit_mov_i(ARM_R3, bpf_op == BPF_DIV ? (u32)jit_udiv : (u32)jit_mod, - ctx); - emit_blx_r(ARM_R3, ctx); + emit(ARM_MOV_SR(ARM_LR, rm, SRTYPE_ASL, rt), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd, SRTYPE_ASL, ARM_IP), ctx); + emit(ARM_ORR_SR(ARM_IP, ARM_LR, rd, SRTYPE_LSR, tmp2[0]), ctx); + emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_ASL, rt), ctx); + + if (dstk) { + emit(ARM_STR_I(ARM_LR, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_LR), ctx); + emit(ARM_MOV_R(rm, ARM_IP), ctx); + } +} - if (rd != ARM_R0) - emit(ARM_MOV_R(rd, ARM_R0), ctx); +/* dst = dst >> src (signed)*/ +static inline void emit_a32_arsh_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup Operands */ + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do the ARSH operation */ + emit(ARM_RSB_I(ARM_IP, rt, 32), ctx); + emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_LSR, rt), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASL, ARM_IP), ctx); + _emit(ARM_COND_MI, ARM_B(0), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASR, tmp2[0]), ctx); + emit(ARM_MOV_SR(ARM_IP, rm, SRTYPE_ASR, rt), ctx); + if (dstk) { + emit(ARM_STR_I(ARM_LR, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_LR), ctx); + emit(ARM_MOV_R(rm, ARM_IP), ctx); + } +} + +/* dst = dst >> src */ +static inline void emit_a32_lsr_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup Operands */ + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSH operation */ + emit(ARM_RSB_I(ARM_IP, rt, 32), ctx); + emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_LSR, rt), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASL, ARM_IP), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_LSR, tmp2[0]), ctx); + emit(ARM_MOV_SR(ARM_IP, rm, SRTYPE_LSR, rt), ctx); + if (dstk) { + emit(ARM_STR_I(ARM_LR, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_LR), ctx); + emit(ARM_MOV_R(rm, ARM_IP), ctx); + } } -static inline void update_on_xread(struct jit_ctx *ctx) +/* dst = dst << val */ +static inline void emit_a32_lsh_i64(const u8 dst[], bool dstk, + const u32 val, struct jit_ctx *ctx){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSH operation */ + if (val < 32) { + emit(ARM_MOV_SI(tmp2[0], rm, SRTYPE_ASL, val), ctx); + emit(ARM_ORR_SI(rm, tmp2[0], rd, SRTYPE_LSR, 32 - val), ctx); + emit(ARM_MOV_SI(rd, rd, SRTYPE_ASL, val), ctx); + } else { + if (val == 32) + emit(ARM_MOV_R(rm, rd), ctx); + else + emit(ARM_MOV_SI(rm, rd, SRTYPE_ASL, val - 32), ctx); + emit(ARM_EOR_R(rd, rd, rd), ctx); + } + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +/* dst = dst >> val */ +static inline void emit_a32_lsr_i64(const u8 dst[], bool dstk, + const u32 val, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSR operation */ + if (val < 32) { + emit(ARM_MOV_SI(tmp2[1], rd, SRTYPE_LSR, val), ctx); + emit(ARM_ORR_SI(rd, tmp2[1], rm, SRTYPE_ASL, 32 - val), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_LSR, val), ctx); + } else if (val == 32) { + emit(ARM_MOV_R(rd, rm), ctx); + emit(ARM_MOV_I(rm, 0), ctx); + } else { + emit(ARM_MOV_SI(rd, rm, SRTYPE_LSR, val - 32), ctx); + emit(ARM_MOV_I(rm, 0), ctx); + } + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +/* dst = dst >> val (signed) */ +static inline void emit_a32_arsh_i64(const u8 dst[], bool dstk, + const u32 val, struct jit_ctx *ctx){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do ARSH operation */ + if (val < 32) { + emit(ARM_MOV_SI(tmp2[1], rd, SRTYPE_LSR, val), ctx); + emit(ARM_ORR_SI(rd, tmp2[1], rm, SRTYPE_ASL, 32 - val), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_ASR, val), ctx); + } else if (val == 32) { + emit(ARM_MOV_R(rd, rm), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_ASR, 31), ctx); + } else { + emit(ARM_MOV_SI(rd, rm, SRTYPE_ASR, val - 32), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_ASR, 31), ctx); + } + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +static inline void emit_a32_mul_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands for multiplication */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rn = sstk ? tmp2[0] : src_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + if (sstk) { + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_hi)), ctx); + } + + /* Do Multiplication */ + emit(ARM_MUL(ARM_IP, rd, rn), ctx); + emit(ARM_MUL(ARM_LR, rm, rt), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_ADD_R(ARM_LR, ARM_IP, ARM_LR), ctx); + + emit(ARM_UMULL(ARM_IP, rm, rd, rt), ctx); + emit(ARM_ADD_R(rm, ARM_LR, rm), ctx); + if (dstk) { + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_IP), ctx); + } +} + +/* *(size *)(dst + off) = src */ +static inline void emit_str_r(const u8 dst, const u8 src, bool dstk, + const s32 off, struct jit_ctx *ctx, const u8 sz){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[1] : dst; + + if (dstk) + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); + if (off) { + emit_a32_mov_i(tmp[0], off, false, ctx); + emit(ARM_ADD_R(tmp[0], rd, tmp[0]), ctx); + rd = tmp[0]; + } + switch (sz) { + case BPF_W: + /* Store a Word */ + emit(ARM_STR_I(src, rd, 0), ctx); + break; + case BPF_H: + /* Store a HalfWord */ + emit(ARM_STRH_I(src, rd, 0), ctx); + break; + case BPF_B: + /* Store a Byte */ + emit(ARM_STRB_I(src, rd, 0), ctx); + break; + } +} + +/* dst = *(size*)(src + off) */ +static inline void emit_ldx_r(const u8 dst, const u8 src, bool dstk, + const s32 off, struct jit_ctx *ctx, const u8 sz){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[1] : dst; + u8 rm = src; + + if (off) { + emit_a32_mov_i(tmp[0], off, false, ctx); + emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); + rm = tmp[0]; + } + switch (sz) { + case BPF_W: + /* Load a Word */ + emit(ARM_LDR_I(rd, rm, 0), ctx); + break; + case BPF_H: + /* Load a HalfWord */ + emit(ARM_LDRH_I(rd, rm, 0), ctx); + break; + case BPF_B: + /* Load a Byte */ + emit(ARM_LDRB_I(rd, rm, 0), ctx); + break; + } + if (dstk) + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); +} + +/* Arithmatic Operation */ +static inline void emit_ar_r(const u8 rd, const u8 rt, const u8 rm, + const u8 rn, struct jit_ctx *ctx, u8 op) { + switch (op) { + case BPF_JSET: + ctx->seen |= SEEN_CALL; + emit(ARM_AND_R(ARM_IP, rt, rn), ctx); + emit(ARM_AND_R(ARM_LR, rd, rm), ctx); + emit(ARM_ORRS_R(ARM_IP, ARM_LR, ARM_IP), ctx); + break; + case BPF_JEQ: + case BPF_JNE: + case BPF_JGT: + case BPF_JGE: + case BPF_JLE: + case BPF_JLT: + emit(ARM_CMP_R(rd, rm), ctx); + _emit(ARM_COND_EQ, ARM_CMP_R(rt, rn), ctx); + break; + case BPF_JSLE: + case BPF_JSGT: + emit(ARM_CMP_R(rn, rt), ctx); + emit(ARM_SBCS_R(ARM_IP, rm, rd), ctx); + break; + case BPF_JSLT: + case BPF_JSGE: + emit(ARM_CMP_R(rt, rn), ctx); + emit(ARM_SBCS_R(ARM_IP, rd, rm), ctx); + break; + } +} + +static int out_offset = -1; /* initialized on the first pass of build_body() */ +static int emit_bpf_tail_call(struct jit_ctx *ctx) { - if (!(ctx->seen & SEEN_X)) - ctx->flags |= FLAG_NEED_X_RESET; - ctx->seen |= SEEN_X; + /* bpf_tail_call(void *prog_ctx, struct bpf_array *array, u64 index) */ + const u8 *r2 = bpf2a32[BPF_REG_2]; + const u8 *r3 = bpf2a32[BPF_REG_3]; + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + const u8 *tcc = bpf2a32[TCALL_CNT]; + const int idx0 = ctx->idx; +#define cur_offset (ctx->idx - idx0) +#define jmp_offset (out_offset - (cur_offset)) + u32 off, lo, hi; + + /* if (index >= array->map.max_entries) + * goto out; + */ + off = offsetof(struct bpf_array, map.max_entries); + /* array->map.max_entries */ + emit_a32_mov_i(tmp[1], off, false, ctx); + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r2[1])), ctx); + emit(ARM_LDR_R(tmp[1], tmp2[1], tmp[1]), ctx); + /* index (64 bit) */ + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r3[1])), ctx); + /* index >= array->map.max_entries */ + emit(ARM_CMP_R(tmp2[1], tmp[1]), ctx); + _emit(ARM_COND_CS, ARM_B(jmp_offset), ctx); + + /* if (tail_call_cnt > MAX_TAIL_CALL_CNT) + * goto out; + * tail_call_cnt++; + */ + lo = (u32)MAX_TAIL_CALL_CNT; + hi = (u32)((u64)MAX_TAIL_CALL_CNT >> 32); + emit(ARM_LDR_I(tmp[1], ARM_SP, STACK_VAR(tcc[1])), ctx); + emit(ARM_LDR_I(tmp[0], ARM_SP, STACK_VAR(tcc[0])), ctx); + emit(ARM_CMP_I(tmp[0], hi), ctx); + _emit(ARM_COND_EQ, ARM_CMP_I(tmp[1], lo), ctx); + _emit(ARM_COND_HI, ARM_B(jmp_offset), ctx); + emit(ARM_ADDS_I(tmp[1], tmp[1], 1), ctx); + emit(ARM_ADC_I(tmp[0], tmp[0], 0), ctx); + emit(ARM_STR_I(tmp[1], ARM_SP, STACK_VAR(tcc[1])), ctx); + emit(ARM_STR_I(tmp[0], ARM_SP, STACK_VAR(tcc[0])), ctx); + + /* prog = array->ptrs[index] + * if (prog == NULL) + * goto out; + */ + off = offsetof(struct bpf_array, ptrs); + emit_a32_mov_i(tmp[1], off, false, ctx); + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r2[1])), ctx); + emit(ARM_ADD_R(tmp[1], tmp2[1], tmp[1]), ctx); + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r3[1])), ctx); + emit(ARM_MOV_SI(tmp[0], tmp2[1], SRTYPE_ASL, 2), ctx); + emit(ARM_LDR_R(tmp[1], tmp[1], tmp[0]), ctx); + emit(ARM_CMP_I(tmp[1], 0), ctx); + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); + + /* goto *(prog->bpf_func + prologue_size); */ + off = offsetof(struct bpf_prog, bpf_func); + emit_a32_mov_i(tmp2[1], off, false, ctx); + emit(ARM_LDR_R(tmp[1], tmp[1], tmp2[1]), ctx); + emit(ARM_ADD_I(tmp[1], tmp[1], ctx->prologue_bytes), ctx); + emit(ARM_BX(tmp[1]), ctx); + + /* out: */ + if (out_offset == -1) + out_offset = cur_offset; + if (cur_offset != out_offset) { + pr_err_once("tail_call out_offset = %d, expected %d!\n", + cur_offset, out_offset); + return -1; + } + return 0; +#undef cur_offset +#undef jmp_offset } -static int build_body(struct jit_ctx *ctx) +/* 0xabcd => 0xcdab */ +static inline void emit_rev16(const u8 rd, const u8 rn, struct jit_ctx *ctx) { - void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w}; - const struct bpf_prog *prog = ctx->skf; - const struct sock_filter *inst; - unsigned i, load_order, off, condt; - int imm12; - u32 k; +#if __LINUX_ARM_ARCH__ < 6 + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + + emit(ARM_AND_I(tmp2[1], rn, 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], rn, SRTYPE_LSR, 8), ctx); + emit(ARM_AND_I(tmp2[0], tmp2[0], 0xff), ctx); + emit(ARM_ORR_SI(rd, tmp2[0], tmp2[1], SRTYPE_LSL, 8), ctx); +#else /* ARMv6+ */ + emit(ARM_REV16(rd, rn), ctx); +#endif +} - for (i = 0; i < prog->len; i++) { - u16 code; +/* 0xabcdefgh => 0xghefcdab */ +static inline void emit_rev32(const u8 rd, const u8 rn, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 6 + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + + emit(ARM_AND_I(tmp2[1], rn, 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], rn, SRTYPE_LSR, 24), ctx); + emit(ARM_ORR_SI(ARM_IP, tmp2[0], tmp2[1], SRTYPE_LSL, 24), ctx); + + emit(ARM_MOV_SI(tmp2[1], rn, SRTYPE_LSR, 8), ctx); + emit(ARM_AND_I(tmp2[1], tmp2[1], 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], rn, SRTYPE_LSR, 16), ctx); + emit(ARM_AND_I(tmp2[0], tmp2[0], 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], tmp2[0], SRTYPE_LSL, 8), ctx); + emit(ARM_ORR_SI(tmp2[0], tmp2[0], tmp2[1], SRTYPE_LSL, 16), ctx); + emit(ARM_ORR_R(rd, ARM_IP, tmp2[0]), ctx); + +#else /* ARMv6+ */ + emit(ARM_REV(rd, rn), ctx); +#endif +} - inst = &(prog->insns[i]); - /* K as an immediate value operand */ - k = inst->k; - code = bpf_anc_helper(inst); +// push the scratch stack register on top of the stack +static inline void emit_push_r64(const u8 src[], const u8 shift, + struct jit_ctx *ctx) +{ + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + u16 reg_set = 0; - /* compute offsets only in the fake pass */ - if (ctx->target == NULL) - ctx->offsets[i] = ctx->idx * 4; + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(src[1]+shift)), ctx); + emit(ARM_LDR_I(tmp2[0], ARM_SP, STACK_VAR(src[0]+shift)), ctx); + + reg_set = (1 << tmp2[1]) | (1 << tmp2[0]); + emit(ARM_PUSH(reg_set), ctx); +} + +static void build_prologue(struct jit_ctx *ctx) +{ + const u8 r0 = bpf2a32[BPF_REG_0][1]; + const u8 r2 = bpf2a32[BPF_REG_1][1]; + const u8 r3 = bpf2a32[BPF_REG_1][0]; + const u8 r4 = bpf2a32[BPF_REG_6][1]; + const u8 r5 = bpf2a32[BPF_REG_6][0]; + const u8 r6 = bpf2a32[TMP_REG_1][1]; + const u8 r7 = bpf2a32[TMP_REG_1][0]; + const u8 r8 = bpf2a32[TMP_REG_2][1]; + const u8 r10 = bpf2a32[TMP_REG_2][0]; + const u8 fplo = bpf2a32[BPF_REG_FP][1]; + const u8 fphi = bpf2a32[BPF_REG_FP][0]; + const u8 sp = ARM_SP; + const u8 *tcc = bpf2a32[TCALL_CNT]; + + u16 reg_set = 0; + + /* + * eBPF prog stack layout + * + * high + * original ARM_SP => +-----+ eBPF prologue + * |FP/LR| + * current ARM_FP => +-----+ + * | ... | callee saved registers + * eBPF fp register => +-----+ <= (BPF_FP) + * | ... | eBPF JIT scratch space + * | | eBPF prog stack + * +-----+ + * |RSVD | JIT scratchpad + * current A64_SP => +-----+ <= (BPF_FP - STACK_SIZE) + * | | + * | ... | Function call stack + * | | + * +-----+ + * low + */ + + /* Save callee saved registers. */ + reg_set |= (1<seen & SEEN_CALL) + reg_set |= (1<stack_size = imm8m(STACK_SIZE); + + /* Set up function call stack */ + emit(ARM_SUB_I(ARM_SP, ARM_SP, ctx->stack_size), ctx); - switch (code) { - case BPF_LD | BPF_IMM: - emit_mov_i(r_A, k, ctx); + /* Set up BPF prog stack base register */ + emit_a32_mov_r(fplo, ARM_IP, true, false, ctx); + emit_a32_mov_i(fphi, 0, true, ctx); + + /* mov r4, 0 */ + emit(ARM_MOV_I(r4, 0), ctx); + + /* Move BPF_CTX to BPF_R1 */ + emit(ARM_MOV_R(r3, r4), ctx); + emit(ARM_MOV_R(r2, r0), ctx); + /* Initialize Tail Count */ + emit(ARM_STR_I(r4, ARM_SP, STACK_VAR(tcc[0])), ctx); + emit(ARM_STR_I(r4, ARM_SP, STACK_VAR(tcc[1])), ctx); + /* end of prologue */ +} + +static void build_epilogue(struct jit_ctx *ctx) +{ + const u8 r4 = bpf2a32[BPF_REG_6][1]; + const u8 r5 = bpf2a32[BPF_REG_6][0]; + const u8 r6 = bpf2a32[TMP_REG_1][1]; + const u8 r7 = bpf2a32[TMP_REG_1][0]; + const u8 r8 = bpf2a32[TMP_REG_2][1]; + const u8 r10 = bpf2a32[TMP_REG_2][0]; + u16 reg_set = 0; + + /* unwind function call stack */ + emit(ARM_ADD_I(ARM_SP, ARM_SP, ctx->stack_size), ctx); + + /* restore callee saved registers. */ + reg_set |= (1<seen & SEEN_CALL) + reg_set |= (1<seen & SEEN_CALL)) + emit(ARM_BX(ARM_LR), ctx); +#endif +} + +/* + * Convert an eBPF instruction to native instruction, i.e + * JITs an eBPF instruction. + * Returns : + * 0 - Successfully JITed an 8-byte eBPF instruction + * >0 - Successfully JITed a 16-byte eBPF instruction + * <0 - Failed to JIT. + */ +static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) +{ + const u8 code = insn->code; + const u8 *dst = bpf2a32[insn->dst_reg]; + const u8 *src = bpf2a32[insn->src_reg]; + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + const s16 off = insn->off; + const s32 imm = insn->imm; + const int i = insn - ctx->prog->insnsi; + const bool is64 = BPF_CLASS(code) == BPF_ALU64; + const bool dstk = is_on_stack(insn->dst_reg); + const bool sstk = is_on_stack(insn->src_reg); + u8 rd, rt, rm, rn; + s32 jmp_offset; + +#define check_imm(bits, imm) do { \ + if ((((imm) > 0) && ((imm) >> (bits))) || \ + (((imm) < 0) && (~(imm) >> (bits)))) { \ + pr_info("[%2d] imm=%d(0x%x) out of range\n", \ + i, imm, imm); \ + return -EINVAL; \ + } \ +} while (0) +#define check_imm24(imm) check_imm(24, imm) + + switch (code) { + /* ALU operations */ + + /* dst = src */ + case BPF_ALU | BPF_MOV | BPF_K: + case BPF_ALU | BPF_MOV | BPF_X: + case BPF_ALU64 | BPF_MOV | BPF_K: + case BPF_ALU64 | BPF_MOV | BPF_X: + switch (BPF_SRC(code)) { + case BPF_X: + emit_a32_mov_r64(is64, dst, src, dstk, sstk, ctx); break; - case BPF_LD | BPF_W | BPF_LEN: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); - emit(ARM_LDR_I(r_A, r_skb, - offsetof(struct sk_buff, len)), ctx); + case BPF_K: + /* Sign-extend immediate value to destination reg */ + emit_a32_mov_i64(is64, dst, imm, dstk, ctx); break; - case BPF_LD | BPF_MEM: - /* A = scratch[k] */ - ctx->seen |= SEEN_MEM_WORD(k); - emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); + } + break; + /* dst = dst + src/imm */ + /* dst = dst - src/imm */ + /* dst = dst | src/imm */ + /* dst = dst & src/imm */ + /* dst = dst ^ src/imm */ + /* dst = dst * src/imm */ + /* dst = dst << src */ + /* dst = dst >> src */ + case BPF_ALU | BPF_ADD | BPF_K: + case BPF_ALU | BPF_ADD | BPF_X: + case BPF_ALU | BPF_SUB | BPF_K: + case BPF_ALU | BPF_SUB | BPF_X: + case BPF_ALU | BPF_OR | BPF_K: + case BPF_ALU | BPF_OR | BPF_X: + case BPF_ALU | BPF_AND | BPF_K: + case BPF_ALU | BPF_AND | BPF_X: + case BPF_ALU | BPF_XOR | BPF_K: + case BPF_ALU | BPF_XOR | BPF_X: + case BPF_ALU | BPF_MUL | BPF_K: + case BPF_ALU | BPF_MUL | BPF_X: + case BPF_ALU | BPF_LSH | BPF_X: + case BPF_ALU | BPF_RSH | BPF_X: + case BPF_ALU | BPF_ARSH | BPF_K: + case BPF_ALU | BPF_ARSH | BPF_X: + case BPF_ALU64 | BPF_ADD | BPF_K: + case BPF_ALU64 | BPF_ADD | BPF_X: + case BPF_ALU64 | BPF_SUB | BPF_K: + case BPF_ALU64 | BPF_SUB | BPF_X: + case BPF_ALU64 | BPF_OR | BPF_K: + case BPF_ALU64 | BPF_OR | BPF_X: + case BPF_ALU64 | BPF_AND | BPF_K: + case BPF_ALU64 | BPF_AND | BPF_X: + case BPF_ALU64 | BPF_XOR | BPF_K: + case BPF_ALU64 | BPF_XOR | BPF_X: + switch (BPF_SRC(code)) { + case BPF_X: + emit_a32_alu_r64(is64, dst, src, dstk, sstk, + ctx, BPF_OP(code)); break; - case BPF_LD | BPF_W | BPF_ABS: - load_order = 2; - goto load; - case BPF_LD | BPF_H | BPF_ABS: - load_order = 1; - goto load; - case BPF_LD | BPF_B | BPF_ABS: - load_order = 0; -load: - emit_mov_i(r_off, k, ctx); -load_common: - ctx->seen |= SEEN_DATA | SEEN_CALL; - - if (load_order > 0) { - emit(ARM_SUB_I(r_scratch, r_skb_hl, - 1 << load_order), ctx); - emit(ARM_CMP_R(r_scratch, r_off), ctx); - condt = ARM_COND_GE; - } else { - emit(ARM_CMP_R(r_skb_hl, r_off), ctx); - condt = ARM_COND_HI; - } - - /* - * test for negative offset, only if we are - * currently scheduled to take the fast - * path. this will update the flags so that - * the slowpath instruction are ignored if the - * offset is negative. - * - * for loard_order == 0 the HI condition will - * make loads at offset 0 take the slow path too. + case BPF_K: + /* Move immediate value to the temporary register + * and then do the ALU operation on the temporary + * register as this will sign-extend the immediate + * value into temporary reg and then it would be + * safe to do the operation on it. */ - _emit(condt, ARM_CMP_I(r_off, 0), ctx); - - _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data), - ctx); - - if (load_order == 0) - _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0), - ctx); - else if (load_order == 1) - emit_load_be16(condt, r_A, r_scratch, ctx); - else if (load_order == 2) - emit_load_be32(condt, r_A, r_scratch, ctx); - - _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx); - - /* the slowpath */ - emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx); - emit(ARM_MOV_R(ARM_R0, r_skb), ctx); - /* the offset is already in R1 */ - emit_blx_r(ARM_R3, ctx); - /* check the result of skb_copy_bits */ - emit(ARM_CMP_I(ARM_R1, 0), ctx); - emit_err_ret(ARM_COND_NE, ctx); - emit(ARM_MOV_R(r_A, ARM_R0), ctx); + emit_a32_mov_i64(is64, tmp2, imm, false, ctx); + emit_a32_alu_r64(is64, dst, tmp2, dstk, false, + ctx, BPF_OP(code)); break; - case BPF_LD | BPF_W | BPF_IND: - load_order = 2; - goto load_ind; - case BPF_LD | BPF_H | BPF_IND: - load_order = 1; - goto load_ind; - case BPF_LD | BPF_B | BPF_IND: - load_order = 0; -load_ind: - update_on_xread(ctx); - OP_IMM3(ARM_ADD, r_off, r_X, k, ctx); - goto load_common; - case BPF_LDX | BPF_IMM: - ctx->seen |= SEEN_X; - emit_mov_i(r_X, k, ctx); + } + break; + /* dst = dst / src(imm) */ + /* dst = dst % src(imm) */ + case BPF_ALU | BPF_DIV | BPF_K: + case BPF_ALU | BPF_DIV | BPF_X: + case BPF_ALU | BPF_MOD | BPF_K: + case BPF_ALU | BPF_MOD | BPF_X: + rt = src_lo; + rd = dstk ? tmp2[1] : dst_lo; + if (dstk) + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + switch (BPF_SRC(code)) { + case BPF_X: + rt = sstk ? tmp2[0] : rt; + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), + ctx); break; - case BPF_LDX | BPF_W | BPF_LEN: - ctx->seen |= SEEN_X | SEEN_SKB; - emit(ARM_LDR_I(r_X, r_skb, - offsetof(struct sk_buff, len)), ctx); + case BPF_K: + rt = tmp2[0]; + emit_a32_mov_i(rt, imm, false, ctx); break; - case BPF_LDX | BPF_MEM: - ctx->seen |= SEEN_X | SEEN_MEM_WORD(k); - emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); + } + emit_udivmod(rd, rd, rt, ctx, BPF_OP(code)); + if (dstk) + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + case BPF_ALU64 | BPF_DIV | BPF_K: + case BPF_ALU64 | BPF_DIV | BPF_X: + case BPF_ALU64 | BPF_MOD | BPF_K: + case BPF_ALU64 | BPF_MOD | BPF_X: + goto notyet; + /* dst = dst >> imm */ + /* dst = dst << imm */ + case BPF_ALU | BPF_RSH | BPF_K: + case BPF_ALU | BPF_LSH | BPF_K: + if (unlikely(imm > 31)) + return -EINVAL; + if (imm) + emit_a32_alu_i(dst_lo, imm, dstk, ctx, BPF_OP(code)); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + /* dst = dst << imm */ + case BPF_ALU64 | BPF_LSH | BPF_K: + if (unlikely(imm > 63)) + return -EINVAL; + emit_a32_lsh_i64(dst, dstk, imm, ctx); + break; + /* dst = dst >> imm */ + case BPF_ALU64 | BPF_RSH | BPF_K: + if (unlikely(imm > 63)) + return -EINVAL; + emit_a32_lsr_i64(dst, dstk, imm, ctx); + break; + /* dst = dst << src */ + case BPF_ALU64 | BPF_LSH | BPF_X: + emit_a32_lsh_r64(dst, src, dstk, sstk, ctx); + break; + /* dst = dst >> src */ + case BPF_ALU64 | BPF_RSH | BPF_X: + emit_a32_lsr_r64(dst, src, dstk, sstk, ctx); + break; + /* dst = dst >> src (signed) */ + case BPF_ALU64 | BPF_ARSH | BPF_X: + emit_a32_arsh_r64(dst, src, dstk, sstk, ctx); + break; + /* dst = dst >> imm (signed) */ + case BPF_ALU64 | BPF_ARSH | BPF_K: + if (unlikely(imm > 63)) + return -EINVAL; + emit_a32_arsh_i64(dst, dstk, imm, ctx); + break; + /* dst = ~dst */ + case BPF_ALU | BPF_NEG: + emit_a32_alu_i(dst_lo, 0, dstk, ctx, BPF_OP(code)); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + /* dst = ~dst (64 bit) */ + case BPF_ALU64 | BPF_NEG: + emit_a32_neg64(dst, dstk, ctx); + break; + /* dst = dst * src/imm */ + case BPF_ALU64 | BPF_MUL | BPF_X: + case BPF_ALU64 | BPF_MUL | BPF_K: + switch (BPF_SRC(code)) { + case BPF_X: + emit_a32_mul_r64(dst, src, dstk, sstk, ctx); break; - case BPF_LDX | BPF_B | BPF_MSH: - /* x = ((*(frame + k)) & 0xf) << 2; */ - ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL; - /* the interpreter should deal with the negative K */ - if ((int)k < 0) - return -1; - /* offset in r1: we might have to take the slow path */ - emit_mov_i(r_off, k, ctx); - emit(ARM_CMP_R(r_skb_hl, r_off), ctx); - - /* load in r0: common with the slowpath */ - _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data, - ARM_R1), ctx); - /* - * emit_mov_i() might generate one or two instructions, - * the same holds for emit_blx_r() + case BPF_K: + /* Move immediate value to the temporary register + * and then do the multiplication on it as this + * will sign-extend the immediate value into temp + * reg then it would be safe to do the operation + * on it. */ - _emit(ARM_COND_HI, ARM_B(b_imm(i + 1, ctx) - 2), ctx); - - emit(ARM_MOV_R(ARM_R0, r_skb), ctx); - /* r_off is r1 */ - emit_mov_i(ARM_R3, (u32)jit_get_skb_b, ctx); - emit_blx_r(ARM_R3, ctx); - /* check the return value of skb_copy_bits */ - emit(ARM_CMP_I(ARM_R1, 0), ctx); - emit_err_ret(ARM_COND_NE, ctx); - - emit(ARM_AND_I(r_X, ARM_R0, 0x00f), ctx); - emit(ARM_LSL_I(r_X, r_X, 2), ctx); - break; - case BPF_ST: - ctx->seen |= SEEN_MEM_WORD(k); - emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); - break; - case BPF_STX: - update_on_xread(ctx); - ctx->seen |= SEEN_MEM_WORD(k); - emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); - break; - case BPF_ALU | BPF_ADD | BPF_K: - /* A += K */ - OP_IMM3(ARM_ADD, r_A, r_A, k, ctx); - break; - case BPF_ALU | BPF_ADD | BPF_X: - update_on_xread(ctx); - emit(ARM_ADD_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_SUB | BPF_K: - /* A -= K */ - OP_IMM3(ARM_SUB, r_A, r_A, k, ctx); - break; - case BPF_ALU | BPF_SUB | BPF_X: - update_on_xread(ctx); - emit(ARM_SUB_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_MUL | BPF_K: - /* A *= K */ - emit_mov_i(r_scratch, k, ctx); - emit(ARM_MUL(r_A, r_A, r_scratch), ctx); - break; - case BPF_ALU | BPF_MUL | BPF_X: - update_on_xread(ctx); - emit(ARM_MUL(r_A, r_A, r_X), ctx); + emit_a32_mov_i64(is64, tmp2, imm, false, ctx); + emit_a32_mul_r64(dst, tmp2, dstk, false, ctx); break; - case BPF_ALU | BPF_DIV | BPF_K: - if (k == 1) - break; - emit_mov_i(r_scratch, k, ctx); - emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_DIV); - break; - case BPF_ALU | BPF_DIV | BPF_X: - update_on_xread(ctx); - emit(ARM_CMP_I(r_X, 0), ctx); - emit_err_ret(ARM_COND_EQ, ctx); - emit_udivmod(r_A, r_A, r_X, ctx, BPF_DIV); + } + break; + /* dst = htole(dst) */ + /* dst = htobe(dst) */ + case BPF_ALU | BPF_END | BPF_FROM_LE: + case BPF_ALU | BPF_END | BPF_FROM_BE: + rd = dstk ? tmp[0] : dst_hi; + rt = dstk ? tmp[1] : dst_lo; + if (dstk) { + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + if (BPF_SRC(code) == BPF_FROM_LE) + goto emit_bswap_uxt; + switch (imm) { + case 16: + emit_rev16(rt, rt, ctx); + goto emit_bswap_uxt; + case 32: + emit_rev32(rt, rt, ctx); + goto emit_bswap_uxt; + case 64: + /* Because of the usage of ARM_LR */ + ctx->seen |= SEEN_CALL; + emit_rev32(ARM_LR, rt, ctx); + emit_rev32(rt, rd, ctx); + emit(ARM_MOV_R(rd, ARM_LR), ctx); break; - case BPF_ALU | BPF_MOD | BPF_K: - if (k == 1) { - emit_mov_i(r_A, 0, ctx); - break; - } - emit_mov_i(r_scratch, k, ctx); - emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_MOD); + } + goto exit; +emit_bswap_uxt: + switch (imm) { + case 16: + /* zero-extend 16 bits into 64 bits */ +#if __LINUX_ARM_ARCH__ < 6 + emit_a32_mov_i(tmp2[1], 0xffff, false, ctx); + emit(ARM_AND_R(rt, rt, tmp2[1]), ctx); +#else /* ARMv6+ */ + emit(ARM_UXTH(rt, rt), ctx); +#endif + emit(ARM_EOR_R(rd, rd, rd), ctx); break; - case BPF_ALU | BPF_MOD | BPF_X: - update_on_xread(ctx); - emit(ARM_CMP_I(r_X, 0), ctx); - emit_err_ret(ARM_COND_EQ, ctx); - emit_udivmod(r_A, r_A, r_X, ctx, BPF_MOD); + case 32: + /* zero-extend 32 bits into 64 bits */ + emit(ARM_EOR_R(rd, rd, rd), ctx); break; - case BPF_ALU | BPF_OR | BPF_K: - /* A |= K */ - OP_IMM3(ARM_ORR, r_A, r_A, k, ctx); + case 64: + /* nop */ break; - case BPF_ALU | BPF_OR | BPF_X: - update_on_xread(ctx); - emit(ARM_ORR_R(r_A, r_A, r_X), ctx); + } +exit: + if (dstk) { + emit(ARM_STR_I(rt, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + break; + /* dst = imm64 */ + case BPF_LD | BPF_IMM | BPF_DW: + { + const struct bpf_insn insn1 = insn[1]; + u32 hi, lo = imm; + + hi = insn1.imm; + emit_a32_mov_i(dst_lo, lo, dstk, ctx); + emit_a32_mov_i(dst_hi, hi, dstk, ctx); + + return 1; + } + /* LDX: dst = *(size *)(src + off) */ + case BPF_LDX | BPF_MEM | BPF_W: + case BPF_LDX | BPF_MEM | BPF_H: + case BPF_LDX | BPF_MEM | BPF_B: + case BPF_LDX | BPF_MEM | BPF_DW: + rn = sstk ? tmp2[1] : src_lo; + if (sstk) + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx); + switch (BPF_SIZE(code)) { + case BPF_W: + /* Load a Word */ + case BPF_H: + /* Load a Half-Word */ + case BPF_B: + /* Load a Byte */ + emit_ldx_r(dst_lo, rn, dstk, off, ctx, BPF_SIZE(code)); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); break; - case BPF_ALU | BPF_XOR | BPF_K: - /* A ^= K; */ - OP_IMM3(ARM_EOR, r_A, r_A, k, ctx); + case BPF_DW: + /* Load a double word */ + emit_ldx_r(dst_lo, rn, dstk, off, ctx, BPF_W); + emit_ldx_r(dst_hi, rn, dstk, off+4, ctx, BPF_W); break; - case BPF_ANC | SKF_AD_ALU_XOR_X: - case BPF_ALU | BPF_XOR | BPF_X: - /* A ^= X */ - update_on_xread(ctx); - emit(ARM_EOR_R(r_A, r_A, r_X), ctx); + } + break; + /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */ + case BPF_LD | BPF_ABS | BPF_W: + case BPF_LD | BPF_ABS | BPF_H: + case BPF_LD | BPF_ABS | BPF_B: + /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + src + imm)) */ + case BPF_LD | BPF_IND | BPF_W: + case BPF_LD | BPF_IND | BPF_H: + case BPF_LD | BPF_IND | BPF_B: + { + const u8 r4 = bpf2a32[BPF_REG_6][1]; /* r4 = ptr to sk_buff */ + const u8 r0 = bpf2a32[BPF_REG_0][1]; /*r0: struct sk_buff *skb*/ + /* rtn value */ + const u8 r1 = bpf2a32[BPF_REG_0][0]; /* r1: int k */ + const u8 r2 = bpf2a32[BPF_REG_1][1]; /* r2: unsigned int size */ + const u8 r3 = bpf2a32[BPF_REG_1][0]; /* r3: void *buffer */ + const u8 r6 = bpf2a32[TMP_REG_1][1]; /* r6: void *(*func)(..) */ + int size; + + /* Setting up first argument */ + emit(ARM_MOV_R(r0, r4), ctx); + + /* Setting up second argument */ + emit_a32_mov_i(r1, imm, false, ctx); + if (BPF_MODE(code) == BPF_IND) + emit_a32_alu_r(r1, src_lo, false, sstk, ctx, + false, false, BPF_ADD); + + /* Setting up third argument */ + switch (BPF_SIZE(code)) { + case BPF_W: + size = 4; break; - case BPF_ALU | BPF_AND | BPF_K: - /* A &= K */ - OP_IMM3(ARM_AND, r_A, r_A, k, ctx); + case BPF_H: + size = 2; break; - case BPF_ALU | BPF_AND | BPF_X: - update_on_xread(ctx); - emit(ARM_AND_R(r_A, r_A, r_X), ctx); + case BPF_B: + size = 1; break; - case BPF_ALU | BPF_LSH | BPF_K: - if (unlikely(k > 31)) - return -1; - emit(ARM_LSL_I(r_A, r_A, k), ctx); + default: + return -EINVAL; + } + emit_a32_mov_i(r2, size, false, ctx); + + /* Setting up fourth argument */ + emit(ARM_ADD_I(r3, ARM_SP, imm8m(SKB_BUFFER)), ctx); + + /* Setting up function pointer to call */ + emit_a32_mov_i(r6, (unsigned int)bpf_load_pointer, false, ctx); + emit_blx_r(r6, ctx); + + emit(ARM_EOR_R(r1, r1, r1), ctx); + /* Check if return address is NULL or not. + * if NULL then jump to epilogue + * else continue to load the value from retn address + */ + emit(ARM_CMP_I(r0, 0), ctx); + jmp_offset = epilogue_offset(ctx); + check_imm24(jmp_offset); + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); + + /* Load value from the address */ + switch (BPF_SIZE(code)) { + case BPF_W: + emit(ARM_LDR_I(r0, r0, 0), ctx); + emit_rev32(r0, r0, ctx); break; - case BPF_ALU | BPF_LSH | BPF_X: - update_on_xread(ctx); - emit(ARM_LSL_R(r_A, r_A, r_X), ctx); + case BPF_H: + emit(ARM_LDRH_I(r0, r0, 0), ctx); + emit_rev16(r0, r0, ctx); break; - case BPF_ALU | BPF_RSH | BPF_K: - if (unlikely(k > 31)) - return -1; - if (k) - emit(ARM_LSR_I(r_A, r_A, k), ctx); + case BPF_B: + emit(ARM_LDRB_I(r0, r0, 0), ctx); + /* No need to reverse */ break; - case BPF_ALU | BPF_RSH | BPF_X: - update_on_xread(ctx); - emit(ARM_LSR_R(r_A, r_A, r_X), ctx); + } + break; + } + /* ST: *(size *)(dst + off) = imm */ + case BPF_ST | BPF_MEM | BPF_W: + case BPF_ST | BPF_MEM | BPF_H: + case BPF_ST | BPF_MEM | BPF_B: + case BPF_ST | BPF_MEM | BPF_DW: + switch (BPF_SIZE(code)) { + case BPF_DW: + /* Sign-extend immediate value into temp reg */ + emit_a32_mov_i64(true, tmp2, imm, false, ctx); + emit_str_r(dst_lo, tmp2[1], dstk, off, ctx, BPF_W); + emit_str_r(dst_lo, tmp2[0], dstk, off+4, ctx, BPF_W); break; - case BPF_ALU | BPF_NEG: - /* A = -A */ - emit(ARM_RSB_I(r_A, r_A, 0), ctx); + case BPF_W: + case BPF_H: + case BPF_B: + emit_a32_mov_i(tmp2[1], imm, false, ctx); + emit_str_r(dst_lo, tmp2[1], dstk, off, ctx, + BPF_SIZE(code)); break; - case BPF_JMP | BPF_JA: - /* pc += K */ - emit(ARM_B(b_imm(i + k + 1, ctx)), ctx); + } + break; + /* STX XADD: lock *(u32 *)(dst + off) += src */ + case BPF_STX | BPF_XADD | BPF_W: + /* STX XADD: lock *(u64 *)(dst + off) += src */ + case BPF_STX | BPF_XADD | BPF_DW: + goto notyet; + /* STX: *(size *)(dst + off) = src */ + case BPF_STX | BPF_MEM | BPF_W: + case BPF_STX | BPF_MEM | BPF_H: + case BPF_STX | BPF_MEM | BPF_B: + case BPF_STX | BPF_MEM | BPF_DW: + { + u8 sz = BPF_SIZE(code); + + rn = sstk ? tmp2[1] : src_lo; + rm = sstk ? tmp2[0] : src_hi; + if (sstk) { + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(src_hi)), ctx); + } + + /* Store the value */ + if (BPF_SIZE(code) == BPF_DW) { + emit_str_r(dst_lo, rn, dstk, off, ctx, BPF_W); + emit_str_r(dst_lo, rm, dstk, off+4, ctx, BPF_W); + } else { + emit_str_r(dst_lo, rn, dstk, off, ctx, sz); + } + break; + } + /* PC += off if dst == src */ + /* PC += off if dst > src */ + /* PC += off if dst >= src */ + /* PC += off if dst < src */ + /* PC += off if dst <= src */ + /* PC += off if dst != src */ + /* PC += off if dst > src (signed) */ + /* PC += off if dst >= src (signed) */ + /* PC += off if dst < src (signed) */ + /* PC += off if dst <= src (signed) */ + /* PC += off if dst & src */ + case BPF_JMP | BPF_JEQ | BPF_X: + case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JNE | BPF_X: + case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSET | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: + /* Setup source registers */ + rm = sstk ? tmp2[0] : src_hi; + rn = sstk ? tmp2[1] : src_lo; + if (sstk) { + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(src_hi)), ctx); + } + goto go_jmp; + /* PC += off if dst == imm */ + /* PC += off if dst > imm */ + /* PC += off if dst >= imm */ + /* PC += off if dst < imm */ + /* PC += off if dst <= imm */ + /* PC += off if dst != imm */ + /* PC += off if dst > imm (signed) */ + /* PC += off if dst >= imm (signed) */ + /* PC += off if dst < imm (signed) */ + /* PC += off if dst <= imm (signed) */ + /* PC += off if dst & imm */ + case BPF_JMP | BPF_JEQ | BPF_K: + case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JNE | BPF_K: + case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSET | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: + if (off == 0) break; - case BPF_JMP | BPF_JEQ | BPF_K: - /* pc += (A == K) ? pc->jt : pc->jf */ - condt = ARM_COND_EQ; - goto cmp_imm; - case BPF_JMP | BPF_JGT | BPF_K: - /* pc += (A > K) ? pc->jt : pc->jf */ - condt = ARM_COND_HI; - goto cmp_imm; - case BPF_JMP | BPF_JGE | BPF_K: - /* pc += (A >= K) ? pc->jt : pc->jf */ - condt = ARM_COND_HS; -cmp_imm: - imm12 = imm8m(k); - if (imm12 < 0) { - emit_mov_i_no8m(r_scratch, k, ctx); - emit(ARM_CMP_R(r_A, r_scratch), ctx); - } else { - emit(ARM_CMP_I(r_A, imm12), ctx); - } -cond_jump: - if (inst->jt) - _emit(condt, ARM_B(b_imm(i + inst->jt + 1, - ctx)), ctx); - if (inst->jf) - _emit(condt ^ 1, ARM_B(b_imm(i + inst->jf + 1, - ctx)), ctx); + rm = tmp2[0]; + rn = tmp2[1]; + /* Sign-extend immediate value */ + emit_a32_mov_i64(true, tmp2, imm, false, ctx); +go_jmp: + /* Setup destination register */ + rd = dstk ? tmp[0] : dst_hi; + rt = dstk ? tmp[1] : dst_lo; + if (dstk) { + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Check for the condition */ + emit_ar_r(rd, rt, rm, rn, ctx, BPF_OP(code)); + + /* Setup JUMP instruction */ + jmp_offset = bpf2a32_offset(i+off, i, ctx); + switch (BPF_OP(code)) { + case BPF_JNE: + case BPF_JSET: + _emit(ARM_COND_NE, ARM_B(jmp_offset), ctx); break; - case BPF_JMP | BPF_JEQ | BPF_X: - /* pc += (A == X) ? pc->jt : pc->jf */ - condt = ARM_COND_EQ; - goto cmp_x; - case BPF_JMP | BPF_JGT | BPF_X: - /* pc += (A > X) ? pc->jt : pc->jf */ - condt = ARM_COND_HI; - goto cmp_x; - case BPF_JMP | BPF_JGE | BPF_X: - /* pc += (A >= X) ? pc->jt : pc->jf */ - condt = ARM_COND_CS; -cmp_x: - update_on_xread(ctx); - emit(ARM_CMP_R(r_A, r_X), ctx); - goto cond_jump; - case BPF_JMP | BPF_JSET | BPF_K: - /* pc += (A & K) ? pc->jt : pc->jf */ - condt = ARM_COND_NE; - /* not set iff all zeroes iff Z==1 iff EQ */ - - imm12 = imm8m(k); - if (imm12 < 0) { - emit_mov_i_no8m(r_scratch, k, ctx); - emit(ARM_TST_R(r_A, r_scratch), ctx); - } else { - emit(ARM_TST_I(r_A, imm12), ctx); - } - goto cond_jump; - case BPF_JMP | BPF_JSET | BPF_X: - /* pc += (A & X) ? pc->jt : pc->jf */ - update_on_xread(ctx); - condt = ARM_COND_NE; - emit(ARM_TST_R(r_A, r_X), ctx); - goto cond_jump; - case BPF_RET | BPF_A: - emit(ARM_MOV_R(ARM_R0, r_A), ctx); - goto b_epilogue; - case BPF_RET | BPF_K: - if ((k == 0) && (ctx->ret0_fp_idx < 0)) - ctx->ret0_fp_idx = i; - emit_mov_i(ARM_R0, k, ctx); -b_epilogue: - if (i != ctx->skf->len - 1) - emit(ARM_B(b_imm(prog->len, ctx)), ctx); + case BPF_JEQ: + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); break; - case BPF_MISC | BPF_TAX: - /* X = A */ - ctx->seen |= SEEN_X; - emit(ARM_MOV_R(r_X, r_A), ctx); + case BPF_JGT: + _emit(ARM_COND_HI, ARM_B(jmp_offset), ctx); break; - case BPF_MISC | BPF_TXA: - /* A = X */ - update_on_xread(ctx); - emit(ARM_MOV_R(r_A, r_X), ctx); + case BPF_JGE: + _emit(ARM_COND_CS, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_PROTOCOL: - /* A = ntohs(skb->protocol) */ - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, - protocol) != 2); - off = offsetof(struct sk_buff, protocol); - emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx); - emit_swap16(r_A, r_scratch, ctx); + case BPF_JSGT: + _emit(ARM_COND_LT, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_CPU: - /* r_scratch = current_thread_info() */ - OP_IMM3(ARM_BIC, r_scratch, ARM_SP, THREAD_SIZE - 1, ctx); - /* A = current_thread_info()->cpu */ - BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); - off = offsetof(struct thread_info, cpu); - emit(ARM_LDR_I(r_A, r_scratch, off), ctx); + case BPF_JSGE: + _emit(ARM_COND_GE, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_IFINDEX: - case BPF_ANC | SKF_AD_HATYPE: - /* A = skb->dev->ifindex */ - /* A = skb->dev->type */ - ctx->seen |= SEEN_SKB; - off = offsetof(struct sk_buff, dev); - emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); - - emit(ARM_CMP_I(r_scratch, 0), ctx); - emit_err_ret(ARM_COND_EQ, ctx); - - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, - ifindex) != 4); - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, - type) != 2); - - if (code == (BPF_ANC | SKF_AD_IFINDEX)) { - off = offsetof(struct net_device, ifindex); - emit(ARM_LDR_I(r_A, r_scratch, off), ctx); - } else { - /* - * offset of field "type" in "struct - * net_device" is above what can be - * used in the ldrh rd, [rn, #imm] - * instruction, so load the offset in - * a register and use ldrh rd, [rn, rm] - */ - off = offsetof(struct net_device, type); - emit_mov_i(ARM_R3, off, ctx); - emit(ARM_LDRH_R(r_A, r_scratch, ARM_R3), ctx); - } + case BPF_JLE: + _emit(ARM_COND_LS, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_MARK: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); - off = offsetof(struct sk_buff, mark); - emit(ARM_LDR_I(r_A, r_skb, off), ctx); + case BPF_JLT: + _emit(ARM_COND_CC, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_RXHASH: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); - off = offsetof(struct sk_buff, hash); - emit(ARM_LDR_I(r_A, r_skb, off), ctx); + case BPF_JSLT: + _emit(ARM_COND_LT, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_VLAN_TAG: - case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); - off = offsetof(struct sk_buff, vlan_tci); - emit(ARM_LDRH_I(r_A, r_skb, off), ctx); - if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) - OP_IMM3(ARM_AND, r_A, r_A, ~VLAN_TAG_PRESENT, ctx); - else { - OP_IMM3(ARM_LSR, r_A, r_A, 12, ctx); - OP_IMM3(ARM_AND, r_A, r_A, 0x1, ctx); - } + case BPF_JSLE: + _emit(ARM_COND_GE, ARM_B(jmp_offset), ctx); break; - case BPF_ANC | SKF_AD_PKTTYPE: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, - __pkt_type_offset[0]) != 1); - off = PKT_TYPE_OFFSET(); - emit(ARM_LDRB_I(r_A, r_skb, off), ctx); - emit(ARM_AND_I(r_A, r_A, PKT_TYPE_MAX), ctx); -#ifdef __BIG_ENDIAN_BITFIELD - emit(ARM_LSR_I(r_A, r_A, 5), ctx); -#endif + } + break; + /* JMP OFF */ + case BPF_JMP | BPF_JA: + { + if (off == 0) break; - case BPF_ANC | SKF_AD_QUEUE: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, - queue_mapping) != 2); - BUILD_BUG_ON(offsetof(struct sk_buff, - queue_mapping) > 0xff); - off = offsetof(struct sk_buff, queue_mapping); - emit(ARM_LDRH_I(r_A, r_skb, off), ctx); + jmp_offset = bpf2a32_offset(i+off, i, ctx); + check_imm24(jmp_offset); + emit(ARM_B(jmp_offset), ctx); + break; + } + /* tail call */ + case BPF_JMP | BPF_TAIL_CALL: + if (emit_bpf_tail_call(ctx)) + return -EFAULT; + break; + /* function call */ + case BPF_JMP | BPF_CALL: + { + const u8 *r0 = bpf2a32[BPF_REG_0]; + const u8 *r1 = bpf2a32[BPF_REG_1]; + const u8 *r2 = bpf2a32[BPF_REG_2]; + const u8 *r3 = bpf2a32[BPF_REG_3]; + const u8 *r4 = bpf2a32[BPF_REG_4]; + const u8 *r5 = bpf2a32[BPF_REG_5]; + const u32 func = (u32)__bpf_call_base + (u32)imm; + + emit_a32_mov_r64(true, r0, r1, false, false, ctx); + emit_a32_mov_r64(true, r1, r2, false, true, ctx); + emit_push_r64(r5, 0, ctx); + emit_push_r64(r4, 8, ctx); + emit_push_r64(r3, 16, ctx); + + emit_a32_mov_i(tmp[1], func, false, ctx); + emit_blx_r(tmp[1], ctx); + + emit(ARM_ADD_I(ARM_SP, ARM_SP, imm8m(24)), ctx); // callee clean + break; + } + /* function return */ + case BPF_JMP | BPF_EXIT: + /* Optimization: when last instruction is EXIT + * simply fallthrough to epilogue. + */ + if (i == ctx->prog->len - 1) break; - case BPF_ANC | SKF_AD_PAY_OFFSET: - ctx->seen |= SEEN_SKB | SEEN_CALL; + jmp_offset = epilogue_offset(ctx); + check_imm24(jmp_offset); + emit(ARM_B(jmp_offset), ctx); + break; +notyet: + pr_info_once("*** NOT YET: opcode %02x ***\n", code); + return -EFAULT; + default: + pr_err_once("unknown opcode %02x\n", code); + return -EINVAL; + } - emit(ARM_MOV_R(ARM_R0, r_skb), ctx); - emit_mov_i(ARM_R3, (unsigned int)skb_get_poff, ctx); - emit_blx_r(ARM_R3, ctx); - emit(ARM_MOV_R(r_A, ARM_R0), ctx); - break; - case BPF_LDX | BPF_W | BPF_ABS: - /* - * load a 32bit word from struct seccomp_data. - * seccomp_check_filter() will already have checked - * that k is 32bit aligned and lies within the - * struct seccomp_data. - */ - ctx->seen |= SEEN_SKB; - emit(ARM_LDR_I(r_A, r_skb, k), ctx); - break; - default: - return -1; + if (ctx->flags & FLAG_IMM_OVERFLOW) + /* + * this instruction generated an overflow when + * trying to access the literal pool, so + * delegate this filter to the kernel interpreter. + */ + return -1; + return 0; +} + +static int build_body(struct jit_ctx *ctx) +{ + const struct bpf_prog *prog = ctx->prog; + unsigned int i; + + for (i = 0; i < prog->len; i++) { + const struct bpf_insn *insn = &(prog->insnsi[i]); + int ret; + + ret = build_insn(insn, ctx); + + /* It's used with loading the 64 bit immediate value. */ + if (ret > 0) { + i++; + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx; + continue; } - if (ctx->flags & FLAG_IMM_OVERFLOW) - /* - * this instruction generated an overflow when - * trying to access the literal pool, so - * delegate this filter to the kernel interpreter. - */ - return -1; + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx; + + /* If unsuccesfull, return with error code */ + if (ret) + return ret; } + return 0; +} - /* compute offsets only during the first pass */ - if (ctx->target == NULL) - ctx->offsets[i] = ctx->idx * 4; +static int validate_code(struct jit_ctx *ctx) +{ + int i; + + for (i = 0; i < ctx->idx; i++) { + if (ctx->target[i] == __opcode_to_mem_arm(ARM_INST_UDF)) + return -1; + } return 0; } +void bpf_jit_compile(struct bpf_prog *prog) +{ + /* Nothing to do here. We support Internal BPF. */ +} -void bpf_jit_compile(struct bpf_prog *fp) +struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) { + struct bpf_prog *tmp, *orig_prog = prog; struct bpf_binary_header *header; + bool tmp_blinded = false; struct jit_ctx ctx; - unsigned tmp_idx; - unsigned alloc_size; - u8 *target_ptr; + unsigned int tmp_idx; + unsigned int image_size; + u8 *image_ptr; + /* If BPF JIT was not enabled then we must fall back to + * the interpreter. + */ if (!bpf_jit_enable) - return; + return orig_prog; - memset(&ctx, 0, sizeof(ctx)); - ctx.skf = fp; - ctx.ret0_fp_idx = -1; + /* If constant blinding was enabled and we failed during blinding + * then we must fall back to the interpreter. Otherwise, we save + * the new JITed code. + */ + tmp = bpf_jit_blind_constants(prog); - ctx.offsets = kzalloc(4 * (ctx.skf->len + 1), GFP_KERNEL); - if (ctx.offsets == NULL) - return; + if (IS_ERR(tmp)) + return orig_prog; + if (tmp != prog) { + tmp_blinded = true; + prog = tmp; + } - /* fake pass to fill in the ctx->seen */ - if (unlikely(build_body(&ctx))) + memset(&ctx, 0, sizeof(ctx)); + ctx.prog = prog; + + /* Not able to allocate memory for offsets[] , then + * we must fall back to the interpreter + */ + ctx.offsets = kcalloc(prog->len, sizeof(int), GFP_KERNEL); + if (ctx.offsets == NULL) { + prog = orig_prog; goto out; + } + + /* 1) fake pass to find in the length of the JITed code, + * to compute ctx->offsets and other context variables + * needed to compute final JITed code. + * Also, calculate random starting pointer/start of JITed code + * which is prefixed by random number of fault instructions. + * + * If the first pass fails then there is no chance of it + * being successful in the second pass, so just fall back + * to the interpreter. + */ + if (build_body(&ctx)) { + prog = orig_prog; + goto out_off; + } tmp_idx = ctx.idx; build_prologue(&ctx); ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4; + ctx.epilogue_offset = ctx.idx; + #if __LINUX_ARM_ARCH__ < 7 tmp_idx = ctx.idx; build_epilogue(&ctx); @@ -1021,64 +1880,83 @@ void bpf_jit_compile(struct bpf_prog *fp) ctx.idx += ctx.imm_count; if (ctx.imm_count) { - ctx.imms = kzalloc(4 * ctx.imm_count, GFP_KERNEL); - if (ctx.imms == NULL) - goto out; + ctx.imms = kcalloc(ctx.imm_count, sizeof(u32), GFP_KERNEL); + if (ctx.imms == NULL) { + prog = orig_prog; + goto out_off; + } } #else - /* there's nothing after the epilogue on ARMv7 */ + /* there's nothing about the epilogue on ARMv7 */ build_epilogue(&ctx); #endif - alloc_size = 4 * ctx.idx; - header = bpf_jit_binary_alloc(alloc_size, &target_ptr, - 4, jit_fill_hole); - if (header == NULL) - goto out; + /* Now we can get the actual image size of the JITed arm code. + * Currently, we are not considering the THUMB-2 instructions + * for jit, although it can decrease the size of the image. + * + * As each arm instruction is of length 32bit, we are translating + * number of JITed intructions into the size required to store these + * JITed code. + */ + image_size = sizeof(u32) * ctx.idx; - ctx.target = (u32 *) target_ptr; + /* Now we know the size of the structure to make */ + header = bpf_jit_binary_alloc(image_size, &image_ptr, + sizeof(u32), jit_fill_hole); + /* Not able to allocate memory for the structure then + * we must fall back to the interpretation + */ + if (header == NULL) { + prog = orig_prog; + goto out_imms; + } + + /* 2.) Actual pass to generate final JIT code */ + ctx.target = (u32 *) image_ptr; ctx.idx = 0; build_prologue(&ctx); + + /* If building the body of the JITed code fails somehow, + * we fall back to the interpretation. + */ if (build_body(&ctx) < 0) { -#if __LINUX_ARM_ARCH__ < 7 - if (ctx.imm_count) - kfree(ctx.imms); -#endif + image_ptr = NULL; bpf_jit_binary_free(header); - goto out; + prog = orig_prog; + goto out_imms; } build_epilogue(&ctx); + /* 3.) Extra pass to validate JITed Code */ + if (validate_code(&ctx)) { + image_ptr = NULL; + bpf_jit_binary_free(header); + prog = orig_prog; + goto out_imms; + } flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx)); -#if __LINUX_ARM_ARCH__ < 7 - if (ctx.imm_count) - kfree(ctx.imms); -#endif - if (bpf_jit_enable > 1) /* there are 2 passes here */ - bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); + bpf_jit_dump(prog->len, image_size, 2, ctx.target); set_memory_ro((unsigned long)header, header->pages); - fp->bpf_func = (void *)ctx.target; - fp->jited = 1; -out: + prog->bpf_func = (void *)ctx.target; + prog->jited = 1; + prog->jited_len = image_size; + +out_imms: +#if __LINUX_ARM_ARCH__ < 7 + if (ctx.imm_count) + kfree(ctx.imms); +#endif +out_off: kfree(ctx.offsets); - return; +out: + if (tmp_blinded) + bpf_jit_prog_release_other(prog, prog == orig_prog ? + tmp : orig_prog); + return prog; } -void bpf_jit_free(struct bpf_prog *fp) -{ - unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; - struct bpf_binary_header *header = (void *)addr; - - if (!fp->jited) - goto free_filter; - - set_memory_rw(addr, header->pages); - bpf_jit_binary_free(header); - -free_filter: - bpf_prog_unlock_free(fp); -} diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h index c46fca2972f750ad434d202716a67929bd73f4c4..d5cf5f6208aa7c993a191564699c00216762c0bb 100644 --- a/arch/arm/net/bpf_jit_32.h +++ b/arch/arm/net/bpf_jit_32.h @@ -11,6 +11,7 @@ #ifndef PFILTER_OPCODES_ARM_H #define PFILTER_OPCODES_ARM_H +/* ARM 32bit Registers */ #define ARM_R0 0 #define ARM_R1 1 #define ARM_R2 2 @@ -22,38 +23,43 @@ #define ARM_R8 8 #define ARM_R9 9 #define ARM_R10 10 -#define ARM_FP 11 -#define ARM_IP 12 -#define ARM_SP 13 -#define ARM_LR 14 -#define ARM_PC 15 - -#define ARM_COND_EQ 0x0 -#define ARM_COND_NE 0x1 -#define ARM_COND_CS 0x2 +#define ARM_FP 11 /* Frame Pointer */ +#define ARM_IP 12 /* Intra-procedure scratch register */ +#define ARM_SP 13 /* Stack pointer: as load/store base reg */ +#define ARM_LR 14 /* Link Register */ +#define ARM_PC 15 /* Program counter */ + +#define ARM_COND_EQ 0x0 /* == */ +#define ARM_COND_NE 0x1 /* != */ +#define ARM_COND_CS 0x2 /* unsigned >= */ #define ARM_COND_HS ARM_COND_CS -#define ARM_COND_CC 0x3 +#define ARM_COND_CC 0x3 /* unsigned < */ #define ARM_COND_LO ARM_COND_CC -#define ARM_COND_MI 0x4 -#define ARM_COND_PL 0x5 -#define ARM_COND_VS 0x6 -#define ARM_COND_VC 0x7 -#define ARM_COND_HI 0x8 -#define ARM_COND_LS 0x9 -#define ARM_COND_GE 0xa -#define ARM_COND_LT 0xb -#define ARM_COND_GT 0xc -#define ARM_COND_LE 0xd -#define ARM_COND_AL 0xe +#define ARM_COND_MI 0x4 /* < 0 */ +#define ARM_COND_PL 0x5 /* >= 0 */ +#define ARM_COND_VS 0x6 /* Signed Overflow */ +#define ARM_COND_VC 0x7 /* No Signed Overflow */ +#define ARM_COND_HI 0x8 /* unsigned > */ +#define ARM_COND_LS 0x9 /* unsigned <= */ +#define ARM_COND_GE 0xa /* Signed >= */ +#define ARM_COND_LT 0xb /* Signed < */ +#define ARM_COND_GT 0xc /* Signed > */ +#define ARM_COND_LE 0xd /* Signed <= */ +#define ARM_COND_AL 0xe /* None */ /* register shift types */ #define SRTYPE_LSL 0 #define SRTYPE_LSR 1 #define SRTYPE_ASR 2 #define SRTYPE_ROR 3 +#define SRTYPE_ASL (SRTYPE_LSL) #define ARM_INST_ADD_R 0x00800000 +#define ARM_INST_ADDS_R 0x00900000 +#define ARM_INST_ADC_R 0x00a00000 +#define ARM_INST_ADC_I 0x02a00000 #define ARM_INST_ADD_I 0x02800000 +#define ARM_INST_ADDS_I 0x02900000 #define ARM_INST_AND_R 0x00000000 #define ARM_INST_AND_I 0x02000000 @@ -76,8 +82,10 @@ #define ARM_INST_LDRH_I 0x01d000b0 #define ARM_INST_LDRH_R 0x019000b0 #define ARM_INST_LDR_I 0x05900000 +#define ARM_INST_LDR_R 0x07900000 #define ARM_INST_LDM 0x08900000 +#define ARM_INST_LDM_IA 0x08b00000 #define ARM_INST_LSL_I 0x01a00000 #define ARM_INST_LSL_R 0x01a00010 @@ -86,6 +94,7 @@ #define ARM_INST_LSR_R 0x01a00030 #define ARM_INST_MOV_R 0x01a00000 +#define ARM_INST_MOVS_R 0x01b00000 #define ARM_INST_MOV_I 0x03a00000 #define ARM_INST_MOVW 0x03000000 #define ARM_INST_MOVT 0x03400000 @@ -96,17 +105,28 @@ #define ARM_INST_PUSH 0x092d0000 #define ARM_INST_ORR_R 0x01800000 +#define ARM_INST_ORRS_R 0x01900000 #define ARM_INST_ORR_I 0x03800000 #define ARM_INST_REV 0x06bf0f30 #define ARM_INST_REV16 0x06bf0fb0 #define ARM_INST_RSB_I 0x02600000 +#define ARM_INST_RSBS_I 0x02700000 +#define ARM_INST_RSC_I 0x02e00000 #define ARM_INST_SUB_R 0x00400000 +#define ARM_INST_SUBS_R 0x00500000 +#define ARM_INST_RSB_R 0x00600000 #define ARM_INST_SUB_I 0x02400000 +#define ARM_INST_SUBS_I 0x02500000 +#define ARM_INST_SBC_I 0x02c00000 +#define ARM_INST_SBC_R 0x00c00000 +#define ARM_INST_SBCS_R 0x00d00000 #define ARM_INST_STR_I 0x05800000 +#define ARM_INST_STRB_I 0x05c00000 +#define ARM_INST_STRH_I 0x01c000b0 #define ARM_INST_TST_R 0x01100000 #define ARM_INST_TST_I 0x03100000 @@ -117,6 +137,8 @@ #define ARM_INST_MLS 0x00600090 +#define ARM_INST_UXTH 0x06ff0070 + /* * Use a suitable undefined instruction to use for ARM/Thumb2 faulting. * We need to be careful not to conflict with those used by other modules @@ -135,9 +157,15 @@ #define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm)) /* immediate */ #define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm)) +/* register with register-shift */ +#define _AL3_SR(inst) (inst | (1 << 4)) #define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm) +#define ARM_ADDS_R(rd, rn, rm) _AL3_R(ARM_INST_ADDS, rd, rn, rm) #define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm) +#define ARM_ADDS_I(rd, rn, imm) _AL3_I(ARM_INST_ADDS, rd, rn, imm) +#define ARM_ADC_R(rd, rn, rm) _AL3_R(ARM_INST_ADC, rd, rn, rm) +#define ARM_ADC_I(rd, rn, imm) _AL3_I(ARM_INST_ADC, rd, rn, imm) #define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm) #define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm) @@ -156,7 +184,9 @@ #define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm) #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ - | (off)) + | ((off) & 0xfff)) +#define ARM_LDR_R(rt, rn, rm) (ARM_INST_LDR_R | (rt) << 12 | (rn) << 16 \ + | (rm)) #define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ | (off)) #define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \ @@ -167,15 +197,23 @@ | (rm)) #define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs)) +#define ARM_LDM_IA(rn, regs) (ARM_INST_LDM_IA | (rn) << 16 | (regs)) #define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8) #define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7) #define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8) #define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7) +#define ARM_ASR_R(rd, rn, rm) (_AL3_R(ARM_INST_ASR, rd, 0, rn) | (rm) << 8) +#define ARM_ASR_I(rd, rn, imm) (_AL3_I(ARM_INST_ASR, rd, 0, rn) | (imm) << 7) #define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm) +#define ARM_MOVS_R(rd, rm) _AL3_R(ARM_INST_MOVS, rd, 0, rm) #define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm) +#define ARM_MOV_SR(rd, rm, type, rs) \ + (_AL3_SR(ARM_MOV_R(rd, rm)) | (type) << 5 | (rs) << 8) +#define ARM_MOV_SI(rd, rm, type, imm6) \ + (ARM_MOV_R(rd, rm) | (type) << 5 | (imm6) << 7) #define ARM_MOVW(rd, imm) \ (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff)) @@ -190,19 +228,38 @@ #define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm) #define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm) -#define ARM_ORR_S(rd, rn, rm, type, rs) \ - (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7) +#define ARM_ORR_SR(rd, rn, rm, type, rs) \ + (_AL3_SR(ARM_ORR_R(rd, rn, rm)) | (type) << 5 | (rs) << 8) +#define ARM_ORRS_R(rd, rn, rm) _AL3_R(ARM_INST_ORRS, rd, rn, rm) +#define ARM_ORRS_SR(rd, rn, rm, type, rs) \ + (_AL3_SR(ARM_ORRS_R(rd, rn, rm)) | (type) << 5 | (rs) << 8) +#define ARM_ORR_SI(rd, rn, rm, type, imm6) \ + (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (imm6) << 7) +#define ARM_ORRS_SI(rd, rn, rm, type, imm6) \ + (ARM_ORRS_R(rd, rn, rm) | (type) << 5 | (imm6) << 7) #define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm)) #define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm)) #define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm) +#define ARM_RSBS_I(rd, rn, imm) _AL3_I(ARM_INST_RSBS, rd, rn, imm) +#define ARM_RSC_I(rd, rn, imm) _AL3_I(ARM_INST_RSC, rd, rn, imm) #define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm) +#define ARM_SUBS_R(rd, rn, rm) _AL3_R(ARM_INST_SUBS, rd, rn, rm) +#define ARM_RSB_R(rd, rn, rm) _AL3_R(ARM_INST_RSB, rd, rn, rm) +#define ARM_SBC_R(rd, rn, rm) _AL3_R(ARM_INST_SBC, rd, rn, rm) +#define ARM_SBCS_R(rd, rn, rm) _AL3_R(ARM_INST_SBCS, rd, rn, rm) #define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm) +#define ARM_SUBS_I(rd, rn, imm) _AL3_I(ARM_INST_SUBS, rd, rn, imm) +#define ARM_SBC_I(rd, rn, imm) _AL3_I(ARM_INST_SBC, rd, rn, imm) #define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \ - | (off)) + | ((off) & 0xfff)) +#define ARM_STRH_I(rt, rn, off) (ARM_INST_STRH_I | (rt) << 12 | (rn) << 16 \ + | (((off) & 0xf0) << 4) | ((off) & 0xf)) +#define ARM_STRB_I(rt, rn, off) (ARM_INST_STRB_I | (rt) << 12 | (rn) << 16 \ + | (((off) & 0xf0) << 4) | ((off) & 0xf)) #define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm) #define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm) @@ -214,5 +271,6 @@ #define ARM_MLS(rd, rn, rm, ra) (ARM_INST_MLS | (rd) << 16 | (rn) | (rm) << 8 \ | (ra) << 12) +#define ARM_UXTH(rd, rm) (ARM_INST_UXTH | (rd) << 12 | (rm)) #endif /* PFILTER_OPCODES_ARM_H */ diff --git a/arch/arm/plat-samsung/include/plat/map-s3c.h b/arch/arm/plat-samsung/include/plat/map-s3c.h index 6feedd47d87543d8cc802f9e8d8679cc9df07b55..33104911862e39d6c585beb1d252bc379607e659 100644 --- a/arch/arm/plat-samsung/include/plat/map-s3c.h +++ b/arch/arm/plat-samsung/include/plat/map-s3c.h @@ -61,7 +61,7 @@ /* deal with the registers that move under the 2412/2413 */ -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#if defined(CONFIG_CPU_S3C2412) #ifndef __ASSEMBLY__ extern void __iomem *s3c24xx_va_gpio2; #endif diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index dfd908630631a30851a8f573e41dbe8b21af5f19..0df64a6a56d4985b9c9da0ea3b9092adddb71194 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -75,6 +75,7 @@ config ARM64 select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE + select HAVE_ARCH_VMAP_STACK select HAVE_ARM_SMCCC select HAVE_EBPF_JIT select HAVE_C_RECORDMCOUNT @@ -960,6 +961,18 @@ config ARM64_UAO regular load/store instructions if the cpu does not implement the feature. +config ARM64_PMEM + bool "Enable support for persistent memory" + select ARCH_HAS_PMEM_API + select ARCH_HAS_UACCESS_FLUSHCACHE + help + Say Y to enable support for the persistent memory API based on the + ARMv8.2 DCPoP feature. + + The feature is detected at runtime, and the kernel will use DC CVAC + operations if DC CVAP is not supported (following the behaviour of + DC CVAP itself if the system does not define a point of persistence). + endmenu config ARM64_MODULE_CMODEL_LARGE diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index f5f0c813dfecc56cf21e0ae18b8b0c34197aad86..6b54ee8c1262dd1587b9081ef8894166b0c14211 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -184,6 +184,12 @@ config ARCH_R8A7796 help This enables support for the Renesas R-Car M3-W SoC. +config ARCH_R8A77995 + bool "Renesas R-Car D3 SoC Platform" + depends on ARCH_RENESAS + help + This enables support for the Renesas R-Car D3 SoC. + config ARCH_STRATIX10 bool "Altera's Stratix 10 SoCFPGA Family" help @@ -250,6 +256,7 @@ config ARCH_XGENE config ARCH_ZX bool "ZTE ZX SoC Family" + select PINCTRL help This enables support for ZTE ZX SoC Family diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 9b41f1e3b1a039cd45fe842e10abff0181186fdf..939b310913cf38cd7ca3136128fb5440340d7d12 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -50,17 +50,22 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads) KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) +KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) +KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) + ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__ AS += -EB LD += -EB +LDFLAGS += -maarch64linuxb UTS_MACHINE := aarch64_be else KBUILD_CPPFLAGS += -mlittle-endian CHECKFLAGS += -D__AARCH64EL__ AS += -EL LD += -EL +LDFLAGS += -maarch64linux UTS_MACHINE := aarch64 endif diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index 108f12ce6d1d0706900d46533b9dd3cb33bb368f..19c3fbd75eda663b9a3ed61993ed353bf465cc0f 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile @@ -1,4 +1,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb diff --git a/arch/arm64/boot/dts/allwinner/axp803.dtsi b/arch/arm64/boot/dts/allwinner/axp803.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..ff8af52743ff4c2e714e233d5fd21e38d4c2d9f9 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/axp803.dtsi @@ -0,0 +1,150 @@ +/* + * Copyright 2017 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * AXP803 Integrated Power Management Chip + * http://files.pine64.org/doc/datasheet/pine64/AXP803_Datasheet_V1.0.pdf + */ + +&axp803 { + interrupt-controller; + #interrupt-cells = <1>; + + regulators { + /* Default work frequency for buck regulators */ + x-powers,dcdc-freq = <3000>; + + reg_aldo1: aldo1 { + regulator-name = "aldo1"; + }; + + reg_aldo2: aldo2 { + regulator-name = "aldo2"; + }; + + reg_aldo3: aldo3 { + regulator-name = "aldo3"; + }; + + reg_dc1sw: dc1sw { + regulator-name = "dc1sw"; + }; + + reg_dcdc1: dcdc1 { + regulator-name = "dcdc1"; + }; + + reg_dcdc2: dcdc2 { + regulator-name = "dcdc2"; + }; + + reg_dcdc3: dcdc3 { + regulator-name = "dcdc3"; + }; + + reg_dcdc4: dcdc4 { + regulator-name = "dcdc4"; + }; + + reg_dcdc5: dcdc5 { + regulator-name = "dcdc5"; + }; + + reg_dcdc6: dcdc6 { + regulator-name = "dcdc6"; + }; + + reg_dldo1: dldo1 { + regulator-name = "dldo1"; + }; + + reg_dldo2: dldo2 { + regulator-name = "dldo2"; + }; + + reg_dldo3: dldo3 { + regulator-name = "dldo3"; + }; + + reg_dldo4: dldo4 { + regulator-name = "dldo4"; + }; + + reg_eldo1: eldo1 { + regulator-name = "eldo1"; + }; + + reg_eldo2: eldo2 { + regulator-name = "eldo2"; + }; + + reg_eldo3: eldo3 { + regulator-name = "eldo3"; + }; + + reg_fldo1: fldo1 { + regulator-name = "fldo1"; + }; + + reg_fldo2: fldo2 { + regulator-name = "fldo2"; + }; + + reg_ldo_io0: ldo-io0 { + regulator-name = "ldo-io0"; + status = "disabled"; + }; + + reg_ldo_io1: ldo-io1 { + regulator-name = "ldo-io1"; + status = "disabled"; + }; + + reg_rtc_ldo: rtc-ldo { + /* RTC_LDO is a fixed, always-on regulator */ + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "rtc-ldo"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts index 0d1f026d831aac7b7ecda69ac5ec0f57e693ec2b..d347f52e27f6070ebf79a5f6fe890feecee2a94b 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts @@ -59,19 +59,13 @@ stdout-path = "serial0:115200n8"; }; - reg_vcc3v3: vcc3v3 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ }; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii"; - phy-handle = <&ext_rgmii_phy>; +&ehci1 { status = "okay"; }; @@ -85,17 +79,10 @@ bias-pull-up; }; -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; cd-inverted; disable-wp; @@ -106,22 +93,143 @@ &mmc1 { pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dldo2>; + vqmmc-supply = <®_dldo4>; + mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; non-removable; status = "okay"; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + interrupt-parent = <&r_pio>; + interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */ + interrupt-names = "host-wake"; + }; }; &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; cap-mmc-hw-reset; status = "okay"; }; +&ohci1 { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi-dsi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + +®_dldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-io"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -133,3 +241,7 @@ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; status = "okay"; }; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts new file mode 100644 index 0000000000000000000000000000000000000000..2beef9e6cb885c0cfd6774175910735e9faa78f7 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2017 Jagan Teki + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "sun50i-a64.dtsi" + +#include + +/ { + model = "FriendlyARM NanoPi A64"; + compatible = "friendlyarm,nanopi-a64", "allwinner,sun50i-a64"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +/* i2c1 connected with gpio headers like pine64, bananapi */ +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "disabled"; +}; + +&i2c1_pins { + bias-pull-up; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; + cd-inverted; + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-3v"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi-dsi"; +}; + +®_dldo4 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pg-wifi-io"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts new file mode 100644 index 0000000000000000000000000000000000000000..338e786155b1f77f4bd206d30c02445125c5967e --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2017 Jagan Teki + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "sun50i-a64.dtsi" + +#include + +/ { + model = "Olimex A64-Olinuxino"; + compatible = "olimex,a64-olinuxino", "allwinner,sun50i-a64"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; + cd-inverted; + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc-pe"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-ddr3"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi"; +}; + +®_dldo3 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc-avdd-csi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-io"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_eldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dvdd-csi"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts index 24f1aac366d64355f5b6b37bb8e263bcce7f2e2d..f82ccf332c0fac86f2756f5818610d086d1c2cc1 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts @@ -48,18 +48,3 @@ /* TODO: Camera, touchscreen, etc. */ }; - -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii"; - phy-handle = <&ext_rgmii_phy>; - status = "okay"; -}; - -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts index 08cda24ea194cbffd08fc8de50dc7a4d525e5019..caf8b6fbe5e350de2095d16489f19ce734ca4bc3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts @@ -78,15 +78,6 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&rmii_pins>; - phy-mode = "rmii"; - phy-handle = <&ext_rmii_phy1>; - status = "okay"; - -}; - &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins>; @@ -97,13 +88,6 @@ bias-pull-up; }; -&mdio { - ext_rmii_phy1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; @@ -123,6 +107,118 @@ status = "okay"; }; +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +/* + * The DRAM chips used by Pine64 boards are DDR3L-compatible, so they can + * work at 1.35V with less power consumption. + * As AXP803 DCDC5 cannot reach 1.35V accurately, use 1.36V instead. + */ +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1360000>; + regulator-max-microvolt = <1360000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + /* On Exp and Euler connectors */ &uart0 { pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts index 17eb1cc5bf6b4061a8ea8cf40e54b4eb52c1ebe3..17ccc12b58df7057ebf695b8c3e4696c7dbbd868 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts @@ -76,21 +76,6 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii"; - phy-handle = <&ext_rgmii_phy>; - status = "okay"; -}; - -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; - &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; @@ -110,6 +95,28 @@ status = "okay"; }; +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi index 475518b031dd811269c2e1c1616056f877197af8..a5da18a6f2866d34537c55dcc5d3288daf6c8331 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi @@ -63,3 +63,89 @@ bus-width = <4>; status = "okay"; }; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_eldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vdd-1v8-lpddr"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 9d00622ce8453820441e9c3c26980cab35c3dcd8..8c8db1b057dfc687aa5bcabce4732cc3653bebbd 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -449,26 +449,6 @@ #size-cells = <0>; }; - emac: ethernet@1c30000 { - compatible = "allwinner,sun50i-a64-emac"; - syscon = <&syscon>; - reg = <0x01c30000 0x100>; - interrupts = ; - interrupt-names = "macirq"; - resets = <&ccu RST_BUS_EMAC>; - reset-names = "stmmaceth"; - clocks = <&ccu CLK_BUS_EMAC>; - clock-names = "stmmaceth"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - - mdio: mdio { - #address-cells = <1>; - #size-cells = <0>; - }; - }; - gic: interrupt-controller@1c81000 { compatible = "arm,gic-400"; reg = <0x01c81000 0x1000>, @@ -487,6 +467,15 @@ ; }; + r_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun50i-a64-r-intc", + "allwinner,sun6i-a31-r-intc"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x01f00c00 0x400>; + interrupts = ; + }; + r_ccu: clock@1f01400 { compatible = "allwinner,sun50i-a64-r-ccu"; reg = <0x01f01400 0x100>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts index 9689087611945ff8f7bd3413d1c4b3e39ad14357..1c2387bd5df6f13cae7201e656923704c2878c8e 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts @@ -50,7 +50,6 @@ compatible = "friendlyarm,nanopi-neo2", "allwinner,sun50i-h5"; aliases { - ethernet0 = &emac; serial0 = &uart0; }; @@ -109,22 +108,6 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; - status = "okay"; -}; - -&mdio { - ext_rgmii_phy: ethernet-phy@7 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <7>; - }; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts index a8296feee88411718818ab5452202d8b19b7b921..4f77c8470f6c3377219dd908cc76aa87cb583607 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts @@ -59,7 +59,6 @@ }; aliases { - ethernet0 = &emac; serial0 = &uart0; }; @@ -137,28 +136,12 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; - status = "okay"; -}; - &ir { pinctrl-names = "default"; pinctrl-0 = <&ir_pins_a>; status = "okay"; }; -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts index d906b302cbcdc9c6a95a1d95bbe79c3d7b853aef..6be06873e5afe55d39aab3c3564b9851bdb17637 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts @@ -54,7 +54,6 @@ compatible = "xunlong,orangepi-prime", "allwinner,sun50i-h5"; aliases { - ethernet0 = &emac; serial0 = &uart0; }; @@ -144,28 +143,12 @@ status = "okay"; }; -&emac { - pinctrl-names = "default"; - pinctrl-0 = <&emac_rgmii_pins>; - phy-supply = <®_gmac_3v3>; - phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; - status = "okay"; -}; - &ir { pinctrl-names = "default"; pinctrl-0 = <&ir_pins_a>; status = "okay"; }; -&mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; - &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 732e2e06f503c83e42c0c4925b06295e6e47dc64..d9a720bff05d39ae93941140a3a8298f0bfa6570 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -120,5 +120,8 @@ }; &pio { + interrupts = , + , + ; compatible = "allwinner,sun50i-h5-pinctrl"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi index dc478d094c113a3b9ce1a7dd13d4352cbd1a4353..4157987f4a3d2515053c1b5a49031c32f7f3b652 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi @@ -121,6 +121,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -161,7 +168,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -187,7 +195,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -205,10 +214,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 35b8c88c3220c84c76ce1b22c8440ad8fdcbaa10..f175db84628612044517ad32987aadb3f2cf2d45 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -225,7 +225,7 @@ }; uart_A: serial@84c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; reg = <0x0 0x84c0 0x0 0x14>; interrupts = ; clocks = <&xtal>; @@ -233,7 +233,7 @@ }; uart_B: serial@84dc { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; reg = <0x0 0x84dc 0x0 0x14>; interrupts = ; clocks = <&xtal>; @@ -279,7 +279,7 @@ }; uart_C: serial@8700 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; reg = <0x0 0x8700 0x0 0x14>; interrupts = ; clocks = <&xtal>; @@ -367,26 +367,40 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; - clkc_AO: clock-controller@040 { - compatible = "amlogic,gx-aoclkc", "amlogic,gxbb-aoclkc"; - reg = <0x0 0x00040 0x0 0x4>; - #clock-cells = <1>; - #reset-cells = <1>; + sysctrl_AO: sys-ctrl@0 { + compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; + reg = <0x0 0x0 0x0 0x100>; + + clkc_AO: clock-controller { + compatible = "amlogic,meson-gx-aoclkc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + }; + + cec_AO: cec@100 { + compatible = "amlogic,meson-gx-ao-cec"; + reg = <0x0 0x00100 0x0 0x14>; + interrupts = ; + }; + + sec_AO: ao-secure@140 { + compatible = "amlogic,meson-gx-ao-secure", "syscon"; + reg = <0x0 0x140 0x0 0x140>; + amlogic,has-chip-id; }; uart_AO: serial@4c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; reg = <0x0 0x004c0 0x0 0x14>; interrupts = ; - clocks = <&xtal>; status = "disabled"; }; uart_AO_B: serial@4e0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; reg = <0x0 0x004e0 0x0 0x14>; interrupts = ; - clocks = <&xtal>; status = "disabled"; }; @@ -400,7 +414,7 @@ }; pwm_AO_ab: pwm@550 { - compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; + compatible = "amlogic,meson-gx-ao-pwm", "amlogic,meson-gxbb-ao-pwm"; reg = <0x0 0x00550 0x0 0x10>; #pwm-cells = <3>; status = "disabled"; @@ -437,9 +451,9 @@ mailbox: mailbox@404 { compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu"; reg = <0 0x404 0 0x4c>; - interrupts = <0 208 IRQ_TYPE_EDGE_RISING>, - <0 209 IRQ_TYPE_EDGE_RISING>, - <0 210 IRQ_TYPE_EDGE_RISING>; + interrupts = , + , + ; #mbox-cells = <1>; }; }; @@ -448,7 +462,7 @@ compatible = "amlogic,meson-gx-dwmac", "amlogic,meson-gxbb-dwmac", "snps,dwmac"; reg = <0x0 0xc9410000 0x0 0x10000 0x0 0xc8834540 0x0 0x4>; - interrupts = <0 8 1>; + interrupts = ; interrupt-names = "macirq"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts index fa462831ccaf45b86dd6625961d8d1928537eaff..4b17a76959b2f6bff6275013d95b74c091032c51 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts @@ -107,6 +107,9 @@ states = <3300000 0>, <1800000 1>; + + regulator-settling-time-up-us = <100>; + regulator-settling-time-down-us = <5000>; }; wifi_32k: wifi-32k { @@ -175,6 +178,64 @@ pinctrl-names = "default"; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", "UART RX", "Power Control", "Power Key In", + "VCCK En", "CON1 Header Pin31", + "I2S Header Pin6", "IR In", "I2S Header Pin7", + "I2S Header Pin3", "I2S Header Pin4", + "I2S Header Pin5", "HDMI CEC", "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "Eth MDIO", "Eth MDC", "Eth RGMII RX Clk", + "Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2", + "Eth RX D3", "Eth RGMII TX Clk", "Eth TX En", + "Eth TX D0", "Eth TX D1", "Eth TX D2", "Eth TX D3", + "Eth PHY nRESET", "Eth PHY Intc", + /* Bank GPIOH */ + "HDMI HPD", "HDMI DDC SDA", "HDMI DDC SCL", + "CON1 Header Pin33", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", "eMMC D4", + "eMMC D5", "eMMC D6", "eMMC D7", "eMMC Clk", + "eMMC Reset", "eMMC CMD", + "", "", "", "", "eMMC DS", + "", "", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "VDDEE Regulator", "VCCK Regulator", + /* Bank GPIOY */ + "CON1 Header Pin7", "CON1 Header Pin11", + "CON1 Header Pin13", "CON1 Header Pin15", + "CON1 Header Pin18", "CON1 Header Pin19", + "CON1 Header Pin22", "CON1 Header Pin21", + "CON1 Header Pin24", "CON1 Header Pin23", + "CON1 Header Pin26", "CON1 Header Pin29", + "CON1 Header Pin32", "CON1 Header Pin8", + "CON1 Header Pin10", "CON1 Header Pin16", + "CON1 Header Pin12", + /* Bank GPIOX */ + "WIFI SDIO D0", "WIFI SDIO D1", "WIFI SDIO D2", + "WIFI SDIO D3", "WIFI SDIO CLK", "WIFI SDIO CMD", + "WIFI Power Enable", "WIFI WAKE HOST", + "Bluetooth PCM DOUT", "Bluetooth PCM DIN", + "Bluetooth PCM SYNC", "Bluetooth PCM CLK", + "Bluetooth UART TX", "Bluetooth UART RX", + "Bluetooth UART CTS", "Bluetooth UART RTS", + "", "", "", "WIFI 32K", "Bluetooth Enable", + "Bluetooth WAKE HOST", + /* Bank GPIOCLK */ + "", "CON1 Header Pin35", "", "", + /* GPIO_TEST_N */ + ""; +}; + &pwm_ef { status = "okay"; pinctrl-0 = <&pwm_e_pins>; @@ -192,7 +253,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>, <&sdio_irq_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -218,11 +280,16 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; - max-frequency = <100000000>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + max-frequency = <200000000>; disable-wp; cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; @@ -236,10 +303,10 @@ &sd_emmc_c { status = "disabled"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; max-frequency = <200000000>; non-removable; disable-wp; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts index a1078b3e1c760d2a1eeb7d8a70c906d25ca5a23e..38dfdde5c1473c71f5eb04ed779d1537d386fe31 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts @@ -51,7 +51,7 @@ / { compatible = "nexbox,a95x", "amlogic,meson-gxbb"; model = "NEXBOX A95X"; - + aliases { serial0 = &uart_AO; }; @@ -171,6 +171,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + ðmac { status = "okay"; pinctrl-0 = <ð_rmii_pins>; @@ -225,7 +232,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -246,7 +254,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -264,10 +273,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index d147c853ab054d86affa734311ae2c9df713ea58..1ffa1c238a725348cdcc10be5afe35be7dac1d60 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -50,7 +50,7 @@ / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; model = "Hardkernel ODROID-C2"; - + aliases { serial0 = &uart_AO; }; @@ -253,7 +253,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -271,10 +272,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; max-frequency = <200000000>; non-removable; disable-wp; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi index d904deb1018cefa602764167219d5ee3a82a385a..23c08c3afd0ab499255ff4502bc9a472aa9d4548 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi @@ -84,6 +84,9 @@ /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */ states = <1800000 0 3300000 1>; + + regulator-settling-time-up-us = <10000>; + regulator-settling-time-down-us = <150000>; }; vddio_boot: regulator-vddio_boot { @@ -148,6 +151,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -184,7 +194,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -210,10 +221,14 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; max-frequency = <100000000>; disable-wp; @@ -228,10 +243,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi index 346753fb632431f1c2e2af4d9c72b740a3f8c3b8..f2bc6dea1fc62235987f28d6ff1871913ee5753d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -155,7 +155,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins &sdio_irq_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -181,7 +182,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -198,10 +200,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts index e76ac313fef9cfb1ea97d4dc5c131d559a12d883..f7144fd5e03f43aa29288178980f75ab49c08d6e 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts @@ -108,6 +108,12 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; &cvbs_vdac_port { cvbs_vdac_out: endpoint { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 17d3efdf146968b9ea60a47ec10045e49be6a4d8..af834cdbba791ab4432065eea6b855396e1937f9 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -307,6 +307,15 @@ }; }; +&cec_AO { + clocks = <&clkc_AO CLKID_AO_CEC_32K>; + clock-names = "core"; +}; + +&clkc_AO { + compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc"; +}; + ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, @@ -383,6 +392,17 @@ }; }; + emmc_clk_gate_pins: emmc_clk_gate { + mux { + groups = "BOOT_8"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "BOOT_8"; + bias-pull-down; + }; + }; + nor_pins: nor { mux { groups = "nor_d", @@ -421,6 +441,17 @@ }; }; + sdcard_clk_gate_pins: sdcard_clk_gate { + mux { + groups = "CARD_2"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "CARD_2"; + bias-pull-down; + }; + }; + sdio_pins: sdio { mux { groups = "sdio_d0", @@ -433,6 +464,17 @@ }; }; + sdio_clk_gate_pins: sdio_clk_gate { + mux { + groups = "GPIOX_4"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "GPIOX_4"; + bias-pull-down; + }; + }; + sdio_irq_pins: sdio_irq { mux { groups = "sdio_irq"; @@ -652,21 +694,21 @@ &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, - <&xtal>, + <&clkc CLKID_SD_EMMC_A_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_b { clocks = <&clkc CLKID_SD_EMMC_B>, - <&xtal>, + <&clkc CLKID_SD_EMMC_B_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_c { clocks = <&clkc CLKID_SD_EMMC_C>, - <&xtal>, + <&clkc CLKID_SD_EMMC_C_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; @@ -682,6 +724,31 @@ clocks = <&clkc CLKID_SPI>; }; +&uart_A { + clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_AO { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_AO_B { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_B { + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + +&uart_C { + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts index 3e0c023d6abde14afa98381e02c3f1dec0c271e4..6827f235d7cfe9a94fe5fe872e01dc1256077637 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts @@ -97,6 +97,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + /* P230 has exclusive choice between internal or external PHY */ ðmac { pinctrl-0 = <ð_pins>; @@ -124,7 +131,6 @@ }; }; - &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts index 2a5804ce7f4bd6bbfe1285f3cc40786778576a09..977b4240f3c1b0de15e0b32c70aafce1123acd01 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts @@ -123,7 +123,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -141,10 +142,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <100000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts index 72c5a9f64ca8499fe83a11bdbb17c1c95c4206c6..edc512ad0bac3d5794d669dc0d21da6e266afda5 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts @@ -67,6 +67,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; @@ -105,12 +112,68 @@ linux,rc-map-name = "rc-geekbox"; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", + "UART RX", + "Power Key In", + "J9 Header Pin35", + "J9 Header Pin16", + "J9 Header Pin15", + "J9 Header Pin33", + "IR In", + "HDMI CEC", + "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "", "", "", "", "", "", "", + "", "", "", "", "", "", "", + "Power OFF", + "VCCK Enable", + /* Bank GPIOH */ + "HDMI HPD", "HDMI SDA", "HDMI SCL", + "HDMI_5V_EN", "SPDIF", + "J9 Header Pin37", + "J9 Header Pin30", + "J9 Header Pin29", + "J9 Header Pin32", + "J9 Header Pin31", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", + "eMMC D4", "eMMC D5", "eMMC D6", "eMMC D7", + "eMMC Clk", "eMMC Reset", "eMMC CMD", + "", "BOOT_MODE", "", "", "eMMC Data Strobe", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "VCCK Regulator", "VDDEE Regulator", + /* Bank GPIOX */ + "WIFI SDIO D0", "WIFI SDIO D1", "WIFI SDIO D2", + "WIFI SDIO D3", "WIFI SDIO CLK", "WIFI SDIO CMD", + "WIFI Power Enable", "WIFI WAKE HOST", + "Bluetooth PCM DOUT", "Bluetooth PCM DIN", + "Bluetooth PCM SYNC", "Bluetooth PCM CLK", + "Bluetooth UART TX", "Bluetooth UART RX", + "Bluetooth UART CTS", "Bluetooth UART RTS", + "WIFI 32K", "Bluetooth Enable", + "Bluetooth WAKE HOST", + /* Bank GPIOCLK */ + "", "J9 Header Pin39", + /* GPIO_TEST_N */ + ""; +}; + &pwm_AO_ab { status = "okay"; pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>; pinctrl-names = "default"; - clocks = <&clkc CLKID_FCLK_DIV4>; - clock-names = "clkin0"; + clocks = <&xtal> , <&xtal>; + clock-names = "clkin0", "clkin1" ; }; &pwm_ef { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts index 890821d6e52b2d01a00e06d03ded2b49e091857a..64c54c92e214d686154de4b237f71a5212c5eb20 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts @@ -10,12 +10,20 @@ #include -#include "meson-gxl-s905x-p212.dtsi" +#include "meson-gxl-s905x.dtsi" / { compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl"; model = "Libre Technology CC"; + aliases { + serial0 = &uart_AO; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + cvbs-connector { compatible = "composite-video-connector"; @@ -26,6 +34,11 @@ }; }; + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; + }; + hdmi-connector { compatible = "hdmi-connector"; type = "a"; @@ -53,6 +66,49 @@ linux,default-trigger = "heartbeat"; }; }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vcc_card: regulator-vcc-card { + compatible = "regulator-gpio"; + + regulator-name = "VCC_CARD"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + states = <3300000 0>, + <1800000 1>; + + regulator-settling-time-up-us = <200>; + regulator-settling-time-down-us = <50000>; + }; + + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; }; &cvbs_vdac_port { @@ -61,6 +117,16 @@ }; }; +ðmac { + status = "okay"; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; @@ -73,20 +139,106 @@ }; }; -/* - * The following devices exists but are exposed on the general - * purpose GPIO header. End user may well decide to use those pins - * for another purpose - */ +&pinctrl_aobus { + gpio-line-names = "UART TX", + "UART RX", + "Blue LED", + "SDCard Voltage Switch", + "7J1 Header Pin5", + "7J1 Header Pin3", + "7J1 Header Pin12", + "IR In", + "9J3 Switch HDMI CEC/7J1 Header Pin11", + "7J1 Header Pin13"; +}; -&sd_emmc_a { - status = "disabled"; +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "", "", "", "", "", "", "", + "", "", "", "", "", "", "", + "Eth Link LED", "Eth Activity LED", + /* Bank GPIOH */ + "HDMI HPD", "HDMI SDA", "HDMI SCL", + "HDMI_5V_EN", "9J1 Header Pin2", + "Analog Audio Mute", + "2J3 Header Pin6", + "2J3 Header Pin5", + "2J3 Header Pin4", + "2J3 Header Pin3", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", + "eMMC D4", "eMMC D5", "eMMC D6", "eMMC D7", + "eMMC Clk", "eMMC Reset", "eMMC CMD", + "ALT BOOT MODE", "", "", "", "eMMC Data Strobe", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", + "Green LED", "VCCK Enable", + "7J1 Header Pin27", "7J1 Header Pin28", + "VCCK Regulator", "VDDEE Regulator", + /* Bank GPIOX */ + "7J1 Header Pin22", "7J1 Header Pin26", + "7J1 Header Pin36", "7J1 Header Pin38", + "7J1 Header Pin40", "7J1 Header Pin37", + "7J1 Header Pin33", "7J1 Header Pin35", + "7J1 Header Pin19", "7J1 Header Pin21", + "7J1 Header Pin24", "7J1 Header Pin23", + "7J1 Header Pin8", "7J1 Header Pin10", + "7J1 Header Pin16", "7J1 Header Pin18", + "7J1 Header Pin32", "7J1 Header Pin29", + "7J1 Header Pin31", + /* Bank GPIOCLK */ + "7J1 Header Pin7", "", + /* GPIO_TEST_N */ + "7J1 Header Pin15"; }; -&uart_A { - status = "disabled"; +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_pins>; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + max-frequency = <100000000>; + disable-wp; + + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; + cd-inverted; + + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_card>; }; -&wifi32k { - status = "disabled"; +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-ddr-3_3v; + max-frequency = <50000000>; + non-removable; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vddio_boot>; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts index 6633a5d8fdd39193be747582e8facc8a581a9486..1b8f32867aa10ab9ae75e90c995cdf16a088632e 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts @@ -140,6 +140,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -182,7 +189,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -203,7 +211,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -221,10 +230,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts index 6ab17c1eeefdc198f7e4417baa780935b885c6c5..6e2bf858291c5f58b0268200c1a014554d24a59d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts @@ -71,6 +71,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi index f3eea8e89d12b7a4479851a8d1e0482374235568..129af9068814d3b0f8e33090adbcda435ea3e202 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi @@ -95,7 +95,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -116,7 +117,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -134,10 +136,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index 8d4f3160a0eefa1220e48541eb8e117441ed6c42..d8dd3298b15cfe5a37d653b8c6d5d39f5ca8c008 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -43,6 +43,7 @@ #include "meson-gx.dtsi" #include +#include #include #include @@ -207,6 +208,15 @@ }; }; +&cec_AO { + clocks = <&clkc_AO CLKID_AO_CEC_32K>; + clock-names = "core"; +}; + +&clkc_AO { + compatible = "amlogic,meson-gxl-aoclkc", "amlogic,meson-gx-aoclkc"; +}; + &hdmi_tx { compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; resets = <&reset RESET_HDMITX_CAPB3>, @@ -271,6 +281,17 @@ }; }; + emmc_clk_gate_pins: emmc_clk_gate { + mux { + groups = "BOOT_8"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "BOOT_8"; + bias-pull-down; + }; + }; + nor_pins: nor { mux { groups = "nor_d", @@ -309,6 +330,17 @@ }; }; + sdcard_clk_gate_pins: sdcard_clk_gate { + mux { + groups = "CARD_2"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "CARD_2"; + bias-pull-down; + }; + }; + sdio_pins: sdio { mux { groups = "sdio_d0", @@ -321,6 +353,17 @@ }; }; + sdio_clk_gate_pins: sdio_clk_gate { + mux { + groups = "GPIOX_4"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "GPIOX_4"; + bias-pull-down; + }; + }; + sdio_irq_pins: sdio_irq { mux { groups = "sdio_irq"; @@ -593,21 +636,21 @@ &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, - <&xtal>, + <&clkc CLKID_SD_EMMC_A_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_b { clocks = <&clkc CLKID_SD_EMMC_B>, - <&xtal>, + <&clkc CLKID_SD_EMMC_B_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_c { clocks = <&clkc CLKID_SD_EMMC_C>, - <&xtal>, + <&clkc CLKID_SD_EMMC_C_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; @@ -623,6 +666,31 @@ clocks = <&clkc CLKID_SPI>; }; +&uart_A { + clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + +&uart_AO { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_AO_B { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_B { + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + +&uart_C { + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + &vpu { compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts index 5f626d6830883466b80b9364547efcf066f6317b..22c697732f668c5fadb5c445a849a80e57956fe0 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts @@ -113,6 +113,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -168,7 +175,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -186,10 +194,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts index 08f1dd69b6792e3ceb54bd1e56697ce14f35df12..470f72bb863c5ff8850508cefd828b1c2e4f5f24 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts @@ -220,7 +220,6 @@ pinctrl-names = "default"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi index fe451cce93e783ce12b857117ab6c3eaa84a9108..19a798d2ae2fdd61a2c3e708dea2b1d59f71e061 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi @@ -117,6 +117,10 @@ }; }; +&clkc_AO { + compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc"; +}; + &saradc { compatible = "amlogic,meson-gxm-saradc", "amlogic,meson-saradc"; }; diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi index 72720e9132a1de4b85a53f55e5a85a95eb4c423a..c9ffffb96e431ec8d4ed875e40c33f901466b7d4 100644 --- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi @@ -626,6 +626,7 @@ 0x43000000 0xe0 0x00000000 0xe0 0x00000000 0x20 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x10 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x11 0x4 @@ -651,6 +652,7 @@ 0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x16 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x17 0x4 diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index 63be8e51eaa8624e4006e1fceda8387d61fd7ce4..c09a36fed91701be7407d6ec42584d88ad511144 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -626,6 +626,7 @@ 0x43000000 0xf0 0x00000000 0xf0 0x00000000 0x10 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x4 @@ -651,6 +652,7 @@ 0x43000000 0xd8 0x00000000 0xd8 0x00000000 0x08 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x4 @@ -676,6 +678,7 @@ 0x43000000 0x94 0x00000000 0x94 0x00000000 0x04 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x4 @@ -701,6 +704,7 @@ 0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x4 @@ -726,6 +730,7 @@ 0x43000000 0xc8 0x00000000 0xc8 0x00000000 0x08 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x4 diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi index 7cfa8e414e7f5111d9c676ee3bc9c6c2fbe8941d..8ecdd4331980e448f6a5c23ad2785cbfd19a9a10 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dtsi +++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -226,7 +226,7 @@ clock-names = "uartclk", "apb_pclk"; }; - virtio_block@0130000 { + virtio-block@0130000 { compatible = "virtio,mmio"; reg = <0x130000 0x200>; interrupts = <42>; diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index e8b7413ec890b8fc88f1fb62d691d7ffcdae8570..fbafe62d6b22deaf3bc22b361c80d38a876f8d34 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -201,7 +201,7 @@ }; }; - cpu_debug0: cpu_debug@22010000 { + cpu_debug0: cpu-debug@22010000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x22010000 0x0 0x1000>; @@ -260,7 +260,7 @@ }; }; - cpu_debug1: cpu_debug@22110000 { + cpu_debug1: cpu-debug@22110000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x22110000 0x0 0x1000>; @@ -283,7 +283,7 @@ }; }; - cpu_debug2: cpu_debug@23010000 { + cpu_debug2: cpu-debug@23010000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23010000 0x0 0x1000>; @@ -356,7 +356,7 @@ }; }; - cpu_debug3: cpu_debug@23110000 { + cpu_debug3: cpu-debug@23110000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23110000 0x0 0x1000>; @@ -379,7 +379,7 @@ }; }; - cpu_debug4: cpu_debug@23210000 { + cpu_debug4: cpu-debug@23210000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23210000 0x0 0x1000>; @@ -402,7 +402,7 @@ }; }; - cpu_debug5: cpu_debug@23310000 { + cpu_debug5: cpu-debug@23310000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23310000 0x0 0x1000>; @@ -426,7 +426,7 @@ }; replicator@20120000 { - compatible = "qcom,coresight-replicator1x", "arm,primecell"; + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0 0x20120000 0 0x1000>; clocks = <&soc_smc50mhz>; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi index 161ac98418a301ef11eafb7dd3539280cad4e9d9..528875c7559871720d0577867737f3c0987ff1f7 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -219,7 +219,7 @@ }; }; - virtio_block@0130000 { + virtio-block@0130000 { compatible = "virtio,mmio"; reg = <0x130000 0x200>; interrupts = <42>; diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile index f11bdd6689ea96b2fce04404ae2166349c7d2c26..3eaef3895d663b150fcbe4b2974c8548620cbf12 100644 --- a/arch/arm64/boot/dts/broadcom/Makefile +++ b/arch/arm64/boot/dts/broadcom/Makefile @@ -1,7 +1,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb -dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb ns2-xmc.dtb -dts-dirs := stingray +dts-dirs += northstar2 +dts-dirs += stingray always := $(dtb-y) subdir-y := $(dts-dirs) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi b/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi deleted file mode 120000 index 3937b77cb310335840d92e4d0d9e085b63d32ecb..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm2835-rpi.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts index 972f14db28accd1f25e5d5cd9d7ce2854c9976c8..699d340a3437eaaca7b56d4124706c1533d1eacf 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts @@ -1,41 +1 @@ -/dts-v1/; -#include "bcm2837.dtsi" -#include "bcm2835-rpi.dtsi" -#include "bcm283x-rpi-smsc9514.dtsi" -#include "bcm283x-rpi-usb-host.dtsi" - -/ { - compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; - model = "Raspberry Pi 3 Model B"; - - memory { - reg = <0 0x40000000>; - }; - - leds { - act { - gpios = <&gpio 47 0>; - }; - }; -}; - -&uart1 { - status = "okay"; -}; - -/* SDHCI is used to control the SDIO for wireless */ -&sdhci { - pinctrl-names = "default"; - pinctrl-0 = <&emmc_gpio34>; - status = "okay"; - bus-width = <4>; - non-removable; -}; - -/* SDHOST is used to drive the SD card */ -&sdhost { - pinctrl-names = "default"; - pinctrl-0 = <&sdhost_gpio48>; - status = "okay"; - bus-width = <4>; -}; +#include "arm/bcm2837-rpi-3-b.dts" diff --git a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi deleted file mode 120000 index dca7c057d5a573f572da3cd91ee61df988aa95a0..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm283x-rpi-smsc9514.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi deleted file mode 120000 index cbeebe312ff89553fe25ac55a6589331de79399f..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm283x-rpi-usb-host.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/bcm283x.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x.dtsi deleted file mode 120000 index 5f54e4cab99bb3253634be7907e6706ab2d9bd67..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm283x.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm283x.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/northstar2/Makefile b/arch/arm64/boot/dts/broadcom/northstar2/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e01a1485b813ea5cf57ab12efb9875d77ee58724 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/northstar2/Makefile @@ -0,0 +1,6 @@ +dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb +dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-xmc.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/broadcom/ns2-clock.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2-clock.dtsi similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2-clock.dtsi rename to arch/arm64/boot/dts/broadcom/northstar2/ns2-clock.dtsi diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2-svk.dts rename to arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts diff --git a/arch/arm64/boot/dts/broadcom/ns2-xmc.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2-xmc.dts rename to arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2.dtsi rename to arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi b/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi index 5dca7d10253bb15bd1657f199889fb48cee76c02..8862ec907fd8e9564aa9d8e5ed4aba173f6a2623 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi @@ -72,6 +72,78 @@ <0x00000008 0x80000000 0x1 0x80000000>; /* 6G @ 34G */ }; +&sata0 { + status = "okay"; +}; + +&sata_phy0{ + status = "okay"; +}; + +&sata1 { + status = "okay"; +}; + +&sata_phy1{ + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +&sata_phy2{ + status = "okay"; +}; + +&sata3 { + status = "okay"; +}; + +&sata_phy3{ + status = "okay"; +}; + +&sata4 { + status = "okay"; +}; + +&sata_phy4{ + status = "okay"; +}; + +&sata5 { + status = "okay"; +}; + +&sata_phy5{ + status = "okay"; +}; + +&sata6 { + status = "okay"; +}; + +&sata_phy6{ + status = "okay"; +}; + +&sata7 { + status = "okay"; +}; + +&sata_phy7{ + status = "okay"; +}; + +&mdio_mux_iproc { + mdio@10 { + gphy0: eth-phy@10 { + reg = <0x10>; + }; + }; +}; + &uart1 { status = "okay"; }; @@ -102,6 +174,12 @@ }; }; +&enet { + phy-mode = "rgmii-id"; + phy-handle = <&gphy0>; + status = "okay"; +}; + &nand { status = "ok"; nandcs@0 { diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts b/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts index 5671669ba34876588f6fae34fd5a711686d1d038..eb6f08cdbd796c3d764393f9e2e70db2129b0e28 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts @@ -39,6 +39,10 @@ model = "Stingray Combo SVK (BCM958742K)"; }; +&gphy0 { + enet-phy-lane-swap; +}; + &uart2 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts b/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts index 6ebe399fda6a7fa01091e8d6b6cb78b2d6c122af..5084b037320fd9cb65133ca929517062a245af3b 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts @@ -38,3 +38,7 @@ compatible = "brcm,bcm958742t", "brcm,stingray"; model = "Stingray SST100 (BCM958742T)"; }; + +&gphy0 { + enet-phy-lane-swap; +}; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-fs4.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-fs4.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..8bf1dc6b46caf303bcae63f2f1fde856127f3a94 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-fs4.dtsi @@ -0,0 +1,118 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016-2017 Broadcom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + fs4: fs4 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x67000000 0x00800000>; + + crypto_mbox: crypto_mbox@00000000 { + compatible = "brcm,iproc-flexrm-mbox"; + reg = <0x00000000 0x200000>; + msi-parent = <&gic_its 0x4100>; + #mbox-cells = <3>; + dma-coherent; + }; + + raid_mbox: raid_mbox@00400000 { + compatible = "brcm,iproc-flexrm-mbox"; + reg = <0x00400000 0x200000>; + dma-coherent; + msi-parent = <&gic_its 0x4300>; + #mbox-cells = <3>; + }; + + raid0: raid@0 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 0 0x1 0xff00>, + <&raid_mbox 1 0x1 0xff00>, + <&raid_mbox 2 0x1 0xff00>, + <&raid_mbox 3 0x1 0xff00>; + }; + + raid1: raid@1 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 4 0x1 0xff00>, + <&raid_mbox 5 0x1 0xff00>, + <&raid_mbox 6 0x1 0xff00>, + <&raid_mbox 7 0x1 0xff00>; + }; + + raid2: raid@2 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 8 0x1 0xff00>, + <&raid_mbox 9 0x1 0xff00>, + <&raid_mbox 10 0x1 0xff00>, + <&raid_mbox 11 0x1 0xff00>; + }; + + raid3: raid@3 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 12 0x1 0xff00>, + <&raid_mbox 13 0x1 0xff00>, + <&raid_mbox 14 0x1 0xff00>, + <&raid_mbox 15 0x1 0xff00>; + }; + + raid4: raid@4 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 16 0x1 0xff00>, + <&raid_mbox 17 0x1 0xff00>, + <&raid_mbox 18 0x1 0xff00>, + <&raid_mbox 19 0x1 0xff00>; + }; + + raid5: raid@5 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 20 0x1 0xff00>, + <&raid_mbox 21 0x1 0xff00>, + <&raid_mbox 22 0x1 0xff00>, + <&raid_mbox 23 0x1 0xff00>; + }; + + raid6: raid@6 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 24 0x1 0xff00>, + <&raid_mbox 25 0x1 0xff00>, + <&raid_mbox 26 0x1 0xff00>, + <&raid_mbox 27 0x1 0xff00>; + }; + + raid7: raid@7 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 28 0x1 0xff00>, + <&raid_mbox 29 0x1 0xff00>, + <&raid_mbox 30 0x1 0xff00>, + <&raid_mbox 31 0x1 0xff00>; + }; + }; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..a774709388df34dfdfb214b0736d7ebd00b0cad3 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi @@ -0,0 +1,278 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016-2017 Broadcom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + sata { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x67d00000 0x00800000>; + + sata0: ahci@00210000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00210000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata0_port0: sata-port@0 { + reg = <0>; + phys = <&sata0_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy0: sata_phy@00212100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00212100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata0_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata1: ahci@00310000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00310000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata1_port0: sata-port@0 { + reg = <0>; + phys = <&sata1_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy1: sata_phy@00312100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00312100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata1_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata2: ahci@00120000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00120000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata2_port0: sata-port@0 { + reg = <0>; + phys = <&sata2_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy2: sata_phy@00122100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00122100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata2_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata3: ahci@00130000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00130000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata3_port0: sata-port@0 { + reg = <0>; + phys = <&sata3_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy3: sata_phy@00132100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00132100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata3_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata4: ahci@00330000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00330000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata4_port0: sata-port@0 { + reg = <0>; + phys = <&sata4_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy4: sata_phy@00332100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00332100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata4_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata5: ahci@00400000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00400000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata5_port0: sata-port@0 { + reg = <0>; + phys = <&sata5_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy5: sata_phy@00402100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00402100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata5_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata6: ahci@00410000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00410000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata6_port0: sata-port@0 { + reg = <0>; + phys = <&sata6_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy6: sata_phy@00412100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00412100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata6_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata7: ahci@00420000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00420000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata7_port0: sata-port@0 { + reg = <0>; + phys = <&sata7_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy7: sata_phy@00422100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00422100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata7_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + }; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi index 49933cf16c92c5be6e138eff6110910395a4b287..e6f75c633623cf45b9efc67844149551eb343e83 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi @@ -152,6 +152,12 @@ #size-cells = <1>; ranges = <0x0 0x0 0x61000000 0x05000000>; + ccn: ccn@00000000 { + compatible = "arm,ccn-502"; + reg = <0x00000000 0x900000>; + interrupts = ; + }; + gic: interrupt-controller@02c00000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; @@ -261,6 +267,9 @@ }; }; + #include "stingray-fs4.dtsi" + #include "stingray-sata.dtsi" + hsls { compatible = "simple-bus"; #address-cells = <1>; @@ -269,6 +278,37 @@ #include "stingray-pinctrl.dtsi" + mdio_mux_iproc: mdio-mux@0002023c { + compatible = "brcm,mdio-mux-iproc"; + reg = <0x0002023c 0x14>; + #address-cells = <1>; + #size-cells = <0>; + + mdio@0 { /* PCIe serdes */ + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@2 { /* SATA */ + reg = <0x2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@3 { /* USB */ + reg = <0x3>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@10 { /* RGMII */ + reg = <0x10>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + pwm: pwm@00010000 { compatible = "brcm,iproc-pwm"; reg = <0x00010000 0x1000>; @@ -277,6 +317,93 @@ status = "disabled"; }; + timer0: timer@00030000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00030000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer1: timer@00040000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00040000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer2: timer@00050000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00050000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer3: timer@00060000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00060000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer4: timer@00070000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00070000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer5: timer@00080000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00080000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer6: timer@00090000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00090000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer7: timer@000a0000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x000a0000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + i2c0: i2c@000b0000 { compatible = "brcm,iproc-i2c"; reg = <0x000b0000 0x100>; @@ -424,6 +551,15 @@ iommus = <&smmu 0x6000 0x0000>; }; + enet: ethernet@00340000{ + compatible = "brcm,amac"; + reg = <0x00340000 0x1000>; + reg-names = "amac_base"; + dma-coherent; + interrupts = ; + status= "disabled"; + }; + nand: nand@00360000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x00360000 0x600>, diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index e2b0da2c0bc771a5d5f3ef721ee45f58ad466554..297597442c44217e0f366995314f6c458ca3c7a1 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -280,9 +280,6 @@ &decon { status = "okay"; - - i80-if-timings { - }; }; &decon_tv { @@ -310,20 +307,6 @@ samsung,pll-clock-frequency = <24000000>; pinctrl-names = "default"; pinctrl-0 = <&te_irq>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - samsung,burst-clock-frequency = <512000000>; - samsung,esc-clock-frequency = <16000000>; - }; - }; - }; }; &hdmi { @@ -846,7 +829,6 @@ &mshc_0 { status = "okay"; - num-slots = <1>; mmc-hs200-1_8v; mmc-hs400-1_8v; cap-mmc-highspeed; @@ -868,7 +850,6 @@ &mshc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; disable-wp; cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>; @@ -1116,9 +1097,6 @@ &mic { status = "okay"; - - i80-if-timings { - }; }; &pmu_system_controller { @@ -1216,8 +1194,9 @@ status = "okay"; }; -&usbdrd_dwc3_0 { +&usbdrd_dwc3 { dr_mode = "otg"; + extcon = <&muic>; }; &usbdrd30_phy { diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 727f36abf3d478d1bd2b86fe09fbe535705401ff..7fe994b750dab050b5a5c834259812acff641705 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1367,7 +1367,7 @@ ranges; status = "disabled"; - dwc3@15400000 { + usbdrd_dwc3: dwc3@15400000 { compatible = "snps,dwc3"; reg = <0x15400000 0x10000>; interrupts = ; @@ -1414,7 +1414,7 @@ ranges; status = "disabled"; - usbdrd_dwc3_0: dwc3@15a00000 { + usbhost_dwc3: dwc3@15a00000 { compatible = "snps,dwc3"; reg = <0x15a00000 0x10000>; interrupts = ; diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts index e5892bb0ae6e55ccf5ba0cc7b30b7b616fea6413..4a8b1fb51243c4a628fd3a27dd7b82ec9ecb3e78 100644 --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts @@ -359,7 +359,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; cap-mmc-highspeed; mmc-hs200-1_8v; non-removable; @@ -375,7 +374,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index b1554cbd2c54f4ca08be37f7add0370758b288d9..df83915d6ea629509b829d82061bd7c6019e790c 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -444,6 +444,15 @@ <&clockgen 4 3>; }; + usb0: usb3@2f00000 { + compatible = "snps,dwc3"; + reg = <0x0 0x2f00000 0x0 0x10000>; + interrupts = <0 60 0x4>; + dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; + snps,dis_rxdet_inp3_quirk; + }; + sata: sata@3200000 { compatible = "fsl,ls1012a-ahci", "fsl,ls1043a-ahci"; reg = <0x0 0x3200000 0x0 0x10000>, @@ -454,5 +463,13 @@ dma-coherent; status = "disabled"; }; + + usb1: usb2@8600000 { + compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr"; + reg = <0x0 0x8600000 0x0 0x1000>; + interrupts = <0 139 0x4>; + dr_mode = "host"; + phy_type = "ulpi"; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 31fd77f82ced81364e9634165d692193972b00a6..d16b9cc1e8252c835479f53f9cf8af1657fa5125 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -653,21 +653,21 @@ }; msi1: msi-controller1@1571000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1571000 0x0 0x8>; msi-controller; interrupts = <0 116 0x4>; }; msi2: msi-controller2@1572000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1572000 0x0 0x8>; msi-controller; interrupts = <0 126 0x4>; }; msi3: msi-controller3@1573000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1573000 0x0 0x8>; msi-controller; interrupts = <0 160 0x4>; @@ -689,7 +689,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi1>; + msi-parent = <&msi1>, <&msi2>, <&msi3>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic 0 110 0x4>, @@ -714,7 +714,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi2>; + msi-parent = <&msi1>, <&msi2>, <&msi3>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic 0 120 0x4>, @@ -739,7 +739,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi3>; + msi-parent = <&msi1>, <&msi2>, <&msi3>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic 0 154 0x4>, diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index dc1640be0345d3be0b0a601421edc7b5cbb9f433..c8ff0baddf1d06858091df65a66d60c348cc0e43 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -630,6 +630,37 @@ interrupts = ; clocks = <&clockgen 4 1>; }; + + msi1: msi-controller@1580000 { + compatible = "fsl,ls1046a-msi"; + msi-controller; + reg = <0x0 0x1580000 0x0 0x10000>; + interrupts = , + , + , + ; + }; + + msi2: msi-controller@1590000 { + compatible = "fsl,ls1046a-msi"; + msi-controller; + reg = <0x0 0x1590000 0x0 0x10000>; + interrupts = , + , + , + ; + }; + + msi3: msi-controller@15a0000 { + compatible = "fsl,ls1046a-msi"; + msi-controller; + reg = <0x0 0x15a0000 0x0 0x10000>; + interrupts = , + , + , + ; + }; + }; reserved-memory { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 213abb72de93e90891b42263adf06854fa1f9fdd..0f6fcda36b9e03279a6a232d4b47d2a31633291b 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -49,7 +49,7 @@ #include "fsl-ls1088a.dtsi" / { - model = "L1088A RDB Board"; + model = "LS1088A RDB Board"; compatible = "fsl,ls1088a-rdb", "fsl,ls1088a"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index c144d06a6e33150c313580b7144d6ededa08cf06..33797b3736744bbeee590014a3342b514758a0b8 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -52,6 +52,10 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + crypto = &crypto; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -62,6 +66,7 @@ compatible = "arm,cortex-a53"; reg = <0x0>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; #cooling-cells = <2>; }; @@ -70,6 +75,7 @@ compatible = "arm,cortex-a53"; reg = <0x1>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; }; cpu2: cpu@2 { @@ -77,6 +83,7 @@ compatible = "arm,cortex-a53"; reg = <0x2>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; }; cpu3: cpu@3 { @@ -84,6 +91,7 @@ compatible = "arm,cortex-a53"; reg = <0x3>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; }; cpu4: cpu@100 { @@ -91,6 +99,7 @@ compatible = "arm,cortex-a53"; reg = <0x100>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; #cooling-cells = <2>; }; @@ -99,6 +108,7 @@ compatible = "arm,cortex-a53"; reg = <0x101>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; }; cpu6: cpu@102 { @@ -106,6 +116,7 @@ compatible = "arm,cortex-a53"; reg = <0x102>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; }; cpu7: cpu@103 { @@ -113,6 +124,16 @@ compatible = "arm,cortex-a53"; reg = <0x103>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; + }; + + CPU_PH20: cpu-ph20 { + compatible = "arm,idle-state"; + idle-state-name = "PH20"; + arm,psci-suspend-param = <0x00010000>; + entry-latency-us = <1000>; + exit-latency-us = <1000>; + min-residency-us = <3000>; }; }; @@ -136,6 +157,11 @@ <1 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */ }; + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -369,6 +395,45 @@ dma-coherent; status = "disabled"; }; + + crypto: crypto@8000000 { + compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; + fsl,sec-era = <8>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x00 0x8000000 0x100000>; + reg = <0x00 0x8000000 0x0 0x100000>; + interrupts = ; + dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x10000 0x10000>; + interrupts = ; + }; + + sec_jr1: jr@20000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x20000 0x10000>; + interrupts = ; + }; + + sec_jr2: jr@30000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x30000 0x10000>; + interrupts = ; + }; + + sec_jr3: jr@40000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x40000 0x10000>; + interrupts = ; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts index ed209cd57283b66cc8d69640e696d9b3a6ee2935..3c99608b9b45d25b0b2f03ccb0bf4b69cfd3c9de 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts @@ -55,11 +55,6 @@ model = "Freescale Layerscape 2080a QDS Board"; compatible = "fsl,ls2080a-qds", "fsl,ls2080a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts index 67ec3f9c81a14848255bed4d2f90dc00581d59f7..a4e7de9f70d8553a05a567589bdf0be6098a674c 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts @@ -55,11 +55,6 @@ model = "Freescale Layerscape 2080a RDB Board"; compatible = "fsl,ls2080a-rdb", "fsl,ls2080a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial1:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts index 3ee718f0aaf85577866203e30189420934f8c5f9..fbbb73e571c06f0db11909372958fa3ba0a6d334 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts @@ -52,11 +52,6 @@ model = "Freescale Layerscape 2080a software Simulator model"; compatible = "fsl,ls2080a-simu", "fsl,ls2080a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - ethernet@2210000 { compatible = "smsc,lan91c111"; reg = <0x0 0x2210000 0x0 0x100>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index d789c6814e6a57fd6e7b0d1e8e4700fd8ce2e7a7..8d739301e7b8acbb34951d2b843553bcc101f1e8 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -53,6 +53,7 @@ compatible = "arm,cortex-a57"; reg = <0x0>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; #cooling-cells = <2>; }; @@ -62,6 +63,7 @@ compatible = "arm,cortex-a57"; reg = <0x1>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; }; @@ -70,6 +72,7 @@ compatible = "arm,cortex-a57"; reg = <0x100>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; #cooling-cells = <2>; }; @@ -79,6 +82,7 @@ compatible = "arm,cortex-a57"; reg = <0x101>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; }; @@ -87,6 +91,7 @@ compatible = "arm,cortex-a57"; reg = <0x200>; clocks = <&clockgen 1 2>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster2_l2>; #cooling-cells = <2>; }; @@ -96,6 +101,7 @@ compatible = "arm,cortex-a57"; reg = <0x201>; clocks = <&clockgen 1 2>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster2_l2>; }; @@ -105,6 +111,7 @@ reg = <0x300>; clocks = <&clockgen 1 3>; next-level-cache = <&cluster3_l2>; + cpu-idle-states = <&CPU_PW20>; #cooling-cells = <2>; }; @@ -113,6 +120,7 @@ compatible = "arm,cortex-a57"; reg = <0x301>; clocks = <&clockgen 1 3>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster3_l2>; }; @@ -131,6 +139,15 @@ cluster3_l2: l2-cache3 { compatible = "cache"; }; + + CPU_PW20: cpu-pw20 { + compatible = "arm,idle-state"; + idle-state-name = "PW20"; + arm,psci-suspend-param = <0x00010000>; + entry-latency-us = <2000>; + exit-latency-us = <2000>; + min-residency-us = <6000>; + }; }; &pcie1 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts index 4a1df5ce3229c55d3f8ab62622792d6f9bf88219..eaee5b1c3a448ac95952b6548c6a2d5ac5ddfc26 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts @@ -54,11 +54,6 @@ model = "Freescale Layerscape 2088A QDS Board"; compatible = "fsl,ls2088a-qds", "fsl,ls2088a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts index a76d4b4debd16cf7ff887f1d5d5f08213a4ea767..c411442cac62cb2e1309a9759d5959050d247659 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts @@ -54,11 +54,6 @@ model = "Freescale Layerscape 2088A RDB Board"; compatible = "fsl,ls2088a-rdb", "fsl,ls2088a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial1:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi index 5c695c6580566020a647f7bbe80efef7df227131..6aa319dae396ffffc135b4e9af9e893029dd1ba7 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi @@ -53,6 +53,7 @@ compatible = "arm,cortex-a72"; reg = <0x0>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; #cooling-cells = <2>; }; @@ -62,6 +63,7 @@ compatible = "arm,cortex-a72"; reg = <0x1>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; }; @@ -70,6 +72,7 @@ compatible = "arm,cortex-a72"; reg = <0x100>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; #cooling-cells = <2>; }; @@ -79,6 +82,7 @@ compatible = "arm,cortex-a72"; reg = <0x101>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; }; @@ -88,6 +92,7 @@ reg = <0x200>; clocks = <&clockgen 1 2>; next-level-cache = <&cluster2_l2>; + cpu-idle-states = <&CPU_PW20>; #cooling-cells = <2>; }; @@ -96,6 +101,7 @@ compatible = "arm,cortex-a72"; reg = <0x201>; clocks = <&clockgen 1 2>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster2_l2>; }; @@ -104,6 +110,7 @@ compatible = "arm,cortex-a72"; reg = <0x300>; clocks = <&clockgen 1 3>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster3_l2>; #cooling-cells = <2>; }; @@ -113,6 +120,7 @@ compatible = "arm,cortex-a72"; reg = <0x301>; clocks = <&clockgen 1 3>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster3_l2>; }; @@ -131,6 +139,15 @@ cluster3_l2: l2-cache3 { compatible = "cache"; }; + + CPU_PW20: cpu-pw20 { + compatible = "arm,idle-state"; + idle-state-name = "PW20"; + arm,psci-suspend-param = <0x00010000>; + entry-latency-us = <2000>; + exit-latency-us = <2000>; + min-residency-us = <6000>; + }; }; &pcie1 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 94cdd30450371ada8dec5dd0fd1ef398b30d30d0..4fb9a0966a84f2db6c51861c5087ccb5346c49c9 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -46,6 +46,7 @@ */ #include +#include / { compatible = "fsl,ls2080a"; @@ -53,6 +54,12 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + crypto = &crypto; + serial0 = &serial0; + serial1 = &serial1; + }; + cpu: cpus { #address-cells = <1>; #size-cells = <0>; @@ -118,6 +125,11 @@ interrupts = <1 7 0x8>; /* PMU PPI, Level low type */ }; + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; @@ -301,6 +313,45 @@ clock-names = "apb_pclk", "wdog_clk"; }; + crypto: crypto@8000000 { + compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; + fsl,sec-era = <8>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x00 0x8000000 0x100000>; + reg = <0x00 0x8000000 0x0 0x100000>; + interrupts = ; + dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x10000 0x10000>; + interrupts = ; + }; + + sec_jr1: jr@20000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x20000 0x10000>; + interrupts = ; + }; + + sec_jr2: jr@30000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x30000 0x10000>; + interrupts = ; + }; + + sec_jr3: jr@40000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x40000 0x10000>; + interrupts = ; + }; + }; + fsl_mc: fsl-mc@80c000000 { compatible = "fsl,qoriq-mc"; reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts index 6609b0fe7a8b48ec02dba0a537731fa02b8061f5..fd4705c451e2697716daea41ff606aabb3bd39fc 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -39,6 +39,34 @@ reg = <0x0 0x0 0x0 0x0>; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + ramoops@32000000 { + compatible = "ramoops"; + reg = <0x0 0x32000000 0x0 0x00100000>; + record-size = <0x00020000>; + console-size = <0x00020000>; + ftrace-size = <0x00020000>; + }; + }; + + reboot-mode-syscon@32100000 { + compatible = "syscon", "simple-mfd"; + reg = <0x0 0x32100000 0x0 0x00001000>; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x0>; + + mode-normal = <0x77665501>; + mode-bootloader = <0x77665500>; + mode-recovery = <0x77665502>; + }; + }; + keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -159,6 +187,13 @@ startup-delay-us = <70000>; enable-active-high; }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; }; &i2c0 { @@ -195,7 +230,7 @@ bluetooth { compatible = "ti,wl1837-st"; enable-gpios = <&gpio15 6 GPIO_ACTIVE_HIGH>; - max-speed = <921600>; + max-speed = <3000000>; }; }; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index c6a1961e8d55ecb9bdb07e8696fe9a755c8d21e8..b7a90d632959d95b0dee0cc93e37037700194b2d 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -58,6 +58,8 @@ device_type = "cpu"; reg = <0x0 0x0>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu1: cpu@1 { @@ -65,6 +67,8 @@ device_type = "cpu"; reg = <0x0 0x1>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu2: cpu@2 { @@ -72,6 +76,8 @@ device_type = "cpu"; reg = <0x0 0x2>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu3: cpu@3 { @@ -79,6 +85,8 @@ device_type = "cpu"; reg = <0x0 0x3>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu4: cpu@100 { @@ -86,6 +94,12 @@ device_type = "cpu"; reg = <0x0 0x100>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; }; cpu5: cpu@101 { @@ -93,6 +107,12 @@ device_type = "cpu"; reg = <0x0 0x101>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; }; cpu6: cpu@102 { @@ -100,6 +120,12 @@ device_type = "cpu"; reg = <0x0 0x102>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; }; cpu7: cpu@103 { @@ -107,6 +133,59 @@ device_type = "cpu"; reg = <0x0 0x103>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; + }; + + idle-states { + entry-method = "psci"; + + CPU_NAP: cpu-nap { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0000001>; + entry-latency-us = <7>; + exit-latency-us = <2>; + min-residency-us = <15>; + }; + + CPU_SLEEP: cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x0010000>; + entry-latency-us = <40>; + exit-latency-us = <70>; + min-residency-us = <3000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <500>; + exit-latency-us = <5000>; + min-residency-us = <20000>; + }; + + CLUSTER_SLEEP_1: cluster-sleep-1 { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <1000>; + exit-latency-us = <5000>; + min-residency-us = <20000>; + }; + }; + + A53_L2: l2-cache0 { + compatible = "cache"; + }; + + A73_L2: l2-cache1 { + compatible = "cache"; }; }; @@ -123,6 +202,26 @@ IRQ_TYPE_LEVEL_HIGH)>; }; + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = , + , + , + , + , + , + , + ; + interrupt-affinity = <&cpu0>, + <&cpu1>, + <&cpu2>, + <&cpu3>, + <&cpu4>, + <&cpu5>, + <&cpu6>, + <&cpu7>; + }; + timer { compatible = "arm,armv8-timer"; interrupt-parent = <&gic>; @@ -337,6 +436,19 @@ status = "disabled"; }; + dma0: dma@fdf30000 { + compatible = "hisilicon,k3-dma-1.0"; + reg = <0x0 0xfdf30000 0x0 0x1000>; + #dma-cells = <1>; + dma-channels = <16>; + dma-requests = <32>; + dma-min-chan = <1>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_DMAC>; + dma-no-cci; + dma-type = "hi3660_dma"; + }; + rtc0: rtc@fff04000 { compatible = "arm,pl031", "arm,primecell"; reg = <0x0 0Xfff04000 0x0 0x1000>; @@ -810,6 +922,7 @@ clock-names = "ciu", "biu"; clock-frequency = <3200000>; resets = <&crg_rst 0x94 18>; + reset-names = "reset"; cd-gpios = <&gpio25 3 0>; hisilicon,peripheral-syscon = <&sctrl>; pinctrl-names = "default"; @@ -839,6 +952,7 @@ <&crg_ctrl HI3660_HCLK_GATE_SDIO0>; clock-names = "ciu", "biu"; resets = <&crg_rst 0x94 20>; + reset-names = "reset"; card-detect-delay = <200>; supports-highspeed; keep-power-in-suspend; @@ -848,5 +962,21 @@ &sdio_cfg_func>; status = "disabled"; }; + + watchdog0: watchdog@e8a06000 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xe8a06000 0x0 0x1000>; + interrupts = ; + clocks = <&crg_ctrl HI3660_OSC32K>; + clock-names = "apb_pclk"; + }; + + watchdog1: watchdog@e8a07000 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xe8a07000 0x0 0x1000>; + interrupts = ; + clocks = <&crg_ctrl HI3660_OSC32K>; + clock-names = "apb_pclk"; + }; }; }; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index eacbe0db5bc2acebe98c16dd36d22fc996a59d7b..02a3aa4b2165d07e8af616998611923f60256ff9 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -262,6 +262,12 @@ #clock-cells = <1>; }; + acpu_sctrl: acpu_sctrl@f6504000 { + compatible = "hisilicon,hi6220-acpu-sctrl", "syscon"; + reg = <0x0 0xf6504000 0x0 0x1000>; + #clock-cells = <1>; + }; + medianoc_ade: medianoc_ade@f4520000 { compatible = "syscon"; reg = <0x0 0xf4520000 0x0 0x4000>; @@ -755,7 +761,8 @@ dr_mode = "otg"; g-rx-fifo-size = <512>; g-np-tx-fifo-size = <128>; - g-tx-fifo-size = <128 128 128 128 128 128>; + g-tx-fifo-size = <128 128 128 128 128 128 128 128 + 16 16 16 16 16 16 16>; interrupts = <0 77 0x4>; }; diff --git a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts index f5d7f0889b41db47ad784f668845b3e5218c6b84..fe7c16c3602593a9b572fef58bba730dbd1a9c73 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts +++ b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts @@ -84,3 +84,7 @@ &sas1 { status = "ok"; }; + +&p0_pcie2_a { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi index 283d7b532e161742c3d1be58e5e6621f21bae51a..2c01a21c36656f9e55f110ec31ee4060724879c1 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi @@ -1534,5 +1534,27 @@ <637 1>,<638 1>,<639 1>; status = "disabled"; }; + + p0_pcie2_a: pcie@a00a0000 { + compatible = "hisilicon,hip07-pcie-ecam"; + reg = <0 0xaf800000 0 0x800000>, + <0 0xa00a0000 0 0x10000>; + bus-range = <0xf8 0xff>; + msi-map = <0xf800 &p0_its_dsa_a 0xf800 0x800>; + msi-map-mask = <0xffff>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + ranges = <0x02000000 0 0xa8000000 0 0xa8000000 0 0x77f0000 + 0x01000000 0 0 0 0xaf7f0000 0 0x10000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0x0 0 0 1 &mbigen_pcie2_a 671 4 + 0x0 0 0 2 &mbigen_pcie2_a 671 4 + 0x0 0 0 3 &mbigen_pcie2_a 671 4 + 0x0 0 0 4 &mbigen_pcie2_a 671 4>; + status = "disabled"; + }; }; }; diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index 3e6ce6c15a7449aefd8bf753675de3a2e70ead39..6cff81eeaae2833829391a2b829115ede9a7860f 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile @@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-8080-db.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts index e3a136ed77b00ce1d1a0f690c05426cb62783eb2..2ce52ba74f73bac47244aaa5896f29ed4b56596a 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts @@ -45,6 +45,7 @@ /dts-v1/; +#include #include "armada-372x.dtsi" / { @@ -59,6 +60,20 @@ device_type = "memory"; reg = <0x00000000 0x00000000 0x00000000 0x20000000>; }; + + vcc_sd_reg1: regulator { + compatible = "regulator-gpio"; + regulator-name = "vcc_sd1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + states = <1800000 0x1 + 3300000 0x0>; + enable-active-high; + }; }; /* J9 */ @@ -71,6 +86,16 @@ status = "okay"; }; +/* J1 */ +&sdhci1 { + wp-inverted; + bus-width = <4>; + cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; + marvell,pad-type = "sd"; + vqmmc-supply = <&vcc_sd_reg1>; + status = "okay"; +}; + /* Exported on the micro USB connector J5 through an FTDI */ &uart0 { status = "okay"; @@ -81,6 +106,11 @@ status = "okay"; }; +/* J8 */ +&usb2 { + status = "okay"; +}; + &mdio { switch0: switch0@1 { compatible = "marvell,mv88e6085"; diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index dbcc3d4e2ed523e72bc8cd68dbf2c52503b7332f..8c0cf7efac65242a50a8ac2b201f351c8c0ce2a6 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -81,6 +81,11 @@ ; }; + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; @@ -219,7 +224,7 @@ reg = <0x18800 0x100>, <0x18C00 0x20>; gpiosb: gpio { #gpio-cells = <2>; - gpio-ranges = <&pinctrl_sb 0 0 29>; + gpio-ranges = <&pinctrl_sb 0 0 30>; gpio-controller; interrupts = , @@ -322,7 +327,11 @@ #interrupt-cells = <3>; interrupt-controller; reg = <0x1d00000 0x10000>, /* GICD */ - <0x1d40000 0x40000>; /* GICR */ + <0x1d40000 0x40000>, /* GICR */ + <0x1d80000 0x2000>, /* GICC */ + <0x1d90000 0x2000>, /* GICH */ + <0x1da0000 0x20000>; /* GICV */ + interrupts = ; }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-7040-db.dts b/arch/arm64/boot/dts/marvell/armada-7040-db.dts index 92c761c380d33c37f5d6070729b02c23a6d93752..9c3bdf87e5433f2a800eae0a2a1e32c8c924dd88 100644 --- a/arch/arm64/boot/dts/marvell/armada-7040-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts @@ -44,6 +44,7 @@ * Device Tree file for Marvell Armada 7040 Development board platform */ +#include #include "armada-7040.dtsi" / { @@ -59,6 +60,34 @@ device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>; }; + + cpm_reg_usb3_0_vbus: cpm-usb3-0-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; + }; + + cpm_reg_usb3_1_vbus: cpm-usb3-1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb3h1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; + }; + + cpm_usb3_0_phy: cpm-usb3-0-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_0_vbus>; + }; + + cpm_usb3_1_phy: cpm-usb3-1-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_1_vbus>; + }; }; &i2c0 { @@ -105,6 +134,14 @@ &cpm_i2c0 { status = "okay"; clock-frequency = <100000>; + + expander0: pca9555@21 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x21>; + }; }; &cpm_spi1 { @@ -140,10 +177,12 @@ }; &cpm_usb3_0 { + usb-phy = <&cpm_usb3_0_phy>; status = "okay"; }; &cpm_usb3_1 { + usb-phy = <&cpm_usb3_1_phy>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-db.dts b/arch/arm64/boot/dts/marvell/armada-8040-db.dts index 1e8f7242ed6ff97f7fe153ee7dc26fa1e950def4..0d7b2ae4661002e7443297f680511950c87bfd8f 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-db.dts @@ -44,6 +44,7 @@ * Device Tree file for Marvell Armada 8040 Development board platform */ +#include #include "armada-8040.dtsi" / { @@ -59,6 +60,48 @@ device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>; }; + + cpm_reg_usb3_0_vbus: cpm-usb3-0-vbus { + compatible = "regulator-fixed"; + regulator-name = "cpm-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; + }; + + cpm_reg_usb3_1_vbus: cpm-usb3-1-vbus { + compatible = "regulator-fixed"; + regulator-name = "cpm-usb3h1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; + }; + + cpm_usb3_0_phy: cpm-usb3-0-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_0_vbus>; + }; + + cpm_usb3_1_phy: cpm-usb3-1-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_1_vbus>; + }; + + cps_reg_usb3_0_vbus: cps-usb3-0-vbus { + compatible = "regulator-fixed"; + regulator-name = "cps-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander1 0 GPIO_ACTIVE_HIGH>; + }; + + cps_usb3_0_phy: cps-usb3-0-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cps_reg_usb3_0_vbus>; + }; }; &i2c0 { @@ -107,6 +150,25 @@ &cpm_i2c0 { status = "okay"; clock-frequency = <100000>; + + /* U31 */ + expander0: pca9555@21 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x21>; + }; + + /* U25 */ + expander1: pca9555@25 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x25>; + }; + }; /* CON4 on CP0 expansion */ @@ -116,11 +178,13 @@ /* CON9 on CP0 expansion */ &cpm_usb3_0 { + usb-phy = <&cpm_usb3_0_phy>; status = "okay"; }; /* CON10 on CP0 expansion */ &cpm_usb3_1 { + usb-phy = <&cpm_usb3_1_phy>; status = "okay"; }; @@ -159,6 +223,7 @@ /* CON9 on CP1 expansion */ &cps_usb3_0 { + usb-phy = <&cps_usb3_0_phy>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts index 4968e731de612e3f781bed2760a0131cb5b42d55..acf5c7d16d79b2f07eedf4691a1fc820073c7ffc 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts @@ -46,11 +46,17 @@ #include "armada-8040.dtsi" +#include + / { model = "Marvell 8040 MACHIATOBin"; compatible = "marvell,armada8040-mcbin", "marvell,armada8040", "marvell,armada-ap806-quad", "marvell,armada-ap806"; + chosen { + stdout-path = "serial0:115200n8"; + }; + memory@00000000 { device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>; @@ -77,11 +83,13 @@ v_5v0_usb3_hst_vbus: regulator-usb3-vbus0 { compatible = "regulator-fixed"; + enable-active-high; + gpio = <&cpm_gpio2 15 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_xhci_vbus_pins>; regulator-name = "v_5v0_usb3_hst_vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - /* actually GPIO controlled, but 8k has no GPIO support yet */ - regulator-always-on; status = "okay"; }; @@ -112,10 +120,44 @@ &cpm_i2c0 { clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c0_pins>; status = "okay"; }; +&cpm_i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c1_pins>; + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + + sfpp0_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + sfpp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + sfp_1g_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + }; +}; + &cpm_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_ge_mdio_pins>; status = "okay"; ge_phy: ethernet-phy@0 { @@ -123,6 +165,67 @@ }; }; +&cpm_pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_pcie_pins>; + num-lanes = <4>; + num-viewport = <8>; + reset-gpio = <&cpm_gpio1 20 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&cpm_pinctrl { + cpm_ge_mdio_pins: ge-mdio-pins { + marvell,pins = "mpp32", "mpp34"; + marvell,function = "ge"; + }; + cpm_i2c1_pins: i2c1-pins { + marvell,pins = "mpp35", "mpp36"; + marvell,function = "i2c1"; + }; + cpm_i2c0_pins: i2c0-pins { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cpm_xhci_vbus_pins: xhci0-vbus-pins { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + cpm_pcie_pins: pcie-pins { + marvell,pins = "mpp52"; + marvell,function = "gpio"; + }; + cpm_sdhci_pins: sdhci-pins { + marvell,pins = "mpp55", "mpp56", "mpp57", "mpp58", "mpp59", + "mpp60", "mpp61"; + marvell,function = "sdio"; + }; +}; + +&cpm_xmdio { + status = "okay"; + + phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + + phy8: ethernet-phy@8 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +&cpm_ethernet { + status = "okay"; +}; + +&cpm_eth0 { + status = "okay"; + phy = <&phy0>; + phy-mode = "10gbase-kr"; +}; + &cpm_sata0 { /* CPM Lane 0 - U29 */ status = "okay"; @@ -132,6 +235,8 @@ /* U6 */ broken-cd; bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_sdhci_pins>; status = "okay"; vqmmc-supply = <&v_3_3>; }; @@ -150,6 +255,12 @@ status = "okay"; }; +&cps_eth0 { + status = "okay"; + phy = <&phy8>; + phy-mode = "10gbase-kr"; +}; + &cps_eth1 { /* CPS Lane 0 - J5 (Gigabit RJ45) */ status = "okay"; @@ -157,6 +268,13 @@ phy-mode = "sgmii"; }; +&cps_pinctrl { + cps_spi1_pins: spi1-pins { + marvell,pins = "mpp12", "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; +}; + &cps_sata0 { /* CPS Lane 1 - U32 */ /* CPS Lane 3 - U31 */ @@ -164,6 +282,8 @@ }; &cps_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cps_spi1_pins>; status = "okay"; spi-flash@0 { diff --git a/arch/arm64/boot/dts/marvell/armada-8080-db.dts b/arch/arm64/boot/dts/marvell/armada-8080-db.dts new file mode 100644 index 0000000000000000000000000000000000000000..707af833832be2039fa82af404e7ac3357b6b38d --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8080-db.dts @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada-8080 Development board platform + */ + +#include "armada-8080.dtsi" + +/ { + model = "Marvell 8080 board"; + compatible = "marvell,armada-8080-db", "marvell,armada-8080", + "marvell,armada-ap810-octa", "marvell,armada-ap810"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; + +&uart0_ap0 { + clock-frequency = <384000>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8080.dtsi b/arch/arm64/boot/dts/marvell/armada-8080.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..d5535b7167350e135df059ef68b05b83d88a8a32 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8080.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada-8080 SoC, made of an AP810 OCTA. + */ + +#include "armada-ap810-ap0-octa-core.dtsi" + +/ { + model = "Marvell 8080 board"; + compatible = "marvell,armada-8080", "marvell,armada-ap810-octa", + "marvell,armada-ap810"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi index 1eb1f1e9aac4cfb36d2de827ff8c5bd4970a3ad0..30d48ecf46e087b24063c0ac546d45ae9afb0d88 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi @@ -254,7 +254,7 @@ ap_syscon: system-controller@6f4000 { compatible = "syscon", "simple-mfd"; - reg = <0x6f4000 0x1000>; + reg = <0x6f4000 0x2000>; ap_clk: clock { compatible = "marvell,ap806-clock"; @@ -265,13 +265,13 @@ compatible = "marvell,ap806-pinctrl"; }; - ap_gpio: gpio { + ap_gpio: gpio@1040 { compatible = "marvell,armada-8k-gpio"; offset = <0x1040>; - ngpios = <19>; + ngpios = <20>; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&ap_pinctrl 0 0 19>; + gpio-ranges = <&ap_pinctrl 0 0 20>; }; }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi b/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..bf1b22b70384ceee5c1284bba316d3298fd21268 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP810 OCTA cores. + */ + +#include "armada-ap810-ap0.dtsi" + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "marvell,armada-ap810-octa"; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x000>; + enable-method = "psci"; + }; + cpu@001 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x001>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x101>; + enable-method = "psci"; + }; + cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x200>; + enable-method = "psci"; + }; + cpu@201 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x201>; + enable-method = "psci"; + }; + cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x300>; + enable-method = "psci"; + }; + cpu@301 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x301>; + enable-method = "psci"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi b/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7e6f039f0f80073ba8fce1dc6413f9e9eaa19bee --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP810. + */ + +#include + +/dts-v1/; + +/ { + model = "Marvell Armada AP810"; + compatible = "marvell,armada-ap810"; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0_ap0; + serial1 = &uart1_ap0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + ap810-ap0 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + config-space@e8000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x0 0x0 0xe8000000 0x4000000>; + interrupt-parent = <&gic>; + + gic: interrupt-controller@3000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-controller; + interrupts = ; + ranges; + + reg = <0x3000000 0x10000>, /* GICD */ + <0x3060000 0x100000>, /* GICR */ + <0x00c0000 0x2000>, /* GICC */ + <0x00d0000 0x1000>, /* GICH */ + <0x00e0000 0x2000>; /* GICV */ + + gic_its_ap0: interrupt-controller@3040000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x3040000 0x20000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + xor@400000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x400000 0x1000>, + <0x410000 0x1000>; + msi-parent = <&gic_its_ap0 0xa0>; + dma-coherent; + }; + + xor@420000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x420000 0x1000>, + <0x430000 0x1000>; + msi-parent = <&gic_its_ap0 0xa1>; + dma-coherent; + }; + + xor@440000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x440000 0x1000>, + <0x450000 0x1000>; + msi-parent = <&gic_its_ap0 0xa2>; + dma-coherent; + }; + + xor@460000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x460000 0x1000>, + <0x470000 0x1000>; + msi-parent = <&gic_its_ap0 0xa3>; + dma-coherent; + }; + + uart0_ap0: serial@512000 { + compatible = "snps,dw-apb-uart"; + reg = <0x512000 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + status = "disabled"; + }; + + uart1_ap0: serial@512100 { + compatible = "snps,dw-apb-uart"; + reg = <0x512100 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi index 726528ce54e9650fe2b0ebfc085b0f0753e876d8..8263a8a504a8fd11896da6aebc99eabdd4be928a 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi @@ -65,25 +65,44 @@ reg = <0x0 0x100000>, <0x129000 0xb000>; clocks = <&cpm_clk 1 3>, <&cpm_clk 1 9>, <&cpm_clk 1 5>; clock-names = "pp_clk", "gop_clk", "mg_clk"; + marvell,system-controller = <&cpm_syscon0>; status = "disabled"; dma-coherent; cpm_eth0: eth0 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <0>; gop-port-id = <0>; status = "disabled"; }; cpm_eth1: eth1 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <1>; gop-port-id = <2>; status = "disabled"; }; cpm_eth2: eth2 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <2>; gop-port-id = <3>; status = "disabled"; @@ -115,6 +134,13 @@ msi-parent = <&gicp>; }; + cpm_rtc: rtc@284000 { + compatible = "marvell,armada-8k-rtc"; + reg = <0x284000 0x20>, <0x284080 0x24>; + reg-names = "rtc", "rtc-soc"; + interrupts = ; + }; + cpm_syscon0: system-controller@440000 { compatible = "syscon", "simple-mfd"; reg = <0x440000 0x1000>; @@ -131,8 +157,12 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cpm_pinctrl 0 0 32>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; - }; cpm_gpio2: gpio@140 { @@ -142,26 +172,15 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cpm_pinctrl 0 32 31>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; }; }; - cpm_rtc: rtc@284000 { - compatible = "marvell,armada-8k-rtc"; - reg = <0x284000 0x20>, <0x284080 0x24>; - reg-names = "rtc", "rtc-soc"; - interrupts = ; - }; - - cpm_sata0: sata@540000 { - compatible = "marvell,armada-8k-ahci", - "generic-ahci"; - reg = <0x540000 0x30000>; - interrupts = ; - clocks = <&cpm_clk 1 15>; - status = "disabled"; - }; - cpm_usb3_0: usb3@500000 { compatible = "marvell,armada-8k-xhci", "generic-xhci"; @@ -182,6 +201,15 @@ status = "disabled"; }; + cpm_sata0: sata@540000 { + compatible = "marvell,armada-8k-ahci", + "generic-ahci"; + reg = <0x540000 0x30000>; + interrupts = ; + clocks = <&cpm_clk 1 15>; + status = "disabled"; + }; + cpm_xor0: xor@6a0000 { compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; reg = <0x6a0000 0x1000>, @@ -240,6 +268,21 @@ status = "disabled"; }; + cpm_nand: nand@720000 { + /* + * Due to the limiation of the pin available + * this controller is only usable on the CPM + * for A7K and on the CPS for A8K. + */ + compatible = "marvell,armada370-nand"; + reg = <0x720000 0x54>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = ; + clocks = <&cpm_clk 1 2>; + status = "disabled"; + }; + cpm_trng: trng@760000 { compatible = "marvell,armada-8k-rng", "inside-secure,safexcel-eip76"; reg = <0x760000 0x7d>; @@ -270,6 +313,7 @@ interrupt-names = "mem", "ring0", "ring1", "ring2", "ring3", "eip"; clocks = <&cpm_clk 1 26>; + dma-coherent; }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi index 95f8e5f607f608d2ec1bd258e1eec76f0d4b8528..b71ee6c83668e8900a4a889614ed83e97e718f85 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi @@ -60,37 +60,49 @@ compatible = "simple-bus"; ranges = <0x0 0x0 0xf4000000 0x2000000>; - cps_rtc: rtc@284000 { - compatible = "marvell,armada-8k-rtc"; - reg = <0x284000 0x20>, <0x284080 0x24>; - reg-names = "rtc", "rtc-soc"; - interrupts = ; - }; - cps_ethernet: ethernet@0 { compatible = "marvell,armada-7k-pp22"; reg = <0x0 0x100000>, <0x129000 0xb000>; clocks = <&cps_clk 1 3>, <&cps_clk 1 9>, <&cps_clk 1 5>; clock-names = "pp_clk", "gop_clk", "mg_clk"; + marvell,system-controller = <&cps_syscon0>; status = "disabled"; dma-coherent; cps_eth0: eth0 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <0>; gop-port-id = <0>; status = "disabled"; }; cps_eth1: eth1 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <1>; gop-port-id = <2>; status = "disabled"; }; cps_eth2: eth2 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <2>; gop-port-id = <3>; status = "disabled"; @@ -122,6 +134,13 @@ msi-parent = <&gicp>; }; + cps_rtc: rtc@284000 { + compatible = "marvell,armada-8k-rtc"; + reg = <0x284000 0x20>, <0x284080 0x24>; + reg-names = "rtc", "rtc-soc"; + interrupts = ; + }; + cps_syscon0: system-controller@440000 { compatible = "syscon", "simple-mfd"; reg = <0x440000 0x1000>; @@ -138,8 +157,12 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cps_pinctrl 0 0 32>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; - }; cps_gpio2: gpio@140 { @@ -149,20 +172,16 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cps_pinctrl 0 32 31>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; }; }; - cps_sata0: sata@540000 { - compatible = "marvell,armada-8k-ahci", - "generic-ahci"; - reg = <0x540000 0x30000>; - interrupts = ; - clocks = <&cps_clk 1 15>; - status = "disabled"; - }; - cps_usb3_0: usb3@500000 { compatible = "marvell,armada-8k-xhci", "generic-xhci"; @@ -183,6 +202,15 @@ status = "disabled"; }; + cps_sata0: sata@540000 { + compatible = "marvell,armada-8k-ahci", + "generic-ahci"; + reg = <0x540000 0x30000>; + interrupts = ; + clocks = <&cps_clk 1 15>; + status = "disabled"; + }; + cps_xor0: xor@6a0000 { compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; reg = <0x6a0000 0x1000>, @@ -241,6 +269,21 @@ status = "disabled"; }; + cps_nand: nand@720000 { + /* + * Due to the limiation of the pin available + * this controller is only usable on the CPM + * for A7K and on the CPS for A8K. + */ + compatible = "marvell,armada370-nand"; + reg = <0x720000 0x54>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = ; + clocks = <&cps_clk 1 2>; + status = "disabled"; + }; + cps_trng: trng@760000 { compatible = "marvell,armada-8k-rng", "inside-secure,safexcel-eip76"; reg = <0x760000 0x7d>; @@ -261,6 +304,7 @@ interrupt-names = "mem", "ring0", "ring1", "ring2", "ring3", "eip"; clocks = <&cps_clk 1 26>; + dma-coherent; /* * The cryptographic engine found on the cp110 * master is enabled by default at the SoC diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 015eb072ddef78ca3eeae9aff539c4233690898e..151723b5c733d7f3ee91953098ab363ede6f8ff3 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -1,6 +1,8 @@ +dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb always := $(dtb-y) diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts new file mode 100644 index 0000000000000000000000000000000000000000..8c804df3da4e85d6a6597b0529ca8e33b42c4957 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: YT Shen + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include "mt2712e.dtsi" + +/ { + model = "MediaTek MT2712 evaluation board"; + compatible = "mediatek,mt2712-evb", "mediatek,mt2712"; + + aliases { + serial0 = &uart0; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..57d0396b7faaf6fbdffa00d446616bf10213e90a --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: YT Shen + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +#include +#include + +/ { + compatible = "mediatek,mt2712"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu2>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x001>; + enable-method = "psci"; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x200>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + baud_clk: dummy26m { + compatible = "fixed-clock"; + clock-frequency = <26000000>; + #clock-cells = <0>; + }; + + sys_clk: dummyclk { + compatible = "fixed-clock"; + clock-frequency = <26000000>; + #clock-cells = <0>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + uart5: serial@1000f000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x1000f000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + sysirq: interrupt-controller@10220a80 { + compatible = "mediatek,mt2712-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10220a80 0 0x40>; + }; + + gic: interrupt-controller@10510000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x10510000 0 0x10000>, + <0 0x10520000 0 0x20000>, + <0 0x10540000 0 0x20000>, + <0 0x10560000 0 0x20000>; + interrupts = ; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart1: serial@11003000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11003000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11004000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart3: serial@11005000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11005000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart4: serial@11019000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11019000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi index 31088a9f71dea04966a5db22567f0a5b4be899fd..4beaa71107d7d507af80b8a3248a55715224d463 100644 --- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi @@ -108,13 +108,6 @@ clock-output-names = "clk26m"; }; - clk32k: oscillator@1 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32000>; - clock-output-names = "clk32k"; - }; - timer { compatible = "arm,armv8-timer"; interrupt-parent = <&gic>; @@ -147,6 +140,11 @@ infracfg = <&infrasys>; }; + watchdog: watchdog@10007000 { + compatible = "mediatek,mt6797-wdt", "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; + }; + apmixedsys: apmixed@1000c000 { compatible = "mediatek,mt6797-apmixedsys"; reg = <0 0x1000c000 0 0x1000>; diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts new file mode 100644 index 0000000000000000000000000000000000000000..c08309df2cc7ff61f746f78a0c972c589d86300d --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include "mt7622.dtsi" + +/ { + model = "MediaTek MT7622 RFB1 board"; + compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622"; + + chosen { + bootargs = "console=ttyS0,115200n1"; + }; + + memory { + reg = <0 0x40000000 0 0x3F000000>; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..b111fec2ed9d11996606e6b06d2e72b25f980728 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +#include +#include + +/ { + compatible = "mediatek,mt7622"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + clock-frequency = <1300000000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + clock-frequency = <1300000000>; + }; + }; + + uart_clk: dummy25m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + bus_clk: dummy280m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <280000000>; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@43000000 { + reg = <0 0x43000000 0 0x30000>; + no-map; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + sysirq: interrupt-controller@10200620 { + compatible = "mediatek,mt7622-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10200620 0 0x20>; + }; + + gic: interrupt-controller@10300000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10310000 0 0x1000>, + <0 0x10320000 0 0x1000>, + <0 0x10340000 0 0x2000>, + <0 0x10360000 0 0x2000>; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = ; + clocks = <&uart_clk>, <&bus_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index cc0f02d9dd02fe43315c96474e73d3b905723c8c..ff81d7e5805e8b9dc4ab8eb886836b28c25ddbfc 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,5 +1,6 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb +dtb-$(CONFIG_ARCH_QCOM) += ipq8074-hk01.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index d9464081219467b4ef224d3ebbeddc2a7792773c..790b7775b9016c899228a5be17ebb3fdbe5f4ab8 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -17,6 +17,7 @@ function = PMIC_GPIO_FUNC_NORMAL; power-source = ; input-disable; + output-high; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index bd310ac1967ab5a07f565bcbeead67a482d2e1b3..1d63e6b879de7cc51784077be9b138f9f5635c8e 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -88,6 +88,8 @@ interrupts = <31 2>; adi,dsi-lanes = <4>; + clocks = <&rpmcc RPM_SMD_BB_CLK2>; + clock-names = "cec"; pd-gpios = <&msmgpio 32 0>; @@ -213,11 +215,14 @@ }; usb@78d9000 { - extcon = <&usb_id>, <&usb_id>; + extcon = <&usb_id>; status = "okay"; adp-disable; hnp-disable; srp-disable; + dr_mode = "host"; + pinctrl-names = "default"; + pinctrl-0 = <&usb_sw_sel_pm>; ulpi { phy { v1p8-supply = <&pm8916_l7>; @@ -337,19 +342,11 @@ usb_id: usb-id { compatible = "linux,extcon-usb-gpio"; - id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + vbus-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&usb_id_default>; }; - usb-switch { - compatible = "toshiba,tc7usb40mu"; - switch-gpios = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; - extcon = <&usb_id>; - pinctrl-names = "default"; - pinctrl-0 = <&usb_sw_sel_pm>; - }; - hdmi-out { compatible = "hdmi-connector"; type = "a"; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi index b1142c45fdc983151e24fa2ff084dec82852a0d5..8e379782597a258f84d934ef19a54ab6e6176e26 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi @@ -24,4 +24,28 @@ power-source = ; // 1.8V }; }; + + usb3_vbus_det_gpio: pm8996_gpio22 { + pinconf { + pins = "gpio22"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + bias-pull-down; + qcom,drive-strength = ; + power-source = ; // 1.8V + }; + }; +}; + +&pmi8994_gpios { + usb2_vbus_det_gpio: pmi8996_gpio6 { + pinconf { + pins = "gpio6"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + bias-pull-down; + qcom,drive-strength = ; + power-source = ; // 1.8V + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index d2196fc6d7397d09b9a9b9c702a45fca08709423..789f3e87321e2d47e51d5af9346441addd385413 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -13,6 +13,7 @@ #include "msm8996.dtsi" #include "pm8994.dtsi" +#include "pmi8994.dtsi" #include "apq8096-db820c-pins.dtsi" #include "apq8096-db820c-pmic-pins.dtsi" #include @@ -88,6 +89,55 @@ cd-gpios = <&msmgpio 38 0x1>; status = "okay"; }; + + phy@34000 { + status = "okay"; + }; + + phy@7410000 { + status = "okay"; + }; + + phy@7411000 { + status = "okay"; + }; + + phy@7412000 { + status = "okay"; + }; + + usb@6a00000 { + status = "okay"; + + dwc3@6a00000 { + extcon = <&usb3_id>; + dr_mode = "otg"; + }; + }; + + usb3_id: usb3-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_vbus_det_gpio>; + }; + + usb@7600000 { + status = "okay"; + + dwc3@7600000 { + extcon = <&usb2_id>; + dr_mode = "otg"; + maximum-speed = "high-speed"; + }; + }; + + usb2_id: usb2-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_gpio>; + }; }; @@ -106,4 +156,152 @@ gpios = <&pm8994_gpios 2 GPIO_ACTIVE_LOW>; }; }; + + rpm-glink { + rpm_requests { + pm8994-regulators { + vdd_l1-supply = <&pm8994_s3>; + vdd_l2_l26_l28-supply = <&pm8994_s3>; + vdd_l3_l11-supply = <&pm8994_s3>; + vdd_l4_l27_l31-supply = <&pm8994_s3>; + vdd_l5_l7-supply = <&pm8994_s5>; + vdd_l14_l15-supply = <&pm8994_s5>; + vdd_l20_l21-supply = <&pm8994_s5>; + vdd_l25-supply = <&pm8994_s3>; + + s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + }; + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + s5 { + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + }; + s7 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + }; + + l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + l2 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + }; + l3 { + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + }; + l4 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + }; + l6 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + l8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l11 { + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + }; + l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + }; + l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l16 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + }; + l17 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + }; + l18 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2900000>; + }; + l19 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + }; + l21 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + }; + l22 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + l23 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + l24 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; + }; + l25 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-allow-set-load; + }; + l27 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + l28 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <925000>; + regulator-allow-set-load; + }; + l29 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + l30 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l32 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts new file mode 100644 index 0000000000000000000000000000000000000000..6a838b5d321e31c408674f642698fb7168b9ca93 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts @@ -0,0 +1,52 @@ +/dts-v1/; +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include "ipq8074.dtsi" + +/ { + #address-cells = <0x2>; + #size-cells = <0x2>; + model = "Qualcomm Technologies, Inc. IPQ8074-HK01"; + compatible = "qcom,ipq8074-hk01", "qcom,ipq8074"; + interrupt-parent = <&intc>; + + aliases { + serial0 = &blsp1_uart5; + }; + + chosen { + stdout-path = "serial0"; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000 0x0 0x20000000>; + }; + + soc { + pinctrl@1000000 { + serial_4_pins: serial4_pinmux { + mux { + pins = "gpio23", "gpio24"; + function = "blsp4_uart1"; + bias-disable; + }; + }; + }; + + serial@78b3000 { + pinctrl-0 = <&serial_4_pins>; + pinctrl-names = "default"; + status = "ok"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..2bc5dec5614dec40962e987e0646321a888d4549 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +/ { + model = "Qualcomm Technologies, Inc. IPQ8074"; + compatible = "qcom,ipq8074"; + + soc: soc { + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + pinctrl@1000000 { + compatible = "qcom,ipq8074-pinctrl"; + reg = <0x1000000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x2>; + }; + + intc: interrupt-controller@b000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <0x3>; + reg = <0xb000000 0x1000>, <0xb002000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + timer@b120000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xb120000 0x1000>; + clock-frequency = <19200000>; + + frame@b120000 { + frame-number = <0>; + interrupts = , + ; + reg = <0xb121000 0x1000>, + <0xb122000 0x1000>; + }; + + frame@b123000 { + frame-number = <1>; + interrupts = ; + reg = <0xb123000 0x1000>; + status = "disabled"; + }; + + frame@b124000 { + frame-number = <2>; + interrupts = ; + reg = <0xb124000 0x1000>; + status = "disabled"; + }; + + frame@b125000 { + frame-number = <3>; + interrupts = ; + reg = <0xb125000 0x1000>; + status = "disabled"; + }; + + frame@b126000 { + frame-number = <4>; + interrupts = ; + reg = <0xb126000 0x1000>; + status = "disabled"; + }; + + frame@b127000 { + frame-number = <5>; + interrupts = ; + reg = <0xb127000 0x1000>; + status = "disabled"; + }; + + frame@b128000 { + frame-number = <6>; + interrupts = ; + reg = <0xb128000 0x1000>; + status = "disabled"; + }; + }; + + gcc: gcc@1800000 { + compatible = "qcom,gcc-ipq8074"; + reg = <0x1800000 0x80000>; + #clock-cells = <0x1>; + #reset-cells = <0x1>; + }; + + blsp1_uart5: serial@78b3000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x78b3000 0x200>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_UART5_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + }; + + cpus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0>; + next-level-cache = <&L2_0>; + enable-method = "psci"; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + reg = <0x1>; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + reg = <0x2>; + next-level-cache = <&L2_0>; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + reg = <0x3>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "cache"; + cache-level = <0x2>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + + clocks { + sleep_clk: sleep_clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + xo: xo { + compatible = "fixed-clock"; + clock-frequency = <19200000>; + #clock-cells = <0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 039991f808317027822148650831c3509b7d349c..dc3817593e144708a514a5605491801056e662ab 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -88,6 +88,11 @@ no-map; }; + venus_mem: venus@89900000 { + reg = <0x0 0x89900000 0x0 0x600000>; + no-map; + }; + mba_mem: mba@8ea00000 { no-map; reg = <0 0x8ea00000 0 0x100000>; @@ -204,6 +209,17 @@ }; + gpu_opp_table: opp_table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + }; + opp-19200000 { + opp-hz = /bits/ 64 <19200000>; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -694,6 +710,84 @@ #thermal-sensor-cells = <1>; }; + apps_iommu: iommu@1ef0000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1e20000 0x40000>; + reg = <0x1ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <17>; + + // mdp_0: + iommu-ctx@4000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x4000 0x1000>; + interrupts = ; + }; + + // venus_ns: + iommu-ctx@5000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x5000 0x1000>; + interrupts = ; + }; + }; + + gpu_iommu: iommu@1f08000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1f08000 0x10000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <18>; + + // gfx3d_user: + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = ; + }; + + // gfx3d_priv: + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x2000 0x1000>; + interrupts = ; + }; + }; + + gpu@1c00000 { + compatible = "qcom,adreno-306.0", "qcom,adreno"; + reg = <0x01c00000 0x20000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + clock-names = + "core", + "iface", + "mem", + "mem_iface", + "alt_mem_iface", + "gfx3d"; + clocks = + <&gcc GCC_OXILI_GFX3D_CLK>, + <&gcc GCC_OXILI_AHB_CLK>, + <&gcc GCC_OXILI_GMEM_CLK>, + <&gcc GCC_BIMC_GFX_CLK>, + <&gcc GCC_BIMC_GPU_CLK>, + <&gcc GFX3D_CLK_SRC>; + power-domains = <&gcc OXILI_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; + }; + mdss: mdss@1a00000 { compatible = "qcom,mdss"; reg = <0x1a00000 0x1000>, @@ -735,6 +829,8 @@ "core_clk", "vsync_clk"; + iommus = <&apps_iommu 4>; + ports { #address-cells = <1>; #size-cells = <0>; @@ -990,7 +1086,7 @@ }; replicator@824000 { - compatible = "qcom,coresight-replicator1x", "arm,primecell"; + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0x824000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; @@ -1207,6 +1303,28 @@ }; }; }; + + venus: video-codec@1d00000 { + compatible = "qcom,msm8916-venus"; + reg = <0x01d00000 0xff000>; + interrupts = ; + power-domains = <&gcc VENUS_GDSC>; + clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>, + <&gcc GCC_VENUS0_AHB_CLK>, + <&gcc GCC_VENUS0_AXI_CLK>; + clock-names = "core", "iface", "bus"; + iommus = <&apps_iommu 5>; + memory-region = <&venus_mem>; + status = "okay"; + + video-decoder { + compatible = "venus-decoder"; + }; + + video-encoder { + compatible = "venus-encoder"; + }; + }; }; smd { diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 8f085716e25898a19a4efb8ad493aaf60963eef9..887b61c872dd15b697e4d1969b26be5010a18d4e 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -276,12 +276,83 @@ hwlocks = <&tcsr_mutex 3>; }; + rpm-glink { + compatible = "qcom,glink-rpm"; + + interrupts = ; + + qcom,rpm-msg-ram = <&rpm_msg_ram>; + + mboxes = <&apcs_glb 0>; + + rpm_requests { + compatible = "qcom,rpm-msm8996"; + qcom,glink-channels = "rpm_requests"; + + pm8994-regulators { + compatible = "qcom,rpm-pm8994-regulators"; + + pm8994_s1: s1 {}; + pm8994_s2: s2 {}; + pm8994_s3: s3 {}; + pm8994_s4: s4 {}; + pm8994_s5: s5 {}; + pm8994_s6: s6 {}; + pm8994_s7: s7 {}; + pm8994_s8: s8 {}; + pm8994_s9: s9 {}; + pm8994_s10: s10 {}; + pm8994_s11: s11 {}; + pm8994_s12: s12 {}; + + pm8994_l1: l1 {}; + pm8994_l2: l2 {}; + pm8994_l3: l3 {}; + pm8994_l4: l4 {}; + pm8994_l5: l5 {}; + pm8994_l6: l6 {}; + pm8994_l7: l7 {}; + pm8994_l8: l8 {}; + pm8994_l9: l9 {}; + pm8994_l10: l10 {}; + pm8994_l11: l11 {}; + pm8994_l12: l12 {}; + pm8994_l13: l13 {}; + pm8994_l14: l14 {}; + pm8994_l15: l15 {}; + pm8994_l16: l16 {}; + pm8994_l17: l17 {}; + pm8994_l18: l18 {}; + pm8994_l19: l19 {}; + pm8994_l20: l20 {}; + pm8994_l21: l21 {}; + pm8994_l22: l22 {}; + pm8994_l23: l23 {}; + pm8994_l24: l24 {}; + pm8994_l25: l25 {}; + pm8994_l26: l26 {}; + pm8994_l27: l27 {}; + pm8994_l28: l28 {}; + pm8994_l29: l29 {}; + pm8994_l30: l30 {}; + pm8994_l31: l31 {}; + pm8994_l32: l32 {}; + }; + + }; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0 0xffffffff>; compatible = "simple-bus"; + rpm_msg_ram: memory@68000 { + compatible = "qcom,rpm-msg-ram"; + reg = <0x68000 0x6000>; + }; + tcsr_mutex_regs: syscon@740000 { compatible = "syscon"; reg = <0x740000 0x20000>; @@ -303,6 +374,13 @@ reg = <0x9820000 0x1000>; }; + apcs_glb: mailbox@9820000 { + compatible = "qcom,msm8996-apcs-hmss-global"; + reg = <0x9820000 0x1000>; + + #mbox-cells = <1>; + }; + gcc: clock-controller@300000 { compatible = "qcom,gcc-msm8996"; #clock-cells = <1>; @@ -538,6 +616,209 @@ <960000000>, <825000000>; }; + + qfprom@74000 { + compatible = "qcom,qfprom"; + reg = <0x74000 0x8ff>; + #address-cells = <1>; + #size-cells = <1>; + + qusb2p_hstx_trim: hstx_trim@24e { + reg = <0x24e 0x2>; + bits = <5 4>; + }; + + qusb2s_hstx_trim: hstx_trim@24f { + reg = <0x24f 0x1>; + bits = <1 4>; + }; + }; + + phy@34000 { + compatible = "qcom,msm8996-qmp-pcie-phy"; + reg = <0x34000 0x488>; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>, + <&gcc GCC_PCIE_CLKREF_CLK>; + clock-names = "aux", "cfg_ahb", "ref"; + + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + + resets = <&gcc GCC_PCIE_PHY_BCR>, + <&gcc GCC_PCIE_PHY_COM_BCR>, + <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>; + reset-names = "phy", "common", "cfg"; + status = "disabled"; + + pciephy_0: lane@35000 { + reg = <0x035000 0x130>, + <0x035200 0x200>, + <0x035400 0x1dc>; + #phy-cells = <0>; + + clock-output-names = "pcie_0_pipe_clk_src"; + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; + clock-names = "pipe0"; + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "lane0"; + }; + + pciephy_1: lane@36000 { + reg = <0x036000 0x130>, + <0x036200 0x200>, + <0x036400 0x1dc>; + #phy-cells = <0>; + + clock-output-names = "pcie_1_pipe_clk_src"; + clocks = <&gcc GCC_PCIE_1_PIPE_CLK>; + clock-names = "pipe1"; + resets = <&gcc GCC_PCIE_1_PHY_BCR>; + reset-names = "lane1"; + }; + + pciephy_2: lane@37000 { + reg = <0x037000 0x130>, + <0x037200 0x200>, + <0x037400 0x1dc>; + #phy-cells = <0>; + + clock-output-names = "pcie_2_pipe_clk_src"; + clocks = <&gcc GCC_PCIE_2_PIPE_CLK>; + clock-names = "pipe2"; + resets = <&gcc GCC_PCIE_2_PHY_BCR>; + reset-names = "lane2"; + }; + }; + + phy@7410000 { + compatible = "qcom,msm8996-qmp-usb3-phy"; + reg = <0x7410000 0x1c4>; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_USB3_PHY_AUX_CLK>, + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&gcc GCC_USB3_CLKREF_CLK>; + clock-names = "aux", "cfg_ahb", "ref"; + + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + + resets = <&gcc GCC_USB3_PHY_BCR>, + <&gcc GCC_USB3PHY_PHY_BCR>; + reset-names = "phy", "common"; + status = "disabled"; + + ssusb_phy_0: lane@7410200 { + reg = <0x7410200 0x200>, + <0x7410400 0x130>, + <0x7410600 0x1a8>; + #phy-cells = <0>; + + clock-output-names = "usb3_phy_pipe_clk_src"; + clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>; + clock-names = "pipe0"; + }; + }; + + hsusb_phy1: phy@7411000 { + compatible = "qcom,msm8996-qusb2-phy"; + reg = <0x7411000 0x180>; + #phy-cells = <0>; + + clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&gcc GCC_RX1_USB2_CLKREF_CLK>; + clock-names = "cfg_ahb", "ref"; + + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-dpdm-supply = <&pm8994_l24>; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + nvmem-cells = <&qusb2p_hstx_trim>; + status = "disabled"; + }; + + hsusb_phy2: phy@7412000 { + compatible = "qcom,msm8996-qusb2-phy"; + reg = <0x7412000 0x180>; + #phy-cells = <0>; + + clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&gcc GCC_RX2_USB2_CLKREF_CLK>; + clock-names = "cfg_ahb", "ref"; + + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-dpdm-supply = <&pm8994_l24>; + + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + nvmem-cells = <&qusb2s_hstx_trim>; + status = "disabled"; + }; + + usb2: usb@7600000 { + compatible = "qcom,dwc3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>, + <&gcc GCC_USB20_MASTER_CLK>, + <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_USB20_SLEEP_CLK>, + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + + assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <60000000>; + + power-domains = <&gcc USB30_GDSC>; + status = "disabled"; + + dwc3@7600000 { + compatible = "snps,dwc3"; + reg = <0x7600000 0xcc00>; + interrupts = <0 138 0>; + phys = <&hsusb_phy2>; + phy-names = "usb2-phy"; + }; + }; + + usb3: usb@6a00000 { + compatible = "qcom,dwc3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_AGGRE2_USB3_AXI_CLK>, + <&gcc GCC_USB30_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + + assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>; + assigned-clock-rates = <19200000>, <120000000>; + + power-domains = <&gcc USB30_GDSC>; + status = "disabled"; + + dwc3@6a00000 { + compatible = "snps,dwc3"; + reg = <0x6a00000 0xcc00>; + interrupts = <0 131 0>; + phys = <&hsusb_phy1>, <&ssusb_phy_0>; + phy-names = "usb2-phy", "usb3-phy"; + }; + }; }; adsp-pil { @@ -558,6 +839,15 @@ qcom,smem-states = <&adsp_smp2p_out 0>; qcom,smem-state-names = "stop"; + + smd-edge { + interrupts = ; + + label = "lpass"; + qcom,ipc = <&apcs 16 8>; + qcom,smd-edge = <1>; + qcom,remote-pid = <2>; + }; }; adsp-smp2p { @@ -584,6 +874,30 @@ }; }; + modem-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; + + interrupts = ; + + qcom,ipc = <&apcs 16 14>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + modem_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + modem_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + smp2p-slpi { compatible = "qcom,smp2p"; qcom,smem = <481>, <430>; diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi index d3879a4e8076d53a4bdcd9d2b81d343797c637a2..57673f92805d00346559dc65e2c4d01fc17bc5dd 100644 --- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -8,6 +8,23 @@ reg = <0x2 SPMI_USID>; #address-cells = <1>; #size-cells = <0>; + + pmi8994_gpios: gpios@c000 { + compatible = "qcom,pmi8994-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <2 0xc0 0 IRQ_TYPE_NONE>, + <2 0xc1 0 IRQ_TYPE_NONE>, + <2 0xc2 0 IRQ_TYPE_NONE>, + <2 0xc3 0 IRQ_TYPE_NONE>, + <2 0xc4 0 IRQ_TYPE_NONE>, + <2 0xc5 0 IRQ_TYPE_NONE>, + <2 0xc6 0 IRQ_TYPE_NONE>, + <2 0xc7 0 IRQ_TYPE_NONE>, + <2 0xc8 0 IRQ_TYPE_NONE>, + <2 0xc9 0 IRQ_TYPE_NONE>; + }; }; pmic@3 { diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index acc4bb30d485b6bc55fa50926ae678d73bdcac92..381928bc1358fd9c97995109143cc72282bda1d4 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -2,6 +2,7 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb r8a7795-h3ulcb.dtb dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-xs.dtb dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb +dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts index 95fe207cb6a3fd2fcb168e8557e38327d6041ae4..dd4f9b6a42546defb7b1161ce4e589c25f739d5c 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts @@ -9,8 +9,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795-es1.dtsi" #include "ulcb.dtsi" diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts index b84c156ed6969947bc64d602fefb8da9a55ad030..3f7d5f51e42878cb8550402dbb851411c6399492 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795-es1.dtsi" #include "salvator-x.dtsi" diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index a0ba7bd21ea3aa185bb725ee43c4a4638609e02b..aaa5e67a963ea9ff1b0dddc3a18d46b3e8ae2031 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -21,6 +21,14 @@ status = "disabled"; }; + /delete-node/ usb-phy@ee0e0200; + /delete-node/ usb@ee0e0100; + /delete-node/ usb@ee0e0000; + /delete-node/ usb@e659c000; + + /delete-node/ dma-controller@e6460000; + /delete-node/ dma-controller@e6470000; + fcpf2: fcp@fe952000 { compatible = "renesas,fcpf"; reg = <0 0xfe952000 0 0x200>; @@ -79,6 +87,5 @@ }; &du { - compatible = "renesas,du-r8a7795"; vsps = <&vspd0 &vspd1 &vspd2 &vspd3>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts index 0426f41765f0bc68f426e5284d84a354c686dbd8..0afe777973dec8b7e8fa41b1d521652ba450914a 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts @@ -9,8 +9,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795.dtsi" #include "ulcb.dtsi" @@ -40,3 +38,17 @@ reg = <0x7 0x00000000 0x0 0x40000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 721>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&versaclock5 3>, + <&versaclock5 4>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 684fb3b9d154559eb31d85c401303f4bc52f9f4e..17953070f38dff8d1a4e3e3050f1259fe802240a 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795.dtsi" #include "salvator-x.dtsi" diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts index de354957144b4822479a25894656028f9f1085c1..7675de5d4f2cb13902ecd325654ece89db098741 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795.dtsi" #include "salvator-xs.dtsi" @@ -46,10 +44,12 @@ <&cpg CPG_MOD 722>, <&cpg CPG_MOD 721>, <&cpg CPG_MOD 727>, + <&versaclock6 1>, <&x21_clk>, - <&x22_clk>; + <&x22_clk>, + <&versaclock6 2>; clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0", - "dclkin.1", "dclkin.2"; + "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3"; }; &ehci2 { diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index e31c1b660b3fe78f370a01e1cc67e8c81d24ee97..2938195b9571dd6cd2f568737679770202bc1a3f 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -12,6 +12,8 @@ #include #include +#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 + / { compatible = "renesas,r8a7795"; #address-cells = <2>; @@ -691,6 +693,126 @@ }; }; + drif00: rif@e6f40000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f40000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 515>; + clock-names = "fck"; + dmas = <&dmac1 0x20>, <&dmac2 0x20>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 515>; + renesas,bonding = <&drif01>; + status = "disabled"; + }; + + drif01: rif@e6f50000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f50000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>; + clock-names = "fck"; + dmas = <&dmac1 0x22>, <&dmac2 0x22>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 514>; + renesas,bonding = <&drif00>; + status = "disabled"; + }; + + drif10: rif@e6f60000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f60000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 513>; + clock-names = "fck"; + dmas = <&dmac1 0x24>, <&dmac2 0x24>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 513>; + renesas,bonding = <&drif11>; + status = "disabled"; + }; + + drif11: rif@e6f70000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f70000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 512>; + clock-names = "fck"; + dmas = <&dmac1 0x26>, <&dmac2 0x26>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 512>; + renesas,bonding = <&drif10>; + status = "disabled"; + }; + + drif20: rif@e6f80000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f80000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 511>; + clock-names = "fck"; + dmas = <&dmac1 0x28>, <&dmac2 0x28>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 511>; + renesas,bonding = <&drif21>; + status = "disabled"; + }; + + drif21: rif@e6f90000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f90000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 510>; + clock-names = "fck"; + dmas = <&dmac1 0x2a>, <&dmac2 0x2a>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 510>; + renesas,bonding = <&drif20>; + status = "disabled"; + }; + + drif30: rif@e6fa0000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fa0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 509>; + clock-names = "fck"; + dmas = <&dmac1 0x2c>, <&dmac2 0x2c>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 509>; + renesas,bonding = <&drif31>; + status = "disabled"; + }; + + drif31: rif@e6fb0000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fb0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 508>; + clock-names = "fck"; + dmas = <&dmac1 0x2e>, <&dmac2 0x2e>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 508>; + renesas,bonding = <&drif30>; + status = "disabled"; + }; + hscif0: serial@e6540000 { compatible = "renesas,hscif-r8a7795", "renesas,rcar-gen3-hscif", @@ -776,6 +898,68 @@ status = "disabled"; }; + msiof0: spi@e6e90000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6e90000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 211>; + dmas = <&dmac1 0x41>, <&dmac1 0x40>, + <&dmac2 0x41>, <&dmac2 0x40>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 211>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof1: spi@e6ea0000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6ea0000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 210>; + dmas = <&dmac1 0x43>, <&dmac1 0x42>, + <&dmac2 0x43>, <&dmac2 0x42>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 210>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof2: spi@e6c00000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6c00000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 209>; + dmas = <&dmac0 0x45>, <&dmac0 0x44>; + dma-names = "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 209>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof3: spi@e6c10000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6c10000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 208>; + dmas = <&dmac0 0x47>, <&dmac0 0x46>; + dma-names = "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 208>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + scif0: serial@e6e60000 { compatible = "renesas,scif-r8a7795", "renesas,rcar-gen3-scif", "renesas,scif"; @@ -1267,7 +1451,8 @@ }; sata: sata@ee300000 { - compatible = "renesas,sata-r8a7795"; + compatible = "renesas,sata-r8a7795", + "renesas,rcar-gen3-sata"; reg = <0 0xee300000 0 0x200000>; interrupts = ; clocks = <&cpg CPG_MOD 815>; @@ -1314,6 +1499,34 @@ dma-channels = <2>; }; + usb_dmac2: dma-controller@e6460000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe6460000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 326>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 326>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac3: dma-controller@e6470000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe6470000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 329>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 329>; + #dma-cells = <1>; + dma-channels = <2>; + }; + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7795"; reg = <0 0xee100000 0 0x2000>; @@ -1392,6 +1605,18 @@ status = "disabled"; }; + usb2_phy3: usb-phy@ee0e0200 { + compatible = "renesas,usb2-phy-r8a7795", + "renesas,rcar-gen3-usb2-phy"; + reg = <0 0xee0e0200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD 700>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 700>; + #phy-cells = <0>; + status = "disabled"; + }; + ehci0: usb@ee080100 { compatible = "generic-ehci"; reg = <0 0xee080100 0 0x100>; @@ -1399,6 +1624,7 @@ clocks = <&cpg CPG_MOD 703>; phys = <&usb2_phy0>; phy-names = "usb"; + companion = <&ohci0>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 703>; status = "disabled"; @@ -1411,6 +1637,7 @@ clocks = <&cpg CPG_MOD 702>; phys = <&usb2_phy1>; phy-names = "usb"; + companion = <&ohci1>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 702>; status = "disabled"; @@ -1423,11 +1650,25 @@ clocks = <&cpg CPG_MOD 701>; phys = <&usb2_phy2>; phy-names = "usb"; + companion = <&ohci2>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 701>; status = "disabled"; }; + ehci3: usb@ee0e0100 { + compatible = "generic-ehci"; + reg = <0 0xee0e0100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 700>; + phys = <&usb2_phy3>; + phy-names = "usb"; + companion = <&ohci3>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 700>; + status = "disabled"; + }; + ohci0: usb@ee080000 { compatible = "generic-ohci"; reg = <0 0xee080000 0 0x100>; @@ -1464,6 +1705,18 @@ status = "disabled"; }; + ohci3: usb@ee0e0000 { + compatible = "generic-ohci"; + reg = <0 0xee0e0000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 700>; + phys = <&usb2_phy3>; + phy-names = "usb"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 700>; + status = "disabled"; + }; + hsusb: usb@e6590000 { compatible = "renesas,usbhs-r8a7795", "renesas,rcar-gen3-usbhs"; @@ -1481,6 +1734,23 @@ status = "disabled"; }; + hsusb3: usb@e659c000 { + compatible = "renesas,usbhs-r8a7795", + "renesas,rcar-gen3-usbhs"; + reg = <0 0xe659c000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 705>; + dmas = <&usb_dmac2 0>, <&usb_dmac2 1>, + <&usb_dmac3 0>, <&usb_dmac3 1>; + dma-names = "ch0", "ch1", "ch2", "ch3"; + renesas,buswait = <11>; + phys = <&usb2_phy3>; + phy-names = "usb"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 705>; + status = "disabled"; + }; + pciec0: pcie@fe000000 { compatible = "renesas,pcie-r8a7795", "renesas,pcie-rcar-gen3"; @@ -1535,6 +1805,46 @@ status = "disabled"; }; + imr-lx4@fe860000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe860000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 823>; + }; + + imr-lx4@fe870000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe870000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 822>; + }; + + imr-lx4@fe880000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe880000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 821>; + }; + + imr-lx4@fe890000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe890000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 820>; + }; + vspbc: vsp@fe920000 { compatible = "renesas,vsp2"; reg = <0 0xfe920000 0 0x8000>; @@ -1755,6 +2065,7 @@ }; du: display@feb00000 { + compatible = "renesas,du-r8a7795"; reg = <0 0xfeb00000 0 0x80000>, <0 0xfeb90000 0 0x14>; reg-names = "du", "lvds.0"; @@ -1768,6 +2079,7 @@ <&cpg CPG_MOD 721>, <&cpg CPG_MOD 727>; clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; + vsps = <&vspd0 0 &vspd1 0 &vspd2 0 &vspd0 1>; status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts index 38b58b7fca4bf0e9a309a1f9a27f91cb26d9e785..daee1f1a3f68951b4a7615305d219bd4fa990469 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts @@ -9,8 +9,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 - /dts-v1/; #include "r8a7796.dtsi" #include "ulcb.dtsi" @@ -30,3 +28,15 @@ reg = <0x6 0x00000000 0x0 0x40000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&versaclock5 3>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts index db4f162d6bdd2c42e13af8057b866498c0bf6c39..b317be03306e69f8ae7357f310c4764b395b1787 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 - /dts-v1/; #include "r8a7796.dtsi" #include "salvator-x.dtsi" @@ -29,3 +27,32 @@ reg = <0x6 0x00000000 0x0 0x80000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&x21_clk>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2"; +}; + +&hdmi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + }; +}; + +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 1f671091204524e84600c66e697bc57a07d704d6..369092e17e3412914d3204d7f308d57fed3cb152 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -12,6 +12,8 @@ #include #include +#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 + / { compatible = "renesas,r8a7796"; #address-cells = <2>; @@ -639,6 +641,126 @@ }; }; + drif00: rif@e6f40000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f40000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 515>; + clock-names = "fck"; + dmas = <&dmac1 0x20>, <&dmac2 0x20>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 515>; + renesas,bonding = <&drif01>; + status = "disabled"; + }; + + drif01: rif@e6f50000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f50000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>; + clock-names = "fck"; + dmas = <&dmac1 0x22>, <&dmac2 0x22>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 514>; + renesas,bonding = <&drif00>; + status = "disabled"; + }; + + drif10: rif@e6f60000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f60000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 513>; + clock-names = "fck"; + dmas = <&dmac1 0x24>, <&dmac2 0x24>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 513>; + renesas,bonding = <&drif11>; + status = "disabled"; + }; + + drif11: rif@e6f70000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f70000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 512>; + clock-names = "fck"; + dmas = <&dmac1 0x26>, <&dmac2 0x26>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 512>; + renesas,bonding = <&drif10>; + status = "disabled"; + }; + + drif20: rif@e6f80000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f80000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 511>; + clock-names = "fck"; + dmas = <&dmac1 0x28>, <&dmac2 0x28>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 511>; + renesas,bonding = <&drif21>; + status = "disabled"; + }; + + drif21: rif@e6f90000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f90000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 510>; + clock-names = "fck"; + dmas = <&dmac1 0x2a>, <&dmac2 0x2a>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 510>; + renesas,bonding = <&drif20>; + status = "disabled"; + }; + + drif30: rif@e6fa0000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fa0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 509>; + clock-names = "fck"; + dmas = <&dmac1 0x2c>, <&dmac2 0x2c>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 509>; + renesas,bonding = <&drif31>; + status = "disabled"; + }; + + drif31: rif@e6fb0000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fb0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 508>; + clock-names = "fck"; + dmas = <&dmac1 0x2e>, <&dmac2 0x2e>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 508>; + renesas,bonding = <&drif30>; + status = "disabled"; + }; + avb: ethernet@e6800000 { compatible = "renesas,etheravb-r8a7796", "renesas,etheravb-rcar-gen3"; @@ -877,7 +999,7 @@ clocks = <&cpg CPG_MOD 211>; dmas = <&dmac1 0x41>, <&dmac1 0x40>, <&dmac2 0x41>, <&dmac2 0x40>; - dma-names = "tx", "rx"; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; resets = <&cpg 211>; #address-cells = <1>; @@ -893,7 +1015,7 @@ clocks = <&cpg CPG_MOD 210>; dmas = <&dmac1 0x43>, <&dmac1 0x42>, <&dmac2 0x43>, <&dmac2 0x42>; - dma-names = "tx", "rx"; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; resets = <&cpg 210>; #address-cells = <1>; @@ -1101,36 +1223,133 @@ dma-channels = <16>; }; + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a7796-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 330>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a7796-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 331>; + #dma-cells = <1>; + dma-channels = <2>; + }; + hsusb: usb@e6590000 { - /* placeholder */ + compatible = "renesas,usbhs-r8a7796", + "renesas,rcar-gen3-usbhs"; + reg = <0 0xe6590000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 704>; + dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, + <&usb_dmac1 0>, <&usb_dmac1 1>; + dma-names = "ch0", "ch1", "ch2", "ch3"; + renesas,buswait = <11>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 704>; + status = "disabled"; }; xhci0: usb@ee000000 { - /* placeholder */ + compatible = "renesas,xhci-r8a7796", + "renesas,rcar-gen3-xhci"; + reg = <0 0xee000000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 328>; + status = "disabled"; }; ohci0: usb@ee080000 { - /* placeholder */ + compatible = "generic-ohci"; + reg = <0 0xee080000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 703>; + status = "disabled"; }; ehci0: usb@ee080100 { - /* placeholder */ + compatible = "generic-ehci"; + reg = <0 0xee080100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + companion= <&ohci0>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 703>; + status = "disabled"; }; usb2_phy0: usb-phy@ee080200 { - /* placeholder */ + compatible = "renesas,usb2-phy-r8a7796", + "renesas,rcar-gen3-usb2-phy"; + reg = <0 0xee080200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 703>; + #phy-cells = <0>; + status = "disabled"; }; ohci1: usb@ee0a0000 { - /* placeholder */ + compatible = "generic-ohci"; + reg = <0 0xee0a0000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 702>; + status = "disabled"; }; ehci1: usb@ee0a0100 { - /* placeholder */ + compatible = "generic-ehci"; + reg = <0 0xee0a0100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + companion= <&ohci1>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 702>; + status = "disabled"; }; usb2_phy1: usb-phy@ee0a0200 { - /* placeholder */ + compatible = "renesas,usb2-phy-r8a7796", + "renesas,rcar-gen3-usb2-phy"; + reg = <0 0xee0a0200 0 0x700>; + clocks = <&cpg CPG_MOD 702>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 702>; + #phy-cells = <0>; + status = "disabled"; }; sdhi0: sd@ee100000 { @@ -1440,8 +1659,150 @@ /* placeholder */ }; + fcpf0: fcp@fe950000 { + compatible = "renesas,fcpf"; + reg = <0 0xfe950000 0 0x200>; + clocks = <&cpg CPG_MOD 615>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 615>; + }; + + vspb: vsp@fe960000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe960000 0 0x8000>; + interrupts = ; + clocks = <&cpg CPG_MOD 626>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 626>; + + renesas,fcp = <&fcpvb0>; + }; + + fcpvb0: fcp@fe96f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe96f000 0 0x200>; + clocks = <&cpg CPG_MOD 607>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 607>; + }; + + vspi0: vsp@fe9a0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe9a0000 0 0x8000>; + interrupts = ; + clocks = <&cpg CPG_MOD 631>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 631>; + + renesas,fcp = <&fcpvi0>; + }; + + fcpvi0: fcp@fe9af000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe9af000 0 0x200>; + clocks = <&cpg CPG_MOD 611>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 611>; + }; + + vspd0: vsp@fea20000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea20000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 623>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 623>; + + renesas,fcp = <&fcpvd0>; + }; + + fcpvd0: fcp@fea27000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea27000 0 0x200>; + clocks = <&cpg CPG_MOD 603>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 603>; + }; + + vspd1: vsp@fea28000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea28000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 622>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 622>; + + renesas,fcp = <&fcpvd1>; + }; + + fcpvd1: fcp@fea2f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea2f000 0 0x200>; + clocks = <&cpg CPG_MOD 602>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 602>; + }; + + vspd2: vsp@fea30000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea30000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 621>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 621>; + + renesas,fcp = <&fcpvd2>; + }; + + fcpvd2: fcp@fea37000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea37000 0 0x200>; + clocks = <&cpg CPG_MOD 601>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 601>; + }; + + hdmi0: hdmi@fead0000 { + compatible = "renesas,r8a7796-hdmi", "renesas,rcar-gen3-hdmi"; + reg = <0 0xfead0000 0 0x10000>; + interrupts = ; + clocks = <&cpg CPG_MOD 729>, <&cpg CPG_CORE R8A7796_CLK_HDMI>; + clock-names = "iahb", "isfr"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 729>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dw_hdmi0_in: endpoint { + remote-endpoint = <&du_out_hdmi0>; + }; + }; + port@1 { + reg = <1>; + }; + }; + }; + du: display@feb00000 { - /* placeholder */ + compatible = "renesas,du-r8a7796"; + reg = <0 0xfeb00000 0 0x70000>, + <0 0xfeb90000 0 0x14>; + reg-names = "du", "lvds.0"; + interrupts = , + , + ; + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 727>; + clock-names = "du.0", "du.1", "du.2", "lvds.0"; + status = "disabled"; + + vsps = <&vspd0 &vspd1 &vspd2>; ports { #address-cells = <1>; @@ -1452,7 +1813,38 @@ du_out_rgb: endpoint { }; }; + port@1 { + reg = <1>; + du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; + }; + }; + port@2 { + reg = <2>; + du_out_lvds0: endpoint { + }; + }; }; }; + + imr-lx4@fe860000 { + compatible = "renesas,r8a7796-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe860000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 823>; + }; + + imr-lx4@fe870000 { + compatible = "renesas,r8a7796-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe870000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 822>; + }; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts new file mode 100644 index 0000000000000000000000000000000000000000..d144370051d559fc9b43fd6ab01f2a5e546d94ce --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -0,0 +1,46 @@ +/* + * Device Tree Source for the Draak board + * + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2017 Glider bvba + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "r8a77995.dtsi" + +/ { + model = "Renesas Draak board based on r8a77995"; + compatible = "renesas,draak", "renesas,r8a77995"; + + aliases { + serial0 = &scif2; + }; + + chosen { + bootargs = "ignore_loglevel"; + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x0 0x18000000>; + }; +}; + +&extal_clk { + clock-frequency = <48000000>; +}; + +&scif2 { + status = "okay"; +}; + +&rwdt { + timeout-sec = <60>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..d0f95b78c022de07bed57a2df667c743dbc43814 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -0,0 +1,155 @@ +/* + * Device Tree Source for the r8a77995 SoC + * + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2017 Glider bvba + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include + +/ { + compatible = "renesas,r8a77995"; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + a53_0: cpu@0 { + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0>; + device_type = "cpu"; + power-domains = <&sysc 5>; + next-level-cache = <&L2_CA53>; + enable-method = "psci"; + }; + + L2_CA53: cache-controller-1 { + compatible = "cache"; + power-domains = <&sysc 21>; + cache-unified; + cache-level = <2>; + }; + }; + + extal_clk: extal { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic: interrupt-controller@f1010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0xf1010000 0 0x1000>, + <0x0 0xf1020000 0 0x20000>, + <0x0 0xf1040000 0 0x20000>, + <0x0 0xf1060000 0 0x20000>; + interrupts = ; + clocks = <&cpg CPG_MOD 408>; + clock-names = "clk"; + power-domains = <&sysc 32>; + resets = <&cpg 408>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a77995-wdt", + "renesas,rcar-gen3-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc 32>; + resets = <&cpg 402>; + status = "disabled"; + }; + + pmu_a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = ; + }; + + cpg: clock-controller@e6150000 { + compatible = "renesas,r8a77995-cpg-mssr"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>; + clock-names = "extal"; + #clock-cells = <2>; + #power-domain-cells = <0>; + #reset-cells = <1>; + }; + + rst: reset-controller@e6160000 { + compatible = "renesas,r8a77995-rst"; + reg = <0 0xe6160000 0 0x0200>; + }; + + pfc: pfc@e6060000 { + compatible = "renesas,pfc-r8a77995"; + reg = <0 0xe6060000 0 0x508>; + }; + + prr: chipid@fff00044 { + compatible = "renesas,prr"; + reg = <0 0xfff00044 0 4>; + }; + + sysc: system-controller@e6180000 { + compatible = "renesas,r8a77995-sysc"; + reg = <0 0xe6180000 0 0x0400>; + #power-domain-cells = <1>; + }; + + scif2: serial@e6e88000 { + compatible = "renesas,scif-r8a77995", + "renesas,rcar-gen3-scif", "renesas,scif"; + reg = <0 0xe6e88000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE 16>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&sysc 32>; + resets = <&cpg 310>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi index aef35e0b685a3a8599f33d1b227f31d0e5f551ea..4786c67b5e6527fd99d27aa969ef0b2d4274b4ad 100644 --- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi @@ -45,7 +45,7 @@ stdout-path = "serial0:115200n8"; }; - audio_clkout: audio_clkout { + audio_clkout: audio-clkout { /* * This is same as <&rcar_sound 0> * but needed to avoid cs2000/rcar_sound probe dead-lock @@ -268,10 +268,6 @@ remote-endpoint = <&adv7123_in>; }; }; - port@3 { - lvds_connector: endpoint { - }; - }; }; }; @@ -508,7 +504,7 @@ /* audio_clkout0/1/2/3 */ #clock-cells = <1>; - clock-frequency = <11289600 12288000>; + clock-frequency = <12288000 11289600>; status = "okay"; diff --git a/arch/arm64/boot/dts/renesas/salvator-xs.dtsi b/arch/arm64/boot/dts/renesas/salvator-xs.dtsi index 81227e3c2c6f1e2d3899e3ea0c824413c3a537a6..bf4d200fb54635eaa448688af444045145a18a96 100644 --- a/arch/arm64/boot/dts/renesas/salvator-xs.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-xs.dtsi @@ -18,3 +18,13 @@ &extal_clk { clock-frequency = <16640000>; }; + +&i2c4 { + versaclock6: clock-generator@6a { + compatible = "idt,5p49v6901"; + reg = <0x6a>; + #clock-cells = <1>; + clocks = <&x23_clk>; + clock-names = "xin"; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi index b5c6ee07d7f91d84d4b5b8e612fcc4f4304bc4c2..1b868df2393ffa3dd07ac2ab6c221e9c5c4c9898 100644 --- a/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -34,6 +34,16 @@ clock-frequency = <11289600>; }; + hdmi0-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi0_con: endpoint { + }; + }; + }; + keyboard { compatible = "gpio-keys"; @@ -120,6 +130,12 @@ #clock-cells = <0>; clock-frequency = <24576000>; }; + + x23_clk: x23-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; }; &audio_clk_a { @@ -153,6 +169,23 @@ clock-frequency = <32768>; }; +&hdmi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + }; +}; + +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; @@ -189,6 +222,24 @@ }; }; +&i2c4 { + status = "okay"; + + clock-frequency = <400000>; + + versaclock5: clock-generator@6a { + compatible = "idt,5p49v5925"; + reg = <0x6a>; + #clock-cells = <1>; + clocks = <&x23_clk>; + clock-names = "xin"; + }; +}; + +&i2c_dvfs { + status = "okay"; +}; + &ohci1 { status = "okay"; }; @@ -281,7 +332,7 @@ /* audio_clkout0/1/2/3 */ #clock-cells = <1>; - clock-frequency = <11289600 12288000>; + clock-frequency = <12288000 11289600>; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index bcfa53b1e6b7ef7e310ba731c090c10fac657bfc..f1c9b13cea5c21ce89efec347c61593e092a681e 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb @@ -7,6 +8,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts index cf272392cebf4712367dcf8c3f5009349f0ed4ad..8e6a6543175673d6fd9e3d7e5d370b29ac7a2c50 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -50,8 +50,189 @@ chosen { stdout-path = "serial2:1500000n8"; }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; +}; + +&gmac2phy { + phy-supply = <&vcc_phy>; + clock_in_out = "output"; + assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; + assigned-clock-rate = <50000000>; + assigned-clocks = <&cru SCLK_MAC2PHY>; + assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + rk805: rk805@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; + vcc6-supply = <&vcc_io>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_18: LDO_REG1 { + regulator-name = "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc18_emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&tsadc { + status = "okay"; }; &uart2 { status = "okay"; }; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&usb20_otg { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts new file mode 100644 index 0000000000000000000000000000000000000000..d4f80786e7c20c0a46bacb9636f8defc7ef137b4 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2017 PINE64 + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "rk3328.dtsi" + +/ { + model = "Pine64 Rock64"; + compatible = "pine64,rock64", "rockchip,rk3328"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac_clkin: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0>; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0m1_gpio>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io>; + }; + + vcc_host_5v: vcc-host-5v-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb30_host_drv>; + regulator-name = "vcc_host_5v"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb20_host_drv>; + regulator-name = "vcc_host1_5v"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc18_emmc>; + status = "okay"; +}; + +&gmac2io { + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; + clock_in_out = "input"; + phy-supply = <&vcc_io>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmiim1_pins>; + snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x26>; + rx_delay = <0x11>; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + rk805: rk805@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; + vcc6-supply = <&vcc_sys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_18: LDO_REG1 { + regulator-name = "vdd_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc_18emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb2 { + usb20_host_drv: usb20-host-drv { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb3 { + usb30_host_drv: usb30-host-drv { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 0be96cee27bd107e5af9cecd8a72ffc6c1ca7b46..6d615cb6e64d07cebcfa0a7ecebf04b8afb152b2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -47,6 +47,7 @@ #include #include #include +#include / { compatible = "rockchip,rk3328"; @@ -63,6 +64,8 @@ i2c1 = &i2c1; i2c2 = &i2c2; i2c3 = &i2c3; + ethernet0 = &gmac2io; + ethernet1 = &gmac2phy; }; cpus { @@ -74,8 +77,11 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x0>; clocks = <&cru ARMCLK>; + #cooling-cells = <2>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu1: cpu@1 { @@ -83,8 +89,10 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x1>; clocks = <&cru ARMCLK>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu2: cpu@2 { @@ -92,8 +100,10 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x2>; clocks = <&cru ARMCLK>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu3: cpu@3 { @@ -101,8 +111,10 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x3>; clocks = <&cru ARMCLK>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; l2: l2-cache0 { @@ -110,6 +122,43 @@ }; }; + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <40000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1100000>; + clock-latency-ns = <40000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1225000>; + clock-latency-ns = <40000>; + }; + opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1300000>; + clock-latency-ns = <40000>; + }; + }; + amba { compatible = "simple-bus"; #address-cells = <2>; @@ -156,12 +205,84 @@ clock-output-names = "xin24m"; }; + i2s0: i2s@ff000000 { + compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s"; + reg = <0x0 0xff000000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; + clock-names = "i2s_clk", "i2s_hclk"; + dmas = <&dmac 11>, <&dmac 12>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + i2s1: i2s@ff010000 { + compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s"; + reg = <0x0 0xff010000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1_8CH>; + clock-names = "i2s_clk", "i2s_hclk"; + dmas = <&dmac 14>, <&dmac 15>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + i2s2: i2s@ff020000 { + compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s"; + reg = <0x0 0xff020000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2_2CH>; + clock-names = "i2s_clk", "i2s_hclk"; + dmas = <&dmac 0>, <&dmac 1>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + spdif: spdif@ff030000 { + compatible = "rockchip,rk3328-spdif"; + reg = <0x0 0xff030000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF_8CH>; + clock-names = "mclk", "hclk"; + dmas = <&dmac 10>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdifm2_tx>; + status = "disabled"; + }; + + pdm: pdm@ff040000 { + compatible = "rockchip,pdm"; + reg = <0x0 0xff040000 0x0 0x1000>; + clocks = <&cru SCLK_PDM>, <&cru HCLK_PDM>; + clock-names = "pdm_clk", "pdm_hclk"; + dmas = <&dmac 16>; + dma-names = "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pdmm0_clk + &pdmm0_sdi0 + &pdmm0_sdi1 + &pdmm0_sdi2 + &pdmm0_sdi3>; + pinctrl-1 = <&pdmm0_clk_sleep + &pdmm0_sdi0_sleep + &pdmm0_sdi1_sleep + &pdmm0_sdi2_sleep + &pdmm0_sdi3_sleep>; + status = "disabled"; + }; + grf: syscon@ff100000 { compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd"; reg = <0x0 0xff100000 0x0 0x1000>; #address-cells = <1>; #size-cells = <1>; + io_domains: io-domains { + compatible = "rockchip,rk3328-io-voltage-domain"; + status = "disabled"; + }; + power: power-controller { compatible = "rockchip,rk3328-power-controller"; #power-domain-cells = <1>; @@ -308,6 +429,108 @@ interrupts = ; }; + pwm0: pwm@ff1b0000 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0000 0x0 0x10>; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@ff1b0010 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0010 0x0 0x10>; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@ff1b0020 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0020 0x0 0x10>; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm2_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@ff1b0030 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0030 0x0 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwmir_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + thermal-zones { + soc_thermal: soc-thermal { + polling-delay-passive = <20>; + polling-delay = <1000>; + sustainable-power = <1000>; + + thermal-sensors = <&tsadc 0>; + + trips { + threshold: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "passive"; + }; + target: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + soc_crit: soc-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <4096>; + }; + }; + }; + + }; + + tsadc: tsadc@ff250000 { + compatible = "rockchip,rk3328-tsadc"; + reg = <0x0 0xff250000 0x0 0x100>; + interrupts = ; + assigned-clocks = <&cru SCLK_TSADC>; + assigned-clock-rates = <50000>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + pinctrl-names = "init", "default", "sleep"; + pinctrl-0 = <&otp_gpio>; + pinctrl-1 = <&otp_out>; + pinctrl-2 = <&otp_gpio>; + resets = <&cru SRST_TSADC>; + reset-names = "tsadc-apb"; + rockchip,grf = <&grf>; + rockchip,hw-tshut-temp = <100000>; + #thermal-sensor-cells = <1>; + status = "disabled"; + }; + saradc: adc@ff280000 { compatible = "rockchip,rk3328-saradc", "rockchip,rk3399-saradc"; reg = <0x0 0xff280000 0x0 0x100>; @@ -320,6 +543,51 @@ status = "disabled"; }; + h265e_mmu: iommu@ff330200 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff330200 0 0x100>; + interrupts = ; + interrupt-names = "h265e_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vepu_mmu: iommu@ff340800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff340800 0x0 0x40>; + interrupts = ; + interrupt-names = "vepu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vpu_mmu: iommu@ff350800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff350800 0x0 0x40>; + interrupts = ; + interrupt-names = "vpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + rkvdec_mmu: iommu@ff360480 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>; + interrupts = ; + interrupt-names = "rkvdec_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vop_mmu: iommu@ff373f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff373f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + cru: clock-controller@ff440000 { compatible = "rockchip,rk3328-cru", "rockchip,cru", "syscon"; reg = <0x0 0xff440000 0x0 0x1000>; @@ -372,6 +640,43 @@ <32768>; }; + usb2phy_grf: syscon@ff450000 { + compatible = "rockchip,rk3328-usb2phy-grf", "syscon", + "simple-mfd"; + reg = <0x0 0xff450000 0x0 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy: usb2-phy@100 { + compatible = "rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <&xin24m>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy"; + #clock-cells = <0>; + assigned-clocks = <&cru USB480M>; + assigned-clock-parents = <&u2phy>; + status = "disabled"; + + u2phy_otg: otg-port { + #phy-cells = <0>; + interrupts = , + , + ; + interrupt-names = "otg-bvalid", "otg-id", + "linestate"; + status = "disabled"; + }; + + u2phy_host: host-port { + #phy-cells = <0>; + interrupts = ; + interrupt-names = "linestate"; + status = "disabled"; + }; + }; + }; + sdmmc: dwmmc@ff500000 { compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff500000 0x0 0x4000>; @@ -424,6 +729,82 @@ status = "disabled"; }; + gmac2phy: ethernet@ff550000 { + compatible = "rockchip,rk3328-gmac"; + reg = <0x0 0xff550000 0x0 0x10000>; + rockchip,grf = <&grf>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&cru SCLK_MAC2PHY_SRC>, <&cru SCLK_MAC2PHY_RXTX>, + <&cru SCLK_MAC2PHY_RXTX>, <&cru SCLK_MAC2PHY_REF>, + <&cru ACLK_MAC2PHY>, <&cru PCLK_MAC2PHY>, + <&cru SCLK_MAC2PHY_OUT>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "aclk_mac", "pclk_mac", + "clk_macphy"; + resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>; + reset-names = "stmmaceth", "mac-phy"; + phy-mode = "rmii"; + phy-handle = <&phy>; + status = "disabled"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + phy: phy@0 { + compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + clocks = <&cru SCLK_MAC2PHY_OUT>; + resets = <&cru SRST_MACPHY>; + pinctrl-names = "default"; + pinctrl-0 = <&fephyled_rxm1 &fephyled_linkm1>; + phy-is-integrated; + }; + }; + }; + + usb20_otg: usb@ff580000 { + compatible = "rockchip,rk3328-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0x0 0xff580000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; + dr_mode = "otg"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; + g-use-dma; + phys = <&u2phy_otg>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + usb_host0_ehci: usb@ff5c0000 { + compatible = "generic-ehci"; + reg = <0x0 0xff5c0000 0x0 0x10000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host0_ohci: usb@ff5d0000 { + compatible = "generic-ohci"; + reg = <0x0 0xff5d0000 0x0 0x10000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + gic: interrupt-controller@ff811000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -610,6 +991,62 @@ }; }; + pdm-0 { + pdmm0_clk: pdmm0-clk { + rockchip,pins = <2 RK_PC2 2 &pcfg_pull_none>; + }; + + pdmm0_fsync: pdmm0-fsync { + rockchip,pins = <2 RK_PC7 2 &pcfg_pull_none>; + }; + + pdmm0_sdi0: pdmm0-sdi0 { + rockchip,pins = <2 RK_PC3 2 &pcfg_pull_none>; + }; + + pdmm0_sdi1: pdmm0-sdi1 { + rockchip,pins = <2 RK_PC4 2 &pcfg_pull_none>; + }; + + pdmm0_sdi2: pdmm0-sdi2 { + rockchip,pins = <2 RK_PC5 2 &pcfg_pull_none>; + }; + + pdmm0_sdi3: pdmm0-sdi3 { + rockchip,pins = <2 RK_PC6 2 &pcfg_pull_none>; + }; + + pdmm0_clk_sleep: pdmm0-clk-sleep { + rockchip,pins = + <2 RK_PC2 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi0_sleep: pdmm0-sdi0-sleep { + rockchip,pins = + <2 RK_PC3 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi1_sleep: pdmm0-sdi1-sleep { + rockchip,pins = + <2 RK_PC4 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi2_sleep: pdmm0-sdi2-sleep { + rockchip,pins = + <2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi3_sleep: pdmm0-sdi3-sleep { + rockchip,pins = + <2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_fsync_sleep: pdmm0-fsync-sleep { + rockchip,pins = + <2 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>; + }; + }; + tsadc { otp_gpio: otp-gpio { rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 4772917c5f7e6067a79cd22080741156329f215c..a37220a9387c325a1caf7e2c735ee5c776af4982 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -156,7 +156,6 @@ disable-wp; mmc-pwrseq = <&emmc_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts b/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts index e631d424f08ea64991b6d00d748819ce5328ae9c..5e4d3a7015f52de883c2a43ce38da7f5c5421993 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts @@ -117,7 +117,6 @@ clock-frequency = <150000000>; disable-wp; non-removable; - num-slots = <1>; vmmc-supply = <&vcc_io>; vqmmc-supply = <&vcc18_flash>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts index fac116acc12fa0f65755fe3897a87347cf75fded..d3f6c8e0d206d0fcf28ade6612499fec212dcc6a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts @@ -203,7 +203,6 @@ mmc-hs200-1_2v; mmc-hs200-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; status = "okay"; @@ -347,7 +346,6 @@ max-frequency = <50000000>; cap-sd-highspeed; card-detect-delay = <200>; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts index ff48edd8e3482bcafcf4920ecdf1b93995bd5a5b..13a9e22f5d2d2caa3604a4315be98879ba069bbd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts @@ -86,12 +86,10 @@ cap-mmc-highspeed; clock-frequency = <150000000>; disable-wp; - keep-power-in-suspend; mmc-hs200-1_8v; no-sdio; no-sd; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -281,7 +279,6 @@ card-detect-delay = <200>; no-emmc; no-sdio; - num-slots = <1>; sd-uhs-sdr12; sd-uhs-sdr25; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 7134181f1dc27190ee2c3be5f1161288a864d3c8..b3510d56517a63a39506e3434ce7969cc708a2d7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -189,7 +189,6 @@ disable-wp; mmc-pwrseq = <&emmc_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; status = "okay"; @@ -254,7 +253,6 @@ keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>; vmmc-supply = <&vcc_io>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 6d5dc0587e599dd768ed00d0df92145a862dce1b..19fbaa5e7bdd573e6ba6959be9c72ccbb0a388a6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -700,6 +700,19 @@ interrupts = ; }; + spdif: spdif@ff880000 { + compatible = "rockchip,rk3368-spdif"; + reg = <0x0 0xff880000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>; + clock-names = "mclk", "hclk"; + dmas = <&dmac_bus 3>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; + status = "disabled"; + }; + i2s_2ch: i2s-2ch@ff890000 { compatible = "rockchip,rk3368-i2s", "rockchip,rk3066-i2s"; reg = <0x0 0xff890000 0x0 0x1000>; @@ -724,6 +737,55 @@ status = "disabled"; }; + iep_mmu: iommu@ff900800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff900800 0x0 0x100>; + interrupts = ; + interrupt-names = "iep_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + isp_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, + <0x0 0xff915000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + + vop_mmu: iommu@ff930300 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff930300 0x0 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + hevc_mmu: iommu@ff9a0440 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9a0440 0x0 0x40>, + <0x0 0xff9a0480 0x0 0x40>; + interrupts = ; + interrupt-names = "hevc_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vpu_mmu: iommu@ff9a0800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9a0800 0x0 0x100>; + interrupts = , + ; + interrupt-names = "vepu_mmu", "vdpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + gic: interrupt-controller@ffb71000 { compatible = "arm,gic-400"; interrupt-controller; @@ -1024,6 +1086,12 @@ }; }; + spdif { + spdif_tx: spdif-tx { + rockchip,pins = <2 RK_PC7 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + spi0 { spi0_clk: spi0-clk { rockchip,pins = <1 29 RK_FUNC_2 &pcfg_pull_up>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts index 42033bcc614cbb05b9615538bb66728ca11416df..56533c344ef2caa5d237e61aff438caf068d96e3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts @@ -199,7 +199,7 @@ ep-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_HIGH>; num-lanes = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pcie_clkreqn>; + pinctrl-0 = <&pcie_clkreqn_cpm>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts index ba1d9810ad1e29916809dc1075359c6d0244d4e7..7fd4bfcaa38e33c8b58ef60dc7adb99772b04cc1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts @@ -43,6 +43,7 @@ /dts-v1/; #include #include "rk3399.dtsi" +#include "rk3399-opp.dtsi" / { model = "Firefly-RK3399 Board"; @@ -550,7 +551,7 @@ ep-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; num-lanes = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pcie_clkreqn>; + pinctrl-0 = <&pcie_clkreqn_cpm>; status = "okay"; }; @@ -630,9 +631,20 @@ status = "okay"; }; +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + status = "okay"; +}; + &sdhci { bus-width = <8>; - keep-power-in-suspend; mmc-hs400-1_8v; mmc-hs400-enhanced-strobe; non-removable; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts index 7bd31066399b5859a053570a35281cec23d1d888..a3d3cea7dc4f60578e5901e13546ad36fa497f41 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts @@ -264,6 +264,50 @@ ap_i2c_dig: &i2c2 { }; }; +&ppvar_bigcpu_pwm { + regulator-min-microvolt = <798674>; + regulator-max-microvolt = <1302172>; +}; + +&ppvar_bigcpu { + regulator-min-microvolt = <798674>; + regulator-max-microvolt = <1302172>; + ctrl-voltage-range = <798674 1302172>; +}; + +&ppvar_litcpu_pwm { + regulator-min-microvolt = <799065>; + regulator-max-microvolt = <1303738>; +}; + +&ppvar_litcpu { + regulator-min-microvolt = <799065>; + regulator-max-microvolt = <1303738>; + ctrl-voltage-range = <799065 1303738>; +}; + +&ppvar_gpu_pwm { + regulator-min-microvolt = <785782>; + regulator-max-microvolt = <1217729>; +}; + +&ppvar_gpu { + regulator-min-microvolt = <785782>; + regulator-max-microvolt = <1217729>; + ctrl-voltage-range = <785782 1217729>; +}; + +&ppvar_centerlogic_pwm { + regulator-min-microvolt = <800069>; + regulator-max-microvolt = <1049692>; +}; + +&ppvar_centerlogic { + regulator-min-microvolt = <800069>; + regulator-max-microvolt = <1049692>; + ctrl-voltage-range = <800069 1049692>; +}; + &saradc { status = "okay"; vref-supply = <&pp1800_ap_io>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index eb505934402311f8b6b4621bb1d79b8965b0648e..199a5118b20dab39f744dfc21814b1a9dafb166f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -164,14 +164,9 @@ vin-supply = <&ppvar_sys>; }; - ppvar_bigcpu: ppvar-bigcpu { + ppvar_bigcpu_pwm: ppvar-bigcpu-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_bigcpu"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_bigcpu_pwm"; pwms = <&pwm1 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -181,18 +176,28 @@ /* EC turns on w/ ap_core_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <798674>; - regulator-max-microvolt = <1302172>; + regulator-min-microvolt = <800107>; + regulator-max-microvolt = <1302232>; }; - ppvar_litcpu: ppvar-litcpu { + ppvar_bigcpu: ppvar-bigcpu { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_bigcpu"; + + regulator-min-microvolt = <800107>; + regulator-max-microvolt = <1302232>; + + ctrl-supply = <&ppvar_bigcpu_pwm>; + ctrl-voltage-range = <800107 1302232>; + + regulator-settling-time-up-us = <322>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; + }; + + ppvar_litcpu_pwm: ppvar-litcpu-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_litcpu"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_litcpu_pwm"; pwms = <&pwm2 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -202,18 +207,28 @@ /* EC turns on w/ ap_core_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <799065>; - regulator-max-microvolt = <1303738>; + regulator-min-microvolt = <797743>; + regulator-max-microvolt = <1307837>; }; - ppvar_gpu: ppvar-gpu { + ppvar_litcpu: ppvar-litcpu { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_litcpu"; + + regulator-min-microvolt = <797743>; + regulator-max-microvolt = <1307837>; + + ctrl-supply = <&ppvar_litcpu_pwm>; + ctrl-voltage-range = <797743 1307837>; + + regulator-settling-time-up-us = <384>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; + }; + + ppvar_gpu_pwm: ppvar-gpu-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_gpu"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_gpu_pwm"; pwms = <&pwm0 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -223,18 +238,28 @@ /* EC turns on w/ ap_core_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <785782>; - regulator-max-microvolt = <1217729>; + regulator-min-microvolt = <786384>; + regulator-max-microvolt = <1217747>; }; - ppvar_centerlogic: ppvar-centerlogic { + ppvar_gpu: ppvar-gpu { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_gpu"; + + regulator-min-microvolt = <786384>; + regulator-max-microvolt = <1217747>; + + ctrl-supply = <&ppvar_gpu_pwm>; + ctrl-voltage-range = <786384 1217747>; + + regulator-settling-time-up-us = <390>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; + }; + + ppvar_centerlogic_pwm: ppvar-centerlogic-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_centerlogic"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_centerlogic_pwm"; pwms = <&pwm3 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -244,8 +269,23 @@ /* EC turns on w/ ppvar_centerlogic_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <800069>; - regulator-max-microvolt = <1049692>; + regulator-min-microvolt = <799434>; + regulator-max-microvolt = <1049925>; + }; + + ppvar_centerlogic: ppvar-centerlogic { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_centerlogic"; + + regulator-min-microvolt = <799434>; + regulator-max-microvolt = <1049925>; + + ctrl-supply = <&ppvar_centerlogic_pwm>; + ctrl-voltage-range = <799434 1049925>; + + regulator-settling-time-up-us = <378>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; }; /* Schematics call this PPVAR even though it's fixed */ @@ -555,6 +595,11 @@ status = "okay"; }; +&gpu { + mali-supply = <&ppvar_gpu>; + status = "okay"; +}; + ap_i2c_mic: &i2c1 { status = "okay"; @@ -567,12 +612,7 @@ ap_i2c_mic: &i2c1 { headsetcodec: rt5514@57 { compatible = "realtek,rt5514"; reg = <0x57>; - interrupt-parent = <&gpio1>; - interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&mic_int>; - realtek,dmic-init-delay = <20>; - wakeup-source; + realtek,dmic-init-delay-ms = <20>; }; }; @@ -781,9 +821,13 @@ ap_i2c_audio: &i2c8 { wacky_spi_audio: spi2@0 { compatible = "realtek,rt5514"; reg = <0>; - + interrupt-parent = <&gpio1>; + interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mic_int>; /* May run faster once verified. */ spi-max-frequency = <10000000>; + wakeup-source; }; }; @@ -1031,7 +1075,7 @@ ap_i2c_audio: &i2c8 { * hurt and dw_mmc will ignore it. We make sure to disable * the pull though so we don't burn needless power. */ - sdmmc_cd: sdmcc-cd { + sdmmc_cd: sdmmc-cd { rockchip,pins = <0 7 RK_FUNC_1 &pcfg_pull_none>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi index be7fe635f7c15f0e1aac3e7e716305bfd1ee715a..d8a120f945c803ee91e4fdd5a7afa3a8b68ed28a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi @@ -118,6 +118,35 @@ opp-microvolt = <1250000>; }; }; + + gpu_opp_table: opp-table2 { + compatible = "operating-points-v2"; + + opp00 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <800000>; + }; + opp01 { + opp-hz = /bits/ 64 <297000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <825000>; + }; + opp03 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <850000>; + }; + opp04 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <925000>; + }; + opp05 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1075000>; + }; + }; }; &cpu_l0 { @@ -143,3 +172,7 @@ &cpu_b1 { operating-points-v2 = <&cluster1_opp>; }; + +&gpu { + operating-points-v2 = <&gpu_opp_table>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi index c83460db130ab35fcf4a37b9c9998de6be87f7d8..81617bcf252272313163f9dc48ef35c077981559 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi @@ -110,6 +110,35 @@ opp-microvolt = <1200000>; }; }; + + gpu_opp_table: opp-table2 { + compatible = "operating-points-v2"; + + opp00 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <800000>; + }; + opp01 { + opp-hz = /bits/ 64 <297000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <825000>; + }; + opp03 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <875000>; + }; + opp04 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <925000>; + }; + opp05 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1100000>; + }; + }; }; &cpu_l0 { @@ -135,3 +164,7 @@ &cpu_b1 { operating-points-v2 = <&cluster1_opp>; }; + +&gpu { + operating-points-v2 = <&gpu_opp_table>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts new file mode 100644 index 0000000000000000000000000000000000000000..9a7486058455fe3c4b39b1bf68cf5434ab444d0a --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "rk3399-puma.dtsi" + +/ { + model = "Theobroma Systems RK3399-Q7 SoM"; + compatible = "tsd,rk3399-puma-haikou", "rockchip,rk3399"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + pinctrl-0 = <&led_pin_module>, <&led_sd_haikou>; + + sd-card-led { + label = "sd_card_led"; + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + }; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc3v3_baseboard: vcc3v3-baseboard { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_otg: vcc5v0-otg-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_drv>; + regulator-name = "vcc5v0_otg"; + regulator-always-on; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2c2 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c4 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2c6 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2s0 { + status = "okay"; + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + ep-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_LOW>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + status = "okay"; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&haikou_pin_hog>; + + hog { + haikou_pin_hog: haikou-pin-hog { + rockchip,pins = + /* LID_BTN */ + , + /* BATLOW# */ + , + /* SLP_BTN# */ + , + /* BIOS_DISABLE# */ + ; + }; + }; + + leds { + led_sd_haikou: led-sd-gpio { + rockchip,pins = + ; + }; + }; + + usb2 { + otg_vbus_drv: otg-vbus-drv { + rockchip,pins = + ; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vmmc-supply = <&vcc3v3_baseboard>; + status = "okay"; +}; + +&spi5 { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + dr_mode = "otg"; + status = "okay"; +}; + +&u2phy0_host { + phy-supply = <&vcc5v0_otg>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..53ff3d191a1d176cc0d7c6d380894b48e42ec7da --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pin_module>; + + module-led { + label = "module_led"; + gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + panic-indicator; + }; + }; + + /* + * Overwrite the opp-table for CPUB as this board uses a different + * regulator (FAN53555) that only allows 10mV steps and therefore + * can't reach the operation point target voltages from rk3399-opp.dtsi + */ + /delete-node/ opp-table1; + cluster1_opp: opp-table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <800000>; + clock-latency-ns = <40000>; + }; + opp01 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <830000>; + opp-suspend; + }; + opp03 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <880000>; + }; + opp04 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <950000>; + }; + opp05 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <1030000>; + }; + opp06 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <1100000>; + }; + opp07 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1200000>; + }; + opp08 { + opp-hz = /bits/ 64 <1992000000>; + opp-microvolt = <1230000>; + turbo-mode; + }; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + vcc1v2_phy: vcc1v2-phy { + compatible = "regulator-fixed"; + regulator-name = "vcc1v2_phy"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + enable-active-low; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 0>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + status = "okay"; + }; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc1v2_phy>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x10>; + rx_delay = <0x10>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + clock-frequency = <400000>; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <22 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc6-supply = <&vcc5v0_sys>; + vcc7-supply = <&vcc5v0_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc5v0_sys>; + vcc10-supply = <&vcc5v0_sys>; + vcc11-supply = <&vcc5v0_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_ldo1: LDO_REG1 { + regulator-name = "vcc_ldo1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_hdmi: LDO_REG2 { + regulator-name = "vcc1v8_hdmi"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sd: LDO_REG4 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_ldo5: LDO_REG5 { + regulator-name = "vcc_ldo5"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ldo6: LDO_REG6 { + regulator-name = "vcc_ldo6"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc0v9_hdmi: LDO_REG7 { + regulator-name = "vcc0v9_hdmi"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_efuse: LDO_REG8 { + regulator-name = "vcc_efuse"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s3: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_gpu: regulator@60 { + compatible = "fcs,fan53555"; + reg = <0x60>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1230000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&i2c7 { + status = "okay"; + clock-frequency = <400000>; + + fan: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + cooling-min-state = <0>; + cooling-max-state = <9>; + #cooling-cells = <2>; + }; + + rtc_twi: rtc@6f { + compatible = "isil,isl1208"; + reg = <0x6f>; + }; +}; + +&i2c8 { + status = "okay"; + clock-frequency = <400000>; + + vdd_cpu_b: regulator@60 { + compatible = "fcs,fan53555"; + reg = <0x60>; + vin-supply = <&vcc5v0_sys>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1230000>; + regulator-ramp-delay = <1000>; + fcs,suspend-voltage-selector = <1>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&io_domains { + status = "okay"; + bt656-supply = <&vcc_1v8>; + audio-supply = <&vcc_1v8>; + sdmmc-supply = <&vcc_sd>; + gpio1830-supply = <&vcc_1v8>; +}; + +&pmu_io_domains { + status = "okay"; + pmu1830-supply = <&vcc_1v8>; +}; + +&pwm2 { + status = "okay"; +}; + +&pinctrl { + i2c8 { + i2c8_xfer_a: i2c8-xfer { + rockchip,pins = + , + ; + }; + }; + + leds { + led_pin_module: led-module-gpio { + rockchip,pins = + ; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + ; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = + ; + }; + }; +}; + +&sdhci { + bus-width = <8>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&sdmmc { + vqmmc = <&vcc_sd>; +}; + +&spi1 { + status = "okay"; + + norflash: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts new file mode 100644 index 0000000000000000000000000000000000000000..b7bd88fb3ae3bff4287f0df1d47593d4cfac316f --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include +#include "rk3399-sapphire.dtsi" + +/ { + model = "Excavator-RK3399 Board"; + compatible = "rockchip,rk3399-sapphire-excavator", "rockchip,rk3399"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-up { + label = "Volume Up"; + linux,code = ; + press-threshold-microvolt = <100000>; + }; + + button-down { + label = "Volume Down"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + + back { + label = "Back"; + linux,code = ; + press-threshold-microvolt = <985000>; + }; + + menu { + label = "Menu"; + linux,code = ; + press-threshold-microvolt = <1314000>; + }; + }; + + edp_panel: edp-panel { + compatible ="lg,lp079qx1-sp0v", "simple-panel"; + backlight = <&backlight>; + enable-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_panel_reset>; + power-supply = <&vcc3v3_s0>; + + ports { + panel_in_edp: endpoint { + remote-endpoint = <&edp_out_panel>; + }; + }; + }; + + keys: gpio-keys { + compatible = "gpio-keys"; + autorepeat; + + power { + debounce-interval = <100>; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO Power"; + linux,code = ; + linux,input-type = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_btn>; + wakeup-source; + }; + }; + + rt5651-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "realtek,rt5651-codec"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + simple-audio-card,cpu { + sound-dai = <&i2s0>; + }; + simple-audio-card,codec { + sound-dai = <&rt5651>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; +}; + +&backlight { + enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&edp { + status = "okay"; + + ports { + edp_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + edp_out_panel: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_in_edp>; + }; + }; + }; +}; + +&i2c1 { + i2c-scl-rising-time-ns = <300>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; + + rt5651: rt5651@1a { + compatible = "rockchip,rt5651"; + reg = <0x1a>; + clocks = <&cru SCLK_I2S_8CH_OUT>; + clock-names = "mclk"; + hp-det-gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>; + spk-con-gpio = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + }; +}; + +&i2c4 { + i2c-scl-rising-time-ns = <600>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + accelerometer@68 { + compatible = "invensense,mpu6500"; + reg = <0x68>; + interrupt-parent = <&gpio1>; + interrupts = ; + }; +}; + +&i2s0 { + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&i2s2 { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&pinctrl { + buttons { + pwr_btn: pwr-btn { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + lcd-panel { + lcd_panel_reset: lcd-panel-reset { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&spdif { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + #sound-dai-cells = <0>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..6c30bb02210d80a2d78843cccaca7a3d83f971cd --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "dt-bindings/pwm/pwm.h" +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + compatible = "rockchip,rk3399-sapphire", "rockchip,rk3399"; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + pwms = <&pwm0 0 25000 0>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + /* switched by pmic_sleep */ + vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc_lan>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x28>; + rx_delay = <0x11>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c3>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l &pmic_dvs2>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc_sys>; + vcc10-supply = <&vcc_sys>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v8_dvp: LDO_REG1 { + regulator-name = "vcc1v8_dvp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v0_tp: LDO_REG2 { + regulator-name = "vcc3v0_tp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio: LDO_REG4 { + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca1v8_codec: LDO_REG7 { + regulator-name = "vcca1v8_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: vcc_lan: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + vin-supply = <&vcc_sys>; + }; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&io_domains { + status = "okay"; + + bt656-supply = <&vcc_3v0>; + audio-supply = <&vcca1v8_codec>; + sdmmc-supply = <&vcc_sdio>; + gpio1830-supply = <&vcc_3v0>; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + assigned-clocks = <&cru SCLK_PCIEPHY_REF>; + assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; + assigned-clock-rates = <100000000>; + ep-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_HIGH>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + status = "okay"; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + pmic_dvs2: pmic-dvs2 { + rockchip,pins = + <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel1_gpio: vsel1-gpio { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = + <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_s3>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + keep-power-in-suspend; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + clock-frequency = <50000000>; + disable-wp; + keep-power-in-suspend; + max-frequency = <50000000>; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + clock-frequency = <150000000>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vqmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + status = "okay"; + dr_mode = "otg"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 69c56f7316c4577105f44d01762d5d1852df05df..ab7629c5b856d7a6ed2ac8e95600262e098a01d6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -110,6 +110,7 @@ enable-method = "psci"; #cooling-cells = <2>; /* min followed by max */ clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_l1: cpu@1 { @@ -118,6 +119,7 @@ reg = <0x0 0x1>; enable-method = "psci"; clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_l2: cpu@2 { @@ -126,6 +128,7 @@ reg = <0x0 0x2>; enable-method = "psci"; clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_l3: cpu@3 { @@ -134,6 +137,7 @@ reg = <0x0 0x3>; enable-method = "psci"; clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_b0: cpu@100 { @@ -143,6 +147,7 @@ enable-method = "psci"; #cooling-cells = <2>; /* min followed by max */ clocks = <&cru ARMCLKB>; + dynamic-power-coefficient = <436>; }; cpu_b1: cpu@101 { @@ -151,9 +156,15 @@ reg = <0x0 0x101>; enable-method = "psci"; clocks = <&cru ARMCLKB>; + dynamic-power-coefficient = <436>; }; }; + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <&vopl_out>, <&vopb_out>; + }; + pmu_a53 { compatible = "arm,cortex-a53-pmu"; interrupts = ; @@ -238,8 +249,10 @@ linux,pci-domain = <0>; max-link-speed = <1>; msi-map = <0x0 &its 0x0 0x1000>; - phys = <&pcie_phy>; - phy-names = "pcie-phy"; + phys = <&pcie_phy 0>, <&pcie_phy 1>, + <&pcie_phy 2>, <&pcie_phy 3>; + phy-names = "pcie-phy-0", "pcie-phy-1", + "pcie-phy-2", "pcie-phy-3"; ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000 0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, @@ -287,6 +300,7 @@ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; resets = <&cru SRST_SDIO0>; reset-names = "reset"; status = "disabled"; @@ -400,6 +414,7 @@ snps,dis-u2-freeclk-exists-quirk; snps,dis_u2_susphy_quirk; snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; status = "disabled"; }; }; @@ -427,6 +442,7 @@ snps,dis-u2-freeclk-exists-quirk; snps,dis_u2_susphy_quirk; snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; status = "disabled"; }; }; @@ -676,6 +692,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi5_clk &spi5_tx &spi5_rx &spi5_cs0>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -948,6 +965,10 @@ }; /* These power domains are grouped by VD_LOGIC */ + pd_edp@RK3399_PD_EDP { + reg = ; + clocks = <&cru PCLK_EDP_CTRL>; + }; pd_emmc@RK3399_PD_EMMC { reg = ; clocks = <&cru ACLK_EMMC>; @@ -965,6 +986,11 @@ <&cru SCLK_SDMMC>; pm_qos = <&qos_sd>; }; + pd_sdioaudio@RK3399_PD_SDIOAUDIO { + reg = ; + clocks = <&cru HCLK_SDIO>; + pm_qos = <&qos_sdioaudio>; + }; pd_vio@RK3399_PD_VIO { reg = ; #address-cells = <1>; @@ -1151,6 +1177,33 @@ status = "disabled"; }; + vpu_mmu: iommu@ff650800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff650800 0x0 0x40>; + interrupts = ; + interrupt-names = "vpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vdec_mmu: iommu@ff660480 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>; + interrupts = ; + interrupt-names = "vdec_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + iep_mmu: iommu@ff670800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff670800 0x0 0x40>; + interrupts = ; + interrupt-names = "iep_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + efuse0: efuse@ff690000 { compatible = "rockchip,rk3399-efuse"; reg = <0x0 0xff690000 0x0 0x80>; @@ -1295,7 +1348,7 @@ compatible = "rockchip,rk3399-pcie-phy"; clocks = <&cru SCLK_PCIEPHY_REF>; clock-names = "refclk"; - #phy-cells = <0>; + #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; reset-names = "phy"; status = "disabled"; @@ -1385,6 +1438,7 @@ clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>; pinctrl-names = "default"; pinctrl-0 = <&spdif_bus>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; status = "disabled"; }; @@ -1399,6 +1453,7 @@ clocks = <&cru SCLK_I2S0_8CH>, <&cru HCLK_I2S0_8CH>; pinctrl-names = "default"; pinctrl-0 = <&i2s0_8ch_bus>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; status = "disabled"; }; @@ -1412,6 +1467,7 @@ clocks = <&cru SCLK_I2S1_8CH>, <&cru HCLK_I2S1_8CH>; pinctrl-names = "default"; pinctrl-0 = <&i2s1_2ch_bus>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; status = "disabled"; }; @@ -1423,6 +1479,224 @@ dma-names = "tx", "rx"; clock-names = "i2s_clk", "i2s_hclk"; clocks = <&cru SCLK_I2S2_8CH>, <&cru HCLK_I2S2_8CH>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; + status = "disabled"; + }; + + vopl: vop@ff8f0000 { + compatible = "rockchip,rk3399-vop-lit"; + reg = <0x0 0xff8f0000 0x0 0x3efc>; + interrupts = ; + assigned-clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; + assigned-clock-rates = <400000000>, <100000000>; + clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + iommus = <&vopl_mmu>; + power-domains = <&power RK3399_PD_VOPL>; + resets = <&cru SRST_A_VOP1>, <&cru SRST_H_VOP1>, <&cru SRST_D_VOP1>; + reset-names = "axi", "ahb", "dclk"; + status = "disabled"; + + vopl_out: port { + #address-cells = <1>; + #size-cells = <0>; + + vopl_out_mipi: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_in_vopl>; + }; + + vopl_out_edp: endpoint@1 { + reg = <1>; + remote-endpoint = <&edp_in_vopl>; + }; + + vopl_out_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_in_vopl>; + }; + }; + }; + + vopl_mmu: iommu@ff8f3f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff8f3f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vopl_mmu"; + clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; + clock-names = "aclk", "hclk"; + power-domains = <&power RK3399_PD_VOPL>; + #iommu-cells = <0>; + status = "disabled"; + }; + + vopb: vop@ff900000 { + compatible = "rockchip,rk3399-vop-big"; + reg = <0x0 0xff900000 0x0 0x3efc>; + interrupts = ; + assigned-clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>; + assigned-clock-rates = <400000000>, <100000000>; + clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + iommus = <&vopb_mmu>; + power-domains = <&power RK3399_PD_VOPB>; + resets = <&cru SRST_A_VOP0>, <&cru SRST_H_VOP0>, <&cru SRST_D_VOP0>; + reset-names = "axi", "ahb", "dclk"; + status = "disabled"; + + vopb_out: port { + #address-cells = <1>; + #size-cells = <0>; + + vopb_out_edp: endpoint@0 { + reg = <0>; + remote-endpoint = <&edp_in_vopb>; + }; + + vopb_out_mipi: endpoint@1 { + reg = <1>; + remote-endpoint = <&mipi_in_vopb>; + }; + + vopb_out_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_in_vopb>; + }; + }; + }; + + vopb_mmu: iommu@ff903f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff903f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vopb_mmu"; + clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>; + clock-names = "aclk", "hclk"; + power-domains = <&power RK3399_PD_VOPB>; + #iommu-cells = <0>; + status = "disabled"; + }; + + isp0_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp0_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + + isp1_mmu: iommu@ff924000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp1_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + + hdmi: hdmi@ff940000 { + compatible = "rockchip,rk3399-dw-hdmi"; + reg = <0x0 0xff940000 0x0 0x20000>; + interrupts = ; + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_SFR>, <&cru PLL_VPLL>, <&cru PCLK_VIO_GRF>; + clock-names = "iahb", "isfr", "vpll", "grf"; + power-domains = <&power RK3399_PD_HDCP>; + reg-io-width = <4>; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; + hdmi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_hdmi>; + }; + }; + }; + }; + + mipi_dsi: mipi@ff960000 { + compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"; + reg = <0x0 0xff960000 0x0 0x8000>; + interrupts = ; + clocks = <&cru SCLK_DPHY_PLL>, <&cru PCLK_MIPI_DSI0>, + <&cru SCLK_DPHY_TX0_CFG>, <&cru PCLK_VIO_GRF>; + clock-names = "ref", "pclk", "phy_cfg", "grf"; + power-domains = <&power RK3399_PD_VIO>; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + mipi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_mipi>; + }; + mipi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_mipi>; + }; + }; + }; + }; + + edp: edp@ff970000 { + compatible = "rockchip,rk3399-edp"; + reg = <0x0 0xff970000 0x0 0x8000>; + interrupts = ; + clocks = <&cru PCLK_EDP>, <&cru PCLK_EDP_CTRL>; + clock-names = "dp", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&edp_hpd>; + power-domains = <&power RK3399_PD_EDP>; + resets = <&cru SRST_P_EDP_CTRL>; + reset-names = "dp"; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + edp_in: port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + edp_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_edp>; + }; + + edp_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_edp>; + }; + }; + }; + }; + + gpu: gpu@ff9a0000 { + compatible = "rockchip,rk3399-mali", "arm,mali-t860"; + reg = <0x0 0xff9a0000 0x0 0x10000>; + interrupts = , + , + ; + interrupt-names = "gpu", "job", "mmu"; + clocks = <&cru ACLK_GPU>; + power-domains = <&power RK3399_PD_GPU>; status = "disabled"; }; @@ -1786,7 +2060,7 @@ <4 RK_PB5 RK_FUNC_1 &pcfg_pull_up>; }; - sdmmc_cd: sdmcc-cd { + sdmmc_cd: sdmmc-cd { rockchip,pins = <0 RK_PA7 RK_FUNC_1 &pcfg_pull_up>; }; @@ -2090,16 +2364,6 @@ }; pcie { - pcie_clkreqn: pci-clkreqn { - rockchip,pins = - <2 26 RK_FUNC_2 &pcfg_pull_none>; - }; - - pcie_clkreqnb: pci-clkreqnb { - rockchip,pins = - <4 24 RK_FUNC_1 &pcfg_pull_none>; - }; - pcie_clkreqn_cpm: pci-clkreqn-cpm { rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile index 4a13a3a971010e7c09f7919b6dacc796c1e3efa4..4bc091b365fd1563999c5dc4fd62f16e64acce80 100644 --- a/arch/arm64/boot/dts/socionext/Makefile +++ b/arch/arm64/boot/dts/socionext/Makefile @@ -2,7 +2,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ld11-global.dtb \ uniphier-ld11-ref.dtb \ uniphier-ld20-global.dtb \ - uniphier-ld20-ref.dtb + uniphier-ld20-ref.dtb \ + uniphier-pxs3-ref.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts index 115357018ef7c73b81c20901badfbab4da71b243..2452b2243f42465476b65891d6a0df6bc5ffda37 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "uniphier-ld11.dtsi" +#include "uniphier-ld11.dtsi" / { model = "UniPhier LD11 Global Board (REF_LD11_GP)"; @@ -68,3 +68,7 @@ &usb2 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts index cc8ebe34c27cd35e131e7a05f66a5c5a63dca7e4..ffb473ad2e0fdbad76e43e50ddcaf3eb32f30c72 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld11.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld11.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD11 Reference Board"; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi index bdce5b89baece0b53738deb8ff76c18f142f986b..ee4aff53a5f5dc8063bf0779e23da47fe5f4e522 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi @@ -150,6 +150,17 @@ clocks = <&peri_clk 3>; }; + adamv@57920000 { + compatible = "socionext,uniphier-ld11-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld11-adamv-reset"; + #reset-cells = <1>; + }; + }; + i2c0: i2c@58780000 { compatible = "socionext,uniphier-fi2c"; status = "disabled"; @@ -344,6 +355,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-ld11-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gic: interrupt-controller@5fe00000 { compatible = "arm,gic-v3"; reg = <0x5fe00000 0x10000>, /* GICD */ @@ -367,8 +385,23 @@ compatible = "socionext,uniphier-ld11-reset"; #reset-cells = <1>; }; + + watchdog { + compatible = "socionext,uniphier-wdt"; + }; + }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts index 9f620d4101b54fa0a1d2aecee398813598891c41..fc2bc9d75d35e6f410a6f012b461cdcac03d6282 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "uniphier-ld20.dtsi" +#include "uniphier-ld20.dtsi" / { model = "UniPhier LD20 Global Board (REF_LD20_GP)"; @@ -50,3 +50,7 @@ &i2c0 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts index 494166aee24ce3c304045075c1a0938f6fdf43f2..1ca0c8620dc5ac33118a72beb5b586ab8ff0ce2f 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld20.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld20.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD20 Reference Board"; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi index de1e7536281718f59617bc3b7be83c7e9ea53ace..a29c279b6e8e4c484b14c77047d1b8436103f6b3 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi @@ -219,6 +219,17 @@ clocks = <&peri_clk 3>; }; + adamv@57920000 { + compatible = "socionext,uniphier-ld20-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld20-adamv-reset"; + #reset-cells = <1>; + }; + }; + i2c0: i2c@58780000 { compatible = "socionext,uniphier-fi2c"; status = "disabled"; @@ -309,7 +320,7 @@ sdctrl@59810000 { compatible = "socionext,uniphier-ld20-sdctrl", "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; + reg = <0x59810000 0x400>; sd_clk: clock { compatible = "socionext,uniphier-ld20-sd-clock"; @@ -365,6 +376,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-ld20-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gic: interrupt-controller@5fe00000 { compatible = "arm,gic-v3"; reg = <0x5fe00000 0x10000>, /* GICD */ @@ -388,8 +406,23 @@ compatible = "socionext,uniphier-ld20-reset"; #reset-cells = <1>; }; + + watchdog { + compatible = "socionext,uniphier-wdt"; + }; + }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi deleted file mode 120000 index f42fb6f38bd35ae90d23fa1b10edabb0a6ef35df..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/uniphier-pinctrl.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..9caabbb8bae3fdd1d1e17ad8d63b99979aef971d --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts new file mode 100644 index 0000000000000000000000000000000000000000..d65f746a3f9d7843761f057840786236fc8a3abd --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts @@ -0,0 +1,62 @@ +/* + * Device Tree Source for UniPhier PXs3 Reference Board + * + * Copyright (C) 2017 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include "uniphier-pxs3.dtsi" +#include "uniphier-support-card.dtsi" + +/ { + model = "UniPhier PXs3 Reference Board"; + compatible = "socionext,uniphier-pxs3-ref", "socionext,uniphier-pxs3"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c6 = &i2c6; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0xa0000000>; + }; +}; + +ðsc { + interrupts = <0 52 4>; +}; + +&serial0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..384729fa740f0b3b8863e1c7c47ddfe50fb9160c --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi @@ -0,0 +1,367 @@ +/* + * Device Tree Source for UniPhier PXs3 SoC + * + * Copyright (C) 2017 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/memreserve/ 0x80000000 0x02000000; + +/ { + compatible = "socionext,uniphier-pxs3"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x000>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x001>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x002>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x003>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + }; + + cluster0_opp: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + clock-latency-ns = <300>; + }; + opp-325000000 { + opp-hz = /bits/ 64 <325000000>; + clock-latency-ns = <300>; + }; + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + clock-latency-ns = <300>; + }; + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + clock-latency-ns = <300>; + }; + opp-666667000 { + opp-hz = /bits/ 64 <666667000>; + clock-latency-ns = <300>; + }; + opp-866667000 { + opp-hz = /bits/ 64 <866667000>; + clock-latency-ns = <300>; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + clock-latency-ns = <300>; + }; + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + clock-latency-ns = <300>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + clocks { + refclk: ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 4>, + <1 14 4>, + <1 11 4>, + <1 10 4>; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + + serial0: serial@54006800 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006800 0x40>; + interrupts = <0 33 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + clocks = <&peri_clk 0>; + }; + + serial1: serial@54006900 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006900 0x40>; + interrupts = <0 35 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + clocks = <&peri_clk 1>; + }; + + serial2: serial@54006a00 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006a00 0x40>; + interrupts = <0 37 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + clocks = <&peri_clk 2>; + }; + + serial3: serial@54006b00 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006b00 0x40>; + interrupts = <0 177 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + clocks = <&peri_clk 3>; + }; + + i2c0: i2c@58780000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58780000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 41 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0>; + clocks = <&peri_clk 4>; + clock-frequency = <100000>; + }; + + i2c1: i2c@58781000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58781000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 42 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + clocks = <&peri_clk 5>; + clock-frequency = <100000>; + }; + + i2c2: i2c@58782000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58782000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 43 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clocks = <&peri_clk 6>; + clock-frequency = <100000>; + }; + + i2c3: i2c@58783000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58783000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 44 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clocks = <&peri_clk 7>; + clock-frequency = <100000>; + }; + + /* chip-internal connection for HDMI */ + i2c6: i2c@58786000 { + compatible = "socionext,uniphier-fi2c"; + reg = <0x58786000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 26 4>; + clocks = <&peri_clk 10>; + clock-frequency = <400000>; + }; + + system_bus: system-bus@58c00000 { + compatible = "socionext,uniphier-system-bus"; + status = "disabled"; + reg = <0x58c00000 0x400>; + #address-cells = <2>; + #size-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_system_bus>; + }; + + smpctrl@59801000 { + compatible = "socionext,uniphier-smpctrl"; + reg = <0x59801000 0x400>; + }; + + sdctrl@59810000 { + compatible = "socionext,uniphier-pxs3-sdctrl", + "simple-mfd", "syscon"; + reg = <0x59810000 0x400>; + + sd_clk: clock { + compatible = "socionext,uniphier-pxs3-sd-clock"; + #clock-cells = <1>; + }; + + sd_rst: reset { + compatible = "socionext,uniphier-pxs3-sd-reset"; + #reset-cells = <1>; + }; + }; + + perictrl@59820000 { + compatible = "socionext,uniphier-pxs3-perictrl", + "simple-mfd", "syscon"; + reg = <0x59820000 0x200>; + + peri_clk: clock { + compatible = "socionext,uniphier-pxs3-peri-clock"; + #clock-cells = <1>; + }; + + peri_rst: reset { + compatible = "socionext,uniphier-pxs3-peri-reset"; + #reset-cells = <1>; + }; + }; + + emmc: sdhc@5a000000 { + compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc"; + reg = <0x5a000000 0x400>; + interrupts = <0 78 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emmc>; + clocks = <&sys_clk 4>; + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + cdns,phy-input-delay-legacy = <4>; + cdns,phy-input-delay-mmc-highspeed = <2>; + cdns,phy-input-delay-mmc-ddr = <3>; + cdns,phy-dll-delay-sdclk = <21>; + cdns,phy-dll-delay-sdclk-hsmmc = <21>; + }; + + soc-glue@5f800000 { + compatible = "socionext,uniphier-pxs3-soc-glue", + "simple-mfd", "syscon"; + reg = <0x5f800000 0x2000>; + + pinctrl: pinctrl { + compatible = "socionext,uniphier-pxs3-pinctrl"; + }; + }; + + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pxs3-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gic: interrupt-controller@5fe00000 { + compatible = "arm,gic-v3"; + reg = <0x5fe00000 0x10000>, /* GICD */ + <0x5fe80000 0x80000>; /* GICR */ + interrupt-controller; + #interrupt-cells = <3>; + interrupts = <1 9 4>; + }; + + sysctrl@61840000 { + compatible = "socionext,uniphier-pxs3-sysctrl", + "simple-mfd", "syscon"; + reg = <0x61840000 0x10000>; + + sys_clk: clock { + compatible = "socionext,uniphier-pxs3-clock"; + #clock-cells = <1>; + }; + + sys_rst: reset { + compatible = "socionext,uniphier-pxs3-reset"; + #reset-cells = <1>; + }; + + watchdog { + compatible = "socionext,uniphier-wdt"; + }; + }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; + }; + }; +}; + +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi deleted file mode 120000 index 4685a8d89cba2b56bcdc24e399c79a850d799491..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/uniphier-ref-daughter.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..e66d999d9f5d3a1ab87fc398ef611ef4cf048be2 --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi deleted file mode 120000 index 1246db9be2a1914221d74871b1e6f303884731c6..0000000000000000000000000000000000000000 --- a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/uniphier-support-card.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..28c5b4ed1d9500fb283876ba766d826a81c44a8d --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi index cdc6a437dcc73d33c0aaedb28df523cda333891a..b87b8316f4acaecab6e5a243f2cce8ae2f1c7d31 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi @@ -11,7 +11,7 @@ * the License, or (at your option) any later version. */ -&amba { +/ { misc_clk: misc_clk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -29,12 +29,60 @@ #clock-cells = <0>; clock-frequency = <75000000>; }; + + clk100: clk100 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + clk600: clk600 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <600000000>; + }; }; &can0 { clocks = <&misc_clk &misc_clk>; }; +&can1 { + clocks = <&misc_clk &misc_clk>; +}; + +&fpd_dma_chan1 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan2 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan3 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan4 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan5 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan6 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan7 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan8 { + clocks = <&clk600>, <&clk100>; +}; + &gem0 { clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts index ef1b9e573af0f5bd2ed6792ba5c9450a64ecaa45..bf552674a834140c0d574fe8b2fd3b0613c17798 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts @@ -13,13 +13,15 @@ /dts-v1/; -/include/ "zynqmp.dtsi" -/include/ "zynqmp-ep108-clk.dtsi" +#include "zynqmp.dtsi" +#include "zynqmp-ep108-clk.dtsi" / { model = "ZynqMP EP108"; aliases { + mmc0 = &sdhci0; + mmc1 = &sdhci1; serial0 = &uart0; }; @@ -37,6 +39,10 @@ status = "okay"; }; +&can1 { + status = "okay"; +}; + &gem0 { status = "okay"; phy-handle = <&phy0>; @@ -55,7 +61,7 @@ status = "okay"; clock-frequency = <400000>; eeprom@54 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x54>; }; }; @@ -64,7 +70,7 @@ status = "okay"; clock-frequency = <400000>; eeprom@55 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x55>; }; }; @@ -92,7 +98,7 @@ spi-max-frequency = <50000000>; reg = <0>; - spi0_flash0@00000000 { + spi0_flash0@0 { label = "spi0_flash0"; reg = <0x0 0x100000>; }; @@ -109,7 +115,7 @@ spi-max-frequency = <50000000>; reg = <0>; - spi1_flash0@00000000 { + spi1_flash0@0 { label = "spi1_flash0"; reg = <0x0 0x100000>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 54dc28351c8cb85a0abbd4bbad554d56dbcbac79..7665fbddff280fcb4be412470e551d9409d1575e 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -20,33 +20,84 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu0: cpu@0 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table>; reg = <0x0>; + cpu-idle-states = <&CPU_SLEEP_0>; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; }; - cpu@2 { + cpu2: cpu@2 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x2>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; }; - cpu@3 { + cpu3: cpu@3 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x3>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; }; + + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x40000000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <600>; + min-residency-us = <10000>; + }; + }; + }; + + cpu_opp_table: cpu_opp_table { + compatible = "operating-points-v2"; + opp-shared; + opp00 { + opp-hz = /bits/ 64 <1199999988>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp01 { + opp-hz = /bits/ 64 <599999994>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp02 { + opp-hz = /bits/ 64 <399999996>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp03 { + opp-hz = /bits/ 64 <299999997>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; }; pmu { @@ -119,6 +170,190 @@ rx-fifo-depth = <0x40>; }; + cci: cci@fd6e0000 { + compatible = "arm,cci-400"; + reg = <0x0 0xfd6e0000 0x0 0x9000>; + ranges = <0x0 0x0 0xfd6e0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + pmu@9000 { + compatible = "arm,cci-400-pmu,r1"; + reg = <0x9000 0x5000>; + interrupt-parent = <&gic>; + interrupts = <0 123 4>, + <0 123 4>, + <0 123 4>, + <0 123 4>, + <0 123 4>; + }; + }; + + /* GDMA */ + fpd_dma_chan1: dma@fd500000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd500000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 124 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan2: dma@fd510000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd510000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 125 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan3: dma@fd520000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd520000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 126 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan4: dma@fd530000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd530000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 127 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan5: dma@fd540000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd540000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 128 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan6: dma@fd550000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd550000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 129 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan7: dma@fd560000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd560000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 130 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan8: dma@fd570000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd570000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 131 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + /* LPDDMA default allows only secured access. inorder to enable + * These dma channels, Users should ensure that these dma + * Channels are allowed for non secure access. + */ + lpd_dma_chan1: dma@ffa80000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffa80000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 77 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan2: dma@ffa90000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffa90000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 78 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan3: dma@ffaa0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffaa0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 79 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan4: dma@ffab0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffab0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 80 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan5: dma@ffac0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffac0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 81 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan6: dma@ffad0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffad0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 82 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan7: dma@ffae0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffae0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 83 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan8: dma@ffaf0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffaf0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 84 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + gem0: ethernet@ff0b0000 { compatible = "cdns,gem"; status = "disabled"; @@ -215,12 +450,9 @@ <0x0 0xfd480000 0x0 0x1000>, <0x80 0x00000000 0x0 0x1000000>; reg-names = "breg", "pcireg", "cfg"; - ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 - 0xe0000000 0x00000000 0x10000000 - /* non-prefetchable memory */ - 0x43000000 0x00000006 0x00000000 0x00000006 - 0x00000000 0x00000002 0x00000000>; - /* prefetchable memory */ + ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000 /* non-prefetchable memory */ + 0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */ + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>, <0x0 0x0 0x0 0x2 &pcie_intc 0x2>, @@ -233,6 +465,16 @@ }; }; + rtc: rtc@ffa60000 { + compatible = "xlnx,zynqmp-rtc"; + status = "disabled"; + reg = <0x0 0xffa60000 0x0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 26 4>, <0 27 4>; + interrupt-names = "alarm", "sec"; + calibration = <0x8000>; + }; + sata: ahci@fd0c0000 { compatible = "ceva,ahci-1v84"; status = "disabled"; @@ -262,13 +504,14 @@ smmu: smmu@fd800000 { compatible = "arm,mmu-500"; reg = <0x0 0xfd800000 0x0 0x20000>; + status = "disabled"; #global-interrupts = <1>; interrupt-parent = <&gic>; - interrupts = <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>; + interrupts = <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>; }; spi0: spi@ff040000 { @@ -330,7 +573,7 @@ }; uart0: serial@ff000000 { - compatible = "cdns,uart-r1p8"; + compatible = "cdns,uart-r1p12", "xlnx,xuartps"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 21 4>; @@ -339,7 +582,7 @@ }; uart1: serial@ff010000 { - compatible = "cdns,uart-r1p8"; + compatible = "cdns,uart-r1p12", "xlnx,xuartps"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 22 4>; diff --git a/arch/arm64/boot/dts/zte/Makefile b/arch/arm64/boot/dts/zte/Makefile index 667806620f59273bf0720e121cc033bc2fc235c7..d86c4def6bc98ebac49c49b23d7294b59cf9da07 100644 --- a/arch/arm64/boot/dts/zte/Makefile +++ b/arch/arm64/boot/dts/zte/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_ZX) += zx296718-evb.dtb +dtb-$(CONFIG_ARCH_ZX) += zx296718-pcbox.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/zte/zx296718-evb.dts b/arch/arm64/boot/dts/zte/zx296718-evb.dts index bb900d2bbcfb5e6b9ca88187fc491142f359ed31..cb2519ecd724b526ff7f342b385d026f4c5808c0 100644 --- a/arch/arm64/boot/dts/zte/zx296718-evb.dts +++ b/arch/arm64/boot/dts/zte/zx296718-evb.dts @@ -57,16 +57,28 @@ reg = <0x40000000 0x40000000>; }; - sound0 { - compatible = "simple-audio-card"; - simple-audio-card,name = "zx_snd_spdif0"; + sound-spdif0 { + compatible = "audio-graph-card"; + dais = <&spdif0_port>; + }; - simple-audio-card,cpu { - sound-dai = <&spdif0>; - }; + sound-i2s0 { + compatible = "audio-graph-card"; + dais = <&i2s0_port>; + pinctrl-names = "default"; + pinctrl-0 = <&lifier_pins>; + pa-gpios = <&bgpio4 0 GPIO_ACTIVE_HIGH>; + widgets = "Line", "Line Out Jack"; + routing = "Amplifier", "LINEOUTL", + "Amplifier", "LINEOUTR", + "Line Out Jack", "Amplifier"; + }; +}; - simple-audio-card,codec { - sound-dai = <&hdmi>; +&aud96p22 { + port { + aud96p22_endpoint: endpoint { + remote-endpoint = <&i2s0_endpoint>; }; }; }; @@ -77,6 +89,36 @@ &hdmi { status = "okay"; + + port { + hdmi_endpoint: endpoint { + remote-endpoint = <&spdif0_endpoint>; + }; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2s0 { + status = "okay"; + + i2s0_port: port { + i2s0_endpoint: endpoint { + remote-endpoint = <&aud96p22_endpoint>; + dai-format = "i2s"; + frame-master; + bitclock-master; + }; + }; +}; + +&pmm { + amplifier_pins: amplifier { + pins = "TSI3_DATA"; + function = "BGPIO"; + }; }; &sd1 { @@ -85,6 +127,16 @@ &spdif0 { status = "okay"; + + spdif0_port: port { + spdif0_endpoint: endpoint { + remote-endpoint = <&hdmi_endpoint>; + }; + }; +}; + +&tvenc { + status = "okay"; }; &uart0 { diff --git a/arch/arm64/boot/dts/zte/zx296718-pcbox.dts b/arch/arm64/boot/dts/zte/zx296718-pcbox.dts new file mode 100644 index 0000000000000000000000000000000000000000..e02509f7082b1d69ac918e4145b43c6dc598523d --- /dev/null +++ b/arch/arm64/boot/dts/zte/zx296718-pcbox.dts @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2017 Sanechips Technology Co., Ltd. + * Copyright 2017 Linaro Ltd. + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include "zx296718.dtsi" +#include + +/ { + model = "ZTE ZX296718 PCBOX Board"; + compatible = "zte,zx296718-pcbox", "zte,zx296718"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + a53_vdd0v9: regulator-a53 { + compatible = "pwm-regulator"; + pwms = <&pwm 3 1250 PWM_POLARITY_INVERTED>; + regulator-name = "A53_VDD0V9"; + regulator-min-microvolt = <855000>; + regulator-max-microvolt = <1183000>; + pwm-dutycycle-unit = <100>; + pwm-dutycycle-range = <0 100>; + regulator-always-on; + regulator-boot-on; + }; + + sound-spdif0 { + compatible = "audio-graph-card"; + dais = <&spdif0_port>; + }; + + sound-i2s0 { + compatible = "audio-graph-card"; + dais = <&i2s0_port>; + }; +}; + +&aud96p22 { + port { + aud96p22_endpoint: endpoint { + remote-endpoint = <&i2s0_endpoint>; + }; + }; +}; + +&cpu0 { + cpu-supply = <&a53_vdd0v9>; +}; + +&emmc { + status = "okay"; +}; + +&hdmi { + status = "disabled"; + + port { + hdmi_endpoint: endpoint { + remote-endpoint = <&spdif0_endpoint>; + }; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2s0 { + status = "okay"; + + i2s0_port: port { + i2s0_endpoint: endpoint { + remote-endpoint = <&aud96p22_endpoint>; + dai-format = "i2s"; + frame-master; + bitclock-master; + }; + }; +}; + +&irdec { + status = "okay"; +}; + +&pmm { + pwm3_pins: pwm3 { + pins = "KEY_ROW2"; + function = "PWM"; + }; + + vga_pins: vga { + pins = "KEY_COL1", "KEY_COL2", "VGA_HS", "VGA_VS"; + function = "VGA"; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pins>; + status = "okay"; +}; + +&sd0 { + status = "okay"; +}; + +&sd1 { + status = "okay"; +}; + +&spdif0 { + status = "okay"; + + spdif0_port: port { + spdif0_endpoint: endpoint { + remote-endpoint = <&hdmi_endpoint>; + }; + }; +}; + +&tvenc { + status = "disabled"; +}; + +&uart0 { + status = "okay"; +}; + +&vga { + pinctrl-names = "default"; + pinctrl-0 = <&vga_pins>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi index d83bf789c8641b73f9c973e7aa0e1bdb41a62017..6eef64761009491ba768fa69919497e24d14f384 100644 --- a/arch/arm64/boot/dts/zte/zx296718.dtsi +++ b/arch/arm64/boot/dts/zte/zx296718.dtsi @@ -53,6 +53,13 @@ interrupt-parent = <&gic>; aliases { + gpio0 = &bgpio0; + gpio1 = &bgpio1; + gpio2 = &bgpio2; + gpio3 = &bgpio3; + gpio4 = &bgpio4; + gpio5 = &bgpio5; + gpio6 = &bgpio6; serial0 = &uart0; }; @@ -120,26 +127,31 @@ opp-500000000 { opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <866000>; clock-latency-ns = <500000>; }; opp-648000000 { opp-hz = /bits/ 64 <648000000>; + opp-microvolt = <866000>; clock-latency-ns = <500000>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <888000>; clock-latency-ns = <500000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <898000>; clock-latency-ns = <500000>; }; opp-1188000000 { opp-hz = /bits/ 64 <1188000000>; + opp-microvolt = <1015000>; clock-latency-ns = <500000>; }; }; @@ -283,11 +295,23 @@ compatible = "simple-bus"; ranges; + irdec: ir-decoder@111000 { + compatible = "zte,zx296718-irdec"; + reg = <0x111000 0x1000>; + interrupts = ; + status = "disabled"; + }; + aon_sysctrl: aon-sysctrl@116000 { compatible = "zte,zx296718-aon-sysctrl", "syscon"; reg = <0x116000 0x1000>; }; + iocfg: pin-controller@119000 { + compatible = "zte,zx296718-iocfg"; + reg = <0x119000 0x1000>; + }; + uart0: uart@11f000 { compatible = "arm,pl011", "arm,primecell"; arm,primecell-periphid = <0x001feffe>; @@ -311,7 +335,6 @@ clock-frequency = <50000000>; clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>; clock-names = "biu", "ciu"; - num-slots = <1>; max-frequency = <50000000>; cap-sdio-irq; cap-sd-highspeed; @@ -336,7 +359,6 @@ clock-frequency = <167000000>; clocks = <&topcrm SD1_AHB>, <&topcrm SD1_WCLK>; clock-names = "biu", "ciu"; - num-slots = <1>; max-frequency = <167000000>; cap-sdio-irq; cap-sd-highspeed; @@ -360,12 +382,109 @@ #clock-cells = <1>; }; + bgpio0: gpio@142d000 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d000 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 48 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio1: gpio@142d040 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d040 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 80 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio2: gpio@142d080 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d080 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 80 3 + &pmm 3 32 4 + &pmm 7 83 9>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio3: gpio@142d0c0 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d0c0 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 92 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio4: gpio@142d100 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d100 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 108 12 + &pmm 12 121 4>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio5: gpio@142d140 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d140 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 125 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio6: gpio@142d180 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d180 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 141 2>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + lsp1crm: clock-controller@1430000 { compatible = "zte,zx296718-lsp1crm"; reg = <0x01430000 0x1000>; #clock-cells = <1>; }; + pwm: pwm@1439000 { + compatible = "zte,zx296718-pwm"; + reg = <0x1439000 0x1000>; + clocks = <&lsp1crm LSP1_PWM_PCLK>, + <&lsp1crm LSP1_PWM_WCLK>; + clock-names = "pclk", "wclk"; + #pwm-cells = <3>; + status = "disabled"; + }; + vou: vou@1440000 { compatible = "zte,zx296718-vou"; #address-cells = <1>; @@ -387,6 +506,16 @@ "main_wclk", "aux_wclk"; }; + vga: vga@8000 { + compatible = "zte,zx296718-vga"; + reg = <0x8000 0x1000>; + interrupts = ; + clocks = <&topcrm VGA_I2C_WCLK>; + clock-names = "i2c_wclk"; + zte,vga-power-control = <&sysctrl 0x170 0xe0>; + status = "disabled"; + }; + hdmi: hdmi@c000 { compatible = "zte,zx296718-hdmi"; reg = <0xc000 0x4000>; @@ -413,6 +542,12 @@ #clock-cells = <1>; }; + pmm: pin-controller@1462000 { + compatible = "zte,zx296718-pmm"; + reg = <0x1462000 0x1000>; + zte,auxiliary-controller = <&iocfg>; + }; + sysctrl: sysctrl@1463000 { compatible = "zte,zx296718-sysctrl", "syscon"; reg = <0x1463000 0x1000>; @@ -445,6 +580,38 @@ #clock-cells = <1>; }; + i2s0: i2s@1482000 { + compatible = "zte,zx296718-i2s", "zte,zx296702-i2s"; + reg = <0x01482000 0x1000>; + clocks = <&audiocrm AUDIO_I2S0_WCLK>, + <&audiocrm AUDIO_I2S0_PCLK>; + clock-names = "wclk", "pclk"; + assigned-clocks = <&audiocrm I2S0_WCLK_MUX>; + assigned-clock-parents = <&topcrm AUDIO_99M>; + interrupts = ; + dmas = <&dma 22>, <&dma 23>; + dma-names = "tx", "rx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2c0: i2c@1486000 { + compatible = "zte,zx296718-i2c"; + reg = <0x01486000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&audiocrm AUDIO_I2C0_WCLK>; + clock-frequency = <1600000>; + status = "disabled"; + + aud96p22: codec@22 { + compatible = "zte,zx-aud96p22"; + #sound-dai-cells = <0>; + reg = <0x22>; + }; + }; + spdif0: spdif@1488000 { compatible = "zte,zx296702-spdif"; reg = <0x1488000 0x1000>; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 6c7d147eed54de4cc19678ce8f318987406b0521..34480e9af2e71d4ae8dfe694b3f2a918d3d9872b 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -68,6 +69,7 @@ CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_PCI_LAYERSCAPE=y CONFIG_PCI_HISI=y CONFIG_PCIE_QCOM=y +CONFIG_PCIE_KIRIN=y CONFIG_PCIE_ARMADA_8K=y CONFIG_PCI_AARDVARK=y CONFIG_PCIE_RCAR=y @@ -88,6 +90,7 @@ CONFIG_XEN=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_HIBERNATION=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y CONFIG_CPUFREQ_DT=y @@ -164,6 +167,7 @@ CONFIG_EEPROM_AT25=m CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y +CONFIG_SCSI_HISI_SAS_PCI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y @@ -203,6 +207,7 @@ CONFIG_MARVELL_PHY=m CONFIG_MESON_GXL_PHY=m CONFIG_MICREL_PHY=y CONFIG_REALTEK_PHY=m +CONFIG_ROCKCHIP_PHY=y CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m @@ -250,6 +255,8 @@ CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_SERIAL_MVEBU_UART=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y CONFIG_VIRTIO_CONSOLE=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y @@ -279,6 +286,7 @@ CONFIG_SPI_ROCKCHIP=y CONFIG_SPI_S3C64XX=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y +CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_MSM8916=y @@ -297,6 +305,7 @@ CONFIG_GPIO_MAX77620=y CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y +CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_BQ27XXX=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m @@ -304,6 +313,7 @@ CONFIG_SENSORS_INA2XX=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y CONFIG_THERMAL_EMULATION=y +CONFIG_BRCMSTB_THERMAL=m CONFIG_EXYNOS_THERMAL=y CONFIG_ROCKCHIP_THERMAL=m CONFIG_WATCHDOG=y @@ -311,19 +321,24 @@ CONFIG_S3C2410_WATCHDOG=y CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_WATCHDOG=m CONFIG_RENESAS_WDT=y +CONFIG_UNIPHIER_WATCHDOG=y CONFIG_BCM2835_WDT=y +CONFIG_MFD_AXP20X_RSB=y CONFIG_MFD_CROS_EC=y CONFIG_MFD_CROS_EC_I2C=y CONFIG_MFD_CROS_EC_SPI=y CONFIG_MFD_EXYNOS_LPASS=m +CONFIG_MFD_HI6421_PMIC=y CONFIG_MFD_HI655X_PMIC=y CONFIG_MFD_MAX77620=y CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y +CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y CONFIG_REGULATOR_HI655X=y CONFIG_REGULATOR_MAX77620=y CONFIG_REGULATOR_PWM=y @@ -358,6 +373,12 @@ CONFIG_DRM_EXYNOS_DSI=y # CONFIG_DRM_EXYNOS_DP is not set CONFIG_DRM_EXYNOS_HDMI=y CONFIG_DRM_EXYNOS_MIC=y +CONFIG_DRM_ROCKCHIP=m +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_CDN_DP=y +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_DRM_RCAR_DU=m CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_RCAR_VSP=y @@ -370,6 +391,7 @@ CONFIG_DRM_MESON=m CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_BACKLIGHT_GENERIC=m +CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_LP855X=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y @@ -380,8 +402,8 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_SOC_SAMSUNG=y -CONFIG_SND_SOC_RCAR=y -CONFIG_SND_SOC_AK4613=y +CONFIG_SND_SOC_RCAR=m +CONFIG_SND_SOC_AK4613=m CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_OTG=y @@ -403,6 +425,7 @@ CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y CONFIG_USB_HSIC_USB3503=y +CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_OTG=y CONFIG_USB_QCOM_8X16_PHY=y CONFIG_USB_ULPI=y @@ -451,6 +474,7 @@ CONFIG_RTC_DRV_TEGRA=y CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y CONFIG_DMA_BCM2835=m +CONFIG_K3_DMA=y CONFIG_MV_XOR_V2=y CONFIG_PL330_DMA=y CONFIG_TEGRA20_APB_DMA=y @@ -473,14 +497,17 @@ CONFIG_CLK_QORIQ=y CONFIG_COMMON_CLK_PWM=y CONFIG_COMMON_CLK_QCOM=y CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_IPQ_GCC_8074=y CONFIG_MSM_GCC_8916=y CONFIG_MSM_GCC_8994=y CONFIG_MSM_MMCC_8996=y +CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y CONFIG_ARM_MHU=y CONFIG_PLATFORM_MHU=y CONFIG_BCM2835_MBOX=y CONFIG_HI6220_MBOX=y +CONFIG_ROCKCHIP_IOMMU=y CONFIG_ARM_SMMU=y CONFIG_ARM_SMMU_V3=y CONFIG_RPMSG_QCOM_SMD=y @@ -514,6 +541,8 @@ CONFIG_PHY_XGENE=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_QCOM_L2_PMU=y CONFIG_QCOM_L3_PMU=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EFI_CAPSULE_LOADER=y @@ -562,8 +591,17 @@ CONFIG_SECURITY=y CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA256_ARM64=m +CONFIG_CRYPTO_SHA512_ARM64=m CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m +CONFIG_CRYPTO_CRC32_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64=m +CONFIG_CRYPTO_AES_ARM64_CE=m CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_AES_ARM64_BS=m diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig index d92293747d63149f8101ff1290044f8283ab0b24..7ca54a76f6b9f1aabd8aaa52f313930702b718fc 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -18,18 +18,23 @@ config CRYPTO_SHA512_ARM64 config CRYPTO_SHA1_ARM64_CE tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_HASH + select CRYPTO_SHA1 config CRYPTO_SHA2_ARM64_CE tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_HASH + select CRYPTO_SHA256_ARM64 config CRYPTO_GHASH_ARM64_CE - tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + tristate "GHASH/AES-GCM using ARMv8 Crypto Extensions" + depends on KERNEL_MODE_NEON select CRYPTO_HASH + select CRYPTO_GF128MUL + select CRYPTO_AES + select CRYPTO_AES_ARM64 config CRYPTO_CRCT10DIF_ARM64_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" @@ -49,25 +54,29 @@ config CRYPTO_AES_ARM64_CE tristate "AES core cipher using ARMv8 Crypto Extensions" depends on ARM64 && KERNEL_MODE_NEON select CRYPTO_ALGAPI + select CRYPTO_AES_ARM64 config CRYPTO_AES_ARM64_CE_CCM tristate "AES in CCM mode using ARMv8 Crypto Extensions" depends on ARM64 && KERNEL_MODE_NEON select CRYPTO_ALGAPI select CRYPTO_AES_ARM64_CE + select CRYPTO_AES_ARM64 select CRYPTO_AEAD config CRYPTO_AES_ARM64_CE_BLK tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_CE + select CRYPTO_AES_ARM64 select CRYPTO_SIMD config CRYPTO_AES_ARM64_NEON_BLK tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER + select CRYPTO_AES_ARM64 select CRYPTO_AES select CRYPTO_SIMD @@ -82,6 +91,7 @@ config CRYPTO_AES_ARM64_BS depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_NEON_BLK + select CRYPTO_AES_ARM64 select CRYPTO_SIMD endif diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce-ccm-core.S index 3363560c79b7e69376ac4a50a5401456640a35af..e3a375c4cb83c383242ac6b9cc8b3247939e0947 100644 --- a/arch/arm64/crypto/aes-ce-ccm-core.S +++ b/arch/arm64/crypto/aes-ce-ccm-core.S @@ -1,7 +1,7 @@ /* * aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions * - * Copyright (C) 2013 - 2014 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -32,7 +32,7 @@ ENTRY(ce_aes_ccm_auth_data) beq 8f /* out of input? */ cbnz w8, 0b eor v0.16b, v0.16b, v1.16b -1: ld1 {v3.16b}, [x4] /* load first round key */ +1: ld1 {v3.4s}, [x4] /* load first round key */ prfm pldl1strm, [x1] cmp w5, #12 /* which key size? */ add x6, x4, #16 @@ -42,17 +42,17 @@ ENTRY(ce_aes_ccm_auth_data) mov v5.16b, v3.16b b 4f 2: mov v4.16b, v3.16b - ld1 {v5.16b}, [x6], #16 /* load 2nd round key */ + ld1 {v5.4s}, [x6], #16 /* load 2nd round key */ 3: aese v0.16b, v4.16b aesmc v0.16b, v0.16b -4: ld1 {v3.16b}, [x6], #16 /* load next round key */ +4: ld1 {v3.4s}, [x6], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b -5: ld1 {v4.16b}, [x6], #16 /* load next round key */ +5: ld1 {v4.4s}, [x6], #16 /* load next round key */ subs w7, w7, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b - ld1 {v5.16b}, [x6], #16 /* load next round key */ + ld1 {v5.4s}, [x6], #16 /* load next round key */ bpl 3b aese v0.16b, v4.16b subs w2, w2, #16 /* last data? */ @@ -90,7 +90,7 @@ ENDPROC(ce_aes_ccm_auth_data) * u32 rounds); */ ENTRY(ce_aes_ccm_final) - ld1 {v3.16b}, [x2], #16 /* load first round key */ + ld1 {v3.4s}, [x2], #16 /* load first round key */ ld1 {v0.16b}, [x0] /* load mac */ cmp w3, #12 /* which key size? */ sub w3, w3, #2 /* modified # of rounds */ @@ -100,17 +100,17 @@ ENTRY(ce_aes_ccm_final) mov v5.16b, v3.16b b 2f 0: mov v4.16b, v3.16b -1: ld1 {v5.16b}, [x2], #16 /* load next round key */ +1: ld1 {v5.4s}, [x2], #16 /* load next round key */ aese v0.16b, v4.16b aesmc v0.16b, v0.16b aese v1.16b, v4.16b aesmc v1.16b, v1.16b -2: ld1 {v3.16b}, [x2], #16 /* load next round key */ +2: ld1 {v3.4s}, [x2], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b aese v1.16b, v5.16b aesmc v1.16b, v1.16b -3: ld1 {v4.16b}, [x2], #16 /* load next round key */ +3: ld1 {v4.4s}, [x2], #16 /* load next round key */ subs w3, w3, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b @@ -137,31 +137,31 @@ CPU_LE( rev x8, x8 ) /* keep swabbed ctr in reg */ cmp w4, #12 /* which key size? */ sub w7, w4, #2 /* get modified # of rounds */ ins v1.d[1], x9 /* no carry in lower ctr */ - ld1 {v3.16b}, [x3] /* load first round key */ + ld1 {v3.4s}, [x3] /* load first round key */ add x10, x3, #16 bmi 1f bne 4f mov v5.16b, v3.16b b 3f 1: mov v4.16b, v3.16b - ld1 {v5.16b}, [x10], #16 /* load 2nd round key */ + ld1 {v5.4s}, [x10], #16 /* load 2nd round key */ 2: /* inner loop: 3 rounds, 2x interleaved */ aese v0.16b, v4.16b aesmc v0.16b, v0.16b aese v1.16b, v4.16b aesmc v1.16b, v1.16b -3: ld1 {v3.16b}, [x10], #16 /* load next round key */ +3: ld1 {v3.4s}, [x10], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b aese v1.16b, v5.16b aesmc v1.16b, v1.16b -4: ld1 {v4.16b}, [x10], #16 /* load next round key */ +4: ld1 {v4.4s}, [x10], #16 /* load next round key */ subs w7, w7, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b aese v1.16b, v3.16b aesmc v1.16b, v1.16b - ld1 {v5.16b}, [x10], #16 /* load next round key */ + ld1 {v5.4s}, [x10], #16 /* load next round key */ bpl 2b aese v0.16b, v4.16b aese v1.16b, v4.16b diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c index 6a7dbc7c83a61d75c02fbd77ba73ea890f00ae69..a1254036f2b1e0df0e3083dae606a543f914f7d3 100644 --- a/arch/arm64/crypto/aes-ce-ccm-glue.c +++ b/arch/arm64/crypto/aes-ce-ccm-glue.c @@ -1,7 +1,7 @@ /* * aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions * - * Copyright (C) 2013 - 2014 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -44,6 +45,8 @@ asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes, asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[], u32 rounds); +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); + static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key, unsigned int key_len) { @@ -103,7 +106,45 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen) return 0; } -static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) +static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[], + u32 abytes, u32 *macp, bool use_neon) +{ + if (likely(use_neon)) { + ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc, + num_rounds(key)); + } else { + if (*macp > 0 && *macp < AES_BLOCK_SIZE) { + int added = min(abytes, AES_BLOCK_SIZE - *macp); + + crypto_xor(&mac[*macp], in, added); + + *macp += added; + in += added; + abytes -= added; + } + + while (abytes > AES_BLOCK_SIZE) { + __aes_arm64_encrypt(key->key_enc, mac, mac, + num_rounds(key)); + crypto_xor(mac, in, AES_BLOCK_SIZE); + + in += AES_BLOCK_SIZE; + abytes -= AES_BLOCK_SIZE; + } + + if (abytes > 0) { + __aes_arm64_encrypt(key->key_enc, mac, mac, + num_rounds(key)); + crypto_xor(mac, in, abytes); + *macp = abytes; + } else { + *macp = 0; + } + } +} + +static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[], + bool use_neon) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead); @@ -122,8 +163,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) ltag.len = 6; } - ce_aes_ccm_auth_data(mac, (u8 *)<ag, ltag.len, &macp, ctx->key_enc, - num_rounds(ctx)); + ccm_update_mac(ctx, mac, (u8 *)<ag, ltag.len, &macp, use_neon); scatterwalk_start(&walk, req->src); do { @@ -135,8 +175,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) n = scatterwalk_clamp(&walk, len); } p = scatterwalk_map(&walk); - ce_aes_ccm_auth_data(mac, p, n, &macp, ctx->key_enc, - num_rounds(ctx)); + ccm_update_mac(ctx, mac, p, n, &macp, use_neon); len -= n; scatterwalk_unmap(p); @@ -145,6 +184,56 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) } while (len); } +static int ccm_crypt_fallback(struct skcipher_walk *walk, u8 mac[], u8 iv0[], + struct crypto_aes_ctx *ctx, bool enc) +{ + u8 buf[AES_BLOCK_SIZE]; + int err = 0; + + while (walk->nbytes) { + int blocks = walk->nbytes / AES_BLOCK_SIZE; + u32 tail = walk->nbytes % AES_BLOCK_SIZE; + u8 *dst = walk->dst.virt.addr; + u8 *src = walk->src.virt.addr; + u32 nbytes = walk->nbytes; + + if (nbytes == walk->total && tail > 0) { + blocks++; + tail = 0; + } + + do { + u32 bsize = AES_BLOCK_SIZE; + + if (nbytes < AES_BLOCK_SIZE) + bsize = nbytes; + + crypto_inc(walk->iv, AES_BLOCK_SIZE); + __aes_arm64_encrypt(ctx->key_enc, buf, walk->iv, + num_rounds(ctx)); + __aes_arm64_encrypt(ctx->key_enc, mac, mac, + num_rounds(ctx)); + if (enc) + crypto_xor(mac, src, bsize); + crypto_xor_cpy(dst, src, buf, bsize); + if (!enc) + crypto_xor(mac, dst, bsize); + dst += bsize; + src += bsize; + nbytes -= bsize; + } while (--blocks); + + err = skcipher_walk_done(walk, tail); + } + + if (!err) { + __aes_arm64_encrypt(ctx->key_enc, buf, iv0, num_rounds(ctx)); + __aes_arm64_encrypt(ctx->key_enc, mac, mac, num_rounds(ctx)); + crypto_xor(mac, buf, AES_BLOCK_SIZE); + } + return err; +} + static int ccm_encrypt(struct aead_request *req) { struct crypto_aead *aead = crypto_aead_reqtfm(req); @@ -153,39 +242,46 @@ static int ccm_encrypt(struct aead_request *req) u8 __aligned(8) mac[AES_BLOCK_SIZE]; u8 buf[AES_BLOCK_SIZE]; u32 len = req->cryptlen; + bool use_neon = may_use_simd(); int err; err = ccm_init_mac(req, mac, len); if (err) return err; - kernel_neon_begin_partial(6); + if (likely(use_neon)) + kernel_neon_begin(); if (req->assoclen) - ccm_calculate_auth_mac(req, mac); + ccm_calculate_auth_mac(req, mac, use_neon); /* preserve the original iv for the final round */ memcpy(buf, req->iv, AES_BLOCK_SIZE); err = skcipher_walk_aead_encrypt(&walk, req, true); - while (walk.nbytes) { - u32 tail = walk.nbytes % AES_BLOCK_SIZE; - - if (walk.nbytes == walk.total) - tail = 0; + if (likely(use_neon)) { + while (walk.nbytes) { + u32 tail = walk.nbytes % AES_BLOCK_SIZE; - ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr, - walk.nbytes - tail, ctx->key_enc, - num_rounds(ctx), mac, walk.iv); + if (walk.nbytes == walk.total) + tail = 0; - err = skcipher_walk_done(&walk, tail); - } - if (!err) - ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx)); + ce_aes_ccm_encrypt(walk.dst.virt.addr, + walk.src.virt.addr, + walk.nbytes - tail, ctx->key_enc, + num_rounds(ctx), mac, walk.iv); - kernel_neon_end(); + err = skcipher_walk_done(&walk, tail); + } + if (!err) + ce_aes_ccm_final(mac, buf, ctx->key_enc, + num_rounds(ctx)); + kernel_neon_end(); + } else { + err = ccm_crypt_fallback(&walk, mac, buf, ctx, true); + } if (err) return err; @@ -205,38 +301,46 @@ static int ccm_decrypt(struct aead_request *req) u8 __aligned(8) mac[AES_BLOCK_SIZE]; u8 buf[AES_BLOCK_SIZE]; u32 len = req->cryptlen - authsize; + bool use_neon = may_use_simd(); int err; err = ccm_init_mac(req, mac, len); if (err) return err; - kernel_neon_begin_partial(6); + if (likely(use_neon)) + kernel_neon_begin(); if (req->assoclen) - ccm_calculate_auth_mac(req, mac); + ccm_calculate_auth_mac(req, mac, use_neon); /* preserve the original iv for the final round */ memcpy(buf, req->iv, AES_BLOCK_SIZE); err = skcipher_walk_aead_decrypt(&walk, req, true); - while (walk.nbytes) { - u32 tail = walk.nbytes % AES_BLOCK_SIZE; + if (likely(use_neon)) { + while (walk.nbytes) { + u32 tail = walk.nbytes % AES_BLOCK_SIZE; - if (walk.nbytes == walk.total) - tail = 0; + if (walk.nbytes == walk.total) + tail = 0; - ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr, - walk.nbytes - tail, ctx->key_enc, - num_rounds(ctx), mac, walk.iv); + ce_aes_ccm_decrypt(walk.dst.virt.addr, + walk.src.virt.addr, + walk.nbytes - tail, ctx->key_enc, + num_rounds(ctx), mac, walk.iv); - err = skcipher_walk_done(&walk, tail); - } - if (!err) - ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx)); + err = skcipher_walk_done(&walk, tail); + } + if (!err) + ce_aes_ccm_final(mac, buf, ctx->key_enc, + num_rounds(ctx)); - kernel_neon_end(); + kernel_neon_end(); + } else { + err = ccm_crypt_fallback(&walk, mac, buf, ctx, false); + } if (err) return err; diff --git a/arch/arm64/crypto/aes-ce-cipher.c b/arch/arm64/crypto/aes-ce-cipher.c index 50d9fe11d0c862bbd9cdd75855bfbc0fbffcfea7..6a75cd75ed11c60f828ff96b4ed0f09c4b288c6c 100644 --- a/arch/arm64/crypto/aes-ce-cipher.c +++ b/arch/arm64/crypto/aes-ce-cipher.c @@ -1,7 +1,7 @@ /* * aes-ce-cipher.c - core AES cipher using ARMv8 Crypto Extensions * - * Copyright (C) 2013 - 2014 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,8 @@ */ #include +#include +#include #include #include #include @@ -20,6 +22,9 @@ MODULE_DESCRIPTION("Synchronous AES cipher using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); +asmlinkage void __aes_arm64_decrypt(u32 *rk, u8 *out, const u8 *in, int rounds); + struct aes_block { u8 b[AES_BLOCK_SIZE]; }; @@ -44,27 +49,32 @@ static void aes_cipher_encrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[]) void *dummy0; int dummy1; - kernel_neon_begin_partial(4); + if (!may_use_simd()) { + __aes_arm64_encrypt(ctx->key_enc, dst, src, num_rounds(ctx)); + return; + } + + kernel_neon_begin(); __asm__(" ld1 {v0.16b}, %[in] ;" - " ld1 {v1.16b}, [%[key]], #16 ;" + " ld1 {v1.4s}, [%[key]], #16 ;" " cmp %w[rounds], #10 ;" " bmi 0f ;" " bne 3f ;" " mov v3.16b, v1.16b ;" " b 2f ;" "0: mov v2.16b, v1.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" "1: aese v0.16b, v2.16b ;" " aesmc v0.16b, v0.16b ;" - "2: ld1 {v1.16b}, [%[key]], #16 ;" + "2: ld1 {v1.4s}, [%[key]], #16 ;" " aese v0.16b, v3.16b ;" " aesmc v0.16b, v0.16b ;" - "3: ld1 {v2.16b}, [%[key]], #16 ;" + "3: ld1 {v2.4s}, [%[key]], #16 ;" " subs %w[rounds], %w[rounds], #3 ;" " aese v0.16b, v1.16b ;" " aesmc v0.16b, v0.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" " bpl 1b ;" " aese v0.16b, v2.16b ;" " eor v0.16b, v0.16b, v3.16b ;" @@ -89,27 +99,32 @@ static void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[]) void *dummy0; int dummy1; - kernel_neon_begin_partial(4); + if (!may_use_simd()) { + __aes_arm64_decrypt(ctx->key_dec, dst, src, num_rounds(ctx)); + return; + } + + kernel_neon_begin(); __asm__(" ld1 {v0.16b}, %[in] ;" - " ld1 {v1.16b}, [%[key]], #16 ;" + " ld1 {v1.4s}, [%[key]], #16 ;" " cmp %w[rounds], #10 ;" " bmi 0f ;" " bne 3f ;" " mov v3.16b, v1.16b ;" " b 2f ;" "0: mov v2.16b, v1.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" "1: aesd v0.16b, v2.16b ;" " aesimc v0.16b, v0.16b ;" - "2: ld1 {v1.16b}, [%[key]], #16 ;" + "2: ld1 {v1.4s}, [%[key]], #16 ;" " aesd v0.16b, v3.16b ;" " aesimc v0.16b, v0.16b ;" - "3: ld1 {v2.16b}, [%[key]], #16 ;" + "3: ld1 {v2.4s}, [%[key]], #16 ;" " subs %w[rounds], %w[rounds], #3 ;" " aesd v0.16b, v1.16b ;" " aesimc v0.16b, v0.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" " bpl 1b ;" " aesd v0.16b, v2.16b ;" " eor v0.16b, v0.16b, v3.16b ;" @@ -165,20 +180,16 @@ int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, key_len != AES_KEYSIZE_256) return -EINVAL; - memcpy(ctx->key_enc, in_key, key_len); ctx->key_length = key_len; + for (i = 0; i < kwords; i++) + ctx->key_enc[i] = get_unaligned_le32(in_key + i * sizeof(u32)); - kernel_neon_begin_partial(2); + kernel_neon_begin(); for (i = 0; i < sizeof(rcon); i++) { u32 *rki = ctx->key_enc + (i * kwords); u32 *rko = rki + kwords; -#ifndef CONFIG_CPU_BIG_ENDIAN rko[0] = ror32(aes_sub(rki[kwords - 1]), 8) ^ rcon[i] ^ rki[0]; -#else - rko[0] = rol32(aes_sub(rki[kwords - 1]), 8) ^ (rcon[i] << 24) ^ - rki[0]; -#endif rko[1] = rko[0] ^ rki[1]; rko[2] = rko[1] ^ rki[2]; rko[3] = rko[2] ^ rki[3]; @@ -210,9 +221,9 @@ int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, key_dec[0] = key_enc[j]; for (i = 1, j--; j > 0; i++, j--) - __asm__("ld1 {v0.16b}, %[in] ;" + __asm__("ld1 {v0.4s}, %[in] ;" "aesimc v1.16b, v0.16b ;" - "st1 {v1.16b}, %[out] ;" + "st1 {v1.4s}, %[out] ;" : [out] "=Q"(key_dec[i]) : [in] "Q"(key_enc[j]) diff --git a/arch/arm64/crypto/aes-ce.S b/arch/arm64/crypto/aes-ce.S index b46093d567e5449256dbf3bf1d4981144bdd8739..50330f5c3adc4f6fcac22794ead1af1c8ca956e2 100644 --- a/arch/arm64/crypto/aes-ce.S +++ b/arch/arm64/crypto/aes-ce.S @@ -2,7 +2,7 @@ * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with * Crypto Extensions * - * Copyright (C) 2013 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,11 +22,11 @@ cmp \rounds, #12 blo 2222f /* 128 bits */ beq 1111f /* 192 bits */ - ld1 {v17.16b-v18.16b}, [\rk], #32 -1111: ld1 {v19.16b-v20.16b}, [\rk], #32 -2222: ld1 {v21.16b-v24.16b}, [\rk], #64 - ld1 {v25.16b-v28.16b}, [\rk], #64 - ld1 {v29.16b-v31.16b}, [\rk] + ld1 {v17.4s-v18.4s}, [\rk], #32 +1111: ld1 {v19.4s-v20.4s}, [\rk], #32 +2222: ld1 {v21.4s-v24.4s}, [\rk], #64 + ld1 {v25.4s-v28.4s}, [\rk], #64 + ld1 {v29.4s-v31.4s}, [\rk] .endm /* prepare for encryption with key in rk[] */ diff --git a/arch/arm64/crypto/aes-cipher-core.S b/arch/arm64/crypto/aes-cipher-core.S index f2f9cc519309c5609996c3a56d85bb5447aaf2b0..6d2445d603cc244e4cd08acf420ae8b8089e5d88 100644 --- a/arch/arm64/crypto/aes-cipher-core.S +++ b/arch/arm64/crypto/aes-cipher-core.S @@ -10,6 +10,7 @@ #include #include +#include .text @@ -17,94 +18,155 @@ out .req x1 in .req x2 rounds .req x3 - tt .req x4 - lt .req x2 + tt .req x2 - .macro __pair, enc, reg0, reg1, in0, in1e, in1d, shift + .macro __pair1, sz, op, reg0, reg1, in0, in1e, in1d, shift + .ifc \op\shift, b0 + ubfiz \reg0, \in0, #2, #8 + ubfiz \reg1, \in1e, #2, #8 + .else ubfx \reg0, \in0, #\shift, #8 - .if \enc ubfx \reg1, \in1e, #\shift, #8 - .else - ubfx \reg1, \in1d, #\shift, #8 .endif + + /* + * AArch64 cannot do byte size indexed loads from a table containing + * 32-bit quantities, i.e., 'ldrb w12, [tt, w12, uxtw #2]' is not a + * valid instruction. So perform the shift explicitly first for the + * high bytes (the low byte is shifted implicitly by using ubfiz rather + * than ubfx above) + */ + .ifnc \op, b ldr \reg0, [tt, \reg0, uxtw #2] ldr \reg1, [tt, \reg1, uxtw #2] + .else + .if \shift > 0 + lsl \reg0, \reg0, #2 + lsl \reg1, \reg1, #2 + .endif + ldrb \reg0, [tt, \reg0, uxtw] + ldrb \reg1, [tt, \reg1, uxtw] + .endif .endm - .macro __hround, out0, out1, in0, in1, in2, in3, t0, t1, enc + .macro __pair0, sz, op, reg0, reg1, in0, in1e, in1d, shift + ubfx \reg0, \in0, #\shift, #8 + ubfx \reg1, \in1d, #\shift, #8 + ldr\op \reg0, [tt, \reg0, uxtw #\sz] + ldr\op \reg1, [tt, \reg1, uxtw #\sz] + .endm + + .macro __hround, out0, out1, in0, in1, in2, in3, t0, t1, enc, sz, op ldp \out0, \out1, [rk], #8 - __pair \enc, w13, w14, \in0, \in1, \in3, 0 - __pair \enc, w15, w16, \in1, \in2, \in0, 8 - __pair \enc, w17, w18, \in2, \in3, \in1, 16 - __pair \enc, \t0, \t1, \in3, \in0, \in2, 24 - - eor \out0, \out0, w13 - eor \out1, \out1, w14 - eor \out0, \out0, w15, ror #24 - eor \out1, \out1, w16, ror #24 - eor \out0, \out0, w17, ror #16 - eor \out1, \out1, w18, ror #16 + __pair\enc \sz, \op, w12, w13, \in0, \in1, \in3, 0 + __pair\enc \sz, \op, w14, w15, \in1, \in2, \in0, 8 + __pair\enc \sz, \op, w16, w17, \in2, \in3, \in1, 16 + __pair\enc \sz, \op, \t0, \t1, \in3, \in0, \in2, 24 + + eor \out0, \out0, w12 + eor \out1, \out1, w13 + eor \out0, \out0, w14, ror #24 + eor \out1, \out1, w15, ror #24 + eor \out0, \out0, w16, ror #16 + eor \out1, \out1, w17, ror #16 eor \out0, \out0, \t0, ror #8 eor \out1, \out1, \t1, ror #8 .endm - .macro fround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1 - __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1 + .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op + __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op .endm - .macro iround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0 - __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0 + .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op + __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op .endm - .macro do_crypt, round, ttab, ltab - ldp w5, w6, [in] - ldp w7, w8, [in, #8] - ldp w9, w10, [rk], #16 - ldp w11, w12, [rk, #-8] + .macro do_crypt, round, ttab, ltab, bsz + ldp w4, w5, [in] + ldp w6, w7, [in, #8] + ldp w8, w9, [rk], #16 + ldp w10, w11, [rk, #-8] +CPU_BE( rev w4, w4 ) CPU_BE( rev w5, w5 ) CPU_BE( rev w6, w6 ) CPU_BE( rev w7, w7 ) -CPU_BE( rev w8, w8 ) + eor w4, w4, w8 eor w5, w5, w9 eor w6, w6, w10 eor w7, w7, w11 - eor w8, w8, w12 adr_l tt, \ttab - adr_l lt, \ltab tbnz rounds, #1, 1f -0: \round w9, w10, w11, w12, w5, w6, w7, w8 - \round w5, w6, w7, w8, w9, w10, w11, w12 +0: \round w8, w9, w10, w11, w4, w5, w6, w7 + \round w4, w5, w6, w7, w8, w9, w10, w11 1: subs rounds, rounds, #4 - \round w9, w10, w11, w12, w5, w6, w7, w8 - csel tt, tt, lt, hi - \round w5, w6, w7, w8, w9, w10, w11, w12 - b.hi 0b - + \round w8, w9, w10, w11, w4, w5, w6, w7 + b.ls 3f +2: \round w4, w5, w6, w7, w8, w9, w10, w11 + b 0b +3: adr_l tt, \ltab + \round w4, w5, w6, w7, w8, w9, w10, w11, \bsz, b + +CPU_BE( rev w4, w4 ) CPU_BE( rev w5, w5 ) CPU_BE( rev w6, w6 ) CPU_BE( rev w7, w7 ) -CPU_BE( rev w8, w8 ) - stp w5, w6, [out] - stp w7, w8, [out, #8] + stp w4, w5, [out] + stp w6, w7, [out, #8] ret .endm - .align 5 + .align L1_CACHE_SHIFT + .type __aes_arm64_inverse_sbox, %object +__aes_arm64_inverse_sbox: + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + .size __aes_arm64_inverse_sbox, . - __aes_arm64_inverse_sbox + ENTRY(__aes_arm64_encrypt) - do_crypt fround, crypto_ft_tab, crypto_fl_tab + do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 ENDPROC(__aes_arm64_encrypt) .align 5 ENTRY(__aes_arm64_decrypt) - do_crypt iround, crypto_it_tab, crypto_il_tab + do_crypt iround, crypto_it_tab, __aes_arm64_inverse_sbox, 0 ENDPROC(__aes_arm64_decrypt) diff --git a/arch/arm64/crypto/aes-ctr-fallback.h b/arch/arm64/crypto/aes-ctr-fallback.h new file mode 100644 index 0000000000000000000000000000000000000000..c9285717b6b5e3d86d38077436328cc62b04449c --- /dev/null +++ b/arch/arm64/crypto/aes-ctr-fallback.h @@ -0,0 +1,53 @@ +/* + * Fallback for sync aes(ctr) in contexts where kernel mode NEON + * is not allowed + * + * Copyright (C) 2017 Linaro Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); + +static inline int aes_ctr_encrypt_fallback(struct crypto_aes_ctx *ctx, + struct skcipher_request *req) +{ + struct skcipher_walk walk; + u8 buf[AES_BLOCK_SIZE]; + int err; + + err = skcipher_walk_virt(&walk, req, true); + + while (walk.nbytes > 0) { + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + int nbytes = walk.nbytes; + int tail = 0; + + if (nbytes < walk.total) { + nbytes = round_down(nbytes, AES_BLOCK_SIZE); + tail = walk.nbytes % AES_BLOCK_SIZE; + } + + do { + int bsize = min(nbytes, AES_BLOCK_SIZE); + + __aes_arm64_encrypt(ctx->key_enc, buf, walk.iv, + 6 + ctx->key_length / 4); + crypto_xor_cpy(dst, src, buf, bsize); + crypto_inc(walk.iv, AES_BLOCK_SIZE); + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + nbytes -= AES_BLOCK_SIZE; + } while (nbytes > 0); + + err = skcipher_walk_done(&walk, tail); + } + return err; +} diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index bcf596b0197ef31cfffa60e04c69cd652f5eac09..998ba519a02666d51ef518f3533b649de1c371ac 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include "aes-ce-setkey.h" +#include "aes-ctr-fallback.h" #ifdef USE_V8_CRYPTO_EXTENSIONS #define MODE "ce" @@ -241,9 +243,7 @@ static int ctr_encrypt(struct skcipher_request *req) aes_ctr_encrypt(tail, NULL, (u8 *)ctx->key_enc, rounds, blocks, walk.iv, first); - if (tdst != tsrc) - memcpy(tdst, tsrc, nbytes); - crypto_xor(tdst, tail, nbytes); + crypto_xor_cpy(tdst, tsrc, tail, nbytes); err = skcipher_walk_done(&walk, 0); } kernel_neon_end(); @@ -251,6 +251,17 @@ static int ctr_encrypt(struct skcipher_request *req) return err; } +static int ctr_encrypt_sync(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + + if (!may_use_simd()) + return aes_ctr_encrypt_fallback(ctx, req); + + return ctr_encrypt(req); +} + static int xts_encrypt(struct skcipher_request *req) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); @@ -357,8 +368,8 @@ static struct skcipher_alg aes_algs[] = { { .ivsize = AES_BLOCK_SIZE, .chunksize = AES_BLOCK_SIZE, .setkey = skcipher_aes_setkey, - .encrypt = ctr_encrypt, - .decrypt = ctr_encrypt, + .encrypt = ctr_encrypt_sync, + .decrypt = ctr_encrypt_sync, }, { .base = { .cra_name = "__xts(aes)", @@ -460,11 +471,35 @@ static int mac_init(struct shash_desc *desc) return 0; } +static void mac_do_update(struct crypto_aes_ctx *ctx, u8 const in[], int blocks, + u8 dg[], int enc_before, int enc_after) +{ + int rounds = 6 + ctx->key_length / 4; + + if (may_use_simd()) { + kernel_neon_begin(); + aes_mac_update(in, ctx->key_enc, rounds, blocks, dg, enc_before, + enc_after); + kernel_neon_end(); + } else { + if (enc_before) + __aes_arm64_encrypt(ctx->key_enc, dg, dg, rounds); + + while (blocks--) { + crypto_xor(dg, in, AES_BLOCK_SIZE); + in += AES_BLOCK_SIZE; + + if (blocks || enc_after) + __aes_arm64_encrypt(ctx->key_enc, dg, dg, + rounds); + } + } +} + static int mac_update(struct shash_desc *desc, const u8 *p, unsigned int len) { struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); struct mac_desc_ctx *ctx = shash_desc_ctx(desc); - int rounds = 6 + tctx->key.key_length / 4; while (len > 0) { unsigned int l; @@ -476,10 +511,8 @@ static int mac_update(struct shash_desc *desc, const u8 *p, unsigned int len) len %= AES_BLOCK_SIZE; - kernel_neon_begin(); - aes_mac_update(p, tctx->key.key_enc, rounds, blocks, - ctx->dg, (ctx->len != 0), (len != 0)); - kernel_neon_end(); + mac_do_update(&tctx->key, p, blocks, ctx->dg, + (ctx->len != 0), (len != 0)); p += blocks * AES_BLOCK_SIZE; @@ -507,11 +540,8 @@ static int cbcmac_final(struct shash_desc *desc, u8 *out) { struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); struct mac_desc_ctx *ctx = shash_desc_ctx(desc); - int rounds = 6 + tctx->key.key_length / 4; - kernel_neon_begin(); - aes_mac_update(NULL, tctx->key.key_enc, rounds, 0, ctx->dg, 1, 0); - kernel_neon_end(); + mac_do_update(&tctx->key, NULL, 0, ctx->dg, 1, 0); memcpy(out, ctx->dg, AES_BLOCK_SIZE); @@ -522,7 +552,6 @@ static int cmac_final(struct shash_desc *desc, u8 *out) { struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); struct mac_desc_ctx *ctx = shash_desc_ctx(desc); - int rounds = 6 + tctx->key.key_length / 4; u8 *consts = tctx->consts; if (ctx->len != AES_BLOCK_SIZE) { @@ -530,9 +559,7 @@ static int cmac_final(struct shash_desc *desc, u8 *out) consts += AES_BLOCK_SIZE; } - kernel_neon_begin(); - aes_mac_update(consts, tctx->key.key_enc, rounds, 1, ctx->dg, 0, 1); - kernel_neon_end(); + mac_do_update(&tctx->key, consts, 1, ctx->dg, 0, 1); memcpy(out, ctx->dg, AES_BLOCK_SIZE); diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c index db2501d93550c35720c3d1adeb78fed49a9df1a2..c55d68ccb89f804a7db201ae23abe49ace0a1188 100644 --- a/arch/arm64/crypto/aes-neonbs-glue.c +++ b/arch/arm64/crypto/aes-neonbs-glue.c @@ -1,7 +1,7 @@ /* * Bit sliced AES using NEON instructions * - * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2016 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,12 +9,15 @@ */ #include +#include #include #include #include #include #include +#include "aes-ctr-fallback.h" + MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); @@ -58,6 +61,11 @@ struct aesbs_cbc_ctx { u32 enc[AES_MAX_KEYLENGTH_U32]; }; +struct aesbs_ctr_ctx { + struct aesbs_ctx key; /* must be first member */ + struct crypto_aes_ctx fallback; +}; + struct aesbs_xts_ctx { struct aesbs_ctx key; u32 twkey[AES_MAX_KEYLENGTH_U32]; @@ -196,6 +204,25 @@ static int cbc_decrypt(struct skcipher_request *req) return err; } +static int aesbs_ctr_setkey_sync(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm); + int err; + + err = crypto_aes_expand_key(&ctx->fallback, in_key, key_len); + if (err) + return err; + + ctx->key.rounds = 6 + key_len / 4; + + kernel_neon_begin(); + aesbs_convert_key(ctx->key.rk, ctx->fallback.key_enc, ctx->key.rounds); + kernel_neon_end(); + + return 0; +} + static int ctr_encrypt(struct skcipher_request *req) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); @@ -224,9 +251,8 @@ static int ctr_encrypt(struct skcipher_request *req) u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; - if (dst != src) - memcpy(dst, src, walk.total % AES_BLOCK_SIZE); - crypto_xor(dst, final, walk.total % AES_BLOCK_SIZE); + crypto_xor_cpy(dst, src, final, + walk.total % AES_BLOCK_SIZE); err = skcipher_walk_done(&walk, 0); break; @@ -260,6 +286,17 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, return aesbs_setkey(tfm, in_key, key_len); } +static int ctr_encrypt_sync(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm); + + if (!may_use_simd()) + return aes_ctr_encrypt_fallback(&ctx->fallback, req); + + return ctr_encrypt(req); +} + static int __xts_crypt(struct skcipher_request *req, void (*fn)(u8 out[], u8 const in[], u8 const rk[], int rounds, int blocks, u8 iv[])) @@ -356,7 +393,7 @@ static struct skcipher_alg aes_algs[] = { { .base.cra_driver_name = "ctr-aes-neonbs", .base.cra_priority = 250 - 1, .base.cra_blocksize = 1, - .base.cra_ctxsize = sizeof(struct aesbs_ctx), + .base.cra_ctxsize = sizeof(struct aesbs_ctr_ctx), .base.cra_module = THIS_MODULE, .min_keysize = AES_MIN_KEY_SIZE, @@ -364,9 +401,9 @@ static struct skcipher_alg aes_algs[] = { { .chunksize = AES_BLOCK_SIZE, .walksize = 8 * AES_BLOCK_SIZE, .ivsize = AES_BLOCK_SIZE, - .setkey = aesbs_setkey, - .encrypt = ctr_encrypt, - .decrypt = ctr_encrypt, + .setkey = aesbs_ctr_setkey_sync, + .encrypt = ctr_encrypt_sync, + .decrypt = ctr_encrypt_sync, }, { .base.cra_name = "__xts(aes)", .base.cra_driver_name = "__xts-aes-neonbs", diff --git a/arch/arm64/crypto/chacha20-neon-glue.c b/arch/arm64/crypto/chacha20-neon-glue.c index a7cd575ea223348e6d2fa99dea5028e7202d04b6..cbdb75d15cd031596c84bdb3959f17910fea08f2 100644 --- a/arch/arm64/crypto/chacha20-neon-glue.c +++ b/arch/arm64/crypto/chacha20-neon-glue.c @@ -1,7 +1,7 @@ /* * ChaCha20 256-bit cipher algorithm, RFC7539, arm64 NEON functions * - * Copyright (C) 2016 Linaro, Ltd. + * Copyright (C) 2016 - 2017 Linaro, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,6 +26,7 @@ #include #include +#include asmlinkage void chacha20_block_xor_neon(u32 *state, u8 *dst, const u8 *src); asmlinkage void chacha20_4block_xor_neon(u32 *state, u8 *dst, const u8 *src); @@ -64,7 +65,7 @@ static int chacha20_neon(struct skcipher_request *req) u32 state[16]; int err; - if (req->cryptlen <= CHACHA20_BLOCK_SIZE) + if (!may_use_simd() || req->cryptlen <= CHACHA20_BLOCK_SIZE) return crypto_chacha20_crypt(req); err = skcipher_walk_virt(&walk, req, true); diff --git a/arch/arm64/crypto/crc32-ce-glue.c b/arch/arm64/crypto/crc32-ce-glue.c index eccb1ae90064106e43d97bcf6b22b7bee1dcc49f..624f4137918ce5563a8e57576f5e0cb5d1ea1cd9 100644 --- a/arch/arm64/crypto/crc32-ce-glue.c +++ b/arch/arm64/crypto/crc32-ce-glue.c @@ -1,7 +1,7 @@ /* * Accelerated CRC32(C) using arm64 NEON and Crypto Extensions instructions * - * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2016 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,6 +19,7 @@ #include #include +#include #include #define PMULL_MIN_LEN 64L /* minimum size of buffer @@ -105,10 +106,10 @@ static int crc32_pmull_update(struct shash_desc *desc, const u8 *data, length -= l; } - if (length >= PMULL_MIN_LEN) { + if (length >= PMULL_MIN_LEN && may_use_simd()) { l = round_down(length, SCALE_F); - kernel_neon_begin_partial(10); + kernel_neon_begin(); *crc = crc32_pmull_le(data, l, *crc); kernel_neon_end(); @@ -137,10 +138,10 @@ static int crc32c_pmull_update(struct shash_desc *desc, const u8 *data, length -= l; } - if (length >= PMULL_MIN_LEN) { + if (length >= PMULL_MIN_LEN && may_use_simd()) { l = round_down(length, SCALE_F); - kernel_neon_begin_partial(10); + kernel_neon_begin(); *crc = crc32c_pmull_le(data, l, *crc); kernel_neon_end(); diff --git a/arch/arm64/crypto/crct10dif-ce-glue.c b/arch/arm64/crypto/crct10dif-ce-glue.c index 60cb590c2590b059007ea0be23e7b4da5836f164..96f0cae4a02258bad9cf63639da45190499d1696 100644 --- a/arch/arm64/crypto/crct10dif-ce-glue.c +++ b/arch/arm64/crypto/crct10dif-ce-glue.c @@ -1,7 +1,7 @@ /* * Accelerated CRC-T10DIF using arm64 NEON and Crypto Extensions instructions * - * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2016 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -18,6 +18,7 @@ #include #include +#include #define CRC_T10DIF_PMULL_CHUNK_SIZE 16U @@ -48,9 +49,13 @@ static int crct10dif_update(struct shash_desc *desc, const u8 *data, } if (length > 0) { - kernel_neon_begin_partial(14); - *crc = crc_t10dif_pmull(*crc, data, length); - kernel_neon_end(); + if (may_use_simd()) { + kernel_neon_begin(); + *crc = crc_t10dif_pmull(*crc, data, length); + kernel_neon_end(); + } else { + *crc = crc_t10dif_generic(*crc, data, length); + } } return 0; diff --git a/arch/arm64/crypto/ghash-ce-core.S b/arch/arm64/crypto/ghash-ce-core.S index f0bb9f0b524fceb8b62ef4be45f57bee3308156e..11ebf1ae248a1b9b9ff9a61ddaa23a439b2cc359 100644 --- a/arch/arm64/crypto/ghash-ce-core.S +++ b/arch/arm64/crypto/ghash-ce-core.S @@ -1,7 +1,7 @@ /* * Accelerated GHASH implementation with ARMv8 PMULL instructions. * - * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2014 - 2017 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -11,31 +11,215 @@ #include #include - SHASH .req v0 - SHASH2 .req v1 - T1 .req v2 - T2 .req v3 - MASK .req v4 - XL .req v5 - XM .req v6 - XH .req v7 - IN1 .req v7 + SHASH .req v0 + SHASH2 .req v1 + T1 .req v2 + T2 .req v3 + MASK .req v4 + XL .req v5 + XM .req v6 + XH .req v7 + IN1 .req v7 + + k00_16 .req v8 + k32_48 .req v9 + + t3 .req v10 + t4 .req v11 + t5 .req v12 + t6 .req v13 + t7 .req v14 + t8 .req v15 + t9 .req v16 + + perm1 .req v17 + perm2 .req v18 + perm3 .req v19 + + sh1 .req v20 + sh2 .req v21 + sh3 .req v22 + sh4 .req v23 + + ss1 .req v24 + ss2 .req v25 + ss3 .req v26 + ss4 .req v27 .text .arch armv8-a+crypto - /* - * void pmull_ghash_update(int blocks, u64 dg[], const char *src, - * struct ghash_key const *k, const char *head) - */ -ENTRY(pmull_ghash_update) + .macro __pmull_p64, rd, rn, rm + pmull \rd\().1q, \rn\().1d, \rm\().1d + .endm + + .macro __pmull2_p64, rd, rn, rm + pmull2 \rd\().1q, \rn\().2d, \rm\().2d + .endm + + .macro __pmull_p8, rq, ad, bd + ext t3.8b, \ad\().8b, \ad\().8b, #1 // A1 + ext t5.8b, \ad\().8b, \ad\().8b, #2 // A2 + ext t7.8b, \ad\().8b, \ad\().8b, #3 // A3 + + __pmull_p8_\bd \rq, \ad + .endm + + .macro __pmull2_p8, rq, ad, bd + tbl t3.16b, {\ad\().16b}, perm1.16b // A1 + tbl t5.16b, {\ad\().16b}, perm2.16b // A2 + tbl t7.16b, {\ad\().16b}, perm3.16b // A3 + + __pmull2_p8_\bd \rq, \ad + .endm + + .macro __pmull_p8_SHASH, rq, ad + __pmull_p8_tail \rq, \ad\().8b, SHASH.8b, 8b,, sh1, sh2, sh3, sh4 + .endm + + .macro __pmull_p8_SHASH2, rq, ad + __pmull_p8_tail \rq, \ad\().8b, SHASH2.8b, 8b,, ss1, ss2, ss3, ss4 + .endm + + .macro __pmull2_p8_SHASH, rq, ad + __pmull_p8_tail \rq, \ad\().16b, SHASH.16b, 16b, 2, sh1, sh2, sh3, sh4 + .endm + + .macro __pmull_p8_tail, rq, ad, bd, nb, t, b1, b2, b3, b4 + pmull\t t3.8h, t3.\nb, \bd // F = A1*B + pmull\t t4.8h, \ad, \b1\().\nb // E = A*B1 + pmull\t t5.8h, t5.\nb, \bd // H = A2*B + pmull\t t6.8h, \ad, \b2\().\nb // G = A*B2 + pmull\t t7.8h, t7.\nb, \bd // J = A3*B + pmull\t t8.8h, \ad, \b3\().\nb // I = A*B3 + pmull\t t9.8h, \ad, \b4\().\nb // K = A*B4 + pmull\t \rq\().8h, \ad, \bd // D = A*B + + eor t3.16b, t3.16b, t4.16b // L = E + F + eor t5.16b, t5.16b, t6.16b // M = G + H + eor t7.16b, t7.16b, t8.16b // N = I + J + + uzp1 t4.2d, t3.2d, t5.2d + uzp2 t3.2d, t3.2d, t5.2d + uzp1 t6.2d, t7.2d, t9.2d + uzp2 t7.2d, t7.2d, t9.2d + + // t3 = (L) (P0 + P1) << 8 + // t5 = (M) (P2 + P3) << 16 + eor t4.16b, t4.16b, t3.16b + and t3.16b, t3.16b, k32_48.16b + + // t7 = (N) (P4 + P5) << 24 + // t9 = (K) (P6 + P7) << 32 + eor t6.16b, t6.16b, t7.16b + and t7.16b, t7.16b, k00_16.16b + + eor t4.16b, t4.16b, t3.16b + eor t6.16b, t6.16b, t7.16b + + zip2 t5.2d, t4.2d, t3.2d + zip1 t3.2d, t4.2d, t3.2d + zip2 t9.2d, t6.2d, t7.2d + zip1 t7.2d, t6.2d, t7.2d + + ext t3.16b, t3.16b, t3.16b, #15 + ext t5.16b, t5.16b, t5.16b, #14 + ext t7.16b, t7.16b, t7.16b, #13 + ext t9.16b, t9.16b, t9.16b, #12 + + eor t3.16b, t3.16b, t5.16b + eor t7.16b, t7.16b, t9.16b + eor \rq\().16b, \rq\().16b, t3.16b + eor \rq\().16b, \rq\().16b, t7.16b + .endm + + .macro __pmull_pre_p64 + movi MASK.16b, #0xe1 + shl MASK.2d, MASK.2d, #57 + .endm + + .macro __pmull_pre_p8 + // k00_16 := 0x0000000000000000_000000000000ffff + // k32_48 := 0x00000000ffffffff_0000ffffffffffff + movi k32_48.2d, #0xffffffff + mov k32_48.h[2], k32_48.h[0] + ushr k00_16.2d, k32_48.2d, #32 + + // prepare the permutation vectors + mov_q x5, 0x080f0e0d0c0b0a09 + movi T1.8b, #8 + dup perm1.2d, x5 + eor perm1.16b, perm1.16b, T1.16b + ushr perm2.2d, perm1.2d, #8 + ushr perm3.2d, perm1.2d, #16 + ushr T1.2d, perm1.2d, #24 + sli perm2.2d, perm1.2d, #56 + sli perm3.2d, perm1.2d, #48 + sli T1.2d, perm1.2d, #40 + + // precompute loop invariants + tbl sh1.16b, {SHASH.16b}, perm1.16b + tbl sh2.16b, {SHASH.16b}, perm2.16b + tbl sh3.16b, {SHASH.16b}, perm3.16b + tbl sh4.16b, {SHASH.16b}, T1.16b + ext ss1.8b, SHASH2.8b, SHASH2.8b, #1 + ext ss2.8b, SHASH2.8b, SHASH2.8b, #2 + ext ss3.8b, SHASH2.8b, SHASH2.8b, #3 + ext ss4.8b, SHASH2.8b, SHASH2.8b, #4 + .endm + + // + // PMULL (64x64->128) based reduction for CPUs that can do + // it in a single instruction. + // + .macro __pmull_reduce_p64 + pmull T2.1q, XL.1d, MASK.1d + eor XM.16b, XM.16b, T1.16b + + mov XH.d[0], XM.d[1] + mov XM.d[1], XL.d[0] + + eor XL.16b, XM.16b, T2.16b + ext T2.16b, XL.16b, XL.16b, #8 + pmull XL.1q, XL.1d, MASK.1d + .endm + + // + // Alternative reduction for CPUs that lack support for the + // 64x64->128 PMULL instruction + // + .macro __pmull_reduce_p8 + eor XM.16b, XM.16b, T1.16b + + mov XL.d[1], XM.d[0] + mov XH.d[0], XM.d[1] + + shl T1.2d, XL.2d, #57 + shl T2.2d, XL.2d, #62 + eor T2.16b, T2.16b, T1.16b + shl T1.2d, XL.2d, #63 + eor T2.16b, T2.16b, T1.16b + ext T1.16b, XL.16b, XH.16b, #8 + eor T2.16b, T2.16b, T1.16b + + mov XL.d[1], T2.d[0] + mov XH.d[0], T2.d[1] + + ushr T2.2d, XL.2d, #1 + eor XH.16b, XH.16b, XL.16b + eor XL.16b, XL.16b, T2.16b + ushr T2.2d, T2.2d, #6 + ushr XL.2d, XL.2d, #1 + .endm + + .macro __pmull_ghash, pn ld1 {SHASH.2d}, [x3] ld1 {XL.2d}, [x1] - movi MASK.16b, #0xe1 ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 - shl MASK.2d, MASK.2d, #57 eor SHASH2.16b, SHASH2.16b, SHASH.16b + __pmull_pre_\pn + /* do the head block first, if supplied */ cbz x4, 0f ld1 {T1.2d}, [x4] @@ -52,28 +236,209 @@ CPU_LE( rev64 T1.16b, T1.16b ) eor T1.16b, T1.16b, T2.16b eor XL.16b, XL.16b, IN1.16b + __pmull2_\pn XH, XL, SHASH // a1 * b1 + eor T1.16b, T1.16b, XL.16b + __pmull_\pn XL, XL, SHASH // a0 * b0 + __pmull_\pn XM, T1, SHASH2 // (a1 + a0)(b1 + b0) + + eor T2.16b, XL.16b, XH.16b + ext T1.16b, XL.16b, XH.16b, #8 + eor XM.16b, XM.16b, T2.16b + + __pmull_reduce_\pn + + eor T2.16b, T2.16b, XH.16b + eor XL.16b, XL.16b, T2.16b + + cbnz w0, 0b + + st1 {XL.2d}, [x1] + ret + .endm + + /* + * void pmull_ghash_update(int blocks, u64 dg[], const char *src, + * struct ghash_key const *k, const char *head) + */ +ENTRY(pmull_ghash_update_p64) + __pmull_ghash p64 +ENDPROC(pmull_ghash_update_p64) + +ENTRY(pmull_ghash_update_p8) + __pmull_ghash p8 +ENDPROC(pmull_ghash_update_p8) + + KS .req v8 + CTR .req v9 + INP .req v10 + + .macro load_round_keys, rounds, rk + cmp \rounds, #12 + blo 2222f /* 128 bits */ + beq 1111f /* 192 bits */ + ld1 {v17.4s-v18.4s}, [\rk], #32 +1111: ld1 {v19.4s-v20.4s}, [\rk], #32 +2222: ld1 {v21.4s-v24.4s}, [\rk], #64 + ld1 {v25.4s-v28.4s}, [\rk], #64 + ld1 {v29.4s-v31.4s}, [\rk] + .endm + + .macro enc_round, state, key + aese \state\().16b, \key\().16b + aesmc \state\().16b, \state\().16b + .endm + + .macro enc_block, state, rounds + cmp \rounds, #12 + b.lo 2222f /* 128 bits */ + b.eq 1111f /* 192 bits */ + enc_round \state, v17 + enc_round \state, v18 +1111: enc_round \state, v19 + enc_round \state, v20 +2222: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29 + enc_round \state, \key + .endr + aese \state\().16b, v30.16b + eor \state\().16b, \state\().16b, v31.16b + .endm + + .macro pmull_gcm_do_crypt, enc + ld1 {SHASH.2d}, [x4] + ld1 {XL.2d}, [x1] + ldr x8, [x5, #8] // load lower counter + + movi MASK.16b, #0xe1 + ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 +CPU_LE( rev x8, x8 ) + shl MASK.2d, MASK.2d, #57 + eor SHASH2.16b, SHASH2.16b, SHASH.16b + + .if \enc == 1 + ld1 {KS.16b}, [x7] + .endif + +0: ld1 {CTR.8b}, [x5] // load upper counter + ld1 {INP.16b}, [x3], #16 + rev x9, x8 + add x8, x8, #1 + sub w0, w0, #1 + ins CTR.d[1], x9 // set lower counter + + .if \enc == 1 + eor INP.16b, INP.16b, KS.16b // encrypt input + st1 {INP.16b}, [x2], #16 + .endif + + rev64 T1.16b, INP.16b + + cmp w6, #12 + b.ge 2f // AES-192/256? + +1: enc_round CTR, v21 + + ext T2.16b, XL.16b, XL.16b, #8 + ext IN1.16b, T1.16b, T1.16b, #8 + + enc_round CTR, v22 + + eor T1.16b, T1.16b, T2.16b + eor XL.16b, XL.16b, IN1.16b + + enc_round CTR, v23 + pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1 eor T1.16b, T1.16b, XL.16b + + enc_round CTR, v24 + pmull XL.1q, SHASH.1d, XL.1d // a0 * b0 pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0) + enc_round CTR, v25 + ext T1.16b, XL.16b, XH.16b, #8 eor T2.16b, XL.16b, XH.16b eor XM.16b, XM.16b, T1.16b + + enc_round CTR, v26 + eor XM.16b, XM.16b, T2.16b pmull T2.1q, XL.1d, MASK.1d + enc_round CTR, v27 + mov XH.d[0], XM.d[1] mov XM.d[1], XL.d[0] + enc_round CTR, v28 + eor XL.16b, XM.16b, T2.16b + + enc_round CTR, v29 + ext T2.16b, XL.16b, XL.16b, #8 + + aese CTR.16b, v30.16b + pmull XL.1q, XL.1d, MASK.1d eor T2.16b, T2.16b, XH.16b + + eor KS.16b, CTR.16b, v31.16b + eor XL.16b, XL.16b, T2.16b + .if \enc == 0 + eor INP.16b, INP.16b, KS.16b + st1 {INP.16b}, [x2], #16 + .endif + cbnz w0, 0b +CPU_LE( rev x8, x8 ) st1 {XL.2d}, [x1] + str x8, [x5, #8] // store lower counter + + .if \enc == 1 + st1 {KS.16b}, [x7] + .endif + + ret + +2: b.eq 3f // AES-192? + enc_round CTR, v17 + enc_round CTR, v18 +3: enc_round CTR, v19 + enc_round CTR, v20 + b 1b + .endm + + /* + * void pmull_gcm_encrypt(int blocks, u64 dg[], u8 dst[], const u8 src[], + * struct ghash_key const *k, u8 ctr[], + * int rounds, u8 ks[]) + */ +ENTRY(pmull_gcm_encrypt) + pmull_gcm_do_crypt 1 +ENDPROC(pmull_gcm_encrypt) + + /* + * void pmull_gcm_decrypt(int blocks, u64 dg[], u8 dst[], const u8 src[], + * struct ghash_key const *k, u8 ctr[], + * int rounds) + */ +ENTRY(pmull_gcm_decrypt) + pmull_gcm_do_crypt 0 +ENDPROC(pmull_gcm_decrypt) + + /* + * void pmull_gcm_encrypt_block(u8 dst[], u8 src[], u8 rk[], int rounds) + */ +ENTRY(pmull_gcm_encrypt_block) + cbz x2, 0f + load_round_keys w3, x2 +0: ld1 {v0.16b}, [x1] + enc_block v0, w3 + st1 {v0.16b}, [x0] ret -ENDPROC(pmull_ghash_update) +ENDPROC(pmull_gcm_encrypt_block) diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c index 833ec1e3f3e9b7491cc26da24fc0ba386b73de81..cfc9c92814fd0cb74bfd3c9ad78973de57c07e20 100644 --- a/arch/arm64/crypto/ghash-ce-glue.c +++ b/arch/arm64/crypto/ghash-ce-glue.c @@ -1,7 +1,7 @@ /* * Accelerated GHASH implementation with ARMv8 PMULL instructions. * - * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2014 - 2017 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -9,22 +9,33 @@ */ #include +#include #include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include -MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions"); +MODULE_DESCRIPTION("GHASH and AES-GCM using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("ghash"); #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 +#define GCM_IV_SIZE 12 struct ghash_key { u64 a; u64 b; + be128 k; }; struct ghash_desc_ctx { @@ -33,8 +44,35 @@ struct ghash_desc_ctx { u32 count; }; -asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src, - struct ghash_key const *k, const char *head); +struct gcm_aes_ctx { + struct crypto_aes_ctx aes_key; + struct ghash_key ghash_key; +}; + +asmlinkage void pmull_ghash_update_p64(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +asmlinkage void pmull_ghash_update_p8(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +static void (*pmull_ghash_update)(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +asmlinkage void pmull_gcm_encrypt(int blocks, u64 dg[], u8 dst[], + const u8 src[], struct ghash_key const *k, + u8 ctr[], int rounds, u8 ks[]); + +asmlinkage void pmull_gcm_decrypt(int blocks, u64 dg[], u8 dst[], + const u8 src[], struct ghash_key const *k, + u8 ctr[], int rounds); + +asmlinkage void pmull_gcm_encrypt_block(u8 dst[], u8 const src[], + u32 const rk[], int rounds); + +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); static int ghash_init(struct shash_desc *desc) { @@ -44,6 +82,36 @@ static int ghash_init(struct shash_desc *desc) return 0; } +static void ghash_do_update(int blocks, u64 dg[], const char *src, + struct ghash_key *key, const char *head) +{ + if (likely(may_use_simd())) { + kernel_neon_begin(); + pmull_ghash_update(blocks, dg, src, key, head); + kernel_neon_end(); + } else { + be128 dst = { cpu_to_be64(dg[1]), cpu_to_be64(dg[0]) }; + + do { + const u8 *in = src; + + if (head) { + in = head; + blocks++; + head = NULL; + } else { + src += GHASH_BLOCK_SIZE; + } + + crypto_xor((u8 *)&dst, in, GHASH_BLOCK_SIZE); + gf128mul_lle(&dst, &key->k); + } while (--blocks); + + dg[0] = be64_to_cpu(dst.b); + dg[1] = be64_to_cpu(dst.a); + } +} + static int ghash_update(struct shash_desc *desc, const u8 *src, unsigned int len) { @@ -67,10 +135,9 @@ static int ghash_update(struct shash_desc *desc, const u8 *src, blocks = len / GHASH_BLOCK_SIZE; len %= GHASH_BLOCK_SIZE; - kernel_neon_begin_partial(8); - pmull_ghash_update(blocks, ctx->digest, src, key, - partial ? ctx->buf : NULL); - kernel_neon_end(); + ghash_do_update(blocks, ctx->digest, src, key, + partial ? ctx->buf : NULL); + src += blocks * GHASH_BLOCK_SIZE; partial = 0; } @@ -89,9 +156,7 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial); - kernel_neon_begin_partial(8); - pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL); - kernel_neon_end(); + ghash_do_update(1, ctx->digest, ctx->buf, key, NULL); } put_unaligned_be64(ctx->digest[1], dst); put_unaligned_be64(ctx->digest[0], dst + 8); @@ -100,16 +165,13 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) return 0; } -static int ghash_setkey(struct crypto_shash *tfm, - const u8 *inkey, unsigned int keylen) +static int __ghash_setkey(struct ghash_key *key, + const u8 *inkey, unsigned int keylen) { - struct ghash_key *key = crypto_shash_ctx(tfm); u64 a, b; - if (keylen != GHASH_BLOCK_SIZE) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } + /* needed for the fallback */ + memcpy(&key->k, inkey, GHASH_BLOCK_SIZE); /* perform multiplication by 'x' in GF(2^128) */ b = get_unaligned_be64(inkey); @@ -124,33 +186,418 @@ static int ghash_setkey(struct crypto_shash *tfm, return 0; } +static int ghash_setkey(struct crypto_shash *tfm, + const u8 *inkey, unsigned int keylen) +{ + struct ghash_key *key = crypto_shash_ctx(tfm); + + if (keylen != GHASH_BLOCK_SIZE) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + return __ghash_setkey(key, inkey, keylen); +} + static struct shash_alg ghash_alg = { - .digestsize = GHASH_DIGEST_SIZE, - .init = ghash_init, - .update = ghash_update, - .final = ghash_final, - .setkey = ghash_setkey, - .descsize = sizeof(struct ghash_desc_ctx), - .base = { - .cra_name = "ghash", - .cra_driver_name = "ghash-ce", - .cra_priority = 200, - .cra_flags = CRYPTO_ALG_TYPE_SHASH, - .cra_blocksize = GHASH_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct ghash_key), - .cra_module = THIS_MODULE, - }, + .base.cra_name = "ghash", + .base.cra_driver_name = "ghash-ce", + .base.cra_priority = 200, + .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, + .base.cra_blocksize = GHASH_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct ghash_key), + .base.cra_module = THIS_MODULE, + + .digestsize = GHASH_DIGEST_SIZE, + .init = ghash_init, + .update = ghash_update, + .final = ghash_final, + .setkey = ghash_setkey, + .descsize = sizeof(struct ghash_desc_ctx), +}; + +static int num_rounds(struct crypto_aes_ctx *ctx) +{ + /* + * # of rounds specified by AES: + * 128 bit key 10 rounds + * 192 bit key 12 rounds + * 256 bit key 14 rounds + * => n byte key => 6 + (n/4) rounds + */ + return 6 + ctx->key_length / 4; +} + +static int gcm_setkey(struct crypto_aead *tfm, const u8 *inkey, + unsigned int keylen) +{ + struct gcm_aes_ctx *ctx = crypto_aead_ctx(tfm); + u8 key[GHASH_BLOCK_SIZE]; + int ret; + + ret = crypto_aes_expand_key(&ctx->aes_key, inkey, keylen); + if (ret) { + tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + __aes_arm64_encrypt(ctx->aes_key.key_enc, key, (u8[AES_BLOCK_SIZE]){}, + num_rounds(&ctx->aes_key)); + + return __ghash_setkey(&ctx->ghash_key, key, sizeof(key)); +} + +static int gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + switch (authsize) { + case 4: + case 8: + case 12 ... 16: + break; + default: + return -EINVAL; + } + return 0; +} + +static void gcm_update_mac(u64 dg[], const u8 *src, int count, u8 buf[], + int *buf_count, struct gcm_aes_ctx *ctx) +{ + if (*buf_count > 0) { + int buf_added = min(count, GHASH_BLOCK_SIZE - *buf_count); + + memcpy(&buf[*buf_count], src, buf_added); + + *buf_count += buf_added; + src += buf_added; + count -= buf_added; + } + + if (count >= GHASH_BLOCK_SIZE || *buf_count == GHASH_BLOCK_SIZE) { + int blocks = count / GHASH_BLOCK_SIZE; + + ghash_do_update(blocks, dg, src, &ctx->ghash_key, + *buf_count ? buf : NULL); + + src += blocks * GHASH_BLOCK_SIZE; + count %= GHASH_BLOCK_SIZE; + *buf_count = 0; + } + + if (count > 0) { + memcpy(buf, src, count); + *buf_count = count; + } +} + +static void gcm_calculate_auth_mac(struct aead_request *req, u64 dg[]) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct gcm_aes_ctx *ctx = crypto_aead_ctx(aead); + u8 buf[GHASH_BLOCK_SIZE]; + struct scatter_walk walk; + u32 len = req->assoclen; + int buf_count = 0; + + scatterwalk_start(&walk, req->src); + + do { + u32 n = scatterwalk_clamp(&walk, len); + u8 *p; + + if (!n) { + scatterwalk_start(&walk, sg_next(walk.sg)); + n = scatterwalk_clamp(&walk, len); + } + p = scatterwalk_map(&walk); + + gcm_update_mac(dg, p, n, buf, &buf_count, ctx); + len -= n; + + scatterwalk_unmap(p); + scatterwalk_advance(&walk, n); + scatterwalk_done(&walk, 0, len); + } while (len); + + if (buf_count) { + memset(&buf[buf_count], 0, GHASH_BLOCK_SIZE - buf_count); + ghash_do_update(1, dg, buf, &ctx->ghash_key, NULL); + } +} + +static void gcm_final(struct aead_request *req, struct gcm_aes_ctx *ctx, + u64 dg[], u8 tag[], int cryptlen) +{ + u8 mac[AES_BLOCK_SIZE]; + u128 lengths; + + lengths.a = cpu_to_be64(req->assoclen * 8); + lengths.b = cpu_to_be64(cryptlen * 8); + + ghash_do_update(1, dg, (void *)&lengths, &ctx->ghash_key, NULL); + + put_unaligned_be64(dg[1], mac); + put_unaligned_be64(dg[0], mac + 8); + + crypto_xor(tag, mac, AES_BLOCK_SIZE); +} + +static int gcm_encrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct gcm_aes_ctx *ctx = crypto_aead_ctx(aead); + struct skcipher_walk walk; + u8 iv[AES_BLOCK_SIZE]; + u8 ks[AES_BLOCK_SIZE]; + u8 tag[AES_BLOCK_SIZE]; + u64 dg[2] = {}; + int err; + + if (req->assoclen) + gcm_calculate_auth_mac(req, dg); + + memcpy(iv, req->iv, GCM_IV_SIZE); + put_unaligned_be32(1, iv + GCM_IV_SIZE); + + if (likely(may_use_simd())) { + kernel_neon_begin(); + + pmull_gcm_encrypt_block(tag, iv, ctx->aes_key.key_enc, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + pmull_gcm_encrypt_block(ks, iv, NULL, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(3, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_encrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + + pmull_gcm_encrypt(blocks, dg, walk.dst.virt.addr, + walk.src.virt.addr, &ctx->ghash_key, + iv, num_rounds(&ctx->aes_key), ks); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + kernel_neon_end(); + } else { + __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_encrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + + do { + __aes_arm64_encrypt(ctx->aes_key.key_enc, + ks, iv, + num_rounds(&ctx->aes_key)); + crypto_xor_cpy(dst, src, ks, AES_BLOCK_SIZE); + crypto_inc(iv, AES_BLOCK_SIZE); + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } while (--blocks > 0); + + ghash_do_update(walk.nbytes / AES_BLOCK_SIZE, dg, + walk.dst.virt.addr, &ctx->ghash_key, + NULL); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + if (walk.nbytes) + __aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv, + num_rounds(&ctx->aes_key)); + } + + /* handle the tail */ + if (walk.nbytes) { + u8 buf[GHASH_BLOCK_SIZE]; + + crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr, ks, + walk.nbytes); + + memcpy(buf, walk.dst.virt.addr, walk.nbytes); + memset(buf + walk.nbytes, 0, GHASH_BLOCK_SIZE - walk.nbytes); + ghash_do_update(1, dg, buf, &ctx->ghash_key, NULL); + + err = skcipher_walk_done(&walk, 0); + } + + if (err) + return err; + + gcm_final(req, ctx, dg, tag, req->cryptlen); + + /* copy authtag to end of dst */ + scatterwalk_map_and_copy(tag, req->dst, req->assoclen + req->cryptlen, + crypto_aead_authsize(aead), 1); + + return 0; +} + +static int gcm_decrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct gcm_aes_ctx *ctx = crypto_aead_ctx(aead); + unsigned int authsize = crypto_aead_authsize(aead); + struct skcipher_walk walk; + u8 iv[AES_BLOCK_SIZE]; + u8 tag[AES_BLOCK_SIZE]; + u8 buf[GHASH_BLOCK_SIZE]; + u64 dg[2] = {}; + int err; + + if (req->assoclen) + gcm_calculate_auth_mac(req, dg); + + memcpy(iv, req->iv, GCM_IV_SIZE); + put_unaligned_be32(1, iv + GCM_IV_SIZE); + + if (likely(may_use_simd())) { + kernel_neon_begin(); + + pmull_gcm_encrypt_block(tag, iv, ctx->aes_key.key_enc, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_decrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + + pmull_gcm_decrypt(blocks, dg, walk.dst.virt.addr, + walk.src.virt.addr, &ctx->ghash_key, + iv, num_rounds(&ctx->aes_key)); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + if (walk.nbytes) + pmull_gcm_encrypt_block(iv, iv, NULL, + num_rounds(&ctx->aes_key)); + + kernel_neon_end(); + } else { + __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_decrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + + ghash_do_update(blocks, dg, walk.src.virt.addr, + &ctx->ghash_key, NULL); + + do { + __aes_arm64_encrypt(ctx->aes_key.key_enc, + buf, iv, + num_rounds(&ctx->aes_key)); + crypto_xor_cpy(dst, src, buf, AES_BLOCK_SIZE); + crypto_inc(iv, AES_BLOCK_SIZE); + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } while (--blocks > 0); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + if (walk.nbytes) + __aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv, + num_rounds(&ctx->aes_key)); + } + + /* handle the tail */ + if (walk.nbytes) { + memcpy(buf, walk.src.virt.addr, walk.nbytes); + memset(buf + walk.nbytes, 0, GHASH_BLOCK_SIZE - walk.nbytes); + ghash_do_update(1, dg, buf, &ctx->ghash_key, NULL); + + crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr, iv, + walk.nbytes); + + err = skcipher_walk_done(&walk, 0); + } + + if (err) + return err; + + gcm_final(req, ctx, dg, tag, req->cryptlen - authsize); + + /* compare calculated auth tag with the stored one */ + scatterwalk_map_and_copy(buf, req->src, + req->assoclen + req->cryptlen - authsize, + authsize, 0); + + if (crypto_memneq(tag, buf, authsize)) + return -EBADMSG; + return 0; +} + +static struct aead_alg gcm_aes_alg = { + .ivsize = GCM_IV_SIZE, + .chunksize = AES_BLOCK_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .setkey = gcm_setkey, + .setauthsize = gcm_setauthsize, + .encrypt = gcm_encrypt, + .decrypt = gcm_decrypt, + + .base.cra_name = "gcm(aes)", + .base.cra_driver_name = "gcm-aes-ce", + .base.cra_priority = 300, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct gcm_aes_ctx), + .base.cra_module = THIS_MODULE, }; static int __init ghash_ce_mod_init(void) { - return crypto_register_shash(&ghash_alg); + int ret; + + if (!(elf_hwcap & HWCAP_ASIMD)) + return -ENODEV; + + if (elf_hwcap & HWCAP_PMULL) + pmull_ghash_update = pmull_ghash_update_p64; + + else + pmull_ghash_update = pmull_ghash_update_p8; + + ret = crypto_register_shash(&ghash_alg); + if (ret) + return ret; + + if (elf_hwcap & HWCAP_PMULL) { + ret = crypto_register_aead(&gcm_aes_alg); + if (ret) + crypto_unregister_shash(&ghash_alg); + } + return ret; } static void __exit ghash_ce_mod_exit(void) { crypto_unregister_shash(&ghash_alg); + crypto_unregister_aead(&gcm_aes_alg); } -module_cpu_feature_match(PMULL, ghash_ce_mod_init); +static const struct cpu_feature ghash_cpu_feature[] = { + { cpu_feature(PMULL) }, { } +}; +MODULE_DEVICE_TABLE(cpu, ghash_cpu_feature); + +module_init(ghash_ce_mod_init); module_exit(ghash_ce_mod_exit); diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c index ea319c055f5dfbee35a31c68ceb005501a8f26b7..efbeb3e0dcfb048099095a971512d8a9a1f62595 100644 --- a/arch/arm64/crypto/sha1-ce-glue.c +++ b/arch/arm64/crypto/sha1-ce-glue.c @@ -1,7 +1,7 @@ /* * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions * - * Copyright (C) 2014 Linaro Ltd + * Copyright (C) 2014 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -37,8 +38,11 @@ static int sha1_ce_update(struct shash_desc *desc, const u8 *data, { struct sha1_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) + return crypto_sha1_update(desc, data, len); + sctx->finalize = 0; - kernel_neon_begin_partial(16); + kernel_neon_begin(); sha1_base_do_update(desc, data, len, (sha1_block_fn *)sha1_ce_transform); kernel_neon_end(); @@ -52,13 +56,16 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data, struct sha1_ce_state *sctx = shash_desc_ctx(desc); bool finalize = !sctx->sst.count && !(len % SHA1_BLOCK_SIZE); + if (!may_use_simd()) + return crypto_sha1_finup(desc, data, len, out); + /* * Allow the asm code to perform the finalization if there is no * partial data and the input is a round multiple of the block size. */ sctx->finalize = finalize; - kernel_neon_begin_partial(16); + kernel_neon_begin(); sha1_base_do_update(desc, data, len, (sha1_block_fn *)sha1_ce_transform); if (!finalize) @@ -71,8 +78,11 @@ static int sha1_ce_final(struct shash_desc *desc, u8 *out) { struct sha1_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) + return crypto_sha1_finup(desc, NULL, 0, out); + sctx->finalize = 0; - kernel_neon_begin_partial(16); + kernel_neon_begin(); sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform); kernel_neon_end(); return sha1_base_finish(desc, out); diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c index 0ed9486f75dd928568c86d1fdd3ad9bca3cde47a..fd1ff2b13dfa35aa356b2511744808a848a56a97 100644 --- a/arch/arm64/crypto/sha2-ce-glue.c +++ b/arch/arm64/crypto/sha2-ce-glue.c @@ -1,7 +1,7 @@ /* * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions * - * Copyright (C) 2014 Linaro Ltd + * Copyright (C) 2014 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -34,13 +35,19 @@ const u32 sha256_ce_offsetof_count = offsetof(struct sha256_ce_state, const u32 sha256_ce_offsetof_finalize = offsetof(struct sha256_ce_state, finalize); +asmlinkage void sha256_block_data_order(u32 *digest, u8 const *src, int blocks); + static int sha256_ce_update(struct shash_desc *desc, const u8 *data, unsigned int len) { struct sha256_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) + return sha256_base_do_update(desc, data, len, + (sha256_block_fn *)sha256_block_data_order); + sctx->finalize = 0; - kernel_neon_begin_partial(28); + kernel_neon_begin(); sha256_base_do_update(desc, data, len, (sha256_block_fn *)sha2_ce_transform); kernel_neon_end(); @@ -54,13 +61,22 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data, struct sha256_ce_state *sctx = shash_desc_ctx(desc); bool finalize = !sctx->sst.count && !(len % SHA256_BLOCK_SIZE); + if (!may_use_simd()) { + if (len) + sha256_base_do_update(desc, data, len, + (sha256_block_fn *)sha256_block_data_order); + sha256_base_do_finalize(desc, + (sha256_block_fn *)sha256_block_data_order); + return sha256_base_finish(desc, out); + } + /* * Allow the asm code to perform the finalization if there is no * partial data and the input is a round multiple of the block size. */ sctx->finalize = finalize; - kernel_neon_begin_partial(28); + kernel_neon_begin(); sha256_base_do_update(desc, data, len, (sha256_block_fn *)sha2_ce_transform); if (!finalize) @@ -74,8 +90,14 @@ static int sha256_ce_final(struct shash_desc *desc, u8 *out) { struct sha256_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) { + sha256_base_do_finalize(desc, + (sha256_block_fn *)sha256_block_data_order); + return sha256_base_finish(desc, out); + } + sctx->finalize = 0; - kernel_neon_begin_partial(28); + kernel_neon_begin(); sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform); kernel_neon_end(); return sha256_base_finish(desc, out); diff --git a/arch/arm64/crypto/sha256-glue.c b/arch/arm64/crypto/sha256-glue.c index a2226f8419609c461cab422337fd604ded53c8ee..b064d925fe2a7552222c568754e03d474c11a5aa 100644 --- a/arch/arm64/crypto/sha256-glue.c +++ b/arch/arm64/crypto/sha256-glue.c @@ -29,6 +29,7 @@ MODULE_ALIAS_CRYPTO("sha256"); asmlinkage void sha256_block_data_order(u32 *digest, const void *data, unsigned int num_blks); +EXPORT_SYMBOL(sha256_block_data_order); asmlinkage void sha256_block_neon(u32 *digest, const void *data, unsigned int num_blks); diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index f81c7b685fc6f3ee2dc7d15fdf31924d06e396ba..2326e39d58929e3c7d10ce94579e5a4a34901e36 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -20,7 +20,6 @@ generic-y += rwsem.h generic-y += segment.h generic-y += serial.h generic-y += set_memory.h -generic-y += simd.h generic-y += sizes.h generic-y += switch_to.h generic-y += trace_clock.h diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 8cef47fa2218d4941c06cb7d80bdd6375b5f36fd..b7e3f74822dafa6525558d356068958acd58c949 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -116,6 +116,8 @@ static inline void gic_write_bpr1(u32 val) #define gic_read_typer(c) readq_relaxed(c) #define gic_write_irouter(v, c) writeq_relaxed(v, c) +#define gic_read_lpir(c) readq_relaxed(c) +#define gic_write_lpir(v, c) writeq_relaxed(v, c) #define gic_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) @@ -133,5 +135,10 @@ static inline void gic_write_bpr1(u32 val) #define gicr_write_pendbaser(v, c) writeq_relaxed(v, c) #define gicr_read_pendbaser(c) readq_relaxed(c) +#define gits_write_vpropbaser(v, c) writeq_relaxed(v, c) + +#define gits_write_vpendbaser(v, c) writeq_relaxed(v, c) +#define gits_read_vpendbaser(c) readq_relaxed(c) + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARCH_GICV3_H */ diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 74d08e44a651b9e58de7d8a6075f6101083f5262..a652ce0a5cb2c33178ac2e447fad1159efb0c6a9 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -65,13 +65,13 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *, u64 _val; \ if (needs_unstable_timer_counter_workaround()) { \ const struct arch_timer_erratum_workaround *wa; \ - preempt_disable(); \ + preempt_disable_notrace(); \ wa = __this_cpu_read(timer_unstable_counter_workaround); \ if (wa && wa->read_##reg) \ _val = wa->read_##reg(); \ else \ _val = read_sysreg(reg); \ - preempt_enable(); \ + preempt_enable_notrace(); \ } else { \ _val = read_sysreg(reg); \ } \ diff --git a/arch/arm64/include/asm/asm-bug.h b/arch/arm64/include/asm/asm-bug.h new file mode 100644 index 0000000000000000000000000000000000000000..636e755bcdca8235e10e88581e0e9eb6af927f69 --- /dev/null +++ b/arch/arm64/include/asm/asm-bug.h @@ -0,0 +1,54 @@ +#ifndef __ASM_ASM_BUG_H +/* + * Copyright (C) 2017 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define __ASM_ASM_BUG_H + +#include + +#ifdef CONFIG_DEBUG_BUGVERBOSE +#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) +#define __BUGVERBOSE_LOCATION(file, line) \ + .pushsection .rodata.str,"aMS",@progbits,1; \ + 2: .string file; \ + .popsection; \ + \ + .long 2b - 0b; \ + .short line; +#else +#define _BUGVERBOSE_LOCATION(file, line) +#endif + +#ifdef CONFIG_GENERIC_BUG + +#define __BUG_ENTRY(flags) \ + .pushsection __bug_table,"aw"; \ + .align 2; \ + 0: .long 1f - 0b; \ +_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ + .short flags; \ + .popsection; \ + 1: +#else +#define __BUG_ENTRY(flags) +#endif + +#define ASM_BUG_FLAGS(flags) \ + __BUG_ENTRY(flags) \ + brk BUG_BRK_IMM + +#define ASM_BUG() ASM_BUG_FLAGS(0) + +#endif /* __ASM_ASM_BUG_H */ diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 1b67c3782d005b5d1872e0ceedcf4250b3b3d8c9..d58a6253c6abc4e8ff04b1d96082d71150006de9 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -230,12 +230,18 @@ lr .req x30 // link register .endm /* - * @dst: Result of per_cpu(sym, smp_processor_id()) + * @dst: Result of per_cpu(sym, smp_processor_id()), can be SP for + * non-module code * @sym: The name of the per-cpu variable * @tmp: scratch register */ .macro adr_this_cpu, dst, sym, tmp +#ifndef MODULE + adrp \tmp, \sym + add \dst, \tmp, #:lo12:\sym +#else adr_l \dst, \sym +#endif mrs \tmp, tpidr_el1 add \dst, \dst, \tmp .endm @@ -352,6 +358,12 @@ alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE dc \op, \kaddr alternative_else dc civac, \kaddr +alternative_endif + .elseif (\op == cvap) +alternative_if ARM64_HAS_DCPOP + sys 3, c7, c12, 1, \kaddr // dc cvap +alternative_else + dc cvac, \kaddr alternative_endif .else dc \op, \kaddr @@ -403,6 +415,17 @@ alternative_endif .size __pi_##x, . - x; \ ENDPROC(x) +/* + * Annotate a function as being unsuitable for kprobes. + */ +#ifdef CONFIG_KPROBES +#define NOKPROBE(x) \ + .pushsection "_kprobe_blacklist", "aw"; \ + .quad x; \ + .popsection; +#else +#define NOKPROBE(x) +#endif /* * Emit a 64-bit absolute little endian symbol reference in a way that * ensures that it will be resolved at build time, even when building a diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h index a02a57186f5689b7a3d99869d6770f7705332957..d7dc437527050736e99dd28e2f0b8bd526551a23 100644 --- a/arch/arm64/include/asm/bug.h +++ b/arch/arm64/include/asm/bug.h @@ -18,41 +18,12 @@ #ifndef _ARCH_ARM64_ASM_BUG_H #define _ARCH_ARM64_ASM_BUG_H -#include +#include -#ifdef CONFIG_DEBUG_BUGVERBOSE -#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) -#define __BUGVERBOSE_LOCATION(file, line) \ - ".pushsection .rodata.str,\"aMS\",@progbits,1\n" \ - "2: .string \"" file "\"\n\t" \ - ".popsection\n\t" \ - \ - ".long 2b - 0b\n\t" \ - ".short " #line "\n\t" -#else -#define _BUGVERBOSE_LOCATION(file, line) -#endif - -#ifdef CONFIG_GENERIC_BUG - -#define __BUG_ENTRY(flags) \ - ".pushsection __bug_table,\"aw\"\n\t" \ - ".align 2\n\t" \ - "0: .long 1f - 0b\n\t" \ -_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ - ".short " #flags "\n\t" \ - ".popsection\n" \ - "1: " -#else -#define __BUG_ENTRY(flags) "" -#endif +#include #define __BUG_FLAGS(flags) \ - asm volatile ( \ - __BUG_ENTRY(flags) \ - "brk %[imm]" :: [imm] "i" (BUG_BRK_IMM) \ - ); - + asm volatile (__stringify(ASM_BUG_FLAGS(flags))); #define BUG() do { \ __BUG_FLAGS(0); \ diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index d74a284abdc2f1f39f6b275a7e0818db2c6ae193..76d1cc85d5b115915aaa63138121e9ba286d8f4e 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h @@ -67,7 +67,9 @@ */ extern void flush_icache_range(unsigned long start, unsigned long end); extern void __flush_dcache_area(void *addr, size_t len); +extern void __inval_dcache_area(void *addr, size_t len); extern void __clean_dcache_area_poc(void *addr, size_t len); +extern void __clean_dcache_area_pop(void *addr, size_t len); extern void __clean_dcache_area_pou(void *addr, size_t len); extern long __flush_cache_user_range(unsigned long start, unsigned long end); extern void sync_icache_aliases(void *kaddr, unsigned long len); @@ -150,6 +152,6 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { } -int set_memory_valid(unsigned long addr, unsigned long size, int enable); +int set_memory_valid(unsigned long addr, int numpages, int enable); #endif diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 8d2272c6822c703b2076eccc04667ecb775c6860..8da621627d7c892a0833d325991e567678b4eced 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -39,7 +39,8 @@ #define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18 #define ARM64_WORKAROUND_858921 19 #define ARM64_WORKAROUND_CAVIUM_30115 20 +#define ARM64_HAS_DCPOP 21 -#define ARM64_NCAPS 21 +#define ARM64_NCAPS 22 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 8f3043aba87307c9ebc3435277e3f4f933fd3278..b93904b16fc2aadb7a4e8c85e1122d5c116788f5 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include #include @@ -20,8 +22,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define arch_efi_call_virt_setup() \ ({ \ - kernel_neon_begin(); \ efi_virtmap_load(); \ + __efi_fpsimd_begin(); \ }) #define arch_efi_call_virt(p, f, args...) \ @@ -33,8 +35,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define arch_efi_call_virt_teardown() \ ({ \ + __efi_fpsimd_end(); \ efi_virtmap_unload(); \ - kernel_neon_end(); \ }) #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) @@ -48,6 +50,13 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); */ #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ +/* + * In some configurations (e.g. VMAP_STACK && 64K pages), stacks built into the + * kernel need greater alignment than we require the segments to be padded to. + */ +#define EFI_KIMG_ALIGN \ + (SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN) + /* on arm64, the FDT may be located anywhere in system RAM */ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) { @@ -81,6 +90,9 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, #define alloc_screen_info(x...) &screen_info #define free_screen_info(x...) +/* redeclare as 'hidden' so the compiler will generate relative references */ +extern struct screen_info screen_info __attribute__((__visibility__("hidden"))); + static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) { } diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index acae781f7359ece14f713e74e168deb6e47dd68b..33be513ef24c84093c9a50441663896b3f04376f 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -114,10 +114,10 @@ /* * This is the base location for PIE (ET_DYN with INTERP) loads. On - * 64-bit, this is raised to 4GB to leave the entire 32-bit address + * 64-bit, this is above 4GB to leave the entire 32-bit address * space open for things that want to use the area for 32-bit pointers. */ -#define ELF_ET_DYN_BASE 0x100000000UL +#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3) #ifndef __ASSEMBLY__ @@ -139,7 +139,6 @@ typedef struct user_fpsimd_state elf_fpregset_t; #define SET_PERSONALITY(ex) \ ({ \ - clear_bit(TIF_32BIT, ¤t->mm->context.flags); \ clear_thread_flag(TIF_32BIT); \ current->personality &= ~READ_IMPLIES_EXEC; \ }) @@ -195,7 +194,6 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; */ #define COMPAT_SET_PERSONALITY(ex) \ ({ \ - set_bit(TIF_32BIT, ¤t->mm->context.flags); \ set_thread_flag(TIF_32BIT); \ }) #define COMPAT_ARCH_DLINFO diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 8cabd57b634832ca7c4df7d8fee39549233167dd..66ed8b6b9976cd2f2762b9ee26e64d922da467e2 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -77,16 +77,23 @@ #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) -#define ESR_ELx_IL (UL(1) << 25) +#define ESR_ELx_IL_SHIFT (25) +#define ESR_ELx_IL (UL(1) << ESR_ELx_IL_SHIFT) #define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1) /* ISS field definitions shared by different classes */ -#define ESR_ELx_WNR (UL(1) << 6) +#define ESR_ELx_WNR_SHIFT (6) +#define ESR_ELx_WNR (UL(1) << ESR_ELx_WNR_SHIFT) /* Shared ISS field definitions for Data/Instruction aborts */ -#define ESR_ELx_FnV (UL(1) << 10) -#define ESR_ELx_EA (UL(1) << 9) -#define ESR_ELx_S1PTW (UL(1) << 7) +#define ESR_ELx_SET_SHIFT (11) +#define ESR_ELx_SET_MASK (UL(3) << ESR_ELx_SET_SHIFT) +#define ESR_ELx_FnV_SHIFT (10) +#define ESR_ELx_FnV (UL(1) << ESR_ELx_FnV_SHIFT) +#define ESR_ELx_EA_SHIFT (9) +#define ESR_ELx_EA (UL(1) << ESR_ELx_EA_SHIFT) +#define ESR_ELx_S1PTW_SHIFT (7) +#define ESR_ELx_S1PTW (UL(1) << ESR_ELx_S1PTW_SHIFT) /* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */ #define ESR_ELx_FSC (0x3F) @@ -97,15 +104,20 @@ #define ESR_ELx_FSC_PERM (0x0C) /* ISS field definitions for Data Aborts */ -#define ESR_ELx_ISV (UL(1) << 24) +#define ESR_ELx_ISV_SHIFT (24) +#define ESR_ELx_ISV (UL(1) << ESR_ELx_ISV_SHIFT) #define ESR_ELx_SAS_SHIFT (22) #define ESR_ELx_SAS (UL(3) << ESR_ELx_SAS_SHIFT) -#define ESR_ELx_SSE (UL(1) << 21) +#define ESR_ELx_SSE_SHIFT (21) +#define ESR_ELx_SSE (UL(1) << ESR_ELx_SSE_SHIFT) #define ESR_ELx_SRT_SHIFT (16) #define ESR_ELx_SRT_MASK (UL(0x1F) << ESR_ELx_SRT_SHIFT) -#define ESR_ELx_SF (UL(1) << 15) -#define ESR_ELx_AR (UL(1) << 14) -#define ESR_ELx_CM (UL(1) << 8) +#define ESR_ELx_SF_SHIFT (15) +#define ESR_ELx_SF (UL(1) << ESR_ELx_SF_SHIFT) +#define ESR_ELx_AR_SHIFT (14) +#define ESR_ELx_AR (UL(1) << ESR_ELx_AR_SHIFT) +#define ESR_ELx_CM_SHIFT (8) +#define ESR_ELx_CM (UL(1) << ESR_ELx_CM_SHIFT) /* ISS field definitions for exceptions taken in to Hyp */ #define ESR_ELx_CV (UL(1) << 24) @@ -157,9 +169,10 @@ /* * User space cache operations have the following sysreg encoding * in System instructions. - * op0=1, op1=3, op2=1, crn=7, crm={ 5, 10, 11, 14 }, WRITE (L=0) + * op0=1, op1=3, op2=1, crn=7, crm={ 5, 10, 11, 12, 14 }, WRITE (L=0) */ #define ESR_ELx_SYS64_ISS_CRM_DC_CIVAC 14 +#define ESR_ELx_SYS64_ISS_CRM_DC_CVAP 12 #define ESR_ELx_SYS64_ISS_CRM_DC_CVAU 11 #define ESR_ELx_SYS64_ISS_CRM_DC_CVAC 10 #define ESR_ELx_SYS64_ISS_CRM_IC_IVAU 5 @@ -209,6 +222,13 @@ #ifndef __ASSEMBLY__ #include +static inline bool esr_is_data_abort(u32 esr) +{ + const u32 ec = ESR_ELx_EC(esr); + + return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR; +} + const char *esr_get_class_string(u32 esr); #endif /* __ASSEMBLY */ diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 50f559f574fe53b4d25995bd465c7b90f0a4b8be..410c48163c6a1f3783752a116cbdec669bd66f09 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -41,16 +41,6 @@ struct fpsimd_state { unsigned int cpu; }; -/* - * Struct for stacking the bottom 'n' FP/SIMD registers. - */ -struct fpsimd_partial_state { - u32 fpsr; - u32 fpcr; - u32 num_regs; - __uint128_t vregs[32]; -}; - #if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* Masks for extracting the FPSR and FPCR from the FPSCR */ @@ -77,9 +67,9 @@ extern void fpsimd_update_current_state(struct fpsimd_state *state); extern void fpsimd_flush_task_state(struct task_struct *target); -extern void fpsimd_save_partial_state(struct fpsimd_partial_state *state, - u32 num_regs); -extern void fpsimd_load_partial_state(struct fpsimd_partial_state *state); +/* For use by EFI runtime services calls only */ +extern void __efi_fpsimd_begin(void); +extern void __efi_fpsimd_end(void); #endif diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index a2daf12930284183122bd14da5a0c2b441c91034..0f5fdd388b0dfb0ee17d01e4357033866d9caa1b 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h @@ -75,59 +75,3 @@ ldr w\tmpnr, [\state, #16 * 2 + 4] fpsimd_restore_fpcr x\tmpnr, \state .endm - -.macro fpsimd_save_partial state, numnr, tmpnr1, tmpnr2 - mrs x\tmpnr1, fpsr - str w\numnr, [\state, #8] - mrs x\tmpnr2, fpcr - stp w\tmpnr1, w\tmpnr2, [\state] - adr x\tmpnr1, 0f - add \state, \state, x\numnr, lsl #4 - sub x\tmpnr1, x\tmpnr1, x\numnr, lsl #1 - br x\tmpnr1 - stp q30, q31, [\state, #-16 * 30 - 16] - stp q28, q29, [\state, #-16 * 28 - 16] - stp q26, q27, [\state, #-16 * 26 - 16] - stp q24, q25, [\state, #-16 * 24 - 16] - stp q22, q23, [\state, #-16 * 22 - 16] - stp q20, q21, [\state, #-16 * 20 - 16] - stp q18, q19, [\state, #-16 * 18 - 16] - stp q16, q17, [\state, #-16 * 16 - 16] - stp q14, q15, [\state, #-16 * 14 - 16] - stp q12, q13, [\state, #-16 * 12 - 16] - stp q10, q11, [\state, #-16 * 10 - 16] - stp q8, q9, [\state, #-16 * 8 - 16] - stp q6, q7, [\state, #-16 * 6 - 16] - stp q4, q5, [\state, #-16 * 4 - 16] - stp q2, q3, [\state, #-16 * 2 - 16] - stp q0, q1, [\state, #-16 * 0 - 16] -0: -.endm - -.macro fpsimd_restore_partial state, tmpnr1, tmpnr2 - ldp w\tmpnr1, w\tmpnr2, [\state] - msr fpsr, x\tmpnr1 - fpsimd_restore_fpcr x\tmpnr2, x\tmpnr1 - adr x\tmpnr1, 0f - ldr w\tmpnr2, [\state, #8] - add \state, \state, x\tmpnr2, lsl #4 - sub x\tmpnr1, x\tmpnr1, x\tmpnr2, lsl #1 - br x\tmpnr1 - ldp q30, q31, [\state, #-16 * 30 - 16] - ldp q28, q29, [\state, #-16 * 28 - 16] - ldp q26, q27, [\state, #-16 * 26 - 16] - ldp q24, q25, [\state, #-16 * 24 - 16] - ldp q22, q23, [\state, #-16 * 22 - 16] - ldp q20, q21, [\state, #-16 * 20 - 16] - ldp q18, q19, [\state, #-16 * 18 - 16] - ldp q16, q17, [\state, #-16 * 16 - 16] - ldp q14, q15, [\state, #-16 * 14 - 16] - ldp q12, q13, [\state, #-16 * 12 - 16] - ldp q10, q11, [\state, #-16 * 10 - 16] - ldp q8, q9, [\state, #-16 * 8 - 16] - ldp q6, q7, [\state, #-16 * 6 - 16] - ldp q4, q5, [\state, #-16 * 4 - 16] - ldp q2, q3, [\state, #-16 * 2 - 16] - ldp q0, q1, [\state, #-16 * 0 - 16] -0: -.endm diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index f32b42e8725dc6d95a884cfffbe3e8fe6134d5d8..5bb2fd4674e7c5f3744362bd7f79e5a30350d4f7 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -48,20 +48,10 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (int)(encoded_op << 8) >> 20; - int cmparg = (int)(encoded_op << 20) >> 20; int oldval = 0, ret, tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1U << (oparg & 0x1f); - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -91,17 +81,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h index 793bd73b0d0788903820cd60fe8affedb97ae126..1dca41bea16ad61fc8fe6f2be528ba452bffdf27 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -18,7 +18,6 @@ #ifndef __ASM_HUGETLB_H #define __ASM_HUGETLB_H -#include #include static inline pte_t huge_ptep_get(pte_t *ptep) @@ -82,6 +81,14 @@ extern void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep); extern void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); +extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz); +#define huge_pte_clear huge_pte_clear +extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, unsigned long sz); +#define set_huge_swap_pte_at set_huge_swap_pte_at + +#include #ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE static inline bool gigantic_page_supported(void) { return true; } diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index b77197d941fc442c4bad04b185d5cf786ca9fea5..5e6f772390644d9dbaf1f2c15033f2f9562522b8 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -1,45 +1,12 @@ #ifndef __ASM_IRQ_H #define __ASM_IRQ_H -#define IRQ_STACK_SIZE THREAD_SIZE -#define IRQ_STACK_START_SP THREAD_START_SP - #ifndef __ASSEMBLER__ -#include - #include -#include struct pt_regs; -DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); - -/* - * The highest address on the stack, and the first to be used. Used to - * find the dummy-stack frame put down by el?_irq() in entry.S, which - * is structured as follows: - * - * ------------ - * | | <- irq_stack_ptr - * top ------------ - * | x19 | <- irq_stack_ptr - 0x08 - * ------------ - * | x29 | <- irq_stack_ptr - 0x10 - * ------------ - * - * where x19 holds a copy of the task stack pointer where the struct pt_regs - * from kernel_entry can be found. - * - */ -#define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP) - -/* - * The offset from irq_stack_ptr where entry.S will store the original - * stack pointer. Used by unwind_frame() and dump_backtrace(). - */ -#define IRQ_STACK_TO_TASK_STACK(ptr) (*((unsigned long *)((ptr) - 0x08))) - extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); static inline int nr_legacy_irqs(void) @@ -47,14 +14,5 @@ static inline int nr_legacy_irqs(void) return 0; } -static inline bool on_irq_stack(unsigned long sp, int cpu) -{ - /* variable names the same as kernel/stacktrace.c */ - unsigned long low = (unsigned long)per_cpu(irq_stack, cpu); - unsigned long high = low + IRQ_STACK_START_SP; - - return (low <= sp && sp <= high); -} - #endif /* !__ASSEMBLER__ */ #endif diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index fe39e6841326f01c9ae2d933b8048459c2e8ef6e..e5df3fce00082a3aa6d1711188e6d1055012dc9d 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -188,11 +188,6 @@ static inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu) return (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT; } -static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) -{ - return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_EA); -} - static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) { return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW); @@ -240,6 +235,25 @@ static inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vcpu) return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE; } +static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) +{ + switch (kvm_vcpu_trap_get_fault_type(vcpu)) { + case FSC_SEA: + case FSC_SEA_TTW0: + case FSC_SEA_TTW1: + case FSC_SEA_TTW2: + case FSC_SEA_TTW3: + case FSC_SECC: + case FSC_SECC_TTW0: + case FSC_SECC_TTW1: + case FSC_SECC_TTW2: + case FSC_SECC_TTW3: + return true; + default: + return false; + } +} + static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu) { u32 esr = kvm_vcpu_get_hsr(vcpu); diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index d68630007b14f542865df7e49bc0efacefe9a39d..e923b58606e2bf8e33a76bd4a8a9a4c1336199c6 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -326,12 +326,6 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); -/* We do not have shadow page tables, hence the empty hooks */ -static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, - unsigned long address) -{ -} - struct kvm_vcpu *kvm_arm_get_running_vcpu(void); struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void); void kvm_arm_halt_guest(struct kvm *kvm); diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index a89cc22abadcaced0ee272ec38eb8e490292fd8d..672c8684d5c2a796fadae762846c1f314016c7c3 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -175,18 +175,15 @@ static inline pmd_t kvm_s2pmd_mkwrite(pmd_t pmd) static inline void kvm_set_s2pte_readonly(pte_t *pte) { - pteval_t pteval; - unsigned long tmp; - - asm volatile("// kvm_set_s2pte_readonly\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " and %0, %0, %3 // clear PTE_S2_RDWR\n" - " orr %0, %0, %4 // set PTE_S2_RDONLY\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*pte)) - : "L" (~PTE_S2_RDWR), "L" (PTE_S2_RDONLY)); + pteval_t old_pteval, pteval; + + pteval = READ_ONCE(pte_val(*pte)); + do { + old_pteval = pteval; + pteval &= ~PTE_S2_RDWR; + pteval |= PTE_S2_RDONLY; + pteval = cmpxchg_relaxed(&pte_val(*pte), old_pteval, pteval); + } while (pteval != old_pteval); } static inline bool kvm_s2pte_readonly(pte_t *pte) diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h index 636c1bced7d4a9dd60d3a6489997ebd82b83d96e..1b266292f0bee00ce1952005479053e820b5ca0e 100644 --- a/arch/arm64/include/asm/linkage.h +++ b/arch/arm64/include/asm/linkage.h @@ -1,7 +1,7 @@ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H -#define __ALIGN .align 4 -#define __ALIGN_STR ".align 4" +#define __ALIGN .align 2 +#define __ALIGN_STR ".align 2" #endif diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 32f82723338a0e23bd880273aa9ae53e93a9979d..f7c4d2146aed09b715a59506f7e01ab0d167f3de 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -25,6 +25,7 @@ #include #include #include +#include #include /* @@ -64,8 +65,10 @@ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. */ #define VA_BITS (CONFIG_ARM64_VA_BITS) -#define VA_START (UL(0xffffffffffffffff) << VA_BITS) -#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) +#define VA_START (UL(0xffffffffffffffff) - \ + (UL(1) << VA_BITS) + 1) +#define PAGE_OFFSET (UL(0xffffffffffffffff) - \ + (UL(1) << (VA_BITS - 1)) + 1) #define KIMAGE_VADDR (MODULES_END) #define MODULES_END (MODULES_VADDR + MODULES_VSIZE) #define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE) @@ -92,13 +95,68 @@ #define KERNEL_END _end /* - * The size of the KASAN shadow region. This should be 1/8th of the - * size of the entire kernel virtual address space. + * KASAN requires 1/8th of the kernel virtual address space for the shadow + * region. KASAN can bloat the stack significantly, so double the (minimum) + * stack size when KASAN is in use. */ #ifdef CONFIG_KASAN #define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3)) +#define KASAN_THREAD_SHIFT 1 #else #define KASAN_SHADOW_SIZE (0) +#define KASAN_THREAD_SHIFT 0 +#endif + +#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT) + +/* + * VMAP'd stacks are allocated at page granularity, so we must ensure that such + * stacks are a multiple of page size. + */ +#if defined(CONFIG_VMAP_STACK) && (MIN_THREAD_SHIFT < PAGE_SHIFT) +#define THREAD_SHIFT PAGE_SHIFT +#else +#define THREAD_SHIFT MIN_THREAD_SHIFT +#endif + +#if THREAD_SHIFT >= PAGE_SHIFT +#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#endif + +#define THREAD_SIZE (UL(1) << THREAD_SHIFT) + +/* + * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by + * checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry + * assembly. + */ +#ifdef CONFIG_VMAP_STACK +#define THREAD_ALIGN (2 * THREAD_SIZE) +#else +#define THREAD_ALIGN THREAD_SIZE +#endif + +#define IRQ_STACK_SIZE THREAD_SIZE + +#define OVERFLOW_STACK_SIZE SZ_4K + +/* + * Alignment of kernel segments (e.g. .text, .data). + */ +#if defined(CONFIG_DEBUG_ALIGN_RODATA) +/* + * 4 KB granule: 1 level 2 entry + * 16 KB granule: 128 level 3 entries, with contiguous bit + * 64 KB granule: 32 level 3 entries, with contiguous bit + */ +#define SEGMENT_ALIGN SZ_2M +#else +/* + * 4 KB granule: 16 level 3 entries, with contiguous bit + * 16 KB granule: 4 level 3 entries, without contiguous bit + * 64 KB granule: 1 level 3 entry + */ +#define SEGMENT_ALIGN SZ_64K #endif /* diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 5468c834b072b2a29701a69e0468b0b32cafba4d..0d34bf0a89c7241bdd89a7a6a4634f7a4af31dd5 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -16,6 +16,8 @@ #ifndef __ASM_MMU_H #define __ASM_MMU_H +#define MMCF_AARCH32 0x1 /* mm context flag for AArch32 executables */ + typedef struct { atomic64_t id; void *vdso; diff --git a/arch/arm64/include/asm/neon.h b/arch/arm64/include/asm/neon.h index ad4cdc966c0f69ac524952caf996e8b4a99b14d2..f922eaf780f9be5c4863170efda01ae64d0ce77e 100644 --- a/arch/arm64/include/asm/neon.h +++ b/arch/arm64/include/asm/neon.h @@ -8,12 +8,22 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_NEON_H +#define __ASM_NEON_H + #include #include #define cpu_has_neon() system_supports_fpsimd() -#define kernel_neon_begin() kernel_neon_begin_partial(32) - -void kernel_neon_begin_partial(u32 num_regs); +void kernel_neon_begin(void); void kernel_neon_end(void); + +/* + * Temporary macro to allow the crypto code to compile. Note that the + * semantics of kernel_neon_begin_partial() are now different from the + * original as it does not allow being called in an interrupt context. + */ +#define kernel_neon_begin_partial(num_regs) kernel_neon_begin() + +#endif /* ! __ASM_NEON_H */ diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h index bf466d1876e3f27d6cd2b6e7edced71c0ae32f7b..ef7b23863a7cb8b817d72a30575fbd7ac0e9bd4a 100644 --- a/arch/arm64/include/asm/numa.h +++ b/arch/arm64/include/asm/numa.h @@ -7,9 +7,6 @@ #define NR_NODE_MEMBLKS (MAX_NUMNODES * 2) -/* currently, arm64 implements flat NUMA topology */ -#define parent_node(node) (node) - int __node_distance(int from, int to); #define node_distance(a, b) __node_distance(a, b) diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h new file mode 100644 index 0000000000000000000000000000000000000000..01591a29dc2e9659e8eca08f153ea4eec669f667 --- /dev/null +++ b/arch/arm64/include/asm/page-def.h @@ -0,0 +1,34 @@ +/* + * Based on arch/arm/include/asm/page.h + * + * Copyright (C) 1995-2003 Russell King + * Copyright (C) 2017 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __ASM_PAGE_DEF_H +#define __ASM_PAGE_DEF_H + +#include + +/* PAGE_SHIFT determines the page size */ +/* CONT_SHIFT determines the number of pages which can be tracked together */ +#define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT +#define CONT_SHIFT CONFIG_ARM64_CONT_SHIFT +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#define CONT_SIZE (_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT)) +#define CONT_MASK (~(CONT_SIZE-1)) + +#endif /* __ASM_PAGE_DEF_H */ diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 8472c6def5ef5efe53ba8a6fbd0be3f456c95d1a..60d02c81a3a2c02a6d41de1721a529a4881b507e 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -19,17 +19,7 @@ #ifndef __ASM_PAGE_H #define __ASM_PAGE_H -#include - -/* PAGE_SHIFT determines the page size */ -/* CONT_SHIFT determines the number of pages which can be tracked together */ -#define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT -#define CONT_SHIFT CONFIG_ARM64_CONT_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#define CONT_SIZE (_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT)) -#define CONT_MASK (~(CONT_SIZE-1)) +#include #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 2142c7726e76d048dd61f4322977832a69da4733..0a5635fb0ef9843f0eac0a328e0c763d76bf4444 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -63,23 +63,21 @@ #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) -#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) +#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN) #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) -#define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) -#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) -#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN) +#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) +#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) +#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN) #define __P000 PAGE_NONE #define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY +#define __P010 PAGE_READONLY +#define __P011 PAGE_READONLY #define __P100 PAGE_EXECONLY #define __P101 PAGE_READONLY_EXEC -#define __P110 PAGE_COPY_EXEC -#define __P111 PAGE_COPY_EXEC +#define __P110 PAGE_READONLY_EXEC +#define __P111 PAGE_READONLY_EXEC #define __S000 PAGE_NONE #define __S001 PAGE_READONLY diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 6eae342ced6be5572c0efa0cbd28e37d76ed03b1..b46e54c2399b58b6451ea9dacc5c033115b05c64 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -39,6 +39,7 @@ #ifndef __ASSEMBLY__ +#include #include #include @@ -84,11 +85,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; (__boundary - 1 < (end) - 1) ? __boundary : (end); \ }) -#ifdef CONFIG_ARM64_HW_AFDBM #define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY)) -#else -#define pte_hw_dirty(pte) (0) -#endif #define pte_sw_dirty(pte) (!!(pte_val(pte) & PTE_DIRTY)) #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) @@ -124,12 +121,16 @@ static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot) static inline pte_t pte_wrprotect(pte_t pte) { - return clear_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); + return pte; } static inline pte_t pte_mkwrite(pte_t pte) { - return set_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); + return pte; } static inline pte_t pte_mkclean(pte_t pte) @@ -168,11 +169,6 @@ static inline pte_t pte_mknoncont(pte_t pte) return clear_pte_bit(pte, __pgprot(PTE_CONT)); } -static inline pte_t pte_clear_rdonly(pte_t pte) -{ - return clear_pte_bit(pte, __pgprot(PTE_RDONLY)); -} - static inline pte_t pte_mkpresent(pte_t pte) { return set_pte_bit(pte, __pgprot(PTE_VALID)); @@ -220,22 +216,15 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { - if (pte_present(pte)) { - if (pte_sw_dirty(pte) && pte_write(pte)) - pte_val(pte) &= ~PTE_RDONLY; - else - pte_val(pte) |= PTE_RDONLY; - if (pte_user_exec(pte) && !pte_special(pte)) - __sync_icache_dcache(pte, addr); - } + if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) + __sync_icache_dcache(pte, addr); /* * If the existing pte is valid, check for potential race with * hardware updates of the pte (ptep_set_access_flags safely changes * valid ptes without going through an invalid entry). */ - if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && - pte_valid(*ptep) && pte_valid(pte)) { + if (pte_valid(*ptep) && pte_valid(pte)) { VM_WARN_ONCE(!pte_young(pte), "%s: racy access flag clearing: 0x%016llx -> 0x%016llx", __func__, pte_val(*ptep), pte_val(pte)); @@ -412,7 +401,7 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd) /* Find an entry in the third-level page table. */ #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -#define pte_offset_phys(dir,addr) (pmd_page_paddr(*(dir)) + pte_index(addr) * sizeof(pte_t)) +#define pte_offset_phys(dir,addr) (pmd_page_paddr(READ_ONCE(*(dir))) + pte_index(addr) * sizeof(pte_t)) #define pte_offset_kernel(dir,addr) ((pte_t *)__va(pte_offset_phys((dir), (addr)))) #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) @@ -571,7 +560,6 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) return pte_pmd(pte_modify(pmd_pte(pmd), newprot)); } -#ifdef CONFIG_ARM64_HW_AFDBM #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, @@ -593,20 +581,17 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma, #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG static inline int __ptep_test_and_clear_young(pte_t *ptep) { - pteval_t pteval; - unsigned int tmp, res; + pte_t old_pte, pte; - asm volatile("// __ptep_test_and_clear_young\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " ubfx %w3, %w0, %5, #1 // extract PTE_AF (young)\n" - " and %0, %0, %4 // clear PTE_AF\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*ptep)), "=&r" (res) - : "L" (~PTE_AF), "I" (ilog2(PTE_AF))); + pte = READ_ONCE(*ptep); + do { + old_pte = pte; + pte = pte_mkold(pte); + pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), + pte_val(old_pte), pte_val(pte)); + } while (pte_val(pte) != pte_val(old_pte)); - return res; + return pte_young(pte); } static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, @@ -630,17 +615,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pteval_t old_pteval; - unsigned int tmp; - - asm volatile("// ptep_get_and_clear\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " stxr %w1, xzr, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))); - - return __pte(old_pteval); + return __pte(xchg_relaxed(&pte_val(*ptep), 0)); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -653,27 +628,32 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ /* - * ptep_set_wrprotect - mark read-only while trasferring potential hardware - * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit. + * ptep_set_wrprotect - mark read-only while preserving the hardware update of + * the Access Flag. */ #define __HAVE_ARCH_PTEP_SET_WRPROTECT static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pteval_t pteval; - unsigned long tmp; + pte_t old_pte, pte; - asm volatile("// ptep_set_wrprotect\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " tst %0, %4 // check for hw dirty (!PTE_RDONLY)\n" - " csel %1, %3, xzr, eq // set PTE_DIRTY|PTE_RDONLY if dirty\n" - " orr %0, %0, %1 // if !dirty, PTE_RDONLY is already set\n" - " and %0, %0, %5 // clear PTE_WRITE/PTE_DBM\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*ptep)) - : "r" (PTE_DIRTY|PTE_RDONLY), "L" (PTE_RDONLY), "L" (~PTE_WRITE) - : "cc"); + /* + * ptep_set_wrprotect() is only called on CoW mappings which are + * private (!VM_SHARED) with the pte either read-only (!PTE_WRITE && + * PTE_RDONLY) or writable and software-dirty (PTE_WRITE && + * !PTE_RDONLY && PTE_DIRTY); see is_cow_mapping() and + * protection_map[]. There is no race with the hardware update of the + * dirty state: clearing of PTE_RDONLY when PTE_WRITE (a.k.a. PTE_DBM) + * is set. + */ + VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(*ptep), + "%s: potential race with hardware DBM", __func__); + pte = READ_ONCE(*ptep); + do { + old_pte = pte; + pte = pte_wrprotect(pte); + pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), + pte_val(old_pte), pte_val(pte)); + } while (pte_val(pte) != pte_val(old_pte)); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -684,7 +664,6 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, ptep_set_wrprotect(mm, address, (pte_t *)pmdp); } #endif -#endif /* CONFIG_ARM64_HW_AFDBM */ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 64c9e78f9882ca1551efcec7ae5ca41bccd892ed..29adab8138c396b48599af345874e5b5c569d572 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -112,7 +112,7 @@ void tls_preserve_current_state(void); static inline void start_thread_common(struct pt_regs *regs, unsigned long pc) { memset(regs, 0, sizeof(*regs)); - regs->syscallno = ~0UL; + forget_syscall(regs); regs->pc = pc; } @@ -159,7 +159,7 @@ extern struct task_struct *cpu_switch_to(struct task_struct *prev, struct task_struct *next); #define task_pt_regs(p) \ - ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) + ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) #define KSTK_EIP(tsk) ((unsigned long)task_pt_regs(tsk)->pc) #define KSTK_ESP(tsk) user_stack_pointer(task_pt_regs(tsk)) diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 11403fdd0a50593bad84714d17fea5510126db5e..6069d66e0bc2b2de5f9cb1a335af7c89e1f70dfb 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -72,8 +72,19 @@ #define COMPAT_PT_TEXT_ADDR 0x10000 #define COMPAT_PT_DATA_ADDR 0x10004 #define COMPAT_PT_TEXT_END_ADDR 0x10008 + +/* + * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing + * a syscall -- i.e., its most recent entry into the kernel from + * userspace was not via SVC, or otherwise a tracer cancelled the syscall. + * + * This must have the value -1, for ABI compatibility with ptrace etc. + */ +#define NO_SYSCALL (-1) + #ifndef __ASSEMBLY__ #include +#include /* sizeof(struct user) for AArch32 */ #define COMPAT_USER_SZ 296 @@ -116,11 +127,29 @@ struct pt_regs { }; }; u64 orig_x0; - u64 syscallno; +#ifdef __AARCH64EB__ + u32 unused2; + s32 syscallno; +#else + s32 syscallno; + u32 unused2; +#endif + u64 orig_addr_limit; u64 unused; // maintain 16 byte alignment + u64 stackframe[2]; }; +static inline bool in_syscall(struct pt_regs const *regs) +{ + return regs->syscallno != NO_SYSCALL; +} + +static inline void forget_syscall(struct pt_regs *regs) +{ + regs->syscallno = NO_SYSCALL; +} + #define MAX_REG_OFFSET offsetof(struct pt_regs, pstate) #define arch_has_single_step() (1) diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h index eeaa97559babffa2fa3e4cf74d084789e59cbf5e..81abea0b7650867d86385fc0c4fc145fefd24c46 100644 --- a/arch/arm64/include/asm/signal32.h +++ b/arch/arm64/include/asm/signal32.h @@ -22,8 +22,6 @@ #define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500 -extern const compat_ulong_t aarch32_sigret_code[6]; - int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs); int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h new file mode 100644 index 0000000000000000000000000000000000000000..fa8b3fe932e6f568841017215524bc0b894cbf28 --- /dev/null +++ b/arch/arm64/include/asm/simd.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __ASM_SIMD_H +#define __ASM_SIMD_H + +#include +#include +#include +#include +#include + +#ifdef CONFIG_KERNEL_MODE_NEON + +DECLARE_PER_CPU(bool, kernel_neon_busy); + +/* + * may_use_simd - whether it is allowable at this time to issue SIMD + * instructions or access the SIMD register file + * + * Callers must not assume that the result remains true beyond the next + * preempt_enable() or return from softirq context. + */ +static __must_check inline bool may_use_simd(void) +{ + /* + * The raw_cpu_read() is racy if called with preemption enabled. + * This is not a bug: kernel_neon_busy is only set when + * preemption is disabled, so we cannot migrate to another CPU + * while it is set, nor can we migrate to a CPU where it is set. + * So, if we find it clear on some CPU then we're guaranteed to + * find it clear on any CPU we could migrate to. + * + * If we are in between kernel_neon_begin()...kernel_neon_end(), + * the flag will be set, but preemption is also disabled, so we + * can't migrate to another CPU and spuriously see it become + * false. + */ + return !in_irq() && !irqs_disabled() && !in_nmi() && + !raw_cpu_read(kernel_neon_busy); +} + +#else /* ! CONFIG_KERNEL_MODE_NEON */ + +static __must_check inline bool may_use_simd(void) { + return false; +} + +#endif /* ! CONFIG_KERNEL_MODE_NEON */ + +#endif diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 55f08c5acfad93072a623a1516a26fbed52a7053..f82b447bd34f03c94998a5ac105fb9adeb1ee7b0 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -148,7 +148,7 @@ static inline void cpu_panic_kernel(void) */ bool cpus_are_stuck_in_kernel(void); -extern void smp_send_crash_stop(void); +extern void crash_smp_send_stop(void); extern bool smp_crash_stop_failed(void); #endif /* ifndef __ASSEMBLY__ */ diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index cae331d553f81b8ab649aa4e65c6da35038c5f97..95ad7102b63cec8f844e211e10ba5987ea812c62 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h @@ -26,58 +26,6 @@ * The memory barriers are implicit with the load-acquire and store-release * instructions. */ -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - unsigned int tmp; - arch_spinlock_t lockval; - u32 owner; - - /* - * Ensure prior spin_lock operations to other locks have completed - * on this CPU before we test whether "lock" is locked. - */ - smp_mb(); - owner = READ_ONCE(lock->owner) << 16; - - asm volatile( -" sevl\n" -"1: wfe\n" -"2: ldaxr %w0, %2\n" - /* Is the lock free? */ -" eor %w1, %w0, %w0, ror #16\n" -" cbz %w1, 3f\n" - /* Lock taken -- has there been a subsequent unlock->lock transition? */ -" eor %w1, %w3, %w0, lsl #16\n" -" cbz %w1, 1b\n" - /* - * The owner has been updated, so there was an unlock->lock - * transition that we missed. That means we can rely on the - * store-release of the unlock operation paired with the - * load-acquire of the lock operation to publish any of our - * previous stores to the new lock owner and therefore don't - * need to bother with the writeback below. - */ -" b 4f\n" -"3:\n" - /* - * Serialise against any concurrent lockers by writing back the - * unlocked lock value - */ - ARM64_LSE_ATOMIC_INSN( - /* LL/SC */ -" stxr %w1, %w0, %2\n" - __nops(2), - /* LSE atomics */ -" mov %w1, %w0\n" -" cas %w0, %w0, %2\n" -" eor %w1, %w1, %w0\n") - /* Somebody else wrote to the lock, GOTO 10 and reload the value */ -" cbnz %w1, 2b\n" -"4:" - : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) - : "r" (owner) - : "memory"); -} #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) @@ -176,7 +124,11 @@ static inline int arch_spin_value_unlocked(arch_spinlock_t lock) static inline int arch_spin_is_locked(arch_spinlock_t *lock) { - smp_mb(); /* See arch_spin_unlock_wait */ + /* + * Ensure prior spin_lock operations to other locks have completed + * on this CPU before we test whether "lock" is locked. + */ + smp_mb(); /* ^^^ */ return !arch_spin_value_unlocked(READ_ONCE(*lock)); } @@ -358,14 +310,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) #define arch_read_relax(lock) cpu_relax() #define arch_write_relax(lock) cpu_relax() -/* - * Accesses appearing in program order before a spin_lock() operation - * can be reordered with accesses inside the critical section, by virtue - * of arch_spin_lock being constructed using acquire semantics. - * - * In cases where this is problematic (e.g. try_to_wake_up), an - * smp_mb__before_spinlock() can restore the required ordering. - */ -#define smp_mb__before_spinlock() smp_mb() +/* See include/linux/spinlock.h */ +#define smp_mb__after_spinlock() smp_mb() #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 5b6eafccc5d8f76d95d0208ee058bc1ad38d19d9..6ad30776e984d071134f8762395565859691e0b0 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -16,11 +16,15 @@ #ifndef __ASM_STACKTRACE_H #define __ASM_STACKTRACE_H -struct task_struct; +#include +#include +#include + +#include +#include struct stackframe { unsigned long fp; - unsigned long sp; unsigned long pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER unsigned int graph; @@ -32,4 +36,57 @@ extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame, int (*fn)(struct stackframe *, void *), void *data); extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk); +DECLARE_PER_CPU(unsigned long *, irq_stack_ptr); + +static inline bool on_irq_stack(unsigned long sp) +{ + unsigned long low = (unsigned long)raw_cpu_read(irq_stack_ptr); + unsigned long high = low + IRQ_STACK_SIZE; + + if (!low) + return false; + + return (low <= sp && sp < high); +} + +static inline bool on_task_stack(struct task_struct *tsk, unsigned long sp) +{ + unsigned long low = (unsigned long)task_stack_page(tsk); + unsigned long high = low + THREAD_SIZE; + + return (low <= sp && sp < high); +} + +#ifdef CONFIG_VMAP_STACK +DECLARE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack); + +static inline bool on_overflow_stack(unsigned long sp) +{ + unsigned long low = (unsigned long)raw_cpu_ptr(overflow_stack); + unsigned long high = low + OVERFLOW_STACK_SIZE; + + return (low <= sp && sp < high); +} +#else +static inline bool on_overflow_stack(unsigned long sp) { return false; } +#endif + +/* + * We can only safely access per-cpu stacks from current in a non-preemptible + * context. + */ +static inline bool on_accessible_stack(struct task_struct *tsk, unsigned long sp) +{ + if (on_task_stack(tsk, sp)) + return true; + if (tsk != current || preemptible()) + return false; + if (on_irq_stack(sp)) + return true; + if (on_overflow_stack(sp)) + return true; + + return false; +} + #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index d0aa42907569beb95142f205c03bc1f21b9bae88..dd95d33a5bd5d652647955c08ab927fb3d8d78f8 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -52,6 +52,10 @@ extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP extern int memcmp(const void *, const void *, size_t); +#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE +#define __HAVE_ARCH_MEMCPY_FLUSHCACHE +void memcpy_flushcache(void *dst, const void *src, size_t cnt); +#endif #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 248339e4aaf5a7a0b6bc09bc2184654bbda72845..f707fed5886f011bce5fd4723d5ab2c739d997b7 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -329,6 +329,7 @@ #define ID_AA64ISAR1_LRCPC_SHIFT 20 #define ID_AA64ISAR1_FCMA_SHIFT 16 #define ID_AA64ISAR1_JSCVT_SHIFT 12 +#define ID_AA64ISAR1_DPB_SHIFT 0 /* id_aa64pfr0 */ #define ID_AA64PFR0_GIC_SHIFT 24 diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 46c3b93cf865b985df8b67114d09645bb0f2c3b6..ddded6497a8a7242299ff406c11f25020f852c3a 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -23,19 +23,11 @@ #include -#ifdef CONFIG_ARM64_4K_PAGES -#define THREAD_SIZE_ORDER 2 -#elif defined(CONFIG_ARM64_16K_PAGES) -#define THREAD_SIZE_ORDER 0 -#endif - -#define THREAD_SIZE 16384 -#define THREAD_START_SP (THREAD_SIZE - 16) - #ifndef __ASSEMBLY__ struct task_struct; +#include #include #include @@ -68,6 +60,9 @@ struct thread_info { #define thread_saved_fp(tsk) \ ((unsigned long)(tsk->thread.cpu_context.fp)) +void arch_setup_new_exec(void); +#define arch_setup_new_exec arch_setup_new_exec + #endif /* @@ -86,6 +81,7 @@ struct thread_info { #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ +#define TIF_FSCHECK 5 /* Check FS is USER_DS on return */ #define TIF_NOHZ 7 #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 @@ -107,11 +103,12 @@ struct thread_info { #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_UPROBE (1 << TIF_UPROBE) +#define _TIF_FSCHECK (1 << TIF_FSCHECK) #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ - _TIF_UPROBE) + _TIF_UPROBE | _TIF_FSCHECK) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index 02e9035b0685823faca22e5b6943ba39b7d27ce2..d131501c62229041320bc10e0b07511a49a0d91d 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h @@ -37,18 +37,11 @@ void unregister_undef_hook(struct undef_hook *hook); void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr); -#ifdef CONFIG_FUNCTION_GRAPH_TRACER static inline int __in_irqentry_text(unsigned long ptr) { return ptr >= (unsigned long)&__irqentry_text_start && ptr < (unsigned long)&__irqentry_text_end; } -#else -static inline int __in_irqentry_text(unsigned long ptr) -{ - return 0; -} -#endif static inline int in_exception_text(unsigned long ptr) { @@ -60,4 +53,9 @@ static inline int in_exception_text(unsigned long ptr) return in ? : __in_irqentry_text(ptr); } +static inline int in_entry_text(unsigned long ptr) +{ + return ptr >= (unsigned long)&__entry_text_start && + ptr < (unsigned long)&__entry_text_end; +} #endif diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index fab46a0ea223d74781464a2a3904a4d2eac0a423..fc0f9eb66039e7021af6a7237d342e58f84337d5 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -45,6 +45,9 @@ static inline void set_fs(mm_segment_t fs) { current_thread_info()->addr_limit = fs; + /* On user-mode return, check fs is correct */ + set_thread_flag(TIF_FSCHECK); + /* * Enable/disable UAO so that copy_to_user() etc can access * kernel memory with the unprivileged instructions. @@ -347,4 +350,16 @@ extern long strncpy_from_user(char *dest, const char __user *src, long count); extern __must_check long strnlen_user(const char __user *str, long n); +#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE +struct page; +void memcpy_page_flushcache(char *to, struct page *page, size_t offset, size_t len); +extern unsigned long __must_check __copy_user_flushcache(void *to, const void __user *from, unsigned long n); + +static inline int __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size) +{ + kasan_check_write(dst, size); + return __copy_user_flushcache(dst, src, size); +} +#endif + #endif /* __ASM_UACCESS_H */ diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index 4e187ce2a8113472b6c94ffb4feb934a45d4e254..4b9344cba83ae30256af652ad56aa9d6cd9e8ac1 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -35,5 +35,6 @@ #define HWCAP_JSCVT (1 << 13) #define HWCAP_FCMA (1 << 14) #define HWCAP_LRCPC (1 << 15) +#define HWCAP_DCPOP (1 << 16) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index e25c11e727fe5150f1792d29221cb03d98c4c7c0..b3162715ed78daefb5b47e0ae9b0035b02217af6 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -95,7 +95,7 @@ static int __init dt_scan_depth1_nodes(unsigned long node, * __acpi_map_table() will be called before page_init(), so early_ioremap() * or early_memremap() should be called here to for ACPI table mapping. */ -char *__init __acpi_map_table(unsigned long phys, unsigned long size) +void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) { if (!size) return NULL; @@ -103,7 +103,7 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) return early_memremap(phys, size); } -void __init __acpi_unmap_table(char *map, unsigned long size) +void __init __acpi_unmap_table(void __iomem *map, unsigned long size) { if (!map || !size) return; diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index f0e6d717885b1fcf3b22f64c10c38f19c25f809d..d06fbe4cd38d7423c900aff64b0e728f995478d3 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -649,4 +649,4 @@ static int __init armv8_deprecated_init(void) return 0; } -late_initcall(armv8_deprecated_init); +core_initcall(armv8_deprecated_init); diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index b3bb7ef97bc85c2c50580d10179f3fbbbb33e8ef..71bf088f1e4b2e63062fd1e75320b69c0951b050 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -75,6 +75,7 @@ int main(void) DEFINE(S_ORIG_X0, offsetof(struct pt_regs, orig_x0)); DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno)); DEFINE(S_ORIG_ADDR_LIMIT, offsetof(struct pt_regs, orig_addr_limit)); + DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); BLANK(); DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter)); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9f9e0064c8c151c95b2995cc14c69b2d6902878f..21e2c95d24e72a8e339406af601f02690675d3d8 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -120,6 +120,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_LRCPC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_FCMA_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_DPB_SHIFT, 4, 0), ARM64_FTR_END, }; @@ -888,6 +889,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .min_field_value = 0, .matches = has_no_fpsimd, }, +#ifdef CONFIG_ARM64_PMEM + { + .desc = "Data cache clean to Point of Persistence", + .capability = ARM64_HAS_DCPOP, + .def_scope = SCOPE_SYSTEM, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .field_pos = ID_AA64ISAR1_DPB_SHIFT, + .min_field_value = 1, + }, +#endif {}, }; @@ -916,6 +928,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_FPHP), HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_ASIMD), HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_ASIMDHP), + HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_DCPOP), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_JSCVT), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FCMA), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_LRCPC), @@ -1294,4 +1307,4 @@ static int __init enable_mrs_emulation(void) return 0; } -late_initcall(enable_mrs_emulation); +core_initcall(enable_mrs_emulation); diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index f495ee5049fd767c3a1bd1f555599167f9a1a1f1..311885962830bd058f6555b95dbdbe266dbef2e7 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -68,6 +68,7 @@ static const char *const hwcap_str[] = { "jscvt", "fcma", "lrcpc", + "dcpop", NULL }; diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S index c44a82f146b16664850ddadbfdc4699784c4e468..6a27cd6dbfa6dd81be8a6042e5366262a8146801 100644 --- a/arch/arm64/kernel/entry-fpsimd.S +++ b/arch/arm64/kernel/entry-fpsimd.S @@ -41,27 +41,3 @@ ENTRY(fpsimd_load_state) fpsimd_restore x0, 8 ret ENDPROC(fpsimd_load_state) - -#ifdef CONFIG_KERNEL_MODE_NEON - -/* - * Save the bottom n FP registers. - * - * x0 - pointer to struct fpsimd_partial_state - */ -ENTRY(fpsimd_save_partial_state) - fpsimd_save_partial x0, 1, 8, 9 - ret -ENDPROC(fpsimd_save_partial_state) - -/* - * Load the bottom n FP registers. - * - * x0 - pointer to struct fpsimd_partial_state - */ -ENTRY(fpsimd_load_partial_state) - fpsimd_restore_partial x0, 8, 9 - ret -ENDPROC(fpsimd_load_partial_state) - -#endif diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index b738880350f9e43b8e2f3234210bda153586caf5..e1c59d4008a8d0e0e4350ce5e3ea7da596b22555 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -69,8 +69,55 @@ #define BAD_FIQ 2 #define BAD_ERROR 3 - .macro kernel_entry, el, regsize = 64 + .macro kernel_ventry label + .align 7 sub sp, sp, #S_FRAME_SIZE +#ifdef CONFIG_VMAP_STACK + /* + * Test whether the SP has overflowed, without corrupting a GPR. + * Task and IRQ stacks are aligned to (1 << THREAD_SHIFT). + */ + add sp, sp, x0 // sp' = sp + x0 + sub x0, sp, x0 // x0' = sp' - x0 = (sp + x0) - x0 = sp + tbnz x0, #THREAD_SHIFT, 0f + sub x0, sp, x0 // x0'' = sp' - x0' = (sp + x0) - sp = x0 + sub sp, sp, x0 // sp'' = sp' - x0 = (sp + x0) - x0 = sp + b \label + +0: + /* + * Either we've just detected an overflow, or we've taken an exception + * while on the overflow stack. Either way, we won't return to + * userspace, and can clobber EL0 registers to free up GPRs. + */ + + /* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */ + msr tpidr_el0, x0 + + /* Recover the original x0 value and stash it in tpidrro_el0 */ + sub x0, sp, x0 + msr tpidrro_el0, x0 + + /* Switch to the overflow stack */ + adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0 + + /* + * Check whether we were already on the overflow stack. This may happen + * after panic() re-enables interrupts. + */ + mrs x0, tpidr_el0 // sp of interrupted context + sub x0, sp, x0 // delta with top of overflow stack + tst x0, #~(OVERFLOW_STACK_SIZE - 1) // within range? + b.ne __bad_stack // no? -> bad stack pointer + + /* We were already on the overflow stack. Restore sp/x0 and carry on. */ + sub sp, sp, x0 + mrs x0, tpidrro_el0 +#endif + b \label + .endm + + .macro kernel_entry, el, regsize = 64 .if \regsize == 32 mov w0, w0 // zero upper 32 bits of x0 .endif @@ -111,6 +158,18 @@ mrs x23, spsr_el1 stp lr, x21, [sp, #S_LR] + /* + * In order to be able to dump the contents of struct pt_regs at the + * time the exception was taken (in case we attempt to walk the call + * stack later), chain it together with the stack frames. + */ + .if \el == 0 + stp xzr, xzr, [sp, #S_STACKFRAME] + .else + stp x29, x22, [sp, #S_STACKFRAME] + .endif + add x29, sp, #S_STACKFRAME + #ifdef CONFIG_ARM64_SW_TTBR0_PAN /* * Set the TTBR0 PAN bit in SPSR. When the exception is taken from @@ -138,12 +197,10 @@ alternative_else_nop_endif stp x22, x23, [sp, #S_PC] - /* - * Set syscallno to -1 by default (overridden later if real syscall). - */ + /* Not in a syscall by default (el0_svc overwrites for real syscall) */ .if \el == 0 - mvn x21, xzr - str x21, [sp, #S_SYSCALLNO] + mov w21, #NO_SYSCALL + str w21, [sp, #S_SYSCALLNO] .endif /* @@ -259,20 +316,12 @@ alternative_else_nop_endif and x25, x25, #~(THREAD_SIZE - 1) cbnz x25, 9998f - adr_this_cpu x25, irq_stack, x26 - mov x26, #IRQ_STACK_START_SP + ldr_this_cpu x25, irq_stack_ptr, x26 + mov x26, #IRQ_STACK_SIZE add x26, x25, x26 /* switch to the irq stack */ mov sp, x26 - - /* - * Add a dummy stack frame, this non-standard format is fixed up - * by unwind_frame() - */ - stp x29, x19, [sp, #-16]! - mov x29, sp - 9998: .endm @@ -290,8 +339,9 @@ alternative_else_nop_endif * * x7 is reserved for the system call number in 32-bit mode. */ -sc_nr .req x25 // number of system calls -scno .req x26 // syscall number +wsc_nr .req w25 // number of system calls +wscno .req w26 // syscall number +xscno .req x26 // syscall number (zero-extended) stbl .req x27 // syscall table pointer tsk .req x28 // current thread_info @@ -315,34 +365,62 @@ tsk .req x28 // current thread_info .align 11 ENTRY(vectors) - ventry el1_sync_invalid // Synchronous EL1t - ventry el1_irq_invalid // IRQ EL1t - ventry el1_fiq_invalid // FIQ EL1t - ventry el1_error_invalid // Error EL1t + kernel_ventry el1_sync_invalid // Synchronous EL1t + kernel_ventry el1_irq_invalid // IRQ EL1t + kernel_ventry el1_fiq_invalid // FIQ EL1t + kernel_ventry el1_error_invalid // Error EL1t - ventry el1_sync // Synchronous EL1h - ventry el1_irq // IRQ EL1h - ventry el1_fiq_invalid // FIQ EL1h - ventry el1_error_invalid // Error EL1h + kernel_ventry el1_sync // Synchronous EL1h + kernel_ventry el1_irq // IRQ EL1h + kernel_ventry el1_fiq_invalid // FIQ EL1h + kernel_ventry el1_error_invalid // Error EL1h - ventry el0_sync // Synchronous 64-bit EL0 - ventry el0_irq // IRQ 64-bit EL0 - ventry el0_fiq_invalid // FIQ 64-bit EL0 - ventry el0_error_invalid // Error 64-bit EL0 + kernel_ventry el0_sync // Synchronous 64-bit EL0 + kernel_ventry el0_irq // IRQ 64-bit EL0 + kernel_ventry el0_fiq_invalid // FIQ 64-bit EL0 + kernel_ventry el0_error_invalid // Error 64-bit EL0 #ifdef CONFIG_COMPAT - ventry el0_sync_compat // Synchronous 32-bit EL0 - ventry el0_irq_compat // IRQ 32-bit EL0 - ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 - ventry el0_error_invalid_compat // Error 32-bit EL0 + kernel_ventry el0_sync_compat // Synchronous 32-bit EL0 + kernel_ventry el0_irq_compat // IRQ 32-bit EL0 + kernel_ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 + kernel_ventry el0_error_invalid_compat // Error 32-bit EL0 #else - ventry el0_sync_invalid // Synchronous 32-bit EL0 - ventry el0_irq_invalid // IRQ 32-bit EL0 - ventry el0_fiq_invalid // FIQ 32-bit EL0 - ventry el0_error_invalid // Error 32-bit EL0 + kernel_ventry el0_sync_invalid // Synchronous 32-bit EL0 + kernel_ventry el0_irq_invalid // IRQ 32-bit EL0 + kernel_ventry el0_fiq_invalid // FIQ 32-bit EL0 + kernel_ventry el0_error_invalid // Error 32-bit EL0 #endif END(vectors) +#ifdef CONFIG_VMAP_STACK + /* + * We detected an overflow in kernel_ventry, which switched to the + * overflow stack. Stash the exception regs, and head to our overflow + * handler. + */ +__bad_stack: + /* Restore the original x0 value */ + mrs x0, tpidrro_el0 + + /* + * Store the original GPRs to the new stack. The orginal SP (minus + * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry. + */ + sub sp, sp, #S_FRAME_SIZE + kernel_entry 1 + mrs x0, tpidr_el0 + add x0, x0, #S_FRAME_SIZE + str x0, [sp, #S_SP] + + /* Stash the regs for handle_bad_stack */ + mov x0, sp + + /* Time to die */ + bl handle_bad_stack + ASM_BUG() +#endif /* CONFIG_VMAP_STACK */ + /* * Invalid mode handlers */ @@ -351,7 +429,8 @@ END(vectors) mov x0, sp mov x1, #\reason mrs x2, esr_el1 - b bad_mode + bl bad_mode + ASM_BUG() .endm el0_sync_invalid: @@ -448,14 +527,16 @@ el1_sp_pc: mrs x0, far_el1 enable_dbg mov x2, sp - b do_sp_pc_abort + bl do_sp_pc_abort + ASM_BUG() el1_undef: /* * Undefined instruction */ enable_dbg mov x0, sp - b do_undefinstr + bl do_undefinstr + ASM_BUG() el1_dbg: /* * Debug exception handling @@ -473,7 +554,8 @@ el1_inv: mov x0, sp mov x2, x1 mov x1, #BAD_SYNC - b bad_mode + bl bad_mode + ASM_BUG() ENDPROC(el1_sync) .align 6 @@ -577,8 +659,8 @@ el0_svc_compat: * AArch32 syscall handling */ adrp stbl, compat_sys_call_table // load compat syscall table pointer - uxtw scno, w7 // syscall number in w7 (r7) - mov sc_nr, #__NR_compat_syscalls + mov wscno, w7 // syscall number in w7 (r7) + mov wsc_nr, #__NR_compat_syscalls b el0_svc_naked .align 6 @@ -706,38 +788,6 @@ el0_irq_naked: b ret_to_user ENDPROC(el0_irq) -/* - * Register switch for AArch64. The callee-saved registers need to be saved - * and restored. On entry: - * x0 = previous task_struct (must be preserved across the switch) - * x1 = next task_struct - * Previous and next are guaranteed not to be the same. - * - */ -ENTRY(cpu_switch_to) - mov x10, #THREAD_CPU_CONTEXT - add x8, x0, x10 - mov x9, sp - stp x19, x20, [x8], #16 // store callee-saved registers - stp x21, x22, [x8], #16 - stp x23, x24, [x8], #16 - stp x25, x26, [x8], #16 - stp x27, x28, [x8], #16 - stp x29, x9, [x8], #16 - str lr, [x8] - add x8, x1, x10 - ldp x19, x20, [x8], #16 // restore callee-saved registers - ldp x21, x22, [x8], #16 - ldp x23, x24, [x8], #16 - ldp x25, x26, [x8], #16 - ldp x27, x28, [x8], #16 - ldp x29, x9, [x8], #16 - ldr lr, [x8] - mov sp, x9 - msr sp_el0, x1 - ret -ENDPROC(cpu_switch_to) - /* * This is the fast syscall return path. We do as little as possible here, * and this includes saving x0 back into the kernel stack. @@ -780,37 +830,25 @@ finish_ret_to_user: kernel_exit 0 ENDPROC(ret_to_user) -/* - * This is how we return from a fork. - */ -ENTRY(ret_from_fork) - bl schedule_tail - cbz x19, 1f // not a kernel thread - mov x0, x20 - blr x19 -1: get_thread_info tsk - b ret_to_user -ENDPROC(ret_from_fork) - /* * SVC handler. */ .align 6 el0_svc: adrp stbl, sys_call_table // load syscall table pointer - uxtw scno, w8 // syscall number in w8 - mov sc_nr, #__NR_syscalls + mov wscno, w8 // syscall number in w8 + mov wsc_nr, #__NR_syscalls el0_svc_naked: // compat entry point - stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number + stp x0, xscno, [sp, #S_ORIG_X0] // save the original x0 and syscall number enable_dbg_and_irq ct_user_exit 1 ldr x16, [tsk, #TSK_TI_FLAGS] // check for syscall hooks tst x16, #_TIF_SYSCALL_WORK b.ne __sys_trace - cmp scno, sc_nr // check upper syscall limit + cmp wscno, wsc_nr // check upper syscall limit b.hs ni_sys - ldr x16, [stbl, scno, lsl #3] // address in the syscall table + ldr x16, [stbl, xscno, lsl #3] // address in the syscall table blr x16 // call sys_* routine b ret_fast_syscall ni_sys: @@ -824,24 +862,23 @@ ENDPROC(el0_svc) * switches, and waiting for our parent to respond. */ __sys_trace: - mov w0, #-1 // set default errno for - cmp scno, x0 // user-issued syscall(-1) + cmp wscno, #NO_SYSCALL // user-issued syscall(-1)? b.ne 1f - mov x0, #-ENOSYS + mov x0, #-ENOSYS // set default errno if so str x0, [sp, #S_X0] 1: mov x0, sp bl syscall_trace_enter - cmp w0, #-1 // skip the syscall? + cmp w0, #NO_SYSCALL // skip the syscall? b.eq __sys_trace_return_skipped - uxtw scno, w0 // syscall number (possibly new) + mov wscno, w0 // syscall number (possibly new) mov x1, sp // pointer to regs - cmp scno, sc_nr // check upper syscall limit + cmp wscno, wsc_nr // check upper syscall limit b.hs __ni_sys_trace ldp x0, x1, [sp] // restore the syscall args ldp x2, x3, [sp, #S_X2] ldp x4, x5, [sp, #S_X4] ldp x6, x7, [sp, #S_X6] - ldr x16, [stbl, scno, lsl #3] // address in the syscall table + ldr x16, [stbl, xscno, lsl #3] // address in the syscall table blr x16 // call sys_* routine __sys_trace_return: @@ -865,3 +902,49 @@ ENTRY(sys_rt_sigreturn_wrapper) mov x0, sp b sys_rt_sigreturn ENDPROC(sys_rt_sigreturn_wrapper) + +/* + * Register switch for AArch64. The callee-saved registers need to be saved + * and restored. On entry: + * x0 = previous task_struct (must be preserved across the switch) + * x1 = next task_struct + * Previous and next are guaranteed not to be the same. + * + */ +ENTRY(cpu_switch_to) + mov x10, #THREAD_CPU_CONTEXT + add x8, x0, x10 + mov x9, sp + stp x19, x20, [x8], #16 // store callee-saved registers + stp x21, x22, [x8], #16 + stp x23, x24, [x8], #16 + stp x25, x26, [x8], #16 + stp x27, x28, [x8], #16 + stp x29, x9, [x8], #16 + str lr, [x8] + add x8, x1, x10 + ldp x19, x20, [x8], #16 // restore callee-saved registers + ldp x21, x22, [x8], #16 + ldp x23, x24, [x8], #16 + ldp x25, x26, [x8], #16 + ldp x27, x28, [x8], #16 + ldp x29, x9, [x8], #16 + ldr lr, [x8] + mov sp, x9 + msr sp_el0, x1 + ret +ENDPROC(cpu_switch_to) +NOKPROBE(cpu_switch_to) + +/* + * This is how we return from a fork. + */ +ENTRY(ret_from_fork) + bl schedule_tail + cbz x19, 1f // not a kernel thread + mov x0, x20 + blr x19 +1: get_thread_info tsk + b ret_to_user +ENDPROC(ret_from_fork) +NOKPROBE(ret_from_fork) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 06da8ea16bbe5e150bb7330ab0049c7438b25f8d..5d547deb6996c0091c64f14de18b5b8a75c88ae4 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -17,16 +17,19 @@ * along with this program. If not, see . */ +#include #include #include #include #include +#include +#include #include #include -#include #include #include +#include #define FPEXC_IOF (1 << 0) #define FPEXC_DZF (1 << 1) @@ -62,6 +65,13 @@ * CPU currently contain the most recent userland FPSIMD state of the current * task. * + * In order to allow softirq handlers to use FPSIMD, kernel_neon_begin() may + * save the task's FPSIMD context back to task_struct from softirq context. + * To prevent this from racing with the manipulation of the task's FPSIMD state + * from task context and thereby corrupting the state, it is necessary to + * protect any manipulation of a task's fpsimd_state or TIF_FOREIGN_FPSTATE + * flag with local_bh_disable() unless softirqs are already masked. + * * For a certain task, the sequence may look something like this: * - the task gets scheduled in; if both the task's fpsimd_state.cpu field * contains the id of the current CPU, and the CPU's fpsimd_last_state per-cpu @@ -161,9 +171,14 @@ void fpsimd_flush_thread(void) { if (!system_supports_fpsimd()) return; + + local_bh_disable(); + memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); fpsimd_flush_task_state(current); set_thread_flag(TIF_FOREIGN_FPSTATE); + + local_bh_enable(); } /* @@ -174,10 +189,13 @@ void fpsimd_preserve_current_state(void) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) fpsimd_save_state(¤t->thread.fpsimd_state); - preempt_enable(); + + local_bh_enable(); } /* @@ -189,15 +207,18 @@ void fpsimd_restore_current_state(void) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { struct fpsimd_state *st = ¤t->thread.fpsimd_state; fpsimd_load_state(st); - this_cpu_write(fpsimd_last_state, st); + __this_cpu_write(fpsimd_last_state, st); st->cpu = smp_processor_id(); } - preempt_enable(); + + local_bh_enable(); } /* @@ -209,15 +230,18 @@ void fpsimd_update_current_state(struct fpsimd_state *state) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + fpsimd_load_state(state); if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { struct fpsimd_state *st = ¤t->thread.fpsimd_state; - this_cpu_write(fpsimd_last_state, st); + __this_cpu_write(fpsimd_last_state, st); st->cpu = smp_processor_id(); } - preempt_enable(); + + local_bh_enable(); } /* @@ -230,52 +254,126 @@ void fpsimd_flush_task_state(struct task_struct *t) #ifdef CONFIG_KERNEL_MODE_NEON -static DEFINE_PER_CPU(struct fpsimd_partial_state, hardirq_fpsimdstate); -static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate); +DEFINE_PER_CPU(bool, kernel_neon_busy); +EXPORT_PER_CPU_SYMBOL(kernel_neon_busy); /* * Kernel-side NEON support functions */ -void kernel_neon_begin_partial(u32 num_regs) + +/* + * kernel_neon_begin(): obtain the CPU FPSIMD registers for use by the calling + * context + * + * Must not be called unless may_use_simd() returns true. + * Task context in the FPSIMD registers is saved back to memory as necessary. + * + * A matching call to kernel_neon_end() must be made before returning from the + * calling context. + * + * The caller may freely use the FPSIMD registers until kernel_neon_end() is + * called. + */ +void kernel_neon_begin(void) { if (WARN_ON(!system_supports_fpsimd())) return; - if (in_interrupt()) { - struct fpsimd_partial_state *s = this_cpu_ptr( - in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); - BUG_ON(num_regs > 32); - fpsimd_save_partial_state(s, roundup(num_regs, 2)); - } else { - /* - * Save the userland FPSIMD state if we have one and if we - * haven't done so already. Clear fpsimd_last_state to indicate - * that there is no longer userland FPSIMD state in the - * registers. - */ - preempt_disable(); - if (current->mm && - !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) - fpsimd_save_state(¤t->thread.fpsimd_state); - this_cpu_write(fpsimd_last_state, NULL); - } + BUG_ON(!may_use_simd()); + + local_bh_disable(); + + __this_cpu_write(kernel_neon_busy, true); + + /* Save unsaved task fpsimd state, if any: */ + if (current->mm && !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) + fpsimd_save_state(¤t->thread.fpsimd_state); + + /* Invalidate any task state remaining in the fpsimd regs: */ + __this_cpu_write(fpsimd_last_state, NULL); + + preempt_disable(); + + local_bh_enable(); } -EXPORT_SYMBOL(kernel_neon_begin_partial); +EXPORT_SYMBOL(kernel_neon_begin); +/* + * kernel_neon_end(): give the CPU FPSIMD registers back to the current task + * + * Must be called from a context in which kernel_neon_begin() was previously + * called, with no call to kernel_neon_end() in the meantime. + * + * The caller must not use the FPSIMD registers after this function is called, + * unless kernel_neon_begin() is called again in the meantime. + */ void kernel_neon_end(void) { + bool busy; + if (!system_supports_fpsimd()) return; - if (in_interrupt()) { - struct fpsimd_partial_state *s = this_cpu_ptr( - in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); - fpsimd_load_partial_state(s); - } else { - preempt_enable(); - } + + busy = __this_cpu_xchg(kernel_neon_busy, false); + WARN_ON(!busy); /* No matching kernel_neon_begin()? */ + + preempt_enable(); } EXPORT_SYMBOL(kernel_neon_end); +#ifdef CONFIG_EFI + +static DEFINE_PER_CPU(struct fpsimd_state, efi_fpsimd_state); +static DEFINE_PER_CPU(bool, efi_fpsimd_state_used); + +/* + * EFI runtime services support functions + * + * The ABI for EFI runtime services allows EFI to use FPSIMD during the call. + * This means that for EFI (and only for EFI), we have to assume that FPSIMD + * is always used rather than being an optional accelerator. + * + * These functions provide the necessary support for ensuring FPSIMD + * save/restore in the contexts from which EFI is used. + * + * Do not use them for any other purpose -- if tempted to do so, you are + * either doing something wrong or you need to propose some refactoring. + */ + +/* + * __efi_fpsimd_begin(): prepare FPSIMD for making an EFI runtime services call + */ +void __efi_fpsimd_begin(void) +{ + if (!system_supports_fpsimd()) + return; + + WARN_ON(preemptible()); + + if (may_use_simd()) + kernel_neon_begin(); + else { + fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state)); + __this_cpu_write(efi_fpsimd_state_used, true); + } +} + +/* + * __efi_fpsimd_end(): clean up FPSIMD after an EFI runtime services call + */ +void __efi_fpsimd_end(void) +{ + if (!system_supports_fpsimd()) + return; + + if (__this_cpu_xchg(efi_fpsimd_state_used, false)) + fpsimd_load_state(this_cpu_ptr(&efi_fpsimd_state)); + else + kernel_neon_end(); +} + +#endif /* CONFIG_EFI */ + #endif /* CONFIG_KERNEL_MODE_NEON */ #ifdef CONFIG_CPU_PM @@ -346,4 +444,4 @@ static int __init fpsimd_init(void) return 0; } -late_initcall(fpsimd_init); +core_initcall(fpsimd_init); diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 973df7de7bf8d3e4fcde6dc2ba1590fa051964a2..0b243ecaf7ac87faa81fed0a09db996757d71f4e 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -143,8 +143,8 @@ preserve_boot_args: dmb sy // needed before dc ivac with // MMU off - add x1, x0, #0x20 // 4 x 8 bytes - b __inval_cache_range // tail call + mov x1, #0x20 // 4 x 8 bytes + b __inval_dcache_area // tail call ENDPROC(preserve_boot_args) /* @@ -221,20 +221,20 @@ __create_page_tables: * dirty cache lines being evicted. */ adrp x0, idmap_pg_dir - adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE - bl __inval_cache_range + ldr x1, =(IDMAP_DIR_SIZE + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE) + bl __inval_dcache_area /* * Clear the idmap and swapper page tables. */ adrp x0, idmap_pg_dir - adrp x6, swapper_pg_dir + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE + ldr x1, =(IDMAP_DIR_SIZE + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE) 1: stp xzr, xzr, [x0], #16 stp xzr, xzr, [x0], #16 stp xzr, xzr, [x0], #16 stp xzr, xzr, [x0], #16 - cmp x0, x6 - b.lo 1b + subs x1, x1, #64 + b.ne 1b mov x7, SWAPPER_MM_MMUFLAGS @@ -307,9 +307,9 @@ __create_page_tables: * tables again to remove any speculatively loaded cache lines. */ adrp x0, idmap_pg_dir - adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE + ldr x1, =(IDMAP_DIR_SIZE + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE) dmb sy - bl __inval_cache_range + bl __inval_dcache_area ret x28 ENDPROC(__create_page_tables) @@ -354,7 +354,6 @@ __primary_switched: tst x23, ~(MIN_KIMG_ALIGN - 1) // already running randomized? b.ne 0f mov x0, x21 // pass FDT address in x0 - mov x1, x23 // pass modulo offset in x1 bl kaslr_early_init // parse FDT for KASLR options cbz x0, 0f // KASLR disabled? just proceed orr x23, x23, x0 // record KASLR offset @@ -362,6 +361,9 @@ __primary_switched: ret // to __primary_switch() 0: #endif + add sp, sp, #16 + mov x29, #0 + mov x30, #0 b start_kernel ENDPROC(__primary_switched) @@ -382,6 +384,7 @@ ENTRY(kimage_vaddr) * booted in EL1 or EL2 respectively. */ ENTRY(el2_setup) + msr SPsel, #1 // We want to use SP_EL{1,2} mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq 1f @@ -617,6 +620,7 @@ __secondary_switched: ldr x2, [x0, #CPU_BOOT_TASK] msr sp_el0, x2 mov x29, #0 + mov x30, #0 b secondary_start_kernel ENDPROC(__secondary_switched) diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index a44e13942d30540ba8f55470a0cfebe362fd4992..095d3c170f5d2e44eb1f849009ef3b658bb2c667 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -330,7 +330,7 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) * read only (code, rodata). Clear the RDONLY bit from * the temporary mappings we use during restore. */ - set_pte(dst_pte, pte_clear_rdonly(pte)); + set_pte(dst_pte, pte_mkwrite(pte)); } else if (debug_pagealloc_enabled() && !pte_none(pte)) { /* * debug_pagealloc will removed the PTE_VALID bit if @@ -343,7 +343,7 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) */ BUG_ON(!pfn_valid(pte_pfn(pte))); - set_pte(dst_pte, pte_mkpresent(pte_clear_rdonly(pte))); + set_pte(dst_pte, pte_mkpresent(pte_mkwrite(pte))); } } diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 2386b26c071274d4d563a4fdc5e864aedda37204..713561e5bcabc5467e2d86c9d88ec75be2c34a44 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -23,15 +23,16 @@ #include #include +#include #include #include #include #include +#include unsigned long irq_err_count; -/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */ -DEFINE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack) __aligned(16); +DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); int arch_show_interrupts(struct seq_file *p, int prec) { @@ -50,8 +51,43 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) handle_arch_irq = handle_irq; } +#ifdef CONFIG_VMAP_STACK +static void init_irq_stacks(void) +{ + int cpu; + unsigned long *p; + + for_each_possible_cpu(cpu) { + /* + * To ensure that VMAP'd stack overflow detection works + * correctly, the IRQ stacks need to have the same + * alignment as other stacks. + */ + p = __vmalloc_node_range(IRQ_STACK_SIZE, THREAD_ALIGN, + VMALLOC_START, VMALLOC_END, + THREADINFO_GFP, PAGE_KERNEL, + 0, cpu_to_node(cpu), + __builtin_return_address(0)); + + per_cpu(irq_stack_ptr, cpu) = p; + } +} +#else +/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */ +DEFINE_PER_CPU_ALIGNED(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); + +static void init_irq_stacks(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu); +} +#endif + void __init init_IRQ(void) { + init_irq_stacks(); irqchip_init(); if (!handle_arch_irq) panic("No interrupt controller found."); diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c index a9710efb8c017a735f9aa6518463d11b8d6264c9..47080c49cc7e77a3df120f061f7b10f90a8c2ec5 100644 --- a/arch/arm64/kernel/kaslr.c +++ b/arch/arm64/kernel/kaslr.c @@ -75,7 +75,7 @@ extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, * containing function pointers) to be reinitialized, and zero-initialized * .bss variables will be reset to 0. */ -u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset) +u64 __init kaslr_early_init(u64 dt_phys) { void *fdt; u64 seed, offset, mask, module_range; @@ -131,15 +131,17 @@ u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset) /* * The kernel Image should not extend across a 1GB/32MB/512MB alignment * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this - * happens, increase the KASLR offset by the size of the kernel image - * rounded up by SWAPPER_BLOCK_SIZE. + * happens, round down the KASLR offset by (1 << SWAPPER_TABLE_SHIFT). + * + * NOTE: The references to _text and _end below will already take the + * modulo offset (the physical displacement modulo 2 MB) into + * account, given that the physical placement is controlled by + * the loader, and will not change as a result of the virtual + * mapping we choose. */ - if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) != - (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) { - u64 kimg_sz = _end - _text; - offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE)) - & mask; - } + if ((((u64)_text + offset) >> SWAPPER_TABLE_SHIFT) != + (((u64)_end + offset) >> SWAPPER_TABLE_SHIFT)) + offset = round_down(offset, 1 << SWAPPER_TABLE_SHIFT); if (IS_ENABLED(CONFIG_KASAN)) /* diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index 481f54a866c535d8e0cd1cb4bc89d357436c8b1b..11121f608eb52718a3f490bb0eddec83486493ad 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -252,7 +252,7 @@ void machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); /* shutdown non-crashing cpus */ - smp_send_crash_stop(); + crash_smp_send_stop(); /* for crashing cpu */ crash_save_cpu(regs, smp_processor_id()); diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index e2b7e4f9cc3180d7a1059cb4983c3739ca4be19c..0e2ea1c785427849b68435eb1c188e8b7d65eb64 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -22,23 +22,6 @@ #include #include -/* - * Called after each bus is probed, but before its children are examined - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* nothing to do, expected to be removed in the future */ -} - -/* - * We don't have to worry about legacy ISA devices, so nothing to do here - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - #ifdef CONFIG_ACPI /* * Try to assign the IRQ number when probing a new device diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c index 713ca824f266a7fa771b3609ec8dec5264eef3ed..bcafd7dcfe8b186c07c1f7138ca4dc62035aa61e 100644 --- a/arch/arm64/kernel/perf_callchain.c +++ b/arch/arm64/kernel/perf_callchain.c @@ -162,7 +162,6 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, } frame.fp = regs->regs[29]; - frame.sp = regs->sp; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = current->curr_ret_stack; diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index b5798ba211895aafe598425d5b9fa45293b3cc2d..9eaef51f83ff8d0ad7c15f54e84db43b14d5fbb3 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -202,55 +202,6 @@ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, }; -/* ARM Cortex-A53 HW events mapping. */ -static const unsigned armv8_a53_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, -}; - -/* ARM Cortex-A57 and Cortex-A72 events mapping. */ -static const unsigned armv8_a57_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, -}; - -static const unsigned armv8_thunder_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, -}; - -/* Broadcom Vulcan events mapping */ -static const unsigned armv8_vulcan_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_BR_RETIRED, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, -}; - static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { @@ -281,27 +232,10 @@ static const unsigned armv8_a53_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { PERF_CACHE_MAP_ALL_UNSUPPORTED, - [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_A53_PERFCTR_PREF_LINEFILL, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, - - [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE, - [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL, - [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE, - [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL, - - [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL, - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, - - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, }; static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -314,18 +248,26 @@ static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, - [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR, - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, +}; - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, +static const unsigned armv8_a73_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + PERF_CACHE_MAP_ALL_UNSUPPORTED, + + [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD, + [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, + + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, + + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, }; static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -340,8 +282,6 @@ static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1D_CACHE_PREF_ACCESS, [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1D_CACHE_PREF_MISS, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_ACCESS, [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_MISS, @@ -349,13 +289,6 @@ static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR, [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR, - - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, - - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, }; static const unsigned armv8_vulcan_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -368,22 +301,11 @@ static const unsigned armv8_vulcan_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, - - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, - [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB, - [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR, [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR, - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, }; @@ -846,17 +768,14 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, struct hw_perf_event *hwc = &event->hw; unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT; - /* Always place a cycle counter into the cycle counter. */ + /* Always prefer to place a cycle counter into the cycle counter. */ if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { - if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) - return -EAGAIN; - - return ARMV8_IDX_CYCLE_COUNTER; + if (!test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) + return ARMV8_IDX_CYCLE_COUNTER; } /* - * For anything other than a cycle counter, try and use - * the events counters + * Otherwise use events counters */ for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) { if (!test_and_set_bit(idx, cpuc->used_mask)) @@ -924,7 +843,13 @@ static void armv8pmu_reset(void *info) ARMV8_PMU_PMCR_LC); } -static int armv8_pmuv3_map_event(struct perf_event *event) +static int __armv8_pmuv3_map_event(struct perf_event *event, + const unsigned (*extra_event_map) + [PERF_COUNT_HW_MAX], + const unsigned (*extra_cache_map) + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX]) { int hw_event_id; struct arm_pmu *armpmu = to_arm_pmu(event->pmu); @@ -932,44 +857,47 @@ static int armv8_pmuv3_map_event(struct perf_event *event) hw_event_id = armpmu_map_event(event, &armv8_pmuv3_perf_map, &armv8_pmuv3_perf_cache_map, ARMV8_PMU_EVTYPE_EVENT); - if (hw_event_id < 0) - return hw_event_id; - /* disable micro/arch events not supported by this PMU */ - if ((hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS) && - !test_bit(hw_event_id, armpmu->pmceid_bitmap)) { - return -EOPNOTSUPP; + /* Onl expose micro/arch events supported by this PMU */ + if ((hw_event_id > 0) && (hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS) + && test_bit(hw_event_id, armpmu->pmceid_bitmap)) { + return hw_event_id; } - return hw_event_id; + return armpmu_map_event(event, extra_event_map, extra_cache_map, + ARMV8_PMU_EVTYPE_EVENT); +} + +static int armv8_pmuv3_map_event(struct perf_event *event) +{ + return __armv8_pmuv3_map_event(event, NULL, NULL); } static int armv8_a53_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_a53_perf_map, - &armv8_a53_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, &armv8_a53_perf_cache_map); } static int armv8_a57_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_a57_perf_map, - &armv8_a57_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, &armv8_a57_perf_cache_map); +} + +static int armv8_a73_map_event(struct perf_event *event) +{ + return __armv8_pmuv3_map_event(event, NULL, &armv8_a73_perf_cache_map); } static int armv8_thunder_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_thunder_perf_map, - &armv8_thunder_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, + &armv8_thunder_perf_cache_map); } static int armv8_vulcan_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_vulcan_perf_map, - &armv8_vulcan_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, + &armv8_vulcan_perf_cache_map); } struct armv8pmu_probe_info { @@ -1062,6 +990,22 @@ static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu) return 0; } +static int armv8_a35_pmu_init(struct arm_pmu *cpu_pmu) +{ + int ret = armv8_pmu_init(cpu_pmu); + if (ret) + return ret; + + cpu_pmu->name = "armv8_cortex_a35"; + cpu_pmu->map_event = armv8_a53_map_event; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = + &armv8_pmuv3_events_attr_group; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = + &armv8_pmuv3_format_attr_group; + + return 0; +} + static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu) { int ret = armv8_pmu_init(cpu_pmu); @@ -1110,6 +1054,22 @@ static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu) return 0; } +static int armv8_a73_pmu_init(struct arm_pmu *cpu_pmu) +{ + int ret = armv8_pmu_init(cpu_pmu); + if (ret) + return ret; + + cpu_pmu->name = "armv8_cortex_a73"; + cpu_pmu->map_event = armv8_a73_map_event; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = + &armv8_pmuv3_events_attr_group; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = + &armv8_pmuv3_format_attr_group; + + return 0; +} + static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu) { int ret = armv8_pmu_init(cpu_pmu); @@ -1144,9 +1104,11 @@ static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu) static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init}, + {.compatible = "arm,cortex-a35-pmu", .data = armv8_a35_pmu_init}, {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init}, {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init}, {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init}, + {.compatible = "arm,cortex-a73-pmu", .data = armv8_a73_pmu_init}, {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init}, {}, diff --git a/arch/arm64/kernel/probes/uprobes.c b/arch/arm64/kernel/probes/uprobes.c index 26c998534dca9a545d006ba5a637a7c1dd24aa52..636ca0119c0efa7cb1254568d04edfdddf791db9 100644 --- a/arch/arm64/kernel/probes/uprobes.c +++ b/arch/arm64/kernel/probes/uprobes.c @@ -40,7 +40,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, probe_opcode_t insn; /* TODO: Currently we do not support AARCH32 instruction probing */ - if (test_bit(TIF_32BIT, &mm->context.flags)) + if (mm->context.flags & MMCF_AARCH32) return -ENOTSUPP; else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) return -EINVAL; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 659ae8094ed5b1bc3f0f1ae6c6b4297062725864..2dc0f84822109b542e21d71deba5206b624f4fc6 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -360,6 +360,8 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, /* * Complete any pending TLB or cache maintenance on this CPU in case * the thread migrates to a different CPU. + * This full barrier is also required by the membarrier system + * call. */ dsb(ish); @@ -382,15 +384,12 @@ unsigned long get_wchan(struct task_struct *p) return 0; frame.fp = thread_saved_fp(p); - frame.sp = thread_saved_sp(p); frame.pc = thread_saved_pc(p); #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = p->curr_ret_stack; #endif do { - if (frame.sp < stack_page || - frame.sp >= stack_page + THREAD_SIZE || - unwind_frame(p, &frame)) + if (unwind_frame(p, &frame)) goto out; if (!in_sched_functions(frame.pc)) { ret = frame.pc; @@ -417,3 +416,11 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) else return randomize_page(mm->brk, SZ_1G); } + +/* + * Called from setup_new_exec() after (COMPAT_)SET_PERSONALITY. + */ +void arch_setup_new_exec(void) +{ + current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0; +} diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 1b38c0150aec6f034289b5e1faead0727f8f5056..9cbb6123208f8dd4164fa90316a12bbf05489c13 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,7 @@ static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) { return ((addr & ~(THREAD_SIZE - 1)) == (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))) || - on_irq_stack(addr, raw_smp_processor_id()); + on_irq_stack(addr); } /** @@ -1363,7 +1364,7 @@ static void tracehook_report_syscall(struct pt_regs *regs, if (dir == PTRACE_SYSCALL_EXIT) tracehook_report_syscall_exit(regs, 0); else if (tracehook_report_syscall_entry(regs)) - regs->syscallno = ~0UL; + forget_syscall(regs); regs->regs[regno] = saved_reg; } diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c index 12a87f2600f2f65d03799a44402eabda5024277e..933adbc0f654d84e2e7331a93455ee74c747a091 100644 --- a/arch/arm64/kernel/return_address.c +++ b/arch/arm64/kernel/return_address.c @@ -42,7 +42,6 @@ void *return_address(unsigned int level) data.addr = NULL; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; frame.pc = (unsigned long)return_address; /* dummy */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = current->curr_ret_stack; diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 089c3747995dc40b726fbe9f53450ddb5c350f95..0bdc96c61bc0f2b14f627142a2778409c9c6a7d0 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include @@ -387,7 +389,7 @@ static int restore_sigframe(struct pt_regs *regs, /* * Avoid sys_rt_sigreturn() restarting. */ - regs->syscallno = ~0UL; + forget_syscall(regs); err |= !valid_user_regs(®s->user_regs, current); if (err == 0) @@ -673,13 +675,12 @@ static void do_signal(struct pt_regs *regs) { unsigned long continue_addr = 0, restart_addr = 0; int retval = 0; - int syscall = (int)regs->syscallno; struct ksignal ksig; /* * If we were from a system call, check for system call restarting... */ - if (syscall >= 0) { + if (in_syscall(regs)) { continue_addr = regs->pc; restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); retval = regs->regs[0]; @@ -687,7 +688,7 @@ static void do_signal(struct pt_regs *regs) /* * Avoid additional syscall restarting via ret_to_user. */ - regs->syscallno = ~0UL; + forget_syscall(regs); /* * Prepare for system call restart. We do this here so that a @@ -731,7 +732,7 @@ static void do_signal(struct pt_regs *regs) * Handle restarting a different system call. As above, if a debugger * has chosen to restart at a different PC, ignore the restart. */ - if (syscall >= 0 && regs->pc == restart_addr) { + if (in_syscall(regs) && regs->pc == restart_addr) { if (retval == -ERESTART_RESTARTBLOCK) setup_restart_syscall(regs); user_rewind_single_step(current); @@ -749,7 +750,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, * Update the trace code with the current status. */ trace_hardirqs_off(); + do { + /* Check valid user FS if needed */ + addr_limit_user_check(); + if (thread_flags & _TIF_NEED_RESCHED) { schedule(); } else { diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index c747a0fc5d7d174d59d0470127f35f6354fa5aaf..e09bf5d1560606405e25175d69d8b67929f02657 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -142,25 +142,25 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); - else switch (from->si_code & __SI_MASK) { - case __SI_KILL: + else switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_TIMER: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_POLL: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_FAULT: + case SIL_FAULT: err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr, &to->si_addr); #ifdef BUS_MCEERR_AO @@ -173,29 +173,24 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); #endif break; - case __SI_CHLD: + case SIL_CHLD: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_status, &to->si_status); err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: /* But this is */ + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_SYS: + case SIL_SYS: err |= __put_user((compat_uptr_t)(unsigned long) from->si_call_addr, &to->si_call_addr); err |= __put_user(from->si_syscall, &to->si_syscall); err |= __put_user(from->si_arch, &to->si_arch); break; - default: /* this is just in case for now ... */ - err |= __put_user(from->si_pid, &to->si_pid); - err |= __put_user(from->si_uid, &to->si_uid); - break; } return err; } @@ -354,7 +349,7 @@ static int compat_restore_sigframe(struct pt_regs *regs, /* * Avoid compat_sys_sigreturn() restarting. */ - regs->syscallno = ~0UL; + forget_syscall(regs); err |= !valid_user_regs(®s->user_regs, current); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index dc66e6ec3a99dfe9e91d83f1cde2cec8ff225863..9f7195a5773ee66138bc5170508f8c251f501e47 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -154,7 +154,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) * page tables. */ secondary_data.task = idle; - secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; + secondary_data.stack = task_stack_page(idle) + THREAD_SIZE; update_cpu_boot_status(CPU_MMU_OFF); __flush_dcache_area(&secondary_data, sizeof(secondary_data)); @@ -690,7 +690,7 @@ void __init smp_init_cpus(void) acpi_parse_gic_cpu_interface, 0); if (cpu_count > nr_cpu_ids) - pr_warn("Number of cores (%d) exceeds configured maximum of %d - clipping\n", + pr_warn("Number of cores (%d) exceeds configured maximum of %u - clipping\n", cpu_count, nr_cpu_ids); if (!bootcpu_valid) { @@ -977,11 +977,21 @@ void smp_send_stop(void) } #ifdef CONFIG_KEXEC_CORE -void smp_send_crash_stop(void) +void crash_smp_send_stop(void) { + static int cpus_stopped; cpumask_t mask; unsigned long timeout; + /* + * This function can be called twice in panic path, but obviously + * we execute this only once. + */ + if (cpus_stopped) + return; + + cpus_stopped = 1; + if (num_online_cpus() == 1) return; diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 09d37d66b6301abee1852bb0aead091fa1157098..76809ccd309ccaf330e45ac4b814922ae5949624 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -42,33 +42,17 @@ */ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) { - unsigned long high, low; unsigned long fp = frame->fp; - unsigned long irq_stack_ptr; + + if (fp & 0xf) + return -EINVAL; if (!tsk) tsk = current; - /* - * Switching between stacks is valid when tracing current and in - * non-preemptible context. - */ - if (tsk == current && !preemptible()) - irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); - else - irq_stack_ptr = 0; - - low = frame->sp; - /* irq stacks are not THREAD_SIZE aligned */ - if (on_irq_stack(frame->sp, raw_smp_processor_id())) - high = irq_stack_ptr; - else - high = ALIGN(low, THREAD_SIZE) - 0x20; - - if (fp < low || fp > high || fp & 0xf) + if (!on_accessible_stack(tsk, fp)) return -EINVAL; - frame->sp = fp + 0x10; frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8)); @@ -86,34 +70,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ /* - * Check whether we are going to walk through from interrupt stack - * to task stack. - * If we reach the end of the stack - and its an interrupt stack, - * unpack the dummy frame to find the original elr. - * - * Check the frame->fp we read from the bottom of the irq_stack, - * and the original task stack pointer are both in current->stack. + * Frames created upon entry from EL0 have NULL FP and PC values, so + * don't bother reporting these. Frames created by __noreturn functions + * might have a valid FP even if PC is bogus, so only terminate where + * both are NULL. */ - if (frame->sp == irq_stack_ptr) { - struct pt_regs *irq_args; - unsigned long orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); - - if (object_is_on_stack((void *)orig_sp) && - object_is_on_stack((void *)frame->fp)) { - frame->sp = orig_sp; - - /* orig_sp is the saved pt_regs, find the elr */ - irq_args = (struct pt_regs *)orig_sp; - frame->pc = irq_args->pc; - } else { - /* - * This frame has a non-standard format, and we - * didn't fix it, because the data looked wrong. - * Refuse to output this frame. - */ - return -EINVAL; - } - } + if (!frame->fp && !frame->pc) + return -EINVAL; return 0; } @@ -167,7 +130,6 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) data.no_sched_functions = 0; frame.fp = regs->regs[29]; - frame.sp = regs->sp; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = current->curr_ret_stack; @@ -178,7 +140,8 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) trace->entries[trace->nr_entries++] = ULONG_MAX; } -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +static noinline void __save_stack_trace(struct task_struct *tsk, + struct stack_trace *trace, unsigned int nosched) { struct stack_trace_data data; struct stackframe frame; @@ -188,17 +151,16 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) data.trace = trace; data.skip = trace->skip; + data.no_sched_functions = nosched; if (tsk != current) { - data.no_sched_functions = 1; frame.fp = thread_saved_fp(tsk); - frame.sp = thread_saved_sp(tsk); frame.pc = thread_saved_pc(tsk); } else { - data.no_sched_functions = 0; + /* We don't want this function nor the caller */ + data.skip += 2; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; - frame.pc = (unsigned long)save_stack_trace_tsk; + frame.pc = (unsigned long)__save_stack_trace; } #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = tsk->curr_ret_stack; @@ -212,9 +174,15 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + __save_stack_trace(tsk, trace, 1); +} + void save_stack_trace(struct stack_trace *trace) { - save_stack_trace_tsk(current, trace); + __save_stack_trace(current, trace, 0); } + EXPORT_SYMBOL_GPL(save_stack_trace); #endif diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c index da33c90248e98eaf1e14a6a0e0061ccddad21420..a4391280fba9631d69cf8bda434c307956b92668 100644 --- a/arch/arm64/kernel/time.c +++ b/arch/arm64/kernel/time.c @@ -50,7 +50,6 @@ unsigned long profile_pc(struct pt_regs *regs) return regs->pc; frame.fp = regs->regs[29]; - frame.sp = regs->sp; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = -1; /* no task info */ diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index d48f470802136e17dfc7ec83be568b8e913e6cf4..5ea4b85aee0e96e93c80a7aca339ffb2e987a53e 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -143,7 +145,6 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - unsigned long irq_stack_ptr; int skip; pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); @@ -154,25 +155,14 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) if (!try_get_task_stack(tsk)) return; - /* - * Switching between stacks is valid when tracing current and in - * non-preemptible context. - */ - if (tsk == current && !preemptible()) - irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); - else - irq_stack_ptr = 0; - if (tsk == current) { frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; frame.pc = (unsigned long)dump_backtrace; } else { /* * task blocked in __switch_to */ frame.fp = thread_saved_fp(tsk); - frame.sp = thread_saved_sp(tsk); frame.pc = thread_saved_pc(tsk); } #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -182,13 +172,12 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) skip = !!regs; printk("Call trace:\n"); while (1) { - unsigned long where = frame.pc; unsigned long stack; int ret; /* skip until specified stack frame */ if (!skip) { - dump_backtrace_entry(where); + dump_backtrace_entry(frame.pc); } else if (frame.fp == regs->regs[29]) { skip = 0; /* @@ -203,20 +192,12 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) ret = unwind_frame(tsk, &frame); if (ret < 0) break; - stack = frame.sp; - if (in_exception_text(where)) { - /* - * If we switched to the irq_stack before calling this - * exception handler, then the pt_regs will be on the - * task stack. The easiest way to tell is if the large - * pt_regs would overlap with the end of the irq_stack. - */ - if (stack < irq_stack_ptr && - (stack + sizeof(struct pt_regs)) > irq_stack_ptr) - stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); + if (in_entry_text(frame.pc)) { + stack = frame.fp - offsetof(struct pt_regs, stackframe); - dump_mem("", "Exception stack", stack, - stack + sizeof(struct pt_regs)); + if (on_accessible_stack(tsk, stack)) + dump_mem("", "Exception stack", stack, + stack + sizeof(struct pt_regs)); } } @@ -257,8 +238,6 @@ static int __die(const char *str, int err, struct pt_regs *regs) end_of_stack(tsk)); if (!user_mode(regs)) { - dump_mem(KERN_EMERG, "Stack: ", regs->sp, - THREAD_SIZE + (unsigned long)task_stack_page(tsk)); dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); } @@ -484,6 +463,9 @@ static void user_cache_maint_handler(unsigned int esr, struct pt_regs *regs) case ESR_ELx_SYS64_ISS_CRM_DC_CVAC: /* DC CVAC, gets promoted */ __user_cache_maint("dc civac", address, ret); break; + case ESR_ELx_SYS64_ISS_CRM_DC_CVAP: /* DC CVAP */ + __user_cache_maint("sys 3, c7, c12, 1", address, ret); + break; case ESR_ELx_SYS64_ISS_CRM_DC_CIVAC: /* DC CIVAC */ __user_cache_maint("dc civac", address, ret); break; @@ -523,7 +505,7 @@ static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs) { int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; - pt_regs_write_reg(regs, rt, read_sysreg(cntfrq_el0)); + pt_regs_write_reg(regs, rt, arch_timer_get_rate()); regs->pc += 4; } @@ -593,7 +575,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) if (show_unhandled_signals_ratelimited()) { pr_info("%s[%d]: syscall %d\n", current->comm, - task_pid_nr(current), (int)regs->syscallno); + task_pid_nr(current), regs->syscallno); dump_instr("", regs); if (user_mode(regs)) __show_regs(regs); @@ -689,6 +671,43 @@ asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) force_sig_info(info.si_signo, &info, current); } +#ifdef CONFIG_VMAP_STACK + +DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack) + __aligned(16); + +asmlinkage void handle_bad_stack(struct pt_regs *regs) +{ + unsigned long tsk_stk = (unsigned long)current->stack; + unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr); + unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack); + unsigned int esr = read_sysreg(esr_el1); + unsigned long far = read_sysreg(far_el1); + + console_verbose(); + pr_emerg("Insufficient stack space to handle exception!"); + + pr_emerg("ESR: 0x%08x -- %s\n", esr, esr_get_class_string(esr)); + pr_emerg("FAR: 0x%016lx\n", far); + + pr_emerg("Task stack: [0x%016lx..0x%016lx]\n", + tsk_stk, tsk_stk + THREAD_SIZE); + pr_emerg("IRQ stack: [0x%016lx..0x%016lx]\n", + irq_stk, irq_stk + THREAD_SIZE); + pr_emerg("Overflow stack: [0x%016lx..0x%016lx]\n", + ovf_stk, ovf_stk + OVERFLOW_STACK_SIZE); + + __show_regs(regs); + + /* + * We use nmi_panic to limit the potential for recusive overflows, and + * to get a better stack trace. + */ + nmi_panic(NULL, "kernel stack overflow"); + cpu_park_loop(); +} +#endif + void __pte_error(const char *file, int line, unsigned long val) { pr_err("%s:%d: bad pte %016lx.\n", file, line, val); diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index e8f759f764f21cb7ee0c1b350cb9b54f4d0815e2..2d419006ad4330c5a76cb0cf9372fdb0c76cf279 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -110,12 +110,27 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) } #endif /* CONFIG_COMPAT */ +static int vdso_mremap(const struct vm_special_mapping *sm, + struct vm_area_struct *new_vma) +{ + unsigned long new_size = new_vma->vm_end - new_vma->vm_start; + unsigned long vdso_size = vdso_end - vdso_start; + + if (vdso_size != new_size) + return -EINVAL; + + current->mm->context.vdso = (void *)new_vma->vm_start; + + return 0; +} + static struct vm_special_mapping vdso_spec[2] __ro_after_init = { { .name = "[vvar]", }, { .name = "[vdso]", + .mremap = vdso_mremap, }, }; diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 987a00ee446c6af321f480840aed59c3bd553cf5..fe56c268a7d9c37374f8126cae0af243adace762 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -72,22 +72,6 @@ PECOFF_FILE_ALIGNMENT = 0x200; #define PECOFF_EDATA_PADDING #endif -#if defined(CONFIG_DEBUG_ALIGN_RODATA) -/* - * 4 KB granule: 1 level 2 entry - * 16 KB granule: 128 level 3 entries, with contiguous bit - * 64 KB granule: 32 level 3 entries, with contiguous bit - */ -#define SEGMENT_ALIGN SZ_2M -#else -/* - * 4 KB granule: 16 level 3 entries, with contiguous bit - * 16 KB granule: 4 level 3 entries, without contiguous bit - * 64 KB granule: 1 level 3 entry - */ -#define SEGMENT_ALIGN SZ_64K -#endif - SECTIONS { /* @@ -192,7 +176,7 @@ SECTIONS _data = .; _sdata = .; - RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) + RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) /* * Data written with the MMU off but read with the MMU on requires diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 17d8a1677a0b34baf4356bf09b0a809cf0a8e58d..7debb74843a053bfdec33cb69326f3f3d0968297 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -84,7 +84,7 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) if (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WFx_ISS_WFE) { trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true); vcpu->stat.wfe_exit_stat++; - kvm_vcpu_on_spin(vcpu); + kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu)); } else { trace_kvm_wfx_arm64(*vcpu_pc(vcpu), false); vcpu->stat.wfi_exit_stat++; diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c index b81f4091c909ce1e2650986648cdde1e2d1a23d0..a81f5e10fc8c14d20d6d76a78dde74c368ce7ef8 100644 --- a/arch/arm64/kvm/hyp/s2-setup.c +++ b/arch/arm64/kvm/hyp/s2-setup.c @@ -70,7 +70,7 @@ u32 __hyp_text __init_stage2_translation(void) * Management in ID_AA64MMFR1_EL1 and enable the feature in VTCR_EL2. */ tmp = (read_sysreg(id_aa64mmfr1_el1) >> ID_AA64MMFR1_HADBS_SHIFT) & 0xf; - if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && tmp) + if (tmp) val |= VTCR_EL2_HA; /* diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 77862881ae860943b2f2553dbbd93c65b64102ab..2e070d3baf9f12db1363ed95d079b19b02ca0382 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -764,7 +764,7 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, if (p->is_write) { if (r->CRm & 0x2) /* accessing PMOVSSET_EL0 */ - kvm_pmu_overflow_set(vcpu, p->regval & mask); + vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= (p->regval & mask); else /* accessing PMOVSCLR_EL0 */ vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask); diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c index 116786d2e8e8fdbe7c2dfc4056b87918e4bf25bf..c77d508b74620e0d5c5868a542346efff9f70ab9 100644 --- a/arch/arm64/kvm/vgic-sys-reg-v3.c +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c @@ -208,29 +208,12 @@ static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu, static bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r, u8 apr) { - struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; u8 idx = r->Op2 & 3; - /* - * num_pri_bits are initialized with HW supported values. - * We can rely safely on num_pri_bits even if VM has not - * restored ICC_CTLR_EL1 before restoring APnR registers. - */ - switch (vgic_v3_cpu->num_pri_bits) { - case 7: - vgic_v3_access_apr_reg(vcpu, p, apr, idx); - break; - case 6: - if (idx > 1) - goto err; - vgic_v3_access_apr_reg(vcpu, p, apr, idx); - break; - default: - if (idx > 0) - goto err; - vgic_v3_access_apr_reg(vcpu, p, apr, idx); - } + if (idx > vgic_v3_max_apr_idx(vcpu)) + goto err; + vgic_v3_access_apr_reg(vcpu, p, apr, idx); return true; err: if (!p->is_write) diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index c86b7909ef312009028c46ba83b375b544d9ae84..a0abc142c92be627e8237b69017945a6fa0f2265 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile @@ -17,3 +17,5 @@ CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2 \ -fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12 \ -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \ -fcall-saved-x18 + +lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o diff --git a/arch/arm64/lib/uaccess_flushcache.c b/arch/arm64/lib/uaccess_flushcache.c new file mode 100644 index 0000000000000000000000000000000000000000..b6ceafdb8b72fc622d6a00ec208ae3e95ba63cb8 --- /dev/null +++ b/arch/arm64/lib/uaccess_flushcache.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +void memcpy_flushcache(void *dst, const void *src, size_t cnt) +{ + /* + * We assume this should not be called with @dst pointing to + * non-cacheable memory, such that we don't need an explicit + * barrier to order the cache maintenance against the memcpy. + */ + memcpy(dst, src, cnt); + __clean_dcache_area_pop(dst, cnt); +} +EXPORT_SYMBOL_GPL(memcpy_flushcache); + +void memcpy_page_flushcache(char *to, struct page *page, size_t offset, + size_t len) +{ + memcpy_flushcache(to, page_address(page) + offset, len); +} + +unsigned long __copy_user_flushcache(void *to, const void __user *from, + unsigned long n) +{ + unsigned long rc = __arch_copy_from_user(to, from, n); + + /* See above */ + __clean_dcache_area_pop(to, n - rc); + return rc; +} diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S index 83c27b6e6dca31007d3b9ae5bc1c48d66456e757..7f1dbe962cf581c88eb488f01636f78996b4ee43 100644 --- a/arch/arm64/mm/cache.S +++ b/arch/arm64/mm/cache.S @@ -109,20 +109,25 @@ ENTRY(__clean_dcache_area_pou) ENDPROC(__clean_dcache_area_pou) /* - * __dma_inv_area(start, size) - * - start - virtual start address of region + * __inval_dcache_area(kaddr, size) + * + * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * are invalidated. Any partial lines at the ends of the interval are + * also cleaned to PoC to prevent data loss. + * + * - kaddr - kernel address * - size - size in question */ -__dma_inv_area: - add x1, x1, x0 +ENTRY(__inval_dcache_area) /* FALLTHROUGH */ /* - * __inval_cache_range(start, end) - * - start - start address of region - * - end - end address of region + * __dma_inv_area(start, size) + * - start - virtual start address of region + * - size - size in question */ -ENTRY(__inval_cache_range) +__dma_inv_area: + add x1, x1, x0 dcache_line_size x2, x3 sub x3, x2, #1 tst x1, x3 // end cache line aligned? @@ -140,7 +145,7 @@ ENTRY(__inval_cache_range) b.lo 2b dsb sy ret -ENDPIPROC(__inval_cache_range) +ENDPIPROC(__inval_dcache_area) ENDPROC(__dma_inv_area) /* @@ -166,6 +171,20 @@ __dma_clean_area: ENDPIPROC(__clean_dcache_area_poc) ENDPROC(__dma_clean_area) +/* + * __clean_dcache_area_pop(kaddr, size) + * + * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * are cleaned to the PoP. + * + * - kaddr - kernel address + * - size - size in question + */ +ENTRY(__clean_dcache_area_pop) + dcache_by_line_op cvap, sy, x0, x1, x2, x3 + ret +ENDPIPROC(__clean_dcache_area_pop) + /* * __dma_flush_area(start, size) * diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index f27d4dd043848dc8775a52588cffa7e27bd006a6..614af886b7ef4f7348470f8746ea822e8665401a 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -42,7 +42,7 @@ static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, return prot; } -static struct gen_pool *atomic_pool; +static struct gen_pool *atomic_pool __ro_after_init; #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; @@ -425,7 +425,7 @@ static int __init atomic_pool_init(void) gen_pool_set_algo(atomic_pool, gen_pool_first_fit_order_align, - (void *)PAGE_SHIFT); + NULL); pr_info("DMA: preallocated %zu KiB pool for atomic allocations\n", atomic_pool_size / 1024); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index c7861c9864e69e7b6dc7efc16083063bbab99e98..b64958b23a7fa193c23dd1a9039f69f4e9f0b863 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,49 @@ static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) } #endif +static void data_abort_decode(unsigned int esr) +{ + pr_alert("Data abort info:\n"); + + if (esr & ESR_ELx_ISV) { + pr_alert(" Access size = %u byte(s)\n", + 1U << ((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT)); + pr_alert(" SSE = %lu, SRT = %lu\n", + (esr & ESR_ELx_SSE) >> ESR_ELx_SSE_SHIFT, + (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT); + pr_alert(" SF = %lu, AR = %lu\n", + (esr & ESR_ELx_SF) >> ESR_ELx_SF_SHIFT, + (esr & ESR_ELx_AR) >> ESR_ELx_AR_SHIFT); + } else { + pr_alert(" ISV = 0, ISS = 0x%08lx\n", esr & ESR_ELx_ISS_MASK); + } + + pr_alert(" CM = %lu, WnR = %lu\n", + (esr & ESR_ELx_CM) >> ESR_ELx_CM_SHIFT, + (esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT); +} + +/* + * Decode mem abort information + */ +static void mem_abort_decode(unsigned int esr) +{ + pr_alert("Mem abort info:\n"); + + pr_alert(" Exception class = %s, IL = %u bits\n", + esr_get_class_string(esr), + (esr & ESR_ELx_IL) ? 32 : 16); + pr_alert(" SET = %lu, FnV = %lu\n", + (esr & ESR_ELx_SET_MASK) >> ESR_ELx_SET_SHIFT, + (esr & ESR_ELx_FnV) >> ESR_ELx_FnV_SHIFT); + pr_alert(" EA = %lu, S1PTW = %lu\n", + (esr & ESR_ELx_EA) >> ESR_ELx_EA_SHIFT, + (esr & ESR_ELx_S1PTW) >> ESR_ELx_S1PTW_SHIFT); + + if (esr_is_data_abort(esr)) + data_abort_decode(esr); +} + /* * Dump out the page tables associated with 'addr' in the currently active mm. */ @@ -139,7 +183,6 @@ void show_pte(unsigned long addr) pr_cont("\n"); } -#ifdef CONFIG_ARM64_HW_AFDBM /* * This function sets the access flags (dirty, accessed), as well as write * permission, and only to a more permissive setting. @@ -154,40 +197,33 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t entry, int dirty) { - pteval_t old_pteval; - unsigned int tmp; + pteval_t old_pteval, pteval; if (pte_same(*ptep, entry)) return 0; /* only preserve the access flags and write permission */ - pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY; - - /* - * PTE_RDONLY is cleared by default in the asm below, so set it in - * back if necessary (read-only or clean PTE). - */ - if (!pte_write(entry) || !pte_sw_dirty(entry)) - pte_val(entry) |= PTE_RDONLY; + pte_val(entry) &= PTE_RDONLY | PTE_AF | PTE_WRITE | PTE_DIRTY; /* * Setting the flags must be done atomically to avoid racing with the - * hardware update of the access/dirty state. + * hardware update of the access/dirty state. The PTE_RDONLY bit must + * be set to the most permissive (lowest value) of *ptep and entry + * (calculated as: a & b == ~(~a | ~b)). */ - asm volatile("// ptep_set_access_flags\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " and %0, %0, %3 // clear PTE_RDONLY\n" - " orr %0, %0, %4 // set flags\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep)) - : "L" (~PTE_RDONLY), "r" (pte_val(entry))); + pte_val(entry) ^= PTE_RDONLY; + pteval = READ_ONCE(pte_val(*ptep)); + do { + old_pteval = pteval; + pteval ^= PTE_RDONLY; + pteval |= pte_val(entry); + pteval ^= PTE_RDONLY; + pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval); + } while (pteval != old_pteval); flush_tlb_fix_spurious_fault(vma, address); return 1; } -#endif static bool is_el1_instruction_abort(unsigned int esr) { @@ -247,6 +283,8 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr, pr_alert("Unable to handle kernel %s at virtual address %08lx\n", msg, addr); + mem_abort_decode(esr); + show_pte(addr); die("Oops", regs, esr); bust_spinlocks(0); @@ -434,8 +472,11 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, * the mmap_sem because it would already be released * in __lock_page_or_retry in mm/filemap.c. */ - if (fatal_signal_pending(current)) + if (fatal_signal_pending(current)) { + if (!user_mode(regs)) + goto no_context; return 0; + } /* * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk of @@ -610,7 +651,7 @@ static const struct fault_info fault_info[] = { { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 0 translation fault" }, { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" }, { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" }, - { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, { do_bad, SIGBUS, 0, "unknown 8" }, { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" }, { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" }, @@ -701,6 +742,8 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n", inf->name, esr, addr); + mem_abort_decode(esr); + info.si_signo = inf->sig; info.si_errno = 0; info.si_code = inf->code; diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c index 21a8d828cbf4f84db380ffdc5060072852da19a7..e36ed5087b5cbba3f71c57937af82b1b00cb88e4 100644 --- a/arch/arm64/mm/flush.c +++ b/arch/arm64/mm/flush.c @@ -83,3 +83,19 @@ EXPORT_SYMBOL(flush_dcache_page); * Additional functions defined in assembly. */ EXPORT_SYMBOL(flush_icache_range); + +#ifdef CONFIG_ARCH_HAS_PMEM_API +void arch_wb_cache_pmem(void *addr, size_t size) +{ + /* Ensure order against any prior non-cacheable writes */ + dmb(osh); + __clean_dcache_area_pop(addr, size); +} +EXPORT_SYMBOL_GPL(arch_wb_cache_pmem); + +void arch_invalidate_pmem(void *addr, size_t size) +{ + __inval_dcache_area(addr, size); +} +EXPORT_SYMBOL_GPL(arch_invalidate_pmem); +#endif diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 656e0ece228946de561456e212843f4a71473fe8..6cb0fa92a65162ecce1e84b8ef09177fcc54785d 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -41,6 +41,16 @@ int pud_huge(pud_t pud) #endif } +/* + * Select all bits except the pfn + */ +static inline pgprot_t pte_pgprot(pte_t pte) +{ + unsigned long pfn = pte_pfn(pte); + + return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte)); +} + static int find_num_contig(struct mm_struct *mm, unsigned long addr, pte_t *ptep, size_t *pgsize) { @@ -58,15 +68,107 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr, return CONT_PTES; } +static inline int num_contig_ptes(unsigned long size, size_t *pgsize) +{ + int contig_ptes = 0; + + *pgsize = size; + + switch (size) { +#ifdef CONFIG_ARM64_4K_PAGES + case PUD_SIZE: +#endif + case PMD_SIZE: + contig_ptes = 1; + break; + case CONT_PMD_SIZE: + *pgsize = PMD_SIZE; + contig_ptes = CONT_PMDS; + break; + case CONT_PTE_SIZE: + *pgsize = PAGE_SIZE; + contig_ptes = CONT_PTES; + break; + } + + return contig_ptes; +} + +/* + * Changing some bits of contiguous entries requires us to follow a + * Break-Before-Make approach, breaking the whole contiguous set + * before we can change any entries. See ARM DDI 0487A.k_iss10775, + * "Misprogramming of the Contiguous bit", page D4-1762. + * + * This helper performs the break step. + */ +static pte_t get_clear_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + struct vm_area_struct vma = { .vm_mm = mm }; + pte_t orig_pte = huge_ptep_get(ptep); + bool valid = pte_valid(orig_pte); + unsigned long i, saddr = addr; + + for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) { + pte_t pte = ptep_get_and_clear(mm, addr, ptep); + + /* + * If HW_AFDBM is enabled, then the HW could turn on + * the dirty bit for any page in the set, so check + * them all. All hugetlb entries are already young. + */ + if (pte_dirty(pte)) + orig_pte = pte_mkdirty(orig_pte); + } + + if (valid) + flush_tlb_range(&vma, saddr, addr); + return orig_pte; +} + +/* + * Changing some bits of contiguous entries requires us to follow a + * Break-Before-Make approach, breaking the whole contiguous set + * before we can change any entries. See ARM DDI 0487A.k_iss10775, + * "Misprogramming of the Contiguous bit", page D4-1762. + * + * This helper performs the break step for use cases where the + * original pte is not needed. + */ +static void clear_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + struct vm_area_struct vma = { .vm_mm = mm }; + unsigned long i, saddr = addr; + + for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) + pte_clear(mm, addr, ptep); + + flush_tlb_range(&vma, saddr, addr); +} + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { size_t pgsize; int i; int ncontig; - unsigned long pfn; + unsigned long pfn, dpfn; pgprot_t hugeprot; + /* + * Code needs to be expanded to handle huge swap and migration + * entries. Needed for HUGETLB and MEMORY_FAILURE. + */ + WARN_ON(!pte_present(pte)); + if (!pte_cont(pte)) { set_pte_at(mm, addr, ptep, pte); return; @@ -74,17 +176,30 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, ncontig = find_num_contig(mm, addr, ptep, &pgsize); pfn = pte_pfn(pte); - hugeprot = __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte)); - for (i = 0; i < ncontig; i++) { + dpfn = pgsize >> PAGE_SHIFT; + hugeprot = pte_pgprot(pte); + + clear_flush(mm, addr, ptep, pgsize, ncontig); + + for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) { pr_debug("%s: set pte %p to 0x%llx\n", __func__, ptep, pte_val(pfn_pte(pfn, hugeprot))); set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); - ptep++; - pfn += pgsize >> PAGE_SHIFT; - addr += pgsize; } } +void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, unsigned long sz) +{ + int i, ncontig; + size_t pgsize; + + ncontig = num_contig_ptes(sz, &pgsize); + + for (i = 0; i < ncontig; i++, ptep++) + set_pte(ptep, pte); +} + pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) { @@ -144,19 +259,28 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; pud = pud_offset(pgd, addr); - if (pud_none(*pud)) + if (sz != PUD_SIZE && pud_none(*pud)) return NULL; - /* swap or huge page */ - if (!pud_present(*pud) || pud_huge(*pud)) + /* hugepage or swap? */ + if (pud_huge(*pud) || !pud_present(*pud)) return (pte_t *)pud; /* table; check the next level */ + if (sz == CONT_PMD_SIZE) + addr &= CONT_PMD_MASK; + pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) + if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) && + pmd_none(*pmd)) return NULL; - if (!pmd_present(*pmd) || pmd_huge(*pmd)) + if (pmd_huge(*pmd) || !pmd_present(*pmd)) return (pte_t *)pmd; + if (sz == CONT_PTE_SIZE) { + pte_t *pte = pte_offset_kernel(pmd, (addr & CONT_PTE_MASK)); + return pte; + } + return NULL; } @@ -176,111 +300,133 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, return entry; } +void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz) +{ + int i, ncontig; + size_t pgsize; + + ncontig = num_contig_ptes(sz, &pgsize); + + for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) + pte_clear(mm, addr, ptep); +} + pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t pte; + int ncontig; + size_t pgsize; + pte_t orig_pte = huge_ptep_get(ptep); - if (pte_cont(*ptep)) { - int ncontig, i; - size_t pgsize; - bool is_dirty = false; - - ncontig = find_num_contig(mm, addr, ptep, &pgsize); - /* save the 1st pte to return */ - pte = ptep_get_and_clear(mm, addr, ptep); - for (i = 1, addr += pgsize; i < ncontig; ++i, addr += pgsize) { - /* - * If HW_AFDBM is enabled, then the HW could - * turn on the dirty bit for any of the page - * in the set, so check them all. - */ - ++ptep; - if (pte_dirty(ptep_get_and_clear(mm, addr, ptep))) - is_dirty = true; - } - if (is_dirty) - return pte_mkdirty(pte); - else - return pte; - } else { + if (!pte_cont(orig_pte)) return ptep_get_and_clear(mm, addr, ptep); - } + + ncontig = find_num_contig(mm, addr, ptep, &pgsize); + + return get_clear_flush(mm, addr, ptep, pgsize, ncontig); } int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { - if (pte_cont(pte)) { - int ncontig, i, changed = 0; - size_t pgsize = 0; - unsigned long pfn = pte_pfn(pte); - /* Select all bits except the pfn */ - pgprot_t hugeprot = - __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ - pte_val(pte)); - - pfn = pte_pfn(pte); - ncontig = find_num_contig(vma->vm_mm, addr, ptep, - &pgsize); - for (i = 0; i < ncontig; ++i, ++ptep, addr += pgsize) { - changed |= ptep_set_access_flags(vma, addr, ptep, - pfn_pte(pfn, - hugeprot), - dirty); - pfn += pgsize >> PAGE_SHIFT; - } - return changed; - } else { + int ncontig, i, changed = 0; + size_t pgsize = 0; + unsigned long pfn = pte_pfn(pte), dpfn; + pgprot_t hugeprot; + pte_t orig_pte; + + if (!pte_cont(pte)) return ptep_set_access_flags(vma, addr, ptep, pte, dirty); - } + + ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize); + dpfn = pgsize >> PAGE_SHIFT; + + orig_pte = get_clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); + if (!pte_same(orig_pte, pte)) + changed = 1; + + /* Make sure we don't lose the dirty state */ + if (pte_dirty(orig_pte)) + pte = pte_mkdirty(pte); + + hugeprot = pte_pgprot(pte); + for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) + set_pte_at(vma->vm_mm, addr, ptep, pfn_pte(pfn, hugeprot)); + + return changed; } void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - if (pte_cont(*ptep)) { - int ncontig, i; - size_t pgsize = 0; - - ncontig = find_num_contig(mm, addr, ptep, &pgsize); - for (i = 0; i < ncontig; ++i, ++ptep, addr += pgsize) - ptep_set_wrprotect(mm, addr, ptep); - } else { + unsigned long pfn, dpfn; + pgprot_t hugeprot; + int ncontig, i; + size_t pgsize; + pte_t pte; + + if (!pte_cont(*ptep)) { ptep_set_wrprotect(mm, addr, ptep); + return; } + + ncontig = find_num_contig(mm, addr, ptep, &pgsize); + dpfn = pgsize >> PAGE_SHIFT; + + pte = get_clear_flush(mm, addr, ptep, pgsize, ncontig); + pte = pte_wrprotect(pte); + + hugeprot = pte_pgprot(pte); + pfn = pte_pfn(pte); + + for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) + set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); } void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - if (pte_cont(*ptep)) { - int ncontig, i; - size_t pgsize = 0; - - ncontig = find_num_contig(vma->vm_mm, addr, ptep, - &pgsize); - for (i = 0; i < ncontig; ++i, ++ptep, addr += pgsize) - ptep_clear_flush(vma, addr, ptep); - } else { + size_t pgsize; + int ncontig; + + if (!pte_cont(*ptep)) { ptep_clear_flush(vma, addr, ptep); + return; } + + ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize); + clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); } static __init int setup_hugepagesz(char *opt) { unsigned long ps = memparse(opt, &opt); - if (ps == PMD_SIZE) { - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); - } else if (ps == PUD_SIZE) { - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); - } else { - hugetlb_bad_size(); - pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); - return 0; + switch (ps) { +#ifdef CONFIG_ARM64_4K_PAGES + case PUD_SIZE: +#endif + case PMD_SIZE * CONT_PMDS: + case PMD_SIZE: + case PAGE_SIZE * CONT_PTES: + hugetlb_add_hstate(ilog2(ps) - PAGE_SHIFT); + return 1; } - return 1; + + hugetlb_bad_size(); + pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); + return 0; } __setup("hugepagesz=", setup_hugepagesz); + +#ifdef CONFIG_ARM64_64K_PAGES +static __init int add_default_hugepagesz(void) +{ + if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL) + hugetlb_add_hstate(CONT_PTE_SHIFT); + return 0; +} +arch_initcall(add_default_hugepagesz); +#endif diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h index b02a9268dfbf1093016dc3609e79681fa6da9dba..783de51a6c4e5b33725d4904be6b09011dd48605 100644 --- a/arch/arm64/net/bpf_jit.h +++ b/arch/arm64/net/bpf_jit.h @@ -44,8 +44,12 @@ #define A64_COND_NE AARCH64_INSN_COND_NE /* != */ #define A64_COND_CS AARCH64_INSN_COND_CS /* unsigned >= */ #define A64_COND_HI AARCH64_INSN_COND_HI /* unsigned > */ +#define A64_COND_LS AARCH64_INSN_COND_LS /* unsigned <= */ +#define A64_COND_CC AARCH64_INSN_COND_CC /* unsigned < */ #define A64_COND_GE AARCH64_INSN_COND_GE /* signed >= */ #define A64_COND_GT AARCH64_INSN_COND_GT /* signed > */ +#define A64_COND_LE AARCH64_INSN_COND_LE /* signed <= */ +#define A64_COND_LT AARCH64_INSN_COND_LT /* signed < */ #define A64_B_(cond, imm19) A64_COND_BRANCH(cond, (imm19) << 2) /* Unconditional branch (immediate) */ diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index f32144b2e07fc13e39baa929bfb9f9c29796905f..ba38d403abb2fc92d8ea6ae9a6c3c38e70979062 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -527,10 +527,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* IF (dst COND src) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JNE | BPF_X: case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: emit(A64_CMP(1, dst, src), ctx); emit_cond_jmp: jmp_offset = bpf2a64_offset(i + off, i, ctx); @@ -542,9 +546,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) case BPF_JGT: jmp_cond = A64_COND_HI; break; + case BPF_JLT: + jmp_cond = A64_COND_CC; + break; case BPF_JGE: jmp_cond = A64_COND_CS; break; + case BPF_JLE: + jmp_cond = A64_COND_LS; + break; case BPF_JSET: case BPF_JNE: jmp_cond = A64_COND_NE; @@ -552,9 +562,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) case BPF_JSGT: jmp_cond = A64_COND_GT; break; + case BPF_JSLT: + jmp_cond = A64_COND_LT; + break; case BPF_JSGE: jmp_cond = A64_COND_GE; break; + case BPF_JSLE: + jmp_cond = A64_COND_LE; + break; default: return -EFAULT; } @@ -566,10 +582,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* IF (dst COND imm) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: emit_a64_mov_i(1, tmp, imm, ctx); emit(A64_CMP(1, dst, tmp), ctx); goto emit_cond_jmp; diff --git a/arch/blackfin/include/asm/bfin_twi.h b/arch/blackfin/include/asm/bfin_twi.h index aaa0834d34aa7ed768fb66d5d779c672225932a8..211e9c78f6fb89f683ace34310c451c971509da3 100644 --- a/arch/blackfin/include/asm/bfin_twi.h +++ b/arch/blackfin/include/asm/bfin_twi.h @@ -1,7 +1,7 @@ /* * bfin_twi.h - interface to Blackfin TWIs * - * Copyright 2005-2010 Analog Devices Inc. + * Copyright 2005-2014 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -10,6 +10,138 @@ #define __ASM_BFIN_TWI_H__ #include +#include +#include + +/* + * ADI twi registers layout + */ +struct bfin_twi_regs { + u16 clkdiv; + u16 dummy1; + u16 control; + u16 dummy2; + u16 slave_ctl; + u16 dummy3; + u16 slave_stat; + u16 dummy4; + u16 slave_addr; + u16 dummy5; + u16 master_ctl; + u16 dummy6; + u16 master_stat; + u16 dummy7; + u16 master_addr; + u16 dummy8; + u16 int_stat; + u16 dummy9; + u16 int_mask; + u16 dummy10; + u16 fifo_ctl; + u16 dummy11; + u16 fifo_stat; + u16 dummy12; + u32 __pad[20]; + u16 xmt_data8; + u16 dummy13; + u16 xmt_data16; + u16 dummy14; + u16 rcv_data8; + u16 dummy15; + u16 rcv_data16; + u16 dummy16; +}; + +struct bfin_twi_iface { + int irq; + spinlock_t lock; + char read_write; + u8 command; + u8 *transPtr; + int readNum; + int writeNum; + int cur_mode; + int manual_stop; + int result; + struct i2c_adapter adap; + struct completion complete; + struct i2c_msg *pmsg; + int msg_num; + int cur_msg; + u16 saved_clkdiv; + u16 saved_control; + struct bfin_twi_regs __iomem *regs_base; +}; + +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (RX/TX*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ #define DEFINE_TWI_REG(reg_name, reg) \ static inline u16 read_##reg_name(struct bfin_twi_iface *iface) \ diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index c58f4a83ed6f343f6ef45962884352d6368f2dc8..f6431439d15d48339ab4b161af70447baaa00e6a 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -48,11 +48,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) __raw_spin_unlock_asm(&lock->lock); } -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - static inline int arch_read_can_lock(arch_rwlock_t *rw) { return __raw_uncached_fetch_asm(&rw->lock) > 0; diff --git a/arch/blackfin/include/uapi/asm/siginfo.h b/arch/blackfin/include/uapi/asm/siginfo.h index c72f4e6e386fa34b2b120e14baa3ee932caadee9..79dfe3979123872c99925b9d08cf2c2bf4e5453b 100644 --- a/arch/blackfin/include/uapi/asm/siginfo.h +++ b/arch/blackfin/include/uapi/asm/siginfo.h @@ -14,28 +14,36 @@ #define si_uid16 _sifields._kill._uid -#define ILL_ILLPARAOP (__SI_FAULT|2) /* illegal opcode combine ********** */ -#define ILL_ILLEXCPT (__SI_FAULT|4) /* unrecoverable exception ********** */ -#define ILL_CPLB_VI (__SI_FAULT|9) /* D/I CPLB protect violation ******** */ -#define ILL_CPLB_MISS (__SI_FAULT|10) /* D/I CPLB miss ******** */ -#define ILL_CPLB_MULHIT (__SI_FAULT|11) /* D/I CPLB multiple hit ******** */ +#define ILL_ILLPARAOP 2 /* illegal opcode combine ********** */ +#define ILL_ILLEXCPT 4 /* unrecoverable exception ********** */ +#define ILL_CPLB_VI 9 /* D/I CPLB protect violation ******** */ +#define ILL_CPLB_MISS 10 /* D/I CPLB miss ******** */ +#define ILL_CPLB_MULHIT 11 /* D/I CPLB multiple hit ******** */ +#undef NSIGILL +#define NSIGILL 11 /* * SIGBUS si_codes */ -#define BUS_OPFETCH (__SI_FAULT|4) /* error from instruction fetch ******** */ +#define BUS_OPFETCH 4 /* error from instruction fetch ******** */ +#undef NSIGBUS +#define NSIGBUS 4 /* * SIGTRAP si_codes */ -#define TRAP_STEP (__SI_FAULT|1) /* single-step breakpoint************* */ -#define TRAP_TRACEFLOW (__SI_FAULT|2) /* trace buffer overflow ************* */ -#define TRAP_WATCHPT (__SI_FAULT|3) /* watchpoint match ************* */ -#define TRAP_ILLTRAP (__SI_FAULT|4) /* illegal trap ************* */ +#define TRAP_STEP 1 /* single-step breakpoint************* */ +#define TRAP_TRACEFLOW 2 /* trace buffer overflow ************* */ +#define TRAP_WATCHPT 3 /* watchpoint match ************* */ +#define TRAP_ILLTRAP 4 /* illegal trap ************* */ +#undef NSIGTRAP +#define NSIGTRAP 4 /* * SIGSEGV si_codes */ -#define SEGV_STACKFLOW (__SI_FAULT|3) /* stack overflow */ +#define SEGV_STACKFLOW 3 /* stack overflow */ +#undef NSIGSEGV +#define NSIGSEGV 3 #endif /* _UAPI_BFIN_SIGINFO_H */ diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c index e272bca93c648faf9d670b7cf239ce4464a9a3e8..f31ace221392c4d5c2006a1fa18b2f1271838eb3 100644 --- a/arch/blackfin/kernel/debug-mmrs.c +++ b/arch/blackfin/kernel/debug-mmrs.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 0188c933b155be395539530e5051e135474bc754..15af5768c40393ef0204aab271f2695d20cb7c97 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -4,8 +4,6 @@ * Licensed under the GPL-2 or later */ -#define pr_fmt(fmt) "module %s: " fmt, mod->name - #include #include #include @@ -16,6 +14,11 @@ #include #include +#define mod_err(mod, fmt, ...) \ + pr_err("module %s: " fmt, (mod)->name, ##__VA_ARGS__) +#define mod_debug(mod, fmt, ...) \ + pr_debug("module %s: " fmt, (mod)->name, ##__VA_ARGS__) + /* Transfer the section to the L1 memory */ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -44,7 +47,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { - pr_err("L1 inst memory allocation failed\n"); + mod_err(mod, "L1 inst memory allocation failed\n"); return -1; } dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -56,7 +59,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -68,7 +71,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_sram_zalloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } @@ -77,7 +80,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.data_b_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -87,7 +90,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.bss_b_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } memset(dest, 0, s->sh_size); @@ -99,7 +102,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_alloc(s->sh_size); mod->arch.text_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n"); + mod_err(mod, "L2 SRAM allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -111,7 +114,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_alloc(s->sh_size); mod->arch.data_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n"); + mod_err(mod, "L2 SRAM allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -123,7 +126,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_zalloc(s->sh_size); mod->arch.bss_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n"); + mod_err(mod, "L2 SRAM allocation failed\n"); return -1; } @@ -157,8 +160,8 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, Elf32_Sym *sym; unsigned long location, value, size; - pr_debug("applying relocate section %u to %u\n", - relsec, sechdrs[relsec].sh_info); + mod_debug(mod, "applying relocate section %u to %u\n", + relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ @@ -174,14 +177,14 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, #ifdef CONFIG_SMP if (location >= COREB_L1_DATA_A_START) { - pr_err("cannot relocate in L1: %u (SMP kernel)\n", + mod_err(mod, "cannot relocate in L1: %u (SMP kernel)\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } #endif - pr_debug("location is %lx, value is %lx type is %d\n", - location, value, ELF32_R_TYPE(rel[i].r_info)); + mod_debug(mod, "location is %lx, value is %lx type is %d\n", + location, value, ELF32_R_TYPE(rel[i].r_info)); switch (ELF32_R_TYPE(rel[i].r_info)) { @@ -200,12 +203,12 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, case R_BFIN_PCREL12_JUMP: case R_BFIN_PCREL12_JUMP_S: case R_BFIN_PCREL10: - pr_err("unsupported relocation: %u (no -mlong-calls?)\n", + mod_err(mod, "unsupported relocation: %u (no -mlong-calls?)\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; default: - pr_err("unknown relocation: %u\n", + mod_err(mod, "unknown relocation: %u\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -222,7 +225,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, isram_memcpy((void *)location, &value, size); break; default: - pr_err("invalid relocation for %#lx\n", location); + mod_err(mod, "invalid relocation for %#lx\n", location); return -ENOEXEC; } } diff --git a/arch/blackfin/mach-bf537/boards/dnp5370.c b/arch/blackfin/mach-bf537/boards/dnp5370.c index e79b3b810c39e302426eb9b2329acc3ca8a19780..c4a8ffb154176b7e7d183180306f3999039d299c 100644 --- a/arch/blackfin/mach-bf537/boards/dnp5370.c +++ b/arch/blackfin/mach-bf537/boards/dnp5370.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 7528148dc4925bb269f7fd4966104479f2af5641..400e6693643eb0827abf5d617514059cd0114b73 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 37f8f25a1347fbed8c77ff6b498e1a062afb4321..696cc9d7820a01b0a9091e56e7798d6e1e2259e6 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/c6x/configs/dsk6455_defconfig b/arch/c6x/configs/dsk6455_defconfig index 4663487c67a176472469348c957137ed12c68412..d764ea4cce7f51c739cc65408df3d469b87d66a1 100644 --- a/arch/c6x/configs/dsk6455_defconfig +++ b/arch/c6x/configs/dsk6455_defconfig @@ -1,5 +1,4 @@ CONFIG_SOC_TMS320C6455=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_SPARSE_IRQ=y @@ -25,7 +24,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=17000 -CONFIG_MISC_DEVICES=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set diff --git a/arch/c6x/configs/evmc6457_defconfig b/arch/c6x/configs/evmc6457_defconfig index bba40e195ec43d1e70d9c2ccc6a4876f4a96abfd..05d0b4a25ab1fcba6500106cc68a7e546aaeeb78 100644 --- a/arch/c6x/configs/evmc6457_defconfig +++ b/arch/c6x/configs/evmc6457_defconfig @@ -1,5 +1,4 @@ CONFIG_SOC_TMS320C6457=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_SPARSE_IRQ=y @@ -26,7 +25,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=17000 -CONFIG_MISC_DEVICES=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set diff --git a/arch/c6x/configs/evmc6472_defconfig b/arch/c6x/configs/evmc6472_defconfig index 8c46155f6d311befd6b2b6d90369149290c5fd4c..8d81fcf86b0e0e86ca9d8bca1a260e9217706b68 100644 --- a/arch/c6x/configs/evmc6472_defconfig +++ b/arch/c6x/configs/evmc6472_defconfig @@ -1,5 +1,4 @@ CONFIG_SOC_TMS320C6472=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_SPARSE_IRQ=y @@ -27,7 +26,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=17000 -CONFIG_MISC_DEVICES=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set diff --git a/arch/c6x/configs/evmc6474_defconfig b/arch/c6x/configs/evmc6474_defconfig index 15533f63231315d7282a0442d9ebd48ef35f0dd3..8156a98f3958be3af5d8a407f6dbae8d6f26bfd0 100644 --- a/arch/c6x/configs/evmc6474_defconfig +++ b/arch/c6x/configs/evmc6474_defconfig @@ -1,5 +1,4 @@ CONFIG_SOC_TMS320C6474=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_SPARSE_IRQ=y @@ -27,7 +26,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=17000 -CONFIG_MISC_DEVICES=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set diff --git a/arch/c6x/configs/evmc6678_defconfig b/arch/c6x/configs/evmc6678_defconfig index 5f126d4905b1973f502010959592b24a94d71aa5..c4f433c25b69d94618779049f9f38fa5ac872437 100644 --- a/arch/c6x/configs/evmc6678_defconfig +++ b/arch/c6x/configs/evmc6678_defconfig @@ -1,5 +1,4 @@ CONFIG_SOC_TMS320C6678=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_SPARSE_IRQ=y @@ -27,7 +26,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=17000 -CONFIG_MISC_DEVICES=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h index 7c87b5be53b5b74c76fbe03829034b1e96ac3c7c..8f7cce829f8e2630cb88e81cdb024a8375a59e4f 100644 --- a/arch/c6x/include/asm/processor.h +++ b/arch/c6x/include/asm/processor.h @@ -92,9 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - /* * saved kernel SP and DP of a blocked thread. */ diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c index 43afc03e41251d45c2ccd0f0a00656ad5e368fe9..9519fa5f97d0c224b83d65abdacd7495a613de14 100644 --- a/arch/c6x/platforms/megamod-pic.c +++ b/arch/c6x/platforms/megamod-pic.c @@ -208,14 +208,14 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) pic = kzalloc(sizeof(struct megamod_pic), GFP_KERNEL); if (!pic) { - pr_err("%s: Could not alloc PIC structure.\n", np->full_name); + pr_err("%pOF: Could not alloc PIC structure.\n", np); return NULL; } pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32, &megamod_domain_ops, pic); if (!pic->irqhost) { - pr_err("%s: Could not alloc host.\n", np->full_name); + pr_err("%pOF: Could not alloc host.\n", np); goto error_free; } @@ -225,7 +225,7 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) pic->regs = of_iomap(np, 0); if (!pic->regs) { - pr_err("%s: Could not map registers.\n", np->full_name); + pr_err("%pOF: Could not map registers.\n", np); goto error_free; } @@ -253,8 +253,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) irq_data = irq_get_irq_data(irq); if (!irq_data) { - pr_err("%s: combiner-%d no irq_data for virq %d!\n", - np->full_name, i, irq); + pr_err("%pOF: combiner-%d no irq_data for virq %d!\n", + np, i, irq); continue; } @@ -265,16 +265,16 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) * of the core priority interrupts (4 - 15). */ if (hwirq < 4 || hwirq >= NR_PRIORITY_IRQS) { - pr_err("%s: combiner-%d core irq %ld out of range!\n", - np->full_name, i, hwirq); + pr_err("%pOF: combiner-%d core irq %ld out of range!\n", + np, i, hwirq); continue; } /* record the mapping */ mapping[hwirq - 4] = i; - pr_debug("%s: combiner-%d cascading to hwirq %ld\n", - np->full_name, i, hwirq); + pr_debug("%pOF: combiner-%d cascading to hwirq %ld\n", + np, i, hwirq); cascade_data[i].pic = pic; cascade_data[i].index = i; @@ -290,8 +290,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) /* Finally, set up the MUX registers */ for (i = 0; i < NR_MUX_OUTPUTS; i++) { if (mapping[i] != IRQ_UNMAPPED) { - pr_debug("%s: setting mux %d to priority %d\n", - np->full_name, mapping[i], i + 4); + pr_debug("%pOF: setting mux %d to priority %d\n", + np, mapping[i], i + 4); set_megamod_mux(pic, mapping[i], i); } } diff --git a/arch/c6x/platforms/plldata.c b/arch/c6x/platforms/plldata.c index 755359eb628622ffd60d2bdd6ebb3a060159620b..e8b6cc6a7b5ac4e97f20877e05817e209fff7e91 100644 --- a/arch/c6x/platforms/plldata.c +++ b/arch/c6x/platforms/plldata.c @@ -436,8 +436,8 @@ void __init c64x_setup_clocks(void) err = of_property_read_u32(node, "clock-frequency", &val); if (err || val == 0) { - pr_err("%s: no clock-frequency found! Using %dMHz\n", - node->full_name, (int)val / 1000000); + pr_err("%pOF: no clock-frequency found! Using %dMHz\n", + node, (int)val / 1000000); val = 25000000; } clkin1.rate = val; diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c index 0bd0452ded80d53698dd1673e15be770d89f8ae8..241a9a607193a00a726fcda8da4d2921d9bcbc83 100644 --- a/arch/c6x/platforms/timer64.c +++ b/arch/c6x/platforms/timer64.c @@ -204,14 +204,14 @@ void __init timer64_init(void) timer = of_iomap(np, 0); if (!timer) { - pr_debug("%s: Cannot map timer registers.\n", np->full_name); + pr_debug("%pOF: Cannot map timer registers.\n", np); goto out; } - pr_debug("%s: Timer registers=%p.\n", np->full_name, timer); + pr_debug("%pOF: Timer registers=%p.\n", np, timer); cd->irq = irq_of_parse_and_map(np, 0); if (cd->irq == NO_IRQ) { - pr_debug("%s: Cannot find interrupt.\n", np->full_name); + pr_debug("%pOF: Cannot find interrupt.\n", np); iounmap(timer); goto out; } @@ -229,7 +229,7 @@ void __init timer64_init(void) dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED); } - pr_debug("%s: Timer irq=%d.\n", np->full_name, cd->irq); + pr_debug("%pOF: Timer irq=%d.\n", np, cd->irq); clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5); diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index 3f646c787e584e40a097208abd9fdb05221cf755..925a98eb6d688eb12e7a18eac07130de202d3095 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index a74540514bdbdcde086259df8f08a9beec340cd0..53b56a429dde8b859b06106472765ac74dc21312 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 394c2a73d5e25bb6cf748a37ddeeb62aa5fed5c2..5cc622c0225e0497406bdb7227e7638a05835062 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -2,10 +2,6 @@ #include #include -void pcibios_fixup_bus(struct pci_bus *b) -{ -} - void pcibios_set_master(struct pci_dev *dev) { u8 lat; diff --git a/arch/cris/arch-v32/mach-a3/arbiter.c b/arch/cris/arch-v32/mach-a3/arbiter.c index ab5c421a4de86fb3af3614e01ec5bd8ebdb5af8d..735a9b0abdb835d44f46eaf7cf7a61f19f0340db 100644 --- a/arch/cris/arch-v32/mach-a3/arbiter.c +++ b/arch/cris/arch-v32/mach-a3/arbiter.c @@ -227,7 +227,7 @@ static void crisv32_arbiter_config(int arbiter, int region, int unused_slots) } } -extern char _stext, _etext; +extern char _stext[], _etext[]; static void crisv32_arbiter_init(void) { @@ -265,7 +265,7 @@ static void crisv32_arbiter_init(void) #ifndef CONFIG_ETRAX_KGDB /* Global watch for writes to kernel text segment. */ - crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, + crisv32_arbiter_watch(virt_to_phys(_stext), _etext - _stext, MARB_CLIENTS(arbiter_all_clients, arbiter_bar_all_clients), arbiter_all_write, NULL); #endif diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c index c97f4d8120f9e43747b120fd8fc8ef814c0060ed..047c70bdbb23b4896422c7bcb843eceda9e3c4e7 100644 --- a/arch/cris/arch-v32/mach-fs/arbiter.c +++ b/arch/cris/arch-v32/mach-fs/arbiter.c @@ -158,7 +158,7 @@ static void crisv32_arbiter_config(int region, int unused_slots) } } -extern char _stext, _etext; +extern char _stext[], _etext[]; static void crisv32_arbiter_init(void) { @@ -190,7 +190,7 @@ static void crisv32_arbiter_init(void) #ifndef CONFIG_ETRAX_KGDB /* Global watch for writes to kernel text segment. */ - crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, + crisv32_arbiter_watch(virt_to_phys(_stext), _etext - _stext, arbiter_all_clients, arbiter_all_write, NULL); #endif } diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index a01636a12a6e87c46361591b69b1ebbaafb6728e..d98131c45bb56ba712d46659c7cadb68eb8841df 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c @@ -42,7 +42,7 @@ void (*nmi_handler)(struct pt_regs *); void show_trace(unsigned long *stack) { unsigned long addr, module_start, module_end; - extern char _stext, _etext; + extern char _stext[], _etext[]; int i; pr_err("\nCall Trace: "); @@ -69,8 +69,8 @@ void show_trace(unsigned long *stack) * down the cause of the crash will be able to figure * out the call path that was taken. */ - if (((addr >= (unsigned long)&_stext) && - (addr <= (unsigned long)&_etext)) || + if (((addr >= (unsigned long)_stext) && + (addr <= (unsigned long)_etext)) || ((addr >= module_start) && (addr <= module_end))) { #ifdef CONFIG_KALLSYMS print_ip_sym(addr); diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index eefd9a4ed156753b6f07cb41cd0cb97ca0f99a48..1cce8243449e03da1855e39c180e9a459bb3ccc7 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -17,6 +17,9 @@ config FRV select HAVE_DEBUG_STACKOVERFLOW select ARCH_NO_COHERENT_DMA_MMAP +config CPU_BIG_ENDIAN + def_bool y + config ZONE_DMA bool default y diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h index 2e1da71e27a45a75f96ef0b91d1f35a71480b2c4..ab346f5f8820a465f681f8ea54bf32352b7d45ed 100644 --- a/arch/frv/include/asm/futex.h +++ b/arch/frv/include/asm/futex.h @@ -7,7 +7,8 @@ #include #include -extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr); +extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr); static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index e4d08d74ed9f8dc4f81140fcf60442378f02cf58..021cce78b4010d7b5c727d1e86812f85e81671bf 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -92,10 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) extern asmlinkage void save_user_regs(struct user_context *target); extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) -#define forget_segments() do { } while (0) - unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) diff --git a/arch/frv/include/uapi/asm/siginfo.h b/arch/frv/include/uapi/asm/siginfo.h index d3fd1ca456536b3586efe9c05fc349beaf1ba03a..f55d9e0e906805dcc5590292d23368e270f2f7b4 100644 --- a/arch/frv/include/uapi/asm/siginfo.h +++ b/arch/frv/include/uapi/asm/siginfo.h @@ -4,7 +4,7 @@ #include #include -#define FPE_MDAOVF (__SI_FAULT|9) /* media overflow */ +#define FPE_MDAOVF 9 /* media overflow */ #undef NSIGFPE #define NSIGFPE 9 diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index f1e3b20dce9fd98c869ee125c281b7123ab74b5c..9abf02d6855a6d28a3cb4ce8b263662be46e02ed 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h @@ -102,5 +102,7 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c index d155ca9e5098c8963f6ea5b0d8c987a6963f0538..37f7b2bf7f730c092d3ea15806c9163c8a3019d9 100644 --- a/arch/frv/kernel/futex.c +++ b/arch/frv/kernel/futex.c @@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o /* * do the futex operations */ -int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; break; - } - } + if (!ret) + *oval = oldval; return ret; -} /* end futex_atomic_op_inuser() */ +} /* end arch_futex_atomic_op_inuser() */ diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 6e3d36f37a02f146424c4ba0b87ae8ab153a0a1c..3089f7fe2abdb2aafa7bb613c45319720ea77a4f 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -23,6 +23,9 @@ config H8300 select HAVE_ARCH_HASH select CPU_NO_EFFICIENT_FFS +config CPU_BIG_ENDIAN + def_bool y + config RWSEM_GENERIC_SPINLOCK def_bool y diff --git a/arch/h8300/include/asm/traps.h b/arch/h8300/include/asm/traps.h index 15e701130b27618a5e46b45a45cff14fa30c518d..1c5a30ec2df89afaee7a19ac5e967571d5e01c93 100644 --- a/arch/h8300/include/asm/traps.h +++ b/arch/h8300/include/asm/traps.h @@ -33,9 +33,9 @@ extern unsigned long *_interrupt_redirect_table; #define TRAP2_VEC 10 #define TRAP3_VEC 11 -extern char _start, _etext; +extern char _start[], _etext[]; #define check_kernel_text(addr) \ - ((addr >= (unsigned long)(&_start)) && \ - (addr < (unsigned long)(&_etext)) && !(addr & 1)) + ((addr >= (unsigned long)(_start)) && \ + (addr < (unsigned long)(_etext)) && !(addr & 1)) #endif /* _H8300_TRAPS_H */ diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index a62ba368b27d1ddf6f750efd1dcaa2b51419d1d8..fb3dfb2a667ee11626cf9c999e5b303fcc9b9c83 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -42,6 +42,8 @@ static inline void atomic_set(atomic_t *v, int new) ); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + /** * atomic_read - reads a word, atomically * @v: pointer to atomic value diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h index 7e597f8434da0c13f3d0e68c6b3d838b0d0126d5..c607b77c8215d2995e2f30f1df5bcf497bd1e65b 100644 --- a/arch/hexagon/include/asm/futex.h +++ b/arch/hexagon/include/asm/futex.h @@ -31,18 +31,9 @@ static inline int -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; pagefault_disable(); @@ -72,30 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/hexagon/include/asm/spinlock.h b/arch/hexagon/include/asm/spinlock.h index a1c55788c5d6591eac4786b2dc0fcdd3164eb65c..53a8d588588787cba2b22202c2ee675fba83e6df 100644 --- a/arch/hexagon/include/asm/spinlock.h +++ b/arch/hexagon/include/asm/spinlock.h @@ -179,11 +179,6 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) */ #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - #define arch_spin_is_locked(x) ((x)->lock != 0) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug index de9d507ba0fd466d8b466f54d1143a46d20caaa0..4763887ba3682112f5fe5020622391c81c830d73 100644 --- a/arch/ia64/Kconfig.debug +++ b/arch/ia64/Kconfig.debug @@ -56,9 +56,4 @@ config IA64_DEBUG_IRQ and restore instructions. It's useful for tracking down spinlock problems, but slow! If you're unsure, select N. -config SYSVIPC_COMPAT - bool - depends on COMPAT && SYSVIPC - default y - endmenu diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index a3d0211970e95e5152edbaeeecd8ab3a42041ac6..c86a947f5368633b86d1a8e5dc7ddd1803982c64 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -112,8 +112,6 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; } -#define acpi_unlazy_tlb(x) - #ifdef CONFIG_ACPI_NUMA extern cpumask_t early_cpu_possible_map; #define for_each_possible_early_cpu(cpu) \ diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h index 76acbcd5c06090e25cd35e77b3afbd5c16f7c0ae..6d67dc1eaf2be247815629184f68da72050b61eb 100644 --- a/arch/ia64/include/asm/futex.h +++ b/arch/ia64/include/asm/futex.h @@ -45,18 +45,9 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -84,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index ca9e76149a4aa16974047820829e6c017afe77dd..df2c121164b8d03e3a9c355e9199d62482fd2c93 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -76,22 +76,6 @@ static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) ACCESS_ONCE(*p) = (tmp + 2) & ~1; } -static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock) -{ - int *p = (int *)&lock->lock, ticket; - - ia64_invala(); - - for (;;) { - asm volatile ("ld4.c.nc %0=[%1]" : "=r"(ticket) : "r"(p) : "memory"); - if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK)) - return; - cpu_relax(); - } - - smp_acquire__after_ctrl_dep(); -} - static inline int __ticket_spin_is_locked(arch_spinlock_t *lock) { long tmp = ACCESS_ONCE(lock->lock); @@ -143,11 +127,6 @@ static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, arch_spin_lock(lock); } -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - __ticket_spin_unlock_wait(lock); -} - #define arch_read_can_lock(rw) (*(volatile int *)(rw) >= 0) #define arch_write_can_lock(rw) (*(volatile int *)(rw) == 0) diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index fced197b96264e01b20743e90706ed20cf30b242..cbe5ac3699bf0f9dbdfd726c112f6fc6bd1271f0 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h @@ -168,7 +168,8 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb) static inline void -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) +arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) { tlb->mm = mm; tlb->max = ARRAY_SIZE(tlb->local); @@ -185,8 +186,11 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start * collected. */ static inline void -tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force) { + if (force) + tlb->need_flush = 1; /* * Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and * tlb->end_addr. diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h index 4694c64252d6daffa827ca6d187f6f676ac7a3a2..33389fc36f239144be69df0c4c11acc49c22a823 100644 --- a/arch/ia64/include/uapi/asm/siginfo.h +++ b/arch/ia64/include/uapi/asm/siginfo.h @@ -98,27 +98,30 @@ typedef struct siginfo { /* * SIGILL si_codes */ -#define ILL_BADIADDR (__SI_FAULT|9) /* unimplemented instruction address */ -#define __ILL_BREAK (__SI_FAULT|10) /* illegal break */ -#define __ILL_BNDMOD (__SI_FAULT|11) /* bundle-update (modification) in progress */ +#define ILL_BADIADDR 9 /* unimplemented instruction address */ +#define __ILL_BREAK 10 /* illegal break */ +#define __ILL_BNDMOD 11 /* bundle-update (modification) in progress */ #undef NSIGILL #define NSIGILL 11 /* * SIGFPE si_codes */ -#define __FPE_DECOVF (__SI_FAULT|9) /* decimal overflow */ -#define __FPE_DECDIV (__SI_FAULT|10) /* decimal division by zero */ -#define __FPE_DECERR (__SI_FAULT|11) /* packed decimal error */ -#define __FPE_INVASC (__SI_FAULT|12) /* invalid ASCII digit */ -#define __FPE_INVDEC (__SI_FAULT|13) /* invalid decimal digit */ +#ifdef __KERNEL__ +#define FPE_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ +#define __FPE_DECOVF 9 /* decimal overflow */ +#define __FPE_DECDIV 10 /* decimal division by zero */ +#define __FPE_DECERR 11 /* packed decimal error */ +#define __FPE_INVASC 12 /* invalid ASCII digit */ +#define __FPE_INVDEC 13 /* invalid decimal digit */ #undef NSIGFPE #define NSIGFPE 13 /* * SIGSEGV si_codes */ -#define __SEGV_PSTKOVF (__SI_FAULT|4) /* paragraph stack overflow */ +#define __SEGV_PSTKOVF 4 /* paragraph stack overflow */ #undef NSIGSEGV #define NSIGSEGV 4 diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 5dd5c5d0d64224098a85491b80cf4e4fed3070e7..002eb85a6941e73d255a6d5f15dc99a6a6843746 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -111,4 +111,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 7508c306aa9e0d8124f5270e5f8b62cf2b7467b6..1d29b2f8726bbaadc24c91f825661f45d68b4c57 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -159,12 +159,12 @@ int acpi_request_vector(u32 int_type) return vector; } -char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size) +void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) { - return __va(phys_addr); + return __va(phys); } -void __init __acpi_unmap_table(char *map, unsigned long size) +void __init __acpi_unmap_table(void __iomem *map, unsigned long size) { } diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 121295637d0df831fbbf919983ee9a0cd1a7d366..81416000c5e07c18f16032bb0b9c9f77abc8b883 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -757,14 +757,14 @@ efi_memmap_intersects (unsigned long phys_addr, unsigned long size) return 0; } -u32 +int efi_mem_type (unsigned long phys_addr) { efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); if (md) return md->type; - return 0; + return -EINVAL; } u64 diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 5db52c6813c418e5c6820d32ca1283e215c5a1e0..6146d53b6ad7df76c5c8a3d7e17b97a01fce58eb 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -124,31 +124,30 @@ copy_siginfo_to_user (siginfo_t __user *to, const siginfo_t *from) */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: + err |= __put_user(from->si_code, &to->si_code); + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_FAULT: err |= __put_user(from->si_flags, &to->si_flags); err |= __put_user(from->si_isr, &to->si_isr); - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_addr, &to->si_addr); err |= __put_user(from->si_imm, &to->si_imm); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_ptr, &to->si_ptr); break; - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_ptr, &to->si_ptr); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); - default: + case SIL_KILL: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); break; diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 7b1fe9462158e1cfbed5bf5367e813dbfe485577..3cb17cf9b3620d386bae6e08415cbd9f14646bb9 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -349,7 +349,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) } siginfo.si_signo = SIGFPE; siginfo.si_errno = 0; - siginfo.si_code = __SI_FAULT; /* default code */ + siginfo.si_code = FPE_FIXME; /* default code */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); if (isr & 0x11) { siginfo.si_code = FPE_FLTINV; @@ -373,7 +373,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) /* raise exception */ siginfo.si_signo = SIGFPE; siginfo.si_errno = 0; - siginfo.si_code = __SI_FAULT; /* default code */ + siginfo.si_code = FPE_FIXME; /* default code */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); if (isr & 0x880) { siginfo.si_code = FPE_FLTOVF; diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 4068bde623dc3dd40c1dc81ccc021d6fdc6303a2..f5ec736100ee6a6a036b6b5b3fa024125aa43154 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -411,13 +411,6 @@ pcibios_disable_device (struct pci_dev *dev) acpi_pci_irq_disable(dev); } -resource_size_t -pcibios_align_resource (void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - /** * ia64_pci_get_legacy_mem - generic legacy mem routine * @bus: bus to get legacy memory base address for diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 87cde1e4b38ca026483729dec6ea61ad5c242a97..0777f3a8a1f37d6f93d707a3333be23c486492e2 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -194,6 +194,10 @@ config TIMER_DIVIDE int "Timer divider (integer)" default "128" +config CPU_BIG_ENDIAN + bool "Generate big endian code" + default n + config CPU_LITTLE_ENDIAN bool "Generate little endian code" default n diff --git a/arch/m32r/configs/m32104ut_defconfig b/arch/m32r/configs/m32104ut_defconfig index be30e094db71ffed9db89ff126d23729d2c6e377..4aa42acbd5129a5b0f85d9062d0fd05b39d173a0 100644 --- a/arch/m32r/configs/m32104ut_defconfig +++ b/arch/m32r/configs/m32104ut_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -40,7 +39,6 @@ CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_ECN=m @@ -48,7 +46,6 @@ CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m @@ -106,7 +103,6 @@ CONFIG_SENSORS_SMSC47M1=m CONFIG_SENSORS_W83781D=m CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83627HF=m -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y diff --git a/arch/m32r/configs/m32700ut.smp_defconfig b/arch/m32r/configs/m32700ut.smp_defconfig index a3d727ed6a1609689c1129973199d64755546ac9..41a0495b65df4d44a2b90a1a69974d38796aa454 100644 --- a/arch/m32r/configs/m32700ut.smp_defconfig +++ b/arch/m32r/configs/m32700ut.smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -30,7 +29,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=m @@ -63,7 +61,6 @@ CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_SERIAL_M32R_PLDSIO=y CONFIG_HW_RANDOM=y CONFIG_DS1302=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_S1D13XXX=y diff --git a/arch/m32r/configs/m32700ut.up_defconfig b/arch/m32r/configs/m32700ut.up_defconfig index b8334163099defd3aa74fa17ed7ee042da5ae74f..20078a866f45eca7775a563e38d15ae9b5b5e46d 100644 --- a/arch/m32r/configs/m32700ut.up_defconfig +++ b/arch/m32r/configs/m32700ut.up_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -29,7 +28,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=m @@ -62,7 +60,6 @@ CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_SERIAL_M32R_PLDSIO=y CONFIG_HW_RANDOM=y CONFIG_DS1302=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_S1D13XXX=y diff --git a/arch/m32r/configs/mappi.nommu_defconfig b/arch/m32r/configs/mappi.nommu_defconfig index 7c90ce2fc42b77713d7f34e0c9f3b481d8d0a468..4bf3820e054a899565424270e8e974f7131a14b2 100644 --- a/arch/m32r/configs/mappi.nommu_defconfig +++ b/arch/m32r/configs/mappi.nommu_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_LOG_BUF_SHIFT=14 @@ -39,7 +38,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_NFS_FS=y diff --git a/arch/m32r/configs/mappi.smp_defconfig b/arch/m32r/configs/mappi.smp_defconfig index 367d07cebcd373786d9f3374d56e852235e8a2a8..f9ed7bdbf4ded00481fb0b6cfdd10ab717e3bb44 100644 --- a/arch/m32r/configs/mappi.smp_defconfig +++ b/arch/m32r/configs/mappi.smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -31,9 +30,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set # CONFIG_STANDALONE is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m @@ -50,7 +47,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=y diff --git a/arch/m32r/configs/mappi.up_defconfig b/arch/m32r/configs/mappi.up_defconfig index cb11384386ce194d72dcdfdae3f4c28d1d26cd6b..289ae7421e1214e3bc41cfd051d228046c15ab8d 100644 --- a/arch/m32r/configs/mappi.up_defconfig +++ b/arch/m32r/configs/mappi.up_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -29,9 +28,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set # CONFIG_STANDALONE is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m @@ -48,7 +45,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=y diff --git a/arch/m32r/configs/mappi2.opsp_defconfig b/arch/m32r/configs/mappi2.opsp_defconfig index 3bff779259b485179e52717d37dda19eb205fa2f..2852f6e7e246a66d13c1ced60a345c5aa1e67467 100644 --- a/arch/m32r/configs/mappi2.opsp_defconfig +++ b/arch/m32r/configs/mappi2.opsp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -50,7 +49,6 @@ CONFIG_SMC91X=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m # CONFIG_VGA_CONSOLE is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/m32r/configs/mappi2.vdec2_defconfig b/arch/m32r/configs/mappi2.vdec2_defconfig index 75246c9c1af82e9082baef90eabddc87e8e54b98..8da4dbad8510c55c9e8addc7656d6366bd1c8959 100644 --- a/arch/m32r/configs/mappi2.vdec2_defconfig +++ b/arch/m32r/configs/mappi2.vdec2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -49,7 +48,6 @@ CONFIG_SMC91X=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m # CONFIG_VGA_CONSOLE is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/m32r/configs/mappi3.smp_defconfig b/arch/m32r/configs/mappi3.smp_defconfig index 27cefd41ac1fd5ab1c7dd8e8829bf1935fc3bd8e..5605b23e2faf8ffc2751e8436bfe2d15fb334e5f 100644 --- a/arch/m32r/configs/mappi3.smp_defconfig +++ b/arch/m32r/configs/mappi3.smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -29,9 +28,7 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m @@ -50,7 +47,6 @@ CONFIG_SMC91X=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=y diff --git a/arch/m32r/configs/oaks32r_defconfig b/arch/m32r/configs/oaks32r_defconfig index 5087a510ca4fcfaefe8df4aa3eb46ed328312275..5ccab127f6ad828ebeaa1a2bae04ae6140f00083 100644 --- a/arch/m32r/configs/oaks32r_defconfig +++ b/arch/m32r/configs/oaks32r_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -37,7 +36,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y diff --git a/arch/m32r/configs/opsput_defconfig b/arch/m32r/configs/opsput_defconfig index 50c6f525db209ff01da71aae187ae3b9f6683aee..3ce1d08355e536dc979b6897e2b17f61fe65aa92 100644 --- a/arch/m32r/configs/opsput_defconfig +++ b/arch/m32r/configs/opsput_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -46,7 +45,6 @@ CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_SERIAL_M32R_PLDSIO=y CONFIG_HW_RANDOM=y CONFIG_DS1302=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=m diff --git a/arch/m32r/configs/usrv_defconfig b/arch/m32r/configs/usrv_defconfig index a3cfaaedab609d70e7c3facf7c97d4f4787d7a6c..cb8c051c3d466c788dad63b988b1d1302b6e2386 100644 --- a/arch/m32r/configs/usrv_defconfig +++ b/arch/m32r/configs/usrv_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -34,9 +33,6 @@ CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -62,7 +58,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_M32R_SIO is not set # CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set diff --git a/arch/m32r/include/asm/flat.h b/arch/m32r/include/asm/flat.h index 455ce7ddbf142e9b5878d4259ea1c92d5f7ec05b..dfcb0e4eb25680f643f840009af29f3b3c40af58 100644 --- a/arch/m32r/include/asm/flat.h +++ b/arch/m32r/include/asm/flat.h @@ -95,7 +95,7 @@ static inline unsigned long m32r_flat_get_addr_from_rp (u32 *rp, return ~0; /* bogus value */ } -static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) +static inline int flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) { unsigned int reloc = flat_m32r_get_reloc_type (relval); if (reloc & 0xf0) { @@ -133,6 +133,7 @@ static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) break; } } + return 0; } // kludge - text_len is a local variable in the only user. diff --git a/arch/m32r/include/asm/processor.h b/arch/m32r/include/asm/processor.h index 657874eeeccc262c11268094e0f0ba530e05dd92..c70fa9ac71690d2529d97e1040a87ed01a8a35da 100644 --- a/arch/m32r/include/asm/processor.h +++ b/arch/m32r/include/asm/processor.h @@ -118,14 +118,6 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -extern void copy_segments(struct task_struct *p, struct mm_struct * mm); -extern void release_segments(struct mm_struct * mm); - -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.lr) #define KSTK_ESP(tsk) ((tsk)->thread.sp) diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index 323c7fc953cdefa3e0b89efaafbe8aace9ed41c0..a56825592b90a070b48a41145fb84332fd6f50fe 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -30,11 +30,6 @@ #define arch_spin_is_locked(x) (*(volatile int *)(&(x)->slock) <= 0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, VAL > 0); -} - /** * arch_spin_trylock - Try spin lock and return a result * @lock: Pointer to the lock variable diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index f8f7b47e247f2d88314f72e7a2f8aead2e247ffb..e268e51a38d1db46a07cf5304d4eca099d360911 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h @@ -102,4 +102,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_M32R_SOCKET_H */ diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index 647dd94a0c399f13f8311e751d273b033908328e..72b96f282689aec63378d85cc50b079ddff2b799 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c @@ -114,6 +114,15 @@ static void set_eit_vector_entries(void) _flush_cache_copyback_all(); } +void abort(void) +{ + BUG(); + + /* if that doesn't kill us, halt */ + panic("Oops failed to kill thread"); +} +EXPORT_SYMBOL(abort); + void __init trap_init(void) { set_eit_vector_entries(); diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 5abb548f0e7075320e339671bbb4cbae65a8d2cd..353d90487c2b9e74bb56e3b35205ae74901b6325 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -24,6 +24,9 @@ config M68K select OLD_SIGSUSPEND3 select OLD_SIGACTION +config CPU_BIG_ENDIAN + def_bool y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/arch/m68k/coldfire/clk.c b/arch/m68k/coldfire/clk.c index 1e3c7e9193d14d0a3c0c6821c1f686d6ef35d02d..856069a3196d224d7ee39a980289dcc738b691b8 100644 --- a/arch/m68k/coldfire/clk.c +++ b/arch/m68k/coldfire/clk.c @@ -121,6 +121,9 @@ EXPORT_SYMBOL(clk_put); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } EXPORT_SYMBOL(clk_get_rate); diff --git a/arch/m68k/coldfire/m5441x.c b/arch/m68k/coldfire/m5441x.c index dc589b039b625e3a6845c2caca07740412f781ae..04fd7fde9fb399e2b7c1c32f60e61f35e2d71d27 100644 --- a/arch/m68k/coldfire/m5441x.c +++ b/arch/m68k/coldfire/m5441x.c @@ -222,40 +222,3 @@ void __init config_BSP(char *commandp, int size) m5441x_uarts_init(); m5441x_fec_init(); } - - -#if IS_ENABLED(CONFIG_RTC_DRV_M5441x) -static struct resource m5441x_rtc_resources[] = { - { - .start = MCFRTC_BASE, - .end = MCFRTC_BASE + MCFRTC_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = MCF_IRQ_RTC, - .end = MCF_IRQ_RTC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device m5441x_rtc = { - .name = "mcfrtc", - .id = 0, - .resource = m5441x_rtc_resources, - .num_resources = ARRAY_SIZE(m5441x_rtc_resources), -}; -#endif - -static struct platform_device *m5441x_devices[] __initdata = { -#if IS_ENABLED(CONFIG_RTC_DRV_M5441x) - &m5441x_rtc, -#endif -}; - -static int __init init_BSP(void) -{ - platform_add_devices(m5441x_devices, ARRAY_SIZE(m5441x_devices)); - return 0; -} - -arch_initcall(init_BSP); diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index 6a640be485684f00497a63ee9630bd77df9dbe4a..3097fa2ca746729d842a5dbb8d98ea2810afb78d 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c @@ -243,6 +243,13 @@ static struct resource mcf_pci_io = { .flags = IORESOURCE_IO, }; +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + /* * Interrupt mapping and setting. */ @@ -258,6 +265,13 @@ static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static int __init mcf_pci_init(void) { + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return -ENOMEM; + pr_info("ColdFire: PCI bus initialization...\n"); /* Reset the external PCI bus */ @@ -312,14 +326,28 @@ static int __init mcf_pci_init(void) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(200)); - rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL); - if (!rootbus) - return -ENODEV; + + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->dev.parent = NULL; + bridge->sysdata = NULL; + bridge->busnr = 0; + bridge->ops = &mcf_pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = mcf_pci_map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return ret; + } + + rootbus = bridge->bus; rootbus->resource[0] = &mcf_pci_io; rootbus->resource[1] = &mcf_pci_mem; - pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); pci_bus_size_bridges(rootbus); pci_bus_assign_resources(rootbus); pci_bus_add_devices(rootbus); diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index ddff1164aff018bc1d192996e58259d00296b92c..54191f6fc7159abef9e852066247cf94b6ab78dd 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -49,6 +49,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -465,8 +466,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m # CONFIG_IOMMU_SUPPORT is not set @@ -477,7 +480,6 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -587,12 +589,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 17384dc959a5720f5f46d755883d984336ebc855..fb466390442834ac5a5af5143a978e54630c78cf 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -47,6 +47,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -427,8 +428,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_HEARTBEAT=y @@ -436,7 +439,6 @@ CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -546,12 +548,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 53a641d62f85d6821eadf1ebe3624029d0e0766c..4ab393e86e52ab379aab820b77b1877e017bc46f 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -47,6 +47,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -442,7 +443,10 @@ CONFIG_DMASOUND_ATARI=m CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_HEARTBEAT=y @@ -457,7 +461,6 @@ CONFIG_ATARI_DSP56K=m CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -567,12 +570,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 3925ae3a5eb32cfc560b2341c50ae581e832f3fc..1dd8d697545bc86f3b3dee431af99fe223d97a68 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -45,6 +45,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -420,15 +421,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -538,12 +540,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index f4a134b390b42a739e150d489a1498a42c2db8dc..02b39f50076e5615391e7774b09f6bf8fbecb8fa 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -47,6 +47,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -430,15 +431,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -548,12 +550,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 9ed0cef632b768b1f5c9491ca41d5b68d84edddb..044dcb2bf8fbec556553ca5a88281733f0eef68b 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -46,6 +46,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -452,15 +453,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -570,12 +572,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index efed0d48fd5325ffd679bec37c0ff7fb1ab6d9bb..3ad04682077a24ac9b6e51854303ed744b9463a9 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -56,6 +56,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -520,8 +521,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m CONFIG_RTC_DRV_GENERIC=m @@ -540,7 +543,6 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -650,12 +652,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 9040457c7f9c1d551dc7eaf99b5f39004c8de8ff..dc2dd61948cdb84442289bd065fbd50f5c8c0a92 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -44,6 +44,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -420,15 +421,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -538,12 +540,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 8b17f00e04843b370b6e720c4e3c900199e2e295..54e7b523fc3d83ab61019d1711118da6cb81af01 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -45,6 +45,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -420,15 +421,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -538,12 +540,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 5f3718c62c85f844fe993ff66a5eb1e91f03c602..d63d8a15f6dbc2896420be1c6daeb37f14538faf 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -45,6 +45,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -442,8 +443,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_HEARTBEAT=y @@ -451,7 +454,6 @@ CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -561,12 +563,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 8c979a68fca5ae9b08ddae43ca27a236608754d2..d0924c22f52a7a43640aa429282480f822ecbe3c 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -42,6 +42,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -422,15 +423,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -540,12 +542,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index a1e79530e806506a6f78a7296c4de94222b71cf1..3001ee1e5dc52a69e5ff9109b728401c5180861c 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -42,6 +42,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -422,15 +423,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -540,12 +542,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/include/asm/asm-prototypes.h b/arch/m68k/include/asm/asm-prototypes.h new file mode 100644 index 0000000000000000000000000000000000000000..22ccb9c9757672010f4b110e8468ca3d5d6b0885 --- /dev/null +++ b/arch/m68k/include/asm/asm-prototypes.h @@ -0,0 +1,5 @@ +extern int __divsi3(int, int); +extern int __modsi3(int, int); +extern int __mulsi3(int, int); +extern unsigned int __udivsi3(unsigned int, unsigned int); +extern unsigned int __umodsi3(unsigned int, unsigned int); diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h index 430d4d54c88383a9620e053c356a71b8cde92e63..d8a02c7e72d3e610dd85206114dd3d7b943166c2 100644 --- a/arch/m68k/include/asm/page.h +++ b/arch/m68k/include/asm/page.h @@ -32,7 +32,7 @@ typedef struct page *pgtable_t; #define pgprot_val(x) ((x).pgprot) #define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) +#define __pmd(x) ((pmd_t) { { (x) }, }) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index 8aa8792e3174c488bc413421efa87449b44635a0..d96348a52362ba74c98386f7fb0d2ab59b5efb7b 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -357,6 +357,17 @@ static void cuda_shutdown(void) struct adb_request req; if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN) < 0) return; + + /* Avoid infinite polling loop when PSU is not under Cuda control */ + switch (macintosh_config->ident) { + case MAC_MODEL_C660: + case MAC_MODEL_Q605: + case MAC_MODEL_Q605_ACC: + case MAC_MODEL_P475: + case MAC_MODEL_P475F: + return; + } + while (!req.complete) cuda_poll(); } @@ -463,8 +474,9 @@ void mac_poweroff(void) pmu_shutdown(); #endif } - local_irq_enable(); + pr_crit("It is now safe to turn off your Macintosh.\n"); + local_irq_disable(); while(1); } @@ -554,8 +566,8 @@ void mac_reset(void) } /* should never get here */ - local_irq_enable(); pr_crit("Restart failed. Please restart manually.\n"); + local_irq_disable(); while(1); } diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig index 5b7a45d99cfbfd5397554b399a6ec2bd8e4b5582..7d8b322e5101d7bd00835be59db1d494be164ad8 100644 --- a/arch/metag/Kconfig +++ b/arch/metag/Kconfig @@ -26,6 +26,7 @@ config METAG select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNDERSCORE_SYMBOL_PREFIX select IRQ_DOMAIN + select GENERIC_IRQ_EFFECTIVE_AFF_MASK select MODULES_USE_ELF_RELA select OF select OF_EARLY_FLATTREE diff --git a/arch/metag/include/asm/atomic_lock1.h b/arch/metag/include/asm/atomic_lock1.h index 6c1380a8a0d4a437dfb2a4146deada934bcdb354..eee779f26cc4c633b9e5c47e2b156e6f4f2481ce 100644 --- a/arch/metag/include/asm/atomic_lock1.h +++ b/arch/metag/include/asm/atomic_lock1.h @@ -37,6 +37,8 @@ static inline int atomic_set(atomic_t *v, int i) return i; } +#define atomic_set_release(v, i) atomic_set((v), (i)) + #define ATOMIC_OP(op, c_op) \ static inline void atomic_##op(int i, atomic_t *v) \ { \ diff --git a/arch/metag/include/asm/dma-mapping.h b/arch/metag/include/asm/dma-mapping.h index fad3dc3cb21008c59d612827c40282fae34d1827..ea573be2b6d0550e46a170c8a72178953022f4f3 100644 --- a/arch/metag/include/asm/dma-mapping.h +++ b/arch/metag/include/asm/dma-mapping.h @@ -9,7 +9,7 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) } /* - * dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to + * dma_alloc_attrs() always returns non-cacheable memory, so there's no need to * do any flushing here. */ static inline void diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h index ec6a49076980fff90dc04ece4b389ea1782449b9..8ae92d6abfd2e24d9e6d767fab2fc83db8720fcf 100644 --- a/arch/metag/include/asm/processor.h +++ b/arch/metag/include/asm/processor.h @@ -131,9 +131,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - /* * Return saved PC of a blocked thread. */ diff --git a/arch/metag/include/asm/spinlock.h b/arch/metag/include/asm/spinlock.h index c0c7a22be1aeff1769308825d9d739837c8baaaa..ddf7fe5708a6ba079a3f50496eeec34f8de8fbc2 100644 --- a/arch/metag/include/asm/spinlock.h +++ b/arch/metag/include/asm/spinlock.h @@ -15,11 +15,6 @@ * locked. */ -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) diff --git a/arch/metag/include/asm/topology.h b/arch/metag/include/asm/topology.h index e95f874ded1bc14bb2c69ab26a4eb40554ab0634..707c7f7b6beabb3647c70c39d34e64d7efdacc36 100644 --- a/arch/metag/include/asm/topology.h +++ b/arch/metag/include/asm/topology.h @@ -4,7 +4,6 @@ #ifdef CONFIG_NUMA #define cpu_to_node(cpu) ((void)(cpu), 0) -#define parent_node(node) ((void)(node), 0) #define cpumask_of_node(node) ((void)node, cpu_online_mask) diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 4ed8ebf33509e5c5d843e1badf3c548c4bac6420..4f798aa671ddd2f481c35689f03be1ea73318ae8 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -36,6 +36,22 @@ config MICROBLAZE select VIRT_TO_BUS select CPU_NO_EFFICIENT_FFS +# Endianness selection +choice + prompt "Endianness selection" + default CPU_LITTLE_ENDIAN + help + microblaze architectures can be configured for either little or + big endian formats. Be sure to select the appropriate mode. + +config CPU_BIG_ENDIAN + bool "Big endian" + +config CPU_LITTLE_ENDIAN + bool "Little endian" + +endchoice + config SWAP def_bool n diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 740f2b82a182a9761b79028d38bde746ba7131c3..1f6c486826a0ee19880b8e7c6eb97f2a267f1bb5 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -35,6 +35,8 @@ endif CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) += -mxl-pattern-compare +CPUFLAGS-$(CONFIG_BIG_ENDIAN) += -mbig-endian +CPUFLAGS-$(CONFIG_LITTLE_ENDIAN) += -mlittle-endian CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER)) diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h index f23c3d266bae3e4e8eb006deca5bbfeed10cecbe..3d2747d4c9672d8a2178df115e3f75c66d88e443 100644 --- a/arch/microblaze/include/asm/flat.h +++ b/arch/microblaze/include/asm/flat.h @@ -60,7 +60,7 @@ static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, * unaligned. */ -static inline void +static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 relval) { u32 *p = (__force u32 *)rp; diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h index 01848f056f439d251f9f61dcc0806a8d47aad4ba..a9dad9e5e132f1c0f3aa3df6af6efdfba8edf1a6 100644 --- a/arch/microblaze/include/asm/futex.h +++ b/arch/microblaze/include/asm/futex.h @@ -29,18 +29,9 @@ }) static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -66,30 +57,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index efd4983cb6972a2b774950617141b9ace491230f..114b93488193283e4f1801b59d3a4fdf50704ab9 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -81,9 +81,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, #define HAVE_ARCH_PCI_RESOURCE_TO_USER -extern void pcibios_setup_bus_devices(struct pci_bus *bus); -extern void pcibios_setup_bus_self(struct pci_bus *bus); - /* This part of code was originally in xilinx-pci.h */ #ifdef CONFIG_PCI_XILINX extern void __init xilinx_pci_init(void); diff --git a/arch/microblaze/include/uapi/asm/Kbuild b/arch/microblaze/include/uapi/asm/Kbuild index e77a596f3f1efcfe94c4bc89b9b3cc860d589210..06609ca361150ab77529bf0999d8e258ad25d62c 100644 --- a/arch/microblaze/include/uapi/asm/Kbuild +++ b/arch/microblaze/include/uapi/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += fcntl.h generic-y += ioctl.h generic-y += ioctls.h generic-y += ipcbuf.h +generic-y += kvm_para.h generic-y += mman.h generic-y += msgbuf.h generic-y += param.h diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index e45ada8fb00669a8889284db230908ed64f2dda1..94700c5270a91e69cb0acb7b32b20f272899a1a6 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -165,7 +165,7 @@ int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma, unsigned long attrs) { #ifdef CONFIG_MMU - unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + unsigned long user_count = vma_pages(vma); unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; unsigned long off = vma->vm_pgoff; unsigned long pfn; diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index ea2d83f1f4bb3a7bb7af9247488f8f7679aa918c..7de941cbbd940fb7ca72840e3bf6422993c6eb94 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -293,7 +293,7 @@ static int __init xilinx_timer_init(struct device_node *timer) return -EINVAL; } - pr_info("%s: irq=%d\n", timer->full_name, irq); + pr_info("%pOF: irq=%d\n", timer, irq); clk = of_clk_get(timer, 0); if (IS_ERR(clk)) { diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 404fb38d06b7627525998909ebfeac5653996401..ae79e8638d50ba18410bfeb0cdcc227b5b481dc4 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -508,8 +508,8 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, struct of_pci_range range; struct of_pci_range_parser parser; - pr_info("PCI host bridge %s %s ranges:\n", - dev->full_name, primary ? "(primary)" : ""); + pr_info("PCI host bridge %pOF %s ranges:\n", + dev, primary ? "(primary)" : ""); /* Check for ranges property */ if (of_pci_range_parser_init(&parser, dev)) @@ -678,144 +678,6 @@ static void pcibios_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); -/* This function tries to figure out if a bridge resource has been initialized - * by the firmware or not. It doesn't have to be absolutely bullet proof, but - * things go more smoothly when it gets it right. It should covers cases such - * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges - */ -static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, - struct resource *res) -{ - struct pci_controller *hose = pci_bus_to_host(bus); - struct pci_dev *dev = bus->self; - resource_size_t offset; - u16 command; - int i; - - /* Job is a bit different between memory and IO */ - if (res->flags & IORESOURCE_MEM) { - /* If the BAR is non-0 (res != pci_mem_offset) then it's - * probably been initialized by somebody - */ - if (res->start != hose->pci_mem_offset) - return 0; - - /* The BAR is 0, let's check if memory decoding is enabled on - * the bridge. If not, we consider it unassigned - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if ((command & PCI_COMMAND_MEMORY) == 0) - return 1; - - /* Memory decoding is enabled and the BAR is 0. If any of - * the bridge resources covers that starting address (0 then - * it's good enough for us for memory - */ - for (i = 0; i < 3; i++) { - if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && - hose->mem_resources[i].start == hose->pci_mem_offset) - return 0; - } - - /* Well, it starts at 0 and we know it will collide so we may as - * well consider it as unassigned. That covers the Apple case. - */ - return 1; - } else { - /* If the BAR is non-0, then we consider it assigned */ - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - if (((res->start - offset) & 0xfffffffful) != 0) - return 0; - - /* Here, we are a bit different than memory as typically IO - * space starting at low addresses -is- valid. What we do - * instead if that we consider as unassigned anything that - * doesn't have IO enabled in the PCI command register, - * and that's it. - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if (command & PCI_COMMAND_IO) - return 0; - - /* It's starting at 0 and IO is disabled in the bridge, consider - * it unassigned - */ - return 1; - } -} - -/* Fixup resources of a PCI<->PCI bridge */ -static void pcibios_fixup_bridge(struct pci_bus *bus) -{ - struct resource *res; - int i; - - struct pci_dev *dev = bus->self; - - pci_bus_for_each_resource(bus, res, i) { - if (!res) - continue; - if (!res->flags) - continue; - if (i >= 3 && bus->self->transparent) - continue; - - pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", - pci_name(dev), i, - (unsigned long long)res->start, - (unsigned long long)res->end, - (unsigned int)res->flags); - - /* Try to detect uninitialized P2P bridge resources, - * and clear them out so they get re-assigned later - */ - if (pcibios_uninitialized_bridge_resource(bus, res)) { - res->flags = 0; - pr_debug("PCI:%s (unassigned)\n", - pci_name(dev)); - } else { - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); - } - } -} - -void pcibios_setup_bus_self(struct pci_bus *bus) -{ - /* Fix up the bus resources for P2P bridges */ - if (bus->self != NULL) - pcibios_fixup_bridge(bus); -} - -void pcibios_setup_bus_devices(struct pci_bus *bus) -{ - struct pci_dev *dev; - - pr_debug("PCI: Fixup bus devices %d (%s)\n", - bus->number, bus->self ? pci_name(bus->self) : "PHB"); - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* Setup OF node pointer in archdata */ - dev->dev.of_node = pci_device_to_OF_node(dev); - - /* Fixup NUMA node as it may not be setup yet by the generic - * code and is needed by the DMA init - */ - set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); - - /* Read default IRQs and fixup if necessary */ - dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); - } -} - -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* nothing to do */ -} -EXPORT_SYMBOL(pcibios_fixup_bus); - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -829,13 +691,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - int pcibios_add_device(struct pci_dev *dev) { dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); @@ -1219,8 +1074,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, if (!res->flags) { pr_warn("PCI: I/O resource not set for host "); - pr_cont("bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + pr_cont("bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); /* Workaround for lack of IO resource only on 32-bit */ res->start = (unsigned long)hose->io_base_virt - isa_io_base; res->end = res->start + IO_SPACE_LIMIT; @@ -1241,8 +1096,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, if (i > 0) continue; pr_err("PCI: Memory resource 0 not set for "); - pr_cont("host bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + pr_cont("host bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); /* Workaround for lack of MEM resource only on 32-bit */ res->start = hose->pci_mem_offset; @@ -1270,7 +1125,7 @@ static void pcibios_scan_phb(struct pci_controller *hose) struct pci_bus *bus; struct device_node *node = hose->dn; - pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node)); + pr_debug("PCI: Scanning PHB %pOF\n", node); pcibios_setup_phb_resources(hose, &resources); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8dd20358464f8efabcad2185d2b6f56c4fe805fa..cb7fcc4216fdfa5d25e6a76265efc0b66b81e0ad 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1627,14 +1627,6 @@ config CPU_R5500 NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV instruction set. -config CPU_R6000 - bool "R6000" - depends on SYS_HAS_CPU_R6000 - select CPU_SUPPORTS_32BIT_KERNEL - help - MIPS Technologies R6000 and R6000A series processors. Note these - processors are extremely rare and the support for them is incomplete. - config CPU_NEVADA bool "RM52xx" depends on SYS_HAS_CPU_NEVADA @@ -1950,9 +1942,6 @@ config SYS_HAS_CPU_R5432 config SYS_HAS_CPU_R5500 bool -config SYS_HAS_CPU_R6000 - bool - config SYS_HAS_CPU_NEVADA bool @@ -2180,7 +2169,7 @@ config PAGE_SIZE_32KB config PAGE_SIZE_64KB bool "64kB" - depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000 + depends on !CPU_R3000 && !CPU_TX39XX help Using 64kB page size will result in higher performance kernel at the price of higher memory consumption. This option is available on @@ -2248,11 +2237,11 @@ config CPU_HAS_PREFETCH config CPU_GENERIC_DUMP_TLB bool - default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX) + default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX) config CPU_R4K_FPU bool - default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON) + default y if !(CPU_R3000 || CPU_TX39XX) config CPU_R4K_CACHE_TLB bool @@ -2260,7 +2249,8 @@ config CPU_R4K_CACHE_TLB config MIPS_MT_SMP bool "MIPS MT SMP support (1 TC on each available VPE)" - depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 + default y + depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI select SYNC_R4K @@ -2376,7 +2366,6 @@ config MIPS_CPS bool "MIPS Coherent Processing System support" depends on SYS_SUPPORTS_MIPS_CPS select MIPS_CM - select MIPS_CPC select MIPS_CPS_PM if HOTPLUG_CPU select SMP select SYNC_R4K if (CEVT_R4K || CSRC_R4K) @@ -2393,11 +2382,11 @@ config MIPS_CPS config MIPS_CPS_PM depends on MIPS_CPS - select MIPS_CPC bool config MIPS_CM bool + select MIPS_CPC config MIPS_CPC bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 04343625b9292807d886951eaed6866426dfc42d..a96d97a806c9906e826ae8a1086be7eb7a8ff65f 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -151,7 +151,6 @@ cflags-y += -fno-stack-check # cflags-$(CONFIG_CPU_R3000) += -march=r3000 cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 -cflags-$(CONFIG_CPU_R6000) += -march=r6000 -Wa,--trap cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap @@ -243,8 +242,21 @@ include arch/mips/Kbuild.platforms ifdef CONFIG_PHYSICAL_START load-y = $(CONFIG_PHYSICAL_START) endif -entry-y = 0x$(shell $(NM) vmlinux 2>/dev/null \ + +entry-noisa-y = 0x$(shell $(NM) vmlinux 2>/dev/null \ | grep "\bkernel_entry\b" | cut -f1 -d \ ) +ifdef CONFIG_CPU_MICROMIPS + # + # Set the ISA bit, since the kernel_entry symbol in the ELF will have it + # clear which would lead to images containing addresses which bootloaders may + # jump to as MIPS32 code. + # + entry-y = $(patsubst %0,%1,$(patsubst %2,%3,$(patsubst %4,%5, \ + $(patsubst %6,%7,$(patsubst %8,%9,$(patsubst %a,%b, \ + $(patsubst %c,%d,$(patsubst %e,%f,$(entry-noisa-y))))))))) +else + entry-y = $(entry-noisa-y) +endif cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ @@ -278,7 +290,8 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ VMLINUX_ENTRY_ADDRESS=$(entry-y) \ - PLATFORM="$(platform-y)" + PLATFORM="$(platform-y)" \ + ITS_INPUTS="$(its-y)" ifdef CONFIG_32BIT bootvars-y += ADDR_BITS=32 endif @@ -286,6 +299,10 @@ ifdef CONFIG_64BIT bootvars-y += ADDR_BITS=64 endif +# This is required to get dwarf unwinding tables into .debug_frame +# instead of .eh_frame so we don't discard them. +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables + LDFLAGS += -m $(ld-emul) ifdef CONFIG_MIPS @@ -487,8 +504,14 @@ $(eval $(call gen_generic_defconfigs,micro32,r2,eb el)) .PHONY: $(generic_defconfigs) $(generic_defconfigs): $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ - -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \ - $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) + -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ | \ + grep -Ev '^#' + $(Q)cp $(KCONFIG_CONFIG) $(objtree)/.config.$@ + $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig \ + KCONFIG_CONFIG=$(objtree)/.config.$@ >/dev/null + $(Q)$(CONFIG_SHELL) $(srctree)/arch/$(ARCH)/tools/generic-board-config.sh \ + $(srctree) $(objtree) $(objtree)/.config.$@ $(KCONFIG_CONFIG) \ + "$(origin BOARDS)" $(BOARDS) $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig # @@ -496,6 +519,19 @@ $(generic_defconfigs): # $(generic_config_dir)/%.config: ; +# +# Prevent direct use of generic_defconfig, which is intended to be used as the +# basis of the various ISA-specific targets generated above. +# +.PHONY: generic_defconfig +generic_defconfig: + $(Q)echo "generic_defconfig is not intended for direct use, but should instead be" + $(Q)echo "used via an ISA-specific target from the following list:" + $(Q)echo + $(Q)for cfg in $(generic_defconfigs); do echo " $${cfg}"; done + $(Q)echo + $(Q)false + # # Legacy defconfig compatibility - these targets used to be real defconfigs but # now that the boards have been converted to use the generic kernel they are diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 992442a03d8ba00d5ab7541b57074ebf3ec0a30d..da76637704253e3610f4f15b69a42e75af99d516 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -344,28 +344,32 @@ static struct platform_device db1200_ide_dev = { /* SD carddetects: they're supposed to be edge-triggered, but ack * doesn't seem to work (CPLD Rev 2). Instead, the screaming one - * is disabled and its counterpart enabled. The 500ms timeout is - * because the carddetect isn't debounced in hardware. + * is disabled and its counterpart enabled. The 200ms timeout is + * because the carddetect usually triggers twice, after debounce. */ static irqreturn_t db1200_mmc_cd(int irq, void *ptr) { - void(*mmc_cd)(struct mmc_host *, unsigned long); + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} - if (irq == DB1200_SD0_INSERT_INT) { - disable_irq_nosync(DB1200_SD0_INSERT_INT); - enable_irq(DB1200_SD0_EJECT_INT); - } else { - disable_irq_nosync(DB1200_SD0_EJECT_INT); - enable_irq(DB1200_SD0_INSERT_INT); - } +static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr) +{ + void (*mmc_cd)(struct mmc_host *, unsigned long); /* link against CONFIG_MMC=m */ mmc_cd = symbol_get(mmc_detect_change); if (mmc_cd) { - mmc_cd(ptr, msecs_to_jiffies(500)); + mmc_cd(ptr, msecs_to_jiffies(200)); symbol_put(mmc_detect_change); } + msleep(100); /* debounce */ + if (irq == DB1200_SD0_INSERT_INT) + enable_irq(DB1200_SD0_EJECT_INT); + else + enable_irq(DB1200_SD0_INSERT_INT); + return IRQ_HANDLED; } @@ -374,13 +378,13 @@ static int db1200_mmc_cd_setup(void *mmc_host, int en) int ret; if (en) { - ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd, - 0, "sd_insert", mmc_host); + ret = request_threaded_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd, + db1200_mmc_cdfn, 0, "sd_insert", mmc_host); if (ret) goto out; - ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd, - 0, "sd_eject", mmc_host); + ret = request_threaded_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd, + db1200_mmc_cdfn, 0, "sd_eject", mmc_host); if (ret) { free_irq(DB1200_SD0_INSERT_INT, mmc_host); goto out; @@ -436,23 +440,27 @@ static struct led_classdev db1200_mmc_led = { static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr) { - void(*mmc_cd)(struct mmc_host *, unsigned long); + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} - if (irq == PB1200_SD1_INSERT_INT) { - disable_irq_nosync(PB1200_SD1_INSERT_INT); - enable_irq(PB1200_SD1_EJECT_INT); - } else { - disable_irq_nosync(PB1200_SD1_EJECT_INT); - enable_irq(PB1200_SD1_INSERT_INT); - } +static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr) +{ + void (*mmc_cd)(struct mmc_host *, unsigned long); /* link against CONFIG_MMC=m */ mmc_cd = symbol_get(mmc_detect_change); if (mmc_cd) { - mmc_cd(ptr, msecs_to_jiffies(500)); + mmc_cd(ptr, msecs_to_jiffies(200)); symbol_put(mmc_detect_change); } + msleep(100); /* debounce */ + if (irq == PB1200_SD1_INSERT_INT) + enable_irq(PB1200_SD1_EJECT_INT); + else + enable_irq(PB1200_SD1_INSERT_INT); + return IRQ_HANDLED; } @@ -461,13 +469,13 @@ static int pb1200_mmc1_cd_setup(void *mmc_host, int en) int ret; if (en) { - ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0, - "sd1_insert", mmc_host); + ret = request_threaded_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, + pb1200_mmc1_cdfn, 0, "sd1_insert", mmc_host); if (ret) goto out; - ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0, - "sd1_eject", mmc_host); + ret = request_threaded_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, + pb1200_mmc1_cdfn, 0, "sd1_eject", mmc_host); if (ret) { free_irq(PB1200_SD1_INSERT_INT, mmc_host); goto out; diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index a5504f57cb00f595e097c545cbd25ba4d89715a4..cd1ae29f95a378e76fea3d8f189ee904197bde99 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -450,24 +450,27 @@ static struct platform_device db1300_ide_dev = { static irqreturn_t db1300_mmc_cd(int irq, void *ptr) { - void(*mmc_cd)(struct mmc_host *, unsigned long); + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} - /* disable the one currently screaming. No other way to shut it up */ - if (irq == DB1300_SD1_INSERT_INT) { - disable_irq_nosync(DB1300_SD1_INSERT_INT); - enable_irq(DB1300_SD1_EJECT_INT); - } else { - disable_irq_nosync(DB1300_SD1_EJECT_INT); - enable_irq(DB1300_SD1_INSERT_INT); - } +static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr) +{ + void (*mmc_cd)(struct mmc_host *, unsigned long); /* link against CONFIG_MMC=m. We can only be called once MMC core has * initialized the controller, so symbol_get() should always succeed. */ mmc_cd = symbol_get(mmc_detect_change); - mmc_cd(ptr, msecs_to_jiffies(500)); + mmc_cd(ptr, msecs_to_jiffies(200)); symbol_put(mmc_detect_change); + msleep(100); /* debounce */ + if (irq == DB1300_SD1_INSERT_INT) + enable_irq(DB1300_SD1_EJECT_INT); + else + enable_irq(DB1300_SD1_INSERT_INT); + return IRQ_HANDLED; } @@ -487,13 +490,13 @@ static int db1300_mmc_cd_setup(void *mmc_host, int en) int ret; if (en) { - ret = request_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, 0, - "sd_insert", mmc_host); + ret = request_threaded_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, + db1300_mmc_cdfn, 0, "sd_insert", mmc_host); if (ret) goto out; - ret = request_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, 0, - "sd_eject", mmc_host); + ret = request_threaded_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, + db1300_mmc_cdfn, 0, "sd_eject", mmc_host); if (ret) { free_irq(DB1300_SD1_INSERT_INT, mmc_host); goto out; diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index 1c01d6eadb08d89a56519b512cc02cb1a186704b..421bd5793f7e3d6281973336d74424248aa16b5b 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/alchemy/devboards/db1xxx.c b/arch/mips/alchemy/devboards/db1xxx.c index 2d47f951121a710fb5960fdae14d28a777e07997..c9ad28995cd2d637ca4bc37ffeec5e7f853d26bc 100644 --- a/arch/mips/alchemy/devboards/db1xxx.c +++ b/arch/mips/alchemy/devboards/db1xxx.c @@ -2,6 +2,7 @@ * Alchemy DB/PB1xxx board support. */ +#include #include #include @@ -97,6 +98,7 @@ arch_initcall(db1xxx_arch_init); static int __init db1xxx_dev_init(void) { + mips_set_machine_name(board_type_str()); switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { case BCSR_WHOAMI_DB1000: case BCSR_WHOAMI_DB1500: diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index dda422a0f36cdc17f9c897bfbdb5455b72e7e072..0137656107a9c5b58c2dcdcaa6bac2132fb1957d 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c @@ -430,6 +430,9 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } EXPORT_SYMBOL(clk_get_rate); diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index fa845953f736f87af7f62100a0b4ac149b3f331b..6b1000b6a6a6717a2e18032a644feef99666a9b4 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -487,17 +487,16 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np) { struct clk *ref_clk; void __iomem *pll_base; - const char *dnfn = of_node_full_name(np); ref_clk = of_clk_get(np, 0); if (IS_ERR(ref_clk)) { - pr_err("%s: of_clk_get failed\n", dnfn); + pr_err("%pOF: of_clk_get failed\n", np); goto err; } pll_base = of_iomap(np, 0); if (!pll_base) { - pr_err("%s: can't map pll registers\n", dnfn); + pr_err("%pOF: can't map pll registers\n", np); goto err_clk; } @@ -506,12 +505,12 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np) else if (of_device_is_compatible(np, "qca,ar9330-pll")) ar9330_clk_init(ref_clk, pll_base); else { - pr_err("%s: could not find any appropriate clk_init()\n", dnfn); + pr_err("%pOF: could not find any appropriate clk_init()\n", np); goto err_iounmap; } if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { - pr_err("%s: could not register clk provider\n", dnfn); + pr_err("%pOF: could not register clk provider\n", np); goto err_iounmap; } diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index 730c0b03060d0c941eaf29ee394f3c55be121954..b816cb4a25ff95eb7ca737f3296a71c5aea54830 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -22,10 +22,10 @@ #include "pci.h" static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); -static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; -static unsigned ath79_pci_nr_irqs __initdata; +static const struct ath79_pci_irq *ath79_pci_irq_map; +static unsigned ath79_pci_nr_irqs; -static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { { .slot = 17, .pin = 1, @@ -41,7 +41,7 @@ static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { } }; -static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq ar724x_pci_irq_map[] = { { .slot = 0, .pin = 1, @@ -49,7 +49,7 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { } }; -static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq qca955x_pci_irq_map[] = { { .bus = 0, .slot = 0, @@ -64,7 +64,7 @@ static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { }, }; -int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) +int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) { int irq = -1; int i; diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index 73626040e4d6a1150f8ac02719eef9b6f7a31d4d..19577f771c1f0ce4ecc5376c40c14f4d138520e7 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -339,6 +339,9 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index 145b5ce8eb7e660dda67f6a53aa472f74a413af0..1bd5c4f00d19bd7ff4aee34789e0fbb371240a4d 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -118,6 +118,12 @@ ifeq ($(ADDR_BITS),64) itb_addr_cells = 2 endif +quiet_cmd_its_cat = CAT $@ + cmd_its_cat = cat $^ >$@ + +$(obj)/vmlinux.its.S: $(addprefix $(srctree)/arch/mips/$(PLATFORM)/,$(ITS_INPUTS)) + $(call if_changed,its_cat) + quiet_cmd_cpp_its_S = ITS $@ cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ @@ -128,19 +134,19 @@ quiet_cmd_cpp_its_S = ITS $@ -DADDR_BITS=$(ADDR_BITS) \ -DADDR_CELLS=$(itb_addr_cells) -$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) -$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.gz.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz) -$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.bz2.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2) -$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.lzma.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma) -$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.lzo.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo) quiet_cmd_itb-image = ITB $@ diff --git a/arch/mips/boot/compressed/.gitignore b/arch/mips/boot/compressed/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ebae133f1d000b096733e361e4a7a5003a6c9e67 --- /dev/null +++ b/arch/mips/boot/compressed/.gitignore @@ -0,0 +1,2 @@ +ashldi3.c +bswapsi.c diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index b9db49203e0c08a1d427fee24864074891c146b2..cbac26ce063ef2954472d9ec0cae42855c7b35d7 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -5,6 +5,7 @@ dts-dirs += ingenic dts-dirs += lantiq dts-dirs += mti dts-dirs += netlogic +dts-dirs += ni dts-dirs += pic32 dts-dirs += qca dts-dirs += ralink diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index fd138d9978c11fb68812f7a2a97b9ec464a8a9ab..6c381844929cf41c5fedba979c1eff2b2b0450b4 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -1,6 +1,7 @@ /dts-v1/; #include "jz4780.dtsi" +#include / { compatible = "img,ci20", "ingenic,jz4780"; @@ -21,6 +22,13 @@ reg = <0x0 0x10000000 0x30000000 0x30000000>; }; + + eth0_power: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "eth0_power"; + gpio = <&gpb 25 GPIO_ACTIVE_LOW>; + enable-active-high; + }; }; &ext { @@ -123,6 +131,29 @@ }; }; }; + + dm9000@6 { + compatible = "davicom,dm9000"; + davicom,no-eeprom; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_nemc_cs6>; + + reg = <6 0 1 /* addr */ + 6 2 1>; /* data */ + + ingenic,nemc-tAS = <15>; + ingenic,nemc-tAH = <10>; + ingenic,nemc-tBP = <20>; + ingenic,nemc-tAW = <50>; + ingenic,nemc-tSTRV = <100>; + + reset-gpios = <&gpf 12 GPIO_ACTIVE_HIGH>; + vcc-supply = <ð0_power>; + + interrupt-parent = <&gpe>; + interrupts = <19 4>; + }; }; &bch { @@ -165,4 +196,10 @@ groups = "nemc-cs1"; bias-disable; }; + + pins_nemc_cs6: nemc-cs6 { + function = "nemc-cs6"; + groups = "nemc-cs6"; + bias-disable; + }; }; diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index 4853ef67b3ab3c556abe4b0fa7876689cab39ebf..e906134ecaef3a194296645aac76a7dcab599d9c 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi @@ -44,6 +44,17 @@ #clock-cells = <1>; }; + rtc_dev: rtc@10003000 { + compatible = "ingenic,jz4780-rtc"; + reg = <0x10003000 0x4c>; + + interrupt-parent = <&intc>; + interrupts = <32>; + + clocks = <&cgu JZ4780_CLK_RTCLK>; + clock-names = "rtc"; + }; + pinctrl: pin-controller@10010000 { compatible = "ingenic,jz4780-pinctrl"; reg = <0x10010000 0x600>; diff --git a/arch/mips/boot/dts/ni/169445.dts b/arch/mips/boot/dts/ni/169445.dts new file mode 100644 index 0000000000000000000000000000000000000000..5389ef46c48092471928902dfadbb38dfb8edcfe --- /dev/null +++ b/arch/mips/boot/dts/ni/169445.dts @@ -0,0 +1,100 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ni,169445"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "mti,mips14KEc"; + clocks = <&baseclk>; + reg = <0>; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x10000000>; + }; + + baseclk: baseclock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + interrupt-controller; + #interrupt-cells = <1>; + }; + + ahb@1f300000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1f300000 0x80FFF>; + + gpio1: gpio@10 { + compatible = "ni,169445-nand-gpio"; + reg = <0x10 0x4>; + reg-names = "dat"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio2: gpio@14 { + compatible = "ni,169445-nand-gpio"; + reg = <0x14 0x4>; + reg-names = "dat"; + gpio-controller; + #gpio-cells = <2>; + no-output; + }; + + nand@0 { + compatible = "gpio-control-nand"; + nand-on-flash-bbt; + nand-ecc-mode = "soft_bch"; + nand-ecc-step-size = <512>; + nand-ecc-strength = <4>; + reg = <0x0 4>; + gpios = <&gpio2 0 0>, /* rdy */ + <&gpio1 1 0>, /* nce */ + <&gpio1 2 0>, /* ale */ + <&gpio1 3 0>, /* cle */ + <&gpio1 4 0>; /* nwp */ + }; + + serial@80000 { + compatible = "ns16550a"; + reg = <0x80000 0x1000>; + interrupt-parent = <&cpu_intc>; + interrupts = <6>; + clocks = <&baseclk>; + reg-shift = <0>; + }; + + ethernet@40000 { + compatible = "snps,dwmac-4.10a"; + interrupt-parent = <&cpu_intc>; + interrupts = <5>; + interrupt-names = "macirq"; + reg = <0x40000 0x2000>; + clock-names = "stmmaceth", "pclk"; + clocks = <&baseclk>, <&baseclk>; + + phy-mode = "rgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; diff --git a/arch/mips/boot/dts/ni/Makefile b/arch/mips/boot/dts/ni/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..66cfdffc51c2d193a62b41dc1b3b8a2d64bcc018 --- /dev/null +++ b/arch/mips/boot/dts/ni/Makefile @@ -0,0 +1,7 @@ +dtb-$(CONFIG_FIT_IMAGE_FDT_NI169445) += 169445.dtb + +# Force kbuild to make empty built-in.o if necessary +obj- += dummy.o + +always := $(dtb-y) +clean-files := *.dtb *.dtb.S diff --git a/arch/mips/boot/dts/ralink/Makefile b/arch/mips/boot/dts/ralink/Makefile index 2a7225954bf6be48c9a7c024f9177de33787c3be..55e2937b61f3810c5654713dc55ef5b01694421e 100644 --- a/arch/mips/boot/dts/ralink/Makefile +++ b/arch/mips/boot/dts/ralink/Makefile @@ -2,6 +2,8 @@ dtb-$(CONFIG_DTB_RT2880_EVAL) += rt2880_eval.dtb dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb +dtb-$(CONFIG_DTB_OMEGA2P) += omega2p.dtb +dtb-$(CONFIG_DTB_VOCORE2) += vocore2.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/ralink/mt7628a.dtsi b/arch/mips/boot/dts/ralink/mt7628a.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..9ff7e8faaeccafa948c81df8cd98fed60c339426 --- /dev/null +++ b/arch/mips/boot/dts/ralink/mt7628a.dtsi @@ -0,0 +1,126 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ralink,mt7628a-soc"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mti,mips24KEc"; + device_type = "cpu"; + reg = <0>; + }; + }; + + resetc: reset-controller { + compatible = "ralink,rt2880-reset"; + #reset-cells = <1>; + }; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + palmbus@10000000 { + compatible = "palmbus"; + reg = <0x10000000 0x200000>; + ranges = <0x0 0x10000000 0x1FFFFF>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "ralink,mt7620a-sysc", "syscon"; + reg = <0x0 0x100>; + }; + + intc: interrupt-controller@200 { + compatible = "ralink,rt2880-intc"; + reg = <0x200 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + resets = <&resetc 9>; + reset-names = "intc"; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + + ralink,intc-registers = <0x9c 0xa0 + 0x6c 0xa4 + 0x80 0x78>; + }; + + memory-controller@300 { + compatible = "ralink,mt7620a-memc"; + reg = <0x300 0x100>; + }; + + uart0: uartlite@c00 { + compatible = "ns16550a"; + reg = <0xc00 0x100>; + + resets = <&resetc 12>; + reset-names = "uart0"; + + interrupt-parent = <&intc>; + interrupts = <20>; + + reg-shift = <2>; + }; + + uart1: uart1@d00 { + compatible = "ns16550a"; + reg = <0xd00 0x100>; + + resets = <&resetc 19>; + reset-names = "uart1"; + + interrupt-parent = <&intc>; + interrupts = <21>; + + reg-shift = <2>; + }; + + uart2: uart2@e00 { + compatible = "ns16550a"; + reg = <0xe00 0x100>; + + resets = <&resetc 20>; + reset-names = "uart2"; + + interrupt-parent = <&intc>; + interrupts = <22>; + + reg-shift = <2>; + }; + }; + + usb_phy: usb-phy@10120000 { + compatible = "mediatek,mt7628-usbphy"; + reg = <0x10120000 0x1000>; + + #phy-cells = <0>; + + ralink,sysctl = <&sysc>; + resets = <&resetc 22 &resetc 25>; + reset-names = "host", "device"; + }; + + ehci@101c0000 { + compatible = "generic-ehci"; + reg = <0x101c0000 0x1000>; + + phys = <&usb_phy>; + phy-names = "usb"; + + interrupt-parent = <&intc>; + interrupts = <18>; + }; +}; diff --git a/arch/mips/boot/dts/ralink/omega2p.dts b/arch/mips/boot/dts/ralink/omega2p.dts new file mode 100644 index 0000000000000000000000000000000000000000..5884fd48f59a62988f5b2246cc609745812ecbea --- /dev/null +++ b/arch/mips/boot/dts/ralink/omega2p.dts @@ -0,0 +1,18 @@ +/dts-v1/; + +/include/ "mt7628a.dtsi" + +/ { + compatible = "onion,omega2+", "ralink,mt7688a-soc", "ralink,mt7628a-soc"; + model = "Onion Omega2+"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; diff --git a/arch/mips/boot/dts/ralink/vocore2.dts b/arch/mips/boot/dts/ralink/vocore2.dts new file mode 100644 index 0000000000000000000000000000000000000000..fa8a5f8f236a87cb3dde5c8482cd4eecd6ac6cb0 --- /dev/null +++ b/arch/mips/boot/dts/ralink/vocore2.dts @@ -0,0 +1,18 @@ +/dts-v1/; + +#include "mt7628a.dtsi" + +/ { + compatible = "vocore,vocore2", "ralink,mt7628a-soc"; + model = "VoCore2"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS2,115200"; + stdout-path = &uart2; + }; +}; diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile index b6d6e841a984ea61270581b4fed097dcd68897bf..50b427879465ef85a48aceb9b7efd65842473a0f 100644 --- a/arch/mips/cavium-octeon/executive/Makefile +++ b/arch/mips/cavium-octeon/executive/Makefile @@ -16,4 +16,4 @@ obj-y += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \ cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \ cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o -obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o +obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o cvmx-boot-vector.o diff --git a/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c b/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c new file mode 100644 index 0000000000000000000000000000000000000000..b7019d21808e04719e9913270dbab0c90438eadb --- /dev/null +++ b/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c @@ -0,0 +1,167 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004-2017 Cavium, Inc. + */ + + +/* + We install this program at the bootvector: +------------------------------------ + .set noreorder + .set nomacro + .set noat +reset_vector: + dmtc0 $k0, $31, 0 # Save $k0 to DESAVE + dmtc0 $k1, $31, 3 # Save $k1 to KScratch2 + + mfc0 $k0, $12, 0 # Status + mfc0 $k1, $15, 1 # Ebase + + ori $k0, 0x84 # Enable 64-bit addressing, set + # ERL (should already be set) + andi $k1, 0x3ff # mask out core ID + + mtc0 $k0, $12, 0 # Status + sll $k1, 5 + + lui $k0, 0xbfc0 + cache 17, 0($0) # Core-14345, clear L1 Dcache virtual + # tags if the core hit an NMI + + ld $k0, 0x78($k0) # k0 <- (bfc00078) pointer to the reset vector + synci 0($0) # Invalidate ICache to get coherent + # view of target code. + + daddu $k0, $k0, $k1 + nop + + ld $k0, 0($k0) # k0 <- core specific target address + dmfc0 $k1, $31, 3 # Restore $k1 from KScratch2 + + beqz $k0, wait_loop # Spin in wait loop + nop + + jr $k0 + nop + + nop # NOPs needed here to fill delay slots + nop # on endian reversal of previous instructions + +wait_loop: + wait + nop + + b wait_loop + nop + + nop + nop +------------------------------------ + +0000000000000000 : + 0: 40baf800 dmtc0 k0,c0_desave + 4: 40bbf803 dmtc0 k1,c0_kscratch2 + + 8: 401a6000 mfc0 k0,c0_status + c: 401b7801 mfc0 k1,c0_ebase + + 10: 375a0084 ori k0,k0,0x84 + 14: 337b03ff andi k1,k1,0x3ff + + 18: 409a6000 mtc0 k0,c0_status + 1c: 001bd940 sll k1,k1,0x5 + + 20: 3c1abfc0 lui k0,0xbfc0 + 24: bc110000 cache 0x11,0(zero) + + 28: df5a0078 ld k0,120(k0) + 2c: 041f0000 synci 0(zero) + + 30: 035bd02d daddu k0,k0,k1 + 34: 00000000 nop + + 38: df5a0000 ld k0,0(k0) + 3c: 403bf803 dmfc0 k1,c0_kscratch2 + + 40: 13400005 beqz k0,58 + 44: 00000000 nop + + 48: 03400008 jr k0 + 4c: 00000000 nop + + 50: 00000000 nop + 54: 00000000 nop + +0000000000000058 : + 58: 42000020 wait + 5c: 00000000 nop + + 60: 1000fffd b 58 + 64: 00000000 nop + + 68: 00000000 nop + 6c: 00000000 nop + + */ + +#include + +static unsigned long long _cvmx_bootvector_data[16] = { + 0x40baf80040bbf803ull, /* patch low order 8-bits if no KScratch*/ + 0x401a6000401b7801ull, + 0x375a0084337b03ffull, + 0x409a6000001bd940ull, + 0x3c1abfc0bc110000ull, + 0xdf5a0078041f0000ull, + 0x035bd02d00000000ull, + 0xdf5a0000403bf803ull, /* patch low order 8-bits if no KScratch*/ + 0x1340000500000000ull, + 0x0340000800000000ull, + 0x0000000000000000ull, + 0x4200002000000000ull, + 0x1000fffd00000000ull, + 0x0000000000000000ull, + OCTEON_BOOT_MOVEABLE_MAGIC1, + 0 /* To be filled in with address of vector block*/ +}; + +/* 2^10 CPUs */ +#define VECTOR_TABLE_SIZE (1024 * sizeof(struct cvmx_boot_vector_element)) + +static void cvmx_boot_vector_init(void *mem) +{ + uint64_t kseg0_mem; + int i; + + memset(mem, 0, VECTOR_TABLE_SIZE); + kseg0_mem = cvmx_ptr_to_phys(mem) | 0x8000000000000000ull; + + for (i = 0; i < 15; i++) { + uint64_t v = _cvmx_bootvector_data[i]; + + if (OCTEON_IS_OCTEON1PLUS() && (i == 0 || i == 7)) + v &= 0xffffffff00000000ull; /* KScratch not availble. */ + cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8); + cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, v); + } + cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, 15 * 8); + cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, kseg0_mem); + cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000); +} + +/** + * Get a pointer to the per-core table of reset vector pointers + * + */ +struct cvmx_boot_vector_element *cvmx_boot_vector_get(void) +{ + struct cvmx_boot_vector_element *ret; + + ret = cvmx_bootmem_alloc_named_range_once(VECTOR_TABLE_SIZE, 0, + (1ull << 32) - 1, 8, "__boot_vector1__", cvmx_boot_vector_init); + return ret; +} +EXPORT_SYMBOL(cvmx_boot_vector_get); diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c index 8d54d774933c560526831f5a3d76402cc2484820..94d97ebfa03604d28fe30c5c71ebde2c3a93cd9d 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c +++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c @@ -44,6 +44,55 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc; /* See header file for descriptions of functions */ +/** + * This macro returns the size of a member of a structure. + * Logically it is the same as "sizeof(s::field)" in C++, but + * C lacks the "::" operator. + */ +#define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field) + +/** + * This macro returns a member of the + * cvmx_bootmem_named_block_desc_t structure. These members can't + * be directly addressed as they might be in memory not directly + * reachable. In the case where bootmem is compiled with + * LINUX_HOST, the structure itself might be located on a remote + * Octeon. The argument "field" is the member name of the + * cvmx_bootmem_named_block_desc_t to read. Regardless of the type + * of the field, the return type is always a uint64_t. The "addr" + * parameter is the physical address of the structure. + */ +#define CVMX_BOOTMEM_NAMED_GET_FIELD(addr, field) \ + __cvmx_bootmem_desc_get(addr, \ + offsetof(struct cvmx_bootmem_named_block_desc, field), \ + SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field)) + +/** + * This function is the implementation of the get macros defined + * for individual structure members. The argument are generated + * by the macros inorder to read only the needed memory. + * + * @param base 64bit physical address of the complete structure + * @param offset Offset from the beginning of the structure to the member being + * accessed. + * @param size Size of the structure member. + * + * @return Value of the structure member promoted into a uint64_t. + */ +static inline uint64_t __cvmx_bootmem_desc_get(uint64_t base, int offset, + int size) +{ + base = (1ull << 63) | (base + offset); + switch (size) { + case 4: + return cvmx_read64_uint32(base); + case 8: + return cvmx_read64_uint64(base); + default: + return 0; + } +} + /* * Wrapper functions are provided for reading/writing the size and * next block values as these may not be directly addressible (in 32 @@ -98,6 +147,42 @@ void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment) return cvmx_bootmem_alloc_range(size, alignment, 0, 0); } +void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, + uint64_t max_addr, uint64_t align, + char *name, + void (*init) (void *)) +{ + int64_t addr; + void *ptr; + uint64_t named_block_desc_addr; + + named_block_desc_addr = (uint64_t) + cvmx_bootmem_phy_named_block_find(name, + (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); + + if (named_block_desc_addr) { + addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_desc_addr, + base_addr); + return cvmx_phys_to_ptr(addr); + } + + addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, + align, name, + (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); + + if (addr < 0) + return NULL; + ptr = cvmx_phys_to_ptr(addr); + + if (init) + init(ptr); + else + memset(ptr, 0, size); + + return ptr; +} +EXPORT_SYMBOL(cvmx_bootmem_alloc_named_range_once); + void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, char *name) diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index c1eb1ff7c80017f53e545229fdd6acbb1c91969d..5b3a3f6a9ad31fd845bd18cdd3197d9c75833c84 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -2963,3 +2963,12 @@ void octeon_fixup_irqs(void) } #endif /* CONFIG_HOTPLUG_CPU */ + +struct irq_domain *octeon_irq_get_block_domain(int node, uint8_t block) +{ + struct octeon_ciu3_info *ciu3_info; + + ciu3_info = octeon_ciu3_info_per_node[node & CVMX_NODE_MASK]; + return ciu3_info->domain[block]; +} +EXPORT_SYMBOL(octeon_irq_get_block_domain); diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c index 542be1cd0f32c6cbe14cb0c3936ffe9cd11bd594..bfdfaf32d2c49742066329e800a6b535f363c3e1 100644 --- a/arch/mips/cavium-octeon/octeon-usb.c +++ b/arch/mips/cavium-octeon/octeon-usb.c @@ -13,9 +13,9 @@ #include #include #include +#include #include -#include /* USB Control Register */ union cvm_usbdrd_uctl_ctl { diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 3de786545ded10ac64f5fa77d2025fa3a9955fd9..75e7c862565983b34f6cc127332f6e8b0f5832c7 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -205,7 +205,7 @@ int plat_post_relocation(long offset) * Firmware CPU startup hook * */ -static void octeon_boot_secondary(int cpu, struct task_struct *idle) +static int octeon_boot_secondary(int cpu, struct task_struct *idle) { int count; @@ -223,8 +223,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle) udelay(1); count--; } - if (count == 0) + if (count == 0) { pr_err("Secondary boot timeout\n"); + return -ETIMEDOUT; + } + + return 0; } /** @@ -408,7 +412,7 @@ late_initcall(register_cavium_notifier); #endif /* CONFIG_HOTPLUG_CPU */ -struct plat_smp_ops octeon_smp_ops = { +const struct plat_smp_ops octeon_smp_ops = { .send_ipi_single = octeon_send_ipi_single, .send_ipi_mask = octeon_send_ipi_mask, .init_secondary = octeon_init_secondary, @@ -485,7 +489,7 @@ static void octeon_78xx_send_ipi_mask(const struct cpumask *mask, octeon_78xx_send_ipi_single(cpu, action); } -static struct plat_smp_ops octeon_78xx_smp_ops = { +static const struct plat_smp_ops octeon_78xx_smp_ops = { .send_ipi_single = octeon_78xx_send_ipi_single, .send_ipi_mask = octeon_78xx_send_ipi_mask, .init_secondary = octeon_init_secondary, @@ -501,7 +505,7 @@ static struct plat_smp_ops octeon_78xx_smp_ops = { void __init octeon_setup_smp(void) { - struct plat_smp_ops *ops; + const struct plat_smp_ops *ops; if (octeon_has_feature(OCTEON_FEATURE_CIU3)) ops = &octeon_78xx_smp_ops; diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index e5b18f1a31a078b5a26e5caeae6059f7b2efec94..490b12af103c1285043ecfec912b1839c5586f06 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig @@ -60,11 +60,8 @@ CONFIG_BLK_DEV_SD=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_AHCI_OCTEON=y CONFIG_PATA_OCTEON_CF=y -CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y -CONFIG_MII=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set # CONFIG_NET_VENDOR_ALTEON is not set @@ -121,22 +118,30 @@ CONFIG_SPI=y CONFIG_SPI_OCTEON=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y -CONFIG_USB=m -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_EHCI_HCD_PLATFORM=m -CONFIG_USB_OHCI_HCD=m -CONFIG_USB_OHCI_HCD_PLATFORM=m +CONFIG_USB=y +# CONFIG_USB_PCI is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y CONFIG_MMC=y # CONFIG_PWRSEQ_EMMC is not set # CONFIG_PWRSEQ_SIMPLE is not set -# CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_CAVIUM_OCTEON=y +CONFIG_EDAC=y +CONFIG_EDAC_OCTEON_PC=y +CONFIG_EDAC_OCTEON_L2C=y +CONFIG_EDAC_OCTEON_LMC=y +CONFIG_EDAC_OCTEON_PCI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_STAGING=y CONFIG_OCTEON_ETHERNET=y -CONFIG_OCTEON_USB=m # CONFIG_IOMMU_SUPPORT is not set +CONFIG_RAS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index b42cfa7865f981e86e9fb6218cc3f292e1edaa34..5ea3104a3aca9891a10be74c5c6757a192febf71 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -91,6 +91,7 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_I2C=y CONFIG_I2C_JZ4780=y CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_INGENIC=y # CONFIG_HWMON is not set CONFIG_REGULATOR=y CONFIG_REGULATOR_DEBUG=y @@ -99,6 +100,8 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_JZ4740=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_MEMORY=y # CONFIG_DNOTIFY is not set diff --git a/arch/mips/configs/generic/board-ni169445.config b/arch/mips/configs/generic/board-ni169445.config new file mode 100644 index 0000000000000000000000000000000000000000..f72223b366cabc4294a4ec40c9e3eb5987cfb55f --- /dev/null +++ b/arch/mips/configs/generic/board-ni169445.config @@ -0,0 +1,30 @@ +# require CONFIG_CPU_MIPS32_R2=y +# require CONFIG_CPU_LITTLE_ENDIAN=y + +CONFIG_FIT_IMAGE_FDT_NI169445=y + +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y + +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC_PLATFORM=y + +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CMDLINE_PARTS=y + +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_BCH=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_GPIO=y +CONFIG_MTD_NAND_IDS=y + +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BLOCK=y + +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_DWMAC_GENERIC=y diff --git a/arch/mips/configs/generic/board-sead-3.config b/arch/mips/configs/generic/board-sead-3.config index 3b5e1ac579ebb78e38dd1abdcc6803b29a51bb0e..df49a592dbb5b288e9091b3b59e6fef7c3b1af4d 100644 --- a/arch/mips/configs/generic/board-sead-3.config +++ b/arch/mips/configs/generic/board-sead-3.config @@ -1,3 +1,5 @@ +# require CONFIG_32BIT=y + CONFIG_LEGACY_BOARD_SEAD3=y CONFIG_AUXDISPLAY=y diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig index 91aacf2ef26dd9572a2d2e3dac27bce59b253511..26b1cd5ffbf550d33b7ff1afe567b30bbfe265b5 100644 --- a/arch/mips/configs/generic_defconfig +++ b/arch/mips/configs/generic_defconfig @@ -3,7 +3,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_MIPS_CPS=y CONFIG_CPU_HAS_MSA=y CONFIG_HIGHMEM=y -CONFIG_NR_CPUS=2 +CONFIG_NR_CPUS=16 CONFIG_MIPS_O32_FP64_SUPPORT=y CONFIG_SYSVIPC=y CONFIG_NO_HZ_IDLE=y @@ -61,7 +61,6 @@ CONFIG_HID_KENSINGTON=y CONFIG_HID_LOGITECH=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y -# CONFIG_USB_SUPPORT is not set # CONFIG_MIPS_PLATFORM_DEVICES is not set # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT4_FS=y diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig index b1911816337c30561f421ed93f7b95196444011c..55438fc9991ec53715b392f074dbb3d864dc197c 100644 --- a/arch/mips/configs/gpr_defconfig +++ b/arch/mips/configs/gpr_defconfig @@ -111,12 +111,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 1ec8ed8d05d117c11e73ea467f6486a66550555e..02be95c1b7128436b1a30e0680298a384c098caa 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -37,7 +37,6 @@ CONFIG_PM=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="/dev/hda3" CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEBUG=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 078ecac071aba6f9a6a69510151144d8bea3da0e..396408404487e1a248bd331b228bc1d4199dc111 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_NR_CPUS=8 CONFIG_HZ_100=y CONFIG_SYSVIPC=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 80ecd94ed1263f4ce85494f361d1592989624b2c..5691673a332772dedd4af5c80af14c2102e79d88 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_NR_CPUS=8 CONFIG_HZ_100=y CONFIG_SYSVIPC=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index 35ad1f8d1a79cd015141fbf7c97f053f43bb6f61..e9cadb37d684f74321c508abf61e0df2b4951353 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -3,6 +3,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_KVM_GUEST=y CONFIG_PAGE_SIZE_16KB=y +# CONFIG_MIPS_MT_SMP is not set CONFIG_HZ_100=y CONFIG_SYSVIPC=y CONFIG_NO_HZ=y diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig index 55b68b981b057c56e2216fe6fc85545606b0088b..d8c8f5fb89180f956221cc3f913e7867d703b88a 100644 --- a/arch/mips/configs/maltasmvp_defconfig +++ b/arch/mips/configs/maltasmvp_defconfig @@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_SCHED_SMT=y CONFIG_MIPS_CPS=y CONFIG_NR_CPUS=8 diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig index 5ca590cf163581e69c0be8417536ea4d2ca8c550..04827bc9f87f97dd5aad599cc10fa9eb4fd22720 100644 --- a/arch/mips/configs/maltasmvp_eva_defconfig +++ b/arch/mips/configs/maltasmvp_eva_defconfig @@ -3,7 +3,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_CPU_MIPS32_3_5_FEATURES=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_SCHED_SMT=y CONFIG_MIPS_CPS=y CONFIG_NR_CPUS=8 diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 4011f1869e726eb4965bb80b2356cd0ddb33ee77..c3d0d0a6e04483247baeec72c6704966a4ee559c 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -146,12 +146,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig index 5720ce23e9aae0ac6f92380ceddbe15ea9a44d8c..7357248b3d7aa75df627dfb05f25a87ad64b5c58 100644 --- a/arch/mips/configs/nlm_xlp_defconfig +++ b/arch/mips/configs/nlm_xlp_defconfig @@ -259,7 +259,6 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_WAN_ROUTER=m diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index fea56c535d9237c4d121a48d4668556b615d2914..1e18fd7de209bc9be10006589cf03b11870b0c99 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig @@ -240,12 +240,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_PHONET=m CONFIG_IEEE802154=m diff --git a/arch/mips/configs/omega2p_defconfig b/arch/mips/configs/omega2p_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..e2731c3cc7e7053a5f77311af9f689265e768b51 --- /dev/null +++ b/arch/mips/configs/omega2p_defconfig @@ -0,0 +1,129 @@ +CONFIG_RALINK=y +CONFIG_SOC_MT7620=y +CONFIG_DTB_OMEGA2P=y +CONFIG_CPU_MIPS32_R2=y +# CONFIG_COMPACTION is not set +CONFIG_HZ_100=y +CONFIG_PREEMPT=y +# CONFIG_SECCOMP is not set +CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +# CONFIG_FW_LOADER is not set +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_NETDEVICES=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=2 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_MMC=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_MEMORY=y +CONFIG_PHY_RALINK_USB=y +# CONFIG_DNOTIFY is not set +CONFIG_PROC_KCORE=y +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=y +CONFIG_NLS_CODEPAGE_775=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +CONFIG_NLS_CODEPAGE_855=y +CONFIG_NLS_CODEPAGE_857=y +CONFIG_NLS_CODEPAGE_860=y +CONFIG_NLS_CODEPAGE_861=y +CONFIG_NLS_CODEPAGE_862=y +CONFIG_NLS_CODEPAGE_863=y +CONFIG_NLS_CODEPAGE_864=y +CONFIG_NLS_CODEPAGE_865=y +CONFIG_NLS_CODEPAGE_866=y +CONFIG_NLS_CODEPAGE_869=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=y +CONFIG_NLS_CODEPAGE_874=y +CONFIG_NLS_ISO8859_8=y +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_ISO8859_3=y +CONFIG_NLS_ISO8859_4=y +CONFIG_NLS_ISO8859_5=y +CONFIG_NLS_ISO8859_6=y +CONFIG_NLS_ISO8859_7=y +CONFIG_NLS_ISO8859_9=y +CONFIG_NLS_ISO8859_13=y +CONFIG_NLS_ISO8859_14=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_KOI8_R=y +CONFIG_NLS_KOI8_U=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_STACKTRACE=y +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRC16=y +CONFIG_XZ_DEC=y diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig index 7d32fbbca96269dd37d22d672ee2a6a6783dfc32..b22a3cf149b6f04911a40da454917ce2403dd78a 100644 --- a/arch/mips/configs/pistachio_defconfig +++ b/arch/mips/configs/pistachio_defconfig @@ -47,6 +47,8 @@ CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y CONFIG_IP_MROUTE=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y @@ -207,7 +209,7 @@ CONFIG_IMGPDC_WDT=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y # CONFIG_RC_DECODERS is not set CONFIG_RC_DEVICES=y CONFIG_IR_IMG=y @@ -292,7 +294,8 @@ CONFIG_SQUASHFS_LZO=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_RAM=y -# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_ASCII=m diff --git a/arch/mips/configs/vocore2_defconfig b/arch/mips/configs/vocore2_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..9121e4194a63c096a64ca99d6a2441f0b391d0be --- /dev/null +++ b/arch/mips/configs/vocore2_defconfig @@ -0,0 +1,129 @@ +CONFIG_RALINK=y +CONFIG_SOC_MT7620=y +CONFIG_DTB_VOCORE2=y +CONFIG_CPU_MIPS32_R2=y +# CONFIG_COMPACTION is not set +CONFIG_HZ_100=y +CONFIG_PREEMPT=y +# CONFIG_SECCOMP is not set +CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +# CONFIG_FW_LOADER is not set +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_NETDEVICES=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=2 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_MMC=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_MEMORY=y +CONFIG_PHY_RALINK_USB=y +# CONFIG_DNOTIFY is not set +CONFIG_PROC_KCORE=y +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=y +CONFIG_NLS_CODEPAGE_775=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +CONFIG_NLS_CODEPAGE_855=y +CONFIG_NLS_CODEPAGE_857=y +CONFIG_NLS_CODEPAGE_860=y +CONFIG_NLS_CODEPAGE_861=y +CONFIG_NLS_CODEPAGE_862=y +CONFIG_NLS_CODEPAGE_863=y +CONFIG_NLS_CODEPAGE_864=y +CONFIG_NLS_CODEPAGE_865=y +CONFIG_NLS_CODEPAGE_866=y +CONFIG_NLS_CODEPAGE_869=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=y +CONFIG_NLS_CODEPAGE_874=y +CONFIG_NLS_ISO8859_8=y +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_ISO8859_3=y +CONFIG_NLS_ISO8859_4=y +CONFIG_NLS_ISO8859_5=y +CONFIG_NLS_ISO8859_6=y +CONFIG_NLS_ISO8859_7=y +CONFIG_NLS_ISO8859_9=y +CONFIG_NLS_ISO8859_13=y +CONFIG_NLS_ISO8859_14=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_KOI8_R=y +CONFIG_NLS_KOI8_U=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_STACKTRACE=y +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRC16=y +CONFIG_XZ_DEC=y diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 1910223a9c02ba1474929905b235e43a07501aaa..cea2bb1621e68b211d5dc99fdad78f208b1ad8a3 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S @@ -147,23 +147,12 @@ * Find irq with highest priority */ # open coded PTR_LA t1, cpu_mask_nr_tbl -#if (_MIPS_SZPTR == 32) +#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) # open coded la t1, cpu_mask_nr_tbl lui t1, %hi(cpu_mask_nr_tbl) addiu t1, %lo(cpu_mask_nr_tbl) - -#endif -#if (_MIPS_SZPTR == 64) - # open coded dla t1, cpu_mask_nr_tbl - .set push - .set noat - lui t1, %highest(cpu_mask_nr_tbl) - lui AT, %hi(cpu_mask_nr_tbl) - daddiu t1, t1, %higher(cpu_mask_nr_tbl) - daddiu AT, AT, %lo(cpu_mask_nr_tbl) - dsll t1, 32 - daddu t1, t1, AT - .set pop +#else +#error GCC `-msym32' option required for 64-bit DECstation builds #endif 1: lw t2,(t1) nop @@ -214,23 +203,12 @@ * Find irq with highest priority */ # open coded PTR_LA t1,asic_mask_nr_tbl -#if (_MIPS_SZPTR == 32) +#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) # open coded la t1, asic_mask_nr_tbl lui t1, %hi(asic_mask_nr_tbl) addiu t1, %lo(asic_mask_nr_tbl) - -#endif -#if (_MIPS_SZPTR == 64) - # open coded dla t1, asic_mask_nr_tbl - .set push - .set noat - lui t1, %highest(asic_mask_nr_tbl) - lui AT, %hi(asic_mask_nr_tbl) - daddiu t1, t1, %higher(asic_mask_nr_tbl) - daddiu AT, AT, %lo(asic_mask_nr_tbl) - dsll t1, 32 - daddu t1, t1, AT - .set pop +#else +#error GCC `-msym32' option required for 64-bit DECstation builds #endif 2: lw t2,(t1) nop diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c index 629b24db0d3a1f46a94d5ec402965e133a51c98d..008555969534236082ea61b1ecab5d627ff7a6d0 100644 --- a/arch/mips/fw/arc/init.c +++ b/arch/mips/fw/arc/init.c @@ -51,7 +51,7 @@ void __init prom_init(void) #endif #ifdef CONFIG_SGI_IP27 { - extern struct plat_smp_ops ip27_smp_ops; + extern const struct plat_smp_ops ip27_smp_ops; register_smp_ops(&ip27_smp_ops); } diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index 51ffbbaddee2e27c770eeb1da89e6dcc3514e8df..e0436aaf7f389e9a6f04d042975eaa29d45020c1 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -36,4 +36,10 @@ config FIT_IMAGE_FDT_BOSTON enable this if you wish to boot on a MIPS Boston board, as it is expected by the bootloader. +config FIT_IMAGE_FDT_NI169445 + bool "Include FDT for NI 169445" + help + Enable this to include the FDT for the 169445 platform from + National Instruments in the FIT kernel image. + endif diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform index 9a30d69e22816e887c5080a69bdd0b8c918b86f3..f5312dfa81840e3506806c9f4912c9ebd325267d 100644 --- a/arch/mips/generic/Platform +++ b/arch/mips/generic/Platform @@ -12,3 +12,7 @@ platform-$(CONFIG_MIPS_GENERIC) += generic/ cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb + +its-y := vmlinux.its.S +its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S +its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S diff --git a/arch/mips/generic/board-boston.its.S b/arch/mips/generic/board-boston.its.S new file mode 100644 index 0000000000000000000000000000000000000000..a7f51f97b9102f79dd4e75fa1894ee42e24e099e --- /dev/null +++ b/arch/mips/generic/board-boston.its.S @@ -0,0 +1,22 @@ +/ { + images { + fdt@boston { + description = "img,boston Device Tree"; + data = /incbin/("boot/dts/img/boston.dtb"); + type = "flat_dt"; + arch = "mips"; + compression = "none"; + hash@0 { + algo = "sha1"; + }; + }; + }; + + configurations { + conf@boston { + description = "Boston Linux kernel"; + kernel = "kernel@0"; + fdt = "fdt@boston"; + }; + }; +}; diff --git a/arch/mips/generic/board-ni169445.its.S b/arch/mips/generic/board-ni169445.its.S new file mode 100644 index 0000000000000000000000000000000000000000..d12e12fe90bec6f4d0290b63ba8a8b2154bff4bc --- /dev/null +++ b/arch/mips/generic/board-ni169445.its.S @@ -0,0 +1,22 @@ +{ + images { + fdt@ni169445 { + description = "NI 169445 device tree"; + data = /incbin/("boot/dts/ni/169445.dtb"); + type = "flat_dt"; + arch = "mips"; + compression = "none"; + hash@0 { + algo = "sha1"; + }; + }; + }; + + configurations { + conf@ni169445 { + description = "NI 169445 Linux Kernel"; + kernel = "kernel@0"; + fdt = "fdt@ni169445"; + }; + }; +}; diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c index 3f32b376d30e482774f55aa2cbcc3664a488ddfb..15a7fb8e2a2e80b28e8bca9d73bef2a64a8bf29a 100644 --- a/arch/mips/generic/init.c +++ b/arch/mips/generic/init.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -88,6 +89,8 @@ void __init *plat_get_fdt(void) return (void *)fdt; } +#ifdef CONFIG_RELOCATABLE + void __init plat_fdt_relocated(void *new_location) { /* @@ -101,6 +104,8 @@ void __init plat_fdt_relocated(void *new_location) fw_arg1 = (unsigned long)new_location; } +#endif /* CONFIG_RELOCATABLE */ + void __init plat_mem_setup(void) { if (mach && mach->fixup_fdt) diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c index 14064bdd91ddcc3e3cd990f457242871af0af524..5322d09dd51b5563d1bf58aa0b31b927c982d080 100644 --- a/arch/mips/generic/irq.c +++ b/arch/mips/generic/irq.c @@ -12,10 +12,11 @@ #include #include #include -#include #include #include +#include +#include int get_c0_fdc_int(void) { @@ -23,7 +24,7 @@ int get_c0_fdc_int(void) if (cpu_has_veic) panic("Unimplemented!"); - else if (gic_present) + else if (mips_gic_present()) mips_cpu_fdc_irq = gic_get_c0_fdc_int(); else if (cp0_fdc_irq >= 0) mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; @@ -39,7 +40,7 @@ int get_c0_perfcount_int(void) if (cpu_has_veic) panic("Unimplemented!"); - else if (gic_present) + else if (mips_gic_present()) mips_cpu_perf_irq = gic_get_c0_perfcount_int(); else if (cp0_perfcount_irq >= 0) mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; @@ -55,7 +56,7 @@ unsigned int get_c0_compare_int(void) if (cpu_has_veic) panic("Unimplemented!"); - else if (gic_present) + else if (mips_gic_present()) mips_cpu_timer_irq = gic_get_c0_compare_int(); else mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S index 3390e2f80b8014a9a8c6c8c39555de460cd5bb48..f67fbf1c85417cc2e2bb07abec86d84b466b8196 100644 --- a/arch/mips/generic/vmlinux.its.S +++ b/arch/mips/generic/vmlinux.its.S @@ -29,28 +29,3 @@ }; }; }; - -#ifdef CONFIG_FIT_IMAGE_FDT_BOSTON -/ { - images { - fdt@boston { - description = "img,boston Device Tree"; - data = /incbin/("boot/dts/img/boston.dtb"); - type = "flat_dt"; - arch = "mips"; - compression = "none"; - hash@0 { - algo = "sha1"; - }; - }; - }; - - configurations { - conf@boston { - description = "Boston Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@boston"; - }; - }; -}; -#endif /* CONFIG_FIT_IMAGE_FDT_BOSTON */ diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h index 859cf7048347bf4b0ebad1f619507202976f74b3..81fae23ce7cdb41b523dd356a64f4da18c833237 100644 --- a/arch/mips/include/asm/asm.h +++ b/arch/mips/include/asm/asm.h @@ -55,6 +55,7 @@ .type symbol, @function; \ .ent symbol, 0; \ symbol: .frame sp, 0, ra; \ + .cfi_startproc; \ .insn /* @@ -66,12 +67,14 @@ symbol: .frame sp, 0, ra; \ .type symbol, @function; \ .ent symbol, 0; \ symbol: .frame sp, framesize, rpc; \ + .cfi_startproc; \ .insn /* * END - mark end of function */ #define END(function) \ + .cfi_endproc; \ .end function; \ .size function, .-function diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index a92aee7b977acb56539f74f7f9db2d9d0c1291a5..b3e2975f83d36e021a57988672ef26c09701f879 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h @@ -48,8 +48,8 @@ #include #include -extern struct plat_smp_ops bmips43xx_smp_ops; -extern struct plat_smp_ops bmips5000_smp_ops; +extern const struct plat_smp_ops bmips43xx_smp_ops; +extern const struct plat_smp_ops bmips5000_smp_ops; static inline int register_bmips_smp_ops(void) { diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h index fc67947ed6586c2e416b2f6cc588a4445b3761ab..8b14c2706aa52ca83e07ff4dcb37c71850d133bc 100644 --- a/arch/mips/include/asm/cache.h +++ b/arch/mips/include/asm/cache.h @@ -9,6 +9,8 @@ #ifndef _ASM_CACHE_H #define _ASM_CACHE_H +#include + #define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 8baa9033b181d2ca2e3f6e469315bdb8bf5345b5..721b698bfe3cf7e0274bb9f0bb4bf58bfecef29e 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -428,6 +428,9 @@ #ifndef cpu_scache_line_size #define cpu_scache_line_size() cpu_data[0].scache.linesz #endif +#ifndef cpu_tcache_line_size +#define cpu_tcache_line_size() cpu_data[0].tcache.linesz +#endif #ifndef cpu_hwrena_impl_bits #define cpu_hwrena_impl_bits 0 diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index cd6efb07c9808594c143d16fcc005c2ce9afb0ea..a41059d47d31c52d377aa39694a0da3ba3e07af5 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -15,6 +15,8 @@ #include #include +#include + /* * Descriptor for a cache */ @@ -77,16 +79,9 @@ struct cpuinfo_mips { struct cache_desc tcache; /* Tertiary/split secondary cache */ int srsets; /* Shadow register sets */ int package;/* physical package number */ - int core; /* physical core number */ + unsigned int globalnumber; #ifdef CONFIG_64BIT int vmbits; /* Virtual memory size in bits */ -#endif -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) - /* - * There is not necessarily a 1:1 mapping of VPE num to CPU number - * in particular on multi-core systems. - */ - int vpe_id; /* Virtual Processor number */ #endif void *data; /* Additional data */ unsigned int watch_reg_count; /* Number that exist */ @@ -144,11 +139,52 @@ struct proc_cpuinfo_notifier_args { unsigned long n; }; -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) -# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) -#else -# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) -#endif +static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo) +{ + /* Optimisation for systems where multiple clusters aren't used */ + if (!IS_ENABLED(CONFIG_CPU_MIPSR6)) + return 0; + + return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >> + MIPS_GLOBALNUMBER_CLUSTER_SHF; +} + +static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo) +{ + return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >> + MIPS_GLOBALNUMBER_CORE_SHF; +} + +static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo) +{ + /* Optimisation for systems where VP(E)s aren't used */ + if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6)) + return 0; + + return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >> + MIPS_GLOBALNUMBER_VP_SHF; +} + +extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster); +extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core); +extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe); + +static inline bool cpus_are_siblings(int cpua, int cpub) +{ + struct cpuinfo_mips *infoa = &cpu_data[cpua]; + struct cpuinfo_mips *infob = &cpu_data[cpub]; + unsigned int gnuma, gnumb; + + if (infoa->package != infob->package) + return false; + + gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP; + gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP; + if (gnuma != gnumb) + return false; + + return true; +} static inline unsigned long cpu_asid_inc(void) { diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index 175fe565f4e1e6e078ead8d42da079cb779d7340..a45af3de075d900cf819071c390820c7f749f47b 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -151,11 +151,6 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_R5500: #endif -#ifdef CONFIG_SYS_HAS_CPU_R6000 - case CPU_R6000: - case CPU_R6000A: -#endif - #ifdef CONFIG_SYS_HAS_CPU_NEVADA case CPU_NEVADA: #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index d0c152b989f8eea1f6d8380386f7997483329f70..ece9b84f3bcbd78511903c97269795dddd8f111d 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -285,11 +285,6 @@ enum cpu_type_enum { CPU_R2000, CPU_R3000, CPU_R3000A, CPU_R3041, CPU_R3051, CPU_R3052, CPU_R3081, CPU_R3081E, - /* - * R6000 class processors - */ - CPU_R6000, CPU_R6000A, - /* * R4000 class processors */ diff --git a/arch/mips/include/asm/floppy.h b/arch/mips/include/asm/floppy.h index d75aed36480a843cfd7703741209e518638ca56f..021d09ae5670a1649f3766927826e342ec35deb3 100644 --- a/arch/mips/include/asm/floppy.h +++ b/arch/mips/include/asm/floppy.h @@ -10,11 +10,11 @@ #ifndef _ASM_FLOPPY_H #define _ASM_FLOPPY_H -#include +#include static inline void fd_cacheflush(char * addr, long size) { - dma_cache_sync(NULL, addr, size, DMA_BIDIRECTIONAL); + dma_cache_wback_inv((unsigned long)addr, size); } #define MAX_BUFFER_SECTORS 24 diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index c05369e0b8d60352dc1833880b026e15ac09ba17..b36097d3cbf43ae9d6c5a27abf10b0f01e9e1636 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h @@ -36,6 +36,7 @@ struct mips_fpu_emulator_stats { unsigned long emulated; unsigned long loads; unsigned long stores; + unsigned long branches; unsigned long cp1ops; unsigned long cp1xops; unsigned long errors; @@ -45,6 +46,121 @@ struct mips_fpu_emulator_stats { unsigned long ieee754_zerodiv; unsigned long ieee754_invalidop; unsigned long ds_emul; + + unsigned long abs_s; + unsigned long abs_d; + unsigned long add_s; + unsigned long add_d; + unsigned long bc1eqz; + unsigned long bc1nez; + unsigned long ceil_w_s; + unsigned long ceil_w_d; + unsigned long ceil_l_s; + unsigned long ceil_l_d; + unsigned long class_s; + unsigned long class_d; + unsigned long cmp_af_s; + unsigned long cmp_af_d; + unsigned long cmp_eq_s; + unsigned long cmp_eq_d; + unsigned long cmp_le_s; + unsigned long cmp_le_d; + unsigned long cmp_lt_s; + unsigned long cmp_lt_d; + unsigned long cmp_ne_s; + unsigned long cmp_ne_d; + unsigned long cmp_or_s; + unsigned long cmp_or_d; + unsigned long cmp_ueq_s; + unsigned long cmp_ueq_d; + unsigned long cmp_ule_s; + unsigned long cmp_ule_d; + unsigned long cmp_ult_s; + unsigned long cmp_ult_d; + unsigned long cmp_un_s; + unsigned long cmp_un_d; + unsigned long cmp_une_s; + unsigned long cmp_une_d; + unsigned long cmp_saf_s; + unsigned long cmp_saf_d; + unsigned long cmp_seq_s; + unsigned long cmp_seq_d; + unsigned long cmp_sle_s; + unsigned long cmp_sle_d; + unsigned long cmp_slt_s; + unsigned long cmp_slt_d; + unsigned long cmp_sne_s; + unsigned long cmp_sne_d; + unsigned long cmp_sor_s; + unsigned long cmp_sor_d; + unsigned long cmp_sueq_s; + unsigned long cmp_sueq_d; + unsigned long cmp_sule_s; + unsigned long cmp_sule_d; + unsigned long cmp_sult_s; + unsigned long cmp_sult_d; + unsigned long cmp_sun_s; + unsigned long cmp_sun_d; + unsigned long cmp_sune_s; + unsigned long cmp_sune_d; + unsigned long cvt_d_l; + unsigned long cvt_d_s; + unsigned long cvt_d_w; + unsigned long cvt_l_s; + unsigned long cvt_l_d; + unsigned long cvt_s_d; + unsigned long cvt_s_l; + unsigned long cvt_s_w; + unsigned long cvt_w_s; + unsigned long cvt_w_d; + unsigned long div_s; + unsigned long div_d; + unsigned long floor_w_s; + unsigned long floor_w_d; + unsigned long floor_l_s; + unsigned long floor_l_d; + unsigned long maddf_s; + unsigned long maddf_d; + unsigned long max_s; + unsigned long max_d; + unsigned long maxa_s; + unsigned long maxa_d; + unsigned long min_s; + unsigned long min_d; + unsigned long mina_s; + unsigned long mina_d; + unsigned long mov_s; + unsigned long mov_d; + unsigned long msubf_s; + unsigned long msubf_d; + unsigned long mul_s; + unsigned long mul_d; + unsigned long neg_s; + unsigned long neg_d; + unsigned long recip_s; + unsigned long recip_d; + unsigned long rint_s; + unsigned long rint_d; + unsigned long round_w_s; + unsigned long round_w_d; + unsigned long round_l_s; + unsigned long round_l_d; + unsigned long rsqrt_s; + unsigned long rsqrt_d; + unsigned long sel_s; + unsigned long sel_d; + unsigned long seleqz_s; + unsigned long seleqz_d; + unsigned long selnez_s; + unsigned long selnez_d; + unsigned long sqrt_s; + unsigned long sqrt_d; + unsigned long sub_s; + unsigned long sub_d; + unsigned long trunc_w_s; + unsigned long trunc_w_d; + unsigned long trunc_l_s; + unsigned long trunc_l_d; }; DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); @@ -62,7 +178,7 @@ do { \ extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, int has_fpu, - void *__user *fault_addr); + void __user **fault_addr); void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, struct task_struct *tsk); int process_fpemu_return(int sig, void __user *fault_addr, diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 1de190bdfb9c9fef90b8976503242e09b97e7f60..a9e61ea54ca96ba69fa49f009d4fc98ff9cb1bdf 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -83,18 +83,9 @@ } static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index ecabc00c1e665ae237faf60a10f07599d04a65c3..0cbf3af37ecad9d195847c49ddffb15a6165fc4d 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -632,4 +632,6 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); */ #define xlate_dev_kmem_ptr(p) p +void __ioread64_copy(void *to, const void __iomem *from, size_t count); + #endif /* _ASM_IO_H */ diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 2998479fd4e83f0ac4c6ccd7d89938c7cc9a6f5f..a9af1d2dcd699114d00a55689c29137cef384841 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -938,11 +938,6 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); -static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, - unsigned long address) -{ -} - /* Emulation */ int kvm_get_inst(u32 *opc, struct kvm_vcpu *vcpu, u32 *out); enum emulation_result update_pc(struct kvm_vcpu *vcpu, u32 cause); diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h index bace5b9ae4df27e1b419095305f08790cdd296ec..f439cf9cf9d123f7bd0a3c1fa08dd8465617b52a 100644 --- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h @@ -8,12 +8,16 @@ #define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H #define cpu_has_tlb 1 +#define cpu_has_ftlb 0 #define cpu_has_tlbinv 0 #define cpu_has_segments 0 #define cpu_has_eva 0 #define cpu_has_htw 0 +#define cpu_has_ldpte 0 #define cpu_has_rixiex 0 #define cpu_has_maar 0 +#define cpu_has_rw_llb 0 +#define cpu_has_3kex 0 #define cpu_has_4kex 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 @@ -30,6 +34,12 @@ #define cpu_has_mcheck 1 #define cpu_has_ejtag 1 #define cpu_has_llsc 1 +#define cpu_has_guestctl0ext 0 +#define cpu_has_guestctl1 0 +#define cpu_has_guestctl2 0 +#define cpu_has_guestid 0 +#define cpu_has_drg 0 +#define cpu_has_bp_ghist 0 #define cpu_has_mips16 0 #define cpu_has_mips16e2 0 #define cpu_has_mdmx 0 @@ -37,17 +47,23 @@ #define cpu_has_smartmips 0 #define cpu_has_rixi 0 #define cpu_has_mmips 0 +#define cpu_has_lpa 0 +#define cpu_has_mhv 0 #define cpu_has_vtag_icache 0 #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 1 #define cpu_has_pindexed_dcache 0 #define cpu_has_mips32r1 1 #define cpu_has_mips32r2 0 +#define cpu_has_mips32r6 0 #define cpu_has_mips64r1 0 #define cpu_has_mips64r2 0 +#define cpu_has_mips64r6 0 #define cpu_has_dsp 0 #define cpu_has_dsp2 0 +#define cpu_has_dsp3 0 #define cpu_has_mipsmt 0 +#define cpu_has_vp 0 #define cpu_has_userlocal 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 0 @@ -58,9 +74,19 @@ #define cpu_dcache_line_size() 32 #define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 0 #define cpu_has_perf_cntr_intr_bit 0 #define cpu_has_vz 0 #define cpu_has_msa 0 +#define cpu_has_fre 0 +#define cpu_has_cdmm 0 +#define cpu_has_small_pages 0 +#define cpu_has_nan_legacy 1 +#define cpu_has_nan_2008 1 +#define cpu_has_ebase_wg 0 +#define cpu_has_badinstr 0 +#define cpu_has_badinstrp 0 +#define cpu_has_contextconfig 0 #endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 5035f09c54274a50d89fdb81426743872a51ad66..24080af570f9ae3d202062f8f6ffc45980446ad6 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -710,7 +710,7 @@ /* Broadcom 6345 ENET DMA definitions */ #define ENETDMA_6345_CHANCFG_REG (0x00) -#define ENETDMA_6345_MAXBURST_REG (0x40) +#define ENETDMA_6345_MAXBURST_REG (0x04) #define ENETDMA_6345_RSTART_REG (0x08) diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index bd8b9bbe17719df3fce2c8c9484fd9dad5eca4d4..a4f798629c3d8147655b411cdcd1cf23f10e49de 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -46,9 +46,9 @@ #define cpu_has_64bits 1 #define cpu_has_octeon_cache 1 #define cpu_has_saa octeon_has_saa() -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 +#define cpu_has_mips32r1 1 +#define cpu_has_mips32r2 1 +#define cpu_has_mips64r1 1 #define cpu_has_mips64r2 1 #define cpu_has_dsp 0 #define cpu_has_dsp2 0 diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h index defd135e7ac8d726f320962cc97cb403aba56d63..3fb7a0e094943c36cb096a129e361f063778c6ba 100644 --- a/arch/mips/include/asm/mach-ip27/topology.h +++ b/arch/mips/include/asm/mach-ip27/topology.h @@ -23,7 +23,6 @@ struct cpuinfo_ip27 { extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; #define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid) -#define parent_node(node) (node) #define cpumask_of_node(node) ((node) == -1 ? \ cpu_all_mask : \ &hub_data(node)->h_cpus) diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h index 7f7b0fc554da5c5a706768f73cfd730d7ed9ae85..f381d465e768cf9e31ce6e44690e04fce4ef267f 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h @@ -16,7 +16,7 @@ #ifndef __ASM_MACH_JZ4740_JZ4740_NAND_H__ #define __ASM_MACH_JZ4740_JZ4740_NAND_H__ -#include +#include #include #define JZ_NAND_NUM_BANKS 4 diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index 8064d7a4b33d7ae88d0889fa32ab0e92c5197c8b..d750f93232e40ab7d9f3c88c273485ead724926b 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h @@ -46,8 +46,6 @@ extern struct clk *clk_get_ppe(void); /* find out what bootsource we have */ extern unsigned char ltq_boot_select(void); -/* find out what caused the last cpu reset */ -extern int ltq_reset_cause(void); /* find out the soc type */ extern int ltq_soc_type(void); diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h index c68c0cc879c6b22756c0f20ea66d469ee56969b1..d0ae5d55413b68f48c8aaa3703bdb3217c9919c1 100644 --- a/arch/mips/include/asm/mach-loongson64/loongson.h +++ b/arch/mips/include/asm/mach-loongson64/loongson.h @@ -26,7 +26,7 @@ extern void mach_prepare_shutdown(void); /* environment arguments from bootloader */ extern u32 cpu_clock_freq; extern u32 memsize, highmemsize; -extern struct plat_smp_ops loongson3_smp_ops; +extern const struct plat_smp_ops loongson3_smp_ops; /* loongson-specific command line, env and memory initialization */ extern void __init prom_init_memory(void); diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h index 0d8f3b55bdbc710da31c666ffc3b4f4b0ce5f65d..bcb885615fcad2e1c79690c85b78224e6589ccf0 100644 --- a/arch/mips/include/asm/mach-loongson64/topology.h +++ b/arch/mips/include/asm/mach-loongson64/topology.h @@ -4,7 +4,6 @@ #ifdef CONFIG_NUMA #define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) -#define parent_node(node) (node) #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) struct pci_bus; diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h index 9df1a53bcb36c60bc082223ff8daa24a7eb4a506..b4e7dfa214eb0b882022fe1ce2e8e7e7c3f0097d 100644 --- a/arch/mips/include/asm/mach-ralink/ralink_regs.h +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h @@ -13,6 +13,8 @@ #ifndef _RALINK_REGS_H_ #define _RALINK_REGS_H_ +#include + enum ralink_soc_type { RALINK_UNKNOWN = 0, RT2880_SOC, diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index 987ff580466b8961225dbc934155ef44309b441b..817698abf2eb089f2aac42fef1a6c7f6aa4e2f38 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -10,8 +10,6 @@ #ifndef _MIPS_MALTAINT_H #define _MIPS_MALTAINT_H -#include - /* * Interrupts 0..15 are used for Malta ISA compatible interrupts */ @@ -62,7 +60,4 @@ #define MSC01E_INT_PERFCTR 10 #define MSC01E_INT_CPUCTR 11 -/* GIC external interrupts */ -#define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3) - #endif /* !(_MIPS_MALTAINT_H) */ diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index cfdbab0157697f74cf0eedf048d2791f2b4dd643..f6231b91b7247fdf39cd81d05036c7c33eb1f534 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -8,16 +8,18 @@ * option) any later version. */ +#ifndef __MIPS_ASM_MIPS_CPS_H__ +# error Please include asm/mips-cps.h rather than asm/mips-cm.h +#endif + #ifndef __MIPS_ASM_MIPS_CM_H__ #define __MIPS_ASM_MIPS_CM_H__ #include #include -#include -#include /* The base address of the CM GCR block */ -extern void __iomem *mips_cm_base; +extern void __iomem *mips_gcr_base; /* The base address of the CM L2-only sync region */ extern void __iomem *mips_cm_l2sync_base; @@ -80,7 +82,7 @@ static inline int mips_cm_probe(void) static inline bool mips_cm_present(void) { #ifdef CONFIG_MIPS_CM - return mips_cm_base != NULL; + return mips_gcr_base != NULL; #else return false; #endif @@ -112,321 +114,219 @@ static inline bool mips_cm_has_l2sync(void) /* Size of the L2-only sync region */ #define MIPS_CM_L2SYNC_SIZE 0x1000 -/* Macros to ease the creation of register access functions */ -#define BUILD_CM_R_(name, off) \ -static inline unsigned long __iomem *addr_gcr_##name(void) \ -{ \ - return (unsigned long __iomem *)(mips_cm_base + (off)); \ -} \ - \ -static inline u32 read32_gcr_##name(void) \ -{ \ - return __raw_readl(addr_gcr_##name()); \ -} \ - \ -static inline u64 read64_gcr_##name(void) \ -{ \ - void __iomem *addr = addr_gcr_##name(); \ - u64 ret; \ - \ - if (mips_cm_is64) { \ - ret = __raw_readq(addr); \ - } else { \ - ret = __raw_readl(addr); \ - ret |= (u64)__raw_readl(addr + 0x4) << 32; \ - } \ - \ - return ret; \ -} \ - \ -static inline unsigned long read_gcr_##name(void) \ -{ \ - if (mips_cm_is64) \ - return read64_gcr_##name(); \ - else \ - return read32_gcr_##name(); \ -} - -#define BUILD_CM__W(name, off) \ -static inline void write32_gcr_##name(u32 value) \ -{ \ - __raw_writel(value, addr_gcr_##name()); \ -} \ - \ -static inline void write64_gcr_##name(u64 value) \ -{ \ - __raw_writeq(value, addr_gcr_##name()); \ -} \ - \ -static inline void write_gcr_##name(unsigned long value) \ -{ \ - if (mips_cm_is64) \ - write64_gcr_##name(value); \ - else \ - write32_gcr_##name(value); \ -} - -#define BUILD_CM_RW(name, off) \ - BUILD_CM_R_(name, off) \ - BUILD_CM__W(name, off) - -#define BUILD_CM_Cx_R_(name, off) \ - BUILD_CM_R_(cl_##name, MIPS_CM_CLCB_OFS + (off)) \ - BUILD_CM_R_(co_##name, MIPS_CM_COCB_OFS + (off)) - -#define BUILD_CM_Cx__W(name, off) \ - BUILD_CM__W(cl_##name, MIPS_CM_CLCB_OFS + (off)) \ - BUILD_CM__W(co_##name, MIPS_CM_COCB_OFS + (off)) - -#define BUILD_CM_Cx_RW(name, off) \ - BUILD_CM_Cx_R_(name, off) \ - BUILD_CM_Cx__W(name, off) - -/* GCB register accessor functions */ -BUILD_CM_R_(config, MIPS_CM_GCB_OFS + 0x00) -BUILD_CM_RW(base, MIPS_CM_GCB_OFS + 0x08) -BUILD_CM_RW(access, MIPS_CM_GCB_OFS + 0x20) -BUILD_CM_R_(rev, MIPS_CM_GCB_OFS + 0x30) -BUILD_CM_RW(err_control, MIPS_CM_GCB_OFS + 0x38) -BUILD_CM_RW(error_mask, MIPS_CM_GCB_OFS + 0x40) -BUILD_CM_RW(error_cause, MIPS_CM_GCB_OFS + 0x48) -BUILD_CM_RW(error_addr, MIPS_CM_GCB_OFS + 0x50) -BUILD_CM_RW(error_mult, MIPS_CM_GCB_OFS + 0x58) -BUILD_CM_RW(l2_only_sync_base, MIPS_CM_GCB_OFS + 0x70) -BUILD_CM_RW(gic_base, MIPS_CM_GCB_OFS + 0x80) -BUILD_CM_RW(cpc_base, MIPS_CM_GCB_OFS + 0x88) -BUILD_CM_RW(reg0_base, MIPS_CM_GCB_OFS + 0x90) -BUILD_CM_RW(reg0_mask, MIPS_CM_GCB_OFS + 0x98) -BUILD_CM_RW(reg1_base, MIPS_CM_GCB_OFS + 0xa0) -BUILD_CM_RW(reg1_mask, MIPS_CM_GCB_OFS + 0xa8) -BUILD_CM_RW(reg2_base, MIPS_CM_GCB_OFS + 0xb0) -BUILD_CM_RW(reg2_mask, MIPS_CM_GCB_OFS + 0xb8) -BUILD_CM_RW(reg3_base, MIPS_CM_GCB_OFS + 0xc0) -BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8) -BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0) -BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0) -BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130) -BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) -BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) -BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) -BUILD_CM_RW(bev_base, MIPS_CM_GCB_OFS + 0x680) - -/* Core Local & Core Other register accessor functions */ -BUILD_CM_Cx_RW(reset_release, 0x00) -BUILD_CM_Cx_RW(coherence, 0x08) -BUILD_CM_Cx_R_(config, 0x10) -BUILD_CM_Cx_RW(other, 0x18) -BUILD_CM_Cx_RW(reset_base, 0x20) -BUILD_CM_Cx_R_(id, 0x28) -BUILD_CM_Cx_RW(reset_ext_base, 0x30) -BUILD_CM_Cx_R_(tcid_0_priority, 0x40) -BUILD_CM_Cx_R_(tcid_1_priority, 0x48) -BUILD_CM_Cx_R_(tcid_2_priority, 0x50) -BUILD_CM_Cx_R_(tcid_3_priority, 0x58) -BUILD_CM_Cx_R_(tcid_4_priority, 0x60) -BUILD_CM_Cx_R_(tcid_5_priority, 0x68) -BUILD_CM_Cx_R_(tcid_6_priority, 0x70) -BUILD_CM_Cx_R_(tcid_7_priority, 0x78) -BUILD_CM_Cx_R_(tcid_8_priority, 0x80) - -/* GCR_CONFIG register fields */ -#define CM_GCR_CONFIG_NUMIOCU_SHF 8 -#define CM_GCR_CONFIG_NUMIOCU_MSK (_ULCAST_(0xf) << 8) -#define CM_GCR_CONFIG_PCORES_SHF 0 -#define CM_GCR_CONFIG_PCORES_MSK (_ULCAST_(0xff) << 0) - -/* GCR_BASE register fields */ -#define CM_GCR_BASE_GCRBASE_SHF 15 -#define CM_GCR_BASE_GCRBASE_MSK (_ULCAST_(0x1ffff) << 15) -#define CM_GCR_BASE_CMDEFTGT_SHF 0 -#define CM_GCR_BASE_CMDEFTGT_MSK (_ULCAST_(0x3) << 0) +#define GCR_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name) + +#define GCR_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name) + +#define GCR_CX_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name) + +#define GCR_CX_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name) + +/* GCR_CONFIG - Information about the system */ +GCR_ACCESSOR_RO(64, 0x000, config) +#define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE BIT_ULL(43) +#define CM_GCR_CONFIG_CLUSTER_ID GENMASK_ULL(39, 32) +#define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23) +#define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8) +#define CM_GCR_CONFIG_PCORES GENMASK(7, 0) + +/* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */ +GCR_ACCESSOR_RW(64, 0x008, base) +#define CM_GCR_BASE_GCRBASE GENMASK_ULL(47, 15) +#define CM_GCR_BASE_CMDEFTGT GENMASK(1, 0) #define CM_GCR_BASE_CMDEFTGT_DISABLED 0 #define CM_GCR_BASE_CMDEFTGT_MEM 1 #define CM_GCR_BASE_CMDEFTGT_IOCU0 2 #define CM_GCR_BASE_CMDEFTGT_IOCU1 3 -/* GCR_RESET_EXT_BASE register fields */ -#define CM_GCR_RESET_EXT_BASE_EVARESET BIT(31) -#define CM_GCR_RESET_EXT_BASE_UEB BIT(30) - -/* GCR_ACCESS register fields */ -#define CM_GCR_ACCESS_ACCESSEN_SHF 0 -#define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0) +/* GCR_ACCESS - Controls core/IOCU access to GCRs */ +GCR_ACCESSOR_RW(32, 0x020, access) +#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0) -/* GCR_REV register fields */ -#define CM_GCR_REV_MAJOR_SHF 8 -#define CM_GCR_REV_MAJOR_MSK (_ULCAST_(0xff) << 8) -#define CM_GCR_REV_MINOR_SHF 0 -#define CM_GCR_REV_MINOR_MSK (_ULCAST_(0xff) << 0) +/* GCR_REV - Indicates the Coherence Manager revision */ +GCR_ACCESSOR_RO(32, 0x030, rev) +#define CM_GCR_REV_MAJOR GENMASK(15, 8) +#define CM_GCR_REV_MINOR GENMASK(7, 0) #define CM_ENCODE_REV(major, minor) \ - (((major) << CM_GCR_REV_MAJOR_SHF) | \ - ((minor) << CM_GCR_REV_MINOR_SHF)) + (((major) << __ffs(CM_GCR_REV_MAJOR)) | \ + ((minor) << __ffs(CM_GCR_REV_MINOR))) #define CM_REV_CM2 CM_ENCODE_REV(6, 0) #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) #define CM_REV_CM3 CM_ENCODE_REV(8, 0) - -/* GCR_ERR_CONTROL register fields */ -#define CM_GCR_ERR_CONTROL_L2_ECC_EN_SHF 1 -#define CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK (_ULCAST_(0x1) << 1) -#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_SHF 0 -#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK (_ULCAST_(0x1) << 0) - -/* GCR_ERROR_CAUSE register fields */ -#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27 -#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27) -#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF 58 -#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK GENMASK_ULL(63, 58) -#define CM_GCR_ERROR_CAUSE_ERRINFO_SHF 0 -#define CM_GCR_ERROR_CAUSE_ERRINGO_MSK (_ULCAST_(0x7ffffff) << 0) - -/* GCR_ERROR_MULT register fields */ -#define CM_GCR_ERROR_MULT_ERR2ND_SHF 0 -#define CM_GCR_ERROR_MULT_ERR2ND_MSK (_ULCAST_(0x1f) << 0) - -/* GCR_L2_ONLY_SYNC_BASE register fields */ -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_SHF 12 -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK (_ULCAST_(0xfffff) << 12) -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_SHF 0 -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK (_ULCAST_(0x1) << 0) - -/* GCR_GIC_BASE register fields */ -#define CM_GCR_GIC_BASE_GICBASE_SHF 17 -#define CM_GCR_GIC_BASE_GICBASE_MSK (_ULCAST_(0x7fff) << 17) -#define CM_GCR_GIC_BASE_GICEN_SHF 0 -#define CM_GCR_GIC_BASE_GICEN_MSK (_ULCAST_(0x1) << 0) - -/* GCR_CPC_BASE register fields */ -#define CM_GCR_CPC_BASE_CPCBASE_SHF 15 -#define CM_GCR_CPC_BASE_CPCBASE_MSK (_ULCAST_(0x1ffff) << 15) -#define CM_GCR_CPC_BASE_CPCEN_SHF 0 -#define CM_GCR_CPC_BASE_CPCEN_MSK (_ULCAST_(0x1) << 0) - -/* GCR_GIC_STATUS register fields */ -#define CM_GCR_GIC_STATUS_GICEX_SHF 0 -#define CM_GCR_GIC_STATUS_GICEX_MSK (_ULCAST_(0x1) << 0) - -/* GCR_REGn_BASE register fields */ -#define CM_GCR_REGn_BASE_BASEADDR_SHF 16 -#define CM_GCR_REGn_BASE_BASEADDR_MSK (_ULCAST_(0xffff) << 16) - -/* GCR_REGn_MASK register fields */ -#define CM_GCR_REGn_MASK_ADDRMASK_SHF 16 -#define CM_GCR_REGn_MASK_ADDRMASK_MSK (_ULCAST_(0xffff) << 16) -#define CM_GCR_REGn_MASK_CCAOVR_SHF 5 -#define CM_GCR_REGn_MASK_CCAOVR_MSK (_ULCAST_(0x3) << 5) -#define CM_GCR_REGn_MASK_CCAOVREN_SHF 4 -#define CM_GCR_REGn_MASK_CCAOVREN_MSK (_ULCAST_(0x1) << 4) -#define CM_GCR_REGn_MASK_DROPL2_SHF 2 -#define CM_GCR_REGn_MASK_DROPL2_MSK (_ULCAST_(0x1) << 2) -#define CM_GCR_REGn_MASK_CMTGT_SHF 0 -#define CM_GCR_REGn_MASK_CMTGT_MSK (_ULCAST_(0x3) << 0) -#define CM_GCR_REGn_MASK_CMTGT_DISABLED (_ULCAST_(0x0) << 0) -#define CM_GCR_REGn_MASK_CMTGT_MEM (_ULCAST_(0x1) << 0) -#define CM_GCR_REGn_MASK_CMTGT_IOCU0 (_ULCAST_(0x2) << 0) -#define CM_GCR_REGn_MASK_CMTGT_IOCU1 (_ULCAST_(0x3) << 0) - -/* GCR_GIC_STATUS register fields */ -#define CM_GCR_GIC_STATUS_EX_SHF 0 -#define CM_GCR_GIC_STATUS_EX_MSK (_ULCAST_(0x1) << 0) - -/* GCR_CPC_STATUS register fields */ -#define CM_GCR_CPC_STATUS_EX_SHF 0 -#define CM_GCR_CPC_STATUS_EX_MSK (_ULCAST_(0x1) << 0) - -/* GCR_L2_CONFIG register fields */ -#define CM_GCR_L2_CONFIG_BYPASS_SHF 20 -#define CM_GCR_L2_CONFIG_BYPASS_MSK (_ULCAST_(0x1) << 20) -#define CM_GCR_L2_CONFIG_SET_SIZE_SHF 12 -#define CM_GCR_L2_CONFIG_SET_SIZE_MSK (_ULCAST_(0xf) << 12) -#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF 8 -#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK (_ULCAST_(0xf) << 8) -#define CM_GCR_L2_CONFIG_ASSOC_SHF 0 -#define CM_GCR_L2_CONFIG_ASSOC_MSK (_ULCAST_(0xff) << 0) - -/* GCR_SYS_CONFIG2 register fields */ -#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0 -#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0) - -/* GCR_L2_PFT_CONTROL register fields */ -#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12 -#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12) -#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8 -#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8) -#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0 -#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0) - -/* GCR_L2_PFT_CONTROL_B register fields */ -#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8 -#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8) -#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0 -#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0) - -/* GCR_Cx_COHERENCE register fields */ -#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 -#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) -#define CM3_GCR_Cx_COHERENCE_COHEN_MSK (_ULCAST_(0x1) << 0) - -/* GCR_Cx_CONFIG register fields */ -#define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 -#define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK (_ULCAST_(0x3) << 10) -#define CM_GCR_Cx_CONFIG_PVPE_SHF 0 -#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x3ff) << 0) - -/* GCR_Cx_OTHER register fields */ -#define CM_GCR_Cx_OTHER_CORENUM_SHF 16 -#define CM_GCR_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xffff) << 16) -#define CM3_GCR_Cx_OTHER_CORE_SHF 8 -#define CM3_GCR_Cx_OTHER_CORE_MSK (_ULCAST_(0x3f) << 8) -#define CM3_GCR_Cx_OTHER_VP_SHF 0 -#define CM3_GCR_Cx_OTHER_VP_MSK (_ULCAST_(0x7) << 0) - -/* GCR_Cx_RESET_BASE register fields */ -#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF 12 -#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_MSK (_ULCAST_(0xfffff) << 12) - -/* GCR_Cx_RESET_EXT_BASE register fields */ -#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_SHF 31 -#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_MSK (_ULCAST_(0x1) << 31) -#define CM_GCR_Cx_RESET_EXT_BASE_UEB_SHF 30 -#define CM_GCR_Cx_RESET_EXT_BASE_UEB_MSK (_ULCAST_(0x1) << 30) -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_SHF 20 -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_MSK (_ULCAST_(0xff) << 20) -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_SHF 1 -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_MSK (_ULCAST_(0x7f) << 1) -#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_SHF 0 -#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_MSK (_ULCAST_(0x1) << 0) - -/** - * mips_cm_numcores - return the number of cores present in the system - * - * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or - * zero if no Coherence Manager is present. - */ -static inline unsigned mips_cm_numcores(void) -{ - if (!mips_cm_present()) - return 0; - - return ((read_gcr_config() & CM_GCR_CONFIG_PCORES_MSK) - >> CM_GCR_CONFIG_PCORES_SHF) + 1; -} - -/** - * mips_cm_numiocu - return the number of IOCUs present in the system - * - * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero - * if no Coherence Manager is present. - */ -static inline unsigned mips_cm_numiocu(void) -{ - if (!mips_cm_present()) - return 0; - - return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU_MSK) - >> CM_GCR_CONFIG_NUMIOCU_SHF; -} +#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0) + +/* GCR_ERR_CONTROL - Control error checking logic */ +GCR_ACCESSOR_RW(32, 0x038, err_control) +#define CM_GCR_ERR_CONTROL_L2_ECC_EN BIT(1) +#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT BIT(0) + +/* GCR_ERR_MASK - Control which errors are reported as interrupts */ +GCR_ACCESSOR_RW(64, 0x040, error_mask) + +/* GCR_ERR_CAUSE - Indicates the type of error that occurred */ +GCR_ACCESSOR_RW(64, 0x048, error_cause) +#define CM_GCR_ERROR_CAUSE_ERRTYPE GENMASK(31, 27) +#define CM3_GCR_ERROR_CAUSE_ERRTYPE GENMASK_ULL(63, 58) +#define CM_GCR_ERROR_CAUSE_ERRINFO GENMASK(26, 0) + +/* GCR_ERR_ADDR - Indicates the address associated with an error */ +GCR_ACCESSOR_RW(64, 0x050, error_addr) + +/* GCR_ERR_MULT - Indicates when multiple errors have occurred */ +GCR_ACCESSOR_RW(64, 0x058, error_mult) +#define CM_GCR_ERROR_MULT_ERR2ND GENMASK(4, 0) + +/* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */ +GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base) +#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE GENMASK(31, 12) +#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN BIT(0) + +/* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */ +GCR_ACCESSOR_RW(64, 0x080, gic_base) +#define CM_GCR_GIC_BASE_GICBASE GENMASK(31, 17) +#define CM_GCR_GIC_BASE_GICEN BIT(0) + +/* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */ +GCR_ACCESSOR_RW(64, 0x088, cpc_base) +#define CM_GCR_CPC_BASE_CPCBASE GENMASK(31, 15) +#define CM_GCR_CPC_BASE_CPCEN BIT(0) + +/* GCR_REGn_BASE - Base addresses of CM address regions */ +GCR_ACCESSOR_RW(64, 0x090, reg0_base) +GCR_ACCESSOR_RW(64, 0x0a0, reg1_base) +GCR_ACCESSOR_RW(64, 0x0b0, reg2_base) +GCR_ACCESSOR_RW(64, 0x0c0, reg3_base) +#define CM_GCR_REGn_BASE_BASEADDR GENMASK(31, 16) + +/* GCR_REGn_MASK - Size & destination of CM address regions */ +GCR_ACCESSOR_RW(64, 0x098, reg0_mask) +GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask) +GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask) +GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask) +#define CM_GCR_REGn_MASK_ADDRMASK GENMASK(31, 16) +#define CM_GCR_REGn_MASK_CCAOVR GENMASK(7, 5) +#define CM_GCR_REGn_MASK_CCAOVREN BIT(4) +#define CM_GCR_REGn_MASK_DROPL2 BIT(2) +#define CM_GCR_REGn_MASK_CMTGT GENMASK(1, 0) +#define CM_GCR_REGn_MASK_CMTGT_DISABLED 0x0 +#define CM_GCR_REGn_MASK_CMTGT_MEM 0x1 +#define CM_GCR_REGn_MASK_CMTGT_IOCU0 0x2 +#define CM_GCR_REGn_MASK_CMTGT_IOCU1 0x3 + +/* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */ +GCR_ACCESSOR_RO(32, 0x0d0, gic_status) +#define CM_GCR_GIC_STATUS_EX BIT(0) + +/* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */ +GCR_ACCESSOR_RO(32, 0x0f0, cpc_status) +#define CM_GCR_CPC_STATUS_EX BIT(0) + +/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */ +GCR_ACCESSOR_RW(32, 0x130, l2_config) +#define CM_GCR_L2_CONFIG_BYPASS BIT(20) +#define CM_GCR_L2_CONFIG_SET_SIZE GENMASK(15, 12) +#define CM_GCR_L2_CONFIG_LINE_SIZE GENMASK(11, 8) +#define CM_GCR_L2_CONFIG_ASSOC GENMASK(7, 0) + +/* GCR_SYS_CONFIG2 - Further information about the system */ +GCR_ACCESSOR_RO(32, 0x150, sys_config2) +#define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0) + +/* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */ +GCR_ACCESSOR_RW(32, 0x300, l2_pft_control) +#define CM_GCR_L2_PFT_CONTROL_PAGEMASK GENMASK(31, 12) +#define CM_GCR_L2_PFT_CONTROL_PFTEN BIT(8) +#define CM_GCR_L2_PFT_CONTROL_NPFT GENMASK(7, 0) + +/* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */ +GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b) +#define CM_GCR_L2_PFT_CONTROL_B_CEN BIT(8) +#define CM_GCR_L2_PFT_CONTROL_B_PORTID GENMASK(7, 0) + +/* GCR_L2SM_COP - L2 cache op state machine control */ +GCR_ACCESSOR_RW(32, 0x620, l2sm_cop) +#define CM_GCR_L2SM_COP_PRESENT BIT(31) +#define CM_GCR_L2SM_COP_RESULT GENMASK(8, 6) +#define CM_GCR_L2SM_COP_RESULT_DONTCARE 0 +#define CM_GCR_L2SM_COP_RESULT_DONE_OK 1 +#define CM_GCR_L2SM_COP_RESULT_DONE_ERROR 2 +#define CM_GCR_L2SM_COP_RESULT_ABORT_OK 3 +#define CM_GCR_L2SM_COP_RESULT_ABORT_ERROR 4 +#define CM_GCR_L2SM_COP_RUNNING BIT(5) +#define CM_GCR_L2SM_COP_TYPE GENMASK(4, 2) +#define CM_GCR_L2SM_COP_TYPE_IDX_WBINV 0 +#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAG 1 +#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA 2 +#define CM_GCR_L2SM_COP_TYPE_HIT_INV 4 +#define CM_GCR_L2SM_COP_TYPE_HIT_WBINV 5 +#define CM_GCR_L2SM_COP_TYPE_HIT_WB 6 +#define CM_GCR_L2SM_COP_TYPE_FETCHLOCK 7 +#define CM_GCR_L2SM_COP_CMD GENMASK(1, 0) +#define CM_GCR_L2SM_COP_CMD_START 1 /* only when idle */ +#define CM_GCR_L2SM_COP_CMD_ABORT 3 /* only when running */ + +/* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */ +GCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop) +#define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES GENMASK_ULL(63, 48) +#define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG GENMASK_ULL(47, 6) + +/* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */ +GCR_ACCESSOR_RW(64, 0x680, bev_base) + +/* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */ +GCR_CX_ACCESSOR_RW(32, 0x000, reset_release) + +/* GCR_Cx_COHERENCE - Controls core coherence */ +GCR_CX_ACCESSOR_RW(32, 0x008, coherence) +#define CM_GCR_Cx_COHERENCE_COHDOMAINEN GENMASK(7, 0) +#define CM3_GCR_Cx_COHERENCE_COHEN BIT(0) + +/* GCR_Cx_CONFIG - Information about a core's configuration */ +GCR_CX_ACCESSOR_RO(32, 0x010, config) +#define CM_GCR_Cx_CONFIG_IOCUTYPE GENMASK(11, 10) +#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0) + +/* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */ +GCR_CX_ACCESSOR_RW(32, 0x018, other) +#define CM_GCR_Cx_OTHER_CORENUM GENMASK(31, 16) /* CM < 3 */ +#define CM_GCR_Cx_OTHER_CLUSTER_EN BIT(31) /* CM >= 3.5 */ +#define CM_GCR_Cx_OTHER_GIC_EN BIT(30) /* CM >= 3.5 */ +#define CM_GCR_Cx_OTHER_BLOCK GENMASK(25, 24) /* CM >= 3.5 */ +#define CM_GCR_Cx_OTHER_BLOCK_LOCAL 0 +#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL 1 +#define CM_GCR_Cx_OTHER_BLOCK_USER 2 +#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH 3 +#define CM_GCR_Cx_OTHER_CLUSTER GENMASK(21, 16) /* CM >= 3.5 */ +#define CM3_GCR_Cx_OTHER_CORE GENMASK(13, 8) /* CM >= 3 */ +#define CM_GCR_Cx_OTHER_CORE_CM 32 +#define CM3_GCR_Cx_OTHER_VP GENMASK(2, 0) /* CM >= 3 */ + +/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */ +GCR_CX_ACCESSOR_RW(32, 0x020, reset_base) +#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE GENMASK(31, 12) + +/* GCR_Cx_ID - Identify the current core */ +GCR_CX_ACCESSOR_RO(32, 0x028, id) +#define CM_GCR_Cx_ID_CLUSTER GENMASK(15, 8) +#define CM_GCR_Cx_ID_CORE GENMASK(7, 0) + +/* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */ +GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base) +#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET BIT(31) +#define CM_GCR_Cx_RESET_EXT_BASE_UEB BIT(30) +#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK GENMASK(27, 20) +#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA GENMASK(7, 1) +#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT BIT(0) /** * mips_cm_l2sync - perform an L2-only sync operation @@ -469,7 +369,7 @@ static inline unsigned int mips_cm_max_vp_width(void) uint32_t cfg; if (mips_cm_revision() >= CM_REV_CM3) - return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK; + return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW; if (mips_cm_present()) { /* @@ -477,8 +377,8 @@ static inline unsigned int mips_cm_max_vp_width(void) * number of VP(E)s, and if that ever changes then this will * need revisiting. */ - cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE_MSK; - return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; + cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE; + return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1; } if (IS_ENABLED(CONFIG_SMP)) @@ -499,7 +399,7 @@ static inline unsigned int mips_cm_max_vp_width(void) */ static inline unsigned int mips_cm_vp_id(unsigned int cpu) { - unsigned int core = cpu_data[cpu].core; + unsigned int core = cpu_core(&cpu_data[cpu]); unsigned int vp = cpu_vpe_id(&cpu_data[cpu]); return (core * mips_cm_max_vp_width()) + vp; @@ -508,29 +408,56 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu) #ifdef CONFIG_MIPS_CM /** - * mips_cm_lock_other - lock access to another core + * mips_cm_lock_other - lock access to redirect/other region + * @cluster: the other cluster to be accessed * @core: the other core to be accessed * @vp: the VP within the other core to be accessed + * @block: the register block to be accessed * - * Call before operating upon a core via the 'other' register region in - * order to prevent the region being moved during access. Must be followed - * by a call to mips_cm_unlock_other. + * Configure the redirect/other region for the local core/VP (depending upon + * the CM revision) to target the specified @cluster, @core, @vp & register + * @block. Must be called before using the redirect/other region, and followed + * by a call to mips_cm_unlock_other() when access to the redirect/other region + * is complete. + * + * This function acquires a spinlock such that code between it & + * mips_cm_unlock_other() calls cannot be pre-empted by anything which may + * reconfigure the redirect/other region, and cannot be interfered with by + * another VP in the core. As such calls to this function should not be nested. */ -extern void mips_cm_lock_other(unsigned int core, unsigned int vp); +extern void mips_cm_lock_other(unsigned int cluster, unsigned int core, + unsigned int vp, unsigned int block); /** - * mips_cm_unlock_other - unlock access to another core + * mips_cm_unlock_other - unlock access to redirect/other region * - * Call after operating upon another core via the 'other' register region. - * Must be called after mips_cm_lock_other. + * Must be called after mips_cm_lock_other() once all required access to the + * redirect/other region has been completed. */ extern void mips_cm_unlock_other(void); #else /* !CONFIG_MIPS_CM */ -static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { } +static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core, + unsigned int vp, unsigned int block) { } static inline void mips_cm_unlock_other(void) { } #endif /* !CONFIG_MIPS_CM */ +/** + * mips_cm_lock_other_cpu - lock access to redirect/other region + * @cpu: the other CPU whose register we want to access + * + * Configure the redirect/other region for the local core/VP (depending upon + * the CM revision) to target the specified @cpu & register @block. This is + * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number + * for convenience. + */ +static inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block) +{ + struct cpuinfo_mips *d = &cpu_data[cpu]; + + mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block); +} + #endif /* __MIPS_ASM_MIPS_CM_H__ */ diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index 8c519f9827a3036c3a16f3beb60ba182b71665fd..f885051a837876ab19bdd110099a2c3a83ec4ba2 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h @@ -8,11 +8,15 @@ * option) any later version. */ +#ifndef __MIPS_ASM_MIPS_CPS_H__ +# error Please include asm/mips-cps.h rather than asm/mips-cpc.h +#endif + #ifndef __MIPS_ASM_MIPS_CPC_H__ #define __MIPS_ASM_MIPS_CPC_H__ -#include -#include +#include +#include /* The base address of the CPC registers */ extern void __iomem *mips_cpc_base; @@ -61,89 +65,92 @@ static inline bool mips_cpc_present(void) #define MIPS_CPC_CLCB_OFS 0x2000 #define MIPS_CPC_COCB_OFS 0x4000 -/* Macros to ease the creation of register access functions */ -#define BUILD_CPC_R_(name, off) \ -static inline u32 *addr_cpc_##name(void) \ -{ \ - return (u32 *)(mips_cpc_base + (off)); \ -} \ - \ -static inline u32 read_cpc_##name(void) \ -{ \ - return __raw_readl(mips_cpc_base + (off)); \ -} - -#define BUILD_CPC__W(name, off) \ -static inline void write_cpc_##name(u32 value) \ -{ \ - __raw_writel(value, mips_cpc_base + (off)); \ -} - -#define BUILD_CPC_RW(name, off) \ - BUILD_CPC_R_(name, off) \ - BUILD_CPC__W(name, off) - -#define BUILD_CPC_Cx_R_(name, off) \ - BUILD_CPC_R_(cl_##name, MIPS_CPC_CLCB_OFS + (off)) \ - BUILD_CPC_R_(co_##name, MIPS_CPC_COCB_OFS + (off)) - -#define BUILD_CPC_Cx__W(name, off) \ - BUILD_CPC__W(cl_##name, MIPS_CPC_CLCB_OFS + (off)) \ - BUILD_CPC__W(co_##name, MIPS_CPC_COCB_OFS + (off)) - -#define BUILD_CPC_Cx_RW(name, off) \ - BUILD_CPC_Cx_R_(name, off) \ - BUILD_CPC_Cx__W(name, off) - -/* GCB register accessor functions */ -BUILD_CPC_RW(access, MIPS_CPC_GCB_OFS + 0x00) -BUILD_CPC_RW(seqdel, MIPS_CPC_GCB_OFS + 0x08) -BUILD_CPC_RW(rail, MIPS_CPC_GCB_OFS + 0x10) -BUILD_CPC_RW(resetlen, MIPS_CPC_GCB_OFS + 0x18) -BUILD_CPC_R_(revision, MIPS_CPC_GCB_OFS + 0x20) - -/* Core Local & Core Other accessor functions */ -BUILD_CPC_Cx_RW(cmd, 0x00) -BUILD_CPC_Cx_RW(stat_conf, 0x08) -BUILD_CPC_Cx_RW(other, 0x10) -BUILD_CPC_Cx_RW(vp_stop, 0x20) -BUILD_CPC_Cx_RW(vp_run, 0x28) -BUILD_CPC_Cx_RW(vp_running, 0x30) - -/* CPC_Cx_CMD register fields */ -#define CPC_Cx_CMD_SHF 0 -#define CPC_Cx_CMD_MSK (_ULCAST_(0xf) << 0) -#define CPC_Cx_CMD_CLOCKOFF (_ULCAST_(0x1) << 0) -#define CPC_Cx_CMD_PWRDOWN (_ULCAST_(0x2) << 0) -#define CPC_Cx_CMD_PWRUP (_ULCAST_(0x3) << 0) -#define CPC_Cx_CMD_RESET (_ULCAST_(0x4) << 0) - -/* CPC_Cx_STAT_CONF register fields */ -#define CPC_Cx_STAT_CONF_PWRUPE_SHF 23 -#define CPC_Cx_STAT_CONF_PWRUPE_MSK (_ULCAST_(0x1) << 23) -#define CPC_Cx_STAT_CONF_SEQSTATE_SHF 19 -#define CPC_Cx_STAT_CONF_SEQSTATE_MSK (_ULCAST_(0xf) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D0 (_ULCAST_(0x0) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U0 (_ULCAST_(0x1) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U1 (_ULCAST_(0x2) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U2 (_ULCAST_(0x3) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U3 (_ULCAST_(0x4) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U4 (_ULCAST_(0x5) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U5 (_ULCAST_(0x6) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U6 (_ULCAST_(0x7) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D1 (_ULCAST_(0x8) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D3 (_ULCAST_(0x9) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D2 (_ULCAST_(0xa) << 19) -#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_SHF 17 -#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK (_ULCAST_(0x1) << 17) -#define CPC_Cx_STAT_CONF_PWRDN_IMPL_SHF 16 -#define CPC_Cx_STAT_CONF_PWRDN_IMPL_MSK (_ULCAST_(0x1) << 16) -#define CPC_Cx_STAT_CONF_EJTAG_PROBE_SHF 15 -#define CPC_Cx_STAT_CONF_EJTAG_PROBE_MSK (_ULCAST_(0x1) << 15) - -/* CPC_Cx_OTHER register fields */ -#define CPC_Cx_OTHER_CORENUM_SHF 16 -#define CPC_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xff) << 16) +#define CPC_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name) + +#define CPC_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name) + +#define CPC_CX_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name) + +#define CPC_CX_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name) + +/* CPC_ACCESS - Control core/IOCU access to CPC registers prior to CM 3 */ +CPC_ACCESSOR_RW(32, 0x000, access) + +/* CPC_SEQDEL - Configure delays between command sequencer steps */ +CPC_ACCESSOR_RW(32, 0x008, seqdel) + +/* CPC_RAIL - Configure the delay from rail power-up to stability */ +CPC_ACCESSOR_RW(32, 0x010, rail) + +/* CPC_RESETLEN - Configure the length of reset sequences */ +CPC_ACCESSOR_RW(32, 0x018, resetlen) + +/* CPC_REVISION - Indicates the revisison of the CPC */ +CPC_ACCESSOR_RO(32, 0x020, revision) + +/* CPC_PWRUP_CTL - Control power to the Coherence Manager (CM) */ +CPC_ACCESSOR_RW(32, 0x030, pwrup_ctl) +#define CPC_PWRUP_CTL_CM_PWRUP BIT(0) + +/* CPC_CONFIG - Mirrors GCR_CONFIG */ +CPC_ACCESSOR_RW(64, 0x138, config) + +/* CPC_SYS_CONFIG - Control cluster endianness */ +CPC_ACCESSOR_RW(32, 0x140, sys_config) +#define CPC_SYS_CONFIG_BE_IMMEDIATE BIT(2) +#define CPC_SYS_CONFIG_BE_STATUS BIT(1) +#define CPC_SYS_CONFIG_BE BIT(0) + +/* CPC_Cx_CMD - Instruct the CPC to take action on a core */ +CPC_CX_ACCESSOR_RW(32, 0x000, cmd) +#define CPC_Cx_CMD GENMASK(3, 0) +#define CPC_Cx_CMD_CLOCKOFF 0x1 +#define CPC_Cx_CMD_PWRDOWN 0x2 +#define CPC_Cx_CMD_PWRUP 0x3 +#define CPC_Cx_CMD_RESET 0x4 + +/* CPC_Cx_STAT_CONF - Indicates core configuration & state */ +CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf) +#define CPC_Cx_STAT_CONF_PWRUPE BIT(23) +#define CPC_Cx_STAT_CONF_SEQSTATE GENMASK(22, 19) +#define CPC_Cx_STAT_CONF_SEQSTATE_D0 0x0 +#define CPC_Cx_STAT_CONF_SEQSTATE_U0 0x1 +#define CPC_Cx_STAT_CONF_SEQSTATE_U1 0x2 +#define CPC_Cx_STAT_CONF_SEQSTATE_U2 0x3 +#define CPC_Cx_STAT_CONF_SEQSTATE_U3 0x4 +#define CPC_Cx_STAT_CONF_SEQSTATE_U4 0x5 +#define CPC_Cx_STAT_CONF_SEQSTATE_U5 0x6 +#define CPC_Cx_STAT_CONF_SEQSTATE_U6 0x7 +#define CPC_Cx_STAT_CONF_SEQSTATE_D1 0x8 +#define CPC_Cx_STAT_CONF_SEQSTATE_D3 0x9 +#define CPC_Cx_STAT_CONF_SEQSTATE_D2 0xa +#define CPC_Cx_STAT_CONF_CLKGAT_IMPL BIT(17) +#define CPC_Cx_STAT_CONF_PWRDN_IMPL BIT(16) +#define CPC_Cx_STAT_CONF_EJTAG_PROBE BIT(15) + +/* CPC_Cx_OTHER - Configure the core-other register block prior to CM 3 */ +CPC_CX_ACCESSOR_RW(32, 0x010, other) +#define CPC_Cx_OTHER_CORENUM GENMASK(23, 16) + +/* CPC_Cx_VP_STOP - Stop Virtual Processors (VPs) within a core from running */ +CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop) + +/* CPC_Cx_VP_START - Start Virtual Processors (VPs) within a core running */ +CPC_CX_ACCESSOR_RW(32, 0x028, vp_run) + +/* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */ +CPC_CX_ACCESSOR_RW(32, 0x030, vp_running) + +/* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */ +CPC_CX_ACCESSOR_RW(32, 0x090, config) #ifdef CONFIG_MIPS_CPC diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h new file mode 100644 index 0000000000000000000000000000000000000000..bf02b5070a989cc11ee39c85ce21ece9ee67990c --- /dev/null +++ b/arch/mips/include/asm/mips-cps.h @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2017 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_ASM_MIPS_CPS_H__ +#define __MIPS_ASM_MIPS_CPS_H__ + +#include +#include + +extern unsigned long __cps_access_bad_size(void) + __compiletime_error("Bad size for CPS accessor"); + +#define CPS_ACCESSOR_A(unit, off, name) \ +static inline void *addr_##unit##_##name(void) \ +{ \ + return mips_##unit##_base + (off); \ +} + +#define CPS_ACCESSOR_R(unit, sz, name) \ +static inline uint##sz##_t read_##unit##_##name(void) \ +{ \ + uint64_t val64; \ + \ + switch (sz) { \ + case 32: \ + return __raw_readl(addr_##unit##_##name()); \ + \ + case 64: \ + if (mips_cm_is64) \ + return __raw_readq(addr_##unit##_##name()); \ + \ + val64 = __raw_readl(addr_##unit##_##name() + 4); \ + val64 <<= 32; \ + val64 |= __raw_readl(addr_##unit##_##name()); \ + return val64; \ + \ + default: \ + return __cps_access_bad_size(); \ + } \ +} + +#define CPS_ACCESSOR_W(unit, sz, name) \ +static inline void write_##unit##_##name(uint##sz##_t val) \ +{ \ + switch (sz) { \ + case 32: \ + __raw_writel(val, addr_##unit##_##name()); \ + break; \ + \ + case 64: \ + if (mips_cm_is64) { \ + __raw_writeq(val, addr_##unit##_##name()); \ + break; \ + } \ + \ + __raw_writel((uint64_t)val >> 32, \ + addr_##unit##_##name() + 4); \ + __raw_writel(val, addr_##unit##_##name()); \ + break; \ + \ + default: \ + __cps_access_bad_size(); \ + break; \ + } \ +} + +#define CPS_ACCESSOR_M(unit, sz, name) \ +static inline void change_##unit##_##name(uint##sz##_t mask, \ + uint##sz##_t val) \ +{ \ + uint##sz##_t reg_val = read_##unit##_##name(); \ + reg_val &= ~mask; \ + reg_val |= val; \ + write_##unit##_##name(reg_val); \ +} \ + \ +static inline void set_##unit##_##name(uint##sz##_t val) \ +{ \ + change_##unit##_##name(val, val); \ +} \ + \ +static inline void clear_##unit##_##name(uint##sz##_t val) \ +{ \ + change_##unit##_##name(val, 0); \ +} + +#define CPS_ACCESSOR_RO(unit, sz, off, name) \ + CPS_ACCESSOR_A(unit, off, name) \ + CPS_ACCESSOR_R(unit, sz, name) + +#define CPS_ACCESSOR_WO(unit, sz, off, name) \ + CPS_ACCESSOR_A(unit, off, name) \ + CPS_ACCESSOR_W(unit, sz, name) + +#define CPS_ACCESSOR_RW(unit, sz, off, name) \ + CPS_ACCESSOR_A(unit, off, name) \ + CPS_ACCESSOR_R(unit, sz, name) \ + CPS_ACCESSOR_W(unit, sz, name) \ + CPS_ACCESSOR_M(unit, sz, name) + +#include +#include +#include + +/** + * mips_cps_numclusters - return the number of clusters present in the system + * + * Returns the number of clusters in the system. + */ +static inline unsigned int mips_cps_numclusters(void) +{ + unsigned int num_clusters; + + if (mips_cm_revision() < CM_REV_CM3_5) + return 1; + + num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS; + num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS); + return num_clusters; +} + +/** + * mips_cps_cluster_config - return (GCR|CPC)_CONFIG from a cluster + * @cluster: the ID of the cluster whose config we want + * + * Read the value of GCR_CONFIG (or its CPC_CONFIG mirror) from a @cluster. + * + * Returns the value of GCR_CONFIG. + */ +static inline uint64_t mips_cps_cluster_config(unsigned int cluster) +{ + uint64_t config; + + if (mips_cm_revision() < CM_REV_CM3_5) { + /* + * Prior to CM 3.5 we don't have the notion of multiple + * clusters so we can trivially read the GCR_CONFIG register + * within this cluster. + */ + WARN_ON(cluster != 0); + config = read_gcr_config(); + } else { + /* + * From CM 3.5 onwards we read the CPC_CONFIG mirror of + * GCR_CONFIG via the redirect region, since the CPC is always + * powered up allowing us not to need to power up the CM. + */ + mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL); + config = read_cpc_redir_config(); + mips_cm_unlock_other(); + } + + return config; +} + +/** + * mips_cps_numcores - return the number of cores present in a cluster + * @cluster: the ID of the cluster whose core count we want + * + * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or + * zero if no Coherence Manager is present. + */ +static inline unsigned int mips_cps_numcores(unsigned int cluster) +{ + if (!mips_cm_present()) + return 0; + + /* Add one before masking to handle 0xff indicating no cores */ + return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; +} + +/** + * mips_cps_numiocu - return the number of IOCUs present in a cluster + * @cluster: the ID of the cluster whose IOCU count we want + * + * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero + * if no Coherence Manager is present. + */ +static inline unsigned int mips_cps_numiocu(unsigned int cluster) +{ + unsigned int num_iocu; + + if (!mips_cm_present()) + return 0; + + num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU; + num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU); + return num_iocu; +} + +/** + * mips_cps_numvps - return the number of VPs (threads) supported by a core + * @cluster: the ID of the cluster containing the core we want to examine + * @core: the ID of the core whose VP count we want + * + * Returns the number of Virtual Processors (VPs, ie. hardware threads) that + * are supported by the given @core in the given @cluster. If the core or the + * kernel do not support hardware mutlti-threading this returns 1. + */ +static inline unsigned int mips_cps_numvps(unsigned int cluster, unsigned int core) +{ + unsigned int cfg; + + if (!mips_cm_present()) + return 1; + + if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) + && (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp)) + return 1; + + mips_cm_lock_other(cluster, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); + + if (mips_cm_revision() < CM_REV_CM3_5) { + /* + * Prior to CM 3.5 we can only have one cluster & don't have + * CPC_Cx_CONFIG, so we read GCR_Cx_CONFIG. + */ + cfg = read_gcr_co_config(); + } else { + /* + * From CM 3.5 onwards we read CPC_Cx_CONFIG because the CPC is + * always powered, which allows us to not worry about powering + * up the cluster's CM here. + */ + cfg = read_cpc_co_config(); + } + + mips_cm_unlock_other(); + + return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE; +} + +#endif /* __MIPS_ASM_MIPS_CPS_H__ */ diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h new file mode 100644 index 0000000000000000000000000000000000000000..a2badf572632d147b1d470f728c029b36fbcf8b4 --- /dev/null +++ b/arch/mips/include/asm/mips-gic.h @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2017 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_ASM_MIPS_CPS_H__ +# error Please include asm/mips-cps.h rather than asm/mips-gic.h +#endif + +#ifndef __MIPS_ASM_MIPS_GIC_H__ +#define __MIPS_ASM_MIPS_GIC_H__ + +#include + +/* The base address of the GIC registers */ +extern void __iomem *mips_gic_base; + +/* Offsets from the GIC base address to various control blocks */ +#define MIPS_GIC_SHARED_OFS 0x00000 +#define MIPS_GIC_SHARED_SZ 0x08000 +#define MIPS_GIC_LOCAL_OFS 0x08000 +#define MIPS_GIC_LOCAL_SZ 0x04000 +#define MIPS_GIC_REDIR_OFS 0x0c000 +#define MIPS_GIC_REDIR_SZ 0x04000 +#define MIPS_GIC_USER_OFS 0x10000 +#define MIPS_GIC_USER_SZ 0x10000 + +/* For read-only shared registers */ +#define GIC_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name) + +/* For read-write shared registers */ +#define GIC_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name) + +/* For read-only local registers */ +#define GIC_VX_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name) \ + CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name) + +/* For read-write local registers */ +#define GIC_VX_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name) \ + CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name) + +/* For read-only shared per-interrupt registers */ +#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \ +static inline void __iomem *addr_gic_##name(unsigned int intr) \ +{ \ + return mips_gic_base + (off) + (intr * (stride)); \ +} \ + \ +static inline unsigned int read_gic_##name(unsigned int intr) \ +{ \ + BUILD_BUG_ON(sz != 32); \ + return __raw_readl(addr_gic_##name(intr)); \ +} + +/* For read-write shared per-interrupt registers */ +#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \ + GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \ + \ +static inline void write_gic_##name(unsigned int intr, \ + unsigned int val) \ +{ \ + BUILD_BUG_ON(sz != 32); \ + __raw_writel(val, addr_gic_##name(intr)); \ +} + +/* For read-only local per-interrupt registers */ +#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \ + GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \ + stride, vl_##name) \ + GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \ + stride, vo_##name) + +/* For read-write local per-interrupt registers */ +#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \ + GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \ + stride, vl_##name) \ + GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \ + stride, vo_##name) + +/* For read-only shared bit-per-interrupt registers */ +#define GIC_ACCESSOR_RO_INTR_BIT(off, name) \ +static inline void __iomem *addr_gic_##name(void) \ +{ \ + return mips_gic_base + (off); \ +} \ + \ +static inline unsigned int read_gic_##name(unsigned int intr) \ +{ \ + void __iomem *addr = addr_gic_##name(); \ + unsigned int val; \ + \ + if (mips_cm_is64) { \ + addr += (intr / 64) * sizeof(uint64_t); \ + val = __raw_readq(addr) >> intr % 64; \ + } else { \ + addr += (intr / 32) * sizeof(uint32_t); \ + val = __raw_readl(addr) >> intr % 32; \ + } \ + \ + return val & 0x1; \ +} + +/* For read-write shared bit-per-interrupt registers */ +#define GIC_ACCESSOR_RW_INTR_BIT(off, name) \ + GIC_ACCESSOR_RO_INTR_BIT(off, name) \ + \ +static inline void write_gic_##name(unsigned int intr) \ +{ \ + void __iomem *addr = addr_gic_##name(); \ + \ + if (mips_cm_is64) { \ + addr += (intr / 64) * sizeof(uint64_t); \ + __raw_writeq(BIT(intr % 64), addr); \ + } else { \ + addr += (intr / 32) * sizeof(uint32_t); \ + __raw_writel(BIT(intr % 32), addr); \ + } \ +} \ + \ +static inline void change_gic_##name(unsigned int intr, \ + unsigned int val) \ +{ \ + void __iomem *addr = addr_gic_##name(); \ + \ + if (mips_cm_is64) { \ + uint64_t _val; \ + \ + addr += (intr / 64) * sizeof(uint64_t); \ + _val = __raw_readq(addr); \ + _val &= ~BIT_ULL(intr % 64); \ + _val |= (uint64_t)val << (intr % 64); \ + __raw_writeq(_val, addr); \ + } else { \ + uint32_t _val; \ + \ + addr += (intr / 32) * sizeof(uint32_t); \ + _val = __raw_readl(addr); \ + _val &= ~BIT(intr % 32); \ + _val |= val << (intr % 32); \ + __raw_writel(_val, addr); \ + } \ +} + +/* For read-only local bit-per-interrupt registers */ +#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name) \ + GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \ + vl_##name) \ + GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \ + vo_##name) + +/* For read-write local bit-per-interrupt registers */ +#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name) \ + GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \ + vl_##name) \ + GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \ + vo_##name) + +/* GIC_SH_CONFIG - Information about the GIC configuration */ +GIC_ACCESSOR_RW(32, 0x000, config) +#define GIC_CONFIG_COUNTSTOP BIT(28) +#define GIC_CONFIG_COUNTBITS GENMASK(27, 24) +#define GIC_CONFIG_NUMINTERRUPTS GENMASK(23, 16) +#define GIC_CONFIG_PVPS GENMASK(6, 0) + +/* GIC_SH_COUNTER - Shared global counter value */ +GIC_ACCESSOR_RW(64, 0x010, counter) +GIC_ACCESSOR_RW(32, 0x010, counter_32l) +GIC_ACCESSOR_RW(32, 0x014, counter_32h) + +/* GIC_SH_POL_* - Configures interrupt polarity */ +GIC_ACCESSOR_RW_INTR_BIT(0x100, pol) +#define GIC_POL_ACTIVE_LOW 0 /* when level triggered */ +#define GIC_POL_ACTIVE_HIGH 1 /* when level triggered */ +#define GIC_POL_FALLING_EDGE 0 /* when single-edge triggered */ +#define GIC_POL_RISING_EDGE 1 /* when single-edge triggered */ + +/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */ +GIC_ACCESSOR_RW_INTR_BIT(0x180, trig) +#define GIC_TRIG_LEVEL 0 +#define GIC_TRIG_EDGE 1 + +/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */ +GIC_ACCESSOR_RW_INTR_BIT(0x200, dual) +#define GIC_DUAL_SINGLE 0 /* when edge-triggered */ +#define GIC_DUAL_DUAL 1 /* when edge-triggered */ + +/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */ +GIC_ACCESSOR_RW(32, 0x280, wedge) +#define GIC_WEDGE_RW BIT(31) +#define GIC_WEDGE_INTR GENMASK(7, 0) + +/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */ +GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask) + +/* GIC_SH_SMASK_* - Set shared interrupt mask bits */ +GIC_ACCESSOR_RW_INTR_BIT(0x380, smask) + +/* GIC_SH_MASK_* - Read the current shared interrupt mask */ +GIC_ACCESSOR_RO_INTR_BIT(0x400, mask) + +/* GIC_SH_PEND_* - Read currently pending shared interrupts */ +GIC_ACCESSOR_RO_INTR_BIT(0x480, pend) + +/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */ +GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin) +#define GIC_MAP_PIN_MAP_TO_PIN BIT(31) +#define GIC_MAP_PIN_MAP_TO_NMI BIT(30) +#define GIC_MAP_PIN_MAP GENMASK(5, 0) + +/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */ +GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp) + +/* GIC_Vx_CTL - VP-level interrupt control */ +GIC_VX_ACCESSOR_RW(32, 0x000, ctl) +#define GIC_VX_CTL_FDC_ROUTABLE BIT(4) +#define GIC_VX_CTL_SWINT_ROUTABLE BIT(3) +#define GIC_VX_CTL_PERFCNT_ROUTABLE BIT(2) +#define GIC_VX_CTL_TIMER_ROUTABLE BIT(1) +#define GIC_VX_CTL_EIC BIT(0) + +/* GIC_Vx_PEND - Read currently pending local interrupts */ +GIC_VX_ACCESSOR_RO(32, 0x004, pend) + +/* GIC_Vx_MASK - Read the current local interrupt mask */ +GIC_VX_ACCESSOR_RO(32, 0x008, mask) + +/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */ +GIC_VX_ACCESSOR_RW(32, 0x00c, rmask) + +/* GIC_Vx_SMASK - Set local interrupt mask bits */ +GIC_VX_ACCESSOR_RW(32, 0x010, smask) + +/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */ +GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map) + +/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x040, wd_map) + +/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x044, compare_map) + +/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x048, timer_map) + +/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map) + +/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map) + +/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */ +GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map) + +/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */ +GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map) + +/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */ +GIC_VX_ACCESSOR_RW(32, 0x080, other) +#define GIC_VX_OTHER_VPNUM GENMASK(5, 0) + +/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */ +GIC_VX_ACCESSOR_RO(32, 0x088, ident) +#define GIC_VX_IDENT_VPNUM GENMASK(5, 0) + +/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */ +GIC_VX_ACCESSOR_RW(64, 0x0a0, compare) + +/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */ +GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set) + +/** + * enum mips_gic_local_interrupt - GIC local interrupts + * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt + * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt + * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt + * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt + * @GIC_LOCAL_INT_SWINT0: Software interrupt 0 + * @GIC_LOCAL_INT_SWINT1: Software interrupt 1 + * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt + * @GIC_NUM_LOCAL_INTRS: The number of local interrupts + * + * Enumerates interrupts provided by the GIC that are local to a VP. + */ +enum mips_gic_local_interrupt { + GIC_LOCAL_INT_WD, + GIC_LOCAL_INT_COMPARE, + GIC_LOCAL_INT_TIMER, + GIC_LOCAL_INT_PERFCTR, + GIC_LOCAL_INT_SWINT0, + GIC_LOCAL_INT_SWINT1, + GIC_LOCAL_INT_FDC, + GIC_NUM_LOCAL_INTRS +}; + +/** + * mips_gic_present() - Determine whether a GIC is present + * + * Determines whether a MIPS Global Interrupt Controller (GIC) is present in + * the system that the kernel is running on. + * + * Return true if a GIC is present, else false. + */ +static inline bool mips_gic_present(void) +{ + return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base; +} + +/** + * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq + * + * Determine the virq number to use for the coprocessor 0 count/compare + * interrupt, which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_c0_compare_int(void); + +/** + * gic_get_c0_perfcount_int() - Return performance counter interrupt virq + * + * Determine the virq number to use for CPU performance counter interrupts, + * which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_c0_perfcount_int(void); + +/** + * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq + * + * Determine the virq number to use for fast debug channel (FDC) interrupts, + * which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_c0_fdc_int(void); + +#endif /* __MIPS_ASM_MIPS_CPS_H__ */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index dbb0eceda2c6d5cf05b347f561fc54cf19f7e635..a6810923b3f0214dfa36eab4a28320a65bba7790 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -48,6 +48,7 @@ #define CP0_ENTRYLO0 $2 #define CP0_ENTRYLO1 $3 #define CP0_CONF $3 +#define CP0_GLOBALNUMBER $3, 1 #define CP0_CONTEXT $4 #define CP0_PAGEMASK $5 #define CP0_SEGCTL0 $5, 2 @@ -147,6 +148,16 @@ #define MIPS_ENTRYLO_XI (_ULCAST_(1) << (BITS_PER_LONG - 2)) #define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1)) +/* + * MIPSr6+ GlobalNumber register definitions + */ +#define MIPS_GLOBALNUMBER_VP_SHF 0 +#define MIPS_GLOBALNUMBER_VP (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_VP_SHF) +#define MIPS_GLOBALNUMBER_CORE_SHF 8 +#define MIPS_GLOBALNUMBER_CORE (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_CORE_SHF) +#define MIPS_GLOBALNUMBER_CLUSTER_SHF 16 +#define MIPS_GLOBALNUMBER_CLUSTER (_ULCAST_(0xf) << MIPS_GLOBALNUMBER_CLUSTER_SHF) + /* * Values for PageMask register */ @@ -1366,29 +1377,32 @@ do { \ #define __write_64bit_c0_split(source, sel, val) \ do { \ + unsigned long long __tmp; \ unsigned long __flags; \ \ local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ - "dsll\t%L0, %L0, 32\n\t" \ + "dsll\t%L0, %L1, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ - "dsll\t%M0, %M0, 32\n\t" \ + "dsll\t%M0, %M1, 32\n\t" \ "or\t%L0, %L0, %M0\n\t" \ "dmtc0\t%L0, " #source "\n\t" \ ".set\tmips0" \ - : : "r" (val)); \ + : "=&r,r" (__tmp) \ + : "r,0" (val)); \ else \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ - "dsll\t%L0, %L0, 32\n\t" \ + "dsll\t%L0, %L1, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ - "dsll\t%M0, %M0, 32\n\t" \ + "dsll\t%M0, %M1, 32\n\t" \ "or\t%L0, %L0, %M0\n\t" \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ - : : "r" (val)); \ + : "=&r,r" (__tmp) \ + : "r,0" (val)); \ local_irq_restore(__flags); \ } while (0) @@ -1446,6 +1460,8 @@ do { \ #define read_c0_conf() __read_32bit_c0_register($3, 0) #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) +#define read_c0_globalnumber() __read_32bit_c0_register($3, 1) + #define read_c0_context() __read_ulong_c0_register($4, 0) #define write_c0_context(val) __write_ulong_c0_register($4, 0, val) diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index e51add184717f4283ba68b5cc3e446af364e1b2e..06552a965cf4b1c9f848cf831e11d424145439e0 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -114,8 +114,6 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "R5432 " #elif defined CONFIG_CPU_R5500 #define MODULE_PROC_FAMILY "R5500 " -#elif defined CONFIG_CPU_R6000 -#define MODULE_PROC_FAMILY "R6000 " #elif defined CONFIG_CPU_NEVADA #define MODULE_PROC_FAMILY "NEVADA " #elif defined CONFIG_CPU_R8000 diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h index e0717d10e650fd0ebcbf734bf7f59ddb0954cc50..a6e6cbebe046e9631055ef3fdaa65ea720b71730 100644 --- a/arch/mips/include/asm/netlogic/common.h +++ b/arch/mips/include/asm/netlogic/common.h @@ -84,7 +84,7 @@ nlm_set_nmi_handler(void *handler) */ void nlm_init_boot_cpu(void); unsigned int nlm_get_cpu_frequency(void); -extern struct plat_smp_ops nlm_smp_ops; +extern const struct plat_smp_ops nlm_smp_ops; extern char nlm_reset_entry[], nlm_reset_entry_end[]; /* SWIOTLB */ diff --git a/arch/mips/include/asm/octeon/cvmx-boot-vector.h b/arch/mips/include/asm/octeon/cvmx-boot-vector.h new file mode 100644 index 0000000000000000000000000000000000000000..8db08241d53c54bebc8793df688b7660aaee869d --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-boot-vector.h @@ -0,0 +1,53 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003-2017 Cavium, Inc. + */ + +#ifndef __CVMX_BOOT_VECTOR_H__ +#define __CVMX_BOOT_VECTOR_H__ + +#include + +/* + * The boot vector table is made up of an array of 1024 elements of + * struct cvmx_boot_vector_element. There is one entry for each + * possible MIPS CPUNum, indexed by the CPUNum. + * + * Once cvmx_boot_vector_get() returns a non-NULL value (indicating + * success), NMI to a core will cause execution to transfer to the + * target_ptr location for that core's entry in the vector table. + * + * The struct cvmx_boot_vector_element fields app0, app1, and app2 can + * be used by the application that has set the target_ptr in any + * application specific manner, they are not touched by the vectoring + * code. + * + * The boot vector code clobbers the CP0_DESAVE register, and on + * OCTEON II and later CPUs also clobbers CP0_KScratch2. All GP + * registers are preserved, except on pre-OCTEON II CPUs, where k1 is + * clobbered. + * + */ + + +/* + * Applications install the boot bus code in cvmx-boot-vector.c, which + * uses this magic: + */ +#define OCTEON_BOOT_MOVEABLE_MAGIC1 0xdb00110ad358eacdull + +struct cvmx_boot_vector_element { + /* kseg0 or xkphys address of target code. */ + uint64_t target_ptr; + /* Three application specific arguments. */ + uint64_t app0; + uint64_t app1; + uint64_t app2; +}; + +struct cvmx_boot_vector_element *cvmx_boot_vector_get(void); + +#endif /* __CVMX_BOOT_VECTOR_H__ */ diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h index 374562507d0befef0394316d353340190be9a826..72d2e403a6e4fcc17062a90bd1c7559987a46bb1 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h @@ -255,6 +255,34 @@ extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, char *name); +/** + * Allocate if needed a block of memory from a specific range of the + * free list that was passed to the application by the bootloader, and + * assign it a name in the global named block table. (part of the + * cvmx_bootmem_descriptor_t structure) Named blocks can later be + * freed. If the requested name block is already allocated, return + * the pointer to block of memory. If request cannot be satisfied + * within the address range specified, NULL is returned + * + * @param size Size in bytes of block to allocate + * @param min_addr minimum address of range + * @param max_addr maximum address of range + * @param align Alignment of memory to be allocated. (must be a power of 2) + * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes + * @param init Initialization function + * + * The initialization function is optional, if omitted the named block + * is initialized to all zeros when it is created, i.e. once. + * + * @return pointer to block of memory, NULL on error + */ +void *cvmx_bootmem_alloc_named_range_once(uint64_t size, + uint64_t min_addr, + uint64_t max_addr, + uint64_t align, + char *name, + void (*init) (void *)); + extern int cvmx_bootmem_free_named(char *name); /** diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h index 0dd0e40c96d4d076c3cc51a27f28c33b86bb0edd..6e61792d9248b4af91b0e64978205c463a24aa49 100644 --- a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h +++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h @@ -128,6 +128,7 @@ static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset) case OCTEON_CN52XX & OCTEON_FAMILY_MASK: case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CN70XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; case OCTEON_CN31XX & OCTEON_FAMILY_MASK: case OCTEON_CN50XX & OCTEON_FAMILY_MASK: @@ -143,6 +144,10 @@ static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset) return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; case OCTEON_CN68XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070100100200ull) + (offset) * 8; + case OCTEON_CNF75XX & OCTEON_FAMILY_MASK: + case OCTEON_CN73XX & OCTEON_FAMILY_MASK: + case OCTEON_CN78XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001010000030000ull) + (offset) * 8; } return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; } @@ -180,6 +185,7 @@ static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset) case OCTEON_CN52XX & OCTEON_FAMILY_MASK: case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CN70XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; case OCTEON_CN31XX & OCTEON_FAMILY_MASK: case OCTEON_CN50XX & OCTEON_FAMILY_MASK: @@ -195,6 +201,10 @@ static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset) return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; case OCTEON_CN68XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070100100000ull) + (offset) * 8; + case OCTEON_CNF75XX & OCTEON_FAMILY_MASK: + case OCTEON_CN73XX & OCTEON_FAMILY_MASK: + case OCTEON_CN78XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001010000020000ull) + (offset) * 8; } return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; } diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h index d045973ddb336abbe9b54b21a65b4fb1a6c4f5fe..3ea84acf1814cb2c874ac17dafc73c64db50b5dc 100644 --- a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h +++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h @@ -33,6 +33,10 @@ #define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull)) #define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull)) #define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull)) +#define CVMX_L2C_ERR_TDTX(block_id) \ + (CVMX_ADD_IO_SEG(0x0001180080A007E0ull) + ((block_id) & 3) * 0x40000ull) +#define CVMX_L2C_ERR_TTGX(block_id) \ + (CVMX_ADD_IO_SEG(0x0001180080A007E8ull) + ((block_id) & 3) * 0x40000ull) #define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull)) #define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull)) #define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull)) @@ -66,9 +70,40 @@ ((offset) & 1) * 8) #define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + \ ((offset) & 31) * 8) -#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull)) +union cvmx_l2c_err_tdtx { + uint64_t u64; + struct cvmx_l2c_err_tdtx_s { + __BITFIELD_FIELD(uint64_t dbe:1, + __BITFIELD_FIELD(uint64_t sbe:1, + __BITFIELD_FIELD(uint64_t vdbe:1, + __BITFIELD_FIELD(uint64_t vsbe:1, + __BITFIELD_FIELD(uint64_t syn:10, + __BITFIELD_FIELD(uint64_t reserved_22_49:28, + __BITFIELD_FIELD(uint64_t wayidx:18, + __BITFIELD_FIELD(uint64_t reserved_2_3:2, + __BITFIELD_FIELD(uint64_t type:2, + ;))))))))) + } s; +}; + +union cvmx_l2c_err_ttgx { + uint64_t u64; + struct cvmx_l2c_err_ttgx_s { + __BITFIELD_FIELD(uint64_t dbe:1, + __BITFIELD_FIELD(uint64_t sbe:1, + __BITFIELD_FIELD(uint64_t noway:1, + __BITFIELD_FIELD(uint64_t reserved_56_60:5, + __BITFIELD_FIELD(uint64_t syn:6, + __BITFIELD_FIELD(uint64_t reserved_22_49:28, + __BITFIELD_FIELD(uint64_t wayidx:15, + __BITFIELD_FIELD(uint64_t reserved_2_6:5, + __BITFIELD_FIELD(uint64_t type:2, + ;))))))))) + } s; +}; + union cvmx_l2c_cfg { uint64_t u64; struct cvmx_l2c_cfg_s { diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h new file mode 100644 index 0000000000000000000000000000000000000000..a951ad5d65ad89dd71e84a7c1f959dc0a68b1a18 --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h @@ -0,0 +1,60 @@ +/***********************license start*************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2017 Cavium, Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information + ***********************license end**************************************/ + +#ifndef __CVMX_L2D_DEFS_H__ +#define __CVMX_L2D_DEFS_H__ + +#define CVMX_L2D_ERR (CVMX_ADD_IO_SEG(0x0001180080000010ull)) +#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull)) + + +union cvmx_l2d_err { + uint64_t u64; + struct cvmx_l2d_err_s { + __BITFIELD_FIELD(uint64_t reserved_6_63:58, + __BITFIELD_FIELD(uint64_t bmhclsel:1, + __BITFIELD_FIELD(uint64_t ded_err:1, + __BITFIELD_FIELD(uint64_t sec_err:1, + __BITFIELD_FIELD(uint64_t ded_intena:1, + __BITFIELD_FIELD(uint64_t sec_intena:1, + __BITFIELD_FIELD(uint64_t ecc_ena:1, + ;))))))) + } s; +}; + +union cvmx_l2d_fus3 { + uint64_t u64; + struct cvmx_l2d_fus3_s { + __BITFIELD_FIELD(uint64_t reserved_40_63:24, + __BITFIELD_FIELD(uint64_t ema_ctl:3, + __BITFIELD_FIELD(uint64_t reserved_34_36:3, + __BITFIELD_FIELD(uint64_t q3fus:34, + ;)))) + } s; +}; + +#endif diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 9742202f2a326c45c504de6d77b51eb523421c0c..205ab2ce10f808cffa420bf8e671643f5df27620 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -62,6 +62,7 @@ enum cvmx_mips_space { #include #include #include +#include #include #include #include @@ -356,6 +357,34 @@ static inline unsigned int cvmx_get_local_core_num(void) return cvmx_get_core_num() & ((1 << CVMX_NODE_NO_SHIFT) - 1); } +#define CVMX_NODE_BITS (2) /* Number of bits to define a node */ +#define CVMX_MAX_NODES (1 << CVMX_NODE_BITS) +#define CVMX_NODE_IO_SHIFT (36) +#define CVMX_NODE_MEM_SHIFT (40) +#define CVMX_NODE_IO_MASK ((uint64_t)CVMX_NODE_MASK << CVMX_NODE_IO_SHIFT) + +static inline void cvmx_write_csr_node(uint64_t node, uint64_t csr_addr, + uint64_t val) +{ + uint64_t composite_csr_addr, node_addr; + + node_addr = (node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT; + composite_csr_addr = (csr_addr & ~CVMX_NODE_IO_MASK) | node_addr; + + cvmx_write64_uint64(composite_csr_addr, val); + if (((csr_addr >> 40) & 0x7ffff) == (0x118)) + cvmx_read64_uint64(CVMX_MIO_BOOT_BIST_STAT | node_addr); +} + +static inline uint64_t cvmx_read_csr_node(uint64_t node, uint64_t csr_addr) +{ + uint64_t node_addr; + + node_addr = (csr_addr & ~CVMX_NODE_IO_MASK) | + (node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT; + return cvmx_read_csr(node_addr); +} + /** * Returns the number of bits set in the provided value. * Simple wrapper for POP instruction. diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index 07c0516ef4d5331096be4dd45182ed938a9a96d3..c99c4b6a79f44d3c4bbb4d2144d76fe008e0deaf 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h @@ -362,4 +362,6 @@ extern void octeon_fixup_irqs(void); extern struct semaphore octeon_bootbus_sem; +struct irq_domain *octeon_irq_get_block_domain(int node, uint8_t block); + #endif /* __ASM_OCTEON_OCTEON_H */ diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h index db7c322f057f936d9c658498a5e7d397303efb09..53b2cb8e59666c268c634866819ebe43aa401810 100644 --- a/arch/mips/include/asm/smp-ops.h +++ b/arch/mips/include/asm/smp-ops.h @@ -13,7 +13,7 @@ #include -#include +#include #ifdef CONFIG_SMP @@ -26,7 +26,7 @@ struct plat_smp_ops { void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action); void (*init_secondary)(void); void (*smp_finish)(void); - void (*boot_secondary)(int cpu, struct task_struct *idle); + int (*boot_secondary)(int cpu, struct task_struct *idle); void (*smp_setup)(void); void (*prepare_cpus)(unsigned int max_cpus); #ifdef CONFIG_HOTPLUG_CPU @@ -35,11 +35,11 @@ struct plat_smp_ops { #endif }; -extern void register_smp_ops(struct plat_smp_ops *ops); +extern void register_smp_ops(const struct plat_smp_ops *ops); static inline void plat_smp_setup(void) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->smp_setup(); } @@ -57,7 +57,7 @@ static inline void plat_smp_setup(void) /* UP, nothing to do ... */ } -static inline void register_smp_ops(struct plat_smp_ops *ops) +static inline void register_smp_ops(const struct plat_smp_ops *ops) { } @@ -66,7 +66,7 @@ static inline void register_smp_ops(struct plat_smp_ops *ops) static inline int register_up_smp_ops(void) { #ifdef CONFIG_SMP_UP - extern struct plat_smp_ops up_smp_ops; + extern const struct plat_smp_ops up_smp_ops; register_smp_ops(&up_smp_ops); @@ -79,7 +79,7 @@ static inline int register_up_smp_ops(void) static inline int register_cmp_smp_ops(void) { #ifdef CONFIG_MIPS_CMP - extern struct plat_smp_ops cmp_smp_ops; + extern const struct plat_smp_ops cmp_smp_ops; if (!mips_cm_present()) return -ENODEV; @@ -95,7 +95,7 @@ static inline int register_cmp_smp_ops(void) static inline int register_vsmp_smp_ops(void) { #ifdef CONFIG_MIPS_MT_SMP - extern struct plat_smp_ops vsmp_smp_ops; + extern const struct plat_smp_ops vsmp_smp_ops; register_smp_ops(&vsmp_smp_ops); diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index bab3d41e5987eea7c56af1e08563d65461eb61fb..9e494f8d9c03a13325bc135725ebfec45c01e24c 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -58,7 +58,7 @@ extern void calculate_cpu_foreign_map(void); */ static inline void smp_send_reschedule(int cpu) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF); } @@ -66,14 +66,14 @@ static inline void smp_send_reschedule(int cpu) #ifdef CONFIG_HOTPLUG_CPU static inline int __cpu_disable(void) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ return mp_ops->cpu_disable(); } static inline void __cpu_die(unsigned int cpu) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->cpu_die(cpu); } @@ -97,14 +97,14 @@ int mips_smp_ipi_free(const struct cpumask *mask); static inline void arch_send_call_function_single_ipi(int cpu) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->send_ipi_mask(cpumask_of(cpu), SMP_CALL_FUNCTION); } static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION); } diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index eaa5a4d7d5e572aa91a0e08ab059796a270556bc..5d3563c55e0c224bc62d20815568d61953f9902c 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -19,20 +19,43 @@ #include #include +/* Make the addition of cfi info a little easier. */ + .macro cfi_rel_offset reg offset=0 docfi=0 + .if \docfi + .cfi_rel_offset \reg, \offset + .endif + .endm + + .macro cfi_st reg offset=0 docfi=0 + LONG_S \reg, \offset(sp) + cfi_rel_offset \reg, \offset, \docfi + .endm + + .macro cfi_restore reg offset=0 docfi=0 + .if \docfi + .cfi_restore \reg + .endif + .endm + + .macro cfi_ld reg offset=0 docfi=0 + LONG_L \reg, \offset(sp) + cfi_restore \reg \offset \docfi + .endm + #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) #define STATMASK 0x3f #else #define STATMASK 0x1f #endif - .macro SAVE_AT + .macro SAVE_AT docfi=0 .set push .set noat - LONG_S $1, PT_R1(sp) + cfi_st $1, PT_R1, \docfi .set pop .endm - .macro SAVE_TEMP + .macro SAVE_TEMP docfi=0 #ifdef CONFIG_CPU_HAS_SMARTMIPS mflhxu v1 LONG_S v1, PT_LO(sp) @@ -44,20 +67,20 @@ mfhi v1 #endif #ifdef CONFIG_32BIT - LONG_S $8, PT_R8(sp) - LONG_S $9, PT_R9(sp) + cfi_st $8, PT_R8, \docfi + cfi_st $9, PT_R9, \docfi #endif - LONG_S $10, PT_R10(sp) - LONG_S $11, PT_R11(sp) - LONG_S $12, PT_R12(sp) + cfi_st $10, PT_R10, \docfi + cfi_st $11, PT_R11, \docfi + cfi_st $12, PT_R12, \docfi #if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6) LONG_S v1, PT_HI(sp) mflo v1 #endif - LONG_S $13, PT_R13(sp) - LONG_S $14, PT_R14(sp) - LONG_S $15, PT_R15(sp) - LONG_S $24, PT_R24(sp) + cfi_st $13, PT_R13, \docfi + cfi_st $14, PT_R14, \docfi + cfi_st $15, PT_R15, \docfi + cfi_st $24, PT_R24, \docfi #if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6) LONG_S v1, PT_LO(sp) #endif @@ -71,20 +94,28 @@ #endif .endm - .macro SAVE_STATIC - LONG_S $16, PT_R16(sp) - LONG_S $17, PT_R17(sp) - LONG_S $18, PT_R18(sp) - LONG_S $19, PT_R19(sp) - LONG_S $20, PT_R20(sp) - LONG_S $21, PT_R21(sp) - LONG_S $22, PT_R22(sp) - LONG_S $23, PT_R23(sp) - LONG_S $30, PT_R30(sp) + .macro SAVE_STATIC docfi=0 + cfi_st $16, PT_R16, \docfi + cfi_st $17, PT_R17, \docfi + cfi_st $18, PT_R18, \docfi + cfi_st $19, PT_R19, \docfi + cfi_st $20, PT_R20, \docfi + cfi_st $21, PT_R21, \docfi + cfi_st $22, PT_R22, \docfi + cfi_st $23, PT_R23, \docfi + cfi_st $30, PT_R30, \docfi .endm +/* + * get_saved_sp returns the SP for the current CPU by looking in the + * kernelsp array for it. If tosp is set, it stores the current sp in + * k0 and loads the new value in sp. If not, it clobbers k0 and + * stores the new value in k1, leaving sp unaffected. + */ #ifdef CONFIG_SMP - .macro get_saved_sp /* SMP variation */ + + /* SMP variation */ + .macro get_saved_sp docfi=0 tosp=0 ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) @@ -97,7 +128,15 @@ #endif LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 + .if \tosp + move k0, sp + .if \docfi + .cfi_register sp, k0 + .endif + LONG_L sp, %lo(kernelsp)(k1) + .else LONG_L k1, %lo(kernelsp)(k1) + .endif .endm .macro set_saved_sp stackp temp temp2 @@ -106,7 +145,8 @@ LONG_S \stackp, kernelsp(\temp) .endm #else /* !CONFIG_SMP */ - .macro get_saved_sp /* Uniprocessor variation */ + /* Uniprocessor variation */ + .macro get_saved_sp docfi=0 tosp=0 #ifdef CONFIG_CPU_JUMP_WORKAROUNDS /* * Clear BTB (branch target buffer), forbid RAS (return address @@ -135,7 +175,15 @@ daddiu k1, %hi(kernelsp) dsll k1, k1, 16 #endif + .if \tosp + move k0, sp + .if \docfi + .cfi_register sp, k0 + .endif + LONG_L sp, %lo(kernelsp)(k1) + .else LONG_L k1, %lo(kernelsp)(k1) + .endif .endm .macro set_saved_sp stackp temp temp2 @@ -143,7 +191,7 @@ .endm #endif - .macro SAVE_SOME + .macro SAVE_SOME docfi=0 .set push .set noat .set reorder @@ -151,7 +199,6 @@ sll k0, 3 /* extract cu0 bit */ .set noreorder bltz k0, 8f - move k1, sp #ifdef CONFIG_EVA /* * Flush interAptiv's Return Prediction Stack (RPS) by writing @@ -178,20 +225,26 @@ MTC0 k0, CP0_ENTRYHI #endif .set reorder + move k0, sp + .if \docfi + .cfi_register sp, k0 + .endif /* Called from user mode, new stack. */ - get_saved_sp -#ifndef CONFIG_CPU_DADDI_WORKAROUNDS -8: move k0, sp - PTR_SUBU sp, k1, PT_SIZE -#else - .set at=k0 -8: PTR_SUBU k1, PT_SIZE + get_saved_sp docfi=\docfi tosp=1 +8: +#ifdef CONFIG_CPU_DADDI_WORKAROUNDS + .set at=k1 +#endif + PTR_SUBU sp, PT_SIZE +#ifdef CONFIG_CPU_DADDI_WORKAROUNDS .set noat - move k0, sp - move sp, k1 #endif - LONG_S k0, PT_R29(sp) - LONG_S $3, PT_R3(sp) + .if \docfi + .cfi_def_cfa sp,0 + .endif + cfi_st k0, PT_R29, \docfi + cfi_rel_offset sp, PT_R29, \docfi + cfi_st v1, PT_R3, \docfi /* * You might think that you don't need to save $0, * but the FPU emulator and gdb remote debug stub @@ -199,23 +252,26 @@ */ LONG_S $0, PT_R0(sp) mfc0 v1, CP0_STATUS - LONG_S $2, PT_R2(sp) + cfi_st v0, PT_R2, \docfi LONG_S v1, PT_STATUS(sp) - LONG_S $4, PT_R4(sp) + cfi_st $4, PT_R4, \docfi mfc0 v1, CP0_CAUSE - LONG_S $5, PT_R5(sp) + cfi_st $5, PT_R5, \docfi LONG_S v1, PT_CAUSE(sp) - LONG_S $6, PT_R6(sp) - MFC0 v1, CP0_EPC - LONG_S $7, PT_R7(sp) + cfi_st $6, PT_R6, \docfi + cfi_st ra, PT_R31, \docfi + MFC0 ra, CP0_EPC + cfi_st $7, PT_R7, \docfi #ifdef CONFIG_64BIT - LONG_S $8, PT_R8(sp) - LONG_S $9, PT_R9(sp) + cfi_st $8, PT_R8, \docfi + cfi_st $9, PT_R9, \docfi #endif - LONG_S v1, PT_EPC(sp) - LONG_S $25, PT_R25(sp) - LONG_S $28, PT_R28(sp) - LONG_S $31, PT_R31(sp) + LONG_S ra, PT_EPC(sp) + .if \docfi + .cfi_rel_offset ra, PT_EPC + .endif + cfi_st $25, PT_R25, \docfi + cfi_st $28, PT_R28, \docfi /* Set thread_info if we're coming from user mode */ mfc0 k0, CP0_STATUS @@ -232,21 +288,21 @@ .set pop .endm - .macro SAVE_ALL - SAVE_SOME - SAVE_AT - SAVE_TEMP - SAVE_STATIC + .macro SAVE_ALL docfi=0 + SAVE_SOME \docfi + SAVE_AT \docfi + SAVE_TEMP \docfi + SAVE_STATIC \docfi .endm - .macro RESTORE_AT + .macro RESTORE_AT docfi=0 .set push .set noat - LONG_L $1, PT_R1(sp) + cfi_ld $1, PT_R1, \docfi .set pop .endm - .macro RESTORE_TEMP + .macro RESTORE_TEMP docfi=0 #ifdef CONFIG_CPU_CAVIUM_OCTEON /* Restore the Octeon multiplier state */ jal octeon_mult_restore @@ -265,33 +321,37 @@ mthi $24 #endif #ifdef CONFIG_32BIT - LONG_L $8, PT_R8(sp) - LONG_L $9, PT_R9(sp) + cfi_ld $8, PT_R8, \docfi + cfi_ld $9, PT_R9, \docfi #endif - LONG_L $10, PT_R10(sp) - LONG_L $11, PT_R11(sp) - LONG_L $12, PT_R12(sp) - LONG_L $13, PT_R13(sp) - LONG_L $14, PT_R14(sp) - LONG_L $15, PT_R15(sp) - LONG_L $24, PT_R24(sp) + cfi_ld $10, PT_R10, \docfi + cfi_ld $11, PT_R11, \docfi + cfi_ld $12, PT_R12, \docfi + cfi_ld $13, PT_R13, \docfi + cfi_ld $14, PT_R14, \docfi + cfi_ld $15, PT_R15, \docfi + cfi_ld $24, PT_R24, \docfi .endm - .macro RESTORE_STATIC - LONG_L $16, PT_R16(sp) - LONG_L $17, PT_R17(sp) - LONG_L $18, PT_R18(sp) - LONG_L $19, PT_R19(sp) - LONG_L $20, PT_R20(sp) - LONG_L $21, PT_R21(sp) - LONG_L $22, PT_R22(sp) - LONG_L $23, PT_R23(sp) - LONG_L $30, PT_R30(sp) + .macro RESTORE_STATIC docfi=0 + cfi_ld $16, PT_R16, \docfi + cfi_ld $17, PT_R17, \docfi + cfi_ld $18, PT_R18, \docfi + cfi_ld $19, PT_R19, \docfi + cfi_ld $20, PT_R20, \docfi + cfi_ld $21, PT_R21, \docfi + cfi_ld $22, PT_R22, \docfi + cfi_ld $23, PT_R23, \docfi + cfi_ld $30, PT_R30, \docfi + .endm + + .macro RESTORE_SP docfi=0 + cfi_ld sp, PT_R29, \docfi .endm #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - .macro RESTORE_SOME + .macro RESTORE_SOME docfi=0 .set push .set reorder .set noat @@ -306,30 +366,30 @@ and v0, v1 or v0, a0 mtc0 v0, CP0_STATUS - LONG_L $31, PT_R31(sp) - LONG_L $28, PT_R28(sp) - LONG_L $25, PT_R25(sp) - LONG_L $7, PT_R7(sp) - LONG_L $6, PT_R6(sp) - LONG_L $5, PT_R5(sp) - LONG_L $4, PT_R4(sp) - LONG_L $3, PT_R3(sp) - LONG_L $2, PT_R2(sp) + cfi_ld $31, PT_R31, \docfi + cfi_ld $28, PT_R28, \docfi + cfi_ld $25, PT_R25, \docfi + cfi_ld $7, PT_R7, \docfi + cfi_ld $6, PT_R6, \docfi + cfi_ld $5, PT_R5, \docfi + cfi_ld $4, PT_R4, \docfi + cfi_ld $3, PT_R3, \docfi + cfi_ld $2, PT_R2, \docfi .set pop .endm - .macro RESTORE_SP_AND_RET + .macro RESTORE_SP_AND_RET docfi=0 .set push .set noreorder LONG_L k0, PT_EPC(sp) - LONG_L sp, PT_R29(sp) + RESTORE_SP \docfi jr k0 rfe .set pop .endm #else - .macro RESTORE_SOME + .macro RESTORE_SOME docfi=0 .set push .set reorder .set noat @@ -346,24 +406,24 @@ mtc0 v0, CP0_STATUS LONG_L v1, PT_EPC(sp) MTC0 v1, CP0_EPC - LONG_L $31, PT_R31(sp) - LONG_L $28, PT_R28(sp) - LONG_L $25, PT_R25(sp) + cfi_ld $31, PT_R31, \docfi + cfi_ld $28, PT_R28, \docfi + cfi_ld $25, PT_R25, \docfi #ifdef CONFIG_64BIT - LONG_L $8, PT_R8(sp) - LONG_L $9, PT_R9(sp) + cfi_ld $8, PT_R8, \docfi + cfi_ld $9, PT_R9, \docfi #endif - LONG_L $7, PT_R7(sp) - LONG_L $6, PT_R6(sp) - LONG_L $5, PT_R5(sp) - LONG_L $4, PT_R4(sp) - LONG_L $3, PT_R3(sp) - LONG_L $2, PT_R2(sp) + cfi_ld $7, PT_R7, \docfi + cfi_ld $6, PT_R6, \docfi + cfi_ld $5, PT_R5, \docfi + cfi_ld $4, PT_R4, \docfi + cfi_ld $3, PT_R3, \docfi + cfi_ld $2, PT_R2, \docfi .set pop .endm - .macro RESTORE_SP_AND_RET - LONG_L sp, PT_R29(sp) + .macro RESTORE_SP_AND_RET docfi=0 + RESTORE_SP \docfi #ifdef CONFIG_CPU_MIPSR6 eretnc #else @@ -375,16 +435,12 @@ #endif - .macro RESTORE_SP - LONG_L sp, PT_R29(sp) - .endm - - .macro RESTORE_ALL - RESTORE_TEMP - RESTORE_STATIC - RESTORE_AT - RESTORE_SOME - RESTORE_SP + .macro RESTORE_ALL docfi=0 + RESTORE_TEMP \docfi + RESTORE_STATIC \docfi + RESTORE_AT \docfi + RESTORE_SOME \docfi + RESTORE_SP \docfi .endm /* diff --git a/arch/mips/include/asm/stacktrace.h b/arch/mips/include/asm/stacktrace.h index 780ee2c2a2ac54afb0f4adad265387cfe2285f7d..10c4e9c84448cc098e77f4ecf0aa44bfb5f9b365 100644 --- a/arch/mips/include/asm/stacktrace.h +++ b/arch/mips/include/asm/stacktrace.h @@ -2,6 +2,8 @@ #define _ASM_STACKTRACE_H #include +#include +#include #ifdef CONFIG_KALLSYMS extern int raw_show_trace; @@ -20,6 +22,14 @@ static inline unsigned long unwind_stack(struct task_struct *task, } #endif +#define STR_PTR_LA __stringify(PTR_LA) +#define STR_LONG_S __stringify(LONG_S) +#define STR_LONG_L __stringify(LONG_L) +#define STR_LONGSIZE __stringify(LONGSIZE) + +#define STORE_ONE_REG(r) \ + STR_LONG_S " $" __stringify(r)",("STR_LONGSIZE"*"__stringify(r)")(%1)\n\t" + static __always_inline void prepare_frametrace(struct pt_regs *regs) { #ifndef CONFIG_KALLSYMS @@ -32,21 +42,47 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs) __asm__ __volatile__( ".set push\n\t" ".set noat\n\t" -#ifdef CONFIG_64BIT - "1: dla $1, 1b\n\t" - "sd $1, %0\n\t" - "sd $29, %1\n\t" - "sd $31, %2\n\t" -#else - "1: la $1, 1b\n\t" - "sw $1, %0\n\t" - "sw $29, %1\n\t" - "sw $31, %2\n\t" -#endif + /* Store $1 so we can use it */ + STR_LONG_S " $1,"STR_LONGSIZE"(%1)\n\t" + /* Store the PC */ + "1: " STR_PTR_LA " $1, 1b\n\t" + STR_LONG_S " $1,%0\n\t" + STORE_ONE_REG(2) + STORE_ONE_REG(3) + STORE_ONE_REG(4) + STORE_ONE_REG(5) + STORE_ONE_REG(6) + STORE_ONE_REG(7) + STORE_ONE_REG(8) + STORE_ONE_REG(9) + STORE_ONE_REG(10) + STORE_ONE_REG(11) + STORE_ONE_REG(12) + STORE_ONE_REG(13) + STORE_ONE_REG(14) + STORE_ONE_REG(15) + STORE_ONE_REG(16) + STORE_ONE_REG(17) + STORE_ONE_REG(18) + STORE_ONE_REG(19) + STORE_ONE_REG(20) + STORE_ONE_REG(21) + STORE_ONE_REG(22) + STORE_ONE_REG(23) + STORE_ONE_REG(24) + STORE_ONE_REG(25) + STORE_ONE_REG(26) + STORE_ONE_REG(27) + STORE_ONE_REG(28) + STORE_ONE_REG(29) + STORE_ONE_REG(30) + STORE_ONE_REG(31) + /* Restore $1 */ + STR_LONG_L " $1,"STR_LONGSIZE"(%1)\n\t" ".set pop\n\t" - : "=m" (regs->cp0_epc), - "=m" (regs->regs[29]), "=m" (regs->regs[31]) - : : "memory"); + : "=m" (regs->cp0_epc) + : "r" (regs->regs) + : "memory"); } #endif /* _ASM_STACKTRACE_H */ diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h index 7afda4150a59d928537cddd33e8ed0105d90629b..0673d2d0f2e6dd02ed14d650e5af7b8a3c162b6f 100644 --- a/arch/mips/include/asm/topology.h +++ b/arch/mips/include/asm/topology.h @@ -13,7 +13,7 @@ #ifdef CONFIG_SMP #define topology_physical_package_id(cpu) (cpu_data[cpu].package) -#define topology_core_id(cpu) (cpu_data[cpu].core) +#define topology_core_id(cpu) (cpu_core(&cpu_data[cpu])) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu]) #endif diff --git a/arch/mips/include/asm/vga.h b/arch/mips/include/asm/vga.h index f82c83749a089bf26d5a06846ebd73edcc4130a8..975ff51f80c4d55868f9296c19ce2ef64ceab622 100644 --- a/arch/mips/include/asm/vga.h +++ b/arch/mips/include/asm/vga.h @@ -6,6 +6,7 @@ #ifndef _ASM_VGA_H #define _ASM_VGA_H +#include #include #include @@ -40,9 +41,15 @@ static inline u16 scr_readw(volatile const u16 *addr) return le16_to_cpu(*addr); } +static inline void scr_memsetw(u16 *s, u16 v, unsigned int count) +{ + memset16(s, cpu_to_le16(v), count / 2); +} + #define scr_memcpyw(d, s, c) memcpy(d, s, c) #define scr_memmovew(d, s, c) memmove(d, s, c) #define VT_BUF_HAVE_MEMCPYW #define VT_BUF_HAVE_MEMMOVEW +#define VT_BUF_HAVE_MEMSETW #endif /* _ASM_VGA_H */ diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index d618975359263fd4262de42f3117980175d6533b..6abea5183d7ca160688089cc92741f872de15c4f 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h @@ -981,7 +981,7 @@ struct mm16_r3_format { /* Load from global pointer format */ struct mm16_r5_format { /* Load/store from stack pointer format */ __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, - __BITFIELD_FIELD(signed int simmediate : 5, + __BITFIELD_FIELD(unsigned int imm : 5, __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ ;)))) }; diff --git a/arch/mips/include/uapi/asm/mman.h b/arch/mips/include/uapi/asm/mman.h index 655e2fb5395b5ba4dbfba2df396c9c0c8752eb2e..da3216007fe0ccac2e0695c10b4e1cac1ada8b9d 100644 --- a/arch/mips/include/uapi/asm/mman.h +++ b/arch/mips/include/uapi/asm/mman.h @@ -91,20 +91,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index 8069cf766603ea3e2e5f090bab3e6547a7ac46b6..cf6113bbcb98cfb4edeeb4e052a6452580d9f018 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h @@ -120,7 +120,7 @@ typedef struct siginfo { #undef SI_TIMER #undef SI_MESGQ #define SI_ASYNCIO -2 /* sent by AIO completion */ -#define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */ -#define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */ +#define SI_TIMER -3 /* sent by timer expiration */ +#define SI_MESGQ -4 /* sent by real time mesq state change */ #endif /* _UAPI_ASM_SIGINFO_H */ diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 882823bec153a69e91522757058d5edaeb4bc64a..6c755bc0797513179d3865bd780ea9bab8a199e5 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -120,4 +120,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 46c0581256f1d7d226b7b49f2968966d4d39ed49..07f0f4a4b56236cead0ce920035d45922ccdeea8 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -35,11 +35,15 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o -obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o -obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o -obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o +sw-y := r4k_switch.o +sw-$(CONFIG_CPU_R3000) := r2300_switch.o +sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o +sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o +obj-y += $(sw-y) + +obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o +obj-$(CONFIG_CPU_R3000) += r2300_fpu.o +obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP_UP) += smp-up.o diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index b849fe6aad941bef458f3b3c7ffe1d6f29d46173..d173b49f212daf65701b9b66e9a110745d091150 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S @@ -327,8 +327,8 @@ LEAF(mips_cps_get_bootcfg) * to handle contiguous VP numbering, but no such systems yet * exist. */ - mfc0 t9, $3, 1 - andi t9, t9, 0xff + mfc0 t9, CP0_GLOBALNUMBER + andi t9, t9, MIPS_GLOBALNUMBER_VP #elif defined(CONFIG_MIPS_MT_SMP) has_mt ta2, 1f diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d08afc7dc5072db9c55d4ca056a4422c03ab927e..cf3fd549e16d05a6e666ee8d96e4bde06878c650 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -326,7 +326,7 @@ static int __init fpu_disable(char *s) __setup("nofpu", fpu_disable); -int mips_dsp_disabled; +static int mips_dsp_disabled; static int __init dsp_disable(char *s) { @@ -919,9 +919,12 @@ static void decode_configs(struct cpuinfo_mips *c) #ifndef CONFIG_MIPS_CPS if (cpu_has_mips_r2_r6) { - c->core = get_ebase_cpunum(); + unsigned int core; + + core = get_ebase_cpunum(); if (cpu_has_mipsmt) - c->core >>= fls(core_nvpes()) - 1; + core >>= fls(core_nvpes()) - 1; + cpu_set_core(c, core); } #endif } @@ -1394,24 +1397,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) MIPS_CPU_DIVEC | MIPS_CPU_LLSC; c->tlbsize = 48; break; - case PRID_IMP_R6000: - c->cputype = CPU_R6000; - __cpu_name[cpu] = "R6000"; - set_isa(c, MIPS_CPU_ISA_II); - c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_R6000A: - c->cputype = CPU_R6000A; - __cpu_name[cpu] = "R6000A"; - set_isa(c, MIPS_CPU_ISA_II); - c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; case PRID_IMP_RM7000: c->cputype = CPU_RM7000; __cpu_name[cpu] = "RM7000"; @@ -2113,3 +2098,35 @@ void cpu_report(void) if (cpu_has_msa) pr_info("MSA revision is: %08x\n", c->msa_id); } + +void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster) +{ + /* Ensure the core number fits in the field */ + WARN_ON(cluster > (MIPS_GLOBALNUMBER_CLUSTER >> + MIPS_GLOBALNUMBER_CLUSTER_SHF)); + + cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CLUSTER; + cpuinfo->globalnumber |= cluster << MIPS_GLOBALNUMBER_CLUSTER_SHF; +} + +void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core) +{ + /* Ensure the core number fits in the field */ + WARN_ON(core > (MIPS_GLOBALNUMBER_CORE >> MIPS_GLOBALNUMBER_CORE_SHF)); + + cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CORE; + cpuinfo->globalnumber |= core << MIPS_GLOBALNUMBER_CORE_SHF; +} + +void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe) +{ + /* Ensure the VP(E) ID fits in the field */ + WARN_ON(vpe > (MIPS_GLOBALNUMBER_VP >> MIPS_GLOBALNUMBER_VP_SHF)); + + /* Ensure we're not using VP(E)s without support */ + WARN_ON(vpe && !IS_ENABLED(CONFIG_MIPS_MT_SMP) && + !IS_ENABLED(CONFIG_CPU_MIPSR6)); + + cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP; + cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF; +} diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 5c429d70e17f6f24cbcfd0fa912c67eccd11f28f..0828d6d963b7294291203500caa95592d962981c 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -87,6 +87,7 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, bool elf32; u32 flags; int ret; + loff_t pos; elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags; @@ -108,21 +109,16 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, if (phdr32->p_filesz < sizeof(abiflags)) return -EINVAL; - - ret = kernel_read(elf, phdr32->p_offset, - (char *)&abiflags, - sizeof(abiflags)); + pos = phdr32->p_offset; } else { if (phdr64->p_type != PT_MIPS_ABIFLAGS) return 0; if (phdr64->p_filesz < sizeof(abiflags)) return -EINVAL; - - ret = kernel_read(elf, phdr64->p_offset, - (char *)&abiflags, - sizeof(abiflags)); + pos = phdr64->p_offset; } + ret = kernel_read(elf, &abiflags, sizeof(abiflags), &pos); if (ret < 0) return ret; if (ret != sizeof(abiflags)) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index ae810da4d499e6282638d8edadb722078b5f04cb..37b9383eacd3e84872b1d2d7d1361cf1b637522f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -150,6 +150,7 @@ LEAF(__r4k_wait) .align 5 BUILD_ROLLBACK_PROLOGUE handle_int NESTED(handle_int, PT_SIZE, sp) + .cfi_signal_frame #ifdef CONFIG_TRACE_IRQFLAGS /* * Check to see if the interrupted code has just disabled @@ -181,7 +182,7 @@ NESTED(handle_int, PT_SIZE, sp) 1: .set pop #endif - SAVE_ALL + SAVE_ALL docfi=1 CLI TRACE_IRQS_OFF @@ -269,8 +270,8 @@ NESTED(except_vec_ejtag_debug, 0, sp) */ BUILD_ROLLBACK_PROLOGUE except_vec_vi NESTED(except_vec_vi, 0, sp) - SAVE_SOME - SAVE_AT + SAVE_SOME docfi=1 + SAVE_AT docfi=1 .set push .set noreorder PTR_LA v1, except_vec_vi_handler @@ -396,6 +397,7 @@ NESTED(except_vec_nmi, 0, sp) __FINIT NESTED(nmi_handler, PT_SIZE, sp) + .cfi_signal_frame .set push .set noat /* @@ -478,6 +480,7 @@ NESTED(nmi_handler, PT_SIZE, sp) .macro __BUILD_HANDLER exception handler clear verbose ext .align 5 NESTED(handle_\exception, PT_SIZE, sp) + .cfi_signal_frame .set noat SAVE_ALL FEXPORT(handle_\exception\ext) @@ -485,8 +488,8 @@ NESTED(nmi_handler, PT_SIZE, sp) .set at __BUILD_\verbose \exception move a0, sp - PTR_LA ra, ret_from_exception - j do_\handler + jal do_\handler + j ret_from_exception END(handle_\exception) .endm diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 60ab4c44d30557b285a90cc28e7b8ae1dd2ca21a..7c246b69c5458344fb1dc7b03c79d54fef53f528 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include #include #include #include diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index cb0c57f860d468fab42cc60aefc80c1c1efe161a..e91c8c4e2eb59e69c76c516bd3fbc99f23f21c8b 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -12,10 +12,10 @@ #include #include -#include +#include #include -void __iomem *mips_cm_base; +void __iomem *mips_gcr_base; void __iomem *mips_cm_l2sync_base; int mips_cm_is64; @@ -167,8 +167,8 @@ phys_addr_t __mips_cm_l2sync_phys_base(void) * current location. */ base_reg = read_gcr_l2_only_sync_base(); - if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK) - return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK; + if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN) + return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE; /* Default to following the CM */ return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; @@ -183,19 +183,19 @@ static void mips_cm_probe_l2sync(void) phys_addr_t addr; /* L2-only sync was introduced with CM major revision 6 */ - major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> - CM_GCR_REV_MAJOR_SHF; + major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >> + __ffs(CM_GCR_REV_MAJOR); if (major_rev < 6) return; /* Find a location for the L2 sync region */ addr = mips_cm_l2sync_phys_base(); - BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK) != addr); + BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE) != addr); if (!addr) return; /* Set the region base address & enable it */ - write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK); + write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN); /* Map the region */ mips_cm_l2sync_base = ioremap_nocache(addr, MIPS_CM_L2SYNC_SIZE); @@ -211,41 +211,39 @@ int mips_cm_probe(void) * No need to probe again if we have already been * here before. */ - if (mips_cm_base) + if (mips_gcr_base) return 0; addr = mips_cm_phys_base(); - BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr); + BUG_ON((addr & CM_GCR_BASE_GCRBASE) != addr); if (!addr) return -ENODEV; - mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE); - if (!mips_cm_base) + mips_gcr_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE); + if (!mips_gcr_base) return -ENXIO; /* sanity check that we're looking at a CM */ base_reg = read_gcr_base(); - if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) { + if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) { pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n", (unsigned long)addr); - mips_cm_base = NULL; + mips_gcr_base = NULL; return -ENODEV; } /* set default target to memory */ - base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK; - base_reg |= CM_GCR_BASE_CMDEFTGT_MEM; - write_gcr_base(base_reg); + change_gcr_base(CM_GCR_BASE_CMDEFTGT, CM_GCR_BASE_CMDEFTGT_MEM); /* disable CM regions */ - write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); - write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); - write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); - write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); + write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK); + write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK); + write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK); + write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK); /* probe for an L2-only sync region */ mips_cm_probe_l2sync(); @@ -259,16 +257,27 @@ int mips_cm_probe(void) return 0; } -void mips_cm_lock_other(unsigned int core, unsigned int vp) +void mips_cm_lock_other(unsigned int cluster, unsigned int core, + unsigned int vp, unsigned int block) { - unsigned curr_core; + unsigned int curr_core, cm_rev; u32 val; + cm_rev = mips_cm_revision(); preempt_disable(); - if (mips_cm_revision() >= CM_REV_CM3) { - val = core << CM3_GCR_Cx_OTHER_CORE_SHF; - val |= vp << CM3_GCR_Cx_OTHER_VP_SHF; + if (cm_rev >= CM_REV_CM3) { + val = core << __ffs(CM3_GCR_Cx_OTHER_CORE); + val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP); + + if (cm_rev >= CM_REV_CM3_5) { + val |= CM_GCR_Cx_OTHER_CLUSTER_EN; + val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER); + val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK); + } else { + WARN_ON(cluster != 0); + WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); + } /* * We need to disable interrupts in SMP systems in order to @@ -282,18 +291,20 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp) spin_lock_irqsave(this_cpu_ptr(&cm_core_lock), *this_cpu_ptr(&cm_core_lock_flags)); } else { + WARN_ON(cluster != 0); WARN_ON(vp != 0); + WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); /* * We only have a GCR_CL_OTHER per core in systems with * CM 2.5 & older, so have to ensure other VP(E)s don't * race with us. */ - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); - val = core << CM_GCR_Cx_OTHER_CORENUM_SHF; + val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM); } write_gcr_cl_other(val); @@ -310,7 +321,7 @@ void mips_cm_unlock_other(void) unsigned int curr_core; if (mips_cm_revision() < CM_REV_CM3) { - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); } else { @@ -332,13 +343,13 @@ void mips_cm_error_report(void) return; revision = mips_cm_revision(); + cm_error = read_gcr_error_cause(); + cm_addr = read_gcr_error_addr(); + cm_other = read_gcr_error_mult(); if (revision < CM_REV_CM3) { /* CM2 */ - cm_error = read_gcr_error_cause(); - cm_addr = read_gcr_error_addr(); - cm_other = read_gcr_error_mult(); - cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF; - ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; + cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE); + ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); if (!cause) return; @@ -380,11 +391,8 @@ void mips_cm_error_report(void) ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit; - cm_error = read64_gcr_error_cause(); - cm_addr = read64_gcr_error_addr(); - cm_other = read64_gcr_error_mult(); - cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF; - ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; + cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE); + ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); if (!cause) return; diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index a4964c334cab66eba2e41e34c25db281a1729555..f66b05ebf637d4c6542df58c4d510e16b88a2b8c 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -12,8 +12,7 @@ #include #include -#include -#include +#include void __iomem *mips_cpc_base; @@ -40,13 +39,13 @@ static phys_addr_t mips_cpc_phys_base(void) if (!mips_cm_present()) return 0; - if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX_MSK)) + if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX)) return 0; /* If the CPC is already enabled, leave it so */ cpc_base = read_gcr_cpc_base(); - if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK) - return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK; + if (cpc_base & CM_GCR_CPC_BASE_CPCEN) + return cpc_base & CM_GCR_CPC_BASE_CPCBASE; /* Otherwise, use the default address */ cpc_base = mips_cpc_default_phys_base(); @@ -54,7 +53,7 @@ static phys_addr_t mips_cpc_phys_base(void) return cpc_base; /* Enable the CPC, mapped at the default address */ - write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK); + write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN); return cpc_base; } @@ -86,10 +85,10 @@ void mips_cpc_lock_other(unsigned int core) return; preempt_disable(); - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); - write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF); + write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM)); /* * Ensure the core-other region reflects the appropriate core & @@ -106,7 +105,7 @@ void mips_cpc_unlock_other(void) /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ return; - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); preempt_enable(); diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index ae64c8f56a8c788450876bd368bc6dba8cab54a7..eb18b186e858c6bec7113785beca3a8a905fdb0e 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -46,9 +46,11 @@ #define LL "ll " #define SC "sc " -DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); -DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); -DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); +#ifdef CONFIG_DEBUG_FS +static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); +static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); +static DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); +#endif extern const unsigned int fpucondbit[8]; @@ -600,7 +602,7 @@ static int ddivu_func(struct pt_regs *regs, u32 ir) } /* R6 removed instructions for the SPECIAL opcode */ -static struct r2_decoder_table spec_op_table[] = { +static const struct r2_decoder_table spec_op_table[] = { { 0xfc1ff83f, 0x00000008, jr_func }, { 0xfc00ffff, 0x00000018, mult_func }, { 0xfc00ffff, 0x00000019, multu_func }, @@ -867,7 +869,7 @@ static int dclo_func(struct pt_regs *regs, u32 ir) } /* R6 removed instructions for the SPECIAL2 opcode */ -static struct r2_decoder_table spec2_op_table[] = { +static const struct r2_decoder_table spec2_op_table[] = { { 0xfc00ffff, 0x70000000, madd_func }, { 0xfc00ffff, 0x70000001, maddu_func }, { 0xfc0007ff, 0x70000002, mul_func }, @@ -881,9 +883,9 @@ static struct r2_decoder_table spec2_op_table[] = { }; static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst, - struct r2_decoder_table *table) + const struct r2_decoder_table *table) { - struct r2_decoder_table *p; + const struct r2_decoder_table *p; int err; for (p = table; p->func; p++) { diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index 3375745b91980013d76ad2e7d9cd632d31b26af9..e42113fe2762b5e8298f40a64d0d635799334d5d 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -10,12 +10,13 @@ * Copyright (C) 2000 MIPS Technologies, Inc. * written by Carsten Langgaard, carstenl@mips.com */ +#include +#include +#include +#include +#include +#include -#define USE_ALTERNATE_RESUME_IMPL 1 - .set push - .set arch=mips64r2 -#include "r4k_switch.S" - .set pop /* * task_struct *resume(task_struct *prev, task_struct *next, * struct thread_info *next_ti) diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 9e6c74bf66c485cc3c1a23ee1d298c1b6f81dad5..6668f67a61c3a2bb09fc23d9e2172d7a738020e1 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -618,8 +618,7 @@ static int mipspmu_event_init(struct perf_event *event) return -ENOENT; } - if ((unsigned int)event->cpu >= nr_cpumask_bits || - (event->cpu >= 0 && !cpu_online(event->cpu))) + if (event->cpu >= 0 && !cpu_online(event->cpu)) return -ENODEV; if (!atomic_inc_not_zero(&active_events)) { diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index d99416094ba964a356bfdf83946ac945f9d600d5..4655017f2377d0246cc5c9604eba39bbc98366c2 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -49,7 +48,7 @@ static DEFINE_PER_CPU_READ_MOSTLY(cps_nc_entry_fn[CPS_PM_STATE_COUNT], nc_asm_enter); /* Bitmap indicating which states are supported by the system */ -DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT); +static DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT); /* * Indicates the number of coupled VPEs ready to operate in a non-coherent @@ -114,7 +113,7 @@ static void coupled_barrier(atomic_t *a, unsigned online) int cps_pm_enter_state(enum cps_pm_state state) { unsigned cpu = smp_processor_id(); - unsigned core = current_cpu_data.core; + unsigned core = cpu_core(¤t_cpu_data); unsigned online, left; cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled); u32 *core_ready_count, *nc_core_ready_count; @@ -486,7 +485,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * defined by the interAptiv & proAptiv SUMs as ensuring that the * operation resulting from the preceding store is complete. */ - uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); + uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu])); uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); @@ -569,8 +568,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * rest will just be performing a rather unusual nop. */ uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3 - ? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK - : CM3_GCR_Cx_COHERENCE_COHEN_MSK); + ? CM_GCR_Cx_COHERENCE_COHDOMAINEN + : CM3_GCR_Cx_COHERENCE_COHEN); uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); @@ -640,7 +639,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) static int cps_pm_online_cpu(unsigned int cpu) { enum cps_pm_state state; - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); void *entry_fn, *core_rc; for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) { @@ -692,7 +691,7 @@ static int __init cps_pm_init(void) /* Detect whether a CPC is present */ if (mips_cpc_present()) { /* Detect whether clock gating is implemented */ - if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK) + if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL) set_bit(CPS_PM_CLOCK_GATED, state_support); else pr_warn("pm-cps: CPC does not support clock gating\n"); diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 70604c753aa4e3175087193fb74d2a65a07f098d..bd9bf528f19bae31896568ce00c5b41c1694af14 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -134,13 +134,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "kscratch registers\t: %d\n", hweight8(cpu_data[n].kscratch_mask)); seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); - seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); + seq_printf(m, "core\t\t\t: %d\n", cpu_core(&cpu_data[n])); #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) if (cpu_has_mipsmt) - seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); + seq_printf(m, "VPE\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n])); else if (cpu_has_vp) - seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id); + seq_printf(m, "VP\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n])); #endif sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 5351e1f3950d158aaa5ff2590c32734862a79834..c5ff6bfe2825b95bdbf5042ed636ac71b3820615 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -208,13 +208,13 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff) * * microMIPS is way more fun... */ - if (mm_insn_16bit(ip->halfword[1])) { + if (mm_insn_16bit(ip->word >> 16)) { switch (ip->mm16_r5_format.opcode) { case mm_swsp16_op: if (ip->mm16_r5_format.rt != 31) return 0; - *poff = ip->mm16_r5_format.simmediate; + *poff = ip->mm16_r5_format.imm; *poff = (*poff << 2) / sizeof(ulong); return 1; @@ -287,7 +287,7 @@ static inline int is_jump_ins(union mips_instruction *ip) * * microMIPS is kind of more fun... */ - if (mm_insn_16bit(ip->halfword[1])) { + if (mm_insn_16bit(ip->word >> 16)) { if ((ip->mm16_r5_format.opcode == mm_pool16c_op && (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op)) return 1; @@ -313,9 +313,11 @@ static inline int is_jump_ins(union mips_instruction *ip) #endif } -static inline int is_sp_move_ins(union mips_instruction *ip) +static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size) { #ifdef CONFIG_CPU_MICROMIPS + unsigned short tmp; + /* * addiusp -imm * addius5 sp,-imm @@ -324,21 +326,40 @@ static inline int is_sp_move_ins(union mips_instruction *ip) * * microMIPS is not more fun... */ - if (mm_insn_16bit(ip->halfword[1])) { - return (ip->mm16_r3_format.opcode == mm_pool16d_op && - ip->mm16_r3_format.simmediate && mm_addiusp_func) || - (ip->mm16_r5_format.opcode == mm_pool16d_op && - ip->mm16_r5_format.rt == 29); + if (mm_insn_16bit(ip->word >> 16)) { + if (ip->mm16_r3_format.opcode == mm_pool16d_op && + ip->mm16_r3_format.simmediate & mm_addiusp_func) { + tmp = ip->mm_b0_format.simmediate >> 1; + tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100; + if ((tmp + 2) < 4) /* 0x0,0x1,0x1fe,0x1ff are special */ + tmp ^= 0x100; + *frame_size = -(signed short)(tmp << 2); + return 1; + } + if (ip->mm16_r5_format.opcode == mm_pool16d_op && + ip->mm16_r5_format.rt == 29) { + tmp = ip->mm16_r5_format.imm >> 1; + *frame_size = -(signed short)(tmp & 0xf); + return 1; + } + return 0; } - return ip->mm_i_format.opcode == mm_addiu32_op && - ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; + if (ip->mm_i_format.opcode == mm_addiu32_op && + ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29) { + *frame_size = -ip->i_format.simmediate; + return 1; + } #else /* addiu/daddiu sp,sp,-imm */ if (ip->i_format.rs != 29 || ip->i_format.rt != 29) return 0; - if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) + + if (ip->i_format.opcode == addiu_op || + ip->i_format.opcode == daddiu_op) { + *frame_size = -ip->i_format.simmediate; return 1; + } #endif return 0; } @@ -348,7 +369,9 @@ static int get_frame_info(struct mips_frame_info *info) bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); union mips_instruction insn, *ip, *ip_end; const unsigned int max_insns = 128; + unsigned int last_insn_size = 0; unsigned int i; + bool saw_jump = false; info->pc_offset = -1; info->frame_size = 0; @@ -359,47 +382,44 @@ static int get_frame_info(struct mips_frame_info *info) ip_end = (void *)ip + info->func_size; - for (i = 0; i < max_insns && ip < ip_end; i++, ip++) { + for (i = 0; i < max_insns && ip < ip_end; i++) { + ip = (void *)ip + last_insn_size; if (is_mmips && mm_insn_16bit(ip->halfword[0])) { - insn.halfword[0] = 0; - insn.halfword[1] = ip->halfword[0]; + insn.word = ip->halfword[0] << 16; + last_insn_size = 2; } else if (is_mmips) { - insn.halfword[0] = ip->halfword[1]; - insn.halfword[1] = ip->halfword[0]; + insn.word = ip->halfword[0] << 16 | ip->halfword[1]; + last_insn_size = 4; } else { insn.word = ip->word; + last_insn_size = 4; } - if (is_jump_ins(&insn)) - break; - if (!info->frame_size) { - if (is_sp_move_ins(&insn)) - { -#ifdef CONFIG_CPU_MICROMIPS - if (mm_insn_16bit(ip->halfword[0])) - { - unsigned short tmp; - - if (ip->halfword[0] & mm_addiusp_func) - { - tmp = (((ip->halfword[0] >> 1) & 0x1ff) << 2); - info->frame_size = -(signed short)(tmp | ((tmp & 0x100) ? 0xfe00 : 0)); - } else { - tmp = (ip->halfword[0] >> 1); - info->frame_size = -(signed short)(tmp & 0xf); - } - ip = (void *) &ip->halfword[1]; - ip--; - } else -#endif - info->frame_size = - ip->i_format.simmediate; - } + is_sp_move_ins(&insn, &info->frame_size); + continue; + } else if (!saw_jump && is_jump_ins(ip)) { + /* + * If we see a jump instruction, we are finished + * with the frame save. + * + * Some functions can have a shortcut return at + * the beginning of the function, so don't start + * looking for jump instruction until we see the + * frame setup. + * + * The RA save instruction can get put into the + * delay slot of the jump instruction, so look + * at the next instruction, too. + */ + saw_jump = true; continue; } if (info->pc_offset == -1 && is_ra_save_ins(&insn, &info->pc_offset)) break; + if (saw_jump) + break; } if (info->frame_size && info->pc_offset >= 0) /* nested */ return 0; diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 6dd13641a4188e2a977592a3a0ed5e964bca064b..1395654cfc8d833b62ded894af5639cc696367c5 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -872,15 +872,13 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) if (unlikely(test_thread_flag(TIF_SECCOMP))) { int ret, i; struct seccomp_data sd; + unsigned long args[6]; sd.nr = syscall; sd.arch = syscall_get_arch(); - for (i = 0; i < 6; i++) { - unsigned long v, r; - - r = mips_get_syscall_arg(&v, current, regs, i); - sd.args[i] = r ? 0 : v; - } + syscall_get_arguments(current, regs, 0, 6, args); + for (i = 0; i < 6; i++) + sd.args[i] = args[i]; sd.instruction_pointer = KSTK_EIP(current); ret = __secure_computing(&sd); diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S index 918f2f6d3861a87dccc85f5256bf9b89cc1d56d3..3062ba66c563549010d02682118807abb34f41f4 100644 --- a/arch/mips/kernel/r2300_fpu.S +++ b/arch/mips/kernel/r2300_fpu.S @@ -12,7 +12,9 @@ * Copyright (c) 1998 Harald Koerfgen */ #include +#include #include +#include #include #include #include @@ -31,9 +33,85 @@ PTR 9b+4,bad_stack; \ .previous - .set noreorder .set mips1 +/* + * Save a thread's fp context. + */ +LEAF(_save_fp) +EXPORT_SYMBOL(_save_fp) + fpu_save_single a0, t1 # clobbers t1 + jr ra + END(_save_fp) + +/* + * Restore a thread's fp context. + */ +LEAF(_restore_fp) + fpu_restore_single a0, t1 # clobbers t1 + jr ra + END(_restore_fp) + +/* + * Load the FPU with signalling NANS. This bit pattern we're using has + * the property that no matter whether considered as single or as double + * precision represents signaling NANS. + * + * The value to initialize fcr31 to comes in $a0. + */ + + .set push + SET_HARDFLOAT + +LEAF(_init_fpu) + mfc0 t0, CP0_STATUS + li t1, ST0_CU1 + or t0, t1 + mtc0 t0, CP0_STATUS + + ctc1 a0, fcr31 + + li t0, -1 + + mtc1 t0, $f0 + mtc1 t0, $f1 + mtc1 t0, $f2 + mtc1 t0, $f3 + mtc1 t0, $f4 + mtc1 t0, $f5 + mtc1 t0, $f6 + mtc1 t0, $f7 + mtc1 t0, $f8 + mtc1 t0, $f9 + mtc1 t0, $f10 + mtc1 t0, $f11 + mtc1 t0, $f12 + mtc1 t0, $f13 + mtc1 t0, $f14 + mtc1 t0, $f15 + mtc1 t0, $f16 + mtc1 t0, $f17 + mtc1 t0, $f18 + mtc1 t0, $f19 + mtc1 t0, $f20 + mtc1 t0, $f21 + mtc1 t0, $f22 + mtc1 t0, $f23 + mtc1 t0, $f24 + mtc1 t0, $f25 + mtc1 t0, $f26 + mtc1 t0, $f27 + mtc1 t0, $f28 + mtc1 t0, $f29 + mtc1 t0, $f30 + mtc1 t0, $f31 + jr ra + END(_init_fpu) + + .set pop + + .set noreorder + /** * _save_fp_context() - save FP context from the FPU * @a0 - pointer to fpregs field of sigcontext diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 1049eeafd97d79ac8198e2666987b69f2deb36ba..e57703b1de50264814ce3a96483721b2556c77b2 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -25,12 +25,6 @@ .set mips1 .align 5 -/* - * Offset to the current process status flags, the first 32 bytes of the - * stack are not used. - */ -#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS) - /* * task_struct *resume(task_struct *prev, task_struct *next, * struct thread_info *next_ti) @@ -68,78 +62,3 @@ LEAF(resume) move v0, a0 jr ra END(resume) - -/* - * Save a thread's fp context. - */ -LEAF(_save_fp) -EXPORT_SYMBOL(_save_fp) - fpu_save_single a0, t1 # clobbers t1 - jr ra - END(_save_fp) - -/* - * Restore a thread's fp context. - */ -LEAF(_restore_fp) - fpu_restore_single a0, t1 # clobbers t1 - jr ra - END(_restore_fp) - -/* - * Load the FPU with signalling NANS. This bit pattern we're using has - * the property that no matter whether considered as single or as double - * precision represents signaling NANS. - * - * The value to initialize fcr31 to comes in $a0. - */ - - .set push - SET_HARDFLOAT - -LEAF(_init_fpu) - mfc0 t0, CP0_STATUS - li t1, ST0_CU1 - or t0, t1 - mtc0 t0, CP0_STATUS - - ctc1 a0, fcr31 - - li t0, -1 - - mtc1 t0, $f0 - mtc1 t0, $f1 - mtc1 t0, $f2 - mtc1 t0, $f3 - mtc1 t0, $f4 - mtc1 t0, $f5 - mtc1 t0, $f6 - mtc1 t0, $f7 - mtc1 t0, $f8 - mtc1 t0, $f9 - mtc1 t0, $f10 - mtc1 t0, $f11 - mtc1 t0, $f12 - mtc1 t0, $f13 - mtc1 t0, $f14 - mtc1 t0, $f15 - mtc1 t0, $f16 - mtc1 t0, $f17 - mtc1 t0, $f18 - mtc1 t0, $f19 - mtc1 t0, $f20 - mtc1 t0, $f21 - mtc1 t0, $f22 - mtc1 t0, $f23 - mtc1 t0, $f24 - mtc1 t0, $f25 - mtc1 t0, $f26 - mtc1 t0, $f27 - mtc1 t0, $f28 - mtc1 t0, $f29 - mtc1 t0, $f30 - mtc1 t0, $f31 - jr ra - END(_init_fpu) - - .set pop diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 56d86b09c917b0de80efca96ac357ef3e8a63c7e..0a83b1708b3cbed5bba0f4781107122cc0c77569 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,201 @@ .previous .endm +/* + * Save a thread's fp context. + */ +LEAF(_save_fp) +EXPORT_SYMBOL(_save_fp) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ + defined(CONFIG_CPU_MIPS32_R6) + mfc0 t0, CP0_STATUS +#endif + fpu_save_double a0 t0 t1 # clobbers t1 + jr ra + END(_save_fp) + +/* + * Restore a thread's fp context. + */ +LEAF(_restore_fp) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ + defined(CONFIG_CPU_MIPS32_R6) + mfc0 t0, CP0_STATUS +#endif + fpu_restore_double a0 t0 t1 # clobbers t1 + jr ra + END(_restore_fp) + +#ifdef CONFIG_CPU_HAS_MSA + +/* + * Save a thread's MSA vector context. + */ +LEAF(_save_msa) +EXPORT_SYMBOL(_save_msa) + msa_save_all a0 + jr ra + END(_save_msa) + +/* + * Restore a thread's MSA vector context. + */ +LEAF(_restore_msa) + msa_restore_all a0 + jr ra + END(_restore_msa) + +LEAF(_init_msa_upper) + msa_init_all_upper + jr ra + END(_init_msa_upper) + +#endif + +/* + * Load the FPU with signalling NANS. This bit pattern we're using has + * the property that no matter whether considered as single or as double + * precision represents signaling NANS. + * + * The value to initialize fcr31 to comes in $a0. + */ + + .set push + SET_HARDFLOAT + +LEAF(_init_fpu) + mfc0 t0, CP0_STATUS + li t1, ST0_CU1 + or t0, t1 + mtc0 t0, CP0_STATUS + enable_fpu_hazard + + ctc1 a0, fcr31 + + li t1, -1 # SNaN + +#ifdef CONFIG_64BIT + sll t0, t0, 5 + bgez t0, 1f # 16 / 32 register mode? + + dmtc1 t1, $f1 + dmtc1 t1, $f3 + dmtc1 t1, $f5 + dmtc1 t1, $f7 + dmtc1 t1, $f9 + dmtc1 t1, $f11 + dmtc1 t1, $f13 + dmtc1 t1, $f15 + dmtc1 t1, $f17 + dmtc1 t1, $f19 + dmtc1 t1, $f21 + dmtc1 t1, $f23 + dmtc1 t1, $f25 + dmtc1 t1, $f27 + dmtc1 t1, $f29 + dmtc1 t1, $f31 +1: +#endif + +#ifdef CONFIG_CPU_MIPS32 + mtc1 t1, $f0 + mtc1 t1, $f1 + mtc1 t1, $f2 + mtc1 t1, $f3 + mtc1 t1, $f4 + mtc1 t1, $f5 + mtc1 t1, $f6 + mtc1 t1, $f7 + mtc1 t1, $f8 + mtc1 t1, $f9 + mtc1 t1, $f10 + mtc1 t1, $f11 + mtc1 t1, $f12 + mtc1 t1, $f13 + mtc1 t1, $f14 + mtc1 t1, $f15 + mtc1 t1, $f16 + mtc1 t1, $f17 + mtc1 t1, $f18 + mtc1 t1, $f19 + mtc1 t1, $f20 + mtc1 t1, $f21 + mtc1 t1, $f22 + mtc1 t1, $f23 + mtc1 t1, $f24 + mtc1 t1, $f25 + mtc1 t1, $f26 + mtc1 t1, $f27 + mtc1 t1, $f28 + mtc1 t1, $f29 + mtc1 t1, $f30 + mtc1 t1, $f31 + +#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6) + .set push + .set MIPS_ISA_LEVEL_RAW + .set fp=64 + sll t0, t0, 5 # is Status.FR set? + bgez t0, 1f # no: skip setting upper 32b + + mthc1 t1, $f0 + mthc1 t1, $f1 + mthc1 t1, $f2 + mthc1 t1, $f3 + mthc1 t1, $f4 + mthc1 t1, $f5 + mthc1 t1, $f6 + mthc1 t1, $f7 + mthc1 t1, $f8 + mthc1 t1, $f9 + mthc1 t1, $f10 + mthc1 t1, $f11 + mthc1 t1, $f12 + mthc1 t1, $f13 + mthc1 t1, $f14 + mthc1 t1, $f15 + mthc1 t1, $f16 + mthc1 t1, $f17 + mthc1 t1, $f18 + mthc1 t1, $f19 + mthc1 t1, $f20 + mthc1 t1, $f21 + mthc1 t1, $f22 + mthc1 t1, $f23 + mthc1 t1, $f24 + mthc1 t1, $f25 + mthc1 t1, $f26 + mthc1 t1, $f27 + mthc1 t1, $f28 + mthc1 t1, $f29 + mthc1 t1, $f30 + mthc1 t1, $f31 +1: .set pop +#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */ +#else + .set MIPS_ISA_ARCH_LEVEL_RAW + dmtc1 t1, $f0 + dmtc1 t1, $f2 + dmtc1 t1, $f4 + dmtc1 t1, $f6 + dmtc1 t1, $f8 + dmtc1 t1, $f10 + dmtc1 t1, $f12 + dmtc1 t1, $f14 + dmtc1 t1, $f16 + dmtc1 t1, $f18 + dmtc1 t1, $f20 + dmtc1 t1, $f22 + dmtc1 t1, $f24 + dmtc1 t1, $f26 + dmtc1 t1, $f28 + dmtc1 t1, $f30 +#endif + jr ra + END(_init_fpu) + + .set pop /* SET_HARDFLOAT */ + .set noreorder /** diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 7b386d54fd656cd6a2789fe79a72466ee8b0695b..17cf9341c1cf0c1ad34dc0362b85ee550a82f9ca 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -12,8 +12,6 @@ */ #include #include -#include -#include #include #include #include @@ -22,10 +20,6 @@ #include -/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ -#undef fp - -#ifndef USE_ALTERNATE_RESUME_IMPL /* * task_struct *resume(task_struct *prev, task_struct *next, * struct thread_info *next_ti) @@ -63,200 +57,3 @@ move v0, a0 jr ra END(resume) - -#endif /* USE_ALTERNATE_RESUME_IMPL */ - -/* - * Save a thread's fp context. - */ -LEAF(_save_fp) -EXPORT_SYMBOL(_save_fp) -#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ - defined(CONFIG_CPU_MIPS32_R6) - mfc0 t0, CP0_STATUS -#endif - fpu_save_double a0 t0 t1 # clobbers t1 - jr ra - END(_save_fp) - -/* - * Restore a thread's fp context. - */ -LEAF(_restore_fp) -#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ - defined(CONFIG_CPU_MIPS32_R6) - mfc0 t0, CP0_STATUS -#endif - fpu_restore_double a0 t0 t1 # clobbers t1 - jr ra - END(_restore_fp) - -#ifdef CONFIG_CPU_HAS_MSA - -/* - * Save a thread's MSA vector context. - */ -LEAF(_save_msa) -EXPORT_SYMBOL(_save_msa) - msa_save_all a0 - jr ra - END(_save_msa) - -/* - * Restore a thread's MSA vector context. - */ -LEAF(_restore_msa) - msa_restore_all a0 - jr ra - END(_restore_msa) - -LEAF(_init_msa_upper) - msa_init_all_upper - jr ra - END(_init_msa_upper) - -#endif - -/* - * Load the FPU with signalling NANS. This bit pattern we're using has - * the property that no matter whether considered as single or as double - * precision represents signaling NANS. - * - * The value to initialize fcr31 to comes in $a0. - */ - - .set push - SET_HARDFLOAT - -LEAF(_init_fpu) - mfc0 t0, CP0_STATUS - li t1, ST0_CU1 - or t0, t1 - mtc0 t0, CP0_STATUS - enable_fpu_hazard - - ctc1 a0, fcr31 - - li t1, -1 # SNaN - -#ifdef CONFIG_64BIT - sll t0, t0, 5 - bgez t0, 1f # 16 / 32 register mode? - - dmtc1 t1, $f1 - dmtc1 t1, $f3 - dmtc1 t1, $f5 - dmtc1 t1, $f7 - dmtc1 t1, $f9 - dmtc1 t1, $f11 - dmtc1 t1, $f13 - dmtc1 t1, $f15 - dmtc1 t1, $f17 - dmtc1 t1, $f19 - dmtc1 t1, $f21 - dmtc1 t1, $f23 - dmtc1 t1, $f25 - dmtc1 t1, $f27 - dmtc1 t1, $f29 - dmtc1 t1, $f31 -1: -#endif - -#ifdef CONFIG_CPU_MIPS32 - mtc1 t1, $f0 - mtc1 t1, $f1 - mtc1 t1, $f2 - mtc1 t1, $f3 - mtc1 t1, $f4 - mtc1 t1, $f5 - mtc1 t1, $f6 - mtc1 t1, $f7 - mtc1 t1, $f8 - mtc1 t1, $f9 - mtc1 t1, $f10 - mtc1 t1, $f11 - mtc1 t1, $f12 - mtc1 t1, $f13 - mtc1 t1, $f14 - mtc1 t1, $f15 - mtc1 t1, $f16 - mtc1 t1, $f17 - mtc1 t1, $f18 - mtc1 t1, $f19 - mtc1 t1, $f20 - mtc1 t1, $f21 - mtc1 t1, $f22 - mtc1 t1, $f23 - mtc1 t1, $f24 - mtc1 t1, $f25 - mtc1 t1, $f26 - mtc1 t1, $f27 - mtc1 t1, $f28 - mtc1 t1, $f29 - mtc1 t1, $f30 - mtc1 t1, $f31 - -#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6) - .set push - .set MIPS_ISA_LEVEL_RAW - .set fp=64 - sll t0, t0, 5 # is Status.FR set? - bgez t0, 1f # no: skip setting upper 32b - - mthc1 t1, $f0 - mthc1 t1, $f1 - mthc1 t1, $f2 - mthc1 t1, $f3 - mthc1 t1, $f4 - mthc1 t1, $f5 - mthc1 t1, $f6 - mthc1 t1, $f7 - mthc1 t1, $f8 - mthc1 t1, $f9 - mthc1 t1, $f10 - mthc1 t1, $f11 - mthc1 t1, $f12 - mthc1 t1, $f13 - mthc1 t1, $f14 - mthc1 t1, $f15 - mthc1 t1, $f16 - mthc1 t1, $f17 - mthc1 t1, $f18 - mthc1 t1, $f19 - mthc1 t1, $f20 - mthc1 t1, $f21 - mthc1 t1, $f22 - mthc1 t1, $f23 - mthc1 t1, $f24 - mthc1 t1, $f25 - mthc1 t1, $f26 - mthc1 t1, $f27 - mthc1 t1, $f28 - mthc1 t1, $f29 - mthc1 t1, $f30 - mthc1 t1, $f31 -1: .set pop -#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */ -#else - .set MIPS_ISA_ARCH_LEVEL_RAW - dmtc1 t1, $f0 - dmtc1 t1, $f2 - dmtc1 t1, $f4 - dmtc1 t1, $f6 - dmtc1 t1, $f8 - dmtc1 t1, $f10 - dmtc1 t1, $f12 - dmtc1 t1, $f14 - dmtc1 t1, $f16 - dmtc1 t1, $f18 - dmtc1 t1, $f20 - dmtc1 t1, $f22 - dmtc1 t1, $f24 - dmtc1 t1, $f26 - dmtc1 t1, $f28 - dmtc1 t1, $f30 -#endif - jr ra - END(_init_fpu) - - .set pop /* SET_HARDFLOAT */ diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S deleted file mode 100644 index 9cc7bfab3419a80e02ae344b6bd154e154370864..0000000000000000000000000000000000000000 --- a/arch/mips/kernel/r6000_fpu.S +++ /dev/null @@ -1,99 +0,0 @@ -/* - * r6000_fpu.S: Save/restore floating point context for signal handlers. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 by Ralf Baechle - * - * Multi-arch abstraction and asm macros for easier reading: - * Copyright (C) 1996 David S. Miller (davem@davemloft.net) - */ -#include -#include -#include -#include -#include - - .set noreorder - .set mips2 - .set push - SET_HARDFLOAT - -/** - * _save_fp_context() - save FP context from the FPU - * @a0 - pointer to fpregs field of sigcontext - * @a1 - pointer to fpc_csr field of sigcontext - * - * Save FP context, including the 32 FP data registers and the FP - * control & status register, from the FPU to signal context. - */ - LEAF(_save_fp_context) - mfc0 t0,CP0_STATUS - sll t0,t0,2 - bgez t0,1f - nop - - cfc1 t1,fcr31 - /* Store the 16 double precision registers */ - sdc1 $f0,0(a0) - sdc1 $f2,16(a0) - sdc1 $f4,32(a0) - sdc1 $f6,48(a0) - sdc1 $f8,64(a0) - sdc1 $f10,80(a0) - sdc1 $f12,96(a0) - sdc1 $f14,112(a0) - sdc1 $f16,128(a0) - sdc1 $f18,144(a0) - sdc1 $f20,160(a0) - sdc1 $f22,176(a0) - sdc1 $f24,192(a0) - sdc1 $f26,208(a0) - sdc1 $f28,224(a0) - sdc1 $f30,240(a0) - jr ra - sw t0,(a1) -1: jr ra - nop - END(_save_fp_context) - -/** - * _restore_fp_context() - restore FP context to the FPU - * @a0 - pointer to fpregs field of sigcontext - * @a1 - pointer to fpc_csr field of sigcontext - * - * Restore FP context, including the 32 FP data registers and the FP - * control & status register, from signal context to the FPU. - */ - LEAF(_restore_fp_context) - mfc0 t0,CP0_STATUS - sll t0,t0,2 - - bgez t0,1f - lw t0,(a1) - /* Restore the 16 double precision registers */ - ldc1 $f0,0(a0) - ldc1 $f2,16(a0) - ldc1 $f4,32(a0) - ldc1 $f6,48(a0) - ldc1 $f8,64(a0) - ldc1 $f10,80(a0) - ldc1 $f12,96(a0) - ldc1 $f14,112(a0) - ldc1 $f16,128(a0) - ldc1 $f18,144(a0) - ldc1 $f20,160(a0) - ldc1 $f22,176(a0) - ldc1 $f24,192(a0) - ldc1 $f26,208(a0) - ldc1 $f28,224(a0) - ldc1 $f30,240(a0) - jr ra - ctc1 t0,fcr31 -1: jr ra - nop - END(_restore_fp_context) - - .set pop /* SET_HARDFLOAT */ diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 27c2f90eeb21f60e07e6cb4534fb33cdd0b68ef9..a9a7d78803cde30097a02c76aa49bef9f812be7e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -190,12 +190,6 @@ illegal_syscall: sll t1, t0, 2 beqz v0, einval lw t2, sys_call_table(t1) # syscall routine - sw a0, PT_R2(sp) # call routine directly on restart - - /* Some syscalls like execve get their arguments from struct pt_regs - and claim zero arguments in the syscall table. Thus we have to - assume the worst case and shuffle around all potential arguments. - If you want performance, don't use indirect syscalls. */ move a0, a1 # shift argument registers move a1, a2 @@ -207,11 +201,6 @@ illegal_syscall: sw t4, 16(sp) sw t5, 20(sp) sw t6, 24(sp) - sw a0, PT_R4(sp) # .. and push back a0 - a3, some - sw a1, PT_R5(sp) # syscalls expect them there - sw a2, PT_R6(sp) - sw a3, PT_R7(sp) - sw a3, PT_R26(sp) # update a3 for syscall restarting jr t2 /* Unreached */ diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index c30bc520885f985a921b066bfb45d5dea8aadab2..9ebe3e2403b1d7b84d66732cd261364208f6020d 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -198,7 +198,6 @@ LEAF(sys32_syscall) dsll t1, t0, 3 beqz v0, einval ld t2, sys32_call_table(t1) # syscall routine - sd a0, PT_R2(sp) # call routine directly on restart move a0, a1 # shift argument registers move a1, a2 @@ -207,11 +206,6 @@ LEAF(sys32_syscall) move a4, a5 move a5, a6 move a6, a7 - sd a0, PT_R4(sp) # ... and push back a0 - a3, some - sd a1, PT_R5(sp) # syscalls expect them there - sd a2, PT_R6(sp) - sd a3, PT_R7(sp) - sd a3, PT_R26(sp) # update a3 for syscall restarting jr t2 /* Unreached */ diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 84165f2b31ff60c6c6842d3d96b38f445b621839..cf5c7c05e5a38798ecb237fac321983809b8476b 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -93,38 +93,37 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_TIMER >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); - default: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user((unsigned long)from->si_addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_SYS >> 16: + case SIL_SYS: err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr, sizeof(compat_uptr_t)); err |= __put_user(from->si_syscall, &to->si_syscall); diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 1b070a76fcdd4c2e5f62a84bfff8e40ad0a8721b..406072e26752052c83b04ffacc254d901a668509 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -179,7 +179,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus) /* * Tell the hardware to boot CPUx - runs on CPU0 */ -static void bmips_boot_secondary(int cpu, struct task_struct *idle) +static int bmips_boot_secondary(int cpu, struct task_struct *idle) { bmips_smp_boot_sp = __KSTK_TOS(idle); bmips_smp_boot_gp = (unsigned long)task_thread_info(idle); @@ -231,6 +231,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) } cpumask_set_cpu(cpu, &bmips_booted_mask); } + + return 0; } /* @@ -245,7 +247,7 @@ static void bmips_init_secondary(void) break; case CPU_BMIPS5000: write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); - current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3; + cpu_set_core(¤t_cpu_data, (read_c0_brcm_config() >> 25) & 3); break; } } @@ -409,7 +411,7 @@ void __ref play_dead(void) #endif /* CONFIG_HOTPLUG_CPU */ -struct plat_smp_ops bmips43xx_smp_ops = { +const struct plat_smp_ops bmips43xx_smp_ops = { .smp_setup = bmips_smp_setup, .prepare_cpus = bmips_prepare_cpus, .boot_secondary = bmips_boot_secondary, @@ -423,7 +425,7 @@ struct plat_smp_ops bmips43xx_smp_ops = { #endif }; -struct plat_smp_ops bmips5000_smp_ops = { +const struct plat_smp_ops bmips5000_smp_ops = { .smp_setup = bmips_smp_setup, .prepare_cpus = bmips_prepare_cpus, .boot_secondary = bmips_boot_secondary, diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index 76923349b4fe16135a97247734a9d803788ae5ca..05295a4909f14affe37487c634b2a12c32c18e16 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -78,7 +77,7 @@ static void cmp_smp_finish(void) * __KSTK_TOS(idle) is apparently the stack pointer * (unsigned long)idle->thread_info the gp */ -static void cmp_boot_secondary(int cpu, struct task_struct *idle) +static int cmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); @@ -95,6 +94,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle) #endif amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); + return 0; } /* @@ -148,7 +148,7 @@ void __init cmp_prepare_cpus(unsigned int max_cpus) } -struct plat_smp_ops cmp_smp_ops = { +const struct plat_smp_ops cmp_smp_ops = { .send_ipi_single = mips_smp_send_ipi_single, .send_ipi_mask = mips_smp_send_ipi_mask, .init_secondary = cmp_init_secondary, diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index f832e99ad4c3879052d924c88750c79c97dc0f78..0063122c85da809853e9bf8ab598495f1f7bb43d 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -19,8 +18,7 @@ #include #include -#include -#include +#include #include #include #include @@ -41,55 +39,58 @@ static int __init setup_nothreads(char *s) } early_param("nothreads", setup_nothreads); -static unsigned core_vpe_count(unsigned core) +static unsigned core_vpe_count(unsigned int cluster, unsigned core) { - unsigned cfg; - if (threads_disabled) return 1; - if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) - && (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp)) - return 1; - - mips_cm_lock_other(core, 0); - cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK; - mips_cm_unlock_other(); - return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; + return mips_cps_numvps(cluster, core); } static void __init cps_smp_setup(void) { - unsigned int ncores, nvpes, core_vpes; + unsigned int nclusters, ncores, nvpes, core_vpes; unsigned long core_entry; - int c, v; + int cl, c, v; /* Detect & record VPE topology */ - ncores = mips_cm_numcores(); + nvpes = 0; + nclusters = mips_cps_numclusters(); pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE"); - for (c = nvpes = 0; c < ncores; c++) { - core_vpes = core_vpe_count(c); - pr_cont("%c%u", c ? ',' : '{', core_vpes); - - /* Use the number of VPEs in core 0 for smp_num_siblings */ - if (!c) - smp_num_siblings = core_vpes; - - for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { - cpu_data[nvpes + v].core = c; -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) - cpu_data[nvpes + v].vpe_id = v; -#endif + for (cl = 0; cl < nclusters; cl++) { + if (cl > 0) + pr_cont(","); + pr_cont("{"); + + ncores = mips_cps_numcores(cl); + for (c = 0; c < ncores; c++) { + core_vpes = core_vpe_count(cl, c); + + if (c > 0) + pr_cont(","); + pr_cont("%u", core_vpes); + + /* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */ + if (!cl && !c) + smp_num_siblings = core_vpes; + + for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { + cpu_set_cluster(&cpu_data[nvpes + v], cl); + cpu_set_core(&cpu_data[nvpes + v], c); + cpu_set_vpe_id(&cpu_data[nvpes + v], v); + } + + nvpes += core_vpes; } - nvpes += core_vpes; + pr_cont("}"); } - pr_cont("} total %u\n", nvpes); + pr_cont(" total %u\n", nvpes); /* Indicate present CPUs (CPU being synonymous with VPE) */ for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) { - set_cpu_possible(v, true); - set_cpu_present(v, true); + set_cpu_possible(v, cpu_cluster(&cpu_data[v]) == 0); + set_cpu_present(v, cpu_cluster(&cpu_data[v]) == 0); __cpu_number_map[v] = v; __cpu_logical_map[v] = v; } @@ -121,7 +122,7 @@ static void __init cps_smp_setup(void) static void __init cps_prepare_cpus(unsigned int max_cpus) { unsigned ncores, core_vpes, c, cca; - bool cca_unsuitable; + bool cca_unsuitable, cores_limited; u32 *entry_code; mips_mt_set_cpuoptions(); @@ -141,19 +142,22 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) } /* Warn the user if the CCA prevents multi-core */ - ncores = mips_cm_numcores(); - if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) { + cores_limited = false; + if (cca_unsuitable || cpu_has_dc_aliases) { + for_each_present_cpu(c) { + if (cpus_are_siblings(smp_processor_id(), c)) + continue; + + set_cpu_present(c, false); + cores_limited = true; + } + } + if (cores_limited) pr_warn("Using only one core due to %s%s%s\n", cca_unsuitable ? "unsuitable CCA" : "", (cca_unsuitable && cpu_has_dc_aliases) ? " & " : "", cpu_has_dc_aliases ? "dcache aliasing" : ""); - for_each_present_cpu(c) { - if (cpu_data[c].core) - set_cpu_present(c, false); - } - } - /* * Patch the start of mips_cps_core_entry to provide: * @@ -168,6 +172,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) __sync(); /* Allocate core boot configuration structs */ + ncores = mips_cps_numcores(0); mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg), GFP_KERNEL); if (!mips_cps_core_bootcfg) { @@ -177,7 +182,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) /* Allocate VPE boot configuration structs */ for (c = 0; c < ncores; c++) { - core_vpes = core_vpe_count(c); + core_vpes = core_vpe_count(0, c); mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes, sizeof(*mips_cps_core_bootcfg[c].vpe_config), GFP_KERNEL); @@ -189,7 +194,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) } /* Mark this CPU as booted */ - atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask, + atomic_set(&mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)].vpe_mask, 1 << cpu_vpe_id(¤t_cpu_data)); return; @@ -212,11 +217,11 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) static void boot_core(unsigned int core, unsigned int vpe_id) { - u32 access, stat, seq_state; + u32 stat, seq_state; unsigned timeout; /* Select the appropriate core */ - mips_cm_lock_other(core, 0); + mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); /* Set its reset vector */ write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry)); @@ -225,12 +230,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id) write_gcr_co_coherence(0); /* Start it with the legacy memory map and exception base */ - write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB); + write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB); /* Ensure the core can access the GCRs */ - access = read_gcr_access(); - access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core); - write_gcr_access(access); + set_gcr_access(1 << core); if (mips_cpc_present()) { /* Reset the core */ @@ -253,7 +256,8 @@ static void boot_core(unsigned int core, unsigned int vpe_id) timeout = 100; while (true) { stat = read_cpc_co_stat_conf(); - seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK; + seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE; + seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE); /* U6 == coherent execution, ie. the core is up */ if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6) @@ -285,15 +289,15 @@ static void boot_core(unsigned int core, unsigned int vpe_id) static void remote_vpe_boot(void *dummy) { - unsigned core = current_cpu_data.core; + unsigned core = cpu_core(¤t_cpu_data); struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); } -static void cps_boot_secondary(int cpu, struct task_struct *idle) +static int cps_boot_secondary(int cpu, struct task_struct *idle) { - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id]; @@ -301,6 +305,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) unsigned int remote; int err; + /* We don't yet support booting CPUs in other clusters */ + if (cpu_cluster(&cpu_data[cpu]) != cpu_cluster(¤t_cpu_data)) + return -ENOSYS; + vpe_cfg->pc = (unsigned long)&smp_bootstrap; vpe_cfg->sp = __KSTK_TOS(idle); vpe_cfg->gp = (unsigned long)task_thread_info(idle); @@ -316,16 +324,16 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) } if (cpu_has_vp) { - mips_cm_lock_other(core, vpe_id); + mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL); core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry); write_gcr_co_reset_base(core_entry); mips_cm_unlock_other(); } - if (core != current_cpu_data.core) { + if (!cpus_are_siblings(cpu, smp_processor_id())) { /* Boot a VPE on another powered up core */ for (remote = 0; remote < NR_CPUS; remote++) { - if (cpu_data[remote].core != core) + if (!cpus_are_siblings(cpu, remote)) continue; if (cpu_online(remote)) break; @@ -349,6 +357,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) mips_cps_boot_vpes(core_cfg, vpe_id); out: preempt_enable(); + return 0; } static void cps_init_secondary(void) @@ -358,7 +367,7 @@ static void cps_init_secondary(void) dmt(); if (mips_cm_revision() >= CM_REV_CM3) { - unsigned ident = gic_read_local_vp_id(); + unsigned int ident = read_gic_vl_ident(); /* * Ensure that our calculation of the VP ID matches up with @@ -402,7 +411,7 @@ static int cps_cpu_disable(void) if (!cps_pm_support_state(CPS_PM_POWER_GATED)) return -EINVAL; - core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core]; + core_cfg = &mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)]; atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); smp_mb__after_atomic(); set_cpu_online(cpu, false); @@ -424,15 +433,17 @@ void play_dead(void) local_irq_disable(); idle_task_exit(); cpu = smp_processor_id(); - core = cpu_data[cpu].core; + core = cpu_core(&cpu_data[cpu]); cpu_death = CPU_DEATH_POWER; pr_debug("CPU%d going offline\n", cpu); if (cpu_has_mipsmt || cpu_has_vp) { + core = cpu_core(&cpu_data[cpu]); + /* Look for another online VPE within the core */ for_each_online_cpu(cpu_death_sibling) { - if (cpu_data[cpu_death_sibling].core != core) + if (!cpus_are_siblings(cpu, cpu_death_sibling)) continue; /* @@ -488,7 +499,7 @@ static void wait_for_sibling_halt(void *ptr_cpu) static void cps_cpu_die(unsigned int cpu) { - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]); ktime_t fail_time; unsigned stat; @@ -519,10 +530,11 @@ static void cps_cpu_die(unsigned int cpu) */ fail_time = ktime_add_ms(ktime_get(), 2000); do { - mips_cm_lock_other(core, 0); + mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); mips_cpc_lock_other(core); stat = read_cpc_co_stat_conf(); - stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK; + stat &= CPC_Cx_STAT_CONF_SEQSTATE; + stat >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE); mips_cpc_unlock_other(); mips_cm_unlock_other(); @@ -544,7 +556,7 @@ static void cps_cpu_die(unsigned int cpu) */ if (WARN(ktime_after(ktime_get(), fail_time), "CPU%u hasn't powered down, seq. state %u\n", - cpu, stat >> CPC_Cx_STAT_CONF_SEQSTATE_SHF)) + cpu, stat)) break; } while (1); @@ -562,7 +574,7 @@ static void cps_cpu_die(unsigned int cpu) panic("Failed to call remote sibling CPU\n"); } else if (cpu_has_vp) { do { - mips_cm_lock_other(core, vpe_id); + mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL); stat = read_cpc_co_vp_running(); mips_cm_unlock_other(); } while (stat & (1 << vpe_id)); @@ -571,7 +583,7 @@ static void cps_cpu_die(unsigned int cpu) #endif /* CONFIG_HOTPLUG_CPU */ -static struct plat_smp_ops cps_smp_ops = { +static const struct plat_smp_ops cps_smp_ops = { .smp_setup = cps_smp_setup, .prepare_cpus = cps_prepare_cpus, .boot_secondary = cps_boot_secondary, @@ -587,7 +599,7 @@ static struct plat_smp_ops cps_smp_ops = { bool mips_cps_smp_in_use(void) { - extern struct plat_smp_ops *mp_ops; + extern const struct plat_smp_ops *mp_ops; return mp_ops == &cps_smp_ops; } @@ -599,7 +611,7 @@ int register_cps_smp_ops(void) } /* check we have a GIC - we need one for IPIs */ - if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX_MSK)) { + if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) { pr_warn("MIPS CPS SMP unable to proceed without a GIC\n"); return -ENODEV; } diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index ed6b4df583ea0d420e9db7c75267fa419a4c4c8f..94ab3276b48c491cb0fcc12f167fb15080e48595 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include static void __init smvp_copy_vpe_config(void) { @@ -83,7 +83,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0, if (tc != 0) smvp_copy_vpe_config(); - cpu_data[ncpu].vpe_id = tc; + cpu_set_vpe_id(&cpu_data[ncpu], tc); return ncpu; } @@ -118,14 +118,12 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0) static void vsmp_init_secondary(void) { -#ifdef CONFIG_MIPS_GIC /* This is Malta specific: IPI,performance and timer interrupts */ - if (gic_present) + if (mips_gic_present()) change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); else -#endif change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7); } @@ -152,7 +150,7 @@ static void vsmp_smp_finish(void) * (unsigned long)idle->thread_info the gp * assumes a 1:1 mapping of TC => VPE */ -static void vsmp_boot_secondary(int cpu, struct task_struct *idle) +static int vsmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); dvpe(); @@ -184,6 +182,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle) clear_c0_mvpcontrol(MVPCONTROL_VPC); evpe(EVPE_ENABLE); + + return 0; } /* @@ -239,7 +239,7 @@ static void __init vsmp_prepare_cpus(unsigned int max_cpus) mips_mt_set_cpuoptions(); } -struct plat_smp_ops vsmp_smp_ops = { +const struct plat_smp_ops vsmp_smp_ops = { .send_ipi_single = mips_smp_send_ipi_single, .send_ipi_mask = mips_smp_send_ipi_mask, .init_secondary = vsmp_init_secondary, diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c index 17878d71ef2bc9f5238c7062b0f09cd5d1ca644b..525d3196f793f254d2620cd8a3f7a828547be3fa 100644 --- a/arch/mips/kernel/smp-up.c +++ b/arch/mips/kernel/smp-up.c @@ -39,8 +39,9 @@ static void up_smp_finish(void) /* * Firmware CPU startup hook */ -static void up_boot_secondary(int cpu, struct task_struct *idle) +static int up_boot_secondary(int cpu, struct task_struct *idle) { + return 0; } static void __init up_smp_setup(void) @@ -63,7 +64,7 @@ static void up_cpu_die(unsigned int cpu) } #endif -struct plat_smp_ops up_smp_ops = { +const struct plat_smp_ops up_smp_ops = { .send_ipi_single = up_send_ipi_single, .send_ipi_mask = up_send_ipi_mask, .init_secondary = up_init_secondary, diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 770d4d1516cbb1ff34cca30cdccbe6c1b0aeebdc..bbe19b64def5b6c863e9d2e11f0ad36609d0bfde 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu(i, &cpu_sibling_setup_map) { - if (cpu_data[cpu].package == cpu_data[i].package && - cpu_data[cpu].core == cpu_data[i].core) { + if (cpus_are_siblings(cpu, i)) { cpumask_set_cpu(i, &cpu_sibling_map[cpu]); cpumask_set_cpu(cpu, &cpu_sibling_map[i]); } @@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void) for_each_online_cpu(i) { core_present = 0; for_each_cpu(k, &temp_foreign_map) - if (cpu_data[i].package == cpu_data[k].package && - cpu_data[i].core == cpu_data[k].core) + if (cpus_are_siblings(i, k)) core_present = 1; if (!core_present) cpumask_set_cpu(i, &temp_foreign_map); @@ -146,10 +144,10 @@ void calculate_cpu_foreign_map(void) &temp_foreign_map, &cpu_sibling_map[i]); } -struct plat_smp_ops *mp_ops; +const struct plat_smp_ops *mp_ops; EXPORT_SYMBOL(mp_ops); -void register_smp_ops(struct plat_smp_ops *ops) +void register_smp_ops(const struct plat_smp_ops *ops) { if (mp_ops) printk(KERN_WARNING "Overriding previously set SMP ops\n"); @@ -186,13 +184,13 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action) if (mips_cpc_present()) { for_each_cpu(cpu, mask) { - core = cpu_data[cpu].core; - - if (core == current_cpu_data.core) + if (cpus_are_siblings(cpu, smp_processor_id())) continue; + core = cpu_core(&cpu_data[cpu]); + while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { - mips_cm_lock_other(core, 0); + mips_cm_lock_other_cpu(cpu, CM_GCR_Cx_OTHER_BLOCK_LOCAL); mips_cpc_lock_other(core); write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); mips_cpc_unlock_other(); @@ -376,9 +374,6 @@ asmlinkage void start_secondary(void) cpumask_set_cpu(cpu, &cpu_coherent_mask); notify_cpu_starting(cpu); - complete(&cpu_running); - synchronise_count_slave(cpu); - set_cpu_online(cpu, true); set_cpu_sibling_map(cpu); @@ -386,6 +381,9 @@ asmlinkage void start_secondary(void) calculate_cpu_foreign_map(); + complete(&cpu_running); + synchronise_count_slave(cpu); + /* * irq will be enabled in ->smp_finish(), enabling it too early * is dangerous. @@ -441,7 +439,11 @@ void smp_prepare_boot_cpu(void) int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - mp_ops->boot_secondary(cpu, tidle); + int err; + + err = mp_ops->boot_secondary(cpu, tidle); + if (err) + return err; /* * We must check for timeout here, as the CPU will not be marked @@ -648,12 +650,12 @@ EXPORT_SYMBOL(flush_tlb_one); #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST static DEFINE_PER_CPU(atomic_t, tick_broadcast_count); -static DEFINE_PER_CPU(struct call_single_data, tick_broadcast_csd); +static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd); void tick_broadcast(const struct cpumask *mask) { atomic_t *count; - struct call_single_data *csd; + call_single_data_t *csd; int cpu; for_each_cpu(cpu, mask) { @@ -674,7 +676,7 @@ static void tick_broadcast_callee(void *info) static int __init tick_broadcast_init(void) { - struct call_single_data *csd; + call_single_data_t *csd; int cpu; for (cpu = 0; cpu < NR_CPUS; cpu++) { diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index c036157fb891ff7e9a76c461b5ed0873c56743b9..a6ebc8135112e5c9c22e5598bf25556469f9dbb4 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -72,20 +72,6 @@ EXPORT_SYMBOL(perf_irq); unsigned int mips_hpt_frequency; EXPORT_SYMBOL_GPL(mips_hpt_frequency); -/* - * This function exists in order to cause an error due to a duplicate - * definition if platform code should have its own implementation. The hook - * to use instead is plat_time_init. plat_time_init does not receive the - * irqaction pointer argument anymore. This is because any function which - * initializes an interrupt timer now takes care of its own request_irq rsp. - * setup_irq calls and each clock_event_device should use its own - * struct irqrequest. - */ -void __init plat_timer_setup(void) -{ - BUG(); -} - static __init int cpu_has_mfc0_count_bug(void) { switch (current_cpu_type()) { diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b68b4d0726d3e02fd7888fd5d757e14c2c8fc4b9..5669d3b8bd382760aa4f7cefa243a13195035928 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -50,9 +50,8 @@ #include #include #include -#include +#include #include -#include #include #include #include @@ -734,8 +733,7 @@ void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, si.si_code = FPE_FLTUND; else if (fcr31 & FPU_CSR_INE_X) si.si_code = FPE_FLTRES; - else - si.si_code = __SI_FAULT; + force_sig_info(SIGFPE, &si, tsk); } @@ -1673,7 +1671,7 @@ static inline void parity_protection_init(void) /* Probe L2 ECC support */ gcr_ectl = read_gcr_err_control(); - if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) || + if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT) || !(cp0_ectl & ERRCTL_PE)) { /* * One of L1 or L2 ECC checking isn't supported, @@ -1693,12 +1691,12 @@ static inline void parity_protection_init(void) /* Configure L2 ECC checking */ if (l2parity) - gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; + gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN; else - gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; + gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN; write_gcr_err_control(gcr_ectl); gcr_ectl = read_gcr_err_control(); - gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; + gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN; WARN_ON(!!gcr_ectl != l2parity); pr_info("Cache parity protection %sabled\n", @@ -2428,21 +2426,6 @@ void __init trap_init(void) set_except_vector(EXCCODE_TR, handle_tr); set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe); - if (current_cpu_type() == CPU_R6000 || - current_cpu_type() == CPU_R6000A) { - /* - * The R6000 is the only R-series CPU that features a machine - * check exception (similar to the R4000 cache error) and - * unaligned ldc1/sdc1 exception. The handlers have not been - * written yet. Well, anyway there is no R6000 machine on the - * current list of targets for Linux/MIPS. - * (Duh, crap, there is someone with a triple R6k machine) - */ - //set_except_vector(14, handle_mc); - //set_except_vector(15, handle_ndc); - } - - if (board_nmi_handler_setup) board_nmi_handler_setup(); diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 5eaf2578ac0407b076b78bd7f8842a49e0d1ba82..2d0b912f9e3e40a987a5a481c7066bf46dcf4acb 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -1378,7 +1378,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; /* Recode table from 16-bit STORE register notation to 32-bit GPR. */ -const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; +static const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; static void emulate_load_store_microMIPS(struct pt_regs *regs, void __user *addr) diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 093517e85a6cdca8a550042dbd06a7c4b2a93ae5..019035d7225c4fd942c96c6628b6605f8d2af1b4 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -13,13 +13,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include /* Kernel-provided data used by the VDSO. */ @@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { struct mips_vdso_image *image = current->thread.abi->vdso; struct mm_struct *mm = current->mm; - unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr; + unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn; struct vm_area_struct *vma; - struct resource gic_res; int ret; if (down_write_killable(&mm->mmap_sem)) @@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * only map a page even though the total area is 64K, as we only need * the counter registers at the start. */ - gic_size = gic_present ? PAGE_SIZE : 0; + gic_size = mips_gic_present() ? PAGE_SIZE : 0; vvar_size = gic_size + PAGE_SIZE; size = vvar_size + image->size; @@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) /* Map GIC user page. */ if (gic_size) { - ret = gic_get_usm_range(&gic_res); - if (ret) - goto out; + gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT; - ret = io_remap_pfn_range(vma, base, - gic_res.start >> PAGE_SHIFT, - gic_size, + ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size, pgprot_noncached(PAGE_READONLY)); if (ret) goto out; diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index d4b2ad18eef2023d23701b0dd5a320d2370fee5d..d535edc01434117a8809fc21fb152226e0b46521 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -98,6 +98,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) return !!(vcpu->arch.pending_exceptions); } +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) +{ + return false; +} + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) { return 1; @@ -509,7 +514,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, dvcpu->arch.wait = 0; - if (swait_active(&dvcpu->wq)) + if (swq_has_sleeper(&dvcpu->wq)) swake_up(&dvcpu->wq); return 0; @@ -1174,7 +1179,7 @@ static void kvm_mips_comparecount_func(unsigned long data) kvm_mips_callbacks->queue_timer_int(vcpu); vcpu->arch.wait = 0; - if (swait_active(&vcpu->wq)) + if (swq_has_sleeper(&vcpu->wq)) swake_up(&vcpu->wq); } diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 177769dbb0e85df724bd5da31951a46bfe544842..35bc69b78268eff635182d3144f01cd40d41b117 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -17,6 +17,8 @@ config SOC_XWAY bool "XWAY" select SOC_TYPE_XWAY select HW_HAS_PCI + select MFD_SYSCON + select MFD_CORE config SOC_FALCON bool "FALCON" diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c index 7a535d72f541afbe03f4c413afc92756f505e634..058b85578cf780e767ae59c39ba959a6aa15ec0c 100644 --- a/arch/mips/lantiq/falcon/reset.c +++ b/arch/mips/lantiq/falcon/reset.c @@ -15,27 +15,14 @@ #include -/* CPU0 Reset Source Register */ -#define SYS1_CPU0RS 0x0040 -/* reset cause mask */ -#define CPU0RS_MASK 0x0003 -/* CPU0 Boot Mode Register */ -#define SYS1_BM 0x00a0 -/* boot mode mask */ -#define BM_MASK 0x0005 - -/* allow platform code to find out what surce we booted from */ +/* + * Dummy implementation. Used to allow platform code to find out what + * source was booted from + */ unsigned char ltq_boot_select(void) { - return ltq_sys1_r32(SYS1_BM) & BM_MASK; -} - -/* allow the watchdog driver to find out what the boot reason was */ -int ltq_reset_cause(void) -{ - return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK; + return BS_SPI; } -EXPORT_SYMBOL_GPL(ltq_reset_cause); #define BOOT_REG_BASE (KSEG1 | 0x1F200000) #define BOOT_PW1_REG (BOOT_REG_BASE | 0x20) diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 33728b7af4267b26902781ef2691a064536c49dd..f0bc3312ed1103bea83c69338e1cf4cc010619cf 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -61,10 +61,6 @@ /* we have a cascade of 8 irqs */ #define MIPS_CPU_IRQ_CASCADE 8 -#ifdef CONFIG_MIPS_MT_SMP -int gic_present; -#endif - static int exin_avail; static u32 ltq_eiu_irq[MAX_EIU]; static void __iomem *ltq_icu_membase[MAX_IM]; diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 96773bed8a8a52cdbe33308cd23f9cd6069665bd..9ff7ccde9de0e8d9899018d3d9152e4a243408e8 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -117,7 +117,7 @@ void __init prom_init(void) int __init plat_of_setup(void) { - return __dt_register_buses(soc_info.compatible, "simple-bus"); + return of_platform_default_populate(NULL, NULL, NULL); } arch_initcall(plat_of_setup); diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index a2edc538f4779df646822b52cb7737ad13b64dcb..fbb0747c70b78b26231a6b51e3eb2f3267c94dd6 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1,5 +1,3 @@ -obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o +obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o obj-y += vmmc.o - -obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c deleted file mode 100644 index 83fd65d76e81d836b982534054f2afe1e7676172..0000000000000000000000000000000000000000 --- a/arch/mips/lantiq/xway/reset.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * Copyright (C) 2010 John Crispin - * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "../prom.h" - -/* reset request register */ -#define RCU_RST_REQ 0x0010 -/* reset status register */ -#define RCU_RST_STAT 0x0014 -/* vr9 gphy registers */ -#define RCU_GFS_ADD0_XRX200 0x0020 -#define RCU_GFS_ADD1_XRX200 0x0068 -/* xRX300 gphy registers */ -#define RCU_GFS_ADD0_XRX300 0x0020 -#define RCU_GFS_ADD1_XRX300 0x0058 -#define RCU_GFS_ADD2_XRX300 0x00AC -/* xRX330 gphy registers */ -#define RCU_GFS_ADD0_XRX330 0x0020 -#define RCU_GFS_ADD1_XRX330 0x0058 -#define RCU_GFS_ADD2_XRX330 0x00AC -#define RCU_GFS_ADD3_XRX330 0x0264 - -/* xbar BE flag */ -#define RCU_AHB_ENDIAN 0x004C -#define RCU_VR9_BE_AHB1S 0x00000008 - -/* reboot bit */ -#define RCU_RD_GPHY0_XRX200 BIT(31) -#define RCU_RD_SRST BIT(30) -#define RCU_RD_GPHY1_XRX200 BIT(29) -/* xRX300 bits */ -#define RCU_RD_GPHY0_XRX300 BIT(31) -#define RCU_RD_GPHY1_XRX300 BIT(29) -#define RCU_RD_GPHY2_XRX300 BIT(28) -/* xRX330 bits */ -#define RCU_RD_GPHY0_XRX330 BIT(31) -#define RCU_RD_GPHY1_XRX330 BIT(29) -#define RCU_RD_GPHY2_XRX330 BIT(28) -#define RCU_RD_GPHY3_XRX330 BIT(10) - -/* reset cause */ -#define RCU_STAT_SHIFT 26 -/* boot selection */ -#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7) -#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10)) - -/* dwc2 USB configuration registers */ -#define RCU_USB1CFG 0x0018 -#define RCU_USB2CFG 0x0034 - -/* USB DMA endianness bits */ -#define RCU_USBCFG_HDSEL_BIT BIT(11) -#define RCU_USBCFG_HOST_END_BIT BIT(10) -#define RCU_USBCFG_SLV_END_BIT BIT(9) - -/* USB reset bits */ -#define RCU_USBRESET 0x0010 - -#define USBRESET_BIT BIT(4) - -#define RCU_USBRESET2 0x0048 - -#define USB1RESET_BIT BIT(4) -#define USB2RESET_BIT BIT(5) - -#define RCU_CFG1A 0x0038 -#define RCU_CFG1B 0x003C - -/* USB PMU devices */ -#define PMU_AHBM BIT(15) -#define PMU_USB0 BIT(6) -#define PMU_USB1 BIT(27) - -/* USB PHY PMU devices */ -#define PMU_USB0_P BIT(0) -#define PMU_USB1_P BIT(26) - -/* remapped base addr of the reset control unit */ -static void __iomem *ltq_rcu_membase; -static struct device_node *ltq_rcu_np; -static DEFINE_SPINLOCK(ltq_rcu_lock); - -static void ltq_rcu_w32(uint32_t val, uint32_t reg_off) -{ - ltq_w32(val, ltq_rcu_membase + reg_off); -} - -static uint32_t ltq_rcu_r32(uint32_t reg_off) -{ - return ltq_r32(ltq_rcu_membase + reg_off); -} - -static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off) -{ - unsigned long flags; - - spin_lock_irqsave(<q_rcu_lock, flags); - ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off); - spin_unlock_irqrestore(<q_rcu_lock, flags); -} - -/* This function is used by the watchdog driver */ -int ltq_reset_cause(void) -{ - u32 val = ltq_rcu_r32(RCU_RST_STAT); - return val >> RCU_STAT_SHIFT; -} -EXPORT_SYMBOL_GPL(ltq_reset_cause); - -/* allow platform code to find out what source we booted from */ -unsigned char ltq_boot_select(void) -{ - u32 val = ltq_rcu_r32(RCU_RST_STAT); - - if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) - return RCU_BOOT_SEL_XRX200(val); - - return RCU_BOOT_SEL(val); -} - -struct ltq_gphy_reset { - u32 rd; - u32 addr; -}; - -/* reset / boot a gphy */ -static struct ltq_gphy_reset xrx200_gphy[] = { - {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200}, - {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200}, -}; - -/* reset / boot a gphy */ -static struct ltq_gphy_reset xrx300_gphy[] = { - {RCU_RD_GPHY0_XRX300, RCU_GFS_ADD0_XRX300}, - {RCU_RD_GPHY1_XRX300, RCU_GFS_ADD1_XRX300}, - {RCU_RD_GPHY2_XRX300, RCU_GFS_ADD2_XRX300}, -}; - -/* reset / boot a gphy */ -static struct ltq_gphy_reset xrx330_gphy[] = { - {RCU_RD_GPHY0_XRX330, RCU_GFS_ADD0_XRX330}, - {RCU_RD_GPHY1_XRX330, RCU_GFS_ADD1_XRX330}, - {RCU_RD_GPHY2_XRX330, RCU_GFS_ADD2_XRX330}, - {RCU_RD_GPHY3_XRX330, RCU_GFS_ADD3_XRX330}, -}; - -static void xrx200_gphy_boot_addr(struct ltq_gphy_reset *phy_regs, - dma_addr_t dev_addr) -{ - ltq_rcu_w32_mask(0, phy_regs->rd, RCU_RST_REQ); - ltq_rcu_w32(dev_addr, phy_regs->addr); - ltq_rcu_w32_mask(phy_regs->rd, 0, RCU_RST_REQ); -} - -/* reset and boot a gphy. these phys only exist on xrx200 SoC */ -int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) -{ - struct clk *clk; - - if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) { - dev_err(dev, "this SoC has no GPHY\n"); - return -EINVAL; - } - - if (of_machine_is_compatible("lantiq,vr9")) { - clk = clk_get_sys("1f203000.rcu", "gphy"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - clk_enable(clk); - } - - dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); - - if (of_machine_is_compatible("lantiq,vr9")) { - if (id >= ARRAY_SIZE(xrx200_gphy)) { - dev_err(dev, "%u is an invalid gphy id\n", id); - return -EINVAL; - } - xrx200_gphy_boot_addr(&xrx200_gphy[id], dev_addr); - } else if (of_machine_is_compatible("lantiq,ar10")) { - if (id >= ARRAY_SIZE(xrx300_gphy)) { - dev_err(dev, "%u is an invalid gphy id\n", id); - return -EINVAL; - } - xrx200_gphy_boot_addr(&xrx300_gphy[id], dev_addr); - } else if (of_machine_is_compatible("lantiq,grx390")) { - if (id >= ARRAY_SIZE(xrx330_gphy)) { - dev_err(dev, "%u is an invalid gphy id\n", id); - return -EINVAL; - } - xrx200_gphy_boot_addr(&xrx330_gphy[id], dev_addr); - } - return 0; -} - -/* reset a io domain for u micro seconds */ -void ltq_reset_once(unsigned int module, ulong u) -{ - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); - udelay(u); - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); -} - -static int ltq_assert_device(struct reset_controller_dev *rcdev, - unsigned long id) -{ - u32 val; - - if (id < 8) - return -1; - - val = ltq_rcu_r32(RCU_RST_REQ); - val |= BIT(id); - ltq_rcu_w32(val, RCU_RST_REQ); - - return 0; -} - -static int ltq_deassert_device(struct reset_controller_dev *rcdev, - unsigned long id) -{ - u32 val; - - if (id < 8) - return -1; - - val = ltq_rcu_r32(RCU_RST_REQ); - val &= ~BIT(id); - ltq_rcu_w32(val, RCU_RST_REQ); - - return 0; -} - -static int ltq_reset_device(struct reset_controller_dev *rcdev, - unsigned long id) -{ - ltq_assert_device(rcdev, id); - return ltq_deassert_device(rcdev, id); -} - -static const struct reset_control_ops reset_ops = { - .reset = ltq_reset_device, - .assert = ltq_assert_device, - .deassert = ltq_deassert_device, -}; - -static struct reset_controller_dev reset_dev = { - .ops = &reset_ops, - .owner = THIS_MODULE, - .nr_resets = 32, - .of_reset_n_cells = 1, -}; - -void ltq_rst_init(void) -{ - reset_dev.of_node = of_find_compatible_node(NULL, NULL, - "lantiq,xway-reset"); - if (!reset_dev.of_node) - pr_err("Failed to find reset controller node"); - else - reset_controller_register(&reset_dev); -} - -static void ltq_machine_restart(char *command) -{ - u32 val = ltq_rcu_r32(RCU_RST_REQ); - - if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) - val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200; - - val |= RCU_RD_SRST; - - local_irq_disable(); - ltq_rcu_w32(val, RCU_RST_REQ); - unreachable(); -} - -static void ltq_machine_halt(void) -{ - local_irq_disable(); - unreachable(); -} - -static void ltq_machine_power_off(void) -{ - local_irq_disable(); - unreachable(); -} - -static void ltq_usb_init(void) -{ - /* Power for USB cores 1 & 2 */ - ltq_pmu_enable(PMU_AHBM); - ltq_pmu_enable(PMU_USB0); - ltq_pmu_enable(PMU_USB1); - - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A); - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B); - - /* Enable USB PHY power for cores 1 & 2 */ - ltq_pmu_enable(PMU_USB0_P); - ltq_pmu_enable(PMU_USB1_P); - - /* Configure cores to host mode */ - ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT, - RCU_USB1CFG); - ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT, - RCU_USB2CFG); - - /* Select DMA endianness (Host-endian: big-endian) */ - ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT) - | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG); - ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT) - | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG); - - /* Hard reset USB state machines */ - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET); - udelay(50 * 1000); - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET); - - /* Soft reset USB state machines */ - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) - | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2); - udelay(50 * 1000); - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) - & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2); -} - -static int __init mips_reboot_setup(void) -{ - struct resource res; - - ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); - if (!ltq_rcu_np) - ltq_rcu_np = of_find_compatible_node(NULL, NULL, - "lantiq,rcu-xrx200"); - - /* check if all the reset register range is available */ - if (!ltq_rcu_np) - panic("Failed to load reset resources from devicetree"); - - if (of_address_to_resource(ltq_rcu_np, 0, &res)) - panic("Failed to get rcu memory range"); - - if (!request_mem_region(res.start, resource_size(&res), res.name)) - pr_err("Failed to request rcu memory"); - - ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res)); - if (!ltq_rcu_membase) - panic("Failed to remap core memory"); - - if (of_machine_is_compatible("lantiq,ar9") || - of_machine_is_compatible("lantiq,vr9")) - ltq_usb_init(); - - if (of_machine_is_compatible("lantiq,vr9")) - ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S, - RCU_AHB_ENDIAN); - - _machine_restart = ltq_machine_restart; - _machine_halt = ltq_machine_halt; - pm_power_off = ltq_machine_power_off; - - return 0; -} - -arch_initcall(mips_reboot_setup); diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 95bec460b651fd1cdad1b1e262463408742c7795..7611c3013793feac519b07025b70206efa320397 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -145,15 +145,7 @@ static u32 pmu_clk_cr_b[] = { #define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y)) #define pmu_r32(x) ltq_r32(pmu_membase + (x)) -#define XBAR_ALWAYS_LAST 0x430 -#define XBAR_FPI_BURST_EN BIT(1) -#define XBAR_AHB_BURST_EN BIT(2) - -#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y)) -#define xbar_r32(x) ltq_r32(ltq_xbar_membase + (x)) - static void __iomem *pmu_membase; -static void __iomem *ltq_xbar_membase; void __iomem *ltq_cgu_membase; void __iomem *ltq_ebu_membase; @@ -293,16 +285,6 @@ static void pci_ext_disable(struct clk *clk) ltq_cgu_w32((1 << 31) | (1 << 30), pcicr); } -static void xbar_fpi_burst_disable(void) -{ - u32 reg; - - /* bit 1 as 1 --burst; bit 1 as 0 -- single */ - reg = xbar_r32(XBAR_ALWAYS_LAST); - reg &= ~XBAR_FPI_BURST_EN; - xbar_w32(reg, XBAR_ALWAYS_LAST); -} - /* enable a clockout source */ static int clkout_enable(struct clk *clk) { @@ -459,26 +441,6 @@ void __init ltq_soc_init(void) if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase) panic("Failed to remap core resources"); - if (of_machine_is_compatible("lantiq,vr9")) { - struct resource res_xbar; - struct device_node *np_xbar = - of_find_compatible_node(NULL, NULL, - "lantiq,xbar-xway"); - - if (!np_xbar) - panic("Failed to load xbar nodes from devicetree"); - if (of_address_to_resource(np_xbar, 0, &res_xbar)) - panic("Failed to get xbar resources"); - if (!request_mem_region(res_xbar.start, resource_size(&res_xbar), - res_xbar.name)) - panic("Failed to get xbar resources"); - - ltq_xbar_membase = ioremap_nocache(res_xbar.start, - resource_size(&res_xbar)); - if (!ltq_xbar_membase) - panic("Failed to remap xbar resources"); - } - /* make sure to unprotect the memory region where flash is located */ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); @@ -507,8 +469,8 @@ void __init ltq_soc_init(void) if (of_machine_is_compatible("lantiq,grx390") || of_machine_is_compatible("lantiq,ar10")) { - clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P); - clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P); + clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P); /* rc 0 */ clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); @@ -528,8 +490,8 @@ void __init ltq_soc_init(void) else clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M, CLOCK_133M); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE); clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY); clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY); @@ -538,8 +500,8 @@ void __init ltq_soc_init(void) } else if (of_machine_is_compatible("lantiq,grx390")) { clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(), ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); /* rc 2 */ clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); @@ -551,22 +513,23 @@ void __init ltq_soc_init(void) } else if (of_machine_is_compatible("lantiq,ar10")) { clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(), ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP | PMU_PPE_TC); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); - clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); + clkdev_add_pmu("1f203020.gphy", NULL, 1, 0, PMU_GPHY); + clkdev_add_pmu("1f203068.gphy", NULL, 1, 0, PMU_GPHY); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); } else if (of_machine_is_compatible("lantiq,vr9")) { clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM); - clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); + clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); @@ -579,17 +542,18 @@ void __init ltq_soc_init(void) PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | PMU_PPE_QSB | PMU_PPE_TOP); - clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY); + clkdev_add_pmu("1f203020.gphy", NULL, 0, 0, PMU_GPHY); + clkdev_add_pmu("1f203068.gphy", NULL, 0, 0, PMU_GPHY); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); } else if (of_machine_is_compatible("lantiq,ar9")) { clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), ltq_ar9_fpi_hz(), CLOCK_250M); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); - clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); @@ -598,14 +562,11 @@ void __init ltq_soc_init(void) } else { clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1f203018.usb2-phy", "ctrl", 1, 0, PMU_USB0); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0); } - - if (of_machine_is_compatible("lantiq,vr9")) - xbar_fpi_burst_disable(); } diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c deleted file mode 100644 index f0a0f2d431b2335fc9f851a41766ec089ea7073d..0000000000000000000000000000000000000000 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Lantiq XRX200 PHY Firmware Loader - * Author: John Crispin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * Copyright (C) 2012 John Crispin - */ - -#include -#include -#include -#include - -#include - -#define XRX200_GPHY_FW_ALIGN (16 * 1024) - -static dma_addr_t xway_gphy_load(struct platform_device *pdev) -{ - const struct firmware *fw; - dma_addr_t dev_addr = 0; - const char *fw_name; - void *fw_addr; - size_t size; - - if (of_get_property(pdev->dev.of_node, "firmware1", NULL) || - of_get_property(pdev->dev.of_node, "firmware2", NULL)) { - switch (ltq_soc_type()) { - case SOC_TYPE_VR9: - if (of_property_read_string(pdev->dev.of_node, - "firmware1", &fw_name)) { - dev_err(&pdev->dev, - "failed to load firmware filename\n"); - return 0; - } - break; - case SOC_TYPE_VR9_2: - if (of_property_read_string(pdev->dev.of_node, - "firmware2", &fw_name)) { - dev_err(&pdev->dev, - "failed to load firmware filename\n"); - return 0; - } - break; - } - } else if (of_property_read_string(pdev->dev.of_node, - "firmware", &fw_name)) { - dev_err(&pdev->dev, "failed to load firmware filename\n"); - return 0; - } - - dev_info(&pdev->dev, "requesting %s\n", fw_name); - if (request_firmware(&fw, fw_name, &pdev->dev)) { - dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name); - return 0; - } - - /* - * GPHY cores need the firmware code in a persistent and contiguous - * memory area with a 16 kB boundary aligned start address - */ - size = fw->size + XRX200_GPHY_FW_ALIGN; - - fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL); - if (fw_addr) { - fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN); - dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN); - memcpy(fw_addr, fw->data, fw->size); - } else { - dev_err(&pdev->dev, "failed to alloc firmware memory\n"); - } - - release_firmware(fw); - return dev_addr; -} - -static int xway_phy_fw_probe(struct platform_device *pdev) -{ - dma_addr_t fw_addr; - struct property *pp; - unsigned char *phyids; - int i, ret = 0; - - fw_addr = xway_gphy_load(pdev); - if (!fw_addr) - return -EINVAL; - pp = of_find_property(pdev->dev.of_node, "phys", NULL); - if (!pp) - return -ENOENT; - phyids = pp->value; - for (i = 0; i < pp->length && !ret; i++) - ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr); - if (!ret) - mdelay(100); - return ret; -} - -static const struct of_device_id xway_phy_match[] = { - { .compatible = "lantiq,phy-xrx200" }, - {}, -}; - -static struct platform_driver xway_phy_driver = { - .probe = xway_phy_fw_probe, - .driver = { - .name = "phy-xrx200", - .of_match_table = xway_phy_match, - }, -}; -builtin_platform_driver(xway_phy_driver); diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index a37fe3d1ee2fbd6b0b0c52fb954daed9f8dfc03e..6ab430d245758abeb74533b9aa9d85c123fad454 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -6,7 +6,7 @@ lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ mips-atomic.o strncpy_user.o \ strnlen_user.o uncached.o -obj-y += iomap.o +obj-y += iomap.o iomap_copy.o obj-$(CONFIG_PCI) += iomap-pci.o lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y)) diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 2307a3cb2714fca0819cfb7727eca41650f51fbf..68c495ed71e303f4bb83bd5cac88d04c73b2a2a9 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2007, 2014 Maciej W. Rozycki */ +#include #include #include #include diff --git a/arch/mips/lib/iomap_copy.c b/arch/mips/lib/iomap_copy.c new file mode 100644 index 0000000000000000000000000000000000000000..368bb38267c58a5ddab15d02ae8909fd7591d630 --- /dev/null +++ b/arch/mips/lib/iomap_copy.c @@ -0,0 +1,42 @@ +/* + * This file is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +/** + * __ioread64_copy - copy data from MMIO space, in 64-bit units + * @to: destination (must be 64-bit aligned) + * @from: source, in MMIO space (must be 64-bit aligned) + * @count: number of 64-bit quantities to copy + * + * Copy data from MMIO space to kernel space, in units of 32 or 64 bits at a + * time. Order of access is not guaranteed, nor is a memory barrier + * performed afterwards. + */ +void __ioread64_copy(void *to, const void __iomem *from, size_t count) +{ +#ifdef CONFIG_64BIT + u64 *dst = to; + const u64 __iomem *src = from; + const u64 __iomem *end = src + count; + + while (src < end) + *dst++ = __raw_readq(src++); +#else + __ioread32_copy(to, from, count * 2); +#endif +} +EXPORT_SYMBOL_GPL(__ioread64_copy); diff --git a/arch/mips/loongson64/lemote-2f/clock.c b/arch/mips/loongson64/lemote-2f/clock.c index a78fb657068cb39fc785e241f9b70aeaa412a09b..8281334df9c86429039501dcd361aeca44141c83 100644 --- a/arch/mips/loongson64/lemote-2f/clock.c +++ b/arch/mips/loongson64/lemote-2f/clock.c @@ -80,6 +80,9 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return (unsigned long)clk->rate; } EXPORT_SYMBOL(clk_get_rate); diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index b7a355c3c40813b45aa29940471bfa7148aa643a..8501109bb0f0f5bb70f7a4907431ff0c54c13e65 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -319,8 +319,8 @@ static void loongson3_init_secondary(void) loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); per_cpu(cpu_state, cpu) = CPU_ONLINE; - cpu_data[cpu].core = - cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_set_core(&cpu_data[cpu], + cpu_logical_map(cpu) % loongson_sysconf.cores_per_package); cpu_data[cpu].package = cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; @@ -386,7 +386,8 @@ static void __init loongson3_smp_setup(void) ipi_status0_regs_init(); ipi_en0_regs_init(); ipi_mailbox_buf_init(); - cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; + cpu_set_core(&cpu_data[0], + cpu_logical_map(0) % loongson_sysconf.cores_per_package); cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; } @@ -399,7 +400,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus) /* * Setup the PC, SP, and GP of a secondary processor and start it runing! */ -static void loongson3_boot_secondary(int cpu, struct task_struct *idle) +static int loongson3_boot_secondary(int cpu, struct task_struct *idle) { unsigned long startargs[4]; @@ -422,6 +423,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); + return 0; } #ifdef CONFIG_HOTPLUG_CPU @@ -697,7 +699,7 @@ void play_dead(void) static int loongson3_disable_clock(unsigned int cpu) { - uint64_t core_id = cpu_data[cpu].core; + uint64_t core_id = cpu_core(&cpu_data[cpu]); uint64_t package_id = cpu_data[cpu].package; if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { @@ -711,7 +713,7 @@ static int loongson3_disable_clock(unsigned int cpu) static int loongson3_enable_clock(unsigned int cpu) { - uint64_t core_id = cpu_data[cpu].core; + uint64_t core_id = cpu_core(&cpu_data[cpu]); uint64_t package_id = cpu_data[cpu].package; if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { @@ -734,7 +736,7 @@ early_initcall(register_loongson3_notifier); #endif -struct plat_smp_ops loongson3_smp_ops = { +const struct plat_smp_ops loongson3_smp_ops = { .send_ipi_single = loongson3_send_ipi_single, .send_ipi_mask = loongson3_send_ipi_mask, .init_secondary = loongson3_init_secondary, diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile index e9bbc2a6526fa57072b0b4299ec1a230bfe01c29..e9f10b88b695baa01ec6f3cc52bd46d3742994ff 100644 --- a/arch/mips/math-emu/Makefile +++ b/arch/mips/math-emu/Makefile @@ -4,9 +4,11 @@ obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \ - dp_tint.o dp_fint.o dp_maddf.o dp_2008class.o dp_fmin.o dp_fmax.o \ + dp_tint.o dp_fint.o dp_rint.o dp_maddf.o dp_2008class.o dp_fmin.o \ + dp_fmax.o \ sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \ - sp_tint.o sp_fint.o sp_maddf.o sp_2008class.o sp_fmin.o sp_fmax.o \ + sp_tint.o sp_fint.o sp_rint.o sp_maddf.o sp_2008class.o sp_fmin.o \ + sp_fmax.o \ dsemul.o lib-y += ieee754d.o \ diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index f08a7b4facb9d2011d045030e58cef82e49d4fdb..192542dbd9724788838a74cb5ed4b8404b0d83fc 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -58,7 +58,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, mips_instruction); static int fpux_emu(struct pt_regs *, - struct mips_fpu_struct *, mips_instruction, void *__user *); + struct mips_fpu_struct *, mips_instruction, void __user **); /* Control registers */ @@ -830,12 +830,12 @@ do { \ } while (0) #define DIFROMREG(di, x) \ - ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0)) + ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0)) #define DITOREG(di, x) \ do { \ unsigned fpr, i; \ - fpr = (x) & ~(cop1_64bit(xcp) == 0); \ + fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \ set_fpr64(&ctx->fpr[fpr], 0, di); \ for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \ set_fpr64(&ctx->fpr[fpr], i, 0); \ @@ -973,7 +973,7 @@ static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx, */ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - struct mm_decoded_insn dec_insn, void *__user *fault_addr) + struct mm_decoded_insn dec_insn, void __user **fault_addr) { unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; unsigned int cond, cbit, bit0; @@ -1195,9 +1195,11 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, bit0 = get_fpr32(fpr, 0) & 0x1; switch (MIPSInst_RS(ir)) { case bc1eqz_op: + MIPS_FPU_EMU_INC_STATS(bc1eqz); cond = bit0 == 0; break; case bc1nez_op: + MIPS_FPU_EMU_INC_STATS(bc1nez); cond = bit0 != 0; break; } @@ -1230,6 +1232,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, break; } branch_common: + MIPS_FPU_EMU_INC_STATS(branches); set_delay_slot(xcp); if (cond) { /* @@ -1460,7 +1463,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - mips_instruction ir, void *__user *fault_addr) + mips_instruction ir, void __user **fault_addr) { unsigned rcsr = 0; /* resulting csr */ @@ -1682,15 +1685,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, switch (MIPSInst_FUNC(ir)) { /* binary ops */ case fadd_op: + MIPS_FPU_EMU_INC_STATS(add_s); handler.b = ieee754sp_add; goto scopbop; case fsub_op: + MIPS_FPU_EMU_INC_STATS(sub_s); handler.b = ieee754sp_sub; goto scopbop; case fmul_op: + MIPS_FPU_EMU_INC_STATS(mul_s); handler.b = ieee754sp_mul; goto scopbop; case fdiv_op: + MIPS_FPU_EMU_INC_STATS(div_s); handler.b = ieee754sp_div; goto scopbop; @@ -1699,6 +1706,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sqrt_s); handler.u = ieee754sp_sqrt; goto scopuop; @@ -1711,6 +1719,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rsqrt_s); handler.u = fpemu_sp_rsqrt; goto scopuop; @@ -1718,6 +1727,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(recip_s); handler.u = fpemu_sp_recip; goto scopuop; @@ -1754,6 +1764,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(seleqz_s); SPFROMREG(rv.s, MIPSInst_FT(ir)); if (rv.w & 0x1) rv.w = 0; @@ -1765,6 +1776,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(selnez_s); SPFROMREG(rv.s, MIPSInst_FT(ir)); if (rv.w & 0x1) SPFROMREG(rv.s, MIPSInst_FS(ir)); @@ -1778,6 +1790,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maddf_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fd, MIPSInst_FD(ir)); @@ -1791,6 +1804,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(msubf_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fd, MIPSInst_FD(ir)); @@ -1804,9 +1818,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rint_s); SPFROMREG(fs, MIPSInst_FS(ir)); - rv.l = ieee754sp_tlong(fs); - rv.s = ieee754sp_flong(rv.l); + rv.s = ieee754sp_rint(fs); goto copcsr; } @@ -1816,6 +1830,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(class_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.w = ieee754sp_2008class(fs); rfmt = w_fmt; @@ -1828,6 +1843,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(min_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmin(fs, ft); @@ -1840,6 +1856,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(mina_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmina(fs, ft); @@ -1852,6 +1869,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(max_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmax(fs, ft); @@ -1864,6 +1882,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maxa_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmaxa(fs, ft); @@ -1871,15 +1890,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, } case fabs_op: + MIPS_FPU_EMU_INC_STATS(abs_s); handler.u = ieee754sp_abs; goto scopuop; case fneg_op: + MIPS_FPU_EMU_INC_STATS(neg_s); handler.u = ieee754sp_neg; goto scopuop; case fmov_op: /* an easy one */ + MIPS_FPU_EMU_INC_STATS(mov_s); SPFROMREG(rv.s, MIPSInst_FS(ir)); goto copcsr; @@ -1922,12 +1944,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, return SIGILL; /* not defined */ case fcvtd_op: + MIPS_FPU_EMU_INC_STATS(cvt_d_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fsp(fs); rfmt = d_fmt; goto copcsr; case fcvtw_op: + MIPS_FPU_EMU_INC_STATS(cvt_w_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.w = ieee754sp_tint(fs); rfmt = w_fmt; @@ -1940,6 +1964,15 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + if (MIPSInst_FUNC(ir) == fceil_op) + MIPS_FPU_EMU_INC_STATS(ceil_w_s); + if (MIPSInst_FUNC(ir) == ffloor_op) + MIPS_FPU_EMU_INC_STATS(floor_w_s); + if (MIPSInst_FUNC(ir) == fround_op) + MIPS_FPU_EMU_INC_STATS(round_w_s); + if (MIPSInst_FUNC(ir) == ftrunc_op) + MIPS_FPU_EMU_INC_STATS(trunc_w_s); + oldrm = ieee754_csr.rm; SPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -1952,6 +1985,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sel_s); SPFROMREG(fd, MIPSInst_FD(ir)); if (fd.bits & 0x1) SPFROMREG(rv.s, MIPSInst_FT(ir)); @@ -1963,6 +1997,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(cvt_l_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.l = ieee754sp_tlong(fs); rfmt = l_fmt; @@ -1975,6 +2010,15 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + if (MIPSInst_FUNC(ir) == fceill_op) + MIPS_FPU_EMU_INC_STATS(ceil_l_s); + if (MIPSInst_FUNC(ir) == ffloorl_op) + MIPS_FPU_EMU_INC_STATS(floor_l_s); + if (MIPSInst_FUNC(ir) == froundl_op) + MIPS_FPU_EMU_INC_STATS(round_l_s); + if (MIPSInst_FUNC(ir) == ftruncl_op) + MIPS_FPU_EMU_INC_STATS(trunc_l_s); + oldrm = ieee754_csr.rm; SPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -2016,15 +2060,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, switch (MIPSInst_FUNC(ir)) { /* binary ops */ case fadd_op: + MIPS_FPU_EMU_INC_STATS(add_d); handler.b = ieee754dp_add; goto dcopbop; case fsub_op: + MIPS_FPU_EMU_INC_STATS(sub_d); handler.b = ieee754dp_sub; goto dcopbop; case fmul_op: + MIPS_FPU_EMU_INC_STATS(mul_d); handler.b = ieee754dp_mul; goto dcopbop; case fdiv_op: + MIPS_FPU_EMU_INC_STATS(div_d); handler.b = ieee754dp_div; goto dcopbop; @@ -2033,6 +2081,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sqrt_d); handler.u = ieee754dp_sqrt; goto dcopuop; /* @@ -2044,12 +2093,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rsqrt_d); handler.u = fpemu_dp_rsqrt; goto dcopuop; case frecip_op: if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(recip_d); handler.u = fpemu_dp_recip; goto dcopuop; case fmovc_op: @@ -2083,6 +2134,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(seleqz_d); DPFROMREG(rv.d, MIPSInst_FT(ir)); if (rv.l & 0x1) rv.l = 0; @@ -2094,6 +2146,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(selnez_d); DPFROMREG(rv.d, MIPSInst_FT(ir)); if (rv.l & 0x1) DPFROMREG(rv.d, MIPSInst_FS(ir)); @@ -2107,6 +2160,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maddf_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fd, MIPSInst_FD(ir)); @@ -2120,6 +2174,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(msubf_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fd, MIPSInst_FD(ir)); @@ -2133,9 +2188,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rint_d); DPFROMREG(fs, MIPSInst_FS(ir)); - rv.l = ieee754dp_tlong(fs); - rv.d = ieee754dp_flong(rv.l); + rv.d = ieee754dp_rint(fs); goto copcsr; } @@ -2145,9 +2200,10 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(class_d); DPFROMREG(fs, MIPSInst_FS(ir)); - rv.w = ieee754dp_2008class(fs); - rfmt = w_fmt; + rv.l = ieee754dp_2008class(fs); + rfmt = l_fmt; break; } @@ -2157,6 +2213,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(min_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmin(fs, ft); @@ -2169,6 +2226,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(mina_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmina(fs, ft); @@ -2181,6 +2239,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(max_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmax(fs, ft); @@ -2193,6 +2252,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maxa_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmaxa(fs, ft); @@ -2200,15 +2260,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, } case fabs_op: + MIPS_FPU_EMU_INC_STATS(abs_d); handler.u = ieee754dp_abs; goto dcopuop; case fneg_op: + MIPS_FPU_EMU_INC_STATS(neg_d); handler.u = ieee754dp_neg; goto dcopuop; case fmov_op: /* an easy one */ + MIPS_FPU_EMU_INC_STATS(mov_d); DPFROMREG(rv.d, MIPSInst_FS(ir)); goto copcsr; @@ -2228,6 +2291,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, * unary conv ops */ case fcvts_op: + MIPS_FPU_EMU_INC_STATS(cvt_s_d); DPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fdp(fs); rfmt = s_fmt; @@ -2237,6 +2301,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, return SIGILL; /* not defined */ case fcvtw_op: + MIPS_FPU_EMU_INC_STATS(cvt_w_d); DPFROMREG(fs, MIPSInst_FS(ir)); rv.w = ieee754dp_tint(fs); /* wrong */ rfmt = w_fmt; @@ -2249,6 +2314,15 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + if (MIPSInst_FUNC(ir) == fceil_op) + MIPS_FPU_EMU_INC_STATS(ceil_w_d); + if (MIPSInst_FUNC(ir) == ffloor_op) + MIPS_FPU_EMU_INC_STATS(floor_w_d); + if (MIPSInst_FUNC(ir) == fround_op) + MIPS_FPU_EMU_INC_STATS(round_w_d); + if (MIPSInst_FUNC(ir) == ftrunc_op) + MIPS_FPU_EMU_INC_STATS(trunc_w_d); + oldrm = ieee754_csr.rm; DPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -2261,6 +2335,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sel_d); DPFROMREG(fd, MIPSInst_FD(ir)); if (fd.bits & 0x1) DPFROMREG(rv.d, MIPSInst_FT(ir)); @@ -2272,6 +2347,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(cvt_l_d); DPFROMREG(fs, MIPSInst_FS(ir)); rv.l = ieee754dp_tlong(fs); rfmt = l_fmt; @@ -2284,6 +2360,15 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + if (MIPSInst_FUNC(ir) == fceill_op) + MIPS_FPU_EMU_INC_STATS(ceil_l_d); + if (MIPSInst_FUNC(ir) == ffloorl_op) + MIPS_FPU_EMU_INC_STATS(floor_l_d); + if (MIPSInst_FUNC(ir) == froundl_op) + MIPS_FPU_EMU_INC_STATS(round_l_d); + if (MIPSInst_FUNC(ir) == ftruncl_op) + MIPS_FPU_EMU_INC_STATS(trunc_l_d); + oldrm = ieee754_csr.rm; DPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -2325,12 +2410,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, switch (MIPSInst_FUNC(ir)) { case fcvts_op: /* convert word to single precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_s_w); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fint(fs.bits); rfmt = s_fmt; goto copcsr; case fcvtd_op: /* convert word to double precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_d_w); SPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fint(fs.bits); rfmt = d_fmt; @@ -2350,6 +2437,90 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, (MIPSInst_FUNC(ir) & 0x20)) return SIGILL; + if (!sig) { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_af_s); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_un_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_eq_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ueq_s); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_lt_s); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_ult_s); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_le_s); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_ule_s); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_or_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_une_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ne_s); + break; + } + } + } else { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_saf_s); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sun_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_seq_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sueq_s); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_slt_s); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_sult_s); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_sle_s); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_sule_s); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sor_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_sune_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sne_s); + break; + } + } + } + /* fmt is w_fmt for single precision so fix it */ rfmt = s_fmt; /* default to false */ @@ -2394,6 +2565,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, break; } } + break; } case l_fmt: @@ -2406,11 +2578,13 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, switch (MIPSInst_FUNC(ir)) { case fcvts_op: /* convert long to single precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_s_l); rv.s = ieee754sp_flong(bits); rfmt = s_fmt; goto copcsr; case fcvtd_op: /* convert long to double precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_d_l); rv.d = ieee754dp_flong(bits); rfmt = d_fmt; goto copcsr; @@ -2424,6 +2598,90 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, (MIPSInst_FUNC(ir) & 0x20)) return SIGILL; + if (!sig) { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_af_d); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_un_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_eq_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ueq_d); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_lt_d); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_ult_d); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_le_d); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_ule_d); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_or_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_une_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ne_d); + break; + } + } + } else { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_saf_d); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sun_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_seq_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sueq_d); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_slt_d); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_sult_d); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_sle_d); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_sule_d); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sor_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_sune_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sne_d); + break; + } + } + } + /* fmt is l_fmt for double precision so fix it */ rfmt = d_fmt; /* default to false */ @@ -2468,6 +2726,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, break; } } + break; + default: return SIGILL; } @@ -2553,7 +2813,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, * For simplicity we always terminate upon an ISA mode switch. */ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - int has_fpu, void *__user *fault_addr) + int has_fpu, void __user **fault_addr) { unsigned long oldepc, prevepc; struct mm_decoded_insn dec_insn; diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c index fd71b8daaaf20525abfb4470f6892fc1dddc5cd1..5bec64f2884eb14103e53726e42a6e29563ff6b5 100644 --- a/arch/mips/math-emu/dp_fmax.c +++ b/arch/mips/math-emu/dp_fmax.c @@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) return ys ? x : y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) else if (xs < ys) return x; - /* Compare exponent */ - if (xe > ye) - return x; - else if (xe < ye) - return y; + /* Signs of inputs are equal, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } else { + /* Inputs are both negative */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return y; + return x; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return y; - return x; + return x; + return y; } union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) @@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754dp_inf(xs & ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): @@ -171,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): return x; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): @@ -180,9 +220,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) return y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) return y; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) return y; - return x; + else if (xm > ym) + return x; + else if (xs == 0) + return x; + return y; } diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c index c1072b0dfb9519dad2b5e0d8b79d2199012d1213..a287b23818d82ed0cf59f9066032619dea8f991a 100644 --- a/arch/mips/math-emu/dp_fmin.c +++ b/arch/mips/math-emu/dp_fmin.c @@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) return ys ? y : x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) else if (xs < ys) return y; - /* Compare exponent */ - if (xe > ye) - return y; - else if (xe < ye) - return x; + /* Signs of inputs are the same, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } else { + /* Inputs are both negative */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return x; + return y; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return x; - return y; + return y; + return x; } union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) @@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,25 +202,25 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754dp_inf(xs | ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; + return y; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return y; + return x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) return x; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) + return x; + else if (xm > ym) + return y; + else if (xs == 1) return x; return y; } diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c index caa62f20a888d120dc22ec187aa5693470b9ec22..e0d9be5fbf4cd541406b93c5d2add6814a82a9eb 100644 --- a/arch/mips/math-emu/dp_maddf.c +++ b/arch/mips/math-emu/dp_maddf.c @@ -14,22 +14,45 @@ #include "ieee754dp.h" -enum maddf_flags { - maddf_negate_product = 1 << 0, -}; + +/* 128 bits shift right logical with rounding. */ +void srl128(u64 *hptr, u64 *lptr, int count) +{ + u64 low; + + if (count >= 128) { + *lptr = *hptr != 0 || *lptr != 0; + *hptr = 0; + } else if (count >= 64) { + if (count == 64) { + *lptr = *hptr | (*lptr != 0); + } else { + low = *lptr; + *lptr = *hptr >> (count - 64); + *lptr |= (*hptr << (128 - count)) != 0 || low != 0; + } + *hptr = 0; + } else { + low = *lptr; + *lptr = low >> count | *hptr << (64 - count); + *lptr |= (low << (64 - count)) != 0; + *hptr = *hptr >> count; + } +} static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, union ieee754dp y, enum maddf_flags flags) { int re; int rs; - u64 rm; unsigned lxm; unsigned hxm; unsigned lym; unsigned hym; u64 lrm; u64 hrm; + u64 lzm; + u64 hzm; u64 t; u64 at; int s; @@ -48,52 +71,34 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, ieee754_clearcx(); - switch (zc) { - case IEEE754_CLASS_SNAN: - ieee754_setcx(IEEE754_INVALID_OPERATION); + /* + * Handle the cases when at least one of x, y or z is a NaN. + * Order of precedence is sNaN, qNaN and z, x, y. + */ + if (zc == IEEE754_CLASS_SNAN) return ieee754dp_nanxcpt(z); - case IEEE754_CLASS_DNORM: - DPDNORMZ; - /* QNAN and ZERO cases are handled separately below */ - } - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + if (xc == IEEE754_CLASS_SNAN) return ieee754dp_nanxcpt(x); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + if (yc == IEEE754_CLASS_SNAN) + return ieee754dp_nanxcpt(y); + if (zc == IEEE754_CLASS_QNAN) + return z; + if (xc == IEEE754_CLASS_QNAN) + return x; + if (yc == IEEE754_CLASS_QNAN) return y; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; + if (zc == IEEE754_CLASS_DNORM) + DPDNORMZ; + /* ZERO z cases are handled separately below */ + switch (CLPAIR(xc, yc)) { /* * Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; ieee754_setcx(IEEE754_INVALID_OPERATION); return ieee754dp_indef(); @@ -102,9 +107,27 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; - return ieee754dp_inf(xs ^ ys); + if ((zc == IEEE754_CLASS_INF) && + ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { + /* + * Cases of addition of infinities with opposite signs + * or subtraction of infinities with same signs. + */ + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754dp_indef(); + } + /* + * z is here either not an infinity, or an infinity having the + * same sign as product (x*y) (in case of MADDF.D instruction) + * or product -(x*y) (in MSUBF.D case). The result must be an + * infinity, and its sign is determined only by the value of + * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. + */ + if (flags & MADDF_NEGATE_PRODUCT) + return ieee754dp_inf(1 ^ (xs ^ ys)); + else + return ieee754dp_inf(xs ^ ys); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): @@ -113,32 +136,42 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); - /* Multiplication is 0 so just return z */ + if (zc == IEEE754_CLASS_ZERO) { + /* Handle cases +0 + (-0) and similar ones. */ + if ((!(flags & MADDF_NEGATE_PRODUCT) + && (zs == (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) + && (zs != (xs ^ ys)))) + /* + * Cases of addition of zeros of equal signs + * or subtraction of zeroes of opposite signs. + * The sign of the resulting zero is in any + * such case determined only by the sign of z. + */ + return z; + + return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); + } + /* x*y is here 0, and z is not 0, so just return z */ return z; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); DPDNORMY; break; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); DPDNORMX; break; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); /* fall through to real computations */ } @@ -157,7 +190,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, re = xe + ye; rs = xs ^ ys; - if (flags & maddf_negate_product) + if (flags & MADDF_NEGATE_PRODUCT) rs ^= 1; /* shunt to top of word */ @@ -165,7 +198,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, ym <<= 64 - (DP_FBITS + 1); /* - * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. + * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm. */ /* 32 * 32 => 64 */ @@ -195,81 +228,110 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, hrm = hrm + (t >> 32); - rm = hrm | (lrm != 0); - - /* - * Sticky shift down to normal rounding precision. - */ - if ((s64) rm < 0) { - rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | - ((rm << (DP_FBITS + 1 + 3)) != 0); + /* Put explicit bit at bit 126 if necessary */ + if ((int64_t)hrm < 0) { + lrm = (hrm << 63) | (lrm >> 1); + hrm = hrm >> 1; re++; - } else { - rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | - ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); } - assert(rm & (DP_HIDDEN_BIT << 3)); - if (zc == IEEE754_CLASS_ZERO) - return ieee754dp_format(rs, re, rm); + assert(hrm & (1 << 62)); - /* And now the addition */ - assert(zm & DP_HIDDEN_BIT); + if (zc == IEEE754_CLASS_ZERO) { + /* + * Move explicit bit from bit 126 to bit 55 since the + * ieee754dp_format code expects the mantissa to be + * 56 bits wide (53 + 3 rounding bits). + */ + srl128(&hrm, &lrm, (126 - 55)); + return ieee754dp_format(rs, re, lrm); + } - /* - * Provide guard,round and stick bit space. - */ - zm <<= 3; + /* Move explicit bit from bit 52 to bit 126 */ + lzm = 0; + hzm = zm << 10; + assert(hzm & (1 << 62)); + /* Make the exponents the same */ if (ze > re) { /* * Have to shift y fraction right to align. */ s = ze - re; - rm = XDPSRS(rm, s); + srl128(&hrm, &lrm, s); re += s; } else if (re > ze) { /* * Have to shift x fraction right to align. */ s = re - ze; - zm = XDPSRS(zm, s); + srl128(&hzm, &lzm, s); ze += s; } assert(ze == re); assert(ze <= DP_EMAX); + /* Do the addition */ if (zs == rs) { /* - * Generate 28 bit result of adding two 27 bit numbers - * leaving result in xm, xs and xe. + * Generate 128 bit result by adding two 127 bit numbers + * leaving result in hzm:lzm, zs and ze. */ - zm = zm + rm; - - if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */ - zm = XDPSRS1(zm); + hzm = hzm + hrm + (lzm > (lzm + lrm)); + lzm = lzm + lrm; + if ((int64_t)hzm < 0) { /* carry out */ + srl128(&hzm, &lzm, 1); ze++; } } else { - if (zm >= rm) { - zm = zm - rm; + if (hzm > hrm || (hzm == hrm && lzm >= lrm)) { + hzm = hzm - hrm - (lzm < lrm); + lzm = lzm - lrm; } else { - zm = rm - zm; + hzm = hrm - hzm - (lrm < lzm); + lzm = lrm - lzm; zs = rs; } - if (zm == 0) + if (lzm == 0 && hzm == 0) return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); /* - * Normalize to rounding precision. + * Put explicit bit at bit 126 if necessary. */ - while ((zm >> (DP_FBITS + 3)) == 0) { - zm <<= 1; - ze--; + if (hzm == 0) { + /* left shift by 63 or 64 bits */ + if ((int64_t)lzm < 0) { + /* MSB of lzm is the explicit bit */ + hzm = lzm >> 1; + lzm = lzm << 63; + ze -= 63; + } else { + hzm = lzm; + lzm = 0; + ze -= 64; + } + } + + t = 0; + while ((hzm >> (62 - t)) == 0) + t++; + + assert(t <= 62); + if (t) { + hzm = hzm << t | lzm >> (64 - t); + lzm = lzm << t; + ze -= t; } } - return ieee754dp_format(zs, ze, zm); + /* + * Move explicit bit from bit 126 to bit 55 since the + * ieee754dp_format code expects the mantissa to be + * 56 bits wide (53 + 3 rounding bits). + */ + srl128(&hzm, &lzm, (126 - 55)); + + return ieee754dp_format(zs, ze, lzm); } union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, @@ -281,5 +343,5 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, union ieee754dp y) { - return _dp_maddf(z, x, y, maddf_negate_product); + return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); } diff --git a/arch/mips/math-emu/dp_rint.c b/arch/mips/math-emu/dp_rint.c new file mode 100644 index 0000000000000000000000000000000000000000..c3b9077ff3575a64b9c123f79ec9afd5794815d3 --- /dev/null +++ b/arch/mips/math-emu/dp_rint.c @@ -0,0 +1,89 @@ +/* IEEE754 floating point arithmetic + * double precision: common utilities + */ +/* + * MIPS floating point support + * Copyright (C) 1994-2000 Algorithmics Ltd. + * Copyright (C) 2017 Imagination Technologies, Ltd. + * Author: Aleksandar Markovic + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. + */ + +#include "ieee754dp.h" + +union ieee754dp ieee754dp_rint(union ieee754dp x) +{ + union ieee754dp ret; + u64 residue; + int sticky; + int round; + int odd; + + COMPXDP; + + ieee754_clearcx(); + + EXPLODEXDP; + FLUSHXDP; + + if (xc == IEEE754_CLASS_SNAN) + return ieee754dp_nanxcpt(x); + + if ((xc == IEEE754_CLASS_QNAN) || + (xc == IEEE754_CLASS_INF) || + (xc == IEEE754_CLASS_ZERO)) + return x; + + if (xe >= DP_FBITS) + return x; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } else { + residue = xm << (64 - DP_FBITS + xe); + round = (residue >> 63) != 0; + sticky = (residue << 1) != 0; + xm >>= DP_FBITS - xe; + } + + odd = (xm & 0x1) != 0x0; + + switch (ieee754_csr.rm) { + case FPU_CSR_RN: /* toward nearest */ + if (round && (sticky || odd)) + xm++; + break; + case FPU_CSR_RZ: /* toward zero */ + break; + case FPU_CSR_RU: /* toward +infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case FPU_CSR_RD: /* toward -infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + + if (round || sticky) + ieee754_setcx(IEEE754_INEXACT); + + ret = ieee754dp_flong(xm); + DPSIGN(ret) = xs; + + return ret; +} diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h index d3be351aed151305396723ddfff661837a114cde..92dc8fa565cb9fe5923cced32efb0e534b957d5a 100644 --- a/arch/mips/math-emu/ieee754.h +++ b/arch/mips/math-emu/ieee754.h @@ -67,6 +67,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y); union ieee754sp ieee754sp_fint(int x); union ieee754sp ieee754sp_flong(s64 x); union ieee754sp ieee754sp_fdp(union ieee754dp x); +union ieee754sp ieee754sp_rint(union ieee754sp x); int ieee754sp_tint(union ieee754sp x); s64 ieee754sp_tlong(union ieee754sp x); @@ -101,6 +102,7 @@ union ieee754dp ieee754dp_neg(union ieee754dp x); union ieee754dp ieee754dp_fint(int x); union ieee754dp ieee754dp_flong(s64 x); union ieee754dp ieee754dp_fsp(union ieee754sp x); +union ieee754dp ieee754dp_rint(union ieee754dp x); int ieee754dp_tint(union ieee754dp x); s64 ieee754dp_tlong(union ieee754dp x); diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h index 8bc2f6963324de776a3ab66ec33638e2b8598211..dd2071f430e0bd180dce8e79bbf00df77b7318dc 100644 --- a/arch/mips/math-emu/ieee754int.h +++ b/arch/mips/math-emu/ieee754int.h @@ -26,6 +26,10 @@ #define CLPAIR(x, y) ((x)*6+(y)) +enum maddf_flags { + MADDF_NEGATE_PRODUCT = 1 << 0, +}; + static inline void ieee754_clearcx(void) { ieee754_csr.cx = 0; diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h index 8476067075fe013331609ed3db1028b04b9d3e66..0f63e4202cffa214009b0b29c041690645159267 100644 --- a/arch/mips/math-emu/ieee754sp.h +++ b/arch/mips/math-emu/ieee754sp.h @@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union ieee754sp x) return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; } +/* 64 bit right shift with rounding */ +#define XSPSRS64(v, rs) \ + (((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0)) + /* 3bit extended single precision sticky right shift */ #define XSPSRS(v, rs) \ ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0)) diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c index be650ed7db596bb8b586c7b65bfdddce56f65b3b..8c0ec154aecc1061a2887bb6d993ed1ced446a99 100644 --- a/arch/mips/math-emu/me-debugfs.c +++ b/arch/mips/math-emu/me-debugfs.c @@ -28,14 +28,190 @@ static int fpuemu_stat_get(void *data, u64 *val) } DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); +/* + * Used to obtain names for a debugfs instruction counter, given field name + * in fpuemustats structure. For example, for input "cmp_sueq_d", the output + * would be "cmp.sueq.d". This is needed since dots are not allowed to be + * used in structure field names, and are, on the other hand, desired to be + * used in debugfs item names to be clearly associated to corresponding + * MIPS FPU instructions. + */ +static void adjust_instruction_counter_name(char *out_name, char *in_name) +{ + int i = 0; + + strcpy(out_name, in_name); + while (in_name[i] != '\0') { + if (out_name[i] == '_') + out_name[i] = '.'; + i++; + } +} + +static int fpuemustats_clear_show(struct seq_file *s, void *unused) +{ + __this_cpu_write((fpuemustats).emulated, 0); + __this_cpu_write((fpuemustats).loads, 0); + __this_cpu_write((fpuemustats).stores, 0); + __this_cpu_write((fpuemustats).branches, 0); + __this_cpu_write((fpuemustats).cp1ops, 0); + __this_cpu_write((fpuemustats).cp1xops, 0); + __this_cpu_write((fpuemustats).errors, 0); + __this_cpu_write((fpuemustats).ieee754_inexact, 0); + __this_cpu_write((fpuemustats).ieee754_underflow, 0); + __this_cpu_write((fpuemustats).ieee754_overflow, 0); + __this_cpu_write((fpuemustats).ieee754_zerodiv, 0); + __this_cpu_write((fpuemustats).ieee754_invalidop, 0); + __this_cpu_write((fpuemustats).ds_emul, 0); + + __this_cpu_write((fpuemustats).abs_s, 0); + __this_cpu_write((fpuemustats).abs_d, 0); + __this_cpu_write((fpuemustats).add_s, 0); + __this_cpu_write((fpuemustats).add_d, 0); + __this_cpu_write((fpuemustats).bc1eqz, 0); + __this_cpu_write((fpuemustats).bc1nez, 0); + __this_cpu_write((fpuemustats).ceil_w_s, 0); + __this_cpu_write((fpuemustats).ceil_w_d, 0); + __this_cpu_write((fpuemustats).ceil_l_s, 0); + __this_cpu_write((fpuemustats).ceil_l_d, 0); + __this_cpu_write((fpuemustats).class_s, 0); + __this_cpu_write((fpuemustats).class_d, 0); + __this_cpu_write((fpuemustats).cmp_af_s, 0); + __this_cpu_write((fpuemustats).cmp_af_d, 0); + __this_cpu_write((fpuemustats).cmp_eq_s, 0); + __this_cpu_write((fpuemustats).cmp_eq_d, 0); + __this_cpu_write((fpuemustats).cmp_le_s, 0); + __this_cpu_write((fpuemustats).cmp_le_d, 0); + __this_cpu_write((fpuemustats).cmp_lt_s, 0); + __this_cpu_write((fpuemustats).cmp_lt_d, 0); + __this_cpu_write((fpuemustats).cmp_ne_s, 0); + __this_cpu_write((fpuemustats).cmp_ne_d, 0); + __this_cpu_write((fpuemustats).cmp_or_s, 0); + __this_cpu_write((fpuemustats).cmp_or_d, 0); + __this_cpu_write((fpuemustats).cmp_ueq_s, 0); + __this_cpu_write((fpuemustats).cmp_ueq_d, 0); + __this_cpu_write((fpuemustats).cmp_ule_s, 0); + __this_cpu_write((fpuemustats).cmp_ule_d, 0); + __this_cpu_write((fpuemustats).cmp_ult_s, 0); + __this_cpu_write((fpuemustats).cmp_ult_d, 0); + __this_cpu_write((fpuemustats).cmp_un_s, 0); + __this_cpu_write((fpuemustats).cmp_un_d, 0); + __this_cpu_write((fpuemustats).cmp_une_s, 0); + __this_cpu_write((fpuemustats).cmp_une_d, 0); + __this_cpu_write((fpuemustats).cmp_saf_s, 0); + __this_cpu_write((fpuemustats).cmp_saf_d, 0); + __this_cpu_write((fpuemustats).cmp_seq_s, 0); + __this_cpu_write((fpuemustats).cmp_seq_d, 0); + __this_cpu_write((fpuemustats).cmp_sle_s, 0); + __this_cpu_write((fpuemustats).cmp_sle_d, 0); + __this_cpu_write((fpuemustats).cmp_slt_s, 0); + __this_cpu_write((fpuemustats).cmp_slt_d, 0); + __this_cpu_write((fpuemustats).cmp_sne_s, 0); + __this_cpu_write((fpuemustats).cmp_sne_d, 0); + __this_cpu_write((fpuemustats).cmp_sor_s, 0); + __this_cpu_write((fpuemustats).cmp_sor_d, 0); + __this_cpu_write((fpuemustats).cmp_sueq_s, 0); + __this_cpu_write((fpuemustats).cmp_sueq_d, 0); + __this_cpu_write((fpuemustats).cmp_sule_s, 0); + __this_cpu_write((fpuemustats).cmp_sule_d, 0); + __this_cpu_write((fpuemustats).cmp_sult_s, 0); + __this_cpu_write((fpuemustats).cmp_sult_d, 0); + __this_cpu_write((fpuemustats).cmp_sun_s, 0); + __this_cpu_write((fpuemustats).cmp_sun_d, 0); + __this_cpu_write((fpuemustats).cmp_sune_s, 0); + __this_cpu_write((fpuemustats).cmp_sune_d, 0); + __this_cpu_write((fpuemustats).cvt_d_l, 0); + __this_cpu_write((fpuemustats).cvt_d_s, 0); + __this_cpu_write((fpuemustats).cvt_d_w, 0); + __this_cpu_write((fpuemustats).cvt_l_s, 0); + __this_cpu_write((fpuemustats).cvt_l_d, 0); + __this_cpu_write((fpuemustats).cvt_s_d, 0); + __this_cpu_write((fpuemustats).cvt_s_l, 0); + __this_cpu_write((fpuemustats).cvt_s_w, 0); + __this_cpu_write((fpuemustats).cvt_w_s, 0); + __this_cpu_write((fpuemustats).cvt_w_d, 0); + __this_cpu_write((fpuemustats).div_s, 0); + __this_cpu_write((fpuemustats).div_d, 0); + __this_cpu_write((fpuemustats).floor_w_s, 0); + __this_cpu_write((fpuemustats).floor_w_d, 0); + __this_cpu_write((fpuemustats).floor_l_s, 0); + __this_cpu_write((fpuemustats).floor_l_d, 0); + __this_cpu_write((fpuemustats).maddf_s, 0); + __this_cpu_write((fpuemustats).maddf_d, 0); + __this_cpu_write((fpuemustats).max_s, 0); + __this_cpu_write((fpuemustats).max_d, 0); + __this_cpu_write((fpuemustats).maxa_s, 0); + __this_cpu_write((fpuemustats).maxa_d, 0); + __this_cpu_write((fpuemustats).min_s, 0); + __this_cpu_write((fpuemustats).min_d, 0); + __this_cpu_write((fpuemustats).mina_s, 0); + __this_cpu_write((fpuemustats).mina_d, 0); + __this_cpu_write((fpuemustats).mov_s, 0); + __this_cpu_write((fpuemustats).mov_d, 0); + __this_cpu_write((fpuemustats).msubf_s, 0); + __this_cpu_write((fpuemustats).msubf_d, 0); + __this_cpu_write((fpuemustats).mul_s, 0); + __this_cpu_write((fpuemustats).mul_d, 0); + __this_cpu_write((fpuemustats).neg_s, 0); + __this_cpu_write((fpuemustats).neg_d, 0); + __this_cpu_write((fpuemustats).recip_s, 0); + __this_cpu_write((fpuemustats).recip_d, 0); + __this_cpu_write((fpuemustats).rint_s, 0); + __this_cpu_write((fpuemustats).rint_d, 0); + __this_cpu_write((fpuemustats).round_w_s, 0); + __this_cpu_write((fpuemustats).round_w_d, 0); + __this_cpu_write((fpuemustats).round_l_s, 0); + __this_cpu_write((fpuemustats).round_l_d, 0); + __this_cpu_write((fpuemustats).rsqrt_s, 0); + __this_cpu_write((fpuemustats).rsqrt_d, 0); + __this_cpu_write((fpuemustats).sel_s, 0); + __this_cpu_write((fpuemustats).sel_d, 0); + __this_cpu_write((fpuemustats).seleqz_s, 0); + __this_cpu_write((fpuemustats).seleqz_d, 0); + __this_cpu_write((fpuemustats).selnez_s, 0); + __this_cpu_write((fpuemustats).selnez_d, 0); + __this_cpu_write((fpuemustats).sqrt_s, 0); + __this_cpu_write((fpuemustats).sqrt_d, 0); + __this_cpu_write((fpuemustats).sub_s, 0); + __this_cpu_write((fpuemustats).sub_d, 0); + __this_cpu_write((fpuemustats).trunc_w_s, 0); + __this_cpu_write((fpuemustats).trunc_w_d, 0); + __this_cpu_write((fpuemustats).trunc_l_s, 0); + __this_cpu_write((fpuemustats).trunc_l_d, 0); + + return 0; +} + +static int fpuemustats_clear_open(struct inode *inode, struct file *file) +{ + return single_open(file, fpuemustats_clear_show, inode->i_private); +} + +static const struct file_operations fpuemustats_clear_fops = { + .open = fpuemustats_clear_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int __init debugfs_fpuemu(void) { - struct dentry *d, *dir; + struct dentry *fpuemu_debugfs_base_dir; + struct dentry *fpuemu_debugfs_inst_dir; + struct dentry *d, *reset_file; if (!mips_debugfs_dir) return -ENODEV; - dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); - if (!dir) + + fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats", + mips_debugfs_dir); + if (!fpuemu_debugfs_base_dir) + return -ENOMEM; + + reset_file = debugfs_create_file("fpuemustats_clear", 0444, + mips_debugfs_dir, NULL, + &fpuemustats_clear_fops); + if (!reset_file) return -ENOMEM; #define FPU_EMU_STAT_OFFSET(m) \ @@ -43,7 +219,7 @@ static int __init debugfs_fpuemu(void) #define FPU_STAT_CREATE(m) \ do { \ - d = debugfs_create_file(#m , S_IRUGO, dir, \ + d = debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \ (void *)FPU_EMU_STAT_OFFSET(m), \ &fops_fpuemu_stat); \ if (!d) \ @@ -53,6 +229,7 @@ do { \ FPU_STAT_CREATE(emulated); FPU_STAT_CREATE(loads); FPU_STAT_CREATE(stores); + FPU_STAT_CREATE(branches); FPU_STAT_CREATE(cp1ops); FPU_STAT_CREATE(cp1xops); FPU_STAT_CREATE(errors); @@ -63,6 +240,139 @@ do { \ FPU_STAT_CREATE(ieee754_invalidop); FPU_STAT_CREATE(ds_emul); + fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions", + fpuemu_debugfs_base_dir); + if (!fpuemu_debugfs_inst_dir) + return -ENOMEM; + +#define FPU_STAT_CREATE_EX(m) \ +do { \ + char name[32]; \ + \ + adjust_instruction_counter_name(name, #m); \ + \ + d = debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \ + (void *)FPU_EMU_STAT_OFFSET(m), \ + &fops_fpuemu_stat); \ + if (!d) \ + return -ENOMEM; \ +} while (0) + + FPU_STAT_CREATE_EX(abs_s); + FPU_STAT_CREATE_EX(abs_d); + FPU_STAT_CREATE_EX(add_s); + FPU_STAT_CREATE_EX(add_d); + FPU_STAT_CREATE_EX(bc1eqz); + FPU_STAT_CREATE_EX(bc1nez); + FPU_STAT_CREATE_EX(ceil_w_s); + FPU_STAT_CREATE_EX(ceil_w_d); + FPU_STAT_CREATE_EX(ceil_l_s); + FPU_STAT_CREATE_EX(ceil_l_d); + FPU_STAT_CREATE_EX(class_s); + FPU_STAT_CREATE_EX(class_d); + FPU_STAT_CREATE_EX(cmp_af_s); + FPU_STAT_CREATE_EX(cmp_af_d); + FPU_STAT_CREATE_EX(cmp_eq_s); + FPU_STAT_CREATE_EX(cmp_eq_d); + FPU_STAT_CREATE_EX(cmp_le_s); + FPU_STAT_CREATE_EX(cmp_le_d); + FPU_STAT_CREATE_EX(cmp_lt_s); + FPU_STAT_CREATE_EX(cmp_lt_d); + FPU_STAT_CREATE_EX(cmp_ne_s); + FPU_STAT_CREATE_EX(cmp_ne_d); + FPU_STAT_CREATE_EX(cmp_or_s); + FPU_STAT_CREATE_EX(cmp_or_d); + FPU_STAT_CREATE_EX(cmp_ueq_s); + FPU_STAT_CREATE_EX(cmp_ueq_d); + FPU_STAT_CREATE_EX(cmp_ule_s); + FPU_STAT_CREATE_EX(cmp_ule_d); + FPU_STAT_CREATE_EX(cmp_ult_s); + FPU_STAT_CREATE_EX(cmp_ult_d); + FPU_STAT_CREATE_EX(cmp_un_s); + FPU_STAT_CREATE_EX(cmp_un_d); + FPU_STAT_CREATE_EX(cmp_une_s); + FPU_STAT_CREATE_EX(cmp_une_d); + FPU_STAT_CREATE_EX(cmp_saf_s); + FPU_STAT_CREATE_EX(cmp_saf_d); + FPU_STAT_CREATE_EX(cmp_seq_s); + FPU_STAT_CREATE_EX(cmp_seq_d); + FPU_STAT_CREATE_EX(cmp_sle_s); + FPU_STAT_CREATE_EX(cmp_sle_d); + FPU_STAT_CREATE_EX(cmp_slt_s); + FPU_STAT_CREATE_EX(cmp_slt_d); + FPU_STAT_CREATE_EX(cmp_sne_s); + FPU_STAT_CREATE_EX(cmp_sne_d); + FPU_STAT_CREATE_EX(cmp_sor_s); + FPU_STAT_CREATE_EX(cmp_sor_d); + FPU_STAT_CREATE_EX(cmp_sueq_s); + FPU_STAT_CREATE_EX(cmp_sueq_d); + FPU_STAT_CREATE_EX(cmp_sule_s); + FPU_STAT_CREATE_EX(cmp_sule_d); + FPU_STAT_CREATE_EX(cmp_sult_s); + FPU_STAT_CREATE_EX(cmp_sult_d); + FPU_STAT_CREATE_EX(cmp_sun_s); + FPU_STAT_CREATE_EX(cmp_sun_d); + FPU_STAT_CREATE_EX(cmp_sune_s); + FPU_STAT_CREATE_EX(cmp_sune_d); + FPU_STAT_CREATE_EX(cvt_d_l); + FPU_STAT_CREATE_EX(cvt_d_s); + FPU_STAT_CREATE_EX(cvt_d_w); + FPU_STAT_CREATE_EX(cvt_l_s); + FPU_STAT_CREATE_EX(cvt_l_d); + FPU_STAT_CREATE_EX(cvt_s_d); + FPU_STAT_CREATE_EX(cvt_s_l); + FPU_STAT_CREATE_EX(cvt_s_w); + FPU_STAT_CREATE_EX(cvt_w_s); + FPU_STAT_CREATE_EX(cvt_w_d); + FPU_STAT_CREATE_EX(div_s); + FPU_STAT_CREATE_EX(div_d); + FPU_STAT_CREATE_EX(floor_w_s); + FPU_STAT_CREATE_EX(floor_w_d); + FPU_STAT_CREATE_EX(floor_l_s); + FPU_STAT_CREATE_EX(floor_l_d); + FPU_STAT_CREATE_EX(maddf_s); + FPU_STAT_CREATE_EX(maddf_d); + FPU_STAT_CREATE_EX(max_s); + FPU_STAT_CREATE_EX(max_d); + FPU_STAT_CREATE_EX(maxa_s); + FPU_STAT_CREATE_EX(maxa_d); + FPU_STAT_CREATE_EX(min_s); + FPU_STAT_CREATE_EX(min_d); + FPU_STAT_CREATE_EX(mina_s); + FPU_STAT_CREATE_EX(mina_d); + FPU_STAT_CREATE_EX(mov_s); + FPU_STAT_CREATE_EX(mov_d); + FPU_STAT_CREATE_EX(msubf_s); + FPU_STAT_CREATE_EX(msubf_d); + FPU_STAT_CREATE_EX(mul_s); + FPU_STAT_CREATE_EX(mul_d); + FPU_STAT_CREATE_EX(neg_s); + FPU_STAT_CREATE_EX(neg_d); + FPU_STAT_CREATE_EX(recip_s); + FPU_STAT_CREATE_EX(recip_d); + FPU_STAT_CREATE_EX(rint_s); + FPU_STAT_CREATE_EX(rint_d); + FPU_STAT_CREATE_EX(round_w_s); + FPU_STAT_CREATE_EX(round_w_d); + FPU_STAT_CREATE_EX(round_l_s); + FPU_STAT_CREATE_EX(round_l_d); + FPU_STAT_CREATE_EX(rsqrt_s); + FPU_STAT_CREATE_EX(rsqrt_d); + FPU_STAT_CREATE_EX(sel_s); + FPU_STAT_CREATE_EX(sel_d); + FPU_STAT_CREATE_EX(seleqz_s); + FPU_STAT_CREATE_EX(seleqz_d); + FPU_STAT_CREATE_EX(selnez_s); + FPU_STAT_CREATE_EX(selnez_d); + FPU_STAT_CREATE_EX(sqrt_s); + FPU_STAT_CREATE_EX(sqrt_d); + FPU_STAT_CREATE_EX(sub_s); + FPU_STAT_CREATE_EX(sub_d); + FPU_STAT_CREATE_EX(trunc_w_s); + FPU_STAT_CREATE_EX(trunc_w_d); + FPU_STAT_CREATE_EX(trunc_l_s); + FPU_STAT_CREATE_EX(trunc_l_d); + return 0; } arch_initcall(debugfs_fpuemu); diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c index 4d000844e48e3d1f7560a3e9dead69ffd9743a2c..74a5a00d2f22b87917cae25c02f9b4f568569dd0 100644 --- a/arch/mips/math-emu/sp_fmax.c +++ b/arch/mips/math-emu/sp_fmax.c @@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) return ys ? x : y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) else if (xs < ys) return x; - /* Compare exponent */ - if (xe > ye) - return x; - else if (xe < ye) - return y; + /* Signs of inputs are equal, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } else { + /* Inputs are both negative */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return y; + return x; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return y; - return x; + return x; + return y; } union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) @@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754sp_inf(xs & ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): @@ -171,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): return x; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): @@ -180,9 +220,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) return y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) return y; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) return y; - return x; + else if (xm > ym) + return x; + else if (xs == 0) + return x; + return y; } diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c index 4eb1bb9e9dec7b45e36355f2bd2eac7da9990810..c51385f46b09968611764d26db082cbf680e8744 100644 --- a/arch/mips/math-emu/sp_fmin.c +++ b/arch/mips/math-emu/sp_fmin.c @@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) return ys ? y : x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) else if (xs < ys) return y; - /* Compare exponent */ - if (xe > ye) - return y; - else if (xe < ye) - return x; + /* Signs of inputs are the same, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } else { + /* Inputs are both negative */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return x; + return y; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return x; - return y; + return y; + return x; } union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) @@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,25 +202,25 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754sp_inf(xs | ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; + return y; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return y; + return x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) return x; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) + return x; + else if (xm > ym) + return y; + else if (xs == 1) return x; return y; } diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c index c91d5e5d9b5fa8293312e074350d10add7648a85..7195fe785d81a8f0a2dda6c2139b95175321803c 100644 --- a/arch/mips/math-emu/sp_maddf.c +++ b/arch/mips/math-emu/sp_maddf.c @@ -14,9 +14,6 @@ #include "ieee754sp.h" -enum maddf_flags { - maddf_negate_product = 1 << 0, -}; static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, union ieee754sp y, enum maddf_flags flags) @@ -24,14 +21,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, int re; int rs; unsigned rm; - unsigned short lxm; - unsigned short hxm; - unsigned short lym; - unsigned short hym; - unsigned lrm; - unsigned hrm; - unsigned t; - unsigned at; + uint64_t rm64; + uint64_t zm64; int s; COMPXSP; @@ -48,51 +39,35 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, ieee754_clearcx(); - switch (zc) { - case IEEE754_CLASS_SNAN: - ieee754_setcx(IEEE754_INVALID_OPERATION); + /* + * Handle the cases when at least one of x, y or z is a NaN. + * Order of precedence is sNaN, qNaN and z, x, y. + */ + if (zc == IEEE754_CLASS_SNAN) return ieee754sp_nanxcpt(z); - case IEEE754_CLASS_DNORM: - SPDNORMZ; - /* QNAN and ZERO cases are handled separately below */ - } - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): + if (xc == IEEE754_CLASS_SNAN) + return ieee754sp_nanxcpt(x); + if (yc == IEEE754_CLASS_SNAN) return ieee754sp_nanxcpt(y); + if (zc == IEEE754_CLASS_QNAN) + return z; + if (xc == IEEE754_CLASS_QNAN) + return x; + if (yc == IEEE754_CLASS_QNAN) + return y; - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x); + if (zc == IEEE754_CLASS_DNORM) + SPDNORMZ; + /* ZERO z cases are handled separately below */ - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; + switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; /* * Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; ieee754_setcx(IEEE754_INVALID_OPERATION); return ieee754sp_indef(); @@ -101,9 +76,27 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; - return ieee754sp_inf(xs ^ ys); + if ((zc == IEEE754_CLASS_INF) && + ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { + /* + * Cases of addition of infinities with opposite signs + * or subtraction of infinities with same signs. + */ + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754sp_indef(); + } + /* + * z is here either not an infinity, or an infinity having the + * same sign as product (x*y) (in case of MADDF.D instruction) + * or product -(x*y) (in MSUBF.D case). The result must be an + * infinity, and its sign is determined only by the value of + * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. + */ + if (flags & MADDF_NEGATE_PRODUCT) + return ieee754sp_inf(1 ^ (xs ^ ys)); + else + return ieee754sp_inf(xs ^ ys); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): @@ -112,32 +105,42 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); - /* Multiplication is 0 so just return z */ + if (zc == IEEE754_CLASS_ZERO) { + /* Handle cases +0 + (-0) and similar ones. */ + if ((!(flags & MADDF_NEGATE_PRODUCT) + && (zs == (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) + && (zs != (xs ^ ys)))) + /* + * Cases of addition of zeros of equal signs + * or subtraction of zeroes of opposite signs. + * The sign of the resulting zero is in any + * such case determined only by the sign of z. + */ + return z; + + return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); + } + /* x*y is here 0, and z is not 0, so just return z */ return z; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); SPDNORMY; break; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); SPDNORMX; break; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); /* fall through to real computations */ } @@ -158,111 +161,93 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, re = xe + ye; rs = xs ^ ys; - if (flags & maddf_negate_product) + if (flags & MADDF_NEGATE_PRODUCT) rs ^= 1; - /* shunt to top of word */ - xm <<= 32 - (SP_FBITS + 1); - ym <<= 32 - (SP_FBITS + 1); - - /* - * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. - */ - lxm = xm & 0xffff; - hxm = xm >> 16; - lym = ym & 0xffff; - hym = ym >> 16; - - lrm = lxm * lym; /* 16 * 16 => 32 */ - hrm = hxm * hym; /* 16 * 16 => 32 */ - - t = lxm * hym; /* 16 * 16 => 32 */ - at = lrm + (t << 16); - hrm += at < lrm; - lrm = at; - hrm = hrm + (t >> 16); + /* Multiple 24 bit xm and ym to give 48 bit results */ + rm64 = (uint64_t)xm * ym; - t = hxm * lym; /* 16 * 16 => 32 */ - at = lrm + (t << 16); - hrm += at < lrm; - lrm = at; - hrm = hrm + (t >> 16); + /* Shunt to top of word */ + rm64 = rm64 << 16; - rm = hrm | (lrm != 0); - - /* - * Sticky shift down to normal rounding precision. - */ - if ((int) rm < 0) { - rm = (rm >> (32 - (SP_FBITS + 1 + 3))) | - ((rm << (SP_FBITS + 1 + 3)) != 0); + /* Put explicit bit at bit 62 if necessary */ + if ((int64_t) rm64 < 0) { + rm64 = rm64 >> 1; re++; - } else { - rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) | - ((rm << (SP_FBITS + 1 + 3 + 1)) != 0); } - assert(rm & (SP_HIDDEN_BIT << 3)); - - if (zc == IEEE754_CLASS_ZERO) - return ieee754sp_format(rs, re, rm); - /* And now the addition */ + assert(rm64 & (1 << 62)); - assert(zm & SP_HIDDEN_BIT); + if (zc == IEEE754_CLASS_ZERO) { + /* + * Move explicit bit from bit 62 to bit 26 since the + * ieee754sp_format code expects the mantissa to be + * 27 bits wide (24 + 3 rounding bits). + */ + rm = XSPSRS64(rm64, (62 - 26)); + return ieee754sp_format(rs, re, rm); + } - /* - * Provide guard,round and stick bit space. - */ - zm <<= 3; + /* Move explicit bit from bit 23 to bit 62 */ + zm64 = (uint64_t)zm << (62 - 23); + assert(zm64 & (1 << 62)); + /* Make the exponents the same */ if (ze > re) { /* * Have to shift r fraction right to align. */ s = ze - re; - rm = XSPSRS(rm, s); + rm64 = XSPSRS64(rm64, s); re += s; } else if (re > ze) { /* * Have to shift z fraction right to align. */ s = re - ze; - zm = XSPSRS(zm, s); + zm64 = XSPSRS64(zm64, s); ze += s; } assert(ze == re); assert(ze <= SP_EMAX); + /* Do the addition */ if (zs == rs) { /* - * Generate 28 bit result of adding two 27 bit numbers - * leaving result in zm, zs and ze. + * Generate 64 bit result by adding two 63 bit numbers + * leaving result in zm64, zs and ze. */ - zm = zm + rm; - - if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ - zm = XSPSRS1(zm); + zm64 = zm64 + rm64; + if ((int64_t)zm64 < 0) { /* carry out */ + zm64 = XSPSRS1(zm64); ze++; } } else { - if (zm >= rm) { - zm = zm - rm; + if (zm64 >= rm64) { + zm64 = zm64 - rm64; } else { - zm = rm - zm; + zm64 = rm64 - zm64; zs = rs; } - if (zm == 0) + if (zm64 == 0) return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); /* - * Normalize in extended single precision + * Put explicit bit at bit 62 if necessary. */ - while ((zm >> (SP_MBITS + 3)) == 0) { - zm <<= 1; + while ((zm64 >> 62) == 0) { + zm64 <<= 1; ze--; } - } + + /* + * Move explicit bit from bit 62 to bit 26 since the + * ieee754sp_format code expects the mantissa to be + * 27 bits wide (24 + 3 rounding bits). + */ + zm = XSPSRS64(zm64, (62 - 26)); + return ieee754sp_format(zs, ze, zm); } @@ -275,5 +260,5 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, union ieee754sp y) { - return _sp_maddf(z, x, y, maddf_negate_product); + return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); } diff --git a/arch/mips/math-emu/sp_rint.c b/arch/mips/math-emu/sp_rint.c new file mode 100644 index 0000000000000000000000000000000000000000..70765b17e1962f39e098dd9b7731ee2cf038b030 --- /dev/null +++ b/arch/mips/math-emu/sp_rint.c @@ -0,0 +1,90 @@ +/* IEEE754 floating point arithmetic + * single precision + */ +/* + * MIPS floating point support + * Copyright (C) 1994-2000 Algorithmics Ltd. + * Copyright (C) 2017 Imagination Technologies, Ltd. + * Author: Aleksandar Markovic + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. + */ + +#include "ieee754sp.h" + +union ieee754sp ieee754sp_rint(union ieee754sp x) +{ + union ieee754sp ret; + u32 residue; + int sticky; + int round; + int odd; + + COMPXDP; /* <-- DP needed for 64-bit mantissa tmp */ + + ieee754_clearcx(); + + EXPLODEXSP; + FLUSHXSP; + + if (xc == IEEE754_CLASS_SNAN) + return ieee754sp_nanxcpt(x); + + if ((xc == IEEE754_CLASS_QNAN) || + (xc == IEEE754_CLASS_INF) || + (xc == IEEE754_CLASS_ZERO)) + return x; + + if (xe >= SP_FBITS) + return x; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } else { + residue = xm << (xe + 1); + residue <<= 31 - SP_FBITS; + round = (residue >> 31) != 0; + sticky = (residue << 1) != 0; + xm >>= SP_FBITS - xe; + } + + odd = (xm & 0x1) != 0x0; + + switch (ieee754_csr.rm) { + case FPU_CSR_RN: /* toward nearest */ + if (round && (sticky || odd)) + xm++; + break; + case FPU_CSR_RZ: /* toward zero */ + break; + case FPU_CSR_RU: /* toward +infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case FPU_CSR_RD: /* toward -infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + + if (round || sticky) + ieee754_setcx(IEEE754_INEXACT); + + ret = ieee754sp_flong(xm); + SPSIGN(ret) = xs; + + return ret; +} diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 81d6a15c93d08ba2603d0e9f2dd8302546a97489..6f534b2099717da8c2d7be70bfa035a05ed5aede 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -37,7 +37,7 @@ #include /* for run_uncached() */ #include #include -#include +#include /* * Bits describing what cache ops an SMP callback function may perform. diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 899e46279902819dcaee11e427411ee11edca9d8..44ac64d5182761d547f5b14a29cd4c9b047d5129 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Cache operations. */ void (*flush_cache_all)(void); @@ -44,7 +45,6 @@ void (*__flush_cache_vunmap)(void); void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); -void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 8e78251eccc25e0a981ede0b89d1df907f9e896a..c01bd20d020810901b9712dc652f283d37d976b3 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -127,23 +127,6 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) return gfp | dma_flag; } -static void *mips_dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t gfp) -{ - void *ret; - - gfp = massage_gfp_flags(dev, gfp); - - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = plat_map_dma_mem(dev, ret, size); - } - - return ret; -} - static void *mips_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { @@ -151,13 +134,6 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, struct page *page = NULL; unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; - /* - * XXX: seems like the coherent and non-coherent implementations could - * be consolidated. - */ - if (attrs & DMA_ATTR_NON_CONSISTENT) - return mips_dma_alloc_noncoherent(dev, size, dma_handle, gfp); - gfp = massage_gfp_flags(dev, gfp); if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp)) @@ -172,7 +148,8 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, ret = page_address(page); memset(ret, 0, size); *dma_handle = plat_map_dma_mem(dev, ret, size); - if (!plat_device_is_coherent(dev)) { + if (!(attrs & DMA_ATTR_NON_CONSISTENT) && + !plat_device_is_coherent(dev)) { dma_cache_wback_inv((unsigned long) ret, size); ret = UNCAC_ADDR(ret); } @@ -180,14 +157,6 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, return ret; } - -static void mips_dma_free_noncoherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - free_pages((unsigned long) vaddr, get_order(size)); -} - static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, unsigned long attrs) { @@ -195,14 +164,9 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; struct page *page = NULL; - if (attrs & DMA_ATTR_NON_CONSISTENT) { - mips_dma_free_noncoherent(dev, size, vaddr, dma_handle); - return; - } - plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - if (!plat_device_is_coherent(dev)) + if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); page = virt_to_page((void *) addr); @@ -409,12 +373,12 @@ static void mips_dma_sync_sg_for_device(struct device *dev, } } -int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } -int mips_dma_supported(struct device *dev, u64 mask) +static int mips_dma_supported(struct device *dev, u64 mask) { return plat_dma_supported(dev, mask); } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 8ce2983a701526a5f1bdfd243ad61d8b80375b1d..5f6ea7d746de659730598e253aae97dc9234ad6e 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 28adeabe851ff22dbea2da9d701208dadcc4925d..33d3251ecd37a257c2cb435a973e612738e0a216 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -7,6 +7,7 @@ * written by Ralf Baechle */ #include +#include #include #include #include diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index c909c334272945c1c52d812462e78a74c2f1824b..acfb89273dad7d9eaa1529f07e94b3b439733309 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include /* * MIPS32/MIPS64 L2 cache handling @@ -63,34 +63,25 @@ static void mips_sc_prefetch_enable(void) * prefetching for both code & data, for all ports. */ pftctl = read_gcr_l2_pft_control(); - if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) { - pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; - pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; - pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; + if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT) { + pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK; + pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK; + pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN; write_gcr_l2_pft_control(pftctl); - pftctl = read_gcr_l2_pft_control_b(); - pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; - pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; - write_gcr_l2_pft_control_b(pftctl); + set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID | + CM_GCR_L2_PFT_CONTROL_B_CEN); } } static void mips_sc_prefetch_disable(void) { - unsigned long pftctl; - if (mips_cm_revision() < CM_REV_CM2_5) return; - pftctl = read_gcr_l2_pft_control(); - pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; - write_gcr_l2_pft_control(pftctl); - - pftctl = read_gcr_l2_pft_control_b(); - pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; - pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; - write_gcr_l2_pft_control_b(pftctl); + clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN); + clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID | + CM_GCR_L2_PFT_CONTROL_B_CEN); } static bool mips_sc_prefetch_is_enabled(void) @@ -101,9 +92,9 @@ static bool mips_sc_prefetch_is_enabled(void) return false; pftctl = read_gcr_l2_pft_control(); - if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK)) + if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT)) return false; - return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK); + return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN); } static struct bcache_ops mips_sc_ops = { @@ -160,21 +151,21 @@ static int __init mips_sc_probe_cm3(void) unsigned long cfg = read_gcr_l2_config(); unsigned long sets, line_sz, assoc; - if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK) + if (cfg & CM_GCR_L2_CONFIG_BYPASS) return 0; - sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK; - sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF; + sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE; + sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE); if (sets) c->scache.sets = 64 << sets; - line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK; - line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF; + line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE; + line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE); if (line_sz) c->scache.linesz = 2 << line_sz; - assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK; - assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF; + assoc = cfg & CM_GCR_L2_CONFIG_ASSOC; + assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC); c->scache.ways = assoc + 1; c->scache.waysize = c->scache.sets * c->scache.linesz; c->scache.waybit = __ffs(c->scache.waysize); diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S index 318855eb5f80309d3e596d33c8130bdbced61bf7..77db401fc62073a119bf79c10da908a07c08c4df 100644 --- a/arch/mips/mm/tlbex-fault.S +++ b/arch/mips/mm/tlbex-fault.S @@ -12,14 +12,15 @@ .macro tlb_do_page_fault, write NESTED(tlb_do_page_fault_\write, PT_SIZE, sp) - SAVE_ALL + .cfi_signal_frame + SAVE_ALL docfi=1 MFC0 a2, CP0_BADVADDR KMODE move a0, sp REG_S a2, PT_BVADDR(sp) li a1, \write - PTR_LA ra, ret_from_exception - j do_page_fault + jal do_page_fault + j ret_from_exception END(tlb_do_page_fault_\write) .endm diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 5aadc69c8ce39d8b894393e5d12e45fec934100c..79b9f2ad3ff514e0e48ab409d6465540a4fe097d 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -2634,11 +2634,6 @@ void build_tlb_refill_handler(void) #endif break; - case CPU_R6000: - case CPU_R6000A: - panic("No R6000 TLB refill handler yet"); - break; - case CPU_R8000: panic("No R8000 TLB refill handler yet"); break; diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index 3f74f6c1f065fb6b5d2b930dc1d164e1624e63f0..9fea6c6bbf49e3768e81ad3ffb8b8af2bbdef61f 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c @@ -48,7 +48,7 @@ #include "uasm.c" -static const struct insn const insn_table[insn_invalid] = { +static const struct insn insn_table[insn_invalid] = { [insn_addiu] = {M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM}, [insn_addu] = {M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD}, [insn_and] = {M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD}, diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c index c398582c316fcc9a8b01f567052ac4bb2ef18c26..a6699c15277d9b802536abba8a2d27288f6e0861 100644 --- a/arch/mips/mti-malta/malta-dtshim.c +++ b/arch/mips/mti-malta/malta-dtshim.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #define ROCIT_REG_BASE 0x1f403000 @@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt) /* if we have a CM which reports a GIC is present, leave the DT alone */ err = mips_cm_probe(); - if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK)) + if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) return; if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 0f3b881a3190fdcb993ea01234a2c304b1511f18..009f2918b3201f1390cc163f2d8b61b44d1160cb 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -21,8 +21,7 @@ #include #include #include -#include -#include +#include #include #include diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index b0f9b188e83359d18073e08e5ec3dd3105155d51..a840e0c1642cb269425d4e2995cb1715312c456f 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -29,9 +28,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -215,7 +214,7 @@ void __init arch_init_irq(void) msc_nr_irqs); } - if (gic_present) { + if (mips_gic_present()) { corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } else if (cpu_has_veic) { set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index a01d5debfcaf5578a30b6114721db82a1c392e19..de34adb761579d81075f3070794e1bafa5112667 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -128,7 +128,7 @@ static int __init plat_enable_iocoherency(void) BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); pr_info("Enabled Bonito IOBC coherency\n"); } - } else if (mips_cm_numiocu() != 0) { + } else if (mips_cps_numiocu(0) != 0) { /* Nothing special needs to be done to enable coherency */ pr_info("CMP IOCU detected\n"); cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0)); diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index cea4ec9098063ed8c82eb41786fba4634f73a4d2..66c866740ff227ed788a4d41f4322aeb5198dd9b 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include @@ -85,8 +85,8 @@ static void __init estimate_frequencies(void) local_irq_save(flags); - if (gic_present) - gic_start_count(); + if (mips_gic_present()) + clear_gic_config(GIC_CONFIG_COUNTSTOP); /* * Read counters exactly on rising edge of update flag. @@ -95,8 +95,8 @@ static void __init estimate_frequencies(void) while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); start = read_c0_count(); - if (gic_present) - gicstart = gic_read_count(); + if (mips_gic_present()) + gicstart = read_gic_counter(); /* Wait for falling edge before reading RTC. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); @@ -105,8 +105,8 @@ static void __init estimate_frequencies(void) /* Read counters again exactly on rising edge of update flag. */ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); count = read_c0_count(); - if (gic_present) - giccount = gic_read_count(); + if (mips_gic_present()) + giccount = read_gic_counter(); /* Wait for falling edge before reading RTC again. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); @@ -128,7 +128,7 @@ static void __init estimate_frequencies(void) count /= secs; mips_hpt_frequency = count; - if (gic_present) { + if (mips_gic_present()) { giccount = div_u64(giccount - gicstart, secs); gic_frequency = giccount; } @@ -154,7 +154,7 @@ int get_c0_fdc_int(void) if (cpu_has_veic) return -1; - else if (gic_present) + else if (mips_gic_present()) return gic_get_c0_fdc_int(); else if (cp0_fdc_irq >= 0) return MIPS_CPU_IRQ_BASE + cp0_fdc_irq; @@ -167,7 +167,7 @@ int get_c0_perfcount_int(void) if (cpu_has_veic) { set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; - } else if (gic_present) { + } else if (mips_gic_present()) { mips_cpu_perf_irq = gic_get_c0_perfcount_int(); } else if (cp0_perfcount_irq >= 0) { mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; @@ -184,7 +184,7 @@ unsigned int get_c0_compare_int(void) if (cpu_has_veic) { set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } else if (gic_present) { + } else if (mips_gic_present()) { mips_cpu_timer_irq = gic_get_c0_compare_int(); } else { mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; @@ -258,8 +258,7 @@ void __init plat_time_init(void) setup_pit_timer(); #endif -#ifdef CONFIG_MIPS_GIC - if (gic_present) { + if (mips_gic_present()) { freq = freqround(gic_frequency, 5000); printk("GIC frequency %d.%02d MHz\n", freq/1000000, (freq%1000000)*100/1000000); @@ -268,5 +267,4 @@ void __init plat_time_init(void) timer_probe(); #endif } -#endif } diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c new file mode 100644 index 0000000000000000000000000000000000000000..7646891c4e9b18077d59ac28bfe2ffe5b82d0d37 --- /dev/null +++ b/arch/mips/net/ebpf_jit.c @@ -0,0 +1,1995 @@ +/* + * Just-In-Time compiler for eBPF filters on MIPS + * + * Copyright (c) 2017 Cavium, Inc. + * + * Based on code from: + * + * Copyright (c) 2014 Imagination Technologies Ltd. + * Author: Markos Chandras + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers used by JIT */ +#define MIPS_R_ZERO 0 +#define MIPS_R_AT 1 +#define MIPS_R_V0 2 /* BPF_R0 */ +#define MIPS_R_V1 3 +#define MIPS_R_A0 4 /* BPF_R1 */ +#define MIPS_R_A1 5 /* BPF_R2 */ +#define MIPS_R_A2 6 /* BPF_R3 */ +#define MIPS_R_A3 7 /* BPF_R4 */ +#define MIPS_R_A4 8 /* BPF_R5 */ +#define MIPS_R_T4 12 /* BPF_AX */ +#define MIPS_R_T5 13 +#define MIPS_R_T6 14 +#define MIPS_R_T7 15 +#define MIPS_R_S0 16 /* BPF_R6 */ +#define MIPS_R_S1 17 /* BPF_R7 */ +#define MIPS_R_S2 18 /* BPF_R8 */ +#define MIPS_R_S3 19 /* BPF_R9 */ +#define MIPS_R_S4 20 /* BPF_TCC */ +#define MIPS_R_S5 21 +#define MIPS_R_S6 22 +#define MIPS_R_S7 23 +#define MIPS_R_T8 24 +#define MIPS_R_T9 25 +#define MIPS_R_SP 29 +#define MIPS_R_RA 31 + +/* eBPF flags */ +#define EBPF_SAVE_S0 BIT(0) +#define EBPF_SAVE_S1 BIT(1) +#define EBPF_SAVE_S2 BIT(2) +#define EBPF_SAVE_S3 BIT(3) +#define EBPF_SAVE_S4 BIT(4) +#define EBPF_SAVE_RA BIT(5) +#define EBPF_SEEN_FP BIT(6) +#define EBPF_SEEN_TC BIT(7) +#define EBPF_TCC_IN_V1 BIT(8) + +/* + * For the mips64 ISA, we need to track the value range or type for + * each JIT register. The BPF machine requires zero extended 32-bit + * values, but the mips64 ISA requires sign extended 32-bit values. + * At each point in the BPF program we track the state of every + * register so that we can zero extend or sign extend as the BPF + * semantics require. + */ +enum reg_val_type { + /* uninitialized */ + REG_UNKNOWN, + /* not known to be 32-bit compatible. */ + REG_64BIT, + /* 32-bit compatible, no truncation needed for 64-bit ops. */ + REG_64BIT_32BIT, + /* 32-bit compatible, need truncation for 64-bit ops. */ + REG_32BIT, + /* 32-bit zero extended. */ + REG_32BIT_ZERO_EX, + /* 32-bit no sign/zero extension needed. */ + REG_32BIT_POS +}; + +/* + * high bit of offsets indicates if long branch conversion done at + * this insn. + */ +#define OFFSETS_B_CONV BIT(31) + +/** + * struct jit_ctx - JIT context + * @skf: The sk_filter + * @stack_size: eBPF stack size + * @tmp_offset: eBPF $sp offset to 8-byte temporary memory + * @idx: Instruction index + * @flags: JIT flags + * @offsets: Instruction offsets + * @target: Memory location for the compiled filter + * @reg_val_types Packed enum reg_val_type for each register. + */ +struct jit_ctx { + const struct bpf_prog *skf; + int stack_size; + int tmp_offset; + u32 idx; + u32 flags; + u32 *offsets; + u32 *target; + u64 *reg_val_types; + unsigned int long_b_conversion:1; + unsigned int gen_b_offsets:1; + unsigned int use_bbit_insns:1; +}; + +static void set_reg_val_type(u64 *rvt, int reg, enum reg_val_type type) +{ + *rvt &= ~(7ull << (reg * 3)); + *rvt |= ((u64)type << (reg * 3)); +} + +static enum reg_val_type get_reg_val_type(const struct jit_ctx *ctx, + int index, int reg) +{ + return (ctx->reg_val_types[index] >> (reg * 3)) & 7; +} + +/* Simply emit the instruction if the JIT memory space has been allocated */ +#define emit_instr(ctx, func, ...) \ +do { \ + if ((ctx)->target != NULL) { \ + u32 *p = &(ctx)->target[ctx->idx]; \ + uasm_i_##func(&p, ##__VA_ARGS__); \ + } \ + (ctx)->idx++; \ +} while (0) + +static unsigned int j_target(struct jit_ctx *ctx, int target_idx) +{ + unsigned long target_va, base_va; + unsigned int r; + + if (!ctx->target) + return 0; + + base_va = (unsigned long)ctx->target; + target_va = base_va + (ctx->offsets[target_idx] & ~OFFSETS_B_CONV); + + if ((base_va & ~0x0ffffffful) != (target_va & ~0x0ffffffful)) + return (unsigned int)-1; + r = target_va & 0x0ffffffful; + return r; +} + +/* Compute the immediate value for PC-relative branches. */ +static u32 b_imm(unsigned int tgt, struct jit_ctx *ctx) +{ + if (!ctx->gen_b_offsets) + return 0; + + /* + * We want a pc-relative branch. tgt is the instruction offset + * we want to jump to. + + * Branch on MIPS: + * I: target_offset <- sign_extend(offset) + * I+1: PC += target_offset (delay slot) + * + * ctx->idx currently points to the branch instruction + * but the offset is added to the delay slot so we need + * to subtract 4. + */ + return (ctx->offsets[tgt] & ~OFFSETS_B_CONV) - + (ctx->idx * 4) - 4; +} + +int bpf_jit_enable __read_mostly; + +enum which_ebpf_reg { + src_reg, + src_reg_no_fp, + dst_reg, + dst_reg_fp_ok +}; + +/* + * For eBPF, the register mapping naturally falls out of the + * requirements of eBPF and the MIPS n64 ABI. We don't maintain a + * separate frame pointer, so BPF_REG_10 relative accesses are + * adjusted to be $sp relative. + */ +int ebpf_to_mips_reg(struct jit_ctx *ctx, const struct bpf_insn *insn, + enum which_ebpf_reg w) +{ + int ebpf_reg = (w == src_reg || w == src_reg_no_fp) ? + insn->src_reg : insn->dst_reg; + + switch (ebpf_reg) { + case BPF_REG_0: + return MIPS_R_V0; + case BPF_REG_1: + return MIPS_R_A0; + case BPF_REG_2: + return MIPS_R_A1; + case BPF_REG_3: + return MIPS_R_A2; + case BPF_REG_4: + return MIPS_R_A3; + case BPF_REG_5: + return MIPS_R_A4; + case BPF_REG_6: + ctx->flags |= EBPF_SAVE_S0; + return MIPS_R_S0; + case BPF_REG_7: + ctx->flags |= EBPF_SAVE_S1; + return MIPS_R_S1; + case BPF_REG_8: + ctx->flags |= EBPF_SAVE_S2; + return MIPS_R_S2; + case BPF_REG_9: + ctx->flags |= EBPF_SAVE_S3; + return MIPS_R_S3; + case BPF_REG_10: + if (w == dst_reg || w == src_reg_no_fp) + goto bad_reg; + ctx->flags |= EBPF_SEEN_FP; + /* + * Needs special handling, return something that + * cannot be clobbered just in case. + */ + return MIPS_R_ZERO; + case BPF_REG_AX: + return MIPS_R_T4; + default: +bad_reg: + WARN(1, "Illegal bpf reg: %d\n", ebpf_reg); + return -EINVAL; + } +} +/* + * eBPF stack frame will be something like: + * + * Entry $sp ------> +--------------------------------+ + * | $ra (optional) | + * +--------------------------------+ + * | $s0 (optional) | + * +--------------------------------+ + * | $s1 (optional) | + * +--------------------------------+ + * | $s2 (optional) | + * +--------------------------------+ + * | $s3 (optional) | + * +--------------------------------+ + * | $s4 (optional) | + * +--------------------------------+ + * | tmp-storage (if $ra saved) | + * $sp + tmp_offset --> +--------------------------------+ <--BPF_REG_10 + * | BPF_REG_10 relative storage | + * | MAX_BPF_STACK (optional) | + * | . | + * | . | + * | . | + * $sp --------> +--------------------------------+ + * + * If BPF_REG_10 is never referenced, then the MAX_BPF_STACK sized + * area is not allocated. + */ +static int gen_int_prologue(struct jit_ctx *ctx) +{ + int stack_adjust = 0; + int store_offset; + int locals_size; + + if (ctx->flags & EBPF_SAVE_RA) + /* + * If RA we are doing a function call and may need + * extra 8-byte tmp area. + */ + stack_adjust += 16; + if (ctx->flags & EBPF_SAVE_S0) + stack_adjust += 8; + if (ctx->flags & EBPF_SAVE_S1) + stack_adjust += 8; + if (ctx->flags & EBPF_SAVE_S2) + stack_adjust += 8; + if (ctx->flags & EBPF_SAVE_S3) + stack_adjust += 8; + if (ctx->flags & EBPF_SAVE_S4) + stack_adjust += 8; + + BUILD_BUG_ON(MAX_BPF_STACK & 7); + locals_size = (ctx->flags & EBPF_SEEN_FP) ? MAX_BPF_STACK : 0; + + stack_adjust += locals_size; + ctx->tmp_offset = locals_size; + + ctx->stack_size = stack_adjust; + + /* + * First instruction initializes the tail call count (TCC). + * On tail call we skip this instruction, and the TCC is + * passed in $v1 from the caller. + */ + emit_instr(ctx, daddiu, MIPS_R_V1, MIPS_R_ZERO, MAX_TAIL_CALL_CNT); + if (stack_adjust) + emit_instr(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, -stack_adjust); + else + return 0; + + store_offset = stack_adjust - 8; + + if (ctx->flags & EBPF_SAVE_RA) { + emit_instr(ctx, sd, MIPS_R_RA, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S0) { + emit_instr(ctx, sd, MIPS_R_S0, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S1) { + emit_instr(ctx, sd, MIPS_R_S1, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S2) { + emit_instr(ctx, sd, MIPS_R_S2, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S3) { + emit_instr(ctx, sd, MIPS_R_S3, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S4) { + emit_instr(ctx, sd, MIPS_R_S4, store_offset, MIPS_R_SP); + store_offset -= 8; + } + + if ((ctx->flags & EBPF_SEEN_TC) && !(ctx->flags & EBPF_TCC_IN_V1)) + emit_instr(ctx, daddu, MIPS_R_S4, MIPS_R_V1, MIPS_R_ZERO); + + return 0; +} + +static int build_int_epilogue(struct jit_ctx *ctx, int dest_reg) +{ + const struct bpf_prog *prog = ctx->skf; + int stack_adjust = ctx->stack_size; + int store_offset = stack_adjust - 8; + int r0 = MIPS_R_V0; + + if (dest_reg == MIPS_R_RA && + get_reg_val_type(ctx, prog->len, BPF_REG_0) == REG_32BIT_ZERO_EX) + /* Don't let zero extended value escape. */ + emit_instr(ctx, sll, r0, r0, 0); + + if (ctx->flags & EBPF_SAVE_RA) { + emit_instr(ctx, ld, MIPS_R_RA, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S0) { + emit_instr(ctx, ld, MIPS_R_S0, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S1) { + emit_instr(ctx, ld, MIPS_R_S1, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S2) { + emit_instr(ctx, ld, MIPS_R_S2, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S3) { + emit_instr(ctx, ld, MIPS_R_S3, store_offset, MIPS_R_SP); + store_offset -= 8; + } + if (ctx->flags & EBPF_SAVE_S4) { + emit_instr(ctx, ld, MIPS_R_S4, store_offset, MIPS_R_SP); + store_offset -= 8; + } + emit_instr(ctx, jr, dest_reg); + + if (stack_adjust) + emit_instr(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, stack_adjust); + else + emit_instr(ctx, nop); + + return 0; +} + +static void gen_imm_to_reg(const struct bpf_insn *insn, int reg, + struct jit_ctx *ctx) +{ + if (insn->imm >= S16_MIN && insn->imm <= S16_MAX) { + emit_instr(ctx, addiu, reg, MIPS_R_ZERO, insn->imm); + } else { + int lower = (s16)(insn->imm & 0xffff); + int upper = insn->imm - lower; + + emit_instr(ctx, lui, reg, upper >> 16); + emit_instr(ctx, addiu, reg, reg, lower); + } + +} + +static int gen_imm_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, + int idx) +{ + int upper_bound, lower_bound; + int dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + + if (dst < 0) + return dst; + + switch (BPF_OP(insn->code)) { + case BPF_MOV: + case BPF_ADD: + upper_bound = S16_MAX; + lower_bound = S16_MIN; + break; + case BPF_SUB: + upper_bound = -(int)S16_MIN; + lower_bound = -(int)S16_MAX; + break; + case BPF_AND: + case BPF_OR: + case BPF_XOR: + upper_bound = 0xffff; + lower_bound = 0; + break; + case BPF_RSH: + case BPF_LSH: + case BPF_ARSH: + /* Shift amounts are truncated, no need for bounds */ + upper_bound = S32_MAX; + lower_bound = S32_MIN; + break; + default: + return -EINVAL; + } + + /* + * Immediate move clobbers the register, so no sign/zero + * extension needed. + */ + if (BPF_CLASS(insn->code) == BPF_ALU64 && + BPF_OP(insn->code) != BPF_MOV && + get_reg_val_type(ctx, idx, insn->dst_reg) == REG_32BIT) + emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); + /* BPF_ALU | BPF_LSH doesn't need separate sign extension */ + if (BPF_CLASS(insn->code) == BPF_ALU && + BPF_OP(insn->code) != BPF_LSH && + BPF_OP(insn->code) != BPF_MOV && + get_reg_val_type(ctx, idx, insn->dst_reg) != REG_32BIT) + emit_instr(ctx, sll, dst, dst, 0); + + if (insn->imm >= lower_bound && insn->imm <= upper_bound) { + /* single insn immediate case */ + switch (BPF_OP(insn->code) | BPF_CLASS(insn->code)) { + case BPF_ALU64 | BPF_MOV: + emit_instr(ctx, daddiu, dst, MIPS_R_ZERO, insn->imm); + break; + case BPF_ALU64 | BPF_AND: + case BPF_ALU | BPF_AND: + emit_instr(ctx, andi, dst, dst, insn->imm); + break; + case BPF_ALU64 | BPF_OR: + case BPF_ALU | BPF_OR: + emit_instr(ctx, ori, dst, dst, insn->imm); + break; + case BPF_ALU64 | BPF_XOR: + case BPF_ALU | BPF_XOR: + emit_instr(ctx, xori, dst, dst, insn->imm); + break; + case BPF_ALU64 | BPF_ADD: + emit_instr(ctx, daddiu, dst, dst, insn->imm); + break; + case BPF_ALU64 | BPF_SUB: + emit_instr(ctx, daddiu, dst, dst, -insn->imm); + break; + case BPF_ALU64 | BPF_RSH: + emit_instr(ctx, dsrl_safe, dst, dst, insn->imm & 0x3f); + break; + case BPF_ALU | BPF_RSH: + emit_instr(ctx, srl, dst, dst, insn->imm & 0x1f); + break; + case BPF_ALU64 | BPF_LSH: + emit_instr(ctx, dsll_safe, dst, dst, insn->imm & 0x3f); + break; + case BPF_ALU | BPF_LSH: + emit_instr(ctx, sll, dst, dst, insn->imm & 0x1f); + break; + case BPF_ALU64 | BPF_ARSH: + emit_instr(ctx, dsra_safe, dst, dst, insn->imm & 0x3f); + break; + case BPF_ALU | BPF_ARSH: + emit_instr(ctx, sra, dst, dst, insn->imm & 0x1f); + break; + case BPF_ALU | BPF_MOV: + emit_instr(ctx, addiu, dst, MIPS_R_ZERO, insn->imm); + break; + case BPF_ALU | BPF_ADD: + emit_instr(ctx, addiu, dst, dst, insn->imm); + break; + case BPF_ALU | BPF_SUB: + emit_instr(ctx, addiu, dst, dst, -insn->imm); + break; + default: + return -EINVAL; + } + } else { + /* multi insn immediate case */ + if (BPF_OP(insn->code) == BPF_MOV) { + gen_imm_to_reg(insn, dst, ctx); + } else { + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + switch (BPF_OP(insn->code) | BPF_CLASS(insn->code)) { + case BPF_ALU64 | BPF_AND: + case BPF_ALU | BPF_AND: + emit_instr(ctx, and, dst, dst, MIPS_R_AT); + break; + case BPF_ALU64 | BPF_OR: + case BPF_ALU | BPF_OR: + emit_instr(ctx, or, dst, dst, MIPS_R_AT); + break; + case BPF_ALU64 | BPF_XOR: + case BPF_ALU | BPF_XOR: + emit_instr(ctx, xor, dst, dst, MIPS_R_AT); + break; + case BPF_ALU64 | BPF_ADD: + emit_instr(ctx, daddu, dst, dst, MIPS_R_AT); + break; + case BPF_ALU64 | BPF_SUB: + emit_instr(ctx, dsubu, dst, dst, MIPS_R_AT); + break; + case BPF_ALU | BPF_ADD: + emit_instr(ctx, addu, dst, dst, MIPS_R_AT); + break; + case BPF_ALU | BPF_SUB: + emit_instr(ctx, subu, dst, dst, MIPS_R_AT); + break; + default: + return -EINVAL; + } + } + } + + return 0; +} + +static void * __must_check +ool_skb_header_pointer(const struct sk_buff *skb, int offset, + int len, void *buffer) +{ + return skb_header_pointer(skb, offset, len, buffer); +} + +static int size_to_len(const struct bpf_insn *insn) +{ + switch (BPF_SIZE(insn->code)) { + case BPF_B: + return 1; + case BPF_H: + return 2; + case BPF_W: + return 4; + case BPF_DW: + return 8; + } + return 0; +} + +static void emit_const_to_reg(struct jit_ctx *ctx, int dst, u64 value) +{ + if (value >= 0xffffffffffff8000ull || value < 0x8000ull) { + emit_instr(ctx, daddiu, dst, MIPS_R_ZERO, (int)value); + } else if (value >= 0xffffffff80000000ull || + (value < 0x80000000 && value > 0xffff)) { + emit_instr(ctx, lui, dst, (s32)(s16)(value >> 16)); + emit_instr(ctx, ori, dst, dst, (unsigned int)(value & 0xffff)); + } else { + int i; + bool seen_part = false; + int needed_shift = 0; + + for (i = 0; i < 4; i++) { + u64 part = (value >> (16 * (3 - i))) & 0xffff; + + if (seen_part && needed_shift > 0 && (part || i == 3)) { + emit_instr(ctx, dsll_safe, dst, dst, needed_shift); + needed_shift = 0; + } + if (part) { + if (i == 0 || (!seen_part && i < 3 && part < 0x8000)) { + emit_instr(ctx, lui, dst, (s32)(s16)part); + needed_shift = -16; + } else { + emit_instr(ctx, ori, dst, + seen_part ? dst : MIPS_R_ZERO, + (unsigned int)part); + } + seen_part = true; + } + if (seen_part) + needed_shift += 16; + } + } +} + +static int emit_bpf_tail_call(struct jit_ctx *ctx, int this_idx) +{ + int off, b_off; + + ctx->flags |= EBPF_SEEN_TC; + /* + * if (index >= array->map.max_entries) + * goto out; + */ + off = offsetof(struct bpf_array, map.max_entries); + emit_instr(ctx, lwu, MIPS_R_T5, off, MIPS_R_A1); + emit_instr(ctx, sltu, MIPS_R_AT, MIPS_R_T5, MIPS_R_A2); + b_off = b_imm(this_idx + 1, ctx); + emit_instr(ctx, bne, MIPS_R_AT, MIPS_R_ZERO, b_off); + /* + * if (--TCC < 0) + * goto out; + */ + /* Delay slot */ + emit_instr(ctx, daddiu, MIPS_R_T5, + (ctx->flags & EBPF_TCC_IN_V1) ? MIPS_R_V1 : MIPS_R_S4, -1); + b_off = b_imm(this_idx + 1, ctx); + emit_instr(ctx, bltz, MIPS_R_T5, b_off); + /* + * prog = array->ptrs[index]; + * if (prog == NULL) + * goto out; + */ + /* Delay slot */ + emit_instr(ctx, dsll, MIPS_R_T8, MIPS_R_A2, 3); + emit_instr(ctx, daddu, MIPS_R_T8, MIPS_R_T8, MIPS_R_A1); + off = offsetof(struct bpf_array, ptrs); + emit_instr(ctx, ld, MIPS_R_AT, off, MIPS_R_T8); + b_off = b_imm(this_idx + 1, ctx); + emit_instr(ctx, beq, MIPS_R_AT, MIPS_R_ZERO, b_off); + /* Delay slot */ + emit_instr(ctx, nop); + + /* goto *(prog->bpf_func + 4); */ + off = offsetof(struct bpf_prog, bpf_func); + emit_instr(ctx, ld, MIPS_R_T9, off, MIPS_R_AT); + /* All systems are go... propagate TCC */ + emit_instr(ctx, daddu, MIPS_R_V1, MIPS_R_T5, MIPS_R_ZERO); + /* Skip first instruction (TCC initialization) */ + emit_instr(ctx, daddiu, MIPS_R_T9, MIPS_R_T9, 4); + return build_int_epilogue(ctx, MIPS_R_T9); +} + +static bool is_bad_offset(int b_off) +{ + return b_off > 0x1ffff || b_off < -0x20000; +} + +/* Returns the number of insn slots consumed. */ +static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, + int this_idx, int exit_idx) +{ + int src, dst, r, td, ts, mem_off, b_off; + bool need_swap, did_move, cmp_eq; + unsigned int target; + u64 t64; + s64 t64s; + int bpf_op = BPF_OP(insn->code); + + switch (insn->code) { + case BPF_ALU64 | BPF_ADD | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_SUB | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_OR | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_AND | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_LSH | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_RSH | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_XOR | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_ARSH | BPF_K: /* ALU64_IMM */ + case BPF_ALU64 | BPF_MOV | BPF_K: /* ALU64_IMM */ + case BPF_ALU | BPF_MOV | BPF_K: /* ALU32_IMM */ + case BPF_ALU | BPF_ADD | BPF_K: /* ALU32_IMM */ + case BPF_ALU | BPF_SUB | BPF_K: /* ALU32_IMM */ + case BPF_ALU | BPF_OR | BPF_K: /* ALU64_IMM */ + case BPF_ALU | BPF_AND | BPF_K: /* ALU64_IMM */ + case BPF_ALU | BPF_LSH | BPF_K: /* ALU64_IMM */ + case BPF_ALU | BPF_RSH | BPF_K: /* ALU64_IMM */ + case BPF_ALU | BPF_XOR | BPF_K: /* ALU64_IMM */ + case BPF_ALU | BPF_ARSH | BPF_K: /* ALU64_IMM */ + r = gen_imm_insn(insn, ctx, this_idx); + if (r < 0) + return r; + break; + case BPF_ALU64 | BPF_MUL | BPF_K: /* ALU64_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT) + emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); + if (insn->imm == 1) /* Mult by 1 is a nop */ + break; + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + emit_instr(ctx, dmultu, MIPS_R_AT, dst); + emit_instr(ctx, mflo, dst); + break; + case BPF_ALU64 | BPF_NEG | BPF_K: /* ALU64_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT) + emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); + emit_instr(ctx, dsubu, dst, MIPS_R_ZERO, dst); + break; + case BPF_ALU | BPF_MUL | BPF_K: /* ALU_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + td = get_reg_val_type(ctx, this_idx, insn->dst_reg); + if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) { + /* sign extend */ + emit_instr(ctx, sll, dst, dst, 0); + } + if (insn->imm == 1) /* Mult by 1 is a nop */ + break; + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + emit_instr(ctx, multu, dst, MIPS_R_AT); + emit_instr(ctx, mflo, dst); + break; + case BPF_ALU | BPF_NEG | BPF_K: /* ALU_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + td = get_reg_val_type(ctx, this_idx, insn->dst_reg); + if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) { + /* sign extend */ + emit_instr(ctx, sll, dst, dst, 0); + } + emit_instr(ctx, subu, dst, MIPS_R_ZERO, dst); + break; + case BPF_ALU | BPF_DIV | BPF_K: /* ALU_IMM */ + case BPF_ALU | BPF_MOD | BPF_K: /* ALU_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + if (insn->imm == 0) { /* Div by zero */ + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off); + emit_instr(ctx, addu, MIPS_R_V0, MIPS_R_ZERO, MIPS_R_ZERO); + } + td = get_reg_val_type(ctx, this_idx, insn->dst_reg); + if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) + /* sign extend */ + emit_instr(ctx, sll, dst, dst, 0); + if (insn->imm == 1) { + /* div by 1 is a nop, mod by 1 is zero */ + if (bpf_op == BPF_MOD) + emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO); + break; + } + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + emit_instr(ctx, divu, dst, MIPS_R_AT); + if (bpf_op == BPF_DIV) + emit_instr(ctx, mflo, dst); + else + emit_instr(ctx, mfhi, dst); + break; + case BPF_ALU64 | BPF_DIV | BPF_K: /* ALU_IMM */ + case BPF_ALU64 | BPF_MOD | BPF_K: /* ALU_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + if (insn->imm == 0) { /* Div by zero */ + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off); + emit_instr(ctx, addu, MIPS_R_V0, MIPS_R_ZERO, MIPS_R_ZERO); + } + if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT) + emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); + + if (insn->imm == 1) { + /* div by 1 is a nop, mod by 1 is zero */ + if (bpf_op == BPF_MOD) + emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO); + break; + } + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + emit_instr(ctx, ddivu, dst, MIPS_R_AT); + if (bpf_op == BPF_DIV) + emit_instr(ctx, mflo, dst); + else + emit_instr(ctx, mfhi, dst); + break; + case BPF_ALU64 | BPF_MOV | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_ADD | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_SUB | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_XOR | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_OR | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_AND | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_MUL | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_DIV | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_MOD | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_LSH | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_RSH | BPF_X: /* ALU64_REG */ + case BPF_ALU64 | BPF_ARSH | BPF_X: /* ALU64_REG */ + src = ebpf_to_mips_reg(ctx, insn, src_reg); + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (src < 0 || dst < 0) + return -EINVAL; + if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT) + emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); + did_move = false; + if (insn->src_reg == BPF_REG_10) { + if (bpf_op == BPF_MOV) { + emit_instr(ctx, daddiu, dst, MIPS_R_SP, MAX_BPF_STACK); + did_move = true; + } else { + emit_instr(ctx, daddiu, MIPS_R_AT, MIPS_R_SP, MAX_BPF_STACK); + src = MIPS_R_AT; + } + } else if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) { + int tmp_reg = MIPS_R_AT; + + if (bpf_op == BPF_MOV) { + tmp_reg = dst; + did_move = true; + } + emit_instr(ctx, daddu, tmp_reg, src, MIPS_R_ZERO); + emit_instr(ctx, dinsu, tmp_reg, MIPS_R_ZERO, 32, 32); + src = MIPS_R_AT; + } + switch (bpf_op) { + case BPF_MOV: + if (!did_move) + emit_instr(ctx, daddu, dst, src, MIPS_R_ZERO); + break; + case BPF_ADD: + emit_instr(ctx, daddu, dst, dst, src); + break; + case BPF_SUB: + emit_instr(ctx, dsubu, dst, dst, src); + break; + case BPF_XOR: + emit_instr(ctx, xor, dst, dst, src); + break; + case BPF_OR: + emit_instr(ctx, or, dst, dst, src); + break; + case BPF_AND: + emit_instr(ctx, and, dst, dst, src); + break; + case BPF_MUL: + emit_instr(ctx, dmultu, dst, src); + emit_instr(ctx, mflo, dst); + break; + case BPF_DIV: + case BPF_MOD: + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off); + emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src); + emit_instr(ctx, ddivu, dst, src); + if (bpf_op == BPF_DIV) + emit_instr(ctx, mflo, dst); + else + emit_instr(ctx, mfhi, dst); + break; + case BPF_LSH: + emit_instr(ctx, dsllv, dst, dst, src); + break; + case BPF_RSH: + emit_instr(ctx, dsrlv, dst, dst, src); + break; + case BPF_ARSH: + emit_instr(ctx, dsrav, dst, dst, src); + break; + default: + pr_err("ALU64_REG NOT HANDLED\n"); + return -EINVAL; + } + break; + case BPF_ALU | BPF_MOV | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_ADD | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_SUB | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_XOR | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_OR | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_AND | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_MUL | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_DIV | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_MOD | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_LSH | BPF_X: /* ALU_REG */ + case BPF_ALU | BPF_RSH | BPF_X: /* ALU_REG */ + src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (src < 0 || dst < 0) + return -EINVAL; + td = get_reg_val_type(ctx, this_idx, insn->dst_reg); + if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) { + /* sign extend */ + emit_instr(ctx, sll, dst, dst, 0); + } + did_move = false; + ts = get_reg_val_type(ctx, this_idx, insn->src_reg); + if (ts == REG_64BIT || ts == REG_32BIT_ZERO_EX) { + int tmp_reg = MIPS_R_AT; + + if (bpf_op == BPF_MOV) { + tmp_reg = dst; + did_move = true; + } + /* sign extend */ + emit_instr(ctx, sll, tmp_reg, src, 0); + src = MIPS_R_AT; + } + switch (bpf_op) { + case BPF_MOV: + if (!did_move) + emit_instr(ctx, addu, dst, src, MIPS_R_ZERO); + break; + case BPF_ADD: + emit_instr(ctx, addu, dst, dst, src); + break; + case BPF_SUB: + emit_instr(ctx, subu, dst, dst, src); + break; + case BPF_XOR: + emit_instr(ctx, xor, dst, dst, src); + break; + case BPF_OR: + emit_instr(ctx, or, dst, dst, src); + break; + case BPF_AND: + emit_instr(ctx, and, dst, dst, src); + break; + case BPF_MUL: + emit_instr(ctx, mul, dst, dst, src); + break; + case BPF_DIV: + case BPF_MOD: + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off); + emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src); + emit_instr(ctx, divu, dst, src); + if (bpf_op == BPF_DIV) + emit_instr(ctx, mflo, dst); + else + emit_instr(ctx, mfhi, dst); + break; + case BPF_LSH: + emit_instr(ctx, sllv, dst, dst, src); + break; + case BPF_RSH: + emit_instr(ctx, srlv, dst, dst, src); + break; + default: + pr_err("ALU_REG NOT HANDLED\n"); + return -EINVAL; + } + break; + case BPF_JMP | BPF_EXIT: + if (this_idx + 1 < exit_idx) { + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off); + emit_instr(ctx, nop); + } + break; + case BPF_JMP | BPF_JEQ | BPF_K: /* JMP_IMM */ + case BPF_JMP | BPF_JNE | BPF_K: /* JMP_IMM */ + cmp_eq = (bpf_op == BPF_JEQ); + dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); + if (dst < 0) + return dst; + if (insn->imm == 0) { + src = MIPS_R_ZERO; + } else { + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + src = MIPS_R_AT; + } + goto jeq_common; + case BPF_JMP | BPF_JEQ | BPF_X: /* JMP_REG */ + case BPF_JMP | BPF_JNE | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: + case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: + case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JSET | BPF_X: + src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (src < 0 || dst < 0) + return -EINVAL; + td = get_reg_val_type(ctx, this_idx, insn->dst_reg); + ts = get_reg_val_type(ctx, this_idx, insn->src_reg); + if (td == REG_32BIT && ts != REG_32BIT) { + emit_instr(ctx, sll, MIPS_R_AT, src, 0); + src = MIPS_R_AT; + } else if (ts == REG_32BIT && td != REG_32BIT) { + emit_instr(ctx, sll, MIPS_R_AT, dst, 0); + dst = MIPS_R_AT; + } + if (bpf_op == BPF_JSET) { + emit_instr(ctx, and, MIPS_R_AT, dst, src); + cmp_eq = false; + dst = MIPS_R_AT; + src = MIPS_R_ZERO; + } else if (bpf_op == BPF_JSGT || bpf_op == BPF_JSLE) { + emit_instr(ctx, dsubu, MIPS_R_AT, dst, src); + if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) { + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + if (bpf_op == BPF_JSGT) + emit_instr(ctx, blez, MIPS_R_AT, b_off); + else + emit_instr(ctx, bgtz, MIPS_R_AT, b_off); + emit_instr(ctx, nop); + return 2; /* We consumed the exit. */ + } + b_off = b_imm(this_idx + insn->off + 1, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + if (bpf_op == BPF_JSGT) + emit_instr(ctx, bgtz, MIPS_R_AT, b_off); + else + emit_instr(ctx, blez, MIPS_R_AT, b_off); + emit_instr(ctx, nop); + break; + } else if (bpf_op == BPF_JSGE || bpf_op == BPF_JSLT) { + emit_instr(ctx, slt, MIPS_R_AT, dst, src); + cmp_eq = bpf_op == BPF_JSGE; + dst = MIPS_R_AT; + src = MIPS_R_ZERO; + } else if (bpf_op == BPF_JGT || bpf_op == BPF_JLE) { + /* dst or src could be AT */ + emit_instr(ctx, dsubu, MIPS_R_T8, dst, src); + emit_instr(ctx, sltu, MIPS_R_AT, dst, src); + /* SP known to be non-zero, movz becomes boolean not */ + emit_instr(ctx, movz, MIPS_R_T9, MIPS_R_SP, MIPS_R_T8); + emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_ZERO, MIPS_R_T8); + emit_instr(ctx, or, MIPS_R_AT, MIPS_R_T9, MIPS_R_AT); + cmp_eq = bpf_op == BPF_JGT; + dst = MIPS_R_AT; + src = MIPS_R_ZERO; + } else if (bpf_op == BPF_JGE || bpf_op == BPF_JLT) { + emit_instr(ctx, sltu, MIPS_R_AT, dst, src); + cmp_eq = bpf_op == BPF_JGE; + dst = MIPS_R_AT; + src = MIPS_R_ZERO; + } else { /* JNE/JEQ case */ + cmp_eq = (bpf_op == BPF_JEQ); + } +jeq_common: + /* + * If the next insn is EXIT and we are jumping arround + * only it, invert the sense of the compare and + * conditionally jump to the exit. Poor man's branch + * chaining. + */ + if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) { + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) { + target = j_target(ctx, exit_idx); + if (target == (unsigned int)-1) + return -E2BIG; + cmp_eq = !cmp_eq; + b_off = 4 * 3; + if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) { + ctx->offsets[this_idx] |= OFFSETS_B_CONV; + ctx->long_b_conversion = 1; + } + } + + if (cmp_eq) + emit_instr(ctx, bne, dst, src, b_off); + else + emit_instr(ctx, beq, dst, src, b_off); + emit_instr(ctx, nop); + if (ctx->offsets[this_idx] & OFFSETS_B_CONV) { + emit_instr(ctx, j, target); + emit_instr(ctx, nop); + } + return 2; /* We consumed the exit. */ + } + b_off = b_imm(this_idx + insn->off + 1, ctx); + if (is_bad_offset(b_off)) { + target = j_target(ctx, this_idx + insn->off + 1); + if (target == (unsigned int)-1) + return -E2BIG; + cmp_eq = !cmp_eq; + b_off = 4 * 3; + if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) { + ctx->offsets[this_idx] |= OFFSETS_B_CONV; + ctx->long_b_conversion = 1; + } + } + + if (cmp_eq) + emit_instr(ctx, beq, dst, src, b_off); + else + emit_instr(ctx, bne, dst, src, b_off); + emit_instr(ctx, nop); + if (ctx->offsets[this_idx] & OFFSETS_B_CONV) { + emit_instr(ctx, j, target); + emit_instr(ctx, nop); + } + break; + case BPF_JMP | BPF_JSGT | BPF_K: /* JMP_IMM */ + case BPF_JMP | BPF_JSGE | BPF_K: /* JMP_IMM */ + case BPF_JMP | BPF_JSLT | BPF_K: /* JMP_IMM */ + case BPF_JMP | BPF_JSLE | BPF_K: /* JMP_IMM */ + cmp_eq = (bpf_op == BPF_JSGE); + dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); + if (dst < 0) + return dst; + + if (insn->imm == 0) { + if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) { + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + switch (bpf_op) { + case BPF_JSGT: + emit_instr(ctx, blez, dst, b_off); + break; + case BPF_JSGE: + emit_instr(ctx, bltz, dst, b_off); + break; + case BPF_JSLT: + emit_instr(ctx, bgez, dst, b_off); + break; + case BPF_JSLE: + emit_instr(ctx, bgtz, dst, b_off); + break; + } + emit_instr(ctx, nop); + return 2; /* We consumed the exit. */ + } + b_off = b_imm(this_idx + insn->off + 1, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + switch (bpf_op) { + case BPF_JSGT: + emit_instr(ctx, bgtz, dst, b_off); + break; + case BPF_JSGE: + emit_instr(ctx, bgez, dst, b_off); + break; + case BPF_JSLT: + emit_instr(ctx, bltz, dst, b_off); + break; + case BPF_JSLE: + emit_instr(ctx, blez, dst, b_off); + break; + } + emit_instr(ctx, nop); + break; + } + /* + * only "LT" compare available, so we must use imm + 1 + * to generate "GT" and imm -1 to generate LE + */ + if (bpf_op == BPF_JSGT) + t64s = insn->imm + 1; + else if (bpf_op == BPF_JSLE) + t64s = insn->imm + 1; + else + t64s = insn->imm; + + cmp_eq = bpf_op == BPF_JSGT || bpf_op == BPF_JSGE; + if (t64s >= S16_MIN && t64s <= S16_MAX) { + emit_instr(ctx, slti, MIPS_R_AT, dst, (int)t64s); + src = MIPS_R_AT; + dst = MIPS_R_ZERO; + goto jeq_common; + } + emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s); + emit_instr(ctx, slt, MIPS_R_AT, dst, MIPS_R_AT); + src = MIPS_R_AT; + dst = MIPS_R_ZERO; + goto jeq_common; + + case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: + cmp_eq = (bpf_op == BPF_JGE); + dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); + if (dst < 0) + return dst; + /* + * only "LT" compare available, so we must use imm + 1 + * to generate "GT" and imm -1 to generate LE + */ + if (bpf_op == BPF_JGT) + t64s = (u64)(u32)(insn->imm) + 1; + else if (bpf_op == BPF_JLE) + t64s = (u64)(u32)(insn->imm) + 1; + else + t64s = (u64)(u32)(insn->imm); + + cmp_eq = bpf_op == BPF_JGT || bpf_op == BPF_JGE; + + emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s); + emit_instr(ctx, sltu, MIPS_R_AT, dst, MIPS_R_AT); + src = MIPS_R_AT; + dst = MIPS_R_ZERO; + goto jeq_common; + + case BPF_JMP | BPF_JSET | BPF_K: /* JMP_IMM */ + dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); + if (dst < 0) + return dst; + + if (ctx->use_bbit_insns && hweight32((u32)insn->imm) == 1) { + if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) { + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, bbit0, dst, ffs((u32)insn->imm) - 1, b_off); + emit_instr(ctx, nop); + return 2; /* We consumed the exit. */ + } + b_off = b_imm(this_idx + insn->off + 1, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_instr(ctx, bbit1, dst, ffs((u32)insn->imm) - 1, b_off); + emit_instr(ctx, nop); + break; + } + t64 = (u32)insn->imm; + emit_const_to_reg(ctx, MIPS_R_AT, t64); + emit_instr(ctx, and, MIPS_R_AT, dst, MIPS_R_AT); + src = MIPS_R_AT; + dst = MIPS_R_ZERO; + cmp_eq = false; + goto jeq_common; + + case BPF_JMP | BPF_JA: + /* + * Prefer relative branch for easier debugging, but + * fall back if needed. + */ + b_off = b_imm(this_idx + insn->off + 1, ctx); + if (is_bad_offset(b_off)) { + target = j_target(ctx, this_idx + insn->off + 1); + if (target == (unsigned int)-1) + return -E2BIG; + emit_instr(ctx, j, target); + } else { + emit_instr(ctx, b, b_off); + } + emit_instr(ctx, nop); + break; + case BPF_LD | BPF_DW | BPF_IMM: + if (insn->src_reg != 0) + return -EINVAL; + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + t64 = ((u64)(u32)insn->imm) | ((u64)(insn + 1)->imm << 32); + emit_const_to_reg(ctx, dst, t64); + return 2; /* Double slot insn */ + + case BPF_JMP | BPF_CALL: + ctx->flags |= EBPF_SAVE_RA; + t64s = (s64)insn->imm + (s64)__bpf_call_base; + emit_const_to_reg(ctx, MIPS_R_T9, (u64)t64s); + emit_instr(ctx, jalr, MIPS_R_RA, MIPS_R_T9); + /* delay slot */ + emit_instr(ctx, nop); + break; + + case BPF_JMP | BPF_TAIL_CALL: + if (emit_bpf_tail_call(ctx, this_idx)) + return -EINVAL; + break; + + case BPF_LD | BPF_B | BPF_ABS: + case BPF_LD | BPF_H | BPF_ABS: + case BPF_LD | BPF_W | BPF_ABS: + case BPF_LD | BPF_DW | BPF_ABS: + ctx->flags |= EBPF_SAVE_RA; + + gen_imm_to_reg(insn, MIPS_R_A1, ctx); + emit_instr(ctx, addiu, MIPS_R_A2, MIPS_R_ZERO, size_to_len(insn)); + + if (insn->imm < 0) { + emit_const_to_reg(ctx, MIPS_R_T9, (u64)bpf_internal_load_pointer_neg_helper); + } else { + emit_const_to_reg(ctx, MIPS_R_T9, (u64)ool_skb_header_pointer); + emit_instr(ctx, daddiu, MIPS_R_A3, MIPS_R_SP, ctx->tmp_offset); + } + goto ld_skb_common; + + case BPF_LD | BPF_B | BPF_IND: + case BPF_LD | BPF_H | BPF_IND: + case BPF_LD | BPF_W | BPF_IND: + case BPF_LD | BPF_DW | BPF_IND: + ctx->flags |= EBPF_SAVE_RA; + src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); + if (src < 0) + return src; + ts = get_reg_val_type(ctx, this_idx, insn->src_reg); + if (ts == REG_32BIT_ZERO_EX) { + /* sign extend */ + emit_instr(ctx, sll, MIPS_R_A1, src, 0); + src = MIPS_R_A1; + } + if (insn->imm >= S16_MIN && insn->imm <= S16_MAX) { + emit_instr(ctx, daddiu, MIPS_R_A1, src, insn->imm); + } else { + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + emit_instr(ctx, daddu, MIPS_R_A1, MIPS_R_AT, src); + } + /* truncate to 32-bit int */ + emit_instr(ctx, sll, MIPS_R_A1, MIPS_R_A1, 0); + emit_instr(ctx, daddiu, MIPS_R_A3, MIPS_R_SP, ctx->tmp_offset); + emit_instr(ctx, slt, MIPS_R_AT, MIPS_R_A1, MIPS_R_ZERO); + + emit_const_to_reg(ctx, MIPS_R_T8, (u64)bpf_internal_load_pointer_neg_helper); + emit_const_to_reg(ctx, MIPS_R_T9, (u64)ool_skb_header_pointer); + emit_instr(ctx, addiu, MIPS_R_A2, MIPS_R_ZERO, size_to_len(insn)); + emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_T8, MIPS_R_AT); + +ld_skb_common: + emit_instr(ctx, jalr, MIPS_R_RA, MIPS_R_T9); + /* delay slot move */ + emit_instr(ctx, daddu, MIPS_R_A0, MIPS_R_S0, MIPS_R_ZERO); + + /* Check the error value */ + b_off = b_imm(exit_idx, ctx); + if (is_bad_offset(b_off)) { + target = j_target(ctx, exit_idx); + if (target == (unsigned int)-1) + return -E2BIG; + + if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) { + ctx->offsets[this_idx] |= OFFSETS_B_CONV; + ctx->long_b_conversion = 1; + } + emit_instr(ctx, bne, MIPS_R_V0, MIPS_R_ZERO, 4 * 3); + emit_instr(ctx, nop); + emit_instr(ctx, j, target); + emit_instr(ctx, nop); + } else { + emit_instr(ctx, beq, MIPS_R_V0, MIPS_R_ZERO, b_off); + emit_instr(ctx, nop); + } + +#ifdef __BIG_ENDIAN + need_swap = false; +#else + need_swap = true; +#endif + dst = MIPS_R_V0; + switch (BPF_SIZE(insn->code)) { + case BPF_B: + emit_instr(ctx, lbu, dst, 0, MIPS_R_V0); + break; + case BPF_H: + emit_instr(ctx, lhu, dst, 0, MIPS_R_V0); + if (need_swap) + emit_instr(ctx, wsbh, dst, dst); + break; + case BPF_W: + emit_instr(ctx, lw, dst, 0, MIPS_R_V0); + if (need_swap) { + emit_instr(ctx, wsbh, dst, dst); + emit_instr(ctx, rotr, dst, dst, 16); + } + break; + case BPF_DW: + emit_instr(ctx, ld, dst, 0, MIPS_R_V0); + if (need_swap) { + emit_instr(ctx, dsbh, dst, dst); + emit_instr(ctx, dshd, dst, dst); + } + break; + } + + break; + case BPF_ALU | BPF_END | BPF_FROM_BE: + case BPF_ALU | BPF_END | BPF_FROM_LE: + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + td = get_reg_val_type(ctx, this_idx, insn->dst_reg); + if (insn->imm == 64 && td == REG_32BIT) + emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); + + if (insn->imm != 64 && + (td == REG_64BIT || td == REG_32BIT_ZERO_EX)) { + /* sign extend */ + emit_instr(ctx, sll, dst, dst, 0); + } + +#ifdef __BIG_ENDIAN + need_swap = (BPF_SRC(insn->code) == BPF_FROM_LE); +#else + need_swap = (BPF_SRC(insn->code) == BPF_FROM_BE); +#endif + if (insn->imm == 16) { + if (need_swap) + emit_instr(ctx, wsbh, dst, dst); + emit_instr(ctx, andi, dst, dst, 0xffff); + } else if (insn->imm == 32) { + if (need_swap) { + emit_instr(ctx, wsbh, dst, dst); + emit_instr(ctx, rotr, dst, dst, 16); + } + } else { /* 64-bit*/ + if (need_swap) { + emit_instr(ctx, dsbh, dst, dst); + emit_instr(ctx, dshd, dst, dst); + } + } + break; + + case BPF_ST | BPF_B | BPF_MEM: + case BPF_ST | BPF_H | BPF_MEM: + case BPF_ST | BPF_W | BPF_MEM: + case BPF_ST | BPF_DW | BPF_MEM: + if (insn->dst_reg == BPF_REG_10) { + ctx->flags |= EBPF_SEEN_FP; + dst = MIPS_R_SP; + mem_off = insn->off + MAX_BPF_STACK; + } else { + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + mem_off = insn->off; + } + gen_imm_to_reg(insn, MIPS_R_AT, ctx); + switch (BPF_SIZE(insn->code)) { + case BPF_B: + emit_instr(ctx, sb, MIPS_R_AT, mem_off, dst); + break; + case BPF_H: + emit_instr(ctx, sh, MIPS_R_AT, mem_off, dst); + break; + case BPF_W: + emit_instr(ctx, sw, MIPS_R_AT, mem_off, dst); + break; + case BPF_DW: + emit_instr(ctx, sd, MIPS_R_AT, mem_off, dst); + break; + } + break; + + case BPF_LDX | BPF_B | BPF_MEM: + case BPF_LDX | BPF_H | BPF_MEM: + case BPF_LDX | BPF_W | BPF_MEM: + case BPF_LDX | BPF_DW | BPF_MEM: + if (insn->src_reg == BPF_REG_10) { + ctx->flags |= EBPF_SEEN_FP; + src = MIPS_R_SP; + mem_off = insn->off + MAX_BPF_STACK; + } else { + src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); + if (src < 0) + return src; + mem_off = insn->off; + } + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + switch (BPF_SIZE(insn->code)) { + case BPF_B: + emit_instr(ctx, lbu, dst, mem_off, src); + break; + case BPF_H: + emit_instr(ctx, lhu, dst, mem_off, src); + break; + case BPF_W: + emit_instr(ctx, lw, dst, mem_off, src); + break; + case BPF_DW: + emit_instr(ctx, ld, dst, mem_off, src); + break; + } + break; + + case BPF_STX | BPF_B | BPF_MEM: + case BPF_STX | BPF_H | BPF_MEM: + case BPF_STX | BPF_W | BPF_MEM: + case BPF_STX | BPF_DW | BPF_MEM: + case BPF_STX | BPF_W | BPF_XADD: + case BPF_STX | BPF_DW | BPF_XADD: + if (insn->dst_reg == BPF_REG_10) { + ctx->flags |= EBPF_SEEN_FP; + dst = MIPS_R_SP; + mem_off = insn->off + MAX_BPF_STACK; + } else { + dst = ebpf_to_mips_reg(ctx, insn, dst_reg); + if (dst < 0) + return dst; + mem_off = insn->off; + } + src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); + if (src < 0) + return dst; + if (BPF_MODE(insn->code) == BPF_XADD) { + switch (BPF_SIZE(insn->code)) { + case BPF_W: + if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) { + emit_instr(ctx, sll, MIPS_R_AT, src, 0); + src = MIPS_R_AT; + } + emit_instr(ctx, ll, MIPS_R_T8, mem_off, dst); + emit_instr(ctx, addu, MIPS_R_T8, MIPS_R_T8, src); + emit_instr(ctx, sc, MIPS_R_T8, mem_off, dst); + /* + * On failure back up to LL (-4 + * instructions of 4 bytes each + */ + emit_instr(ctx, beq, MIPS_R_T8, MIPS_R_ZERO, -4 * 4); + emit_instr(ctx, nop); + break; + case BPF_DW: + if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) { + emit_instr(ctx, daddu, MIPS_R_AT, src, MIPS_R_ZERO); + emit_instr(ctx, dinsu, MIPS_R_AT, MIPS_R_ZERO, 32, 32); + src = MIPS_R_AT; + } + emit_instr(ctx, lld, MIPS_R_T8, mem_off, dst); + emit_instr(ctx, daddu, MIPS_R_T8, MIPS_R_T8, src); + emit_instr(ctx, scd, MIPS_R_T8, mem_off, dst); + emit_instr(ctx, beq, MIPS_R_T8, MIPS_R_ZERO, -4 * 4); + emit_instr(ctx, nop); + break; + } + } else { /* BPF_MEM */ + switch (BPF_SIZE(insn->code)) { + case BPF_B: + emit_instr(ctx, sb, src, mem_off, dst); + break; + case BPF_H: + emit_instr(ctx, sh, src, mem_off, dst); + break; + case BPF_W: + emit_instr(ctx, sw, src, mem_off, dst); + break; + case BPF_DW: + if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) { + emit_instr(ctx, daddu, MIPS_R_AT, src, MIPS_R_ZERO); + emit_instr(ctx, dinsu, MIPS_R_AT, MIPS_R_ZERO, 32, 32); + src = MIPS_R_AT; + } + emit_instr(ctx, sd, src, mem_off, dst); + break; + } + } + break; + + default: + pr_err("NOT HANDLED %d - (%02x)\n", + this_idx, (unsigned int)insn->code); + return -EINVAL; + } + return 1; +} + +#define RVT_VISITED_MASK 0xc000000000000000ull +#define RVT_FALL_THROUGH 0x4000000000000000ull +#define RVT_BRANCH_TAKEN 0x8000000000000000ull +#define RVT_DONE (RVT_FALL_THROUGH | RVT_BRANCH_TAKEN) + +static int build_int_body(struct jit_ctx *ctx) +{ + const struct bpf_prog *prog = ctx->skf; + const struct bpf_insn *insn; + int i, r; + + for (i = 0; i < prog->len; ) { + insn = prog->insnsi + i; + if ((ctx->reg_val_types[i] & RVT_VISITED_MASK) == 0) { + /* dead instruction, don't emit it. */ + i++; + continue; + } + + if (ctx->target == NULL) + ctx->offsets[i] = (ctx->offsets[i] & OFFSETS_B_CONV) | (ctx->idx * 4); + + r = build_one_insn(insn, ctx, i, prog->len); + if (r < 0) + return r; + i += r; + } + /* epilogue offset */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + /* + * All exits have an offset of the epilogue, some offsets may + * not have been set due to banch-around threading, so set + * them now. + */ + if (ctx->target == NULL) + for (i = 0; i < prog->len; i++) { + insn = prog->insnsi + i; + if (insn->code == (BPF_JMP | BPF_EXIT)) + ctx->offsets[i] = ctx->idx * 4; + } + return 0; +} + +/* return the last idx processed, or negative for error */ +static int reg_val_propagate_range(struct jit_ctx *ctx, u64 initial_rvt, + int start_idx, bool follow_taken) +{ + const struct bpf_prog *prog = ctx->skf; + const struct bpf_insn *insn; + u64 exit_rvt = initial_rvt; + u64 *rvt = ctx->reg_val_types; + int idx; + int reg; + + for (idx = start_idx; idx < prog->len; idx++) { + rvt[idx] = (rvt[idx] & RVT_VISITED_MASK) | exit_rvt; + insn = prog->insnsi + idx; + switch (BPF_CLASS(insn->code)) { + case BPF_ALU: + switch (BPF_OP(insn->code)) { + case BPF_ADD: + case BPF_SUB: + case BPF_MUL: + case BPF_DIV: + case BPF_OR: + case BPF_AND: + case BPF_LSH: + case BPF_RSH: + case BPF_NEG: + case BPF_MOD: + case BPF_XOR: + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT); + break; + case BPF_MOV: + if (BPF_SRC(insn->code)) { + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT); + } else { + /* IMM to REG move*/ + if (insn->imm >= 0) + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS); + else + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT); + } + break; + case BPF_END: + if (insn->imm == 64) + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT); + else if (insn->imm == 32) + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT); + else /* insn->imm == 16 */ + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS); + break; + } + rvt[idx] |= RVT_DONE; + break; + case BPF_ALU64: + switch (BPF_OP(insn->code)) { + case BPF_MOV: + if (BPF_SRC(insn->code)) { + /* REG to REG move*/ + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT); + } else { + /* IMM to REG move*/ + if (insn->imm >= 0) + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS); + else + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT_32BIT); + } + break; + default: + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT); + } + rvt[idx] |= RVT_DONE; + break; + case BPF_LD: + switch (BPF_SIZE(insn->code)) { + case BPF_DW: + if (BPF_MODE(insn->code) == BPF_IMM) { + s64 val; + + val = (s64)((u32)insn->imm | ((u64)(insn + 1)->imm << 32)); + if (val > 0 && val <= S32_MAX) + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS); + else if (val >= S32_MIN && val <= S32_MAX) + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT_32BIT); + else + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT); + rvt[idx] |= RVT_DONE; + idx++; + } else { + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT); + } + break; + case BPF_B: + case BPF_H: + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS); + break; + case BPF_W: + if (BPF_MODE(insn->code) == BPF_IMM) + set_reg_val_type(&exit_rvt, insn->dst_reg, + insn->imm >= 0 ? REG_32BIT_POS : REG_32BIT); + else + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT); + break; + } + rvt[idx] |= RVT_DONE; + break; + case BPF_LDX: + switch (BPF_SIZE(insn->code)) { + case BPF_DW: + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT); + break; + case BPF_B: + case BPF_H: + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS); + break; + case BPF_W: + set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT); + break; + } + rvt[idx] |= RVT_DONE; + break; + case BPF_JMP: + switch (BPF_OP(insn->code)) { + case BPF_EXIT: + rvt[idx] = RVT_DONE | exit_rvt; + rvt[prog->len] = exit_rvt; + return idx; + case BPF_JA: + rvt[idx] |= RVT_DONE; + idx += insn->off; + break; + case BPF_JEQ: + case BPF_JGT: + case BPF_JGE: + case BPF_JLT: + case BPF_JLE: + case BPF_JSET: + case BPF_JNE: + case BPF_JSGT: + case BPF_JSGE: + case BPF_JSLT: + case BPF_JSLE: + if (follow_taken) { + rvt[idx] |= RVT_BRANCH_TAKEN; + idx += insn->off; + follow_taken = false; + } else { + rvt[idx] |= RVT_FALL_THROUGH; + } + break; + case BPF_CALL: + set_reg_val_type(&exit_rvt, BPF_REG_0, REG_64BIT); + /* Upon call return, argument registers are clobbered. */ + for (reg = BPF_REG_0; reg <= BPF_REG_5; reg++) + set_reg_val_type(&exit_rvt, reg, REG_64BIT); + + rvt[idx] |= RVT_DONE; + break; + default: + WARN(1, "Unhandled BPF_JMP case.\n"); + rvt[idx] |= RVT_DONE; + break; + } + break; + default: + rvt[idx] |= RVT_DONE; + break; + } + } + return idx; +} + +/* + * Track the value range (i.e. 32-bit vs. 64-bit) of each register at + * each eBPF insn. This allows unneeded sign and zero extension + * operations to be omitted. + * + * Doesn't handle yet confluence of control paths with conflicting + * ranges, but it is good enough for most sane code. + */ +static int reg_val_propagate(struct jit_ctx *ctx) +{ + const struct bpf_prog *prog = ctx->skf; + u64 exit_rvt; + int reg; + int i; + + /* + * 11 registers * 3 bits/reg leaves top bits free for other + * uses. Bit-62..63 used to see if we have visited an insn. + */ + exit_rvt = 0; + + /* Upon entry, argument registers are 64-bit. */ + for (reg = BPF_REG_1; reg <= BPF_REG_5; reg++) + set_reg_val_type(&exit_rvt, reg, REG_64BIT); + + /* + * First follow all conditional branches on the fall-through + * edge of control flow.. + */ + reg_val_propagate_range(ctx, exit_rvt, 0, false); +restart_search: + /* + * Then repeatedly find the first conditional branch where + * both edges of control flow have not been taken, and follow + * the branch taken edge. We will end up restarting the + * search once per conditional branch insn. + */ + for (i = 0; i < prog->len; i++) { + u64 rvt = ctx->reg_val_types[i]; + + if ((rvt & RVT_VISITED_MASK) == RVT_DONE || + (rvt & RVT_VISITED_MASK) == 0) + continue; + if ((rvt & RVT_VISITED_MASK) == RVT_FALL_THROUGH) { + reg_val_propagate_range(ctx, rvt & ~RVT_VISITED_MASK, i, true); + } else { /* RVT_BRANCH_TAKEN */ + WARN(1, "Unexpected RVT_BRANCH_TAKEN case.\n"); + reg_val_propagate_range(ctx, rvt & ~RVT_VISITED_MASK, i, false); + } + goto restart_search; + } + /* + * Eventually all conditional branches have been followed on + * both branches and we are done. Any insn that has not been + * visited at this point is dead. + */ + + return 0; +} + +static void jit_fill_hole(void *area, unsigned int size) +{ + u32 *p; + + /* We are guaranteed to have aligned memory. */ + for (p = area; size >= sizeof(u32); size -= sizeof(u32)) + uasm_i_break(&p, BRK_BUG); /* Increments p */ +} + +struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) +{ + struct bpf_prog *orig_prog = prog; + bool tmp_blinded = false; + struct bpf_prog *tmp; + struct bpf_binary_header *header = NULL; + struct jit_ctx ctx; + unsigned int image_size; + u8 *image_ptr; + + if (!bpf_jit_enable || !cpu_has_mips64r2) + return prog; + + tmp = bpf_jit_blind_constants(prog); + /* If blinding was requested and we failed during blinding, + * we must fall back to the interpreter. + */ + if (IS_ERR(tmp)) + return orig_prog; + if (tmp != prog) { + tmp_blinded = true; + prog = tmp; + } + + memset(&ctx, 0, sizeof(ctx)); + + preempt_disable(); + switch (current_cpu_type()) { + case CPU_CAVIUM_OCTEON: + case CPU_CAVIUM_OCTEON_PLUS: + case CPU_CAVIUM_OCTEON2: + case CPU_CAVIUM_OCTEON3: + ctx.use_bbit_insns = 1; + break; + default: + ctx.use_bbit_insns = 0; + } + preempt_enable(); + + ctx.offsets = kcalloc(prog->len + 1, sizeof(*ctx.offsets), GFP_KERNEL); + if (ctx.offsets == NULL) + goto out_err; + + ctx.reg_val_types = kcalloc(prog->len + 1, sizeof(*ctx.reg_val_types), GFP_KERNEL); + if (ctx.reg_val_types == NULL) + goto out_err; + + ctx.skf = prog; + + if (reg_val_propagate(&ctx)) + goto out_err; + + /* + * First pass discovers used resources and instruction offsets + * assuming short branches are used. + */ + if (build_int_body(&ctx)) + goto out_err; + + /* + * If no calls are made (EBPF_SAVE_RA), then tail call count + * in $v1, else we must save in n$s4. + */ + if (ctx.flags & EBPF_SEEN_TC) { + if (ctx.flags & EBPF_SAVE_RA) + ctx.flags |= EBPF_SAVE_S4; + else + ctx.flags |= EBPF_TCC_IN_V1; + } + + /* + * Second pass generates offsets, if any branches are out of + * range a jump-around long sequence is generated, and we have + * to try again from the beginning to generate the new + * offsets. This is done until no additional conversions are + * necessary. + */ + do { + ctx.idx = 0; + ctx.gen_b_offsets = 1; + ctx.long_b_conversion = 0; + if (gen_int_prologue(&ctx)) + goto out_err; + if (build_int_body(&ctx)) + goto out_err; + if (build_int_epilogue(&ctx, MIPS_R_RA)) + goto out_err; + } while (ctx.long_b_conversion); + + image_size = 4 * ctx.idx; + + header = bpf_jit_binary_alloc(image_size, &image_ptr, + sizeof(u32), jit_fill_hole); + if (header == NULL) + goto out_err; + + ctx.target = (u32 *)image_ptr; + + /* Third pass generates the code */ + ctx.idx = 0; + if (gen_int_prologue(&ctx)) + goto out_err; + if (build_int_body(&ctx)) + goto out_err; + if (build_int_epilogue(&ctx, MIPS_R_RA)) + goto out_err; + + /* Update the icache */ + flush_icache_range((unsigned long)ctx.target, + (unsigned long)(ctx.target + ctx.idx * sizeof(u32))); + + if (bpf_jit_enable > 1) + /* Dump JIT code */ + bpf_jit_dump(prog->len, image_size, 2, ctx.target); + + bpf_jit_binary_lock_ro(header); + prog->bpf_func = (void *)ctx.target; + prog->jited = 1; + prog->jited_len = image_size; +out_normal: + if (tmp_blinded) + bpf_jit_prog_release_other(prog, prog == orig_prog ? + tmp : orig_prog); + kfree(ctx.offsets); + kfree(ctx.reg_val_types); + + return prog; + +out_err: + prog = orig_prog; + if (header) + bpf_jit_binary_free(header); + goto out_normal; +} diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index bddf1ef553a4f695d320d4f88eb7f28b079cec94..39a300bd6cc274e5812fb6450984b5cc41843507 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -122,7 +122,7 @@ static void nlm_init_secondary(void) int hwtid; hwtid = hard_smp_processor_id(); - current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; + cpu_set_core(¤t_cpu_data, hwtid / NLM_THREADS_PER_CORE); current_cpu_data.package = nlm_nodeid(); nlm_percpu_init(hwtid); nlm_smp_irq_init(hwtid); @@ -147,7 +147,7 @@ unsigned long nlm_next_gp; unsigned long nlm_next_sp; static cpumask_t phys_cpu_present_mask; -void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) +int nlm_boot_secondary(int logical_cpu, struct task_struct *idle) { uint64_t picbase; int hwtid; @@ -161,6 +161,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) /* barrier for sp/gp store above */ __sync(); nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */ + + return 0; } void __init nlm_smp_setup(void) @@ -272,7 +274,7 @@ int nlm_wakeup_secondary_cpus(void) return 0; } -struct plat_smp_ops nlm_smp_ops = { +const struct plat_smp_ops nlm_smp_ops = { .send_ipi_single = nlm_send_ipi_single, .send_ipi_mask = nlm_send_ipi_mask, .init_secondary = nlm_init_secondary, diff --git a/arch/mips/netlogic/xlr/platform-flash.c b/arch/mips/netlogic/xlr/platform-flash.c index f03131fec41d4508737d33b344bf9f59dbc2fb34..4d1b4c003376d1d0d196c623738e60f8d07826e4 100644 --- a/arch/mips/netlogic/xlr/platform-flash.c +++ b/arch/mips/netlogic/xlr/platform-flash.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index c57da6f13929a4e9a52ae6156dd9ddbf38909511..c3e4c18ef8d4d1ca5e4dc74ffd990b800ca0fd1b 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -38,9 +38,9 @@ static int perfcount_irq; #ifdef CONFIG_MIPS_MT_SMP static int cpu_has_mipsmt_pertccounters; #define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \ - M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) + M_PERFCTL_VPEID(cpu_vpe_id(¤t_cpu_data))) #define vpe_id() (cpu_has_mipsmt_pertccounters ? \ - 0 : cpu_data[smp_processor_id()].vpe_id) + 0 : cpu_vpe_id(¤t_cpu_data)) /* * The number of bits to shift to convert between counters per core and diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c index 72eb1a56c64508c732ccf1d7965367b85cf1e867..107d9f90d668c2e5008678f0aa320c969cf5d06a 100644 --- a/arch/mips/paravirt/paravirt-smp.c +++ b/arch/mips/paravirt/paravirt-smp.c @@ -100,11 +100,12 @@ static void paravirt_smp_finish(void) local_irq_enable(); } -static void paravirt_boot_secondary(int cpu, struct task_struct *idle) +static int paravirt_boot_secondary(int cpu, struct task_struct *idle) { paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle); smp_wmb(); paravirt_smp_sp[cpu] = __KSTK_TOS(idle); + return 0; } static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id) @@ -133,7 +134,7 @@ static void paravirt_prepare_cpus(unsigned int max_cpus) } } -struct plat_smp_ops paravirt_smp_ops = { +const struct plat_smp_ops paravirt_smp_ops = { .send_ipi_single = paravirt_send_ipi_single, .send_ipi_mask = paravirt_send_ipi_mask, .init_secondary = paravirt_init_secondary, diff --git a/arch/mips/paravirt/setup.c b/arch/mips/paravirt/setup.c index cb8448b373a743f88f1e9a7ff6a592bf8f3b9bc0..d2ffec1409a734ac5d94bcb6513474c95ab8d46b 100644 --- a/arch/mips/paravirt/setup.c +++ b/arch/mips/paravirt/setup.c @@ -14,7 +14,7 @@ #include #include -extern struct plat_smp_ops paravirt_smp_ops; +extern const struct plat_smp_ops paravirt_smp_ops; const char *get_system_type(void) { diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c index 1c02f5737367aa7e75569afeb98aebcd3ebb5327..b4c263f16b15eeb62c4fc93d70ff828cdfa7ac7f 100644 --- a/arch/mips/pci/fixup-capcella.c +++ b/arch/mips/pci/fixup-capcella.c @@ -32,13 +32,13 @@ #define INTC PC104PLUS_INTC_IRQ #define INTD PC104PLUS_INTD_IRQ -static char irq_tab_capcella[][5] __initdata = { +static char irq_tab_capcella[][5] = { [11] = { -1, INT1, INT1, INT1, INT1 }, [12] = { -1, INT2, INT2, INT2, INT2 }, [14] = { -1, INTA, INTB, INTC, INTD } }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_capcella[slot][pin]; } diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index b3ab59318d91a7a2817e6615efba1ef3fc0a2c37..44be65c3e6bb3d211d8692211b732d5f41f2caa4 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c @@ -147,7 +147,7 @@ static void qube_raq_via_board_id_fixup(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, qube_raq_via_board_id_fixup); -static char irq_tab_qube1[] __initdata = { +static char irq_tab_qube1[] = { [COBALT_PCICONF_CPU] = 0, [COBALT_PCICONF_ETH0] = QUBE1_ETH0_IRQ, [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, @@ -156,7 +156,7 @@ static char irq_tab_qube1[] __initdata = { [COBALT_PCICONF_ETH1] = 0 }; -static char irq_tab_cobalt[] __initdata = { +static char irq_tab_cobalt[] = { [COBALT_PCICONF_CPU] = 0, [COBALT_PCICONF_ETH0] = ETH0_IRQ, [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, @@ -165,7 +165,7 @@ static char irq_tab_cobalt[] __initdata = { [COBALT_PCICONF_ETH1] = ETH1_IRQ }; -static char irq_tab_raq2[] __initdata = { +static char irq_tab_raq2[] = { [COBALT_PCICONF_CPU] = 0, [COBALT_PCICONF_ETH0] = ETH0_IRQ, [COBALT_PCICONF_RAQSCSI] = RAQ2_SCSI_IRQ, @@ -174,7 +174,7 @@ static char irq_tab_raq2[] __initdata = { [COBALT_PCICONF_ETH1] = ETH1_IRQ }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) return irq_tab_qube1[slot]; diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c index 19caf775c20645ada7f1bbc86777c2bd45b23246..c31cb6af1cd07f8e9dd5ad715d30f93abd53a927 100644 --- a/arch/mips/pci/fixup-emma2rh.c +++ b/arch/mips/pci/fixup-emma2rh.c @@ -43,7 +43,7 @@ */ #define MAX_SLOT_NUM 10 -static unsigned char irq_map[][5] __initdata = { +static unsigned char irq_map[][5] = { [3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC, MARKEINS_PCI_IRQ_INTD, 0,}, [4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,}, @@ -85,7 +85,7 @@ static void emma2rh_pci_host_fixup(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, emma2rh_pci_host_fixup); -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_map[slot][pin]; } diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c index 50da773faedee8fc5850480857ea5e36a78f24c0..b47c2771dc997663a7046dcb6166d1987957c89e 100644 --- a/arch/mips/pci/fixup-fuloong2e.c +++ b/arch/mips/pci/fixup-fuloong2e.c @@ -19,7 +19,7 @@ /* South bridge slot number is set by the pci probe process */ static u8 sb_slot = 5; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = 0; diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c index 133685e215ee6a2f02a5a244e04e08464543273d..c6ec18a07e63ab2f88e53a5ff25cde90704f59a5 100644 --- a/arch/mips/pci/fixup-ip32.c +++ b/arch/mips/pci/fixup-ip32.c @@ -21,7 +21,7 @@ #define INTB MACEPCI_SHARED0_IRQ #define INTC MACEPCI_SHARED1_IRQ #define INTD MACEPCI_SHARED2_IRQ -static char irq_tab_mace[][5] __initdata = { +static char irq_tab_mace[][5] = { /* Dummy INT#A INT#B INT#C INT#D */ {0, 0, 0, 0, 0}, /* This is placeholder row - never used */ {0, SCSI0, SCSI0, SCSI0, SCSI0}, @@ -39,7 +39,7 @@ static char irq_tab_mace[][5] __initdata = { * irqs. I suppose a device without a pin A will thank us for doing it * right if there exists such a broken piece of crap. */ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_mace[slot][pin]; } diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index 0f1069527cbae435775c39d7acbaeb9369561d87..d3102eeea898983c655d7b8e6d7f923cdc56395a 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -31,7 +31,7 @@ #include #include -int __init jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c index 2b5427d3f35c255bc566978b02ff1ac8e057f551..81530a13b34990a38d159ae248aa0a2d453bf332 100644 --- a/arch/mips/pci/fixup-lantiq.c +++ b/arch/mips/pci/fixup-lantiq.c @@ -23,7 +23,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return of_irq_parse_and_map_pci(dev, slot, pin); } diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c index 95ab9a1bd0107384a3faa8e45c9f2872f7c561df..20cdfdc0893875a7556cfbef91db0ab18b8099d2 100644 --- a/arch/mips/pci/fixup-lemote2f.c +++ b/arch/mips/pci/fixup-lemote2f.c @@ -30,7 +30,7 @@ #define PCID 7 /* all the pci device has the PCIA pin, check the datasheet. */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0}, /* 11: Unused */ {0, 0, 0, 0, 0}, /* 12: Unused */ @@ -51,7 +51,7 @@ static char irq_tab[][5] __initdata = { {0, 0, 0, 0, 0}, /* 27: Unused */ }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int virq; diff --git a/arch/mips/pci/fixup-loongson3.c b/arch/mips/pci/fixup-loongson3.c index 2b6d5e196f9990255eb5d35de3e6580a69f6003f..8a741c2c6685ded75b18975613f3e0a8b40867a1 100644 --- a/arch/mips/pci/fixup-loongson3.c +++ b/arch/mips/pci/fixup-loongson3.c @@ -32,7 +32,7 @@ static void print_fixup_info(const struct pci_dev *pdev) pdev->vendor, pdev->device, pdev->irq); } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { print_fixup_info(dev); return dev->irq; diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 40e920c653cc31762bcc10e4e6a235a4c53b78fa..3ec85331795ef561ce1bc624ae55cd009fc6a844 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c @@ -12,7 +12,7 @@ static char pci_irq[5] = { }; -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* 0: GT64120 PCI bridge */ {0, 0, 0, 0, 0 }, /* 1: Unused */ @@ -38,7 +38,7 @@ static char irq_tab[][5] __initdata = { {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */ }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int virq; virq = irq_tab[slot][pin]; diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c index 8e4f8288eca2e2fcfc17bd615a26a5e0a6a152de..66eaf456bc89c31031abc74762874d09131a9ed0 100644 --- a/arch/mips/pci/fixup-mpc30x.c +++ b/arch/mips/pci/fixup-mpc30x.c @@ -22,19 +22,19 @@ #include -static const int internal_func_irqs[] __initconst = { +static const int internal_func_irqs[] = { VRC4173_CASCADE_IRQ, VRC4173_AC97_IRQ, VRC4173_USB_IRQ, }; -static const int irq_tab_mpc30x[] __initconst = { +static const int irq_tab_mpc30x[] = { [12] = VRC4173_PCMCIA1_IRQ, [13] = VRC4173_PCMCIA2_IRQ, [29] = MQ200_IRQ, }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == 30) return internal_func_irqs[PCI_FUNC(dev->devfn)]; diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c index fab405c21c2f76f856af004fab4e88e68f81cef2..4ad2ef02087bc0cf8bec3b19835ce88aec73b1f7 100644 --- a/arch/mips/pci/fixup-pmcmsp.c +++ b/arch/mips/pci/fixup-pmcmsp.c @@ -47,7 +47,7 @@ #if defined(CONFIG_PMC_MSP7120_GW) /* Garibaldi Board IRQ wiring to PCI slots */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ @@ -86,7 +86,7 @@ static char irq_tab[][5] __initdata = { #elif defined(CONFIG_PMC_MSP7120_EVAL) /* MSP7120 Eval Board IRQ wiring to PCI slots */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ @@ -125,7 +125,7 @@ static char irq_tab[][5] __initdata = { #else /* Unknown board -- don't assign any IRQs */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ @@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) * RETURNS: IRQ number * ****************************************************************************/ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { #if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 321db265829c0c0e88cd83790edc028d2bec77d0..d6aaed1d6be9ed3f10d9843b068661b3dcc2e18d 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -36,7 +36,7 @@ #include #include -int __init rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c index a80579af609bc7155f86836a3e4f0e8ed457e7d3..ff22a22db73ee618a30cb7af4e906ce060da7d92 100644 --- a/arch/mips/pci/fixup-rbtx4938.c +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -13,7 +13,7 @@ #include #include -int __init rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = tx4938_pcic1_map_irq(dev, slot); diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c index f67ebeeb42000bb5d4d73961d6bcc4d632375298..adb9a58641e8a1891e409b078e256d846ffa5d14 100644 --- a/arch/mips/pci/fixup-sni.c +++ b/arch/mips/pci/fixup-sni.c @@ -40,7 +40,7 @@ * seem to be a documentation error. At least on my RM200C the Cirrus * Logic CL-GD5434 VGA is device 3. */ -static char irq_tab_rm200[8][5] __initdata = { +static char irq_tab_rm200[8][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* EISA bridge */ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ @@ -57,7 +57,7 @@ static char irq_tab_rm200[8][5] __initdata = { * * The VGA card is optional for RM300 systems. */ -static char irq_tab_rm300d[8][5] __initdata = { +static char irq_tab_rm300d[8][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* EISA bridge */ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ @@ -69,7 +69,7 @@ static char irq_tab_rm300d[8][5] __initdata = { { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ }; -static char irq_tab_rm300e[5][5] __initdata = { +static char irq_tab_rm300e[5][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ @@ -96,7 +96,7 @@ static char irq_tab_rm300e[5][5] __initdata = { #define INTC PCIT_IRQ_INTC #define INTD PCIT_IRQ_INTD -static char irq_tab_pcit[13][5] __initdata = { +static char irq_tab_pcit[13][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */ @@ -113,7 +113,7 @@ static char irq_tab_pcit[13][5] __initdata = { { 0, INTA, INTB, INTC, INTD }, /* Slot 5 */ }; -static char irq_tab_pcit_cplus[13][5] __initdata = { +static char irq_tab_pcit_cplus[13][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { 0, INTB, INTC, INTD, INTA }, /* PCI Slot 9 */ @@ -130,7 +130,7 @@ static inline int is_rm300_revd(void) return (csmsr & 0xa0) == 0x20; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (sni_brd_type) { case SNI_BRD_PCI_TOWER_CPLUS: diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c index d0b0083fbd278a529209d41c7259e645d2c37f6c..cc581535f25772daf542445e1e4e59318e94a56f 100644 --- a/arch/mips/pci/fixup-tb0219.c +++ b/arch/mips/pci/fixup-tb0219.c @@ -23,7 +23,7 @@ #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c index 4196ccf3ea3da5e6783de7acd913f68d2fc218bc..b827b5cad5fd80eb8e4fde0a0e66bfbed524751c 100644 --- a/arch/mips/pci/fixup-tb0226.c +++ b/arch/mips/pci/fixup-tb0226.c @@ -23,7 +23,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c index 8c5039ed75d74c40df1b739ad37edf177dfad5bf..98f26285f2e3a904c7bff305d5a1cc9d65389f26 100644 --- a/arch/mips/pci/fixup-tb0287.c +++ b/arch/mips/pci/fixup-tb0287.c @@ -22,7 +22,7 @@ #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char bus; int irq = -1; diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index e99ca7702d8ad81660ab011ae4c990c0fb954f96..f15ec98de2de5b5569f051705b74985693406ea5 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -522,7 +522,7 @@ static int __init alchemy_pci_init(void) arch_initcall(alchemy_pci_init); -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct alchemy_pci_context *ctx = dev->sysdata; if (ctx && ctx->board_map_irq) diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c index 76f16eaed0ad3e9851d854d940e871c8c5f69aa9..230d7dd273e21af0668062c648ee2b6962383de1 100644 --- a/arch/mips/pci/pci-bcm47xx.c +++ b/arch/mips/pci/pci-bcm47xx.c @@ -28,7 +28,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return 0; } diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index 40d2797d2bc43b255edd050cf17d270cdbc4325d..47f4ee6bbb3bf9bb9874d6d26510d7e1f13cf94e 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c @@ -61,7 +61,7 @@ arch_initcall(lasat_pci_setup); #define LASAT_IRQ_PCIC (LASAT_IRQ_BASE + 7) #define LASAT_IRQ_PCID (LASAT_IRQ_BASE + 8) -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (slot) { case 1: diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 174575a9a112dcb73634e31b21040df3ad6ad470..0c65c38e05d6cc8ce1730476bb49baf9465a8583 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose) static int need_domain_info; LIST_HEAD(resources); struct pci_bus *bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) next_busno = (*hose->get_busno)(); @@ -87,18 +93,24 @@ static void pcibios_scanbus(struct pci_controller *hose) pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset); pci_add_resource(&resources, hose->busn_resource); - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = hose->pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pcibios_map_irq; + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + hose->bus = bus = bridge->bus; need_domain_info = need_domain_info || pci_domain_nr(bus); set_pci_need_domain_info(hose, need_domain_info); - if (!bus) { - pci_free_resource_list(&resources); - return; - } - next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ @@ -127,7 +139,7 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) struct of_pci_range range; struct of_pci_range_parser parser; - pr_info("PCI host bridge %s ranges:\n", node->full_name); + pr_info("PCI host bridge %pOF ranges:\n", node); hose->of_node = node; if (of_pci_range_parser_init(&parser, node)) @@ -224,8 +236,6 @@ static int __init pcibios_init(void) list_for_each_entry(hose, &controllers, list) pcibios_scanbus(hose); - pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); - pci_initialized = 1; return 0; diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c index cfbbc3e3e914526e8086e156d426a82c043032a2..88e625fb3a4722a08fc34e8e5704d9e26ec7305d 100644 --- a/arch/mips/pci/pci-malta.c +++ b/arch/mips/pci/pci-malta.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -201,7 +201,7 @@ void __init mips_pcibios_init(void) msc_mem_resource.start = start & mask; msc_mem_resource.end = (start & mask) | ~mask; msc_controller.mem_offset = (start & mask) - (map & mask); - if (mips_cm_numiocu()) { + if (mips_cps_numiocu(0)) { write_gcr_reg0_base(start); write_gcr_reg0_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); @@ -213,7 +213,7 @@ void __init mips_pcibios_init(void) msc_io_resource.end = (map & mask) | ~mask; msc_controller.io_offset = 0; ioport_resource.end = ~mask; - if (mips_cm_numiocu()) { + if (mips_cps_numiocu(0)) { write_gcr_reg1_base(start); write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index 628c5132b3d8b254ad0c590ef9a606af05412972..90fba9bf98da7104ee5ef74bd0f259653d279aa3 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c @@ -291,7 +291,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) IORESOURCE_MEM, 1); u32 val = 0; - rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0"); + rstpcie0 = devm_reset_control_get_exclusive(&pdev->dev, "pcie0"); if (IS_ERR(rstpcie0)) return PTR_ERR(rstpcie0); @@ -361,7 +361,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) return 0; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u16 cmd; u32 val; diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 9ee01936862ee1dfe11d8a21754bb16572230aac..3e92a06fa77288c2705e8435e9352b6bf8c5e368 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -59,8 +59,7 @@ union octeon_pci_address { } s; }; -int __initconst (*octeon_pcibios_map_irq)(const struct pci_dev *dev, - u8 slot, u8 pin); +int (*octeon_pcibios_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; /** @@ -74,7 +73,7 @@ enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; * as it goes through each bridge. * Returns Interrupt number for the device */ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (octeon_pcibios_map_irq) return octeon_pcibios_map_irq(dev, slot, pin); diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c index d6360fe73d058c5733274fb1b163c393a3f0e14c..711cdccdf65ba7df9647f72bd11952432086e33b 100644 --- a/arch/mips/pci/pci-rt2880.c +++ b/arch/mips/pci/pci-rt2880.c @@ -181,7 +181,7 @@ static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) spin_unlock_irqrestore(&rt2880_pci_lock, flags); } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u16 cmd; int irq = -1; diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 3520e9b414e7b91dfedc59abeb37d757579e475a..958899ffe99c14b3e149a88e303fb4cd3d497d81 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -207,8 +207,7 @@ static int rt3883_pci_irq_init(struct device *dev, irq = irq_of_parse_and_map(rpc->intc_of_node, 0); if (irq == 0) { - dev_err(dev, "%s has no IRQ", - of_node_full_name(rpc->intc_of_node)); + dev_err(dev, "%pOF has no IRQ", rpc->intc_of_node); return -EINVAL; } @@ -438,8 +437,8 @@ static int rt3883_pci_probe(struct platform_device *pdev) } if (!rpc->intc_of_node) { - dev_err(dev, "%s has no %s child node", - of_node_full_name(rpc->intc_of_node), + dev_err(dev, "%pOF has no %s child node", + rpc->intc_of_node, "interrupt controller"); return -EINVAL; } @@ -454,8 +453,8 @@ static int rt3883_pci_probe(struct platform_device *pdev) } if (!rpc->pci_controller.of_node) { - dev_err(dev, "%s has no %s child node", - of_node_full_name(rpc->intc_of_node), + dev_err(dev, "%pOF has no %s child node", + rpc->intc_of_node, "PCI host bridge"); err = -EINVAL; goto err_put_intc_node; @@ -565,7 +564,7 @@ static int rt3883_pci_probe(struct platform_device *pdev) return err; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return of_irq_parse_and_map_pci(dev, slot, pin); } diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c index 000c0e1f9ef869d884d8c9a0cbb286ba87bae97b..a6418460e3c4447e62028b63655e29233a166c42 100644 --- a/arch/mips/pci/pci-tx4938.c +++ b/arch/mips/pci/pci-tx4938.c @@ -112,7 +112,7 @@ int __init tx4938_pciclk66_setup(void) return pciclk; } -int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) { if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { switch (slot) { diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c index 9d6acc00f3489ddbf4558aa1d67568899e7eea9f..09a65f7dbe7ca001d55780d0bf7c2008a9320cdf 100644 --- a/arch/mips/pci/pci-tx4939.c +++ b/arch/mips/pci/pci-tx4939.c @@ -48,7 +48,7 @@ void __init tx4939_report_pci1clk(void) ((pciclk + 50000) / 100000) % 10); } -int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +int tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) { if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) { switch (slot) { @@ -68,7 +68,7 @@ int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) return -1; } -int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = tx4939_pcic1_map_irq(dev, slot); diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c index 7babf01600cb0fd9cbb97d4bb40f079693b2e8ed..9eff9137f78e52dc60bd4c031e42f1db4001ab6e 100644 --- a/arch/mips/pci/pci-xlp.c +++ b/arch/mips/pci/pci-xlp.c @@ -205,7 +205,7 @@ int xlp_socdev_to_node(const struct pci_dev *lnkdev) return PCI_SLOT(lnkdev->devfn) / 8; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_dev *lnkdev; int lnkfunc, node; diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 26d2dabef28152541b709b11d2257cb563fe0349..2a1c81a129ba31ae9a6757ef819f2cab3fe2f93a 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -315,7 +315,7 @@ static void xls_pcie_ack_b(struct irq_data *d) } } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return get_irq_vector(dev); } diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index bd67ac74fe2d3420509a03647a20856341bb70c8..9632436d74d7a74b3d584ab6e87a1fc7e55827cc 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -28,16 +28,15 @@ EXPORT_SYMBOL(PCIBIOS_MIN_MEM); static int __init pcibios_set_cache_line_size(void) { - struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int lsize; /* * Set PCI cacheline size to that of the highest level in the * cache hierarchy. */ - lsize = c->dcache.linesz; - lsize = c->scache.linesz ? : lsize; - lsize = c->tcache.linesz ? : lsize; + lsize = cpu_dcache_line_size(); + lsize = cpu_scache_line_size() ? : lsize; + lsize = cpu_tcache_line_size() ? : lsize; BUG_ON(!lsize); diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index ad3584dbc9d72bc1d0b845a1089ce41cec494737..fd2887415bc8935acf86c79a864b78dbd5878a03 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -1464,8 +1464,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port) * as it goes through each bridge. * Returns Interrupt number for the device */ -int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, - u8 slot, u8 pin) +int octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The EBH5600 board with the PCI to PCIe bridge mistakenly diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c index 1c91cad7988fb4b2e63e43eeeeefbc46ac72e7df..0b06c953d29359bffcebad378c565202b3a6c646 100644 --- a/arch/mips/pistachio/init.c +++ b/arch/mips/pistachio/init.c @@ -19,8 +19,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c index 0a6b24c246528180e35c2cf9e41e5d90b9e03b5d..709a8219073ac772d1aaf6d6ab5bd24a4115b820 100644 --- a/arch/mips/pistachio/irq.c +++ b/arch/mips/pistachio/irq.c @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c index 17a0f1dec05bd6bff766f5bbbe446b029deb5b5d..8a6af9b76202bd268c267aafe5164c0855670008 100644 --- a/arch/mips/pistachio/time.c +++ b/arch/mips/pistachio/time.c @@ -12,9 +12,9 @@ #include #include #include -#include #include +#include #include unsigned int get_c0_compare_int(void) diff --git a/arch/mips/pmcs-msp71xx/msp_smp.c b/arch/mips/pmcs-msp71xx/msp_smp.c index ffa0f7101a9773ec8e24813f37e3c270d912b5e2..2b08242ade628989e96aa3f24450b406ecdc7e7a 100644 --- a/arch/mips/pmcs-msp71xx/msp_smp.c +++ b/arch/mips/pmcs-msp71xx/msp_smp.c @@ -22,6 +22,8 @@ #include #include +#include + #ifdef CONFIG_MIPS_MT_SMP #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */ diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index 7cf4eb50fc7211f93219dbe23cb47581cac32f3a..a7a4e9f5146d8264fa5452ed744f3331345e810e 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 710b04cf48516f228ffedc113c67c03ad7a016e0..b4627080b828fa2891374b945aed6d7e04bfcb1b 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -82,6 +82,16 @@ choice depends on SOC_MT7620 select BUILTIN_DTB + config DTB_OMEGA2P + bool "Onion Omega2+" + depends on SOC_MT7620 + select BUILTIN_DTB + + config DTB_VOCORE2 + bool "VoCore2" + depends on SOC_MT7620 + select BUILTIN_DTB + endchoice endif diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index eb1c61917eb76baa14b031ead89693f27a1df22d..1b7df115eb607b8e270bda0de02bd5710133eb30 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c @@ -53,6 +53,9 @@ EXPORT_SYMBOL_GPL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } EXPORT_SYMBOL_GPL(clk_get_rate); diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c index 2058280450b5e5d5cd867edbe1065b3be407fb60..bda576f2cad8b7d24069e068d1172439d181b568 100644 --- a/arch/mips/ralink/irq-gic.c +++ b/arch/mips/ralink/irq-gic.c @@ -11,7 +11,7 @@ #include #include -#include +#include int get_c0_perfcount_int(void) { diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index 094a0ee4af46e913f2cb92f25a8503313dccc26c..9be8b08ae46b76a59984f47745138ceb16983e3a 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -12,6 +12,7 @@ #include #include +#include #include #include diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c index 0695c2d64e49107141091f8614c2689c18e68663..1b274742077dc191161c95ea62ea15a3b329b59f 100644 --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c @@ -12,8 +12,7 @@ #include #include -#include -#include +#include #include #include @@ -199,7 +198,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) mips_cm_probe(); mips_cpc_probe(); - if (mips_cm_numiocu()) { + if (mips_cps_numiocu(0)) { /* * mips_cm_probe() wipes out bootloader * config for CM regions and we have to configure them diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 0966adccf52005b35c308bd75b8ab92936eb6b99..32ea3e6731d6c8e72d9945ba0c53f347e3bfac77 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index 4cd47d23d81a76105b5a5fc21a768cc50d478879..545446dfe7faa4f1cf16b0fec3a2369606922ae2 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c @@ -195,7 +195,7 @@ static void ip27_smp_finish(void) * set sp to the kernel stack of the newly created idle process, gp to the proc * struct so that current_thread_info() will work. */ -static void ip27_boot_secondary(int cpu, struct task_struct *idle) +static int ip27_boot_secondary(int cpu, struct task_struct *idle) { unsigned long gp = (unsigned long)task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); @@ -203,6 +203,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle) LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), 0, (void *) sp, (void *) gp); + return 0; } static void __init ip27_smp_setup(void) @@ -231,7 +232,7 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus) /* We already did everything necessary earlier */ } -struct plat_smp_ops ip27_smp_ops = { +const struct plat_smp_ops ip27_smp_ops = { .send_ipi_single = ip27_send_ipi_single, .send_ipi_mask = ip27_send_ipi_mask, .init_secondary = ip27_init_secondary, diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index d0e94ffcc1b8b8abb058920631c68b500efaa336..90c9d1255ad798a284389fbb2aaeaa5aacca7a09 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c @@ -117,7 +117,7 @@ static void bcm1480_smp_finish(void) * Setup the PC, SP, and GP of a secondary processor and start it * running! */ -static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) +static int bcm1480_boot_secondary(int cpu, struct task_struct *idle) { int retval; @@ -126,6 +126,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return retval; } /* @@ -157,7 +158,7 @@ static void __init bcm1480_prepare_cpus(unsigned int max_cpus) { } -struct plat_smp_ops bcm1480_smp_ops = { +const struct plat_smp_ops bcm1480_smp_ops = { .send_ipi_single = bcm1480_send_ipi_single, .send_ipi_mask = bcm1480_send_ipi_mask, .init_secondary = bcm1480_init_secondary, diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index c1a11a11db7f71b0564d1195c9f95f1f556ebbbb..115399202eab18a252f8a304cfcf791836c3e95f 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -229,8 +229,8 @@ static int __init initrd_setup(char *str) #endif -extern struct plat_smp_ops sb_smp_ops; -extern struct plat_smp_ops bcm1480_smp_ops; +extern const struct plat_smp_ops sb_smp_ops; +extern const struct plat_smp_ops bcm1480_smp_ops; /* * prom_init is called just after the cpu type is determined, from setup_arch() diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index 0a4a2c3982d86dc6394b222c2632eace7cd83f56..5baabca52f25c3164b9ee4d8d8b6a7c0c5bcec6c 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c @@ -106,7 +106,7 @@ static void sb1250_smp_finish(void) * Setup the PC, SP, and GP of a secondary processor and start it * running! */ -static void sb1250_boot_secondary(int cpu, struct task_struct *idle) +static int sb1250_boot_secondary(int cpu, struct task_struct *idle) { int retval; @@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return retval; } /* @@ -146,7 +147,7 @@ static void __init sb1250_prepare_cpus(unsigned int max_cpus) { } -struct plat_smp_ops sb_smp_ops = { +const struct plat_smp_ops sb_smp_ops = { .send_ipi_single = sb1250_send_ipi_single, .send_ipi_mask = sb1250_send_ipi_mask, .init_secondary = sb1250_init_secondary, diff --git a/arch/mips/tools/generic-board-config.sh b/arch/mips/tools/generic-board-config.sh new file mode 100755 index 0000000000000000000000000000000000000000..5c4f936870391195da1d8de70d789650fc11acb5 --- /dev/null +++ b/arch/mips/tools/generic-board-config.sh @@ -0,0 +1,90 @@ +#!/bin/sh +# +# Copyright (C) 2017 Imagination Technologies +# Author: Paul Burton +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This script merges configuration fragments for boards supported by the +# generic MIPS kernel. It checks each for requirements specified using +# formatted comments, and then calls merge_config.sh to merge those +# fragments which have no unmet requirements. +# +# An example of requirements in your board config fragment might be: +# +# # require CONFIG_CPU_MIPS32_R2=y +# # require CONFIG_CPU_LITTLE_ENDIAN=y +# +# This would mean that your board is only included in kernels which are +# configured for little endian MIPS32r2 CPUs, and not for example in kernels +# configured for 64 bit or big endian systems. +# + +srctree="$1" +objtree="$2" +ref_cfg="$3" +cfg="$4" +boards_origin="$5" +shift 5 + +cd "${srctree}" + +# Only print Skipping... lines if the user explicitly specified BOARDS=. In the +# general case it only serves to obscure the useful output about what actually +# was included. +case ${boards_origin} in +"command line") + print_skipped=1 + ;; +environment*) + print_skipped=1 + ;; +*) + print_skipped=0 + ;; +esac + +for board in $@; do + board_cfg="arch/mips/configs/generic/board-${board}.config" + if [ ! -f "${board_cfg}" ]; then + echo "WARNING: Board config '${board_cfg}' not found" + continue + fi + + # For each line beginning with # require, cut out the field following + # it & search for that in the reference config file. If the requirement + # is not found then the subshell will exit with code 1, and we'll + # continue on to the next board. + grep -E '^# require ' "${board_cfg}" | \ + cut -d' ' -f 3- | \ + while read req; do + case ${req} in + *=y) + # If we require something =y then we check that a line + # containing it is present in the reference config. + grep -Eq "^${req}\$" "${ref_cfg}" && continue + ;; + *=n) + # If we require something =n then we just invert that + # check, considering the requirement met if there isn't + # a line containing the value =y in the reference + # config. + grep -Eq "^${req/%=n/=y}\$" "${ref_cfg}" || continue + ;; + *) + echo "WARNING: Unhandled requirement '${req}'" + ;; + esac + + [ ${print_skipped} -eq 1 ] && echo "Skipping ${board_cfg}" + exit 1 + done || continue + + # Merge this board config fragment into our final config file + ./scripts/kconfig/merge_config.sh \ + -m -O ${objtree} ${cfg} ${board_cfg} \ + | grep -Ev '^(#|Using)' +done diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 0bd2a1e1ff9ab8e0f0d8c56e31872ac08404c7b6..fb998726bd5d58b31e520d8ac4f8290835db473a 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -386,9 +386,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int (*txx9_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - return txx9_board_vec->pci_map_irq(dev, slot, pin); + return txx9_pci_map_irq(dev, slot, pin); } char * (*txx9_board_pcibios_setup)(char *str) __initdata; @@ -424,5 +425,8 @@ char *__init txx9_pcibios_setup(char *str) txx9_pci_err_action = TXX9_PCI_ERR_IGNORE; return NULL; } + + txx9_pci_map_irq = txx9_board_vec->pci_map_irq; + return str; } diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c index 974276e828b2cdd3eecb07493f480a8779da2d41..e22b422f282c7a22556ca690413f0dfb83314126 100644 --- a/arch/mips/vdso/gettimeofday.c +++ b/arch/mips/vdso/gettimeofday.c @@ -11,12 +11,10 @@ #include "vdso.h" #include -#include #include #include #include -#include #include #include @@ -35,7 +33,8 @@ static __always_inline long gettimeofday_fallback(struct timeval *_tv, " syscall\n" : "=r" (ret), "=r" (error) : "r" (tv), "r" (tz), "r" (nr) - : "memory"); + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); return error ? -ret : ret; } @@ -55,7 +54,8 @@ static __always_inline long clock_gettime_fallback(clockid_t _clkid, " syscall\n" : "=r" (ret), "=r" (error) : "r" (clkid), "r" (ts), "r" (nr) - : "memory"); + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); return error ? -ret : ret; } @@ -124,9 +124,9 @@ static __always_inline u64 read_gic_count(const union mips_vdso_data *data) u32 hi, hi2, lo; do { - hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); - lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS); - hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); + hi = __raw_readl(gic + sizeof(lo)); + lo = __raw_readl(gic); + hi2 = __raw_readl(gic + sizeof(lo)); } while (hi2 != hi); return (((u64)hi) << 32) + lo; diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S index 715bf599352971067a1c384c601b7bfa4da90d0f..30c6219912ac17224ccb0d033739821c34d8005d 100644 --- a/arch/mips/vdso/sigreturn.S +++ b/arch/mips/vdso/sigreturn.S @@ -19,31 +19,21 @@ .cfi_sections .debug_frame LEAF(__vdso_rt_sigreturn) - .cfi_startproc - .frame sp, 0, ra - .mask 0x00000000, 0 - .fmask 0x00000000, 0 .cfi_signal_frame li v0, __NR_rt_sigreturn syscall - .cfi_endproc END(__vdso_rt_sigreturn) #if _MIPS_SIM == _MIPS_SIM_ABI32 LEAF(__vdso_sigreturn) - .cfi_startproc - .frame sp, 0, ra - .mask 0x00000000, 0 - .fmask 0x00000000, 0 .cfi_signal_frame li v0, __NR_sigreturn syscall - .cfi_endproc END(__vdso_sigreturn) #endif diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig index 1fd41ec1dfb54396846832e9f42b904f65b97d68..d06dae131139c3785fcd113b78a4ba3c45e83b82 100644 --- a/arch/mn10300/configs/asb2303_defconfig +++ b/arch/mn10300/configs/asb2303_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_TINY_RCU=y @@ -28,16 +27,13 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_MTD=y CONFIG_MTD_DEBUG=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_CHAR=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -48,8 +44,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set diff --git a/arch/mn10300/configs/asb2364_defconfig b/arch/mn10300/configs/asb2364_defconfig index cd0a6cb17deebd988a2871607d19c423a430b233..b1d80cee97eef96d8a793703686c245f55eb8ec6 100644 --- a/arch/mn10300/configs/asb2364_defconfig +++ b/arch/mn10300/configs/asb2364_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -40,7 +39,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set @@ -50,10 +48,8 @@ CONFIG_IPV6=y CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_DEBUG=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_CHAR=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -64,8 +60,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -77,7 +71,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_PROC_KCORE=y # CONFIG_PROC_PAGE_MONITOR is not set @@ -93,4 +86,3 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h index 9c7b8f7942d8e9aadf3008875774b55a37959ae9..fe413b41df6cbbc50551f734d793e3b6c0c8d3d1 100644 --- a/arch/mn10300/include/asm/spinlock.h +++ b/arch/mn10300/include/asm/spinlock.h @@ -26,11 +26,6 @@ #define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) != 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, !VAL); -} - static inline void arch_spin_unlock(arch_spinlock_t *lock) { asm volatile( diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index c710db354ff222d9aab0d2ee2a5fdd3b9f971284..ac82a3f26dbf9f71117cc49429e11a083f62990b 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h @@ -102,4 +102,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index 89e8027e07fb327d39de0170c0da61af177c7160..7c475fd99c468396122e77c8f1dbe738ae368bc0 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c @@ -59,10 +59,6 @@ void arch_cpu_idle(void) } #endif -void release_segments(struct mm_struct *mm) -{ -} - void machine_restart(char *cmd) { #ifdef CONFIG_KERNEL_DEBUGGER @@ -112,14 +108,6 @@ void release_thread(struct task_struct *dead_task) { } -/* - * we do not have to muck with descriptors here, that is - * done in switch_mm() as needed. - */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) -{ -} - /* * this gets called so that we can store lazy state into memory and copy the * current task into the new thread. diff --git a/arch/nios2/boot/dts/3c120_devboard.dts b/arch/nios2/boot/dts/3c120_devboard.dts index 31c51f9a2f0973c9d9ee38637ff00b988eb280a2..36ccdf05837dec19988d0be5206257d09a92ecd6 100644 --- a/arch/nios2/boot/dts/3c120_devboard.dts +++ b/arch/nios2/boot/dts/3c120_devboard.dts @@ -159,6 +159,7 @@ }; chosen { - bootargs = "debug console=ttyJ0,115200"; + bootargs = "debug earlycon console=ttyJ0,115200"; + stdout-path = &jtag_uart; }; }; diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h index 7b3c6f280293aeb5cdd13b1de341f0e74f36bf2d..f8dc622227414abf8852c5c0718c2f832512eb50 100644 --- a/arch/nios2/include/asm/dma-mapping.h +++ b/arch/nios2/include/asm/dma-mapping.h @@ -18,7 +18,7 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) } /* - * dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to + * dma_alloc_attrs() always returns non-cacheable memory, so there's no need to * do any flushing here. */ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c index 645129aaa9a016b5e91b2ebc6e42e241ee00f72d..20e86209ef2e03646b49dd1f00324dae0ecedf72 100644 --- a/arch/nios2/kernel/time.c +++ b/arch/nios2/kernel/time.c @@ -107,7 +107,10 @@ static struct nios2_clocksource nios2_cs = { cycles_t get_cycles(void) { - return nios2_timer_read(&nios2_cs.cs); + /* Only read timer if it has been initialized */ + if (nios2_cs.timer.base) + return nios2_timer_read(&nios2_cs.cs); + return 0; } EXPORT_SYMBOL(get_cycles); diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 1e95920b07377417415c8622201d8e04bfd1f1a7..a0f2e4a323c1d543b46f8de29c90ab3d90519b72 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -29,6 +29,9 @@ config OPENRISC select CPU_NO_EFFICIENT_FFS if !OPENRISC_HAVE_INST_FF1 select NO_BOOTMEM +config CPU_BIG_ENDIAN + def_bool y + config MMU def_bool y diff --git a/arch/openrisc/include/asm/futex.h b/arch/openrisc/include/asm/futex.h index 7780873419771e27cf92b684887790029f5de113..8fed278a24b8afa4cf159363be081597c9ef9bbb 100644 --- a/arch/openrisc/include/asm/futex.h +++ b/arch/openrisc/include/asm/futex.h @@ -30,20 +30,10 @@ }) static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -68,30 +58,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h index ff97374ca0693d526582b8c34e7f9f421f43ed48..71a6f08de8f21a896f955f7a95792b7e62054a3a 100644 --- a/arch/openrisc/include/asm/pgtable.h +++ b/arch/openrisc/include/asm/pgtable.h @@ -414,6 +414,8 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */ +struct vm_area_struct; + /* * or32 doesn't have any external MMU info: the kernel page * tables contain all the necessary information. diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 531da9eb8f4363ad95c65e16b3d7c9653ac973b8..a57dedbfc7b77802e09104ee115702a9fe6fee13 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -9,6 +9,9 @@ config PARISC select ARCH_WANT_FRAME_POINTERS select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_STRICT_KERNEL_RWX + select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_WANTS_UBSAN_NO_NULL + select ARCH_SUPPORTS_MEMORY_FAILURE select RTC_CLASS select RTC_DRV_GENERIC select INIT_ALL_POSSIBLE @@ -17,6 +20,12 @@ config PARISC select BUG select BUILDTIME_EXTABLE_SORT select HAVE_PERF_EVENTS + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZ4 + select HAVE_KERNEL_LZMA + select HAVE_KERNEL_LZO + select HAVE_KERNEL_XZ select GENERIC_ATOMIC64 if !64BIT select GENERIC_IRQ_PROBE select GENERIC_PCI_IOMAP @@ -47,6 +56,12 @@ config PARISC and later HP3000 series). The PA-RISC Linux project home page is at . +config CPU_BIG_ENDIAN + def_bool y + +config CPU_BIG_ENDIAN + def_bool y + config MMU def_bool y @@ -242,6 +257,18 @@ config PARISC_PAGE_SIZE_64KB endchoice +config PARISC_SELF_EXTRACT + bool "Build kernel as self-extracting executable" + default y + help + Say Y if you want to build the parisc kernel as a kind of + self-extracting executable. + + If you say N here, the kernel will be compressed with gzip + which can be loaded by the palo bootloader directly too. + + If you don't know what to do here, say Y. + config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 75cb451b1f03069ccd2e77fae86cb1e4da6b7922..01946ebaff72814435cf6128665bd778eb217fb1 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -24,15 +24,20 @@ KBUILD_DEFCONFIG := default_defconfig NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) +export LIBGCC ifdef CONFIG_64BIT UTS_MACHINE := parisc64 CHECKFLAGS += -D__LP64__=1 -m64 CC_ARCHES = hppa64 +LD_BFD := elf64-hppa-linux else # 32-bit CC_ARCHES = hppa hppa2.0 hppa1.1 +LD_BFD := elf32-hppa-linux endif +export LD_BFD + ifneq ($(SUBARCH),$(UTS_MACHINE)) ifeq ($(CROSS_COMPILE),) CC_SUFFIXES = linux linux-gnu unknown-linux-gnu @@ -88,6 +93,8 @@ libs-y += arch/parisc/lib/ $(LIBGCC) drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ +boot := arch/parisc/boot + PALO := $(shell if (which palo 2>&1); then : ; \ elif [ -x /sbin/palo ]; then echo /sbin/palo; \ fi) @@ -116,11 +123,19 @@ INSTALL_TARGETS = zinstall install PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) -bzImage zImage: vmlinuz +zImage: vmlinuz Image: vmlinux +bzImage: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + +ifdef CONFIG_PARISC_SELF_EXTRACT +vmlinuz: bzImage + $(OBJCOPY) $(boot)/bzImage $@ +else vmlinuz: vmlinux @gzip -cf -9 $< > $@ +endif install: $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ diff --git a/arch/parisc/boot/.gitignore b/arch/parisc/boot/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..017d5912ad2d59a1a85024c20732298b7ad347a4 --- /dev/null +++ b/arch/parisc/boot/.gitignore @@ -0,0 +1,2 @@ +image +bzImage diff --git a/arch/parisc/boot/Makefile b/arch/parisc/boot/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cad68a5848843c97197957a7dbfe0f589134140d --- /dev/null +++ b/arch/parisc/boot/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for the linux parisc-specific parts of the boot image creator. +# + +COMPILE_VERSION := __linux_compile_version_id__`hostname | \ + tr -c '[0-9A-Za-z]' '_'`__`date | \ + tr -c '[0-9A-Za-z]' '_'`_t + +ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I. + +targets := image +targets += bzImage +subdir- := compressed + +$(obj)/image: vmlinux FORCE + $(call if_changed,objcopy) + +$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE + $(call if_changed,objcopy) + +$(obj)/compressed/vmlinux: FORCE + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ + +install: $(CONFIGURE) $(obj)/bzImage + sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ + System.map "$(INSTALL_PATH)" diff --git a/arch/parisc/boot/compressed/.gitignore b/arch/parisc/boot/compressed/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ae06b9b4c02f79a7f6bc188dad222d20f5bd0bcf --- /dev/null +++ b/arch/parisc/boot/compressed/.gitignore @@ -0,0 +1,3 @@ +sizes.h +vmlinux +vmlinux.lds diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7d7e594bda36f0403aef33577c9e75c1817011d4 --- /dev/null +++ b/arch/parisc/boot/compressed/Makefile @@ -0,0 +1,86 @@ +# +# linux/arch/parisc/boot/compressed/Makefile +# +# create a compressed self-extracting vmlinux image from the original vmlinux +# + +KCOV_INSTRUMENT := n +GCOV_PROFILE := n +UBSAN_SANITIZE := n + +targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 +targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4 +targets += misc.o piggy.o sizes.h head.o real2.o firmware.o + +KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER +KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks +KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os +ifndef CONFIG_64BIT +KBUILD_CFLAGS += -mfast-indirect-calls +endif + +OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o + +# LDFLAGS_vmlinux := -X --whole-archive -e startup -T +LDFLAGS_vmlinux := -X -e startup --as-needed -T +$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC) + $(call if_changed,ld) + +sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p' + +quiet_cmd_sizes = GEN $@ + cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@ + +$(obj)/sizes.h: vmlinux + $(call if_changed,sizes) + +AFLAGS_head.o += -I$(objtree)/$(obj) -DBOOTLOADER +$(obj)/head.o: $(obj)/sizes.h + +CFLAGS_misc.o += -I$(objtree)/$(obj) +$(obj)/misc.o: $(obj)/sizes.h + +$(obj)/firmware.o: $(obj)/firmware.c +$(obj)/firmware.c: $(srctree)/arch/$(SRCARCH)/kernel/firmware.c + $(call cmd,shipped) + +AFLAGS_real2.o += -DBOOTLOADER +$(obj)/real2.o: $(obj)/real2.S +$(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S + $(call cmd,shipped) + +$(obj)/misc.o: $(obj)/sizes.h + +CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER +$(obj)/vmlinux.lds: $(obj)/sizes.h + +OBJCOPYFLAGS_vmlinux.bin := -O binary -R .comment -S +$(obj)/vmlinux.bin: vmlinux + $(call if_changed,objcopy) + +vmlinux.bin.all-y := $(obj)/vmlinux.bin + +suffix-$(CONFIG_KERNEL_GZIP) := gz +suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +suffix-$(CONFIG_KERNEL_LZ4) := lz4 +suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_KERNEL_LZO) := lzo +suffix-$(CONFIG_KERNEL_XZ) := xz + +$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) + $(call if_changed,gzip) +$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) + $(call if_changed,bzip2) +$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) + $(call if_changed,lz4) +$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) + $(call if_changed,lzma) +$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) + $(call if_changed,lzo) +$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) + $(call if_changed,xzkern) + +LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) + $(call if_changed,ld) diff --git a/arch/parisc/boot/compressed/head.S b/arch/parisc/boot/compressed/head.S new file mode 100644 index 0000000000000000000000000000000000000000..5aba20fa48aafeac0ce7475bdf228b803d7f2f5c --- /dev/null +++ b/arch/parisc/boot/compressed/head.S @@ -0,0 +1,85 @@ +/* + * Startup glue code to uncompress the kernel + * + * (C) 2017 Helge Deller + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sizes.h" + +#define BOOTADDR(x) (x) + +#ifndef CONFIG_64BIT + .import $global$ /* forward declaration */ +#endif /*!CONFIG_64BIT*/ + + __HEAD + +ENTRY(startup) + .level LEVEL + +#define PSW_W_SM 0x200 +#define PSW_W_BIT 36 + + ;! nuke the W bit, saving original value + .level 2.0 + rsm PSW_W_SM, %r1 + + .level 1.1 + extrw,u %r1, PSW_W_BIT-32, 1, %r1 + copy %r1, %arg0 + + /* Make sure sr4-sr7 are set to zero for the kernel address space */ + mtsp %r0,%sr4 + mtsp %r0,%sr5 + mtsp %r0,%sr6 + mtsp %r0,%sr7 + + /* Clear BSS */ + + .import _bss,data + .import _ebss,data + + load32 BOOTADDR(_bss),%r3 + load32 BOOTADDR(_ebss),%r4 + ldo FRAME_SIZE(%r4),%sp /* stack at end of bss */ +$bss_loop: + cmpb,<<,n %r3,%r4,$bss_loop + stw,ma %r0,4(%r3) + + /* Initialize the global data pointer */ + loadgp + + /* arg0..arg4 were set by palo. */ + copy %arg1, %r6 /* command line */ + copy %arg2, %r7 /* rd-start */ + copy %arg3, %r8 /* rd-end */ + load32 BOOTADDR(decompress_kernel),%r3 + +#ifdef CONFIG_64BIT + .level LEVEL + ssm PSW_W_SM, %r0 /* set W-bit */ + depdi 0, 31, 32, %r3 +#endif + load32 BOOTADDR(startup_continue), %r2 + bv,n 0(%r3) + +startup_continue: +#ifdef CONFIG_64BIT + .level LEVEL + rsm PSW_W_SM, %r0 /* clear W-bit */ +#endif + + load32 KERNEL_BINARY_TEXT_START, %arg0 /* free mem */ + copy %r6, %arg1 /* command line */ + copy %r7, %arg2 /* rd-start */ + copy %r8, %arg3 /* rd-end */ + + bv,n 0(%ret0) +END(startup) diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c new file mode 100644 index 0000000000000000000000000000000000000000..9345b44b86f036572e33721eb80e9bbbe4493aa4 --- /dev/null +++ b/arch/parisc/boot/compressed/misc.c @@ -0,0 +1,302 @@ +/* + * Definitions and wrapper functions for kernel decompressor + * + * (C) 2017 Helge Deller + */ + +#include +#include +#include +#include "sizes.h" + +/* + * gzip declarations + */ +#define STATIC static + +#undef memmove +#define memmove memmove +#define memzero(s, n) memset((s), 0, (n)) + +#define malloc malloc_gzip +#define free free_gzip + +/* Symbols defined by linker scripts */ +extern char input_data[]; +extern int input_len; +/* output_len is inserted by the linker possibly at an unaligned address */ +extern __le32 output_len __aligned(1); +extern char _text, _end; +extern char _bss, _ebss; +extern char _startcode_end; +extern void startup_continue(void *entry, unsigned long cmdline, + unsigned long rd_start, unsigned long rd_end) __noreturn; + +void error(char *m) __noreturn; + +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif + +#ifdef CONFIG_KERNEL_BZIP2 +#include "../../../../lib/decompress_bunzip2.c" +#endif + +#ifdef CONFIG_KERNEL_LZ4 +#include "../../../../lib/decompress_unlz4.c" +#endif + +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif + +#ifdef CONFIG_KERNEL_XZ +#include "../../../../lib/decompress_unxz.c" +#endif + +void *memmove(void *dest, const void *src, size_t n) +{ + const char *s = src; + char *d = dest; + + if (d <= s) { + while (n--) + *d++ = *s++; + } else { + d += n; + s += n; + while (n--) + *--d = *--s; + } + return dest; +} + +void *memset(void *s, int c, size_t count) +{ + char *xs = (char *)s; + + while (count--) + *xs++ = c; + return s; +} + +void *memcpy(void *d, const void *s, size_t len) +{ + char *dest = (char *)d; + const char *source = (const char *)s; + + while (len--) + *dest++ = *source++; + return d; +} + +size_t strlen(const char *s) +{ + const char *sc; + + for (sc = s; *sc != '\0'; ++sc) + ; + return sc - s; +} + +char *strchr(const char *s, int c) +{ + while (*s) { + if (*s == (char)c) + return (char *)s; + ++s; + } + return NULL; +} + +int puts(const char *s) +{ + const char *nuline = s; + + while ((nuline = strchr(s, '\n')) != NULL) { + if (nuline != s) + pdc_iodc_print(s, nuline - s); + pdc_iodc_print("\r\n", 2); + s = nuline + 1; + } + if (*s != '\0') + pdc_iodc_print(s, strlen(s)); + + return 0; +} + +static int putchar(int c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = '\0'; + puts(buf); + return c; +} + +void __noreturn error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + while (1) /* wait forever */ + ; +} + +static int print_hex(unsigned long num) +{ + const char hex[] = "0123456789abcdef"; + char str[40]; + int i = sizeof(str)-1; + + str[i--] = '\0'; + do { + str[i--] = hex[num & 0x0f]; + num >>= 4; + } while (num); + + str[i--] = 'x'; + str[i] = '0'; + puts(&str[i]); + + return 0; +} + +int printf(const char *fmt, ...) +{ + va_list args; + int i = 0; + + va_start(args, fmt); + + while (fmt[i]) { + if (fmt[i] != '%') { +put: + putchar(fmt[i++]); + continue; + } + + if (fmt[++i] == '%') + goto put; + ++i; + print_hex(va_arg(args, unsigned long)); + } + + va_end(args); + return 0; +} + +/* helper functions for libgcc */ +void abort(void) +{ + error("aborted."); +} + +#undef malloc +void *malloc(size_t size) +{ + return malloc_gzip(size); +} + +#undef free +void free(void *ptr) +{ + return free_gzip(ptr); +} + + +static void flush_data_cache(char *start, unsigned long length) +{ + char *end = start + length; + + do { + asm volatile("fdc 0(%0)" : : "r" (start)); + asm volatile("fic 0(%%sr0,%0)" : : "r" (start)); + start += 16; + } while (start < end); + asm volatile("fdc 0(%0)" : : "r" (end)); + + asm ("sync"); +} + +unsigned long decompress_kernel(unsigned int started_wide, + unsigned int command_line, + const unsigned int rd_start, + const unsigned int rd_end) +{ + char *output; + unsigned long len, len_all; + +#ifdef CONFIG_64BIT + parisc_narrow_firmware = 0; +#endif + + set_firmware_width_unlocked(); + + putchar('U'); /* if you get this p and no more, string storage */ + /* in $GLOBAL$ is wrong or %dp is wrong */ + puts("ncompressing ...\n"); + + output = (char *) KERNEL_BINARY_TEXT_START; + len_all = __pa(SZ_end) - __pa(SZparisc_kernel_start); + + if ((unsigned long) &_startcode_end > (unsigned long) output) + error("Bootcode overlaps kernel code"); + + len = get_unaligned_le32(&output_len); + if (len > len_all) + error("Output len too big."); + else + memset(&output[len], 0, len_all - len); + + /* + * Initialize free_mem_ptr and free_mem_end_ptr. + */ + free_mem_ptr = (unsigned long) &_ebss; + free_mem_ptr += 2*1024*1024; /* leave 2 MB for stack */ + + /* Limit memory for bootoader to 1GB */ + #define ARTIFICIAL_LIMIT (1*1024*1024*1024) + free_mem_end_ptr = PAGE0->imm_max_mem; + if (free_mem_end_ptr > ARTIFICIAL_LIMIT) + free_mem_end_ptr = ARTIFICIAL_LIMIT; + +#ifdef CONFIG_BLK_DEV_INITRD + /* if we have ramdisk this is at end of memory */ + if (rd_start && rd_start < free_mem_end_ptr) + free_mem_end_ptr = rd_start; +#endif + +#ifdef DEBUG + printf("startcode_end = %x\n", &_startcode_end); + printf("commandline = %x\n", command_line); + printf("rd_start = %x\n", rd_start); + printf("rd_end = %x\n", rd_end); + + printf("free_ptr = %x\n", free_mem_ptr); + printf("free_ptr_end = %x\n", free_mem_end_ptr); + + printf("input_data = %x\n", input_data); + printf("input_len = %x\n", input_len); + printf("output = %x\n", output); + printf("output_len = %x\n", len); + printf("output_max = %x\n", len_all); +#endif + + __decompress(input_data, input_len, NULL, NULL, + output, 0, NULL, error); + + flush_data_cache(output, len); + + printf("Booting kernel ...\n\n"); + + return (unsigned long) output; +} diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S new file mode 100644 index 0000000000000000000000000000000000000000..a4ce3314e78e04a1e47ac977234eee5f731248f2 --- /dev/null +++ b/arch/parisc/boot/compressed/vmlinux.lds.S @@ -0,0 +1,101 @@ +#include +#include +#include "sizes.h" + +#ifndef CONFIG_64BIT +OUTPUT_FORMAT("elf32-hppa-linux") +OUTPUT_ARCH(hppa) +#else +OUTPUT_FORMAT("elf64-hppa-linux") +OUTPUT_ARCH(hppa:hppa2.0w) +#endif + +ENTRY(startup) + +SECTIONS +{ + /* palo loads at 0x60000 */ + /* loaded kernel will move to 0x10000 */ + . = 0xe0000; /* should not overwrite palo code */ + + .head.text : { + _head = . ; + HEAD_TEXT + _ehead = . ; + } + + /* keep __gp below 0x1000000 */ +#ifdef CONFIG_64BIT + . = ALIGN(16); + /* Linkage tables */ + .opd : { + *(.opd) + } PROVIDE (__gp = .); + .plt : { + *(.plt) + } + .dlt : { + *(.dlt) + } +#endif + _startcode_end = .; + + /* bootloader code and data starts behind area of extracted kernel */ + . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START); + + /* align on next page boundary */ + . = ALIGN(4096); + .text : { + _text = .; /* Text */ + *(.text) + *(.text.*) + _etext = . ; + } + . = ALIGN(8); + .data : { + _data = . ; + *(.data) + *(.data.*) + _edata = . ; + } + . = ALIGN(8); + .rodata : { + _rodata = . ; + *(.rodata) /* read-only data */ + *(.rodata.*) + _erodata = . ; + } + . = ALIGN(8); + .rodata.compressed : { + *(.rodata.compressed) + } + . = ALIGN(8); + .bss : { + _bss = . ; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4096); + _ebss = .; + } + + STABS_DEBUG + .note 0 : { *(.note) } + + /* Sections to be discarded */ + DISCARDS + /DISCARD/ : { +#ifdef CONFIG_64BIT + /* temporary hack until binutils is fixed to not emit these + * for static binaries + */ + *(.PARISC.unwind) /* no unwind data */ + *(.interp) + *(.dynsym) + *(.dynstr) + *(.dynamic) + *(.hash) + *(.gnu.hash) +#endif + } +} diff --git a/arch/parisc/boot/compressed/vmlinux.scr b/arch/parisc/boot/compressed/vmlinux.scr new file mode 100644 index 0000000000000000000000000000000000000000..dac2d142bcfa1d692a092abc341be1af2e78728e --- /dev/null +++ b/arch/parisc/boot/compressed/vmlinux.scr @@ -0,0 +1,10 @@ +SECTIONS +{ + .rodata.compressed : { + input_len = .; + LONG(input_data_end - input_data) input_data = .; + *(.data) + output_len = . - 4; /* can be at unaligned address */ + input_data_end = .; + } +} diff --git a/arch/parisc/boot/install.sh b/arch/parisc/boot/install.sh new file mode 100644 index 0000000000000000000000000000000000000000..8f7c365fad83792c3337ce3930ca027d915ba205 --- /dev/null +++ b/arch/parisc/boot/install.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# +# arch/parisc/install.sh, derived from arch/i386/boot/install.sh +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995 by Linus Torvalds +# +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# +# "make install" script for i386 architecture +# +# Arguments: +# $1 - kernel version +# $2 - kernel image file +# $3 - kernel map file +# $4 - default install path (blank if root directory) +# + +verify () { + if [ ! -f "$1" ]; then + echo "" 1>&2 + echo " *** Missing file: $1" 1>&2 + echo ' *** You need to run "make" before "make install".' 1>&2 + echo "" 1>&2 + exit 1 + fi +} + +# Make sure the files actually exist + +verify "$2" +verify "$3" + +# User may have a custom install script + +if [ -n "${INSTALLKERNEL}" ]; then + if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi + if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi +fi + +# Default install + +if [ "$(basename $2)" = "zImage" ]; then +# Compressed install + echo "Installing compressed kernel" + base=vmlinuz +else +# Normal install + echo "Installing normal kernel" + base=vmlinux +fi + +if [ -f $4/$base-$1 ]; then + mv $4/$base-$1 $4/$base-$1.old +fi +cat $2 > $4/$base-$1 + +# Install system map file +if [ -f $4/System.map-$1 ]; then + mv $4/System.map-$1 $4/System.map-$1.old +fi +cp $3 $4/System.map-$1 diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index 0764d3971cf66e456a03e26f7542a11ddd98f86f..8d41a73bd71b5e953128e4977c80596112ce43aa 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_INET6_IPCOMP=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y CONFIG_NET_PKTGEN=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 5394b9c5f914fdc4339224a3950e9d1c4ccd6bbb..17b98a87e5e26774298f955a3da234dd2742e2a4 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -65,6 +65,8 @@ static __inline__ void atomic_set(atomic_t *v, int i) _atomic_spin_unlock_irqrestore(v, flags); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + static __inline__ int atomic_read(const atomic_t *v) { return READ_ONCE((v)->counter); diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 0ba14300cd8e8bf09b0331ac004c98e601aa3bb2..c601aab2fb36d992db913e38dd83faf975721505 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -32,22 +32,12 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) } static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { unsigned long int flags; - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval, ret; u32 tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) - return -EFAULT; - _futex_spin_lock_irqsave(uaddr, &flags); pagefault_disable(); @@ -85,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); _futex_spin_unlock_irqrestore(uaddr, &flags); - if (ret == 0) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h index a8122625787846b8ee4233217911b23e7b89e2f6..e4a6570940585fa3a38a24cfaff5d253e4b46de0 100644 --- a/arch/parisc/include/asm/mmu_context.h +++ b/arch/parisc/include/asm/mmu_context.h @@ -63,6 +63,9 @@ static inline void switch_mm(struct mm_struct *prev, { unsigned long flags; + if (prev == next) + return; + local_irq_save(flags); switch_mm_irqs_off(prev, next, tsk); local_irq_restore(flags); diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index 80e742a1c162fbd89b27a21bd4ff75eb169b9b38..bfed09d80bae1caf0dd79d21daeda860e2ad9f8e 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -116,11 +116,15 @@ extern int npmem_ranges; /* This governs the relationship between virtual and physical addresses. * If you alter it, make sure to take care of our various fixed mapping * segments in fixmap.h */ +#if defined(BOOTLOADER) +#define __PAGE_OFFSET (0) /* bootloader uses physical addresses */ +#else #ifdef CONFIG_64BIT #define __PAGE_OFFSET (0x40000000) /* 1GB */ #else #define __PAGE_OFFSET (0x10000000) /* 256MB */ #endif +#endif /* BOOTLOADER */ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 7569627a032bb6e99ff0a546b864f6e0e64b71bc..510341f62d979e0ced75108c4b771380e0866c57 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -5,6 +5,8 @@ #if !defined(__ASSEMBLY__) +extern int parisc_narrow_firmware; + extern int pdc_type; extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ @@ -278,6 +280,7 @@ void setup_pdc(void); /* in inventory.c */ /* wrapper-functions from pdc.c */ int pdc_add_valid(unsigned long address); +int pdc_instr(unsigned int *instr); int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); int pdc_chassis_disp(unsigned long disp); int pdc_chassis_warn(unsigned long *warn); diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h index e3c0586260d8a34cd188764dae1e5452eefd7c22..a468a172ee33b5d0c845136b3e658d1d6693ec9a 100644 --- a/arch/parisc/include/asm/pdcpat.h +++ b/arch/parisc/include/asm/pdcpat.h @@ -223,6 +223,18 @@ struct pdc_pat_mem_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_INFO (return info) */ unsigned long clear_time; /* last PDT clear time (since Jan 1970) */ }; +struct pdc_pat_mem_cell_pdt_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_CELL_INFO */ + u64 reserved:32; + u64 cs:1; /* clear status: cleared since the last call? */ + u64 current_pdt_entries:15; + u64 ic:1; /* interleaving had to be changed ? */ + u64 max_pdt_entries:15; + unsigned long good_mem; + unsigned long first_dbe_loc; /* first location of double bit error */ + unsigned long clear_time; /* last PDT clear time (since Jan 1970) */ +}; + + struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */ unsigned long actual_count_bytes; unsigned long pdt_entries; @@ -325,6 +337,8 @@ extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *va extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); extern int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo); +extern int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo, + unsigned long cell); extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, unsigned long *pdt_entries_ptr, unsigned long max_entries); extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index a5dc9066c6d8d50cb35f2e4cf88509fa4621b84b..ad9c9c3b4136da6633e5d0c72fb117465376993e 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h @@ -1,6 +1,7 @@ #ifndef __ASM_SMP_H #define __ASM_SMP_H +extern int init_per_cpu(int cpuid); #if defined(CONFIG_SMP) diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index e32936cd7f1017a418bf1f086cfc819640616260..55bfe4affca30215db7bd23721795c89992b6d86 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -14,13 +14,6 @@ static inline int arch_spin_is_locked(arch_spinlock_t *x) #define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *x) -{ - volatile unsigned int *a = __ldcw_align(x); - - smp_cond_load_acquire(a, VAL); -} - static inline void arch_spin_lock_flags(arch_spinlock_t *x, unsigned long flags) { diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 88fe0aad4390b10830ce1bc1be62925d4b2d4bbc..bc208136bbb26a837a978cdf77304f1c9dec0b2d 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h @@ -34,7 +34,7 @@ struct thread_info { /* thread information allocation */ -#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */ +#define THREAD_SIZE_ORDER 3 /* PA-RISC requires at least 32k stack */ /* Be sure to hunt all references to this down when you change the size of * the kernel stack */ #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h index 5979745815a5ebcc2825f21a8b98125a0916d5fa..775b5d5e41a1db26358b1457290a499d442bee71 100644 --- a/arch/parisc/include/uapi/asm/mman.h +++ b/arch/parisc/include/uapi/asm/mman.h @@ -40,9 +40,6 @@ #define MADV_SEQUENTIAL 2 /* expect sequential page references */ #define MADV_WILLNEED 3 /* will need these pages */ #define MADV_DONTNEED 4 /* don't need these pages */ -#define MADV_SPACEAVAIL 5 /* insure that resources are reserved */ -#define MADV_VPS_PURGE 6 /* Purge pages from VM page cache */ -#define MADV_VPS_INHERIT 7 /* Inherit parents page size */ /* common/generic parameters */ #define MADV_FREE 8 /* free pages only if memory pressure */ @@ -60,21 +57,16 @@ overrides the coredump filter bits */ #define MADV_DODUMP 70 /* Clear the MADV_NODUMP flag */ +#define MADV_WIPEONFORK 71 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 72 /* Undo MADV_WIPEONFORK */ + +#define MADV_HWPOISON 100 /* poison a page for testing */ +#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */ + /* compatibility flags */ #define MAP_FILE 0 #define MAP_VARIABLE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index a0d4dc9f4eb2ff412e37f811087a768b921ac5b9..3b2bf7ae703b55bbd7e877a47b13dbf1cdccab28 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -101,4 +101,6 @@ #define SO_PEERGROUPS 0x4034 +#define SO_ZEROCOPY 0x4035 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 85a92db70afc99ab9151924823a3e277f1c0e8c5..19c0c141bc3f9f0edd509708f978a2d7ca16c230 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -587,13 +587,12 @@ void flush_cache_range(struct vm_area_struct *vma, if (parisc_requires_coherency()) flush_tlb_range(vma, start, end); - if ((end - start) >= parisc_cache_flush_threshold) { + if ((end - start) >= parisc_cache_flush_threshold + || vma->vm_mm->context != mfsp(3)) { flush_cache_all(); return; } - BUG_ON(vma->vm_mm->context != mfsp(3)); - flush_user_dcache_range_asm(start, end); if (vma->vm_flags & VM_EXEC) flush_user_icache_range_asm(start, end); diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index f622a311d04a1a99676f5b90469d18940a9d8294..6d471c00c71af12f6a48c4deebb5d260071d5dd3 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -69,7 +69,15 @@ #include #include /* for boot_cpu_data */ +#if defined(BOOTLOADER) +# undef spin_lock_irqsave +# define spin_lock_irqsave(a, b) { b = 1; } +# undef spin_unlock_irqrestore +# define spin_unlock_irqrestore(a, b) +#else static DEFINE_SPINLOCK(pdc_lock); +#endif + extern unsigned long pdc_result[NUM_PDC_RESULT]; extern unsigned long pdc_result2[NUM_PDC_RESULT]; @@ -142,8 +150,8 @@ static void convert_to_wide(unsigned long *addr) int i; unsigned int *p = (unsigned int *)addr; - if(unlikely(parisc_narrow_firmware)) { - for(i = 31; i >= 0; --i) + if (unlikely(parisc_narrow_firmware)) { + for (i = (NUM_PDC_RESULT-1); i >= 0; --i) addr[i] = p[i]; } #endif @@ -186,6 +194,8 @@ void set_firmware_width(void) } #endif /*CONFIG_64BIT*/ + +#if !defined(BOOTLOADER) /** * pdc_emergency_unlock - Unlock the linux pdc lock * @@ -222,6 +232,26 @@ int pdc_add_valid(unsigned long address) } EXPORT_SYMBOL(pdc_add_valid); +/** + * pdc_instr - Get instruction that invokes PDCE_CHECK in HPMC handler. + * @instr: Pointer to variable which will get instruction opcode. + * + * The return value is PDC_OK (0) in case call succeeded. + */ +int __init pdc_instr(unsigned int *instr) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_INSTR, 0UL, __pa(pdc_result)); + convert_to_wide(pdc_result); + *instr = pdc_result[0]; + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + /** * pdc_chassis_info - Return chassis information. * @result: The return buffer. @@ -979,16 +1009,22 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret, spin_lock_irqsave(&pdc_lock, flags); retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result), - __pa(pdc_result2)); + __pa(pdt_entries_ptr)); if (retval == PDC_OK) { convert_to_wide(pdc_result); memcpy(pret, pdc_result, sizeof(*pret)); - convert_to_wide(pdc_result2); - memcpy(pdt_entries_ptr, pdc_result2, - pret->pdt_entries * sizeof(*pdt_entries_ptr)); } spin_unlock_irqrestore(&pdc_lock, flags); +#ifdef CONFIG_64BIT + /* + * 64-bit kernels should not call this PDT function in narrow mode. + * The pdt_entries_ptr array above will now contain 32-bit values + */ + if (WARN_ON_ONCE((retval == PDC_OK) && parisc_narrow_firmware)) + return PDC_ERROR; +#endif + return retval; } @@ -1143,6 +1179,8 @@ void pdc_io_reset_devices(void) spin_unlock_irqrestore(&pdc_lock, flags); } +#endif /* defined(BOOTLOADER) */ + /* locked by pdc_console_lock */ static int __attribute__((aligned(8))) iodc_retbuf[32]; static char __attribute__((aligned(64))) iodc_dbuf[4096]; @@ -1187,6 +1225,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) return i; } +#if !defined(BOOTLOADER) /** * pdc_iodc_getc - Read a character (non-blocking) from the PDC console. * @@ -1439,6 +1478,29 @@ int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo) return retval; } +/** + * pdc_pat_mem_pdt_cell_info - Retrieve information about page deallocation + * table of a cell + * @rinfo: memory pdt information + * @cell: cell number + * + */ +int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo, + unsigned long cell) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_INFO, + __pa(&pdc_result), cell); + if (retval == PDC_OK) + memcpy(rinfo, &pdc_result, sizeof(*rinfo)); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + /** * pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware * @pret: array of PDT entries @@ -1455,14 +1517,14 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, spin_lock_irqsave(&pdc_lock, flags); /* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */ retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ, - __pa(&pdc_result), parisc_cell_num, __pa(&pdc_result2)); + __pa(&pdc_result), parisc_cell_num, + __pa(pdt_entries_ptr)); if (retval == PDC_OK) { /* build up return value as for PDC_PAT_MEM_PD_READ */ entries = min(pdc_result[0], max_entries); pret->pdt_entries = entries; pret->actual_count_bytes = entries * sizeof(unsigned long); - memcpy(pdt_entries_ptr, &pdc_result2, pret->actual_count_bytes); } spin_unlock_irqrestore(&pdc_lock, flags); @@ -1474,6 +1536,8 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, * pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware * @pret: array of PDT entries * @pdt_entries_ptr: ptr to hold number of PDT entries + * @count: number of bytes to read + * @offset: offset to start (in bytes) * */ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, @@ -1524,6 +1588,7 @@ int pdc_pat_mem_get_dimm_phys_location( return retval; } #endif /* CONFIG_64BIT */ +#endif /* defined(BOOTLOADER) */ /***************** 32-bit real-mode calls ***********/ @@ -1633,4 +1698,3 @@ long real64_call(unsigned long fn, ...) } #endif /* CONFIG_64BIT */ - diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 5404e4086cb95d5e7a5b49e06e783f0cfdf89b8b..0ca254085a6626374ed488401618ca3af19872c7 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -380,7 +380,7 @@ static inline int eirr_to_irq(unsigned long eirr) /* * IRQ STACK - used for irq handler */ -#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ +#define IRQ_STACK_SIZE (4096 << 3) /* 32k irq stack size */ union irq_stack_union { unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 5f0067a62738a77f5b62efb2ea45cc847c1d424d..bd4c0a7471d30b1c3411d372ef027bce24476f08 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -41,7 +41,7 @@ static unsigned long pcxl_used_bytes __read_mostly = 0; static unsigned long pcxl_used_pages __read_mostly = 0; extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */ -static spinlock_t pcxl_res_lock; +static DEFINE_SPINLOCK(pcxl_res_lock); static char *pcxl_res_map; static int pcxl_res_hint; static int pcxl_res_size; @@ -390,7 +390,6 @@ pcxl_dma_init(void) if (pcxl_dma_start == 0) return 0; - spin_lock_init(&pcxl_res_lock); pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3); pcxl_res_hint = 0; pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL, diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c index d02874ecb94df27d3171ae221ba693f4f8ca0a9c..00aed082969b126719a988bbe7c63a210c10ed90 100644 --- a/arch/parisc/kernel/pdt.c +++ b/arch/parisc/kernel/pdt.c @@ -1,19 +1,21 @@ /* * Page Deallocation Table (PDT) support * - * The Page Deallocation Table (PDT) holds a table with pointers to bad - * memory (broken RAM modules) which is maintained by firmware. + * The Page Deallocation Table (PDT) is maintained by firmware and holds a + * list of memory addresses in which memory errors were detected. + * The list contains both single-bit (correctable) and double-bit + * (uncorrectable) errors. * * Copyright 2017 by Helge Deller * - * TODO: - * - check regularily for new bad memory - * - add userspace interface with procfs or sysfs - * - increase number of PDT entries dynamically + * possible future enhancements: + * - add userspace interface via procfs or sysfs to clear PDT */ #include #include +#include +#include #include #include @@ -24,11 +26,16 @@ enum pdt_access_type { PDT_NONE, PDT_PDC, PDT_PAT_NEW, - PDT_PAT_OLD + PDT_PAT_CELL }; static enum pdt_access_type pdt_type; +/* PDT poll interval: 1 minute if errors, 5 minutes if everything OK. */ +#define PDT_POLL_INTERVAL_DEFAULT (5*60*HZ) +#define PDT_POLL_INTERVAL_SHORT (1*60*HZ) +static unsigned long pdt_poll_interval = PDT_POLL_INTERVAL_DEFAULT; + /* global PDT status information */ static struct pdc_mem_retinfo pdt_status; @@ -36,6 +43,21 @@ static struct pdc_mem_retinfo pdt_status; #define MAX_PDT_ENTRIES (MAX_PDT_TABLE_SIZE / sizeof(unsigned long)) static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; +/* + * Constants for the pdt_entry format: + * A pdt_entry holds the physical address in bits 0-57, bits 58-61 are + * reserved, bit 62 is the perm bit and bit 63 is the error_type bit. + * The perm bit indicates whether the error have been verified as a permanent + * error (value of 1) or has not been verified, and may be transient (value + * of 0). The error_type bit indicates whether the error is a single bit error + * (value of 1) or a multiple bit error. + * On non-PAT machines phys_addr is encoded in bits 0-59 and error_type in bit + * 63. Those machines don't provide the perm bit. + */ + +#define PDT_ADDR_PHYS_MASK (pdt_type != PDT_PDC ? ~0x3f : ~0x0f) +#define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL) +#define PDT_ADDR_SINGLE_ERR 1UL /* report PDT entries via /proc/meminfo */ void arch_report_meminfo(struct seq_file *m) @@ -49,6 +71,68 @@ void arch_report_meminfo(struct seq_file *m) pdt_status.pdt_entries); } +static int get_info_pat_new(void) +{ + struct pdc_pat_mem_retinfo pat_rinfo; + int ret; + + /* newer PAT machines like C8000 report info for all cells */ + if (is_pdc_pat()) + ret = pdc_pat_mem_pdt_info(&pat_rinfo); + else + return PDC_BAD_PROC; + + pdt_status.pdt_size = pat_rinfo.max_pdt_entries; + pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; + pdt_status.pdt_status = 0; + pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; + pdt_status.good_mem = pat_rinfo.good_mem; + + return ret; +} + +static int get_info_pat_cell(void) +{ + struct pdc_pat_mem_cell_pdt_retinfo cell_rinfo; + int ret; + + /* older PAT machines like rp5470 report cell info only */ + if (is_pdc_pat()) + ret = pdc_pat_mem_pdt_cell_info(&cell_rinfo, parisc_cell_num); + else + return PDC_BAD_PROC; + + pdt_status.pdt_size = cell_rinfo.max_pdt_entries; + pdt_status.pdt_entries = cell_rinfo.current_pdt_entries; + pdt_status.pdt_status = 0; + pdt_status.first_dbe_loc = cell_rinfo.first_dbe_loc; + pdt_status.good_mem = cell_rinfo.good_mem; + + return ret; +} + +static void report_mem_err(unsigned long pde) +{ + struct pdc_pat_mem_phys_mem_location loc; + unsigned long addr; + char dimm_txt[32]; + + addr = pde & PDT_ADDR_PHYS_MASK; + + /* show DIMM slot description on PAT machines */ + if (is_pdc_pat()) { + pdc_pat_mem_get_dimm_phys_location(&loc, addr); + sprintf(dimm_txt, "DIMM slot %02x, ", loc.dimm_slot); + } else + dimm_txt[0] = 0; + + pr_warn("PDT: BAD MEMORY at 0x%08lx, %s%s%s-bit error.\n", + addr, dimm_txt, + pde & PDT_ADDR_PERM_ERR ? "permanent ":"", + pde & PDT_ADDR_SINGLE_ERR ? "single":"multi"); +} + + /* * pdc_pdt_init() * @@ -63,18 +147,17 @@ void __init pdc_pdt_init(void) unsigned long entries; struct pdc_mem_read_pdt pdt_read_ret; - if (is_pdc_pat()) { - struct pdc_pat_mem_retinfo pat_rinfo; + pdt_type = PDT_PAT_NEW; + ret = get_info_pat_new(); - pdt_type = PDT_PAT_NEW; - ret = pdc_pat_mem_pdt_info(&pat_rinfo); - pdt_status.pdt_size = pat_rinfo.max_pdt_entries; - pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; - pdt_status.pdt_status = 0; - pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; - pdt_status.good_mem = pat_rinfo.good_mem; - } else { + if (ret != PDC_OK) { + pdt_type = PDT_PAT_CELL; + ret = get_info_pat_cell(); + } + + if (ret != PDC_OK) { pdt_type = PDT_PDC; + /* non-PAT machines provide the standard PDC call */ ret = pdc_mem_pdt_info(&pdt_status); } @@ -86,13 +169,17 @@ void __init pdc_pdt_init(void) } entries = pdt_status.pdt_entries; - WARN_ON(entries > MAX_PDT_ENTRIES); + if (WARN_ON(entries > MAX_PDT_ENTRIES)) + entries = pdt_status.pdt_entries = MAX_PDT_ENTRIES; - pr_info("PDT: size %lu, entries %lu, status %lu, dbe_loc 0x%lx," - " good_mem %lu\n", + pr_info("PDT: type %s, size %lu, entries %lu, status %lu, dbe_loc 0x%lx," + " good_mem %lu MB\n", + pdt_type == PDT_PDC ? __stringify(PDT_PDC) : + pdt_type == PDT_PAT_CELL ? __stringify(PDT_PAT_CELL) + : __stringify(PDT_PAT_NEW), pdt_status.pdt_size, pdt_status.pdt_entries, pdt_status.pdt_status, pdt_status.first_dbe_loc, - pdt_status.good_mem); + pdt_status.good_mem / 1024 / 1024); if (entries == 0) { pr_info("PDT: Firmware reports all memory OK.\n"); @@ -112,15 +199,12 @@ void __init pdc_pdt_init(void) #ifdef CONFIG_64BIT struct pdc_pat_mem_read_pd_retinfo pat_pret; - /* try old obsolete PAT firmware function first */ - pdt_type = PDT_PAT_OLD; - ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, - MAX_PDT_ENTRIES); - if (ret != PDC_OK) { - pdt_type = PDT_PAT_NEW; + if (pdt_type == PDT_PAT_CELL) + ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, + MAX_PDT_ENTRIES); + else ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry, MAX_PDT_TABLE_SIZE, 0); - } #else ret = PDC_BAD_PROC; #endif @@ -128,27 +212,150 @@ void __init pdc_pdt_init(void) if (ret != PDC_OK) { pdt_type = PDT_NONE; - pr_debug("PDT type %d, retval = %d\n", pdt_type, ret); + pr_warn("PDT: Get PDT entries failed with %d\n", ret); return; } for (i = 0; i < pdt_status.pdt_entries; i++) { - struct pdc_pat_mem_phys_mem_location loc; + unsigned long addr; - /* get DIMM slot number */ - loc.dimm_slot = 0xff; -#ifdef CONFIG_64BIT - pdc_pat_mem_get_dimm_phys_location(&loc, pdt_entry[i]); -#endif + report_mem_err(pdt_entry[i]); - pr_warn("PDT: BAD PAGE #%d at 0x%08lx, " - "DIMM slot %02x (error_type = %lu)\n", - i, - pdt_entry[i] & PAGE_MASK, - loc.dimm_slot, - pdt_entry[i] & 1); + addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK; + if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && + addr >= initrd_start && addr < initrd_end) + pr_crit("CRITICAL: initrd possibly broken " + "due to bad memory!\n"); /* mark memory page bad */ memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE); } } + + +/* + * This is the PDT kernel thread main loop. + */ + +static int pdt_mainloop(void *unused) +{ + struct pdc_mem_read_pdt pdt_read_ret; + struct pdc_pat_mem_read_pd_retinfo pat_pret __maybe_unused; + unsigned long old_num_entries; + unsigned long *bad_mem_ptr; + int num, ret; + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + + old_num_entries = pdt_status.pdt_entries; + + schedule_timeout(pdt_poll_interval); + if (kthread_should_stop()) + break; + + /* Do we have new PDT entries? */ + switch (pdt_type) { + case PDT_PAT_NEW: + ret = get_info_pat_new(); + break; + case PDT_PAT_CELL: + ret = get_info_pat_cell(); + break; + default: + ret = pdc_mem_pdt_info(&pdt_status); + break; + } + + if (ret != PDC_OK) { + pr_warn("PDT: unexpected failure %d\n", ret); + return -EINVAL; + } + + /* if no new PDT entries, just wait again */ + num = pdt_status.pdt_entries - old_num_entries; + if (num <= 0) + continue; + + /* decrease poll interval in case we found memory errors */ + if (pdt_status.pdt_entries && + pdt_poll_interval == PDT_POLL_INTERVAL_DEFAULT) + pdt_poll_interval = PDT_POLL_INTERVAL_SHORT; + + /* limit entries to get */ + if (num > MAX_PDT_ENTRIES) { + num = MAX_PDT_ENTRIES; + pdt_status.pdt_entries = old_num_entries + num; + } + + /* get new entries */ + switch (pdt_type) { +#ifdef CONFIG_64BIT + case PDT_PAT_CELL: + if (pdt_status.pdt_entries > MAX_PDT_ENTRIES) { + pr_crit("PDT: too many entries.\n"); + return -ENOMEM; + } + ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, + MAX_PDT_ENTRIES); + bad_mem_ptr = &pdt_entry[old_num_entries]; + break; + case PDT_PAT_NEW: + ret = pdc_pat_mem_read_pd_pdt(&pat_pret, + pdt_entry, + num * sizeof(unsigned long), + old_num_entries * sizeof(unsigned long)); + bad_mem_ptr = &pdt_entry[0]; + break; +#endif + default: + ret = pdc_mem_pdt_read_entries(&pdt_read_ret, + pdt_entry); + bad_mem_ptr = &pdt_entry[old_num_entries]; + break; + } + + /* report and mark memory broken */ + while (num--) { + unsigned long pde = *bad_mem_ptr++; + + report_mem_err(pde); + +#ifdef CONFIG_MEMORY_FAILURE + if ((pde & PDT_ADDR_PERM_ERR) || + ((pde & PDT_ADDR_SINGLE_ERR) == 0)) + memory_failure(pde >> PAGE_SHIFT, 0, 0); + else + soft_offline_page( + pfn_to_page(pde >> PAGE_SHIFT), 0); +#else + pr_crit("PDT: memory error at 0x%lx ignored.\n" + "Rebuild kernel with CONFIG_MEMORY_FAILURE=y " + "for real handling.\n", + pde & PDT_ADDR_PHYS_MASK); +#endif + + } + } + + return 0; +} + + +static int __init pdt_initcall(void) +{ + struct task_struct *kpdtd_task; + + if (pdt_type == PDT_NONE) + return -ENODEV; + + kpdtd_task = kthread_create(pdt_mainloop, NULL, "kpdtd"); + if (IS_ERR(kpdtd_task)) + return PTR_ERR(kpdtd_task); + + wake_up_process(kpdtd_task); + + return 0; +} + +late_initcall(pdt_initcall); diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 6017a5af2e6e2c8feb45de54adfb36865b65d3ee..0813359049aec5347e7e239850808b9aa02f04a7 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -69,7 +69,7 @@ struct rdr_tbl_ent { static int perf_processor_interface __read_mostly = UNKNOWN_INTF; static int perf_enabled __read_mostly; -static spinlock_t perf_lock; +static DEFINE_SPINLOCK(perf_lock); struct parisc_device *cpu_device __read_mostly; /* RDRs to write for PCX-W */ @@ -533,8 +533,6 @@ static int __init perf_init(void) /* Patch the images to match the system */ perf_patch_images(); - spin_lock_init(&perf_lock); - /* TODO: this only lets us access the first cpu.. what to do for SMP? */ cpu_device = per_cpu(cpu_data, 0).dev; printk("Performance monitoring counters enabled for %s\n", diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index a45a67d526f8ca8001fd1d06625b3b233d5a3835..30f92391a93ef6d5a90970b81921a2133d5e2eb0 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -146,7 +146,7 @@ void machine_power_off(void) /* prevent soft lockup/stalled CPU messages for endless loop. */ rcu_sysrq_start(); - lockup_detector_suspend(); + lockup_detector_soft_poweroff(); for (;;); } diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 0ab32779dfa737d8b2a8ad341ac6e169f0f66a1e..e120d63c1b285ad545c2281de0abbbcc2dde6e08 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -89,7 +90,7 @@ init_percpu_prof(unsigned long cpunum) * (return 1). If so, initialize the chip and tell other partners in crime * they have work to do. */ -static int processor_probe(struct parisc_device *dev) +static int __init processor_probe(struct parisc_device *dev) { unsigned long txn_addr; unsigned long cpuid; @@ -237,28 +238,45 @@ static int processor_probe(struct parisc_device *dev) */ void __init collect_boot_cpu_data(void) { + unsigned long cr16_seed; + memset(&boot_cpu_data, 0, sizeof(boot_cpu_data)); + cr16_seed = get_cycles(); + add_device_randomness(&cr16_seed, sizeof(cr16_seed)); + boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */ /* get CPU-Model Information... */ #define p ((unsigned long *)&boot_cpu_data.pdc.model) - if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) + if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) { printk(KERN_INFO "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); + + add_device_randomness(&boot_cpu_data.pdc.model, + sizeof(boot_cpu_data.pdc.model)); + } #undef p - if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) + if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) { printk(KERN_INFO "vers %08lx\n", boot_cpu_data.pdc.versions); - if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) + add_device_randomness(&boot_cpu_data.pdc.versions, + sizeof(boot_cpu_data.pdc.versions)); + } + + if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) { printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n", (boot_cpu_data.pdc.cpuid >> 5) & 127, boot_cpu_data.pdc.cpuid & 31, boot_cpu_data.pdc.cpuid); + add_device_randomness(&boot_cpu_data.pdc.cpuid, + sizeof(boot_cpu_data.pdc.cpuid)); + } + if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK) printk(KERN_INFO "capabilities 0x%lx\n", boot_cpu_data.pdc.capabilities); @@ -299,7 +317,7 @@ void __init collect_boot_cpu_data(void) * * o Enable CPU profiling hooks. */ -int init_per_cpu(int cpunum) +int __init init_per_cpu(int cpunum) { int ret; struct pdc_coproc_cfg coproc_cfg; @@ -414,12 +432,12 @@ show_cpuinfo (struct seq_file *m, void *v) return 0; } -static const struct parisc_device_id processor_tbl[] = { +static const struct parisc_device_id processor_tbl[] __initconst = { { HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID }, { 0, } }; -static struct parisc_driver cpu_driver = { +static struct parisc_driver cpu_driver __refdata = { .name = "CPU", .id_table = processor_tbl, .probe = processor_probe diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 1db58e546230be27515c649a9a4ae2fe57c061fe..cc9963421a19377f3faea08bf2686611a0856816 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -162,6 +162,7 @@ ENDPROC_CFI(restore_control_regs) .text .align 128 ENTRY_CFI(rfi_virt2real) +#if !defined(BOOTLOADER) /* switch to real mode... */ rsm PSW_SM_I,%r0 load32 PA(rfi_v2r_1), %r1 @@ -191,6 +192,7 @@ ENTRY_CFI(rfi_virt2real) nop rfi_v2r_1: tophys_r1 %r2 +#endif /* defined(BOOTLOADER) */ bv 0(%r2) nop ENDPROC_CFI(rfi_virt2real) @@ -198,6 +200,7 @@ ENDPROC_CFI(rfi_virt2real) .text .align 128 ENTRY_CFI(rfi_real2virt) +#if !defined(BOOTLOADER) rsm PSW_SM_I,%r0 load32 (rfi_r2v_1), %r1 nop @@ -226,6 +229,7 @@ ENTRY_CFI(rfi_real2virt) nop rfi_r2v_1: tovirt_r1 %r2 +#endif /* defined(BOOTLOADER) */ bv 0(%r2) nop ENDPROC_CFI(rfi_real2virt) diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index dee6f9d6a153ce461ec816e6caeb5a38dd3bb9f2..f7d0c3b33d70a53b5350729f1e3d59b2e803749b 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include static char __initdata command_line[COMMAND_LINE_SIZE]; @@ -115,7 +117,6 @@ void __init dma_ops_init(void) } #endif -extern int init_per_cpu(int cpuid); extern void collect_boot_cpu_data(void); void __init setup_arch(char **cmdline_p) @@ -398,9 +399,8 @@ static int __init parisc_init(void) } arch_initcall(parisc_init); -void start_parisc(void) +void __init start_parisc(void) { - extern void start_kernel(void); extern void early_trap_init(void); int ret, cpunum; diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 70aaabb8b3cb33cd869c865bb653c434861f8b6b..9e0cb6a577d67976dff26e4532fee777d50eb59a 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -290,25 +290,25 @@ copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) if (to->si_code < 0) err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (to->si_code >> 16) { - case __SI_CHLD >> 16: + switch (siginfo_layout(to->si_signo, to->si_code)) { + case SIL_CHLD: err |= __get_user(to->si_utime, &from->si_utime); err |= __get_user(to->si_stime, &from->si_stime); err |= __get_user(to->si_status, &from->si_status); default: + case SIL_KILL: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __get_user(addr, &from->si_addr); to->si_addr = compat_ptr(addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_fd, &from->si_fd); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); err |= __get_user(to->si_int, &from->si_int); @@ -337,41 +337,40 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_CHLD >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); - default: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: addr = ptr_to_compat(from->si_addr); err |= __put_user(addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); val = (compat_int_t)from->si_int; err |= __put_user(val, &to->si_int); break; - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); val = (compat_int_t)from->si_int; err |= __put_user(val, &to->si_int); break; - case __SI_SYS >> 16: + case SIL_SYS: err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr); err |= __put_user(from->si_syscall, &to->si_syscall); err |= __put_user(from->si_arch, &to->si_arch); diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 63365106ea1907589bbdee1688a1a9be54b1a74d..30c28ab145409b5966f7237ec2b6ca07121adc10 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -255,12 +255,11 @@ void arch_send_call_function_single_ipi(int cpu) static void __init smp_cpu_init(int cpunum) { - extern int init_per_cpu(int); /* arch/parisc/kernel/processor.c */ extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */ extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */ /* Set modes and Enable floating point coprocessor */ - (void) init_per_cpu(cpunum); + init_per_cpu(cpunum); disable_sr_hashing(); diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 991654c88eec8635056bef3ae9f536a6e8ff8862..230333157fe384c4171749e2b4eab43e3070a89d 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -817,7 +817,7 @@ void __init initialize_ivt(const void *iva) u32 check = 0; u32 *ivap; u32 *hpmcp; - u32 length; + u32 length, instr; if (strcmp((const char *)iva, "cows can fly")) panic("IVT invalid"); @@ -827,6 +827,14 @@ void __init initialize_ivt(const void *iva) for (i = 0; i < 8; i++) *ivap++ = 0; + /* + * Use PDC_INSTR firmware function to get instruction that invokes + * PDCE_CHECK in HPMC handler. See programming note at page 1-31 of + * the PA 1.1 Firmware Architecture document. + */ + if (pdc_instr(&instr) == PDC_OK) + ivap[0] = instr; + /* Compute Checksum for HPMC handler */ length = os_hpmc_size; ivap[7] = length; diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 1b73690477c5caf60c5b684389129e5f0bcb6c1c..caab39dfa95d606564af62d3fd565eef6fc41757 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,7 @@ extern struct unwind_table_entry __start___unwind[]; extern struct unwind_table_entry __stop___unwind[]; -static spinlock_t unwind_lock; +static DEFINE_SPINLOCK(unwind_lock); /* * the kernel unwind block is not dynamically allocated so that * we can call unwind_init as early in the bootup process as @@ -181,8 +182,6 @@ int __init unwind_init(void) start = (long)&__start___unwind[0]; stop = (long)&__stop___unwind[0]; - spin_lock_init(&unwind_lock); - printk("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n", start, stop, (stop - start) / sizeof(struct unwind_table_entry)); @@ -281,6 +280,17 @@ static void unwind_frame_regs(struct unwind_frame_info *info) info->prev_sp = sp - 64; info->prev_ip = 0; + + /* The stack is at the end inside the thread_union + * struct. If we reach data, we have reached the + * beginning of the stack and should stop unwinding. */ + if (info->prev_sp >= (unsigned long) task_thread_info(info->t) && + info->prev_sp < ((unsigned long) task_thread_info(info->t) + + THREAD_SZ_ALGN)) { + info->prev_sp = 0; + break; + } + if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) break; info->prev_ip = tmp; diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index 99115cd9e790b00a19e87161a2bbc89f8f4aee58..865a7f796c7fbf8ae817786451a4d78a48c8cb46 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -27,8 +27,6 @@ #include #include -DECLARE_PER_CPU(struct exception_data, exception_data); - #define get_user_space() (uaccess_kernel() ? 0 : mfsp(3)) #define get_kernel_space() (0) diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 5b101f6a5607dc1ef9e229b6f2421a78d35355ce..e247edbca68ecd2f56500e467776c9d2fa1f1c11 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, struct task_struct *tsk; struct mm_struct *mm; unsigned long acc_type; - int fault; + int fault = 0; unsigned int flags; if (faulthandler_disabled()) @@ -315,7 +316,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, goto out_of_memory; else if (fault & VM_FAULT_SIGSEGV) goto bad_area; - else if (fault & VM_FAULT_SIGBUS) + else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| + VM_FAULT_HWPOISON_LARGE)) goto bad_area; BUG(); } @@ -352,8 +354,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, if (user_mode(regs)) { struct siginfo si; - - show_signal_msg(regs, code, address, tsk, vma); + unsigned int lsb = 0; switch (code) { case 15: /* Data TLB miss fault/Data page fault */ @@ -386,6 +387,30 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; break; } + +#ifdef CONFIG_MEMORY_FAILURE + if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { + printk(KERN_ERR + "MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n", + tsk->comm, tsk->pid, address); + si.si_signo = SIGBUS; + si.si_code = BUS_MCEERR_AR; + } +#endif + + /* + * Either small page or large page may be poisoned. + * In other words, VM_FAULT_HWPOISON_LARGE and + * VM_FAULT_HWPOISON are mutually exclusive. + */ + if (fault & VM_FAULT_HWPOISON_LARGE) + lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); + else if (fault & VM_FAULT_HWPOISON) + lsb = PAGE_SHIFT; + else + show_signal_msg(regs, code, address, tsk, vma); + si.si_addr_lsb = lsb; + si.si_errno = 0; si.si_addr = (void __user *) address; force_sig_info(si.si_signo, &si, current); diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 36f858c37ca70b576e851a52ada48e2400de86a1..809c468edab13dc7f7b6a657c5b1c22546ae53ef 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -85,6 +85,17 @@ config NMI_IPI depends on SMP && (DEBUGGER || KEXEC_CORE || HARDLOCKUP_DETECTOR) default y +config PPC_WATCHDOG + bool + depends on HARDLOCKUP_DETECTOR + depends on HAVE_HARDLOCKUP_DETECTOR_ARCH + default y + help + This is a placeholder when the powerpc hardlockup detector + watchdog is selected (arch/powerpc/kernel/watchdog.c). It is + seleted via the generic lockup detector menu which is why we + have no standalone config option for it here. + config STACKTRACE_SUPPORT bool default y @@ -165,7 +176,7 @@ config PPC select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK - select ARCH_HAS_STRICT_KERNEL_RWX if (PPC_BOOK3S_64 && !RELOCATABLE && !HIBERNATION) + select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select HAVE_CBPF_JIT if !PPC64 select HAVE_CONTEXT_TRACKING if PPC64 @@ -199,7 +210,7 @@ config PPC select HAVE_OPTPROBES if PPC64 select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS_NMI if PPC64 - select HAVE_HARDLOCKUP_DETECTOR_PERF if HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH + select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE if SMP @@ -356,10 +367,6 @@ config PPC_ADV_DEBUG_DAC_RANGE depends on PPC_ADV_DEBUG_REGS && 44x default y -config PPC_EMULATE_SSTEP - bool - default y if KPROBES || UPROBES || XMON || HAVE_HW_BREAKPOINT - config ZONE_DMA32 bool default y if PPC64 @@ -394,7 +401,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE config MATH_EMULATION bool "Math emulation" - depends on 4xx || 8xx || PPC_MPC832x || BOOKE + depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE ---help--- Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the @@ -956,9 +963,9 @@ config PPC_PCI_CHOICE config PCI bool "PCI support" if PPC_PCI_CHOICE - default y if !40x && !CPM2 && !8xx && !PPC_83xx \ + default y if !40x && !CPM2 && !PPC_8xx && !PPC_83xx \ && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON - default PCI_QSPAN if !4xx && !CPM2 && 8xx + default PCI_QSPAN if PPC_8xx select GENERIC_PCI_IOMAP help Find out whether your system includes a PCI bus. PCI is the name of @@ -974,7 +981,7 @@ config PCI_SYSCALL config PCI_QSPAN bool "QSpan PCI" - depends on !4xx && !CPM2 && 8xx + depends on PPC_8xx select PPC_I8259 help Say Y here if you have a system based on a Motorola 8xx-series @@ -1165,12 +1172,23 @@ config CONSISTENT_SIZE config PIN_TLB bool "Pinned Kernel TLBs (860 ONLY)" - depends on ADVANCED_OPTIONS && 8xx + depends on ADVANCED_OPTIONS && PPC_8xx && \ + !DEBUG_PAGEALLOC && !STRICT_KERNEL_RWX + +config PIN_TLB_DATA + bool "Pinned TLB for DATA" + depends on PIN_TLB + default y config PIN_TLB_IMMR bool "Pinned TLB for IMMR" depends on PIN_TLB default y + +config PIN_TLB_TEXT + bool "Pinned TLB for TEXT" + depends on PIN_TLB + default y endmenu if PPC64 diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e2b3e7a00c9e3548e0b0086f878d4b707ba40dbb..1381693a4a51bee5b1f37290b604f4df1588b845 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -250,7 +250,7 @@ KBUILD_AFLAGS += $(aflags-y) KBUILD_CFLAGS += $(cflags-y) head-y := arch/powerpc/kernel/head_$(BITS).o -head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o +head-$(CONFIG_PPC_8xx) := arch/powerpc/kernel/head_8xx.o head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o @@ -317,6 +317,10 @@ PHONY += ppc64le_defconfig ppc64le_defconfig: $(call merge_into_defconfig,ppc64_defconfig,le) +PHONY += powernv_be_defconfig +powernv_be_defconfig: + $(call merge_into_defconfig,powernv_defconfig,be) + PHONY += mpc85xx_defconfig mpc85xx_defconfig: $(call merge_into_defconfig,mpc85xx_basic_defconfig,\ diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c index 9d3bd4c45a2406992005018d70f1db1e1f56b591..f7da651691249f30798f3f5dc0e4d569b6a0e45b 100644 --- a/arch/powerpc/boot/4xx.c +++ b/arch/powerpc/boot/4xx.c @@ -564,7 +564,7 @@ void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) fbdv = 16; cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */ opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */ - ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */ + ppdv = ((pllmr & 0x00006000) >> 13) + 1; /* PLB:PCI */ epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */ udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1; diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index a7814a7b15233261b0d9ba9d848543948dcd34d6..c4e6fe35c075568787f21e7b850d8cd9ccb72a0b 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -25,12 +25,20 @@ compress-$(CONFIG_KERNEL_XZ) := CONFIG_KERNEL_XZ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -Os -msoft-float -pipe \ -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ - -isystem $(shell $(CROSS32CC) -print-file-name=include) \ -D$(compress-y) +BOOTCC := $(CC) ifdef CONFIG_PPC64_BOOT_WRAPPER BOOTCFLAGS += -m64 +else +BOOTCFLAGS += -m32 +ifdef CROSS32_COMPILE + BOOTCC := $(CROSS32_COMPILE)gcc +endif endif + +BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) + ifdef CONFIG_CPU_BIG_ENDIAN BOOTCFLAGS += -mbig-endian else @@ -99,17 +107,18 @@ src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \ $(libfdt) libfdt-wrapper.c \ ns16550.c serial.c simple_alloc.c div64.S util.S \ elf_util.c $(zlib-y) devtree.c stdlib.c \ - oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \ - uartlite.c mpc52xx-psc.c opal.c + oflib.c ofconsole.c cuboot.c cpm-serial.c \ + uartlite.c opal.c +src-wlib-$(CONFIG_PPC_MPC52XX) += mpc52xx-psc.c src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S ifndef CONFIG_PPC64_BOOT_WRAPPER src-wlib-y += crtsavres.S endif src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c -src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c +src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c -src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c +src-wlib-$(CONFIG_EMBEDDED6xx) += mpsc.c mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c src-plat-y := of.c epapr.c src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ @@ -124,7 +133,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \ treeboot-iss4xx.c treeboot-currituck.c \ treeboot-akebono.c \ simpleboot.c fixed-head.S virtex.c -src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c +src-plat-$(CONFIG_PPC_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c @@ -183,10 +192,10 @@ clean-files := $(zlib-) $(zlibheader-) $(zliblinuxheader-) \ empty.c zImage.coff.lds zImage.ps3.lds zImage.lds quiet_cmd_bootcc = BOOTCC $@ - cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< + cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< quiet_cmd_bootas = BOOTAS $@ - cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< + cmd_bootas = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< quiet_cmd_bootar = BOOTAR $@ cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@ diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 12866ccb5694d3bce05fa7ab8030a57585eb2914..dcf2f15e679715b2e4000727a576e1a9f6cb1bb1 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S @@ -26,17 +26,17 @@ _zimage_start_opd: #ifdef __powerpc64__ .balign 8 -p_start: .llong _start -p_etext: .llong _etext -p_bss_start: .llong __bss_start -p_end: .llong _end - -p_toc: .llong __toc_start + 0x8000 - p_base -p_dyn: .llong __dynamic_start - p_base -p_rela: .llong __rela_dyn_start - p_base -p_prom: .llong 0 +p_start: .8byte _start +p_etext: .8byte _etext +p_bss_start: .8byte __bss_start +p_end: .8byte _end + +p_toc: .8byte __toc_start + 0x8000 - p_base +p_dyn: .8byte __dynamic_start - p_base +p_rela: .8byte __rela_dyn_start - p_base +p_prom: .8byte 0 .weak _platform_stack_top -p_pstack: .llong _platform_stack_top +p_pstack: .8byte _platform_stack_top #else p_start: .long _start p_etext: .long _etext diff --git a/arch/powerpc/boot/dts/fsp2.dts b/arch/powerpc/boot/dts/fsp2.dts index 475953ada7072c80d67e379af736220677a7b496..f10a64aeb83bd64046b0147f33e9a71baf174f18 100644 --- a/arch/powerpc/boot/dts/fsp2.dts +++ b/arch/powerpc/boot/dts/fsp2.dts @@ -52,6 +52,7 @@ clocks { mmc_clk: mmc_clk { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <50000000>; clock-output-names = "mmc_clk"; }; @@ -359,20 +360,6 @@ interrupts = <31 0x4 15 0x84>; }; - mmc0: sdhci@020c0000 { - compatible = "st,sdhci-stih407", "st,sdhci"; - status = "disabled"; - reg = <0x020c0000 0x20000>; - reg-names = "mmc"; - interrupt-parent = <&UIC1_3>; - interrupts = <21 0x4 22 0x4>; - interrupt-names = "mmcirq"; - pinctrl-names = "default"; - pinctrl-0 = <>; - clock-names = "mmc"; - clocks = <&mmc_clk>; - }; - plb6 { compatible = "ibm,plb6"; #address-cells = <2>; @@ -501,6 +488,24 @@ /*RXDE*/ 4 &UIC1_2 13 0x4>; }; + mmc0: mmc@20c0000 { + compatible = "st,sdhci-stih407", "st,sdhci"; + reg = <0x020c0000 0x20000>; + reg-names = "mmc"; + interrupts = <21 0x4>; + interrupt-parent = <&UIC1_3>; + interrupt-names = "mmcirq"; + pinctrl-names = "default"; + pinctrl-0 = <>; + clock-names = "mmc"; + clocks = <&mmc_clk>; + bus-width = <4>; + non-removable; + sd-uhs-sdr50; + sd-uhs-sdr104; + sd-uhs-ddr50; + }; + opb { compatible = "ibm,opb"; #address-cells = <1>; diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h index 68e388ee94fe51ac89f47669f3eb41a65384d13a..c63299f9fdd9abb5f6d56162edb7373b3b476aa0 100644 --- a/arch/powerpc/boot/ppc_asm.h +++ b/arch/powerpc/boot/ppc_asm.h @@ -80,4 +80,12 @@ .long 0xa6037b7d; /* mtsrr1 r11 */ \ .long 0x2400004c /* rfid */ +#ifdef CONFIG_PPC_8xx +#define MFTBL(dest) mftb dest +#define MFTBU(dest) mftbu dest +#else +#define MFTBL(dest) mfspr dest, SPRN_TBRL +#define MFTBU(dest) mfspr dest, SPRN_TBRU +#endif + #endif /* _PPC64_PPC_ASM_H */ diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c index e04c1e4063ae4ab6929d02268faac4e14db07ac6..7b5c02b1afd00987ad1bdf3336480de0f198d1e1 100644 --- a/arch/powerpc/boot/serial.c +++ b/arch/powerpc/boot/serial.c @@ -120,15 +120,19 @@ int serial_console_init(void) if (dt_is_compatible(devp, "ns16550") || dt_is_compatible(devp, "pnpPNP,501")) rc = ns16550_console_init(devp, &serial_cd); +#ifdef CONFIG_EMBEDDED6xx else if (dt_is_compatible(devp, "marvell,mv64360-mpsc")) rc = mpsc_console_init(devp, &serial_cd); +#endif else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") || dt_is_compatible(devp, "fsl,cpm1-smc-uart") || dt_is_compatible(devp, "fsl,cpm2-scc-uart") || dt_is_compatible(devp, "fsl,cpm2-smc-uart")) rc = cpm_console_init(devp, &serial_cd); +#ifdef CONFIG_PPC_MPC52XX else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart")) rc = mpc5200_psc_console_init(devp, &serial_cd); +#endif else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") || dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a")) rc = uartlite_console_init(devp, &serial_cd); diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index 243b8497d58b847a2877523c45df04f2f1326b32..ec069177d942280fa36f79bec2e6c13732a18672 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S @@ -71,32 +71,18 @@ udelay: add r4,r4,r5 addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ -#ifdef CONFIG_8xx -1: mftbu r5 - mftb r6 - mftbu r7 -#else -1: mfspr r5, SPRN_TBRU - mfspr r6, SPRN_TBRL - mfspr r7, SPRN_TBRU -#endif +1: MFTBU(r5) + MFTBL(r6) + MFTBU(r7) cmpw 0,r5,r7 bne 1b /* Get [synced] base time */ addc r9,r6,r4 /* Compute end time */ addze r8,r5 -#ifdef CONFIG_8xx -2: mftbu r5 -#else -2: mfspr r5, SPRN_TBRU -#endif +2: MFTBU(r5) cmpw 0,r5,r8 blt 2b bgt 3f -#ifdef CONFIG_8xx - mftb r6 -#else - mfspr r6, SPRN_TBRL -#endif + MFTBL(r6) cmpw 0,r6,r9 blt 2b 3: blr diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig index 3438ed99c088e38c2f1965a8b6fa8d7242b1999a..e57344c3b0d75d124c8fd5334e6b9f552173bb43 100644 --- a/arch/powerpc/configs/40x/acadia_defconfig +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -64,4 +64,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig index 36c44c0b560c24147fe7f91432ff1ee5316c5bd8..0f66f8a87be88575f6013a2936c33cc3c83a461c 100644 --- a/arch/powerpc/configs/40x/ep405_defconfig +++ b/arch/powerpc/configs/40x/ep405_defconfig @@ -64,4 +64,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index ad2156c6e2fc1769c8343bd9a8b6c3c970343846..b5cc7426c21fd030614cc3696a5efa65eb138ea9 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -72,4 +72,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/configs/40x/klondike_defconfig index 28adb782ec5175c8c9c4ef7429b596146c7f24df..caab658d1da15daffeed842f95760ac23d97e39a 100644 --- a/arch/powerpc/configs/40x/klondike_defconfig +++ b/arch/powerpc/configs/40x/klondike_defconfig @@ -26,7 +26,6 @@ CONFIG_SCSI_SAS_ATTRS=y # CONFIG_VT is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig index a00f434c4d47a7eb4f3dcdc2d86de8181114815d..e0b1489b7c7b060b06a686ffdabbed31a921127e 100644 --- a/arch/powerpc/configs/40x/makalu_defconfig +++ b/arch/powerpc/configs/40x/makalu_defconfig @@ -62,4 +62,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/obs600_defconfig b/arch/powerpc/configs/40x/obs600_defconfig index e500e6a12b3e49f3a5ad03a570ab8b883eb12e52..aac06d2ad01ae25742ba1163b98b4d5f1154165c 100644 --- a/arch/powerpc/configs/40x/obs600_defconfig +++ b/arch/powerpc/configs/40x/obs600_defconfig @@ -72,4 +72,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig index 65dc084a154ce3fa2a5bf75cfdaa50096a71e726..a2b2770eee8f8031fa315d32d910b7c7887b7d2e 100644 --- a/arch/powerpc/configs/40x/virtex_defconfig +++ b/arch/powerpc/configs/40x/virtex_defconfig @@ -41,9 +41,9 @@ CONFIG_NETDEVICES=y CONFIG_SERIO_XILINX_XPS_PS2=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_XILINX_HWICAP=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -74,4 +74,3 @@ CONFIG_FONT_8x16=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig index 567f99bd64a30610820b762bce6a767ba5ad952e..6faa03cd661c4eaa880e60dccd64a969f8e62580 100644 --- a/arch/powerpc/configs/40x/walnut_defconfig +++ b/arch/powerpc/configs/40x/walnut_defconfig @@ -57,4 +57,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig index 143b2fbddb464e1c7deadbe7303baa9eaea81e7f..9fcd361607e2fb6ccc362d5ad0da9c573ac40417 100644 --- a/arch/powerpc/configs/44x/akebono_defconfig +++ b/arch/powerpc/configs/44x/akebono_defconfig @@ -123,7 +123,6 @@ CONFIG_NLS_DEFAULT="n" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y @@ -135,5 +134,4 @@ CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1_PPC=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/bamboo_defconfig b/arch/powerpc/configs/44x/bamboo_defconfig index 477d99fefd9a46e5a3a7c39167ea4bdc3dc993eb..6f3a6ecc81e7defa505c74e516715a7d6962f52f 100644 --- a/arch/powerpc/configs/44x/bamboo_defconfig +++ b/arch/powerpc/configs/44x/bamboo_defconfig @@ -55,4 +55,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/currituck_defconfig b/arch/powerpc/configs/44x/currituck_defconfig index 3799a26de6f4c7de1da0e25370616c626cd53335..5f1df5fe4453206462232991f895d1a8d8043fd6 100644 --- a/arch/powerpc/configs/44x/currituck_defconfig +++ b/arch/powerpc/configs/44x/currituck_defconfig @@ -81,7 +81,6 @@ CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NLS_DEFAULT="n" CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y @@ -94,5 +93,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/ebony_defconfig b/arch/powerpc/configs/44x/ebony_defconfig index c265f54ab9e520291db8b06f8eff19ea65c7e9de..e2b6578993d54b2e086a79dea488faced4a77a82 100644 --- a/arch/powerpc/configs/44x/ebony_defconfig +++ b/arch/powerpc/configs/44x/ebony_defconfig @@ -59,5 +59,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig index bb6bd6d9082172a0dbe05a7badd31040ed82a065..f6dc23fef6837689ae3d1e0a1e9fd462b1b5166b 100644 --- a/arch/powerpc/configs/44x/eiger_defconfig +++ b/arch/powerpc/configs/44x/eiger_defconfig @@ -84,18 +84,14 @@ CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_XTS=y -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_BLOWFISH=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/fsp2_defconfig b/arch/powerpc/configs/44x/fsp2_defconfig index e8e6a69998527e0567768146e3688c633576fc3f..bae6b26bcfba7fd2b77d9c4bf583720f665a7746 100644 --- a/arch/powerpc/configs/44x/fsp2_defconfig +++ b/arch/powerpc/configs/44x/fsp2_defconfig @@ -92,8 +92,10 @@ CONFIG_MMC_DEBUG=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SDHCI_ST=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_M41T80=y +CONFIG_RESET_CONTROLLER=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y @@ -115,7 +117,6 @@ CONFIG_PRINTK_TIME=y CONFIG_MESSAGE_LOGLEVEL_DEFAULT=3 CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_CBC=y diff --git a/arch/powerpc/configs/44x/icon_defconfig b/arch/powerpc/configs/44x/icon_defconfig index 060f2edddb71d949d8cec81783bd6e43529e68d0..4453a4590b1a02beec353a99557f4b1e42b2016c 100644 --- a/arch/powerpc/configs/44x/icon_defconfig +++ b/arch/powerpc/configs/44x/icon_defconfig @@ -47,8 +47,6 @@ CONFIG_FUSION_LOGGING=y CONFIG_NETDEVICES=y CONFIG_IBM_EMAC=y # CONFIG_WLAN is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 # CONFIG_MOUSE_PS2_ALPS is not set # CONFIG_MOUSE_PS2_LOGIPS2PP is not set # CONFIG_MOUSE_PS2_SYNAPTICS is not set @@ -94,4 +92,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/iss476-smp_defconfig b/arch/powerpc/configs/44x/iss476-smp_defconfig index 115a6b2be18bf362e108841c644d906f64a79d0e..d24bfa6ecd6241ae0e1e0c0d4cfd839c7adba805 100644 --- a/arch/powerpc/configs/44x/iss476-smp_defconfig +++ b/arch/powerpc/configs/44x/iss476-smp_defconfig @@ -63,7 +63,6 @@ CONFIG_TMPFS=y CONFIG_CRAMFS=y # CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_PPC_EARLY_DEBUG=y @@ -72,5 +71,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig index b999048c4ae6224d9db9e37b7f345b5e080e9c7a..5d3f685a7af87254afcfc91276f04e55a0031903 100644 --- a/arch/powerpc/configs/44x/katmai_defconfig +++ b/arch/powerpc/configs/44x/katmai_defconfig @@ -60,4 +60,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/rainier_defconfig b/arch/powerpc/configs/44x/rainier_defconfig index b8c9ee45d0a2bb82a945ba51f93f79ac338bd431..7b8355a5698d8570a463fa6e3cf88d89c740e940 100644 --- a/arch/powerpc/configs/44x/rainier_defconfig +++ b/arch/powerpc/configs/44x/rainier_defconfig @@ -66,4 +66,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig index a4bb048448dac4f8ab2ec8ff1212b916d8a9c82f..918cfb63f0c85f9ef49a58fd033577f01c5335e8 100644 --- a/arch/powerpc/configs/44x/redwood_defconfig +++ b/arch/powerpc/configs/44x/redwood_defconfig @@ -83,18 +83,14 @@ CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_XTS=y -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_BLOWFISH=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig index b3792fd8111d78aae36a3d77877ba22c42cada76..1e04122912f300f5b9cd63bbbf03df1b2f960355 100644 --- a/arch/powerpc/configs/44x/sequoia_defconfig +++ b/arch/powerpc/configs/44x/sequoia_defconfig @@ -67,4 +67,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/taishan_defconfig b/arch/powerpc/configs/44x/taishan_defconfig index ff6f86241418a505dcd5a7ba2b8188418d0c9f9f..42cc7b4ed95f6225bb759a54b9ad16c4119947d5 100644 --- a/arch/powerpc/configs/44x/taishan_defconfig +++ b/arch/powerpc/configs/44x/taishan_defconfig @@ -61,4 +61,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/virtex5_defconfig b/arch/powerpc/configs/44x/virtex5_defconfig index ce052064bcbbcdeb21562c9ffa08dc3db7a6d362..99cc3dc02df18f2481738411a4fcccfd07bef60b 100644 --- a/arch/powerpc/configs/44x/virtex5_defconfig +++ b/arch/powerpc/configs/44x/virtex5_defconfig @@ -40,9 +40,9 @@ CONFIG_NETDEVICES=y CONFIG_SERIO_XILINX_XPS_PS2=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_XILINX_HWICAP=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -73,4 +73,3 @@ CONFIG_FONT_8x16=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig index ab932488e68b5801db6b4478da20b5d1728207dd..b5c866073efda593948d52875277653503b3bbd5 100644 --- a/arch/powerpc/configs/44x/warp_defconfig +++ b/arch/powerpc/configs/44x/warp_defconfig @@ -97,4 +97,3 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig index c1faac800806627b6d81856c201ec387abf76dc0..73948e88ac82e6c5c8f408391e79cef1b83b340d 100644 --- a/arch/powerpc/configs/52xx/cm5200_defconfig +++ b/arch/powerpc/configs/52xx/cm5200_defconfig @@ -77,4 +77,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig index 9493b02ac66001cf55a505b4fd27ddff91665f36..6fc7f786c83c13ae12e09dc2b797ea56a86ee00f 100644 --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -14,6 +14,7 @@ CONFIG_PPC_MPC52xx=y CONFIG_PPC_MPC5200_SIMPLE=y CONFIG_PPC_LITE5200=y # CONFIG_PPC_PMAC is not set +CONFIG_GEN_RTC=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -44,7 +45,6 @@ CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -62,4 +62,3 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index fe8126bc1655f4eaa0030bf6418a6cdc00340a4b..ae2a1f74103b3a1b4969cd29169cf495cb130559 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -41,16 +41,16 @@ CONFIG_ATA=y CONFIG_PATA_MPC52xx=y CONFIG_NETDEVICES=y CONFIG_FEC_MPC52xx=y -CONFIG_MARVELL_PHY=y +CONFIG_MDIO_BITBANG=y +CONFIG_BROADCOM_PHY=y +CONFIG_CICADA_PHY=y CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y +CONFIG_ICPLUS_PHY=y CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_QSEMI_PHY=y CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y -CONFIG_MDIO_BITBANG=y +CONFIG_VITESSE_PHY=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -90,4 +90,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index b8b316b884aa2dafbd61dbf2476afc6e29f2124e..0777e6efd22dd4ecff825327d84d5c60aac7c2a5 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -48,7 +48,6 @@ CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_FEC_MPC52xx=y CONFIG_LXT_PHY=y -CONFIG_FIXED_PHY=y CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 @@ -92,4 +91,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/asp8347_defconfig b/arch/powerpc/configs/83xx/asp8347_defconfig index b60cac088a7b49a4d97a49cd386d20bc4a7e13c3..dd884df32dfdd86f0337de65ec836cde54ab2218 100644 --- a/arch/powerpc/configs/83xx/asp8347_defconfig +++ b/arch/powerpc/configs/83xx/asp8347_defconfig @@ -42,7 +42,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_GIANFAR=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -71,4 +70,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/kmeter1_defconfig b/arch/powerpc/configs/83xx/kmeter1_defconfig index 9547dcdd648916bb0c05e759678de8257dc43869..d21b5cb365f23a2d21a62966f1ef9449a9db0d48 100644 --- a/arch/powerpc/configs/83xx/kmeter1_defconfig +++ b/arch/powerpc/configs/83xx/kmeter1_defconfig @@ -55,7 +55,6 @@ CONFIG_HDLC=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig index 80aa844c14284f6d6ed3c3a4b7939d28d85f071a..1f69f4edf0748e6ac1fae2e1ee8c5d6bd6dd3473 100644 --- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig @@ -48,8 +48,6 @@ CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y CONFIG_CICADA_PHY=y -CONFIG_FIXED_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -87,4 +85,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig index d89d13bc6901e7f19a76942bcfe11b87bf520530..797fc3ffddee25749349bbdb2683f317d758c4f5 100644 --- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig @@ -47,7 +47,6 @@ CONFIG_MD_RAID1=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -85,4 +84,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig index e789518a2881a5bc0552039f12e6c1a451791623..4f914906ee4b4deb15ed547f7e5197bc1e05e352 100644 --- a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig @@ -14,7 +14,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC832x_MDS=y -CONFIG_QUICC_ENGINE=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -36,7 +35,6 @@ CONFIG_SCSI=y CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_DAVICOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -50,6 +48,7 @@ CONFIG_I2C_MPC=y CONFIG_WATCHDOG=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1374=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -59,4 +58,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig index 917a49ca2bd1a068d22eac57bf349f49ebd22291..a484eb8401e88bc270193a07a25b12c3b008ddda 100644 --- a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig @@ -14,7 +14,7 @@ CONFIG_LDM_PARTITION=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC832x_RDB=y -CONFIG_QUICC_ENGINE=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -38,7 +38,6 @@ CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_E1000=y CONFIG_ICPLUS_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -46,7 +45,6 @@ CONFIG_ICPLUS_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -62,6 +60,7 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_SPI=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_MSDOS_FS=y @@ -78,4 +77,3 @@ CONFIG_NLS_ISO8859_1=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig index 00f636e95cc8cb3154370ea7aa7ea3665491f173..37f4d93b3f81eb4bbc8c05f386b722c5b794715b 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig @@ -49,7 +49,6 @@ CONFIG_MD_RAID1=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_CICADA_PHY=y -CONFIG_FIXED_PHY=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -84,4 +83,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig index a539d44d1dbaa31d5e76b826aae78ec4d96fb9f5..7adb6708a761642baa8451d148404d9b83f27923 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig @@ -75,4 +75,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig index 9f0ddc830c82ae93a1bc1690c79f59b90209723f..d7ce3551529d13a5f963b8bd2ece1a4e59ea6368 100644 --- a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig @@ -35,7 +35,6 @@ CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -58,4 +57,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig index ceed4c1f0ab51e02bde5bd3b9f5a7c07fdb1235d..92134cee3f375c877ba9b33a38c56604f306e65c 100644 --- a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig @@ -14,7 +14,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC836x_MDS=y -CONFIG_QUICC_ENGINE=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -41,7 +40,6 @@ CONFIG_SCSI=y CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -55,6 +53,7 @@ CONFIG_I2C_MPC=y CONFIG_WATCHDOG=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1374=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -64,4 +63,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig index a6819bf3ef5e4a2bd6ae17e86cab6435e557e9f0..97f7ea5f205f682f81db967db9ece09d72627ed1 100644 --- a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig +++ b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig @@ -12,7 +12,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC836x_RDK=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_PCI=y CONFIG_NET=y @@ -39,11 +38,9 @@ CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_QE=y @@ -63,6 +60,7 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_USB_SUPPORT is not set +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -72,4 +70,3 @@ CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_PPC_EARLY_DEBUG=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig index 4bd1992e4d982e4baab53551a74cc1427b7d600f..ee7510a33d06b2ec0dba4061124c8068b7530df4 100644 --- a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC837x_MDS=y +CONFIG_GEN_RTC=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -35,7 +36,6 @@ CONFIG_SATA_FSL=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -43,7 +43,6 @@ CONFIG_MARVELL_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig index 2d4bb63882b8022aecba5ddc9be24a6fcf2cf14e..8966a9af42300d8807b881018005142e84509081 100644 --- a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC837x_RDB=y +CONFIG_GEN_RTC=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -41,9 +42,7 @@ CONFIG_MD_RAID456=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -CONFIG_FIXED_PHY=y CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -51,7 +50,6 @@ CONFIG_INPUT_FF_MEMLESS=m CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -86,4 +84,3 @@ CONFIG_CRC_T10DIF=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/sbc834x_defconfig b/arch/powerpc/configs/83xx/sbc834x_defconfig index b3380dbd192514134e3f134063bfee648d5515fc..7d74699334da5c1470cfe9b6ec42bc9caa0cb5b4 100644 --- a/arch/powerpc/configs/83xx/sbc834x_defconfig +++ b/arch/powerpc/configs/83xx/sbc834x_defconfig @@ -11,6 +11,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_SBC834x=y +CONFIG_GEN_RTC=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -41,7 +42,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -52,7 +52,6 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -72,5 +71,4 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/85xx/ge_imp3a_defconfig b/arch/powerpc/configs/85xx/ge_imp3a_defconfig index a917f7afb4f9bd7af7bcf3d17ec7ad03a7150049..dd98f43b2fb806501dd1454e6fe2fa265ba04d43 100644 --- a/arch/powerpc/configs/85xx/ge_imp3a_defconfig +++ b/arch/powerpc/configs/85xx/ge_imp3a_defconfig @@ -22,7 +22,6 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_GE_IMP3A=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_CPM2=y CONFIG_HIGHMEM=y @@ -161,6 +160,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RX8581=y CONFIG_DMADEVICES=y CONFIG_FSL_DMA=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -233,5 +233,4 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_TALITOS=y diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig index bd814dfb0bbdfaf26b1cbe8b0d979aa71b0ce4d9..9ce6f48cfb61b55c5acdd8ba4adbed44a9081639 100644 --- a/arch/powerpc/configs/85xx/ksi8560_defconfig +++ b/arch/powerpc/configs/85xx/ksi8560_defconfig @@ -8,6 +8,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_KSI8560=y CONFIG_CPM2=y +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y @@ -39,14 +40,12 @@ CONFIG_FS_ENET=y CONFIG_FS_ENET_MDIO_FCC=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -57,4 +56,3 @@ CONFIG_DEBUG_FS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig index 32af10def64104b4590259a593b06aac525a7682..5fbc3f904046b98ce60fafa27dbaf9d9a9e90a99 100644 --- a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig +++ b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_MPC8540_ADS=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -30,7 +31,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_GIANFAR=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -38,7 +38,6 @@ CONFIG_GIANFAR=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -47,4 +46,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig index a52b2170ee33e979f5bd069fb43511be58045f40..ff981d7905c77c26188681ca1c97fa32fdec2dd9 100644 --- a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig +++ b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig @@ -7,6 +7,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_MPC8560_ADS=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -32,16 +33,14 @@ CONFIG_FS_ENET=y # CONFIG_FS_ENET_HAS_SCC is not set CONFIG_GIANFAR=y CONFIG_E1000=y -CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_MARVELL_PHY=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -50,4 +49,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig index 002bb48abaa37407ef1031dbc6217f72ac651b08..974f0706d777551bf3cd5e5711cab775519adbe1 100644 --- a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig +++ b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_MPC85xx_CDS=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E1000=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -43,7 +43,6 @@ CONFIG_E1000=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -52,4 +51,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/sbc8548_defconfig b/arch/powerpc/configs/85xx/sbc8548_defconfig index 97ae02377cf3d745b43238c0e5981f80e23f132f..7e3e84a842e4e4b5b0e30284f7fb12dae5a541ca 100644 --- a/arch/powerpc/configs/85xx/sbc8548_defconfig +++ b/arch/powerpc/configs/85xx/sbc8548_defconfig @@ -6,6 +6,7 @@ CONFIG_EXPERT=y CONFIG_SLAB=y # CONFIG_BLK_DEV_BSG is not set CONFIG_SBC8548=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -36,7 +37,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,10 +44,8 @@ CONFIG_BROADCOM_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y # CONFIG_USB_SUPPORT is not set CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/socrates_defconfig b/arch/powerpc/configs/85xx/socrates_defconfig index 13579cb305399ee11f8fa63df62bf578c5ee8526..6106fadbbd8ba3fe4ae50c7557ec94dd2a6a4acc 100644 --- a/arch/powerpc/configs/85xx/socrates_defconfig +++ b/arch/powerpc/configs/85xx/socrates_defconfig @@ -42,8 +42,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=800 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -86,4 +84,3 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_FONTS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig index 384926f3ce1dced3e058ee25a425fdb81f1d7300..5b9cc01b909876d6bcff0eb8aa465d51b59bcfb1 100644 --- a/arch/powerpc/configs/85xx/stx_gp3_defconfig +++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig @@ -39,8 +39,6 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=m # CONFIG_VT is not set @@ -68,4 +66,3 @@ CONFIG_CRC_T10DIF=m CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_BDI_SWITCH=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8540_defconfig b/arch/powerpc/configs/85xx/tqm8540_defconfig index 908f3885f4a54fb2ac863680d4422436f390f4dd..98982a0e82d804359381a5fbac67eb931eb8731b 100644 --- a/arch/powerpc/configs/85xx/tqm8540_defconfig +++ b/arch/powerpc/configs/85xx/tqm8540_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8540=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,14 +36,12 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -56,4 +55,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8541_defconfig b/arch/powerpc/configs/85xx/tqm8541_defconfig index f47e57610b7c0bbd07f811302a6998f7325806fd..a6e21db1dafe3ac246775bb525e63d64c9fc3e18 100644 --- a/arch/powerpc/configs/85xx/tqm8541_defconfig +++ b/arch/powerpc/configs/85xx/tqm8541_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8541=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,7 +44,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig index 42f5d0a7698e5af48cb058e9427e1051eaca2b64..2697e4e8a761c9995791a93444d315c2e9fb823a 100644 --- a/arch/powerpc/configs/85xx/tqm8548_defconfig +++ b/arch/powerpc/configs/85xx/tqm8548_defconfig @@ -43,7 +43,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_GIANFAR=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -66,4 +65,3 @@ CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8555_defconfig b/arch/powerpc/configs/85xx/tqm8555_defconfig index 71552b7929cdf2f27caa742296efe36f6d3ebeab..ca1de3979474bac4bdad18b618ecb769109f827a 100644 --- a/arch/powerpc/configs/85xx/tqm8555_defconfig +++ b/arch/powerpc/configs/85xx/tqm8555_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8555=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,7 +44,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8560_defconfig b/arch/powerpc/configs/85xx/tqm8560_defconfig index 25aac973d6d7c1a414a56074d6ef5fdab084bc1e..ca3b8c8ef30f9cc2e0de0098219c7414a75b49a4 100644 --- a/arch/powerpc/configs/85xx/tqm8560_defconfig +++ b/arch/powerpc/configs/85xx/tqm8560_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8560=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,7 +44,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig index 72900b84d3e05ae332fca49c0b2de241f578819f..6531139a8a8d338fd1e0f8444bb89075f334c519 100644 --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig @@ -54,7 +54,6 @@ CONFIG_IP_PIMSM_V2=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_IPV6=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_REDBOOT_PARTS=y @@ -86,7 +85,6 @@ CONFIG_DUMMY=y CONFIG_GIANFAR=y CONFIG_E1000=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set CONFIG_SERIO_LIBPS2=y @@ -107,8 +105,8 @@ CONFIG_SENSORS_LM90=y CONFIG_WATCHDOG=y CONFIG_USB=y CONFIG_USB_MON=y -CONFIG_USB_ISP1760=y CONFIG_USB_STORAGE=y +CONFIG_USB_ISP1760=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_PCA955X=y @@ -143,4 +141,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig index 6a3f825452e90c210b0607655188e64486b794a4..935ea3ade7de8bb172c428bef2559c26790de92c 100644 --- a/arch/powerpc/configs/adder875_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -12,6 +12,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_PPC_ADDER875=y CONFIG_8xx_COPYBACK=y +CONFIG_GEN_RTC=y CONFIG_HZ_1000=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -41,7 +42,6 @@ CONFIG_DAVICOM_PHY=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_USB_SUPPORT is not set diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig index 8d3e3c41258dee2f7bdfdeb8dc7f9f543c0ac500..12f397d403c671cdc8102562c2ff4b8baa3f452e 100644 --- a/arch/powerpc/configs/amigaone_defconfig +++ b/arch/powerpc/configs/amigaone_defconfig @@ -45,7 +45,6 @@ CONFIG_PARPORT_PC_FIFO=y CONFIG_BLK_DEV_FD=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y @@ -120,5 +119,4 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/be.config b/arch/powerpc/configs/be.config new file mode 100644 index 0000000000000000000000000000000000000000..c5cdc99a6530f1b51df7bc3fa29454470f5e17aa --- /dev/null +++ b/arch/powerpc/configs/be.config @@ -0,0 +1 @@ +CONFIG_CPU_BIG_ENDIAN=y diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig index 7c9d9537015001b3fb28061d5bd9e6bfa017ecdc..f1552af9eeccd24c1d5bb35bce62c2d9dfafa11f 100644 --- a/arch/powerpc/configs/c2k_defconfig +++ b/arch/powerpc/configs/c2k_defconfig @@ -27,6 +27,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_BINFMT_MISC=y @@ -197,7 +198,6 @@ CONFIG_TUN=m # CONFIG_ATM_DRIVERS is not set CONFIG_MV643XX_ETH=y CONFIG_VITESSE_PHY=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -209,7 +209,6 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_MPSC=y CONFIG_SERIAL_MPSC_CONSOLE=y CONFIG_NVRAM=m -CONFIG_GEN_RTC=m CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=8192 CONFIG_I2C=m @@ -390,7 +389,6 @@ CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DISABLE=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=y @@ -402,4 +400,3 @@ CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index aa564599e36885f2eadfbbf0b45599ae84d4f33e..560a93a84efe2fba8ac74d4a801cabfea257419c 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -4,7 +4,6 @@ CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_SYSVIPC=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y @@ -34,10 +33,10 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=m CONFIG_IRQ_ALL_CPUS=y CONFIG_NUMA=y -CONFIG_MEMORY_HOTREMOVE=y CONFIG_PPC_64K_PAGES=y CONFIG_SCHED_SMT=y CONFIG_PCIEPORTBUS=y @@ -53,7 +52,6 @@ CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_IPV6=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -141,7 +139,6 @@ CONFIG_SKY2=m CONFIG_GELIC_NET=m CONFIG_GELIC_WIRELESS=y CONFIG_SPIDER_NET=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_I8042 is not set @@ -149,8 +146,6 @@ CONFIG_SPIDER_NET=y CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_TXX9_NR_UARTS=2 -CONFIG_SERIAL_TXX9_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HVC_RTAS=y CONFIG_IPMI_HANDLER=m @@ -159,7 +154,6 @@ CONFIG_IPMI_SI=m CONFIG_IPMI_WATCHDOG=m CONFIG_IPMI_POWEROFF=m # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_WATCHDOG=y # CONFIG_VGA_CONSOLE is not set @@ -207,7 +201,6 @@ CONFIG_NLS_ISO8859_13=m CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index 1f6f90cd8affd7db5d356e44d173c5be2ee7c0b6..a203b1cf67d3d5713100092b8c266d62771b07e7 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig @@ -16,6 +16,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y # CONFIG_PPC_PMAC is not set +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_BINFMT_MISC=y CONFIG_IRQ_ALL_CPUS=y @@ -79,7 +80,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y @@ -124,5 +124,4 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig index 3403b85f9d8139e8b5b6b06af4e6d11b68a89810..2e6c8a45ae88a9e4bd49153037a5f893892c5ef2 100644 --- a/arch/powerpc/configs/ep8248e_defconfig +++ b/arch/powerpc/configs/ep8248e_defconfig @@ -70,5 +70,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig index 95411aeeeb8d3280d5d3811f438cb9b2476b9f47..7cb590e8f8fd172b908976dd30553fc25556786b 100644 --- a/arch/powerpc/configs/ep88xc_defconfig +++ b/arch/powerpc/configs/ep88xc_defconfig @@ -14,6 +14,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_PPC_EP88XC=y CONFIG_8xx_COPYBACK=y +CONFIG_GEN_RTC=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -45,7 +46,6 @@ CONFIG_LXT_PHY=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index e18f2e06553fee6fdbad84c3c360627768f9eaaf..063817fee61cfeea164555a99139de3ffda3aedf 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -4,7 +4,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y @@ -25,6 +24,7 @@ CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_PMAC64=y +CONFIG_GEN_RTC=y CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_PCI_MSI=y @@ -115,7 +115,6 @@ CONFIG_USB_USBNET=m # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -123,7 +122,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_RAW_DRIVER=y CONFIG_I2C_CHARDEV=y CONFIG_AGP=m @@ -140,10 +138,11 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_POWERMAC=m CONFIG_SND_AOA=m CONFIG_SND_AOA_FABRIC_LAYOUT=m @@ -213,20 +212,20 @@ CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_APPLEDISPLAY=m -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=y CONFIG_REISERFS_FS_XATTR=y CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y CONFIG_XFS_FS=m CONFIG_XFS_POSIX_ACL=y +CONFIG_FS_DAX=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y @@ -254,14 +253,12 @@ CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_15=y CONFIG_NLS_UTF8=y CONFIG_CRC_T10DIF=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y CONFIG_LATENCYTOP=y CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_HMAC=y @@ -276,5 +273,4 @@ CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig index c0eec4a5df4ea91e66064d8d5c231058793a3bec..805b0f87653c1939f2722929689db2ebb128930f 100644 --- a/arch/powerpc/configs/gamecube_defconfig +++ b/arch/powerpc/configs/gamecube_defconfig @@ -45,7 +45,6 @@ CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_NETDEVICES=y # CONFIG_WLAN is not set CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -54,7 +53,6 @@ CONFIG_INPUT_JOYSTICK=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set CONFIG_LEGACY_PTY_COUNT=64 -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set CONFIG_FB=y @@ -66,11 +64,12 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_SEQUENCER=y +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y # CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQUENCER_OSS=y # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_GENERIC=y diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig index e56e800905294f657882c3ed7165a571fd561bf9..71d8d2430b6cbeafa32278cee83158fbe26ebbc8 100644 --- a/arch/powerpc/configs/holly_defconfig +++ b/arch/powerpc/configs/holly_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_EMBEDDED6xx=y CONFIG_PPC_HOLLY=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,115200" @@ -37,7 +38,6 @@ CONFIG_NETDEVICES=y CONFIG_VORTEX=y CONFIG_TSI108_ETH=y CONFIG_PHYLIB=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -49,7 +49,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig index b413c19d7031a71d7fa8c75bb308b77aa62ba30b..477794c41d502110871f01d826bbb09325a5f96f 100644 --- a/arch/powerpc/configs/linkstation_defconfig +++ b/arch/powerpc/configs/linkstation_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -79,7 +78,6 @@ CONFIG_NET_TULIP=y CONFIG_TULIP=y CONFIG_TULIP_MMIO=y CONFIG_R8169=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -142,4 +140,3 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index c4018179e219a580b8e51213dcfd6a8c0b69caeb..078cdb427fc99a039502e8ef83e9d044ac5ce3fa 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -3,7 +3,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y @@ -24,6 +23,7 @@ CONFIG_MAC_PARTITION=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_MAPLE=y CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_GEN_RTC=y CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_PCI_MSI=y @@ -53,9 +53,6 @@ CONFIG_AMD8111_ETH=y CONFIG_TIGON3=y CONFIG_E1000=y CONFIG_USB_PEGASUS=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -63,7 +60,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HVC_RTAS=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_AMD8111=y @@ -100,8 +96,8 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49W=y CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y CONFIG_USB_SERIAL_TI=m CONFIG_EXT2_FS=y -CONFIG_FS_DAX=y CONFIG_EXT4_FS=y +CONFIG_FS_DAX=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y @@ -127,5 +123,4 @@ CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig index 197acaa026eb3840ecc028d333775b32e02e3fc4..5d5f08e5b8d9334e39a29c1359c5e741808b016f 100644 --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig @@ -46,7 +46,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y CONFIG_FS_ENET_MDIO_FCC=y -CONFIG_FIXED_PHY=y # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set @@ -83,5 +82,4 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_BDI_SWITCH=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index 0b4854cf26cb27d91bdff7dec0e6dd3af99e30e9..10be5773ad5dc63283d592d19df2e0c22d0af221 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig @@ -12,6 +12,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set # CONFIG_PPC_CHRP is not set CONFIG_PPC_MPC512x=y +CONFIG_MPC512x_LPBFIFO=y CONFIG_MPC5121_ADS=y CONFIG_MPC512x_GENERIC=y CONFIG_PDM360NG=y @@ -61,25 +62,22 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y +CONFIG_MDIO_BITBANG=y CONFIG_BROADCOM_PHY=y +CONFIG_CICADA_PHY=y +CONFIG_DAVICOM_PHY=y CONFIG_ICPLUS_PHY=y -CONFIG_REALTEK_PHY=y +CONFIG_LSI_ET1011C_PHY=y +CONFIG_LXT_PHY=y +CONFIG_MARVELL_PHY=y CONFIG_NATIONAL_PHY=y +CONFIG_QSEMI_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_SMSC_PHY=y CONFIG_STE10XP=y -CONFIG_LSI_ET1011C_PHY=y -CONFIG_FIXED_PHY=y -CONFIG_MDIO_BITBANG=y +CONFIG_VITESSE_PHY=y # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 @@ -111,10 +109,9 @@ CONFIG_RTC_DRV_M41T80=y CONFIG_RTC_DRV_MPC5121=y CONFIG_DMADEVICES=y CONFIG_MPC512X_DMA=y -CONFIG_MPC512x_LPBFIFO=y -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y +CONFIG_FS_DAX=y # CONFIG_DNOTIFY is not set CONFIG_VFAT_FS=y CONFIG_TMPFS=y @@ -126,5 +123,4 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 88336d0df0d6ee77da1468fc79ed744abbdfe50d..7a2b2aa37defc07ec8c286ecc55b203950ef3e04 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -50,7 +50,6 @@ CONFIG_NETDEVICES=y CONFIG_FEC_MPC52xx=y CONFIG_AMD_PHY=y CONFIG_LXT_PHY=y -CONFIG_FIXED_PHY=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -71,12 +70,10 @@ CONFIG_SENSORS_LM87=m CONFIG_WATCHDOG=y CONFIG_MFD_SM501=m CONFIG_DRM=y -CONFIG_FB=y CONFIG_FB_FOREIGN_ENDIAN=y CONFIG_FB_RADEON=y CONFIG_FB_SM501=m # CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y @@ -130,4 +127,3 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index d933326b4cf9e79fd8ab5874e46250f96179492c..4b14c02b437c33e7481d96a2cd4dc8e162d9515c 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_EMBEDDED6xx=y CONFIG_MPC7448HPC2=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -38,7 +39,6 @@ CONFIG_8139TOO=y # CONFIG_8139TOO_PIO is not set CONFIG_TSI108_ETH=y CONFIG_PHYLIB=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -46,7 +46,6 @@ CONFIG_PHYLIB=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -54,4 +53,3 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig index 4cb0f617c0d69318c134793d211924fa7402e24e..b1e88b64536b5a3d56e923c030b29df2246bf0d8 100644 --- a/arch/powerpc/configs/mpc8272_ads_defconfig +++ b/arch/powerpc/configs/mpc8272_ads_defconfig @@ -77,5 +77,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig index 6574477fd726eba8a96941428bf3bb365a3a5132..d1b82035d35f9aae54886fe01798e9e5cdea5d91 100644 --- a/arch/powerpc/configs/mpc83xx_defconfig +++ b/arch/powerpc/configs/mpc83xx_defconfig @@ -21,7 +21,6 @@ CONFIG_MPC837x_MDS=y CONFIG_MPC837x_RDB=y CONFIG_SBC834x=y CONFIG_ASP834x=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y @@ -60,13 +59,11 @@ CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_GIANFAR=y -CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y -CONFIG_VITESSE_PHY=y CONFIG_ICPLUS_PHY=y -CONFIG_FIXED_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_VITESSE_PHY=y CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -99,6 +96,7 @@ CONFIG_USB_EHCI_FSL=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_DS1374=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -109,7 +107,5 @@ CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_TALITOS=y diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig index 998454471a488503577449b6e6515935a832d712..f1f176c29fa3e932c1626453fc48824bd489fc41 100644 --- a/arch/powerpc/configs/mpc866_ads_defconfig +++ b/arch/powerpc/configs/mpc866_ads_defconfig @@ -14,6 +14,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MPC86XADS=y CONFIG_8xx_COPYBACK=y CONFIG_8xx_CPU6=y +CONFIG_GEN_RTC=y CONFIG_HZ_1000=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -28,12 +29,10 @@ CONFIG_SYN_COOKIES=y CONFIG_BLK_DEV_LOOP=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y -CONFIG_FIXED_PHY=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT4_FS=y @@ -43,4 +42,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC_CCITT=y CONFIG_CRC32_SLICEBY4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig index 3283f0586e112d580ccf94e6e2d5c7b7b9f65af0..67bd1fa036eed6bd09a198859f120310225990bf 100644 --- a/arch/powerpc/configs/mpc86xx_basic_defconfig +++ b/arch/powerpc/configs/mpc86xx_basic_defconfig @@ -1,11 +1,11 @@ -CONFIG_HIGHMEM=y -CONFIG_KEXEC=y CONFIG_PPC_86xx=y -CONFIG_PROC_KCORE=y +CONFIG_MPC8641_HPCN=y +CONFIG_SBC8641D=y +CONFIG_MPC8610_HPCD=y CONFIG_GEF_PPC9A=y CONFIG_GEF_SBC310=y CONFIG_GEF_SBC610=y -CONFIG_MPC8610_HPCD=y -CONFIG_MPC8641_HPCN=y -CONFIG_SBC8641D=y CONFIG_MVME7100=y +CONFIG_HIGHMEM=y +CONFIG_KEXEC=y +CONFIG_PROC_KCORE=y diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig index 91f53f1bec5d39152f449177ef82bd7e31094338..ec3fcc2bf7378d3987978da5aa828a121413d940 100644 --- a/arch/powerpc/configs/mpc885_ads_defconfig +++ b/arch/powerpc/configs/mpc885_ads_defconfig @@ -13,6 +13,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_8xx_COPYBACK=y +CONFIG_GEN_RTC=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -51,7 +52,6 @@ CONFIG_DAVICOM_PHY=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set diff --git a/arch/powerpc/configs/mvme5100_defconfig b/arch/powerpc/configs/mvme5100_defconfig index 139add95a16a775c8775d838fb9e94110ac39d54..63e38c7220f12fa1374dd96481e01cbd8e913a65 100644 --- a/arch/powerpc/configs/mvme5100_defconfig +++ b/arch/powerpc/configs/mvme5100_defconfig @@ -35,7 +35,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -70,7 +69,6 @@ CONFIG_TUN=m # CONFIG_NET_VENDOR_3COM is not set CONFIG_E100=y # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -130,4 +128,3 @@ CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index fe43ff47bd2f217631b98ec0851c62d7ef91fe10..6daa56f8895cb22bcd37011328c68932abe50074 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -3,7 +3,6 @@ CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_SYSVIPC=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y @@ -116,9 +115,10 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_SEQUENCER=y +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER=y CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_USX2Y=y @@ -145,6 +145,7 @@ CONFIG_EDAC=y CONFIG_EDAC_PASEMI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_RAS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -167,7 +168,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_CRC_CCITT=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y @@ -175,7 +175,5 @@ CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_BLOWFISH=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index fc1e7a7388b8894f9eb9e549fcaaa071de583399..1aab9a62a681d4856aff8f7afaa0f9435832b4d9 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -21,6 +21,7 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_PMAC=y CONFIG_PPC601_SYNC_FIX=y +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -179,10 +180,10 @@ CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=m CONFIG_USB_USBNET=m # CONFIG_USB_NET_CDC_SUBSET is not set -CONFIG_PRISM54=m CONFIG_B43=m CONFIG_B43LEGACY=m CONFIG_P54_COMMON=m +CONFIG_PRISM54=m CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_MOUSE_PS2 is not set @@ -193,7 +194,6 @@ CONFIG_SERIAL_8250=m CONFIG_SERIAL_PMACZILOG=m CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_NVRAM=y -CONFIG_GEN_RTC=y CONFIG_I2C_CHARDEV=m CONFIG_APM_POWER=y CONFIG_BATTERY_PMU=y @@ -201,8 +201,9 @@ CONFIG_HWMON=m CONFIG_AGP=m CONFIG_AGP_UNINORTH=m CONFIG_DRM=m -CONFIG_DRM_R128=m CONFIG_DRM_RADEON=m +CONFIG_DRM_LEGACY=y +CONFIG_DRM_R128=m CONFIG_FB=y CONFIG_FB_OF=y CONFIG_FB_CONTROL=y @@ -226,11 +227,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_DUMMY=m CONFIG_SND_POWERMAC=m CONFIG_SND_AOA=m @@ -300,8 +302,6 @@ CONFIG_NFSD_V4=y CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_ISO8859_1=m CONFIG_CRC_T10DIF=y -CONFIG_LIBCRC32C=m -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y @@ -310,7 +310,6 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_SHA512=m @@ -325,4 +324,3 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig index 0695ce047d565199e4501333fa41ece48cdf9e45..caee834760d2f32668b21efffe1190ab0d54183d 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -1,10 +1,8 @@ CONFIG_PPC64=y -CONFIG_SMP=y CONFIG_NR_CPUS=2048 CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_AUDIT=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_NO_HZ=y @@ -26,8 +24,8 @@ CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_BPF=y CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_BPF_SYSCALL=y @@ -62,7 +60,6 @@ CONFIG_PPC_64K_PAGES=y CONFIG_PPC_SUBPAGE_PROT=y CONFIG_SCHED_SMT=y CONFIG_PM=y -CONFIG_PCI_MSI=y CONFIG_HOTPLUG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -158,7 +155,6 @@ CONFIG_NETCONSOLE=y CONFIG_TUN=m CONFIG_VETH=m CONFIG_VIRTIO_NET=m -CONFIG_VHOST_NET=m CONFIG_VORTEX=m CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -184,16 +180,13 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y # CONFIG_SERIO_SERPORT is not set -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_JSM=m CONFIG_VIRTIO_CONSOLE=m -CONFIG_POWERNV_OP_PANEL=m CONFIG_IPMI_HANDLER=y CONFIG_IPMI_DEVICE_INTERFACE=y CONFIG_IPMI_POWERNV=y @@ -293,11 +286,15 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_LATENCYTOP=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_SCHED_TRACER=y +CONFIG_FTRACE_SYSCALLS=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_UPROBE_EVENT=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y @@ -309,6 +306,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CRC32C_VPMSUM=m CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m @@ -317,14 +315,13 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_DEV_NX=y CONFIG_CRYPTO_DEV_VMX=y -CONFIG_CRYPTO_DEV_VMX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=m +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig index 370c0bbcff71b25c26cff8a9a60122c20e5ec6ec..10fb1df63b4659b4ce93ca63730f2f68ce0451e1 100644 --- a/arch/powerpc/configs/ppc40x_defconfig +++ b/arch/powerpc/configs/ppc40x_defconfig @@ -51,9 +51,9 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_XILINX_HWICAP=m CONFIG_I2C=m @@ -85,4 +85,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 2766e8f590bc0108950c6c40add178413a673388..66dd6bf45cde3ce7f6d945dbd3b138ee139fb455 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -68,9 +68,9 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_XILINX_HWICAP=m CONFIG_I2C=m @@ -94,7 +94,6 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_UBIFS_FS=m -CONFIG_LOGFS=m CONFIG_CRAMFS=y CONFIG_SQUASHFS=m CONFIG_SQUASHFS_XATTR=y @@ -108,6 +107,5 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set CONFIG_VIRTUALIZATION=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 5175028c56ce74e3e50a2b30eabccf7b87ed8f0e..6ddca80c52c3b4c1fef2e1442a5c1d2a31f24e2e 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -1,8 +1,6 @@ CONFIG_PPC64=y -CONFIG_SMP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -28,9 +26,10 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y CONFIG_PPC_SPLPAR=y +CONFIG_DTL=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y -CONFIG_DTL=y +CONFIG_IBMEBUS=y CONFIG_PPC_MAPLE=y CONFIG_PPC_PASEMI=y CONFIG_PPC_PASEMI_IOMMU=y @@ -41,9 +40,8 @@ CONFIG_PS3_FLASH=m CONFIG_PS3_LPM=m CONFIG_PPC_IBM_CELL_BLADE=y CONFIG_RTAS_FLASH=m -CONFIG_IBMEBUS=y -CONFIG_CPU_FREQ_PMAC64=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_PMAC64=y CONFIG_HZ_100=y CONFIG_BINFMT_MISC=m CONFIG_PPC_TRANSACTIONAL_MEM=y @@ -51,14 +49,15 @@ CONFIG_KEXEC=y CONFIG_KEXEC_FILE=y CONFIG_CRASH_DUMP=y CONFIG_IRQ_ALL_CPUS=y -CONFIG_MEMORY_HOTREMOVE=y CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PPC_64K_PAGES=y CONFIG_SCHED_SMT=y -CONFIG_PCCARD=y -CONFIG_ELECTRA_CF=y CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m +CONFIG_PCCARD=y +CONFIG_ELECTRA_CF=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -154,7 +153,6 @@ CONFIG_DUMMY=m CONFIG_NETCONSOLE=y CONFIG_TUN=m CONFIG_VIRTIO_NET=m -CONFIG_VHOST_NET=m CONFIG_VORTEX=m CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -181,15 +179,14 @@ CONFIG_SUNGEM=y CONFIG_GELIC_NET=m CONFIG_GELIC_WIRELESS=y CONFIG_SPIDER_NET=m -CONFIG_MARVELL_PHY=y CONFIG_BROADCOM_PHY=m +CONFIG_MARVELL_PHY=y CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m @@ -197,7 +194,6 @@ CONFIG_INPUT_PCSPKR=m CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_ICOM=m -CONFIG_SERIAL_TXX9_CONSOLE=y CONFIG_SERIAL_JSM=m CONFIG_HVC_CONSOLE=y CONFIG_HVC_RTAS=y @@ -226,11 +222,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_POWERMAC=m CONFIG_SND_AOA=m CONFIG_SND_AOA_FABRIC_LAYOUT=m @@ -250,6 +247,9 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=m CONFIG_USB_APPLEDISPLAY=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m @@ -267,7 +267,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m -CONFIG_FS_DAX=y +CONFIG_RAS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -287,6 +287,7 @@ CONFIG_XFS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m +CONFIG_FS_DAX=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_OVERLAY_FS=m @@ -324,12 +325,15 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_DEBUG_MUTEXES=y CONFIG_LATENCYTOP=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_UPROBE_EVENT=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y @@ -342,6 +346,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CRC32C_VPMSUM=m CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m @@ -350,19 +355,14 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_NX=y CONFIG_CRYPTO_DEV_NX_ENCRYPT=m CONFIG_CRYPTO_DEV_VMX=y -CONFIG_CRYPTO_DEV_VMX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m -CONFIG_LEDS_POWERNV=m +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 6340e6c53c5446b5abb043ab1e185ab26ca650d9..41d85cb3c9a2fb65fae203654e0759dde8099080 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -3,7 +3,6 @@ CONFIG_PPC_BOOK3E_64=y CONFIG_SMP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_TASKSTATS=y @@ -30,8 +29,8 @@ CONFIG_BINFMT_MISC=m CONFIG_IRQ_ALL_CPUS=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_PCI_MSI=y -CONFIG_PCCARD=y CONFIG_HOTPLUG_PCI=y +CONFIG_PCCARD=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -108,15 +107,14 @@ CONFIG_E100=y CONFIG_E1000=y CONFIG_IXGB=m CONFIG_SUNGEM=y -CONFIG_MARVELL_PHY=y CONFIG_BROADCOM_PHY=m +CONFIG_MARVELL_PHY=y CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y # CONFIG_SERIO_SERPORT is not set @@ -143,11 +141,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_HID_DRAGONRISE=y CONFIG_HID_GYRATION=y CONFIG_HID_TWINHAN=y @@ -172,10 +171,8 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_ISER=m -CONFIG_EDAC=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -192,6 +189,7 @@ CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y CONFIG_XFS_FS=m CONFIG_XFS_POSIX_ACL=y +CONFIG_FS_DAX=y CONFIG_AUTOFS4_FS=m CONFIG_ISO9660_FS=y CONFIG_UDF_FS=m @@ -251,5 +249,4 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 18d0d60dadbf126fc10fcd40eb65edb2fa749775..da0e8d535eb8889efbd937a1d2ba62aac6236400 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -11,10 +11,10 @@ CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_CGROUPS=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y # CONFIG_COMPAT_BRK is not set @@ -61,7 +61,7 @@ CONFIG_SBC8641D=y CONFIG_MPC8610_HPCD=y CONFIG_GEF_SBC610=y CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m @@ -70,7 +70,6 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m CONFIG_CPU_FREQ_PMAC=y CONFIG_TAU=y CONFIG_TAU_AVERAGE=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_MCU_MPC8349EMITX=y CONFIG_HIGHMEM=y @@ -141,7 +140,6 @@ CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -187,7 +185,6 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m @@ -195,7 +192,6 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_NF_CONNTRACK_IPV4=m -# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -334,9 +330,7 @@ CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m @@ -370,7 +364,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_CDROM_PKTCDVD=m CONFIG_VIRTIO_BLK=m -CONFIG_BLK_DEV_HD=y CONFIG_ENCLOSURE_SERVICES=m CONFIG_SENSORS_TSL2550=m CONFIG_EEPROM_AT24=m @@ -548,16 +541,16 @@ CONFIG_PCMCIA_XIRC2PS=m CONFIG_FDDI=y CONFIG_SKFP=m CONFIG_NET_SB1000=m -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m CONFIG_BROADCOM_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_DAVICOM_PHY=m CONFIG_ICPLUS_PHY=m +CONFIG_LXT_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_VITESSE_PHY=m CONFIG_PLIP=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y @@ -585,7 +578,6 @@ CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y CONFIG_MOUSE_SERIAL=m @@ -647,7 +639,6 @@ CONFIG_SYNCLINKMP=m CONFIG_SYNCLINK_GT=m CONFIG_NOZOMI=m CONFIG_N_HDLC=m -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m @@ -657,13 +648,13 @@ CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=m CONFIG_SERIAL_PMACZILOG=m CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 CONFIG_SERIAL_JSM=m -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_PRINTER=m CONFIG_LP_CONSOLE=y CONFIG_PPDEV=m @@ -748,9 +739,10 @@ CONFIG_MFD_SM501_GPIO=y CONFIG_AGP=y CONFIG_AGP_UNINORTH=y CONFIG_DRM=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_LEGACY=y CONFIG_DRM_TDFX=m CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m CONFIG_DRM_VIA=m @@ -797,17 +789,18 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y CONFIG_SND_DEBUG_VERBOSE=y CONFIG_SND_PCM_XRUN_DEBUG=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_DUMMY=m CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m @@ -899,7 +892,7 @@ CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=m -CONFIG_USB_EHCI_FSL=y +CONFIG_USB_EHCI_FSL=m CONFIG_USB_OHCI_HCD=m CONFIG_USB_OHCI_HCD_PPC_OF_BE=y CONFIG_USB_OHCI_HCD_PPC_OF_LE=y @@ -967,7 +960,6 @@ CONFIG_USB_ADUTUX=m CONFIG_USB_SEVSEG=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m -CONFIG_USB_LED=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m @@ -1020,15 +1012,14 @@ CONFIG_UIO_CIF=m CONFIG_UIO_PDRV_GENIRQ=m CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m -CONFIG_FS_DAX=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=m CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT4_FS=m +CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_FS=y CONFIG_JBD2_DEBUG=y CONFIG_REISERFS_FS=m CONFIG_REISERFS_PROC_INFO=y @@ -1042,6 +1033,7 @@ CONFIG_XFS_FS=m CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_GFS2_FS=m +CONFIG_FS_DAX=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m @@ -1146,7 +1138,6 @@ CONFIG_DEBUG_VM=y CONFIG_DEBUG_HIGHMEM=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_SHIRQ=y -CONFIG_TIMER_STATS=y CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y @@ -1173,7 +1164,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m @@ -1201,7 +1191,6 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_HIFN_795X=m CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y CONFIG_CRYPTO_DEV_TALITOS=m diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig index 50b2bad51d0a71eb3e75c9341d0e0d7abf7a3935..0ededa8c837dc1399bff519c97e326413bcf5d2e 100644 --- a/arch/powerpc/configs/pq2fads_defconfig +++ b/arch/powerpc/configs/pq2fads_defconfig @@ -79,4 +79,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index ee0ec5a682fc16a9f30535ddaa3e8b54e6d49ef7..2efa025bf48369639e846ae12b2f5c1c86138bfa 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -5,7 +5,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -94,7 +93,6 @@ CONFIG_USB_USBNET=m # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set @@ -161,7 +159,6 @@ CONFIG_NLS_ISO8859_1=y CONFIG_CRC_CCITT=m CONFIG_CRC_T10DIF=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=y diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 1a61aa20dfbac9d5072ae83ef90640b8be380bd3..3d935969e5a268c9928b9cb8d98df108b88a49d1 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -1,11 +1,8 @@ CONFIG_PPC64=y -CONFIG_SMP=y CONFIG_NR_CPUS=2048 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -18,17 +15,16 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 CONFIG_NUMA_BALANCING=y -CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_BPF=y -CONFIG_MEMCG=y -CONFIG_MEMCG_SWAP=y CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_BPF=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_BPF_SYSCALL=y @@ -43,12 +39,12 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y CONFIG_PPC_SPLPAR=y +CONFIG_DTL=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y -CONFIG_DTL=y +CONFIG_IBMEBUS=y # CONFIG_PPC_PMAC is not set CONFIG_RTAS_FLASH=m -CONFIG_IBMEBUS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_HZ_100=y CONFIG_BINFMT_MISC=m @@ -155,7 +151,6 @@ CONFIG_NETCONSOLE=y CONFIG_TUN=m CONFIG_VETH=m CONFIG_VIRTIO_NET=m -CONFIG_VHOST_NET=m CONFIG_VORTEX=m CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -183,12 +178,10 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m # CONFIG_SERIO_SERPORT is not set -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_ICOM=m @@ -198,8 +191,6 @@ CONFIG_HVC_RTAS=y CONFIG_HVCS=m CONFIG_VIRTIO_CONSOLE=m CONFIG_IBM_BSR=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_GENERIC=y CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=1024 CONFIG_FB=y @@ -227,6 +218,9 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_HCD_PPC_OF is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m @@ -238,9 +232,10 @@ CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_CM=y CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_ISER=m +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=y CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -256,6 +251,7 @@ CONFIG_XFS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m +CONFIG_FS_DAX=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_OVERLAY_FS=m @@ -291,11 +287,14 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_LATENCYTOP=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_UPROBE_EVENT=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y @@ -306,6 +305,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CRC32C_VPMSUM=m CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m @@ -314,19 +314,14 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_NX=y CONFIG_CRYPTO_DEV_NX_ENCRYPT=m CONFIG_CRYPTO_DEV_VMX=y -CONFIG_CRYPTO_DEV_VMX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m -CONFIG_LEDS_POWERNV=m +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig index 78fddf24b5d3378feaee458097d1719efbd4c1a1..cd72193fac0a52c2f6af0ab56cabeb26759ea96c 100644 --- a/arch/powerpc/configs/tqm8xx_defconfig +++ b/arch/powerpc/configs/tqm8xx_defconfig @@ -18,6 +18,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_TQM8XX=y CONFIG_8xx_COPYBACK=y # CONFIG_8xx_CPU15 is not set +CONFIG_GEN_RTC=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -44,7 +45,6 @@ CONFIG_MTD_PHYSMAP_OF=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y CONFIG_DAVICOM_PHY=y -CONFIG_FIXED_PHY=y # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set @@ -53,7 +53,6 @@ CONFIG_FIXED_PHY=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig index dcdd51b577837353a8081478de215f8fc6caf22f..9c7400a19e9df2aca8b005bb658d802c48eb88af 100644 --- a/arch/powerpc/configs/wii_defconfig +++ b/arch/powerpc/configs/wii_defconfig @@ -55,9 +55,6 @@ CONFIG_B43_SDIO=y # CONFIG_B43_PHY_LP is not set CONFIG_B43_DEBUG=y CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -68,7 +65,6 @@ CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set CONFIG_LEGACY_PTY_COUNT=64 -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y CONFIG_I2C=y @@ -83,11 +79,12 @@ CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_SEQUENCER=y +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y # CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQUENCER_OSS=y CONFIG_HID_APPLE=m CONFIG_HID_WACOM=m CONFIG_MMC=y @@ -119,5 +116,4 @@ CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_DMA_API_DEBUG=y CONFIG_PPC_EARLY_DEBUG=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 5c4fbc80dc6ce683d278ce13174b770f337bcaa0..2542ea15d33841bba6a3b6a5c9bfa5a21390976f 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -8,3 +8,4 @@ generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += rwsem.h generic-y += vtime.h +generic-y += msi.h diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index cee3aa087653d805225db3e182857c0f5ac7adc9..7f2a7702596cd5a2a44c386431df1ad590acac86 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -25,7 +25,7 @@ #define PPC_LCMPI stringify_in_c(cmpdi) #define PPC_LCMPLI stringify_in_c(cmpldi) #define PPC_LCMP stringify_in_c(cmpd) -#define PPC_LONG stringify_in_c(.llong) +#define PPC_LONG stringify_in_c(.8byte) #define PPC_LONG_ALIGN stringify_in_c(.balign 8) #define PPC_TLNEI stringify_in_c(tdnei) #define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh) diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index 25d42bd3f1144c177110bb3235157d68b5b09583..9c601adfc50000dea26834f884cf4248952cee6e 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -74,13 +74,6 @@ do { \ ___p1; \ }) -/* - * This must resolve to hwsync on SMP for the context switch path. - * See _switch, and core scheduler context switch memory ordering - * comments. - */ -#define smp_mb__before_spinlock() smp_mb() - #include #endif /* _ASM_POWERPC_BARRIER_H */ diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 7fb7558804098d4e3033aebb073a65f5271e01d8..4d453f9795535edeee1b73bd1fb9351bc58cf3f3 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -294,13 +294,11 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 }) -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, - pmd_t **pmdp); - int map_kernel_page(unsigned long va, phys_addr_t pa, int flags); /* Generic accessors to PTE bits */ static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} +static inline int pte_read(pte_t pte) { return 1; } static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 36fc7bfe9e1140d1e5eabc781199851a6445d51a..f88452019114c2d75d78b4b8b05611a7761bb0c1 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -40,7 +40,7 @@ * Define the address range of the kernel non-linear virtual area */ #define H_KERN_VIRT_START ASM_CONST(0xD000000000000000) -#define H_KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) +#define H_KERN_VIRT_SIZE ASM_CONST(0x0000400000000000) /* 64T */ /* * The vmalloc space starts at the beginning of that region, and @@ -48,9 +48,11 @@ * (we keep a quarter for the virtual memmap) */ #define H_VMALLOC_START H_KERN_VIRT_START -#define H_VMALLOC_SIZE (H_KERN_VIRT_SIZE >> 1) +#define H_VMALLOC_SIZE ASM_CONST(0x380000000000) /* 56T */ #define H_VMALLOC_END (H_VMALLOC_START + H_VMALLOC_SIZE) +#define H_KERN_IO_START H_VMALLOC_END + /* * Region IDs */ diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h index 5c28bd6f2ae13f52fbbf79da538ece1de6600d3d..2d1ca488ca44e47a91e52bcd4cb2fbcf9159742a 100644 --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h @@ -54,9 +54,7 @@ static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, #ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE static inline bool gigantic_page_supported(void) { - if (radix_enabled()) - return true; - return false; + return true; } #endif diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 6981a52b3887079fe2b2870b1fcc78b17e909878..508275bb05d51b2908d7549acb71bc0978e901c8 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -104,6 +104,7 @@ #define HPTE_R_C ASM_CONST(0x0000000000000080) #define HPTE_R_R ASM_CONST(0x0000000000000100) #define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00) +#define HPTE_R_KEY (HPTE_R_KEY_LO | HPTE_R_KEY_HI) #define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000) #define HPTE_V_VRMA_MASK ASM_CONST(0x4001ffffff000000) @@ -468,7 +469,7 @@ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, int psize, int ssize); int htab_remove_mapping(unsigned long vstart, unsigned long vend, int psize, int ssize); -extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages); +extern void pseries_add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages); extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); #ifdef CONFIG_PPC_PSERIES diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 5b4023c616f7087d247d17509f170944b26f6a76..c3b00e8ff79103876b3368a5cf3b4d708c579bf8 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -83,6 +83,9 @@ typedef struct { mm_context_id_t id; u16 user_psize; /* page size index */ + /* Number of bits in the mm_cpumask */ + atomic_t active_cpus; + /* NPU NMMU context */ struct npu_context *npu_context; @@ -97,11 +100,6 @@ typedef struct { #ifdef CONFIG_PPC_SUBPAGE_PROT struct subpage_prot_table spt; #endif /* CONFIG_PPC_SUBPAGE_PROT */ -#ifdef CONFIG_PPC_ICSWX - struct spinlock *cop_lockp; /* guard acop and cop_pid */ - unsigned long acop; /* mask of enabled coprocessor types */ - unsigned int cop_pid; /* pid value used with coprocessors */ -#endif /* CONFIG_PPC_ICSWX */ #ifdef CONFIG_PPC_64K_PAGES /* for 4K PTE fragment support */ void *pte_frag; diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h index e2329db9d6f405fe1d32ebfb8f95035cf1ecedcd..1fcfa425cefaf205fe787cc9a480265aec758e0f 100644 --- a/arch/powerpc/include/asm/book3s/64/pgalloc.h +++ b/arch/powerpc/include/asm/book3s/64/pgalloc.h @@ -41,8 +41,6 @@ extern struct kmem_cache *pgtable_cache[]; pgtable_cache[(shift) - 1]; \ }) -#define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO - extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int); extern void pte_fragment_free(unsigned long *, int); extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift); diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index d1da415e283cd270d8d2d089508558d369c7cf98..b9aff515b4de28c10b3b2a040b140592efd1010e 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -272,8 +272,10 @@ extern unsigned long __vmalloc_end; extern unsigned long __kernel_virt_start; extern unsigned long __kernel_virt_size; +extern unsigned long __kernel_io_start; #define KERN_VIRT_START __kernel_virt_start #define KERN_VIRT_SIZE __kernel_virt_size +#define KERN_IO_START __kernel_io_start extern struct page *vmemmap; extern unsigned long ioremap_bot; extern unsigned long pci_io_base; @@ -298,7 +300,6 @@ extern unsigned long pci_io_base; * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE */ -#define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1)) #define FULL_IO_SIZE 0x80000000ul #define ISA_IO_BASE (KERN_IO_START) #define ISA_IO_END (KERN_IO_START + 0x10000ul) @@ -409,6 +410,11 @@ static inline int pte_write(pte_t pte) return __pte_write(pte) || pte_savedwrite(pte); } +static inline int pte_read(pte_t pte) +{ + return !!(pte_raw(pte) & cpu_to_be64(_PAGE_READ)); +} + #define __HAVE_ARCH_PTEP_SET_WRPROTECT static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -608,9 +614,17 @@ static inline pte_t pte_mkdevmap(pte_t pte) return __pte(pte_val(pte) | _PAGE_SPECIAL|_PAGE_DEVMAP); } +/* + * This is potentially called with a pmd as the argument, in which case it's not + * safe to check _PAGE_DEVMAP unless we also confirm that _PAGE_PTE is set. + * That's because the bit we use for _PAGE_DEVMAP is not reserved for software + * use in page directory entries (ie. non-ptes). + */ static inline int pte_devmap(pte_t pte) { - return !!(pte_raw(pte) & cpu_to_be64(_PAGE_DEVMAP)); + u64 mask = cpu_to_be64(_PAGE_DEVMAP | _PAGE_PTE); + + return (pte_raw(pte) & mask) == mask; } static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) @@ -1159,6 +1173,7 @@ static inline bool arch_needs_pgtable_deposit(void) return false; return true; } +extern void serialize_against_pte_lookup(struct mm_struct *mm); static inline pmd_t pmd_mkdevmap(pmd_t pmd) diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index 544440b5aff395c1d00076af87dec8b15628dd77..1e5ba94e62ef393ecf4be526d184aef4446dbc01 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -110,6 +110,8 @@ */ #define RADIX_VMEMMAP_BASE (RADIX_VMALLOC_END) +#define RADIX_KERN_IO_START (RADIX_KERN_VIRT_START + (RADIX_KERN_VIRT_SIZE >> 1)) + #ifndef __ASSEMBLY__ #define RADIX_PTE_TABLE_SIZE (sizeof(pte_t) << RADIX_PTE_INDEX_SIZE) #define RADIX_PMD_TABLE_SIZE (sizeof(pmd_t) << RADIX_PMD_INDEX_SIZE) diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h index cc7fbde4f53cac09b257f9a7ff4f1202af7c3c98..9b433a624bf3620d46cd97e6b8e563abce691169 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h @@ -22,22 +22,21 @@ extern void radix__flush_tlb_kernel_range(unsigned long start, unsigned long end extern void radix__local_flush_tlb_mm(struct mm_struct *mm); extern void radix__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -extern void radix__local_flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); extern void radix__local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize); extern void radix__tlb_flush(struct mmu_gather *tlb); #ifdef CONFIG_SMP extern void radix__flush_tlb_mm(struct mm_struct *mm); extern void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); extern void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize); #else #define radix__flush_tlb_mm(mm) radix__local_flush_tlb_mm(mm) #define radix__flush_tlb_page(vma,addr) radix__local_flush_tlb_page(vma,addr) #define radix__flush_tlb_page_psize(mm,addr,p) radix__local_flush_tlb_page_psize(mm,addr,p) -#define radix__flush_tlb_pwc(tlb, addr) radix__local_flush_tlb_pwc(tlb, addr) #endif +extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); +extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr); extern void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa, unsigned long page_size); extern void radix__flush_tlb_lpid(unsigned long lpid); diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 87fcc19488177e6e15b79e1a7e5487edabe4b408..7ee763d3bea95c03f66709347967e30503a0fb77 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -133,6 +133,7 @@ extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); extern void bad_page_fault(struct pt_regs *, unsigned long, int); extern void _exception(int, struct pt_regs *, int, unsigned long); extern void die(const char *, struct pt_regs *, long); +extern bool die_will_crash(void); #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 5a90292afbad1ea3681ac06aa9f6096cabf6ab5e..d122f7f957ce324a1ec046381d1c36afd15ca763 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -5,7 +5,7 @@ /* bytes per L1 cache line */ -#if defined(CONFIG_8xx) || defined(CONFIG_403GCX) +#if defined(CONFIG_PPC_8xx) || defined(CONFIG_403GCX) #define L1_CACHE_SHIFT 4 #define MAX_COPY_PREFETCH 1 #elif defined(CONFIG_PPC_E500MC) diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h index 52586f9956bbf9a4ccc0b53bd79c178e975bc341..eb43b5c3a7b57f471c4a112cf7bf66d820809d9e 100644 --- a/arch/powerpc/include/asm/cpuidle.h +++ b/arch/powerpc/include/asm/cpuidle.h @@ -67,6 +67,17 @@ #define ERR_DEEP_STATE_ESL_MISMATCH -2 #ifndef __ASSEMBLY__ +/* Additional SPRs that need to be saved/restored during stop */ +struct stop_sprs { + u64 pid; + u64 ldbar; + u64 fscr; + u64 hfscr; + u64 mmcr1; + u64 mmcr2; + u64 mmcra; +}; + extern u32 pnv_fastsleep_workaround_at_entry[]; extern u32 pnv_fastsleep_workaround_at_exit[]; @@ -90,20 +101,4 @@ static inline void report_invalid_psscr_val(u64 psscr_val, int err) #endif -/* Idle state entry routines */ -#ifdef CONFIG_PPC_P7_NAP -#define IDLE_STATE_ENTER_SEQ(IDLE_INST) \ - /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ - std r0,0(r1); \ - ptesync; \ - ld r0,0(r1); \ -236: cmpd cr0,r0,r0; \ - bne 236b; \ - IDLE_INST; \ - -#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ - IDLE_STATE_ENTER_SEQ(IDLE_INST) \ - b . -#endif /* CONFIG_PPC_P7_NAP */ - #endif diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index d02ad93bf70892f8d342b9d8890a4e1b8065eed6..a9bf921f4efcdef13afa48dd52378771855a4e8f 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -513,7 +513,7 @@ enum { #else CPU_FTRS_GENERIC_32 | #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx CPU_FTRS_8XX | #endif #ifdef CONFIG_40x @@ -565,7 +565,7 @@ enum { #else CPU_FTRS_GENERIC_32 & #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx CPU_FTRS_8XX & #endif #ifdef CONFIG_40x diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 8e37b71674f4acdfa530ce5517dcf262e20bb644..9847ae3a12d178bc081c4d1916c0c036acdb1a78 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -131,7 +131,6 @@ static inline bool eeh_pe_passed(struct eeh_pe *pe) struct eeh_dev { int mode; /* EEH mode */ int class_code; /* Class code of the device */ - int config_addr; /* Config address */ int pe_config_addr; /* PE config address */ u32 config_space[16]; /* Saved PCI config space */ int pcix_cap; /* Saved PCIx capability */ @@ -141,7 +140,6 @@ struct eeh_dev { struct eeh_pe *pe; /* Associated PE */ struct list_head list; /* Form link list in the PE */ struct list_head rmv_list; /* Record the removed edevs */ - struct pci_controller *phb; /* Associated PHB */ struct pci_dn *pdn; /* Associated PCI device node */ struct pci_dev *pdev; /* Associated PCI device */ bool in_error; /* Error flag for edev */ @@ -262,7 +260,8 @@ typedef void *(*eeh_traverse_func)(void *data, void *flag); void eeh_set_pe_aux_size(int size); int eeh_phb_pe_create(struct pci_controller *phb); struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb); -struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); +struct eeh_pe *eeh_pe_get(struct pci_controller *phb, + int pe_no, int config_addr); int eeh_add_to_parent_pe(struct eeh_dev *edev); int eeh_rmv_from_parent_pe(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h index ce88bbe1d809ea038db3c9dacbacea30fcad4f0e..5a23010af600337b89887cab179cf2e9b1b385b0 100644 --- a/arch/powerpc/include/asm/fadump.h +++ b/arch/powerpc/include/asm/fadump.h @@ -209,11 +209,13 @@ extern int early_init_dt_scan_fw_dump(unsigned long node, extern int fadump_reserve_mem(void); extern int setup_fadump(void); extern int is_fadump_active(void); +extern int should_fadump_crash(void); extern void crash_fadump(struct pt_regs *, const char *); extern void fadump_cleanup(void); #else /* CONFIG_FA_DUMP */ static inline int is_fadump_active(void) { return 0; } +static inline int should_fadump_crash(void) { return 0; } static inline void crash_fadump(struct pt_regs *regs, const char *str) { } #endif #endif diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index 2de2319b99e2c6a69991df5de988cc02c9abb3aa..8f88f771cc55ce982c11599b273e584babd38600 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h @@ -19,11 +19,11 @@ */ #if defined(CONFIG_PPC64) && !defined(__powerpc64__) /* 64 bits kernel, 32 bits code (ie. vdso32) */ -#define FTR_ENTRY_LONG .llong +#define FTR_ENTRY_LONG .8byte #define FTR_ENTRY_OFFSET .long 0xffffffff; .long #elif defined(CONFIG_PPC64) -#define FTR_ENTRY_LONG .llong -#define FTR_ENTRY_OFFSET .llong +#define FTR_ENTRY_LONG .8byte +#define FTR_ENTRY_OFFSET .8byte #else #define FTR_ENTRY_LONG .long #define FTR_ENTRY_OFFSET .long diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h index 4508b322f2cde2f0b7b823f8e3b2738102529f30..6c40dfda59126d59cd3de2fe4c328273841cc350 100644 --- a/arch/powerpc/include/asm/fixmap.h +++ b/arch/powerpc/include/asm/fixmap.h @@ -17,6 +17,7 @@ #ifndef __ASSEMBLY__ #include #include +#include #ifdef CONFIG_HIGHMEM #include #include @@ -62,9 +63,6 @@ enum fixed_addresses { __end_of_fixed_addresses }; -extern void __set_fixmap (enum fixed_addresses idx, - phys_addr_t phys, pgprot_t flags); - #define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) @@ -72,5 +70,11 @@ extern void __set_fixmap (enum fixed_addresses idx, #include +static inline void __set_fixmap(enum fixed_addresses idx, + phys_addr_t phys, pgprot_t flags) +{ + map_kernel_page(fix_to_virt(idx), phys, pgprot_val(flags)); +} + #endif /* !__ASSEMBLY__ */ #endif diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h index f79d6c74eb2a0e9e63a3d35e8e2ce147c165c382..8def56ec05c6075afd8567c6c5117c5c2d334288 100644 --- a/arch/powerpc/include/asm/fs_pd.h +++ b/arch/powerpc/include/asm/fs_pd.h @@ -26,7 +26,7 @@ #define cpm2_unmap(addr) do {} while(0) #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx #include extern immap_t __iomem *mpc8xx_immr; diff --git a/arch/powerpc/include/asm/futex.h b/arch/powerpc/include/asm/futex.h index eaada6c923443cf412b66a5e3a0319beb68ce92b..719ed9b61ea7ec5b8cbf527fd4c06181c3f1756c 100644 --- a/arch/powerpc/include/asm/futex.h +++ b/arch/powerpc/include/asm/futex.h @@ -29,18 +29,10 @@ : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ : "cr0", "memory") -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -66,17 +58,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h index 8add8b861e8d76de6657838d3fd62fec66c97f97..c97603d617e366d1b55a9a780615f3ad3f68873c 100644 --- a/arch/powerpc/include/asm/hardirq.h +++ b/arch/powerpc/include/asm/hardirq.h @@ -12,6 +12,10 @@ typedef struct { unsigned int mce_exceptions; unsigned int spurious_irqs; unsigned int hmi_exceptions; + unsigned int sreset_irqs; +#ifdef CONFIG_PPC_WATCHDOG + unsigned int soft_nmi_irqs; +#endif #ifdef CONFIG_PPC_DOORBELL unsigned int doorbell_irqs; #endif diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 7f4025a6c69ea5b71b340989b35197d8f9d17b91..b8a0fb442c6487ef70afcbd7209206606293a1ad 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -218,18 +218,4 @@ static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr, } #endif /* CONFIG_HUGETLB_PAGE */ -/* - * FSL Book3E platforms require special gpage handling - the gpages - * are reserved early in the boot process by memblock instead of via - * the .dts as on IBM platforms. - */ -#if defined(CONFIG_HUGETLB_PAGE) && (defined(CONFIG_PPC_FSL_BOOK3E) || \ - defined(CONFIG_PPC_8xx)) -extern void __init reserve_hugetlb_gpages(void); -#else -static inline void reserve_hugetlb_gpages(void) -{ -} -#endif - #endif /* _ASM_POWERPC_HUGETLB_H */ diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 57d38b504ff773facfeaee601cd5bab8e2d9796c..3d34dc0869f687a731ed97ad42eb4c47c579f11b 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -280,7 +280,18 @@ #define H_RESIZE_HPT_COMMIT 0x370 #define H_REGISTER_PROC_TBL 0x37C #define H_SIGNAL_SYS_RESET 0x380 -#define MAX_HCALL_OPCODE H_SIGNAL_SYS_RESET +#define H_INT_GET_SOURCE_INFO 0x3A8 +#define H_INT_SET_SOURCE_CONFIG 0x3AC +#define H_INT_GET_SOURCE_CONFIG 0x3B0 +#define H_INT_GET_QUEUE_INFO 0x3B4 +#define H_INT_SET_QUEUE_CONFIG 0x3B8 +#define H_INT_GET_QUEUE_CONFIG 0x3BC +#define H_INT_SET_OS_REPORTING_LINE 0x3C0 +#define H_INT_GET_OS_REPORTING_LINE 0x3C4 +#define H_INT_ESB 0x3C8 +#define H_INT_SYNC 0x3CC +#define H_INT_RESET 0x3D0 +#define MAX_HCALL_OPCODE H_INT_RESET /* H_VIOCTL functions */ #define H_GET_VIOA_DUMP_SIZE 0x01 diff --git a/arch/powerpc/include/asm/icswx.h b/arch/powerpc/include/asm/icswx.h index 27e588f6c72eec75b1a4f2644272ac16ebd4d7dd..6a2c875775419b523cd1edbb53205e042cdcccfa 100644 --- a/arch/powerpc/include/asm/icswx.h +++ b/arch/powerpc/include/asm/icswx.h @@ -69,7 +69,10 @@ struct coprocessor_completion_block { #define CSB_CC_WR_PROTECTION (16) #define CSB_CC_UNKNOWN_CODE (17) #define CSB_CC_ABORT (18) +#define CSB_CC_EXCEED_BYTE_COUNT (19) /* P9 or later */ #define CSB_CC_TRANSPORT (20) +#define CSB_CC_INVALID_CRB (21) /* P9 or later */ +#define CSB_CC_INVALID_DDE (30) /* P9 or later */ #define CSB_CC_SEGMENTED_DDL (31) #define CSB_CC_PROGRESS_POINT (32) #define CSB_CC_DDE_OVERFLOW (33) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h new file mode 100644 index 0000000000000000000000000000000000000000..7f74c282710f4c232c873119ebd2118c2307eb29 --- /dev/null +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -0,0 +1,128 @@ +#ifndef __ASM_POWERPC_IMC_PMU_H +#define __ASM_POWERPC_IMC_PMU_H + +/* + * IMC Nest Performance Monitor counter support. + * + * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation. + * (C) 2017 Anju T Sudhakar, IBM Corporation. + * (C) 2017 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or later version. + */ + +#include +#include +#include +#include +#include + +/* + * For static allocation of some of the structures. + */ +#define IMC_MAX_PMUS 32 + +/* + * Compatibility macros for IMC devices + */ +#define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" +#define IMC_DTB_UNIT_COMPAT "ibm,imc-counters" + + +/* + * LDBAR: Counter address and Enable/Disable macro. + * perf/imc-pmu.c has the LDBAR layout information. + */ +#define THREAD_IMC_LDBAR_MASK 0x0003ffffffffe000ULL +#define THREAD_IMC_ENABLE 0x8000000000000000ULL + +/* + * Structure to hold memory address information for imc units. + */ +struct imc_mem_info { + u64 *vbase; + u32 id; +}; + +/* + * Place holder for nest pmu events and values. + */ +struct imc_events { + u32 value; + char *name; + char *unit; + char *scale; +}; + +/* Event attribute array index */ +#define IMC_FORMAT_ATTR 0 +#define IMC_EVENT_ATTR 1 +#define IMC_CPUMASK_ATTR 2 +#define IMC_NULL_ATTR 3 + +/* PMU Format attribute macros */ +#define IMC_EVENT_OFFSET_MASK 0xffffffffULL + +/* + * Device tree parser code detects IMC pmu support and + * registers new IMC pmus. This structure will hold the + * pmu functions, events, counter memory information + * and attrs for each imc pmu and will be referenced at + * the time of pmu registration. + */ +struct imc_pmu { + struct pmu pmu; + struct imc_mem_info *mem_info; + struct imc_events **events; + /* + * Attribute groups for the PMU. Slot 0 used for + * format attribute, slot 1 used for cpusmask attribute, + * slot 2 used for event attribute. Slot 3 keep as + * NULL. + */ + const struct attribute_group *attr_groups[4]; + u32 counter_mem_size; + int domain; + /* + * flag to notify whether the memory is mmaped + * or allocated by kernel. + */ + bool imc_counter_mmaped; +}; + +/* + * Structure to hold id, lock and reference count for the imc events which + * are inited. + */ +struct imc_pmu_ref { + struct mutex lock; + unsigned int id; + int refc; +}; + +/* + * In-Memory Collection Counters type. + * Data comes from Device tree. + * Three device type are supported. + */ + +enum { + IMC_TYPE_THREAD = 0x1, + IMC_TYPE_CORE = 0x4, + IMC_TYPE_CHIP = 0x10, +}; + +/* + * Domains for IMC PMUs + */ +#define IMC_DOMAIN_NEST 1 +#define IMC_DOMAIN_CORE 2 +#define IMC_DOMAIN_THREAD 3 + +extern int init_imc_pmu(struct device_node *parent, + struct imc_pmu *pmu_ptr, int pmu_id); +extern void thread_imc_disable(void); +#endif /* __ASM_POWERPC_IMC_PMU_H */ diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index 7cea76f11c26c66fc52e08aae5b37e6534ac79a8..83596f32f50b49672d7ced5f3ee806c921406114 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -104,6 +104,10 @@ struct kvmppc_host_state { u8 napping; #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + /* + * hwthread_req/hwthread_state pair is used to pull sibling threads + * out of guest on pre-ISAv3.0B CPUs where threads share MMU. + */ u8 hwthread_req; u8 hwthread_state; u8 host_ipi; diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 8b3f1238d07f18eda49eb9326934427cf2d83736..e372ed871c513b00e78f69898601c598ee5a026b 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -67,11 +67,6 @@ extern int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); -static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, - unsigned long address) -{ -} - #define HPTEG_CACHE_NUM (1 << 15) #define HPTEG_HASH_BITS_PTE 13 #define HPTEG_HASH_BITS_PTE_LONG 12 diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index cd2fc1cc1cc7c056255b6f49effefb1e6d0cc1e6..73b92017b6d7b5231cd8c9d46b7986bb9131f12c 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -76,7 +76,6 @@ struct machdep_calls { void __noreturn (*restart)(char *cmd); void __noreturn (*halt)(void); - void (*panic)(char *str); void (*cpu_die)(void); long (*time_init)(void); /* Optional, may be NULL */ diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 0c76675394c5930d5cecf2ac01a2718c8e9b6c1f..309592589e301c2258d3cb1b9cfdca213c9cc23e 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -77,58 +77,8 @@ extern void switch_cop(struct mm_struct *next); extern int use_cop(unsigned long acop, struct mm_struct *mm); extern void drop_cop(unsigned long acop, struct mm_struct *mm); -/* - * switch_mm is the entry point called from the architecture independent - * code in kernel/sched/core.c - */ -static inline void switch_mm_irqs_off(struct mm_struct *prev, - struct mm_struct *next, - struct task_struct *tsk) -{ - bool new_on_cpu = false; - - /* Mark this context has been used on the new CPU */ - if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) { - cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); - new_on_cpu = true; - } - - /* 32-bit keeps track of the current PGDIR in the thread struct */ -#ifdef CONFIG_PPC32 - tsk->thread.pgdir = next->pgd; -#endif /* CONFIG_PPC32 */ - - /* 64-bit Book3E keeps track of current PGD in the PACA */ -#ifdef CONFIG_PPC_BOOK3E_64 - get_paca()->pgd = next->pgd; -#endif - /* Nothing else to do if we aren't actually switching */ - if (prev == next) - return; - -#ifdef CONFIG_PPC_ICSWX - /* Switch coprocessor context only if prev or next uses a coprocessor */ - if (prev->context.acop || next->context.acop) - switch_cop(next); -#endif /* CONFIG_PPC_ICSWX */ - - /* We must stop all altivec streams before changing the HW - * context - */ -#ifdef CONFIG_ALTIVEC - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - asm volatile ("dssall"); -#endif /* CONFIG_ALTIVEC */ - - if (new_on_cpu) - radix_kvm_prefetch_workaround(next); - - /* - * The actual HW switching method differs between the various - * sub architectures. Out of line for now - */ - switch_mmu_context(prev, next, tsk); -} +extern void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk); static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) @@ -150,11 +100,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, */ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { - unsigned long flags; - - local_irq_save(flags); switch_mm(prev, next, current); - local_irq_restore(flags); } /* We don't currently use enter_lazy_tlb() for anything */ diff --git a/arch/powerpc/include/asm/nmi.h b/arch/powerpc/include/asm/nmi.h index 6f8e79cd35d87f9eababcbbbba23c3d7f0f98f87..3760150a0ff0fb6964c709be983385bf48bdaecd 100644 --- a/arch/powerpc/include/asm/nmi.h +++ b/arch/powerpc/include/asm/nmi.h @@ -1,9 +1,8 @@ #ifndef _ASM_NMI_H #define _ASM_NMI_H -#ifdef CONFIG_HARDLOCKUP_DETECTOR +#ifdef CONFIG_PPC_WATCHDOG extern void arch_touch_nmi_watchdog(void); - extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self); #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index 91314268f04f983e0b56130a90ac57d30ea65863..185c6a47f9bad440861d38d4842614286df5318b 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -121,7 +121,7 @@ extern int icache_44x_need_flush; #include #elif defined(CONFIG_FSL_BOOKE) #include -#elif defined(CONFIG_8xx) +#elif defined(CONFIG_PPC_8xx) #include #endif @@ -337,9 +337,6 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 }) -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, - pmd_t **pmdp); - int map_kernel_page(unsigned long va, phys_addr_t pa, int flags); #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index e5805ad78e127ba456ba305abf09d30fdc38c5f4..17989c3d9a24fdfb5835206d9833d26eb8a95864 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -14,6 +14,7 @@ static inline int pte_write(pte_t pte) { return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; } +static inline int pte_read(pte_t pte) { return 1; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 3130a73652c70ac6bb89747b1e906b6b853f6aee..450a60b81d2a6ecfbb0ea92f4f7625ed498a26ff 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -42,6 +42,7 @@ #define OPAL_I2C_STOP_ERR -24 #define OPAL_XIVE_PROVISIONING -31 #define OPAL_XIVE_FREE_ACTIVE -32 +#define OPAL_TIMEOUT -33 /* API Tokens (in r0) */ #define OPAL_INVALID_CALL -1 @@ -190,7 +191,16 @@ #define OPAL_NPU_INIT_CONTEXT 146 #define OPAL_NPU_DESTROY_CONTEXT 147 #define OPAL_NPU_MAP_LPAR 148 -#define OPAL_LAST 148 +#define OPAL_IMC_COUNTERS_INIT 149 +#define OPAL_IMC_COUNTERS_START 150 +#define OPAL_IMC_COUNTERS_STOP 151 +#define OPAL_GET_POWERCAP 152 +#define OPAL_SET_POWERCAP 153 +#define OPAL_GET_POWER_SHIFT_RATIO 154 +#define OPAL_SET_POWER_SHIFT_RATIO 155 +#define OPAL_SENSOR_GROUP_CLEAR 156 +#define OPAL_PCI_SET_P2P 157 +#define OPAL_LAST 157 /* Device tree flags */ @@ -1084,6 +1094,18 @@ enum { XIVE_DUMP_EMU_STATE = 5, }; +/* "type" argument options for OPAL_IMC_COUNTERS_* calls */ +enum { + OPAL_IMC_COUNTERS_NEST = 1, + OPAL_IMC_COUNTERS_CORE = 2, +}; + + +/* PCI p2p descriptor */ +#define OPAL_PCI_P2P_ENABLE 0x1 +#define OPAL_PCI_P2P_LOAD 0x2 +#define OPAL_PCI_P2P_STORE 0x4 + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 588fb1c23af915cc6bf258947c611945d6d3551e..726c23304a5706ea806a0ea08c3f68c088042d06 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -50,7 +50,7 @@ int64_t opal_tpo_write(uint64_t token, uint32_t year_mon_day, uint32_t hour_min); int64_t opal_cec_power_down(uint64_t request); int64_t opal_cec_reboot(void); -int64_t opal_cec_reboot2(uint32_t reboot_type, char *diag); +int64_t opal_cec_reboot2(uint32_t reboot_type, const char *diag); int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_handle_interrupt(uint64_t isn, __be64 *outstanding_event_mask); @@ -267,6 +267,19 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id); int64_t opal_xive_free_irq(uint32_t girq); int64_t opal_xive_sync(uint32_t type, uint32_t id); int64_t opal_xive_dump(uint32_t type, uint32_t id); +int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target, + uint64_t desc, uint16_t pe_number); + +int64_t opal_imc_counters_init(uint32_t type, uint64_t address, + uint64_t cpu_pir); +int64_t opal_imc_counters_start(uint32_t type, uint64_t cpu_pir); +int64_t opal_imc_counters_stop(uint32_t type, uint64_t cpu_pir); + +int opal_get_powercap(u32 handle, int token, u32 *pcap); +int opal_set_powercap(u32 handle, int token, u32 pcap); +int opal_get_power_shift_ratio(u32 handle, int token, u32 *psr); +int opal_set_power_shift_ratio(u32 handle, int token, u32 psr); +int opal_sensor_group_clear(u32 group_hndl, int token); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, @@ -345,6 +358,10 @@ static inline int opal_get_async_rc(struct opal_msg msg) void opal_wake_poller(void); +void opal_powercap_init(void); +void opal_psr_init(void); +void opal_sensor_groups_init(void); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_OPAL_H */ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index dc88a31cc79ac7f8e2c47525ddebea6f280dc3ed..04b60af027ae3bfcf56e2aade2879ba50471c1c4 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -31,6 +31,7 @@ #endif #include #include +#include register struct paca_struct *local_paca asm("r13"); @@ -183,6 +184,12 @@ struct paca_struct { struct paca_struct **thread_sibling_pacas; /* The PSSCR value that the kernel requested before going to stop */ u64 requested_psscr; + + /* + * Save area for additional SPRs that need to be + * saved/restored during cpuidle stop. + */ + struct stop_sprs stop_sprs; #endif #ifdef CONFIG_PPC_STD_MMU_64 diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 56c67d3f010842b6dc4dc9a56e6d61459ff35c62..0b8aa1fe2d5f5dbc7b7dc96dfda5ab20c9de9971 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -195,7 +195,6 @@ struct pci_dn { struct pci_dn *parent; struct pci_controller *phb; /* for pci devices */ struct iommu_table_group *table_group; /* for phb's or bridges */ - struct device_node *node; /* back-pointer to the device_node */ int pci_ext_config_space; /* for pci devices */ diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h index d795c5d5789cfddc584bd1a75c8e71e6e29155cf..45ae1212ab8a965cf057062677f6ea429188bd55 100644 --- a/arch/powerpc/include/asm/pgalloc.h +++ b/arch/powerpc/include/asm/pgalloc.h @@ -17,6 +17,8 @@ static inline gfp_t pgtable_gfp_flags(struct mm_struct *mm, gfp_t gfp) } #endif /* MODULE */ +#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) + #ifdef CONFIG_PPC_BOOK3S #include #else diff --git a/arch/powerpc/include/asm/pgtable-be-types.h b/arch/powerpc/include/asm/pgtable-be-types.h index 9c0f5db5cf461a92e72185701b4cbc1df168dfcc..67e7e3d990f44ef495ee02b6fcb3ba16053bd5c5 100644 --- a/arch/powerpc/include/asm/pgtable-be-types.h +++ b/arch/powerpc/include/asm/pgtable-be-types.h @@ -87,6 +87,7 @@ static inline bool pte_xchg(pte_t *ptep, pte_t old, pte_t new) unsigned long *p = (unsigned long *)ptep; __be64 prev; + /* See comment in switch_mm_irqs_off() */ prev = (__force __be64)__cmpxchg_u64(p, (__force unsigned long)pte_raw(old), (__force unsigned long)pte_raw(new)); diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h index 8bd3b13fe2fb2e8bd1c5762c4e080c9cd921edaa..369a164b545c09087e0740fd6c32ea282a7b5245 100644 --- a/arch/powerpc/include/asm/pgtable-types.h +++ b/arch/powerpc/include/asm/pgtable-types.h @@ -62,6 +62,7 @@ static inline bool pte_xchg(pte_t *ptep, pte_t old, pte_t new) { unsigned long *p = (unsigned long *)ptep; + /* See comment in switch_mm_irqs_off() */ return pte_val(old) == __cmpxchg_u64(p, pte_val(old), pte_val(new)); } #endif diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index afae9a336136a4916c9912d3fd7f8c8f268406f2..7d0d38f5824376fe0c6047443afe90e59a64acf9 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -66,22 +66,14 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, #ifndef CONFIG_TRANSPARENT_HUGEPAGE #define pmd_large(pmd) 0 #endif -pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, - bool *is_thp, unsigned *shift); -static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, - bool *is_thp, unsigned *shift) -{ - VM_WARN(!arch_irqs_disabled(), - "%s called with irq enabled\n", __func__); - return __find_linux_pte_or_hugepte(pgdir, ea, is_thp, shift); -} +/* can we use this in kvm */ unsigned long vmalloc_to_phys(void *vmalloc_addr); void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); void pgtable_cache_init(void); -#ifdef CONFIG_STRICT_KERNEL_RWX +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_PPC32) void mark_initmem_nx(void); #else static inline void mark_initmem_nx(void) { } diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index de9681034353c661d3e0a6299c3c6b7c3573b832..3e5cf251ad9ad7da490ce0da39261a6f035614d6 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -26,6 +26,8 @@ extern int pnv_pci_get_presence_state(uint64_t id, uint8_t *state); extern int pnv_pci_get_power_state(uint64_t id, uint8_t *state); extern int pnv_pci_set_power_state(uint64_t id, uint8_t state, struct opal_msg *msg); +extern int pnv_pci_set_p2p(struct pci_dev *initiator, struct pci_dev *target, + u64 desc); int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode); int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index fa9ebaead91e575579b4d27a2df54d6bab19c356..ce0930d68857c64b8f7c55e85df9028293f71ebd 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -193,6 +193,7 @@ #define PPC_INST_CLRBHRB 0x7c00035c #define PPC_INST_COPY 0x7c20060c #define PPC_INST_CP_ABORT 0x7c00068c +#define PPC_INST_DARN 0x7c0005e6 #define PPC_INST_DCBA 0x7c0005ec #define PPC_INST_DCBA_MASK 0xfc0007fe #define PPC_INST_DCBAL 0x7c2005ec @@ -204,6 +205,8 @@ #define PPC_INST_ISEL_MASK 0xfc00003e #define PPC_INST_LDARX 0x7c0000a8 #define PPC_INST_STDCX 0x7c0001ad +#define PPC_INST_LQARX 0x7c000228 +#define PPC_INST_STQCX 0x7c00016d #define PPC_INST_LSWI 0x7c0004aa #define PPC_INST_LSWX 0x7c00042a #define PPC_INST_LWARX 0x7c000028 @@ -261,7 +264,7 @@ #define PPC_INST_TLBSRX_DOT 0x7c0006a5 #define PPC_INST_VPMSUMW 0x10000488 #define PPC_INST_VPMSUMD 0x100004c8 -#define PPC_INST_XXLOR 0xf0000510 +#define PPC_INST_XXLOR 0xf0000490 #define PPC_INST_XXSWAPD 0xf0000250 #define PPC_INST_XVCPSGNDP 0xf0000780 #define PPC_INST_TRECHKPT 0x7c0007dd @@ -395,16 +398,25 @@ #define PPC_CP_ABORT stringify_in_c(.long PPC_INST_CP_ABORT) #define PPC_COPY(a, b) stringify_in_c(.long PPC_INST_COPY | \ ___PPC_RA(a) | ___PPC_RB(b)) +#define PPC_DARN(t, l) stringify_in_c(.long PPC_INST_DARN | \ + ___PPC_RT(t) | \ + (((l) & 0x3) << 16)) #define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ __PPC_RA(a) | __PPC_RB(b)) #define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \ __PPC_RA(a) | __PPC_RB(b)) +#define PPC_LQARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LQARX | \ + ___PPC_RT(t) | ___PPC_RA(a) | \ + ___PPC_RB(b) | __PPC_EH(eh)) #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \ ___PPC_RT(t) | ___PPC_RA(a) | \ ___PPC_RB(b) | __PPC_EH(eh)) #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \ ___PPC_RT(t) | ___PPC_RA(a) | \ ___PPC_RB(b) | __PPC_EH(eh)) +#define PPC_STQCX(t, a, b) stringify_in_c(.long PPC_INST_STQCX | \ + ___PPC_RT(t) | ___PPC_RA(a) | \ + ___PPC_RB(b)) #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ ___PPC_RB(b)) #define PPC_MSGSYNC stringify_in_c(.long PPC_INST_MSGSYNC) @@ -414,6 +426,8 @@ ___PPC_RB(b)) #define PPC_MSGCLRP(b) stringify_in_c(.long PPC_INST_MSGCLRP | \ ___PPC_RB(b)) +#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \ + ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ __PPC_RA(a) | __PPC_RS(s)) #define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \ diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 6baeeb9acd0d6efdcf19f07075668a42f30c8c40..36f3e41c9fbeabc8ed949b2cc6590848ca370dd2 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -378,10 +378,16 @@ BEGIN_FTR_SECTION_NESTED(96); \ cmpwi dest,0; \ beq- 90b; \ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) -#elif defined(CONFIG_8xx) -#define MFTB(dest) mftb dest #else -#define MFTB(dest) mfspr dest, SPRN_TBRL +#define MFTB(dest) MFTBL(dest) +#endif + +#ifdef CONFIG_PPC_8xx +#define MFTBL(dest) mftb dest +#define MFTBU(dest) mftbu dest +#else +#define MFTBL(dest) mfspr dest, SPRN_TBRL +#define MFTBU(dest) mfspr dest, SPRN_TBRU #endif #ifndef CONFIG_SMP @@ -411,7 +417,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) * and they must be used. */ -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) +#if !defined(CONFIG_4xx) && !defined(CONFIG_PPC_8xx) #define tlbia \ li r4,1024; \ mtctr r4; \ @@ -439,7 +445,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) .machine push ; \ .machine "power4" ; \ lis scratch,0x60000000@h; \ - dcbt r0,scratch,0b01010; \ + dcbt 0,scratch,0b01010; \ .machine pop /* diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 35c00d7a0cf81a4773d0fad7dc2747923cd2c643..825bd5998701c7ff8123c9b5f1dd1d0abaaed9dd 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -159,7 +159,10 @@ struct of_drconf_cell { #define OV5_PFO_HW_842 0x1140 /* PFO Compression Accelerator */ #define OV5_PFO_HW_ENCR 0x1120 /* PFO Encryption Accelerator */ #define OV5_SUB_PROCESSORS 0x1501 /* 1,2,or 4 Sub-Processors supported */ -#define OV5_XIVE_EXPLOIT 0x1701 /* XIVE exploitation supported */ +#define OV5_XIVE_SUPPORT 0x17C0 /* XIVE Exploitation Support Mask */ +#define OV5_XIVE_LEGACY 0x1700 /* XIVE legacy mode Only */ +#define OV5_XIVE_EXPLOIT 0x1740 /* XIVE exploitation mode Only */ +#define OV5_XIVE_EITHER 0x1780 /* XIVE legacy or exploitation mode */ /* MMU Base Architecture */ #define OV5_MMU_SUPPORT 0x18C0 /* MMU Mode Support Mask */ #define OV5_MMU_HASH 0x1800 /* Hash MMU Only */ diff --git a/arch/powerpc/include/asm/pte-walk.h b/arch/powerpc/include/asm/pte-walk.h new file mode 100644 index 0000000000000000000000000000000000000000..2d633e9d686c4f9d3b4ea39ebd160d93806467a7 --- /dev/null +++ b/arch/powerpc/include/asm/pte-walk.h @@ -0,0 +1,35 @@ +#ifndef _ASM_POWERPC_PTE_WALK_H +#define _ASM_POWERPC_PTE_WALK_H + +#include + +/* Don't use this directly */ +extern pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hshift); + +static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hshift) +{ + VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__); + return __find_linux_pte(pgdir, ea, is_thp, hshift); +} + +static inline pte_t *find_init_mm_pte(unsigned long ea, unsigned *hshift) +{ + pgd_t *pgdir = init_mm.pgd; + return __find_linux_pte(pgdir, ea, NULL, hshift); +} +/* + * This is what we should always use. Any other lockless page table lookup needs + * careful audit against THP split. + */ +static inline pte_t *find_current_mm_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hshift) +{ + VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__); + VM_WARN(pgdir != current->mm->pgd, + "%s lock less page table lookup called on wrong mm\n", __func__); + return __find_linux_pte(pgdir, ea, is_thp, hshift); +} + +#endif /* _ASM_POWERPC_PTE_WALK_H */ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a3b6575c7842ed42261efbde20fd1b55e269e031..f92eaf7a4c0d5b7c6a6f3748cb9d8d79caa5d2ad 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -22,9 +22,9 @@ #include #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx #include -#endif /* CONFIG_8xx */ +#endif /* CONFIG_PPC_8xx */ #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ @@ -135,7 +135,7 @@ #define MSR_KERNEL (MSR_ | MSR_64BIT) #define MSR_USER32 (MSR_ | MSR_PR | MSR_EE) #define MSR_USER64 (MSR_USER32 | MSR_64BIT) -#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_8xx) +#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_8xx) /* Default MSR for kernel mode. */ #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) @@ -272,16 +272,65 @@ #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ -#define DSISR_NOHPTE 0x40000000 /* no translation found */ -#define DSISR_PROTFAULT 0x08000000 /* protection fault */ -#define DSISR_BADACCESS 0x04000000 /* bad access to CI or G */ -#define DSISR_ISSTORE 0x02000000 /* access was a store */ -#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ -#define DSISR_NOSEGMENT 0x00200000 /* SLB miss */ -#define DSISR_KEYFAULT 0x00200000 /* Key fault */ -#define DSISR_UNSUPP_MMU 0x00080000 /* Unsupported MMU config */ -#define DSISR_SET_RC 0x00040000 /* Failed setting of R/C bits */ -#define DSISR_PGDIRFAULT 0x00020000 /* Fault on page directory */ +#define DSISR_BAD_DIRECT_ST 0x80000000 /* Obsolete: Direct store error */ +#define DSISR_NOHPTE 0x40000000 /* no translation found */ +#define DSISR_ATTR_CONFLICT 0x20000000 /* P9: Process vs. Partition attr */ +#define DSISR_NOEXEC_OR_G 0x10000000 /* Alias of SRR1 bit, see below */ +#define DSISR_PROTFAULT 0x08000000 /* protection fault */ +#define DSISR_BADACCESS 0x04000000 /* bad access to CI or G */ +#define DSISR_ISSTORE 0x02000000 /* access was a store */ +#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ +#define DSISR_NOSEGMENT 0x00200000 /* STAB miss (unsupported) */ +#define DSISR_KEYFAULT 0x00200000 /* Storage Key fault */ +#define DSISR_BAD_EXT_CTRL 0x00100000 /* Obsolete: External ctrl error */ +#define DSISR_UNSUPP_MMU 0x00080000 /* P9: Unsupported MMU config */ +#define DSISR_SET_RC 0x00040000 /* P9: Failed setting of R/C bits */ +#define DSISR_PRTABLE_FAULT 0x00020000 /* P9: Fault on process table */ +#define DSISR_ICSWX_NO_CT 0x00004000 /* P7: icswx unavailable cp type */ +#define DSISR_BAD_COPYPASTE 0x00000008 /* P9: Copy/Paste on wrong memtype */ +#define DSISR_BAD_AMO 0x00000004 /* P9: Incorrect AMO opcode */ +#define DSISR_BAD_CI_LDST 0x00000002 /* P8: Bad HV CI load/store */ + +/* + * DSISR_NOEXEC_OR_G doesn't actually exist. This bit is always + * 0 on DSIs. However, on ISIs, the corresponding bit in SRR1 + * indicates an attempt at executing from a no-execute PTE + * or segment or from a guarded page. + * + * We add a definition here for completeness as we alias + * DSISR and SRR1 in do_page_fault. + */ + +/* + * DSISR bits that are treated as a fault. Any bit set + * here will skip hash_page, and cause do_page_fault to + * trigger a SIGBUS or SIGSEGV: + */ +#define DSISR_BAD_FAULT_32S (DSISR_BAD_DIRECT_ST | \ + DSISR_BADACCESS | \ + DSISR_BAD_EXT_CTRL) +#define DSISR_BAD_FAULT_64S (DSISR_BAD_FAULT_32S | \ + DSISR_ATTR_CONFLICT | \ + DSISR_KEYFAULT | \ + DSISR_UNSUPP_MMU | \ + DSISR_PRTABLE_FAULT | \ + DSISR_ICSWX_NO_CT | \ + DSISR_BAD_COPYPASTE | \ + DSISR_BAD_AMO | \ + DSISR_BAD_CI_LDST) +/* + * These bits are equivalent in SRR1 and DSISR for 0x400 + * instruction access interrupts on Book3S + */ +#define DSISR_SRR1_MATCH_32S (DSISR_NOHPTE | \ + DSISR_NOEXEC_OR_G | \ + DSISR_PROTFAULT) +#define DSISR_SRR1_MATCH_64S (DSISR_SRR1_MATCH_32S | \ + DSISR_KEYFAULT | \ + DSISR_UNSUPP_MMU | \ + DSISR_SET_RC | \ + DSISR_PRTABLE_FAULT) + #define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ #define SPRN_CIR 0x11B /* Chip Information Register (hyper, R/0) */ @@ -307,6 +356,7 @@ #define SPRN_PMSR 0x355 /* Power Management Status Reg */ #define SPRN_PMMAR 0x356 /* Power Management Memory Activity Register */ #define SPRN_PSSCR 0x357 /* Processor Stop Status and Control Register (ISA 3.0) */ +#define SPRN_PSSCR_PR 0x337 /* PSSCR ISA 3.0, privileged mode access */ #define SPRN_PMCR 0x374 /* Power Management Control Register */ /* HFSCR and FSCR bit numbers are the same */ @@ -675,6 +725,7 @@ * may not be recoverable */ #define SRR1_WS_DEEPER 0x00020000 /* Some resources not maintained */ #define SRR1_WS_DEEP 0x00010000 /* All resources maintained */ +#define SRR1_PROGTM 0x00200000 /* TM Bad Thing */ #define SRR1_PROGFPE 0x00100000 /* Floating Point Enabled */ #define SRR1_PROGILL 0x00080000 /* Illegal instruction */ #define SRR1_PROGPRIV 0x00040000 /* Privileged instruction */ @@ -1114,7 +1165,7 @@ #endif #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx #define SPRN_SPRG_SCRATCH0 SPRN_SPRG0 #define SPRN_SPRG_SCRATCH1 SPRN_SPRG1 #define SPRN_SPRG_SCRATCH2 SPRN_SPRG2 @@ -1197,10 +1248,8 @@ * differentiated by the version number in the Communication Processor * Module (CPM). */ -#define PVR_821 0x00500000 -#define PVR_823 PVR_821 -#define PVR_850 PVR_821 -#define PVR_860 PVR_821 +#define PVR_8xx 0x00500000 + #define PVR_8240 0x00810100 #define PVR_8245 0x80811014 #define PVR_8260 PVR_8240 @@ -1295,12 +1344,12 @@ static inline void msr_check_and_clear(unsigned long bits) ".section __ftr_fixup,\"a\"\n" \ ".align 3\n" \ "98:\n" \ - " .llong %1\n" \ - " .llong %1\n" \ - " .llong 97b-98b\n" \ - " .llong 99b-98b\n" \ - " .llong 0\n" \ - " .llong 0\n" \ + " .8byte %1\n" \ + " .8byte %1\n" \ + " .8byte 97b-98b\n" \ + " .8byte 99b-98b\n" \ + " .8byte 0\n" \ + " .8byte 0\n" \ ".previous" \ : "=r" (rval) \ : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \ @@ -1313,7 +1362,7 @@ static inline void msr_check_and_clear(unsigned long bits) #else /* __powerpc64__ */ -#if defined(CONFIG_8xx) +#if defined(CONFIG_PPC_8xx) #define mftbl() ({unsigned long rval; \ asm volatile("mftbl %0" : "=r" (rval)); rval;}) #define mftbu() ({unsigned long rval; \ diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 737e012ef56e124807d885f05dc6bc0d0a54cd9f..eb2a33d5df26b559cf73d7f072fd4655ebb86852 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -221,10 +221,7 @@ #define SPRN_CSRR0 SPRN_SRR2 /* Critical Save and Restore Register 0 */ #define SPRN_CSRR1 SPRN_SRR3 /* Critical Save and Restore Register 1 */ #endif - -#ifdef CONFIG_PPC_ICSWX #define SPRN_HACOP 0x15F /* Hypervisor Available Coprocessor Register */ -#endif /* Bit definitions for CCR1. */ #define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */ diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index 654d64c9f3acd8366fdcf109111f3b5c16cdde21..3a3fb0ca68f5f64ed176e20536481c810f5ff36d 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h @@ -23,7 +23,6 @@ extern void reloc_got2(unsigned long); void check_for_initrd(void); void initmem_init(void); -void setup_panic(void); #define ARCH_PANIC_TIMEOUT 180 #ifdef CONFIG_PPC_PSERIES diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 8ea98504f90078e6ea0592531ef4b482f63ef4d3..fac963e10d3957a86ac1549ae5abee2f5623fd53 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -97,6 +97,7 @@ static inline void set_hard_smp_processor_id(int cpu, int phys) #endif DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DECLARE_PER_CPU(cpumask_var_t, cpu_l2_cache_map); DECLARE_PER_CPU(cpumask_var_t, cpu_core_map); static inline struct cpumask *cpu_sibling_mask(int cpu) @@ -109,6 +110,11 @@ static inline struct cpumask *cpu_core_mask(int cpu) return per_cpu(cpu_core_map, cpu); } +static inline struct cpumask *cpu_l2_cache_mask(int cpu) +{ + return per_cpu(cpu_l2_cache_map, cpu); +} + extern int cpu_to_core_id(int cpu); /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index 8c1b913de6d72ccb2a54759570fc8a511a4ea4e9..edbe571bcc54a7b8eb41e3f0c35f1105ac9b3af7 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -170,39 +170,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) lock->slock = 0; } -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - arch_spinlock_t lock_val; - - smp_mb(); - - /* - * Atomically load and store back the lock value (unchanged). This - * ensures that our observation of the lock value is ordered with - * respect to other lock operations. - */ - __asm__ __volatile__( -"1: " PPC_LWARX(%0, 0, %2, 0) "\n" -" stwcx. %0, 0, %2\n" -" bne- 1b\n" - : "=&r" (lock_val), "+m" (*lock) - : "r" (lock) - : "cr0", "xer"); - - if (arch_spin_value_unlocked(lock_val)) - goto out; - - while (lock->slock) { - HMT_low(); - if (SHARED_PROCESSOR) - __spin_yield(lock); - } - HMT_medium(); - -out: - smp_mb(); -} - /* * Read-write spinlocks, allowing multiple readers * but only one writer. @@ -342,5 +309,8 @@ static inline void arch_write_unlock(arch_rwlock_t *rw) #define arch_read_relax(lock) __rw_yield(lock) #define arch_write_relax(lock) __rw_yield(lock) +/* See include/linux/spinlock.h */ +#define smp_mb__after_spinlock() smp_mb() + #endif /* __KERNEL__ */ #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index d3a42cc45a8286023b47f98403229e02f8e1f238..ab9d849644d05d9662445b6d30a74a6419ad55ad 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -23,12 +23,9 @@ struct pt_regs; #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) #define IS_RFI(instr) (((instr) & 0xfc0007fe) == 0x4c000064) -/* Emulate instructions that cause a transfer of control. */ -extern int emulate_step(struct pt_regs *regs, unsigned int instr); - enum instruction_type { COMPUTE, /* arith/logical/CR op, etc. */ - LOAD, + LOAD, /* load and store types need to be contiguous */ LOAD_MULTI, LOAD_FP, LOAD_VMX, @@ -55,10 +52,31 @@ enum instruction_type { #define INSTR_TYPE_MASK 0x1f +#define OP_IS_LOAD_STORE(type) (LOAD <= (type) && (type) <= STCX) + +/* Compute flags, ORed in with type */ +#define SETREG 0x20 +#define SETCC 0x40 +#define SETXER 0x80 + +/* Branch flags, ORed in with type */ +#define SETLK 0x20 +#define BRTAKEN 0x40 +#define DECCTR 0x80 + /* Load/store flags, ORed in with type */ #define SIGNEXT 0x20 #define UPDATE 0x40 /* matches bit in opcode 31 instructions */ #define BYTEREV 0x80 +#define FPCONV 0x100 + +/* Barrier type field, ORed in with type */ +#define BARRIER_MASK 0xe0 +#define BARRIER_SYNC 0x00 +#define BARRIER_ISYNC 0x20 +#define BARRIER_EIEIO 0x40 +#define BARRIER_LWSYNC 0x60 +#define BARRIER_PTESYNC 0x80 /* Cacheop values, ORed in with type */ #define CACHEOP_MASK 0x700 @@ -67,10 +85,17 @@ enum instruction_type { #define DCBTST 0x200 #define DCBT 0x300 #define ICBI 0x400 +#define DCBZ 0x500 + +/* VSX flags values */ +#define VSX_FPCONV 1 /* do floating point SP/DP conversion */ +#define VSX_SPLAT 2 /* store loaded value into all elements */ +#define VSX_LDLEFT 4 /* load VSX register from left */ +#define VSX_CHECK_VEC 8 /* check MSR_VEC not MSR_VSX for reg >= 32 */ /* Size field in type word */ -#define SIZE(n) ((n) << 8) -#define GETSIZE(w) ((w) >> 8) +#define SIZE(n) ((n) << 12) +#define GETSIZE(w) ((w) >> 12) #define MKOP(t, f, s) ((t) | (f) | SIZE(s)) @@ -83,7 +108,63 @@ struct instruction_op { int update_reg; /* For MFSPR */ int spr; + u32 ccval; + u32 xerval; + u8 element_size; /* for VSX/VMX loads/stores */ + u8 vsx_flags; +}; + +union vsx_reg { + u8 b[16]; + u16 h[8]; + u32 w[4]; + unsigned long d[2]; + float fp[4]; + double dp[2]; + __vector128 v; }; -extern int analyse_instr(struct instruction_op *op, struct pt_regs *regs, +/* + * Decode an instruction, and return information about it in *op + * without changing *regs. + * + * Return value is 1 if the instruction can be emulated just by + * updating *regs with the information in *op, -1 if we need the + * GPRs but *regs doesn't contain the full register set, or 0 + * otherwise. + */ +extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, unsigned int instr); + +/* + * Emulate an instruction that can be executed just by updating + * fields in *regs. + */ +void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op); + +/* + * Emulate instructions that cause a transfer of control, + * arithmetic/logical instructions, loads and stores, + * cache operations and barriers. + * + * Returns 1 if the instruction was emulated successfully, + * 0 if it could not be emulated, or -1 for an instruction that + * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.). + */ +extern int emulate_step(struct pt_regs *regs, unsigned int instr); + +/* + * Emulate a load or store instruction by reading/writing the + * memory of the current process. FP/VMX/VSX registers are assumed + * to hold live values if the appropriate enable bit in regs->msr is + * set; otherwise this will use the saved values in the thread struct + * for user-mode accesses. + */ +extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op); + +extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, + const void *mem, bool cross_endian); +extern void emulate_vsx_store(struct instruction_op *op, + const union vsx_reg *reg, void *mem, + bool cross_endian); +extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs); diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index da3cdffca440931051add9bd312b2c6b06bd3814..cc9addefb51c781400940b4a6f8c752c1dbc3bbf 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -10,6 +10,7 @@ #define __HAVE_ARCH_MEMMOVE #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR +#define __HAVE_ARCH_MEMSET16 extern char * strcpy(char *,const char *); extern char * strncpy(char *,const char *, __kernel_size_t); @@ -23,6 +24,31 @@ extern void * memmove(void *,const void *,__kernel_size_t); extern int memcmp(const void *,const void *,__kernel_size_t); extern void * memchr(const void *,int,__kernel_size_t); +#ifdef CONFIG_PPC64 +#define __HAVE_ARCH_MEMSET32 +#define __HAVE_ARCH_MEMSET64 + +extern void *__memset16(uint16_t *, uint16_t v, __kernel_size_t); +extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); +extern void *__memset64(uint64_t *, uint64_t v, __kernel_size_t); + +static inline void *memset16(uint16_t *p, uint16_t v, __kernel_size_t n) +{ + return __memset16(p, v, n * 2); +} + +static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n) +{ + return __memset32(p, v, n * 4); +} + +static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) +{ + return __memset64(p, v, n * 8); +} +#else +extern void *memset16(uint16_t *, uint16_t, __kernel_size_t); +#endif #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_STRING_H */ diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h index 2cf846edb3fcc4e941e44a8fc032eecd789b22d7..cb61eae5b7ed3309ff4dd6f91135faa3f9180bcb 100644 --- a/arch/powerpc/include/asm/timex.h +++ b/arch/powerpc/include/asm/timex.h @@ -29,7 +29,7 @@ static inline cycles_t get_cycles(void) ret = 0; __asm__ __volatile__( -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx "97: mftb %0\n" #else "97: mfspr %0, %2\n" @@ -45,11 +45,7 @@ static inline cycles_t get_cycles(void) " .long 0\n" " .long 0\n" ".previous" -#ifdef CONFIG_8xx - : "=r" (ret) : "i" (CPU_FTR_601)); -#else : "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL)); -#endif return ret; #endif } diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h index 609557569f6520f13167838ef11d4dfc1401a0c7..a7eabff27a0faa24904485af089f8434eeee246c 100644 --- a/arch/powerpc/include/asm/tlb.h +++ b/arch/powerpc/include/asm/tlb.h @@ -69,13 +69,22 @@ static inline int mm_is_core_local(struct mm_struct *mm) topology_sibling_cpumask(smp_processor_id())); } +#ifdef CONFIG_PPC_BOOK3S_64 +static inline int mm_is_thread_local(struct mm_struct *mm) +{ + if (atomic_read(&mm->context.active_cpus) > 1) + return false; + return cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)); +} +#else /* CONFIG_PPC_BOOK3S_64 */ static inline int mm_is_thread_local(struct mm_struct *mm) { return cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())); } +#endif /* !CONFIG_PPC_BOOK3S_64 */ -#else +#else /* CONFIG_SMP */ static inline int mm_is_core_local(struct mm_struct *mm) { return 1; diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index dc4e15937ccf847f4fa040d4b77cf0ae07a7ba8d..2d84bca8d053e9ae6f2ca5a0ac323cb4cc10caf8 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -16,8 +16,6 @@ struct device_node; #include -#define parent_node(node) (node) - #define cpumask_of_node(node) ((node) == -1 ? \ cpu_all_mask : \ node_to_cpumask_map[node]) diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h new file mode 100644 index 0000000000000000000000000000000000000000..fd5963acd65824d2d6147a4816189637ccff9d73 --- /dev/null +++ b/arch/powerpc/include/asm/vas.h @@ -0,0 +1,159 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_POWERPC_VAS_H +#define _ASM_POWERPC_VAS_H + +/* + * Min and max FIFO sizes are based on Version 1.05 Section 3.1.4.25 + * (Local FIFO Size Register) of the VAS workbook. + */ +#define VAS_RX_FIFO_SIZE_MIN (1 << 10) /* 1KB */ +#define VAS_RX_FIFO_SIZE_MAX (8 << 20) /* 8MB */ + +/* + * Threshold Control Mode: Have paste operation fail if the number of + * requests in receive FIFO exceeds a threshold. + * + * NOTE: No special error code yet if paste is rejected because of these + * limits. So users can't distinguish between this and other errors. + */ +#define VAS_THRESH_DISABLED 0 +#define VAS_THRESH_FIFO_GT_HALF_FULL 1 +#define VAS_THRESH_FIFO_GT_QTR_FULL 2 +#define VAS_THRESH_FIFO_GT_EIGHTH_FULL 3 + +/* + * Get/Set bit fields + */ +#define GET_FIELD(m, v) (((v) & (m)) >> MASK_LSH(m)) +#define MASK_LSH(m) (__builtin_ffsl(m) - 1) +#define SET_FIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_LSH(m)) & (m))) + +/* + * Co-processor Engine type. + */ +enum vas_cop_type { + VAS_COP_TYPE_FAULT, + VAS_COP_TYPE_842, + VAS_COP_TYPE_842_HIPRI, + VAS_COP_TYPE_GZIP, + VAS_COP_TYPE_GZIP_HIPRI, + VAS_COP_TYPE_FTW, + VAS_COP_TYPE_MAX, +}; + +/* + * Receive window attributes specified by the (in-kernel) owner of window. + */ +struct vas_rx_win_attr { + void *rx_fifo; + int rx_fifo_size; + int wcreds_max; + + bool pin_win; + bool rej_no_credit; + bool tx_wcred_mode; + bool rx_wcred_mode; + bool tx_win_ord_mode; + bool rx_win_ord_mode; + bool data_stamp; + bool nx_win; + bool fault_win; + bool user_win; + bool notify_disable; + bool intr_disable; + bool notify_early; + + int lnotify_lpid; + int lnotify_pid; + int lnotify_tid; + u32 pswid; + + int tc_mode; +}; + +/* + * Window attributes specified by the in-kernel owner of a send window. + */ +struct vas_tx_win_attr { + enum vas_cop_type cop; + int wcreds_max; + int lpid; + int pidr; /* hardware PID (from SPRN_PID) */ + int pid; /* linux process id */ + int pswid; + int rsvd_txbuf_count; + int tc_mode; + + bool user_win; + bool pin_win; + bool rej_no_credit; + bool rsvd_txbuf_enable; + bool tx_wcred_mode; + bool rx_wcred_mode; + bool tx_win_ord_mode; + bool rx_win_ord_mode; +}; + +/* + * Helper to initialize receive window attributes to defaults for an + * NX window. + */ +void vas_init_rx_win_attr(struct vas_rx_win_attr *rxattr, enum vas_cop_type cop); + +/* + * Open a VAS receive window for the instance of VAS identified by @vasid + * Use @attr to initialize the attributes of the window. + * + * Return a handle to the window or ERR_PTR() on error. + */ +struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop, + struct vas_rx_win_attr *attr); + +/* + * Helper to initialize send window attributes to defaults for an NX window. + */ +extern void vas_init_tx_win_attr(struct vas_tx_win_attr *txattr, + enum vas_cop_type cop); + +/* + * Open a VAS send window for the instance of VAS identified by @vasid + * and the co-processor type @cop. Use @attr to initialize attributes + * of the window. + * + * Note: The instance of VAS must already have an open receive window for + * the coprocessor type @cop. + * + * Return a handle to the send window or ERR_PTR() on error. + */ +struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, + struct vas_tx_win_attr *attr); + +/* + * Close the send or receive window identified by @win. For receive windows + * return -EAGAIN if there are active send windows attached to this receive + * window. + */ +int vas_win_close(struct vas_window *win); + +/* + * Copy the co-processor request block (CRB) @crb into the local L2 cache. + */ +int vas_copy_crb(void *crb, int offset); + +/* + * Paste a previously copied CRB (see vas_copy_crb()) from the L2 cache to + * the hardware address associated with the window @win. @re is expected/ + * assumed to be true for NX windows. + */ +int vas_paste_crb(struct vas_window *win, int offset, bool re); + +#endif /* __ASM_POWERPC_VAS_H */ diff --git a/arch/powerpc/include/asm/vga.h b/arch/powerpc/include/asm/vga.h index ab3acd2f2786c61f721e031cc79f51ffa457605a..7a7b541b74930440372fcea8c87afeb3698eb0c2 100644 --- a/arch/powerpc/include/asm/vga.h +++ b/arch/powerpc/include/asm/vga.h @@ -33,8 +33,16 @@ static inline u16 scr_readw(volatile const u16 *addr) return le16_to_cpu(*addr); } +#define VT_BUF_HAVE_MEMSETW +static inline void scr_memsetw(u16 *s, u16 v, unsigned int n) +{ + memset16(s, cpu_to_le16(v), n / 2); +} + #define VT_BUF_HAVE_MEMCPYW +#define VT_BUF_HAVE_MEMMOVEW #define scr_memcpyw memcpy +#define scr_memmovew memmove #endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */ diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index c23ff4389ca236c43994fe4279b7f151e80fe5e7..371fbebf1ec9e4c43739e0d44439145b34e791d6 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -45,6 +45,7 @@ struct xive_irq_data { void __iomem *trig_mmio; u32 esb_shift; int src_chip; + u32 hw_irq; /* Setup/used by frontend */ int target; @@ -55,6 +56,7 @@ struct xive_irq_data { #define XIVE_IRQ_FLAG_SHIFT_BUG 0x04 #define XIVE_IRQ_FLAG_MASK_FW 0x08 #define XIVE_IRQ_FLAG_EOI_FW 0x10 +#define XIVE_IRQ_FLAG_H_INT_ESB 0x20 #define XIVE_INVALID_CHIP_ID -1 @@ -110,11 +112,13 @@ extern bool __xive_enabled; static inline bool xive_enabled(void) { return __xive_enabled; } +extern bool xive_spapr_init(void); extern bool xive_native_init(void); extern void xive_smp_probe(void); extern int xive_smp_prepare_cpu(unsigned int cpu); extern void xive_smp_setup_cpu(void); extern void xive_smp_disable_cpu(void); +extern void xive_teardown_cpu(void); extern void xive_kexec_teardown_cpu(int secondary); extern void xive_shutdown(void); extern void xive_flush_interrupt(void); @@ -147,6 +151,7 @@ extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id) static inline bool xive_enabled(void) { return false; } +static inline bool xive_spapr_init(void) { return false; } static inline bool xive_native_init(void) { return false; } static inline void xive_smp_probe(void) { } extern inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; } diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h index ab45cc2f31018a66aebec62c93f27e6274467f70..03c06ba7464f4fc47d7f5b6f0fb0057fa69d8f1c 100644 --- a/arch/powerpc/include/uapi/asm/mman.h +++ b/arch/powerpc/include/uapi/asm/mman.h @@ -29,20 +29,4 @@ #define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ #define MAP_HUGETLB 0x40000 /* create a huge page mapping */ -/* - * When MAP_HUGETLB is set, bits [26:31] of the flags argument to mmap(2), - * encode the log2 of the huge page size. A value of zero indicates that the - * default huge page size should be used. To use a non-default huge page size, - * one of these defines can be used, or the size can be encoded by hand. Note - * that on most systems only a subset, or possibly none, of these sizes will be - * available. - */ -#define MAP_HUGE_512KB (19 << MAP_HUGE_SHIFT) /* 512KB HugeTLB Page */ -#define MAP_HUGE_1MB (20 << MAP_HUGE_SHIFT) /* 1MB HugeTLB Page */ -#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) /* 2MB HugeTLB Page */ -#define MAP_HUGE_8MB (23 << MAP_HUGE_SHIFT) /* 8MB HugeTLB Page */ -#define MAP_HUGE_16MB (24 << MAP_HUGE_SHIFT) /* 16MB HugeTLB Page */ -#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) /* 1GB HugeTLB Page */ -#define MAP_HUGE_16GB (34 << MAP_HUGE_SHIFT) /* 16GB HugeTLB Page */ - #endif /* _UAPI_ASM_POWERPC_MMAN_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 4aa7c147e4472257564200a8a55a742c78989023..91960f83039c816b674d0b3f07f09808a2af39cb 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -38,7 +38,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o nvram_64.o firmware.o obj-$(CONFIG_VDSO32) += vdso32/ -obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog.o +obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o @@ -83,7 +83,7 @@ extra-y := head_$(BITS).o extra-$(CONFIG_40x) := head_40x.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o -extra-$(CONFIG_8xx) := head_8xx.o +extra-$(CONFIG_PPC_8xx) := head_8xx.o extra-y += vmlinux.lds obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index ec7a8b099dd960b43896ad2cd50b1e5f87f420f7..43ef2515648098f985ff5f7d10a66b2f6d724391 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -27,6 +27,7 @@ #include #include #include +#include struct aligninfo { unsigned char len; @@ -40,364 +41,9 @@ struct aligninfo { #define LD 0 /* load */ #define ST 1 /* store */ #define SE 2 /* sign-extend value, or FP ld/st as word */ -#define F 4 /* to/from fp regs */ -#define U 8 /* update index register */ -#define M 0x10 /* multiple load/store */ #define SW 0x20 /* byte swap */ -#define S 0x40 /* single-precision fp or... */ -#define SX 0x40 /* ... byte count in XER */ -#define HARD 0x80 /* string, stwcx. */ #define E4 0x40 /* SPE endianness is word */ #define E8 0x80 /* SPE endianness is double word */ -#define SPLT 0x80 /* VSX SPLAT load */ - -/* DSISR bits reported for a DCBZ instruction: */ -#define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */ - -/* - * The PowerPC stores certain bits of the instruction that caused the - * alignment exception in the DSISR register. This array maps those - * bits to information about the operand length and what the - * instruction would do. - */ -static struct aligninfo aligninfo[128] = { - { 4, LD }, /* 00 0 0000: lwz / lwarx */ - INVALID, /* 00 0 0001 */ - { 4, ST }, /* 00 0 0010: stw */ - INVALID, /* 00 0 0011 */ - { 2, LD }, /* 00 0 0100: lhz */ - { 2, LD+SE }, /* 00 0 0101: lha */ - { 2, ST }, /* 00 0 0110: sth */ - { 4, LD+M }, /* 00 0 0111: lmw */ - { 4, LD+F+S }, /* 00 0 1000: lfs */ - { 8, LD+F }, /* 00 0 1001: lfd */ - { 4, ST+F+S }, /* 00 0 1010: stfs */ - { 8, ST+F }, /* 00 0 1011: stfd */ - { 16, LD }, /* 00 0 1100: lq */ - { 8, LD }, /* 00 0 1101: ld/ldu/lwa */ - INVALID, /* 00 0 1110 */ - { 8, ST }, /* 00 0 1111: std/stdu */ - { 4, LD+U }, /* 00 1 0000: lwzu */ - INVALID, /* 00 1 0001 */ - { 4, ST+U }, /* 00 1 0010: stwu */ - INVALID, /* 00 1 0011 */ - { 2, LD+U }, /* 00 1 0100: lhzu */ - { 2, LD+SE+U }, /* 00 1 0101: lhau */ - { 2, ST+U }, /* 00 1 0110: sthu */ - { 4, ST+M }, /* 00 1 0111: stmw */ - { 4, LD+F+S+U }, /* 00 1 1000: lfsu */ - { 8, LD+F+U }, /* 00 1 1001: lfdu */ - { 4, ST+F+S+U }, /* 00 1 1010: stfsu */ - { 8, ST+F+U }, /* 00 1 1011: stfdu */ - { 16, LD+F }, /* 00 1 1100: lfdp */ - INVALID, /* 00 1 1101 */ - { 16, ST+F }, /* 00 1 1110: stfdp */ - INVALID, /* 00 1 1111 */ - { 8, LD }, /* 01 0 0000: ldx */ - INVALID, /* 01 0 0001 */ - { 8, ST }, /* 01 0 0010: stdx */ - INVALID, /* 01 0 0011 */ - INVALID, /* 01 0 0100 */ - { 4, LD+SE }, /* 01 0 0101: lwax */ - INVALID, /* 01 0 0110 */ - INVALID, /* 01 0 0111 */ - { 4, LD+M+HARD+SX }, /* 01 0 1000: lswx */ - { 4, LD+M+HARD }, /* 01 0 1001: lswi */ - { 4, ST+M+HARD+SX }, /* 01 0 1010: stswx */ - { 4, ST+M+HARD }, /* 01 0 1011: stswi */ - INVALID, /* 01 0 1100 */ - { 8, LD+U }, /* 01 0 1101: ldu */ - INVALID, /* 01 0 1110 */ - { 8, ST+U }, /* 01 0 1111: stdu */ - { 8, LD+U }, /* 01 1 0000: ldux */ - INVALID, /* 01 1 0001 */ - { 8, ST+U }, /* 01 1 0010: stdux */ - INVALID, /* 01 1 0011 */ - INVALID, /* 01 1 0100 */ - { 4, LD+SE+U }, /* 01 1 0101: lwaux */ - INVALID, /* 01 1 0110 */ - INVALID, /* 01 1 0111 */ - INVALID, /* 01 1 1000 */ - INVALID, /* 01 1 1001 */ - INVALID, /* 01 1 1010 */ - INVALID, /* 01 1 1011 */ - INVALID, /* 01 1 1100 */ - INVALID, /* 01 1 1101 */ - INVALID, /* 01 1 1110 */ - INVALID, /* 01 1 1111 */ - INVALID, /* 10 0 0000 */ - INVALID, /* 10 0 0001 */ - INVALID, /* 10 0 0010: stwcx. */ - INVALID, /* 10 0 0011 */ - INVALID, /* 10 0 0100 */ - INVALID, /* 10 0 0101 */ - INVALID, /* 10 0 0110 */ - INVALID, /* 10 0 0111 */ - { 4, LD+SW }, /* 10 0 1000: lwbrx */ - INVALID, /* 10 0 1001 */ - { 4, ST+SW }, /* 10 0 1010: stwbrx */ - INVALID, /* 10 0 1011 */ - { 2, LD+SW }, /* 10 0 1100: lhbrx */ - { 4, LD+SE }, /* 10 0 1101 lwa */ - { 2, ST+SW }, /* 10 0 1110: sthbrx */ - { 16, ST }, /* 10 0 1111: stq */ - INVALID, /* 10 1 0000 */ - INVALID, /* 10 1 0001 */ - INVALID, /* 10 1 0010 */ - INVALID, /* 10 1 0011 */ - INVALID, /* 10 1 0100 */ - INVALID, /* 10 1 0101 */ - INVALID, /* 10 1 0110 */ - INVALID, /* 10 1 0111 */ - INVALID, /* 10 1 1000 */ - INVALID, /* 10 1 1001 */ - INVALID, /* 10 1 1010 */ - INVALID, /* 10 1 1011 */ - INVALID, /* 10 1 1100 */ - INVALID, /* 10 1 1101 */ - INVALID, /* 10 1 1110 */ - { 0, ST+HARD }, /* 10 1 1111: dcbz */ - { 4, LD }, /* 11 0 0000: lwzx */ - INVALID, /* 11 0 0001 */ - { 4, ST }, /* 11 0 0010: stwx */ - INVALID, /* 11 0 0011 */ - { 2, LD }, /* 11 0 0100: lhzx */ - { 2, LD+SE }, /* 11 0 0101: lhax */ - { 2, ST }, /* 11 0 0110: sthx */ - INVALID, /* 11 0 0111 */ - { 4, LD+F+S }, /* 11 0 1000: lfsx */ - { 8, LD+F }, /* 11 0 1001: lfdx */ - { 4, ST+F+S }, /* 11 0 1010: stfsx */ - { 8, ST+F }, /* 11 0 1011: stfdx */ - { 16, LD+F }, /* 11 0 1100: lfdpx */ - { 4, LD+F+SE }, /* 11 0 1101: lfiwax */ - { 16, ST+F }, /* 11 0 1110: stfdpx */ - { 4, ST+F }, /* 11 0 1111: stfiwx */ - { 4, LD+U }, /* 11 1 0000: lwzux */ - INVALID, /* 11 1 0001 */ - { 4, ST+U }, /* 11 1 0010: stwux */ - INVALID, /* 11 1 0011 */ - { 2, LD+U }, /* 11 1 0100: lhzux */ - { 2, LD+SE+U }, /* 11 1 0101: lhaux */ - { 2, ST+U }, /* 11 1 0110: sthux */ - INVALID, /* 11 1 0111 */ - { 4, LD+F+S+U }, /* 11 1 1000: lfsux */ - { 8, LD+F+U }, /* 11 1 1001: lfdux */ - { 4, ST+F+S+U }, /* 11 1 1010: stfsux */ - { 8, ST+F+U }, /* 11 1 1011: stfdux */ - INVALID, /* 11 1 1100 */ - { 4, LD+F }, /* 11 1 1101: lfiwzx */ - INVALID, /* 11 1 1110 */ - INVALID, /* 11 1 1111 */ -}; - -/* - * The dcbz (data cache block zero) instruction - * gives an alignment fault if used on non-cacheable - * memory. We handle the fault mainly for the - * case when we are running with the cache disabled - * for debugging. - */ -static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) -{ - long __user *p; - int i, size; - -#ifdef __powerpc64__ - size = ppc64_caches.l1d.block_size; -#else - size = L1_CACHE_BYTES; -#endif - p = (long __user *) (regs->dar & -size); - if (user_mode(regs) && !access_ok(VERIFY_WRITE, p, size)) - return -EFAULT; - for (i = 0; i < size / sizeof(long); ++i) - if (__put_user_inatomic(0, p+i)) - return -EFAULT; - return 1; -} - -/* - * Emulate load & store multiple instructions - * On 64-bit machines, these instructions only affect/use the - * bottom 4 bytes of each register, and the loads clear the - * top 4 bytes of the affected register. - */ -#ifdef __BIG_ENDIAN__ -#ifdef CONFIG_PPC64 -#define REG_BYTE(rp, i) *((u8 *)((rp) + ((i) >> 2)) + ((i) & 3) + 4) -#else -#define REG_BYTE(rp, i) *((u8 *)(rp) + (i)) -#endif -#else -#define REG_BYTE(rp, i) (*(((u8 *)((rp) + ((i)>>2)) + ((i)&3)))) -#endif - -#define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz)) - -static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, - unsigned int reg, unsigned int nb, - unsigned int flags, unsigned int instr, - unsigned long swiz) -{ - unsigned long *rptr; - unsigned int nb0, i, bswiz; - unsigned long p; - - /* - * We do not try to emulate 8 bytes multiple as they aren't really - * available in our operating environments and we don't try to - * emulate multiples operations in kernel land as they should never - * be used/generated there at least not on unaligned boundaries - */ - if (unlikely((nb > 4) || !user_mode(regs))) - return 0; - - /* lmw, stmw, lswi/x, stswi/x */ - nb0 = 0; - if (flags & HARD) { - if (flags & SX) { - nb = regs->xer & 127; - if (nb == 0) - return 1; - } else { - unsigned long pc = regs->nip ^ (swiz & 4); - - if (__get_user_inatomic(instr, - (unsigned int __user *)pc)) - return -EFAULT; - if (swiz == 0 && (flags & SW)) - instr = cpu_to_le32(instr); - nb = (instr >> 11) & 0x1f; - if (nb == 0) - nb = 32; - } - if (nb + reg * 4 > 128) { - nb0 = nb + reg * 4 - 128; - nb = 128 - reg * 4; - } -#ifdef __LITTLE_ENDIAN__ - /* - * String instructions are endian neutral but the code - * below is not. Force byte swapping on so that the - * effects of swizzling are undone in the load/store - * loops below. - */ - flags ^= SW; -#endif - } else { - /* lwm, stmw */ - nb = (32 - reg) * 4; - } - - if (!access_ok((flags & ST ? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0)) - return -EFAULT; /* bad address */ - - rptr = ®s->gpr[reg]; - p = (unsigned long) addr; - bswiz = (flags & SW)? 3: 0; - - if (!(flags & ST)) { - /* - * This zeroes the top 4 bytes of the affected registers - * in 64-bit mode, and also zeroes out any remaining - * bytes of the last register for lsw*. - */ - memset(rptr, 0, ((nb + 3) / 4) * sizeof(unsigned long)); - if (nb0 > 0) - memset(®s->gpr[0], 0, - ((nb0 + 3) / 4) * sizeof(unsigned long)); - - for (i = 0; i < nb; ++i, ++p) - if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - if (nb0 > 0) { - rptr = ®s->gpr[0]; - addr += nb; - for (i = 0; i < nb0; ++i, ++p) - if (__get_user_inatomic(REG_BYTE(rptr, - i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - } - - } else { - for (i = 0; i < nb; ++i, ++p) - if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - if (nb0 > 0) { - rptr = ®s->gpr[0]; - addr += nb; - for (i = 0; i < nb0; ++i, ++p) - if (__put_user_inatomic(REG_BYTE(rptr, - i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - } - } - return 1; -} - -/* - * Emulate floating-point pair loads and stores. - * Only POWER6 has these instructions, and it does true little-endian, - * so we don't need the address swizzling. - */ -static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, - unsigned int flags) -{ - char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); - char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); - int i, ret, sw = 0; - - if (reg & 1) - return 0; /* invalid form: FRS/FRT must be even */ - if (flags & SW) - sw = 7; - ret = 0; - for (i = 0; i < 8; ++i) { - if (!(flags & ST)) { - ret |= __get_user(ptr0[i^sw], addr + i); - ret |= __get_user(ptr1[i^sw], addr + i + 8); - } else { - ret |= __put_user(ptr0[i^sw], addr + i); - ret |= __put_user(ptr1[i^sw], addr + i + 8); - } - } - if (ret) - return -EFAULT; - return 1; /* exception handled and fixed up */ -} - -#ifdef CONFIG_PPC64 -static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr, - unsigned int reg, unsigned int flags) -{ - char *ptr0 = (char *)®s->gpr[reg]; - char *ptr1 = (char *)®s->gpr[reg+1]; - int i, ret, sw = 0; - - if (reg & 1) - return 0; /* invalid form: GPR must be even */ - if (flags & SW) - sw = 7; - ret = 0; - for (i = 0; i < 8; ++i) { - if (!(flags & ST)) { - ret |= __get_user(ptr0[i^sw], addr + i); - ret |= __get_user(ptr1[i^sw], addr + i + 8); - } else { - ret |= __put_user(ptr0[i^sw], addr + i); - ret |= __put_user(ptr1[i^sw], addr + i + 8); - } - } - if (ret) - return -EFAULT; - return 1; /* exception handled and fixed up */ -} -#endif /* CONFIG_PPC64 */ #ifdef CONFIG_SPE @@ -636,133 +282,21 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, } #endif /* CONFIG_SPE */ -#ifdef CONFIG_VSX -/* - * Emulate VSX instructions... - */ -static int emulate_vsx(unsigned char __user *addr, unsigned int reg, - unsigned int areg, struct pt_regs *regs, - unsigned int flags, unsigned int length, - unsigned int elsize) -{ - char *ptr; - unsigned long *lptr; - int ret = 0; - int sw = 0; - int i, j; - - /* userland only */ - if (unlikely(!user_mode(regs))) - return 0; - - flush_vsx_to_thread(current); - - if (reg < 32) - ptr = (char *) ¤t->thread.fp_state.fpr[reg][0]; - else - ptr = (char *) ¤t->thread.vr_state.vr[reg - 32]; - - lptr = (unsigned long *) ptr; - -#ifdef __LITTLE_ENDIAN__ - if (flags & SW) { - elsize = length; - sw = length-1; - } else { - /* - * The elements are BE ordered, even in LE mode, so process - * them in reverse order. - */ - addr += length - elsize; - - /* 8 byte memory accesses go in the top 8 bytes of the VR */ - if (length == 8) - ptr += 8; - } -#else - if (flags & SW) - sw = elsize-1; -#endif - - for (j = 0; j < length; j += elsize) { - for (i = 0; i < elsize; ++i) { - if (flags & ST) - ret |= __put_user(ptr[i^sw], addr + i); - else - ret |= __get_user(ptr[i^sw], addr + i); - } - ptr += elsize; -#ifdef __LITTLE_ENDIAN__ - addr -= elsize; -#else - addr += elsize; -#endif - } - -#ifdef __BIG_ENDIAN__ -#define VSX_HI 0 -#define VSX_LO 1 -#else -#define VSX_HI 1 -#define VSX_LO 0 -#endif - - if (!ret) { - if (flags & U) - regs->gpr[areg] = regs->dar; - - /* Splat load copies the same data to top and bottom 8 bytes */ - if (flags & SPLT) - lptr[VSX_LO] = lptr[VSX_HI]; - /* For 8 byte loads, zero the low 8 bytes */ - else if (!(flags & ST) && (8 == length)) - lptr[VSX_LO] = 0; - } else - return -EFAULT; - - return 1; -} -#endif - /* * Called on alignment exception. Attempts to fixup * * Return 1 on success * Return 0 if unable to handle the interrupt * Return -EFAULT if data address is bad + * Other negative return values indicate that the instruction can't + * be emulated, and the process should be given a SIGBUS. */ int fix_alignment(struct pt_regs *regs) { - unsigned int instr, nb, flags, instruction = 0; - unsigned int reg, areg; - unsigned int dsisr; - unsigned char __user *addr; - unsigned long p, swiz; - int ret, i; - union data { - u64 ll; - double dd; - unsigned char v[8]; - struct { -#ifdef __LITTLE_ENDIAN__ - int low32; - unsigned hi32; -#else - unsigned hi32; - int low32; -#endif - } x32; - struct { -#ifdef __LITTLE_ENDIAN__ - short low16; - unsigned char hi48[6]; -#else - unsigned char hi48[6]; - short low16; -#endif - } x16; - } data; + unsigned int instr; + struct instruction_op op; + int r, type; /* * We require a complete register set, if not, then our assembly @@ -770,121 +304,23 @@ int fix_alignment(struct pt_regs *regs) */ CHECK_FULL_REGS(regs); - dsisr = regs->dsisr; - - /* Some processors don't provide us with a DSISR we can use here, - * let's make one up from the instruction - */ - if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) { - unsigned long pc = regs->nip; - - if (cpu_has_feature(CPU_FTR_PPC_LE) && (regs->msr & MSR_LE)) - pc ^= 4; - if (unlikely(__get_user_inatomic(instr, - (unsigned int __user *)pc))) - return -EFAULT; - if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE)) - instr = cpu_to_le32(instr); - dsisr = make_dsisr(instr); - instruction = instr; + if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip))) + return -EFAULT; + if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { + /* We don't handle PPC little-endian any more... */ + if (cpu_has_feature(CPU_FTR_PPC_LE)) + return -EIO; + instr = swab32(instr); } - /* extract the operation and registers from the dsisr */ - reg = (dsisr >> 5) & 0x1f; /* source/dest register */ - areg = dsisr & 0x1f; /* register to update */ - #ifdef CONFIG_SPE if ((instr >> 26) == 0x4) { + int reg = (instr >> 21) & 0x1f; PPC_WARN_ALIGNMENT(spe, regs); return emulate_spe(regs, reg, instr); } #endif - instr = (dsisr >> 10) & 0x7f; - instr |= (dsisr >> 13) & 0x60; - - /* Lookup the operation in our table */ - nb = aligninfo[instr].len; - flags = aligninfo[instr].flags; - - /* - * Handle some cases which give overlaps in the DSISR values. - */ - if (IS_XFORM(instruction)) { - switch (get_xop(instruction)) { - case 532: /* ldbrx */ - nb = 8; - flags = LD+SW; - break; - case 660: /* stdbrx */ - nb = 8; - flags = ST+SW; - break; - case 20: /* lwarx */ - case 84: /* ldarx */ - case 116: /* lharx */ - case 276: /* lqarx */ - return 0; /* not emulated ever */ - } - } - - /* Byteswap little endian loads and stores */ - swiz = 0; - if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { - flags ^= SW; -#ifdef __BIG_ENDIAN__ - /* - * So-called "PowerPC little endian" mode works by - * swizzling addresses rather than by actually doing - * any byte-swapping. To emulate this, we XOR each - * byte address with 7. We also byte-swap, because - * the processor's address swizzling depends on the - * operand size (it xors the address with 7 for bytes, - * 6 for halfwords, 4 for words, 0 for doublewords) but - * we will xor with 7 and load/store each byte separately. - */ - if (cpu_has_feature(CPU_FTR_PPC_LE)) - swiz = 7; -#endif - } - - /* DAR has the operand effective address */ - addr = (unsigned char __user *)regs->dar; - -#ifdef CONFIG_VSX - if ((instruction & 0xfc00003e) == 0x7c000018) { - unsigned int elsize; - - /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */ - reg |= (instruction & 0x1) << 5; - /* Simple inline decoder instead of a table */ - /* VSX has only 8 and 16 byte memory accesses */ - nb = 8; - if (instruction & 0x200) - nb = 16; - - /* Vector stores in little-endian mode swap individual - elements, so process them separately */ - elsize = 4; - if (instruction & 0x80) - elsize = 8; - - flags = 0; - if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) - flags |= SW; - if (instruction & 0x100) - flags |= ST; - if (instruction & 0x040) - flags |= U; - /* splat load needs a special decoder */ - if ((instruction & 0x400) == 0){ - flags |= SPLT; - nb = 8; - } - PPC_WARN_ALIGNMENT(vsx, regs); - return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize); - } -#endif /* * ISA 3.0 (such as P9) copy, copy_first, paste and paste_last alignment @@ -896,173 +332,27 @@ int fix_alignment(struct pt_regs *regs) * when pasting to a co-processor. Furthermore, paste_last is the * synchronisation point for preceding copy/paste sequences. */ - if ((instruction & 0xfc0006fe) == PPC_INST_COPY) + if ((instr & 0xfc0006fe) == PPC_INST_COPY) return -EIO; - /* A size of 0 indicates an instruction we don't support, with - * the exception of DCBZ which is handled as a special case here - */ - if (instr == DCBZ) { - PPC_WARN_ALIGNMENT(dcbz, regs); - return emulate_dcbz(regs, addr); - } - if (unlikely(nb == 0)) - return 0; - - /* Load/Store Multiple instructions are handled in their own - * function - */ - if (flags & M) { - PPC_WARN_ALIGNMENT(multiple, regs); - return emulate_multiple(regs, addr, reg, nb, - flags, instr, swiz); - } - - /* Verify the address of the operand */ - if (unlikely(user_mode(regs) && - !access_ok((flags & ST ? VERIFY_WRITE : VERIFY_READ), - addr, nb))) - return -EFAULT; - - /* Force the fprs into the save area so we can reference them */ - if (flags & F) { - /* userland only */ - if (unlikely(!user_mode(regs))) - return 0; - flush_fp_to_thread(current); - } + r = analyse_instr(&op, regs, instr); + if (r < 0) + return -EINVAL; - if (nb == 16) { - if (flags & F) { - /* Special case for 16-byte FP loads and stores */ - PPC_WARN_ALIGNMENT(fp_pair, regs); - return emulate_fp_pair(addr, reg, flags); - } else { -#ifdef CONFIG_PPC64 - /* Special case for 16-byte loads and stores */ - PPC_WARN_ALIGNMENT(lq_stq, regs); - return emulate_lq_stq(regs, addr, reg, flags); -#else - return 0; -#endif - } - } - - PPC_WARN_ALIGNMENT(unaligned, regs); - - /* If we are loading, get the data from user space, else - * get it from register values - */ - if (!(flags & ST)) { - unsigned int start = 0; - - switch (nb) { - case 4: - start = offsetof(union data, x32.low32); - break; - case 2: - start = offsetof(union data, x16.low16); - break; - } - - data.ll = 0; - ret = 0; - p = (unsigned long)addr; - - for (i = 0; i < nb; i++) - ret |= __get_user_inatomic(data.v[start + i], - SWIZ_PTR(p++)); - - if (unlikely(ret)) - return -EFAULT; - - } else if (flags & F) { - data.ll = current->thread.TS_FPR(reg); - if (flags & S) { - /* Single-precision FP store requires conversion... */ -#ifdef CONFIG_PPC_FPU - preempt_disable(); - enable_kernel_fp(); - cvt_df(&data.dd, (float *)&data.x32.low32); - disable_kernel_fp(); - preempt_enable(); -#else - return 0; -#endif - } - } else - data.ll = regs->gpr[reg]; - - if (flags & SW) { - switch (nb) { - case 8: - data.ll = swab64(data.ll); - break; - case 4: - data.x32.low32 = swab32(data.x32.low32); - break; - case 2: - data.x16.low16 = swab16(data.x16.low16); - break; - } - } - - /* Perform other misc operations like sign extension - * or floating point single precision conversion - */ - switch (flags & ~(U|SW)) { - case LD+SE: /* sign extending integer loads */ - case LD+F+SE: /* sign extend for lfiwax */ - if ( nb == 2 ) - data.ll = data.x16.low16; - else /* nb must be 4 */ - data.ll = data.x32.low32; - break; - - /* Single-precision FP load requires conversion... */ - case LD+F+S: -#ifdef CONFIG_PPC_FPU - preempt_disable(); - enable_kernel_fp(); - cvt_fd((float *)&data.x32.low32, &data.dd); - disable_kernel_fp(); - preempt_enable(); -#else - return 0; -#endif - break; + type = op.type & INSTR_TYPE_MASK; + if (!OP_IS_LOAD_STORE(type)) { + if (op.type != CACHEOP + DCBZ) + return -EINVAL; + PPC_WARN_ALIGNMENT(dcbz, regs); + r = emulate_dcbz(op.ea, regs); + } else { + if (type == LARX || type == STCX) + return -EIO; + PPC_WARN_ALIGNMENT(unaligned, regs); + r = emulate_loadstore(regs, &op); } - /* Store result to memory or update registers */ - if (flags & ST) { - unsigned int start = 0; - - switch (nb) { - case 4: - start = offsetof(union data, x32.low32); - break; - case 2: - start = offsetof(union data, x16.low16); - break; - } - - ret = 0; - p = (unsigned long)addr; - - for (i = 0; i < nb; i++) - ret |= __put_user_inatomic(data.v[start + i], - SWIZ_PTR(p++)); - - if (unlikely(ret)) - return -EFAULT; - } else if (flags & F) - current->thread.TS_FPR(reg) = data.ll; - else - regs->gpr[reg] = data.ll; - - /* Update RA as needed */ - if (flags & U) - regs->gpr[areg] = regs->dar; - - return 1; + if (!r) + return 1; + return r; } diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 6e95c2c19a7e0fb8906e3f33aacd54b79514f905..8cfb20e38cfe9740c168c6389223493a034c6c5a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -746,6 +746,14 @@ int main(void) OFFSET(PACA_SUBCORE_SIBLING_MASK, paca_struct, subcore_sibling_mask); OFFSET(PACA_SIBLING_PACA_PTRS, paca_struct, thread_sibling_pacas); OFFSET(PACA_REQ_PSSCR, paca_struct, requested_psscr); +#define STOP_SPR(x, f) OFFSET(x, paca_struct, stop_sprs.f) + STOP_SPR(STOP_PID, pid); + STOP_SPR(STOP_LDBAR, ldbar); + STOP_SPR(STOP_FSCR, fscr); + STOP_SPR(STOP_HFSCR, hfscr); + STOP_SPR(STOP_MMCR1, mmcr1); + STOP_SPR(STOP_MMCR2, mmcr2); + STOP_SPR(STOP_MMCRA, mmcra); #endif DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER); diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 8275858a434d9fc2fe9ad8ba8700ac46b1e80125..3f46ca1c59f90b1a918567b868bda34cc4d00b1e 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -253,7 +253,7 @@ int __init btext_find_display(int allow_nonstdout) for_each_node_by_type(np, "display") { if (of_get_property(np, "linux,opened", NULL)) { - printk("trying %s ...\n", np->full_name); + printk("trying %pOF ...\n", np); rc = btext_initialize(np); printk("result: %d\n", rc); } diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index c641983bbdd68a646b850e42673ce6599fdbc824..a8f20e5928e132588a4387b6260ef1884a7a920e 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -167,10 +167,10 @@ static void release_cache_debugcheck(struct cache *cache) list_for_each_entry(iter, &cache_list, list) WARN_ONCE(iter->next_local == cache, - "cache for %s(%s) refers to cache for %s(%s)\n", - iter->ofnode->full_name, + "cache for %pOF(%s) refers to cache for %pOF(%s)\n", + iter->ofnode, cache_type_string(iter), - cache->ofnode->full_name, + cache->ofnode, cache_type_string(cache)); } @@ -179,8 +179,8 @@ static void release_cache(struct cache *cache) if (!cache) return; - pr_debug("freeing L%d %s cache for %s\n", cache->level, - cache_type_string(cache), cache->ofnode->full_name); + pr_debug("freeing L%d %s cache for %pOF\n", cache->level, + cache_type_string(cache), cache->ofnode); release_cache_debugcheck(cache); list_del(&cache->list); @@ -194,8 +194,8 @@ static void cache_cpu_set(struct cache *cache, int cpu) while (next) { WARN_ONCE(cpumask_test_cpu(cpu, &next->shared_cpu_map), - "CPU %i already accounted in %s(%s)\n", - cpu, next->ofnode->full_name, + "CPU %i already accounted in %pOF(%s)\n", + cpu, next->ofnode, cache_type_string(next)); cpumask_set_cpu(cpu, &next->shared_cpu_map); next = next->next_local; @@ -355,7 +355,7 @@ static int cache_is_unified_d(const struct device_node *np) */ static struct cache *cache_do_one_devnode_unified(struct device_node *node, int level) { - pr_debug("creating L%d ucache for %s\n", level, node->full_name); + pr_debug("creating L%d ucache for %pOF\n", level, node); return new_cache(cache_is_unified_d(node), level, node); } @@ -365,8 +365,8 @@ static struct cache *cache_do_one_devnode_split(struct device_node *node, { struct cache *dcache, *icache; - pr_debug("creating L%d dcache and icache for %s\n", level, - node->full_name); + pr_debug("creating L%d dcache and icache for %pOF\n", level, + node); dcache = new_cache(CACHE_TYPE_DATA, level, node); icache = new_cache(CACHE_TYPE_INSTRUCTION, level, node); @@ -679,7 +679,6 @@ static struct kobj_type cache_index_type = { static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir) { - const char *cache_name; const char *cache_type; struct cache *cache; char *buf; @@ -690,7 +689,6 @@ static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir) return; cache = dir->cache; - cache_name = cache->ofnode->full_name; cache_type = cache_type_string(cache); /* We don't want to create an attribute that can't provide a @@ -707,14 +705,14 @@ static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir) rc = attr->show(&dir->kobj, attr, buf); if (rc <= 0) { pr_debug("not creating %s attribute for " - "%s(%s) (rc = %zd)\n", - attr->attr.name, cache_name, + "%pOF(%s) (rc = %zd)\n", + attr->attr.name, cache->ofnode, cache_type, rc); continue; } if (sysfs_create_file(&dir->kobj, &attr->attr)) - pr_debug("could not create %s attribute for %s(%s)\n", - attr->attr.name, cache_name, cache_type); + pr_debug("could not create %s attribute for %pOF(%s)\n", + attr->attr.name, cache->ofnode, cache_type); } kfree(buf); @@ -831,8 +829,8 @@ static void cache_cpu_clear(struct cache *cache, int cpu) struct cache *next = cache->next_local; WARN_ONCE(!cpumask_test_cpu(cpu, &cache->shared_cpu_map), - "CPU %i not accounted in %s(%s)\n", - cpu, cache->ofnode->full_name, + "CPU %i not accounted in %pOF(%s)\n", + cpu, cache->ofnode, cache_type_string(cache)); cpumask_clear_cpu(cpu, &cache->shared_cpu_map); diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 6f849832a66914f520d59c38a3c6c28f405de904..760872916013dc24ed009248a9b64717f339952d 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1259,10 +1259,10 @@ static struct cpu_spec __initdata cpu_specs[] = { .platform = "ppc603", }, #endif /* CONFIG_PPC_BOOK3S_32 */ -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx { /* 8xx */ .pvr_mask = 0xffff0000, - .pvr_value = 0x00500000, + .pvr_value = PVR_8xx, .cpu_name = "8xx", /* CPU_FTR_MAYBE_CAN_DOZE is possible, * if the 8xx code is there.... */ @@ -1274,7 +1274,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_8xx, .platform = "ppc823", }, -#endif /* CONFIG_8xx */ +#endif /* CONFIG_PPC_8xx */ #ifdef CONFIG_40x { /* 403GC */ .pvr_mask = 0xffffff00, @@ -1936,6 +1936,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, +#ifdef CONFIG_PPC_47x { /* 476 DD2 core */ .pvr_mask = 0xffffffff, .pvr_value = 0x11a52080, @@ -1992,6 +1993,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_47x, .platform = "ppc470", }, +#endif /* CONFIG_PPC_47x */ { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 1df770e8cbe03194f31576cff264fdedbb1aa517..7275fed271afa601711b2f43b0da2c2377c68eff 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -102,10 +102,10 @@ static void cpufeatures_flush_tlb(void) case PVR_POWER8: case PVR_POWER8E: case PVR_POWER8NVL: - __flush_tlb_power8(POWER8_TLB_SETS); + __flush_tlb_power8(TLB_INVAL_SCOPE_GLOBAL); break; case PVR_POWER9: - __flush_tlb_power9(POWER9_TLB_SETS_HASH); + __flush_tlb_power9(TLB_INVAL_SCOPE_GLOBAL); break; default: pr_err("unknown CPU version for boot TLB flush\n"); diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 63992b2d8e15684a17e05981fbfd8260ee45af50..116000b4553195f44adabf2894b002fcd5e6d6e1 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -44,6 +44,7 @@ #include #include #include +#include /** Overview: @@ -169,10 +170,10 @@ static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len) char buffer[128]; n += scnprintf(buf+n, len-n, "%04x:%02x:%02x.%01x\n", - edev->phb->global_number, pdn->busno, + pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); pr_warn("EEH: of node=%04x:%02x:%02x.%01x\n", - edev->phb->global_number, pdn->busno, + pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); eeh_ops->read_config(pdn, PCI_VENDOR_ID, 4, &cfg); @@ -352,8 +353,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) * worried about _PAGE_SPLITTING/collapse. Also we will not hit * page table free, because of init_mm. */ - ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token, - NULL, &hugepage_shift); + ptep = find_init_mm_pte(token, &hugepage_shift); if (!ptep) return token; WARN_ON(hugepage_shift); @@ -435,7 +435,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) int ret; int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); unsigned long flags; - struct pci_dn *pdn; + struct device_node *dn; struct pci_dev *dev; struct eeh_pe *pe, *parent_pe, *phb_pe; int rc = 0; @@ -493,9 +493,10 @@ int eeh_dev_check_failure(struct eeh_dev *edev) if (pe->state & EEH_PE_ISOLATED) { pe->check_count++; if (pe->check_count % EEH_MAX_FAILS == 0) { - pdn = eeh_dev_to_pdn(edev); - if (pdn->node) - location = of_get_property(pdn->node, "ibm,loc-code", NULL); + dn = pci_device_to_OF_node(dev); + if (dn) + location = of_get_property(dn, "ibm,loc-code", + NULL); printk(KERN_ERR "EEH: %d reads ignored for recovering device at " "location=%s driver=%s pci addr=%s\n", pe->check_count, @@ -1018,6 +1019,10 @@ int eeh_init(void) } else if ((ret = eeh_ops->init())) return ret; + /* Initialize PHB PEs */ + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + eeh_dev_phb_init_dynamic(hose); + /* Initialize EEH event */ ret = eeh_event_init(); if (ret) @@ -1064,7 +1069,7 @@ core_initcall_sync(eeh_init); */ void eeh_add_device_early(struct pci_dn *pdn) { - struct pci_controller *phb; + struct pci_controller *phb = pdn ? pdn->phb : NULL; struct eeh_dev *edev = pdn_to_eeh_dev(pdn); if (!edev) @@ -1074,7 +1079,6 @@ void eeh_add_device_early(struct pci_dn *pdn) return; /* USB Bus children of PCI devices will not have BUID's */ - phb = edev->phb; if (NULL == phb || (eeh_has_flag(EEH_PROBE_MODE_DEVTREE) && 0 == phb->buid)) return; diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c index d6b2ca70d14d7046637967646f9210ca52c2e2d3..a34e6912c15e2a027c55b3ef1802d22792cac5f9 100644 --- a/arch/powerpc/kernel/eeh_dev.c +++ b/arch/powerpc/kernel/eeh_dev.c @@ -50,21 +50,16 @@ */ struct eeh_dev *eeh_dev_init(struct pci_dn *pdn) { - struct pci_controller *phb = pdn->phb; struct eeh_dev *edev; /* Allocate EEH device */ edev = kzalloc(sizeof(*edev), GFP_KERNEL); - if (!edev) { - pr_warn("%s: out of memory\n", - __func__); + if (!edev) return NULL; - } /* Associate EEH device with OF node */ pdn->edev = edev; edev->pdn = pdn; - edev->phb = phb; INIT_LIST_HEAD(&edev->list); INIT_LIST_HEAD(&edev->rmv_list); @@ -83,21 +78,3 @@ void eeh_dev_phb_init_dynamic(struct pci_controller *phb) /* EEH PE for PHB */ eeh_phb_pe_create(phb); } - -/** - * eeh_dev_phb_init - Create EEH devices for devices included in existing PHBs - * - * Scan all the existing PHBs and create EEH devices for their OF - * nodes and their children OF nodes - */ -static int __init eeh_dev_phb_init(void) -{ - struct pci_controller *phb, *tmp; - - list_for_each_entry_safe(phb, tmp, &hose_list, list_node) - eeh_dev_phb_init_dynamic(phb); - - return 0; -} - -core_initcall(eeh_dev_phb_init); diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index c405c79e50cdc99267e0fe1bb08aff4578064ce8..8b840191df59680b7030f3202d1b83571c7d8f6a 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -428,7 +428,7 @@ static void *eeh_add_virt_device(void *data, void *userdata) if (!(edev->physfn)) { pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n", - __func__, edev->phb->global_number, pdn->busno, + __func__, pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); return NULL; } diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index cc4b206f77e422872e8e0691d2cc90900509d91e..2e8d1b2b5af4571132c38593ef1ca160347efecf 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -230,10 +230,15 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root, * Bus/Device/Function number. The extra data referred by flag * indicates which type of address should be used. */ +struct eeh_pe_get_flag { + int pe_no; + int config_addr; +}; + static void *__eeh_pe_get(void *data, void *flag) { struct eeh_pe *pe = (struct eeh_pe *)data; - struct eeh_dev *edev = (struct eeh_dev *)flag; + struct eeh_pe_get_flag *tmp = (struct eeh_pe_get_flag *) flag; /* Unexpected PHB PE */ if (pe->type & EEH_PE_PHB) @@ -244,17 +249,17 @@ static void *__eeh_pe_get(void *data, void *flag) * have non-zero PE address */ if (eeh_has_flag(EEH_VALID_PE_ZERO)) { - if (edev->pe_config_addr == pe->addr) + if (tmp->pe_no == pe->addr) return pe; } else { - if (edev->pe_config_addr && - (edev->pe_config_addr == pe->addr)) + if (tmp->pe_no && + (tmp->pe_no == pe->addr)) return pe; } /* Try BDF address */ - if (edev->config_addr && - (edev->config_addr == pe->config_addr)) + if (tmp->config_addr && + (tmp->config_addr == pe->config_addr)) return pe; return NULL; @@ -262,7 +267,9 @@ static void *__eeh_pe_get(void *data, void *flag) /** * eeh_pe_get - Search PE based on the given address - * @edev: EEH device + * @phb: PCI controller + * @pe_no: PE number + * @config_addr: Config address * * Search the corresponding PE based on the specified address which * is included in the eeh device. The function is used to check if @@ -271,12 +278,14 @@ static void *__eeh_pe_get(void *data, void *flag) * which is composed of PCI bus/device/function number, or unified * PE address. */ -struct eeh_pe *eeh_pe_get(struct eeh_dev *edev) +struct eeh_pe *eeh_pe_get(struct pci_controller *phb, + int pe_no, int config_addr) { - struct eeh_pe *root = eeh_phb_pe_get(edev->phb); + struct eeh_pe *root = eeh_phb_pe_get(phb); + struct eeh_pe_get_flag tmp = { pe_no, config_addr }; struct eeh_pe *pe; - pe = eeh_pe_traverse(root, __eeh_pe_get, edev); + pe = eeh_pe_traverse(root, __eeh_pe_get, &tmp); return pe; } @@ -330,11 +339,13 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev) int eeh_add_to_parent_pe(struct eeh_dev *edev) { struct eeh_pe *pe, *parent; + struct pci_dn *pdn = eeh_dev_to_pdn(edev); + int config_addr = (pdn->busno << 8) | (pdn->devfn); /* Check if the PE number is valid */ if (!eeh_has_flag(EEH_VALID_PE_ZERO) && !edev->pe_config_addr) { pr_err("%s: Invalid PE#0 for edev 0x%x on PHB#%x\n", - __func__, edev->config_addr, edev->phb->global_number); + __func__, config_addr, pdn->phb->global_number); return -EINVAL; } @@ -344,7 +355,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) * PE should be composed of PCI bus and its subordinate * components. */ - pe = eeh_pe_get(edev); + pe = eeh_pe_get(pdn->phb, edev->pe_config_addr, config_addr); if (pe && !(pe->type & EEH_PE_INVALID)) { /* Mark the PE as type of PCI bus */ pe->type = EEH_PE_BUS; @@ -353,11 +364,11 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) /* Put the edev to PE */ list_add_tail(&edev->list, &pe->edevs); pr_debug("EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x\n", - edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF), - pe->addr); + pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn), + pe->addr); return 0; } else if (pe && (pe->type & EEH_PE_INVALID)) { list_add_tail(&edev->list, &pe->edevs); @@ -376,25 +387,25 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) pr_debug("EEH: Add %04x:%02x:%02x.%01x to Device " "PE#%x, Parent PE#%x\n", - edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF), - pe->addr, pe->parent->addr); + pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn), + pe->addr, pe->parent->addr); return 0; } /* Create a new EEH PE */ if (edev->physfn) - pe = eeh_pe_alloc(edev->phb, EEH_PE_VF); + pe = eeh_pe_alloc(pdn->phb, EEH_PE_VF); else - pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); + pe = eeh_pe_alloc(pdn->phb, EEH_PE_DEVICE); if (!pe) { pr_err("%s: out of memory!\n", __func__); return -ENOMEM; } pe->addr = edev->pe_config_addr; - pe->config_addr = edev->config_addr; + pe->config_addr = config_addr; /* * Put the new EEH PE into hierarchy tree. If the parent @@ -404,10 +415,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) */ parent = eeh_pe_get_parent(edev); if (!parent) { - parent = eeh_phb_pe_get(edev->phb); + parent = eeh_phb_pe_get(pdn->phb); if (!parent) { pr_err("%s: No PHB PE is found (PHB Domain=%d)\n", - __func__, edev->phb->global_number); + __func__, pdn->phb->global_number); edev->pe = NULL; kfree(pe); return -EEXIST; @@ -424,10 +435,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) edev->pe = pe; pr_debug("EEH: Add %04x:%02x:%02x.%01x to " "Device PE#%x, Parent PE#%x\n", - edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF), + pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn), pe->addr, pe->parent->addr); return 0; @@ -446,13 +457,14 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev) { struct eeh_pe *pe, *parent, *child; int cnt; + struct pci_dn *pdn = eeh_dev_to_pdn(edev); if (!edev->pe) { pr_debug("%s: No PE found for device %04x:%02x:%02x.%01x\n", - __func__, edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF)); + __func__, pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn)); return -EEXIST; } @@ -712,10 +724,10 @@ static void eeh_bridge_check_link(struct eeh_dev *edev) return; pr_debug("%s: Check PCIe link for %04x:%02x:%02x.%01x ...\n", - __func__, edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF)); + __func__, pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn)); /* Check slot status */ cap = edev->pcie_cap; diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index 1ceecdda810b04722b88329d52b866c3c540ad0e..797549289798b33bf2e867c23d3047cf342e89f1 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c @@ -51,7 +51,6 @@ static ssize_t eeh_show_##_name(struct device *dev, \ static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL); EEH_SHOW_ATTR(eeh_mode, mode, "0x%x"); -EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); static ssize_t eeh_pe_state_show(struct device *dev, @@ -103,7 +102,6 @@ void eeh_sysfs_add_device(struct pci_dev *pdev) return; rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); - rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_state); @@ -128,7 +126,6 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev) } device_remove_file(&pdev->dev, &dev_attr_eeh_mode); - device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state); diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 8587059ad84830a4e4b2cb45749782228e7b1571..e780e1fbf6c2123d5170de951a696e53c29fdf66 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -43,6 +43,13 @@ #define LOAD_MSR_KERNEL(r, x) li r,(x) #endif +/* + * Align to 4k in order to ensure that all functions modyfing srr0/srr1 + * fit into one page in order to not encounter a TLB miss between the + * modification of srr0/srr1 and the associated rfi. + */ + .align 12 + #ifdef CONFIG_BOOKE .globl mcheck_transfer_to_handler mcheck_transfer_to_handler: @@ -586,6 +593,10 @@ ppc_swapcontext: handle_page_fault: stw r4,_DAR(r1) addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_6xx + andis. r0,r5,DSISR_DABRMATCH@h + bne- handle_dabr_fault +#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except @@ -599,6 +610,17 @@ handle_page_fault: bl bad_page_fault b ret_from_except_full +#ifdef CONFIG_6xx + /* We have a data breakpoint exception - handle it */ +handle_dabr_fault: + SAVE_NVGPRS(r1) + lwz r0,_TRAP(r1) + clrrwi r0,r0,1 + stw r0,_TRAP(r1) + bl do_break + b ret_from_except_full +#endif + /* * This routine switches between two different tasks. The process * state of one is saved on its kernel stack. Then the state diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 49d8422767b4de686ec0ee64fbf69ac415f05003..4a0fd4f4024533c473f5cfe6f015924e29ed4acc 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -223,17 +223,27 @@ system_call_exit: andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) bne- .Lsyscall_exit_work - /* If MSR_FP and MSR_VEC are set in user msr, then no need to restore */ - li r7,MSR_FP + andi. r0,r8,MSR_FP + beq 2f #ifdef CONFIG_ALTIVEC - oris r7,r7,MSR_VEC@h + andis. r0,r8,MSR_VEC@h + bne 3f #endif - and r0,r8,r7 - cmpd r0,r7 - bne .Lsyscall_restore_math -.Lsyscall_restore_math_cont: +2: addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_PPC_BOOK3S + li r10,MSR_RI + mtmsrd r10,1 /* Restore RI */ +#endif + bl restore_math +#ifdef CONFIG_PPC_BOOK3S + li r11,0 + mtmsrd r11,1 +#endif + ld r8,_MSR(r1) + ld r3,RESULT(r1) + li r11,-MAX_ERRNO - cmpld r3,r11 +3: cmpld r3,r11 ld r5,_CCR(r1) bge- .Lsyscall_error .Lsyscall_error_cont: @@ -267,40 +277,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) std r5,_CCR(r1) b .Lsyscall_error_cont -.Lsyscall_restore_math: - /* - * Some initial tests from restore_math to avoid the heavyweight - * C code entry and MSR manipulations. - */ - LOAD_REG_IMMEDIATE(r0, MSR_TS_MASK) - and. r0,r0,r8 - bne 1f - - ld r7,PACACURRENT(r13) - lbz r0,THREAD+THREAD_LOAD_FP(r7) -#ifdef CONFIG_ALTIVEC - lbz r6,THREAD+THREAD_LOAD_VEC(r7) - add r0,r0,r6 -#endif - cmpdi r0,0 - beq .Lsyscall_restore_math_cont - -1: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S - li r10,MSR_RI - mtmsrd r10,1 /* Restore RI */ -#endif - bl restore_math -#ifdef CONFIG_PPC_BOOK3S - li r11,0 - mtmsrd r11,1 -#endif - /* Restore volatiles, reload MSR from updated one */ - ld r8,_MSR(r1) - ld r3,RESULT(r1) - li r11,-MAX_ERRNO - b .Lsyscall_restore_math_cont - /* Traced system call support */ .Lsyscall_dotrace: bl save_nvgprs @@ -990,16 +966,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) #ifdef CONFIG_PPC_BOOK3E cmpwi cr0,r3,0x280 #else - BEGIN_FTR_SECTION - cmpwi cr0,r3,0xe80 - FTR_SECTION_ELSE - cmpwi cr0,r3,0xa00 - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) + cmpwi cr0,r3,0xa00 #endif /* CONFIG_PPC_BOOK3E */ bne 1f addi r3,r1,STACK_FRAME_OVERHEAD; bl doorbell_exception - b ret_from_except #endif /* CONFIG_PPC_DOORBELL */ 1: b ret_from_except /* What else to do here ? */ @@ -1133,7 +1104,7 @@ _ASM_NOKPROBE_SYMBOL(__enter_rtas) _ASM_NOKPROBE_SYMBOL(rtas_return_loc) .align 3 -1: .llong rtas_restore_regs +1: .8byte rtas_restore_regs rtas_restore_regs: /* relocation is on at this point */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 9029afd1fa2ab2ce231045659abf11ec9eaa32f6..48da0f5d2f7fe0a4745bce864795df16d612a89e 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -541,7 +541,7 @@ EXC_COMMON_BEGIN(instruction_access_common) RECONCILE_IRQ_STATE(r10, r11) ld r12,_MSR(r1) ld r3,_NIP(r1) - andis. r4,r12,0x5820 + andis. r4,r12,DSISR_BAD_FAULT_64S@h li r5,0x400 std r3,_DAR(r1) std r4,_DSISR(r1) @@ -1314,7 +1314,7 @@ EXC_REAL_NONE(0x1800, 0x100) EXC_VIRT_NONE(0x5800, 0x100) #endif -#if defined(CONFIG_HARDLOCKUP_DETECTOR) && defined(CONFIG_HAVE_HARDLOCKUP_DETECTOR_ARCH) +#ifdef CONFIG_PPC_WATCHDOG #define MASKED_DEC_HANDLER_LABEL 3f @@ -1325,20 +1325,28 @@ EXC_VIRT_NONE(0x5800, 0x100) std r10,PACA_EXGEN+EX_R13(r13); \ EXCEPTION_PROLOG_PSERIES_1(soft_nmi_common, _H) +/* + * Branch to soft_nmi_interrupt using the emergency stack. The emergency + * stack is one that is usable by maskable interrupts so long as MSR_EE + * remains off. It is used for recovery when something has corrupted the + * normal kernel stack, for example. The "soft NMI" must not use the process + * stack because we want irq disabled sections to avoid touching the stack + * at all (other than PMU interrupts), so use the emergency stack for this, + * and run it entirely with interrupts hard disabled. + */ EXC_COMMON_BEGIN(soft_nmi_common) mr r10,r1 ld r1,PACAEMERGSP(r13) - ld r1,PACA_NMI_EMERG_SP(r13) subi r1,r1,INT_FRAME_SIZE EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900, system_reset, soft_nmi_interrupt, ADD_NVGPRS;ADD_RECONCILE) b ret_from_except -#else +#else /* CONFIG_PPC_WATCHDOG */ #define MASKED_DEC_HANDLER_LABEL 2f /* normal return */ #define MASKED_DEC_HANDLER(_H) -#endif +#endif /* CONFIG_PPC_WATCHDOG */ /* * An interrupt came in while soft-disabled. We set paca->irq_happened, then: @@ -1362,19 +1370,16 @@ masked_##_H##interrupt: \ ori r10,r10,0xffff; \ mtspr SPRN_DEC,r10; \ b MASKED_DEC_HANDLER_LABEL; \ -1: cmpwi r10,PACA_IRQ_DBELL; \ - beq 2f; \ - cmpwi r10,PACA_IRQ_HMI; \ - beq 2f; \ +1: andi. r10,r10,(PACA_IRQ_DBELL|PACA_IRQ_HMI); \ + bne 2f; \ mfspr r10,SPRN_##_H##SRR1; \ - rldicl r10,r10,48,1; /* clear MSR_EE */ \ - rotldi r10,r10,16; \ + xori r10,r10,MSR_EE; /* clear MSR_EE */ \ mtspr SPRN_##_H##SRR1,r10; \ 2: mtcrf 0x80,r9; \ ld r9,PACA_EXGEN+EX_R9(r13); \ ld r10,PACA_EXGEN+EX_R10(r13); \ ld r11,PACA_EXGEN+EX_R11(r13); \ - GET_SCRATCH0(r13); \ + /* returns to kernel where r13 must be set up, so don't restore it */ \ ##_H##rfid; \ b .; \ MASKED_DEC_HANDLER(_H) @@ -1477,8 +1482,10 @@ USE_TEXT_SECTION() */ .balign IFETCH_ALIGN_BYTES do_hash_page: -#ifdef CONFIG_PPC_STD_MMU_64 - andis. r0,r4,0xa450 /* weird error? */ + #ifdef CONFIG_PPC_STD_MMU_64 + lis r0,DSISR_BAD_FAULT_64S@h + ori r0,r0,DSISR_BAD_FAULT_64S@l + and. r0,r4,r0 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */ CURRENT_THREAD_INFO(r11, r1) lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ @@ -1661,25 +1668,27 @@ _GLOBAL(__replay_interrupt) * we don't give a damn about, so we don't bother storing them. */ mfmsr r12 - LOAD_REG_ADDR(r11, 1f) + LOAD_REG_ADDR(r11, replay_interrupt_return) mfcr r9 ori r12,r12,MSR_EE cmpwi r3,0x900 beq decrementer_common cmpwi r3,0x500 +BEGIN_FTR_SECTION + beq h_virt_irq_common +FTR_SECTION_ELSE beq hardware_interrupt_common +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_300) BEGIN_FTR_SECTION - cmpwi r3,0xe80 + cmpwi r3,0xa00 beq h_doorbell_common_msgclr - cmpwi r3,0xea0 - beq h_virt_irq_common cmpwi r3,0xe60 beq hmi_exception_common FTR_SECTION_ELSE cmpwi r3,0xa00 beq doorbell_super_common_msgclr ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) -1: +replay_interrupt_return: blr _ASM_NOKPROBE_SYMBOL(__replay_interrupt) diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index dc0c49cfd90a093aba02fc3f8931e87d687380a7..e1431800bfb9f7ed85a87ef6a1886901917a706b 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -125,6 +125,13 @@ int is_fadump_boot_memory_area(u64 addr, ulong size) return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size; } +int should_fadump_crash(void) +{ + if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr) + return 0; + return 1; +} + int is_fadump_active(void) { return fw_dump.dump_active; @@ -518,7 +525,7 @@ void crash_fadump(struct pt_regs *regs, const char *str) struct fadump_crash_info_header *fdh = NULL; int old_cpu, this_cpu; - if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr) + if (!should_fadump_crash()) return; /* @@ -1446,6 +1453,25 @@ static void fadump_init_files(void) return; } +static int fadump_panic_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + /* + * If firmware-assisted dump has been registered then trigger + * firmware-assisted dump and let firmware handle everything + * else. If this returns, then fadump was not registered, so + * go through the rest of the panic path. + */ + crash_fadump(NULL, ptr); + + return NOTIFY_DONE; +} + +static struct notifier_block fadump_panic_block = { + .notifier_call = fadump_panic_event, + .priority = INT_MIN /* may not return; must be done last */ +}; + /* * Prepare for firmware-assisted dump. */ @@ -1478,6 +1504,9 @@ int __init setup_fadump(void) init_fadump_mem_struct(&fdm, fw_dump.reserve_dump_area_start); fadump_init_files(); + atomic_notifier_chain_register(&panic_notifier_list, + &fadump_panic_block); + return 1; } subsys_initcall(setup_fadump); diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index e22734278458d567f85e6d071fee8fad2b282776..8c54166491e7cf7f8ea19cbd28a8e85943dbfa3f 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -388,7 +388,7 @@ DataAccess: EXCEPTION_PROLOG mfspr r10,SPRN_DSISR stw r10,_DSISR(r11) - andis. r0,r10,0xa470 /* weird error? */ + andis. r0,r10,DSISR_BAD_FAULT_32S@h bne 1f /* if not, try to put a PTE */ mfspr r4,SPRN_DAR /* into the hash table */ rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ @@ -403,13 +403,13 @@ DataAccess: DO_KVM 0x400 InstructionAccess: EXCEPTION_PROLOG - andis. r0,r9,0x4000 /* no pte found? */ + andis. r0,r9,SRR1_ISI_NOPT@h /* no pte found? */ beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ mr r4,r12 /* SRR0 is fault address */ bl hash_page 1: mr r4,r12 - mr r5,r9 + andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ EXC_XFER_LITE(0x400, handle_page_fault) /* External interrupt */ diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 0ddc602b33a4dcad12e935c197a5f944617e5935..ff8511d6d8eadbd03e48ce9c0b639c8d3c80e8aa 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -92,13 +92,13 @@ END_FTR_SECTION(0, 1) .balign 8 .globl __secondary_hold_spinloop __secondary_hold_spinloop: - .llong 0x0 + .8byte 0x0 /* Secondary processors write this value with their cpu # */ /* after they enter the spin loop immediately below. */ .globl __secondary_hold_acknowledge __secondary_hold_acknowledge: - .llong 0x0 + .8byte 0x0 #ifdef CONFIG_RELOCATABLE /* This flag is set to 1 by a loader if the kernel should run @@ -650,7 +650,7 @@ __after_prom_start: bctr .balign 8 -p_end: .llong _end - copy_to_here +p_end: .8byte _end - copy_to_here 4: /* @@ -892,7 +892,7 @@ _GLOBAL(relative_toc) blr .balign 8 -p_toc: .llong __toc_start + 0x8000 - 0b +p_toc: .8byte __toc_start + 0x8000 - 0b /* * This is where the main kernel code starts. diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index c032fe8c2d26e49f5be446060556229542992ca2..4fee00d414e87c78d8a09ef3e9662b7bb7234c66 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -50,18 +50,20 @@ mtspr spr, reg #endif -/* Macro to test if an address is a kernel address */ #if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000 -#define IS_KERNEL(tmp, addr) \ - andis. tmp, addr, 0x8000 /* Address >= 0x80000000 */ -#define BRANCH_UNLESS_KERNEL(label) beq label -#else -#define IS_KERNEL(tmp, addr) \ - rlwinm tmp, addr, 16, 16, 31; \ - cmpli cr0, tmp, PAGE_OFFSET >> 16 -#define BRANCH_UNLESS_KERNEL(label) blt label +/* By simply checking Address >= 0x80000000, we know if its a kernel address */ +#define SIMPLE_KERNEL_ADDRESS 1 #endif +/* + * We need an ITLB miss handler for kernel addresses if: + * - Either we have modules + * - Or we have not pinned the first 8M + */ +#if defined(CONFIG_MODULES) || !defined(CONFIG_PIN_TLB_TEXT) || \ + defined(CONFIG_DEBUG_PAGEALLOC) +#define ITLB_MISS_KERNEL 1 +#endif /* * Value for the bits that have fixed value in RPN entries. @@ -123,7 +125,6 @@ turn_on_mmu: lis r0,start_here@h ori r0,r0,start_here@l mtspr SPRN_SRR0,r0 - SYNC rfi /* enables MMU */ /* @@ -170,7 +171,7 @@ turn_on_mmu: stw r1,0(r11); \ tovirt(r1,r11); /* set new kernel sp */ \ li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ - MTMSRD(r10); /* (except for mach check in rtas) */ \ + mtmsr r10; \ stw r0,GPR0(r11); \ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) @@ -300,7 +301,7 @@ SystemCall: /* On the MPC8xx, this is a software emulation interrupt. It occurs * for all unimplemented and illegal instructions. */ - EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD) + EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD) . = 0x1100 /* @@ -325,7 +326,7 @@ SystemCall: #endif InstructionTLBMiss: -#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(CONFIG_8xx_CPU6) || defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mtspr SPRN_SPRG_SCRATCH2, r3 #endif EXCEPTION_PROLOG_0 @@ -343,15 +344,32 @@ InstructionTLBMiss: INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10) /* Only modules will cause ITLB Misses as we always * pin the first 8MB of kernel memory */ -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mfcr r3 #endif -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) - IS_KERNEL(r11, r10) +#ifdef ITLB_MISS_KERNEL +#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) + andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ +#else + rlwinm r11, r10, 16, 0xfff8 + cmpli cr0, r11, PAGE_OFFSET@h +#ifndef CONFIG_PIN_TLB_TEXT + /* It is assumed that kernel code fits into the first 8M page */ +_ENTRY(ITLBMiss_cmp) + cmpli cr7, r11, (PAGE_OFFSET + 0x0800000)@h +#endif +#endif #endif mfspr r11, SPRN_M_TW /* Get level 1 table */ -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) - BRANCH_UNLESS_KERNEL(3f) +#ifdef ITLB_MISS_KERNEL +#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) + beq+ 3f +#else + blt+ 3f +#endif +#ifndef CONFIG_PIN_TLB_TEXT + blt cr7, ITLBMissLinear +#endif lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha 3: #endif @@ -369,7 +387,7 @@ InstructionTLBMiss: rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */ lwz r10, 0(r10) /* Get the pte */ 4: -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mtcr r3 #endif /* Insert the APG into the TWC from the Linux PTE. */ @@ -400,7 +418,7 @@ InstructionTLBMiss: MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */ /* Restore registers */ -#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(CONFIG_8xx_CPU6) || defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mfspr r3, SPRN_SPRG_SCRATCH2 #endif EXCEPTION_EPILOG_0 @@ -447,23 +465,23 @@ DataStoreTLBMiss: * kernel page tables. */ mfspr r10, SPRN_MD_EPN - rlwinm r10, r10, 16, 0xfff8 - cmpli cr0, r10, PAGE_OFFSET@h + rlwinm r11, r10, 16, 0xfff8 + cmpli cr0, r11, PAGE_OFFSET@h mfspr r11, SPRN_M_TW /* Get level 1 table */ blt+ 3f + rlwinm r11, r10, 16, 0xfff8 #ifndef CONFIG_PIN_TLB_IMMR - cmpli cr0, r10, VIRT_IMMR_BASE@h + cmpli cr0, r11, VIRT_IMMR_BASE@h #endif _ENTRY(DTLBMiss_cmp) - cmpli cr7, r10, (PAGE_OFFSET + 0x1800000)@h - lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha + cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h #ifndef CONFIG_PIN_TLB_IMMR _ENTRY(DTLBMiss_jmp) beq- DTLBMissIMMR #endif blt cr7, DTLBMissLinear + lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha 3: - mfspr r10, SPRN_MD_EPN /* Insert level 1 index */ rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 @@ -569,8 +587,8 @@ _ENTRY(DTLBMiss_jmp) InstructionTLBError: EXCEPTION_PROLOG mr r4,r12 - mr r5,r9 - andis. r10,r5,0x4000 + andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ + andis. r10,r9,SRR1_ISI_NOPT@h beq+ 1f tlbie r4 itlbie: @@ -595,7 +613,7 @@ DARFixed:/* Return from dcbx instruction bug workaround */ mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) mfspr r4,SPRN_DAR - andis. r10,r5,0x4000 + andis. r10,r5,DSISR_NOHPTE@h beq+ 1f tlbie r4 dtlbie: @@ -684,7 +702,7 @@ DTLBMissLinear: /* Set 8M byte page and mark it valid */ li r11, MD_PS8MEG | MD_SVALID MTSPR_CPU6(SPRN_MD_TWC, r11, r3) - rlwinm r10, r10, 16, 0x0f800000 /* 8xx supports max 256Mb RAM */ + rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ _PAGE_PRESENT MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */ @@ -695,6 +713,22 @@ DTLBMissLinear: EXCEPTION_EPILOG_0 rfi +#ifndef CONFIG_PIN_TLB_TEXT +ITLBMissLinear: + mtcr r3 + /* Set 8M byte page and mark it valid */ + li r11, MI_PS8MEG | MI_SVALID | _PAGE_EXEC + MTSPR_CPU6(SPRN_MI_TWC, r11, r3) + rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ + ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ + _PAGE_PRESENT + MTSPR_CPU6(SPRN_MI_RPN, r10, r11) /* Update TLB entry */ + + mfspr r3, SPRN_SPRG_SCRATCH2 + EXCEPTION_EPILOG_0 + rfi +#endif + /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions * by decoding the registers used by the dcbx instruction and adding them. * DAR is set to the calculated address. @@ -705,9 +739,10 @@ FixupDAR:/* Entry point for dcbx workaround. */ mtspr SPRN_SPRG_SCRATCH2, r10 /* fetch instruction from memory. */ mfspr r10, SPRN_SRR0 - IS_KERNEL(r11, r10) + rlwinm r11, r10, 16, 0xfff8 + cmpli cr0, r11, PAGE_OFFSET@h mfspr r11, SPRN_M_TW /* Get level 1 table */ - BRANCH_UNLESS_KERNEL(3f) + blt+ 3f rlwinm r11, r10, 16, 0xfff8 _ENTRY(FixupDAR_cmp) cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h @@ -915,10 +950,8 @@ start_here: rfi /* Load up the kernel context */ 2: - SYNC /* Force all PTE updates to finish */ tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ - TLBSYNC /* ... on all CPUs */ /* set up the PTE pointers for the Abatron bdiGDB. */ @@ -955,15 +988,14 @@ initial_mmu: mtspr SPRN_MD_CTR, r10 /* remove PINNED DTLB entries */ tlbia /* Invalidate all TLB entries */ -/* Always pin the first 8 MB ITLB to prevent ITLB - misses while mucking around with SRR0/SRR1 in asm -*/ +#ifdef CONFIG_PIN_TLB_TEXT lis r8, MI_RSV4I@h ori r8, r8, 0x1c00 mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ +#endif -#ifdef CONFIG_PIN_TLB +#ifdef CONFIG_PIN_TLB_DATA oris r10, r10, MD_RSV4I@h mtspr SPRN_MD_CTR, r10 /* Set data TLB control */ #endif @@ -989,6 +1021,7 @@ initial_mmu: * internal registers (among other things). */ #ifdef CONFIG_PIN_TLB_IMMR + oris r10, r10, MD_RSV4I@h ori r10, r10, 0x1c00 mtspr SPRN_MD_CTR, r10 diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 516ebef905c063b6bdb696f5f6048da37f7822cd..1125c9be9e067683c43c583d1672b1b6d3269840 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -85,7 +85,61 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300) std r3,_WORT(r1) mfspr r3,SPRN_WORC std r3,_WORC(r1) +/* + * On POWER9, there are idle states such as stop4, invoked via cpuidle, + * that lose hypervisor resources. In such cases, we need to save + * additional SPRs before entering those idle states so that they can + * be restored to their older values on wakeup from the idle state. + * + * On POWER8, the only such deep idle state is winkle which is used + * only in the context of CPU-Hotplug, where these additional SPRs are + * reinitiazed to a sane value. Hence there is no need to save/restore + * these SPRs. + */ +BEGIN_FTR_SECTION + blr +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) + +power9_save_additional_sprs: + mfspr r3, SPRN_PID + mfspr r4, SPRN_LDBAR + std r3, STOP_PID(r13) + std r4, STOP_LDBAR(r13) + mfspr r3, SPRN_FSCR + mfspr r4, SPRN_HFSCR + std r3, STOP_FSCR(r13) + std r4, STOP_HFSCR(r13) + + mfspr r3, SPRN_MMCRA + mfspr r4, SPRN_MMCR1 + std r3, STOP_MMCRA(r13) + std r4, STOP_MMCR1(r13) + + mfspr r3, SPRN_MMCR2 + std r3, STOP_MMCR2(r13) + blr + +power9_restore_additional_sprs: + ld r3,_LPCR(r1) + ld r4, STOP_PID(r13) + mtspr SPRN_LPCR,r3 + mtspr SPRN_PID, r4 + + ld r3, STOP_LDBAR(r13) + ld r4, STOP_FSCR(r13) + mtspr SPRN_LDBAR, r3 + mtspr SPRN_FSCR, r4 + + ld r3, STOP_HFSCR(r13) + ld r4, STOP_MMCRA(r13) + mtspr SPRN_HFSCR, r3 + mtspr SPRN_MMCRA, r4 + /* We have already restored PACA_MMCR0 */ + ld r3, STOP_MMCR1(r13) + ld r4, STOP_MMCR2(r13) + mtspr SPRN_MMCR1, r3 + mtspr SPRN_MMCR2, r4 blr /* @@ -141,7 +195,16 @@ pnv_powersave_common: std r5,_CCR(r1) std r1,PACAR1(r13) +BEGIN_FTR_SECTION + /* + * POWER9 does not require real mode to stop, and presently does not + * set hwthread_state for KVM (threads don't share MMU context), so + * we can remain in virtual mode for this. + */ + bctr +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) /* + * POWER8 * Go to real mode to do the nap, as required by the architecture. * Also, we need to be in real mode before setting hwthread_state, * because as soon as we do that, another thread can switch @@ -151,6 +214,20 @@ pnv_powersave_common: mtmsrd r7,0 bctr +/* + * This is the sequence required to execute idle instructions, as + * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0. + */ +#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ + /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ + std r0,0(r1); \ + ptesync; \ + ld r0,0(r1); \ +236: cmpd cr0,r0,r0; \ + bne 236b; \ + IDLE_INST; + + .globl pnv_enter_arch207_idle_mode pnv_enter_arch207_idle_mode: #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE @@ -242,20 +319,27 @@ enter_winkle: /* * r3 - PSSCR value corresponding to the requested stop state. */ -power_enter_stop: #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE - /* Tell KVM we're entering idle */ +power_enter_stop_kvm_rm: + /* + * This is currently unused because POWER9 KVM does not have to + * gather secondary threads into sibling mode, but the code is + * here in case that function is required. + * + * Tell KVM we're entering idle. + */ li r4,KVM_HWTHREAD_IN_IDLE /* DO THIS IN REAL MODE! See comment above. */ stb r4,HSTATE_HWTHREAD_STATE(r13) #endif +power_enter_stop: /* * Check if we are executing the lite variant with ESL=EC=0 */ andis. r4,r3,PSSCR_EC_ESL_MASK_SHIFTED clrldi r3,r3,60 /* r3 = Bits[60:63] = Requested Level (RL) */ bne .Lhandle_esl_ec_set - IDLE_STATE_ENTER_SEQ(PPC_STOP) + PPC_STOP li r3,0 /* Since we didn't lose state, return 0 */ /* @@ -288,7 +372,8 @@ power_enter_stop: ld r4,ADDROFF(pnv_first_deep_stop_state)(r5) cmpd r3,r4 bge .Lhandle_deep_stop - IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP) + PPC_STOP /* Does not return (system reset interrupt) */ + .Lhandle_deep_stop: /* * Entering deep idle state. @@ -310,7 +395,7 @@ lwarx_loop_stop: bl save_sprs_to_stack - IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP) + PPC_STOP /* Does not return (system reset interrupt) */ /* * Entered with MSR[EE]=0 and no soft-masked interrupts pending. @@ -411,6 +496,18 @@ pnv_powersave_wakeup_mce: b pnv_powersave_wakeup +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +kvm_start_guest_check: + li r0,KVM_HWTHREAD_IN_KERNEL + stb r0,HSTATE_HWTHREAD_STATE(r13) + /* Order setting hwthread_state vs. testing hwthread_req */ + sync + lbz r0,HSTATE_HWTHREAD_REQ(r13) + cmpwi r0,0 + beqlr + b kvm_start_guest +#endif + /* * Called from reset vector for powersave wakeups. * cr3 - set to gt if waking up with partial/complete hypervisor state loss @@ -435,15 +532,9 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300) mr r3,r12 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE - li r0,KVM_HWTHREAD_IN_KERNEL - stb r0,HSTATE_HWTHREAD_STATE(r13) - /* Order setting hwthread_state vs. testing hwthread_req */ - sync - lbz r0,HSTATE_HWTHREAD_REQ(r13) - cmpwi r0,0 - beq 1f - b kvm_start_guest -1: +BEGIN_FTR_SECTION + bl kvm_start_guest_check +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) #endif /* Return SRR1 from power7_nap() */ @@ -460,11 +551,17 @@ pnv_restore_hyp_resource_arch300: /* * Workaround for POWER9, if we lost resources, the ERAT * might have been mixed up and needs flushing. We also need - * to reload MMCR0 (see comment above). + * to reload MMCR0 (see comment above). We also need to set + * then clear bit 60 in MMCRA to ensure the PMU starts running. */ blt cr3,1f PPC_INVALIDATE_ERAT ld r1,PACAR1(r13) + mfspr r4,SPRN_MMCRA + ori r4,r4,(1 << (63-60)) + mtspr SPRN_MMCRA,r4 + xori r4,r4,(1 << (63-60)) + mtspr SPRN_MMCRA,r4 ld r4,_MMCR0(r1) mtspr SPRN_MMCR0,r4 1: @@ -803,9 +900,16 @@ no_segments: mtctr r12 bctrl +/* + * On POWER9, we can come here on wakeup from a cpuidle stop state. + * Hence restore the additional SPRs to the saved value. + * + * On POWER8, we come here only on winkle. Since winkle is used + * only in the case of CPU-Hotplug, we don't need to restore + * the additional SPRs. + */ BEGIN_FTR_SECTION - ld r4,_LPCR(r1) - mtspr SPRN_LPCR,r4 + bl power9_restore_additional_sprs END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) hypervisor_state_restored: diff --git a/arch/powerpc/kernel/io-workarounds.c b/arch/powerpc/kernel/io-workarounds.c index a582e0d4252552c1a0e40ec97fbbc4bcfa439864..aa9f1b8261dbf812ad110f5ac736de5c82e36589 100644 --- a/arch/powerpc/kernel/io-workarounds.c +++ b/arch/powerpc/kernel/io-workarounds.c @@ -19,6 +19,8 @@ #include #include #include +#include + #define IOWA_MAX_BUS 8 @@ -75,8 +77,7 @@ struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr) * We won't find huge pages here (iomem). Also can't hit * a page table free due to init_mm */ - ptep = __find_linux_pte_or_hugepte(init_mm.pgd, vaddr, - NULL, &hugepage_shift); + ptep = find_init_mm_pte(vaddr, &hugepage_shift); if (ptep == NULL) paddr = 0; else { @@ -192,7 +193,7 @@ void iowa_register_bus(struct pci_controller *phb, struct ppc_pci_io *ops, if (iowa_bus_count >= IOWA_MAX_BUS) { pr_err("IOWA:Too many pci bridges, " - "workarounds disabled for %s\n", np->full_name); + "workarounds disabled for %pOF\n", np); return; } @@ -207,6 +208,6 @@ void iowa_register_bus(struct pci_controller *phb, struct ppc_pci_io *ops, iowa_bus_count++; - pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name); + pr_debug("IOWA:[%d]Add bus, %pOF.\n", iowa_bus_count-1, np); } diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 233ca3fe4754a40b379f9b5570cabe4cdcfeafa7..af7a20dc6e0934e0945c95e21c7b1eb07e11fdd1 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -127,8 +127,7 @@ static ssize_t fail_iommu_store(struct device *dev, return count; } -static DEVICE_ATTR(fail_iommu, S_IRUGO|S_IWUSR, fail_iommu_show, - fail_iommu_store); +static DEVICE_ATTR_RW(fail_iommu); static int fail_iommu_bus_notify(struct notifier_block *nb, unsigned long action, void *data) @@ -190,7 +189,7 @@ static unsigned long iommu_range_alloc(struct device *dev, unsigned int pool_nr; struct iommu_pool *pool; - align_mask = 0xffffffffffffffffl >> (64 - align_order); + align_mask = (1ull << align_order) - 1; /* This allocator was derived from x86_64's bit string search */ @@ -208,7 +207,7 @@ static unsigned long iommu_range_alloc(struct device *dev, * We don't need to disable preemption here because any CPU can * safely use any IOMMU pool. */ - pool_nr = __this_cpu_read(iommu_pool_hash) & (tbl->nr_pools - 1); + pool_nr = raw_cpu_read(iommu_pool_hash) & (tbl->nr_pools - 1); if (largealloc) pool = &(tbl->large_pool); diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 0bcec745a6724771c076e34132fb40e158b318f1..4e65bf82f5e0b1b368170177a43b4cd830fc0932 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -24,7 +24,7 @@ * mask register (of which only 16 are defined), hence the weird shifting * and complement of the cached_irq_mask. I want to be able to stuff * this right into the SIU SMASK register. - * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx + * Many of the prep/chrp functions are conditional compiled on CONFIG_PPC_8xx * to reduce code space and undefined function references. */ @@ -143,8 +143,22 @@ notrace unsigned int __check_irq_replay(void) */ unsigned char happened = local_paca->irq_happened; - /* Clear bit 0 which we wouldn't clear otherwise */ - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; + if (happened & PACA_IRQ_HARD_DIS) { + /* Clear bit 0 which we wouldn't clear otherwise */ + local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; + + /* + * We may have missed a decrementer interrupt if hard disabled. + * Check the decrementer register in case we had a rollover + * while hard disabled. + */ + if (!(happened & PACA_IRQ_DEC)) { + if (decrementer_check_overflow()) { + local_paca->irq_happened |= PACA_IRQ_DEC; + happened |= PACA_IRQ_DEC; + } + } + } /* * Force the delivery of pending soft-disabled interrupts on PS3. @@ -160,41 +174,39 @@ notrace unsigned int __check_irq_replay(void) * This is a higher priority interrupt than the others, so * replay it first. */ - local_paca->irq_happened &= ~PACA_IRQ_HMI; - if (happened & PACA_IRQ_HMI) + if (happened & PACA_IRQ_HMI) { + local_paca->irq_happened &= ~PACA_IRQ_HMI; return 0xe60; + } - /* - * We may have missed a decrementer interrupt. We check the - * decrementer itself rather than the paca irq_happened field - * in case we also had a rollover while hard disabled - */ - local_paca->irq_happened &= ~PACA_IRQ_DEC; - if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow()) + if (happened & PACA_IRQ_DEC) { + local_paca->irq_happened &= ~PACA_IRQ_DEC; return 0x900; + } - /* Finally check if an external interrupt happened */ - local_paca->irq_happened &= ~PACA_IRQ_EE; - if (happened & PACA_IRQ_EE) + if (happened & PACA_IRQ_EE) { + local_paca->irq_happened &= ~PACA_IRQ_EE; return 0x500; + } #ifdef CONFIG_PPC_BOOK3E - /* Finally check if an EPR external interrupt happened - * this bit is typically set if we need to handle another - * "edge" interrupt from within the MPIC "EPR" handler + /* + * Check if an EPR external interrupt happened this bit is typically + * set if we need to handle another "edge" interrupt from within the + * MPIC "EPR" handler. */ - local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; - if (happened & PACA_IRQ_EE_EDGE) + if (happened & PACA_IRQ_EE_EDGE) { + local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; return 0x500; + } - local_paca->irq_happened &= ~PACA_IRQ_DBELL; - if (happened & PACA_IRQ_DBELL) + if (happened & PACA_IRQ_DBELL) { + local_paca->irq_happened &= ~PACA_IRQ_DBELL; return 0x280; + } #else - local_paca->irq_happened &= ~PACA_IRQ_DBELL; if (happened & PACA_IRQ_DBELL) { - if (cpu_has_feature(CPU_FTR_HVMODE)) - return 0xe80; + local_paca->irq_happened &= ~PACA_IRQ_DBELL; return 0xa00; } #endif /* CONFIG_PPC_BOOK3E */ @@ -470,6 +482,18 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, " Hypervisor Maintenance Interrupts\n"); } + seq_printf(p, "%*s: ", prec, "NMI"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", per_cpu(irq_stat, j).sreset_irqs); + seq_printf(p, " System Reset interrupts\n"); + +#ifdef CONFIG_PPC_WATCHDOG + seq_printf(p, "%*s: ", prec, "WDG"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", per_cpu(irq_stat, j).soft_nmi_irqs); + seq_printf(p, " Watchdog soft-NMI interrupts\n"); +#endif + #ifdef CONFIG_PPC_DOORBELL if (cpu_has_feature(CPU_FTR_DBELL)) { seq_printf(p, "%*s: ", prec, "DBL"); @@ -494,6 +518,10 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum += per_cpu(irq_stat, cpu).spurious_irqs; sum += per_cpu(irq_stat, cpu).timer_irqs_others; sum += per_cpu(irq_stat, cpu).hmi_exceptions; + sum += per_cpu(irq_stat, cpu).sreset_irqs; +#ifdef CONFIG_PPC_WATCHDOG + sum += per_cpu(irq_stat, cpu).soft_nmi_irqs; +#endif #ifdef CONFIG_PPC_DOORBELL sum += per_cpu(irq_stat, cpu).doorbell_irqs; #endif diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c index bb6f8993412e3e502cd2c286795331454fd2533c..1df6c74aa7319eca390a28d66aae89799f04fba0 100644 --- a/arch/powerpc/kernel/isa-bridge.c +++ b/arch/powerpc/kernel/isa-bridge.c @@ -164,7 +164,7 @@ void __init isa_bridge_find_early(struct pci_controller *hose) /* Set the global ISA io base to indicate we have an ISA bridge */ isa_io_base = ISA_IO_BASE; - pr_debug("ISA bridge (early) is %s\n", np->full_name); + pr_debug("ISA bridge (early) is %pOF\n", np); } /** @@ -187,15 +187,15 @@ void __init isa_bridge_init_non_pci(struct device_node *np) pna = of_n_addr_cells(np); if (of_property_read_u32(np, "#address-cells", &na) || of_property_read_u32(np, "#size-cells", &ns)) { - pr_warn("ISA: Non-PCI bridge %s is missing address format\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF is missing address format\n", + np); return; } /* Check it's a supported address format */ if (na != 2 || ns != 1) { - pr_warn("ISA: Non-PCI bridge %s has unsupported address format\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has unsupported address format\n", + np); return; } rs = na + ns + pna; @@ -203,8 +203,8 @@ void __init isa_bridge_init_non_pci(struct device_node *np) /* Grab the ranges property */ ranges = of_get_property(np, "ranges", &rlen); if (ranges == NULL || rlen < rs) { - pr_warn("ISA: Non-PCI bridge %s has absent or invalid ranges\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has absent or invalid ranges\n", + np); return; } @@ -220,8 +220,8 @@ void __init isa_bridge_init_non_pci(struct device_node *np) /* Got something ? */ if (!size || !pbasep) { - pr_warn("ISA: Non-PCI bridge %s has no usable IO range\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has no usable IO range\n", + np); return; } @@ -233,15 +233,15 @@ void __init isa_bridge_init_non_pci(struct device_node *np) /* Map pbase */ pbase = of_translate_address(np, pbasep); if (pbase == OF_BAD_ADDR) { - pr_warn("ISA: Non-PCI bridge %s failed to translate IO base\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF failed to translate IO base\n", + np); return; } /* We need page alignment */ if ((cbase & ~PAGE_MASK) || (pbase & ~PAGE_MASK)) { - pr_warn("ISA: Non-PCI bridge %s has non aligned IO range\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has non aligned IO range\n", + np); return; } @@ -255,7 +255,7 @@ void __init isa_bridge_init_non_pci(struct device_node *np) __ioremap_at(pbase, (void *)ISA_IO_BASE, size, pgprot_val(pgprot_noncached(__pgprot(0)))); - pr_debug("ISA: Non-PCI bridge is %s\n", np->full_name); + pr_debug("ISA: Non-PCI bridge is %pOF\n", np); } /** @@ -277,8 +277,8 @@ static void isa_bridge_find_late(struct pci_dev *pdev, /* Set the global ISA io base to indicate we have an ISA bridge */ isa_io_base = ISA_IO_BASE; - pr_debug("ISA bridge (late) is %s on %s\n", - devnode->full_name, pci_name(pdev)); + pr_debug("ISA bridge (late) is %pOF on %s\n", + devnode, pci_name(pdev)); } /** diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index dbf098121ce638fcbb2c6c91e1426014b2b28f3d..35e240a0a40871f9492a769604895a350e7cbce6 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -67,9 +67,9 @@ static struct hard_trap_info #endif #else /* ! (defined(CONFIG_40x) || defined(CONFIG_BOOKE)) */ { 0x0d00, 0x05 /* SIGTRAP */ }, /* single-step */ -#if defined(CONFIG_8xx) +#if defined(CONFIG_PPC_8xx) { 0x1000, 0x04 /* SIGILL */ }, /* software emulation */ -#else /* ! CONFIG_8xx */ +#else /* ! CONFIG_PPC_8xx */ { 0x0f00, 0x04 /* SIGILL */ }, /* performance monitor */ { 0x0f20, 0x08 /* SIGFPE */ }, /* altivec unavailable */ { 0x1300, 0x05 /* SIGTRAP */ }, /* instruction address break */ diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 1086ea37c83241a115378ae1de5971f6c004aaad..9ad37f827a975f1f2a7f165447f951c9e2aa8fa7 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -25,7 +25,6 @@ #include #include #include -#include /* hardlockup_detector_disable() */ #include #include @@ -719,12 +718,6 @@ static __init void kvm_free_tmp(void) static int __init kvm_guest_init(void) { - /* - * The hardlockup detector is likely to get false positives in - * KVM guests, so disable it by default. - */ - hardlockup_detector_disable(); - if (!kvm_para_available()) goto free_tmp; diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S index 97ec8557f974b2bd0c5a8e04571e1b19719a33fc..6408f09dbbd9dc504d62da7b11ef65fbd18ac77c 100644 --- a/arch/powerpc/kernel/l2cr_6xx.S +++ b/arch/powerpc/kernel/l2cr_6xx.S @@ -181,7 +181,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) mtctr r4 li r4,0 1: - lwzx r0,r0,r4 + lwzx r0,0,r4 addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b isync @@ -328,7 +328,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L3CR) mtctr r4 li r4,0 1: - lwzx r0,r0,r4 + lwzx r0,0,r4 dcbf 0,r4 addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 0694d20f85b68b86ade804f7ffc3879bf6bfb42b..5e5a64a8b4e4eb7c272f81bcbbc434a50de44b10 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -147,8 +147,8 @@ static int __init add_legacy_port(struct device_node *np, int want_index, legacy_serial_ports[index].serial_out = tsi_serial_out; } - printk(KERN_DEBUG "Found legacy serial port %d for %s\n", - index, np->full_name); + printk(KERN_DEBUG "Found legacy serial port %d for %pOF\n", + index, np); printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", (iotype == UPIO_PORT) ? "port" : "mem", (unsigned long long)base, (unsigned long long)taddr, irq, @@ -207,7 +207,7 @@ static int __init add_legacy_isa_port(struct device_node *np, int index = -1; u64 taddr; - DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); + DBG(" -> add_legacy_isa_port(%pOF)\n", np); /* Get the ISA port number */ reg = of_get_property(np, "reg", NULL); @@ -256,7 +256,7 @@ static int __init add_legacy_pci_port(struct device_node *np, unsigned int flags; int iotype, index = -1, lindex = 0; - DBG(" -> add_legacy_pci_port(%s)\n", np->full_name); + DBG(" -> add_legacy_pci_port(%pOF)\n", np); /* We only support ports that have a clock frequency properly * encoded in the device-tree (that is have an fcode). Anything @@ -374,7 +374,7 @@ void __init find_legacy_serial_ports(void) if (path != NULL) { stdout = of_find_node_by_path(path); if (stdout) - DBG("stdout is %s\n", stdout->full_name); + DBG("stdout is %pOF\n", stdout); } else { DBG(" no linux,stdout-path !\n"); } @@ -603,7 +603,7 @@ static int __init check_legacy_serial_console(void) DBG(" can't find stdout package %s !\n", name); return -ENODEV; } - DBG("stdout is %s\n", prom_stdout->full_name); + DBG("stdout is %pOF\n", prom_stdout); name = of_get_property(prom_stdout, "name", NULL); if (!name) { diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index e0e131e662ed347ddb03457ec89f0e77bb95f65f..9b2ea7e71c06df9b302f1f017b90b66e3d403bd0 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -22,11 +22,14 @@ #undef DEBUG #define pr_fmt(fmt) "mce: " fmt +#include #include #include #include #include #include + +#include #include static DEFINE_PER_CPU(int, mce_nest_count); @@ -446,3 +449,33 @@ uint64_t get_mce_fault_addr(struct machine_check_event *evt) return 0; } EXPORT_SYMBOL(get_mce_fault_addr); + +/* + * This function is called in real mode. Strictly no printk's please. + * + * regs->nip and regs->msr contains srr0 and ssr1. + */ +long machine_check_early(struct pt_regs *regs) +{ + long handled = 0; + + __this_cpu_inc(irq_stat.mce_exceptions); + + if (cur_cpu_spec && cur_cpu_spec->machine_check_early) + handled = cur_cpu_spec->machine_check_early(regs); + return handled; +} + +long hmi_exception_realmode(struct pt_regs *regs) +{ + __this_cpu_inc(irq_stat.hmi_exceptions); + + wait_for_subcore_guest_exit(); + + if (ppc_md.hmi_exception_early) + ppc_md.hmi_exception_early(regs); + + wait_for_tb_resync(); + + return 0; +} diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index b76ca198e09c186e2d90e9b3eb83c7765c6c1cdf..72f153c6f3facea2bda06b64e90b24a6fed253d5 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -624,5 +624,18 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs) long __machine_check_early_realmode_p9(struct pt_regs *regs) { + /* + * On POWER9 DD2.1 and below, it's possible to get a machine check + * caused by a paste instruction where only DSISR bit 25 is set. This + * will result in the MCE handler seeing an unknown event and the kernel + * crashing. An MCE that occurs like this is spurious, so we don't need + * to do anything in terms of servicing it. If there is something that + * needs to be serviced, the CPU will raise the MCE again with the + * correct DSISR so that it can be serviced properly. So detect this + * case and mark it as handled. + */ + if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000) + return 1; + return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table); } diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 34aeac54f120053a1ff9f8f9311baf30f7b1a1f6..becaec990140be33e741c1ffb3ac6777b9099ca2 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -45,7 +45,7 @@ static int of_pci_phb_probe(struct platform_device *dev) if (ppc_md.pci_setup_phb == NULL) return -ENODEV; - pr_info("Setting up PCI bus %s\n", dev->dev.of_node->full_name); + pr_info("Setting up PCI bus %pOF\n", dev->dev.of_node); /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(dev->dev.of_node); diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 6f8273f5e988b2cca6f320299ca6c67445ebca66..91e037ab20a197de398161c057d86bffabc3a68a 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -104,8 +104,10 @@ static unsigned long can_optimize(struct kprobe *p) * and that can be emulated. */ if (!is_conditional_branch(*p->ainsn.insn) && - analyse_instr(&op, ®s, *p->ainsn.insn)) + analyse_instr(&op, ®s, *p->ainsn.insn) == 1) { + emulate_update_regs(®s, &op); nip = regs.nip; + } return nip; } diff --git a/arch/powerpc/kernel/optprobes_head.S b/arch/powerpc/kernel/optprobes_head.S index 4937bef7652f4bc3dd1837be993d5d117917664c..52fc864cdec4e9f3950fc5da1a48de74a34380d7 100644 --- a/arch/powerpc/kernel/optprobes_head.S +++ b/arch/powerpc/kernel/optprobes_head.S @@ -60,10 +60,6 @@ optprobe_template_entry: std r5,_CCR(r1) lbz r5,PACASOFTIRQEN(r13) std r5,SOFTE(r1) - mfdar r5 - std r5,_DAR(r1) - mfdsisr r5 - std r5,_DSISR(r1) /* * We may get here from a module, so load the kernel TOC in r2. @@ -122,10 +118,6 @@ optprobe_template_call_emulate: mtxer r5 ld r5,_CCR(r1) mtcr r5 - ld r5,_DAR(r1) - mtdar r5 - ld r5,_DSISR(r1) - mtdsisr r5 REST_GPR(0,r1) REST_10GPRS(2,r1) REST_10GPRS(12,r1) diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 8d63627e067f7a43ce7168b53db515432554d63c..2ff2b8a19f712d8b14c958b86ca947bdc50169cb 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -99,18 +99,27 @@ static inline void free_lppacas(void) { } * If you make the number of persistent SLB entries dynamic, please also * update PR KVM to flush and restore them accordingly. */ -static struct slb_shadow *slb_shadow; +static struct slb_shadow * __initdata slb_shadow; static void __init allocate_slb_shadows(int nr_cpus, int limit) { int size = PAGE_ALIGN(sizeof(struct slb_shadow) * nr_cpus); + + if (early_radix_enabled()) + return; + slb_shadow = __va(memblock_alloc_base(size, PAGE_SIZE, limit)); memset(slb_shadow, 0, size); } static struct slb_shadow * __init init_slb_shadow(int cpu) { - struct slb_shadow *s = &slb_shadow[cpu]; + struct slb_shadow *s; + + if (early_radix_enabled()) + return NULL; + + s = &slb_shadow[cpu]; /* * When we come through here to initialise boot_paca, the slb_shadow @@ -215,7 +224,7 @@ void __init allocate_pacas(void) paca = __va(memblock_alloc_base(paca_size, PAGE_SIZE, limit)); memset(paca, 0, paca_size); - printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n", + printk(KERN_DEBUG "Allocated %u bytes for %u pacas at %p\n", paca_size, nr_cpu_ids, paca); allocate_lppacas(nr_cpu_ids, limit); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 341a7469cab84a14bf06db6984b58716933d6aa6..02831a3964197a5bf443687368ceebd6ff723cdc 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -373,9 +373,8 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) if (virq) irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { - pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", - oirq.args_count, oirq.args[0], oirq.args[1], - of_node_full_name(oirq.np)); + pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %pOF\n", + oirq.args_count, oirq.args[0], oirq.args[1], oirq.np); virq = irq_create_of_mapping(&oirq); } @@ -741,8 +740,8 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, struct of_pci_range range; struct of_pci_range_parser parser; - printk(KERN_INFO "PCI host bridge %s %s ranges:\n", - dev->full_name, primary ? "(primary)" : ""); + printk(KERN_INFO "PCI host bridge %pOF %s ranges:\n", + dev, primary ? "(primary)" : ""); /* Check for ranges property */ if (of_pci_range_parser_init(&parser, dev)) @@ -1556,8 +1555,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, if (!res->flags) { pr_debug("PCI: I/O resource not set for host" - " bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + " bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); } else { offset = pcibios_io_space_offset(hose); @@ -1668,7 +1667,7 @@ void pcibios_scan_phb(struct pci_controller *hose) struct device_node *node = hose->dn; int mode; - pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node)); + pr_debug("PCI: Scanning PHB %pOF\n", node); /* Get some IO space for the new PHB */ pcibios_setup_phb_io_space(hose); diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 41c86c6b6e4d563cd7e93eb7f7d9b967c7a867d1..1d817f4d97d960cae8b2c75ec580588538c31282 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -79,8 +79,8 @@ make_one_node_map(struct device_node* node, u8 pci_bus) return; bus_range = of_get_property(node, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, " - "assuming it starts at 0\n", node->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, " + "assuming it starts at 0\n", node); pci_to_OF_bus_map[pci_bus] = 0; } else pci_to_OF_bus_map[pci_bus] = bus_range[0]; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index ed5e9ff61a68c91ff1ce3446231d387445511473..932b9741aa8f2339accf0098b63df61fd73d5680 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -111,7 +111,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus) if (hose->io_base_alloc == NULL) return 0; - pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name); + pr_debug("IO unmapping for PHB %pOF\n", hose->dn); pr_debug(" alloc=0x%p\n", hose->io_base_alloc); /* This is a PHB, we fully unmap the IO area */ @@ -151,7 +151,7 @@ static int pcibios_map_phb_io_space(struct pci_controller *hose) hose->io_base_virt = (void __iomem *)(area->addr + hose->io_base_phys - phys_page); - pr_debug("IO mapping for PHB %s\n", hose->dn->full_name); + pr_debug("IO mapping for PHB %pOF\n", hose->dn); pr_debug(" phys=0x%016llx, virt=0x%p (alloc=0x%p)\n", hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); pr_debug(" size=0x%016llx (alloc=0x%016lx)\n", diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index 592693437070201b84e8aa52b0ca69018746579c..0e395afbf0f498a89f2fd66a8f8b6ed74f381f24 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -139,7 +139,6 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev) #ifdef CONFIG_PCI_IOV static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, - struct pci_dev *pdev, int vf_index, int busno, int devfn) { @@ -150,10 +149,8 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, return NULL; pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); - if (!pdn) { - dev_warn(&pdev->dev, "%s: Out of memory!\n", __func__); + if (!pdn) return NULL; - } pdn->phb = parent->phb; pdn->parent = parent; @@ -167,13 +164,6 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, INIT_LIST_HEAD(&pdn->list); list_add_tail(&pdn->list, &parent->child_list); - /* - * If we already have PCI device instance, lets - * bind them. - */ - if (pdev) - pdev->dev.archdata.pci_data = pdn; - return pdn; } #endif @@ -201,7 +191,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { struct eeh_dev *edev __maybe_unused; - pdn = add_one_dev_pci_data(parent, NULL, i, + pdn = add_one_dev_pci_data(parent, i, pci_iov_virtfn_bus(pdev, i), pci_iov_virtfn_devfn(pdev, i)); if (!pdn) { @@ -303,7 +293,6 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose, if (pdn == NULL) return NULL; dn->data = pdn; - pdn->node = dn; pdn->phb = hose; #ifdef CONFIG_PPC_POWERNV pdn->pe_number = IODA_INVALID_PE; @@ -352,6 +341,7 @@ EXPORT_SYMBOL_GPL(pci_add_device_node_info); void pci_remove_device_node_info(struct device_node *dn) { struct pci_dn *pdn = dn ? PCI_DN(dn) : NULL; + struct device_node *parent; #ifdef CONFIG_EEH struct eeh_dev *edev = pdn_to_eeh_dev(pdn); @@ -364,8 +354,10 @@ void pci_remove_device_node_info(struct device_node *dn) WARN_ON(!list_empty(&pdn->child_list)); list_del(&pdn->list); - if (pdn->parent) - of_node_put(pdn->parent->node); + + parent = of_get_parent(dn); + if (parent) + of_node_put(parent); dn->data = NULL; kfree(pdn); diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index ea3d98115b8836df231c7eb3455d613b1bf9397b..0d790f8432d27b6293c647176984d45f792c72c6 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -211,19 +211,19 @@ void of_scan_pci_bridge(struct pci_dev *dev) unsigned int flags; u64 size; - pr_debug("of_scan_pci_bridge(%s)\n", node->full_name); + pr_debug("of_scan_pci_bridge(%pOF)\n", node); /* parse bus-range property */ busrange = of_get_property(node, "bus-range", &len); if (busrange == NULL || len != 8) { - printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", - node->full_name); + printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %pOF\n", + node); return; } ranges = of_get_property(node, "ranges", &len); if (ranges == NULL) { - printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", - node->full_name); + printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %pOF\n", + node); return; } @@ -233,8 +233,8 @@ void of_scan_pci_bridge(struct pci_dev *dev) bus = pci_add_new_bus(dev->bus, dev, of_read_number(busrange, 1)); if (!bus) { - printk(KERN_ERR "Failed to create pci bus for %s\n", - node->full_name); + printk(KERN_ERR "Failed to create pci bus for %pOF\n", + node); return; } } @@ -262,13 +262,13 @@ void of_scan_pci_bridge(struct pci_dev *dev) res = bus->resource[0]; if (res->flags) { printk(KERN_ERR "PCI: ignoring extra I/O range" - " for bridge %s\n", node->full_name); + " for bridge %pOF\n", node); continue; } } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" - " for bridge %s\n", node->full_name); + " for bridge %pOF\n", node); continue; } res = bus->resource[i]; @@ -307,7 +307,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, struct eeh_dev *edev = pdn_to_eeh_dev(PCI_DN(dn)); #endif - pr_debug(" * %s\n", dn->full_name); + pr_debug(" * %pOF\n", dn); if (!of_device_is_available(dn)) return NULL; @@ -350,8 +350,8 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus, struct device_node *child; struct pci_dev *dev; - pr_debug("of_scan_bus(%s) bus no %d...\n", - node->full_name, bus->number); + pr_debug("of_scan_bus(%pOF) bus no %d...\n", + node, bus->number); /* Scan direct children */ for_each_child_of_node(node, child) { diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9f3e2c932dccc1c3a1158fc174a8cf57e63dd75d..a0c74bbf345426bc9918860a203b8ab3427a3390 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -230,7 +230,8 @@ void enable_kernel_fp(void) } EXPORT_SYMBOL(enable_kernel_fp); -static int restore_fp(struct task_struct *tsk) { +static int restore_fp(struct task_struct *tsk) +{ if (tsk->thread.load_fp || msr_tm_active(tsk->thread.regs->msr)) { load_fp_state(¤t->thread.fp_state); current->thread.load_fp++; @@ -330,11 +331,19 @@ static inline int restore_altivec(struct task_struct *tsk) { return 0; } #ifdef CONFIG_VSX static void __giveup_vsx(struct task_struct *tsk) { - if (tsk->thread.regs->msr & MSR_FP) + unsigned long msr = tsk->thread.regs->msr; + + /* + * We should never be ssetting MSR_VSX without also setting + * MSR_FP and MSR_VEC + */ + WARN_ON((msr & MSR_VSX) && !((msr & MSR_FP) && (msr & MSR_VEC))); + + /* __giveup_fpu will clear MSR_VSX */ + if (msr & MSR_FP) __giveup_fpu(tsk); - if (tsk->thread.regs->msr & MSR_VEC) + if (msr & MSR_VEC) __giveup_altivec(tsk); - tsk->thread.regs->msr &= ~MSR_VSX; } static void giveup_vsx(struct task_struct *tsk) @@ -346,14 +355,6 @@ static void giveup_vsx(struct task_struct *tsk) msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); } -static void save_vsx(struct task_struct *tsk) -{ - if (tsk->thread.regs->msr & MSR_FP) - save_fpu(tsk); - if (tsk->thread.regs->msr & MSR_VEC) - save_altivec(tsk); -} - void enable_kernel_vsx(void) { unsigned long cpumsr; @@ -362,7 +363,8 @@ void enable_kernel_vsx(void) cpumsr = msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); - if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) { + if (current->thread.regs && + (current->thread.regs->msr & (MSR_VSX|MSR_VEC|MSR_FP))) { check_if_tm_restore_required(current); /* * If a thread has already been reclaimed then the @@ -373,10 +375,6 @@ void enable_kernel_vsx(void) */ if(!msr_tm_active(cpumsr) && msr_tm_active(current->thread.regs->msr)) return; - if (current->thread.regs->msr & MSR_FP) - __giveup_fpu(current); - if (current->thread.regs->msr & MSR_VEC) - __giveup_altivec(current); __giveup_vsx(current); } } @@ -386,7 +384,7 @@ void flush_vsx_to_thread(struct task_struct *tsk) { if (tsk->thread.regs) { preempt_disable(); - if (tsk->thread.regs->msr & MSR_VSX) { + if (tsk->thread.regs->msr & (MSR_VSX|MSR_VEC|MSR_FP)) { BUG_ON(tsk != current); giveup_vsx(tsk); } @@ -406,7 +404,6 @@ static int restore_vsx(struct task_struct *tsk) } #else static inline int restore_vsx(struct task_struct *tsk) { return 0; } -static inline void save_vsx(struct task_struct *tsk) { } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE @@ -486,6 +483,8 @@ void giveup_all(struct task_struct *tsk) msr_check_and_set(msr_all_available); check_if_tm_restore_required(tsk); + WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC))); + #ifdef CONFIG_PPC_FPU if (usermsr & MSR_FP) __giveup_fpu(tsk); @@ -494,10 +493,6 @@ void giveup_all(struct task_struct *tsk) if (usermsr & MSR_VEC) __giveup_altivec(tsk); #endif -#ifdef CONFIG_VSX - if (usermsr & MSR_VSX) - __giveup_vsx(tsk); -#endif #ifdef CONFIG_SPE if (usermsr & MSR_SPE) __giveup_spe(tsk); @@ -511,10 +506,6 @@ void restore_math(struct pt_regs *regs) { unsigned long msr; - /* - * Syscall exit makes a similar initial check before branching - * to restore_math. Keep them in synch. - */ if (!msr_tm_active(regs->msr) && !current->thread.load_fp && !loadvec(current->thread)) return; @@ -556,19 +547,13 @@ void save_all(struct task_struct *tsk) msr_check_and_set(msr_all_available); - /* - * Saving the way the register space is in hardware, save_vsx boils - * down to a save_fpu() and save_altivec() - */ - if (usermsr & MSR_VSX) { - save_vsx(tsk); - } else { - if (usermsr & MSR_FP) - save_fpu(tsk); + WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC))); - if (usermsr & MSR_VEC) - save_altivec(tsk); - } + if (usermsr & MSR_FP) + save_fpu(tsk); + + if (usermsr & MSR_VEC) + save_altivec(tsk); if (usermsr & MSR_SPE) __giveup_spe(tsk); @@ -1395,13 +1380,13 @@ void show_regs(struct pt_regs * regs) show_regs_print_info(KERN_DEFAULT); - printk("NIP: "REG" LR: "REG" CTR: "REG"\n", + printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); printk("REGS: %p TRAP: %04lx %s (%s)\n", regs, regs->trap, print_tainted(), init_utsname()->release); - printk("MSR: "REG" ", regs->msr); + printk("MSR: "REG" ", regs->msr); print_msr_bits(regs->msr); - printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); + pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); trap = TRAP(regs); if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) pr_cont("CFAR: "REG" ", regs->orig_gpr3); @@ -1994,11 +1979,25 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) void notrace __ppc64_runlatch_on(void) { struct thread_info *ti = current_thread_info(); - unsigned long ctrl; - ctrl = mfspr(SPRN_CTRLF); - ctrl |= CTRL_RUNLATCH; - mtspr(SPRN_CTRLT, ctrl); + if (cpu_has_feature(CPU_FTR_ARCH_206)) { + /* + * Least significant bit (RUN) is the only writable bit of + * the CTRL register, so we can avoid mfspr. 2.06 is not the + * earliest ISA where this is the case, but it's convenient. + */ + mtspr(SPRN_CTRLT, CTRL_RUNLATCH); + } else { + unsigned long ctrl; + + /* + * Some architectures (e.g., Cell) have writable fields other + * than RUN, so do the read-modify-write. + */ + ctrl = mfspr(SPRN_CTRLF); + ctrl |= CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); + } ti->local_flags |= _TLF_RUNLATCH; } @@ -2007,13 +2006,18 @@ void notrace __ppc64_runlatch_on(void) void notrace __ppc64_runlatch_off(void) { struct thread_info *ti = current_thread_info(); - unsigned long ctrl; ti->local_flags &= ~_TLF_RUNLATCH; - ctrl = mfspr(SPRN_CTRLF); - ctrl &= ~CTRL_RUNLATCH; - mtspr(SPRN_CTRLT, ctrl); + if (cpu_has_feature(CPU_FTR_ARCH_206)) { + mtspr(SPRN_CTRLT, 0); + } else { + unsigned long ctrl; + + ctrl = mfspr(SPRN_CTRLF); + ctrl &= ~CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); + } } #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 613f79f03877d725fd09305072e31938ae33fe3a..02190e90c7aef4a1a71d513542ebcef556295753 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -177,6 +177,7 @@ struct platform_support { bool hash_mmu; bool radix_mmu; bool radix_gtse; + bool xive; }; /* Platforms codes are now obsolete in the kernel. Now only used within this @@ -1041,6 +1042,27 @@ static void __init prom_parse_mmu_model(u8 val, } } +static void __init prom_parse_xive_model(u8 val, + struct platform_support *support) +{ + switch (val) { + case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */ + prom_debug("XIVE - either mode supported\n"); + support->xive = true; + break; + case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */ + prom_debug("XIVE - exploitation mode supported\n"); + support->xive = true; + break; + case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */ + prom_debug("XIVE - legacy mode supported\n"); + break; + default: + prom_debug("Unknown xive support option: 0x%x\n", val); + break; + } +} + static void __init prom_parse_platform_support(u8 index, u8 val, struct platform_support *support) { @@ -1054,6 +1076,10 @@ static void __init prom_parse_platform_support(u8 index, u8 val, support->radix_gtse = true; } break; + case OV5_INDX(OV5_XIVE_SUPPORT): /* Interrupt mode */ + prom_parse_xive_model(val & OV5_FEAT(OV5_XIVE_SUPPORT), + support); + break; } } @@ -1062,7 +1088,8 @@ static void __init prom_check_platform_support(void) struct platform_support supported = { .hash_mmu = false, .radix_mmu = false, - .radix_gtse = false + .radix_gtse = false, + .xive = false }; int prop_len = prom_getproplen(prom.chosen, "ibm,arch-vec-5-platform-support"); @@ -1095,6 +1122,11 @@ static void __init prom_check_platform_support(void) /* We're probably on a legacy hypervisor */ prom_debug("Assuming legacy hash support\n"); } + + if (supported.xive) { + prom_debug("Asking for XIVE\n"); + ibm_architecture_vec.vec5.intarch = OV5_FEAT(OV5_XIVE_EXPLOIT); + } } static void __init prom_send_capabilities(void) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 925a4ef9055932174b4dc5a8f0424b330149132b..f52ad5bb710960906b8ae61400688845e2811dd5 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -127,12 +127,19 @@ static void flush_tmregs_to_thread(struct task_struct *tsk) * If task is not current, it will have been flushed already to * it's thread_struct during __switch_to(). * - * A reclaim flushes ALL the state. + * A reclaim flushes ALL the state or if not in TM save TM SPRs + * in the appropriate thread structures from live. */ - if (tsk == current && MSR_TM_SUSPENDED(mfmsr())) - tm_reclaim_current(TM_CAUSE_SIGNAL); + if ((!cpu_has_feature(CPU_FTR_TM)) || (tsk != current)) + return; + if (MSR_TM_SUSPENDED(mfmsr())) { + tm_reclaim_current(TM_CAUSE_SIGNAL); + } else { + tm_enable(); + tm_save_sprs(&(tsk->thread)); + } } #else static inline void flush_tmregs_to_thread(struct task_struct *tsk) { } @@ -1587,11 +1594,8 @@ static int ppr_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ppr, 0, sizeof(u64)); - return ret; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.ppr, 0, sizeof(u64)); } static int ppr_set(struct task_struct *target, @@ -1599,11 +1603,8 @@ static int ppr_set(struct task_struct *target, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - int ret; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ppr, 0, sizeof(u64)); - return ret; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.ppr, 0, sizeof(u64)); } static int dscr_get(struct task_struct *target, @@ -1611,22 +1612,16 @@ static int dscr_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.dscr, 0, sizeof(u64)); - return ret; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.dscr, 0, sizeof(u64)); } static int dscr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - int ret; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.dscr, 0, sizeof(u64)); - return ret; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.dscr, 0, sizeof(u64)); } #endif #ifdef CONFIG_PPC_BOOK3S_64 @@ -1635,22 +1630,16 @@ static int tar_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tar, 0, sizeof(u64)); - return ret; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tar, 0, sizeof(u64)); } static int tar_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - int ret; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tar, 0, sizeof(u64)); - return ret; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tar, 0, sizeof(u64)); } static int ebb_active(struct task_struct *target, diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S index d88736fbece67c6627e6f33a9c4fd3e31ee2b533..e8cfc69f59aeff3be4e1737d9ce37fb8aa83f0d9 100644 --- a/arch/powerpc/kernel/reloc_64.S +++ b/arch/powerpc/kernel/reloc_64.S @@ -82,7 +82,7 @@ _GLOBAL(relocate) 6: blr .balign 8 -p_dyn: .llong __dynamic_start - 0b -p_rela: .llong __rela_dyn_start - 0b -p_st: .llong _stext - 0b +p_dyn: .8byte __dynamic_start - 0b +p_rela: .8byte __rela_dyn_start - 0b +p_st: .8byte _stext - 0b diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index b8a4987f58cfdc6ccd66a94d68eea419bc68a37c..1643e9e5365573659bbdf79d6e5dfddb5ee4eafc 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -914,7 +914,7 @@ int rtas_online_cpus_mask(cpumask_var_t cpus) if (ret) { cpumask_var_t tmp_mask; - if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY)) + if (!alloc_cpumask_var(&tmp_mask, GFP_KERNEL)) return ret; /* Use tmp_mask to preserve cpus mask from first failure */ @@ -962,7 +962,7 @@ int rtas_ibm_suspend_me(u64 handle) return -EIO; } - if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) + if (!alloc_cpumask_var(&offline_mask, GFP_KERNEL)) return -ENOMEM; atomic_set(&data.working, 0); diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 73f1934582c2d45c860a8cfd781ec4dd11c0a003..c2b148b1634aacd6203c318e718c074a0dc42160 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -91,26 +91,14 @@ static int rtas_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - struct device_node *busdn, *dn; struct pci_dn *pdn; - bool found = false; int ret; - /* Search only direct children of the bus */ *val = 0xFFFFFFFF; - busdn = pci_bus_to_OF_node(bus); - for (dn = busdn->child; dn; dn = dn->sibling) { - pdn = PCI_DN(dn); - if (pdn && pdn->devfn == devfn - && of_device_is_available(dn)) { - found = true; - break; - } - } - if (!found) - return PCIBIOS_DEVICE_NOT_FOUND; + pdn = pci_get_pdn_by_devfn(bus, devfn); + /* Validity of pdn is checked in here */ ret = rtas_read_config(pdn, where, size, val); if (*val == EEH_IO_ERROR_VALUE(size) && eeh_dev_check_failure(pdn_to_eeh_dev(pdn))) @@ -153,24 +141,11 @@ static int rtas_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - struct device_node *busdn, *dn; struct pci_dn *pdn; - bool found = false; - - /* Search only direct children of the bus */ - busdn = pci_bus_to_OF_node(bus); - for (dn = busdn->child; dn; dn = dn->sibling) { - pdn = PCI_DN(dn); - if (pdn && pdn->devfn == devfn - && of_device_is_available(dn)) { - found = true; - break; - } - } - if (!found) - return PCIBIOS_DEVICE_NOT_FOUND; + pdn = pci_get_pdn_by_devfn(bus, devfn); + /* Validity of pdn is checked in here. */ return rtas_write_config(pdn, where, size, val); } diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 94a948207cd2375e67117c3e439e5f422e861a31..2e3bc16d02b289b5d03906010518bc7005233452 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -481,7 +481,7 @@ void __init smp_setup_cpu_maps(void) __be32 cpu_be; int j, len; - DBG(" * %s...\n", dn->full_name); + DBG(" * %pOF...\n", dn); intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); @@ -551,7 +551,7 @@ void __init smp_setup_cpu_maps(void) if (maxcpus > nr_cpu_ids) { printk(KERN_WARNING "Partition configured for %d cpus, " - "operating system maximum is %d.\n", + "operating system maximum is %u.\n", maxcpus, nr_cpu_ids); maxcpus = nr_cpu_ids; } else @@ -704,30 +704,6 @@ int check_legacy_ioport(unsigned long base_port) } EXPORT_SYMBOL(check_legacy_ioport); -static int ppc_panic_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - /* - * If firmware-assisted dump has been registered then trigger - * firmware-assisted dump and let firmware handle everything else. - */ - crash_fadump(NULL, ptr); - ppc_md.panic(ptr); /* May not return */ - return NOTIFY_DONE; -} - -static struct notifier_block ppc_panic_block = { - .notifier_call = ppc_panic_event, - .priority = INT_MIN /* may not return; must be done last */ -}; - -void __init setup_panic(void) -{ - if (!ppc_md.panic) - return; - atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block); -} - #ifdef CONFIG_CHECK_CACHE_COHERENCY /* * For platforms that have configurable cache-coherency. This function @@ -872,9 +848,6 @@ void __init setup_arch(char **cmdline_p) /* Probe the machine type, establish ppc_md. */ probe_machine(); - /* Setup panic notifier if requested by the platform. */ - setup_panic(); - /* * Configure ppc_md.power_save (ppc32 only, 64-bit machines do * it from their respective probe() function. @@ -916,13 +889,6 @@ void __init setup_arch(char **cmdline_p) /* Reserve large chunks of memory for use by CMA for KVM. */ kvm_cma_reserve(); - /* - * Reserve any gigantic pages requested on the command line. - * memblock needs to have been initialized by the time this is - * called since this will reserve memory. - */ - reserve_hugetlb_gpages(); - klp_init_thread_info(&init_thread_info); init_mm.start_code = (unsigned long)_stext; @@ -938,9 +904,6 @@ void __init setup_arch(char **cmdline_p) #endif #endif -#ifdef CONFIG_PPC_64K_PAGES - init_mm.context.pte_frag = NULL; -#endif #ifdef CONFIG_SPAPR_TCE_IOMMU mm_iommu_init(&init_mm); #endif diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 2f88f6cf1a4212c7ae0e3f0843f1cc8962dd232b..51ebc01fff52549e00bf565b8718cda72d74bc31 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -98,6 +98,9 @@ extern unsigned int memset_nocache_branch; /* Insn to be replaced by NOP */ notrace void __init machine_init(u64 dt_ptr) { + unsigned int *addr = &memset_nocache_branch; + unsigned long insn; + /* Configure static keys first, now that we're relocated. */ setup_feature_keys(); @@ -105,7 +108,9 @@ notrace void __init machine_init(u64 dt_ptr) udbg_early_init(); patch_instruction((unsigned int *)&memcpy, PPC_INST_NOP); - patch_instruction(&memset_nocache_branch, PPC_INST_NOP); + + insn = create_cond_branch(addr, branch_target(addr), 0x820000); + patch_instruction(addr, insn); /* replace b by bne cr0 */ /* Do some early initialization based on the flat device tree */ early_init_devtree(__va(dt_ptr)); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index af23d4b576ec5ba40326b46070869ac6fa861a8d..b89c6aac48c9bc2d199b36e759d49c814e34c45c 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -564,6 +564,9 @@ static __init u64 safe_stack_limit(void) /* Other BookE, we assume the first GB is bolted */ return 1ul << 30; #else + if (early_radix_enabled()) + return ULONG_MAX; + /* BookS, the first segment is bolted */ if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) return 1UL << SID_SHIFT_1T; @@ -578,7 +581,8 @@ void __init irqstack_early_init(void) /* * Interrupt stacks must be in the first segment since we - * cannot afford to take SLB misses on them. + * cannot afford to take SLB misses on them. They are not + * accessed in realmode. */ for_each_possible_cpu(i) { softirq_ctx[i] = (struct thread_info *) @@ -649,8 +653,9 @@ void __init emergency_stack_init(void) * aligned. * * Since we use these as temporary stacks during secondary CPU - * bringup, we need to get at them in real mode. This means they - * must also be within the RMO region. + * bringup, machine check, system reset, and HMI, we need to get + * at them in real mode. This means they must also be within the RMO + * region. * * The IRQ stacks allocated elsewhere in this file are zeroed and * initialized in kernel/irq.c. These are initialized here in order @@ -751,3 +756,31 @@ unsigned long memory_block_size_bytes(void) struct ppc_pci_io ppc_pci_io; EXPORT_SYMBOL(ppc_pci_io); #endif + +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF +u64 hw_nmi_get_sample_period(int watchdog_thresh) +{ + return ppc_proc_freq * watchdog_thresh; +} +#endif + +/* + * The perf based hardlockup detector breaks PMU event based branches, so + * disable it by default. Book3S has a soft-nmi hardlockup detector based + * on the decrementer interrupt, so it does not suffer from this problem. + * + * It is likely to get false positives in VM guests, so disable it there + * by default too. + */ +static int __init disable_hardlockup_detector(void) +{ +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF + hardlockup_detector_disable(); +#else + if (firmware_has_feature(FW_FEATURE_LPAR)) + hardlockup_detector_disable(); +#endif + + return 0; +} +early_initcall(disable_hardlockup_detector); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 97bb1385e77152d95215d83278771a0fbe972982..92fb1c8dbbd83772af643dce2c9bef527e676f40 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -913,42 +913,40 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, const siginfo_t *s) */ err = __put_user(s->si_signo, &d->si_signo); err |= __put_user(s->si_errno, &d->si_errno); - err |= __put_user((short)s->si_code, &d->si_code); + err |= __put_user(s->si_code, &d->si_code); if (s->si_code < 0) err |= __copy_to_user(&d->_sifields._pad, &s->_sifields._pad, SI_PAD_SIZE32); - else switch(s->si_code >> 16) { - case __SI_CHLD >> 16: + else switch(siginfo_layout(s->si_signo, s->si_code)) { + case SIL_CHLD: err |= __put_user(s->si_pid, &d->si_pid); err |= __put_user(s->si_uid, &d->si_uid); err |= __put_user(s->si_utime, &d->si_utime); err |= __put_user(s->si_stime, &d->si_stime); err |= __put_user(s->si_status, &d->si_status); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user((unsigned int)(unsigned long)s->si_addr, &d->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(s->si_band, &d->si_band); err |= __put_user(s->si_fd, &d->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(s->si_tid, &d->si_tid); err |= __put_user(s->si_overrun, &d->si_overrun); err |= __put_user(s->si_int, &d->si_int); break; - case __SI_SYS >> 16: + case SIL_SYS: err |= __put_user(ptr_to_compat(s->si_call_addr), &d->si_call_addr); err |= __put_user(s->si_syscall, &d->si_syscall); err |= __put_user(s->si_arch, &d->si_arch); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(s->si_int, &d->si_int); /* fallthrough */ - case __SI_KILL >> 16: - default: + case SIL_KILL: err |= __put_user(s->si_pid, &d->si_pid); err |= __put_user(s->si_uid, &d->si_uid); break; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 997c88d54acf292b3e80beef1791ee2194ca9071..e0a4c1f82e25a33de0d3b0c86fbb8ea8c8f9a2ba 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -75,9 +75,11 @@ static DEFINE_PER_CPU(int, cpu_state) = { 0 }; struct thread_info *secondary_ti; DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DEFINE_PER_CPU(cpumask_var_t, cpu_l2_cache_map); DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); +EXPORT_PER_CPU_SYMBOL(cpu_l2_cache_map); EXPORT_PER_CPU_SYMBOL(cpu_core_map); /* SMP operations for this machine */ @@ -351,7 +353,7 @@ static void nmi_ipi_lock_start(unsigned long *flags) hard_irq_disable(); while (atomic_cmpxchg(&__nmi_ipi_lock, 0, 1) == 1) { raw_local_irq_restore(*flags); - cpu_relax(); + spin_until_cond(atomic_read(&__nmi_ipi_lock) == 0); raw_local_irq_save(*flags); hard_irq_disable(); } @@ -360,7 +362,7 @@ static void nmi_ipi_lock_start(unsigned long *flags) static void nmi_ipi_lock(void) { while (atomic_cmpxchg(&__nmi_ipi_lock, 0, 1) == 1) - cpu_relax(); + spin_until_cond(atomic_read(&__nmi_ipi_lock) == 0); } static void nmi_ipi_unlock(void) @@ -475,7 +477,7 @@ int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us) nmi_ipi_lock_start(&flags); while (nmi_ipi_busy_count) { nmi_ipi_unlock_end(&flags); - cpu_relax(); + spin_until_cond(nmi_ipi_busy_count == 0); nmi_ipi_lock_start(&flags); } @@ -571,6 +573,26 @@ static void smp_store_cpu_info(int id) #endif } +/* + * Relationships between CPUs are maintained in a set of per-cpu cpumasks so + * rather than just passing around the cpumask we pass around a function that + * returns the that cpumask for the given CPU. + */ +static void set_cpus_related(int i, int j, struct cpumask *(*get_cpumask)(int)) +{ + cpumask_set_cpu(i, get_cpumask(j)); + cpumask_set_cpu(j, get_cpumask(i)); +} + +#ifdef CONFIG_HOTPLUG_CPU +static void set_cpus_unrelated(int i, int j, + struct cpumask *(*get_cpumask)(int)) +{ + cpumask_clear_cpu(i, get_cpumask(j)); + cpumask_clear_cpu(j, get_cpumask(i)); +} +#endif + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int cpu; @@ -590,6 +612,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) for_each_possible_cpu(cpu) { zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu), GFP_KERNEL, cpu_to_node(cpu)); + zalloc_cpumask_var_node(&per_cpu(cpu_l2_cache_map, cpu), + GFP_KERNEL, cpu_to_node(cpu)); zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), GFP_KERNEL, cpu_to_node(cpu)); /* @@ -602,7 +626,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } + /* Init the cpumasks so the boot CPU is related to itself */ cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); + cpumask_set_cpu(boot_cpuid, cpu_l2_cache_mask(boot_cpuid)); cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid)); if (smp_ops && smp_ops->probe) @@ -828,33 +854,6 @@ int cpu_first_thread_of_core(int core) } EXPORT_SYMBOL_GPL(cpu_first_thread_of_core); -static void traverse_siblings_chip_id(int cpu, bool add, int chipid) -{ - const struct cpumask *mask; - struct device_node *np; - int i, plen; - const __be32 *prop; - - mask = add ? cpu_online_mask : cpu_present_mask; - for_each_cpu(i, mask) { - np = of_get_cpu_node(i, NULL); - if (!np) - continue; - prop = of_get_property(np, "ibm,chip-id", &plen); - if (prop && plen == sizeof(int) && - of_read_number(prop, 1) == chipid) { - if (add) { - cpumask_set_cpu(cpu, cpu_core_mask(i)); - cpumask_set_cpu(i, cpu_core_mask(cpu)); - } else { - cpumask_clear_cpu(cpu, cpu_core_mask(i)); - cpumask_clear_cpu(i, cpu_core_mask(cpu)); - } - } - of_node_put(np); - } -} - /* Must be called when no change can occur to cpu_present_mask, * i.e. during cpu online or offline. */ @@ -877,52 +876,93 @@ static struct device_node *cpu_to_l2cache(int cpu) return cache; } -static void traverse_core_siblings(int cpu, bool add) +static bool update_mask_by_l2(int cpu, struct cpumask *(*mask_fn)(int)) { struct device_node *l2_cache, *np; - const struct cpumask *mask; - int i, chip, plen; - const __be32 *prop; - - /* First see if we have ibm,chip-id properties in cpu nodes */ - np = of_get_cpu_node(cpu, NULL); - if (np) { - chip = -1; - prop = of_get_property(np, "ibm,chip-id", &plen); - if (prop && plen == sizeof(int)) - chip = of_read_number(prop, 1); - of_node_put(np); - if (chip >= 0) { - traverse_siblings_chip_id(cpu, add, chip); - return; - } - } + int i; l2_cache = cpu_to_l2cache(cpu); - mask = add ? cpu_online_mask : cpu_present_mask; - for_each_cpu(i, mask) { + if (!l2_cache) + return false; + + for_each_cpu(i, cpu_online_mask) { + /* + * when updating the marks the current CPU has not been marked + * online, but we need to update the cache masks + */ np = cpu_to_l2cache(i); if (!np) continue; - if (np == l2_cache) { - if (add) { - cpumask_set_cpu(cpu, cpu_core_mask(i)); - cpumask_set_cpu(i, cpu_core_mask(cpu)); - } else { - cpumask_clear_cpu(cpu, cpu_core_mask(i)); - cpumask_clear_cpu(i, cpu_core_mask(cpu)); - } - } + + if (np == l2_cache) + set_cpus_related(cpu, i, mask_fn); + of_node_put(np); } of_node_put(l2_cache); + + return true; } +#ifdef CONFIG_HOTPLUG_CPU +static void remove_cpu_from_masks(int cpu) +{ + int i; + + /* NB: cpu_core_mask is a superset of the others */ + for_each_cpu(i, cpu_core_mask(cpu)) { + set_cpus_unrelated(cpu, i, cpu_core_mask); + set_cpus_unrelated(cpu, i, cpu_l2_cache_mask); + set_cpus_unrelated(cpu, i, cpu_sibling_mask); + } +} +#endif + +static void add_cpu_to_masks(int cpu) +{ + int first_thread = cpu_first_thread_sibling(cpu); + int chipid = cpu_to_chip_id(cpu); + int i; + + /* + * This CPU will not be in the online mask yet so we need to manually + * add it to it's own thread sibling mask. + */ + cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); + + for (i = first_thread; i < first_thread + threads_per_core; i++) + if (cpu_online(i)) + set_cpus_related(i, cpu, cpu_sibling_mask); + + /* + * Copy the thread sibling mask into the cache sibling mask + * and mark any CPUs that share an L2 with this CPU. + */ + for_each_cpu(i, cpu_sibling_mask(cpu)) + set_cpus_related(cpu, i, cpu_l2_cache_mask); + update_mask_by_l2(cpu, cpu_l2_cache_mask); + + /* + * Copy the cache sibling mask into core sibling mask and mark + * any CPUs on the same chip as this CPU. + */ + for_each_cpu(i, cpu_l2_cache_mask(cpu)) + set_cpus_related(cpu, i, cpu_core_mask); + + if (chipid == -1) + return; + + for_each_cpu(i, cpu_online_mask) + if (cpu_to_chip_id(i) == chipid) + set_cpus_related(cpu, i, cpu_core_mask); +} + +static bool shared_caches; + /* Activate a secondary processor. */ void start_secondary(void *unused) { unsigned int cpu = smp_processor_id(); - int i, base; mmgrab(&init_mm); current->active_mm = &init_mm; @@ -945,22 +985,15 @@ void start_secondary(void *unused) vdso_getcpu_init(); #endif - /* Update sibling maps */ - base = cpu_first_thread_sibling(cpu); - for (i = 0; i < threads_per_core; i++) { - if (cpu_is_offline(base + i) && (cpu != base + i)) - continue; - cpumask_set_cpu(cpu, cpu_sibling_mask(base + i)); - cpumask_set_cpu(base + i, cpu_sibling_mask(cpu)); + /* Update topology CPU masks */ + add_cpu_to_masks(cpu); - /* cpu_core_map should be a superset of - * cpu_sibling_map even if we don't have cache - * information, so update the former here, too. - */ - cpumask_set_cpu(cpu, cpu_core_mask(base + i)); - cpumask_set_cpu(base + i, cpu_core_mask(cpu)); - } - traverse_core_siblings(cpu, true); + /* + * Check for any shared caches. Note that this must be done on a + * per-core basis because one core in the pair might be disabled. + */ + if (!cpumask_equal(cpu_l2_cache_mask(cpu), cpu_sibling_mask(cpu))) + shared_caches = true; set_numa_node(numa_cpu_lookup_table[cpu]); set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); @@ -1003,35 +1036,65 @@ static struct sched_domain_topology_level powerpc_topology[] = { { NULL, }, }; -static __init long smp_setup_cpu_workfn(void *data __always_unused) +/* + * P9 has a slightly odd architecture where pairs of cores share an L2 cache. + * This topology makes it *much* cheaper to migrate tasks between adjacent cores + * since the migrated task remains cache hot. We want to take advantage of this + * at the scheduler level so an extra topology level is required. + */ +static int powerpc_shared_cache_flags(void) { - smp_ops->setup_cpu(boot_cpuid); - return 0; + return SD_SHARE_PKG_RESOURCES; } +/* + * We can't just pass cpu_l2_cache_mask() directly because + * returns a non-const pointer and the compiler barfs on that. + */ +static const struct cpumask *shared_cache_mask(int cpu) +{ + return cpu_l2_cache_mask(cpu); +} + +static struct sched_domain_topology_level power9_topology[] = { +#ifdef CONFIG_SCHED_SMT + { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, +#endif + { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, + { cpu_cpu_mask, SD_INIT_NAME(DIE) }, + { NULL, }, +}; + void __init smp_cpus_done(unsigned int max_cpus) { /* - * We want the setup_cpu() here to be called on the boot CPU, but - * init might run on any CPU, so make sure it's invoked on the boot - * CPU. + * We are running pinned to the boot CPU, see rest_init(). */ if (smp_ops && smp_ops->setup_cpu) - work_on_cpu_safe(boot_cpuid, smp_setup_cpu_workfn, NULL); + smp_ops->setup_cpu(boot_cpuid); if (smp_ops && smp_ops->bringup_done) smp_ops->bringup_done(); dump_numa_cpu_topology(); - set_sched_topology(powerpc_topology); + /* + * If any CPU detects that it's sharing a cache with another CPU then + * use the deeper topology that is aware of this sharing. + */ + if (shared_caches) { + pr_info("Using shared cache scheduler topology\n"); + set_sched_topology(power9_topology); + } else { + pr_info("Using standard scheduler topology\n"); + set_sched_topology(powerpc_topology); + } } #ifdef CONFIG_HOTPLUG_CPU int __cpu_disable(void) { int cpu = smp_processor_id(); - int base, i; int err; if (!smp_ops->cpu_disable) @@ -1042,14 +1105,7 @@ int __cpu_disable(void) return err; /* Update sibling maps */ - base = cpu_first_thread_sibling(cpu); - for (i = 0; i < threads_per_core && base + i < nr_cpu_ids; i++) { - cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); - cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); - cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); - cpumask_clear_cpu(base + i, cpu_core_mask(cpu)); - } - traverse_core_siblings(cpu, false); + remove_cpu_from_masks(cpu); return 0; } diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S index 988f38dced0fb02e4d8b95c4d51df7d581e471ce..82d8aae81c6adb86ddbd07125e96eb936a48cc10 100644 --- a/arch/powerpc/kernel/swsusp_asm64.S +++ b/arch/powerpc/kernel/swsusp_asm64.S @@ -179,7 +179,7 @@ nothing_to_copy: sld r3, r3, r0 li r0, 0 1: - dcbf r0,r3 + dcbf 0,r3 addi r3,r3,0x20 bdnz 1b diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 4d6b1d3a747f63cd8b9f54aff9ec3ebb2da11c94..7ccb7f81f8db813a82fd72014cf1efc0fed57807 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -17,13 +17,13 @@ #include #ifdef CONFIG_PPC64 -#define SYSCALL(func) .llong DOTSYM(sys_##func),DOTSYM(sys_##func) -#define COMPAT_SYS(func) .llong DOTSYM(sys_##func),DOTSYM(compat_sys_##func) -#define PPC_SYS(func) .llong DOTSYM(ppc_##func),DOTSYM(ppc_##func) -#define OLDSYS(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall) -#define SYS32ONLY(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func) -#define PPC64ONLY(func) .llong DOTSYM(ppc_##func),DOTSYM(sys_ni_syscall) -#define SYSX(f, f3264, f32) .llong DOTSYM(f),DOTSYM(f3264) +#define SYSCALL(func) .8byte DOTSYM(sys_##func),DOTSYM(sys_##func) +#define COMPAT_SYS(func) .8byte DOTSYM(sys_##func),DOTSYM(compat_sys_##func) +#define PPC_SYS(func) .8byte DOTSYM(ppc_##func),DOTSYM(ppc_##func) +#define OLDSYS(func) .8byte DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall) +#define SYS32ONLY(func) .8byte DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func) +#define PPC64ONLY(func) .8byte DOTSYM(ppc_##func),DOTSYM(sys_ni_syscall) +#define SYSX(f, f3264, f32) .8byte DOTSYM(f),DOTSYM(f3264) #else #define SYSCALL(func) .long sys_##func #define COMPAT_SYS(func) .long sys_##func diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index bfcfd9ef09f20a3980f544373616e6ceba3de88c..13c9dcdcba6922e32d4c00267201f47e9498f805 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -114,6 +114,28 @@ static void pmac_backlight_unblank(void) static inline void pmac_backlight_unblank(void) { } #endif +/* + * If oops/die is expected to crash the machine, return true here. + * + * This should not be expected to be 100% accurate, there may be + * notifiers registered or other unexpected conditions that may bring + * down the kernel. Or if the current process in the kernel is holding + * locks or has other critical state, the kernel may become effectively + * unusable anyway. + */ +bool die_will_crash(void) +{ + if (should_fadump_crash()) + return true; + if (kexec_should_crash(current)) + return true; + if (in_interrupt() || panic_on_oops || + !current->pid || is_global_init(current)) + return true; + + return false; +} + static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count; @@ -162,21 +184,9 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, crash_fadump(regs, "die oops"); - /* - * A system reset (0x100) is a request to dump, so we always send - * it through the crashdump code. - */ - if (kexec_should_crash(current) || (TRAP(regs) == 0x100)) { + if (kexec_should_crash(current)) crash_kexec(regs); - /* - * We aren't the primary crash CPU. We need to send it - * to a holding pattern to avoid it ending up in the panic - * code. - */ - crash_kexec_secondary(regs); - } - if (!signr) return; @@ -202,18 +212,25 @@ NOKPROBE_SYMBOL(oops_end); static int __die(const char *str, struct pt_regs *regs, long err) { printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); -#endif -#ifdef CONFIG_SMP - printk("SMP NR_CPUS=%d ", NR_CPUS); -#endif + + if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) + printk("LE "); + else + printk("BE "); + + if (IS_ENABLED(CONFIG_PREEMPT)) + pr_cont("PREEMPT "); + + if (IS_ENABLED(CONFIG_SMP)) + pr_cont("SMP NR_CPUS=%d ", NR_CPUS); + if (debug_pagealloc_enabled()) - printk("DEBUG_PAGEALLOC "); -#ifdef CONFIG_NUMA - printk("NUMA "); -#endif - printk("%s\n", ppc_md.name ? ppc_md.name : ""); + pr_cont("DEBUG_PAGEALLOC "); + + if (IS_ENABLED(CONFIG_NUMA)) + pr_cont("NUMA "); + + pr_cont("%s\n", ppc_md.name ? ppc_md.name : ""); if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP) return 1; @@ -288,23 +305,52 @@ void system_reset_exception(struct pt_regs *regs) if (!nested) nmi_enter(); + __this_cpu_inc(irq_stat.sreset_irqs); + /* See if any machine dependent calls */ if (ppc_md.system_reset_exception) { if (ppc_md.system_reset_exception(regs)) goto out; } - die("System Reset", regs, SIGABRT); + if (debugger(regs)) + goto out; + + /* + * A system reset is a request to dump, so we always send + * it through the crashdump code (if fadump or kdump are + * registered). + */ + crash_fadump(regs, "System Reset"); + + crash_kexec(regs); + + /* + * We aren't the primary crash CPU. We need to send it + * to a holding pattern to avoid it ending up in the panic + * code. + */ + crash_kexec_secondary(regs); + + /* + * No debugger or crash dump registered, print logs then + * panic. + */ + __die("System Reset", regs, SIGABRT); + + mdelay(2*MSEC_PER_SEC); /* Wait a little while for others to print */ + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); + nmi_panic(regs, "System Reset"); out: #ifdef CONFIG_PPC_BOOK3S_64 BUG_ON(get_paca()->in_nmi == 0); if (get_paca()->in_nmi > 1) - panic("Unrecoverable nested System Reset"); + nmi_panic(regs, "Unrecoverable nested System Reset"); #endif /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) - panic("Unrecoverable System Reset"); + nmi_panic(regs, "Unrecoverable System Reset"); if (!nested) nmi_exit(); @@ -312,39 +358,6 @@ void system_reset_exception(struct pt_regs *regs) /* What should we do here? We could issue a shutdown or hard reset. */ } -#ifdef CONFIG_PPC64 -/* - * This function is called in real mode. Strictly no printk's please. - * - * regs->nip and regs->msr contains srr0 and ssr1. - */ -long machine_check_early(struct pt_regs *regs) -{ - long handled = 0; - - __this_cpu_inc(irq_stat.mce_exceptions); - - if (cur_cpu_spec && cur_cpu_spec->machine_check_early) - handled = cur_cpu_spec->machine_check_early(regs); - return handled; -} - -long hmi_exception_realmode(struct pt_regs *regs) -{ - __this_cpu_inc(irq_stat.hmi_exceptions); - - wait_for_subcore_guest_exit(); - - if (ppc_md.hmi_exception_early) - ppc_md.hmi_exception_early(regs); - - wait_for_tb_resync(); - - return 0; -} - -#endif - /* * I/O accesses can cause machine checks on powermacs. * Check if the NIP corresponds to the address of a sync @@ -397,11 +410,6 @@ static inline int check_io_access(struct pt_regs *regs) /* On 4xx, the reason for the machine check or program exception is in the ESR. */ #define get_reason(regs) ((regs)->dsisr) -#ifndef CONFIG_FSL_BOOKE -#define get_mc_reason(regs) ((regs)->dsisr) -#else -#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) -#endif #define REASON_FP ESR_FP #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) #define REASON_PRIVILEGED ESR_PPR @@ -415,111 +423,21 @@ static inline int check_io_access(struct pt_regs *regs) /* On non-4xx, the reason for the machine check or program exception is in the MSR. */ #define get_reason(regs) ((regs)->msr) -#define get_mc_reason(regs) ((regs)->msr) -#define REASON_TM 0x200000 -#define REASON_FP 0x100000 -#define REASON_ILLEGAL 0x80000 -#define REASON_PRIVILEGED 0x40000 -#define REASON_TRAP 0x20000 +#define REASON_TM SRR1_PROGTM +#define REASON_FP SRR1_PROGFPE +#define REASON_ILLEGAL SRR1_PROGILL +#define REASON_PRIVILEGED SRR1_PROGPRIV +#define REASON_TRAP SRR1_PROGTRAP #define single_stepping(regs) ((regs)->msr & MSR_SE) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif -#if defined(CONFIG_4xx) -int machine_check_4xx(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - - if (reason & ESR_IMCP) { - printk("Instruction"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - } else - printk("Data"); - printk(" machine check in kernel mode.\n"); - - return 0; -} - -int machine_check_440A(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - - printk("Machine check in kernel mode.\n"); - if (reason & ESR_IMCP){ - printk("Instruction Synchronous Machine Check exception\n"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - } - else { - u32 mcsr = mfspr(SPRN_MCSR); - if (mcsr & MCSR_IB) - printk("Instruction Read PLB Error\n"); - if (mcsr & MCSR_DRB) - printk("Data Read PLB Error\n"); - if (mcsr & MCSR_DWB) - printk("Data Write PLB Error\n"); - if (mcsr & MCSR_TLBP) - printk("TLB Parity Error\n"); - if (mcsr & MCSR_ICP){ - flush_instruction_cache(); - printk("I-Cache Parity Error\n"); - } - if (mcsr & MCSR_DCSP) - printk("D-Cache Search Parity Error\n"); - if (mcsr & MCSR_DCFP) - printk("D-Cache Flush Parity Error\n"); - if (mcsr & MCSR_IMPE) - printk("Machine Check exception is imprecise\n"); - - /* Clear MCSR */ - mtspr(SPRN_MCSR, mcsr); - } - return 0; -} - -int machine_check_47x(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - u32 mcsr; - - printk(KERN_ERR "Machine check in kernel mode.\n"); - if (reason & ESR_IMCP) { - printk(KERN_ERR - "Instruction Synchronous Machine Check exception\n"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - return 0; - } - mcsr = mfspr(SPRN_MCSR); - if (mcsr & MCSR_IB) - printk(KERN_ERR "Instruction Read PLB Error\n"); - if (mcsr & MCSR_DRB) - printk(KERN_ERR "Data Read PLB Error\n"); - if (mcsr & MCSR_DWB) - printk(KERN_ERR "Data Write PLB Error\n"); - if (mcsr & MCSR_TLBP) - printk(KERN_ERR "TLB Parity Error\n"); - if (mcsr & MCSR_ICP) { - flush_instruction_cache(); - printk(KERN_ERR "I-Cache Parity Error\n"); - } - if (mcsr & MCSR_DCSP) - printk(KERN_ERR "D-Cache Search Parity Error\n"); - if (mcsr & PPC47x_MCSR_GPR) - printk(KERN_ERR "GPR Parity Error\n"); - if (mcsr & PPC47x_MCSR_FPR) - printk(KERN_ERR "FPR Parity Error\n"); - if (mcsr & PPC47x_MCSR_IPR) - printk(KERN_ERR "Machine Check exception is imprecise\n"); - - /* Clear MCSR */ - mtspr(SPRN_MCSR, mcsr); - - return 0; -} -#elif defined(CONFIG_E500) +#if defined(CONFIG_E500) int machine_check_e500mc(struct pt_regs *regs) { unsigned long mcsr = mfspr(SPRN_MCSR); + unsigned long pvr = mfspr(SPRN_PVR); unsigned long reason = mcsr; int recoverable = 1; @@ -561,8 +479,15 @@ int machine_check_e500mc(struct pt_regs *regs) * may still get logged and cause a machine check. We should * only treat the non-write shadow case as non-recoverable. */ - if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) - recoverable = 0; + /* On e6500 core, L1 DCWS (Data cache write shadow mode) bit + * is not implemented but L1 data cache always runs in write + * shadow mode. Hence on data cache parity errors HW will + * automatically invalidate the L1 Data Cache. + */ + if (PVR_VER(pvr) != PVR_VER_E6500) { + if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) + recoverable = 0; + } } if (reason & MCSR_L2MMU_MHIT) { @@ -618,7 +543,7 @@ int machine_check_e500mc(struct pt_regs *regs) int machine_check_e500(struct pt_regs *regs) { - unsigned long reason = get_mc_reason(regs); + unsigned long reason = mfspr(SPRN_MCSR); if (reason & MCSR_BUS_RBERR) { if (fsl_rio_mcheck_exception(regs)) @@ -665,7 +590,7 @@ int machine_check_generic(struct pt_regs *regs) #elif defined(CONFIG_E200) int machine_check_e200(struct pt_regs *regs) { - unsigned long reason = get_mc_reason(regs); + unsigned long reason = mfspr(SPRN_MCSR); printk("Machine check in kernel mode.\n"); printk("Caused by (from MCSR=%lx): ", reason); @@ -687,35 +612,10 @@ int machine_check_e200(struct pt_regs *regs) return 0; } -#elif defined(CONFIG_PPC_8xx) -int machine_check_8xx(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - - pr_err("Machine check in kernel mode.\n"); - pr_err("Caused by (from SRR1=%lx): ", reason); - if (reason & 0x40000000) - pr_err("Fetch error at address %lx\n", regs->nip); - else - pr_err("Data access error at address %lx\n", regs->dar); - -#ifdef CONFIG_PCI - /* the qspan pci read routines can cause machine checks -- Cort - * - * yuck !!! that totally needs to go away ! There are better ways - * to deal with that than having a wart in the mcheck handler. - * -- BenH - */ - bad_page_fault(regs, regs->dar, SIGBUS); - return 1; -#else - return 0; -#endif -} -#else +#elif defined(CONFIG_PPC32) int machine_check_generic(struct pt_regs *regs) { - unsigned long reason = get_mc_reason(regs); + unsigned long reason = regs->msr; printk("Machine check in kernel mode.\n"); printk("Caused by (from SRR1=%lx): ", reason); @@ -752,10 +652,14 @@ int machine_check_generic(struct pt_regs *regs) void machine_check_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); int recover = 0; + bool nested = in_nmi(); + if (!nested) + nmi_enter(); - __this_cpu_inc(irq_stat.mce_exceptions); + /* 64s accounts the mce in machine_check_early when in HVMODE */ + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) || !cpu_has_feature(CPU_FTR_HVMODE)) + __this_cpu_inc(irq_stat.mce_exceptions); add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); @@ -783,10 +687,11 @@ void machine_check_exception(struct pt_regs *regs) /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) - panic("Unrecoverable Machine check"); + nmi_panic(regs, "Unrecoverable Machine check"); bail: - exception_exit(prev_state); + if (!nested) + nmi_exit(); } void SMIException(struct pt_regs *regs) @@ -1672,24 +1577,6 @@ void performance_monitor_exception(struct pt_regs *regs) perf_irq(regs); } -#ifdef CONFIG_8xx -void SoftwareEmulation(struct pt_regs *regs) -{ - CHECK_FULL_REGS(regs); - - if (!user_mode(regs)) { - debugger(regs); - die("Kernel Mode Unimplemented Instruction or SW FPU Emulation", - regs, SIGFPE); - } - - if (!emulate_math(regs)) - return; - - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); -} -#endif /* CONFIG_8xx */ - #ifdef CONFIG_PPC_ADV_DEBUG_REGS static void handle_debug(struct pt_regs *regs, unsigned long debug_status) { diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index 003b20964ea0dfa435af8e1aac8fadde534f1fc2..5d105b8eeecec0215e0b3ec5db226b1a78b2f9f2 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c @@ -205,3 +205,12 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs return orig_ret_vaddr; } + +bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, + struct pt_regs *regs) +{ + if (ctx == RP_CHECK_CHAIN_CALL) + return regs->gpr[1] <= ret->stack; + else + return regs->gpr[1] < ret->stack; +} diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 6b2b69616e7762507f3375300513834f328bb503..769c2624e0a6b4dc162d12781d29198a84d51786 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -232,15 +232,9 @@ __do_get_tspec: lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) /* Get a stable TB value */ -#ifdef CONFIG_8xx -2: mftbu r3 - mftbl r4 - mftbu r0 -#else -2: mfspr r3, SPRN_TBRU - mfspr r4, SPRN_TBRL - mfspr r0, SPRN_TBRU -#endif +2: MFTBU(r3) + MFTBL(r4) + MFTBU(r0) cmplw cr0,r3,r0 bne- 2b diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index b1a250560198a7960f5d7bc9f197a8a4fd4c8e6f..882628fa6987cfdf161aa3afee565a67f03765f8 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -8,7 +8,7 @@ #include #include -#ifdef CONFIG_STRICT_KERNEL_RWX +#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_PPC32) #define STRICT_ALIGN_SIZE (1 << 24) #else #define STRICT_ALIGN_SIZE PAGE_SIZE diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c index b67f8b03a32d0f12ce29eeb4ac3be0a97384fe72..c702a898145250aa4e4da3a88bd32a960ad4fb78 100644 --- a/arch/powerpc/kernel/watchdog.c +++ b/arch/powerpc/kernel/watchdog.c @@ -71,15 +71,20 @@ static inline void wd_smp_lock(unsigned long *flags) * This may be called from low level interrupt handlers at some * point in future. */ - local_irq_save(*flags); - while (unlikely(test_and_set_bit_lock(0, &__wd_smp_lock))) - cpu_relax(); + raw_local_irq_save(*flags); + hard_irq_disable(); /* Make it soft-NMI safe */ + while (unlikely(test_and_set_bit_lock(0, &__wd_smp_lock))) { + raw_local_irq_restore(*flags); + spin_until_cond(!test_bit(0, &__wd_smp_lock)); + raw_local_irq_save(*flags); + hard_irq_disable(); + } } static inline void wd_smp_unlock(unsigned long *flags) { clear_bit_unlock(0, &__wd_smp_lock); - local_irq_restore(*flags); + raw_local_irq_restore(*flags); } static void wd_lockup_ipi(struct pt_regs *regs) @@ -96,10 +101,10 @@ static void wd_lockup_ipi(struct pt_regs *regs) nmi_panic(regs, "Hard LOCKUP"); } -static void set_cpu_stuck(int cpu, u64 tb) +static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb) { - cpumask_set_cpu(cpu, &wd_smp_cpus_stuck); - cpumask_clear_cpu(cpu, &wd_smp_cpus_pending); + cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask); + cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask); if (cpumask_empty(&wd_smp_cpus_pending)) { wd_smp_last_reset_tb = tb; cpumask_andnot(&wd_smp_cpus_pending, @@ -107,6 +112,10 @@ static void set_cpu_stuck(int cpu, u64 tb) &wd_smp_cpus_stuck); } } +static void set_cpu_stuck(int cpu, u64 tb) +{ + set_cpumask_stuck(cpumask_of(cpu), tb); +} static void watchdog_smp_panic(int cpu, u64 tb) { @@ -135,11 +144,9 @@ static void watchdog_smp_panic(int cpu, u64 tb) } smp_flush_nmi_ipi(1000000); - /* Take the stuck CPU out of the watch group */ - for_each_cpu(c, &wd_smp_cpus_pending) - set_cpu_stuck(c, tb); + /* Take the stuck CPUs out of the watch group */ + set_cpumask_stuck(&wd_smp_cpus_pending, tb); -out: wd_smp_unlock(&flags); printk_safe_flush(); @@ -152,6 +159,11 @@ static void watchdog_smp_panic(int cpu, u64 tb) if (hardlockup_panic) nmi_panic(NULL, "Hard LOCKUP"); + + return; + +out: + wd_smp_unlock(&flags); } static void wd_smp_clear_cpu_pending(int cpu, u64 tb) @@ -204,6 +216,9 @@ void soft_nmi_interrupt(struct pt_regs *regs) return; nmi_enter(); + + __this_cpu_inc(irq_stat.soft_nmi_irqs); + tb = get_tb(); if (tb - per_cpu(wd_timer_tb, cpu) >= wd_panic_timeout_tb) { per_cpu(wd_timer_tb, cpu) = tb; @@ -258,9 +273,11 @@ static void wd_timer_fn(unsigned long data) void arch_touch_nmi_watchdog(void) { + unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000; int cpu = smp_processor_id(); - watchdog_timer_interrupt(cpu); + if (get_tb() - per_cpu(wd_timer_tb, cpu) >= ticks) + watchdog_timer_interrupt(cpu); } EXPORT_SYMBOL(arch_touch_nmi_watchdog); @@ -283,6 +300,8 @@ static void stop_watchdog_timer_on(unsigned int cpu) static int start_wd_on_cpu(unsigned int cpu) { + unsigned long flags; + if (cpumask_test_cpu(cpu, &wd_cpus_enabled)) { WARN_ON(1); return 0; @@ -291,18 +310,17 @@ static int start_wd_on_cpu(unsigned int cpu) if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) return 0; - if (watchdog_suspended) - return 0; - if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) return 0; + wd_smp_lock(&flags); cpumask_set_cpu(cpu, &wd_cpus_enabled); if (cpumask_weight(&wd_cpus_enabled) == 1) { cpumask_set_cpu(cpu, &wd_smp_cpus_pending); wd_smp_last_reset_tb = get_tb(); } - smp_wmb(); + wd_smp_unlock(&flags); + start_watchdog_timer_on(cpu); return 0; @@ -310,12 +328,17 @@ static int start_wd_on_cpu(unsigned int cpu) static int stop_wd_on_cpu(unsigned int cpu) { + unsigned long flags; + if (!cpumask_test_cpu(cpu, &wd_cpus_enabled)) return 0; /* Can happen in CPU unplug case */ stop_watchdog_timer_on(cpu); + wd_smp_lock(&flags); cpumask_clear_cpu(cpu, &wd_cpus_enabled); + wd_smp_unlock(&flags); + wd_smp_clear_cpu_pending(cpu, get_tb()); return 0; @@ -332,36 +355,39 @@ static void watchdog_calc_timeouts(void) wd_timer_period_ms = watchdog_thresh * 1000 * 2 / 5; } -void watchdog_nmi_reconfigure(void) +void watchdog_nmi_stop(void) { int cpu; - watchdog_calc_timeouts(); - for_each_cpu(cpu, &wd_cpus_enabled) stop_wd_on_cpu(cpu); +} +void watchdog_nmi_start(void) +{ + int cpu; + + watchdog_calc_timeouts(); for_each_cpu_and(cpu, cpu_online_mask, &watchdog_cpumask) start_wd_on_cpu(cpu); } /* - * This runs after lockup_detector_init() which sets up watchdog_cpumask. + * Invoked from core watchdog init. */ -static int __init powerpc_watchdog_init(void) +int __init watchdog_nmi_probe(void) { int err; - watchdog_calc_timeouts(); - - err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/watchdog:online", - start_wd_on_cpu, stop_wd_on_cpu); - if (err < 0) + err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "powerpc/watchdog:online", + start_wd_on_cpu, stop_wd_on_cpu); + if (err < 0) { pr_warn("Watchdog could not be initialized"); - + return err; + } return 0; } -arch_initcall(powerpc_watchdog_init); static void handle_backtrace_ipi(struct pt_regs *regs) { diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index b42812e014c04b2fc96cdf5d183c23df0ee88b53..7c62967d672caa818d12c26620520603fb3c49c7 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "trace_hv.h" @@ -599,8 +600,8 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, * hugepage split and collapse. */ local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(current->mm->pgd, - hva, NULL, NULL); + ptep = find_current_mm_pte(current->mm->pgd, + hva, NULL, NULL); if (ptep) { pte = kvmppc_read_update_linux_pte(ptep, 1); if (__pte_write(pte)) @@ -1940,6 +1941,7 @@ int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *ghf) rwflag = (ghf->flags & KVM_GET_HTAB_WRITE) ? O_WRONLY : O_RDONLY; ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag | O_CLOEXEC); if (ret < 0) { + kfree(ctx); kvm_put_kvm(kvm); return ret; } diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index f6b3e67c576294f96cbb5a5e5178f09563307c1b..c5d7435455f11ad3adb27743627ee48e71c4cdba 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -17,6 +17,7 @@ #include #include #include +#include /* * Supported radix tree geometry. @@ -322,13 +323,13 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, gpa = vcpu->arch.fault_gpa & ~0xfffUL; gpa &= ~0xF000000000000000ul; gfn = gpa >> PAGE_SHIFT; - if (!(dsisr & DSISR_PGDIRFAULT)) + if (!(dsisr & DSISR_PRTABLE_FAULT)) gpa |= ea & 0xfff; memslot = gfn_to_memslot(kvm, gfn); /* No memslot means it's an emulated MMIO region */ if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) { - if (dsisr & (DSISR_PGDIRFAULT | DSISR_BADACCESS | + if (dsisr & (DSISR_PRTABLE_FAULT | DSISR_BADACCESS | DSISR_SET_RC)) { /* * Bad address in guest page table tree, or other @@ -359,8 +360,7 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, if (writing) pgflags |= _PAGE_DIRTY; local_irq_save(flags); - ptep = __find_linux_pte_or_hugepte(current->mm->pgd, hva, - NULL, NULL); + ptep = find_current_mm_pte(current->mm->pgd, hva, NULL, NULL); if (ptep) { pte = READ_ONCE(*ptep); if (pte_present(pte) && @@ -374,8 +374,12 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, spin_unlock(&kvm->mmu_lock); return RESUME_GUEST; } - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, - gpa, NULL, &shift); + /* + * We are walking the secondary page table here. We can do this + * without disabling irq. + */ + ptep = __find_linux_pte(kvm->arch.pgtable, + gpa, NULL, &shift); if (ptep && pte_present(*ptep)) { kvmppc_radix_update_pte(kvm, ptep, 0, pgflags, gpa, shift); @@ -427,8 +431,8 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, pgflags |= _PAGE_WRITE; } else { local_irq_save(flags); - ptep = __find_linux_pte_or_hugepte(current->mm->pgd, - hva, NULL, NULL); + ptep = find_current_mm_pte(current->mm->pgd, + hva, NULL, NULL); if (ptep && pte_write(*ptep) && pte_dirty(*ptep)) pgflags |= _PAGE_WRITE; local_irq_restore(flags); @@ -499,8 +503,7 @@ int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned int shift; unsigned long old; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep)) { old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_PRESENT, 0, gpa, shift); @@ -525,8 +528,7 @@ int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned int shift; int ref = 0; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep) && pte_young(*ptep)) { kvmppc_radix_update_pte(kvm, ptep, _PAGE_ACCESSED, 0, gpa, shift); @@ -545,8 +547,7 @@ int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned int shift; int ref = 0; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep) && pte_young(*ptep)) ref = 1; return ref; @@ -562,8 +563,7 @@ static int kvm_radix_test_clear_dirty(struct kvm *kvm, unsigned int shift; int ret = 0; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep) && pte_dirty(*ptep)) { ret = 1; if (shift) diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index a160c14304eba22bd83ee98b8f052a2ed8bf7a3f..8f2da8bba737b066488a5c0b3909a02ede239ba6 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -265,8 +265,11 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) { struct kvmppc_spapr_tce_table *stt = filp->private_data; struct kvmppc_spapr_tce_iommu_table *stit, *tmp; + struct kvm *kvm = stt->kvm; + mutex_lock(&kvm->lock); list_del_rcu(&stt->list); + mutex_unlock(&kvm->lock); list_for_each_entry_safe(stit, tmp, &stt->iommu_tables, next) { WARN_ON(!kref_read(&stit->kref)); @@ -294,6 +297,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, struct kvm_create_spapr_tce_64 *args) { struct kvmppc_spapr_tce_table *stt = NULL; + struct kvmppc_spapr_tce_table *siter; unsigned long npages, size; int ret = -ENOMEM; int i; @@ -301,25 +305,17 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, if (!args->size) return -EINVAL; - /* Check this LIOBN hasn't been previously allocated */ - list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) { - if (stt->liobn == args->liobn) - return -EBUSY; - } - size = _ALIGN_UP(args->size, PAGE_SIZE >> 3); npages = kvmppc_tce_pages(size); ret = kvmppc_account_memlimit(kvmppc_stt_pages(npages), true); - if (ret) { - stt = NULL; - goto fail; - } + if (ret) + return ret; ret = -ENOMEM; stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *), GFP_KERNEL); if (!stt) - goto fail; + goto fail_acct; stt->liobn = args->liobn; stt->page_shift = args->page_shift; @@ -334,24 +330,39 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, goto fail; } - kvm_get_kvm(kvm); - mutex_lock(&kvm->lock); - list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables); + + /* Check this LIOBN hasn't been previously allocated */ + ret = 0; + list_for_each_entry(siter, &kvm->arch.spapr_tce_tables, list) { + if (siter->liobn == args->liobn) { + ret = -EBUSY; + break; + } + } + + if (!ret) + ret = anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, + stt, O_RDWR | O_CLOEXEC); + + if (ret >= 0) { + list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables); + kvm_get_kvm(kvm); + } mutex_unlock(&kvm->lock); - return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, - stt, O_RDWR | O_CLOEXEC); + if (ret >= 0) + return ret; -fail: - if (stt) { - for (i = 0; i < npages; i++) - if (stt->pages[i]) - __free_page(stt->pages[i]); + fail: + for (i = 0; i < npages; i++) + if (stt->pages[i]) + __free_page(stt->pages[i]); - kfree(stt); - } + kfree(stt); + fail_acct: + kvmppc_account_memlimit(kvmppc_stt_pages(npages), false); return ret; } diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 3adfd2f5301c686762007e496717d453c258d37c..c32e9bfe75b1abbf6b27a574f91bf5b3fcaf5e66 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef CONFIG_BUG @@ -353,7 +354,16 @@ static long kvmppc_rm_ua_to_hpa(struct kvm_vcpu *vcpu, pte_t *ptep, pte; unsigned shift = 0; - ptep = __find_linux_pte_or_hugepte(vcpu->arch.pgdir, ua, NULL, &shift); + /* + * Called in real mode with MSR_EE = 0. We are safe here. + * It is ok to do the lookup with arch.pgdir here, because + * we are doing this on secondary cpus and current task there + * is not the hypervisor. Also this is safe against THP in the + * host, because an IPI to primary thread will wait for the secondary + * to exit which will agains result in the below page table walk + * to finish. + */ + ptep = __find_linux_pte(vcpu->arch.pgdir, ua, NULL, &shift); if (!ptep || !pte_present(*ptep)) return -ENXIO; pte = *ptep; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 359c79cdf0cc821d87a4e4322177294648b42ee3..73bf1ebfa78fcc7ef74dd51713d800ea12e9e745 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -181,7 +181,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu) struct swait_queue_head *wqp; wqp = kvm_arch_vcpu_wq(vcpu); - if (swait_active(wqp)) { + if (swq_has_sleeper(wqp)) { swake_up(wqp); ++vcpu->stat.halt_wakeup; } @@ -485,7 +485,13 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, switch (subfunc) { case H_VPA_REG_VPA: /* register VPA */ - if (len < sizeof(struct lppaca)) + /* + * The size of our lppaca is 1kB because of the way we align + * it for the guest to avoid crossing a 4kB boundary. We only + * use 640 bytes of the structure though, so we should accept + * clients that set a size of 640. + */ + if (len < 640) break; vpap = &tvcpu->arch.vpa; err = 0; @@ -2111,6 +2117,15 @@ static int kvmppc_grab_hwthread(int cpu) struct paca_struct *tpaca; long timeout = 10000; + /* + * ISA v3.0 idle routines do not set hwthread_state or test + * hwthread_req, so they can not grab idle threads. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + WARN(1, "KVM: can not control sibling threads\n"); + return -EBUSY; + } + tpaca = &paca[cpu]; /* Ensure the thread won't go into the kernel if it wakes */ @@ -2145,10 +2160,12 @@ static void kvmppc_release_hwthread(int cpu) struct paca_struct *tpaca; tpaca = &paca[cpu]; - tpaca->kvm_hstate.hwthread_req = 0; tpaca->kvm_hstate.kvm_vcpu = NULL; tpaca->kvm_hstate.kvm_vcore = NULL; tpaca->kvm_hstate.kvm_split_mode = NULL; + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + tpaca->kvm_hstate.hwthread_req = 0; + } static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) @@ -3325,6 +3342,14 @@ static int kvm_vm_ioctl_get_smmu_info_hv(struct kvm *kvm, if (radix_enabled()) return -EINVAL; + /* + * POWER7, POWER8 and POWER9 all support 32 storage keys for data. + * POWER7 doesn't support keys for instruction accesses, + * POWER8 and POWER9 do. + */ + info->data_keys = 32; + info->instr_keys = cpu_has_feature(CPU_FTR_ARCH_207S) ? 32 : 0; + info->flags = KVM_PPC_PAGE_SIZES_REAL; if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) info->flags |= KVM_PPC_1T_SEGMENTS; @@ -4187,11 +4212,13 @@ static int kvmhv_configure_mmu(struct kvm *kvm, struct kvm_ppc_mmuv3_cfg *cfg) if ((cfg->process_table & PRTS_MASK) > 24) return -EINVAL; + mutex_lock(&kvm->lock); kvm->arch.process_table = cfg->process_table; kvmppc_setup_partition_table(kvm); lpcr = (cfg->flags & KVM_PPC_MMUV3_GTSE) ? LPCR_GTSE : 0; kvmppc_update_lpcr(kvm, lpcr, LPCR_GTSE); + mutex_unlock(&kvm->lock); return 0; } diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 584c74c8119f0db6f4cb76023dfa07ee26a941bd..4efe364f11881b573acb1c18356be40bd34a553a 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Translate address of a vmalloc'd thing to a linear map address */ static void *real_vmalloc_addr(void *x) @@ -31,9 +32,9 @@ static void *real_vmalloc_addr(void *x) /* * assume we don't have huge pages in vmalloc space... * So don't worry about THP collapse/split. Called - * Only in realmode, hence won't need irq_save/restore. + * Only in realmode with MSR_EE = 0, hence won't need irq_save/restore. */ - p = __find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL, NULL); + p = find_init_mm_pte(addr, NULL); if (!p || !pte_present(*p)) return NULL; addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK); @@ -230,14 +231,13 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, * If we had a page table table change after lookup, we would * retry via mmu_notifier_retry. */ - if (realmode) - ptep = __find_linux_pte_or_hugepte(pgdir, hva, NULL, - &hpage_shift); - else { + if (!realmode) local_irq_save(irq_flags); - ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL, - &hpage_shift); - } + /* + * If called in real mode we have MSR_EE = 0. Otherwise + * we disable irq above. + */ + ptep = __find_linux_pte(pgdir, hva, NULL, &hpage_shift); if (ptep) { pte_t pte; unsigned int host_pte_size; @@ -269,7 +269,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, if (!realmode) local_irq_restore(irq_flags); - ptel &= ~(HPTE_R_PP0 - psize); + ptel &= HPTE_R_KEY | HPTE_R_PP0 | (psize-1); ptel |= pa; if (pa) diff --git a/arch/powerpc/kvm/book3s_hv_rm_xive.c b/arch/powerpc/kvm/book3s_hv_rm_xive.c index abf5f01b6eb1f04b05d0643ddc46bb8ded237d8f..5b81a807d742c8b11018ead176b60590064f5d7f 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xive.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xive.c @@ -38,7 +38,6 @@ static inline void __iomem *get_tima_phys(void) #define __x_tima get_tima_phys() #define __x_eoi_page(xd) ((void __iomem *)((xd)->eoi_page)) #define __x_trig_page(xd) ((void __iomem *)((xd)->trig_page)) -#define __x_readb __raw_rm_readb #define __x_writeb __raw_rm_writeb #define __x_readw __raw_rm_readw #define __x_readq __raw_rm_readq diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index c52184a8efdf025c1efffc6dd7310e9374dca630..ec69fa45d5a2f249322d32218a722f4d54390e97 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -149,9 +149,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) subf r4, r4, r3 mtspr SPRN_DEC, r4 +BEGIN_FTR_SECTION /* hwthread_req may have got set by cede or no vcpu, so clear it */ li r0, 0 stb r0, HSTATE_HWTHREAD_REQ(r13) +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) /* * For external interrupts we need to call the Linux @@ -314,6 +316,7 @@ kvm_novcpu_exit: * Relocation is off and most register values are lost. * r13 points to the PACA. * r3 contains the SRR1 wakeup value, SRR1 is trashed. + * This is not used by ISAv3.0B processors. */ .globl kvm_start_guest kvm_start_guest: @@ -432,6 +435,9 @@ kvm_secondary_got_guest: * While waiting we also need to check if we get given a vcpu to run. */ kvm_no_guest: +BEGIN_FTR_SECTION + twi 31,0,0 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) lbz r3, HSTATE_HWTHREAD_REQ(r13) cmpwi r3, 0 bne 53f @@ -765,6 +771,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ bl kvmppc_restore_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif @@ -976,7 +985,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300) #ifdef CONFIG_KVM_XICS /* We are entering the guest on that thread, push VCPU to XIVE */ ld r10, HSTATE_XIVE_TIMA_PHYS(r13) - cmpldi cr0, r10, r0 + cmpldi cr0, r10, 0 beq no_xive ld r11, VCPU_XIVE_SAVED_STATE(r4) li r9, TM_QW1_OS @@ -1112,6 +1121,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) BEGIN_FTR_SECTION mtspr SPRN_PPR, r0 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + +/* Move canary into DSISR to check for later */ +BEGIN_FTR_SECTION + li r0, 0x7fff + mtspr SPRN_HDSISR, r0 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + ld r0, VCPU_GPR(R0)(r4) ld r4, VCPU_GPR(R4)(r4) @@ -1280,7 +1296,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER bne 2f mfspr r3,SPRN_HDEC - cmpwi r3,0 + EXTEND_HDEC(r3) + cmpdi r3,0 mr r4,r9 bge fast_guest_return 2: @@ -1291,6 +1308,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) /* Hypervisor doorbell - exit only if host IPI flag set */ cmpwi r12, BOOK3S_INTERRUPT_H_DOORBELL bne 3f +BEGIN_FTR_SECTION + PPC_MSGSYNC +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) lbz r0, HSTATE_HOST_IPI(r13) cmpwi r0, 0 beq 4f @@ -1620,6 +1640,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ bl kvmppc_save_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif @@ -1739,7 +1762,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) /* * Are we running hash or radix ? */ - beq cr2,3f + ld r5, VCPU_KVM(r9) + lbz r0, KVM_RADIX(r5) + cmpwi cr2, r0, 0 + beq cr2, 3f /* Radix: Handle the case where the guest used an illegal PID */ LOAD_REG_ADDR(r4, mmu_base_pid) @@ -1937,9 +1963,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX) kvmppc_hdsi: ld r3, VCPU_KVM(r9) lbz r0, KVM_RADIX(r3) - cmpwi r0, 0 mfspr r4, SPRN_HDAR mfspr r6, SPRN_HDSISR +BEGIN_FTR_SECTION + /* Look for DSISR canary. If we find it, retry instruction */ + cmpdi r6, 0x7fff + beq 6f +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + cmpwi r0, 0 bne .Lradix_hdsi /* on radix, just save DAR/DSISR/ASDR */ /* HPTE not found fault or protection fault? */ andis. r0, r6, (DSISR_NOHPTE | DSISR_PROTFAULT)@h @@ -2456,6 +2487,9 @@ _GLOBAL(kvmppc_h_cede) /* r3 = vcpu pointer, r11 = msr, r13 = paca */ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ ld r9, HSTATE_KVM_VCPU(r13) bl kvmppc_save_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) @@ -2509,8 +2543,10 @@ kvm_do_nap: clrrdi r0, r0, 1 mtspr SPRN_CTRLT, r0 +BEGIN_FTR_SECTION li r0,1 stb r0,HSTATE_HWTHREAD_REQ(r13) +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) mfspr r5,SPRN_LPCR ori r5,r5,LPCR_PECE0 | LPCR_PECE1 BEGIN_FTR_SECTION @@ -2566,6 +2602,9 @@ kvm_end_cede: #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ bl kvmppc_restore_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 08b200a0bbcec8c47a3128f4685ffcbfad261552..bf457843e03217b9aa02815d7791f0fce72aea2b 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -48,7 +48,6 @@ #define __x_tima xive_tima #define __x_eoi_page(xd) ((void __iomem *)((xd)->eoi_mmio)) #define __x_trig_page(xd) ((void __iomem *)((xd)->trig_mmio)) -#define __x_readb __raw_readb #define __x_writeb __raw_writeb #define __x_readw __raw_readw #define __x_readq __raw_readq @@ -623,7 +622,7 @@ int kvmppc_xive_get_xive(struct kvm *kvm, u32 irq, u32 *server, return -EINVAL; state = &sb->irq_state[idx]; arch_spin_lock(&sb->lock); - *server = state->guest_server; + *server = state->act_server; *priority = state->guest_priority; arch_spin_unlock(&sb->lock); @@ -1332,7 +1331,7 @@ static int xive_get_source(struct kvmppc_xive *xive, long irq, u64 addr) xive->saved_src_count++; /* Convert saved state into something compatible with xics */ - val = state->guest_server; + val = state->act_server; prio = state->saved_scan_prio; if (prio == MASKED) { @@ -1508,7 +1507,6 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) /* First convert prio and mark interrupt as untargetted */ act_prio = xive_prio_from_guest(guest_prio); state->act_priority = MASKED; - state->guest_server = server; /* * We need to drop the lock due to the mutex below. Hopefully diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 5938f7644dc17587dc811132459cf8b71425856a..6ba63f8e8a614ed4aad2a5890236834f3e08c0a7 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -35,7 +35,6 @@ struct kvmppc_xive_irq_state { struct xive_irq_data *pt_data; /* XIVE Pass-through associated data */ /* Targetting as set by guest */ - u32 guest_server; /* Current guest selected target */ u8 guest_priority; /* Guest set priority */ u8 saved_priority; /* Saved priority when masking */ diff --git a/arch/powerpc/kvm/book3s_xive_template.c b/arch/powerpc/kvm/book3s_xive_template.c index 4636ca6e7d383b7d3ce26b18df01152b8087a8ec..c7a5deadd1cc782ddd45667c9fc29f96166e85e7 100644 --- a/arch/powerpc/kvm/book3s_xive_template.c +++ b/arch/powerpc/kvm/book3s_xive_template.c @@ -16,7 +16,23 @@ static void GLUE(X_PFX,ack_pending)(struct kvmppc_xive_vcpu *xc) u8 cppr; u16 ack; - /* XXX DD1 bug workaround: Check PIPR vs. CPPR first ! */ + /* + * Ensure any previous store to CPPR is ordered vs. + * the subsequent loads from PIPR or ACK. + */ + eieio(); + + /* + * DD1 bug workaround: If PIPR is less favored than CPPR + * ignore the interrupt or we might incorrectly lose an IPB + * bit. + */ + if (cpu_has_feature(CPU_FTR_POWER9_DD1)) { + __be64 qw1 = __x_readq(__x_tima + TM_QW1_OS); + u8 pipr = be64_to_cpu(qw1) & 0xff; + if (pipr >= xc->hw_cppr) + return; + } /* Perform the acknowledge OS to register cycle. */ ack = be16_to_cpu(__x_readw(__x_tima + TM_SPC_ACK_OS_REG)); @@ -235,6 +251,11 @@ static u32 GLUE(X_PFX,scan_interrupts)(struct kvmppc_xive_vcpu *xc, /* * If we found an interrupt, adjust what the guest CPPR should * be as if we had just fetched that interrupt from HW. + * + * Note: This can only make xc->cppr smaller as the previous + * loop will only exit with hirq != 0 if prio is lower than + * the current xc->cppr. Thus we don't need to re-check xc->mfrr + * for pending IPIs. */ if (hirq) xc->cppr = prio; @@ -316,7 +337,6 @@ X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned long struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; u8 pending = xc->pending; u32 hirq; - u8 pipr; pr_devel("H_IPOLL(server=%ld)\n", server); @@ -333,7 +353,8 @@ X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned long pending = 0xff; } else { /* Grab pending interrupt if any */ - pipr = __x_readb(__x_tima + TM_QW1_OS + TM_PIPR); + __be64 qw1 = __x_readq(__x_tima + TM_QW1_OS); + u8 pipr = be64_to_cpu(qw1) & 0xff; if (pipr < 8) pending |= 1 << pipr; } @@ -380,6 +401,12 @@ X_STATIC int GLUE(X_PFX,h_cppr)(struct kvm_vcpu *vcpu, unsigned long cppr) old_cppr = xc->cppr; xc->cppr = cppr; + /* + * Order the above update of xc->cppr with the subsequent + * read of xc->mfrr inside push_pending_to_hw() + */ + smp_mb(); + /* * We are masking less, we need to look for pending things * to deliver and set VP pending bits accordingly to trigger @@ -420,21 +447,37 @@ X_STATIC int GLUE(X_PFX,h_eoi)(struct kvm_vcpu *vcpu, unsigned long xirr) * used to signal MFRR changes is EOId when fetched from * the queue. */ - if (irq == XICS_IPI || irq == 0) + if (irq == XICS_IPI || irq == 0) { + /* + * This barrier orders the setting of xc->cppr vs. + * subsquent test of xc->mfrr done inside + * scan_interrupts and push_pending_to_hw + */ + smp_mb(); goto bail; + } /* Find interrupt source */ sb = kvmppc_xive_find_source(xive, irq, &src); if (!sb) { pr_devel(" source not found !\n"); rc = H_PARAMETER; + /* Same as above */ + smp_mb(); goto bail; } state = &sb->irq_state[src]; kvmppc_xive_select_irq(state, &hw_num, &xd); state->in_eoi = true; - mb(); + + /* + * This barrier orders both setting of in_eoi above vs, + * subsequent test of guest_priority, and the setting + * of xc->cppr vs. subsquent test of xc->mfrr done inside + * scan_interrupts and push_pending_to_hw + */ + smp_mb(); again: if (state->guest_priority == MASKED) { @@ -461,6 +504,14 @@ X_STATIC int GLUE(X_PFX,h_eoi)(struct kvm_vcpu *vcpu, unsigned long xirr) } + /* + * This barrier orders the above guest_priority check + * and spin_lock/unlock with clearing in_eoi below. + * + * It also has to be a full mb() as it must ensure + * the MMIOs done in source_eoi() are completed before + * state->in_eoi is visible. + */ mb(); state->in_eoi = false; bail: @@ -495,6 +546,18 @@ X_STATIC int GLUE(X_PFX,h_ipi)(struct kvm_vcpu *vcpu, unsigned long server, /* Locklessly write over MFRR */ xc->mfrr = mfrr; + /* + * The load of xc->cppr below and the subsequent MMIO store + * to the IPI must happen after the above mfrr update is + * globally visible so that: + * + * - Synchronize with another CPU doing an H_EOI or a H_CPPR + * updating xc->cppr then reading xc->mfrr. + * + * - The target of the IPI sees the xc->mfrr update + */ + mb(); + /* Shoot the IPI if most favored than target cppr */ if (mfrr < xc->cppr) __x_writeq(0, __x_trig_page(&xc->vp_ipi_data)); diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 32fdab57d604d02eb16886818b0631b6612e3e61..f9f6468f41712549666771fa730c24bdf6673684 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -455,16 +455,20 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_e500(struct kvm *kvm, if (err) goto free_vcpu; - if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) + if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) { + err = -ENOMEM; goto uninit_vcpu; + } err = kvmppc_e500_tlb_init(vcpu_e500); if (err) goto uninit_id; vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!vcpu->arch.shared) + if (!vcpu->arch.shared) { + err = -ENOMEM; goto uninit_tlb; + } return vcpu; diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 77fd043b3ecc50857ac25cc266fd559be715e9de..c6c734424c707002810ccf59d78c6cb670c74555 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "e500.h" #include "timing.h" @@ -476,7 +477,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, * can't run hence pfn won't change. */ local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL, NULL); + ptep = find_linux_pte(pgdir, hva, NULL, NULL); if (ptep) { pte_t pte = READ_ONCE(*ptep); diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index f48a0c22e8f9024e87965df7b0821596d43c926a..d0b6b5788afcff7b15f63fb80f9d2c0c3d656d3b 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -331,8 +331,10 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_e500mc(struct kvm *kvm, goto uninit_vcpu; vcpu->arch.shared = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); - if (!vcpu->arch.shared) + if (!vcpu->arch.shared) { + err = -ENOMEM; goto uninit_tlb; + } return vcpu; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1a75c0b5f4ca8fba049f572e829d46c0cd40329d..3480faaf1ef886118ba1ee26389ea25c4c3d8a69 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -58,6 +58,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) return !!(v->arch.pending_exceptions) || kvm_request_pending(v); } +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) +{ + return false; +} + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) { return 1; diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 3c3146ba62daa5d018a58d43671a009f122c68b8..50d5bf954cff3ef158854ef53dc67d2934e80dcb 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -31,7 +31,8 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o obj-y += checksum_$(BITS).o checksum_wrappers.o -obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o +obj-y += sstep.o ldstfp.o quad.o +obj64-y += quad.o obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index 8aedbb5f4b86ec327383fa0d0b08023bc8ba89e5..da425bb6b3697348a6debe379159a31da9b66ea0 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -67,6 +67,20 @@ CACHELINE_BYTES = L1_CACHE_BYTES LG_CACHELINE_BYTES = L1_CACHE_SHIFT CACHELINE_MASK = (L1_CACHE_BYTES-1) +_GLOBAL(memset16) + rlwinm. r0 ,r5, 31, 1, 31 + addi r6, r3, -4 + beq- 2f + rlwimi r4 ,r4 ,16 ,0 ,15 + mtctr r0 +1: stwu r4, 4(r6) + bdnz 1b +2: andi. r0, r5, 1 + beqlr + sth r4, 4(r6) + blr +EXPORT_SYMBOL(memset16) + /* * Use dcbz on the complete cache lines in the destination * to set them to zero. This requires that the destination @@ -77,22 +91,24 @@ CACHELINE_MASK = (L1_CACHE_BYTES-1) * replaced by a nop once cache is active. This is done in machine_init() */ _GLOBAL(memset) + cmplwi 0,r5,4 + blt 7f + rlwimi r4,r4,8,16,23 rlwimi r4,r4,16,0,15 - addi r6,r3,-4 - cmplwi 0,r5,4 - blt 7f - stwu r4,4(r6) + stw r4,0(r3) beqlr - andi. r0,r6,3 + andi. r0,r3,3 add r5,r0,r5 - subf r6,r0,r6 + subf r6,r0,r3 cmplwi 0,r4,0 - bne 2f /* Use normal procedure if r4 is not zero */ -EXPORT_SYMBOL(memset) + /* + * Skip optimised bloc until cache is enabled. Will be replaced + * by 'bne' during boot to use normal procedure if r4 is not zero + */ _GLOBAL(memset_nocache_branch) - b 2f /* Skip optimised bloc until cache is enabled */ + b 2f clrlwi r7,r6,32-LG_CACHELINE_BYTES add r8,r7,r5 @@ -119,7 +135,6 @@ _GLOBAL(memset_nocache_branch) 1: stwu r4,4(r6) bdnz 1b 6: andi. r5,r5,3 -7: cmpwi 0,r5,0 beqlr mtctr r5 addi r6,r6,3 @@ -127,6 +142,15 @@ _GLOBAL(memset_nocache_branch) bdnz 8b blr +7: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r6,r3,-1 +9: stbu r4,1(r6) + bdnz 9b + blr +EXPORT_SYMBOL(memset) + /* * This version uses dcbz on the complete cache lines in the * destination area to reduce memory traffic. This requires that diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S index a84d333ecb09f2c43615eca62178a4cef9ee7652..ca5fc8fa7efc9207372da8d36c517a349432fa4f 100644 --- a/arch/powerpc/lib/copypage_power7.S +++ b/arch/powerpc/lib/copypage_power7.S @@ -45,13 +45,13 @@ _GLOBAL(copypage_power7) .machine push .machine "power4" /* setup read stream 0 */ - dcbt r0,r4,0b01000 /* addr from */ - dcbt r0,r7,0b01010 /* length and depth from */ + dcbt 0,r4,0b01000 /* addr from */ + dcbt 0,r7,0b01010 /* length and depth from */ /* setup write stream 1 */ - dcbtst r0,r9,0b01000 /* addr to */ - dcbtst r0,r10,0b01010 /* length and depth to */ + dcbtst 0,r9,0b01000 /* addr to */ + dcbtst 0,r10,0b01010 /* length and depth to */ eieio - dcbt r0,r8,0b01010 /* all streams GO */ + dcbt 0,r8,0b01010 /* all streams GO */ .machine pop #ifdef CONFIG_ALTIVEC @@ -83,7 +83,7 @@ _GLOBAL(copypage_power7) li r12,112 .align 5 -1: lvx v7,r0,r4 +1: lvx v7,0,r4 lvx v6,r4,r6 lvx v5,r4,r7 lvx v4,r4,r8 @@ -92,7 +92,7 @@ _GLOBAL(copypage_power7) lvx v1,r4,r11 lvx v0,r4,r12 addi r4,r4,128 - stvx v7,r0,r3 + stvx v7,0,r3 stvx v6,r3,r6 stvx v5,r3,r7 stvx v4,r3,r8 diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index 706b7cc1984627278ac490f3ea42ef3cf8127ecf..d416a4a6657858809a9e54d0fea77cb49d8976a3 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -315,13 +315,13 @@ err1; stb r0,0(r3) .machine push .machine "power4" /* setup read stream 0 */ - dcbt r0,r6,0b01000 /* addr from */ - dcbt r0,r7,0b01010 /* length and depth from */ + dcbt 0,r6,0b01000 /* addr from */ + dcbt 0,r7,0b01010 /* length and depth from */ /* setup write stream 1 */ - dcbtst r0,r9,0b01000 /* addr to */ - dcbtst r0,r10,0b01010 /* length and depth to */ + dcbtst 0,r9,0b01000 /* addr to */ + dcbtst 0,r10,0b01010 /* length and depth to */ eieio - dcbt r0,r8,0b01010 /* all streams GO */ + dcbt 0,r8,0b01010 /* all streams GO */ .machine pop beq cr1,.Lunwind_stack_nonvmx_copy @@ -376,26 +376,26 @@ err3; std r0,0(r3) li r11,48 bf cr7*4+3,5f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 addi r4,r4,16 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 addi r3,r3,16 5: bf cr7*4+2,6f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 err3; lvx v0,r4,r9 addi r4,r4,32 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 err3; stvx v0,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 err3; lvx v2,r4,r9 err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 addi r4,r4,64 -err3; stvx v3,r0,r3 +err3; stvx v3,0,r3 err3; stvx v2,r3,r9 err3; stvx v1,r3,r10 err3; stvx v0,r3,r11 @@ -421,7 +421,7 @@ err3; stvx v0,r3,r11 */ .align 5 8: -err4; lvx v7,r0,r4 +err4; lvx v7,0,r4 err4; lvx v6,r4,r9 err4; lvx v5,r4,r10 err4; lvx v4,r4,r11 @@ -430,7 +430,7 @@ err4; lvx v2,r4,r14 err4; lvx v1,r4,r15 err4; lvx v0,r4,r16 addi r4,r4,128 -err4; stvx v7,r0,r3 +err4; stvx v7,0,r3 err4; stvx v6,r3,r9 err4; stvx v5,r3,r10 err4; stvx v4,r3,r11 @@ -451,29 +451,29 @@ err4; stvx v0,r3,r16 mtocrf 0x01,r6 bf cr7*4+1,9f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 err3; lvx v2,r4,r9 err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 addi r4,r4,64 -err3; stvx v3,r0,r3 +err3; stvx v3,0,r3 err3; stvx v2,r3,r9 err3; stvx v1,r3,r10 err3; stvx v0,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 err3; lvx v0,r4,r9 addi r4,r4,32 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 err3; stvx v0,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 addi r4,r4,16 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 addi r3,r3,16 /* Up to 15B to go */ @@ -553,25 +553,25 @@ err3; lvx v0,0,r4 addi r4,r4,16 bf cr7*4+3,5f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 addi r3,r3,16 vor v0,v1,v1 5: bf cr7*4+2,6f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) err3; lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 VPERM(v8,v0,v3,v16) err3; lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -580,7 +580,7 @@ err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 err3; stvx v10,r3,r10 err3; stvx v11,r3,r11 @@ -606,7 +606,7 @@ err3; stvx v11,r3,r11 */ .align 5 8: -err4; lvx v7,r0,r4 +err4; lvx v7,0,r4 VPERM(v8,v0,v7,v16) err4; lvx v6,r4,r9 VPERM(v9,v7,v6,v16) @@ -623,7 +623,7 @@ err4; lvx v1,r4,r15 err4; lvx v0,r4,r16 VPERM(v15,v1,v0,v16) addi r4,r4,128 -err4; stvx v8,r0,r3 +err4; stvx v8,0,r3 err4; stvx v9,r3,r9 err4; stvx v10,r3,r10 err4; stvx v11,r3,r11 @@ -644,7 +644,7 @@ err4; stvx v15,r3,r16 mtocrf 0x01,r6 bf cr7*4+1,9f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 VPERM(v8,v0,v3,v16) err3; lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -653,27 +653,27 @@ err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 err3; stvx v10,r3,r10 err3; stvx v11,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) err3; lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 addi r3,r3,16 /* Up to 15B to go */ diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S index a58777c1b2cba79605290f7375412d16b0e9b516..ae15eba49c1fcd89b61eba5c76ad91774555cbf6 100644 --- a/arch/powerpc/lib/ldstfp.S +++ b/arch/powerpc/lib/ldstfp.S @@ -21,27 +21,19 @@ #define STKFRM (PPC_MIN_STKFRM + 16) - .macro inst32 op -reg = 0 - .rept 32 -20: \op reg,0,r4 - b 3f - EX_TABLE(20b,99f) -reg = reg + 1 - .endr - .endm - -/* Get the contents of frN into fr0; N is in r3. */ +/* Get the contents of frN into *p; N is in r3 and p is in r4. */ _GLOBAL(get_fpr) mflr r0 + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* fr0 is already in fr0 */ - nop -reg = 1 - .rept 31 - fmr fr0,reg - blr +reg = 0 + .rept 32 + stfd reg, 0(r4) + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -49,18 +41,23 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr +2: MTMSRD(r6) + isync + blr -/* Put the contents of fr0 into frN; N is in r3. */ +/* Put the contents of *p into frN; N is in r3 and p is in r4. */ _GLOBAL(put_fpr) mflr r0 + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* fr0 is already in fr0 */ - nop -reg = 1 - .rept 31 - fmr reg,fr0 - blr +reg = 0 + .rept 32 + lfd reg, 0(r4) + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -68,127 +65,24 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr - -/* Load FP reg N from float at *p. N is in r3, p in r4. */ -_GLOBAL(do_lfs) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) - isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) -1: li r9,-EFAULT -2: lfs fr0,0(r4) - li r9,0 -3: bl put_fpr - beq cr7,4f - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) - -/* Load FP reg N from double at *p. N is in r3, p in r4. */ -_GLOBAL(do_lfd) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) - isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) -1: li r9,-EFAULT -2: lfd fr0,0(r4) - li r9,0 -3: beq cr7,4f - bl put_fpr - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) +2: MTMSRD(r6) isync - mr r3,r9 - addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) -/* Store FP reg N to float at *p. N is in r3, p in r4. */ -_GLOBAL(do_stfs) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) - isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) - bl get_fpr -1: li r9,-EFAULT -2: stfs fr0,0(r4) - li r9,0 -3: beq cr7,4f - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) - -/* Store FP reg N to double at *p. N is in r3, p in r4. */ -_GLOBAL(do_stfd) - PPC_STLU r1,-STKFRM(r1) +#ifdef CONFIG_ALTIVEC +/* Get the contents of vrN into *p; N is in r3 and p is in r4. */ +_GLOBAL(get_vr) mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 + oris r7, r6, MSR_VEC@h MTMSRD(r7) isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) - bl get_fpr -1: li r9,-EFAULT -2: stfd fr0,0(r4) - li r9,0 -3: beq cr7,4f - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) - -#ifdef CONFIG_ALTIVEC -/* Get the contents of vrN into v0; N is in r3. */ -_GLOBAL(get_vr) - mflr r0 rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* v0 is already in v0 */ - nop -reg = 1 - .rept 31 - vor v0,reg,reg /* assembler doesn't know vmr? */ - blr +reg = 0 + .rept 32 + stvx reg, 0, r4 + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -196,18 +90,23 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr +2: MTMSRD(r6) + isync + blr -/* Put the contents of v0 into vrN; N is in r3. */ +/* Put the contents of *p into vrN; N is in r3 and p is in r4. */ _GLOBAL(put_vr) mflr r0 + mfmsr r6 + oris r7, r6, MSR_VEC@h + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* v0 is already in v0 */ - nop -reg = 1 - .rept 31 - vor reg,v0,v0 - blr +reg = 0 + .rept 32 + lvx reg, 0, r4 + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -215,62 +114,9 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr - -/* Load vector reg N from *p. N is in r3, p in r4. */ -_GLOBAL(do_lvx) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - oris r7,r6,MSR_VEC@h - cmpwi cr7,r3,0 - li r8,STKFRM-16 - MTMSRD(r7) - isync - beq cr7,1f - stvx v0,r1,r8 -1: li r9,-EFAULT -2: lvx v0,0,r4 - li r9,0 -3: beq cr7,4f - bl put_vr - lvx v0,r1,r8 -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) +2: MTMSRD(r6) isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) - -/* Store vector reg N to *p. N is in r3, p in r4. */ -_GLOBAL(do_stvx) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - oris r7,r6,MSR_VEC@h - cmpwi cr7,r3,0 - li r8,STKFRM-16 - MTMSRD(r7) - isync - beq cr7,1f - stvx v0,r1,r8 - bl get_vr -1: li r9,-EFAULT -2: stvx v0,0,r4 - li r9,0 -3: beq cr7,4f - lvx v0,r1,r8 -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX @@ -313,7 +159,7 @@ reg = reg + 1 bctr /* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */ -_GLOBAL(do_lxvd2x) +_GLOBAL(load_vsrn) PPC_STLU r1,-STKFRM(r1) mflr r0 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) @@ -325,49 +171,74 @@ _GLOBAL(do_lxvd2x) isync beq cr7,1f STXVD2X(0,R1,R8) -1: li r9,-EFAULT -2: LXVD2X(0,R0,R4) - li r9,0 -3: beq cr7,4f +1: LXVD2X(0,R0,R4) +#ifdef __LITTLE_ENDIAN__ + XXSWAPD(0,0) +#endif + beq cr7,4f bl put_vsr LXVD2X(0,R1,R8) 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) mtlr r0 MTMSRD(r6) isync - mr r3,r9 addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) /* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */ -_GLOBAL(do_stxvd2x) +_GLOBAL(store_vsrn) PPC_STLU r1,-STKFRM(r1) mflr r0 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) mfmsr r6 oris r7,r6,MSR_VSX@h - cmpwi cr7,r3,0 li r8,STKFRM-16 MTMSRD(r7) isync - beq cr7,1f STXVD2X(0,R1,R8) bl get_vsr -1: li r9,-EFAULT -2: STXVD2X(0,R0,R4) - li r9,0 -3: beq cr7,4f +#ifdef __LITTLE_ENDIAN__ + XXSWAPD(0,0) +#endif + STXVD2X(0,R0,R4) LXVD2X(0,R1,R8) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) + PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) mtlr r0 MTMSRD(r6) isync mr r3,r9 addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) - #endif /* CONFIG_VSX */ +/* Convert single-precision to double, without disturbing FPRs. */ +/* conv_sp_to_dp(float *sp, double *dp) */ +_GLOBAL(conv_sp_to_dp) + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync + stfd fr0, -16(r1) + lfs fr0, 0(r3) + stfd fr0, 0(r4) + lfd fr0, -16(r1) + MTMSRD(r6) + isync + blr + +/* Convert single-precision to double, without disturbing FPRs. */ +/* conv_sp_to_dp(double *dp, float *sp) */ +_GLOBAL(conv_dp_to_sp) + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync + stfd fr0, -16(r1) + lfd fr0, 0(r3) + stfs fr0, 0(r4) + lfd fr0, -16(r1) + MTMSRD(r6) + isync + blr + #endif /* CONFIG_PPC_FPU */ diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S index 85fa9869aec5848d1c22c7b24e297cb51f1d4a9d..ec531de99996260b2f649034a781b486dbaba819 100644 --- a/arch/powerpc/lib/mem_64.S +++ b/arch/powerpc/lib/mem_64.S @@ -13,6 +13,23 @@ #include #include +_GLOBAL(__memset16) + rlwimi r4,r4,16,0,15 + /* fall through */ + +_GLOBAL(__memset32) + rldimi r4,r4,32,0 + /* fall through */ + +_GLOBAL(__memset64) + neg r0,r3 + andi. r0,r0,7 + cmplw cr1,r5,r0 + b .Lms +EXPORT_SYMBOL(__memset16) +EXPORT_SYMBOL(__memset32) +EXPORT_SYMBOL(__memset64) + _GLOBAL(memset) neg r0,r3 rlwimi r4,r4,8,16,23 @@ -20,7 +37,7 @@ _GLOBAL(memset) rlwimi r4,r4,16,0,15 cmplw cr1,r5,r0 /* do we get that far? */ rldimi r4,r4,32,0 - PPC_MTOCRF(1,r0) +.Lms: PPC_MTOCRF(1,r0) mr r6,r3 blt cr1,8f beq+ 3f /* if already 8-byte aligned */ diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index 786234fd4e914b87676422ce0cfd86f151088603..193909abd18b3edea2170601081753f70cc39577 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S @@ -261,12 +261,12 @@ _GLOBAL(memcpy_power7) .machine push .machine "power4" - dcbt r0,r6,0b01000 - dcbt r0,r7,0b01010 - dcbtst r0,r9,0b01000 - dcbtst r0,r10,0b01010 + dcbt 0,r6,0b01000 + dcbt 0,r7,0b01010 + dcbtst 0,r9,0b01000 + dcbtst 0,r10,0b01010 eieio - dcbt r0,r8,0b01010 /* GO */ + dcbt 0,r8,0b01010 /* GO */ .machine pop beq cr1,.Lunwind_stack_nonvmx_copy @@ -321,26 +321,26 @@ _GLOBAL(memcpy_power7) li r11,48 bf cr7*4+3,5f - lvx v1,r0,r4 + lvx v1,0,r4 addi r4,r4,16 - stvx v1,r0,r3 + stvx v1,0,r3 addi r3,r3,16 5: bf cr7*4+2,6f - lvx v1,r0,r4 + lvx v1,0,r4 lvx v0,r4,r9 addi r4,r4,32 - stvx v1,r0,r3 + stvx v1,0,r3 stvx v0,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f - lvx v3,r0,r4 + lvx v3,0,r4 lvx v2,r4,r9 lvx v1,r4,r10 lvx v0,r4,r11 addi r4,r4,64 - stvx v3,r0,r3 + stvx v3,0,r3 stvx v2,r3,r9 stvx v1,r3,r10 stvx v0,r3,r11 @@ -366,7 +366,7 @@ _GLOBAL(memcpy_power7) */ .align 5 8: - lvx v7,r0,r4 + lvx v7,0,r4 lvx v6,r4,r9 lvx v5,r4,r10 lvx v4,r4,r11 @@ -375,7 +375,7 @@ _GLOBAL(memcpy_power7) lvx v1,r4,r15 lvx v0,r4,r16 addi r4,r4,128 - stvx v7,r0,r3 + stvx v7,0,r3 stvx v6,r3,r9 stvx v5,r3,r10 stvx v4,r3,r11 @@ -396,29 +396,29 @@ _GLOBAL(memcpy_power7) mtocrf 0x01,r6 bf cr7*4+1,9f - lvx v3,r0,r4 + lvx v3,0,r4 lvx v2,r4,r9 lvx v1,r4,r10 lvx v0,r4,r11 addi r4,r4,64 - stvx v3,r0,r3 + stvx v3,0,r3 stvx v2,r3,r9 stvx v1,r3,r10 stvx v0,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f - lvx v1,r0,r4 + lvx v1,0,r4 lvx v0,r4,r9 addi r4,r4,32 - stvx v1,r0,r3 + stvx v1,0,r3 stvx v0,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f - lvx v1,r0,r4 + lvx v1,0,r4 addi r4,r4,16 - stvx v1,r0,r3 + stvx v1,0,r3 addi r3,r3,16 /* Up to 15B to go */ @@ -499,25 +499,25 @@ _GLOBAL(memcpy_power7) addi r4,r4,16 bf cr7*4+3,5f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 - stvx v8,r0,r3 + stvx v8,0,r3 addi r3,r3,16 vor v0,v1,v1 5: bf cr7*4+2,6f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f - lvx v3,r0,r4 + lvx v3,0,r4 VPERM(v8,v0,v3,v16) lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -526,7 +526,7 @@ _GLOBAL(memcpy_power7) lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 stvx v10,r3,r10 stvx v11,r3,r11 @@ -552,7 +552,7 @@ _GLOBAL(memcpy_power7) */ .align 5 8: - lvx v7,r0,r4 + lvx v7,0,r4 VPERM(v8,v0,v7,v16) lvx v6,r4,r9 VPERM(v9,v7,v6,v16) @@ -569,7 +569,7 @@ _GLOBAL(memcpy_power7) lvx v0,r4,r16 VPERM(v15,v1,v0,v16) addi r4,r4,128 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 stvx v10,r3,r10 stvx v11,r3,r11 @@ -590,7 +590,7 @@ _GLOBAL(memcpy_power7) mtocrf 0x01,r6 bf cr7*4+1,9f - lvx v3,r0,r4 + lvx v3,0,r4 VPERM(v8,v0,v3,v16) lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -599,27 +599,27 @@ _GLOBAL(memcpy_power7) lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 stvx v10,r3,r10 stvx v11,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 - stvx v8,r0,r3 + stvx v8,0,r3 addi r3,r3,16 /* Up to 15B to go */ diff --git a/arch/powerpc/lib/quad.S b/arch/powerpc/lib/quad.S new file mode 100644 index 0000000000000000000000000000000000000000..c4d12fae872480c7e58d2d65035af17d2fe0ed40 --- /dev/null +++ b/arch/powerpc/lib/quad.S @@ -0,0 +1,62 @@ +/* + * Quadword loads and stores + * for use in instruction emulation. + * + * Copyright 2017 Paul Mackerras, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +/* do_lq(unsigned long ea, unsigned long *regs) */ +_GLOBAL(do_lq) +1: lq r6, 0(r3) + std r6, 0(r4) + std r7, 8(r4) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) + +/* do_stq(unsigned long ea, unsigned long val0, unsigned long val1) */ +_GLOBAL(do_stq) +1: stq r4, 0(r3) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) + +/* do_lqarx(unsigned long ea, unsigned long *regs) */ +_GLOBAL(do_lqarx) +1: PPC_LQARX(6, 0, 3, 0) + std r6, 0(r4) + std r7, 8(r4) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) + +/* do_stqcx(unsigned long ea, unsigned long val0, unsigned long val1, + unsigned int *crp) */ + +_GLOBAL(do_stqcx) +1: PPC_STQCX(4, 0, 3) + mfcr r5 + stw r5, 0(r6) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index ee33327686aec7a9c8784182383c709706e2394c..5e8418c28bd884bd854818755b61b06fcff776e6 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -36,14 +36,33 @@ extern char system_call_common[]; /* * Functions in ldstfp.S */ -extern int do_lfs(int rn, unsigned long ea); -extern int do_lfd(int rn, unsigned long ea); -extern int do_stfs(int rn, unsigned long ea); -extern int do_stfd(int rn, unsigned long ea); -extern int do_lvx(int rn, unsigned long ea); -extern int do_stvx(int rn, unsigned long ea); -extern int do_lxvd2x(int rn, unsigned long ea); -extern int do_stxvd2x(int rn, unsigned long ea); +extern void get_fpr(int rn, double *p); +extern void put_fpr(int rn, const double *p); +extern void get_vr(int rn, __vector128 *p); +extern void put_vr(int rn, __vector128 *p); +extern void load_vsrn(int vsr, const void *p); +extern void store_vsrn(int vsr, void *p); +extern void conv_sp_to_dp(const float *sp, double *dp); +extern void conv_dp_to_sp(const double *dp, float *sp); +#endif + +#ifdef __powerpc64__ +/* + * Functions in quad.S + */ +extern int do_lq(unsigned long ea, unsigned long *regs); +extern int do_stq(unsigned long ea, unsigned long val0, unsigned long val1); +extern int do_lqarx(unsigned long ea, unsigned long *regs); +extern int do_stqcx(unsigned long ea, unsigned long val0, unsigned long val1, + unsigned int *crp); +#endif + +#ifdef __LITTLE_ENDIAN__ +#define IS_LE 1 +#define IS_BE 0 +#else +#define IS_LE 0 +#define IS_BE 1 #endif /* @@ -62,15 +81,17 @@ static nokprobe_inline unsigned long truncate_if_32bit(unsigned long msr, /* * Determine whether a conditional branch instruction would branch. */ -static nokprobe_inline int branch_taken(unsigned int instr, struct pt_regs *regs) +static nokprobe_inline int branch_taken(unsigned int instr, + const struct pt_regs *regs, + struct instruction_op *op) { unsigned int bo = (instr >> 21) & 0x1f; unsigned int bi; if ((bo & 4) == 0) { /* decrement counter */ - --regs->ctr; - if (((bo >> 1) & 1) ^ (regs->ctr == 0)) + op->type |= DECCTR; + if (((bo >> 1) & 1) ^ (regs->ctr == 1)) return 0; } if ((bo & 0x10) == 0) { @@ -82,17 +103,26 @@ static nokprobe_inline int branch_taken(unsigned int instr, struct pt_regs *regs return 1; } -static nokprobe_inline long address_ok(struct pt_regs *regs, unsigned long ea, int nb) +static nokprobe_inline long address_ok(struct pt_regs *regs, + unsigned long ea, int nb) { if (!user_mode(regs)) return 1; - return __access_ok(ea, nb, USER_DS); + if (__access_ok(ea, nb, USER_DS)) + return 1; + if (__access_ok(ea, 1, USER_DS)) + /* Access overlaps the end of the user region */ + regs->dar = USER_DS.seg; + else + regs->dar = ea; + return 0; } /* * Calculate effective address for a D-form instruction */ -static nokprobe_inline unsigned long dform_ea(unsigned int instr, struct pt_regs *regs) +static nokprobe_inline unsigned long dform_ea(unsigned int instr, + const struct pt_regs *regs) { int ra; unsigned long ea; @@ -102,14 +132,15 @@ static nokprobe_inline unsigned long dform_ea(unsigned int instr, struct pt_regs if (ra) ea += regs->gpr[ra]; - return truncate_if_32bit(regs->msr, ea); + return ea; } #ifdef __powerpc64__ /* * Calculate effective address for a DS-form instruction */ -static nokprobe_inline unsigned long dsform_ea(unsigned int instr, struct pt_regs *regs) +static nokprobe_inline unsigned long dsform_ea(unsigned int instr, + const struct pt_regs *regs) { int ra; unsigned long ea; @@ -119,7 +150,24 @@ static nokprobe_inline unsigned long dsform_ea(unsigned int instr, struct pt_reg if (ra) ea += regs->gpr[ra]; - return truncate_if_32bit(regs->msr, ea); + return ea; +} + +/* + * Calculate effective address for a DQ-form instruction + */ +static nokprobe_inline unsigned long dqform_ea(unsigned int instr, + const struct pt_regs *regs) +{ + int ra; + unsigned long ea; + + ra = (instr >> 16) & 0x1f; + ea = (signed short) (instr & ~0xf); /* sign-extend */ + if (ra) + ea += regs->gpr[ra]; + + return ea; } #endif /* __powerpc64 */ @@ -127,7 +175,7 @@ static nokprobe_inline unsigned long dsform_ea(unsigned int instr, struct pt_reg * Calculate effective address for an X-form instruction */ static nokprobe_inline unsigned long xform_ea(unsigned int instr, - struct pt_regs *regs) + const struct pt_regs *regs) { int ra, rb; unsigned long ea; @@ -138,7 +186,7 @@ static nokprobe_inline unsigned long xform_ea(unsigned int instr, if (ra) ea += regs->gpr[ra]; - return truncate_if_32bit(regs->msr, ea); + return ea; } /* @@ -151,7 +199,6 @@ static nokprobe_inline unsigned long max_align(unsigned long x) return x & -x; /* isolates rightmost bit */ } - static nokprobe_inline unsigned long byterev_2(unsigned long x) { return ((x >> 8) & 0xff) | ((x & 0xff) << 8); @@ -170,8 +217,36 @@ static nokprobe_inline unsigned long byterev_8(unsigned long x) } #endif +static nokprobe_inline void do_byte_reverse(void *ptr, int nb) +{ + switch (nb) { + case 2: + *(u16 *)ptr = byterev_2(*(u16 *)ptr); + break; + case 4: + *(u32 *)ptr = byterev_4(*(u32 *)ptr); + break; +#ifdef __powerpc64__ + case 8: + *(unsigned long *)ptr = byterev_8(*(unsigned long *)ptr); + break; + case 16: { + unsigned long *up = (unsigned long *)ptr; + unsigned long tmp; + tmp = byterev_8(up[0]); + up[0] = byterev_8(up[1]); + up[1] = tmp; + break; + } +#endif + default: + WARN_ON_ONCE(1); + } +} + static nokprobe_inline int read_mem_aligned(unsigned long *dest, - unsigned long ea, int nb) + unsigned long ea, int nb, + struct pt_regs *regs) { int err = 0; unsigned long x = 0; @@ -194,59 +269,77 @@ static nokprobe_inline int read_mem_aligned(unsigned long *dest, } if (!err) *dest = x; + else + regs->dar = ea; return err; } -static nokprobe_inline int read_mem_unaligned(unsigned long *dest, - unsigned long ea, int nb, struct pt_regs *regs) +/* + * Copy from userspace to a buffer, using the largest possible + * aligned accesses, up to sizeof(long). + */ +static int nokprobe_inline copy_mem_in(u8 *dest, unsigned long ea, int nb, + struct pt_regs *regs) { - int err; - unsigned long x, b, c; -#ifdef __LITTLE_ENDIAN__ - int len = nb; /* save a copy of the length for byte reversal */ -#endif + int err = 0; + int c; - /* unaligned, do this in pieces */ - x = 0; for (; nb > 0; nb -= c) { -#ifdef __LITTLE_ENDIAN__ - c = 1; -#endif -#ifdef __BIG_ENDIAN__ c = max_align(ea); -#endif if (c > nb) c = max_align(nb); - err = read_mem_aligned(&b, ea, c); - if (err) - return err; - x = (x << (8 * c)) + b; - ea += c; - } -#ifdef __LITTLE_ENDIAN__ - switch (len) { - case 2: - *dest = byterev_2(x); - break; - case 4: - *dest = byterev_4(x); - break; + switch (c) { + case 1: + err = __get_user(*dest, (unsigned char __user *) ea); + break; + case 2: + err = __get_user(*(u16 *)dest, + (unsigned short __user *) ea); + break; + case 4: + err = __get_user(*(u32 *)dest, + (unsigned int __user *) ea); + break; #ifdef __powerpc64__ - case 8: - *dest = byterev_8(x); - break; + case 8: + err = __get_user(*(unsigned long *)dest, + (unsigned long __user *) ea); + break; #endif + } + if (err) { + regs->dar = ea; + return err; + } + dest += c; + ea += c; } -#endif -#ifdef __BIG_ENDIAN__ - *dest = x; -#endif return 0; } +static nokprobe_inline int read_mem_unaligned(unsigned long *dest, + unsigned long ea, int nb, + struct pt_regs *regs) +{ + union { + unsigned long ul; + u8 b[sizeof(unsigned long)]; + } u; + int i; + int err; + + u.ul = 0; + i = IS_BE ? sizeof(unsigned long) - nb : 0; + err = copy_mem_in(&u.b[i], ea, nb, regs); + if (!err) + *dest = u.ul; + return err; +} + /* * Read memory at address ea for nb bytes, return 0 for success - * or -EFAULT if an error occurred. + * or -EFAULT if an error occurred. N.B. nb must be 1, 2, 4 or 8. + * If nb < sizeof(long), the result is right-justified on BE systems. */ static int read_mem(unsigned long *dest, unsigned long ea, int nb, struct pt_regs *regs) @@ -254,13 +347,14 @@ static int read_mem(unsigned long *dest, unsigned long ea, int nb, if (!address_ok(regs, ea, nb)) return -EFAULT; if ((ea & (nb - 1)) == 0) - return read_mem_aligned(dest, ea, nb); + return read_mem_aligned(dest, ea, nb, regs); return read_mem_unaligned(dest, ea, nb, regs); } NOKPROBE_SYMBOL(read_mem); static nokprobe_inline int write_mem_aligned(unsigned long val, - unsigned long ea, int nb) + unsigned long ea, int nb, + struct pt_regs *regs) { int err = 0; @@ -280,51 +374,72 @@ static nokprobe_inline int write_mem_aligned(unsigned long val, break; #endif } + if (err) + regs->dar = ea; return err; } -static nokprobe_inline int write_mem_unaligned(unsigned long val, - unsigned long ea, int nb, struct pt_regs *regs) +/* + * Copy from a buffer to userspace, using the largest possible + * aligned accesses, up to sizeof(long). + */ +static int nokprobe_inline copy_mem_out(u8 *dest, unsigned long ea, int nb, + struct pt_regs *regs) { - int err; - unsigned long c; + int err = 0; + int c; -#ifdef __LITTLE_ENDIAN__ - switch (nb) { - case 2: - val = byterev_2(val); - break; - case 4: - val = byterev_4(val); - break; -#ifdef __powerpc64__ - case 8: - val = byterev_8(val); - break; -#endif - } -#endif - /* unaligned or little-endian, do this in pieces */ for (; nb > 0; nb -= c) { -#ifdef __LITTLE_ENDIAN__ - c = 1; -#endif -#ifdef __BIG_ENDIAN__ c = max_align(ea); -#endif if (c > nb) c = max_align(nb); - err = write_mem_aligned(val >> (nb - c) * 8, ea, c); - if (err) + switch (c) { + case 1: + err = __put_user(*dest, (unsigned char __user *) ea); + break; + case 2: + err = __put_user(*(u16 *)dest, + (unsigned short __user *) ea); + break; + case 4: + err = __put_user(*(u32 *)dest, + (unsigned int __user *) ea); + break; +#ifdef __powerpc64__ + case 8: + err = __put_user(*(unsigned long *)dest, + (unsigned long __user *) ea); + break; +#endif + } + if (err) { + regs->dar = ea; return err; + } + dest += c; ea += c; } return 0; } +static nokprobe_inline int write_mem_unaligned(unsigned long val, + unsigned long ea, int nb, + struct pt_regs *regs) +{ + union { + unsigned long ul; + u8 b[sizeof(unsigned long)]; + } u; + int i; + + u.ul = val; + i = IS_BE ? sizeof(unsigned long) - nb : 0; + return copy_mem_out(&u.b[i], ea, nb, regs); +} + /* * Write memory at address ea for nb bytes, return 0 for success - * or -EFAULT if an error occurred. + * or -EFAULT if an error occurred. N.B. nb must be 1, 2, 4 or 8. */ static int write_mem(unsigned long val, unsigned long ea, int nb, struct pt_regs *regs) @@ -332,163 +447,465 @@ static int write_mem(unsigned long val, unsigned long ea, int nb, if (!address_ok(regs, ea, nb)) return -EFAULT; if ((ea & (nb - 1)) == 0) - return write_mem_aligned(val, ea, nb); + return write_mem_aligned(val, ea, nb, regs); return write_mem_unaligned(val, ea, nb, regs); } NOKPROBE_SYMBOL(write_mem); #ifdef CONFIG_PPC_FPU /* - * Check the address and alignment, and call func to do the actual - * load or store. + * These access either the real FP register or the image in the + * thread_struct, depending on regs->msr & MSR_FP. */ -static int do_fp_load(int rn, int (*func)(int, unsigned long), - unsigned long ea, int nb, - struct pt_regs *regs) +static int do_fp_load(struct instruction_op *op, unsigned long ea, + struct pt_regs *regs, bool cross_endian) { - int err; + int err, rn, nb; union { - double dbl; - unsigned long ul[2]; - struct { -#ifdef __BIG_ENDIAN__ - unsigned _pad_; - unsigned word; -#endif -#ifdef __LITTLE_ENDIAN__ - unsigned word; - unsigned _pad_; -#endif - } single; - } data; - unsigned long ptr; - + int i; + unsigned int u; + float f; + double d[2]; + unsigned long l[2]; + u8 b[2 * sizeof(double)]; + } u; + + nb = GETSIZE(op->type); if (!address_ok(regs, ea, nb)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - ptr = (unsigned long) &data.ul; - if (sizeof(unsigned long) == 8 || nb == 4) { - err = read_mem_unaligned(&data.ul[0], ea, nb, regs); - if (nb == 4) - ptr = (unsigned long)&(data.single.word); - } else { - /* reading a double on 32-bit */ - err = read_mem_unaligned(&data.ul[0], ea, 4, regs); - if (!err) - err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs); - } + rn = op->reg; + err = copy_mem_in(u.b, ea, nb, regs); if (err) return err; - return (*func)(rn, ptr); + if (unlikely(cross_endian)) { + do_byte_reverse(u.b, min(nb, 8)); + if (nb == 16) + do_byte_reverse(&u.b[8], 8); + } + preempt_disable(); + if (nb == 4) { + if (op->type & FPCONV) + conv_sp_to_dp(&u.f, &u.d[0]); + else if (op->type & SIGNEXT) + u.l[0] = u.i; + else + u.l[0] = u.u; + } + if (regs->msr & MSR_FP) + put_fpr(rn, &u.d[0]); + else + current->thread.TS_FPR(rn) = u.l[0]; + if (nb == 16) { + /* lfdp */ + rn |= 1; + if (regs->msr & MSR_FP) + put_fpr(rn, &u.d[1]); + else + current->thread.TS_FPR(rn) = u.l[1]; + } + preempt_enable(); + return 0; } NOKPROBE_SYMBOL(do_fp_load); -static int do_fp_store(int rn, int (*func)(int, unsigned long), - unsigned long ea, int nb, - struct pt_regs *regs) +static int do_fp_store(struct instruction_op *op, unsigned long ea, + struct pt_regs *regs, bool cross_endian) { - int err; + int rn, nb; union { - double dbl; - unsigned long ul[2]; - struct { -#ifdef __BIG_ENDIAN__ - unsigned _pad_; - unsigned word; -#endif -#ifdef __LITTLE_ENDIAN__ - unsigned word; - unsigned _pad_; -#endif - } single; - } data; - unsigned long ptr; - + unsigned int u; + float f; + double d[2]; + unsigned long l[2]; + u8 b[2 * sizeof(double)]; + } u; + + nb = GETSIZE(op->type); if (!address_ok(regs, ea, nb)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - ptr = (unsigned long) &data.ul[0]; - if (sizeof(unsigned long) == 8 || nb == 4) { - if (nb == 4) - ptr = (unsigned long)&(data.single.word); - err = (*func)(rn, ptr); - if (err) - return err; - err = write_mem_unaligned(data.ul[0], ea, nb, regs); - } else { - /* writing a double on 32-bit */ - err = (*func)(rn, ptr); - if (err) - return err; - err = write_mem_unaligned(data.ul[0], ea, 4, regs); - if (!err) - err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs); + rn = op->reg; + preempt_disable(); + if (regs->msr & MSR_FP) + get_fpr(rn, &u.d[0]); + else + u.l[0] = current->thread.TS_FPR(rn); + if (nb == 4) { + if (op->type & FPCONV) + conv_dp_to_sp(&u.d[0], &u.f); + else + u.u = u.l[0]; } - return err; + if (nb == 16) { + rn |= 1; + if (regs->msr & MSR_FP) + get_fpr(rn, &u.d[1]); + else + u.l[1] = current->thread.TS_FPR(rn); + } + preempt_enable(); + if (unlikely(cross_endian)) { + do_byte_reverse(u.b, min(nb, 8)); + if (nb == 16) + do_byte_reverse(&u.b[8], 8); + } + return copy_mem_out(u.b, ea, nb, regs); } NOKPROBE_SYMBOL(do_fp_store); #endif #ifdef CONFIG_ALTIVEC /* For Altivec/VMX, no need to worry about alignment */ -static nokprobe_inline int do_vec_load(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +static nokprobe_inline int do_vec_load(int rn, unsigned long ea, + int size, struct pt_regs *regs, + bool cross_endian) { + int err; + union { + __vector128 v; + u8 b[sizeof(__vector128)]; + } u = {}; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; - return (*func)(rn, ea); + /* align to multiple of size */ + ea &= ~(size - 1); + err = copy_mem_in(&u.b[ea & 0xf], ea, size, regs); + if (err) + return err; + if (unlikely(cross_endian)) + do_byte_reverse(&u.b[ea & 0xf], size); + preempt_disable(); + if (regs->msr & MSR_VEC) + put_vr(rn, &u.v); + else + current->thread.vr_state.vr[rn] = u.v; + preempt_enable(); + return 0; } -static nokprobe_inline int do_vec_store(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +static nokprobe_inline int do_vec_store(int rn, unsigned long ea, + int size, struct pt_regs *regs, + bool cross_endian) { + union { + __vector128 v; + u8 b[sizeof(__vector128)]; + } u; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; - return (*func)(rn, ea); + /* align to multiple of size */ + ea &= ~(size - 1); + + preempt_disable(); + if (regs->msr & MSR_VEC) + get_vr(rn, &u.v); + else + u.v = current->thread.vr_state.vr[rn]; + preempt_enable(); + if (unlikely(cross_endian)) + do_byte_reverse(&u.b[ea & 0xf], size); + return copy_mem_out(&u.b[ea & 0xf], ea, size, regs); } #endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_VSX -static nokprobe_inline int do_vsx_load(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +#ifdef __powerpc64__ +static nokprobe_inline int emulate_lq(struct pt_regs *regs, unsigned long ea, + int reg, bool cross_endian) { int err; - unsigned long val[2]; if (!address_ok(regs, ea, 16)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - err = read_mem_unaligned(&val[0], ea, 8, regs); - if (!err) - err = read_mem_unaligned(&val[1], ea + 8, 8, regs); - if (!err) - err = (*func)(rn, (unsigned long) &val[0]); + /* if aligned, should be atomic */ + if ((ea & 0xf) == 0) { + err = do_lq(ea, ®s->gpr[reg]); + } else { + err = read_mem(®s->gpr[reg + IS_LE], ea, 8, regs); + if (!err) + err = read_mem(®s->gpr[reg + IS_BE], ea + 8, 8, regs); + } + if (!err && unlikely(cross_endian)) + do_byte_reverse(®s->gpr[reg], 16); return err; } -static nokprobe_inline int do_vsx_store(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea, + int reg, bool cross_endian) { int err; - unsigned long val[2]; + unsigned long vals[2]; if (!address_ok(regs, ea, 16)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - err = (*func)(rn, (unsigned long) &val[0]); - if (err) - return err; - err = write_mem_unaligned(val[0], ea, 8, regs); + vals[0] = regs->gpr[reg]; + vals[1] = regs->gpr[reg + 1]; + if (unlikely(cross_endian)) + do_byte_reverse(vals, 16); + + /* if aligned, should be atomic */ + if ((ea & 0xf) == 0) + return do_stq(ea, vals[0], vals[1]); + + err = write_mem(vals[IS_LE], ea, 8, regs); if (!err) - err = write_mem_unaligned(val[1], ea + 8, 8, regs); + err = write_mem(vals[IS_BE], ea + 8, 8, regs); return err; } +#endif /* __powerpc64 */ + +#ifdef CONFIG_VSX +void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, + const void *mem, bool rev) +{ + int size, read_size; + int i, j; + const unsigned int *wp; + const unsigned short *hp; + const unsigned char *bp; + + size = GETSIZE(op->type); + reg->d[0] = reg->d[1] = 0; + + switch (op->element_size) { + case 16: + /* whole vector; lxv[x] or lxvl[l] */ + if (size == 0) + break; + memcpy(reg, mem, size); + if (IS_LE && (op->vsx_flags & VSX_LDLEFT)) + rev = !rev; + if (rev) + do_byte_reverse(reg, 16); + break; + case 8: + /* scalar loads, lxvd2x, lxvdsx */ + read_size = (size >= 8) ? 8 : size; + i = IS_LE ? 8 : 8 - read_size; + memcpy(®->b[i], mem, read_size); + if (rev) + do_byte_reverse(®->b[i], 8); + if (size < 8) { + if (op->type & SIGNEXT) { + /* size == 4 is the only case here */ + reg->d[IS_LE] = (signed int) reg->d[IS_LE]; + } else if (op->vsx_flags & VSX_FPCONV) { + preempt_disable(); + conv_sp_to_dp(®->fp[1 + IS_LE], + ®->dp[IS_LE]); + preempt_enable(); + } + } else { + if (size == 16) { + unsigned long v = *(unsigned long *)(mem + 8); + reg->d[IS_BE] = !rev ? v : byterev_8(v); + } else if (op->vsx_flags & VSX_SPLAT) + reg->d[IS_BE] = reg->d[IS_LE]; + } + break; + case 4: + /* lxvw4x, lxvwsx */ + wp = mem; + for (j = 0; j < size / 4; ++j) { + i = IS_LE ? 3 - j : j; + reg->w[i] = !rev ? *wp++ : byterev_4(*wp++); + } + if (op->vsx_flags & VSX_SPLAT) { + u32 val = reg->w[IS_LE ? 3 : 0]; + for (; j < 4; ++j) { + i = IS_LE ? 3 - j : j; + reg->w[i] = val; + } + } + break; + case 2: + /* lxvh8x */ + hp = mem; + for (j = 0; j < size / 2; ++j) { + i = IS_LE ? 7 - j : j; + reg->h[i] = !rev ? *hp++ : byterev_2(*hp++); + } + break; + case 1: + /* lxvb16x */ + bp = mem; + for (j = 0; j < size; ++j) { + i = IS_LE ? 15 - j : j; + reg->b[i] = *bp++; + } + break; + } +} +EXPORT_SYMBOL_GPL(emulate_vsx_load); +NOKPROBE_SYMBOL(emulate_vsx_load); + +void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, + void *mem, bool rev) +{ + int size, write_size; + int i, j; + union vsx_reg buf; + unsigned int *wp; + unsigned short *hp; + unsigned char *bp; + + size = GETSIZE(op->type); + + switch (op->element_size) { + case 16: + /* stxv, stxvx, stxvl, stxvll */ + if (size == 0) + break; + if (IS_LE && (op->vsx_flags & VSX_LDLEFT)) + rev = !rev; + if (rev) { + /* reverse 16 bytes */ + buf.d[0] = byterev_8(reg->d[1]); + buf.d[1] = byterev_8(reg->d[0]); + reg = &buf; + } + memcpy(mem, reg, size); + break; + case 8: + /* scalar stores, stxvd2x */ + write_size = (size >= 8) ? 8 : size; + i = IS_LE ? 8 : 8 - write_size; + if (size < 8 && op->vsx_flags & VSX_FPCONV) { + buf.d[0] = buf.d[1] = 0; + preempt_disable(); + conv_dp_to_sp(®->dp[IS_LE], &buf.fp[1 + IS_LE]); + preempt_enable(); + reg = &buf; + } + memcpy(mem, ®->b[i], write_size); + if (size == 16) + memcpy(mem + 8, ®->d[IS_BE], 8); + if (unlikely(rev)) { + do_byte_reverse(mem, write_size); + if (size == 16) + do_byte_reverse(mem + 8, 8); + } + break; + case 4: + /* stxvw4x */ + wp = mem; + for (j = 0; j < size / 4; ++j) { + i = IS_LE ? 3 - j : j; + *wp++ = !rev ? reg->w[i] : byterev_4(reg->w[i]); + } + break; + case 2: + /* stxvh8x */ + hp = mem; + for (j = 0; j < size / 2; ++j) { + i = IS_LE ? 7 - j : j; + *hp++ = !rev ? reg->h[i] : byterev_2(reg->h[i]); + } + break; + case 1: + /* stvxb16x */ + bp = mem; + for (j = 0; j < size; ++j) { + i = IS_LE ? 15 - j : j; + *bp++ = reg->b[i]; + } + break; + } +} +EXPORT_SYMBOL_GPL(emulate_vsx_store); +NOKPROBE_SYMBOL(emulate_vsx_store); + +static nokprobe_inline int do_vsx_load(struct instruction_op *op, + unsigned long ea, struct pt_regs *regs, + bool cross_endian) +{ + int reg = op->reg; + u8 mem[16]; + union vsx_reg buf; + int size = GETSIZE(op->type); + + if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs)) + return -EFAULT; + + emulate_vsx_load(op, &buf, mem, cross_endian); + preempt_disable(); + if (reg < 32) { + /* FP regs + extensions */ + if (regs->msr & MSR_FP) { + load_vsrn(reg, &buf); + } else { + current->thread.fp_state.fpr[reg][0] = buf.d[0]; + current->thread.fp_state.fpr[reg][1] = buf.d[1]; + } + } else { + if (regs->msr & MSR_VEC) + load_vsrn(reg, &buf); + else + current->thread.vr_state.vr[reg - 32] = buf.v; + } + preempt_enable(); + return 0; +} + +static nokprobe_inline int do_vsx_store(struct instruction_op *op, + unsigned long ea, struct pt_regs *regs, + bool cross_endian) +{ + int reg = op->reg; + u8 mem[16]; + union vsx_reg buf; + int size = GETSIZE(op->type); + + if (!address_ok(regs, ea, size)) + return -EFAULT; + + preempt_disable(); + if (reg < 32) { + /* FP regs + extensions */ + if (regs->msr & MSR_FP) { + store_vsrn(reg, &buf); + } else { + buf.d[0] = current->thread.fp_state.fpr[reg][0]; + buf.d[1] = current->thread.fp_state.fpr[reg][1]; + } + } else { + if (regs->msr & MSR_VEC) + store_vsrn(reg, &buf); + else + buf.v = current->thread.vr_state.vr[reg - 32]; + } + preempt_enable(); + emulate_vsx_store(op, &buf, mem, cross_endian); + return copy_mem_out(mem, ea, size, regs); +} #endif /* CONFIG_VSX */ +int emulate_dcbz(unsigned long ea, struct pt_regs *regs) +{ + int err; + unsigned long i, size; + +#ifdef __powerpc64__ + size = ppc64_caches.l1d.block_size; + if (!(regs->msr & MSR_64BIT)) + ea &= 0xffffffffUL; +#else + size = L1_CACHE_BYTES; +#endif + ea &= ~(size - 1); + if (!address_ok(regs, ea, size)) + return -EFAULT; + for (i = 0; i < size; i += sizeof(long)) { + err = __put_user(0, (unsigned long __user *) (ea + i)); + if (err) { + regs->dar = ea; + return err; + } + } + return 0; +} +NOKPROBE_SYMBOL(emulate_dcbz); + #define __put_user_asmx(x, addr, err, op, cr) \ __asm__ __volatile__( \ "1: " op " %2,0,%3\n" \ @@ -526,24 +943,27 @@ static nokprobe_inline int do_vsx_store(int rn, int (*func)(int, unsigned long), : "=r" (err) \ : "r" (addr), "i" (-EFAULT), "0" (err)) -static nokprobe_inline void set_cr0(struct pt_regs *regs, int rd) +static nokprobe_inline void set_cr0(const struct pt_regs *regs, + struct instruction_op *op) { - long val = regs->gpr[rd]; + long val = op->val; - regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); + op->type |= SETCC; + op->ccval = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); #ifdef __powerpc64__ if (!(regs->msr & MSR_64BIT)) val = (int) val; #endif if (val < 0) - regs->ccr |= 0x80000000; + op->ccval |= 0x80000000; else if (val > 0) - regs->ccr |= 0x40000000; + op->ccval |= 0x40000000; else - regs->ccr |= 0x20000000; + op->ccval |= 0x20000000; } -static nokprobe_inline void add_with_carry(struct pt_regs *regs, int rd, +static nokprobe_inline void add_with_carry(const struct pt_regs *regs, + struct instruction_op *op, int rd, unsigned long val1, unsigned long val2, unsigned long carry_in) { @@ -551,24 +971,29 @@ static nokprobe_inline void add_with_carry(struct pt_regs *regs, int rd, if (carry_in) ++val; - regs->gpr[rd] = val; + op->type = COMPUTE + SETREG + SETXER; + op->reg = rd; + op->val = val; #ifdef __powerpc64__ if (!(regs->msr & MSR_64BIT)) { val = (unsigned int) val; val1 = (unsigned int) val1; } #endif + op->xerval = regs->xer; if (val < val1 || (carry_in && val == val1)) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; } -static nokprobe_inline void do_cmp_signed(struct pt_regs *regs, long v1, long v2, - int crfld) +static nokprobe_inline void do_cmp_signed(const struct pt_regs *regs, + struct instruction_op *op, + long v1, long v2, int crfld) { unsigned int crval, shift; + op->type = COMPUTE + SETCC; crval = (regs->xer >> 31) & 1; /* get SO bit */ if (v1 < v2) crval |= 8; @@ -577,14 +1002,17 @@ static nokprobe_inline void do_cmp_signed(struct pt_regs *regs, long v1, long v2 else crval |= 2; shift = (7 - crfld) * 4; - regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); + op->ccval = (regs->ccr & ~(0xf << shift)) | (crval << shift); } -static nokprobe_inline void do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, - unsigned long v2, int crfld) +static nokprobe_inline void do_cmp_unsigned(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, + unsigned long v2, int crfld) { unsigned int crval, shift; + op->type = COMPUTE + SETCC; crval = (regs->xer >> 31) & 1; /* get SO bit */ if (v1 < v2) crval |= 8; @@ -593,7 +1021,90 @@ static nokprobe_inline void do_cmp_unsigned(struct pt_regs *regs, unsigned long else crval |= 2; shift = (7 - crfld) * 4; - regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); + op->ccval = (regs->ccr & ~(0xf << shift)) | (crval << shift); +} + +static nokprobe_inline void do_cmpb(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, unsigned long v2) +{ + unsigned long long out_val, mask; + int i; + + out_val = 0; + for (i = 0; i < 8; i++) { + mask = 0xffUL << (i * 8); + if ((v1 & mask) == (v2 & mask)) + out_val |= mask; + } + op->val = out_val; +} + +/* + * The size parameter is used to adjust the equivalent popcnt instruction. + * popcntb = 8, popcntw = 32, popcntd = 64 + */ +static nokprobe_inline void do_popcnt(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, int size) +{ + unsigned long long out = v1; + + out -= (out >> 1) & 0x5555555555555555; + out = (0x3333333333333333 & out) + (0x3333333333333333 & (out >> 2)); + out = (out + (out >> 4)) & 0x0f0f0f0f0f0f0f0f; + + if (size == 8) { /* popcntb */ + op->val = out; + return; + } + out += out >> 8; + out += out >> 16; + if (size == 32) { /* popcntw */ + op->val = out & 0x0000003f0000003f; + return; + } + + out = (out + (out >> 32)) & 0x7f; + op->val = out; /* popcntd */ +} + +#ifdef CONFIG_PPC64 +static nokprobe_inline void do_bpermd(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, unsigned long v2) +{ + unsigned char perm, idx; + unsigned int i; + + perm = 0; + for (i = 0; i < 8; i++) { + idx = (v1 >> (i * 8)) & 0xff; + if (idx < 64) + if (v2 & PPC_BIT(idx)) + perm |= 1 << i; + } + op->val = perm; +} +#endif /* CONFIG_PPC64 */ +/* + * The size parameter adjusts the equivalent prty instruction. + * prtyw = 32, prtyd = 64 + */ +static nokprobe_inline void do_prty(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v, int size) +{ + unsigned long long res = v ^ (v >> 8); + + res ^= res >> 16; + if (size == 32) { /* prtyw */ + op->val = res & 0x0000000100000001; + return; + } + + res ^= res >> 32; + op->val = res & 1; /*prtyd */ } static nokprobe_inline int trap_compare(long v1, long v2) @@ -629,14 +1140,18 @@ static nokprobe_inline int trap_compare(long v1, long v2) #define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x)) /* - * Decode an instruction, and execute it if that can be done just by - * modifying *regs (i.e. integer arithmetic and logical instructions, - * branches, and barrier instructions). - * Returns 1 if the instruction has been executed, or 0 if not. - * Sets *op to indicate what the instruction does. + * Decode an instruction, and return information about it in *op + * without changing *regs. + * Integer arithmetic and logical instructions, branches, and barrier + * instructions can be emulated just using the information in *op. + * + * Return value is 1 if the instruction can be emulated just by + * updating *regs with the information in *op, -1 if we need the + * GPRs but *regs doesn't contain the full register set, or 0 + * otherwise. */ -int analyse_instr(struct instruction_op *op, struct pt_regs *regs, - unsigned int instr) +int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, + unsigned int instr) { unsigned int opcode, ra, rb, rd, spr, u; unsigned long int imm; @@ -653,12 +1168,11 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, imm = (signed short)(instr & 0xfffc); if ((instr & 2) == 0) imm += regs->nip; - regs->nip += 4; - regs->nip = truncate_if_32bit(regs->msr, regs->nip); + op->val = truncate_if_32bit(regs->msr, imm); if (instr & 1) - regs->link = regs->nip; - if (branch_taken(instr, regs)) - regs->nip = truncate_if_32bit(regs->msr, imm); + op->type |= SETLK; + if (branch_taken(instr, regs, op)) + op->type |= BRTAKEN; return 1; #ifdef CONFIG_PPC64 case 17: /* sc */ @@ -669,38 +1183,37 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, return 0; #endif case 18: /* b */ - op->type = BRANCH; + op->type = BRANCH | BRTAKEN; imm = instr & 0x03fffffc; if (imm & 0x02000000) imm -= 0x04000000; if ((instr & 2) == 0) imm += regs->nip; + op->val = truncate_if_32bit(regs->msr, imm); if (instr & 1) - regs->link = truncate_if_32bit(regs->msr, regs->nip + 4); - imm = truncate_if_32bit(regs->msr, imm); - regs->nip = imm; + op->type |= SETLK; return 1; case 19: switch ((instr >> 1) & 0x3ff) { case 0: /* mcrf */ + op->type = COMPUTE + SETCC; rd = 7 - ((instr >> 23) & 0x7); ra = 7 - ((instr >> 18) & 0x7); rd *= 4; ra *= 4; val = (regs->ccr >> ra) & 0xf; - regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd); - goto instr_done; + op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd); + return 1; case 16: /* bclr */ case 528: /* bcctr */ op->type = BRANCH; imm = (instr & 0x400)? regs->ctr: regs->link; - regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); - imm = truncate_if_32bit(regs->msr, imm); + op->val = truncate_if_32bit(regs->msr, imm); if (instr & 1) - regs->link = regs->nip; - if (branch_taken(instr, regs)) - regs->nip = imm; + op->type |= SETLK; + if (branch_taken(instr, regs, op)) + op->type |= BRTAKEN; return 1; case 18: /* rfid, scary */ @@ -710,9 +1223,8 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, return 0; case 150: /* isync */ - op->type = BARRIER; - isync(); - goto instr_done; + op->type = BARRIER | BARRIER_ISYNC; + return 1; case 33: /* crnor */ case 129: /* crandc */ @@ -722,45 +1234,44 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 289: /* creqv */ case 417: /* crorc */ case 449: /* cror */ + op->type = COMPUTE + SETCC; ra = (instr >> 16) & 0x1f; rb = (instr >> 11) & 0x1f; rd = (instr >> 21) & 0x1f; ra = (regs->ccr >> (31 - ra)) & 1; rb = (regs->ccr >> (31 - rb)) & 1; val = (instr >> (6 + ra * 2 + rb)) & 1; - regs->ccr = (regs->ccr & ~(1UL << (31 - rd))) | + op->ccval = (regs->ccr & ~(1UL << (31 - rd))) | (val << (31 - rd)); - goto instr_done; + return 1; } break; case 31: switch ((instr >> 1) & 0x3ff) { case 598: /* sync */ - op->type = BARRIER; + op->type = BARRIER + BARRIER_SYNC; #ifdef __powerpc64__ switch ((instr >> 21) & 3) { case 1: /* lwsync */ - asm volatile("lwsync" : : : "memory"); - goto instr_done; + op->type = BARRIER + BARRIER_LWSYNC; + break; case 2: /* ptesync */ - asm volatile("ptesync" : : : "memory"); - goto instr_done; + op->type = BARRIER + BARRIER_PTESYNC; + break; } #endif - mb(); - goto instr_done; + return 1; case 854: /* eieio */ - op->type = BARRIER; - eieio(); - goto instr_done; + op->type = BARRIER + BARRIER_EIEIO; + return 1; } break; } /* Following cases refer to regs->gpr[], so we need all regs */ if (!FULL_REGS(regs)) - return 0; + return -1; rd = (instr >> 21) & 0x1f; ra = (instr >> 16) & 0x1f; @@ -771,21 +1282,21 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 2: /* tdi */ if (rd & trap_compare(regs->gpr[ra], (short) instr)) goto trap; - goto instr_done; + return 1; #endif case 3: /* twi */ if (rd & trap_compare((int)regs->gpr[ra], (short) instr)) goto trap; - goto instr_done; + return 1; case 7: /* mulli */ - regs->gpr[rd] = regs->gpr[ra] * (short) instr; - goto instr_done; + op->val = regs->gpr[ra] * (short) instr; + goto compute_done; case 8: /* subfic */ imm = (short) instr; - add_with_carry(regs, rd, ~regs->gpr[ra], imm, 1); - goto instr_done; + add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1); + return 1; case 10: /* cmpli */ imm = (unsigned short) instr; @@ -794,8 +1305,8 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, if ((rd & 1) == 0) val = (unsigned int) val; #endif - do_cmp_unsigned(regs, val, imm, rd >> 2); - goto instr_done; + do_cmp_unsigned(regs, op, val, imm, rd >> 2); + return 1; case 11: /* cmpi */ imm = (short) instr; @@ -804,47 +1315,58 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, if ((rd & 1) == 0) val = (int) val; #endif - do_cmp_signed(regs, val, imm, rd >> 2); - goto instr_done; + do_cmp_signed(regs, op, val, imm, rd >> 2); + return 1; case 12: /* addic */ imm = (short) instr; - add_with_carry(regs, rd, regs->gpr[ra], imm, 0); - goto instr_done; + add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); + return 1; case 13: /* addic. */ imm = (short) instr; - add_with_carry(regs, rd, regs->gpr[ra], imm, 0); - set_cr0(regs, rd); - goto instr_done; + add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); + set_cr0(regs, op); + return 1; case 14: /* addi */ imm = (short) instr; if (ra) imm += regs->gpr[ra]; - regs->gpr[rd] = imm; - goto instr_done; + op->val = imm; + goto compute_done; case 15: /* addis */ imm = ((short) instr) << 16; if (ra) imm += regs->gpr[ra]; - regs->gpr[rd] = imm; - goto instr_done; + op->val = imm; + goto compute_done; + + case 19: + if (((instr >> 1) & 0x1f) == 2) { + /* addpcis */ + imm = (short) (instr & 0xffc1); /* d0 + d2 fields */ + imm |= (instr >> 15) & 0x3e; /* d1 field */ + op->val = regs->nip + (imm << 16) + 4; + goto compute_done; + } + op->type = UNKNOWN; + return 0; case 20: /* rlwimi */ mb = (instr >> 6) & 0x1f; me = (instr >> 1) & 0x1f; val = DATA32(regs->gpr[rd]); imm = MASK32(mb, me); - regs->gpr[ra] = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); + op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); goto logical_done; case 21: /* rlwinm */ mb = (instr >> 6) & 0x1f; me = (instr >> 1) & 0x1f; val = DATA32(regs->gpr[rd]); - regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); + op->val = ROTATE(val, rb) & MASK32(mb, me); goto logical_done; case 23: /* rlwnm */ @@ -852,40 +1374,37 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, me = (instr >> 1) & 0x1f; rb = regs->gpr[rb] & 0x1f; val = DATA32(regs->gpr[rd]); - regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); + op->val = ROTATE(val, rb) & MASK32(mb, me); goto logical_done; case 24: /* ori */ - imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] | imm; - goto instr_done; + op->val = regs->gpr[rd] | (unsigned short) instr; + goto logical_done_nocc; case 25: /* oris */ imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] | (imm << 16); - goto instr_done; + op->val = regs->gpr[rd] | (imm << 16); + goto logical_done_nocc; case 26: /* xori */ - imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] ^ imm; - goto instr_done; + op->val = regs->gpr[rd] ^ (unsigned short) instr; + goto logical_done_nocc; case 27: /* xoris */ imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] ^ (imm << 16); - goto instr_done; + op->val = regs->gpr[rd] ^ (imm << 16); + goto logical_done_nocc; case 28: /* andi. */ - imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] & imm; - set_cr0(regs, ra); - goto instr_done; + op->val = regs->gpr[rd] & (unsigned short) instr; + set_cr0(regs, op); + goto logical_done_nocc; case 29: /* andis. */ imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] & (imm << 16); - set_cr0(regs, ra); - goto instr_done; + op->val = regs->gpr[rd] & (imm << 16); + set_cr0(regs, op); + goto logical_done_nocc; #ifdef __powerpc64__ case 30: /* rld* */ @@ -896,48 +1415,60 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, val = ROTATE(val, sh); switch ((instr >> 2) & 3) { case 0: /* rldicl */ - regs->gpr[ra] = val & MASK64_L(mb); - goto logical_done; + val &= MASK64_L(mb); + break; case 1: /* rldicr */ - regs->gpr[ra] = val & MASK64_R(mb); - goto logical_done; + val &= MASK64_R(mb); + break; case 2: /* rldic */ - regs->gpr[ra] = val & MASK64(mb, 63 - sh); - goto logical_done; + val &= MASK64(mb, 63 - sh); + break; case 3: /* rldimi */ imm = MASK64(mb, 63 - sh); - regs->gpr[ra] = (regs->gpr[ra] & ~imm) | + val = (regs->gpr[ra] & ~imm) | (val & imm); - goto logical_done; } + op->val = val; + goto logical_done; } else { sh = regs->gpr[rb] & 0x3f; val = ROTATE(val, sh); switch ((instr >> 1) & 7) { case 0: /* rldcl */ - regs->gpr[ra] = val & MASK64_L(mb); + op->val = val & MASK64_L(mb); goto logical_done; case 1: /* rldcr */ - regs->gpr[ra] = val & MASK64_R(mb); + op->val = val & MASK64_R(mb); goto logical_done; } } #endif - break; /* illegal instruction */ + op->type = UNKNOWN; /* illegal instruction */ + return 0; case 31: + /* isel occupies 32 minor opcodes */ + if (((instr >> 1) & 0x1f) == 15) { + mb = (instr >> 6) & 0x1f; /* bc field */ + val = (regs->ccr >> (31 - mb)) & 1; + val2 = (ra) ? regs->gpr[ra] : 0; + + op->val = (val) ? val2 : regs->gpr[rb]; + goto compute_done; + } + switch ((instr >> 1) & 0x3ff) { case 4: /* tw */ if (rd == 0x1f || (rd & trap_compare((int)regs->gpr[ra], (int)regs->gpr[rb]))) goto trap; - goto instr_done; + return 1; #ifdef __powerpc64__ case 68: /* td */ if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb])) goto trap; - goto instr_done; + return 1; #endif case 83: /* mfmsr */ if (regs->msr & MSR_PR) @@ -966,74 +1497,50 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, #endif case 19: /* mfcr */ + imm = 0xffffffffUL; if ((instr >> 20) & 1) { imm = 0xf0000000UL; for (sh = 0; sh < 8; ++sh) { - if (instr & (0x80000 >> sh)) { - regs->gpr[rd] = regs->ccr & imm; + if (instr & (0x80000 >> sh)) break; - } imm >>= 4; } - - goto instr_done; } - - regs->gpr[rd] = regs->ccr; - regs->gpr[rd] &= 0xffffffffUL; - goto instr_done; + op->val = regs->ccr & imm; + goto compute_done; case 144: /* mtcrf */ + op->type = COMPUTE + SETCC; imm = 0xf0000000UL; val = regs->gpr[rd]; + op->ccval = regs->ccr; for (sh = 0; sh < 8; ++sh) { if (instr & (0x80000 >> sh)) - regs->ccr = (regs->ccr & ~imm) | + op->ccval = (op->ccval & ~imm) | (val & imm); imm >>= 4; } - goto instr_done; + return 1; case 339: /* mfspr */ spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); - switch (spr) { - case SPRN_XER: /* mfxer */ - regs->gpr[rd] = regs->xer; - regs->gpr[rd] &= 0xffffffffUL; - goto instr_done; - case SPRN_LR: /* mflr */ - regs->gpr[rd] = regs->link; - goto instr_done; - case SPRN_CTR: /* mfctr */ - regs->gpr[rd] = regs->ctr; - goto instr_done; - default: - op->type = MFSPR; - op->reg = rd; - op->spr = spr; - return 0; - } - break; + op->type = MFSPR; + op->reg = rd; + op->spr = spr; + if (spr == SPRN_XER || spr == SPRN_LR || + spr == SPRN_CTR) + return 1; + return 0; case 467: /* mtspr */ spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); - switch (spr) { - case SPRN_XER: /* mtxer */ - regs->xer = (regs->gpr[rd] & 0xffffffffUL); - goto instr_done; - case SPRN_LR: /* mtlr */ - regs->link = regs->gpr[rd]; - goto instr_done; - case SPRN_CTR: /* mtctr */ - regs->ctr = regs->gpr[rd]; - goto instr_done; - default: - op->type = MTSPR; - op->val = regs->gpr[rd]; - op->spr = spr; - return 0; - } - break; + op->type = MTSPR; + op->val = regs->gpr[rd]; + op->spr = spr; + if (spr == SPRN_XER || spr == SPRN_LR || + spr == SPRN_CTR) + return 1; + return 0; /* * Compare instructions @@ -1048,8 +1555,8 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, val2 = (int) val2; } #endif - do_cmp_signed(regs, val, val2, rd >> 2); - goto instr_done; + do_cmp_signed(regs, op, val, val2, rd >> 2); + return 1; case 32: /* cmpl */ val = regs->gpr[ra]; @@ -1061,109 +1568,114 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, val2 = (unsigned int) val2; } #endif - do_cmp_unsigned(regs, val, val2, rd >> 2); - goto instr_done; + do_cmp_unsigned(regs, op, val, val2, rd >> 2); + return 1; + + case 508: /* cmpb */ + do_cmpb(regs, op, regs->gpr[rd], regs->gpr[rb]); + goto logical_done_nocc; /* * Arithmetic instructions */ case 8: /* subfc */ - add_with_carry(regs, rd, ~regs->gpr[ra], + add_with_carry(regs, op, rd, ~regs->gpr[ra], regs->gpr[rb], 1); goto arith_done; #ifdef __powerpc64__ case 9: /* mulhdu */ - asm("mulhdu %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhdu %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; #endif case 10: /* addc */ - add_with_carry(regs, rd, regs->gpr[ra], + add_with_carry(regs, op, rd, regs->gpr[ra], regs->gpr[rb], 0); goto arith_done; case 11: /* mulhwu */ - asm("mulhwu %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhwu %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; case 40: /* subf */ - regs->gpr[rd] = regs->gpr[rb] - regs->gpr[ra]; + op->val = regs->gpr[rb] - regs->gpr[ra]; goto arith_done; #ifdef __powerpc64__ case 73: /* mulhd */ - asm("mulhd %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhd %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; #endif case 75: /* mulhw */ - asm("mulhw %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhw %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; case 104: /* neg */ - regs->gpr[rd] = -regs->gpr[ra]; + op->val = -regs->gpr[ra]; goto arith_done; case 136: /* subfe */ - add_with_carry(regs, rd, ~regs->gpr[ra], regs->gpr[rb], - regs->xer & XER_CA); + add_with_carry(regs, op, rd, ~regs->gpr[ra], + regs->gpr[rb], regs->xer & XER_CA); goto arith_done; case 138: /* adde */ - add_with_carry(regs, rd, regs->gpr[ra], regs->gpr[rb], - regs->xer & XER_CA); + add_with_carry(regs, op, rd, regs->gpr[ra], + regs->gpr[rb], regs->xer & XER_CA); goto arith_done; case 200: /* subfze */ - add_with_carry(regs, rd, ~regs->gpr[ra], 0L, + add_with_carry(regs, op, rd, ~regs->gpr[ra], 0L, regs->xer & XER_CA); goto arith_done; case 202: /* addze */ - add_with_carry(regs, rd, regs->gpr[ra], 0L, + add_with_carry(regs, op, rd, regs->gpr[ra], 0L, regs->xer & XER_CA); goto arith_done; case 232: /* subfme */ - add_with_carry(regs, rd, ~regs->gpr[ra], -1L, + add_with_carry(regs, op, rd, ~regs->gpr[ra], -1L, regs->xer & XER_CA); goto arith_done; #ifdef __powerpc64__ case 233: /* mulld */ - regs->gpr[rd] = regs->gpr[ra] * regs->gpr[rb]; + op->val = regs->gpr[ra] * regs->gpr[rb]; goto arith_done; #endif case 234: /* addme */ - add_with_carry(regs, rd, regs->gpr[ra], -1L, + add_with_carry(regs, op, rd, regs->gpr[ra], -1L, regs->xer & XER_CA); goto arith_done; case 235: /* mullw */ - regs->gpr[rd] = (unsigned int) regs->gpr[ra] * - (unsigned int) regs->gpr[rb]; + op->val = (long)(int) regs->gpr[ra] * + (int) regs->gpr[rb]; + goto arith_done; case 266: /* add */ - regs->gpr[rd] = regs->gpr[ra] + regs->gpr[rb]; + op->val = regs->gpr[ra] + regs->gpr[rb]; goto arith_done; #ifdef __powerpc64__ case 457: /* divdu */ - regs->gpr[rd] = regs->gpr[ra] / regs->gpr[rb]; + op->val = regs->gpr[ra] / regs->gpr[rb]; goto arith_done; #endif case 459: /* divwu */ - regs->gpr[rd] = (unsigned int) regs->gpr[ra] / + op->val = (unsigned int) regs->gpr[ra] / (unsigned int) regs->gpr[rb]; goto arith_done; #ifdef __powerpc64__ case 489: /* divd */ - regs->gpr[rd] = (long int) regs->gpr[ra] / + op->val = (long int) regs->gpr[ra] / (long int) regs->gpr[rb]; goto arith_done; #endif case 491: /* divw */ - regs->gpr[rd] = (int) regs->gpr[ra] / + op->val = (int) regs->gpr[ra] / (int) regs->gpr[rb]; goto arith_done; @@ -1172,57 +1684,79 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, * Logical instructions */ case 26: /* cntlzw */ - asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) : - "r" (regs->gpr[rd])); + op->val = __builtin_clz((unsigned int) regs->gpr[rd]); goto logical_done; #ifdef __powerpc64__ case 58: /* cntlzd */ - asm("cntlzd %0,%1" : "=r" (regs->gpr[ra]) : - "r" (regs->gpr[rd])); + op->val = __builtin_clzl(regs->gpr[rd]); goto logical_done; #endif case 28: /* and */ - regs->gpr[ra] = regs->gpr[rd] & regs->gpr[rb]; + op->val = regs->gpr[rd] & regs->gpr[rb]; goto logical_done; case 60: /* andc */ - regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb]; + op->val = regs->gpr[rd] & ~regs->gpr[rb]; goto logical_done; + case 122: /* popcntb */ + do_popcnt(regs, op, regs->gpr[rd], 8); + goto logical_done_nocc; + case 124: /* nor */ - regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]); + op->val = ~(regs->gpr[rd] | regs->gpr[rb]); goto logical_done; + case 154: /* prtyw */ + do_prty(regs, op, regs->gpr[rd], 32); + goto logical_done_nocc; + + case 186: /* prtyd */ + do_prty(regs, op, regs->gpr[rd], 64); + goto logical_done_nocc; +#ifdef CONFIG_PPC64 + case 252: /* bpermd */ + do_bpermd(regs, op, regs->gpr[rd], regs->gpr[rb]); + goto logical_done_nocc; +#endif case 284: /* xor */ - regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]); + op->val = ~(regs->gpr[rd] ^ regs->gpr[rb]); goto logical_done; case 316: /* xor */ - regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb]; + op->val = regs->gpr[rd] ^ regs->gpr[rb]; goto logical_done; + case 378: /* popcntw */ + do_popcnt(regs, op, regs->gpr[rd], 32); + goto logical_done_nocc; + case 412: /* orc */ - regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb]; + op->val = regs->gpr[rd] | ~regs->gpr[rb]; goto logical_done; case 444: /* or */ - regs->gpr[ra] = regs->gpr[rd] | regs->gpr[rb]; + op->val = regs->gpr[rd] | regs->gpr[rb]; goto logical_done; case 476: /* nand */ - regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]); + op->val = ~(regs->gpr[rd] & regs->gpr[rb]); goto logical_done; - +#ifdef CONFIG_PPC64 + case 506: /* popcntd */ + do_popcnt(regs, op, regs->gpr[rd], 64); + goto logical_done_nocc; +#endif case 922: /* extsh */ - regs->gpr[ra] = (signed short) regs->gpr[rd]; + op->val = (signed short) regs->gpr[rd]; goto logical_done; case 954: /* extsb */ - regs->gpr[ra] = (signed char) regs->gpr[rd]; + op->val = (signed char) regs->gpr[rd]; goto logical_done; #ifdef __powerpc64__ case 986: /* extsw */ - regs->gpr[ra] = (signed int) regs->gpr[rd]; + op->val = (signed int) regs->gpr[rd]; goto logical_done; #endif @@ -1232,75 +1766,83 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 24: /* slw */ sh = regs->gpr[rb] & 0x3f; if (sh < 32) - regs->gpr[ra] = (regs->gpr[rd] << sh) & 0xffffffffUL; + op->val = (regs->gpr[rd] << sh) & 0xffffffffUL; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 536: /* srw */ sh = regs->gpr[rb] & 0x3f; if (sh < 32) - regs->gpr[ra] = (regs->gpr[rd] & 0xffffffffUL) >> sh; + op->val = (regs->gpr[rd] & 0xffffffffUL) >> sh; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 792: /* sraw */ + op->type = COMPUTE + SETREG + SETXER; sh = regs->gpr[rb] & 0x3f; ival = (signed int) regs->gpr[rd]; - regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); + op->val = ival >> (sh < 32 ? sh : 31); + op->xerval = regs->xer; if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0)) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; case 824: /* srawi */ + op->type = COMPUTE + SETREG + SETXER; sh = rb; ival = (signed int) regs->gpr[rd]; - regs->gpr[ra] = ival >> sh; + op->val = ival >> sh; + op->xerval = regs->xer; if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; #ifdef __powerpc64__ case 27: /* sld */ sh = regs->gpr[rb] & 0x7f; if (sh < 64) - regs->gpr[ra] = regs->gpr[rd] << sh; + op->val = regs->gpr[rd] << sh; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 539: /* srd */ sh = regs->gpr[rb] & 0x7f; if (sh < 64) - regs->gpr[ra] = regs->gpr[rd] >> sh; + op->val = regs->gpr[rd] >> sh; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 794: /* srad */ + op->type = COMPUTE + SETREG + SETXER; sh = regs->gpr[rb] & 0x7f; ival = (signed long int) regs->gpr[rd]; - regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); + op->val = ival >> (sh < 64 ? sh : 63); + op->xerval = regs->xer; if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0)) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; case 826: /* sradi with sh_5 = 0 */ case 827: /* sradi with sh_5 = 1 */ + op->type = COMPUTE + SETREG + SETXER; sh = rb | ((instr & 2) << 4); ival = (signed long int) regs->gpr[rd]; - regs->gpr[ra] = ival >> sh; + op->val = ival >> sh; + op->xerval = regs->xer; if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; #endif /* __powerpc64__ */ @@ -1333,18 +1875,24 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->type = MKOP(CACHEOP, ICBI, 0); op->ea = xform_ea(instr, regs); return 0; + + case 1014: /* dcbz */ + op->type = MKOP(CACHEOP, DCBZ, 0); + op->ea = xform_ea(instr, regs); + return 0; } break; } - /* - * Loads and stores. - */ +/* + * Loads and stores. + */ op->type = UNKNOWN; op->update_reg = ra; op->reg = rd; op->val = regs->gpr[rd]; u = (instr >> 20) & UPDATE; + op->vsx_flags = 0; switch (opcode) { case 31: @@ -1368,9 +1916,30 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->type = MKOP(STCX, 0, 8); break; - case 21: /* ldx */ - case 53: /* ldux */ - op->type = MKOP(LOAD, u, 8); + case 52: /* lbarx */ + op->type = MKOP(LARX, 0, 1); + break; + + case 694: /* stbcx. */ + op->type = MKOP(STCX, 0, 1); + break; + + case 116: /* lharx */ + op->type = MKOP(LARX, 0, 2); + break; + + case 726: /* sthcx. */ + op->type = MKOP(STCX, 0, 2); + break; + + case 276: /* lqarx */ + if (!((rd & 1) || rd == ra || rd == rb)) + op->type = MKOP(LARX, 0, 16); + break; + + case 182: /* stqcx. */ + if (!(rd & 1)) + op->type = MKOP(STCX, 0, 16); break; #endif @@ -1385,22 +1954,58 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; #ifdef CONFIG_ALTIVEC + /* + * Note: for the load/store vector element instructions, + * bits of the EA say which field of the VMX register to use. + */ + case 7: /* lvebx */ + op->type = MKOP(LOAD_VMX, 0, 1); + op->element_size = 1; + break; + + case 39: /* lvehx */ + op->type = MKOP(LOAD_VMX, 0, 2); + op->element_size = 2; + break; + + case 71: /* lvewx */ + op->type = MKOP(LOAD_VMX, 0, 4); + op->element_size = 4; + break; + case 103: /* lvx */ case 359: /* lvxl */ - if (!(regs->msr & MSR_VEC)) - goto vecunavail; op->type = MKOP(LOAD_VMX, 0, 16); + op->element_size = 16; + break; + + case 135: /* stvebx */ + op->type = MKOP(STORE_VMX, 0, 1); + op->element_size = 1; + break; + + case 167: /* stvehx */ + op->type = MKOP(STORE_VMX, 0, 2); + op->element_size = 2; + break; + + case 199: /* stvewx */ + op->type = MKOP(STORE_VMX, 0, 4); + op->element_size = 4; break; case 231: /* stvx */ case 487: /* stvxl */ - if (!(regs->msr & MSR_VEC)) - goto vecunavail; op->type = MKOP(STORE_VMX, 0, 16); break; #endif /* CONFIG_ALTIVEC */ #ifdef __powerpc64__ + case 21: /* ldx */ + case 53: /* ldux */ + op->type = MKOP(LOAD, u, 8); + break; + case 149: /* stdx */ case 181: /* stdux */ op->type = MKOP(STORE, u, 8); @@ -1457,41 +2062,52 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, if (rb == 0) rb = 32; /* # bytes to load */ op->type = MKOP(LOAD_MULTI, 0, rb); - op->ea = 0; - if (ra) - op->ea = truncate_if_32bit(regs->msr, - regs->gpr[ra]); + op->ea = ra ? regs->gpr[ra] : 0; break; #ifdef CONFIG_PPC_FPU case 535: /* lfsx */ case 567: /* lfsux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(LOAD_FP, u, 4); + op->type = MKOP(LOAD_FP, u | FPCONV, 4); break; case 599: /* lfdx */ case 631: /* lfdux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(LOAD_FP, u, 8); break; case 663: /* stfsx */ case 695: /* stfsux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(STORE_FP, u, 4); + op->type = MKOP(STORE_FP, u | FPCONV, 4); break; case 727: /* stfdx */ case 759: /* stfdux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(STORE_FP, u, 8); break; -#endif + +#ifdef __powerpc64__ + case 791: /* lfdpx */ + op->type = MKOP(LOAD_FP, 0, 16); + break; + + case 855: /* lfiwax */ + op->type = MKOP(LOAD_FP, SIGNEXT, 4); + break; + + case 887: /* lfiwzx */ + op->type = MKOP(LOAD_FP, 0, 4); + break; + + case 919: /* stfdpx */ + op->type = MKOP(STORE_FP, 0, 16); + break; + + case 983: /* stfiwx */ + op->type = MKOP(STORE_FP, 0, 4); + break; +#endif /* __powerpc64 */ +#endif /* CONFIG_PPC_FPU */ #ifdef __powerpc64__ case 660: /* stdbrx */ @@ -1509,14 +2125,11 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->val = byterev_4(regs->gpr[rd]); break; - case 725: + case 725: /* stswi */ if (rb == 0) rb = 32; /* # bytes to store */ op->type = MKOP(STORE_MULTI, 0, rb); - op->ea = 0; - if (ra) - op->ea = truncate_if_32bit(regs->msr, - regs->gpr[ra]); + op->ea = ra ? regs->gpr[ra] : 0; break; case 790: /* lhbrx */ @@ -1529,20 +2142,184 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; #ifdef CONFIG_VSX + case 12: /* lxsiwzx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 8; + break; + + case 76: /* lxsiwax */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, SIGNEXT, 4); + op->element_size = 8; + break; + + case 140: /* stxsiwx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 4); + op->element_size = 8; + break; + + case 268: /* lxvx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 269: /* lxvl */ + case 301: { /* lxvll */ + int nb; + op->reg = rd | ((instr & 1) << 5); + op->ea = ra ? regs->gpr[ra] : 0; + nb = regs->gpr[rb] & 0xff; + if (nb > 16) + nb = 16; + op->type = MKOP(LOAD_VSX, 0, nb); + op->element_size = 16; + op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | + VSX_CHECK_VEC; + break; + } + case 332: /* lxvdsx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 8); + op->element_size = 8; + op->vsx_flags = VSX_SPLAT; + break; + + case 364: /* lxvwsx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 4; + op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC; + break; + + case 396: /* stxvx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 397: /* stxvl */ + case 429: { /* stxvll */ + int nb; + op->reg = rd | ((instr & 1) << 5); + op->ea = ra ? regs->gpr[ra] : 0; + nb = regs->gpr[rb] & 0xff; + if (nb > 16) + nb = 16; + op->type = MKOP(STORE_VSX, 0, nb); + op->element_size = 16; + op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | + VSX_CHECK_VEC; + break; + } + case 524: /* lxsspx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV; + break; + + case 588: /* lxsdx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 8); + op->element_size = 8; + break; + + case 652: /* stxsspx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV; + break; + + case 716: /* stxsdx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 8); + op->element_size = 8; + break; + + case 780: /* lxvw4x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 4; + break; + + case 781: /* lxsibzx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 1); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 812: /* lxvh8x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 2; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 813: /* lxsihzx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 2); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 844: /* lxvd2x */ - case 876: /* lxvd2ux */ - if (!(regs->msr & MSR_VSX)) - goto vsxunavail; op->reg = rd | ((instr & 1) << 5); - op->type = MKOP(LOAD_VSX, u, 16); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 8; + break; + + case 876: /* lxvb16x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 1; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 908: /* stxvw4x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 4; + break; + + case 909: /* stxsibx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 1); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 940: /* stxvh8x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 2; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 941: /* stxsihx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 2); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; break; case 972: /* stxvd2x */ - case 1004: /* stxvd2ux */ - if (!(regs->msr & MSR_VSX)) - goto vsxunavail; op->reg = rd | ((instr & 1) << 5); - op->type = MKOP(STORE_VSX, u, 16); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 8; + break; + + case 1004: /* stxvb16x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 1; + op->vsx_flags = VSX_CHECK_VEC; break; #endif /* CONFIG_VSX */ @@ -1606,37 +2383,62 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, #ifdef CONFIG_PPC_FPU case 48: /* lfs */ case 49: /* lfsu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(LOAD_FP, u, 4); + op->type = MKOP(LOAD_FP, u | FPCONV, 4); op->ea = dform_ea(instr, regs); break; case 50: /* lfd */ case 51: /* lfdu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(LOAD_FP, u, 8); op->ea = dform_ea(instr, regs); break; case 52: /* stfs */ case 53: /* stfsu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(STORE_FP, u, 4); + op->type = MKOP(STORE_FP, u | FPCONV, 4); op->ea = dform_ea(instr, regs); break; case 54: /* stfd */ case 55: /* stfdu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(STORE_FP, u, 8); op->ea = dform_ea(instr, regs); break; #endif +#ifdef __powerpc64__ + case 56: /* lq */ + if (!((rd & 1) || (rd == ra))) + op->type = MKOP(LOAD, 0, 16); + op->ea = dqform_ea(instr, regs); + break; +#endif + +#ifdef CONFIG_VSX + case 57: /* lfdp, lxsd, lxssp */ + op->ea = dsform_ea(instr, regs); + switch (instr & 3) { + case 0: /* lfdp */ + if (rd & 1) + break; /* reg must be even */ + op->type = MKOP(LOAD_FP, 0, 16); + break; + case 2: /* lxsd */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, 0, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 3: /* lxssp */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + } + break; +#endif /* CONFIG_VSX */ + #ifdef __powerpc64__ case 58: /* ld[u], lwa */ op->ea = dsform_ea(instr, regs); @@ -1652,7 +2454,57 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; } break; +#endif + +#ifdef CONFIG_VSX + case 61: /* stfdp, lxv, stxsd, stxssp, stxv */ + switch (instr & 7) { + case 0: /* stfdp with LSB of DS field = 0 */ + case 4: /* stfdp with LSB of DS field = 1 */ + op->ea = dsform_ea(instr, regs); + op->type = MKOP(STORE_FP, 0, 16); + break; + + case 1: /* lxv */ + op->ea = dqform_ea(instr, regs); + if (instr & 8) + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 2: /* stxsd with LSB of DS field = 0 */ + case 6: /* stxsd with LSB of DS field = 1 */ + op->ea = dsform_ea(instr, regs); + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, 0, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 3: /* stxssp with LSB of DS field = 0 */ + case 7: /* stxssp with LSB of DS field = 1 */ + op->ea = dsform_ea(instr, regs); + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + + case 5: /* stxv */ + op->ea = dqform_ea(instr, regs); + if (instr & 8) + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + } + break; +#endif /* CONFIG_VSX */ +#ifdef __powerpc64__ case 62: /* std[u] */ op->ea = dsform_ea(instr, regs); switch (instr & 3) { @@ -1662,6 +2514,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 1: /* stdu */ op->type = MKOP(STORE, UPDATE, 8); break; + case 2: /* stq */ + if (!(rd & 1)) + op->type = MKOP(STORE, 0, 16); + break; } break; #endif /* __powerpc64__ */ @@ -1671,15 +2527,18 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, logical_done: if (instr & 1) - set_cr0(regs, ra); - goto instr_done; + set_cr0(regs, op); + logical_done_nocc: + op->reg = ra; + op->type |= SETREG; + return 1; arith_done: if (instr & 1) - set_cr0(regs, rd); - - instr_done: - regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); + set_cr0(regs, op); + compute_done: + op->reg = rd; + op->type |= SETREG; return 1; priv: @@ -1691,24 +2550,6 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->type = INTERRUPT | 0x700; op->val = SRR1_PROGTRAP; return 0; - -#ifdef CONFIG_PPC_FPU - fpunavail: - op->type = INTERRUPT | 0x800; - return 0; -#endif - -#ifdef CONFIG_ALTIVEC - vecunavail: - op->type = INTERRUPT | 0xf20; - return 0; -#endif - -#ifdef CONFIG_VSX - vsxunavail: - op->type = INTERRUPT | 0xf40; - return 0; -#endif } EXPORT_SYMBOL_GPL(analyse_instr); NOKPROBE_SYMBOL(analyse_instr); @@ -1771,190 +2612,412 @@ static nokprobe_inline void do_byterev(unsigned long *valp, int size) } /* - * Emulate instructions that cause a transfer of control, - * loads and stores, and a few other instructions. - * Returns 1 if the step was emulated, 0 if not, - * or -1 if the instruction is one that should not be stepped, - * such as an rfid, or a mtmsrd that would clear MSR_RI. + * Emulate an instruction that can be executed just by updating + * fields in *regs. */ -int emulate_step(struct pt_regs *regs, unsigned int instr) +void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op) { - struct instruction_op op; - int r, err, size; - unsigned long val; - unsigned int cr; - int i, rd, nb; + unsigned long next_pc; + + next_pc = truncate_if_32bit(regs->msr, regs->nip + 4); + switch (op->type & INSTR_TYPE_MASK) { + case COMPUTE: + if (op->type & SETREG) + regs->gpr[op->reg] = op->val; + if (op->type & SETCC) + regs->ccr = op->ccval; + if (op->type & SETXER) + regs->xer = op->xerval; + break; - r = analyse_instr(&op, regs, instr); - if (r != 0) - return r; + case BRANCH: + if (op->type & SETLK) + regs->link = next_pc; + if (op->type & BRTAKEN) + next_pc = op->val; + if (op->type & DECCTR) + --regs->ctr; + break; - err = 0; - size = GETSIZE(op.type); - switch (op.type & INSTR_TYPE_MASK) { - case CACHEOP: - if (!address_ok(regs, op.ea, 8)) - return 0; - switch (op.type & CACHEOP_MASK) { - case DCBST: - __cacheop_user_asmx(op.ea, err, "dcbst"); + case BARRIER: + switch (op->type & BARRIER_MASK) { + case BARRIER_SYNC: + mb(); break; - case DCBF: - __cacheop_user_asmx(op.ea, err, "dcbf"); + case BARRIER_ISYNC: + isync(); break; - case DCBTST: - if (op.reg == 0) - prefetchw((void *) op.ea); + case BARRIER_EIEIO: + eieio(); break; - case DCBT: - if (op.reg == 0) - prefetch((void *) op.ea); + case BARRIER_LWSYNC: + asm volatile("lwsync" : : : "memory"); break; - case ICBI: - __cacheop_user_asmx(op.ea, err, "icbi"); + case BARRIER_PTESYNC: + asm volatile("ptesync" : : : "memory"); break; } - if (err) - return 0; - goto instr_done; + break; + + case MFSPR: + switch (op->spr) { + case SPRN_XER: + regs->gpr[op->reg] = regs->xer & 0xffffffffUL; + break; + case SPRN_LR: + regs->gpr[op->reg] = regs->link; + break; + case SPRN_CTR: + regs->gpr[op->reg] = regs->ctr; + break; + default: + WARN_ON_ONCE(1); + } + break; + case MTSPR: + switch (op->spr) { + case SPRN_XER: + regs->xer = op->val & 0xffffffffUL; + break; + case SPRN_LR: + regs->link = op->val; + break; + case SPRN_CTR: + regs->ctr = op->val; + break; + default: + WARN_ON_ONCE(1); + } + break; + + default: + WARN_ON_ONCE(1); + } + regs->nip = next_pc; +} + +/* + * Emulate a previously-analysed load or store instruction. + * Return values are: + * 0 = instruction emulated successfully + * -EFAULT = address out of range or access faulted (regs->dar + * contains the faulting address) + * -EACCES = misaligned access, instruction requires alignment + * -EINVAL = unknown operation in *op + */ +int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) +{ + int err, size, type; + int i, rd, nb; + unsigned int cr; + unsigned long val; + unsigned long ea; + bool cross_endian; + + err = 0; + size = GETSIZE(op->type); + type = op->type & INSTR_TYPE_MASK; + cross_endian = (regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE); + ea = truncate_if_32bit(regs->msr, op->ea); + + switch (type) { case LARX: - if (op.ea & (size - 1)) - break; /* can't handle misaligned */ - if (!address_ok(regs, op.ea, size)) - return 0; + if (ea & (size - 1)) + return -EACCES; /* can't handle misaligned */ + if (!address_ok(regs, ea, size)) + return -EFAULT; err = 0; + val = 0; switch (size) { +#ifdef __powerpc64__ + case 1: + __get_user_asmx(val, ea, err, "lbarx"); + break; + case 2: + __get_user_asmx(val, ea, err, "lharx"); + break; +#endif case 4: - __get_user_asmx(val, op.ea, err, "lwarx"); + __get_user_asmx(val, ea, err, "lwarx"); break; #ifdef __powerpc64__ case 8: - __get_user_asmx(val, op.ea, err, "ldarx"); + __get_user_asmx(val, ea, err, "ldarx"); + break; + case 16: + err = do_lqarx(ea, ®s->gpr[op->reg]); break; #endif default: - return 0; + return -EINVAL; } - if (!err) - regs->gpr[op.reg] = val; - goto ldst_done; + if (err) { + regs->dar = ea; + break; + } + if (size < 16) + regs->gpr[op->reg] = val; + break; case STCX: - if (op.ea & (size - 1)) - break; /* can't handle misaligned */ - if (!address_ok(regs, op.ea, size)) - return 0; + if (ea & (size - 1)) + return -EACCES; /* can't handle misaligned */ + if (!address_ok(regs, ea, size)) + return -EFAULT; err = 0; switch (size) { +#ifdef __powerpc64__ + case 1: + __put_user_asmx(op->val, ea, err, "stbcx.", cr); + break; + case 2: + __put_user_asmx(op->val, ea, err, "stbcx.", cr); + break; +#endif case 4: - __put_user_asmx(op.val, op.ea, err, "stwcx.", cr); + __put_user_asmx(op->val, ea, err, "stwcx.", cr); break; #ifdef __powerpc64__ case 8: - __put_user_asmx(op.val, op.ea, err, "stdcx.", cr); + __put_user_asmx(op->val, ea, err, "stdcx.", cr); + break; + case 16: + err = do_stqcx(ea, regs->gpr[op->reg], + regs->gpr[op->reg + 1], &cr); break; #endif default: - return 0; + return -EINVAL; } if (!err) regs->ccr = (regs->ccr & 0x0fffffff) | (cr & 0xe0000000) | ((regs->xer >> 3) & 0x10000000); - goto ldst_done; + else + regs->dar = ea; + break; case LOAD: - err = read_mem(®s->gpr[op.reg], op.ea, size, regs); +#ifdef __powerpc64__ + if (size == 16) { + err = emulate_lq(regs, ea, op->reg, cross_endian); + break; + } +#endif + err = read_mem(®s->gpr[op->reg], ea, size, regs); if (!err) { - if (op.type & SIGNEXT) - do_signext(®s->gpr[op.reg], size); - if (op.type & BYTEREV) - do_byterev(®s->gpr[op.reg], size); + if (op->type & SIGNEXT) + do_signext(®s->gpr[op->reg], size); + if ((op->type & BYTEREV) == (cross_endian ? 0 : BYTEREV)) + do_byterev(®s->gpr[op->reg], size); } - goto ldst_done; + break; #ifdef CONFIG_PPC_FPU case LOAD_FP: - if (size == 4) - err = do_fp_load(op.reg, do_lfs, op.ea, size, regs); - else - err = do_fp_load(op.reg, do_lfd, op.ea, size, regs); - goto ldst_done; + /* + * If the instruction is in userspace, we can emulate it even + * if the VMX state is not live, because we have the state + * stored in the thread_struct. If the instruction is in + * the kernel, we must not touch the state in the thread_struct. + */ + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP)) + return 0; + err = do_fp_load(op, ea, regs, cross_endian); + break; #endif #ifdef CONFIG_ALTIVEC case LOAD_VMX: - err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs); - goto ldst_done; + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC)) + return 0; + err = do_vec_load(op->reg, ea, size, regs, cross_endian); + break; #endif #ifdef CONFIG_VSX - case LOAD_VSX: - err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs); - goto ldst_done; + case LOAD_VSX: { + unsigned long msrbit = MSR_VSX; + + /* + * Some VSX instructions check the MSR_VEC bit rather than MSR_VSX + * when the target of the instruction is a vector register. + */ + if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC)) + msrbit = MSR_VEC; + if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit)) + return 0; + err = do_vsx_load(op, ea, regs, cross_endian); + break; + } #endif case LOAD_MULTI: - if (regs->msr & MSR_LE) - return 0; - rd = op.reg; + if (!address_ok(regs, ea, size)) + return -EFAULT; + rd = op->reg; for (i = 0; i < size; i += 4) { + unsigned int v32 = 0; + nb = size - i; if (nb > 4) nb = 4; - err = read_mem(®s->gpr[rd], op.ea, nb, regs); + err = copy_mem_in((u8 *) &v32, ea, nb, regs); if (err) - return 0; - if (nb < 4) /* left-justify last bytes */ - regs->gpr[rd] <<= 32 - 8 * nb; - op.ea += 4; - ++rd; + break; + if (unlikely(cross_endian)) + v32 = byterev_4(v32); + regs->gpr[rd] = v32; + ea += 4; + /* reg number wraps from 31 to 0 for lsw[ix] */ + rd = (rd + 1) & 0x1f; } - goto instr_done; + break; case STORE: - if ((op.type & UPDATE) && size == sizeof(long) && - op.reg == 1 && op.update_reg == 1 && +#ifdef __powerpc64__ + if (size == 16) { + err = emulate_stq(regs, ea, op->reg, cross_endian); + break; + } +#endif + if ((op->type & UPDATE) && size == sizeof(long) && + op->reg == 1 && op->update_reg == 1 && !(regs->msr & MSR_PR) && - op.ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) { - err = handle_stack_update(op.ea, regs); - goto ldst_done; + ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) { + err = handle_stack_update(ea, regs); + break; } - err = write_mem(op.val, op.ea, size, regs); - goto ldst_done; + if (unlikely(cross_endian)) + do_byterev(&op->val, size); + err = write_mem(op->val, ea, size, regs); + break; #ifdef CONFIG_PPC_FPU case STORE_FP: - if (size == 4) - err = do_fp_store(op.reg, do_stfs, op.ea, size, regs); - else - err = do_fp_store(op.reg, do_stfd, op.ea, size, regs); - goto ldst_done; + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP)) + return 0; + err = do_fp_store(op, ea, regs, cross_endian); + break; #endif #ifdef CONFIG_ALTIVEC case STORE_VMX: - err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs); - goto ldst_done; + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC)) + return 0; + err = do_vec_store(op->reg, ea, size, regs, cross_endian); + break; #endif #ifdef CONFIG_VSX - case STORE_VSX: - err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs); - goto ldst_done; + case STORE_VSX: { + unsigned long msrbit = MSR_VSX; + + /* + * Some VSX instructions check the MSR_VEC bit rather than MSR_VSX + * when the target of the instruction is a vector register. + */ + if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC)) + msrbit = MSR_VEC; + if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit)) + return 0; + err = do_vsx_store(op, ea, regs, cross_endian); + break; + } #endif case STORE_MULTI: - if (regs->msr & MSR_LE) - return 0; - rd = op.reg; + if (!address_ok(regs, ea, size)) + return -EFAULT; + rd = op->reg; for (i = 0; i < size; i += 4) { - val = regs->gpr[rd]; + unsigned int v32 = regs->gpr[rd]; + nb = size - i; if (nb > 4) nb = 4; - else - val >>= 32 - 8 * nb; - err = write_mem(val, op.ea, nb, regs); + if (unlikely(cross_endian)) + v32 = byterev_4(v32); + err = copy_mem_out((u8 *) &v32, ea, nb, regs); if (err) - return 0; - op.ea += 4; - ++rd; + break; + ea += 4; + /* reg number wraps from 31 to 0 for stsw[ix] */ + rd = (rd + 1) & 0x1f; + } + break; + + default: + return -EINVAL; + } + + if (err) + return err; + + if (op->type & UPDATE) + regs->gpr[op->update_reg] = op->ea; + + return 0; +} +NOKPROBE_SYMBOL(emulate_loadstore); + +/* + * Emulate instructions that cause a transfer of control, + * loads and stores, and a few other instructions. + * Returns 1 if the step was emulated, 0 if not, + * or -1 if the instruction is one that should not be stepped, + * such as an rfid, or a mtmsrd that would clear MSR_RI. + */ +int emulate_step(struct pt_regs *regs, unsigned int instr) +{ + struct instruction_op op; + int r, err, type; + unsigned long val; + unsigned long ea; + + r = analyse_instr(&op, regs, instr); + if (r < 0) + return r; + if (r > 0) { + emulate_update_regs(regs, &op); + return 1; + } + + err = 0; + type = op.type & INSTR_TYPE_MASK; + + if (OP_IS_LOAD_STORE(type)) { + err = emulate_loadstore(regs, &op); + if (err) + return 0; + goto instr_done; + } + + switch (type) { + case CACHEOP: + ea = truncate_if_32bit(regs->msr, op.ea); + if (!address_ok(regs, ea, 8)) + return 0; + switch (op.type & CACHEOP_MASK) { + case DCBST: + __cacheop_user_asmx(ea, err, "dcbst"); + break; + case DCBF: + __cacheop_user_asmx(ea, err, "dcbf"); + break; + case DCBTST: + if (op.reg == 0) + prefetchw((void *) ea); + break; + case DCBT: + if (op.reg == 0) + prefetch((void *) ea); + break; + case ICBI: + __cacheop_user_asmx(ea, err, "icbi"); + break; + case DCBZ: + err = emulate_dcbz(ea, regs); + break; + } + if (err) { + regs->dar = ea; + return 0; } goto instr_done; @@ -1998,12 +3061,6 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) } return 0; - ldst_done: - if (err) - return 0; - if (op.type & UPDATE) - regs->gpr[op.update_reg] = op.ea; - instr_done: regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); return 1; diff --git a/arch/powerpc/lib/string_64.S b/arch/powerpc/lib/string_64.S index d5b4d9498c5426d19f54b3c4b5565399312406b9..56aac4c2202570c27da243049398b30c07f7cde5 100644 --- a/arch/powerpc/lib/string_64.S +++ b/arch/powerpc/lib/string_64.S @@ -184,7 +184,7 @@ err1; std r0,8(r3) mtctr r6 mr r8,r3 14: -err1; dcbz r0,r3 +err1; dcbz 0,r3 add r3,r3,r9 bdnz 14b diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c index f4c6472f2fc4dcf39cd3d3dd495a23db90125e26..f29212e40f40928e9d4b7e5c5a28bc294e8d0051 100644 --- a/arch/powerpc/mm/8xx_mmu.c +++ b/arch/powerpc/mm/8xx_mmu.c @@ -22,8 +22,11 @@ extern int __map_without_ltlbs; +static unsigned long block_mapped_ram; + /* - * Return PA for this VA if it is in IMMR area, or 0 + * Return PA for this VA if it is in an area mapped with LTLBs. + * Otherwise, returns 0 */ phys_addr_t v_block_mapped(unsigned long va) { @@ -33,11 +36,13 @@ phys_addr_t v_block_mapped(unsigned long va) return 0; if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE) return p + va - VIRT_IMMR_BASE; + if (va >= PAGE_OFFSET && va < PAGE_OFFSET + block_mapped_ram) + return __pa(va); return 0; } /* - * Return VA for a given PA or 0 if not mapped + * Return VA for a given PA mapped with LTLBs or 0 if not mapped */ unsigned long p_block_mapped(phys_addr_t pa) { @@ -47,6 +52,8 @@ unsigned long p_block_mapped(phys_addr_t pa) return 0; if (pa >= p && pa < p + IMMR_SIZE) return VIRT_IMMR_BASE + pa - p; + if (pa < block_mapped_ram) + return (unsigned long)__va(pa); return 0; } @@ -58,7 +65,7 @@ unsigned long p_block_mapped(phys_addr_t pa) void __init MMU_init_hw(void) { /* PIN up to the 3 first 8Mb after IMMR in DTLB table */ -#ifdef CONFIG_PIN_TLB +#ifdef CONFIG_PIN_TLB_DATA unsigned long ctr = mfspr(SPRN_MD_CTR) & 0xfe000000; unsigned long flags = 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY; #ifdef CONFIG_PIN_TLB_IMMR @@ -80,7 +87,7 @@ void __init MMU_init_hw(void) #endif } -static void mmu_mapin_immr(void) +static void __init mmu_mapin_immr(void) { unsigned long p = PHYS_IMMR_BASE; unsigned long v = VIRT_IMMR_BASE; @@ -96,8 +103,11 @@ static void mmu_mapin_immr(void) extern unsigned int DTLBMiss_jmp; #endif extern unsigned int DTLBMiss_cmp, FixupDAR_cmp; +#ifndef CONFIG_PIN_TLB_TEXT +extern unsigned int ITLBMiss_cmp; +#endif -void mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped) +static void __init mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped) { unsigned int instr = *addr; @@ -115,6 +125,9 @@ unsigned long __init mmu_mapin_ram(unsigned long top) mmu_mapin_immr(); #ifndef CONFIG_PIN_TLB_IMMR patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP); +#endif +#ifndef CONFIG_PIN_TLB_TEXT + mmu_patch_cmp_limit(&ITLBMiss_cmp, 0); #endif } else { mapped = top & ~(LARGE_PAGE_SIZE_8M - 1); @@ -133,11 +146,13 @@ unsigned long __init mmu_mapin_ram(unsigned long top) if (mapped) memblock_set_current_limit(mapped); + block_mapped_ram = mapped; + return mapped; } -void setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size) +void __init setup_initial_memory_limit(phys_addr_t first_memblock_base, + phys_addr_t first_memblock_size) { /* We don't currently support the first MEMBLOCK not mapping 0 * physical on those processors diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 7414034df1c364682ee8736d72c09927bea7ff24..fb844d2f266e1666aa91199b16fc5bad7972eaed 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -8,7 +8,7 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) obj-y := fault.o mem.o pgtable.o mmap.o \ init_$(BITS).o pgtable_$(BITS).o \ - init-common.o + init-common.o mmu_context.o obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ tlb_nohash_low.o obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(BITS)e.o @@ -22,8 +22,6 @@ ifeq ($(CONFIG_PPC_STD_MMU_64),y) obj-$(CONFIG_PPC_4K_PAGES) += hash64_4k.o obj-$(CONFIG_PPC_64K_PAGES) += hash64_64k.o endif -obj-$(CONFIG_PPC_ICSWX) += icswx.o -obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o obj-$(CONFIG_40x) += 40x_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_PPC_8xx) += 8xx_mmu.o diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/dump_hashpagetable.c index b1c144b03fcf3c448245aec655d84b3c1561f65c..5c4c93dcff190bf5a4babd9f8a8197aadd27347d 100644 --- a/arch/powerpc/mm/dump_hashpagetable.c +++ b/arch/powerpc/mm/dump_hashpagetable.c @@ -205,7 +205,7 @@ static void dump_hpte_info(struct pg_state *st, unsigned long ea, u64 v, u64 r, aps_index = calculate_pagesize(st, aps, "actual"); if (aps_index != 2) seq_printf(st->seq, "LP enc: %lx", lp); - seq_puts(st->seq, "\n"); + seq_putc(st->seq, '\n'); } diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c index 44fe4833910f64bcd014a2e3843ecd8c3077fc26..c9282d27b2037122577e7966601d70914e794bbc 100644 --- a/arch/powerpc/mm/dump_linuxpagetables.c +++ b/arch/powerpc/mm/dump_linuxpagetables.c @@ -350,7 +350,7 @@ static void note_page(struct pg_state *st, unsigned long addr, st->current_flags, pg_level[st->level].num); - seq_puts(st->seq, "\n"); + seq_putc(st->seq, '\n'); } /* diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 4c422632047bae05984eb7a44f80fba5a3f134d0..4797d08581cec347b6cf34a316c1ef585209653c 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -45,43 +45,39 @@ #include #include -#include "icswx.h" - -#ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs) +static inline bool notify_page_fault(struct pt_regs *regs) { - int ret = 0; + bool ret = false; +#ifdef CONFIG_KPROBES /* kprobe_running() needs smp_processor_id() */ if (!user_mode(regs)) { preempt_disable(); if (kprobe_running() && kprobe_fault_handler(regs, 11)) - ret = 1; + ret = true; preempt_enable(); } +#endif /* CONFIG_KPROBES */ + + if (unlikely(debugger_fault_handler(regs))) + ret = true; return ret; } -#else -static inline int notify_page_fault(struct pt_regs *regs) -{ - return 0; -} -#endif /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. */ -static int store_updates_sp(struct pt_regs *regs) +static bool store_updates_sp(struct pt_regs *regs) { unsigned int inst; if (get_user(inst, (unsigned int __user *)regs->nip)) - return 0; + return false; /* check for 1 in the rA field */ if (((inst >> 16) & 0x1f) != 1) - return 0; + return false; /* check major opcode */ switch (inst >> 26) { case 37: /* stwu */ @@ -89,7 +85,7 @@ static int store_updates_sp(struct pt_regs *regs) case 45: /* sthu */ case 53: /* stfsu */ case 55: /* stfdu */ - return 1; + return true; case 62: /* std or stdu */ return (inst & 3) == 1; case 31: @@ -101,18 +97,53 @@ static int store_updates_sp(struct pt_regs *regs) case 439: /* sthux */ case 695: /* stfsux */ case 759: /* stfdux */ - return 1; + return true; } } - return 0; + return false; } /* * do_page_fault error handling helpers */ -#define MM_FAULT_RETURN 0 -#define MM_FAULT_CONTINUE -1 -#define MM_FAULT_ERR(sig) (sig) +static int +__bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code) +{ + /* + * If we are in kernel mode, bail out with a SEGV, this will + * be caught by the assembly which will restore the non-volatile + * registers before calling bad_page_fault() + */ + if (!user_mode(regs)) + return SIGSEGV; + + _exception(SIGSEGV, regs, si_code, address); + + return 0; +} + +static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address) +{ + return __bad_area_nosemaphore(regs, address, SEGV_MAPERR); +} + +static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code) +{ + struct mm_struct *mm = current->mm; + + /* + * Something tried to access memory that isn't in our memory map.. + * Fix it, but check if it's kernel or user first.. + */ + up_read(&mm->mmap_sem); + + return __bad_area_nosemaphore(regs, address, si_code); +} + +static noinline int bad_area(struct pt_regs *regs, unsigned long address) +{ + return __bad_area(regs, address, SEGV_MAPERR); +} static int do_sigbus(struct pt_regs *regs, unsigned long address, unsigned int fault) @@ -121,7 +152,7 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address, unsigned int lsb = 0; if (!user_mode(regs)) - return MM_FAULT_ERR(SIGBUS); + return SIGBUS; current->thread.trap_nr = BUS_ADRERR; info.si_signo = SIGBUS; @@ -142,25 +173,17 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address, #endif info.si_addr_lsb = lsb; force_sig_info(SIGBUS, &info, current); - return MM_FAULT_RETURN; + return 0; } static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) { /* - * Pagefault was interrupted by SIGKILL. We have no reason to - * continue the pagefault. + * Kernel page fault interrupted by SIGKILL. We have no reason to + * continue processing. */ - if (fatal_signal_pending(current)) { - /* Coming from kernel, we need to deal with uaccess fixups */ - if (user_mode(regs)) - return MM_FAULT_RETURN; - return MM_FAULT_ERR(SIGKILL); - } - - /* No fault: be happy */ - if (!(fault & VM_FAULT_ERROR)) - return MM_FAULT_CONTINUE; + if (fatal_signal_pending(current) && !user_mode(regs)) + return SIGKILL; /* Out of memory */ if (fault & VM_FAULT_OOM) { @@ -169,19 +192,176 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) * made us unable to handle the page fault gracefully. */ if (!user_mode(regs)) - return MM_FAULT_ERR(SIGKILL); + return SIGSEGV; pagefault_out_of_memory(); - return MM_FAULT_RETURN; + } else { + if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| + VM_FAULT_HWPOISON_LARGE)) + return do_sigbus(regs, addr, fault); + else if (fault & VM_FAULT_SIGSEGV) + return bad_area_nosemaphore(regs, addr); + else + BUG(); + } + return 0; +} + +/* Is this a bad kernel fault ? */ +static bool bad_kernel_fault(bool is_exec, unsigned long error_code, + unsigned long address) +{ + if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT))) { + printk_ratelimited(KERN_CRIT "kernel tried to execute" + " exec-protected page (%lx) -" + "exploit attempt? (uid: %d)\n", + address, from_kuid(&init_user_ns, + current_uid())); } + return is_exec || (address >= TASK_SIZE); +} - if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) - return do_sigbus(regs, addr, fault); +static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address, + struct vm_area_struct *vma, + bool store_update_sp) +{ + /* + * N.B. The POWER/Open ABI allows programs to access up to + * 288 bytes below the stack pointer. + * The kernel signal delivery code writes up to about 1.5kB + * below the stack pointer (r1) before decrementing it. + * The exec code can write slightly over 640kB to the stack + * before setting the user r1. Thus we allow the stack to + * expand to 1MB without further checks. + */ + if (address + 0x100000 < vma->vm_end) { + /* get user regs even if this fault is in kernel mode */ + struct pt_regs *uregs = current->thread.regs; + if (uregs == NULL) + return true; - /* We don't understand the fault code, this is fatal */ - BUG(); - return MM_FAULT_CONTINUE; + /* + * A user-mode access to an address a long way below + * the stack pointer is only valid if the instruction + * is one which would update the stack pointer to the + * address accessed if the instruction completed, + * i.e. either stwu rs,n(r1) or stwux rs,r1,rb + * (or the byte, halfword, float or double forms). + * + * If we don't check this then any write to the area + * between the last mapped region and the stack will + * expand the stack rather than segfaulting. + */ + if (address + 2048 < uregs->gpr[1] && !store_update_sp) + return true; + } + return false; +} + +static bool access_error(bool is_write, bool is_exec, + struct vm_area_struct *vma) +{ + /* + * Allow execution from readable areas if the MMU does not + * provide separate controls over reading and executing. + * + * Note: That code used to not be enabled for 4xx/BookE. + * It is now as I/D cache coherency for these is done at + * set_pte_at() time and I see no reason why the test + * below wouldn't be valid on those processors. This -may- + * break programs compiled with a really old ABI though. + */ + if (is_exec) { + return !(vma->vm_flags & VM_EXEC) && + (cpu_has_feature(CPU_FTR_NOEXECUTE) || + !(vma->vm_flags & (VM_READ | VM_WRITE))); + } + + if (is_write) { + if (unlikely(!(vma->vm_flags & VM_WRITE))) + return true; + return false; + } + + if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + return true; + + return false; } +#ifdef CONFIG_PPC_SMLPAR +static inline void cmo_account_page_fault(void) +{ + if (firmware_has_feature(FW_FEATURE_CMO)) { + u32 page_ins; + + preempt_disable(); + page_ins = be32_to_cpu(get_lppaca()->page_ins); + page_ins += 1 << PAGE_FACTOR; + get_lppaca()->page_ins = cpu_to_be32(page_ins); + preempt_enable(); + } +} +#else +static inline void cmo_account_page_fault(void) { } +#endif /* CONFIG_PPC_SMLPAR */ + +#ifdef CONFIG_PPC_STD_MMU +static void sanity_check_fault(bool is_write, unsigned long error_code) +{ + /* + * For hash translation mode, we should never get a + * PROTFAULT. Any update to pte to reduce access will result in us + * removing the hash page table entry, thus resulting in a DSISR_NOHPTE + * fault instead of DSISR_PROTFAULT. + * + * A pte update to relax the access will not result in a hash page table + * entry invalidate and hence can result in DSISR_PROTFAULT. + * ptep_set_access_flags() doesn't do a hpte flush. This is why we have + * the special !is_write in the below conditional. + * + * For platforms that doesn't supports coherent icache and do support + * per page noexec bit, we do setup things such that we do the + * sync between D/I cache via fault. But that is handled via low level + * hash fault code (hash_page_do_lazy_icache()) and we should not reach + * here in such case. + * + * For wrong access that can result in PROTFAULT, the above vma->vm_flags + * check should handle those and hence we should fall to the bad_area + * handling correctly. + * + * For embedded with per page exec support that doesn't support coherent + * icache we do get PROTFAULT and we handle that D/I cache sync in + * set_pte_at while taking the noexec/prot fault. Hence this is WARN_ON + * is conditional for server MMU. + * + * For radix, we can get prot fault for autonuma case, because radix + * page table will have them marked noaccess for user. + */ + if (!radix_enabled() && !is_write) + WARN_ON_ONCE(error_code & DSISR_PROTFAULT); +} +#else +static void sanity_check_fault(bool is_write, unsigned long error_code) { } +#endif /* CONFIG_PPC_STD_MMU */ + +/* + * Define the correct "is_write" bit in error_code based + * on the processor family + */ +#if (defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) +#define page_fault_is_write(__err) ((__err) & ESR_DST) +#define page_fault_is_bad(__err) (0) +#else +#define page_fault_is_write(__err) ((__err) & DSISR_ISSTORE) +#if defined(CONFIG_PPC_8xx) +#define page_fault_is_bad(__err) ((__err) & DSISR_NOEXEC_OR_G) +#elif defined(CONFIG_PPC64) +#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_64S) +#else +#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S) +#endif +#endif + /* * For 600- and 800-family processors, the error_code parameter is DSISR * for a data fault, SRR1 for an instruction fault. For 400-family processors @@ -195,92 +375,56 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) * The return value is 0 if the fault was handled, or the signal * number if this is a kernel fault that can't be handled here. */ -int do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +static int __do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) { - enum ctx_state prev_state = exception_enter(); struct vm_area_struct * vma; struct mm_struct *mm = current->mm; unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; - int code = SEGV_MAPERR; - int is_write = 0; - int trap = TRAP(regs); - int is_exec = trap == 0x400; + int is_exec = TRAP(regs) == 0x400; int is_user = user_mode(regs); - int fault; - int rc = 0, store_update_sp = 0; + int is_write = page_fault_is_write(error_code); + int fault, major = 0; + bool store_update_sp = false; -#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) - /* - * Fortunately the bit assignments in SRR1 for an instruction - * fault and DSISR for a data fault are mostly the same for the - * bits we are interested in. But there are some bits which - * indicate errors in DSISR but can validly be set in SRR1. - */ - if (is_exec) - error_code &= 0x48200000; - else - is_write = error_code & DSISR_ISSTORE; -#else - is_write = error_code & ESR_DST; -#endif /* CONFIG_4xx || CONFIG_BOOKE */ + if (notify_page_fault(regs)) + return 0; -#ifdef CONFIG_PPC_ICSWX - /* - * we need to do this early because this "data storage - * interrupt" does not update the DAR/DEAR so we don't want to - * look at it - */ - if (error_code & ICSWX_DSI_UCT) { - rc = acop_handle_fault(regs, address, error_code); - if (rc) - goto bail; + if (unlikely(page_fault_is_bad(error_code))) { + if (is_user) { + _exception(SIGBUS, regs, BUS_OBJERR, address); + return 0; + } + return SIGBUS; } -#endif /* CONFIG_PPC_ICSWX */ - - if (notify_page_fault(regs)) - goto bail; - if (unlikely(debugger_fault_handler(regs))) - goto bail; + /* Additional sanity check(s) */ + sanity_check_fault(is_write, error_code); /* * The kernel should never take an execute fault nor should it * take a page fault to a kernel address. */ - if (!is_user && (is_exec || (address >= TASK_SIZE))) { - rc = SIGSEGV; - goto bail; - } + if (unlikely(!is_user && bad_kernel_fault(is_exec, error_code, address))) + return SIGSEGV; -#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \ - defined(CONFIG_PPC_BOOK3S_64) || defined(CONFIG_PPC_8xx)) - if (error_code & DSISR_DABRMATCH) { - /* breakpoint match */ - do_break(regs, address, error_code); - goto bail; + /* + * If we're in an interrupt, have no user context or are running + * in a region with pagefaults disabled then we must not take the fault + */ + if (unlikely(faulthandler_disabled() || !mm)) { + if (is_user) + printk_ratelimited(KERN_ERR "Page fault in user mode" + " with faulthandler_disabled()=%d" + " mm=%p\n", + faulthandler_disabled(), mm); + return bad_area_nosemaphore(regs, address); } -#endif /* We restore the interrupt state now */ if (!arch_irq_disabled_regs(regs)) local_irq_enable(); - if (faulthandler_disabled() || mm == NULL) { - if (!is_user) { - rc = SIGSEGV; - goto bail; - } - /* faulthandler_disabled() in user mode is really bad, - as is current->mm == NULL. */ - printk(KERN_EMERG "Page fault in user mode with " - "faulthandler_disabled() = %d mm = %p\n", - faulthandler_disabled(), mm); - printk(KERN_EMERG "NIP = %lx MSR = %lx\n", - regs->nip, regs->msr); - die("Weird page fault", regs, SIGSEGV); - } - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); /* @@ -293,6 +437,10 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, if (is_user) flags |= FAULT_FLAG_USER; + if (is_write) + flags |= FAULT_FLAG_WRITE; + if (is_exec) + flags |= FAULT_FLAG_INSTRUCTION; /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the @@ -309,9 +457,9 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, * source. If this is invalid we can skip the address space check, * thus avoiding the deadlock. */ - if (!down_read_trylock(&mm->mmap_sem)) { + if (unlikely(!down_read_trylock(&mm->mmap_sem))) { if (!is_user && !search_exception_tables(regs->nip)) - goto bad_area_nosemaphore; + return bad_area_nosemaphore(regs, address); retry: down_read(&mm->mmap_sem); @@ -325,122 +473,24 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, } vma = find_vma(mm, address); - if (!vma) - goto bad_area; - if (vma->vm_start <= address) + if (unlikely(!vma)) + return bad_area(regs, address); + if (likely(vma->vm_start <= address)) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; + if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) + return bad_area(regs, address); - /* - * N.B. The POWER/Open ABI allows programs to access up to - * 288 bytes below the stack pointer. - * The kernel signal delivery code writes up to about 1.5kB - * below the stack pointer (r1) before decrementing it. - * The exec code can write slightly over 640kB to the stack - * before setting the user r1. Thus we allow the stack to - * expand to 1MB without further checks. - */ - if (address + 0x100000 < vma->vm_end) { - /* get user regs even if this fault is in kernel mode */ - struct pt_regs *uregs = current->thread.regs; - if (uregs == NULL) - goto bad_area; + /* The stack is being expanded, check if it's valid */ + if (unlikely(bad_stack_expansion(regs, address, vma, store_update_sp))) + return bad_area(regs, address); - /* - * A user-mode access to an address a long way below - * the stack pointer is only valid if the instruction - * is one which would update the stack pointer to the - * address accessed if the instruction completed, - * i.e. either stwu rs,n(r1) or stwux rs,r1,rb - * (or the byte, halfword, float or double forms). - * - * If we don't check this then any write to the area - * between the last mapped region and the stack will - * expand the stack rather than segfaulting. - */ - if (address + 2048 < uregs->gpr[1] && !store_update_sp) - goto bad_area; - } - if (expand_stack(vma, address)) - goto bad_area; + /* Try to expand it */ + if (unlikely(expand_stack(vma, address))) + return bad_area(regs, address); good_area: - code = SEGV_ACCERR; -#if defined(CONFIG_6xx) - if (error_code & 0x95700000) - /* an error such as lwarx to I/O controller space, - address matching DABR, eciwx, etc. */ - goto bad_area; -#endif /* CONFIG_6xx */ -#if defined(CONFIG_8xx) - /* The MPC8xx seems to always set 0x80000000, which is - * "undefined". Of those that can be set, this is the only - * one which seems bad. - */ - if (error_code & 0x10000000) - /* Guarded storage error. */ - goto bad_area; -#endif /* CONFIG_8xx */ - - if (is_exec) { - /* - * Allow execution from readable areas if the MMU does not - * provide separate controls over reading and executing. - * - * Note: That code used to not be enabled for 4xx/BookE. - * It is now as I/D cache coherency for these is done at - * set_pte_at() time and I see no reason why the test - * below wouldn't be valid on those processors. This -may- - * break programs compiled with a really old ABI though. - */ - if (!(vma->vm_flags & VM_EXEC) && - (cpu_has_feature(CPU_FTR_NOEXECUTE) || - !(vma->vm_flags & (VM_READ | VM_WRITE)))) - goto bad_area; - /* a write */ - } else if (is_write) { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - flags |= FAULT_FLAG_WRITE; - /* a read */ - } else { - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) - goto bad_area; - } -#ifdef CONFIG_PPC_STD_MMU - /* - * For hash translation mode, we should never get a - * PROTFAULT. Any update to pte to reduce access will result in us - * removing the hash page table entry, thus resulting in a DSISR_NOHPTE - * fault instead of DSISR_PROTFAULT. - * - * A pte update to relax the access will not result in a hash page table - * entry invalidate and hence can result in DSISR_PROTFAULT. - * ptep_set_access_flags() doesn't do a hpte flush. This is why we have - * the special !is_write in the below conditional. - * - * For platforms that doesn't supports coherent icache and do support - * per page noexec bit, we do setup things such that we do the - * sync between D/I cache via fault. But that is handled via low level - * hash fault code (hash_page_do_lazy_icache()) and we should not reach - * here in such case. - * - * For wrong access that can result in PROTFAULT, the above vma->vm_flags - * check should handle those and hence we should fall to the bad_area - * handling correctly. - * - * For embedded with per page exec support that doesn't support coherent - * icache we do get PROTFAULT and we handle that D/I cache sync in - * set_pte_at while taking the noexec/prot fault. Hence this is WARN_ON - * is conditional for server MMU. - * - * For radix, we can get prot fault for autonuma case, because radix - * page table will have them marked noaccess for user. - */ - if (!radix_enabled() && !is_write) - WARN_ON_ONCE(error_code & DSISR_PROTFAULT); -#endif /* CONFIG_PPC_STD_MMU */ + if (unlikely(access_error(is_write, is_exec, vma))) + return bad_area(regs, address); /* * If for any reason at all we couldn't handle the fault, @@ -448,6 +498,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, * the fault. */ fault = handle_mm_fault(vma, address, flags); + major |= fault & VM_FAULT_MAJOR; /* * Handle the retry right now, the mmap_sem has been released in that @@ -465,64 +516,39 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, if (!fatal_signal_pending(current)) goto retry; } - /* We will enter mm_fault_error() below */ - } else - up_read(¤t->mm->mmap_sem); - - if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { - if (fault & VM_FAULT_SIGSEGV) - goto bad_area_nosemaphore; - rc = mm_fault_error(regs, address, fault); - if (rc >= MM_FAULT_RETURN) - goto bail; - else - rc = 0; + + /* + * User mode? Just return to handle the fatal exception otherwise + * return to bad_page_fault + */ + return is_user ? 0 : SIGBUS; } + up_read(¤t->mm->mmap_sem); + + if (unlikely(fault & VM_FAULT_ERROR)) + return mm_fault_error(regs, address, fault); + /* * Major/minor page fault accounting. */ - if (fault & VM_FAULT_MAJOR) { + if (major) { current->maj_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, - regs, address); -#ifdef CONFIG_PPC_SMLPAR - if (firmware_has_feature(FW_FEATURE_CMO)) { - u32 page_ins; - - preempt_disable(); - page_ins = be32_to_cpu(get_lppaca()->page_ins); - page_ins += 1 << PAGE_FACTOR; - get_lppaca()->page_ins = cpu_to_be32(page_ins); - preempt_enable(); - } -#endif /* CONFIG_PPC_SMLPAR */ + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); + cmo_account_page_fault(); } else { current->min_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, - regs, address); - } - - goto bail; - -bad_area: - up_read(&mm->mmap_sem); - -bad_area_nosemaphore: - /* User mode accesses cause a SIGSEGV */ - if (is_user) { - _exception(SIGSEGV, regs, code, address); - goto bail; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } + return 0; +} +NOKPROBE_SYMBOL(__do_page_fault); - if (is_exec && (error_code & DSISR_PROTFAULT)) - printk_ratelimited(KERN_CRIT "kernel tried to execute NX-protected" - " page (%lx) - exploit attempt? (uid: %d)\n", - address, from_kuid(&init_user_ns, current_uid())); - - rc = SIGSEGV; - -bail: +int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + enum ctx_state prev_state = exception_enter(); + int rc = __do_page_fault(regs, address, error_code); exception_exit(prev_state); return rc; } diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S index 6f962e5cb5e195cbb617359c3262d28ad164ab73..ffbd7c0bda968b1306bbafcac4703d2ae4ed0b61 100644 --- a/arch/powerpc/mm/hash_low_32.S +++ b/arch/powerpc/mm/hash_low_32.S @@ -575,7 +575,6 @@ _GLOBAL(flush_hash_pages) rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ stwcx. r8,0,r5 /* update the pte */ bne- 33b -EXPORT_SYMBOL(flush_hash_pages) /* Get the address of the primary PTE group in the hash table (r3) */ _GLOBAL(flush_hash_patch_A) @@ -634,6 +633,7 @@ _GLOBAL(flush_hash_patch_B) SYNC_601 isync blr +EXPORT_SYMBOL(flush_hash_pages) /* * Flush an entry from the TLB diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 7a20669c19e7258d979d60a19f3acec378c9dbad..67ec2e927253ef47077e3b7daf91ff8d3998ecd4 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -61,6 +61,7 @@ #include #include #include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -507,9 +508,9 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, printk(KERN_INFO "Huge page(16GB) memory: " "addr = 0x%lX size = 0x%lX pages = %d\n", phys_addr, block_size, expected_pages); - if (phys_addr + (16 * GB) <= memblock_end_of_DRAM()) { + if (phys_addr + block_size * expected_pages <= memblock_end_of_DRAM()) { memblock_reserve(phys_addr, block_size * expected_pages); - add_gpage(phys_addr, block_size, expected_pages); + pseries_add_gpage(phys_addr, block_size, expected_pages); } return 0; } @@ -1019,6 +1020,7 @@ void __init hash__early_init_mmu(void) __kernel_virt_size = H_KERN_VIRT_SIZE; __vmalloc_start = H_VMALLOC_START; __vmalloc_end = H_VMALLOC_END; + __kernel_io_start = H_KERN_IO_START; vmemmap = (struct page *)H_VMEMMAP_BASE; ioremap_bot = IOREMAP_BASE; @@ -1228,7 +1230,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long vsid; pte_t *ptep; unsigned hugeshift; - const struct cpumask *tmp; int rc, user_region = 0; int psize, ssize; @@ -1280,8 +1281,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, } /* Check CPU locality */ - tmp = cpumask_of(smp_processor_id()); - if (user_region && cpumask_equal(mm_cpumask(mm), tmp)) + if (user_region && mm_is_thread_local(mm)) flags |= HPTE_LOCAL_UPDATE; #ifndef CONFIG_PPC_64K_PAGES @@ -1297,7 +1297,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, #endif /* CONFIG_PPC_64K_PAGES */ /* Get PTE and page size from page tables */ - ptep = __find_linux_pte_or_hugepte(pgdir, ea, &is_thp, &hugeshift); + ptep = find_linux_pte(pgdir, ea, &is_thp, &hugeshift); if (ptep == NULL || !pte_present(*ptep)) { DBG_LOW(" no PTE !\n"); rc = 1; @@ -1526,7 +1526,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, * THP pages use update_mmu_cache_pmd. We don't do * hash preload there. Hence can ignore THP here */ - ptep = find_linux_pte_or_hugepte(pgdir, ea, NULL, &hugepage_shift); + ptep = find_current_mm_pte(pgdir, ea, NULL, &hugepage_shift); if (!ptep) goto out_exit; @@ -1543,7 +1543,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, #endif /* CONFIG_PPC_64K_PAGES */ /* Is that local to this CPU ? */ - if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) + if (mm_is_thread_local(mm)) update_flags |= HPTE_LOCAL_UPDATE; /* Hash it in */ diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index e1bf5ca397fe13c00ebe194e879a21ac759f8f28..1571a498a33fc6a688713f4f275b7b55cedabace 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -24,6 +24,8 @@ #include #include #include +#include + #ifdef CONFIG_HUGETLB_PAGE @@ -36,32 +38,15 @@ unsigned int HPAGE_SHIFT; EXPORT_SYMBOL(HPAGE_SHIFT); -/* - * Tracks gpages after the device tree is scanned and before the - * huge_boot_pages list is ready. On non-Freescale implementations, this is - * just used to track 16G pages and so is a single array. FSL-based - * implementations may have more than one gpage size, so we need multiple - * arrays - */ -#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx) -#define MAX_NUMBER_GPAGES 128 -struct psize_gpages { - u64 gpage_list[MAX_NUMBER_GPAGES]; - unsigned int nr_gpages; -}; -static struct psize_gpages gpage_freearray[MMU_PAGE_COUNT]; -#else -#define MAX_NUMBER_GPAGES 1024 -static u64 gpage_freearray[MAX_NUMBER_GPAGES]; -static unsigned nr_gpages; -#endif - #define hugepd_none(hpd) (hpd_val(hpd) == 0) pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz) { - /* Only called for hugetlbfs pages, hence can ignore THP */ - return __find_linux_pte_or_hugepte(mm->pgd, addr, NULL, NULL); + /* + * Only called for hugetlbfs pages, hence can ignore THP and the + * irq disabled walk. + */ + return __find_linux_pte(mm->pgd, addr, NULL, NULL); } static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, @@ -210,145 +195,20 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz return hugepte_offset(*hpdp, addr, pdshift); } -#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx) -/* Build list of addresses of gigantic pages. This function is used in early - * boot before the buddy allocator is setup. - */ -void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) -{ - unsigned int idx = shift_to_mmu_psize(__ffs(page_size)); - int i; - - if (addr == 0) - return; - - gpage_freearray[idx].nr_gpages = number_of_pages; - - for (i = 0; i < number_of_pages; i++) { - gpage_freearray[idx].gpage_list[i] = addr; - addr += page_size; - } -} - -/* - * Moves the gigantic page addresses from the temporary list to the - * huge_boot_pages list. - */ -int alloc_bootmem_huge_page(struct hstate *hstate) -{ - struct huge_bootmem_page *m; - int idx = shift_to_mmu_psize(huge_page_shift(hstate)); - int nr_gpages = gpage_freearray[idx].nr_gpages; - - if (nr_gpages == 0) - return 0; - -#ifdef CONFIG_HIGHMEM - /* - * If gpages can be in highmem we can't use the trick of storing the - * data structure in the page; allocate space for this - */ - m = memblock_virt_alloc(sizeof(struct huge_bootmem_page), 0); - m->phys = gpage_freearray[idx].gpage_list[--nr_gpages]; -#else - m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]); -#endif - - list_add(&m->list, &huge_boot_pages); - gpage_freearray[idx].nr_gpages = nr_gpages; - gpage_freearray[idx].gpage_list[nr_gpages] = 0; - m->hstate = hstate; - - return 1; -} +#ifdef CONFIG_PPC_BOOK3S_64 /* - * Scan the command line hugepagesz= options for gigantic pages; store those in - * a list that we use to allocate the memory once all options are parsed. + * Tracks gpages after the device tree is scanned and before the + * huge_boot_pages list is ready on pseries. */ - -unsigned long gpage_npages[MMU_PAGE_COUNT]; - -static int __init do_gpage_early_setup(char *param, char *val, - const char *unused, void *arg) -{ - static phys_addr_t size; - unsigned long npages; - - /* - * The hugepagesz and hugepages cmdline options are interleaved. We - * use the size variable to keep track of whether or not this was done - * properly and skip over instances where it is incorrect. Other - * command-line parsing code will issue warnings, so we don't need to. - * - */ - if ((strcmp(param, "default_hugepagesz") == 0) || - (strcmp(param, "hugepagesz") == 0)) { - size = memparse(val, NULL); - } else if (strcmp(param, "hugepages") == 0) { - if (size != 0) { - if (sscanf(val, "%lu", &npages) <= 0) - npages = 0; - if (npages > MAX_NUMBER_GPAGES) { - pr_warn("MMU: %lu pages requested for page " -#ifdef CONFIG_PHYS_ADDR_T_64BIT - "size %llu KB, limiting to " -#else - "size %u KB, limiting to " -#endif - __stringify(MAX_NUMBER_GPAGES) "\n", - npages, size / 1024); - npages = MAX_NUMBER_GPAGES; - } - gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages; - size = 0; - } - } - return 0; -} - +#define MAX_NUMBER_GPAGES 1024 +__initdata static u64 gpage_freearray[MAX_NUMBER_GPAGES]; +__initdata static unsigned nr_gpages; /* - * This function allocates physical space for pages that are larger than the - * buddy allocator can handle. We want to allocate these in highmem because - * the amount of lowmem is limited. This means that this function MUST be - * called before lowmem_end_addr is set up in MMU_init() in order for the lmb - * allocate to grab highmem. - */ -void __init reserve_hugetlb_gpages(void) -{ - static __initdata char cmdline[COMMAND_LINE_SIZE]; - phys_addr_t size, base; - int i; - - strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); - parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0, - NULL, &do_gpage_early_setup); - - /* - * Walk gpage list in reverse, allocating larger page sizes first. - * Skip over unsupported sizes, or sizes that have 0 gpages allocated. - * When we reach the point in the list where pages are no longer - * considered gpages, we're done. - */ - for (i = MMU_PAGE_COUNT-1; i >= 0; i--) { - if (mmu_psize_defs[i].shift == 0 || gpage_npages[i] == 0) - continue; - else if (mmu_psize_to_shift(i) < (MAX_ORDER + PAGE_SHIFT)) - break; - - size = (phys_addr_t)(1ULL << mmu_psize_to_shift(i)); - base = memblock_alloc_base(size * gpage_npages[i], size, - MEMBLOCK_ALLOC_ANYWHERE); - add_gpage(base, size, gpage_npages[i]); - } -} - -#else /* !PPC_FSL_BOOK3E */ - -/* Build list of addresses of gigantic pages. This function is used in early + * Build list of addresses of gigantic pages. This function is used in early * boot before the buddy allocator is setup. */ -void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) +void __init pseries_add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) { if (!addr) return; @@ -360,10 +220,7 @@ void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) } } -/* Moves the gigantic page addresses from the temporary list to the - * huge_boot_pages list. - */ -int alloc_bootmem_huge_page(struct hstate *hstate) +int __init pseries_alloc_bootmem_huge_page(struct hstate *hstate) { struct huge_bootmem_page *m; if (nr_gpages == 0) @@ -376,6 +233,17 @@ int alloc_bootmem_huge_page(struct hstate *hstate) } #endif + +int __init alloc_bootmem_huge_page(struct hstate *h) +{ + +#ifdef CONFIG_PPC_BOOK3S_64 + if (firmware_has_feature(FW_FEATURE_LPAR) && !radix_enabled()) + return pseries_alloc_bootmem_huge_page(h); +#endif + return __alloc_bootmem_huge_page(h); +} + #if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx) #define HUGEPD_FREELIST_SIZE \ ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t)) @@ -407,8 +275,7 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte) batchp = &get_cpu_var(hugepd_freelist_cur); if (atomic_read(&tlb->mm->mm_users) < 2 || - cpumask_equal(mm_cpumask(tlb->mm), - cpumask_of(smp_processor_id()))) { + mm_is_thread_local(tlb->mm)) { kmem_cache_free(hugepte_cache, hugepte); put_cpu_var(hugepd_freelist_cur); return; @@ -886,9 +753,8 @@ void flush_dcache_icache_hugepage(struct page *page) * This function need to be called with interrupts disabled. We use this variant * when we have MSR[EE] = 0 but the paca->soft_enabled = 1 */ - -pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, - bool *is_thp, unsigned *shift) +pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hpage_shift) { pgd_t pgd, *pgdp; pud_t pud, *pudp; @@ -897,8 +763,8 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, hugepd_t *hpdp = NULL; unsigned pdshift = PGDIR_SHIFT; - if (shift) - *shift = 0; + if (hpage_shift) + *hpage_shift = 0; if (is_thp) *is_thp = false; @@ -968,16 +834,15 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, ret_pte = hugepte_offset(*hpdp, ea, pdshift); pdshift = hugepd_shift(*hpdp); out: - if (shift) - *shift = pdshift; + if (hpage_shift) + *hpage_shift = pdshift; return ret_pte; } -EXPORT_SYMBOL_GPL(__find_linux_pte_or_hugepte); +EXPORT_SYMBOL_GPL(__find_linux_pte); int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask; unsigned long pte_end; struct page *head, *page; pte_t pte; @@ -988,18 +853,10 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, end = pte_end; pte = READ_ONCE(*ptep); - mask = _PAGE_PRESENT | _PAGE_READ; - /* - * On some CPUs like the 8xx, _PAGE_RW hence _PAGE_WRITE is defined - * as 0 and _PAGE_RO has to be set when a page is not writable - */ - if (write) - mask |= _PAGE_WRITE; - else - mask |= _PAGE_RO; - - if ((pte_val(pte) & mask) != mask) + if (!pte_present(pte) || !pte_read(pte)) + return 0; + if (write && !pte_write(pte)) return 0; /* hugepages are never "special" */ diff --git a/arch/powerpc/mm/icswx.c b/arch/powerpc/mm/icswx.c deleted file mode 100644 index 1fa794d7d59f2d693fca0732b15b727e831bbcad..0000000000000000000000000000000000000000 --- a/arch/powerpc/mm/icswx.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * ICSWX and ACOP Management - * - * Copyright (C) 2011 Anton Blanchard, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "icswx.h" - -/* - * The processor and its L2 cache cause the icswx instruction to - * generate a COP_REQ transaction on PowerBus. The transaction has no - * address, and the processor does not perform an MMU access to - * authenticate the transaction. The command portion of the PowerBus - * COP_REQ transaction includes the LPAR_ID (LPID) and the coprocessor - * Process ID (PID), which the coprocessor compares to the authorized - * LPID and PID held in the coprocessor, to determine if the process - * is authorized to generate the transaction. The data of the COP_REQ - * transaction is 128-byte or less in size and is placed in cacheable - * memory on a 128-byte cache line boundary. - * - * The task to use a coprocessor should use use_cop() to mark the use - * of the Coprocessor Type (CT) and context switching. On a server - * class processor, the PID register is used only for coprocessor - * management + * and so a coprocessor PID is allocated before - * executing icswx + * instruction. Drop_cop() is used to free the - * coprocessor PID. - * - * Example: - * Host Fabric Interface (HFI) is a PowerPC network coprocessor. - * Each HFI have multiple windows. Each HFI window serves as a - * network device sending to and receiving from HFI network. - * HFI immediate send function uses icswx instruction. The immediate - * send function allows small (single cache-line) packets be sent - * without using the regular HFI send FIFO and doorbell, which are - * much slower than immediate send. - * - * For each task intending to use HFI immediate send, the HFI driver - * calls use_cop() to obtain a coprocessor PID for the task. - * The HFI driver then allocate a free HFI window and save the - * coprocessor PID to the HFI window to allow the task to use the - * HFI window. - * - * The HFI driver repeatedly creates immediate send packets and - * issues icswx instruction to send data through the HFI window. - * The HFI compares the coprocessor PID in the CPU PID register - * to the PID held in the HFI window to determine if the transaction - * is allowed. - * - * When the task to release the HFI window, the HFI driver calls - * drop_cop() to release the coprocessor PID. - */ - -void switch_cop(struct mm_struct *next) -{ -#ifdef CONFIG_PPC_ICSWX_PID - mtspr(SPRN_PID, next->context.cop_pid); -#endif - mtspr(SPRN_ACOP, next->context.acop); -} - -/** - * Start using a coprocessor. - * @acop: mask of coprocessor to be used. - * @mm: The mm the coprocessor to associate with. Most likely current mm. - * - * Return a positive PID if successful. Negative errno otherwise. - * The returned PID will be fed to the coprocessor to determine if an - * icswx transaction is authenticated. - */ -int use_cop(unsigned long acop, struct mm_struct *mm) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_ICSWX)) - return -ENODEV; - - if (!mm || !acop) - return -EINVAL; - - /* The page_table_lock ensures mm_users won't change under us */ - spin_lock(&mm->page_table_lock); - spin_lock(mm->context.cop_lockp); - - ret = get_cop_pid(mm); - if (ret < 0) - goto out; - - /* update acop */ - mm->context.acop |= acop; - - sync_cop(mm); - - /* - * If this is a threaded process then there might be other threads - * running. We need to send an IPI to force them to pick up any - * change in PID and ACOP. - */ - if (atomic_read(&mm->mm_users) > 1) - smp_call_function(sync_cop, mm, 1); - -out: - spin_unlock(mm->context.cop_lockp); - spin_unlock(&mm->page_table_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(use_cop); - -/** - * Stop using a coprocessor. - * @acop: mask of coprocessor to be stopped. - * @mm: The mm the coprocessor associated with. - */ -void drop_cop(unsigned long acop, struct mm_struct *mm) -{ - int free_pid; - - if (!cpu_has_feature(CPU_FTR_ICSWX)) - return; - - if (WARN_ON_ONCE(!mm)) - return; - - /* The page_table_lock ensures mm_users won't change under us */ - spin_lock(&mm->page_table_lock); - spin_lock(mm->context.cop_lockp); - - mm->context.acop &= ~acop; - - free_pid = disable_cop_pid(mm); - sync_cop(mm); - - /* - * If this is a threaded process then there might be other threads - * running. We need to send an IPI to force them to pick up any - * change in PID and ACOP. - */ - if (atomic_read(&mm->mm_users) > 1) - smp_call_function(sync_cop, mm, 1); - - if (free_pid != COP_PID_NONE) - free_cop_pid(free_pid); - - spin_unlock(mm->context.cop_lockp); - spin_unlock(&mm->page_table_lock); -} -EXPORT_SYMBOL_GPL(drop_cop); - -static int acop_use_cop(int ct) -{ - /* There is no alternate policy, yet */ - return -1; -} - -/* - * Get the instruction word at the NIP - */ -static u32 acop_get_inst(struct pt_regs *regs) -{ - u32 inst; - u32 __user *p; - - p = (u32 __user *)regs->nip; - if (!access_ok(VERIFY_READ, p, sizeof(*p))) - return 0; - - if (__get_user(inst, p)) - return 0; - - return inst; -} - -/** - * @regs: registers at time of interrupt - * @address: storage address - * @error_code: Fault code, usually the DSISR or ESR depending on - * processor type - * - * Return 0 if we are able to resolve the data storage fault that - * results from a CT miss in the ACOP register. - */ -int acop_handle_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) -{ - int ct; - u32 inst = 0; - - if (!cpu_has_feature(CPU_FTR_ICSWX)) { - pr_info("No coprocessors available"); - _exception(SIGILL, regs, ILL_ILLOPN, address); - } - - if (!user_mode(regs)) { - /* this could happen if the HV denies the - * kernel access, for now we just die */ - die("ICSWX from kernel failed", regs, SIGSEGV); - } - - /* Some implementations leave us a hint for the CT */ - ct = ICSWX_GET_CT_HINT(error_code); - if (ct < 0) { - /* we have to peek at the instruction word to figure out CT */ - u32 ccw; - u32 rs; - - inst = acop_get_inst(regs); - if (inst == 0) - return -1; - - rs = (inst >> (31 - 10)) & 0x1f; - ccw = regs->gpr[rs]; - ct = (ccw >> 16) & 0x3f; - } - - /* - * We could be here because another thread has enabled acop - * but the ACOP register has yet to be updated. - * - * This should have been taken care of by the IPI to sync all - * the threads (see smp_call_function(sync_cop, mm, 1)), but - * that could take forever if there are a significant amount - * of threads. - * - * Given the number of threads on some of these systems, - * perhaps this is the best way to sync ACOP rather than whack - * every thread with an IPI. - */ - if ((acop_copro_type_bit(ct) & current->active_mm->context.acop) != 0) { - sync_cop(current->active_mm); - return 0; - } - - /* check for alternate policy */ - if (!acop_use_cop(ct)) - return 0; - - /* at this point the CT is unknown to the system */ - pr_warn("%s[%d]: Coprocessor %d is unavailable\n", - current->comm, current->pid, ct); - - /* get inst if we don't already have it */ - if (inst == 0) { - inst = acop_get_inst(regs); - if (inst == 0) - return -1; - } - - /* Check if the instruction is the "record form" */ - if (inst & 1) { - /* - * the instruction is "record" form so we can reject - * using CR0 - */ - regs->ccr &= ~(0xful << 28); - regs->ccr |= ICSWX_RC_NOT_FOUND << 28; - - /* Move on to the next instruction */ - regs->nip += 4; - } else { - /* - * There is no architected mechanism to report a bad - * CT so we could either SIGILL or report nothing. - * Since the non-record version should only bu used - * for "hints" or "don't care" we should probably do - * nothing. However, I could see how some people - * might want an SIGILL so it here if you want it. - */ -#ifdef CONFIG_PPC_ICSWX_USE_SIGILL - _exception(SIGILL, regs, ILL_ILLOPN, address); -#else - regs->nip += 4; -#endif - } - - return 0; -} -EXPORT_SYMBOL_GPL(acop_handle_fault); diff --git a/arch/powerpc/mm/icswx.h b/arch/powerpc/mm/icswx.h deleted file mode 100644 index 6dedc08e62c874f26d5e57917b79d9bc5f507dae..0000000000000000000000000000000000000000 --- a/arch/powerpc/mm/icswx.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _ARCH_POWERPC_MM_ICSWX_H_ -#define _ARCH_POWERPC_MM_ICSWX_H_ - -/* - * ICSWX and ACOP Management - * - * Copyright (C) 2011 Anton Blanchard, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include - -/* also used to denote that PIDs are not used */ -#define COP_PID_NONE 0 - -static inline void sync_cop(void *arg) -{ - struct mm_struct *mm = arg; - - if (mm == current->active_mm) - switch_cop(current->active_mm); -} - -#ifdef CONFIG_PPC_ICSWX_PID -extern int get_cop_pid(struct mm_struct *mm); -extern int disable_cop_pid(struct mm_struct *mm); -extern void free_cop_pid(int free_pid); -#else -#define get_cop_pid(m) (COP_PID_NONE) -#define disable_cop_pid(m) (COP_PID_NONE) -#define free_cop_pid(p) -#endif - -/* - * These are implementation bits for architected registers. If this - * ever becomes architecture the should be moved to reg.h et. al. - */ -/* UCT is the same bit for Server and Embedded */ -#define ICSWX_DSI_UCT 0x00004000 /* Unavailable Coprocessor Type */ - -#ifdef CONFIG_PPC_BOOK3E -/* Embedded implementation gives us no hints as to what the CT is */ -#define ICSWX_GET_CT_HINT(x) (-1) -#else -/* Server implementation contains the CT value in the DSISR */ -#define ICSWX_DSISR_CTMASK 0x00003f00 -#define ICSWX_GET_CT_HINT(x) (((x) & ICSWX_DSISR_CTMASK) >> 8) -#endif - -#define ICSWX_RC_STARTED 0x8 /* The request has been started */ -#define ICSWX_RC_NOT_IDLE 0x4 /* No coprocessor found idle */ -#define ICSWX_RC_NOT_FOUND 0x2 /* No coprocessor found */ -#define ICSWX_RC_UNDEFINED 0x1 /* Reserved */ - -extern int acop_handle_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code); - -static inline u64 acop_copro_type_bit(unsigned int type) -{ - return 1ULL << (63 - type); -} - -#endif /* !_ARCH_POWERPC_MM_ICSWX_H_ */ diff --git a/arch/powerpc/mm/icswx_pid.c b/arch/powerpc/mm/icswx_pid.c deleted file mode 100644 index 91e30eb7d054e9cbb0ddf161df6dc27b3177beed..0000000000000000000000000000000000000000 --- a/arch/powerpc/mm/icswx_pid.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * ICSWX and ACOP/PID Management - * - * Copyright (C) 2011 Anton Blanchard, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "icswx.h" - -#define COP_PID_MIN (COP_PID_NONE + 1) -#define COP_PID_MAX (0xFFFF) - -static DEFINE_SPINLOCK(mmu_context_acop_lock); -static DEFINE_IDA(cop_ida); - -static int new_cop_pid(struct ida *ida, int min_id, int max_id, - spinlock_t *lock) -{ - int index; - int err; - -again: - if (!ida_pre_get(ida, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(lock); - err = ida_get_new_above(ida, min_id, &index); - spin_unlock(lock); - - if (err == -EAGAIN) - goto again; - else if (err) - return err; - - if (index > max_id) { - spin_lock(lock); - ida_remove(ida, index); - spin_unlock(lock); - return -ENOMEM; - } - - return index; -} - -int get_cop_pid(struct mm_struct *mm) -{ - int pid; - - if (mm->context.cop_pid == COP_PID_NONE) { - pid = new_cop_pid(&cop_ida, COP_PID_MIN, COP_PID_MAX, - &mmu_context_acop_lock); - if (pid >= 0) - mm->context.cop_pid = pid; - } - return mm->context.cop_pid; -} - -int disable_cop_pid(struct mm_struct *mm) -{ - int free_pid = COP_PID_NONE; - - if ((!mm->context.acop) && (mm->context.cop_pid != COP_PID_NONE)) { - free_pid = mm->context.cop_pid; - mm->context.cop_pid = COP_PID_NONE; - } - return free_pid; -} - -void free_cop_pid(int free_pid) -{ - spin_lock(&mmu_context_acop_lock); - ida_remove(&cop_ida, free_pid); - spin_unlock(&mmu_context_acop_lock); -} diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 8a7c38b8d335d733917962fbf0c2eaad31b982e4..6419b33ca3099f5d73ffcbb451bbd2f6b8a90401 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -113,6 +113,12 @@ void __init MMU_setup(void) __map_without_bats = 1; __map_without_ltlbs = 1; } +#ifdef CONFIG_STRICT_KERNEL_RWX + if (rodata_enabled) { + __map_without_bats = 1; + __map_without_ltlbs = 1; + } +#endif } /* @@ -132,8 +138,6 @@ void __init MMU_init(void) * Reserve gigantic pages for hugetlb. This MUST occur before * lowmem_end_addr is initialized below. */ - reserve_hugetlb_gpages(); - if (memblock.memory.cnt > 1) { #ifndef CONFIG_WII memblock_enforce_memory_limit(memblock.memory.regions[0].size); diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 5b4c25d12ff3564ed90628447c74c18ea570be86..588a521966ec1e098eb954fbb87a582a6599ad84 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -356,7 +356,7 @@ struct page *realmode_pfn_to_page(unsigned long pfn) } EXPORT_SYMBOL_GPL(realmode_pfn_to_page); -#elif defined(CONFIG_FLATMEM) +#else struct page *realmode_pfn_to_page(unsigned long pfn) { @@ -365,7 +365,7 @@ struct page *realmode_pfn_to_page(unsigned long pfn) } EXPORT_SYMBOL_GPL(realmode_pfn_to_page); -#endif /* CONFIG_SPARSEMEM_VMEMMAP/CONFIG_FLATMEM */ +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ #ifdef CONFIG_PPC_STD_MMU_64 static bool disable_radix; @@ -381,7 +381,7 @@ early_param("disable_radix", parse_disable_radix); * /chosen/ibm,architecture-vec-5 to see if the hypervisor is willing to do * radix. If not, we clear the radix feature bit so we fall back to hash. */ -static void early_check_vec5(void) +static void __init early_check_vec5(void) { unsigned long root, chosen; int size; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 46b4e67d2372328231b47c7e225af6d780fde022..4362b86ef84c5daa404e806cf3802128b77b8532 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -436,7 +436,7 @@ void flush_dcache_icache_page(struct page *page) return; } #endif -#if defined(CONFIG_8xx) || defined(CONFIG_PPC64) +#if defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC64) /* On 8xx there is no need to kmap since highmem is not supported */ __flush_dcache_icache(page_address(page)); #else diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c new file mode 100644 index 0000000000000000000000000000000000000000..0f613bc63c50f04a559dd25f5523c0a6a086fb69 --- /dev/null +++ b/arch/powerpc/mm/mmu_context.c @@ -0,0 +1,99 @@ +/* + * Common implementation of switch_mm_irqs_off + * + * Copyright IBM Corp. 2017 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include + +#include + +#if defined(CONFIG_PPC32) +static inline void switch_mm_pgdir(struct task_struct *tsk, + struct mm_struct *mm) +{ + /* 32-bit keeps track of the current PGDIR in the thread struct */ + tsk->thread.pgdir = mm->pgd; +} +#elif defined(CONFIG_PPC_BOOK3E_64) +static inline void switch_mm_pgdir(struct task_struct *tsk, + struct mm_struct *mm) +{ + /* 64-bit Book3E keeps track of current PGD in the PACA */ + get_paca()->pgd = mm->pgd; +} +#else +static inline void switch_mm_pgdir(struct task_struct *tsk, + struct mm_struct *mm) { } +#endif + +#ifdef CONFIG_PPC_BOOK3S_64 +static inline void inc_mm_active_cpus(struct mm_struct *mm) +{ + atomic_inc(&mm->context.active_cpus); +} +#else +static inline void inc_mm_active_cpus(struct mm_struct *mm) { } +#endif + +void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + bool new_on_cpu = false; + + /* Mark this context has been used on the new CPU */ + if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) { + cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); + inc_mm_active_cpus(next); + + /* + * This full barrier orders the store to the cpumask above vs + * a subsequent operation which allows this CPU to begin loading + * translations for next. + * + * When using the radix MMU that operation is the load of the + * MMU context id, which is then moved to SPRN_PID. + * + * For the hash MMU it is either the first load from slb_cache + * in switch_slb(), and/or the store of paca->mm_ctx_id in + * copy_mm_to_paca(). + * + * On the read side the barrier is in pte_xchg(), which orders + * the store to the PTE vs the load of mm_cpumask. + */ + smp_mb(); + + new_on_cpu = true; + } + + /* Some subarchs need to track the PGD elsewhere */ + switch_mm_pgdir(tsk, next); + + /* Nothing else to do if we aren't actually switching */ + if (prev == next) + return; + + /* + * We must stop all altivec streams before changing the HW + * context + */ + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + asm volatile ("dssall"); + + if (new_on_cpu) + radix_kvm_prefetch_workaround(next); + + /* + * The actual HW switching method differs between the various + * sub architectures. Out of line for now + */ + switch_mmu_context(prev, next, tsk); +} + diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index a75f63833284cbb089f67fa21bee0357426a2a88..05e15386d4cb356da7e5b320be4b92907c99500b 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c @@ -25,8 +25,6 @@ #include #include -#include "icswx.h" - static DEFINE_SPINLOCK(mmu_context_lock); static DEFINE_IDA(mmu_context_ida); @@ -165,16 +163,6 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) return index; mm->context.id = index; -#ifdef CONFIG_PPC_ICSWX - mm->context.cop_lockp = kmalloc(sizeof(spinlock_t), GFP_KERNEL); - if (!mm->context.cop_lockp) { - __destroy_context(index); - subpage_prot_free(mm); - mm->context.id = MMU_NO_CONTEXT; - return -ENOMEM; - } - spin_lock_init(mm->context.cop_lockp); -#endif /* CONFIG_PPC_ICSWX */ #ifdef CONFIG_PPC_64K_PAGES mm->context.pte_frag = NULL; @@ -182,6 +170,8 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) #ifdef CONFIG_SPAPR_TCE_IOMMU mm_iommu_init(mm); #endif + atomic_set(&mm->context.active_cpus, 0); + return 0; } @@ -226,12 +216,6 @@ void destroy_context(struct mm_struct *mm) #ifdef CONFIG_SPAPR_TCE_IOMMU WARN_ON_ONCE(!list_empty(&mm->context.iommu_group_mem_list)); #endif -#ifdef CONFIG_PPC_ICSWX - drop_cop(mm->context.acop, mm); - kfree(mm->context.cop_lockp); - mm->context.cop_lockp = NULL; -#endif /* CONFIG_PPC_ICSWX */ - if (radix_enabled()) { /* * Radix doesn't have a valid bit in the process table diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index d46128b221503f7ec5aa2b65c93d1e5d78707beb..57fbc554c78589f4e076ccfe647a2bb6ebd9011a 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -27,7 +27,7 @@ /* * On 40x and 8xx, we directly inline tlbia and tlbivax */ -#if defined(CONFIG_40x) || defined(CONFIG_8xx) +#if defined(CONFIG_40x) || defined(CONFIG_PPC_8xx) static inline void _tlbil_all(void) { asm volatile ("sync; tlbia; isync" : : : "memory"); @@ -38,7 +38,7 @@ static inline void _tlbil_pid(unsigned int pid) } #define _tlbil_pid_noind(pid) _tlbil_pid(pid) -#else /* CONFIG_40x || CONFIG_8xx */ +#else /* CONFIG_40x || CONFIG_PPC_8xx */ extern void _tlbil_all(void); extern void _tlbil_pid(unsigned int pid); #ifdef CONFIG_PPC_BOOK3E @@ -46,12 +46,12 @@ extern void _tlbil_pid_noind(unsigned int pid); #else #define _tlbil_pid_noind(pid) _tlbil_pid(pid) #endif -#endif /* !(CONFIG_40x || CONFIG_8xx) */ +#endif /* !(CONFIG_40x || CONFIG_PPC_8xx) */ /* * On 8xx, we directly inline tlbie, on others, it's extern */ -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx static inline void _tlbil_va(unsigned long address, unsigned int pid, unsigned int tsize, unsigned int ind) { @@ -67,7 +67,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid, { __tlbil_va(address, pid); } -#endif /* CONFIG_8xx */ +#endif /* CONFIG_PPC_8xx */ #if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x) extern void _tlbivax_bcast(unsigned long address, unsigned int pid, diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c index 31eed8fa8e991c0322e6b88112ce2ed974518f21..3b65917785a5789a771e6befc1c09d4c03d876de 100644 --- a/arch/powerpc/mm/pgtable-book3s64.c +++ b/arch/powerpc/mm/pgtable-book3s64.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -64,6 +65,27 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, trace_hugepage_set_pmd(addr, pmd_val(pmd)); return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); } + +static void do_nothing(void *unused) +{ + +} +/* + * Serialize against find_current_mm_pte which does lock-less + * lookup in page tables with local interrupts disabled. For huge pages + * it casts pmd_t to pte_t. Since format of pte_t is different from + * pmd_t we want to prevent transit from pmd pointing to page table + * to pmd pointing to huge page (and back) while interrupts are disabled. + * We clear pmd to possibly replace it with page table pointer in + * different code paths. So make sure we wait for the parallel + * find_current_mm_pte to finish. + */ +void serialize_against_pte_lookup(struct mm_struct *mm) +{ + smp_mb(); + smp_call_function_many(mm_cpumask(mm), do_nothing, NULL, 1); +} + /* * We use this to invalidate a pmdp entry before switching from a * hugepte to regular pmd entry. @@ -77,7 +99,7 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, * This ensures that generic code that rely on IRQ disabling * to prevent a parallel THP split work as expected. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(vma->vm_mm); } static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c index 443a2c66a30467d7bea260d6a7d01df19d55c33a..ec277913e01b4e06b1034531818b96c253004863 100644 --- a/arch/powerpc/mm/pgtable-hash64.c +++ b/arch/powerpc/mm/pgtable-hash64.c @@ -239,7 +239,7 @@ pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addres * by sending an IPI to all the cpus and executing a dummy * function there. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(vma->vm_mm); /* * Now invalidate the hpte entries in the range * covered by pmd. This make sure we take a @@ -329,7 +329,6 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, unsigned int psize; unsigned long vsid; unsigned long flags = 0; - const struct cpumask *tmp; /* get the base page size,vsid and segment size */ #ifdef CONFIG_DEBUG_VM @@ -350,8 +349,7 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, ssize = mmu_kernel_ssize; } - tmp = cpumask_of(smp_processor_id()); - if (cpumask_equal(mm_cpumask(mm), tmp)) + if (mm_is_thread_local(mm)) flags |= HPTE_LOCAL_UPDATE; return flush_hash_hugepage(vsid, addr, pmdp, psize, ssize, flags); @@ -380,16 +378,16 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, */ memset(pgtable, 0, PTE_FRAG_SIZE); /* - * Serialize against find_linux_pte_or_hugepte which does lock-less + * Serialize against find_current_mm_pte variants which does lock-less * lookup in page tables with local interrupts disabled. For huge pages * it casts pmd_t to pte_t. Since format of pte_t is different from * pmd_t we want to prevent transit from pmd pointing to page table * to pmd pointing to huge page (and back) while interrupts are disabled. * We clear pmd to possibly replace it with page table pointer in * different code paths. So make sure we wait for the parallel - * find_linux_pte_or_hugepage to finish. + * find_curren_mm_pte to finish. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(mm); return old_pmd; } diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c index 671a45d86c18dd7e174ffb909084cd0a37fcdaff..39c252b54d1618a35f24084a1a455652daab17a7 100644 --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c @@ -8,10 +8,15 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + +#define pr_fmt(fmt) "radix-mmu: " fmt + +#include #include #include #include #include +#include #include #include @@ -31,9 +36,13 @@ unsigned int mmu_base_pid; static int native_register_process_table(unsigned long base, unsigned long pg_sz, unsigned long table_size) { - unsigned long patb1 = base | table_size | PATB_GR; + unsigned long patb0, patb1; + + patb0 = be64_to_cpu(partition_tb[0].patb0); + patb1 = base | table_size | PATB_GR; + + mmu_partition_table_set_entry(0, patb0, patb1); - partition_tb->patb1 = cpu_to_be64(patb1); return 0; } @@ -179,10 +188,14 @@ static inline void __meminit print_mapping(unsigned long start, unsigned long end, unsigned long size) { + char buf[10]; + if (end <= start) return; - pr_info("Mapped range 0x%lx - 0x%lx with 0x%lx\n", start, end, size); + string_get_size(size, 1, STRING_UNITS_2, buf, sizeof(buf)); + + pr_info("Mapped 0x%016lx-0x%016lx with %s pages\n", start, end, buf); } static int __meminit create_physical_mapping(unsigned long start, @@ -526,6 +539,7 @@ void __init radix__early_init_mmu(void) __kernel_virt_size = RADIX_KERN_VIRT_SIZE; __vmalloc_start = RADIX_VMALLOC_START; __vmalloc_end = RADIX_VMALLOC_END; + __kernel_io_start = RADIX_KERN_IO_START; vmemmap = (struct page *)RADIX_VMEMMAP_BASE; ioremap_bot = IOREMAP_BASE; @@ -836,9 +850,12 @@ pmd_t radix__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addre */ pmd = *pmdp; pmd_clear(pmdp); + /*FIXME!! Verify whether we need this kick below */ - kick_all_cpus_sync(); - flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); + serialize_against_pte_lookup(vma->vm_mm); + + radix__flush_tlb_collapsed_pmd(vma->vm_mm, address); + return pmd; } @@ -897,16 +914,16 @@ pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm, old = radix__pmd_hugepage_update(mm, addr, pmdp, ~0UL, 0); old_pmd = __pmd(old); /* - * Serialize against find_linux_pte_or_hugepte which does lock-less + * Serialize against find_current_mm_pte which does lock-less * lookup in page tables with local interrupts disabled. For huge pages * it casts pmd_t to pte_t. Since format of pte_t is different from * pmd_t we want to prevent transit from pmd pointing to page table * to pmd pointing to huge page (and back) while interrupts are disabled. * We clear pmd to possibly replace it with page table pointer in * different code paths. So make sure we wait for the parallel - * find_linux_pte_or_hugepage to finish. + * find_current_mm_pte to finish. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(mm); return old_pmd; } diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index a9e4bfc025bc9cdbff6cc57fa275709a0a102269..f6c7f54c05157e226c5426798b6fa0f379f8becb 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "mmu_decl.h" @@ -242,7 +243,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, int flags) /* * Map in a chunk of physical memory starting at start. */ -void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) +static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) { unsigned long v, s, f; phys_addr_t p; @@ -294,7 +295,7 @@ void __init mapin_ram(void) * Returns true (1) if PTE was found, zero otherwise. The pointer to * the PTE pointer is unmodified if PTE is not found. */ -int +static int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) { pgd_t *pgd; @@ -323,9 +324,7 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) return(retval); } -#ifdef CONFIG_DEBUG_PAGEALLOC - -static int __change_page_attr(struct page *page, pgprot_t prot) +static int __change_page_attr_noflush(struct page *page, pgprot_t prot) { pte_t *kpte; pmd_t *kpmd; @@ -339,8 +338,6 @@ static int __change_page_attr(struct page *page, pgprot_t prot) if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) return -EINVAL; __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); - wmb(); - flush_tlb_page(NULL, address); pte_unmap(kpte); return 0; @@ -349,44 +346,65 @@ static int __change_page_attr(struct page *page, pgprot_t prot) /* * Change the page attributes of an page in the linear mapping. * - * THIS CONFLICTS WITH BAT MAPPINGS, DEBUG USE ONLY + * THIS DOES NOTHING WITH BAT MAPPINGS, DEBUG USE ONLY */ static int change_page_attr(struct page *page, int numpages, pgprot_t prot) { int i, err = 0; unsigned long flags; + struct page *start = page; local_irq_save(flags); for (i = 0; i < numpages; i++, page++) { - err = __change_page_attr(page, prot); + err = __change_page_attr_noflush(page, prot); if (err) break; } + wmb(); local_irq_restore(flags); + flush_tlb_kernel_range((unsigned long)page_address(start), + (unsigned long)page_address(page)); return err; } - -void __kernel_map_pages(struct page *page, int numpages, int enable) +void mark_initmem_nx(void) { - if (PageHighMem(page)) - return; + struct page *page = virt_to_page(_sinittext); + unsigned long numpages = PFN_UP((unsigned long)_einittext) - + PFN_DOWN((unsigned long)_sinittext); - change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); + change_page_attr(page, numpages, PAGE_KERNEL); } -#endif /* CONFIG_DEBUG_PAGEALLOC */ -static int fixmaps; - -void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) +#ifdef CONFIG_STRICT_KERNEL_RWX +void mark_rodata_ro(void) { - unsigned long address = __fix_to_virt(idx); + struct page *page; + unsigned long numpages; + + page = virt_to_page(_stext); + numpages = PFN_UP((unsigned long)_etext) - + PFN_DOWN((unsigned long)_stext); - if (idx >= __end_of_fixed_addresses) { - BUG(); + change_page_attr(page, numpages, PAGE_KERNEL_ROX); + /* + * mark .rodata as read only. Use __init_begin rather than __end_rodata + * to cover NOTES and EXCEPTION_TABLE. + */ + page = virt_to_page(__start_rodata); + numpages = PFN_UP((unsigned long)__init_begin) - + PFN_DOWN((unsigned long)__start_rodata); + + change_page_attr(page, numpages, PAGE_KERNEL_RO); +} +#endif + +#ifdef CONFIG_DEBUG_PAGEALLOC +void __kernel_map_pages(struct page *page, int numpages, int enable) +{ + if (PageHighMem(page)) return; - } - map_kernel_page(address, phys, pgprot_val(flags)); - fixmaps++; + change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); } +#endif /* CONFIG_DEBUG_PAGEALLOC */ diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 0736e94c7615a67b2efd8bd39e237bb757a8e74c..ac0717a90ca6bd7be1a9071666e61c4e78782ceb 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -104,6 +104,8 @@ unsigned long __vmalloc_start; EXPORT_SYMBOL(__vmalloc_start); unsigned long __vmalloc_end; EXPORT_SYMBOL(__vmalloc_end); +unsigned long __kernel_io_start; +EXPORT_SYMBOL(__kernel_io_start); struct page *vmemmap; EXPORT_SYMBOL(vmemmap); unsigned long __pte_frag_nr; diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index bde378559d0159add6e963178edd6ef186d04c70..906a86fe457bb392b4899b78e76804a745c08558 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S @@ -121,12 +121,25 @@ slb_miss_kernel_load_vmemmap: 1: #endif /* CONFIG_SPARSEMEM_VMEMMAP */ - /* vmalloc mapping gets the encoding from the PACA as the mapping - * can be demoted from 64K -> 4K dynamically on some machines + /* + * r10 contains the ESID, which is the original faulting EA shifted + * right by 28 bits. We need to compare that with (H_VMALLOC_END >> 28) + * which is 0xd00038000. That can't be used as an immediate, even if we + * ignored the 0xd, so we have to load it into a register, and we only + * have one register free. So we must load all of (H_VMALLOC_END >> 28) + * into a register and compare ESID against that. + */ + lis r11,(H_VMALLOC_END >> 32)@h // r11 = 0xffffffffd0000000 + ori r11,r11,(H_VMALLOC_END >> 32)@l // r11 = 0xffffffffd0003800 + // Rotate left 4, then mask with 0xffffffff0 + rldic r11,r11,4,28 // r11 = 0xd00038000 + cmpld r10,r11 // if r10 >= r11 + bge 5f // goto io_mapping + + /* + * vmalloc mapping gets the encoding from the PACA as the mapping + * can be demoted from 64K -> 4K dynamically on some machines. */ - clrldi r11,r10,48 - cmpldi r11,(H_VMALLOC_SIZE >> 28) - 1 - bgt 5f lhz r11,PACAVMALLOCSLLP(r13) b 6f 5: diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c index 16ae1bbe13f09e588919f8aa55a81ed575290360..b3e849c4886e66c883451a59fe603e04132c00c0 100644 --- a/arch/powerpc/mm/tlb-radix.c +++ b/arch/powerpc/mm/tlb-radix.c @@ -54,23 +54,15 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) */ __tlbiel_pid(pid, 0, ric); - if (ric == RIC_FLUSH_ALL) - /* For the remaining sets, just flush the TLB */ - ric = RIC_FLUSH_TLB; + /* For PWC, only one flush is needed */ + if (ric == RIC_FLUSH_PWC) { + asm volatile("ptesync": : :"memory"); + return; + } + /* For the remaining sets, just flush the TLB */ for (set = 1; set < POWER9_TLB_SETS_RADIX ; set++) - __tlbiel_pid(pid, set, ric); - - asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); -} - -static inline void tlbiel_pwc(unsigned long pid) -{ - asm volatile("ptesync": : :"memory"); - - /* For PWC flush, we don't look at set number */ - __tlbiel_pid(pid, 0, RIC_FLUSH_PWC); + __tlbiel_pid(pid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); @@ -146,31 +138,23 @@ void radix__local_flush_tlb_mm(struct mm_struct *mm) preempt_disable(); pid = mm->context.id; if (pid != MMU_NO_CONTEXT) - _tlbiel_pid(pid, RIC_FLUSH_ALL); + _tlbiel_pid(pid, RIC_FLUSH_TLB); preempt_enable(); } EXPORT_SYMBOL(radix__local_flush_tlb_mm); -void radix__local_flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) +#ifndef CONFIG_SMP +static void radix__local_flush_all_mm(struct mm_struct *mm) { unsigned long pid; - struct mm_struct *mm = tlb->mm; - /* - * If we are doing a full mm flush, we will do a tlb flush - * with RIC_FLUSH_ALL later. - */ - if (tlb->fullmm) - return; preempt_disable(); - pid = mm->context.id; if (pid != MMU_NO_CONTEXT) - tlbiel_pwc(pid); - + _tlbiel_pid(pid, RIC_FLUSH_ALL); preempt_enable(); } -EXPORT_SYMBOL(radix__local_flush_tlb_pwc); +#endif /* CONFIG_SMP */ void radix__local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize) @@ -208,38 +192,35 @@ void radix__flush_tlb_mm(struct mm_struct *mm) goto no_context; if (!mm_is_thread_local(mm)) - _tlbie_pid(pid, RIC_FLUSH_ALL); + _tlbie_pid(pid, RIC_FLUSH_TLB); else - _tlbiel_pid(pid, RIC_FLUSH_ALL); + _tlbiel_pid(pid, RIC_FLUSH_TLB); no_context: preempt_enable(); } EXPORT_SYMBOL(radix__flush_tlb_mm); -void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) +static void radix__flush_all_mm(struct mm_struct *mm) { unsigned long pid; - struct mm_struct *mm = tlb->mm; - /* - * If we are doing a full mm flush, we will do a tlb flush - * with RIC_FLUSH_ALL later. - */ - if (tlb->fullmm) - return; preempt_disable(); - pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) goto no_context; if (!mm_is_thread_local(mm)) - _tlbie_pid(pid, RIC_FLUSH_PWC); + _tlbie_pid(pid, RIC_FLUSH_ALL); else - tlbiel_pwc(pid); + _tlbiel_pid(pid, RIC_FLUSH_ALL); no_context: preempt_enable(); } + +void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) +{ + tlb->need_flush_all = 1; +} EXPORT_SYMBOL(radix__flush_tlb_pwc); void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, @@ -271,6 +252,8 @@ void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) } EXPORT_SYMBOL(radix__flush_tlb_page); +#else /* CONFIG_SMP */ +#define radix__flush_all_mm radix__local_flush_all_mm #endif /* CONFIG_SMP */ void radix__flush_tlb_kernel_range(unsigned long start, unsigned long end) @@ -288,6 +271,7 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start, { struct mm_struct *mm = vma->vm_mm; + radix__flush_tlb_mm(mm); } EXPORT_SYMBOL(radix__flush_tlb_range); @@ -319,7 +303,10 @@ void radix__tlb_flush(struct mmu_gather *tlb) */ if (psize != -1 && !tlb->fullmm && !tlb->need_flush_all) radix__flush_tlb_range_psize(mm, tlb->start, tlb->end, psize); - else + else if (tlb->need_flush_all) { + tlb->need_flush_all = 0; + radix__flush_all_mm(mm); + } else radix__flush_tlb_mm(mm); } @@ -364,6 +351,43 @@ void radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start, preempt_enable(); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr) +{ + int local = mm_is_thread_local(mm); + unsigned long ap = mmu_get_ap(mmu_virtual_psize); + unsigned long pid, end; + + + pid = mm ? mm->context.id : 0; + if (unlikely(pid == MMU_NO_CONTEXT)) + goto no_context; + + /* 4k page size, just blow the world */ + if (PAGE_SIZE == 0x1000) { + radix__flush_all_mm(mm); + return; + } + + /* Otherwise first do the PWC */ + if (local) + _tlbiel_pid(pid, RIC_FLUSH_PWC); + else + _tlbie_pid(pid, RIC_FLUSH_PWC); + + /* Then iterate the pages */ + end = addr + HPAGE_PMD_SIZE; + for (; addr < end; addr += PAGE_SIZE) { + if (local) + _tlbiel_va(addr, pid, ap, RIC_FLUSH_TLB); + else + _tlbie_va(addr, pid, ap, RIC_FLUSH_TLB); + } +no_context: + preempt_enable(); +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa, unsigned long page_size) { diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c index b5b0fb97b9c03c4e8bfa5ab71a3b153353aa2314..881ebd53ffc27c8840ae57b088c4d247ba7ef191 100644 --- a/arch/powerpc/mm/tlb_hash64.c +++ b/arch/powerpc/mm/tlb_hash64.c @@ -29,6 +29,8 @@ #include #include #include +#include + #include @@ -138,13 +140,10 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, */ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) { - const struct cpumask *tmp; - int i, local = 0; + int i, local; i = batch->index; - tmp = cpumask_of(smp_processor_id()); - if (cpumask_equal(mm_cpumask(batch->mm), tmp)) - local = 1; + local = mm_is_thread_local(batch->mm); if (i == 1) flush_hash_page(batch->vpn[0], batch->pte[0], batch->psize, batch->ssize, local); @@ -207,8 +206,8 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, local_irq_save(flags); arch_enter_lazy_mmu_mode(); for (; start < end; start += PAGE_SIZE) { - pte_t *ptep = find_linux_pte_or_hugepte(mm->pgd, start, &is_thp, - &hugepage_shift); + pte_t *ptep = find_current_mm_pte(mm->pgd, start, &is_thp, + &hugepage_shift); unsigned long pte; if (ptep == NULL) diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index eabecfcaef7cf0503c125535619a9fcc6acbcf86..048b8e9f44928ebbe3d9892ae8f7154d56ff1954 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -60,7 +60,7 @@ _GLOBAL(__tlbil_va) isync 1: blr -#elif defined(CONFIG_8xx) +#elif defined(CONFIG_PPC_8xx) /* * Nothing to do for 8xx, everything is inline diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 30cf03f534280b9c956f5c78aab02ae4223c1061..47fc6660845d3735545efc718ae013ee3c1609a8 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -263,6 +263,7 @@ static inline bool is_nearbranch(int offset) #define COND_EQ (CR0_EQ | COND_CMP_TRUE) #define COND_NE (CR0_EQ | COND_CMP_FALSE) #define COND_LT (CR0_LT | COND_CMP_TRUE) +#define COND_LE (CR0_GT | COND_CMP_FALSE) #endif diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index 861c5af1c9c4bdd85dba552b2e41a9587162e3a7..a66e64b0b251f7853722333ba3559ff556ceabc4 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -25,11 +25,7 @@ int bpf_jit_enable __read_mostly; static void bpf_jit_fill_ill_insns(void *area, unsigned int size) { - int *p = area; - - /* Fill whole space with trap instructions */ - while (p < (int *)((char *)area + size)) - *p++ = BREAKPOINT_INSTRUCTION; + memset32(area, BREAKPOINT_INSTRUCTION, size/4); } static inline void bpf_flush_icache(void *start, void *end) @@ -795,12 +791,24 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, case BPF_JMP | BPF_JSGT | BPF_X: true_cond = COND_GT; goto cond_branch; + case BPF_JMP | BPF_JLT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_X: + true_cond = COND_LT; + goto cond_branch; case BPF_JMP | BPF_JGE | BPF_K: case BPF_JMP | BPF_JGE | BPF_X: case BPF_JMP | BPF_JSGE | BPF_K: case BPF_JMP | BPF_JSGE | BPF_X: true_cond = COND_GE; goto cond_branch; + case BPF_JMP | BPF_JLE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_X: + true_cond = COND_LE; + goto cond_branch; case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JEQ | BPF_X: true_cond = COND_EQ; @@ -817,14 +825,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, cond_branch: switch (code) { case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JNE | BPF_X: /* unsigned comparison */ PPC_CMPLD(dst_reg, src_reg); break; case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: /* signed comparison */ PPC_CMPD(dst_reg, src_reg); break; @@ -834,7 +846,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: /* * Need sign-extended load, so only positive * values can be used as imm in cmpldi @@ -849,7 +863,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, } break; case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: /* * signed comparison, so any 16-bit value * can be used in cmpdi diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index 4d606b99a5cb94302a0a40d5ee2bb84d3319c6ba..3f3a5ce664952f16c7a6361348dfecb84d1e04f8 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -8,6 +8,7 @@ obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ isa207-common.o power8-pmu.o power9-pmu.o obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o +obj-$(CONFIG_PPC_POWERNV) += imc-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c index 0fc26714780acd95e3df8043c4a764d1e823aefc..0af051a1974e0e1151eb3964c327dc5ee8967c7d 100644 --- a/arch/powerpc/perf/callchain.c +++ b/arch/powerpc/perf/callchain.c @@ -22,6 +22,7 @@ #ifdef CONFIG_PPC64 #include "../kernel/ppc32.h" #endif +#include /* @@ -127,7 +128,7 @@ static int read_user_stack_slow(void __user *ptr, void *buf, int nb) return -EFAULT; local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(pgdir, addr, NULL, &shift); + ptep = find_current_mm_pte(pgdir, addr, NULL, &shift); if (!ptep) goto err_out; if (!shift) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 6c2d4168daec9a426ff2d9d5fb622fe3338dc836..9e3da168d54cdcd36e3911ff040ff2ad187c92b7 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -793,6 +793,11 @@ void perf_event_print_debug(void) u32 pmcs[MAX_HWEVENTS]; int i; + if (!ppmu) { + pr_info("Performance monitor hardware not registered.\n"); + return; + } + if (!ppmu->n_counter) return; @@ -2039,7 +2044,8 @@ static void record_and_restart(struct perf_event *event, unsigned long val, perf_sample_data_init(&data, ~0ULL, event->hw.last_period); - if (event->attr.sample_type & PERF_SAMPLE_ADDR) + if (event->attr.sample_type & + (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) perf_get_data_addr(regs, &data.addr); if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) { diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c new file mode 100644 index 0000000000000000000000000000000000000000..9ccac86f346385eaa624930f3050cdae62b6b09d --- /dev/null +++ b/arch/powerpc/perf/imc-pmu.c @@ -0,0 +1,1306 @@ +/* + * In-Memory Collection (IMC) Performance Monitor counter support. + * + * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation. + * (C) 2017 Anju T Sudhakar, IBM Corporation. + * (C) 2017 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or later version. + */ +#include +#include +#include +#include +#include +#include +#include + +/* Nest IMC data structures and variables */ + +/* + * Used to avoid races in counting the nest-pmu units during hotplug + * register and unregister + */ +static DEFINE_MUTEX(nest_init_lock); +static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc); +static struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +static cpumask_t nest_imc_cpumask; +struct imc_pmu_ref *nest_imc_refc; +static int nest_pmus; + +/* Core IMC data structures and variables */ + +static cpumask_t core_imc_cpumask; +struct imc_pmu_ref *core_imc_refc; +static struct imc_pmu *core_imc_pmu; + +/* Thread IMC data structures and variables */ + +static DEFINE_PER_CPU(u64 *, thread_imc_mem); +static struct imc_pmu *thread_imc_pmu; +static int thread_imc_mem_size; + +struct imc_pmu *imc_event_to_pmu(struct perf_event *event) +{ + return container_of(event->pmu, struct imc_pmu, pmu); +} + +PMU_FORMAT_ATTR(event, "config:0-40"); +PMU_FORMAT_ATTR(offset, "config:0-31"); +PMU_FORMAT_ATTR(rvalue, "config:32"); +PMU_FORMAT_ATTR(mode, "config:33-40"); +static struct attribute *imc_format_attrs[] = { + &format_attr_event.attr, + &format_attr_offset.attr, + &format_attr_rvalue.attr, + &format_attr_mode.attr, + NULL, +}; + +static struct attribute_group imc_format_group = { + .name = "format", + .attrs = imc_format_attrs, +}; + +/* Get the cpumask printed to a buffer "buf" */ +static ssize_t imc_pmu_cpumask_get_attr(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct imc_pmu *imc_pmu = container_of(pmu, struct imc_pmu, pmu); + cpumask_t *active_mask; + + switch(imc_pmu->domain){ + case IMC_DOMAIN_NEST: + active_mask = &nest_imc_cpumask; + break; + case IMC_DOMAIN_CORE: + active_mask = &core_imc_cpumask; + break; + default: + return 0; + } + + return cpumap_print_to_pagebuf(true, buf, active_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL); + +static struct attribute *imc_pmu_cpumask_attrs[] = { + &dev_attr_cpumask.attr, + NULL, +}; + +static struct attribute_group imc_pmu_cpumask_attr_group = { + .attrs = imc_pmu_cpumask_attrs, +}; + +/* device_str_attr_create : Populate event "name" and string "str" in attribute */ +static struct attribute *device_str_attr_create(const char *name, const char *str) +{ + struct perf_pmu_events_attr *attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) + return NULL; + sysfs_attr_init(&attr->attr.attr); + + attr->event_str = str; + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = perf_event_sysfs_show; + + return &attr->attr.attr; +} + +struct imc_events *imc_parse_event(struct device_node *np, const char *scale, + const char *unit, const char *prefix, u32 base) +{ + struct imc_events *event; + const char *s; + u32 reg; + + event = kzalloc(sizeof(struct imc_events), GFP_KERNEL); + if (!event) + return NULL; + + if (of_property_read_u32(np, "reg", ®)) + goto error; + /* Add the base_reg value to the "reg" */ + event->value = base + reg; + + if (of_property_read_string(np, "event-name", &s)) + goto error; + + event->name = kasprintf(GFP_KERNEL, "%s%s", prefix, s); + if (!event->name) + goto error; + + if (of_property_read_string(np, "scale", &s)) + s = scale; + + if (s) { + event->scale = kstrdup(s, GFP_KERNEL); + if (!event->scale) + goto error; + } + + if (of_property_read_string(np, "unit", &s)) + s = unit; + + if (s) { + event->unit = kstrdup(s, GFP_KERNEL); + if (!event->unit) + goto error; + } + + return event; +error: + kfree(event->unit); + kfree(event->scale); + kfree(event->name); + kfree(event); + + return NULL; +} + +/* + * update_events_in_group: Update the "events" information in an attr_group + * and assign the attr_group to the pmu "pmu". + */ +static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) +{ + struct attribute_group *attr_group; + struct attribute **attrs, *dev_str; + struct device_node *np, *pmu_events; + struct imc_events *ev; + u32 handle, base_reg; + int i=0, j=0, ct; + const char *prefix, *g_scale, *g_unit; + const char *ev_val_str, *ev_scale_str, *ev_unit_str; + + if (!of_property_read_u32(node, "events", &handle)) + pmu_events = of_find_node_by_phandle(handle); + else + return 0; + + /* Did not find any node with a given phandle */ + if (!pmu_events) + return 0; + + /* Get a count of number of child nodes */ + ct = of_get_child_count(pmu_events); + + /* Get the event prefix */ + if (of_property_read_string(node, "events-prefix", &prefix)) + return 0; + + /* Get a global unit and scale data if available */ + if (of_property_read_string(node, "scale", &g_scale)) + g_scale = NULL; + + if (of_property_read_string(node, "unit", &g_unit)) + g_unit = NULL; + + /* "reg" property gives out the base offset of the counters data */ + of_property_read_u32(node, "reg", &base_reg); + + /* Allocate memory for the events */ + pmu->events = kcalloc(ct, sizeof(struct imc_events), GFP_KERNEL); + if (!pmu->events) + return -ENOMEM; + + ct = 0; + /* Parse the events and update the struct */ + for_each_child_of_node(pmu_events, np) { + ev = imc_parse_event(np, g_scale, g_unit, prefix, base_reg); + if (ev) + pmu->events[ct++] = ev; + } + + /* Allocate memory for attribute group */ + attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + if (!attr_group) + return -ENOMEM; + + /* + * Allocate memory for attributes. + * Since we have count of events for this pmu, we also allocate + * memory for the scale and unit attribute for now. + * "ct" has the total event structs added from the events-parent node. + * So allocate three times the "ct" (this includes event, event_scale and + * event_unit). + */ + attrs = kcalloc(((ct * 3) + 1), sizeof(struct attribute *), GFP_KERNEL); + if (!attrs) { + kfree(attr_group); + kfree(pmu->events); + return -ENOMEM; + } + + attr_group->name = "events"; + attr_group->attrs = attrs; + do { + ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i]->value); + dev_str = device_str_attr_create(pmu->events[i]->name, ev_val_str); + if (!dev_str) + continue; + + attrs[j++] = dev_str; + if (pmu->events[i]->scale) { + ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale",pmu->events[i]->name); + dev_str = device_str_attr_create(ev_scale_str, pmu->events[i]->scale); + if (!dev_str) + continue; + + attrs[j++] = dev_str; + } + + if (pmu->events[i]->unit) { + ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit",pmu->events[i]->name); + dev_str = device_str_attr_create(ev_unit_str, pmu->events[i]->unit); + if (!dev_str) + continue; + + attrs[j++] = dev_str; + } + } while (++i < ct); + + /* Save the event attribute */ + pmu->attr_groups[IMC_EVENT_ATTR] = attr_group; + + kfree(pmu->events); + return 0; +} + +/* get_nest_pmu_ref: Return the imc_pmu_ref struct for the given node */ +static struct imc_pmu_ref *get_nest_pmu_ref(int cpu) +{ + return per_cpu(local_nest_imc_refc, cpu); +} + +static void nest_change_cpu_context(int old_cpu, int new_cpu) +{ + struct imc_pmu **pn = per_nest_pmu_arr; + int i; + + if (old_cpu < 0 || new_cpu < 0) + return; + + for (i = 0; *pn && i < IMC_MAX_PMUS; i++, pn++) + perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu); +} + +static int ppc_nest_imc_cpu_offline(unsigned int cpu) +{ + int nid, target = -1; + const struct cpumask *l_cpumask; + struct imc_pmu_ref *ref; + + /* + * Check in the designated list for this cpu. Dont bother + * if not one of them. + */ + if (!cpumask_test_and_clear_cpu(cpu, &nest_imc_cpumask)) + return 0; + + /* + * Now that this cpu is one of the designated, + * find a next cpu a) which is online and b) in same chip. + */ + nid = cpu_to_node(cpu); + l_cpumask = cpumask_of_node(nid); + target = cpumask_any_but(l_cpumask, cpu); + + /* + * Update the cpumask with the target cpu and + * migrate the context if needed + */ + if (target >= 0 && target < nr_cpu_ids) { + cpumask_set_cpu(target, &nest_imc_cpumask); + nest_change_cpu_context(cpu, target); + } else { + opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(cpu)); + /* + * If this is the last cpu in this chip then, skip the reference + * count mutex lock and make the reference count on this chip zero. + */ + ref = get_nest_pmu_ref(cpu); + if (!ref) + return -EINVAL; + + ref->refc = 0; + } + return 0; +} + +static int ppc_nest_imc_cpu_online(unsigned int cpu) +{ + const struct cpumask *l_cpumask; + static struct cpumask tmp_mask; + int res; + + /* Get the cpumask of this node */ + l_cpumask = cpumask_of_node(cpu_to_node(cpu)); + + /* + * If this is not the first online CPU on this node, then + * just return. + */ + if (cpumask_and(&tmp_mask, l_cpumask, &nest_imc_cpumask)) + return 0; + + /* + * If this is the first online cpu on this node + * disable the nest counters by making an OPAL call. + */ + res = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(cpu)); + if (res) + return res; + + /* Make this CPU the designated target for counter collection */ + cpumask_set_cpu(cpu, &nest_imc_cpumask); + return 0; +} + +static int nest_pmu_cpumask_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE, + "perf/powerpc/imc:online", + ppc_nest_imc_cpu_online, + ppc_nest_imc_cpu_offline); +} + +static void nest_imc_counters_release(struct perf_event *event) +{ + int rc, node_id; + struct imc_pmu_ref *ref; + + if (event->cpu < 0) + return; + + node_id = cpu_to_node(event->cpu); + + /* + * See if we need to disable the nest PMU. + * If no events are currently in use, then we have to take a + * mutex to ensure that we don't race with another task doing + * enable or disable the nest counters. + */ + ref = get_nest_pmu_ref(event->cpu); + if (!ref) + return; + + /* Take the mutex lock for this node and then decrement the reference count */ + mutex_lock(&ref->lock); + ref->refc--; + if (ref->refc == 0) { + rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("nest-imc: Unable to stop the counters for core %d\n", node_id); + return; + } + } else if (ref->refc < 0) { + WARN(1, "nest-imc: Invalid event reference count\n"); + ref->refc = 0; + } + mutex_unlock(&ref->lock); +} + +static int nest_imc_event_init(struct perf_event *event) +{ + int chip_id, rc, node_id; + u32 l_config, config = event->attr.config; + struct imc_mem_info *pcni; + struct imc_pmu *pmu; + struct imc_pmu_ref *ref; + bool flag = false; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + pmu = imc_event_to_pmu(event); + + /* Sanity check for config (event offset) */ + if ((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size) + return -EINVAL; + + /* + * Nest HW counter memory resides in a per-chip reserve-memory (HOMER). + * Get the base memory addresss for this cpu. + */ + chip_id = topology_physical_package_id(event->cpu); + pcni = pmu->mem_info; + do { + if (pcni->id == chip_id) { + flag = true; + break; + } + pcni++; + } while (pcni); + + if (!flag) + return -ENODEV; + + /* + * Add the event offset to the base address. + */ + l_config = config & IMC_EVENT_OFFSET_MASK; + event->hw.event_base = (u64)pcni->vbase + l_config; + node_id = cpu_to_node(event->cpu); + + /* + * Get the imc_pmu_ref struct for this node. + * Take the mutex lock and then increment the count of nest pmu events + * inited. + */ + ref = get_nest_pmu_ref(event->cpu); + if (!ref) + return -EINVAL; + + mutex_lock(&ref->lock); + if (ref->refc == 0) { + rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("nest-imc: Unable to start the counters for node %d\n", + node_id); + return rc; + } + } + ++ref->refc; + mutex_unlock(&ref->lock); + + event->destroy = nest_imc_counters_release; + return 0; +} + +/* + * core_imc_mem_init : Initializes memory for the current core. + * + * Uses alloc_pages_node() and uses the returned address as an argument to + * an opal call to configure the pdbar. The address sent as an argument is + * converted to physical address before the opal call is made. This is the + * base address at which the core imc counters are populated. + */ +static int core_imc_mem_init(int cpu, int size) +{ + int phys_id, rc = 0, core_id = (cpu / threads_per_core); + struct imc_mem_info *mem_info; + + /* + * alloc_pages_node() will allocate memory for core in the + * local node only. + */ + phys_id = topology_physical_package_id(cpu); + mem_info = &core_imc_pmu->mem_info[core_id]; + mem_info->id = core_id; + + /* We need only vbase for core counters */ + mem_info->vbase = page_address(alloc_pages_node(phys_id, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, + get_order(size))); + if (!mem_info->vbase) + return -ENOMEM; + + /* Init the mutex */ + core_imc_refc[core_id].id = core_id; + mutex_init(&core_imc_refc[core_id].lock); + + rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE, + __pa((void *)mem_info->vbase), + get_hard_smp_processor_id(cpu)); + if (rc) { + free_pages((u64)mem_info->vbase, get_order(size)); + mem_info->vbase = NULL; + } + + return rc; +} + +static bool is_core_imc_mem_inited(int cpu) +{ + struct imc_mem_info *mem_info; + int core_id = (cpu / threads_per_core); + + mem_info = &core_imc_pmu->mem_info[core_id]; + if (!mem_info->vbase) + return false; + + return true; +} + +static int ppc_core_imc_cpu_online(unsigned int cpu) +{ + const struct cpumask *l_cpumask; + static struct cpumask tmp_mask; + int ret = 0; + + /* Get the cpumask for this core */ + l_cpumask = cpu_sibling_mask(cpu); + + /* If a cpu for this core is already set, then, don't do anything */ + if (cpumask_and(&tmp_mask, l_cpumask, &core_imc_cpumask)) + return 0; + + if (!is_core_imc_mem_inited(cpu)) { + ret = core_imc_mem_init(cpu, core_imc_pmu->counter_mem_size); + if (ret) { + pr_info("core_imc memory allocation for cpu %d failed\n", cpu); + return ret; + } + } + + /* set the cpu in the mask */ + cpumask_set_cpu(cpu, &core_imc_cpumask); + return 0; +} + +static int ppc_core_imc_cpu_offline(unsigned int cpu) +{ + unsigned int ncpu, core_id; + struct imc_pmu_ref *ref; + + /* + * clear this cpu out of the mask, if not present in the mask, + * don't bother doing anything. + */ + if (!cpumask_test_and_clear_cpu(cpu, &core_imc_cpumask)) + return 0; + + /* Find any online cpu in that core except the current "cpu" */ + ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu); + + if (ncpu >= 0 && ncpu < nr_cpu_ids) { + cpumask_set_cpu(ncpu, &core_imc_cpumask); + perf_pmu_migrate_context(&core_imc_pmu->pmu, cpu, ncpu); + } else { + /* + * If this is the last cpu in this core then, skip taking refernce + * count mutex lock for this core and directly zero "refc" for + * this core. + */ + opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(cpu)); + core_id = cpu / threads_per_core; + ref = &core_imc_refc[core_id]; + if (!ref) + return -EINVAL; + + ref->refc = 0; + } + return 0; +} + +static int core_imc_pmu_cpumask_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE, + "perf/powerpc/imc_core:online", + ppc_core_imc_cpu_online, + ppc_core_imc_cpu_offline); +} + +static void core_imc_counters_release(struct perf_event *event) +{ + int rc, core_id; + struct imc_pmu_ref *ref; + + if (event->cpu < 0) + return; + /* + * See if we need to disable the IMC PMU. + * If no events are currently in use, then we have to take a + * mutex to ensure that we don't race with another task doing + * enable or disable the core counters. + */ + core_id = event->cpu / threads_per_core; + + /* Take the mutex lock and decrement the refernce count for this core */ + ref = &core_imc_refc[core_id]; + if (!ref) + return; + + mutex_lock(&ref->lock); + ref->refc--; + if (ref->refc == 0) { + rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("IMC: Unable to stop the counters for core %d\n", core_id); + return; + } + } else if (ref->refc < 0) { + WARN(1, "core-imc: Invalid event reference count\n"); + ref->refc = 0; + } + mutex_unlock(&ref->lock); +} + +static int core_imc_event_init(struct perf_event *event) +{ + int core_id, rc; + u64 config = event->attr.config; + struct imc_mem_info *pcmi; + struct imc_pmu *pmu; + struct imc_pmu_ref *ref; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + event->hw.idx = -1; + pmu = imc_event_to_pmu(event); + + /* Sanity check for config (event offset) */ + if (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size)) + return -EINVAL; + + if (!is_core_imc_mem_inited(event->cpu)) + return -ENODEV; + + core_id = event->cpu / threads_per_core; + pcmi = &core_imc_pmu->mem_info[core_id]; + if ((!pcmi->vbase)) + return -ENODEV; + + /* Get the core_imc mutex for this core */ + ref = &core_imc_refc[core_id]; + if (!ref) + return -EINVAL; + + /* + * Core pmu units are enabled only when it is used. + * See if this is triggered for the first time. + * If yes, take the mutex lock and enable the core counters. + * If not, just increment the count in core_imc_refc struct. + */ + mutex_lock(&ref->lock); + if (ref->refc == 0) { + rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("core-imc: Unable to start the counters for core %d\n", + core_id); + return rc; + } + } + ++ref->refc; + mutex_unlock(&ref->lock); + + event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK); + event->destroy = core_imc_counters_release; + return 0; +} + +/* + * Allocates a page of memory for each of the online cpus, and write the + * physical base address of that page to the LDBAR for that cpu. + * + * LDBAR Register Layout: + * + * 0 4 8 12 16 20 24 28 + * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | + * | | [ ] [ Counter Address [8:50] + * | * Mode | + * | * PB Scope + * * Enable/Disable + * + * 32 36 40 44 48 52 56 60 + * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | + * Counter Address [8:50] ] + * + */ +static int thread_imc_mem_alloc(int cpu_id, int size) +{ + u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id); + int phys_id = topology_physical_package_id(cpu_id); + + if (!local_mem) { + /* + * This case could happen only once at start, since we dont + * free the memory in cpu offline path. + */ + local_mem = page_address(alloc_pages_node(phys_id, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, + get_order(size))); + if (!local_mem) + return -ENOMEM; + + per_cpu(thread_imc_mem, cpu_id) = local_mem; + } + + ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | THREAD_IMC_ENABLE; + + mtspr(SPRN_LDBAR, ldbar_value); + return 0; +} + +static int ppc_thread_imc_cpu_online(unsigned int cpu) +{ + return thread_imc_mem_alloc(cpu, thread_imc_mem_size); +} + +static int ppc_thread_imc_cpu_offline(unsigned int cpu) +{ + mtspr(SPRN_LDBAR, 0); + return 0; +} + +static int thread_imc_cpu_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE, + "perf/powerpc/imc_thread:online", + ppc_thread_imc_cpu_online, + ppc_thread_imc_cpu_offline); +} + +void thread_imc_pmu_sched_task(struct perf_event_context *ctx, + bool sched_in) +{ + int core_id; + struct imc_pmu_ref *ref; + + if (!is_core_imc_mem_inited(smp_processor_id())) + return; + + core_id = smp_processor_id() / threads_per_core; + /* + * imc pmus are enabled only when it is used. + * See if this is triggered for the first time. + * If yes, take the mutex lock and enable the counters. + * If not, just increment the count in ref count struct. + */ + ref = &core_imc_refc[core_id]; + if (!ref) + return; + + if (sched_in) { + mutex_lock(&ref->lock); + if (ref->refc == 0) { + if (opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(smp_processor_id()))) { + mutex_unlock(&ref->lock); + pr_err("thread-imc: Unable to start the counter\ + for core %d\n", core_id); + return; + } + } + ++ref->refc; + mutex_unlock(&ref->lock); + } else { + mutex_lock(&ref->lock); + ref->refc--; + if (ref->refc == 0) { + if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(smp_processor_id()))) { + mutex_unlock(&ref->lock); + pr_err("thread-imc: Unable to stop the counters\ + for core %d\n", core_id); + return; + } + } else if (ref->refc < 0) { + ref->refc = 0; + } + mutex_unlock(&ref->lock); + } + + return; +} + +static int thread_imc_event_init(struct perf_event *event) +{ + u32 config = event->attr.config; + struct task_struct *target; + struct imc_pmu *pmu; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + event->hw.idx = -1; + pmu = imc_event_to_pmu(event); + + /* Sanity check for config offset */ + if (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size)) + return -EINVAL; + + target = event->hw.target; + if (!target) + return -EINVAL; + + event->pmu->task_ctx_nr = perf_sw_context; + return 0; +} + +static bool is_thread_imc_pmu(struct perf_event *event) +{ + if (!strncmp(event->pmu->name, "thread_imc", strlen("thread_imc"))) + return true; + + return false; +} + +static u64 * get_event_base_addr(struct perf_event *event) +{ + u64 addr; + + if (is_thread_imc_pmu(event)) { + addr = (u64)per_cpu(thread_imc_mem, smp_processor_id()); + return (u64 *)(addr + (event->attr.config & IMC_EVENT_OFFSET_MASK)); + } + + return (u64 *)event->hw.event_base; +} + +static void thread_imc_pmu_start_txn(struct pmu *pmu, + unsigned int txn_flags) +{ + if (txn_flags & ~PERF_PMU_TXN_ADD) + return; + perf_pmu_disable(pmu); +} + +static void thread_imc_pmu_cancel_txn(struct pmu *pmu) +{ + perf_pmu_enable(pmu); +} + +static int thread_imc_pmu_commit_txn(struct pmu *pmu) +{ + perf_pmu_enable(pmu); + return 0; +} + +static u64 imc_read_counter(struct perf_event *event) +{ + u64 *addr, data; + + /* + * In-Memory Collection (IMC) counters are free flowing counters. + * So we take a snapshot of the counter value on enable and save it + * to calculate the delta at later stage to present the event counter + * value. + */ + addr = get_event_base_addr(event); + data = be64_to_cpu(READ_ONCE(*addr)); + local64_set(&event->hw.prev_count, data); + + return data; +} + +static void imc_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count; + + counter_prev = local64_read(&event->hw.prev_count); + counter_new = imc_read_counter(event); + final_count = counter_new - counter_prev; + + /* Update the delta to the event count */ + local64_add(final_count, &event->count); +} + +static void imc_event_start(struct perf_event *event, int flags) +{ + /* + * In Memory Counters are free flowing counters. HW or the microcode + * keeps adding to the counter offset in memory. To get event + * counter value, we snapshot the value here and we calculate + * delta at later point. + */ + imc_read_counter(event); +} + +static void imc_event_stop(struct perf_event *event, int flags) +{ + /* + * Take a snapshot and calculate the delta and update + * the event counter values. + */ + imc_event_update(event); +} + +static int imc_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + imc_event_start(event, flags); + + return 0; +} + +static int thread_imc_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + imc_event_start(event, flags); + + /* Enable the sched_task to start the engine */ + perf_sched_cb_inc(event->ctx->pmu); + return 0; +} + +static void thread_imc_event_del(struct perf_event *event, int flags) +{ + /* + * Take a snapshot and calculate the delta and update + * the event counter values. + */ + imc_event_update(event); + perf_sched_cb_dec(event->ctx->pmu); +} + +/* update_pmu_ops : Populate the appropriate operations for "pmu" */ +static int update_pmu_ops(struct imc_pmu *pmu) +{ + pmu->pmu.task_ctx_nr = perf_invalid_context; + pmu->pmu.add = imc_event_add; + pmu->pmu.del = imc_event_stop; + pmu->pmu.start = imc_event_start; + pmu->pmu.stop = imc_event_stop; + pmu->pmu.read = imc_event_update; + pmu->pmu.attr_groups = pmu->attr_groups; + pmu->attr_groups[IMC_FORMAT_ATTR] = &imc_format_group; + + switch (pmu->domain) { + case IMC_DOMAIN_NEST: + pmu->pmu.event_init = nest_imc_event_init; + pmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group; + break; + case IMC_DOMAIN_CORE: + pmu->pmu.event_init = core_imc_event_init; + pmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group; + break; + case IMC_DOMAIN_THREAD: + pmu->pmu.event_init = thread_imc_event_init; + pmu->pmu.sched_task = thread_imc_pmu_sched_task; + pmu->pmu.add = thread_imc_event_add; + pmu->pmu.del = thread_imc_event_del; + pmu->pmu.start_txn = thread_imc_pmu_start_txn; + pmu->pmu.cancel_txn = thread_imc_pmu_cancel_txn; + pmu->pmu.commit_txn = thread_imc_pmu_commit_txn; + break; + default: + break; + } + + return 0; +} + +/* init_nest_pmu_ref: Initialize the imc_pmu_ref struct for all the nodes */ +static int init_nest_pmu_ref(void) +{ + int nid, i, cpu; + + nest_imc_refc = kcalloc(num_possible_nodes(), sizeof(*nest_imc_refc), + GFP_KERNEL); + + if (!nest_imc_refc) + return -ENOMEM; + + i = 0; + for_each_node(nid) { + /* + * Mutex lock to avoid races while tracking the number of + * sessions using the chip's nest pmu units. + */ + mutex_init(&nest_imc_refc[i].lock); + + /* + * Loop to init the "id" with the node_id. Variable "i" initialized to + * 0 and will be used as index to the array. "i" will not go off the + * end of the array since the "for_each_node" loops for "N_POSSIBLE" + * nodes only. + */ + nest_imc_refc[i++].id = nid; + } + + /* + * Loop to init the per_cpu "local_nest_imc_refc" with the proper + * "nest_imc_refc" index. This makes get_nest_pmu_ref() alot simple. + */ + for_each_possible_cpu(cpu) { + nid = cpu_to_node(cpu); + for (i = 0; i < num_possible_nodes(); i++) { + if (nest_imc_refc[i].id == nid) { + per_cpu(local_nest_imc_refc, cpu) = &nest_imc_refc[i]; + break; + } + } + } + return 0; +} + +static void cleanup_all_core_imc_memory(void) +{ + int i, nr_cores = num_present_cpus() / threads_per_core; + struct imc_mem_info *ptr = core_imc_pmu->mem_info; + int size = core_imc_pmu->counter_mem_size; + + /* mem_info will never be NULL */ + for (i = 0; i < nr_cores; i++) { + if (ptr[i].vbase) + free_pages((u64)ptr->vbase, get_order(size)); + } + + kfree(ptr); + kfree(core_imc_refc); +} + +static void thread_imc_ldbar_disable(void *dummy) +{ + /* + * By Zeroing LDBAR, we disable thread-imc + * updates. + */ + mtspr(SPRN_LDBAR, 0); +} + +void thread_imc_disable(void) +{ + on_each_cpu(thread_imc_ldbar_disable, NULL, 1); +} + +static void cleanup_all_thread_imc_memory(void) +{ + int i, order = get_order(thread_imc_mem_size); + + for_each_online_cpu(i) { + if (per_cpu(thread_imc_mem, i)) + free_pages((u64)per_cpu(thread_imc_mem, i), order); + + } +} + +/* + * Common function to unregister cpu hotplug callback and + * free the memory. + * TODO: Need to handle pmu unregistering, which will be + * done in followup series. + */ +static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) +{ + if (pmu_ptr->domain == IMC_DOMAIN_NEST) { + mutex_lock(&nest_init_lock); + if (nest_pmus == 1) { + cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE); + kfree(nest_imc_refc); + } + + if (nest_pmus > 0) + nest_pmus--; + mutex_unlock(&nest_init_lock); + } + + /* Free core_imc memory */ + if (pmu_ptr->domain == IMC_DOMAIN_CORE) { + cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE); + cleanup_all_core_imc_memory(); + } + + /* Free thread_imc memory */ + if (pmu_ptr->domain == IMC_DOMAIN_THREAD) { + cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE); + cleanup_all_thread_imc_memory(); + } + + /* Only free the attr_groups which are dynamically allocated */ + kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); + kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); + kfree(pmu_ptr); + return; +} + + +/* + * imc_mem_init : Function to support memory allocation for core imc. + */ +static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent, + int pmu_index) +{ + const char *s; + int nr_cores, cpu, res; + + if (of_property_read_string(parent, "name", &s)) + return -ENODEV; + + switch (pmu_ptr->domain) { + case IMC_DOMAIN_NEST: + /* Update the pmu name */ + pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s_imc", "nest_", s); + if (!pmu_ptr->pmu.name) + return -ENOMEM; + + /* Needed for hotplug/migration */ + per_nest_pmu_arr[pmu_index] = pmu_ptr; + break; + case IMC_DOMAIN_CORE: + /* Update the pmu name */ + pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc"); + if (!pmu_ptr->pmu.name) + return -ENOMEM; + + nr_cores = num_present_cpus() / threads_per_core; + pmu_ptr->mem_info = kcalloc(nr_cores, sizeof(struct imc_mem_info), + GFP_KERNEL); + + if (!pmu_ptr->mem_info) + return -ENOMEM; + + core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref), + GFP_KERNEL); + + if (!core_imc_refc) + return -ENOMEM; + + core_imc_pmu = pmu_ptr; + break; + case IMC_DOMAIN_THREAD: + /* Update the pmu name */ + pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc"); + if (!pmu_ptr->pmu.name) + return -ENOMEM; + + thread_imc_mem_size = pmu_ptr->counter_mem_size; + for_each_online_cpu(cpu) { + res = thread_imc_mem_alloc(cpu, pmu_ptr->counter_mem_size); + if (res) + return res; + } + + thread_imc_pmu = pmu_ptr; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * init_imc_pmu : Setup and register the IMC pmu device. + * + * @parent: Device tree unit node + * @pmu_ptr: memory allocated for this pmu + * @pmu_idx: Count of nest pmc registered + * + * init_imc_pmu() setup pmu cpumask and registers for a cpu hotplug callback. + * Handles failure cases and accordingly frees memory. + */ +int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_idx) +{ + int ret; + + ret = imc_mem_init(pmu_ptr, parent, pmu_idx); + if (ret) + goto err_free; + + switch (pmu_ptr->domain) { + case IMC_DOMAIN_NEST: + /* + * Nest imc pmu need only one cpu per chip, we initialize the + * cpumask for the first nest imc pmu and use the same for the + * rest. To handle the cpuhotplug callback unregister, we track + * the number of nest pmus in "nest_pmus". + */ + mutex_lock(&nest_init_lock); + if (nest_pmus == 0) { + ret = init_nest_pmu_ref(); + if (ret) { + mutex_unlock(&nest_init_lock); + goto err_free; + } + /* Register for cpu hotplug notification. */ + ret = nest_pmu_cpumask_init(); + if (ret) { + mutex_unlock(&nest_init_lock); + goto err_free; + } + } + nest_pmus++; + mutex_unlock(&nest_init_lock); + break; + case IMC_DOMAIN_CORE: + ret = core_imc_pmu_cpumask_init(); + if (ret) { + cleanup_all_core_imc_memory(); + return ret; + } + + break; + case IMC_DOMAIN_THREAD: + ret = thread_imc_cpu_init(); + if (ret) { + cleanup_all_thread_imc_memory(); + return ret; + } + + break; + default: + return -1; /* Unknown domain */ + } + + ret = update_events_in_group(parent, pmu_ptr); + if (ret) + goto err_free; + + ret = update_pmu_ops(pmu_ptr); + if (ret) + goto err_free; + + ret = perf_pmu_register(&pmu_ptr->pmu, pmu_ptr->pmu.name, -1); + if (ret) + goto err_free; + + pr_info("%s performance monitor hardware support registered\n", + pmu_ptr->pmu.name); + + return 0; + +err_free: + imc_common_cpuhp_mem_free(pmu_ptr); + return ret; +} diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 3f3aa9a7063ab32acfd71dec1b04d973e6d7394b..2efee3f196f56efe845d7aa833755bf1491d910b 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -99,7 +99,7 @@ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) else if (!cpu_has_feature(CPU_FTR_POWER9_DD1) && p9_SDAR_MODE(event)) *mmcra |= p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT; else - *mmcra |= MMCRA_SDAR_MODE_TLB; + *mmcra |= MMCRA_SDAR_MODE_DCACHE; } else *mmcra |= MMCRA_SDAR_MODE_TLB; } @@ -488,8 +488,8 @@ static int find_alternative(u64 event, const unsigned int ev_alt[][MAX_ALT], int return -1; } -int isa207_get_alternatives(u64 event, u64 alt[], - const unsigned int ev_alt[][MAX_ALT], int size) +int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, + const unsigned int ev_alt[][MAX_ALT]) { int i, j, num_alt = 0; u64 alt_event; @@ -505,5 +505,30 @@ int isa207_get_alternatives(u64 event, u64 alt[], } } + if (flags & PPMU_ONLY_COUNT_RUN) { + /* + * We're only counting in RUN state, so PM_CYC is equivalent to + * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. + */ + j = num_alt; + for (i = 0; i < num_alt; ++i) { + switch (alt[i]) { + case 0x1e: /* PMC_CYC */ + alt[j++] = 0x600f4; /* PM_RUN_CYC */ + break; + case 0x600f4: + alt[j++] = 0x1e; + break; + case 0x2: /* PM_INST_CMPL */ + alt[j++] = 0x500fa; /* PM_RUN_INST_CMPL */ + break; + case 0x500fa: + alt[j++] = 0x2; + break; + } + } + num_alt = j; + } + return num_alt; } diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index 8acbe6e802c749ce39101fddf04467a32189c095..6c737d675792ed6a7e513fb0729aec1698875d02 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h @@ -247,6 +247,7 @@ #define MMCRA_SDAR_MODE_SHIFT 42 #define MMCRA_SDAR_MODE_TLB (1ull << MMCRA_SDAR_MODE_SHIFT) #define MMCRA_SDAR_MODE_NO_UPDATES ~(0x3ull << MMCRA_SDAR_MODE_SHIFT) +#define MMCRA_SDAR_MODE_DCACHE (2ull << MMCRA_SDAR_MODE_SHIFT) #define MMCRA_IFM_SHIFT 30 #define MMCRA_THR_CTR_MANT_SHIFT 19 #define MMCRA_THR_CTR_MANT_MASK 0x7Ful @@ -287,8 +288,8 @@ int isa207_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[]); void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[]); -int isa207_get_alternatives(u64 event, u64 alt[], - const unsigned int ev_alt[][MAX_ALT], int size); +int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, + const unsigned int ev_alt[][MAX_ALT]); void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags, struct pt_regs *regs); void isa207_get_mem_weight(u64 *weight); diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 5463516e369b679e8a0682975e4ee8e94e1398fa..c9356955cab4c6096078b74352b894e5e44cd673 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -50,34 +50,11 @@ static const unsigned int event_alternatives[][MAX_ALT] = { static int power8_get_alternatives(u64 event, unsigned int flags, u64 alt[]) { - int i, j, num_alt = 0; - - num_alt = isa207_get_alternatives(event, alt, event_alternatives, - (int)ARRAY_SIZE(event_alternatives)); - if (flags & PPMU_ONLY_COUNT_RUN) { - /* - * We're only counting in RUN state, so PM_CYC is equivalent to - * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. - */ - j = num_alt; - for (i = 0; i < num_alt; ++i) { - switch (alt[i]) { - case PM_CYC: - alt[j++] = PM_RUN_CYC; - break; - case PM_RUN_CYC: - alt[j++] = PM_CYC; - break; - case PM_INST_CMPL: - alt[j++] = PM_RUN_INST_CMPL; - break; - case PM_RUN_INST_CMPL: - alt[j++] = PM_INST_CMPL; - break; - } - } - num_alt = j; - } + int num_alt = 0; + + num_alt = isa207_get_alternatives(event, alt, + ARRAY_SIZE(event_alternatives), flags, + event_alternatives); return num_alt; } diff --git a/arch/powerpc/perf/power9-events-list.h b/arch/powerpc/perf/power9-events-list.h index 50689180a6c1285f03448069989124c2788b17ad..e99c6bf4d391073e0fdb94c588421b8b821efab5 100644 --- a/arch/powerpc/perf/power9-events-list.h +++ b/arch/powerpc/perf/power9-events-list.h @@ -16,13 +16,16 @@ EVENT(PM_CYC, 0x0001e) EVENT(PM_ICT_NOSLOT_CYC, 0x100f8) EVENT(PM_CMPLU_STALL, 0x1e054) EVENT(PM_INST_CMPL, 0x00002) -EVENT(PM_BRU_CMPL, 0x4d05e) +EVENT(PM_BR_CMPL, 0x4d05e) EVENT(PM_BR_MPRED_CMPL, 0x400f6) /* All L1 D cache load references counted at finish, gated by reject */ EVENT(PM_LD_REF_L1, 0x100fc) /* Load Missed L1 */ EVENT(PM_LD_MISS_L1_FIN, 0x2c04e) +EVENT(PM_LD_MISS_L1, 0x3e054) +/* Alternate event code for PM_LD_MISS_L1 */ +EVENT(PM_LD_MISS_L1_ALT, 0x400f0) /* Store Missed L1 */ EVENT(PM_ST_MISS_L1, 0x300f0) /* L1 cache data prefetches */ @@ -62,3 +65,7 @@ EVENT(PM_INST_DISP, 0x200f2) EVENT(PM_INST_DISP_ALT, 0x300f2) /* Alternate Branch event code */ EVENT(PM_BR_CMPL_ALT, 0x10012) +/* Branch event that are not strongly biased */ +EVENT(PM_BR_2PATH, 0x20036) +/* ALternate branch event that are not strongly biased */ +EVENT(PM_BR_2PATH_ALT, 0x40036) diff --git a/arch/powerpc/perf/power9-pmu.c b/arch/powerpc/perf/power9-pmu.c index 2280cf87ff9c9423ad27f84d212dbc1fafe963ca..24b5b5b7a2064179a6e6685ee3331cf45b6861be 100644 --- a/arch/powerpc/perf/power9-pmu.c +++ b/arch/powerpc/perf/power9-pmu.c @@ -109,14 +109,17 @@ static const unsigned int power9_event_alternatives[][MAX_ALT] = { { PM_INST_DISP, PM_INST_DISP_ALT }, { PM_RUN_CYC_ALT, PM_RUN_CYC }, { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL }, + { PM_LD_MISS_L1, PM_LD_MISS_L1_ALT }, + { PM_BR_2PATH, PM_BR_2PATH_ALT }, }; static int power9_get_alternatives(u64 event, unsigned int flags, u64 alt[]) { int num_alt = 0; - num_alt = isa207_get_alternatives(event, alt, power9_event_alternatives, - (int)ARRAY_SIZE(power9_event_alternatives)); + num_alt = isa207_get_alternatives(event, alt, + ARRAY_SIZE(power9_event_alternatives), flags, + power9_event_alternatives); return num_alt; } @@ -125,7 +128,7 @@ GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_ICT_NOSLOT_CYC); GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL); GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); -GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_CMPL); +GENERIC_EVENT_ATTR(branch-instructions, PM_BR_CMPL); GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL); GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1_FIN); @@ -143,7 +146,7 @@ CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL); CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS); CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST); CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL); -CACHE_EVENT_ATTR(branch-loads, PM_BRU_CMPL); +CACHE_EVENT_ATTR(branch-loads, PM_BR_CMPL); CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS); @@ -152,7 +155,7 @@ static struct attribute *power9_events_attr[] = { GENERIC_EVENT_PTR(PM_ICT_NOSLOT_CYC), GENERIC_EVENT_PTR(PM_CMPLU_STALL), GENERIC_EVENT_PTR(PM_INST_CMPL), - GENERIC_EVENT_PTR(PM_BRU_CMPL), + GENERIC_EVENT_PTR(PM_BR_CMPL), GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL), GENERIC_EVENT_PTR(PM_LD_REF_L1), GENERIC_EVENT_PTR(PM_LD_MISS_L1_FIN), @@ -169,7 +172,7 @@ static struct attribute *power9_events_attr[] = { CACHE_EVENT_PTR(PM_L2_ST_MISS), CACHE_EVENT_PTR(PM_L2_ST), CACHE_EVENT_PTR(PM_BR_MPRED_CMPL), - CACHE_EVENT_PTR(PM_BRU_CMPL), + CACHE_EVENT_PTR(PM_BR_CMPL), CACHE_EVENT_PTR(PM_DTLB_MISS), CACHE_EVENT_PTR(PM_ITLB_MISS), NULL @@ -244,7 +247,7 @@ static int power9_generic_events[] = { [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_ICT_NOSLOT_CYC, [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL, [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_CMPL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL, [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL, [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1_FIN, @@ -370,7 +373,7 @@ static int power9_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { }, [ C(BPU) ] = { [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = PM_BRU_CMPL, + [ C(RESULT_ACCESS) ] = PM_BR_CMPL, [ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL, }, [ C(OP_WRITE) ] = { @@ -459,8 +462,8 @@ static int __init init_power9_pmu(void) * Power9 DD1 should use PM_BR_CMPL_ALT event code for * "branches" to provide correct counter value. */ - EVENT_VAR(PM_BRU_CMPL, _g).id = PM_BR_CMPL_ALT; - EVENT_VAR(PM_BRU_CMPL, _c).id = PM_BR_CMPL_ALT; + EVENT_VAR(PM_BR_CMPL, _g).id = PM_BR_CMPL_ALT; + EVENT_VAR(PM_BR_CMPL, _c).id = PM_BR_CMPL_ALT; rc = register_power_pmu(&power9_isa207_pmu); } else { rc = register_power_pmu(&power9_pmu); diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 72b824160660e0b9302216318ea6d16598f3f5bc..2c5651992369839424006ef077acd25a4bfaeb6a 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -1,6 +1,6 @@ -obj-$(CONFIG_44x) += misc_44x.o +obj-y += misc_44x.o machine_check.o ifneq ($(CONFIG_PPC4xx_CPM),y) -obj-$(CONFIG_44x) += idle.o +obj-y += idle.o endif obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o obj-$(CONFIG_EBONY) += ebony.o diff --git a/arch/powerpc/platforms/44x/machine_check.c b/arch/powerpc/platforms/44x/machine_check.c new file mode 100644 index 0000000000000000000000000000000000000000..034d70d6d3356a42122b8a394ad3fd0b75af93a5 --- /dev/null +++ b/arch/powerpc/platforms/44x/machine_check.c @@ -0,0 +1,89 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +int machine_check_440A(struct pt_regs *regs) +{ + unsigned long reason = regs->dsisr; + + printk("Machine check in kernel mode.\n"); + if (reason & ESR_IMCP){ + printk("Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } + else { + u32 mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk("Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk("Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk("Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk("TLB Parity Error\n"); + if (mcsr & MCSR_ICP){ + flush_instruction_cache(); + printk("I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk("D-Cache Search Parity Error\n"); + if (mcsr & MCSR_DCFP) + printk("D-Cache Flush Parity Error\n"); + if (mcsr & MCSR_IMPE) + printk("Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + } + return 0; +} + +#ifdef CONFIG_PPC_47x +int machine_check_47x(struct pt_regs *regs) +{ + unsigned long reason = regs->dsisr; + u32 mcsr; + + printk(KERN_ERR "Machine check in kernel mode.\n"); + if (reason & ESR_IMCP) { + printk(KERN_ERR "Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + return 0; + } + mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk(KERN_ERR "Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk(KERN_ERR "Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk(KERN_ERR "Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk(KERN_ERR "TLB Parity Error\n"); + if (mcsr & MCSR_ICP) { + flush_instruction_cache(); + printk(KERN_ERR "I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk(KERN_ERR "D-Cache Search Parity Error\n"); + if (mcsr & PPC47x_MCSR_GPR) + printk(KERN_ERR "GPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_FPR) + printk(KERN_ERR "FPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_IPR) + printk(KERN_ERR "Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + + return 0; +} +#endif /* CONFIG_PPC_47x */ diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9779c32db34e0a7624f488a3170af7ff40c42103 --- /dev/null +++ b/arch/powerpc/platforms/4xx/Makefile @@ -0,0 +1,8 @@ +obj-y += uic.o machine_check.o +obj-$(CONFIG_PPC4xx_OCM) += ocm.o +obj-$(CONFIG_4xx_SOC) += soc.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_PPC4xx_HSTA_MSI) += hsta_msi.o +obj-$(CONFIG_PPC4xx_MSI) += msi.o +obj-$(CONFIG_PPC4xx_CPM) += cpm.o +obj-$(CONFIG_PPC4xx_GPIO) += gpio.o diff --git a/arch/powerpc/sysdev/ppc4xx_cpm.c b/arch/powerpc/platforms/4xx/cpm.c similarity index 97% rename from arch/powerpc/sysdev/ppc4xx_cpm.c rename to arch/powerpc/platforms/4xx/cpm.c index ba95adf81d8d9dac32c40fffa3732bf4e092b927..53ff81ca8a3ce6cc637115042a28c189db83b50a 100644 --- a/arch/powerpc/sysdev/ppc4xx_cpm.c +++ b/arch/powerpc/platforms/4xx/cpm.c @@ -240,7 +240,7 @@ static int cpm_suspend_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops cpm_suspend_ops = { +static const struct platform_suspend_ops cpm_suspend_ops = { .valid = cpm_suspend_valid, .enter = cpm_suspend_enter, }; @@ -278,8 +278,8 @@ static int __init cpm_init(void) dcr_len = dcr_resource_len(np, 0); if (dcr_base == 0 || dcr_len == 0) { - printk(KERN_ERR "cpm: could not parse dcr property for %s\n", - np->full_name); + printk(KERN_ERR "cpm: could not parse dcr property for %pOF\n", + np); ret = -EINVAL; goto node_put; } @@ -287,8 +287,8 @@ static int __init cpm_init(void) cpm.dcr_host = dcr_map(np, dcr_base, dcr_len); if (!DCR_MAP_OK(cpm.dcr_host)) { - printk(KERN_ERR "cpm: failed to map dcr property for %s\n", - np->full_name); + printk(KERN_ERR "cpm: failed to map dcr property for %pOF\n", + np); ret = -EINVAL; goto node_put; } diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/platforms/4xx/gpio.c similarity index 98% rename from arch/powerpc/sysdev/ppc4xx_gpio.c rename to arch/powerpc/platforms/4xx/gpio.c index 5382d04dd8723f632ac781207da39be7f9f8704e..2238e369cde452eb05175f85d67a72a329c07e8e 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/platforms/4xx/gpio.c @@ -198,8 +198,7 @@ static int __init ppc4xx_add_gpiochips(void) goto err; continue; err: - pr_err("%s: registration failed with status %d\n", - np->full_name, ret); + pr_err("%pOF: registration failed with status %d\n", np, ret); kfree(ppc4xx_gc); /* try others anyway */ } diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/platforms/4xx/hsta_msi.c similarity index 100% rename from arch/powerpc/sysdev/ppc4xx_hsta_msi.c rename to arch/powerpc/platforms/4xx/hsta_msi.c diff --git a/arch/powerpc/platforms/4xx/machine_check.c b/arch/powerpc/platforms/4xx/machine_check.c new file mode 100644 index 0000000000000000000000000000000000000000..aa039dfaf82fa4d0a4bbbaaa4767cb636e082870 --- /dev/null +++ b/arch/powerpc/platforms/4xx/machine_check.c @@ -0,0 +1,26 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +int machine_check_4xx(struct pt_regs *regs) +{ + unsigned long reason = regs->dsisr; + + if (reason & ESR_IMCP) { + printk("Instruction"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } else + printk("Data"); + printk(" machine check in kernel mode.\n"); + + return 0; +} diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/platforms/4xx/msi.c similarity index 98% rename from arch/powerpc/sysdev/ppc4xx_msi.c rename to arch/powerpc/platforms/4xx/msi.c index 590dab4f47d63c1018bcd52966b5a426ae37205b..d50417e23add8961d8b96addbfeefd38d384464d 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/platforms/4xx/msi.c @@ -233,8 +233,7 @@ static int ppc4xx_msi_probe(struct platform_device *dev) /* Get MSI ranges */ err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { - dev_err(&dev->dev, "%s resource error!\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF resource error!\n", dev->dev.of_node); goto error_out; } diff --git a/arch/powerpc/sysdev/ppc4xx_ocm.c b/arch/powerpc/platforms/4xx/ocm.c similarity index 100% rename from arch/powerpc/sysdev/ppc4xx_ocm.c rename to arch/powerpc/platforms/4xx/ocm.c diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/platforms/4xx/pci.c similarity index 95% rename from arch/powerpc/sysdev/ppc4xx_pci.c rename to arch/powerpc/platforms/4xx/pci.c index 086aca69ecae39cf773dfb8fb9675d5843a58fd6..73e6b36bcd5125724a0c913d745e1a4bab9b1133 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/platforms/4xx/pci.c @@ -32,7 +32,7 @@ #include #include -#include "ppc4xx_pci.h" +#include "pci.h" static int dma_offset_set; @@ -127,9 +127,9 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, * within 32 bits space */ if (cpu_addr != 0 || pci_addr > 0xffffffff) { - printk(KERN_WARNING "%s: Ignored unsupported dma range" + printk(KERN_WARNING "%pOF: Ignored unsupported dma range" " 0x%016llx...0x%016llx -> 0x%016llx\n", - hose->dn->full_name, + hose->dn, pci_addr, pci_addr + size - 1, cpu_addr); continue; } @@ -152,8 +152,7 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, /* We only support one global DMA offset */ if (dma_offset_set && pci_dram_offset != res->start) { - printk(KERN_ERR "%s: dma-ranges(s) mismatch\n", - hose->dn->full_name); + printk(KERN_ERR "%pOF: dma-ranges(s) mismatch\n", hose->dn); return -ENXIO; } @@ -161,17 +160,16 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, * DMA bounce buffers */ if (size < total_memory) { - printk(KERN_ERR "%s: dma-ranges too small " + printk(KERN_ERR "%pOF: dma-ranges too small " "(size=%llx total_memory=%llx)\n", - hose->dn->full_name, size, (u64)total_memory); + hose->dn, size, (u64)total_memory); return -ENXIO; } /* Check we are a power of 2 size and that base is a multiple of size*/ if ((size & (size - 1)) != 0 || (res->start & (size - 1)) != 0) { - printk(KERN_ERR "%s: dma-ranges unaligned\n", - hose->dn->full_name); + printk(KERN_ERR "%pOF: dma-ranges unaligned\n", hose->dn); return -ENXIO; } @@ -181,8 +179,8 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, if (res->end > 0xffffffff && !(of_device_is_compatible(hose->dn, "ibm,plb-pciex-460sx") || of_device_is_compatible(hose->dn, "ibm,plb-pciex-476fpe"))) { - printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", - hose->dn->full_name); + printk(KERN_ERR "%pOF: dma-ranges outside of 32 bits space\n", + hose->dn); return -ENXIO; } out: @@ -233,8 +231,7 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, */ if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { - printk(KERN_WARNING "%s: Resource out of range\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Resource out of range\n", hose->dn); return -1; } ma = (0xffffffffu << ilog2(size)) | 1; @@ -266,8 +263,7 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, if (!(res->flags & IORESOURCE_MEM)) continue; if (j > 2) { - printk(KERN_WARNING "%s: Too many ranges\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Too many ranges\n", hose->dn); break; } @@ -292,8 +288,8 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, if (j <= 2 && !found_isa_hole && hose->isa_mem_size) if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0, hose->isa_mem_size, 0, j) == 0) - printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", - hose->dn->full_name); + printk(KERN_INFO "%pOF: Legacy ISA memory support enabled\n", + hose->dn); } static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, @@ -333,21 +329,20 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np) /* Check if device is enabled */ if (!of_device_is_available(np)) { - printk(KERN_INFO "%s: Port disabled via device-tree\n", - np->full_name); + printk(KERN_INFO "%pOF: Port disabled via device-tree\n", np); return; } /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { - printk(KERN_ERR "%s: Can't get PCI config register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI config register base !", + np); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 3, &rsrc_reg)) { - printk(KERN_ERR "%s: Can't get PCI internal register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI internal register base !", + np); return; } @@ -361,7 +356,7 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np) /* Map registers */ reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); if (reg == NULL) { - printk(KERN_ERR "%s: Can't map registers !", np->full_name); + printk(KERN_ERR "%pOF: Can't map registers !", np); goto fail; } @@ -423,8 +418,8 @@ static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose, if (!is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { - printk(KERN_WARNING "%s: Resource out of range\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Resource out of range\n", + hose->dn); return -1; } @@ -467,8 +462,7 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, if (!(res->flags & IORESOURCE_MEM)) continue; if (j > 1) { - printk(KERN_WARNING "%s: Too many ranges\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Too many ranges\n", hose->dn); break; } @@ -493,8 +487,8 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, if (j <= 1 && !found_isa_hole && hose->isa_mem_size) if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0, hose->isa_mem_size, 0, j) == 0) - printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", - hose->dn->full_name); + printk(KERN_INFO "%pOF: Legacy ISA memory support enabled\n", + hose->dn); } static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, @@ -539,14 +533,14 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { - printk(KERN_ERR "%s:Can't get PCI-X config register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI-X config register base !", + np); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 3, &rsrc_reg)) { - printk(KERN_ERR "%s: Can't get PCI-X internal register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI-X internal register base !", + np); return; } @@ -568,7 +562,7 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) /* Map registers */ reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); if (reg == NULL) { - printk(KERN_ERR "%s: Can't map registers !", np->full_name); + printk(KERN_ERR "%pOF: Can't map registers !", np); goto fail; } @@ -1246,8 +1240,8 @@ static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port) mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); if (mbase == NULL) { - printk(KERN_ERR "%s: Can't map internal config space !", - port->node->full_name); + printk(KERN_ERR "%pOF: Can't map internal config space !", + port->node); goto done; } @@ -1389,7 +1383,7 @@ static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port) port->index); return; } - + while (timeout_ms--) { val = in_le32(mbase + PECFG_TLDLP); @@ -1448,8 +1442,7 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; #endif if (ppc4xx_pciex_hwops == NULL) { - printk(KERN_WARNING "PCIE: unknown host type %s\n", - np->full_name); + printk(KERN_WARNING "PCIE: unknown host type %pOF\n", np); return -ENODEV; } @@ -1730,8 +1723,7 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, (index < 2 && size < 0x100000) || (index == 2 && size < 0x100) || (plb_addr & (size - 1)) != 0) { - printk(KERN_WARNING "%s: Resource out of range\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Resource out of range\n", hose->dn); return -1; } @@ -1807,8 +1799,8 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, if (!(res->flags & IORESOURCE_MEM)) continue; if (j > 1) { - printk(KERN_WARNING "%s: Too many ranges\n", - port->node->full_name); + printk(KERN_WARNING "%pOF: Too many ranges\n", + port->node); break; } @@ -1834,8 +1826,8 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, hose->isa_mem_phys, 0, hose->isa_mem_size, 0, j) == 0) - printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", - hose->dn->full_name); + printk(KERN_INFO "%pOF: Legacy ISA memory support enabled\n", + hose->dn); /* Configure IO, always 64K starting at 0. We hard wire it to 64K ! * Note also that it -has- to be region index 2 on this HW @@ -1970,8 +1962,8 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) (hose->first_busno + 1) * 0x100000, busses * 0x100000); if (cfg_data == NULL) { - printk(KERN_ERR "%s: Can't map external config space !", - port->node->full_name); + printk(KERN_ERR "%pOF: Can't map external config space !", + port->node); goto fail; } hose->cfg_data = cfg_data; @@ -1982,13 +1974,13 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) */ mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); if (mbase == NULL) { - printk(KERN_ERR "%s: Can't map internal config space !", - port->node->full_name); + printk(KERN_ERR "%pOF: Can't map internal config space !", + port->node); goto fail; } hose->cfg_addr = mbase; - pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, + pr_debug("PCIE %pOF, bus %d..%d\n", port->node, hose->first_busno, hose->last_busno); pr_debug(" config space mapped at: root @0x%p, other @0x%p\n", hose->cfg_addr, hose->cfg_data); @@ -2100,14 +2092,13 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) /* Get the port number from the device-tree */ pval = of_get_property(np, "port", NULL); if (pval == NULL) { - printk(KERN_ERR "PCIE: Can't find port number for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: Can't find port number for %pOF\n", np); return; } portno = *pval; if (portno >= ppc4xx_pciex_port_count) { - printk(KERN_ERR "PCIE: port number out of range for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: port number out of range for %pOF\n", + np); return; } port = &ppc4xx_pciex_ports[portno]; @@ -2125,8 +2116,8 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) if (ppc4xx_pciex_hwops->want_sdr) { pval = of_get_property(np, "sdr-base", NULL); if (pval == NULL) { - printk(KERN_ERR "PCIE: missing sdr-base for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: missing sdr-base for %pOF\n", + np); return; } port->sdr_base = *pval; @@ -2142,29 +2133,26 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) } else if (!strcmp(val, "pci")) { port->endpoint = 0; } else { - printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: missing or incorrect device_type for %pOF\n", + np); return; } /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &port->cfg_space)) { - printk(KERN_ERR "%s: Can't get PCI-E config space !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI-E config space !", np); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 1, &port->utl_regs)) { - printk(KERN_ERR "%s: Can't get UTL register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get UTL register base !", np); return; } /* Map DCRs */ dcrs = dcr_resource_start(np, 0); if (dcrs == 0) { - printk(KERN_ERR "%s: Can't get DCR register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get DCR register base !", np); return; } port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/platforms/4xx/pci.h similarity index 100% rename from arch/powerpc/sysdev/ppc4xx_pci.h rename to arch/powerpc/platforms/4xx/pci.h diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/platforms/4xx/soc.c similarity index 97% rename from arch/powerpc/sysdev/ppc4xx_soc.c rename to arch/powerpc/platforms/4xx/soc.c index d41134d2f78648c14589b3c8dd2948665d45b72e..5e36508b2a703e4dabea0d99e5a0e60b2cb2e9a9 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/platforms/4xx/soc.c @@ -90,7 +90,7 @@ static int __init ppc4xx_l2c_probe(void) /* Get l2 cache size */ prop = of_get_property(np, "cache-size", NULL); if (prop == NULL) { - printk(KERN_ERR "%s: Can't get cache-size!\n", np->full_name); + printk(KERN_ERR "%pOF: Can't get cache-size!\n", np); of_node_put(np); return -ENODEV; } @@ -99,8 +99,7 @@ static int __init ppc4xx_l2c_probe(void) /* Map DCRs */ dcrreg = of_get_property(np, "dcr-reg", &len); if (!dcrreg || (len != 4 * sizeof(u32))) { - printk(KERN_ERR "%s: Can't get DCR register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get DCR register base !", np); of_node_put(np); return -ENODEV; } diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/platforms/4xx/uic.c similarity index 95% rename from arch/powerpc/sysdev/uic.c rename to arch/powerpc/platforms/4xx/uic.c index a00949f3e3788ca025bb58493e927ad49c9c19e0..8b4dd0da08395556950c50029af05bcfad41085c 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/platforms/4xx/uic.c @@ -243,16 +243,16 @@ static struct uic * __init uic_init_one(struct device_node *node) raw_spin_lock_init(&uic->lock); indexp = of_get_property(node, "cell-index", &len); if (!indexp || (len != sizeof(u32))) { - printk(KERN_ERR "uic: Device node %s has missing or invalid " - "cell-index property\n", node->full_name); + printk(KERN_ERR "uic: Device node %pOF has missing or invalid " + "cell-index property\n", node); return NULL; } uic->index = *indexp; dcrreg = of_get_property(node, "dcr-reg", &len); if (!dcrreg || (len != 2*sizeof(u32))) { - printk(KERN_ERR "uic: Device node %s has missing or invalid " - "dcr-reg property\n", node->full_name); + printk(KERN_ERR "uic: Device node %pOF has missing or invalid " + "dcr-reg property\n", node); return NULL; } uic->dcrbase = *dcrreg; @@ -292,7 +292,7 @@ void __init uic_init_tree(void) * top-level interrupt controller */ primary_uic = uic_init_one(np); if (!primary_uic) - panic("Unable to initialize primary UIC %s\n", np->full_name); + panic("Unable to initialize primary UIC %pOF\n", np); irq_set_default_host(primary_uic->irqhost); of_node_put(np); @@ -306,8 +306,8 @@ void __init uic_init_tree(void) uic = uic_init_one(np); if (! uic) - panic("Unable to initialize a secondary UIC %s\n", - np->full_name); + panic("Unable to initialize a secondary UIC %pOF\n", + np); cascade_virq = irq_of_parse_and_map(np, 0); diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index add5a5374fa0c693082824fbf5cb1ddb9f75e4e0..b3097fe6441b9571095a696b7ee357c995b88dbb 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -363,7 +363,7 @@ static int get_cpmf_mult_x2(void) */ /* applies to the IPS_DIV, and PCI_DIV values */ -static struct clk_div_table divtab_2346[] = { +static const struct clk_div_table divtab_2346[] = { { .val = 2, .div = 2, }, { .val = 3, .div = 3, }, { .val = 4, .div = 4, }, @@ -372,7 +372,7 @@ static struct clk_div_table divtab_2346[] = { }; /* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */ -static struct clk_div_table divtab_1234[] = { +static const struct clk_div_table divtab_1234[] = { { .val = 1, .div = 1, }, { .val = 2, .div = 2, }, { .val = 3, .div = 3, }, diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 6b4f4cb7009a33c3fed9e0dce6df52cb2c006330..f99e79ee060e11169c3ef72522324fd23b5627c1 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -387,8 +387,8 @@ static unsigned int __init get_fifo_size(struct device_node *np, if (fp) return *fp; - pr_warning("no %s property in %s node, defaulting to %d\n", - prop_name, np->full_name, DEFAULT_FIFO_SIZE); + pr_warning("no %s property in %pOF node, defaulting to %d\n", + prop_name, np, DEFAULT_FIFO_SIZE); return DEFAULT_FIFO_SIZE; } @@ -426,15 +426,15 @@ static void __init mpc512x_psc_fifo_init(void) psc = of_iomap(np, 0); if (!psc) { - pr_err("%s: Can't map %s device\n", - __func__, np->full_name); + pr_err("%s: Can't map %pOF device\n", + __func__, np); continue; } /* FIFO space is 4KiB, check if requested size is available */ if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { - pr_err("%s: no fifo space available for %s\n", - __func__, np->full_name); + pr_err("%s: no fifo space available for %pOF\n", + __func__, np); iounmap(psc); /* * chances are that another device requests less diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 39b49822ace12bdeb960c196050e758235a986fe..1ecbf176d35a16aca54fc1193fe8b5a78ff3bcb6 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -99,7 +99,7 @@ static void __init efika_pcisetup(void) bus_range = of_get_property(pcictrl, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Can't get bus-range for %s\n", pcictrl->full_name); + ": Can't get bus-range for %pOF\n", pcictrl); goto out_put; } @@ -109,14 +109,14 @@ static void __init efika_pcisetup(void) else printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", bus_range[0], bus_range[1]); - printk(" controlled by %s\n", pcictrl->full_name); + printk(" controlled by %pOF\n", pcictrl); printk("\n"); hose = pcibios_alloc_controller(pcictrl); if (!hose) { printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Can't allocate PCI controller structure for %s\n", - pcictrl->full_name); + ": Can't allocate PCI controller structure for %pOF\n", + pcictrl); goto out_put; } diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index a3227040cc8684ea8b20b0b032ec930b5d7d33af..1fcab233d2f2e851ce89091c3a05e144ab212af2 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -156,7 +156,7 @@ static void __init media5200_init_irq(void) fpga_np = of_find_compatible_node(NULL, NULL, "fsl,media5200-fpga"); if (!fpga_np) goto out; - pr_debug("%s: found fpga node: %s\n", __func__, fpga_np->full_name); + pr_debug("%s: found fpga node: %pOF\n", __func__, fpga_np); media5200_irq.regs = of_iomap(fpga_np, 0); if (!media5200_irq.regs) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 22645a7c6b8a9a3ef10f498aafc509f56a9070e6..9e974b1e169727726a86937a72e222b93710a7b0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -226,7 +226,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct, dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]); if ((intsize < 1) || (intspec[0] > 3)) { - dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name); + dev_err(gpt->dev, "bad irq specifier in %pOF\n", ct); return -EINVAL; } @@ -331,7 +331,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) if (!of_find_property(node, "gpio-controller", NULL)) return; - gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL); + gpt->gc.label = kasprintf(GFP_KERNEL, "%pOF", node); if (!gpt->gc.label) { dev_err(gpt->dev, "out of memory\n"); return; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 00282c2b0cae9bee9d8cef2be40128e02b65f563..af0f799952147b05438f2bfc8d2c701d06657a20 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -369,19 +369,19 @@ mpc52xx_add_bridge(struct device_node *node) const int *bus_range; struct resource rsrc; - pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); + pr_debug("Adding MPC52xx PCI host bridge %pOF\n", node); pci_add_flags(PCI_REASSIGN_ALL_BUS); if (of_address_to_resource(node, 0, &rsrc) != 0) { - printk(KERN_ERR "Can't get %s resources\n", node->full_name); + printk(KERN_ERR "Can't get %pOF resources\n", node); return -EINVAL; } bus_range = of_get_property(node, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n", - node->full_name); + printk(KERN_WARNING "Can't get %pOF bus-range, assume bus 0\n", + node); bus_range = NULL; } diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 63c5ab6489c94d4c3e3e14c1f381bcee519c9c29..96bb55ca61d39884b56550112791e9e6ac0dd7f5 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -128,7 +128,7 @@ static int mcu_gpiochip_add(struct mcu *mcu) return -ENODEV; gc->owner = THIS_MODULE; - gc->label = np->full_name; + gc->label = kasprintf(GFP_KERNEL, "%pOF", np); gc->can_sleep = 1; gc->ngpio = MCU_NUM_GPIO; gc->base = -1; @@ -141,6 +141,7 @@ static int mcu_gpiochip_add(struct mcu *mcu) static int mcu_gpiochip_remove(struct mcu *mcu) { + kfree(mcu->gc.label); gpiochip_remove(&mcu->gc); return 0; } diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index d7c9b186954d931c0957908dbd7a19e3f19d0610..a4539c5accb0bc68f29aa814d5845eb24a13c241 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -89,7 +89,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, goto err; ret = of_irq_to_resource(np, 0, &res[1]); - if (!ret) + if (ret <= 0) goto err; pdev = platform_device_alloc("mpc83xx_spi", i); @@ -113,7 +113,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, unreg: platform_device_del(pdev); err: - pr_err("%s: registration failed\n", np->full_name); + pr_err("%pOF: registration failed\n", np); next: i++; } diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 978b85bb3233e55a78ea671629a07963d62e5fb3..7fa3e197871aa82b62c1aa9ff3a333f4d3ba0505 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -361,7 +361,7 @@ static int pmc_probe(struct platform_device *ofdev) return -EBUSY; } - pmc_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc)); + pmc_regs = ioremap(res.start, sizeof(*pmc_regs)); if (!pmc_regs) { ret = -ENOMEM; @@ -374,7 +374,7 @@ static int pmc_probe(struct platform_device *ofdev) goto out_pmc; } - clock_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc)); + clock_regs = ioremap(res.start, sizeof(*clock_regs)); if (!clock_regs) { ret = -ENOMEM; diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 0908abd7e36f684cf60162fd572a6175abfeb833..9fb57f78cdbe37f08a3d5f2ddef7b06696e04aa2 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -508,8 +508,8 @@ static void __init p1022_ds_setup_arch(void) * allocate one static local variable for each * call to this function. */ - pr_info("p1022ds: disabling %s node", - np2->full_name); + pr_info("p1022ds: disabling %pOF node", + np2); of_update_property(np2, &nor_status); of_node_put(np2); } @@ -524,8 +524,8 @@ static void __init p1022_ds_setup_arch(void) .length = sizeof("disabled"), }; - pr_info("p1022ds: disabling %s node", - np2->full_name); + pr_info("p1022ds: disabling %pOF node", + np2); of_update_property(np2, &nand_status); of_node_put(np2); } diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index cd6ce845f398b69334dfa8602bd7ec37c7ad44e8..77e618dce4a876ad58f101f848b6fca2b019736c 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -100,8 +100,8 @@ static void xes_mpc85xx_fixups(void) err = of_address_to_resource(np, 0, &r[0]); if (err) { printk(KERN_WARNING "xes_mpc85xx: Could not get " - "resource for device tree node '%s'", - np->full_name); + "resource for device tree node '%pOF'", + np); continue; } diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index 80cbcb0ad9b1bebde2202af3247d45f29c44d0ad..536b0c5d5ce390bf827c758a3418b99fa03a1d46 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig @@ -5,7 +5,6 @@ config CPM1 choice prompt "8xx Machine Type" depends on PPC_8xx - depends on 8xx default MPC885ADS config MPC8XXFADS @@ -92,7 +91,7 @@ endmenu # menu "MPC8xx CPM Options" - depends on 8xx + depends on PPC_8xx # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile index 76a81c3350a8993ef34eeb0c0b429dbadc542d40..f9af3218bd9c0cd8cc835075b394df0f9f226084 100644 --- a/arch/powerpc/platforms/8xx/Makefile +++ b/arch/powerpc/platforms/8xx/Makefile @@ -1,7 +1,7 @@ # # Makefile for the PowerPC 8xx linux kernel. # -obj-$(CONFIG_PPC_8xx) += m8xx_setup.o +obj-y += m8xx_setup.o machine_check.o pic.o obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o obj-$(CONFIG_PPC_EP88XC) += ep88xc.o diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c index f81069f79a94820a83a46dcfd58c001af86ef276..1917d69f84dfe38899451e383b8b20b8b4099822 100644 --- a/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -23,7 +23,7 @@ #include #include -#include +#include "pic.h" #include "mpc8xx.h" diff --git a/arch/powerpc/platforms/8xx/machine_check.c b/arch/powerpc/platforms/8xx/machine_check.c new file mode 100644 index 0000000000000000000000000000000000000000..402016705a39f7aa4e0857e3e49350cd0110d0d2 --- /dev/null +++ b/arch/powerpc/platforms/8xx/machine_check.c @@ -0,0 +1,37 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +int machine_check_8xx(struct pt_regs *regs) +{ + unsigned long reason = regs->msr; + + pr_err("Machine check in kernel mode.\n"); + pr_err("Caused by (from SRR1=%lx): ", reason); + if (reason & 0x40000000) + pr_err("Fetch error at address %lx\n", regs->nip); + else + pr_err("Data access error at address %lx\n", regs->dar); + +#ifdef CONFIG_PCI + /* the qspan pci read routines can cause machine checks -- Cort + * + * yuck !!! that totally needs to go away ! There are better ways + * to deal with that than having a wart in the mcheck handler. + * -- BenH + */ + bad_page_fault(regs, regs->dar, SIGBUS); + return 1; +#else + return 0; +#endif +} diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/platforms/8xx/pic.c similarity index 99% rename from arch/powerpc/sysdev/mpc8xx_pic.c rename to arch/powerpc/platforms/8xx/pic.c index 2842f9d63d215b036b9f4588d7ae1656d3ce95c6..8d5a25d43ef32e0c034aa7a1b7516c1d9aa8dfd9 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/platforms/8xx/pic.c @@ -9,7 +9,7 @@ #include #include -#include "mpc8xx_pic.h" +#include "pic.h" #define PIC_VEC_SPURRIOUS 15 diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/platforms/8xx/pic.h similarity index 100% rename from arch/powerpc/sysdev/mpc8xx_pic.h rename to arch/powerpc/platforms/8xx/pic.h diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 2f629e0551e970f346a3ac89d3d5a993b524ce36..13663efc1d316db30c217adab02b7f8e89b7d3d1 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -32,7 +32,6 @@ config PPC_85xx config PPC_8xx bool "Freescale 8xx" select FSL_SOC - select 8xx select PPC_LIB_RHEAP select SYS_SUPPORTS_HUGETLBFS @@ -149,10 +148,6 @@ config 6xx depends on PPC32 && PPC_BOOK3S select PPC_HAVE_PMU_SUPPORT -# this is temp to handle compat with arch=ppc -config 8xx - bool - config E500 select FSL_EMB_PERFMON select PPC_FSL_BOOK3E @@ -271,44 +266,6 @@ config VSX If in doubt, say Y here. -config PPC_ICSWX - bool "Support for PowerPC icswx coprocessor instruction" - depends on PPC_BOOK3S_64 - default n - ---help--- - - This option enables kernel support for the PowerPC Initiate - Coprocessor Store Word (icswx) coprocessor instruction on POWER7 - and POWER8 processors. POWER9 uses new copy/paste instructions - to invoke the coprocessor. - - This option is only useful if you have a processor that supports - the icswx coprocessor instruction. It does not have any effect - on processors without the icswx coprocessor instruction. - - This option slightly increases kernel memory usage. - - If in doubt, say N here. - -config PPC_ICSWX_PID - bool "icswx requires direct PID management" - depends on PPC_ICSWX - default y - ---help--- - The PID register in server is used explicitly for ICSWX. In - embedded systems PID management is done by the system. - -config PPC_ICSWX_USE_SIGILL - bool "Should a bad CT cause a SIGILL?" - depends on PPC_ICSWX - default n - ---help--- - Should a bad CT used for "non-record form ICSWX" cause an - illegal instruction signal or should it be silent as - architected. - - If in doubt, say N here. - config SPE_POSSIBLE def_bool y depends on E200 || (E500 && !PPC_E500MC) @@ -413,7 +370,7 @@ config NR_CPUS config NOT_COHERENT_CACHE bool - depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON + depends on 4xx || PPC_8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON default n if PPC_47x default y diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 469ef170d218e24fadc665623787e70a7dbd39f8..d7a55ecfaee5e7fc7432154a4e34be721cfa7eb7 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o obj-$(CONFIG_PPC_PMAC) += powermac/ obj-$(CONFIG_PPC_CHRP) += chrp/ +obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_40x) += 40x/ obj-$(CONFIG_44x) += 44x/ obj-$(CONFIG_PPC_MPC512x) += 512x/ diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index 45cb9821173c6526b6b15423d1fbe9e0dd5840b3..b9d466cc2b8af79f27f307135b1c11637cf5fb7e 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -40,7 +40,7 @@ static int __init amigaone_add_bridge(struct device_node *dev) const int *bus_range; struct pci_controller *hose; - printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name); + printk(KERN_INFO "Adding PCI host bridge %pOF\n", dev); cfg_addr = of_get_address(dev, 0, NULL, NULL); cfg_data = of_get_address(dev, 1, NULL, NULL); @@ -49,8 +49,8 @@ static int __init amigaone_add_bridge(struct device_node *dev) bus_range = of_get_property(dev, "bus-range", &len); if ((bus_range == NULL) || (len < 2 * sizeof(int))) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); hose = pcibios_alloc_controller(dev); if (hose == NULL) diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 8d3ae2cc52bfb86145345065fed076574cd0bc35..6ea3f248b1558550bcde3df3d8749d7708c44a2c 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -187,8 +187,8 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev) irq_domain = irq_find_host(dn); if (!irq_domain) { - dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n", - dn->full_name); + dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %pOF\n", + dn); goto out_error; } @@ -326,8 +326,8 @@ static void axon_msi_shutdown(struct platform_device *device) struct axon_msic *msic = dev_get_drvdata(&device->dev); u32 tmp; - pr_devel("axon_msi: disabling %s\n", - irq_domain_get_of_node(msic->irq_domain)->full_name); + pr_devel("axon_msi: disabling %pOF\n", + irq_domain_get_of_node(msic->irq_domain)); tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; msic_dcr_write(msic, MSIC_CTRL_REG, tmp); @@ -340,12 +340,12 @@ static int axon_msi_probe(struct platform_device *device) unsigned int virq; int dcr_base, dcr_len; - pr_devel("axon_msi: setting up dn %s\n", dn->full_name); + pr_devel("axon_msi: setting up dn %pOF\n", dn); msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL); if (!msic) { - printk(KERN_ERR "axon_msi: couldn't allocate msic for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: couldn't allocate msic for %pOF\n", + dn); goto out; } @@ -354,30 +354,30 @@ static int axon_msi_probe(struct platform_device *device) if (dcr_base == 0 || dcr_len == 0) { printk(KERN_ERR - "axon_msi: couldn't parse dcr properties on %s\n", - dn->full_name); + "axon_msi: couldn't parse dcr properties on %pOF\n", + dn); goto out_free_msic; } msic->dcr_host = dcr_map(dn, dcr_base, dcr_len); if (!DCR_MAP_OK(msic->dcr_host)) { - printk(KERN_ERR "axon_msi: dcr_map failed for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: dcr_map failed for %pOF\n", + dn); goto out_free_msic; } msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, &msic->fifo_phys, GFP_KERNEL); if (!msic->fifo_virt) { - printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: couldn't allocate fifo for %pOF\n", + dn); goto out_free_msic; } virq = irq_of_parse_and_map(dn, 0); if (!virq) { - printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: irq parse and map failed for %pOF\n", + dn); goto out_free_fifo; } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); @@ -385,8 +385,8 @@ static int axon_msi_probe(struct platform_device *device) /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); if (!msic->irq_domain) { - printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %pOF\n", + dn); goto out_free_fifo; } @@ -412,7 +412,7 @@ static int axon_msi_probe(struct platform_device *device) axon_msi_debug_setup(dn, msic); - printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); + printk(KERN_DEBUG "axon_msi: setup MSIC on %pOF\n", dn); return 0; diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 871d38479a25234a0a33358ac41d52b88f3a9474..6fc85e29dc082a5a00a79298dc768acf9b99f0bd 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -303,8 +303,8 @@ static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr, iic->node = of_node_get(node); out_be64(&iic->regs->prio, 0); - printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n", - hw_cpu, iic->target_id, node->full_name); + printk(KERN_INFO "IIC for CPU %d target id 0x%x : %pOF\n", + hw_cpu, iic->target_id, node); } static int __init setup_iic(void) diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 29d4f96ed33ea5ee1bd3f721dc681bd5bc3fbb5f..4b91ad08eefd93767c5d40d445ae082fd42cf084 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -278,8 +278,8 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base) if (of_node_to_nid(np) != nid) continue; if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "iommu: can't get address for %s\n", - np->full_name); + printk(KERN_ERR "iommu: can't get address for %pOF\n", + np); continue; } *base = r.start; @@ -458,8 +458,8 @@ static inline u32 cell_iommu_get_ioid(struct device_node *np) ioid = of_get_property(np, "ioid", NULL); if (ioid == NULL) { - printk(KERN_WARNING "iommu: missing ioid for %s using 0\n", - np->full_name); + printk(KERN_WARNING "iommu: missing ioid for %pOF using 0\n", + np); return 0; } @@ -559,8 +559,8 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) */ iommu = cell_iommu_for_node(dev_to_node(dev)); if (iommu == NULL || list_empty(&iommu->windows)) { - dev_err(dev, "iommu: missing iommu for %s (node %d)\n", - of_node_full_name(dev->of_node), dev_to_node(dev)); + dev_err(dev, "iommu: missing iommu for %pOF (node %d)\n", + dev->of_node, dev_to_node(dev)); return NULL; } window = list_entry(iommu->windows.next, struct iommu_window, list); @@ -720,12 +720,12 @@ static struct cbe_iommu * __init cell_iommu_alloc(struct device_node *np) /* Get node ID */ nid = of_node_to_nid(np); if (nid < 0) { - printk(KERN_ERR "iommu: failed to get node for %s\n", - np->full_name); + printk(KERN_ERR "iommu: failed to get node for %pOF\n", + np); return NULL; } - pr_debug("iommu: setting up iommu for node %d (%s)\n", - nid, np->full_name); + pr_debug("iommu: setting up iommu for node %d (%pOF)\n", + nid, np); /* XXX todo: If we can have multiple windows on the same IOMMU, which * isn't the case today, we probably want here to check whether the @@ -736,8 +736,8 @@ static struct cbe_iommu * __init cell_iommu_alloc(struct device_node *np) */ if (cbe_nr_iommus >= NR_IOMMUS) { - printk(KERN_ERR "iommu: too many IOMMUs detected ! (%s)\n", - np->full_name); + printk(KERN_ERR "iommu: too many IOMMUs detected ! (%pOF)\n", + np); return NULL; } diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 460ab392f0e791ff2c73d561ccd4c5b2fac92018..2f704afe9af3a038f3a18d5a339f56aa3594cbfc 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -196,8 +196,8 @@ static int __init cbe_ptcal_enable(void) for_each_node_by_type(np, "cpu") { const u32 *nid = of_get_property(np, "node-id", NULL); if (!nid) { - printk(KERN_ERR "%s: node %s is missing node-id?\n", - __func__, np->full_name); + printk(KERN_ERR "%s: node %pOF is missing node-id?\n", + __func__, np); continue; } cbe_ptcal_enable_on_node(*nid, order); diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index f1f7878893f3c79eb75418148fa57ebc132328f8..d1e61e273e64a8ba4e4eefc768c70698e94dc3f3 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -130,8 +130,8 @@ int __init spiderpci_iowa_init(struct iowa_bus *bus, void *data) struct resource r; unsigned long offset = (unsigned long)data; - pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%s)\n", - np->full_name); + pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%pOF)\n", + np); priv = kzalloc(sizeof(struct spiderpci_iowa_private), GFP_KERNEL); if (!priv) { diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index ff924af00e78eca8b492f8ebdeb559bac9551c9b..aa44bfc464677a3c3718d0f9e5febfb55b90a38a 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -323,8 +323,8 @@ static void __init spider_init_one(struct device_node *of_node, int chip, irq_set_handler_data(virq, pic); irq_set_chained_handler(virq, spider_irq_cascade); - printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %s\n", - pic->node_id, addr, of_node->full_name); + printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %pOF\n", + pic->node_id, addr, of_node); /* Enable the interrupt detection enable bit. Do this last! */ out_be32(pic->regs + TIR_DEN, in_be32(pic->regs + TIR_DEN) | 0x1); diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 672d310dcf14a1cf36e6849b18220b5510fd4720..f636ee22b20358097e6628c6e8ca7772d53ae9d2 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -191,8 +191,8 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) goto err; } ret = -EINVAL; - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.args[0], - oirq.np->full_name); + pr_debug(" irq %d no 0x%x on %pOF\n", i, oirq.args[0], + oirq.np); spu->irqs[i] = irq_create_of_mapping(&oirq); if (!spu->irqs[i]) { pr_debug("spu_new: failed to map it !\n"); @@ -243,32 +243,32 @@ static int __init spu_map_device(struct spu *spu) ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, &spu->local_store_phys); if (ret) { - pr_debug("spu_new: failed to map %s resource 0\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 0\n", + np); goto out; } ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, &spu->problem_phys); if (ret) { - pr_debug("spu_new: failed to map %s resource 1\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 1\n", + np); goto out_unmap; } ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); if (ret) { - pr_debug("spu_new: failed to map %s resource 2\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 2\n", + np); goto out_unmap; } if (!firmware_has_feature(FW_FEATURE_LPAR)) ret = spu_map_resource(spu, 3, (void __iomem**)&spu->priv1, NULL); if (ret) { - pr_debug("spu_new: failed to map %s resource 3\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 3\n", + np); goto out_unmap; } - pr_debug("spu_new: %s maps:\n", np->full_name); + pr_debug("spu_new: %pOF maps:\n", np); pr_debug(" local store : 0x%016lx -> 0x%p\n", spu->local_store_phys, spu->local_store); pr_debug(" problem state : 0x%016lx -> 0x%p\n", @@ -316,8 +316,8 @@ static int __init of_create_spu(struct spu *spu, void *data) spu->node = of_node_to_nid(spe); if (spu->node >= MAX_NUMNODES) { - printk(KERN_WARNING "SPE %s on node %d ignored," - " node number too big\n", spe->full_name, spu->node); + printk(KERN_WARNING "SPE %pOF on node %d ignored," + " node number too big\n", spe, spu->node); printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); ret = -ENODEV; goto out; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index ae2f740a82f1493df8a2e8283271d6bb09ac8836..5ffcdeb1eb17680cf9a02771a8248ef62fae34e0 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1749,7 +1749,7 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id) static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int datasync) { struct inode *inode = file_inode(file); - int err = filemap_write_and_wait_range(inode->i_mapping, start, end); + int err = file_write_and_wait_range(file, start, end); if (!err) { inode_lock(inode); err = spufs_mfc_flush(file, NULL); diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 1b87e198faa78c059fb853532564e55cf985a737..27264794f5c022f4faa2c5d00e61a766221fae03 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -235,14 +235,14 @@ chrp_find_bridges(void) ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ if (of_address_to_resource(dev, 0, &r) && !is_longtrail) { - printk(KERN_WARNING "Can't use %s: no address\n", - dev->full_name); + printk(KERN_WARNING "Can't use %pOF: no address\n", + dev); continue; } bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF\n", + dev); continue; } if (bus_range[1] == bus_range[0]) @@ -250,15 +250,15 @@ chrp_find_bridges(void) else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); - printk(" controlled by %s", dev->full_name); + printk(" controlled by %pOF", dev); if (!is_longtrail) printk(" at %llx", (unsigned long long)r.start); printk("\n"); hose = pcibios_alloc_controller(dev); if (!hose) { - printk("Can't allocate PCI controller structure for %s\n", - dev->full_name); + printk("Can't allocate PCI controller structure for %pOF\n", + dev); continue; } hose->first_busno = hose->self_busno = bus_range[0]; @@ -297,8 +297,8 @@ chrp_find_bridges(void) } } } else { - printk("No methods for %s (model %s), using RTAS\n", - dev->full_name, model); + printk("No methods for %pOF (model %s), using RTAS\n", + dev, model); hose->ops = &rtas_pci_ops; } diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 2b4dc6abde6ce30a3dda84bbc94ed91b2434f36f..19760712b39da3e1f3063c3046814a47e4ba3073 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -63,7 +63,7 @@ static struct platform_device mv643xx_eth_mvmdio_device = { .name = "orion-mdio", .id = -1, .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources), - .resource = mv643xx_eth_shared_resources, + .resource = mv643xx_eth_mvmdio_resources, }; static struct resource mv643xx_eth_port1_resources[] = { diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index f29cf29b11f895799740bd25cd7585024a9b840a..f514d5d28cd4fc7041a700bce0e699172932c6c8 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -41,12 +41,12 @@ static int __init linkstation_add_bridge(struct device_node *dev) struct pci_controller *hose; const int *bus_range; - printk("Adding PCI host bridge %s\n", dev->full_name); + printk("Adding PCI host bridge %pOF\n", dev); bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); hose = pcibios_alloc_controller(dev); if (hose == NULL) diff --git a/arch/powerpc/platforms/embedded6xx/mvme5100.c b/arch/powerpc/platforms/embedded6xx/mvme5100.c index 8e35909419602f3b3d97d4a03e280544641991f8..273dfa3f025263b2870a5f6ff106391539706f04 100644 --- a/arch/powerpc/platforms/embedded6xx/mvme5100.c +++ b/arch/powerpc/platforms/embedded6xx/mvme5100.c @@ -115,7 +115,7 @@ static int __init mvme5100_add_bridge(struct device_node *dev) struct pci_controller *hose; unsigned short devid; - pr_info("Adding PCI host bridge %s\n", dev->full_name); + pr_info("Adding PCI host bridge %pOF\n", dev); bus_range = of_get_property(dev, "bus-range", &len); diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index 471a50bcd074e6902b06e61ed24765e8b23bc576..ed1914dd34bba08c004d383e008785a3eb4d6189 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c @@ -44,7 +44,7 @@ static int __init storcenter_add_bridge(struct device_node *dev) struct pci_controller *hose; const int *bus_range; - printk("Adding PCI host bridge %s\n", dev->full_name); + printk("Adding PCI host bridge %pOF\n", dev); hose = pcibios_alloc_controller(dev); if (hose == NULL) diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 69794d9389c2b1f9d0e6d3a6fae46430fdc190f6..e3821379e86f38c7799602db8a9211c5afb1d46e 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -73,8 +73,8 @@ static void __init fixup_bus_range(struct device_node *bridge) /* Lookup the "bus-range" property for the hose */ prop = of_find_property(bridge, "bus-range", &len); if (prop == NULL || prop->value == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - bridge->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF\n", + bridge); return; } bus_range = prop->value; @@ -498,12 +498,12 @@ static int __init maple_add_bridge(struct device_node *dev) const int *bus_range; int primary = 1; - DBG("Adding PCI host bridge %s\n", dev->full_name); + DBG("Adding PCI host bridge %pOF\n", dev); bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", - dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume bus 0\n", + dev); } hose = pcibios_alloc_controller(dev); diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c index 10c4e8fc6ea9e4ecc64dfb78e9e441e50f6d85f4..5ff6108f19e98b125af9c0c2a17f0ecd118200d7 100644 --- a/arch/powerpc/platforms/pasemi/pci.c +++ b/arch/powerpc/platforms/pasemi/pci.c @@ -193,7 +193,7 @@ static int __init pas_add_bridge(struct device_node *dev) { struct pci_controller *hose; - pr_debug("Adding PCI host bridge %s\n", dev->full_name); + pr_debug("Adding PCI host bridge %pOF\n", dev); hose = pcibios_alloc_controller(dev); if (!hose) diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 1e02328c3f2d4d8c1bd45c7b5f074dc59f9641bd..9e3f39d36e88ff32dfd2c7585ef635ec2daf5e2d 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -2658,25 +2658,25 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ if (i >= MAX_MACIO_CHIPS) { printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); - printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); + printk(KERN_ERR "pmac_feature: %pOF skipped\n", node); return; } addrp = of_get_pci_address(node, 0, &size, NULL); if (addrp == NULL) { - printk(KERN_ERR "pmac_feature: %s: can't find base !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: %pOF: can't find base !\n", + node); return; } addr = of_translate_address(node, addrp); if (addr == 0) { - printk(KERN_ERR "pmac_feature: %s, can't translate base !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: %pOF, can't translate base !\n", + node); return; } base = ioremap(addr, (unsigned long)size); if (!base) { - printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: %pOF, can't map mac-io chip !\n", + node); return; } if (type == macio_keylargo || type == macio_keylargo2) { diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index f627c9fd7b485284c00f971daaa4f97e6dfc2615..70183eb3d5c89761c541672175ffaad1993c5982 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -494,8 +494,8 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); if (host == NULL) { - printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", - np->full_name); + printk(KERN_ERR "low_i2c: Can't allocate host for %pOF\n", + np); return NULL; } @@ -505,8 +505,8 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) */ addrp = of_get_property(np, "AAPL,address", NULL); if (addrp == NULL) { - printk(KERN_ERR "low_i2c: Can't find address for %s\n", - np->full_name); + printk(KERN_ERR "low_i2c: Can't find address for %pOF\n", + np); kfree(host); return NULL; } @@ -538,13 +538,13 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host->irq = irq_of_parse_and_map(np, 0); if (!host->irq) printk(KERN_WARNING - "low_i2c: Failed to map interrupt for %s\n", - np->full_name); + "low_i2c: Failed to map interrupt for %pOF\n", + np); host->base = ioremap((*addrp), 0x1000); if (host->base == NULL) { - printk(KERN_ERR "low_i2c: Can't map registers for %s\n", - np->full_name); + printk(KERN_ERR "low_i2c: Can't map registers for %pOF\n", + np); kfree(host); return NULL; } @@ -560,8 +560,8 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) "keywest i2c", host)) host->irq = 0; - printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", - *addrp, host->irq, np->full_name); + printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %pOF\n", + *addrp, host->irq, np); return host; } @@ -798,7 +798,7 @@ static void __init pmu_i2c_probe(void) if (busnode == NULL) return; - printk(KERN_INFO "PMU i2c %s\n", busnode->full_name); + printk(KERN_INFO "PMU i2c %pOF\n", busnode); /* * We add bus 1 and 2 only for now, bus 0 is "special" @@ -913,7 +913,7 @@ static void __init smu_i2c_probe(void) if (controller == NULL) return; - printk(KERN_INFO "SMU i2c %s\n", controller->full_name); + printk(KERN_INFO "SMU i2c %pOF\n", controller); /* Look for childs, note that they might not be of the right * type as older device trees mix i2c busses and other things @@ -945,8 +945,8 @@ static void __init smu_i2c_probe(void) bus->flags = 0; list_add(&bus->link, &pmac_i2c_busses); - printk(KERN_INFO " channel %x bus %s\n", - bus->channel, busnode->full_name); + printk(KERN_INFO " channel %x bus %pOF\n", + bus->channel, busnode); } } @@ -1129,7 +1129,7 @@ int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode) */ if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) { printk(KERN_ERR "low_i2c: Invalid mode %d requested on" - " bus %s !\n", mode, bus->busnode->full_name); + " bus %pOF !\n", mode, bus->busnode); return -EINVAL; } bus->mode = mode; @@ -1146,8 +1146,8 @@ int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, WARN_ON(!bus->opened); DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x," - " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize, - subaddr, len, bus->busnode->full_name); + " %d bytes, bus %pOF\n", bus->channel, addrdir, bus->mode, subsize, + subaddr, len, bus->busnode); rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len); @@ -1241,13 +1241,13 @@ static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args) bus = pmac_i2c_find_bus(func->node); if (bus == NULL) { - printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n", - func->node->full_name); + printk(KERN_ERR "low_i2c: Can't find bus for %pOF (pfunc)\n", + func->node); return NULL; } if (pmac_i2c_open(bus, 0)) { - printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n", - func->node->full_name); + printk(KERN_ERR "low_i2c: Can't open i2c bus for %pOF (pfunc)\n", + func->node); return NULL; } @@ -1417,7 +1417,7 @@ static struct pmf_handlers pmac_i2c_pfunc_handlers = { static void __init pmac_i2c_dev_create(struct device_node *np, int quirks) { - DBG("dev_create(%s)\n", np->full_name); + DBG("dev_create(%pOF)\n", np); pmf_register_driver(np, &pmac_i2c_pfunc_handlers, (void *)(long)quirks); @@ -1425,20 +1425,20 @@ static void __init pmac_i2c_dev_create(struct device_node *np, int quirks) static void __init pmac_i2c_dev_init(struct device_node *np, int quirks) { - DBG("dev_create(%s)\n", np->full_name); + DBG("dev_create(%pOF)\n", np); pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL); } static void pmac_i2c_dev_suspend(struct device_node *np, int quirks) { - DBG("dev_suspend(%s)\n", np->full_name); + DBG("dev_suspend(%pOF)\n", np); pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL); } static void pmac_i2c_dev_resume(struct device_node *np, int quirks) { - DBG("dev_resume(%s)\n", np->full_name); + DBG("dev_resume(%pOF)\n", np); pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL); } diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 6e06c3be2e9ac4e3c60951722dc7712d3f53193e..0b8174a799937b7a11e84a56a95c5ff163e10901 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -783,7 +783,7 @@ static int __init pmac_add_bridge(struct device_node *dev) const int *bus_range; int primary = 1, has_address = 0; - DBG("Adding PCI host bridge %s\n", dev->full_name); + DBG("Adding PCI host bridge %pOF\n", dev); /* Fetch host bridge registers address */ has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); @@ -791,8 +791,8 @@ static int __init pmac_add_bridge(struct device_node *dev) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); } hose = pcibios_alloc_controller(dev); diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c index 459138ed4571311772e4f4e8b58566714612a756..860159d46ab826844a1ac8e158e8e66df34fc5f2 100644 --- a/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/arch/powerpc/platforms/powermac/pfunc_base.c @@ -54,8 +54,8 @@ static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask) raw_spin_lock_irqsave(&feature_lock, flags); tmp = readb(addr); tmp = (tmp & ~mask) | (value & mask); - DBG("Do write 0x%02x to GPIO %s (%p)\n", - tmp, func->node->full_name, addr); + DBG("Do write 0x%02x to GPIO %pOF (%p)\n", + tmp, func->node, addr); writeb(tmp, addr); raw_spin_unlock_irqrestore(&feature_lock, flags); @@ -107,8 +107,8 @@ static void macio_gpio_init_one(struct macio_chip *macio) if (gparent == NULL) return; - DBG("Installing GPIO functions for macio %s\n", - macio->of_node->full_name); + DBG("Installing GPIO functions for macio %pOF\n", + macio->of_node); /* * Ok, got one, we dont need anything special to track them down, so @@ -129,8 +129,8 @@ static void macio_gpio_init_one(struct macio_chip *macio) pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset); } - DBG("Calling initial GPIO functions for macio %s\n", - macio->of_node->full_name); + DBG("Calling initial GPIO functions for macio %pOF\n", + macio->of_node); /* And now we run all the init ones */ for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) @@ -267,8 +267,8 @@ static struct pmf_handlers macio_mmio_handlers = { static void macio_mmio_init_one(struct macio_chip *macio) { - DBG("Installing MMIO functions for macio %s\n", - macio->of_node->full_name); + DBG("Installing MMIO functions for macio %pOF\n", + macio->of_node); pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio); } @@ -298,8 +298,8 @@ static void uninorth_install_pfunc(void) { struct device_node *np; - DBG("Installing functions for UniN %s\n", - uninorth_node->full_name); + DBG("Installing functions for UniN %pOF\n", + uninorth_node); /* * Install handlers for the bridge itself @@ -317,8 +317,8 @@ static void uninorth_install_pfunc(void) break; } if (unin_hwclock) { - DBG("Installing functions for UniN clock %s\n", - unin_hwclock->full_name); + DBG("Installing functions for UniN clock %pOF\n", + unin_hwclock); pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL); pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT, NULL); diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 695e8c4d4224de4ebbae3d0c4e1616b6d5b21456..df3c93bef228b6fa73ae4a72288f97d16e258c0e 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -708,7 +708,7 @@ int pmf_register_driver(struct device_node *np, if (handlers == NULL) return -EINVAL; - DBG("pmf: registering driver for node %s\n", np->full_name); + DBG("pmf: registering driver for node %pOF\n", np); spin_lock_irqsave(&pmf_lock, flags); dev = pmf_find_device(np); @@ -781,7 +781,7 @@ void pmf_unregister_driver(struct device_node *np) struct pmf_device *dev; unsigned long flags; - DBG("pmf: unregistering driver for node %s\n", np->full_name); + DBG("pmf: unregistering driver for node %pOF\n", np); spin_lock_irqsave(&pmf_lock, flags); dev = pmf_find_device(np); @@ -940,7 +940,7 @@ int pmf_call_one(struct pmf_function *func, struct pmf_args *args) void *instdata = NULL; int rc = 0; - DBG(" ** pmf_call_one(%s/%s) **\n", dev->node->full_name, func->name); + DBG(" ** pmf_call_one(%pOF/%s) **\n", dev->node, func->name); if (dev->handlers->begin) instdata = dev->handlers->begin(func, args); diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index f5f9ad7c339875fdbc5bcc2cc2129a640821bd6e..5e0719b2729488feff62f46ce1b03e6295b090e9 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -364,8 +364,8 @@ static void __init pmac_pic_probe_oldstyle(void) (addr + 0x10); of_node_put(master); - printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n", - master->full_name, max_real_irqs); + printk(KERN_INFO "irq: Found primary Apple PIC %pOF for %d irqs\n", + master, max_real_irqs); /* Map interrupts of cascaded controller */ if (slave && !of_address_to_resource(slave, 0, &r)) { @@ -378,8 +378,8 @@ static void __init pmac_pic_probe_oldstyle(void) (addr + 0x10); pmac_irq_cascade = irq_of_parse_and_map(slave, 0); - printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs" - " cascade: %d\n", slave->full_name, + printk(KERN_INFO "irq: Found slave Apple PIC %pOF for %d irqs" + " cascade: %d\n", slave, max_irqs - max_real_irqs, pmac_irq_cascade); } of_node_put(slave); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 6b4e9d1811262f5dc0687af9771cff10639f7a0e..ab668cb72263ce69da918e712183c3083d2140d9 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -556,7 +556,7 @@ static int __init check_pmac_serial_console(void) pr_debug(" can't find stdout package %s !\n", name); return -ENODEV; } - pr_debug("stdout is %s\n", prom_stdout->full_name); + pr_debug("stdout is %pOF\n", prom_stdout); name = of_get_property(prom_stdout, "name", NULL); if (!name) { diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index 6a6f4ef46b9e5e0123352e4c1c9f13a7a749c5e6..340cbe263b333490ba59e67a0a28cb609bd327dd 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig @@ -30,3 +30,25 @@ config OPAL_PRD help This enables the opal-prd driver, a facility to run processor recovery diagnostics on OpenPower machines + +config PPC_MEMTRACE + bool "Enable removal of RAM from kernel mappings for tracing" + depends on PPC_POWERNV && MEMORY_HOTREMOVE + default n + help + Enabling this option allows for the removal of memory (RAM) + from the kernel mappings to be used for hardware tracing. + +config PPC_VAS + bool "IBM Virtual Accelerator Switchboard (VAS)" + depends on PPC_POWERNV && PPC_64K_PAGES + default y + help + This enables support for IBM Virtual Accelerator Switchboard (VAS). + + VAS allows accelerators in co-processors like NX-GZIP and NX-842 + to be accessible to kernel subsystems and user processes. + + VAS adapters are found in POWER9 based systems. + + If unsure, say N. diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb3f4826c1ab0c88b794234a6f3d306ff1e..37d60f7dd86d939b2ae991cfed9e0bce7c335fd6 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-powercap.o opal-psr.o opal-sensor-groups.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o @@ -12,3 +12,6 @@ obj-$(CONFIG_PPC_SCOM) += opal-xscom.o obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o obj-$(CONFIG_TRACEPOINTS) += opal-tracepoints.o obj-$(CONFIG_OPAL_PRD) += opal-prd.o +obj-$(CONFIG_PERF_EVENTS) += opal-imc.o +obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o +obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o diff --git a/arch/powerpc/platforms/powernv/copy-paste.h b/arch/powerpc/platforms/powernv/copy-paste.h new file mode 100644 index 0000000000000000000000000000000000000000..c9a50362343107b079875233faac064301435084 --- /dev/null +++ b/arch/powerpc/platforms/powernv/copy-paste.h @@ -0,0 +1,46 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include + +#define CR0_SHIFT 28 +#define CR0_MASK 0xF +/* + * Copy/paste instructions: + * + * copy RA,RB + * Copy contents of address (RA) + effective_address(RB) + * to internal copy-buffer. + * + * paste RA,RB + * Paste contents of internal copy-buffer to the address + * (RA) + effective_address(RB) + */ +static inline int vas_copy(void *crb, int offset) +{ + asm volatile(PPC_COPY(%0, %1)";" + : + : "b" (offset), "b" (crb) + : "memory"); + + return 0; +} + +static inline int vas_paste(void *paste_address, int offset) +{ + u32 cr; + + cr = 0; + asm volatile(PPC_PASTE(%1, %2)";" + "mfocrf %0, 0x80;" + : "=r" (cr) + : "b" (offset), "b" (paste_address) + : "memory", "cr0"); + + return (cr >> CR0_SHIFT) & CR0_MASK; +} diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 3f48f6df1cf3937e1f854f9d2bfcb84e27f946c6..8864065eba227cf9b8f9972f8adff00f842b639f 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -113,7 +113,6 @@ static ssize_t pnv_eeh_ei_write(struct file *filp, size_t count, loff_t *ppos) { struct pci_controller *hose = filp->private_data; - struct eeh_dev *edev; struct eeh_pe *pe; int pe_no, type, func; unsigned long addr, mask; @@ -135,13 +134,7 @@ static ssize_t pnv_eeh_ei_write(struct file *filp, return -EINVAL; /* Retrieve PE */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); - if (!edev) - return -ENOMEM; - edev->phb = hose; - edev->pe_config_addr = pe_no; - pe = eeh_pe_get(edev); - kfree(edev); + pe = eeh_pe_get(hose, pe_no, 0); if (!pe) return -ENODEV; @@ -359,6 +352,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) struct eeh_dev *edev = pdn_to_eeh_dev(pdn); uint32_t pcie_flags; int ret; + int config_addr = (pdn->busno << 8) | (pdn->devfn); /* * When probing the root bridge, which doesn't have any @@ -393,8 +387,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) } } - edev->config_addr = (pdn->busno << 8) | (pdn->devfn); - edev->pe_config_addr = phb->ioda.pe_rmap[edev->config_addr]; + edev->pe_config_addr = phb->ioda.pe_rmap[config_addr]; /* Create PE */ ret = eeh_add_to_parent_pe(edev); @@ -933,7 +926,6 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev) static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type, int pos, u16 mask) { - struct eeh_dev *edev = pdn_to_eeh_dev(pdn); int i, status = 0; /* Wait for Transaction Pending bit to be cleared */ @@ -947,7 +939,7 @@ static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type, pr_warn("%s: Pending transaction while issuing %sFLR to %04x:%02x:%02x.%01x\n", __func__, type, - edev->phb->global_number, pdn->busno, + pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); } @@ -1381,7 +1373,6 @@ static int pnv_eeh_get_pe(struct pci_controller *hose, struct pnv_phb *phb = hose->private_data; struct pnv_ioda_pe *pnv_pe; struct eeh_pe *dev_pe; - struct eeh_dev edev; /* * If PHB supports compound PE, to fetch @@ -1397,10 +1388,7 @@ static int pnv_eeh_get_pe(struct pci_controller *hose, } /* Find the PE according to PE# */ - memset(&edev, 0, sizeof(struct eeh_dev)); - edev.phb = hose; - edev.pe_config_addr = pe_no; - dev_pe = eeh_pe_get(&edev); + dev_pe = eeh_pe_get(hose, pe_no, 0); if (!dev_pe) return -EEXIST; @@ -1711,6 +1699,7 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn) struct eeh_dev *edev = pdn_to_eeh_dev(pdn); struct pnv_phb *phb; s64 ret; + int config_addr = (pdn->busno << 8) | (pdn->devfn); if (!edev) return -EEXIST; @@ -1725,14 +1714,14 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn) if (edev->physfn) { ret = pnv_eeh_restore_vf_config(pdn); } else { - phb = edev->phb->private_data; + phb = pdn->phb->private_data; ret = opal_pci_reinit(phb->opal_id, - OPAL_REINIT_PCI_DEV, edev->config_addr); + OPAL_REINIT_PCI_DEV, config_addr); } if (ret) { pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", - __func__, edev->config_addr, ret); + __func__, config_addr, ret); return -EIO; } diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 2abee070373fb3a8b757b8d3cb269e5d0b89dff6..443d5ca719958e5170374edbcaaf7d2cc52b8104 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -56,6 +56,7 @@ u64 pnv_first_deep_stop_state = MAX_STOP_STATE; */ static u64 pnv_deepest_stop_psscr_val; static u64 pnv_deepest_stop_psscr_mask; +static u64 pnv_deepest_stop_flag; static bool deepest_stop_found; static int pnv_save_sprs_for_deep_states(void) @@ -68,7 +69,7 @@ static int pnv_save_sprs_for_deep_states(void) * all cpus at boot. Get these reg values of current cpu and use the * same across all cpus. */ - uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; + uint64_t lpcr_val = mfspr(SPRN_LPCR); uint64_t hid0_val = mfspr(SPRN_HID0); uint64_t hid1_val = mfspr(SPRN_HID1); uint64_t hid4_val = mfspr(SPRN_HID4); @@ -185,8 +186,40 @@ static void pnv_alloc_idle_core_states(void) update_subcore_sibling_mask(); - if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) - pnv_save_sprs_for_deep_states(); + if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) { + int rc = pnv_save_sprs_for_deep_states(); + + if (likely(!rc)) + return; + + /* + * The stop-api is unable to restore hypervisor + * resources on wakeup from platform idle states which + * lose full context. So disable such states. + */ + supported_cpuidle_states &= ~OPAL_PM_LOSE_FULL_CONTEXT; + pr_warn("cpuidle-powernv: Disabling idle states that lose full context\n"); + pr_warn("cpuidle-powernv: Idle power-savings, CPU-Hotplug affected\n"); + + if (cpu_has_feature(CPU_FTR_ARCH_300) && + (pnv_deepest_stop_flag & OPAL_PM_LOSE_FULL_CONTEXT)) { + /* + * Use the default stop state for CPU-Hotplug + * if available. + */ + if (default_stop_found) { + pnv_deepest_stop_psscr_val = + pnv_default_stop_val; + pnv_deepest_stop_psscr_mask = + pnv_default_stop_mask; + pr_warn("cpuidle-powernv: Offlined CPUs will stop with psscr = 0x%016llx\n", + pnv_deepest_stop_psscr_val); + } else { /* Fallback to snooze loop for CPU-Hotplug */ + deepest_stop_found = false; + pr_warn("cpuidle-powernv: Offlined CPUs will busy wait\n"); + } + } + } } u32 pnv_get_supported_cpuidle_states(void) @@ -355,6 +388,20 @@ void power9_idle(void) } #ifdef CONFIG_HOTPLUG_CPU +static void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val) +{ + u64 pir = get_hard_smp_processor_id(cpu); + + mtspr(SPRN_LPCR, lpcr_val); + + /* + * Program the LPCR via stop-api only if the deepest stop state + * can lose hypervisor context. + */ + if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) + opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val); +} + /* * pnv_cpu_offline: A function that puts the CPU into the deepest * available platform idle state on a CPU-Offline. @@ -364,6 +411,20 @@ unsigned long pnv_cpu_offline(unsigned int cpu) { unsigned long srr1; u32 idle_states = pnv_get_supported_cpuidle_states(); + u64 lpcr_val; + + /* + * We don't want to take decrementer interrupts while we are + * offline, so clear LPCR:PECE1. We keep PECE2 (and + * LPCR_PECE_HVEE on P9) enabled as to let IPIs in. + * + * If the CPU gets woken up by a special wakeup, ensure that + * the SLW engine sets LPCR with decrementer bit cleared, else + * the CPU will come back to the kernel due to a spurious + * wakeup. + */ + lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; + pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val); __ppc64_runlatch_off(); @@ -375,7 +436,8 @@ unsigned long pnv_cpu_offline(unsigned int cpu) pnv_deepest_stop_psscr_val; srr1 = power9_idle_stop(psscr); - } else if (idle_states & OPAL_PM_WINKLE_ENABLED) { + } else if ((idle_states & OPAL_PM_WINKLE_ENABLED) && + (idle_states & OPAL_PM_LOSE_FULL_CONTEXT)) { srr1 = power7_idle_insn(PNV_THREAD_WINKLE); } else if ((idle_states & OPAL_PM_SLEEP_ENABLED) || (idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) { @@ -394,6 +456,16 @@ unsigned long pnv_cpu_offline(unsigned int cpu) __ppc64_runlatch_on(); + /* + * Re-enable decrementer interrupts in LPCR. + * + * Further, we want stop states to be woken up by decrementer + * for non-hotplug cases. So program the LPCR via stop api as + * well. + */ + lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1; + pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val); + return srr1; } #endif @@ -553,6 +625,7 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, max_residency_ns = residency_ns[i]; pnv_deepest_stop_psscr_val = psscr_val[i]; pnv_deepest_stop_psscr_mask = psscr_mask[i]; + pnv_deepest_stop_flag = flags[i]; deepest_stop_found = true; } diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c new file mode 100644 index 0000000000000000000000000000000000000000..de470caf07848e28864cbb8ff0129e4ed7aaf021 --- /dev/null +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) IBM Corporation, 2014, 2017 + * Anton Blanchard, Rashmica Gupta. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#define pr_fmt(fmt) "memtrace: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This enables us to keep track of the memory removed from each node. */ +struct memtrace_entry { + void *mem; + u64 start; + u64 size; + u32 nid; + struct dentry *dir; + char name[16]; +}; + +static u64 memtrace_size; + +static struct memtrace_entry *memtrace_array; +static unsigned int memtrace_array_nr; + + +static ssize_t memtrace_read(struct file *filp, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct memtrace_entry *ent = filp->private_data; + + return simple_read_from_buffer(ubuf, count, ppos, ent->mem, ent->size); +} + +static bool valid_memtrace_range(struct memtrace_entry *dev, + unsigned long start, unsigned long size) +{ + if ((start >= dev->start) && + ((start + size) <= (dev->start + dev->size))) + return true; + + return false; +} + +static int memtrace_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long size = vma->vm_end - vma->vm_start; + struct memtrace_entry *dev = filp->private_data; + + if (!valid_memtrace_range(dev, vma->vm_pgoff << PAGE_SHIFT, size)) + return -EINVAL; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff + (dev->start >> PAGE_SHIFT), + size, vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} + +static const struct file_operations memtrace_fops = { + .llseek = default_llseek, + .read = memtrace_read, + .mmap = memtrace_mmap, + .open = simple_open, +}; + +static void flush_memory_region(u64 base, u64 size) +{ + unsigned long line_size = ppc64_caches.l1d.size; + u64 end = base + size; + u64 addr; + + base = round_down(base, line_size); + end = round_up(end, line_size); + + for (addr = base; addr < end; addr += line_size) + asm volatile("dcbf 0,%0" : "=r" (addr) :: "memory"); +} + +static int check_memblock_online(struct memory_block *mem, void *arg) +{ + if (mem->state != MEM_ONLINE) + return -1; + + return 0; +} + +static int change_memblock_state(struct memory_block *mem, void *arg) +{ + unsigned long state = (unsigned long)arg; + + mem->state = state; + + return 0; +} + +static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages) +{ + u64 end_pfn = start_pfn + nr_pages - 1; + + if (walk_memory_range(start_pfn, end_pfn, NULL, + check_memblock_online)) + return false; + + walk_memory_range(start_pfn, end_pfn, (void *)MEM_GOING_OFFLINE, + change_memblock_state); + + if (offline_pages(start_pfn, nr_pages)) { + walk_memory_range(start_pfn, end_pfn, (void *)MEM_ONLINE, + change_memblock_state); + return false; + } + + walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE, + change_memblock_state); + + /* RCU grace period? */ + flush_memory_region((u64)__va(start_pfn << PAGE_SHIFT), + nr_pages << PAGE_SHIFT); + + lock_device_hotplug(); + remove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT); + unlock_device_hotplug(); + + return true; +} + +static u64 memtrace_alloc_node(u32 nid, u64 size) +{ + u64 start_pfn, end_pfn, nr_pages; + u64 base_pfn; + + if (!NODE_DATA(nid) || !node_spanned_pages(nid)) + return 0; + + start_pfn = node_start_pfn(nid); + end_pfn = node_end_pfn(nid); + nr_pages = size >> PAGE_SHIFT; + + /* Trace memory needs to be aligned to the size */ + end_pfn = round_down(end_pfn - nr_pages, nr_pages); + + for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) { + if (memtrace_offline_pages(nid, base_pfn, nr_pages) == true) + return base_pfn << PAGE_SHIFT; + } + + return 0; +} + +static int memtrace_init_regions_runtime(u64 size) +{ + u32 nid; + u64 m; + + memtrace_array = kcalloc(num_online_nodes(), + sizeof(struct memtrace_entry), GFP_KERNEL); + if (!memtrace_array) { + pr_err("Failed to allocate memtrace_array\n"); + return -EINVAL; + } + + for_each_online_node(nid) { + m = memtrace_alloc_node(nid, size); + + /* + * A node might not have any local memory, so warn but + * continue on. + */ + if (!m) { + pr_err("Failed to allocate trace memory on node %d\n", nid); + continue; + } + + pr_info("Allocated trace memory on node %d at 0x%016llx\n", nid, m); + + memtrace_array[memtrace_array_nr].start = m; + memtrace_array[memtrace_array_nr].size = size; + memtrace_array[memtrace_array_nr].nid = nid; + memtrace_array_nr++; + } + + return 0; +} + +static struct dentry *memtrace_debugfs_dir; + +static int memtrace_init_debugfs(void) +{ + int ret = 0; + int i; + + for (i = 0; i < memtrace_array_nr; i++) { + struct dentry *dir; + struct memtrace_entry *ent = &memtrace_array[i]; + + ent->mem = ioremap(ent->start, ent->size); + /* Warn but continue on */ + if (!ent->mem) { + pr_err("Failed to map trace memory at 0x%llx\n", + ent->start); + ret = -1; + continue; + } + + snprintf(ent->name, 16, "%08x", ent->nid); + dir = debugfs_create_dir(ent->name, memtrace_debugfs_dir); + if (!dir) + return -1; + + ent->dir = dir; + debugfs_create_file("trace", 0400, dir, ent, &memtrace_fops); + debugfs_create_x64("start", 0400, dir, &ent->start); + debugfs_create_x64("size", 0400, dir, &ent->size); + } + + return ret; +} + +static int memtrace_enable_set(void *data, u64 val) +{ + if (memtrace_size) + return -EINVAL; + + if (!val) + return -EINVAL; + + /* Make sure size is aligned to a memory block */ + if (val & (memory_block_size_bytes() - 1)) + return -EINVAL; + + if (memtrace_init_regions_runtime(val)) + return -EINVAL; + + if (memtrace_init_debugfs()) + return -EINVAL; + + memtrace_size = val; + + return 0; +} + +static int memtrace_enable_get(void *data, u64 *val) +{ + *val = memtrace_size; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(memtrace_init_fops, memtrace_enable_get, + memtrace_enable_set, "0x%016llx\n"); + +static int memtrace_init(void) +{ + memtrace_debugfs_dir = debugfs_create_dir("memtrace", + powerpc_debugfs_root); + if (!memtrace_debugfs_dir) + return -1; + + debugfs_create_file("enable", 0600, memtrace_debugfs_dir, + NULL, &memtrace_init_fops); + + return 0; +} +machine_device_initcall(powernv, memtrace_init); diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index b5d960d6db3d0b18d33273b31ac67e03caebd02b..2cb6cbea4b3b377329803a1a825360c60df10835 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -545,6 +545,12 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; unsigned long pid = npu_context->mm->context.id; + /* + * Unfortunately the nest mmu does not support flushing specific + * addresses so we have to flush the whole mm. + */ + flush_tlb_mm(npu_context->mm); + /* * Loop over all the NPUs this process is active on and launch * an invalidate. @@ -576,12 +582,6 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, } } - /* - * Unfortunately the nest mmu does not support flushing specific - * addresses so we have to flush the whole mm. - */ - flush_tlb_mm(npu_context->mm); - mmio_invalidate_wait(mmio_atsd_reg, flush); if (flush) /* Wait for the flush to complete */ @@ -614,15 +614,6 @@ static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn, mmio_invalidate(npu_context, 1, address, true); } -static void pnv_npu2_mn_invalidate_page(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long address) -{ - struct npu_context *npu_context = mn_to_npu_context(mn); - - mmio_invalidate(npu_context, 1, address, true); -} - static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long start, unsigned long end) @@ -640,7 +631,6 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, static const struct mmu_notifier_ops nv_nmmu_notifier_ops = { .release = pnv_npu2_mn_release, .change_pte = pnv_npu2_mn_change_pte, - .invalidate_page = pnv_npu2_mn_invalidate_page, .invalidate_range = pnv_npu2_mn_invalidate_range, }; diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c index 83bebeec0fea58de5babedeceb8714e66fcec635..cf33769a7b725253c74d1eb85de885b6cb35a16c 100644 --- a/arch/powerpc/platforms/powernv/opal-async.c +++ b/arch/powerpc/platforms/powernv/opal-async.c @@ -171,8 +171,8 @@ int __init opal_async_comp_init(void) async = of_get_property(opal_node, "opal-msg-async-num", NULL); if (!async) { - pr_err("%s: %s has no opal-msg-async-num\n", - __func__, opal_node->full_name); + pr_err("%s: %pOF has no opal-msg-async-num\n", + __func__, opal_node); err = -ENOENT; goto out_opal_node; } diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index 4ec6219287fc3a0caba84d9f07cbd978e4ffe825..2fa3ac80cb4e5c002ae17b1382e2d278282363e0 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c @@ -520,7 +520,7 @@ static ssize_t image_data_write(struct file *filp, struct kobject *kobj, * update_flash : Flash new firmware image * */ -static struct bin_attribute image_data_attr = { +static const struct bin_attribute image_data_attr = { .attr = {.name = "image", .mode = 0200}, .size = MAX_IMAGE_SIZE, /* Limit image size */ .write = image_data_write, diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index 88f3c61eec9513887a681d3d0551006c61753b1b..d78fed728cdf307d12c43ec058a54edd4101f5f4 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c @@ -30,6 +30,8 @@ #include #include +#include "powernv.h" + static int opal_hmi_handler_nb_init; struct OpalHmiEvtNode { struct list_head list; @@ -267,8 +269,6 @@ static void hmi_event_handler(struct work_struct *work) spin_unlock_irqrestore(&opal_hmi_evt_lock, flags); if (unrecoverable) { - int ret; - /* Pull all HMI events from OPAL before we panic. */ while (opal_get_msg(__pa(&msg), sizeof(msg)) == OPAL_SUCCESS) { u32 type; @@ -284,23 +284,7 @@ static void hmi_event_handler(struct work_struct *work) print_hmi_event_info(hmi_evt); } - /* - * Unrecoverable HMI exception. We need to inform BMC/OCC - * about this error so that it can collect relevant data - * for error analysis before rebooting. - */ - ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, - "Unrecoverable HMI exception"); - if (ret == OPAL_UNSUPPORTED) { - pr_emerg("Reboot type %d not supported\n", - OPAL_REBOOT_PLATFORM_ERROR); - } - - /* - * Fall through and panic if opal_cec_reboot2() returns - * OPAL_UNSUPPORTED. - */ - panic("Unrecoverable HMI exception"); + pnv_platform_error_reboot(NULL, "Unrecoverable HMI exception"); } } diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c new file mode 100644 index 0000000000000000000000000000000000000000..21f6531fae20fc1e010f499923cde964540b895a --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -0,0 +1,226 @@ +/* + * OPAL IMC interface detection driver + * Supported on POWERNV platform + * + * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation. + * (C) 2017 Anju T Sudhakar, IBM Corporation. + * (C) 2017 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * imc_get_mem_addr_nest: Function to get nest counter memory region + * for each chip + */ +static int imc_get_mem_addr_nest(struct device_node *node, + struct imc_pmu *pmu_ptr, + u32 offset) +{ + int nr_chips = 0, i; + u64 *base_addr_arr, baddr; + u32 *chipid_arr; + + nr_chips = of_property_count_u32_elems(node, "chip-id"); + if (nr_chips <= 0) + return -ENODEV; + + base_addr_arr = kcalloc(nr_chips, sizeof(u64), GFP_KERNEL); + if (!base_addr_arr) + return -ENOMEM; + + chipid_arr = kcalloc(nr_chips, sizeof(u32), GFP_KERNEL); + if (!chipid_arr) + return -ENOMEM; + + if (of_property_read_u32_array(node, "chip-id", chipid_arr, nr_chips)) + goto error; + + if (of_property_read_u64_array(node, "base-addr", base_addr_arr, + nr_chips)) + goto error; + + pmu_ptr->mem_info = kcalloc(nr_chips, sizeof(struct imc_mem_info), + GFP_KERNEL); + if (!pmu_ptr->mem_info) + goto error; + + for (i = 0; i < nr_chips; i++) { + pmu_ptr->mem_info[i].id = chipid_arr[i]; + baddr = base_addr_arr[i] + offset; + pmu_ptr->mem_info[i].vbase = phys_to_virt(baddr); + } + + pmu_ptr->imc_counter_mmaped = true; + kfree(base_addr_arr); + kfree(chipid_arr); + return 0; + +error: + kfree(pmu_ptr->mem_info); + kfree(base_addr_arr); + kfree(chipid_arr); + return -1; +} + +/* + * imc_pmu_create : Takes the parent device which is the pmu unit, pmu_index + * and domain as the inputs. + * Allocates memory for the struct imc_pmu, sets up its domain, size and offsets + */ +static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain) +{ + int ret = 0; + struct imc_pmu *pmu_ptr; + u32 offset; + + /* memory for pmu */ + pmu_ptr = kzalloc(sizeof(struct imc_pmu), GFP_KERNEL); + if (!pmu_ptr) + return -ENOMEM; + + /* Set the domain */ + pmu_ptr->domain = domain; + + ret = of_property_read_u32(parent, "size", &pmu_ptr->counter_mem_size); + if (ret) { + ret = -EINVAL; + goto free_pmu; + } + + if (!of_property_read_u32(parent, "offset", &offset)) { + if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) { + ret = -EINVAL; + goto free_pmu; + } + } + + /* Function to register IMC pmu */ + ret = init_imc_pmu(parent, pmu_ptr, pmu_index); + if (ret) + pr_err("IMC PMU %s Register failed\n", pmu_ptr->pmu.name); + + return 0; + +free_pmu: + kfree(pmu_ptr); + return ret; +} + +static void disable_nest_pmu_counters(void) +{ + int nid, cpu; + const struct cpumask *l_cpumask; + + get_online_cpus(); + for_each_online_node(nid) { + l_cpumask = cpumask_of_node(nid); + cpu = cpumask_first(l_cpumask); + opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(cpu)); + } + put_online_cpus(); +} + +static void disable_core_pmu_counters(void) +{ + cpumask_t cores_map; + int cpu, rc; + + get_online_cpus(); + /* Disable the IMC Core functions */ + cores_map = cpu_online_cores_map(); + for_each_cpu(cpu, &cores_map) { + rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(cpu)); + if (rc) + pr_err("%s: Failed to stop Core (cpu = %d)\n", + __FUNCTION__, cpu); + } + put_online_cpus(); +} + +static int opal_imc_counters_probe(struct platform_device *pdev) +{ + struct device_node *imc_dev = pdev->dev.of_node; + int pmu_count = 0, domain; + u32 type; + + /* + * Check whether this is kdump kernel. If yes, force the engines to + * stop and return. + */ + if (is_kdump_kernel()) { + disable_nest_pmu_counters(); + disable_core_pmu_counters(); + return -ENODEV; + } + + for_each_compatible_node(imc_dev, NULL, IMC_DTB_UNIT_COMPAT) { + if (of_property_read_u32(imc_dev, "type", &type)) { + pr_warn("IMC Device without type property\n"); + continue; + } + + switch (type) { + case IMC_TYPE_CHIP: + domain = IMC_DOMAIN_NEST; + break; + case IMC_TYPE_CORE: + domain =IMC_DOMAIN_CORE; + break; + case IMC_TYPE_THREAD: + domain = IMC_DOMAIN_THREAD; + break; + default: + pr_warn("IMC Unknown Device type \n"); + domain = -1; + break; + } + + if (!imc_pmu_create(imc_dev, pmu_count, domain)) + pmu_count++; + } + + return 0; +} + +static void opal_imc_counters_shutdown(struct platform_device *pdev) +{ + /* + * Function only stops the engines which is bare minimum. + * TODO: Need to handle proper memory cleanup and pmu + * unregister. + */ + disable_nest_pmu_counters(); + disable_core_pmu_counters(); +} + +static const struct of_device_id opal_imc_match[] = { + { .compatible = IMC_DTB_COMPAT }, + {}, +}; + +static struct platform_driver opal_imc_driver = { + .driver = { + .name = "opal-imc-counters", + .of_match_table = opal_imc_match, + }, + .probe = opal_imc_counters_probe, + .shutdown = opal_imc_counters_shutdown, +}; + +builtin_platform_driver(opal_imc_driver); diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c new file mode 100644 index 0000000000000000000000000000000000000000..badb29bde93f818d92ecc2ce0d64530f3e63410a --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-powercap.c @@ -0,0 +1,244 @@ +/* + * PowerNV OPAL Powercap interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-powercap: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(powercap_mutex); + +static struct kobject *powercap_kobj; + +struct powercap_attr { + u32 handle; + struct kobj_attribute attr; +}; + +static struct pcap { + struct attribute_group pg; + struct powercap_attr *pattrs; +} *pcaps; + +static ssize_t powercap_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct powercap_attr *pcap_attr = container_of(attr, + struct powercap_attr, attr); + struct opal_msg msg; + u32 pcap; + int ret, token; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&powercap_mutex); + if (ret) + goto out_token; + + ret = opal_get_powercap(pcap_attr->handle, token, (u32 *)__pa(&pcap)); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) { + ret = sprintf(buf, "%u\n", be32_to_cpu(pcap)); + if (ret < 0) + ret = -EIO; + } + break; + case OPAL_SUCCESS: + ret = sprintf(buf, "%u\n", be32_to_cpu(pcap)); + if (ret < 0) + ret = -EIO; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&powercap_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static ssize_t powercap_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + struct powercap_attr *pcap_attr = container_of(attr, + struct powercap_attr, attr); + struct opal_msg msg; + u32 pcap; + int ret, token; + + ret = kstrtoint(buf, 0, &pcap); + if (ret) + return ret; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&powercap_mutex); + if (ret) + goto out_token; + + ret = opal_set_powercap(pcap_attr->handle, token, pcap); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) + ret = count; + break; + case OPAL_SUCCESS: + ret = count; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&powercap_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static void powercap_add_attr(int handle, const char *name, + struct powercap_attr *attr) +{ + attr->handle = handle; + sysfs_attr_init(&attr->attr.attr); + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = powercap_show; +} + +void __init opal_powercap_init(void) +{ + struct device_node *powercap, *node; + int i = 0; + + powercap = of_find_compatible_node(NULL, NULL, "ibm,opal-powercap"); + if (!powercap) { + pr_devel("Powercap node not found\n"); + return; + } + + pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps), + GFP_KERNEL); + if (!pcaps) + return; + + powercap_kobj = kobject_create_and_add("powercap", opal_kobj); + if (!powercap_kobj) { + pr_warn("Failed to create powercap kobject\n"); + goto out_pcaps; + } + + i = 0; + for_each_child_of_node(powercap, node) { + u32 cur, min, max; + int j = 0; + bool has_cur = false, has_min = false, has_max = false; + + if (!of_property_read_u32(node, "powercap-min", &min)) { + j++; + has_min = true; + } + + if (!of_property_read_u32(node, "powercap-max", &max)) { + j++; + has_max = true; + } + + if (!of_property_read_u32(node, "powercap-current", &cur)) { + j++; + has_cur = true; + } + + pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr), + GFP_KERNEL); + if (!pcaps[i].pattrs) + goto out_pcaps_pattrs; + + pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *), + GFP_KERNEL); + if (!pcaps[i].pg.attrs) { + kfree(pcaps[i].pattrs); + goto out_pcaps_pattrs; + } + + j = 0; + pcaps[i].pg.name = node->name; + if (has_min) { + powercap_add_attr(min, "powercap-min", + &pcaps[i].pattrs[j]); + pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr; + j++; + } + + if (has_max) { + powercap_add_attr(max, "powercap-max", + &pcaps[i].pattrs[j]); + pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr; + j++; + } + + if (has_cur) { + powercap_add_attr(cur, "powercap-current", + &pcaps[i].pattrs[j]); + pcaps[i].pattrs[j].attr.attr.mode |= 0220; + pcaps[i].pattrs[j].attr.store = powercap_store; + pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr; + j++; + } + + if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) { + pr_warn("Failed to create powercap attribute group %s\n", + pcaps[i].pg.name); + goto out_pcaps_pattrs; + } + i++; + } + + return; + +out_pcaps_pattrs: + while (--i >= 0) { + kfree(pcaps[i].pattrs); + kfree(pcaps[i].pg.attrs); + } + kobject_put(powercap_kobj); +out_pcaps: + kfree(pcaps); +} diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c index 2d6ee1c5ad859f4253f4b3c42e2aca1a6f9056a5..de4dd09f4a15c3ba5130322ccd57c134033739f7 100644 --- a/arch/powerpc/platforms/powernv/opal-prd.c +++ b/arch/powerpc/platforms/powernv/opal-prd.c @@ -241,15 +241,9 @@ static ssize_t opal_prd_write(struct file *file, const char __user *buf, size = be16_to_cpu(hdr.size); - msg = kmalloc(size, GFP_KERNEL); - if (!msg) - return -ENOMEM; - - rc = copy_from_user(msg, buf, size); - if (rc) { - size = -EFAULT; - goto out_free; - } + msg = memdup_user(buf, size); + if (IS_ERR(msg)) + return PTR_ERR(msg); rc = opal_prd_msg(msg); if (rc) { @@ -257,7 +251,6 @@ static ssize_t opal_prd_write(struct file *file, const char __user *buf, size = -EIO; } -out_free: kfree(msg); return size; diff --git a/arch/powerpc/platforms/powernv/opal-psr.c b/arch/powerpc/platforms/powernv/opal-psr.c new file mode 100644 index 0000000000000000000000000000000000000000..7313b7fc9071f889cd3053ce938de9b2cf313a57 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-psr.c @@ -0,0 +1,175 @@ +/* + * PowerNV OPAL Power-Shift-Ratio interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-psr: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(psr_mutex); + +static struct kobject *psr_kobj; + +struct psr_attr { + u32 handle; + struct kobj_attribute attr; +} *psr_attrs; + +static ssize_t psr_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct psr_attr *psr_attr = container_of(attr, struct psr_attr, attr); + struct opal_msg msg; + int psr, ret, token; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&psr_mutex); + if (ret) + goto out_token; + + ret = opal_get_power_shift_ratio(psr_attr->handle, token, + (u32 *)__pa(&psr)); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) { + ret = sprintf(buf, "%u\n", be32_to_cpu(psr)); + if (ret < 0) + ret = -EIO; + } + break; + case OPAL_SUCCESS: + ret = sprintf(buf, "%u\n", be32_to_cpu(psr)); + if (ret < 0) + ret = -EIO; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&psr_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static ssize_t psr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct psr_attr *psr_attr = container_of(attr, struct psr_attr, attr); + struct opal_msg msg; + int psr, ret, token; + + ret = kstrtoint(buf, 0, &psr); + if (ret) + return ret; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&psr_mutex); + if (ret) + goto out_token; + + ret = opal_set_power_shift_ratio(psr_attr->handle, token, psr); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) + ret = count; + break; + case OPAL_SUCCESS: + ret = count; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&psr_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +void __init opal_psr_init(void) +{ + struct device_node *psr, *node; + int i = 0; + + psr = of_find_compatible_node(NULL, NULL, + "ibm,opal-power-shift-ratio"); + if (!psr) { + pr_devel("Power-shift-ratio node not found\n"); + return; + } + + psr_attrs = kcalloc(of_get_child_count(psr), sizeof(struct psr_attr), + GFP_KERNEL); + if (!psr_attrs) + return; + + psr_kobj = kobject_create_and_add("psr", opal_kobj); + if (!psr_kobj) { + pr_warn("Failed to create psr kobject\n"); + goto out; + } + + for_each_child_of_node(psr, node) { + if (of_property_read_u32(node, "handle", + &psr_attrs[i].handle)) + goto out_kobj; + + sysfs_attr_init(&psr_attrs[i].attr.attr); + if (of_property_read_string(node, "label", + &psr_attrs[i].attr.attr.name)) + goto out_kobj; + psr_attrs[i].attr.attr.mode = 0664; + psr_attrs[i].attr.show = psr_show; + psr_attrs[i].attr.store = psr_store; + if (sysfs_create_file(psr_kobj, &psr_attrs[i].attr.attr)) { + pr_devel("Failed to create psr sysfs file %s\n", + psr_attrs[i].attr.attr.name); + goto out_kobj; + } + i++; + } + + return; +out_kobj: + kobject_put(psr_kobj); +out: + kfree(psr_attrs); +} diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c b/arch/powerpc/platforms/powernv/opal-sensor-groups.c new file mode 100644 index 0000000000000000000000000000000000000000..7e5a235ebf767700649d2a57202ec3dd4b3616ff --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c @@ -0,0 +1,212 @@ +/* + * PowerNV OPAL Sensor-groups interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-sensor-groups: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(sg_mutex); + +static struct kobject *sg_kobj; + +struct sg_attr { + u32 handle; + struct kobj_attribute attr; +}; + +static struct sensor_group { + char name[20]; + struct attribute_group sg; + struct sg_attr *sgattrs; +} *sgs; + +static ssize_t sg_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct sg_attr *sattr = container_of(attr, struct sg_attr, attr); + struct opal_msg msg; + u32 data; + int ret, token; + + ret = kstrtoint(buf, 0, &data); + if (ret) + return ret; + + if (data != 1) + return -EINVAL; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&sg_mutex); + if (ret) + goto out_token; + + ret = opal_sensor_group_clear(sattr->handle, token); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) + ret = count; + break; + case OPAL_SUCCESS: + ret = count; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&sg_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static struct sg_ops_info { + int opal_no; + const char *attr_name; + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +} ops_info[] = { + { OPAL_SENSOR_GROUP_CLEAR, "clear", sg_store }, +}; + +static void add_attr(int handle, struct sg_attr *attr, int index) +{ + attr->handle = handle; + sysfs_attr_init(&attr->attr.attr); + attr->attr.attr.name = ops_info[index].attr_name; + attr->attr.attr.mode = 0220; + attr->attr.store = ops_info[index].store; +} + +static int add_attr_group(const __be32 *ops, int len, struct sensor_group *sg, + u32 handle) +{ + int i, j; + int count = 0; + + for (i = 0; i < len; i++) + for (j = 0; j < ARRAY_SIZE(ops_info); j++) + if (be32_to_cpu(ops[i]) == ops_info[j].opal_no) { + add_attr(handle, &sg->sgattrs[count], j); + sg->sg.attrs[count] = + &sg->sgattrs[count].attr.attr; + count++; + } + + return sysfs_create_group(sg_kobj, &sg->sg); +} + +static int get_nr_attrs(const __be32 *ops, int len) +{ + int i, j; + int nr_attrs = 0; + + for (i = 0; i < len; i++) + for (j = 0; j < ARRAY_SIZE(ops_info); j++) + if (be32_to_cpu(ops[i]) == ops_info[j].opal_no) + nr_attrs++; + + return nr_attrs; +} + +void __init opal_sensor_groups_init(void) +{ + struct device_node *sg, *node; + int i = 0; + + sg = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group"); + if (!sg) { + pr_devel("Sensor groups node not found\n"); + return; + } + + sgs = kcalloc(of_get_child_count(sg), sizeof(*sgs), GFP_KERNEL); + if (!sgs) + return; + + sg_kobj = kobject_create_and_add("sensor_groups", opal_kobj); + if (!sg_kobj) { + pr_warn("Failed to create sensor group kobject\n"); + goto out_sgs; + } + + for_each_child_of_node(sg, node) { + const __be32 *ops; + u32 sgid, len, nr_attrs, chipid; + + ops = of_get_property(node, "ops", &len); + if (!ops) + continue; + + nr_attrs = get_nr_attrs(ops, len); + if (!nr_attrs) + continue; + + sgs[i].sgattrs = kcalloc(nr_attrs, sizeof(struct sg_attr), + GFP_KERNEL); + if (!sgs[i].sgattrs) + goto out_sgs_sgattrs; + + sgs[i].sg.attrs = kcalloc(nr_attrs + 1, + sizeof(struct attribute *), + GFP_KERNEL); + + if (!sgs[i].sg.attrs) { + kfree(sgs[i].sgattrs); + goto out_sgs_sgattrs; + } + + if (of_property_read_u32(node, "sensor-group-id", &sgid)) { + pr_warn("sensor-group-id property not found\n"); + goto out_sgs_sgattrs; + } + + if (!of_property_read_u32(node, "ibm,chip-id", &chipid)) + sprintf(sgs[i].name, "%s%d", node->name, chipid); + else + sprintf(sgs[i].name, "%s", node->name); + + sgs[i].sg.name = sgs[i].name; + if (add_attr_group(ops, len, &sgs[i], sgid)) { + pr_warn("Failed to create sensor attribute group %s\n", + sgs[i].sg.name); + goto out_sgs_sgattrs; + } + i++; + } + + return; + +out_sgs_sgattrs: + while (--i >= 0) { + kfree(sgs[i].sgattrs); + kfree(sgs[i].sg.attrs); + } + kobject_put(sg_kobj); +out_sgs: + kfree(sgs); +} diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 4ca6c26a56d5cd2c2ef5fcbe0fda2c034b9dae3d..8c1ede2d3f7e5fe4655d8acc30226dbc3c0d5294 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -27,7 +27,7 @@ .globl opal_tracepoint_refcount opal_tracepoint_refcount: - .llong 0 + .8byte 0 .section ".text" @@ -310,3 +310,12 @@ OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT); OPAL_CALL(opal_npu_map_lpar, OPAL_NPU_MAP_LPAR); +OPAL_CALL(opal_imc_counters_init, OPAL_IMC_COUNTERS_INIT); +OPAL_CALL(opal_imc_counters_start, OPAL_IMC_COUNTERS_START); +OPAL_CALL(opal_imc_counters_stop, OPAL_IMC_COUNTERS_STOP); +OPAL_CALL(opal_pci_set_p2p, OPAL_PCI_SET_P2P); +OPAL_CALL(opal_get_powercap, OPAL_GET_POWERCAP); +OPAL_CALL(opal_set_powercap, OPAL_SET_POWERCAP); +OPAL_CALL(opal_get_power_shift_ratio, OPAL_GET_POWER_SHIFT_RATIO); +OPAL_CALL(opal_set_power_shift_ratio, OPAL_SET_POWER_SHIFT_RATIO); +OPAL_CALL(opal_sensor_group_clear, OPAL_SENSOR_GROUP_CLEAR); diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 28651fb254175bc81539721d0bf9585a0d3c92ac..81c0a943dea9bb581d0f6d663df5c431a5529127 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -36,14 +36,14 @@ static scom_map_t opal_scom_map(struct device_node *dev, u64 reg, u64 count) const __be32 *gcid; if (!of_get_property(dev, "scom-controller", NULL)) { - pr_err("%s: device %s is not a SCOM controller\n", - __func__, dev->full_name); + pr_err("%s: device %pOF is not a SCOM controller\n", + __func__, dev); return SCOM_MAP_INVALID; } gcid = of_get_property(dev, "ibm,chip-id", NULL); if (!gcid) { - pr_err("%s: device %s has no ibm,chip-id\n", - __func__, dev->full_name); + pr_err("%s: device %pOF has no ibm,chip-id\n", + __func__, dev); return SCOM_MAP_INVALID; } m = kmalloc(sizeof(struct opal_scom_map), GFP_KERNEL); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index cad6b57ce494bb72dff04102e7d8d0499b8e038a..65c79ecf5a4d685c3c2d5035a18b196bb9664f63 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,11 +26,17 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include +#include +#include #include "powernv.h" @@ -162,12 +169,9 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node, sizeof(struct mcheck_recoverable_range); /* - * Allocate a buffer to hold the MC recoverable ranges. We would be - * accessing them in real mode, hence it needs to be within - * RMO region. + * Allocate a buffer to hold the MC recoverable ranges. */ - mc_recoverable_range =__va(memblock_alloc_base(size, __alignof__(u64), - ppc64_rma_size)); + mc_recoverable_range =__va(memblock_alloc(size, __alignof__(u64))); memset(mc_recoverable_range, 0, size); for (i = 0; i < mc_recoverable_range_len; i++) { @@ -422,24 +426,88 @@ static int opal_recover_mce(struct pt_regs *regs, /* Fatal machine check */ pr_err("Machine check interrupt is fatal\n"); recovered = 0; - } else if ((evt->severity == MCE_SEV_ERROR_SYNC) && - (user_mode(regs) && !is_global_init(current))) { + } + + if (!recovered && evt->severity == MCE_SEV_ERROR_SYNC) { /* - * For now, kill the task if we have received exception when - * in userspace. + * Try to kill processes if we get a synchronous machine check + * (e.g., one caused by execution of this instruction). This + * will devolve into a panic if we try to kill init or are in + * an interrupt etc. * * TODO: Queue up this address for hwpoisioning later. + * TODO: This is not quite right for d-side machine + * checks ->nip is not necessarily the important + * address. */ - _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); - recovered = 1; + if ((user_mode(regs))) { + _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); + recovered = 1; + } else if (die_will_crash()) { + /* + * die() would kill the kernel, so better to go via + * the platform reboot code that will log the + * machine check. + */ + recovered = 0; + } else { + die("Machine check", regs, SIGBUS); + recovered = 1; + } } + return recovered; } +void pnv_platform_error_reboot(struct pt_regs *regs, const char *msg) +{ + /* + * This is mostly taken from kernel/panic.c, but tries to do + * relatively minimal work. Don't use delay functions (TB may + * be broken), don't crash dump (need to set a firmware log), + * don't run notifiers. We do want to get some information to + * Linux console. + */ + console_verbose(); + bust_spinlocks(1); + pr_emerg("Hardware platform error: %s\n", msg); + if (regs) + show_regs(regs); + smp_send_stop(); + printk_safe_flush_on_panic(); + kmsg_dump(KMSG_DUMP_PANIC); + bust_spinlocks(0); + debug_locks_off(); + console_flush_on_panic(); + + /* + * Don't bother to shut things down because this will + * xstop the system. + */ + if (opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, msg) + == OPAL_UNSUPPORTED) { + pr_emerg("Reboot type %d not supported for %s\n", + OPAL_REBOOT_PLATFORM_ERROR, msg); + } + + /* + * We reached here. There can be three possibilities: + * 1. We are running on a firmware level that do not support + * opal_cec_reboot2() + * 2. We are running on a firmware level that do not support + * OPAL_REBOOT_PLATFORM_ERROR reboot type. + * 3. We are running on FSP based system that does not need + * opal to trigger checkstop explicitly for error analysis. + * The FSP PRD component would have already got notified + * about this error through other channels. + */ + + ppc_md.restart(NULL); +} + int opal_machine_check(struct pt_regs *regs) { struct machine_check_event evt; - int ret; if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) return 0; @@ -455,43 +523,7 @@ int opal_machine_check(struct pt_regs *regs) if (opal_recover_mce(regs, &evt)) return 1; - /* - * Unrecovered machine check, we are heading to panic path. - * - * We may have hit this MCE in very early stage of kernel - * initialization even before opal-prd has started running. If - * this is the case then this MCE error may go un-noticed or - * un-analyzed if we go down panic path. We need to inform - * BMC/OCC about this error so that they can collect relevant - * data for error analysis before rebooting. - * Use opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR) to do so. - * This function may not return on BMC based system. - */ - ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, - "Unrecoverable Machine Check exception"); - if (ret == OPAL_UNSUPPORTED) { - pr_emerg("Reboot type %d not supported\n", - OPAL_REBOOT_PLATFORM_ERROR); - } - - /* - * We reached here. There can be three possibilities: - * 1. We are running on a firmware level that do not support - * opal_cec_reboot2() - * 2. We are running on a firmware level that do not support - * OPAL_REBOOT_PLATFORM_ERROR reboot type. - * 3. We are running on FSP based system that does not need opal - * to trigger checkstop explicitly for error analysis. The FSP - * PRD component would have already got notified about this - * error through other channels. - * - * If hardware marked this as an unrecoverable MCE, we are - * going to panic anyway. Even if it didn't, it's not safe to - * continue at this point, so we should explicitly panic. - */ - - panic("PowerNV Unrecovered Machine Check"); - return 0; + pnv_platform_error_reboot(regs, "Unrecoverable Machine Check exception"); } /* Early hmi handler called in real mode. */ @@ -720,6 +752,15 @@ static void opal_pdev_init(const char *compatible) of_platform_device_create(np, NULL, NULL); } +static void __init opal_imc_init_dev(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, IMC_DTB_COMPAT); + if (np) + of_platform_device_create(np, NULL, NULL); +} + static int kopald(void *unused) { unsigned long timeout = msecs_to_jiffies(opal_heartbeat) + 1; @@ -793,6 +834,9 @@ static int __init opal_init(void) /* Setup a heatbeat thread if requested by OPAL */ opal_init_heartbeat(); + /* Detect In-Memory Collection counters and create devices*/ + opal_imc_init_dev(); + /* Create leds platform devices */ leds = of_find_node_by_path("/ibm,opal/leds"); if (leds) { @@ -836,6 +880,15 @@ static int __init opal_init(void) /* Initialise OPAL kmsg dumper for flushing console on panic */ opal_kmsg_init(); + /* Initialise OPAL powercap interface */ + opal_powercap_init(); + + /* Initialise OPAL Power-Shifting-Ratio interface */ + opal_psr_init(); + + /* Initialise OPAL sensor groups */ + opal_sensor_groups_init(); + return 0; } machine_subsys_initcall(powernv, opal_init); @@ -952,6 +1005,7 @@ int opal_error_code(int rc) case OPAL_UNSUPPORTED: return -EIO; case OPAL_HARDWARE: return -EIO; case OPAL_INTERNAL_ERROR: return -EIO; + case OPAL_TIMEOUT: return -ETIMEDOUT; default: pr_err("%s: unexpected OPAL error %d\n", __func__, rc); return -EIO; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 437613588df15ceab2a1ce5e88649b675c495de4..57f9e55f4352d41ad61da71671d0d675d336b8b6 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -444,8 +444,8 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) r = of_get_property(dn, "ibm,opal-m64-window", NULL); if (!r) { - pr_info(" No on %s\n", - dn->full_name); + pr_info(" No on %pOF\n", + dn); return; } @@ -1408,7 +1408,6 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) static long pnv_pci_ioda2_unset_window(struct iommu_table_group *table_group, int num); -static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable); static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe *pe) { @@ -1852,6 +1851,14 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask) /* 4GB offset bypasses 32-bit space */ set_dma_offset(&pdev->dev, (1ULL << 32)); set_dma_ops(&pdev->dev, &dma_direct_ops); + } else if (dma_mask >> 32 && dma_mask != DMA_BIT_MASK(64)) { + /* + * Fail the request if a DMA mask between 32 and 64 bits + * was requested but couldn't be fulfilled. Ideally we + * would do this for 64-bits but historically we have + * always fallen back to 32-bits. + */ + return -ENOMEM; } else { dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n"); set_dma_ops(&pdev->dev, &dma_iommu_ops); @@ -2394,7 +2401,7 @@ static long pnv_pci_ioda2_set_window(struct iommu_table_group *table_group, return 0; } -static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable) +void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable) { uint16_t window_id = (pe->pe_number << 1 ) + 1; int64_t rc; @@ -3789,8 +3796,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, if (!of_device_is_available(np)) return; - pr_info("Initializing %s PHB (%s)\n", - pnv_phb_names[ioda_type], of_node_full_name(np)); + pr_info("Initializing %s PHB (%pOF)\n", pnv_phb_names[ioda_type], np); prop64 = of_get_property(np, "ibm,opal-phbid", NULL); if (!prop64) { @@ -3805,8 +3811,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, /* Allocate PCI controller */ phb->hose = hose = pcibios_alloc_controller(np); if (!phb->hose) { - pr_err(" Can't allocate PCI controller for %s\n", - np->full_name); + pr_err(" Can't allocate PCI controller for %pOF\n", + np); memblock_free(__pa(phb), sizeof(struct pnv_phb)); return; } @@ -3817,7 +3823,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, hose->first_busno = be32_to_cpu(prop32[0]); hose->last_busno = be32_to_cpu(prop32[1]); } else { - pr_warn(" Broken on %s\n", np->full_name); + pr_warn(" Broken on %pOF\n", np); hose->first_busno = 0; hose->last_busno = 0xff; } @@ -4038,7 +4044,7 @@ void __init pnv_pci_init_ioda_hub(struct device_node *np) const __be64 *prop64; u64 hub_id; - pr_info("Probing IODA IO-Hub %s\n", np->full_name); + pr_info("Probing IODA IO-Hub %pOF\n", np); prop64 = of_get_property(np, "ibm,opal-hubid", NULL); if (!prop64) { diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 7905d179d036410536d05d4f4292df633744a266..5422f4a6317cadf06335c4c1a18e3d7dcccd6db6 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -37,6 +37,8 @@ #include "powernv.h" #include "pci.h" +static DEFINE_MUTEX(p2p_mutex); + int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id) { struct device_node *parent = np; @@ -1017,6 +1019,79 @@ void pnv_pci_dma_bus_setup(struct pci_bus *bus) } } +int pnv_pci_set_p2p(struct pci_dev *initiator, struct pci_dev *target, u64 desc) +{ + struct pci_controller *hose; + struct pnv_phb *phb_init, *phb_target; + struct pnv_ioda_pe *pe_init; + int rc; + + if (!opal_check_token(OPAL_PCI_SET_P2P)) + return -ENXIO; + + hose = pci_bus_to_host(initiator->bus); + phb_init = hose->private_data; + + hose = pci_bus_to_host(target->bus); + phb_target = hose->private_data; + + pe_init = pnv_ioda_get_pe(initiator); + if (!pe_init) + return -ENODEV; + + /* + * Configuring the initiator's PHB requires to adjust its + * TVE#1 setting. Since the same device can be an initiator + * several times for different target devices, we need to keep + * a reference count to know when we can restore the default + * bypass setting on its TVE#1 when disabling. Opal is not + * tracking PE states, so we add a reference count on the PE + * in linux. + * + * For the target, the configuration is per PHB, so we keep a + * target reference count on the PHB. + */ + mutex_lock(&p2p_mutex); + + if (desc & OPAL_PCI_P2P_ENABLE) { + /* always go to opal to validate the configuration */ + rc = opal_pci_set_p2p(phb_init->opal_id, phb_target->opal_id, + desc, pe_init->pe_number); + + if (rc != OPAL_SUCCESS) { + rc = -EIO; + goto out; + } + + pe_init->p2p_initiator_count++; + phb_target->p2p_target_count++; + } else { + if (!pe_init->p2p_initiator_count || + !phb_target->p2p_target_count) { + rc = -EINVAL; + goto out; + } + + if (--pe_init->p2p_initiator_count == 0) + pnv_pci_ioda2_set_bypass(pe_init, true); + + if (--phb_target->p2p_target_count == 0) { + rc = opal_pci_set_p2p(phb_init->opal_id, + phb_target->opal_id, desc, + pe_init->pe_number); + if (rc != OPAL_SUCCESS) { + rc = -EIO; + goto out; + } + } + } + rc = 0; +out: + mutex_unlock(&p2p_mutex); + return rc; +} +EXPORT_SYMBOL_GPL(pnv_pci_set_p2p); + void pnv_pci_shutdown(void) { struct pci_controller *hose; diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index f16bc403ec03cff364ff79b7d27fb0f6168525f6..a95273c524f65381595434b4f35860be75bc44f0 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -78,6 +78,9 @@ struct pnv_ioda_pe { struct pnv_ioda_pe *master; struct list_head slaves; + /* PCI peer-to-peer*/ + int p2p_initiator_count; + /* Link in list of PE#s */ struct list_head list; }; @@ -189,6 +192,7 @@ struct pnv_phb { #ifdef CONFIG_CXL_BASE struct cxl_afu *cxl_afu; #endif + int p2p_target_count; }; extern struct pci_ops pnv_pci_ops; @@ -229,6 +233,7 @@ extern void pnv_teardown_msi_irqs(struct pci_dev *pdev); extern struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev); extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq); extern bool pnv_pci_enable_device_hook(struct pci_dev *dev); +extern void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable); extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, const char *fmt, ...); diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index 6dbc0a1da1f61d8906ca3eeb515ad5e0da0e1800..a159d48573d703dcb2ee040ff1ea28404217f735 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h @@ -7,6 +7,8 @@ extern void pnv_smp_init(void); static inline void pnv_smp_init(void) { } #endif +extern void pnv_platform_error_reboot(struct pt_regs *regs, const char *msg) __noreturn; + struct pci_dev; #ifdef CONFIG_PCI diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 1a9d84371a4dd65386d88c25a2486333c161f7ab..718f50ed22f1f235a73cb25104fc74b6032c23df 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -16,11 +16,13 @@ #include #include #include +#include #include #include #include #include +#define DARN_ERR 0xFFFFFFFFFFFFFFFFul struct powernv_rng { void __iomem *regs; @@ -67,6 +69,41 @@ int powernv_get_random_real_mode(unsigned long *v) return 1; } +int powernv_get_random_darn(unsigned long *v) +{ + unsigned long val; + + /* Using DARN with L=1 - 64-bit conditioned random number */ + asm volatile(PPC_DARN(%0, 1) : "=r"(val)); + + if (val == DARN_ERR) + return 0; + + *v = val; + + return 1; +} + +static int initialise_darn(void) +{ + unsigned long val; + int i; + + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + return -ENODEV; + + for (i = 0; i < 10; i++) { + if (powernv_get_random_darn(&val)) { + ppc_md.get_random_seed = powernv_get_random_darn; + return 0; + } + } + + pr_warn("Unable to use DARN for get_random_seed()\n"); + + return -EIO; +} + int powernv_get_random_long(unsigned long *v) { struct powernv_rng *rng; @@ -88,7 +125,7 @@ static __init void rng_init_per_cpu(struct powernv_rng *rng, chip_id = of_get_ibm_chip_id(dn); if (chip_id == -1) - pr_warn("No ibm,chip-id found for %s.\n", dn->full_name); + pr_warn("No ibm,chip-id found for %pOF.\n", dn); for_each_possible_cpu(cpu) { if (per_cpu(powernv_rng, cpu) == NULL || @@ -141,8 +178,8 @@ static __init int rng_init(void) for_each_compatible_node(dn, NULL, "ibm,power-rng") { rc = rng_create(dn); if (rc) { - pr_err("Failed creating rng for %s (%d).\n", - dn->full_name, rc); + pr_err("Failed creating rng for %pOF (%d).\n", + dn, rc); continue; } @@ -150,6 +187,8 @@ static __init int rng_init(void) of_platform_device_create(dn, NULL, NULL); } + initialise_darn(); + return 0; } machine_subsys_initcall(powernv, rng_init); diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 897aa1400eb833e944fabbc65840904006267a1f..bbb73aa0eb8f041630110c795828215471cc5f2d 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -272,7 +272,15 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE static unsigned long pnv_memory_block_size(void) { - return 256UL * 1024 * 1024; + /* + * We map the kernel linear region with 1GB large pages on radix. For + * memory hot unplug to work our memory block size must be at least + * this size. + */ + if (radix_enabled()) + return 1UL * 1024 * 1024 * 1024; + else + return 256UL * 1024 * 1024; } #endif diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 40dae96f7e20c6d2c1446e89f770e031c70e13f8..c17f81e433f7dffc6ec651b79bc8a6053197244b 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -57,7 +57,7 @@ static void pnv_smp_setup_cpu(int cpu) static int pnv_smp_kick_cpu(int nr) { - unsigned int pcpu = get_hard_smp_processor_id(nr); + unsigned int pcpu; unsigned long start_here = __pa(ppc_function_entry(generic_secondary_smp_init)); long rc; @@ -66,6 +66,7 @@ static int pnv_smp_kick_cpu(int nr) if (nr < 0 || nr >= nr_cpu_ids) return -EINVAL; + pcpu = get_hard_smp_processor_id(nr); /* * If we already started or OPAL is not supported, we just * kick the CPU via the PACA @@ -164,12 +165,6 @@ static void pnv_smp_cpu_kill_self(void) if (cpu_has_feature(CPU_FTR_ARCH_207S)) wmask = SRR1_WAKEMASK_P8; - /* We don't want to take decrementer interrupts while we are offline, - * so clear LPCR:PECE1. We keep PECE2 (and LPCR_PECE_HVEE on P9) - * enabled as to let IPIs in. - */ - mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); - while (!generic_check_cpu_restart(cpu)) { /* * Clear IPI flag, since we don't handle IPIs while @@ -219,8 +214,6 @@ static void pnv_smp_cpu_kill_self(void) } - /* Re-enable decrementer interrupts */ - mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); DBG("CPU%d coming online...\n", cpu); } diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c new file mode 100644 index 0000000000000000000000000000000000000000..5aae845b8cd965a3774ded631ceef5557ba96a0a --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -0,0 +1,1134 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "vas: " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include "vas.h" +#include "copy-paste.h" + +/* + * Compute the paste address region for the window @window using the + * ->paste_base_addr and ->paste_win_id_shift we got from device tree. + */ +static void compute_paste_address(struct vas_window *window, u64 *addr, int *len) +{ + int winid; + u64 base, shift; + + base = window->vinst->paste_base_addr; + shift = window->vinst->paste_win_id_shift; + winid = window->winid; + + *addr = base + (winid << shift); + if (len) + *len = PAGE_SIZE; + + pr_debug("Txwin #%d: Paste addr 0x%llx\n", winid, *addr); +} + +static inline void get_hvwc_mmio_bar(struct vas_window *window, + u64 *start, int *len) +{ + u64 pbaddr; + + pbaddr = window->vinst->hvwc_bar_start; + *start = pbaddr + window->winid * VAS_HVWC_SIZE; + *len = VAS_HVWC_SIZE; +} + +static inline void get_uwc_mmio_bar(struct vas_window *window, + u64 *start, int *len) +{ + u64 pbaddr; + + pbaddr = window->vinst->uwc_bar_start; + *start = pbaddr + window->winid * VAS_UWC_SIZE; + *len = VAS_UWC_SIZE; +} + +/* + * Map the paste bus address of the given send window into kernel address + * space. Unlike MMIO regions (map_mmio_region() below), paste region must + * be mapped cache-able and is only applicable to send windows. + */ +static void *map_paste_region(struct vas_window *txwin) +{ + int len; + void *map; + char *name; + u64 start; + + name = kasprintf(GFP_KERNEL, "window-v%d-w%d", txwin->vinst->vas_id, + txwin->winid); + if (!name) + goto free_name; + + txwin->paste_addr_name = name; + compute_paste_address(txwin, &start, &len); + + if (!request_mem_region(start, len, name)) { + pr_devel("%s(): request_mem_region(0x%llx, %d) failed\n", + __func__, start, len); + goto free_name; + } + + map = ioremap_cache(start, len); + if (!map) { + pr_devel("%s(): ioremap_cache(0x%llx, %d) failed\n", __func__, + start, len); + goto free_name; + } + + pr_devel("Mapped paste addr 0x%llx to kaddr 0x%p\n", start, map); + return map; + +free_name: + kfree(name); + return ERR_PTR(-ENOMEM); +} + +static void *map_mmio_region(char *name, u64 start, int len) +{ + void *map; + + if (!request_mem_region(start, len, name)) { + pr_devel("%s(): request_mem_region(0x%llx, %d) failed\n", + __func__, start, len); + return NULL; + } + + map = ioremap(start, len); + if (!map) { + pr_devel("%s(): ioremap(0x%llx, %d) failed\n", __func__, start, + len); + return NULL; + } + + return map; +} + +static void unmap_region(void *addr, u64 start, int len) +{ + iounmap(addr); + release_mem_region((phys_addr_t)start, len); +} + +/* + * Unmap the paste address region for a window. + */ +static void unmap_paste_region(struct vas_window *window) +{ + int len; + u64 busaddr_start; + + if (window->paste_kaddr) { + compute_paste_address(window, &busaddr_start, &len); + unmap_region(window->paste_kaddr, busaddr_start, len); + window->paste_kaddr = NULL; + kfree(window->paste_addr_name); + window->paste_addr_name = NULL; + } +} + +/* + * Unmap the MMIO regions for a window. + */ +static void unmap_winctx_mmio_bars(struct vas_window *window) +{ + int len; + u64 busaddr_start; + + if (window->hvwc_map) { + get_hvwc_mmio_bar(window, &busaddr_start, &len); + unmap_region(window->hvwc_map, busaddr_start, len); + window->hvwc_map = NULL; + } + + if (window->uwc_map) { + get_uwc_mmio_bar(window, &busaddr_start, &len); + unmap_region(window->uwc_map, busaddr_start, len); + window->uwc_map = NULL; + } +} + +/* + * Find the Hypervisor Window Context (HVWC) MMIO Base Address Region and the + * OS/User Window Context (UWC) MMIO Base Address Region for the given window. + * Map these bus addresses and save the mapped kernel addresses in @window. + */ +int map_winctx_mmio_bars(struct vas_window *window) +{ + int len; + u64 start; + + get_hvwc_mmio_bar(window, &start, &len); + window->hvwc_map = map_mmio_region("HVWCM_Window", start, len); + + get_uwc_mmio_bar(window, &start, &len); + window->uwc_map = map_mmio_region("UWCM_Window", start, len); + + if (!window->hvwc_map || !window->uwc_map) { + unmap_winctx_mmio_bars(window); + return -1; + } + + return 0; +} + +/* + * Reset all valid registers in the HV and OS/User Window Contexts for + * the window identified by @window. + * + * NOTE: We cannot really use a for loop to reset window context. Not all + * offsets in a window context are valid registers and the valid + * registers are not sequential. And, we can only write to offsets + * with valid registers. + */ +void reset_window_regs(struct vas_window *window) +{ + write_hvwc_reg(window, VREG(LPID), 0ULL); + write_hvwc_reg(window, VREG(PID), 0ULL); + write_hvwc_reg(window, VREG(XLATE_MSR), 0ULL); + write_hvwc_reg(window, VREG(XLATE_LPCR), 0ULL); + write_hvwc_reg(window, VREG(XLATE_CTL), 0ULL); + write_hvwc_reg(window, VREG(AMR), 0ULL); + write_hvwc_reg(window, VREG(SEIDR), 0ULL); + write_hvwc_reg(window, VREG(FAULT_TX_WIN), 0ULL); + write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL); + write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), 0ULL); + write_hvwc_reg(window, VREG(PSWID), 0ULL); + write_hvwc_reg(window, VREG(LFIFO_BAR), 0ULL); + write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), 0ULL); + write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), 0ULL); + write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); + write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LRX_WCRED), 0ULL); + write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); + write_hvwc_reg(window, VREG(TX_WCRED), 0ULL); + write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); + write_hvwc_reg(window, VREG(LFIFO_SIZE), 0ULL); + write_hvwc_reg(window, VREG(WINCTL), 0ULL); + write_hvwc_reg(window, VREG(WIN_STATUS), 0ULL); + write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), 0ULL); + write_hvwc_reg(window, VREG(TX_RSVD_BUF_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LRFIFO_WIN_PTR), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_CTL), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_PID), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_LPID), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_TID), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_SCOPE), 0ULL); + write_hvwc_reg(window, VREG(NX_UTIL_ADDER), 0ULL); + + /* Skip read-only registers: NX_UTIL and NX_UTIL_SE */ + + /* + * The send and receive window credit adder registers are also + * accessible from HVWC and have been initialized above. We don't + * need to initialize from the OS/User Window Context, so skip + * following calls: + * + * write_uwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); + * write_uwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); + */ +} + +/* + * Initialize window context registers related to Address Translation. + * These registers are common to send/receive windows although they + * differ for user/kernel windows. As we resolve the TODOs we may + * want to add fields to vas_winctx and move the initialization to + * init_vas_winctx_regs(). + */ +static void init_xlate_regs(struct vas_window *window, bool user_win) +{ + u64 lpcr, val; + + /* + * MSR_TA, MSR_US are false for both kernel and user. + * MSR_DR and MSR_PR are false for kernel. + */ + val = 0ULL; + val = SET_FIELD(VAS_XLATE_MSR_HV, val, 1); + val = SET_FIELD(VAS_XLATE_MSR_SF, val, 1); + if (user_win) { + val = SET_FIELD(VAS_XLATE_MSR_DR, val, 1); + val = SET_FIELD(VAS_XLATE_MSR_PR, val, 1); + } + write_hvwc_reg(window, VREG(XLATE_MSR), val); + + lpcr = mfspr(SPRN_LPCR); + val = 0ULL; + /* + * NOTE: From Section 5.7.8.1 Segment Lookaside Buffer of the + * Power ISA, v3.0B, Page size encoding is 0 = 4KB, 5 = 64KB. + * + * NOTE: From Section 1.3.1, Address Translation Context of the + * Nest MMU Workbook, LPCR_SC should be 0 for Power9. + */ + val = SET_FIELD(VAS_XLATE_LPCR_PAGE_SIZE, val, 5); + val = SET_FIELD(VAS_XLATE_LPCR_ISL, val, lpcr & LPCR_ISL); + val = SET_FIELD(VAS_XLATE_LPCR_TC, val, lpcr & LPCR_TC); + val = SET_FIELD(VAS_XLATE_LPCR_SC, val, 0); + write_hvwc_reg(window, VREG(XLATE_LPCR), val); + + /* + * Section 1.3.1 (Address translation Context) of NMMU workbook. + * 0b00 Hashed Page Table mode + * 0b01 Reserved + * 0b10 Radix on HPT + * 0b11 Radix on Radix + */ + val = 0ULL; + val = SET_FIELD(VAS_XLATE_MODE, val, radix_enabled() ? 3 : 2); + write_hvwc_reg(window, VREG(XLATE_CTL), val); + + /* + * TODO: Can we mfspr(AMR) even for user windows? + */ + val = 0ULL; + val = SET_FIELD(VAS_AMR, val, mfspr(SPRN_AMR)); + write_hvwc_reg(window, VREG(AMR), val); + + val = 0ULL; + val = SET_FIELD(VAS_SEIDR, val, 0); + write_hvwc_reg(window, VREG(SEIDR), val); +} + +/* + * Initialize Reserved Send Buffer Count for the send window. It involves + * writing to the register, reading it back to confirm that the hardware + * has enough buffers to reserve. See section 1.3.1.2.1 of VAS workbook. + * + * Since we can only make a best-effort attempt to fulfill the request, + * we don't return any errors if we cannot. + * + * TODO: Reserved (aka dedicated) send buffers are not supported yet. + */ +static void init_rsvd_tx_buf_count(struct vas_window *txwin, + struct vas_winctx *winctx) +{ + write_hvwc_reg(txwin, VREG(TX_RSVD_BUF_COUNT), 0ULL); +} + +/* + * init_winctx_regs() + * Initialize window context registers for a receive window. + * Except for caching control and marking window open, the registers + * are initialized in the order listed in Section 3.1.4 (Window Context + * Cache Register Details) of the VAS workbook although they don't need + * to be. + * + * Design note: For NX receive windows, NX allocates the FIFO buffer in OPAL + * (so that it can get a large contiguous area) and passes that buffer + * to kernel via device tree. We now write that buffer address to the + * FIFO BAR. Would it make sense to do this all in OPAL? i.e have OPAL + * write the per-chip RX FIFO addresses to the windows during boot-up + * as a one-time task? That could work for NX but what about other + * receivers? Let the receivers tell us the rx-fifo buffers for now. + */ +int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx) +{ + u64 val; + int fifo_size; + + reset_window_regs(window); + + val = 0ULL; + val = SET_FIELD(VAS_LPID, val, winctx->lpid); + write_hvwc_reg(window, VREG(LPID), val); + + val = 0ULL; + val = SET_FIELD(VAS_PID_ID, val, winctx->pidr); + write_hvwc_reg(window, VREG(PID), val); + + init_xlate_regs(window, winctx->user_win); + + val = 0ULL; + val = SET_FIELD(VAS_FAULT_TX_WIN, val, 0); + write_hvwc_reg(window, VREG(FAULT_TX_WIN), val); + + /* In PowerNV, interrupts go to HV. */ + write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL); + + val = 0ULL; + val = SET_FIELD(VAS_HV_INTR_SRC_RA, val, winctx->irq_port); + write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), val); + + val = 0ULL; + val = SET_FIELD(VAS_PSWID_EA_HANDLE, val, winctx->pswid); + write_hvwc_reg(window, VREG(PSWID), val); + + write_hvwc_reg(window, VREG(SPARE1), 0ULL); + write_hvwc_reg(window, VREG(SPARE2), 0ULL); + write_hvwc_reg(window, VREG(SPARE3), 0ULL); + + /* + * NOTE: VAS expects the FIFO address to be copied into the LFIFO_BAR + * register as is - do NOT shift the address into VAS_LFIFO_BAR + * bit fields! Ok to set the page migration select fields - + * VAS ignores the lower 10+ bits in the address anyway, because + * the minimum FIFO size is 1K? + * + * See also: Design note in function header. + */ + val = __pa(winctx->rx_fifo); + val = SET_FIELD(VAS_PAGE_MIGRATION_SELECT, val, 0); + write_hvwc_reg(window, VREG(LFIFO_BAR), val); + + val = 0ULL; + val = SET_FIELD(VAS_LDATA_STAMP, val, winctx->data_stamp); + write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), val); + + val = 0ULL; + val = SET_FIELD(VAS_LDMA_TYPE, val, winctx->dma_type); + val = SET_FIELD(VAS_LDMA_FIFO_DISABLE, val, winctx->fifo_disable); + write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), val); + + write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); + write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); + + val = 0ULL; + val = SET_FIELD(VAS_LRX_WCRED, val, winctx->wcreds_max); + write_hvwc_reg(window, VREG(LRX_WCRED), val); + + val = 0ULL; + val = SET_FIELD(VAS_TX_WCRED, val, winctx->wcreds_max); + write_hvwc_reg(window, VREG(TX_WCRED), val); + + write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); + write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); + + fifo_size = winctx->rx_fifo_size / 1024; + + val = 0ULL; + val = SET_FIELD(VAS_LFIFO_SIZE, val, ilog2(fifo_size)); + write_hvwc_reg(window, VREG(LFIFO_SIZE), val); + + /* Update window control and caching control registers last so + * we mark the window open only after fully initializing it and + * pushing context to cache. + */ + + write_hvwc_reg(window, VREG(WIN_STATUS), 0ULL); + + init_rsvd_tx_buf_count(window, winctx); + + /* for a send window, point to the matching receive window */ + val = 0ULL; + val = SET_FIELD(VAS_LRX_WIN_ID, val, winctx->rx_win_id); + write_hvwc_reg(window, VREG(LRFIFO_WIN_PTR), val); + + write_hvwc_reg(window, VREG(SPARE4), 0ULL); + + val = 0ULL; + val = SET_FIELD(VAS_NOTIFY_DISABLE, val, winctx->notify_disable); + val = SET_FIELD(VAS_INTR_DISABLE, val, winctx->intr_disable); + val = SET_FIELD(VAS_NOTIFY_EARLY, val, winctx->notify_early); + val = SET_FIELD(VAS_NOTIFY_OSU_INTR, val, winctx->notify_os_intr_reg); + write_hvwc_reg(window, VREG(LNOTIFY_CTL), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_PID, val, winctx->lnotify_pid); + write_hvwc_reg(window, VREG(LNOTIFY_PID), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_LPID, val, winctx->lnotify_lpid); + write_hvwc_reg(window, VREG(LNOTIFY_LPID), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_TID, val, winctx->lnotify_tid); + write_hvwc_reg(window, VREG(LNOTIFY_TID), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_MIN_SCOPE, val, winctx->min_scope); + val = SET_FIELD(VAS_LNOTIFY_MAX_SCOPE, val, winctx->max_scope); + write_hvwc_reg(window, VREG(LNOTIFY_SCOPE), val); + + /* Skip read-only registers NX_UTIL and NX_UTIL_SE */ + + write_hvwc_reg(window, VREG(SPARE5), 0ULL); + write_hvwc_reg(window, VREG(NX_UTIL_ADDER), 0ULL); + write_hvwc_reg(window, VREG(SPARE6), 0ULL); + + /* Finally, push window context to memory and... */ + val = 0ULL; + val = SET_FIELD(VAS_PUSH_TO_MEM, val, 1); + write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), val); + + /* ... mark the window open for business */ + val = 0ULL; + val = SET_FIELD(VAS_WINCTL_REJ_NO_CREDIT, val, winctx->rej_no_credit); + val = SET_FIELD(VAS_WINCTL_PIN, val, winctx->pin_win); + val = SET_FIELD(VAS_WINCTL_TX_WCRED_MODE, val, winctx->tx_wcred_mode); + val = SET_FIELD(VAS_WINCTL_RX_WCRED_MODE, val, winctx->rx_wcred_mode); + val = SET_FIELD(VAS_WINCTL_TX_WORD_MODE, val, winctx->tx_word_mode); + val = SET_FIELD(VAS_WINCTL_RX_WORD_MODE, val, winctx->rx_word_mode); + val = SET_FIELD(VAS_WINCTL_FAULT_WIN, val, winctx->fault_win); + val = SET_FIELD(VAS_WINCTL_NX_WIN, val, winctx->nx_win); + val = SET_FIELD(VAS_WINCTL_OPEN, val, 1); + write_hvwc_reg(window, VREG(WINCTL), val); + + return 0; +} + +static DEFINE_SPINLOCK(vas_ida_lock); + +static void vas_release_window_id(struct ida *ida, int winid) +{ + spin_lock(&vas_ida_lock); + ida_remove(ida, winid); + spin_unlock(&vas_ida_lock); +} + +static int vas_assign_window_id(struct ida *ida) +{ + int rc, winid; + + do { + rc = ida_pre_get(ida, GFP_KERNEL); + if (!rc) + return -EAGAIN; + + spin_lock(&vas_ida_lock); + rc = ida_get_new(ida, &winid); + spin_unlock(&vas_ida_lock); + } while (rc == -EAGAIN); + + if (rc) + return rc; + + if (winid > VAS_WINDOWS_PER_CHIP) { + pr_err("Too many (%d) open windows\n", winid); + vas_release_window_id(ida, winid); + return -EAGAIN; + } + + return winid; +} + +static void vas_window_free(struct vas_window *window) +{ + int winid = window->winid; + struct vas_instance *vinst = window->vinst; + + unmap_winctx_mmio_bars(window); + kfree(window); + + vas_release_window_id(&vinst->ida, winid); +} + +static struct vas_window *vas_window_alloc(struct vas_instance *vinst) +{ + int winid; + struct vas_window *window; + + winid = vas_assign_window_id(&vinst->ida); + if (winid < 0) + return ERR_PTR(winid); + + window = kzalloc(sizeof(*window), GFP_KERNEL); + if (!window) + goto out_free; + + window->vinst = vinst; + window->winid = winid; + + if (map_winctx_mmio_bars(window)) + goto out_free; + + return window; + +out_free: + kfree(window); + vas_release_window_id(&vinst->ida, winid); + return ERR_PTR(-ENOMEM); +} + +static void put_rx_win(struct vas_window *rxwin) +{ + /* Better not be a send window! */ + WARN_ON_ONCE(rxwin->tx_win); + + atomic_dec(&rxwin->num_txwins); +} + +/* + * Get the VAS receive window associated with NX engine identified + * by @cop and if applicable, @pswid. + * + * See also function header of set_vinst_win(). + */ +static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst, + enum vas_cop_type cop, u32 pswid) +{ + struct vas_window *rxwin; + + mutex_lock(&vinst->mutex); + + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) + rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL); + else + rxwin = ERR_PTR(-EINVAL); + + if (!IS_ERR(rxwin)) + atomic_inc(&rxwin->num_txwins); + + mutex_unlock(&vinst->mutex); + + return rxwin; +} + +/* + * We have two tables of windows in a VAS instance. The first one, + * ->windows[], contains all the windows in the instance and allows + * looking up a window by its id. It is used to look up send windows + * during fault handling and receive windows when pairing user space + * send/receive windows. + * + * The second table, ->rxwin[], contains receive windows that are + * associated with NX engines. This table has VAS_COP_TYPE_MAX + * entries and is used to look up a receive window by its + * coprocessor type. + * + * Here, we save @window in the ->windows[] table. If it is a receive + * window, we also save the window in the ->rxwin[] table. + */ +static void set_vinst_win(struct vas_instance *vinst, + struct vas_window *window) +{ + int id = window->winid; + + mutex_lock(&vinst->mutex); + + /* + * There should only be one receive window for a coprocessor type + * unless its a user (FTW) window. + */ + if (!window->user_win && !window->tx_win) { + WARN_ON_ONCE(vinst->rxwin[window->cop]); + vinst->rxwin[window->cop] = window; + } + + WARN_ON_ONCE(vinst->windows[id] != NULL); + vinst->windows[id] = window; + + mutex_unlock(&vinst->mutex); +} + +/* + * Clear this window from the table(s) of windows for this VAS instance. + * See also function header of set_vinst_win(). + */ +static void clear_vinst_win(struct vas_window *window) +{ + int id = window->winid; + struct vas_instance *vinst = window->vinst; + + mutex_lock(&vinst->mutex); + + if (!window->user_win && !window->tx_win) { + WARN_ON_ONCE(!vinst->rxwin[window->cop]); + vinst->rxwin[window->cop] = NULL; + } + + WARN_ON_ONCE(vinst->windows[id] != window); + vinst->windows[id] = NULL; + + mutex_unlock(&vinst->mutex); +} + +static void init_winctx_for_rxwin(struct vas_window *rxwin, + struct vas_rx_win_attr *rxattr, + struct vas_winctx *winctx) +{ + /* + * We first zero (memset()) all fields and only set non-zero fields. + * Following fields are 0/false but maybe deserve a comment: + * + * ->notify_os_intr_reg In powerNV, send intrs to HV + * ->notify_disable False for NX windows + * ->intr_disable False for Fault Windows + * ->xtra_write False for NX windows + * ->notify_early NA for NX windows + * ->rsvd_txbuf_count NA for Rx windows + * ->lpid, ->pid, ->tid NA for Rx windows + */ + + memset(winctx, 0, sizeof(struct vas_winctx)); + + winctx->rx_fifo = rxattr->rx_fifo; + winctx->rx_fifo_size = rxattr->rx_fifo_size; + winctx->wcreds_max = rxattr->wcreds_max ?: VAS_WCREDS_DEFAULT; + winctx->pin_win = rxattr->pin_win; + + winctx->nx_win = rxattr->nx_win; + winctx->fault_win = rxattr->fault_win; + winctx->rx_word_mode = rxattr->rx_win_ord_mode; + winctx->tx_word_mode = rxattr->tx_win_ord_mode; + winctx->rx_wcred_mode = rxattr->rx_wcred_mode; + winctx->tx_wcred_mode = rxattr->tx_wcred_mode; + + if (winctx->nx_win) { + winctx->data_stamp = true; + winctx->intr_disable = true; + winctx->pin_win = true; + + WARN_ON_ONCE(winctx->fault_win); + WARN_ON_ONCE(!winctx->rx_word_mode); + WARN_ON_ONCE(!winctx->tx_word_mode); + WARN_ON_ONCE(winctx->notify_after_count); + } else if (winctx->fault_win) { + winctx->notify_disable = true; + } else if (winctx->user_win) { + /* + * Section 1.8.1 Low Latency Core-Core Wake up of + * the VAS workbook: + * + * - disable credit checks ([tr]x_wcred_mode = false) + * - disable FIFO writes + * - enable ASB_Notify, disable interrupt + */ + winctx->fifo_disable = true; + winctx->intr_disable = true; + winctx->rx_fifo = NULL; + } + + winctx->lnotify_lpid = rxattr->lnotify_lpid; + winctx->lnotify_pid = rxattr->lnotify_pid; + winctx->lnotify_tid = rxattr->lnotify_tid; + winctx->pswid = rxattr->pswid; + winctx->dma_type = VAS_DMA_TYPE_INJECT; + winctx->tc_mode = rxattr->tc_mode; + + winctx->min_scope = VAS_SCOPE_LOCAL; + winctx->max_scope = VAS_SCOPE_VECTORED_GROUP; +} + +static bool rx_win_args_valid(enum vas_cop_type cop, + struct vas_rx_win_attr *attr) +{ + dump_rx_win_attr(attr); + + if (cop >= VAS_COP_TYPE_MAX) + return false; + + if (cop != VAS_COP_TYPE_FTW && + attr->rx_fifo_size < VAS_RX_FIFO_SIZE_MIN) + return false; + + if (attr->rx_fifo_size > VAS_RX_FIFO_SIZE_MAX) + return false; + + if (attr->nx_win) { + /* cannot be fault or user window if it is nx */ + if (attr->fault_win || attr->user_win) + return false; + /* + * Section 3.1.4.32: NX Windows must not disable notification, + * and must not enable interrupts or early notification. + */ + if (attr->notify_disable || !attr->intr_disable || + attr->notify_early) + return false; + } else if (attr->fault_win) { + /* cannot be both fault and user window */ + if (attr->user_win) + return false; + + /* + * Section 3.1.4.32: Fault windows must disable notification + * but not interrupts. + */ + if (!attr->notify_disable || attr->intr_disable) + return false; + + } else if (attr->user_win) { + /* + * User receive windows are only for fast-thread-wakeup + * (FTW). They don't need a FIFO and must disable interrupts + */ + if (attr->rx_fifo || attr->rx_fifo_size || !attr->intr_disable) + return false; + } else { + /* Rx window must be one of NX or Fault or User window. */ + return false; + } + + return true; +} + +void vas_init_rx_win_attr(struct vas_rx_win_attr *rxattr, enum vas_cop_type cop) +{ + memset(rxattr, 0, sizeof(*rxattr)); + + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) { + rxattr->pin_win = true; + rxattr->nx_win = true; + rxattr->fault_win = false; + rxattr->intr_disable = true; + rxattr->rx_wcred_mode = true; + rxattr->tx_wcred_mode = true; + rxattr->rx_win_ord_mode = true; + rxattr->tx_win_ord_mode = true; + } else if (cop == VAS_COP_TYPE_FAULT) { + rxattr->pin_win = true; + rxattr->fault_win = true; + rxattr->notify_disable = true; + rxattr->rx_wcred_mode = true; + rxattr->tx_wcred_mode = true; + rxattr->rx_win_ord_mode = true; + rxattr->tx_win_ord_mode = true; + } else if (cop == VAS_COP_TYPE_FTW) { + rxattr->user_win = true; + rxattr->intr_disable = true; + + /* + * As noted in the VAS Workbook we disable credit checks. + * If we enable credit checks in the future, we must also + * implement a mechanism to return the user credits or new + * paste operations will fail. + */ + } +} +EXPORT_SYMBOL_GPL(vas_init_rx_win_attr); + +struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop, + struct vas_rx_win_attr *rxattr) +{ + struct vas_window *rxwin; + struct vas_winctx winctx; + struct vas_instance *vinst; + + if (!rx_win_args_valid(cop, rxattr)) + return ERR_PTR(-EINVAL); + + vinst = find_vas_instance(vasid); + if (!vinst) { + pr_devel("vasid %d not found!\n", vasid); + return ERR_PTR(-EINVAL); + } + pr_devel("Found instance %d\n", vasid); + + rxwin = vas_window_alloc(vinst); + if (IS_ERR(rxwin)) { + pr_devel("Unable to allocate memory for Rx window\n"); + return rxwin; + } + + rxwin->tx_win = false; + rxwin->nx_win = rxattr->nx_win; + rxwin->user_win = rxattr->user_win; + rxwin->cop = cop; + if (rxattr->user_win) + rxwin->pid = task_pid_vnr(current); + + init_winctx_for_rxwin(rxwin, rxattr, &winctx); + init_winctx_regs(rxwin, &winctx); + + set_vinst_win(vinst, rxwin); + + return rxwin; +} +EXPORT_SYMBOL_GPL(vas_rx_win_open); + +void vas_init_tx_win_attr(struct vas_tx_win_attr *txattr, enum vas_cop_type cop) +{ + memset(txattr, 0, sizeof(*txattr)); + + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) { + txattr->rej_no_credit = false; + txattr->rx_wcred_mode = true; + txattr->tx_wcred_mode = true; + txattr->rx_win_ord_mode = true; + txattr->tx_win_ord_mode = true; + } else if (cop == VAS_COP_TYPE_FTW) { + txattr->user_win = true; + } +} +EXPORT_SYMBOL_GPL(vas_init_tx_win_attr); + +static void init_winctx_for_txwin(struct vas_window *txwin, + struct vas_tx_win_attr *txattr, + struct vas_winctx *winctx) +{ + /* + * We first zero all fields and only set non-zero ones. Following + * are some fields set to 0/false for the stated reason: + * + * ->notify_os_intr_reg In powernv, send intrs to HV + * ->rsvd_txbuf_count Not supported yet. + * ->notify_disable False for NX windows + * ->xtra_write False for NX windows + * ->notify_early NA for NX windows + * ->lnotify_lpid NA for Tx windows + * ->lnotify_pid NA for Tx windows + * ->lnotify_tid NA for Tx windows + * ->tx_win_cred_mode Ignore for now for NX windows + * ->rx_win_cred_mode Ignore for now for NX windows + */ + memset(winctx, 0, sizeof(struct vas_winctx)); + + winctx->wcreds_max = txattr->wcreds_max ?: VAS_WCREDS_DEFAULT; + + winctx->user_win = txattr->user_win; + winctx->nx_win = txwin->rxwin->nx_win; + winctx->pin_win = txattr->pin_win; + + winctx->rx_wcred_mode = txattr->rx_wcred_mode; + winctx->tx_wcred_mode = txattr->tx_wcred_mode; + winctx->rx_word_mode = txattr->rx_win_ord_mode; + winctx->tx_word_mode = txattr->tx_win_ord_mode; + + if (winctx->nx_win) { + winctx->data_stamp = true; + winctx->intr_disable = true; + } + + winctx->lpid = txattr->lpid; + winctx->pidr = txattr->pidr; + winctx->rx_win_id = txwin->rxwin->winid; + + winctx->dma_type = VAS_DMA_TYPE_INJECT; + winctx->tc_mode = txattr->tc_mode; + winctx->min_scope = VAS_SCOPE_LOCAL; + winctx->max_scope = VAS_SCOPE_VECTORED_GROUP; + + winctx->pswid = 0; +} + +static bool tx_win_args_valid(enum vas_cop_type cop, + struct vas_tx_win_attr *attr) +{ + if (attr->tc_mode != VAS_THRESH_DISABLED) + return false; + + if (cop > VAS_COP_TYPE_MAX) + return false; + + if (attr->user_win && + (cop != VAS_COP_TYPE_FTW || attr->rsvd_txbuf_count)) + return false; + + return true; +} + +struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, + struct vas_tx_win_attr *attr) +{ + int rc; + struct vas_window *txwin; + struct vas_window *rxwin; + struct vas_winctx winctx; + struct vas_instance *vinst; + + if (!tx_win_args_valid(cop, attr)) + return ERR_PTR(-EINVAL); + + vinst = find_vas_instance(vasid); + if (!vinst) { + pr_devel("vasid %d not found!\n", vasid); + return ERR_PTR(-EINVAL); + } + + rxwin = get_vinst_rxwin(vinst, cop, attr->pswid); + if (IS_ERR(rxwin)) { + pr_devel("No RxWin for vasid %d, cop %d\n", vasid, cop); + return rxwin; + } + + txwin = vas_window_alloc(vinst); + if (IS_ERR(txwin)) { + rc = PTR_ERR(txwin); + goto put_rxwin; + } + + txwin->tx_win = 1; + txwin->rxwin = rxwin; + txwin->nx_win = txwin->rxwin->nx_win; + txwin->pid = attr->pid; + txwin->user_win = attr->user_win; + + init_winctx_for_txwin(txwin, attr, &winctx); + + init_winctx_regs(txwin, &winctx); + + /* + * If its a kernel send window, map the window address into the + * kernel's address space. For user windows, user must issue an + * mmap() to map the window into their address space. + * + * NOTE: If kernel ever resubmits a user CRB after handling a page + * fault, we will need to map this into kernel as well. + */ + if (!txwin->user_win) { + txwin->paste_kaddr = map_paste_region(txwin); + if (IS_ERR(txwin->paste_kaddr)) { + rc = PTR_ERR(txwin->paste_kaddr); + goto free_window; + } + } + + set_vinst_win(vinst, txwin); + + return txwin; + +free_window: + vas_window_free(txwin); + +put_rxwin: + put_rx_win(rxwin); + return ERR_PTR(rc); + +} +EXPORT_SYMBOL_GPL(vas_tx_win_open); + +int vas_copy_crb(void *crb, int offset) +{ + return vas_copy(crb, offset); +} +EXPORT_SYMBOL_GPL(vas_copy_crb); + +#define RMA_LSMP_REPORT_ENABLE PPC_BIT(53) +int vas_paste_crb(struct vas_window *txwin, int offset, bool re) +{ + int rc; + void *addr; + uint64_t val; + + /* + * Only NX windows are supported for now and hardware assumes + * report-enable flag is set for NX windows. Ensure software + * complies too. + */ + WARN_ON_ONCE(txwin->nx_win && !re); + + addr = txwin->paste_kaddr; + if (re) { + /* + * Set the REPORT_ENABLE bit (equivalent to writing + * to 1K offset of the paste address) + */ + val = SET_FIELD(RMA_LSMP_REPORT_ENABLE, 0ULL, 1); + addr += val; + } + + /* + * Map the raw CR value from vas_paste() to an error code (there + * is just pass or fail for now though). + */ + rc = vas_paste(addr, offset); + if (rc == 2) + rc = 0; + else + rc = -EINVAL; + + print_fifo_msg_count(txwin); + + return rc; +} +EXPORT_SYMBOL_GPL(vas_paste_crb); + +static void poll_window_busy_state(struct vas_window *window) +{ + int busy; + u64 val; + +retry: + /* + * Poll Window Busy flag + */ + val = read_hvwc_reg(window, VREG(WIN_STATUS)); + busy = GET_FIELD(VAS_WIN_BUSY, val); + if (busy) { + val = 0; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto retry; + } +} + +static void poll_window_castout(struct vas_window *window) +{ + int cached; + u64 val; + + /* Cast window context out of the cache */ +retry: + val = read_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL)); + cached = GET_FIELD(VAS_WIN_CACHE_STATUS, val); + if (cached) { + val = 0ULL; + val = SET_FIELD(VAS_CASTOUT_REQ, val, 1); + val = SET_FIELD(VAS_PUSH_TO_MEM, val, 0); + write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), val); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto retry; + } +} + +/* + * Close a window. + * + * See Section 1.12.1 of VAS workbook v1.05 for details on closing window: + * - Disable new paste operations (unmap paste address) + * - Poll for the "Window Busy" bit to be cleared + * - Clear the Open/Enable bit for the Window. + * - Poll for return of window Credits (implies FIFO empty for Rx win?) + * - Unpin and cast window context out of cache + * + * Besides the hardware, kernel has some bookkeeping of course. + */ +int vas_win_close(struct vas_window *window) +{ + u64 val; + + if (!window) + return 0; + + if (!window->tx_win && atomic_read(&window->num_txwins) != 0) { + pr_devel("Attempting to close an active Rx window!\n"); + WARN_ON_ONCE(1); + return -EBUSY; + } + + unmap_paste_region(window); + + clear_vinst_win(window); + + poll_window_busy_state(window); + + /* Unpin window from cache and close it */ + val = read_hvwc_reg(window, VREG(WINCTL)); + val = SET_FIELD(VAS_WINCTL_PIN, val, 0); + val = SET_FIELD(VAS_WINCTL_OPEN, val, 0); + write_hvwc_reg(window, VREG(WINCTL), val); + + poll_window_castout(window); + + /* if send window, drop reference to matching receive window */ + if (window->tx_win) + put_rx_win(window->rxwin); + + vas_window_free(window); + + return 0; +} +EXPORT_SYMBOL_GPL(vas_win_close); diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c new file mode 100644 index 0000000000000000000000000000000000000000..565a4878fefa2f41742ec5b54d794dd36055eed2 --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas.c @@ -0,0 +1,151 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "vas: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vas.h" + +static DEFINE_MUTEX(vas_mutex); +static LIST_HEAD(vas_instances); + +static int init_vas_instance(struct platform_device *pdev) +{ + int rc, vasid; + struct resource *res; + struct vas_instance *vinst; + struct device_node *dn = pdev->dev.of_node; + + rc = of_property_read_u32(dn, "ibm,vas-id", &vasid); + if (rc) { + pr_err("No ibm,vas-id property for %s?\n", pdev->name); + return -ENODEV; + } + + if (pdev->num_resources != 4) { + pr_err("Unexpected DT configuration for [%s, %d]\n", + pdev->name, vasid); + return -ENODEV; + } + + vinst = kzalloc(sizeof(*vinst), GFP_KERNEL); + if (!vinst) + return -ENOMEM; + + INIT_LIST_HEAD(&vinst->node); + ida_init(&vinst->ida); + mutex_init(&vinst->mutex); + vinst->vas_id = vasid; + vinst->pdev = pdev; + + res = &pdev->resource[0]; + vinst->hvwc_bar_start = res->start; + + res = &pdev->resource[1]; + vinst->uwc_bar_start = res->start; + + res = &pdev->resource[2]; + vinst->paste_base_addr = res->start; + + res = &pdev->resource[3]; + if (res->end > 62) { + pr_err("Bad 'paste_win_id_shift' in DT, %llx\n", res->end); + goto free_vinst; + } + + vinst->paste_win_id_shift = 63 - res->end; + + pr_devel("Initialized instance [%s, %d], paste_base 0x%llx, " + "paste_win_id_shift 0x%llx\n", pdev->name, vasid, + vinst->paste_base_addr, vinst->paste_win_id_shift); + + mutex_lock(&vas_mutex); + list_add(&vinst->node, &vas_instances); + mutex_unlock(&vas_mutex); + + dev_set_drvdata(&pdev->dev, vinst); + + return 0; + +free_vinst: + kfree(vinst); + return -ENODEV; + +} + +/* + * Although this is read/used multiple times, it is written to only + * during initialization. + */ +struct vas_instance *find_vas_instance(int vasid) +{ + struct list_head *ent; + struct vas_instance *vinst; + + mutex_lock(&vas_mutex); + list_for_each(ent, &vas_instances) { + vinst = list_entry(ent, struct vas_instance, node); + if (vinst->vas_id == vasid) { + mutex_unlock(&vas_mutex); + return vinst; + } + } + mutex_unlock(&vas_mutex); + + pr_devel("Instance %d not found\n", vasid); + return NULL; +} + +static int vas_probe(struct platform_device *pdev) +{ + return init_vas_instance(pdev); +} + +static const struct of_device_id powernv_vas_match[] = { + { .compatible = "ibm,vas",}, + {}, +}; + +static struct platform_driver vas_driver = { + .driver = { + .name = "vas", + .of_match_table = powernv_vas_match, + }, + .probe = vas_probe, +}; + +static int __init vas_init(void) +{ + int found = 0; + struct device_node *dn; + + platform_driver_register(&vas_driver); + + for_each_compatible_node(dn, NULL, "ibm,vas") { + of_platform_device_create(dn, NULL, NULL); + found++; + } + + if (!found) + return -ENODEV; + + pr_devel("Found %d instances\n", found); + + return 0; +} +device_initcall(vas_init); diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h new file mode 100644 index 0000000000000000000000000000000000000000..38dee5d50f316c52d8373202c8bbc78b0f8d839d --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas.h @@ -0,0 +1,467 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _VAS_H +#define _VAS_H +#include +#include +#include +#include + +/* + * Overview of Virtual Accelerator Switchboard (VAS). + * + * VAS is a hardware "switchboard" that allows senders and receivers to + * exchange messages with _minimal_ kernel involvment. The receivers are + * typically NX coprocessor engines that perform compression or encryption + * in hardware, but receivers can also be other software threads. + * + * Senders are user/kernel threads that submit compression/encryption or + * other requests to the receivers. Senders must format their messages as + * Coprocessor Request Blocks (CRB)s and submit them using the "copy" and + * "paste" instructions which were introduced in Power9. + * + * A Power node can have (upto?) 8 Power chips. There is one instance of + * VAS in each Power9 chip. Each instance of VAS has 64K windows or ports, + * Senders and receivers must each connect to a separate window before they + * can exchange messages through the switchboard. + * + * Each window is described by two types of window contexts: + * + * Hypervisor Window Context (HVWC) of size VAS_HVWC_SIZE bytes + * + * OS/User Window Context (UWC) of size VAS_UWC_SIZE bytes. + * + * A window context can be viewed as a set of 64-bit registers. The settings + * in these registers configure/control/determine the behavior of the VAS + * hardware when messages are sent/received through the window. The registers + * in the HVWC are configured by the kernel while the registers in the UWC can + * be configured by the kernel or by the user space application that is using + * the window. + * + * The HVWCs for all windows on a specific instance of VAS are in a contiguous + * range of hardware addresses or Base address region (BAR) referred to as the + * HVWC BAR for the instance. Similarly the UWCs for all windows on an instance + * are referred to as the UWC BAR for the instance. + * + * The two BARs for each instance are defined Power9 MMIO Ranges spreadsheet + * and available to the kernel in the VAS node's "reg" property in the device + * tree: + * + * /proc/device-tree/vasm@.../reg + * + * (see vas_probe() for details on the reg property). + * + * The kernel maps the HVWC and UWC BAR regions into the kernel address + * space (hvwc_map and uwc_map). The kernel can then access the window + * contexts of a specific window using: + * + * hvwc = hvwc_map + winid * VAS_HVWC_SIZE. + * uwc = uwc_map + winid * VAS_UWC_SIZE. + * + * where winid is the window index (0..64K). + * + * As mentioned, a window context is used to "configure" a window. Besides + * this configuration address, each _send_ window also has a unique hardware + * "paste" address that is used to submit requests/CRBs (see vas_paste_crb()). + * + * The hardware paste address for a window is computed using the "paste + * base address" and "paste win id shift" reg properties in the VAS device + * tree node using: + * + * paste_addr = paste_base + ((winid << paste_win_id_shift)) + * + * (again, see vas_probe() for ->paste_base_addr and ->paste_win_id_shift). + * + * The kernel maps this hardware address into the sender's address space + * after which they can use the 'paste' instruction (new in Power9) to + * send a message (submit a request aka CRB) to the coprocessor. + * + * NOTE: In the initial version, senders can only in-kernel drivers/threads. + * Support for user space threads will be added in follow-on patches. + * + * TODO: Do we need to map the UWC into user address space so they can return + * credits? Its NA for NX but may be needed for other receive windows. + * + */ + +#define VAS_WINDOWS_PER_CHIP (64 << 10) + +/* + * Hypervisor and OS/USer Window Context sizes + */ +#define VAS_HVWC_SIZE 512 +#define VAS_UWC_SIZE PAGE_SIZE + +/* + * Initial per-process credits. + * Max send window credits: 4K-1 (12-bits in VAS_TX_WCRED) + * Max receive window credits: 64K-1 (16 bits in VAS_LRX_WCRED) + * + * TODO: Needs tuning for per-process credits + */ +#define VAS_WCREDS_MIN 16 +#define VAS_WCREDS_MAX ((64 << 10) - 1) +#define VAS_WCREDS_DEFAULT (1 << 10) + +/* + * VAS Window Context Register Offsets and bitmasks. + * See Section 3.1.4 of VAS Work book + */ +#define VAS_LPID_OFFSET 0x010 +#define VAS_LPID PPC_BITMASK(0, 11) + +#define VAS_PID_OFFSET 0x018 +#define VAS_PID_ID PPC_BITMASK(0, 19) + +#define VAS_XLATE_MSR_OFFSET 0x020 +#define VAS_XLATE_MSR_DR PPC_BIT(0) +#define VAS_XLATE_MSR_TA PPC_BIT(1) +#define VAS_XLATE_MSR_PR PPC_BIT(2) +#define VAS_XLATE_MSR_US PPC_BIT(3) +#define VAS_XLATE_MSR_HV PPC_BIT(4) +#define VAS_XLATE_MSR_SF PPC_BIT(5) + +#define VAS_XLATE_LPCR_OFFSET 0x028 +#define VAS_XLATE_LPCR_PAGE_SIZE PPC_BITMASK(0, 2) +#define VAS_XLATE_LPCR_ISL PPC_BIT(3) +#define VAS_XLATE_LPCR_TC PPC_BIT(4) +#define VAS_XLATE_LPCR_SC PPC_BIT(5) + +#define VAS_XLATE_CTL_OFFSET 0x030 +#define VAS_XLATE_MODE PPC_BITMASK(0, 1) + +#define VAS_AMR_OFFSET 0x040 +#define VAS_AMR PPC_BITMASK(0, 63) + +#define VAS_SEIDR_OFFSET 0x048 +#define VAS_SEIDR PPC_BITMASK(0, 63) + +#define VAS_FAULT_TX_WIN_OFFSET 0x050 +#define VAS_FAULT_TX_WIN PPC_BITMASK(48, 63) + +#define VAS_OSU_INTR_SRC_RA_OFFSET 0x060 +#define VAS_OSU_INTR_SRC_RA PPC_BITMASK(8, 63) + +#define VAS_HV_INTR_SRC_RA_OFFSET 0x070 +#define VAS_HV_INTR_SRC_RA PPC_BITMASK(8, 63) + +#define VAS_PSWID_OFFSET 0x078 +#define VAS_PSWID_EA_HANDLE PPC_BITMASK(0, 31) + +#define VAS_SPARE1_OFFSET 0x080 +#define VAS_SPARE2_OFFSET 0x088 +#define VAS_SPARE3_OFFSET 0x090 +#define VAS_SPARE4_OFFSET 0x130 +#define VAS_SPARE5_OFFSET 0x160 +#define VAS_SPARE6_OFFSET 0x188 + +#define VAS_LFIFO_BAR_OFFSET 0x0A0 +#define VAS_LFIFO_BAR PPC_BITMASK(8, 53) +#define VAS_PAGE_MIGRATION_SELECT PPC_BITMASK(54, 56) + +#define VAS_LDATA_STAMP_CTL_OFFSET 0x0A8 +#define VAS_LDATA_STAMP PPC_BITMASK(0, 1) +#define VAS_XTRA_WRITE PPC_BIT(2) + +#define VAS_LDMA_CACHE_CTL_OFFSET 0x0B0 +#define VAS_LDMA_TYPE PPC_BITMASK(0, 1) +#define VAS_LDMA_FIFO_DISABLE PPC_BIT(2) + +#define VAS_LRFIFO_PUSH_OFFSET 0x0B8 +#define VAS_LRFIFO_PUSH PPC_BITMASK(0, 15) + +#define VAS_CURR_MSG_COUNT_OFFSET 0x0C0 +#define VAS_CURR_MSG_COUNT PPC_BITMASK(0, 7) + +#define VAS_LNOTIFY_AFTER_COUNT_OFFSET 0x0C8 +#define VAS_LNOTIFY_AFTER_COUNT PPC_BITMASK(0, 7) + +#define VAS_LRX_WCRED_OFFSET 0x0E0 +#define VAS_LRX_WCRED PPC_BITMASK(0, 15) + +#define VAS_LRX_WCRED_ADDER_OFFSET 0x190 +#define VAS_LRX_WCRED_ADDER PPC_BITMASK(0, 15) + +#define VAS_TX_WCRED_OFFSET 0x0F0 +#define VAS_TX_WCRED PPC_BITMASK(4, 15) + +#define VAS_TX_WCRED_ADDER_OFFSET 0x1A0 +#define VAS_TX_WCRED_ADDER PPC_BITMASK(4, 15) + +#define VAS_LFIFO_SIZE_OFFSET 0x100 +#define VAS_LFIFO_SIZE PPC_BITMASK(0, 3) + +#define VAS_WINCTL_OFFSET 0x108 +#define VAS_WINCTL_OPEN PPC_BIT(0) +#define VAS_WINCTL_REJ_NO_CREDIT PPC_BIT(1) +#define VAS_WINCTL_PIN PPC_BIT(2) +#define VAS_WINCTL_TX_WCRED_MODE PPC_BIT(3) +#define VAS_WINCTL_RX_WCRED_MODE PPC_BIT(4) +#define VAS_WINCTL_TX_WORD_MODE PPC_BIT(5) +#define VAS_WINCTL_RX_WORD_MODE PPC_BIT(6) +#define VAS_WINCTL_RSVD_TXBUF PPC_BIT(7) +#define VAS_WINCTL_THRESH_CTL PPC_BITMASK(8, 9) +#define VAS_WINCTL_FAULT_WIN PPC_BIT(10) +#define VAS_WINCTL_NX_WIN PPC_BIT(11) + +#define VAS_WIN_STATUS_OFFSET 0x110 +#define VAS_WIN_BUSY PPC_BIT(1) + +#define VAS_WIN_CTX_CACHING_CTL_OFFSET 0x118 +#define VAS_CASTOUT_REQ PPC_BIT(0) +#define VAS_PUSH_TO_MEM PPC_BIT(1) +#define VAS_WIN_CACHE_STATUS PPC_BIT(4) + +#define VAS_TX_RSVD_BUF_COUNT_OFFSET 0x120 +#define VAS_RXVD_BUF_COUNT PPC_BITMASK(58, 63) + +#define VAS_LRFIFO_WIN_PTR_OFFSET 0x128 +#define VAS_LRX_WIN_ID PPC_BITMASK(0, 15) + +/* + * Local Notification Control Register controls what happens in _response_ + * to a paste command and hence applies only to receive windows. + */ +#define VAS_LNOTIFY_CTL_OFFSET 0x138 +#define VAS_NOTIFY_DISABLE PPC_BIT(0) +#define VAS_INTR_DISABLE PPC_BIT(1) +#define VAS_NOTIFY_EARLY PPC_BIT(2) +#define VAS_NOTIFY_OSU_INTR PPC_BIT(3) + +#define VAS_LNOTIFY_PID_OFFSET 0x140 +#define VAS_LNOTIFY_PID PPC_BITMASK(0, 19) + +#define VAS_LNOTIFY_LPID_OFFSET 0x148 +#define VAS_LNOTIFY_LPID PPC_BITMASK(0, 11) + +#define VAS_LNOTIFY_TID_OFFSET 0x150 +#define VAS_LNOTIFY_TID PPC_BITMASK(0, 15) + +#define VAS_LNOTIFY_SCOPE_OFFSET 0x158 +#define VAS_LNOTIFY_MIN_SCOPE PPC_BITMASK(0, 1) +#define VAS_LNOTIFY_MAX_SCOPE PPC_BITMASK(2, 3) + +#define VAS_NX_UTIL_OFFSET 0x1B0 +#define VAS_NX_UTIL PPC_BITMASK(0, 63) + +/* SE: Side effects */ +#define VAS_NX_UTIL_SE_OFFSET 0x1B8 +#define VAS_NX_UTIL_SE PPC_BITMASK(0, 63) + +#define VAS_NX_UTIL_ADDER_OFFSET 0x180 +#define VAS_NX_UTIL_ADDER PPC_BITMASK(32, 63) + +/* + * Local Notify Scope Control Register. (Receive windows only). + */ +enum vas_notify_scope { + VAS_SCOPE_LOCAL, + VAS_SCOPE_GROUP, + VAS_SCOPE_VECTORED_GROUP, + VAS_SCOPE_UNUSED, +}; + +/* + * Local DMA Cache Control Register (Receive windows only). + */ +enum vas_dma_type { + VAS_DMA_TYPE_INJECT, + VAS_DMA_TYPE_WRITE, +}; + +/* + * Local Notify Scope Control Register. (Receive windows only). + * Not applicable to NX receive windows. + */ +enum vas_notify_after_count { + VAS_NOTIFY_AFTER_256 = 0, + VAS_NOTIFY_NONE, + VAS_NOTIFY_AFTER_2 +}; + +/* + * One per instance of VAS. Each instance will have a separate set of + * receive windows, one per coprocessor type. + * + * See also function header of set_vinst_win() for details on ->windows[] + * and ->rxwin[] tables. + */ +struct vas_instance { + int vas_id; + struct ida ida; + struct list_head node; + struct platform_device *pdev; + + u64 hvwc_bar_start; + u64 uwc_bar_start; + u64 paste_base_addr; + u64 paste_win_id_shift; + + struct mutex mutex; + struct vas_window *rxwin[VAS_COP_TYPE_MAX]; + struct vas_window *windows[VAS_WINDOWS_PER_CHIP]; +}; + +/* + * In-kernel state a VAS window. One per window. + */ +struct vas_window { + /* Fields common to send and receive windows */ + struct vas_instance *vinst; + int winid; + bool tx_win; /* True if send window */ + bool nx_win; /* True if NX window */ + bool user_win; /* True if user space window */ + void *hvwc_map; /* HV window context */ + void *uwc_map; /* OS/User window context */ + pid_t pid; /* Linux process id of owner */ + + /* Fields applicable only to send windows */ + void *paste_kaddr; + char *paste_addr_name; + struct vas_window *rxwin; + + /* Feilds applicable only to receive windows */ + enum vas_cop_type cop; + atomic_t num_txwins; +}; + +/* + * Container for the hardware state of a window. One per-window. + * + * A VAS Window context is a 512-byte area in the hardware that contains + * a set of 64-bit registers. Individual bit-fields in these registers + * determine the configuration/operation of the hardware. struct vas_winctx + * is a container for the register fields in the window context. + */ +struct vas_winctx { + void *rx_fifo; + int rx_fifo_size; + int wcreds_max; + int rsvd_txbuf_count; + + bool user_win; + bool nx_win; + bool fault_win; + bool rsvd_txbuf_enable; + bool pin_win; + bool rej_no_credit; + bool tx_wcred_mode; + bool rx_wcred_mode; + bool tx_word_mode; + bool rx_word_mode; + bool data_stamp; + bool xtra_write; + bool notify_disable; + bool intr_disable; + bool fifo_disable; + bool notify_early; + bool notify_os_intr_reg; + + int lpid; + int pidr; /* value from SPRN_PID, not linux pid */ + int lnotify_lpid; + int lnotify_pid; + int lnotify_tid; + u32 pswid; + int rx_win_id; + int fault_win_id; + int tc_mode; + + u64 irq_port; + + enum vas_dma_type dma_type; + enum vas_notify_scope min_scope; + enum vas_notify_scope max_scope; + enum vas_notify_after_count notify_after_count; +}; + +extern struct vas_instance *find_vas_instance(int vasid); + +/* + * VREG(x): + * Expand a register's short name (eg: LPID) into two parameters: + * - the register's short name in string form ("LPID"), and + * - the name of the macro (eg: VAS_LPID_OFFSET), defining the + * register's offset in the window context + */ +#define VREG_SFX(n, s) __stringify(n), VAS_##n##s +#define VREG(r) VREG_SFX(r, _OFFSET) + +#ifdef vas_debug +static inline void dump_rx_win_attr(struct vas_rx_win_attr *attr) +{ + pr_err("fault %d, notify %d, intr %d early %d\n", + attr->fault_win, attr->notify_disable, + attr->intr_disable, attr->notify_early); + + pr_err("rx_fifo_size %d, max value %d\n", + attr->rx_fifo_size, VAS_RX_FIFO_SIZE_MAX); +} + +static inline void vas_log_write(struct vas_window *win, char *name, + void *regptr, u64 val) +{ + if (val) + pr_err("%swin #%d: %s reg %p, val 0x%016llx\n", + win->tx_win ? "Tx" : "Rx", win->winid, name, + regptr, val); +} + +#else /* vas_debug */ + +#define vas_log_write(win, name, reg, val) +#define dump_rx_win_attr(attr) + +#endif /* vas_debug */ + +static inline void write_uwc_reg(struct vas_window *win, char *name, + s32 reg, u64 val) +{ + void *regptr; + + regptr = win->uwc_map + reg; + vas_log_write(win, name, regptr, val); + + out_be64(regptr, val); +} + +static inline void write_hvwc_reg(struct vas_window *win, char *name, + s32 reg, u64 val) +{ + void *regptr; + + regptr = win->hvwc_map + reg; + vas_log_write(win, name, regptr, val); + + out_be64(regptr, val); +} + +static inline u64 read_hvwc_reg(struct vas_window *win, + char *name __maybe_unused, s32 reg) +{ + return in_be64(win->hvwc_map+reg); +} + +#ifdef vas_debug + +static void print_fifo_msg_count(struct vas_window *txwin) +{ + uint64_t read_hvwc_reg(struct vas_window *w, char *n, uint64_t o); + pr_devel("Winid %d, Msg count %llu\n", txwin->winid, + (uint64_t)read_hvwc_reg(txwin, VREG(LRFIFO_PUSH))); +} +#else /* vas_debug */ + +#define print_fifo_msg_count(window) + +#endif /* vas_debug */ + +#endif /* _VAS_H */ diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 814a7eaa77691aaf0d5642805eb03dae7e9bedc9..50dbaf24b1ee67f6ec622c6e4584613eb4a17648 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -170,14 +170,8 @@ int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id) { - int result; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("id", 0), - 0, 0, - bus_id, NULL); - return result; + return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), + make_field("id", 0), 0, 0, bus_id, NULL); } int ps3_repository_read_bus_type(unsigned int bus_index, @@ -224,15 +218,9 @@ int ps3_repository_read_dev_str(unsigned int bus_index, int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, u64 *dev_id) { - int result; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("id", 0), - 0, - dev_id, NULL); - return result; + return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), + make_field("dev", dev_index), make_field("id", 0), 0, + dev_id, NULL); } int ps3_repository_read_dev_type(unsigned int bus_index, diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 6244bc849469e33af7dcc5a4ac2b21dd970ac1c6..9dabea6e14439647b726d007a63de63a853ac3d0 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -104,20 +104,6 @@ static void __noreturn ps3_halt(void) ps3_sys_manager_halt(); /* never returns */ } -static void ps3_panic(char *str) -{ - DBG("%s:%d %s\n", __func__, __LINE__, str); - - smp_send_stop(); - printk("\n"); - printk(" System does not reboot automatically.\n"); - printk(" Please press POWER button.\n"); - printk("\n"); - - while(1) - lv1_pause(1); -} - #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \ defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) static void __init prealloc(struct ps3_prealloc *p) @@ -269,7 +255,6 @@ define_machine(ps3) { .probe = ps3_probe, .setup_arch = ps3_setup_arch, .init_IRQ = ps3_init_IRQ, - .panic = ps3_panic, .get_boot_time = ps3_get_boot_time, .set_dabr = ps3_set_dabr, .calibrate_decr = ps3_calibrate_decr, diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 3a6dfd14f64ba236a1a7eaea7f0aae6e607eab67..71dd69d9ec64578e32292f772d43b6056347c896 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -7,6 +7,7 @@ config PPC_PSERIES select PCI select PCI_MSI select PPC_XICS + select PPC_XIVE_SPAPR select PPC_ICP_NATIVE select PPC_ICP_HV select PPC_ICS_RTAS diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 39187696ee74b2bc6b3d10a6a0638474b6de326e..e45b5f10645ae54b6610298a0a03c07f7e5d0966 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -254,22 +254,18 @@ struct device_node *dlpar_configure_connector(__be32 drc_index, return first_dn; } -int dlpar_attach_node(struct device_node *dn) +int dlpar_attach_node(struct device_node *dn, struct device_node *parent) { int rc; - dn->parent = pseries_of_derive_parent(dn->full_name); - if (IS_ERR(dn->parent)) - return PTR_ERR(dn->parent); + dn->parent = parent; rc = of_attach_node(dn); if (rc) { - printk(KERN_ERR "Failed to add device node %s\n", - dn->full_name); + printk(KERN_ERR "Failed to add device node %pOF\n", dn); return rc; } - of_node_put(dn->parent); return 0; } diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 1eef46d9cf304bc5b7a8457f13f6dd59e339d1dc..6b812ad990e48318803c0d1d5d6d02e569c2ee9c 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -247,14 +247,13 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) /* Initialize the fake PE */ memset(&pe, 0, sizeof(struct eeh_pe)); - pe.phb = edev->phb; + pe.phb = pdn->phb; pe.config_addr = (pdn->busno << 16) | (pdn->devfn << 8); /* Enable EEH on the device */ ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); if (!ret) { /* Retrieve PE address */ - edev->config_addr = (pdn->busno << 16) | (pdn->devfn << 8); edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); pe.addr = edev->pe_config_addr; @@ -279,7 +278,6 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) /* This device doesn't support EEH, but it may have an * EEH parent, in which case we mark it as supported. */ - edev->config_addr = pdn_to_eeh_dev(pdn->parent)->config_addr; edev->pe_config_addr = pdn_to_eeh_dev(pdn->parent)->pe_config_addr; eeh_add_to_parent_pe(edev); } diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c index 32187dc76730966481bbe3f90070e6845defdbcc..6eeb0d4bab6129b17b989b82d8a513fa55739fe3 100644 --- a/arch/powerpc/platforms/pseries/event_sources.c +++ b/arch/powerpc/platforms/pseries/event_sources.c @@ -36,8 +36,8 @@ void request_event_sources_irqs(struct device_node *np, virqs[count] = irq_create_of_mapping(&oirq); if (!virqs[count]) { pr_err("event-sources: Unable to allocate " - "interrupt number for %s\n", - np->full_name); + "interrupt number for %pOF\n", + np); WARN_ON(1); } else { count++; @@ -48,7 +48,7 @@ void request_event_sources_irqs(struct device_node *np, for (i = 0; i < count; i++) { if (request_irq(virqs[i], handler, 0, name, NULL)) { pr_err("event-sources: Unable to request interrupt " - "%d for %s\n", virqs[i], np->full_name); + "%d for %pOF\n", virqs[i], np); WARN_ON(1); return; } diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6afd1efd3633f2a2b89fdf7d28b88cd2326c3900..fadb95efbb9e1856ed8a7182cf870dcf3a5f5331 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "pseries.h" @@ -109,7 +110,10 @@ static void pseries_mach_cpu_die(void) local_irq_disable(); idle_task_exit(); - xics_teardown_cpu(); + if (xive_enabled()) + xive_teardown_cpu(); + else + xics_teardown_cpu(); if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { set_cpu_current_state(cpu, CPU_STATE_INACTIVE); @@ -174,7 +178,10 @@ static int pseries_cpu_disable(void) boot_cpuid = cpumask_any(cpu_online_mask); /* FIXME: abstract this to not be platform specific later on */ - xics_migrate_irqs_away(); + if (xive_enabled()) + xive_smp_disable_cpu(); + else + xics_migrate_irqs_away(); return 0; } @@ -264,8 +271,8 @@ static int pseries_add_processor(struct device_node *np) /* If we get here, it most likely means that NR_CPUS is * less than the partition's max processors setting. */ - printk(KERN_ERR "Cannot add cpu %s; this system configuration" - " supports %d logical cpus.\n", np->full_name, + printk(KERN_ERR "Cannot add cpu %pOF; this system configuration" + " supports %d logical cpus.\n", np, num_possible_cpus()); goto out_unlock; } @@ -455,15 +462,19 @@ static ssize_t dlpar_cpu_add(u32 drc_index) } dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); - of_node_put(parent); if (!dn) { pr_warn("Failed call to configure-connector, drc index: %x\n", drc_index); dlpar_release_drc(drc_index); + of_node_put(parent); return -EINVAL; } - rc = dlpar_attach_node(dn); + rc = dlpar_attach_node(dn, parent); + + /* Regardless we are done with parent now */ + of_node_put(parent); + if (rc) { saved_rc = rc; pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n", diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index ca9b2f4aaa22f4107e08577b581bb0c813a1473a..1d48ab424bd9029a1da7ec310a76bd119c582961 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -336,7 +336,38 @@ static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb) return mem_block; } +static int dlpar_change_lmb_state(struct of_drconf_cell *lmb, bool online) +{ + struct memory_block *mem_block; + int rc; + + mem_block = lmb_to_memblock(lmb); + if (!mem_block) + return -EINVAL; + + if (online && mem_block->dev.offline) + rc = device_online(&mem_block->dev); + else if (!online && !mem_block->dev.offline) + rc = device_offline(&mem_block->dev); + else + rc = 0; + + put_device(&mem_block->dev); + + return rc; +} + +static int dlpar_online_lmb(struct of_drconf_cell *lmb) +{ + return dlpar_change_lmb_state(lmb, true); +} + #ifdef CONFIG_MEMORY_HOTREMOVE +static int dlpar_offline_lmb(struct of_drconf_cell *lmb) +{ + return dlpar_change_lmb_state(lmb, false); +} + static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long block_sz, start_pfn; @@ -431,19 +462,13 @@ static int dlpar_add_lmb(struct of_drconf_cell *); static int dlpar_remove_lmb(struct of_drconf_cell *lmb) { - struct memory_block *mem_block; unsigned long block_sz; int nid, rc; if (!lmb_is_removable(lmb)) return -EINVAL; - mem_block = lmb_to_memblock(lmb); - if (!mem_block) - return -EINVAL; - - rc = device_offline(&mem_block->dev); - put_device(&mem_block->dev); + rc = dlpar_offline_lmb(lmb); if (rc) return rc; @@ -737,20 +762,6 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index, } #endif /* CONFIG_MEMORY_HOTREMOVE */ -static int dlpar_online_lmb(struct of_drconf_cell *lmb) -{ - struct memory_block *mem_block; - int rc; - - mem_block = lmb_to_memblock(lmb); - if (!mem_block) - return -EINVAL; - - rc = device_online(&mem_block->dev); - put_device(&mem_block->dev); - return rc; -} - static int dlpar_add_lmb(struct of_drconf_cell *lmb) { unsigned long block_sz; @@ -817,6 +828,9 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) return -EINVAL; for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) { + if (lmbs[i].flags & DRCONF_MEM_ASSIGNED) + continue; + rc = dlpar_acquire_drc(lmbs[i].drc_index); if (rc) continue; @@ -859,6 +873,7 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) lmbs[i].base_addr, lmbs[i].drc_index); lmbs[i].reserved = 0; } + rc = 0; } return rc; diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 74b5b8e239c8235ac61b529b8085cc3ceff096ed..c511a1743a449aa6e0da5932c411f595708322b0 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -23,7 +23,7 @@ .globl hcall_tracepoint_refcount hcall_tracepoint_refcount: - .llong 0 + .8byte 0 .section ".text" #endif diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index 52146b1356d240c3fa34392fd97533939f534346..408a8604413300bd0085158f75247752318db8a6 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -150,8 +150,7 @@ static const struct dma_map_ops ibmebus_dma_ops = { static int ibmebus_match_path(struct device *dev, void *data) { struct device_node *dn = to_platform_device(dev)->dev.of_node; - return (dn->full_name && - (strcasecmp((char *)data, dn->full_name) == 0)); + return (of_find_node_by_path(data) == dn); } static int ibmebus_match_node(struct device *dev, void *data) @@ -395,7 +394,7 @@ static ssize_t devspec_show(struct device *dev, struct platform_device *ofdev; ofdev = to_platform_device(dev); - return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); + return sprintf(buf, "%pOF\n", ofdev->dev.of_node); } static DEVICE_ATTR_RO(devspec); diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 8374adee27e36b17ffddcbe5481e173fa2b3a6ff..7c181467d0ad9b14785291a8aa11c5d9b6284587 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -511,8 +511,8 @@ static void iommu_table_setparms(struct pci_controller *phb, basep = of_get_property(node, "linux,tce-base", NULL); sizep = of_get_property(node, "linux,tce-size", NULL); if (basep == NULL || sizep == NULL) { - printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has " - "missing tce entries !\n", dn->full_name); + printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %pOF has " + "missing tce entries !\n", dn); return; } @@ -587,7 +587,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) dn = pci_bus_to_OF_node(bus); - pr_debug("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name); + pr_debug("pci_dma_bus_setup_pSeries: setting up bus %pOF\n", dn); if (bus->self) { /* This is not a root bus, any setup will be done for the @@ -701,8 +701,8 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) dn = pci_bus_to_OF_node(bus); - pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", - dn->full_name); + pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %pOF\n", + dn); /* Find nearest ibm,dma-window, walking up the device tree */ for (pdn = dn; pdn != NULL; pdn = pdn->parent) { @@ -718,8 +718,8 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) ppci = PCI_DN(pdn); - pr_debug(" parent is %s, iommu_table: 0x%p\n", - pdn->full_name, ppci->table_group); + pr_debug(" parent is %pOF, iommu_table: 0x%p\n", + pdn, ppci->table_group); if (!ppci->table_group) { ppci->table_group = iommu_pseries_alloc_group(ppci->phb->node); @@ -817,28 +817,28 @@ static void remove_ddw(struct device_node *np, bool remove_prop) ret = tce_clearrange_multi_pSeriesLP(0, 1ULL << (be32_to_cpu(dwp->window_shift) - PAGE_SHIFT), dwp); if (ret) - pr_warning("%s failed to clear tces in window.\n", - np->full_name); + pr_warning("%pOF failed to clear tces in window.\n", + np); else - pr_debug("%s successfully cleared tces in window.\n", - np->full_name); + pr_debug("%pOF successfully cleared tces in window.\n", + np); ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn); if (ret) - pr_warning("%s: failed to remove direct window: rtas returned " + pr_warning("%pOF: failed to remove direct window: rtas returned " "%d to ibm,remove-pe-dma-window(%x) %llx\n", - np->full_name, ret, ddw_avail[2], liobn); + np, ret, ddw_avail[2], liobn); else - pr_debug("%s: successfully removed direct window: rtas returned " + pr_debug("%pOF: successfully removed direct window: rtas returned " "%d to ibm,remove-pe-dma-window(%x) %llx\n", - np->full_name, ret, ddw_avail[2], liobn); + np, ret, ddw_avail[2], liobn); delprop: if (remove_prop) ret = of_remove_property(np, win64); if (ret) - pr_warning("%s: failed to remove direct window property: %d\n", - np->full_name, ret); + pr_warning("%pOF: failed to remove direct window property: %d\n", + np, ret); } static u64 find_existing_ddw(struct device_node *pdn) @@ -1004,7 +1004,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) * list. */ list_for_each_entry(fpdn, &failed_ddw_pdn_list, list) { - if (!strcmp(fpdn->pdn->full_name, pdn->full_name)) + if (fpdn->pdn == pdn) goto out_unlock; } @@ -1087,8 +1087,8 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) ddwprop->tce_shift = cpu_to_be32(page_shift); ddwprop->window_shift = cpu_to_be32(len); - dev_dbg(&dev->dev, "created tce table LIOBN 0x%x for %s\n", - create.liobn, dn->full_name); + dev_dbg(&dev->dev, "created tce table LIOBN 0x%x for %pOF\n", + create.liobn, dn); window = kzalloc(sizeof(*window), GFP_KERNEL); if (!window) @@ -1097,15 +1097,15 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT, win64->value, tce_setrange_multi_pSeriesLP_walk); if (ret) { - dev_info(&dev->dev, "failed to map direct window for %s: %d\n", - dn->full_name, ret); + dev_info(&dev->dev, "failed to map direct window for %pOF: %d\n", + dn, ret); goto out_free_window; } ret = of_add_property(pdn, win64); if (ret) { - dev_err(&dev->dev, "unable to add dma window property for %s: %d", - pdn->full_name, ret); + dev_err(&dev->dev, "unable to add dma window property for %pOF: %d", + pdn, ret); goto out_free_window; } @@ -1158,7 +1158,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) * already allocated. */ dn = pci_device_to_OF_node(dev); - pr_debug(" node is %s\n", dn->full_name); + pr_debug(" node is %pOF\n", dn); for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group; pdn = pdn->parent) { @@ -1169,11 +1169,11 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) if (!pdn || !PCI_DN(pdn)) { printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: " - "no DMA window found for pci dev=%s dn=%s\n", - pci_name(dev), of_node_full_name(dn)); + "no DMA window found for pci dev=%s dn=%pOF\n", + pci_name(dev), dn); return; } - pr_debug(" parent is %s\n", pdn->full_name); + pr_debug(" parent is %pOF\n", pdn); pci = PCI_DN(pdn); if (!pci->table_group) { @@ -1213,7 +1213,7 @@ static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask) /* only attempt to use a new window if 64-bit DMA is requested */ if (!disable_ddw && dma_mask == DMA_BIT_MASK(64)) { dn = pci_device_to_OF_node(pdev); - dev_dbg(dev, "node is %s\n", dn->full_name); + dev_dbg(dev, "node is %pOF\n", dn); /* * the device tree might contain the dma-window properties diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c index 6681ac97fb1830d30638676698287d0d3d42fdae..eeb13429d68535e50e2d80f05ce8d89ba01fbc4c 100644 --- a/arch/powerpc/platforms/pseries/kexec.c +++ b/arch/powerpc/platforms/pseries/kexec.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -51,5 +52,8 @@ void pseries_kexec_cpu_down(int crash_shutdown, int secondary) } } - xics_kexec_teardown_cpu(secondary); + if (xive_enabled()) + xive_kexec_teardown_cpu(secondary); + else + xics_kexec_teardown_cpu(secondary); } diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 2da4851eff994717ef218d68831a78138604136a..f7042ad492bafba5ac21e3db9ce24977fd527169 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -226,10 +226,12 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) return -ENOENT; dn = dlpar_configure_connector(drc_index, parent_dn); - if (!dn) + if (!dn) { + of_node_put(parent_dn); return -ENOENT; + } - rc = dlpar_attach_node(dn); + rc = dlpar_attach_node(dn, parent_dn); if (rc) dlpar_free_cc_nodes(dn); diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 326ef0dd603812561e08a2d3139d19de31fa0490..b7496948129ef17591da6ce913265586a3b43d3d 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -132,19 +132,14 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev) static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) { struct device_node *dn; - struct pci_dn *pdn; const __be32 *p; u32 req_msi; - pdn = pci_get_pdn(pdev); - if (!pdn) - return -ENODEV; - - dn = pdn->node; + dn = pci_device_to_OF_node(pdev); p = of_get_property(dn, prop_name, NULL); if (!p) { - pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name); + pr_debug("rtas_msi: No %s on %pOF\n", prop_name, dn); return -ENOENT; } @@ -182,8 +177,8 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) while (dn) { p = of_get_property(dn, "ibm,pe-total-#msi", NULL); if (p) { - pr_debug("rtas_msi: found prop on dn %s\n", - dn->full_name); + pr_debug("rtas_msi: found prop on dn %pOF\n", + dn); *total = be32_to_cpup(p); return dn; } @@ -197,7 +192,6 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) { struct device_node *dn; - struct pci_dn *pdn; struct eeh_dev *edev; /* Found our PE and assume 8 at that point. */ @@ -210,8 +204,7 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) edev = pdn_to_eeh_dev(PCI_DN(dn)); if (edev->pe) edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); - pdn = eeh_dev_to_pdn(edev); - dn = pdn ? pdn->node : NULL; + dn = pci_device_to_OF_node(edev->pdev); if (!dn) return NULL; @@ -222,7 +215,7 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) /* Hardcode of 8 for old firmwares */ *total = 8; - pr_debug("rtas_msi: using PE dn %s\n", dn->full_name); + pr_debug("rtas_msi: using PE dn %pOF\n", dn); return dn; } @@ -242,7 +235,7 @@ static void *count_non_bridge_devices(struct device_node *dn, void *data) const __be32 *p; u32 class; - pr_debug("rtas_msi: counting %s\n", dn->full_name); + pr_debug("rtas_msi: counting %pOF\n", dn); p = of_get_property(dn, "class-code", NULL); class = p ? be32_to_cpup(p) : 0; @@ -300,7 +293,7 @@ static int msi_quota_for_device(struct pci_dev *dev, int request) goto out; } - pr_debug("rtas_msi: found PE %s\n", pe_dn->full_name); + pr_debug("rtas_msi: found PE %pOF\n", pe_dn); memset(&counts, 0, sizeof(struct msi_counts)); diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 547fd13e4f8e88a1d6d3e49fb270649c349fea5b..561917fa54a8a0cb86a880ebcede34a2fdd460e7 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -38,7 +38,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn) { struct pci_controller *phb; - pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name); + pr_debug("PCI: Initializing new hotplug PHB %pOF\n", dn); phb = pcibios_alloc_controller(dn); if (!phb) diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 1361a9db534b76bfdd21cd058e828aaa8ae04dee..4470a3194311e06e040c624b8b1491eb0e071298 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -46,7 +46,7 @@ extern void dlpar_free_cc_nodes(struct device_node *); extern void dlpar_free_cc_property(struct property *); extern struct device_node *dlpar_configure_connector(__be32, struct device_node *); -extern int dlpar_attach_node(struct device_node *); +extern int dlpar_attach_node(struct device_node *, struct device_node *); extern int dlpar_detach_node(struct device_node *); extern int dlpar_acquire_drc(u32 drc_index); extern int dlpar_release_drc(u32 drc_index); diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 164a13d3998acbeaababb3d6316671a29cf75d09..35c891aabef0e0347cd5b231c73d991786f920e9 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -229,10 +229,9 @@ static int __init pseries_energy_init(void) int cpu, err; struct device *cpu_dev; - if (!firmware_has_feature(FW_FEATURE_BEST_ENERGY)) { - printk(KERN_INFO "Hypercall H_BEST_ENERGY not supported\n"); - return 0; - } + if (!firmware_has_feature(FW_FEATURE_BEST_ENERGY)) + return 0; /* H_BEST_ENERGY hcall not supported */ + /* Create the sysfs files */ err = device_create_file(cpu_subsys.dev_root, &attr_cpu_activate_hint_list); diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index bb70b26334f071da6ea7a504c1929a7a7aa165a6..4923ffe230cf926565c0ed4c9a339a822b073c15 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -379,6 +379,21 @@ static void fwnmi_release_errinfo(void) int pSeries_system_reset_exception(struct pt_regs *regs) { +#ifdef __LITTLE_ENDIAN__ + /* + * Some firmware byteswaps SRR registers and gives incorrect SRR1. Try + * to detect the bad SRR1 pattern here. Flip the NIP back to correct + * endian for reporting purposes. Unfortunately the MSR can't be fixed, + * so clear it. It will be missing MSR_RI so we won't try to recover. + */ + if ((be64_to_cpu(regs->msr) & + (MSR_LE|MSR_RI|MSR_DR|MSR_IR|MSR_ME|MSR_PR| + MSR_ILE|MSR_HV|MSR_SF)) == (MSR_DR|MSR_SF)) { + regs->nip = be64_to_cpu((__be64)regs->nip); + regs->msr = 0; + } +#endif + if (fwnmi_active) { struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs); if (errhdr) { diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 011ef2180fe6b8d85f4fa11a1b31e8636e29d617..296c188fd5cad51202f8c2a174aa36e679171a93 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -362,20 +362,13 @@ static int do_update_property(char *buf, size_t bufsize) static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - int rv = 0; + int rv; char *kbuf; char *tmp; - if (!(kbuf = kmalloc(count + 1, GFP_KERNEL))) { - rv = -ENOMEM; - goto out; - } - if (copy_from_user(kbuf, buf, count)) { - rv = -EFAULT; - goto out; - } - - kbuf[count] = '\0'; + kbuf = memdup_user_nul(buf, count); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); tmp = strchr(kbuf, ' '); if (!tmp) { diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index b5d86426e97bc6a5cd17fd1b94573b7868449169..5f1beb8367acaa4562dbc647ad06a1f4c12a8f72 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -176,8 +177,11 @@ static void __init pseries_setup_i8259_cascade(void) static void __init pseries_init_irq(void) { - xics_init(); - pseries_setup_i8259_cascade(); + /* Try using a XIVE if available, otherwise use a XICS */ + if (!xive_spapr_init()) { + xics_init(); + pseries_setup_i8259_cascade(); + } } static void pseries_lpar_enable_pmcs(void) @@ -722,7 +726,6 @@ define_machine(pseries) { .pcibios_fixup = pSeries_final_fixup, .restart = rtas_restart, .halt = rtas_halt, - .panic = rtas_os_term, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, .set_rtc_time = rtas_set_rtc_time, diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 24785f63fb4033ab0a4f6a020934019f3f04b6eb..2e184829e5d496d7ce1ecf0808c3a6185b04395b 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -136,7 +137,9 @@ static inline int smp_startup_cpu(unsigned int lcpu) static void smp_setup_cpu(int cpu) { - if (cpu != boot_cpuid) + if (xive_enabled()) + xive_smp_setup_cpu(); + else if (cpu != boot_cpuid) xics_setup_cpu(); if (firmware_has_feature(FW_FEATURE_SPLPAR)) @@ -181,6 +184,13 @@ static int smp_pSeries_kick_cpu(int nr) return 0; } +static int pseries_smp_prepare_cpu(int cpu) +{ + if (xive_enabled()) + return xive_smp_prepare_cpu(cpu); + return 0; +} + static void smp_pseries_cause_ipi(int cpu) { /* POWER9 should not use this handler */ @@ -211,7 +221,7 @@ static int pseries_cause_nmi_ipi(int cpu) return 0; } -static __init void pSeries_smp_probe(void) +static __init void pSeries_smp_probe_xics(void) { xics_smp_probe(); @@ -221,11 +231,24 @@ static __init void pSeries_smp_probe(void) smp_ops->cause_ipi = icp_ops->cause_ipi; } +static __init void pSeries_smp_probe(void) +{ + if (xive_enabled()) + /* + * Don't use P9 doorbells when XIVE is enabled. IPIs + * using MMIOs should be faster + */ + xive_smp_probe(); + else + pSeries_smp_probe_xics(); +} + static struct smp_ops_t pseries_smp_ops = { .message_pass = NULL, /* Use smp_muxed_ipi_message_pass */ .cause_ipi = NULL, /* Filled at runtime by pSeries_smp_probe() */ .cause_nmi_ipi = pseries_cause_nmi_ipi, .probe = pSeries_smp_probe, + .prepare_cpu = pseries_smp_prepare_cpu, .kick_cpu = smp_pSeries_kick_cpu, .setup_cpu = smp_setup_cpu, .cpu_bootable = smp_generic_cpu_bootable, diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index e76aefae2aa2b1020e90180b6f4e930acece7294..89726f07d2492fd17beb05eea48c476fd2652550 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -151,7 +151,7 @@ static ssize_t store_hibernate(struct device *dev, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) + if (!alloc_cpumask_var(&offline_mask, GFP_KERNEL)) return -ENOMEM; stream_id = simple_strtoul(buf, NULL, 16); diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 8a47f168476bb4784a62345f66c959f71b03bae9..12277bc9fd9ebd05ab433ce9ce8f40f9f4daf0b8 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -1357,14 +1357,14 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) */ parent_node = of_get_parent(of_node); if (parent_node) { - if (!strcmp(parent_node->full_name, "/ibm,platform-facilities")) + if (!strcmp(parent_node->type, "ibm,platform-facilities")) family = PFO; - else if (!strcmp(parent_node->full_name, "/vdevice")) + else if (!strcmp(parent_node->type, "vdevice")) family = VDEVICE; else { - pr_warn("%s: parent(%s) of %s not recognized.\n", + pr_warn("%s: parent(%pOF) of %s not recognized.\n", __func__, - parent_node->full_name, + parent_node, of_node_name); of_node_put(parent_node); return NULL; @@ -1555,7 +1555,7 @@ static ssize_t devspec_show(struct device *dev, { struct device_node *of_node = dev->of_node; - return sprintf(buf, "%s\n", of_node_full_name(of_node)); + return sprintf(buf, "%pOF\n", of_node); } static DEVICE_ATTR_RO(devspec); diff --git a/arch/powerpc/purgatory/trampoline.S b/arch/powerpc/purgatory/trampoline.S index 3696ea6c4826b9740398113d207b1679318db2f8..4aad9dd10ace93fe9632a344595df9e42a8e9912 100644 --- a/arch/powerpc/purgatory/trampoline.S +++ b/arch/powerpc/purgatory/trampoline.S @@ -67,7 +67,7 @@ master: mr %r16,%r3 /* save dt address in reg16 */ li %r4,20 LWZX_BE %r6,%r3,%r4 /* fetch __be32 version number at byte 20 */ - cmpwi %r0,%r6,2 /* v2 or later? */ + cmpwi %cr0,%r6,2 /* v2 or later? */ blt 1f li %r4,28 STWX_BE %r17,%r3,%r4 /* Store my cpu as __be32 at byte 28 */ @@ -104,13 +104,13 @@ master: .balign 8 .globl kernel kernel: - .llong 0x0 + .8byte 0x0 .size kernel, . - kernel .balign 8 .globl dt_offset dt_offset: - .llong 0x0 + .8byte 0x0 .size dt_offset, . - dt_offset diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index c0ae11d4f62f3feb54ab6862b6566399a0ea93a6..79416fa2e3bae0f9f1d05dcc7bd1a0dbff563397 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -36,25 +36,15 @@ obj-$(CONFIG_AXON_RAM) += axonram.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_IPIC) += ipic.o -obj-$(CONFIG_4xx) += uic.o -obj-$(CONFIG_PPC4xx_OCM) += ppc4xx_ocm.o -obj-$(CONFIG_4xx_SOC) += ppc4xx_soc.o obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o obj-$(CONFIG_XILINX_PCI) += xilinx_pci.o obj-$(CONFIG_OF_RTC) += of_rtc.o -ifeq ($(CONFIG_PCI),y) -obj-$(CONFIG_4xx) += ppc4xx_pci.o -endif -obj-$(CONFIG_PPC4xx_HSTA_MSI) += ppc4xx_hsta_msi.o -obj-$(CONFIG_PPC4xx_MSI) += ppc4xx_msi.o -obj-$(CONFIG_PPC4xx_CPM) += ppc4xx_cpm.o -obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o obj-$(CONFIG_CPM) += cpm_common.o +obj-$(CONFIG_CPM1) += cpm1.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o obj-$(CONFIG_PPC_DCR) += dcr.o -obj-$(CONFIG_8xx) += mpc8xx_pic.o cpm1.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o obj-$(CONFIG_PPC_MPC512x) += mpc5xxx_clocks.o diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 2799706106c63a3f5e3bc377d10385f3149a065d..c60e84e4558d995bedddce41ee20340dbc737a78 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -110,7 +110,7 @@ axon_ram_irq_handler(int irq, void *dev) static blk_qc_t axon_ram_make_request(struct request_queue *queue, struct bio *bio) { - struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data; + struct axon_ram_bank *bank = bio->bi_disk->private_data; unsigned long phys_mem, phys_end; void *user_mem; struct bio_vec vec; @@ -188,15 +188,12 @@ static int axon_ram_probe(struct platform_device *device) axon_ram_bank_id++; - dev_info(&device->dev, "Found memory controller on %s\n", - device->dev.of_node->full_name); + dev_info(&device->dev, "Found memory controller on %pOF\n", + device->dev.of_node); - bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); - if (bank == NULL) { - dev_err(&device->dev, "Out of memory\n"); - rc = -ENOMEM; - goto failed; - } + bank = kzalloc(sizeof(*bank), GFP_KERNEL); + if (!bank) + return -ENOMEM; device->dev.platform_data = bank; @@ -292,25 +289,22 @@ static int axon_ram_probe(struct platform_device *device) return 0; failed: - if (bank != NULL) { - if (bank->irq_id) - free_irq(bank->irq_id, device); - if (bank->disk != NULL) { - if (bank->disk->major > 0) - unregister_blkdev(bank->disk->major, - bank->disk->disk_name); - if (bank->disk->flags & GENHD_FL_UP) - del_gendisk(bank->disk); - put_disk(bank->disk); - } - kill_dax(bank->dax_dev); - put_dax(bank->dax_dev); - device->dev.platform_data = NULL; - if (bank->io_addr != 0) - iounmap((void __iomem *) bank->io_addr); - kfree(bank); + if (bank->irq_id) + free_irq(bank->irq_id, device); + if (bank->disk != NULL) { + if (bank->disk->major > 0) + unregister_blkdev(bank->disk->major, + bank->disk->disk_name); + if (bank->disk->flags & GENHD_FL_UP) + del_gendisk(bank->disk); + put_disk(bank->disk); } - + kill_dax(bank->dax_dev); + put_dax(bank->dax_dev); + device->dev.platform_data = NULL; + if (bank->io_addr != 0) + iounmap((void __iomem *) bank->io_addr); + kfree(bank); return rc; } diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 121e26fffd50946e8df457b51c3c088b6c6fa528..d72eda568b7dffb9f740275116f40f8656a97284 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -195,8 +195,8 @@ dcr_host_mmio_t dcr_map_mmio(struct device_node *dev, dcr_host_mmio_t ret = { .token = NULL, .stride = 0, .base = dcr_n }; u64 addr; - pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", - dev->full_name, dcr_n, dcr_c); + pr_debug("dcr_map(%pOF, 0x%x, 0x%x)\n", + dev, dcr_n, dcr_c); addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); pr_debug("translates to addr: 0x%llx, stride: 0x%x\n", diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c index 37a69097e02251e9b8158ff7b9f3e2f7bb952adc..00ccf3e4fcb4a397a258e9ab41a082b5ab719501 100644 --- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c +++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c @@ -101,8 +101,8 @@ int __init instantiate_cache_sram(struct platform_device *dev, if (!request_mem_region(cache_sram->base_phys, cache_sram->size, "fsl_85xx_cache_sram")) { - dev_err(&dev->dev, "%s: request memory failed\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF: request memory failed\n", + dev->dev.of_node); ret = -ENXIO; goto out_free; } @@ -110,16 +110,16 @@ int __init instantiate_cache_sram(struct platform_device *dev, cache_sram->base_virt = ioremap_prot(cache_sram->base_phys, cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL); if (!cache_sram->base_virt) { - dev_err(&dev->dev, "%s: ioremap_prot failed\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF: ioremap_prot failed\n", + dev->dev.of_node); ret = -ENOMEM; goto out_release; } cache_sram->rh = rh_create(sizeof(unsigned int)); if (IS_ERR(cache_sram->rh)) { - dev_err(&dev->dev, "%s: Unable to create remote heap\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF: Unable to create remote heap\n", + dev->dev.of_node); ret = PTR_ERR(cache_sram->rh); goto out_unmap; } diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index a6f0b96ce2c94b82aeac14608befd7a9b530aa84..d902306f47183274c214db7d801037c5417fa80e 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -388,8 +388,8 @@ static int __init fsl_gtm_init(void) gtm = kzalloc(sizeof(*gtm), GFP_KERNEL); if (!gtm) { - pr_err("%s: unable to allocate memory\n", - np->full_name); + pr_err("%pOF: unable to allocate memory\n", + np); continue; } @@ -397,7 +397,7 @@ static int __init fsl_gtm_init(void) clock = of_get_property(np, "clock-frequency", &size); if (!clock || size != sizeof(*clock)) { - pr_err("%s: no clock-frequency\n", np->full_name); + pr_err("%pOF: no clock-frequency\n", np); goto err; } gtm->clock = *clock; @@ -407,8 +407,8 @@ static int __init fsl_gtm_init(void) irq = irq_of_parse_and_map(np, i); if (!irq) { - pr_err("%s: not enough interrupts specified\n", - np->full_name); + pr_err("%pOF: not enough interrupts specified\n", + np); goto err; } gtm->timers[i].irq = irq; @@ -417,8 +417,8 @@ static int __init fsl_gtm_init(void) gtm->regs = of_iomap(np, 0); if (!gtm->regs) { - pr_err("%s: unable to iomap registers\n", - np->full_name); + pr_err("%pOF: unable to iomap registers\n", + np); goto err; } diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 8a244828782e017b5b9100823227e1da5167207e..44cbf4c12ea137562f02758aab4e2e604f54e96f 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -214,8 +214,8 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) phandle = np->phandle; else { dev_err(&pdev->dev, - "node %s has an invalid fsl,msi phandle %u\n", - hose->dn->full_name, np->phandle); + "node %pOF has an invalid fsl,msi phandle %u\n", + hose->dn, np->phandle); return -EINVAL; } } @@ -438,16 +438,16 @@ static int fsl_of_msi_probe(struct platform_device *dev) if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) != FSL_PIC_IP_VMPIC) { err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { - dev_err(&dev->dev, "invalid resource for node %s\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "invalid resource for node %pOF\n", + dev->dev.of_node); goto error_out; } msi->msi_regs = ioremap(res.start, resource_size(&res)); if (!msi->msi_regs) { err = -ENOMEM; - dev_err(&dev->dev, "could not map node %s\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "could not map node %pOF\n", + dev->dev.of_node); goto error_out; } msi->msiir_offset = @@ -522,8 +522,8 @@ static int fsl_of_msi_probe(struct platform_device *dev) for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { if (p[i * 2] % IRQS_PER_MSI_REG || p[i * 2 + 1] % IRQS_PER_MSI_REG) { - pr_warn("%s: %s: msi available range of %u at %u is not IRQ-aligned\n", - __func__, dev->dev.of_node->full_name, + pr_warn("%s: %pOF: msi available range of %u at %u is not IRQ-aligned\n", + __func__, dev->dev.of_node, p[i * 2 + 1], p[i * 2]); err = -EINVAL; goto error_out; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index d3a597456b6e57f83efb165e065a572d0105cc99..22d98057f773bf5837ef26a51fb9ea2427006dae 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -202,7 +202,6 @@ static void setup_pci_atmu(struct pci_controller *hose) u32 pcicsrbar = 0, pcicsrbar_sz; u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; - const char *name = hose->dn->full_name; const u64 *reg; int len; bool setup_inbound; @@ -290,12 +289,12 @@ static void setup_pci_atmu(struct pci_controller *hose) paddr_lo -= offset; if (paddr_hi == paddr_lo) { - pr_err("%s: No outbound window space\n", name); + pr_err("%pOF: No outbound window space\n", hose->dn); return; } if (paddr_lo == 0) { - pr_err("%s: No space for inbound window\n", name); + pr_err("%pOF: No space for inbound window\n", hose->dn); return; } @@ -313,7 +312,7 @@ static void setup_pci_atmu(struct pci_controller *hose) paddr_lo = min(paddr_lo, (u64)pcicsrbar); - pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar); + pr_info("%pOF: PCICSRBAR @ 0x%x\n", hose->dn, pcicsrbar); /* Setup inbound mem window */ mem = memblock_end_of_DRAM(); @@ -336,12 +335,12 @@ static void setup_pci_atmu(struct pci_controller *hose) u64 address = be64_to_cpup(reg); if ((address >= mem) && (address < (mem + PAGE_SIZE))) { - pr_info("%s: extending DDR ATMU to cover MSIIR", name); + pr_info("%pOF: extending DDR ATMU to cover MSIIR", hose->dn); mem += PAGE_SIZE; } else { /* TODO: Create a new ATMU for MSIIR */ - pr_warn("%s: msi-address-64 address of %llx is " - "unsupported\n", name, address); + pr_warn("%pOF: msi-address-64 address of %llx is " + "unsupported\n", hose->dn, address); } } @@ -354,8 +353,8 @@ static void setup_pci_atmu(struct pci_controller *hose) if ((1ull << mem_log) != mem) { mem_log++; if ((1ull << mem_log) > mem) - pr_info("%s: Setting PCI inbound window " - "greater than memory size\n", name); + pr_info("%pOF: Setting PCI inbound window " + "greater than memory size\n", hose->dn); } piwar |= ((mem_log - 1) & PIWAR_SZ_MASK); @@ -402,7 +401,7 @@ static void setup_pci_atmu(struct pci_controller *hose) */ ppc_md.dma_set_mask = fsl_pci_dma_set_mask; - pr_info("%s: Setup 64-bit PCI DMA window\n", name); + pr_info("%pOF: Setup 64-bit PCI DMA window\n", hose->dn); } } else { u64 paddr = 0; @@ -443,18 +442,18 @@ static void setup_pci_atmu(struct pci_controller *hose) #ifdef CONFIG_SWIOTLB ppc_swiotlb_enable = 1; #else - pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to " + pr_err("%pOF: ERROR: Memory size exceeds PCI ATMU ability to " "map - enable CONFIG_SWIOTLB to avoid dma errors.\n", - name); + hose->dn); #endif /* adjusting outbound windows could reclaim space in mem map */ if (paddr_hi < 0xffffffffull) - pr_warning("%s: WARNING: Outbound window cfg leaves " + pr_warning("%pOF: WARNING: Outbound window cfg leaves " "gaps in memory map. Adjusting the memory map " "could reduce unnecessary bounce buffering.\n", - name); + hose->dn); - pr_info("%s: DMA window size is 0x%llx\n", name, + pr_info("%pOF: DMA window size is 0x%llx\n", hose->dn, (u64)hose->dma_window_size); } } @@ -532,11 +531,11 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary) dev = pdev->dev.of_node; if (!of_device_is_available(dev)) { - pr_warning("%s: disabled\n", dev->full_name); + pr_warning("%pOF: disabled\n", dev); return -ENODEV; } - pr_debug("Adding PCI host bridge %s\n", dev->full_name); + pr_debug("Adding PCI host bridge %pOF\n", dev); /* Fetch host bridge registers address */ if (of_address_to_resource(dev, 0, &rsrc)) { @@ -547,8 +546,8 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); pci_add_flags(PCI_REASSIGN_ALL_BUS); hose = pcibios_alloc_controller(dev); @@ -809,11 +808,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev) is_mpc83xx_pci = 1; if (!of_device_is_available(dev)) { - pr_warning("%s: disabled by the firmware.\n", - dev->full_name); + pr_warning("%pOF: disabled by the firmware.\n", + dev); return -ENODEV; } - pr_debug("Adding PCI host bridge %s\n", dev->full_name); + pr_debug("Adding PCI host bridge %pOF\n", dev); /* Fetch host bridge registers address */ if (of_address_to_resource(dev, 0, &rsrc_reg)) { @@ -848,8 +847,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); } pci_add_flags(PCI_REASSIGN_ALL_BUS); diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 1c41c51f22cb596876788930962c53fda3b664b9..5011ffea4e4b3a8d3c69160bb1bb896cdeb8cb1f 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -71,6 +71,8 @@ #define RIWAR_WRTYP_ALLOC 0x00006000 #define RIWAR_SIZE_MASK 0x0000003F +static DEFINE_SPINLOCK(fsl_rio_config_lock); + #define __fsl_read_rio_config(x, addr, err, op) \ __asm__ __volatile__( \ "1: "op" %1,0(%2)\n" \ @@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 *val) { struct rio_priv *priv = mport->priv; + unsigned long flags; u8 *data; u32 rval, err = 0; @@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) return -EINVAL; + spin_lock_irqsave(&fsl_rio_config_lock, flags); + out_be32(&priv->maint_atmu_regs->rowtar, (destid << 22) | (hopcount << 12) | (offset >> 12)); out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -213,6 +218,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, __fsl_read_rio_config(rval, data, err, "lwz"); break; default: + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); return -EINVAL; } @@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, err, destid, hopcount, offset); } + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); *val = rval; return err; @@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 val) { struct rio_priv *priv = mport->priv; + unsigned long flags; u8 *data; + int ret = 0; + pr_debug ("fsl_rio_config_write:" " index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", @@ -255,6 +265,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) return -EINVAL; + spin_lock_irqsave(&fsl_rio_config_lock, flags); + out_be32(&priv->maint_atmu_regs->rowtar, (destid << 22) | (hopcount << 12) | (offset >> 12)); out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -271,10 +283,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, out_be32((u32 *) data, val); break; default: - return -EINVAL; + ret = -EINVAL; } + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); - return 0; + return ret; } static void fsl_rio_inbound_mem_init(struct rio_priv *priv) @@ -450,12 +463,12 @@ int fsl_rio_setup(struct platform_device *dev) rc = of_address_to_resource(dev->dev.of_node, 0, ®s); if (rc) { - dev_err(&dev->dev, "Can't get %s property 'reg'\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'reg'\n", + dev->dev.of_node); return -EFAULT; } - dev_info(&dev->dev, "Of-device full name %s\n", - dev->dev.of_node->full_name); + dev_info(&dev->dev, "Of-device full name %pOF\n", + dev->dev.of_node); dev_info(&dev->dev, "Regs: %pR\n", ®s); rio_regs_win = ioremap(regs.start, resource_size(®s)); @@ -494,8 +507,8 @@ int fsl_rio_setup(struct platform_device *dev) } rc = of_address_to_resource(rmu_node, 0, &rmu_regs); if (rc) { - dev_err(&dev->dev, "Can't get %s property 'reg'\n", - rmu_node->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'reg'\n", + rmu_node); goto err_rmu; } rmu_regs_win = ioremap(rmu_regs.start, resource_size(&rmu_regs)); @@ -529,8 +542,8 @@ int fsl_rio_setup(struct platform_device *dev) aw = of_n_addr_cells(np); dt_range = of_get_property(np, "reg", &rlen); if (!dt_range) { - pr_err("%s: unable to find 'reg' property\n", - np->full_name); + pr_err("%pOF: unable to find 'reg' property\n", + np); rc = -ENOMEM; goto err_pw; } @@ -557,8 +570,8 @@ int fsl_rio_setup(struct platform_device *dev) aw = of_n_addr_cells(np); dt_range = of_get_property(np, "reg", &rlen); if (!dt_range) { - pr_err("%s: unable to find 'reg' property\n", - np->full_name); + pr_err("%pOF: unable to find 'reg' property\n", + np); rc = -ENOMEM; goto err; } @@ -569,15 +582,15 @@ int fsl_rio_setup(struct platform_device *dev) for_each_child_of_node(dev->dev.of_node, np) { port_index = of_get_property(np, "cell-index", NULL); if (!port_index) { - dev_err(&dev->dev, "Can't get %s property 'cell-index'\n", - np->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'cell-index'\n", + np); continue; } dt_range = of_get_property(np, "ranges", &rlen); if (!dt_range) { - dev_err(&dev->dev, "Can't get %s property 'ranges'\n", - np->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'ranges'\n", + np); continue; } @@ -598,8 +611,8 @@ int fsl_rio_setup(struct platform_device *dev) range_start = of_read_number(dt_range + aw, paw); range_size = of_read_number(dt_range + aw + paw, sw); - dev_info(&dev->dev, "%s: LAW start 0x%016llx, size 0x%016llx.\n", - np->full_name, range_start, range_size); + dev_info(&dev->dev, "%pOF: LAW start 0x%016llx, size 0x%016llx.\n", + np, range_start, range_size); port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); if (!port) @@ -757,8 +770,8 @@ int fsl_rio_setup(struct platform_device *dev) */ static int fsl_of_rio_rpn_probe(struct platform_device *dev) { - printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", - dev->dev.of_node->full_name); + printk(KERN_INFO "Setting up RapidIO peer-to-peer network %pOF\n", + dev->dev.of_node); return fsl_rio_setup(dev); }; diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index c1826de4e749dc1ab15987831d310fb91f0fc6c9..88b35a3dcdc599b01c37da944ba3f8481215d6cc 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -104,6 +104,8 @@ #define DOORBELL_MESSAGE_SIZE 0x08 +static DEFINE_SPINLOCK(fsl_rio_doorbell_lock); + struct rio_msg_regs { u32 omr; u32 osr; @@ -626,9 +628,13 @@ int fsl_rio_port_write_init(struct fsl_rio_pw *pw) int fsl_rio_doorbell_send(struct rio_mport *mport, int index, u16 destid, u16 data) { + unsigned long flags; + pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", index, destid, data); + spin_lock_irqsave(&fsl_rio_doorbell_lock, flags); + /* In the serial version silicons, such as MPC8548, MPC8641, * below operations is must be. */ @@ -638,6 +644,8 @@ int fsl_rio_doorbell_send(struct rio_mport *mport, out_be32(&dbell->dbell_regs->oddatr, (index << 20) | data); out_be32(&dbell->dbell_regs->odmr, 0x00000001); + spin_unlock_irqrestore(&fsl_rio_doorbell_lock, flags); + return 0; } @@ -1074,8 +1082,8 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) priv = mport->priv; if (!node) { - dev_warn(priv->dev, "Can't get %s property 'fsl,rmu'\n", - priv->dev->of_node->full_name); + dev_warn(priv->dev, "Can't get %pOF property 'fsl,rmu'\n", + priv->dev->of_node); return -EINVAL; } @@ -1086,8 +1094,8 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) aw = of_n_addr_cells(node); msg_addr = of_get_property(node, "reg", &mlen); if (!msg_addr) { - pr_err("%s: unable to find 'reg' property of message-unit\n", - node->full_name); + pr_err("%pOF: unable to find 'reg' property of message-unit\n", + node); kfree(rmu); return -ENOMEM; } @@ -1098,8 +1106,8 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) rmu->txirq = irq_of_parse_and_map(node, 0); rmu->rxirq = irq_of_parse_and_map(node, 1); - printk(KERN_INFO "%s: txirq: %d, rxirq %d\n", - node->full_name, rmu->txirq, rmu->rxirq); + printk(KERN_INFO "%pOF: txirq: %d, rxirq %d\n", + node, rmu->txirq, rmu->rxirq); priv->rmm_handle = rmu; diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 19101f9cfcfc131dcda03abb145ced50957d0ee2..1f614fb2be567a47c59373152260ab089bc75933 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -98,7 +98,7 @@ u32 fsl_get_sys_freq(void) } EXPORT_SYMBOL(fsl_get_sys_freq); -#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) u32 get_brgfreq(void) { diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index d73daa4f0ccfc9005ff2cca7df398a590f709179..2640446f8bc40483ab4c1f16d50bbf0aea1f76b7 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -7,7 +7,7 @@ struct spi_device; extern phys_addr_t get_immrbase(void); -#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) extern u32 get_brgfreq(void); extern u32 get_baudrate(void); #else diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index f267ee0afc082068266d3032ff41d194523ccb5a..16f1edd78c40e52a126e2d40f70242e3f6c82533 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -315,6 +315,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 7, }, [48] = { + .ack = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_A, .force = IPIC_SEFCR, diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index b9aac951a90f69ec3e05775fe50495b25fea6716..ead3e2549ebfe2b891e54e37e8ef3e3f77e963d0 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1650,8 +1650,8 @@ void __init mpic_init(struct mpic *mpic) if (mpic->flags & MPIC_SECONDARY) { int virq = irq_of_parse_and_map(mpic->node, 0); if (virq) { - printk(KERN_INFO "%s: hooking up to IRQ %d\n", - mpic->node->full_name, virq); + printk(KERN_INFO "%pOF: hooking up to IRQ %d\n", + mpic->node, virq); irq_set_handler_data(virq, mpic); irq_set_chained_handler(virq, &mpic_cascade); } diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index db2286be5d9aa741ca4a5070b62f336d5a5764de..eb69a51862431cccc81034f1fb9a1c8decc906d2 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -192,7 +192,7 @@ static int mpic_msgr_probe(struct platform_device *dev) return -ENOMEM; } } - dev_info(&dev->dev, "Of-device full name %s\n", np->full_name); + dev_info(&dev->dev, "Of-device full name %pOF\n", np); /* IO map the message register block. */ of_address_to_resource(np, 0, &rsrc); diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index 1d48a5385905a8ce96290f10064546a39efed403..9ed860aee9c334f58e8763c3ad43ca28bedf7bfd 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -60,7 +60,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) np = NULL; while ((np = of_find_all_nodes(np))) { - pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); + pr_debug("mpic: mapping hwirqs for %pOF\n", np); index = 0; while (of_irq_parse_one(np, index++, &oirq) == 0) { diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index 9d9b06217f8b9dff2a994ad5d357436e9986553e..a418579591bed5e3de647afc2087e780d1d6c8ab 100644 --- a/arch/powerpc/sysdev/mpic_timer.c +++ b/arch/powerpc/sysdev/mpic_timer.c @@ -466,8 +466,7 @@ static int timer_group_get_irq(struct device_node *np, p = of_get_property(np, "fsl,available-ranges", &len); if (p && len % (2 * sizeof(u32)) != 0) { - pr_err("%s: malformed available-ranges property.\n", - np->full_name); + pr_err("%pOF: malformed available-ranges property.\n", np); return -EINVAL; } @@ -484,8 +483,7 @@ static int timer_group_get_irq(struct device_node *np, for (j = 0; j < count; j++) { irq = irq_of_parse_and_map(np, irq_index); if (!irq) { - pr_err("%s: irq parse and map failed.\n", - np->full_name); + pr_err("%pOF: irq parse and map failed.\n", np); return -EINVAL; } @@ -508,8 +506,7 @@ static void timer_group_init(struct device_node *np) priv = kzalloc(sizeof(struct timer_group_priv), GFP_KERNEL); if (!priv) { - pr_err("%s: cannot allocate memory for group.\n", - np->full_name); + pr_err("%pOF: cannot allocate memory for group.\n", np); return; } @@ -518,29 +515,27 @@ static void timer_group_init(struct device_node *np) priv->regs = of_iomap(np, i++); if (!priv->regs) { - pr_err("%s: cannot ioremap timer register address.\n", - np->full_name); + pr_err("%pOF: cannot ioremap timer register address.\n", np); goto out; } if (priv->flags & FSL_GLOBAL_TIMER) { priv->group_tcr = of_iomap(np, i++); if (!priv->group_tcr) { - pr_err("%s: cannot ioremap tcr address.\n", - np->full_name); + pr_err("%pOF: cannot ioremap tcr address.\n", np); goto out; } } ret = timer_group_get_freq(np, priv); if (ret < 0) { - pr_err("%s: cannot get timer frequency.\n", np->full_name); + pr_err("%pOF: cannot get timer frequency.\n", np); goto out; } ret = timer_group_get_irq(np, priv); if (ret < 0) { - pr_err("%s: cannot get timer irqs.\n", np->full_name); + pr_err("%pOF: cannot get timer irqs.\n", np); goto out; } diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 5ebd3f0182951634e419d6c651a59e9182f31e48..c4dae27172b3e44968f4b11cb413cd4836f01972 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c @@ -86,13 +86,13 @@ int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp) p = of_get_property(bmp->of_node, "msi-available-ranges", &len); if (!p) { pr_debug("msi_bitmap: no msi-available-ranges property " \ - "found on %s\n", bmp->of_node->full_name); + "found on %pOF\n", bmp->of_node); return 1; } if (len % (2 * sizeof(u32)) != 0) { printk(KERN_WARNING "msi_bitmap: Malformed msi-available-ranges" - " property on %s\n", bmp->of_node->full_name); + " property on %pOF\n", bmp->of_node); return -EINVAL; } diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 026bbc3b2c47d75f967d777bc797f446a615438c..185a67e742a61614a38233dd6d531888ef5f914f 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -452,8 +452,8 @@ static int __init mv64x60_device_setup(void) err = mv64x60_mpsc_device_setup(np, id++); if (err) printk(KERN_ERR "Failed to initialize MV64x60 " - "serial device %s: error %d.\n", - np->full_name, err); + "serial device %pOF: error %d.\n", + np, err); } id = 0; @@ -463,8 +463,8 @@ static int __init mv64x60_device_setup(void) if (IS_ERR(pdev)) { err = PTR_ERR(pdev); printk(KERN_ERR "Failed to initialize MV64x60 " - "network block %s: error %d.\n", - np->full_name, err); + "network block %pOF: error %d.\n", + np, err); continue; } for_each_child_of_node(np, np2) { @@ -474,9 +474,9 @@ static int __init mv64x60_device_setup(void) err = mv64x60_eth_device_setup(np2, id2++, pdev); if (err) printk(KERN_ERR "Failed to initialize " - "MV64x60 network device %s: " + "MV64x60 network device %pOF: " "error %d.\n", - np2->full_name, err); + np2, err); } } @@ -485,8 +485,8 @@ static int __init mv64x60_device_setup(void) err = mv64x60_i2c_device_setup(np, id++); if (err) printk(KERN_ERR "Failed to initialize MV64x60 I2C " - "bus %s: error %d.\n", - np->full_name, err); + "bus %pOF: error %d.\n", + np, err); } /* support up to one watchdog timer */ @@ -494,8 +494,8 @@ static int __init mv64x60_device_setup(void) if (np) { if ((err = mv64x60_wdt_device_setup(np, id))) printk(KERN_ERR "Failed to initialize MV64x60 " - "Watchdog %s: error %d.\n", - np->full_name, err); + "Watchdog %pOF: error %d.\n", + np, err); of_node_put(np); } diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index 330d56613c5a0ca88513e234cbbe0ce15ce77b11..d52b3b81e05fba706af2012804fcf410f5d8c2b4 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -70,7 +70,7 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */ +static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */ .attr = { .name = "hs_reg", .mode = S_IRUGO | S_IWUSR, @@ -136,8 +136,8 @@ static int __init mv64x60_add_bridge(struct device_node *dev) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); hose = pcibios_alloc_controller(dev); if (!hose) diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c index 6f54b54b13283f71af521f3bbda1c1a764781f4c..153fdac4720f05e29893d2eb4f7f5229539b3a19 100644 --- a/arch/powerpc/sysdev/of_rtc.c +++ b/arch/powerpc/sysdev/of_rtc.c @@ -38,21 +38,21 @@ void __init of_instantiate_rtc(void) res = kmalloc(sizeof(*res), GFP_KERNEL); if (!res) { printk(KERN_ERR "OF RTC: Out of memory " - "allocating resource structure for %s\n", - node->full_name); + "allocating resource structure for %pOF\n", + node); continue; } err = of_address_to_resource(node, 0, res); if (err) { printk(KERN_ERR "OF RTC: Error " - "translating resources for %s\n", - node->full_name); + "translating resources for %pOF\n", + node); continue; } - printk(KERN_INFO "OF_RTC: %s is a %s @ 0x%llx-0x%llx\n", - node->full_name, plat_name, + printk(KERN_INFO "OF_RTC: %pOF is a %s @ 0x%llx-0x%llx\n", + node, plat_name, (unsigned long long)res->start, (unsigned long long)res->end); platform_device_register_simple(plat_name, -1, res, 1); diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c index 76ea32c1b664da4a3aca842641528d6fb85565df..0f6fd5d04d332372aa74d94caf6d17fce3402559 100644 --- a/arch/powerpc/sysdev/scom.c +++ b/arch/powerpc/sysdev/scom.c @@ -194,12 +194,13 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, ent->dn = of_node_get(dn); snprintf(ent->name, 16, "%08x", i); - ent->path.data = (void*) dn->full_name; - ent->path.size = strlen(dn->full_name); + ent->path.data = (void*)kasprintf(GFP_KERNEL, "%pOF", dn); + ent->path.size = strlen((char *)ent->path.data); dir = debugfs_create_dir(ent->name, root); if (!dir) { of_node_put(dn); + kfree(ent->path.data); kfree(ent); return -1; } diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index 6afddae2fb4796dc61de3258f683bcc158b15a2e..f02d4576138c1f94f497e75dddbba5bfe3a6d111 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c @@ -142,7 +142,6 @@ void __init simple_gpiochip_init(const char *compatible) } continue; err: - pr_err("%s: registration failed, status %d\n", - np->full_name, ret); + pr_err("%pOF: registration failed, status %d\n", np, ret); } } diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 5692dd569b9b6dadf1c8d4c117a7b1a1698ab2c6..28ff1f53cefc1d1101695f5c280578cf516403c2 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -213,8 +213,8 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); } hose = pcibios_alloc_controller(dev); diff --git a/arch/powerpc/sysdev/xive/Kconfig b/arch/powerpc/sysdev/xive/Kconfig index 12ccd7373d2f017ea5fca33261a781a5eed42108..3e3e25b5e30d66ace3e9a77c39311c82faf9f3fe 100644 --- a/arch/powerpc/sysdev/xive/Kconfig +++ b/arch/powerpc/sysdev/xive/Kconfig @@ -9,3 +9,8 @@ config PPC_XIVE_NATIVE default n select PPC_XIVE depends on PPC_POWERNV + +config PPC_XIVE_SPAPR + bool + default n + select PPC_XIVE diff --git a/arch/powerpc/sysdev/xive/Makefile b/arch/powerpc/sysdev/xive/Makefile index 3fab303fc16966302ebc74a4c9ba47b067cb005d..536d6e5706e32c253b0a742065e6c964e914cf3b 100644 --- a/arch/powerpc/sysdev/xive/Makefile +++ b/arch/powerpc/sysdev/xive/Makefile @@ -2,3 +2,4 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-y += common.o obj-$(CONFIG_PPC_XIVE_NATIVE) += native.o +obj-$(CONFIG_PPC_XIVE_SPAPR) += spapr.o diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 6595462b1fc8e8dcef978d00fa2ac0ed7dfc2433..a3b8d7d1316eb1863f19ffa19ff34f0c761ada33 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -40,7 +40,8 @@ #undef DEBUG_ALL #ifdef DEBUG_ALL -#define DBG_VERBOSE(fmt...) pr_devel(fmt) +#define DBG_VERBOSE(fmt, ...) pr_devel("cpu %d - " fmt, \ + smp_processor_id(), ## __VA_ARGS__) #else #define DBG_VERBOSE(fmt...) do { } while(0) #endif @@ -190,7 +191,7 @@ static u32 xive_scan_interrupts(struct xive_cpu *xc, bool just_peek) * This is used to perform the magic loads from an ESB * described in xive.h */ -static u8 xive_poke_esb(struct xive_irq_data *xd, u32 offset) +static notrace u8 xive_esb_read(struct xive_irq_data *xd, u32 offset) { u64 val; @@ -198,13 +199,28 @@ static u8 xive_poke_esb(struct xive_irq_data *xd, u32 offset) if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) offset |= offset << 4; - val = in_be64(xd->eoi_mmio + offset); + if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) + val = xive_ops->esb_rw(xd->hw_irq, offset, 0, 0); + else + val = in_be64(xd->eoi_mmio + offset); return (u8)val; } +static void xive_esb_write(struct xive_irq_data *xd, u32 offset, u64 data) +{ + /* Handle HW errata */ + if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) + offset |= offset << 4; + + if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) + xive_ops->esb_rw(xd->hw_irq, offset, data, 1); + else + out_be64(xd->eoi_mmio + offset, data); +} + #ifdef CONFIG_XMON -static void xive_dump_eq(const char *name, struct xive_q *q) +static notrace void xive_dump_eq(const char *name, struct xive_q *q) { u32 i0, i1, idx; @@ -218,7 +234,7 @@ static void xive_dump_eq(const char *name, struct xive_q *q) q->toggle, i0, i1); } -void xmon_xive_do_dump(int cpu) +notrace void xmon_xive_do_dump(int cpu) { struct xive_cpu *xc = per_cpu(xive_cpu, cpu); @@ -227,7 +243,7 @@ void xmon_xive_do_dump(int cpu) xive_dump_eq("IRQ", &xc->queue[xive_irq_priority]); #ifdef CONFIG_SMP { - u64 val = xive_poke_esb(&xc->ipi_data, XIVE_ESB_GET); + u64 val = xive_esb_read(&xc->ipi_data, XIVE_ESB_GET); xmon_printf(" IPI state: %x:%c%c\n", xc->hw_ipi, val & XIVE_ESB_VAL_P ? 'P' : 'p', val & XIVE_ESB_VAL_P ? 'Q' : 'q'); @@ -297,7 +313,7 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd) { /* If the XIVE supports the new "store EOI facility, use it */ if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) - out_be64(xd->eoi_mmio + XIVE_ESB_STORE_EOI, 0); + xive_esb_write(xd, XIVE_ESB_STORE_EOI, 0); else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) { /* * The FW told us to call it. This happens for some @@ -326,10 +342,10 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd) * properly. */ if (xd->flags & XIVE_IRQ_FLAG_LSI) - in_be64(xd->eoi_mmio); + xive_esb_read(xd, XIVE_ESB_LOAD_EOI); else { - eoi_val = xive_poke_esb(xd, XIVE_ESB_SET_PQ_00); - DBG_VERBOSE("eoi_val=%x\n", offset, eoi_val); + eoi_val = xive_esb_read(xd, XIVE_ESB_SET_PQ_00); + DBG_VERBOSE("eoi_val=%x\n", eoi_val); /* Re-trigger if needed */ if ((eoi_val & XIVE_ESB_VAL_Q) && xd->trig_mmio) @@ -383,12 +399,12 @@ static void xive_do_source_set_mask(struct xive_irq_data *xd, * ESB accordingly on unmask. */ if (mask) { - val = xive_poke_esb(xd, XIVE_ESB_SET_PQ_01); + val = xive_esb_read(xd, XIVE_ESB_SET_PQ_01); xd->saved_p = !!(val & XIVE_ESB_VAL_P); } else if (xd->saved_p) - xive_poke_esb(xd, XIVE_ESB_SET_PQ_10); + xive_esb_read(xd, XIVE_ESB_SET_PQ_10); else - xive_poke_esb(xd, XIVE_ESB_SET_PQ_00); + xive_esb_read(xd, XIVE_ESB_SET_PQ_00); } /* @@ -447,7 +463,7 @@ static int xive_find_target_in_mask(const struct cpumask *mask, int cpu, first, num, i; /* Pick up a starting point CPU in the mask based on fuzz */ - num = cpumask_weight(mask); + num = min_t(int, cpumask_weight(mask), nr_cpu_ids); first = fuzz % num; /* Locate it */ @@ -672,6 +688,10 @@ static int xive_irq_set_affinity(struct irq_data *d, if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) return -EINVAL; + /* Don't do anything if the interrupt isn't started */ + if (!irqd_is_started(d)) + return IRQ_SET_MASK_OK; + /* * If existing target is already in the new mask, and is * online then do nothing. @@ -768,7 +788,7 @@ static int xive_irq_retrigger(struct irq_data *d) * To perform a retrigger, we first set the PQ bits to * 11, then perform an EOI. */ - xive_poke_esb(xd, XIVE_ESB_SET_PQ_11); + xive_esb_read(xd, XIVE_ESB_SET_PQ_11); /* * Note: We pass "0" to the hw_irq argument in order to @@ -803,7 +823,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state) irqd_set_forwarded_to_vcpu(d); /* Set it to PQ=10 state to prevent further sends */ - pq = xive_poke_esb(xd, XIVE_ESB_SET_PQ_10); + pq = xive_esb_read(xd, XIVE_ESB_SET_PQ_10); /* No target ? nothing to do */ if (xd->target == XIVE_INVALID_TARGET) { @@ -832,7 +852,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state) * for sure the queue slot is no longer in use. */ if (pq & 2) { - pq = xive_poke_esb(xd, XIVE_ESB_SET_PQ_11); + pq = xive_esb_read(xd, XIVE_ESB_SET_PQ_11); xd->saved_p = true; /* @@ -989,6 +1009,9 @@ static void xive_ipi_eoi(struct irq_data *d) { struct xive_cpu *xc = __this_cpu_read(xive_cpu); + DBG_VERBOSE("IPI eoi: irq=%d [0x%lx] (HW IRQ 0x%x) pending=%02x\n", + d->irq, irqd_to_hwirq(d), xc->hw_ipi, xc->pending_prio); + /* Handle possible race with unplug and drop stale IPIs */ if (!xc) return; @@ -1368,6 +1391,27 @@ void xive_flush_interrupt(void) #endif /* CONFIG_SMP */ +void xive_teardown_cpu(void) +{ + struct xive_cpu *xc = __this_cpu_read(xive_cpu); + unsigned int cpu = smp_processor_id(); + + /* Set CPPR to 0 to disable flow of interrupts */ + xc->cppr = 0; + out_8(xive_tima + xive_tima_offset + TM_CPPR, 0); + + if (xive_ops->teardown_cpu) + xive_ops->teardown_cpu(cpu, xc); + +#ifdef CONFIG_SMP + /* Get rid of IPI */ + xive_cleanup_cpu_ipi(cpu, xc); +#endif + + /* Disable and free the queues */ + xive_cleanup_cpu_queues(cpu, xc); +} + void xive_kexec_teardown_cpu(int secondary) { struct xive_cpu *xc = __this_cpu_read(xive_cpu); @@ -1395,8 +1439,8 @@ void xive_shutdown(void) xive_ops->shutdown(); } -bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, - u8 max_prio) +bool __init xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, + u8 max_prio) { xive_tima = area; xive_tima_offset = offset; @@ -1424,6 +1468,22 @@ bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, return true; } +__be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift) +{ + unsigned int alloc_order; + struct page *pages; + __be32 *qpage; + + alloc_order = xive_alloc_order(queue_shift); + pages = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, alloc_order); + if (!pages) + return ERR_PTR(-ENOMEM); + qpage = (__be32 *)page_address(pages); + memset(qpage, 0, 1 << queue_shift); + + return qpage; +} + static int __init xive_off(char *arg) { xive_cmdline_disabled = true; diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 0f95476b01f6f7beae053a959e0d234ba5643f7f..ebc244b08d6748512c19199446d25f7ac49fca9b 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -82,6 +82,8 @@ int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) return -ENOMEM; } + data->hw_irq = hw_irq; + if (!data->trig_page) return 0; if (data->trig_page == data->eoi_page) { @@ -202,17 +204,12 @@ EXPORT_SYMBOL_GPL(xive_native_disable_queue); static int xive_native_setup_queue(unsigned int cpu, struct xive_cpu *xc, u8 prio) { struct xive_q *q = &xc->queue[prio]; - unsigned int alloc_order; - struct page *pages; __be32 *qpage; - alloc_order = (xive_queue_shift > PAGE_SHIFT) ? - (xive_queue_shift - PAGE_SHIFT) : 0; - pages = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, alloc_order); - if (!pages) - return -ENOMEM; - qpage = (__be32 *)page_address(pages); - memset(qpage, 0, 1 << xive_queue_shift); + qpage = xive_queue_page_alloc(cpu, xive_queue_shift); + if (IS_ERR(qpage)) + return PTR_ERR(qpage); + return xive_native_configure_queue(get_hard_smp_processor_id(cpu), q, prio, qpage, xive_queue_shift, false); } @@ -227,8 +224,7 @@ static void xive_native_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, u8 * from an IPI and iounmap isn't safe */ __xive_native_disable_queue(get_hard_smp_processor_id(cpu), q, prio); - alloc_order = (xive_queue_shift > PAGE_SHIFT) ? - (xive_queue_shift - PAGE_SHIFT) : 0; + alloc_order = xive_alloc_order(xive_queue_shift); free_pages((unsigned long)q->qpage, alloc_order); q->qpage = NULL; } @@ -515,13 +511,13 @@ static bool xive_parse_provisioning(struct device_node *np) static void xive_native_setup_pools(void) { /* Allocate a pool big enough */ - pr_debug("XIVE: Allocating VP block for pool size %d\n", nr_cpu_ids); + pr_debug("XIVE: Allocating VP block for pool size %u\n", nr_cpu_ids); xive_pool_vps = xive_native_alloc_vp_block(nr_cpu_ids); if (WARN_ON(xive_pool_vps == XIVE_INVALID_VP)) pr_err("XIVE: Failed to allocate pool VP, KVM might not function\n"); - pr_debug("XIVE: Pool VPs allocated at 0x%x for %d max CPUs\n", + pr_debug("XIVE: Pool VPs allocated at 0x%x for %u max CPUs\n", xive_pool_vps, nr_cpu_ids); } @@ -531,7 +527,7 @@ u32 xive_native_default_eq_shift(void) } EXPORT_SYMBOL_GPL(xive_native_default_eq_shift); -bool xive_native_init(void) +bool __init xive_native_init(void) { struct device_node *np; struct resource r; @@ -551,7 +547,7 @@ bool xive_native_init(void) pr_devel("not found !\n"); return false; } - pr_devel("Found %s\n", np->full_name); + pr_devel("Found %pOF\n", np); /* Resource 1 is HV window */ if (of_address_to_resource(np, 1, &r)) { diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c new file mode 100644 index 0000000000000000000000000000000000000000..d9c4c93660491849029044d37ab8e60160b0d7de --- /dev/null +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -0,0 +1,666 @@ +/* + * Copyright 2016,2017 IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "xive: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xive-internal.h" + +static u32 xive_queue_shift; + +struct xive_irq_bitmap { + unsigned long *bitmap; + unsigned int base; + unsigned int count; + spinlock_t lock; + struct list_head list; +}; + +static LIST_HEAD(xive_irq_bitmaps); + +static int xive_irq_bitmap_add(int base, int count) +{ + struct xive_irq_bitmap *xibm; + + xibm = kzalloc(sizeof(*xibm), GFP_ATOMIC); + if (!xibm) + return -ENOMEM; + + spin_lock_init(&xibm->lock); + xibm->base = base; + xibm->count = count; + xibm->bitmap = kzalloc(xibm->count, GFP_KERNEL); + list_add(&xibm->list, &xive_irq_bitmaps); + + pr_info("Using IRQ range [%x-%x]", xibm->base, + xibm->base + xibm->count - 1); + return 0; +} + +static int __xive_irq_bitmap_alloc(struct xive_irq_bitmap *xibm) +{ + int irq; + + irq = find_first_zero_bit(xibm->bitmap, xibm->count); + if (irq != xibm->count) { + set_bit(irq, xibm->bitmap); + irq += xibm->base; + } else { + irq = -ENOMEM; + } + + return irq; +} + +static int xive_irq_bitmap_alloc(void) +{ + struct xive_irq_bitmap *xibm; + unsigned long flags; + int irq = -ENOENT; + + list_for_each_entry(xibm, &xive_irq_bitmaps, list) { + spin_lock_irqsave(&xibm->lock, flags); + irq = __xive_irq_bitmap_alloc(xibm); + spin_unlock_irqrestore(&xibm->lock, flags); + if (irq >= 0) + break; + } + return irq; +} + +static void xive_irq_bitmap_free(int irq) +{ + unsigned long flags; + struct xive_irq_bitmap *xibm; + + list_for_each_entry(xibm, &xive_irq_bitmaps, list) { + if ((irq >= xibm->base) && (irq < xibm->base + xibm->count)) { + spin_lock_irqsave(&xibm->lock, flags); + clear_bit(irq - xibm->base, xibm->bitmap); + spin_unlock_irqrestore(&xibm->lock, flags); + break; + } + } +} + +static long plpar_int_get_source_info(unsigned long flags, + unsigned long lisn, + unsigned long *src_flags, + unsigned long *eoi_page, + unsigned long *trig_page, + unsigned long *esb_shift) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long rc; + + rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn); + if (rc) { + pr_err("H_INT_GET_SOURCE_INFO lisn=%ld failed %ld\n", lisn, rc); + return rc; + } + + *src_flags = retbuf[0]; + *eoi_page = retbuf[1]; + *trig_page = retbuf[2]; + *esb_shift = retbuf[3]; + + pr_devel("H_INT_GET_SOURCE_INFO flags=%lx eoi=%lx trig=%lx shift=%lx\n", + retbuf[0], retbuf[1], retbuf[2], retbuf[3]); + + return 0; +} + +#define XIVE_SRC_SET_EISN (1ull << (63 - 62)) +#define XIVE_SRC_MASK (1ull << (63 - 63)) /* unused */ + +static long plpar_int_set_source_config(unsigned long flags, + unsigned long lisn, + unsigned long target, + unsigned long prio, + unsigned long sw_irq) +{ + long rc; + + + pr_devel("H_INT_SET_SOURCE_CONFIG flags=%lx lisn=%lx target=%lx prio=%lx sw_irq=%lx\n", + flags, lisn, target, prio, sw_irq); + + + rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn, + target, prio, sw_irq); + if (rc) { + pr_err("H_INT_SET_SOURCE_CONFIG lisn=%ld target=%lx prio=%lx failed %ld\n", + lisn, target, prio, rc); + return rc; + } + + return 0; +} + +static long plpar_int_get_queue_info(unsigned long flags, + unsigned long target, + unsigned long priority, + unsigned long *esn_page, + unsigned long *esn_size) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long rc; + + rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, priority); + if (rc) { + pr_err("H_INT_GET_QUEUE_INFO cpu=%ld prio=%ld failed %ld\n", + target, priority, rc); + return rc; + } + + *esn_page = retbuf[0]; + *esn_size = retbuf[1]; + + pr_devel("H_INT_GET_QUEUE_INFO page=%lx size=%lx\n", + retbuf[0], retbuf[1]); + + return 0; +} + +#define XIVE_EQ_ALWAYS_NOTIFY (1ull << (63 - 63)) + +static long plpar_int_set_queue_config(unsigned long flags, + unsigned long target, + unsigned long priority, + unsigned long qpage, + unsigned long qsize) +{ + long rc; + + pr_devel("H_INT_SET_QUEUE_CONFIG flags=%lx target=%lx priority=%lx qpage=%lx qsize=%lx\n", + flags, target, priority, qpage, qsize); + + rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target, + priority, qpage, qsize); + if (rc) { + pr_err("H_INT_SET_QUEUE_CONFIG cpu=%ld prio=%ld qpage=%lx returned %ld\n", + target, priority, qpage, rc); + return rc; + } + + return 0; +} + +static long plpar_int_sync(unsigned long flags, unsigned long lisn) +{ + long rc; + + rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn); + if (rc) { + pr_err("H_INT_SYNC lisn=%ld returned %ld\n", lisn, rc); + return rc; + } + + return 0; +} + +#define XIVE_ESB_FLAG_STORE (1ull << (63 - 63)) + +static long plpar_int_esb(unsigned long flags, + unsigned long lisn, + unsigned long offset, + unsigned long in_data, + unsigned long *out_data) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long rc; + + pr_devel("H_INT_ESB flags=%lx lisn=%lx offset=%lx in=%lx\n", + flags, lisn, offset, in_data); + + rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, in_data); + if (rc) { + pr_err("H_INT_ESB lisn=%ld offset=%ld returned %ld\n", + lisn, offset, rc); + return rc; + } + + *out_data = retbuf[0]; + + return 0; +} + +static u64 xive_spapr_esb_rw(u32 lisn, u32 offset, u64 data, bool write) +{ + unsigned long read_data; + long rc; + + rc = plpar_int_esb(write ? XIVE_ESB_FLAG_STORE : 0, + lisn, offset, data, &read_data); + if (rc) + return -1; + + return write ? 0 : read_data; +} + +#define XIVE_SRC_H_INT_ESB (1ull << (63 - 60)) +#define XIVE_SRC_LSI (1ull << (63 - 61)) +#define XIVE_SRC_TRIGGER (1ull << (63 - 62)) +#define XIVE_SRC_STORE_EOI (1ull << (63 - 63)) + +static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) +{ + long rc; + unsigned long flags; + unsigned long eoi_page; + unsigned long trig_page; + unsigned long esb_shift; + + memset(data, 0, sizeof(*data)); + + rc = plpar_int_get_source_info(0, hw_irq, &flags, &eoi_page, &trig_page, + &esb_shift); + if (rc) + return -EINVAL; + + if (flags & XIVE_SRC_H_INT_ESB) + data->flags |= XIVE_IRQ_FLAG_H_INT_ESB; + if (flags & XIVE_SRC_STORE_EOI) + data->flags |= XIVE_IRQ_FLAG_STORE_EOI; + if (flags & XIVE_SRC_LSI) + data->flags |= XIVE_IRQ_FLAG_LSI; + data->eoi_page = eoi_page; + data->esb_shift = esb_shift; + data->trig_page = trig_page; + + /* + * No chip-id for the sPAPR backend. This has an impact how we + * pick a target. See xive_pick_irq_target(). + */ + data->src_chip = XIVE_INVALID_CHIP_ID; + + data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); + if (!data->eoi_mmio) { + pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); + return -ENOMEM; + } + + data->hw_irq = hw_irq; + + /* Full function page supports trigger */ + if (flags & XIVE_SRC_TRIGGER) { + data->trig_mmio = data->eoi_mmio; + return 0; + } + + data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift); + if (!data->trig_mmio) { + pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq); + return -ENOMEM; + } + return 0; +} + +static int xive_spapr_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq) +{ + long rc; + + rc = plpar_int_set_source_config(XIVE_SRC_SET_EISN, hw_irq, target, + prio, sw_irq); + + return rc == 0 ? 0 : -ENXIO; +} + +/* This can be called multiple time to change a queue configuration */ +static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio, + __be32 *qpage, u32 order) +{ + s64 rc = 0; + unsigned long esn_page; + unsigned long esn_size; + u64 flags, qpage_phys; + + /* If there's an actual queue page, clean it */ + if (order) { + if (WARN_ON(!qpage)) + return -EINVAL; + qpage_phys = __pa(qpage); + } else { + qpage_phys = 0; + } + + /* Initialize the rest of the fields */ + q->msk = order ? ((1u << (order - 2)) - 1) : 0; + q->idx = 0; + q->toggle = 0; + + rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); + if (rc) { + pr_err("Error %lld getting queue info prio %d\n", rc, prio); + rc = -EIO; + goto fail; + } + + /* TODO: add support for the notification page */ + q->eoi_phys = esn_page; + + /* Default is to always notify */ + flags = XIVE_EQ_ALWAYS_NOTIFY; + + /* Configure and enable the queue in HW */ + rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); + if (rc) { + pr_err("Error %lld setting queue for prio %d\n", rc, prio); + rc = -EIO; + } else { + q->qpage = qpage; + } +fail: + return rc; +} + +static int xive_spapr_setup_queue(unsigned int cpu, struct xive_cpu *xc, + u8 prio) +{ + struct xive_q *q = &xc->queue[prio]; + __be32 *qpage; + + qpage = xive_queue_page_alloc(cpu, xive_queue_shift); + if (IS_ERR(qpage)) + return PTR_ERR(qpage); + + return xive_spapr_configure_queue(cpu, q, prio, qpage, + xive_queue_shift); +} + +static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, + u8 prio) +{ + struct xive_q *q = &xc->queue[prio]; + unsigned int alloc_order; + long rc; + + rc = plpar_int_set_queue_config(0, cpu, prio, 0, 0); + if (rc) + pr_err("Error %ld setting queue for prio %d\n", rc, prio); + + alloc_order = xive_alloc_order(xive_queue_shift); + free_pages((unsigned long)q->qpage, alloc_order); + q->qpage = NULL; +} + +static bool xive_spapr_match(struct device_node *node) +{ + /* Ignore cascaded controllers for the moment */ + return 1; +} + +#ifdef CONFIG_SMP +static int xive_spapr_get_ipi(unsigned int cpu, struct xive_cpu *xc) +{ + int irq = xive_irq_bitmap_alloc(); + + if (irq < 0) { + pr_err("Failed to allocate IPI on CPU %d\n", cpu); + return -ENXIO; + } + + xc->hw_ipi = irq; + return 0; +} + +static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc) +{ + if (!xc->hw_ipi) + return; + + xive_irq_bitmap_free(xc->hw_ipi); + xc->hw_ipi = 0; +} +#endif /* CONFIG_SMP */ + +static void xive_spapr_shutdown(void) +{ + long rc; + + rc = plpar_hcall_norets(H_INT_RESET, 0); + if (rc) + pr_err("H_INT_RESET failed %ld\n", rc); +} + +/* + * Perform an "ack" cycle on the current thread. Grab the pending + * active priorities and update the CPPR to the most favored one. + */ +static void xive_spapr_update_pending(struct xive_cpu *xc) +{ + u8 nsr, cppr; + u16 ack; + + /* + * Perform the "Acknowledge O/S to Register" cycle. + * + * Let's speedup the access to the TIMA using the raw I/O + * accessor as we don't need the synchronisation routine of + * the higher level ones + */ + ack = be16_to_cpu(__raw_readw(xive_tima + TM_SPC_ACK_OS_REG)); + + /* Synchronize subsequent queue accesses */ + mb(); + + /* + * Grab the CPPR and the "NSR" field which indicates the source + * of the interrupt (if any) + */ + cppr = ack & 0xff; + nsr = ack >> 8; + + if (nsr & TM_QW1_NSR_EO) { + if (cppr == 0xff) + return; + /* Mark the priority pending */ + xc->pending_prio |= 1 << cppr; + + /* + * A new interrupt should never have a CPPR less favored + * than our current one. + */ + if (cppr >= xc->cppr) + pr_err("CPU %d odd ack CPPR, got %d at %d\n", + smp_processor_id(), cppr, xc->cppr); + + /* Update our idea of what the CPPR is */ + xc->cppr = cppr; + } +} + +static void xive_spapr_eoi(u32 hw_irq) +{ + /* Not used */; +} + +static void xive_spapr_setup_cpu(unsigned int cpu, struct xive_cpu *xc) +{ + /* Only some debug on the TIMA settings */ + pr_debug("(HW value: %08x %08x %08x)\n", + in_be32(xive_tima + TM_QW1_OS + TM_WORD0), + in_be32(xive_tima + TM_QW1_OS + TM_WORD1), + in_be32(xive_tima + TM_QW1_OS + TM_WORD2)); +} + +static void xive_spapr_teardown_cpu(unsigned int cpu, struct xive_cpu *xc) +{ + /* Nothing to do */; +} + +static void xive_spapr_sync_source(u32 hw_irq) +{ + /* Specs are unclear on what this is doing */ + plpar_int_sync(0, hw_irq); +} + +static const struct xive_ops xive_spapr_ops = { + .populate_irq_data = xive_spapr_populate_irq_data, + .configure_irq = xive_spapr_configure_irq, + .setup_queue = xive_spapr_setup_queue, + .cleanup_queue = xive_spapr_cleanup_queue, + .match = xive_spapr_match, + .shutdown = xive_spapr_shutdown, + .update_pending = xive_spapr_update_pending, + .eoi = xive_spapr_eoi, + .setup_cpu = xive_spapr_setup_cpu, + .teardown_cpu = xive_spapr_teardown_cpu, + .sync_source = xive_spapr_sync_source, + .esb_rw = xive_spapr_esb_rw, +#ifdef CONFIG_SMP + .get_ipi = xive_spapr_get_ipi, + .put_ipi = xive_spapr_put_ipi, +#endif /* CONFIG_SMP */ + .name = "spapr", +}; + +/* + * get max priority from "/ibm,plat-res-int-priorities" + */ +static bool xive_get_max_prio(u8 *max_prio) +{ + struct device_node *rootdn; + const __be32 *reg; + u32 len; + int prio, found; + + rootdn = of_find_node_by_path("/"); + if (!rootdn) { + pr_err("not root node found !\n"); + return false; + } + + reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len); + if (!reg) { + pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n"); + return false; + } + + if (len % (2 * sizeof(u32)) != 0) { + pr_err("invalid 'ibm,plat-res-int-priorities' property\n"); + return false; + } + + /* HW supports priorities in the range [0-7] and 0xFF is a + * wildcard priority used to mask. We scan the ranges reserved + * by the hypervisor to find the lowest priority we can use. + */ + found = 0xFF; + for (prio = 0; prio < 8; prio++) { + int reserved = 0; + int i; + + for (i = 0; i < len / (2 * sizeof(u32)); i++) { + int base = be32_to_cpu(reg[2 * i]); + int range = be32_to_cpu(reg[2 * i + 1]); + + if (prio >= base && prio < base + range) + reserved++; + } + + if (!reserved) + found = prio; + } + + if (found == 0xFF) { + pr_err("no valid priority found in 'ibm,plat-res-int-priorities'\n"); + return false; + } + + *max_prio = found; + return true; +} + +bool __init xive_spapr_init(void) +{ + struct device_node *np; + struct resource r; + void __iomem *tima; + struct property *prop; + u8 max_prio; + u32 val; + u32 len; + const __be32 *reg; + int i; + + if (xive_cmdline_disabled) + return false; + + pr_devel("%s()\n", __func__); + np = of_find_compatible_node(NULL, NULL, "ibm,power-ivpe"); + if (!np) { + pr_devel("not found !\n"); + return false; + } + pr_devel("Found %s\n", np->full_name); + + /* Resource 1 is the OS ring TIMA */ + if (of_address_to_resource(np, 1, &r)) { + pr_err("Failed to get thread mgmnt area resource\n"); + return false; + } + tima = ioremap(r.start, resource_size(&r)); + if (!tima) { + pr_err("Failed to map thread mgmnt area\n"); + return false; + } + + if (!xive_get_max_prio(&max_prio)) + return false; + + /* Feed the IRQ number allocator with the ranges given in the DT */ + reg = of_get_property(np, "ibm,xive-lisn-ranges", &len); + if (!reg) { + pr_err("Failed to read 'ibm,xive-lisn-ranges' property\n"); + return false; + } + + if (len % (2 * sizeof(u32)) != 0) { + pr_err("invalid 'ibm,xive-lisn-ranges' property\n"); + return false; + } + + for (i = 0; i < len / (2 * sizeof(u32)); i++, reg += 2) + xive_irq_bitmap_add(be32_to_cpu(reg[0]), + be32_to_cpu(reg[1])); + + /* Iterate the EQ sizes and pick one */ + of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) { + xive_queue_shift = val; + if (val == PAGE_SHIFT) + break; + } + + /* Initialize XIVE core with our backend */ + if (!xive_core_init(&xive_spapr_ops, tima, TM_QW1_OS, max_prio)) + return false; + + pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); + return true; +} diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h index d07ef2d29caf0776bfcb709ccec2c45fbb660b84..f34abed0c05fd3064bf0a2c45fb193b49079283f 100644 --- a/arch/powerpc/sysdev/xive/xive-internal.h +++ b/arch/powerpc/sysdev/xive/xive-internal.h @@ -47,6 +47,7 @@ struct xive_ops { void (*update_pending)(struct xive_cpu *xc); void (*eoi)(u32 hw_irq); void (*sync_source)(u32 hw_irq); + u64 (*esb_rw)(u32 hw_irq, u32 offset, u64 data, bool write); #ifdef CONFIG_SMP int (*get_ipi)(unsigned int cpu, struct xive_cpu *xc); void (*put_ipi)(unsigned int cpu, struct xive_cpu *xc); @@ -56,6 +57,12 @@ struct xive_ops { bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, u8 max_prio); +__be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift); + +static inline u32 xive_alloc_order(u32 queue_shift) +{ + return (queue_shift > PAGE_SHIFT) ? (queue_shift - PAGE_SHIFT) : 0; +} extern bool xive_cmdline_disabled; diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 0b2f771593ebde86b39e636f6ed2a280603c7159..1dd88315cff4bd8bb12da4bcfe10b7db209d0f55 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -5,6 +5,10 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror GCOV_PROFILE := n UBSAN_SANITIZE := n +# Disable ftrace for the entire directory +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(subst -mno-sched-epilog,,$(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS))) + ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) obj-y += xmon.o nonstdio.o spr_access.o diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 08e367e3e8c3128ef6da58b3cd5caa5c511e98b4..33351c6704b1d0e0fe5138f24ccfed8f1af555e8 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -89,6 +89,7 @@ static unsigned long nidump = 16; static unsigned long ncsum = 4096; static int termch; static char tmpstr[128]; +static int tracing_enabled; static long bus_error_jmp[JMP_BUF_LEN]; static int catch_memory_errors; @@ -234,6 +235,7 @@ Commands:\n\ "\ dr dump stream of raw bytes\n\ dt dump the tracing buffers (uses printk)\n\ + dtc dump the tracing buffers for current CPU (uses printk)\n\ " #ifdef CONFIG_PPC_POWERNV " dx# dump xive on CPU #\n\ @@ -461,6 +463,9 @@ static int xmon_core(struct pt_regs *regs, int fromipi) local_irq_save(flags); hard_irq_disable(); + tracing_enabled = tracing_is_on(); + tracing_off(); + bp = in_breakpoint_table(regs->nip, &offset); if (bp != NULL) { regs->nip = bp->address + offset; @@ -981,6 +986,8 @@ cmds(struct pt_regs *excp) break; case 'x': case 'X': + if (tracing_enabled) + tracing_on(); return cmd; case EOF: printf(" \n"); @@ -1732,23 +1739,25 @@ static void dump_206_sprs(void) /* Actually some of these pre-date 2.06, but whatevs */ - printf("srr0 = %.16x srr1 = %.16x dsisr = %.8x\n", + printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8x\n", mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR)); - printf("dscr = %.16x ppr = %.16x pir = %.8x\n", + printf("dscr = %.16lx ppr = %.16lx pir = %.8x\n", mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR)); + printf("amr = %.16lx uamor = %.16lx\n", + mfspr(SPRN_AMR), mfspr(SPRN_UAMOR)); if (!(mfmsr() & MSR_HV)) return; - printf("sdr1 = %.16x hdar = %.16x hdsisr = %.8x\n", + printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8x\n", mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR)); - printf("hsrr0 = %.16x hsrr1 = %.16x hdec = %.8x\n", + printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n", mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC)); - printf("lpcr = %.16x pcr = %.16x lpidr = %.8x\n", + printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8x\n", mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID)); - printf("hsprg0 = %.16x hsprg1 = %.16x\n", - mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1)); - printf("dabr = %.16x dabrx = %.16x\n", + printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n", + mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR)); + printf("dabr = %.16lx dabrx = %.16lx\n", mfspr(SPRN_DABR), mfspr(SPRN_DABRX)); #endif } @@ -1761,42 +1770,65 @@ static void dump_207_sprs(void) if (!cpu_has_feature(CPU_FTR_ARCH_207S)) return; - printf("dpdes = %.16x tir = %.16x cir = %.8x\n", + printf("dpdes = %.16lx tir = %.16lx cir = %.8x\n", mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR)); - printf("fscr = %.16x tar = %.16x pspb = %.8x\n", + printf("fscr = %.16lx tar = %.16lx pspb = %.8x\n", mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB)); msr = mfmsr(); if (msr & MSR_TM) { /* Only if TM has been enabled in the kernel */ - printf("tfhar = %.16x tfiar = %.16x texasr = %.16x\n", + printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n", mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR), mfspr(SPRN_TEXASR)); } - printf("mmcr0 = %.16x mmcr1 = %.16x mmcr2 = %.16x\n", + printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n", mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2)); printf("pmc1 = %.8x pmc2 = %.8x pmc3 = %.8x pmc4 = %.8x\n", mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3), mfspr(SPRN_PMC4)); - printf("mmcra = %.16x siar = %.16x pmc5 = %.8x\n", + printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8x\n", mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5)); - printf("sdar = %.16x sier = %.16x pmc6 = %.8x\n", + printf("sdar = %.16lx sier = %.16lx pmc6 = %.8x\n", mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6)); - printf("ebbhr = %.16x ebbrr = %.16x bescr = %.16x\n", + printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n", mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR)); + printf("iamr = %.16lx\n", mfspr(SPRN_IAMR)); if (!(msr & MSR_HV)) return; - printf("hfscr = %.16x dhdes = %.16x rpr = %.16x\n", + printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n", mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR)); - printf("dawr = %.16x dawrx = %.16x ciabr = %.16x\n", + printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n", mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR)); #endif } +static void dump_300_sprs(void) +{ +#ifdef CONFIG_PPC64 + bool hv = mfmsr() & MSR_HV; + + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + return; + + printf("pidr = %.16lx tidr = %.16lx\n", + mfspr(SPRN_PID), mfspr(SPRN_TIDR)); + printf("asdr = %.16lx psscr = %.16lx\n", + mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR) + : mfspr(SPRN_PSSCR_PR)); + + if (!hv) + return; + + printf("ptcr = %.16lx\n", + mfspr(SPRN_PTCR)); +#endif +} + static void dump_one_spr(int spr, bool show_unimplemented) { unsigned long val; @@ -1850,6 +1882,7 @@ static void super_regs(void) dump_206_sprs(); dump_207_sprs(); + dump_300_sprs(); return; } @@ -2231,6 +2264,17 @@ static void xmon_rawdump (unsigned long adrs, long ndump) printf("\n"); } +static void dump_tracing(void) +{ + int c; + + c = inchar(); + if (c == 'c') + ftrace_dump(DUMP_ORIG); + else + ftrace_dump(DUMP_ALL); +} + #ifdef CONFIG_PPC64 static void dump_one_paca(int cpu) { @@ -2507,6 +2551,11 @@ dump(void) } #endif + if (c == 't') { + dump_tracing(); + return; + } + if (c == '\n') termch = c; @@ -2525,9 +2574,6 @@ dump(void) dump_log_buf(); } else if (c == 'o') { dump_opal_msglog(); - } else if (c == 't') { - ftrace_dump(DUMP_ALL); - tracing_on(); } else if (c == 'r') { scanhex(&ndump); if (ndump == 0) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 7eeb75d758c196449e6ed90527c731b945e97e49..48af970320cbdf7a7cdbfff88a6e91a5f1c91b46 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -222,6 +222,10 @@ config HAVE_MARCH_Z13_FEATURES def_bool n select HAVE_MARCH_ZEC12_FEATURES +config HAVE_MARCH_Z14_FEATURES + def_bool n + select HAVE_MARCH_Z13_FEATURES + choice prompt "Processor type" default MARCH_Z196 @@ -282,6 +286,14 @@ config MARCH_Z13 2964 series). The kernel will be slightly faster but will not work on older machines. +config MARCH_Z14 + bool "IBM z14" + select HAVE_MARCH_Z14_FEATURES + help + Select this to enable optimizations for IBM z14 (3906 series). + The kernel will be slightly faster but will not work on older + machines. + endchoice config MARCH_Z900_TUNE @@ -305,6 +317,9 @@ config MARCH_ZEC12_TUNE config MARCH_Z13_TUNE def_bool TUNE_Z13 || MARCH_Z13 && TUNE_DEFAULT +config MARCH_Z14_TUNE + def_bool TUNE_Z14 || MARCH_Z14 && TUNE_DEFAULT + choice prompt "Tune code generation" default TUNE_DEFAULT @@ -343,6 +358,9 @@ config TUNE_ZEC12 config TUNE_Z13 bool "IBM z13" +config TUNE_Z14 + bool "IBM z14" + endchoice config 64BIT diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 54e00526b8dfcf1b8d3f21278b1626551dc68459..dac821cfcd430310a95624754d7dd814bcd7705b 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -31,7 +31,8 @@ mflags-$(CONFIG_MARCH_Z9_109) := -march=z9-109 mflags-$(CONFIG_MARCH_Z10) := -march=z10 mflags-$(CONFIG_MARCH_Z196) := -march=z196 mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12 -mflags-$(CONFIG_MARCH_Z13) := -march=z13 +mflags-$(CONFIG_MARCH_Z13) := -march=z13 +mflags-$(CONFIG_MARCH_Z14) := -march=z14 export CC_FLAGS_MARCH := $(mflags-y) @@ -44,7 +45,8 @@ cflags-$(CONFIG_MARCH_Z9_109_TUNE) += -mtune=z9-109 cflags-$(CONFIG_MARCH_Z10_TUNE) += -mtune=z10 cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196 cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 -cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 +cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 +cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index b3c88479febab2f7b60f7f6c238886e31ff8579f..6e2c9f7e47fa03a7dcc51691da104aa9d3b6fcbf 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -16,4 +16,5 @@ generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h generic-y += preempt.h generic-y += trace_clock.h +generic-y += unaligned.h generic-y += word-at-a-time.h diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h new file mode 100644 index 0000000000000000000000000000000000000000..c02f4aba88a6220bfc1bc7714632d52676aa5bef --- /dev/null +++ b/arch/s390/include/asm/ap.h @@ -0,0 +1,126 @@ +/* + * Adjunct processor (AP) interfaces + * + * Copyright IBM Corp. 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Tony Krowiak + * Martin Schwidefsky + * Harald Freudenberger + */ + +#ifndef _ASM_S390_AP_H_ +#define _ASM_S390_AP_H_ + +/** + * The ap_qid_t identifier of an ap queue. + * If the AP facilities test (APFT) facility is available, + * card and queue index are 8 bit values, otherwise + * card index is 6 bit and queue index a 4 bit value. + */ +typedef unsigned int ap_qid_t; + +#define AP_MKQID(_card, _queue) (((_card) & 63) << 8 | ((_queue) & 255)) +#define AP_QID_CARD(_qid) (((_qid) >> 8) & 63) +#define AP_QID_QUEUE(_qid) ((_qid) & 255) + +/** + * struct ap_queue_status - Holds the AP queue status. + * @queue_empty: Shows if queue is empty + * @replies_waiting: Waiting replies + * @queue_full: Is 1 if the queue is full + * @irq_enabled: Shows if interrupts are enabled for the AP + * @response_code: Holds the 8 bit response code + * + * The ap queue status word is returned by all three AP functions + * (PQAP, NQAP and DQAP). There's a set of flags in the first + * byte, followed by a 1 byte response code. + */ +struct ap_queue_status { + unsigned int queue_empty : 1; + unsigned int replies_waiting : 1; + unsigned int queue_full : 1; + unsigned int _pad1 : 4; + unsigned int irq_enabled : 1; + unsigned int response_code : 8; + unsigned int _pad2 : 16; +}; + +/** + * ap_test_queue(): Test adjunct processor queue. + * @qid: The AP queue number + * @tbit: Test facilities bit + * @info: Pointer to queue descriptor + * + * Returns AP queue status structure. + */ +struct ap_queue_status ap_test_queue(ap_qid_t qid, + int tbit, + unsigned long *info); + +struct ap_config_info { + unsigned int apsc : 1; /* S bit */ + unsigned int apxa : 1; /* N bit */ + unsigned int qact : 1; /* C bit */ + unsigned int rc8a : 1; /* R bit */ + unsigned char _reserved1 : 4; + unsigned char _reserved2[3]; + unsigned char Na; /* max # of APs - 1 */ + unsigned char Nd; /* max # of Domains - 1 */ + unsigned char _reserved3[10]; + unsigned int apm[8]; /* AP ID mask */ + unsigned int aqm[8]; /* AP queue mask */ + unsigned int adm[8]; /* AP domain mask */ + unsigned char _reserved4[16]; +} __aligned(8); + +/* + * ap_query_configuration(): Fetch cryptographic config info + * + * Returns the ap configuration info fetched via PQAP(QCI). + * On success 0 is returned, on failure a negative errno + * is returned, e.g. if the PQAP(QCI) instruction is not + * available, the return value will be -EOPNOTSUPP. + */ +int ap_query_configuration(struct ap_config_info *info); + +/* + * struct ap_qirq_ctrl - convenient struct for easy invocation + * of the ap_queue_irq_ctrl() function. This struct is passed + * as GR1 parameter to the PQAP(AQIC) instruction. For details + * please see the AR documentation. + */ +struct ap_qirq_ctrl { + unsigned int _res1 : 8; + unsigned int zone : 8; /* zone info */ + unsigned int ir : 1; /* ir flag: enable (1) or disable (0) irq */ + unsigned int _res2 : 4; + unsigned int gisc : 3; /* guest isc field */ + unsigned int _res3 : 6; + unsigned int gf : 2; /* gisa format */ + unsigned int _res4 : 1; + unsigned int gisa : 27; /* gisa origin */ + unsigned int _res5 : 1; + unsigned int isc : 3; /* irq sub class */ +}; + +/** + * ap_queue_irq_ctrl(): Control interruption on a AP queue. + * @qid: The AP queue number + * @qirqctrl: struct ap_qirq_ctrl, see above + * @ind: The notification indicator byte + * + * Returns AP queue status. + * + * Control interruption on the given AP queue. + * Just a simple wrapper function for the low level PQAP(AQIC) + * instruction available for other kernel modules. + */ +struct ap_queue_status ap_queue_irq_ctrl(ap_qid_t qid, + struct ap_qirq_ctrl qirqctrl, + void *ind); + +#endif /* _ASM_S390_AP_H_ */ diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index b9300f8aee10a5754909e63946c6f06d0bbc74f1..07a82bc933a775df11a9d2084bcd0b4eeb768311 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -8,11 +8,12 @@ #include #include -#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) +#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \ + typeof(0?(__force t)0:0ULL), u64)) #define __SC_DELOUSE(t,v) ({ \ BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ - (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ + (__force t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ }) #define PSW32_MASK_PER 0x40000000UL diff --git a/arch/s390/include/asm/cpcmd.h b/arch/s390/include/asm/cpcmd.h index 3dfadb5d648f5de6a14d2010a101d377dadb0787..ca2b0624ad461d0bf03068f99a422bb58851caec 100644 --- a/arch/s390/include/asm/cpcmd.h +++ b/arch/s390/include/asm/cpcmd.h @@ -10,9 +10,8 @@ /* * the lowlevel function for cpcmd - * the caller of __cpcmd has to ensure that the response buffer is below 2 GB */ -extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); +int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); /* * cpcmd is the in-kernel interface for issuing CP commands @@ -25,8 +24,8 @@ extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code * response_code: return pointer for VM's error code * return value: the size of the response. The caller can check if the buffer * was large enough by comparing the return value and rlen - * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep + * NOTE: If the response buffer is not in real storage, cpcmd can sleep */ -extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code); +int cpcmd(const char *cmd, char *response, int rlen, int *response_code); #endif /* _ASM_S390_CPCMD_H */ diff --git a/arch/s390/include/asm/ebcdic.h b/arch/s390/include/asm/ebcdic.h index c5befc5a3bf5757c98e0f5cedefa9bc4ec00815a..b71735eab23f640171d1c5cb8d381111bfc99e73 100644 --- a/arch/s390/include/asm/ebcdic.h +++ b/arch/s390/include/asm/ebcdic.h @@ -9,9 +9,7 @@ #ifndef _EBCDIC_H #define _EBCDIC_H -#ifndef _S390_TYPES_H -#include -#endif +#include extern __u8 _ascebc_500[256]; /* ASCII -> EBCDIC 500 conversion table */ extern __u8 _ebcasc_500[256]; /* EBCDIC 500 -> ASCII conversion table */ diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index c92ed0170be22061e7b02b5d9ec29a76a0b0abe9..65998a1f5d430f23feca39251fadd4bdf6854f9a 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -191,7 +191,7 @@ struct arch_elf_state { } while (0) #define CORE_DUMP_USE_REGSET -#define ELF_EXEC_PAGESIZE 4096 +#define ELF_EXEC_PAGESIZE PAGE_SIZE /* * This is the base location for PIE (ET_DYN with INTERP) loads. On diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index a4811aa0304d03264c4e63626d61619c62d16f0c..8f8eec9e1198cc97fef9fd036a953dbd7c9d6009 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h @@ -21,17 +21,12 @@ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ "m" (*uaddr) : "cc"); -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, newval, ret; load_kernel_asce(); - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; pagefault_disable(); switch (op) { @@ -60,17 +55,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index edb5161df7e2945831f9697f676a24e0e8582450..6810bd75731288b74acf11ea3c8c0a709141af4c 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -81,7 +81,7 @@ struct ipl_parameter_block { struct ipl_block_fcp fcp; struct ipl_block_ccw ccw; } ipl_info; -} __attribute__((packed,aligned(4096))); +} __packed __aligned(PAGE_SIZE); /* * IPL validity flags diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index a409d59919344a277fac0858c2bd12ece1bd83c9..51375e766e905a955a4df21fa185c669bfaa9544 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -226,7 +226,9 @@ struct kvm_s390_sie_block { #define ECB3_RI 0x01 __u8 ecb3; /* 0x0063 */ __u32 scaol; /* 0x0064 */ - __u8 reserved68[4]; /* 0x0068 */ + __u8 reserved68; /* 0x0068 */ + __u8 epdx; /* 0x0069 */ + __u8 reserved6a[2]; /* 0x006a */ __u32 todpr; /* 0x006c */ __u8 reserved70[16]; /* 0x0070 */ __u64 mso; /* 0x0080 */ @@ -265,6 +267,7 @@ struct kvm_s390_sie_block { __u64 cbrlo; /* 0x01b8 */ __u8 reserved1c0[8]; /* 0x01c0 */ #define ECD_HOSTREGMGMT 0x20000000 +#define ECD_MEF 0x08000000 __u32 ecd; /* 0x01c8 */ __u8 reserved1cc[18]; /* 0x01cc */ __u64 pp; /* 0x01de */ @@ -739,6 +742,7 @@ struct kvm_arch{ struct kvm_s390_cpu_model model; struct kvm_s390_crypto crypto; struct kvm_s390_vsie vsie; + u8 epdx; u64 epoch; struct kvm_s390_migration_state *migration_state; /* subset of available cpu features enabled by user space */ diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 8a5b082797f89ad0e456211de630a06ab98140f8..a6870ea6ea8b48083430d38ed628ed5964f42b84 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -95,46 +95,46 @@ struct lowcore { __u64 int_clock; /* 0x0310 */ __u64 mcck_clock; /* 0x0318 */ __u64 clock_comparator; /* 0x0320 */ + __u64 boot_clock[2]; /* 0x0328 */ /* Current process. */ - __u64 current_task; /* 0x0328 */ - __u8 pad_0x318[0x320-0x318]; /* 0x0330 */ - __u64 kernel_stack; /* 0x0338 */ + __u64 current_task; /* 0x0338 */ + __u64 kernel_stack; /* 0x0340 */ /* Interrupt, panic and restart stack. */ - __u64 async_stack; /* 0x0340 */ - __u64 panic_stack; /* 0x0348 */ - __u64 restart_stack; /* 0x0350 */ + __u64 async_stack; /* 0x0348 */ + __u64 panic_stack; /* 0x0350 */ + __u64 restart_stack; /* 0x0358 */ /* Restart function and parameter. */ - __u64 restart_fn; /* 0x0358 */ - __u64 restart_data; /* 0x0360 */ - __u64 restart_source; /* 0x0368 */ + __u64 restart_fn; /* 0x0360 */ + __u64 restart_data; /* 0x0368 */ + __u64 restart_source; /* 0x0370 */ /* Address space pointer. */ - __u64 kernel_asce; /* 0x0370 */ - __u64 user_asce; /* 0x0378 */ + __u64 kernel_asce; /* 0x0378 */ + __u64 user_asce; /* 0x0380 */ /* * The lpp and current_pid fields form a * 64-bit value that is set as program * parameter with the LPP instruction. */ - __u32 lpp; /* 0x0380 */ - __u32 current_pid; /* 0x0384 */ + __u32 lpp; /* 0x0388 */ + __u32 current_pid; /* 0x038c */ /* SMP info area */ - __u32 cpu_nr; /* 0x0388 */ - __u32 softirq_pending; /* 0x038c */ - __u64 percpu_offset; /* 0x0390 */ - __u64 vdso_per_cpu_data; /* 0x0398 */ - __u64 machine_flags; /* 0x03a0 */ - __u32 preempt_count; /* 0x03a8 */ - __u8 pad_0x03ac[0x03b0-0x03ac]; /* 0x03ac */ - __u64 gmap; /* 0x03b0 */ - __u32 spinlock_lockval; /* 0x03b8 */ - __u32 fpu_flags; /* 0x03bc */ - __u8 pad_0x03c0[0x0400-0x03c0]; /* 0x03c0 */ + __u32 cpu_nr; /* 0x0390 */ + __u32 softirq_pending; /* 0x0394 */ + __u64 percpu_offset; /* 0x0398 */ + __u64 vdso_per_cpu_data; /* 0x03a0 */ + __u64 machine_flags; /* 0x03a8 */ + __u32 preempt_count; /* 0x03b0 */ + __u8 pad_0x03b4[0x03b8-0x03b4]; /* 0x03b4 */ + __u64 gmap; /* 0x03b8 */ + __u32 spinlock_lockval; /* 0x03c0 */ + __u32 fpu_flags; /* 0x03c4 */ + __u8 pad_0x03c8[0x0400-0x03c8]; /* 0x03c8 */ /* Per cpu primary space access list */ __u32 paste[16]; /* 0x0400 */ diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h deleted file mode 100644 index b79813d9cf68f8e328c64e17b19fe4f60d66f8dd..0000000000000000000000000000000000000000 --- a/arch/s390/include/asm/mman.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * S390 version - * - * Derived from "include/asm-i386/mman.h" - */ -#ifndef __S390_MMAN_H__ -#define __S390_MMAN_H__ - -#include - -#endif /* __S390_MMAN_H__ */ diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index bd6f303045185b7dbb2a4bc4a14d4c7729a84e4a..3f46a6577b8d70d891ee032777bbaaabb6ec8229 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h @@ -5,12 +5,11 @@ #include typedef struct { + spinlock_t lock; cpumask_t cpu_attach_mask; atomic_t flush_count; unsigned int flush_mm; - spinlock_t pgtable_lock; struct list_head pgtable_list; - spinlock_t gmap_lock; struct list_head gmap_list; unsigned long gmap_asce; unsigned long asce; @@ -27,10 +26,8 @@ typedef struct { } mm_context_t; #define INIT_MM_CONTEXT(name) \ - .context.pgtable_lock = \ - __SPIN_LOCK_UNLOCKED(name.context.pgtable_lock), \ + .context.lock = __SPIN_LOCK_UNLOCKED(name.context.lock), \ .context.pgtable_list = LIST_HEAD_INIT(name.context.pgtable_list), \ - .context.gmap_lock = __SPIN_LOCK_UNLOCKED(name.context.gmap_lock), \ .context.gmap_list = LIST_HEAD_INIT(name.context.gmap_list), static inline int tprot(unsigned long addr) diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 4541ac44b35f0e39b831b3eba2e5669d29dd9f89..3c9abedc323cbb488f46a7ae1d1bc40e4c7de9e1 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -12,13 +12,13 @@ #include #include #include +#include static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { - spin_lock_init(&mm->context.pgtable_lock); + spin_lock_init(&mm->context.lock); INIT_LIST_HEAD(&mm->context.pgtable_list); - spin_lock_init(&mm->context.gmap_lock); INIT_LIST_HEAD(&mm->context.gmap_list); cpumask_clear(&mm->context.cpu_attach_mask); atomic_set(&mm->context.flush_count, 0); @@ -33,7 +33,7 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.use_cmma = 0; #endif switch (mm->context.asce_limit) { - case 1UL << 42: + case _REGION2_SIZE: /* * forked 3-level task, fall through to set new asce with new * mm->pgd @@ -44,12 +44,17 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION3; break; - case 1UL << 53: + case -PAGE_SIZE: + /* forked 5-level task, set new asce with new_mm->pgd */ + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION1; + break; + case _REGION1_SIZE: /* forked 4-level task, set new asce with new mm->pgd */ mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION2; break; - case 1UL << 31: + case _REGION3_SIZE: /* forked 2-level compat task, set new asce with new mm->pgd */ mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; @@ -97,7 +102,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, if (prev == next) return; cpumask_set_cpu(cpu, &next->context.cpu_attach_mask); - cpumask_set_cpu(cpu, mm_cpumask(next)); /* Clear old ASCE by loading the kernel ASCE. */ __ctl_load(S390_lowcore.kernel_asce, 1, 1); __ctl_load(S390_lowcore.kernel_asce, 7, 7); @@ -115,9 +119,8 @@ static inline void finish_arch_post_lock_switch(void) preempt_disable(); while (atomic_read(&mm->context.flush_count)) cpu_relax(); - - if (mm->context.flush_mm) - __tlb_flush_mm(mm); + cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + __tlb_flush_mm_lazy(mm); preempt_enable(); } set_fs(current->thread.mm_segment); @@ -130,33 +133,8 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { switch_mm(prev, next, current); + cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); set_user_asce(next); } -static inline void arch_dup_mmap(struct mm_struct *oldmm, - struct mm_struct *mm) -{ -} - -static inline void arch_exit_mmap(struct mm_struct *mm) -{ -} - -static inline void arch_unmap(struct mm_struct *mm, - struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ -} - -static inline void arch_bprm_mm_init(struct mm_struct *mm, - struct vm_area_struct *vma) -{ -} - -static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, - bool write, bool execute, bool foreign) -{ - /* by default, allow everything */ - return true; -} #endif /* __S390_MMU_CONTEXT_H */ diff --git a/arch/s390/include/asm/nmi.h b/arch/s390/include/asm/nmi.h index 9d91cf3e427feb00652b6c9b2291090a550d54c9..c8e211b9a0020b1245e05236630dee472debe16a 100644 --- a/arch/s390/include/asm/nmi.h +++ b/arch/s390/include/asm/nmi.h @@ -72,7 +72,7 @@ union mci { u64 ar : 1; /* 33 access register validity */ u64 da : 1; /* 34 delayed access exception */ u64 : 1; /* 35 */ - u64 gs : 1; /* 36 guarded storage registers */ + u64 gs : 1; /* 36 guarded storage registers validity */ u64 : 5; /* 37-41 */ u64 pr : 1; /* 42 tod programmable register validity */ u64 fc : 1; /* 43 fp control register validity */ diff --git a/arch/s390/include/asm/page-states.h b/arch/s390/include/asm/page-states.h index 42267a2fe29e74763ae08b2f5d782c54d1ecc615..22b0f49e87c1a74ec726be3440e100e80efc645f 100644 --- a/arch/s390/include/asm/page-states.h +++ b/arch/s390/include/asm/page-states.h @@ -13,7 +13,8 @@ #define ESSA_SET_POT_VOLATILE 4 #define ESSA_SET_STABLE_RESIDENT 5 #define ESSA_SET_STABLE_IF_RESIDENT 6 +#define ESSA_SET_STABLE_NODAT 7 -#define ESSA_MAX ESSA_SET_STABLE_IF_RESIDENT +#define ESSA_MAX ESSA_SET_STABLE_NODAT #endif diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 624deaa44230c2bc55b63fe4d70757562dad8c3b..5d5c2b3500a4dd180d45857042354c19a396809f 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -10,10 +10,14 @@ #include #include +#define _PAGE_SHIFT 12 +#define _PAGE_SIZE (_AC(1, UL) << _PAGE_SHIFT) +#define _PAGE_MASK (~(_PAGE_SIZE - 1)) + /* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#define PAGE_SHIFT _PAGE_SHIFT +#define PAGE_SIZE _PAGE_SIZE +#define PAGE_MASK _PAGE_MASK #define PAGE_DEFAULT_ACC 0 #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) @@ -133,6 +137,9 @@ static inline int page_reset_referenced(unsigned long addr) struct page; void arch_free_page(struct page *page, int order); void arch_alloc_page(struct page *page, int order); +void arch_set_page_dat(struct page *page, int order); +void arch_set_page_nodat(struct page *page, int order); +int arch_test_page_nodat(struct page *page); void arch_set_page_states(int make_stable); static inline int devmem_is_allowed(unsigned long pfn) @@ -145,16 +152,26 @@ static inline int devmem_is_allowed(unsigned long pfn) #endif /* !__ASSEMBLY__ */ -#define __PAGE_OFFSET 0x0UL -#define PAGE_OFFSET 0x0UL -#define __pa(x) (unsigned long)(x) -#define __va(x) (void *)(unsigned long)(x) -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define __PAGE_OFFSET 0x0UL +#define PAGE_OFFSET 0x0UL + +#define __pa(x) ((unsigned long)(x)) +#define __va(x) ((void *)(unsigned long)(x)) + +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) #define page_to_virt(page) pfn_to_virt(page_to_pfn(page)) +#define phys_to_pfn(kaddr) ((kaddr) >> PAGE_SHIFT) +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) + +#define phys_to_page(kaddr) pfn_to_page(phys_to_pfn(kaddr)) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) + +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index f36b4b7260577d574e2f8f70a0ca52609eee1ee0..386df9adef0a409ada718390eb3705fba78fc5c3 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -122,6 +123,8 @@ struct zpci_dev { unsigned long iommu_pages; unsigned int next_bit; + struct iommu_device iommu_dev; /* IOMMU core handle */ + char res_name[16]; struct zpci_bar_struct bars[PCI_BAR_COUNT]; @@ -174,6 +177,10 @@ int clp_enable_fh(struct zpci_dev *, u8); int clp_disable_fh(struct zpci_dev *); int clp_get_state(u32 fid, enum zpci_state *state); +/* IOMMU Interface */ +int zpci_init_iommu(struct zpci_dev *zdev); +void zpci_destroy_iommu(struct zpci_dev *zdev); + #ifdef CONFIG_PCI /* Error handling and recovery */ void zpci_event_error(void *); diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index bb0ff1bb0c4a824e22e9919832e89fa2cb377977..a0d9167519b19b51b401880d8f5b504c588044c0 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -15,6 +15,8 @@ #include #include +#define CRST_ALLOC_ORDER 2 + unsigned long *crst_table_alloc(struct mm_struct *); void crst_table_free(struct mm_struct *, unsigned long *); @@ -42,16 +44,16 @@ static inline void clear_table(unsigned long *s, unsigned long val, size_t n) static inline void crst_table_init(unsigned long *crst, unsigned long entry) { - clear_table(crst, entry, sizeof(unsigned long)*2048); + clear_table(crst, entry, _CRST_TABLE_SIZE); } static inline unsigned long pgd_entry_type(struct mm_struct *mm) { - if (mm->context.asce_limit <= (1UL << 31)) + if (mm->context.asce_limit <= _REGION3_SIZE) return _SEGMENT_ENTRY_EMPTY; - if (mm->context.asce_limit <= (1UL << 42)) + if (mm->context.asce_limit <= _REGION2_SIZE) return _REGION3_ENTRY_EMPTY; - if (mm->context.asce_limit <= (1UL << 53)) + if (mm->context.asce_limit <= _REGION1_SIZE) return _REGION2_ENTRY_EMPTY; return _REGION1_ENTRY_EMPTY; } @@ -119,7 +121,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) if (!table) return NULL; - if (mm->context.asce_limit == (1UL << 31)) { + if (mm->context.asce_limit == _REGION3_SIZE) { /* Forking a compat process with 2 page table levels */ if (!pgtable_pmd_page_ctor(virt_to_page(table))) { crst_table_free(mm, table); @@ -131,7 +133,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { - if (mm->context.asce_limit == (1UL << 31)) + if (mm->context.asce_limit == _REGION3_SIZE) pgtable_pmd_page_dtor(virt_to_page(pgd)); crst_table_free(mm, (unsigned long *) pgd); } @@ -158,4 +160,8 @@ static inline void pmd_populate(struct mm_struct *mm, extern void rcu_table_freelist_finish(void); +void vmem_map_init(void); +void *vmem_crst_alloc(unsigned long val); +pte_t *vmem_pte_alloc(void); + #endif /* _S390_PGALLOC_H */ diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 57057fb1cc07eae47d4f841d5b83bfac909a6872..20e75a2ca93a283f6413ca6a8ee40ff280e3c74d 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -11,19 +11,6 @@ #ifndef _ASM_S390_PGTABLE_H #define _ASM_S390_PGTABLE_H -/* - * The Linux memory management assumes a three-level page table setup. - * For s390 64 bit we use up to four of the five levels the hardware - * provides (region first tables are not used). - * - * The "pgd_xxx()" functions are trivial for a folded two-level - * setup: the pgd is never bad, and a pmd always exists (as it's folded - * into the pgd entry) - * - * This file contains the functions and defines necessary to modify and use - * the S390 page table tree. - */ -#ifndef __ASSEMBLY__ #include #include #include @@ -34,9 +21,6 @@ extern pgd_t swapper_pg_dir[]; extern void paging_init(void); -extern void vmem_map_init(void); -pmd_t *vmem_pmd_alloc(void); -pte_t *vmem_pte_alloc(void); enum { PG_DIRECT_MAP_4K = 0, @@ -77,38 +61,6 @@ extern unsigned long zero_page_mask; #define __HAVE_COLOR_ZERO_PAGE /* TODO: s390 cannot support io_remap_pfn_range... */ -#endif /* !__ASSEMBLY__ */ - -/* - * PMD_SHIFT determines the size of the area a second-level page - * table can map - * PGDIR_SHIFT determines what a third-level page table entry can map - */ -#define PMD_SHIFT 20 -#define PUD_SHIFT 31 -#define P4D_SHIFT 42 -#define PGDIR_SHIFT 53 - -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) -#define PUD_SIZE (1UL << PUD_SHIFT) -#define PUD_MASK (~(PUD_SIZE-1)) -#define P4D_SIZE (1UL << P4D_SHIFT) -#define P4D_MASK (~(P4D_SIZE-1)) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -/* - * entries per page directory level: the S390 is two-level, so - * we don't really have any PMD directory physically. - * for S390 segment-table entries are combined to one PGD - * that leads to 1024 pte per pgd - */ -#define PTRS_PER_PTE 256 -#define PTRS_PER_PMD 2048 -#define PTRS_PER_PUD 2048 -#define PTRS_PER_P4D 2048 -#define PTRS_PER_PGD 2048 #define FIRST_USER_ADDRESS 0UL @@ -123,7 +75,6 @@ extern unsigned long zero_page_mask; #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) -#ifndef __ASSEMBLY__ /* * The vmalloc and module area will always be on the topmost area of the * kernel mapping. We reserve 128GB (64bit) for vmalloc and modules. @@ -269,7 +220,7 @@ static inline int is_module_addr(void *addr) */ /* Bits in the segment/region table address-space-control-element */ -#define _ASCE_ORIGIN ~0xfffUL/* segment table origin */ +#define _ASCE_ORIGIN ~0xfffUL/* region/segment table origin */ #define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ #define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ #define _ASCE_SPACE_SWITCH 0x40 /* space switch event */ @@ -320,9 +271,9 @@ static inline int is_module_addr(void *addr) #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL #define _SEGMENT_ENTRY_BITS_LARGE 0xfffffffffff0ff33UL #define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ -#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ -#define _SEGMENT_ENTRY_PROTECT 0x200 /* page protection bit */ -#define _SEGMENT_ENTRY_NOEXEC 0x100 /* region no-execute bit */ +#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* page table origin */ +#define _SEGMENT_ENTRY_PROTECT 0x200 /* segment protection bit */ +#define _SEGMENT_ENTRY_NOEXEC 0x100 /* segment no-execute bit */ #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ #define _SEGMENT_ENTRY (0) @@ -340,6 +291,54 @@ static inline int is_module_addr(void *addr) #define _SEGMENT_ENTRY_SOFT_DIRTY 0x0000 /* SW segment soft dirty bit */ #endif +#define _CRST_ENTRIES 2048 /* number of region/segment table entries */ +#define _PAGE_ENTRIES 256 /* number of page table entries */ + +#define _CRST_TABLE_SIZE (_CRST_ENTRIES * 8) +#define _PAGE_TABLE_SIZE (_PAGE_ENTRIES * 8) + +#define _REGION1_SHIFT 53 +#define _REGION2_SHIFT 42 +#define _REGION3_SHIFT 31 +#define _SEGMENT_SHIFT 20 + +#define _REGION1_INDEX (0x7ffUL << _REGION1_SHIFT) +#define _REGION2_INDEX (0x7ffUL << _REGION2_SHIFT) +#define _REGION3_INDEX (0x7ffUL << _REGION3_SHIFT) +#define _SEGMENT_INDEX (0x7ffUL << _SEGMENT_SHIFT) +#define _PAGE_INDEX (0xffUL << _PAGE_SHIFT) + +#define _REGION1_SIZE (1UL << _REGION1_SHIFT) +#define _REGION2_SIZE (1UL << _REGION2_SHIFT) +#define _REGION3_SIZE (1UL << _REGION3_SHIFT) +#define _SEGMENT_SIZE (1UL << _SEGMENT_SHIFT) + +#define _REGION1_MASK (~(_REGION1_SIZE - 1)) +#define _REGION2_MASK (~(_REGION2_SIZE - 1)) +#define _REGION3_MASK (~(_REGION3_SIZE - 1)) +#define _SEGMENT_MASK (~(_SEGMENT_SIZE - 1)) + +#define PMD_SHIFT _SEGMENT_SHIFT +#define PUD_SHIFT _REGION3_SHIFT +#define P4D_SHIFT _REGION2_SHIFT +#define PGDIR_SHIFT _REGION1_SHIFT + +#define PMD_SIZE _SEGMENT_SIZE +#define PUD_SIZE _REGION3_SIZE +#define P4D_SIZE _REGION2_SIZE +#define PGDIR_SIZE _REGION1_SIZE + +#define PMD_MASK _SEGMENT_MASK +#define PUD_MASK _REGION3_MASK +#define P4D_MASK _REGION2_MASK +#define PGDIR_MASK _REGION1_MASK + +#define PTRS_PER_PTE _PAGE_ENTRIES +#define PTRS_PER_PMD _CRST_ENTRIES +#define PTRS_PER_PUD _CRST_ENTRIES +#define PTRS_PER_P4D _CRST_ENTRIES +#define PTRS_PER_PGD _CRST_ENTRIES + /* * Segment table and region3 table entry encoding * (R = read-only, I = invalid, y = young bit): @@ -376,6 +375,7 @@ static inline int is_module_addr(void *addr) /* Guest Page State used for virtualization */ #define _PGSTE_GPS_ZERO 0x0000000080000000UL +#define _PGSTE_GPS_NODAT 0x0000000040000000UL #define _PGSTE_GPS_USAGE_MASK 0x0000000003000000UL #define _PGSTE_GPS_USAGE_STABLE 0x0000000000000000UL #define _PGSTE_GPS_USAGE_UNUSED 0x0000000001000000UL @@ -505,7 +505,7 @@ static inline int mm_alloc_pgste(struct mm_struct *mm) * In the case that a guest uses storage keys * faults should no longer be backed by zero pages */ -#define mm_forbids_zeropage mm_use_skey +#define mm_forbids_zeropage mm_has_pgste static inline int mm_use_skey(struct mm_struct *mm) { #ifdef CONFIG_PGSTE @@ -952,15 +952,30 @@ static inline pte_t pte_mkhuge(pte_t pte) #define IPTE_GLOBAL 0 #define IPTE_LOCAL 1 -static inline void __ptep_ipte(unsigned long address, pte_t *ptep, int local) +#define IPTE_NODAT 0x400 +#define IPTE_GUEST_ASCE 0x800 + +static inline void __ptep_ipte(unsigned long address, pte_t *ptep, + unsigned long opt, unsigned long asce, + int local) { unsigned long pto = (unsigned long) ptep; - /* Invalidation + TLB flush for the pte */ + if (__builtin_constant_p(opt) && opt == 0) { + /* Invalidation + TLB flush for the pte */ + asm volatile( + " .insn rrf,0xb2210000,%[r1],%[r2],0,%[m4]" + : "+m" (*ptep) : [r1] "a" (pto), [r2] "a" (address), + [m4] "i" (local)); + return; + } + + /* Invalidate ptes with options + TLB flush of the ptes */ + opt = opt | (asce & _ASCE_ORIGIN); asm volatile( - " .insn rrf,0xb2210000,%[r1],%[r2],0,%[m4]" - : "+m" (*ptep) : [r1] "a" (pto), [r2] "a" (address), - [m4] "i" (local)); + " .insn rrf,0xb2210000,%[r1],%[r2],%[r3],%[m4]" + : [r2] "+a" (address), [r3] "+a" (opt) + : [r1] "a" (pto), [m4] "i" (local) : "memory"); } static inline void __ptep_ipte_range(unsigned long address, int nr, @@ -1341,31 +1356,61 @@ static inline void __pmdp_csp(pmd_t *pmdp) #define IDTE_GLOBAL 0 #define IDTE_LOCAL 1 -static inline void __pmdp_idte(unsigned long address, pmd_t *pmdp, int local) +#define IDTE_PTOA 0x0800 +#define IDTE_NODAT 0x1000 +#define IDTE_GUEST_ASCE 0x2000 + +static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp, + unsigned long opt, unsigned long asce, + int local) { unsigned long sto; - sto = (unsigned long) pmdp - pmd_index(address) * sizeof(pmd_t); - asm volatile( - " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" - : "+m" (*pmdp) - : [r1] "a" (sto), [r2] "a" ((address & HPAGE_MASK)), - [m4] "i" (local) - : "cc" ); + sto = (unsigned long) pmdp - pmd_index(addr) * sizeof(pmd_t); + if (__builtin_constant_p(opt) && opt == 0) { + /* flush without guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" + : "+m" (*pmdp) + : [r1] "a" (sto), [r2] "a" ((addr & HPAGE_MASK)), + [m4] "i" (local) + : "cc" ); + } else { + /* flush with guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],%[r3],%[m4]" + : "+m" (*pmdp) + : [r1] "a" (sto), [r2] "a" ((addr & HPAGE_MASK) | opt), + [r3] "a" (asce), [m4] "i" (local) + : "cc" ); + } } -static inline void __pudp_idte(unsigned long address, pud_t *pudp, int local) +static inline void __pudp_idte(unsigned long addr, pud_t *pudp, + unsigned long opt, unsigned long asce, + int local) { unsigned long r3o; - r3o = (unsigned long) pudp - pud_index(address) * sizeof(pud_t); + r3o = (unsigned long) pudp - pud_index(addr) * sizeof(pud_t); r3o |= _ASCE_TYPE_REGION3; - asm volatile( - " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" - : "+m" (*pudp) - : [r1] "a" (r3o), [r2] "a" ((address & PUD_MASK)), - [m4] "i" (local) - : "cc"); + if (__builtin_constant_p(opt) && opt == 0) { + /* flush without guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" + : "+m" (*pudp) + : [r1] "a" (r3o), [r2] "a" ((addr & PUD_MASK)), + [m4] "i" (local) + : "cc"); + } else { + /* flush with guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],%[r3],%[m4]" + : "+m" (*pudp) + : [r1] "a" (r3o), [r2] "a" ((addr & PUD_MASK) | opt), + [r3] "a" (asce), [m4] "i" (local) + : "cc" ); + } } pmd_t pmdp_xchg_direct(struct mm_struct *, unsigned long, pmd_t *, pmd_t); @@ -1462,7 +1507,9 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, static inline void pmdp_invalidate(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmdp) { - pmdp_xchg_direct(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY)); + pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); + + pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); } #define __HAVE_ARCH_PMDP_SET_WRPROTECT @@ -1548,8 +1595,6 @@ static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#endif /* !__ASSEMBLY__ */ - #define kern_addr_valid(addr) (1) extern int vmem_add_mapping(unsigned long start, unsigned long size); diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 998b61cd0e5694b37160ccddb4f9cad6f15f18ae..eaee69e7c42a05c5c835a736e85532cc74965c73 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -80,7 +80,7 @@ struct qdr { u32 qkey : 4; u32 : 28; struct qdesfmt0 qdf0[126]; -} __attribute__ ((packed, aligned(4096))); +} __packed __aligned(PAGE_SIZE); #define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 #define QIB_RFLAGS_ENABLE_QEBSM 0x80 diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index cd78155b18296aec0e370b3f2a2315adf5c74a11..490e035b371690f5817200504990f57520f65d6b 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -29,8 +29,10 @@ #define MACHINE_FLAG_TE _BITUL(11) #define MACHINE_FLAG_TLB_LC _BITUL(12) #define MACHINE_FLAG_VX _BITUL(13) -#define MACHINE_FLAG_NX _BITUL(14) -#define MACHINE_FLAG_GS _BITUL(15) +#define MACHINE_FLAG_TLB_GUEST _BITUL(14) +#define MACHINE_FLAG_NX _BITUL(15) +#define MACHINE_FLAG_GS _BITUL(16) +#define MACHINE_FLAG_SCC _BITUL(17) #define LPP_MAGIC _BITUL(31) #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) @@ -68,8 +70,10 @@ extern void detect_memory_memblock(void); #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) #define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX) +#define MACHINE_HAS_TLB_GUEST (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_GUEST) #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) +#define MACHINE_HAS_SCC (S390_lowcore.machine_flags & MACHINE_FLAG_SCC) /* * Console mode. Override with conmode= @@ -104,9 +108,16 @@ extern void pfault_fini(void); #define pfault_fini() do { } while (0) #endif /* CONFIG_PFAULT */ +#ifdef CONFIG_VMCP +void vmcp_cma_reserve(void); +#else +static inline void vmcp_cma_reserve(void) { } +#endif + void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault); -extern void cmma_init(void); +void cmma_init(void); +void cmma_init_nodat(void); extern void (*_machine_restart)(char *command); extern void (*_machine_halt)(void); diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index f7838ecd83c6691d9ffa4e4d50af32292b4b5a3e..8182b521c42f010e94e6c06e9a49e6f32bf307da 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -92,17 +92,11 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp) { typecheck(int, lp->lock); asm volatile( - "st %1,%0\n" - : "+Q" (lp->lock) - : "d" (0) - : "cc", "memory"); -} - -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - while (arch_spin_is_locked(lock)) - arch_spin_relax(lock); - smp_acquire__after_ctrl_dep(); +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + " .long 0xb2fa0070\n" /* NIAI 7 */ +#endif + " st %1,%0\n" + : "=Q" (lp->lock) : "d" (0) : "cc", "memory"); } /* diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index 118535123f346d9b32bfb140d45884870a99fd2f..93f2eb3f277c6550d54982403a8a04419ea8543f 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -15,6 +15,8 @@ /* The value of the TOD clock for 1.1.1970. */ #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL +extern u64 clock_comparator_max; + /* Inline functions for clock register access. */ static inline int set_tod_clock(__u64 time) { @@ -126,7 +128,7 @@ static inline unsigned long long local_tick_disable(void) unsigned long long old; old = S390_lowcore.clock_comparator; - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = clock_comparator_max; set_clock_comparator(S390_lowcore.clock_comparator); return old; } @@ -174,24 +176,24 @@ static inline cycles_t get_cycles(void) return (cycles_t) get_tod_clock() >> 2; } -int get_phys_clock(unsigned long long *clock); +int get_phys_clock(unsigned long *clock); void init_cpu_timer(void); unsigned long long monotonic_clock(void); -extern u64 sched_clock_base_cc; +extern unsigned char tod_clock_base[16] __aligned(8); /** * get_clock_monotonic - returns current time in clock rate units * * The caller must ensure that preemption is disabled. - * The clock and sched_clock_base get changed via stop_machine. + * The clock and tod_clock_base get changed via stop_machine. * Therefore preemption must be disabled when calling this * function, otherwise the returned value is not guaranteed to * be monotonic. */ static inline unsigned long long get_tod_clock_monotonic(void) { - return get_tod_clock() - sched_clock_base_cc; + return get_tod_clock() - *(unsigned long long *) &tod_clock_base[1]; } /** @@ -218,4 +220,32 @@ static inline unsigned long long tod_to_ns(unsigned long long todval) return ((todval >> 9) * 125) + (((todval & 0x1ff) * 125) >> 9); } +/** + * tod_after - compare two 64 bit TOD values + * @a: first 64 bit TOD timestamp + * @b: second 64 bit TOD timestamp + * + * Returns: true if a is later than b + */ +static inline int tod_after(unsigned long long a, unsigned long long b) +{ + if (MACHINE_HAS_SCC) + return (long long) a > (long long) b; + return a > b; +} + +/** + * tod_after_eq - compare two 64 bit TOD values + * @a: first 64 bit TOD timestamp + * @b: second 64 bit TOD timestamp + * + * Returns: true if a is later than b + */ +static inline int tod_after_eq(unsigned long long a, unsigned long long b) +{ + if (MACHINE_HAS_SCC) + return (long long) a >= (long long) b; + return a >= b; +} + #endif diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 7317b3108a88859a91523c45f1e52c08cb22fdc4..3a14b864b2e30af5b1f1867ae59b069926a07d9d 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -47,10 +47,9 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); -static inline void tlb_gather_mmu(struct mmu_gather *tlb, - struct mm_struct *mm, - unsigned long start, - unsigned long end) +static inline void +arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) { tlb->mm = mm; tlb->start = start; @@ -76,9 +75,15 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb) tlb_flush_mmu_free(tlb); } -static inline void tlb_finish_mmu(struct mmu_gather *tlb, - unsigned long start, unsigned long end) +static inline void +arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force) { + if (force) { + tlb->start = start; + tlb->end = end; + } + tlb_flush_mmu(tlb); } @@ -130,7 +135,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, unsigned long address) { - if (tlb->mm->context.asce_limit <= (1UL << 31)) + if (tlb->mm->context.asce_limit <= _REGION3_SIZE) return; pgtable_pmd_page_dtor(virt_to_page(pmd)); tlb_remove_table(tlb, pmd); @@ -146,7 +151,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, unsigned long address) { - if (tlb->mm->context.asce_limit <= (1UL << 53)) + if (tlb->mm->context.asce_limit <= _REGION1_SIZE) return; tlb_remove_table(tlb, p4d); } @@ -161,7 +166,7 @@ static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, unsigned long address) { - if (tlb->mm->context.asce_limit <= (1UL << 42)) + if (tlb->mm->context.asce_limit <= _REGION2_SIZE) return; tlb_remove_table(tlb, pud); } diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 39846100682a3e9c11ab9ffc4223d4734844cd1d..b08d5bc2666e65f42e2444158133b712ec8dc1ff 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -20,10 +20,15 @@ static inline void __tlb_flush_local(void) */ static inline void __tlb_flush_idte(unsigned long asce) { + unsigned long opt; + + opt = IDTE_PTOA; + if (MACHINE_HAS_TLB_GUEST) + opt |= IDTE_GUEST_ASCE; /* Global TLB flush for the mm */ asm volatile( " .insn rrf,0xb98e0000,0,%0,%1,0" - : : "a" (2048), "a" (asce) : "cc"); + : : "a" (opt), "a" (asce) : "cc"); } #ifdef CONFIG_SMP @@ -43,23 +48,6 @@ static inline void __tlb_flush_global(void) * Flush TLB entries for a specific mm on all CPUs (in case gmap is used * this implicates multiple ASCEs!). */ -static inline void __tlb_flush_full(struct mm_struct *mm) -{ - preempt_disable(); - atomic_inc(&mm->context.flush_count); - if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { - /* Local TLB flush */ - __tlb_flush_local(); - } else { - /* Global TLB flush */ - __tlb_flush_global(); - /* Reset TLB flush mask */ - cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); - } - atomic_dec(&mm->context.flush_count); - preempt_enable(); -} - static inline void __tlb_flush_mm(struct mm_struct *mm) { unsigned long gmap_asce; @@ -71,16 +59,18 @@ static inline void __tlb_flush_mm(struct mm_struct *mm) */ preempt_disable(); atomic_inc(&mm->context.flush_count); + /* Reset TLB flush mask */ + cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); + barrier(); gmap_asce = READ_ONCE(mm->context.gmap_asce); if (MACHINE_HAS_IDTE && gmap_asce != -1UL) { if (gmap_asce) __tlb_flush_idte(gmap_asce); __tlb_flush_idte(mm->context.asce); } else { - __tlb_flush_full(mm); + /* Global TLB flush */ + __tlb_flush_global(); } - /* Reset TLB flush mask */ - cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); atomic_dec(&mm->context.flush_count); preempt_enable(); } @@ -94,7 +84,6 @@ static inline void __tlb_flush_kernel(void) } #else #define __tlb_flush_global() __tlb_flush_local() -#define __tlb_flush_full(mm) __tlb_flush_local() /* * Flush TLB entries for a specific ASCE on all CPUs. @@ -112,10 +101,12 @@ static inline void __tlb_flush_kernel(void) static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) { + spin_lock(&mm->context.lock); if (mm->context.flush_mm) { - __tlb_flush_mm(mm); mm->context.flush_mm = 0; + __tlb_flush_mm(mm); } + spin_unlock(&mm->context.lock); } /* diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index fa1bfce10370564b24b640782360a95e3ea2666a..5222da162b69502942bdad09a56890e4e83d4bc4 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -77,12 +77,6 @@ static inline const struct cpumask *cpumask_of_node(int node) return &node_to_cpumask_map[node]; } -/* - * Returns the number of the node containing node 'node'. This - * architecture is flat, so it is a pretty simple function! - */ -#define parent_node(node) (node) - #define pcibus_to_node(bus) __pcibus_to_node(bus) #define node_distance(a, b) __node_distance(a, b) diff --git a/arch/s390/include/asm/types.h b/arch/s390/include/asm/types.h deleted file mode 100644 index 6740f4f9781f9c613ff3ff9473193a121f41e9ed..0000000000000000000000000000000000000000 --- a/arch/s390/include/asm/types.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * S390 version - * - * Derived from "include/asm-i386/types.h" - */ -#ifndef _S390_TYPES_H -#define _S390_TYPES_H - -#include - -#endif /* _S390_TYPES_H */ diff --git a/arch/s390/include/asm/unaligned.h b/arch/s390/include/asm/unaligned.h deleted file mode 100644 index da9627afe5d8578ea951037f7ddbba33fb8e6b08..0000000000000000000000000000000000000000 --- a/arch/s390/include/asm/unaligned.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_S390_UNALIGNED_H -#define _ASM_S390_UNALIGNED_H - -/* - * The S390 can do unaligned accesses itself. - */ -#include -#include - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#endif /* _ASM_S390_UNALIGNED_H */ diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild index ca62066895e00eeff9e569790e875c02a7e936f1..098f28778a13408e220e7d3b0a8a657e7e508c69 100644 --- a/arch/s390/include/uapi/asm/Kbuild +++ b/arch/s390/include/uapi/asm/Kbuild @@ -9,4 +9,5 @@ generic-y += param.h generic-y += poll.h generic-y += resource.h generic-y += sockios.h +generic-y += swab.h generic-y += termbits.h diff --git a/arch/s390/include/uapi/asm/dasd.h b/arch/s390/include/uapi/asm/dasd.h index 1340311dab77db4cb0766d3ffaab5370dd883193..ab5797cdc1b79ca3c9c3903296446d81482caa52 100644 --- a/arch/s390/include/uapi/asm/dasd.h +++ b/arch/s390/include/uapi/asm/dasd.h @@ -72,7 +72,10 @@ typedef struct dasd_information2_t { * 0x02: use diag discipline (diag) * 0x04: set the device initially online (internal use only) * 0x08: enable ERP related logging - * 0x20: give access to raw eckd data + * 0x10: allow I/O to fail on lost paths + * 0x20: allow I/O to fail when a lock was stolen + * 0x40: give access to raw eckd data + * 0x80: enable discard support */ #define DASD_FEATURE_DEFAULT 0x00 #define DASD_FEATURE_READONLY 0x01 @@ -82,6 +85,7 @@ typedef struct dasd_information2_t { #define DASD_FEATURE_FAILFAST 0x10 #define DASD_FEATURE_FAILONSLCK 0x20 #define DASD_FEATURE_USERAW 0x40 +#define DASD_FEATURE_DISCARD 0x80 #define DASD_PARTN_BITS 2 diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 69d09c39bbcd00858121ebf9f6bb1f7a57ff20e1..cd7359e23d869465d1cb70b637c64c85283e37ac 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h @@ -88,6 +88,12 @@ struct kvm_s390_io_adapter_req { /* kvm attributes for KVM_S390_VM_TOD */ #define KVM_S390_VM_TOD_LOW 0 #define KVM_S390_VM_TOD_HIGH 1 +#define KVM_S390_VM_TOD_EXT 2 + +struct kvm_s390_vm_tod_clock { + __u8 epoch_idx; + __u64 tod; +}; /* kvm attributes for KVM_S390_VM_CPU_MODEL */ /* processor related attributes are r/w */ diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 52a63f4175cb8de14d9da9fb1c086f23e02e5aaf..a56916c835654b4eae4781758d13865994fcbaa4 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -108,4 +108,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/s390/include/uapi/asm/swab.h b/arch/s390/include/uapi/asm/swab.h deleted file mode 100644 index da3bfe5cc161557f770d49dc0a1a67d10676b04a..0000000000000000000000000000000000000000 --- a/arch/s390/include/uapi/asm/swab.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _S390_SWAB_H -#define _S390_SWAB_H - -/* - * S390 version - * Copyright IBM Corp. 1999 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) - */ - -#include - -#ifndef __s390x__ -# define __SWAB_64_THRU_32__ -#endif - -#ifdef __s390x__ -static inline __u64 __arch_swab64p(const __u64 *x) -{ - __u64 result; - - asm volatile("lrvg %0,%1" : "=d" (result) : "m" (*x)); - return result; -} -#define __arch_swab64p __arch_swab64p - -static inline __u64 __arch_swab64(__u64 x) -{ - __u64 result; - - asm volatile("lrvgr %0,%1" : "=d" (result) : "d" (x)); - return result; -} -#define __arch_swab64 __arch_swab64 - -static inline void __arch_swab64s(__u64 *x) -{ - *x = __arch_swab64p(x); -} -#define __arch_swab64s __arch_swab64s -#endif /* __s390x__ */ - -static inline __u32 __arch_swab32p(const __u32 *x) -{ - __u32 result; - - asm volatile( -#ifndef __s390x__ - " icm %0,8,%O1+3(%R1)\n" - " icm %0,4,%O1+2(%R1)\n" - " icm %0,2,%O1+1(%R1)\n" - " ic %0,%1" - : "=&d" (result) : "Q" (*x) : "cc"); -#else /* __s390x__ */ - " lrv %0,%1" - : "=d" (result) : "m" (*x)); -#endif /* __s390x__ */ - return result; -} -#define __arch_swab32p __arch_swab32p - -#ifdef __s390x__ -static inline __u32 __arch_swab32(__u32 x) -{ - __u32 result; - - asm volatile("lrvr %0,%1" : "=d" (result) : "d" (x)); - return result; -} -#define __arch_swab32 __arch_swab32 -#endif /* __s390x__ */ - -static inline __u16 __arch_swab16p(const __u16 *x) -{ - __u16 result; - - asm volatile( -#ifndef __s390x__ - " icm %0,2,%O1+1(%R1)\n" - " ic %0,%1\n" - : "=&d" (result) : "Q" (*x) : "cc"); -#else /* __s390x__ */ - " lrvh %0,%1" - : "=d" (result) : "m" (*x)); -#endif /* __s390x__ */ - return result; -} -#define __arch_swab16p __arch_swab16p - -#endif /* _S390_SWAB_H */ diff --git a/drivers/s390/char/vmcp.h b/arch/s390/include/uapi/asm/vmcp.h similarity index 56% rename from drivers/s390/char/vmcp.h rename to arch/s390/include/uapi/asm/vmcp.h index 1e29b04183820cda1c576764478a5b42ff4dd1d6..4caf71714a552332a169cb6799288442984ca088 100644 --- a/drivers/s390/char/vmcp.h +++ b/arch/s390/include/uapi/asm/vmcp.h @@ -12,19 +12,13 @@ * The idea of this driver is based on cpint from Neale Ferguson */ +#ifndef _UAPI_ASM_VMCP_H +#define _UAPI_ASM_VMCP_H + #include -#include -#define VMCP_GETCODE _IOR(0x10, 1, int) -#define VMCP_SETBUF _IOW(0x10, 2, int) -#define VMCP_GETSIZE _IOR(0x10, 3, int) +#define VMCP_GETCODE _IOR(0x10, 1, int) +#define VMCP_SETBUF _IOW(0x10, 2, int) +#define VMCP_GETSIZE _IOR(0x10, 3, int) -struct vmcp_session { - unsigned int bufsize; - char *response; - int resp_size; - int resp_code; - /* As we use copy_from/to_user, which might * - * sleep and cannot use a spinlock */ - struct mutex mutex; -}; +#endif /* _UAPI_ASM_VMCP_H */ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index b65c414b6c0e030cecb4bdb8fb074fa935c769df..3d42f91c95fd7ded7daa1654ab200486e902ce13 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -158,6 +158,7 @@ int main(void) OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock); OFFSET(__LC_INT_CLOCK, lowcore, int_clock); OFFSET(__LC_MCCK_CLOCK, lowcore, mcck_clock); + OFFSET(__LC_BOOT_CLOCK, lowcore, boot_clock); OFFSET(__LC_CURRENT, lowcore, current_task); OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack); OFFSET(__LC_ASYNC_STACK, lowcore, async_stack); diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index c620049c61f2dfcd0e8824e28f3c329c077f8644..f549c4657376a4cec8009ada0a5d6b366d1d02f2 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -75,35 +75,34 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_RT: err |= __put_user(from->si_int, &to->si_int); /* fallthrough */ - case __SI_KILL >> 16: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user((unsigned long) from->si_addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); @@ -127,32 +126,31 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) if (to->si_code < 0) err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (to->si_code >> 16) { - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + switch (siginfo_layout(to->si_signo, to->si_code)) { + case SIL_RT: err |= __get_user(to->si_int, &from->si_int); /* fallthrough */ - case __SI_KILL >> 16: + case SIL_KILL: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); err |= __get_user(to->si_utime, &from->si_utime); err |= __get_user(to->si_stime, &from->si_stime); err |= __get_user(to->si_status, &from->si_status); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __get_user(tmp, &from->si_addr); to->si_addr = (void __force __user *) (u64) (tmp & PSW32_ADDR_INSN); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_fd, &from->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __get_user(to->si_tid, &from->si_tid); err |= __get_user(to->si_overrun, &from->si_overrun); err |= __get_user(to->si_int, &from->si_int); diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 9f0e4a2785f7fb74d7863da83ba89a0a3458b539..63bc6603e0ed835f8b2d3adf628aaa599557dbba 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -28,9 +29,7 @@ static int diag8_noresponse(int cmdlen) register unsigned long reg3 asm ("3") = cmdlen; asm volatile( - " sam31\n" " diag %1,%0,0x8\n" - " sam64\n" : "+d" (reg3) : "d" (reg2) : "cc"); return reg3; } @@ -43,9 +42,7 @@ static int diag8_response(int cmdlen, char *response, int *rlen) register unsigned long reg5 asm ("5") = *rlen; asm volatile( - " sam31\n" " diag %2,%0,0x8\n" - " sam64\n" " brc 8,1f\n" " agr %1,%4\n" "1:\n" @@ -57,7 +54,6 @@ static int diag8_response(int cmdlen, char *response, int *rlen) /* * __cpcmd has some restrictions over cpcmd - * - the response buffer must reside below 2GB (if any) * - __cpcmd is unlocked and therefore not SMP-safe */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) @@ -88,13 +84,12 @@ EXPORT_SYMBOL(__cpcmd); int cpcmd(const char *cmd, char *response, int rlen, int *response_code) { + unsigned long flags; char *lowbuf; int len; - unsigned long flags; - if ((virt_to_phys(response) != (unsigned long) response) || - (((unsigned long)response + rlen) >> 31)) { - lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); + if (is_vmalloc_or_module_addr(response)) { + lowbuf = kmalloc(rlen, GFP_KERNEL); if (!lowbuf) { pr_warn("The cpcmd kernel function failed to allocate a response buffer\n"); return -ENOMEM; diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 86b3e74f569eb7823ba6c4b0c4ec7baeb456e2f1..1d9e83c401fcf32f7ba16e5298641bfb334226ac 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -866,7 +866,8 @@ static inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, int exception) { - active->id.stck = get_tod_clock_fast() - sched_clock_base_cc; + active->id.stck = get_tod_clock_fast() - + *(unsigned long long *) &tod_clock_base[1]; active->id.fields.cpuid = smp_processor_id(); active->caller = __builtin_return_address(0); active->id.fields.exception = exception; @@ -1455,15 +1456,15 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, int area, debug_entry_t * entry, char *out_buf) { - unsigned long sec, usec; + unsigned long base, sec, usec; char *except_str; unsigned long caller; int rc = 0; unsigned int level; level = entry->id.fields.level; - sec = (entry->id.stck >> 12) + (sched_clock_base_cc >> 12); - sec = sec - (TOD_UNIX_EPOCH >> 12); + base = (*(unsigned long *) &tod_clock_base[0]) >> 4; + sec = (entry->id.stck >> 12) + base - (TOD_UNIX_EPOCH >> 12); usec = do_div(sec, USEC_PER_SEC); if (entry->id.fields.exception) diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index dab78babfab6dd39c9517d4c73aef0de52c09dd3..2aa545dca4d53c1c5b2bb7c6bdc18db10fd37930 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -76,7 +76,7 @@ void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task, frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); #ifdef CONFIG_CHECK_STACK sp = __dump_trace(func, data, sp, - S390_lowcore.panic_stack + frame_size - 4096, + S390_lowcore.panic_stack + frame_size - PAGE_SIZE, S390_lowcore.panic_stack + frame_size); #endif sp = __dump_trace(func, data, sp, diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 5d20182ee8aed5b9e2b07f76a69456d7259a3ed2..60181caf8e8ad332029212e82b07c561cb44395a 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -53,8 +53,9 @@ static void __init reset_tod_clock(void) if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) disabled_wait(0); - sched_clock_base_cc = TOD_UNIX_EPOCH; - S390_lowcore.last_update_clock = sched_clock_base_cc; + memset(tod_clock_base, 0, 16); + *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; + S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; } #ifdef CONFIG_SHARED_KERNEL @@ -165,8 +166,8 @@ static noinline __init void create_kernel_nss(void) } /* re-initialize cputime accounting. */ - sched_clock_base_cc = get_tod_clock(); - S390_lowcore.last_update_clock = sched_clock_base_cc; + get_tod_clock_ext(tod_clock_base); + S390_lowcore.last_update_clock = *(__u64 *) &tod_clock_base[1]; S390_lowcore.last_update_timer = 0x7fffffffffffffffULL; S390_lowcore.user_timer = 0; S390_lowcore.system_timer = 0; @@ -387,6 +388,12 @@ static __init void detect_machine_facilities(void) } if (test_facility(133)) S390_lowcore.machine_flags |= MACHINE_FLAG_GS; + if (test_facility(139) && (tod_clock_base[1] & 0x80)) { + /* Enabled signed clock comparator comparisons */ + S390_lowcore.machine_flags |= MACHINE_FLAG_SCC; + clock_comparator_max = -1ULL >> 1; + __ctl_set_bit(0, 53); + } } static inline void save_vector_registers(void) @@ -397,23 +404,11 @@ static inline void save_vector_registers(void) #endif } -static int __init topology_setup(char *str) -{ - bool enabled; - int rc; - - rc = kstrtobool(str, &enabled); - if (!rc && !enabled) - S390_lowcore.machine_flags &= ~MACHINE_FLAG_TOPOLOGY; - return rc; -} -early_param("topology", topology_setup); - static int __init disable_vector_extension(char *str) { S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; __ctl_clear_bit(0, 17); - return 1; + return 0; } early_param("novx", disable_vector_extension); diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index eff5b31671d42ce8040b9d285fe99585a7f8d6f4..8ed753c72d9bec259b0f6117b2674fc10dcc730f 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -302,7 +302,8 @@ ENTRY(startup_kdump) xc 0xe00(256),0xe00 xc 0xf00(256),0xf00 lctlg %c0,%c15,0x200(%r0) # initialize control registers - stck __LC_LAST_UPDATE_CLOCK + stcke __LC_BOOT_CLOCK + mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1 spt 6f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) l %r15,.Lstack-.LPG0(%r13) diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 31c91f24e5624389b34017c45fd44dad3b11114f..0d8f2a858ced7d87d8e8130a07728a6245cded55 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -21,8 +21,8 @@ ENTRY(startup_continue) xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid mvi __LC_LPP,0x80 # and set LPP_MAGIC .insn s,0xb2800000,__LC_LPP # load program parameter -0: larl %r1,sched_clock_base_cc - mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK +0: larl %r1,tod_clock_base + mvc 0(16,%r1),__LC_BOOT_CLOCK larl %r13,.LPG1 # get base lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 6dca93b29beda49b76c2dd4bae6939ed60b8510d..a2fdff0e730bdbc25994bdad77aa5b12e052dd17 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -105,7 +105,8 @@ void do_IRQ(struct pt_regs *regs, int irq) old_regs = set_irq_regs(regs); irq_enter(); - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) + if (tod_after_eq(S390_lowcore.int_clock, + S390_lowcore.clock_comparator)) /* Serve timer interrupts first. */ clock_comparator_work(); generic_handle_irq(irq); diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index c1bf75ffb8756549b1c6a5c97908ff49dd2e79aa..7e1e40323b78e1bb7a3910e1191dfbe40027b748 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -823,9 +823,12 @@ static int cpumsf_pmu_event_init(struct perf_event *event) } /* Check online status of the CPU to which the event is pinned */ - if ((unsigned int)event->cpu >= nr_cpumask_bits || - (event->cpu >= 0 && !cpu_online(event->cpu))) - return -ENODEV; + if (event->cpu >= 0) { + if ((unsigned int)event->cpu >= nr_cpumask_bits) + return -ENODEV; + if (!cpu_online(event->cpu)) + return -ENODEV; + } /* Force reset of idle/hv excludes regardless of what the * user requested. diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index cfac28330b03f271726bf8b1d61ee74c7ceac5a7..4bdc656366031ea5bd8411829aecdefb87359683 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -7,6 +7,7 @@ */ #include +#include #include /* @@ -55,8 +56,8 @@ ENTRY(relocate_kernel) .back_pgm: lmg %r0,%r15,gprregs-.base(%r13) .top: - lghi %r7,4096 # load PAGE_SIZE in r7 - lghi %r9,4096 # load PAGE_SIZE in r9 + lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7 + lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9 lg %r5,0(%r2) # read another word for indirection page aghi %r2,8 # increment pointer tml %r5,0x1 # is it a destination page? diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 3d1d808ea8a97bb31be7dee6a7c06e16b3f56ad6..164a1e16b53edfb2d60da9e1a459630023bc392a 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -305,7 +305,7 @@ static void __init setup_lowcore(void) /* * Setup lowcore for boot cpu */ - BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096); + BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * PAGE_SIZE); lc = memblock_virt_alloc_low(sizeof(*lc), sizeof(*lc)); lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.addr = (unsigned long) restart_int_handler; @@ -323,7 +323,7 @@ static void __init setup_lowcore(void) lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; lc->io_new_psw.addr = (unsigned long) io_int_handler; - lc->clock_comparator = -1ULL; + lc->clock_comparator = clock_comparator_max; lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); lc->async_stack = (unsigned long) @@ -469,10 +469,10 @@ static void __init setup_memory_end(void) vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN; tmp = (memory_end ?: max_physmem_end) / PAGE_SIZE; tmp = tmp * (sizeof(struct page) + PAGE_SIZE); - if (tmp + vmalloc_size + MODULES_LEN <= (1UL << 42)) - vmax = 1UL << 42; /* 3-level kernel page table */ + if (tmp + vmalloc_size + MODULES_LEN <= _REGION2_SIZE) + vmax = _REGION2_SIZE; /* 3-level kernel page table */ else - vmax = 1UL << 53; /* 4-level kernel page table */ + vmax = _REGION1_SIZE; /* 4-level kernel page table */ /* module area is at the end of the kernel address space. */ MODULES_END = vmax; MODULES_VADDR = MODULES_END - MODULES_LEN; @@ -818,6 +818,9 @@ static int __init setup_hwcaps(void) case 0x2965: strcpy(elf_platform, "z13"); break; + case 0x3906: + strcpy(elf_platform, "z14"); + break; } /* @@ -922,6 +925,7 @@ void __init setup_arch(char **cmdline_p) setup_memory_end(); setup_memory(); dma_contiguous_reserve(memory_end); + vmcp_cma_reserve(); check_initrd(); reserve_crashkernel(); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1020a11a24e50ea8dd629876fda04ef3480058a1..1cee6753d47a5cba115730cb73cef4324e8d3ed1 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1181,6 +1181,7 @@ static int __init s390_smp_init(void) rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "s390/smp:online", smp_cpu_online, smp_cpu_pre_down); + rc = rc <= 0 ? rc : 0; out: return rc; } diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index 39e2f41b6cf0cf93c80744ca46687800e2b188c7..c8ea715bfe101d43cf6d7ccac6ac17eb8bc6be1b 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c @@ -98,10 +98,16 @@ int page_key_alloc(unsigned long pages) */ void page_key_read(unsigned long *pfn) { + struct page *page; unsigned long addr; - - addr = (unsigned long) page_address(pfn_to_page(*pfn)); - *(unsigned char *) pfn = (unsigned char) page_get_storage_key(addr); + unsigned char key; + + page = pfn_to_page(*pfn); + addr = (unsigned long) page_address(page); + key = (unsigned char) page_get_storage_key(addr) & 0x7f; + if (arch_test_page_nodat(page)) + key |= 0x80; + *(unsigned char *) pfn = key; } /* @@ -126,8 +132,16 @@ void page_key_memorize(unsigned long *pfn) */ void page_key_write(void *address) { - page_set_storage_key((unsigned long) address, - page_key_rp->data[page_key_rx], 0); + struct page *page; + unsigned char key; + + key = page_key_rp->data[page_key_rx]; + page_set_storage_key((unsigned long) address, key & 0x7f, 0); + page = virt_to_page(address); + if (key & 0x80) + arch_set_page_nodat(page, 0); + else + arch_set_page_dat(page, 0); if (++page_key_rx >= PAGE_KEY_DATA_SIZE) return; page_key_rp = page_key_rp->next; diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 192efdfac91829c49a6f41e04c9e3b601c84c0f7..5cbd52169348faf9c09bc258c2cd0072e0089ee0 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -51,8 +51,15 @@ #include #include "entry.h" -u64 sched_clock_base_cc = -1; /* Force to data section. */ -EXPORT_SYMBOL_GPL(sched_clock_base_cc); +unsigned char tod_clock_base[16] __aligned(8) = { + /* Force to data section. */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; +EXPORT_SYMBOL_GPL(tod_clock_base); + +u64 clock_comparator_max = -1ULL; +EXPORT_SYMBOL_GPL(clock_comparator_max); static DEFINE_PER_CPU(struct clock_event_device, comparators); @@ -75,7 +82,7 @@ void __init time_early_init(void) struct ptff_qui qui; /* Initialize TOD steering parameters */ - tod_steering_end = sched_clock_base_cc; + tod_steering_end = *(unsigned long long *) &tod_clock_base[1]; vdso_data->ts_end = tod_steering_end; if (!test_facility(28)) @@ -111,22 +118,27 @@ unsigned long long monotonic_clock(void) } EXPORT_SYMBOL(monotonic_clock); -static void tod_to_timeval(__u64 todval, struct timespec64 *xt) +static void ext_to_timespec64(unsigned char *clk, struct timespec64 *xt) { - unsigned long long sec; + unsigned long long high, low, rem, sec, nsec; + + /* Split extendnd TOD clock to micro-seconds and sub-micro-seconds */ + high = (*(unsigned long long *) clk) >> 4; + low = (*(unsigned long long *)&clk[7]) << 4; + /* Calculate seconds and nano-seconds */ + sec = high; + rem = do_div(sec, 1000000); + nsec = (((low >> 32) + (rem << 32)) * 1000) >> 32; - sec = todval >> 12; - do_div(sec, 1000000); xt->tv_sec = sec; - todval -= (sec * 1000000) << 12; - xt->tv_nsec = ((todval * 1000) >> 12); + xt->tv_nsec = nsec; } void clock_comparator_work(void) { struct clock_event_device *cd; - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = clock_comparator_max; cd = this_cpu_ptr(&comparators); cd->event_handler(cd); } @@ -148,7 +160,7 @@ void init_cpu_timer(void) struct clock_event_device *cd; int cpu; - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = clock_comparator_max; set_clock_comparator(S390_lowcore.clock_comparator); cpu = smp_processor_id(); @@ -179,7 +191,7 @@ static void clock_comparator_interrupt(struct ext_code ext_code, unsigned long param64) { inc_irq_stat(IRQEXT_CLK); - if (S390_lowcore.clock_comparator == -1ULL) + if (S390_lowcore.clock_comparator == clock_comparator_max) set_clock_comparator(S390_lowcore.clock_comparator); } @@ -197,18 +209,28 @@ static void stp_reset(void); void read_persistent_clock64(struct timespec64 *ts) { - __u64 clock; + unsigned char clk[STORE_CLOCK_EXT_SIZE]; + __u64 delta; - clock = get_tod_clock() - initial_leap_seconds; - tod_to_timeval(clock - TOD_UNIX_EPOCH, ts); + delta = initial_leap_seconds + TOD_UNIX_EPOCH; + get_tod_clock_ext(clk); + *(__u64 *) &clk[1] -= delta; + if (*(__u64 *) &clk[1] > delta) + clk[0]--; + ext_to_timespec64(clk, ts); } void read_boot_clock64(struct timespec64 *ts) { - __u64 clock; + unsigned char clk[STORE_CLOCK_EXT_SIZE]; + __u64 delta; - clock = sched_clock_base_cc - initial_leap_seconds; - tod_to_timeval(clock - TOD_UNIX_EPOCH, ts); + delta = initial_leap_seconds + TOD_UNIX_EPOCH; + memcpy(clk, tod_clock_base, 16); + *(__u64 *) &clk[1] -= delta; + if (*(__u64 *) &clk[1] > delta) + clk[0]--; + ext_to_timespec64(clk, ts); } static u64 read_tod_clock(struct clocksource *cs) @@ -335,7 +357,7 @@ static unsigned long clock_sync_flags; * source. If the clock mode is local it will return -EOPNOTSUPP and * -EAGAIN if the clock is not in sync with the external reference. */ -int get_phys_clock(unsigned long long *clock) +int get_phys_clock(unsigned long *clock) { atomic_t *sw_ptr; unsigned int sw0, sw1; @@ -406,7 +428,10 @@ static void clock_sync_global(unsigned long long delta) struct ptff_qto qto; /* Fixup the monotonic sched clock. */ - sched_clock_base_cc += delta; + *(unsigned long long *) &tod_clock_base[1] += delta; + if (*(unsigned long long *) &tod_clock_base[1] < delta) + /* Epoch overflow */ + tod_clock_base[0]++; /* Adjust TOD steering parameters. */ vdso_data->tb_update_count++; now = get_tod_clock(); @@ -437,7 +462,7 @@ static void clock_sync_global(unsigned long long delta) static void clock_sync_local(unsigned long long delta) { /* Add the delta to the clock comparator. */ - if (S390_lowcore.clock_comparator != -1ULL) { + if (S390_lowcore.clock_comparator != clock_comparator_max) { S390_lowcore.clock_comparator += delta; set_clock_comparator(S390_lowcore.clock_comparator); } diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index bb47c92476f0d852ded0b9b50f9756e46480e9b9..ed0bdd220e1a643788655fbefaef328dd38c7951 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include #include @@ -29,12 +31,20 @@ #define PTF_VERTICAL (1UL) #define PTF_CHECK (2UL) +enum { + TOPOLOGY_MODE_HW, + TOPOLOGY_MODE_SINGLE, + TOPOLOGY_MODE_PACKAGE, + TOPOLOGY_MODE_UNINITIALIZED +}; + struct mask_info { struct mask_info *next; unsigned char id; cpumask_t mask; }; +static int topology_mode = TOPOLOGY_MODE_UNINITIALIZED; static void set_topology_timer(void); static void topology_work_fn(struct work_struct *work); static struct sysinfo_15_1_x *tl_info; @@ -59,11 +69,26 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) cpumask_t mask; cpumask_copy(&mask, cpumask_of(cpu)); - if (!MACHINE_HAS_TOPOLOGY) - return mask; - for (; info; info = info->next) { - if (cpumask_test_cpu(cpu, &info->mask)) - return info->mask; + switch (topology_mode) { + case TOPOLOGY_MODE_HW: + while (info) { + if (cpumask_test_cpu(cpu, &info->mask)) { + mask = info->mask; + break; + } + info = info->next; + } + if (cpumask_empty(&mask)) + cpumask_copy(&mask, cpumask_of(cpu)); + break; + case TOPOLOGY_MODE_PACKAGE: + cpumask_copy(&mask, cpu_present_mask); + break; + default: + /* fallthrough */ + case TOPOLOGY_MODE_SINGLE: + cpumask_copy(&mask, cpumask_of(cpu)); + break; } return mask; } @@ -74,7 +99,7 @@ static cpumask_t cpu_thread_map(unsigned int cpu) int i; cpumask_copy(&mask, cpumask_of(cpu)); - if (!MACHINE_HAS_TOPOLOGY) + if (topology_mode != TOPOLOGY_MODE_HW) return mask; cpu -= cpu % (smp_cpu_mtid + 1); for (i = 0; i <= smp_cpu_mtid; i++) @@ -184,10 +209,8 @@ static void topology_update_polarization_simple(void) { int cpu; - mutex_lock(&smp_cpu_state_mutex); for_each_possible_cpu(cpu) smp_cpu_set_polarization(cpu, POLARIZATION_HRZ); - mutex_unlock(&smp_cpu_state_mutex); } static int ptf(unsigned long fc) @@ -223,7 +246,7 @@ int topology_set_cpu_management(int fc) static void update_cpu_masks(void) { struct cpu_topology_s390 *topo; - int cpu; + int cpu, id; for_each_possible_cpu(cpu) { topo = &cpu_topology[cpu]; @@ -231,12 +254,13 @@ static void update_cpu_masks(void) topo->core_mask = cpu_group_map(&socket_info, cpu); topo->book_mask = cpu_group_map(&book_info, cpu); topo->drawer_mask = cpu_group_map(&drawer_info, cpu); - if (!MACHINE_HAS_TOPOLOGY) { + if (topology_mode != TOPOLOGY_MODE_HW) { + id = topology_mode == TOPOLOGY_MODE_PACKAGE ? 0 : cpu; topo->thread_id = cpu; topo->core_id = cpu; - topo->socket_id = cpu; - topo->book_id = cpu; - topo->drawer_id = cpu; + topo->socket_id = id; + topo->book_id = id; + topo->drawer_id = id; if (cpu_present(cpu)) cpumask_set_cpu(cpu, &cpus_with_topology); } @@ -254,6 +278,7 @@ static int __arch_update_cpu_topology(void) struct sysinfo_15_1_x *info = tl_info; int rc = 0; + mutex_lock(&smp_cpu_state_mutex); cpumask_clear(&cpus_with_topology); if (MACHINE_HAS_TOPOLOGY) { rc = 1; @@ -263,6 +288,7 @@ static int __arch_update_cpu_topology(void) update_cpu_masks(); if (!MACHINE_HAS_TOPOLOGY) topology_update_polarization_simple(); + mutex_unlock(&smp_cpu_state_mutex); return rc; } @@ -289,6 +315,11 @@ void topology_schedule_update(void) schedule_work(&topology_work); } +static void topology_flush_work(void) +{ + flush_work(&topology_work); +} + static void topology_timer_fn(unsigned long ignored) { if (ptf(PTF_CHECK)) @@ -459,6 +490,12 @@ void __init topology_init_early(void) struct sysinfo_15_1_x *info; set_sched_topology(s390_topology); + if (topology_mode == TOPOLOGY_MODE_UNINITIALIZED) { + if (MACHINE_HAS_TOPOLOGY) + topology_mode = TOPOLOGY_MODE_HW; + else + topology_mode = TOPOLOGY_MODE_SINGLE; + } if (!MACHINE_HAS_TOPOLOGY) goto out; tl_info = memblock_virt_alloc(PAGE_SIZE, PAGE_SIZE); @@ -474,12 +511,97 @@ void __init topology_init_early(void) __arch_update_cpu_topology(); } +static inline int topology_get_mode(int enabled) +{ + if (!enabled) + return TOPOLOGY_MODE_SINGLE; + return MACHINE_HAS_TOPOLOGY ? TOPOLOGY_MODE_HW : TOPOLOGY_MODE_PACKAGE; +} + +static inline int topology_is_enabled(void) +{ + return topology_mode != TOPOLOGY_MODE_SINGLE; +} + +static int __init topology_setup(char *str) +{ + bool enabled; + int rc; + + rc = kstrtobool(str, &enabled); + if (rc) + return rc; + topology_mode = topology_get_mode(enabled); + return 0; +} +early_param("topology", topology_setup); + +static int topology_ctl_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + unsigned int len; + int new_mode; + char buf[2]; + + if (!*lenp || *ppos) { + *lenp = 0; + return 0; + } + if (!write) { + strncpy(buf, topology_is_enabled() ? "1\n" : "0\n", + ARRAY_SIZE(buf)); + len = strnlen(buf, ARRAY_SIZE(buf)); + if (len > *lenp) + len = *lenp; + if (copy_to_user(buffer, buf, len)) + return -EFAULT; + goto out; + } + len = *lenp; + if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) + return -EFAULT; + if (buf[0] != '0' && buf[0] != '1') + return -EINVAL; + mutex_lock(&smp_cpu_state_mutex); + new_mode = topology_get_mode(buf[0] == '1'); + if (topology_mode != new_mode) { + topology_mode = new_mode; + topology_schedule_update(); + } + mutex_unlock(&smp_cpu_state_mutex); + topology_flush_work(); +out: + *lenp = len; + *ppos += len; + return 0; +} + +static struct ctl_table topology_ctl_table[] = { + { + .procname = "topology", + .mode = 0644, + .proc_handler = topology_ctl_handler, + }, + { }, +}; + +static struct ctl_table topology_dir_table[] = { + { + .procname = "s390", + .maxlen = 0, + .mode = 0555, + .child = topology_ctl_table, + }, + { }, +}; + static int __init topology_init(void) { if (MACHINE_HAS_TOPOLOGY) set_topology_timer(); else topology_update_polarization_simple(); + register_sysctl_table(topology_dir_table); return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); } device_initcall(topology_init); diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index b89d19f6f2ab4b745b7ea09b446c5fb13d76c42a..eacda05b45d7e0ac81b8b60f632a43fc0c268b6c 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -157,6 +157,8 @@ int vdso_alloc_per_cpu(struct lowcore *lowcore) page_frame = get_zeroed_page(GFP_KERNEL); if (!segment_table || !page_table || !page_frame) goto out; + arch_set_page_dat(virt_to_page(segment_table), SEGMENT_ORDER); + arch_set_page_dat(virt_to_page(page_table), 0); /* Initialize per-cpu vdso data page */ vd = (struct vdso_per_cpu_data *) page_frame; diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S index 8f048c2d6d138a123c74571337d36c6bdde21a67..263a7f9eee1eec82295891ad30fcd00bc0ac1407 100644 --- a/arch/s390/kernel/vdso32/vdso32.lds.S +++ b/arch/s390/kernel/vdso32/vdso32.lds.S @@ -2,6 +2,8 @@ * This is the infamous ld script for the 32 bits vdso * library */ + +#include #include OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") @@ -91,7 +93,7 @@ SECTIONS .debug_ranges 0 : { *(.debug_ranges) } .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); PROVIDE(_vdso_data = .); /DISCARD/ : { diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S index f35455d497feffc2226d8621bb47d2f1361ce6c4..9e3dbbcc1cfc3363af7f7d4a9cfbcd7e58034aaa 100644 --- a/arch/s390/kernel/vdso64/vdso64.lds.S +++ b/arch/s390/kernel/vdso64/vdso64.lds.S @@ -2,6 +2,8 @@ * This is the infamous ld script for the 64 bits vdso * library */ + +#include #include OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") @@ -91,7 +93,7 @@ SECTIONS .debug_ranges 0 : { *(.debug_ranges) } .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); PROVIDE(_vdso_data = .); /DISCARD/ : { diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index ce865bd4f81d9696e7c9907d7bcaedede8f7cf43..d93a2c0474bf67e45698882ecb5f36f0d8688a7d 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -27,7 +27,7 @@ static int diag_release_pages(struct kvm_vcpu *vcpu) unsigned long prefix = kvm_s390_get_prefix(vcpu); start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; - end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096; + end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + PAGE_SIZE; vcpu->stat.diagnose_10++; if (start & ~PAGE_MASK || end & ~PAGE_MASK || start >= end @@ -51,9 +51,9 @@ static int diag_release_pages(struct kvm_vcpu *vcpu) */ gmap_discard(vcpu->arch.gmap, start, prefix); if (start <= prefix) - gmap_discard(vcpu->arch.gmap, 0, 4096); - if (end > prefix + 4096) - gmap_discard(vcpu->arch.gmap, 4096, 8192); + gmap_discard(vcpu->arch.gmap, 0, PAGE_SIZE); + if (end > prefix + PAGE_SIZE) + gmap_discard(vcpu->arch.gmap, PAGE_SIZE, 2 * PAGE_SIZE); gmap_discard(vcpu->arch.gmap, prefix + 2 * PAGE_SIZE, end); } return 0; @@ -150,7 +150,7 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu) { VCPU_EVENT(vcpu, 5, "%s", "diag time slice end"); vcpu->stat.diagnose_44++; - kvm_vcpu_on_spin(vcpu); + kvm_vcpu_on_spin(vcpu, true); return 0; } diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 653cae5e1ee1f97b6de07f665cf2b90ba8619d8e..3cc77391a10229cfd1eb1f3d375327005bdd0c33 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -629,7 +629,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, iep = ctlreg0.iep && test_kvm_facility(vcpu->kvm, 130); if (asce.r) goto real_address; - ptr = asce.origin * 4096; + ptr = asce.origin * PAGE_SIZE; switch (asce.dt) { case ASCE_TYPE_REGION1: if (vaddr.rfx01 > asce.tl) @@ -674,7 +674,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_REGION_SECOND_TRANS; if (edat1) dat_protection |= rfte.p; - ptr = rfte.rto * 4096 + vaddr.rsx * 8; + ptr = rfte.rto * PAGE_SIZE + vaddr.rsx * 8; } /* fallthrough */ case ASCE_TYPE_REGION2: { @@ -692,7 +692,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_REGION_THIRD_TRANS; if (edat1) dat_protection |= rste.p; - ptr = rste.rto * 4096 + vaddr.rtx * 8; + ptr = rste.rto * PAGE_SIZE + vaddr.rtx * 8; } /* fallthrough */ case ASCE_TYPE_REGION3: { @@ -720,7 +720,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_SEGMENT_TRANSLATION; if (edat1) dat_protection |= rtte.fc0.p; - ptr = rtte.fc0.sto * 4096 + vaddr.sx * 8; + ptr = rtte.fc0.sto * PAGE_SIZE + vaddr.sx * 8; } /* fallthrough */ case ASCE_TYPE_SEGMENT: { @@ -743,7 +743,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, goto absolute_address; } dat_protection |= ste.fc0.p; - ptr = ste.fc0.pto * 2048 + vaddr.px * 8; + ptr = ste.fc0.pto * (PAGE_SIZE / 2) + vaddr.px * 8; } } if (kvm_is_error_gpa(vcpu->kvm, ptr)) @@ -993,7 +993,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, parent = sg->parent; vaddr.addr = saddr; asce.val = sg->orig_asce; - ptr = asce.origin * 4096; + ptr = asce.origin * PAGE_SIZE; if (asce.r) { *fake = 1; ptr = 0; @@ -1029,7 +1029,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, union region1_table_entry rfte; if (*fake) { - ptr += (unsigned long) vaddr.rfx << 53; + ptr += vaddr.rfx * _REGION1_SIZE; rfte.val = ptr; goto shadow_r2t; } @@ -1044,7 +1044,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, return PGM_REGION_SECOND_TRANS; if (sg->edat_level >= 1) *dat_protection |= rfte.p; - ptr = rfte.rto << 12UL; + ptr = rfte.rto * PAGE_SIZE; shadow_r2t: rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake); if (rc) @@ -1055,7 +1055,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, union region2_table_entry rste; if (*fake) { - ptr += (unsigned long) vaddr.rsx << 42; + ptr += vaddr.rsx * _REGION2_SIZE; rste.val = ptr; goto shadow_r3t; } @@ -1070,7 +1070,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, return PGM_REGION_THIRD_TRANS; if (sg->edat_level >= 1) *dat_protection |= rste.p; - ptr = rste.rto << 12UL; + ptr = rste.rto * PAGE_SIZE; shadow_r3t: rste.p |= *dat_protection; rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake); @@ -1082,7 +1082,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, union region3_table_entry rtte; if (*fake) { - ptr += (unsigned long) vaddr.rtx << 31; + ptr += vaddr.rtx * _REGION3_SIZE; rtte.val = ptr; goto shadow_sgt; } @@ -1098,7 +1098,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, if (rtte.fc && sg->edat_level >= 2) { *dat_protection |= rtte.fc0.p; *fake = 1; - ptr = rtte.fc1.rfaa << 31UL; + ptr = rtte.fc1.rfaa * _REGION3_SIZE; rtte.val = ptr; goto shadow_sgt; } @@ -1106,7 +1106,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, return PGM_SEGMENT_TRANSLATION; if (sg->edat_level >= 1) *dat_protection |= rtte.fc0.p; - ptr = rtte.fc0.sto << 12UL; + ptr = rtte.fc0.sto * PAGE_SIZE; shadow_sgt: rtte.fc0.p |= *dat_protection; rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake); @@ -1118,7 +1118,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, union segment_table_entry ste; if (*fake) { - ptr += (unsigned long) vaddr.sx << 20; + ptr += vaddr.sx * _SEGMENT_SIZE; ste.val = ptr; goto shadow_pgt; } @@ -1134,11 +1134,11 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, *dat_protection |= ste.fc0.p; if (ste.fc && sg->edat_level >= 1) { *fake = 1; - ptr = ste.fc1.sfaa << 20UL; + ptr = ste.fc1.sfaa * _SEGMENT_SIZE; ste.val = ptr; goto shadow_pgt; } - ptr = ste.fc0.pto << 11UL; + ptr = ste.fc0.pto * (PAGE_SIZE / 2); shadow_pgt: ste.fc0.p |= *dat_protection; rc = gmap_shadow_pgt(sg, saddr, ste.val, *fake); @@ -1187,8 +1187,7 @@ int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg, vaddr.addr = saddr; if (fake) { - /* offset in 1MB guest memory block */ - pte.val = pgt + ((unsigned long) vaddr.px << 12UL); + pte.val = pgt + vaddr.px * PAGE_SIZE; goto shadow_page; } if (!rc) diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index c2e0ddc1356e551ebd8c466b73956e2574b67436..bcbd86621d018085d036f43d815ae1c97791951c 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -308,7 +308,7 @@ static inline int in_addr_range(u64 addr, u64 a, u64 b) return (addr >= a) && (addr <= b); else /* "overflowing" interval */ - return (addr <= a) && (addr >= b); + return (addr >= a) || (addr <= b); } #define end_of_range(bp_info) (bp_info->addr + bp_info->len - 1) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index a619ddae610da2c0fabaf66a9a123d1572b51f9c..a832ad031cee78f5cc6fe17b93fb315e17fdd50a 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -2479,6 +2479,7 @@ void kvm_s390_reinject_machine_check(struct kvm_vcpu *vcpu, struct kvm_s390_mchk_info *mchk; union mci mci; __u64 cr14 = 0; /* upper bits are not used */ + int rc; mci.val = mcck_info->mcic; if (mci.sr) @@ -2496,12 +2497,13 @@ void kvm_s390_reinject_machine_check(struct kvm_vcpu *vcpu, if (mci.ck) { /* Inject the floating machine check */ inti.type = KVM_S390_MCHK; - WARN_ON_ONCE(__inject_vm(vcpu->kvm, &inti)); + rc = __inject_vm(vcpu->kvm, &inti); } else { /* Inject the machine check to specified vcpu */ irq.type = KVM_S390_MCHK; - WARN_ON_ONCE(kvm_s390_inject_vcpu(vcpu, &irq)); + rc = kvm_s390_inject_vcpu(vcpu, &irq); } + WARN_ON_ONCE(rc); } int kvm_set_routing_entry(struct kvm *kvm, diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index af09d3437631d348dca2f1a6699c34ed49c624ed..40d0a1a97889b04f5e0bf1beb9d509721e1d5ff8 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -130,6 +130,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { NULL } }; +struct kvm_s390_tod_clock_ext { + __u8 epoch_idx; + __u64 tod; + __u8 reserved[7]; +} __packed; + /* allow nested virtualization in KVM (if enabled by user space) */ static int nested; module_param(nested, int, S_IRUGO); @@ -874,6 +880,26 @@ static int kvm_s390_vm_get_migration(struct kvm *kvm, return 0; } +static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_tod_clock gtod; + + if (copy_from_user(>od, (void __user *)attr->addr, sizeof(gtod))) + return -EFAULT; + + if (test_kvm_facility(kvm, 139)) + kvm_s390_set_tod_clock_ext(kvm, >od); + else if (gtod.epoch_idx == 0) + kvm_s390_set_tod_clock(kvm, gtod.tod); + else + return -EINVAL; + + VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx", + gtod.epoch_idx, gtod.tod); + + return 0; +} + static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) { u8 gtod_high; @@ -909,6 +935,9 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr) return -EINVAL; switch (attr->attr) { + case KVM_S390_VM_TOD_EXT: + ret = kvm_s390_set_tod_ext(kvm, attr); + break; case KVM_S390_VM_TOD_HIGH: ret = kvm_s390_set_tod_high(kvm, attr); break; @@ -922,6 +951,43 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr) return ret; } +static void kvm_s390_get_tod_clock_ext(struct kvm *kvm, + struct kvm_s390_vm_tod_clock *gtod) +{ + struct kvm_s390_tod_clock_ext htod; + + preempt_disable(); + + get_tod_clock_ext((char *)&htod); + + gtod->tod = htod.tod + kvm->arch.epoch; + gtod->epoch_idx = htod.epoch_idx + kvm->arch.epdx; + + if (gtod->tod < htod.tod) + gtod->epoch_idx += 1; + + preempt_enable(); +} + +static int kvm_s390_get_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_tod_clock gtod; + + memset(>od, 0, sizeof(gtod)); + + if (test_kvm_facility(kvm, 139)) + kvm_s390_get_tod_clock_ext(kvm, >od); + else + gtod.tod = kvm_s390_get_tod_clock_fast(kvm); + + if (copy_to_user((void __user *)attr->addr, >od, sizeof(gtod))) + return -EFAULT; + + VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x, TOD base: 0x%llx", + gtod.epoch_idx, gtod.tod); + return 0; +} + static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) { u8 gtod_high = 0; @@ -954,6 +1020,9 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) return -EINVAL; switch (attr->attr) { + case KVM_S390_VM_TOD_EXT: + ret = kvm_s390_get_tod_ext(kvm, attr); + break; case KVM_S390_VM_TOD_HIGH: ret = kvm_s390_get_tod_high(kvm, attr); break; @@ -1505,7 +1574,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm, if (r < 0) pgstev = 0; /* save the value */ - res[i++] = (pgstev >> 24) & 0x3; + res[i++] = (pgstev >> 24) & 0x43; /* * if the next bit is too far away, stop. * if we reached the previous "next", find the next one @@ -1583,7 +1652,7 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm, pgstev = bits[i]; pgstev = pgstev << 24; - mask &= _PGSTE_GPS_USAGE_MASK; + mask &= _PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT; set_pgste_bits(kvm->mm, hva, mask, pgstev); } srcu_read_unlock(&kvm->srcu, srcu_idx); @@ -1858,8 +1927,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask, S390_ARCH_FAC_LIST_SIZE_BYTE); + /* we are always in czam mode - even on pre z14 machines */ + set_kvm_facility(kvm->arch.model.fac_mask, 138); + set_kvm_facility(kvm->arch.model.fac_list, 138); + /* we emulate STHYI in kvm */ set_kvm_facility(kvm->arch.model.fac_mask, 74); set_kvm_facility(kvm->arch.model.fac_list, 74); + if (MACHINE_HAS_TLB_GUEST) { + set_kvm_facility(kvm->arch.model.fac_mask, 147); + set_kvm_facility(kvm->arch.model.fac_list, 147); + } kvm->arch.model.cpuid = kvm_s390_get_initial_cpuid(); kvm->arch.model.ibc = sclp.ibc & 0x0fff; @@ -2369,6 +2446,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->eca |= ECA_VX; vcpu->arch.sie_block->ecd |= ECD_HOSTREGMGMT; } + if (test_kvm_facility(vcpu->kvm, 139)) + vcpu->arch.sie_block->ecd |= ECD_MEF; + vcpu->arch.sie_block->sdnxo = ((unsigned long) &vcpu->run->s.regs.sdnx) | SDNXC; vcpu->arch.sie_block->riccbd = (unsigned long) &vcpu->run->s.regs.riccb; @@ -2447,6 +2527,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) return kvm_s390_vcpu_has_irq(vcpu, 0); } +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) +{ + return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE); +} + void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu) { atomic_or(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20); @@ -2855,6 +2940,35 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) return 0; } +void kvm_s390_set_tod_clock_ext(struct kvm *kvm, + const struct kvm_s390_vm_tod_clock *gtod) +{ + struct kvm_vcpu *vcpu; + struct kvm_s390_tod_clock_ext htod; + int i; + + mutex_lock(&kvm->lock); + preempt_disable(); + + get_tod_clock_ext((char *)&htod); + + kvm->arch.epoch = gtod->tod - htod.tod; + kvm->arch.epdx = gtod->epoch_idx - htod.epoch_idx; + + if (kvm->arch.epoch > gtod->tod) + kvm->arch.epdx -= 1; + + kvm_s390_vcpu_block_all(kvm); + kvm_for_each_vcpu(i, vcpu, kvm) { + vcpu->arch.sie_block->epoch = kvm->arch.epoch; + vcpu->arch.sie_block->epdx = kvm->arch.epdx; + } + + kvm_s390_vcpu_unblock_all(kvm); + preempt_enable(); + mutex_unlock(&kvm->lock); +} + void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod) { struct kvm_vcpu *vcpu; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 6fedc8bc7a37393bd1fa50be94d22d53f431a076..9f8fdd7b231134da9b2d2d4d8971a05546b33c6b 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -272,6 +272,8 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); int handle_sthyi(struct kvm_vcpu *vcpu); /* implemented in kvm-s390.c */ +void kvm_s390_set_tod_clock_ext(struct kvm *kvm, + const struct kvm_s390_vm_tod_clock *gtod); void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod); long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 8a1dac793d6b0ad0685ffd7a35743ca511274035..c954ac49eee47158ac27bd1d16ba9dbcab7e25a3 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -329,7 +329,7 @@ static int handle_sske(struct kvm_vcpu *vcpu) start = kvm_s390_logical_to_effective(vcpu, start); if (m3 & SSKE_MB) { /* start already designates an absolute address */ - end = (start + (1UL << 20)) & ~((1UL << 20) - 1); + end = (start + _SEGMENT_SIZE) & ~(_SEGMENT_SIZE - 1); } else { start = kvm_s390_real_to_abs(vcpu, start); end = start + PAGE_SIZE; @@ -893,10 +893,10 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) case 0x00000000: /* only 4k frames specify a real address */ start = kvm_s390_real_to_abs(vcpu, start); - end = (start + (1UL << 12)) & ~((1UL << 12) - 1); + end = (start + PAGE_SIZE) & ~(PAGE_SIZE - 1); break; case 0x00001000: - end = (start + (1UL << 20)) & ~((1UL << 20) - 1); + end = (start + _SEGMENT_SIZE) & ~(_SEGMENT_SIZE - 1); break; case 0x00002000: /* only support 2G frame size if EDAT2 is available and we are @@ -904,7 +904,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) if (!test_kvm_facility(vcpu->kvm, 78) || psw_bits(vcpu->arch.sie_block->gpsw).eaba == PSW_BITS_AMODE_24BIT) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - end = (start + (1UL << 31)) & ~((1UL << 31) - 1); + end = (start + _REGION3_SIZE) & ~(_REGION3_SIZE - 1); break; default: return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); @@ -988,6 +988,8 @@ static inline int do_essa(struct kvm_vcpu *vcpu, const int orc) if (pgstev & _PGSTE_GPS_ZERO) res |= 1; } + if (pgstev & _PGSTE_GPS_NODAT) + res |= 0x20; vcpu->run->s.regs.gprs[r1] = res; /* * It is possible that all the normal 511 slots were full, in which case @@ -1027,7 +1029,9 @@ static int handle_essa(struct kvm_vcpu *vcpu) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); /* Check for invalid operation request code */ orc = (vcpu->arch.sie_block->ipb & 0xf0000000) >> 28; - if (orc > ESSA_MAX) + /* ORCs 0-6 are always valid */ + if (orc > (test_kvm_facility(vcpu->kvm, 147) ? ESSA_SET_STABLE_NODAT + : ESSA_SET_STABLE_IF_RESIDENT)) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); if (likely(!vcpu->kvm->arch.migration_state)) { diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 1a252f5370818e5febbe5d05f96432be93f33488..9d592ef4104b0416029944fed5770a8ea74a47cb 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -155,29 +155,26 @@ static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu, return rc; } -static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) +static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter, + u64 *status_reg) { - int rc; unsigned int i; struct kvm_vcpu *v; + bool all_stopped = true; - switch (parameter & 0xff) { - case 0: - rc = SIGP_CC_NOT_OPERATIONAL; - break; - case 1: - case 2: - kvm_for_each_vcpu(i, v, vcpu->kvm) { - v->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; - kvm_clear_async_pf_completion_queue(v); - } - - rc = SIGP_CC_ORDER_CODE_ACCEPTED; - break; - default: - rc = -EOPNOTSUPP; + kvm_for_each_vcpu(i, v, vcpu->kvm) { + if (v == vcpu) + continue; + if (!is_vcpu_stopped(v)) + all_stopped = false; } - return rc; + + *status_reg &= 0xffffffff00000000UL; + + /* Reject set arch order, with czam we're always in z/Arch mode. */ + *status_reg |= (all_stopped ? SIGP_STATUS_INVALID_PARAMETER : + SIGP_STATUS_INCORRECT_STATE); + return SIGP_CC_STATUS_STORED; } static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, @@ -446,7 +443,8 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) switch (order_code) { case SIGP_SET_ARCHITECTURE: vcpu->stat.instruction_sigp_arch++; - rc = __sigp_set_arch(vcpu, parameter); + rc = __sigp_set_arch(vcpu, parameter, + &vcpu->run->s.regs.gprs[r1]); break; default: rc = handle_sigp_dst(vcpu, order_code, cpu_addr, diff --git a/arch/s390/kvm/sthyi.c b/arch/s390/kvm/sthyi.c index 926b5244263efd3dd1fadf637ce4790251367e60..395926b8c1ed48f7994210c8ff6c7de7ae43e709 100644 --- a/arch/s390/kvm/sthyi.c +++ b/arch/s390/kvm/sthyi.c @@ -394,7 +394,7 @@ static int sthyi(u64 vaddr) "srl %[cc],28\n" : [cc] "=d" (cc) : [code] "d" (code), [addr] "a" (addr) - : "memory", "cc"); + : "3", "memory", "cc"); return cc; } @@ -425,7 +425,7 @@ int handle_sthyi(struct kvm_vcpu *vcpu) VCPU_EVENT(vcpu, 3, "STHYI: fc: %llu addr: 0x%016llx", code, addr); trace_kvm_s390_handle_sthyi(vcpu, code, addr); - if (reg1 == reg2 || reg1 & 1 || reg2 & 1 || addr & ~PAGE_MASK) + if (reg1 == reg2 || reg1 & 1 || reg2 & 1) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); if (code & 0xffff) { @@ -433,13 +433,8 @@ int handle_sthyi(struct kvm_vcpu *vcpu) goto out; } - /* - * If the page has not yet been faulted in, we want to do that - * now and not after all the expensive calculations. - */ - r = write_guest(vcpu, addr, reg2, &cc, 1); - if (r) - return kvm_s390_inject_prog_cond(vcpu, r); + if (addr & ~PAGE_MASK) + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); sctns = (void *)get_zeroed_page(GFP_KERNEL); if (!sctns) diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 715c19c45d9adbf565c28839d6f9d45cdb627b15..b18b5652e5c59b84f64f24a89fb2a14033e65e36 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -349,6 +349,9 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) scb_s->eca |= scb_o->eca & ECA_IB; if (test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_CEI)) scb_s->eca |= scb_o->eca & ECA_CEI; + /* Epoch Extension */ + if (test_kvm_facility(vcpu->kvm, 139)) + scb_s->ecd |= scb_o->ecd & ECD_MEF; prepare_ibc(vcpu, vsie_page); rc = shadow_crycb(vcpu, vsie_page); @@ -806,8 +809,6 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) { struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s; struct kvm_s390_sie_block *scb_o = vsie_page->scb_o; - struct mcck_volatile_info *mcck_info; - struct sie_page *sie_page; int rc; handle_last_fault(vcpu, vsie_page); @@ -831,9 +832,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) if (rc == -EINTR) { VCPU_EVENT(vcpu, 3, "%s", "machine check"); - sie_page = container_of(scb_s, struct sie_page, sie_block); - mcck_info = &sie_page->mcck_info; - kvm_s390_reinject_machine_check(vcpu, mcck_info); + kvm_s390_reinject_machine_check(vcpu, &vsie_page->mcck_info); return 0; } @@ -919,6 +918,13 @@ static void register_shadow_scb(struct kvm_vcpu *vcpu, */ preempt_disable(); scb_s->epoch += vcpu->kvm->arch.epoch; + + if (scb_s->ecd & ECD_MEF) { + scb_s->epdx += vcpu->kvm->arch.epdx; + if (scb_s->epoch < vcpu->kvm->arch.epoch) + scb_s->epdx += 1; + } + preempt_enable(); } @@ -1069,7 +1075,7 @@ int kvm_s390_handle_vsie(struct kvm_vcpu *vcpu) if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); - BUILD_BUG_ON(sizeof(struct vsie_page) != 4096); + BUILD_BUG_ON(sizeof(struct vsie_page) != PAGE_SIZE); scb_addr = kvm_s390_get_base_disp_s(vcpu, NULL); /* 512 byte alignment */ diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 92e90e40b6fb4a3dfaa952fd6413e301cda81711..7f17555ad4d58208eeedf2230e9cdf9d0a7b4eec 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -57,7 +57,7 @@ static void __udelay_enabled(unsigned long long usecs) end = get_tod_clock_fast() + (usecs << 12); do { clock_saved = 0; - if (end < S390_lowcore.clock_comparator) { + if (tod_after(S390_lowcore.clock_comparator, end)) { clock_saved = local_tick_disable(); set_clock_comparator(end); } diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index ffb15bd4c593f645f5ea9d226473af47a2be39a8..b12663d653d82879fb38db734b82b4dc3ec7cf2e 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -32,42 +32,63 @@ static int __init spin_retry_setup(char *str) } __setup("spin_retry=", spin_retry_setup); +static inline int arch_load_niai4(int *lock) +{ + int owner; + + asm volatile( +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + " .long 0xb2fa0040\n" /* NIAI 4 */ +#endif + " l %0,%1\n" + : "=d" (owner) : "Q" (*lock) : "memory"); + return owner; +} + +static inline int arch_cmpxchg_niai8(int *lock, int old, int new) +{ + int expected = old; + + asm volatile( +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + " .long 0xb2fa0080\n" /* NIAI 8 */ +#endif + " cs %0,%3,%1\n" + : "=d" (old), "=Q" (*lock) + : "0" (old), "d" (new), "Q" (*lock) + : "cc", "memory"); + return expected == old; +} + void arch_spin_lock_wait(arch_spinlock_t *lp) { int cpu = SPINLOCK_LOCKVAL; - int owner, count, first_diag; + int owner, count; + + /* Pass the virtual CPU to the lock holder if it is not running */ + owner = arch_load_niai4(&lp->lock); + if (owner && arch_vcpu_is_preempted(~owner)) + smp_yield_cpu(~owner); - first_diag = 1; + count = spin_retry; while (1) { - owner = ACCESS_ONCE(lp->lock); + owner = arch_load_niai4(&lp->lock); /* Try to get the lock if it is free. */ if (!owner) { - if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu)) + if (arch_cmpxchg_niai8(&lp->lock, 0, cpu)) return; continue; } - /* First iteration: check if the lock owner is running. */ - if (first_diag && arch_vcpu_is_preempted(~owner)) { - smp_yield_cpu(~owner); - first_diag = 0; + if (count-- >= 0) continue; - } - /* Loop for a while on the lock value. */ count = spin_retry; - do { - owner = ACCESS_ONCE(lp->lock); - } while (owner && count-- > 0); - if (!owner) - continue; /* * For multiple layers of hypervisors, e.g. z/VM + LPAR * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) { + if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) smp_yield_cpu(~owner); - first_diag = 0; - } } } EXPORT_SYMBOL(arch_spin_lock_wait); @@ -75,42 +96,36 @@ EXPORT_SYMBOL(arch_spin_lock_wait); void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) { int cpu = SPINLOCK_LOCKVAL; - int owner, count, first_diag; + int owner, count; local_irq_restore(flags); - first_diag = 1; + + /* Pass the virtual CPU to the lock holder if it is not running */ + owner = arch_load_niai4(&lp->lock); + if (owner && arch_vcpu_is_preempted(~owner)) + smp_yield_cpu(~owner); + + count = spin_retry; while (1) { - owner = ACCESS_ONCE(lp->lock); + owner = arch_load_niai4(&lp->lock); /* Try to get the lock if it is free. */ if (!owner) { local_irq_disable(); - if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu)) + if (arch_cmpxchg_niai8(&lp->lock, 0, cpu)) return; local_irq_restore(flags); continue; } - /* Check if the lock owner is running. */ - if (first_diag && arch_vcpu_is_preempted(~owner)) { - smp_yield_cpu(~owner); - first_diag = 0; + if (count-- >= 0) continue; - } - /* Loop for a while on the lock value. */ count = spin_retry; - do { - owner = ACCESS_ONCE(lp->lock); - } while (owner && count-- > 0); - if (!owner) - continue; /* * For multiple layers of hypervisors, e.g. z/VM + LPAR * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) { + if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) smp_yield_cpu(~owner); - first_diag = 0; - } } } EXPORT_SYMBOL(arch_spin_lock_wait_flags); diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index b3bd3f23b8e851c7f67e46cb527e20603512e7f5..4ea9106417ee0f177df50a6187c6e2436972f4ca 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -15,8 +15,30 @@ #include #include +#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES static DEFINE_STATIC_KEY_FALSE(have_mvcos); +static int __init uaccess_init(void) +{ + if (test_facility(27)) + static_branch_enable(&have_mvcos); + return 0; +} +early_initcall(uaccess_init); + +static inline int copy_with_mvcos(void) +{ + if (static_branch_likely(&have_mvcos)) + return 1; + return 0; +} +#else +static inline int copy_with_mvcos(void) +{ + return 1; +} +#endif + static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr, unsigned long size) { @@ -84,7 +106,7 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr, unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return copy_from_user_mvcos(to, from, n); return copy_from_user_mvcp(to, from, n); } @@ -157,7 +179,7 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x, unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return copy_to_user_mvcos(to, from, n); return copy_to_user_mvcs(to, from, n); } @@ -220,7 +242,7 @@ static inline unsigned long copy_in_user_mvc(void __user *to, const void __user unsigned long raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return copy_in_user_mvcos(to, from, n); return copy_in_user_mvc(to, from, n); } @@ -292,7 +314,7 @@ static inline unsigned long clear_user_xc(void __user *to, unsigned long size) unsigned long __clear_user(void __user *to, unsigned long size) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return clear_user_mvcos(to, size); return clear_user_xc(to, size); } @@ -349,11 +371,3 @@ long __strncpy_from_user(char *dst, const char __user *src, long size) return done; } EXPORT_SYMBOL(__strncpy_from_user); - -static int __init uaccess_init(void) -{ - if (test_facility(27)) - static_branch_enable(&have_mvcos); - return 0; -} -early_initcall(uaccess_init); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 14f25798b001ca770ccb8ae63099ce9f86f988c8..bdabb013537b2e0c6f2cbded853963b3b581df3f 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -135,7 +135,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) pr_alert("AS:%016lx ", asce); switch (asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: - table = table + ((address >> 53) & 0x7ff); + table += (address & _REGION1_INDEX) >> _REGION1_SHIFT; if (bad_address(table)) goto bad; pr_cont("R1:%016lx ", *table); @@ -144,7 +144,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_REGION2: - table = table + ((address >> 42) & 0x7ff); + table += (address & _REGION2_INDEX) >> _REGION2_SHIFT; if (bad_address(table)) goto bad; pr_cont("R2:%016lx ", *table); @@ -153,7 +153,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_REGION3: - table = table + ((address >> 31) & 0x7ff); + table += (address & _REGION3_INDEX) >> _REGION3_SHIFT; if (bad_address(table)) goto bad; pr_cont("R3:%016lx ", *table); @@ -162,7 +162,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_SEGMENT: - table = table + ((address >> 20) & 0x7ff); + table += (address & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; if (bad_address(table)) goto bad; pr_cont("S:%016lx ", *table); @@ -170,7 +170,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) goto out; table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); } - table = table + ((address >> 12) & 0xff); + table += (address & _PAGE_INDEX) >> _PAGE_SHIFT; if (bad_address(table)) goto bad; pr_cont("P:%016lx ", *table); diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 4fb3d3cdb370db610c0fcafb6d7f25af7084d331..2f66290c9b9273b2bf0295742bb5e56c0d51f1d6 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -36,16 +36,16 @@ static struct gmap *gmap_alloc(unsigned long limit) unsigned long *table; unsigned long etype, atype; - if (limit < (1UL << 31)) { - limit = (1UL << 31) - 1; + if (limit < _REGION3_SIZE) { + limit = _REGION3_SIZE - 1; atype = _ASCE_TYPE_SEGMENT; etype = _SEGMENT_ENTRY_EMPTY; - } else if (limit < (1UL << 42)) { - limit = (1UL << 42) - 1; + } else if (limit < _REGION2_SIZE) { + limit = _REGION2_SIZE - 1; atype = _ASCE_TYPE_REGION3; etype = _REGION3_ENTRY_EMPTY; - } else if (limit < (1UL << 53)) { - limit = (1UL << 53) - 1; + } else if (limit < _REGION1_SIZE) { + limit = _REGION1_SIZE - 1; atype = _ASCE_TYPE_REGION2; etype = _REGION2_ENTRY_EMPTY; } else { @@ -65,7 +65,7 @@ static struct gmap *gmap_alloc(unsigned long limit) spin_lock_init(&gmap->guest_table_lock); spin_lock_init(&gmap->shadow_lock); atomic_set(&gmap->ref_count, 1); - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) goto out_free; page->index = 0; @@ -100,14 +100,14 @@ struct gmap *gmap_create(struct mm_struct *mm, unsigned long limit) if (!gmap) return NULL; gmap->mm = mm; - spin_lock(&mm->context.gmap_lock); + spin_lock(&mm->context.lock); list_add_rcu(&gmap->list, &mm->context.gmap_list); if (list_is_singular(&mm->context.gmap_list)) gmap_asce = gmap->asce; else gmap_asce = -1UL; WRITE_ONCE(mm->context.gmap_asce, gmap_asce); - spin_unlock(&mm->context.gmap_lock); + spin_unlock(&mm->context.lock); return gmap; } EXPORT_SYMBOL_GPL(gmap_create); @@ -186,7 +186,7 @@ static void gmap_free(struct gmap *gmap) gmap_flush_tlb(gmap); /* Free all segment & region tables. */ list_for_each_entry_safe(page, next, &gmap->crst_list, lru) - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); gmap_radix_tree_free(&gmap->guest_to_host); gmap_radix_tree_free(&gmap->host_to_guest); @@ -248,7 +248,7 @@ void gmap_remove(struct gmap *gmap) spin_unlock(&gmap->shadow_lock); } /* Remove gmap from the pre-mm list */ - spin_lock(&gmap->mm->context.gmap_lock); + spin_lock(&gmap->mm->context.lock); list_del_rcu(&gmap->list); if (list_empty(&gmap->mm->context.gmap_list)) gmap_asce = 0; @@ -258,7 +258,7 @@ void gmap_remove(struct gmap *gmap) else gmap_asce = -1UL; WRITE_ONCE(gmap->mm->context.gmap_asce, gmap_asce); - spin_unlock(&gmap->mm->context.gmap_lock); + spin_unlock(&gmap->mm->context.lock); synchronize_rcu(); /* Put reference */ gmap_put(gmap); @@ -306,7 +306,7 @@ static int gmap_alloc_table(struct gmap *gmap, unsigned long *table, unsigned long *new; /* since we dont free the gmap table until gmap_free we can unlock */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; new = (unsigned long *) page_to_phys(page); @@ -321,7 +321,7 @@ static int gmap_alloc_table(struct gmap *gmap, unsigned long *table, } spin_unlock(&gmap->guest_table_lock); if (page) - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return 0; } @@ -546,30 +546,30 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) /* Create higher level tables in the gmap page table */ table = gmap->table; if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION1) { - table += (gaddr >> 53) & 0x7ff; + table += (gaddr & _REGION1_INDEX) >> _REGION1_SHIFT; if ((*table & _REGION_ENTRY_INVALID) && gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY, - gaddr & 0xffe0000000000000UL)) + gaddr & _REGION1_MASK)) return -ENOMEM; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); } if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION2) { - table += (gaddr >> 42) & 0x7ff; + table += (gaddr & _REGION2_INDEX) >> _REGION2_SHIFT; if ((*table & _REGION_ENTRY_INVALID) && gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY, - gaddr & 0xfffffc0000000000UL)) + gaddr & _REGION2_MASK)) return -ENOMEM; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); } if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION3) { - table += (gaddr >> 31) & 0x7ff; + table += (gaddr & _REGION3_INDEX) >> _REGION3_SHIFT; if ((*table & _REGION_ENTRY_INVALID) && gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY, - gaddr & 0xffffffff80000000UL)) + gaddr & _REGION3_MASK)) return -ENOMEM; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); } - table += (gaddr >> 20) & 0x7ff; + table += (gaddr & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; /* Walk the parent mm page table */ mm = gmap->mm; pgd = pgd_offset(mm, vmaddr); @@ -771,7 +771,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = gmap->table; switch (gmap->asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: - table += (gaddr >> 53) & 0x7ff; + table += (gaddr & _REGION1_INDEX) >> _REGION1_SHIFT; if (level == 4) break; if (*table & _REGION_ENTRY_INVALID) @@ -779,7 +779,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* Fallthrough */ case _ASCE_TYPE_REGION2: - table += (gaddr >> 42) & 0x7ff; + table += (gaddr & _REGION2_INDEX) >> _REGION2_SHIFT; if (level == 3) break; if (*table & _REGION_ENTRY_INVALID) @@ -787,7 +787,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* Fallthrough */ case _ASCE_TYPE_REGION3: - table += (gaddr >> 31) & 0x7ff; + table += (gaddr & _REGION3_INDEX) >> _REGION3_SHIFT; if (level == 2) break; if (*table & _REGION_ENTRY_INVALID) @@ -795,13 +795,13 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* Fallthrough */ case _ASCE_TYPE_SEGMENT: - table += (gaddr >> 20) & 0x7ff; + table += (gaddr & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; if (level == 1) break; if (*table & _REGION_ENTRY_INVALID) return NULL; table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); - table += (gaddr >> 12) & 0xff; + table += (gaddr & _PAGE_INDEX) >> _PAGE_SHIFT; } return table; } @@ -1126,7 +1126,7 @@ static void gmap_unshadow_page(struct gmap *sg, unsigned long raddr) table = gmap_table_walk(sg, raddr, 0); /* get page table pointer */ if (!table || *table & _PAGE_INVALID) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 12) - 1); + gmap_call_notifier(sg, raddr, raddr + _PAGE_SIZE - 1); ptep_unshadow_pte(sg->mm, raddr, (pte_t *) table); } @@ -1144,7 +1144,7 @@ static void __gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr, int i; BUG_ON(!gmap_is_shadow(sg)); - for (i = 0; i < 256; i++, raddr += 1UL << 12) + for (i = 0; i < _PAGE_ENTRIES; i++, raddr += _PAGE_SIZE) pgt[i] = _PAGE_INVALID; } @@ -1164,8 +1164,8 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr) ste = gmap_table_walk(sg, raddr, 1); /* get segment pointer */ if (!ste || !(*ste & _SEGMENT_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 20) - 1); - sto = (unsigned long) (ste - ((raddr >> 20) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _SEGMENT_SIZE - 1); + sto = (unsigned long) (ste - ((raddr & _SEGMENT_INDEX) >> _SEGMENT_SHIFT)); gmap_idte_one(sto | _ASCE_TYPE_SEGMENT, raddr); pgt = (unsigned long *)(*ste & _SEGMENT_ENTRY_ORIGIN); *ste = _SEGMENT_ENTRY_EMPTY; @@ -1193,7 +1193,7 @@ static void __gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) sgt | _ASCE_TYPE_SEGMENT; - for (i = 0; i < 2048; i++, raddr += 1UL << 20) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _SEGMENT_SIZE) { if (!(sgt[i] & _SEGMENT_ENTRY_ORIGIN)) continue; pgt = (unsigned long *)(sgt[i] & _REGION_ENTRY_ORIGIN); @@ -1222,8 +1222,8 @@ static void gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr) r3e = gmap_table_walk(sg, raddr, 2); /* get region-3 pointer */ if (!r3e || !(*r3e & _REGION_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 31) - 1); - r3o = (unsigned long) (r3e - ((raddr >> 31) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _REGION3_SIZE - 1); + r3o = (unsigned long) (r3e - ((raddr & _REGION3_INDEX) >> _REGION3_SHIFT)); gmap_idte_one(r3o | _ASCE_TYPE_REGION3, raddr); sgt = (unsigned long *)(*r3e & _REGION_ENTRY_ORIGIN); *r3e = _REGION3_ENTRY_EMPTY; @@ -1231,7 +1231,7 @@ static void gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr) /* Free segment table */ page = pfn_to_page(__pa(sgt) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } /** @@ -1251,7 +1251,7 @@ static void __gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) r3t | _ASCE_TYPE_REGION3; - for (i = 0; i < 2048; i++, raddr += 1UL << 31) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _REGION3_SIZE) { if (!(r3t[i] & _REGION_ENTRY_ORIGIN)) continue; sgt = (unsigned long *)(r3t[i] & _REGION_ENTRY_ORIGIN); @@ -1260,7 +1260,7 @@ static void __gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr, /* Free segment table */ page = pfn_to_page(__pa(sgt) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } } @@ -1280,8 +1280,8 @@ static void gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr) r2e = gmap_table_walk(sg, raddr, 3); /* get region-2 pointer */ if (!r2e || !(*r2e & _REGION_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 42) - 1); - r2o = (unsigned long) (r2e - ((raddr >> 42) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _REGION2_SIZE - 1); + r2o = (unsigned long) (r2e - ((raddr & _REGION2_INDEX) >> _REGION2_SHIFT)); gmap_idte_one(r2o | _ASCE_TYPE_REGION2, raddr); r3t = (unsigned long *)(*r2e & _REGION_ENTRY_ORIGIN); *r2e = _REGION2_ENTRY_EMPTY; @@ -1289,7 +1289,7 @@ static void gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr) /* Free region 3 table */ page = pfn_to_page(__pa(r3t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } /** @@ -1309,7 +1309,7 @@ static void __gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) r2t | _ASCE_TYPE_REGION2; - for (i = 0; i < 2048; i++, raddr += 1UL << 42) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _REGION2_SIZE) { if (!(r2t[i] & _REGION_ENTRY_ORIGIN)) continue; r3t = (unsigned long *)(r2t[i] & _REGION_ENTRY_ORIGIN); @@ -1318,7 +1318,7 @@ static void __gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr, /* Free region 3 table */ page = pfn_to_page(__pa(r3t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } } @@ -1338,8 +1338,8 @@ static void gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr) r1e = gmap_table_walk(sg, raddr, 4); /* get region-1 pointer */ if (!r1e || !(*r1e & _REGION_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 53) - 1); - r1o = (unsigned long) (r1e - ((raddr >> 53) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _REGION1_SIZE - 1); + r1o = (unsigned long) (r1e - ((raddr & _REGION1_INDEX) >> _REGION1_SHIFT)); gmap_idte_one(r1o | _ASCE_TYPE_REGION1, raddr); r2t = (unsigned long *)(*r1e & _REGION_ENTRY_ORIGIN); *r1e = _REGION1_ENTRY_EMPTY; @@ -1347,7 +1347,7 @@ static void gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr) /* Free region 2 table */ page = pfn_to_page(__pa(r2t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } /** @@ -1367,7 +1367,7 @@ static void __gmap_unshadow_r1t(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) r1t | _ASCE_TYPE_REGION1; - for (i = 0; i < 2048; i++, raddr += 1UL << 53) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _REGION1_SIZE) { if (!(r1t[i] & _REGION_ENTRY_ORIGIN)) continue; r2t = (unsigned long *)(r1t[i] & _REGION_ENTRY_ORIGIN); @@ -1378,7 +1378,7 @@ static void __gmap_unshadow_r1t(struct gmap *sg, unsigned long raddr, /* Free region 2 table */ page = pfn_to_page(__pa(r2t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } } @@ -1535,7 +1535,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce, /* protect after insertion, so it will get properly invalidated */ down_read(&parent->mm->mmap_sem); rc = gmap_protect_range(parent, asce & _ASCE_ORIGIN, - ((asce & _ASCE_TABLE_LENGTH) + 1) * 4096, + ((asce & _ASCE_TABLE_LENGTH) + 1) * PAGE_SIZE, PROT_READ, PGSTE_VSIE_BIT); up_read(&parent->mm->mmap_sem); spin_lock(&parent->shadow_lock); @@ -1578,7 +1578,7 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, BUG_ON(!gmap_is_shadow(sg)); /* Allocate a shadow region second table */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = r2t & _REGION_ENTRY_ORIGIN; @@ -1614,10 +1614,10 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, } spin_unlock(&sg->guest_table_lock); /* Make r2t read-only in parent gmap page table */ - raddr = (saddr & 0xffe0000000000000UL) | _SHADOW_RMAP_REGION1; + raddr = (saddr & _REGION1_MASK) | _SHADOW_RMAP_REGION1; origin = r2t & _REGION_ENTRY_ORIGIN; - offset = ((r2t & _REGION_ENTRY_OFFSET) >> 6) * 4096; - len = ((r2t & _REGION_ENTRY_LENGTH) + 1) * 4096 - offset; + offset = ((r2t & _REGION_ENTRY_OFFSET) >> 6) * PAGE_SIZE; + len = ((r2t & _REGION_ENTRY_LENGTH) + 1) * PAGE_SIZE - offset; rc = gmap_protect_rmap(sg, raddr, origin + offset, len, PROT_READ); spin_lock(&sg->guest_table_lock); if (!rc) { @@ -1634,7 +1634,7 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, return rc; out_free: spin_unlock(&sg->guest_table_lock); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return rc; } EXPORT_SYMBOL_GPL(gmap_shadow_r2t); @@ -1662,7 +1662,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, BUG_ON(!gmap_is_shadow(sg)); /* Allocate a shadow region second table */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = r3t & _REGION_ENTRY_ORIGIN; @@ -1697,10 +1697,10 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, } spin_unlock(&sg->guest_table_lock); /* Make r3t read-only in parent gmap page table */ - raddr = (saddr & 0xfffffc0000000000UL) | _SHADOW_RMAP_REGION2; + raddr = (saddr & _REGION2_MASK) | _SHADOW_RMAP_REGION2; origin = r3t & _REGION_ENTRY_ORIGIN; - offset = ((r3t & _REGION_ENTRY_OFFSET) >> 6) * 4096; - len = ((r3t & _REGION_ENTRY_LENGTH) + 1) * 4096 - offset; + offset = ((r3t & _REGION_ENTRY_OFFSET) >> 6) * PAGE_SIZE; + len = ((r3t & _REGION_ENTRY_LENGTH) + 1) * PAGE_SIZE - offset; rc = gmap_protect_rmap(sg, raddr, origin + offset, len, PROT_READ); spin_lock(&sg->guest_table_lock); if (!rc) { @@ -1717,7 +1717,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, return rc; out_free: spin_unlock(&sg->guest_table_lock); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return rc; } EXPORT_SYMBOL_GPL(gmap_shadow_r3t); @@ -1745,7 +1745,7 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, BUG_ON(!gmap_is_shadow(sg) || (sgt & _REGION3_ENTRY_LARGE)); /* Allocate a shadow segment table */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = sgt & _REGION_ENTRY_ORIGIN; @@ -1781,10 +1781,10 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, } spin_unlock(&sg->guest_table_lock); /* Make sgt read-only in parent gmap page table */ - raddr = (saddr & 0xffffffff80000000UL) | _SHADOW_RMAP_REGION3; + raddr = (saddr & _REGION3_MASK) | _SHADOW_RMAP_REGION3; origin = sgt & _REGION_ENTRY_ORIGIN; - offset = ((sgt & _REGION_ENTRY_OFFSET) >> 6) * 4096; - len = ((sgt & _REGION_ENTRY_LENGTH) + 1) * 4096 - offset; + offset = ((sgt & _REGION_ENTRY_OFFSET) >> 6) * PAGE_SIZE; + len = ((sgt & _REGION_ENTRY_LENGTH) + 1) * PAGE_SIZE - offset; rc = gmap_protect_rmap(sg, raddr, origin + offset, len, PROT_READ); spin_lock(&sg->guest_table_lock); if (!rc) { @@ -1801,7 +1801,7 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, return rc; out_free: spin_unlock(&sg->guest_table_lock); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return rc; } EXPORT_SYMBOL_GPL(gmap_shadow_sgt); @@ -1902,7 +1902,7 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt, } spin_unlock(&sg->guest_table_lock); /* Make pgt read-only in parent gmap page table (not the pgste) */ - raddr = (saddr & 0xfffffffffff00000UL) | _SHADOW_RMAP_SEGMENT; + raddr = (saddr & _SEGMENT_MASK) | _SHADOW_RMAP_SEGMENT; origin = pgt & _SEGMENT_ENTRY_ORIGIN & PAGE_MASK; rc = gmap_protect_rmap(sg, raddr, origin, PAGE_SIZE, PROT_READ); spin_lock(&sg->guest_table_lock); @@ -2021,7 +2021,7 @@ static void gmap_shadow_notify(struct gmap *sg, unsigned long vmaddr, } /* Check for top level table */ start = sg->orig_asce & _ASCE_ORIGIN; - end = start + ((sg->orig_asce & _ASCE_TABLE_LENGTH) + 1) * 4096; + end = start + ((sg->orig_asce & _ASCE_TABLE_LENGTH) + 1) * PAGE_SIZE; if (!(sg->orig_asce & _ASCE_REAL_SPACE) && gaddr >= start && gaddr < end) { /* The complete shadow table has to go */ @@ -2032,7 +2032,7 @@ static void gmap_shadow_notify(struct gmap *sg, unsigned long vmaddr, return; } /* Remove the page table tree from on specific entry */ - head = radix_tree_delete(&sg->host_to_rmap, vmaddr >> 12); + head = radix_tree_delete(&sg->host_to_rmap, vmaddr >> PAGE_SHIFT); gmap_for_each_rmap_safe(rmap, rnext, head) { bits = rmap->raddr & _SHADOW_RMAP_MASK; raddr = rmap->raddr ^ bits; @@ -2076,7 +2076,7 @@ void ptep_notify(struct mm_struct *mm, unsigned long vmaddr, struct gmap *gmap, *sg, *next; offset = ((unsigned long) pte) & (255 * sizeof(pte_t)); - offset = offset * (4096 / sizeof(pte_t)); + offset = offset * (PAGE_SIZE / sizeof(pte_t)); rcu_read_lock(); list_for_each_entry_rcu(gmap, &mm->context.gmap_list, list) { spin_lock(&gmap->guest_table_lock); @@ -2120,6 +2120,37 @@ static inline void thp_split_mm(struct mm_struct *mm) #endif } +/* + * Remove all empty zero pages from the mapping for lazy refaulting + * - This must be called after mm->context.has_pgste is set, to avoid + * future creation of zero pages + * - This must be called after THP was enabled + */ +static int __zap_zero_pages(pmd_t *pmd, unsigned long start, + unsigned long end, struct mm_walk *walk) +{ + unsigned long addr; + + for (addr = start; addr != end; addr += PAGE_SIZE) { + pte_t *ptep; + spinlock_t *ptl; + + ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); + if (is_zero_pfn(pte_pfn(*ptep))) + ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID)); + pte_unmap_unlock(ptep, ptl); + } + return 0; +} + +static inline void zap_zero_pages(struct mm_struct *mm) +{ + struct mm_walk walk = { .pmd_entry = __zap_zero_pages }; + + walk.mm = mm; + walk_page_range(0, TASK_SIZE, &walk); +} + /* * switch on pgstes for its userspace process (for kvm) */ @@ -2137,6 +2168,7 @@ int s390_enable_sie(void) mm->context.has_pgste = 1; /* split thp mappings and disable thp for future mappings */ thp_split_mm(mm); + zap_zero_pages(mm); up_write(&mm->mmap_sem); return 0; } @@ -2149,13 +2181,6 @@ EXPORT_SYMBOL_GPL(s390_enable_sie); static int __s390_enable_skey(pte_t *pte, unsigned long addr, unsigned long next, struct mm_walk *walk) { - /* - * Remove all zero page mappings, - * after establishing a policy to forbid zero page mappings - * following faults for that page will get fresh anonymous pages - */ - if (is_zero_pfn(pte_pfn(*pte))) - ptep_xchg_direct(walk->mm, addr, pte, __pte(_PAGE_INVALID)); /* Clear storage key */ ptep_zap_key(walk->mm, addr, pte); return 0; diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 8ecc25e760fa6dfba0f082cfd8dff38b8c33d9e9..98ffe3ee9411ad23798c7ef896783ebd4d6edcfc 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -56,13 +56,12 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask, result; struct page *head, *page; + unsigned long mask; int refs; - result = write ? 0 : _SEGMENT_ENTRY_PROTECT; - mask = result | _SEGMENT_ENTRY_INVALID; - if ((pmd_val(pmd) & mask) != result) + mask = (write ? _SEGMENT_ENTRY_PROTECT : 0) | _SEGMENT_ENTRY_INVALID; + if ((pmd_val(pmd) & mask) != 0) return 0; VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT)); diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 8111694ce55a8f9f081e070628cf0114eb396565..3b567838b905f99ff8a755a90647520ba9348d00 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -84,7 +85,7 @@ void __init paging_init(void) psw_t psw; init_mm.pgd = swapper_pg_dir; - if (VMALLOC_END > (1UL << 42)) { + if (VMALLOC_END > _REGION2_SIZE) { asce_bits = _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH; pgd_type = _REGION2_ENTRY_EMPTY; } else { @@ -93,8 +94,7 @@ void __init paging_init(void) } init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; S390_lowcore.kernel_asce = init_mm.context.asce; - clear_table((unsigned long *) init_mm.pgd, pgd_type, - sizeof(unsigned long)*2048); + crst_table_init((unsigned long *) init_mm.pgd, pgd_type); vmem_map_init(); /* enable virtual mapping in kernel mode */ @@ -137,6 +137,8 @@ void __init mem_init(void) free_all_bootmem(); setup_zero_pages(); /* Setup zeroed pages. */ + cmma_init_nodat(); + mem_init_print_info(NULL); } @@ -166,6 +168,58 @@ unsigned long memory_block_size_bytes(void) } #ifdef CONFIG_MEMORY_HOTPLUG + +#ifdef CONFIG_CMA + +/* Prevent memory blocks which contain cma regions from going offline */ + +struct s390_cma_mem_data { + unsigned long start; + unsigned long end; +}; + +static int s390_cma_check_range(struct cma *cma, void *data) +{ + struct s390_cma_mem_data *mem_data; + unsigned long start, end; + + mem_data = data; + start = cma_get_base(cma); + end = start + cma_get_size(cma); + if (end < mem_data->start) + return 0; + if (start >= mem_data->end) + return 0; + return -EBUSY; +} + +static int s390_cma_mem_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct s390_cma_mem_data mem_data; + struct memory_notify *arg; + int rc = 0; + + arg = data; + mem_data.start = arg->start_pfn << PAGE_SHIFT; + mem_data.end = mem_data.start + (arg->nr_pages << PAGE_SHIFT); + if (action == MEM_GOING_OFFLINE) + rc = cma_for_each_area(s390_cma_check_range, &mem_data); + return notifier_from_errno(rc); +} + +static struct notifier_block s390_cma_mem_nb = { + .notifier_call = s390_cma_mem_notifier, +}; + +static int __init s390_cma_mem_init(void) +{ + return register_memory_notifier(&s390_cma_mem_nb); +} +device_initcall(s390_cma_mem_init); + +#endif /* CONFIG_CMA */ + int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) { unsigned long start_pfn = PFN_DOWN(start); diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 2e10d2b8ad359607981ce381e27c3bf22e2e184d..5bea139517a2edc21dc50074d2c2e9a94dabb19e 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -119,7 +119,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, return addr; check_asce_limit: - if (addr + len > current->mm->context.asce_limit) { + if (addr + len > current->mm->context.asce_limit && + addr + len <= TASK_SIZE) { rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; @@ -183,7 +184,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, } check_asce_limit: - if (addr + len > current->mm->context.asce_limit) { + if (addr + len > current->mm->context.asce_limit && + addr + len <= TASK_SIZE) { rc = crst_table_upgrade(mm, addr + len); if (rc) return (unsigned long) rc; diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index 69a7b01ae746f02c3ab6dea4bf158e8fe04efd41..07fa7b8ae233a6eb700726fc649871ec0fb174c3 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c @@ -10,9 +10,10 @@ #include #include #include +#include #include #include - +#include #include static int cmma_flag = 1; @@ -36,14 +37,16 @@ __setup("cmma=", cmma); static inline int cmma_test_essa(void) { register unsigned long tmp asm("0") = 0; - register int rc asm("1") = -EOPNOTSUPP; + register int rc asm("1"); + /* test ESSA_GET_STATE */ asm volatile( - " .insn rrf,0xb9ab0000,%1,%1,0,0\n" + " .insn rrf,0xb9ab0000,%1,%1,%2,0\n" "0: la %0,0\n" "1:\n" EX_TABLE(0b,1b) - : "+&d" (rc), "+&d" (tmp)); + : "=&d" (rc), "+&d" (tmp) + : "i" (ESSA_GET_STATE), "0" (-EOPNOTSUPP)); return rc; } @@ -51,11 +54,26 @@ void __init cmma_init(void) { if (!cmma_flag) return; - if (cmma_test_essa()) + if (cmma_test_essa()) { cmma_flag = 0; + return; + } + if (test_facility(147)) + cmma_flag = 2; } -static inline void set_page_unstable(struct page *page, int order) +static inline unsigned char get_page_state(struct page *page) +{ + unsigned char state; + + asm volatile(" .insn rrf,0xb9ab0000,%0,%1,%2,0" + : "=&d" (state) + : "a" (page_to_phys(page)), + "i" (ESSA_GET_STATE)); + return state & 0x3f; +} + +static inline void set_page_unused(struct page *page, int order) { int i, rc; @@ -66,14 +84,18 @@ static inline void set_page_unstable(struct page *page, int order) "i" (ESSA_SET_UNUSED)); } -void arch_free_page(struct page *page, int order) +static inline void set_page_stable_dat(struct page *page, int order) { - if (!cmma_flag) - return; - set_page_unstable(page, order); + int i, rc; + + for (i = 0; i < (1 << order); i++) + asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" + : "=&d" (rc) + : "a" (page_to_phys(page + i)), + "i" (ESSA_SET_STABLE)); } -static inline void set_page_stable(struct page *page, int order) +static inline void set_page_stable_nodat(struct page *page, int order) { int i, rc; @@ -81,14 +103,154 @@ static inline void set_page_stable(struct page *page, int order) asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" : "=&d" (rc) : "a" (page_to_phys(page + i)), - "i" (ESSA_SET_STABLE)); + "i" (ESSA_SET_STABLE_NODAT)); +} + +static void mark_kernel_pmd(pud_t *pud, unsigned long addr, unsigned long end) +{ + unsigned long next; + struct page *page; + pmd_t *pmd; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if (pmd_none(*pmd) || pmd_large(*pmd)) + continue; + page = virt_to_page(pmd_val(*pmd)); + set_bit(PG_arch_1, &page->flags); + } while (pmd++, addr = next, addr != end); +} + +static void mark_kernel_pud(p4d_t *p4d, unsigned long addr, unsigned long end) +{ + unsigned long next; + struct page *page; + pud_t *pud; + int i; + + pud = pud_offset(p4d, addr); + do { + next = pud_addr_end(addr, end); + if (pud_none(*pud) || pud_large(*pud)) + continue; + if (!pud_folded(*pud)) { + page = virt_to_page(pud_val(*pud)); + for (i = 0; i < 3; i++) + set_bit(PG_arch_1, &page[i].flags); + } + mark_kernel_pmd(pud, addr, next); + } while (pud++, addr = next, addr != end); +} + +static void mark_kernel_p4d(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + unsigned long next; + struct page *page; + p4d_t *p4d; + int i; + + p4d = p4d_offset(pgd, addr); + do { + next = p4d_addr_end(addr, end); + if (p4d_none(*p4d)) + continue; + if (!p4d_folded(*p4d)) { + page = virt_to_page(p4d_val(*p4d)); + for (i = 0; i < 3; i++) + set_bit(PG_arch_1, &page[i].flags); + } + mark_kernel_pud(p4d, addr, next); + } while (p4d++, addr = next, addr != end); +} + +static void mark_kernel_pgd(void) +{ + unsigned long addr, next; + struct page *page; + pgd_t *pgd; + int i; + + addr = 0; + pgd = pgd_offset_k(addr); + do { + next = pgd_addr_end(addr, MODULES_END); + if (pgd_none(*pgd)) + continue; + if (!pgd_folded(*pgd)) { + page = virt_to_page(pgd_val(*pgd)); + for (i = 0; i < 3; i++) + set_bit(PG_arch_1, &page[i].flags); + } + mark_kernel_p4d(pgd, addr, next); + } while (pgd++, addr = next, addr != MODULES_END); +} + +void __init cmma_init_nodat(void) +{ + struct memblock_region *reg; + struct page *page; + unsigned long start, end, ix; + + if (cmma_flag < 2) + return; + /* Mark pages used in kernel page tables */ + mark_kernel_pgd(); + + /* Set all kernel pages not used for page tables to stable/no-dat */ + for_each_memblock(memory, reg) { + start = memblock_region_memory_base_pfn(reg); + end = memblock_region_memory_end_pfn(reg); + page = pfn_to_page(start); + for (ix = start; ix < end; ix++, page++) { + if (__test_and_clear_bit(PG_arch_1, &page->flags)) + continue; /* skip page table pages */ + if (!list_empty(&page->lru)) + continue; /* skip free pages */ + set_page_stable_nodat(page, 0); + } + } +} + +void arch_free_page(struct page *page, int order) +{ + if (!cmma_flag) + return; + set_page_unused(page, order); } void arch_alloc_page(struct page *page, int order) { if (!cmma_flag) return; - set_page_stable(page, order); + if (cmma_flag < 2) + set_page_stable_dat(page, order); + else + set_page_stable_nodat(page, order); +} + +void arch_set_page_dat(struct page *page, int order) +{ + if (!cmma_flag) + return; + set_page_stable_dat(page, order); +} + +void arch_set_page_nodat(struct page *page, int order) +{ + if (cmma_flag < 2) + return; + set_page_stable_nodat(page, order); +} + +int arch_test_page_nodat(struct page *page) +{ + unsigned char state; + + if (cmma_flag < 2) + return 0; + state = get_page_state(page); + return !!(state & 0x20); } void arch_set_page_states(int make_stable) @@ -108,9 +270,9 @@ void arch_set_page_states(int make_stable) list_for_each(l, &zone->free_area[order].free_list[t]) { page = list_entry(l, struct page, lru); if (make_stable) - set_page_stable(page, order); + set_page_stable_dat(page, 0); else - set_page_unstable(page, order); + set_page_unused(page, order); } } spin_unlock_irqrestore(&zone->lock, flags); diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 1804815892465834c56b5a6bfcf90d3b86359b20..552f898dfa74c1452388ff202ac5502a19e31748 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -191,7 +192,7 @@ static int split_pud_page(pud_t *pudp, unsigned long addr) pud_t new; int i, ro, nx; - pm_dir = vmem_pmd_alloc(); + pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY); if (!pm_dir) return -ENOMEM; pmd_addr = pud_pfn(*pudp) << PAGE_SHIFT; @@ -328,7 +329,7 @@ static void ipte_range(pte_t *pte, unsigned long address, int nr) return; } for (i = 0; i < nr; i++) { - __ptep_ipte(address, pte, IPTE_GLOBAL); + __ptep_ipte(address, pte, 0, 0, IPTE_GLOBAL); address += PAGE_SIZE; pte++; } diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index 18918e394ce4b67614f9ac0e70a7a112f73fbc6a..05f1f27e6708f31642b9297013109702127c73b2 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -57,6 +57,7 @@ unsigned long *crst_table_alloc(struct mm_struct *mm) if (!page) return NULL; + arch_set_page_dat(page, 2); return (unsigned long *) page_to_phys(page); } @@ -82,7 +83,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end) int rc, notify; /* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */ - BUG_ON(mm->context.asce_limit < (1UL << 42)); + VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE); if (end >= TASK_SIZE_MAX) return -ENOMEM; rc = 0; @@ -95,11 +96,11 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end) } spin_lock_bh(&mm->page_table_lock); pgd = (unsigned long *) mm->pgd; - if (mm->context.asce_limit == (1UL << 42)) { + if (mm->context.asce_limit == _REGION2_SIZE) { crst_table_init(table, _REGION2_ENTRY_EMPTY); p4d_populate(mm, (p4d_t *) table, (pud_t *) pgd); mm->pgd = (pgd_t *) table; - mm->context.asce_limit = 1UL << 53; + mm->context.asce_limit = _REGION1_SIZE; mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION2; } else { @@ -123,7 +124,7 @@ void crst_table_downgrade(struct mm_struct *mm) pgd_t *pgd; /* downgrade should only happen from 3 to 2 levels (compat only) */ - BUG_ON(mm->context.asce_limit != (1UL << 42)); + VM_BUG_ON(mm->context.asce_limit != _REGION2_SIZE); if (current->active_mm == mm) { clear_user_asce(); @@ -132,7 +133,7 @@ void crst_table_downgrade(struct mm_struct *mm) pgd = mm->pgd; mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); - mm->context.asce_limit = 1UL << 31; + mm->context.asce_limit = _REGION3_SIZE; mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; crst_table_free(mm, (unsigned long *) pgd); @@ -187,7 +188,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) /* Try to get a fragment of a 4K page as a 2K page table */ if (!mm_alloc_pgste(mm)) { table = NULL; - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); if (!list_empty(&mm->context.pgtable_list)) { page = list_first_entry(&mm->context.pgtable_list, struct page, lru); @@ -202,7 +203,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) list_del(&page->lru); } } - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); if (table) return table; } @@ -214,6 +215,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) __free_page(page); return NULL; } + arch_set_page_dat(page, 0); /* Initialize page table */ table = (unsigned long *) page_to_phys(page); if (mm_alloc_pgste(mm)) { @@ -225,9 +227,9 @@ unsigned long *page_table_alloc(struct mm_struct *mm) /* Return the first 2K fragment of the page */ atomic_set(&page->_mapcount, 1); clear_table(table, _PAGE_INVALID, PAGE_SIZE); - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); list_add(&page->lru, &mm->context.pgtable_list); - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); } return table; } @@ -241,13 +243,13 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) if (!mm_alloc_pgste(mm)) { /* Free 2K page table fragment of a 4K page */ bit = (__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)); - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); mask = atomic_xor_bits(&page->_mapcount, 1U << bit); if (mask & 3) list_add(&page->lru, &mm->context.pgtable_list); else list_del(&page->lru); - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); if (mask != 0) return; } @@ -273,13 +275,13 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table, return; } bit = (__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t)); - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); mask = atomic_xor_bits(&page->_mapcount, 0x11U << bit); if (mask & 3) list_add_tail(&page->lru, &mm->context.pgtable_list); else list_del(&page->lru); - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); table = (unsigned long *) (__pa(table) | (1U << bit)); tlb_remove_table(tlb, table); } diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 4a1f7366b17aeffacb6c766ab891227e2609f1b9..ae677f814bc07a406f7f996a81ed2db65718f5ff 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -25,8 +25,49 @@ #include #include +static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, int nodat) +{ + unsigned long opt, asce; + + if (MACHINE_HAS_TLB_GUEST) { + opt = 0; + asce = READ_ONCE(mm->context.gmap_asce); + if (asce == 0UL || nodat) + opt |= IPTE_NODAT; + if (asce != -1UL) { + asce = asce ? : mm->context.asce; + opt |= IPTE_GUEST_ASCE; + } + __ptep_ipte(addr, ptep, opt, asce, IPTE_LOCAL); + } else { + __ptep_ipte(addr, ptep, 0, 0, IPTE_LOCAL); + } +} + +static inline void ptep_ipte_global(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, int nodat) +{ + unsigned long opt, asce; + + if (MACHINE_HAS_TLB_GUEST) { + opt = 0; + asce = READ_ONCE(mm->context.gmap_asce); + if (asce == 0UL || nodat) + opt |= IPTE_NODAT; + if (asce != -1UL) { + asce = asce ? : mm->context.asce; + opt |= IPTE_GUEST_ASCE; + } + __ptep_ipte(addr, ptep, opt, asce, IPTE_GLOBAL); + } else { + __ptep_ipte(addr, ptep, 0, 0, IPTE_GLOBAL); + } +} + static inline pte_t ptep_flush_direct(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) + unsigned long addr, pte_t *ptep, + int nodat) { pte_t old; @@ -36,15 +77,16 @@ static inline pte_t ptep_flush_direct(struct mm_struct *mm, atomic_inc(&mm->context.flush_count); if (MACHINE_HAS_TLB_LC && cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __ptep_ipte(addr, ptep, IPTE_LOCAL); + ptep_ipte_local(mm, addr, ptep, nodat); else - __ptep_ipte(addr, ptep, IPTE_GLOBAL); + ptep_ipte_global(mm, addr, ptep, nodat); atomic_dec(&mm->context.flush_count); return old; } static inline pte_t ptep_flush_lazy(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) + unsigned long addr, pte_t *ptep, + int nodat) { pte_t old; @@ -57,7 +99,7 @@ static inline pte_t ptep_flush_lazy(struct mm_struct *mm, pte_val(*ptep) |= _PAGE_INVALID; mm->context.flush_mm = 1; } else - __ptep_ipte(addr, ptep, IPTE_GLOBAL); + ptep_ipte_global(mm, addr, ptep, nodat); atomic_dec(&mm->context.flush_count); return old; } @@ -229,10 +271,12 @@ pte_t ptep_xchg_direct(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; pte_t old; + int nodat; preempt_disable(); pgste = ptep_xchg_start(mm, addr, ptep); - old = ptep_flush_direct(mm, addr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + old = ptep_flush_direct(mm, addr, ptep, nodat); old = ptep_xchg_commit(mm, addr, ptep, pgste, old, new); preempt_enable(); return old; @@ -244,10 +288,12 @@ pte_t ptep_xchg_lazy(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; pte_t old; + int nodat; preempt_disable(); pgste = ptep_xchg_start(mm, addr, ptep); - old = ptep_flush_lazy(mm, addr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + old = ptep_flush_lazy(mm, addr, ptep, nodat); old = ptep_xchg_commit(mm, addr, ptep, pgste, old, new); preempt_enable(); return old; @@ -259,10 +305,12 @@ pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; pte_t old; + int nodat; preempt_disable(); pgste = ptep_xchg_start(mm, addr, ptep); - old = ptep_flush_lazy(mm, addr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + old = ptep_flush_lazy(mm, addr, ptep, nodat); if (mm_has_pgste(mm)) { pgste = pgste_update_all(old, pgste, mm); pgste_set(ptep, pgste); @@ -290,6 +338,28 @@ void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, } EXPORT_SYMBOL(ptep_modify_prot_commit); +static inline void pmdp_idte_local(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_LOCAL); + else + __pmdp_idte(addr, pmdp, 0, 0, IDTE_LOCAL); +} + +static inline void pmdp_idte_global(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_GLOBAL); + else if (MACHINE_HAS_IDTE) + __pmdp_idte(addr, pmdp, 0, 0, IDTE_GLOBAL); + else + __pmdp_csp(pmdp); +} + static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp) { @@ -298,16 +368,12 @@ static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, old = *pmdp; if (pmd_val(old) & _SEGMENT_ENTRY_INVALID) return old; - if (!MACHINE_HAS_IDTE) { - __pmdp_csp(pmdp); - return old; - } atomic_inc(&mm->context.flush_count); if (MACHINE_HAS_TLB_LC && cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __pmdp_idte(addr, pmdp, IDTE_LOCAL); + pmdp_idte_local(mm, addr, pmdp); else - __pmdp_idte(addr, pmdp, IDTE_GLOBAL); + pmdp_idte_global(mm, addr, pmdp); atomic_dec(&mm->context.flush_count); return old; } @@ -325,10 +391,9 @@ static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm, cpumask_of(smp_processor_id()))) { pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID; mm->context.flush_mm = 1; - } else if (MACHINE_HAS_IDTE) - __pmdp_idte(addr, pmdp, IDTE_GLOBAL); - else - __pmdp_csp(pmdp); + } else { + pmdp_idte_global(mm, addr, pmdp); + } atomic_dec(&mm->context.flush_count); return old; } @@ -359,28 +424,46 @@ pmd_t pmdp_xchg_lazy(struct mm_struct *mm, unsigned long addr, } EXPORT_SYMBOL(pmdp_xchg_lazy); -static inline pud_t pudp_flush_direct(struct mm_struct *mm, - unsigned long addr, pud_t *pudp) +static inline void pudp_idte_local(struct mm_struct *mm, + unsigned long addr, pud_t *pudp) { - pud_t old; + if (MACHINE_HAS_TLB_GUEST) + __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_LOCAL); + else + __pudp_idte(addr, pudp, 0, 0, IDTE_LOCAL); +} - old = *pudp; - if (pud_val(old) & _REGION_ENTRY_INVALID) - return old; - if (!MACHINE_HAS_IDTE) { +static inline void pudp_idte_global(struct mm_struct *mm, + unsigned long addr, pud_t *pudp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_GLOBAL); + else if (MACHINE_HAS_IDTE) + __pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL); + else /* * Invalid bit position is the same for pmd and pud, so we can * re-use _pmd_csp() here */ __pmdp_csp((pmd_t *) pudp); +} + +static inline pud_t pudp_flush_direct(struct mm_struct *mm, + unsigned long addr, pud_t *pudp) +{ + pud_t old; + + old = *pudp; + if (pud_val(old) & _REGION_ENTRY_INVALID) return old; - } atomic_inc(&mm->context.flush_count); if (MACHINE_HAS_TLB_LC && cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __pudp_idte(addr, pudp, IDTE_LOCAL); + pudp_idte_local(mm, addr, pudp); else - __pudp_idte(addr, pudp, IDTE_GLOBAL); + pudp_idte_global(mm, addr, pudp); atomic_dec(&mm->context.flush_count); return old; } @@ -482,7 +565,7 @@ int ptep_force_prot(struct mm_struct *mm, unsigned long addr, { pte_t entry; pgste_t pgste; - int pte_i, pte_p; + int pte_i, pte_p, nodat; pgste = pgste_get_lock(ptep); entry = *ptep; @@ -495,13 +578,14 @@ int ptep_force_prot(struct mm_struct *mm, unsigned long addr, return -EAGAIN; } /* Change access rights and set pgste bit */ + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); if (prot == PROT_NONE && !pte_i) { - ptep_flush_direct(mm, addr, ptep); + ptep_flush_direct(mm, addr, ptep, nodat); pgste = pgste_update_all(entry, pgste, mm); pte_val(entry) |= _PAGE_INVALID; } if (prot == PROT_READ && !pte_p) { - ptep_flush_direct(mm, addr, ptep); + ptep_flush_direct(mm, addr, ptep, nodat); pte_val(entry) &= ~_PAGE_INVALID; pte_val(entry) |= _PAGE_PROTECT; } @@ -541,10 +625,12 @@ int ptep_shadow_pte(struct mm_struct *mm, unsigned long saddr, void ptep_unshadow_pte(struct mm_struct *mm, unsigned long saddr, pte_t *ptep) { pgste_t pgste; + int nodat; pgste = pgste_get_lock(ptep); /* notifier is called by the caller */ - ptep_flush_direct(mm, saddr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + ptep_flush_direct(mm, saddr, ptep, nodat); /* don't touch the storage key - it belongs to parent pgste */ pgste = pgste_set_pte(ptep, pgste, __pte(_PAGE_INVALID)); pgste_set_unlock(ptep, pgste); @@ -617,6 +703,7 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr) pte_t *ptep; pte_t pte; bool dirty; + int nodat; pgd = pgd_offset(mm, addr); p4d = p4d_alloc(mm, pgd, addr); @@ -645,7 +732,8 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr) pte = *ptep; if (dirty && (pte_val(pte) & _PAGE_PRESENT)) { pgste = pgste_pte_notify(mm, addr, ptep, pgste); - __ptep_ipte(addr, ptep, IPTE_GLOBAL); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + ptep_ipte_global(mm, addr, ptep, nodat); if (MACHINE_HAS_ESOP || !(pte_val(pte) & _PAGE_WRITE)) pte_val(pte) |= _PAGE_PROTECT; else @@ -831,7 +919,7 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, case ESSA_GET_STATE: break; case ESSA_SET_STABLE: - pgstev &= ~_PGSTE_GPS_USAGE_MASK; + pgstev &= ~(_PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT); pgstev |= _PGSTE_GPS_USAGE_STABLE; break; case ESSA_SET_UNUSED: @@ -877,6 +965,10 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, pgstev |= _PGSTE_GPS_USAGE_STABLE; } break; + case ESSA_SET_STABLE_NODAT: + pgstev &= ~_PGSTE_GPS_USAGE_MASK; + pgstev |= _PGSTE_GPS_USAGE_STABLE | _PGSTE_GPS_NODAT; + break; default: /* we should never get here! */ break; diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index d8398962a7236e2264a0424b0bc4a4d4befd9493..c0af0d7b6e5feeb348f8c7bfd2e107a3ff4ab295 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -38,37 +38,14 @@ static void __ref *vmem_alloc_pages(unsigned int order) return (void *) memblock_alloc(size, size); } -static inline p4d_t *vmem_p4d_alloc(void) +void *vmem_crst_alloc(unsigned long val) { - p4d_t *p4d = NULL; + unsigned long *table; - p4d = vmem_alloc_pages(2); - if (!p4d) - return NULL; - clear_table((unsigned long *) p4d, _REGION2_ENTRY_EMPTY, PAGE_SIZE * 4); - return p4d; -} - -static inline pud_t *vmem_pud_alloc(void) -{ - pud_t *pud = NULL; - - pud = vmem_alloc_pages(2); - if (!pud) - return NULL; - clear_table((unsigned long *) pud, _REGION3_ENTRY_EMPTY, PAGE_SIZE * 4); - return pud; -} - -pmd_t *vmem_pmd_alloc(void) -{ - pmd_t *pmd = NULL; - - pmd = vmem_alloc_pages(2); - if (!pmd) - return NULL; - clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE * 4); - return pmd; + table = vmem_alloc_pages(CRST_ALLOC_ORDER); + if (table) + crst_table_init(table, val); + return table; } pte_t __ref *vmem_pte_alloc(void) @@ -114,14 +91,14 @@ static int vmem_add_mem(unsigned long start, unsigned long size) while (address < end) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { - p4_dir = vmem_p4d_alloc(); + p4_dir = vmem_crst_alloc(_REGION2_ENTRY_EMPTY); if (!p4_dir) goto out; pgd_populate(&init_mm, pg_dir, p4_dir); } p4_dir = p4d_offset(pg_dir, address); if (p4d_none(*p4_dir)) { - pu_dir = vmem_pud_alloc(); + pu_dir = vmem_crst_alloc(_REGION3_ENTRY_EMPTY); if (!pu_dir) goto out; p4d_populate(&init_mm, p4_dir, pu_dir); @@ -136,7 +113,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size) continue; } if (pud_none(*pu_dir)) { - pm_dir = vmem_pmd_alloc(); + pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY); if (!pm_dir) goto out; pud_populate(&init_mm, pu_dir, pm_dir); @@ -253,7 +230,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) for (address = start; address < end;) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { - p4_dir = vmem_p4d_alloc(); + p4_dir = vmem_crst_alloc(_REGION2_ENTRY_EMPTY); if (!p4_dir) goto out; pgd_populate(&init_mm, pg_dir, p4_dir); @@ -261,7 +238,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) p4_dir = p4d_offset(pg_dir, address); if (p4d_none(*p4_dir)) { - pu_dir = vmem_pud_alloc(); + pu_dir = vmem_crst_alloc(_REGION3_ENTRY_EMPTY); if (!pu_dir) goto out; p4d_populate(&init_mm, p4_dir, pu_dir); @@ -269,7 +246,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) pu_dir = pud_offset(p4_dir, address); if (pud_none(*pu_dir)) { - pm_dir = vmem_pmd_alloc(); + pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY); if (!pm_dir) goto out; pud_populate(&init_mm, pu_dir, pm_dir); diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 01c6fbc3e85b62fdec83bacea0f76a88126bfe84..8ec88497a28dace3e25e371e4347693c053678eb 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -1093,15 +1093,27 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i case BPF_JMP | BPF_JSGT | BPF_K: /* ((s64) dst > (s64) imm) */ mask = 0x2000; /* jh */ goto branch_ks; + case BPF_JMP | BPF_JSLT | BPF_K: /* ((s64) dst < (s64) imm) */ + mask = 0x4000; /* jl */ + goto branch_ks; case BPF_JMP | BPF_JSGE | BPF_K: /* ((s64) dst >= (s64) imm) */ mask = 0xa000; /* jhe */ goto branch_ks; + case BPF_JMP | BPF_JSLE | BPF_K: /* ((s64) dst <= (s64) imm) */ + mask = 0xc000; /* jle */ + goto branch_ks; case BPF_JMP | BPF_JGT | BPF_K: /* (dst_reg > imm) */ mask = 0x2000; /* jh */ goto branch_ku; + case BPF_JMP | BPF_JLT | BPF_K: /* (dst_reg < imm) */ + mask = 0x4000; /* jl */ + goto branch_ku; case BPF_JMP | BPF_JGE | BPF_K: /* (dst_reg >= imm) */ mask = 0xa000; /* jhe */ goto branch_ku; + case BPF_JMP | BPF_JLE | BPF_K: /* (dst_reg <= imm) */ + mask = 0xc000; /* jle */ + goto branch_ku; case BPF_JMP | BPF_JNE | BPF_K: /* (dst_reg != imm) */ mask = 0x7000; /* jne */ goto branch_ku; @@ -1119,15 +1131,27 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i case BPF_JMP | BPF_JSGT | BPF_X: /* ((s64) dst > (s64) src) */ mask = 0x2000; /* jh */ goto branch_xs; + case BPF_JMP | BPF_JSLT | BPF_X: /* ((s64) dst < (s64) src) */ + mask = 0x4000; /* jl */ + goto branch_xs; case BPF_JMP | BPF_JSGE | BPF_X: /* ((s64) dst >= (s64) src) */ mask = 0xa000; /* jhe */ goto branch_xs; + case BPF_JMP | BPF_JSLE | BPF_X: /* ((s64) dst <= (s64) src) */ + mask = 0xc000; /* jle */ + goto branch_xs; case BPF_JMP | BPF_JGT | BPF_X: /* (dst > src) */ mask = 0x2000; /* jh */ goto branch_xu; + case BPF_JMP | BPF_JLT | BPF_X: /* (dst < src) */ + mask = 0x4000; /* jl */ + goto branch_xu; case BPF_JMP | BPF_JGE | BPF_X: /* (dst >= src) */ mask = 0xa000; /* jhe */ goto branch_xu; + case BPF_JMP | BPF_JLE | BPF_X: /* (dst <= src) */ + mask = 0xc000; /* jle */ + goto branch_xu; case BPF_JMP | BPF_JNE | BPF_X: /* (dst != src) */ mask = 0x7000; /* jne */ goto branch_xu; @@ -1253,7 +1277,8 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp) insn_count = bpf_jit_insn(jit, fp, i); if (insn_count < 0) return -1; - jit->addrs[i + 1] = jit->prg; /* Next instruction address */ + /* Next instruction address */ + jit->addrs[i + insn_count] = jit->prg; } bpf_jit_epilogue(jit); diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 7b30af5da222a947cceb1cf226945884e0682847..a25d95a6612dd90f9ff009764a1d318e087495b0 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -262,10 +262,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) return rc; } -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) @@ -776,6 +772,7 @@ void pcibios_remove_bus(struct pci_bus *bus) zpci_exit_slot(zdev); zpci_cleanup_bus_resources(zdev); + zpci_destroy_iommu(zdev); zpci_free_domain(zdev); spin_lock(&zpci_list_lock); @@ -848,11 +845,15 @@ int zpci_create_device(struct zpci_dev *zdev) if (rc) goto out; + rc = zpci_init_iommu(zdev); + if (rc) + goto out_free; + mutex_init(&zdev->lock); if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { rc = zpci_enable_device(zdev); if (rc) - goto out_free; + goto out_destroy_iommu; } rc = zpci_scan_bus(zdev); if (rc) @@ -869,6 +870,8 @@ int zpci_create_device(struct zpci_dev *zdev) out_disable: if (zdev->state == ZPCI_FN_STATE_ONLINE) zpci_disable_device(zdev); +out_destroy_iommu: + zpci_destroy_iommu(zdev); out_free: zpci_free_domain(zdev); out: diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index bd534b4d40e3f3a5db21db39f1f1d20e714d7bd5..0ae3936e266fe707e29a8d6169e6a002de1b49a5 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -24,6 +24,14 @@ bool zpci_unique_uid; +static void update_uid_checking(bool new) +{ + if (zpci_unique_uid != new) + zpci_dbg(1, "uid checking:%d\n", new); + + zpci_unique_uid = new; +} + static inline void zpci_err_clp(unsigned int rsp, int rc) { struct { @@ -319,7 +327,7 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data, goto out; } - zpci_unique_uid = rrb->response.uid_checking; + update_uid_checking(rrb->response.uid_checking); WARN_ON_ONCE(rrb->response.entry_size != sizeof(struct clp_fh_list_entry)); diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index 025ea20fc4b4b8d0abb0ec038f99599cecb289f2..70dd8f17d0547ebc2c2ee059b0e54834b67c0f79 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c @@ -41,7 +41,7 @@ static struct facility_def facility_defs[] = { 27, /* mvcos */ 32, /* compare and swap and store */ 33, /* compare and swap and store 2 */ - 34, /* general extension facility */ + 34, /* general instructions extension */ 35, /* execute extensions */ #endif #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES @@ -53,6 +53,9 @@ static struct facility_def facility_defs[] = { #endif #ifdef CONFIG_HAVE_MARCH_Z13_FEATURES 53, /* load-and-zero-rightmost-byte, etc. */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z14_FEATURES + 58, /* miscellaneous-instruction-extension 2 */ #endif -1 /* END */ } @@ -80,6 +83,7 @@ static struct facility_def facility_defs[] = { 78, /* enhanced-DAT 2 */ 130, /* instruction-execution-protection */ 131, /* enhanced-SOP 2 and side-effect */ + 139, /* multiple epoch facility */ 146, /* msa extension 8 */ -1 /* END */ } diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 5de60a77eaa1abf56bde5814ac5ca7d2f0ed7014..0bcbe58b11e956bb1cb714396528810903dfe1e5 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index e5335123b5e99c098f15d2a284e1d28c605277c3..72b72e50a92edf3feb2bb09c84d8b572a9344e00 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -28,14 +27,10 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -51,8 +46,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -82,7 +75,6 @@ CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y CONFIG_MMC_SPI=y @@ -110,8 +102,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/apsh4a3a_defconfig b/arch/sh/configs/apsh4a3a_defconfig index 6cb327977d1379a806ff7590bcee1ae6bd51a71b..4710df43a5b54f78862f454ab267bde3eb56ed13 100644 --- a/arch/sh/configs/apsh4a3a_defconfig +++ b/arch/sh/configs/apsh4a3a_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -28,15 +27,11 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -46,8 +41,6 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set @@ -66,7 +59,6 @@ CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y @@ -96,7 +88,6 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_FTRACE is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig index fe45d2c9b15121ab75fc7291a56a13ed9ea3e874..825c641726c43193ea709b9f2c53f878f70fbaaa 100644 --- a/arch/sh/configs/apsh4ad0a_defconfig +++ b/arch/sh/configs/apsh4ad0a_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -53,7 +52,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_NET_KEY=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -70,8 +68,6 @@ CONFIG_NETDEVICES=y CONFIG_MDIO_BITBANG=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set @@ -83,7 +79,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FB_SH7785FB=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -124,6 +119,5 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_VM=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_DWARF_UNWINDER=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig index 67e150631ea514b72dc14e1b0f03b46ef11d550e..5a90e24aa8a6679dc61e1c2fde23fd60a7be12f8 100644 --- a/arch/sh/configs/cayman_defconfig +++ b/arch/sh/configs/cayman_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_POSIX_MQUEUE=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -19,7 +18,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -38,7 +36,6 @@ CONFIG_NET_ETHERNET=y CONFIG_HW_RANDOM=y CONFIG_I2C=m CONFIG_WATCHDOG=y -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y @@ -67,5 +64,4 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index ec243ca295292f2a2da487735551048996b741d1..3f08dc54480b8f9be93e4d24e645a05e0fac3930 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 @@ -32,7 +31,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set @@ -43,8 +41,6 @@ CONFIG_NET_ETHERNET=y CONFIG_NET_PCI=y CONFIG_8139TOO=y # CONFIG_8139TOO_PIO is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_MAPLE=y # CONFIG_MOUSE_PS2 is not set @@ -56,7 +52,6 @@ CONFIG_HW_RANDOM=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_SH_WDT=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_PVR2=y @@ -74,5 +69,4 @@ CONFIG_LOGO=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_HUGETLBFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig index 5fcb17bff24a3d8ec19e023e647045ee554aa098..0c5dfccbfe37d1805d00028f1c8654abaab06c68 100644 --- a/arch/sh/configs/ecovec24-romimage_defconfig +++ b/arch/sh/configs/ecovec24-romimage_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -26,19 +25,15 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -51,7 +46,6 @@ CONFIG_I2C=y CONFIG_I2C_SH_MOBILE=y CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y @@ -64,4 +58,3 @@ CONFIG_TMPFS=y # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 0b364e3b0ff8206a9f40aabfc9febdb7227b78ff..3568310c2c2fc120434deca34a8dc9962e2b34f8 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -29,16 +28,12 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_IRDA=y CONFIG_SH_SIR=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -53,8 +48,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -140,8 +133,6 @@ CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig index 41fa3a7eed961432c6f11121843ce90a0838087e..db756e0990527d3f950ef233febc8a0b5772b993 100644 --- a/arch/sh/configs/edosk7705_defconfig +++ b/arch/sh/configs/edosk7705_defconfig @@ -20,7 +20,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y CONFIG_SH_EDOSK7705=y CONFIG_SH_PCLK_FREQ=31250000 # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -35,5 +34,4 @@ CONFIG_SH_PCLK_FREQ=31250000 # CONFIG_SYSFS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index e1077a041ac3a453ea6381ce573f2d508144118f..aab4ff1e247c898b29e78d206d51dc0d46fb0b34 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="_edosk7760" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -31,7 +30,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -39,10 +37,7 @@ CONFIG_DEBUG_DRIVER=y CONFIG_DEBUG_DEVRES=y CONFIG_MTD=y CONFIG_MTD_DEBUG=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y @@ -62,12 +57,9 @@ CONFIG_MTD_ABSENT=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=26000 -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -92,7 +84,6 @@ CONFIG_SND=y # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_SOC=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y @@ -119,8 +110,6 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig index 67cb1094a03333dfc84a2f2214d75bfc6450e342..2985fe7c6d5009a0afb99aac741e767520b0098b 100644 --- a/arch/sh/configs/espt_defconfig +++ b/arch/sh/configs/espt_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -26,13 +25,10 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y @@ -43,14 +39,11 @@ CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -65,7 +58,6 @@ CONFIG_FB_FOREIGN_ENDIAN=y CONFIG_FB_SH7760=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y @@ -73,7 +65,6 @@ CONFIG_USB_STORAGE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y @@ -123,6 +114,5 @@ CONFIG_NLS_UTF8=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig index 496edcdf95a3e8f246113757a99b791dbd15cdd2..4dcf7f5525829abe3c7b5751c91370fc9fb5f269 100644 --- a/arch/sh/configs/hp6xx_defconfig +++ b/arch/sh/configs/hp6xx_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -37,7 +36,6 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=64 # CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_HIT=y @@ -46,7 +44,6 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FONTS=y CONFIG_FONT_PEARL_8x8=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_SH=y @@ -55,7 +52,6 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y CONFIG_NLS_CODEPAGE_850=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_ECB=y diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig index 029a506ca3258da0bb7bd957548859061cbe6487..9cc37f29e3b4b6ec1f3bfea6dde07cae3bcd5d9c 100644 --- a/arch/sh/configs/kfr2r09-romimage_defconfig +++ b/arch/sh/configs/kfr2r09-romimage_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -26,12 +25,10 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -44,7 +41,6 @@ CONFIG_I2C=y CONFIG_I2C_SH_MOBILE=y CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y CONFIG_USB_CDC_COMPOSITE=y # CONFIG_DNOTIFY is not set @@ -55,5 +51,4 @@ CONFIG_TMPFS=y # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig index fac13ded07b2bd71c6bbac7e0e48dc28bf86112d..46693d0336446ccbc0c0e34ad1fc05fd17b69ccb 100644 --- a/arch/sh/configs/kfr2r09_defconfig +++ b/arch/sh/configs/kfr2r09_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -33,15 +32,12 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y @@ -49,7 +45,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_GENERIC=y CONFIG_MTD_UBI=y -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -77,7 +72,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set # CONFIG_LOGO_SUPERH_MONO is not set # CONFIG_LOGO_SUPERH_CLUT224 is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y @@ -91,4 +85,3 @@ CONFIG_TMPFS=y # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index 6783f31315c7eeda3861fbb2a286964fc159c0fd..467f4d2d8e87f4a9fd63f7f15dc54b8cf82555ed 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SYSCTL_SYSCALL is not set @@ -24,10 +23,8 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_IP_NF_QUEUE=m CONFIG_ATALK=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y @@ -118,7 +115,6 @@ CONFIG_NFSD_V3=y CONFIG_SMB_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_932=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index e3c0894b1bb4abc5a55eeaabfa74caa369d0f675..9e3edfdf9b2e3ac43f9b5e5bf9e837d68f4b8600 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SYSCTL_SYSCALL is not set @@ -28,7 +27,6 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -61,7 +59,6 @@ CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_ROMFS_FS=y CONFIG_NLS_CODEPAGE_437=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig index 9479872b1ae6b0332a97b6d5d53adb93831d6ee6..fb7415dbc102ed08a2ae72d5443963968466b48a 100644 --- a/arch/sh/configs/magicpanelr2_defconfig +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -35,16 +34,13 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -55,8 +51,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_EVDEV=y # CONFIG_MOUSE_PS2 is not set CONFIG_SERIAL_8250=y @@ -68,7 +62,6 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set @@ -96,7 +89,5 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_KOBJECT=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index f1d2e1b5ee419eaad55cadab5f230c6ace448c92..c3f7d5899922259473a9530a71b6112ab9523d93 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -19,7 +18,6 @@ CONFIG_SUPERHYWAY=y CONFIG_NET=y CONFIG_INET=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -45,6 +43,5 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index cc61eda44922ed131baf608f25695139fc2efb93..e04f21be0756dc5ec3ea8c472489fa993fa01ebc 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -26,15 +25,11 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -47,8 +42,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -101,7 +94,6 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig index f3d5d9f76310612d42a69c457835875b57f4e81b..0a432b5f50e74c7df47f4d45a654207b592fd4f8 100644 --- a/arch/sh/configs/polaris_defconfig +++ b/arch/sh/configs/polaris_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -37,14 +36,11 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -57,8 +53,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -71,7 +65,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_SH=y @@ -91,5 +84,3 @@ CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_SG=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index 920b8471ceb766ff35ed309bd2e5435e860822e1..435bcd66c667e491058cc13590af79d4d71311a9 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -35,13 +34,11 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_BRIDGE=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_COMPLEX_MAPPINGS=y @@ -110,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_HMAC=y diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index c77da6be06b8975ed68a992bb96ae6fab3bc9d24..5877e6d1f285d011c32656f9ce92ec7f63b185a9 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -42,7 +41,6 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_BRIDGE=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -104,7 +102,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_DEBUG_LOCKING_API_SELFTESTS=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_4KSTACKS=y diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig index 5df916d931c5eb6d0a6ab4f29e2c0d2be43895e0..b195bc01e406f6030fa20b3f52f5b6c1e7f31a14 100644 --- a/arch/sh/configs/rsk7201_defconfig +++ b/arch/sh/configs/rsk7201_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -37,10 +36,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,8 +54,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set CONFIG_THERMAL=y -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_SH=y @@ -71,5 +65,3 @@ CONFIG_ROMFS_FS=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig index 3c4f6f4d52b0df695c1b36154e13546aacec189f..8c471959bbc7bfd501e18088e80b37a5792eb1f6 100644 --- a/arch/sh/configs/rsk7203_defconfig +++ b/arch/sh/configs/rsk7203_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -44,7 +43,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -52,10 +50,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -64,8 +59,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set @@ -81,7 +74,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_THERMAL=y CONFIG_REGULATOR=y -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -130,6 +122,4 @@ CONFIG_DEBUG_VM=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_SG=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_STACK_USAGE=y diff --git a/arch/sh/configs/rsk7264_defconfig b/arch/sh/configs/rsk7264_defconfig index eecdf65bb7892e56b7404b8055409ba75dac03ea..2b9b731fc86b4a0401605f270a814b28b170b15f 100644 --- a/arch/sh/configs/rsk7264_defconfig +++ b/arch/sh/configs/rsk7264_defconfig @@ -35,7 +35,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -61,11 +60,9 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y -CONFIG_USB_LIBUSUAL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set diff --git a/arch/sh/configs/rsk7269_defconfig b/arch/sh/configs/rsk7269_defconfig index 8370b10df35721e02c01adcc98ddae4747a1129a..d041f7bcb84c34a11763bff85319bf078bfa1b89 100644 --- a/arch/sh/configs/rsk7269_defconfig +++ b/arch/sh/configs/rsk7269_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -44,11 +43,9 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y -CONFIG_USB_LIBUSUAL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -60,5 +57,4 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_FTRACE is not set diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index a3d081095ce23a293dedf7e4aeee44a27e67e90a..379d673f5ce8492f9757712d6ef56f4a81101d7e 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -22,7 +21,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m @@ -48,7 +46,6 @@ CONFIG_HW_RANDOM=y CONFIG_SPI=y CONFIG_SPI_SH_SCI=y CONFIG_MFD_SM501=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=m CONFIG_FB_SM501=y @@ -83,7 +80,6 @@ CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_R9701=y CONFIG_EXT2_FS=y @@ -94,6 +90,5 @@ CONFIG_TMPFS=y CONFIG_MINIX_FS=y CONFIG_NLS_CODEPAGE_932=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index b1a04f3c598bb1088bf2f363c0a84ab8f431c909..11177bceda834726c5bdb0518962a535e289d1bc 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -22,15 +21,11 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y @@ -56,7 +51,6 @@ CONFIG_HW_RANDOM=y CONFIG_SPI=y CONFIG_SPI_SH_SCI=y CONFIG_MFD_SM501=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=m CONFIG_FB_SM501=y @@ -91,7 +85,6 @@ CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_R9701=y CONFIG_EXT2_FS=y @@ -102,6 +95,5 @@ CONFIG_TMPFS=y CONFIG_MINIX_FS=y CONFIG_NLS_CODEPAGE_932=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index bbd4c2298708f8202433c4da43ffe4522813e941..95e5208b82600b38cb2d04d14dcdb1023996560b 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="_SDK7780" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -39,7 +38,6 @@ CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_BEET is not set CONFIG_NET_SCHED=y @@ -47,7 +45,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_PARPORT=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_PLATFORM=y @@ -63,8 +60,6 @@ CONFIG_BLK_DEV_DM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_NETCONSOLE=y CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_EVDEV=y @@ -78,7 +73,6 @@ CONFIG_SSB=y CONFIG_SSB_DRIVER_PCICORE=y CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=m -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y @@ -101,7 +95,6 @@ CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_TT_NEWSCHED is not set @@ -144,8 +137,6 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_SH_STANDARD_BIOS=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 36642ec2cb9799aabd2c90f294ebf970cd949825..e9ee0c878ead383e686be75ed510630a61545f9f 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_KERNEL_LZO=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -90,13 +89,11 @@ CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_FTL=y @@ -119,7 +116,6 @@ CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_PLATFORM=y @@ -140,8 +136,6 @@ CONFIG_MDIO_BITBANG=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_SERIAL_SH_SCI=y @@ -157,7 +151,6 @@ CONFIG_SPI=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_SH_WDT=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y @@ -223,9 +216,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_TIMER_STATS=y CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_RCU_CPU_STALL_VERBOSE is not set CONFIG_LATENCYTOP=y -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_FUNCTION_TRACER=y # CONFIG_FUNCTION_GRAPH_TRACER is not set CONFIG_DMA_API_DEBUG=y diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 91853a67ec34ace092f610591048952ae94a91e6..3553acd5edb1772ad78cf14538e24c759392a56c 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -57,7 +56,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -65,9 +63,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -78,8 +73,6 @@ CONFIG_EEPROM_93CX6=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -109,7 +102,6 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_VM=y CONFIG_DEBUG_LIST=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_DEBUG_STACK_USAGE=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig index 201acb4652f71a773c975578a7913009c60a8ef5..fc77a67b16e7ff50a11b77ebc9a7cd80e7e14a08 100644 --- a/arch/sh/configs/se7343_defconfig +++ b/arch/sh/configs/se7343_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -27,26 +26,19 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_RAM=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_USB_USBNET=y # CONFIG_USB_NET_AX8817X is not set CONFIG_USB_NET_DM9601=y @@ -104,5 +96,4 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFSD=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig index 9a9ad9adf9597a516016b41e53250bb91b1678f7..f54722dbc8f52c8cfbea55179eb29d52c4353d94 100644 --- a/arch/sh/configs/se7619_defconfig +++ b/arch/sh/configs/se7619_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_UID16 is not set @@ -24,10 +23,7 @@ CONFIG_BINFMT_ZFLAT=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -48,4 +44,3 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_SYSFS is not set CONFIG_ROMFS_FS=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 044e0844fda18ede97b143ea366e5f7afa0069d8..ddfc6984195569c10b9ecaf2a825a299cdf5b248 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -27,11 +26,8 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,5 +54,4 @@ CONFIG_PROC_KCORE=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig index 1248635e4f888a4a248f4efa7236243fb4ee0deb..5a1097641247893cd0f373d308462b5a8b865ffb 100644 --- a/arch/sh/configs/se7712_defconfig +++ b/arch/sh/configs/se7712_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -47,7 +46,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_NET_SCHED=y @@ -68,9 +66,6 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_IND=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -104,8 +99,6 @@ CONFIG_ROOT_NFS=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig index c3ba6e8a981810542ecd702cf8ca2d9240496d74..9c0ef13bee10d3ac5e53a9503fc77fe4c9925c59 100644 --- a/arch/sh/configs/se7721_defconfig +++ b/arch/sh/configs/se7721_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -46,7 +45,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_NET_SCHED=y @@ -67,9 +65,6 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_IND=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -132,6 +127,5 @@ CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_CCITT=y diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index ae998c7e2ee0f5aa59a4e524ed2f6ba06305d78a..ccc7fc423fde7fe3f5b5185eae1bbbf23034e224 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -26,7 +25,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -57,6 +55,5 @@ CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index 1faa788aecae48754cadcb0cd8ff4600213f20bf..aedb3a2d9a10857377fe80c5e6a3a416f3bf8b96 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -30,14 +29,10 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -53,8 +48,6 @@ CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -137,8 +130,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index 912c98590e2215c69dde022f9698862f93fb4da5..b23f67542728cc3120be2b6a7de85f79eb518138 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -25,11 +24,8 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,5 +54,4 @@ CONFIG_ROOT_NFS=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig index 75c92fc1876b79c629b44d418be27c309862ab8c..16234368393752d98630bb36049c58e313bbb4ab 100644 --- a/arch/sh/configs/se7751_defconfig +++ b/arch/sh/configs/se7751_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 @@ -25,13 +24,9 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y -CONFIG_IP_NF_QUEUE=y CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -49,5 +44,4 @@ CONFIG_EXT2_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index b0ef63ce525aa6330a615fb243c6379381645db7..ec32c82646ed68c6df8e729a6747bdf53a566b9d 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -24,7 +24,6 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set # CONFIG_INET6_XFRM_MODE_TUNNEL is not set @@ -32,8 +31,6 @@ CONFIG_IPV6=y # CONFIG_IPV6_SIT is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -54,8 +51,6 @@ CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y CONFIG_NET_PCI=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_KEYBOARD is not set @@ -94,7 +89,6 @@ CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y @@ -110,5 +104,4 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/secureedge5410_defconfig b/arch/sh/configs/secureedge5410_defconfig index 7eae4e59d7f0437d399ae6a3ff92b00bf100ec13..360592d63a2f5dcd21d2685e3deb09b125917184 100644 --- a/arch/sh/configs/secureedge5410_defconfig +++ b/arch/sh/configs/secureedge5410_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -18,12 +17,9 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK_RO=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -34,14 +30,11 @@ CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PLATRAM=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_NET_PCI=y CONFIG_8139CP=y CONFIG_8139TOO=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -51,7 +44,6 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1302=y @@ -60,4 +52,3 @@ CONFIG_EXT2_FS=y CONFIG_TMPFS=y CONFIG_CRAMFS=y CONFIG_ROMFS_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index 0cf4097b71e8d02051a3976d86b63226ab2b8924..2156223405a160df5031ba0dcff300118a979262 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -34,7 +33,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set @@ -70,7 +68,6 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_ISO9660_FS=m CONFIG_JOLIET=y @@ -126,7 +123,6 @@ CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_HMAC=y diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig index df25ae774ee0d2a3fcf46448413393b673b623d9..34094e05e892b888712f9e963d990e2903ba80a5 100644 --- a/arch/sh/configs/sh2007_defconfig +++ b/arch/sh/configs/sh2007_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -42,7 +41,6 @@ CONFIG_NET_IPIP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETWORK_SECMARK=y CONFIG_NET_PKTGEN=y @@ -50,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=y -# CONFIG_MISC_DEVICES is not set CONFIG_RAID_ATTRS=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -72,8 +69,6 @@ CONFIG_TUN=y CONFIG_VETH=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_MOUSEDEV is not set @@ -95,9 +90,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -172,7 +165,6 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_AUTHENC=y diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig index f92ad17cd629ffa93eae80be7dac2315e7f6e468..65a1aad899c8ea2a69a4809fb1b7253e4a3c58f6 100644 --- a/arch/sh/configs/sh7710voipgw_defconfig +++ b/arch/sh/configs/sh7710voipgw_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -24,7 +23,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y @@ -36,8 +34,6 @@ CONFIG_NET_CLS_ROUTE4=y CONFIG_NET_CLS_U32=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -59,5 +55,4 @@ CONFIG_THERMAL=y # CONFIG_DNOTIFY is not set CONFIG_JFFS2_FS=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig index f83ac7b0b031185c5e2f5e353c048228e03fa737..d15e53647983a33b90f8fbf4c1db29a6ec27ba44 100644 --- a/arch/sh/configs/sh7724_generic_defconfig +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_CGROUPS=y @@ -18,7 +17,6 @@ CONFIG_HIBERNATION=y CONFIG_CPU_IDLE=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -44,5 +42,4 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_MISC_FILESYSTEMS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig index cfde98ddb29d3e437b1c49d07d1e659c09158c1c..b0c4bc830fb8c968da640fd75dd88cb7b5efaeac 100644 --- a/arch/sh/configs/sh7757lcr_defconfig +++ b/arch/sh/configs/sh7757lcr_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -32,13 +31,11 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set CONFIG_IPV6=y # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_M25P80=y CONFIG_BLK_DEV_RAM=y @@ -48,7 +45,6 @@ CONFIG_NETDEVICES=y CONFIG_VITESSE_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_MOUSE_PS2 is not set diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig index 4795364402643eb80c4cf919f72d4a03c267ca81..2ef780fb9813c9278bb63f0ef410b1df0e21f984 100644 --- a/arch/sh/configs/sh7763rdp_defconfig +++ b/arch/sh/configs/sh7763rdp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -26,11 +25,9 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLKDEVS=y CONFIG_MTD_CFI=y @@ -43,14 +40,11 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -65,7 +59,6 @@ CONFIG_FB_FOREIGN_ENDIAN=y CONFIG_FB_SH7760=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y @@ -74,7 +67,6 @@ CONFIG_MMC=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -124,6 +116,5 @@ CONFIG_NLS_UTF8=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig index 025bd3ac5ab08799556e37bc462f1833247070a4..742634b37c0a0f74a54e6a36c3984ab6c6790d93 100644 --- a/arch/sh/configs/sh7770_generic_defconfig +++ b/arch/sh/configs/sh7770_generic_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_CGROUPS=y @@ -20,7 +19,6 @@ CONFIG_HIBERNATION=y CONFIG_CPU_IDLE=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -46,5 +44,4 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_MISC_FILESYSTEMS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index 2fce54d9c388496e8c3de442e6c3ddb835acddaf..2ddf5ca7094ebcb25d0e43440bb6ace4b2899dea 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -44,13 +43,9 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,7 +53,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set @@ -69,7 +63,6 @@ CONFIG_NET_ETHERNET=y CONFIG_NET_VENDOR_3COM=y CONFIG_VORTEX=y CONFIG_R8169=y -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_EVDEV=y @@ -113,7 +106,6 @@ CONFIG_SND_CMIPCI=y CONFIG_SND_EMU10K1=y # CONFIG_SND_SUPERH is not set CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_MMC=y @@ -154,9 +146,7 @@ CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_LATENCYTOP=y -CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_FTRACE is not set CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig index d29da4a0f6c271f0a4b3b90d4b19d1710e3e3081..7098828d392e2102d738328e4c4828fbb556cb9e 100644 --- a/arch/sh/configs/sh7785lcr_defconfig +++ b/arch/sh/configs/sh7785lcr_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -26,27 +25,21 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_ATA=y CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y CONFIG_R8169=y -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_KEYBOARD_ATKBD is not set @@ -121,8 +114,6 @@ CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig index 4802e14a4649aa977af83b8af6e8e6916e437147..d589cfdfb7ebb11a62008a5a0e0ab2155499ba67 100644 --- a/arch/sh/configs/shmin_defconfig +++ b/arch/sh/configs/shmin_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_UID16 is not set @@ -28,10 +27,8 @@ CONFIG_NET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y @@ -53,6 +50,5 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index 4a4269ad5b04539d5b716775a8552e6f4853951f..755c4f73c71838635774e8f2a3d50e62df9fc254 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -56,7 +55,6 @@ CONFIG_NET=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set CONFIG_CAN=m CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m @@ -70,8 +68,6 @@ CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -82,7 +78,6 @@ CONFIG_I2C=m CONFIG_SPI=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_R8A66597_HCD=m @@ -104,7 +99,6 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_VM=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_DEBUG_STACK_USAGE=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index a77b778c745b98ea76292d76b2309959a739b08a..ceb48e9b70f4fbc6d8b2af38dffe888b3b739e35 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -49,7 +48,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y @@ -79,7 +77,6 @@ CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m @@ -88,7 +85,6 @@ CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m @@ -96,7 +92,6 @@ CONFIG_IP_NF_RAW=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -106,7 +101,6 @@ CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m @@ -154,7 +148,6 @@ CONFIG_FW_LOADER=m CONFIG_CONNECTOR=m CONFIG_MTD=m CONFIG_MTD_DEBUG=y -CONFIG_MTD_CHAR=m CONFIG_MTD_BLOCK=m CONFIG_FTL=m CONFIG_NFTL=m @@ -261,7 +254,6 @@ CONFIG_NLS_UTF8=m CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_MD4=m diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig index 2d288b887fbdd8c56bb45c6a6d67273abc8fac77..5f2921a8519265f4c1b028d8bbac3b200c39d923 100644 --- a/arch/sh/configs/ul2_defconfig +++ b/arch/sh/configs/ul2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -29,7 +28,6 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_CFG80211=y CONFIG_MAC80211=y @@ -37,9 +35,6 @@ CONFIG_MAC80211_RC_PID=y # CONFIG_MAC80211_RC_MINSTREL is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -50,8 +45,6 @@ CONFIG_ATA=y CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_LIBERTAS=m CONFIG_LIBERTAS_SDIO=m CONFIG_LIBERTAS_DEBUG=y @@ -70,7 +63,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_R8A66597_HCD=y @@ -92,6 +84,5 @@ CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 01c9a91ee896bbcfce76741ccdb72511e1909feb..7d5591b7c0886dc6ff10a77e53122bd14b408fa3 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -46,20 +45,15 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_ATA=y @@ -73,7 +67,6 @@ CONFIG_NET_PCI=y CONFIG_8139CP=y CONFIG_SKY2=y CONFIG_SKY2_DEBUG=y -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_KEYBOARD_ATKBD is not set @@ -150,8 +143,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_FTRACE is not set # CONFIG_DUMP_CODE is not set CONFIG_CRYPTO_HMAC=y diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index edc2fb7a5bb25540e75cf42b86877b8c16ed8558..32467884d6f796fe8f59f331c3c9e91e2819c5f2 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c @@ -5,7 +5,7 @@ #include #include "pci-sh5.h" -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int result = -1; diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 1d1c5a227e509e50e865011b7e9912c8db109196..48aaefd8f5d6ccc5a3a2a67f0b484743d896a632 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -63,11 +63,10 @@ static void gapspci_fixup_resources(struct pci_dev *dev) res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1; res.flags = IORESOURCE_MEM; pcibios_resource_to_bus(dev->bus, ®ion, &res); - BUG_ON(!dma_declare_coherent_memory(&dev->dev, + BUG_ON(dma_declare_coherent_memory(&dev->dev, res.start, region.start, resource_size(&res), - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)); break; default: @@ -76,7 +75,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The interrupt routing semantics here are quite trivial. diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 57ed3f09d0c2b838d5e0daa372b319ff32fb3565..2c9b58f848dd3457fd4913f56269445409d96fac 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -15,7 +15,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return evt2irq(0xa20) + slot; } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index eaddb56c45c612493e0c996183d092df25efa882..358ac104f08c4ee572f08d9d9b701f04125def57 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -20,18 +20,18 @@ #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB -static u8 rts7751r2d_irq_tab[] __initdata = { +static u8 rts7751r2d_irq_tab[] = { IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD, }; -static char lboxre2_irq_tab[] __initdata = { +static char lboxre2_irq_tab[] = { IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { if (mach_is_lboxre2()) return lboxre2_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index c0a015ae6ecf718df7a2bfba9ea4fc4edd35bd82..24e96dfbdb229c3992bee3c200229283af24e87c 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -22,7 +22,7 @@ #define IRQ_INTD evt2irq(0xa80) /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ -static char sdk7780_irq_tab[4][16] __initdata = { +static char sdk7780_irq_tab[4][16] = { /* INTA */ { IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, @@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = { -1, -1, -1 }, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return sdk7780_irq_tab[pin-1][slot]; } diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index 84a88ca9200821c4fbd9b1266967ded716c89d72..1cb8d0ac4fdb5aebf4e1b616422fb3a8db83e463 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -7,7 +7,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) { switch (slot) { case 0: return evt2irq(0x3a0); diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 16207bef9f52586dee90548d6c472e318dbc3a68..55ac1ba2c74fefbf597346a40d3ac2c4b718a217 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c @@ -4,7 +4,7 @@ #include #include -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 6e33ba4cd0765254ea0f7c0b7c274c2f3cf92b0d..a931e5928f58ca544b4715dae6da08a4f0017d81 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c @@ -19,7 +19,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index bd1addb1b8be4f91c8f25d3bdf3d58346450712b..a9d563e479d5c12b418957f4202dbbcf3fa61023 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c @@ -19,7 +19,7 @@ #include #include "pci-sh4.h" -static char titan_irq_tab[] __initdata = { +static char titan_irq_tab[] = { TITAN_IRQ_WAN, TITAN_IRQ_LAN, TITAN_IRQ_MPCIA, @@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = { TITAN_IRQ_USB, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = titan_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c99ee286b69f126506eebe9814588096cb224a5b..5976a2c8a3e350db0e228b224593f17fb47dc602 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose) LIST_HEAD(resources); struct resource *res; resource_size_t offset; - int i; - struct pci_bus *bus; + int i, ret; + struct pci_host_bridge *bridge; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; for (i = 0; i < hose->nr_resources; i++) { res = hose->resources + i; @@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose) pci_add_resource_offset(&resources, res, offset); } - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = hose->pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pcibios_map_platform_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + hose->bus = bridge->bus; need_domain_info = need_domain_info || hose->index; hose->need_domain_info = need_domain_info; - if (!bus) { - pci_free_resource_list(&resources); - return; - } - - next_busno = bus->busn_res.end + 1; + next_busno = hose->bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { @@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose) need_domain_info = 1; } - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - pci_bus_add_devices(bus); + pci_bus_size_bridges(hose->bus); + pci_bus_assign_resources(hose->bus); + pci_bus_add_devices(hose->bus); } /* @@ -144,8 +155,6 @@ static int __init pcibios_init(void) for (hose = hose_head; hose; hose = hose->next) pcibios_scanbus(hose); - pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); - dma_debug_add_bus(&pci_bus_type); pci_initialized = 1; @@ -154,14 +163,6 @@ static int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index a162a7f86b2e500e1439ea639e233a5cdabbb904..0167a735271942a04580d527c844ce6dd0628673 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) return 0; } -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return evt2irq(0xae0); } diff --git a/arch/sh/include/asm/futex.h b/arch/sh/include/asm/futex.h index d0078747d308cad1e98d28970f2593a2ef6ad752..8f8cf941a8cd29c716a923002490dc5506ee57a5 100644 --- a/arch/sh/include/asm/futex.h +++ b/arch/sh/include/asm/futex.h @@ -27,21 +27,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return atomic_futex_op_cmpxchg_inatomic(uval, uaddr, oldval, newval); } -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - u32 oparg = (encoded_op << 8) >> 20; - u32 cmparg = (encoded_op << 20) >> 20; u32 oldval, newval, prev; int ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); do { @@ -80,17 +71,8 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = ((int)oldval < (int)cmparg); break; - case FUTEX_OP_CMP_GE: ret = ((int)oldval >= (int)cmparg); break; - case FUTEX_OP_CMP_LE: ret = ((int)oldval <= (int)cmparg); break; - case FUTEX_OP_CMP_GT: ret = ((int)oldval > (int)cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; return ret; } diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 18e0377f72bbb9ad8f559b00fc2452532d0ad312..88ce1e22237b2b9a22f100e753d00456699ece47 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -136,10 +136,6 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned lo /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while(0) -#define release_segments(mm) do { } while(0) - /* * FPU lazy state save handling. */ diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index eedd4f625d07650e1f392a37b45e22d765e51602..777a16318aff1fd41df535ccc91453d7d91d318f 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -170,10 +170,6 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while (0) -#define release_segments(mm) do { } while (0) -#define forget_segments() do { } while (0) /* * FPU lazy state save handling. */ diff --git a/arch/sh/include/asm/spinlock-cas.h b/arch/sh/include/asm/spinlock-cas.h index c46e8cc7b515d9c7ba8654b1e45f681fc2cdd0cf..5ed7dbbd94ff5bce146bf9581297d9e1358373e7 100644 --- a/arch/sh/include/asm/spinlock-cas.h +++ b/arch/sh/include/asm/spinlock-cas.h @@ -29,11 +29,6 @@ static inline unsigned __sl_cas(volatile unsigned *p, unsigned old, unsigned new #define arch_spin_is_locked(x) ((x)->lock <= 0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, VAL > 0); -} - static inline void arch_spin_lock(arch_spinlock_t *lock) { while (!__sl_cas(&lock->lock, 1, 0)); diff --git a/arch/sh/include/asm/spinlock-llsc.h b/arch/sh/include/asm/spinlock-llsc.h index cec78143fa8368bf610347a100d8e598e0176288..f77263aae7607ff649ff167446c44879f2133345 100644 --- a/arch/sh/include/asm/spinlock-llsc.h +++ b/arch/sh/include/asm/spinlock-llsc.h @@ -21,11 +21,6 @@ #define arch_spin_is_locked(x) ((x)->lock <= 0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, VAL > 0); -} - /* * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 46e0d635e36f711aff9a88c45955905d7fbf3cc2..51a8bc967e75f1e3c96a70783e9da439310edbcb 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -36,7 +36,8 @@ static inline void init_tlb_gather(struct mmu_gather *tlb) } static inline void -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) +arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) { tlb->mm = mm; tlb->start = start; @@ -47,9 +48,10 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start } static inline void -tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force) { - if (tlb->fullmm) + if (tlb->fullmm || force) flush_tlb_mm(tlb->mm); /* keep the page table cache within bounds */ diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7264.h b/arch/sh/include/cpu-sh2a/cpu/sh7264.h index 4d1ef6d74bd6050cb34d0f2fdd91d114fb0baa96..2ae0e938b657a109963dc2059b401f02a673d4fc 100644 --- a/arch/sh/include/cpu-sh2a/cpu/sh7264.h +++ b/arch/sh/include/cpu-sh2a/cpu/sh7264.h @@ -43,9 +43,7 @@ enum { GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4, GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0, - /* Port H */ - GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4, - GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0, + /* Port H - Port H does not have a Data Register */ /* Port I - not on device */ diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7269.h b/arch/sh/include/cpu-sh2a/cpu/sh7269.h index 2a0ca8780f0d8c343fb87e434cf6acec73acaddb..13c495a9fc0007b414bb8f8e36c0e9618e356c3e 100644 --- a/arch/sh/include/cpu-sh2a/cpu/sh7269.h +++ b/arch/sh/include/cpu-sh2a/cpu/sh7269.h @@ -45,9 +45,7 @@ enum { GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4, GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0, - /* Port H */ - GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4, - GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0, + /* Port H - Port H does not have a Data Register */ /* Port I - not on device */ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h index 3bb74e534d0f8ca44208827d762e9dec03b2525a..78961ab78a5a9c83320706171123e59115d00ba5 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7722.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h @@ -67,7 +67,7 @@ enum { GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0, /* PTQ */ - GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, + GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0, /* PTR */ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 5340f3bc1863c3890dde9a8286e05d111a8393ed..b40fb541e72a78ae18002aa79702fa2e72e298b7 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h @@ -40,7 +40,7 @@ enum { /* PTJ */ GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3, - GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV, + GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, /* PTK */ GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3, @@ -48,7 +48,7 @@ enum { /* PTL */ GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3, - GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV, + GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, /* PTM */ GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3, @@ -56,7 +56,7 @@ enum { /* PTN */ GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3, - GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV, + GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, /* PTO */ GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3, @@ -68,7 +68,7 @@ enum { /* PTQ */ GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3, - GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV, + GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, /* PTR */ GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3, diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index a4a626199c47e1afce31559a028df4cda331f619..0be3828752e5bc9ddf33ba74c9e5b9efd03691e4 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -97,6 +97,9 @@ config ARCH_PROC_KCORE_TEXT config CPU_BIG_ENDIAN def_bool y +config CPU_BIG_ENDIAN + def_bool y + config ARCH_ATU bool default y if SPARC64 diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig index c74d3701ad6830fe88338c185be374f7a6730f07..207a43a2d8b337ee61d8d982341946018ded5c97 100644 --- a/arch/sparc/configs/sparc32_defconfig +++ b/arch/sparc/configs/sparc32_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_LOG_BUF_SHIFT=14 @@ -23,7 +22,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -69,7 +67,6 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_ISO9660_FS=m CONFIG_PROC_KCORE=y @@ -82,7 +79,6 @@ CONFIG_NLS=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_KGDB=y CONFIG_KGDB_TESTS=y CONFIG_CRYPTO_NULL=m diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index b2e650d1764f63d430d6b96eac793621d26902da..4d4e1cc6402faa27f0d825d41ffcf39471805ee4 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -1,5 +1,4 @@ CONFIG_64BIT=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -184,7 +183,6 @@ CONFIG_HID_TOPSEED=y CONFIG_HID_THRUSTMASTER=y CONFIG_HID_ZEROPLUS=y CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_TT_NEWSCHED is not set CONFIG_USB_OHCI_HCD=y @@ -210,8 +208,6 @@ CONFIG_LOCKUP_DETECTOR=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set CONFIG_SCHEDSTATS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_UPROBE_EVENTS=y CONFIG_KEYS=y @@ -242,3 +238,4 @@ CONFIG_CRYPTO_TWOFISH=m # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC16=m CONFIG_LIBCRC32C=m +CONFIG_VCC=m diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c index c90930de76ba8670041598ba0d6461ef439c9539..3cd4f6b198b65665046101184f579b51138a688d 100644 --- a/arch/sparc/crypto/aes_glue.c +++ b/arch/sparc/crypto/aes_glue.c @@ -344,8 +344,7 @@ static void ctr_crypt_final(struct crypto_sparc64_aes_ctx *ctx, ctx->ops->ecb_encrypt(&ctx->key[0], (const u64 *)ctrblk, keystream, AES_BLOCK_SIZE); - crypto_xor((u8 *) keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, (u8 *) keystream, src, nbytes); crypto_inc(ctrblk, AES_BLOCK_SIZE); } diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h index ee3f11c43cdaa2ef6ab6fe444130e8dd2a8a5541..7643e979e3338c8f23affa81269379f3d77fba52 100644 --- a/arch/sparc/include/asm/atomic_32.h +++ b/arch/sparc/include/asm/atomic_32.h @@ -29,6 +29,8 @@ int atomic_xchg(atomic_t *, int); int __atomic_add_unless(atomic_t *, int, int); void atomic_set(atomic_t *, int); +#define atomic_set_release(v, i) atomic_set((v), (i)) + #define atomic_read(v) ACCESS_ONCE((v)->counter) #define atomic_add(i, v) ((void)atomic_add_return( (int)(i), (v))) diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h index 4e899b0dabf79154f0ccc96a2ed1e0d7d230e04b..1cfd89d922080103d8e4b55c8cc36d94290a75df 100644 --- a/arch/sparc/include/asm/futex_64.h +++ b/arch/sparc/include/asm/futex_64.h @@ -29,22 +29,14 @@ : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ : "memory") -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tem; - if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))) - return -EFAULT; if (unlikely((((unsigned long) uaddr) & 0x3UL))) return -EINVAL; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - pagefault_disable(); switch (op) { @@ -69,17 +61,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index d1f837dc77a4d0c975f94e5bbd315b347001d01a..0ca7caab1b06ef646d96aa6abf9c644e68ba6a95 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h @@ -4,6 +4,13 @@ #include #include +#ifdef CONFIG_HUGETLB_PAGE +struct pud_huge_patch_entry { + unsigned int addr; + unsigned int insn; +}; +extern struct pud_huge_patch_entry __pud_huge_patch, __pud_huge_patch_end; +#endif void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index 73cb8978df58c9f25e2f06101a84bf1101dc7cf3..3dc9215d0357e0732ac31a906e4fa4d3a63b1470 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -298,6 +298,24 @@ unsigned long sun4v_cpu_stop(unsigned long cpuid); unsigned long sun4v_cpu_yield(void); #endif +/* cpu_poke() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_POKE + * RET0: status + * ERRORS: ENOCPU cpuid refers to a CPU that does not exist + * EINVAL cpuid is current CPU + * + * Poke CPU cpuid. If the target CPU is currently suspended having + * invoked the cpu-yield service, that vCPU will be resumed. + * Poke interrupts may only be sent to valid, non-local CPUs. + * It is not legal to poke the current vCPU. + */ +#define HV_FAST_CPU_POKE 0x13 + +#ifndef __ASSEMBLY__ +unsigned long sun4v_cpu_poke(unsigned long cpuid); +#endif + /* cpu_qconf() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_CPU_QCONF diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h index 2cddcda4f85f7555dced053b1fc82fd991e19943..87841d687f8d5306663c54d050aa0ca4b2b08cd7 100644 --- a/arch/sparc/include/asm/mmu_context_64.h +++ b/arch/sparc/include/asm/mmu_context_64.h @@ -27,9 +27,11 @@ void destroy_context(struct mm_struct *mm); void __tsb_context_switch(unsigned long pgd_pa, struct tsb_config *tsb_base, struct tsb_config *tsb_huge, - unsigned long tsb_descr_pa); + unsigned long tsb_descr_pa, + unsigned long secondary_ctx); -static inline void tsb_context_switch(struct mm_struct *mm) +static inline void tsb_context_switch_ctx(struct mm_struct *mm, + unsigned long ctx) { __tsb_context_switch(__pa(mm->pgd), &mm->context.tsb_block[MM_TSB_BASE], @@ -40,9 +42,12 @@ static inline void tsb_context_switch(struct mm_struct *mm) #else NULL #endif - , __pa(&mm->context.tsb_descr[MM_TSB_BASE])); + , __pa(&mm->context.tsb_descr[MM_TSB_BASE]), + ctx); } +#define tsb_context_switch(X) tsb_context_switch_ctx(X, 0) + void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long mm_rss); @@ -112,8 +117,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str * cpu0 to update it's TSB because at that point the cpu_vm_mask * only had cpu1 set in it. */ - load_secondary_context(mm); - tsb_context_switch(mm); + tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context)); /* Any time a processor runs a context on an address space * for the first time, we must flush that context out of the diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index 0efd0583a8c9da1afc2acc508f2e2e1a5388441d..6249214148c24bb44f2203117200768a410cee2d 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h @@ -68,6 +68,7 @@ typedef struct { unsigned long iopgprot; } iopgprot_t; #define iopgprot_val(x) ((x).iopgprot) #define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { { (x) }, }) #define __iopte(x) ((iopte_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) #define __ctxd(x) ((ctxd_t) { (x) } ) @@ -95,6 +96,7 @@ typedef unsigned long iopgprot_t; #define iopgprot_val(x) (x) #define __pte(x) (x) +#define __pmd(x) ((pmd_t) { { (x) }, }) #define __iopte(x) (x) #define __pgd(x) (x) #define __ctxd(x) (x) diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index 5961b2d8398a9cdfa359483f009f0c30cfcca9a8..8ee1f97589a1aca43cd41c2b9fecb51bfcb68fee 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -17,6 +17,7 @@ #define HPAGE_SHIFT 23 #define REAL_HPAGE_SHIFT 22 +#define HPAGE_16GB_SHIFT 34 #define HPAGE_2GB_SHIFT 31 #define HPAGE_256MB_SHIFT 28 #define HPAGE_64K_SHIFT 16 @@ -28,7 +29,7 @@ #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define REAL_HPAGE_PER_HPAGE (_AC(1,UL) << (HPAGE_SHIFT - REAL_HPAGE_SHIFT)) -#define HUGE_MAX_HSTATE 4 +#define HUGE_MAX_HSTATE 5 #endif #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 6fbd931f0570021fd297db9163ed170fc21aafe2..4fefe3762083d42746d51c779c7f830cd439973d 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -414,6 +414,11 @@ static inline bool is_hugetlb_pmd(pmd_t pmd) return !!(pmd_val(pmd) & _PAGE_PMD_HUGE); } +static inline bool is_hugetlb_pud(pud_t pud) +{ + return !!(pud_val(pud) & _PAGE_PUD_HUGE); +} + #ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline pmd_t pmd_mkhuge(pmd_t pmd) { @@ -687,6 +692,8 @@ static inline unsigned long pmd_write(pmd_t pmd) return pte_write(pte); } +#define pud_write(pud) pte_write(__pte(pud_val(pud))) + #ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline unsigned long pmd_dirty(pmd_t pmd) { @@ -823,9 +830,18 @@ static inline unsigned long __pmd_page(pmd_t pmd) return ((unsigned long) __va(pfn << PAGE_SHIFT)); } + +static inline unsigned long pud_page_vaddr(pud_t pud) +{ + pte_t pte = __pte(pud_val(pud)); + unsigned long pfn; + + pfn = pte_pfn(pte); + + return ((unsigned long) __va(pfn << PAGE_SHIFT)); +} + #define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) -#define pud_page_vaddr(pud) \ - ((unsigned long) __va(pud_val(pud))) #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) #define pud_present(pud) (pud_val(pud) != 0U) diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index ce2233f7e662d7f85f5a32ea45339f0eda67e19c..a75089285db851e8cf3083d069bf3dada4d47c11 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -33,6 +33,9 @@ DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); extern cpumask_t cpu_core_map[NR_CPUS]; +void smp_init_cpu_poke(void); +void scheduler_poke(void); + void arch_send_call_function_single_ipi(int cpu); void arch_send_call_function_ipi_mask(const struct cpumask *mask); @@ -74,6 +77,8 @@ void __cpu_die(unsigned int cpu); #define smp_fetch_global_regs() do { } while (0) #define smp_fetch_global_pmu() do { } while (0) #define smp_fill_in_cpu_possible_map() do { } while (0) +#define smp_init_cpu_poke() do { } while (0) +#define scheduler_poke() do { } while (0) #endif /* !(CONFIG_SMP) */ diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 8011e79f59c96f3658e430765e6aa56caa400098..67345b2dc408b94970f80a40d4aba18d2c08c7bc 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -14,11 +14,6 @@ #define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - static inline void arch_spin_lock(arch_spinlock_t *lock) { __asm__ __volatile__( diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h index 1d8321c827a8821bb4e9f4989eb883cd761370db..1b1286d0506910c0f9a92ab6af14e272dd008d61 100644 --- a/arch/sparc/include/asm/spitfire.h +++ b/arch/sparc/include/asm/spitfire.h @@ -47,10 +47,26 @@ #define SUN4V_CHIP_NIAGARA5 0x05 #define SUN4V_CHIP_SPARC_M6 0x06 #define SUN4V_CHIP_SPARC_M7 0x07 +#define SUN4V_CHIP_SPARC_M8 0x08 #define SUN4V_CHIP_SPARC64X 0x8a #define SUN4V_CHIP_SPARC_SN 0x8b #define SUN4V_CHIP_UNKNOWN 0xff +/* + * The following CPU_ID_xxx constants are used + * to identify the CPU type in the setup phase + * (see head_64.S) + */ +#define CPU_ID_NIAGARA1 ('1') +#define CPU_ID_NIAGARA2 ('2') +#define CPU_ID_NIAGARA3 ('3') +#define CPU_ID_NIAGARA4 ('4') +#define CPU_ID_NIAGARA5 ('5') +#define CPU_ID_M6 ('6') +#define CPU_ID_M7 ('7') +#define CPU_ID_M8 ('8') +#define CPU_ID_SONOMA1 ('N') + #ifndef __ASSEMBLY__ enum ultra_tlb_layout { diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h index ff05992dae7a352597bf99fcd2d83500ad0c2995..dfc538609eb2d570ce7eb20cbce5a7bd9e99366d 100644 --- a/arch/sparc/include/asm/trap_block.h +++ b/arch/sparc/include/asm/trap_block.h @@ -73,6 +73,8 @@ struct sun4v_1insn_patch_entry { }; extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch, __sun4v_1insn_patch_end; +extern struct sun4v_1insn_patch_entry __fast_win_ctrl_1insn_patch, + __fast_win_ctrl_1insn_patch_end; struct sun4v_2insn_patch_entry { unsigned int addr; diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 32258e08da035f018df2915bf9935556556628bb..acf55063aa3dd9ae66bc1f7760782a84404d03f8 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h @@ -195,6 +195,41 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; nop; \ 699: + /* PUD has been loaded into REG1, interpret the value, seeing + * if it is a HUGE PUD or a normal one. If it is not valid + * then jump to FAIL_LABEL. If it is a HUGE PUD, and it + * translates to a valid PTE, branch to PTE_LABEL. + * + * We have to propagate bits [32:22] from the virtual address + * to resolve at 4M granularity. + */ +#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) +#define USER_PGTABLE_CHECK_PUD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \ +700: ba 700f; \ + nop; \ + .section .pud_huge_patch, "ax"; \ + .word 700b; \ + nop; \ + .previous; \ + brz,pn REG1, FAIL_LABEL; \ + sethi %uhi(_PAGE_PUD_HUGE), REG2; \ + sllx REG2, 32, REG2; \ + andcc REG1, REG2, %g0; \ + be,pt %xcc, 700f; \ + sethi %hi(0x1ffc0000), REG2; \ + sllx REG2, 1, REG2; \ + brgez,pn REG1, FAIL_LABEL; \ + andn REG1, REG2, REG1; \ + and VADDR, REG2, REG2; \ + brlz,pt REG1, PTE_LABEL; \ + or REG1, REG2, REG1; \ +700: +#else +#define USER_PGTABLE_CHECK_PUD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \ + brz,pn REG1, FAIL_LABEL; \ + nop; +#endif + /* PMD has been loaded into REG1, interpret the value, seeing * if it is a HUGE PMD or a normal one. If it is not valid * then jump to FAIL_LABEL. If it is a HUGE PMD, and it @@ -242,6 +277,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; srlx REG2, 64 - PAGE_SHIFT, REG2; \ andn REG2, 0x7, REG2; \ ldxa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ + USER_PGTABLE_CHECK_PUD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, 800f) \ brz,pn REG1, FAIL_LABEL; \ sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ srlx REG2, 64 - PAGE_SHIFT, REG2; \ diff --git a/arch/sparc/include/asm/vga.h b/arch/sparc/include/asm/vga.h index ec0e9967d93d5904eeb9b9c1ab10a1794321c810..f54e8b6fb1972e8282f38c792cb77e9793950fd0 100644 --- a/arch/sparc/include/asm/vga.h +++ b/arch/sparc/include/asm/vga.h @@ -8,9 +8,13 @@ #define _LINUX_ASM_VGA_H_ #include +#include #include #define VT_BUF_HAVE_RW +#define VT_BUF_HAVE_MEMSETW +#define VT_BUF_HAVE_MEMCPYW +#define VT_BUF_HAVE_MEMMOVEW #undef scr_writew #undef scr_readw @@ -29,6 +33,27 @@ static inline u16 scr_readw(const u16 *addr) return *addr; } +static inline void scr_memsetw(u16 *p, u16 v, unsigned int n) +{ + BUG_ON((long) p >= 0); + + memset16(p, cpu_to_le16(v), n / 2); +} + +static inline void scr_memcpyw(u16 *d, u16 *s, unsigned int n) +{ + BUG_ON((long) d >= 0); + + memcpy(d, s, n); +} + +static inline void scr_memmovew(u16 *d, u16 *s, unsigned int n) +{ + BUG_ON((long) d >= 0); + + memmove(d, s, n); +} + #define VGA_MAP_MEM(x,s) (x) #endif diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index d1c47e9f0090fad3de19279675dce729064ccad4..f3d4ac232690ce96cddc8db4fe1abb68e92790f6 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h @@ -52,6 +52,7 @@ struct vio_ver_info { #define VDEV_NETWORK_SWITCH 0x02 #define VDEV_DISK 0x03 #define VDEV_DISK_SERVER 0x04 +#define VDEV_CONSOLE_CON 0x05 u8 resv1[3]; u64 resv2[5]; @@ -282,6 +283,14 @@ struct vio_dring_state { struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES]; }; +#define VIO_TAG_SIZE ((int)sizeof(struct vio_msg_tag)) +#define VIO_VCC_MTU_SIZE (LDC_PACKET_SIZE - VIO_TAG_SIZE) + +struct vio_vcc { + struct vio_msg_tag tag; + char data[VIO_VCC_MTU_SIZE]; +}; + static inline void *vio_dring_cur(struct vio_dring_state *dr) { return dr->base + (dr->entry_size * dr->prod); diff --git a/arch/sparc/include/uapi/asm/siginfo.h b/arch/sparc/include/uapi/asm/siginfo.h index 2d9b79ccaa50263be9582f6c317b7ab7bb96a948..157f46fe374f5cb1fc54d0ea3ca75958440e995e 100644 --- a/arch/sparc/include/uapi/asm/siginfo.h +++ b/arch/sparc/include/uapi/asm/siginfo.h @@ -16,10 +16,17 @@ #define SI_NOINFO 32767 /* no information in siginfo_t */ +/* + * SIGFPE si_codes + */ +#ifdef __KERNEL__ +#define FPE_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ + /* * SIGEMT si_codes */ -#define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */ +#define EMT_TAGOVF 1 /* tag overflow */ #define NSIGEMT 1 #endif /* _UAPI__SPARC_SIGINFO_H */ diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 186fd8199f5487f7f2947c5649176d343064a611..b2f5c50d09474b8c5c20a5c153d0834f7196bc4a 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -98,6 +98,8 @@ #define SO_PEERGROUPS 0x003d +#define SO_ZEROCOPY 0x003e + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 493e023a468a919c61d77451e43e0a4a2e414bbe..ef4f18f7a67402ed8baceb2ea05ee7f6368cc404 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -506,6 +506,12 @@ static void __init sun4v_cpu_probe(void) sparc_pmu_type = "sparc-m7"; break; + case SUN4V_CHIP_SPARC_M8: + sparc_cpu_type = "SPARC-M8"; + sparc_fpu_type = "SPARC-M8 integrated FPU"; + sparc_pmu_type = "sparc-m8"; + break; + case SUN4V_CHIP_SPARC_SN: sparc_cpu_type = "SPARC-SN"; sparc_fpu_type = "SPARC-SN integrated FPU"; diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 45c820e1cba5d949ff936f15392ca3c0c8578a34..90d550bbfeefe484f1560940f111235f26332d7a 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -328,6 +328,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) case SUN4V_CHIP_NIAGARA5: case SUN4V_CHIP_SPARC_M6: case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_M8: case SUN4V_CHIP_SPARC_SN: case SUN4V_CHIP_SPARC64X: rover_inc_table = niagara_iterate_method; diff --git a/arch/sparc/kernel/etrap_64.S b/arch/sparc/kernel/etrap_64.S index 1276ca2567bab310771d214baa77876ea9e43f0e..5c237467d156f550740ce4ec3723bebf28976940 100644 --- a/arch/sparc/kernel/etrap_64.S +++ b/arch/sparc/kernel/etrap_64.S @@ -38,7 +38,11 @@ etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1) or %g1, %g3, %g1 bne,pn %xcc, 1f sub %sp, STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS, %g2 - wrpr %g0, 7, %cleanwin +661: wrpr %g0, 7, %cleanwin + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + .word 0x85880000 ! allclean + .previous sethi %hi(TASK_REGOFF), %g2 sethi %hi(TSTATE_PEF), %g3 @@ -88,16 +92,30 @@ etrap_save: save %g2, -STACK_BIAS, %sp bne,pn %xcc, 3f mov PRIMARY_CONTEXT, %l4 - rdpr %canrestore, %g3 +661: rdpr %canrestore, %g3 + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + nop + .previous + rdpr %wstate, %g2 - wrpr %g0, 0, %canrestore +661: wrpr %g0, 0, %canrestore + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + nop + .previous sll %g2, 3, %g2 /* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR. */ mov 1, %l5 sth %l5, [%l6 + TI_SYS_NOERROR] - wrpr %g3, 0, %otherwin +661: wrpr %g3, 0, %otherwin + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + .word 0x87880000 ! otherw + .previous + wrpr %g2, 0, %wstate sethi %hi(sparc64_kern_pri_context), %g2 ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3 diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 41a4073286671eff51f275bfca4ae6d9d01db74d..4de9fbd1a177ebcc02826469badc2eb32ca45643 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -424,22 +424,25 @@ EXPORT_SYMBOL(sun4v_chip_type) nop 70: ldub [%g1 + 7], %g2 - cmp %g2, '3' + cmp %g2, CPU_ID_NIAGARA3 be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA3, %g4 - cmp %g2, '4' + cmp %g2, CPU_ID_NIAGARA4 be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA4, %g4 - cmp %g2, '5' + cmp %g2, CPU_ID_NIAGARA5 be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA5, %g4 - cmp %g2, '6' + cmp %g2, CPU_ID_M6 be,pt %xcc, 5f mov SUN4V_CHIP_SPARC_M6, %g4 - cmp %g2, '7' + cmp %g2, CPU_ID_M7 be,pt %xcc, 5f mov SUN4V_CHIP_SPARC_M7, %g4 - cmp %g2, 'N' + cmp %g2, CPU_ID_M8 + be,pt %xcc, 5f + mov SUN4V_CHIP_SPARC_M8, %g4 + cmp %g2, CPU_ID_SONOMA1 be,pt %xcc, 5f mov SUN4V_CHIP_SPARC_SN, %g4 ba,pt %xcc, 49f @@ -448,10 +451,10 @@ EXPORT_SYMBOL(sun4v_chip_type) 91: sethi %hi(prom_cpu_compatible), %g1 or %g1, %lo(prom_cpu_compatible), %g1 ldub [%g1 + 17], %g2 - cmp %g2, '1' + cmp %g2, CPU_ID_NIAGARA1 be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA1, %g4 - cmp %g2, '2' + cmp %g2, CPU_ID_NIAGARA2 be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA2, %g4 @@ -600,7 +603,10 @@ niagara_tlb_fixup: be,pt %xcc, niagara4_patch nop cmp %g1, SUN4V_CHIP_SPARC_M7 - be,pt %xcc, niagara4_patch + be,pt %xcc, sparc_m7_patch + nop + cmp %g1, SUN4V_CHIP_SPARC_M8 + be,pt %xcc, sparc_m7_patch nop cmp %g1, SUN4V_CHIP_SPARC_SN be,pt %xcc, niagara4_patch @@ -615,6 +621,18 @@ niagara_tlb_fixup: ba,a,pt %xcc, 80f nop + +sparc_m7_patch: + call m7_patch_copyops + nop + call m7_patch_bzero + nop + call m7_patch_pageops + nop + + ba,a,pt %xcc, 80f + nop + niagara4_patch: call niagara4_patch_copyops nop @@ -875,7 +893,6 @@ sparc64_boot_end: #include "misctrap.S" #include "syscalls.S" #include "helpers.S" -#include "hvcalls.S" #include "sun4v_tlb_miss.S" #include "sun4v_ivec.S" #include "ktlb.S" @@ -920,6 +937,7 @@ swapper_4m_tsb: ! 0x0000000000428000 +#include "hvcalls.S" #include "systbls_64.S" .data diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 267731234ce8a2ee2cdc03686377c11a2ea6205f..d41ce33d87d68447427d5eced888f5f01a10df06 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c @@ -189,7 +189,7 @@ void __init sun4v_hvapi_init(void) group = HV_GRP_CORE; major = 1; - minor = 1; + minor = 6; if (sun4v_hvapi_register(group, major, &minor)) goto bad; diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index 4116ee5c77913221593421836eaae0803115a028..e57007ff7f8f946432add5cc97f1ad028b534a1d 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S @@ -106,6 +106,17 @@ ENTRY(sun4v_cpu_yield) nop ENDPROC(sun4v_cpu_yield) + /* %o0: cpuid + * + * returns %o0: status + */ +ENTRY(sun4v_cpu_poke) + mov HV_FAST_CPU_POKE, %o5 + ta HV_FAST_TRAP + retl + nop +ENDPROC(sun4v_cpu_poke) + /* %o0: type * %o1: queue paddr * %o2: num queue entries diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 840e0b21bfe31addc817bcbbf6a8cb70d6f9f72f..acffbc894ab0315362cca01a82bf6c90949a2a68 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1480,6 +1480,7 @@ int ldc_rx_reset(struct ldc_channel *lp) { return __set_rx_head(lp, lp->rx_tail); } +EXPORT_SYMBOL(ldc_rx_reset); void __ldc_print(struct ldc_channel *lp, const char *caller) { @@ -1493,6 +1494,7 @@ void __ldc_print(struct ldc_channel *lp, const char *caller) lp->tx_head, lp->tx_tail, lp->tx_num_entries, lp->rcv_nxt, lp->snd_nxt); } +EXPORT_SYMBOL(__ldc_print); static int write_raw(struct ldc_channel *lp, const void *buf, unsigned int size) { diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 4371f72ff02500d57c56343a254468375324490c..98c223edac84f47361cce51fa429026f15ed984f 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -25,6 +25,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) { LIST_HEAD(resources); struct pci_bus *root_bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; pci_add_resource_offset(&resources, &info->io_space, info->io_space.start - 0x1000); @@ -32,15 +38,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) info->busn.flags = IORESOURCE_BUS; pci_add_resource(&resources, &info->busn); - root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, - &resources); - if (!root_bus) { - pci_free_resource_list(&resources); + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = &ofdev->dev; + bridge->sysdata = info; + bridge->busnr = 0; + bridge->ops = info->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = info->map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); return; } - /* Setup IRQs of all devices using custom routines */ - pci_fixup_irqs(pci_common_swizzle, info->map_irq); + root_bus = bridge->bus; /* Assign devices with resources */ pci_assign_unassigned_resources(); @@ -94,9 +106,3 @@ void pcibios_fixup_bus(struct pci_bus *pbus) } } } - -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c index 1e77128a8f881b9670342d17f7f67d44d38b8698..83ba5005d44c1d59f4a5b773c602a50d7096d5bf 100644 --- a/arch/sparc/kernel/leon_pci_grpci1.c +++ b/arch/sparc/kernel/leon_pci_grpci1.c @@ -695,7 +695,7 @@ static int grpci1_of_probe(struct platform_device *ofdev) return err; } -static struct of_device_id grpci1_of_match[] = { +static const struct of_device_id grpci1_of_match[] __initconst = { { .name = "GAISLER_PCIFBRG", }, diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index f727c4de1316578505ed37aee52e39f9e9626ea5..ff0e5c90310fb1b287d3950e1148b1d8d9bd3ec3 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -886,7 +886,7 @@ static int grpci2_of_probe(struct platform_device *ofdev) return err; } -static struct of_device_id grpci2_of_match[] = { +static const struct of_device_id grpci2_of_match[] __initconst = { { .name = "GAISLER_GRPCI2", }, diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 7eceaa10836f0141472a7b71c445b4a65140a3e6..3f8670c9295115d4186762f89726a9ab7f55442f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -690,16 +690,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, return bus; } -void pcibios_fixup_bus(struct pci_bus *pbus) -{ -} - -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, oldcmd; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index f10e2f7123949dedc8904ea37895d402ed097d2b..9ebebf1fd93d2f5db8c09804c336b006041b28af 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1266,8 +1266,6 @@ static int pci_sun4v_probe(struct platform_device *op) * ATU group, but ATU hcalls won't be available. */ hv_atu = false; - pr_err(PFX "Could not register hvapi ATU err=%d\n", - err); } else { pr_info(PFX "Registered hvapi ATU major[%lu] minor[%lu]\n", vatu_major, vatu_minor); diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index a38787b843220807d0f5527f864981fc75e8486f..4a133c052af89cc7cbb2118bf16e60a40d428ec4 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -602,7 +602,7 @@ void pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev; int i, has_io, has_mem; - unsigned int cmd; + unsigned int cmd = 0; struct linux_pcic *pcic; /* struct linux_pbm_info* pbm = &pcic->pbm; */ int node; @@ -746,12 +746,6 @@ static void watchdog_reset() { } #endif -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - int pcibios_enable_device(struct pci_dev *pdev, int mask) { return 0; diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index b96104da5bd6116b119872eaa79e013636aa328c..44e5da405f9673210f63bee85ade543724a8e9be 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -77,8 +77,13 @@ void arch_cpu_idle(void) : "=&r" (pstate) : "i" (PSTATE_IE)); - if (!need_resched() && !cpu_is_offline(smp_processor_id())) + if (!need_resched() && !cpu_is_offline(smp_processor_id())) { sun4v_cpu_yield(); + /* If resumed by cpu_poke then we need to explicitly + * call scheduler_ipi(). + */ + scheduler_poke(); + } /* Re-enable interrupts. */ __asm__ __volatile__( diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 709a82ebd294c07bd4b87698c695325e5093a7e4..dff86fad0a1fde57548da37f62a2294714013230 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -224,10 +224,19 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 rdpr %otherwin, %l2 srl %l1, 3, %l1 - wrpr %l2, %g0, %canrestore +661: wrpr %l2, %g0, %canrestore + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + .word 0x89880000 ! normalw + .previous + wrpr %l1, %g0, %wstate brnz,pt %l2, user_rtt_restore - wrpr %g0, %g0, %otherwin +661: wrpr %g0, %g0, %otherwin + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + nop + .previous ldx [%g6 + TI_FLAGS], %g3 wr %g0, ASI_AIUP, %asi diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 4d9c3e13c15056b5d60e7ccd266b36cfe29d2c00..db4c4d7e28a07a040fd48b39a3698198d41ddd42 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -288,10 +288,22 @@ static void __init sun4v_patch(void) sun4v_patch_2insn_range(&__sun4v_2insn_patch, &__sun4v_2insn_patch_end); - if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || - sun4v_chip_type == SUN4V_CHIP_SPARC_SN) + + switch (sun4v_chip_type) { + case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_M8: + case SUN4V_CHIP_SPARC_SN: sun_m7_patch_2insn_range(&__sun_m7_2insn_patch, &__sun_m7_2insn_patch_end); + break; + default: + break; + } + + if (sun4v_chip_type != SUN4V_CHIP_NIAGARA1) { + sun4v_patch_1insn_range(&__fast_win_ctrl_1insn_patch, + &__fast_win_ctrl_1insn_patch_end); + } sun4v_hvapi_init(); } @@ -356,6 +368,7 @@ void __init start_early_boot(void) check_if_starfire(); per_cpu_patch(); sun4v_patch(); + smp_init_cpu_poke(); cpu = hard_smp_processor_id(); if (cpu >= NR_CPUS) { @@ -529,6 +542,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_M8 || sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= HWCAP_SPARC_BLKINIT; @@ -538,6 +552,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_M8 || sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= HWCAP_SPARC_N2; @@ -568,6 +583,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_M8 || sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | @@ -578,6 +594,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_M8 || sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index b4096bb665b2dd736fd1da18d0b756d081d4100c..0e4c08c45a37b0d704fce734a3109c089cc6ae2f 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -85,34 +85,34 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_TIMER >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); default: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user(from->si_trapno, &to->si_trapno); err |= __put_user((unsigned long)from->si_addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 3218bc43302e1cbbfc48420d868f5148a8d61085..4898329970c50d816196d6eaf632b8e02445d24a 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -74,6 +74,9 @@ EXPORT_SYMBOL(cpu_core_sib_cache_map); static cpumask_t smp_commenced_mask; +static DEFINE_PER_CPU(bool, poke); +static bool cpu_poke; + void smp_info(struct seq_file *m) { int i; @@ -1439,15 +1442,86 @@ void __init smp_cpus_done(unsigned int max_cpus) { } +static void send_cpu_ipi(int cpu) +{ + xcall_deliver((u64) &xcall_receive_signal, + 0, 0, cpumask_of(cpu)); +} + +void scheduler_poke(void) +{ + if (!cpu_poke) + return; + + if (!__this_cpu_read(poke)) + return; + + __this_cpu_write(poke, false); + set_softint(1 << PIL_SMP_RECEIVE_SIGNAL); +} + +static unsigned long send_cpu_poke(int cpu) +{ + unsigned long hv_err; + + per_cpu(poke, cpu) = true; + hv_err = sun4v_cpu_poke(cpu); + if (hv_err != HV_EOK) { + per_cpu(poke, cpu) = false; + pr_err_ratelimited("%s: sun4v_cpu_poke() fails err=%lu\n", + __func__, hv_err); + } + + return hv_err; +} + void smp_send_reschedule(int cpu) { if (cpu == smp_processor_id()) { WARN_ON_ONCE(preemptible()); set_softint(1 << PIL_SMP_RECEIVE_SIGNAL); - } else { - xcall_deliver((u64) &xcall_receive_signal, - 0, 0, cpumask_of(cpu)); + return; + } + + /* Use cpu poke to resume idle cpu if supported. */ + if (cpu_poke && idle_cpu(cpu)) { + unsigned long ret; + + ret = send_cpu_poke(cpu); + if (ret == HV_EOK) + return; } + + /* Use IPI in following cases: + * - cpu poke not supported + * - cpu not idle + * - send_cpu_poke() returns with error + */ + send_cpu_ipi(cpu); +} + +void smp_init_cpu_poke(void) +{ + unsigned long major; + unsigned long minor; + int ret; + + if (tlb_type != hypervisor) + return; + + ret = sun4v_hvapi_get(HV_GRP_CORE, &major, &minor); + if (ret) { + pr_debug("HV_GRP_CORE is not registered\n"); + return; + } + + if (major == 1 && minor >= 6) { + /* CPU POKE is registered. */ + cpu_poke = true; + return; + } + + pr_debug("CPU_POKE not supported\n"); } void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index 466d4aed06c771a9d3c523f6777dac8f7fc80f5f..581cf35ee7e3a7c18c9c0578ca495b8c877f3adf 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c @@ -306,7 +306,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, info.si_errno = 0; info.si_addr = (void __user *)pc; info.si_trapno = 0; - info.si_code = __SI_FAULT; + info.si_code = FPE_FIXME; if ((fsr & 0x1c000) == (1 << 14)) { if (fsr & 0x10) info.si_code = FPE_FLTINV; diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index ad31af1dd726575986c87bba514b345f291342ec..0a56dc257cb9a687292817962f9a94eaebd4bd3c 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -265,6 +265,45 @@ void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u sun4v_insn_access_exception(regs, addr, type_ctx); } +bool is_no_fault_exception(struct pt_regs *regs) +{ + unsigned char asi; + u32 insn; + + if (get_user(insn, (u32 __user *)regs->tpc) == -EFAULT) + return false; + + /* + * Must do a little instruction decoding here in order to + * decide on a course of action. The bits of interest are: + * insn[31:30] = op, where 3 indicates the load/store group + * insn[24:19] = op3, which identifies individual opcodes + * insn[13] indicates an immediate offset + * op3[4]=1 identifies alternate space instructions + * op3[5:4]=3 identifies floating point instructions + * op3[2]=1 identifies stores + * See "Opcode Maps" in the appendix of any Sparc V9 + * architecture spec for full details. + */ + if ((insn & 0xc0800000) == 0xc0800000) { /* op=3, op3[4]=1 */ + if (insn & 0x2000) /* immediate offset */ + asi = (regs->tstate >> 24); /* saved %asi */ + else + asi = (insn >> 5); /* immediate asi */ + if ((asi & 0xf2) == ASI_PNF) { + if (insn & 0x1000000) { /* op3[5:4]=3 */ + handle_ldf_stq(insn, regs); + return true; + } else if (insn & 0x200000) { /* op3[2], stores */ + return false; + } + handle_ld_nf(insn, regs); + return true; + } + } + return false; +} + void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { enum ctx_state prev_state = exception_enter(); @@ -296,6 +335,9 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un die_if_kernel("Dax", regs); } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; @@ -352,6 +394,9 @@ void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsig regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; @@ -2258,7 +2303,7 @@ static void do_fpe_common(struct pt_regs *regs) info.si_errno = 0; info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; - info.si_code = __SI_FAULT; + info.si_code = FPE_FIXME; if ((fsr & 0x1c000) == (1 << 14)) { if (fsr & 0x10) info.si_code = FPE_FLTINV; @@ -2575,6 +2620,9 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc)); goto out; } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; @@ -2597,6 +2645,9 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc)); return; } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index 07c0df92496034efd1262dd2b40e56ffd5486c0c..f74115364b1eff6053f40ad224c070070e517249 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S @@ -117,7 +117,7 @@ tsb_miss_page_table_walk_sun4v_fastpath: /* Valid PTE is now in %g5. */ #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) - sethi %uhi(_PAGE_PMD_HUGE), %g7 + sethi %uhi(_PAGE_PMD_HUGE | _PAGE_PUD_HUGE), %g7 sllx %g7, 32, %g7 andcc %g5, %g7, %g0 @@ -360,6 +360,7 @@ tsb_flush: * %o1: TSB base config pointer * %o2: TSB huge config pointer, or NULL if none * %o3: Hypervisor TSB descriptor physical address + * %o4: Secondary context to load, if non-zero * * We have to run this whole thing with interrupts * disabled so that the current cpu doesn't change @@ -372,6 +373,17 @@ __tsb_context_switch: rdpr %pstate, %g1 wrpr %g1, PSTATE_IE, %pstate + brz,pn %o4, 1f + mov SECONDARY_CONTEXT, %o5 + +661: stxa %o4, [%o5] ASI_DMMU + .section .sun4v_1insn_patch, "ax" + .word 661b + stxa %o4, [%o5] ASI_MMU + .previous + flush %g6 + +1: TRAP_LOAD_TRAP_BLOCK(%g2, %g3) stx %o0, [%g2 + TRAP_PER_CPU_PGD_PADDR] diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 1c8763c9c52b292b85cccdc544e034ba318d564f..da1ac3f22b245d8a69f8b0cfa16f71eec4b47465 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -246,6 +246,7 @@ u64 vio_vdev_node(struct mdesc_handle *hp, struct vio_dev *vdev) return node; } +EXPORT_SYMBOL(vio_vdev_node); static void vio_fill_channel_info(struct mdesc_handle *hp, u64 mp, struct vio_dev *vdev) diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index d4f13c037a40a3b63b1e39c771c279c730b9ea31..dcd278f295736384ed91e7f21a7c4726499d620e 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c @@ -814,15 +814,21 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, case VDEV_NETWORK_SWITCH: case VDEV_DISK: case VDEV_DISK_SERVER: + case VDEV_CONSOLE_CON: break; default: return -EINVAL; } - if (!ops || !ops->send_attr || !ops->handle_attr || - !ops->handshake_complete) - return -EINVAL; + if (dev_class == VDEV_NETWORK || + dev_class == VDEV_NETWORK_SWITCH || + dev_class == VDEV_DISK || + dev_class == VDEV_DISK_SERVER) { + if (!ops || !ops->send_attr || !ops->handle_attr || + !ops->handshake_complete) + return -EINVAL; + } if (!ver_table || ver_table_size < 0) return -EINVAL; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 03b3d65d1266d3e3c0de536406d4ae0c9f959c92..d78847d56a4b492f1ceee02be2fb1acac94c7134 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -154,6 +154,16 @@ SECTIONS *(.get_tick_patch) __get_tick_patch_end = .; } + .pud_huge_patch : { + __pud_huge_patch = .; + *(.pud_huge_patch) + __pud_huge_patch_end = .; + } + .fast_win_ctrl_1insn_patch : { + __fast_win_ctrl_1insn_patch = .; + *(.fast_win_ctrl_1insn_patch) + __fast_win_ctrl_1insn_patch_end = .; + } PERCPU_SECTION(SMP_CACHE_BYTES) #ifdef CONFIG_JUMP_LABEL diff --git a/arch/sparc/lib/M7copy_from_user.S b/arch/sparc/lib/M7copy_from_user.S new file mode 100644 index 0000000000000000000000000000000000000000..66464b3e364984d4234f991f406b24e83cffaa68 --- /dev/null +++ b/arch/sparc/lib/M7copy_from_user.S @@ -0,0 +1,40 @@ +/* + * M7copy_from_user.S: SPARC M7 optimized copy from userspace. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + + +#define EX_LD(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y; \ + .text; \ + .align 4; + +#define EX_LD_FP(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y##_fp; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#define FUNC_NAME M7copy_from_user +#define LOAD(type,addr,dest) type##a [addr] %asi, dest +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, raw_copy_in_user; \ + nop +#endif + +#include "M7memcpy.S" diff --git a/arch/sparc/lib/M7copy_to_user.S b/arch/sparc/lib/M7copy_to_user.S new file mode 100644 index 0000000000000000000000000000000000000000..a60ac467f808d260d2deda875614af12ec33150e --- /dev/null +++ b/arch/sparc/lib/M7copy_to_user.S @@ -0,0 +1,51 @@ +/* + * M7copy_to_user.S: SPARC M7 optimized copy to userspace. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + + +#define EX_ST(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y; \ + .text; \ + .align 4; + +#define EX_ST_FP(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y##_fp; \ + .text; \ + .align 4; + + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#ifndef ASI_BLK_INIT_QUAD_LDD_AIUS +#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 +#endif + +#define FUNC_NAME M7copy_to_user +#define STORE(type,src,addr) type##a src, [addr] %asi +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_AIUS +#define STORE_MRU_ASI ASI_ST_BLKINIT_MRU_S +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ + /* Writing to %asi is _expensive_ so we hardcode it. + * Reading %asi to check for KERNEL_DS is comparatively + * cheap. + */ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, raw_copy_in_user; \ + nop +#endif + +#include "M7memcpy.S" diff --git a/arch/sparc/lib/M7memcpy.S b/arch/sparc/lib/M7memcpy.S new file mode 100644 index 0000000000000000000000000000000000000000..cbd42ea7c3f7c25a369536eaf8d0b28a808ae5ba --- /dev/null +++ b/arch/sparc/lib/M7memcpy.S @@ -0,0 +1,923 @@ +/* + * M7memcpy: Optimized SPARC M7 memcpy + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + + .file "M7memcpy.S" + +/* + * memcpy(s1, s2, len) + * + * Copy s2 to s1, always copy n bytes. + * Note: this C code does not work for overlapped copies. + * + * Fast assembler language version of the following C-program for memcpy + * which represents the `standard' for the C-library. + * + * void * + * memcpy(void *s, const void *s0, size_t n) + * { + * if (n != 0) { + * char *s1 = s; + * const char *s2 = s0; + * do { + * *s1++ = *s2++; + * } while (--n != 0); + * } + * return (s); + * } + * + * + * SPARC T7/M7 Flow : + * + * if (count < SMALL_MAX) { + * if count < SHORTCOPY (SHORTCOPY=3) + * copy bytes; exit with dst addr + * if src & dst aligned on word boundary but not long word boundary, + * copy with ldw/stw; branch to finish_up + * if src & dst aligned on long word boundary + * copy with ldx/stx; branch to finish_up + * if src & dst not aligned and length <= SHORTCHECK (SHORTCHECK=14) + * copy bytes; exit with dst addr + * move enough bytes to get src to word boundary + * if dst now on word boundary + * move_words: + * copy words; branch to finish_up + * if dst now on half word boundary + * load words, shift half words, store words; branch to finish_up + * if dst on byte 1 + * load words, shift 3 bytes, store words; branch to finish_up + * if dst on byte 3 + * load words, shift 1 byte, store words; branch to finish_up + * finish_up: + * copy bytes; exit with dst addr + * } else { More than SMALL_MAX bytes + * move bytes until dst is on long word boundary + * if( src is on long word boundary ) { + * if (count < MED_MAX) { + * finish_long: src/dst aligned on 8 bytes + * copy with ldx/stx in 8-way unrolled loop; + * copy final 0-63 bytes; exit with dst addr + * } else { src/dst aligned; count > MED_MAX + * align dst on 64 byte boundary; for main data movement: + * prefetch src data to L2 cache; let HW prefetch move data to L1 cache + * Use BIS (block initializing store) to avoid copying store cache + * lines from memory. But pre-store first element of each cache line + * ST_CHUNK lines in advance of the rest of that cache line. That + * gives time for replacement cache lines to be written back without + * excess STQ and Miss Buffer filling. Repeat until near the end, + * then finish up storing before going to finish_long. + * } + * } else { src/dst not aligned on 8 bytes + * if src is word aligned and count < MED_WMAX + * move words in 8-way unrolled loop + * move final 0-31 bytes; exit with dst addr + * if count < MED_UMAX + * use alignaddr/faligndata combined with ldd/std in 8-way + * unrolled loop to move data. + * go to unalign_done + * else + * setup alignaddr for faligndata instructions + * align dst on 64 byte boundary; prefetch src data to L1 cache + * loadx8, falign, block-store, prefetch loop + * (only use block-init-store when src/dst on 8 byte boundaries.) + * unalign_done: + * move remaining bytes for unaligned cases. exit with dst addr. + * } + * + */ + +#include +#include + +#if !defined(EX_LD) && !defined(EX_ST) +#define NON_USER_COPY +#endif + +#ifndef EX_LD +#define EX_LD(x,y) x +#endif +#ifndef EX_LD_FP +#define EX_LD_FP(x,y) x +#endif + +#ifndef EX_ST +#define EX_ST(x,y) x +#endif +#ifndef EX_ST_FP +#define EX_ST_FP(x,y) x +#endif + +#ifndef EX_RETVAL +#define EX_RETVAL(x) x +#endif + +#ifndef LOAD +#define LOAD(type,addr,dest) type [addr], dest +#endif + +#ifndef STORE +#define STORE(type,src,addr) type src, [addr] +#endif + +/* + * ASI_BLK_INIT_QUAD_LDD_P/ASI_BLK_INIT_QUAD_LDD_S marks the cache + * line as "least recently used" which means if many threads are + * active, it has a high probability of being pushed out of the cache + * between the first initializing store and the final stores. + * Thus, we use ASI_ST_BLKINIT_MRU_P/ASI_ST_BLKINIT_MRU_S which + * marks the cache line as "most recently used" for all + * but the last cache line + */ +#ifndef STORE_ASI +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P +#else +#define STORE_ASI 0x80 /* ASI_P */ +#endif +#endif + +#ifndef STORE_MRU_ASI +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA +#define STORE_MRU_ASI ASI_ST_BLKINIT_MRU_P +#else +#define STORE_MRU_ASI 0x80 /* ASI_P */ +#endif +#endif + +#ifndef STORE_INIT +#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI +#endif + +#ifndef STORE_INIT_MRU +#define STORE_INIT_MRU(src,addr) stxa src, [addr] STORE_MRU_ASI +#endif + +#ifndef FUNC_NAME +#define FUNC_NAME M7memcpy +#endif + +#ifndef PREAMBLE +#define PREAMBLE +#endif + +#define BLOCK_SIZE 64 +#define SHORTCOPY 3 +#define SHORTCHECK 14 +#define SHORT_LONG 64 /* max copy for short longword-aligned case */ + /* must be at least 64 */ +#define SMALL_MAX 128 +#define MED_UMAX 1024 /* max copy for medium un-aligned case */ +#define MED_WMAX 1024 /* max copy for medium word-aligned case */ +#define MED_MAX 1024 /* max copy for medium longword-aligned case */ +#define ST_CHUNK 24 /* ST_CHUNK - block of values for BIS Store */ +#define ALIGN_PRE 24 /* distance for aligned prefetch loop */ + + .register %g2,#scratch + + .section ".text" + .global FUNC_NAME + .type FUNC_NAME, #function + .align 16 +FUNC_NAME: + srlx %o2, 31, %g2 + cmp %g2, 0 + tne %xcc, 5 + PREAMBLE + mov %o0, %g1 ! save %o0 + brz,pn %o2, .Lsmallx + cmp %o2, 3 + ble,pn %icc, .Ltiny_cp + cmp %o2, 19 + ble,pn %icc, .Lsmall_cp + or %o0, %o1, %g2 + cmp %o2, SMALL_MAX + bl,pn %icc, .Lmedium_cp + nop + +.Lmedium: + neg %o0, %o5 + andcc %o5, 7, %o5 ! bytes till DST 8 byte aligned + brz,pt %o5, .Ldst_aligned_on_8 + + ! %o5 has the bytes to be written in partial store. + sub %o2, %o5, %o2 + sub %o1, %o0, %o1 ! %o1 gets the difference +7: ! dst aligning loop + add %o1, %o0, %o4 + EX_LD(LOAD(ldub, %o4, %o4), memcpy_retl_o2_plus_o5) ! load one byte + subcc %o5, 1, %o5 + EX_ST(STORE(stb, %o4, %o0), memcpy_retl_o2_plus_o5_plus_1) + bgu,pt %xcc, 7b + add %o0, 1, %o0 ! advance dst + add %o1, %o0, %o1 ! restore %o1 +.Ldst_aligned_on_8: + andcc %o1, 7, %o5 + brnz,pt %o5, .Lsrc_dst_unaligned_on_8 + nop + +.Lsrc_dst_aligned_on_8: + ! check if we are copying MED_MAX or more bytes + set MED_MAX, %o3 + cmp %o2, %o3 ! limit to store buffer size + bgu,pn %xcc, .Llarge_align8_copy + nop + +/* + * Special case for handling when src and dest are both long word aligned + * and total data to move is less than MED_MAX bytes + */ +.Lmedlong: + subcc %o2, 63, %o2 ! adjust length to allow cc test + ble,pn %xcc, .Lmedl63 ! skip big loop if less than 64 bytes + nop +.Lmedl64: + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_63) ! load + subcc %o2, 64, %o2 ! decrement length count + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_63_64) ! and store + EX_LD(LOAD(ldx, %o1+8, %o3), memcpy_retl_o2_plus_63_56) ! a block of 64 + EX_ST(STORE(stx, %o3, %o0+8), memcpy_retl_o2_plus_63_56) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_63_48) + EX_ST(STORE(stx, %o4, %o0+16), memcpy_retl_o2_plus_63_48) + EX_LD(LOAD(ldx, %o1+24, %o3), memcpy_retl_o2_plus_63_40) + EX_ST(STORE(stx, %o3, %o0+24), memcpy_retl_o2_plus_63_40) + EX_LD(LOAD(ldx, %o1+32, %o4), memcpy_retl_o2_plus_63_32)! load and store + EX_ST(STORE(stx, %o4, %o0+32), memcpy_retl_o2_plus_63_32) + EX_LD(LOAD(ldx, %o1+40, %o3), memcpy_retl_o2_plus_63_24)! a block of 64 + add %o1, 64, %o1 ! increase src ptr by 64 + EX_ST(STORE(stx, %o3, %o0+40), memcpy_retl_o2_plus_63_24) + EX_LD(LOAD(ldx, %o1-16, %o4), memcpy_retl_o2_plus_63_16) + add %o0, 64, %o0 ! increase dst ptr by 64 + EX_ST(STORE(stx, %o4, %o0-16), memcpy_retl_o2_plus_63_16) + EX_LD(LOAD(ldx, %o1-8, %o3), memcpy_retl_o2_plus_63_8) + bgu,pt %xcc, .Lmedl64 ! repeat if at least 64 bytes left + EX_ST(STORE(stx, %o3, %o0-8), memcpy_retl_o2_plus_63_8) +.Lmedl63: + addcc %o2, 32, %o2 ! adjust remaining count + ble,pt %xcc, .Lmedl31 ! to skip if 31 or fewer bytes left + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_31) ! load + sub %o2, 32, %o2 ! decrement length count + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_31_32) ! and store + EX_LD(LOAD(ldx, %o1+8, %o3), memcpy_retl_o2_plus_31_24) ! a block of 32 + add %o1, 32, %o1 ! increase src ptr by 32 + EX_ST(STORE(stx, %o3, %o0+8), memcpy_retl_o2_plus_31_24) + EX_LD(LOAD(ldx, %o1-16, %o4), memcpy_retl_o2_plus_31_16) + add %o0, 32, %o0 ! increase dst ptr by 32 + EX_ST(STORE(stx, %o4, %o0-16), memcpy_retl_o2_plus_31_16) + EX_LD(LOAD(ldx, %o1-8, %o3), memcpy_retl_o2_plus_31_8) + EX_ST(STORE(stx, %o3, %o0-8), memcpy_retl_o2_plus_31_8) +.Lmedl31: + addcc %o2, 16, %o2 ! adjust remaining count + ble,pt %xcc, .Lmedl15 ! skip if 15 or fewer bytes left + nop ! + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_15) + add %o1, 16, %o1 ! increase src ptr by 16 + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_15) + sub %o2, 16, %o2 ! decrease count by 16 + EX_LD(LOAD(ldx, %o1-8, %o3), memcpy_retl_o2_plus_15_8) + add %o0, 16, %o0 ! increase dst ptr by 16 + EX_ST(STORE(stx, %o3, %o0-8), memcpy_retl_o2_plus_15_8) +.Lmedl15: + addcc %o2, 15, %o2 ! restore count + bz,pt %xcc, .Lsmallx ! exit if finished + cmp %o2, 8 + blt,pt %xcc, .Lmedw7 ! skip if 7 or fewer bytes left + tst %o2 + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) ! load 8 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + add %o0, 8, %o0 ! increase dst ptr by 8 + subcc %o2, 8, %o2 ! decrease count by 8 + bnz,pn %xcc, .Lmedw7 + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) ! and store 8 + retl + mov EX_RETVAL(%g1), %o0 ! restore %o0 + + .align 16 +.Lsrc_dst_unaligned_on_8: + ! DST is 8-byte aligned, src is not +2: + andcc %o1, 0x3, %o5 ! test word alignment + bnz,pt %xcc, .Lunalignsetup ! branch to skip if not word aligned + nop + +/* + * Handle all cases where src and dest are aligned on word + * boundaries. Use unrolled loops for better performance. + * This option wins over standard large data move when + * source and destination is in cache for.Lmedium + * to short data moves. + */ + set MED_WMAX, %o3 + cmp %o2, %o3 ! limit to store buffer size + bge,pt %xcc, .Lunalignrejoin ! otherwise rejoin main loop + nop + + subcc %o2, 31, %o2 ! adjust length to allow cc test + ! for end of loop + ble,pt %xcc, .Lmedw31 ! skip big loop if less than 16 +.Lmedw32: + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2_plus_31)! move a block of 32 + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1+4, %o4), memcpy_retl_o2_plus_31) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_31) + subcc %o2, 32, %o2 ! decrement length count + EX_LD(LOAD(ld, %o1+8, %o4), memcpy_retl_o2_plus_31_24) + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1+12, %o4), memcpy_retl_o2_plus_31_24) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0+8), memcpy_retl_o2_plus_31_24) + add %o1, 32, %o1 ! increase src ptr by 32 + EX_LD(LOAD(ld, %o1-16, %o4), memcpy_retl_o2_plus_31_16) + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1-12, %o4), memcpy_retl_o2_plus_31_16) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0+16), memcpy_retl_o2_plus_31_16) + add %o0, 32, %o0 ! increase dst ptr by 32 + EX_LD(LOAD(ld, %o1-8, %o4), memcpy_retl_o2_plus_31_8) + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1-4, %o4), memcpy_retl_o2_plus_31_8) + or %o4, %o5, %o5 + bgu,pt %xcc, .Lmedw32 ! repeat if at least 32 bytes left + EX_ST(STORE(stx, %o5, %o0-8), memcpy_retl_o2_plus_31_8) +.Lmedw31: + addcc %o2, 31, %o2 ! restore count + + bz,pt %xcc, .Lsmallx ! exit if finished + nop + cmp %o2, 16 + blt,pt %xcc, .Lmedw15 + nop + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2)! move a block of 16 bytes + sllx %o4, 32, %o5 + subcc %o2, 16, %o2 ! decrement length count + EX_LD(LOAD(ld, %o1+4, %o4), memcpy_retl_o2_plus_16) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_16) + add %o1, 16, %o1 ! increase src ptr by 16 + EX_LD(LOAD(ld, %o1-8, %o4), memcpy_retl_o2_plus_8) + add %o0, 16, %o0 ! increase dst ptr by 16 + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1-4, %o4), memcpy_retl_o2_plus_8) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0-8), memcpy_retl_o2_plus_8) +.Lmedw15: + bz,pt %xcc, .Lsmallx ! exit if finished + cmp %o2, 8 + blt,pn %xcc, .Lmedw7 ! skip if 7 or fewer bytes left + tst %o2 + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2) ! load 4 bytes + subcc %o2, 8, %o2 ! decrease count by 8 + EX_ST(STORE(stw, %o4, %o0), memcpy_retl_o2_plus_8)! and store 4 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + EX_LD(LOAD(ld, %o1-4, %o3), memcpy_retl_o2_plus_4) ! load 4 bytes + add %o0, 8, %o0 ! increase dst ptr by 8 + EX_ST(STORE(stw, %o3, %o0-4), memcpy_retl_o2_plus_4)! and store 4 bytes + bz,pt %xcc, .Lsmallx ! exit if finished +.Lmedw7: ! count is ge 1, less than 8 + cmp %o2, 4 ! check for 4 bytes left + blt,pn %xcc, .Lsmallleft3 ! skip if 3 or fewer bytes left + nop ! + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2) ! load 4 bytes + add %o1, 4, %o1 ! increase src ptr by 4 + add %o0, 4, %o0 ! increase dst ptr by 4 + subcc %o2, 4, %o2 ! decrease count by 4 + bnz .Lsmallleft3 + EX_ST(STORE(stw, %o4, %o0-4), memcpy_retl_o2_plus_4)! and store 4 bytes + retl + mov EX_RETVAL(%g1), %o0 + + .align 16 +.Llarge_align8_copy: ! Src and dst share 8 byte alignment + ! align dst to 64 byte boundary + andcc %o0, 0x3f, %o3 ! %o3 == 0 means dst is 64 byte aligned + brz,pn %o3, .Laligned_to_64 + andcc %o0, 8, %o3 ! odd long words to move? + brz,pt %o3, .Laligned_to_16 + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) + sub %o2, 8, %o2 + add %o1, 8, %o1 ! increment src ptr + add %o0, 8, %o0 ! increment dst ptr + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) +.Laligned_to_16: + andcc %o0, 16, %o3 ! pair of long words to move? + brz,pt %o3, .Laligned_to_32 + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) + sub %o2, 16, %o2 + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_16) + add %o1, 16, %o1 ! increment src ptr + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_8) + add %o0, 16, %o0 ! increment dst ptr + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) +.Laligned_to_32: + andcc %o0, 32, %o3 ! four long words to move? + brz,pt %o3, .Laligned_to_64 + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) + sub %o2, 32, %o2 + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_32) + EX_LD(LOAD(ldx, %o1+8, %o4), memcpy_retl_o2_plus_24) + EX_ST(STORE(stx, %o4, %o0+8), memcpy_retl_o2_plus_24) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_16) + EX_ST(STORE(stx, %o4, %o0+16), memcpy_retl_o2_plus_16) + add %o1, 32, %o1 ! increment src ptr + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_8) + add %o0, 32, %o0 ! increment dst ptr + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) +.Laligned_to_64: +! +! Using block init store (BIS) instructions to avoid fetching cache +! lines from memory. Use ST_CHUNK stores to first element of each cache +! line (similar to prefetching) to avoid overfilling STQ or miss buffers. +! Gives existing cache lines time to be moved out of L1/L2/L3 cache. +! Initial stores using MRU version of BIS to keep cache line in +! cache until we are ready to store final element of cache line. +! Then store last element using the LRU version of BIS. +! + andn %o2, 0x3f, %o5 ! %o5 is multiple of block size + and %o2, 0x3f, %o2 ! residue bytes in %o2 +! +! We use STORE_MRU_ASI for the first seven stores to each cache line +! followed by STORE_ASI (mark as LRU) for the last store. That +! mixed approach reduces the probability that the cache line is removed +! before we finish setting it, while minimizing the effects on +! other cached values during a large memcpy +! +! ST_CHUNK batches up initial BIS operations for several cache lines +! to allow multiple requests to not be blocked by overflowing the +! the store miss buffer. Then the matching stores for all those +! BIS operations are executed. +! + + sub %o0, 8, %o0 ! adjust %o0 for ASI alignment +.Lalign_loop: + cmp %o5, ST_CHUNK*64 + blu,pt %xcc, .Lalign_loop_fin + mov ST_CHUNK,%o3 +.Lalign_loop_start: + prefetch [%o1 + (ALIGN_PRE * BLOCK_SIZE)], 21 + subcc %o3, 1, %o3 + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_o5) + add %o1, 64, %o1 + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + bgu %xcc,.Lalign_loop_start + add %o0, 56, %o0 + + mov ST_CHUNK,%o3 + sllx %o3, 6, %o4 ! ST_CHUNK*64 + sub %o1, %o4, %o1 ! reset %o1 + sub %o0, %o4, %o0 ! reset %o0 + +.Lalign_loop_rest: + EX_LD(LOAD(ldx, %o1+8, %o4), memcpy_retl_o2_plus_o5) + add %o0, 16, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + subcc %o3, 1, %o3 + EX_LD(LOAD(ldx, %o1+24, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+32, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+40, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+48, %o4), memcpy_retl_o2_plus_o5) + add %o1, 64, %o1 + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_o5) + sub %o5, 64, %o5 + bgu %xcc,.Lalign_loop_rest + ! mark cache line as LRU + EX_ST(STORE_INIT(%o4, %o0), memcpy_retl_o2_plus_o5_plus_64) + + cmp %o5, ST_CHUNK*64 + bgu,pt %xcc, .Lalign_loop_start + mov ST_CHUNK,%o3 + + cmp %o5, 0 + beq .Lalign_done + nop +.Lalign_loop_fin: + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_o5) + EX_ST(STORE(stx, %o4, %o0+8), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+8, %o4), memcpy_retl_o2_plus_o5) + EX_ST(STORE(stx, %o4, %o0+8+8), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_o5) + EX_ST(STORE(stx, %o4, %o0+8+16), memcpy_retl_o2_plus_o5) + subcc %o5, 64, %o5 + EX_LD(LOAD(ldx, %o1+24, %o4), memcpy_retl_o2_plus_o5_64) + EX_ST(STORE(stx, %o4, %o0+8+24), memcpy_retl_o2_plus_o5_64) + EX_LD(LOAD(ldx, %o1+32, %o4), memcpy_retl_o2_plus_o5_64) + EX_ST(STORE(stx, %o4, %o0+8+32), memcpy_retl_o2_plus_o5_64) + EX_LD(LOAD(ldx, %o1+40, %o4), memcpy_retl_o2_plus_o5_64) + EX_ST(STORE(stx, %o4, %o0+8+40), memcpy_retl_o2_plus_o5_64) + EX_LD(LOAD(ldx, %o1+48, %o4), memcpy_retl_o2_plus_o5_64) + add %o1, 64, %o1 + EX_ST(STORE(stx, %o4, %o0+8+48), memcpy_retl_o2_plus_o5_64) + add %o0, 64, %o0 + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_o5_64) + bgu %xcc,.Lalign_loop_fin + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_o5_64) + +.Lalign_done: + add %o0, 8, %o0 ! restore %o0 from ASI alignment + membar #StoreStore + sub %o2, 63, %o2 ! adjust length to allow cc test + ba .Lmedl63 ! in .Lmedl63 + nop + + .align 16 + ! Dst is on 8 byte boundary; src is not; remaining count > SMALL_MAX +.Lunalignsetup: +.Lunalignrejoin: + mov %g1, %o3 ! save %g1 as VISEntryHalf clobbers it +#ifdef NON_USER_COPY + VISEntryHalfFast(.Lmedium_vis_entry_fail_cp) +#else + VISEntryHalf +#endif + mov %o3, %g1 ! restore %g1 + + set MED_UMAX, %o3 + cmp %o2, %o3 ! check for.Lmedium unaligned limit + bge,pt %xcc,.Lunalign_large + prefetch [%o1 + (4 * BLOCK_SIZE)], 20 + andn %o2, 0x3f, %o5 ! %o5 is multiple of block size + and %o2, 0x3f, %o2 ! residue bytes in %o2 + cmp %o2, 8 ! Insure we do not load beyond + bgt .Lunalign_adjust ! end of source buffer + andn %o1, 0x7, %o4 ! %o4 has long word aligned src address + add %o2, 64, %o2 ! adjust to leave loop + sub %o5, 64, %o5 ! early if necessary +.Lunalign_adjust: + alignaddr %o1, %g0, %g0 ! generate %gsr + add %o1, %o5, %o1 ! advance %o1 to after blocks + EX_LD_FP(LOAD(ldd, %o4, %f0), memcpy_retl_o2_plus_o5) +.Lunalign_loop: + EX_LD_FP(LOAD(ldd, %o4+8, %f2), memcpy_retl_o2_plus_o5) + faligndata %f0, %f2, %f16 + EX_LD_FP(LOAD(ldd, %o4+16, %f4), memcpy_retl_o2_plus_o5) + subcc %o5, BLOCK_SIZE, %o5 + EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5_plus_64) + faligndata %f2, %f4, %f18 + EX_LD_FP(LOAD(ldd, %o4+24, %f6), memcpy_retl_o2_plus_o5_plus_56) + EX_ST_FP(STORE(std, %f18, %o0+8), memcpy_retl_o2_plus_o5_plus_56) + faligndata %f4, %f6, %f20 + EX_LD_FP(LOAD(ldd, %o4+32, %f8), memcpy_retl_o2_plus_o5_plus_48) + EX_ST_FP(STORE(std, %f20, %o0+16), memcpy_retl_o2_plus_o5_plus_48) + faligndata %f6, %f8, %f22 + EX_LD_FP(LOAD(ldd, %o4+40, %f10), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f22, %o0+24), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f8, %f10, %f24 + EX_LD_FP(LOAD(ldd, %o4+48, %f12), memcpy_retl_o2_plus_o5_plus_32) + EX_ST_FP(STORE(std, %f24, %o0+32), memcpy_retl_o2_plus_o5_plus_32) + faligndata %f10, %f12, %f26 + EX_LD_FP(LOAD(ldd, %o4+56, %f14), memcpy_retl_o2_plus_o5_plus_24) + add %o4, BLOCK_SIZE, %o4 + EX_ST_FP(STORE(std, %f26, %o0+40), memcpy_retl_o2_plus_o5_plus_24) + faligndata %f12, %f14, %f28 + EX_LD_FP(LOAD(ldd, %o4, %f0), memcpy_retl_o2_plus_o5_plus_16) + EX_ST_FP(STORE(std, %f28, %o0+48), memcpy_retl_o2_plus_o5_plus_16) + faligndata %f14, %f0, %f30 + EX_ST_FP(STORE(std, %f30, %o0+56), memcpy_retl_o2_plus_o5_plus_8) + add %o0, BLOCK_SIZE, %o0 + bgu,pt %xcc, .Lunalign_loop + prefetch [%o4 + (5 * BLOCK_SIZE)], 20 + ba .Lunalign_done + nop + +.Lunalign_large: + andcc %o0, 0x3f, %o3 ! is dst 64-byte block aligned? + bz %xcc, .Lunalignsrc + sub %o3, 64, %o3 ! %o3 will be multiple of 8 + neg %o3 ! bytes until dest is 64 byte aligned + sub %o2, %o3, %o2 ! update cnt with bytes to be moved + ! Move bytes according to source alignment + andcc %o1, 0x1, %o5 + bnz %xcc, .Lunalignbyte ! check for byte alignment + nop + andcc %o1, 2, %o5 ! check for half word alignment + bnz %xcc, .Lunalignhalf + nop + ! Src is word aligned +.Lunalignword: + EX_LD_FP(LOAD(ld, %o1, %o4), memcpy_retl_o2_plus_o3) ! load 4 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + EX_ST_FP(STORE(stw, %o4, %o0), memcpy_retl_o2_plus_o3) ! and store 4 + subcc %o3, 8, %o3 ! decrease count by 8 + EX_LD_FP(LOAD(ld, %o1-4, %o4), memcpy_retl_o2_plus_o3_plus_4)! load 4 + add %o0, 8, %o0 ! increase dst ptr by 8 + bnz %xcc, .Lunalignword + EX_ST_FP(STORE(stw, %o4, %o0-4), memcpy_retl_o2_plus_o3_plus_4) + ba .Lunalignsrc + nop + + ! Src is half-word aligned +.Lunalignhalf: + EX_LD_FP(LOAD(lduh, %o1, %o4), memcpy_retl_o2_plus_o3) ! load 2 bytes + sllx %o4, 32, %o5 ! shift left + EX_LD_FP(LOAD(lduw, %o1+2, %o4), memcpy_retl_o2_plus_o3) + or %o4, %o5, %o5 + sllx %o5, 16, %o5 + EX_LD_FP(LOAD(lduh, %o1+6, %o4), memcpy_retl_o2_plus_o3) + or %o4, %o5, %o5 + EX_ST_FP(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_o3) + add %o1, 8, %o1 + subcc %o3, 8, %o3 + bnz %xcc, .Lunalignhalf + add %o0, 8, %o0 + ba .Lunalignsrc + nop + + ! Src is Byte aligned +.Lunalignbyte: + sub %o0, %o1, %o0 ! share pointer advance +.Lunalignbyte_loop: + EX_LD_FP(LOAD(ldub, %o1, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 56, %o5 + EX_LD_FP(LOAD(lduh, %o1+1, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 40, %o4 + or %o4, %o5, %o5 + EX_LD_FP(LOAD(lduh, %o1+3, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 24, %o4 + or %o4, %o5, %o5 + EX_LD_FP(LOAD(lduh, %o1+5, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 8, %o4 + or %o4, %o5, %o5 + EX_LD_FP(LOAD(ldub, %o1+7, %o4), memcpy_retl_o2_plus_o3) + or %o4, %o5, %o5 + add %o0, %o1, %o0 + EX_ST_FP(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_o3) + sub %o0, %o1, %o0 + subcc %o3, 8, %o3 + bnz %xcc, .Lunalignbyte_loop + add %o1, 8, %o1 + add %o0,%o1, %o0 ! restore pointer + + ! Destination is now block (64 byte aligned) +.Lunalignsrc: + andn %o2, 0x3f, %o5 ! %o5 is multiple of block size + and %o2, 0x3f, %o2 ! residue bytes in %o2 + add %o2, 64, %o2 ! Insure we do not load beyond + sub %o5, 64, %o5 ! end of source buffer + + andn %o1, 0x7, %o4 ! %o4 has long word aligned src address + alignaddr %o1, %g0, %g0 ! generate %gsr + add %o1, %o5, %o1 ! advance %o1 to after blocks + + EX_LD_FP(LOAD(ldd, %o4, %f14), memcpy_retl_o2_plus_o5) + add %o4, 8, %o4 +.Lunalign_sloop: + EX_LD_FP(LOAD(ldd, %o4, %f16), memcpy_retl_o2_plus_o5) + faligndata %f14, %f16, %f0 + EX_LD_FP(LOAD(ldd, %o4+8, %f18), memcpy_retl_o2_plus_o5) + faligndata %f16, %f18, %f2 + EX_LD_FP(LOAD(ldd, %o4+16, %f20), memcpy_retl_o2_plus_o5) + faligndata %f18, %f20, %f4 + EX_ST_FP(STORE(std, %f0, %o0), memcpy_retl_o2_plus_o5) + subcc %o5, 64, %o5 + EX_LD_FP(LOAD(ldd, %o4+24, %f22), memcpy_retl_o2_plus_o5_plus_56) + faligndata %f20, %f22, %f6 + EX_ST_FP(STORE(std, %f2, %o0+8), memcpy_retl_o2_plus_o5_plus_56) + EX_LD_FP(LOAD(ldd, %o4+32, %f24), memcpy_retl_o2_plus_o5_plus_48) + faligndata %f22, %f24, %f8 + EX_ST_FP(STORE(std, %f4, %o0+16), memcpy_retl_o2_plus_o5_plus_48) + EX_LD_FP(LOAD(ldd, %o4+40, %f26), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f24, %f26, %f10 + EX_ST_FP(STORE(std, %f6, %o0+24), memcpy_retl_o2_plus_o5_plus_40) + EX_LD_FP(LOAD(ldd, %o4+48, %f28), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f26, %f28, %f12 + EX_ST_FP(STORE(std, %f8, %o0+32), memcpy_retl_o2_plus_o5_plus_40) + add %o4, 64, %o4 + EX_LD_FP(LOAD(ldd, %o4-8, %f30), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f28, %f30, %f14 + EX_ST_FP(STORE(std, %f10, %o0+40), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f12, %o0+48), memcpy_retl_o2_plus_o5_plus_40) + add %o0, 64, %o0 + EX_ST_FP(STORE(std, %f14, %o0-8), memcpy_retl_o2_plus_o5_plus_40) + fsrc2 %f30, %f14 + bgu,pt %xcc, .Lunalign_sloop + prefetch [%o4 + (8 * BLOCK_SIZE)], 20 + +.Lunalign_done: + ! Handle trailing bytes, 64 to 127 + ! Dest long word aligned, Src not long word aligned + cmp %o2, 15 + bleu %xcc, .Lunalign_short + + andn %o2, 0x7, %o5 ! %o5 is multiple of 8 + and %o2, 0x7, %o2 ! residue bytes in %o2 + add %o2, 8, %o2 + sub %o5, 8, %o5 ! insure we do not load past end of src + andn %o1, 0x7, %o4 ! %o4 has long word aligned src address + add %o1, %o5, %o1 ! advance %o1 to after multiple of 8 + EX_LD_FP(LOAD(ldd, %o4, %f0), memcpy_retl_o2_plus_o5)! fetch partialword +.Lunalign_by8: + EX_LD_FP(LOAD(ldd, %o4+8, %f2), memcpy_retl_o2_plus_o5) + add %o4, 8, %o4 + faligndata %f0, %f2, %f16 + subcc %o5, 8, %o5 + EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5) + fsrc2 %f2, %f0 + bgu,pt %xcc, .Lunalign_by8 + add %o0, 8, %o0 + +.Lunalign_short: +#ifdef NON_USER_COPY + VISExitHalfFast +#else + VISExitHalf +#endif + ba .Lsmallrest + nop + +/* + * This is a special case of nested memcpy. This can happen when kernel + * calls unaligned memcpy back to back without saving FP registers. We need + * traps(context switch) to save/restore FP registers. If the kernel calls + * memcpy without this trap sequence we will hit FP corruption. Let's use + * the normal integer load/store method in this case. + */ + +#ifdef NON_USER_COPY +.Lmedium_vis_entry_fail_cp: + or %o0, %o1, %g2 +#endif +.Lmedium_cp: + LOAD(prefetch, %o1 + 0x40, #n_reads_strong) + andcc %g2, 0x7, %g0 + bne,pn %xcc, .Lmedium_unaligned_cp + nop + +.Lmedium_noprefetch_cp: + andncc %o2, 0x20 - 1, %o5 + be,pn %xcc, 2f + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x00, %o3), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x08, %g2), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x10, %g7), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x18, %o4), memcpy_retl_o2_plus_o5) + add %o1, 0x20, %o1 + subcc %o5, 0x20, %o5 + EX_ST(STORE(stx, %o3, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) + EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %g7, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) + bne,pt %xcc, 1b + add %o0, 0x20, %o0 +2: andcc %o2, 0x18, %o5 + be,pt %xcc, 3f + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x00, %o3), memcpy_retl_o2_plus_o5) + add %o1, 0x08, %o1 + add %o0, 0x08, %o0 + subcc %o5, 0x08, %o5 + bne,pt %xcc, 1b + EX_ST(STORE(stx, %o3, %o0 - 0x08), memcpy_retl_o2_plus_o5_plus_8) +3: brz,pt %o2, .Lexit_cp + cmp %o2, 0x04 + bl,pn %xcc, .Ltiny_cp + nop + EX_LD(LOAD(lduw, %o1 + 0x00, %o3), memcpy_retl_o2) + add %o1, 0x04, %o1 + add %o0, 0x04, %o0 + subcc %o2, 0x04, %o2 + bne,pn %xcc, .Ltiny_cp + EX_ST(STORE(stw, %o3, %o0 - 0x04), memcpy_retl_o2_plus_4) + ba,a,pt %xcc, .Lexit_cp + +.Lmedium_unaligned_cp: + /* First get dest 8 byte aligned. */ + sub %g0, %o0, %o3 + and %o3, 0x7, %o3 + brz,pt %o3, 2f + sub %o2, %o3, %o2 + +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) + add %o1, 1, %o1 + subcc %o3, 1, %o3 + add %o0, 1, %o0 + bne,pt %xcc, 1b + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) +2: + and %o1, 0x7, %o3 + brz,pn %o3, .Lmedium_noprefetch_cp + sll %o3, 3, %o3 + mov 64, %g2 + sub %g2, %o3, %g2 + andn %o1, 0x7, %o1 + EX_LD(LOAD(ldx, %o1 + 0x00, %o4), memcpy_retl_o2) + sllx %o4, %o3, %o4 + andn %o2, 0x08 - 1, %o5 + sub %o2, %o5, %o2 + +1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), memcpy_retl_o2_plus_o5) + add %o1, 0x08, %o1 + subcc %o5, 0x08, %o5 + srlx %g3, %g2, %g7 + or %g7, %o4, %g7 + EX_ST(STORE(stx, %g7, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_8) + add %o0, 0x08, %o0 + bne,pt %xcc, 1b + sllx %g3, %o3, %o4 + srl %o3, 3, %o3 + add %o1, %o3, %o1 + brz,pn %o2, .Lexit_cp + nop + ba,pt %xcc, .Lsmall_unaligned_cp + +.Ltiny_cp: + EX_LD(LOAD(ldub, %o1 + 0x00, %o3), memcpy_retl_o2) + subcc %o2, 1, %o2 + be,pn %xcc, .Lexit_cp + EX_ST(STORE(stb, %o3, %o0 + 0x00), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x01, %o3), memcpy_retl_o2) + subcc %o2, 1, %o2 + be,pn %xcc, .Lexit_cp + EX_ST(STORE(stb, %o3, %o0 + 0x01), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x02, %o3), memcpy_retl_o2) + ba,pt %xcc, .Lexit_cp + EX_ST(STORE(stb, %o3, %o0 + 0x02), memcpy_retl_o2) + +.Lsmall_cp: + andcc %g2, 0x3, %g0 + bne,pn %xcc, .Lsmall_unaligned_cp + andn %o2, 0x4 - 1, %o5 + sub %o2, %o5, %o2 +1: + EX_LD(LOAD(lduw, %o1 + 0x00, %o3), memcpy_retl_o2_plus_o5) + add %o1, 0x04, %o1 + subcc %o5, 0x04, %o5 + add %o0, 0x04, %o0 + bne,pt %xcc, 1b + EX_ST(STORE(stw, %o3, %o0 - 0x04), memcpy_retl_o2_plus_o5_plus_4) + brz,pt %o2, .Lexit_cp + nop + ba,a,pt %xcc, .Ltiny_cp + +.Lsmall_unaligned_cp: +1: EX_LD(LOAD(ldub, %o1 + 0x00, %o3), memcpy_retl_o2) + add %o1, 1, %o1 + add %o0, 1, %o0 + subcc %o2, 1, %o2 + bne,pt %xcc, 1b + EX_ST(STORE(stb, %o3, %o0 - 0x01), memcpy_retl_o2_plus_1) + ba,a,pt %xcc, .Lexit_cp + +.Lsmallrest: + tst %o2 + bz,pt %xcc, .Lsmallx + cmp %o2, 4 + blt,pn %xcc, .Lsmallleft3 + nop + sub %o2, 3, %o2 +.Lsmallnotalign4: + EX_LD(LOAD(ldub, %o1, %o3), memcpy_retl_o2_plus_3)! read byte + subcc %o2, 4, %o2 ! reduce count by 4 + EX_ST(STORE(stb, %o3, %o0), memcpy_retl_o2_plus_7)! write byte & repeat + EX_LD(LOAD(ldub, %o1+1, %o3), memcpy_retl_o2_plus_6)! for total of 4 + add %o1, 4, %o1 ! advance SRC by 4 + EX_ST(STORE(stb, %o3, %o0+1), memcpy_retl_o2_plus_6) + EX_LD(LOAD(ldub, %o1-2, %o3), memcpy_retl_o2_plus_5) + add %o0, 4, %o0 ! advance DST by 4 + EX_ST(STORE(stb, %o3, %o0-2), memcpy_retl_o2_plus_5) + EX_LD(LOAD(ldub, %o1-1, %o3), memcpy_retl_o2_plus_4) + bgu,pt %xcc, .Lsmallnotalign4 ! loop til 3 or fewer bytes remain + EX_ST(STORE(stb, %o3, %o0-1), memcpy_retl_o2_plus_4) + addcc %o2, 3, %o2 ! restore count + bz,pt %xcc, .Lsmallx +.Lsmallleft3: ! 1, 2, or 3 bytes remain + subcc %o2, 1, %o2 + EX_LD(LOAD(ldub, %o1, %o3), memcpy_retl_o2_plus_1) ! load one byte + bz,pt %xcc, .Lsmallx + EX_ST(STORE(stb, %o3, %o0), memcpy_retl_o2_plus_1) ! store one byte + EX_LD(LOAD(ldub, %o1+1, %o3), memcpy_retl_o2) ! load second byte + subcc %o2, 1, %o2 + bz,pt %xcc, .Lsmallx + EX_ST(STORE(stb, %o3, %o0+1), memcpy_retl_o2_plus_1)! store second byte + EX_LD(LOAD(ldub, %o1+2, %o3), memcpy_retl_o2) ! load third byte + EX_ST(STORE(stb, %o3, %o0+2), memcpy_retl_o2) ! store third byte +.Lsmallx: + retl + mov EX_RETVAL(%g1), %o0 +.Lsmallfin: + tst %o2 + bnz,pn %xcc, .Lsmallleft3 + nop + retl + mov EX_RETVAL(%g1), %o0 ! restore %o0 +.Lexit_cp: + retl + mov EX_RETVAL(%g1), %o0 + .size FUNC_NAME, .-FUNC_NAME diff --git a/arch/sparc/lib/M7memset.S b/arch/sparc/lib/M7memset.S new file mode 100644 index 0000000000000000000000000000000000000000..62ea91b3a6b8360070b27b2f33e19d6f102048d8 --- /dev/null +++ b/arch/sparc/lib/M7memset.S @@ -0,0 +1,352 @@ +/* + * M7memset.S: SPARC M7 optimized memset. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + +/* + * M7memset.S: M7 optimized memset. + * + * char *memset(sp, c, n) + * + * Set an array of n chars starting at sp to the character c. + * Return sp. + * + * Fast assembler language version of the following C-program for memset + * which represents the `standard' for the C-library. + * + * void * + * memset(void *sp1, int c, size_t n) + * { + * if (n != 0) { + * char *sp = sp1; + * do { + * *sp++ = (char)c; + * } while (--n != 0); + * } + * return (sp1); + * } + * + * The algorithm is as follows : + * + * For small 6 or fewer bytes stores, bytes will be stored. + * + * For less than 32 bytes stores, align the address on 4 byte boundary. + * Then store as many 4-byte chunks, followed by trailing bytes. + * + * For sizes greater than 32 bytes, align the address on 8 byte boundary. + * if (count >= 64) { + * store 8-bytes chunks to align the address on 64 byte boundary + * if (value to be set is zero && count >= MIN_ZERO) { + * Using BIS stores, set the first long word of each + * 64-byte cache line to zero which will also clear the + * other seven long words of the cache line. + * } + * else if (count >= MIN_LOOP) { + * Using BIS stores, set the first long word of each of + * ST_CHUNK cache lines (64 bytes each) before the main + * loop is entered. + * In the main loop, continue pre-setting the first long + * word of each cache line ST_CHUNK lines in advance while + * setting the other seven long words (56 bytes) of each + * cache line until fewer than ST_CHUNK*64 bytes remain. + * Then set the remaining seven long words of each cache + * line that has already had its first long word set. + * } + * store remaining data in 64-byte chunks until less than + * 64 bytes remain. + * } + * Store as many 8-byte chunks, followed by trailing bytes. + * + * BIS = Block Init Store + * Doing the advance store of the first element of the cache line + * initiates the displacement of a cache line while only using a single + * instruction in the pipeline. That avoids various pipeline delays, + * such as filling the miss buffer. The performance effect is + * similar to prefetching for normal stores. + * The special case for zero fills runs faster and uses fewer instruction + * cycles than the normal memset loop. + * + * We only use BIS for memset of greater than MIN_LOOP bytes because a sequence + * BIS stores must be followed by a membar #StoreStore. The benefit of + * the BIS store must be balanced against the cost of the membar operation. + */ + +/* + * ASI_STBI_P marks the cache line as "least recently used" + * which means if many threads are active, it has a high chance + * of being pushed out of the cache between the first initializing + * store and the final stores. + * Thus, we use ASI_STBIMRU_P which marks the cache line as + * "most recently used" for all but the last store to the cache line. + */ + +#include +#include + +#define ASI_STBI_P ASI_BLK_INIT_QUAD_LDD_P +#define ASI_STBIMRU_P ASI_ST_BLKINIT_MRU_P + + +#define ST_CHUNK 24 /* multiple of 4 due to loop unrolling */ +#define MIN_LOOP 16320 +#define MIN_ZERO 512 + + .section ".text" + .align 32 + +/* + * Define clear_page(dest) as memset(dest, 0, PAGE_SIZE) + * (can create a more optimized version later.) + */ + .globl M7clear_page + .globl M7clear_user_page +M7clear_page: /* clear_page(dest) */ +M7clear_user_page: + set PAGE_SIZE, %o1 + /* fall through into bzero code */ + + .size M7clear_page,.-M7clear_page + .size M7clear_user_page,.-M7clear_user_page + +/* + * Define bzero(dest, n) as memset(dest, 0, n) + * (can create a more optimized version later.) + */ + .globl M7bzero +M7bzero: /* bzero(dest, size) */ + mov %o1, %o2 + mov 0, %o1 + /* fall through into memset code */ + + .size M7bzero,.-M7bzero + + .global M7memset + .type M7memset, #function + .register %g3, #scratch +M7memset: + mov %o0, %o5 ! copy sp1 before using it + cmp %o2, 7 ! if small counts, just write bytes + bleu,pn %xcc, .wrchar + and %o1, 0xff, %o1 ! o1 is (char)c + + sll %o1, 8, %o3 + or %o1, %o3, %o1 ! now o1 has 2 bytes of c + sll %o1, 16, %o3 + cmp %o2, 32 + blu,pn %xcc, .wdalign + or %o1, %o3, %o1 ! now o1 has 4 bytes of c + + sllx %o1, 32, %o3 + or %o1, %o3, %o1 ! now o1 has 8 bytes of c + +.dbalign: + andcc %o5, 7, %o3 ! is sp1 aligned on a 8 byte bound? + bz,pt %xcc, .blkalign ! already long word aligned + sub %o3, 8, %o3 ! -(bytes till long word aligned) + + add %o2, %o3, %o2 ! update o2 with new count + ! Set -(%o3) bytes till sp1 long word aligned +1: stb %o1, [%o5] ! there is at least 1 byte to set + inccc %o3 ! byte clearing loop + bl,pt %xcc, 1b + inc %o5 + + ! Now sp1 is long word aligned (sp1 is found in %o5) +.blkalign: + cmp %o2, 64 ! check if there are 64 bytes to set + blu,pn %xcc, .wrshort + mov %o2, %o3 + + andcc %o5, 63, %o3 ! is sp1 block aligned? + bz,pt %xcc, .blkwr ! now block aligned + sub %o3, 64, %o3 ! o3 is -(bytes till block aligned) + add %o2, %o3, %o2 ! o2 is the remainder + + ! Store -(%o3) bytes till dst is block (64 byte) aligned. + ! Use long word stores. + ! Recall that dst is already long word aligned +1: + addcc %o3, 8, %o3 + stx %o1, [%o5] + bl,pt %xcc, 1b + add %o5, 8, %o5 + + ! Now sp1 is block aligned +.blkwr: + andn %o2, 63, %o4 ! calculate size of blocks in bytes + brz,pn %o1, .wrzero ! special case if c == 0 + and %o2, 63, %o3 ! %o3 = bytes left after blk stores. + + set MIN_LOOP, %g1 + cmp %o4, %g1 ! check there are enough bytes to set + blu,pn %xcc, .short_set ! to justify cost of membar + ! must be > pre-cleared lines + nop + + ! initial cache-clearing stores + ! get store pipeline moving + rd %asi, %g3 ! save %asi to be restored later + wr %g0, ASI_STBIMRU_P, %asi + + ! Primary memset loop for large memsets +.wr_loop: + sub %o5, 8, %o5 ! adjust %o5 for ASI store alignment + mov ST_CHUNK, %g1 +.wr_loop_start: + stxa %o1, [%o5+8]%asi + subcc %g1, 4, %g1 + stxa %o1, [%o5+8+64]%asi + add %o5, 256, %o5 + stxa %o1, [%o5+8-128]%asi + bgu %xcc, .wr_loop_start + stxa %o1, [%o5+8-64]%asi + + sub %o5, ST_CHUNK*64, %o5 ! reset %o5 + mov ST_CHUNK, %g1 + +.wr_loop_rest: + stxa %o1, [%o5+8+8]%asi + sub %o4, 64, %o4 + stxa %o1, [%o5+16+8]%asi + subcc %g1, 1, %g1 + stxa %o1, [%o5+24+8]%asi + stxa %o1, [%o5+32+8]%asi + stxa %o1, [%o5+40+8]%asi + add %o5, 64, %o5 + stxa %o1, [%o5-8]%asi + bgu %xcc, .wr_loop_rest + stxa %o1, [%o5]ASI_STBI_P + + ! If more than ST_CHUNK*64 bytes remain to set, continue + ! setting the first long word of each cache line in advance + ! to keep the store pipeline moving. + + cmp %o4, ST_CHUNK*64 + bge,pt %xcc, .wr_loop_start + mov ST_CHUNK, %g1 + + brz,a,pn %o4, .asi_done + add %o5, 8, %o5 ! restore %o5 offset + +.wr_loop_small: + stxa %o1, [%o5+8]%asi + stxa %o1, [%o5+8+8]%asi + stxa %o1, [%o5+16+8]%asi + stxa %o1, [%o5+24+8]%asi + stxa %o1, [%o5+32+8]%asi + subcc %o4, 64, %o4 + stxa %o1, [%o5+40+8]%asi + add %o5, 64, %o5 + stxa %o1, [%o5-8]%asi + bgu,pt %xcc, .wr_loop_small + stxa %o1, [%o5]ASI_STBI_P + + ba .asi_done + add %o5, 8, %o5 ! restore %o5 offset + + ! Special case loop for zero fill memsets + ! For each 64 byte cache line, single STBI to first element + ! clears line +.wrzero: + cmp %o4, MIN_ZERO ! check if enough bytes to set + ! to pay %asi + membar cost + blu %xcc, .short_set + nop + sub %o4, 256, %o4 + +.wrzero_loop: + mov 64, %g3 + stxa %o1, [%o5]ASI_STBI_P + subcc %o4, 256, %o4 + stxa %o1, [%o5+%g3]ASI_STBI_P + add %o5, 256, %o5 + sub %g3, 192, %g3 + stxa %o1, [%o5+%g3]ASI_STBI_P + add %g3, 64, %g3 + bge,pt %xcc, .wrzero_loop + stxa %o1, [%o5+%g3]ASI_STBI_P + add %o4, 256, %o4 + + brz,pn %o4, .bsi_done + nop + +.wrzero_small: + stxa %o1, [%o5]ASI_STBI_P + subcc %o4, 64, %o4 + bgu,pt %xcc, .wrzero_small + add %o5, 64, %o5 + ba,a .bsi_done + +.asi_done: + wr %g3, 0x0, %asi ! restored saved %asi +.bsi_done: + membar #StoreStore ! required by use of Block Store Init + +.short_set: + cmp %o4, 64 ! check if 64 bytes to set + blu %xcc, 5f + nop +4: ! set final blocks of 64 bytes + stx %o1, [%o5] + stx %o1, [%o5+8] + stx %o1, [%o5+16] + stx %o1, [%o5+24] + subcc %o4, 64, %o4 + stx %o1, [%o5+32] + stx %o1, [%o5+40] + add %o5, 64, %o5 + stx %o1, [%o5-16] + bgu,pt %xcc, 4b + stx %o1, [%o5-8] + +5: + ! Set the remaining long words +.wrshort: + subcc %o3, 8, %o3 ! Can we store any long words? + blu,pn %xcc, .wrchars + and %o2, 7, %o2 ! calc bytes left after long words +6: + subcc %o3, 8, %o3 + stx %o1, [%o5] ! store the long words + bgeu,pt %xcc, 6b + add %o5, 8, %o5 + +.wrchars: ! check for extra chars + brnz %o2, .wrfin + nop + retl + nop + +.wdalign: + andcc %o5, 3, %o3 ! is sp1 aligned on a word boundary + bz,pn %xcc, .wrword + andn %o2, 3, %o3 ! create word sized count in %o3 + + dec %o2 ! decrement count + stb %o1, [%o5] ! clear a byte + b .wdalign + inc %o5 ! next byte + +.wrword: + subcc %o3, 4, %o3 + st %o1, [%o5] ! 4-byte writing loop + bnz,pt %xcc, .wrword + add %o5, 4, %o5 + + and %o2, 3, %o2 ! leftover count, if any + +.wrchar: + ! Set the remaining bytes, if any + brz %o2, .exit + nop +.wrfin: + deccc %o2 + stb %o1, [%o5] + bgu,pt %xcc, .wrfin + inc %o5 +.exit: + retl ! %o0 was preserved + nop + + .size M7memset,.-M7memset diff --git a/arch/sparc/lib/M7patch.S b/arch/sparc/lib/M7patch.S new file mode 100644 index 0000000000000000000000000000000000000000..9000b7bc5f2bf863be4348dbe279e38d37a9fd52 --- /dev/null +++ b/arch/sparc/lib/M7patch.S @@ -0,0 +1,51 @@ +/* + * M7patch.S: Patch generic routines with M7 variant. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + +#include + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + +ENTRY(m7_patch_copyops) + NG_DO_PATCH(memcpy, M7memcpy) + NG_DO_PATCH(raw_copy_from_user, M7copy_from_user) + NG_DO_PATCH(raw_copy_to_user, M7copy_to_user) + retl + nop +ENDPROC(m7_patch_copyops) + +ENTRY(m7_patch_bzero) + NG_DO_PATCH(memset, M7memset) + NG_DO_PATCH(__bzero, M7bzero) + NG_DO_PATCH(__clear_user, NGclear_user) + NG_DO_PATCH(tsb_init, NGtsb_init) + retl + nop +ENDPROC(m7_patch_bzero) + +ENTRY(m7_patch_pageops) + NG_DO_PATCH(copy_user_page, NG4copy_user_page) + NG_DO_PATCH(_clear_page, M7clear_page) + NG_DO_PATCH(clear_user_page, M7clear_user_page) + retl + nop +ENDPROC(m7_patch_pageops) diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 07c03e72d81248cebe9c3d48bbc93e1e2de455b7..a1a2d39ec96e714d69420bf1d7a35192e95c35d4 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -36,6 +36,11 @@ lib-$(CONFIG_SPARC64) += NG2patch.o lib-$(CONFIG_SPARC64) += NG4memcpy.o NG4copy_from_user.o NG4copy_to_user.o lib-$(CONFIG_SPARC64) += NG4patch.o NG4copy_page.o NG4clear_page.o NG4memset.o +lib-$(CONFIG_SPARC64) += Memcpy_utils.o + +lib-$(CONFIG_SPARC64) += M7memcpy.o M7copy_from_user.o M7copy_to_user.o +lib-$(CONFIG_SPARC64) += M7patch.o M7memset.o + lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o diff --git a/arch/sparc/lib/Memcpy_utils.S b/arch/sparc/lib/Memcpy_utils.S new file mode 100644 index 0000000000000000000000000000000000000000..64fbac28b3db18864b0d067acaee0d7898feec7a --- /dev/null +++ b/arch/sparc/lib/Memcpy_utils.S @@ -0,0 +1,345 @@ +#ifndef __ASM_MEMCPY_UTILS +#define __ASM_MEMCPY_UTILS + +#include +#include +#include + +ENTRY(__restore_asi_fp) + VISExitHalf + retl + wr %g0, ASI_AIUS, %asi +ENDPROC(__restore_asi_fp) + +ENTRY(__restore_asi) + retl + wr %g0, ASI_AIUS, %asi +ENDPROC(__restore_asi) + +ENTRY(memcpy_retl_o2) + ba,pt %xcc, __restore_asi + mov %o2, %o0 +ENDPROC(memcpy_retl_o2) +ENTRY(memcpy_retl_o2_plus_1) + ba,pt %xcc, __restore_asi + add %o2, 1, %o0 +ENDPROC(memcpy_retl_o2_plus_1) +ENTRY(memcpy_retl_o2_plus_3) + ba,pt %xcc, __restore_asi + add %o2, 3, %o0 +ENDPROC(memcpy_retl_o2_plus_3) +ENTRY(memcpy_retl_o2_plus_4) + ba,pt %xcc, __restore_asi + add %o2, 4, %o0 +ENDPROC(memcpy_retl_o2_plus_4) +ENTRY(memcpy_retl_o2_plus_5) + ba,pt %xcc, __restore_asi + add %o2, 5, %o0 +ENDPROC(memcpy_retl_o2_plus_5) +ENTRY(memcpy_retl_o2_plus_6) + ba,pt %xcc, __restore_asi + add %o2, 6, %o0 +ENDPROC(memcpy_retl_o2_plus_6) +ENTRY(memcpy_retl_o2_plus_7) + ba,pt %xcc, __restore_asi + add %o2, 7, %o0 +ENDPROC(memcpy_retl_o2_plus_7) +ENTRY(memcpy_retl_o2_plus_8) + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_8) +ENTRY(memcpy_retl_o2_plus_15) + ba,pt %xcc, __restore_asi + add %o2, 15, %o0 +ENDPROC(memcpy_retl_o2_plus_15) +ENTRY(memcpy_retl_o2_plus_15_8) + add %o2, 15, %o2 + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_15_8) +ENTRY(memcpy_retl_o2_plus_16) + ba,pt %xcc, __restore_asi + add %o2, 16, %o0 +ENDPROC(memcpy_retl_o2_plus_16) +ENTRY(memcpy_retl_o2_plus_24) + ba,pt %xcc, __restore_asi + add %o2, 24, %o0 +ENDPROC(memcpy_retl_o2_plus_24) +ENTRY(memcpy_retl_o2_plus_31) + ba,pt %xcc, __restore_asi + add %o2, 31, %o0 +ENDPROC(memcpy_retl_o2_plus_31) +ENTRY(memcpy_retl_o2_plus_32) + ba,pt %xcc, __restore_asi + add %o2, 32, %o0 +ENDPROC(memcpy_retl_o2_plus_32) +ENTRY(memcpy_retl_o2_plus_31_32) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 32, %o0 +ENDPROC(memcpy_retl_o2_plus_31_32) +ENTRY(memcpy_retl_o2_plus_31_24) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 24, %o0 +ENDPROC(memcpy_retl_o2_plus_31_24) +ENTRY(memcpy_retl_o2_plus_31_16) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 16, %o0 +ENDPROC(memcpy_retl_o2_plus_31_16) +ENTRY(memcpy_retl_o2_plus_31_8) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_31_8) +ENTRY(memcpy_retl_o2_plus_63) + ba,pt %xcc, __restore_asi + add %o2, 63, %o0 +ENDPROC(memcpy_retl_o2_plus_63) +ENTRY(memcpy_retl_o2_plus_63_64) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 64, %o0 +ENDPROC(memcpy_retl_o2_plus_63_64) +ENTRY(memcpy_retl_o2_plus_63_56) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 56, %o0 +ENDPROC(memcpy_retl_o2_plus_63_56) +ENTRY(memcpy_retl_o2_plus_63_48) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 48, %o0 +ENDPROC(memcpy_retl_o2_plus_63_48) +ENTRY(memcpy_retl_o2_plus_63_40) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 40, %o0 +ENDPROC(memcpy_retl_o2_plus_63_40) +ENTRY(memcpy_retl_o2_plus_63_32) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 32, %o0 +ENDPROC(memcpy_retl_o2_plus_63_32) +ENTRY(memcpy_retl_o2_plus_63_24) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 24, %o0 +ENDPROC(memcpy_retl_o2_plus_63_24) +ENTRY(memcpy_retl_o2_plus_63_16) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 16, %o0 +ENDPROC(memcpy_retl_o2_plus_63_16) +ENTRY(memcpy_retl_o2_plus_63_8) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_63_8) +ENTRY(memcpy_retl_o2_plus_o5) + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5) +ENTRY(memcpy_retl_o2_plus_o5_plus_1) + add %o5, 1, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_1) +ENTRY(memcpy_retl_o2_plus_o5_plus_4) + add %o5, 4, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_4) +ENTRY(memcpy_retl_o2_plus_o5_plus_8) + add %o5, 8, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_8) +ENTRY(memcpy_retl_o2_plus_o5_plus_16) + add %o5, 16, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_16) +ENTRY(memcpy_retl_o2_plus_o5_plus_24) + add %o5, 24, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_24) +ENTRY(memcpy_retl_o2_plus_o5_plus_32) + add %o5, 32, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_32) +ENTRY(memcpy_retl_o2_plus_o5_64) + add %o5, 32, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_64) +ENTRY(memcpy_retl_o2_plus_g1) + ba,pt %xcc, __restore_asi + add %o2, %g1, %o0 +ENDPROC(memcpy_retl_o2_plus_g1) +ENTRY(memcpy_retl_o2_plus_g1_plus_1) + add %g1, 1, %g1 + ba,pt %xcc, __restore_asi + add %o2, %g1, %o0 +ENDPROC(memcpy_retl_o2_plus_g1_plus_1) +ENTRY(memcpy_retl_o2_plus_g1_plus_8) + add %g1, 8, %g1 + ba,pt %xcc, __restore_asi + add %o2, %g1, %o0 +ENDPROC(memcpy_retl_o2_plus_g1_plus_8) +ENTRY(memcpy_retl_o2_plus_o4) + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4) +ENTRY(memcpy_retl_o2_plus_o4_plus_8) + add %o4, 8, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_8) +ENTRY(memcpy_retl_o2_plus_o4_plus_16) + add %o4, 16, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_16) +ENTRY(memcpy_retl_o2_plus_o4_plus_24) + add %o4, 24, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_24) +ENTRY(memcpy_retl_o2_plus_o4_plus_32) + add %o4, 32, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_32) +ENTRY(memcpy_retl_o2_plus_o4_plus_40) + add %o4, 40, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_40) +ENTRY(memcpy_retl_o2_plus_o4_plus_48) + add %o4, 48, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_48) +ENTRY(memcpy_retl_o2_plus_o4_plus_56) + add %o4, 56, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_56) +ENTRY(memcpy_retl_o2_plus_o4_plus_64) + add %o4, 64, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_64) +ENTRY(memcpy_retl_o2_plus_o5_plus_64) + add %o5, 64, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_64) +ENTRY(memcpy_retl_o2_plus_o3_fp) + ba,pt %xcc, __restore_asi_fp + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_fp) +ENTRY(memcpy_retl_o2_plus_o3_plus_1_fp) + add %o3, 1, %o3 + ba,pt %xcc, __restore_asi_fp + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_plus_1_fp) +ENTRY(memcpy_retl_o2_plus_o3_plus_4_fp) + add %o3, 4, %o3 + ba,pt %xcc, __restore_asi_fp + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_plus_4_fp) +ENTRY(memcpy_retl_o2_plus_o4_fp) + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_8_fp) + add %o4, 8, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_8_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_16_fp) + add %o4, 16, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_16_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_24_fp) + add %o4, 24, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_24_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_32_fp) + add %o4, 32, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_32_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_40_fp) + add %o4, 40, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_40_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_48_fp) + add %o4, 48, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_48_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_56_fp) + add %o4, 56, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_56_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_64_fp) + add %o4, 64, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_64_fp) +ENTRY(memcpy_retl_o2_plus_o5_fp) + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_64_fp) + add %o5, 64, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_64_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_56_fp) + add %o5, 56, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_56_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_48_fp) + add %o5, 48, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_48_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_40_fp) + add %o5, 40, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_40_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_32_fp) + add %o5, 32, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_32_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_24_fp) + add %o5, 24, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_24_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_16_fp) + add %o5, 16, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_16_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_8_fp) + add %o5, 8, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_8_fp) + +#endif diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S index 78ea962edcbee4c974481520de516e751d78a61d..b5dacd1d207870655156857b5c9fa40de626a1e9 100644 --- a/arch/sparc/lib/NG4memcpy.S +++ b/arch/sparc/lib/NG4memcpy.S @@ -94,155 +94,6 @@ .text #ifndef EX_RETVAL #define EX_RETVAL(x) x -__restore_asi_fp: - VISExitHalf -__restore_asi: - retl - wr %g0, ASI_AIUS, %asi - -ENTRY(NG4_retl_o2) - ba,pt %xcc, __restore_asi - mov %o2, %o0 -ENDPROC(NG4_retl_o2) -ENTRY(NG4_retl_o2_plus_1) - ba,pt %xcc, __restore_asi - add %o2, 1, %o0 -ENDPROC(NG4_retl_o2_plus_1) -ENTRY(NG4_retl_o2_plus_4) - ba,pt %xcc, __restore_asi - add %o2, 4, %o0 -ENDPROC(NG4_retl_o2_plus_4) -ENTRY(NG4_retl_o2_plus_o5) - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5) -ENTRY(NG4_retl_o2_plus_o5_plus_4) - add %o5, 4, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_4) -ENTRY(NG4_retl_o2_plus_o5_plus_8) - add %o5, 8, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_8) -ENTRY(NG4_retl_o2_plus_o5_plus_16) - add %o5, 16, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_16) -ENTRY(NG4_retl_o2_plus_o5_plus_24) - add %o5, 24, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_24) -ENTRY(NG4_retl_o2_plus_o5_plus_32) - add %o5, 32, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_32) -ENTRY(NG4_retl_o2_plus_g1) - ba,pt %xcc, __restore_asi - add %o2, %g1, %o0 -ENDPROC(NG4_retl_o2_plus_g1) -ENTRY(NG4_retl_o2_plus_g1_plus_1) - add %g1, 1, %g1 - ba,pt %xcc, __restore_asi - add %o2, %g1, %o0 -ENDPROC(NG4_retl_o2_plus_g1_plus_1) -ENTRY(NG4_retl_o2_plus_g1_plus_8) - add %g1, 8, %g1 - ba,pt %xcc, __restore_asi - add %o2, %g1, %o0 -ENDPROC(NG4_retl_o2_plus_g1_plus_8) -ENTRY(NG4_retl_o2_plus_o4) - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4) -ENTRY(NG4_retl_o2_plus_o4_plus_8) - add %o4, 8, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_8) -ENTRY(NG4_retl_o2_plus_o4_plus_16) - add %o4, 16, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_16) -ENTRY(NG4_retl_o2_plus_o4_plus_24) - add %o4, 24, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_24) -ENTRY(NG4_retl_o2_plus_o4_plus_32) - add %o4, 32, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_32) -ENTRY(NG4_retl_o2_plus_o4_plus_40) - add %o4, 40, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_40) -ENTRY(NG4_retl_o2_plus_o4_plus_48) - add %o4, 48, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_48) -ENTRY(NG4_retl_o2_plus_o4_plus_56) - add %o4, 56, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_56) -ENTRY(NG4_retl_o2_plus_o4_plus_64) - add %o4, 64, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_64) -ENTRY(NG4_retl_o2_plus_o4_fp) - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_8_fp) - add %o4, 8, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_8_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_16_fp) - add %o4, 16, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_16_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_24_fp) - add %o4, 24, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_24_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_32_fp) - add %o4, 32, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_32_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_40_fp) - add %o4, 40, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_40_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_48_fp) - add %o4, 48, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_48_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_56_fp) - add %o4, 56, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_56_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_64_fp) - add %o4, 64, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_64_fp) #endif .align 64 @@ -275,12 +126,12 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ sub %o2, %g1, %o2 -1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) add %o1, 1, %o1 subcc %g1, 1, %g1 add %o0, 1, %o0 bne,pt %icc, 1b - EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1) + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) 51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong) LOAD(prefetch, %o1 + 0x080, #n_reads_strong) @@ -305,43 +156,43 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ brz,pt %g1, .Llarge_aligned sub %o2, %g1, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) add %o1, 8, %o1 subcc %g1, 8, %g1 add %o0, 8, %o0 bne,pt %icc, 1b - EX_ST(STORE(stx, %g2, %o0 - 0x08), NG4_retl_o2_plus_g1_plus_8) + EX_ST(STORE(stx, %g2, %o0 - 0x08), memcpy_retl_o2_plus_g1_plus_8) .Llarge_aligned: /* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */ andn %o2, 0x3f, %o4 sub %o2, %o4, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o4) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o4) add %o1, 0x40, %o1 - EX_LD(LOAD(ldx, %o1 - 0x38, %g2), NG4_retl_o2_plus_o4) + EX_LD(LOAD(ldx, %o1 - 0x38, %g2), memcpy_retl_o2_plus_o4) subcc %o4, 0x40, %o4 - EX_LD(LOAD(ldx, %o1 - 0x30, %g3), NG4_retl_o2_plus_o4_plus_64) - EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_64) - EX_LD(LOAD(ldx, %o1 - 0x20, %o5), NG4_retl_o2_plus_o4_plus_64) - EX_ST(STORE_INIT(%g1, %o0), NG4_retl_o2_plus_o4_plus_64) + EX_LD(LOAD(ldx, %o1 - 0x30, %g3), memcpy_retl_o2_plus_o4_plus_64) + EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), memcpy_retl_o2_plus_o4_plus_64) + EX_LD(LOAD(ldx, %o1 - 0x20, %o5), memcpy_retl_o2_plus_o4_plus_64) + EX_ST(STORE_INIT(%g1, %o0), memcpy_retl_o2_plus_o4_plus_64) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_56) + EX_ST(STORE_INIT(%g2, %o0), memcpy_retl_o2_plus_o4_plus_56) add %o0, 0x08, %o0 - EX_LD(LOAD(ldx, %o1 - 0x18, %g2), NG4_retl_o2_plus_o4_plus_48) - EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_48) + EX_LD(LOAD(ldx, %o1 - 0x18, %g2), memcpy_retl_o2_plus_o4_plus_48) + EX_ST(STORE_INIT(%g3, %o0), memcpy_retl_o2_plus_o4_plus_48) add %o0, 0x08, %o0 - EX_LD(LOAD(ldx, %o1 - 0x10, %g3), NG4_retl_o2_plus_o4_plus_40) - EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_40) + EX_LD(LOAD(ldx, %o1 - 0x10, %g3), memcpy_retl_o2_plus_o4_plus_40) + EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), memcpy_retl_o2_plus_o4_plus_40) add %o0, 0x08, %o0 - EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_32) - EX_ST(STORE_INIT(%o5, %o0), NG4_retl_o2_plus_o4_plus_32) + EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), memcpy_retl_o2_plus_o4_plus_32) + EX_ST(STORE_INIT(%o5, %o0), memcpy_retl_o2_plus_o4_plus_32) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_24) + EX_ST(STORE_INIT(%g2, %o0), memcpy_retl_o2_plus_o4_plus_24) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_16) + EX_ST(STORE_INIT(%g3, %o0), memcpy_retl_o2_plus_o4_plus_16) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_8) + EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), memcpy_retl_o2_plus_o4_plus_8) add %o0, 0x08, %o0 bne,pt %icc, 1b LOAD(prefetch, %o1 + 0x200, #n_reads_strong) @@ -367,17 +218,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ sub %o2, %o4, %o2 alignaddr %o1, %g0, %g1 add %o1, %o4, %o1 - EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), NG4_retl_o2_plus_o4) -1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), NG4_retl_o2_plus_o4) + EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), memcpy_retl_o2_plus_o4) +1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), memcpy_retl_o2_plus_o4) subcc %o4, 0x40, %o4 - EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), NG4_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), memcpy_retl_o2_plus_o4_plus_64) faligndata %f0, %f2, %f16 - EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), NG4_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), memcpy_retl_o2_plus_o4_plus_64) faligndata %f2, %f4, %f18 add %g1, 0x40, %g1 faligndata %f4, %f6, %f20 @@ -386,14 +237,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ faligndata %f10, %f12, %f26 faligndata %f12, %f14, %f28 faligndata %f14, %f0, %f30 - EX_ST_FP(STORE(std, %f16, %o0 + 0x00), NG4_retl_o2_plus_o4_plus_64) - EX_ST_FP(STORE(std, %f18, %o0 + 0x08), NG4_retl_o2_plus_o4_plus_56) - EX_ST_FP(STORE(std, %f20, %o0 + 0x10), NG4_retl_o2_plus_o4_plus_48) - EX_ST_FP(STORE(std, %f22, %o0 + 0x18), NG4_retl_o2_plus_o4_plus_40) - EX_ST_FP(STORE(std, %f24, %o0 + 0x20), NG4_retl_o2_plus_o4_plus_32) - EX_ST_FP(STORE(std, %f26, %o0 + 0x28), NG4_retl_o2_plus_o4_plus_24) - EX_ST_FP(STORE(std, %f28, %o0 + 0x30), NG4_retl_o2_plus_o4_plus_16) - EX_ST_FP(STORE(std, %f30, %o0 + 0x38), NG4_retl_o2_plus_o4_plus_8) + EX_ST_FP(STORE(std, %f16, %o0 + 0x00), memcpy_retl_o2_plus_o4_plus_64) + EX_ST_FP(STORE(std, %f18, %o0 + 0x08), memcpy_retl_o2_plus_o4_plus_56) + EX_ST_FP(STORE(std, %f20, %o0 + 0x10), memcpy_retl_o2_plus_o4_plus_48) + EX_ST_FP(STORE(std, %f22, %o0 + 0x18), memcpy_retl_o2_plus_o4_plus_40) + EX_ST_FP(STORE(std, %f24, %o0 + 0x20), memcpy_retl_o2_plus_o4_plus_32) + EX_ST_FP(STORE(std, %f26, %o0 + 0x28), memcpy_retl_o2_plus_o4_plus_24) + EX_ST_FP(STORE(std, %f28, %o0 + 0x30), memcpy_retl_o2_plus_o4_plus_16) + EX_ST_FP(STORE(std, %f30, %o0 + 0x38), memcpy_retl_o2_plus_o4_plus_8) add %o0, 0x40, %o0 bne,pt %icc, 1b LOAD(prefetch, %g1 + 0x200, #n_reads_strong) @@ -421,38 +272,38 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ andncc %o2, 0x20 - 1, %o5 be,pn %icc, 2f sub %o2, %o5, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) - EX_LD(LOAD(ldx, %o1 + 0x08, %g2), NG4_retl_o2_plus_o5) - EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), NG4_retl_o2_plus_o5) - EX_LD(LOAD(ldx, %o1 + 0x18, %o4), NG4_retl_o2_plus_o5) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x08, %g2), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x18, %o4), memcpy_retl_o2_plus_o5) add %o1, 0x20, %o1 subcc %o5, 0x20, %o5 - EX_ST(STORE(stx, %g1, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_32) - EX_ST(STORE(stx, %g2, %o0 + 0x08), NG4_retl_o2_plus_o5_plus_24) - EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), NG4_retl_o2_plus_o5_plus_24) - EX_ST(STORE(stx, %o4, %o0 + 0x18), NG4_retl_o2_plus_o5_plus_8) + EX_ST(STORE(stx, %g1, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) + EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) bne,pt %icc, 1b add %o0, 0x20, %o0 2: andcc %o2, 0x18, %o5 be,pt %icc, 3f sub %o2, %o5, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o5) add %o1, 0x08, %o1 add %o0, 0x08, %o0 subcc %o5, 0x08, %o5 bne,pt %icc, 1b - EX_ST(STORE(stx, %g1, %o0 - 0x08), NG4_retl_o2_plus_o5_plus_8) + EX_ST(STORE(stx, %g1, %o0 - 0x08), memcpy_retl_o2_plus_o5_plus_8) 3: brz,pt %o2, .Lexit cmp %o2, 0x04 bl,pn %icc, .Ltiny nop - EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2) + EX_LD(LOAD(lduw, %o1 + 0x00, %g1), memcpy_retl_o2) add %o1, 0x04, %o1 add %o0, 0x04, %o0 subcc %o2, 0x04, %o2 bne,pn %icc, .Ltiny - EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_4) + EX_ST(STORE(stw, %g1, %o0 - 0x04), memcpy_retl_o2_plus_4) ba,a,pt %icc, .Lexit .Lmedium_unaligned: /* First get dest 8 byte aligned. */ @@ -461,12 +312,12 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ brz,pt %g1, 2f sub %o2, %g1, %o2 -1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) add %o1, 1, %o1 subcc %g1, 1, %g1 add %o0, 1, %o0 bne,pt %icc, 1b - EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1) + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) 2: and %o1, 0x7, %g1 brz,pn %g1, .Lmedium_noprefetch @@ -474,16 +325,16 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ mov 64, %g2 sub %g2, %g1, %g2 andn %o1, 0x7, %o1 - EX_LD(LOAD(ldx, %o1 + 0x00, %o4), NG4_retl_o2) + EX_LD(LOAD(ldx, %o1 + 0x00, %o4), memcpy_retl_o2) sllx %o4, %g1, %o4 andn %o2, 0x08 - 1, %o5 sub %o2, %o5, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), NG4_retl_o2_plus_o5) +1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), memcpy_retl_o2_plus_o5) add %o1, 0x08, %o1 subcc %o5, 0x08, %o5 srlx %g3, %g2, GLOBAL_SPARE or GLOBAL_SPARE, %o4, GLOBAL_SPARE - EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_8) + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_8) add %o0, 0x08, %o0 bne,pt %icc, 1b sllx %g3, %g1, %o4 @@ -494,17 +345,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %icc, .Lsmall_unaligned .Ltiny: - EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2) + EX_LD(LOAD(ldub, %o1 + 0x00, %g1), memcpy_retl_o2) subcc %o2, 1, %o2 be,pn %icc, .Lexit - EX_ST(STORE(stb, %g1, %o0 + 0x00), NG4_retl_o2_plus_1) - EX_LD(LOAD(ldub, %o1 + 0x01, %g1), NG4_retl_o2) + EX_ST(STORE(stb, %g1, %o0 + 0x00), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x01, %g1), memcpy_retl_o2) subcc %o2, 1, %o2 be,pn %icc, .Lexit - EX_ST(STORE(stb, %g1, %o0 + 0x01), NG4_retl_o2_plus_1) - EX_LD(LOAD(ldub, %o1 + 0x02, %g1), NG4_retl_o2) + EX_ST(STORE(stb, %g1, %o0 + 0x01), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x02, %g1), memcpy_retl_o2) ba,pt %icc, .Lexit - EX_ST(STORE(stb, %g1, %o0 + 0x02), NG4_retl_o2) + EX_ST(STORE(stb, %g1, %o0 + 0x02), memcpy_retl_o2) .Lsmall: andcc %g2, 0x3, %g0 @@ -512,23 +363,23 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ andn %o2, 0x4 - 1, %o5 sub %o2, %o5, %o2 1: - EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) + EX_LD(LOAD(lduw, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o5) add %o1, 0x04, %o1 subcc %o5, 0x04, %o5 add %o0, 0x04, %o0 bne,pt %icc, 1b - EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_o5_plus_4) + EX_ST(STORE(stw, %g1, %o0 - 0x04), memcpy_retl_o2_plus_o5_plus_4) brz,pt %o2, .Lexit nop ba,a,pt %icc, .Ltiny .Lsmall_unaligned: -1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1), memcpy_retl_o2) add %o1, 1, %o1 add %o0, 1, %o0 subcc %o2, 1, %o2 bne,pt %icc, 1b - EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1) + EX_ST(STORE(stb, %g1, %o0 - 0x01), memcpy_retl_o2_plus_1) ba,a,pt %icc, .Lexit nop .size FUNC_NAME, .-FUNC_NAME diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S index 54f98706b03b2f53025adb99e086002a0629e9f0..f9b42b3c63b07c030daa69e88127563131fbdf3a 100644 --- a/arch/sparc/lib/U3memcpy.S +++ b/arch/sparc/lib/U3memcpy.S @@ -145,13 +145,13 @@ ENDPROC(U3_retl_o2_plus_GS_plus_0x08) ENTRY(U3_retl_o2_and_7_plus_GS) and %o2, 7, %o2 retl - add %o2, GLOBAL_SPARE, %o2 + add %o2, GLOBAL_SPARE, %o0 ENDPROC(U3_retl_o2_and_7_plus_GS) ENTRY(U3_retl_o2_and_7_plus_GS_plus_8) add GLOBAL_SPARE, 8, GLOBAL_SPARE and %o2, 7, %o2 retl - add %o2, GLOBAL_SPARE, %o2 + add %o2, GLOBAL_SPARE, %o0 ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8) #endif @@ -168,18 +168,25 @@ ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8) FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ srlx %o2, 31, %g2 cmp %g2, 0 + + /* software trap 5 "Range Check" if dst >= 0x80000000 */ tne %xcc, 5 PREAMBLE mov %o0, %o4 + + /* if len == 0 */ cmp %o2, 0 - be,pn %XCC, 85f + be,pn %XCC, end_return or %o0, %o1, %o3 + + /* if len < 16 */ cmp %o2, 16 - blu,a,pn %XCC, 80f + blu,a,pn %XCC, less_than_16 or %o3, %o2, %o3 + /* if len < 192 */ cmp %o2, (3 * 64) - blu,pt %XCC, 70f + blu,pt %XCC, less_than_192 andcc %o3, 0x7, %g0 /* Clobbers o5/g1/g2/g3/g7/icc/xcc. We must preserve @@ -362,7 +369,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ cmp %o2, 0 add %o1, %g1, %o1 VISExitHalf - be,pn %XCC, 85f + be,pn %XCC, end_return sub %o0, %o1, %o3 andcc %g1, 0x7, %g0 @@ -392,14 +399,15 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ sub %o2, 2, %o2 1: andcc %o2, 0x1, %g0 - be,pt %icc, 85f + be,pt %icc, end_return nop EX_LD(LOAD(ldub, %o1, %o5), U3_retl_o2) - ba,pt %xcc, 85f + ba,pt %xcc, end_return EX_ST(STORE(stb, %o5, %o1 + %o3), U3_retl_o2) .align 64 -70: /* 16 < len <= 64 */ + /* 16 <= len < 192 */ +less_than_192: bne,pn %XCC, 75f sub %o0, %o1, %o3 @@ -429,7 +437,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ EX_ST(STORE(stw, %o5, %o1 + %o3), U3_retl_o2_plus_4) add %o1, 0x4, %o1 1: cmp %o2, 0 - be,pt %XCC, 85f + be,pt %XCC, end_return nop ba,pt %xcc, 90f nop @@ -475,13 +483,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ srl %g1, 3, %g1 andcc %o2, 0x7, %o2 - be,pn %icc, 85f + be,pn %icc, end_return add %o1, %g1, %o1 ba,pt %xcc, 90f sub %o0, %o1, %o3 .align 64 -80: /* 0 < len <= 16 */ + /* 0 < len < 16 */ +less_than_16: andcc %o3, 0x3, %g0 bne,pn %XCC, 90f sub %o0, %o1, %o3 @@ -493,7 +502,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ bgu,pt %XCC, 1b add %o1, 4, %o1 -85: retl +end_return: + retl mov EX_RETVAL(%o4), %o0 .align 32 diff --git a/arch/sparc/lib/multi3.S b/arch/sparc/lib/multi3.S index d6b6c97fe3c73061f911737a5da23ab41a3eab77..703127aaf4a5015ee4a1099e6129735f7162222b 100644 --- a/arch/sparc/lib/multi3.S +++ b/arch/sparc/lib/multi3.S @@ -5,26 +5,26 @@ .align 4 ENTRY(__multi3) /* %o0 = u, %o1 = v */ mov %o1, %g1 - srl %o3, 0, %g4 - mulx %g4, %g1, %o1 + srl %o3, 0, %o4 + mulx %o4, %g1, %o1 srlx %g1, 0x20, %g3 - mulx %g3, %g4, %g5 - sllx %g5, 0x20, %o5 - srl %g1, 0, %g4 + mulx %g3, %o4, %g7 + sllx %g7, 0x20, %o5 + srl %g1, 0, %o4 sub %o1, %o5, %o5 srlx %o5, 0x20, %o5 - addcc %g5, %o5, %g5 + addcc %g7, %o5, %g7 srlx %o3, 0x20, %o5 - mulx %g4, %o5, %g4 + mulx %o4, %o5, %o4 mulx %g3, %o5, %o5 sethi %hi(0x80000000), %g3 - addcc %g5, %g4, %g5 - srlx %g5, 0x20, %g5 + addcc %g7, %o4, %g7 + srlx %g7, 0x20, %g7 add %g3, %g3, %g3 movcc %xcc, %g0, %g3 - addcc %o5, %g5, %o5 - sllx %g4, 0x20, %g4 - add %o1, %g4, %o1 + addcc %o5, %g7, %o5 + sllx %o4, 0x20, %o4 + add %o1, %o4, %o1 add %o5, %g3, %g2 mulx %g1, %o2, %g1 add %g1, %g2, %g1 diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index f80cfc64c55ba2b975cf5c3c0fe4fb72da316de9..d809099ffd47394795b108d3ec7bed5efbcdc992 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c @@ -103,6 +103,45 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, return 1; } +static int gup_huge_pud(pud_t *pudp, pud_t pud, unsigned long addr, + unsigned long end, int write, struct page **pages, + int *nr) +{ + struct page *head, *page; + int refs; + + if (!(pud_val(pud) & _PAGE_VALID)) + return 0; + + if (write && !pud_write(pud)) + return 0; + + refs = 0; + page = pud_page(pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT); + head = compound_head(page); + do { + VM_BUG_ON(compound_head(page) != head); + pages[*nr] = page; + (*nr)++; + page++; + refs++; + } while (addr += PAGE_SIZE, addr != end); + + if (!page_cache_add_speculative(head, refs)) { + *nr -= refs; + return 0; + } + + if (unlikely(pud_val(pud) != pud_val(*pudp))) { + *nr -= refs; + while (refs--) + put_page(head); + return 0; + } + + return 1; +} + static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { @@ -141,7 +180,11 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, next = pud_addr_end(addr, end); if (pud_none(pud)) return 0; - if (!gup_pmd_range(pud, addr, next, write, pages, nr)) + if (unlikely(pud_large(pud))) { + if (!gup_huge_pud(pudp, pud, addr, next, + write, pages, nr)) + return 0; + } else if (!gup_pmd_range(pud, addr, next, write, pages, nr)) return 0; } while (pudp++, addr = next, addr != end); diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index 28ee8d8ffa0771fa8e22a9be6882695cab873ad4..bcd8cdbc377f63bb57d4d5345b9a0c666570bafc 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -143,6 +143,10 @@ static pte_t sun4v_hugepage_shift_to_tte(pte_t entry, unsigned int shift) pte_val(entry) = pte_val(entry) & ~_PAGE_SZALL_4V; switch (shift) { + case HPAGE_16GB_SHIFT: + hugepage_size = _PAGE_SZ16GB_4V; + pte_val(entry) |= _PAGE_PUD_HUGE; + break; case HPAGE_2GB_SHIFT: hugepage_size = _PAGE_SZ2GB_4V; pte_val(entry) |= _PAGE_PMD_HUGE; @@ -187,6 +191,9 @@ static unsigned int sun4v_huge_tte_to_shift(pte_t entry) unsigned int shift; switch (tte_szbits) { + case _PAGE_SZ16GB_4V: + shift = HPAGE_16GB_SHIFT; + break; case _PAGE_SZ2GB_4V: shift = HPAGE_2GB_SHIFT; break; @@ -259,22 +266,19 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, pgd_t *pgd; pud_t *pud; pmd_t *pmd; - pte_t *pte = NULL; pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); - if (pud) { - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - return NULL; - - if (sz >= PMD_SIZE) - pte = (pte_t *)pmd; - else - pte = pte_alloc_map(mm, pmd, addr); - } - - return pte; + if (!pud) + return NULL; + if (sz >= PUD_SIZE) + return (pte_t *)pud; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + return NULL; + if (sz >= PMD_SIZE) + return (pte_t *)pmd; + return pte_alloc_map(mm, pmd, addr); } pte_t *huge_pte_offset(struct mm_struct *mm, @@ -283,34 +287,40 @@ pte_t *huge_pte_offset(struct mm_struct *mm, pgd_t *pgd; pud_t *pud; pmd_t *pmd; - pte_t *pte = NULL; pgd = pgd_offset(mm, addr); - if (!pgd_none(*pgd)) { - pud = pud_offset(pgd, addr); - if (!pud_none(*pud)) { - pmd = pmd_offset(pud, addr); - if (!pmd_none(*pmd)) { - if (is_hugetlb_pmd(*pmd)) - pte = (pte_t *)pmd; - else - pte = pte_offset_map(pmd, addr); - } - } - } - - return pte; + if (pgd_none(*pgd)) + return NULL; + pud = pud_offset(pgd, addr); + if (pud_none(*pud)) + return NULL; + if (is_hugetlb_pud(*pud)) + return (pte_t *)pud; + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) + return NULL; + if (is_hugetlb_pmd(*pmd)) + return (pte_t *)pmd; + return pte_offset_map(pmd, addr); } void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { - unsigned int i, nptes, orig_shift, shift; - unsigned long size; + unsigned int nptes, orig_shift, shift; + unsigned long i, size; pte_t orig; size = huge_tte_to_size(entry); - shift = size >= HPAGE_SIZE ? PMD_SHIFT : PAGE_SHIFT; + + shift = PAGE_SHIFT; + if (size >= PUD_SIZE) + shift = PUD_SHIFT; + else if (size >= PMD_SIZE) + shift = PMD_SHIFT; + else + shift = PAGE_SHIFT; + nptes = size >> shift; if (!pte_present(*ptep) && pte_present(entry)) @@ -333,19 +343,23 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - unsigned int i, nptes, hugepage_shift; + unsigned int i, nptes, orig_shift, shift; unsigned long size; pte_t entry; entry = *ptep; size = huge_tte_to_size(entry); - if (size >= HPAGE_SIZE) - nptes = size >> PMD_SHIFT; + + shift = PAGE_SHIFT; + if (size >= PUD_SIZE) + shift = PUD_SHIFT; + else if (size >= PMD_SIZE) + shift = PMD_SHIFT; else - nptes = size >> PAGE_SHIFT; + shift = PAGE_SHIFT; - hugepage_shift = pte_none(entry) ? PAGE_SHIFT : - huge_tte_to_shift(entry); + nptes = size >> shift; + orig_shift = pte_none(entry) ? PAGE_SHIFT : huge_tte_to_shift(entry); if (pte_present(entry)) mm->context.hugetlb_pte_count -= nptes; @@ -354,11 +368,11 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, for (i = 0; i < nptes; i++) ptep[i] = __pte(0UL); - maybe_tlb_batch_add(mm, addr, ptep, entry, 0, hugepage_shift); + maybe_tlb_batch_add(mm, addr, ptep, entry, 0, orig_shift); /* An HPAGE_SIZE'ed page is composed of two REAL_HPAGE_SIZE'ed pages */ if (size == HPAGE_SIZE) maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, entry, 0, - hugepage_shift); + orig_shift); return entry; } @@ -371,7 +385,8 @@ int pmd_huge(pmd_t pmd) int pud_huge(pud_t pud) { - return 0; + return !pud_none(pud) && + (pud_val(pud) & (_PAGE_VALID|_PAGE_PUD_HUGE)) != _PAGE_VALID; } static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd, @@ -435,8 +450,11 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, next = pud_addr_end(addr, end); if (pud_none_or_clear_bad(pud)) continue; - hugetlb_free_pmd_range(tlb, pud, addr, next, floor, - ceiling); + if (is_hugetlb_pud(*pud)) + pud_clear(pud); + else + hugetlb_free_pmd_range(tlb, pud, addr, next, floor, + ceiling); } while (pud++, addr = next, addr != end); start &= PGDIR_MASK; diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3c40ebd50f928cbbbfe69c65c35810a78b30c53d..b2ba410b26f4a013493a51772ce2eb76c9ddc9f3 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -325,6 +325,41 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde } #ifdef CONFIG_HUGETLB_PAGE +static void __init add_huge_page_size(unsigned long size) +{ + unsigned int order; + + if (size_to_hstate(size)) + return; + + order = ilog2(size) - PAGE_SHIFT; + hugetlb_add_hstate(order); +} + +static int __init hugetlbpage_init(void) +{ + add_huge_page_size(1UL << HPAGE_64K_SHIFT); + add_huge_page_size(1UL << HPAGE_SHIFT); + add_huge_page_size(1UL << HPAGE_256MB_SHIFT); + add_huge_page_size(1UL << HPAGE_2GB_SHIFT); + + return 0; +} + +arch_initcall(hugetlbpage_init); + +static void __init pud_huge_patch(void) +{ + struct pud_huge_patch_entry *p; + unsigned long addr; + + p = &__pud_huge_patch; + addr = p->addr; + *(unsigned int *)addr = p->insn; + + __asm__ __volatile__("flush %0" : : "r" (addr)); +} + static int __init setup_hugepagesz(char *string) { unsigned long long hugepage_size; @@ -337,6 +372,11 @@ static int __init setup_hugepagesz(char *string) hugepage_shift = ilog2(hugepage_size); switch (hugepage_shift) { + case HPAGE_16GB_SHIFT: + hv_pgsz_mask = HV_PGSZ_MASK_16GB; + hv_pgsz_idx = HV_PGSZ_IDX_16GB; + pud_huge_patch(); + break; case HPAGE_2GB_SHIFT: hv_pgsz_mask = HV_PGSZ_MASK_2GB; hv_pgsz_idx = HV_PGSZ_IDX_2GB; @@ -364,7 +404,7 @@ static int __init setup_hugepagesz(char *string) goto out; } - hugetlb_add_hstate(hugepage_shift - PAGE_SHIFT); + add_huge_page_size(hugepage_size); rc = 1; out: @@ -377,6 +417,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * { struct mm_struct *mm; unsigned long flags; + bool is_huge_tsb; pte_t pte = *ptep; if (tlb_type != hypervisor) { @@ -394,15 +435,37 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * spin_lock_irqsave(&mm->context.lock, flags); + is_huge_tsb = false; #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) - if ((mm->context.hugetlb_pte_count || mm->context.thp_pte_count) && - is_hugetlb_pmd(__pmd(pte_val(pte)))) { - /* We are fabricating 8MB pages using 4MB real hw pages. */ - pte_val(pte) |= (address & (1UL << REAL_HPAGE_SHIFT)); - __update_mmu_tsb_insert(mm, MM_TSB_HUGE, REAL_HPAGE_SHIFT, - address, pte_val(pte)); - } else + if (mm->context.hugetlb_pte_count || mm->context.thp_pte_count) { + unsigned long hugepage_size = PAGE_SIZE; + + if (is_vm_hugetlb_page(vma)) + hugepage_size = huge_page_size(hstate_vma(vma)); + + if (hugepage_size >= PUD_SIZE) { + unsigned long mask = 0x1ffc00000UL; + + /* Transfer bits [32:22] from address to resolve + * at 4M granularity. + */ + pte_val(pte) &= ~mask; + pte_val(pte) |= (address & mask); + } else if (hugepage_size >= PMD_SIZE) { + /* We are fabricating 8MB pages using 4MB + * real hw pages. + */ + pte_val(pte) |= (address & (1UL << REAL_HPAGE_SHIFT)); + } + + if (hugepage_size >= PMD_SIZE) { + __update_mmu_tsb_insert(mm, MM_TSB_HUGE, + REAL_HPAGE_SHIFT, address, pte_val(pte)); + is_huge_tsb = true; + } + } #endif + if (!is_huge_tsb) __update_mmu_tsb_insert(mm, MM_TSB_BASE, PAGE_SHIFT, address, pte_val(pte)); @@ -1921,12 +1984,22 @@ static void __init setup_page_offset(void) break; case SUN4V_CHIP_SPARC_M7: case SUN4V_CHIP_SPARC_SN: - default: /* M7 and later support 52-bit virtual addresses. */ sparc64_va_hole_top = 0xfff8000000000000UL; sparc64_va_hole_bottom = 0x0008000000000000UL; max_phys_bits = 49; break; + case SUN4V_CHIP_SPARC_M8: + default: + /* M8 and later support 54-bit virtual addresses. + * However, restricting M8 and above VA bits to 53 + * as 4-level page table cannot support more than + * 53 VA bits. + */ + sparc64_va_hole_top = 0xfff0000000000000UL; + sparc64_va_hole_bottom = 0x0010000000000000UL; + max_phys_bits = 51; + break; } } @@ -2138,6 +2211,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) */ switch (sun4v_chip_type) { case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_M8: case SUN4V_CHIP_SPARC_SN: pagecv_flag = 0x00; break; @@ -2290,6 +2364,7 @@ void __init paging_init(void) */ switch (sun4v_chip_type) { case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_M8: case SUN4V_CHIP_SPARC_SN: page_cache4v_flag = _PAGE_CP_4V; break; diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 8799ae9a8788f6fd8628c35974ec172d6aab61cc..c340af7b13717e7fa63039ec27d863a106b3fd45 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -128,6 +128,8 @@ static u32 WDISP10(u32 off) #define BA (BRANCH | CONDA) #define BG (BRANCH | CONDG) +#define BL (BRANCH | CONDL) +#define BLE (BRANCH | CONDLE) #define BGU (BRANCH | CONDGU) #define BLEU (BRANCH | CONDLEU) #define BGE (BRANCH | CONDGE) @@ -715,9 +717,15 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src, case BPF_JGT: br_opcode = BGU; break; + case BPF_JLT: + br_opcode = BLU; + break; case BPF_JGE: br_opcode = BGEU; break; + case BPF_JLE: + br_opcode = BLEU; + break; case BPF_JSET: case BPF_JNE: br_opcode = BNE; @@ -725,9 +733,15 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src, case BPF_JSGT: br_opcode = BG; break; + case BPF_JSLT: + br_opcode = BL; + break; case BPF_JSGE: br_opcode = BGE; break; + case BPF_JSLE: + br_opcode = BLE; + break; default: /* Make sure we dont leak kernel information to the * user. @@ -746,18 +760,30 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src, case BPF_JGT: cbcond_opcode = CBCONDGU; break; + case BPF_JLT: + cbcond_opcode = CBCONDLU; + break; case BPF_JGE: cbcond_opcode = CBCONDGEU; break; + case BPF_JLE: + cbcond_opcode = CBCONDLEU; + break; case BPF_JNE: cbcond_opcode = CBCONDNE; break; case BPF_JSGT: cbcond_opcode = CBCONDG; break; + case BPF_JSLT: + cbcond_opcode = CBCONDL; + break; case BPF_JSGE: cbcond_opcode = CBCONDGE; break; + case BPF_JSLE: + cbcond_opcode = CBCONDLE; + break; default: /* Make sure we dont leak kernel information to the * user. @@ -1176,10 +1202,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* IF (dst COND src) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JNE | BPF_X: case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: case BPF_JMP | BPF_JSET | BPF_X: { int err; @@ -1191,10 +1221,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* IF (dst COND imm) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: case BPF_JMP | BPF_JSET | BPF_K: { int err; diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c index 17bd2e167e07edd934dfe9957c43712b21401c55..df707a8ad3117074805e138a3992a7e080d43e5a 100644 --- a/arch/sparc/power/hibernate.c +++ b/arch/sparc/power/hibernate.c @@ -35,6 +35,5 @@ void restore_processor_state(void) { struct mm_struct *mm = current->active_mm; - load_secondary_context(mm); - tsb_context_switch(mm); + tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context)); } diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index 0d925fa0f0c1f270c7bb6ffcacd8f548ede225ec..9f94435cc44f455597fad4afda30fca3e5238675 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -409,5 +409,4 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 149d8e8eacb83c223d186f86d342de9db21f6063..1c5bd4f8ffca34110fe68fd3ffd96e98743aef2f 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -189,7 +189,6 @@ CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m @@ -521,7 +520,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRC_CCITT=m CONFIG_CRC7=m diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h index a93774255136d4c250065407d2c295ac7f2088e7..53a423e7cb92e445d54b5f10f546b410683cf367 100644 --- a/arch/tile/include/asm/atomic_32.h +++ b/arch/tile/include/asm/atomic_32.h @@ -101,6 +101,8 @@ static inline void atomic_set(atomic_t *v, int n) _atomic_xchg(&v->counter, n); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + /* A 64bit atomic type */ typedef struct { diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h index bbc71a29b2c6a860abf9d7a9d81a6ad75a57f7a1..7061dc8af43af0681208f0fef5b769a99348f346 100644 --- a/arch/tile/include/asm/dma-mapping.h +++ b/arch/tile/include/asm/dma-mapping.h @@ -68,8 +68,8 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) int dma_set_mask(struct device *dev, u64 mask); /* - * dma_alloc_noncoherent() is #defined to return coherent memory, - * so there's no need to do any flushing here. + * dma_alloc_attrs() always returns non-cacheable memory, so there's no need to + * do any flushing here. */ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h index e64a1b75fc386c4786d6a4988a4f5eb71bbfbd27..83c1e639b41111049aad89164067d4dd8b587bb5 100644 --- a/arch/tile/include/asm/futex.h +++ b/arch/tile/include/asm/futex.h @@ -106,12 +106,9 @@ lock = __atomic_hashed_lock((int __force *)uaddr) #endif -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int uninitialized_var(val), ret; __futex_prolog(); @@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) /* The 32-bit futex code makes this assumption, so validate it here. */ BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int)); - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (val == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (val != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (val < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (val >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (val <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (val > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = val; + return ret; } diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h index b14b1ba5bf9c328959bea3a14643fbb87e4ae7b1..cba8ba9b8da6ab218cee2d4ca3cecaf6a2488d97 100644 --- a/arch/tile/include/asm/spinlock_32.h +++ b/arch/tile/include/asm/spinlock_32.h @@ -64,8 +64,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) lock->current_ticket = old_ticket + TICKET_QUANTUM; } -void arch_spin_unlock_wait(arch_spinlock_t *lock); - /* * Read-write spinlocks, allowing multiple readers * but only one writer. diff --git a/arch/tile/include/asm/spinlock_64.h b/arch/tile/include/asm/spinlock_64.h index b9718fb4e74a7703a0fbf3c37691b9c00a84aced..9a2c2d605752e6649c97286389013b1cce5f3e2f 100644 --- a/arch/tile/include/asm/spinlock_64.h +++ b/arch/tile/include/asm/spinlock_64.h @@ -58,8 +58,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) __insn_fetchadd4(&lock->lock, 1U << __ARCH_SPIN_CURRENT_SHIFT); } -void arch_spin_unlock_wait(arch_spinlock_t *lock); - void arch_spin_lock_slow(arch_spinlock_t *lock, u32 val); /* Grab the "next" ticket number and bump it atomically. diff --git a/arch/tile/include/uapi/asm/siginfo.h b/arch/tile/include/uapi/asm/siginfo.h index 56d661bb010bc77d36a4e18cdc60799ff9c52744..e83f931aa1f0a1d21f6db9a422bea2ff0c88c524 100644 --- a/arch/tile/include/uapi/asm/siginfo.h +++ b/arch/tile/include/uapi/asm/siginfo.h @@ -26,8 +26,8 @@ /* * Additional Tile-specific SIGILL si_codes */ -#define ILL_DBLFLT (__SI_FAULT|9) /* double fault */ -#define ILL_HARDWALL (__SI_FAULT|10) /* user networks hardwall violation */ +#define ILL_DBLFLT 9 /* double fault */ +#define ILL_HARDWALL 10 /* user networks hardwall violation */ #undef NSIGILL #define NSIGILL 10 diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 0e863f1ee08c040f84c4aa24a770877a2049fe98..971d87a1d8cf8a9241c026e7d83f33bb8581c9eb 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c @@ -64,7 +64,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr 3 ints plus the relevant union member. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) { err |= __put_user(from->si_pid, &to->si_pid); @@ -77,28 +77,26 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr */ err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_FAULT: break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); /* FALL THROUGH */ default: - case __SI_KILL >> 16: + case SIL_KILL: err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - /* This is not generated by the kernel as of now. */ - case __SI_RT >> 16: - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index bc6656b5708b168f8f26c99b599b0233cf7ba5e2..bbf81579b1f84f7fbbc3738bb14b511a65134f1a 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -66,16 +66,6 @@ static int pci_scan_flags[TILE_NUM_PCIE]; static struct pci_ops tile_cfg_ops; -/* - * We don't need to worry about the alignment of resources. - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - /* * Open a FD to the hypervisor PCI device. * @@ -274,6 +264,7 @@ static void fixup_read_and_payload_sizes(void) */ int __init pcibios_init(void) { + struct pci_host_bridge *bridge; int i; pr_info("PCI: Probing PCI hardware\n"); @@ -306,16 +297,26 @@ int __init pcibios_init(void) pci_add_resource(&resources, &ioport_resource); pci_add_resource(&resources, &iomem_resource); - bus = pci_scan_root_bus(NULL, 0, controller->ops, - controller, &resources); + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + break; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = controller; + bridge->busnr = 0; + bridge->ops = controller->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = tile_map_irq; + + pci_scan_root_bus_bridge(bridge); + bus = bridge->bus; controller->root_bus = bus; controller->last_busno = bus->busn_res.end; } } - /* Do machine dependent PCI interrupt routing */ - pci_fixup_irqs(pci_common_swizzle, tile_map_irq); - /* * This comes from the generic Linux PCI driver. * @@ -369,14 +370,6 @@ int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* - * No bus fixups needed. - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Nothing needs to be done. */ -} - void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling. */ diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index b554a68eea1bbeb4b65aae2b0b6fcf226ca381ec..9aa238ac7b3582a6894b03295811b60f02874e9e 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -108,15 +108,6 @@ static struct pci_ops tile_cfg_ops; /* Mask of CPUs that should receive PCIe interrupts. */ static struct cpumask intr_cpus_map; -/* We don't need to worry about the alignment of resources. */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, - resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - /* * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. * For now, we simply send interrupts to non-dataplane CPUs. @@ -669,6 +660,7 @@ int __init pcibios_init(void) resource_size_t offset; LIST_HEAD(resources); int next_busno; + struct pci_host_bridge *bridge; int i; tile_pci_init(); @@ -881,15 +873,25 @@ int __init pcibios_init(void) controller->mem_offset); pci_add_resource(&resources, &controller->io_space); controller->first_busno = next_busno; - bus = pci_scan_root_bus(NULL, next_busno, controller->ops, - controller, &resources); + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + break; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = controller; + bridge->busnr = next_busno; + bridge->ops = controller->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = tile_map_irq; + + pci_scan_root_bus_bridge(bridge); + bus = bridge->bus; controller->root_bus = bus; next_busno = bus->busn_res.end + 1; } - /* Do machine dependent PCI interrupt routing */ - pci_fixup_irqs(pci_common_swizzle, tile_map_irq); - /* * This comes from the generic Linux PCI driver. * @@ -1038,11 +1040,6 @@ int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* No bus fixups needed. */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - /* Process any "pci=" kernel boot arguments. */ char *__init pcibios_setup(char *str) { diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index 443a70bccc1c862d945d3a84945c6771033b74c7..ad83c1e66dbd23c5ba46e20c8e5deefdf6f3655e 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -140,7 +140,7 @@ static int __init setup_maxnodemem(char *str) { char *endp; unsigned long long maxnodemem; - long node; + unsigned long node; node = str ? simple_strtoul(str, &endp, 0) : INT_MAX; if (node >= MAX_NUMNODES || *endp != ':') @@ -1200,7 +1200,7 @@ static void __init validate_hv(void) * We use a struct cpumask for this, so it must be big enough. */ if ((smp_height * smp_width) > nr_cpu_ids) - early_panic("Hypervisor %d x %d grid too big for Linux NR_CPUS %d\n", + early_panic("Hypervisor %d x %d grid too big for Linux NR_CPUS %u\n", smp_height, smp_width, nr_cpu_ids); #endif diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index 54804866f238a5f4c41162bef9e163281cbac818..9b08c6055f15eb7e057eda016d5dcad30643af26 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c @@ -188,7 +188,7 @@ static int special_ill(tile_bundle_bits bundle, int *sigp, int *codep) /* Make it the requested signal. */ *sigp = sig; - *codep = code | __SI_FAULT; + *codep = code; return 1; } diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c index 076c6cc431136fc8475b0fa0b768bb7a6083dc66..db9333f2447c397013854ef0f1f7abe3e675089b 100644 --- a/arch/tile/lib/spinlock_32.c +++ b/arch/tile/lib/spinlock_32.c @@ -62,29 +62,6 @@ int arch_spin_trylock(arch_spinlock_t *lock) } EXPORT_SYMBOL(arch_spin_trylock); -void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - u32 iterations = 0; - int curr = READ_ONCE(lock->current_ticket); - int next = READ_ONCE(lock->next_ticket); - - /* Return immediately if unlocked. */ - if (next == curr) - return; - - /* Wait until the current locker has released the lock. */ - do { - delay_backoff(iterations++); - } while (READ_ONCE(lock->current_ticket) == curr); - - /* - * The TILE architecture doesn't do read speculation; therefore - * a control dependency guarantees a LOAD->{LOAD,STORE} order. - */ - barrier(); -} -EXPORT_SYMBOL(arch_spin_unlock_wait); - /* * The low byte is always reserved to be the marker for a "tns" operation * since the low bit is set to "1" by a tns. The next seven bits are diff --git a/arch/tile/lib/spinlock_64.c b/arch/tile/lib/spinlock_64.c index a4b5b2cbce9337bdc775a92c087b3c5cf3876965..de414c22892fd5bca9caeaf5cdf8e7de8ae6ffc8 100644 --- a/arch/tile/lib/spinlock_64.c +++ b/arch/tile/lib/spinlock_64.c @@ -62,28 +62,6 @@ int arch_spin_trylock(arch_spinlock_t *lock) } EXPORT_SYMBOL(arch_spin_trylock); -void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - u32 iterations = 0; - u32 val = READ_ONCE(lock->lock); - u32 curr = arch_spin_current(val); - - /* Return immediately if unlocked. */ - if (arch_spin_next(val) == curr) - return; - - /* Wait until the current locker has released the lock. */ - do { - delay_backoff(iterations++); - } while (arch_spin_current(READ_ONCE(lock->lock)) == curr); - - /* - * The TILE architecture doesn't do read speculation; therefore - * a control dependency guarantees a LOAD->{LOAD,STORE} order. - */ - barrier(); -} -EXPORT_SYMBOL(arch_spin_unlock_wait); /* * If the read lock fails due to a writer, we retry periodically diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index 4b2ed5858b2ee0797215279c8d6decadb91298d4..e26376ab5452e2068ce9b3a71ec903ffe444a935 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -20,6 +20,7 @@ config LD_SCRIPT_DYN bool default y depends on !LD_SCRIPT_STATIC + select MODULE_REL_CRCS if MODVERSIONS source "fs/Kconfig.binfmt" diff --git a/arch/um/Makefile b/arch/um/Makefile index 6ca4f66085c145fe07c106d1320c2541166ba8c9..b76fcce397a11c44891658ceab02cedf244d44fa 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -121,7 +121,7 @@ archheaders: archprepare: include/generated/user_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib +LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie) CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ $(call cc-option, -fno-stack-protector,) \ diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig index 5636221b8785b0678e2b471b8de8744a3fe2ad30..8f114e3b0a7a36143f79e9af98553ab09784f0bd 100644 --- a/arch/um/configs/i386_defconfig +++ b/arch/um/configs/i386_defconfig @@ -53,7 +53,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UML_NET=y CONFIG_UML_NET_ETHERTAP=y diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig index 7a67b7ac1a7e83cfdfd396db153c3da4aa0179af..5d0875fc0db25b6f8b0c1e1c457bc54703ebfff7 100644 --- a/arch/um/configs/x86_64_defconfig +++ b/arch/um/configs/x86_64_defconfig @@ -51,7 +51,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UML_NET=y CONFIG_UML_NET_ETHERTAP=y diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index af326fb6510dbf993b2b548537731919330b9e9b..c4d162a94be9d612d6ec834c243b4626a6b15779 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -148,12 +148,7 @@ void mconsole_proc(struct mc_request *req) } do { - loff_t pos = file->f_pos; - mm_segment_t old_fs = get_fs(); - set_fs(KERNEL_DS); - len = vfs_read(file, buf, PAGE_SIZE - 1, &pos); - set_fs(old_fs); - file->f_pos = pos; + len = kernel_read(file, buf, PAGE_SIZE - 1, &file->f_pos); if (len < 0) { mconsole_reply(req, "Read of file failed", 1, 0); goto out_free; diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index f6d1a3f747a9b58b3f33ce0ee25c3bf889985c0b..86942a492454c296bcc5cfc7f5fdd23544a46dc9 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -58,11 +58,6 @@ static inline void release_thread(struct task_struct *task) { } -static inline void mm_copy_segments(struct mm_struct *from_mm, - struct mm_struct *new_mm) -{ -} - #define init_stack (init_thread_union.stack) /* diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 053baff036746f8360a6ff81034a6e3bcc332156..9300f7630d2ad8f0bfa6e3360bd5af5c04e98181 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -11,6 +11,7 @@ #include #include #include +#include struct thread_info { struct task_struct *task; /* main task structure */ @@ -22,6 +23,8 @@ struct thread_info { 0-0xBFFFFFFF for user 0-0xFFFFFFFF for kernel */ struct thread_info *real_thread; /* Points to non-IRQ stack */ + unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore + them out-of-band */ }; #define INIT_THREAD_INFO(tsk) \ diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h index 600a2e9bfee2feea2a6dbc8b91d2a5a872d9d8d3..344d95619d0334659e6f4a9f3a5bff70ae95f67c 100644 --- a/arch/um/include/asm/tlb.h +++ b/arch/um/include/asm/tlb.h @@ -45,7 +45,8 @@ static inline void init_tlb_gather(struct mmu_gather *tlb) } static inline void -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) +arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) { tlb->mm = mm; tlb->start = start; @@ -80,13 +81,19 @@ tlb_flush_mmu(struct mmu_gather *tlb) tlb_flush_mmu_free(tlb); } -/* tlb_finish_mmu +/* arch_tlb_finish_mmu * Called at the end of the shootdown operation to free up any resources * that were required. */ static inline void -tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force) { + if (force) { + tlb->start = start; + tlb->end = end; + tlb->need_flush = 1; + } tlb_flush_mmu(tlb); /* keep the page table cache within bounds */ diff --git a/arch/um/include/asm/unwind.h b/arch/um/include/asm/unwind.h new file mode 100644 index 0000000000000000000000000000000000000000..7ffa5437b761d6f39b0e7a95de44236255bcd8d5 --- /dev/null +++ b/arch/um/include/asm/unwind.h @@ -0,0 +1,8 @@ +#ifndef _ASM_UML_UNWIND_H +#define _ASM_UML_UNWIND_H + +static inline void +unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size) {} + +#endif /* _ASM_UML_UNWIND_H */ diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 574e03fc7ba256d74e074c4762ced1f77d3cc0b1..d8ddaf9790d2bd858db7f4e41f45d43d1a49d0d0 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -278,7 +278,7 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr, extern int is_skas_winch(int pid, int fd, void *data); extern int start_userspace(unsigned long stub_stack); extern int copy_context_skas0(unsigned long stack, int pid); -extern void userspace(struct uml_pt_regs *regs); +extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs); extern int map_stub_pages(int fd, unsigned long code, unsigned long data, unsigned long stack); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c index 1bf61266da8e1e355ef7c1377dcff22f21385ce9..f138a4a0db990fc681bec3554b2790578bff9358 100644 --- a/arch/um/kernel/gmon_syms.c +++ b/arch/um/kernel/gmon_syms.c @@ -7,3 +7,10 @@ extern void __bb_init_func(void *) __attribute__((weak)); EXPORT_SYMBOL(__bb_init_func); + +extern void __gcov_init(void *) __attribute__((weak)); +EXPORT_SYMBOL(__gcov_init); +extern void __gcov_merge_add(void *, unsigned int) __attribute__((weak)); +EXPORT_SYMBOL(__gcov_merge_add); +extern void __gcov_exit(void) __attribute__((weak)); +EXPORT_SYMBOL(__gcov_exit); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2c7f721eccbcb2b45799a380cfddb9327c0d509c..691b83b10649c04e267c763f04776da70b2f6f03 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -131,7 +131,7 @@ void new_thread_handler(void) * callback returns only if the kernel thread execs a process */ n = fn(arg); - userspace(¤t->thread.regs.regs); + userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); } /* Called magically, see new_thread_handler above */ @@ -150,7 +150,7 @@ void fork_handler(void) current->thread.prev_sched = NULL; - userspace(¤t->thread.regs.regs); + userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); } int copy_thread(unsigned long clone_flags, unsigned long sp, diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 0b034ebbda2a1c2dd0125a6d4c2135dd886eb440..7f69d17de3540ca8491270408946a00654493cd2 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -98,7 +98,7 @@ static struct clocksource timer_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init timer_setup(void) +static void __init um_timer_setup(void) { int err; @@ -132,5 +132,5 @@ void read_persistent_clock(struct timespec *ts) void __init time_init(void) { timer_set_signal_handler(); - late_time_init = timer_setup; + late_time_init = um_timer_setup; } diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index c2e6e1dad8763b2547269fc242e12ecf72cd08ab..db24ce0d09a6443fc18e7d1a69acc7971ecd11d9 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -80,7 +80,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, pid = run_helper(tuntap_pre_exec, &data, argv); if (pid < 0) - return -pid; + return pid; close(remote); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 819d68656673c53f14ee38513a73f63f19f1ac64..c94c3bd70ccd797d03a53f7f9b7b5773ff274506 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -88,12 +88,11 @@ void wait_stub_done(int pid) extern unsigned long current_stub_stack(void); -static void get_skas_faultinfo(int pid, struct faultinfo *fi) +static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs) { int err; - unsigned long fpregs[FP_SIZE]; - err = get_fp_registers(pid, fpregs); + err = get_fp_registers(pid, aux_fp_regs); if (err < 0) { printk(UM_KERN_ERR "save_fp_registers returned %d\n", err); @@ -113,7 +112,7 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) */ memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); - err = put_fp_registers(pid, fpregs); + err = put_fp_registers(pid, aux_fp_regs); if (err < 0) { printk(UM_KERN_ERR "put_fp_registers returned %d\n", err); @@ -121,9 +120,9 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) } } -static void handle_segv(int pid, struct uml_pt_regs * regs) +static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs) { - get_skas_faultinfo(pid, ®s->faultinfo); + get_skas_faultinfo(pid, ®s->faultinfo, aux_fp_regs); segv(regs->faultinfo, 0, 1, NULL); } @@ -332,7 +331,7 @@ int start_userspace(unsigned long stub_stack) return err; } -void userspace(struct uml_pt_regs *regs) +void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) { int err, status, op, pid = userspace_pid[0]; /* To prevent races if using_sysemu changes under us.*/ @@ -407,11 +406,11 @@ void userspace(struct uml_pt_regs *regs) case SIGSEGV: if (PTRACE_FULL_FAULTINFO) { get_skas_faultinfo(pid, - ®s->faultinfo); + ®s->faultinfo, aux_fp_regs); (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, regs); } - else handle_segv(pid, regs); + else handle_segv(pid, regs, aux_fp_regs); break; case SIGTRAP + 0x80: handle_trap(pid, regs, local_using_sysemu); diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index b1b6b75c5b173092dc986307780586b54c1d02f2..82bf5f8442ba4ec963f27a2ab2ad310682c87032 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -154,10 +154,10 @@ static int __init nosysemu_cmd_param(char *str, int* add) __uml_setup("nosysemu", nosysemu_cmd_param, "nosysemu\n" -" Turns off syscall emulation patch for ptrace (SYSEMU) on.\n" +" Turns off syscall emulation patch for ptrace (SYSEMU).\n" " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" -" behaviour of ptrace() and helps reducing host context switch rate.\n" -" To make it working, you need a kernel patch for your host, too.\n" +" behaviour of ptrace() and helps reduce host context switch rates.\n" +" To make it work, you need a kernel patch for your host, too.\n" " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n" " information.\n\n"); diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 1053bca1f8aa1592f03c8bff0759d8673b3f3217..9f26840e41b121212db984605317642da3f2d140 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -101,7 +101,7 @@ void pci_puv3_preinit(void) writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); } -static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->bus->number == 0) { #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ @@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pcibios_fixup_bus); +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + static int __init pci_common_init(void) { struct pci_bus *puv3_bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return -ENOMEM; pci_puv3_preinit(); - puv3_bus = pci_scan_bus(0, &pci_puv3_ops, NULL); + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->sysdata = NULL; + bridge->busnr = 0; + bridge->ops = &pci_puv3_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pci_puv3_map_irq; + + /* Scan our single hose. */ + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + puv3_bus = bridge->bus; if (!puv3_bus) panic("PCI: unable to scan bus!"); - pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); - pci_bus_size_bridges(puv3_bus); pci_bus_assign_resources(puv3_bus); pci_bus_add_devices(puv3_bus); diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild index 586b786b3edf9a6930bfdf05c47b4c8e0c57e718..0038a2d10a7a575f1aa24aa6485fd277503d1753 100644 --- a/arch/x86/Kbuild +++ b/arch/x86/Kbuild @@ -8,10 +8,7 @@ obj-$(CONFIG_KVM) += kvm/ obj-$(CONFIG_XEN) += xen/ # Hyper-V paravirtualization support -obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/ - -# lguest paravirtualization support -obj-$(CONFIG_LGUEST_GUEST) += lguest/ +obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/ obj-y += realmode/ obj-y += kernel/ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 781521b7cf9ef6b6766dac9249a3568f257c4fa8..971feac135060d371e130680b54034f9dd39556a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -53,8 +53,9 @@ config X86 select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_KCOV if X86_64 - select ARCH_HAS_MMIO_FLUSH select ARCH_HAS_PMEM_API if X86_64 + # Causing hangs/crashes, see the commit that added this change for details. + select ARCH_HAS_REFCOUNT if BROKEN select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 select ARCH_HAS_SET_MEMORY select ARCH_HAS_SG_CHAIN @@ -73,7 +74,6 @@ config X86 select ARCH_USE_QUEUED_RWLOCKS select ARCH_USE_QUEUED_SPINLOCKS select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH - select ARCH_WANT_FRAME_POINTERS select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_WANTS_THP_SWAP if X86_64 select BUILDTIME_EXTABLE_SORT @@ -100,6 +100,7 @@ config X86 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL + select HARDLOCKUP_CHECK_TIMESTAMP if X86_64 select HAVE_ACPI_APEI if ACPI select HAVE_ACPI_APEI_NMI if ACPI select HAVE_ALIGNED_STRUCT_PAGE if SLUB @@ -157,17 +158,19 @@ config X86 select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_MIXED_BREAKPOINTS_REGS + select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI select HAVE_OPROFILE select HAVE_OPTPROBES select HAVE_PCSPKR_PLATFORM select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS_NMI - select HAVE_HARDLOCKUP_DETECTOR_PERF if HAVE_PERF_EVENTS_NMI + select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_RCU_TABLE_FREE select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER && STACK_VALIDATION + select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER_UNWINDER && STACK_VALIDATION select HAVE_STACK_VALIDATION if X86_64 select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNSTABLE_SCHED_CLOCK @@ -326,6 +329,7 @@ config FIX_EARLYCON_MEM config PGTABLE_LEVELS int + default 5 if X86_5LEVEL default 4 if X86_64 default 3 if X86_PAE default 2 @@ -424,16 +428,16 @@ config GOLDFISH def_bool y depends on X86_GOLDFISH -config INTEL_RDT_A - bool "Intel Resource Director Technology Allocation support" +config INTEL_RDT + bool "Intel Resource Director Technology support" default n depends on X86 && CPU_SUP_INTEL select KERNFS help - Select to enable resource allocation which is a sub-feature of - Intel Resource Director Technology(RDT). More information about - RDT can be found in the Intel x86 Architecture Software - Developer Manual. + Select to enable resource allocation and monitoring which are + sub-features of Intel Resource Director Technology(RDT). More + information about RDT can be found in the Intel x86 + Architecture Software Developer Manual. Say N if unsure. @@ -777,8 +781,6 @@ config KVM_DEBUG_FS Statistics are displayed in debugfs filesystem. Enabling this option may incur significant overhead. -source "arch/x86/lguest/Kconfig" - config PARAVIRT_TIME_ACCOUNTING bool "Paravirtual steal time accounting" depends on PARAVIRT @@ -1398,6 +1400,24 @@ config X86_PAE has the cost of more pagetable lookup overhead, and also consumes more pagetable space per process. +config X86_5LEVEL + bool "Enable 5-level page tables support" + depends on X86_64 + ---help--- + 5-level paging enables access to larger address space: + upto 128 PiB of virtual address space and 4 PiB of + physical address space. + + It will be supported by future Intel CPUs. + + Note: a kernel with this option enabled can only be booted + on machines that support the feature. + + See Documentation/x86/x86_64/5level-paging.txt for more + information. + + Say N if unsure. + config ARCH_PHYS_ADDR_T_64BIT def_bool y depends on X86_64 || X86_PAE @@ -1415,6 +1435,35 @@ config X86_DIRECT_GBPAGES supports them), so don't confuse the user by printing that we have them enabled. +config ARCH_HAS_MEM_ENCRYPT + def_bool y + +config AMD_MEM_ENCRYPT + bool "AMD Secure Memory Encryption (SME) support" + depends on X86_64 && CPU_SUP_AMD + ---help--- + Say yes to enable support for the encryption of system memory. + This requires an AMD processor that supports Secure Memory + Encryption (SME). + +config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT + bool "Activate AMD Secure Memory Encryption (SME) by default" + default y + depends on AMD_MEM_ENCRYPT + ---help--- + Say yes to have system memory encrypted by default if running on + an AMD processor that supports Secure Memory Encryption (SME). + + If set to Y, then the encryption of system memory can be + deactivated with the mem_encrypt=off command line option. + + If set to N, then the encryption of system memory can be + activated with the mem_encrypt=on command line option. + +config ARCH_USE_MEMREMAP_PROT + def_bool y + depends on AMD_MEM_ENCRYPT + # Common NUMA Features config NUMA bool "Numa Memory Allocation and Scheduler Support" @@ -1756,7 +1805,9 @@ config X86_SMAP config X86_INTEL_MPX prompt "Intel MPX (Memory Protection Extensions)" def_bool n - depends on CPU_SUP_INTEL + # Note: only available in 64-bit mode due to VMA flags shortage + depends on CPU_SUP_INTEL && X86_64 + select ARCH_USES_HIGH_VMA_FLAGS ---help--- MPX provides hardware features that can be used in conjunction with compiler-instrumented code to check @@ -2271,6 +2322,10 @@ source "kernel/livepatch/Kconfig" endmenu +config ARCH_HAS_ADD_PAGES + def_bool y + depends on X86_64 && ARCH_ENABLE_MEMORY_HOTPLUG + config ARCH_ENABLE_MEMORY_HOTPLUG def_bool y depends on X86_64 || (X86_32 && HIGHMEM) @@ -2291,6 +2346,10 @@ config ARCH_ENABLE_HUGEPAGE_MIGRATION def_bool y depends on X86_64 && HUGETLB_PAGE && MIGRATION +config ARCH_ENABLE_THP_MIGRATION + def_bool y + depends on X86_64 && TRANSPARENT_HUGEPAGE + menu "Power management and ACPI options" config ARCH_HIBERNATION_HEADER diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index cd20ca0b404341d12e3a619fefacf7f3652a8ea2..71a48a30fc849059a418866a8ad4d10d7a922bf3 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -305,8 +305,6 @@ config DEBUG_ENTRY Some of these sanity checks may slow down kernel entries and exits or otherwise impact performance. - This is currently used to help test NMI code. - If unsure, say N. config DEBUG_NMI_SELFTEST @@ -358,4 +356,61 @@ config PUNIT_ATOM_DEBUG The current power state can be read from /sys/kernel/debug/punit_atom/dev_power_state +choice + prompt "Choose kernel unwinder" + default FRAME_POINTER_UNWINDER + ---help--- + This determines which method will be used for unwinding kernel stack + traces for panics, oopses, bugs, warnings, perf, /proc//stack, + livepatch, lockdep, and more. + +config FRAME_POINTER_UNWINDER + bool "Frame pointer unwinder" + select FRAME_POINTER + ---help--- + This option enables the frame pointer unwinder for unwinding kernel + stack traces. + + The unwinder itself is fast and it uses less RAM than the ORC + unwinder, but the kernel text size will grow by ~3% and the kernel's + overall performance will degrade by roughly 5-10%. + + This option is recommended if you want to use the livepatch + consistency model, as this is currently the only way to get a + reliable stack trace (CONFIG_HAVE_RELIABLE_STACKTRACE). + +config ORC_UNWINDER + bool "ORC unwinder" + depends on X86_64 + select STACK_VALIDATION + ---help--- + This option enables the ORC (Oops Rewind Capability) unwinder for + unwinding kernel stack traces. It uses a custom data format which is + a simplified version of the DWARF Call Frame Information standard. + + This unwinder is more accurate across interrupt entry frames than the + frame pointer unwinder. It also enables a 5-10% performance + improvement across the entire kernel compared to frame pointers. + + Enabling this option will increase the kernel's runtime memory usage + by roughly 2-4MB, depending on your kernel config. + +config GUESS_UNWINDER + bool "Guess unwinder" + depends on EXPERT + ---help--- + This option enables the "guess" unwinder for unwinding kernel stack + traces. It scans the stack and reports every kernel text address it + finds. Some of the addresses it reports may be incorrect. + + While this option often produces false positives, it can still be + useful in many cases. Unlike the other unwinders, it has no runtime + overhead. + +endchoice + +config FRAME_POINTER + depends on !ORC_UNWINDER && !GUESS_UNWINDER + bool + endmenu diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 1e902f926be3fd2d788ce4d26154af677c83c330..6276572259c888fa392543cee4ebd001684ca7c7 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -14,9 +14,11 @@ endif # For gcc stack alignment is specified with -mpreferred-stack-boundary, # clang has the option -mstack-alignment for that purpose. ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align_opt := -mpreferred-stack-boundary -else ifneq ($(call cc-option, -mstack-alignment=4),) - cc_stack_align_opt := -mstack-alignment + cc_stack_align4 := -mpreferred-stack-boundary=2 + cc_stack_align8 := -mpreferred-stack-boundary=3 +else ifneq ($(call cc-option, -mstack-alignment=16),) + cc_stack_align4 := -mstack-alignment=4 + cc_stack_align8 := -mstack-alignment=8 endif # How to compile the 16-bit code. Note we always compile for -march=i386; @@ -36,7 +38,7 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -D__KERNEL__ \ REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector) -REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align_opt)=2) +REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) export REALMODE_CFLAGS # BITS is used as extension for files which are available in a 32 bit @@ -76,7 +78,7 @@ ifeq ($(CONFIG_X86_32),y) # Align the stack to the register width instead of using the default # alignment of 16 bytes. This reduces stack usage and the number of # alignment instructions. - KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align_opt)=2) + KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align4)) # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use # a lot more stack due to the lack of sharing of stacklots: @@ -115,7 +117,7 @@ else # default alignment which keep the stack *mis*aligned. # Furthermore an alignment to the register width reduces stack usage # and the number of alignment instructions. - KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align_opt)=3) + KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align8)) # Use -mskip-rax-setup if supported. KBUILD_CFLAGS += $(call cc-option,-mskip-rax-setup) @@ -232,9 +234,6 @@ KBUILD_CFLAGS += -Wno-sign-compare # KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -KBUILD_CFLAGS += $(mflags-y) -KBUILD_AFLAGS += $(mflags-y) - archscripts: scripts_basic $(Q)$(MAKE) $(build)=arch/x86/tools relocs diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c3e869eaef0c625b98f5bcafabd1a2aba02ab8c7..e56dbc67e8378e891fa8aa64192d0875237f4aba 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -767,7 +767,7 @@ static efi_status_t setup_e820(struct boot_params *params, m |= (u64)efi->efi_memmap_hi << 32; #endif - d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size)); + d = efi_early_memdesc_ptr(m, efi->efi_memdesc_size, i); switch (d->type) { case EFI_RESERVED_TYPE: case EFI_RUNTIME_SERVICES_CODE: @@ -997,6 +997,9 @@ struct boot_params *efi_main(struct efi_config *c, if (boot_params->secure_boot == efi_secureboot_mode_unset) boot_params->secure_boot = efi_get_secureboot(sys_table); + /* Ask the firmware to clear memory on unclean shutdown */ + efi_enable_reset_attack_mitigation(sys_table); + setup_graphics(boot_params); setup_efi_pci(boot_params); @@ -1058,7 +1061,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; - desc->limit = 0xf; + desc->limit1 = 0xf; desc->avl = 0; desc->l = 0; desc->d = SEG_OP_SIZE_32BIT; @@ -1078,7 +1081,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; - desc->limit = 0xf; + desc->limit1 = 0xf; desc->avl = 0; if (IS_ENABLED(CONFIG_X86_64)) { desc->l = 1; @@ -1099,7 +1102,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; - desc->limit = 0xf; + desc->limit1 = 0xf; desc->avl = 0; desc->l = 0; desc->d = SEG_OP_SIZE_32BIT; @@ -1116,7 +1119,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = 0; desc->dpl = 0; desc->p = 1; - desc->limit = 0x0; + desc->limit1 = 0x0; desc->avl = 0; desc->l = 0; desc->d = 0; diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index d85b9625e836d5429e4eff13104e0b01f338f4d0..11c68cf53d4e8223dcea00a327cac11b6c2dfa9e 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -61,71 +61,6 @@ __HEAD ENTRY(startup_32) -#ifdef CONFIG_EFI_STUB - jmp preferred_addr - - /* - * We don't need the return address, so set up the stack so - * efi_main() can find its arguments. - */ -ENTRY(efi_pe_entry) - add $0x4, %esp - - call 1f -1: popl %esi - subl $1b, %esi - - popl %ecx - movl %ecx, efi32_config(%esi) /* Handle */ - popl %ecx - movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */ - - /* Relocate efi_config->call() */ - leal efi32_config(%esi), %eax - add %esi, 40(%eax) - pushl %eax - - call make_boot_params - cmpl $0, %eax - je fail - movl %esi, BP_code32_start(%eax) - popl %ecx - pushl %eax - pushl %ecx - jmp 2f /* Skip efi_config initialization */ - -ENTRY(efi32_stub_entry) - add $0x4, %esp - popl %ecx - popl %edx - - call 1f -1: popl %esi - subl $1b, %esi - - movl %ecx, efi32_config(%esi) /* Handle */ - movl %edx, efi32_config+8(%esi) /* EFI System table pointer */ - - /* Relocate efi_config->call() */ - leal efi32_config(%esi), %eax - add %esi, 40(%eax) - pushl %eax -2: - call efi_main - cmpl $0, %eax - movl %eax, %esi - jne 2f -fail: - /* EFI init failed, so hang. */ - hlt - jmp fail -2: - movl BP_code32_start(%esi), %eax - leal preferred_addr(%eax), %eax - jmp *%eax - -preferred_addr: -#endif cld /* * Test KEEP_SEGMENTS flag to see if the bootloader is asking @@ -208,6 +143,70 @@ preferred_addr: jmp *%eax ENDPROC(startup_32) +#ifdef CONFIG_EFI_STUB +/* + * We don't need the return address, so set up the stack so efi_main() can find + * its arguments. + */ +ENTRY(efi_pe_entry) + add $0x4, %esp + + call 1f +1: popl %esi + subl $1b, %esi + + popl %ecx + movl %ecx, efi32_config(%esi) /* Handle */ + popl %ecx + movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */ + + /* Relocate efi_config->call() */ + leal efi32_config(%esi), %eax + add %esi, 40(%eax) + pushl %eax + + call make_boot_params + cmpl $0, %eax + je fail + movl %esi, BP_code32_start(%eax) + popl %ecx + pushl %eax + pushl %ecx + jmp 2f /* Skip efi_config initialization */ +ENDPROC(efi_pe_entry) + +ENTRY(efi32_stub_entry) + add $0x4, %esp + popl %ecx + popl %edx + + call 1f +1: popl %esi + subl $1b, %esi + + movl %ecx, efi32_config(%esi) /* Handle */ + movl %edx, efi32_config+8(%esi) /* EFI System table pointer */ + + /* Relocate efi_config->call() */ + leal efi32_config(%esi), %eax + add %esi, 40(%eax) + pushl %eax +2: + call efi_main + cmpl $0, %eax + movl %eax, %esi + jne 2f +fail: + /* EFI init failed, so hang. */ + hlt + jmp fail +2: + movl BP_code32_start(%esi), %eax + leal startup_32(%eax), %eax + jmp *%eax +ENDPROC(efi32_stub_entry) +#endif + .text relocated: diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index fbf4c32d0b62d9181a7784a20086b805baaa78af..b4a5d284391c278edf539c43ac665521ff3ed70c 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -243,65 +243,6 @@ ENTRY(startup_64) * that maps our entire kernel(text+data+bss+brk), zero page * and command line. */ -#ifdef CONFIG_EFI_STUB - /* - * The entry point for the PE/COFF executable is efi_pe_entry, so - * only legacy boot loaders will execute this jmp. - */ - jmp preferred_addr - -ENTRY(efi_pe_entry) - movq %rcx, efi64_config(%rip) /* Handle */ - movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ - - leaq efi64_config(%rip), %rax - movq %rax, efi_config(%rip) - - call 1f -1: popq %rbp - subq $1b, %rbp - - /* - * Relocate efi_config->call(). - */ - addq %rbp, efi64_config+40(%rip) - - movq %rax, %rdi - call make_boot_params - cmpq $0,%rax - je fail - mov %rax, %rsi - leaq startup_32(%rip), %rax - movl %eax, BP_code32_start(%rsi) - jmp 2f /* Skip the relocation */ - -handover_entry: - call 1f -1: popq %rbp - subq $1b, %rbp - - /* - * Relocate efi_config->call(). - */ - movq efi_config(%rip), %rax - addq %rbp, 40(%rax) -2: - movq efi_config(%rip), %rdi - call efi_main - movq %rax,%rsi - cmpq $0,%rax - jne 2f -fail: - /* EFI init failed, so hang. */ - hlt - jmp fail -2: - movl BP_code32_start(%esi), %eax - leaq preferred_addr(%rax), %rax - jmp *%rax - -preferred_addr: -#endif /* Setup data segments. */ xorl %eax, %eax @@ -413,6 +354,59 @@ lvl5: jmp *%rax #ifdef CONFIG_EFI_STUB + +/* The entry point for the PE/COFF executable is efi_pe_entry. */ +ENTRY(efi_pe_entry) + movq %rcx, efi64_config(%rip) /* Handle */ + movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + addq %rbp, efi64_config+40(%rip) + + movq %rax, %rdi + call make_boot_params + cmpq $0,%rax + je fail + mov %rax, %rsi + leaq startup_32(%rip), %rax + movl %eax, BP_code32_start(%rsi) + jmp 2f /* Skip the relocation */ + +handover_entry: + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + movq efi_config(%rip), %rax + addq %rbp, 40(%rax) +2: + movq efi_config(%rip), %rdi + call efi_main + movq %rax,%rsi + cmpq $0,%rax + jne 2f +fail: + /* EFI init failed, so hang. */ + hlt + jmp fail +2: + movl BP_code32_start(%esi), %eax + leaq startup_64(%rax), %rax + jmp *%rax +ENDPROC(efi_pe_entry) + .org 0x390 ENTRY(efi64_stub_entry) movq %rdi, efi64_config(%rip) /* Handle */ diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 91f27ab970ef74347c1915e7ff6ac5f8a8803b8d..17818ba6906f84f6d4a90d59893875fe7f314731 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -37,7 +37,9 @@ #include #include #include +#include #include +#include /* Macros used by the included decompressor code below. */ #define STATIC @@ -479,35 +481,31 @@ static unsigned long slots_fetch_random(void) return 0; } -static void process_e820_entry(struct boot_e820_entry *entry, +static void process_mem_region(struct mem_vector *entry, unsigned long minimum, unsigned long image_size) { struct mem_vector region, overlap; struct slot_area slot_area; unsigned long start_orig, end; - struct boot_e820_entry cur_entry; - - /* Skip non-RAM entries. */ - if (entry->type != E820_TYPE_RAM) - return; + struct mem_vector cur_entry; /* On 32-bit, ignore entries entirely above our maximum. */ - if (IS_ENABLED(CONFIG_X86_32) && entry->addr >= KERNEL_IMAGE_SIZE) + if (IS_ENABLED(CONFIG_X86_32) && entry->start >= KERNEL_IMAGE_SIZE) return; /* Ignore entries entirely below our minimum. */ - if (entry->addr + entry->size < minimum) + if (entry->start + entry->size < minimum) return; /* Ignore entries above memory limit */ - end = min(entry->size + entry->addr, mem_limit); - if (entry->addr >= end) + end = min(entry->size + entry->start, mem_limit); + if (entry->start >= end) return; - cur_entry.addr = entry->addr; - cur_entry.size = end - entry->addr; + cur_entry.start = entry->start; + cur_entry.size = end - entry->start; - region.start = cur_entry.addr; + region.start = cur_entry.start; region.size = cur_entry.size; /* Give up if slot area array is full. */ @@ -521,8 +519,8 @@ static void process_e820_entry(struct boot_e820_entry *entry, /* Potentially raise address to meet alignment needs. */ region.start = ALIGN(region.start, CONFIG_PHYSICAL_ALIGN); - /* Did we raise the address above this e820 region? */ - if (region.start > cur_entry.addr + cur_entry.size) + /* Did we raise the address above the passed in memory entry? */ + if (region.start > cur_entry.start + cur_entry.size) return; /* Reduce size by any delta from the original address. */ @@ -562,31 +560,126 @@ static void process_e820_entry(struct boot_e820_entry *entry, } } -static unsigned long find_random_phys_addr(unsigned long minimum, - unsigned long image_size) +#ifdef CONFIG_EFI +/* + * Returns true if mirror region found (and must have been processed + * for slots adding) + */ +static bool +process_efi_entries(unsigned long minimum, unsigned long image_size) { + struct efi_info *e = &boot_params->efi_info; + bool efi_mirror_found = false; + struct mem_vector region; + efi_memory_desc_t *md; + unsigned long pmap; + char *signature; + u32 nr_desc; int i; - unsigned long addr; - /* Check if we had too many memmaps. */ - if (memmap_too_large) { - debug_putstr("Aborted e820 scan (more than 4 memmap= args)!\n"); - return 0; + signature = (char *)&e->efi_loader_signature; + if (strncmp(signature, EFI32_LOADER_SIGNATURE, 4) && + strncmp(signature, EFI64_LOADER_SIGNATURE, 4)) + return false; + +#ifdef CONFIG_X86_32 + /* Can't handle data above 4GB at this time */ + if (e->efi_memmap_hi) { + warn("EFI memmap is above 4GB, can't be handled now on x86_32. EFI should be disabled.\n"); + return false; } + pmap = e->efi_memmap; +#else + pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); +#endif - /* Make sure minimum is aligned. */ - minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); + nr_desc = e->efi_memmap_size / e->efi_memdesc_size; + for (i = 0; i < nr_desc; i++) { + md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); + if (md->attribute & EFI_MEMORY_MORE_RELIABLE) { + efi_mirror_found = true; + break; + } + } + + for (i = 0; i < nr_desc; i++) { + md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); + + /* + * Here we are more conservative in picking free memory than + * the EFI spec allows: + * + * According to the spec, EFI_BOOT_SERVICES_{CODE|DATA} are also + * free memory and thus available to place the kernel image into, + * but in practice there's firmware where using that memory leads + * to crashes. + * + * Only EFI_CONVENTIONAL_MEMORY is guaranteed to be free. + */ + if (md->type != EFI_CONVENTIONAL_MEMORY) + continue; + + if (efi_mirror_found && + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) + continue; + + region.start = md->phys_addr; + region.size = md->num_pages << EFI_PAGE_SHIFT; + process_mem_region(®ion, minimum, image_size); + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted EFI scan (slot_areas full)!\n"); + break; + } + } + return true; +} +#else +static inline bool +process_efi_entries(unsigned long minimum, unsigned long image_size) +{ + return false; +} +#endif + +static void process_e820_entries(unsigned long minimum, + unsigned long image_size) +{ + int i; + struct mem_vector region; + struct boot_e820_entry *entry; /* Verify potential e820 positions, appending to slots list. */ for (i = 0; i < boot_params->e820_entries; i++) { - process_e820_entry(&boot_params->e820_table[i], minimum, - image_size); + entry = &boot_params->e820_table[i]; + /* Skip non-RAM entries. */ + if (entry->type != E820_TYPE_RAM) + continue; + region.start = entry->addr; + region.size = entry->size; + process_mem_region(®ion, minimum, image_size); if (slot_area_index == MAX_SLOT_AREA) { debug_putstr("Aborted e820 scan (slot_areas full)!\n"); break; } } +} + +static unsigned long find_random_phys_addr(unsigned long minimum, + unsigned long image_size) +{ + /* Check if we had too many memmaps. */ + if (memmap_too_large) { + debug_putstr("Aborted memory entries scan (more than 4 memmap= args)!\n"); + return 0; + } + + /* Make sure minimum is aligned. */ + minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); + + if (process_efi_entries(minimum, image_size)) + return slots_fetch_random(); + process_e820_entries(minimum, image_size); return slots_fetch_random(); } @@ -645,7 +738,7 @@ void choose_random_location(unsigned long input, */ min_addr = min(*output, 512UL << 20); - /* Walk e820 and find a random address. */ + /* Walk available memory entries to find a random address. */ random_addr = find_random_phys_addr(min_addr, output_size); if (!random_addr) { warn("Physical KASLR disabled: no suitable memory region!"); diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index a0838ab929f2276de8ed08e2e0430f4e3e7943f8..c14217cd0155f09ab7f00e018ec25fe3b4c4cf5e 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -116,8 +116,7 @@ void __putstr(const char *s) } } - if (boot_params->screen_info.orig_video_mode == 0 && - lines == 0 && cols == 0) + if (lines == 0 || cols == 0) return; x = boot_params->screen_info.orig_x; diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c index 28029be47fbb839f248826b517a9e295f4389395..f1aa43854bed423e7bfccaa84ff66ea91996b731 100644 --- a/arch/x86/boot/compressed/pagetable.c +++ b/arch/x86/boot/compressed/pagetable.c @@ -15,6 +15,13 @@ #define __pa(x) ((unsigned long)(x)) #define __va(x) ((void *)((unsigned long)(x))) +/* + * The pgtable.h and mm/ident_map.c includes make use of the SME related + * information which is not used in the compressed image support. Un-define + * the SME support to avoid any compile and link errors. + */ +#undef CONFIG_AMD_MEM_ENCRYPT + #include "misc.h" /* These actually do the work of building the kernel identity maps. */ diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 2ed8f0c25def4b01dd50107425c5b6e54d60f2eb..1bb08ecffd24a61e1d9bccf2094e70996f280bce 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -520,8 +520,14 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr # the description in lib/decompressor_xxx.c for specific information. # # extra_bytes = (uncompressed_size >> 12) + 65536 + 128 +# +# LZ4 is even worse: data that cannot be further compressed grows by 0.4%, +# or one byte per 256 bytes. OTOH, we can safely get rid of the +128 as +# the size-dependent part now grows so fast. +# +# extra_bytes = (uncompressed_size >> 8) + 65536 -#define ZO_z_extra_bytes ((ZO_z_output_len >> 12) + 65536 + 128) +#define ZO_z_extra_bytes ((ZO_z_output_len >> 8) + 65536) #if ZO_z_output_len > ZO_z_input_len # define ZO_z_extract_offset (ZO_z_output_len + ZO_z_extra_bytes - \ ZO_z_input_len) diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config index 4b429df40d7a2fb9ee9fce2eb5315b592d1200e9..550cd5012b7354efd1d1eb3eaeebffd8cd7e30eb 100644 --- a/arch/x86/configs/tiny.config +++ b/arch/x86/configs/tiny.config @@ -1,3 +1,5 @@ CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set +CONFIG_GUESS_UNWINDER=y +# CONFIG_FRAME_POINTER_UNWINDER is not set diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 4a55cdcdc0082790bcf6457ab43e1a84caea7388..5c15d6b573299e75c2eec54d98bbde9f48e67637 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -475,8 +475,8 @@ static void ctr_crypt_final(struct crypto_aes_ctx *ctx, unsigned int nbytes = walk->nbytes; aesni_enc(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); + crypto_inc(ctrblk, AES_BLOCK_SIZE); } diff --git a/arch/x86/crypto/blowfish-x86_64-asm_64.S b/arch/x86/crypto/blowfish-x86_64-asm_64.S index 246c67006ed06ad84516b3a56ceac06e05734a1c..8c1fcb6bad21f91604f0b61357db834f560b7fdb 100644 --- a/arch/x86/crypto/blowfish-x86_64-asm_64.S +++ b/arch/x86/crypto/blowfish-x86_64-asm_64.S @@ -33,7 +33,7 @@ #define s3 ((16 + 2 + (3 * 256)) * 4) /* register macros */ -#define CTX %rdi +#define CTX %r12 #define RIO %rsi #define RX0 %rax @@ -56,12 +56,12 @@ #define RX2bh %ch #define RX3bh %dh -#define RT0 %rbp +#define RT0 %rdi #define RT1 %rsi #define RT2 %r8 #define RT3 %r9 -#define RT0d %ebp +#define RT0d %edi #define RT1d %esi #define RT2d %r8d #define RT3d %r9d @@ -120,13 +120,14 @@ ENTRY(__blowfish_enc_blk) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src * %rcx: bool, if true: xor output */ - movq %rbp, %r11; + movq %r12, %r11; + movq %rdi, CTX; movq %rsi, %r10; movq %rdx, RIO; @@ -142,7 +143,7 @@ ENTRY(__blowfish_enc_blk) round_enc(14); add_roundkey_enc(16); - movq %r11, %rbp; + movq %r11, %r12; movq %r10, RIO; test %cl, %cl; @@ -157,12 +158,13 @@ ENDPROC(__blowfish_enc_blk) ENTRY(blowfish_dec_blk) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ - movq %rbp, %r11; + movq %r12, %r11; + movq %rdi, CTX; movq %rsi, %r10; movq %rdx, RIO; @@ -181,7 +183,7 @@ ENTRY(blowfish_dec_blk) movq %r10, RIO; write_block(); - movq %r11, %rbp; + movq %r11, %r12; ret; ENDPROC(blowfish_dec_blk) @@ -298,20 +300,21 @@ ENDPROC(blowfish_dec_blk) ENTRY(__blowfish_enc_blk_4way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src * %rcx: bool, if true: xor output */ - pushq %rbp; + pushq %r12; pushq %rbx; pushq %rcx; - preload_roundkey_enc(0); - + movq %rdi, CTX movq %rsi, %r11; movq %rdx, RIO; + preload_roundkey_enc(0); + read_block4(); round_enc4(0); @@ -324,39 +327,40 @@ ENTRY(__blowfish_enc_blk_4way) round_enc4(14); add_preloaded_roundkey4(); - popq %rbp; + popq %r12; movq %r11, RIO; - test %bpl, %bpl; + test %r12b, %r12b; jnz .L__enc_xor4; write_block4(); popq %rbx; - popq %rbp; + popq %r12; ret; .L__enc_xor4: xor_block4(); popq %rbx; - popq %rbp; + popq %r12; ret; ENDPROC(__blowfish_enc_blk_4way) ENTRY(blowfish_dec_blk_4way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ - pushq %rbp; + pushq %r12; pushq %rbx; - preload_roundkey_dec(17); - movq %rsi, %r11; + movq %rdi, CTX; + movq %rsi, %r11 movq %rdx, RIO; + preload_roundkey_dec(17); read_block4(); round_dec4(17); @@ -373,7 +377,7 @@ ENTRY(blowfish_dec_blk_4way) write_block4(); popq %rbx; - popq %rbp; + popq %r12; ret; ENDPROC(blowfish_dec_blk_4way) diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c index 17c05531dfd1752234eb9b6835f848b12ed07817..f9eca34301e20fccec4b8daa5a0cc98710fa3094 100644 --- a/arch/x86/crypto/blowfish_glue.c +++ b/arch/x86/crypto/blowfish_glue.c @@ -271,8 +271,7 @@ static void ctr_crypt_final(struct bf_ctx *ctx, struct blkcipher_walk *walk) unsigned int nbytes = walk->nbytes; blowfish_enc_blk(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); crypto_inc(ctrblk, BF_BLOCK_SIZE); } diff --git a/arch/x86/crypto/camellia-x86_64-asm_64.S b/arch/x86/crypto/camellia-x86_64-asm_64.S index 310319c601ede2884b2d031ca4603593f304e4b3..95ba6956a7f6a1fc0b01e2938f94cee0ff6a2ac3 100644 --- a/arch/x86/crypto/camellia-x86_64-asm_64.S +++ b/arch/x86/crypto/camellia-x86_64-asm_64.S @@ -75,17 +75,17 @@ #define RCD1bh %dh #define RT0 %rsi -#define RT1 %rbp +#define RT1 %r12 #define RT2 %r8 #define RT0d %esi -#define RT1d %ebp +#define RT1d %r12d #define RT2d %r8d #define RT2bl %r8b #define RXOR %r9 -#define RRBP %r10 +#define RR12 %r10 #define RDST %r11 #define RXORd %r9d @@ -197,7 +197,7 @@ ENTRY(__camellia_enc_blk) * %rdx: src * %rcx: bool xor */ - movq %rbp, RRBP; + movq %r12, RR12; movq %rcx, RXOR; movq %rsi, RDST; @@ -227,13 +227,13 @@ ENTRY(__camellia_enc_blk) enc_outunpack(mov, RT1); - movq RRBP, %rbp; + movq RR12, %r12; ret; .L__enc_xor: enc_outunpack(xor, RT1); - movq RRBP, %rbp; + movq RR12, %r12; ret; ENDPROC(__camellia_enc_blk) @@ -248,7 +248,7 @@ ENTRY(camellia_dec_blk) movl $24, RXORd; cmovel RXORd, RT2d; /* max */ - movq %rbp, RRBP; + movq %r12, RR12; movq %rsi, RDST; movq %rdx, RIO; @@ -271,7 +271,7 @@ ENTRY(camellia_dec_blk) dec_outunpack(); - movq RRBP, %rbp; + movq RR12, %r12; ret; ENDPROC(camellia_dec_blk) @@ -433,7 +433,7 @@ ENTRY(__camellia_enc_blk_2way) */ pushq %rbx; - movq %rbp, RRBP; + movq %r12, RR12; movq %rcx, RXOR; movq %rsi, RDST; movq %rdx, RIO; @@ -461,14 +461,14 @@ ENTRY(__camellia_enc_blk_2way) enc_outunpack2(mov, RT2); - movq RRBP, %rbp; + movq RR12, %r12; popq %rbx; ret; .L__enc2_xor: enc_outunpack2(xor, RT2); - movq RRBP, %rbp; + movq RR12, %r12; popq %rbx; ret; ENDPROC(__camellia_enc_blk_2way) @@ -485,7 +485,7 @@ ENTRY(camellia_dec_blk_2way) cmovel RXORd, RT2d; /* max */ movq %rbx, RXOR; - movq %rbp, RRBP; + movq %r12, RR12; movq %rsi, RDST; movq %rdx, RIO; @@ -508,7 +508,7 @@ ENTRY(camellia_dec_blk_2way) dec_outunpack2(); - movq RRBP, %rbp; + movq RR12, %r12; movq RXOR, %rbx; ret; ENDPROC(camellia_dec_blk_2way) diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S index b4a8806234ea1c5f61f46898900a84035af72763..86107c961bb4627f08f6c7eac252589218c6c7e3 100644 --- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S @@ -47,7 +47,7 @@ /********************************************************************** 16-way AVX cast5 **********************************************************************/ -#define CTX %rdi +#define CTX %r15 #define RL1 %xmm0 #define RR1 %xmm1 @@ -70,8 +70,8 @@ #define RTMP %xmm15 -#define RID1 %rbp -#define RID1d %ebp +#define RID1 %rdi +#define RID1d %edi #define RID2 %rsi #define RID2d %esi @@ -226,7 +226,7 @@ .align 16 __cast5_enc_blk16: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RL1: blocks 1 and 2 * RR1: blocks 3 and 4 * RL2: blocks 5 and 6 @@ -246,9 +246,11 @@ __cast5_enc_blk16: * RR4: encrypted blocks 15 and 16 */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -283,7 +285,7 @@ __cast5_enc_blk16: .L__skip_enc: popq %rbx; - popq %rbp; + popq %r15; vmovdqa .Lbswap_mask, RKM; @@ -298,7 +300,7 @@ ENDPROC(__cast5_enc_blk16) .align 16 __cast5_dec_blk16: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RL1: encrypted blocks 1 and 2 * RR1: encrypted blocks 3 and 4 * RL2: encrypted blocks 5 and 6 @@ -318,9 +320,11 @@ __cast5_dec_blk16: * RR4: decrypted blocks 15 and 16 */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -356,7 +360,7 @@ __cast5_dec_blk16: vmovdqa .Lbswap_mask, RKM; popq %rbx; - popq %rbp; + popq %r15; outunpack_blocks(RR1, RL1, RTMP, RX, RKM); outunpack_blocks(RR2, RL2, RTMP, RX, RKM); @@ -372,12 +376,14 @@ ENDPROC(__cast5_dec_blk16) ENTRY(cast5_ecb_enc_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; vmovdqu (0*4*4)(%rdx), RL1; @@ -400,18 +406,22 @@ ENTRY(cast5_ecb_enc_16way) vmovdqu RR4, (6*4*4)(%r11); vmovdqu RL4, (7*4*4)(%r11); + popq %r15; FRAME_END ret; ENDPROC(cast5_ecb_enc_16way) ENTRY(cast5_ecb_dec_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + + movq %rdi, CTX; movq %rsi, %r11; vmovdqu (0*4*4)(%rdx), RL1; @@ -434,20 +444,22 @@ ENTRY(cast5_ecb_dec_16way) vmovdqu RR4, (6*4*4)(%r11); vmovdqu RL4, (7*4*4)(%r11); + popq %r15; FRAME_END ret; ENDPROC(cast5_ecb_dec_16way) ENTRY(cast5_cbc_dec_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN - pushq %r12; + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -483,23 +495,24 @@ ENTRY(cast5_cbc_dec_16way) vmovdqu RR4, (6*16)(%r11); vmovdqu RL4, (7*16)(%r11); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast5_cbc_dec_16way) ENTRY(cast5_ctr_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src * %rcx: iv (big endian, 64bit) */ FRAME_BEGIN - pushq %r12; + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -558,8 +571,8 @@ ENTRY(cast5_ctr_16way) vmovdqu RR4, (6*16)(%r11); vmovdqu RL4, (7*16)(%r11); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast5_ctr_16way) diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c index 8648158f39166f1cf1603fc7f139af629e163bde..dbea6020ffe7d462bd93bf703ccecbe1f817d3f4 100644 --- a/arch/x86/crypto/cast5_avx_glue.c +++ b/arch/x86/crypto/cast5_avx_glue.c @@ -256,8 +256,7 @@ static void ctr_crypt_final(struct blkcipher_desc *desc, unsigned int nbytes = walk->nbytes; __cast5_encrypt(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); crypto_inc(ctrblk, CAST5_BLOCK_SIZE); } diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S index 952d3156a93312ff8c5a5c2c193132a89f7413da..7f30b6f0d72c15f402a69d621ecde1c283780266 100644 --- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S @@ -47,7 +47,7 @@ /********************************************************************** 8-way AVX cast6 **********************************************************************/ -#define CTX %rdi +#define CTX %r15 #define RA1 %xmm0 #define RB1 %xmm1 @@ -70,8 +70,8 @@ #define RTMP %xmm15 -#define RID1 %rbp -#define RID1d %ebp +#define RID1 %rdi +#define RID1d %edi #define RID2 %rsi #define RID2d %esi @@ -264,15 +264,17 @@ .align 8 __cast6_enc_blk8: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks * output: * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -297,7 +299,7 @@ __cast6_enc_blk8: QBAR(11); popq %rbx; - popq %rbp; + popq %r15; vmovdqa .Lbswap_mask, RKM; @@ -310,15 +312,17 @@ ENDPROC(__cast6_enc_blk8) .align 8 __cast6_dec_blk8: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks * output: * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: decrypted blocks */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -343,7 +347,7 @@ __cast6_dec_blk8: QBAR(0); popq %rbx; - popq %rbp; + popq %r15; vmovdqa .Lbswap_mask, RKM; outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM); @@ -354,12 +358,14 @@ ENDPROC(__cast6_dec_blk8) ENTRY(cast6_ecb_enc_8way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -368,18 +374,21 @@ ENTRY(cast6_ecb_enc_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_ecb_enc_8way) ENTRY(cast6_ecb_dec_8way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -388,20 +397,22 @@ ENTRY(cast6_ecb_dec_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_ecb_dec_8way) ENTRY(cast6_cbc_dec_8way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN - pushq %r12; + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -411,8 +422,8 @@ ENTRY(cast6_cbc_dec_8way) store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast6_cbc_dec_8way) @@ -425,9 +436,10 @@ ENTRY(cast6_ctr_8way) * %rcx: iv (little endian, 128bit) */ FRAME_BEGIN - pushq %r12; + pushq %r15 + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -438,8 +450,8 @@ ENTRY(cast6_ctr_8way) store_ctr_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast6_ctr_8way) @@ -452,7 +464,9 @@ ENTRY(cast6_xts_enc_8way) * %rcx: iv (t ⊕ α⿠∈ GF(2¹²â¸)) */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX movq %rsi, %r11; /* regs <= src, dst <= IVs, regs <= regs xor IVs */ @@ -464,6 +478,7 @@ ENTRY(cast6_xts_enc_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_xts_enc_8way) @@ -476,7 +491,9 @@ ENTRY(cast6_xts_dec_8way) * %rcx: iv (t ⊕ α⿠∈ GF(2¹²â¸)) */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX movq %rsi, %r11; /* regs <= src, dst <= IVs, regs <= regs xor IVs */ @@ -488,6 +505,7 @@ ENTRY(cast6_xts_dec_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_xts_dec_8way) diff --git a/arch/x86/crypto/des3_ede-asm_64.S b/arch/x86/crypto/des3_ede-asm_64.S index f3e91647ca274a4b20d4b18f0d7232a3c8ca4567..8e49ce1174947ea612fca65a6d143cdc2386534e 100644 --- a/arch/x86/crypto/des3_ede-asm_64.S +++ b/arch/x86/crypto/des3_ede-asm_64.S @@ -64,12 +64,12 @@ #define RW2bh %ch #define RT0 %r15 -#define RT1 %rbp +#define RT1 %rsi #define RT2 %r14 #define RT3 %rdx #define RT0d %r15d -#define RT1d %ebp +#define RT1d %esi #define RT2d %r14d #define RT3d %edx @@ -177,13 +177,14 @@ ENTRY(des3_ede_x86_64_crypt_blk) * %rsi: dst * %rdx: src */ - pushq %rbp; pushq %rbx; pushq %r12; pushq %r13; pushq %r14; pushq %r15; + pushq %rsi; /* dst */ + read_block(%rdx, RL0, RR0); initial_permutation(RL0, RR0); @@ -241,6 +242,8 @@ ENTRY(des3_ede_x86_64_crypt_blk) round1(32+15, RL0, RR0, dummy2); final_permutation(RR0, RL0); + + popq %rsi /* dst */ write_block(%rsi, RR0, RL0); popq %r15; @@ -248,7 +251,6 @@ ENTRY(des3_ede_x86_64_crypt_blk) popq %r13; popq %r12; popq %rbx; - popq %rbp; ret; ENDPROC(des3_ede_x86_64_crypt_blk) @@ -432,13 +434,14 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) * %rdx: src (3 blocks) */ - pushq %rbp; pushq %rbx; pushq %r12; pushq %r13; pushq %r14; pushq %r15; + pushq %rsi /* dst */ + /* load input */ movl 0 * 4(%rdx), RL0d; movl 1 * 4(%rdx), RR0d; @@ -520,6 +523,7 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) bswapl RR2d; bswapl RL2d; + popq %rsi /* dst */ movl RR0d, 0 * 4(%rsi); movl RL0d, 1 * 4(%rsi); movl RR1d, 2 * 4(%rsi); @@ -532,7 +536,6 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) popq %r13; popq %r12; popq %rbx; - popq %rbp; ret; ENDPROC(des3_ede_x86_64_crypt_blk_3way) diff --git a/arch/x86/crypto/des3_ede_glue.c b/arch/x86/crypto/des3_ede_glue.c index d6fc59aaaadfbc0461a9aaab1557eb27f7841402..30c0a37f488264651460d5de9df30a097164ed88 100644 --- a/arch/x86/crypto/des3_ede_glue.c +++ b/arch/x86/crypto/des3_ede_glue.c @@ -277,8 +277,7 @@ static void ctr_crypt_final(struct des3_ede_x86_ctx *ctx, unsigned int nbytes = walk->nbytes; des3_ede_enc_blk(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); crypto_inc(ctrblk, DES3_EDE_BLOCK_SIZE); } diff --git a/arch/x86/crypto/sha1_avx2_x86_64_asm.S b/arch/x86/crypto/sha1_avx2_x86_64_asm.S index 1cd792db15efe760e3a6fc8b17b9a4c4e6f35233..9f712a7dfd797cc499e1ef52ba7999078530494a 100644 --- a/arch/x86/crypto/sha1_avx2_x86_64_asm.S +++ b/arch/x86/crypto/sha1_avx2_x86_64_asm.S @@ -89,7 +89,7 @@ #define REG_RE %rdx #define REG_RTA %r12 #define REG_RTB %rbx -#define REG_T1 %ebp +#define REG_T1 %r11d #define xmm_mov vmovups #define avx2_zeroupper vzeroupper #define RND_F1 1 @@ -117,11 +117,10 @@ .set T1, REG_T1 .endm -#define K_BASE %r8 #define HASH_PTR %r9 +#define BLOCKS_CTR %r8 #define BUFFER_PTR %r10 #define BUFFER_PTR2 %r13 -#define BUFFER_END %r11 #define PRECALC_BUF %r14 #define WK_BUF %r15 @@ -205,14 +204,14 @@ * blended AVX2 and ALU instruction scheduling * 1 vector iteration per 8 rounds */ - vmovdqu ((i * 2) + PRECALC_OFFSET)(BUFFER_PTR), W_TMP + vmovdqu (i * 2)(BUFFER_PTR), W_TMP .elseif ((i & 7) == 1) - vinsertf128 $1, (((i-1) * 2)+PRECALC_OFFSET)(BUFFER_PTR2),\ + vinsertf128 $1, ((i-1) * 2)(BUFFER_PTR2),\ WY_TMP, WY_TMP .elseif ((i & 7) == 2) vpshufb YMM_SHUFB_BSWAP, WY_TMP, WY .elseif ((i & 7) == 4) - vpaddd K_XMM(K_BASE), WY, WY_TMP + vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP .elseif ((i & 7) == 7) vmovdqu WY_TMP, PRECALC_WK(i&~7) @@ -255,7 +254,7 @@ vpxor WY, WY_TMP, WY_TMP .elseif ((i & 7) == 7) vpxor WY_TMP2, WY_TMP, WY - vpaddd K_XMM(K_BASE), WY, WY_TMP + vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP vmovdqu WY_TMP, PRECALC_WK(i&~7) PRECALC_ROTATE_WY @@ -291,7 +290,7 @@ vpsrld $30, WY, WY vpor WY, WY_TMP, WY .elseif ((i & 7) == 7) - vpaddd K_XMM(K_BASE), WY, WY_TMP + vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP vmovdqu WY_TMP, PRECALC_WK(i&~7) PRECALC_ROTATE_WY @@ -446,6 +445,16 @@ .endm +/* Add constant only if (%2 > %3) condition met (uses RTA as temp) + * %1 + %2 >= %3 ? %4 : 0 + */ +.macro ADD_IF_GE a, b, c, d + mov \a, RTA + add $\d, RTA + cmp $\c, \b + cmovge RTA, \a +.endm + /* * macro implements 80 rounds of SHA-1, for multiple blocks with s/w pipelining */ @@ -463,13 +472,16 @@ lea (2*4*80+32)(%rsp), WK_BUF # Precalc WK for first 2 blocks - PRECALC_OFFSET = 0 + ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 2, 64 .set i, 0 .rept 160 PRECALC i .set i, i + 1 .endr - PRECALC_OFFSET = 128 + + /* Go to next block if needed */ + ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 3, 128 + ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128 xchg WK_BUF, PRECALC_BUF .align 32 @@ -479,8 +491,8 @@ _loop: * we use K_BASE value as a signal of a last block, * it is set below by: cmovae BUFFER_PTR, K_BASE */ - cmp K_BASE, BUFFER_PTR - jne _begin + test BLOCKS_CTR, BLOCKS_CTR + jnz _begin .align 32 jmp _end .align 32 @@ -512,10 +524,10 @@ _loop0: .set j, j+2 .endr - add $(2*64), BUFFER_PTR /* move to next odd-64-byte block */ - cmp BUFFER_END, BUFFER_PTR /* is current block the last one? */ - cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */ - + /* Update Counter */ + sub $1, BLOCKS_CTR + /* Move to the next block only if needed*/ + ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 4, 128 /* * rounds * 60,62,64,66,68 @@ -532,8 +544,8 @@ _loop0: UPDATE_HASH 12(HASH_PTR), D UPDATE_HASH 16(HASH_PTR), E - cmp K_BASE, BUFFER_PTR /* is current block the last one? */ - je _loop + test BLOCKS_CTR, BLOCKS_CTR + jz _loop mov TB, B @@ -575,10 +587,10 @@ _loop2: .set j, j+2 .endr - add $(2*64), BUFFER_PTR2 /* move to next even-64-byte block */ - - cmp BUFFER_END, BUFFER_PTR2 /* is current block the last one */ - cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */ + /* update counter */ + sub $1, BLOCKS_CTR + /* Move to the next block only if needed*/ + ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128 jmp _loop3 _loop3: @@ -625,7 +637,6 @@ _loop3: ENTRY(\name) push %rbx - push %rbp push %r12 push %r13 push %r14 @@ -641,19 +652,12 @@ _loop3: avx2_zeroupper - lea K_XMM_AR(%rip), K_BASE - + /* Setup initial values */ mov CTX, HASH_PTR mov BUF, BUFFER_PTR - lea 64(BUF), BUFFER_PTR2 - - shl $6, CNT /* mul by 64 */ - add BUF, CNT - add $64, CNT - mov CNT, BUFFER_END - cmp BUFFER_END, BUFFER_PTR2 - cmovae K_BASE, BUFFER_PTR2 + mov BUF, BUFFER_PTR2 + mov CNT, BLOCKS_CTR xmm_mov BSWAP_SHUFB_CTL(%rip), YMM_SHUFB_BSWAP @@ -668,7 +672,6 @@ _loop3: pop %r14 pop %r13 pop %r12 - pop %rbp pop %rbx ret diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S index a4109506a5e8884ba54562aed09bc36e5e800d12..6204bd53528c65c0d4a70f05e76a60bcc476499e 100644 --- a/arch/x86/crypto/sha1_ssse3_asm.S +++ b/arch/x86/crypto/sha1_ssse3_asm.S @@ -37,7 +37,7 @@ #define REG_A %ecx #define REG_B %esi #define REG_C %edi -#define REG_D %ebp +#define REG_D %r12d #define REG_E %edx #define REG_T1 %eax @@ -74,10 +74,10 @@ ENTRY(\name) push %rbx - push %rbp push %r12 + push %rbp + mov %rsp, %rbp - mov %rsp, %r12 sub $64, %rsp # allocate workspace and $~15, %rsp # align stack @@ -99,10 +99,9 @@ xor %rax, %rax rep stosq - mov %r12, %rsp # deallocate workspace - - pop %r12 + mov %rbp, %rsp # deallocate workspace pop %rbp + pop %r12 pop %rbx ret diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c index f960a043cdeba4a36f4ba20fddf81369f8ced38f..fc61739150e7c2c5a484c020b14441551fe5403a 100644 --- a/arch/x86/crypto/sha1_ssse3_glue.c +++ b/arch/x86/crypto/sha1_ssse3_glue.c @@ -201,7 +201,7 @@ asmlinkage void sha1_transform_avx2(u32 *digest, const char *data, static bool avx2_usable(void) { - if (false && avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) + if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_BMI1) && boot_cpu_has(X86_FEATURE_BMI2)) return true; diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S index e08888a1a5f2cf5f8a6809d86d497664cece52a1..001bbcf93c79ba08628abcf30dd49ad77158420d 100644 --- a/arch/x86/crypto/sha256-avx-asm.S +++ b/arch/x86/crypto/sha256-avx-asm.S @@ -103,7 +103,7 @@ SRND = %rsi # clobbers INP c = %ecx d = %r8d e = %edx -TBL = %rbp +TBL = %r12 a = %eax b = %ebx @@ -350,13 +350,13 @@ a = TMP_ ENTRY(sha256_transform_avx) .align 32 pushq %rbx - pushq %rbp + pushq %r12 pushq %r13 pushq %r14 pushq %r15 - pushq %r12 + pushq %rbp + movq %rsp, %rbp - mov %rsp, %r12 subq $STACK_SIZE, %rsp # allocate stack space and $~15, %rsp # align stack pointer @@ -452,13 +452,12 @@ loop2: done_hash: - mov %r12, %rsp - - popq %r12 + mov %rbp, %rsp + popq %rbp popq %r15 popq %r14 popq %r13 - popq %rbp + popq %r12 popq %rbx ret ENDPROC(sha256_transform_avx) diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S index 89c8f09787d20552c12230ded345282bb2f2bf42..1420db15dcddc8505b57faad5e6e6701f972b517 100644 --- a/arch/x86/crypto/sha256-avx2-asm.S +++ b/arch/x86/crypto/sha256-avx2-asm.S @@ -98,8 +98,6 @@ d = %r8d e = %edx # clobbers NUM_BLKS y3 = %esi # clobbers INP - -TBL = %rbp SRND = CTX # SRND is same register as CTX a = %eax @@ -531,7 +529,6 @@ STACK_SIZE = _RSP + _RSP_SIZE ENTRY(sha256_transform_rorx) .align 32 pushq %rbx - pushq %rbp pushq %r12 pushq %r13 pushq %r14 @@ -568,8 +565,6 @@ ENTRY(sha256_transform_rorx) mov CTX, _CTX(%rsp) loop0: - lea K256(%rip), TBL - ## Load first 16 dwords from two blocks VMOVDQ 0*32(INP),XTMP0 VMOVDQ 1*32(INP),XTMP1 @@ -597,19 +592,19 @@ last_block_enter: .align 16 loop1: - vpaddd 0*32(TBL, SRND), X0, XFER + vpaddd K256+0*32(SRND), X0, XFER vmovdqa XFER, 0*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 0*32 - vpaddd 1*32(TBL, SRND), X0, XFER + vpaddd K256+1*32(SRND), X0, XFER vmovdqa XFER, 1*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 1*32 - vpaddd 2*32(TBL, SRND), X0, XFER + vpaddd K256+2*32(SRND), X0, XFER vmovdqa XFER, 2*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 2*32 - vpaddd 3*32(TBL, SRND), X0, XFER + vpaddd K256+3*32(SRND), X0, XFER vmovdqa XFER, 3*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 3*32 @@ -619,10 +614,11 @@ loop1: loop2: ## Do last 16 rounds with no scheduling - vpaddd 0*32(TBL, SRND), X0, XFER + vpaddd K256+0*32(SRND), X0, XFER vmovdqa XFER, 0*32+_XFER(%rsp, SRND) DO_4ROUNDS _XFER + 0*32 - vpaddd 1*32(TBL, SRND), X1, XFER + + vpaddd K256+1*32(SRND), X1, XFER vmovdqa XFER, 1*32+_XFER(%rsp, SRND) DO_4ROUNDS _XFER + 1*32 add $2*32, SRND @@ -676,9 +672,6 @@ loop3: ja done_hash do_last_block: - #### do last block - lea K256(%rip), TBL - VMOVDQ 0*16(INP),XWORD0 VMOVDQ 1*16(INP),XWORD1 VMOVDQ 2*16(INP),XWORD2 @@ -718,7 +711,6 @@ done_hash: popq %r14 popq %r13 popq %r12 - popq %rbp popq %rbx ret ENDPROC(sha256_transform_rorx) diff --git a/arch/x86/crypto/sha256-ssse3-asm.S b/arch/x86/crypto/sha256-ssse3-asm.S index 39b83c93e7fd6cdbc658a35ef4698756cccef612..c6c05ed2c16a593390ddf7617070f45e58a40ad4 100644 --- a/arch/x86/crypto/sha256-ssse3-asm.S +++ b/arch/x86/crypto/sha256-ssse3-asm.S @@ -95,7 +95,7 @@ SRND = %rsi # clobbers INP c = %ecx d = %r8d e = %edx -TBL = %rbp +TBL = %r12 a = %eax b = %ebx @@ -356,13 +356,13 @@ a = TMP_ ENTRY(sha256_transform_ssse3) .align 32 pushq %rbx - pushq %rbp + pushq %r12 pushq %r13 pushq %r14 pushq %r15 - pushq %r12 + pushq %rbp + mov %rsp, %rbp - mov %rsp, %r12 subq $STACK_SIZE, %rsp and $~15, %rsp @@ -462,13 +462,12 @@ loop2: done_hash: - mov %r12, %rsp - - popq %r12 + mov %rbp, %rsp + popq %rbp popq %r15 popq %r14 popq %r13 - popq %rbp + popq %r12 popq %rbx ret diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S index 7f5f6c6ec72e9cb0a47c2b5babbbedff487fbbf3..b16d560051629a1c6d518321b93be2672b861c9e 100644 --- a/arch/x86/crypto/sha512-avx2-asm.S +++ b/arch/x86/crypto/sha512-avx2-asm.S @@ -69,8 +69,9 @@ XFER = YTMP0 BYTE_FLIP_MASK = %ymm9 -# 1st arg -CTX = %rdi +# 1st arg is %rdi, which is saved to the stack and accessed later via %r12 +CTX1 = %rdi +CTX2 = %r12 # 2nd arg INP = %rsi # 3rd arg @@ -81,7 +82,7 @@ d = %r8 e = %rdx y3 = %rsi -TBL = %rbp +TBL = %rdi # clobbers CTX1 a = %rax b = %rbx @@ -91,26 +92,26 @@ g = %r10 h = %r11 old_h = %r11 -T1 = %r12 +T1 = %r12 # clobbers CTX2 y0 = %r13 y1 = %r14 y2 = %r15 -y4 = %r12 - # Local variables (stack frame) XFER_SIZE = 4*8 SRND_SIZE = 1*8 INP_SIZE = 1*8 INPEND_SIZE = 1*8 +CTX_SIZE = 1*8 RSPSAVE_SIZE = 1*8 -GPRSAVE_SIZE = 6*8 +GPRSAVE_SIZE = 5*8 frame_XFER = 0 frame_SRND = frame_XFER + XFER_SIZE frame_INP = frame_SRND + SRND_SIZE frame_INPEND = frame_INP + INP_SIZE -frame_RSPSAVE = frame_INPEND + INPEND_SIZE +frame_CTX = frame_INPEND + INPEND_SIZE +frame_RSPSAVE = frame_CTX + CTX_SIZE frame_GPRSAVE = frame_RSPSAVE + RSPSAVE_SIZE frame_size = frame_GPRSAVE + GPRSAVE_SIZE @@ -576,12 +577,11 @@ ENTRY(sha512_transform_rorx) mov %rax, frame_RSPSAVE(%rsp) # Save GPRs - mov %rbp, frame_GPRSAVE(%rsp) - mov %rbx, 8*1+frame_GPRSAVE(%rsp) - mov %r12, 8*2+frame_GPRSAVE(%rsp) - mov %r13, 8*3+frame_GPRSAVE(%rsp) - mov %r14, 8*4+frame_GPRSAVE(%rsp) - mov %r15, 8*5+frame_GPRSAVE(%rsp) + mov %rbx, 8*0+frame_GPRSAVE(%rsp) + mov %r12, 8*1+frame_GPRSAVE(%rsp) + mov %r13, 8*2+frame_GPRSAVE(%rsp) + mov %r14, 8*3+frame_GPRSAVE(%rsp) + mov %r15, 8*4+frame_GPRSAVE(%rsp) shl $7, NUM_BLKS # convert to bytes jz done_hash @@ -589,14 +589,17 @@ ENTRY(sha512_transform_rorx) mov NUM_BLKS, frame_INPEND(%rsp) ## load initial digest - mov 8*0(CTX),a - mov 8*1(CTX),b - mov 8*2(CTX),c - mov 8*3(CTX),d - mov 8*4(CTX),e - mov 8*5(CTX),f - mov 8*6(CTX),g - mov 8*7(CTX),h + mov 8*0(CTX1), a + mov 8*1(CTX1), b + mov 8*2(CTX1), c + mov 8*3(CTX1), d + mov 8*4(CTX1), e + mov 8*5(CTX1), f + mov 8*6(CTX1), g + mov 8*7(CTX1), h + + # save %rdi (CTX) before it gets clobbered + mov %rdi, frame_CTX(%rsp) vmovdqa PSHUFFLE_BYTE_FLIP_MASK(%rip), BYTE_FLIP_MASK @@ -652,14 +655,15 @@ loop2: subq $1, frame_SRND(%rsp) jne loop2 - addm 8*0(CTX),a - addm 8*1(CTX),b - addm 8*2(CTX),c - addm 8*3(CTX),d - addm 8*4(CTX),e - addm 8*5(CTX),f - addm 8*6(CTX),g - addm 8*7(CTX),h + mov frame_CTX(%rsp), CTX2 + addm 8*0(CTX2), a + addm 8*1(CTX2), b + addm 8*2(CTX2), c + addm 8*3(CTX2), d + addm 8*4(CTX2), e + addm 8*5(CTX2), f + addm 8*6(CTX2), g + addm 8*7(CTX2), h mov frame_INP(%rsp), INP add $128, INP @@ -669,12 +673,11 @@ loop2: done_hash: # Restore GPRs - mov frame_GPRSAVE(%rsp) ,%rbp - mov 8*1+frame_GPRSAVE(%rsp) ,%rbx - mov 8*2+frame_GPRSAVE(%rsp) ,%r12 - mov 8*3+frame_GPRSAVE(%rsp) ,%r13 - mov 8*4+frame_GPRSAVE(%rsp) ,%r14 - mov 8*5+frame_GPRSAVE(%rsp) ,%r15 + mov 8*0+frame_GPRSAVE(%rsp), %rbx + mov 8*1+frame_GPRSAVE(%rsp), %r12 + mov 8*2+frame_GPRSAVE(%rsp), %r13 + mov 8*3+frame_GPRSAVE(%rsp), %r14 + mov 8*4+frame_GPRSAVE(%rsp), %r15 # Restore Stack Pointer mov frame_RSPSAVE(%rsp), %rsp diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S index b3f49d2863480334e8b2d12828e4ca20045b8be9..73b471da36226386112a23c0036b7f5da14b3266 100644 --- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S @@ -76,8 +76,8 @@ #define RT %xmm14 #define RR %xmm15 -#define RID1 %rbp -#define RID1d %ebp +#define RID1 %r13 +#define RID1d %r13d #define RID2 %rsi #define RID2d %esi @@ -259,7 +259,7 @@ __twofish_enc_blk8: vmovdqu w(CTX), RK1; - pushq %rbp; + pushq %r13; pushq %rbx; pushq %rcx; @@ -282,7 +282,7 @@ __twofish_enc_blk8: popq %rcx; popq %rbx; - popq %rbp; + popq %r13; outunpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2); outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2); @@ -301,7 +301,7 @@ __twofish_dec_blk8: vmovdqu (w+4*4)(CTX), RK1; - pushq %rbp; + pushq %r13; pushq %rbx; inpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2); @@ -322,7 +322,7 @@ __twofish_dec_blk8: vmovdqu (w)(CTX), RK1; popq %rbx; - popq %rbp; + popq %r13; outunpack_blocks(RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2); outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2); diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile index 9976fcecd17edfca5d5dbfe94c2dad0a635edf2d..af28a8a24366b9ba9365726f17cf4745dcf5823b 100644 --- a/arch/x86/entry/Makefile +++ b/arch/x86/entry/Makefile @@ -2,7 +2,6 @@ # Makefile for the x86 low level entry code # -OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y CFLAGS_syscall_64.o += $(call cc-option,-Wno-override-init,) diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 05ed3d393da797e648cf2e7d477d5c7a5ba523fe..640aafebdc00e460687a796f5011c1ab917a4ab9 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -1,4 +1,5 @@ #include +#include /* @@ -112,6 +113,7 @@ For 32-bit we have the following conventions - kernel is built with movq %rdx, 12*8+\offset(%rsp) movq %rsi, 13*8+\offset(%rsp) movq %rdi, 14*8+\offset(%rsp) + UNWIND_HINT_REGS offset=\offset extra=0 .endm .macro SAVE_C_REGS offset=0 SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1 @@ -136,6 +138,7 @@ For 32-bit we have the following conventions - kernel is built with movq %r12, 3*8+\offset(%rsp) movq %rbp, 4*8+\offset(%rsp) movq %rbx, 5*8+\offset(%rsp) + UNWIND_HINT_REGS offset=\offset .endm .macro RESTORE_EXTRA_REGS offset=0 @@ -145,6 +148,7 @@ For 32-bit we have the following conventions - kernel is built with movq 3*8+\offset(%rsp), %r12 movq 4*8+\offset(%rsp), %rbp movq 5*8+\offset(%rsp), %rbx + UNWIND_HINT_REGS offset=\offset extra=0 .endm .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1 @@ -167,6 +171,7 @@ For 32-bit we have the following conventions - kernel is built with .endif movq 13*8(%rsp), %rsi movq 14*8(%rsp), %rdi + UNWIND_HINT_IRET_REGS offset=16*8 .endm .macro RESTORE_C_REGS RESTORE_C_REGS_HELPER 1,1,1,1,1 diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index cdefcfdd9e63effa6a06660adf013c4fe96ea853..03505ffbe1b68d49982db71dfad0c83b04e45246 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,8 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) struct thread_info *ti = current_thread_info(); u32 cached_flags; + addr_limit_user_check(); + if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled())) local_irq_disable(); diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 48ef7bb32c4269331ceb2332b8e6bf5faffcb3de..8a13d468635a8f56f772a6879d3e907a1945dd6a 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -673,16 +673,8 @@ ENTRY(name) \ jmp ret_from_intr; \ ENDPROC(name) - -#ifdef CONFIG_TRACING -# define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) -#else -# define TRACE_BUILD_INTERRUPT(name, nr) -#endif - #define BUILD_INTERRUPT(name, nr) \ BUILD_INTERRUPT3(name, nr, smp_##name); \ - TRACE_BUILD_INTERRUPT(name, nr) /* The include is where all of the SMP etc. interrupts come from */ #include @@ -880,25 +872,17 @@ ENTRY(xen_failsafe_callback) ENDPROC(xen_failsafe_callback) BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - xen_evtchn_do_upcall) + xen_evtchn_do_upcall) #endif /* CONFIG_XEN */ #if IS_ENABLED(CONFIG_HYPERV) BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - hyperv_vector_handler) + hyperv_vector_handler) #endif /* CONFIG_HYPERV */ -#ifdef CONFIG_TRACING -ENTRY(trace_page_fault) - ASM_CLAC - pushl $trace_do_page_fault - jmp common_exception -END(trace_page_fault) -#endif - ENTRY(page_fault) ASM_CLAC pushl $do_page_fault diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index d271fb79248f3569c6a0a934f707d91f398562b8..49167258d587570673c5e515cb00b4d8f26263b7 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -36,6 +36,7 @@ #include #include #include +#include #include .code64 @@ -43,9 +44,10 @@ #ifdef CONFIG_PARAVIRT ENTRY(native_usergs_sysret64) + UNWIND_HINT_EMPTY swapgs sysretq -ENDPROC(native_usergs_sysret64) +END(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ .macro TRACE_IRQS_IRETQ @@ -134,19 +136,14 @@ ENDPROC(native_usergs_sysret64) */ ENTRY(entry_SYSCALL_64) + UNWIND_HINT_EMPTY /* * Interrupts are off on entry. * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON, * it is too small to ever cause noticeable irq latency. */ - SWAPGS_UNSAFE_STACK - /* - * A hypervisor implementation might want to use a label - * after the swapgs, so that it can do the swapgs - * for the guest and jump here on syscall. - */ -GLOBAL(entry_SYSCALL_64_after_swapgs) + swapgs movq %rsp, PER_CPU_VAR(rsp_scratch) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp @@ -158,6 +155,7 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) pushq %r11 /* pt_regs->flags */ pushq $__USER_CS /* pt_regs->cs */ pushq %rcx /* pt_regs->ip */ +GLOBAL(entry_SYSCALL_64_after_hwframe) pushq %rax /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -169,6 +167,7 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) pushq %r10 /* pt_regs->r10 */ pushq %r11 /* pt_regs->r11 */ sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */ + UNWIND_HINT_REGS extra=0 /* * If we need to do entry work or if we guess we'll need to do @@ -223,6 +222,7 @@ entry_SYSCALL_64_fastpath: movq EFLAGS(%rsp), %r11 RESTORE_C_REGS_EXCEPT_RCX_R11 movq RSP(%rsp), %rsp + UNWIND_HINT_EMPTY USERGS_SYSRET64 1: @@ -316,6 +316,7 @@ syscall_return_via_sysret: /* rcx and r11 are already restored (see code above) */ RESTORE_C_REGS_EXCEPT_RCX_R11 movq RSP(%rsp), %rsp + UNWIND_HINT_EMPTY USERGS_SYSRET64 opportunistic_sysret_failed: @@ -343,6 +344,7 @@ ENTRY(stub_ptregs_64) DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF popq %rax + UNWIND_HINT_REGS extra=0 jmp entry_SYSCALL64_slow_path 1: @@ -351,6 +353,7 @@ END(stub_ptregs_64) .macro ptregs_stub func ENTRY(ptregs_\func) + UNWIND_HINT_FUNC leaq \func(%rip), %rax jmp stub_ptregs_64 END(ptregs_\func) @@ -367,6 +370,7 @@ END(ptregs_\func) * %rsi: next task */ ENTRY(__switch_to_asm) + UNWIND_HINT_FUNC /* * Save callee-saved registers * This must match the order in inactive_task_frame @@ -406,6 +410,7 @@ END(__switch_to_asm) * r12: kernel thread arg */ ENTRY(ret_from_fork) + UNWIND_HINT_EMPTY movq %rax, %rdi call schedule_tail /* rdi: 'prev' task parameter */ @@ -413,6 +418,7 @@ ENTRY(ret_from_fork) jnz 1f /* kernel threads are uncommon */ 2: + UNWIND_HINT_REGS movq %rsp, %rdi call syscall_return_slowpath /* returns with IRQs disabled */ TRACE_IRQS_ON /* user mode is traced as IRQS on */ @@ -440,13 +446,102 @@ END(ret_from_fork) ENTRY(irq_entries_start) vector=FIRST_EXTERNAL_VECTOR .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR) + UNWIND_HINT_IRET_REGS pushq $(~vector+0x80) /* Note: always in signed byte range */ - vector=vector+1 jmp common_interrupt .align 8 + vector=vector+1 .endr END(irq_entries_start) +.macro DEBUG_ENTRY_ASSERT_IRQS_OFF +#ifdef CONFIG_DEBUG_ENTRY + pushfq + testl $X86_EFLAGS_IF, (%rsp) + jz .Lokay_\@ + ud2 +.Lokay_\@: + addq $8, %rsp +#endif +.endm + +/* + * Enters the IRQ stack if we're not already using it. NMI-safe. Clobbers + * flags and puts old RSP into old_rsp, and leaves all other GPRs alone. + * Requires kernel GSBASE. + * + * The invariant is that, if irq_count != -1, then the IRQ stack is in use. + */ +.macro ENTER_IRQ_STACK regs=1 old_rsp + DEBUG_ENTRY_ASSERT_IRQS_OFF + movq %rsp, \old_rsp + + .if \regs + UNWIND_HINT_REGS base=\old_rsp + .endif + + incl PER_CPU_VAR(irq_count) + jnz .Lirq_stack_push_old_rsp_\@ + + /* + * Right now, if we just incremented irq_count to zero, we've + * claimed the IRQ stack but we haven't switched to it yet. + * + * If anything is added that can interrupt us here without using IST, + * it must be *extremely* careful to limit its stack usage. This + * could include kprobes and a hypothetical future IST-less #DB + * handler. + * + * The OOPS unwinder relies on the word at the top of the IRQ + * stack linking back to the previous RSP for the entire time we're + * on the IRQ stack. For this to work reliably, we need to write + * it before we actually move ourselves to the IRQ stack. + */ + + movq \old_rsp, PER_CPU_VAR(irq_stack_union + IRQ_STACK_SIZE - 8) + movq PER_CPU_VAR(irq_stack_ptr), %rsp + +#ifdef CONFIG_DEBUG_ENTRY + /* + * If the first movq above becomes wrong due to IRQ stack layout + * changes, the only way we'll notice is if we try to unwind right + * here. Assert that we set up the stack right to catch this type + * of bug quickly. + */ + cmpq -8(%rsp), \old_rsp + je .Lirq_stack_okay\@ + ud2 + .Lirq_stack_okay\@: +#endif + +.Lirq_stack_push_old_rsp_\@: + pushq \old_rsp + + .if \regs + UNWIND_HINT_REGS indirect=1 + .endif +.endm + +/* + * Undoes ENTER_IRQ_STACK. + */ +.macro LEAVE_IRQ_STACK regs=1 + DEBUG_ENTRY_ASSERT_IRQS_OFF + /* We need to be off the IRQ stack before decrementing irq_count. */ + popq %rsp + + .if \regs + UNWIND_HINT_REGS + .endif + + /* + * As in ENTER_IRQ_STACK, irq_count == 0, we are still claiming + * the irq stack but we're not on it. + */ + + decl PER_CPU_VAR(irq_count) +.endm + /* * Interrupt entry/exit. * @@ -485,17 +580,7 @@ END(irq_entries_start) CALL_enter_from_user_mode 1: - /* - * Save previous stack pointer, optionally switch to interrupt stack. - * irq_count is used to check if a CPU is already on an interrupt stack - * or not. While this is essentially redundant with preempt_count it is - * a little cheaper to use a separate counter in the PDA (short of - * moving irq_enter into assembly, which would be too much work) - */ - movq %rsp, %rdi - incl PER_CPU_VAR(irq_count) - cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp - pushq %rdi + ENTER_IRQ_STACK old_rsp=%rdi /* We entered an interrupt context - irqs are off: */ TRACE_IRQS_OFF @@ -515,10 +600,8 @@ common_interrupt: ret_from_intr: DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF - decl PER_CPU_VAR(irq_count) - /* Restore saved previous stack */ - popq %rsp + LEAVE_IRQ_STACK testb $3, CS(%rsp) jz retint_kernel @@ -561,6 +644,7 @@ restore_c_regs_and_iret: INTERRUPT_RETURN ENTRY(native_iret) + UNWIND_HINT_IRET_REGS /* * Are we returning to a stack segment from the LDT? Note: in * 64-bit mode SS:RSP on the exception stack is always valid. @@ -633,6 +717,7 @@ native_irq_return_ldt: orq PER_CPU_VAR(espfix_stack), %rax SWAPGS movq %rax, %rsp + UNWIND_HINT_IRET_REGS offset=8 /* * At this point, we cannot write to the stack any more, but we can @@ -654,6 +739,7 @@ END(common_interrupt) */ .macro apicinterrupt3 num sym do_sym ENTRY(\sym) + UNWIND_HINT_IRET_REGS ASM_CLAC pushq $~(\num) .Lcommon_\sym: @@ -662,31 +748,13 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -#define trace(sym) trace_##sym -#define smp_trace(sym) smp_trace_##sym - -.macro trace_apicinterrupt num sym -apicinterrupt3 \num trace(\sym) smp_trace(\sym) -.endm -#else -.macro trace_apicinterrupt num sym do_sym -.endm -#endif - /* Make sure APIC interrupt handlers end up in the irqentry section: */ -#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) -# define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" -# define POP_SECTION_IRQENTRY .popsection -#else -# define PUSH_SECTION_IRQENTRY -# define POP_SECTION_IRQENTRY -#endif +#define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" +#define POP_SECTION_IRQENTRY .popsection .macro apicinterrupt num sym do_sym PUSH_SECTION_IRQENTRY apicinterrupt3 \num \sym \do_sym -trace_apicinterrupt \num \sym POP_SECTION_IRQENTRY .endm @@ -740,13 +808,14 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym) + UNWIND_HINT_IRET_REGS offset=8 + /* Sanity check */ .if \shift_ist != -1 && \paranoid == 0 .error "using shift_ist requires paranoid=1" .endif ASM_CLAC - PARAVIRT_ADJUST_EXCEPTION_FRAME .ifeq \has_error_code pushq $-1 /* ORIG_RAX: no syscall to restart */ @@ -763,6 +832,7 @@ ENTRY(\sym) .else call error_entry .endif + UNWIND_HINT_REGS /* returned flag: ebx=0: need swapgs on exit, ebx=1: don't need it */ .if \paranoid @@ -829,17 +899,6 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -.macro trace_idtentry sym do_sym has_error_code:req -idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#else -.macro trace_idtentry sym do_sym has_error_code:req -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#endif - idtentry divide_error do_divide_error has_error_code=0 idtentry overflow do_overflow has_error_code=0 idtentry bounds do_bounds has_error_code=0 @@ -860,6 +919,7 @@ idtentry simd_coprocessor_error do_simd_coprocessor_error has_error_code=0 * edi: new selector */ ENTRY(native_load_gs_index) + FRAME_BEGIN pushfq DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) SWAPGS @@ -868,8 +928,9 @@ ENTRY(native_load_gs_index) 2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE SWAPGS popfq + FRAME_END ret -END(native_load_gs_index) +ENDPROC(native_load_gs_index) EXPORT_SYMBOL(native_load_gs_index) _ASM_EXTABLE(.Lgs_change, bad_gs) @@ -892,17 +953,15 @@ bad_gs: ENTRY(do_softirq_own_stack) pushq %rbp mov %rsp, %rbp - incl PER_CPU_VAR(irq_count) - cmove PER_CPU_VAR(irq_stack_ptr), %rsp - push %rbp /* frame pointer backlink */ + ENTER_IRQ_STACK regs=0 old_rsp=%r11 call __do_softirq + LEAVE_IRQ_STACK regs=0 leaveq - decl PER_CPU_VAR(irq_count) ret -END(do_softirq_own_stack) +ENDPROC(do_softirq_own_stack) #ifdef CONFIG_XEN -idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 +idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 /* * A note on the "critical region" in our callback handler. @@ -923,14 +982,14 @@ ENTRY(xen_do_hypervisor_callback) /* do_hypervisor_callback(struct *pt_regs) */ * Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will * see the correct pointer to the pt_regs */ + UNWIND_HINT_FUNC movq %rdi, %rsp /* we don't return, adjust the stack frame */ -11: incl PER_CPU_VAR(irq_count) - movq %rsp, %rbp - cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp - pushq %rbp /* frame pointer backlink */ + UNWIND_HINT_REGS + + ENTER_IRQ_STACK old_rsp=%r10 call xen_evtchn_do_upcall - popq %rsp - decl PER_CPU_VAR(irq_count) + LEAVE_IRQ_STACK + #ifndef CONFIG_PREEMPT call xen_maybe_preempt_hcall #endif @@ -951,6 +1010,7 @@ END(xen_do_hypervisor_callback) * with its current contents: any discrepancy means we in category 1. */ ENTRY(xen_failsafe_callback) + UNWIND_HINT_EMPTY movl %ds, %ecx cmpw %cx, 0x10(%rsp) jne 1f @@ -968,13 +1028,13 @@ ENTRY(xen_failsafe_callback) movq 8(%rsp), %r11 addq $0x30, %rsp pushq $0 /* RIP */ - pushq %r11 - pushq %rcx + UNWIND_HINT_IRET_REGS offset=8 jmp general_protection 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ movq (%rsp), %rcx movq 8(%rsp), %r11 addq $0x30, %rsp + UNWIND_HINT_IRET_REGS pushq $-1 /* orig_ax = -1 => not a system call */ ALLOC_PT_GPREGS_ON_STACK SAVE_C_REGS @@ -998,13 +1058,12 @@ idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK idtentry stack_segment do_stack_segment has_error_code=1 #ifdef CONFIG_XEN -idtentry xen_debug do_debug has_error_code=0 -idtentry xen_int3 do_int3 has_error_code=0 -idtentry xen_stack_segment do_stack_segment has_error_code=1 +idtentry xendebug do_debug has_error_code=0 +idtentry xenint3 do_int3 has_error_code=0 #endif idtentry general_protection do_general_protection has_error_code=1 -trace_idtentry page_fault do_page_fault has_error_code=1 +idtentry page_fault do_page_fault has_error_code=1 #ifdef CONFIG_KVM_GUEST idtentry async_page_fault do_async_page_fault has_error_code=1 @@ -1020,6 +1079,7 @@ idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vec * Return: ebx=0: need swapgs on exit, ebx=1: otherwise */ ENTRY(paranoid_entry) + UNWIND_HINT_FUNC cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 @@ -1047,6 +1107,7 @@ END(paranoid_entry) * On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */ ENTRY(paranoid_exit) + UNWIND_HINT_REGS DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF_DEBUG testl %ebx, %ebx /* swapgs needed? */ @@ -1068,6 +1129,7 @@ END(paranoid_exit) * Return: EBX=0: came from user mode; EBX=1: otherwise */ ENTRY(error_entry) + UNWIND_HINT_FUNC cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 @@ -1152,6 +1214,7 @@ END(error_entry) * 0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode */ ENTRY(error_exit) + UNWIND_HINT_REGS DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF testl %ebx, %ebx @@ -1160,19 +1223,9 @@ ENTRY(error_exit) END(error_exit) /* Runs on exception stack */ +/* XXX: broken on Xen PV */ ENTRY(nmi) - /* - * Fix up the exception frame if we're on Xen. - * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most - * one value to the stack on native, so it may clobber the rdx - * scratch slot, but it won't clobber any of the important - * slots past it. - * - * Xen is a different story, because the Xen frame itself overlaps - * the "NMI executing" variable. - */ - PARAVIRT_ADJUST_EXCEPTION_FRAME - + UNWIND_HINT_IRET_REGS /* * We allow breakpoints in NMIs. If a breakpoint occurs, then * the iretq it performs will take us out of NMI context. @@ -1211,6 +1264,8 @@ ENTRY(nmi) * other IST entries. */ + ASM_CLAC + /* Use %rdx as our temp variable throughout */ pushq %rdx @@ -1232,11 +1287,13 @@ ENTRY(nmi) cld movq %rsp, %rdx movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp + UNWIND_HINT_IRET_REGS base=%rdx offset=8 pushq 5*8(%rdx) /* pt_regs->ss */ pushq 4*8(%rdx) /* pt_regs->rsp */ pushq 3*8(%rdx) /* pt_regs->flags */ pushq 2*8(%rdx) /* pt_regs->cs */ pushq 1*8(%rdx) /* pt_regs->rip */ + UNWIND_HINT_IRET_REGS pushq $-1 /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -1253,6 +1310,7 @@ ENTRY(nmi) pushq %r13 /* pt_regs->r13 */ pushq %r14 /* pt_regs->r14 */ pushq %r15 /* pt_regs->r15 */ + UNWIND_HINT_REGS ENCODE_FRAME_POINTER /* @@ -1407,6 +1465,7 @@ first_nmi: .rept 5 pushq 11*8(%rsp) .endr + UNWIND_HINT_IRET_REGS /* Everything up to here is safe from nested NMIs */ @@ -1422,6 +1481,7 @@ first_nmi: pushq $__KERNEL_CS /* CS */ pushq $1f /* RIP */ INTERRUPT_RETURN /* continues at repeat_nmi below */ + UNWIND_HINT_IRET_REGS 1: #endif @@ -1471,6 +1531,7 @@ end_repeat_nmi: * exceptions might do. */ call paranoid_entry + UNWIND_HINT_REGS /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp, %rdi @@ -1508,17 +1569,19 @@ nmi_restore: END(nmi) ENTRY(ignore_sysret) + UNWIND_HINT_EMPTY mov $-ENOSYS, %eax sysret END(ignore_sysret) ENTRY(rewind_stack_do_exit) + UNWIND_HINT_FUNC /* Prevent any naive code from trying to unwind to our caller. */ xorl %ebp, %ebp movq PER_CPU_VAR(cpu_current_top_of_stack), %rax - leaq -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%rax), %rsp + leaq -PTREGS_SIZE(%rax), %rsp + UNWIND_HINT_FUNC sp_offset=PTREGS_SIZE call do_exit -1: jmp 1b END(rewind_stack_do_exit) diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index e1721dafbcb13fab9230cc20d598b18ebef8306b..e26c25ca77565938fb9ca4d16b08c3bcf4f48264 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -183,21 +183,20 @@ ENDPROC(entry_SYSENTER_compat) */ ENTRY(entry_SYSCALL_compat) /* Interrupts are off on entry. */ - SWAPGS_UNSAFE_STACK + swapgs /* Stash user ESP and switch to the kernel stack. */ movl %esp, %r8d movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp - /* Zero-extending 32-bit regs, do not remove */ - movl %eax, %eax - /* Construct struct pt_regs on stack */ pushq $__USER32_DS /* pt_regs->ss */ pushq %r8 /* pt_regs->sp */ pushq %r11 /* pt_regs->flags */ pushq $__USER32_CS /* pt_regs->cs */ pushq %rcx /* pt_regs->ip */ +GLOBAL(entry_SYSCALL_compat_after_hwframe) + movl %eax, %eax /* discard orig_ax high bits */ pushq %rax /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -294,7 +293,6 @@ ENTRY(entry_INT80_compat) /* * Interrupts are off on entry. */ - PARAVIRT_ADJUST_EXCEPTION_FRAME ASM_CLAC /* Do this early to minimize exposure */ SWAPGS @@ -342,8 +340,7 @@ ENTRY(entry_INT80_compat) jmp restore_regs_and_iret END(entry_INT80_compat) - ALIGN -GLOBAL(stub32_clone) +ENTRY(stub32_clone) /* * The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr). * The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val). @@ -353,3 +350,4 @@ GLOBAL(stub32_clone) */ xchg %r8, %rcx jmp sys_clone +ENDPROC(stub32_clone) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 726355ce8497bf5c9c90828862a3afa1bc5c34b6..1911310959f8b475cf42ef51a7c8d31780f7bc4b 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -351,7 +351,7 @@ static void vgetcpu_cpu_init(void *arg) * and 8 bits for the node) */ d.limit0 = cpu | ((node & 0xf) << 12); - d.limit = node >> 4; + d.limit1 = node >> 4; d.type = 5; /* RO data, expand down, accessed */ d.dpl = 3; /* Visible to user code */ d.s = 1; /* Not a system segment */ diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index ad44af0dd6679b50ce2c48bf37b56959b967c3cb..f5cbbba992833af251e750a1d64a120e9f46368d 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -400,11 +400,24 @@ static int amd_uncore_cpu_starting(unsigned int cpu) if (amd_uncore_llc) { unsigned int apicid = cpu_data(cpu).apicid; - unsigned int nshared; + unsigned int nshared, subleaf, prev_eax = 0; uncore = *per_cpu_ptr(amd_uncore_llc, cpu); - cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx); - nshared = ((eax >> 14) & 0xfff) + 1; + /* + * Iterate over Cache Topology Definition leaves until no + * more cache descriptions are available. + */ + for (subleaf = 0; subleaf < 5; subleaf++) { + cpuid_count(0x8000001d, subleaf, &eax, &ebx, &ecx, &edx); + + /* EAX[0:4] gives type of cache */ + if (!(eax & 0x1f)) + break; + + prev_eax = eax; + } + nshared = ((prev_eax >> 14) & 0xfff) + 1; + uncore->id = apicid - (apicid % nshared); uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_llc); @@ -555,7 +568,7 @@ static int __init amd_uncore_init(void) ret = 0; } - if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) { + if (boot_cpu_has(X86_FEATURE_PERFCTR_LLC)) { amd_uncore_llc = alloc_percpu(struct amd_uncore *); if (!amd_uncore_llc) { ret = -ENOMEM; diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 8e3db8f642a7a02dd8f99db3a25dedbfd1deb01a..80534d3c2480013caa8b170c09c0803b7fef55b9 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -487,22 +487,28 @@ static inline int precise_br_compat(struct perf_event *event) return m == b; } -int x86_pmu_hw_config(struct perf_event *event) +int x86_pmu_max_precise(void) { - if (event->attr.precise_ip) { - int precise = 0; + int precise = 0; - /* Support for constant skid */ - if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { + /* Support for constant skid */ + if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { + precise++; + + /* Support for IP fixup */ + if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2) precise++; - /* Support for IP fixup */ - if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2) - precise++; + if (x86_pmu.pebs_prec_dist) + precise++; + } + return precise; +} - if (x86_pmu.pebs_prec_dist) - precise++; - } +int x86_pmu_hw_config(struct perf_event *event) +{ + if (event->attr.precise_ip) { + int precise = x86_pmu_max_precise(); if (event->attr.precise_ip > precise) return -EOPNOTSUPP; @@ -1751,6 +1757,7 @@ ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event) } static struct attribute_group x86_pmu_attr_group; +static struct attribute_group x86_pmu_caps_group; static int __init init_hw_perf_events(void) { @@ -1799,6 +1806,14 @@ static int __init init_hw_perf_events(void) x86_pmu_format_group.attrs = x86_pmu.format_attrs; + if (x86_pmu.caps_attrs) { + struct attribute **tmp; + + tmp = merge_attr(x86_pmu_caps_group.attrs, x86_pmu.caps_attrs); + if (!WARN_ON(!tmp)) + x86_pmu_caps_group.attrs = tmp; + } + if (x86_pmu.event_attrs) x86_pmu_events_group.attrs = x86_pmu.event_attrs; @@ -2114,7 +2129,7 @@ static void refresh_pce(void *ignored) load_mm_cr4(this_cpu_read(cpu_tlbstate.loaded_mm)); } -static void x86_pmu_event_mapped(struct perf_event *event) +static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm) { if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) return; @@ -2129,22 +2144,20 @@ static void x86_pmu_event_mapped(struct perf_event *event) * For now, this can't happen because all callers hold mmap_sem * for write. If this changes, we'll need a different solution. */ - lockdep_assert_held_exclusive(¤t->mm->mmap_sem); + lockdep_assert_held_exclusive(&mm->mmap_sem); - if (atomic_inc_return(¤t->mm->context.perf_rdpmc_allowed) == 1) - on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1); + if (atomic_inc_return(&mm->context.perf_rdpmc_allowed) == 1) + on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1); } -static void x86_pmu_event_unmapped(struct perf_event *event) +static void x86_pmu_event_unmapped(struct perf_event *event, struct mm_struct *mm) { - if (!current->mm) - return; if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) return; - if (atomic_dec_and_test(¤t->mm->context.perf_rdpmc_allowed)) - on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1); + if (atomic_dec_and_test(&mm->context.perf_rdpmc_allowed)) + on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1); } static int x86_pmu_event_idx(struct perf_event *event) @@ -2215,10 +2228,30 @@ static struct attribute_group x86_pmu_attr_group = { .attrs = x86_pmu_attrs, }; +static ssize_t max_precise_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu_max_precise()); +} + +static DEVICE_ATTR_RO(max_precise); + +static struct attribute *x86_pmu_caps_attrs[] = { + &dev_attr_max_precise.attr, + NULL +}; + +static struct attribute_group x86_pmu_caps_group = { + .name = "caps", + .attrs = x86_pmu_caps_attrs, +}; + static const struct attribute_group *x86_pmu_attr_groups[] = { &x86_pmu_attr_group, &x86_pmu_format_group, &x86_pmu_events_group, + &x86_pmu_caps_group, NULL, }; @@ -2337,12 +2370,9 @@ static unsigned long get_segment_base(unsigned int segment) #ifdef CONFIG_MODIFY_LDT_SYSCALL struct ldt_struct *ldt; - if (idx > LDT_ENTRIES) - return 0; - /* IRQs are off, so this synchronizes with smp_store_release */ ldt = lockless_dereference(current->active_mm->context.ldt); - if (!ldt || idx > ldt->nr_entries) + if (!ldt || idx >= ldt->nr_entries) return 0; desc = &ldt->entries[idx]; @@ -2350,7 +2380,7 @@ static unsigned long get_segment_base(unsigned int segment) return 0; #endif } else { - if (idx > GDT_ENTRIES) + if (idx >= GDT_ENTRIES) return 0; desc = raw_cpu_ptr(gdt_page.gdt) + idx; diff --git a/arch/x86/events/intel/Makefile b/arch/x86/events/intel/Makefile index 06c2baa518144336133f775299b086d0ac4306ec..e9d8520a801aa548764410e4ea914839953ee802 100644 --- a/arch/x86/events/intel/Makefile +++ b/arch/x86/events/intel/Makefile @@ -1,4 +1,4 @@ -obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o +obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o obj-$(CONFIG_CPU_SUP_INTEL) += ds.o knc.o obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl-perf.o diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index 8ae8c5ce3a1f94debb2fe81f5652cbd7b35f2c4a..16076eb34699691ce8d150ae82fc93b34d46b895 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c @@ -69,7 +69,7 @@ struct bts_buffer { struct bts_phys buf[0]; }; -struct pmu bts_pmu; +static struct pmu bts_pmu; static size_t buf_size(struct page *page) { @@ -268,7 +268,7 @@ static void bts_event_start(struct perf_event *event, int flags) bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum; bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold; - event->hw.itrace_started = 1; + perf_event_itrace_started(event); event->hw.state = 0; __bts_event_start(event); diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 98b0f072952735da9928970093ac1857bb9a932a..9fb9a1f1e47bd0d0db3f9be9d4722f956d48dcfe 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3415,12 +3415,26 @@ static struct attribute *intel_arch3_formats_attr[] = { &format_attr_any.attr, &format_attr_inv.attr, &format_attr_cmask.attr, + NULL, +}; + +static struct attribute *hsw_format_attr[] = { &format_attr_in_tx.attr, &format_attr_in_tx_cp.attr, + &format_attr_offcore_rsp.attr, + &format_attr_ldlat.attr, + NULL +}; - &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ - &format_attr_ldlat.attr, /* PEBS load latency */ - NULL, +static struct attribute *nhm_format_attr[] = { + &format_attr_offcore_rsp.attr, + &format_attr_ldlat.attr, + NULL +}; + +static struct attribute *slm_format_attr[] = { + &format_attr_offcore_rsp.attr, + NULL }; static struct attribute *skl_format_attr[] = { @@ -3781,6 +3795,36 @@ static ssize_t freeze_on_smi_store(struct device *cdev, static DEVICE_ATTR_RW(freeze_on_smi); +static ssize_t branches_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu.lbr_nr); +} + +static DEVICE_ATTR_RO(branches); + +static struct attribute *lbr_attrs[] = { + &dev_attr_branches.attr, + NULL +}; + +static char pmu_name_str[30]; + +static ssize_t pmu_name_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", pmu_name_str); +} + +static DEVICE_ATTR_RO(pmu_name); + +static struct attribute *intel_pmu_caps_attrs[] = { + &dev_attr_pmu_name.attr, + NULL +}; + static struct attribute *intel_pmu_attrs[] = { &dev_attr_freeze_on_smi.attr, NULL, @@ -3795,6 +3839,8 @@ __init int intel_pmu_init(void) unsigned int unused; struct extra_reg *er; int version, i; + struct attribute **extra_attr = NULL; + char *name; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { switch (boot_cpu_data.x86) { @@ -3862,6 +3908,7 @@ __init int intel_pmu_init(void) switch (boot_cpu_data.x86_model) { case INTEL_FAM6_CORE_YONAH: pr_cont("Core events, "); + name = "core"; break; case INTEL_FAM6_CORE2_MEROM: @@ -3877,6 +3924,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_core2_event_constraints; x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints; pr_cont("Core2 events, "); + name = "core2"; break; case INTEL_FAM6_NEHALEM: @@ -3905,8 +3953,11 @@ __init int intel_pmu_init(void) intel_pmu_pebs_data_source_nhm(); x86_add_quirk(intel_nehalem_quirk); + x86_pmu.pebs_no_tlb = 1; + extra_attr = nhm_format_attr; pr_cont("Nehalem events, "); + name = "nehalem"; break; case INTEL_FAM6_ATOM_PINEVIEW: @@ -3923,6 +3974,7 @@ __init int intel_pmu_init(void) x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints; x86_pmu.pebs_aliases = intel_pebs_aliases_core2; pr_cont("Atom events, "); + name = "bonnell"; break; case INTEL_FAM6_ATOM_SILVERMONT1: @@ -3940,7 +3992,9 @@ __init int intel_pmu_init(void) x86_pmu.extra_regs = intel_slm_extra_regs; x86_pmu.flags |= PMU_FL_HAS_RSP_1; x86_pmu.cpu_events = slm_events_attrs; + extra_attr = slm_format_attr; pr_cont("Silvermont events, "); + name = "silvermont"; break; case INTEL_FAM6_ATOM_GOLDMONT: @@ -3965,7 +4019,9 @@ __init int intel_pmu_init(void) x86_pmu.lbr_pt_coexist = true; x86_pmu.flags |= PMU_FL_HAS_RSP_1; x86_pmu.cpu_events = glm_events_attrs; + extra_attr = slm_format_attr; pr_cont("Goldmont events, "); + name = "goldmont"; break; case INTEL_FAM6_ATOM_GEMINI_LAKE: @@ -3991,7 +4047,9 @@ __init int intel_pmu_init(void) x86_pmu.cpu_events = glm_events_attrs; /* Goldmont Plus has 4-wide pipeline */ event_attr_td_total_slots_scale_glm.event_str = "4"; + extra_attr = slm_format_attr; pr_cont("Goldmont plus events, "); + name = "goldmont_plus"; break; case INTEL_FAM6_WESTMERE: @@ -4020,7 +4078,9 @@ __init int intel_pmu_init(void) X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1); intel_pmu_pebs_data_source_nhm(); + extra_attr = nhm_format_attr; pr_cont("Westmere events, "); + name = "westmere"; break; case INTEL_FAM6_SANDYBRIDGE: @@ -4056,7 +4116,10 @@ __init int intel_pmu_init(void) intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = X86_CONFIG(.event=0xb1, .umask=0x01, .inv=1, .cmask=1); + extra_attr = nhm_format_attr; + pr_cont("SandyBridge events, "); + name = "sandybridge"; break; case INTEL_FAM6_IVYBRIDGE: @@ -4090,7 +4153,10 @@ __init int intel_pmu_init(void) intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); + extra_attr = nhm_format_attr; + pr_cont("IvyBridge events, "); + name = "ivybridge"; break; @@ -4118,7 +4184,10 @@ __init int intel_pmu_init(void) x86_pmu.get_event_constraints = hsw_get_event_constraints; x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.lbr_double_abort = true; + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; pr_cont("Haswell events, "); + name = "haswell"; break; case INTEL_FAM6_BROADWELL_CORE: @@ -4154,7 +4223,10 @@ __init int intel_pmu_init(void) x86_pmu.get_event_constraints = hsw_get_event_constraints; x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.limit_period = bdw_limit_period; + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; pr_cont("Broadwell events, "); + name = "broadwell"; break; case INTEL_FAM6_XEON_PHI_KNL: @@ -4172,8 +4244,9 @@ __init int intel_pmu_init(void) /* all extra regs are per-cpu when HT is on */ x86_pmu.flags |= PMU_FL_HAS_RSP_1; x86_pmu.flags |= PMU_FL_NO_HT_SHARING; - + extra_attr = slm_format_attr; pr_cont("Knights Landing/Mill events, "); + name = "knights-landing"; break; case INTEL_FAM6_SKYLAKE_MOBILE: @@ -4203,11 +4276,14 @@ __init int intel_pmu_init(void) x86_pmu.hw_config = hsw_hw_config; x86_pmu.get_event_constraints = hsw_get_event_constraints; - x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr, - skl_format_attr); - WARN_ON(!x86_pmu.format_attrs); + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; + extra_attr = merge_attr(extra_attr, skl_format_attr); x86_pmu.cpu_events = hsw_events_attrs; + intel_pmu_pebs_data_source_skl( + boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); pr_cont("Skylake events, "); + name = "skylake"; break; default: @@ -4215,6 +4291,7 @@ __init int intel_pmu_init(void) case 1: x86_pmu.event_constraints = intel_v1_event_constraints; pr_cont("generic architected perfmon v1, "); + name = "generic_arch_v1"; break; default: /* @@ -4222,10 +4299,19 @@ __init int intel_pmu_init(void) */ x86_pmu.event_constraints = intel_gen_event_constraints; pr_cont("generic architected perfmon, "); + name = "generic_arch_v2+"; break; } } + snprintf(pmu_name_str, sizeof pmu_name_str, "%s", name); + + if (version >= 2 && extra_attr) { + x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr, + extra_attr); + WARN_ON(!x86_pmu.format_attrs); + } + if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC); @@ -4272,8 +4358,13 @@ __init int intel_pmu_init(void) x86_pmu.lbr_nr = 0; } - if (x86_pmu.lbr_nr) + x86_pmu.caps_attrs = intel_pmu_caps_attrs; + + if (x86_pmu.lbr_nr) { + x86_pmu.caps_attrs = merge_attr(x86_pmu.caps_attrs, lbr_attrs); pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr); + } + /* * Access extra MSR may cause #GP under certain circumstances. * E.g. KVM doesn't support offcore event @@ -4318,10 +4409,9 @@ static __init int fixup_ht_bug(void) return 0; } - if (lockup_detector_suspend() != 0) { - pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n"); - return 0; - } + cpus_read_lock(); + + hardlockup_detector_perf_stop(); x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED); @@ -4329,9 +4419,7 @@ static __init int fixup_ht_bug(void) x86_pmu.commit_scheduling = NULL; x86_pmu.stop_scheduling = NULL; - lockup_detector_resume(); - - cpus_read_lock(); + hardlockup_detector_perf_restart(); for_each_online_cpu(c) free_excl_cntrs(c); diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c deleted file mode 100644 index 2521f771f2f51be3f3035e09d8d181bccadf15bb..0000000000000000000000000000000000000000 --- a/arch/x86/events/intel/cqm.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* - * Intel Cache Quality-of-Service Monitoring (CQM) support. - * - * Based very, very heavily on work by Peter Zijlstra. - */ - -#include -#include -#include -#include -#include "../perf_event.h" - -#define MSR_IA32_QM_CTR 0x0c8e -#define MSR_IA32_QM_EVTSEL 0x0c8d - -#define MBM_CNTR_WIDTH 24 -/* - * Guaranteed time in ms as per SDM where MBM counters will not overflow. - */ -#define MBM_CTR_OVERFLOW_TIME 1000 - -static u32 cqm_max_rmid = -1; -static unsigned int cqm_l3_scale; /* supposedly cacheline size */ -static bool cqm_enabled, mbm_enabled; -unsigned int mbm_socket_max; - -/* - * The cached intel_pqr_state is strictly per CPU and can never be - * updated from a remote CPU. Both functions which modify the state - * (intel_cqm_event_start and intel_cqm_event_stop) are called with - * interrupts disabled, which is sufficient for the protection. - */ -DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); -static struct hrtimer *mbm_timers; -/** - * struct sample - mbm event's (local or total) data - * @total_bytes #bytes since we began monitoring - * @prev_msr previous value of MSR - */ -struct sample { - u64 total_bytes; - u64 prev_msr; -}; - -/* - * samples profiled for total memory bandwidth type events - */ -static struct sample *mbm_total; -/* - * samples profiled for local memory bandwidth type events - */ -static struct sample *mbm_local; - -#define pkg_id topology_physical_package_id(smp_processor_id()) -/* - * rmid_2_index returns the index for the rmid in mbm_local/mbm_total array. - * mbm_total[] and mbm_local[] are linearly indexed by socket# * max number of - * rmids per socket, an example is given below - * RMID1 of Socket0: vrmid = 1 - * RMID1 of Socket1: vrmid = 1 * (cqm_max_rmid + 1) + 1 - * RMID1 of Socket2: vrmid = 2 * (cqm_max_rmid + 1) + 1 - */ -#define rmid_2_index(rmid) ((pkg_id * (cqm_max_rmid + 1)) + rmid) -/* - * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru. - * Also protects event->hw.cqm_rmid - * - * Hold either for stability, both for modification of ->hw.cqm_rmid. - */ -static DEFINE_MUTEX(cache_mutex); -static DEFINE_RAW_SPINLOCK(cache_lock); - -/* - * Groups of events that have the same target(s), one RMID per group. - */ -static LIST_HEAD(cache_groups); - -/* - * Mask of CPUs for reading CQM values. We only need one per-socket. - */ -static cpumask_t cqm_cpumask; - -#define RMID_VAL_ERROR (1ULL << 63) -#define RMID_VAL_UNAVAIL (1ULL << 62) - -/* - * Event IDs are used to program IA32_QM_EVTSEL before reading event - * counter from IA32_QM_CTR - */ -#define QOS_L3_OCCUP_EVENT_ID 0x01 -#define QOS_MBM_TOTAL_EVENT_ID 0x02 -#define QOS_MBM_LOCAL_EVENT_ID 0x03 - -/* - * This is central to the rotation algorithm in __intel_cqm_rmid_rotate(). - * - * This rmid is always free and is guaranteed to have an associated - * near-zero occupancy value, i.e. no cachelines are tagged with this - * RMID, once __intel_cqm_rmid_rotate() returns. - */ -static u32 intel_cqm_rotation_rmid; - -#define INVALID_RMID (-1) - -/* - * Is @rmid valid for programming the hardware? - * - * rmid 0 is reserved by the hardware for all non-monitored tasks, which - * means that we should never come across an rmid with that value. - * Likewise, an rmid value of -1 is used to indicate "no rmid currently - * assigned" and is used as part of the rotation code. - */ -static inline bool __rmid_valid(u32 rmid) -{ - if (!rmid || rmid == INVALID_RMID) - return false; - - return true; -} - -static u64 __rmid_read(u32 rmid) -{ - u64 val; - - /* - * Ignore the SDM, this thing is _NOTHING_ like a regular perfcnt, - * it just says that to increase confusion. - */ - wrmsr(MSR_IA32_QM_EVTSEL, QOS_L3_OCCUP_EVENT_ID, rmid); - rdmsrl(MSR_IA32_QM_CTR, val); - - /* - * Aside from the ERROR and UNAVAIL bits, assume this thing returns - * the number of cachelines tagged with @rmid. - */ - return val; -} - -enum rmid_recycle_state { - RMID_YOUNG = 0, - RMID_AVAILABLE, - RMID_DIRTY, -}; - -struct cqm_rmid_entry { - u32 rmid; - enum rmid_recycle_state state; - struct list_head list; - unsigned long queue_time; -}; - -/* - * cqm_rmid_free_lru - A least recently used list of RMIDs. - * - * Oldest entry at the head, newest (most recently used) entry at the - * tail. This list is never traversed, it's only used to keep track of - * the lru order. That is, we only pick entries of the head or insert - * them on the tail. - * - * All entries on the list are 'free', and their RMIDs are not currently - * in use. To mark an RMID as in use, remove its entry from the lru - * list. - * - * - * cqm_rmid_limbo_lru - list of currently unused but (potentially) dirty RMIDs. - * - * This list is contains RMIDs that no one is currently using but that - * may have a non-zero occupancy value associated with them. The - * rotation worker moves RMIDs from the limbo list to the free list once - * the occupancy value drops below __intel_cqm_threshold. - * - * Both lists are protected by cache_mutex. - */ -static LIST_HEAD(cqm_rmid_free_lru); -static LIST_HEAD(cqm_rmid_limbo_lru); - -/* - * We use a simple array of pointers so that we can lookup a struct - * cqm_rmid_entry in O(1). This alleviates the callers of __get_rmid() - * and __put_rmid() from having to worry about dealing with struct - * cqm_rmid_entry - they just deal with rmids, i.e. integers. - * - * Once this array is initialized it is read-only. No locks are required - * to access it. - * - * All entries for all RMIDs can be looked up in the this array at all - * times. - */ -static struct cqm_rmid_entry **cqm_rmid_ptrs; - -static inline struct cqm_rmid_entry *__rmid_entry(u32 rmid) -{ - struct cqm_rmid_entry *entry; - - entry = cqm_rmid_ptrs[rmid]; - WARN_ON(entry->rmid != rmid); - - return entry; -} - -/* - * Returns < 0 on fail. - * - * We expect to be called with cache_mutex held. - */ -static u32 __get_rmid(void) -{ - struct cqm_rmid_entry *entry; - - lockdep_assert_held(&cache_mutex); - - if (list_empty(&cqm_rmid_free_lru)) - return INVALID_RMID; - - entry = list_first_entry(&cqm_rmid_free_lru, struct cqm_rmid_entry, list); - list_del(&entry->list); - - return entry->rmid; -} - -static void __put_rmid(u32 rmid) -{ - struct cqm_rmid_entry *entry; - - lockdep_assert_held(&cache_mutex); - - WARN_ON(!__rmid_valid(rmid)); - entry = __rmid_entry(rmid); - - entry->queue_time = jiffies; - entry->state = RMID_YOUNG; - - list_add_tail(&entry->list, &cqm_rmid_limbo_lru); -} - -static void cqm_cleanup(void) -{ - int i; - - if (!cqm_rmid_ptrs) - return; - - for (i = 0; i < cqm_max_rmid; i++) - kfree(cqm_rmid_ptrs[i]); - - kfree(cqm_rmid_ptrs); - cqm_rmid_ptrs = NULL; - cqm_enabled = false; -} - -static int intel_cqm_setup_rmid_cache(void) -{ - struct cqm_rmid_entry *entry; - unsigned int nr_rmids; - int r = 0; - - nr_rmids = cqm_max_rmid + 1; - cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) * - nr_rmids, GFP_KERNEL); - if (!cqm_rmid_ptrs) - return -ENOMEM; - - for (; r <= cqm_max_rmid; r++) { - struct cqm_rmid_entry *entry; - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - goto fail; - - INIT_LIST_HEAD(&entry->list); - entry->rmid = r; - cqm_rmid_ptrs[r] = entry; - - list_add_tail(&entry->list, &cqm_rmid_free_lru); - } - - /* - * RMID 0 is special and is always allocated. It's used for all - * tasks that are not monitored. - */ - entry = __rmid_entry(0); - list_del(&entry->list); - - mutex_lock(&cache_mutex); - intel_cqm_rotation_rmid = __get_rmid(); - mutex_unlock(&cache_mutex); - - return 0; - -fail: - cqm_cleanup(); - return -ENOMEM; -} - -/* - * Determine if @a and @b measure the same set of tasks. - * - * If @a and @b measure the same set of tasks then we want to share a - * single RMID. - */ -static bool __match_event(struct perf_event *a, struct perf_event *b) -{ - /* Per-cpu and task events don't mix */ - if ((a->attach_state & PERF_ATTACH_TASK) != - (b->attach_state & PERF_ATTACH_TASK)) - return false; - -#ifdef CONFIG_CGROUP_PERF - if (a->cgrp != b->cgrp) - return false; -#endif - - /* If not task event, we're machine wide */ - if (!(b->attach_state & PERF_ATTACH_TASK)) - return true; - - /* - * Events that target same task are placed into the same cache group. - * Mark it as a multi event group, so that we update ->count - * for every event rather than just the group leader later. - */ - if (a->hw.target == b->hw.target) { - b->hw.is_group_event = true; - return true; - } - - /* - * Are we an inherited event? - */ - if (b->parent == a) - return true; - - return false; -} - -#ifdef CONFIG_CGROUP_PERF -static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event) -{ - if (event->attach_state & PERF_ATTACH_TASK) - return perf_cgroup_from_task(event->hw.target, event->ctx); - - return event->cgrp; -} -#endif - -/* - * Determine if @a's tasks intersect with @b's tasks - * - * There are combinations of events that we explicitly prohibit, - * - * PROHIBITS - * system-wide -> cgroup and task - * cgroup -> system-wide - * -> task in cgroup - * task -> system-wide - * -> task in cgroup - * - * Call this function before allocating an RMID. - */ -static bool __conflict_event(struct perf_event *a, struct perf_event *b) -{ -#ifdef CONFIG_CGROUP_PERF - /* - * We can have any number of cgroups but only one system-wide - * event at a time. - */ - if (a->cgrp && b->cgrp) { - struct perf_cgroup *ac = a->cgrp; - struct perf_cgroup *bc = b->cgrp; - - /* - * This condition should have been caught in - * __match_event() and we should be sharing an RMID. - */ - WARN_ON_ONCE(ac == bc); - - if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) || - cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup)) - return true; - - return false; - } - - if (a->cgrp || b->cgrp) { - struct perf_cgroup *ac, *bc; - - /* - * cgroup and system-wide events are mutually exclusive - */ - if ((a->cgrp && !(b->attach_state & PERF_ATTACH_TASK)) || - (b->cgrp && !(a->attach_state & PERF_ATTACH_TASK))) - return true; - - /* - * Ensure neither event is part of the other's cgroup - */ - ac = event_to_cgroup(a); - bc = event_to_cgroup(b); - if (ac == bc) - return true; - - /* - * Must have cgroup and non-intersecting task events. - */ - if (!ac || !bc) - return false; - - /* - * We have cgroup and task events, and the task belongs - * to a cgroup. Check for for overlap. - */ - if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) || - cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup)) - return true; - - return false; - } -#endif - /* - * If one of them is not a task, same story as above with cgroups. - */ - if (!(a->attach_state & PERF_ATTACH_TASK) || - !(b->attach_state & PERF_ATTACH_TASK)) - return true; - - /* - * Must be non-overlapping. - */ - return false; -} - -struct rmid_read { - u32 rmid; - u32 evt_type; - atomic64_t value; -}; - -static void __intel_cqm_event_count(void *info); -static void init_mbm_sample(u32 rmid, u32 evt_type); -static void __intel_mbm_event_count(void *info); - -static bool is_cqm_event(int e) -{ - return (e == QOS_L3_OCCUP_EVENT_ID); -} - -static bool is_mbm_event(int e) -{ - return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID); -} - -static void cqm_mask_call(struct rmid_read *rr) -{ - if (is_mbm_event(rr->evt_type)) - on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count, rr, 1); - else - on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, rr, 1); -} - -/* - * Exchange the RMID of a group of events. - */ -static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid) -{ - struct perf_event *event; - struct list_head *head = &group->hw.cqm_group_entry; - u32 old_rmid = group->hw.cqm_rmid; - - lockdep_assert_held(&cache_mutex); - - /* - * If our RMID is being deallocated, perform a read now. - */ - if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) { - struct rmid_read rr = { - .rmid = old_rmid, - .evt_type = group->attr.config, - .value = ATOMIC64_INIT(0), - }; - - cqm_mask_call(&rr); - local64_set(&group->count, atomic64_read(&rr.value)); - } - - raw_spin_lock_irq(&cache_lock); - - group->hw.cqm_rmid = rmid; - list_for_each_entry(event, head, hw.cqm_group_entry) - event->hw.cqm_rmid = rmid; - - raw_spin_unlock_irq(&cache_lock); - - /* - * If the allocation is for mbm, init the mbm stats. - * Need to check if each event in the group is mbm event - * because there could be multiple type of events in the same group. - */ - if (__rmid_valid(rmid)) { - event = group; - if (is_mbm_event(event->attr.config)) - init_mbm_sample(rmid, event->attr.config); - - list_for_each_entry(event, head, hw.cqm_group_entry) { - if (is_mbm_event(event->attr.config)) - init_mbm_sample(rmid, event->attr.config); - } - } - - return old_rmid; -} - -/* - * If we fail to assign a new RMID for intel_cqm_rotation_rmid because - * cachelines are still tagged with RMIDs in limbo, we progressively - * increment the threshold until we find an RMID in limbo with <= - * __intel_cqm_threshold lines tagged. This is designed to mitigate the - * problem where cachelines tagged with an RMID are not steadily being - * evicted. - * - * On successful rotations we decrease the threshold back towards zero. - * - * __intel_cqm_max_threshold provides an upper bound on the threshold, - * and is measured in bytes because it's exposed to userland. - */ -static unsigned int __intel_cqm_threshold; -static unsigned int __intel_cqm_max_threshold; - -/* - * Test whether an RMID has a zero occupancy value on this cpu. - */ -static void intel_cqm_stable(void *arg) -{ - struct cqm_rmid_entry *entry; - - list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) { - if (entry->state != RMID_AVAILABLE) - break; - - if (__rmid_read(entry->rmid) > __intel_cqm_threshold) - entry->state = RMID_DIRTY; - } -} - -/* - * If we have group events waiting for an RMID that don't conflict with - * events already running, assign @rmid. - */ -static bool intel_cqm_sched_in_event(u32 rmid) -{ - struct perf_event *leader, *event; - - lockdep_assert_held(&cache_mutex); - - leader = list_first_entry(&cache_groups, struct perf_event, - hw.cqm_groups_entry); - event = leader; - - list_for_each_entry_continue(event, &cache_groups, - hw.cqm_groups_entry) { - if (__rmid_valid(event->hw.cqm_rmid)) - continue; - - if (__conflict_event(event, leader)) - continue; - - intel_cqm_xchg_rmid(event, rmid); - return true; - } - - return false; -} - -/* - * Initially use this constant for both the limbo queue time and the - * rotation timer interval, pmu::hrtimer_interval_ms. - * - * They don't need to be the same, but the two are related since if you - * rotate faster than you recycle RMIDs, you may run out of available - * RMIDs. - */ -#define RMID_DEFAULT_QUEUE_TIME 250 /* ms */ - -static unsigned int __rmid_queue_time_ms = RMID_DEFAULT_QUEUE_TIME; - -/* - * intel_cqm_rmid_stabilize - move RMIDs from limbo to free list - * @nr_available: number of freeable RMIDs on the limbo list - * - * Quiescent state; wait for all 'freed' RMIDs to become unused, i.e. no - * cachelines are tagged with those RMIDs. After this we can reuse them - * and know that the current set of active RMIDs is stable. - * - * Return %true or %false depending on whether stabilization needs to be - * reattempted. - * - * If we return %true then @nr_available is updated to indicate the - * number of RMIDs on the limbo list that have been queued for the - * minimum queue time (RMID_AVAILABLE), but whose data occupancy values - * are above __intel_cqm_threshold. - */ -static bool intel_cqm_rmid_stabilize(unsigned int *available) -{ - struct cqm_rmid_entry *entry, *tmp; - - lockdep_assert_held(&cache_mutex); - - *available = 0; - list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) { - unsigned long min_queue_time; - unsigned long now = jiffies; - - /* - * We hold RMIDs placed into limbo for a minimum queue - * time. Before the minimum queue time has elapsed we do - * not recycle RMIDs. - * - * The reasoning is that until a sufficient time has - * passed since we stopped using an RMID, any RMID - * placed onto the limbo list will likely still have - * data tagged in the cache, which means we'll probably - * fail to recycle it anyway. - * - * We can save ourselves an expensive IPI by skipping - * any RMIDs that have not been queued for the minimum - * time. - */ - min_queue_time = entry->queue_time + - msecs_to_jiffies(__rmid_queue_time_ms); - - if (time_after(min_queue_time, now)) - break; - - entry->state = RMID_AVAILABLE; - (*available)++; - } - - /* - * Fast return if none of the RMIDs on the limbo list have been - * sitting on the queue for the minimum queue time. - */ - if (!*available) - return false; - - /* - * Test whether an RMID is free for each package. - */ - on_each_cpu_mask(&cqm_cpumask, intel_cqm_stable, NULL, true); - - list_for_each_entry_safe(entry, tmp, &cqm_rmid_limbo_lru, list) { - /* - * Exhausted all RMIDs that have waited min queue time. - */ - if (entry->state == RMID_YOUNG) - break; - - if (entry->state == RMID_DIRTY) - continue; - - list_del(&entry->list); /* remove from limbo */ - - /* - * The rotation RMID gets priority if it's - * currently invalid. In which case, skip adding - * the RMID to the the free lru. - */ - if (!__rmid_valid(intel_cqm_rotation_rmid)) { - intel_cqm_rotation_rmid = entry->rmid; - continue; - } - - /* - * If we have groups waiting for RMIDs, hand - * them one now provided they don't conflict. - */ - if (intel_cqm_sched_in_event(entry->rmid)) - continue; - - /* - * Otherwise place it onto the free list. - */ - list_add_tail(&entry->list, &cqm_rmid_free_lru); - } - - - return __rmid_valid(intel_cqm_rotation_rmid); -} - -/* - * Pick a victim group and move it to the tail of the group list. - * @next: The first group without an RMID - */ -static void __intel_cqm_pick_and_rotate(struct perf_event *next) -{ - struct perf_event *rotor; - u32 rmid; - - lockdep_assert_held(&cache_mutex); - - rotor = list_first_entry(&cache_groups, struct perf_event, - hw.cqm_groups_entry); - - /* - * The group at the front of the list should always have a valid - * RMID. If it doesn't then no groups have RMIDs assigned and we - * don't need to rotate the list. - */ - if (next == rotor) - return; - - rmid = intel_cqm_xchg_rmid(rotor, INVALID_RMID); - __put_rmid(rmid); - - list_rotate_left(&cache_groups); -} - -/* - * Deallocate the RMIDs from any events that conflict with @event, and - * place them on the back of the group list. - */ -static void intel_cqm_sched_out_conflicting_events(struct perf_event *event) -{ - struct perf_event *group, *g; - u32 rmid; - - lockdep_assert_held(&cache_mutex); - - list_for_each_entry_safe(group, g, &cache_groups, hw.cqm_groups_entry) { - if (group == event) - continue; - - rmid = group->hw.cqm_rmid; - - /* - * Skip events that don't have a valid RMID. - */ - if (!__rmid_valid(rmid)) - continue; - - /* - * No conflict? No problem! Leave the event alone. - */ - if (!__conflict_event(group, event)) - continue; - - intel_cqm_xchg_rmid(group, INVALID_RMID); - __put_rmid(rmid); - } -} - -/* - * Attempt to rotate the groups and assign new RMIDs. - * - * We rotate for two reasons, - * 1. To handle the scheduling of conflicting events - * 2. To recycle RMIDs - * - * Rotating RMIDs is complicated because the hardware doesn't give us - * any clues. - * - * There's problems with the hardware interface; when you change the - * task:RMID map cachelines retain their 'old' tags, giving a skewed - * picture. In order to work around this, we must always keep one free - * RMID - intel_cqm_rotation_rmid. - * - * Rotation works by taking away an RMID from a group (the old RMID), - * and assigning the free RMID to another group (the new RMID). We must - * then wait for the old RMID to not be used (no cachelines tagged). - * This ensure that all cachelines are tagged with 'active' RMIDs. At - * this point we can start reading values for the new RMID and treat the - * old RMID as the free RMID for the next rotation. - * - * Return %true or %false depending on whether we did any rotating. - */ -static bool __intel_cqm_rmid_rotate(void) -{ - struct perf_event *group, *start = NULL; - unsigned int threshold_limit; - unsigned int nr_needed = 0; - unsigned int nr_available; - bool rotated = false; - - mutex_lock(&cache_mutex); - -again: - /* - * Fast path through this function if there are no groups and no - * RMIDs that need cleaning. - */ - if (list_empty(&cache_groups) && list_empty(&cqm_rmid_limbo_lru)) - goto out; - - list_for_each_entry(group, &cache_groups, hw.cqm_groups_entry) { - if (!__rmid_valid(group->hw.cqm_rmid)) { - if (!start) - start = group; - nr_needed++; - } - } - - /* - * We have some event groups, but they all have RMIDs assigned - * and no RMIDs need cleaning. - */ - if (!nr_needed && list_empty(&cqm_rmid_limbo_lru)) - goto out; - - if (!nr_needed) - goto stabilize; - - /* - * We have more event groups without RMIDs than available RMIDs, - * or we have event groups that conflict with the ones currently - * scheduled. - * - * We force deallocate the rmid of the group at the head of - * cache_groups. The first event group without an RMID then gets - * assigned intel_cqm_rotation_rmid. This ensures we always make - * forward progress. - * - * Rotate the cache_groups list so the previous head is now the - * tail. - */ - __intel_cqm_pick_and_rotate(start); - - /* - * If the rotation is going to succeed, reduce the threshold so - * that we don't needlessly reuse dirty RMIDs. - */ - if (__rmid_valid(intel_cqm_rotation_rmid)) { - intel_cqm_xchg_rmid(start, intel_cqm_rotation_rmid); - intel_cqm_rotation_rmid = __get_rmid(); - - intel_cqm_sched_out_conflicting_events(start); - - if (__intel_cqm_threshold) - __intel_cqm_threshold--; - } - - rotated = true; - -stabilize: - /* - * We now need to stablize the RMID we freed above (if any) to - * ensure that the next time we rotate we have an RMID with zero - * occupancy value. - * - * Alternatively, if we didn't need to perform any rotation, - * we'll have a bunch of RMIDs in limbo that need stabilizing. - */ - threshold_limit = __intel_cqm_max_threshold / cqm_l3_scale; - - while (intel_cqm_rmid_stabilize(&nr_available) && - __intel_cqm_threshold < threshold_limit) { - unsigned int steal_limit; - - /* - * Don't spin if nobody is actively waiting for an RMID, - * the rotation worker will be kicked as soon as an - * event needs an RMID anyway. - */ - if (!nr_needed) - break; - - /* Allow max 25% of RMIDs to be in limbo. */ - steal_limit = (cqm_max_rmid + 1) / 4; - - /* - * We failed to stabilize any RMIDs so our rotation - * logic is now stuck. In order to make forward progress - * we have a few options: - * - * 1. rotate ("steal") another RMID - * 2. increase the threshold - * 3. do nothing - * - * We do both of 1. and 2. until we hit the steal limit. - * - * The steal limit prevents all RMIDs ending up on the - * limbo list. This can happen if every RMID has a - * non-zero occupancy above threshold_limit, and the - * occupancy values aren't dropping fast enough. - * - * Note that there is prioritisation at work here - we'd - * rather increase the number of RMIDs on the limbo list - * than increase the threshold, because increasing the - * threshold skews the event data (because we reuse - * dirty RMIDs) - threshold bumps are a last resort. - */ - if (nr_available < steal_limit) - goto again; - - __intel_cqm_threshold++; - } - -out: - mutex_unlock(&cache_mutex); - return rotated; -} - -static void intel_cqm_rmid_rotate(struct work_struct *work); - -static DECLARE_DELAYED_WORK(intel_cqm_rmid_work, intel_cqm_rmid_rotate); - -static struct pmu intel_cqm_pmu; - -static void intel_cqm_rmid_rotate(struct work_struct *work) -{ - unsigned long delay; - - __intel_cqm_rmid_rotate(); - - delay = msecs_to_jiffies(intel_cqm_pmu.hrtimer_interval_ms); - schedule_delayed_work(&intel_cqm_rmid_work, delay); -} - -static u64 update_sample(unsigned int rmid, u32 evt_type, int first) -{ - struct sample *mbm_current; - u32 vrmid = rmid_2_index(rmid); - u64 val, bytes, shift; - u32 eventid; - - if (evt_type == QOS_MBM_LOCAL_EVENT_ID) { - mbm_current = &mbm_local[vrmid]; - eventid = QOS_MBM_LOCAL_EVENT_ID; - } else { - mbm_current = &mbm_total[vrmid]; - eventid = QOS_MBM_TOTAL_EVENT_ID; - } - - wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); - rdmsrl(MSR_IA32_QM_CTR, val); - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - return mbm_current->total_bytes; - - if (first) { - mbm_current->prev_msr = val; - mbm_current->total_bytes = 0; - return mbm_current->total_bytes; - } - - /* - * The h/w guarantees that counters will not overflow - * so long as we poll them at least once per second. - */ - shift = 64 - MBM_CNTR_WIDTH; - bytes = (val << shift) - (mbm_current->prev_msr << shift); - bytes >>= shift; - - bytes *= cqm_l3_scale; - - mbm_current->total_bytes += bytes; - mbm_current->prev_msr = val; - - return mbm_current->total_bytes; -} - -static u64 rmid_read_mbm(unsigned int rmid, u32 evt_type) -{ - return update_sample(rmid, evt_type, 0); -} - -static void __intel_mbm_event_init(void *info) -{ - struct rmid_read *rr = info; - - update_sample(rr->rmid, rr->evt_type, 1); -} - -static void init_mbm_sample(u32 rmid, u32 evt_type) -{ - struct rmid_read rr = { - .rmid = rmid, - .evt_type = evt_type, - .value = ATOMIC64_INIT(0), - }; - - /* on each socket, init sample */ - on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_init, &rr, 1); -} - -/* - * Find a group and setup RMID. - * - * If we're part of a group, we use the group's RMID. - */ -static void intel_cqm_setup_event(struct perf_event *event, - struct perf_event **group) -{ - struct perf_event *iter; - bool conflict = false; - u32 rmid; - - event->hw.is_group_event = false; - list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { - rmid = iter->hw.cqm_rmid; - - if (__match_event(iter, event)) { - /* All tasks in a group share an RMID */ - event->hw.cqm_rmid = rmid; - *group = iter; - if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) - init_mbm_sample(rmid, event->attr.config); - return; - } - - /* - * We only care about conflicts for events that are - * actually scheduled in (and hence have a valid RMID). - */ - if (__conflict_event(iter, event) && __rmid_valid(rmid)) - conflict = true; - } - - if (conflict) - rmid = INVALID_RMID; - else - rmid = __get_rmid(); - - if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) - init_mbm_sample(rmid, event->attr.config); - - event->hw.cqm_rmid = rmid; -} - -static void intel_cqm_event_read(struct perf_event *event) -{ - unsigned long flags; - u32 rmid; - u64 val; - - /* - * Task events are handled by intel_cqm_event_count(). - */ - if (event->cpu == -1) - return; - - raw_spin_lock_irqsave(&cache_lock, flags); - rmid = event->hw.cqm_rmid; - - if (!__rmid_valid(rmid)) - goto out; - - if (is_mbm_event(event->attr.config)) - val = rmid_read_mbm(rmid, event->attr.config); - else - val = __rmid_read(rmid); - - /* - * Ignore this reading on error states and do not update the value. - */ - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - goto out; - - local64_set(&event->count, val); -out: - raw_spin_unlock_irqrestore(&cache_lock, flags); -} - -static void __intel_cqm_event_count(void *info) -{ - struct rmid_read *rr = info; - u64 val; - - val = __rmid_read(rr->rmid); - - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - return; - - atomic64_add(val, &rr->value); -} - -static inline bool cqm_group_leader(struct perf_event *event) -{ - return !list_empty(&event->hw.cqm_groups_entry); -} - -static void __intel_mbm_event_count(void *info) -{ - struct rmid_read *rr = info; - u64 val; - - val = rmid_read_mbm(rr->rmid, rr->evt_type); - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - return; - atomic64_add(val, &rr->value); -} - -static enum hrtimer_restart mbm_hrtimer_handle(struct hrtimer *hrtimer) -{ - struct perf_event *iter, *iter1; - int ret = HRTIMER_RESTART; - struct list_head *head; - unsigned long flags; - u32 grp_rmid; - - /* - * Need to cache_lock as the timer Event Select MSR reads - * can race with the mbm/cqm count() and mbm_init() reads. - */ - raw_spin_lock_irqsave(&cache_lock, flags); - - if (list_empty(&cache_groups)) { - ret = HRTIMER_NORESTART; - goto out; - } - - list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { - grp_rmid = iter->hw.cqm_rmid; - if (!__rmid_valid(grp_rmid)) - continue; - if (is_mbm_event(iter->attr.config)) - update_sample(grp_rmid, iter->attr.config, 0); - - head = &iter->hw.cqm_group_entry; - if (list_empty(head)) - continue; - list_for_each_entry(iter1, head, hw.cqm_group_entry) { - if (!iter1->hw.is_group_event) - break; - if (is_mbm_event(iter1->attr.config)) - update_sample(iter1->hw.cqm_rmid, - iter1->attr.config, 0); - } - } - - hrtimer_forward_now(hrtimer, ms_to_ktime(MBM_CTR_OVERFLOW_TIME)); -out: - raw_spin_unlock_irqrestore(&cache_lock, flags); - - return ret; -} - -static void __mbm_start_timer(void *info) -{ - hrtimer_start(&mbm_timers[pkg_id], ms_to_ktime(MBM_CTR_OVERFLOW_TIME), - HRTIMER_MODE_REL_PINNED); -} - -static void __mbm_stop_timer(void *info) -{ - hrtimer_cancel(&mbm_timers[pkg_id]); -} - -static void mbm_start_timers(void) -{ - on_each_cpu_mask(&cqm_cpumask, __mbm_start_timer, NULL, 1); -} - -static void mbm_stop_timers(void) -{ - on_each_cpu_mask(&cqm_cpumask, __mbm_stop_timer, NULL, 1); -} - -static void mbm_hrtimer_init(void) -{ - struct hrtimer *hr; - int i; - - for (i = 0; i < mbm_socket_max; i++) { - hr = &mbm_timers[i]; - hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hr->function = mbm_hrtimer_handle; - } -} - -static u64 intel_cqm_event_count(struct perf_event *event) -{ - unsigned long flags; - struct rmid_read rr = { - .evt_type = event->attr.config, - .value = ATOMIC64_INIT(0), - }; - - /* - * We only need to worry about task events. System-wide events - * are handled like usual, i.e. entirely with - * intel_cqm_event_read(). - */ - if (event->cpu != -1) - return __perf_event_count(event); - - /* - * Only the group leader gets to report values except in case of - * multiple events in the same group, we still need to read the - * other events.This stops us - * reporting duplicate values to userspace, and gives us a clear - * rule for which task gets to report the values. - * - * Note that it is impossible to attribute these values to - * specific packages - we forfeit that ability when we create - * task events. - */ - if (!cqm_group_leader(event) && !event->hw.is_group_event) - return 0; - - /* - * Getting up-to-date values requires an SMP IPI which is not - * possible if we're being called in interrupt context. Return - * the cached values instead. - */ - if (unlikely(in_interrupt())) - goto out; - - /* - * Notice that we don't perform the reading of an RMID - * atomically, because we can't hold a spin lock across the - * IPIs. - * - * Speculatively perform the read, since @event might be - * assigned a different (possibly invalid) RMID while we're - * busying performing the IPI calls. It's therefore necessary to - * check @event's RMID afterwards, and if it has changed, - * discard the result of the read. - */ - rr.rmid = ACCESS_ONCE(event->hw.cqm_rmid); - - if (!__rmid_valid(rr.rmid)) - goto out; - - cqm_mask_call(&rr); - - raw_spin_lock_irqsave(&cache_lock, flags); - if (event->hw.cqm_rmid == rr.rmid) - local64_set(&event->count, atomic64_read(&rr.value)); - raw_spin_unlock_irqrestore(&cache_lock, flags); -out: - return __perf_event_count(event); -} - -static void intel_cqm_event_start(struct perf_event *event, int mode) -{ - struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - u32 rmid = event->hw.cqm_rmid; - - if (!(event->hw.cqm_state & PERF_HES_STOPPED)) - return; - - event->hw.cqm_state &= ~PERF_HES_STOPPED; - - if (state->rmid_usecnt++) { - if (!WARN_ON_ONCE(state->rmid != rmid)) - return; - } else { - WARN_ON_ONCE(state->rmid); - } - - state->rmid = rmid; - wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid); -} - -static void intel_cqm_event_stop(struct perf_event *event, int mode) -{ - struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - - if (event->hw.cqm_state & PERF_HES_STOPPED) - return; - - event->hw.cqm_state |= PERF_HES_STOPPED; - - intel_cqm_event_read(event); - - if (!--state->rmid_usecnt) { - state->rmid = 0; - wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid); - } else { - WARN_ON_ONCE(!state->rmid); - } -} - -static int intel_cqm_event_add(struct perf_event *event, int mode) -{ - unsigned long flags; - u32 rmid; - - raw_spin_lock_irqsave(&cache_lock, flags); - - event->hw.cqm_state = PERF_HES_STOPPED; - rmid = event->hw.cqm_rmid; - - if (__rmid_valid(rmid) && (mode & PERF_EF_START)) - intel_cqm_event_start(event, mode); - - raw_spin_unlock_irqrestore(&cache_lock, flags); - - return 0; -} - -static void intel_cqm_event_destroy(struct perf_event *event) -{ - struct perf_event *group_other = NULL; - unsigned long flags; - - mutex_lock(&cache_mutex); - /* - * Hold the cache_lock as mbm timer handlers could be - * scanning the list of events. - */ - raw_spin_lock_irqsave(&cache_lock, flags); - - /* - * If there's another event in this group... - */ - if (!list_empty(&event->hw.cqm_group_entry)) { - group_other = list_first_entry(&event->hw.cqm_group_entry, - struct perf_event, - hw.cqm_group_entry); - list_del(&event->hw.cqm_group_entry); - } - - /* - * And we're the group leader.. - */ - if (cqm_group_leader(event)) { - /* - * If there was a group_other, make that leader, otherwise - * destroy the group and return the RMID. - */ - if (group_other) { - list_replace(&event->hw.cqm_groups_entry, - &group_other->hw.cqm_groups_entry); - } else { - u32 rmid = event->hw.cqm_rmid; - - if (__rmid_valid(rmid)) - __put_rmid(rmid); - list_del(&event->hw.cqm_groups_entry); - } - } - - raw_spin_unlock_irqrestore(&cache_lock, flags); - - /* - * Stop the mbm overflow timers when the last event is destroyed. - */ - if (mbm_enabled && list_empty(&cache_groups)) - mbm_stop_timers(); - - mutex_unlock(&cache_mutex); -} - -static int intel_cqm_event_init(struct perf_event *event) -{ - struct perf_event *group = NULL; - bool rotate = false; - unsigned long flags; - - if (event->attr.type != intel_cqm_pmu.type) - return -ENOENT; - - if ((event->attr.config < QOS_L3_OCCUP_EVENT_ID) || - (event->attr.config > QOS_MBM_LOCAL_EVENT_ID)) - return -EINVAL; - - if ((is_cqm_event(event->attr.config) && !cqm_enabled) || - (is_mbm_event(event->attr.config) && !mbm_enabled)) - return -EINVAL; - - /* unsupported modes and filters */ - if (event->attr.exclude_user || - event->attr.exclude_kernel || - event->attr.exclude_hv || - event->attr.exclude_idle || - event->attr.exclude_host || - event->attr.exclude_guest || - event->attr.sample_period) /* no sampling */ - return -EINVAL; - - INIT_LIST_HEAD(&event->hw.cqm_group_entry); - INIT_LIST_HEAD(&event->hw.cqm_groups_entry); - - event->destroy = intel_cqm_event_destroy; - - mutex_lock(&cache_mutex); - - /* - * Start the mbm overflow timers when the first event is created. - */ - if (mbm_enabled && list_empty(&cache_groups)) - mbm_start_timers(); - - /* Will also set rmid */ - intel_cqm_setup_event(event, &group); - - /* - * Hold the cache_lock as mbm timer handlers be - * scanning the list of events. - */ - raw_spin_lock_irqsave(&cache_lock, flags); - - if (group) { - list_add_tail(&event->hw.cqm_group_entry, - &group->hw.cqm_group_entry); - } else { - list_add_tail(&event->hw.cqm_groups_entry, - &cache_groups); - - /* - * All RMIDs are either in use or have recently been - * used. Kick the rotation worker to clean/free some. - * - * We only do this for the group leader, rather than for - * every event in a group to save on needless work. - */ - if (!__rmid_valid(event->hw.cqm_rmid)) - rotate = true; - } - - raw_spin_unlock_irqrestore(&cache_lock, flags); - mutex_unlock(&cache_mutex); - - if (rotate) - schedule_delayed_work(&intel_cqm_rmid_work, 0); - - return 0; -} - -EVENT_ATTR_STR(llc_occupancy, intel_cqm_llc, "event=0x01"); -EVENT_ATTR_STR(llc_occupancy.per-pkg, intel_cqm_llc_pkg, "1"); -EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes"); -EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL); -EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1"); - -EVENT_ATTR_STR(total_bytes, intel_cqm_total_bytes, "event=0x02"); -EVENT_ATTR_STR(total_bytes.per-pkg, intel_cqm_total_bytes_pkg, "1"); -EVENT_ATTR_STR(total_bytes.unit, intel_cqm_total_bytes_unit, "MB"); -EVENT_ATTR_STR(total_bytes.scale, intel_cqm_total_bytes_scale, "1e-6"); - -EVENT_ATTR_STR(local_bytes, intel_cqm_local_bytes, "event=0x03"); -EVENT_ATTR_STR(local_bytes.per-pkg, intel_cqm_local_bytes_pkg, "1"); -EVENT_ATTR_STR(local_bytes.unit, intel_cqm_local_bytes_unit, "MB"); -EVENT_ATTR_STR(local_bytes.scale, intel_cqm_local_bytes_scale, "1e-6"); - -static struct attribute *intel_cqm_events_attr[] = { - EVENT_PTR(intel_cqm_llc), - EVENT_PTR(intel_cqm_llc_pkg), - EVENT_PTR(intel_cqm_llc_unit), - EVENT_PTR(intel_cqm_llc_scale), - EVENT_PTR(intel_cqm_llc_snapshot), - NULL, -}; - -static struct attribute *intel_mbm_events_attr[] = { - EVENT_PTR(intel_cqm_total_bytes), - EVENT_PTR(intel_cqm_local_bytes), - EVENT_PTR(intel_cqm_total_bytes_pkg), - EVENT_PTR(intel_cqm_local_bytes_pkg), - EVENT_PTR(intel_cqm_total_bytes_unit), - EVENT_PTR(intel_cqm_local_bytes_unit), - EVENT_PTR(intel_cqm_total_bytes_scale), - EVENT_PTR(intel_cqm_local_bytes_scale), - NULL, -}; - -static struct attribute *intel_cmt_mbm_events_attr[] = { - EVENT_PTR(intel_cqm_llc), - EVENT_PTR(intel_cqm_total_bytes), - EVENT_PTR(intel_cqm_local_bytes), - EVENT_PTR(intel_cqm_llc_pkg), - EVENT_PTR(intel_cqm_total_bytes_pkg), - EVENT_PTR(intel_cqm_local_bytes_pkg), - EVENT_PTR(intel_cqm_llc_unit), - EVENT_PTR(intel_cqm_total_bytes_unit), - EVENT_PTR(intel_cqm_local_bytes_unit), - EVENT_PTR(intel_cqm_llc_scale), - EVENT_PTR(intel_cqm_total_bytes_scale), - EVENT_PTR(intel_cqm_local_bytes_scale), - EVENT_PTR(intel_cqm_llc_snapshot), - NULL, -}; - -static struct attribute_group intel_cqm_events_group = { - .name = "events", - .attrs = NULL, -}; - -PMU_FORMAT_ATTR(event, "config:0-7"); -static struct attribute *intel_cqm_formats_attr[] = { - &format_attr_event.attr, - NULL, -}; - -static struct attribute_group intel_cqm_format_group = { - .name = "format", - .attrs = intel_cqm_formats_attr, -}; - -static ssize_t -max_recycle_threshold_show(struct device *dev, struct device_attribute *attr, - char *page) -{ - ssize_t rv; - - mutex_lock(&cache_mutex); - rv = snprintf(page, PAGE_SIZE-1, "%u\n", __intel_cqm_max_threshold); - mutex_unlock(&cache_mutex); - - return rv; -} - -static ssize_t -max_recycle_threshold_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int bytes, cachelines; - int ret; - - ret = kstrtouint(buf, 0, &bytes); - if (ret) - return ret; - - mutex_lock(&cache_mutex); - - __intel_cqm_max_threshold = bytes; - cachelines = bytes / cqm_l3_scale; - - /* - * The new maximum takes effect immediately. - */ - if (__intel_cqm_threshold > cachelines) - __intel_cqm_threshold = cachelines; - - mutex_unlock(&cache_mutex); - - return count; -} - -static DEVICE_ATTR_RW(max_recycle_threshold); - -static struct attribute *intel_cqm_attrs[] = { - &dev_attr_max_recycle_threshold.attr, - NULL, -}; - -static const struct attribute_group intel_cqm_group = { - .attrs = intel_cqm_attrs, -}; - -static const struct attribute_group *intel_cqm_attr_groups[] = { - &intel_cqm_events_group, - &intel_cqm_format_group, - &intel_cqm_group, - NULL, -}; - -static struct pmu intel_cqm_pmu = { - .hrtimer_interval_ms = RMID_DEFAULT_QUEUE_TIME, - .attr_groups = intel_cqm_attr_groups, - .task_ctx_nr = perf_sw_context, - .event_init = intel_cqm_event_init, - .add = intel_cqm_event_add, - .del = intel_cqm_event_stop, - .start = intel_cqm_event_start, - .stop = intel_cqm_event_stop, - .read = intel_cqm_event_read, - .count = intel_cqm_event_count, -}; - -static inline void cqm_pick_event_reader(int cpu) -{ - int reader; - - /* First online cpu in package becomes the reader */ - reader = cpumask_any_and(&cqm_cpumask, topology_core_cpumask(cpu)); - if (reader >= nr_cpu_ids) - cpumask_set_cpu(cpu, &cqm_cpumask); -} - -static int intel_cqm_cpu_starting(unsigned int cpu) -{ - struct intel_pqr_state *state = &per_cpu(pqr_state, cpu); - struct cpuinfo_x86 *c = &cpu_data(cpu); - - state->rmid = 0; - state->closid = 0; - state->rmid_usecnt = 0; - - WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid); - WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale); - - cqm_pick_event_reader(cpu); - return 0; -} - -static int intel_cqm_cpu_exit(unsigned int cpu) -{ - int target; - - /* Is @cpu the current cqm reader for this package ? */ - if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask)) - return 0; - - /* Find another online reader in this package */ - target = cpumask_any_but(topology_core_cpumask(cpu), cpu); - - if (target < nr_cpu_ids) - cpumask_set_cpu(target, &cqm_cpumask); - - return 0; -} - -static const struct x86_cpu_id intel_cqm_match[] = { - { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_OCCUP_LLC }, - {} -}; - -static void mbm_cleanup(void) -{ - if (!mbm_enabled) - return; - - kfree(mbm_local); - kfree(mbm_total); - mbm_enabled = false; -} - -static const struct x86_cpu_id intel_mbm_local_match[] = { - { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_LOCAL }, - {} -}; - -static const struct x86_cpu_id intel_mbm_total_match[] = { - { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_TOTAL }, - {} -}; - -static int intel_mbm_init(void) -{ - int ret = 0, array_size, maxid = cqm_max_rmid + 1; - - mbm_socket_max = topology_max_packages(); - array_size = sizeof(struct sample) * maxid * mbm_socket_max; - mbm_local = kmalloc(array_size, GFP_KERNEL); - if (!mbm_local) - return -ENOMEM; - - mbm_total = kmalloc(array_size, GFP_KERNEL); - if (!mbm_total) { - ret = -ENOMEM; - goto out; - } - - array_size = sizeof(struct hrtimer) * mbm_socket_max; - mbm_timers = kmalloc(array_size, GFP_KERNEL); - if (!mbm_timers) { - ret = -ENOMEM; - goto out; - } - mbm_hrtimer_init(); - -out: - if (ret) - mbm_cleanup(); - - return ret; -} - -static int __init intel_cqm_init(void) -{ - char *str = NULL, scale[20]; - int cpu, ret; - - if (x86_match_cpu(intel_cqm_match)) - cqm_enabled = true; - - if (x86_match_cpu(intel_mbm_local_match) && - x86_match_cpu(intel_mbm_total_match)) - mbm_enabled = true; - - if (!cqm_enabled && !mbm_enabled) - return -ENODEV; - - cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale; - - /* - * It's possible that not all resources support the same number - * of RMIDs. Instead of making scheduling much more complicated - * (where we have to match a task's RMID to a cpu that supports - * that many RMIDs) just find the minimum RMIDs supported across - * all cpus. - * - * Also, check that the scales match on all cpus. - */ - cpus_read_lock(); - for_each_online_cpu(cpu) { - struct cpuinfo_x86 *c = &cpu_data(cpu); - - if (c->x86_cache_max_rmid < cqm_max_rmid) - cqm_max_rmid = c->x86_cache_max_rmid; - - if (c->x86_cache_occ_scale != cqm_l3_scale) { - pr_err("Multiple LLC scale values, disabling\n"); - ret = -EINVAL; - goto out; - } - } - - /* - * A reasonable upper limit on the max threshold is the number - * of lines tagged per RMID if all RMIDs have the same number of - * lines tagged in the LLC. - * - * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC. - */ - __intel_cqm_max_threshold = - boot_cpu_data.x86_cache_size * 1024 / (cqm_max_rmid + 1); - - snprintf(scale, sizeof(scale), "%u", cqm_l3_scale); - str = kstrdup(scale, GFP_KERNEL); - if (!str) { - ret = -ENOMEM; - goto out; - } - - event_attr_intel_cqm_llc_scale.event_str = str; - - ret = intel_cqm_setup_rmid_cache(); - if (ret) - goto out; - - if (mbm_enabled) - ret = intel_mbm_init(); - if (ret && !cqm_enabled) - goto out; - - if (cqm_enabled && mbm_enabled) - intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr; - else if (!cqm_enabled && mbm_enabled) - intel_cqm_events_group.attrs = intel_mbm_events_attr; - else if (cqm_enabled && !mbm_enabled) - intel_cqm_events_group.attrs = intel_cqm_events_attr; - - ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1); - if (ret) { - pr_err("Intel CQM perf registration failed: %d\n", ret); - goto out; - } - - if (cqm_enabled) - pr_info("Intel CQM monitoring enabled\n"); - if (mbm_enabled) - pr_info("Intel MBM enabled\n"); - - /* - * Setup the hot cpu notifier once we are sure cqm - * is enabled to avoid notifier leak. - */ - cpuhp_setup_state_cpuslocked(CPUHP_AP_PERF_X86_CQM_STARTING, - "perf/x86/cqm:starting", - intel_cqm_cpu_starting, NULL); - cpuhp_setup_state_cpuslocked(CPUHP_AP_PERF_X86_CQM_ONLINE, - "perf/x86/cqm:online", - NULL, intel_cqm_cpu_exit); -out: - cpus_read_unlock(); - - if (ret) { - kfree(str); - cqm_cleanup(); - mbm_cleanup(); - } - - return ret; -} -device_initcall(intel_cqm_init); diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 4cf100ff2a3746f440049dd5c27c254e4dcc1776..72db0664a53dfd6fe64512ebda83caaa97db1abd 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -552,6 +552,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, snb_cstates), @@ -560,6 +561,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_DENVERTON, glm_cstates), + + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GEMINI_LAKE, glm_cstates), { }, }; MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index a322fed5f8edcab18401e2745438c362f80e0851..e1965e5ff570835be004e753a718858473bc8325 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -49,34 +49,47 @@ union intel_x86_pebs_dse { */ #define P(a, b) PERF_MEM_S(a, b) #define OP_LH (P(OP, LOAD) | P(LVL, HIT)) +#define LEVEL(x) P(LVLNUM, x) +#define REM P(REMOTE, REMOTE) #define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS)) /* Version for Sandy Bridge and later */ static u64 pebs_data_source[] = { - P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */ - OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */ - OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */ - OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */ - OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */ - OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */ - OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */ - OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */ - OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */ - OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/ - OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */ - OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */ - OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */ - OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */ - OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */ - OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */ + P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),/* 0x00:ukn L3 */ + OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 local */ + OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x03: L2 hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* 0x04: L3 hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */ + OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */ + OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */ + OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | SNOOP_NONE_MISS, /* 0x0c: L3 miss, excl */ + OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* 0x0d: L3 miss, excl */ + OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0e: I/O */ + OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0f: uncached */ }; /* Patch up minor differences in the bits */ void __init intel_pmu_pebs_data_source_nhm(void) { - pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT); - pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM); - pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM); + pebs_data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); + pebs_data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); + pebs_data_source[0x07] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); +} + +void __init intel_pmu_pebs_data_source_skl(bool pmem) +{ + u64 pmem_or_l4 = pmem ? LEVEL(PMEM) : LEVEL(L4); + + pebs_data_source[0x08] = OP_LH | pmem_or_l4 | P(SNOOP, HIT); + pebs_data_source[0x09] = OP_LH | pmem_or_l4 | REM | P(SNOOP, HIT); + pebs_data_source[0x0b] = OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE); + pebs_data_source[0x0c] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOPX, FWD); + pebs_data_source[0x0d] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOP, HITM); } static u64 precise_store_data(u64 status) @@ -149,8 +162,6 @@ static u64 load_latency_data(u64 status) { union intel_x86_pebs_dse dse; u64 val; - int model = boot_cpu_data.x86_model; - int fam = boot_cpu_data.x86; dse.val = status; @@ -162,8 +173,7 @@ static u64 load_latency_data(u64 status) /* * Nehalem models do not support TLB, Lock infos */ - if (fam == 0x6 && (model == 26 || model == 30 - || model == 31 || model == 46)) { + if (x86_pmu.pebs_no_tlb) { val |= P(TLB, NA) | P(LOCK, NA); return val; } @@ -1175,7 +1185,7 @@ static void setup_pebs_sample_data(struct perf_event *event, else regs->flags &= ~PERF_EFLAGS_EXACT; - if ((sample_type & PERF_SAMPLE_ADDR) && + if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) && x86_pmu.intel_cap.pebs_format >= 1) data->addr = pebs->dla; diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 955457a30197e8be224f0304ec83f14365b3fba9..8a6bbacd17dcfb077e2a910b5b532c1d24a4a623 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -109,6 +109,9 @@ enum { X86_BR_ZERO_CALL = 1 << 15,/* zero length call */ X86_BR_CALL_STACK = 1 << 16,/* call stack */ X86_BR_IND_JMP = 1 << 17,/* indirect jump */ + + X86_BR_TYPE_SAVE = 1 << 18,/* indicate to save branch type */ + }; #define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL) @@ -514,6 +517,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) cpuc->lbr_entries[i].in_tx = 0; cpuc->lbr_entries[i].abort = 0; cpuc->lbr_entries[i].cycles = 0; + cpuc->lbr_entries[i].type = 0; cpuc->lbr_entries[i].reserved = 0; } cpuc->lbr_stack.nr = i; @@ -600,6 +604,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) cpuc->lbr_entries[out].in_tx = in_tx; cpuc->lbr_entries[out].abort = abort; cpuc->lbr_entries[out].cycles = cycles; + cpuc->lbr_entries[out].type = 0; cpuc->lbr_entries[out].reserved = 0; out++; } @@ -677,6 +682,10 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event) if (br_type & PERF_SAMPLE_BRANCH_CALL) mask |= X86_BR_CALL | X86_BR_ZERO_CALL; + + if (br_type & PERF_SAMPLE_BRANCH_TYPE_SAVE) + mask |= X86_BR_TYPE_SAVE; + /* * stash actual user request into reg, it may * be used by fixup code for some CPU @@ -930,6 +939,43 @@ static int branch_type(unsigned long from, unsigned long to, int abort) return ret; } +#define X86_BR_TYPE_MAP_MAX 16 + +static int branch_map[X86_BR_TYPE_MAP_MAX] = { + PERF_BR_CALL, /* X86_BR_CALL */ + PERF_BR_RET, /* X86_BR_RET */ + PERF_BR_SYSCALL, /* X86_BR_SYSCALL */ + PERF_BR_SYSRET, /* X86_BR_SYSRET */ + PERF_BR_UNKNOWN, /* X86_BR_INT */ + PERF_BR_UNKNOWN, /* X86_BR_IRET */ + PERF_BR_COND, /* X86_BR_JCC */ + PERF_BR_UNCOND, /* X86_BR_JMP */ + PERF_BR_UNKNOWN, /* X86_BR_IRQ */ + PERF_BR_IND_CALL, /* X86_BR_IND_CALL */ + PERF_BR_UNKNOWN, /* X86_BR_ABORT */ + PERF_BR_UNKNOWN, /* X86_BR_IN_TX */ + PERF_BR_UNKNOWN, /* X86_BR_NO_TX */ + PERF_BR_CALL, /* X86_BR_ZERO_CALL */ + PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */ + PERF_BR_IND, /* X86_BR_IND_JMP */ +}; + +static int +common_branch_type(int type) +{ + int i; + + type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */ + + if (type) { + i = __ffs(type); + if (i < X86_BR_TYPE_MAP_MAX) + return branch_map[i]; + } + + return PERF_BR_UNKNOWN; +} + /* * implement actual branch filter based on user demand. * Hardware may not exactly satisfy that request, thus @@ -946,7 +992,8 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc) bool compress = false; /* if sampling all branches, then nothing to filter */ - if ((br_sel & X86_BR_ALL) == X86_BR_ALL) + if (((br_sel & X86_BR_ALL) == X86_BR_ALL) && + ((br_sel & X86_BR_TYPE_SAVE) != X86_BR_TYPE_SAVE)) return; for (i = 0; i < cpuc->lbr_stack.nr; i++) { @@ -967,6 +1014,9 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc) cpuc->lbr_entries[i].from = 0; compress = true; } + + if ((br_sel & X86_BR_TYPE_SAVE) == X86_BR_TYPE_SAVE) + cpuc->lbr_entries[i].type = common_branch_type(type); } if (!compress) diff --git a/arch/x86/events/intel/p4.c b/arch/x86/events/intel/p4.c index eb0533558c2b705957a30704218b983eda65e61e..d32c0eed38ca92665d378fa2d0792eed12aad818 100644 --- a/arch/x86/events/intel/p4.c +++ b/arch/x86/events/intel/p4.c @@ -587,7 +587,7 @@ static __initconst const u64 p4_hw_cache_event_ids * P4_CONFIG_ALIASABLE or bits for P4_PEBS_METRIC, they are * either up to date automatically or not applicable at all. */ -struct p4_event_alias { +static struct p4_event_alias { u64 original; u64 alternative; } p4_event_aliases[] = { diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index ae8324d65e619551bfb07ec98b20171c41e03bb3..81fd41d5a0d98eecd8e3252211e2e82d8e4b4cf5 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -471,8 +471,9 @@ static void pt_config(struct perf_event *event) struct pt *pt = this_cpu_ptr(&pt_ctx); u64 reg; - if (!event->hw.itrace_started) { - event->hw.itrace_started = 1; + /* First round: clear STATUS, in particular the PSB byte counter. */ + if (!event->hw.config) { + perf_event_itrace_started(event); wrmsrl(MSR_IA32_RTIT_STATUS, 0); } diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index a45e2114a8460925b44bd6e0983f3ee37e83d861..005908ee9333f0e87cdd4db7ca14a278d52fa773 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -559,7 +559,7 @@ static struct attribute_group rapl_pmu_format_group = { .attrs = rapl_formats_attr, }; -const struct attribute_group *rapl_attr_groups[] = { +static const struct attribute_group *rapl_attr_groups[] = { &rapl_pmu_attr_group, &rapl_pmu_format_group, &rapl_pmu_events_group, @@ -775,6 +775,9 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_rapl_init), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, hsw_rapl_init), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_DENVERTON, hsw_rapl_init), + + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GEMINI_LAKE, hsw_rapl_init), {}, }; diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 44ec523287f670dff8eee3e3c9eb1bb1606489b6..1c5390f1cf0992787afa8d34bb361f622b00dcb2 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -721,7 +721,7 @@ static struct attribute *uncore_pmu_attrs[] = { NULL, }; -static struct attribute_group uncore_pmu_attr_group = { +static const struct attribute_group uncore_pmu_attr_group = { .attrs = uncore_pmu_attrs, }; diff --git a/arch/x86/events/intel/uncore_nhmex.c b/arch/x86/events/intel/uncore_nhmex.c index cda56933200503662d133050fc47bdae050e8d61..6a5cbe90f8593eb23a7a403132240fc9afc87c9d 100644 --- a/arch/x86/events/intel/uncore_nhmex.c +++ b/arch/x86/events/intel/uncore_nhmex.c @@ -272,7 +272,7 @@ static struct attribute *nhmex_uncore_ubox_formats_attr[] = { NULL, }; -static struct attribute_group nhmex_uncore_ubox_format_group = { +static const struct attribute_group nhmex_uncore_ubox_format_group = { .name = "format", .attrs = nhmex_uncore_ubox_formats_attr, }; @@ -299,7 +299,7 @@ static struct attribute *nhmex_uncore_cbox_formats_attr[] = { NULL, }; -static struct attribute_group nhmex_uncore_cbox_format_group = { +static const struct attribute_group nhmex_uncore_cbox_format_group = { .name = "format", .attrs = nhmex_uncore_cbox_formats_attr, }; @@ -407,7 +407,7 @@ static struct attribute *nhmex_uncore_bbox_formats_attr[] = { NULL, }; -static struct attribute_group nhmex_uncore_bbox_format_group = { +static const struct attribute_group nhmex_uncore_bbox_format_group = { .name = "format", .attrs = nhmex_uncore_bbox_formats_attr, }; @@ -484,7 +484,7 @@ static struct attribute *nhmex_uncore_sbox_formats_attr[] = { NULL, }; -static struct attribute_group nhmex_uncore_sbox_format_group = { +static const struct attribute_group nhmex_uncore_sbox_format_group = { .name = "format", .attrs = nhmex_uncore_sbox_formats_attr, }; @@ -898,7 +898,7 @@ static struct attribute *nhmex_uncore_mbox_formats_attr[] = { NULL, }; -static struct attribute_group nhmex_uncore_mbox_format_group = { +static const struct attribute_group nhmex_uncore_mbox_format_group = { .name = "format", .attrs = nhmex_uncore_mbox_formats_attr, }; @@ -1163,7 +1163,7 @@ static struct attribute *nhmex_uncore_rbox_formats_attr[] = { NULL, }; -static struct attribute_group nhmex_uncore_rbox_format_group = { +static const struct attribute_group nhmex_uncore_rbox_format_group = { .name = "format", .attrs = nhmex_uncore_rbox_formats_attr, }; diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c index a3dcc12bef4ab3a67aab29c6acf3480920e06952..db1127ce685eb8ea687bb4e0279f13ad5706a59f 100644 --- a/arch/x86/events/intel/uncore_snb.c +++ b/arch/x86/events/intel/uncore_snb.c @@ -130,7 +130,7 @@ static struct attribute *snb_uncore_formats_attr[] = { NULL, }; -static struct attribute_group snb_uncore_format_group = { +static const struct attribute_group snb_uncore_format_group = { .name = "format", .attrs = snb_uncore_formats_attr, }; @@ -289,7 +289,7 @@ static struct attribute *snb_uncore_imc_formats_attr[] = { NULL, }; -static struct attribute_group snb_uncore_imc_format_group = { +static const struct attribute_group snb_uncore_imc_format_group = { .name = "format", .attrs = snb_uncore_imc_formats_attr, }; @@ -769,7 +769,7 @@ static struct attribute *nhm_uncore_formats_attr[] = { NULL, }; -static struct attribute_group nhm_uncore_format_group = { +static const struct attribute_group nhm_uncore_format_group = { .name = "format", .attrs = nhm_uncore_formats_attr, }; diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 4f9127644b80abd87d4c49204dde197a9ade7ac2..a7196818416a57381b513254628206a9660ed578 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -602,27 +602,27 @@ static struct uncore_event_desc snbep_uncore_qpi_events[] = { { /* end: all zeroes */ }, }; -static struct attribute_group snbep_uncore_format_group = { +static const struct attribute_group snbep_uncore_format_group = { .name = "format", .attrs = snbep_uncore_formats_attr, }; -static struct attribute_group snbep_uncore_ubox_format_group = { +static const struct attribute_group snbep_uncore_ubox_format_group = { .name = "format", .attrs = snbep_uncore_ubox_formats_attr, }; -static struct attribute_group snbep_uncore_cbox_format_group = { +static const struct attribute_group snbep_uncore_cbox_format_group = { .name = "format", .attrs = snbep_uncore_cbox_formats_attr, }; -static struct attribute_group snbep_uncore_pcu_format_group = { +static const struct attribute_group snbep_uncore_pcu_format_group = { .name = "format", .attrs = snbep_uncore_pcu_formats_attr, }; -static struct attribute_group snbep_uncore_qpi_format_group = { +static const struct attribute_group snbep_uncore_qpi_format_group = { .name = "format", .attrs = snbep_uncore_qpi_formats_attr, }; @@ -1431,27 +1431,27 @@ static struct attribute *ivbep_uncore_qpi_formats_attr[] = { NULL, }; -static struct attribute_group ivbep_uncore_format_group = { +static const struct attribute_group ivbep_uncore_format_group = { .name = "format", .attrs = ivbep_uncore_formats_attr, }; -static struct attribute_group ivbep_uncore_ubox_format_group = { +static const struct attribute_group ivbep_uncore_ubox_format_group = { .name = "format", .attrs = ivbep_uncore_ubox_formats_attr, }; -static struct attribute_group ivbep_uncore_cbox_format_group = { +static const struct attribute_group ivbep_uncore_cbox_format_group = { .name = "format", .attrs = ivbep_uncore_cbox_formats_attr, }; -static struct attribute_group ivbep_uncore_pcu_format_group = { +static const struct attribute_group ivbep_uncore_pcu_format_group = { .name = "format", .attrs = ivbep_uncore_pcu_formats_attr, }; -static struct attribute_group ivbep_uncore_qpi_format_group = { +static const struct attribute_group ivbep_uncore_qpi_format_group = { .name = "format", .attrs = ivbep_uncore_qpi_formats_attr, }; @@ -1887,7 +1887,7 @@ static struct attribute *knl_uncore_ubox_formats_attr[] = { NULL, }; -static struct attribute_group knl_uncore_ubox_format_group = { +static const struct attribute_group knl_uncore_ubox_format_group = { .name = "format", .attrs = knl_uncore_ubox_formats_attr, }; @@ -1927,7 +1927,7 @@ static struct attribute *knl_uncore_cha_formats_attr[] = { NULL, }; -static struct attribute_group knl_uncore_cha_format_group = { +static const struct attribute_group knl_uncore_cha_format_group = { .name = "format", .attrs = knl_uncore_cha_formats_attr, }; @@ -2037,7 +2037,7 @@ static struct attribute *knl_uncore_pcu_formats_attr[] = { NULL, }; -static struct attribute_group knl_uncore_pcu_format_group = { +static const struct attribute_group knl_uncore_pcu_format_group = { .name = "format", .attrs = knl_uncore_pcu_formats_attr, }; @@ -2187,7 +2187,7 @@ static struct attribute *knl_uncore_irp_formats_attr[] = { NULL, }; -static struct attribute_group knl_uncore_irp_format_group = { +static const struct attribute_group knl_uncore_irp_format_group = { .name = "format", .attrs = knl_uncore_irp_formats_attr, }; @@ -2385,7 +2385,7 @@ static struct attribute *hswep_uncore_ubox_formats_attr[] = { NULL, }; -static struct attribute_group hswep_uncore_ubox_format_group = { +static const struct attribute_group hswep_uncore_ubox_format_group = { .name = "format", .attrs = hswep_uncore_ubox_formats_attr, }; @@ -2439,7 +2439,7 @@ static struct attribute *hswep_uncore_cbox_formats_attr[] = { NULL, }; -static struct attribute_group hswep_uncore_cbox_format_group = { +static const struct attribute_group hswep_uncore_cbox_format_group = { .name = "format", .attrs = hswep_uncore_cbox_formats_attr, }; @@ -2621,7 +2621,7 @@ static struct attribute *hswep_uncore_sbox_formats_attr[] = { NULL, }; -static struct attribute_group hswep_uncore_sbox_format_group = { +static const struct attribute_group hswep_uncore_sbox_format_group = { .name = "format", .attrs = hswep_uncore_sbox_formats_attr, }; @@ -3314,7 +3314,7 @@ static struct attribute *skx_uncore_cha_formats_attr[] = { NULL, }; -static struct attribute_group skx_uncore_chabox_format_group = { +static const struct attribute_group skx_uncore_chabox_format_group = { .name = "format", .attrs = skx_uncore_cha_formats_attr, }; @@ -3427,7 +3427,7 @@ static struct attribute *skx_uncore_iio_formats_attr[] = { NULL, }; -static struct attribute_group skx_uncore_iio_format_group = { +static const struct attribute_group skx_uncore_iio_format_group = { .name = "format", .attrs = skx_uncore_iio_formats_attr, }; @@ -3462,7 +3462,7 @@ static struct intel_uncore_ops skx_uncore_iio_ops = { static struct intel_uncore_type skx_uncore_iio = { .name = "iio", .num_counters = 4, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IIO0_MSR_PMON_CTL0, .perf_ctr = SKX_IIO0_MSR_PMON_CTR0, @@ -3484,7 +3484,7 @@ static struct attribute *skx_uncore_formats_attr[] = { NULL, }; -static struct attribute_group skx_uncore_format_group = { +static const struct attribute_group skx_uncore_format_group = { .name = "format", .attrs = skx_uncore_formats_attr, }; @@ -3492,7 +3492,7 @@ static struct attribute_group skx_uncore_format_group = { static struct intel_uncore_type skx_uncore_irp = { .name = "irp", .num_counters = 2, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IRP0_MSR_PMON_CTL0, .perf_ctr = SKX_IRP0_MSR_PMON_CTR0, @@ -3605,7 +3605,7 @@ static struct attribute *skx_upi_uncore_formats_attr[] = { NULL, }; -static struct attribute_group skx_upi_uncore_format_group = { +static const struct attribute_group skx_upi_uncore_format_group = { .name = "format", .attrs = skx_upi_uncore_formats_attr, }; diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index 4bb3ec69e8ea10537c25ef2d792be94f1d7a4127..06723671ae4e91d53b7327b44fe96b588826d838 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -63,6 +63,14 @@ static bool test_intel(int idx) case INTEL_FAM6_ATOM_SILVERMONT1: case INTEL_FAM6_ATOM_SILVERMONT2: case INTEL_FAM6_ATOM_AIRMONT: + + case INTEL_FAM6_ATOM_GOLDMONT: + case INTEL_FAM6_ATOM_DENVERTON: + + case INTEL_FAM6_ATOM_GEMINI_LAKE: + + case INTEL_FAM6_XEON_PHI_KNL: + case INTEL_FAM6_XEON_PHI_KNM: if (idx == PERF_MSR_SMI) return true; break; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 476aec3a4cabd3852be09731a69f6c5f3c28948b..4196f81ec0e1b0de71483cbc999837ec48b51f33 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -91,7 +91,7 @@ struct amd_nb { (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \ PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \ PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \ - PERF_SAMPLE_TRANSACTION) + PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR) /* * A debug store configuration. @@ -558,6 +558,7 @@ struct x86_pmu { int attr_rdpmc; struct attribute **format_attrs; struct attribute **event_attrs; + struct attribute **caps_attrs; ssize_t (*events_sysfs_show)(char *page, u64 config); struct attribute **cpu_events; @@ -591,7 +592,8 @@ struct x86_pmu { pebs :1, pebs_active :1, pebs_broken :1, - pebs_prec_dist :1; + pebs_prec_dist :1, + pebs_no_tlb :1; int pebs_record_size; int pebs_buffer_size; void (*drain_pebs)(struct pt_regs *regs); @@ -741,6 +743,8 @@ int x86_reserve_hardware(void); void x86_release_hardware(void); +int x86_pmu_max_precise(void); + void hw_perf_lbr_event_destroy(struct perf_event *event); int x86_setup_perfctr(struct perf_event *event); @@ -947,6 +951,8 @@ void intel_pmu_lbr_init_knl(void); void intel_pmu_pebs_data_source_nhm(void); +void intel_pmu_pebs_data_source_skl(bool pmem); + int intel_pmu_setup_lbr_filter(struct perf_event *event); void intel_pt_interrupt(void); diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile index 171ae09864d7dc24199c0d316bbb3a28a17b7425..367a8203cfcf5e556b5583b037d0ad65a72225d3 100644 --- a/arch/x86/hyperv/Makefile +++ b/arch/x86/hyperv/Makefile @@ -1 +1 @@ -obj-y := hv_init.o +obj-y := hv_init.o mmu.o diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 5b882cc0c0e9a96e1bd8beeec260ef657a439de4..1a8eb550c40f13d8f4f4f5d049e09d323a2bb185 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #ifdef CONFIG_HYPERV_TSCPAGE @@ -75,10 +77,25 @@ static struct clocksource hyperv_cs_msr = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void *hypercall_pg; +void *hv_hypercall_pg; +EXPORT_SYMBOL_GPL(hv_hypercall_pg); struct clocksource *hyperv_cs; EXPORT_SYMBOL_GPL(hyperv_cs); +u32 *hv_vp_index; +EXPORT_SYMBOL_GPL(hv_vp_index); + +static int hv_cpu_init(unsigned int cpu) +{ + u64 msr_vp_index; + + hv_get_vp_index(msr_vp_index); + + hv_vp_index[smp_processor_id()] = msr_vp_index; + + return 0; +} + /* * This function is to be invoked early in the boot sequence after the * hypervisor has been detected. @@ -94,6 +111,16 @@ void hyperv_init(void) if (x86_hyper != &x86_hyper_ms_hyperv) return; + /* Allocate percpu VP index */ + hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index), + GFP_KERNEL); + if (!hv_vp_index) + return; + + if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online", + hv_cpu_init, NULL) < 0) + goto free_vp_index; + /* * Setup the hypercall page and enable hypercalls. * 1. Register the guest ID @@ -102,17 +129,19 @@ void hyperv_init(void) guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id); - hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); - if (hypercall_pg == NULL) { + hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); + if (hv_hypercall_pg == NULL) { wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); - return; + goto free_vp_index; } rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); hypercall_msr.enable = 1; - hypercall_msr.guest_physical_address = vmalloc_to_pfn(hypercall_pg); + hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); + hyper_alloc_mmu(); + /* * Register Hyper-V specific clocksource. */ @@ -148,6 +177,12 @@ void hyperv_init(void) hyperv_cs = &hyperv_cs_msr; if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100); + + return; + +free_vp_index: + kfree(hv_vp_index); + hv_vp_index = NULL; } /* @@ -170,51 +205,6 @@ void hyperv_cleanup(void) } EXPORT_SYMBOL_GPL(hyperv_cleanup); -/* - * hv_do_hypercall- Invoke the specified hypercall - */ -u64 hv_do_hypercall(u64 control, void *input, void *output) -{ - u64 input_address = (input) ? virt_to_phys(input) : 0; - u64 output_address = (output) ? virt_to_phys(output) : 0; -#ifdef CONFIG_X86_64 - u64 hv_status = 0; - - if (!hypercall_pg) - return (u64)ULLONG_MAX; - - __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); - __asm__ __volatile__("call *%3" : "=a" (hv_status) : - "c" (control), "d" (input_address), - "m" (hypercall_pg)); - - return hv_status; - -#else - - u32 control_hi = control >> 32; - u32 control_lo = control & 0xFFFFFFFF; - u32 hv_status_hi = 1; - u32 hv_status_lo = 1; - u32 input_address_hi = input_address >> 32; - u32 input_address_lo = input_address & 0xFFFFFFFF; - u32 output_address_hi = output_address >> 32; - u32 output_address_lo = output_address & 0xFFFFFFFF; - - if (!hypercall_pg) - return (u64)ULLONG_MAX; - - __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), - "=a"(hv_status_lo) : "d" (control_hi), - "a" (control_lo), "b" (input_address_hi), - "c" (input_address_lo), "D"(output_address_hi), - "S"(output_address_lo), "m" (hypercall_pg)); - - return hv_status_lo | ((u64)hv_status_hi << 32); -#endif /* !x86_64 */ -} -EXPORT_SYMBOL_GPL(hv_do_hypercall); - void hyperv_report_panic(struct pt_regs *regs) { static bool panic_reported; diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c new file mode 100644 index 0000000000000000000000000000000000000000..39e7f6e50919117087fe663e013cd77d12b16b7b --- /dev/null +++ b/arch/x86/hyperv/mmu.c @@ -0,0 +1,272 @@ +#define pr_fmt(fmt) "Hyper-V: " fmt + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CREATE_TRACE_POINTS +#include + +/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */ +struct hv_flush_pcpu { + u64 address_space; + u64 flags; + u64 processor_mask; + u64 gva_list[]; +}; + +/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */ +struct hv_flush_pcpu_ex { + u64 address_space; + u64 flags; + struct { + u64 format; + u64 valid_bank_mask; + u64 bank_contents[]; + } hv_vp_set; + u64 gva_list[]; +}; + +/* Each gva in gva_list encodes up to 4096 pages to flush */ +#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE) + +static struct hv_flush_pcpu __percpu *pcpu_flush; + +static struct hv_flush_pcpu_ex __percpu *pcpu_flush_ex; + +/* + * Fills in gva_list starting from offset. Returns the number of items added. + */ +static inline int fill_gva_list(u64 gva_list[], int offset, + unsigned long start, unsigned long end) +{ + int gva_n = offset; + unsigned long cur = start, diff; + + do { + diff = end > cur ? end - cur : 0; + + gva_list[gva_n] = cur & PAGE_MASK; + /* + * Lower 12 bits encode the number of additional + * pages to flush (in addition to the 'cur' page). + */ + if (diff >= HV_TLB_FLUSH_UNIT) + gva_list[gva_n] |= ~PAGE_MASK; + else if (diff) + gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT; + + cur += HV_TLB_FLUSH_UNIT; + gva_n++; + + } while (cur < end); + + return gva_n - offset; +} + +/* Return the number of banks in the resulting vp_set */ +static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush, + const struct cpumask *cpus) +{ + int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1; + + /* + * Some banks may end up being empty but this is acceptable. + */ + for_each_cpu(cpu, cpus) { + vcpu = hv_cpu_number_to_vp_number(cpu); + vcpu_bank = vcpu / 64; + vcpu_offset = vcpu % 64; + + /* valid_bank_mask can represent up to 64 banks */ + if (vcpu_bank >= 64) + return 0; + + __set_bit(vcpu_offset, (unsigned long *) + &flush->hv_vp_set.bank_contents[vcpu_bank]); + if (vcpu_bank >= nr_bank) + nr_bank = vcpu_bank + 1; + } + flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0); + + return nr_bank; +} + +static void hyperv_flush_tlb_others(const struct cpumask *cpus, + const struct flush_tlb_info *info) +{ + int cpu, vcpu, gva_n, max_gvas; + struct hv_flush_pcpu *flush; + u64 status = U64_MAX; + unsigned long flags; + + trace_hyperv_mmu_flush_tlb_others(cpus, info); + + if (!pcpu_flush || !hv_hypercall_pg) + goto do_native; + + if (cpumask_empty(cpus)) + return; + + local_irq_save(flags); + + flush = this_cpu_ptr(pcpu_flush); + + if (info->mm) { + flush->address_space = virt_to_phys(info->mm->pgd); + flush->flags = 0; + } else { + flush->address_space = 0; + flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; + } + + flush->processor_mask = 0; + if (cpumask_equal(cpus, cpu_present_mask)) { + flush->flags |= HV_FLUSH_ALL_PROCESSORS; + } else { + for_each_cpu(cpu, cpus) { + vcpu = hv_cpu_number_to_vp_number(cpu); + if (vcpu >= 64) + goto do_native; + + __set_bit(vcpu, (unsigned long *) + &flush->processor_mask); + } + } + + /* + * We can flush not more than max_gvas with one hypercall. Flush the + * whole address space if we were asked to do more. + */ + max_gvas = (PAGE_SIZE - sizeof(*flush)) / sizeof(flush->gva_list[0]); + + if (info->end == TLB_FLUSH_ALL) { + flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; + status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE, + flush, NULL); + } else if (info->end && + ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) { + status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE, + flush, NULL); + } else { + gva_n = fill_gva_list(flush->gva_list, 0, + info->start, info->end); + status = hv_do_rep_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST, + gva_n, 0, flush, NULL); + } + + local_irq_restore(flags); + + if (!(status & HV_HYPERCALL_RESULT_MASK)) + return; +do_native: + native_flush_tlb_others(cpus, info); +} + +static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus, + const struct flush_tlb_info *info) +{ + int nr_bank = 0, max_gvas, gva_n; + struct hv_flush_pcpu_ex *flush; + u64 status = U64_MAX; + unsigned long flags; + + trace_hyperv_mmu_flush_tlb_others(cpus, info); + + if (!pcpu_flush_ex || !hv_hypercall_pg) + goto do_native; + + if (cpumask_empty(cpus)) + return; + + local_irq_save(flags); + + flush = this_cpu_ptr(pcpu_flush_ex); + + if (info->mm) { + flush->address_space = virt_to_phys(info->mm->pgd); + flush->flags = 0; + } else { + flush->address_space = 0; + flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; + } + + flush->hv_vp_set.valid_bank_mask = 0; + + if (!cpumask_equal(cpus, cpu_present_mask)) { + flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K; + nr_bank = cpumask_to_vp_set(flush, cpus); + } + + if (!nr_bank) { + flush->hv_vp_set.format = HV_GENERIC_SET_ALL; + flush->flags |= HV_FLUSH_ALL_PROCESSORS; + } + + /* + * We can flush not more than max_gvas with one hypercall. Flush the + * whole address space if we were asked to do more. + */ + max_gvas = + (PAGE_SIZE - sizeof(*flush) - nr_bank * + sizeof(flush->hv_vp_set.bank_contents[0])) / + sizeof(flush->gva_list[0]); + + if (info->end == TLB_FLUSH_ALL) { + flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; + status = hv_do_rep_hypercall( + HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX, + 0, nr_bank + 2, flush, NULL); + } else if (info->end && + ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) { + status = hv_do_rep_hypercall( + HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX, + 0, nr_bank + 2, flush, NULL); + } else { + gva_n = fill_gva_list(flush->gva_list, nr_bank, + info->start, info->end); + status = hv_do_rep_hypercall( + HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX, + gva_n, nr_bank + 2, flush, NULL); + } + + local_irq_restore(flags); + + if (!(status & HV_HYPERCALL_RESULT_MASK)) + return; +do_native: + native_flush_tlb_others(cpus, info); +} + +void hyperv_setup_mmu_ops(void) +{ + if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)) + return; + + setup_clear_cpu_cap(X86_FEATURE_PCID); + + if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) { + pr_info("Using hypercall for remote TLB flush\n"); + pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others; + } else { + pr_info("Using ext hypercall for remote TLB flush\n"); + pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex; + } +} + +void hyper_alloc_mmu(void) +{ + if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)) + return; + + if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) + pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE); + else + pcpu_flush_ex = __alloc_percpu(PAGE_SIZE, PAGE_SIZE); +} diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 8d0879f1d42cad890057408160e253ca026503b9..8e02b30cf08e16a2ca5b3d0b6aa97bda051a2c85 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -407,10 +407,10 @@ static int load_aout_library(struct file *file) unsigned long bss, start_addr, len, error; int retval; struct exec ex; - + loff_t pos = 0; retval = -ENOEXEC; - error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); + error = kernel_read(file, &ex, sizeof(ex), &pos); if (error != sizeof(ex)) goto out; diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 724153797209e9da677412b89feab4a6e23337ec..0e2a5edbce00111f6a41f1b3070610b5316d1e71 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -226,12 +226,12 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, if (ksig->ka.sa.sa_flags & SA_ONSTACK) sp = sigsp(sp, ksig); /* This is the legacy signal stack switching. */ - else if ((regs->ss & 0xffff) != __USER32_DS && + else if (regs->ss != __USER32_DS && !(ksig->ka.sa.sa_flags & SA_RESTORER) && ksig->ka.sa.sa_restorer) sp = (unsigned long) ksig->ka.sa.sa_restorer; - if (fpu->fpstate_active) { + if (fpu->initialized) { unsigned long fx_aligned, math_size; sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size); diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 2efc768e43627a48118d28729c380c0fbcaa7681..72d867f6b518e4db5a79a10c924f858a3edb0af8 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -150,8 +150,6 @@ static inline void disable_acpi(void) { } extern int x86_acpi_numa_init(void); #endif /* CONFIG_ACPI_NUMA */ -#define acpi_unlazy_tlb(x) leave_mm(x) - #ifdef CONFIG_ACPI_APEI static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) { @@ -162,12 +160,13 @@ static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) * you call efi_mem_attributes() during boot and at runtime, * you could theoretically see different attributes. * - * Since we are yet to see any x86 platforms that require - * anything other than PAGE_KERNEL (some arm64 platforms - * require the equivalent of PAGE_KERNEL_NOCACHE), return that - * until we know differently. + * We are yet to see any x86 platforms that require anything + * other than PAGE_KERNEL (some ARM64 platforms require the + * equivalent of PAGE_KERNEL_NOCACHE). Additionally, if SME + * is active, the ACPI information will not be encrypted, + * so return PAGE_KERNEL_NOENC until we know differently. */ - return PAGE_KERNEL; + return PAGE_KERNEL_NOENC; } #endif diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 1b020381ab38965ae2a80d2d86df32c66c92e2e8..c096624137ae831fa4d0f9cebf528453598fdefb 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -218,10 +218,9 @@ static inline int alternatives_text_reserved(void *start, void *end) #define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ output, input...) \ { \ - register void *__sp asm(_ASM_SP); \ asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ "call %P[new2]", feature2) \ - : output, "+r" (__sp) \ + : output, ASM_CALL_CONSTRAINT \ : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ [new2] "i" (newfunc2), ## input); \ } diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 7a9df3beb89b1c6ba39365eb5059d39373bb6070..b0dc91f4bedc680ac69d7ecc481a71c863bade77 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -11,10 +11,12 @@ # define __ASM_FORM_COMMA(x) " " #x "," #endif -#ifdef CONFIG_X86_32 +#ifndef __x86_64__ +/* 32 bit */ # define __ASM_SEL(a,b) __ASM_FORM(a) # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(a) #else +/* 64 bit */ # define __ASM_SEL(a,b) __ASM_FORM(b) # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b) #endif @@ -74,6 +76,9 @@ # define _ASM_EXTABLE_EX(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) +# define _ASM_EXTABLE_REFCOUNT(from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount) + # define _ASM_NOKPROBE(entry) \ .pushsection "_kprobe_blacklist","aw" ; \ _ASM_ALIGN ; \ @@ -123,7 +128,21 @@ # define _ASM_EXTABLE_EX(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) +# define _ASM_EXTABLE_REFCOUNT(from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount) + /* For C file, we already have NOKPROBE_SYMBOL macro */ #endif +#ifndef __ASSEMBLY__ +/* + * This output constraint should be used for any inline asm which has a "call" + * instruction. Otherwise the asm may be inserted before the frame pointer + * gets set up by the containing function. If you forget to do this, objtool + * may print a "call without frame pointer save/setup" warning. + */ +register unsigned long current_stack_pointer asm(_ASM_SP); +#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) +#endif + #endif /* _ASM_X86_ASM_H */ diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 33380b8714634f93ef77290e8601e6834701ddf1..0874ebda3069d9eb3a8811f8d05951e929ab7d18 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -197,35 +197,56 @@ static inline int atomic_xchg(atomic_t *v, int new) return xchg(&v->counter, new); } -#define ATOMIC_OP(op) \ -static inline void atomic_##op(int i, atomic_t *v) \ -{ \ - asm volatile(LOCK_PREFIX #op"l %1,%0" \ - : "+m" (v->counter) \ - : "ir" (i) \ - : "memory"); \ +static inline void atomic_and(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "andl %1,%0" + : "+m" (v->counter) + : "ir" (i) + : "memory"); +} + +static inline int atomic_fetch_and(int i, atomic_t *v) +{ + int val = atomic_read(v); + + do { } while (!atomic_try_cmpxchg(v, &val, val & i)); + + return val; } -#define ATOMIC_FETCH_OP(op, c_op) \ -static inline int atomic_fetch_##op(int i, atomic_t *v) \ -{ \ - int val = atomic_read(v); \ - do { \ - } while (!atomic_try_cmpxchg(v, &val, val c_op i)); \ - return val; \ +static inline void atomic_or(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "orl %1,%0" + : "+m" (v->counter) + : "ir" (i) + : "memory"); } -#define ATOMIC_OPS(op, c_op) \ - ATOMIC_OP(op) \ - ATOMIC_FETCH_OP(op, c_op) +static inline int atomic_fetch_or(int i, atomic_t *v) +{ + int val = atomic_read(v); -ATOMIC_OPS(and, &) -ATOMIC_OPS(or , |) -ATOMIC_OPS(xor, ^) + do { } while (!atomic_try_cmpxchg(v, &val, val | i)); -#undef ATOMIC_OPS -#undef ATOMIC_FETCH_OP -#undef ATOMIC_OP + return val; +} + +static inline void atomic_xor(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "xorl %1,%0" + : "+m" (v->counter) + : "ir" (i) + : "memory"); +} + +static inline int atomic_fetch_xor(int i, atomic_t *v) +{ + int val = atomic_read(v); + + do { } while (!atomic_try_cmpxchg(v, &val, val ^ i)); + + return val; +} /** * __atomic_add_unless - add unless the number is already a given value @@ -239,10 +260,12 @@ ATOMIC_OPS(xor, ^) static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c = atomic_read(v); + do { if (unlikely(c == u)) break; } while (!atomic_try_cmpxchg(v, &c, c + a)); + return c; } diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index 71d7705fb303ba5238f4f812fdb071277addbce8..9e206f31ce2a6d0bbb2a036e25cb221cad6376c9 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h @@ -312,37 +312,70 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v) #undef alternative_atomic64 #undef __alternative_atomic64 -#define ATOMIC64_OP(op, c_op) \ -static inline void atomic64_##op(long long i, atomic64_t *v) \ -{ \ - long long old, c = 0; \ - while ((old = atomic64_cmpxchg(v, c, c c_op i)) != c) \ - c = old; \ +static inline void atomic64_and(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c & i)) != c) + c = old; } -#define ATOMIC64_FETCH_OP(op, c_op) \ -static inline long long atomic64_fetch_##op(long long i, atomic64_t *v) \ -{ \ - long long old, c = 0; \ - while ((old = atomic64_cmpxchg(v, c, c c_op i)) != c) \ - c = old; \ - return old; \ +static inline long long atomic64_fetch_and(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c & i)) != c) + c = old; + + return old; } -ATOMIC64_FETCH_OP(add, +) +static inline void atomic64_or(long long i, atomic64_t *v) +{ + long long old, c = 0; -#define atomic64_fetch_sub(i, v) atomic64_fetch_add(-(i), (v)) + while ((old = atomic64_cmpxchg(v, c, c | i)) != c) + c = old; +} + +static inline long long atomic64_fetch_or(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c | i)) != c) + c = old; + + return old; +} -#define ATOMIC64_OPS(op, c_op) \ - ATOMIC64_OP(op, c_op) \ - ATOMIC64_FETCH_OP(op, c_op) +static inline void atomic64_xor(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c ^ i)) != c) + c = old; +} -ATOMIC64_OPS(and, &) -ATOMIC64_OPS(or, |) -ATOMIC64_OPS(xor, ^) +static inline long long atomic64_fetch_xor(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c ^ i)) != c) + c = old; + + return old; +} -#undef ATOMIC64_OPS -#undef ATOMIC64_FETCH_OP -#undef ATOMIC64_OP +static inline long long atomic64_fetch_add(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c + i)) != c) + c = old; + + return old; +} + +#define atomic64_fetch_sub(i, v) atomic64_fetch_add(-(i), (v)) #endif /* _ASM_X86_ATOMIC64_32_H */ diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 6189a433c9a93946dbabf2cb8a6ca6b50a7bdc93..5d9de36a2f04cf17d879d7dcf3d712cf6a9c2ff2 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -177,7 +177,7 @@ static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new) } #define atomic64_try_cmpxchg atomic64_try_cmpxchg -static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, long *old, long new) +static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, s64 *old, long new) { return try_cmpxchg(&v->counter, old, new); } @@ -198,7 +198,7 @@ static inline long atomic64_xchg(atomic64_t *v, long new) */ static inline bool atomic64_add_unless(atomic64_t *v, long a, long u) { - long c = atomic64_read(v); + s64 c = atomic64_read(v); do { if (unlikely(c == u)) return false; @@ -217,7 +217,7 @@ static inline bool atomic64_add_unless(atomic64_t *v, long a, long u) */ static inline long atomic64_dec_if_positive(atomic64_t *v) { - long dec, c = atomic64_read(v); + s64 dec, c = atomic64_read(v); do { dec = c - 1; if (unlikely(dec < 0)) @@ -226,34 +226,55 @@ static inline long atomic64_dec_if_positive(atomic64_t *v) return dec; } -#define ATOMIC64_OP(op) \ -static inline void atomic64_##op(long i, atomic64_t *v) \ -{ \ - asm volatile(LOCK_PREFIX #op"q %1,%0" \ - : "+m" (v->counter) \ - : "er" (i) \ - : "memory"); \ +static inline void atomic64_and(long i, atomic64_t *v) +{ + asm volatile(LOCK_PREFIX "andq %1,%0" + : "+m" (v->counter) + : "er" (i) + : "memory"); } -#define ATOMIC64_FETCH_OP(op, c_op) \ -static inline long atomic64_fetch_##op(long i, atomic64_t *v) \ -{ \ - long val = atomic64_read(v); \ - do { \ - } while (!atomic64_try_cmpxchg(v, &val, val c_op i)); \ - return val; \ +static inline long atomic64_fetch_and(long i, atomic64_t *v) +{ + s64 val = atomic64_read(v); + + do { + } while (!atomic64_try_cmpxchg(v, &val, val & i)); + return val; } -#define ATOMIC64_OPS(op, c_op) \ - ATOMIC64_OP(op) \ - ATOMIC64_FETCH_OP(op, c_op) +static inline void atomic64_or(long i, atomic64_t *v) +{ + asm volatile(LOCK_PREFIX "orq %1,%0" + : "+m" (v->counter) + : "er" (i) + : "memory"); +} -ATOMIC64_OPS(and, &) -ATOMIC64_OPS(or, |) -ATOMIC64_OPS(xor, ^) +static inline long atomic64_fetch_or(long i, atomic64_t *v) +{ + s64 val = atomic64_read(v); -#undef ATOMIC64_OPS -#undef ATOMIC64_FETCH_OP -#undef ATOMIC64_OP + do { + } while (!atomic64_try_cmpxchg(v, &val, val | i)); + return val; +} + +static inline void atomic64_xor(long i, atomic64_t *v) +{ + asm volatile(LOCK_PREFIX "xorq %1,%0" + : "+m" (v->counter) + : "er" (i) + : "memory"); +} + +static inline long atomic64_fetch_xor(long i, atomic64_t *v) +{ + s64 val = atomic64_read(v); + + do { + } while (!atomic64_try_cmpxchg(v, &val, val ^ i)); + return val; +} #endif /* _ASM_X86_ATOMIC64_64_H */ diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index 8b4140f6724f4cfe4cf89135b9e0547baa527d94..cb9a1af109b4796152d8017ca8a9d11f959183f7 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h @@ -7,6 +7,4 @@ void clflush_cache_range(void *addr, unsigned int size); -#define mmio_flush_range(addr, size) clflush_cache_range(addr, size) - #endif /* _ASM_X86_CACHEFLUSH_H */ diff --git a/arch/x86/include/asm/cmdline.h b/arch/x86/include/asm/cmdline.h index e01f7f7ccb0c5711db4f1fe130938cee36169965..84ae170bc3d0cd73cfa7d08fa6f730bd3106e4ea 100644 --- a/arch/x86/include/asm/cmdline.h +++ b/arch/x86/include/asm/cmdline.h @@ -2,5 +2,7 @@ #define _ASM_X86_CMDLINE_H int cmdline_find_option_bool(const char *cmdline_ptr, const char *option); +int cmdline_find_option(const char *cmdline_ptr, const char *option, + char *buffer, int bufsize); #endif /* _ASM_X86_CMDLINE_H */ diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index d90296d061e8267a97cd8a58328d8a20534289d4..b5069e802d5ce4acbe9f8ac61f47401db8f1f54d 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -157,7 +157,7 @@ extern void __add_wrong_size(void) #define __raw_try_cmpxchg(_ptr, _pold, _new, size, lock) \ ({ \ bool success; \ - __typeof__(_ptr) _old = (_pold); \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ __typeof__(*(_ptr)) __old = *_old; \ __typeof__(*(_ptr)) __new = (_new); \ switch (size) { \ diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index ca3c48c0872f4beba6b03ac92c50eb6a352b3006..2519c6c801c917d7a30b3826c86679edf18616d5 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -177,7 +177,7 @@ #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ #define X86_FEATURE_PTSC ( 6*32+27) /* performance time-stamp counter */ -#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ +#define X86_FEATURE_PERFCTR_LLC ( 6*32+28) /* Last Level Cache performance counter extensions */ #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ /* @@ -196,6 +196,7 @@ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ @@ -286,7 +287,8 @@ #define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ -#define X86_FEATURE_VIRTUAL_VMLOAD_VMSAVE (15*32+15) /* Virtual VMLOAD VMSAVE */ +#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ +#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index d0a21b12dd585c5e73c1930f4afa37aee5a483c6..9d0e13738ed3d3ea9cc9200c62153c101624a7b7 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in desc->s = 1; desc->dpl = 0x3; desc->p = info->seg_not_present ^ 1; - desc->limit = (info->limit & 0xf0000) >> 16; + desc->limit1 = (info->limit & 0xf0000) >> 16; desc->avl = info->useable; desc->d = info->seg_32bit; desc->g = info->limit_in_pages; @@ -83,33 +84,25 @@ static inline phys_addr_t get_cpu_gdt_paddr(unsigned int cpu) return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu)); } -#ifdef CONFIG_X86_64 - static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, unsigned dpl, unsigned ist, unsigned seg) { - gate->offset_low = PTR_LOW(func); + gate->offset_low = (u16) func; + gate->bits.p = 1; + gate->bits.dpl = dpl; + gate->bits.zero = 0; + gate->bits.type = type; + gate->offset_middle = (u16) (func >> 16); +#ifdef CONFIG_X86_64 gate->segment = __KERNEL_CS; - gate->ist = ist; - gate->p = 1; - gate->dpl = dpl; - gate->zero0 = 0; - gate->zero1 = 0; - gate->type = type; - gate->offset_middle = PTR_MIDDLE(func); - gate->offset_high = PTR_HIGH(func); -} - + gate->bits.ist = ist; + gate->reserved = 0; + gate->offset_high = (u32) (func >> 32); #else -static inline void pack_gate(gate_desc *gate, unsigned char type, - unsigned long base, unsigned dpl, unsigned flags, - unsigned short seg) -{ - gate->a = (seg << 16) | (base & 0xffff); - gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8); -} - + gate->segment = seg; + gate->bits.ist = 0; #endif +} static inline int desc_empty(const void *ptr) { @@ -128,7 +121,6 @@ static inline int desc_empty(const void *ptr) #define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt)) #define store_gdt(dtr) native_store_gdt(dtr) -#define store_idt(dtr) native_store_idt(dtr) #define store_tr(tr) (tr = native_store_tr()) #define load_TLS(t, cpu) native_load_tls(t, cpu) @@ -173,35 +165,22 @@ native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int memcpy(&gdt[entry], desc, size); } -static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, - unsigned long limit, unsigned char type, - unsigned char flags) -{ - desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); - desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | - (limit & 0x000f0000) | ((type & 0xff) << 8) | - ((flags & 0xf) << 20); - desc->p = 1; -} - - -static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size) +static inline void set_tssldt_descriptor(void *d, unsigned long addr, + unsigned type, unsigned size) { -#ifdef CONFIG_X86_64 - struct ldttss_desc64 *desc = d; + struct ldttss_desc *desc = d; memset(desc, 0, sizeof(*desc)); - desc->limit0 = size & 0xFFFF; - desc->base0 = PTR_LOW(addr); - desc->base1 = PTR_MIDDLE(addr) & 0xFF; + desc->limit0 = (u16) size; + desc->base0 = (u16) addr; + desc->base1 = (addr >> 16) & 0xFF; desc->type = type; desc->p = 1; desc->limit1 = (size >> 16) & 0xF; - desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; - desc->base3 = PTR_HIGH(addr); -#else - pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); + desc->base2 = (addr >> 24) & 0xFF; +#ifdef CONFIG_X86_64 + desc->base3 = (u32) (addr >> 32); #endif } @@ -248,7 +227,7 @@ static inline void native_store_gdt(struct desc_ptr *dtr) asm volatile("sgdt %0":"=m" (*dtr)); } -static inline void native_store_idt(struct desc_ptr *dtr) +static inline void store_idt(struct desc_ptr *dtr) { asm volatile("sidt %0":"=m" (*dtr)); } @@ -401,147 +380,20 @@ static inline void set_desc_base(struct desc_struct *desc, unsigned long base) static inline unsigned long get_desc_limit(const struct desc_struct *desc) { - return desc->limit0 | (desc->limit << 16); + return desc->limit0 | (desc->limit1 << 16); } static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) { desc->limit0 = limit & 0xffff; - desc->limit = (limit >> 16) & 0xf; -} - -#ifdef CONFIG_X86_64 -static inline void set_nmi_gate(int gate, void *addr) -{ - gate_desc s; - - pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); - write_idt_entry(debug_idt_table, gate, &s); + desc->limit1 = (limit >> 16) & 0xf; } -#endif -#ifdef CONFIG_TRACING -extern struct desc_ptr trace_idt_descr; -extern gate_desc trace_idt_table[]; -static inline void write_trace_idt_entry(int entry, const gate_desc *gate) -{ - write_idt_entry(trace_idt_table, entry, gate); -} +void update_intr_gate(unsigned int n, const void *addr); +void alloc_intr_gate(unsigned int n, const void *addr); -static inline void _trace_set_gate(int gate, unsigned type, void *addr, - unsigned dpl, unsigned ist, unsigned seg) -{ - gate_desc s; - - pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); - /* - * does not need to be atomic because it is only done once at - * setup time - */ - write_trace_idt_entry(gate, &s); -} -#else -static inline void write_trace_idt_entry(int entry, const gate_desc *gate) -{ -} - -#define _trace_set_gate(gate, type, addr, dpl, ist, seg) -#endif - -static inline void _set_gate(int gate, unsigned type, void *addr, - unsigned dpl, unsigned ist, unsigned seg) -{ - gate_desc s; - - pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); - /* - * does not need to be atomic because it is only done once at - * setup time - */ - write_idt_entry(idt_table, gate, &s); - write_trace_idt_entry(gate, &s); -} - -/* - * This needs to use 'idt_table' rather than 'idt', and - * thus use the _nonmapped_ version of the IDT, as the - * Pentium F0 0F bugfix can have resulted in the mapped - * IDT being write-protected. - */ -#define set_intr_gate_notrace(n, addr) \ - do { \ - BUG_ON((unsigned)n > 0xFF); \ - _set_gate(n, GATE_INTERRUPT, (void *)addr, 0, 0, \ - __KERNEL_CS); \ - } while (0) - -#define set_intr_gate(n, addr) \ - do { \ - set_intr_gate_notrace(n, addr); \ - _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\ - 0, 0, __KERNEL_CS); \ - } while (0) - -extern int first_system_vector; -/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ extern unsigned long used_vectors[]; -static inline void alloc_system_vector(int vector) -{ - if (!test_bit(vector, used_vectors)) { - set_bit(vector, used_vectors); - if (first_system_vector > vector) - first_system_vector = vector; - } else { - BUG(); - } -} - -#define alloc_intr_gate(n, addr) \ - do { \ - alloc_system_vector(n); \ - set_intr_gate(n, addr); \ - } while (0) - -/* - * This routine sets up an interrupt gate at directory privilege level 3. - */ -static inline void set_system_intr_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); -} - -static inline void set_system_trap_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); -} - -static inline void set_trap_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); -} - -static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3)); -} - -static inline void set_intr_gate_ist(int n, void *addr, unsigned ist) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS); -} - -static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); -} - #ifdef CONFIG_X86_64 DECLARE_PER_CPU(u32, debug_idt_ctr); static inline bool is_debug_idt_enabled(void) @@ -567,31 +419,6 @@ static inline void load_debug_idt(void) } #endif -#ifdef CONFIG_TRACING -extern atomic_t trace_idt_ctr; -static inline bool is_trace_idt_enabled(void) -{ - if (atomic_read(&trace_idt_ctr)) - return true; - - return false; -} - -static inline void load_trace_idt(void) -{ - load_idt((const struct desc_ptr *)&trace_idt_descr); -} -#else -static inline bool is_trace_idt_enabled(void) -{ - return false; -} - -static inline void load_trace_idt(void) -{ -} -#endif - /* * The load_current_idt() must be called with interrupts disabled * to avoid races. That way the IDT will always be set back to the expected @@ -603,9 +430,25 @@ static inline void load_current_idt(void) { if (is_debug_idt_enabled()) load_debug_idt(); - else if (is_trace_idt_enabled()) - load_trace_idt(); else load_idt((const struct desc_ptr *)&idt_descr); } + +extern void idt_setup_early_handler(void); +extern void idt_setup_early_traps(void); +extern void idt_setup_traps(void); +extern void idt_setup_apic_and_irq_gates(void); + +#ifdef CONFIG_X86_64 +extern void idt_setup_early_pf(void); +extern void idt_setup_ist_traps(void); +extern void idt_setup_debugidt_traps(void); +#else +static inline void idt_setup_early_pf(void) { } +static inline void idt_setup_ist_traps(void) { } +static inline void idt_setup_debugidt_traps(void) { } +#endif + +extern void idt_invalidate(void *addr); + #endif /* _ASM_X86_DESC_H */ diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h index 49265345d4d223ffcf15e03ba2843ddaabe82668..346d252029b7080a902770c0e92c2e9a69cec734 100644 --- a/arch/x86/include/asm/desc_defs.h +++ b/arch/x86/include/asm/desc_defs.h @@ -11,34 +11,30 @@ #include -/* - * FIXME: Accessing the desc_struct through its fields is more elegant, - * and should be the one valid thing to do. However, a lot of open code - * still touches the a and b accessors, and doing this allow us to do it - * incrementally. We keep the signature as a struct, rather than a union, - * so we can get rid of it transparently in the future -- glommer - */ /* 8 byte segment descriptor */ struct desc_struct { - union { - struct { - unsigned int a; - unsigned int b; - }; - struct { - u16 limit0; - u16 base0; - unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1; - unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; - }; - }; + u16 limit0; + u16 base0; + u16 base1: 8, type: 4, s: 1, dpl: 2, p: 1; + u16 limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; } __attribute__((packed)); -#define GDT_ENTRY_INIT(flags, base, limit) { { { \ - .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \ - .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \ - ((limit) & 0xf0000) | ((base) & 0xff000000), \ - } } } +#define GDT_ENTRY_INIT(flags, base, limit) \ + { \ + .limit0 = (u16) (limit), \ + .limit1 = ((limit) >> 16) & 0x0F, \ + .base0 = (u16) (base), \ + .base1 = ((base) >> 16) & 0xFF, \ + .base2 = ((base) >> 24) & 0xFF, \ + .type = (flags & 0x0f), \ + .s = (flags >> 4) & 0x01, \ + .dpl = (flags >> 5) & 0x03, \ + .p = (flags >> 7) & 0x01, \ + .avl = (flags >> 12) & 0x01, \ + .l = (flags >> 13) & 0x01, \ + .d = (flags >> 14) & 0x01, \ + .g = (flags >> 15) & 0x01, \ + } enum { GATE_INTERRUPT = 0xE, @@ -47,49 +43,63 @@ enum { GATE_TASK = 0x5, }; -/* 16byte gate */ -struct gate_struct64 { - u16 offset_low; - u16 segment; - unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; - u16 offset_middle; - u32 offset_high; - u32 zero1; -} __attribute__((packed)); - -#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF) -#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH(x) ((unsigned long long)(x) >> 32) - enum { DESC_TSS = 0x9, DESC_LDT = 0x2, DESCTYPE_S = 0x10, /* !system */ }; -/* LDT or TSS descriptor in the GDT. 16 bytes. */ -struct ldttss_desc64 { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 5, dpl : 2, p : 1; - unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; - u32 base3; - u32 zero1; +/* LDT or TSS descriptor in the GDT. */ +struct ldttss_desc { + u16 limit0; + u16 base0; + + u16 base1 : 8, type : 5, dpl : 2, p : 1; + u16 limit1 : 4, zero0 : 3, g : 1, base2 : 8; +#ifdef CONFIG_X86_64 + u32 base3; + u32 zero1; +#endif } __attribute__((packed)); +typedef struct ldttss_desc ldt_desc; +typedef struct ldttss_desc tss_desc; + +struct idt_bits { + u16 ist : 3, + zero : 5, + type : 5, + dpl : 2, + p : 1; +} __attribute__((packed)); + +struct gate_struct { + u16 offset_low; + u16 segment; + struct idt_bits bits; + u16 offset_middle; +#ifdef CONFIG_X86_64 + u32 offset_high; + u32 reserved; +#endif +} __attribute__((packed)); + +typedef struct gate_struct gate_desc; + +static inline unsigned long gate_offset(const gate_desc *g) +{ #ifdef CONFIG_X86_64 -typedef struct gate_struct64 gate_desc; -typedef struct ldttss_desc64 ldt_desc; -typedef struct ldttss_desc64 tss_desc; -#define gate_offset(g) ((g).offset_low | ((unsigned long)(g).offset_middle << 16) | ((unsigned long)(g).offset_high << 32)) -#define gate_segment(g) ((g).segment) + return g->offset_low | ((unsigned long)g->offset_middle << 16) | + ((unsigned long) g->offset_high << 32); #else -typedef struct desc_struct gate_desc; -typedef struct desc_struct ldt_desc; -typedef struct desc_struct tss_desc; -#define gate_offset(g) (((g).b & 0xffff0000) | ((g).a & 0x0000ffff)) -#define gate_segment(g) ((g).a >> 16) + return g->offset_low | ((unsigned long)g->offset_middle << 16); #endif +} + +static inline unsigned long gate_segment(const gate_desc *g) +{ + return g->segment; +} struct desc_ptr { unsigned short size; diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index 5dff775af7cd6456f7177d9ce5888ae78dc6bc10..c10c9128f54e6b7296014a74e7a253a1eedaacd9 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -21,11 +21,13 @@ # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) +# define DISABLE_PCID 0 #else # define DISABLE_VME 0 # define DISABLE_K6_MTRR 0 # define DISABLE_CYRIX_ARR 0 # define DISABLE_CENTAUR_MCR 0 +# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31)) #endif /* CONFIG_X86_64 */ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS @@ -49,7 +51,7 @@ #define DISABLED_MASK1 0 #define DISABLED_MASK2 0 #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) -#define DISABLED_MASK4 0 +#define DISABLED_MASK4 (DISABLE_PCID) #define DISABLED_MASK5 0 #define DISABLED_MASK6 0 #define DISABLED_MASK7 0 diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 398c79889f5c43d384b72238ce025f140debeb0b..1387dafdba2d2c24061adb014354b82174f620d4 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_ISA # define ISA_DMA_BIT_MASK DMA_BIT_MASK(24) @@ -57,12 +58,12 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { - return paddr; + return __sme_set(paddr); } static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { - return daddr; + return __sme_clr(daddr); } #endif /* CONFIG_X86_DMA_REMAP */ diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h index 3c69fed215c56c3203e59d97a6c7e11381c97cf8..a8e15b04565b842def6a1bd1fa4b3b03db756c3c 100644 --- a/arch/x86/include/asm/dmi.h +++ b/arch/x86/include/asm/dmi.h @@ -13,9 +13,9 @@ static __always_inline __init void *dmi_alloc(unsigned len) } /* Use early IO mappings for DMI because it's initialized early */ -#define dmi_early_remap early_ioremap -#define dmi_early_unmap early_iounmap -#define dmi_remap ioremap_cache -#define dmi_unmap iounmap +#define dmi_early_remap early_memremap +#define dmi_early_unmap early_memunmap +#define dmi_remap(_x, _l) memremap(_x, _l, MEMREMAP_WB) +#define dmi_unmap(_x) memunmap(_x) #endif /* _ASM_X86_DMI_H */ diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/api.h index a504adc661a4954ca0d1c5ed04149fece0e042a3..cd266d830e4960fd023aa0411c991a2701db09f9 100644 --- a/arch/x86/include/asm/e820/api.h +++ b/arch/x86/include/asm/e820/api.h @@ -39,6 +39,8 @@ extern void e820__setup_pci_gap(void); extern void e820__reallocate_tables(void); extern void e820__register_nosave_regions(unsigned long limit_pfn); +extern int e820__get_entry_type(u64 start, u64 end); + /* * Returns true iff the specified range [start,end) is completely contained inside * the ISA region. diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 1c18d83d3f094d1f5abfa09a08b67e9cb6b7376d..04330c8d9af99d61c774ee166a9c0073fd99e536 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -126,15 +126,15 @@ do { \ pr_reg[4] = regs->di; \ pr_reg[5] = regs->bp; \ pr_reg[6] = regs->ax; \ - pr_reg[7] = regs->ds & 0xffff; \ - pr_reg[8] = regs->es & 0xffff; \ - pr_reg[9] = regs->fs & 0xffff; \ + pr_reg[7] = regs->ds; \ + pr_reg[8] = regs->es; \ + pr_reg[9] = regs->fs; \ pr_reg[11] = regs->orig_ax; \ pr_reg[12] = regs->ip; \ - pr_reg[13] = regs->cs & 0xffff; \ + pr_reg[13] = regs->cs; \ pr_reg[14] = regs->flags; \ pr_reg[15] = regs->sp; \ - pr_reg[16] = regs->ss & 0xffff; \ + pr_reg[16] = regs->ss; \ } while (0); #define ELF_CORE_COPY_REGS(pr_reg, regs) \ @@ -204,6 +204,7 @@ void set_personality_ia32(bool); #define ELF_CORE_COPY_REGS(pr_reg, regs) \ do { \ + unsigned long base; \ unsigned v; \ (pr_reg)[0] = (regs)->r15; \ (pr_reg)[1] = (regs)->r14; \ @@ -226,8 +227,8 @@ do { \ (pr_reg)[18] = (regs)->flags; \ (pr_reg)[19] = (regs)->sp; \ (pr_reg)[20] = (regs)->ss; \ - (pr_reg)[21] = current->thread.fsbase; \ - (pr_reg)[22] = current->thread.gsbase; \ + rdmsrl(MSR_FS_BASE, base); (pr_reg)[21] = base; \ + rdmsrl(MSR_KERNEL_GS_BASE, base); (pr_reg)[22] = base; \ asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ @@ -247,11 +248,11 @@ extern int force_personality32; /* * This is the base location for PIE (ET_DYN with INTERP) loads. On - * 64-bit, this is raised to 4GB to leave the entire 32-bit address + * 64-bit, this is above 4GB to leave the entire 32-bit address * space open for things that want to use the area for 32-bit pointers. */ #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \ - 0x100000000UL) + (TASK_SIZE / 3 * 2)) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space, @@ -304,8 +305,8 @@ static inline int mmap_is_ia32(void) test_thread_flag(TIF_ADDR32)); } -extern unsigned long tasksize_32bit(void); -extern unsigned long tasksize_64bit(void); +extern unsigned long task_size_32bit(void); +extern unsigned long task_size_64bit(int full_addr_space); extern unsigned long get_mmap_base(int is_legacy); #ifdef CONFIG_X86_32 diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index 07b06955a05df90575d2d66ffec0e0b44793a587..aa15d1f7e5307d92df578e024b2c6f508613b9d1 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h @@ -13,20 +13,14 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) -BUILD_INTERRUPT3(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR, - smp_irq_move_cleanup_interrupt) -BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt) +BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR) +BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR) #endif -BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) - #ifdef CONFIG_HAVE_KVM -BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR, - smp_kvm_posted_intr_ipi) -BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR, - smp_kvm_posted_intr_wakeup_ipi) -BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR, - smp_kvm_posted_intr_nested_ipi) +BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR) #endif /* @@ -41,6 +35,7 @@ BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR, BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) #ifdef CONFIG_IRQ_WORK BUILD_INTERRUPT(irq_work_interrupt, IRQ_WORK_VECTOR) diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index b65155cc3760a72b49b680c3f70923ddedf684d2..dcd9fb55e67991821d46602754a392c6f2ed0e06 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -157,6 +157,26 @@ static inline void __set_fixmap(enum fixed_addresses idx, } #endif +/* + * FIXMAP_PAGE_NOCACHE is used for MMIO. Memory encryption is not + * supported for MMIO addresses, so make sure that the memory encryption + * mask is not part of the page attributes. + */ +#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_IO_NOCACHE + +/* + * Early memremap routines used for in-place encryption. The mappings created + * by these routines are intended to be used as temporary mappings. + */ +void __init *early_memremap_encrypted(resource_size_t phys_addr, + unsigned long size); +void __init *early_memremap_encrypted_wp(resource_size_t phys_addr, + unsigned long size); +void __init *early_memremap_decrypted(resource_size_t phys_addr, + unsigned long size); +void __init *early_memremap_decrypted_wp(resource_size_t phys_addr, + unsigned long size); + #include #define __late_set_fixmap(idx, phys, flags) __set_fixmap(idx, phys, flags) diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 255645f60ca2b4be333de67a10c6780f364e6fb2..e3221ffa304e301858db746a03d6cf8600790004 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -23,11 +23,9 @@ /* * High level FPU state handling functions: */ -extern void fpu__activate_curr(struct fpu *fpu); -extern void fpu__activate_fpstate_read(struct fpu *fpu); -extern void fpu__activate_fpstate_write(struct fpu *fpu); -extern void fpu__current_fpstate_write_begin(void); -extern void fpu__current_fpstate_write_end(void); +extern void fpu__initialize(struct fpu *fpu); +extern void fpu__prepare_read(struct fpu *fpu); +extern void fpu__prepare_write(struct fpu *fpu); extern void fpu__save(struct fpu *fpu); extern void fpu__restore(struct fpu *fpu); extern int fpu__restore_sig(void __user *buf, int ia32_frame); @@ -120,20 +118,11 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu); err; \ }) -#define check_insn(insn, output, input...) \ -({ \ - int err; \ +#define kernel_insn(insn, output, input...) \ asm volatile("1:" #insn "\n\t" \ "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl $-1,%[err]\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err), output \ - : "0"(0), input); \ - err; \ -}) + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_fprestore) \ + : output : input) static inline int copy_fregs_to_user(struct fregs_state __user *fx) { @@ -153,20 +142,16 @@ static inline int copy_fxregs_to_user(struct fxregs_state __user *fx) static inline void copy_kernel_to_fxregs(struct fxregs_state *fx) { - int err; - if (IS_ENABLED(CONFIG_X86_32)) { - err = check_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx)); + kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx)); } else { if (IS_ENABLED(CONFIG_AS_FXSAVEQ)) { - err = check_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx)); + kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx)); } else { /* See comment in copy_fxregs_to_kernel() below. */ - err = check_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx), "m" (*fx)); + kernel_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx), "m" (*fx)); } } - /* Copying from a kernel buffer to FPU registers should never fail: */ - WARN_ON_FPU(err); } static inline int copy_user_to_fxregs(struct fxregs_state __user *fx) @@ -183,9 +168,7 @@ static inline int copy_user_to_fxregs(struct fxregs_state __user *fx) static inline void copy_kernel_to_fregs(struct fregs_state *fx) { - int err = check_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx)); - - WARN_ON_FPU(err); + kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx)); } static inline int copy_user_to_fregs(struct fregs_state __user *fx) @@ -281,18 +264,13 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact * XSAVE area format. */ -#define XSTATE_XRESTORE(st, lmask, hmask, err) \ +#define XSTATE_XRESTORE(st, lmask, hmask) \ asm volatile(ALTERNATIVE(XRSTOR, \ XRSTORS, X86_FEATURE_XSAVES) \ "\n" \ - "xor %[err], %[err]\n" \ "3:\n" \ - ".pushsection .fixup,\"ax\"\n" \ - "4: movl $-2, %[err]\n" \ - "jmp 3b\n" \ - ".popsection\n" \ - _ASM_EXTABLE(661b, 4b) \ - : [err] "=r" (err) \ + _ASM_EXTABLE_HANDLE(661b, 3b, ex_handler_fprestore)\ + : \ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ : "memory") @@ -336,7 +314,10 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) else XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); - /* We should never fault when copying from a kernel buffer: */ + /* + * We should never fault when copying from a kernel buffer, and the FPU + * state we set at boot time should be valid. + */ WARN_ON_FPU(err); } @@ -350,7 +331,7 @@ static inline void copy_xregs_to_kernel(struct xregs_state *xstate) u32 hmask = mask >> 32; int err; - WARN_ON(!alternatives_patched); + WARN_ON_FPU(!alternatives_patched); XSTATE_XSAVE(xstate, lmask, hmask, err); @@ -365,12 +346,8 @@ static inline void copy_kernel_to_xregs(struct xregs_state *xstate, u64 mask) { u32 lmask = mask; u32 hmask = mask >> 32; - int err; - - XSTATE_XRESTORE(xstate, lmask, hmask, err); - /* We should never fault when copying from a kernel buffer: */ - WARN_ON_FPU(err); + XSTATE_XRESTORE(xstate, lmask, hmask); } /* @@ -450,10 +427,10 @@ static inline int copy_fpregs_to_fpstate(struct fpu *fpu) return 0; } -static inline void __copy_kernel_to_fpregs(union fpregs_state *fpstate) +static inline void __copy_kernel_to_fpregs(union fpregs_state *fpstate, u64 mask) { if (use_xsave()) { - copy_kernel_to_xregs(&fpstate->xsave, -1); + copy_kernel_to_xregs(&fpstate->xsave, mask); } else { if (use_fxsr()) copy_kernel_to_fxregs(&fpstate->fxsave); @@ -477,7 +454,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate) : : [addr] "m" (fpstate)); } - __copy_kernel_to_fpregs(fpstate); + __copy_kernel_to_fpregs(fpstate, -1); } extern int copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size); @@ -526,37 +503,16 @@ static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu) */ static inline void fpregs_deactivate(struct fpu *fpu) { - WARN_ON_FPU(!fpu->fpregs_active); - - fpu->fpregs_active = 0; this_cpu_write(fpu_fpregs_owner_ctx, NULL); trace_x86_fpu_regs_deactivated(fpu); } static inline void fpregs_activate(struct fpu *fpu) { - WARN_ON_FPU(fpu->fpregs_active); - - fpu->fpregs_active = 1; this_cpu_write(fpu_fpregs_owner_ctx, fpu); trace_x86_fpu_regs_activated(fpu); } -/* - * The question "does this thread have fpu access?" - * is slightly racy, since preemption could come in - * and revoke it immediately after the test. - * - * However, even in that very unlikely scenario, - * we can just assume we have FPU access - typically - * to save the FP state - we'll just take a #NM - * fault and get the FPU access back. - */ -static inline int fpregs_active(void) -{ - return current->thread.fpu.fpregs_active; -} - /* * FPU state switching for scheduling. * @@ -571,14 +527,13 @@ static inline int fpregs_active(void) static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) { - if (old_fpu->fpregs_active) { + if (old_fpu->initialized) { if (!copy_fpregs_to_fpstate(old_fpu)) old_fpu->last_cpu = -1; else old_fpu->last_cpu = cpu; /* But leave fpu_fpregs_owner_ctx! */ - old_fpu->fpregs_active = 0; trace_x86_fpu_regs_deactivated(old_fpu); } else old_fpu->last_cpu = -1; @@ -595,7 +550,7 @@ switch_fpu_prepare(struct fpu *old_fpu, int cpu) static inline void switch_fpu_finish(struct fpu *new_fpu, int cpu) { bool preload = static_cpu_has(X86_FEATURE_FPU) && - new_fpu->fpstate_active; + new_fpu->initialized; if (preload) { if (!fpregs_state_valid(new_fpu, cpu)) @@ -617,8 +572,7 @@ static inline void user_fpu_begin(void) struct fpu *fpu = ¤t->thread.fpu; preempt_disable(); - if (!fpregs_active()) - fpregs_activate(fpu); + fpregs_activate(fpu); preempt_enable(); } diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h index 3c80f5b9c09d8cf5407378a39ba27cfa380bafbf..a1520575d86b81fd2521d7e4013856b7e70d4db2 100644 --- a/arch/x86/include/asm/fpu/types.h +++ b/arch/x86/include/asm/fpu/types.h @@ -68,6 +68,9 @@ struct fxregs_state { /* Default value for fxregs_state.mxcsr: */ #define MXCSR_DEFAULT 0x1f80 +/* Copy both mxcsr & mxcsr_flags with a single u64 memcpy: */ +#define MXCSR_AND_FLAGS_SIZE sizeof(u64) + /* * Software based FPU emulation state. This is arbitrary really, * it matches the x87 format to make it easier to understand: @@ -290,36 +293,13 @@ struct fpu { unsigned int last_cpu; /* - * @fpstate_active: + * @initialized: * - * This flag indicates whether this context is active: if the task + * This flag indicates whether this context is initialized: if the task * is not running then we can restore from this context, if the task * is running then we should save into this context. */ - unsigned char fpstate_active; - - /* - * @fpregs_active: - * - * This flag determines whether a given context is actively - * loaded into the FPU's registers and that those registers - * represent the task's current FPU state. - * - * Note the interaction with fpstate_active: - * - * # task does not use the FPU: - * fpstate_active == 0 - * - * # task uses the FPU and regs are active: - * fpstate_active == 1 && fpregs_active == 1 - * - * # the regs are inactive but still match fpstate: - * fpstate_active == 1 && fpregs_active == 0 && fpregs_owner == fpu - * - * The third state is what we use for the lazy restore optimization - * on lazy-switching CPUs. - */ - unsigned char fpregs_active; + unsigned char initialized; /* * @state: diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index 1b2799e0699a4d47a3ef191f6177f0a4abc13ceb..83fee2469eb76079771c668545db95e929d1446c 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -48,8 +48,12 @@ void fpu__xstate_clear_all_cpu_caps(void); void *get_xsave_addr(struct xregs_state *xsave, int xstate); const void *get_xsave_field_ptr(int xstate_field); int using_compacted_format(void); -int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, - void __user *ubuf, struct xregs_state *xsave); -int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, - struct xregs_state *xsave); +int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset, unsigned int size); +int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset, unsigned int size); +int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf); +int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf); + +/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ +extern int validate_xstate_header(const struct xstate_header *hdr); + #endif diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h index b4c1f545343663057460376157de5d9d55a6f528..f4dc9b63bdda9df2b4d79ae12c601ba6b9e0ec0d 100644 --- a/arch/x86/include/asm/futex.h +++ b/arch/x86/include/asm/futex.h @@ -41,20 +41,11 @@ "+m" (*uaddr), "=&r" (tem) \ : "r" (oparg), "i" (-EFAULT), "1" (0)) -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tem; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -80,30 +71,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index d6dbafbd420737a5ea5363c700940acb22a8c358..6dfe366a8804576719196970e8e6c92f84fb1408 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -46,26 +46,6 @@ extern asmlinkage void deferred_error_interrupt(void); extern asmlinkage void call_function_interrupt(void); extern asmlinkage void call_function_single_interrupt(void); -#ifdef CONFIG_TRACING -/* Interrupt handlers registered during init_IRQ */ -extern void trace_apic_timer_interrupt(void); -extern void trace_x86_platform_ipi(void); -extern void trace_error_interrupt(void); -extern void trace_irq_work_interrupt(void); -extern void trace_spurious_interrupt(void); -extern void trace_thermal_interrupt(void); -extern void trace_reschedule_interrupt(void); -extern void trace_threshold_interrupt(void); -extern void trace_deferred_error_interrupt(void); -extern void trace_call_function_interrupt(void); -extern void trace_call_function_single_interrupt(void); -#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt -#define trace_reboot_interrupt reboot_interrupt -#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi -#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi -#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi -#endif /* CONFIG_TRACING */ - #ifdef CONFIG_X86_LOCAL_APIC struct irq_data; struct pci_dev; diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 21126155a739f4a3495499f052abcd3eab5a0bb7..0ead9dbb91301d0f7f8923dcf33f25515bd182b8 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h @@ -43,6 +43,9 @@ struct hypervisor_x86 { /* pin current vcpu to specified physical cpu (run rarely) */ void (*pin_vcpu)(int); + + /* called during init_mem_mapping() to setup early mappings. */ + void (*init_mem_mapping)(void); }; extern const struct hypervisor_x86 *x86_hyper; @@ -57,8 +60,15 @@ extern const struct hypervisor_x86 x86_hyper_kvm; extern void init_hypervisor_platform(void); extern bool hypervisor_x2apic_available(void); extern void hypervisor_pin_vcpu(int cpu); + +static inline void hypervisor_init_mem_mapping(void) +{ + if (x86_hyper && x86_hyper->init_mem_mapping) + x86_hyper->init_mem_mapping(); +} #else static inline void init_hypervisor_platform(void) { } static inline bool hypervisor_x2apic_available(void) { return false; } +static inline void hypervisor_init_mem_mapping(void) { } #endif /* CONFIG_HYPERVISOR_GUEST */ #endif /* _ASM_X86_HYPERVISOR_H */ diff --git a/arch/x86/include/asm/init.h b/arch/x86/include/asm/init.h index 474eb8c66feeb2c98de2f5d6fe1db84de752c806..05c4aa00cc862e3b1dad1b344b0eddb9d6f44db4 100644 --- a/arch/x86/include/asm/init.h +++ b/arch/x86/include/asm/init.h @@ -7,6 +7,7 @@ struct x86_mapping_info { unsigned long page_flag; /* page flag for PMD or PUD entry */ unsigned long offset; /* ident mapping offset */ bool direct_gbpages; /* PUD level 1GB page support */ + unsigned long kernpg_flag; /* kernel pagetable flag override */ }; int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h deleted file mode 100644 index 597dc4995678b2ec82bd6e370fa13afcb8611e5c..0000000000000000000000000000000000000000 --- a/arch/x86/include/asm/intel_rdt.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef _ASM_X86_INTEL_RDT_H -#define _ASM_X86_INTEL_RDT_H - -#ifdef CONFIG_INTEL_RDT_A - -#include -#include -#include - -#include - -#define IA32_L3_QOS_CFG 0xc81 -#define IA32_L3_CBM_BASE 0xc90 -#define IA32_L2_CBM_BASE 0xd10 -#define IA32_MBA_THRTL_BASE 0xd50 - -#define L3_QOS_CDP_ENABLE 0x01ULL - -/** - * struct rdtgroup - store rdtgroup's data in resctrl file system. - * @kn: kernfs node - * @rdtgroup_list: linked list for all rdtgroups - * @closid: closid for this rdtgroup - * @cpu_mask: CPUs assigned to this rdtgroup - * @flags: status bits - * @waitcount: how many cpus expect to find this - * group when they acquire rdtgroup_mutex - */ -struct rdtgroup { - struct kernfs_node *kn; - struct list_head rdtgroup_list; - int closid; - struct cpumask cpu_mask; - int flags; - atomic_t waitcount; -}; - -/* rdtgroup.flags */ -#define RDT_DELETED 1 - -/* rftype.flags */ -#define RFTYPE_FLAGS_CPUS_LIST 1 - -/* List of all resource groups */ -extern struct list_head rdt_all_groups; - -extern int max_name_width, max_data_width; - -int __init rdtgroup_init(void); - -/** - * struct rftype - describe each file in the resctrl file system - * @name: File name - * @mode: Access mode - * @kf_ops: File operations - * @flags: File specific RFTYPE_FLAGS_* flags - * @seq_show: Show content of the file - * @write: Write to the file - */ -struct rftype { - char *name; - umode_t mode; - struct kernfs_ops *kf_ops; - unsigned long flags; - - int (*seq_show)(struct kernfs_open_file *of, - struct seq_file *sf, void *v); - /* - * write() is the generic write callback which maps directly to - * kernfs write operation and overrides all other operations. - * Maximum write size is determined by ->max_write_len. - */ - ssize_t (*write)(struct kernfs_open_file *of, - char *buf, size_t nbytes, loff_t off); -}; - -/** - * struct rdt_domain - group of cpus sharing an RDT resource - * @list: all instances of this resource - * @id: unique id for this instance - * @cpu_mask: which cpus share this resource - * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) - * @new_ctrl: new ctrl value to be loaded - * @have_new_ctrl: did user provide new_ctrl for this domain - */ -struct rdt_domain { - struct list_head list; - int id; - struct cpumask cpu_mask; - u32 *ctrl_val; - u32 new_ctrl; - bool have_new_ctrl; -}; - -/** - * struct msr_param - set a range of MSRs from a domain - * @res: The resource to use - * @low: Beginning index from base MSR - * @high: End index - */ -struct msr_param { - struct rdt_resource *res; - int low; - int high; -}; - -/** - * struct rdt_cache - Cache allocation related data - * @cbm_len: Length of the cache bit mask - * @min_cbm_bits: Minimum number of consecutive bits to be set - * @cbm_idx_mult: Multiplier of CBM index - * @cbm_idx_offset: Offset of CBM index. CBM index is computed by: - * closid * cbm_idx_multi + cbm_idx_offset - * in a cache bit mask - */ -struct rdt_cache { - unsigned int cbm_len; - unsigned int min_cbm_bits; - unsigned int cbm_idx_mult; - unsigned int cbm_idx_offset; -}; - -/** - * struct rdt_membw - Memory bandwidth allocation related data - * @max_delay: Max throttle delay. Delay is the hardware - * representation for memory bandwidth. - * @min_bw: Minimum memory bandwidth percentage user can request - * @bw_gran: Granularity at which the memory bandwidth is allocated - * @delay_linear: True if memory B/W delay is in linear scale - * @mb_map: Mapping of memory B/W percentage to memory B/W delay - */ -struct rdt_membw { - u32 max_delay; - u32 min_bw; - u32 bw_gran; - u32 delay_linear; - u32 *mb_map; -}; - -/** - * struct rdt_resource - attributes of an RDT resource - * @enabled: Is this feature enabled on this machine - * @capable: Is this feature available on this machine - * @name: Name to use in "schemata" file - * @num_closid: Number of CLOSIDs available - * @cache_level: Which cache level defines scope of this resource - * @default_ctrl: Specifies default cache cbm or memory B/W percent. - * @msr_base: Base MSR address for CBMs - * @msr_update: Function pointer to update QOS MSRs - * @data_width: Character width of data when displaying - * @domains: All domains for this resource - * @cache: Cache allocation related data - * @info_files: resctrl info files for the resource - * @nr_info_files: Number of info files - * @format_str: Per resource format string to show domain value - * @parse_ctrlval: Per resource function pointer to parse control values - */ -struct rdt_resource { - bool enabled; - bool capable; - char *name; - int num_closid; - int cache_level; - u32 default_ctrl; - unsigned int msr_base; - void (*msr_update) (struct rdt_domain *d, struct msr_param *m, - struct rdt_resource *r); - int data_width; - struct list_head domains; - struct rdt_cache cache; - struct rdt_membw membw; - struct rftype *info_files; - int nr_info_files; - const char *format_str; - int (*parse_ctrlval) (char *buf, struct rdt_resource *r, - struct rdt_domain *d); -}; - -void rdt_get_cache_infofile(struct rdt_resource *r); -void rdt_get_mba_infofile(struct rdt_resource *r); -int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d); -int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d); - -extern struct mutex rdtgroup_mutex; - -extern struct rdt_resource rdt_resources_all[]; -extern struct rdtgroup rdtgroup_default; -DECLARE_STATIC_KEY_FALSE(rdt_enable_key); - -int __init rdtgroup_init(void); - -enum { - RDT_RESOURCE_L3, - RDT_RESOURCE_L3DATA, - RDT_RESOURCE_L3CODE, - RDT_RESOURCE_L2, - RDT_RESOURCE_MBA, - - /* Must be the last */ - RDT_NUM_RESOURCES, -}; - -#define for_each_capable_rdt_resource(r) \ - for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ - r++) \ - if (r->capable) - -#define for_each_enabled_rdt_resource(r) \ - for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ - r++) \ - if (r->enabled) - -/* CPUID.(EAX=10H, ECX=ResID=1).EAX */ -union cpuid_0x10_1_eax { - struct { - unsigned int cbm_len:5; - } split; - unsigned int full; -}; - -/* CPUID.(EAX=10H, ECX=ResID=3).EAX */ -union cpuid_0x10_3_eax { - struct { - unsigned int max_delay:12; - } split; - unsigned int full; -}; - -/* CPUID.(EAX=10H, ECX=ResID).EDX */ -union cpuid_0x10_x_edx { - struct { - unsigned int cos_max:16; - } split; - unsigned int full; -}; - -DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid); - -void rdt_ctrl_update(void *arg); -struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); -void rdtgroup_kn_unlock(struct kernfs_node *kn); -ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, - char *buf, size_t nbytes, loff_t off); -int rdtgroup_schemata_show(struct kernfs_open_file *of, - struct seq_file *s, void *v); - -/* - * intel_rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR - * - * Following considerations are made so that this has minimal impact - * on scheduler hot path: - * - This will stay as no-op unless we are running on an Intel SKU - * which supports resource control and we enable by mounting the - * resctrl file system. - * - Caches the per cpu CLOSid values and does the MSR write only - * when a task with a different CLOSid is scheduled in. - * - * Must be called with preemption disabled. - */ -static inline void intel_rdt_sched_in(void) -{ - if (static_branch_likely(&rdt_enable_key)) { - struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - int closid; - - /* - * If this task has a closid assigned, use it. - * Else use the closid assigned to this cpu. - */ - closid = current->closid; - if (closid == 0) - closid = this_cpu_read(cpu_closid); - - if (closid != state->closid) { - state->closid = closid; - wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, closid); - } - } -} - -#else - -static inline void intel_rdt_sched_in(void) {} - -#endif /* CONFIG_INTEL_RDT_A */ -#endif /* _ASM_X86_INTEL_RDT_H */ diff --git a/arch/x86/include/asm/intel_rdt_common.h b/arch/x86/include/asm/intel_rdt_common.h deleted file mode 100644 index b31081b894076092e15654a3659fbd860e4ead84..0000000000000000000000000000000000000000 --- a/arch/x86/include/asm/intel_rdt_common.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _ASM_X86_INTEL_RDT_COMMON_H -#define _ASM_X86_INTEL_RDT_COMMON_H - -#define MSR_IA32_PQR_ASSOC 0x0c8f - -/** - * struct intel_pqr_state - State cache for the PQR MSR - * @rmid: The cached Resource Monitoring ID - * @closid: The cached Class Of Service ID - * @rmid_usecnt: The usage counter for rmid - * - * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the - * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always - * contains both parts, so we need to cache them. - * - * The cache also helps to avoid pointless updates if the value does - * not change. - */ -struct intel_pqr_state { - u32 rmid; - u32 closid; - int rmid_usecnt; -}; - -DECLARE_PER_CPU(struct intel_pqr_state, pqr_state); - -#endif /* _ASM_X86_INTEL_RDT_COMMON_H */ diff --git a/arch/x86/include/asm/intel_rdt_sched.h b/arch/x86/include/asm/intel_rdt_sched.h new file mode 100644 index 0000000000000000000000000000000000000000..b4bbf8b21512f9423bbe557ad3255c39650565af --- /dev/null +++ b/arch/x86/include/asm/intel_rdt_sched.h @@ -0,0 +1,92 @@ +#ifndef _ASM_X86_INTEL_RDT_SCHED_H +#define _ASM_X86_INTEL_RDT_SCHED_H + +#ifdef CONFIG_INTEL_RDT + +#include +#include + +#define IA32_PQR_ASSOC 0x0c8f + +/** + * struct intel_pqr_state - State cache for the PQR MSR + * @cur_rmid: The cached Resource Monitoring ID + * @cur_closid: The cached Class Of Service ID + * @default_rmid: The user assigned Resource Monitoring ID + * @default_closid: The user assigned cached Class Of Service ID + * + * The upper 32 bits of IA32_PQR_ASSOC contain closid and the + * lower 10 bits rmid. The update to IA32_PQR_ASSOC always + * contains both parts, so we need to cache them. This also + * stores the user configured per cpu CLOSID and RMID. + * + * The cache also helps to avoid pointless updates if the value does + * not change. + */ +struct intel_pqr_state { + u32 cur_rmid; + u32 cur_closid; + u32 default_rmid; + u32 default_closid; +}; + +DECLARE_PER_CPU(struct intel_pqr_state, pqr_state); + +DECLARE_STATIC_KEY_FALSE(rdt_enable_key); +DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key); +DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); + +/* + * __intel_rdt_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR + * + * Following considerations are made so that this has minimal impact + * on scheduler hot path: + * - This will stay as no-op unless we are running on an Intel SKU + * which supports resource control or monitoring and we enable by + * mounting the resctrl file system. + * - Caches the per cpu CLOSid/RMID values and does the MSR write only + * when a task with a different CLOSid/RMID is scheduled in. + * - We allocate RMIDs/CLOSids globally in order to keep this as + * simple as possible. + * Must be called with preemption disabled. + */ +static void __intel_rdt_sched_in(void) +{ + struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); + u32 closid = state->default_closid; + u32 rmid = state->default_rmid; + + /* + * If this task has a closid/rmid assigned, use it. + * Else use the closid/rmid assigned to this cpu. + */ + if (static_branch_likely(&rdt_alloc_enable_key)) { + if (current->closid) + closid = current->closid; + } + + if (static_branch_likely(&rdt_mon_enable_key)) { + if (current->rmid) + rmid = current->rmid; + } + + if (closid != state->cur_closid || rmid != state->cur_rmid) { + state->cur_closid = closid; + state->cur_rmid = rmid; + wrmsr(IA32_PQR_ASSOC, rmid, closid); + } +} + +static inline void intel_rdt_sched_in(void) +{ + if (static_branch_likely(&rdt_enable_key)) + __intel_rdt_sched_in(); +} + +#else + +static inline void intel_rdt_sched_in(void) {} + +#endif /* CONFIG_INTEL_RDT */ + +#endif /* _ASM_X86_INTEL_RDT_SCHED_H */ diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 48febf07e828099d0580be40ad82a8baee6ade18..c40a95c33bb8434c8b41641e57c38a79eeddb7ad 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -69,6 +69,9 @@ build_mmio_write(__writeb, "b", unsigned char, "q", ) build_mmio_write(__writew, "w", unsigned short, "r", ) build_mmio_write(__writel, "l", unsigned int, "r", ) +#define readb readb +#define readw readw +#define readl readl #define readb_relaxed(a) __readb(a) #define readw_relaxed(a) __readw(a) #define readl_relaxed(a) __readl(a) @@ -76,6 +79,9 @@ build_mmio_write(__writel, "l", unsigned int, "r", ) #define __raw_readw __readw #define __raw_readl __readl +#define writeb writeb +#define writew writew +#define writel writel #define writeb_relaxed(v, a) __writeb(v, a) #define writew_relaxed(v, a) __writew(v, a) #define writel_relaxed(v, a) __writel(v, a) @@ -88,13 +94,15 @@ build_mmio_write(__writel, "l", unsigned int, "r", ) #ifdef CONFIG_X86_64 build_mmio_read(readq, "q", unsigned long, "=r", :"memory") +build_mmio_read(__readq, "q", unsigned long, "=r", ) build_mmio_write(writeq, "q", unsigned long, "r", :"memory") +build_mmio_write(__writeq, "q", unsigned long, "r", ) -#define readq_relaxed(a) readq(a) -#define writeq_relaxed(v, a) writeq(v, a) +#define readq_relaxed(a) __readq(a) +#define writeq_relaxed(v, a) __writeq(v, a) -#define __raw_readq(a) readq(a) -#define __raw_writeq(val, addr) writeq(val, addr) +#define __raw_readq __readq +#define __raw_writeq __writeq /* Let people know that we have them */ #define readq readq @@ -119,6 +127,7 @@ static inline phys_addr_t virt_to_phys(volatile void *address) { return __pa(address); } +#define virt_to_phys virt_to_phys /** * phys_to_virt - map physical address to virtual @@ -137,6 +146,7 @@ static inline void *phys_to_virt(phys_addr_t address) { return __va(address); } +#define phys_to_virt phys_to_virt /* * Change "struct page" to physical address. @@ -169,11 +179,14 @@ static inline unsigned int isa_virt_to_bus(volatile void *address) * else, you probably want one of the following. */ extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size); +#define ioremap_nocache ioremap_nocache extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size); #define ioremap_uc ioremap_uc extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size); +#define ioremap_cache ioremap_cache extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val); +#define ioremap_prot ioremap_prot /** * ioremap - map bus memory into CPU space @@ -193,8 +206,10 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size) { return ioremap_nocache(offset, size); } +#define ioremap ioremap extern void iounmap(volatile void __iomem *addr); +#define iounmap iounmap extern void set_iounmap_nonlazy(void); @@ -202,53 +217,6 @@ extern void set_iounmap_nonlazy(void); #include -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -/** - * memset_io Set a range of I/O memory to a constant value - * @addr: The beginning of the I/O-memory range to set - * @val: The value to set the memory to - * @count: The number of bytes to set - * - * Set a range of I/O memory to a given value. - */ -static inline void -memset_io(volatile void __iomem *addr, unsigned char val, size_t count) -{ - memset((void __force *)addr, val, count); -} - -/** - * memcpy_fromio Copy a block of data from I/O memory - * @dst: The (RAM) destination for the copy - * @src: The (I/O memory) source for the data - * @count: The number of bytes to copy - * - * Copy a block of data from I/O memory. - */ -static inline void -memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count) -{ - memcpy(dst, (const void __force *)src, count); -} - -/** - * memcpy_toio Copy a block of data into I/O memory - * @dst: The (I/O memory) destination for the copy - * @src: The (RAM) source for the data - * @count: The number of bytes to copy - * - * Copy a block of data to I/O memory. - */ -static inline void -memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) -{ - memcpy((void __force *)dst, src, count); -} - /* * ISA space is 'always mapped' on a typical x86 system, no need to * explicitly ioremap() it. The fact that the ISA IO space is mapped @@ -341,13 +309,38 @@ BUILDIO(b, b, char) BUILDIO(w, w, short) BUILDIO(l, , int) +#define inb inb +#define inw inw +#define inl inl +#define inb_p inb_p +#define inw_p inw_p +#define inl_p inl_p +#define insb insb +#define insw insw +#define insl insl + +#define outb outb +#define outw outw +#define outl outl +#define outb_p outb_p +#define outw_p outw_p +#define outl_p outl_p +#define outsb outsb +#define outsw outsw +#define outsl outsl + extern void *xlate_dev_mem_ptr(phys_addr_t phys); extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); +#define xlate_dev_mem_ptr xlate_dev_mem_ptr +#define unxlate_dev_mem_ptr unxlate_dev_mem_ptr + extern int ioremap_change_attr(unsigned long vaddr, unsigned long size, enum page_cache_mode pcm); extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size); +#define ioremap_wc ioremap_wc extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size); +#define ioremap_wt ioremap_wt extern bool is_early_ioremap_ptep(pte_t *ptep); @@ -365,6 +358,9 @@ extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, #define IO_SPACE_LIMIT 0xffff +#include +#undef PCI_IOBASE + #ifdef CONFIG_MTRR extern int __must_check arch_phys_wc_index(int handle); #define arch_phys_wc_index arch_phys_wc_index @@ -381,4 +377,12 @@ extern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size) #define arch_io_reserve_memtype_wc arch_io_reserve_memtype_wc #endif +extern bool arch_memremap_can_ram_remap(resource_size_t offset, + unsigned long size, + unsigned long flags); +#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap + +extern bool phys_mem_access_encrypted(unsigned long phys_addr, + unsigned long size); + #endif /* _ASM_X86_IO_H */ diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 668cca540025b017e78ba49aba4f762c9a733abb..9958ceea2fa3c7bd3b48571eaf9d35fb82b6afd4 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -42,10 +42,6 @@ extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); extern __visible unsigned int do_IRQ(struct pt_regs *regs); -/* Interrupt vector management */ -extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -extern int vector_used_by_percpu_irq(unsigned int vector); - extern void init_ISA_irqs(void); #ifdef CONFIG_X86_LOCAL_APIC diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h index f70604125286b90d820bc14be0b65ecccb4f7a44..ddbb8ea0f5a9fbde772a43e4bd7b1108c363e19b 100644 --- a/arch/x86/include/asm/irq_work.h +++ b/arch/x86/include/asm/irq_work.h @@ -3,9 +3,17 @@ #include +#ifdef CONFIG_X86_LOCAL_APIC static inline bool arch_irq_work_has_interrupt(void) { return boot_cpu_has(X86_FEATURE_APIC); } +extern void arch_irq_work_raise(void); +#else +static inline bool arch_irq_work_has_interrupt(void) +{ + return false; +} +#endif #endif /* _ASM_IRQ_WORK_H */ diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h index 70ef205489f00e53ff568180c4dcbf6fb9e6ded1..942c1f444da88ddeb182e57f582a068c15cb2717 100644 --- a/arch/x86/include/asm/kexec.h +++ b/arch/x86/include/asm/kexec.h @@ -147,7 +147,8 @@ unsigned long relocate_kernel(unsigned long indirection_page, unsigned long page_list, unsigned long start_address, - unsigned int preserve_context); + unsigned int preserve_context, + unsigned int sme_active); #endif #define ARCH_HAS_KIMAGE_ARCH @@ -207,6 +208,14 @@ struct kexec_entry64_regs { uint64_t r15; uint64_t rip; }; + +extern int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, + gfp_t gfp); +#define arch_kexec_post_alloc_pages arch_kexec_post_alloc_pages + +extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages); +#define arch_kexec_pre_free_pages arch_kexec_pre_free_pages + #endif typedef void crash_vmclear_fn(void); diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index fde36f189836db83af655652f44eec92820072b8..fa2558e120249e6c36e368e396d2c9e188c57056 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -219,8 +219,8 @@ struct x86_emulate_ops { struct x86_instruction_info *info, enum x86_intercept_stage stage); - void (*get_cpuid)(struct x86_emulate_ctxt *ctxt, - u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); + bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx, + u32 *ecx, u32 *edx, bool check_limit); void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked); unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt); diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 87ac4fba6d8e12f07e8a9f191bdb028a1c3e6234..c73e493adf0748108c31389ca62437267ea877e2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -79,15 +79,14 @@ | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \ | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) -#define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL #define CR3_PCID_INVD BIT_64(63) #define CR4_RESERVED_BITS \ (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\ | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \ | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ - | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP \ - | X86_CR4_PKE)) + | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \ + | X86_CR4_SMAP | X86_CR4_PKE)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) @@ -204,7 +203,6 @@ enum { #define PFERR_GUEST_PAGE_MASK (1ULL << PFERR_GUEST_PAGE_BIT) #define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \ - PFERR_USER_MASK | \ PFERR_WRITE_MASK | \ PFERR_PRESENT_MASK) @@ -317,15 +315,17 @@ struct kvm_pio_request { int size; }; +#define PT64_ROOT_MAX_LEVEL 5 + struct rsvd_bits_validate { - u64 rsvd_bits_mask[2][4]; + u64 rsvd_bits_mask[2][PT64_ROOT_MAX_LEVEL]; u64 bad_mt_xwr; }; /* - * x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level - * 32-bit). The kvm_mmu structure abstracts the details of the current mmu - * mode. + * x86 supports 4 paging modes (5-level 64-bit, 4-level 64-bit, 3-level 32-bit, + * and 2-level 32-bit). The kvm_mmu structure abstracts the details of the + * current mmu mode. */ struct kvm_mmu { void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root); @@ -492,6 +492,7 @@ struct kvm_vcpu_arch { unsigned long cr4; unsigned long cr4_guest_owned_bits; unsigned long cr8; + u32 pkru; u32 hflags; u64 efer; u64 apic_base; @@ -547,8 +548,8 @@ struct kvm_vcpu_arch { struct kvm_queued_exception { bool pending; + bool injected; bool has_error_code; - bool reinject; u8 nr; u32 error_code; u8 nested_apf; @@ -686,8 +687,12 @@ struct kvm_vcpu_arch { int pending_ioapic_eoi; int pending_external_vector; - /* GPA available (AMD only) */ + /* GPA available */ bool gpa_available; + gpa_t gpa_val; + + /* be preempted when it's in kernel-mode(cpl=0) */ + bool preempted_in_kernel; }; struct kvm_lpage_info { @@ -946,7 +951,6 @@ struct kvm_x86_ops { void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); - u32 (*get_pkru)(struct kvm_vcpu *vcpu); void (*tlb_flush)(struct kvm_vcpu *vcpu); @@ -968,7 +972,7 @@ struct kvm_x86_ops { void (*enable_nmi_window)(struct kvm_vcpu *vcpu); void (*enable_irq_window)(struct kvm_vcpu *vcpu); void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr); - bool (*get_enable_apicv)(void); + bool (*get_enable_apicv)(struct kvm_vcpu *vcpu); void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu); void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr); void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr); @@ -978,7 +982,7 @@ struct kvm_x86_ops { void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu); int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); - int (*get_tdp_level)(void); + int (*get_tdp_level)(struct kvm_vcpu *vcpu); u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); int (*get_lpage_level)(void); bool (*rdtscp_supported)(void); @@ -1078,7 +1082,7 @@ void kvm_mmu_init_vm(struct kvm *kvm); void kvm_mmu_uninit_vm(struct kvm *kvm); void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 p_mask, - u64 acc_track_mask); + u64 acc_track_mask, u64 me_mask); void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, @@ -1296,20 +1300,6 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); } -static inline u64 get_canonical(u64 la) -{ - return ((int64_t)la << 16) >> 16; -} - -static inline bool is_noncanonical_address(u64 la) -{ -#ifdef CONFIG_X86_64 - return get_canonical(la) != la; -#else - return false; -#endif -} - #define TSS_IOPB_BASE_OFFSET 0x66 #define TSS_BASE_SIZE 0x68 #define TSS_IOPB_SIZE (65536 / 8) @@ -1374,8 +1364,6 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu); -void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, - unsigned long address); void kvm_define_shared_msr(unsigned index, u32 msr); int kvm_set_shared_msr(unsigned index, u64 val, u64 mask); diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index bc62e7cbf1b1f883fc9acb0a145305384a3bf062..59ad3d132353280cae5a1ba4f3a8ae0efe996331 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -88,7 +88,7 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, bool kvm_para_available(void); unsigned int kvm_arch_para_features(void); void __init kvm_guest_init(void); -void kvm_async_pf_task_wait(u32 token); +void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); void kvm_async_pf_task_wake(u32 token); u32 kvm_read_and_reset_pf_reason(void); extern void kvm_disable_steal_time(void); @@ -103,7 +103,7 @@ static inline void kvm_spinlock_init(void) #else /* CONFIG_KVM_GUEST */ #define kvm_guest_init() do {} while (0) -#define kvm_async_pf_task_wait(T) do {} while(0) +#define kvm_async_pf_task_wait(T, I) do {} while(0) #define kvm_async_pf_task_wake(T) do {} while(0) static inline bool kvm_para_available(void) diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h deleted file mode 100644 index 73d0c9b92087c4eb64f834c21df64889529f72fd..0000000000000000000000000000000000000000 --- a/arch/x86/include/asm/lguest.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _ASM_X86_LGUEST_H -#define _ASM_X86_LGUEST_H - -#define GDT_ENTRY_LGUEST_CS 10 -#define GDT_ENTRY_LGUEST_DS 11 -#define LGUEST_CS (GDT_ENTRY_LGUEST_CS * 8) -#define LGUEST_DS (GDT_ENTRY_LGUEST_DS * 8) - -#ifndef __ASSEMBLY__ -#include - -#define GUEST_PL 1 - -/* Page for Switcher text itself, then two pages per cpu */ -#define SWITCHER_TEXT_PAGES (1) -#define SWITCHER_STACK_PAGES (2 * nr_cpu_ids) -#define TOTAL_SWITCHER_PAGES (SWITCHER_TEXT_PAGES + SWITCHER_STACK_PAGES) - -/* Where we map the Switcher, in both Host and Guest. */ -extern unsigned long switcher_addr; - -/* Found in switcher.S */ -extern unsigned long default_idt_entries[]; - -/* Declarations for definitions in arch/x86/lguest/head_32.S */ -extern char lguest_noirq_iret[]; -extern const char lgstart_cli[], lgend_cli[]; -extern const char lgstart_pushf[], lgend_pushf[]; - -extern void lguest_iret(void); -extern void lguest_init(void); - -struct lguest_regs { - /* Manually saved part. */ - unsigned long eax, ebx, ecx, edx; - unsigned long esi, edi, ebp; - unsigned long gs; - unsigned long fs, ds, es; - unsigned long trapnum, errcode; - /* Trap pushed part */ - unsigned long eip; - unsigned long cs; - unsigned long eflags; - unsigned long esp; - unsigned long ss; -}; - -/* This is a guest-specific page (mapped ro) into the guest. */ -struct lguest_ro_state { - /* Host information we need to restore when we switch back. */ - u32 host_cr3; - struct desc_ptr host_idt_desc; - struct desc_ptr host_gdt_desc; - u32 host_sp; - - /* Fields which are used when guest is running. */ - struct desc_ptr guest_idt_desc; - struct desc_ptr guest_gdt_desc; - struct x86_hw_tss guest_tss; - struct desc_struct guest_idt[IDT_ENTRIES]; - struct desc_struct guest_gdt[GDT_ENTRIES]; -}; - -struct lg_cpu_arch { - /* The GDT entries copied into lguest_ro_state when running. */ - struct desc_struct gdt[GDT_ENTRIES]; - - /* The IDT entries: some copied into lguest_ro_state when running. */ - struct desc_struct idt[IDT_ENTRIES]; - - /* The address of the last guest-visible pagefault (ie. cr2). */ - unsigned long last_pagefault; -}; - -static inline void lguest_set_ts(void) -{ - u32 cr0; - - cr0 = read_cr0(); - if (!(cr0 & 8)) - write_cr0(cr0 | 8); -} - -/* Full 4G segment descriptors, suitable for CS and DS. */ -#define FULL_EXEC_SEGMENT \ - ((struct desc_struct)GDT_ENTRY_INIT(0xc09b, 0, 0xfffff)) -#define FULL_SEGMENT ((struct desc_struct)GDT_ENTRY_INIT(0xc093, 0, 0xfffff)) - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_X86_LGUEST_H */ diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h deleted file mode 100644 index 6c119cfae218bb6cce5b53d1bbae9427835f207c..0000000000000000000000000000000000000000 --- a/arch/x86/include/asm/lguest_hcall.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Architecture specific portion of the lguest hypercalls */ -#ifndef _ASM_X86_LGUEST_HCALL_H -#define _ASM_X86_LGUEST_HCALL_H - -#define LHCALL_FLUSH_ASYNC 0 -#define LHCALL_LGUEST_INIT 1 -#define LHCALL_SHUTDOWN 2 -#define LHCALL_NEW_PGTABLE 4 -#define LHCALL_FLUSH_TLB 5 -#define LHCALL_LOAD_IDT_ENTRY 6 -#define LHCALL_SET_STACK 7 -#define LHCALL_SET_CLOCKEVENT 9 -#define LHCALL_HALT 10 -#define LHCALL_SET_PMD 13 -#define LHCALL_SET_PTE 14 -#define LHCALL_SET_PGD 15 -#define LHCALL_LOAD_TLS 16 -#define LHCALL_LOAD_GDT_ENTRY 18 -#define LHCALL_SEND_INTERRUPTS 19 - -#define LGUEST_TRAP_ENTRY 0x1F - -/* Argument number 3 to LHCALL_LGUEST_SHUTDOWN */ -#define LGUEST_SHUTDOWN_POWEROFF 1 -#define LGUEST_SHUTDOWN_RESTART 2 - -#ifndef __ASSEMBLY__ -#include - -/*G:030 - * But first, how does our Guest contact the Host to ask for privileged - * operations? There are two ways: the direct way is to make a "hypercall", - * to make requests of the Host Itself. - * - * Our hypercall mechanism uses the highest unused trap code (traps 32 and - * above are used by real hardware interrupts). Seventeen hypercalls are - * available: the hypercall number is put in the %eax register, and the - * arguments (when required) are placed in %ebx, %ecx, %edx and %esi. - * If a return value makes sense, it's returned in %eax. - * - * Grossly invalid calls result in Sudden Death at the hands of the vengeful - * Host, rather than returning failure. This reflects Winston Churchill's - * definition of a gentleman: "someone who is only rude intentionally". - */ -static inline unsigned long -hcall(unsigned long call, - unsigned long arg1, unsigned long arg2, unsigned long arg3, - unsigned long arg4) -{ - /* "int" is the Intel instruction to trigger a trap. */ - asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) - /* The call in %eax (aka "a") might be overwritten */ - : "=a"(call) - /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */ - : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) - /* "memory" means this might write somewhere in memory. - * This isn't true for all calls, but it's safe to tell - * gcc that it might happen so it doesn't get clever. */ - : "memory"); - return call; -} -/*:*/ - -/* Can't use our min() macro here: needs to be a constant */ -#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) - -#define LHCALL_RING_SIZE 64 -struct hcall_args { - /* These map directly onto eax/ebx/ecx/edx/esi in struct lguest_regs */ - unsigned long arg0, arg1, arg2, arg3, arg4; -}; - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_X86_LGUEST_HCALL_H */ diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h new file mode 100644 index 0000000000000000000000000000000000000000..6a77c63540f7585477229f27fc1797bc1bdd5719 --- /dev/null +++ b/arch/x86/include/asm/mem_encrypt.h @@ -0,0 +1,80 @@ +/* + * AMD Memory Encryption Support + * + * Copyright (C) 2016 Advanced Micro Devices, Inc. + * + * Author: Tom Lendacky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __X86_MEM_ENCRYPT_H__ +#define __X86_MEM_ENCRYPT_H__ + +#ifndef __ASSEMBLY__ + +#include + +#include + +#ifdef CONFIG_AMD_MEM_ENCRYPT + +extern u64 sme_me_mask; + +void sme_encrypt_execute(unsigned long encrypted_kernel_vaddr, + unsigned long decrypted_kernel_vaddr, + unsigned long kernel_len, + unsigned long encryption_wa, + unsigned long encryption_pgd); + +void __init sme_early_encrypt(resource_size_t paddr, + unsigned long size); +void __init sme_early_decrypt(resource_size_t paddr, + unsigned long size); + +void __init sme_map_bootdata(char *real_mode_data); +void __init sme_unmap_bootdata(char *real_mode_data); + +void __init sme_early_init(void); + +void __init sme_encrypt_kernel(void); +void __init sme_enable(struct boot_params *bp); + +/* Architecture __weak replacement functions */ +void __init mem_encrypt_init(void); + +void swiotlb_set_mem_attributes(void *vaddr, unsigned long size); + +#else /* !CONFIG_AMD_MEM_ENCRYPT */ + +#define sme_me_mask 0ULL + +static inline void __init sme_early_encrypt(resource_size_t paddr, + unsigned long size) { } +static inline void __init sme_early_decrypt(resource_size_t paddr, + unsigned long size) { } + +static inline void __init sme_map_bootdata(char *real_mode_data) { } +static inline void __init sme_unmap_bootdata(char *real_mode_data) { } + +static inline void __init sme_early_init(void) { } + +static inline void __init sme_encrypt_kernel(void) { } +static inline void __init sme_enable(struct boot_params *bp) { } + +#endif /* CONFIG_AMD_MEM_ENCRYPT */ + +/* + * The __sme_pa() and __sme_pa_nodebug() macros are meant for use when + * writing to or comparing values from the cr3 register. Having the + * encryption mask set in cr3 enables the PGD entry to be encrypted and + * avoid special case handling of PGD allocations. + */ +#define __sme_pa(x) (__pa(x) | sme_me_mask) +#define __sme_pa_nodebug(x) (__pa_nodebug(x) | sme_me_mask) + +#endif /* __ASSEMBLY__ */ + +#endif /* __X86_MEM_ENCRYPT_H__ */ diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 79b647a7ebd0079b96472e52634c898301d3a63e..bb8c597c2248a9c8341d04813b04e1d42e9c7019 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h @@ -3,12 +3,28 @@ #include #include +#include /* - * The x86 doesn't have a mmu context, but - * we put the segment information here. + * x86 has arch-specific MMU state beyond what lives in mm_struct. */ typedef struct { + /* + * ctx_id uniquely identifies this mm_struct. A ctx_id will never + * be reused, and zero is not a valid ctx_id. + */ + u64 ctx_id; + + /* + * Any code that needs to do any sort of TLB flushing for this + * mm will first make its changes to the page tables, then + * increment tlb_gen, then flush. This lets the low-level + * flushing code keep track of what needs flushing. + * + * This is not used on Xen PV. + */ + atomic64_t tlb_gen; + #ifdef CONFIG_MODIFY_LDT_SYSCALL struct ldt_struct *ldt; #endif @@ -37,6 +53,11 @@ typedef struct { #endif } mm_context_t; +#define INIT_MM_CONTEXT(mm) \ + .context = { \ + .ctx_id = 1, \ + } + void leave_mm(int cpu); #endif /* _ASM_X86_MMU_H */ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 265c907d7d4c9b8c69e24792a20c5a3dfb6c95ee..c120b5db178aa415e1bbb97957dd7d73687575d3 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -12,6 +12,9 @@ #include #include #include + +extern atomic64_t last_mm_ctx_id; + #ifndef CONFIG_PARAVIRT static inline void paravirt_activate_mm(struct mm_struct *prev, struct mm_struct *next) @@ -125,13 +128,18 @@ static inline void switch_ldt(struct mm_struct *prev, struct mm_struct *next) static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { - if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) - this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); + int cpu = smp_processor_id(); + + if (cpumask_test_cpu(cpu, mm_cpumask(mm))) + cpumask_clear_cpu(cpu, mm_cpumask(mm)); } static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { + mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); + atomic64_set(&mm->context.tlb_gen, 0); + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { /* pkey 0 is the default and always allocated */ @@ -140,9 +148,7 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.execute_only_pkey = -1; } #endif - init_new_context_ldt(tsk, mm); - - return 0; + return init_new_context_ldt(tsk, mm); } static inline void destroy_context(struct mm_struct *mm) { @@ -280,6 +286,32 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, return __pkru_allows_pkey(vma_pkey(vma), write); } +/* + * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID + * bits. This serves two purposes. It prevents a nasty situation in + * which PCID-unaware code saves CR3, loads some other value (with PCID + * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if + * the saved ASID was nonzero. It also means that any bugs involving + * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger + * deterministically. + */ + +static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid) +{ + if (static_cpu_has(X86_FEATURE_PCID)) { + VM_WARN_ON_ONCE(asid > 4094); + return __sme_pa(mm->pgd) | (asid + 1); + } else { + VM_WARN_ON_ONCE(asid != 0); + return __sme_pa(mm->pgd); + } +} + +static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) +{ + VM_WARN_ON_ONCE(asid > 4094); + return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH; +} /* * This can be used from process context to figure out what the value of @@ -290,7 +322,8 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, */ static inline unsigned long __get_current_cr3_fast(void) { - unsigned long cr3 = __pa(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd); + unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm), + this_cpu_read(cpu_tlbstate.loaded_mm_asid)); /* For now, be very restrictive about when this can be called. */ VM_WARN_ON(in_nmi() || preemptible()); diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h index e3b7819caeef1c813c309c04519af9ef93183a9a..9eb7c718aaf8bdcd3ba6c3fc18e38d04a8228440 100644 --- a/arch/x86/include/asm/module.h +++ b/arch/x86/include/asm/module.h @@ -2,6 +2,15 @@ #define _ASM_X86_MODULE_H #include +#include + +struct mod_arch_specific { +#ifdef CONFIG_ORC_UNWINDER + unsigned int num_orcs; + int *orc_unwind_ip; + struct orc_entry *orc_unwind; +#endif +}; #ifdef CONFIG_X86_64 /* X86_64 does not define MODULE_PROC_FAMILY */ diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 831eb78955352bcded4422a8584d7becaf6ba15c..c471ca1f9412bdb021b0c27c00fb9fbfd8bebc90 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -86,7 +86,6 @@ static inline void e820__memblock_alloc_reserved_mpc_new(void) { } #endif int generic_processor_info(int apicid, int version); -int __generic_processor_info(int apicid, int version, bool enabled); #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_LOCAL_APIC) diff --git a/arch/x86/include/asm/mpx.h b/arch/x86/include/asm/mpx.h index a0d662be4c5b8545a7b0b8c5c846187ced8d0020..7d7404756bb4a734bcb04c5f57931daff8af73b3 100644 --- a/arch/x86/include/asm/mpx.h +++ b/arch/x86/include/asm/mpx.h @@ -73,6 +73,9 @@ static inline void mpx_mm_init(struct mm_struct *mm) } void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end); + +unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, + unsigned long flags); #else static inline siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) { @@ -94,6 +97,12 @@ static inline void mpx_notify_unmap(struct mm_struct *mm, unsigned long start, unsigned long end) { } + +static inline unsigned long mpx_unmapped_area_check(unsigned long addr, + unsigned long len, unsigned long flags) +{ + return addr; +} #endif /* CONFIG_X86_INTEL_MPX */ #endif /* _ASM_X86_MPX_H */ diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 2b58c8c1eeaafd9afca3a55b3486ec3a360adffa..738503e1f80c14f1b5720275dd57161509927ef8 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include /* @@ -28,6 +30,8 @@ struct ms_hyperv_info { u32 features; u32 misc_features; u32 hints; + u32 max_vp_index; + u32 max_lp_index; }; extern struct ms_hyperv_info ms_hyperv; @@ -168,12 +172,153 @@ void hv_remove_crash_handler(void); #if IS_ENABLED(CONFIG_HYPERV) extern struct clocksource *hyperv_cs; +extern void *hv_hypercall_pg; + +static inline u64 hv_do_hypercall(u64 control, void *input, void *output) +{ + u64 input_address = input ? virt_to_phys(input) : 0; + u64 output_address = output ? virt_to_phys(output) : 0; + u64 hv_status; + +#ifdef CONFIG_X86_64 + if (!hv_hypercall_pg) + return U64_MAX; + + __asm__ __volatile__("mov %4, %%r8\n" + "call *%5" + : "=a" (hv_status), ASM_CALL_CONSTRAINT, + "+c" (control), "+d" (input_address) + : "r" (output_address), "m" (hv_hypercall_pg) + : "cc", "memory", "r8", "r9", "r10", "r11"); +#else + u32 input_address_hi = upper_32_bits(input_address); + u32 input_address_lo = lower_32_bits(input_address); + u32 output_address_hi = upper_32_bits(output_address); + u32 output_address_lo = lower_32_bits(output_address); + + if (!hv_hypercall_pg) + return U64_MAX; + + __asm__ __volatile__("call *%7" + : "=A" (hv_status), + "+c" (input_address_lo), ASM_CALL_CONSTRAINT + : "A" (control), + "b" (input_address_hi), + "D"(output_address_hi), "S"(output_address_lo), + "m" (hv_hypercall_pg) + : "cc", "memory"); +#endif /* !x86_64 */ + return hv_status; +} + +#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0) +#define HV_HYPERCALL_FAST_BIT BIT(16) +#define HV_HYPERCALL_VARHEAD_OFFSET 17 +#define HV_HYPERCALL_REP_COMP_OFFSET 32 +#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32) +#define HV_HYPERCALL_REP_START_OFFSET 48 +#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48) + +/* Fast hypercall with 8 bytes of input and no output */ +static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) +{ + u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT; + +#ifdef CONFIG_X86_64 + { + __asm__ __volatile__("call *%4" + : "=a" (hv_status), ASM_CALL_CONSTRAINT, + "+c" (control), "+d" (input1) + : "m" (hv_hypercall_pg) + : "cc", "r8", "r9", "r10", "r11"); + } +#else + { + u32 input1_hi = upper_32_bits(input1); + u32 input1_lo = lower_32_bits(input1); + + __asm__ __volatile__ ("call *%5" + : "=A"(hv_status), + "+c"(input1_lo), + ASM_CALL_CONSTRAINT + : "A" (control), + "b" (input1_hi), + "m" (hv_hypercall_pg) + : "cc", "edi", "esi"); + } +#endif + return hv_status; +} + +/* + * Rep hypercalls. Callers of this functions are supposed to ensure that + * rep_count and varhead_size comply with Hyper-V hypercall definition. + */ +static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, + void *input, void *output) +{ + u64 control = code; + u64 status; + u16 rep_comp; + + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET; + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET; + + do { + status = hv_do_hypercall(control, input, output); + if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS) + return status; + + /* Bits 32-43 of status have 'Reps completed' data. */ + rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >> + HV_HYPERCALL_REP_COMP_OFFSET; + + control &= ~HV_HYPERCALL_REP_START_MASK; + control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET; + + touch_nmi_watchdog(); + } while (rep_comp < rep_count); + + return status; +} + +/* + * Hypervisor's notion of virtual processor ID is different from + * Linux' notion of CPU ID. This information can only be retrieved + * in the context of the calling CPU. Setup a map for easy access + * to this information. + */ +extern u32 *hv_vp_index; + +/** + * hv_cpu_number_to_vp_number() - Map CPU to VP. + * @cpu_number: CPU number in Linux terms + * + * This function returns the mapping between the Linux processor + * number and the hypervisor's virtual processor number, useful + * in making hypercalls and such that talk about specific + * processors. + * + * Return: Virtual processor number in Hyper-V terms + */ +static inline int hv_cpu_number_to_vp_number(int cpu_number) +{ + return hv_vp_index[cpu_number]; +} void hyperv_init(void); +void hyperv_setup_mmu_ops(void); +void hyper_alloc_mmu(void); void hyperv_report_panic(struct pt_regs *regs); bool hv_is_hypercall_page_setup(void); void hyperv_cleanup(void); -#endif +#else /* CONFIG_HYPERV */ +static inline void hyperv_init(void) {} +static inline bool hv_is_hypercall_page_setup(void) { return false; } +static inline void hyperv_cleanup(void) {} +static inline void hyperv_setup_mmu_ops(void) {} +#endif /* CONFIG_HYPERV */ + #ifdef CONFIG_HYPERV_TSCPAGE struct ms_hyperv_tsc_page *hv_get_tsc_page(void); static inline u64 hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 5573c75f8e4ced276c8585b71f0df9b786ea9e90..17f5c12e1afd0c6ddb3fa2e6fc94b1fec52f7d5c 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -356,6 +356,8 @@ #define MSR_K8_TOP_MEM1 0xc001001a #define MSR_K8_TOP_MEM2 0xc001001d #define MSR_K8_SYSCFG 0xc0010010 +#define MSR_K8_SYSCFG_MEM_ENCRYPT_BIT 23 +#define MSR_K8_SYSCFG_MEM_ENCRYPT BIT_ULL(MSR_K8_SYSCFG_MEM_ENCRYPT_BIT) #define MSR_K8_INT_PENDING_MSG 0xc0010055 /* C1E active bits in int pending message */ #define K8_INTP_C1E_ACTIVE_MASK 0x18000000 diff --git a/arch/x86/include/asm/orc_lookup.h b/arch/x86/include/asm/orc_lookup.h new file mode 100644 index 0000000000000000000000000000000000000000..91c8d868424d1362f0a2cca42c3e43eddf962c28 --- /dev/null +++ b/arch/x86/include/asm/orc_lookup.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#ifndef _ORC_LOOKUP_H +#define _ORC_LOOKUP_H + +/* + * This is a lookup table for speeding up access to the .orc_unwind table. + * Given an input address offset, the corresponding lookup table entry + * specifies a subset of the .orc_unwind table to search. + * + * Each block represents the end of the previous range and the start of the + * next range. An extra block is added to give the last range an end. + * + * The block size should be a power of 2 to avoid a costly 'div' instruction. + * + * A block size of 256 was chosen because it roughly doubles unwinder + * performance while only adding ~5% to the ORC data footprint. + */ +#define LOOKUP_BLOCK_ORDER 8 +#define LOOKUP_BLOCK_SIZE (1 << LOOKUP_BLOCK_ORDER) + +#ifndef LINKER_SCRIPT + +extern unsigned int orc_lookup[]; +extern unsigned int orc_lookup_end[]; + +#define LOOKUP_START_IP (unsigned long)_stext +#define LOOKUP_STOP_IP (unsigned long)_etext + +#endif /* LINKER_SCRIPT */ + +#endif /* _ORC_LOOKUP_H */ diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h new file mode 100644 index 0000000000000000000000000000000000000000..9c9dc579bd7db172287f5fdea9628cabaeff56af --- /dev/null +++ b/arch/x86/include/asm/orc_types.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _ORC_TYPES_H +#define _ORC_TYPES_H + +#include +#include + +/* + * The ORC_REG_* registers are base registers which are used to find other + * registers on the stack. + * + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the + * address of the previous frame: the caller's SP before it called the current + * function. + * + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in + * the current frame. + * + * The most commonly used base registers are SP and BP -- which the previous SP + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is + * usually based on. + * + * The rest of the base registers are needed for special cases like entry code + * and GCC realigned stacks. + */ +#define ORC_REG_UNDEFINED 0 +#define ORC_REG_PREV_SP 1 +#define ORC_REG_DX 2 +#define ORC_REG_DI 3 +#define ORC_REG_BP 4 +#define ORC_REG_SP 5 +#define ORC_REG_R10 6 +#define ORC_REG_R13 7 +#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_MAX 15 + +/* + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the + * caller's SP right before it made the call). Used for all callable + * functions, i.e. all C code and all callable asm functions. + * + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points + * to a fully populated pt_regs from a syscall, interrupt, or exception. + * + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset + * points to the iret return frame. + * + * The UNWIND_HINT macros are used only for the unwind_hint struct. They + * aren't used in struct orc_entry due to size and complexity constraints. + * Objtool converts them to real types when it converts the hints to orc + * entries. + */ +#define ORC_TYPE_CALL 0 +#define ORC_TYPE_REGS 1 +#define ORC_TYPE_REGS_IRET 2 +#define UNWIND_HINT_TYPE_SAVE 3 +#define UNWIND_HINT_TYPE_RESTORE 4 + +#ifndef __ASSEMBLY__ +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:2; +} __packed; + +/* + * This struct is used by asm and inline asm code to manually annotate the + * location of registers on the stack for the ORC unwinder. + * + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. + */ +struct unwind_hint { + u32 ip; + s16 sp_offset; + u8 sp_reg; + u8 type; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ORC_TYPES_H */ diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index b4a0d43248cf3d6f2c7ef042200c31a25f29f122..b50df06ad251f143e105843ab84ac1a14f40abdf 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -51,6 +51,10 @@ static inline void clear_page(void *page) void copy_page(void *to, void *from); +#ifdef CONFIG_X86_MCE +#define arch_unmap_kpfn arch_unmap_kpfn +#endif + #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_X86_VSYSCALL_EMULATION diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 7bd0099384cac4ed0fa89a4e25c42e4a63ae5f9c..b98ed9d1463098936bcebbae46b59dc00495508c 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -3,6 +3,7 @@ #include #include +#include /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 @@ -15,7 +16,7 @@ #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) -#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1)) +#define __PHYSICAL_MASK ((phys_addr_t)(__sme_clr((1ULL << __PHYSICAL_MASK_SHIFT) - 1))) #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) /* Cast *PAGE_MASK to a signed type so that it is sign-extended if diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 9ccac1926587f6a959dcf735278c1c29f2782097..12deec722cf0a14374d794b037eb26bf2e02ad51 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -71,11 +71,6 @@ static inline void write_cr3(unsigned long x) PVOP_VCALL1(pv_mmu_ops.write_cr3, x); } -static inline unsigned long __read_cr4(void) -{ - return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4); -} - static inline void __write_cr4(unsigned long x) { PVOP_VCALL1(pv_cpu_ops.write_cr4, x); @@ -228,10 +223,6 @@ static inline void set_ldt(const void *addr, unsigned entries) { PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_idt(struct desc_ptr *dtr) -{ - PVOP_VCALL1(pv_cpu_ops.store_idt, dtr); -} static inline unsigned long paravirt_store_tr(void) { return PVOP_CALL0(unsigned long, pv_cpu_ops.store_tr); @@ -365,12 +356,6 @@ static inline void paravirt_release_p4d(unsigned long pfn) PVOP_VCALL1(pv_mmu_ops.release_p4d, pfn); } -static inline void pte_update(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) -{ - PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep); -} - static inline pte_t __pte(pteval_t val) { pteval_t ret; @@ -472,28 +457,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); } -static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmd) -{ - if (sizeof(pmdval_t) > sizeof(long)) - /* 5 arg words */ - pv_mmu_ops.set_pmd_at(mm, addr, pmdp, pmd); - else - PVOP_VCALL4(pv_mmu_ops.set_pmd_at, mm, addr, pmdp, - native_pmd_val(pmd)); -} - -static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, - pud_t *pudp, pud_t pud) -{ - if (sizeof(pudval_t) > sizeof(long)) - /* 5 arg words */ - pv_mmu_ops.set_pud_at(mm, addr, pudp, pud); - else - PVOP_VCALL4(pv_mmu_ops.set_pud_at, mm, addr, pudp, - native_pud_val(pud)); -} - static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) { pmdval_t val = native_pmd_val(pmd); @@ -960,11 +923,6 @@ extern void default_banner(void); #define GET_CR2_INTO_RAX \ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) -#define PARAVIRT_ADJUST_EXCEPTION_FRAME \ - PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ - CLBR_NONE, \ - call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) - #define USERGS_SYSRET64 \ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ CLBR_NONE, \ diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 9ffc36bfe4cddfb96a019ceea43c074a9be682de..280d94c36dada184fce42cd03d5d05fe7ebc8698 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -107,7 +107,6 @@ struct pv_cpu_ops { unsigned long (*read_cr0)(void); void (*write_cr0)(unsigned long); - unsigned long (*read_cr4)(void); void (*write_cr4)(unsigned long); #ifdef CONFIG_X86_64 @@ -119,8 +118,6 @@ struct pv_cpu_ops { void (*load_tr_desc)(void); void (*load_gdt)(const struct desc_ptr *); void (*load_idt)(const struct desc_ptr *); - /* store_gdt has been removed. */ - void (*store_idt)(struct desc_ptr *); void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); @@ -196,9 +193,6 @@ struct pv_irq_ops { void (*safe_halt)(void); void (*halt)(void); -#ifdef CONFIG_X86_64 - void (*adjust_exception_frame)(void); -#endif } __no_randomize_layout; struct pv_mmu_ops { @@ -248,12 +242,6 @@ struct pv_mmu_ops { void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); - void (*set_pmd_at)(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmdval); - void (*set_pud_at)(struct mm_struct *mm, unsigned long addr, - pud_t *pudp, pud_t pudval); - void (*pte_update)(struct mm_struct *mm, unsigned long addr, - pte_t *ptep); pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); @@ -471,8 +459,8 @@ int paravirt_disable_iospace(void); */ #ifdef CONFIG_X86_32 #define PVOP_VCALL_ARGS \ - unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; \ - register void *__sp asm("esp") + unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; + #define PVOP_CALL_ARGS PVOP_VCALL_ARGS #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) @@ -492,8 +480,8 @@ int paravirt_disable_iospace(void); /* [re]ax isn't an arg, but the return val */ #define PVOP_VCALL_ARGS \ unsigned long __edi = __edi, __esi = __esi, \ - __edx = __edx, __ecx = __ecx, __eax = __eax; \ - register void *__sp asm("rsp") + __edx = __edx, __ecx = __ecx, __eax = __eax; + #define PVOP_CALL_ARGS PVOP_VCALL_ARGS #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) @@ -544,7 +532,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr, "+r" (__sp) \ + : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ @@ -554,7 +542,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr, "+r" (__sp) \ + : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ @@ -581,7 +569,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr, "+r" (__sp) \ + : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 77037b6f1caa22f622f50d67ea6cebd00f76f685..b714934512b391905ed37400b6acb37ce6529ca2 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1,6 +1,7 @@ #ifndef _ASM_X86_PGTABLE_H #define _ASM_X86_PGTABLE_H +#include #include #include @@ -13,9 +14,18 @@ cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))) \ : (prot)) +/* + * Macros to add or remove encryption attribute + */ +#define pgprot_encrypted(prot) __pgprot(__sme_set(pgprot_val(prot))) +#define pgprot_decrypted(prot) __pgprot(__sme_clr(pgprot_val(prot))) + #ifndef __ASSEMBLY__ #include +extern pgd_t early_top_pgt[PTRS_PER_PGD]; +int __init __early_make_pgtable(unsigned long address, pmdval_t pmd); + void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd); void ptdump_walk_pgd_level_checkwx(void); @@ -38,13 +48,13 @@ extern struct list_head pgd_list; extern struct mm_struct *pgd_page_get_mm(struct page *page); +extern pmdval_t early_pmd_flags; + #ifdef CONFIG_PARAVIRT #include #else /* !CONFIG_PARAVIRT */ #define set_pte(ptep, pte) native_set_pte(ptep, pte) #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) -#define set_pmd_at(mm, addr, pmdp, pmd) native_set_pmd_at(mm, addr, pmdp, pmd) -#define set_pud_at(mm, addr, pudp, pud) native_set_pud_at(mm, addr, pudp, pud) #define set_pte_atomic(ptep, pte) \ native_set_pte_atomic(ptep, pte) @@ -75,8 +85,6 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); #define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) #define pmd_clear(pmd) native_pmd_clear(pmd) -#define pte_update(mm, addr, ptep) do { } while (0) - #define pgd_val(x) native_pgd_val(x) #define __pgd(x) native_make_pgd(x) @@ -195,6 +203,11 @@ static inline unsigned long p4d_pfn(p4d_t p4d) return (p4d_val(p4d) & p4d_pfn_mask(p4d)) >> PAGE_SHIFT; } +static inline unsigned long pgd_pfn(pgd_t pgd) +{ + return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT; +} + static inline int p4d_large(p4d_t p4d) { /* No 512 GiB pages yet */ @@ -704,8 +717,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pmd_page(pmd) \ - pfn_to_page((pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT) +#define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd)) /* * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] @@ -773,8 +785,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pud_page(pud) \ - pfn_to_page((pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT) +#define pud_page(pud) pfn_to_page(pud_pfn(pud)) /* Find an entry in the second-level page table.. */ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) @@ -824,8 +835,7 @@ static inline unsigned long p4d_page_vaddr(p4d_t p4d) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define p4d_page(p4d) \ - pfn_to_page((p4d_val(p4d) & p4d_pfn_mask(p4d)) >> PAGE_SHIFT) +#define p4d_page(p4d) pfn_to_page(p4d_pfn(p4d)) /* Find an entry in the third-level page table.. */ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) @@ -859,7 +869,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) +#define pgd_page(pgd) pfn_to_page(pgd_pfn(pgd)) /* to find an entry in a page-table-directory. */ static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) @@ -965,31 +975,18 @@ static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, native_set_pte(ptep, pte); } -static inline void native_set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp , pmd_t pmd) +static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) { native_set_pmd(pmdp, pmd); } -static inline void native_set_pud_at(struct mm_struct *mm, unsigned long addr, - pud_t *pudp, pud_t pud) +static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, + pud_t *pudp, pud_t pud) { native_set_pud(pudp, pud); } -#ifndef CONFIG_PARAVIRT -/* - * Rules for using pte_update - it must be called after any PTE update which - * has not been done using the set_pte / clear_pte interfaces. It is used by - * shadow mode hypervisors to resynchronize the shadow page tables. Kernel PTE - * updates should either be sets, clears, or set_pte_atomic for P->P - * transitions, which means this hook should only be called for user PTEs. - * This hook implies a P->P protection or access change has taken place, which - * requires a subsequent TLB flush. - */ -#define pte_update(mm, addr, ptep) do { } while (0) -#endif - /* * We only update the dirty/accessed state if we set * the dirty bit by hand in the kernel, since the hardware @@ -1017,7 +1014,6 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t pte = native_ptep_get_and_clear(ptep); - pte_update(mm, addr, ptep); return pte; } @@ -1044,7 +1040,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte); - pte_update(mm, addr, ptep); } #define flush_tlb_fix_spurious_fault(vma, address) do { } while (0) @@ -1158,6 +1153,23 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) { return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY); } + +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) +{ + return pmd_set_flags(pmd, _PAGE_SWP_SOFT_DIRTY); +} + +static inline int pmd_swp_soft_dirty(pmd_t pmd) +{ + return pmd_flags(pmd) & _PAGE_SWP_SOFT_DIRTY; +} + +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) +{ + return pmd_clear_flags(pmd, _PAGE_SWP_SOFT_DIRTY); +} +#endif #endif #define PKRU_AD_BIT 0x1 diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 2160c1fee9209d7ca7336ee367a0dbadc41d1b55..972a4698c530dc52c98d62247ed3377cf8ad1cf5 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -180,15 +180,21 @@ static inline int pgd_large(pgd_t pgd) { return 0; } /* * Encode and de-code a swap entry * - * | ... | 11| 10| 9|8|7|6|5| 4| 3|2|1|0| <- bit number - * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U|W|P| <- bit names - * | OFFSET (14->63) | TYPE (9-13) |0|X|X|X| X| X|X|X|0| <- swp entry + * | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number + * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names + * | OFFSET (14->63) | TYPE (9-13) |0|0|X|X| X| X|X|SD|0| <- swp entry * * G (8) is aliased and used as a PROT_NONE indicator for * !present ptes. We need to start storing swap entries above * there. We also need to avoid using A and D because of an * erratum where they can be incorrectly set by hardware on * non-present PTEs. + * + * SD (1) in swp entry is used to store soft dirty bit, which helps us + * remember soft dirty over page migration + * + * Bit 7 in swp entry should be 0 because pmd_present checks not only P, + * but also L and G. */ #define SWP_TYPE_FIRST_BIT (_PAGE_BIT_PROTNONE + 1) #define SWP_TYPE_BITS 5 @@ -204,7 +210,9 @@ static inline int pgd_large(pgd_t pgd) { return 0; } ((type) << (SWP_TYPE_FIRST_BIT)) \ | ((offset) << SWP_OFFSET_FIRST_BIT) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) +#define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) }) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) +#define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val }) extern int kern_addr_valid(unsigned long addr); extern void cleanup_highmap(void); diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index bf9638e1ee4215d4101d2836d5c3963d59e6dbab..f1492473f10e050d5e877c02bf4e9c06b71f2fd9 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -2,6 +2,8 @@ #define _ASM_X86_PGTABLE_DEFS_H #include +#include + #include #define FIRST_USER_ADDRESS 0UL @@ -97,15 +99,15 @@ /* * Tracking soft dirty bit when a page goes to a swap is tricky. * We need a bit which can be stored in pte _and_ not conflict - * with swap entry format. On x86 bits 6 and 7 are *not* involved - * into swap entry computation, but bit 6 is used for nonlinear - * file mapping, so we borrow bit 7 for soft dirty tracking. + * with swap entry format. On x86 bits 1-4 are *not* involved + * into swap entry computation, but bit 7 is used for thp migration, + * so we borrow bit 1 for soft dirty tracking. * * Please note that this bit must be treated as swap dirty page - * mark if and only if the PTE has present bit clear! + * mark if and only if the PTE/PMD has present bit clear! */ #ifdef CONFIG_MEM_SOFT_DIRTY -#define _PAGE_SWP_SOFT_DIRTY _PAGE_PSE +#define _PAGE_SWP_SOFT_DIRTY _PAGE_RW #else #define _PAGE_SWP_SOFT_DIRTY (_AT(pteval_t, 0)) #endif @@ -121,10 +123,10 @@ #define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE) -#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ - _PAGE_DIRTY) +#define _PAGE_TABLE_NOENC (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |\ + _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE_NOENC (_PAGE_PRESENT | _PAGE_RW | \ + _PAGE_ACCESSED | _PAGE_DIRTY) /* * Set of bits not changed in pte_modify. The pte's @@ -159,6 +161,7 @@ enum page_cache_mode { #define _PAGE_CACHE_MASK (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT) #define _PAGE_NOCACHE (cachemode2protval(_PAGE_CACHE_MODE_UC)) +#define _PAGE_CACHE_WP (cachemode2protval(_PAGE_CACHE_MODE_WP)) #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ @@ -187,22 +190,42 @@ enum page_cache_mode { #define __PAGE_KERNEL_VVAR (__PAGE_KERNEL_RO | _PAGE_USER) #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) +#define __PAGE_KERNEL_WP (__PAGE_KERNEL | _PAGE_CACHE_WP) #define __PAGE_KERNEL_IO (__PAGE_KERNEL) #define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) -#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) -#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) -#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) -#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) -#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) -#define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR) +#ifndef __ASSEMBLY__ + +#define _PAGE_ENC (_AT(pteval_t, sme_me_mask)) + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_ENC) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ + _PAGE_DIRTY | _PAGE_ENC) + +#define __PAGE_KERNEL_ENC (__PAGE_KERNEL | _PAGE_ENC) +#define __PAGE_KERNEL_ENC_WP (__PAGE_KERNEL_WP | _PAGE_ENC) + +#define __PAGE_KERNEL_NOENC (__PAGE_KERNEL) +#define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP) + +#define PAGE_KERNEL __pgprot(__PAGE_KERNEL | _PAGE_ENC) +#define PAGE_KERNEL_NOENC __pgprot(__PAGE_KERNEL) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO | _PAGE_ENC) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC | _PAGE_ENC) +#define PAGE_KERNEL_EXEC_NOENC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX | _PAGE_ENC) +#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) +#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) +#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC) +#define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) + +#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) +#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) -#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) -#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) +#endif /* __ASSEMBLY__ */ /* xwr */ #define __P000 PAGE_NONE @@ -287,6 +310,11 @@ static inline p4dval_t native_p4d_val(p4d_t p4d) #else #include +static inline p4d_t native_make_p4d(pudval_t val) +{ + return (p4d_t) { .pgd = native_make_pgd((pgdval_t)val) }; +} + static inline p4dval_t native_p4d_val(p4d_t p4d) { return native_pgd_val(p4d.pgd); diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h index ec1f3c6511506ee1f0ff5240a9ff95d0e6fa68c1..4f44505dbf870e79d4689af9db2f537fe764b831 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h @@ -100,19 +100,14 @@ static __always_inline bool should_resched(int preempt_offset) #ifdef CONFIG_PREEMPT extern asmlinkage void ___preempt_schedule(void); -# define __preempt_schedule() \ -({ \ - register void *__sp asm(_ASM_SP); \ - asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \ -}) +# define __preempt_schedule() \ + asm volatile ("call ___preempt_schedule" : ASM_CALL_CONSTRAINT) extern asmlinkage void preempt_schedule(void); extern asmlinkage void ___preempt_schedule_notrace(void); -# define __preempt_schedule_notrace() \ -({ \ - register void *__sp asm(_ASM_SP); \ - asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \ -}) +# define __preempt_schedule_notrace() \ + asm volatile ("call ___preempt_schedule_notrace" : ASM_CALL_CONSTRAINT) + extern asmlinkage void preempt_schedule_notrace(void); #endif diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h index 79aa2f98398d4eaabf45a1493baaa072f11782ec..dc723b64acf0675689c1feb187bfd957480c5d94 100644 --- a/arch/x86/include/asm/processor-flags.h +++ b/arch/x86/include/asm/processor-flags.h @@ -2,6 +2,7 @@ #define _ASM_X86_PROCESSOR_FLAGS_H #include +#include #ifdef CONFIG_VM86 #define X86_VM_MASK X86_EFLAGS_VM @@ -32,16 +33,18 @@ * CR3_ADDR_MASK is the mask used by read_cr3_pa(). */ #ifdef CONFIG_X86_64 -/* Mask off the address space ID bits. */ -#define CR3_ADDR_MASK 0x7FFFFFFFFFFFF000ull -#define CR3_PCID_MASK 0xFFFull +/* Mask off the address space ID and SME encryption bits. */ +#define CR3_ADDR_MASK __sme_clr(0x7FFFFFFFFFFFF000ull) +#define CR3_PCID_MASK 0xFFFull +#define CR3_NOFLUSH BIT_ULL(63) #else /* * CR3_ADDR_MASK needs at least bits 31:5 set on PAE systems, and we save * a tiny bit of code size by setting all the bits. */ -#define CR3_ADDR_MASK 0xFFFFFFFFull -#define CR3_PCID_MASK 0ull +#define CR3_ADDR_MASK 0xFFFFFFFFull +#define CR3_PCID_MASK 0ull +#define CR3_NOFLUSH 0 #endif #endif /* _ASM_X86_PROCESSOR_FLAGS_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 028245e1c42b23d1498643427ebb73be25ded661..b390ff76e58fd9f28c62ba5e3a8ab169ac18ad62 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -22,6 +22,7 @@ struct vm86; #include #include #include +#include #include #include @@ -29,6 +30,7 @@ struct vm86; #include #include #include +#include /* * We handle most unaligned accesses in hardware. On the other hand @@ -239,9 +241,14 @@ static inline unsigned long read_cr3_pa(void) return __read_cr3() & CR3_ADDR_MASK; } +static inline unsigned long native_read_cr3_pa(void) +{ + return __native_read_cr3() & CR3_ADDR_MASK; +} + static inline void load_cr3(pgd_t *pgdir) { - write_cr3(__pa(pgdir)); + write_cr3(__sme_pa(pgdir)); } #ifdef CONFIG_X86_32 @@ -661,7 +668,7 @@ static inline void sync_core(void) * In case NMI unmasking or performance ever becomes a problem, * the next best option appears to be MOV-to-CR2 and an * unconditional jump. That sequence also works on all CPUs, - * but it will fault at CPL3 (i.e. Xen PV and lguest). + * but it will fault at CPL3 (i.e. Xen PV). * * CPUID is the conventional way, but it's nasty: it doesn't * exist on some 486-like CPUs, and it usually exits to a @@ -670,8 +677,6 @@ static inline void sync_core(void) * Like all of Linux's memory ordering operations, this is a * compiler barrier as well. */ - register void *__sp asm(_ASM_SP); - #ifdef CONFIG_X86_32 asm volatile ( "pushfl\n\t" @@ -679,11 +684,12 @@ static inline void sync_core(void) "pushl $1f\n\t" "iret\n\t" "1:" - : "+r" (__sp) : : "memory"); + : ASM_CALL_CONSTRAINT : : "memory"); #else unsigned int tmp; asm volatile ( + UNWIND_HINT_SAVE "mov %%ss, %0\n\t" "pushq %q0\n\t" "pushq %%rsp\n\t" @@ -693,8 +699,9 @@ static inline void sync_core(void) "pushq %q0\n\t" "pushq $1f\n\t" "iretq\n\t" + UNWIND_HINT_RESTORE "1:" - : "=&r" (tmp), "+r" (__sp) : : "cc", "memory"); + : "=&r" (tmp), ASM_CALL_CONSTRAINT : : "cc", "memory"); #endif } @@ -802,7 +809,9 @@ static inline void spin_lock_prefetch(const void *x) */ #define IA32_PAGE_OFFSET PAGE_OFFSET #define TASK_SIZE PAGE_OFFSET +#define TASK_SIZE_LOW TASK_SIZE #define TASK_SIZE_MAX TASK_SIZE +#define DEFAULT_MAP_WINDOW TASK_SIZE #define STACK_TOP TASK_SIZE #define STACK_TOP_MAX STACK_TOP @@ -842,7 +851,9 @@ static inline void spin_lock_prefetch(const void *x) * particular problem by preventing anything from being mapped * at the maximum canonical address. */ -#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE) +#define TASK_SIZE_MAX ((1UL << __VIRTUAL_MASK_SHIFT) - PAGE_SIZE) + +#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. @@ -850,12 +861,14 @@ static inline void spin_lock_prefetch(const void *x) #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ 0xc0000000 : 0xFFFFe000) +#define TASK_SIZE_LOW (test_thread_flag(TIF_ADDR32) ? \ + IA32_PAGE_OFFSET : DEFAULT_MAP_WINDOW) #define TASK_SIZE (test_thread_flag(TIF_ADDR32) ? \ IA32_PAGE_OFFSET : TASK_SIZE_MAX) #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \ IA32_PAGE_OFFSET : TASK_SIZE_MAX) -#define STACK_TOP TASK_SIZE +#define STACK_TOP TASK_SIZE_LOW #define STACK_TOP_MAX TASK_SIZE_MAX #define INIT_THREAD { \ @@ -876,7 +889,7 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, * space during mmap's. */ #define __TASK_UNMAPPED_BASE(task_size) (PAGE_ALIGN(task_size / 3)) -#define TASK_UNMAPPED_BASE __TASK_UNMAPPED_BASE(TASK_SIZE) +#define TASK_UNMAPPED_BASE __TASK_UNMAPPED_BASE(TASK_SIZE_LOW) #define KSTK_EIP(task) (task_pt_regs(task)->ip) diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h index 8d3964fc5f915c37ec7bf74706446adc8ad2e93b..b408b18861957c28fb6903100430528ebe90456c 100644 --- a/arch/x86/include/asm/proto.h +++ b/arch/x86/include/asm/proto.h @@ -24,6 +24,9 @@ void entry_SYSENTER_compat(void); void __end_entry_SYSENTER_compat(void); void entry_SYSCALL_compat(void); void entry_INT80_compat(void); +#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV) +void xen_entry_INT80_compat(void); +#endif #endif void x86_configure_nx(void); diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 2b5d686ea9f37b3bd503d44e9481fd17682a2e6e..91c04c8e67fabcd2d61c5d47da0f4da9ce7efb4c 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -9,6 +9,20 @@ #ifdef __i386__ struct pt_regs { + /* + * NB: 32-bit x86 CPUs are inconsistent as what happens in the + * following cases (where %seg represents a segment register): + * + * - pushl %seg: some do a 16-bit write and leave the high + * bits alone + * - movl %seg, [mem]: some do a 16-bit write despite the movl + * - IDT entry: some (e.g. 486) will leave the high bits of CS + * and (if applicable) SS undefined. + * + * Fortunately, x86-32 doesn't read the high bits on POP or IRET, + * so we can just treat all of the segment registers as 16-bit + * values. + */ unsigned long bx; unsigned long cx; unsigned long dx; @@ -16,16 +30,22 @@ struct pt_regs { unsigned long di; unsigned long bp; unsigned long ax; - unsigned long ds; - unsigned long es; - unsigned long fs; - unsigned long gs; + unsigned short ds; + unsigned short __dsh; + unsigned short es; + unsigned short __esh; + unsigned short fs; + unsigned short __fsh; + unsigned short gs; + unsigned short __gsh; unsigned long orig_ax; unsigned long ip; - unsigned long cs; + unsigned short cs; + unsigned short __csh; unsigned long flags; unsigned long sp; - unsigned long ss; + unsigned short ss; + unsigned short __ssh; }; #else /* __i386__ */ @@ -176,6 +196,17 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, if (offset == offsetof(struct pt_regs, sp) && regs->cs == __KERNEL_CS) return kernel_stack_pointer(regs); + + /* The selector fields are 16-bit. */ + if (offset == offsetof(struct pt_regs, cs) || + offset == offsetof(struct pt_regs, ss) || + offset == offsetof(struct pt_regs, ds) || + offset == offsetof(struct pt_regs, es) || + offset == offsetof(struct pt_regs, fs) || + offset == offsetof(struct pt_regs, gs)) { + return *(u16 *)((unsigned long)regs + offset); + + } #endif return *(unsigned long *)((unsigned long)regs + offset); } diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index 230e1903acf07faa831c8d2496a4457aaae9b5ea..90d91520c13ab09b566ca0a599a6170353153e47 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h @@ -1,6 +1,15 @@ #ifndef _ARCH_X86_REALMODE_H #define _ARCH_X86_REALMODE_H +/* + * Flag bit definitions for use with the flags field of the trampoline header + * in the CONFIG_X86_64 variant. + */ +#define TH_FLAGS_SME_ACTIVE_BIT 0 +#define TH_FLAGS_SME_ACTIVE BIT(TH_FLAGS_SME_ACTIVE_BIT) + +#ifndef __ASSEMBLY__ + #include #include @@ -38,6 +47,7 @@ struct trampoline_header { u64 start; u64 efer; u32 cr4; + u32 flags; #endif }; @@ -69,4 +79,6 @@ static inline size_t real_mode_size_needed(void) void set_real_mode_mem(phys_addr_t mem, size_t size); void reserve_real_mode(void); +#endif /* __ASSEMBLY__ */ + #endif /* _ARCH_X86_REALMODE_H */ diff --git a/arch/x86/include/asm/refcount.h b/arch/x86/include/asm/refcount.h new file mode 100644 index 0000000000000000000000000000000000000000..ff871210b9f2f3f73ff030fe820d7c665de948b1 --- /dev/null +++ b/arch/x86/include/asm/refcount.h @@ -0,0 +1,109 @@ +#ifndef __ASM_X86_REFCOUNT_H +#define __ASM_X86_REFCOUNT_H +/* + * x86-specific implementation of refcount_t. Based on PAX_REFCOUNT from + * PaX/grsecurity. + */ +#include + +/* + * This is the first portion of the refcount error handling, which lives in + * .text.unlikely, and is jumped to from the CPU flag check (in the + * following macros). This saves the refcount value location into CX for + * the exception handler to use (in mm/extable.c), and then triggers the + * central refcount exception. The fixup address for the exception points + * back to the regular execution flow in .text. + */ +#define _REFCOUNT_EXCEPTION \ + ".pushsection .text.unlikely\n" \ + "111:\tlea %[counter], %%" _ASM_CX "\n" \ + "112:\t" ASM_UD0 "\n" \ + ASM_UNREACHABLE \ + ".popsection\n" \ + "113:\n" \ + _ASM_EXTABLE_REFCOUNT(112b, 113b) + +/* Trigger refcount exception if refcount result is negative. */ +#define REFCOUNT_CHECK_LT_ZERO \ + "js 111f\n\t" \ + _REFCOUNT_EXCEPTION + +/* Trigger refcount exception if refcount result is zero or negative. */ +#define REFCOUNT_CHECK_LE_ZERO \ + "jz 111f\n\t" \ + REFCOUNT_CHECK_LT_ZERO + +/* Trigger refcount exception unconditionally. */ +#define REFCOUNT_ERROR \ + "jmp 111f\n\t" \ + _REFCOUNT_EXCEPTION + +static __always_inline void refcount_add(unsigned int i, refcount_t *r) +{ + asm volatile(LOCK_PREFIX "addl %1,%0\n\t" + REFCOUNT_CHECK_LT_ZERO + : [counter] "+m" (r->refs.counter) + : "ir" (i) + : "cc", "cx"); +} + +static __always_inline void refcount_inc(refcount_t *r) +{ + asm volatile(LOCK_PREFIX "incl %0\n\t" + REFCOUNT_CHECK_LT_ZERO + : [counter] "+m" (r->refs.counter) + : : "cc", "cx"); +} + +static __always_inline void refcount_dec(refcount_t *r) +{ + asm volatile(LOCK_PREFIX "decl %0\n\t" + REFCOUNT_CHECK_LE_ZERO + : [counter] "+m" (r->refs.counter) + : : "cc", "cx"); +} + +static __always_inline __must_check +bool refcount_sub_and_test(unsigned int i, refcount_t *r) +{ + GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", REFCOUNT_CHECK_LT_ZERO, + r->refs.counter, "er", i, "%0", e); +} + +static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r) +{ + GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", REFCOUNT_CHECK_LT_ZERO, + r->refs.counter, "%0", e); +} + +static __always_inline __must_check +bool refcount_add_not_zero(unsigned int i, refcount_t *r) +{ + int c, result; + + c = atomic_read(&(r->refs)); + do { + if (unlikely(c == 0)) + return false; + + result = c + i; + + /* Did we try to increment from/to an undesirable state? */ + if (unlikely(c < 0 || c == INT_MAX || result < c)) { + asm volatile(REFCOUNT_ERROR + : : [counter] "m" (r->refs.counter) + : "cc", "cx"); + break; + } + + } while (!atomic_try_cmpxchg(&(r->refs), &c, result)); + + return c != 0; +} + +static __always_inline __must_check bool refcount_inc_not_zero(refcount_t *r) +{ + return refcount_add_not_zero(1, r); +} + +#endif diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h index 661dd305694af8878b8cdcd8b9396b9c7da3b646..045f99211a9921cfd4eddb7250ff4ed56a602c2a 100644 --- a/arch/x86/include/asm/rmwcc.h +++ b/arch/x86/include/asm/rmwcc.h @@ -1,45 +1,56 @@ #ifndef _ASM_X86_RMWcc #define _ASM_X86_RMWcc +#define __CLOBBERS_MEM "memory" +#define __CLOBBERS_MEM_CC_CX "memory", "cc", "cx" + #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO) /* Use asm goto */ -#define __GEN_RMWcc(fullop, var, cc, ...) \ +#define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ do { \ asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ - : : "m" (var), ## __VA_ARGS__ \ - : "memory" : cc_label); \ + : : [counter] "m" (var), ## __VA_ARGS__ \ + : clobbers : cc_label); \ return 0; \ cc_label: \ return 1; \ } while (0) -#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ - __GEN_RMWcc(op " " arg0, var, cc) +#define __BINARY_RMWcc_ARG " %1, " -#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ - __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ /* Use flags output or a set instruction */ -#define __GEN_RMWcc(fullop, var, cc, ...) \ +#define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ do { \ bool c; \ asm volatile (fullop ";" CC_SET(cc) \ - : "+m" (var), CC_OUT(cc) (c) \ - : __VA_ARGS__ : "memory"); \ + : [counter] "+m" (var), CC_OUT(cc) (c) \ + : __VA_ARGS__ : clobbers); \ return c; \ } while (0) +#define __BINARY_RMWcc_ARG " %2, " + +#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ + #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ - __GEN_RMWcc(op " " arg0, var, cc) + __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM) + +#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc) \ + __GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc, \ + __CLOBBERS_MEM_CC_CX) #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ - __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) + __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc, \ + __CLOBBERS_MEM, vcon (val)) -#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ +#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc) \ + __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc, \ + __CLOBBERS_MEM_CC_CX, vcon (val)) #endif /* _ASM_X86_RMWcc */ diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index a34e0d4b957d639afb5978863e57fefb74a173f2..7116b7931c7b807766fef6d820ec929da43940c7 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h @@ -103,7 +103,6 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) ({ \ long tmp; \ struct rw_semaphore* ret; \ - register void *__sp asm(_ASM_SP); \ \ asm volatile("# beginning down_write\n\t" \ LOCK_PREFIX " xadd %1,(%4)\n\t" \ @@ -114,7 +113,8 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) " call " slow_path "\n" \ "1:\n" \ "# ending down_write" \ - : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \ + : "+m" (sem->count), "=d" (tmp), \ + "=a" (ret), ASM_CALL_CONSTRAINT \ : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ : "memory", "cc"); \ ret; \ diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 1549caa098f0828e6c533f714f22a7f97532427e..066aaf8131413e73f5b60969c2255888ab1f722b 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -238,9 +238,7 @@ #ifndef __ASSEMBLY__ extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; -#ifdef CONFIG_TRACING -# define trace_early_idt_handler_array early_idt_handler_array -#endif +extern void early_ignore_irq(void); /* * Load a segment. Fall back on loading the zero segment if something goes diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h index eaec6c364e42d07f55930a80ef29b9d5c248165d..cd71273ec49d91aacffe3eff8883617ef94d8627 100644 --- a/arch/x86/include/asm/set_memory.h +++ b/arch/x86/include/asm/set_memory.h @@ -11,6 +11,7 @@ * Executability : eXeutable, NoteXecutable * Read/Write : ReadOnly, ReadWrite * Presence : NotPresent + * Encryption : Encrypted, Decrypted * * Within a category, the attributes are mutually exclusive. * @@ -42,6 +43,8 @@ int set_memory_wt(unsigned long addr, int numpages); int set_memory_wb(unsigned long addr, int numpages); int set_memory_np(unsigned long addr, int numpages); int set_memory_4k(unsigned long addr, int numpages); +int set_memory_encrypted(unsigned long addr, int numpages); +int set_memory_decrypted(unsigned long addr, int numpages); int set_memory_array_uc(unsigned long *addr, int addrinarray); int set_memory_array_wc(unsigned long *addr, int addrinarray); diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index e4585a393965b098ed6fafcc80e6d8129dab0dd8..a65cf544686aca2051ddeff71de9942c691f418a 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -39,6 +39,7 @@ static inline void vsmp_init(void) { } #endif void setup_bios_corruption_check(void); +void early_platform_quirks(void); extern unsigned long saved_video_mode; diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 9efaabf5b54be04d722295dea1fd20a6e2515825..a24dfcf79f4acadd7b49f47c5138bc05cc50aa56 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -135,6 +135,11 @@ static inline void native_wbinvd(void) extern asmlinkage void native_load_gs_index(unsigned); +static inline unsigned long __read_cr4(void) +{ + return native_read_cr4(); +} + #ifdef CONFIG_PARAVIRT #include #else @@ -173,11 +178,6 @@ static inline void write_cr3(unsigned long x) native_write_cr3(x); } -static inline unsigned long __read_cr4(void) -{ - return native_read_cr4(); -} - static inline void __write_cr4(unsigned long x) { native_write_cr4(x); diff --git a/arch/x86/include/asm/string_32.h b/arch/x86/include/asm/string_32.h index e9ee84873de50a3b60a4cf8e978d4bf6eae9665f..e371e7229042a567cf487b4426641b7c2cf9e947 100644 --- a/arch/x86/include/asm/string_32.h +++ b/arch/x86/include/asm/string_32.h @@ -340,6 +340,30 @@ extern void *memset(void *, int, size_t); #endif #endif /* !CONFIG_FORTIFY_SOURCE */ +#define __HAVE_ARCH_MEMSET16 +static inline void *memset16(uint16_t *s, uint16_t v, size_t n) +{ + int d0, d1; + asm volatile("rep\n\t" + "stosw" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + +#define __HAVE_ARCH_MEMSET32 +static inline void *memset32(uint32_t *s, uint32_t v, size_t n) +{ + int d0, d1; + asm volatile("rep\n\t" + "stosl" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + /* * find the first occurrence of byte 'c', or 1 past the area if none */ diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h index 2a8c822de1fc695c3bc18768c51494632043d6fe..f372a70a523f10f07509d95b30b10f620a29d46e 100644 --- a/arch/x86/include/asm/string_64.h +++ b/arch/x86/include/asm/string_64.h @@ -58,6 +58,42 @@ extern void *__memcpy(void *to, const void *from, size_t len); void *memset(void *s, int c, size_t n); void *__memset(void *s, int c, size_t n); +#define __HAVE_ARCH_MEMSET16 +static inline void *memset16(uint16_t *s, uint16_t v, size_t n) +{ + long d0, d1; + asm volatile("rep\n\t" + "stosw" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + +#define __HAVE_ARCH_MEMSET32 +static inline void *memset32(uint32_t *s, uint32_t v, size_t n) +{ + long d0, d1; + asm volatile("rep\n\t" + "stosl" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + +#define __HAVE_ARCH_MEMSET64 +static inline void *memset64(uint64_t *s, uint64_t v, size_t n) +{ + long d0, d1; + asm volatile("rep\n\t" + "stosq" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + #define __HAVE_ARCH_MEMMOVE void *memmove(void *dest, const void *src, size_t count); void *__memmove(void *dest, const void *src, size_t count); diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 58fffe79e417e61cbd4f7041c9a7753a84b1331c..14835dd205a5c0bc23fe45704e9df7824a21211c 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -107,6 +107,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define V_IRQ_SHIFT 8 #define V_IRQ_MASK (1 << V_IRQ_SHIFT) +#define V_GIF_SHIFT 9 +#define V_GIF_MASK (1 << V_GIF_SHIFT) + #define V_INTR_PRIO_SHIFT 16 #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) @@ -116,6 +119,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define V_INTR_MASKING_SHIFT 24 #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) +#define V_GIF_ENABLE_SHIFT 25 +#define V_GIF_ENABLE_MASK (1 << V_GIF_ENABLE_SHIFT) + #define AVIC_ENABLE_SHIFT 31 #define AVIC_ENABLE_MASK (1 << AVIC_ENABLE_SHIFT) diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e00e1bd6e7b3fd46c411017143ade731ab06361b..89e7eeb5cec1dfa6804d5bba2dfe010e6ad8f455 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -98,6 +98,7 @@ struct thread_info { #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */ #define TIF_ADDR32 29 /* 32-bit address space on 64 bits */ #define TIF_X32 30 /* 32-bit native x86-64 binary */ +#define TIF_FSCHECK 31 /* Check FS is USER_DS on return */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) @@ -122,6 +123,7 @@ struct thread_info { #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_ADDR32 (1 << TIF_ADDR32) #define _TIF_X32 (1 << TIF_X32) +#define _TIF_FSCHECK (1 << TIF_FSCHECK) /* * work to do in syscall_trace_enter(). Also includes TIF_NOHZ for @@ -137,7 +139,8 @@ struct thread_info { (_TIF_SYSCALL_TRACE | _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ _TIF_NEED_RESCHED | _TIF_SINGLESTEP | _TIF_SYSCALL_EMU | \ _TIF_SYSCALL_AUDIT | _TIF_USER_RETURN_NOTIFY | _TIF_UPROBE | \ - _TIF_PATCH_PENDING | _TIF_NOHZ | _TIF_SYSCALL_TRACEPOINT) + _TIF_PATCH_PENDING | _TIF_NOHZ | _TIF_SYSCALL_TRACEPOINT | \ + _TIF_FSCHECK) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ @@ -155,17 +158,6 @@ struct thread_info { */ #ifndef __ASSEMBLY__ -static inline unsigned long current_stack_pointer(void) -{ - unsigned long sp; -#ifdef CONFIG_X86_64 - asm("mov %%rsp,%0" : "=g" (sp)); -#else - asm("mov %%esp,%0" : "=g" (sp)); -#endif - return sp; -} - /* * Walks up the stack frames to make sure that the specified object is * entirely contained by a single stack frame. diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index c7797307fc2ba5b24adacced83c9587bc5d2a8de..79a4ca6a96063529aafd883bfc69b40febf1d2f1 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h @@ -15,4 +15,18 @@ #include +/* + * While x86 architecture in general requires an IPI to perform TLB + * shootdown, enablement code for several hypervisors overrides + * .flush_tlb_others hook in pv_mmu_ops and implements it by issuing + * a hypercall. To keep software pagetable walkers safe in this case we + * switch to RCU based table free (HAVE_RCU_TABLE_FREE). See the comment + * below 'ifdef CONFIG_HAVE_RCU_TABLE_FREE' in include/asm-generic/tlb.h + * for more details. + */ +static inline void __tlb_remove_table(void *table) +{ + free_page_and_swap_cache(table); +} + #endif /* _ASM_X86_TLB_H */ diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 50ea3482e1d1d0babfecf7864a6e9307ba6651fe..4893abf7f74f9e264f5aaaec5a58211b6d324b3c 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -57,6 +57,23 @@ static inline void invpcid_flush_all_nonglobals(void) __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); } +static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) +{ + u64 new_tlb_gen; + + /* + * Bump the generation count. This also serves as a full barrier + * that synchronizes with switch_mm(): callers are required to order + * their read of mm_cpumask after their writes to the paging + * structures. + */ + smp_mb__before_atomic(); + new_tlb_gen = atomic64_inc_return(&mm->context.tlb_gen); + smp_mb__after_atomic(); + + return new_tlb_gen; +} + #ifdef CONFIG_PARAVIRT #include #else @@ -65,6 +82,17 @@ static inline void invpcid_flush_all_nonglobals(void) #define __flush_tlb_single(addr) __native_flush_tlb_single(addr) #endif +/* + * 6 because 6 should be plenty and struct tlb_state will fit in + * two cache lines. + */ +#define TLB_NR_DYN_ASIDS 6 + +struct tlb_context { + u64 ctx_id; + u64 tlb_gen; +}; + struct tlb_state { /* * cpu_tlbstate.loaded_mm should match CR3 whenever interrupts @@ -73,13 +101,35 @@ struct tlb_state { * mode even if we've already switched back to swapper_pg_dir. */ struct mm_struct *loaded_mm; - int state; + u16 loaded_mm_asid; + u16 next_asid; /* * Access to this CR4 shadow and to H/W CR4 is protected by * disabling interrupts when modifying either one. */ unsigned long cr4; + + /* + * This is a list of all contexts that might exist in the TLB. + * There is one per ASID that we use, and the ASID (what the + * CPU calls PCID) is the index into ctxts. + * + * For each context, ctx_id indicates which mm the TLB's user + * entries came from. As an invariant, the TLB will never + * contain entries that are out-of-date as when that mm reached + * the tlb_gen in the list. + * + * To be clear, this means that it's legal for the TLB code to + * flush the TLB without updating tlb_gen. This can happen + * (for now, at least) due to paravirt remote flushes. + * + * NB: context 0 is a bit special, since it's also used by + * various bits of init code. This is fine -- code that + * isn't aware of PCID will end up harmlessly flushing + * context 0. + */ + struct tlb_context ctxs[TLB_NR_DYN_ASIDS]; }; DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate); @@ -148,6 +198,8 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask) cr4_set_bits(mask); } +extern void initialize_tlbstate_and_flush(void); + static inline void __native_flush_tlb(void) { /* @@ -207,6 +259,14 @@ static inline void __flush_tlb_all(void) __flush_tlb_global(); else __flush_tlb(); + + /* + * Note: if we somehow had PCID but not PGE, then this wouldn't work -- + * we'd end up flushing kernel translations for the current ASID but + * we might fail to flush kernel translations for other cached ASIDs. + * + * To avoid this issue, we force PCID off if PGE is off. + */ } static inline void __flush_tlb_one(unsigned long addr) @@ -231,9 +291,26 @@ static inline void __flush_tlb_one(unsigned long addr) * and page-granular flushes are available only on i486 and up. */ struct flush_tlb_info { - struct mm_struct *mm; - unsigned long start; - unsigned long end; + /* + * We support several kinds of flushes. + * + * - Fully flush a single mm. .mm will be set, .end will be + * TLB_FLUSH_ALL, and .new_tlb_gen will be the tlb_gen to + * which the IPI sender is trying to catch us up. + * + * - Partially flush a single mm. .mm will be set, .start and + * .end will indicate the range, and .new_tlb_gen will be set + * such that the changes between generation .new_tlb_gen-1 and + * .new_tlb_gen are entirely contained in the indicated range. + * + * - Fully flush all mms whose tlb_gens have been updated. .mm + * will be NULL, .end will be TLB_FLUSH_ALL, and .new_tlb_gen + * will be zero. + */ + struct mm_struct *mm; + unsigned long start; + unsigned long end; + u64 new_tlb_gen; }; #define local_flush_tlb() __flush_tlb() @@ -256,12 +333,10 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a) void native_flush_tlb_others(const struct cpumask *cpumask, const struct flush_tlb_info *info); -#define TLBSTATE_OK 1 -#define TLBSTATE_LAZY 2 - static inline void arch_tlbbatch_add_mm(struct arch_tlbflush_unmap_batch *batch, struct mm_struct *mm) { + inc_mm_tlb_gen(mm); cpumask_or(&batch->cpumask, &batch->cpumask, mm_cpumask(mm)); } diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 6358a85e2270b83a8872ef00724feb77f41c0e58..c1d2a9892352742a1512306138da023d77c6050b 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -75,12 +75,6 @@ static inline const struct cpumask *cpumask_of_node(int node) extern void setup_node_to_cpumask_map(void); -/* - * Returns the number of the node containing Node 'node'. This - * architecture is flat, so it is a pretty simple function! - */ -#define parent_node(node) (node) - #define pcibus_to_node(bus) __pcibus_to_node(bus) extern int __node_distance(int, int); diff --git a/arch/x86/include/asm/trace/common.h b/arch/x86/include/asm/trace/common.h new file mode 100644 index 0000000000000000000000000000000000000000..57c8da027d99238f03591a0ab4cfab53da9a03a7 --- /dev/null +++ b/arch/x86/include/asm/trace/common.h @@ -0,0 +1,16 @@ +#ifndef _ASM_TRACE_COMMON_H +#define _ASM_TRACE_COMMON_H + +#ifdef CONFIG_TRACING +DECLARE_STATIC_KEY_FALSE(trace_pagefault_key); +#define trace_pagefault_enabled() \ + static_branch_unlikely(&trace_pagefault_key) +DECLARE_STATIC_KEY_FALSE(trace_resched_ipi_key); +#define trace_resched_ipi_enabled() \ + static_branch_unlikely(&trace_resched_ipi_key) +#else +static inline bool trace_pagefault_enabled(void) { return false; } +static inline bool trace_resched_ipi_enabled(void) { return false; } +#endif + +#endif diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h index 2422b14c50a7f9ce1a6776eda1a0b309be26afbf..5665bf205b8d500c0e5d08fa11d213aefdae053f 100644 --- a/arch/x86/include/asm/trace/exceptions.h +++ b/arch/x86/include/asm/trace/exceptions.h @@ -5,9 +5,10 @@ #define _TRACE_PAGE_FAULT_H #include +#include -extern int trace_irq_vector_regfunc(void); -extern void trace_irq_vector_unregfunc(void); +extern int trace_pagefault_reg(void); +extern void trace_pagefault_unreg(void); DECLARE_EVENT_CLASS(x86_exceptions, @@ -37,8 +38,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, \ TP_PROTO(unsigned long address, struct pt_regs *regs, \ unsigned long error_code), \ TP_ARGS(address, regs, error_code), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); + trace_pagefault_reg, trace_pagefault_unreg); DEFINE_PAGE_FAULT_EVENT(page_fault_user); DEFINE_PAGE_FAULT_EVENT(page_fault_kernel); diff --git a/arch/x86/include/asm/trace/fpu.h b/arch/x86/include/asm/trace/fpu.h index 342e59789fcdc2e62ce1fd94df32f99f12359bd0..39f7a27bef130fbb6c83a881951e440091ed9168 100644 --- a/arch/x86/include/asm/trace/fpu.h +++ b/arch/x86/include/asm/trace/fpu.h @@ -12,25 +12,22 @@ DECLARE_EVENT_CLASS(x86_fpu, TP_STRUCT__entry( __field(struct fpu *, fpu) - __field(bool, fpregs_active) - __field(bool, fpstate_active) + __field(bool, initialized) __field(u64, xfeatures) __field(u64, xcomp_bv) ), TP_fast_assign( __entry->fpu = fpu; - __entry->fpregs_active = fpu->fpregs_active; - __entry->fpstate_active = fpu->fpstate_active; + __entry->initialized = fpu->initialized; if (boot_cpu_has(X86_FEATURE_OSXSAVE)) { __entry->xfeatures = fpu->state.xsave.header.xfeatures; __entry->xcomp_bv = fpu->state.xsave.header.xcomp_bv; } ), - TP_printk("x86/fpu: %p fpregs_active: %d fpstate_active: %d xfeatures: %llx xcomp_bv: %llx", + TP_printk("x86/fpu: %p initialized: %d xfeatures: %llx xcomp_bv: %llx", __entry->fpu, - __entry->fpregs_active, - __entry->fpstate_active, + __entry->initialized, __entry->xfeatures, __entry->xcomp_bv ) diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h new file mode 100644 index 0000000000000000000000000000000000000000..4253bca9998904e882803690e023d970d20dd5cd --- /dev/null +++ b/arch/x86/include/asm/trace/hyperv.h @@ -0,0 +1,40 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM hyperv + +#if !defined(_TRACE_HYPERV_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HYPERV_H + +#include + +#if IS_ENABLED(CONFIG_HYPERV) + +TRACE_EVENT(hyperv_mmu_flush_tlb_others, + TP_PROTO(const struct cpumask *cpus, + const struct flush_tlb_info *info), + TP_ARGS(cpus, info), + TP_STRUCT__entry( + __field(unsigned int, ncpus) + __field(struct mm_struct *, mm) + __field(unsigned long, addr) + __field(unsigned long, end) + ), + TP_fast_assign(__entry->ncpus = cpumask_weight(cpus); + __entry->mm = info->mm; + __entry->addr = info->start; + __entry->end = info->end; + ), + TP_printk("ncpus %d mm %p addr %lx, end %lx", + __entry->ncpus, __entry->mm, + __entry->addr, __entry->end) + ); + +#endif /* CONFIG_HYPERV */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH asm/trace/ +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE hyperv +#endif /* _TRACE_HYPERV_H */ + +/* This part must be outside protection */ +#include diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h index 32dd6a9e343c075307585a8464d53743a46b7206..1599d394c8c1a154cd40f1dd8965140de5f44992 100644 --- a/arch/x86/include/asm/trace/irq_vectors.h +++ b/arch/x86/include/asm/trace/irq_vectors.h @@ -5,9 +5,12 @@ #define _TRACE_IRQ_VECTORS_H #include +#include -extern int trace_irq_vector_regfunc(void); -extern void trace_irq_vector_unregfunc(void); +#ifdef CONFIG_X86_LOCAL_APIC + +extern int trace_resched_ipi_reg(void); +extern void trace_resched_ipi_unreg(void); DECLARE_EVENT_CLASS(x86_irq_vector, @@ -26,17 +29,24 @@ DECLARE_EVENT_CLASS(x86_irq_vector, TP_printk("vector=%d", __entry->vector) ); #define DEFINE_IRQ_VECTOR_EVENT(name) \ +DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ + TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); \ +DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ + TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); + +#define DEFINE_RESCHED_IPI_EVENT(name) \ DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); \ + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg); \ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); - + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg); /* * local_timer - called when entering/exiting a local timer interrupt @@ -44,11 +54,6 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ */ DEFINE_IRQ_VECTOR_EVENT(local_timer); -/* - * reschedule - called when entering/exiting a reschedule vector handler - */ -DEFINE_IRQ_VECTOR_EVENT(reschedule); - /* * spurious_apic - called when entering/exiting a spurious apic vector handler */ @@ -65,6 +70,7 @@ DEFINE_IRQ_VECTOR_EVENT(error_apic); */ DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi); +#ifdef CONFIG_IRQ_WORK /* * irq_work - called when entering/exiting a irq work interrupt * vector handler @@ -81,6 +87,18 @@ DEFINE_IRQ_VECTOR_EVENT(irq_work); * 4) goto 1 */ TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0); +#endif + +/* + * The ifdef is required because that tracepoint macro hell emits tracepoint + * code in files which include this header even if the tracepoint is not + * enabled. Brilliant stuff that. + */ +#ifdef CONFIG_SMP +/* + * reschedule - called when entering/exiting a reschedule vector handler + */ +DEFINE_RESCHED_IPI_EVENT(reschedule); /* * call_function - called when entering/exiting a call function interrupt @@ -93,24 +111,33 @@ DEFINE_IRQ_VECTOR_EVENT(call_function); * single interrupt vector handler */ DEFINE_IRQ_VECTOR_EVENT(call_function_single); +#endif +#ifdef CONFIG_X86_MCE_THRESHOLD /* * threshold_apic - called when entering/exiting a threshold apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT(threshold_apic); +#endif +#ifdef CONFIG_X86_MCE_AMD /* * deferred_error_apic - called when entering/exiting a deferred apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic); +#endif +#ifdef CONFIG_X86_THERMAL_VECTOR /* * thermal_apic - called when entering/exiting a thermal apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT(thermal_apic); +#endif + +#endif /* CONFIG_X86_LOCAL_APIC */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 01fd0a7f48cd2f97dac2c1fd20e809e17975ad34..5545f6459bf59719b3b9822f597225e8da999f88 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -13,9 +13,6 @@ asmlinkage void divide_error(void); asmlinkage void debug(void); asmlinkage void nmi(void); asmlinkage void int3(void); -asmlinkage void xen_debug(void); -asmlinkage void xen_int3(void); -asmlinkage void xen_stack_segment(void); asmlinkage void overflow(void); asmlinkage void bounds(void); asmlinkage void invalid_op(void); @@ -38,22 +35,29 @@ asmlinkage void machine_check(void); #endif /* CONFIG_X86_MCE */ asmlinkage void simd_coprocessor_error(void); -#ifdef CONFIG_TRACING -asmlinkage void trace_page_fault(void); -#define trace_stack_segment stack_segment -#define trace_divide_error divide_error -#define trace_bounds bounds -#define trace_invalid_op invalid_op -#define trace_device_not_available device_not_available -#define trace_coprocessor_segment_overrun coprocessor_segment_overrun -#define trace_invalid_TSS invalid_TSS -#define trace_segment_not_present segment_not_present -#define trace_general_protection general_protection -#define trace_spurious_interrupt_bug spurious_interrupt_bug -#define trace_coprocessor_error coprocessor_error -#define trace_alignment_check alignment_check -#define trace_simd_coprocessor_error simd_coprocessor_error -#define trace_async_page_fault async_page_fault +#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV) +asmlinkage void xen_divide_error(void); +asmlinkage void xen_xendebug(void); +asmlinkage void xen_xenint3(void); +asmlinkage void xen_nmi(void); +asmlinkage void xen_overflow(void); +asmlinkage void xen_bounds(void); +asmlinkage void xen_invalid_op(void); +asmlinkage void xen_device_not_available(void); +asmlinkage void xen_double_fault(void); +asmlinkage void xen_coprocessor_segment_overrun(void); +asmlinkage void xen_invalid_TSS(void); +asmlinkage void xen_segment_not_present(void); +asmlinkage void xen_stack_segment(void); +asmlinkage void xen_general_protection(void); +asmlinkage void xen_page_fault(void); +asmlinkage void xen_spurious_interrupt_bug(void); +asmlinkage void xen_coprocessor_error(void); +asmlinkage void xen_alignment_check(void); +#ifdef CONFIG_X86_MCE +asmlinkage void xen_machine_check(void); +#endif /* CONFIG_X86_MCE */ +asmlinkage void xen_simd_coprocessor_error(void); #endif dotraplinkage void do_divide_error(struct pt_regs *, long); @@ -74,14 +78,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *); #endif dotraplinkage void do_general_protection(struct pt_regs *, long); dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); -#ifdef CONFIG_TRACING -dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); -#else -static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error) -{ - do_page_fault(regs, error); -} -#endif dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); dotraplinkage void do_coprocessor_error(struct pt_regs *, long); dotraplinkage void do_alignment_check(struct pt_regs *, long); diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 30269dafec47916e0f46866fa9cb3c19e93f9828..4b892917edeb787ce6380fd78a0d1c82f2299982 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -26,7 +26,12 @@ #define get_ds() (KERNEL_DS) #define get_fs() (current->thread.addr_limit) -#define set_fs(x) (current->thread.addr_limit = (x)) +static inline void set_fs(mm_segment_t fs) +{ + current->thread.addr_limit = fs; + /* On user-mode return, check fs is correct */ + set_thread_flag(TIF_FSCHECK); +} #define segment_eq(a, b) ((a).seg == (b).seg) @@ -161,11 +166,11 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) ({ \ int __ret_gu; \ register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ - register void *__sp asm(_ASM_SP); \ __chk_user_ptr(ptr); \ might_fault(); \ asm volatile("call __get_user_%P4" \ - : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \ + : "=a" (__ret_gu), "=r" (__val_gu), \ + ASM_CALL_CONSTRAINT \ : "0" (ptr), "i" (sizeof(*(ptr)))); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ __builtin_expect(__ret_gu, 0); \ @@ -332,7 +337,7 @@ do { \ _ASM_EXTABLE(1b, 4b) \ _ASM_EXTABLE(2b, 4b) \ : "=r" (retval), "=&A"(x) \ - : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \ + : "m" (__m(__ptr)), "m" __m(((u32 __user *)(__ptr)) + 1), \ "i" (errret), "0" (retval)); \ }) diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index e6676495b1259c9462723a3a8971bb61f5b4f86b..e9f793e2df7a135f72a5dcbeee6a09a1d73fb383 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -12,11 +12,14 @@ struct unwind_state { struct task_struct *task; int graph_idx; bool error; -#ifdef CONFIG_FRAME_POINTER +#if defined(CONFIG_ORC_UNWINDER) + bool signal, full_regs; + unsigned long sp, bp, ip; + struct pt_regs *regs; +#elif defined(CONFIG_FRAME_POINTER_UNWINDER) bool got_irq; - unsigned long *bp, *orig_sp; + unsigned long *bp, *orig_sp, ip; struct pt_regs *regs; - unsigned long ip; #else unsigned long *sp; #endif @@ -24,41 +27,30 @@ struct unwind_state { void __unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs, unsigned long *first_frame); - bool unwind_next_frame(struct unwind_state *state); - unsigned long unwind_get_return_address(struct unwind_state *state); +unsigned long *unwind_get_return_address_ptr(struct unwind_state *state); static inline bool unwind_done(struct unwind_state *state) { return state->stack_info.type == STACK_TYPE_UNKNOWN; } -static inline -void unwind_start(struct unwind_state *state, struct task_struct *task, - struct pt_regs *regs, unsigned long *first_frame) -{ - first_frame = first_frame ? : get_stack_pointer(task, regs); - - __unwind_start(state, task, regs, first_frame); -} - static inline bool unwind_error(struct unwind_state *state) { return state->error; } -#ifdef CONFIG_FRAME_POINTER - static inline -unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) +void unwind_start(struct unwind_state *state, struct task_struct *task, + struct pt_regs *regs, unsigned long *first_frame) { - if (unwind_done(state)) - return NULL; + first_frame = first_frame ? : get_stack_pointer(task, regs); - return state->regs ? &state->regs->ip : state->bp + 1; + __unwind_start(state, task, regs, first_frame); } +#if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER_UNWINDER) static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) { if (unwind_done(state)) @@ -66,20 +58,46 @@ static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) return state->regs; } - -#else /* !CONFIG_FRAME_POINTER */ - -static inline -unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) +#else +static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) { return NULL; } +#endif -static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) +#ifdef CONFIG_ORC_UNWINDER +void unwind_init(void); +void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size); +#else +static inline void unwind_init(void) {} +static inline +void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size) {} +#endif + +/* + * This disables KASAN checking when reading a value from another task's stack, + * since the other task could be running on another CPU and could have poisoned + * the stack in the meantime. + */ +#define READ_ONCE_TASK_STACK(task, x) \ +({ \ + unsigned long val; \ + if (task == current) \ + val = READ_ONCE(x); \ + else \ + val = READ_ONCE_NOCHECK(x); \ + val; \ +}) + +static inline bool task_on_another_cpu(struct task_struct *task) { - return NULL; +#ifdef CONFIG_SMP + return task != current && task->on_cpu; +#else + return false; +#endif } -#endif /* CONFIG_FRAME_POINTER */ - #endif /* _ASM_X86_UNWIND_H */ diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h new file mode 100644 index 0000000000000000000000000000000000000000..bae46fc6b9de3e97794f0576cae455ba15150cd7 --- /dev/null +++ b/arch/x86/include/asm/unwind_hints.h @@ -0,0 +1,105 @@ +#ifndef _ASM_X86_UNWIND_HINTS_H +#define _ASM_X86_UNWIND_HINTS_H + +#include "orc_types.h" + +#ifdef __ASSEMBLY__ + +/* + * In asm, there are two kinds of code: normal C-type callable functions and + * the rest. The normal callable functions can be called by other code, and + * don't do anything unusual with the stack. Such normal callable functions + * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this + * category. In this case, no special debugging annotations are needed because + * objtool can automatically generate the ORC data for the ORC unwinder to read + * at runtime. + * + * Anything which doesn't fall into the above category, such as syscall and + * interrupt handlers, tends to not be called directly by other functions, and + * often does unusual non-C-function-type things with the stack pointer. Such + * code needs to be annotated such that objtool can understand it. The + * following CFI hint macros are for this type of code. + * + * These macros provide hints to objtool about the state of the stack at each + * instruction. Objtool starts from the hints and follows the code flow, + * making automatic CFI adjustments when it sees pushes and pops, filling out + * the debuginfo as necessary. It will also warn if it sees any + * inconsistencies. + */ +.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL +#ifdef CONFIG_STACK_VALIDATION +.Lunwind_hint_ip_\@: + .pushsection .discard.unwind_hints + /* struct unwind_hint */ + .long .Lunwind_hint_ip_\@ - . + .short \sp_offset + .byte \sp_reg + .byte \type + .popsection +#endif +.endm + +.macro UNWIND_HINT_EMPTY + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED +.endm + +.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0 + .if \base == %rsp + .if \indirect + .set sp_reg, ORC_REG_SP_INDIRECT + .else + .set sp_reg, ORC_REG_SP + .endif + .elseif \base == %rbp + .set sp_reg, ORC_REG_BP + .elseif \base == %rdi + .set sp_reg, ORC_REG_DI + .elseif \base == %rdx + .set sp_reg, ORC_REG_DX + .elseif \base == %r10 + .set sp_reg, ORC_REG_R10 + .else + .error "UNWIND_HINT_REGS: bad base register" + .endif + + .set sp_offset, \offset + + .if \iret + .set type, ORC_TYPE_REGS_IRET + .elseif \extra == 0 + .set type, ORC_TYPE_REGS_IRET + .set sp_offset, \offset + (16*8) + .else + .set type, ORC_TYPE_REGS + .endif + + UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type +.endm + +.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 + UNWIND_HINT_REGS base=\base offset=\offset iret=1 +.endm + +.macro UNWIND_HINT_FUNC sp_offset=8 + UNWIND_HINT sp_offset=\sp_offset +.endm + +#else /* !__ASSEMBLY__ */ + +#define UNWIND_HINT(sp_reg, sp_offset, type) \ + "987: \n\t" \ + ".pushsection .discard.unwind_hints\n\t" \ + /* struct unwind_hint */ \ + ".long 987b - .\n\t" \ + ".short " __stringify(sp_offset) "\n\t" \ + ".byte " __stringify(sp_reg) "\n\t" \ + ".byte " __stringify(type) "\n\t" \ + ".popsection\n\t" + +#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE) + +#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_X86_UNWIND_HINTS_H */ diff --git a/arch/x86/include/asm/vga.h b/arch/x86/include/asm/vga.h index c4b9dc2f67c5f6f7a095dd7d4a3a6bb7fd7b3975..9f42beefc67a3d5d5242e054425c713ca394553e 100644 --- a/arch/x86/include/asm/vga.h +++ b/arch/x86/include/asm/vga.h @@ -7,12 +7,24 @@ #ifndef _ASM_X86_VGA_H #define _ASM_X86_VGA_H +#include + /* * On the PC, we can just recalculate addresses and then * access the videoram directly without any black magic. + * To support memory encryption however, we need to access + * the videoram as decrypted memory. */ -#define VGA_MAP_MEM(x, s) (unsigned long)phys_to_virt(x) +#define VGA_MAP_MEM(x, s) \ +({ \ + unsigned long start = (unsigned long)phys_to_virt(x); \ + \ + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) \ + set_memory_decrypted(start, (s) >> PAGE_SHIFT); \ + \ + start; \ +}) #define vga_readb(x) (*(x)) #define vga_writeb(x, y) (*(y) = (x)) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 35cd06f636abc9a357532f67ec1d1b41fbc8aa85..caec8417539ff179bf7be44abd6d92dccee5394d 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -72,6 +72,7 @@ #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 #define SECONDARY_EXEC_RDRAND 0x00000800 #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 +#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000 #define SECONDARY_EXEC_SHADOW_VMCS 0x00004000 #define SECONDARY_EXEC_RDSEED 0x00010000 #define SECONDARY_EXEC_ENABLE_PML 0x00020000 @@ -114,6 +115,10 @@ #define VMX_MISC_SAVE_EFER_LMA 0x00000020 #define VMX_MISC_ACTIVITY_HLT 0x00000040 +/* VMFUNC functions */ +#define VMX_VMFUNC_EPTP_SWITCHING 0x00000001 +#define VMFUNC_EPTP_ENTRIES 512 + static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic) { return vmx_basic & GENMASK_ULL(30, 0); @@ -187,6 +192,8 @@ enum vmcs_field { APIC_ACCESS_ADDR_HIGH = 0x00002015, POSTED_INTR_DESC_ADDR = 0x00002016, POSTED_INTR_DESC_ADDR_HIGH = 0x00002017, + VM_FUNCTION_CONTROL = 0x00002018, + VM_FUNCTION_CONTROL_HIGH = 0x00002019, EPT_POINTER = 0x0000201a, EPT_POINTER_HIGH = 0x0000201b, EOI_EXIT_BITMAP0 = 0x0000201c, @@ -197,6 +204,8 @@ enum vmcs_field { EOI_EXIT_BITMAP2_HIGH = 0x00002021, EOI_EXIT_BITMAP3 = 0x00002022, EOI_EXIT_BITMAP3_HIGH = 0x00002023, + EPTP_LIST_ADDRESS = 0x00002024, + EPTP_LIST_ADDRESS_HIGH = 0x00002025, VMREAD_BITMAP = 0x00002026, VMWRITE_BITMAP = 0x00002028, XSS_EXIT_BITMAP = 0x0000202C, @@ -444,6 +453,7 @@ enum vmcs_field { #define VMX_EPT_EXECUTE_ONLY_BIT (1ull) #define VMX_EPT_PAGE_WALK_4_BIT (1ull << 6) +#define VMX_EPT_PAGE_WALK_5_BIT (1ull << 7) #define VMX_EPTP_UC_BIT (1ull << 8) #define VMX_EPTP_WB_BIT (1ull << 14) #define VMX_EPT_2MB_PAGE_BIT (1ull << 16) @@ -459,12 +469,14 @@ enum vmcs_field { #define VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT (1ull << 10) /* (42 - 32) */ #define VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT (1ull << 11) /* (43 - 32) */ -#define VMX_EPT_DEFAULT_GAW 3 -#define VMX_EPT_MAX_GAW 0x4 #define VMX_EPT_MT_EPTE_SHIFT 3 -#define VMX_EPT_GAW_EPTP_SHIFT 3 -#define VMX_EPT_AD_ENABLE_BIT (1ull << 6) -#define VMX_EPT_DEFAULT_MT 0x6ull +#define VMX_EPTP_PWL_MASK 0x38ull +#define VMX_EPTP_PWL_4 0x18ull +#define VMX_EPTP_PWL_5 0x20ull +#define VMX_EPTP_AD_ENABLE_BIT (1ull << 6) +#define VMX_EPTP_MT_MASK 0x7ull +#define VMX_EPTP_MT_WB 0x6ull +#define VMX_EPTP_MT_UC 0x0ull #define VMX_EPT_READABLE_MASK 0x1ull #define VMX_EPT_WRITABLE_MASK 0x2ull #define VMX_EPT_EXECUTABLE_MASK 0x4ull diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 11071fcd630e46a126ed8e17be76c0e16eb759d4..7cb282e9e58777aeb2ffd86b344d39a5189c5f84 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -113,10 +113,9 @@ extern struct { char _entry[32]; } hypercall_page[]; register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ - register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \ - register void *__sp asm(_ASM_SP); + register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; -#define __HYPERCALL_0PARAM "=r" (__res), "+r" (__sp) +#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) @@ -557,10 +556,12 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, mcl->args[0] = maddr; mcl->args[1] = *(unsigned long *)&desc; } else { + u32 *p = (u32 *)&desc; + mcl->args[0] = maddr; mcl->args[1] = maddr >> 32; - mcl->args[2] = desc.a; - mcl->args[3] = desc.b; + mcl->args[2] = *p++; + mcl->args[3] = *p; } trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4); diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 8417ef7c38852effdedec055df56de271809eb03..07b6531813c495a8c8fed7c2624e514bf8d8d274 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -158,9 +158,6 @@ static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn) unsigned long pfn; int ret; - if (xen_feature(XENFEAT_auto_translated_physmap)) - return mfn; - if (unlikely(mfn >= machine_to_phys_nr)) return ~0; @@ -317,8 +314,6 @@ static inline pte_t __pte_ma(pteval_t x) #define p4d_val_ma(x) ((x).p4d) #endif -void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid); - xmaddr_t arbitrary_virt_to_machine(void *address); unsigned long arbitrary_virt_to_mfn(void *vaddr); void make_lowmem_page_readonly(void *vaddr); diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index ddef37b16af2c92ccef2b23088763a211dab6ea6..66b8f93333d1ee14ed7d937373377bd7ed1c3db8 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -201,7 +201,7 @@ struct boot_params { * * @X86_SUBARCH_PC: Should be used if the hardware is enumerable using standard * PC mechanisms (PCI, ACPI) and doesn't need a special boot flow. - * @X86_SUBARCH_LGUEST: Used for x86 hypervisor demo, lguest + * @X86_SUBARCH_LGUEST: Used for x86 hypervisor demo, lguest, deprecated * @X86_SUBARCH_XEN: Used for Xen guest types which follow the PV boot path, * which start at asm startup_xen() entry point and later jump to the C * xen_start_kernel() entry point. Both domU and dom0 type of guests are diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index 127ddadee1a5ae2317db5682fe9132eb88326504..f65d12504e8051f2e47aae2a0076a883c1ce535e 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h @@ -149,12 +149,9 @@ */ #define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9) -/* - * HV_VP_SET available - */ +/* Recommend using the newer ExProcessorMasks interface */ #define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11) - /* * Crash notification flag. */ @@ -242,7 +239,11 @@ (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1)) /* Declare the various hypercall operations. */ +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002 +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003 #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008 +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013 +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014 #define HVCALL_POST_MESSAGE 0x005c #define HVCALL_SIGNAL_EVENT 0x005d @@ -259,6 +260,16 @@ #define HV_PROCESSOR_POWER_STATE_C2 2 #define HV_PROCESSOR_POWER_STATE_C3 3 +#define HV_FLUSH_ALL_PROCESSORS BIT(0) +#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1) +#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2) +#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3) + +enum HV_GENERIC_SET_FORMAT { + HV_GENERIC_SET_SPARCE_4K, + HV_GENERIC_SET_ALL, +}; + /* hypercall status code */ #define HV_STATUS_SUCCESS 0 #define HV_STATUS_INVALID_HYPERCALL_CODE 2 diff --git a/arch/x86/include/uapi/asm/mman.h b/arch/x86/include/uapi/asm/mman.h index 39bca7fac087098c1f972de4b1468733ffe6220a..3be08f07695c0ebe567dbad418152c5767277912 100644 --- a/arch/x86/include/uapi/asm/mman.h +++ b/arch/x86/include/uapi/asm/mman.h @@ -3,9 +3,6 @@ #define MAP_32BIT 0x40 /* only give out 32bit addresses */ -#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) -#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) - #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS /* * Take the 4 protection key bits out of the vma->vm_flags diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a01892bdd61a4fccdc52b5c5678c1a954ef72c0f..fd0a7895b63f57bd77a4310936e6d239a45035d1 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -42,7 +42,7 @@ CFLAGS_irq.o := -I$(src)/../include/asm/trace obj-y := process_$(BITS).o signal.o obj-$(CONFIG_COMPAT) += signal_compat.o -obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o +obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o @@ -111,6 +111,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o +obj-$(CONFIG_EISA) += eisa.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o @@ -126,11 +127,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_TRACING) += tracepoint.o obj-$(CONFIG_SCHED_MC_PRIO) += itmt.o -ifdef CONFIG_FRAME_POINTER -obj-y += unwind_frame.o -else -obj-y += unwind_guess.o -endif +obj-$(CONFIG_ORC_UNWINDER) += unwind_orc.o +obj-$(CONFIG_FRAME_POINTER_UNWINDER) += unwind_frame.o +obj-$(CONFIG_GUESS_UNWINDER) += unwind_guess.o ### # 64 bit specific files diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 7491e73d92530bf868a9b91b2c71c892bcbdb94a..079535e53e2a6435b3b4bd0fc3fa5c932cc2cd09 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -115,24 +115,24 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = { #define ACPI_INVALID_GSI INT_MIN /* - * This is just a simple wrapper around early_ioremap(), + * This is just a simple wrapper around early_memremap(), * with sanity checks for phys == 0 and size == 0. */ -char *__init __acpi_map_table(unsigned long phys, unsigned long size) +void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) { if (!phys || !size) return NULL; - return early_ioremap(phys, size); + return early_memremap(phys, size); } -void __init __acpi_unmap_table(char *map, unsigned long size) +void __init __acpi_unmap_table(void __iomem *map, unsigned long size) { if (!map || !size) return; - early_iounmap(map, size); + early_memunmap(map, size); } #ifdef CONFIG_X86_LOCAL_APIC @@ -199,8 +199,10 @@ static int __init acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) { struct acpi_madt_local_x2apic *processor = NULL; +#ifdef CONFIG_X86_X2APIC int apic_id; u8 enabled; +#endif processor = (struct acpi_madt_local_x2apic *)header; @@ -209,9 +211,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) acpi_table_print_madt_entry(header); +#ifdef CONFIG_X86_X2APIC apic_id = processor->local_apic_id; enabled = processor->lapic_flags & ACPI_MADT_ENABLED; -#ifdef CONFIG_X86_X2APIC + /* * We need to register disabled CPU as well to permit * counting disabled CPUs. This allows us to size @@ -1083,7 +1086,7 @@ static void __init mp_config_acpi_legacy_irqs(void) mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; #endif set_bit(MP_ISA_BUS, mp_bus_not_pci); - pr_debug("Bus #%d is ISA\n", MP_ISA_BUS); + pr_debug("Bus #%d is ISA (nIRQs: %d)\n", MP_ISA_BUS, nr_legacy_irqs()); /* * Use the default configuration for the IRQs 0-15. Unless @@ -1370,7 +1373,7 @@ static void __init acpi_reduced_hw_init(void) * If your system is blacklisted here, but you find that acpi=force * works for you, please contact linux-acpi@vger.kernel.org */ -static struct dmi_system_id __initdata acpi_dmi_table[] = { +static const struct dmi_system_id acpi_dmi_table[] __initconst = { /* * Boxes that need ACPI disabled */ @@ -1445,7 +1448,7 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { }; /* second table for DMI checks that should run after early-quirks */ -static struct dmi_system_id __initdata acpi_dmi_table_late[] = { +static const struct dmi_system_id acpi_dmi_table_late[] __initconst = { /* * HP laptops which use a DSDT reporting as HP/SB400/10000, * which includes some code which overrides all temperature diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 32e14d13741670efa680c3c9e9facd1ffc0415a5..3344d3382e91393fa7dd16ee336db3ca11a3a433 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -742,7 +742,16 @@ static void *bp_int3_handler, *bp_int3_addr; int poke_int3_handler(struct pt_regs *regs) { - /* bp_patching_in_progress */ + /* + * Having observed our INT3 instruction, we now must observe + * bp_patching_in_progress. + * + * in_progress = TRUE INT3 + * WMB RMB + * write INT3 if (in_progress) + * + * Idem for bp_int3_handler. + */ smp_rmb(); if (likely(!bp_patching_in_progress)) @@ -788,9 +797,8 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler) bp_int3_addr = (u8 *)addr + sizeof(int3); bp_patching_in_progress = true; /* - * Corresponding read barrier in int3 notifier for - * making sure the in_progress flags is correctly ordered wrt. - * patching + * Corresponding read barrier in int3 notifier for making sure the + * in_progress and handler are correctly ordered wrt. patching. */ smp_wmb(); @@ -815,9 +823,11 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler) text_poke(addr, opcode, sizeof(int3)); on_each_cpu(do_sync_core, NULL, 1); - + /* + * sync_core() implies an smp_mb() and orders this store against + * the writing of the new instruction. + */ bp_patching_in_progress = false; - smp_wmb(); return addr; } diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 98b3dd8cf2bf4331f360f06b7501f03d397ceac2..d705c769f77d52ce55e4f7d5d32b9853ceb40394 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -177,8 +177,6 @@ static int disable_apic_timer __initdata; int local_apic_timer_c2_ok; EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); -int first_system_vector = FIRST_SYSTEM_VECTOR; - /* * Debug level, exported for io_apic.c */ @@ -599,9 +597,13 @@ static const struct x86_cpu_id deadline_match[] = { static void apic_check_deadline_errata(void) { - const struct x86_cpu_id *m = x86_match_cpu(deadline_match); + const struct x86_cpu_id *m; u32 rev; + if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) + return; + + m = x86_match_cpu(deadline_match); if (!m) return; @@ -990,8 +992,7 @@ void setup_secondary_APIC_clock(void) */ static void local_apic_timer_interrupt(void) { - int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(lapic_events, cpu); + struct clock_event_device *evt = this_cpu_ptr(&lapic_events); /* * Normally we should not be here till LAPIC has been initialized but @@ -1005,7 +1006,8 @@ static void local_apic_timer_interrupt(void) * spurious. */ if (!evt->event_handler) { - pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); + pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", + smp_processor_id()); /* Switch it off */ lapic_timer_shutdown(evt); return; @@ -1031,25 +1033,6 @@ __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - /* - * NOTE! We'd better ACK the irq immediately, - * because timer handling can be slow. - * - * update_process_times() expects us to have done irq_enter(). - * Besides, if we don't timer interrupts ignore the global - * interrupt lock, which is the WrongThing (tm) to do. - */ - entering_ack_irq(); - local_apic_timer_interrupt(); - exiting_irq(); - - set_irq_regs(old_regs); -} - -__visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - /* * NOTE! We'd better ACK the irq immediately, * because timer handling can be slow. @@ -1920,10 +1903,14 @@ void __init register_lapic_address(unsigned long address) /* * This interrupt should _never_ happen with our APIC/SMP architecture */ -static void __smp_spurious_interrupt(u8 vector) +__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs) { + u8 vector = ~regs->orig_ax; u32 v; + entering_irq(); + trace_spurious_apic_entry(vector); + /* * Check if this really is a spurious interrupt and ACK it * if it is a vectored one. Just in case... @@ -1938,22 +1925,7 @@ static void __smp_spurious_interrupt(u8 vector) /* see sw-dev-man vol 3, chapter 7.4.13.5 */ pr_info("spurious APIC interrupt through vector %02x on CPU#%d, " "should never happen.\n", vector, smp_processor_id()); -} -__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs) -{ - entering_irq(); - __smp_spurious_interrupt(~regs->orig_ax); - exiting_irq(); -} - -__visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs) -{ - u8 vector = ~regs->orig_ax; - - entering_irq(); - trace_spurious_apic_entry(vector); - __smp_spurious_interrupt(vector); trace_spurious_apic_exit(vector); exiting_irq(); } @@ -1961,10 +1933,8 @@ __visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs) /* * This interrupt should never happen with our APIC/SMP architecture */ -static void __smp_error_interrupt(struct pt_regs *regs) +__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs) { - u32 v; - u32 i = 0; static const char * const error_interrupt_reason[] = { "Send CS error", /* APIC Error Bit 0 */ "Receive CS error", /* APIC Error Bit 1 */ @@ -1975,6 +1945,10 @@ static void __smp_error_interrupt(struct pt_regs *regs) "Received illegal vector", /* APIC Error Bit 6 */ "Illegal register address", /* APIC Error Bit 7 */ }; + u32 v, i = 0; + + entering_irq(); + trace_error_apic_entry(ERROR_APIC_VECTOR); /* First tickle the hardware, only then report what went on. -- REW */ if (lapic_get_maxlvt() > 3) /* Due to the Pentium erratum 3AP. */ @@ -1996,20 +1970,6 @@ static void __smp_error_interrupt(struct pt_regs *regs) apic_printk(APIC_DEBUG, KERN_CONT "\n"); -} - -__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs) -{ - entering_irq(); - __smp_error_interrupt(regs); - exiting_irq(); -} - -__visible void __irq_entry smp_trace_error_interrupt(struct pt_regs *regs) -{ - entering_irq(); - trace_error_apic_entry(ERROR_APIC_VECTOR); - __smp_error_interrupt(regs); trace_error_apic_exit(ERROR_APIC_VECTOR); exiting_irq(); } @@ -2137,7 +2097,7 @@ static int allocate_logical_cpuid(int apicid) /* Allocate a new cpuid. */ if (nr_logical_cpuids >= nr_cpu_ids) { - WARN_ONCE(1, "APIC: NR_CPUS/possible_cpus limit of %i reached. " + WARN_ONCE(1, "APIC: NR_CPUS/possible_cpus limit of %u reached. " "Processor %d/0x%x and the rest are ignored.\n", nr_cpu_ids, nr_logical_cpuids, apicid); return -EINVAL; @@ -2170,7 +2130,7 @@ int generic_processor_info(int apicid, int version) * Since fixing handling of boot_cpu_physical_apicid requires * another discussion and tests on each platform, we leave it * for now and here we use read_apic_id() directly in this - * function, __generic_processor_info(). + * function, generic_processor_info(). */ if (disabled_cpu_apicid != BAD_APICID && disabled_cpu_apicid != read_apic_id() && diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 237e9c2341c71eef924296d3d425c9cd4e95f447..70e48aa6af982e4b94564986e352de61ba81d27f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1243,7 +1243,7 @@ static void io_apic_print_entries(unsigned int apic, unsigned int nr_entries) entry.vector, entry.irr, entry.delivery_status); if (ir_entry->format) printk(KERN_DEBUG "%s, remapped, I(%04X), Z(%X)\n", - buf, (ir_entry->index << 15) | ir_entry->index, + buf, (ir_entry->index2 << 15) | ir_entry->index, ir_entry->zero); else printk(KERN_DEBUG "%s, %s, D(%02X), M(%1d)\n", diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index b3af457ed667563091898d2ce95aef29290904ad..88c214e75a6be0bd26a126e2f57ad67d46a444fe 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -166,7 +166,7 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, offset = current_offset; next: vector += 16; - if (vector >= first_system_vector) { + if (vector >= FIRST_SYSTEM_VECTOR) { offset = (offset + 1) % 16; vector = FIRST_EXTERNAL_VECTOR + offset; } diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 446b0d3d4932fbe30f6d067cfd09bf65a5ac6709..e4b0d92b3ae067cec7f68acc76d7ac4615fe43b1 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -2043,7 +2043,7 @@ static int __init swab_apm_power_in_minutes(const struct dmi_system_id *d) return 0; } -static struct dmi_system_id __initdata apm_dmi_table[] = { +static const struct dmi_system_id apm_dmi_table[] __initconst = { { print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 880aa093268df7a0d7db23abde984647880c47cc..710edab9e6443a0078d3b7fc91cc0500bba0ac6c 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -4,9 +4,6 @@ #include -#include -#include "../../../drivers/lguest/lg.h" - #define __SYSCALL_I386(nr, sym, qual) [nr] = 1, static char syscalls[] = { #include @@ -62,23 +59,6 @@ void foo(void) OFFSET(stack_canary_offset, stack_canary, canary); #endif -#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE) - BLANK(); - OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled); - OFFSET(LGUEST_DATA_irq_pending, lguest_data, irq_pending); - - BLANK(); - OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc); - OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc); - OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3); - OFFSET(LGUEST_PAGES_host_sp, lguest_pages, state.host_sp); - OFFSET(LGUEST_PAGES_guest_gdt_desc, lguest_pages,state.guest_gdt_desc); - OFFSET(LGUEST_PAGES_guest_idt_desc, lguest_pages,state.guest_idt_desc); - OFFSET(LGUEST_PAGES_guest_gdt, lguest_pages, state.guest_gdt); - OFFSET(LGUEST_PAGES_regs_trapnum, lguest_pages, regs.trapnum); - OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode); - OFFSET(LGUEST_PAGES_regs, lguest_pages, regs); -#endif BLANK(); DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); DEFINE(NR_syscalls, sizeof(syscalls)); diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 99332f550c4888408cae2d5ce0dc9c5ff1709a60..cf42206926af5e985f449254e14968ad1bb9d557 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -20,7 +20,6 @@ static char syscalls_ia32[] = { int main(void) { #ifdef CONFIG_PARAVIRT - OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame); OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); BLANK(); diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index cdf82492b77003c3b98bbdfe216dc5c1c3408336..e17942c131c81e098e8c580624a7c2068cdaec24 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -33,7 +33,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o -obj-$(CONFIG_INTEL_RDT_A) += intel_rdt.o intel_rdt_rdtgroup.o intel_rdt_schemata.o +obj-$(CONFIG_INTEL_RDT) += intel_rdt.o intel_rdt_rdtgroup.o intel_rdt_monitor.o intel_rdt_ctrlmondata.o obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 3b9e220621f83c8a5161e8b57b297233370f72ea..d58184b7cd4438144e2d0ac3f4744d19ff4ffb31 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -297,13 +297,29 @@ static int nearby_node(int apicid) } #endif +#ifdef CONFIG_SMP +/* + * Fix up cpu_core_id for pre-F17h systems to be in the + * [0 .. cores_per_node - 1] range. Not really needed but + * kept so as not to break existing setups. + */ +static void legacy_fixup_core_id(struct cpuinfo_x86 *c) +{ + u32 cus_per_node; + + if (c->x86 >= 0x17) + return; + + cus_per_node = c->x86_max_cores / nodes_per_socket; + c->cpu_core_id %= cus_per_node; +} + /* * Fixup core topology information for * (1) AMD multi-node processors * Assumption: Number of cores in each internal node is the same. * (2) AMD processors supporting compute units */ -#ifdef CONFIG_SMP static void amd_get_topology(struct cpuinfo_x86 *c) { u8 node_id; @@ -354,15 +370,9 @@ static void amd_get_topology(struct cpuinfo_x86 *c) } else return; - /* fixup multi-node processor information */ if (nodes_per_socket > 1) { - u32 cus_per_node; - set_cpu_cap(c, X86_FEATURE_AMD_DCM); - cus_per_node = c->x86_max_cores / nodes_per_socket; - - /* core id has to be in the [0 .. cores_per_node - 1] range */ - c->cpu_core_id %= cus_per_node; + legacy_fixup_core_id(c); } } #endif @@ -548,8 +558,12 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) static void early_init_amd(struct cpuinfo_x86 *c) { + u32 dummy; + early_init_amd_mc(c); + rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); + /* * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate * with P/T states and does not stop in deep C-states @@ -612,6 +626,27 @@ static void early_init_amd(struct cpuinfo_x86 *c) */ if (cpu_has_amd_erratum(c, amd_erratum_400)) set_cpu_bug(c, X86_BUG_AMD_E400); + + /* + * BIOS support is required for SME. If BIOS has enabled SME then + * adjust x86_phys_bits by the SME physical address space reduction + * value. If BIOS has not enabled SME then don't advertise the + * feature (set in scattered.c). Also, since the SME support requires + * long mode, don't advertise the feature under CONFIG_X86_32. + */ + if (cpu_has(c, X86_FEATURE_SME)) { + u64 msr; + + /* Check if SME is enabled */ + rdmsrl(MSR_K8_SYSCFG, msr); + if (msr & MSR_K8_SYSCFG_MEM_ENCRYPT) { + c->x86_phys_bits -= (cpuid_ebx(0x8000001f) >> 6) & 0x3f; + if (IS_ENABLED(CONFIG_X86_32)) + clear_cpu_cap(c, X86_FEATURE_SME); + } else { + clear_cpu_cap(c, X86_FEATURE_SME); + } + } } static void init_amd_k8(struct cpuinfo_x86 *c) @@ -728,10 +763,18 @@ static void init_amd_bd(struct cpuinfo_x86 *c) } } -static void init_amd(struct cpuinfo_x86 *c) +static void init_amd_zn(struct cpuinfo_x86 *c) { - u32 dummy; + /* + * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects + * all up to and including B1. + */ + if (c->x86_model <= 1 && c->x86_mask <= 1) + set_cpu_cap(c, X86_FEATURE_CPB); +} +static void init_amd(struct cpuinfo_x86 *c) +{ early_init_amd(c); /* @@ -758,6 +801,7 @@ static void init_amd(struct cpuinfo_x86 *c) case 0x10: init_amd_gh(c); break; case 0x12: init_amd_ln(c); break; case 0x15: init_amd_bd(c); break; + case 0x17: init_amd_zn(c); break; } /* Enable workaround for FXSAVE leak */ @@ -793,8 +837,6 @@ static void init_amd(struct cpuinfo_x86 *c) if (c->x86 > 0x11) set_cpu_cap(c, X86_FEATURE_ARAT); - rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); - /* 3DNow or LM implies PREFETCHW */ if (!cpu_has(c, X86_FEATURE_3DNOWPREFETCH)) if (cpu_has(c, X86_FEATURE_3DNOW) || cpu_has(c, X86_FEATURE_LM)) diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c index d869c8671e364d55e343322b410fec9a3e5f66c6..0ee83321a3136fcca7a00a3b7e6c375e7a51e13f 100644 --- a/arch/x86/kernel/cpu/aperfmperf.c +++ b/arch/x86/kernel/cpu/aperfmperf.c @@ -8,20 +8,25 @@ * This file is licensed under GPLv2. */ -#include +#include +#include #include #include #include struct aperfmperf_sample { unsigned int khz; - unsigned long jiffies; + ktime_t time; u64 aperf; u64 mperf; }; static DEFINE_PER_CPU(struct aperfmperf_sample, samples); +#define APERFMPERF_CACHE_THRESHOLD_MS 10 +#define APERFMPERF_REFRESH_DELAY_MS 20 +#define APERFMPERF_STALE_THRESHOLD_MS 1000 + /* * aperfmperf_snapshot_khz() * On the current CPU, snapshot APERF, MPERF, and jiffies @@ -33,13 +38,18 @@ static void aperfmperf_snapshot_khz(void *dummy) u64 aperf, aperf_delta; u64 mperf, mperf_delta; struct aperfmperf_sample *s = this_cpu_ptr(&samples); + ktime_t now = ktime_get(); + s64 time_delta = ktime_ms_delta(now, s->time); + unsigned long flags; - /* Don't bother re-computing within 10 ms */ - if (time_before(jiffies, s->jiffies + HZ/100)) + /* Don't bother re-computing within the cache threshold time. */ + if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS) return; + local_irq_save(flags); rdmsrl(MSR_IA32_APERF, aperf); rdmsrl(MSR_IA32_MPERF, mperf); + local_irq_restore(flags); aperf_delta = aperf - s->aperf; mperf_delta = mperf - s->mperf; @@ -51,22 +61,21 @@ static void aperfmperf_snapshot_khz(void *dummy) if (mperf_delta == 0) return; - /* - * if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then - * khz = (cpu_khz * aperf_delta) / mperf_delta - */ - if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta) - s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta); - else /* khz = aperf_delta / (mperf_delta / cpu_khz) */ - s->khz = div64_u64(aperf_delta, - div64_u64(mperf_delta, cpu_khz)); - s->jiffies = jiffies; + s->time = now; s->aperf = aperf; s->mperf = mperf; + + /* If the previous iteration was too long ago, discard it. */ + if (time_delta > APERFMPERF_STALE_THRESHOLD_MS) + s->khz = 0; + else + s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta); } unsigned int arch_freq_get_on_cpu(int cpu) { + unsigned int khz; + if (!cpu_khz) return 0; @@ -74,6 +83,12 @@ unsigned int arch_freq_get_on_cpu(int cpu) return 0; smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1); + khz = per_cpu(samples.khz, cpu); + if (khz) + return khz; + + msleep(APERFMPERF_REFRESH_DELAY_MS); + smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1); return per_cpu(samples.khz, cpu); } diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c8b39870f33e8d5579eb1b30ecd24ace23de9d86..c9176bae7fd8cdb0e85f6d60766a809b9b36aa42 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -168,6 +168,24 @@ static int __init x86_mpx_setup(char *s) } __setup("nompx", x86_mpx_setup); +#ifdef CONFIG_X86_64 +static int __init x86_nopcid_setup(char *s) +{ + /* nopcid doesn't accept parameters */ + if (s) + return -EINVAL; + + /* do not emit a message if the feature is not present */ + if (!boot_cpu_has(X86_FEATURE_PCID)) + return 0; + + setup_clear_cpu_cap(X86_FEATURE_PCID); + pr_info("nopcid: PCID feature disabled\n"); + return 0; +} +early_param("nopcid", x86_nopcid_setup); +#endif + static int __init x86_noinvpcid_setup(char *s) { /* noinvpcid doesn't accept parameters */ @@ -886,6 +904,14 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) setup_force_cpu_cap(X86_FEATURE_ALWAYS); fpu__init_system(c); + +#ifdef CONFIG_X86_32 + /* + * Regardless of whether PCID is enumerated, the SDM says + * that it can't be enabled in 32-bit mode. + */ + setup_clear_cpu_cap(X86_FEATURE_PCID); +#endif } void __init early_cpu_init(void) @@ -1289,15 +1315,6 @@ static __init int setup_disablecpuid(char *arg) __setup("clearcpuid=", setup_disablecpuid); #ifdef CONFIG_X86_64 -struct desc_ptr idt_descr __ro_after_init = { - .size = NR_VECTORS * 16 - 1, - .address = (unsigned long) idt_table, -}; -const struct desc_ptr debug_idt_descr = { - .size = NR_VECTORS * 16 - 1, - .address = (unsigned long) debug_idt_table, -}; - DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union) __aligned(PAGE_SIZE) __visible; @@ -1552,6 +1569,7 @@ void cpu_init(void) mmgrab(&init_mm); me->active_mm = &init_mm; BUG_ON(me->mm); + initialize_tlbstate_and_flush(); enter_lazy_tlb(&init_mm, me); load_sp0(t, ¤t->thread); @@ -1606,6 +1624,7 @@ void cpu_init(void) mmgrab(&init_mm); curr->active_mm = &init_mm; BUG_ON(curr->mm); + initialize_tlbstate_and_flush(); enter_lazy_tlb(&init_mm, curr); load_sp0(t, thread); diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index c55fb2cb2acca8236741e94e2389aef35db424ff..24f749324c0f0f5d6f63b6810c71143f452d0fac 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -811,7 +811,24 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, struct cacheinfo *this_leaf; int i, sibling; - if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + /* + * For L3, always use the pre-calculated cpu_llc_shared_mask + * to derive shared_cpu_map. + */ + if (index == 3) { + for_each_cpu(i, cpu_llc_shared_mask(cpu)) { + this_cpu_ci = get_cpu_cacheinfo(i); + if (!this_cpu_ci->info_list) + continue; + this_leaf = this_cpu_ci->info_list + index; + for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { + if (!cpu_online(sibling)) + continue; + cpumask_set_cpu(sibling, + &this_leaf->shared_cpu_map); + } + } + } else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { unsigned int apicid, nshared, first, last; this_leaf = this_cpu_ci->info_list + index; @@ -839,19 +856,6 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, &this_leaf->shared_cpu_map); } } - } else if (index == 3) { - for_each_cpu(i, cpu_llc_shared_mask(cpu)) { - this_cpu_ci = get_cpu_cacheinfo(i); - if (!this_cpu_ci->info_list) - continue; - this_leaf = this_cpu_ci->info_list + index; - for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { - if (!cpu_online(sibling)) - continue; - cpumask_set_cpu(sibling, - &this_leaf->shared_cpu_map); - } - } } else return 0; diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 5b366462f5790fd1482214229678bdf0c636ed41..cd5fc61ba45020f66bb8e619b4c033eb6b786a63 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -30,7 +30,8 @@ #include #include -#include +#include +#include "intel_rdt.h" #define MAX_MBA_BW 100u #define MBA_IS_LINEAR 0x4 @@ -38,7 +39,13 @@ /* Mutex to protect rdtgroup access. */ DEFINE_MUTEX(rdtgroup_mutex); -DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid); +/* + * The cached intel_pqr_state is strictly per CPU and can never be + * updated from a remote CPU. Functions which modify the state + * are called with interrupts disabled and no preemption, which + * is sufficient for the protection. + */ +DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); /* * Used to store the max resource name width and max resource data width @@ -46,6 +53,12 @@ DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid); */ int max_name_width, max_data_width; +/* + * Global boolean for rdt_alloc which is true if any + * resource allocation is enabled. + */ +bool rdt_alloc_capable; + static void mba_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r); static void @@ -54,7 +67,9 @@ cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r); #define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].domains) struct rdt_resource rdt_resources_all[] = { + [RDT_RESOURCE_L3] = { + .rid = RDT_RESOURCE_L3, .name = "L3", .domains = domain_init(RDT_RESOURCE_L3), .msr_base = IA32_L3_CBM_BASE, @@ -67,8 +82,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_L3DATA] = { + .rid = RDT_RESOURCE_L3DATA, .name = "L3DATA", .domains = domain_init(RDT_RESOURCE_L3DATA), .msr_base = IA32_L3_CBM_BASE, @@ -81,8 +99,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_L3CODE] = { + .rid = RDT_RESOURCE_L3CODE, .name = "L3CODE", .domains = domain_init(RDT_RESOURCE_L3CODE), .msr_base = IA32_L3_CBM_BASE, @@ -95,8 +116,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_L2] = { + .rid = RDT_RESOURCE_L2, .name = "L2", .domains = domain_init(RDT_RESOURCE_L2), .msr_base = IA32_L2_CBM_BASE, @@ -109,8 +133,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_MBA] = { + .rid = RDT_RESOURCE_MBA, .name = "MB", .domains = domain_init(RDT_RESOURCE_MBA), .msr_base = IA32_MBA_THRTL_BASE, @@ -118,6 +145,7 @@ struct rdt_resource rdt_resources_all[] = { .cache_level = 3, .parse_ctrlval = parse_bw, .format_str = "%d=%*d", + .fflags = RFTYPE_RES_MB, }, }; @@ -144,33 +172,28 @@ static unsigned int cbm_idx(struct rdt_resource *r, unsigned int closid) * is always 20 on hsw server parts. The minimum cache bitmask length * allowed for HSW server is always 2 bits. Hardcode all of them. */ -static inline bool cache_alloc_hsw_probe(void) +static inline void cache_alloc_hsw_probe(void) { - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 6 && - boot_cpu_data.x86_model == INTEL_FAM6_HASWELL_X) { - struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; - u32 l, h, max_cbm = BIT_MASK(20) - 1; - - if (wrmsr_safe(IA32_L3_CBM_BASE, max_cbm, 0)) - return false; - rdmsr(IA32_L3_CBM_BASE, l, h); + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; + u32 l, h, max_cbm = BIT_MASK(20) - 1; - /* If all the bits were set in MSR, return success */ - if (l != max_cbm) - return false; + if (wrmsr_safe(IA32_L3_CBM_BASE, max_cbm, 0)) + return; + rdmsr(IA32_L3_CBM_BASE, l, h); - r->num_closid = 4; - r->default_ctrl = max_cbm; - r->cache.cbm_len = 20; - r->cache.min_cbm_bits = 2; - r->capable = true; - r->enabled = true; + /* If all the bits were set in MSR, return success */ + if (l != max_cbm) + return; - return true; - } + r->num_closid = 4; + r->default_ctrl = max_cbm; + r->cache.cbm_len = 20; + r->cache.shareable_bits = 0xc0000; + r->cache.min_cbm_bits = 2; + r->alloc_capable = true; + r->alloc_enabled = true; - return false; + rdt_alloc_capable = true; } /* @@ -213,15 +236,14 @@ static bool rdt_get_mem_config(struct rdt_resource *r) return false; } r->data_width = 3; - rdt_get_mba_infofile(r); - r->capable = true; - r->enabled = true; + r->alloc_capable = true; + r->alloc_enabled = true; return true; } -static void rdt_get_cache_config(int idx, struct rdt_resource *r) +static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r) { union cpuid_0x10_1_eax eax; union cpuid_0x10_x_edx edx; @@ -231,10 +253,10 @@ static void rdt_get_cache_config(int idx, struct rdt_resource *r) r->num_closid = edx.split.cos_max + 1; r->cache.cbm_len = eax.split.cbm_len + 1; r->default_ctrl = BIT_MASK(eax.split.cbm_len + 1) - 1; + r->cache.shareable_bits = ebx & r->default_ctrl; r->data_width = (r->cache.cbm_len + 3) / 4; - rdt_get_cache_infofile(r); - r->capable = true; - r->enabled = true; + r->alloc_capable = true; + r->alloc_enabled = true; } static void rdt_get_cdp_l3_config(int type) @@ -246,12 +268,12 @@ static void rdt_get_cdp_l3_config(int type) r->cache.cbm_len = r_l3->cache.cbm_len; r->default_ctrl = r_l3->default_ctrl; r->data_width = (r->cache.cbm_len + 3) / 4; - r->capable = true; + r->alloc_capable = true; /* * By default, CDP is disabled. CDP can be enabled by mount parameter * "cdp" during resctrl file system mount time. */ - r->enabled = false; + r->alloc_enabled = false; } static int get_cache_id(int cpu, int level) @@ -300,6 +322,19 @@ cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) wrmsrl(r->msr_base + cbm_idx(r, i), d->ctrl_val[i]); } +struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r) +{ + struct rdt_domain *d; + + list_for_each_entry(d, &r->domains, list) { + /* Find the domain that contains this CPU */ + if (cpumask_test_cpu(cpu, &d->cpu_mask)) + return d; + } + + return NULL; +} + void rdt_ctrl_update(void *arg) { struct msr_param *m = arg; @@ -307,12 +342,10 @@ void rdt_ctrl_update(void *arg) int cpu = smp_processor_id(); struct rdt_domain *d; - list_for_each_entry(d, &r->domains, list) { - /* Find the domain that contains this CPU */ - if (cpumask_test_cpu(cpu, &d->cpu_mask)) { - r->msr_update(d, m, r); - return; - } + d = get_domain_from_cpu(cpu, r); + if (d) { + r->msr_update(d, m, r); + return; } pr_warn_once("cpu %d not found in any domain for resource %s\n", cpu, r->name); @@ -326,8 +359,8 @@ void rdt_ctrl_update(void *arg) * caller, return the first domain whose id is bigger than the input id. * The domain list is sorted by id in ascending order. */ -static struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, - struct list_head **pos) +struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, + struct list_head **pos) { struct rdt_domain *d; struct list_head *l; @@ -377,6 +410,44 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) return 0; } +static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) +{ + size_t tsize; + + if (is_llc_occupancy_enabled()) { + d->rmid_busy_llc = kcalloc(BITS_TO_LONGS(r->num_rmid), + sizeof(unsigned long), + GFP_KERNEL); + if (!d->rmid_busy_llc) + return -ENOMEM; + INIT_DELAYED_WORK(&d->cqm_limbo, cqm_handle_limbo); + } + if (is_mbm_total_enabled()) { + tsize = sizeof(*d->mbm_total); + d->mbm_total = kcalloc(r->num_rmid, tsize, GFP_KERNEL); + if (!d->mbm_total) { + kfree(d->rmid_busy_llc); + return -ENOMEM; + } + } + if (is_mbm_local_enabled()) { + tsize = sizeof(*d->mbm_local); + d->mbm_local = kcalloc(r->num_rmid, tsize, GFP_KERNEL); + if (!d->mbm_local) { + kfree(d->rmid_busy_llc); + kfree(d->mbm_total); + return -ENOMEM; + } + } + + if (is_mbm_enabled()) { + INIT_DELAYED_WORK(&d->mbm_over, mbm_handle_overflow); + mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL); + } + + return 0; +} + /* * domain_add_cpu - Add a cpu to a resource's domain list. * @@ -412,14 +483,26 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) return; d->id = id; + cpumask_set_cpu(cpu, &d->cpu_mask); - if (domain_setup_ctrlval(r, d)) { + if (r->alloc_capable && domain_setup_ctrlval(r, d)) { + kfree(d); + return; + } + + if (r->mon_capable && domain_setup_mon_state(r, d)) { kfree(d); return; } - cpumask_set_cpu(cpu, &d->cpu_mask); list_add_tail(&d->list, add_pos); + + /* + * If resctrl is mounted, add + * per domain monitor data directories. + */ + if (static_branch_unlikely(&rdt_mon_enable_key)) + mkdir_mondata_subdir_allrdtgrp(r, d); } static void domain_remove_cpu(int cpu, struct rdt_resource *r) @@ -435,19 +518,58 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) cpumask_clear_cpu(cpu, &d->cpu_mask); if (cpumask_empty(&d->cpu_mask)) { + /* + * If resctrl is mounted, remove all the + * per domain monitor data directories. + */ + if (static_branch_unlikely(&rdt_mon_enable_key)) + rmdir_mondata_subdir_allrdtgrp(r, d->id); kfree(d->ctrl_val); + kfree(d->rmid_busy_llc); + kfree(d->mbm_total); + kfree(d->mbm_local); list_del(&d->list); + if (is_mbm_enabled()) + cancel_delayed_work(&d->mbm_over); + if (is_llc_occupancy_enabled() && has_busy_rmid(r, d)) { + /* + * When a package is going down, forcefully + * decrement rmid->ebusy. There is no way to know + * that the L3 was flushed and hence may lead to + * incorrect counts in rare scenarios, but leaving + * the RMID as busy creates RMID leaks if the + * package never comes back. + */ + __check_limbo(d, true); + cancel_delayed_work(&d->cqm_limbo); + } + kfree(d); + return; + } + + if (r == &rdt_resources_all[RDT_RESOURCE_L3]) { + if (is_mbm_enabled() && cpu == d->mbm_work_cpu) { + cancel_delayed_work(&d->mbm_over); + mbm_setup_overflow_handler(d, 0); + } + if (is_llc_occupancy_enabled() && cpu == d->cqm_work_cpu && + has_busy_rmid(r, d)) { + cancel_delayed_work(&d->cqm_limbo); + cqm_setup_limbo_handler(d, 0); + } } } -static void clear_closid(int cpu) +static void clear_closid_rmid(int cpu) { struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - per_cpu(cpu_closid, cpu) = 0; - state->closid = 0; - wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, 0); + state->default_closid = 0; + state->default_rmid = 0; + state->cur_closid = 0; + state->cur_rmid = 0; + wrmsr(IA32_PQR_ASSOC, 0, 0); } static int intel_rdt_online_cpu(unsigned int cpu) @@ -459,12 +581,23 @@ static int intel_rdt_online_cpu(unsigned int cpu) domain_add_cpu(cpu, r); /* The cpu is set in default rdtgroup after online. */ cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask); - clear_closid(cpu); + clear_closid_rmid(cpu); mutex_unlock(&rdtgroup_mutex); return 0; } +static void clear_childcpus(struct rdtgroup *r, unsigned int cpu) +{ + struct rdtgroup *cr; + + list_for_each_entry(cr, &r->mon.crdtgrp_list, mon.crdtgrp_list) { + if (cpumask_test_and_clear_cpu(cpu, &cr->cpu_mask)) { + break; + } + } +} + static int intel_rdt_offline_cpu(unsigned int cpu) { struct rdtgroup *rdtgrp; @@ -474,10 +607,12 @@ static int intel_rdt_offline_cpu(unsigned int cpu) for_each_capable_rdt_resource(r) domain_remove_cpu(cpu, r); list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) { - if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) + if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) { + clear_childcpus(rdtgrp, cpu); break; + } } - clear_closid(cpu); + clear_closid_rmid(cpu); mutex_unlock(&rdtgroup_mutex); return 0; @@ -492,7 +627,7 @@ static __init void rdt_init_padding(void) struct rdt_resource *r; int cl; - for_each_capable_rdt_resource(r) { + for_each_alloc_capable_rdt_resource(r) { cl = strlen(r->name); if (cl > max_name_width) max_name_width = cl; @@ -502,38 +637,153 @@ static __init void rdt_init_padding(void) } } -static __init bool get_rdt_resources(void) +enum { + RDT_FLAG_CMT, + RDT_FLAG_MBM_TOTAL, + RDT_FLAG_MBM_LOCAL, + RDT_FLAG_L3_CAT, + RDT_FLAG_L3_CDP, + RDT_FLAG_L2_CAT, + RDT_FLAG_MBA, +}; + +#define RDT_OPT(idx, n, f) \ +[idx] = { \ + .name = n, \ + .flag = f \ +} + +struct rdt_options { + char *name; + int flag; + bool force_off, force_on; +}; + +static struct rdt_options rdt_options[] __initdata = { + RDT_OPT(RDT_FLAG_CMT, "cmt", X86_FEATURE_CQM_OCCUP_LLC), + RDT_OPT(RDT_FLAG_MBM_TOTAL, "mbmtotal", X86_FEATURE_CQM_MBM_TOTAL), + RDT_OPT(RDT_FLAG_MBM_LOCAL, "mbmlocal", X86_FEATURE_CQM_MBM_LOCAL), + RDT_OPT(RDT_FLAG_L3_CAT, "l3cat", X86_FEATURE_CAT_L3), + RDT_OPT(RDT_FLAG_L3_CDP, "l3cdp", X86_FEATURE_CDP_L3), + RDT_OPT(RDT_FLAG_L2_CAT, "l2cat", X86_FEATURE_CAT_L2), + RDT_OPT(RDT_FLAG_MBA, "mba", X86_FEATURE_MBA), +}; +#define NUM_RDT_OPTIONS ARRAY_SIZE(rdt_options) + +static int __init set_rdt_options(char *str) +{ + struct rdt_options *o; + bool force_off; + char *tok; + + if (*str == '=') + str++; + while ((tok = strsep(&str, ",")) != NULL) { + force_off = *tok == '!'; + if (force_off) + tok++; + for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) { + if (strcmp(tok, o->name) == 0) { + if (force_off) + o->force_off = true; + else + o->force_on = true; + break; + } + } + } + return 1; +} +__setup("rdt", set_rdt_options); + +static bool __init rdt_cpu_has(int flag) +{ + bool ret = boot_cpu_has(flag); + struct rdt_options *o; + + if (!ret) + return ret; + + for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) { + if (flag == o->flag) { + if (o->force_off) + ret = false; + if (o->force_on) + ret = true; + break; + } + } + return ret; +} + +static __init bool get_rdt_alloc_resources(void) { bool ret = false; - if (cache_alloc_hsw_probe()) + if (rdt_alloc_capable) return true; if (!boot_cpu_has(X86_FEATURE_RDT_A)) return false; - if (boot_cpu_has(X86_FEATURE_CAT_L3)) { - rdt_get_cache_config(1, &rdt_resources_all[RDT_RESOURCE_L3]); - if (boot_cpu_has(X86_FEATURE_CDP_L3)) { + if (rdt_cpu_has(X86_FEATURE_CAT_L3)) { + rdt_get_cache_alloc_cfg(1, &rdt_resources_all[RDT_RESOURCE_L3]); + if (rdt_cpu_has(X86_FEATURE_CDP_L3)) { rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); } ret = true; } - if (boot_cpu_has(X86_FEATURE_CAT_L2)) { + if (rdt_cpu_has(X86_FEATURE_CAT_L2)) { /* CPUID 0x10.2 fields are same format at 0x10.1 */ - rdt_get_cache_config(2, &rdt_resources_all[RDT_RESOURCE_L2]); + rdt_get_cache_alloc_cfg(2, &rdt_resources_all[RDT_RESOURCE_L2]); ret = true; } - if (boot_cpu_has(X86_FEATURE_MBA)) { + if (rdt_cpu_has(X86_FEATURE_MBA)) { if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA])) ret = true; } - return ret; } +static __init bool get_rdt_mon_resources(void) +{ + if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) + rdt_mon_features |= (1 << QOS_L3_OCCUP_EVENT_ID); + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) + rdt_mon_features |= (1 << QOS_L3_MBM_TOTAL_EVENT_ID); + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) + rdt_mon_features |= (1 << QOS_L3_MBM_LOCAL_EVENT_ID); + + if (!rdt_mon_features) + return false; + + return !rdt_get_mon_l3_config(&rdt_resources_all[RDT_RESOURCE_L3]); +} + +static __init void rdt_quirks(void) +{ + switch (boot_cpu_data.x86_model) { + case INTEL_FAM6_HASWELL_X: + if (!rdt_options[RDT_FLAG_L3_CAT].force_off) + cache_alloc_hsw_probe(); + break; + case INTEL_FAM6_SKYLAKE_X: + if (boot_cpu_data.x86_mask <= 4) + set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat"); + } +} + +static __init bool get_rdt_resources(void) +{ + rdt_quirks(); + rdt_alloc_capable = get_rdt_alloc_resources(); + rdt_mon_capable = get_rdt_mon_resources(); + + return (rdt_mon_capable || rdt_alloc_capable); +} + static int __init intel_rdt_late_init(void) { struct rdt_resource *r; @@ -556,9 +806,12 @@ static int __init intel_rdt_late_init(void) return ret; } - for_each_capable_rdt_resource(r) + for_each_alloc_capable_rdt_resource(r) pr_info("Intel RDT %s allocation detected\n", r->name); + for_each_mon_capable_rdt_resource(r) + pr_info("Intel RDT %s monitoring detected\n", r->name); + return 0; } diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h new file mode 100644 index 0000000000000000000000000000000000000000..ebaddaeef023f8625a36f1064425826dedb1a39d --- /dev/null +++ b/arch/x86/kernel/cpu/intel_rdt.h @@ -0,0 +1,440 @@ +#ifndef _ASM_X86_INTEL_RDT_H +#define _ASM_X86_INTEL_RDT_H + +#include +#include +#include + +#define IA32_L3_QOS_CFG 0xc81 +#define IA32_L3_CBM_BASE 0xc90 +#define IA32_L2_CBM_BASE 0xd10 +#define IA32_MBA_THRTL_BASE 0xd50 + +#define L3_QOS_CDP_ENABLE 0x01ULL + +/* + * Event IDs are used to program IA32_QM_EVTSEL before reading event + * counter from IA32_QM_CTR + */ +#define QOS_L3_OCCUP_EVENT_ID 0x01 +#define QOS_L3_MBM_TOTAL_EVENT_ID 0x02 +#define QOS_L3_MBM_LOCAL_EVENT_ID 0x03 + +#define CQM_LIMBOCHECK_INTERVAL 1000 + +#define MBM_CNTR_WIDTH 24 +#define MBM_OVERFLOW_INTERVAL 1000 + +#define RMID_VAL_ERROR BIT_ULL(63) +#define RMID_VAL_UNAVAIL BIT_ULL(62) + +DECLARE_STATIC_KEY_FALSE(rdt_enable_key); + +/** + * struct mon_evt - Entry in the event list of a resource + * @evtid: event id + * @name: name of the event + */ +struct mon_evt { + u32 evtid; + char *name; + struct list_head list; +}; + +/** + * struct mon_data_bits - Monitoring details for each event file + * @rid: Resource id associated with the event file. + * @evtid: Event id associated with the event file + * @domid: The domain to which the event file belongs + */ +union mon_data_bits { + void *priv; + struct { + unsigned int rid : 10; + unsigned int evtid : 8; + unsigned int domid : 14; + } u; +}; + +struct rmid_read { + struct rdtgroup *rgrp; + struct rdt_domain *d; + int evtid; + bool first; + u64 val; +}; + +extern unsigned int intel_cqm_threshold; +extern bool rdt_alloc_capable; +extern bool rdt_mon_capable; +extern unsigned int rdt_mon_features; + +enum rdt_group_type { + RDTCTRL_GROUP = 0, + RDTMON_GROUP, + RDT_NUM_GROUP, +}; + +/** + * struct mongroup - store mon group's data in resctrl fs. + * @mon_data_kn kernlfs node for the mon_data directory + * @parent: parent rdtgrp + * @crdtgrp_list: child rdtgroup node list + * @rmid: rmid for this rdtgroup + */ +struct mongroup { + struct kernfs_node *mon_data_kn; + struct rdtgroup *parent; + struct list_head crdtgrp_list; + u32 rmid; +}; + +/** + * struct rdtgroup - store rdtgroup's data in resctrl file system. + * @kn: kernfs node + * @rdtgroup_list: linked list for all rdtgroups + * @closid: closid for this rdtgroup + * @cpu_mask: CPUs assigned to this rdtgroup + * @flags: status bits + * @waitcount: how many cpus expect to find this + * group when they acquire rdtgroup_mutex + * @type: indicates type of this rdtgroup - either + * monitor only or ctrl_mon group + * @mon: mongroup related data + */ +struct rdtgroup { + struct kernfs_node *kn; + struct list_head rdtgroup_list; + u32 closid; + struct cpumask cpu_mask; + int flags; + atomic_t waitcount; + enum rdt_group_type type; + struct mongroup mon; +}; + +/* rdtgroup.flags */ +#define RDT_DELETED 1 + +/* rftype.flags */ +#define RFTYPE_FLAGS_CPUS_LIST 1 + +/* + * Define the file type flags for base and info directories. + */ +#define RFTYPE_INFO BIT(0) +#define RFTYPE_BASE BIT(1) +#define RF_CTRLSHIFT 4 +#define RF_MONSHIFT 5 +#define RFTYPE_CTRL BIT(RF_CTRLSHIFT) +#define RFTYPE_MON BIT(RF_MONSHIFT) +#define RFTYPE_RES_CACHE BIT(8) +#define RFTYPE_RES_MB BIT(9) +#define RF_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL) +#define RF_MON_INFO (RFTYPE_INFO | RFTYPE_MON) +#define RF_CTRL_BASE (RFTYPE_BASE | RFTYPE_CTRL) + +/* List of all resource groups */ +extern struct list_head rdt_all_groups; + +extern int max_name_width, max_data_width; + +int __init rdtgroup_init(void); + +/** + * struct rftype - describe each file in the resctrl file system + * @name: File name + * @mode: Access mode + * @kf_ops: File operations + * @flags: File specific RFTYPE_FLAGS_* flags + * @fflags: File specific RF_* or RFTYPE_* flags + * @seq_show: Show content of the file + * @write: Write to the file + */ +struct rftype { + char *name; + umode_t mode; + struct kernfs_ops *kf_ops; + unsigned long flags; + unsigned long fflags; + + int (*seq_show)(struct kernfs_open_file *of, + struct seq_file *sf, void *v); + /* + * write() is the generic write callback which maps directly to + * kernfs write operation and overrides all other operations. + * Maximum write size is determined by ->max_write_len. + */ + ssize_t (*write)(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off); +}; + +/** + * struct mbm_state - status for each MBM counter in each domain + * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) + * @prev_msr Value of IA32_QM_CTR for this RMID last time we read it + */ +struct mbm_state { + u64 chunks; + u64 prev_msr; +}; + +/** + * struct rdt_domain - group of cpus sharing an RDT resource + * @list: all instances of this resource + * @id: unique id for this instance + * @cpu_mask: which cpus share this resource + * @rmid_busy_llc: + * bitmap of which limbo RMIDs are above threshold + * @mbm_total: saved state for MBM total bandwidth + * @mbm_local: saved state for MBM local bandwidth + * @mbm_over: worker to periodically read MBM h/w counters + * @cqm_limbo: worker to periodically read CQM h/w counters + * @mbm_work_cpu: + * worker cpu for MBM h/w counters + * @cqm_work_cpu: + * worker cpu for CQM h/w counters + * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) + * @new_ctrl: new ctrl value to be loaded + * @have_new_ctrl: did user provide new_ctrl for this domain + */ +struct rdt_domain { + struct list_head list; + int id; + struct cpumask cpu_mask; + unsigned long *rmid_busy_llc; + struct mbm_state *mbm_total; + struct mbm_state *mbm_local; + struct delayed_work mbm_over; + struct delayed_work cqm_limbo; + int mbm_work_cpu; + int cqm_work_cpu; + u32 *ctrl_val; + u32 new_ctrl; + bool have_new_ctrl; +}; + +/** + * struct msr_param - set a range of MSRs from a domain + * @res: The resource to use + * @low: Beginning index from base MSR + * @high: End index + */ +struct msr_param { + struct rdt_resource *res; + int low; + int high; +}; + +/** + * struct rdt_cache - Cache allocation related data + * @cbm_len: Length of the cache bit mask + * @min_cbm_bits: Minimum number of consecutive bits to be set + * @cbm_idx_mult: Multiplier of CBM index + * @cbm_idx_offset: Offset of CBM index. CBM index is computed by: + * closid * cbm_idx_multi + cbm_idx_offset + * in a cache bit mask + * @shareable_bits: Bitmask of shareable resource with other + * executing entities + */ +struct rdt_cache { + unsigned int cbm_len; + unsigned int min_cbm_bits; + unsigned int cbm_idx_mult; + unsigned int cbm_idx_offset; + unsigned int shareable_bits; +}; + +/** + * struct rdt_membw - Memory bandwidth allocation related data + * @max_delay: Max throttle delay. Delay is the hardware + * representation for memory bandwidth. + * @min_bw: Minimum memory bandwidth percentage user can request + * @bw_gran: Granularity at which the memory bandwidth is allocated + * @delay_linear: True if memory B/W delay is in linear scale + * @mb_map: Mapping of memory B/W percentage to memory B/W delay + */ +struct rdt_membw { + u32 max_delay; + u32 min_bw; + u32 bw_gran; + u32 delay_linear; + u32 *mb_map; +}; + +static inline bool is_llc_occupancy_enabled(void) +{ + return (rdt_mon_features & (1 << QOS_L3_OCCUP_EVENT_ID)); +} + +static inline bool is_mbm_total_enabled(void) +{ + return (rdt_mon_features & (1 << QOS_L3_MBM_TOTAL_EVENT_ID)); +} + +static inline bool is_mbm_local_enabled(void) +{ + return (rdt_mon_features & (1 << QOS_L3_MBM_LOCAL_EVENT_ID)); +} + +static inline bool is_mbm_enabled(void) +{ + return (is_mbm_total_enabled() || is_mbm_local_enabled()); +} + +static inline bool is_mbm_event(int e) +{ + return (e >= QOS_L3_MBM_TOTAL_EVENT_ID && + e <= QOS_L3_MBM_LOCAL_EVENT_ID); +} + +/** + * struct rdt_resource - attributes of an RDT resource + * @rid: The index of the resource + * @alloc_enabled: Is allocation enabled on this machine + * @mon_enabled: Is monitoring enabled for this feature + * @alloc_capable: Is allocation available on this machine + * @mon_capable: Is monitor feature available on this machine + * @name: Name to use in "schemata" file + * @num_closid: Number of CLOSIDs available + * @cache_level: Which cache level defines scope of this resource + * @default_ctrl: Specifies default cache cbm or memory B/W percent. + * @msr_base: Base MSR address for CBMs + * @msr_update: Function pointer to update QOS MSRs + * @data_width: Character width of data when displaying + * @domains: All domains for this resource + * @cache: Cache allocation related data + * @format_str: Per resource format string to show domain value + * @parse_ctrlval: Per resource function pointer to parse control values + * @evt_list: List of monitoring events + * @num_rmid: Number of RMIDs available + * @mon_scale: cqm counter * mon_scale = occupancy in bytes + * @fflags: flags to choose base and info files + */ +struct rdt_resource { + int rid; + bool alloc_enabled; + bool mon_enabled; + bool alloc_capable; + bool mon_capable; + char *name; + int num_closid; + int cache_level; + u32 default_ctrl; + unsigned int msr_base; + void (*msr_update) (struct rdt_domain *d, struct msr_param *m, + struct rdt_resource *r); + int data_width; + struct list_head domains; + struct rdt_cache cache; + struct rdt_membw membw; + const char *format_str; + int (*parse_ctrlval) (char *buf, struct rdt_resource *r, + struct rdt_domain *d); + struct list_head evt_list; + int num_rmid; + unsigned int mon_scale; + unsigned long fflags; +}; + +int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d); +int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d); + +extern struct mutex rdtgroup_mutex; + +extern struct rdt_resource rdt_resources_all[]; +extern struct rdtgroup rdtgroup_default; +DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key); + +int __init rdtgroup_init(void); + +enum { + RDT_RESOURCE_L3, + RDT_RESOURCE_L3DATA, + RDT_RESOURCE_L3CODE, + RDT_RESOURCE_L2, + RDT_RESOURCE_MBA, + + /* Must be the last */ + RDT_NUM_RESOURCES, +}; + +#define for_each_capable_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->alloc_capable || r->mon_capable) + +#define for_each_alloc_capable_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->alloc_capable) + +#define for_each_mon_capable_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->mon_capable) + +#define for_each_alloc_enabled_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->alloc_enabled) + +#define for_each_mon_enabled_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->mon_enabled) + +/* CPUID.(EAX=10H, ECX=ResID=1).EAX */ +union cpuid_0x10_1_eax { + struct { + unsigned int cbm_len:5; + } split; + unsigned int full; +}; + +/* CPUID.(EAX=10H, ECX=ResID=3).EAX */ +union cpuid_0x10_3_eax { + struct { + unsigned int max_delay:12; + } split; + unsigned int full; +}; + +/* CPUID.(EAX=10H, ECX=ResID).EDX */ +union cpuid_0x10_x_edx { + struct { + unsigned int cos_max:16; + } split; + unsigned int full; +}; + +void rdt_ctrl_update(void *arg); +struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); +void rdtgroup_kn_unlock(struct kernfs_node *kn); +struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, + struct list_head **pos); +ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off); +int rdtgroup_schemata_show(struct kernfs_open_file *of, + struct seq_file *s, void *v); +struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r); +int alloc_rmid(void); +void free_rmid(u32 rmid); +int rdt_get_mon_l3_config(struct rdt_resource *r); +void mon_event_count(void *info); +int rdtgroup_mondata_show(struct seq_file *m, void *arg); +void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, + unsigned int dom_id); +void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, + struct rdt_domain *d); +void mon_event_read(struct rmid_read *rr, struct rdt_domain *d, + struct rdtgroup *rdtgrp, int evtid, int first); +void mbm_setup_overflow_handler(struct rdt_domain *dom, + unsigned long delay_ms); +void mbm_handle_overflow(struct work_struct *work); +void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms); +void cqm_handle_limbo(struct work_struct *work); +bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d); +void __check_limbo(struct rdt_domain *d, bool force_free); + +#endif /* _ASM_X86_INTEL_RDT_H */ diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c similarity index 82% rename from arch/x86/kernel/cpu/intel_rdt_schemata.c rename to arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c index 406d7a6532f98c586164cd8115edb1912581b82a..f6ea94f8954a7d5e862b4f25a98b963d664007ec 100644 --- a/arch/x86/kernel/cpu/intel_rdt_schemata.c +++ b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "intel_rdt.h" /* * Check whether MBA bandwidth percentage value is correct. The value is @@ -192,7 +192,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid) { struct rdt_resource *r; - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { if (!strcmp(resname, r->name) && closid < r->num_closid) return parse_line(tok, r); } @@ -221,7 +221,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, closid = rdtgrp->closid; - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { list_for_each_entry(dom, &r->domains, list) dom->have_new_ctrl = false; } @@ -237,7 +237,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, goto out; } - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { ret = update_domains(r, closid); if (ret) goto out; @@ -269,12 +269,13 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of, { struct rdtgroup *rdtgrp; struct rdt_resource *r; - int closid, ret = 0; + int ret = 0; + u32 closid; rdtgrp = rdtgroup_kn_lock_live(of->kn); if (rdtgrp) { closid = rdtgrp->closid; - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { if (closid < r->num_closid) show_doms(s, r, closid); } @@ -284,3 +285,57 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of, rdtgroup_kn_unlock(of->kn); return ret; } + +void mon_event_read(struct rmid_read *rr, struct rdt_domain *d, + struct rdtgroup *rdtgrp, int evtid, int first) +{ + /* + * setup the parameters to send to the IPI to read the data. + */ + rr->rgrp = rdtgrp; + rr->evtid = evtid; + rr->d = d; + rr->val = 0; + rr->first = first; + + smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1); +} + +int rdtgroup_mondata_show(struct seq_file *m, void *arg) +{ + struct kernfs_open_file *of = m->private; + u32 resid, evtid, domid; + struct rdtgroup *rdtgrp; + struct rdt_resource *r; + union mon_data_bits md; + struct rdt_domain *d; + struct rmid_read rr; + int ret = 0; + + rdtgrp = rdtgroup_kn_lock_live(of->kn); + + md.priv = of->kn->priv; + resid = md.u.rid; + domid = md.u.domid; + evtid = md.u.evtid; + + r = &rdt_resources_all[resid]; + d = rdt_find_domain(r, domid, NULL); + if (!d) { + ret = -ENOENT; + goto out; + } + + mon_event_read(&rr, d, rdtgrp, evtid, false); + + if (rr.val & RMID_VAL_ERROR) + seq_puts(m, "Error\n"); + else if (rr.val & RMID_VAL_UNAVAIL) + seq_puts(m, "Unavailable\n"); + else + seq_printf(m, "%llu\n", rr.val * r->mon_scale); + +out: + rdtgroup_kn_unlock(of->kn); + return ret; +} diff --git a/arch/x86/kernel/cpu/intel_rdt_monitor.c b/arch/x86/kernel/cpu/intel_rdt_monitor.c new file mode 100644 index 0000000000000000000000000000000000000000..30827510094befb37aec9be1b356201a3644dd5e --- /dev/null +++ b/arch/x86/kernel/cpu/intel_rdt_monitor.c @@ -0,0 +1,499 @@ +/* + * Resource Director Technology(RDT) + * - Monitoring code + * + * Copyright (C) 2017 Intel Corporation + * + * Author: + * Vikas Shivappa + * + * This replaces the cqm.c based on perf but we reuse a lot of + * code and datastructures originally from Peter Zijlstra and Matt Fleming. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * More information about RDT be found in the Intel (R) x86 Architecture + * Software Developer Manual June 2016, volume 3, section 17.17. + */ + +#include +#include +#include +#include "intel_rdt.h" + +#define MSR_IA32_QM_CTR 0x0c8e +#define MSR_IA32_QM_EVTSEL 0x0c8d + +struct rmid_entry { + u32 rmid; + int busy; + struct list_head list; +}; + +/** + * @rmid_free_lru A least recently used list of free RMIDs + * These RMIDs are guaranteed to have an occupancy less than the + * threshold occupancy + */ +static LIST_HEAD(rmid_free_lru); + +/** + * @rmid_limbo_count count of currently unused but (potentially) + * dirty RMIDs. + * This counts RMIDs that no one is currently using but that + * may have a occupancy value > intel_cqm_threshold. User can change + * the threshold occupancy value. + */ +unsigned int rmid_limbo_count; + +/** + * @rmid_entry - The entry in the limbo and free lists. + */ +static struct rmid_entry *rmid_ptrs; + +/* + * Global boolean for rdt_monitor which is true if any + * resource monitoring is enabled. + */ +bool rdt_mon_capable; + +/* + * Global to indicate which monitoring events are enabled. + */ +unsigned int rdt_mon_features; + +/* + * This is the threshold cache occupancy at which we will consider an + * RMID available for re-allocation. + */ +unsigned int intel_cqm_threshold; + +static inline struct rmid_entry *__rmid_entry(u32 rmid) +{ + struct rmid_entry *entry; + + entry = &rmid_ptrs[rmid]; + WARN_ON(entry->rmid != rmid); + + return entry; +} + +static u64 __rmid_read(u32 rmid, u32 eventid) +{ + u64 val; + + /* + * As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured + * with a valid event code for supported resource type and the bits + * IA32_QM_EVTSEL.RMID (bits 41:32) are configured with valid RMID, + * IA32_QM_CTR.data (bits 61:0) reports the monitored data. + * IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62) + * are error bits. + */ + wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); + rdmsrl(MSR_IA32_QM_CTR, val); + + return val; +} + +static bool rmid_dirty(struct rmid_entry *entry) +{ + u64 val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID); + + return val >= intel_cqm_threshold; +} + +/* + * Check the RMIDs that are marked as busy for this domain. If the + * reported LLC occupancy is below the threshold clear the busy bit and + * decrement the count. If the busy count gets to zero on an RMID, we + * free the RMID + */ +void __check_limbo(struct rdt_domain *d, bool force_free) +{ + struct rmid_entry *entry; + struct rdt_resource *r; + u32 crmid = 1, nrmid; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + + /* + * Skip RMID 0 and start from RMID 1 and check all the RMIDs that + * are marked as busy for occupancy < threshold. If the occupancy + * is less than the threshold decrement the busy counter of the + * RMID and move it to the free list when the counter reaches 0. + */ + for (;;) { + nrmid = find_next_bit(d->rmid_busy_llc, r->num_rmid, crmid); + if (nrmid >= r->num_rmid) + break; + + entry = __rmid_entry(nrmid); + if (force_free || !rmid_dirty(entry)) { + clear_bit(entry->rmid, d->rmid_busy_llc); + if (!--entry->busy) { + rmid_limbo_count--; + list_add_tail(&entry->list, &rmid_free_lru); + } + } + crmid = nrmid + 1; + } +} + +bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d) +{ + return find_first_bit(d->rmid_busy_llc, r->num_rmid) != r->num_rmid; +} + +/* + * As of now the RMIDs allocation is global. + * However we keep track of which packages the RMIDs + * are used to optimize the limbo list management. + */ +int alloc_rmid(void) +{ + struct rmid_entry *entry; + + lockdep_assert_held(&rdtgroup_mutex); + + if (list_empty(&rmid_free_lru)) + return rmid_limbo_count ? -EBUSY : -ENOSPC; + + entry = list_first_entry(&rmid_free_lru, + struct rmid_entry, list); + list_del(&entry->list); + + return entry->rmid; +} + +static void add_rmid_to_limbo(struct rmid_entry *entry) +{ + struct rdt_resource *r; + struct rdt_domain *d; + int cpu; + u64 val; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + + entry->busy = 0; + cpu = get_cpu(); + list_for_each_entry(d, &r->domains, list) { + if (cpumask_test_cpu(cpu, &d->cpu_mask)) { + val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID); + if (val <= intel_cqm_threshold) + continue; + } + + /* + * For the first limbo RMID in the domain, + * setup up the limbo worker. + */ + if (!has_busy_rmid(r, d)) + cqm_setup_limbo_handler(d, CQM_LIMBOCHECK_INTERVAL); + set_bit(entry->rmid, d->rmid_busy_llc); + entry->busy++; + } + put_cpu(); + + if (entry->busy) + rmid_limbo_count++; + else + list_add_tail(&entry->list, &rmid_free_lru); +} + +void free_rmid(u32 rmid) +{ + struct rmid_entry *entry; + + if (!rmid) + return; + + lockdep_assert_held(&rdtgroup_mutex); + + entry = __rmid_entry(rmid); + + if (is_llc_occupancy_enabled()) + add_rmid_to_limbo(entry); + else + list_add_tail(&entry->list, &rmid_free_lru); +} + +static int __mon_event_count(u32 rmid, struct rmid_read *rr) +{ + u64 chunks, shift, tval; + struct mbm_state *m; + + tval = __rmid_read(rmid, rr->evtid); + if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { + rr->val = tval; + return -EINVAL; + } + switch (rr->evtid) { + case QOS_L3_OCCUP_EVENT_ID: + rr->val += tval; + return 0; + case QOS_L3_MBM_TOTAL_EVENT_ID: + m = &rr->d->mbm_total[rmid]; + break; + case QOS_L3_MBM_LOCAL_EVENT_ID: + m = &rr->d->mbm_local[rmid]; + break; + default: + /* + * Code would never reach here because + * an invalid event id would fail the __rmid_read. + */ + return -EINVAL; + } + + if (rr->first) { + m->prev_msr = tval; + m->chunks = 0; + return 0; + } + + shift = 64 - MBM_CNTR_WIDTH; + chunks = (tval << shift) - (m->prev_msr << shift); + chunks >>= shift; + m->chunks += chunks; + m->prev_msr = tval; + + rr->val += m->chunks; + return 0; +} + +/* + * This is called via IPI to read the CQM/MBM counters + * on a domain. + */ +void mon_event_count(void *info) +{ + struct rdtgroup *rdtgrp, *entry; + struct rmid_read *rr = info; + struct list_head *head; + + rdtgrp = rr->rgrp; + + if (__mon_event_count(rdtgrp->mon.rmid, rr)) + return; + + /* + * For Ctrl groups read data from child monitor groups. + */ + head = &rdtgrp->mon.crdtgrp_list; + + if (rdtgrp->type == RDTCTRL_GROUP) { + list_for_each_entry(entry, head, mon.crdtgrp_list) { + if (__mon_event_count(entry->mon.rmid, rr)) + return; + } + } +} + +static void mbm_update(struct rdt_domain *d, int rmid) +{ + struct rmid_read rr; + + rr.first = false; + rr.d = d; + + /* + * This is protected from concurrent reads from user + * as both the user and we hold the global mutex. + */ + if (is_mbm_total_enabled()) { + rr.evtid = QOS_L3_MBM_TOTAL_EVENT_ID; + __mon_event_count(rmid, &rr); + } + if (is_mbm_local_enabled()) { + rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID; + __mon_event_count(rmid, &rr); + } +} + +/* + * Handler to scan the limbo list and move the RMIDs + * to free list whose occupancy < threshold_occupancy. + */ +void cqm_handle_limbo(struct work_struct *work) +{ + unsigned long delay = msecs_to_jiffies(CQM_LIMBOCHECK_INTERVAL); + int cpu = smp_processor_id(); + struct rdt_resource *r; + struct rdt_domain *d; + + mutex_lock(&rdtgroup_mutex); + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + d = get_domain_from_cpu(cpu, r); + + if (!d) { + pr_warn_once("Failure to get domain for limbo worker\n"); + goto out_unlock; + } + + __check_limbo(d, false); + + if (has_busy_rmid(r, d)) + schedule_delayed_work_on(cpu, &d->cqm_limbo, delay); + +out_unlock: + mutex_unlock(&rdtgroup_mutex); +} + +void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms) +{ + unsigned long delay = msecs_to_jiffies(delay_ms); + struct rdt_resource *r; + int cpu; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + + cpu = cpumask_any(&dom->cpu_mask); + dom->cqm_work_cpu = cpu; + + schedule_delayed_work_on(cpu, &dom->cqm_limbo, delay); +} + +void mbm_handle_overflow(struct work_struct *work) +{ + unsigned long delay = msecs_to_jiffies(MBM_OVERFLOW_INTERVAL); + struct rdtgroup *prgrp, *crgrp; + int cpu = smp_processor_id(); + struct list_head *head; + struct rdt_domain *d; + + mutex_lock(&rdtgroup_mutex); + + if (!static_branch_likely(&rdt_enable_key)) + goto out_unlock; + + d = get_domain_from_cpu(cpu, &rdt_resources_all[RDT_RESOURCE_L3]); + if (!d) + goto out_unlock; + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + mbm_update(d, prgrp->mon.rmid); + + head = &prgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) + mbm_update(d, crgrp->mon.rmid); + } + + schedule_delayed_work_on(cpu, &d->mbm_over, delay); + +out_unlock: + mutex_unlock(&rdtgroup_mutex); +} + +void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms) +{ + unsigned long delay = msecs_to_jiffies(delay_ms); + int cpu; + + if (!static_branch_likely(&rdt_enable_key)) + return; + cpu = cpumask_any(&dom->cpu_mask); + dom->mbm_work_cpu = cpu; + schedule_delayed_work_on(cpu, &dom->mbm_over, delay); +} + +static int dom_data_init(struct rdt_resource *r) +{ + struct rmid_entry *entry = NULL; + int i, nr_rmids; + + nr_rmids = r->num_rmid; + rmid_ptrs = kcalloc(nr_rmids, sizeof(struct rmid_entry), GFP_KERNEL); + if (!rmid_ptrs) + return -ENOMEM; + + for (i = 0; i < nr_rmids; i++) { + entry = &rmid_ptrs[i]; + INIT_LIST_HEAD(&entry->list); + + entry->rmid = i; + list_add_tail(&entry->list, &rmid_free_lru); + } + + /* + * RMID 0 is special and is always allocated. It's used for all + * tasks that are not monitored. + */ + entry = __rmid_entry(0); + list_del(&entry->list); + + return 0; +} + +static struct mon_evt llc_occupancy_event = { + .name = "llc_occupancy", + .evtid = QOS_L3_OCCUP_EVENT_ID, +}; + +static struct mon_evt mbm_total_event = { + .name = "mbm_total_bytes", + .evtid = QOS_L3_MBM_TOTAL_EVENT_ID, +}; + +static struct mon_evt mbm_local_event = { + .name = "mbm_local_bytes", + .evtid = QOS_L3_MBM_LOCAL_EVENT_ID, +}; + +/* + * Initialize the event list for the resource. + * + * Note that MBM events are also part of RDT_RESOURCE_L3 resource + * because as per the SDM the total and local memory bandwidth + * are enumerated as part of L3 monitoring. + */ +static void l3_mon_evt_init(struct rdt_resource *r) +{ + INIT_LIST_HEAD(&r->evt_list); + + if (is_llc_occupancy_enabled()) + list_add_tail(&llc_occupancy_event.list, &r->evt_list); + if (is_mbm_total_enabled()) + list_add_tail(&mbm_total_event.list, &r->evt_list); + if (is_mbm_local_enabled()) + list_add_tail(&mbm_local_event.list, &r->evt_list); +} + +int rdt_get_mon_l3_config(struct rdt_resource *r) +{ + int ret; + + r->mon_scale = boot_cpu_data.x86_cache_occ_scale; + r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1; + + /* + * A reasonable upper limit on the max threshold is the number + * of lines tagged per RMID if all RMIDs have the same number of + * lines tagged in the LLC. + * + * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC. + */ + intel_cqm_threshold = boot_cpu_data.x86_cache_size * 1024 / r->num_rmid; + + /* h/w works in units of "boot_cpu_data.x86_cache_occ_scale" */ + intel_cqm_threshold /= r->mon_scale; + + ret = dom_data_init(r); + if (ret) + return ret; + + l3_mon_evt_init(r); + + r->mon_capable = true; + r->mon_enabled = true; + + return 0; +} diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index 9257bd9dc6640bd2b1eff8e6cfb7021139332530..a869d4a073c5ced61e19977eccaa94cf8891e208 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c @@ -32,17 +32,25 @@ #include -#include -#include +#include +#include "intel_rdt.h" DEFINE_STATIC_KEY_FALSE(rdt_enable_key); -struct kernfs_root *rdt_root; +DEFINE_STATIC_KEY_FALSE(rdt_mon_enable_key); +DEFINE_STATIC_KEY_FALSE(rdt_alloc_enable_key); +static struct kernfs_root *rdt_root; struct rdtgroup rdtgroup_default; LIST_HEAD(rdt_all_groups); /* Kernel fs node for "info" directory under root */ static struct kernfs_node *kn_info; +/* Kernel fs node for "mon_groups" directory under root */ +static struct kernfs_node *kn_mongrp; + +/* Kernel fs node for "mon_data" directory under root */ +static struct kernfs_node *kn_mondata; + /* * Trivial allocator for CLOSIDs. Since h/w only supports a small number, * we can keep a bitmap of free CLOSIDs in a single integer. @@ -66,7 +74,7 @@ static void closid_init(void) int rdt_min_closid = 32; /* Compute rdt_min_closid across all resources */ - for_each_enabled_rdt_resource(r) + for_each_alloc_enabled_rdt_resource(r) rdt_min_closid = min(rdt_min_closid, r->num_closid); closid_free_map = BIT_MASK(rdt_min_closid) - 1; @@ -75,9 +83,9 @@ static void closid_init(void) closid_free_map &= ~1; } -int closid_alloc(void) +static int closid_alloc(void) { - int closid = ffs(closid_free_map); + u32 closid = ffs(closid_free_map); if (closid == 0) return -ENOSPC; @@ -125,28 +133,6 @@ static int rdtgroup_add_file(struct kernfs_node *parent_kn, struct rftype *rft) return 0; } -static int rdtgroup_add_files(struct kernfs_node *kn, struct rftype *rfts, - int len) -{ - struct rftype *rft; - int ret; - - lockdep_assert_held(&rdtgroup_mutex); - - for (rft = rfts; rft < rfts + len; rft++) { - ret = rdtgroup_add_file(kn, rft); - if (ret) - goto error; - } - - return 0; -error: - pr_warn("Failed to add %s, err=%d\n", rft->name, ret); - while (--rft >= rfts) - kernfs_remove_by_name(kn, rft->name); - return ret; -} - static int rdtgroup_seqfile_show(struct seq_file *m, void *arg) { struct kernfs_open_file *of = m->private; @@ -174,6 +160,11 @@ static struct kernfs_ops rdtgroup_kf_single_ops = { .seq_show = rdtgroup_seqfile_show, }; +static struct kernfs_ops kf_mondata_ops = { + .atomic_write_len = PAGE_SIZE, + .seq_show = rdtgroup_mondata_show, +}; + static bool is_cpu_list(struct kernfs_open_file *of) { struct rftype *rft = of->kn->priv; @@ -203,13 +194,18 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of, /* * This is safe against intel_rdt_sched_in() called from __switch_to() * because __switch_to() is executed with interrupts disabled. A local call - * from rdt_update_closid() is proteced against __switch_to() because + * from update_closid_rmid() is proteced against __switch_to() because * preemption is disabled. */ -static void rdt_update_cpu_closid(void *closid) +static void update_cpu_closid_rmid(void *info) { - if (closid) - this_cpu_write(cpu_closid, *(int *)closid); + struct rdtgroup *r = info; + + if (r) { + this_cpu_write(pqr_state.default_closid, r->closid); + this_cpu_write(pqr_state.default_rmid, r->mon.rmid); + } + /* * We cannot unconditionally write the MSR because the current * executing task might have its own closid selected. Just reuse @@ -221,28 +217,128 @@ static void rdt_update_cpu_closid(void *closid) /* * Update the PGR_ASSOC MSR on all cpus in @cpu_mask, * - * Per task closids must have been set up before calling this function. - * - * The per cpu closids are updated with the smp function call, when @closid - * is not NULL. If @closid is NULL then all affected percpu closids must - * have been set up before calling this function. + * Per task closids/rmids must have been set up before calling this function. */ static void -rdt_update_closid(const struct cpumask *cpu_mask, int *closid) +update_closid_rmid(const struct cpumask *cpu_mask, struct rdtgroup *r) { int cpu = get_cpu(); if (cpumask_test_cpu(cpu, cpu_mask)) - rdt_update_cpu_closid(closid); - smp_call_function_many(cpu_mask, rdt_update_cpu_closid, closid, 1); + update_cpu_closid_rmid(r); + smp_call_function_many(cpu_mask, update_cpu_closid_rmid, r, 1); put_cpu(); } +static int cpus_mon_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, + cpumask_var_t tmpmask) +{ + struct rdtgroup *prgrp = rdtgrp->mon.parent, *crgrp; + struct list_head *head; + + /* Check whether cpus belong to parent ctrl group */ + cpumask_andnot(tmpmask, newmask, &prgrp->cpu_mask); + if (cpumask_weight(tmpmask)) + return -EINVAL; + + /* Check whether cpus are dropped from this group */ + cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); + if (cpumask_weight(tmpmask)) { + /* Give any dropped cpus to parent rdtgroup */ + cpumask_or(&prgrp->cpu_mask, &prgrp->cpu_mask, tmpmask); + update_closid_rmid(tmpmask, prgrp); + } + + /* + * If we added cpus, remove them from previous group that owned them + * and update per-cpu rmid + */ + cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); + if (cpumask_weight(tmpmask)) { + head = &prgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + if (crgrp == rdtgrp) + continue; + cpumask_andnot(&crgrp->cpu_mask, &crgrp->cpu_mask, + tmpmask); + } + update_closid_rmid(tmpmask, rdtgrp); + } + + /* Done pushing/pulling - update this group with new mask */ + cpumask_copy(&rdtgrp->cpu_mask, newmask); + + return 0; +} + +static void cpumask_rdtgrp_clear(struct rdtgroup *r, struct cpumask *m) +{ + struct rdtgroup *crgrp; + + cpumask_andnot(&r->cpu_mask, &r->cpu_mask, m); + /* update the child mon group masks as well*/ + list_for_each_entry(crgrp, &r->mon.crdtgrp_list, mon.crdtgrp_list) + cpumask_and(&crgrp->cpu_mask, &r->cpu_mask, &crgrp->cpu_mask); +} + +static int cpus_ctrl_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, + cpumask_var_t tmpmask, cpumask_var_t tmpmask1) +{ + struct rdtgroup *r, *crgrp; + struct list_head *head; + + /* Check whether cpus are dropped from this group */ + cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); + if (cpumask_weight(tmpmask)) { + /* Can't drop from default group */ + if (rdtgrp == &rdtgroup_default) + return -EINVAL; + + /* Give any dropped cpus to rdtgroup_default */ + cpumask_or(&rdtgroup_default.cpu_mask, + &rdtgroup_default.cpu_mask, tmpmask); + update_closid_rmid(tmpmask, &rdtgroup_default); + } + + /* + * If we added cpus, remove them from previous group and + * the prev group's child groups that owned them + * and update per-cpu closid/rmid. + */ + cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); + if (cpumask_weight(tmpmask)) { + list_for_each_entry(r, &rdt_all_groups, rdtgroup_list) { + if (r == rdtgrp) + continue; + cpumask_and(tmpmask1, &r->cpu_mask, tmpmask); + if (cpumask_weight(tmpmask1)) + cpumask_rdtgrp_clear(r, tmpmask1); + } + update_closid_rmid(tmpmask, rdtgrp); + } + + /* Done pushing/pulling - update this group with new mask */ + cpumask_copy(&rdtgrp->cpu_mask, newmask); + + /* + * Clear child mon group masks since there is a new parent mask + * now and update the rmid for the cpus the child lost. + */ + head = &rdtgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + cpumask_and(tmpmask, &rdtgrp->cpu_mask, &crgrp->cpu_mask); + update_closid_rmid(tmpmask, rdtgrp); + cpumask_clear(&crgrp->cpu_mask); + } + + return 0; +} + static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { - cpumask_var_t tmpmask, newmask; - struct rdtgroup *rdtgrp, *r; + cpumask_var_t tmpmask, newmask, tmpmask1; + struct rdtgroup *rdtgrp; int ret; if (!buf) @@ -254,6 +350,11 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, free_cpumask_var(tmpmask); return -ENOMEM; } + if (!zalloc_cpumask_var(&tmpmask1, GFP_KERNEL)) { + free_cpumask_var(tmpmask); + free_cpumask_var(newmask); + return -ENOMEM; + } rdtgrp = rdtgroup_kn_lock_live(of->kn); if (!rdtgrp) { @@ -276,41 +377,18 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, goto unlock; } - /* Check whether cpus are dropped from this group */ - cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); - if (cpumask_weight(tmpmask)) { - /* Can't drop from default group */ - if (rdtgrp == &rdtgroup_default) { - ret = -EINVAL; - goto unlock; - } - /* Give any dropped cpus to rdtgroup_default */ - cpumask_or(&rdtgroup_default.cpu_mask, - &rdtgroup_default.cpu_mask, tmpmask); - rdt_update_closid(tmpmask, &rdtgroup_default.closid); - } - - /* - * If we added cpus, remove them from previous group that owned them - * and update per-cpu closid - */ - cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); - if (cpumask_weight(tmpmask)) { - list_for_each_entry(r, &rdt_all_groups, rdtgroup_list) { - if (r == rdtgrp) - continue; - cpumask_andnot(&r->cpu_mask, &r->cpu_mask, tmpmask); - } - rdt_update_closid(tmpmask, &rdtgrp->closid); - } - - /* Done pushing/pulling - update this group with new mask */ - cpumask_copy(&rdtgrp->cpu_mask, newmask); + if (rdtgrp->type == RDTCTRL_GROUP) + ret = cpus_ctrl_write(rdtgrp, newmask, tmpmask, tmpmask1); + else if (rdtgrp->type == RDTMON_GROUP) + ret = cpus_mon_write(rdtgrp, newmask, tmpmask); + else + ret = -EINVAL; unlock: rdtgroup_kn_unlock(of->kn); free_cpumask_var(tmpmask); free_cpumask_var(newmask); + free_cpumask_var(tmpmask1); return ret ?: nbytes; } @@ -336,6 +414,7 @@ static void move_myself(struct callback_head *head) if (atomic_dec_and_test(&rdtgrp->waitcount) && (rdtgrp->flags & RDT_DELETED)) { current->closid = 0; + current->rmid = 0; kfree(rdtgrp); } @@ -374,7 +453,20 @@ static int __rdtgroup_move_task(struct task_struct *tsk, atomic_dec(&rdtgrp->waitcount); kfree(callback); } else { - tsk->closid = rdtgrp->closid; + /* + * For ctrl_mon groups move both closid and rmid. + * For monitor groups, can move the tasks only from + * their parent CTRL group. + */ + if (rdtgrp->type == RDTCTRL_GROUP) { + tsk->closid = rdtgrp->closid; + tsk->rmid = rdtgrp->mon.rmid; + } else if (rdtgrp->type == RDTMON_GROUP) { + if (rdtgrp->mon.parent->closid == tsk->closid) + tsk->rmid = rdtgrp->mon.rmid; + else + ret = -EINVAL; + } } return ret; } @@ -454,7 +546,8 @@ static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) rcu_read_lock(); for_each_process_thread(p, t) { - if (t->closid == r->closid) + if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || + (r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) seq_printf(s, "%d\n", t->pid); } rcu_read_unlock(); @@ -476,39 +569,6 @@ static int rdtgroup_tasks_show(struct kernfs_open_file *of, return ret; } -/* Files in each rdtgroup */ -static struct rftype rdtgroup_base_files[] = { - { - .name = "cpus", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_cpus_write, - .seq_show = rdtgroup_cpus_show, - }, - { - .name = "cpus_list", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_cpus_write, - .seq_show = rdtgroup_cpus_show, - .flags = RFTYPE_FLAGS_CPUS_LIST, - }, - { - .name = "tasks", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_tasks_write, - .seq_show = rdtgroup_tasks_show, - }, - { - .name = "schemata", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_schemata_write, - .seq_show = rdtgroup_schemata_show, - }, -}; - static int rdt_num_closids_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { @@ -536,6 +596,15 @@ static int rdt_min_cbm_bits_show(struct kernfs_open_file *of, return 0; } +static int rdt_shareable_bits_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%x\n", r->cache.shareable_bits); + return 0; +} + static int rdt_min_bw_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { @@ -545,6 +614,28 @@ static int rdt_min_bw_show(struct kernfs_open_file *of, return 0; } +static int rdt_num_rmids_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%d\n", r->num_rmid); + + return 0; +} + +static int rdt_mon_features_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + struct mon_evt *mevt; + + list_for_each_entry(mevt, &r->evt_list, list) + seq_printf(seq, "%s\n", mevt->name); + + return 0; +} + static int rdt_bw_gran_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { @@ -563,100 +654,220 @@ static int rdt_delay_linear_show(struct kernfs_open_file *of, return 0; } +static int max_threshold_occ_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%u\n", intel_cqm_threshold * r->mon_scale); + + return 0; +} + +static ssize_t max_threshold_occ_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct rdt_resource *r = of->kn->parent->priv; + unsigned int bytes; + int ret; + + ret = kstrtouint(buf, 0, &bytes); + if (ret) + return ret; + + if (bytes > (boot_cpu_data.x86_cache_size * 1024)) + return -EINVAL; + + intel_cqm_threshold = bytes / r->mon_scale; + + return nbytes; +} + /* rdtgroup information files for one cache resource. */ -static struct rftype res_cache_info_files[] = { +static struct rftype res_common_files[] = { { .name = "num_closids", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_num_closids_show, + .fflags = RF_CTRL_INFO, + }, + { + .name = "mon_features", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_mon_features_show, + .fflags = RF_MON_INFO, + }, + { + .name = "num_rmids", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_num_rmids_show, + .fflags = RF_MON_INFO, }, { .name = "cbm_mask", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_default_ctrl_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, { .name = "min_cbm_bits", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_min_cbm_bits_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, -}; - -/* rdtgroup information files for memory bandwidth. */ -static struct rftype res_mba_info_files[] = { { - .name = "num_closids", + .name = "shareable_bits", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, - .seq_show = rdt_num_closids_show, + .seq_show = rdt_shareable_bits_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, { .name = "min_bandwidth", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_min_bw_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, }, { .name = "bandwidth_gran", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_bw_gran_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, }, { .name = "delay_linear", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_delay_linear_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, + }, + { + .name = "max_threshold_occupancy", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = max_threshold_occ_write, + .seq_show = max_threshold_occ_show, + .fflags = RF_MON_INFO | RFTYPE_RES_CACHE, + }, + { + .name = "cpus", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_cpus_write, + .seq_show = rdtgroup_cpus_show, + .fflags = RFTYPE_BASE, + }, + { + .name = "cpus_list", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_cpus_write, + .seq_show = rdtgroup_cpus_show, + .flags = RFTYPE_FLAGS_CPUS_LIST, + .fflags = RFTYPE_BASE, + }, + { + .name = "tasks", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_tasks_write, + .seq_show = rdtgroup_tasks_show, + .fflags = RFTYPE_BASE, + }, + { + .name = "schemata", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_schemata_write, + .seq_show = rdtgroup_schemata_show, + .fflags = RF_CTRL_BASE, }, }; -void rdt_get_mba_infofile(struct rdt_resource *r) +static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) { - r->info_files = res_mba_info_files; - r->nr_info_files = ARRAY_SIZE(res_mba_info_files); -} + struct rftype *rfts, *rft; + int ret, len; -void rdt_get_cache_infofile(struct rdt_resource *r) -{ - r->info_files = res_cache_info_files; - r->nr_info_files = ARRAY_SIZE(res_cache_info_files); + rfts = res_common_files; + len = ARRAY_SIZE(res_common_files); + + lockdep_assert_held(&rdtgroup_mutex); + + for (rft = rfts; rft < rfts + len; rft++) { + if ((fflags & rft->fflags) == rft->fflags) { + ret = rdtgroup_add_file(kn, rft); + if (ret) + goto error; + } + } + + return 0; +error: + pr_warn("Failed to add %s, err=%d\n", rft->name, ret); + while (--rft >= rfts) { + if ((fflags & rft->fflags) == rft->fflags) + kernfs_remove_by_name(kn, rft->name); + } + return ret; } -static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) +static int rdtgroup_mkdir_info_resdir(struct rdt_resource *r, char *name, + unsigned long fflags) { struct kernfs_node *kn_subdir; - struct rftype *res_info_files; - struct rdt_resource *r; - int ret, len; + int ret; - /* create the directory */ - kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); - if (IS_ERR(kn_info)) - return PTR_ERR(kn_info); + kn_subdir = kernfs_create_dir(kn_info, name, + kn_info->mode, r); + if (IS_ERR(kn_subdir)) + return PTR_ERR(kn_subdir); + + kernfs_get(kn_subdir); + ret = rdtgroup_kn_set_ugid(kn_subdir); + if (ret) + return ret; + + ret = rdtgroup_add_files(kn_subdir, fflags); + if (!ret) + kernfs_activate(kn_subdir); + + return ret; +} + +static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) +{ + struct rdt_resource *r; + unsigned long fflags; + char name[32]; + int ret; + + /* create the directory */ + kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); + if (IS_ERR(kn_info)) + return PTR_ERR(kn_info); kernfs_get(kn_info); - for_each_enabled_rdt_resource(r) { - kn_subdir = kernfs_create_dir(kn_info, r->name, - kn_info->mode, r); - if (IS_ERR(kn_subdir)) { - ret = PTR_ERR(kn_subdir); - goto out_destroy; - } - kernfs_get(kn_subdir); - ret = rdtgroup_kn_set_ugid(kn_subdir); + for_each_alloc_enabled_rdt_resource(r) { + fflags = r->fflags | RF_CTRL_INFO; + ret = rdtgroup_mkdir_info_resdir(r, r->name, fflags); if (ret) goto out_destroy; + } - res_info_files = r->info_files; - len = r->nr_info_files; - - ret = rdtgroup_add_files(kn_subdir, res_info_files, len); + for_each_mon_enabled_rdt_resource(r) { + fflags = r->fflags | RF_MON_INFO; + sprintf(name, "%s_MON", r->name); + ret = rdtgroup_mkdir_info_resdir(r, name, fflags); if (ret) goto out_destroy; - kernfs_activate(kn_subdir); } /* @@ -678,6 +889,39 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) return ret; } +static int +mongroup_create_dir(struct kernfs_node *parent_kn, struct rdtgroup *prgrp, + char *name, struct kernfs_node **dest_kn) +{ + struct kernfs_node *kn; + int ret; + + /* create the directory */ + kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp); + if (IS_ERR(kn)) + return PTR_ERR(kn); + + if (dest_kn) + *dest_kn = kn; + + /* + * This extra ref will be put in kernfs_remove() and guarantees + * that @rdtgrp->kn is always accessible. + */ + kernfs_get(kn); + + ret = rdtgroup_kn_set_ugid(kn); + if (ret) + goto out_destroy; + + kernfs_activate(kn); + + return 0; + +out_destroy: + kernfs_remove(kn); + return ret; +} static void l3_qos_cfg_update(void *arg) { bool *enable = arg; @@ -718,14 +962,15 @@ static int cdp_enable(void) struct rdt_resource *r_l3 = &rdt_resources_all[RDT_RESOURCE_L3]; int ret; - if (!r_l3->capable || !r_l3data->capable || !r_l3code->capable) + if (!r_l3->alloc_capable || !r_l3data->alloc_capable || + !r_l3code->alloc_capable) return -EINVAL; ret = set_l3_qos_cfg(r_l3, true); if (!ret) { - r_l3->enabled = false; - r_l3data->enabled = true; - r_l3code->enabled = true; + r_l3->alloc_enabled = false; + r_l3data->alloc_enabled = true; + r_l3code->alloc_enabled = true; } return ret; } @@ -734,11 +979,11 @@ static void cdp_disable(void) { struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; - r->enabled = r->capable; + r->alloc_enabled = r->alloc_capable; - if (rdt_resources_all[RDT_RESOURCE_L3DATA].enabled) { - rdt_resources_all[RDT_RESOURCE_L3DATA].enabled = false; - rdt_resources_all[RDT_RESOURCE_L3CODE].enabled = false; + if (rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled) { + rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled = false; + rdt_resources_all[RDT_RESOURCE_L3CODE].alloc_enabled = false; set_l3_qos_cfg(r, false); } } @@ -823,10 +1068,16 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn) } } +static int mkdir_mondata_all(struct kernfs_node *parent_kn, + struct rdtgroup *prgrp, + struct kernfs_node **mon_data_kn); + static struct dentry *rdt_mount(struct file_system_type *fs_type, int flags, const char *unused_dev_name, void *data) { + struct rdt_domain *dom; + struct rdt_resource *r; struct dentry *dentry; int ret; @@ -853,15 +1104,54 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type, goto out_cdp; } + if (rdt_mon_capable) { + ret = mongroup_create_dir(rdtgroup_default.kn, + NULL, "mon_groups", + &kn_mongrp); + if (ret) { + dentry = ERR_PTR(ret); + goto out_info; + } + kernfs_get(kn_mongrp); + + ret = mkdir_mondata_all(rdtgroup_default.kn, + &rdtgroup_default, &kn_mondata); + if (ret) { + dentry = ERR_PTR(ret); + goto out_mongrp; + } + kernfs_get(kn_mondata); + rdtgroup_default.mon.mon_data_kn = kn_mondata; + } + dentry = kernfs_mount(fs_type, flags, rdt_root, RDTGROUP_SUPER_MAGIC, NULL); if (IS_ERR(dentry)) - goto out_destroy; + goto out_mondata; + + if (rdt_alloc_capable) + static_branch_enable(&rdt_alloc_enable_key); + if (rdt_mon_capable) + static_branch_enable(&rdt_mon_enable_key); + + if (rdt_alloc_capable || rdt_mon_capable) + static_branch_enable(&rdt_enable_key); + + if (is_mbm_enabled()) { + r = &rdt_resources_all[RDT_RESOURCE_L3]; + list_for_each_entry(dom, &r->domains, list) + mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL); + } - static_branch_enable(&rdt_enable_key); goto out; -out_destroy: +out_mondata: + if (rdt_mon_capable) + kernfs_remove(kn_mondata); +out_mongrp: + if (rdt_mon_capable) + kernfs_remove(kn_mongrp); +out_info: kernfs_remove(kn_info); out_cdp: cdp_disable(); @@ -909,6 +1199,18 @@ static int reset_all_ctrls(struct rdt_resource *r) return 0; } +static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_alloc_capable && + (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); +} + +static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_mon_capable && + (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); +} + /* * Move tasks from one to the other group. If @from is NULL, then all tasks * in the systems are moved unconditionally (used for teardown). @@ -924,8 +1226,11 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, read_lock(&tasklist_lock); for_each_process_thread(p, t) { - if (!from || t->closid == from->closid) { + if (!from || is_closid_match(t, from) || + is_rmid_match(t, from)) { t->closid = to->closid; + t->rmid = to->mon.rmid; + #ifdef CONFIG_SMP /* * This is safe on x86 w/o barriers as the ordering @@ -944,6 +1249,19 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, read_unlock(&tasklist_lock); } +static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp) +{ + struct rdtgroup *sentry, *stmp; + struct list_head *head; + + head = &rdtgrp->mon.crdtgrp_list; + list_for_each_entry_safe(sentry, stmp, head, mon.crdtgrp_list) { + free_rmid(sentry->mon.rmid); + list_del(&sentry->mon.crdtgrp_list); + kfree(sentry); + } +} + /* * Forcibly remove all of subdirectories under root. */ @@ -955,6 +1273,9 @@ static void rmdir_all_sub(void) rdt_move_group_tasks(NULL, &rdtgroup_default, NULL); list_for_each_entry_safe(rdtgrp, tmp, &rdt_all_groups, rdtgroup_list) { + /* Free any child rmids */ + free_all_child_rdtgrp(rdtgrp); + /* Remove each rdtgroup other than root */ if (rdtgrp == &rdtgroup_default) continue; @@ -967,16 +1288,20 @@ static void rmdir_all_sub(void) cpumask_or(&rdtgroup_default.cpu_mask, &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); + free_rmid(rdtgrp->mon.rmid); + kernfs_remove(rdtgrp->kn); list_del(&rdtgrp->rdtgroup_list); kfree(rdtgrp); } /* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */ get_online_cpus(); - rdt_update_closid(cpu_online_mask, &rdtgroup_default.closid); + update_closid_rmid(cpu_online_mask, &rdtgroup_default); put_online_cpus(); kernfs_remove(kn_info); + kernfs_remove(kn_mongrp); + kernfs_remove(kn_mondata); } static void rdt_kill_sb(struct super_block *sb) @@ -986,10 +1311,12 @@ static void rdt_kill_sb(struct super_block *sb) mutex_lock(&rdtgroup_mutex); /*Put everything back to default values. */ - for_each_enabled_rdt_resource(r) + for_each_alloc_enabled_rdt_resource(r) reset_all_ctrls(r); cdp_disable(); rmdir_all_sub(); + static_branch_disable(&rdt_alloc_enable_key); + static_branch_disable(&rdt_mon_enable_key); static_branch_disable(&rdt_enable_key); kernfs_kill_sb(sb); mutex_unlock(&rdtgroup_mutex); @@ -1001,46 +1328,223 @@ static struct file_system_type rdt_fs_type = { .kill_sb = rdt_kill_sb, }; -static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, - umode_t mode) +static int mon_addfile(struct kernfs_node *parent_kn, const char *name, + void *priv) { - struct rdtgroup *parent, *rdtgrp; struct kernfs_node *kn; - int ret, closid; + int ret = 0; - /* Only allow mkdir in the root directory */ - if (parent_kn != rdtgroup_default.kn) - return -EPERM; + kn = __kernfs_create_file(parent_kn, name, 0444, 0, + &kf_mondata_ops, priv, NULL, NULL); + if (IS_ERR(kn)) + return PTR_ERR(kn); - /* Do not accept '\n' to avoid unparsable situation. */ - if (strchr(name, '\n')) - return -EINVAL; + ret = rdtgroup_kn_set_ugid(kn); + if (ret) { + kernfs_remove(kn); + return ret; + } - parent = rdtgroup_kn_lock_live(parent_kn); - if (!parent) { - ret = -ENODEV; - goto out_unlock; + return ret; +} + +/* + * Remove all subdirectories of mon_data of ctrl_mon groups + * and monitor groups with given domain id. + */ +void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, unsigned int dom_id) +{ + struct rdtgroup *prgrp, *crgrp; + char name[32]; + + if (!r->mon_enabled) + return; + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + sprintf(name, "mon_%s_%02d", r->name, dom_id); + kernfs_remove_by_name(prgrp->mon.mon_data_kn, name); + + list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list) + kernfs_remove_by_name(crgrp->mon.mon_data_kn, name); } +} - ret = closid_alloc(); - if (ret < 0) +static int mkdir_mondata_subdir(struct kernfs_node *parent_kn, + struct rdt_domain *d, + struct rdt_resource *r, struct rdtgroup *prgrp) +{ + union mon_data_bits priv; + struct kernfs_node *kn; + struct mon_evt *mevt; + struct rmid_read rr; + char name[32]; + int ret; + + sprintf(name, "mon_%s_%02d", r->name, d->id); + /* create the directory */ + kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp); + if (IS_ERR(kn)) + return PTR_ERR(kn); + + /* + * This extra ref will be put in kernfs_remove() and guarantees + * that kn is always accessible. + */ + kernfs_get(kn); + ret = rdtgroup_kn_set_ugid(kn); + if (ret) + goto out_destroy; + + if (WARN_ON(list_empty(&r->evt_list))) { + ret = -EPERM; + goto out_destroy; + } + + priv.u.rid = r->rid; + priv.u.domid = d->id; + list_for_each_entry(mevt, &r->evt_list, list) { + priv.u.evtid = mevt->evtid; + ret = mon_addfile(kn, mevt->name, priv.priv); + if (ret) + goto out_destroy; + + if (is_mbm_event(mevt->evtid)) + mon_event_read(&rr, d, prgrp, mevt->evtid, true); + } + kernfs_activate(kn); + return 0; + +out_destroy: + kernfs_remove(kn); + return ret; +} + +/* + * Add all subdirectories of mon_data for "ctrl_mon" groups + * and "monitor" groups with given domain id. + */ +void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, + struct rdt_domain *d) +{ + struct kernfs_node *parent_kn; + struct rdtgroup *prgrp, *crgrp; + struct list_head *head; + + if (!r->mon_enabled) + return; + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + parent_kn = prgrp->mon.mon_data_kn; + mkdir_mondata_subdir(parent_kn, d, r, prgrp); + + head = &prgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + parent_kn = crgrp->mon.mon_data_kn; + mkdir_mondata_subdir(parent_kn, d, r, crgrp); + } + } +} + +static int mkdir_mondata_subdir_alldom(struct kernfs_node *parent_kn, + struct rdt_resource *r, + struct rdtgroup *prgrp) +{ + struct rdt_domain *dom; + int ret; + + list_for_each_entry(dom, &r->domains, list) { + ret = mkdir_mondata_subdir(parent_kn, dom, r, prgrp); + if (ret) + return ret; + } + + return 0; +} + +/* + * This creates a directory mon_data which contains the monitored data. + * + * mon_data has one directory for each domain whic are named + * in the format mon__. For ex: A mon_data + * with L3 domain looks as below: + * ./mon_data: + * mon_L3_00 + * mon_L3_01 + * mon_L3_02 + * ... + * + * Each domain directory has one file per event: + * ./mon_L3_00/: + * llc_occupancy + * + */ +static int mkdir_mondata_all(struct kernfs_node *parent_kn, + struct rdtgroup *prgrp, + struct kernfs_node **dest_kn) +{ + struct rdt_resource *r; + struct kernfs_node *kn; + int ret; + + /* + * Create the mon_data directory first. + */ + ret = mongroup_create_dir(parent_kn, NULL, "mon_data", &kn); + if (ret) + return ret; + + if (dest_kn) + *dest_kn = kn; + + /* + * Create the subdirectories for each domain. Note that all events + * in a domain like L3 are grouped into a resource whose domain is L3 + */ + for_each_mon_enabled_rdt_resource(r) { + ret = mkdir_mondata_subdir_alldom(kn, r, prgrp); + if (ret) + goto out_destroy; + } + + return 0; + +out_destroy: + kernfs_remove(kn); + return ret; +} + +static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, + struct kernfs_node *prgrp_kn, + const char *name, umode_t mode, + enum rdt_group_type rtype, struct rdtgroup **r) +{ + struct rdtgroup *prdtgrp, *rdtgrp; + struct kernfs_node *kn; + uint files = 0; + int ret; + + prdtgrp = rdtgroup_kn_lock_live(prgrp_kn); + if (!prdtgrp) { + ret = -ENODEV; goto out_unlock; - closid = ret; + } /* allocate the rdtgroup. */ rdtgrp = kzalloc(sizeof(*rdtgrp), GFP_KERNEL); if (!rdtgrp) { ret = -ENOSPC; - goto out_closid_free; + goto out_unlock; } - rdtgrp->closid = closid; - list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups); + *r = rdtgrp; + rdtgrp->mon.parent = prdtgrp; + rdtgrp->type = rtype; + INIT_LIST_HEAD(&rdtgrp->mon.crdtgrp_list); /* kernfs creates the directory for rdtgrp */ - kn = kernfs_create_dir(parent->kn, name, mode, rdtgrp); + kn = kernfs_create_dir(parent_kn, name, mode, rdtgrp); if (IS_ERR(kn)) { ret = PTR_ERR(kn); - goto out_cancel_ref; + goto out_free_rgrp; } rdtgrp->kn = kn; @@ -1056,43 +1560,211 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, if (ret) goto out_destroy; - ret = rdtgroup_add_files(kn, rdtgroup_base_files, - ARRAY_SIZE(rdtgroup_base_files)); + files = RFTYPE_BASE | RFTYPE_CTRL; + files = RFTYPE_BASE | BIT(RF_CTRLSHIFT + rtype); + ret = rdtgroup_add_files(kn, files); if (ret) goto out_destroy; + if (rdt_mon_capable) { + ret = alloc_rmid(); + if (ret < 0) + goto out_destroy; + rdtgrp->mon.rmid = ret; + + ret = mkdir_mondata_all(kn, rdtgrp, &rdtgrp->mon.mon_data_kn); + if (ret) + goto out_idfree; + } kernfs_activate(kn); - ret = 0; - goto out_unlock; + /* + * The caller unlocks the prgrp_kn upon success. + */ + return 0; +out_idfree: + free_rmid(rdtgrp->mon.rmid); out_destroy: kernfs_remove(rdtgrp->kn); -out_cancel_ref: - list_del(&rdtgrp->rdtgroup_list); +out_free_rgrp: kfree(rdtgrp); -out_closid_free: - closid_free(closid); out_unlock: - rdtgroup_kn_unlock(parent_kn); + rdtgroup_kn_unlock(prgrp_kn); return ret; } -static int rdtgroup_rmdir(struct kernfs_node *kn) +static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp) +{ + kernfs_remove(rgrp->kn); + free_rmid(rgrp->mon.rmid); + kfree(rgrp); +} + +/* + * Create a monitor group under "mon_groups" directory of a control + * and monitor group(ctrl_mon). This is a resource group + * to monitor a subset of tasks and cpus in its parent ctrl_mon group. + */ +static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn, + struct kernfs_node *prgrp_kn, + const char *name, + umode_t mode) +{ + struct rdtgroup *rdtgrp, *prgrp; + int ret; + + ret = mkdir_rdt_prepare(parent_kn, prgrp_kn, name, mode, RDTMON_GROUP, + &rdtgrp); + if (ret) + return ret; + + prgrp = rdtgrp->mon.parent; + rdtgrp->closid = prgrp->closid; + + /* + * Add the rdtgrp to the list of rdtgrps the parent + * ctrl_mon group has to track. + */ + list_add_tail(&rdtgrp->mon.crdtgrp_list, &prgrp->mon.crdtgrp_list); + + rdtgroup_kn_unlock(prgrp_kn); + return ret; +} + +/* + * These are rdtgroups created under the root directory. Can be used + * to allocate and monitor resources. + */ +static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn, + struct kernfs_node *prgrp_kn, + const char *name, umode_t mode) { - int ret, cpu, closid = rdtgroup_default.closid; struct rdtgroup *rdtgrp; - cpumask_var_t tmpmask; + struct kernfs_node *kn; + u32 closid; + int ret; - if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL)) - return -ENOMEM; + ret = mkdir_rdt_prepare(parent_kn, prgrp_kn, name, mode, RDTCTRL_GROUP, + &rdtgrp); + if (ret) + return ret; - rdtgrp = rdtgroup_kn_lock_live(kn); - if (!rdtgrp) { - ret = -EPERM; - goto out; + kn = rdtgrp->kn; + ret = closid_alloc(); + if (ret < 0) + goto out_common_fail; + closid = ret; + + rdtgrp->closid = closid; + list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups); + + if (rdt_mon_capable) { + /* + * Create an empty mon_groups directory to hold the subset + * of tasks and cpus to monitor. + */ + ret = mongroup_create_dir(kn, NULL, "mon_groups", NULL); + if (ret) + goto out_id_free; } + goto out_unlock; + +out_id_free: + closid_free(closid); + list_del(&rdtgrp->rdtgroup_list); +out_common_fail: + mkdir_rdt_prepare_clean(rdtgrp); +out_unlock: + rdtgroup_kn_unlock(prgrp_kn); + return ret; +} + +/* + * We allow creating mon groups only with in a directory called "mon_groups" + * which is present in every ctrl_mon group. Check if this is a valid + * "mon_groups" directory. + * + * 1. The directory should be named "mon_groups". + * 2. The mon group itself should "not" be named "mon_groups". + * This makes sure "mon_groups" directory always has a ctrl_mon group + * as parent. + */ +static bool is_mon_groups(struct kernfs_node *kn, const char *name) +{ + return (!strcmp(kn->name, "mon_groups") && + strcmp(name, "mon_groups")); +} + +static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, + umode_t mode) +{ + /* Do not accept '\n' to avoid unparsable situation. */ + if (strchr(name, '\n')) + return -EINVAL; + + /* + * If the parent directory is the root directory and RDT + * allocation is supported, add a control and monitoring + * subdirectory + */ + if (rdt_alloc_capable && parent_kn == rdtgroup_default.kn) + return rdtgroup_mkdir_ctrl_mon(parent_kn, parent_kn, name, mode); + + /* + * If RDT monitoring is supported and the parent directory is a valid + * "mon_groups" directory, add a monitoring subdirectory. + */ + if (rdt_mon_capable && is_mon_groups(parent_kn, name)) + return rdtgroup_mkdir_mon(parent_kn, parent_kn->parent, name, mode); + + return -EPERM; +} + +static int rdtgroup_rmdir_mon(struct kernfs_node *kn, struct rdtgroup *rdtgrp, + cpumask_var_t tmpmask) +{ + struct rdtgroup *prdtgrp = rdtgrp->mon.parent; + int cpu; + + /* Give any tasks back to the parent group */ + rdt_move_group_tasks(rdtgrp, prdtgrp, tmpmask); + + /* Update per cpu rmid of the moved CPUs first */ + for_each_cpu(cpu, &rdtgrp->cpu_mask) + per_cpu(pqr_state.default_rmid, cpu) = prdtgrp->mon.rmid; + /* + * Update the MSR on moved CPUs and CPUs which have moved + * task running on them. + */ + cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask); + update_closid_rmid(tmpmask, NULL); + + rdtgrp->flags = RDT_DELETED; + free_rmid(rdtgrp->mon.rmid); + + /* + * Remove the rdtgrp from the parent ctrl_mon group's list + */ + WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list)); + list_del(&rdtgrp->mon.crdtgrp_list); + + /* + * one extra hold on this, will drop when we kfree(rdtgrp) + * in rdtgroup_kn_unlock() + */ + kernfs_get(kn); + kernfs_remove(rdtgrp->kn); + + return 0; +} + +static int rdtgroup_rmdir_ctrl(struct kernfs_node *kn, struct rdtgroup *rdtgrp, + cpumask_var_t tmpmask) +{ + int cpu; + /* Give any tasks back to the default group */ rdt_move_group_tasks(rdtgrp, &rdtgroup_default, tmpmask); @@ -1100,18 +1772,28 @@ static int rdtgroup_rmdir(struct kernfs_node *kn) cpumask_or(&rdtgroup_default.cpu_mask, &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); - /* Update per cpu closid of the moved CPUs first */ - for_each_cpu(cpu, &rdtgrp->cpu_mask) - per_cpu(cpu_closid, cpu) = closid; + /* Update per cpu closid and rmid of the moved CPUs first */ + for_each_cpu(cpu, &rdtgrp->cpu_mask) { + per_cpu(pqr_state.default_closid, cpu) = rdtgroup_default.closid; + per_cpu(pqr_state.default_rmid, cpu) = rdtgroup_default.mon.rmid; + } + /* * Update the MSR on moved CPUs and CPUs which have moved * task running on them. */ cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask); - rdt_update_closid(tmpmask, NULL); + update_closid_rmid(tmpmask, NULL); rdtgrp->flags = RDT_DELETED; closid_free(rdtgrp->closid); + free_rmid(rdtgrp->mon.rmid); + + /* + * Free all the child monitor group rmids. + */ + free_all_child_rdtgrp(rdtgrp); + list_del(&rdtgrp->rdtgroup_list); /* @@ -1120,7 +1802,41 @@ static int rdtgroup_rmdir(struct kernfs_node *kn) */ kernfs_get(kn); kernfs_remove(rdtgrp->kn); - ret = 0; + + return 0; +} + +static int rdtgroup_rmdir(struct kernfs_node *kn) +{ + struct kernfs_node *parent_kn = kn->parent; + struct rdtgroup *rdtgrp; + cpumask_var_t tmpmask; + int ret = 0; + + if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL)) + return -ENOMEM; + + rdtgrp = rdtgroup_kn_lock_live(kn); + if (!rdtgrp) { + ret = -EPERM; + goto out; + } + + /* + * If the rdtgroup is a ctrl_mon group and parent directory + * is the root directory, remove the ctrl_mon group. + * + * If the rdtgroup is a mon group and parent directory + * is a valid "mon_groups" directory, remove the mon group. + */ + if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) + ret = rdtgroup_rmdir_ctrl(kn, rdtgrp, tmpmask); + else if (rdtgrp->type == RDTMON_GROUP && + is_mon_groups(parent_kn, kn->name)) + ret = rdtgroup_rmdir_mon(kn, rdtgrp, tmpmask); + else + ret = -EPERM; + out: rdtgroup_kn_unlock(kn); free_cpumask_var(tmpmask); @@ -1129,7 +1845,7 @@ static int rdtgroup_rmdir(struct kernfs_node *kn) static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf) { - if (rdt_resources_all[RDT_RESOURCE_L3DATA].enabled) + if (rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled) seq_puts(seq, ",cdp"); return 0; } @@ -1153,10 +1869,13 @@ static int __init rdtgroup_setup_root(void) mutex_lock(&rdtgroup_mutex); rdtgroup_default.closid = 0; + rdtgroup_default.mon.rmid = 0; + rdtgroup_default.type = RDTCTRL_GROUP; + INIT_LIST_HEAD(&rdtgroup_default.mon.crdtgrp_list); + list_add(&rdtgroup_default.rdtgroup_list, &rdt_all_groups); - ret = rdtgroup_add_files(rdt_root->kn, rdtgroup_base_files, - ARRAY_SIZE(rdtgroup_base_files)); + ret = rdtgroup_add_files(rdt_root->kn, RF_CTRL_BASE); if (ret) { kernfs_destroy_root(rdt_root); goto out; diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 6dde0497efc7514b9981bd2d33014a6686c65677..3b413065c61308104794db2efe6ab939b39411a1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "mce-internal.h" @@ -1051,6 +1052,48 @@ static int do_memory_failure(struct mce *m) return ret; } +#if defined(arch_unmap_kpfn) && defined(CONFIG_MEMORY_FAILURE) + +void arch_unmap_kpfn(unsigned long pfn) +{ + unsigned long decoy_addr; + + /* + * Unmap this page from the kernel 1:1 mappings to make sure + * we don't log more errors because of speculative access to + * the page. + * We would like to just call: + * set_memory_np((unsigned long)pfn_to_kaddr(pfn), 1); + * but doing that would radically increase the odds of a + * speculative access to the posion page because we'd have + * the virtual address of the kernel 1:1 mapping sitting + * around in registers. + * Instead we get tricky. We create a non-canonical address + * that looks just like the one we want, but has bit 63 flipped. + * This relies on set_memory_np() not checking whether we passed + * a legal address. + */ + +/* + * Build time check to see if we have a spare virtual bit. Don't want + * to leave this until run time because most developers don't have a + * system that can exercise this code path. This will only become a + * problem if/when we move beyond 5-level page tables. + * + * Hard code "9" here because cpp doesn't grok ilog2(PTRS_PER_PGD) + */ +#if PGDIR_SHIFT + 9 < 63 + decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63)); +#else +#error "no unused virtual bit available" +#endif + + if (set_memory_np(decoy_addr, 1)) + pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); + +} +#endif + /* * The actual machine check handler. This only handles real * exceptions when something got corrupted coming in through int 18. diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 9e314bcf67ccdd53e585c3047ad682f4bc20dad5..40e28ed77fbf017aee3ddb5c8dd128ff8ac2b826 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -201,8 +201,8 @@ static void smca_configure(unsigned int bank, unsigned int cpu) wrmsr(smca_config, low, high); } - /* Collect bank_info using CPU 0 for now. */ - if (cpu) + /* Return early if this bank was already initialized. */ + if (smca_banks[bank].hwid) return; if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) { @@ -216,11 +216,6 @@ static void smca_configure(unsigned int bank, unsigned int cpu) for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) { s_hwid = &smca_hwid_mcatypes[i]; if (hwid_mcatype == s_hwid->hwid_mcatype) { - - WARN(smca_banks[bank].hwid, - "Bank %s already initialized!\n", - smca_get_name(s_hwid->bank_type)); - smca_banks[bank].hwid = s_hwid; smca_banks[bank].id = low; smca_banks[bank].sysfs_id = s_hwid->count++; @@ -776,24 +771,12 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc) mce_log(&m); } -static inline void __smp_deferred_error_interrupt(void) -{ - inc_irq_stat(irq_deferred_error_count); - deferred_error_int_vector(); -} - asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void) -{ - entering_irq(); - __smp_deferred_error_interrupt(); - exiting_ack_irq(); -} - -asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void) { entering_irq(); trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR); - __smp_deferred_error_interrupt(); + inc_irq_stat(irq_deferred_error_count); + deferred_error_int_vector(); trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR); exiting_ack_irq(); } diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index d7cc190ae45719bf84d721e781dc7fde00c85e14..2da67b70ba989821db25e3190a5c68964f9e1c26 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -122,7 +122,7 @@ static struct attribute *thermal_throttle_attrs[] = { NULL }; -static struct attribute_group thermal_attr_group = { +static const struct attribute_group thermal_attr_group = { .attrs = thermal_throttle_attrs, .name = "thermal_throttle" }; @@ -390,26 +390,12 @@ static void unexpected_thermal_interrupt(void) static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; -static inline void __smp_thermal_interrupt(void) -{ - inc_irq_stat(irq_thermal_count); - smp_thermal_vector(); -} - -asmlinkage __visible void __irq_entry -smp_thermal_interrupt(struct pt_regs *regs) -{ - entering_irq(); - __smp_thermal_interrupt(); - exiting_ack_irq(); -} - -asmlinkage __visible void __irq_entry -smp_trace_thermal_interrupt(struct pt_regs *regs) +asmlinkage __visible void __irq_entry smp_thermal_interrupt(struct pt_regs *r) { entering_irq(); trace_thermal_apic_entry(THERMAL_APIC_VECTOR); - __smp_thermal_interrupt(); + inc_irq_stat(irq_thermal_count); + smp_thermal_vector(); trace_thermal_apic_exit(THERMAL_APIC_VECTOR); exiting_ack_irq(); } diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index bb0e75eed10a10a1b19daf82eeef12aefd8be2db..5e7249e42f8ff9f5410e0999420c953575e1dd34 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c @@ -17,24 +17,12 @@ static void default_threshold_interrupt(void) void (*mce_threshold_vector)(void) = default_threshold_interrupt; -static inline void __smp_threshold_interrupt(void) -{ - inc_irq_stat(irq_threshold_count); - mce_threshold_vector(); -} - asmlinkage __visible void __irq_entry smp_threshold_interrupt(void) -{ - entering_irq(); - __smp_threshold_interrupt(); - exiting_ack_irq(); -} - -asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void) { entering_irq(); trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); - __smp_threshold_interrupt(); + inc_irq_stat(irq_threshold_count); + mce_threshold_vector(); trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR); exiting_ack_irq(); } diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 21b185793c80ae4910b39b85a4a7ed6bc8284427..c6daec4bdba5b180e45c5f78019fcba7b2880428 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -400,9 +400,12 @@ static void update_cache(struct ucode_patch *new_patch) list_for_each_entry(p, µcode_cache, plist) { if (p->equiv_cpu == new_patch->equiv_cpu) { - if (p->patch_id >= new_patch->patch_id) + if (p->patch_id >= new_patch->patch_id) { /* we already have the latest patch */ + kfree(new_patch->data); + kfree(new_patch); return; + } list_replace(&p->plist, &new_patch->plist); kfree(p->data); diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 9cb98ee103db1bf0cdc2349614fe0d4e59cfb21f..86e8f0b2537b3eaedd2da204d67c94947a1b16f1 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -561,7 +561,7 @@ static struct attribute *mc_default_attrs[] = { NULL }; -static struct attribute_group mc_attr_group = { +static const struct attribute_group mc_attr_group = { .attrs = mc_default_attrs, .name = "microcode", }; @@ -707,7 +707,7 @@ static struct attribute *cpu_root_microcode_attrs[] = { NULL }; -static struct attribute_group cpu_root_microcode_group = { +static const struct attribute_group cpu_root_microcode_group = { .name = "microcode", .attrs = cpu_root_microcode_attrs, }; diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 59edbe9d4ccbb1500b82136a5061abb057bd333e..8f7a9bbad514efbec73ed1beb167c7d8432521b2 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -146,18 +146,18 @@ static bool microcode_matches(struct microcode_header_intel *mc_header, return false; } -static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size) +static struct ucode_patch *memdup_patch(void *data, unsigned int size) { struct ucode_patch *p; p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); if (!p) - return ERR_PTR(-ENOMEM); + return NULL; p->data = kmemdup(data, size, GFP_KERNEL); if (!p->data) { kfree(p); - return ERR_PTR(-ENOMEM); + return NULL; } return p; @@ -183,8 +183,8 @@ static void save_microcode_patch(void *data, unsigned int size) if (mc_hdr->rev <= mc_saved_hdr->rev) continue; - p = __alloc_microcode_buf(data, size); - if (IS_ERR(p)) + p = memdup_patch(data, size); + if (!p) pr_err("Error allocating buffer %p\n", data); else list_replace(&iter->plist, &p->plist); @@ -196,24 +196,25 @@ static void save_microcode_patch(void *data, unsigned int size) * newly found. */ if (!prev_found) { - p = __alloc_microcode_buf(data, size); - if (IS_ERR(p)) + p = memdup_patch(data, size); + if (!p) pr_err("Error allocating buffer for %p\n", data); else list_add_tail(&p->plist, µcode_cache); } + if (!p) + return; + /* * Save for early loading. On 32-bit, that needs to be a physical * address as the APs are running from physical addresses, before * paging has been enabled. */ - if (p) { - if (IS_ENABLED(CONFIG_X86_32)) - intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); - else - intel_ucode_patch = p->data; - } + if (IS_ENABLED(CONFIG_X86_32)) + intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); + else + intel_ucode_patch = p->data; } static int microcode_sanity_check(void *mc, int print_err) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 70e717fccdd6cabaf8eb778b6f407c43b6e0c412..236324e83a3ae0755c4de2a087983759793c0add 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -59,13 +59,6 @@ void hyperv_vector_handler(struct pt_regs *regs) void hv_setup_vmbus_irq(void (*handler)(void)) { vmbus_handler = handler; - /* - * Setup the IDT for hypervisor callback. Prevent reallocation - * at module reload. - */ - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, - hyperv_callback_vector); } void hv_remove_vmbus_irq(void) @@ -184,9 +177,15 @@ static void __init ms_hyperv_init_platform(void) ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES); ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO); - pr_info("HyperV: features 0x%x, hints 0x%x\n", + pr_info("Hyper-V: features 0x%x, hints 0x%x\n", ms_hyperv.features, ms_hyperv.hints); + ms_hyperv.max_vp_index = cpuid_eax(HVCPUID_IMPLEMENTATION_LIMITS); + ms_hyperv.max_lp_index = cpuid_ebx(HVCPUID_IMPLEMENTATION_LIMITS); + + pr_debug("Hyper-V: max %u virtual processors, %u logical processors\n", + ms_hyperv.max_vp_index, ms_hyperv.max_lp_index); + /* * Extract host information. */ @@ -219,7 +218,7 @@ static void __init ms_hyperv_init_platform(void) rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency); hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ); lapic_timer_frequency = hv_lapic_frequency; - pr_info("HyperV: LAPIC Timer Frequency: %#x\n", + pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n", lapic_timer_frequency); } @@ -249,11 +248,14 @@ static void __init ms_hyperv_init_platform(void) * Setup the hook to get control post apic initialization. */ x86_platform.apic_post_init = hyperv_init; + hyperv_setup_mmu_ops(); + /* Setup the IDT for hypervisor callback */ + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); #endif } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { - .name = "Microsoft HyperV", + .name = "Microsoft Hyper-V", .detect = ms_hyperv_platform, .init_platform = ms_hyperv_init_platform, }; diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index c5bb63be4ba1e6a2df1203fe73079faad9fc62e7..40d5a8a752125ed5d26a7605d5eabad572879bfc 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -237,6 +237,18 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ stop_machine(mtrr_rendezvous_handler, &data, cpu_online_mask); } +static void set_mtrr_cpuslocked(unsigned int reg, unsigned long base, + unsigned long size, mtrr_type type) +{ + struct set_mtrr_data data = { .smp_reg = reg, + .smp_base = base, + .smp_size = size, + .smp_type = type + }; + + stop_machine_cpuslocked(mtrr_rendezvous_handler, &data, cpu_online_mask); +} + static void set_mtrr_from_inactive_cpu(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type) { @@ -370,7 +382,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, /* Search for an empty MTRR */ i = mtrr_if->get_free_region(base, size, replace); if (i >= 0) { - set_mtrr(i, base, size, type); + set_mtrr_cpuslocked(i, base, size, type); if (likely(replace < 0)) { mtrr_usage_table[i] = 1; } else { @@ -378,7 +390,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, if (increment) mtrr_usage_table[i]++; if (unlikely(replace != i)) { - set_mtrr(replace, 0, 0, 0); + set_mtrr_cpuslocked(replace, 0, 0, 0); mtrr_usage_table[replace] = 0; } } @@ -506,7 +518,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) goto out; } if (--mtrr_usage_table[reg] < 1) - set_mtrr(reg, 0, 0, 0); + set_mtrr_cpuslocked(reg, 0, 0, 0); error = reg; out: mutex_unlock(&mtrr_mutex); diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 23c23508c0125e50caf69a6959aaf000151cf572..05459ad3db46e2139b7d97514899d398c321c541 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -31,6 +31,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, + { X86_FEATURE_SME, CPUID_EAX, 0, 0x8000001f, 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index dbce3cca94cb46fda2b3fd676be1d078b4f73161..f13b4c00a5de4b7a7b36c40d27311672bcc9d05c 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -94,6 +94,9 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, if (stack_name) printk("%s <%s>\n", log_lvl, stack_name); + if (regs && on_stack(&stack_info, regs, sizeof(*regs))) + __show_regs(regs, 0); + /* * Scan the stack, printing any text addresses we find. At the * same time, follow proper stack frames with the unwinder. @@ -118,10 +121,8 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, * Don't print regs->ip again if it was already printed * by __show_regs() below. */ - if (regs && stack == ®s->ip) { - unwind_next_frame(&state); - continue; - } + if (regs && stack == ®s->ip) + goto next; if (stack == ret_addr_p) reliable = 1; @@ -144,6 +145,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, if (!reliable) continue; +next: /* * Get the next frame from the unwinder. No need to * check for an error: if anything goes wrong, the rest @@ -153,7 +155,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, /* if the frame has entry regs, print them */ regs = unwind_get_entry_regs(&state); - if (regs) + if (regs && on_stack(&stack_info, regs, sizeof(*regs))) __show_regs(regs, 0); } @@ -265,7 +267,7 @@ int __die(const char *str, struct pt_regs *regs, long err) #ifdef CONFIG_X86_32 if (user_mode(regs)) { sp = regs->sp; - ss = regs->ss & 0xffff; + ss = regs->ss; } else { sp = kernel_stack_pointer(regs); savesegment(ss, ss); diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index e5f0b40e66d238b931d14d78ea579abd195a3350..4f04814749037e403f063a33a3249896a4c97f55 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -37,7 +37,7 @@ static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) * This is a software stack, so 'end' can be a valid stack pointer. * It just means the stack is empty. */ - if (stack < begin || stack > end) + if (stack <= begin || stack > end) return false; info->type = STACK_TYPE_IRQ; @@ -62,7 +62,7 @@ static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) * This is a software stack, so 'end' can be a valid stack pointer. * It just means the stack is empty. */ - if (stack < begin || stack > end) + if (stack <= begin || stack > end) return false; info->type = STACK_TYPE_SOFTIRQ; diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 3e1471d5748723069d70577fd9061a1cb26770ba..225af4184f06bf4d343eb1eb43ded549299fc031 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -55,7 +55,7 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info) begin = end - (exception_stack_sizes[k] / sizeof(long)); regs = (struct pt_regs *)end - 1; - if (stack < begin || stack >= end) + if (stack <= begin || stack >= end) continue; info->type = STACK_TYPE_EXCEPTION + k; @@ -78,7 +78,7 @@ static bool in_irq_stack(unsigned long *stack, struct stack_info *info) * This is a software stack, so 'end' can be a valid stack pointer. * It just means the stack is empty. */ - if (stack < begin || stack > end) + if (stack <= begin || stack > end) return false; info->type = STACK_TYPE_IRQ; diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 532da61d605ccc2271067fdf67bac83c454616aa..71c11ad5643e80059d4f262002fc9620044b594b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -96,7 +96,8 @@ EXPORT_SYMBOL_GPL(e820__mapped_any); * Note: this function only works correctly once the E820 table is sorted and * not-overlapping (at least for the range specified), which is the case normally. */ -bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) +static struct e820_entry *__e820__mapped_all(u64 start, u64 end, + enum e820_type type) { int i; @@ -122,9 +123,28 @@ bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) * coverage of the desired range exists: */ if (start >= end) - return 1; + return entry; } - return 0; + + return NULL; +} + +/* + * This function checks if the entire range is mapped with type. + */ +bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) +{ + return __e820__mapped_all(start, end, type); +} + +/* + * This function returns the type associated with the range . + */ +int e820__get_entry_type(u64 start, u64 end) +{ + struct e820_entry *entry = __e820__mapped_all(start, end, 0); + + return entry ? entry->type : -EINVAL; } /* diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index d907c3d8633fdb289ea03397c2e76efc284517aa..927abeaf63e27744125cab694bc0f4917dc1b449 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -12,10 +12,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -527,6 +527,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_BXT_IDS(&gen9_early_ops), INTEL_KBL_IDS(&gen9_early_ops), INTEL_GLK_IDS(&gen9_early_ops), + INTEL_CNL_IDS(&gen9_early_ops), }; static void __init @@ -593,7 +594,7 @@ static void __init apple_airport_reset(int bus, int slot, int func) u64 addr; int i; - if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc.")) + if (!x86_apple_machine) return; /* Card may have been put into PCI_D3hot by grub quirk */ diff --git a/arch/x86/kernel/eisa.c b/arch/x86/kernel/eisa.c new file mode 100644 index 0000000000000000000000000000000000000000..f260e452e4f8726237618efe4b9526938d31d81d --- /dev/null +++ b/arch/x86/kernel/eisa.c @@ -0,0 +1,19 @@ +/* + * EISA specific code + * + * This file is licensed under the GPL V2 + */ +#include +#include +#include + +static __init int eisa_bus_probe(void) +{ + void __iomem *p = ioremap(0x0FFFD9, 4); + + if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) + EISA_bus = 1; + iounmap(p); + return 0; +} +subsys_initcall(eisa_bus_probe); diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c index 6b91e2eb8d3f8a5b8ad1a57c7a2a47d0a3b4440d..9c4e7ba6870c142921cfbbd07b8bbf45285e5c07 100644 --- a/arch/x86/kernel/espfix_64.c +++ b/arch/x86/kernel/espfix_64.c @@ -195,7 +195,7 @@ void init_espfix_ap(int cpu) pte_p = pte_offset_kernel(&pmd, addr); stack_page = page_address(alloc_pages_node(node, GFP_KERNEL, 0)); - pte = __pte(__pa(stack_page) | (__PAGE_KERNEL_RO & ptemask)); + pte = __pte(__pa(stack_page) | ((__PAGE_KERNEL_RO | _PAGE_ENC) & ptemask)); for (n = 0; n < ESPFIX_PTE_CLONES; n++) set_pte(&pte_p[n*PTE_STRIDE], pte); diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index e1114f070c2dfdedf9911cd587afb7cca1769785..f92a6593de1ec651d244d43d16acbd8d49959e4b 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -100,7 +100,7 @@ void __kernel_fpu_begin(void) kernel_fpu_disable(); - if (fpu->fpregs_active) { + if (fpu->initialized) { /* * Ignore return value -- we don't care if reg state * is clobbered. @@ -116,7 +116,7 @@ void __kernel_fpu_end(void) { struct fpu *fpu = ¤t->thread.fpu; - if (fpu->fpregs_active) + if (fpu->initialized) copy_kernel_to_fpregs(&fpu->state); kernel_fpu_enable(); @@ -148,7 +148,7 @@ void fpu__save(struct fpu *fpu) preempt_disable(); trace_x86_fpu_before_save(fpu); - if (fpu->fpregs_active) { + if (fpu->initialized) { if (!copy_fpregs_to_fpstate(fpu)) { copy_kernel_to_fpregs(&fpu->state); } @@ -189,10 +189,9 @@ EXPORT_SYMBOL_GPL(fpstate_init); int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) { - dst_fpu->fpregs_active = 0; dst_fpu->last_cpu = -1; - if (!src_fpu->fpstate_active || !static_cpu_has(X86_FEATURE_FPU)) + if (!src_fpu->initialized || !static_cpu_has(X86_FEATURE_FPU)) return 0; WARN_ON_FPU(src_fpu != ¤t->thread.fpu); @@ -206,26 +205,14 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) /* * Save current FPU registers directly into the child * FPU context, without any memory-to-memory copying. - * In lazy mode, if the FPU context isn't loaded into - * fpregs, CR0.TS will be set and do_device_not_available - * will load the FPU context. * - * We have to do all this with preemption disabled, - * mostly because of the FNSAVE case, because in that - * case we must not allow preemption in the window - * between the FNSAVE and us marking the context lazy. - * - * It shouldn't be an issue as even FNSAVE is plenty - * fast in terms of critical section length. + * ( The function 'fails' in the FNSAVE case, which destroys + * register contents so we have to copy them back. ) */ - preempt_disable(); if (!copy_fpregs_to_fpstate(dst_fpu)) { - memcpy(&src_fpu->state, &dst_fpu->state, - fpu_kernel_xstate_size); - + memcpy(&src_fpu->state, &dst_fpu->state, fpu_kernel_xstate_size); copy_kernel_to_fpregs(&src_fpu->state); } - preempt_enable(); trace_x86_fpu_copy_src(src_fpu); trace_x86_fpu_copy_dst(dst_fpu); @@ -237,45 +224,48 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) * Activate the current task's in-memory FPU context, * if it has not been used before: */ -void fpu__activate_curr(struct fpu *fpu) +void fpu__initialize(struct fpu *fpu) { WARN_ON_FPU(fpu != ¤t->thread.fpu); - if (!fpu->fpstate_active) { + if (!fpu->initialized) { fpstate_init(&fpu->state); trace_x86_fpu_init_state(fpu); trace_x86_fpu_activate_state(fpu); /* Safe to do for the current task: */ - fpu->fpstate_active = 1; + fpu->initialized = 1; } } -EXPORT_SYMBOL_GPL(fpu__activate_curr); +EXPORT_SYMBOL_GPL(fpu__initialize); /* * This function must be called before we read a task's fpstate. * - * If the task has not used the FPU before then initialize its - * fpstate. + * There's two cases where this gets called: + * + * - for the current task (when coredumping), in which case we have + * to save the latest FPU registers into the fpstate, + * + * - or it's called for stopped tasks (ptrace), in which case the + * registers were already saved by the context-switch code when + * the task scheduled out - we only have to initialize the registers + * if they've never been initialized. * * If the task has used the FPU before then save it. */ -void fpu__activate_fpstate_read(struct fpu *fpu) +void fpu__prepare_read(struct fpu *fpu) { - /* - * If fpregs are active (in the current CPU), then - * copy them to the fpstate: - */ - if (fpu->fpregs_active) { + if (fpu == ¤t->thread.fpu) { fpu__save(fpu); } else { - if (!fpu->fpstate_active) { + if (!fpu->initialized) { fpstate_init(&fpu->state); trace_x86_fpu_init_state(fpu); trace_x86_fpu_activate_state(fpu); /* Safe to do for current and for stopped child tasks: */ - fpu->fpstate_active = 1; + fpu->initialized = 1; } } } @@ -283,17 +273,17 @@ void fpu__activate_fpstate_read(struct fpu *fpu) /* * This function must be called before we write a task's fpstate. * - * If the task has used the FPU before then unlazy it. + * If the task has used the FPU before then invalidate any cached FPU registers. * If the task has not used the FPU before then initialize its fpstate. * * After this function call, after registers in the fpstate are * modified and the child task has woken up, the child task will * restore the modified FPU state from the modified context. If we - * didn't clear its lazy status here then the lazy in-registers + * didn't clear its cached status here then the cached in-registers * state pending on its former CPU could be restored, corrupting * the modifications. */ -void fpu__activate_fpstate_write(struct fpu *fpu) +void fpu__prepare_write(struct fpu *fpu) { /* * Only stopped child tasks can be used to modify the FPU @@ -301,8 +291,8 @@ void fpu__activate_fpstate_write(struct fpu *fpu) */ WARN_ON_FPU(fpu == ¤t->thread.fpu); - if (fpu->fpstate_active) { - /* Invalidate any lazy state: */ + if (fpu->initialized) { + /* Invalidate any cached state: */ __fpu_invalidate_fpregs_state(fpu); } else { fpstate_init(&fpu->state); @@ -310,73 +300,10 @@ void fpu__activate_fpstate_write(struct fpu *fpu) trace_x86_fpu_activate_state(fpu); /* Safe to do for stopped child tasks: */ - fpu->fpstate_active = 1; + fpu->initialized = 1; } } -/* - * This function must be called before we write the current - * task's fpstate. - * - * This call gets the current FPU register state and moves - * it in to the 'fpstate'. Preemption is disabled so that - * no writes to the 'fpstate' can occur from context - * swiches. - * - * Must be followed by a fpu__current_fpstate_write_end(). - */ -void fpu__current_fpstate_write_begin(void) -{ - struct fpu *fpu = ¤t->thread.fpu; - - /* - * Ensure that the context-switching code does not write - * over the fpstate while we are doing our update. - */ - preempt_disable(); - - /* - * Move the fpregs in to the fpu's 'fpstate'. - */ - fpu__activate_fpstate_read(fpu); - - /* - * The caller is about to write to 'fpu'. Ensure that no - * CPU thinks that its fpregs match the fpstate. This - * ensures we will not be lazy and skip a XRSTOR in the - * future. - */ - __fpu_invalidate_fpregs_state(fpu); -} - -/* - * This function must be paired with fpu__current_fpstate_write_begin() - * - * This will ensure that the modified fpstate gets placed back in - * the fpregs if necessary. - * - * Note: This function may be called whether or not an _actual_ - * write to the fpstate occurred. - */ -void fpu__current_fpstate_write_end(void) -{ - struct fpu *fpu = ¤t->thread.fpu; - - /* - * 'fpu' now has an updated copy of the state, but the - * registers may still be out of date. Update them with - * an XRSTOR if they are active. - */ - if (fpregs_active()) - copy_kernel_to_fpregs(&fpu->state); - - /* - * Our update is done and the fpregs/fpstate are in sync - * if necessary. Context switches can happen again. - */ - preempt_enable(); -} - /* * 'fpu__restore()' is called to copy FPU registers from * the FPU fpstate to the live hw registers and to activate @@ -389,7 +316,7 @@ void fpu__current_fpstate_write_end(void) */ void fpu__restore(struct fpu *fpu) { - fpu__activate_curr(fpu); + fpu__initialize(fpu); /* Avoid __kernel_fpu_begin() right after fpregs_activate() */ kernel_fpu_disable(); @@ -414,15 +341,17 @@ void fpu__drop(struct fpu *fpu) { preempt_disable(); - if (fpu->fpregs_active) { - /* Ignore delayed exceptions from user space */ - asm volatile("1: fwait\n" - "2:\n" - _ASM_EXTABLE(1b, 2b)); - fpregs_deactivate(fpu); + if (fpu == ¤t->thread.fpu) { + if (fpu->initialized) { + /* Ignore delayed exceptions from user space */ + asm volatile("1: fwait\n" + "2:\n" + _ASM_EXTABLE(1b, 2b)); + fpregs_deactivate(fpu); + } } - fpu->fpstate_active = 0; + fpu->initialized = 0; trace_x86_fpu_dropped(fpu); @@ -462,9 +391,11 @@ void fpu__clear(struct fpu *fpu) * Make sure fpstate is cleared and initialized. */ if (static_cpu_has(X86_FEATURE_FPU)) { - fpu__activate_curr(fpu); + preempt_disable(); + fpu__initialize(fpu); user_fpu_begin(); copy_init_fpstate_to_fpregs(); + preempt_enable(); } } diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index d5d44c452624c88e3abb5c75e68d00b55fee6019..7affb7e3d9a5b94326b51528119787f4f956640b 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -240,7 +240,7 @@ static void __init fpu__init_system_ctx_switch(void) WARN_ON_FPU(!on_boot_cpu); on_boot_cpu = 0; - WARN_ON_FPU(current->thread.fpu.fpstate_active); + WARN_ON_FPU(current->thread.fpu.initialized); } /* diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index b188b16841e376574c5f39e55b7b687ffdd09495..3ea15137238964cc6f972b2d11c83cb619de55bd 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -16,14 +16,14 @@ int regset_fpregs_active(struct task_struct *target, const struct user_regset *r { struct fpu *target_fpu = &target->thread.fpu; - return target_fpu->fpstate_active ? regset->n : 0; + return target_fpu->initialized ? regset->n : 0; } int regset_xregset_fpregs_active(struct task_struct *target, const struct user_regset *regset) { struct fpu *target_fpu = &target->thread.fpu; - if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->fpstate_active) + if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->initialized) return regset->n; else return 0; @@ -38,7 +38,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, if (!boot_cpu_has(X86_FEATURE_FXSR)) return -ENODEV; - fpu__activate_fpstate_read(fpu); + fpu__prepare_read(fpu); fpstate_sanitize_xstate(fpu); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, @@ -55,7 +55,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, if (!boot_cpu_has(X86_FEATURE_FXSR)) return -ENODEV; - fpu__activate_fpstate_write(fpu); + fpu__prepare_write(fpu); fpstate_sanitize_xstate(fpu); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, @@ -89,10 +89,13 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset, xsave = &fpu->state.xsave; - fpu__activate_fpstate_read(fpu); + fpu__prepare_read(fpu); if (using_compacted_format()) { - ret = copyout_from_xsaves(pos, count, kbuf, ubuf, xsave); + if (kbuf) + ret = copy_xstate_to_kernel(kbuf, xsave, pos, count); + else + ret = copy_xstate_to_user(ubuf, xsave, pos, count); } else { fpstate_sanitize_xstate(fpu); /* @@ -129,28 +132,29 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, xsave = &fpu->state.xsave; - fpu__activate_fpstate_write(fpu); + fpu__prepare_write(fpu); - if (boot_cpu_has(X86_FEATURE_XSAVES)) - ret = copyin_to_xsaves(kbuf, ubuf, xsave); - else + if (using_compacted_format()) { + if (kbuf) + ret = copy_kernel_to_xstate(xsave, kbuf); + else + ret = copy_user_to_xstate(xsave, ubuf); + } else { ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); - - /* - * In case of failure, mark all states as init: - */ - if (ret) - fpstate_init(&fpu->state); + if (!ret) + ret = validate_xstate_header(&xsave->header); + } /* * mxcsr reserved bits must be masked to zero for security reasons. */ xsave->i387.mxcsr &= mxcsr_feature_mask; - xsave->header.xfeatures &= xfeatures_mask; + /* - * These bits must be zero. + * In case of failure, mark all states as init: */ - memset(&xsave->header.reserved, 0, 48); + if (ret) + fpstate_init(&fpu->state); return ret; } @@ -299,7 +303,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, struct fpu *fpu = &target->thread.fpu; struct user_i387_ia32_struct env; - fpu__activate_fpstate_read(fpu); + fpu__prepare_read(fpu); if (!boot_cpu_has(X86_FEATURE_FPU)) return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); @@ -329,7 +333,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, struct user_i387_ia32_struct env; int ret; - fpu__activate_fpstate_write(fpu); + fpu__prepare_write(fpu); fpstate_sanitize_xstate(fpu); if (!boot_cpu_has(X86_FEATURE_FPU)) @@ -369,7 +373,7 @@ int dump_fpu(struct pt_regs *regs, struct user_i387_struct *ufpu) struct fpu *fpu = &tsk->thread.fpu; int fpvalid; - fpvalid = fpu->fpstate_active; + fpvalid = fpu->initialized; if (fpvalid) fpvalid = !fpregs_get(tsk, NULL, 0, sizeof(struct user_i387_ia32_struct), diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 83c23c230b4c4fc78664ba08663a04c684c2105b..fb639e70048f58dfaef5576ab73e6998fa8ebbd1 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -155,7 +155,8 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) */ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) { - struct xregs_state *xsave = ¤t->thread.fpu.state.xsave; + struct fpu *fpu = ¤t->thread.fpu; + struct xregs_state *xsave = &fpu->state.xsave; struct task_struct *tsk = current; int ia32_fxstate = (buf != buf_fx); @@ -170,13 +171,13 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) sizeof(struct user_i387_ia32_struct), NULL, (struct _fpstate_32 __user *) buf) ? -1 : 1; - if (fpregs_active() || using_compacted_format()) { + if (fpu->initialized || using_compacted_format()) { /* Save the live register state to the user directly. */ if (copy_fpregs_to_sigframe(buf_fx)) return -1; /* Update the thread's fxstate to save the fsave header. */ if (ia32_fxstate) - copy_fxregs_to_kernel(&tsk->thread.fpu); + copy_fxregs_to_kernel(fpu); } else { /* * It is a *bug* if kernel uses compacted-format for xsave @@ -189,7 +190,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) return -1; } - fpstate_sanitize_xstate(&tsk->thread.fpu); + fpstate_sanitize_xstate(fpu); if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size)) return -1; } @@ -213,8 +214,11 @@ sanitize_restored_xstate(struct task_struct *tsk, struct xstate_header *header = &xsave->header; if (use_xsave()) { - /* These bits must be zero. */ - memset(header->reserved, 0, 48); + /* + * Note: we don't need to zero the reserved bits in the + * xstate_header here because we either didn't copy them at all, + * or we checked earlier that they aren't set. + */ /* * Init the state that is not present in the memory @@ -223,7 +227,7 @@ sanitize_restored_xstate(struct task_struct *tsk, if (fx_only) header->xfeatures = XFEATURE_MASK_FPSSE; else - header->xfeatures &= (xfeatures_mask & xfeatures); + header->xfeatures &= xfeatures; } if (use_fxsr()) { @@ -279,7 +283,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) if (!access_ok(VERIFY_READ, buf, size)) return -EACCES; - fpu__activate_curr(fpu); + fpu__initialize(fpu); if (!static_cpu_has(X86_FEATURE_FPU)) return fpregs_soft_set(current, NULL, @@ -307,28 +311,29 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) /* * For 32-bit frames with fxstate, copy the user state to the * thread's fpu state, reconstruct fxstate from the fsave - * header. Sanitize the copied state etc. + * header. Validate and sanitize the copied state. */ struct fpu *fpu = &tsk->thread.fpu; struct user_i387_ia32_struct env; int err = 0; /* - * Drop the current fpu which clears fpu->fpstate_active. This ensures + * Drop the current fpu which clears fpu->initialized. This ensures * that any context-switch during the copy of the new state, * avoids the intermediate state from getting restored/saved. * Thus avoiding the new restored state from getting corrupted. * We will be ready to restore/save the state only after - * fpu->fpstate_active is again set. + * fpu->initialized is again set. */ fpu__drop(fpu); if (using_compacted_format()) { - err = copyin_to_xsaves(NULL, buf_fx, - &fpu->state.xsave); + err = copy_user_to_xstate(&fpu->state.xsave, buf_fx); } else { - err = __copy_from_user(&fpu->state.xsave, - buf_fx, state_size); + err = __copy_from_user(&fpu->state.xsave, buf_fx, state_size); + + if (!err && state_size > offsetof(struct xregs_state, header)) + err = validate_xstate_header(&fpu->state.xsave.header); } if (err || __copy_from_user(&env, buf, sizeof(env))) { @@ -339,7 +344,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) sanitize_restored_xstate(tsk, &env, xfeatures, fx_only); } - fpu->fpstate_active = 1; + fpu->initialized = 1; preempt_disable(); fpu__restore(fpu); preempt_enable(); diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index c24ac1efb12d7a1574450a1359699309148afcd6..f1d5476c902209eebeae83d3cd30fe5b6226921c 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -483,6 +483,30 @@ int using_compacted_format(void) return boot_cpu_has(X86_FEATURE_XSAVES); } +/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ +int validate_xstate_header(const struct xstate_header *hdr) +{ + /* No unknown or supervisor features may be set */ + if (hdr->xfeatures & (~xfeatures_mask | XFEATURE_MASK_SUPERVISOR)) + return -EINVAL; + + /* Userspace must use the uncompacted format */ + if (hdr->xcomp_bv) + return -EINVAL; + + /* + * If 'reserved' is shrunken to add a new field, make sure to validate + * that new field here! + */ + BUILD_BUG_ON(sizeof(hdr->reserved) != 48); + + /* No reserved bits may be set */ + if (memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved))) + return -EINVAL; + + return 0; +} + static void __xstate_dump_leaves(void) { int i; @@ -867,7 +891,7 @@ const void *get_xsave_field_ptr(int xsave_state) { struct fpu *fpu = ¤t->thread.fpu; - if (!fpu->fpstate_active) + if (!fpu->initialized) return NULL; /* * fpu__save() takes the CPU's xstate registers @@ -920,39 +944,130 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, } #endif /* ! CONFIG_ARCH_HAS_PKEYS */ +/* + * Weird legacy quirk: SSE and YMM states store information in the + * MXCSR and MXCSR_FLAGS fields of the FP area. That means if the FP + * area is marked as unused in the xfeatures header, we need to copy + * MXCSR and MXCSR_FLAGS if either SSE or YMM are in use. + */ +static inline bool xfeatures_mxcsr_quirk(u64 xfeatures) +{ + if (!(xfeatures & (XFEATURE_MASK_SSE|XFEATURE_MASK_YMM))) + return false; + + if (xfeatures & XFEATURE_MASK_FP) + return false; + + return true; +} + /* * This is similar to user_regset_copyout(), but will not add offset to * the source data pointer or increment pos, count, kbuf, and ubuf. */ -static inline int xstate_copyout(unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf, - const void *data, const int start_pos, - const int end_pos) +static inline void +__copy_xstate_to_kernel(void *kbuf, const void *data, + unsigned int offset, unsigned int size, unsigned int size_total) { - if ((count == 0) || (pos < start_pos)) - return 0; + if (offset < size_total) { + unsigned int copy = min(size, size_total - offset); - if (end_pos < 0 || pos < end_pos) { - unsigned int copy = (end_pos < 0 ? count : min(count, end_pos - pos)); + memcpy(kbuf + offset, data, copy); + } +} - if (kbuf) { - memcpy(kbuf + pos, data, copy); - } else { - if (__copy_to_user(ubuf + pos, data, copy)) - return -EFAULT; +/* + * Convert from kernel XSAVES compacted format to standard format and copy + * to a kernel-space ptrace buffer. + * + * It supports partial copy but pos always starts from zero. This is called + * from xstateregs_get() and there we check the CPU has XSAVES. + */ +int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) +{ + unsigned int offset, size; + struct xstate_header header; + int i; + + /* + * Currently copy_regset_to_user() starts from pos 0: + */ + if (unlikely(offset_start != 0)) + return -EFAULT; + + /* + * The destination is a ptrace buffer; we put in only user xstates: + */ + memset(&header, 0, sizeof(header)); + header.xfeatures = xsave->header.xfeatures; + header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; + + /* + * Copy xregs_state->header: + */ + offset = offsetof(struct xregs_state, header); + size = sizeof(header); + + __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total); + + for (i = 0; i < XFEATURE_MAX; i++) { + /* + * Copy only in-use xstates: + */ + if ((header.xfeatures >> i) & 1) { + void *src = __raw_xsave_addr(xsave, 1 << i); + + offset = xstate_offsets[i]; + size = xstate_sizes[i]; + + /* The next component has to fit fully into the output buffer: */ + if (offset + size > size_total) + break; + + __copy_xstate_to_kernel(kbuf, src, offset, size, size_total); } + + } + + if (xfeatures_mxcsr_quirk(header.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + __copy_xstate_to_kernel(kbuf, &xsave->i387.mxcsr, offset, size, size_total); + } + + /* + * Fill xsave->i387.sw_reserved value for ptrace frame: + */ + offset = offsetof(struct fxregs_state, sw_reserved); + size = sizeof(xstate_fx_sw_bytes); + + __copy_xstate_to_kernel(kbuf, xstate_fx_sw_bytes, offset, size, size_total); + + return 0; +} + +static inline int +__copy_xstate_to_user(void __user *ubuf, const void *data, unsigned int offset, unsigned int size, unsigned int size_total) +{ + if (!size) + return 0; + + if (offset < size_total) { + unsigned int copy = min(size, size_total - offset); + + if (__copy_to_user(ubuf + offset, data, copy)) + return -EFAULT; } return 0; } /* * Convert from kernel XSAVES compacted format to standard format and copy - * to a ptrace buffer. It supports partial copy but pos always starts from + * to a user-space buffer. It supports partial copy but pos always starts from * zero. This is called from xstateregs_get() and there we check the CPU * has XSAVES. */ -int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, - void __user *ubuf, struct xregs_state *xsave) +int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) { unsigned int offset, size; int ret, i; @@ -961,7 +1076,7 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, /* * Currently copy_regset_to_user() starts from pos 0: */ - if (unlikely(pos != 0)) + if (unlikely(offset_start != 0)) return -EFAULT; /* @@ -977,8 +1092,7 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, offset = offsetof(struct xregs_state, header); size = sizeof(header); - ret = xstate_copyout(offset, size, kbuf, ubuf, &header, 0, count); - + ret = __copy_xstate_to_user(ubuf, &header, offset, size, size_total); if (ret) return ret; @@ -992,25 +1106,30 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, offset = xstate_offsets[i]; size = xstate_sizes[i]; - ret = xstate_copyout(offset, size, kbuf, ubuf, src, 0, count); + /* The next component has to fit fully into the output buffer: */ + if (offset + size > size_total) + break; + ret = __copy_xstate_to_user(ubuf, src, offset, size, size_total); if (ret) return ret; - - if (offset + size >= count) - break; } } + if (xfeatures_mxcsr_quirk(header.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + __copy_xstate_to_user(ubuf, &xsave->i387.mxcsr, offset, size, size_total); + } + /* * Fill xsave->i387.sw_reserved value for ptrace frame: */ offset = offsetof(struct fxregs_state, sw_reserved); size = sizeof(xstate_fx_sw_bytes); - ret = xstate_copyout(offset, size, kbuf, ubuf, xstate_fx_sw_bytes, 0, count); - + ret = __copy_xstate_to_user(ubuf, xstate_fx_sw_bytes, offset, size, size_total); if (ret) return ret; @@ -1018,55 +1137,98 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, } /* - * Convert from a ptrace standard-format buffer to kernel XSAVES format - * and copy to the target thread. This is called from xstateregs_set() and - * there we check the CPU has XSAVES and a whole standard-sized buffer - * exists. + * Convert from a ptrace standard-format kernel buffer to kernel XSAVES format + * and copy to the target thread. This is called from xstateregs_set(). */ -int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, - struct xregs_state *xsave) +int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) { unsigned int offset, size; int i; - u64 xfeatures; - u64 allowed_features; + struct xstate_header hdr; offset = offsetof(struct xregs_state, header); - size = sizeof(xfeatures); + size = sizeof(hdr); - if (kbuf) { - memcpy(&xfeatures, kbuf + offset, size); - } else { - if (__copy_from_user(&xfeatures, ubuf + offset, size)) - return -EFAULT; + memcpy(&hdr, kbuf + offset, size); + + if (validate_xstate_header(&hdr)) + return -EINVAL; + + for (i = 0; i < XFEATURE_MAX; i++) { + u64 mask = ((u64)1 << i); + + if (hdr.xfeatures & mask) { + void *dst = __raw_xsave_addr(xsave, 1 << i); + + offset = xstate_offsets[i]; + size = xstate_sizes[i]; + + memcpy(dst, kbuf + offset, size); + } + } + + if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + memcpy(&xsave->i387.mxcsr, kbuf + offset, size); } /* - * Reject if the user sets any disabled or supervisor features: + * The state that came in from userspace was user-state only. + * Mask all the user states out of 'xfeatures': + */ + xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; + + /* + * Add back in the features that came in from userspace: */ - allowed_features = xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR; + xsave->header.xfeatures |= hdr.xfeatures; - if (xfeatures & ~allowed_features) + return 0; +} + +/* + * Convert from a ptrace or sigreturn standard-format user-space buffer to + * kernel XSAVES format and copy to the target thread. This is called from + * xstateregs_set(), as well as potentially from the sigreturn() and + * rt_sigreturn() system calls. + */ +int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) +{ + unsigned int offset, size; + int i; + struct xstate_header hdr; + + offset = offsetof(struct xregs_state, header); + size = sizeof(hdr); + + if (__copy_from_user(&hdr, ubuf + offset, size)) + return -EFAULT; + + if (validate_xstate_header(&hdr)) return -EINVAL; for (i = 0; i < XFEATURE_MAX; i++) { u64 mask = ((u64)1 << i); - if (xfeatures & mask) { + if (hdr.xfeatures & mask) { void *dst = __raw_xsave_addr(xsave, 1 << i); offset = xstate_offsets[i]; size = xstate_sizes[i]; - if (kbuf) { - memcpy(dst, kbuf + offset, size); - } else { - if (__copy_from_user(dst, ubuf + offset, size)) - return -EFAULT; - } + if (__copy_from_user(dst, ubuf + offset, size)) + return -EFAULT; } } + if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + if (__copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size)) + return -EFAULT; + } + /* * The state that came in from userspace was user-state only. * Mask all the user states out of 'xfeatures': @@ -1076,7 +1238,7 @@ int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, /* * Add back in the features that came in from userspace: */ - xsave->header.xfeatures |= xfeatures; + xsave->header.xfeatures |= hdr.xfeatures; return 0; } diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 538ec012b3717c6c73f2deb45423322cecc649d5..cf2ce063f65aff6166d51aa74e56d1ebdd22bb41 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,9 @@ static void __init i386_default_early_setup(void) asmlinkage __visible void __init i386_start_kernel(void) { cr4_init_shadow(); + + idt_setup_early_handler(); + sanitize_boot_params(&boot_params); x86_early_init_platform_quirks(); diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 46c3c73e7f43f5fbb56fe0028d8aafb64a3f8a9e..bab4fa579450cd5192a60366993a168493789fb4 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -33,7 +34,6 @@ /* * Manage page tables very early on. */ -extern pgd_t early_top_pgt[PTRS_PER_PGD]; extern pmd_t early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD]; static unsigned int __initdata next_early_pgt; pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); @@ -45,14 +45,17 @@ static void __head *fixup_pointer(void *ptr, unsigned long physaddr) return ptr - (void *)_text + (void *)physaddr; } -void __head __startup_64(unsigned long physaddr) +unsigned long __head __startup_64(unsigned long physaddr, + struct boot_params *bp) { unsigned long load_delta, *p; + unsigned long pgtable_flags; pgdval_t *pgd; p4dval_t *p4d; pudval_t *pud; pmdval_t *pmd, pmd_entry; int i; + unsigned int *next_pgt_ptr; /* Is the address too large? */ if (physaddr >> MAX_PHYSMEM_BITS) @@ -68,6 +71,12 @@ void __head __startup_64(unsigned long physaddr) if (load_delta & ~PMD_PAGE_MASK) for (;;); + /* Activate Secure Memory Encryption (SME) if supported and enabled */ + sme_enable(bp); + + /* Include the SME encryption mask in the fixup value */ + load_delta += sme_get_me_mask(); + /* Fixup the physical addresses in the page table */ pgd = fixup_pointer(&early_top_pgt, physaddr); @@ -92,30 +101,34 @@ void __head __startup_64(unsigned long physaddr) * it avoids problems around wraparound. */ - pud = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr); - pmd = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr); + next_pgt_ptr = fixup_pointer(&next_early_pgt, physaddr); + pud = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr); + pmd = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr); + + pgtable_flags = _KERNPG_TABLE_NOENC + sme_get_me_mask(); if (IS_ENABLED(CONFIG_X86_5LEVEL)) { p4d = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr); i = (physaddr >> PGDIR_SHIFT) % PTRS_PER_PGD; - pgd[i + 0] = (pgdval_t)p4d + _KERNPG_TABLE; - pgd[i + 1] = (pgdval_t)p4d + _KERNPG_TABLE; + pgd[i + 0] = (pgdval_t)p4d + pgtable_flags; + pgd[i + 1] = (pgdval_t)p4d + pgtable_flags; i = (physaddr >> P4D_SHIFT) % PTRS_PER_P4D; - p4d[i + 0] = (pgdval_t)pud + _KERNPG_TABLE; - p4d[i + 1] = (pgdval_t)pud + _KERNPG_TABLE; + p4d[i + 0] = (pgdval_t)pud + pgtable_flags; + p4d[i + 1] = (pgdval_t)pud + pgtable_flags; } else { i = (physaddr >> PGDIR_SHIFT) % PTRS_PER_PGD; - pgd[i + 0] = (pgdval_t)pud + _KERNPG_TABLE; - pgd[i + 1] = (pgdval_t)pud + _KERNPG_TABLE; + pgd[i + 0] = (pgdval_t)pud + pgtable_flags; + pgd[i + 1] = (pgdval_t)pud + pgtable_flags; } i = (physaddr >> PUD_SHIFT) % PTRS_PER_PUD; - pud[i + 0] = (pudval_t)pmd + _KERNPG_TABLE; - pud[i + 1] = (pudval_t)pmd + _KERNPG_TABLE; + pud[i + 0] = (pudval_t)pmd + pgtable_flags; + pud[i + 1] = (pudval_t)pmd + pgtable_flags; pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; + pmd_entry += sme_get_me_mask(); pmd_entry += physaddr; for (i = 0; i < DIV_ROUND_UP(_end - _text, PMD_SIZE); i++) { @@ -136,9 +149,30 @@ void __head __startup_64(unsigned long physaddr) pmd[i] += load_delta; } - /* Fixup phys_base */ + /* + * Fixup phys_base - remove the memory encryption mask to obtain + * the true physical address. + */ p = fixup_pointer(&phys_base, physaddr); - *p += load_delta; + *p += load_delta - sme_get_me_mask(); + + /* Encrypt the kernel (if SME is active) */ + sme_encrypt_kernel(); + + /* + * Return the SME encryption mask (if SME is active) to be used as a + * modifier for the initial pgdir entry programmed into CR3. + */ + return sme_get_me_mask(); +} + +unsigned long __startup_secondary_64(void) +{ + /* + * Return the SME encryption mask (if SME is active) to be used as a + * modifier for the initial pgdir entry programmed into CR3. + */ + return sme_get_me_mask(); } /* Wipe all early page tables except for the kernel symbol map */ @@ -146,17 +180,17 @@ static void __init reset_early_page_tables(void) { memset(early_top_pgt, 0, sizeof(pgd_t)*(PTRS_PER_PGD-1)); next_early_pgt = 0; - write_cr3(__pa_nodebug(early_top_pgt)); + write_cr3(__sme_pa_nodebug(early_top_pgt)); } /* Create a new PMD entry */ -int __init early_make_pgtable(unsigned long address) +int __init __early_make_pgtable(unsigned long address, pmdval_t pmd) { unsigned long physaddr = address - __PAGE_OFFSET; pgdval_t pgd, *pgd_p; p4dval_t p4d, *p4d_p; pudval_t pud, *pud_p; - pmdval_t pmd, *pmd_p; + pmdval_t *pmd_p; /* Invalid address or early pgt is done ? */ if (physaddr >= MAXMEM || read_cr3_pa() != __pa_nodebug(early_top_pgt)) @@ -215,12 +249,21 @@ int __init early_make_pgtable(unsigned long address) memset(pmd_p, 0, sizeof(*pmd_p) * PTRS_PER_PMD); *pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; } - pmd = (physaddr & PMD_MASK) + early_pmd_flags; pmd_p[pmd_index(address)] = pmd; return 0; } +int __init early_make_pgtable(unsigned long address) +{ + unsigned long physaddr = address - __PAGE_OFFSET; + pmdval_t pmd; + + pmd = (physaddr & PMD_MASK) + early_pmd_flags; + + return __early_make_pgtable(address, pmd); +} + /* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ static void __init clear_bss(void) @@ -243,6 +286,12 @@ static void __init copy_bootdata(char *real_mode_data) char * command_line; unsigned long cmd_line_ptr; + /* + * If SME is active, this will create decrypted mappings of the + * boot data in advance of the copy operations. + */ + sme_map_bootdata(real_mode_data); + memcpy(&boot_params, real_mode_data, sizeof boot_params); sanitize_boot_params(&boot_params); cmd_line_ptr = get_cmd_line_ptr(); @@ -250,12 +299,18 @@ static void __init copy_bootdata(char *real_mode_data) command_line = __va(cmd_line_ptr); memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); } + + /* + * The old boot data is no longer needed and won't be reserved, + * freeing up that memory for use by the system. If SME is active, + * we need to remove the mappings that were created so that the + * memory doesn't remain mapped as decrypted. + */ + sme_unmap_bootdata(real_mode_data); } asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) { - int i; - /* * Build-time sanity checks on the kernel image and module * area mappings. (these are purely build-time and produce no code) @@ -279,11 +334,16 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) clear_page(init_top_pgt); + /* + * SME support may update early_pmd_flags to include the memory + * encryption mask, so it needs to be called before anything + * that may generate a page fault. + */ + sme_early_init(); + kasan_early_init(); - for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) - set_intr_gate(i, early_idt_handler_array[i]); - load_idt((const struct desc_ptr *)&idt_descr); + idt_setup_early_handler(); copy_bootdata(__va(real_mode_data)); diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 1f85ee8f9439fff69f6bc7a38523b38f88311cb0..9ed3074d0d2747baf51f9d1e83b388a61d7b8d78 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -155,7 +155,6 @@ ENTRY(startup_32) jmp *%eax .Lbad_subarch: -WEAK(lguest_entry) WEAK(xen_entry) /* Unknown implementation; there's really nothing we can do at this point. */ @@ -165,7 +164,6 @@ WEAK(xen_entry) subarch_entries: .long .Ldefault_entry /* normal x86/PC */ - .long lguest_entry /* lguest hypervisor */ .long xen_entry /* Xen hypervisor */ .long .Ldefault_entry /* Moorestown MID */ num_subarch_entries = (. - subarch_entries) / 4 @@ -347,7 +345,6 @@ ENTRY(startup_32_smp) movl %eax,%cr0 lgdt early_gdt_descr - lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt. @@ -380,37 +377,6 @@ ENDPROC(startup_32_smp) */ __INIT setup_once: - /* - * Set up a idt with 256 interrupt gates that push zero if there - * is no error code and then jump to early_idt_handler_common. - * It doesn't actually load the idt - that needs to be done on - * each CPU. Interrupts are enabled elsewhere, when we can be - * relatively sure everything is ok. - */ - - movl $idt_table,%edi - movl $early_idt_handler_array,%eax - movl $NUM_EXCEPTION_VECTORS,%ecx -1: - movl %eax,(%edi) - movl %eax,4(%edi) - /* interrupt gate, dpl=0, present */ - movl $(0x8E000000 + __KERNEL_CS),2(%edi) - addl $EARLY_IDT_HANDLER_SIZE,%eax - addl $8,%edi - loop 1b - - movl $256 - NUM_EXCEPTION_VECTORS,%ecx - movl $ignore_int,%edx - movl $(__KERNEL_CS << 16),%eax - movw %dx,%ax /* selector = 0x0010 = cs */ - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ -2: - movl %eax,(%edi) - movl %edx,4(%edi) - addl $8,%edi - loop 2b - #ifdef CONFIG_CC_STACKPROTECTOR /* * Configure the stack canary. The linker can't handle this by @@ -457,12 +423,9 @@ early_idt_handler_common: /* The vector number is in pt_regs->gs */ cld - pushl %fs /* pt_regs->fs */ - movw $0, 2(%esp) /* clear high bits (some CPUs leave garbage) */ - pushl %es /* pt_regs->es */ - movw $0, 2(%esp) /* clear high bits (some CPUs leave garbage) */ - pushl %ds /* pt_regs->ds */ - movw $0, 2(%esp) /* clear high bits (some CPUs leave garbage) */ + pushl %fs /* pt_regs->fs (__fsh varies by model) */ + pushl %es /* pt_regs->es (__esh varies by model) */ + pushl %ds /* pt_regs->ds (__dsh varies by model) */ pushl %eax /* pt_regs->ax */ pushl %ebp /* pt_regs->bp */ pushl %edi /* pt_regs->di */ @@ -479,9 +442,8 @@ early_idt_handler_common: /* Load the vector number into EDX */ movl PT_GS(%esp), %edx - /* Load GS into pt_regs->gs and clear high bits */ + /* Load GS into pt_regs->gs (and maybe clobber __gsh) */ movw %gs, PT_GS(%esp) - movw $0, PT_GS+2(%esp) movl %esp, %eax /* args are pt_regs (EAX), trapnr (EDX) */ call early_fixup_exception @@ -493,18 +455,17 @@ early_idt_handler_common: popl %edi /* pt_regs->di */ popl %ebp /* pt_regs->bp */ popl %eax /* pt_regs->ax */ - popl %ds /* pt_regs->ds */ - popl %es /* pt_regs->es */ - popl %fs /* pt_regs->fs */ - popl %gs /* pt_regs->gs */ + popl %ds /* pt_regs->ds (always ignores __dsh) */ + popl %es /* pt_regs->es (always ignores __esh) */ + popl %fs /* pt_regs->fs (always ignores __fsh) */ + popl %gs /* pt_regs->gs (always ignores __gsh) */ decl %ss:early_recursion_flag addl $4, %esp /* pop pt_regs->orig_ax */ iret ENDPROC(early_idt_handler_common) /* This is the default interrupt "handler" :-) */ - ALIGN -ignore_int: +ENTRY(early_ignore_irq) cld #ifdef CONFIG_PRINTK pushl %eax @@ -539,7 +500,8 @@ ignore_int: hlt_loop: hlt jmp hlt_loop -ENDPROC(ignore_int) +ENDPROC(early_ignore_irq) + __INITDATA .align 4 GLOBAL(early_recursion_flag) @@ -628,7 +590,6 @@ int_msg: .data .globl boot_gdt_descr -.globl idt_descr ALIGN # early boot GDT descriptor (must use 1:1 address mapping) @@ -637,11 +598,6 @@ boot_gdt_descr: .word __BOOT_DS+7 .long boot_gdt - __PAGE_OFFSET - .word 0 # 32-bit align idt_desc.address -idt_descr: - .word IDT_ENTRIES*8-1 # idt contains 256 entries - .long idt_table - # boot GDT descriptor (later on used by CPU#0): .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 6225550883dfe1e98bcf35ac5ed870e334b34399..513cbb012eccc51f18ac16f9dac74a33abaa4c16 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -73,12 +73,19 @@ startup_64: /* Sanitize CPU configuration */ call verify_cpu + /* + * Perform pagetable fixups. Additionally, if SME is active, encrypt + * the kernel and retrieve the modifier (SME encryption mask if SME + * is active) to be added to the initial pgdir entry that will be + * programmed into CR3. + */ leaq _text(%rip), %rdi pushq %rsi call __startup_64 popq %rsi - movq $(early_top_pgt - __START_KERNEL_map), %rax + /* Form the CR3 value being sure to include the CR3 modifier */ + addq $(early_top_pgt - __START_KERNEL_map), %rax jmp 1f ENTRY(secondary_startup_64) /* @@ -98,7 +105,16 @@ ENTRY(secondary_startup_64) /* Sanitize CPU configuration */ call verify_cpu - movq $(init_top_pgt - __START_KERNEL_map), %rax + /* + * Retrieve the modifier (SME encryption mask if SME is active) to be + * added to the initial pgdir entry that will be programmed into CR3. + */ + pushq %rsi + call __startup_secondary_64 + popq %rsi + + /* Form the CR3 value being sure to include the CR3 modifier */ + addq $(init_top_pgt - __START_KERNEL_map), %rax 1: /* Enable PAE mode, PGE and LA57 */ @@ -335,9 +351,9 @@ GLOBAL(name) NEXT_PAGE(early_top_pgt) .fill 511,8,0 #ifdef CONFIG_X86_5LEVEL - .quad level4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC #else - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC #endif NEXT_PAGE(early_dynamic_pgts) @@ -350,15 +366,15 @@ NEXT_PAGE(init_top_pgt) .fill 512,8,0 #else NEXT_PAGE(init_top_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC .org init_top_pgt + PGD_PAGE_OFFSET*8, 0 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC .org init_top_pgt + PGD_START_KERNEL*8, 0 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC NEXT_PAGE(level3_ident_pgt) - .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC .fill 511, 8, 0 NEXT_PAGE(level2_ident_pgt) /* Since I easily can, map the first 1G. @@ -370,14 +386,14 @@ NEXT_PAGE(level2_ident_pgt) #ifdef CONFIG_X86_5LEVEL NEXT_PAGE(level4_kernel_pgt) .fill 511,8,0 - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC #endif NEXT_PAGE(level3_kernel_pgt) .fill L3_START_KERNEL,8,0 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ - .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE - .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC + .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC NEXT_PAGE(level2_kernel_pgt) /* @@ -395,7 +411,7 @@ NEXT_PAGE(level2_kernel_pgt) NEXT_PAGE(level2_fixmap_pgt) .fill 506,8,0 - .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */ .fill 5,8,0 diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 16f82a3aaec7c9c8d85e7c8b4f805da396981fce..8ce4212e2b8d0f139e543e05e7e284ee25ee856d 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -345,21 +345,10 @@ static int hpet_shutdown(struct clock_event_device *evt, int timer) return 0; } -static int hpet_resume(struct clock_event_device *evt, int timer) -{ - if (!timer) { - hpet_enable_legacy_int(); - } else { - struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt); - - irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq)); - irq_domain_activate_irq(irq_get_irq_data(hdev->irq)); - disable_hardirq(hdev->irq); - irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu)); - enable_irq(hdev->irq); - } +static int hpet_resume(struct clock_event_device *evt) +{ + hpet_enable_legacy_int(); hpet_print_config(); - return 0; } @@ -417,7 +406,7 @@ static int hpet_legacy_set_periodic(struct clock_event_device *evt) static int hpet_legacy_resume(struct clock_event_device *evt) { - return hpet_resume(evt, 0); + return hpet_resume(evt); } static int hpet_legacy_next_event(unsigned long delta, @@ -510,8 +499,14 @@ static int hpet_msi_set_periodic(struct clock_event_device *evt) static int hpet_msi_resume(struct clock_event_device *evt) { struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt); + struct irq_data *data = irq_get_irq_data(hdev->irq); + struct msi_msg msg; - return hpet_resume(evt, hdev->num); + /* Restore the MSI msg and unmask the interrupt */ + irq_chip_compose_msi_msg(data, &msg); + hpet_msi_write(hdev, &msg); + hpet_msi_unmask(data); + return 0; } static int hpet_msi_next_event(unsigned long delta, diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c new file mode 100644 index 0000000000000000000000000000000000000000..6107ee1cb8d56762ab76b0e076b52c3f838b1698 --- /dev/null +++ b/arch/x86/kernel/idt.c @@ -0,0 +1,371 @@ +/* + * Interrupt descriptor table related code + * + * This file is licensed under the GPL V2 + */ +#include + +#include +#include +#include + +struct idt_data { + unsigned int vector; + unsigned int segment; + struct idt_bits bits; + const void *addr; +}; + +#define DPL0 0x0 +#define DPL3 0x3 + +#define DEFAULT_STACK 0 + +#define G(_vector, _addr, _ist, _type, _dpl, _segment) \ + { \ + .vector = _vector, \ + .bits.ist = _ist, \ + .bits.type = _type, \ + .bits.dpl = _dpl, \ + .bits.p = 1, \ + .addr = _addr, \ + .segment = _segment, \ + } + +/* Interrupt gate */ +#define INTG(_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* System interrupt gate */ +#define SYSG(_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) + +/* Interrupt gate with interrupt stack */ +#define ISTG(_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* System interrupt gate with interrupt stack */ +#define SISTG(_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) + +/* Task gate */ +#define TSKG(_vector, _gdt) \ + G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) + +/* + * Early traps running on the DEFAULT_STACK because the other interrupt + * stacks work only after cpu_init(). + */ +static const __initdata struct idt_data early_idts[] = { + INTG(X86_TRAP_DB, debug), + SYSG(X86_TRAP_BP, int3), +#ifdef CONFIG_X86_32 + INTG(X86_TRAP_PF, page_fault), +#endif +}; + +/* + * The default IDT entries which are set up in trap_init() before + * cpu_init() is invoked. Interrupt stacks cannot be used at that point and + * the traps which use them are reinitialized with IST after cpu_init() has + * set up TSS. + */ +static const __initdata struct idt_data def_idts[] = { + INTG(X86_TRAP_DE, divide_error), + INTG(X86_TRAP_NMI, nmi), + INTG(X86_TRAP_BR, bounds), + INTG(X86_TRAP_UD, invalid_op), + INTG(X86_TRAP_NM, device_not_available), + INTG(X86_TRAP_OLD_MF, coprocessor_segment_overrun), + INTG(X86_TRAP_TS, invalid_TSS), + INTG(X86_TRAP_NP, segment_not_present), + INTG(X86_TRAP_SS, stack_segment), + INTG(X86_TRAP_GP, general_protection), + INTG(X86_TRAP_SPURIOUS, spurious_interrupt_bug), + INTG(X86_TRAP_MF, coprocessor_error), + INTG(X86_TRAP_AC, alignment_check), + INTG(X86_TRAP_XF, simd_coprocessor_error), + +#ifdef CONFIG_X86_32 + TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS), +#else + INTG(X86_TRAP_DF, double_fault), +#endif + INTG(X86_TRAP_DB, debug), + INTG(X86_TRAP_NMI, nmi), + INTG(X86_TRAP_BP, int3), + +#ifdef CONFIG_X86_MCE + INTG(X86_TRAP_MC, &machine_check), +#endif + + SYSG(X86_TRAP_OF, overflow), +#if defined(CONFIG_IA32_EMULATION) + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), +#elif defined(CONFIG_X86_32) + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), +#endif +}; + +/* + * The APIC and SMP idt entries + */ +static const __initdata struct idt_data apic_idts[] = { +#ifdef CONFIG_SMP + INTG(RESCHEDULE_VECTOR, reschedule_interrupt), + INTG(CALL_FUNCTION_VECTOR, call_function_interrupt), + INTG(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt), + INTG(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt), + INTG(REBOOT_VECTOR, reboot_interrupt), +#endif + +#ifdef CONFIG_X86_THERMAL_VECTOR + INTG(THERMAL_APIC_VECTOR, thermal_interrupt), +#endif + +#ifdef CONFIG_X86_MCE_THRESHOLD + INTG(THRESHOLD_APIC_VECTOR, threshold_interrupt), +#endif + +#ifdef CONFIG_X86_MCE_AMD + INTG(DEFERRED_ERROR_VECTOR, deferred_error_interrupt), +#endif + +#ifdef CONFIG_X86_LOCAL_APIC + INTG(LOCAL_TIMER_VECTOR, apic_timer_interrupt), + INTG(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi), +# ifdef CONFIG_HAVE_KVM + INTG(POSTED_INTR_VECTOR, kvm_posted_intr_ipi), + INTG(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi), + INTG(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi), +# endif +# ifdef CONFIG_IRQ_WORK + INTG(IRQ_WORK_VECTOR, irq_work_interrupt), +# endif + INTG(SPURIOUS_APIC_VECTOR, spurious_interrupt), + INTG(ERROR_APIC_VECTOR, error_interrupt), +#endif +}; + +#ifdef CONFIG_X86_64 +/* + * Early traps running on the DEFAULT_STACK because the other interrupt + * stacks work only after cpu_init(). + */ +static const __initdata struct idt_data early_pf_idts[] = { + INTG(X86_TRAP_PF, page_fault), +}; + +/* + * Override for the debug_idt. Same as the default, but with interrupt + * stack set to DEFAULT_STACK (0). Required for NMI trap handling. + */ +static const __initdata struct idt_data dbg_idts[] = { + INTG(X86_TRAP_DB, debug), + INTG(X86_TRAP_BP, int3), +}; +#endif + +/* Must be page-aligned because the real IDT is used in a fixmap. */ +gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; + +struct desc_ptr idt_descr __ro_after_init = { + .size = (IDT_ENTRIES * 2 * sizeof(unsigned long)) - 1, + .address = (unsigned long) idt_table, +}; + +#ifdef CONFIG_X86_64 +/* No need to be aligned, but done to keep all IDTs defined the same way. */ +gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; + +/* + * The exceptions which use Interrupt stacks. They are setup after + * cpu_init() when the TSS has been initialized. + */ +static const __initdata struct idt_data ist_idts[] = { + ISTG(X86_TRAP_DB, debug, DEBUG_STACK), + ISTG(X86_TRAP_NMI, nmi, NMI_STACK), + SISTG(X86_TRAP_BP, int3, DEBUG_STACK), + ISTG(X86_TRAP_DF, double_fault, DOUBLEFAULT_STACK), +#ifdef CONFIG_X86_MCE + ISTG(X86_TRAP_MC, &machine_check, MCE_STACK), +#endif +}; + +/* + * Override for the debug_idt. Same as the default, but with interrupt + * stack set to DEFAULT_STACK (0). Required for NMI trap handling. + */ +const struct desc_ptr debug_idt_descr = { + .size = IDT_ENTRIES * 16 - 1, + .address = (unsigned long) debug_idt_table, +}; +#endif + +static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) +{ + unsigned long addr = (unsigned long) d->addr; + + gate->offset_low = (u16) addr; + gate->segment = (u16) d->segment; + gate->bits = d->bits; + gate->offset_middle = (u16) (addr >> 16); +#ifdef CONFIG_X86_64 + gate->offset_high = (u32) (addr >> 32); + gate->reserved = 0; +#endif +} + +static void +idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) +{ + gate_desc desc; + + for (; size > 0; t++, size--) { + idt_init_desc(&desc, t); + write_idt_entry(idt, t->vector, &desc); + if (sys) + set_bit(t->vector, used_vectors); + } +} + +static void set_intr_gate(unsigned int n, const void *addr) +{ + struct idt_data data; + + BUG_ON(n > 0xFF); + + memset(&data, 0, sizeof(data)); + data.vector = n; + data.addr = addr; + data.segment = __KERNEL_CS; + data.bits.type = GATE_INTERRUPT; + data.bits.p = 1; + + idt_setup_from_table(idt_table, &data, 1, false); +} + +/** + * idt_setup_early_traps - Initialize the idt table with early traps + * + * On X8664 these traps do not use interrupt stacks as they can't work + * before cpu_init() is invoked and sets up TSS. The IST variants are + * installed after that. + */ +void __init idt_setup_early_traps(void) +{ + idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts), + true); + load_idt(&idt_descr); +} + +/** + * idt_setup_traps - Initialize the idt table with default traps + */ +void __init idt_setup_traps(void) +{ + idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true); +} + +#ifdef CONFIG_X86_64 +/** + * idt_setup_early_pf - Initialize the idt table with early pagefault handler + * + * On X8664 this does not use interrupt stacks as they can't work before + * cpu_init() is invoked and sets up TSS. The IST variant is installed + * after that. + * + * FIXME: Why is 32bit and 64bit installing the PF handler at different + * places in the early setup code? + */ +void __init idt_setup_early_pf(void) +{ + idt_setup_from_table(idt_table, early_pf_idts, + ARRAY_SIZE(early_pf_idts), true); +} + +/** + * idt_setup_ist_traps - Initialize the idt table with traps using IST + */ +void __init idt_setup_ist_traps(void) +{ + idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true); +} + +/** + * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps + */ +void __init idt_setup_debugidt_traps(void) +{ + memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16); + + idt_setup_from_table(debug_idt_table, dbg_idts, ARRAY_SIZE(dbg_idts), false); +} +#endif + +/** + * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates + */ +void __init idt_setup_apic_and_irq_gates(void) +{ + int i = FIRST_EXTERNAL_VECTOR; + void *entry; + + idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true); + + for_each_clear_bit_from(i, used_vectors, FIRST_SYSTEM_VECTOR) { + entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); + set_intr_gate(i, entry); + } + + for_each_clear_bit_from(i, used_vectors, NR_VECTORS) { +#ifdef CONFIG_X86_LOCAL_APIC + set_bit(i, used_vectors); + set_intr_gate(i, spurious_interrupt); +#else + entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); + set_intr_gate(i, entry); +#endif + } +} + +/** + * idt_setup_early_handler - Initializes the idt table with early handlers + */ +void __init idt_setup_early_handler(void) +{ + int i; + + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) + set_intr_gate(i, early_idt_handler_array[i]); +#ifdef CONFIG_X86_32 + for ( ; i < NR_VECTORS; i++) + set_intr_gate(i, early_ignore_irq); +#endif + load_idt(&idt_descr); +} + +/** + * idt_invalidate - Invalidate interrupt descriptor table + * @addr: The virtual address of the 'invalid' IDT + */ +void idt_invalidate(void *addr) +{ + struct desc_ptr idt = { .address = (unsigned long) addr, .size = 0 }; + + load_idt(&idt); +} + +void __init update_intr_gate(unsigned int n, const void *addr) +{ + if (WARN_ON_ONCE(!test_bit(n, used_vectors))) + return; + set_intr_gate(n, addr); +} + +void alloc_intr_gate(unsigned int n, const void *addr) +{ + BUG_ON(n < FIRST_SYSTEM_VECTOR); + if (!test_and_set_bit(n, used_vectors)) + set_intr_gate(n, addr); +} diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c index 50c89e8a95f2f49ecb1d9fd3321d7c86a2deb7eb..7ebcc4a744389d192df8d9c2078922a2ffbca74a 100644 --- a/arch/x86/kernel/io_delay.c +++ b/arch/x86/kernel/io_delay.c @@ -58,7 +58,7 @@ static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id) * Quirk table for systems that misbehave (lock up, etc.) if port * 0x80 is used: */ -static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = { +static const struct dmi_system_id io_delay_0xed_port_dmi_table[] __initconst = { { .callback = dmi_io_delay_0xed_port, .ident = "Compaq Presario V6000", diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 4ed0aba8dbc83b6ef83aed558ae4c459009d9146..52089c043160b5b54b667f6054bdb4c53f269d43 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -29,9 +29,6 @@ EXPORT_PER_CPU_SYMBOL(irq_regs); atomic_t irq_err_count; -/* Function pointer for generic interrupt vector handling */ -void (*x86_platform_ipi_callback)(void) = NULL; - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -87,13 +84,13 @@ int arch_show_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count); seq_puts(p, " APIC ICR read retries\n"); -#endif if (x86_platform_ipi_callback) { seq_printf(p, "%*s: ", prec, "PLT"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis); seq_puts(p, " Platform interrupts\n"); } +#endif #ifdef CONFIG_SMP seq_printf(p, "%*s: ", prec, "RES"); for_each_online_cpu(j) @@ -183,9 +180,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum += irq_stats(cpu)->apic_perf_irqs; sum += irq_stats(cpu)->apic_irq_work_irqs; sum += irq_stats(cpu)->icr_read_retry_count; -#endif if (x86_platform_ipi_callback) sum += irq_stats(cpu)->x86_platform_ipis; +#endif #ifdef CONFIG_SMP sum += irq_stats(cpu)->irq_resched_count; sum += irq_stats(cpu)->irq_call_count; @@ -259,26 +256,26 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) return 1; } +#ifdef CONFIG_X86_LOCAL_APIC +/* Function pointer for generic interrupt vector handling */ +void (*x86_platform_ipi_callback)(void) = NULL; /* * Handler for X86_PLATFORM_IPI_VECTOR. */ -void __smp_x86_platform_ipi(void) -{ - inc_irq_stat(x86_platform_ipis); - - if (x86_platform_ipi_callback) - x86_platform_ipi_callback(); -} - __visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); entering_ack_irq(); - __smp_x86_platform_ipi(); + trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); + inc_irq_stat(x86_platform_ipis); + if (x86_platform_ipi_callback) + x86_platform_ipi_callback(); + trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); exiting_irq(); set_irq_regs(old_regs); } +#endif #ifdef CONFIG_HAVE_KVM static void dummy_handler(void) {} @@ -334,19 +331,6 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs) } #endif -__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - - entering_ack_irq(); - trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); - __smp_x86_platform_ipi(); - trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); - exiting_irq(); - set_irq_regs(old_regs); -} - -EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); #ifdef CONFIG_HOTPLUG_CPU @@ -431,7 +415,7 @@ int check_irq_vectors_for_cpu_disable(void) * this w/o holding vector_lock. */ for (vector = FIRST_EXTERNAL_VECTOR; - vector < first_system_vector; vector++) { + vector < FIRST_SYSTEM_VECTOR; vector++) { if (!test_bit(vector, used_vectors) && IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) { if (++count == this_count) diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 1f38d9a4d9deaf707af2b7e658bd9e9022ba8d75..d4eb450144fdb42c4f667b9f5b1a69d91aa78a2e 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -64,7 +64,7 @@ static void call_on_stack(void *func, void *stack) static inline void *current_stack(void) { - return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1)); + return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); } static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) @@ -88,7 +88,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) /* Save the next esp at the bottom of the stack */ prev_esp = (u32 *)irqstk; - *prev_esp = current_stack_pointer(); + *prev_esp = current_stack_pointer; if (unlikely(overflow)) call_on_stack(print_stack_overflow, isp); @@ -139,7 +139,7 @@ void do_softirq_own_stack(void) /* Push the previous esp onto the stack */ prev_esp = (u32 *)irqstk; - *prev_esp = current_stack_pointer(); + *prev_esp = current_stack_pointer; call_on_stack(__do_softirq, isp); } diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c index 275487872be2b35e7c6d01335fb08170b2cf7fa0..70dee056f92b671ac1b3f77c68c83d187262b095 100644 --- a/arch/x86/kernel/irq_work.c +++ b/arch/x86/kernel/irq_work.c @@ -11,35 +11,23 @@ #include #include -static inline void __smp_irq_work_interrupt(void) -{ - inc_irq_stat(apic_irq_work_irqs); - irq_work_run(); -} - +#ifdef CONFIG_X86_LOCAL_APIC __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) -{ - ipi_entering_ack_irq(); - __smp_irq_work_interrupt(); - exiting_irq(); -} - -__visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs) { ipi_entering_ack_irq(); trace_irq_work_entry(IRQ_WORK_VECTOR); - __smp_irq_work_interrupt(); + inc_irq_stat(apic_irq_work_irqs); + irq_work_run(); trace_irq_work_exit(IRQ_WORK_VECTOR); exiting_irq(); } void arch_irq_work_raise(void) { -#ifdef CONFIG_X86_LOCAL_APIC if (!arch_irq_work_has_interrupt()) return; apic->send_IPI_self(IRQ_WORK_VECTOR); apic_wait_icr_idle(); -#endif } +#endif diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index c7fd18526c3e3087dee25af3ab0c3f3ff7dc616b..1add9e08e83ede731aab12d650a4284d97120cf6 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -55,18 +55,6 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = { [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, }; -int vector_used_by_percpu_irq(unsigned int vector) -{ - int cpu; - - for_each_online_cpu(cpu) { - if (!IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) - return 1; - } - - return 0; -} - void __init init_ISA_irqs(void) { struct irq_chip *chip = legacy_pic->chip; @@ -99,100 +87,12 @@ void __init init_IRQ(void) x86_init.irqs.intr_init(); } -static void __init smp_intr_init(void) -{ -#ifdef CONFIG_SMP - /* - * The reschedule interrupt is a CPU-to-CPU reschedule-helper - * IPI, driven by wakeup. - */ - alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); - - /* IPI for generic function call */ - alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); - - /* IPI for generic single function call */ - alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, - call_function_single_interrupt); - - /* Low priority IPI to cleanup after moving an irq */ - set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); - set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); - - /* IPI used for rebooting/stopping */ - alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt); -#endif /* CONFIG_SMP */ -} - -static void __init apic_intr_init(void) -{ - smp_intr_init(); - -#ifdef CONFIG_X86_THERMAL_VECTOR - alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); -#endif -#ifdef CONFIG_X86_MCE_THRESHOLD - alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); -#endif - -#ifdef CONFIG_X86_MCE_AMD - alloc_intr_gate(DEFERRED_ERROR_VECTOR, deferred_error_interrupt); -#endif - -#ifdef CONFIG_X86_LOCAL_APIC - /* self generated IPI for local APIC timer */ - alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); - - /* IPI for X86 platform specific use */ - alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi); -#ifdef CONFIG_HAVE_KVM - /* IPI for KVM to deliver posted interrupt */ - alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi); - /* IPI for KVM to deliver interrupt to wake up tasks */ - alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi); - /* IPI for KVM to deliver nested posted interrupt */ - alloc_intr_gate(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi); -#endif - - /* IPI vectors for APIC spurious and error interrupts */ - alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); - alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); - - /* IRQ work interrupts: */ -# ifdef CONFIG_IRQ_WORK - alloc_intr_gate(IRQ_WORK_VECTOR, irq_work_interrupt); -# endif - -#endif -} - void __init native_init_IRQ(void) { - int i; - /* Execute any quirks before the call gates are initialised: */ x86_init.irqs.pre_vector_init(); - apic_intr_init(); - - /* - * Cover the whole vector space, no vector can escape - * us. (some of these will be overridden and become - * 'special' SMP interrupts) - */ - i = FIRST_EXTERNAL_VECTOR; -#ifndef CONFIG_X86_LOCAL_APIC -#define first_system_vector NR_VECTORS -#endif - for_each_clear_bit_from(i, used_vectors, first_system_vector) { - /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ - set_intr_gate(i, irq_entries_start + - 8 * (i - FIRST_EXTERNAL_VECTOR)); - } -#ifdef CONFIG_X86_LOCAL_APIC - for_each_clear_bit_from(i, used_vectors, NR_VECTORS) - set_intr_gate(i, spurious_interrupt); -#endif + idt_setup_apic_and_irq_gates(); if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) setup_irq(2, &irq2); diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index 38b64587b31be5611a763df6dafe8434db2a66b5..fd6f8fbbe6f2a05d061c3e0196c313293ae8ad08 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -33,7 +33,6 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, struct setup_data_node *node = file->private_data; unsigned long remain; loff_t pos = *ppos; - struct page *pg; void *p; u64 pa; @@ -47,18 +46,13 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, count = node->len - pos; pa = node->paddr + sizeof(struct setup_data) + pos; - pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT); - if (PageHighMem(pg)) { - p = ioremap_cache(pa, count); - if (!p) - return -ENXIO; - } else - p = __va(pa); + p = memremap(pa, count, MEMREMAP_WB); + if (!p) + return -ENOMEM; remain = copy_to_user(user_buf, p, count); - if (PageHighMem(pg)) - iounmap(p); + memunmap(p); if (remain) return -EFAULT; @@ -109,7 +103,6 @@ static int __init create_setup_data_nodes(struct dentry *parent) struct setup_data *data; int error; struct dentry *d; - struct page *pg; u64 pa_data; int no = 0; @@ -126,16 +119,12 @@ static int __init create_setup_data_nodes(struct dentry *parent) goto err_dir; } - pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT); - if (PageHighMem(pg)) { - data = ioremap_cache(pa_data, sizeof(*data)); - if (!data) { - kfree(node); - error = -ENXIO; - goto err_dir; - } - } else - data = __va(pa_data); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); + if (!data) { + kfree(node); + error = -ENOMEM; + goto err_dir; + } node->paddr = pa_data; node->type = data->type; @@ -143,8 +132,7 @@ static int __init create_setup_data_nodes(struct dentry *parent) error = create_setup_data_node(d, no, node); pa_data = data->next; - if (PageHighMem(pg)) - iounmap(data); + memunmap(data); if (error) goto err_dir; no++; diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 69ea0bc1cfa394c0625f2beb9280db7a273dbafe..4f98aad382378a5987306842ea4fc9cde56972d4 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "common.h" @@ -251,10 +252,12 @@ static int can_optimize(unsigned long paddr) /* * Do not optimize in the entry code due to the unstable - * stack handling. + * stack handling and registers setup. */ - if ((paddr >= (unsigned long)__entry_text_start) && - (paddr < (unsigned long)__entry_text_end)) + if (((paddr >= (unsigned long)__entry_text_start) && + (paddr < (unsigned long)__entry_text_end)) || + ((paddr >= (unsigned long)__irqentry_text_start) && + (paddr < (unsigned long)__irqentry_text_end))) return 0; /* Check there is enough space for a relative jump. */ diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c index 4afc67f5facc497606e2fb898ba7b7d402f04caa..8c1cc08f514f4362bdaefa933fda3cd3769b04f9 100644 --- a/arch/x86/kernel/ksysfs.c +++ b/arch/x86/kernel/ksysfs.c @@ -16,8 +16,8 @@ #include #include #include +#include -#include #include static ssize_t version_show(struct kobject *kobj, @@ -55,7 +55,7 @@ static struct bin_attribute *boot_params_data_attrs[] = { NULL, }; -static struct attribute_group boot_params_attr_group = { +static const struct attribute_group boot_params_attr_group = { .attrs = boot_params_version_attrs, .bin_attrs = boot_params_data_attrs, }; @@ -79,12 +79,12 @@ static int get_setup_data_paddr(int nr, u64 *paddr) *paddr = pa_data; return 0; } - data = ioremap_cache(pa_data, sizeof(*data)); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; pa_data = data->next; - iounmap(data); + memunmap(data); i++; } return -EINVAL; @@ -97,17 +97,17 @@ static int __init get_setup_data_size(int nr, size_t *size) u64 pa_data = boot_params.hdr.setup_data; while (pa_data) { - data = ioremap_cache(pa_data, sizeof(*data)); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; if (nr == i) { *size = data->len; - iounmap(data); + memunmap(data); return 0; } pa_data = data->next; - iounmap(data); + memunmap(data); i++; } return -EINVAL; @@ -127,12 +127,12 @@ static ssize_t type_show(struct kobject *kobj, ret = get_setup_data_paddr(nr, &paddr); if (ret) return ret; - data = ioremap_cache(paddr, sizeof(*data)); + data = memremap(paddr, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; ret = sprintf(buf, "0x%x\n", data->type); - iounmap(data); + memunmap(data); return ret; } @@ -154,7 +154,7 @@ static ssize_t setup_data_data_read(struct file *fp, ret = get_setup_data_paddr(nr, &paddr); if (ret) return ret; - data = ioremap_cache(paddr, sizeof(*data)); + data = memremap(paddr, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; @@ -170,15 +170,15 @@ static ssize_t setup_data_data_read(struct file *fp, goto out; ret = count; - p = ioremap_cache(paddr + sizeof(*data), data->len); + p = memremap(paddr + sizeof(*data), data->len, MEMREMAP_WB); if (!p) { ret = -ENOMEM; goto out; } memcpy(buf, p + off, count); - iounmap(p); + memunmap(p); out: - iounmap(data); + memunmap(data); return ret; } @@ -202,7 +202,7 @@ static struct bin_attribute *setup_data_data_attrs[] = { NULL, }; -static struct attribute_group setup_data_attr_group = { +static const struct attribute_group setup_data_attr_group = { .attrs = setup_data_type_attrs, .bin_attrs = setup_data_data_attrs, }; @@ -250,13 +250,13 @@ static int __init get_setup_data_total_num(u64 pa_data, int *nr) *nr = 0; while (pa_data) { *nr += 1; - data = ioremap_cache(pa_data, sizeof(*data)); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); if (!data) { ret = -ENOMEM; goto out; } pa_data = data->next; - iounmap(data); + memunmap(data); } out: @@ -299,7 +299,7 @@ static int __init create_setup_data_nodes(struct kobject *parent) return 0; out_clean_nodes: - for (j = i - 1; j > 0; j--) + for (j = i - 1; j >= 0; j--) cleanup_setup_data_node(*(kobjp + j)); kfree(kobjp); out_setup_data_kobj: diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 71c17a5be983524ea277718b759ff1511a9a3214..8bb9594d076166ee0f6bd4f70350fe3ecf8c3d8b 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -117,7 +117,11 @@ static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b, return NULL; } -void kvm_async_pf_task_wait(u32 token) +/* + * @interrupt_kernel: Is this called from a routine which interrupts the kernel + * (other than user space)? + */ +void kvm_async_pf_task_wait(u32 token, int interrupt_kernel) { u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; @@ -140,7 +144,10 @@ void kvm_async_pf_task_wait(u32 token) n.token = token; n.cpu = smp_processor_id(); - n.halted = is_idle_task(current) || preempt_count() > 1; + n.halted = is_idle_task(current) || + (IS_ENABLED(CONFIG_PREEMPT_COUNT) + ? preempt_count() > 1 || rcu_preempt_depth() + : interrupt_kernel); init_swait_queue_head(&n.wq); hlist_add_head(&n.link, &b->list); raw_spin_unlock(&b->lock); @@ -151,6 +158,8 @@ void kvm_async_pf_task_wait(u32 token) if (hlist_unhashed(&n.link)) break; + rcu_irq_exit(); + if (!n.halted) { local_irq_enable(); schedule(); @@ -159,11 +168,11 @@ void kvm_async_pf_task_wait(u32 token) /* * We cannot reschedule. So halt. */ - rcu_irq_exit(); native_safe_halt(); local_irq_disable(); - rcu_irq_enter(); } + + rcu_irq_enter(); } if (!n.halted) finish_swait(&n.wq, &wait); @@ -178,7 +187,7 @@ static void apf_task_wake_one(struct kvm_task_sleep_node *n) hlist_del_init(&n->link); if (n->halted) smp_send_reschedule(n->cpu); - else if (swait_active(&n->wq)) + else if (swq_has_sleeper(&n->wq)) swake_up(&n->wq); } @@ -261,12 +270,12 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) switch (kvm_read_and_reset_pf_reason()) { default: - trace_do_page_fault(regs, error_code); + do_page_fault(regs, error_code); break; case KVM_PV_REASON_PAGE_NOT_PRESENT: /* page is swapped out by the host. */ prev_state = exception_enter(); - kvm_async_pf_task_wait((u32)read_cr2()); + kvm_async_pf_task_wait((u32)read_cr2(), !user_mode(regs)); exception_exit(prev_state); break; case KVM_PV_REASON_PAGE_READY: @@ -453,7 +462,7 @@ static int kvm_cpu_down_prepare(unsigned int cpu) static void __init kvm_apf_trap_init(void) { - set_intr_gate(14, async_page_fault); + update_intr_gate(X86_TRAP_PF, async_page_fault); } void __init kvm_guest_init(void) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index a870910c85658af0379d5dea041d687547078663..f0e64db18ac83db5f45e6bb7f531e1536d11522a 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -21,6 +21,25 @@ #include #include +static void refresh_ldt_segments(void) +{ +#ifdef CONFIG_X86_64 + unsigned short sel; + + /* + * Make sure that the cached DS and ES descriptors match the updated + * LDT. + */ + savesegment(ds, sel); + if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) + loadsegment(ds, sel); + + savesegment(es, sel); + if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) + loadsegment(es, sel); +#endif +} + /* context.lock is held for us, so we don't need any locking. */ static void flush_ldt(void *__mm) { @@ -32,6 +51,8 @@ static void flush_ldt(void *__mm) pc = &mm->context; set_ldt(pc->ldt->entries, pc->ldt->nr_entries); + + refresh_ldt_segments(); } /* The caller must call finalize_ldt_struct on the result. LDT starts zeroed. */ diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 8c53c5d7a1bc5e9733e4b4da8ed1a760ab138dbe..00bc751c861ce8fa42c1b93d39d029694f4e328d 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -26,18 +26,6 @@ #include #include -static void set_idt(void *newidt, __u16 limit) -{ - struct desc_ptr curidt; - - /* ia32 supports unaliged loads & stores */ - curidt.size = limit; - curidt.address = (unsigned long)newidt; - - load_idt(&curidt); -} - - static void set_gdt(void *newgdt, __u16 limit) { struct desc_ptr curgdt; @@ -245,7 +233,7 @@ void machine_kexec(struct kimage *image) * If you want to load them you must set up your own idt & gdt. */ set_gdt(phys_to_virt(0), 0); - set_idt(phys_to_virt(0), 0); + idt_invalidate(phys_to_virt(0)); /* now call it */ image->start = relocate_kernel_ptr((unsigned long)image->head, diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index cb0a30473c2310b76695c73ec6fad3cd1e7b051f..1f790cf9d38fe0e10e46eaf9b5bef945d25a9370 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -87,7 +87,7 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE)); } pte = pte_offset_kernel(pmd, vaddr); - set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC)); + set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC)); return 0; err: free_transition_pgtable(image); @@ -115,6 +115,7 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) .alloc_pgt_page = alloc_pgt_page, .context = image, .page_flag = __PAGE_KERNEL_LARGE_EXEC, + .kernpg_flag = _KERNPG_TABLE_NOENC, }; unsigned long mstart, mend; pgd_t *level4p; @@ -334,7 +335,8 @@ void machine_kexec(struct kimage *image) image->start = relocate_kernel((unsigned long)image->head, (unsigned long)page_list, image->start, - image->preserve_context); + image->preserve_context, + sme_active()); #ifdef CONFIG_KEXEC_JUMP if (image->preserve_context) @@ -602,3 +604,22 @@ void arch_kexec_unprotect_crashkres(void) { kexec_mark_crashkres(false); } + +int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp) +{ + /* + * If SME is active we need to be sure that kexec pages are + * not encrypted because when we boot to the new kernel the + * pages won't be accessed encrypted (initially). + */ + return set_memory_decrypted((unsigned long)vaddr, pages); +} + +void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) +{ + /* + * If SME is active we need to reset the pages back to being + * an encrypted mapping before freeing them. + */ + set_memory_encrypted((unsigned long)vaddr, pages); +} diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index f67bd3205df7aafd61d22d55b0a4f4573bf90b9e..62e7d70aadd5ffece72b357ac1e3024a1b9f7897 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -35,6 +35,7 @@ #include #include #include +#include #if 0 #define DEBUGP(fmt, ...) \ @@ -213,7 +214,7 @@ int module_finalize(const Elf_Ehdr *hdr, struct module *me) { const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, - *para = NULL; + *para = NULL, *orc = NULL, *orc_ip = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { @@ -225,6 +226,10 @@ int module_finalize(const Elf_Ehdr *hdr, locks = s; if (!strcmp(".parainstructions", secstrings + s->sh_name)) para = s; + if (!strcmp(".orc_unwind", secstrings + s->sh_name)) + orc = s; + if (!strcmp(".orc_unwind_ip", secstrings + s->sh_name)) + orc_ip = s; } if (alt) { @@ -248,6 +253,10 @@ int module_finalize(const Elf_Ehdr *hdr, /* make jump label nops */ jump_label_apply_nops(me); + if (orc && orc_ip) + unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size, + (void *)orc->sh_addr, orc->sh_size); + return 0; } diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 0d904d759ff1d42c97e57a7ef5e126bd961b8b03..5cbb3177ed17270b993a4c1a686282ce80608ed1 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -429,16 +429,16 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) } } -static struct mpf_intel *mpf_found; +static unsigned long mpf_base; static unsigned long __init get_mpc_size(unsigned long physptr) { struct mpc_table *mpc; unsigned long size; - mpc = early_ioremap(physptr, PAGE_SIZE); + mpc = early_memremap(physptr, PAGE_SIZE); size = mpc->length; - early_iounmap(mpc, PAGE_SIZE); + early_memunmap(mpc, PAGE_SIZE); apic_printk(APIC_VERBOSE, " mpc: %lx-%lx\n", physptr, physptr + size); return size; @@ -450,7 +450,8 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) unsigned long size; size = get_mpc_size(mpf->physptr); - mpc = early_ioremap(mpf->physptr, size); + mpc = early_memremap(mpf->physptr, size); + /* * Read the physical hardware table. Anything here will * override the defaults. @@ -461,10 +462,10 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) #endif pr_err("BIOS bug, MP table errors detected!...\n"); pr_cont("... disabling SMP support. (tell your hw vendor)\n"); - early_iounmap(mpc, size); + early_memunmap(mpc, size); return -1; } - early_iounmap(mpc, size); + early_memunmap(mpc, size); if (early) return -1; @@ -497,12 +498,12 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) */ void __init default_get_smp_config(unsigned int early) { - struct mpf_intel *mpf = mpf_found; + struct mpf_intel *mpf; if (!smp_found_config) return; - if (!mpf) + if (!mpf_base) return; if (acpi_lapic && early) @@ -515,6 +516,12 @@ void __init default_get_smp_config(unsigned int early) if (acpi_lapic && acpi_ioapic) return; + mpf = early_memremap(mpf_base, sizeof(*mpf)); + if (!mpf) { + pr_err("MPTABLE: error mapping MP table\n"); + return; + } + pr_info("Intel MultiProcessor Specification v1.%d\n", mpf->specification); #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) @@ -529,7 +536,7 @@ void __init default_get_smp_config(unsigned int early) /* * Now see if we need to read further. */ - if (mpf->feature1 != 0) { + if (mpf->feature1) { if (early) { /* * local APIC has default address @@ -542,8 +549,10 @@ void __init default_get_smp_config(unsigned int early) construct_default_ISA_mptable(mpf->feature1); } else if (mpf->physptr) { - if (check_physptr(mpf, early)) + if (check_physptr(mpf, early)) { + early_memunmap(mpf, sizeof(*mpf)); return; + } } else BUG(); @@ -552,6 +561,8 @@ void __init default_get_smp_config(unsigned int early) /* * Only use the first configuration found. */ + + early_memunmap(mpf, sizeof(*mpf)); } static void __init smp_reserve_memory(struct mpf_intel *mpf) @@ -561,15 +572,16 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf) static int __init smp_scan_config(unsigned long base, unsigned long length) { - unsigned int *bp = phys_to_virt(base); + unsigned int *bp; struct mpf_intel *mpf; - unsigned long mem; + int ret = 0; apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n", base, base + length - 1); BUILD_BUG_ON(sizeof(*mpf) != 16); while (length > 0) { + bp = early_memremap(base, length); mpf = (struct mpf_intel *)bp; if ((*bp == SMP_MAGIC_IDENT) && (mpf->length == 1) && @@ -579,24 +591,26 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) #ifdef CONFIG_X86_LOCAL_APIC smp_found_config = 1; #endif - mpf_found = mpf; + mpf_base = base; - pr_info("found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n", - (unsigned long long) virt_to_phys(mpf), - (unsigned long long) virt_to_phys(mpf) + - sizeof(*mpf) - 1, mpf); + pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n", + base, base + sizeof(*mpf) - 1, mpf); - mem = virt_to_phys(mpf); - memblock_reserve(mem, sizeof(*mpf)); + memblock_reserve(base, sizeof(*mpf)); if (mpf->physptr) smp_reserve_memory(mpf); - return 1; + ret = 1; } - bp += 4; + early_memunmap(bp, length); + + if (ret) + break; + + base += 16; length -= 16; } - return 0; + return ret; } void __init default_find_smp_config(void) @@ -838,29 +852,40 @@ static int __init update_mp_table(void) char oem[10]; struct mpf_intel *mpf; struct mpc_table *mpc, *mpc_new; + unsigned long size; if (!enable_update_mptable) return 0; - mpf = mpf_found; - if (!mpf) + if (!mpf_base) return 0; + mpf = early_memremap(mpf_base, sizeof(*mpf)); + if (!mpf) { + pr_err("MPTABLE: mpf early_memremap() failed\n"); + return 0; + } + /* * Now see if we need to go further. */ - if (mpf->feature1 != 0) - return 0; + if (mpf->feature1) + goto do_unmap_mpf; if (!mpf->physptr) - return 0; + goto do_unmap_mpf; - mpc = phys_to_virt(mpf->physptr); + size = get_mpc_size(mpf->physptr); + mpc = early_memremap(mpf->physptr, size); + if (!mpc) { + pr_err("MPTABLE: mpc early_memremap() failed\n"); + goto do_unmap_mpf; + } if (!smp_check_mpc(mpc, oem, str)) - return 0; + goto do_unmap_mpc; - pr_info("mpf: %llx\n", (u64)virt_to_phys(mpf)); + pr_info("mpf: %llx\n", (u64)mpf_base); pr_info("physptr: %x\n", mpf->physptr); if (mpc_new_phys && mpc->length > mpc_new_length) { @@ -878,21 +903,32 @@ static int __init update_mp_table(void) new = mpf_checksum((unsigned char *)mpc, mpc->length); if (old == new) { pr_info("mpc is readonly, please try alloc_mptable instead\n"); - return 0; + goto do_unmap_mpc; } pr_info("use in-position replacing\n"); } else { + mpc_new = early_memremap(mpc_new_phys, mpc_new_length); + if (!mpc_new) { + pr_err("MPTABLE: new mpc early_memremap() failed\n"); + goto do_unmap_mpc; + } mpf->physptr = mpc_new_phys; - mpc_new = phys_to_virt(mpc_new_phys); memcpy(mpc_new, mpc, mpc->length); + early_memunmap(mpc, size); mpc = mpc_new; + size = mpc_new_length; /* check if we can modify that */ if (mpc_new_phys - mpf->physptr) { struct mpf_intel *mpf_new; /* steal 16 bytes from [0, 1k) */ + mpf_new = early_memremap(0x400 - 16, sizeof(*mpf_new)); + if (!mpf_new) { + pr_err("MPTABLE: new mpf early_memremap() failed\n"); + goto do_unmap_mpc; + } pr_info("mpf new: %x\n", 0x400 - 16); - mpf_new = phys_to_virt(0x400 - 16); memcpy(mpf_new, mpf, 16); + early_memunmap(mpf, sizeof(*mpf)); mpf = mpf_new; mpf->physptr = mpc_new_phys; } @@ -909,6 +945,12 @@ static int __init update_mp_table(void) */ replace_intsrc_all(mpc, mpc_new_phys, mpc_new_length); +do_unmap_mpc: + early_memunmap(mpc, size); + +do_unmap_mpf: + early_memunmap(mpf, sizeof(*mpf)); + return 0; } diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 446c8aa09b9bc1935627579926c0e9b22f7aa12f..35aafc95e4b8a505491d7079a06e8e1b8e16c968 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -39,26 +39,26 @@ #include struct nmi_desc { - spinlock_t lock; + raw_spinlock_t lock; struct list_head head; }; static struct nmi_desc nmi_desc[NMI_MAX] = { { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[0].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[0].lock), .head = LIST_HEAD_INIT(nmi_desc[0].head), }, { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[1].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[1].lock), .head = LIST_HEAD_INIT(nmi_desc[1].head), }, { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[2].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[2].lock), .head = LIST_HEAD_INIT(nmi_desc[2].head), }, { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[3].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[3].lock), .head = LIST_HEAD_INIT(nmi_desc[3].head), }, @@ -163,7 +163,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) init_irq_work(&action->irq_work, nmi_max_handler); - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); /* * Indicate if there are multiple registrations on the @@ -181,7 +181,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) else list_add_tail_rcu(&action->list, &desc->head); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } EXPORT_SYMBOL(__register_nmi_handler); @@ -192,7 +192,7 @@ void unregister_nmi_handler(unsigned int type, const char *name) struct nmiaction *n; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); list_for_each_entry_rcu(n, &desc->head, list) { /* @@ -207,7 +207,7 @@ void unregister_nmi_handler(unsigned int type, const char *name) } } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); synchronize_rcu(); } EXPORT_SYMBOL_GPL(unregister_nmi_handler); diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index bc0a849589bbb1e5c5c5710fec4358dfd21888db..19a3e8f961c772af6572f80a860e1c892ad31a32 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -319,9 +319,6 @@ __visible struct pv_irq_ops pv_irq_ops = { .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), .safe_halt = native_safe_halt, .halt = native_halt, -#ifdef CONFIG_X86_64 - .adjust_exception_frame = paravirt_nop, -#endif }; __visible struct pv_cpu_ops pv_cpu_ops = { @@ -330,7 +327,6 @@ __visible struct pv_cpu_ops pv_cpu_ops = { .set_debugreg = native_set_debugreg, .read_cr0 = native_read_cr0, .write_cr0 = native_write_cr0, - .read_cr4 = native_read_cr4, .write_cr4 = native_write_cr4, #ifdef CONFIG_X86_64 .read_cr8 = native_read_cr8, @@ -346,7 +342,6 @@ __visible struct pv_cpu_ops pv_cpu_ops = { .set_ldt = native_set_ldt, .load_gdt = native_load_gdt, .load_idt = native_load_idt, - .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, #ifdef CONFIG_X86_64 @@ -414,8 +409,6 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = { .set_pte = native_set_pte, .set_pte_at = native_set_pte_at, .set_pmd = native_set_pmd, - .set_pmd_at = native_set_pmd_at, - .pte_update = paravirt_nop, .ptep_modify_prot_start = __ptep_modify_prot_start, .ptep_modify_prot_commit = __ptep_modify_prot_commit, @@ -427,7 +420,6 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = { .pmd_clear = native_pmd_clear, #endif .set_pud = native_set_pud, - .set_pud_at = native_set_pud_at, .pmd_val = PTE_IDENT, .make_pmd = PTE_IDENT, diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 5e16d3f2959468f6d05aaa1be5eef2f8b945abb1..0accc2404b9214d1b318577668f103bc41bc8d35 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -93,9 +93,12 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, if (gfpflags_allow_blocking(flag)) { page = dma_alloc_from_contiguous(dev, count, get_order(size), flag); - if (page && page_to_phys(page) + size > dma_mask) { - dma_release_from_contiguous(dev, page, count); - page = NULL; + if (page) { + addr = phys_to_dma(dev, page_to_phys(page)); + if (addr + size > dma_mask) { + dma_release_from_contiguous(dev, page, count); + page = NULL; + } } } /* fallback */ @@ -104,7 +107,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, if (!page) return NULL; - addr = page_to_phys(page); + addr = phys_to_dma(dev, page_to_phys(page)); if (addr + size > dma_mask) { __free_pages(page, get_order(size)); diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index a6d404087fe3285f65de353613153abde4a698a0..4fc3cb60ea11a546b08ae8c2f3fdbb9007dee670 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -32,7 +32,7 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page, enum dma_data_direction dir, unsigned long attrs) { - dma_addr_t bus = page_to_phys(page) + offset; + dma_addr_t bus = phys_to_dma(dev, page_to_phys(page)) + offset; WARN_ON(size == 0); if (!check_addr("map_single", dev, bus, size)) return NOMMU_MAPPING_ERROR; diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 1e23577e17cf10f87d584e4cdc38f4691db57862..677077510e308ebfabb56d8072a2afed439f23c8 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c @@ -6,12 +6,14 @@ #include #include #include +#include #include #include #include #include #include + int swiotlb __read_mostly; void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, @@ -79,8 +81,8 @@ IOMMU_INIT_FINISH(pci_swiotlb_detect_override, pci_swiotlb_late_init); /* - * if 4GB or more detected (and iommu=off not set) return 1 - * and set swiotlb to 1. + * If 4GB or more detected (and iommu=off not set) or if SME is active + * then set swiotlb to 1 and return 1. */ int __init pci_swiotlb_detect_4gb(void) { @@ -89,6 +91,15 @@ int __init pci_swiotlb_detect_4gb(void) if (!no_iommu && max_possible_pfn > MAX_DMA32_PFN) swiotlb = 1; #endif + + /* + * If SME is active then swiotlb will be set to 1 so that bounce + * buffers are allocated and used for devices that do not support + * the addressing range required for the encryption mask. + */ + if (sme_active()) + swiotlb = 1; + return swiotlb; } IOMMU_INIT(pci_swiotlb_detect_4gb, diff --git a/arch/x86/kernel/platform-quirks.c b/arch/x86/kernel/platform-quirks.c index 91271122f0dfb947e1b1b68cddeb505053fd9425..502a77d0adb0504861155484d01dfd263bf47897 100644 --- a/arch/x86/kernel/platform-quirks.c +++ b/arch/x86/kernel/platform-quirks.c @@ -16,7 +16,6 @@ void __init x86_early_init_platform_quirks(void) x86_platform.legacy.reserve_bios_regions = 1; break; case X86_SUBARCH_XEN: - case X86_SUBARCH_LGUEST: x86_platform.legacy.devices.pnpbios = 0; x86_platform.legacy.rtc = 0; break; diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 3ca198080ea9294486ae9a1121e7815dfba7cb19..bd6b85fac66696da70e316656ad6f0d51291f8aa 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -355,6 +355,7 @@ bool xen_set_default_idle(void) return ret; } #endif + void stop_this_cpu(void *dummy) { local_irq_disable(); @@ -365,8 +366,20 @@ void stop_this_cpu(void *dummy) disable_local_APIC(); mcheck_cpu_clear(this_cpu_ptr(&cpu_info)); - for (;;) - halt(); + for (;;) { + /* + * Use wbinvd followed by hlt to stop the processor. This + * provides support for kexec on a processor that supports + * SME. With kexec, going from SME inactive to SME active + * requires clearing cache entries so that addresses without + * the encryption bit set don't corrupt the same physical + * address that has the encryption bit set when caches are + * flushed. To achieve this a wbinvd is performed followed by + * a hlt. Even if the processor is not in the kexec/SME + * scenario this only adds a wbinvd to a halting processor. + */ + asm volatile("wbinvd; hlt" : : : "memory"); + } } /* diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index c6d6dc5f8bb2a2245bf0203c498abf38d6be0bc4..11966251cd4259b871203636953e4897e8bd67ab 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include void __show_regs(struct pt_regs *regs, int all) @@ -68,7 +68,7 @@ void __show_regs(struct pt_regs *regs, int all) if (user_mode(regs)) { sp = regs->sp; - ss = regs->ss & 0xffff; + ss = regs->ss; gs = get_user_gs(regs); } else { sp = kernel_stack_pointer(regs); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c3169be4c5967de78efd75690a2bce80ca01506d..302e7b2572d1883d7f79d90956446fff1ef8c8ab 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_IA32_EMULATION /* Not included via unistd.h */ @@ -69,8 +69,7 @@ void __show_regs(struct pt_regs *regs, int all) unsigned int fsindex, gsindex; unsigned int ds, cs, es; - printk(KERN_DEFAULT "RIP: %04lx:%pS\n", regs->cs & 0xffff, - (void *)regs->ip); + printk(KERN_DEFAULT "RIP: %04lx:%pS\n", regs->cs, (void *)regs->ip); printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx", regs->ss, regs->sp, regs->flags); if (regs->orig_ax != -1) @@ -149,6 +148,123 @@ void release_thread(struct task_struct *dead_task) } } +enum which_selector { + FS, + GS +}; + +/* + * Saves the FS or GS base for an outgoing thread if FSGSBASE extensions are + * not available. The goal is to be reasonably fast on non-FSGSBASE systems. + * It's forcibly inlined because it'll generate better code and this function + * is hot. + */ +static __always_inline void save_base_legacy(struct task_struct *prev_p, + unsigned short selector, + enum which_selector which) +{ + if (likely(selector == 0)) { + /* + * On Intel (without X86_BUG_NULL_SEG), the segment base could + * be the pre-existing saved base or it could be zero. On AMD + * (with X86_BUG_NULL_SEG), the segment base could be almost + * anything. + * + * This branch is very hot (it's hit twice on almost every + * context switch between 64-bit programs), and avoiding + * the RDMSR helps a lot, so we just assume that whatever + * value is already saved is correct. This matches historical + * Linux behavior, so it won't break existing applications. + * + * To avoid leaking state, on non-X86_BUG_NULL_SEG CPUs, if we + * report that the base is zero, it needs to actually be zero: + * see the corresponding logic in load_seg_legacy. + */ + } else { + /* + * If the selector is 1, 2, or 3, then the base is zero on + * !X86_BUG_NULL_SEG CPUs and could be anything on + * X86_BUG_NULL_SEG CPUs. In the latter case, Linux + * has never attempted to preserve the base across context + * switches. + * + * If selector > 3, then it refers to a real segment, and + * saving the base isn't necessary. + */ + if (which == FS) + prev_p->thread.fsbase = 0; + else + prev_p->thread.gsbase = 0; + } +} + +static __always_inline void save_fsgs(struct task_struct *task) +{ + savesegment(fs, task->thread.fsindex); + savesegment(gs, task->thread.gsindex); + save_base_legacy(task, task->thread.fsindex, FS); + save_base_legacy(task, task->thread.gsindex, GS); +} + +static __always_inline void loadseg(enum which_selector which, + unsigned short sel) +{ + if (which == FS) + loadsegment(fs, sel); + else + load_gs_index(sel); +} + +static __always_inline void load_seg_legacy(unsigned short prev_index, + unsigned long prev_base, + unsigned short next_index, + unsigned long next_base, + enum which_selector which) +{ + if (likely(next_index <= 3)) { + /* + * The next task is using 64-bit TLS, is not using this + * segment at all, or is having fun with arcane CPU features. + */ + if (next_base == 0) { + /* + * Nasty case: on AMD CPUs, we need to forcibly zero + * the base. + */ + if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { + loadseg(which, __USER_DS); + loadseg(which, next_index); + } else { + /* + * We could try to exhaustively detect cases + * under which we can skip the segment load, + * but there's really only one case that matters + * for performance: if both the previous and + * next states are fully zeroed, we can skip + * the load. + * + * (This assumes that prev_base == 0 has no + * false positives. This is the case on + * Intel-style CPUs.) + */ + if (likely(prev_index | next_index | prev_base)) + loadseg(which, next_index); + } + } else { + if (prev_index != next_index) + loadseg(which, next_index); + wrmsrl(which == FS ? MSR_FS_BASE : MSR_KERNEL_GS_BASE, + next_base); + } + } else { + /* + * The next task is using a real segment. Loading the selector + * is sufficient. + */ + loadseg(which, next_index); + } +} + int copy_thread_tls(unsigned long clone_flags, unsigned long sp, unsigned long arg, struct task_struct *p, unsigned long tls) { @@ -229,10 +345,19 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp, unsigned int _cs, unsigned int _ss, unsigned int _ds) { + WARN_ON_ONCE(regs != current_pt_regs()); + + if (static_cpu_has(X86_BUG_NULL_SEG)) { + /* Loading zero below won't clear the base. */ + loadsegment(fs, __USER_DS); + load_gs_index(__USER_DS); + } + loadsegment(fs, 0); loadsegment(es, _ds); loadsegment(ds, _ds); load_gs_index(0); + regs->ip = new_ip; regs->sp = new_sp; regs->cs = _cs; @@ -277,7 +402,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) struct fpu *next_fpu = &next->fpu; int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(cpu_tss, cpu); - unsigned prev_fsindex, prev_gsindex; + + WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) && + this_cpu_read(irq_count) != -1); switch_fpu_prepare(prev_fpu, cpu); @@ -286,8 +413,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) * * (e.g. xen_load_tls()) */ - savesegment(fs, prev_fsindex); - savesegment(gs, prev_gsindex); + save_fsgs(prev_p); /* * Load TLS before restoring any segments so that segment loads @@ -326,108 +452,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) if (unlikely(next->ds | prev->ds)) loadsegment(ds, next->ds); - /* - * Switch FS and GS. - * - * These are even more complicated than DS and ES: they have - * 64-bit bases are that controlled by arch_prctl. The bases - * don't necessarily match the selectors, as user code can do - * any number of things to cause them to be inconsistent. - * - * We don't promise to preserve the bases if the selectors are - * nonzero. We also don't promise to preserve the base if the - * selector is zero and the base doesn't match whatever was - * most recently passed to ARCH_SET_FS/GS. (If/when the - * FSGSBASE instructions are enabled, we'll need to offer - * stronger guarantees.) - * - * As an invariant, - * (fsbase != 0 && fsindex != 0) || (gsbase != 0 && gsindex != 0) is - * impossible. - */ - if (next->fsindex) { - /* Loading a nonzero value into FS sets the index and base. */ - loadsegment(fs, next->fsindex); - } else { - if (next->fsbase) { - /* Next index is zero but next base is nonzero. */ - if (prev_fsindex) - loadsegment(fs, 0); - wrmsrl(MSR_FS_BASE, next->fsbase); - } else { - /* Next base and index are both zero. */ - if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { - /* - * We don't know the previous base and can't - * find out without RDMSR. Forcibly clear it. - */ - loadsegment(fs, __USER_DS); - loadsegment(fs, 0); - } else { - /* - * If the previous index is zero and ARCH_SET_FS - * didn't change the base, then the base is - * also zero and we don't need to do anything. - */ - if (prev->fsbase || prev_fsindex) - loadsegment(fs, 0); - } - } - } - /* - * Save the old state and preserve the invariant. - * NB: if prev_fsindex == 0, then we can't reliably learn the base - * without RDMSR because Intel user code can zero it without telling - * us and AMD user code can program any 32-bit value without telling - * us. - */ - if (prev_fsindex) - prev->fsbase = 0; - prev->fsindex = prev_fsindex; - - if (next->gsindex) { - /* Loading a nonzero value into GS sets the index and base. */ - load_gs_index(next->gsindex); - } else { - if (next->gsbase) { - /* Next index is zero but next base is nonzero. */ - if (prev_gsindex) - load_gs_index(0); - wrmsrl(MSR_KERNEL_GS_BASE, next->gsbase); - } else { - /* Next base and index are both zero. */ - if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { - /* - * We don't know the previous base and can't - * find out without RDMSR. Forcibly clear it. - * - * This contains a pointless SWAPGS pair. - * Fixing it would involve an explicit check - * for Xen or a new pvop. - */ - load_gs_index(__USER_DS); - load_gs_index(0); - } else { - /* - * If the previous index is zero and ARCH_SET_GS - * didn't change the base, then the base is - * also zero and we don't need to do anything. - */ - if (prev->gsbase || prev_gsindex) - load_gs_index(0); - } - } - } - /* - * Save the old state and preserve the invariant. - * NB: if prev_gsindex == 0, then we can't reliably learn the base - * without RDMSR because Intel user code can zero it without telling - * us and AMD user code can program any 32-bit value without telling - * us. - */ - if (prev_gsindex) - prev->gsbase = 0; - prev->gsindex = prev_gsindex; + load_seg_legacy(prev->fsindex, prev->fsbase, + next->fsindex, next->fsbase, FS); + load_seg_legacy(prev->gsindex, prev->gsbase, + next->gsindex, next->gsbase, GS); switch_fpu_finish(next_fpu, cpu); diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 0bee04d41bed04406de00732cb1d73e5f6f32c33..eaa591cfd98b4d4f466f9a2afd38b508d9daffd4 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -1,6 +1,7 @@ /* * This file contains work-arounds for x86 and x86_64 platform bugs. */ +#include #include #include @@ -656,3 +657,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, quirk_intel_brickland_xeon_ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2083, quirk_intel_purley_xeon_ras_cap); #endif #endif + +bool x86_apple_machine; +EXPORT_SYMBOL(x86_apple_machine); + +void __init early_platform_quirks(void) +{ + x86_apple_machine = dmi_match(DMI_SYS_VENDOR, "Apple Inc.") || + dmi_match(DMI_SYS_VENDOR, "Apple Computer, Inc."); +} diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index a56bf6051f4e3707594b1b5ddab9711da9c27117..54180fa6f66fa8fe04c7528f054d642db522b617 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -38,8 +38,6 @@ void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); -static const struct desc_ptr no_idt = {}; - /* * This is set if we need to go through the 'emergency' path. * When machine_emergency_restart() is called, we may be on @@ -152,7 +150,7 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) /* * This is a single dmi_table handling all reboot quirks. */ -static struct dmi_system_id __initdata reboot_dmi_table[] = { +static const struct dmi_system_id reboot_dmi_table[] __initconst = { /* Acer */ { /* Handle reboot issue on Acer Aspire one */ @@ -638,7 +636,7 @@ static void native_machine_emergency_restart(void) break; case BOOT_TRIPLE: - load_idt(&no_idt); + idt_invalidate(NULL); __asm__ __volatile__("int3"); /* We're probably dead after this, but... */ diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 98111b38ebfd6eb9949242c5aae7b18bbbdb4489..307d3bac5f04ece485ac1fe42226ee111c0c6e85 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -47,6 +47,7 @@ relocate_kernel: * %rsi page_list * %rdx start address * %rcx preserve_context + * %r8 sme_active */ /* Save the CPU context, used for jumping back */ @@ -71,6 +72,9 @@ relocate_kernel: pushq $0 popfq + /* Save SME active flag */ + movq %r8, %r12 + /* * get physical address of control page now * this is impossible after page table switch @@ -132,6 +136,16 @@ identity_mapped: /* Flush the TLB (needed?) */ movq %r9, %cr3 + /* + * If SME is active, there could be old encrypted cache line + * entries that will conflict with the now unencrypted memory + * used by kexec. Flush the caches before copying the kernel. + */ + testq %r12, %r12 + jz 1f + wbinvd +1: + movq %rcx, %r11 call swap_pages diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 3486d04988000b05344a590ce9ab8c86e96d0ec2..0957dd73d127554803f35d5be45dcddb845ca741 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include ", short_cfo_a, short_cfo_b); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "Long CFO(Hz) ", long_cfo_a, long_cfo_b); + + /*SCFO*/ + value32 = odm_get_bb_reg(dm, 0xdb8, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xdb4, MASKDWORD); + + scfo_b = (s32)(value32 & 0x7ff); /*S(11,10)*/ + scfo_a = (s32)((value32 & 0x07ff0000) >> 16); + + if (scfo_a > 1023) + scfo_a = scfo_a - 2048; + + if (scfo_b > 1023) + scfo_b = scfo_b - 2048; + + scfo_a = scfo_a * 312500 / 1024; + scfo_b = scfo_b * 312500 / 1024; + + avg_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/ + avg_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16); + + if (avg_cfo_a > 4095) + avg_cfo_a = avg_cfo_a - 8192; + + if (avg_cfo_b > 4095) + avg_cfo_b = avg_cfo_b - 8192; + + avg_cfo_a = avg_cfo_a * 312500 / 4096; + avg_cfo_b = avg_cfo_b * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "value SCFO(Hz) ", scfo_a, scfo_b); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "Avg CFO(Hz) ", avg_cfo_a, avg_cfo_b); + + value32 = odm_get_bb_reg(dm, 0xdbc, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xde0, MASKDWORD); + + cfo_end_b = (s32)(value32 & 0x1fff); /*S(13,12)*/ + cfo_end_a = (s32)((value32 & 0x1fff0000) >> 16); + + if (cfo_end_a > 4095) + cfo_end_a = cfo_end_a - 8192; + + if (cfo_end_b > 4095) + cfo_end_b = cfo_end_b - 8192; + + cfo_end_a = cfo_end_a * 312500 / 4096; + cfo_end_b = cfo_end_b * 312500 / 4096; + + acq_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/ + acq_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16); + + if (acq_cfo_a > 4095) + acq_cfo_a = acq_cfo_a - 8192; + + if (acq_cfo_b > 4095) + acq_cfo_b = acq_cfo_b - 8192; + + acq_cfo_a = acq_cfo_a * 312500 / 4096; + acq_cfo_b = acq_cfo_b * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "End CFO(Hz) ", cfo_end_a, cfo_end_b); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "ACQ CFO(Hz) ", acq_cfo_a, acq_cfo_b); +} + +static void phydm_bb_debug_info(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + char *tmp_string = NULL; + + u8 rx_ht_bw, rx_vht_bw, rxsc, rx_ht, rx_bw; + static u8 v_rx_bw; + u32 value32, value32_1, value32_2, value32_3; + s32 sfo_a, sfo_b, sfo_c, sfo_d; + s32 lfo_a, lfo_b, lfo_c, lfo_d; + static u8 MCSS, tail, parity, rsv, vrsv, idx, smooth, htsound, agg, + stbc, vstbc, fec, fecext, sgi, sgiext, htltf, vgid, v_nsts, + vtxops, vrsv2, vbrsv, bf, vbcrc; + static u16 h_length, htcrc8, length; + static u16 vpaid; + static u16 v_length, vhtcrc8, v_mcss, v_tail, vb_tail; + static u8 hmcss, hrx_bw; + + u8 pwdb; + s8 rxevm_0, rxevm_1, rxevm_2; + u8 rf_gain_path_a, rf_gain_path_b, rf_gain_path_c, rf_gain_path_d; + u8 rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, rx_snr_path_d; + s32 sig_power; + + const char *L_rate[8] = {"6M", "9M", "12M", "18M", + "24M", "36M", "48M", "54M"}; + + if (dm->support_ic_type & ODM_IC_11N_SERIES) { + phydm_bb_debug_info_n_series(dm, &used, output, &out_len); + return; + } + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s\n", + "BB Report Info"); + + /*BW & mode Detection*/ + + value32 = odm_get_bb_reg(dm, 0xf80, MASKDWORD); + value32_2 = value32; + rx_ht_bw = (u8)(value32 & 0x1); + rx_vht_bw = (u8)((value32 >> 1) & 0x3); + rxsc = (u8)(value32 & 0x78); + value32_1 = (value32 & 0x180) >> 7; + rx_ht = (u8)(value32_1); + + rx_bw = 0; + + if (rx_ht == 2) { + if (rx_vht_bw == 0) + tmp_string = "20M"; + else if (rx_vht_bw == 1) + tmp_string = "40M"; + else + tmp_string = "80M"; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s %s %s", "mode", "VHT", tmp_string); + rx_bw = rx_vht_bw; + } else if (rx_ht == 1) { + if (rx_ht_bw == 0) + tmp_string = "20M"; + else if (rx_ht_bw == 1) + tmp_string = "40M"; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s %s %s", "mode", "HT", tmp_string); + rx_bw = rx_ht_bw; + } else { + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s %s", + "mode", "Legacy"); + } + if (rx_ht != 0) { + if (rxsc == 0) + tmp_string = "duplicate/full bw"; + else if (rxsc == 1) + tmp_string = "usc20-1"; + else if (rxsc == 2) + tmp_string = "lsc20-1"; + else if (rxsc == 3) + tmp_string = "usc20-2"; + else if (rxsc == 4) + tmp_string = "lsc20-2"; + else if (rxsc == 9) + tmp_string = "usc40"; + else if (rxsc == 10) + tmp_string = "lsc40"; + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s", + tmp_string); + } + + /* RX signal power and AGC related info*/ + + value32 = odm_get_bb_reg(dm, 0xF90, MASKDWORD); + pwdb = (u8)((value32 & MASKBYTE1) >> 8); + pwdb = pwdb >> 1; + sig_power = -110 + pwdb; + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "OFDM RX Signal Power(dB)", sig_power); + + value32 = odm_get_bb_reg(dm, 0xd14, MASKDWORD); + rx_snr_path_a = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_a = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_a *= 2; + value32 = odm_get_bb_reg(dm, 0xd54, MASKDWORD); + rx_snr_path_b = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_b = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_b *= 2; + value32 = odm_get_bb_reg(dm, 0xd94, MASKDWORD); + rx_snr_path_c = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_c = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_c *= 2; + value32 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD); + rx_snr_path_d = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_d = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_d *= 2; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d / %d", + "OFDM RX RF Gain(A/B/C/D)", rf_gain_path_a, + rf_gain_path_b, rf_gain_path_c, rf_gain_path_d); + + /* RX counter related info*/ + + value32 = odm_get_bb_reg(dm, 0xF08, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "OFDM CCA counter", ((value32 & 0xFFFF0000) >> 16)); + + value32 = odm_get_bb_reg(dm, 0xFD0, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "OFDM SBD Fail counter", value32 & 0xFFFF); + + value32 = odm_get_bb_reg(dm, 0xFC4, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "VHT SIGA/SIGB CRC8 Fail counter", value32 & 0xFFFF, + ((value32 & 0xFFFF0000) >> 16)); + + value32 = odm_get_bb_reg(dm, 0xFCC, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "CCK CCA counter", value32 & 0xFFFF); + + value32 = odm_get_bb_reg(dm, 0xFBC, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "LSIG (parity Fail/rate Illegal) counter", + value32 & 0xFFFF, ((value32 & 0xFFFF0000) >> 16)); + + value32_1 = odm_get_bb_reg(dm, 0xFC8, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xFC0, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "HT/VHT MCS NOT SUPPORT counter", + ((value32_2 & 0xFFFF0000) >> 16), value32_1 & 0xFFFF); + + /* PostFFT related info*/ + value32 = odm_get_bb_reg(dm, 0xF8c, MASKDWORD); + rxevm_0 = (s8)((value32 & MASKBYTE2) >> 16); + rxevm_0 /= 2; + if (rxevm_0 < -63) + rxevm_0 = 0; + + rxevm_1 = (s8)((value32 & MASKBYTE3) >> 24); + rxevm_1 /= 2; + value32 = odm_get_bb_reg(dm, 0xF88, MASKDWORD); + rxevm_2 = (s8)((value32 & MASKBYTE2) >> 16); + rxevm_2 /= 2; + + if (rxevm_1 < -63) + rxevm_1 = 0; + if (rxevm_2 < -63) + rxevm_2 = 0; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d", "RXEVM (1ss/2ss/3ss)", + rxevm_0, rxevm_1, rxevm_2); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)", + rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, + rx_snr_path_d); + + value32 = odm_get_bb_reg(dm, 0xF8C, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "CSI_1st /CSI_2nd", value32 & 0xFFFF, + ((value32 & 0xFFFF0000) >> 16)); + + /*BW & mode Detection*/ + + /*Reset Page F counter*/ + odm_set_bb_reg(dm, 0xB58, BIT(0), 1); + odm_set_bb_reg(dm, 0xB58, BIT(0), 0); + + /*CFO Report Info*/ + /*Short CFO*/ + value32 = odm_get_bb_reg(dm, 0xd0c, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xd4c, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xd8c, MASKDWORD); + value32_3 = odm_get_bb_reg(dm, 0xdcc, MASKDWORD); + + sfo_a = (s32)(value32 & 0xfff); + sfo_b = (s32)(value32_1 & 0xfff); + sfo_c = (s32)(value32_2 & 0xfff); + sfo_d = (s32)(value32_3 & 0xfff); + + lfo_a = (s32)(value32 >> 16); + lfo_b = (s32)(value32_1 >> 16); + lfo_c = (s32)(value32_2 >> 16); + lfo_d = (s32)(value32_3 >> 16); + + /*SFO 2's to dec*/ + if (sfo_a > 2047) + sfo_a = sfo_a - 4096; + sfo_a = (sfo_a * 312500) / 2048; + if (sfo_b > 2047) + sfo_b = sfo_b - 4096; + sfo_b = (sfo_b * 312500) / 2048; + if (sfo_c > 2047) + sfo_c = sfo_c - 4096; + sfo_c = (sfo_c * 312500) / 2048; + if (sfo_d > 2047) + sfo_d = sfo_d - 4096; + sfo_d = (sfo_d * 312500) / 2048; + + /*LFO 2's to dec*/ + + if (lfo_a > 4095) + lfo_a = lfo_a - 8192; + + if (lfo_b > 4095) + lfo_b = lfo_b - 8192; + + if (lfo_c > 4095) + lfo_c = lfo_c - 8192; + + if (lfo_d > 4095) + lfo_d = lfo_d - 8192; + lfo_a = lfo_a * 312500 / 4096; + lfo_b = lfo_b * 312500 / 4096; + lfo_c = lfo_c * 312500 / 4096; + lfo_d = lfo_d * 312500 / 4096; + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "CFO Report Info"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", + "Short CFO(Hz) ", sfo_a, sfo_b, sfo_c, sfo_d); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", + "Long CFO(Hz) ", lfo_a, lfo_b, lfo_c, lfo_d); + + /*SCFO*/ + value32 = odm_get_bb_reg(dm, 0xd10, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xd50, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xd90, MASKDWORD); + value32_3 = odm_get_bb_reg(dm, 0xdd0, MASKDWORD); + + sfo_a = (s32)(value32 & 0x7ff); + sfo_b = (s32)(value32_1 & 0x7ff); + sfo_c = (s32)(value32_2 & 0x7ff); + sfo_d = (s32)(value32_3 & 0x7ff); + + if (sfo_a > 1023) + sfo_a = sfo_a - 2048; + + if (sfo_b > 2047) + sfo_b = sfo_b - 4096; + + if (sfo_c > 2047) + sfo_c = sfo_c - 4096; + + if (sfo_d > 2047) + sfo_d = sfo_d - 4096; + + sfo_a = sfo_a * 312500 / 1024; + sfo_b = sfo_b * 312500 / 1024; + sfo_c = sfo_c * 312500 / 1024; + sfo_d = sfo_d * 312500 / 1024; + + lfo_a = (s32)(value32 >> 16); + lfo_b = (s32)(value32_1 >> 16); + lfo_c = (s32)(value32_2 >> 16); + lfo_d = (s32)(value32_3 >> 16); + + if (lfo_a > 4095) + lfo_a = lfo_a - 8192; + + if (lfo_b > 4095) + lfo_b = lfo_b - 8192; + + if (lfo_c > 4095) + lfo_c = lfo_c - 8192; + + if (lfo_d > 4095) + lfo_d = lfo_d - 8192; + lfo_a = lfo_a * 312500 / 4096; + lfo_b = lfo_b * 312500 / 4096; + lfo_c = lfo_c * 312500 / 4096; + lfo_d = lfo_d * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", + "value SCFO(Hz) ", sfo_a, sfo_b, sfo_c, sfo_d); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", "ACQ CFO(Hz) ", + lfo_a, lfo_b, lfo_c, lfo_d); + + value32 = odm_get_bb_reg(dm, 0xd14, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xd54, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xd94, MASKDWORD); + value32_3 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD); + + lfo_a = (s32)(value32 >> 16); + lfo_b = (s32)(value32_1 >> 16); + lfo_c = (s32)(value32_2 >> 16); + lfo_d = (s32)(value32_3 >> 16); + + if (lfo_a > 4095) + lfo_a = lfo_a - 8192; + + if (lfo_b > 4095) + lfo_b = lfo_b - 8192; + + if (lfo_c > 4095) + lfo_c = lfo_c - 8192; + + if (lfo_d > 4095) + lfo_d = lfo_d - 8192; + + lfo_a = lfo_a * 312500 / 4096; + lfo_b = lfo_b * 312500 / 4096; + lfo_c = lfo_c * 312500 / 4096; + lfo_d = lfo_d * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", "End CFO(Hz) ", + lfo_a, lfo_b, lfo_c, lfo_d); + + value32 = odm_get_bb_reg(dm, 0xf20, MASKDWORD); /*L SIG*/ + + tail = (u8)((value32 & 0xfc0000) >> 16); + parity = (u8)((value32 & 0x20000) >> 16); + length = (u16)((value32 & 0x1ffe00) >> 8); + rsv = (u8)(value32 & 0x10); + MCSS = (u8)(value32 & 0x0f); + + switch (MCSS) { + case 0x0b: + idx = 0; + break; + case 0x0f: + idx = 1; + break; + case 0x0a: + idx = 2; + break; + case 0x0e: + idx = 3; + break; + case 0x09: + idx = 4; + break; + case 0x08: + idx = 5; + break; + case 0x0c: + idx = 6; + break; + default: + idx = 6; + break; + } + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "L-SIG"); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s : %s", "rate", + L_rate[idx]); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x", "Rsv/length/parity", rsv, + rx_bw, length); + + value32 = odm_get_bb_reg(dm, 0xf2c, MASKDWORD); /*HT SIG*/ + if (rx_ht == 1) { + hmcss = (u8)(value32 & 0x7F); + hrx_bw = (u8)(value32 & 0x80); + h_length = (u16)((value32 >> 8) & 0xffff); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "HT-SIG1"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x", "MCS/BW/length", hmcss, + hrx_bw, h_length); + + value32 = odm_get_bb_reg(dm, 0xf30, MASKDWORD); /*HT SIG*/ + + if (rx_ht == 1) { + smooth = (u8)(value32 & 0x01); + htsound = (u8)(value32 & 0x02); + rsv = (u8)(value32 & 0x04); + agg = (u8)(value32 & 0x08); + stbc = (u8)(value32 & 0x30); + fec = (u8)(value32 & 0x40); + sgi = (u8)(value32 & 0x80); + htltf = (u8)((value32 & 0x300) >> 8); + htcrc8 = (u16)((value32 & 0x3fc00) >> 8); + tail = (u8)((value32 & 0xfc0000) >> 16); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "HT-SIG2"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x / %x / %x", + "Smooth/NoSound/Rsv/Aggregate/STBC/LDPC", smooth, + htsound, rsv, agg, stbc, fec); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x", + "SGI/E-HT-LTFs/CRC/tail", sgi, htltf, htcrc8, tail); + + value32 = odm_get_bb_reg(dm, 0xf2c, MASKDWORD); /*VHT SIG A1*/ + if (rx_ht == 2) { + /* value32 = odm_get_bb_reg(dm, 0xf2c,MASKDWORD);*/ + v_rx_bw = (u8)(value32 & 0x03); + vrsv = (u8)(value32 & 0x04); + vstbc = (u8)(value32 & 0x08); + vgid = (u8)((value32 & 0x3f0) >> 4); + v_nsts = (u8)(((value32 & 0x1c00) >> 8) + 1); + vpaid = (u16)(value32 & 0x3fe); + vtxops = (u8)((value32 & 0x400000) >> 20); + vrsv2 = (u8)((value32 & 0x800000) >> 20); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "VHT-SIG-A1"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x / %x", + "BW/Rsv1/STBC/GID/Nsts/PAID/TXOPPS/Rsv2", v_rx_bw, vrsv, + vstbc, vgid, v_nsts, vpaid, vtxops, vrsv2); + + value32 = odm_get_bb_reg(dm, 0xf30, MASKDWORD); /*VHT SIG*/ + + if (rx_ht == 2) { + /*value32 = odm_get_bb_reg(dm, 0xf30,MASKDWORD); */ /*VHT SIG*/ + + /* sgi=(u8)(value32&0x01); */ + sgiext = (u8)(value32 & 0x03); + /* fec = (u8)(value32&0x04); */ + fecext = (u8)(value32 & 0x0C); + + v_mcss = (u8)(value32 & 0xf0); + bf = (u8)((value32 & 0x100) >> 8); + vrsv = (u8)((value32 & 0x200) >> 8); + vhtcrc8 = (u16)((value32 & 0x3fc00) >> 8); + v_tail = (u8)((value32 & 0xfc0000) >> 16); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "VHT-SIG-A2"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x", + "SGI/FEC/MCS/BF/Rsv/CRC/tail", sgiext, fecext, v_mcss, + bf, vrsv, vhtcrc8, v_tail); + + value32 = odm_get_bb_reg(dm, 0xf34, MASKDWORD); /*VHT SIG*/ + { + v_length = (u16)(value32 & 0x1fffff); + vbrsv = (u8)((value32 & 0x600000) >> 20); + vb_tail = (u16)((value32 & 0x1f800000) >> 20); + vbcrc = (u8)((value32 & 0x80000000) >> 28); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "VHT-SIG-B"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x", "length/Rsv/tail/CRC", + v_length, vbrsv, vb_tail, vbcrc); + + /*for Condition number*/ + if (dm->support_ic_type & ODM_RTL8822B) { + s32 condition_num = 0; + char *factor = NULL; + + /*enable report condition number*/ + odm_set_bb_reg(dm, 0x1988, BIT(22), 0x1); + + condition_num = odm_get_bb_reg(dm, 0xf84, MASKDWORD); + condition_num = (condition_num & 0x3ffff) >> 4; + + if (*dm->band_width == ODM_BW80M) { + factor = "256/234"; + } else if (*dm->band_width == ODM_BW40M) { + factor = "128/108"; + } else if (*dm->band_width == ODM_BW20M) { + if (rx_ht == 2 || rx_ht == 1) + factor = "64/52"; /*HT or VHT*/ + else + factor = "64/48"; /*legacy*/ + } + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d (factor = %s)", + "Condition number", condition_num, factor); + } +} + +void phydm_basic_dbg_message(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct false_alarm_stat *false_alm_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + struct cfo_tracking *cfo_track = + (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK); + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct ra_table *ra_tab = &dm->dm_ra_table; + u16 macid, phydm_macid, client_cnt = 0; + struct rtl_sta_info *entry; + s32 tmp_val = 0; + u8 tmp_val_u1 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "[PHYDM Common MSG] System up time: ((%d sec))----->\n", + dm->phydm_sys_up_time); + + if (dm->is_linked) { + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "ID=%d, BW=((%d)), CH=((%d))\n", + dm->curr_station_id, 20 << *dm->band_width, + *dm->channel); + + /*Print RX rate*/ + if (dm->rx_rate <= ODM_RATE11M) + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "[CCK AGC Report] LNA_idx = 0x%x, VGA_idx = 0x%x\n", + dm->cck_lna_idx, dm->cck_vga_idx); + else + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "[OFDM AGC Report] { 0x%x, 0x%x, 0x%x, 0x%x }\n", + dm->ofdm_agc_idx[0], dm->ofdm_agc_idx[1], + dm->ofdm_agc_idx[2], dm->ofdm_agc_idx[3]); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "RSSI: { %d, %d, %d, %d }, rx_rate:", + (dm->rssi_a == 0xff) ? 0 : dm->rssi_a, + (dm->rssi_b == 0xff) ? 0 : dm->rssi_b, + (dm->rssi_c == 0xff) ? 0 : dm->rssi_c, + (dm->rssi_d == 0xff) ? 0 : dm->rssi_d); + + phydm_print_rate(dm, dm->rx_rate, ODM_COMP_COMMON); + + /*Print TX rate*/ + for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) { + entry = dm->odm_sta_info[macid]; + if (!IS_STA_VALID(entry)) + continue; + + phydm_macid = (dm->platform2phydm_macid_table[macid]); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "TXRate [%d]:", + macid); + phydm_print_rate(dm, ra_tab->link_tx_rate[macid], + ODM_COMP_COMMON); + + client_cnt++; + + if (client_cnt == dm->number_linked_client) + break; + } + + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "TP { TX, RX, total} = {%d, %d, %d }Mbps, traffic_load = (%d))\n", + dm->tx_tp, dm->rx_tp, dm->total_tp, dm->traffic_load); + + tmp_val_u1 = + (cfo_track->crystal_cap > cfo_track->def_x_cap) ? + (cfo_track->crystal_cap - + cfo_track->def_x_cap) : + (cfo_track->def_x_cap - cfo_track->crystal_cap); + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "CFO_avg = ((%d kHz)) , CrystalCap_tracking = ((%s%d))\n", + cfo_track->CFO_ave_pre, + ((cfo_track->crystal_cap > cfo_track->def_x_cap) ? "+" : + "-"), + tmp_val_u1); + + /* Condition number */ + if (dm->support_ic_type == ODM_RTL8822B) { + tmp_val = phydm_get_condition_number_8822B(dm); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "Condition number = ((%d))\n", tmp_val); + } + + /*STBC or LDPC pkt*/ + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "LDPC = %s, STBC = %s\n", + (dm->phy_dbg_info.is_ldpc_pkt) ? "Y" : "N", + (dm->phy_dbg_info.is_stbc_pkt) ? "Y" : "N"); + } else { + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "No Link !!!\n"); + } + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, + false_alm_cnt->cnt_cca_all); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, + false_alm_cnt->cnt_all); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n", + false_alm_cnt->cnt_parity_fail, + false_alm_cnt->cnt_rate_illegal, + false_alm_cnt->cnt_crc8_fail, + false_alm_cnt->cnt_mcs_fail, + false_alm_cnt->cnt_fast_fsync, + false_alm_cnt->cnt_sb_search_fail); + + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "is_linked = %d, Num_client = %d, rssi_min = %d, current_igi = 0x%x, bNoisy=%d\n\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dig_tab->cur_ig_value, dm->noisy_decision); +} + +void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + char *cut = NULL; + char *ic_type = NULL; + u32 used = *_used; + u32 out_len = *_out_len; + u32 date = 0; + char *commit_by = NULL; + u32 release_ver = 0; + + PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n", + "% Basic Profile %"); + + if (dm->support_ic_type == ODM_RTL8188E) { + } else if (dm->support_ic_type == ODM_RTL8822B) { + ic_type = "RTL8822B"; + date = RELEASE_DATE_8822B; + commit_by = COMMIT_BY_8822B; + release_ver = RELEASE_VERSION_8822B; + } + + /* JJ ADD 20161014 */ + + PHYDM_SNPRINTF(output + used, out_len - used, + " %-35s: %s (MP Chip: %s)\n", "IC type", ic_type, + dm->is_mp_chip ? "Yes" : "No"); + + if (dm->cut_version == ODM_CUT_A) + cut = "A"; + else if (dm->cut_version == ODM_CUT_B) + cut = "B"; + else if (dm->cut_version == ODM_CUT_C) + cut = "C"; + else if (dm->cut_version == ODM_CUT_D) + cut = "D"; + else if (dm->cut_version == ODM_CUT_E) + cut = "E"; + else if (dm->cut_version == ODM_CUT_F) + cut = "F"; + else if (dm->cut_version == ODM_CUT_I) + cut = "I"; + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "cut version", cut); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n", + "PHY Parameter version", odm_get_hw_img_version(dm)); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n", + "PHY Parameter Commit date", date); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "PHY Parameter Commit by", commit_by); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n", + "PHY Parameter Release version", release_ver); + + { + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + PHYDM_SNPRINTF(output + used, out_len - used, + " %-35s: %d (Subversion: %d)\n", "FW version", + rtlhal->fw_version, rtlhal->fw_subversion); + } + /* 1 PHY DM version List */ + PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n", + "% PHYDM version %"); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Code base", PHYDM_CODE_BASE); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Release Date", PHYDM_RELEASE_DATE); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "adaptivity", ADAPTIVITY_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", "DIG", + DIG_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Dynamic BB PowerSaving", DYNAMIC_BBPWRSAV_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "CFO Tracking", CFO_TRACKING_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Antenna Diversity", ANTDIV_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Power Tracking", POWRTRACKING_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Dynamic TxPower", DYNAMIC_TXPWR_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "RA Info", RAINFO_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Auto channel Selection", ACS_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "EDCA Turbo", EDCATURBO_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "LA mode", DYNAMIC_LA_MODE); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Dynamic RX path", DYNAMIC_RX_PATH_VERSION); + + if (dm->support_ic_type & ODM_RTL8822B) + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "PHY config 8822B", PHY_CONFIG_VERSION_8822B); + + *_used = used; + *_out_len = out_len; +} + +void phydm_fw_trace_en_h2c(void *dm_void, bool enable, u32 fw_debug_component, + u32 monitor_mode, u32 macid) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 h2c_parameter[7] = {0}; + u8 cmd_length; + + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + h2c_parameter[0] = enable; + h2c_parameter[1] = (u8)(fw_debug_component & MASKBYTE0); + h2c_parameter[2] = (u8)((fw_debug_component & MASKBYTE1) >> 8); + h2c_parameter[3] = (u8)((fw_debug_component & MASKBYTE2) >> 16); + h2c_parameter[4] = (u8)((fw_debug_component & MASKBYTE3) >> 24); + h2c_parameter[5] = (u8)monitor_mode; + h2c_parameter[6] = (u8)macid; + cmd_length = 7; + + } else { + h2c_parameter[0] = enable; + h2c_parameter[1] = (u8)monitor_mode; + h2c_parameter[2] = (u8)macid; + cmd_length = 3; + } + + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "---->\n"); + if (monitor_mode == 0) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[H2C] FW_debug_en: (( %d ))\n", enable); + else + ODM_RT_TRACE( + dm, ODM_FW_DEBUG_TRACE, + "[H2C] FW_debug_en: (( %d )), mode: (( %d )), macid: (( %d ))\n", + enable, monitor_mode, macid); + odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_TRACE_EN, cmd_length, h2c_parameter); +} + +bool phydm_api_set_txagc(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate, + bool is_single_rate) +{ + bool ret = false; + + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) { + if (is_single_rate) { + if (dm->support_ic_type == ODM_RTL8822B) + ret = phydm_write_txagc_1byte_8822b( + dm, power_index, path, hw_rate); + + } else { + if (dm->support_ic_type == ODM_RTL8822B) + ret = config_phydm_write_txagc_8822b( + dm, power_index, path, hw_rate); + } + } + + return ret; +} + +static u8 phydm_api_get_txagc(struct phy_dm_struct *dm, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u8 ret = 0; + + if (dm->support_ic_type & ODM_RTL8822B) + ret = config_phydm_read_txagc_8822b(dm, path, hw_rate); + + return ret; +} + +static bool phydm_api_switch_bw_channel(struct phy_dm_struct *dm, u8 central_ch, + u8 primary_ch_idx, + enum odm_bw bandwidth) +{ + bool ret = false; + + if (dm->support_ic_type & ODM_RTL8822B) + ret = config_phydm_switch_channel_bw_8822b( + dm, central_ch, primary_ch_idx, bandwidth); + + return ret; +} + +bool phydm_api_trx_mode(struct phy_dm_struct *dm, enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path) +{ + bool ret = false; + + if (dm->support_ic_type & ODM_RTL8822B) + ret = config_phydm_trx_mode_8822b(dm, tx_path, rx_path, + is_tx2_path); + + return ret; +} + +static void phydm_get_per_path_txagc(void *dm_void, u8 path, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 rate_idx; + u8 txagc; + u32 used = *_used; + u32 out_len = *_out_len; + + if (((dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) && + (path <= ODM_RF_PATH_B)) || + ((dm->support_ic_type & (ODM_RTL8821C)) && + (path <= ODM_RF_PATH_A))) { + for (rate_idx = 0; rate_idx <= 0x53; rate_idx++) { + if (rate_idx == ODM_RATE1M) + PHYDM_SNPRINTF(output + used, out_len - used, + " %-35s\n", "CCK====>"); + else if (rate_idx == ODM_RATE6M) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "OFDM====>"); + else if (rate_idx == ODM_RATEMCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 1ss====>"); + else if (rate_idx == ODM_RATEMCS8) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 2ss====>"); + else if (rate_idx == ODM_RATEMCS16) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 3ss====>"); + else if (rate_idx == ODM_RATEMCS24) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 4ss====>"); + else if (rate_idx == ODM_RATEVHTSS1MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 1ss====>"); + else if (rate_idx == ODM_RATEVHTSS2MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 2ss====>"); + else if (rate_idx == ODM_RATEVHTSS3MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 3ss====>"); + else if (rate_idx == ODM_RATEVHTSS4MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 4ss====>"); + + txagc = phydm_api_get_txagc( + dm, (enum odm_rf_radio_path)path, rate_idx); + if (config_phydm_read_txagc_check(txagc)) + PHYDM_SNPRINTF(output + used, out_len - used, + " 0x%02x ", txagc); + else + PHYDM_SNPRINTF(output + used, out_len - used, + " 0x%s ", "xx"); + } + } +} + +static void phydm_get_txagc(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + /* path-A */ + PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n", + "path-A===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_A, _used, output, _out_len); + + /* path-B */ + PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n", + "path-B===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_B, _used, output, _out_len); + + /* path-C */ + PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n", + "path-C===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_C, _used, output, _out_len); + + /* path-D */ + PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n", + "path-D===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_D, _used, output, _out_len); +} + +static void phydm_set_txagc(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + /*dm_value[1] = path*/ + /*dm_value[2] = hw_rate*/ + /*dm_value[3] = power_index*/ + + if (dm->support_ic_type & + (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)) { + if (dm_value[1] <= 1) { + phydm_check_dmval_txagc(dm, used, out_len, dm_value, + output); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, + " %s%d %s%x%s\n", "Write path-", + (dm_value[1] & 0x1), "rate index-0x", + (dm_value[2] & 0x7f), " fail"); + } + } +} + +static void phydm_debug_trace(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 pre_debug_components, one = 1; + u32 used = *_used; + u32 out_len = *_out_len; + + pre_debug_components = dm->debug_components; + + PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n", + "================================"); + if (dm_value[0] == 100) { + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "[Debug Message] PhyDM Selection"); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + PHYDM_SNPRINTF(output + used, out_len - used, + "00. (( %s ))DIG\n", + ((dm->debug_components & ODM_COMP_DIG) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "01. (( %s ))RA_MASK\n", + ((dm->debug_components & ODM_COMP_RA_MASK) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, + "02. (( %s ))DYNAMIC_TXPWR\n", + ((dm->debug_components & ODM_COMP_DYNAMIC_TXPWR) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "03. (( %s ))FA_CNT\n", + ((dm->debug_components & ODM_COMP_FA_CNT) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "04. (( %s ))RSSI_MONITOR\n", + ((dm->debug_components & ODM_COMP_RSSI_MONITOR) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "05. (( %s ))SNIFFER\n", + ((dm->debug_components & ODM_COMP_SNIFFER) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "06. (( %s ))ANT_DIV\n", + ((dm->debug_components & ODM_COMP_ANT_DIV) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "07. (( %s ))DFS\n", + ((dm->debug_components & ODM_COMP_DFS) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "08. (( %s ))NOISY_DETECT\n", + ((dm->debug_components & ODM_COMP_NOISY_DETECT) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, + "09. (( %s ))RATE_ADAPTIVE\n", + ((dm->debug_components & ODM_COMP_RATE_ADAPTIVE) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "10. (( %s ))PATH_DIV\n", + ((dm->debug_components & ODM_COMP_PATH_DIV) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, + "12. (( %s ))DYNAMIC_PRICCA\n", + ((dm->debug_components & ODM_COMP_DYNAMIC_PRICCA) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "14. (( %s ))MP\n", + ((dm->debug_components & ODM_COMP_MP) ? ("V") : ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "15. (( %s ))struct cfo_tracking\n", + ((dm->debug_components & ODM_COMP_CFO_TRACKING) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "16. (( %s ))struct acs_info\n", + ((dm->debug_components & ODM_COMP_ACS) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "17. (( %s ))ADAPTIVITY\n", + ((dm->debug_components & PHYDM_COMP_ADAPTIVITY) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "18. (( %s ))RA_DBG\n", + ((dm->debug_components & PHYDM_COMP_RA_DBG) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "19. (( %s ))TXBF\n", + ((dm->debug_components & PHYDM_COMP_TXBF) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "20. (( %s ))EDCA_TURBO\n", + ((dm->debug_components & ODM_COMP_EDCA_TURBO) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "22. (( %s ))FW_DEBUG_TRACE\n", + ((dm->debug_components & ODM_FW_DEBUG_TRACE) ? + ("V") : + ("."))); + + PHYDM_SNPRINTF(output + used, out_len - used, + "24. (( %s ))TX_PWR_TRACK\n", + ((dm->debug_components & ODM_COMP_TX_PWR_TRACK) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "26. (( %s ))CALIBRATION\n", + ((dm->debug_components & ODM_COMP_CALIBRATION) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "28. (( %s ))PHY_CONFIG\n", + ((dm->debug_components & ODM_PHY_CONFIG) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "29. (( %s ))INIT\n", + ((dm->debug_components & ODM_COMP_INIT) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "30. (( %s ))COMMON\n", + ((dm->debug_components & ODM_COMP_COMMON) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "31. (( %s ))API\n", + ((dm->debug_components & ODM_COMP_API) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + + } else if (dm_value[0] == 101) { + dm->debug_components = 0; + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "Disable all debug components"); + } else { + if (dm_value[1] == 1) /*enable*/ + dm->debug_components |= (one << dm_value[0]); + else if (dm_value[1] == 2) /*disable*/ + dm->debug_components &= ~(one << dm_value[0]); + else + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "[Warning!!!] 1:enable, 2:disable"); + } + PHYDM_SNPRINTF(output + used, out_len - used, + "pre-DbgComponents = 0x%x\n", pre_debug_components); + PHYDM_SNPRINTF(output + used, out_len - used, + "Curr-DbgComponents = 0x%x\n", dm->debug_components); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); +} + +static void phydm_fw_debug_trace(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 pre_fw_debug_components, one = 1; + u32 used = *_used; + u32 out_len = *_out_len; + + pre_fw_debug_components = dm->fw_debug_components; + + PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n", + "================================"); + if (dm_value[0] == 100) { + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "[FW Debug Component]"); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + PHYDM_SNPRINTF( + output + used, out_len - used, "00. (( %s ))RA\n", + ((dm->fw_debug_components & PHYDM_FW_COMP_RA) ? ("V") : + ("."))); + + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "01. (( %s ))MU\n", + ((dm->fw_debug_components & PHYDM_FW_COMP_MU) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "02. (( %s ))path Div\n", + ((dm->fw_debug_components & + PHYDM_FW_COMP_PHY_CONFIG) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "03. (( %s ))Phy Config\n", + ((dm->fw_debug_components & + PHYDM_FW_COMP_PHY_CONFIG) ? + ("V") : + ("."))); + } + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + + } else { + if (dm_value[0] == 101) { + dm->fw_debug_components = 0; + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "Clear all fw debug components"); + } else { + if (dm_value[1] == 1) /*enable*/ + dm->fw_debug_components |= (one << dm_value[0]); + else if (dm_value[1] == 2) /*disable*/ + dm->fw_debug_components &= + ~(one << dm_value[0]); + else + PHYDM_SNPRINTF( + output + used, out_len - used, "%s\n", + "[Warning!!!] 1:enable, 2:disable"); + } + + if (dm->fw_debug_components == 0) { + dm->debug_components &= ~ODM_FW_DEBUG_TRACE; + phydm_fw_trace_en_h2c( + dm, false, dm->fw_debug_components, dm_value[2], + dm_value[3]); /*H2C to enable C2H Msg*/ + } else { + dm->debug_components |= ODM_FW_DEBUG_TRACE; + phydm_fw_trace_en_h2c( + dm, true, dm->fw_debug_components, dm_value[2], + dm_value[3]); /*H2C to enable C2H Msg*/ + } + } +} + +static void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 addr = 0; + u32 used = *_used; + u32 out_len = *_out_len; + + /* For Nseries IC we only need to dump page8 to pageF using 3 digits*/ + for (addr = 0x800; addr < 0xfff; addr += 4) { + if (dm->support_ic_type & ODM_IC_11N_SERIES) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%03x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + else + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + + if (dm->support_ic_type & + (ODM_RTL8822B | ODM_RTL8814A | ODM_RTL8821C)) { + if (dm->rf_type > ODM_2T2R) { + for (addr = 0x1800; addr < 0x18ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + + if (dm->rf_type > ODM_3T3R) { + for (addr = 0x1a00; addr < 0x1aff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + + for (addr = 0x1900; addr < 0x19ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + for (addr = 0x1c00; addr < 0x1cff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + for (addr = 0x1f00; addr < 0x1fff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } +} + +static void phydm_dump_all_reg(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 addr = 0; + u32 used = *_used; + u32 out_len = *_out_len; + + /* dump MAC register */ + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "MAC==========\n"); + for (addr = 0; addr < 0x7ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + for (addr = 0x1000; addr < 0x17ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + /* dump BB register */ + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "BB==========\n"); + phydm_dump_bb_reg(dm, &used, output, &out_len); + + /* dump RF register */ + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-A==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_A, addr, + RFREGOFFSETMASK)); + + if (dm->rf_type > ODM_1T1R) { + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-B==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_B, addr, + RFREGOFFSETMASK)); + } + + if (dm->rf_type > ODM_2T2R) { + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-C==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_C, addr, + RFREGOFFSETMASK)); + } + + if (dm->rf_type > ODM_3T3R) { + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-D==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_D, addr, + RFREGOFFSETMASK)); + } +} + +static void phydm_enable_big_jump(struct phy_dm_struct *dm, bool state) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (!state) { + dm->dm_dig_table.enable_adjust_big_jump = false; + odm_set_bb_reg(dm, 0x8c8, 0xfe, + ((dig_tab->big_jump_step3 << 5) | + (dig_tab->big_jump_step2 << 3) | + dig_tab->big_jump_step1)); + } else { + dm->dm_dig_table.enable_adjust_big_jump = true; + } +} + +static void phydm_show_rx_rate(struct phy_dm_struct *dm, u32 *_used, + char *output, u32 *_out_len) +{ + u32 used = *_used; + u32 out_len = *_out_len; + + PHYDM_SNPRINTF(output + used, out_len - used, + "=====Rx SU rate Statistics=====\n"); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS0 = %d, 1SS MCS1 = %d, 1SS MCS2 = %d, 1SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[0], + dm->phy_dbg_info.num_qry_vht_pkt[1], + dm->phy_dbg_info.num_qry_vht_pkt[2], + dm->phy_dbg_info.num_qry_vht_pkt[3]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS4 = %d, 1SS MCS5 = %d, 1SS MCS6 = %d, 1SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[4], + dm->phy_dbg_info.num_qry_vht_pkt[5], + dm->phy_dbg_info.num_qry_vht_pkt[6], + dm->phy_dbg_info.num_qry_vht_pkt[7]); + PHYDM_SNPRINTF(output + used, out_len - used, + "1SS MCS8 = %d, 1SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[8], + dm->phy_dbg_info.num_qry_vht_pkt[9]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS0 = %d, 2SS MCS1 = %d, 2SS MCS2 = %d, 2SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[10], + dm->phy_dbg_info.num_qry_vht_pkt[11], + dm->phy_dbg_info.num_qry_vht_pkt[12], + dm->phy_dbg_info.num_qry_vht_pkt[13]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS4 = %d, 2SS MCS5 = %d, 2SS MCS6 = %d, 2SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[14], + dm->phy_dbg_info.num_qry_vht_pkt[15], + dm->phy_dbg_info.num_qry_vht_pkt[16], + dm->phy_dbg_info.num_qry_vht_pkt[17]); + PHYDM_SNPRINTF(output + used, out_len - used, + "2SS MCS8 = %d, 2SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[18], + dm->phy_dbg_info.num_qry_vht_pkt[19]); + + PHYDM_SNPRINTF(output + used, out_len - used, + "=====Rx MU rate Statistics=====\n"); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS0 = %d, 1SS MCS1 = %d, 1SS MCS2 = %d, 1SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[0], + dm->phy_dbg_info.num_qry_mu_vht_pkt[1], + dm->phy_dbg_info.num_qry_mu_vht_pkt[2], + dm->phy_dbg_info.num_qry_mu_vht_pkt[3]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS4 = %d, 1SS MCS5 = %d, 1SS MCS6 = %d, 1SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[4], + dm->phy_dbg_info.num_qry_mu_vht_pkt[5], + dm->phy_dbg_info.num_qry_mu_vht_pkt[6], + dm->phy_dbg_info.num_qry_mu_vht_pkt[7]); + PHYDM_SNPRINTF(output + used, out_len - used, + "1SS MCS8 = %d, 1SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[8], + dm->phy_dbg_info.num_qry_mu_vht_pkt[9]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS0 = %d, 2SS MCS1 = %d, 2SS MCS2 = %d, 2SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[10], + dm->phy_dbg_info.num_qry_mu_vht_pkt[11], + dm->phy_dbg_info.num_qry_mu_vht_pkt[12], + dm->phy_dbg_info.num_qry_mu_vht_pkt[13]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS4 = %d, 2SS MCS5 = %d, 2SS MCS6 = %d, 2SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[14], + dm->phy_dbg_info.num_qry_mu_vht_pkt[15], + dm->phy_dbg_info.num_qry_mu_vht_pkt[16], + dm->phy_dbg_info.num_qry_mu_vht_pkt[17]); + PHYDM_SNPRINTF(output + used, out_len - used, + "2SS MCS8 = %d, 2SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[18], + dm->phy_dbg_info.num_qry_mu_vht_pkt[19]); +} + +struct phydm_command { + char name[16]; + u8 id; +}; + +enum PHYDM_CMD_ID { + PHYDM_HELP, + PHYDM_DEMO, + PHYDM_RA, + PHYDM_PROFILE, + PHYDM_ANTDIV, + PHYDM_PATHDIV, + PHYDM_DEBUG, + PHYDM_FW_DEBUG, + PHYDM_SUPPORT_ABILITY, + PHYDM_GET_TXAGC, + PHYDM_SET_TXAGC, + PHYDM_SMART_ANT, + PHYDM_API, + PHYDM_TRX_PATH, + PHYDM_LA_MODE, + PHYDM_DUMP_REG, + PHYDM_MU_MIMO, + PHYDM_HANG, + PHYDM_BIG_JUMP, + PHYDM_SHOW_RXRATE, + PHYDM_NBI_EN, + PHYDM_CSI_MASK_EN, + PHYDM_DFS, + PHYDM_IQK, + PHYDM_NHM, + PHYDM_CLM, + PHYDM_BB_INFO, + PHYDM_TXBF, + PHYDM_PAUSE_DIG_EN, + PHYDM_H2C, + PHYDM_ANT_SWITCH, + PHYDM_DYNAMIC_RA_PATH, + PHYDM_PSD, + PHYDM_DEBUG_PORT +}; + +static struct phydm_command phy_dm_ary[] = { + {"-h", PHYDM_HELP}, /*do not move this element to other position*/ + {"demo", PHYDM_DEMO}, /*do not move this element to other position*/ + {"ra", PHYDM_RA}, + {"profile", PHYDM_PROFILE}, + {"antdiv", PHYDM_ANTDIV}, + {"pathdiv", PHYDM_PATHDIV}, + {"dbg", PHYDM_DEBUG}, + {"fw_dbg", PHYDM_FW_DEBUG}, + {"ability", PHYDM_SUPPORT_ABILITY}, + {"get_txagc", PHYDM_GET_TXAGC}, + {"set_txagc", PHYDM_SET_TXAGC}, + {"smtant", PHYDM_SMART_ANT}, + {"api", PHYDM_API}, + {"trxpath", PHYDM_TRX_PATH}, + {"lamode", PHYDM_LA_MODE}, + {"dumpreg", PHYDM_DUMP_REG}, + {"mu", PHYDM_MU_MIMO}, + {"hang", PHYDM_HANG}, + {"bigjump", PHYDM_BIG_JUMP}, + {"rxrate", PHYDM_SHOW_RXRATE}, + {"nbi", PHYDM_NBI_EN}, + {"csi_mask", PHYDM_CSI_MASK_EN}, + {"dfs", PHYDM_DFS}, + {"iqk", PHYDM_IQK}, + {"nhm", PHYDM_NHM}, + {"clm", PHYDM_CLM}, + {"bbinfo", PHYDM_BB_INFO}, + {"txbf", PHYDM_TXBF}, + {"pause_dig", PHYDM_PAUSE_DIG_EN}, + {"h2c", PHYDM_H2C}, + {"ant_switch", PHYDM_ANT_SWITCH}, + {"drp", PHYDM_DYNAMIC_RA_PATH}, + {"psd", PHYDM_PSD}, + {"dbgport", PHYDM_DEBUG_PORT}, +}; + +void phydm_cmd_parser(struct phy_dm_struct *dm, char input[][MAX_ARGV], + u32 input_num, u8 flag, char *output, u32 out_len) +{ + u32 used = 0; + u8 id = 0; + int var1[10] = {0}; + int i, input_idx = 0, phydm_ary_size; + char help[] = "-h"; + + bool is_enable_dbg_mode; + u8 central_ch, primary_ch_idx, bandwidth; + + if (flag == 0) { + PHYDM_SNPRINTF(output + used, out_len - used, + "GET, nothing to print\n"); + return; + } + + PHYDM_SNPRINTF(output + used, out_len - used, "\n"); + + /* Parsing Cmd ID */ + if (input_num) { + phydm_ary_size = + sizeof(phy_dm_ary) / sizeof(struct phydm_command); + for (i = 0; i < phydm_ary_size; i++) { + if (strcmp(phy_dm_ary[i].name, input[0]) == 0) { + id = phy_dm_ary[i].id; + break; + } + } + if (i == phydm_ary_size) { + PHYDM_SNPRINTF(output + used, out_len - used, + "SET, command not found!\n"); + return; + } + } + + switch (id) { + case PHYDM_HELP: { + PHYDM_SNPRINTF(output + used, out_len - used, "BB cmd ==>\n"); + for (i = 0; i < phydm_ary_size - 2; i++) { + PHYDM_SNPRINTF(output + used, out_len - used, + " %-5d: %s\n", i, + phy_dm_ary[i + 2].name); + /**/ + } + } break; + + case PHYDM_DEMO: { /*echo demo 10 0x3a z abcde >cmd*/ + u32 directory = 0; + + char char_temp; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &directory); + PHYDM_SNPRINTF(output + used, out_len - used, + "Decimal value = %d\n", directory); + PHYDM_SSCANF(input[2], DCMD_HEX, &directory); + PHYDM_SNPRINTF(output + used, out_len - used, + "Hex value = 0x%x\n", directory); + PHYDM_SSCANF(input[3], DCMD_CHAR, &char_temp); + PHYDM_SNPRINTF(output + used, out_len - used, "Char = %c\n", + char_temp); + PHYDM_SNPRINTF(output + used, out_len - used, "String = %s\n", + input[4]); + } break; + + case PHYDM_RA: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_RA_debug_PCR(dm, (u32 *)var1, &used, output, + &out_len); + } + + break; + + case PHYDM_ANTDIV: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + + input_idx++; + } + } + + break; + + case PHYDM_PATHDIV: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + + input_idx++; + } + } + + break; + + case PHYDM_DEBUG: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_debug_trace(dm, (u32 *)var1, &used, output, + &out_len); + } + + break; + + case PHYDM_FW_DEBUG: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) + phydm_fw_debug_trace(dm, (u32 *)var1, &used, output, + &out_len); + + break; + + case PHYDM_SUPPORT_ABILITY: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_support_ability_debug(dm, (u32 *)var1, &used, + output, &out_len); + } + + break; + + case PHYDM_SMART_ANT: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + break; + + case PHYDM_API: + if (!(dm->support_ic_type & + (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C))) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "This IC doesn't support PHYDM API function\n"); + } + + for (i = 0; i < 4; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + is_enable_dbg_mode = (bool)var1[0]; + central_ch = (u8)var1[1]; + primary_ch_idx = (u8)var1[2]; + bandwidth = (enum odm_bw)var1[3]; + + if (is_enable_dbg_mode) { + dm->is_disable_phy_api = false; + phydm_api_switch_bw_channel(dm, central_ch, + primary_ch_idx, + (enum odm_bw)bandwidth); + dm->is_disable_phy_api = true; + PHYDM_SNPRINTF( + output + used, out_len - used, + "central_ch = %d, primary_ch_idx = %d, bandwidth = %d\n", + central_ch, primary_ch_idx, bandwidth); + } else { + dm->is_disable_phy_api = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "Disable API debug mode\n"); + } + break; + + case PHYDM_PROFILE: /*echo profile, >cmd*/ + phydm_basic_profile(dm, &used, output, &out_len); + break; + + case PHYDM_GET_TXAGC: + phydm_get_txagc(dm, &used, output, &out_len); + break; + + case PHYDM_SET_TXAGC: { + bool is_enable_dbg_mode; + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if ((strcmp(input[1], help) == 0)) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "{En} {pathA~D(0~3)} {rate_idx(Hex), All_rate:0xff} {txagc_idx (Hex)}\n"); + /**/ + + } else { + is_enable_dbg_mode = (bool)var1[0]; + if (is_enable_dbg_mode) { + dm->is_disable_phy_api = false; + phydm_set_txagc(dm, (u32 *)var1, &used, output, + &out_len); + dm->is_disable_phy_api = true; + } else { + dm->is_disable_phy_api = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "Disable API debug mode\n"); + } + } + } break; + + case PHYDM_TRX_PATH: + + for (i = 0; i < 4; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) { + u8 tx_path, rx_path; + bool is_enable_dbg_mode, is_tx2_path; + + is_enable_dbg_mode = (bool)var1[0]; + tx_path = (u8)var1[1]; + rx_path = (u8)var1[2]; + is_tx2_path = (bool)var1[3]; + + if (is_enable_dbg_mode) { + dm->is_disable_phy_api = false; + phydm_api_trx_mode( + dm, (enum odm_rf_path)tx_path, + (enum odm_rf_path)rx_path, is_tx2_path); + dm->is_disable_phy_api = true; + PHYDM_SNPRINTF( + output + used, out_len - used, + "tx_path = 0x%x, rx_path = 0x%x, is_tx2_path = %d\n", + tx_path, rx_path, is_tx2_path); + } else { + dm->is_disable_phy_api = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "Disable API debug mode\n"); + } + } else { + phydm_config_trx_path(dm, (u32 *)var1, &used, output, + &out_len); + } + break; + + case PHYDM_LA_MODE: + + dm->support_ability &= ~(ODM_BB_FA_CNT); + phydm_lamode_trigger_setting(dm, &input[0], &used, output, + &out_len, input_num); + dm->support_ability |= ODM_BB_FA_CNT; + + break; + + case PHYDM_DUMP_REG: { + u8 type = 0; + + if (input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + type = (u8)var1[0]; + } + + if (type == 0) + phydm_dump_bb_reg(dm, &used, output, &out_len); + else if (type == 1) + phydm_dump_all_reg(dm, &used, output, &out_len); + } break; + + case PHYDM_MU_MIMO: + + if (input[1]) + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + else + var1[0] = 0; + + if (var1[0] == 1) { + PHYDM_SNPRINTF(output + used, out_len - used, + "Get MU BFee CSI\n"); + odm_set_bb_reg(dm, 0x9e8, BIT(17) | BIT(16), + 2); /*Read BFee*/ + odm_set_bb_reg(dm, 0x1910, BIT(15), + 1); /*Select BFee's CSI report*/ + odm_set_bb_reg(dm, 0x19b8, BIT(6), + 1); /*set as CSI report*/ + odm_set_bb_reg(dm, 0x19a8, 0xFFFF, + 0xFFFF); /*disable gated_clk*/ + phydm_print_csi(dm, used, out_len, output); + + } else if (var1[0] == 2) { + PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[1]); + PHYDM_SNPRINTF(output + used, out_len - used, + "Get MU BFer's STA%d CSI\n", var1[1]); + odm_set_bb_reg(dm, 0x9e8, BIT(24), 0); /*Read BFer*/ + odm_set_bb_reg(dm, 0x9e8, BIT(25), + 1); /*enable Read/Write RAM*/ + odm_set_bb_reg(dm, 0x9e8, BIT(30) | BIT(29) | BIT(28), + var1[1]); /*read which STA's CSI report*/ + odm_set_bb_reg(dm, 0x1910, BIT(15), + 0); /*select BFer's CSI*/ + odm_set_bb_reg(dm, 0x19e0, 0x00003FC0, + 0xFF); /*disable gated_clk*/ + phydm_print_csi(dm, used, out_len, output); + } + break; + + case PHYDM_BIG_JUMP: { + if (input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + phydm_enable_big_jump(dm, (bool)(var1[0])); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, + "unknown command!\n"); + } + break; + } + + case PHYDM_HANG: + phydm_bb_rx_hang_info(dm, &used, output, &out_len); + break; + + case PHYDM_SHOW_RXRATE: { + u8 rate_idx; + + if (input[1]) + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (var1[0] == 1) { + phydm_show_rx_rate(dm, &used, output, &out_len); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, + "Reset Rx rate counter\n"); + + for (rate_idx = 0; rate_idx < 40; rate_idx++) { + dm->phy_dbg_info.num_qry_vht_pkt[rate_idx] = 0; + dm->phy_dbg_info.num_qry_mu_vht_pkt[rate_idx] = + 0; + } + } + } break; + + case PHYDM_NBI_EN: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_api_debug(dm, PHYDM_API_NBI, (u32 *)var1, &used, + output, &out_len); + /**/ + } + + break; + + case PHYDM_CSI_MASK_EN: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_api_debug(dm, PHYDM_API_CSI_MASK, (u32 *)var1, + &used, output, &out_len); + /**/ + } + + break; + + case PHYDM_DFS: + break; + + case PHYDM_IQK: + break; + + case PHYDM_NHM: { + u8 target_rssi; + u16 nhm_period = 0xC350; /* 200ms */ + u8 IGI; + struct ccx_info *ccx_info = &dm->dm_ccx_info; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (input_num == 1) { + ccx_info->echo_NHM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Trigger NHM: echo nhm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Exclude CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Trigger NHM: echo nhm 2\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Include CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get NHM results: echo nhm 3\n"); + + return; + } + + /* NMH trigger */ + if ((var1[0] <= 2) && (var1[0] != 0)) { + ccx_info->echo_NHM_en = true; + ccx_info->echo_IGI = + (u8)odm_get_bb_reg(dm, 0xC50, MASKBYTE0); + + target_rssi = ccx_info->echo_IGI - 10; + + ccx_info->NHM_th[0] = (target_rssi - 15 + 10) * 2; + + for (i = 1; i <= 10; i++) + ccx_info->NHM_th[i] = + ccx_info->NHM_th[0] + 6 * i; + + /* 4 1. store previous NHM setting */ + phydm_nhm_setting(dm, STORE_NHM_SETTING); + + /* 4 2. Set NHM period, 0x990[31:16]=0xC350, + * Time duration for NHM unit: 4us, 0xC350=200ms + */ + ccx_info->NHM_period = nhm_period; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Monitor NHM for %d us", + nhm_period * 4); + + /* 4 3. Set NHM inexclude_txon, inexclude_cca, ccx_en */ + + ccx_info->nhm_inexclude_cca = (var1[0] == 1) ? + NHM_EXCLUDE_CCA : + NHM_INCLUDE_CCA; + ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON; + + phydm_nhm_setting(dm, SET_NHM_SETTING); + phydm_print_nhm_trigger(output, used, out_len, + ccx_info); + + /* 4 4. Trigger NHM */ + phydm_nhm_trigger(dm); + } + + /*Get NHM results*/ + else if (var1[0] == 3) { + IGI = (u8)odm_get_bb_reg(dm, 0xC50, MASKBYTE0); + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Cur_IGI = 0x%x", IGI); + + phydm_get_nhm_result(dm); + + /* 4 Resotre NHM setting */ + phydm_nhm_setting(dm, RESTORE_NHM_SETTING); + phydm_print_nhm_result(output, used, out_len, ccx_info); + + ccx_info->echo_NHM_en = false; + } else { + ccx_info->echo_NHM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Trigger NHM: echo nhm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Exclude CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Trigger NHM: echo nhm 2\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Include CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get NHM results: echo nhm 3\n"); + + return; + } + } break; + + case PHYDM_CLM: { + struct ccx_info *ccx_info = &dm->dm_ccx_info; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (input_num == 1) { + ccx_info->echo_CLM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Trigger CLM: echo clm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get CLM results: echo clm 2\n"); + return; + } + + /* Set & trigger CLM */ + if (var1[0] == 1) { + ccx_info->echo_CLM_en = true; + ccx_info->CLM_period = 0xC350; /*100ms*/ + phydm_clm_setting(dm); + phydm_clm_trigger(dm); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Monitor CLM for 200ms\n"); + } + + /* Get CLM results */ + else if (var1[0] == 2) { + ccx_info->echo_CLM_en = false; + phydm_get_cl_mresult(dm); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n CLM_result = %d us\n", + ccx_info->CLM_result * 4); + + } else { + ccx_info->echo_CLM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\n\r Error command !\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Trigger CLM: echo clm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get CLM results: echo clm 2\n"); + } + } break; + + case PHYDM_BB_INFO: { + s32 value32 = 0; + + phydm_bb_debug_info(dm, &used, output, &out_len); + + if (dm->support_ic_type & ODM_RTL8822B && input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + odm_set_bb_reg(dm, 0x1988, 0x003fff00, var1[0]); + value32 = odm_get_bb_reg(dm, 0xf84, MASKDWORD); + value32 = (value32 & 0xff000000) >> 24; + PHYDM_SNPRINTF( + output + used, out_len - used, + "\r\n %-35s = condition num = %d, subcarriers = %d\n", + "Over condition num subcarrier", var1[0], + value32); + odm_set_bb_reg(dm, 0x1988, BIT(22), + 0x0); /*disable report condition number*/ + } + } break; + + case PHYDM_TXBF: { + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n no TxBF !!\n"); + } break; + + case PHYDM_PAUSE_DIG_EN: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + if (var1[0] == 0) { + odm_pause_dig(dm, PHYDM_PAUSE, + PHYDM_PAUSE_LEVEL_7, (u8)var1[1]); + PHYDM_SNPRINTF(output + used, out_len - used, + "Set IGI_value = ((%x))\n", + var1[1]); + } else if (var1[0] == 1) { + odm_pause_dig(dm, PHYDM_RESUME, + PHYDM_PAUSE_LEVEL_7, (u8)var1[1]); + PHYDM_SNPRINTF(output + used, out_len - used, + "Resume IGI_value\n"); + } else { + PHYDM_SNPRINTF( + output + used, out_len - used, + "echo (1:pause, 2resume) (IGI_value)\n"); + } + } + break; + case PHYDM_H2C: + + for (i = 0; i < 8; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) + phydm_h2C_debug(dm, (u32 *)var1, &used, output, + &out_len); + + break; + + case PHYDM_ANT_SWITCH: + + for (i = 0; i < 8; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + PHYDM_SNPRINTF(output + used, out_len - used, + "Not Support IC"); + } + + break; + + case PHYDM_DYNAMIC_RA_PATH: + + PHYDM_SNPRINTF(output + used, out_len - used, "Not Support IC"); + + break; + + case PHYDM_PSD: + + phydm_psd_debug(dm, &input[0], &used, output, &out_len, + input_num); + + break; + + case PHYDM_DEBUG_PORT: { + u32 dbg_port_value; + + PHYDM_SSCANF(input[1], DCMD_HEX, &var1[0]); + + if (phydm_set_bb_dbg_port(dm, BB_DBGPORT_PRIORITY_3, + var1[0])) { /*set debug port to 0x0*/ + + dbg_port_value = phydm_get_bb_dbg_port_value(dm); + phydm_release_bb_dbg_port(dm); + + PHYDM_SNPRINTF(output + used, out_len - used, + "Debug Port[0x%x] = ((0x%x))\n", var1[1], + dbg_port_value); + } + } break; + + default: + PHYDM_SNPRINTF(output + used, out_len - used, + "SET, unknown command!\n"); + break; + } +} + +s32 phydm_cmd(struct phy_dm_struct *dm, char *input, u32 in_len, u8 flag, + char *output, u32 out_len) +{ + char *token; + u32 argc = 0; + char argv[MAX_ARGC][MAX_ARGV]; + + do { + token = strsep(&input, ", "); + if (token) { + strcpy(argv[argc], token); + argc++; + } else { + break; + } + } while (argc < MAX_ARGC); + + if (argc == 1) + argv[0][strlen(argv[0]) - 1] = '\0'; + + phydm_cmd_parser(dm, argv, argc, flag, output, out_len); + + return 0; +} + +void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /*u8 debug_trace_11byte[60];*/ + u8 freg_num, c2h_seq, buf_0 = 0; + + if (!(dm->support_ic_type & PHYDM_IC_3081_SERIES)) + return; + + if (cmd_len > 12) + return; + + buf_0 = cmd_buf[0]; + freg_num = (buf_0 & 0xf); + c2h_seq = (buf_0 & 0xf0) >> 4; + + if ((c2h_seq != dm->pre_c2h_seq) && !dm->fw_buff_is_enpty) { + dm->fw_debug_trace[dm->c2h_cmd_start] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW Dbg Queue Overflow] %s\n", + dm->fw_debug_trace); + dm->c2h_cmd_start = 0; + } + + if ((cmd_len - 1) > (60 - dm->c2h_cmd_start)) { + dm->fw_debug_trace[dm->c2h_cmd_start] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW Dbg Queue error: wrong C2H length] %s\n", + dm->fw_debug_trace); + dm->c2h_cmd_start = 0; + return; + } + + strncpy((char *)&dm->fw_debug_trace[dm->c2h_cmd_start], + (char *)&cmd_buf[1], (cmd_len - 1)); + dm->c2h_cmd_start += (cmd_len - 1); + dm->fw_buff_is_enpty = false; + + if (freg_num == 0 || dm->c2h_cmd_start >= 60) { + if (dm->c2h_cmd_start < 60) + dm->fw_debug_trace[dm->c2h_cmd_start] = '\0'; + else + dm->fw_debug_trace[59] = '\0'; + + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s\n", + dm->fw_debug_trace); + /*dbg_print("[FW DBG Msg] %s\n", dm->fw_debug_trace);*/ + dm->c2h_cmd_start = 0; + dm->fw_buff_is_enpty = true; + } + + dm->pre_c2h_seq = c2h_seq; +} + +void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 function = buffer[0]; + u8 dbg_num = buffer[1]; + u16 content_0 = (((u16)buffer[3]) << 8) | ((u16)buffer[2]); + u16 content_1 = (((u16)buffer[5]) << 8) | ((u16)buffer[4]); + u16 content_2 = (((u16)buffer[7]) << 8) | ((u16)buffer[6]); + u16 content_3 = (((u16)buffer[9]) << 8) | ((u16)buffer[8]); + u16 content_4 = (((u16)buffer[11]) << 8) | ((u16)buffer[10]); + + if (cmd_len > 12) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW Msg] Invalid cmd length (( %d )) >12\n", + cmd_len); + + /*--------------------------------------------*/ + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW][general][%d, %d, %d] = {%d, %d, %d, %d}\n", function, + dbg_num, content_0, content_1, content_2, content_3, + content_4); + /*--------------------------------------------*/ +} + +void phydm_fw_trace_handler_8051(void *dm_void, u8 *buffer, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + int i = 0; + u8 extend_c2h_sub_id = 0, extend_c2h_dbg_len = 0, + extend_c2h_dbg_seq = 0; + u8 fw_debug_trace[128]; + u8 *extend_c2h_dbg_content = NULL; + + if (cmd_len > 127) + return; + + extend_c2h_sub_id = buffer[0]; + extend_c2h_dbg_len = buffer[1]; + extend_c2h_dbg_content = buffer + 2; /*DbgSeq+DbgContent for show HEX*/ + +go_backfor_aggre_dbg_pkt: + i = 0; + extend_c2h_dbg_seq = buffer[2]; + extend_c2h_dbg_content = buffer + 3; + + for (;; i++) { + fw_debug_trace[i] = extend_c2h_dbg_content[i]; + if (extend_c2h_dbg_content[i + 1] == '\0') { + fw_debug_trace[i + 1] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s", + &fw_debug_trace[0]); + break; + } else if (extend_c2h_dbg_content[i] == '\n') { + fw_debug_trace[i + 1] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s", + &fw_debug_trace[0]); + buffer = extend_c2h_dbg_content + i + 3; + goto go_backfor_aggre_dbg_pkt; + } + } +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_debug.h b/drivers/staging/rtlwifi/phydm/phydm_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..f442f7c19595aeaac97e251d0f69d16a04c77fd4 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_debug.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_DBG_H__ +#define __ODM_DBG_H__ + +/*#define DEBUG_VERSION "1.1"*/ /*2015.07.29 YuChen*/ +/*#define DEBUG_VERSION "1.2"*/ /*2015.08.28 Dino*/ +#define DEBUG_VERSION "1.3" /*2016.04.28 YuChen*/ +#define ODM_DBG_TRACE 5 + +/*FW DBG MSG*/ +#define RATE_DECISION BIT(0) +#define INIT_RA_TABLE BIT(1) +#define RATE_UP BIT(2) +#define RATE_DOWN BIT(3) +#define TRY_DONE BIT(4) +#define RA_H2C BIT(5) +#define F_RATE_AP_RPT BIT(7) + +/* ----------------------------------------------------------------------------- + * Define the tracing components + * + * ----------------------------------------------------------------------------- + */ +/*BB FW Functions*/ +#define PHYDM_FW_COMP_RA BIT(0) +#define PHYDM_FW_COMP_MU BIT(1) +#define PHYDM_FW_COMP_PATH_DIV BIT(2) +#define PHYDM_FW_COMP_PHY_CONFIG BIT(3) + +/*BB Driver Functions*/ +#define ODM_COMP_DIG BIT(0) +#define ODM_COMP_RA_MASK BIT(1) +#define ODM_COMP_DYNAMIC_TXPWR BIT(2) +#define ODM_COMP_FA_CNT BIT(3) +#define ODM_COMP_RSSI_MONITOR BIT(4) +#define ODM_COMP_SNIFFER BIT(5) +#define ODM_COMP_ANT_DIV BIT(6) +#define ODM_COMP_DFS BIT(7) +#define ODM_COMP_NOISY_DETECT BIT(8) +#define ODM_COMP_RATE_ADAPTIVE BIT(9) +#define ODM_COMP_PATH_DIV BIT(10) +#define ODM_COMP_CCX BIT(11) + +#define ODM_COMP_DYNAMIC_PRICCA BIT(12) +/*BIT13 TBD*/ +#define ODM_COMP_MP BIT(14) +#define ODM_COMP_CFO_TRACKING BIT(15) +#define ODM_COMP_ACS BIT(16) +#define PHYDM_COMP_ADAPTIVITY BIT(17) +#define PHYDM_COMP_RA_DBG BIT(18) +#define PHYDM_COMP_TXBF BIT(19) +/* MAC Functions */ +#define ODM_COMP_EDCA_TURBO BIT(20) +#define ODM_COMP_DYNAMIC_RX_PATH BIT(21) +#define ODM_FW_DEBUG_TRACE BIT(22) +/* RF Functions */ +/*BIT23 TBD*/ +#define ODM_COMP_TX_PWR_TRACK BIT(24) +/*BIT25 TBD*/ +#define ODM_COMP_CALIBRATION BIT(26) +/* Common Functions */ +/*BIT27 TBD*/ +#define ODM_PHY_CONFIG BIT(28) +#define ODM_COMP_INIT BIT(29) +#define ODM_COMP_COMMON BIT(30) +#define ODM_COMP_API BIT(31) + +#define ODM_COMP_UNCOND 0xFFFFFFFF + +/*------------------------Export Marco Definition---------------------------*/ + +#define config_phydm_read_txagc_check(data) (data != INVALID_TXAGC_DATA) + +#define ODM_RT_TRACE(dm, comp, fmt, ...) \ + do { \ + if (((comp) & dm->debug_components) || \ + ((comp) == ODM_COMP_UNCOND)) \ + RT_TRACE(dm->adapter, COMP_PHYDM, DBG_DMESG, fmt, \ + ##__VA_ARGS__); \ + } while (0) + +#define BB_DBGPORT_PRIORITY_3 3 /*Debug function (the highest priority)*/ +#define BB_DBGPORT_PRIORITY_2 2 /*Check hang function & Strong function*/ +#define BB_DBGPORT_PRIORITY_1 1 /*Watch dog function*/ +#define BB_DBGPORT_RELEASE 0 /*Init value (the lowest priority)*/ + +void phydm_init_debug_setting(struct phy_dm_struct *dm); + +u8 phydm_set_bb_dbg_port(void *dm_void, u8 curr_dbg_priority, u32 debug_port); + +void phydm_release_bb_dbg_port(void *dm_void); + +u32 phydm_get_bb_dbg_port_value(void *dm_void); + +void phydm_basic_dbg_message(void *dm_void); + +#define PHYDM_DBGPRINT 0 +#define MAX_ARGC 20 +#define MAX_ARGV 16 +#define DCMD_DECIMAL "%d" +#define DCMD_CHAR "%c" +#define DCMD_HEX "%x" + +#define PHYDM_SSCANF(x, y, z) \ + do { \ + if (sscanf(x, y, z) != 1) \ + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, \ + "%s:%d sscanf fail!", __func__, \ + __LINE__); \ + } while (0) + +#define PHYDM_VAST_INFO_SNPRINTF(msg, ...) \ + do { \ + snprintf(msg, ##__VA_ARGS__); \ + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, output); \ + } while (0) + +#if (PHYDM_DBGPRINT == 1) +#define PHYDM_SNPRINTF(msg, ...) \ + do { \ + snprintf(msg, ##__VA_ARGS__); \ + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, output); \ + } while (0) +#else +#define PHYDM_SNPRINTF(msg, ...) \ + do { \ + if (out_len > used) \ + used += snprintf(msg, ##__VA_ARGS__); \ + } while (0) +#endif + +void phydm_basic_profile(void *dm_void, u32 *_used, char *output, + u32 *_out_len); +s32 phydm_cmd(struct phy_dm_struct *dm, char *input, u32 in_len, u8 flag, + char *output, u32 out_len); +void phydm_cmd_parser(struct phy_dm_struct *dm, char input[][16], u32 input_num, + u8 flag, char *output, u32 out_len); + +bool phydm_api_trx_mode(struct phy_dm_struct *dm, enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path); + +void phydm_fw_trace_en_h2c(void *dm_void, bool enable, u32 fw_debug_component, + u32 monitor_mode, u32 macid); + +void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len); + +void phydm_fw_trace_handler_8051(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +#endif /* __ODM_DBG_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_dfs.h b/drivers/staging/rtlwifi/phydm/phydm_dfs.h new file mode 100644 index 0000000000000000000000000000000000000000..59a1d08cf3819ada18cb0bd070ec6f2fcdd73e68 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dfs.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDM_DFS_H__ +#define __PHYDM_DFS_H__ + +#define DFS_VERSION "0.0" + +/* ============================================================ + * Definition + * ============================================================ + */ + +/* ============================================================ + * 1 structure + * ============================================================ + */ + +/* ============================================================ + * enumeration + * ============================================================ + */ + +enum phydm_dfs_region_domain { + PHYDM_DFS_DOMAIN_UNKNOWN = 0, + PHYDM_DFS_DOMAIN_FCC = 1, + PHYDM_DFS_DOMAIN_MKK = 2, + PHYDM_DFS_DOMAIN_ETSI = 3, +}; + +/* ============================================================ + * function prototype + * ============================================================ + */ +#define phydm_dfs_master_enabled(dm) false + +#endif /*#ifndef __PHYDM_DFS_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.c b/drivers/staging/rtlwifi/phydm/phydm_dig.c new file mode 100644 index 0000000000000000000000000000000000000000..31a4f3fcad193502180320b27d2d76936442d4db --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dig.c @@ -0,0 +1,1535 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +static int get_igi_for_diff(int); + +static inline void phydm_check_ap_write_dig(struct phy_dm_struct *dm, + u8 current_igi) +{ + switch (*dm->one_path_cca) { + case ODM_CCA_2R: + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + + if (dm->rf_type > ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), + current_igi); + break; + case ODM_CCA_1R_A: + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + if (dm->rf_type != ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), + get_igi_for_diff(current_igi)); + break; + case ODM_CCA_1R_B: + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), + get_igi_for_diff(current_igi)); + if (dm->rf_type != ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + break; + } +} + +static inline u8 phydm_get_current_igi(u8 dig_max_of_min, u8 rssi_min, + u8 current_igi) +{ + if (rssi_min < dig_max_of_min) { + if (current_igi < rssi_min) + return rssi_min; + } else { + if (current_igi < dig_max_of_min) + return dig_max_of_min; + } + return current_igi; +} + +void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type, + u32 dm_value) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (dm_type == DIG_TYPE_THRESH_HIGH) { + dig_tab->rssi_high_thresh = dm_value; + } else if (dm_type == DIG_TYPE_THRESH_LOW) { + dig_tab->rssi_low_thresh = dm_value; + } else if (dm_type == DIG_TYPE_ENABLE) { + dig_tab->dig_enable_flag = true; + } else if (dm_type == DIG_TYPE_DISABLE) { + dig_tab->dig_enable_flag = false; + } else if (dm_type == DIG_TYPE_BACKOFF) { + if (dm_value > 30) + dm_value = 30; + dig_tab->backoff_val = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) { + if (dm_value == 0) + dm_value = 0x1; + dig_tab->rx_gain_range_min = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) { + if (dm_value > 0x50) + dm_value = 0x50; + dig_tab->rx_gain_range_max = (u8)dm_value; + } +} /* dm_change_dynamic_init_gain_thresh */ + +static int get_igi_for_diff(int value_IGI) +{ +#define ONERCCA_LOW_TH 0x30 +#define ONERCCA_LOW_DIFF 8 + + if (value_IGI < ONERCCA_LOW_TH) { + if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) + return ONERCCA_LOW_TH; + else + return value_IGI + ONERCCA_LOW_DIFF; + } + + return value_IGI; +} + +static void odm_fa_threshold_check(void *dm_void, bool is_dfs_band, + bool is_performance, u32 rx_tp, u32 tx_tp, + u32 *dm_FA_thres) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->is_linked && (is_performance || is_dfs_band)) { + /*For NIC*/ + dm_FA_thres[0] = DM_DIG_FA_TH0; + dm_FA_thres[1] = DM_DIG_FA_TH1; + dm_FA_thres[2] = DM_DIG_FA_TH2; + } else { + if (is_dfs_band) { + /* For DFS band and no link */ + dm_FA_thres[0] = 250; + dm_FA_thres[1] = 1000; + dm_FA_thres[2] = 2000; + } else { + dm_FA_thres[0] = 2000; + dm_FA_thres[1] = 4000; + dm_FA_thres[2] = 5000; + } + } +} + +static u8 odm_forbidden_igi_check(void *dm_void, u8 dig_dynamic_min, + u8 current_igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct false_alarm_stat *fa_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + u8 rx_gain_range_min = dig_tab->rx_gain_range_min; + + if (dig_tab->large_fa_timeout) { + if (--dig_tab->large_fa_timeout == 0) + dig_tab->large_fa_hit = 0; + } + + if (fa_cnt->cnt_all > 10000) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Abnormally false alarm case.\n", __func__); + + if (dig_tab->large_fa_hit != 3) + dig_tab->large_fa_hit++; + + if (dig_tab->forbidden_igi < current_igi) { + dig_tab->forbidden_igi = current_igi; + dig_tab->large_fa_hit = 1; + dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT; + } + + if (dig_tab->large_fa_hit >= 3) { + if ((dig_tab->forbidden_igi + 2) > + dig_tab->rx_gain_range_max) + rx_gain_range_min = dig_tab->rx_gain_range_max; + else + rx_gain_range_min = + (dig_tab->forbidden_igi + 2); + dig_tab->recover_cnt = 1800; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Abnormally false alarm case: recover_cnt = %d\n", + __func__, dig_tab->recover_cnt); + } + } + + else if (fa_cnt->cnt_all > 2000) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "Abnormally false alarm case.\n"); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n", + fa_cnt->cnt_all, fa_cnt->cnt_all_pre, current_igi, + dig_tab->pre_ig_value); + + /* fa_cnt->cnt_all = 1.1875*fa_cnt->cnt_all_pre */ + if ((fa_cnt->cnt_all > + (fa_cnt->cnt_all_pre + (fa_cnt->cnt_all_pre >> 3) + + (fa_cnt->cnt_all_pre >> 4))) && + (current_igi < dig_tab->pre_ig_value)) { + if (dig_tab->large_fa_hit != 3) + dig_tab->large_fa_hit++; + + if (dig_tab->forbidden_igi < current_igi) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n", + dig_tab->forbidden_igi, current_igi); + + dig_tab->forbidden_igi = current_igi; + dig_tab->large_fa_hit = 1; + dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT; + } + } + + if (dig_tab->large_fa_hit >= 3) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n", + dig_tab->rx_gain_range_max, rx_gain_range_min, + dig_tab->forbidden_igi); + + if ((dig_tab->forbidden_igi + 1) > + dig_tab->rx_gain_range_max) + rx_gain_range_min = dig_tab->rx_gain_range_max; + else + rx_gain_range_min = + (dig_tab->forbidden_igi + 1); + + dig_tab->recover_cnt = 1200; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n", + dig_tab->recover_cnt, rx_gain_range_min); + } + } else { + if (dig_tab->recover_cnt != 0) { + dig_tab->recover_cnt--; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Normal Case: recover_cnt = %d\n", + __func__, dig_tab->recover_cnt); + return rx_gain_range_min; + } + + if (dig_tab->large_fa_hit >= 3) { + dig_tab->large_fa_hit = 0; + return rx_gain_range_min; + } + + if ((dig_tab->forbidden_igi - 2) < + dig_dynamic_min) { /* DM_DIG_MIN) */ + dig_tab->forbidden_igi = + dig_dynamic_min; /* DM_DIG_MIN; */ + rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Normal Case: At Lower Bound\n", + __func__); + } else { + if (dig_tab->large_fa_hit == 0) { + dig_tab->forbidden_igi -= 2; + rx_gain_range_min = + (dig_tab->forbidden_igi + 2); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Normal Case: Approach Lower Bound\n", + __func__); + } + } + } + + return rx_gain_range_min; +} + +static void phydm_set_big_jump_step(void *dm_void, u8 current_igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + u8 step1[8] = {24, 30, 40, 50, 60, 70, 80, 90}; + u8 i; + + if (dig_tab->enable_adjust_big_jump == 0) + return; + + for (i = 0; i <= dig_tab->big_jump_step1; i++) { + if ((current_igi + step1[i]) > + dig_tab->big_jump_lmt[dig_tab->agc_table_idx]) { + if (i != 0) + i = i - 1; + break; + } else if (i == dig_tab->big_jump_step1) { + break; + } + } + if (dm->support_ic_type & ODM_RTL8822B) + odm_set_bb_reg(dm, 0x8c8, 0xe, i); + else if (dm->support_ic_type & ODM_RTL8197F) + odm_set_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i); + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): bigjump = %d (ori = 0x%x), LMT=0x%x\n", __func__, i, + dig_tab->big_jump_step1, + dig_tab->big_jump_lmt[dig_tab->agc_table_idx]); +} + +void odm_write_dig(void *dm_void, u8 current_igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (dig_tab->is_stop_dig) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Stop Writing IGI\n", + __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): ODM_REG(IGI_A,dm)=0x%x, ODM_BIT(IGI,dm)=0x%x\n", + __func__, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + + /* 1 Check initial gain by upper bound */ + if ((!dig_tab->is_psd_in_progress) && dm->is_linked) { + if (current_igi > dig_tab->rx_gain_range_max) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): current_igi(0x%02x) is larger than upper bound !!\n", + __func__, current_igi); + current_igi = dig_tab->rx_gain_range_max; + } + if (dm->support_ability & ODM_BB_ADAPTIVITY && + dm->adaptivity_flag) { + if (current_igi > dm->adaptivity_igi_upper) + current_igi = dm->adaptivity_igi_upper; + + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): adaptivity case: Force upper bound to 0x%x !!!!!!\n", + __func__, current_igi); + } + } + + if (dig_tab->cur_ig_value != current_igi) { + /* Modify big jump step for 8822B and 8197F */ + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) + phydm_set_big_jump_step(dm, current_igi); + + /* Set IGI value of CCK for new CCK AGC */ + if (dm->cck_new_agc) { + if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) + odm_set_bb_reg(dm, 0xa0c, 0x00003f00, + (current_igi >> 1)); + } + + /*Add by YuChen for USB IO too slow issue*/ + if ((dm->support_ability & ODM_BB_ADAPTIVITY) && + (current_igi > dig_tab->cur_ig_value)) { + dig_tab->cur_ig_value = current_igi; + phydm_adaptivity(dm); + } + + /* 1 Set IGI value */ + if (dm->support_platform & (ODM_WIN | ODM_CE)) { + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + + if (dm->rf_type > ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), + ODM_BIT(IGI, dm), current_igi); + + } else if (dm->support_platform & (ODM_AP)) { + phydm_check_ap_write_dig(dm, current_igi); + } + + dig_tab->cur_ig_value = current_igi; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi(0x%02x).\n", __func__, + current_igi); +} + +void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, u8 igi_value) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + s8 max_level; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__, + pause_level); + + if ((dig_tab->pause_dig_level == 0) && + (!(dm->support_ability & ODM_BB_DIG) || + !(dm->support_ability & ODM_BB_FA_CNT))) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Return: support_ability DIG or FA is disabled !!\n", + __func__); + return; + } + + if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: Wrong pause level !!\n", __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_dig_level, igi_value); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_dig_value[7], + dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5], + dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3], + dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1], + dig_tab->pause_dig_value[0]); + + switch (pause_type) { + /* Pause DIG */ + case PHYDM_PAUSE: { + /* Disable DIG */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability & (~ODM_BB_DIG)); + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Pause DIG !!\n", + __func__); + + /* Backup IGI value */ + if (dig_tab->pause_dig_level == 0) { + dig_tab->igi_backup = dig_tab->cur_ig_value; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Backup IGI = 0x%x, new IGI = 0x%x\n", + __func__, dig_tab->igi_backup, igi_value); + } + + /* Record IGI value */ + dig_tab->pause_dig_value[pause_level] = igi_value; + + /* Update pause level */ + dig_tab->pause_dig_level = + (dig_tab->pause_dig_level | BIT(pause_level)); + + /* Write new IGI value */ + if (BIT(pause_level + 1) > dig_tab->pause_dig_level) { + odm_write_dig(dm, igi_value); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): IGI of higher level = 0x%x\n", + __func__, igi_value); + } + break; + } + /* Resume DIG */ + case PHYDM_RESUME: { + /* check if the level is illegal or not */ + if ((dig_tab->pause_dig_level & (BIT(pause_level))) != 0) { + dig_tab->pause_dig_level = dig_tab->pause_dig_level & + (~(BIT(pause_level))); + dig_tab->pause_dig_value[pause_level] = 0; + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Resume DIG !!\n", + __func__); + } else { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Wrong resume level !!\n", __func__); + break; + } + + /* Resume DIG */ + if (dig_tab->pause_dig_level == 0) { + /* Write backup IGI value */ + odm_write_dig(dm, dig_tab->igi_backup); + dig_tab->is_ignore_dig = true; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write original IGI = 0x%x\n", + __func__, dig_tab->igi_backup); + + /* Enable DIG */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability | ODM_BB_DIG); + break; + } + + if (BIT(pause_level) <= dig_tab->pause_dig_level) + break; + + /* Calculate the maximum level now */ + for (max_level = (pause_level - 1); max_level >= 0; + max_level--) { + if ((dig_tab->pause_dig_level & BIT(max_level)) > 0) + break; + } + + /* write IGI of lower level */ + odm_write_dig(dm, dig_tab->pause_dig_value[max_level]); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write IGI (0x%x) of level (%d)\n", __func__, + dig_tab->pause_dig_value[max_level], max_level); + break; + } + default: + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n", + __func__); + break; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_dig_level, igi_value); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_dig_value[7], + dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5], + dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3], + dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1], + dig_tab->pause_dig_value[0]); +} + +static bool odm_dig_abort(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + /* support_ability */ + if (!(dm->support_ability & ODM_BB_FA_CNT)) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Return: support_ability ODM_BB_FA_CNT is disabled\n", + __func__); + return true; + } + + /* support_ability */ + if (!(dm->support_ability & ODM_BB_DIG)) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Return: support_ability ODM_BB_DIG is disabled\n", + __func__); + return true; + } + + /* ScanInProcess */ + if (*dm->is_scan_in_process) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: In Scan Progress\n", __func__); + return true; + } + + if (dig_tab->is_ignore_dig) { + dig_tab->is_ignore_dig = false; + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Return: Ignore DIG\n", + __func__); + return true; + } + + /* add by Neil Chen to avoid PSD is processing */ + if (!dm->is_dm_initial_gain_enable) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: PSD is Processing\n", __func__); + return true; + } + + return false; +} + +void odm_dig_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + u32 ret_value; + u8 i; + + dig_tab->is_stop_dig = false; + dig_tab->is_ignore_dig = false; + dig_tab->is_psd_in_progress = false; + dig_tab->cur_ig_value = + (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + dig_tab->pre_ig_value = 0; + dig_tab->rssi_low_thresh = DM_DIG_THRESH_LOW; + dig_tab->rssi_high_thresh = DM_DIG_THRESH_HIGH; + dig_tab->fa_low_thresh = DM_FALSEALARM_THRESH_LOW; + dig_tab->fa_high_thresh = DM_FALSEALARM_THRESH_HIGH; + dig_tab->backoff_val = DM_DIG_BACKOFF_DEFAULT; + dig_tab->backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dig_tab->backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dig_tab->pre_cck_cca_thres = 0xFF; + dig_tab->cur_cck_cca_thres = 0x83; + dig_tab->forbidden_igi = DM_DIG_MIN_NIC; + dig_tab->large_fa_hit = 0; + dig_tab->large_fa_timeout = 0; + dig_tab->recover_cnt = 0; + dig_tab->is_media_connect_0 = false; + dig_tab->is_media_connect_1 = false; + + /*To initialize dm->is_dm_initial_gain_enable==false to avoid DIG err*/ + dm->is_dm_initial_gain_enable = true; + + dig_tab->dig_dynamic_min_0 = DM_DIG_MIN_NIC; + dig_tab->dig_dynamic_min_1 = DM_DIG_MIN_NIC; + + /* To Initi BT30 IGI */ + dig_tab->bt30_cur_igi = 0x32; + + odm_memory_set(dm, dig_tab->pause_dig_value, 0, + (DM_DIG_MAX_PAUSE_TYPE + 1)); + dig_tab->pause_dig_level = 0; + odm_memory_set(dm, dig_tab->pause_cckpd_value, 0, + (DM_DIG_MAX_PAUSE_TYPE + 1)); + dig_tab->pause_cckpd_level = 0; + + if (dm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) { + dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC; + dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC; + } else { + dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC; + dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC; + } + + dig_tab->enable_adjust_big_jump = 1; + if (dm->support_ic_type & ODM_RTL8822B) { + ret_value = odm_get_bb_reg(dm, 0x8c8, MASKLWORD); + dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; + dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; + dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; + + } else if (dm->support_ic_type & ODM_RTL8197F) { + ret_value = + odm_get_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, MASKLWORD); + dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; + dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; + dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; + } + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) { + for (i = 0; i < sizeof(dig_tab->big_jump_lmt); i++) { + if (dig_tab->big_jump_lmt[i] == 0) + dig_tab->big_jump_lmt[i] = + 0x64; /* Set -10dBm as default value */ + } + } +} + +void odm_DIG(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /* Common parameters */ + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct false_alarm_stat *fa_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + bool first_connect, first_dis_connect; + u8 dig_max_of_min, dig_dynamic_min; + u8 dm_dig_max, dm_dig_min; + u8 current_igi = dig_tab->cur_ig_value; + u8 offset; + u32 dm_FA_thres[3]; + u32 tx_tp = 0, rx_tp = 0; + bool is_dfs_band = false; + bool is_performance = true, is_first_tp_target = false, + is_first_coverage = false; + + if (odm_dig_abort(dm)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG Start===>\n"); + + /* 1 Update status */ + { + dig_dynamic_min = dig_tab->dig_dynamic_min_0; + first_connect = (dm->is_linked) && !dig_tab->is_media_connect_0; + first_dis_connect = + (!dm->is_linked) && dig_tab->is_media_connect_0; + } + + /* 1 Boundary Decision */ + { + /* 2 For WIN\CE */ + if (dm->support_ic_type >= ODM_RTL8188E) + dm_dig_max = 0x5A; + else + dm_dig_max = DM_DIG_MAX_NIC; + + if (dm->support_ic_type != ODM_RTL8821) + dm_dig_min = DM_DIG_MIN_NIC; + else + dm_dig_min = 0x1C; + + dig_max_of_min = DM_DIG_MAX_AP; + + /* Modify lower bound for DFS band */ + if ((((*dm->channel >= 52) && (*dm->channel <= 64)) || + ((*dm->channel >= 100) && (*dm->channel <= 140))) && + phydm_dfs_master_enabled(dm)) { + is_dfs_band = true; + if (*dm->band_width == ODM_BW20M) + dm_dig_min = DM_DIG_MIN_AP_DFS + 2; + else + dm_dig_min = DM_DIG_MIN_AP_DFS; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: ====== In DFS band ======\n"); + } + } + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: Absolutly upper bound = 0x%x, lower bound = 0x%x\n", + dm_dig_max, dm_dig_min); + + if (dm->pu1_forced_igi_lb && (*dm->pu1_forced_igi_lb > 0)) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Force IGI lb to: 0x%02x\n", + *dm->pu1_forced_igi_lb); + dm_dig_min = *dm->pu1_forced_igi_lb; + dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) : + (dm_dig_min + 1); + } + + /* 1 Adjust boundary by RSSI */ + if (dm->is_linked && is_performance) { + /* 2 Modify DIG upper bound */ + /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */ + if ((dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B | + ODM_RTL8812 | ODM_RTL8821)) && + (dm->is_bt_limited_dig == 1)) { + offset = 10; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Coex. case: Force upper bound to RSSI + %d\n", + offset); + } else { + offset = 15; + } + + if ((dm->rssi_min + offset) > dm_dig_max) + dig_tab->rx_gain_range_max = dm_dig_max; + else if ((dm->rssi_min + offset) < dm_dig_min) + dig_tab->rx_gain_range_max = dm_dig_min; + else + dig_tab->rx_gain_range_max = dm->rssi_min + offset; + + /* 2 Modify DIG lower bound */ + /* if(dm->is_one_entry_only) */ + { + if (dm->rssi_min < dm_dig_min) + dig_dynamic_min = dm_dig_min; + else if (dm->rssi_min > dig_max_of_min) + dig_dynamic_min = dig_max_of_min; + else + dig_dynamic_min = dm->rssi_min; + + if (is_dfs_band) { + dig_dynamic_min = dm_dig_min; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: DFS band: Force lower bound to 0x%x after link\n", + dm_dig_min); + } + } + } else { + if (is_performance && is_dfs_band) { + dig_tab->rx_gain_range_max = 0x28; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: DFS band: Force upper bound to 0x%x before link\n", + dig_tab->rx_gain_range_max); + } else { + if (is_performance) + dig_tab->rx_gain_range_max = DM_DIG_MAX_OF_MIN; + else + dig_tab->rx_gain_range_max = dm_dig_max; + } + dig_dynamic_min = dm_dig_min; + } + + /* 1 Force Lower Bound for AntDiv */ + if (dm->is_linked && !dm->is_one_entry_only && + (dm->support_ic_type & ODM_ANTDIV_SUPPORT) && + (dm->support_ability & ODM_BB_ANT_DIV)) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV || + dm->ant_div_type == CG_TRX_SMART_ANTDIV) { + if (dig_tab->ant_div_rssi_max > dig_max_of_min) + dig_dynamic_min = dig_max_of_min; + else + dig_dynamic_min = (u8)dig_tab->ant_div_rssi_max; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: AntDiv case: Force lower bound to 0x%x\n", + dig_dynamic_min); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: AntDiv case: rssi_max = 0x%x\n", + dig_tab->ant_div_rssi_max); + } + } + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n", + dig_tab->rx_gain_range_max, dig_dynamic_min); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n", + dm->is_linked, dm->rssi_min, first_connect, first_dis_connect); + + /* 1 Modify DIG lower bound, deal with abnormal case */ + /* 2 Abnormal false alarm case */ + if (is_dfs_band) { + dig_tab->rx_gain_range_min = dig_dynamic_min; + } else { + if (!dm->is_linked) { + dig_tab->rx_gain_range_min = dig_dynamic_min; + + if (first_dis_connect) + dig_tab->forbidden_igi = dig_dynamic_min; + } else { + dig_tab->rx_gain_range_min = odm_forbidden_igi_check( + dm, dig_dynamic_min, current_igi); + } + } + + /* 2 Abnormal # beacon case */ + if (dm->is_linked && !first_connect) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "Beacon Num (%d)\n", + dm->phy_dbg_info.num_qry_beacon_pkt); + if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) && + (dm->bsta_state)) { + dig_tab->rx_gain_range_min = 0x1c; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n", + dm->phy_dbg_info.num_qry_beacon_pkt, + dig_tab->rx_gain_range_min); + } + } + + /* 2 Abnormal lower bound case */ + if (dig_tab->rx_gain_range_min > dig_tab->rx_gain_range_max) { + dig_tab->rx_gain_range_min = dig_tab->rx_gain_range_max; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n", + dig_tab->rx_gain_range_min); + } + + /* 1 False alarm threshold decision */ + odm_fa_threshold_check(dm, is_dfs_band, is_performance, rx_tp, tx_tp, + dm_FA_thres); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: False alarm threshold = %d, %d, %d\n", + dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]); + + /* 1 Adjust initial gain by false alarm */ + if (dm->is_linked && is_performance) { + /* 2 After link */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI after link\n"); + + if (is_first_tp_target || (first_connect && is_performance)) { + dig_tab->large_fa_hit = 0; + + if (is_dfs_band) { + u8 rssi = dm->rssi_min; + + current_igi = + (dm->rssi_min > 0x28) ? 0x28 : rssi; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: DFS band: One-shot to 0x28 upmost\n"); + } else { + current_igi = phydm_get_current_igi( + dig_max_of_min, dm->rssi_min, + current_igi); + } + + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: First connect case: IGI does on-shot to 0x%x\n", + current_igi); + + } else { + if (fa_cnt->cnt_all > dm_FA_thres[2]) + current_igi = current_igi + 4; + else if (fa_cnt->cnt_all > dm_FA_thres[1]) + current_igi = current_igi + 2; + else if (fa_cnt->cnt_all < dm_FA_thres[0]) + current_igi = current_igi - 2; + + /* 4 Abnormal # beacon case */ + if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) && + (fa_cnt->cnt_all < DM_DIG_FA_TH1) && + (dm->bsta_state)) { + current_igi = dig_tab->rx_gain_range_min; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n", + dm->phy_dbg_info.num_qry_beacon_pkt, + current_igi); + } + } + } else { + /* 2 Before link */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI before link\n"); + + if (first_dis_connect || is_first_coverage) { + current_igi = dm_dig_min; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: First disconnect case: IGI does on-shot to lower bound\n"); + } else { + if (fa_cnt->cnt_all > dm_FA_thres[2]) + current_igi = current_igi + 4; + else if (fa_cnt->cnt_all > dm_FA_thres[1]) + current_igi = current_igi + 2; + else if (fa_cnt->cnt_all < dm_FA_thres[0]) + current_igi = current_igi - 2; + } + } + + /* 1 Check initial gain by upper/lower bound */ + if (current_igi < dig_tab->rx_gain_range_min) + current_igi = dig_tab->rx_gain_range_min; + + if (current_igi > dig_tab->rx_gain_range_max) + current_igi = dig_tab->rx_gain_range_max; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: cur_ig_value=0x%x, TotalFA = %d\n", + current_igi, fa_cnt->cnt_all); + + /* 1 Update status */ + if (dm->is_bt_hs_operation) { + if (dm->is_linked) { + if (dig_tab->bt30_cur_igi > (current_igi)) + odm_write_dig(dm, current_igi); + else + odm_write_dig(dm, dig_tab->bt30_cur_igi); + + dig_tab->is_media_connect_0 = dm->is_linked; + dig_tab->dig_dynamic_min_0 = dig_dynamic_min; + } else { + if (dm->is_link_in_process) + odm_write_dig(dm, 0x1c); + else if (dm->is_bt_connect_process) + odm_write_dig(dm, 0x28); + else + odm_write_dig(dm, dig_tab->bt30_cur_igi); + } + } else { /* BT is not using */ + odm_write_dig(dm, current_igi); + dig_tab->is_media_connect_0 = dm->is_linked; + dig_tab->dig_dynamic_min_0 = dig_dynamic_min; + } + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG end\n"); +} + +void odm_dig_by_rssi_lps(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct false_alarm_stat *fa_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + + u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ + u8 current_igi = dm->rssi_min; + + if (odm_dig_abort(dm)) + return; + + current_igi = current_igi + RSSI_OFFSET_DIG; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()==>\n", __func__); + + /* Using FW PS mode to make IGI */ + /* Adjust by FA in LPS MODE */ + if (fa_cnt->cnt_all > DM_DIG_FA_TH2_LPS) + current_igi = current_igi + 4; + else if (fa_cnt->cnt_all > DM_DIG_FA_TH1_LPS) + current_igi = current_igi + 2; + else if (fa_cnt->cnt_all < DM_DIG_FA_TH0_LPS) + current_igi = current_igi - 2; + + /* Lower bound checking */ + + /* RSSI Lower bound check */ + if ((dm->rssi_min - 10) > DM_DIG_MIN_NIC) + rssi_lower = (dm->rssi_min - 10); + else + rssi_lower = DM_DIG_MIN_NIC; + + /* Upper and Lower Bound checking */ + if (current_igi > DM_DIG_MAX_NIC) + current_igi = DM_DIG_MAX_NIC; + else if (current_igi < rssi_lower) + current_igi = rssi_lower; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): fa_cnt->cnt_all = %d\n", __func__, + fa_cnt->cnt_all); + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): dm->rssi_min = %d\n", __func__, + dm->rssi_min); + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi = 0x%x\n", __func__, + current_igi); + + odm_write_dig( + dm, + current_igi); /* odm_write_dig(dm, dig_tab->cur_ig_value); */ +} + +/* 3============================================================ + * 3 FASLE ALARM CHECK + * 3============================================================ + */ + +void odm_false_alarm_counter_statistics(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct false_alarm_stat *false_alm_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + struct rt_adcsmp *adc_smp = &dm->adcsmp; + u32 ret_value; + + if (!(dm->support_ability & ODM_BB_FA_CNT)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "%s()======>\n", __func__); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) { + /* hold ofdm counter */ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), + 1); /* hold page C counter */ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), + 1); /* hold page D counter */ + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N, + MASKDWORD); + false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff); + false_alm_cnt->cnt_sb_search_fail = + ((ret_value & 0xffff0000) >> 16); + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE2_11N, + MASKDWORD); + false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff); + false_alm_cnt->cnt_parity_fail = + ((ret_value & 0xffff0000) >> 16); + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE3_11N, + MASKDWORD); + false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE4_11N, + MASKDWORD); + false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + + false_alm_cnt->cnt_ofdm_fail = + false_alm_cnt->cnt_parity_fail + + false_alm_cnt->cnt_rate_illegal + + false_alm_cnt->cnt_crc8_fail + + false_alm_cnt->cnt_mcs_fail + + false_alm_cnt->cnt_fast_fsync + + false_alm_cnt->cnt_sb_search_fail; + + /* read CCK CRC32 counter */ + false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg( + dm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD); + false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg( + dm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD); + + /* read OFDM CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11N, + MASKDWORD); + false_alm_cnt->cnt_ofdm_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff; + + /* read HT CRC32 counter */ + ret_value = + odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD); + false_alm_cnt->cnt_ht_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff; + + /* read VHT CRC32 counter */ + false_alm_cnt->cnt_vht_crc32_error = 0; + false_alm_cnt->cnt_vht_crc32_ok = 0; + + { + /* hold cck counter */ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); + + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_LSB_11N, + MASKBYTE0); + false_alm_cnt->cnt_cck_fail = ret_value; + + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_MSB_11N, + MASKBYTE3); + false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11N, + MASKDWORD); + false_alm_cnt->cnt_cck_cca = + ((ret_value & 0xFF) << 8) | + ((ret_value & 0xFF00) >> 8); + } + + false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all; + + false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync + + false_alm_cnt->cnt_sb_search_fail + + false_alm_cnt->cnt_parity_fail + + false_alm_cnt->cnt_rate_illegal + + false_alm_cnt->cnt_crc8_fail + + false_alm_cnt->cnt_mcs_fail + + false_alm_cnt->cnt_cck_fail); + + false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca + + false_alm_cnt->cnt_cck_cca; + + if (dm->support_ic_type >= ODM_RTL8188E) { + /*reset false alarm counter registers*/ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), + 1); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), + 0); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), + 1); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), + 0); + + /*update ofdm counter*/ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), + 0); /*update page C counter*/ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), + 0); /*update page D counter*/ + + /*reset CCK CCA counter*/ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(13) | BIT(12), 0); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(13) | BIT(12), 2); + + /*reset CCK FA counter*/ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(15) | BIT(14), 0); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(15) | BIT(14), 2); + + /*reset CRC32 counter*/ + odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1); + odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0); + } + + /* Get debug port 0 */ + odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0); + false_alm_cnt->dbg_port0 = + odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD); + + /* Get EDCCA flag */ + odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208); + false_alm_cnt->edcca_flag = + (bool)odm_get_bb_reg(dm, ODM_REG_RPT_11N, BIT(30)); + + ODM_RT_TRACE( + dm, ODM_COMP_FA_CNT, + "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n", + false_alm_cnt->cnt_parity_fail, + false_alm_cnt->cnt_rate_illegal, + false_alm_cnt->cnt_crc8_fail, + false_alm_cnt->cnt_mcs_fail, + false_alm_cnt->cnt_fast_fsync, + false_alm_cnt->cnt_sb_search_fail); + } + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + u32 cck_enable; + + /* read OFDM FA counter */ + false_alm_cnt->cnt_ofdm_fail = + odm_get_bb_reg(dm, ODM_REG_OFDM_FA_11AC, MASKLWORD); + + /* Read CCK FA counter */ + false_alm_cnt->cnt_cck_fail = + odm_get_bb_reg(dm, ODM_REG_CCK_FA_11AC, MASKLWORD); + + /* read CCK/OFDM CCA counter */ + ret_value = + odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD); + false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_cck_cca = ret_value & 0xffff; + + /* read CCK CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_cck_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff; + + /* read OFDM CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_ofdm_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff; + + /* read HT CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_ht_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff; + + /* read VHT CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_vht_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff; + + /* reset OFDM FA counter */ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); + + /* reset CCK FA counter */ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); + + /* reset CCA counter */ + odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 1); + odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 0); + + cck_enable = + odm_get_bb_reg(dm, ODM_REG_BB_RX_PATH_11AC, BIT(28)); + if (cck_enable) { /* if(*dm->band_type == ODM_BAND_2_4G) */ + false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail + + false_alm_cnt->cnt_cck_fail; + false_alm_cnt->cnt_cca_all = + false_alm_cnt->cnt_cck_cca + + false_alm_cnt->cnt_ofdm_cca; + } else { + false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail; + false_alm_cnt->cnt_cca_all = + false_alm_cnt->cnt_ofdm_cca; + } + + if (adc_smp->adc_smp_state == ADCSMP_STATE_IDLE) { + if (phydm_set_bb_dbg_port( + dm, BB_DBGPORT_PRIORITY_1, + 0x0)) { /*set debug port to 0x0*/ + false_alm_cnt->dbg_port0 = + phydm_get_bb_dbg_port_value(dm); + phydm_release_bb_dbg_port(dm); + } + + if (phydm_set_bb_dbg_port( + dm, BB_DBGPORT_PRIORITY_1, + 0x209)) { /*set debug port to 0x0*/ + false_alm_cnt->edcca_flag = + (bool)((phydm_get_bb_dbg_port_value( + dm) & + BIT(30)) >> + 30); + phydm_release_bb_dbg_port(dm); + } + } + } + + false_alm_cnt->cnt_crc32_error_all = + false_alm_cnt->cnt_vht_crc32_error + + false_alm_cnt->cnt_ht_crc32_error + + false_alm_cnt->cnt_ofdm_crc32_error + + false_alm_cnt->cnt_cck_crc32_error; + false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok + + false_alm_cnt->cnt_ht_crc32_ok + + false_alm_cnt->cnt_ofdm_crc32_ok + + false_alm_cnt->cnt_cck_crc32_ok; + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, + false_alm_cnt->cnt_cca_all); + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, + false_alm_cnt->cnt_all); + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[CCK] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_cck_crc32_error, + false_alm_cnt->cnt_cck_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "[OFDM]CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_ofdm_crc32_error, + false_alm_cnt->cnt_ofdm_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[ HT ] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_ht_crc32_error, + false_alm_cnt->cnt_ht_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[VHT] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_vht_crc32_error, + false_alm_cnt->cnt_vht_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[VHT] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_crc32_error_all, + false_alm_cnt->cnt_crc32_ok_all); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n", + false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag); +} + +/* 3============================================================ + * 3 CCK Packet Detect threshold + * 3============================================================ + */ + +void odm_pause_cck_packet_detection(void *dm_void, + enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, + u8 cck_pd_threshold) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + s8 max_level; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__, + pause_level); + + if ((dig_tab->pause_cckpd_level == 0) && + (!(dm->support_ability & ODM_BB_CCK_PD) || + !(dm->support_ability & ODM_BB_FA_CNT))) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n"); + return; + } + + if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: Wrong pause level !!\n", __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_cckpd_level, cck_pd_threshold); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_cckpd_value[7], + dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5], + dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3], + dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1], + dig_tab->pause_cckpd_value[0]); + + switch (pause_type) { + /* Pause CCK Packet Detection threshold */ + case PHYDM_PAUSE: { + /* Disable CCK PD */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability & (~ODM_BB_CCK_PD)); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Pause CCK packet detection threshold !!\n", + __func__); + + /*Backup original CCK PD threshold decided by CCK PD mechanism*/ + if (dig_tab->pause_cckpd_level == 0) { + dig_tab->cck_pd_backup = dig_tab->cur_cck_cca_thres; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n", + __func__, dig_tab->cck_pd_backup, + cck_pd_threshold); + } + + /* Update pause level */ + dig_tab->pause_cckpd_level = + (dig_tab->pause_cckpd_level | BIT(pause_level)); + + /* Record CCK PD threshold */ + dig_tab->pause_cckpd_value[pause_level] = cck_pd_threshold; + + /* Write new CCK PD threshold */ + if (BIT(pause_level + 1) > dig_tab->pause_cckpd_level) { + odm_write_cck_cca_thres(dm, cck_pd_threshold); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): CCKPD of higher level = 0x%x\n", + __func__, cck_pd_threshold); + } + break; + } + /* Resume CCK Packet Detection threshold */ + case PHYDM_RESUME: { + /* check if the level is illegal or not */ + if ((dig_tab->pause_cckpd_level & (BIT(pause_level))) != 0) { + dig_tab->pause_cckpd_level = + dig_tab->pause_cckpd_level & + (~(BIT(pause_level))); + dig_tab->pause_cckpd_value[pause_level] = 0; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Resume CCK PD !!\n", __func__); + } else { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Wrong resume level !!\n", __func__); + break; + } + + /* Resume DIG */ + if (dig_tab->pause_cckpd_level == 0) { + /* Write backup IGI value */ + odm_write_cck_cca_thres(dm, dig_tab->cck_pd_backup); + /* dig_tab->is_ignore_dig = true; */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write original CCKPD = 0x%x\n", + __func__, dig_tab->cck_pd_backup); + + /* Enable DIG */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability | + ODM_BB_CCK_PD); + break; + } + + if (BIT(pause_level) <= dig_tab->pause_cckpd_level) + break; + + /* Calculate the maximum level now */ + for (max_level = (pause_level - 1); max_level >= 0; + max_level--) { + if ((dig_tab->pause_cckpd_level & BIT(max_level)) > 0) + break; + } + + /* write CCKPD of lower level */ + odm_write_cck_cca_thres(dm, + dig_tab->pause_cckpd_value[max_level]); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write CCKPD (0x%x) of level (%d)\n", + __func__, dig_tab->pause_cckpd_value[max_level], + max_level); + break; + } + default: + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n", + __func__); + break; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_cckpd_level, cck_pd_threshold); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_cckpd_value[7], + dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5], + dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3], + dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1], + dig_tab->pause_cckpd_value[0]); +} + +void odm_cck_packet_detection_thresh(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct false_alarm_stat *false_alm_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + u8 cur_cck_cca_thres = dig_tab->cur_cck_cca_thres, rssi_thd = 35; + + if ((!(dm->support_ability & ODM_BB_CCK_PD)) || + (!(dm->support_ability & ODM_BB_FA_CNT))) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: return==========\n"); + return; + } + + if (dm->ext_lna) + return; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: ==========>\n"); + + if (dig_tab->cck_fa_ma == 0xffffffff) + dig_tab->cck_fa_ma = false_alm_cnt->cnt_cck_fail; + else + dig_tab->cck_fa_ma = + ((dig_tab->cck_fa_ma << 1) + dig_tab->cck_fa_ma + + false_alm_cnt->cnt_cck_fail) >> + 2; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: CCK FA moving average = %d\n", + dig_tab->cck_fa_ma); + + if (dm->is_linked) { + if (dm->rssi_min > rssi_thd) { + cur_cck_cca_thres = 0xcd; + } else if (dm->rssi_min > 20) { + if (dig_tab->cck_fa_ma > + ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3))) + cur_cck_cca_thres = 0xcd; + else if (dig_tab->cck_fa_ma < (DM_DIG_FA_TH0 >> 1)) + cur_cck_cca_thres = 0x83; + } else if (dm->rssi_min > 7) { + cur_cck_cca_thres = 0x83; + } else { + cur_cck_cca_thres = 0x40; + } + + } else { + if (dig_tab->cck_fa_ma > 0x400) + cur_cck_cca_thres = 0x83; + else if (dig_tab->cck_fa_ma < 0x200) + cur_cck_cca_thres = 0x40; + } + + { + odm_write_cck_cca_thres(dm, cur_cck_cca_thres); + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: cck_cca_th=((0x%x))\n\n", + cur_cck_cca_thres); +} + +void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (dig_tab->cur_cck_cca_thres != + cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */ + odm_write_1byte(dm, ODM_REG(CCK_CCA, dm), cur_cck_cca_thres); + dig_tab->cck_fa_ma = 0xffffffff; + } + dig_tab->pre_cck_cca_thres = dig_tab->cur_cck_cca_thres; + dig_tab->cur_cck_cca_thres = cur_cck_cca_thres; +} + +bool phydm_dig_go_up_check(void *dm_void) +{ + bool ret = true; + + return ret; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.h b/drivers/staging/rtlwifi/phydm/phydm_dig.h new file mode 100644 index 0000000000000000000000000000000000000000..af70aaec3b196ea371f2fc5d7188e93ade3aab42 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dig.h @@ -0,0 +1,241 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDIG_H__ +#define __PHYDMDIG_H__ + +#define DIG_VERSION "1.32" /* 2016.09.02 YuChen. add CCK PD for 8197F*/ + +/* Pause DIG & CCKPD */ +#define DM_DIG_MAX_PAUSE_TYPE 0x7 + +enum dig_goupcheck_level { + DIG_GOUPCHECK_LEVEL_0, + DIG_GOUPCHECK_LEVEL_1, + DIG_GOUPCHECK_LEVEL_2 + +}; + +struct dig_thres { + bool is_stop_dig; /* for debug */ + bool is_ignore_dig; + bool is_psd_in_progress; + + u8 dig_enable_flag; + u8 dig_ext_port_stage; + + int rssi_low_thresh; + int rssi_high_thresh; + + u32 fa_low_thresh; + u32 fa_high_thresh; + + u8 cur_sta_connect_state; + u8 pre_sta_connect_state; + u8 cur_multi_sta_connect_state; + + u8 pre_ig_value; + u8 cur_ig_value; + u8 backup_ig_value; /* MP DIG */ + u8 bt30_cur_igi; + u8 igi_backup; + + s8 backoff_val; + s8 backoff_val_range_max; + s8 backoff_val_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 rssi_val_min; + + u8 pre_cck_cca_thres; + u8 cur_cck_cca_thres; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 cck_pd_backup; + u8 pause_cckpd_level; + u8 pause_cckpd_value[DM_DIG_MAX_PAUSE_TYPE + 1]; + + u8 large_fa_hit; + u8 large_fa_timeout; /*if (large_fa_hit), monitor "large_fa_timeout" + *sec, if timeout, large_fa_hit=0 + */ + u8 forbidden_igi; + u32 recover_cnt; + + u8 dig_dynamic_min_0; + u8 dig_dynamic_min_1; + bool is_media_connect_0; + bool is_media_connect_1; + + u32 ant_div_rssi_max; + u32 rssi_max; + + u8 *is_p2p_in_process; + + u8 pause_dig_level; + u8 pause_dig_value[DM_DIG_MAX_PAUSE_TYPE + 1]; + + u32 cck_fa_ma; + enum dig_goupcheck_level dig_go_up_check_level; + u8 aaa_default; + + u8 rf_gain_idx; + u8 agc_table_idx; + u8 big_jump_lmt[16]; + u8 enable_adjust_big_jump : 1; + u8 big_jump_step1 : 3; + u8 big_jump_step2 : 2; + u8 big_jump_step3 : 2; +}; + +struct false_alarm_stat { + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_crc8_fail; + u32 cnt_mcs_fail; + u32 cnt_ofdm_fail; + u32 cnt_ofdm_fail_pre; /* For RTL8881A */ + u32 cnt_cck_fail; + u32 cnt_all; + u32 cnt_all_pre; + u32 cnt_fast_fsync; + u32 cnt_sb_search_fail; + u32 cnt_ofdm_cca; + u32 cnt_cck_cca; + u32 cnt_cca_all; + u32 cnt_bw_usc; /* Gary */ + u32 cnt_bw_lsc; /* Gary */ + u32 cnt_cck_crc32_error; + u32 cnt_cck_crc32_ok; + u32 cnt_ofdm_crc32_error; + u32 cnt_ofdm_crc32_ok; + u32 cnt_ht_crc32_error; + u32 cnt_ht_crc32_ok; + u32 cnt_vht_crc32_error; + u32 cnt_vht_crc32_ok; + u32 cnt_crc32_error_all; + u32 cnt_crc32_ok_all; + bool cck_block_enable; + bool ofdm_block_enable; + u32 dbg_port0; + bool edcca_flag; +}; + +enum dm_dig_op { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum phydm_pause_type { PHYDM_PAUSE = BIT(0), PHYDM_RESUME = BIT(1) }; + +enum phydm_pause_level { + /* number of pause level can't exceed DM_DIG_MAX_PAUSE_TYPE */ + PHYDM_PAUSE_LEVEL_0 = 0, + PHYDM_PAUSE_LEVEL_1 = 1, + PHYDM_PAUSE_LEVEL_2 = 2, + PHYDM_PAUSE_LEVEL_3 = 3, + PHYDM_PAUSE_LEVEL_4 = 4, + PHYDM_PAUSE_LEVEL_5 = 5, + PHYDM_PAUSE_LEVEL_6 = 6, + PHYDM_PAUSE_LEVEL_7 = DM_DIG_MAX_PAUSE_TYPE /* maximum level */ +}; + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX_NIC 0x3e +#define DM_DIG_MIN_NIC 0x20 +#define DM_DIG_MAX_OF_MIN_NIC 0x3e + +#define DM_DIG_MAX_AP 0x3e +#define DM_DIG_MIN_AP 0x20 +#define DM_DIG_MAX_OF_MIN 0x2A /* 0x32 */ +#define DM_DIG_MIN_AP_DFS 0x20 + +#define DM_DIG_MAX_NIC_HP 0x46 +#define DM_DIG_MIN_NIC_HP 0x2e + +#define DM_DIG_MAX_AP_HP 0x42 +#define DM_DIG_MIN_AP_HP 0x30 + +/* vivi 92c&92d has different definition, 20110504 + * this is for 92c + */ +#define DM_DIG_FA_TH0 0x200 /* 0x20 */ + +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 +/* this is for 92d */ +#define DM_DIG_FA_TH0_92D 0x100 +#define DM_DIG_FA_TH1_92D 0x400 +#define DM_DIG_FA_TH2_92D 0x600 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define DM_DIG_FA_TH0_LPS 4 /* -> 4 in lps */ +#define DM_DIG_FA_TH1_LPS 15 /* -> 15 lps */ +#define DM_DIG_FA_TH2_LPS 30 /* -> 30 lps */ +#define RSSI_OFFSET_DIG 0x05 +#define LARGE_FA_TIMEOUT 60 + +void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type, + u32 dm_value); + +void odm_write_dig(void *dm_void, u8 current_igi); + +void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, u8 igi_value); + +void odm_dig_init(void *dm_void); + +void odm_DIG(void *dm_void); + +void odm_dig_by_rssi_lps(void *dm_void); + +void odm_false_alarm_counter_statistics(void *dm_void); + +void odm_pause_cck_packet_detection(void *dm_void, + enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, + u8 cck_pd_threshold); + +void odm_cck_packet_detection_thresh(void *dm_void); + +void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres); + +bool phydm_dig_go_up_check(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h b/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h new file mode 100644 index 0000000000000000000000000000000000000000..9f3cb2468c02042fb80765e9c89b3b1d9b21b5ec --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDYMICRXPATH_H__ +#define __PHYDMDYMICRXPATH_H__ + +#define DYNAMIC_RX_PATH_VERSION "1.0" /*2016.07.15 Dino */ + +#define DRP_RSSI_TH 35 + +#define INIT_DRP_TIMMER 0 +#define CANCEL_DRP_TIMMER 1 +#define RELEASE_DRP_TIMMER 2 + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c new file mode 100644 index 0000000000000000000000000000000000000000..7661c499aeb110b77ab940ee91b2167ad032fd81 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +static inline void phydm_update_rf_state(struct phy_dm_struct *dm, + struct dyn_pwr_saving *dm_ps_table, + int _rssi_up_bound, + int _rssi_low_bound, + int _is_force_in_normal) +{ + if (_is_force_in_normal) { + dm_ps_table->cur_rf_state = rf_normal; + return; + } + + if (dm->rssi_min == 0xFF) { + dm_ps_table->cur_rf_state = RF_MAX; + return; + } + + if (dm_ps_table->pre_rf_state == rf_normal) { + if (dm->rssi_min >= _rssi_up_bound) + dm_ps_table->cur_rf_state = rf_save; + else + dm_ps_table->cur_rf_state = rf_normal; + } else { + if (dm->rssi_min <= _rssi_low_bound) + dm_ps_table->cur_rf_state = rf_normal; + else + dm_ps_table->cur_rf_state = rf_save; + } +} + +void odm_dynamic_bb_power_saving_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dyn_pwr_saving *dm_ps_table = &dm->dm_ps_table; + + dm_ps_table->pre_cca_state = CCA_MAX; + dm_ps_table->cur_cca_state = CCA_MAX; + dm_ps_table->pre_rf_state = RF_MAX; + dm_ps_table->cur_rf_state = RF_MAX; + dm_ps_table->rssi_val_min = 0; + dm_ps_table->initialize = 0; +} + +void odm_rf_saving(void *dm_void, u8 is_force_in_normal) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dyn_pwr_saving *dm_ps_table = &dm->dm_ps_table; + u8 rssi_up_bound = 30; + u8 rssi_low_bound = 25; + + if (dm->patch_id == 40) { /* RT_CID_819x_FUNAI_TV */ + rssi_up_bound = 50; + rssi_low_bound = 45; + } + if (dm_ps_table->initialize == 0) { + dm_ps_table->reg874 = + (odm_get_bb_reg(dm, 0x874, MASKDWORD) & 0x1CC000) >> 14; + dm_ps_table->regc70 = + (odm_get_bb_reg(dm, 0xc70, MASKDWORD) & BIT(3)) >> 3; + dm_ps_table->reg85c = + (odm_get_bb_reg(dm, 0x85c, MASKDWORD) & 0xFF000000) >> + 24; + dm_ps_table->rega74 = + (odm_get_bb_reg(dm, 0xa74, MASKDWORD) & 0xF000) >> 12; + /* Reg818 = phy_query_bb_reg(adapter, 0x818, MASKDWORD); */ + dm_ps_table->initialize = 1; + } + + phydm_update_rf_state(dm, dm_ps_table, rssi_up_bound, rssi_low_bound, + is_force_in_normal); + + if (dm_ps_table->pre_rf_state != dm_ps_table->cur_rf_state) { + if (dm_ps_table->cur_rf_state == rf_save) { + odm_set_bb_reg(dm, 0x874, 0x1C0000, + 0x2); /* reg874[20:18]=3'b010 */ + odm_set_bb_reg(dm, 0xc70, BIT(3), + 0); /* regc70[3]=1'b0 */ + odm_set_bb_reg(dm, 0x85c, 0xFF000000, + 0x63); /* reg85c[31:24]=0x63 */ + odm_set_bb_reg(dm, 0x874, 0xC000, + 0x2); /* reg874[15:14]=2'b10 */ + odm_set_bb_reg(dm, 0xa74, 0xF000, + 0x3); /* RegA75[7:4]=0x3 */ + odm_set_bb_reg(dm, 0x818, BIT(28), + 0x0); /* Reg818[28]=1'b0 */ + odm_set_bb_reg(dm, 0x818, BIT(28), + 0x1); /* Reg818[28]=1'b1 */ + } else { + odm_set_bb_reg(dm, 0x874, 0x1CC000, + dm_ps_table->reg874); + odm_set_bb_reg(dm, 0xc70, BIT(3), dm_ps_table->regc70); + odm_set_bb_reg(dm, 0x85c, 0xFF000000, + dm_ps_table->reg85c); + odm_set_bb_reg(dm, 0xa74, 0xF000, dm_ps_table->rega74); + odm_set_bb_reg(dm, 0x818, BIT(28), 0x0); + } + dm_ps_table->pre_rf_state = dm_ps_table->cur_rf_state; + } +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h new file mode 100644 index 0000000000000000000000000000000000000000..e7394c475395a4ca196e6af92267d546ab010c99 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDYNAMICBBPOWERSAVING_H__ +#define __PHYDMDYNAMICBBPOWERSAVING_H__ + +#define DYNAMIC_BBPWRSAV_VERSION "1.1" + +struct dyn_pwr_saving { + u8 pre_cca_state; + u8 cur_cca_state; + + u8 pre_rf_state; + u8 cur_rf_state; + + int rssi_val_min; + + u8 initialize; + u32 reg874, regc70, reg85c, rega74; +}; + +#define dm_rf_saving odm_rf_saving + +void odm_rf_saving(void *dm_void, u8 is_force_in_normal); + +void odm_dynamic_bb_power_saving_init(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c new file mode 100644 index 0000000000000000000000000000000000000000..ebb43342b80b36793f5c160583f92703cabdcef0 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +void odm_dynamic_tx_power_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + dm->last_dtp_lvl = tx_high_pwr_level_normal; + dm->dynamic_tx_high_power_lvl = tx_high_pwr_level_normal; + dm->tx_agc_ofdm_18_6 = + odm_get_bb_reg(dm, 0xC24, MASKDWORD); /*TXAGC {18M 12M 9M 6M}*/ +} + +void odm_dynamic_tx_power_save_power_index(void *dm_void) {} + +void odm_dynamic_tx_power_restore_power_index(void *dm_void) {} + +void odm_dynamic_tx_power_write_power_index(void *dm_void, u8 value) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 index; + u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + + for (index = 0; index < 6; index++) + odm_write_1byte(dm, power_index_reg[index], value); +} + +static void odm_dynamic_tx_power_nic_ce(void *dm_void) {} + +void odm_dynamic_tx_power(void *dm_void) +{ + /* */ + /* For AP/ADSL use struct rtl8192cd_priv* */ + /* For CE/NIC use struct void* */ + /* */ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) + return; + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + switch (dm->support_platform) { + case ODM_WIN: + odm_dynamic_tx_power_nic(dm); + break; + case ODM_CE: + odm_dynamic_tx_power_nic_ce(dm); + break; + case ODM_AP: + odm_dynamic_tx_power_ap(dm); + break; + default: + break; + } +} + +void odm_dynamic_tx_power_nic(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) + return; +} + +void odm_dynamic_tx_power_ap(void *dm_void + + ) +{ +} + +void odm_dynamic_tx_power_8821(void *dm_void, u8 *desc, u8 mac_id) {} diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h new file mode 100644 index 0000000000000000000000000000000000000000..10bad1209db28b4b2a7b47132dca7b97c80dce7f --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDYNAMICTXPOWER_H__ +#define __PHYDMDYNAMICTXPOWER_H__ + +/*#define DYNAMIC_TXPWR_VERSION "1.0"*/ +/*#define DYNAMIC_TXPWR_VERSION "1.3" */ /*2015.08.26, Add 8814 Dynamic TX pwr*/ +#define DYNAMIC_TXPWR_VERSION "1.4" /*2015.11.06,Add CE 8821A Dynamic TX pwr*/ + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 60 + +#define tx_high_pwr_level_normal 0 +#define tx_high_pwr_level_level1 1 +#define tx_high_pwr_level_level2 2 + +#define tx_high_pwr_level_bt1 3 +#define tx_high_pwr_level_bt2 4 +#define tx_high_pwr_level_15 5 +#define tx_high_pwr_level_35 6 +#define tx_high_pwr_level_50 7 +#define tx_high_pwr_level_70 8 +#define tx_high_pwr_level_100 9 + +void odm_dynamic_tx_power_init(void *dm_void); + +void odm_dynamic_tx_power_restore_power_index(void *dm_void); + +void odm_dynamic_tx_power_nic(void *dm_void); + +void odm_dynamic_tx_power_save_power_index(void *dm_void); + +void odm_dynamic_tx_power_write_power_index(void *dm_void, u8 value); + +void odm_dynamic_tx_power_8821(void *dm_void, u8 *desc, u8 mac_id); + +void odm_dynamic_tx_power(void *dm_void); + +void odm_dynamic_tx_power_ap(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c new file mode 100644 index 0000000000000000000000000000000000000000..753a9b9834e49400de4660bff65921c0e68ef43a --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c @@ -0,0 +1,139 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +void odm_edca_turbo_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + dm->dm_edca_table.is_current_turbo_edca = false; + dm->dm_edca_table.is_cur_rdl_state = false; + + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial VO PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_VO_PARAM)); + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial VI PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_VI_PARAM)); + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial BE PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_BE_PARAM)); + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial BK PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_BK_PARAM)); + +} /* ODM_InitEdcaTurbo */ + +void odm_edca_turbo_check(void *dm_void) +{ + /* For AP/ADSL use struct rtl8192cd_priv* */ + /* For CE/NIC use struct void* */ + + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, + "%s========================>\n", __func__); + + if (!(dm->support_ability & ODM_MAC_EDCA_TURBO)) + return; + + switch (dm->support_platform) { + case ODM_WIN: + + break; + + case ODM_CE: + odm_edca_turbo_check_ce(dm); + break; + } + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, + "<========================%s\n", __func__); + +} /* odm_CheckEdcaTurbo */ + +void odm_edca_turbo_check_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + u32 edca_be = 0x5ea42b; + bool is_cur_rdlstate; + bool edca_turbo_on = false; + + if (dm->wifi_test) + return; + + if (!dm->is_linked) { + rtlpriv->dm.is_any_nonbepkts = false; + return; + } + + if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) + rtlpriv->dm.is_any_nonbepkts = true; + rtlpriv->dm.dbginfo.num_non_be_pkt = 0; + + cur_txok_cnt = rtlpriv->stats.txbytesunicast_inperiod; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast_inperiod; + + /*b_bias_on_rx = false;*/ + edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) ? + true : + false; + + if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) + goto label_exit; + + if (edca_turbo_on) { + is_cur_rdlstate = + (cur_rxok_cnt > cur_txok_cnt * 4) ? true : false; + + edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul; + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM_8822B, edca_be); + rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate; + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + + rtlpriv->cfg->ops->set_hw_reg(rtlpriv->hw, + HW_VAR_AC_PARAM, + (u8 *)(&tmp)); + rtlpriv->dm.current_turbo_edca = false; + } + } + +label_exit: + rtlpriv->dm.is_any_nonbepkts = false; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h new file mode 100644 index 0000000000000000000000000000000000000000..5845b108a00198ab75e73c9e9e6f603f6751d1ee --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMEDCATURBOCHECK_H__ +#define __PHYDMEDCATURBOCHECK_H__ + +/*#define EDCATURBO_VERSION "2.1"*/ +#define EDCATURBO_VERSION "2.3" /*2015.07.29 by YuChen*/ + +struct edca_turbo { + bool is_current_turbo_edca; + bool is_cur_rdl_state; + + u32 prv_traffic_idx; /* edca turbo */ +}; + +void odm_edca_turbo_check(void *dm_void); +void odm_edca_turbo_init(void *dm_void); + +void odm_edca_turbo_check_ce(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_features.h b/drivers/staging/rtlwifi/phydm/phydm_features.h new file mode 100644 index 0000000000000000000000000000000000000000..37f6f0cd7235042bc2e78b6403956a8b6373524d --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_features.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDM_FEATURES_H__ +#define __PHYDM_FEATURES + +/*phydm debyg report & tools*/ + +/*Antenna Diversity*/ + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..0a1f11a926e442ac1c372f0a4bfa0ed6acb49275 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c @@ -0,0 +1,1928 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ + +#include "mp_precomp.h" +#include "phydm_precomp.h" + +#define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm)) +#define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm)) + +#define READ_AND_CONFIG READ_AND_CONFIG_MP + +#define READ_FIRMWARE_MP(ic, txt) \ + (odm_read_firmware_mp_##ic##txt(dm, p_firmware, size)) +#define READ_FIRMWARE_TC(ic, txt) \ + (odm_read_firmware_tc_##ic##txt(dm, p_firmware, size)) + +#define READ_FIRMWARE READ_FIRMWARE_MP + +#define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt()) +#define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt()) + +#define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt) + +static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm, + struct rtl_sta_info *entry, + struct dm_per_pkt_info *pktinfo, + u32 undecorated_smoothed_ofdm, + u32 undecorated_smoothed_cck) +{ + u32 weighting = 0, undecorated_smoothed_pwdb; + /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */ + + if (entry->rssi_stat.ofdm_pkt == + 64) { /* speed up when all packets are OFDM*/ + undecorated_smoothed_pwdb = undecorated_smoothed_ofdm; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id, + undecorated_smoothed_cck); + } else { + if (entry->rssi_stat.valid_bit < 64) + entry->rssi_stat.valid_bit++; + + if (entry->rssi_stat.valid_bit == 64) { + weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ? + 64 : + (entry->rssi_stat.ofdm_pkt << 4); + undecorated_smoothed_pwdb = + (weighting * undecorated_smoothed_ofdm + + (64 - weighting) * undecorated_smoothed_cck) >> + 6; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "PWDB_1[%d] = (( %d )), W = (( %d ))\n", + pktinfo->station_id, + undecorated_smoothed_cck, weighting); + } else { + if (entry->rssi_stat.valid_bit != 0) + undecorated_smoothed_pwdb = + (entry->rssi_stat.ofdm_pkt * + undecorated_smoothed_ofdm + + (entry->rssi_stat.valid_bit - + entry->rssi_stat.ofdm_pkt) * + undecorated_smoothed_cck) / + entry->rssi_stat.valid_bit; + else + undecorated_smoothed_pwdb = 0; + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n", + pktinfo->station_id, undecorated_smoothed_cck, + entry->rssi_stat.ofdm_pkt, + entry->rssi_stat.valid_bit); + } + } + + return undecorated_smoothed_pwdb; +} + +static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct rtl_sta_info *entry, + u32 undecorated_smoothed_cck) +{ + u32 rssi_ave; + u8 i; + + rssi_ave = phy_info->rx_pwdb_all; + dm->rssi_a = (u8)phy_info->rx_pwdb_all; + dm->rssi_b = 0xFF; + dm->rssi_c = 0xFF; + dm->rssi_d = 0xFF; + + if (entry->rssi_stat.cck_pkt <= 63) + entry->rssi_stat.cck_pkt++; + + /* 1 Process CCK RSSI */ + if (undecorated_smoothed_cck <= 0) { /* initialize */ + undecorated_smoothed_cck = phy_info->rx_pwdb_all; + entry->rssi_stat.cck_sum_power = + (u16)phy_info->rx_pwdb_all; /*reset*/ + entry->rssi_stat.cck_pkt = 1; /*reset*/ + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n", + undecorated_smoothed_cck); + } else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) { + entry->rssi_stat.cck_sum_power = + entry->rssi_stat.cck_sum_power + + (u16)phy_info->rx_pwdb_all; + undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power / + entry->rssi_stat.cck_pkt; + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n", + undecorated_smoothed_cck, + entry->rssi_stat.cck_sum_power, + entry->rssi_stat.cck_pkt); + } else { + if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) { + undecorated_smoothed_cck = + (((undecorated_smoothed_cck) * + (RX_SMOOTH_FACTOR - 1)) + + (phy_info->rx_pwdb_all)) / + (RX_SMOOTH_FACTOR); + undecorated_smoothed_cck = undecorated_smoothed_cck + 1; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "CCK_1: (( %d ))\n", + undecorated_smoothed_cck); + } else { + undecorated_smoothed_cck = + (((undecorated_smoothed_cck) * + (RX_SMOOTH_FACTOR - 1)) + + (phy_info->rx_pwdb_all)) / + (RX_SMOOTH_FACTOR); + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "CCK_2: (( %d ))\n", + undecorated_smoothed_cck); + } + } + + i = 63; + entry->rssi_stat.ofdm_pkt -= + (u8)((entry->rssi_stat.packet_map >> i) & BIT(0)); + entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1; + return undecorated_smoothed_cck; +} + +static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct rtl_sta_info *entry, + u32 undecorated_smoothed_ofdm) +{ + u32 rssi_ave; + u8 rssi_max, rssi_min, i; + + if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) { + u8 rx_count = 0; + u32 rssi_linear = 0; + + if (dm->rx_ant_status & ODM_RF_A) { + dm->rssi_a = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]); + } else { + dm->rssi_a = 0; + } + + if (dm->rx_ant_status & ODM_RF_B) { + dm->rssi_b = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]); + } else { + dm->rssi_b = 0; + } + + if (dm->rx_ant_status & ODM_RF_C) { + dm->rssi_c = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_C]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_C]); + } else { + dm->rssi_c = 0; + } + + if (dm->rx_ant_status & ODM_RF_D) { + dm->rssi_d = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_D]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_D]); + } else { + dm->rssi_d = 0; + } + + /* Calculate average RSSI */ + switch (rx_count) { + case 2: + rssi_linear = (rssi_linear >> 1); + break; + case 3: + /* rssi_linear/3 ~ rssi_linear*11/32 */ + rssi_linear = ((rssi_linear) + (rssi_linear << 1) + + (rssi_linear << 3)) >> + 5; + break; + case 4: + rssi_linear = (rssi_linear >> 2); + break; + } + + rssi_ave = odm_convert_to_db(rssi_linear); + } else { + if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) { + rssi_ave = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + dm->rssi_a = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + dm->rssi_b = 0; + } else { + dm->rssi_a = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + dm->rssi_b = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + + if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > + phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) { + rssi_max = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + rssi_min = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + } else { + rssi_max = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + rssi_min = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + } + if ((rssi_max - rssi_min) < 3) + rssi_ave = rssi_max; + else if ((rssi_max - rssi_min) < 6) + rssi_ave = rssi_max - 1; + else if ((rssi_max - rssi_min) < 10) + rssi_ave = rssi_max - 2; + else + rssi_ave = rssi_max - 3; + } + } + + /* 1 Process OFDM RSSI */ + if (undecorated_smoothed_ofdm <= 0) { /* initialize */ + undecorated_smoothed_ofdm = phy_info->rx_pwdb_all; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n", + undecorated_smoothed_ofdm); + } else { + if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) { + undecorated_smoothed_ofdm = + (((undecorated_smoothed_ofdm) * + (RX_SMOOTH_FACTOR - 1)) + + (rssi_ave)) / + (RX_SMOOTH_FACTOR); + undecorated_smoothed_ofdm = + undecorated_smoothed_ofdm + 1; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "OFDM_1: (( %d ))\n", + undecorated_smoothed_ofdm); + } else { + undecorated_smoothed_ofdm = + (((undecorated_smoothed_ofdm) * + (RX_SMOOTH_FACTOR - 1)) + + (rssi_ave)) / + (RX_SMOOTH_FACTOR); + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "OFDM_2: (( %d ))\n", + undecorated_smoothed_ofdm); + } + } + + if (entry->rssi_stat.ofdm_pkt != 64) { + i = 63; + entry->rssi_stat.ofdm_pkt -= + (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1); + } + + entry->rssi_stat.packet_map = + (entry->rssi_stat.packet_map << 1) | BIT(0); + return undecorated_smoothed_ofdm; +} + +static u8 odm_evm_db_to_percentage(s8); +static u8 odm_evm_dbm_jaguar_series(s8); + +static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info) +{ + u8 rssi_max = 0, rssi_min = 0; + + dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + + if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > + phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) { + rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + } else { + rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + } + if ((rssi_max - rssi_min) < 3) + return rssi_max; + else if ((rssi_max - rssi_min) < 6) + return rssi_max - 1; + else if ((rssi_max - rssi_min) < 10) + return rssi_max - 2; + else + return rssi_max - 3; +} + +static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM, + struct phy_status_rpt_8812 *phy_sta_rpt, + struct dm_phy_status_info *phy_info) +{ + if (i < ODM_RF_PATH_C) + return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]); + else + return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]); + /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/ + /*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/ +} + +static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo, + struct phy_status_rpt_8812 *phy_sta_rpt) +{ + u8 evm = 0; + + if (pktinfo->data_rate >= ODM_RATE6M && + pktinfo->data_rate <= ODM_RATE54M) { + if (i == ODM_RF_PATH_A) { + evm = odm_evm_db_to_percentage( + (phy_sta_rpt->sigevm)); /*dbm*/ + evm += 20; + if (evm > 100) + evm = 100; + } + } else { + if (i < ODM_RF_PATH_C) { + if (phy_sta_rpt->rxevm[i] == -128) + phy_sta_rpt->rxevm[i] = -25; + evm = odm_evm_db_to_percentage( + (phy_sta_rpt->rxevm[i])); /*dbm*/ + } else { + if (phy_sta_rpt->rxevm_cd[i - 2] == -128) + phy_sta_rpt->rxevm_cd[i - 2] = -25; + evm = odm_evm_db_to_percentage( + (phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/ + } + } + + return evm; +} + +static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr) +{ + switch (LNA_idx) { + case 7: + if (VGA_idx <= 27) + return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/ + else + return -100; + break; + case 6: + return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/ + case 5: + return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/ + case 4: + return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/ + case 3: + return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/ + case 2: + if (cck_highpwr) + return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/ + else + return -6 + 2 * (5 - VGA_idx); + break; + case 1: + return 8 - 2 * VGA_idx; + case 0: + return 14 - 2 * VGA_idx; + default: + break; + } + return 0; +} + +static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all) +{ + if (!cck_highpwr) { + if (pwdb_all >= 80) + return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) + + 80; + else if ((pwdb_all <= 78) && (pwdb_all >= 20)) + return pwdb_all + 3; + if (pwdb_all > 100) + return 100; + } + return pwdb_all; +} + +static inline u8 +phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info, + struct phy_dm_struct *dm, + struct phy_status_rpt_8812 *phy_sta_rpt) +{ + u8 sq_rpt; + + if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test) + return 100; + + sq_rpt = phy_sta_rpt->pwdb_all; + + if (sq_rpt > 64) + return 0; + else if (sq_rpt < 20) + return 100; + else + return ((64 - sq_rpt) * 100) / 44; +} + +static inline u8 +phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info, + struct phy_dm_struct *dm, + struct phy_status_rpt_8192cd *phy_sta_rpt) +{ + u8 sq_rpt; + + if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test) + return 100; + + sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all; + + if (sq_rpt > 64) + return 0; + else if (sq_rpt < 20) + return 100; + else + return ((64 - sq_rpt) * 100) / 44; +} + +static u8 odm_query_rx_pwr_percentage(s8 ant_power) +{ + if ((ant_power <= -100) || (ant_power >= 20)) + return 0; + else if (ant_power >= 0) + return 100; + else + return 100 + ant_power; +} + +/* + * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. + * IF other SW team do not support the feature, remove this section.?? + */ + +s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig) +{ + { + return curr_sig; + } +} + +static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm, + u8 is_cck_rate, u8 pwdb_all, + u8 path, u8 RSSI) +{ + u8 sq = 0; + return sq; +} + +static u8 odm_evm_db_to_percentage(s8 value) +{ + /* -33dB~0dB to 0%~99% */ + s8 ret_val; + + ret_val = value; + ret_val /= 2; + + if (ret_val >= 0) + ret_val = 0; + + if (ret_val <= -33) + ret_val = -33; + + ret_val = 0 - ret_val; + ret_val *= 3; + + if (ret_val == 99) + ret_val = 100; + + return (u8)ret_val; +} + +static u8 odm_evm_dbm_jaguar_series(s8 value) +{ + s8 ret_val = value; + + /* -33dB~0dB to 33dB ~ 0dB */ + if (ret_val == -128) + ret_val = 127; + else if (ret_val < 0) + ret_val = 0 - ret_val; + + ret_val = ret_val >> 1; + return (u8)ret_val; +} + +static s16 odm_cfo(s8 value) +{ + s16 ret_val; + + if (value < 0) { + ret_val = 0 - value; + ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */ + ret_val = + ret_val | BIT(12); /* set bit12 as 1 for negative cfo */ + } else { + ret_val = value; + ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */ + } + return ret_val; +} + +static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate) +{ + u8 num_ss = 1; + + if (data_rate <= ODM_RATE54M) + num_ss = 1; + else if (data_rate <= ODM_RATEMCS31) + num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1; + else if (data_rate <= ODM_RATEVHTSS1MCS9) + num_ss = 1; + else if (data_rate <= ODM_RATEVHTSS2MCS9) + num_ss = 2; + else if (data_rate <= ODM_RATEVHTSS3MCS9) + num_ss = 3; + else if (data_rate <= ODM_RATEVHTSS4MCS9) + num_ss = 4; + + return num_ss; +} + +static void odm_rx_phy_status92c_series_parsing( + struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, + u8 *phy_status, struct dm_per_pkt_info *pktinfo) +{ + u8 i, max_spatial_stream; + s8 rx_pwr[4], rx_pwr_all = 0; + u8 EVM, pwdb_all = 0, pwdb_all_bt; + u8 RSSI, total_rssi = 0; + bool is_cck_rate = false; + u8 rf_rx_num = 0; + u8 LNA_idx = 0; + u8 VGA_idx = 0; + u8 cck_agc_rpt; + u8 num_ss; + struct phy_status_rpt_8192cd *phy_sta_rpt = + (struct phy_status_rpt_8192cd *)phy_status; + + is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false; + + if (pktinfo->is_to_self) + dm->curr_station_id = pktinfo->station_id; + + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; + + if (is_cck_rate) { + dm->phy_dbg_info.num_qry_phy_status_cck++; + cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a; + + if (dm->support_ic_type & (ODM_RTL8703B)) { + } else { /*3 bit LNA*/ + + LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); + VGA_idx = (cck_agc_rpt & 0x1F); + } + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n", + dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all); + + if (dm->board_type & ODM_BOARD_EXT_LNA) + rx_pwr_all -= dm->ext_lna_gain; + + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + + if (pktinfo->is_to_self) { + dm->cck_lna_idx = LNA_idx; + dm->cck_vga_idx = VGA_idx; + } + phy_info->rx_pwdb_all = pwdb_all; + + phy_info->bt_rx_rssi_percentage = pwdb_all; + phy_info->recv_signal_power = rx_pwr_all; + /* (3) Get Signal Quality (EVM) */ + { + u8 sq; + + sq = phydm_get_signal_quality_8192(phy_info, dm, + phy_sta_rpt); + phy_info->signal_quality = sq; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) { + if (i == 0) + phy_info->rx_mimo_signal_strength[0] = pwdb_all; + else + phy_info->rx_mimo_signal_strength[1] = 0; + } + } else { /* 2 is OFDM rate */ + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /* */ + /* (1)Get RSSI for HT rate */ + /* */ + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) { + /* 2008/01/30 MH we will judge RF RX path now. */ + if (dm->rf_path_rx_enable & BIT(i)) + rf_rx_num++; + /* else */ + /* continue; */ + + rx_pwr[i] = + ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) - + 110; + + if (pktinfo->is_to_self) { + dm->ofdm_agc_idx[i] = + (phy_sta_rpt->path_agc[i].gain & 0x3F); + /**/ + } + + phy_info->rx_pwr[i] = rx_pwr[i]; + + /* Translate DBM to percentage. */ + RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]); + total_rssi += RSSI; + + phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; + + /* Get Rx snr value in DB */ + dm->phy_dbg_info.rx_snr_db[i] = + (s32)(phy_sta_rpt->path_rxsnr[i] / 2); + phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i]; + + /* Record Signal Strength for next packet */ + /* if(pktinfo->is_packet_match_bssid) */ + { + } + } + + /* */ + /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */ + /* */ + rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & + 0x7f) - + 110; + + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + pwdb_all_bt = pwdb_all; + + phy_info->rx_pwdb_all = pwdb_all; + phy_info->bt_rx_rssi_percentage = pwdb_all_bt; + phy_info->rx_power = rx_pwr_all; + phy_info->recv_signal_power = rx_pwr_all; + + if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) { + /* do nothing */ + } else if ((dm->support_platform == ODM_WIN) && + (dm->patch_id == 25)) { + /* do nothing */ + } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */ + /* */ + /* (3)EVM of HT rate */ + /* */ + if (pktinfo->data_rate >= ODM_RATEMCS8 && + pktinfo->data_rate <= ODM_RATEMCS15) { + /* both spatial stream make sense */ + max_spatial_stream = 2; + } else { + /* only spatial stream 1 makes sense */ + max_spatial_stream = 1; + } + + for (i = 0; i < max_spatial_stream; i++) { + /*Don't use shift operation like "rx_evmX >>= 1" + *because the compilor of free build environment + *fill most significant bit to "zero" when doing + *shifting operation which may change a negative + *value to positive one, then the dbm value + *(which is supposed to be negative) is not + *correct anymore. + */ + EVM = odm_evm_db_to_percentage( + (phy_sta_rpt + ->stream_rxevm[i])); /* dbm */ + + /* Fill value in RFD, Get the first spatial + * stream only + */ + if (i == ODM_RF_PATH_A) + phy_info->signal_quality = + (u8)(EVM & 0xff); + phy_info->rx_mimo_signal_quality[i] = + (u8)(EVM & 0xff); + } + } + + num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); + odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss); + } + /* UI BSS List signal strength(in percentage), make it good looking, + * from 0~100. + */ + /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */ + if (is_cck_rate) { + phy_info->signal_strength = (u8)( + odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/ + } else { + if (rf_rx_num != 0) { + phy_info->signal_strength = + (u8)(odm_signal_scale_mapping(dm, total_rssi /= + rf_rx_num)); + } + } + + /* For 92C/92D HW (Hybrid) Antenna Diversity */ +} + +static void +odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info, + struct dm_per_pkt_info *pktinfo, + struct phy_status_rpt_8812 *phy_sta_rpt) +{ + if (pktinfo->data_rate <= ODM_RATE54M) { + switch (phy_sta_rpt->r_RFMOD) { + case 1: + if (phy_sta_rpt->sub_chnl == 0) + phy_info->band_width = 1; + else + phy_info->band_width = 0; + break; + + case 2: + if (phy_sta_rpt->sub_chnl == 0) + phy_info->band_width = 2; + else if (phy_sta_rpt->sub_chnl == 9 || + phy_sta_rpt->sub_chnl == 10) + phy_info->band_width = 1; + else + phy_info->band_width = 0; + break; + + default: + case 0: + phy_info->band_width = 0; + break; + } + } +} + +static void odm_rx_phy_status_jaguar_series_parsing( + struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, + u8 *phy_status, struct dm_per_pkt_info *pktinfo) +{ + u8 i, max_spatial_stream; + s8 rx_pwr[4], rx_pwr_all = 0; + u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt; + u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0; + u8 is_cck_rate = 0; + u8 rf_rx_num = 0; + u8 cck_highpwr = 0; + u8 LNA_idx, VGA_idx; + struct phy_status_rpt_8812 *phy_sta_rpt = + (struct phy_status_rpt_8812 *)phy_status; + struct fast_antenna_training *fat_tab = &dm->dm_fat_table; + u8 num_ss; + + odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt); + + if (pktinfo->data_rate <= ODM_RATE11M) + is_cck_rate = true; + else + is_cck_rate = false; + + if (pktinfo->is_to_self) + dm->curr_station_id = pktinfo->station_id; + else + dm->curr_station_id = 0xff; + + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1; + + if (is_cck_rate) { + u8 cck_agc_rpt; + + dm->phy_dbg_info.num_qry_phy_status_cck++; + + /*(1)Hardware does not provide RSSI for CCK*/ + /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/ + + cck_highpwr = dm->is_cck_high_power; + + cck_agc_rpt = phy_sta_rpt->cfosho[0]; + LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); + VGA_idx = (cck_agc_rpt & 0x1F); + + if (dm->support_ic_type == ODM_RTL8812) { + rx_pwr_all = + phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr); + rx_pwr_all += 6; + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all); + + } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) { + s8 pout = -6; + + switch (LNA_idx) { + case 5: + rx_pwr_all = pout - 32 - (2 * VGA_idx); + break; + case 4: + rx_pwr_all = pout - 24 - (2 * VGA_idx); + break; + case 2: + rx_pwr_all = pout - 11 - (2 * VGA_idx); + break; + case 1: + rx_pwr_all = pout + 5 - (2 * VGA_idx); + break; + case 0: + rx_pwr_all = pout + 21 - (2 * VGA_idx); + break; + } + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + } else if (dm->support_ic_type == ODM_RTL8814A || + dm->support_ic_type == ODM_RTL8822B) { + s8 pout = -6; + + switch (LNA_idx) { + /*CCK only use LNA: 2, 3, 5, 7*/ + case 7: + rx_pwr_all = pout - 32 - (2 * VGA_idx); + break; + case 5: + rx_pwr_all = pout - 22 - (2 * VGA_idx); + break; + case 3: + rx_pwr_all = pout - 2 - (2 * VGA_idx); + break; + case 2: + rx_pwr_all = pout + 5 - (2 * VGA_idx); + break; + default: + break; + } + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + } + + dm->cck_lna_idx = LNA_idx; + dm->cck_vga_idx = VGA_idx; + phy_info->rx_pwdb_all = pwdb_all; + phy_info->bt_rx_rssi_percentage = pwdb_all; + phy_info->recv_signal_power = rx_pwr_all; + /*(3) Get Signal Quality (EVM)*/ + { + u8 sq; + + if ((dm->support_platform == ODM_WIN) && + (dm->patch_id == RT_CID_819X_LENOVO)) + sq = odm_sq_process_patch_rt_cid_819x_lenovo( + dm, is_cck_rate, pwdb_all, 0, 0); + else + sq = phydm_get_signal_quality_8812(phy_info, dm, + phy_sta_rpt); + + phy_info->signal_quality = sq; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq; + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (i == 0) + phy_info->rx_mimo_signal_strength[0] = pwdb_all; + else + phy_info->rx_mimo_signal_strength[i] = 0; + } + } else { + /*is OFDM rate*/ + fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur; + + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /*(1)Get RSSI for OFDM rate*/ + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + /*2008/01/30 MH we will judge RF RX path now.*/ + if (dm->rf_path_rx_enable & BIT(i)) + rf_rx_num++; + /*2012.05.25 LukeLee: Testchip AGC report is wrong, + *it should be restored back to old formula in MP chip + */ + if (i < ODM_RF_PATH_C) + rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) - + 110; + else + rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] & + 0x7F) - + 110; + + phy_info->rx_pwr[i] = rx_pwr[i]; + + /* Translate DBM to percentage. */ + RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]); + + /*total_rssi += RSSI;*/ + /*Get the best two RSSI*/ + if (RSSI > best_rssi && RSSI > second_rssi) { + second_rssi = best_rssi; + best_rssi = RSSI; + } else if (RSSI > second_rssi && RSSI <= best_rssi) { + second_rssi = RSSI; + } + + phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; + + /*Get Rx snr value in DB*/ + if (i < ODM_RF_PATH_C) + phy_info->rx_snr[i] = + dm->phy_dbg_info.rx_snr_db[i] = + phy_sta_rpt->rxsnr[i] / 2; + else if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8822B)) + phy_info->rx_snr[i] = dm->phy_dbg_info + .rx_snr_db[i] = + phy_sta_rpt->csi_current[i - 2] / 2; + + /*(2) CFO_short & CFO_tail*/ + if (i < ODM_RF_PATH_C) { + phy_info->cfo_short[i] = + odm_cfo((phy_sta_rpt->cfosho[i])); + phy_info->cfo_tail[i] = + odm_cfo((phy_sta_rpt->cfotail[i])); + } + } + + /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/ + + /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be + *restored back to old formula in MP chip + */ + if ((dm->support_ic_type & + (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) && + (!dm->is_mp_chip)) + rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110; + else + rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) - + 110; /*OLD FORMULA*/ + + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + pwdb_all_bt = pwdb_all; + + phy_info->rx_pwdb_all = pwdb_all; + phy_info->bt_rx_rssi_percentage = pwdb_all_bt; + phy_info->rx_power = rx_pwr_all; + phy_info->recv_signal_power = rx_pwr_all; + + if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) { + /*do nothing*/ + } else { + /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/ + + /*(4)EVM of OFDM rate*/ + + if ((pktinfo->data_rate >= ODM_RATEMCS8) && + (pktinfo->data_rate <= ODM_RATEMCS15)) + max_spatial_stream = 2; + else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) && + (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9)) + max_spatial_stream = 2; + else if ((pktinfo->data_rate >= ODM_RATEMCS16) && + (pktinfo->data_rate <= ODM_RATEMCS23)) + max_spatial_stream = 3; + else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) && + (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9)) + max_spatial_stream = 3; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + /*Don't use shift operation like "rx_evmX >>= 1" + *because the compilor of free build environment + *fill most significant bit to "zero" when doing + *shifting operation which may change a negative + *value to positive one, then the dbm value + *(which is supposed to be negative) is not + *correct anymore. + */ + + EVM = phydm_get_odm_evm(i, pktinfo, + phy_sta_rpt); + evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt, + phy_info); + phy_info->rx_mimo_signal_quality[i] = EVM; + phy_info->rx_mimo_evm_dbm[i] = evm_dbm; + } + } + + num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); + odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss); + } + + /*UI BSS List signal strength(in percentage), make it good looking, + *from 0~100. + */ + /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/ + if (is_cck_rate) { + phy_info->signal_strength = (u8)( + odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/ + } else { + if (rf_rx_num != 0) { + /* 2015/01 Sean, use the best two RSSI only, + * suggested by Ynlin and ChenYu. + */ + if (rf_rx_num == 1) + avg_rssi = best_rssi; + else + avg_rssi = (best_rssi + second_rssi) / 2; + phy_info->signal_strength = + (u8)(odm_signal_scale_mapping(dm, avg_rssi)); + } + } + dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all; + + dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd; +} + +void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id) +{ + struct rtl_sta_info *entry; + + entry = dm->odm_sta_info[station_id]; + + if (!IS_STA_VALID(entry)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "Reset RSSI for macid = (( %d ))\n", station_id); + + entry->rssi_stat.undecorated_smoothed_cck = -1; + entry->rssi_stat.undecorated_smoothed_ofdm = -1; + entry->rssi_stat.undecorated_smoothed_pwdb = -1; + entry->rssi_stat.ofdm_pkt = 0; + entry->rssi_stat.cck_pkt = 0; + entry->rssi_stat.cck_sum_power = 0; + entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT; + entry->rssi_stat.packet_map = 0; + entry->rssi_stat.valid_bit = 0; +} + +void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {} + +static void odm_process_rssi_for_dm(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct dm_per_pkt_info *pktinfo) +{ + s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck, + undecorated_smoothed_ofdm; + u8 is_cck_rate = 0; + u8 send_rssi_2_fw = 0; + struct rtl_sta_info *entry; + + if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM) + return; + + /* 2012/05/30 MH/Luke.Lee Add some description */ + /* In windows driver: AP/IBSS mode STA */ + entry = dm->odm_sta_info[pktinfo->station_id]; + + if (!IS_STA_VALID(entry)) + return; + + { + if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/ + return; + } + + if (pktinfo->is_packet_beacon) + dm->phy_dbg_info.num_qry_beacon_pkt++; + + is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false; + dm->rx_rate = pktinfo->data_rate; + + /* --------------Statistic for antenna/path diversity---------------- */ + + /* -----------------Smart Antenna Debug Message------------------ */ + + undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck; + undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm; + undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb; + + if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) { + if (!is_cck_rate) /* ofdm rate */ + undecorated_smoothed_ofdm = phydm_process_rssi_ofdm( + dm, phy_info, entry, undecorated_smoothed_ofdm); + else + undecorated_smoothed_cck = phydm_process_rssi_cck( + dm, phy_info, entry, undecorated_smoothed_cck); + + undecorated_smoothed_pwdb = phydm_process_rssi_pwdb( + dm, entry, pktinfo, undecorated_smoothed_ofdm, + undecorated_smoothed_cck); + + if ((entry->rssi_stat.ofdm_pkt >= 1 || + entry->rssi_stat.cck_pkt >= 5) && + (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) { + send_rssi_2_fw = 1; + entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND; + } + + entry->rssi_stat.undecorated_smoothed_cck = + undecorated_smoothed_cck; + entry->rssi_stat.undecorated_smoothed_ofdm = + undecorated_smoothed_ofdm; + entry->rssi_stat.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + + if (send_rssi_2_fw) { /* Trigger init rate by RSSI */ + + if (entry->rssi_stat.ofdm_pkt != 0) + entry->rssi_stat.undecorated_smoothed_pwdb = + undecorated_smoothed_ofdm; + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n", + undecorated_smoothed_pwdb, + entry->rssi_stat.ofdm_pkt, + entry->rssi_stat.cck_pkt); + } + } +} + +/* + * Endianness before calling this API + */ +static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo) +{ + odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo); + odm_process_rssi_for_dm(dm, phy_info, pktinfo); +} + +/* + * Endianness before calling this API + */ + +static void odm_phy_status_query_jaguar_series( + struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, + u8 *phy_status, struct dm_per_pkt_info *pktinfo) +{ + odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status, + pktinfo); + odm_process_rssi_for_dm(dm, phy_info, pktinfo); +} + +void odm_phy_status_query(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, u8 *phy_status, + struct dm_per_pkt_info *pktinfo) +{ + if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) { + phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info); + return; + } + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) + odm_phy_status_query_jaguar_series(dm, phy_info, phy_status, + pktinfo); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) + odm_phy_status_query_92c_series(dm, phy_info, phy_status, + pktinfo); +} + +/* For future use. */ +void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id, + bool is_packet_match_bssid, bool is_packet_to_self, + bool is_packet_beacon) +{ + /* 2011/10/19 Driver team will handle in the future. */ +} + +/* + * If you want to add a new IC, Please follow below template and generate + * a new one. + */ + +enum hal_status +odm_config_rf_with_header_file(struct phy_dm_struct *dm, + enum odm_rf_config_type config_type, + enum odm_rf_radio_path e_rf_path) +{ + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===>%s (%s)\n", __func__, + (dm->is_mp_chip) ? "MPChip" : "TestChip"); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", + dm->support_platform, dm->support_interface, dm->board_type); + + /* 1 AP doesn't use PHYDM power tracking table in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + if (dm->support_ic_type == ODM_RTL8822B) { + if (config_type == CONFIG_RF_RADIO) { + if (e_rf_path == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8822b, _radioa); + else if (e_rf_path == ODM_RF_PATH_B) + READ_AND_CONFIG_MP(8822b, _radiob); + } else if (config_type == CONFIG_RF_TXPWR_LMT) { + if (dm->rfe_type == 5) + READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5); + else + READ_AND_CONFIG_MP(8822b, _txpwr_lmt); + } + } + + return HAL_STATUS_SUCCESS; +} + +enum hal_status +odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm) +{ + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===>%s (%s)\n", __func__, + (dm->is_mp_chip) ? "MPChip" : "TestChip"); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", + dm->support_platform, dm->support_interface, dm->board_type); + + /* 1 AP doesn't use PHYDM power tracking table in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + + if (dm->support_ic_type == ODM_RTL8822B) { + if (dm->rfe_type == 0) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type0); + else if (dm->rfe_type == 1) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type1); + else if (dm->rfe_type == 2) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type2); + else if ((dm->rfe_type == 3) || (dm->rfe_type == 5)) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5); + else if (dm->rfe_type == 4) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type4); + else if (dm->rfe_type == 6) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type6); + else if (dm->rfe_type == 7) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type7); + else if (dm->rfe_type == 8) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type8); + else if (dm->rfe_type == 9) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type9); + else + READ_AND_CONFIG_MP(8822b, _txpowertrack); + } + + return HAL_STATUS_SUCCESS; +} + +enum hal_status +odm_config_bb_with_header_file(struct phy_dm_struct *dm, + enum odm_bb_config_type config_type) +{ + /* 1 AP doesn't use PHYDM initialization in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + if (dm->support_ic_type == ODM_RTL8822B) { + if (config_type == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8822b, _phy_reg); + else if (config_type == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8822b, _agc_tab); + else if (config_type == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG_MP(8822b, _phy_reg_pg); + /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/ + /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/ + } + + return HAL_STATUS_SUCCESS; +} + +enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm) +{ + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===>%s (%s)\n", __func__, + (dm->is_mp_chip) ? "MPChip" : "TestChip"); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", + dm->support_platform, dm->support_interface, dm->board_type); + + /* 1 AP doesn't use PHYDM initialization in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + if (dm->support_ic_type == ODM_RTL8822B) + READ_AND_CONFIG_MP(8822b, _mac_reg); + + return HAL_STATUS_SUCCESS; +} + +enum hal_status +odm_config_fw_with_header_file(struct phy_dm_struct *dm, + enum odm_fw_config_type config_type, + u8 *p_firmware, u32 *size) +{ + return HAL_STATUS_SUCCESS; +} + +u32 odm_get_hw_img_version(struct phy_dm_struct *dm) +{ + u32 version = 0; + + /* 1 AP doesn't use PHYDM initialization in these ICs */ + /* JJ ADD 20161014 */ + + /*1 All platforms support*/ + if (dm->support_ic_type == ODM_RTL8822B) + version = GET_VERSION_MP(8822b, _mac_reg); + + return version; +} + +/* For 8822B only!! need to move to FW finally */ +/*==============================================*/ + +bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx, + u8 *p_data_rate, u8 *p_gid) +{ + u8 data_rate = 0, gid = 0; + bool is_mu = false; + + data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx]; + gid = phydm->phy_dbg_info.gid_num[ppdu_idx]; + + if (data_rate & BIT(7)) { + is_mu = true; + data_rate = data_rate & ~(BIT(7)); + } else { + is_mu = false; + } + + *p_data_rate = data_rate; + *p_gid = gid; + + return is_mu; +} + +static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status, + struct dm_per_pkt_info *pktinfo) +{ + struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type1 *)phy_status; + u8 date_rate = pktinfo->data_rate & ~(BIT(7)); + + if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) { + if (date_rate >= ODM_RATEVHTSS1MCS0) { + phydm->phy_dbg_info + .num_qry_mu_vht_pkt[date_rate - 0x2C]++; + phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] = + date_rate | BIT(7); + phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] = + phy_sta_rpt->gid; + } + + } else { + if (date_rate >= ODM_RATEVHTSS1MCS0) { + phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++; + phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] = + date_rate; + phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] = + phy_sta_rpt->gid; + } + } +} + +static void phydm_reset_phy_info(struct phy_dm_struct *phydm, + struct dm_phy_status_info *phy_info) +{ + phy_info->rx_pwdb_all = 0; + phy_info->signal_quality = 0; + phy_info->band_width = 0; + phy_info->rx_count = 0; + odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4); + odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4); + odm_memory_set(phydm, phy_info->rx_snr, 0, 4); + + phy_info->rx_power = -110; + phy_info->recv_signal_power = -110; + phy_info->bt_rx_rssi_percentage = 0; + phy_info->signal_strength = 0; + phy_info->bt_coex_pwr_adjust = 0; + phy_info->channel = 0; + phy_info->is_mu_packet = 0; + phy_info->is_beamformed = 0; + phy_info->rxsc = 0; + odm_memory_set(phydm, phy_info->rx_pwr, -110, 4); + odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4); + odm_memory_set(phydm, phy_info->cfo_short, 0, 8); + odm_memory_set(phydm, phy_info->cfo_tail, 0, 8); +} + +static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm, + s8 cfo_tail, s8 rx_snr, + struct dm_phy_status_info *phy_info) +{ + u8 evm_dbm = 0; + u8 evm_percentage = 0; + + /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */ + + if (rx_evm < 0) { + /* Calculate EVM in dBm */ + evm_dbm = ((u8)(0 - rx_evm) >> 1); + + /* Calculate EVM in percentage */ + if (evm_dbm >= 33) + evm_percentage = 100; + else + evm_percentage = (evm_dbm << 1) + (evm_dbm); + } + + phy_info->rx_pwr[rx_path] = rx_pwr; + phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm; + + /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/ + phy_info->cfo_tail[rx_path] = cfo_tail; + phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) + + (phy_info->cfo_tail[rx_path] << 2) + + (phy_info->cfo_tail[rx_path] << 1) + + (phy_info->cfo_tail[rx_path])) >> + 9; + + phy_info->rx_mimo_signal_strength[rx_path] = + odm_query_rx_pwr_percentage(rx_pwr); + phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage; + phy_info->rx_snr[rx_path] = rx_snr >> 1; +} + +static void phydm_set_common_phy_info(s8 rx_power, u8 channel, + bool is_beamformed, bool is_mu_packet, + u8 bandwidth, u8 signal_quality, u8 rxsc, + struct dm_phy_status_info *phy_info) +{ + phy_info->rx_power = rx_power; /* RSSI in dB */ + phy_info->recv_signal_power = rx_power; /* RSSI in dB */ + phy_info->channel = channel; /* channel number */ + phy_info->is_beamformed = is_beamformed; /* apply BF */ + phy_info->is_mu_packet = is_mu_packet; /* MU packet */ + phy_info->rxsc = rxsc; + phy_info->rx_pwdb_all = + odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */ + phy_info->signal_quality = signal_quality; /* signal quality */ + phy_info->band_width = bandwidth; /* bandwidth */ +} + +static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + /* type 0 is used for cck packet */ + + struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type0 *)phy_status; + u8 sq = 0; + s8 rx_power = phy_sta_rpt->pwdb - 110; + + /* JJ ADD 20161014 */ + + /* Calculate Signal Quality*/ + if (pktinfo->is_packet_match_bssid) { + if (phy_sta_rpt->signal_quality >= 64) { + sq = 0; + } else if (phy_sta_rpt->signal_quality <= 20) { + sq = 100; + } else { + /* mapping to 2~99% */ + sq = 64 - phy_sta_rpt->signal_quality; + sq = ((sq << 3) + sq) >> 2; + } + } + + /* Modify CCK PWDB if old AGC */ + if (!dm->cck_new_agc) { + u8 lna_idx, vga_idx; + + lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l); + vga_idx = phy_sta_rpt->vga; + + /* JJ ADD 20161014 */ + + /* Need to do !! */ + /*if (dm->support_ic_type & ODM_RTL8822B) */ + /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/ + } + + /* Update CCK packet counter */ + dm->phy_dbg_info.num_qry_phy_status_cck++; + + /*CCK no STBC and LDPC*/ + dm->phy_dbg_info.is_ldpc_pkt = false; + dm->phy_dbg_info.is_stbc_pkt = false; + + /* Update Common information */ + phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false, + ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info); + + /* Update CCK pwdb */ + /* Update per-path information */ + phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info); + + dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d; +} + +static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + /* type 1 is used for ofdm packet */ + + struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type1 *)phy_status; + s8 rx_pwr_db = -120; + u8 i, rxsc, bw = ODM_BW20M, rx_count = 0; + bool is_mu; + u8 num_ss; + + /* Update OFDM packet counter */ + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /* Update per-path information */ + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (dm->rx_ant_status & BIT(i)) { + s8 rx_path_pwr_db; + + /* RX path counter */ + rx_count++; + + /* Update per-path information + * (RSSI_dB RSSI_percentage EVM SNR CFO sq) + */ + /* EVM report is reported by stream, not path */ + rx_path_pwr_db = phy_sta_rpt->pwdb[i] - + 110; /* per-path pwdb in dB domain */ + phydm_set_per_path_phy_info( + i, rx_path_pwr_db, + phy_sta_rpt->rxevm[rx_count - 1], + phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i], + phy_info); + + /* search maximum pwdb */ + if (rx_path_pwr_db > rx_pwr_db) + rx_pwr_db = rx_path_pwr_db; + } + } + + /* mapping RX counter from 1~4 to 0~3 */ + if (rx_count > 0) + phy_info->rx_count = rx_count - 1; + + /* Check if MU packet or not */ + if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) { + is_mu = true; + dm->phy_dbg_info.num_qry_mu_pkt++; + } else { + is_mu = false; + } + + /* count BF packet */ + dm->phy_dbg_info.num_qry_bf_pkt = + dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed; + + /*STBC or LDPC pkt*/ + dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc; + dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc; + + /* Check sub-channel */ + if ((pktinfo->data_rate > ODM_RATE11M) && + (pktinfo->data_rate < ODM_RATEMCS0)) + rxsc = phy_sta_rpt->l_rxsc; + else + rxsc = phy_sta_rpt->ht_rxsc; + + /* Check RX bandwidth */ + if (dm->support_ic_type & ODM_RTL8822B) { + if ((rxsc >= 1) && (rxsc <= 8)) + bw = ODM_BW20M; + else if ((rxsc >= 9) && (rxsc <= 12)) + bw = ODM_BW40M; + else if (rxsc >= 13) + bw = ODM_BW80M; + else + bw = phy_sta_rpt->rf_mode; + } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D | + ODM_RTL8710B)) { /* JJ ADD 20161014 */ + if (phy_sta_rpt->rf_mode == 0) + bw = ODM_BW20M; + else if ((rxsc == 1) || (rxsc == 2)) + bw = ODM_BW20M; + else + bw = ODM_BW40M; + } + + /* Update packet information */ + phydm_set_common_phy_info( + rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed, + is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]), + rxsc, phy_info); + + num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); + + odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss); + dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d; + + if (pktinfo->is_packet_match_bssid) { + /* */ + phydm_rx_statistic_cal(dm, phy_status, pktinfo); + } +} + +static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type2 *)phy_status; + s8 rx_pwr_db = -120; + u8 i, rxsc, bw = ODM_BW20M, rx_count = 0; + + /* Update OFDM packet counter */ + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /* Update per-path information */ + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (dm->rx_ant_status & BIT(i)) { + s8 rx_path_pwr_db; + + /* RX path counter */ + rx_count++; + + /* Update per-path information + * (RSSI_dB RSSI_percentage EVM SNR CFO sq) + */ + rx_path_pwr_db = phy_sta_rpt->pwdb[i] - + 110; /* per-path pwdb in dB domain */ + + phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0, + phy_info); + + /* search maximum pwdb */ + if (rx_path_pwr_db > rx_pwr_db) + rx_pwr_db = rx_path_pwr_db; + } + } + + /* mapping RX counter from 1~4 to 0~3 */ + if (rx_count > 0) + phy_info->rx_count = rx_count - 1; + + /* Check RX sub-channel */ + if ((pktinfo->data_rate > ODM_RATE11M) && + (pktinfo->data_rate < ODM_RATEMCS0)) + rxsc = phy_sta_rpt->l_rxsc; + else + rxsc = phy_sta_rpt->ht_rxsc; + + /*STBC or LDPC pkt*/ + dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc; + dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc; + + /* Check RX bandwidth */ + /* the BW information of sc=0 is useless, because there is + * no information of RF mode + */ + + if (dm->support_ic_type & ODM_RTL8822B) { + if ((rxsc >= 1) && (rxsc <= 8)) + bw = ODM_BW20M; + else if ((rxsc >= 9) && (rxsc <= 12)) + bw = ODM_BW40M; + else if (rxsc >= 13) + bw = ODM_BW80M; + else + bw = ODM_BW20M; + } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D | + ODM_RTL8710B)) { /* JJ ADD 20161014 */ + if (rxsc == 3) + bw = ODM_BW40M; + else if ((rxsc == 1) || (rxsc == 2)) + bw = ODM_BW20M; + else + bw = ODM_BW20M; + } + + /* Update packet information */ + phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel, + (bool)phy_sta_rpt->beamformed, false, bw, 0, + rxsc, phy_info); +} + +static void +phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct dm_per_pkt_info *pktinfo) +{ + s32 undecorated_smoothed_pwdb, accumulate_pwdb; + u32 rssi_ave; + u8 i; + struct rtl_sta_info *entry; + u8 scaling_factor = 4; + + if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM) + return; + + entry = dm->odm_sta_info[pktinfo->station_id]; + + if (!IS_STA_VALID(entry)) + return; + + if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/ + return; + + if (pktinfo->is_packet_beacon) + dm->phy_dbg_info.num_qry_beacon_pkt++; + + if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) { + u32 rssi_linear = 0; + + dm->rx_rate = pktinfo->data_rate; + undecorated_smoothed_pwdb = + entry->rssi_stat.undecorated_smoothed_pwdb; + accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id]; + dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C]; + dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D]; + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (phy_info->rx_mimo_signal_strength[i] != 0) + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength[i]); + } + + switch (phy_info->rx_count + 1) { + case 2: + rssi_linear = (rssi_linear >> 1); + break; + case 3: + /* rssi_linear/3 ~ rssi_linear*11/32 */ + rssi_linear = ((rssi_linear) + (rssi_linear << 1) + + (rssi_linear << 3)) >> + 5; + break; + case 4: + rssi_linear = (rssi_linear >> 2); + break; + } + rssi_ave = odm_convert_to_db(rssi_linear); + + if (undecorated_smoothed_pwdb <= 0) { + accumulate_pwdb = + (phy_info->rx_pwdb_all << scaling_factor); + undecorated_smoothed_pwdb = phy_info->rx_pwdb_all; + } else { + accumulate_pwdb = accumulate_pwdb - + (accumulate_pwdb >> scaling_factor) + + rssi_ave; + undecorated_smoothed_pwdb = + (accumulate_pwdb + + (1 << (scaling_factor - 1))) >> + scaling_factor; + } + + entry->rssi_stat.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb; + } +} + +void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + u8 phy_status_type = (*phy_status & 0xf); + + /* Memory reset */ + phydm_reset_phy_info(phydm, phy_info); + + /* Phy status parsing */ + switch (phy_status_type) { + case 0: { + phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo, + phy_info); + break; + } + case 1: { + phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo, + phy_info); + break; + } + case 2: { + phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo, + phy_info); + break; + } + default: + return; + } + + /* Update signal strength to UI, and phy_info->rx_pwdb_all is the + * maximum RSSI of all path + */ + phy_info->signal_strength = + (u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all)); + + /* Calculate average RSSI and smoothed RSSI */ + phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo); +} + +u32 query_phydm_trx_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_stbc_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_txbf_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..ec94c61df2b97d230af46d8cd7eff78034764db5 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h @@ -0,0 +1,510 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __HALHWOUTSRC_H__ +#define __HALHWOUTSRC_H__ + +/*--------------------------Define -------------------------------------------*/ +#define CCK_RSSI_INIT_COUNT 5 + +#define RA_RSSI_STATE_INIT 0 +#define RA_RSSI_STATE_SEND 1 +#define RA_RSSI_STATE_HOLD 2 + +#define CFO_HW_RPT_2_MHZ(val) ((val << 1) + (val >> 1)) +/* ((X* 3125) / 10)>>7 = (X*10)>>2 = X*2.5 = X<<1 + X>>1 */ + +#define AGC_DIFF_CONFIG_MP(ic, band) \ + (odm_read_and_config_mp_##ic##_agc_tab_diff( \ + dm, array_mp_##ic##_agc_tab_diff_##band, \ + sizeof(array_mp_##ic##_agc_tab_diff_##band) / sizeof(u32))) +#define AGC_DIFF_CONFIG_TC(ic, band) \ + (odm_read_and_config_tc_##ic##_agc_tab_diff( \ + dm, array_tc_##ic##_agc_tab_diff_##band, \ + sizeof(array_tc_##ic##_agc_tab_diff_##band) / sizeof(u32))) + +#define AGC_DIFF_CONFIG(ic, band) \ + do { \ + if (dm->is_mp_chip) \ + AGC_DIFF_CONFIG_MP(ic, band); \ + else \ + AGC_DIFF_CONFIG_TC(ic, band); \ + } while (0) + +/* ************************************************************ + * structure and define + * *************************************************************/ + +struct phy_rx_agc_info { +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 gain : 7, trsw : 1; +#else + u8 trsw : 1, gain : 7; +#endif +}; + +struct phy_status_rpt_8192cd { + struct phy_rx_agc_info path_agc[2]; + u8 ch_corr[2]; + u8 cck_sig_qual_ofdm_pwdb_all; + u8 cck_agc_rpt_ofdm_cfosho_a; + u8 cck_rpt_b_ofdm_cfosho_b; + u8 rsvd_1; /*ch_corr_msb;*/ + u8 noise_power_db_msb; + s8 path_cfotail[2]; + u8 pcts_mask[2]; + s8 stream_rxevm[2]; + u8 path_rxsnr[2]; + u8 noise_power_db_lsb; + u8 rsvd_2[3]; + u8 stream_csi[2]; + u8 stream_target_csi[2]; + s8 sig_evm; + u8 rsvd_3; + +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antsel_rx_keep_2 : 1; /*ex_intf_flg:1;*/ + u8 sgi_en : 1; + u8 rxsc : 2; + u8 idle_long : 1; + u8 r_ant_train_en : 1; + u8 ant_sel_b : 1; + u8 ant_sel : 1; +#else /*_BIG_ENDIAN_ */ + u8 ant_sel : 1; + u8 ant_sel_b : 1; + u8 r_ant_train_en : 1; + u8 idle_long : 1; + u8 rxsc : 2; + u8 sgi_en : 1; + u8 antsel_rx_keep_2 : 1; /*ex_intf_flg:1;*/ +#endif +}; + +struct phy_status_rpt_8812 { + /* DWORD 0*/ + u8 gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/ + u8 chl_num_LSB; /*channel number[7:0]*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 chl_num_MSB : 2; /*channel number[9:8]*/ + u8 sub_chnl : 4; /*sub-channel location[3:0]*/ + u8 r_RFMOD : 2; /*RF mode[1:0]*/ +#else /*_BIG_ENDIAN_ */ + u8 r_RFMOD : 2; + u8 sub_chnl : 4; + u8 chl_num_MSB : 2; +#endif + + /* DWORD 1*/ + u8 pwdb_all; /*CCK signal quality / OFDM pwdb all*/ + s8 cfosho[2]; /*DW1 byte 1 DW1 byte2 */ +/*CCK AGC report and CCK_BB_Power / OFDM path-A and path-B short CFO*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + /*this should be checked again + *because the definition of 8812 and 8814 is different + */ + u8 resvd_0 : 6; + u8 bt_RF_ch_MSB : 2; /*8812A:2'b0, 8814A: bt rf channel keep[7:6]*/ +#else /*_BIG_ENDIAN_*/ + u8 bt_RF_ch_MSB : 2; + u8 resvd_0 : 6; +#endif + +/* DWORD 2*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 ant_div_sw_a : 1; /*8812A: ant_div_sw_a, 8814A: 1'b0*/ + u8 ant_div_sw_b : 1; /*8812A: ant_div_sw_b, 8814A: 1'b0*/ + u8 bt_RF_ch_LSB : 6; /*8812A: 6'b0, 8814A: bt rf channel keep[5:0]*/ +#else /*_BIG_ENDIAN_ */ + u8 bt_RF_ch_LSB : 6; + u8 ant_div_sw_b : 1; + u8 ant_div_sw_a : 1; +#endif + s8 cfotail[2]; /*DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/ + u8 PCTS_MSK_RPT_0; /*PCTS mask report[7:0]*/ + u8 PCTS_MSK_RPT_1; /*PCTS mask report[15:8]*/ + + /* DWORD 3*/ + s8 rxevm[2]; /*DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/ + s8 rxsnr[2]; /*DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/ + + /* DWORD 4*/ + u8 PCTS_MSK_RPT_2; /*PCTS mask report[23:16]*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 PCTS_MSK_RPT_3 : 6; /*PCTS mask report[29:24]*/ + u8 pcts_rpt_valid : 1; /*pcts_rpt_valid*/ + u8 resvd_1 : 1; /*1'b0*/ +#else /*_BIG_ENDIAN_*/ + u8 resvd_1 : 1; + u8 pcts_rpt_valid : 1; + u8 PCTS_MSK_RPT_3 : 6; +#endif + s8 rxevm_cd[2]; /*DW 4 byte 3 DW5 byte 0 */ + /* 8812A: 16'b0, 8814A: stream 3 and stream 4 RX EVM*/ + + /* DWORD 5*/ + u8 csi_current[2]; /*DW5 byte 1 DW5 byte 2 */ + /* 8812A: stream 1 and 2 CSI, 8814A: path-C and path-D RX SNR*/ + u8 gain_trsw_cd[2]; /*DW5 byte 3 DW6 byte 0 */ + /* path-C and path-D {TRSW, gain[6:0] }*/ + + /* DWORD 6*/ + s8 sigevm; /*signal field EVM*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_antc : 3; /*8812A: 3'b0 8814A: antidx_antc[2:0]*/ + u8 antidx_antd : 3; /*8812A: 3'b0 8814A: antidx_antd[2:0]*/ + u8 dpdt_ctrl_keep : 1; /*8812A: 1'b0 8814A: dpdt_ctrl_keep*/ + u8 GNT_BT_keep : 1; /*8812A: 1'b0 8814A: GNT_BT_keep*/ +#else /*_BIG_ENDIAN_*/ + u8 GNT_BT_keep : 1; + u8 dpdt_ctrl_keep : 1; + u8 antidx_antd : 3; + u8 antidx_antc : 3; +#endif +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_anta : 3; /*antidx_anta[2:0]*/ + u8 antidx_antb : 3; /*antidx_antb[2:0]*/ + u8 hw_antsw_occur : 2; /*1'b0*/ +#else /*_BIG_ENDIAN_*/ + u8 hw_antsw_occur : 2; + u8 antidx_antb : 3; + u8 antidx_anta : 3; +#endif +}; + +void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id); + +void odm_init_rssi_for_dm(struct phy_dm_struct *dm); + +void odm_phy_status_query(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, u8 *phy_status, + struct dm_per_pkt_info *pktinfo); + +void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id, + bool is_packet_match_bssid, bool is_packet_to_self, + bool is_packet_beacon); + +enum hal_status +odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm); + +enum hal_status +odm_config_rf_with_header_file(struct phy_dm_struct *dm, + enum odm_rf_config_type config_type, + enum odm_rf_radio_path e_rf_path); + +enum hal_status +odm_config_bb_with_header_file(struct phy_dm_struct *dm, + enum odm_bb_config_type config_type); + +enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm); + +enum hal_status +odm_config_fw_with_header_file(struct phy_dm_struct *dm, + enum odm_fw_config_type config_type, + u8 *p_firmware, u32 *size); + +u32 odm_get_hw_img_version(struct phy_dm_struct *dm); + +s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig); + +/*For 8822B only!! need to move to FW finally */ +/*==============================================*/ +void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info); + +bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx, + u8 *p_data_rate, u8 *p_gid); + +struct phy_status_rpt_jaguar2_type0 { + /* DW0 */ + u8 page_num; + u8 pwdb; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 gain : 6; + u8 rsvd_0 : 1; + u8 trsw : 1; +#else + u8 trsw : 1; + u8 rsvd_0 : 1; + u8 gain : 6; +#endif + u8 rsvd_1; + + /* DW1 */ + u8 rsvd_2; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 rxsc : 4; + u8 agc_table : 4; +#else + u8 agc_table : 4; + u8 rxsc : 4; +#endif + u8 channel; + u8 band; + + /* DW2 */ + u16 length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_a : 3; + u8 antidx_b : 3; + u8 rsvd_3 : 2; + u8 antidx_c : 3; + u8 antidx_d : 3; + u8 rsvd_4 : 2; +#else + u8 rsvd_3 : 2; + u8 antidx_b : 3; + u8 antidx_a : 3; + u8 rsvd_4 : 2; + u8 antidx_d : 3; + u8 antidx_c : 3; +#endif + + /* DW3 */ + u8 signal_quality; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 vga : 5; + u8 lna_l : 3; + u8 bb_power : 6; + u8 rsvd_9 : 1; + u8 lna_h : 1; +#else + u8 lna_l : 3; + u8 vga : 5; + u8 lna_h : 1; + u8 rsvd_9 : 1; + u8 bb_power : 6; +#endif + u8 rsvd_5; + + /* DW4 */ + u32 rsvd_6; + + /* DW5 */ + u32 rsvd_7; + + /* DW6 */ + u32 rsvd_8; +}; + +struct phy_status_rpt_jaguar2_type1 { + /* DW0 and DW1 */ + u8 page_num; + u8 pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 l_rxsc : 4; + u8 ht_rxsc : 4; +#else + u8 ht_rxsc : 4; + u8 l_rxsc : 4; +#endif + u8 channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 band : 2; + u8 rsvd_0 : 1; + u8 hw_antsw_occu : 1; + u8 gnt_bt : 1; + u8 ldpc : 1; + u8 stbc : 1; + u8 beamformed : 1; +#else + u8 beamformed : 1; + u8 stbc : 1; + u8 ldpc : 1; + u8 gnt_bt : 1; + u8 hw_antsw_occu : 1; + u8 rsvd_0 : 1; + u8 band : 2; +#endif + + /* DW2 */ + u16 lsig_length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_a : 3; + u8 antidx_b : 3; + u8 rsvd_1 : 2; + u8 antidx_c : 3; + u8 antidx_d : 3; + u8 rsvd_2 : 2; +#else + u8 rsvd_1 : 2; + u8 antidx_b : 3; + u8 antidx_a : 3; + u8 rsvd_2 : 2; + u8 antidx_d : 3; + u8 antidx_c : 3; +#endif + + /* DW3 */ + u8 paid; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 paid_msb : 1; + u8 gid : 6; + u8 rsvd_3 : 1; +#else + u8 rsvd_3 : 1; + u8 gid : 6; + u8 paid_msb : 1; +#endif + u8 intf_pos; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 intf_pos_msb : 1; + u8 rsvd_4 : 2; + u8 nb_intf_flag : 1; + u8 rf_mode : 2; + u8 rsvd_5 : 2; +#else + u8 rsvd_5 : 2; + u8 rf_mode : 2; + u8 nb_intf_flag : 1; + u8 rsvd_4 : 2; + u8 intf_pos_msb : 1; +#endif + + /* DW4 */ + s8 rxevm[4]; /* s(8,1) */ + + /* DW5 */ + s8 cfo_tail[4]; /* s(8,7) */ + + /* DW6 */ + s8 rxsnr[4]; /* s(8,1) */ +}; + +struct phy_status_rpt_jaguar2_type2 { + /* DW0 ane DW1 */ + u8 page_num; + u8 pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 l_rxsc : 4; + u8 ht_rxsc : 4; +#else + u8 ht_rxsc : 4; + u8 l_rxsc : 4; +#endif + u8 channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 band : 2; + u8 rsvd_0 : 1; + u8 hw_antsw_occu : 1; + u8 gnt_bt : 1; + u8 ldpc : 1; + u8 stbc : 1; + u8 beamformed : 1; +#else + u8 beamformed : 1; + u8 stbc : 1; + u8 ldpc : 1; + u8 gnt_bt : 1; + u8 hw_antsw_occu : 1; + u8 rsvd_0 : 1; + u8 band : 2; +#endif + +/* DW2 */ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 shift_l_map : 6; + u8 rsvd_1 : 2; +#else + u8 rsvd_1 : 2; + u8 shift_l_map : 6; +#endif + u8 cnt_pw2cca; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 agc_table_a : 4; + u8 agc_table_b : 4; + u8 agc_table_c : 4; + u8 agc_table_d : 4; +#else + u8 agc_table_b : 4; + u8 agc_table_a : 4; + u8 agc_table_d : 4; + u8 agc_table_c : 4; +#endif + + /* DW3 ~ DW6*/ + u8 cnt_cca2agc_rdy; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 gain_a : 6; + u8 rsvd_2 : 1; + u8 trsw_a : 1; + u8 gain_b : 6; + u8 rsvd_3 : 1; + u8 trsw_b : 1; + u8 gain_c : 6; + u8 rsvd_4 : 1; + u8 trsw_c : 1; + u8 gain_d : 6; + u8 rsvd_5 : 1; + u8 trsw_d : 1; + u8 aagc_step_a : 2; + u8 aagc_step_b : 2; + u8 aagc_step_c : 2; + u8 aagc_step_d : 2; +#else + u8 trsw_a : 1; + u8 rsvd_2 : 1; + u8 gain_a : 6; + u8 trsw_b : 1; + u8 rsvd_3 : 1; + u8 gain_b : 6; + u8 trsw_c : 1; + u8 rsvd_4 : 1; + u8 gain_c : 6; + u8 trsw_d : 1; + u8 rsvd_5 : 1; + u8 gain_d : 6; + u8 aagc_step_d : 2; + u8 aagc_step_c : 2; + u8 aagc_step_b : 2; + u8 aagc_step_a : 2; +#endif + u8 ht_aagc_gain[4]; + u8 dagc_gain[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 counter : 6; + u8 rsvd_6 : 2; + u8 syn_count : 5; + u8 rsvd_7 : 3; +#else + u8 rsvd_6 : 2; + u8 counter : 6; + u8 rsvd_7 : 3; + u8 syn_count : 5; +#endif +}; + +u32 query_phydm_trx_capability(struct phy_dm_struct *dm); + +u32 query_phydm_stbc_capability(struct phy_dm_struct *dm); + +u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm); + +u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm); + +u32 query_phydm_txbf_capability(struct phy_dm_struct *dm); + +#endif /*#ifndef __HALHWOUTSRC_H__*/ diff --git a/drivers/staging/rtlwifi/phydm/phydm_interface.c b/drivers/staging/rtlwifi/phydm/phydm_interface.c new file mode 100644 index 0000000000000000000000000000000000000000..102576a46c0415eb6fa2bd53ad5209b80a53a460 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_interface.c @@ -0,0 +1,341 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ + +#include "mp_precomp.h" +#include "phydm_precomp.h" + +/* + * ODM IO Relative API. + */ + +u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_read_byte(rtlpriv, reg_addr); +} + +u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_read_word(rtlpriv, reg_addr); +} + +u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_read_dword(rtlpriv, reg_addr); +} + +void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_write_byte(rtlpriv, reg_addr, data); +} + +void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_write_word(rtlpriv, reg_addr, data); +} + +void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_write_dword(rtlpriv, reg_addr, data); +} + +void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data); +} + +u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask); +} + +void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data); +} + +u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask); +} + +void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_set_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr, + bit_mask, data); +} + +u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_get_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr, + bit_mask); +} + +/* + * ODM Memory relative API. + */ +void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length) +{ + *ptr = kmalloc(length, GFP_ATOMIC); +} + +/* length could be ignored, used to detect memory leakage. */ +void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length) +{ + kfree(ptr); +} + +void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src, + u32 length) +{ + memcpy(p_dest, src, length); +} + +void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length) +{ + memset(pbuf, value, length); +} + +s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2, + u32 length) +{ + return memcmp(p_buf1, buf2, length); +} + +/* + * ODM MISC relative API. + */ +void odm_acquire_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type) +{ +} + +void odm_release_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type) +{ +} + +/* + * ODM Timer relative API. + */ +void odm_stall_execution(u32 us_delay) { udelay(us_delay); } + +void ODM_delay_ms(u32 ms) { mdelay(ms); } + +void ODM_delay_us(u32 us) { udelay(us); } + +void ODM_sleep_ms(u32 ms) { msleep(ms); } + +void ODM_sleep_us(u32 us) { usleep_range(us, us + 1); } + +void odm_set_timer(struct phy_dm_struct *dm, struct timer_list *timer, + u32 ms_delay) +{ + mod_timer(timer, jiffies + msecs_to_jiffies(ms_delay)); +} + +void odm_initialize_timer(struct phy_dm_struct *dm, struct timer_list *timer, + void *call_back_func, void *context, + const char *sz_id) +{ + init_timer(timer); + timer->function = call_back_func; + timer->data = (unsigned long)dm; + /*mod_timer(timer, jiffies+RTL_MILISECONDS_TO_JIFFIES(10)); */ +} + +void odm_cancel_timer(struct phy_dm_struct *dm, struct timer_list *timer) +{ + del_timer(timer); +} + +void odm_release_timer(struct phy_dm_struct *dm, struct timer_list *timer) {} + +static u8 phydm_trans_h2c_id(struct phy_dm_struct *dm, u8 phydm_h2c_id) +{ + u8 platform_h2c_id = phydm_h2c_id; + + switch (phydm_h2c_id) { + /* 1 [0] */ + case ODM_H2C_RSSI_REPORT: + + break; + + /* 1 [3] */ + case ODM_H2C_WIFI_CALIBRATION: + + break; + + /* 1 [4] */ + case ODM_H2C_IQ_CALIBRATION: + + break; + /* 1 [5] */ + case ODM_H2C_RA_PARA_ADJUST: + + break; + + /* 1 [6] */ + case PHYDM_H2C_DYNAMIC_TX_PATH: + + break; + + /* [7]*/ + case PHYDM_H2C_FW_TRACE_EN: + + platform_h2c_id = 0x49; + + break; + + case PHYDM_H2C_TXBF: + break; + + case PHYDM_H2C_MU: + platform_h2c_id = 0x4a; /*H2C_MU*/ + break; + + default: + platform_h2c_id = phydm_h2c_id; + break; + } + + return platform_h2c_id; +} + +/*ODM FW relative API.*/ + +void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 phydm_h2c_id, u32 cmd_len, + u8 *cmd_buffer) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + u8 platform_h2c_id; + + platform_h2c_id = phydm_trans_h2c_id(dm, phydm_h2c_id); + + ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG, + "[H2C] platform_h2c_id = ((0x%x))\n", platform_h2c_id); + + rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->hw, platform_h2c_id, cmd_len, + cmd_buffer); +} + +u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len, + u8 *tmp_buf) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 extend_c2h_sub_id = 0; + u8 find_c2h_cmd = true; + + switch (c2h_cmd_id) { + case PHYDM_C2H_DBG: + phydm_fw_trace_handler(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_RA_RPT: + phydm_c2h_ra_report_handler(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_RA_PARA_RPT: + odm_c2h_ra_para_report_handler(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_DYNAMIC_TX_PATH_RPT: + break; + + case PHYDM_C2H_IQK_FINISH: + break; + + case PHYDM_C2H_DBG_CODE: + phydm_fw_trace_handler_code(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_EXTEND: + extend_c2h_sub_id = tmp_buf[0]; + if (extend_c2h_sub_id == PHYDM_EXTEND_C2H_DBG_PRINT) + phydm_fw_trace_handler_8051(dm, tmp_buf, c2h_cmd_len); + + break; + + default: + find_c2h_cmd = false; + break; + } + + return find_c2h_cmd; +} + +u64 odm_get_current_time(struct phy_dm_struct *dm) { return jiffies; } + +u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time) +{ + return jiffies_to_msecs(jiffies - (u32)start_time); +} + +void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm, + u8 rf_path, u8 channel, + u8 rate_section) +{ + void *adapter = dm->adapter; + + phy_set_tx_power_index_by_rs(adapter, channel, rf_path, rate_section); +} + +u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate, + u8 band_width, u8 channel) +{ + void *adapter = dm->adapter; + + return phy_get_tx_power_index(adapter, (enum odm_rf_radio_path)rf_path, + tx_rate, band_width, channel); +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_interface.h b/drivers/staging/rtlwifi/phydm/phydm_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..d315c79c962aca8cbd268916825ef9a268a0bd08 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_interface.h @@ -0,0 +1,205 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_INTERFACE_H__ +#define __ODM_INTERFACE_H__ + +#define INTERFACE_VERSION "1.1" /*2015.07.29 YuChen*/ + +/* + * =========== Constant/Structure/Enum/... Define + */ + +/* + * =========== Macro Define + */ + +#define _reg_all(_name) ODM_##_name +#define _reg_ic(_name, _ic) ODM_##_name##_ic +#define _bit_all(_name) BIT_##_name +#define _bit_ic(_name, _ic) BIT_##_name##_ic + +/* _cat: implemented by Token-Pasting Operator. */ + +/*=================================== + * + * #define ODM_REG_DIG_11N 0xC50 + * #define ODM_REG_DIG_11AC 0xDDD + * + * ODM_REG(DIG,_pdm_odm) + * =================================== + */ + +#define _reg_11N(_name) ODM_REG_##_name##_11N +#define _reg_11AC(_name) ODM_REG_##_name##_11AC +#define _bit_11N(_name) ODM_BIT_##_name##_11N +#define _bit_11AC(_name) ODM_BIT_##_name##_11AC + +#define _cat(_name, _ic_type, _func) \ + (((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \ + _func##_11AC(_name)) + +/* _name: name of register or bit. + * Example: "ODM_REG(R_A_AGC_CORE1, dm)" + * gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", + * depends on support_ic_type. + */ +#define ODM_REG(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _reg) +#define ODM_BIT(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _bit) +enum phydm_h2c_cmd { + PHYDM_H2C_TXBF = 0x41, + ODM_H2C_RSSI_REPORT = 0x42, + ODM_H2C_IQ_CALIBRATION = 0x45, + ODM_H2C_RA_PARA_ADJUST = 0x47, + PHYDM_H2C_DYNAMIC_TX_PATH = 0x48, + PHYDM_H2C_FW_TRACE_EN = 0x49, + ODM_H2C_WIFI_CALIBRATION = 0x6d, + PHYDM_H2C_MU = 0x4a, + ODM_MAX_H2CCMD +}; + +enum phydm_c2h_evt { + PHYDM_C2H_DBG = 0, + PHYDM_C2H_LB = 1, + PHYDM_C2H_XBF = 2, + PHYDM_C2H_TX_REPORT = 3, + PHYDM_C2H_INFO = 9, + PHYDM_C2H_BT_MP = 11, + PHYDM_C2H_RA_RPT = 12, + PHYDM_C2H_RA_PARA_RPT = 14, + PHYDM_C2H_DYNAMIC_TX_PATH_RPT = 15, + PHYDM_C2H_IQK_FINISH = 17, /*0x11*/ + PHYDM_C2H_DBG_CODE = 0xFE, + PHYDM_C2H_EXTEND = 0xFF, +}; + +enum phydm_extend_c2h_evt { + PHYDM_EXTEND_C2H_DBG_PRINT = 0 + +}; + +/* + * =========== Extern Variable ??? It should be forbidden. + */ + +/* + * =========== EXtern Function Prototype + */ + +u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr); + +u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr); + +u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr); + +void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data); + +void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data); + +void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data); + +void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data); + +u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask); + +void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data); + +u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask); + +void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask, u32 data); + +u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask); + +/* + * Memory Relative Function. + */ +void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length); +void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length); + +void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src, + u32 length); + +s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2, + u32 length); + +void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length); + +/* + * ODM MISC-spin lock relative API. + */ +void odm_acquire_spin_lock(struct phy_dm_struct *dm, + enum rt_spinlock_type type); + +void odm_release_spin_lock(struct phy_dm_struct *dm, + enum rt_spinlock_type type); + +/* + * ODM Timer relative API. + */ +void odm_stall_execution(u32 us_delay); + +void ODM_delay_ms(u32 ms); + +void ODM_delay_us(u32 us); + +void ODM_sleep_ms(u32 ms); + +void ODM_sleep_us(u32 us); + +void odm_set_timer(struct phy_dm_struct *dm, struct timer_list *timer, + u32 ms_delay); + +void odm_initialize_timer(struct phy_dm_struct *dm, struct timer_list *timer, + void *call_back_func, void *context, + const char *sz_id); + +void odm_cancel_timer(struct phy_dm_struct *dm, struct timer_list *timer); + +void odm_release_timer(struct phy_dm_struct *dm, struct timer_list *timer); + +/* + * ODM FW relative API. + */ +void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 element_id, u32 cmd_len, + u8 *cmd_buffer); + +u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len, + u8 *tmp_buf); + +u64 odm_get_current_time(struct phy_dm_struct *dm); +u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time); + +void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm, + u8 rf_path, u8 channel, + u8 rate_section); + +u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate, + u8 band_width, u8 channel); + +#endif /* __ODM_INTERFACE_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_iqk.h b/drivers/staging/rtlwifi/phydm/phydm_iqk.h new file mode 100644 index 0000000000000000000000000000000000000000..0d45bf099aebf8c3643f7ee4b9effd190a97b79c --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_iqk.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMIQK_H__ +#define __PHYDMIQK_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define LOK_delay 1 +#define WBIQK_delay 10 +#define TX_IQK 0 +#define RX_IQK 1 +#define TXIQK 0 +#define RXIQK1 1 +#define RXIQK2 2 +#define GSRXK1 0 +#define GSRXK2 1 +#define kcount_limit_80m 2 +#define kcount_limit_others 4 +#define rxiqk_gs_limit 4 + +#define NUM 4 +/*----------------------End Define Parameters-------------------------------*/ + +struct dm_iqk_info { + bool lok_fail[NUM]; + bool iqk_fail[2][NUM]; + u32 iqc_matrix[2][NUM]; + u8 iqk_times; + u32 rf_reg18; + u32 lna_idx; + u8 rxiqk_step; + u8 tmp1bcc; + u8 kcount; + + u32 iqk_channel[2]; + bool iqk_fail_report[2][4][2]; /*channel/path/TRX(TX:0, RX:1) */ + u32 iqk_cfir_real[2][4][2] + [8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/ + u32 iqk_cfir_imag[2][4][2] + [8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ + u8 retry_count[2][4][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */ + u8 gs_retry_count[2][4][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */ + u8 rxiqk_fail_code[2][4]; /* channel / path + * 0:SRXK1 fail, 1:RXK1 fail 2:RXK2 fail + */ + u32 lok_idac[2][4]; /*channel / path*/ + u16 rxiqk_agc[2][4]; /*channel / path*/ + u32 bypass_iqk[2][4]; /*channel / 0xc94/0xe94*/ + u32 tmp_gntwl; + bool is_btg; + bool isbnd; +}; + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_kfree.c b/drivers/staging/rtlwifi/phydm/phydm_kfree.c new file mode 100644 index 0000000000000000000000000000000000000000..5f3582341806d93796305577bcaec2ff3b326216 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_kfree.c @@ -0,0 +1,228 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*============================================================*/ +/*include files*/ +/*============================================================*/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +/* Add for KFree Feature Requested by RF David.*/ +/*This is a phydm API*/ + +static void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + bool is_odd; + + if ((data % 2) != 0) { /*odd->positive*/ + data = data - 1; + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), + 1); + is_odd = true; + } else { /*even->negative*/ + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), + 0); + is_odd = false; + } + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): RF_0x55[19]= %d\n", __func__, + is_odd); + switch (data) { + case 0: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 0); + cali_info->kfree_offset[e_rf_path] = 0; + break; + case 2: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 0); + cali_info->kfree_offset[e_rf_path] = 0; + break; + case 4: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 1); + cali_info->kfree_offset[e_rf_path] = 1; + break; + case 6: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 1); + cali_info->kfree_offset[e_rf_path] = 1; + break; + case 8: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 2); + cali_info->kfree_offset[e_rf_path] = 2; + break; + case 10: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 2); + cali_info->kfree_offset[e_rf_path] = 2; + break; + case 12: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 3); + cali_info->kfree_offset[e_rf_path] = 3; + break; + case 14: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 3); + cali_info->kfree_offset[e_rf_path] = 3; + break; + case 16: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 4); + cali_info->kfree_offset[e_rf_path] = 4; + break; + case 18: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 4); + cali_info->kfree_offset[e_rf_path] = 4; + break; + case 20: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 5); + cali_info->kfree_offset[e_rf_path] = 5; + break; + + default: + break; + } + + if (!is_odd) { + /*that means Kfree offset is negative, we need to record it.*/ + cali_info->kfree_offset[e_rf_path] = + (-1) * cali_info->kfree_offset[e_rf_path]; + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n", + __func__, cali_info->kfree_offset[e_rf_path]); + } else { + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n", + __func__, cali_info->kfree_offset[e_rf_path]); + } +} + +static void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->support_ic_type & ODM_RTL8814A) + phydm_set_kfree_to_rf_8814a(dm, e_rf_path, data); +} + +void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + u8 rfpath = 0, max_rf_path = 0; + u8 channel_idx = 0; + + if (dm->support_ic_type & ODM_RTL8814A) + max_rf_path = 4; /*0~3*/ + else if (dm->support_ic_type & + (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B)) + max_rf_path = 2; /*0~1*/ + else + max_rf_path = 1; + + ODM_RT_TRACE(dm, ODM_COMP_MP, "===>%s()\n", __func__); + + if (cali_info->reg_rf_kfree_enable == 2) { + ODM_RT_TRACE(dm, ODM_COMP_MP, + "%s(): reg_rf_kfree_enable == 2, Disable\n", + __func__); + return; + } + + if (cali_info->reg_rf_kfree_enable != 1 && + cali_info->reg_rf_kfree_enable != 0) { + ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): reg_rf_kfree_enable == true\n", + __func__); + /*Make sure the targetval is defined*/ + if (((cali_info->reg_rf_kfree_enable == 1) && + (kfree_table[0] != 0xFF)) || + cali_info->rf_kfree_enable) { + /*if kfree_table[0] == 0xff, means no Kfree*/ + if (*dm->band_type == ODM_BAND_2_4G) { + if (channel_to_sw <= 14 && channel_to_sw >= 1) + channel_idx = PHYDM_2G; + } else if (*dm->band_type == ODM_BAND_5G) { + if (channel_to_sw >= 36 && channel_to_sw <= 48) + channel_idx = PHYDM_5GLB1; + if (channel_to_sw >= 52 && channel_to_sw <= 64) + channel_idx = PHYDM_5GLB2; + if (channel_to_sw >= 100 && channel_to_sw <= 120) + channel_idx = PHYDM_5GMB1; + if (channel_to_sw >= 124 && channel_to_sw <= 144) + channel_idx = PHYDM_5GMB2; + if (channel_to_sw >= 149 && channel_to_sw <= 177) + channel_idx = PHYDM_5GHB; + } + + for (rfpath = ODM_RF_PATH_A; rfpath < max_rf_path; rfpath++) { + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): PATH_%d: %#x\n", + __func__, rfpath, + kfree_table[channel_idx * max_rf_path + + rfpath]); + phydm_set_kfree_to_rf( + dm, rfpath, + kfree_table[channel_idx * max_rf_path + + rfpath]); + } + } else { + ODM_RT_TRACE( + dm, ODM_COMP_MP, + "%s(): targetval not defined, Don't execute KFree Process.\n", + __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__); +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_kfree.h b/drivers/staging/rtlwifi/phydm/phydm_kfree.h new file mode 100644 index 0000000000000000000000000000000000000000..1ee60059afc181e15911a957a7a645ae88b32f1f --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_kfree.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMKFREE_H__ +#define __PHYDKFREE_H__ + +#define KFREE_VERSION "1.0" + +enum phydm_kfree_channeltosw { + PHYDM_2G = 0, + PHYDM_5GLB1 = 1, + PHYDM_5GLB2 = 2, + PHYDM_5GMB1 = 3, + PHYDM_5GMB2 = 4, + PHYDM_5GHB = 5, +}; + +void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c new file mode 100644 index 0000000000000000000000000000000000000000..8d79a5add1b4616c9998051b752487ae7f60bee7 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c @@ -0,0 +1,330 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" +#include "phydm_noisemonitor.h" + +/* ************************************************* + * This function is for inband noise test utility only + * To obtain the inband noise level(dbm), do the following. + * 1. disable DIG and Power Saving + * 2. Set initial gain = 0x1a + * 3. Stop updating idle time pwer report (for driver read) + * - 0x80c[25] + * + * **************************************************/ + +#define VALID_MIN -35 +#define VALID_MAX 10 +#define VALID_CNT 5 + +static inline void phydm_set_noise_data_sum(struct noise_level *noise_data, + u8 max_rf_path) +{ + u8 rf_path; + + for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { + if (noise_data->valid_cnt[rf_path]) + noise_data->sum[rf_path] /= + noise_data->valid_cnt[rf_path]; + else + noise_data->sum[rf_path] = 0; + } +} + +static s16 odm_inband_noise_monitor_n_series(struct phy_dm_struct *dm, + u8 is_pause_dig, u8 igi_value, + u32 max_time) +{ + u32 tmp4b; + u8 max_rf_path = 0, rf_path; + u8 reg_c50, reg_c58, valid_done = 0; + struct noise_level noise_data; + u64 start = 0, func_start = 0, func_end = 0; + + func_start = odm_get_current_time(dm); + dm->noise_level.noise_all = 0; + + if ((dm->rf_type == ODM_1T2R) || (dm->rf_type == ODM_2T2R)) + max_rf_path = 2; + else + max_rf_path = 1; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() ==>\n", __func__); + + odm_memory_set(dm, &noise_data, 0, sizeof(struct noise_level)); + + /* */ + /* step 1. Disable DIG && Set initial gain. */ + /* */ + + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value); + /* */ + /* step 2. Disable all power save for read registers */ + /* */ + /* dcmd_DebugControlPowerSave(adapter, PSDisable); */ + + /* */ + /* step 3. Get noise power level */ + /* */ + start = odm_get_current_time(dm); + while (1) { + /* Stop updating idle time pwer report (for driver read) */ + odm_set_bb_reg(dm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 1); + + /* Read Noise Floor Report */ + tmp4b = odm_get_bb_reg(dm, 0x8f8, MASKDWORD); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b); + + /* update idle time pwer report per 5us */ + odm_set_bb_reg(dm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 0); + + noise_data.value[ODM_RF_PATH_A] = (u8)(tmp4b & 0xff); + noise_data.value[ODM_RF_PATH_B] = (u8)((tmp4b & 0xff00) >> 8); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "value_a = 0x%x(%d), value_b = 0x%x(%d)\n", + noise_data.value[ODM_RF_PATH_A], + noise_data.value[ODM_RF_PATH_A], + noise_data.value[ODM_RF_PATH_B], + noise_data.value[ODM_RF_PATH_B]); + + for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; + rf_path++) { + noise_data.sval[rf_path] = + (s8)noise_data.value[rf_path]; + noise_data.sval[rf_path] /= 2; + } + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "sval_a = %d, sval_b = %d\n", + noise_data.sval[ODM_RF_PATH_A], + noise_data.sval[ODM_RF_PATH_B]); + + for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; + rf_path++) { + if (!(noise_data.valid_cnt[rf_path] < VALID_CNT) || + !(noise_data.sval[rf_path] < VALID_MAX && + noise_data.sval[rf_path] >= VALID_MIN)) { + continue; + } + + noise_data.valid_cnt[rf_path]++; + noise_data.sum[rf_path] += noise_data.sval[rf_path]; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "rf_path:%d Valid sval = %d\n", rf_path, + noise_data.sval[rf_path]); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Sum of sval = %d,\n", + noise_data.sum[rf_path]); + if (noise_data.valid_cnt[rf_path] == VALID_CNT) { + valid_done++; + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "After divided, rf_path:%d,sum = %d\n", + rf_path, noise_data.sum[rf_path]); + } + } + + if ((valid_done == max_rf_path) || + (odm_get_progressing_time(dm, start) > max_time)) { + phydm_set_noise_data_sum(&noise_data, max_rf_path); + break; + } + } + reg_c50 = (u8)odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKBYTE0); + reg_c50 &= ~BIT(7); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "0x%x = 0x%02x(%d)\n", + REG_OFDM_0_XA_AGC_CORE1, reg_c50, reg_c50); + dm->noise_level.noise[ODM_RF_PATH_A] = + (u8)(-110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]); + dm->noise_level.noise_all += dm->noise_level.noise[ODM_RF_PATH_A]; + + if (max_rf_path == 2) { + reg_c58 = (u8)odm_get_bb_reg(dm, REG_OFDM_0_XB_AGC_CORE1, + MASKBYTE0); + reg_c58 &= ~BIT(7); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "0x%x = 0x%02x(%d)\n", + REG_OFDM_0_XB_AGC_CORE1, reg_c58, reg_c58); + dm->noise_level.noise[ODM_RF_PATH_B] = + (u8)(-110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]); + dm->noise_level.noise_all += + dm->noise_level.noise[ODM_RF_PATH_B]; + } + dm->noise_level.noise_all /= max_rf_path; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "noise_a = %d, noise_b = %d\n", + dm->noise_level.noise[ODM_RF_PATH_A], + dm->noise_level.noise[ODM_RF_PATH_B]); + + /* */ + /* step 4. Recover the Dig */ + /* */ + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value); + func_end = odm_get_progressing_time(dm, func_start); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() <==\n", __func__); + return dm->noise_level.noise_all; +} + +static s16 odm_inband_noise_monitor_ac_series(struct phy_dm_struct *dm, + u8 is_pause_dig, u8 igi_value, + u32 max_time) +{ + s32 rxi_buf_anta, rxq_buf_anta; /*rxi_buf_antb, rxq_buf_antb;*/ + s32 value32, pwdb_A = 0, sval, noise, sum; + bool pd_flag; + u8 valid_cnt; + u64 start = 0, func_start = 0, func_end = 0; + + if (!(dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A))) + return 0; + + func_start = odm_get_current_time(dm); + dm->noise_level.noise_all = 0; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() ==>\n", __func__); + + /* step 1. Disable DIG && Set initial gain. */ + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value); + + /* step 2. Disable all power save for read registers */ + /*dcmd_DebugControlPowerSave(adapter, PSDisable); */ + + /* step 3. Get noise power level */ + start = odm_get_current_time(dm); + + /* reset counters */ + sum = 0; + valid_cnt = 0; + + /* step 3. Get noise power level */ + while (1) { + /*Set IGI=0x1C */ + odm_write_dig(dm, 0x1C); + /*stop CK320&CK88 */ + odm_set_bb_reg(dm, 0x8B4, BIT(6), 1); + /*Read path-A */ + odm_set_bb_reg(dm, 0x8FC, MASKDWORD, 0x200); /*set debug port*/ + value32 = odm_get_bb_reg(dm, 0xFA0, + MASKDWORD); /*read debug port*/ + + rxi_buf_anta = (value32 & 0xFFC00) >> + 10; /*rxi_buf_anta=RegFA0[19:10]*/ + rxq_buf_anta = value32 & 0x3FF; /*rxq_buf_anta=RegFA0[19:10]*/ + + pd_flag = (bool)((value32 & BIT(31)) >> 31); + + /*Not in packet detection period or Tx state */ + if ((!pd_flag) || (rxi_buf_anta != 0x200)) { + /*sign conversion*/ + rxi_buf_anta = odm_sign_conversion(rxi_buf_anta, 10); + rxq_buf_anta = odm_sign_conversion(rxq_buf_anta, 10); + + pwdb_A = odm_pwdb_conversion( + rxi_buf_anta * rxi_buf_anta + + rxq_buf_anta * rxq_buf_anta, + 20, 18); /*S(10,9)*S(10,9)=S(20,18)*/ + + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "pwdb_A= %d dB, rxi_buf_anta= 0x%x, rxq_buf_anta= 0x%x\n", + pwdb_A, rxi_buf_anta & 0x3FF, + rxq_buf_anta & 0x3FF); + } + /*Start CK320&CK88*/ + odm_set_bb_reg(dm, 0x8B4, BIT(6), 0); + /*BB Reset*/ + odm_write_1byte(dm, 0x02, odm_read_1byte(dm, 0x02) & (~BIT(0))); + odm_write_1byte(dm, 0x02, odm_read_1byte(dm, 0x02) | BIT(0)); + /*PMAC Reset*/ + odm_write_1byte(dm, 0xB03, + odm_read_1byte(dm, 0xB03) & (~BIT(0))); + odm_write_1byte(dm, 0xB03, odm_read_1byte(dm, 0xB03) | BIT(0)); + /*CCK Reset*/ + if (odm_read_1byte(dm, 0x80B) & BIT(4)) { + odm_write_1byte(dm, 0x80B, + odm_read_1byte(dm, 0x80B) & (~BIT(4))); + odm_write_1byte(dm, 0x80B, + odm_read_1byte(dm, 0x80B) | BIT(4)); + } + + sval = pwdb_A; + + if ((sval < 0 && sval >= -27) && (valid_cnt < VALID_CNT)) { + valid_cnt++; + sum += sval; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Valid sval = %d\n", + sval); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Sum of sval = %d,\n", + sum); + if ((valid_cnt >= VALID_CNT) || + (odm_get_progressing_time(dm, start) > max_time)) { + sum /= VALID_CNT; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "After divided, sum = %d\n", sum); + break; + } + } + } + + /*ADC backoff is 12dB,*/ + /*Ptarget=0x1C-110=-82dBm*/ + noise = sum + 12 + 0x1C - 110; + + /*Offset*/ + noise = noise - 3; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "noise = %d\n", noise); + dm->noise_level.noise_all = (s16)noise; + + /* step 4. Recover the Dig*/ + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value); + + func_end = odm_get_progressing_time(dm, func_start); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() <==\n", __func__); + + return dm->noise_level.noise_all; +} + +s16 odm_inband_noise_monitor(void *dm_void, u8 is_pause_dig, u8 igi_value, + u32 max_time) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) + return odm_inband_noise_monitor_ac_series(dm, is_pause_dig, + igi_value, max_time); + else + return odm_inband_noise_monitor_n_series(dm, is_pause_dig, + igi_value, max_time); +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..a711b7954985f0cdd65d4b503940360c014d42bc --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __ODMNOISEMONITOR_H__ +#define __ODMNOISEMONITOR_H__ + +#define ODM_MAX_CHANNEL_NUM 38 /* 14+24 */ +struct noise_level { + u8 value[MAX_RF_PATH]; + s8 sval[MAX_RF_PATH]; + + s32 sum[MAX_RF_PATH]; + u8 valid[MAX_RF_PATH]; + u8 valid_cnt[MAX_RF_PATH]; +}; + +struct odm_noise_monitor { + s8 noise[MAX_RF_PATH]; + s16 noise_all; +}; + +s16 odm_inband_noise_monitor(void *dm_void, u8 is_pause_dig, u8 igi_value, + u32 max_time); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c new file mode 100644 index 0000000000000000000000000000000000000000..48e73eb1622b36a6f964d4aa947d315380628814 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c @@ -0,0 +1,644 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*============================================================ */ +/* include files */ +/*============================================================ */ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +/* ************************************************************ + * Global var + * *************************************************************/ + +u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, /* 0, +6.0dB */ + 0x788001e2, /* 1, +5.5dB */ + 0x71c001c7, /* 2, +5.0dB*/ + 0x6b8001ae, /* 3, +4.5dB*/ + 0x65400195, /* 4, +4.0dB*/ + 0x5fc0017f, /* 5, +3.5dB*/ + 0x5a400169, /* 6, +3.0dB*/ + 0x55400155, /* 7, +2.5dB*/ + 0x50800142, /* 8, +2.0dB*/ + 0x4c000130, /* 9, +1.5dB*/ + 0x47c0011f, /* 10, +1.0dB*/ + 0x43c0010f, /* 11, +0.5dB*/ + 0x40000100, /* 12, +0dB*/ + 0x3c8000f2, /* 13, -0.5dB*/ + 0x390000e4, /* 14, -1.0dB*/ + 0x35c000d7, /* 15, -1.5dB*/ + 0x32c000cb, /* 16, -2.0dB*/ + 0x300000c0, /* 17, -2.5dB*/ + 0x2d4000b5, /* 18, -3.0dB*/ + 0x2ac000ab, /* 19, -3.5dB*/ + 0x288000a2, /* 20, -4.0dB*/ + 0x26000098, /* 21, -4.5dB*/ + 0x24000090, /* 22, -5.0dB*/ + 0x22000088, /* 23, -5.5dB*/ + 0x20000080, /* 24, -6.0dB*/ + 0x1e400079, /* 25, -6.5dB*/ + 0x1c800072, /* 26, -7.0dB*/ + 0x1b00006c, /* 27. -7.5dB*/ + 0x19800066, /* 28, -8.0dB*/ + 0x18000060, /* 29, -8.5dB*/ + 0x16c0005b, /* 30, -9.0dB*/ + 0x15800056, /* 31, -9.5dB*/ + 0x14400051, /* 32, -10.0dB*/ + 0x1300004c, /* 33, -10.5dB*/ + 0x12000048, /* 34, -11.0dB*/ + 0x11000044, /* 35, -11.5dB*/ + 0x10000040, /* 36, -12.0dB*/ +}; + +u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB*/ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB*/ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB*/ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB*/ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB*/ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB*/ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB*/ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, + 0x02}, /* 12, -6.0dB <== default */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB*/ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB*/ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB*/ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB*/ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/ +}; + +u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB*/ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB*/ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB*/ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB*/ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, + 0x00}, /* 12, -6.0dB <== default*/ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB*/ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB*/ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB*/ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/ +}; + +u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { + 0x0b40002d, /* 0, -15.0dB */ + 0x0c000030, /* 1, -14.5dB*/ + 0x0cc00033, /* 2, -14.0dB*/ + 0x0d800036, /* 3, -13.5dB*/ + 0x0e400039, /* 4, -13.0dB */ + 0x0f00003c, /* 5, -12.5dB*/ + 0x10000040, /* 6, -12.0dB*/ + 0x11000044, /* 7, -11.5dB*/ + 0x12000048, /* 8, -11.0dB*/ + 0x1300004c, /* 9, -10.5dB*/ + 0x14400051, /* 10, -10.0dB*/ + 0x15800056, /* 11, -9.5dB*/ + 0x16c0005b, /* 12, -9.0dB*/ + 0x18000060, /* 13, -8.5dB*/ + 0x19800066, /* 14, -8.0dB*/ + 0x1b00006c, /* 15, -7.5dB*/ + 0x1c800072, /* 16, -7.0dB*/ + 0x1e400079, /* 17, -6.5dB*/ + 0x20000080, /* 18, -6.0dB*/ + 0x22000088, /* 19, -5.5dB*/ + 0x24000090, /* 20, -5.0dB*/ + 0x26000098, /* 21, -4.5dB*/ + 0x288000a2, /* 22, -4.0dB*/ + 0x2ac000ab, /* 23, -3.5dB*/ + 0x2d4000b5, /* 24, -3.0dB*/ + 0x300000c0, /* 25, -2.5dB*/ + 0x32c000cb, /* 26, -2.0dB*/ + 0x35c000d7, /* 27, -1.5dB*/ + 0x390000e4, /* 28, -1.0dB*/ + 0x3c8000f2, /* 29, -0.5dB*/ + 0x40000100, /* 30, +0dB*/ + 0x43c0010f, /* 31, +0.5dB*/ + 0x47c0011f, /* 32, +1.0dB*/ + 0x4c000130, /* 33, +1.5dB*/ + 0x50800142, /* 34, +2.0dB*/ + 0x55400155, /* 35, +2.5dB*/ + 0x5a400169, /* 36, +3.0dB*/ + 0x5fc0017f, /* 37, +3.5dB*/ + 0x65400195, /* 38, +4.0dB*/ + 0x6b8001ae, /* 39, +4.5dB*/ + 0x71c001c7, /* 40, +5.0dB*/ + 0x788001e2, /* 41, +5.5dB*/ + 0x7f8001fe /* 42, +6.0dB*/ +}; + +u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { + {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { + {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { + {0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB*/ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB*/ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB*/ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB*/ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB*/ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB*/ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB*/ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB*/ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB*/ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB*/ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB*/ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB*/ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB*/ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB*/ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB*/ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB*/ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB*/ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*20, -6.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB*/ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB*/ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB*/ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB*/ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB*/ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB*/ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB*/ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB*/ + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/ +}; + +u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB*/ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB*/ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB*/ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB*/ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB*/ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*5, -13.5dB*/ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB*/ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB*/ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB*/ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB*/ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB*/ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /*11, -10.5dB*/ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB*/ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB*/ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*14, -9.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB*/ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB*/ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB*/ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /*23, -4.5dB*/ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /*27, -2.5dB*/ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /*29, -1.5dB*/ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */ + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */ +}; + +u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { + 0x0CD, /*0 , -20dB*/ + 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 0x16C, + 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 0x287, + 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 0x47F, + 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 0x7FF, +}; + +/* JJ ADD 20161014 */ +u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { + 0x0CD, /*0 , -20dB*/ + 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 0x16C, + 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 0x287, + 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 0x47F, + 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 0x7FF, +}; + +u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = { + 0x081, /* 0, -12.0dB*/ + 0x088, /* 1, -11.5dB*/ + 0x090, /* 2, -11.0dB*/ + 0x099, /* 3, -10.5dB*/ + 0x0A2, /* 4, -10.0dB*/ + 0x0AC, /* 5, -9.5dB*/ + 0x0B6, /* 6, -9.0dB*/ + 0x0C0, /*7, -8.5dB*/ + 0x0CC, /* 8, -8.0dB*/ + 0x0D8, /* 9, -7.5dB*/ + 0x0E5, /* 10, -7.0dB*/ + 0x0F2, /* 11, -6.5dB*/ + 0x101, /* 12, -6.0dB*/ + 0x110, /* 13, -5.5dB*/ + 0x120, /* 14, -5.0dB*/ + 0x131, /* 15, -4.5dB*/ + 0x143, /* 16, -4.0dB*/ + 0x156, /* 17, -3.5dB*/ + 0x16A, /* 18, -3.0dB*/ + 0x180, /* 19, -2.5dB*/ + 0x197, /* 20, -2.0dB*/ + 0x1AF, /* 21, -1.5dB*/ + 0x1C8, /* 22, -1.0dB*/ + 0x1E3, /* 23, -0.5dB*/ + 0x200, /* 24, +0 dB*/ + 0x21E, /* 25, +0.5dB*/ + 0x23E, /* 26, +1.0dB*/ + 0x261, /* 27, +1.5dB*/ + 0x285, /* 28, +2.0dB*/ + 0x2AB, /* 29, +2.5dB*/ + 0x2D3, /*30, +3.0dB*/ + 0x2FE, /* 31, +3.5dB*/ + 0x32B, /* 32, +4.0dB*/ + 0x35C, /* 33, +4.5dB*/ + 0x38E, /* 34, +5.0dB*/ + 0x3C4, /* 35, +5.5dB*/ + 0x3FE /* 36, +6.0dB */ +}; + +void odm_txpowertracking_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + odm_txpowertracking_thermal_meter_init(dm); +} + +static u8 get_swing_index(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 i = 0; + u32 bb_swing; + u32 swing_table_size; + u32 *swing_table; + + if (dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8188F || + dm->support_ic_type == ODM_RTL8703B) { + bb_swing = odm_get_bb_reg(dm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + 0xFFC00000); + + swing_table = ofdm_swing_table_new; + swing_table_size = OFDM_TABLE_SIZE; + } else { + { + bb_swing = 0; + swing_table = ofdm_swing_table; + swing_table_size = OFDM_TABLE_SIZE; + } + } + + for (i = 0; i < swing_table_size; ++i) { + u32 table_value = swing_table[i]; + + if (table_value >= 0x100000) + table_value >>= 22; + if (bb_swing == table_value) + break; + } + return i; +} + +void odm_txpowertracking_thermal_meter_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 default_swing_index = get_swing_index(dm); + u8 p = 0; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv); + + cali_info->is_txpowertracking = true; + cali_info->tx_powercount = 0; + cali_info->is_txpowertracking_init = false; + + if (!dm->mp_mode) + cali_info->txpowertrack_control = true; + else + cali_info->txpowertrack_control = false; + + if (!dm->mp_mode) + cali_info->txpowertrack_control = true; + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "dm txpowertrack_control = %d\n", + cali_info->txpowertrack_control); + + /* dm->rf_calibrate_info.txpowertrack_control = true; */ + cali_info->thermal_value = rtlefu->eeprom_thermalmeter; + cali_info->thermal_value_iqk = rtlefu->eeprom_thermalmeter; + cali_info->thermal_value_lck = rtlefu->eeprom_thermalmeter; + + if (!cali_info->default_bb_swing_index_flag) { + /*The index of "0 dB" in SwingTable.*/ + if (dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8703B) { + cali_info->default_ofdm_index = + (default_swing_index >= OFDM_TABLE_SIZE) ? + 30 : + default_swing_index; + cali_info->default_cck_index = 20; + } else if (dm->support_ic_type == + ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/ + cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/ + cali_info->default_cck_index = 20; /*CCK:-6dB*/ + } else if (dm->support_ic_type == + ODM_RTL8723D) { /*add by zhaohe 2015-10-27*/ + cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/ + cali_info->default_cck_index = 28; /*CCK: -6dB*/ + } else if (dm->support_ic_type == + ODM_RTL8710B) { /* JJ ADD 20161014 */ + cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/ + cali_info->default_cck_index = 28; /*CCK: -6dB*/ + } else { + cali_info->default_ofdm_index = + (default_swing_index >= TXSCALE_TABLE_SIZE) ? + 24 : + default_swing_index; + cali_info->default_cck_index = 24; + } + cali_info->default_bb_swing_index_flag = true; + } + + cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index; + cali_info->CCK_index = cali_info->default_cck_index; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) { + cali_info->bb_swing_idx_ofdm_base[p] = + cali_info->default_ofdm_index; + cali_info->OFDM_index[p] = cali_info->default_ofdm_index; + cali_info->delta_power_index[p] = 0; + cali_info->delta_power_index_last[p] = 0; + cali_info->power_index_offset[p] = 0; + } + cali_info->modify_tx_agc_value_ofdm = 0; + cali_info->modify_tx_agc_value_cck = 0; +} + +void odm_txpowertracking_check(void *dm_void) +{ + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + switch (dm->support_platform) { + case ODM_WIN: + odm_txpowertracking_check_mp(dm); + break; + + case ODM_CE: + odm_txpowertracking_check_ce(dm); + break; + + case ODM_AP: + odm_txpowertracking_check_ap(dm); + break; + + default: + break; + } +} + +void odm_txpowertracking_check_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + void *adapter = dm->adapter; + + if (!(dm->support_ability & ODM_RF_TX_PWR_TRACK)) + return; + + if (!dm->rf_calibrate_info.tm_trigger) { + if (IS_HARDWARE_TYPE_8188E(adapter) || + IS_HARDWARE_TYPE_8188F(adapter) || + IS_HARDWARE_TYPE_8192E(adapter) || + IS_HARDWARE_TYPE_8723B(adapter) || + IS_HARDWARE_TYPE_JAGUAR(adapter) || + IS_HARDWARE_TYPE_8814A(adapter) || + IS_HARDWARE_TYPE_8703B(adapter) || + IS_HARDWARE_TYPE_8723D(adapter) || + IS_HARDWARE_TYPE_8822B(adapter) || + IS_HARDWARE_TYPE_8821C(adapter) || + (dm->support_ic_type == ODM_RTL8710B)) /* JJ ADD 20161014 */ + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_T_METER_NEW, + (BIT(17) | BIT(16)), 0x03); + else + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_T_METER_OLD, + RFREGOFFSETMASK, 0x60); + + dm->rf_calibrate_info.tm_trigger = 1; + return; + } + + odm_txpowertracking_callback_thermal_meter(dm); + dm->rf_calibrate_info.tm_trigger = 0; +} + +void odm_txpowertracking_check_mp(void *dm_void) {} + +void odm_txpowertracking_check_ap(void *dm_void) {} diff --git a/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h new file mode 100644 index 0000000000000000000000000000000000000000..757d7720d931878a2283c019f578fd06f71fca78 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h @@ -0,0 +1,293 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMPOWERTRACKING_H__ +#define __PHYDMPOWERTRACKING_H__ + +#define POWRTRACKING_VERSION "1.1" + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#define CCK_TABLE_SIZE_88F 21 +#define TXSCALE_TABLE_SIZE 37 +#define CCK_TABLE_SIZE_8723D 41 +/* JJ ADD 20161014 */ +#define CCK_TABLE_SIZE_8710B 41 + +#define TXPWR_TRACK_TABLE_SIZE 30 +#define DELTA_SWINGIDX_SIZE 30 +#define DELTA_SWINTSSI_SIZE 61 +#define BAND_NUM 4 + +#define AVG_THERMAL_NUM 8 +#define HP_THERMAL_NUM 8 +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM_MAX 10 + +#define IQK_BB_REG_NUM 9 + +#define iqk_matrix_reg_num 8 + +extern u32 ofdm_swing_table[OFDM_TABLE_SIZE]; +extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8]; +extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8]; + +extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE]; +extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8]; +extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8]; +extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16]; +extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D]; +/* JJ ADD 20161014 */ +extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B]; + +extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE]; + +/* <20121018, Kordan> In case fail to read TxPowerTrack.txt, + * we use the table of 88E as the default table. + */ + +#define dm_check_txpowertracking odm_txpowertracking_check + +struct iqk_matrix_regs_setting { + bool is_iqk_done; + s32 value[3][iqk_matrix_reg_num]; + bool is_bw_iqk_result_saved[3]; +}; + +struct dm_rf_calibration_struct { + /* for tx power tracking */ + + u32 rega24; /* for TempCCK */ + s32 rege94; + s32 rege9c; + s32 regeb4; + s32 regebc; + + u8 tx_powercount; + bool is_txpowertracking_init; + bool is_txpowertracking; + /* for mp mode, turn off txpwrtracking as default */ + u8 txpowertrack_control; + u8 tm_trigger; + u8 internal_pa_5g[2]; /* pathA / pathB */ + + u8 thermal_meter + [2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */ + u8 thermal_value; + u8 thermal_value_lck; + u8 thermal_value_iqk; + s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */ + u8 thermal_value_dpk; + u8 thermal_value_avg[AVG_THERMAL_NUM]; + u8 thermal_value_avg_index; + u8 thermal_value_rx_gain; + u8 thermal_value_crystal; + u8 thermal_value_dpk_store; + u8 thermal_value_dpk_track; + bool txpowertracking_in_progress; + + bool is_reloadtxpowerindex; + u8 is_rf_pi_enable; + u32 txpowertracking_callback_cnt; /* cosa add for debug */ + + /* ---------------------- Tx power Tracking ------------------------- */ + u8 is_cck_in_ch14; + u8 CCK_index; + u8 OFDM_index[MAX_RF_PATH]; + s8 power_index_offset[MAX_RF_PATH]; + s8 delta_power_index[MAX_RF_PATH]; + s8 delta_power_index_last[MAX_RF_PATH]; + bool is_tx_power_changed; + s8 xtal_offset; + s8 xtal_offset_last; + + u8 thermal_value_hp[HP_THERMAL_NUM]; + u8 thermal_value_hp_index; + struct iqk_matrix_regs_setting + iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM]; + u8 delta_lck; + s8 bb_swing_diff_2g, bb_swing_diff_5g; /* Unit: dB */ + u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE]; + s8 delta_swing_table_xtal_p[DELTA_SWINGIDX_SIZE]; + s8 delta_swing_table_xtal_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE]; + + u8 bb_swing_idx_ofdm[MAX_RF_PATH]; + u8 bb_swing_idx_ofdm_current; + u8 bb_swing_idx_ofdm_base[MAX_RF_PATH]; + bool default_bb_swing_index_flag; + bool bb_swing_flag_ofdm; + u8 bb_swing_idx_cck; + u8 bb_swing_idx_cck_current; + u8 bb_swing_idx_cck_base; + u8 default_ofdm_index; + u8 default_cck_index; + bool bb_swing_flag_cck; + + s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_ofdm_swing_idx[MAX_RF_PATH]; + s8 absolute_cck_swing_idx[MAX_RF_PATH]; + s8 remnant_cck_swing_idx; + s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */ + bool modify_tx_agc_flag_path_a; + bool modify_tx_agc_flag_path_b; + bool modify_tx_agc_flag_path_c; + bool modify_tx_agc_flag_path_d; + bool modify_tx_agc_flag_path_a_cck; + + s8 kfree_offset[MAX_RF_PATH]; + + /* ------------------------------------------------------------------ */ + + /* for IQK */ + u32 regc04; + u32 reg874; + u32 regc08; + u32 regb68; + u32 regb6c; + u32 reg870; + u32 reg860; + u32 reg864; + + bool is_iqk_initialized; + bool is_lck_in_progress; + bool is_antenna_detected; + bool is_need_iqk; + bool is_iqk_in_progress; + bool is_iqk_pa_off; + u8 delta_iqk; + u32 ADDA_backup[IQK_ADDA_REG_NUM]; + u32 IQK_MAC_backup[IQK_MAC_REG_NUM]; + u32 IQK_BB_backup_recover[9]; + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */ + u32 IQK_BB_backup[IQK_BB_REG_NUM]; + u32 tx_iqc_8723b[2][3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */ + u32 rx_iqc_8723b[2][2][2]; + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u32 tx_iqc_8703b[3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + u32 rx_iqc_8703b[2][2]; + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u32 tx_iqc_8723d[2][3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + u32 rx_iqc_8723d[2][2][2]; + /* JJ ADD 20161014 */ + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u32 tx_iqc_8710b[2][3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + u32 rx_iqc_8710b[2][2][2]; + + u8 iqk_step; + u8 kcount; + u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */ + bool is_mp_mode; + + /* IQK time measurement */ + u64 iqk_start_time; + u64 iqk_progressing_time; + u64 iqk_total_progressing_time; + + u32 lok_result; + + /* for APK */ + u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */ + u8 is_ap_kdone; + u8 is_apk_thermal_meter_ignore; + + /* DPK */ + bool is_dpk_fail; + u8 is_dp_done; + u8 is_dp_path_aok; + u8 is_dp_path_bok; + + u32 tx_lok[2]; + u32 dpk_tx_agc; + s32 dpk_gain; + u32 dpk_thermal[4]; + s8 modify_tx_agc_value_ofdm; + s8 modify_tx_agc_value_cck; + + /*Add by Yuchen for Kfree Phydm*/ + u8 reg_rf_kfree_enable; /*for registry*/ + u8 rf_kfree_enable; /*for efuse enable check*/ +}; + +void odm_txpowertracking_check(void *dm_void); + +void odm_txpowertracking_init(void *dm_void); + +void odm_txpowertracking_check_ap(void *dm_void); + +void odm_txpowertracking_thermal_meter_init(void *dm_void); + +void odm_txpowertracking_init(void *dm_void); + +void odm_txpowertracking_check_mp(void *dm_void); + +void odm_txpowertracking_check_ce(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_pre_define.h b/drivers/staging/rtlwifi/phydm/phydm_pre_define.h new file mode 100644 index 0000000000000000000000000000000000000000..6c301fe87b3de06a780c0610483c2c6c756973a0 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_pre_define.h @@ -0,0 +1,613 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMPREDEFINE_H__ +#define __PHYDMPREDEFINE_H__ + +/* 1 ============================================================ + * 1 Definition + * 1 ============================================================ + */ + +#define PHYDM_CODE_BASE "PHYDM_TRUNK" +#define PHYDM_RELEASE_DATE "00000000" + +/* Max path of IC */ +#define MAX_PATH_NUM_8188E 1 +#define MAX_PATH_NUM_8192E 2 +#define MAX_PATH_NUM_8723B 1 +#define MAX_PATH_NUM_8812A 2 +#define MAX_PATH_NUM_8821A 1 +#define MAX_PATH_NUM_8814A 4 +#define MAX_PATH_NUM_8822B 2 +#define MAX_PATH_NUM_8821B 2 +#define MAX_PATH_NUM_8703B 1 +#define MAX_PATH_NUM_8188F 1 +#define MAX_PATH_NUM_8723D 1 +#define MAX_PATH_NUM_8197F 2 +#define MAX_PATH_NUM_8821C 1 +/* JJ ADD 20161014 */ +#define MAX_PATH_NUM_8710B 1 + +/* Max RF path */ +#define ODM_RF_PATH_MAX 2 +#define ODM_RF_PATH_MAX_JAGUAR 4 + +/*Bit define path*/ +#define PHYDM_A BIT(0) +#define PHYDM_B BIT(1) +#define PHYDM_C BIT(2) +#define PHYDM_D BIT(3) +#define PHYDM_AB (BIT(0) | BIT(1)) +#define PHYDM_AC (BIT(0) | BIT(2)) +#define PHYDM_AD (BIT(0) | BIT(3)) +#define PHYDM_BC (BIT(1) | BIT(2)) +#define PHYDM_BD (BIT(1) | BIT(3)) +#define PHYDM_CD (BIT(2) | BIT(3)) +#define PHYDM_ABC (BIT(0) | BIT(1) | BIT(2)) +#define PHYDM_ABD (BIT(0) | BIT(1) | BIT(3)) +#define PHYDM_ACD (BIT(0) | BIT(2) | BIT(3)) +#define PHYDM_BCD (BIT(1) | BIT(2) | BIT(3)) +#define PHYDM_ABCD (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +/* number of entry */ +/* defined in wifi.h (32+1) */ +#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM + +#define RX_SMOOTH_FACTOR 20 + +/* -----MGN rate--------------------------------- */ + +enum ODM_MGN_RATE { + ODM_MGN_1M = 0x02, + ODM_MGN_2M = 0x04, + ODM_MGN_5_5M = 0x0B, + ODM_MGN_6M = 0x0C, + ODM_MGN_9M = 0x12, + ODM_MGN_11M = 0x16, + ODM_MGN_12M = 0x18, + ODM_MGN_18M = 0x24, + ODM_MGN_24M = 0x30, + ODM_MGN_36M = 0x48, + ODM_MGN_48M = 0x60, + ODM_MGN_54M = 0x6C, + ODM_MGN_MCS32 = 0x7F, + ODM_MGN_MCS0, + ODM_MGN_MCS1, + ODM_MGN_MCS2, + ODM_MGN_MCS3, + ODM_MGN_MCS4, + ODM_MGN_MCS5, + ODM_MGN_MCS6, + ODM_MGN_MCS7, + ODM_MGN_MCS8, + ODM_MGN_MCS9, + ODM_MGN_MCS10, + ODM_MGN_MCS11, + ODM_MGN_MCS12, + ODM_MGN_MCS13, + ODM_MGN_MCS14, + ODM_MGN_MCS15, + ODM_MGN_MCS16, + ODM_MGN_MCS17, + ODM_MGN_MCS18, + ODM_MGN_MCS19, + ODM_MGN_MCS20, + ODM_MGN_MCS21, + ODM_MGN_MCS22, + ODM_MGN_MCS23, + ODM_MGN_MCS24, + ODM_MGN_MCS25, + ODM_MGN_MCS26, + ODM_MGN_MCS27, + ODM_MGN_MCS28, + ODM_MGN_MCS29, + ODM_MGN_MCS30, + ODM_MGN_MCS31, + ODM_MGN_VHT1SS_MCS0, + ODM_MGN_VHT1SS_MCS1, + ODM_MGN_VHT1SS_MCS2, + ODM_MGN_VHT1SS_MCS3, + ODM_MGN_VHT1SS_MCS4, + ODM_MGN_VHT1SS_MCS5, + ODM_MGN_VHT1SS_MCS6, + ODM_MGN_VHT1SS_MCS7, + ODM_MGN_VHT1SS_MCS8, + ODM_MGN_VHT1SS_MCS9, + ODM_MGN_VHT2SS_MCS0, + ODM_MGN_VHT2SS_MCS1, + ODM_MGN_VHT2SS_MCS2, + ODM_MGN_VHT2SS_MCS3, + ODM_MGN_VHT2SS_MCS4, + ODM_MGN_VHT2SS_MCS5, + ODM_MGN_VHT2SS_MCS6, + ODM_MGN_VHT2SS_MCS7, + ODM_MGN_VHT2SS_MCS8, + ODM_MGN_VHT2SS_MCS9, + ODM_MGN_VHT3SS_MCS0, + ODM_MGN_VHT3SS_MCS1, + ODM_MGN_VHT3SS_MCS2, + ODM_MGN_VHT3SS_MCS3, + ODM_MGN_VHT3SS_MCS4, + ODM_MGN_VHT3SS_MCS5, + ODM_MGN_VHT3SS_MCS6, + ODM_MGN_VHT3SS_MCS7, + ODM_MGN_VHT3SS_MCS8, + ODM_MGN_VHT3SS_MCS9, + ODM_MGN_VHT4SS_MCS0, + ODM_MGN_VHT4SS_MCS1, + ODM_MGN_VHT4SS_MCS2, + ODM_MGN_VHT4SS_MCS3, + ODM_MGN_VHT4SS_MCS4, + ODM_MGN_VHT4SS_MCS5, + ODM_MGN_VHT4SS_MCS6, + ODM_MGN_VHT4SS_MCS7, + ODM_MGN_VHT4SS_MCS8, + ODM_MGN_VHT4SS_MCS9, + ODM_MGN_UNKNOWN +}; + +#define ODM_MGN_MCS0_SG 0xc0 +#define ODM_MGN_MCS1_SG 0xc1 +#define ODM_MGN_MCS2_SG 0xc2 +#define ODM_MGN_MCS3_SG 0xc3 +#define ODM_MGN_MCS4_SG 0xc4 +#define ODM_MGN_MCS5_SG 0xc5 +#define ODM_MGN_MCS6_SG 0xc6 +#define ODM_MGN_MCS7_SG 0xc7 +#define ODM_MGN_MCS8_SG 0xc8 +#define ODM_MGN_MCS9_SG 0xc9 +#define ODM_MGN_MCS10_SG 0xca +#define ODM_MGN_MCS11_SG 0xcb +#define ODM_MGN_MCS12_SG 0xcc +#define ODM_MGN_MCS13_SG 0xcd +#define ODM_MGN_MCS14_SG 0xce +#define ODM_MGN_MCS15_SG 0xcf + +/* -----DESC rate--------------------------------- */ + +#define ODM_RATEMCS15_SG 0x1c +#define ODM_RATEMCS32 0x20 + +/* CCK Rates, TxHT = 0 */ +#define ODM_RATE1M 0x00 +#define ODM_RATE2M 0x01 +#define ODM_RATE5_5M 0x02 +#define ODM_RATE11M 0x03 +/* OFDM Rates, TxHT = 0 */ +#define ODM_RATE6M 0x04 +#define ODM_RATE9M 0x05 +#define ODM_RATE12M 0x06 +#define ODM_RATE18M 0x07 +#define ODM_RATE24M 0x08 +#define ODM_RATE36M 0x09 +#define ODM_RATE48M 0x0A +#define ODM_RATE54M 0x0B +/* MCS Rates, TxHT = 1 */ +#define ODM_RATEMCS0 0x0C +#define ODM_RATEMCS1 0x0D +#define ODM_RATEMCS2 0x0E +#define ODM_RATEMCS3 0x0F +#define ODM_RATEMCS4 0x10 +#define ODM_RATEMCS5 0x11 +#define ODM_RATEMCS6 0x12 +#define ODM_RATEMCS7 0x13 +#define ODM_RATEMCS8 0x14 +#define ODM_RATEMCS9 0x15 +#define ODM_RATEMCS10 0x16 +#define ODM_RATEMCS11 0x17 +#define ODM_RATEMCS12 0x18 +#define ODM_RATEMCS13 0x19 +#define ODM_RATEMCS14 0x1A +#define ODM_RATEMCS15 0x1B +#define ODM_RATEMCS16 0x1C +#define ODM_RATEMCS17 0x1D +#define ODM_RATEMCS18 0x1E +#define ODM_RATEMCS19 0x1F +#define ODM_RATEMCS20 0x20 +#define ODM_RATEMCS21 0x21 +#define ODM_RATEMCS22 0x22 +#define ODM_RATEMCS23 0x23 +#define ODM_RATEMCS24 0x24 +#define ODM_RATEMCS25 0x25 +#define ODM_RATEMCS26 0x26 +#define ODM_RATEMCS27 0x27 +#define ODM_RATEMCS28 0x28 +#define ODM_RATEMCS29 0x29 +#define ODM_RATEMCS30 0x2A +#define ODM_RATEMCS31 0x2B +#define ODM_RATEVHTSS1MCS0 0x2C +#define ODM_RATEVHTSS1MCS1 0x2D +#define ODM_RATEVHTSS1MCS2 0x2E +#define ODM_RATEVHTSS1MCS3 0x2F +#define ODM_RATEVHTSS1MCS4 0x30 +#define ODM_RATEVHTSS1MCS5 0x31 +#define ODM_RATEVHTSS1MCS6 0x32 +#define ODM_RATEVHTSS1MCS7 0x33 +#define ODM_RATEVHTSS1MCS8 0x34 +#define ODM_RATEVHTSS1MCS9 0x35 +#define ODM_RATEVHTSS2MCS0 0x36 +#define ODM_RATEVHTSS2MCS1 0x37 +#define ODM_RATEVHTSS2MCS2 0x38 +#define ODM_RATEVHTSS2MCS3 0x39 +#define ODM_RATEVHTSS2MCS4 0x3A +#define ODM_RATEVHTSS2MCS5 0x3B +#define ODM_RATEVHTSS2MCS6 0x3C +#define ODM_RATEVHTSS2MCS7 0x3D +#define ODM_RATEVHTSS2MCS8 0x3E +#define ODM_RATEVHTSS2MCS9 0x3F +#define ODM_RATEVHTSS3MCS0 0x40 +#define ODM_RATEVHTSS3MCS1 0x41 +#define ODM_RATEVHTSS3MCS2 0x42 +#define ODM_RATEVHTSS3MCS3 0x43 +#define ODM_RATEVHTSS3MCS4 0x44 +#define ODM_RATEVHTSS3MCS5 0x45 +#define ODM_RATEVHTSS3MCS6 0x46 +#define ODM_RATEVHTSS3MCS7 0x47 +#define ODM_RATEVHTSS3MCS8 0x48 +#define ODM_RATEVHTSS3MCS9 0x49 +#define ODM_RATEVHTSS4MCS0 0x4A +#define ODM_RATEVHTSS4MCS1 0x4B +#define ODM_RATEVHTSS4MCS2 0x4C +#define ODM_RATEVHTSS4MCS3 0x4D +#define ODM_RATEVHTSS4MCS4 0x4E +#define ODM_RATEVHTSS4MCS5 0x4F +#define ODM_RATEVHTSS4MCS6 0x50 +#define ODM_RATEVHTSS4MCS7 0x51 +#define ODM_RATEVHTSS4MCS8 0x52 +#define ODM_RATEVHTSS4MCS9 0x53 + +#define ODM_NUM_RATE_IDX (ODM_RATEVHTSS4MCS9 + 1) + +/* 1 ============================================================ + * 1 enumeration + * 1 ============================================================ + */ + +/* ODM_CMNINFO_INTERFACE */ +enum odm_interface { + ODM_ITRF_PCIE = 0x1, + ODM_ITRF_USB = 0x2, + ODM_ITRF_SDIO = 0x4, + ODM_ITRF_ALL = 0x7, +}; + +/* ODM_CMNINFO_IC_TYPE */ +enum odm_ic_type { + ODM_RTL8188E = BIT(0), + ODM_RTL8812 = BIT(1), + ODM_RTL8821 = BIT(2), + ODM_RTL8192E = BIT(3), + ODM_RTL8723B = BIT(4), + ODM_RTL8814A = BIT(5), + ODM_RTL8881A = BIT(6), + ODM_RTL8822B = BIT(7), + ODM_RTL8703B = BIT(8), + ODM_RTL8195A = BIT(9), + ODM_RTL8188F = BIT(10), + ODM_RTL8723D = BIT(11), + ODM_RTL8197F = BIT(12), + ODM_RTL8821C = BIT(13), + ODM_RTL8814B = BIT(14), + ODM_RTL8198F = BIT(15), + /* JJ ADD 20161014 */ + ODM_RTL8710B = BIT(16), +}; + +/* JJ ADD 20161014 */ +#define ODM_IC_1SS \ + (ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8723B | ODM_RTL8703B | \ + ODM_RTL8723D | ODM_RTL8881A | ODM_RTL8821 | ODM_RTL8821C | \ + ODM_RTL8195A | ODM_RTL8710B) +#define ODM_IC_2SS (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8812 | ODM_RTL8822B) +#define ODM_IC_3SS (ODM_RTL8814A) +#define ODM_IC_4SS (ODM_RTL8814B | ODM_RTL8198F) + +/* JJ ADD 20161014 */ +#define ODM_IC_11N_SERIES \ + (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | \ + ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8197F | ODM_RTL8710B) +#define ODM_IC_11AC_SERIES \ + (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8881A | \ + ODM_RTL8822B | ODM_RTL8821C) +#define ODM_IC_11AC_1_SERIES (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A) +#define ODM_IC_11AC_2_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C) +#define ODM_IC_TXBF_SUPPORT \ + (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | \ + ODM_RTL8881A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C) +#define ODM_IC_11N_GAIN_IDX_EDCCA \ + (ODM_RTL8195A | ODM_RTL8703B | ODM_RTL8188F | ODM_RTL8723D | \ + ODM_RTL8197F | ODM_RTL8710B) +#define ODM_IC_11AC_GAIN_IDX_EDCCA (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C) +#define ODM_IC_PHY_STATUE_NEW_TYPE \ + (ODM_RTL8197F | ODM_RTL8822B | ODM_RTL8723D | ODM_RTL8821C | \ + ODM_RTL8710B) + +#define PHYDM_IC_8051_SERIES \ + (ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8188E | \ + ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | ODM_RTL8188F) +#define PHYDM_IC_3081_SERIES \ + (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C) + +#define PHYDM_IC_SUPPORT_LA_MODE \ + (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C) + +/* JJ ADD 20161014 */ + +/* ODM_CMNINFO_CUT_VER */ +enum odm_cut_version { + ODM_CUT_A = 0, + ODM_CUT_B = 1, + ODM_CUT_C = 2, + ODM_CUT_D = 3, + ODM_CUT_E = 4, + ODM_CUT_F = 5, + + ODM_CUT_I = 8, + ODM_CUT_J = 9, + ODM_CUT_K = 10, + ODM_CUT_TEST = 15, +}; + +/* ODM_CMNINFO_FAB_VER */ +enum odm_fab { + ODM_TSMC = 0, + ODM_UMC = 1, +}; + +/* ODM_CMNINFO_RF_TYPE + * + * For example 1T2R (A+AB = BIT(0)|BIT(4)|BIT(5)) + */ +enum odm_rf_path { + ODM_RF_A = BIT(0), + ODM_RF_B = BIT(1), + ODM_RF_C = BIT(2), + ODM_RF_D = BIT(3), +}; + +enum odm_rf_tx_num { + ODM_1T = 1, + ODM_2T = 2, + ODM_3T = 3, + ODM_4T = 4, +}; + +enum odm_rf_type { + ODM_1T1R, + ODM_1T2R, + ODM_2T2R, + ODM_2T2R_GREEN, + ODM_2T3R, + ODM_2T4R, + ODM_3T3R, + ODM_3T4R, + ODM_4T4R, + ODM_XTXR +}; + +enum odm_mac_phy_mode { + ODM_SMSP = 0, + ODM_DMSP = 1, + ODM_DMDP = 2, +}; + +enum odm_bt_coexist { + ODM_BT_BUSY = 1, + ODM_BT_ON = 2, + ODM_BT_OFF = 3, + ODM_BT_NONE = 4, +}; + +/* ODM_CMNINFO_OP_MODE */ +enum odm_operation_mode { + ODM_NO_LINK = BIT(0), + ODM_LINK = BIT(1), + ODM_SCAN = BIT(2), + ODM_POWERSAVE = BIT(3), + ODM_AP_MODE = BIT(4), + ODM_CLIENT_MODE = BIT(5), + ODM_AD_HOC = BIT(6), + ODM_WIFI_DIRECT = BIT(7), + ODM_WIFI_DISPLAY = BIT(8), +}; + +/* ODM_CMNINFO_WM_MODE */ +enum odm_wireless_mode { + ODM_WM_UNKNOWN = 0x0, + ODM_WM_B = BIT(0), + ODM_WM_G = BIT(1), + ODM_WM_A = BIT(2), + ODM_WM_N24G = BIT(3), + ODM_WM_N5G = BIT(4), + ODM_WM_AUTO = BIT(5), + ODM_WM_AC = BIT(6), +}; + +/* ODM_CMNINFO_BAND */ +enum odm_band_type { + ODM_BAND_2_4G = 0, + ODM_BAND_5G, + ODM_BAND_ON_BOTH, + ODM_BANDMAX +}; + +/* ODM_CMNINFO_SEC_CHNL_OFFSET */ +enum phydm_sec_chnl_offset { + PHYDM_DONT_CARE = 0, + PHYDM_BELOW = 1, + PHYDM_ABOVE = 2 +}; + +/* ODM_CMNINFO_SEC_MODE */ +enum odm_security { + ODM_SEC_OPEN = 0, + ODM_SEC_WEP40 = 1, + ODM_SEC_TKIP = 2, + ODM_SEC_RESERVE = 3, + ODM_SEC_AESCCMP = 4, + ODM_SEC_WEP104 = 5, + ODM_WEP_WPA_MIXED = 6, /* WEP + WPA */ + ODM_SEC_SMS4 = 7, +}; + +/* ODM_CMNINFO_BW */ +enum odm_bw { + ODM_BW20M = 0, + ODM_BW40M = 1, + ODM_BW80M = 2, + ODM_BW160M = 3, + ODM_BW5M = 4, + ODM_BW10M = 5, + ODM_BW_MAX = 6 +}; + +/* ODM_CMNINFO_CHNL */ + +/* ODM_CMNINFO_BOARD_TYPE */ +enum odm_board_type { + ODM_BOARD_DEFAULT = 0, /* The DEFAULT case. */ + ODM_BOARD_MINICARD = BIT(0), /* 0 = non-mini card, 1= mini card. */ + ODM_BOARD_SLIM = BIT(1), /* 0 = non-slim card, 1 = slim card */ + ODM_BOARD_BT = BIT(2), /* 0 = without BT card, 1 = with BT */ + ODM_BOARD_EXT_PA = + BIT(3), /* 0 = no 2G ext-PA, 1 = existing 2G ext-PA */ + ODM_BOARD_EXT_LNA = + BIT(4), /* 0 = no 2G ext-LNA, 1 = existing 2G ext-LNA */ + ODM_BOARD_EXT_TRSW = + BIT(5), /* 0 = no ext-TRSW, 1 = existing ext-TRSW */ + ODM_BOARD_EXT_PA_5G = + BIT(6), /* 0 = no 5G ext-PA, 1 = existing 5G ext-PA */ + ODM_BOARD_EXT_LNA_5G = + BIT(7), /* 0 = no 5G ext-LNA, 1 = existing 5G ext-LNA */ +}; + +enum odm_package_type { + ODM_PACKAGE_DEFAULT = 0, + ODM_PACKAGE_QFN68 = BIT(0), + ODM_PACKAGE_TFBGA90 = BIT(1), + ODM_PACKAGE_TFBGA79 = BIT(2), +}; + +enum odm_type_gpa { + TYPE_GPA0 = 0x0000, + TYPE_GPA1 = 0x0055, + TYPE_GPA2 = 0x00AA, + TYPE_GPA3 = 0x00FF, + TYPE_GPA4 = 0x5500, + TYPE_GPA5 = 0x5555, + TYPE_GPA6 = 0x55AA, + TYPE_GPA7 = 0x55FF, + TYPE_GPA8 = 0xAA00, + TYPE_GPA9 = 0xAA55, + TYPE_GPA10 = 0xAAAA, + TYPE_GPA11 = 0xAAFF, + TYPE_GPA12 = 0xFF00, + TYPE_GPA13 = 0xFF55, + TYPE_GPA14 = 0xFFAA, + TYPE_GPA15 = 0xFFFF, +}; + +enum odm_type_apa { + TYPE_APA0 = 0x0000, + TYPE_APA1 = 0x0055, + TYPE_APA2 = 0x00AA, + TYPE_APA3 = 0x00FF, + TYPE_APA4 = 0x5500, + TYPE_APA5 = 0x5555, + TYPE_APA6 = 0x55AA, + TYPE_APA7 = 0x55FF, + TYPE_APA8 = 0xAA00, + TYPE_APA9 = 0xAA55, + TYPE_APA10 = 0xAAAA, + TYPE_APA11 = 0xAAFF, + TYPE_APA12 = 0xFF00, + TYPE_APA13 = 0xFF55, + TYPE_APA14 = 0xFFAA, + TYPE_APA15 = 0xFFFF, +}; + +enum odm_type_glna { + TYPE_GLNA0 = 0x0000, + TYPE_GLNA1 = 0x0055, + TYPE_GLNA2 = 0x00AA, + TYPE_GLNA3 = 0x00FF, + TYPE_GLNA4 = 0x5500, + TYPE_GLNA5 = 0x5555, + TYPE_GLNA6 = 0x55AA, + TYPE_GLNA7 = 0x55FF, + TYPE_GLNA8 = 0xAA00, + TYPE_GLNA9 = 0xAA55, + TYPE_GLNA10 = 0xAAAA, + TYPE_GLNA11 = 0xAAFF, + TYPE_GLNA12 = 0xFF00, + TYPE_GLNA13 = 0xFF55, + TYPE_GLNA14 = 0xFFAA, + TYPE_GLNA15 = 0xFFFF, +}; + +enum odm_type_alna { + TYPE_ALNA0 = 0x0000, + TYPE_ALNA1 = 0x0055, + TYPE_ALNA2 = 0x00AA, + TYPE_ALNA3 = 0x00FF, + TYPE_ALNA4 = 0x5500, + TYPE_ALNA5 = 0x5555, + TYPE_ALNA6 = 0x55AA, + TYPE_ALNA7 = 0x55FF, + TYPE_ALNA8 = 0xAA00, + TYPE_ALNA9 = 0xAA55, + TYPE_ALNA10 = 0xAAAA, + TYPE_ALNA11 = 0xAAFF, + TYPE_ALNA12 = 0xFF00, + TYPE_ALNA13 = 0xFF55, + TYPE_ALNA14 = 0xFFAA, + TYPE_ALNA15 = 0xFFFF, +}; + +enum odm_rf_radio_path { + ODM_RF_PATH_A = 0, /* Radio path A */ + ODM_RF_PATH_B = 1, /* Radio path B */ + ODM_RF_PATH_C = 2, /* Radio path C */ + ODM_RF_PATH_D = 3, /* Radio path D */ + ODM_RF_PATH_AB, + ODM_RF_PATH_AC, + ODM_RF_PATH_AD, + ODM_RF_PATH_BC, + ODM_RF_PATH_BD, + ODM_RF_PATH_CD, + ODM_RF_PATH_ABC, + ODM_RF_PATH_ACD, + ODM_RF_PATH_BCD, + ODM_RF_PATH_ABCD, + /* ODM_RF_PATH_MAX, */ /* Max RF number 90 support */ +}; + +enum odm_parameter_init { + ODM_PRE_SETTING = 0, + ODM_POST_SETTING = 1, +}; + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_precomp.h b/drivers/staging/rtlwifi/phydm/phydm_precomp.h new file mode 100644 index 0000000000000000000000000000000000000000..bada15c4d2d8839b4300799c1e62db807fca6a40 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_precomp.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_PRECOMP_H__ +#define __ODM_PRECOMP_H__ + +#include "phydm_types.h" + +/* 2 Config Flags and Structs - defined by each ODM type */ + +#include "../wifi.h" +#include "rtl_phydm.h" + +/* 2 OutSrc Header Files */ + +#include "phydm.h" +#include "phydm_hwconfig.h" +#include "phydm_debug.h" +#include "phydm_regdefine11ac.h" +#include "phydm_regdefine11n.h" +#include "phydm_interface.h" +#include "phydm_reg.h" + +#include "phydm_adc_sampling.h" + +/* JJ ADD 20161014 */ + +#include "../halmac/halmac_reg2.h" + +#define LDPC_HT_ENABLE_RX BIT(0) +#define LDPC_HT_ENABLE_TX BIT(1) +#define LDPC_HT_TEST_TX_ENABLE BIT(2) +#define LDPC_HT_CAP_TX BIT(3) + +#define STBC_HT_ENABLE_RX BIT(0) +#define STBC_HT_ENABLE_TX BIT(1) +#define STBC_HT_TEST_TX_ENABLE BIT(2) +#define STBC_HT_CAP_TX BIT(3) + +#define LDPC_VHT_ENABLE_RX BIT(0) +#define LDPC_VHT_ENABLE_TX BIT(1) +#define LDPC_VHT_TEST_TX_ENABLE BIT(2) +#define LDPC_VHT_CAP_TX BIT(3) + +#define STBC_VHT_ENABLE_RX BIT(0) +#define STBC_VHT_ENABLE_TX BIT(1) +#define STBC_VHT_TEST_TX_ENABLE BIT(2) +#define STBC_VHT_CAP_TX BIT(3) + +#include "rtl8822b/halhwimg8822b_mac.h" +#include "rtl8822b/halhwimg8822b_rf.h" +#include "rtl8822b/halhwimg8822b_bb.h" +#include "rtl8822b/phydm_regconfig8822b.h" +#include "rtl8822b/halphyrf_8822b.h" +#include "rtl8822b/phydm_rtl8822b.h" +#include "rtl8822b/phydm_hal_api8822b.h" +#include "rtl8822b/version_rtl8822b.h" + +#include "../halmac/halmac_reg_8822b.h" + +/* JJ ADD 20161014 */ + +#endif /* __ODM_PRECOMP_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_psd.c b/drivers/staging/rtlwifi/phydm/phydm_psd.c new file mode 100644 index 0000000000000000000000000000000000000000..48f8776bc8f90c62b62ae621ebac3d0d99c7ea7b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_psd.c @@ -0,0 +1,422 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*============================================================ + * include files + *============================================================ + */ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u32 psd_report = 0; + + odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0x3ff, psd_tone_idx); + + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22), + 1); /*PSD trigger start*/ + ODM_delay_us(10); + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22), + 0); /*PSD trigger stop*/ + + psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, 0xffff); + psd_report = odm_convert_to_db(psd_report) + igi; + + return psd_report; +} + +static u8 phydm_psd_stop_trx(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 i; + u8 trx_idle_success = false; + u32 dbg_port_value = 0; + + /*[Stop TRX]----------------------------------------------------------*/ + if (!phydm_set_bb_dbg_port(dm, BB_DBGPORT_PRIORITY_3, + 0x0)) /*set debug port to 0x0*/ + return STOP_TRX_FAIL; + + for (i = 0; i < 10000; i++) { + dbg_port_value = phydm_get_bb_dbg_port_value(dm); + if ((dbg_port_value & (BIT(17) | BIT(3))) == + 0) /* PHYTXON && CCA_all */ { + ODM_RT_TRACE(dm, ODM_COMP_API, + "PSD wait for ((%d)) times\n", i); + + trx_idle_success = true; + break; + } + } + + if (trx_idle_success) { + /*pause all TX queue*/ + odm_set_bb_reg(dm, 0x520, 0xff0000, 0xff); + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + /*disable CCK block*/ + odm_set_bb_reg(dm, 0x808, BIT(28), 0); + /*disable OFDM RX CCA*/ + odm_set_bb_reg(dm, 0x838, BIT(1), 1); + } else { + /*TBD*/ + /* disable whole CCK block */ + odm_set_bb_reg(dm, 0x800, BIT(24), 0); + /*[ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA]*/ + odm_set_bb_reg(dm, 0xC14, MASKDWORD, 0x0); + } + + } else { + return STOP_TRX_FAIL; + } + + phydm_release_bb_dbg_port(dm); + + return STOP_TRX_SUCCESS; +} + +static u8 psd_result_cali_tone_8821[7] = {21, 28, 33, 93, 98, 105, 127}; +static u8 psd_result_cali_val_8821[7] = {67, 69, 71, 72, 71, 69, 67}; + +void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u32 i = 0, mod_tone_idx; + u32 t = 0; + u16 fft_max_half_bw; + u32 psd_igi_a_reg; + u32 psd_igi_b_reg; + u16 psd_fc_channel = dm_psd_table->psd_fc_channel; + u8 ag_rf_mode_reg = 0; + u8 rf_reg18_9_8 = 0; + u32 psd_result_tmp = 0; + u8 psd_result = 0; + u8 psd_result_cali_tone[7] = {0}; + u8 psd_result_cali_val[7] = {0}; + u8 noise_table_idx = 0; + + if (dm->support_ic_type == ODM_RTL8821) { + odm_move_memory(dm, psd_result_cali_tone, + psd_result_cali_tone_8821, 7); + odm_move_memory(dm, psd_result_cali_val, + psd_result_cali_val_8821, 7); + } + + dm_psd_table->psd_in_progress = 1; + + /*[Stop DIG]*/ + dm->support_ability &= ~(ODM_BB_DIG); + dm->support_ability &= ~(ODM_BB_FA_CNT); + + ODM_RT_TRACE(dm, ODM_COMP_API, "PSD Start =>\n"); + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + psd_igi_a_reg = 0xc50; + psd_igi_b_reg = 0xe50; + } else { + psd_igi_a_reg = 0xc50; + psd_igi_b_reg = 0xc58; + } + + /*[back up IGI]*/ + dm_psd_table->initial_gain_backup = + odm_get_bb_reg(dm, psd_igi_a_reg, 0xff); + odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, + 0x6e); /*IGI target at 0dBm & make it can't CCA*/ + odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, + 0x6e); /*IGI target at 0dBm & make it can't CCA*/ + ODM_delay_us(10); + + if (phydm_psd_stop_trx(dm) == STOP_TRX_FAIL) { + ODM_RT_TRACE(dm, ODM_COMP_API, "STOP_TRX_FAIL\n"); + return; + } + + /*[Set IGI]*/ + odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, igi); + odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, igi); + + /*[Backup RF Reg]*/ + dm_psd_table->rf_0x18_bkp = + odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK); + + if (psd_fc_channel > 14) { + rf_reg18_9_8 = 1; + + if (psd_fc_channel >= 36 && psd_fc_channel <= 64) + ag_rf_mode_reg = 0x1; + else if (psd_fc_channel >= 100 && psd_fc_channel <= 140) + ag_rf_mode_reg = 0x3; + else if (psd_fc_channel > 140) + ag_rf_mode_reg = 0x5; + } + + /* Set RF fc*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xff, psd_fc_channel); + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0x300, rf_reg18_9_8); + /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xc00, + dm_psd_table->psd_bw_rf_reg); + /* Set RF ag fc mode*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xf0000, ag_rf_mode_reg); + + ODM_RT_TRACE(dm, ODM_COMP_API, "0xc50=((0x%x))\n", + odm_get_bb_reg(dm, 0xc50, MASKDWORD)); + ODM_RT_TRACE(dm, ODM_COMP_API, "RF0x18=((0x%x))\n", + odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK)); + + /*[Stop 3-wires]*/ + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + odm_set_bb_reg(dm, 0xc00, 0xf, 0x4); /* hardware 3-wire off */ + odm_set_bb_reg(dm, 0xe00, 0xf, 0x4); /* hardware 3-wire off */ + } else { + odm_set_bb_reg(dm, 0x88c, 0xf00000, + 0xf); /* 3 wire Disable 88c[23:20]=0xf */ + } + ODM_delay_us(10); + + if (stop_point > (dm_psd_table->fft_smp_point - 1)) + stop_point = (dm_psd_table->fft_smp_point - 1); + + if (start_point > (dm_psd_table->fft_smp_point - 1)) + start_point = (dm_psd_table->fft_smp_point - 1); + + if (start_point > stop_point) + stop_point = start_point; + + if (stop_point > 127) /* limit of psd_result[128] */ + stop_point = 127; + + for (i = start_point; i <= stop_point; i++) { + fft_max_half_bw = (dm_psd_table->fft_smp_point) >> 1; + + if (i < fft_max_half_bw) + mod_tone_idx = i + fft_max_half_bw; + else + mod_tone_idx = i - fft_max_half_bw; + + psd_result_tmp = 0; + for (t = 0; t < dm_psd_table->sw_avg_time; t++) + psd_result_tmp += + phydm_get_psd_data(dm, mod_tone_idx, igi); + psd_result = + (u8)((psd_result_tmp / dm_psd_table->sw_avg_time)) - + dm_psd_table->psd_pwr_common_offset; + + if (dm_psd_table->fft_smp_point == 128 && + (dm_psd_table->noise_k_en)) { + if (i > psd_result_cali_tone[noise_table_idx]) + noise_table_idx++; + + if (noise_table_idx > 6) + noise_table_idx = 6; + + if (psd_result >= psd_result_cali_val[noise_table_idx]) + psd_result = + psd_result - + psd_result_cali_val[noise_table_idx]; + else + psd_result = 0; + + dm_psd_table->psd_result[i] = psd_result; + } + + ODM_RT_TRACE(dm, ODM_COMP_API, "[%d] N_cali = %d, PSD = %d\n", + mod_tone_idx, psd_result_cali_val[noise_table_idx], + psd_result); + } + + /*[Start 3-wires]*/ + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + odm_set_bb_reg(dm, 0xc00, 0xf, 0x7); /* hardware 3-wire on */ + odm_set_bb_reg(dm, 0xe00, 0xf, 0x7); /* hardware 3-wire on */ + } else { + odm_set_bb_reg(dm, 0x88c, 0xf00000, + 0x0); /* 3 wire enable 88c[23:20]=0x0 */ + } + ODM_delay_us(10); + + /*[Revert Reg]*/ + odm_set_bb_reg(dm, 0x520, 0xff0000, 0x0); /*start all TX queue*/ + odm_set_bb_reg(dm, 0x808, BIT(28), 1); /*enable CCK block*/ + odm_set_bb_reg(dm, 0x838, BIT(1), 0); /*enable OFDM RX CCA*/ + + odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, + dm_psd_table->initial_gain_backup); + odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, + dm_psd_table->initial_gain_backup); + + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK, + dm_psd_table->rf_0x18_bkp); + + ODM_RT_TRACE(dm, ODM_COMP_API, "PSD finished\n\n"); + + dm->support_ability |= ODM_BB_DIG; + dm->support_ability |= ODM_BB_FA_CNT; + dm_psd_table->psd_in_progress = 0; +} + +void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, + u8 i_q_setting, u16 fft_smp_point, u8 ant_sel, + u8 psd_input, u8 channel, u8 noise_k_en) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u8 fft_smp_point_idx = 0; + + dm_psd_table->fft_smp_point = fft_smp_point; + + if (sw_avg_time == 0) + sw_avg_time = 1; + + dm_psd_table->sw_avg_time = sw_avg_time; + dm_psd_table->psd_fc_channel = channel; + dm_psd_table->noise_k_en = noise_k_en; + + if (fft_smp_point == 128) + fft_smp_point_idx = 0; + else if (fft_smp_point == 256) + fft_smp_point_idx = 1; + else if (fft_smp_point == 512) + fft_smp_point_idx = 2; + else if (fft_smp_point == 1024) + fft_smp_point_idx = 3; + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + odm_set_bb_reg(dm, 0x910, BIT(11) | BIT(10), i_q_setting); + odm_set_bb_reg(dm, 0x910, BIT(13) | BIT(12), hw_avg_time); + odm_set_bb_reg(dm, 0x910, BIT(15) | BIT(14), fft_smp_point_idx); + odm_set_bb_reg(dm, 0x910, BIT(17) | BIT(16), ant_sel); + odm_set_bb_reg(dm, 0x910, BIT(23), psd_input); + } + + /*bw = (*dm->band_width); //ODM_BW20M */ + /*channel = *(dm->channel);*/ +} + +void phydm_psd_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + + ODM_RT_TRACE(dm, ODM_COMP_API, "PSD para init\n"); + + dm_psd_table->psd_in_progress = false; + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + dm_psd_table->psd_reg = 0x910; + dm_psd_table->psd_report_reg = 0xF44; + + if (ODM_IC_11AC_2_SERIES) + dm_psd_table->psd_bw_rf_reg = + 1; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + else + dm_psd_table->psd_bw_rf_reg = + 2; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + + } else { + dm_psd_table->psd_reg = 0x808; + dm_psd_table->psd_report_reg = 0x8B4; + dm_psd_table->psd_bw_rf_reg = + 2; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + } + + if (dm->support_ic_type == ODM_RTL8812) + dm_psd_table->psd_pwr_common_offset = 0; + else if (dm->support_ic_type == ODM_RTL8821) + dm_psd_table->psd_pwr_common_offset = 0; + else + dm_psd_table->psd_pwr_common_offset = 0; + + phydm_psd_para_setting(dm, 1, 2, 3, 128, 0, 0, 7, 0); + /*phydm_psd(dm, 0x3c, 0, 127);*/ /* target at -50dBm */ +} + +void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, char *output, + u32 *_out_len, u32 input_num) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i; + + if ((strcmp(input[1], help) == 0)) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)} {path_sel 0~3} {0:ADC, 1:RXIQC} {CH} {noise_k}\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "{1} {IGI(hex)} {start_point} {stop_point}\n"); + return; + } + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (var1[0] == 0) { + for (i = 1; i < 10; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + PHYDM_SNPRINTF( + output + used, out_len - used, + "sw_avg_time=((%d)), hw_avg_time=((%d)), IQ=((%d)), fft=((%d)), path=((%d)), input =((%d)) ch=((%d)), noise_k=((%d))\n", + var1[1], var1[2], var1[3], var1[4], var1[5], var1[6], + (u8)var1[7], (u8)var1[8]); + phydm_psd_para_setting(dm, (u8)var1[1], (u8)var1[2], + (u8)var1[3], (u16)var1[4], (u8)var1[5], + (u8)var1[6], (u8)var1[7], (u8)var1[8]); + + } else if (var1[0] == 1) { + PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]); + PHYDM_SSCANF(input[3], DCMD_DECIMAL, &var1[2]); + PHYDM_SSCANF(input[4], DCMD_DECIMAL, &var1[3]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "IGI=((0x%x)), start_point=((%d)), stop_point=((%d))\n", + var1[1], var1[2], var1[3]); + dm->debug_components |= ODM_COMP_API; + phydm_psd(dm, var1[1], (u16)var1[2], (u16)var1[3]); + dm->debug_components &= (~ODM_COMP_API); + } +} + +u8 phydm_get_psd_result_table(void *dm_void, int index) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u8 temp_result = 0; + + if (index < 128) + temp_result = dm_psd_table->psd_result[index]; + + return temp_result; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_psd.h b/drivers/staging/rtlwifi/phydm/phydm_psd.h new file mode 100644 index 0000000000000000000000000000000000000000..aeb70751d80b1d46d89e1698253cae6ab8e5b81c --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_psd.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMPSD_H__ +#define __PHYDMPSD_H__ + +/*#define PSD_VERSION "1.0"*/ /*2016.09.22 Dino*/ +#define PSD_VERSION "1.1" /*2016.10.07 Dino, Add Option for PSD Tone index + *Selection + */ + +#define STOP_TRX_SUCCESS 1 +#define STOP_TRX_FAIL 0 + +struct psd_info { + u8 psd_in_progress; + u32 psd_reg; + u32 psd_report_reg; + u8 psd_pwr_common_offset; + u16 sw_avg_time; + u16 fft_smp_point; + u32 initial_gain_backup; + u32 rf_0x18_bkp; + u16 psd_fc_channel; + u32 psd_bw_rf_reg; + u8 psd_result[128]; + u8 noise_k_en; +}; + +u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi); + +void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, char *output, + u32 *_out_len, u32 input_num); + +void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point); + +void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, + u8 i_q_setting, u16 fft_smp_point, u8 ant_sel, + u8 psd_input, u8 channel, u8 noise_k_en); + +void phydm_psd_init(void *dm_void); + +u8 phydm_get_psd_result_table(void *dm_void, int index); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c new file mode 100644 index 0000000000000000000000000000000000000000..8c08c76d4edaba6c13bfed26ddb8a248a17c399a --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c @@ -0,0 +1,1208 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +void phydm_h2C_debug(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 h2c_parameter[H2C_MAX_LENGTH] = {0}; + u8 phydm_h2c_id = (u8)dm_value[0]; + u8 i; + u32 used = *_used; + u32 out_len = *_out_len; + + PHYDM_SNPRINTF(output + used, out_len - used, + "Phydm Send H2C_ID (( 0x%x))\n", phydm_h2c_id); + for (i = 0; i < H2C_MAX_LENGTH; i++) { + h2c_parameter[i] = (u8)dm_value[i + 1]; + PHYDM_SNPRINTF(output + used, out_len - used, + "H2C: Byte[%d] = ((0x%x))\n", i, + h2c_parameter[i]); + } + + odm_fill_h2c_cmd(dm, phydm_h2c_id, H2C_MAX_LENGTH, h2c_parameter); +} + +void phydm_RA_debug_PCR(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u32 used = *_used; + u32 out_len = *_out_len; + + if (dm_value[0] == 100) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "[Get] PCR RA_threshold_offset = (( %s%d ))\n", + ((ra_tab->RA_threshold_offset == 0) ? + " " : + ((ra_tab->RA_offset_direction) ? "+" : "-")), + ra_tab->RA_threshold_offset); + /**/ + } else if (dm_value[0] == 0) { + ra_tab->RA_offset_direction = 0; + ra_tab->RA_threshold_offset = (u8)dm_value[1]; + PHYDM_SNPRINTF(output + used, out_len - used, + "[Set] PCR RA_threshold_offset = (( -%d ))\n", + ra_tab->RA_threshold_offset); + } else if (dm_value[0] == 1) { + ra_tab->RA_offset_direction = 1; + ra_tab->RA_threshold_offset = (u8)dm_value[1]; + PHYDM_SNPRINTF(output + used, out_len - used, + "[Set] PCR RA_threshold_offset = (( +%d ))\n", + ra_tab->RA_threshold_offset); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, "[Set] Error\n"); + /**/ + } +} + +void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + u8 para_idx = cmd_buf[0]; /*Retry Penalty, NH, NL*/ + u8 i; + + ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG, + "[ From FW C2H RA Para ] cmd_buf[0]= (( %d ))\n", + cmd_buf[0]); + + if (para_idx == RADBG_DEBUG_MONITOR1) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "RSSI =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "rate =", cmd_buf[2] & 0x7f); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "SGI =", (cmd_buf[2] & 0x80) >> 7); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "BW =", cmd_buf[3]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "BW_max =", cmd_buf[4]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "multi_rate0 =", cmd_buf[5]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "multi_rate1 =", cmd_buf[6]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "DISRA =", cmd_buf[7]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "VHT_EN =", cmd_buf[8]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "SGI_support =", cmd_buf[9]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "try_ness =", cmd_buf[10]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "pre_rate =", cmd_buf[11]); + } else { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "RSSI =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %x\n", + "BW =", cmd_buf[2]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "DISRA =", cmd_buf[3]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "VHT_EN =", cmd_buf[4]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "Hightest rate =", cmd_buf[5]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "Lowest rate =", cmd_buf[6]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "SGI_support =", cmd_buf[7]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "Rate_ID =", cmd_buf[8]); + ; + } + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + } else if (para_idx == RADBG_DEBUG_MONITOR2) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "rate_id =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "highest_rate =", cmd_buf[2]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "lowest_rate =", cmd_buf[3]); + + for (i = 4; i <= 11; i++) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "RAMASK = 0x%x\n", cmd_buf[i]); + } else { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "%5s %x%x %x%x %x%x %x%x\n", + "RA Mask:", cmd_buf[8], cmd_buf[7], + cmd_buf[6], cmd_buf[5], cmd_buf[4], + cmd_buf[3], cmd_buf[2], cmd_buf[1]); + } + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + } else if (para_idx == RADBG_DEBUG_MONITOR3) { + for (i = 0; i < (cmd_len - 1); i++) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "content[%d] = %d\n", i, cmd_buf[1 + i]); + } else if (para_idx == RADBG_DEBUG_MONITOR4) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s {%d.%d}\n", + "RA version =", cmd_buf[1], cmd_buf[2]); + } else if (para_idx == RADBG_DEBUG_MONITOR5) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "Current rate =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "Retry ratio =", cmd_buf[2]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "rate down ratio =", cmd_buf[3]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "highest rate =", cmd_buf[4]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s {0x%x 0x%x}\n", + "Muti-try =", cmd_buf[5], cmd_buf[6]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x%x%x%x%x\n", + "RA mask =", cmd_buf[11], cmd_buf[10], cmd_buf[9], + cmd_buf[8], cmd_buf[7]); + } +} + +void phydm_ra_dynamic_retry_count(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_DYNAMIC_ARFR)) + return; + + if (dm->pre_b_noisy != dm->noisy_decision) { + if (dm->noisy_decision) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "->Noisy Env. RA fallback value\n"); + odm_set_mac_reg(dm, 0x430, MASKDWORD, 0x0); + odm_set_mac_reg(dm, 0x434, MASKDWORD, 0x04030201); + } else { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "->Clean Env. RA fallback value\n"); + odm_set_mac_reg(dm, 0x430, MASKDWORD, 0x01000000); + odm_set_mac_reg(dm, 0x434, MASKDWORD, 0x06050402); + } + dm->pre_b_noisy = dm->noisy_decision; + } +} + +void phydm_ra_dynamic_retry_limit(void *dm_void) {} + +void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; + u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/ + u8 vht_en = (rate_idx >= ODM_RATEVHTSS1MCS0) ? 1 : 0; + u8 b_sgi = (rate & 0x80) >> 7; + + ODM_RT_TRACE(dm, dbg_component, "( %s%s%s%s%d%s%s)\n", + ((rate_idx >= ODM_RATEVHTSS1MCS0) && + (rate_idx <= ODM_RATEVHTSS1MCS9)) ? + "VHT 1ss " : + "", + ((rate_idx >= ODM_RATEVHTSS2MCS0) && + (rate_idx <= ODM_RATEVHTSS2MCS9)) ? + "VHT 2ss " : + "", + ((rate_idx >= ODM_RATEVHTSS3MCS0) && + (rate_idx <= ODM_RATEVHTSS3MCS9)) ? + "VHT 3ss " : + "", + (rate_idx >= ODM_RATEMCS0) ? "MCS " : "", + (vht_en) ? ((rate_idx - ODM_RATEVHTSS1MCS0) % 10) : + ((rate_idx >= ODM_RATEMCS0) ? + (rate_idx - ODM_RATEMCS0) : + ((rate_idx <= ODM_RATE54M) ? + legacy_table[rate_idx] : + 0)), + (b_sgi) ? "-S" : " ", + (rate_idx >= ODM_RATEMCS0) ? "" : "M"); +} + +void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u8 macid = cmd_buf[1]; + u8 rate = cmd_buf[0]; + u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/ + u8 rate_order; + + if (cmd_len >= 4) { + if (cmd_buf[3] == 0) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "TX Init-rate Update[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 0xff) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "FW Level: Fix rate[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 1) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "Try Success[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 2) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "Try Fail & Try Again[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 3) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "rate Back[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 4) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "start rate by RSSI[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 5) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "Try rate[%d]:", macid); + /**/ + } + } else { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, "Tx rate Update[%d]:", + macid); + /**/ + } + + phydm_print_rate(dm, rate, ODM_COMP_RATE_ADAPTIVE); + + ra_tab->link_tx_rate[macid] = rate; + + /*trigger power training*/ + + rate_order = phydm_rate_order_compute(dm, rate_idx); + + if ((dm->is_one_entry_only) || + ((rate_order > ra_tab->highest_client_tx_order) && + (ra_tab->power_tracking_flag == 1))) { + phydm_update_pwr_track(dm, rate_idx); + ra_tab->power_tracking_flag = 0; + } + + /*trigger dynamic rate ID*/ +} + +void odm_rssi_monitor_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + ra_tab->firstconnect = false; +} + +void odm_ra_post_action_on_assoc(void *dm_void) {} + +void phydm_init_ra_info(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->support_ic_type == ODM_RTL8822B) { + u32 ret_value; + + ret_value = odm_get_bb_reg(dm, 0x4c8, MASKBYTE2); + odm_set_bb_reg(dm, 0x4cc, MASKBYTE3, (ret_value - 1)); + } +} + +void phydm_modify_RA_PCR_threshold(void *dm_void, u8 RA_offset_direction, + u8 RA_threshold_offset + + ) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + ra_tab->RA_offset_direction = RA_offset_direction; + ra_tab->RA_threshold_offset = RA_threshold_offset; + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Set RA_threshold_offset = (( %s%d ))\n", + ((RA_threshold_offset == 0) ? + " " : + ((RA_offset_direction) ? "+" : "-")), + RA_threshold_offset); +} + +static void odm_rssi_monitor_check_mp(void *dm_void) {} + +static void odm_rssi_monitor_check_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_sta_info *entry; + int i; + int tmp_entry_min_pwdb = 0xff; + unsigned long cur_tx_ok_cnt = 0, cur_rx_ok_cnt = 0; + u8 UL_DL_STATE = 0, STBC_TX = 0, tx_bf_en = 0; + u8 h2c_parameter[H2C_0X42_LENGTH] = {0}; + u8 cmdlen = H2C_0X42_LENGTH; + u8 macid = 0; + + if (!dm->is_linked) + return; + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + entry = (struct rtl_sta_info *)dm->odm_sta_info[i]; + if (!IS_STA_VALID(entry)) + continue; + + if (is_multicast_ether_addr(entry->mac_addr) || + is_broadcast_ether_addr(entry->mac_addr)) + continue; + + if (entry->rssi_stat.undecorated_smoothed_pwdb == (-1)) + continue; + + /* calculate min_pwdb */ + if (entry->rssi_stat.undecorated_smoothed_pwdb < + tmp_entry_min_pwdb) + tmp_entry_min_pwdb = + entry->rssi_stat.undecorated_smoothed_pwdb; + + /* report RSSI */ + cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast_inperiod; + cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast_inperiod; + + if (cur_rx_ok_cnt > (cur_tx_ok_cnt * 6)) + UL_DL_STATE = 1; + else + UL_DL_STATE = 0; + + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + struct ieee80211_sta *sta = container_of( + (void *)entry, struct ieee80211_sta, drv_priv); + macid = sta->aid + 1; + } + + h2c_parameter[0] = macid; + h2c_parameter[2] = + entry->rssi_stat.undecorated_smoothed_pwdb & 0x7F; + + if (UL_DL_STATE) + h2c_parameter[3] |= RAINFO_BE_RX_STATE; + + if (tx_bf_en) + h2c_parameter[3] |= RAINFO_BF_STATE; + if (STBC_TX) + h2c_parameter[3] |= RAINFO_STBC_STATE; + if (dm->noisy_decision) + h2c_parameter[3] |= RAINFO_NOISY_STATE; + + if (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_SEND) { + h2c_parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE; + entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_HOLD; + } + + h2c_parameter[4] = (ra_tab->RA_threshold_offset & 0x7f) | + (ra_tab->RA_offset_direction << 7); + + odm_fill_h2c_cmd(dm, ODM_H2C_RSSI_REPORT, cmdlen, + h2c_parameter); + } + + if (tmp_entry_min_pwdb != 0xff) + dm->rssi_min = tmp_entry_min_pwdb; +} + +static void odm_rssi_monitor_check_ap(void *dm_void) {} + +void odm_rssi_monitor_check(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_RSSI_MONITOR)) + return; + + switch (dm->support_platform) { + case ODM_WIN: + odm_rssi_monitor_check_mp(dm); + break; + + case ODM_CE: + odm_rssi_monitor_check_ce(dm); + break; + + case ODM_AP: + odm_rssi_monitor_check_ap(dm); + break; + + default: + break; + } +} + +void odm_rate_adaptive_mask_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct odm_rate_adaptive *odm_ra = &dm->rate_adaptive; + + odm_ra->type = dm_type_by_driver; + if (odm_ra->type == dm_type_by_driver) + dm->is_use_ra_mask = true; + else + dm->is_use_ra_mask = false; + + odm_ra->ratr_state = DM_RATR_STA_INIT; + + odm_ra->ldpc_thres = 35; + odm_ra->is_use_ldpc = false; + + odm_ra->high_rssi_thresh = 50; + odm_ra->low_rssi_thresh = 20; +} + +/*----------------------------------------------------------------------------- + * Function: odm_refresh_rate_adaptive_mask() + * + * Overview: Update rate table mask according to rssi + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/27/2009 hpfan Create version 0. + * + *--------------------------------------------------------------------------- + */ +void odm_refresh_rate_adaptive_mask(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + if (!dm->is_linked) + return; + + if (!(dm->support_ability & ODM_BB_RA_MASK)) { + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "%s(): Return cos not supported\n", __func__); + return; + } + + ra_tab->force_update_ra_mask_count++; + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + switch (dm->support_platform) { + case ODM_WIN: + odm_refresh_rate_adaptive_mask_mp(dm); + break; + + case ODM_CE: + odm_refresh_rate_adaptive_mask_ce(dm); + break; + + case ODM_AP: + odm_refresh_rate_adaptive_mask_apadsl(dm); + break; + } +} + +static u8 phydm_trans_platform_bw(void *dm_void, u8 BW) +{ + if (BW == HT_CHANNEL_WIDTH_20) + BW = PHYDM_BW_20; + + else if (BW == HT_CHANNEL_WIDTH_20_40) + BW = PHYDM_BW_40; + + else if (BW == HT_CHANNEL_WIDTH_80) + BW = PHYDM_BW_80; + + return BW; +} + +static u8 phydm_trans_platform_rf_type(void *dm_void, u8 rf_type) +{ + if (rf_type == RF_1T2R) + rf_type = PHYDM_RF_1T2R; + + else if (rf_type == RF_2T4R) + rf_type = PHYDM_RF_2T4R; + + else if (rf_type == RF_2T2R) + rf_type = PHYDM_RF_2T2R; + + else if (rf_type == RF_1T1R) + rf_type = PHYDM_RF_1T1R; + + else if (rf_type == RF_2T2R_GREEN) + rf_type = PHYDM_RF_2T2R_GREEN; + + else if (rf_type == RF_3T3R) + rf_type = PHYDM_RF_3T3R; + + else if (rf_type == RF_4T4R) + rf_type = PHYDM_RF_4T4R; + + else if (rf_type == RF_2T3R) + rf_type = PHYDM_RF_1T2R; + + else if (rf_type == RF_3T4R) + rf_type = PHYDM_RF_3T4R; + + return rf_type; +} + +static u32 phydm_trans_platform_wireless_mode(void *dm_void, u32 wireless_mode) +{ + return wireless_mode; +} + +u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 vht_en_out = 0; + + if ((wireless_mode == PHYDM_WIRELESS_MODE_AC_5G) || + (wireless_mode == PHYDM_WIRELESS_MODE_AC_24G) || + (wireless_mode == PHYDM_WIRELESS_MODE_AC_ONLY)) { + vht_en_out = 1; + /**/ + } + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "wireless_mode= (( 0x%x )), VHT_EN= (( %d ))\n", + wireless_mode, vht_en_out); + return vht_en_out; +} + +u8 phydm_rate_id_mapping(void *dm_void, u32 wireless_mode, u8 rf_type, u8 bw) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 rate_id_idx = 0; + u8 phydm_BW; + u8 phydm_rf_type; + + phydm_BW = phydm_trans_platform_bw(dm, bw); + phydm_rf_type = phydm_trans_platform_rf_type(dm, rf_type); + wireless_mode = phydm_trans_platform_wireless_mode(dm, wireless_mode); + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x ))\n", + wireless_mode, phydm_rf_type, phydm_BW); + + switch (wireless_mode) { + case PHYDM_WIRELESS_MODE_N_24G: { + if (phydm_BW == PHYDM_BW_40) { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_BGN_40M_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_BGN_40M_2SS; + else + rate_id_idx = PHYDM_ARFR5_N_3SS; + + } else { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_BGN_20M_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_BGN_20M_2SS; + else + rate_id_idx = PHYDM_ARFR5_N_3SS; + } + } break; + + case PHYDM_WIRELESS_MODE_N_5G: { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_GN_N1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_GN_N2SS; + else + rate_id_idx = PHYDM_ARFR5_N_3SS; + } + + break; + + case PHYDM_WIRELESS_MODE_G: + rate_id_idx = PHYDM_BG; + break; + + case PHYDM_WIRELESS_MODE_A: + rate_id_idx = PHYDM_G; + break; + + case PHYDM_WIRELESS_MODE_B: + rate_id_idx = PHYDM_B_20M; + break; + + case PHYDM_WIRELESS_MODE_AC_5G: + case PHYDM_WIRELESS_MODE_AC_ONLY: { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_ARFR1_AC_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_ARFR0_AC_2SS; + else + rate_id_idx = PHYDM_ARFR4_AC_3SS; + } break; + + case PHYDM_WIRELESS_MODE_AC_24G: { + /*Becareful to set "Lowest rate" while using PHYDM_ARFR4_AC_3SS + *in 2.4G/5G + */ + if (phydm_BW >= PHYDM_BW_80) { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_ARFR1_AC_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_ARFR0_AC_2SS; + else + rate_id_idx = PHYDM_ARFR4_AC_3SS; + } else { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; + else + rate_id_idx = PHYDM_ARFR4_AC_3SS; + } + } break; + + default: + rate_id_idx = 0; + break; + } + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "RA rate ID = (( 0x%x ))\n", + rate_id_idx); + + return rate_id_idx; +} + +void phydm_update_hal_ra_mask(void *dm_void, u32 wireless_mode, u8 rf_type, + u8 BW, u8 mimo_ps_enable, u8 disable_cck_rate, + u32 *ratr_bitmap_msb_in, u32 *ratr_bitmap_lsb_in, + u8 tx_rate_level) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 phydm_rf_type; + u8 phydm_BW; + u32 ratr_bitmap = *ratr_bitmap_lsb_in, + ratr_bitmap_msb = *ratr_bitmap_msb_in; + + wireless_mode = phydm_trans_platform_wireless_mode(dm, wireless_mode); + + phydm_rf_type = phydm_trans_platform_rf_type(dm, rf_type); + phydm_BW = phydm_trans_platform_bw(dm, BW); + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Platfoem original RA Mask = (( 0x %x | %x ))\n", + ratr_bitmap_msb, ratr_bitmap); + + switch (wireless_mode) { + case PHYDM_WIRELESS_MODE_B: { + ratr_bitmap &= 0x0000000f; + } break; + + case PHYDM_WIRELESS_MODE_G: { + ratr_bitmap &= 0x00000ff5; + } break; + + case PHYDM_WIRELESS_MODE_A: { + ratr_bitmap &= 0x00000ff0; + } break; + + case PHYDM_WIRELESS_MODE_N_24G: + case PHYDM_WIRELESS_MODE_N_5G: { + if (mimo_ps_enable) + phydm_rf_type = PHYDM_RF_1T1R; + + if (phydm_rf_type == PHYDM_RF_1T1R) { + if (phydm_BW == PHYDM_BW_40) + ratr_bitmap &= 0x000ff015; + else + ratr_bitmap &= 0x000ff005; + } else if (phydm_rf_type == PHYDM_RF_2T2R || + phydm_rf_type == PHYDM_RF_2T4R || + phydm_rf_type == PHYDM_RF_2T3R) { + if (phydm_BW == PHYDM_BW_40) + ratr_bitmap &= 0x0ffff015; + else + ratr_bitmap &= 0x0ffff005; + } else { /*3T*/ + + ratr_bitmap &= 0xfffff015; + ratr_bitmap_msb &= 0xf; + } + } break; + + case PHYDM_WIRELESS_MODE_AC_24G: { + if (phydm_rf_type == PHYDM_RF_1T1R) { + ratr_bitmap &= 0x003ff015; + } else if (phydm_rf_type == PHYDM_RF_2T2R || + phydm_rf_type == PHYDM_RF_2T4R || + phydm_rf_type == PHYDM_RF_2T3R) { + ratr_bitmap &= 0xfffff015; + } else { /*3T*/ + + ratr_bitmap &= 0xfffff010; + ratr_bitmap_msb &= 0x3ff; + } + + if (phydm_BW == + PHYDM_BW_20) { /* AC 20MHz doesn't support MCS9 */ + ratr_bitmap &= 0x7fdfffff; + ratr_bitmap_msb &= 0x1ff; + } + } break; + + case PHYDM_WIRELESS_MODE_AC_5G: { + if (phydm_rf_type == PHYDM_RF_1T1R) { + ratr_bitmap &= 0x003ff010; + } else if (phydm_rf_type == PHYDM_RF_2T2R || + phydm_rf_type == PHYDM_RF_2T4R || + phydm_rf_type == PHYDM_RF_2T3R) { + ratr_bitmap &= 0xfffff010; + } else { /*3T*/ + + ratr_bitmap &= 0xfffff010; + ratr_bitmap_msb &= 0x3ff; + } + + if (phydm_BW == + PHYDM_BW_20) { /* AC 20MHz doesn't support MCS9 */ + ratr_bitmap &= 0x7fdfffff; + ratr_bitmap_msb &= 0x1ff; + } + } break; + + default: + break; + } + + if (wireless_mode != PHYDM_WIRELESS_MODE_B) { + if (tx_rate_level == 0) + ratr_bitmap &= 0xffffffff; + else if (tx_rate_level == 1) + ratr_bitmap &= 0xfffffff0; + else if (tx_rate_level == 2) + ratr_bitmap &= 0xffffefe0; + else if (tx_rate_level == 3) + ratr_bitmap &= 0xffffcfc0; + else if (tx_rate_level == 4) + ratr_bitmap &= 0xffff8f80; + else if (tx_rate_level >= 5) + ratr_bitmap &= 0xffff0f00; + } + + if (disable_cck_rate) + ratr_bitmap &= 0xfffffff0; + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x )), MimoPs_en = (( %d )), tx_rate_level= (( 0x%x ))\n", + wireless_mode, phydm_rf_type, phydm_BW, mimo_ps_enable, + tx_rate_level); + + *ratr_bitmap_lsb_in = ratr_bitmap; + *ratr_bitmap_msb_in = ratr_bitmap_msb; + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Phydm modified RA Mask = (( 0x %x | %x ))\n", + *ratr_bitmap_msb_in, *ratr_bitmap_lsb_in); +} + +u8 phydm_RA_level_decision(void *dm_void, u32 rssi, u8 ratr_state) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 ra_rate_floor_table[RA_FLOOR_TABLE_SIZE] = { + 20, 34, 38, 42, + 46, 50, 100}; /*MCS0 ~ MCS4 , VHT1SS MCS0 ~ MCS4 , G 6M~24M*/ + u8 new_ratr_state = 0; + u8 i; + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "curr RA level = ((%d)), Rate_floor_table ori [ %d , %d, %d , %d, %d, %d]\n", + ratr_state, ra_rate_floor_table[0], ra_rate_floor_table[1], + ra_rate_floor_table[2], ra_rate_floor_table[3], + ra_rate_floor_table[4], ra_rate_floor_table[5]); + + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { + if (i >= (ratr_state)) + ra_rate_floor_table[i] += RA_FLOOR_UP_GAP; + } + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "RSSI = ((%d)), Rate_floor_table_mod [ %d , %d, %d , %d, %d, %d]\n", + rssi, ra_rate_floor_table[0], ra_rate_floor_table[1], + ra_rate_floor_table[2], ra_rate_floor_table[3], + ra_rate_floor_table[4], ra_rate_floor_table[5]); + + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { + if (rssi < ra_rate_floor_table[i]) { + new_ratr_state = i; + break; + } + } + + return new_ratr_state; +} + +void odm_refresh_rate_adaptive_mask_mp(void *dm_void) {} + +void odm_refresh_rate_adaptive_mask_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + void *adapter = dm->adapter; + u32 i; + struct rtl_sta_info *entry; + u8 ratr_state_new; + + if (!dm->is_use_ra_mask) { + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "<---- %s(): driver does not control rate adaptive mask\n", + __func__); + return; + } + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + entry = dm->odm_sta_info[i]; + + if (!IS_STA_VALID(entry)) + continue; + + if (is_multicast_ether_addr(entry->mac_addr)) + continue; + else if (is_broadcast_ether_addr(entry->mac_addr)) + continue; + + ratr_state_new = phydm_RA_level_decision( + dm, entry->rssi_stat.undecorated_smoothed_pwdb, + entry->rssi_level); + + if ((entry->rssi_level != ratr_state_new) || + (ra_tab->force_update_ra_mask_count >= + FORCED_UPDATE_RAMASK_PERIOD)) { + ra_tab->force_update_ra_mask_count = 0; + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "Update Tx RA Level: ((%x)) -> ((%x)), RSSI = ((%d))\n", + entry->rssi_level, ratr_state_new, + entry->rssi_stat.undecorated_smoothed_pwdb); + + entry->rssi_level = ratr_state_new; + rtl_hal_update_ra_mask(adapter, entry, + entry->rssi_level); + } else { + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Stay in RA level = (( %d ))\n\n", + ratr_state_new); + /**/ + } + } +} + +void odm_refresh_rate_adaptive_mask_apadsl(void *dm_void) {} + +void odm_refresh_basic_rate_mask(void *dm_void) {} + +u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx) +{ + u8 rate_order = 0; + + if (rate_idx >= ODM_RATEVHTSS4MCS0) { + rate_idx -= ODM_RATEVHTSS4MCS0; + /**/ + } else if (rate_idx >= ODM_RATEVHTSS3MCS0) { + rate_idx -= ODM_RATEVHTSS3MCS0; + /**/ + } else if (rate_idx >= ODM_RATEVHTSS2MCS0) { + rate_idx -= ODM_RATEVHTSS2MCS0; + /**/ + } else if (rate_idx >= ODM_RATEVHTSS1MCS0) { + rate_idx -= ODM_RATEVHTSS1MCS0; + /**/ + } else if (rate_idx >= ODM_RATEMCS24) { + rate_idx -= ODM_RATEMCS24; + /**/ + } else if (rate_idx >= ODM_RATEMCS16) { + rate_idx -= ODM_RATEMCS16; + /**/ + } else if (rate_idx >= ODM_RATEMCS8) { + rate_idx -= ODM_RATEMCS8; + /**/ + } + rate_order = rate_idx; + + return rate_order; +} + +static void phydm_ra_common_info_update(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u16 macid; + u8 rate_order_tmp; + u8 cnt = 0; + + ra_tab->highest_client_tx_order = 0; + ra_tab->power_tracking_flag = 1; + + if (dm->number_linked_client != 0) { + for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) { + rate_order_tmp = phydm_rate_order_compute( + dm, ((ra_tab->link_tx_rate[macid]) & 0x7f)); + + if (rate_order_tmp >= + (ra_tab->highest_client_tx_order)) { + ra_tab->highest_client_tx_order = + rate_order_tmp; + ra_tab->highest_client_tx_rate_order = macid; + } + + cnt++; + + if (cnt == dm->number_linked_client) + break; + } + ODM_RT_TRACE( + dm, ODM_COMP_RATE_ADAPTIVE, + "MACID[%d], Highest Tx order Update for power traking: %d\n", + (ra_tab->highest_client_tx_rate_order), + (ra_tab->highest_client_tx_order)); + } +} + +void phydm_ra_info_watchdog(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + phydm_ra_common_info_update(dm); + phydm_ra_dynamic_retry_limit(dm); + phydm_ra_dynamic_retry_count(dm); + odm_refresh_rate_adaptive_mask(dm); + odm_refresh_basic_rate_mask(dm); +} + +void phydm_ra_info_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + ra_tab->highest_client_tx_rate_order = 0; + ra_tab->highest_client_tx_order = 0; + ra_tab->RA_threshold_offset = 0; + ra_tab->RA_offset_direction = 0; +} + +u8 odm_find_rts_rate(void *dm_void, u8 tx_rate, bool is_erp_protect) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 rts_ini_rate = ODM_RATE6M; + + if (is_erp_protect) { /* use CCK rate as RTS*/ + rts_ini_rate = ODM_RATE1M; + } else { + switch (tx_rate) { + case ODM_RATEVHTSS3MCS9: + case ODM_RATEVHTSS3MCS8: + case ODM_RATEVHTSS3MCS7: + case ODM_RATEVHTSS3MCS6: + case ODM_RATEVHTSS3MCS5: + case ODM_RATEVHTSS3MCS4: + case ODM_RATEVHTSS3MCS3: + case ODM_RATEVHTSS2MCS9: + case ODM_RATEVHTSS2MCS8: + case ODM_RATEVHTSS2MCS7: + case ODM_RATEVHTSS2MCS6: + case ODM_RATEVHTSS2MCS5: + case ODM_RATEVHTSS2MCS4: + case ODM_RATEVHTSS2MCS3: + case ODM_RATEVHTSS1MCS9: + case ODM_RATEVHTSS1MCS8: + case ODM_RATEVHTSS1MCS7: + case ODM_RATEVHTSS1MCS6: + case ODM_RATEVHTSS1MCS5: + case ODM_RATEVHTSS1MCS4: + case ODM_RATEVHTSS1MCS3: + case ODM_RATEMCS15: + case ODM_RATEMCS14: + case ODM_RATEMCS13: + case ODM_RATEMCS12: + case ODM_RATEMCS11: + case ODM_RATEMCS7: + case ODM_RATEMCS6: + case ODM_RATEMCS5: + case ODM_RATEMCS4: + case ODM_RATEMCS3: + case ODM_RATE54M: + case ODM_RATE48M: + case ODM_RATE36M: + case ODM_RATE24M: + rts_ini_rate = ODM_RATE24M; + break; + case ODM_RATEVHTSS3MCS2: + case ODM_RATEVHTSS3MCS1: + case ODM_RATEVHTSS2MCS2: + case ODM_RATEVHTSS2MCS1: + case ODM_RATEVHTSS1MCS2: + case ODM_RATEVHTSS1MCS1: + case ODM_RATEMCS10: + case ODM_RATEMCS9: + case ODM_RATEMCS2: + case ODM_RATEMCS1: + case ODM_RATE18M: + case ODM_RATE12M: + rts_ini_rate = ODM_RATE12M; + break; + case ODM_RATEVHTSS3MCS0: + case ODM_RATEVHTSS2MCS0: + case ODM_RATEVHTSS1MCS0: + case ODM_RATEMCS8: + case ODM_RATEMCS0: + case ODM_RATE9M: + case ODM_RATE6M: + rts_ini_rate = ODM_RATE6M; + break; + case ODM_RATE11M: + case ODM_RATE5_5M: + case ODM_RATE2M: + case ODM_RATE1M: + rts_ini_rate = ODM_RATE1M; + break; + default: + rts_ini_rate = ODM_RATE6M; + break; + } + } + + if (*dm->band_type == 1) { + if (rts_ini_rate < ODM_RATE6M) + rts_ini_rate = ODM_RATE6M; + } + return rts_ini_rate; +} + +static void odm_set_ra_dm_arfb_by_noisy(struct phy_dm_struct *dm) {} + +void odm_update_noisy_state(void *dm_void, bool is_noisy_state_from_c2h) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /* JJ ADD 20161014 */ + if (dm->support_ic_type == ODM_RTL8821 || + dm->support_ic_type == ODM_RTL8812 || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8723D || + dm->support_ic_type == ODM_RTL8710B) + dm->is_noisy_state = is_noisy_state_from_c2h; + odm_set_ra_dm_arfb_by_noisy(dm); +}; + +void phydm_update_pwr_track(void *dm_void, u8 rate) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Pwr Track Get rate=0x%x\n", + rate); + + dm->tx_rate = rate; +} + +/* RA_MASK_PHYDMLIZE, will delete it later*/ + +bool odm_ra_state_check(void *dm_void, s32 rssi, bool is_force_update, + u8 *ra_tr_state) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct odm_rate_adaptive *ra = &dm->rate_adaptive; + const u8 go_up_gap = 5; + u8 high_rssi_thresh_for_ra = ra->high_rssi_thresh; + u8 low_rssi_thresh_for_ra = ra->low_rssi_thresh; + u8 ratr_state; + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "RSSI= (( %d )), Current_RSSI_level = (( %d ))\n", rssi, + *ra_tr_state); + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "[Ori RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", + high_rssi_thresh_for_ra, low_rssi_thresh_for_ra); + /* threshold Adjustment: + * when RSSI state trends to go up one or two levels, make sure RSSI is + * high enough. Here go_up_gap is added to solve the boundary's level + * alternation issue. + */ + + switch (*ra_tr_state) { + case DM_RATR_STA_INIT: + case DM_RATR_STA_HIGH: + break; + + case DM_RATR_STA_MIDDLE: + high_rssi_thresh_for_ra += go_up_gap; + break; + + case DM_RATR_STA_LOW: + high_rssi_thresh_for_ra += go_up_gap; + low_rssi_thresh_for_ra += go_up_gap; + break; + + default: + WARN_ONCE(true, "wrong rssi level setting %d !", *ra_tr_state); + break; + } + + /* Decide ratr_state by RSSI.*/ + if (rssi > high_rssi_thresh_for_ra) + ratr_state = DM_RATR_STA_HIGH; + else if (rssi > low_rssi_thresh_for_ra) + ratr_state = DM_RATR_STA_MIDDLE; + + else + ratr_state = DM_RATR_STA_LOW; + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "[Mod RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", + high_rssi_thresh_for_ra, low_rssi_thresh_for_ra); + + if (*ra_tr_state != ratr_state || is_force_update) { + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "[RSSI Level Update] %d->%d\n", *ra_tr_state, + ratr_state); + *ra_tr_state = ratr_state; + return true; + } + + return false; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.h b/drivers/staging/rtlwifi/phydm/phydm_rainfo.h new file mode 100644 index 0000000000000000000000000000000000000000..c14ed9bda0af60ca1094d090ccc74641319a511b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMRAINFO_H__ +#define __PHYDMRAINFO_H__ + +/*#define RAINFO_VERSION "2.0"*/ /*2014.11.04*/ +/*#define RAINFO_VERSION "3.0"*/ /*2015.01.13 Dino*/ +/*#define RAINFO_VERSION "3.1"*/ /*2015.01.14 Dino*/ +/*#define RAINFO_VERSION "3.3"*/ /*2015.07.29 YuChen*/ +/*#define RAINFO_VERSION "3.4"*/ /*2015.12.15 Stanley*/ +/*#define RAINFO_VERSION "4.0"*/ /*2016.03.24 Dino, Add more RA mask + *state and Phydm-lize partial ra mask + *function + */ +/*#define RAINFO_VERSION "4.1"*/ /*2016.04.20 Dino, Add new function to + *adjust PCR RA threshold + */ +/*#define RAINFO_VERSION "4.2"*/ /*2016.05.17 Dino, Add H2C debug cmd */ +#define RAINFO_VERSION "4.3" /*2016.07.11 Dino, Fix RA hang in CCK 1M problem*/ + +#define FORCED_UPDATE_RAMASK_PERIOD 5 + +#define H2C_0X42_LENGTH 5 +#define H2C_MAX_LENGTH 7 + +#define RA_FLOOR_UP_GAP 3 +#define RA_FLOOR_TABLE_SIZE 7 + +#define ACTIVE_TP_THRESHOLD 150 +#define RA_RETRY_DESCEND_NUM 2 +#define RA_RETRY_LIMIT_LOW 4 +#define RA_RETRY_LIMIT_HIGH 32 + +#define RAINFO_BE_RX_STATE BIT(0) /* 1:RX */ /* ULDL */ +#define RAINFO_STBC_STATE BIT(1) +/* #define RAINFO_LDPC_STATE BIT2 */ +#define RAINFO_NOISY_STATE BIT(2) /* set by Noisy_Detection */ +#define RAINFO_SHURTCUT_STATE BIT(3) +#define RAINFO_SHURTCUT_FLAG BIT(4) +#define RAINFO_INIT_RSSI_RATE_STATE BIT(5) +#define RAINFO_BF_STATE BIT(6) +#define RAINFO_BE_TX_STATE BIT(7) /* 1:TX */ + +#define RA_MASK_CCK 0xf +#define RA_MASK_OFDM 0xff0 +#define RA_MASK_HT1SS 0xff000 +#define RA_MASK_HT2SS 0xff00000 +/*#define RA_MASK_MCS3SS */ +#define RA_MASK_HT4SS 0xff0 +#define RA_MASK_VHT1SS 0x3ff000 +#define RA_MASK_VHT2SS 0xffc00000 + +#define RA_FIRST_MACID 0 + +#define ap_init_rate_adaptive_state odm_rate_adaptive_state_ap_init + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 +#define DM_RATR_STA_ULTRA_LOW 4 + +enum phydm_ra_arfr_num { + ARFR_0_RATE_ID = 0x9, + ARFR_1_RATE_ID = 0xa, + ARFR_2_RATE_ID = 0xb, + ARFR_3_RATE_ID = 0xc, + ARFR_4_RATE_ID = 0xd, + ARFR_5_RATE_ID = 0xe +}; + +enum phydm_ra_dbg_para { + RADBG_PCR_TH_OFFSET = 0, + RADBG_RTY_PENALTY = 1, + RADBG_N_HIGH = 2, + RADBG_N_LOW = 3, + RADBG_TRATE_UP_TABLE = 4, + RADBG_TRATE_DOWN_TABLE = 5, + RADBG_TRYING_NECESSARY = 6, + RADBG_TDROPING_NECESSARY = 7, + RADBG_RATE_UP_RTY_RATIO = 8, + RADBG_RATE_DOWN_RTY_RATIO = 9, /* u8 */ + + RADBG_DEBUG_MONITOR1 = 0xc, + RADBG_DEBUG_MONITOR2 = 0xd, + RADBG_DEBUG_MONITOR3 = 0xe, + RADBG_DEBUG_MONITOR4 = 0xf, + RADBG_DEBUG_MONITOR5 = 0x10, + NUM_RA_PARA +}; + +enum phydm_wireless_mode { + PHYDM_WIRELESS_MODE_UNKNOWN = 0x00, + PHYDM_WIRELESS_MODE_A = 0x01, + PHYDM_WIRELESS_MODE_B = 0x02, + PHYDM_WIRELESS_MODE_G = 0x04, + PHYDM_WIRELESS_MODE_AUTO = 0x08, + PHYDM_WIRELESS_MODE_N_24G = 0x10, + PHYDM_WIRELESS_MODE_N_5G = 0x20, + PHYDM_WIRELESS_MODE_AC_5G = 0x40, + PHYDM_WIRELESS_MODE_AC_24G = 0x80, + PHYDM_WIRELESS_MODE_AC_ONLY = 0x100, + PHYDM_WIRELESS_MODE_MAX = 0x800, + PHYDM_WIRELESS_MODE_ALL = 0xFFFF +}; + +enum phydm_rateid_idx { + PHYDM_BGN_40M_2SS = 0, + PHYDM_BGN_40M_1SS = 1, + PHYDM_BGN_20M_2SS = 2, + PHYDM_BGN_20M_1SS = 3, + PHYDM_GN_N2SS = 4, + PHYDM_GN_N1SS = 5, + PHYDM_BG = 6, + PHYDM_G = 7, + PHYDM_B_20M = 8, + PHYDM_ARFR0_AC_2SS = 9, + PHYDM_ARFR1_AC_1SS = 10, + PHYDM_ARFR2_AC_2G_1SS = 11, + PHYDM_ARFR3_AC_2G_2SS = 12, + PHYDM_ARFR4_AC_3SS = 13, + PHYDM_ARFR5_N_3SS = 14 +}; + +enum phydm_rf_type_def { + PHYDM_RF_1T1R = 0, + PHYDM_RF_1T2R, + PHYDM_RF_2T2R, + PHYDM_RF_2T2R_GREEN, + PHYDM_RF_2T3R, + PHYDM_RF_2T4R, + PHYDM_RF_3T3R, + PHYDM_RF_3T4R, + PHYDM_RF_4T4R, + PHYDM_RF_MAX_TYPE +}; + +enum phydm_bw { + PHYDM_BW_20 = 0, + PHYDM_BW_40, + PHYDM_BW_80, + PHYDM_BW_80_80, + PHYDM_BW_160, + PHYDM_BW_10, + PHYDM_BW_5 +}; + +struct ra_table { + u8 firstconnect; + + u8 link_tx_rate[ODM_ASSOCIATE_ENTRY_NUM]; + u8 highest_client_tx_order; + u16 highest_client_tx_rate_order; + u8 power_tracking_flag; + u8 RA_threshold_offset; + u8 RA_offset_direction; + u8 force_update_ra_mask_count; +}; + +struct odm_rate_adaptive { + /* dm_type_by_fw/dm_type_by_driver */ + u8 type; + /* if RSSI > high_rssi_thresh => ratr_state is DM_RATR_STA_HIGH */ + u8 high_rssi_thresh; + /* if RSSI <= low_rssi_thresh => ratr_state is DM_RATR_STA_LOW */ + u8 low_rssi_thresh; + /* Cur RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW*/ + u8 ratr_state; + + /* if RSSI > ldpc_thres => switch from LPDC to BCC */ + u8 ldpc_thres; + bool is_lower_rts_rate; + + bool is_use_ldpc; +}; + +void phydm_h2C_debug(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len); + +void phydm_RA_debug_PCR(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len); + +void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +void odm_ra_para_adjust(void *dm_void); + +void phydm_ra_dynamic_retry_count(void *dm_void); + +void phydm_ra_dynamic_retry_limit(void *dm_void); + +void phydm_ra_dynamic_rate_id_on_assoc(void *dm_void, u8 wireless_mode, + u8 init_rate_id); + +void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component); + +void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx); + +void phydm_ra_info_watchdog(void *dm_void); + +void phydm_ra_info_init(void *dm_void); + +void odm_rssi_monitor_init(void *dm_void); + +void phydm_modify_RA_PCR_threshold(void *dm_void, u8 RA_offset_direction, + u8 RA_threshold_offset); + +void odm_rssi_monitor_check(void *dm_void); + +void phydm_init_ra_info(void *dm_void); + +u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode); + +u8 phydm_rate_id_mapping(void *dm_void, u32 wireless_mode, u8 rf_type, u8 bw); + +void phydm_update_hal_ra_mask(void *dm_void, u32 wireless_mode, u8 rf_type, + u8 BW, u8 mimo_ps_enable, u8 disable_cck_rate, + u32 *ratr_bitmap_msb_in, u32 *ratr_bitmap_in, + u8 tx_rate_level); + +void odm_rate_adaptive_mask_init(void *dm_void); + +void odm_refresh_rate_adaptive_mask(void *dm_void); + +void odm_refresh_rate_adaptive_mask_mp(void *dm_void); + +void odm_refresh_rate_adaptive_mask_ce(void *dm_void); + +void odm_refresh_rate_adaptive_mask_apadsl(void *dm_void); + +u8 phydm_RA_level_decision(void *dm_void, u32 rssi, u8 ratr_state); + +bool odm_ra_state_check(void *dm_void, s32 RSSI, bool is_force_update, + u8 *ra_tr_state); + +void odm_refresh_basic_rate_mask(void *dm_void); +void odm_ra_post_action_on_assoc(void *dm); + +u8 odm_find_rts_rate(void *dm_void, u8 tx_rate, bool is_erp_protect); + +void odm_update_noisy_state(void *dm_void, bool is_noisy_state_from_c2h); + +void phydm_update_pwr_track(void *dm_void, u8 rate); + +#endif /*#ifndef __ODMRAINFO_H__*/ diff --git a/drivers/staging/rtlwifi/phydm/phydm_reg.h b/drivers/staging/rtlwifi/phydm/phydm_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..d9d878e4c9250792b671e7856c2e66fd49c5964b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_reg.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +/* ************************************************************ + * File Name: odm_reg.h + * + * Description: + * + * This file is for general register definition. + * + * + * *************************************************************/ +#ifndef __HAL_ODM_REG_H__ +#define __HAL_ODM_REG_H__ + +/* + * Register Definition + */ + +/* MAC REG */ +#define ODM_BB_RESET 0x002 +#define ODM_DUMMY 0x4fe +#define RF_T_METER_OLD 0x24 +#define RF_T_METER_NEW 0x42 + +#define ODM_EDCA_VO_PARAM 0x500 +#define ODM_EDCA_VI_PARAM 0x504 +#define ODM_EDCA_BE_PARAM 0x508 +#define ODM_EDCA_BK_PARAM 0x50C +#define ODM_TXPAUSE 0x522 + +/* LTE_COEX */ +#define REG_LTECOEX_CTRL 0x07C0 +#define REG_LTECOEX_WRITE_DATA 0x07C4 +#define REG_LTECOEX_READ_DATA 0x07C8 +#define REG_LTECOEX_PATH_CONTROL 0x70 + +/* BB REG */ +#define ODM_FPGA_PHY0_PAGE8 0x800 +#define ODM_PSD_SETTING 0x808 +#define ODM_AFE_SETTING 0x818 +#define ODM_TXAGC_B_6_18 0x830 +#define ODM_TXAGC_B_24_54 0x834 +#define ODM_TXAGC_B_MCS32_5 0x838 +#define ODM_TXAGC_B_MCS0_MCS3 0x83c +#define ODM_TXAGC_B_MCS4_MCS7 0x848 +#define ODM_TXAGC_B_MCS8_MCS11 0x84c +#define ODM_ANALOG_REGISTER 0x85c +#define ODM_RF_INTERFACE_OUTPUT 0x860 +#define ODM_TXAGC_B_MCS12_MCS15 0x868 +#define ODM_TXAGC_B_11_A_2_11 0x86c +#define ODM_AD_DA_LSB_MASK 0x874 +#define ODM_ENABLE_3_WIRE 0x88c +#define ODM_PSD_REPORT 0x8b4 +#define ODM_R_ANT_SELECT 0x90c +#define ODM_CCK_ANT_SELECT 0xa07 +#define ODM_CCK_PD_THRESH 0xa0a +#define ODM_CCK_RF_REG1 0xa11 +#define ODM_CCK_MATCH_FILTER 0xa20 +#define ODM_CCK_RAKE_MAC 0xa2e +#define ODM_CCK_CNT_RESET 0xa2d +#define ODM_CCK_TX_DIVERSITY 0xa2f +#define ODM_CCK_FA_CNT_MSB 0xa5b +#define ODM_CCK_FA_CNT_LSB 0xa5c +#define ODM_CCK_NEW_FUNCTION 0xa75 +#define ODM_OFDM_PHY0_PAGE_C 0xc00 +#define ODM_OFDM_RX_ANT 0xc04 +#define ODM_R_A_RXIQI 0xc14 +#define ODM_R_A_AGC_CORE1 0xc50 +#define ODM_R_A_AGC_CORE2 0xc54 +#define ODM_R_B_AGC_CORE1 0xc58 +#define ODM_R_AGC_PAR 0xc70 +#define ODM_R_HTSTF_AGC_PAR 0xc7c +#define ODM_TX_PWR_TRAINING_A 0xc90 +#define ODM_TX_PWR_TRAINING_B 0xc98 +#define ODM_OFDM_FA_CNT1 0xcf0 +#define ODM_OFDM_PHY0_PAGE_D 0xd00 +#define ODM_OFDM_FA_CNT2 0xda0 +#define ODM_OFDM_FA_CNT3 0xda4 +#define ODM_OFDM_FA_CNT4 0xda8 +#define ODM_TXAGC_A_6_18 0xe00 +#define ODM_TXAGC_A_24_54 0xe04 +#define ODM_TXAGC_A_1_MCS32 0xe08 +#define ODM_TXAGC_A_MCS0_MCS3 0xe10 +#define ODM_TXAGC_A_MCS4_MCS7 0xe14 +#define ODM_TXAGC_A_MCS8_MCS11 0xe18 +#define ODM_TXAGC_A_MCS12_MCS15 0xe1c + +/* RF REG */ +#define ODM_GAIN_SETTING 0x00 +#define ODM_CHANNEL 0x18 +#define ODM_RF_T_METER 0x24 +#define ODM_RF_T_METER_92D 0x42 +#define ODM_RF_T_METER_88E 0x42 +#define ODM_RF_T_METER_92E 0x42 +#define ODM_RF_T_METER_8812 0x42 +#define REG_RF_TX_GAIN_OFFSET 0x55 + +/* ant Detect Reg */ +#define ODM_DPDT 0x300 + +/* PSD Init */ +#define ODM_PSDREG 0x808 + +/* 92D path Div */ +#define PATHDIV_REG 0xB30 +#define PATHDIV_TRI 0xBA0 + +/* + * Bitmap Definition + */ + +#define BIT_FA_RESET BIT(0) + +#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0xC80 +#define REG_OFDM_0_ECCA_THRESHOLD 0xC4C +#define REG_FPGA0_XB_LSSI_READ_BACK 0x8A4 +#define REG_FPGA0_TX_GAIN_STAGE 0x80C +#define REG_OFDM_0_XA_AGC_CORE1 0xC50 +#define REG_OFDM_0_XB_AGC_CORE1 0xC58 +#define REG_A_TX_SCALE_JAGUAR 0xC1C +#define REG_B_TX_SCALE_JAGUAR 0xE1C + +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002C + +#define RF_CHNLBW 0x18 + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h b/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h new file mode 100644 index 0000000000000000000000000000000000000000..28d48415ac99d8d11d3e111eaa60536ca95d7343 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h @@ -0,0 +1,94 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_REGDEFINE11AC_H__ +#define __ODM_REGDEFINE11AC_H__ + +/* 2 RF REG LIST */ + +/* 2 BB REG LIST */ +/* PAGE 8 */ +#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804 +#define ODM_REG_BB_RX_PATH_11AC 0x808 +#define ODM_REG_BB_TX_PATH_11AC 0x80c +#define ODM_REG_BB_ATC_11AC 0x860 +#define ODM_REG_EDCCA_POWER_CAL 0x8dc +#define ODM_REG_DBG_RPT_11AC 0x8fc +/* PAGE 9 */ +#define ODM_REG_EDCCA_DOWN_OPT 0x900 +#define ODM_REG_ACBB_EDCCA_ENHANCE 0x944 +#define odm_adc_trigger_jaguar2 0x95C /*ADC sample mode*/ +#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 +#define ODM_REG_CCX_PERIOD_11AC 0x990 +#define ODM_REG_NHM_TH9_TH10_11AC 0x994 +#define ODM_REG_CLM_11AC 0x994 +#define ODM_REG_NHM_TH3_TO_TH0_11AC 0x998 +#define ODM_REG_NHM_TH7_TO_TH4_11AC 0x99c +#define ODM_REG_NHM_TH8_11AC 0x9a0 +#define ODM_REG_NHM_9E8_11AC 0x9e8 +#define ODM_REG_CSI_CONTENT_VALUE 0x9b4 +/* PAGE A */ +#define ODM_REG_CCK_CCA_11AC 0xA0A +#define ODM_REG_CCK_FA_RST_11AC 0xA2C +#define ODM_REG_CCK_FA_11AC 0xA5C +/* PAGE B */ +#define ODM_REG_RST_RPT_11AC 0xB58 +/* PAGE C */ +#define ODM_REG_TRMUX_11AC 0xC08 +#define ODM_REG_IGI_A_11AC 0xC50 +/* PAGE E */ +#define ODM_REG_IGI_B_11AC 0xE50 +#define ODM_REG_TRMUX_11AC_B 0xE08 +/* PAGE F */ +#define ODM_REG_CCK_CRC32_CNT_11AC 0xF04 +#define ODM_REG_CCK_CCA_CNT_11AC 0xF08 +#define ODM_REG_VHT_CRC32_CNT_11AC 0xF0c +#define ODM_REG_HT_CRC32_CNT_11AC 0xF10 +#define ODM_REG_OFDM_CRC32_CNT_11AC 0xF14 +#define ODM_REG_OFDM_FA_11AC 0xF48 +#define ODM_REG_RPT_11AC 0xfa0 +#define ODM_REG_CLM_RESULT_11AC 0xfa4 +#define ODM_REG_NHM_CNT_11AC 0xfa8 +#define ODM_REG_NHM_DUR_READY_11AC 0xfb4 + +#define ODM_REG_NHM_CNT7_TO_CNT4_11AC 0xfac +#define ODM_REG_NHM_CNT11_TO_CNT8_11AC 0xfb0 +#define ODM_REG_OFDM_FA_TYPE2_11AC 0xFD0 +/* PAGE 18 */ +#define ODM_REG_IGI_C_11AC 0x1850 +/* PAGE 1A */ +#define ODM_REG_IGI_D_11AC 0x1A50 + +/* 2 MAC REG LIST */ +#define ODM_REG_RESP_TX_11AC 0x6D8 + +/* DIG Related */ +#define ODM_BIT_IGI_11AC 0xFFFFFFFF +#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT(16) +#define ODM_BIT_BB_RX_PATH_11AC 0xF +#define ODM_BIT_BB_TX_PATH_11AC 0xF +#define ODM_BIT_BB_ATC_11AC BIT(14) + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h b/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h new file mode 100644 index 0000000000000000000000000000000000000000..0b6581c50ab34c0b622efc6153c997e728fba6e5 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h @@ -0,0 +1,213 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_REGDEFINE11N_H__ +#define __ODM_REGDEFINE11N_H__ + +/* 2 RF REG LIST */ +#define ODM_REG_RF_MODE_11N 0x00 +#define ODM_REG_RF_0B_11N 0x0B +#define ODM_REG_CHNBW_11N 0x18 +#define ODM_REG_T_METER_11N 0x24 +#define ODM_REG_RF_25_11N 0x25 +#define ODM_REG_RF_26_11N 0x26 +#define ODM_REG_RF_27_11N 0x27 +#define ODM_REG_RF_2B_11N 0x2B +#define ODM_REG_RF_2C_11N 0x2C +#define ODM_REG_RXRF_A3_11N 0x3C +#define ODM_REG_T_METER_92D_11N 0x42 +#define ODM_REG_T_METER_88E_11N 0x42 + +/* 2 BB REG LIST */ +/* PAGE 8 */ +#define ODM_REG_BB_CTRL_11N 0x800 +#define ODM_REG_RF_PIN_11N 0x804 +#define ODM_REG_PSD_CTRL_11N 0x808 +#define ODM_REG_TX_ANT_CTRL_11N 0x80C +#define ODM_REG_BB_PWR_SAV5_11N 0x818 +#define ODM_REG_CCK_RPT_FORMAT_11N 0x824 +#define ODM_REG_CCK_RPT_FORMAT_11N_B 0x82C +#define ODM_REG_RX_DEFAULT_A_11N 0x858 +#define ODM_REG_RX_DEFAULT_B_11N 0x85A +#define ODM_REG_BB_PWR_SAV3_11N 0x85C +#define ODM_REG_ANTSEL_CTRL_11N 0x860 +#define ODM_REG_RX_ANT_CTRL_11N 0x864 +#define ODM_REG_PIN_CTRL_11N 0x870 +#define ODM_REG_BB_PWR_SAV1_11N 0x874 +#define ODM_REG_ANTSEL_PATH_11N 0x878 +#define ODM_REG_BB_3WIRE_11N 0x88C +#define ODM_REG_SC_CNT_11N 0x8C4 +#define ODM_REG_PSD_DATA_11N 0x8B4 +#define ODM_REG_CCX_PERIOD_11N 0x894 +#define ODM_REG_NHM_TH9_TH10_11N 0x890 +#define ODM_REG_CLM_11N 0x890 +#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898 +#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c +#define ODM_REG_NHM_TH8_11N 0xe28 +#define ODM_REG_CLM_READY_11N 0x8b4 +#define ODM_REG_CLM_RESULT_11N 0x8d0 +#define ODM_REG_NHM_CNT_11N 0x8d8 + +/* For struct acs_info, Jeffery, 2014-12-26 */ +#define ODM_REG_NHM_CNT7_TO_CNT4_11N 0x8dc +#define ODM_REG_NHM_CNT9_TO_CNT8_11N 0x8d0 +#define ODM_REG_NHM_CNT10_TO_CNT11_11N 0x8d4 + +/* PAGE 9 */ +#define ODM_REG_BB_CTRL_PAGE9_11N 0x900 +#define ODM_REG_DBG_RPT_11N 0x908 +#define ODM_REG_BB_TX_PATH_11N 0x90c +#define ODM_REG_ANT_MAPPING1_11N 0x914 +#define ODM_REG_ANT_MAPPING2_11N 0x918 +#define ODM_REG_EDCCA_DOWN_OPT_11N 0x948 +#define ODM_REG_RX_DFIR_MOD_97F 0x948 + +/* PAGE A */ +#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define ODM_REG_CCK_ANT_SEL_11N 0xA04 +#define ODM_REG_CCK_CCA_11N 0xA0A +#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define ODM_REG_CCK_FA_RST_11N 0xA2C +#define ODM_REG_CCK_FA_MSB_11N 0xA58 +#define ODM_REG_CCK_FA_LSB_11N 0xA5C +#define ODM_REG_CCK_CCA_CNT_11N 0xA60 +#define ODM_REG_BB_PWR_SAV4_11N 0xA74 +/* PAGE B */ +#define ODM_REG_LNA_SWITCH_11N 0xB2C +#define ODM_REG_PATH_SWITCH_11N 0xB30 +#define ODM_REG_RSSI_CTRL_11N 0xB38 +#define ODM_REG_CONFIG_ANTA_11N 0xB68 +#define ODM_REG_RSSI_BT_11N 0xB9C +#define ODM_REG_RXCK_RFMOD 0xBB0 +#define ODM_REG_EDCCA_DCNF_97F 0xBC0 + +/* PAGE C */ +#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define ODM_REG_BB_RX_PATH_11N 0xC04 +#define ODM_REG_TRMUX_11N 0xC08 +#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C +#define ODM_REG_DOWNSAM_FACTOR_11N 0xC10 +#define ODM_REG_RXIQI_MATRIX_11N 0xC14 +#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define ODM_REG_IGI_A_11N 0xC50 +#define ODM_REG_ANTDIV_PARA2_11N 0xC54 +#define ODM_REG_IGI_B_11N 0xC58 +#define ODM_REG_ANTDIV_PARA3_11N 0xC5C +#define ODM_REG_L1SBD_PD_CH_11N 0XC6C +#define ODM_REG_BB_PWR_SAV2_11N 0xC70 +#define ODM_REG_BB_AGC_SET_2_11N 0xc74 +#define ODM_REG_RX_OFF_11N 0xC7C +#define ODM_REG_TXIQK_MATRIXA_11N 0xC80 +#define ODM_REG_TXIQK_MATRIXB_11N 0xC88 +#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define ODM_REG_ANTDIV_PARA1_11N 0xCA4 +#define ODM_REG_SMALL_BANDWIDTH_11N 0xCE4 +#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0 +/* PAGE D */ +#define ODM_REG_OFDM_FA_RSTD_11N 0xD00 +#define ODM_REG_BB_RX_ANT_11N 0xD04 +#define ODM_REG_BB_ATC_11N 0xD2C +#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8 +#define ODM_REG_RPT_11N 0xDF4 +/* PAGE E */ +#define ODM_REG_TXAGC_A_6_18_11N 0xE00 +#define ODM_REG_TXAGC_A_24_54_11N 0xE04 +#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define ODM_REG_EDCCA_DCNF_11N 0xE24 +#define ODM_REG_TAP_UPD_97F 0xE24 +#define ODM_REG_FPGA0_IQK_11N 0xE28 +#define ODM_REG_PAGE_B1_97F 0xE28 +#define ODM_REG_TXIQK_TONE_A_11N 0xE30 +#define ODM_REG_RXIQK_TONE_A_11N 0xE34 +#define ODM_REG_TXIQK_PI_A_11N 0xE38 +#define ODM_REG_RXIQK_PI_A_11N 0xE3C +#define ODM_REG_TXIQK_11N 0xE40 +#define ODM_REG_RXIQK_11N 0xE44 +#define ODM_REG_IQK_AGC_PTS_11N 0xE48 +#define ODM_REG_IQK_AGC_RSP_11N 0xE4C +#define ODM_REG_BLUETOOTH_11N 0xE6C +#define ODM_REG_RX_WAIT_CCA_11N 0xE70 +#define ODM_REG_TX_CCK_RFON_11N 0xE74 +#define ODM_REG_TX_CCK_BBON_11N 0xE78 +#define ODM_REG_OFDM_RFON_11N 0xE7C +#define ODM_REG_OFDM_BBON_11N 0xE80 +#define ODM_REG_TX2RX_11N 0xE84 +#define ODM_REG_TX2TX_11N 0xE88 +#define ODM_REG_RX_CCK_11N 0xE8C +#define ODM_REG_RX_OFDM_11N 0xED0 +#define ODM_REG_RX_WAIT_RIFS_11N 0xED4 +#define ODM_REG_RX2RX_11N 0xED8 +#define ODM_REG_STANDBY_11N 0xEDC +#define ODM_REG_SLEEP_11N 0xEE0 +#define ODM_REG_PMPD_ANAEN_11N 0xEEC +/* PAGE F */ +#define ODM_REG_PAGE_F_RST_11N 0xF14 +#define ODM_REG_IGI_C_11N 0xF84 +#define ODM_REG_IGI_D_11N 0xF88 +#define ODM_REG_CCK_CRC32_ERROR_CNT_11N 0xF84 +#define ODM_REG_CCK_CRC32_OK_CNT_11N 0xF88 +#define ODM_REG_HT_CRC32_CNT_11N 0xF90 +#define ODM_REG_OFDM_CRC32_CNT_11N 0xF94 + +/* 2 MAC REG LIST */ +#define ODM_REG_BB_RST_11N 0x02 +#define ODM_REG_ANTSEL_PIN_11N 0x4C +#define ODM_REG_EARLY_MODE_11N 0x4D0 +#define ODM_REG_RSSI_MONITOR_11N 0x4FE +#define ODM_REG_EDCA_VO_11N 0x500 +#define ODM_REG_EDCA_VI_11N 0x504 +#define ODM_REG_EDCA_BE_11N 0x508 +#define ODM_REG_EDCA_BK_11N 0x50C +#define ODM_REG_TXPAUSE_11N 0x522 +#define ODM_REG_RESP_TX_11N 0x6D8 +#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + +/* DIG Related */ +#define ODM_BIT_IGI_11N 0x0000007F +#define ODM_BIT_CCK_RPT_FORMAT_11N BIT(9) +#define ODM_BIT_BB_RX_PATH_11N 0xF +#define ODM_BIT_BB_TX_PATH_11N 0xF +#define ODM_BIT_BB_ATC_11N BIT(11) + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_types.h b/drivers/staging/rtlwifi/phydm/phydm_types.h new file mode 100644 index 0000000000000000000000000000000000000000..a34ebe8765286f682d76b20bd47b27622fba18e0 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_types.h @@ -0,0 +1,130 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __ODM_TYPES_H__ +#define __ODM_TYPES_H__ + +/*Define Different SW team support*/ +#define ODM_AP 0x01 /*BIT0*/ +#define ODM_CE 0x04 /*BIT2*/ +#define ODM_WIN 0x08 /*BIT3*/ +#define ODM_ADSL 0x10 /*BIT4*/ +#define ODM_IOT 0x20 /*BIT5*/ + +/*Deifne HW endian support*/ +#define ODM_ENDIAN_BIG 0 +#define ODM_ENDIAN_LITTLE 1 + +#define GET_PDM_ODM(__padapter) \ + ((struct phy_dm_struct *)(&(GET_HAL_DATA(__padapter))->odmpriv)) + +enum hal_status { + HAL_STATUS_SUCCESS, + HAL_STATUS_FAILURE, +}; + +/* + * Declare for ODM spin lock definition temporarily fro compile pass. + */ +enum rt_spinlock_type { + RT_TX_SPINLOCK = 1, + RT_RX_SPINLOCK = 2, + RT_RM_SPINLOCK = 3, + RT_CAM_SPINLOCK = 4, + RT_SCAN_SPINLOCK = 5, + RT_LOG_SPINLOCK = 7, + RT_BW_SPINLOCK = 8, + RT_CHNLOP_SPINLOCK = 9, + RT_RF_OPERATE_SPINLOCK = 10, + RT_INITIAL_SPINLOCK = 11, + RT_RF_STATE_SPINLOCK = + 12, /* For RF state. Added by Bruce, 2007-10-30. */ + /* Shall we define Ndis 6.2 SpinLock Here ? */ + RT_PORT_SPINLOCK = 16, + RT_VNIC_SPINLOCK = 17, + RT_HVL_SPINLOCK = 18, + RT_H2C_SPINLOCK = 20, /* For H2C cmd. Added by tynli. 2009.11.09. */ + + rt_bt_data_spinlock = 25, + + RT_WAPI_OPTION_SPINLOCK = 26, + RT_WAPI_RX_SPINLOCK = 27, + + /* add for 92D CCK control issue */ + RT_CCK_PAGEA_SPINLOCK = 28, + RT_BUFFER_SPINLOCK = 29, + RT_CHANNEL_AND_BANDWIDTH_SPINLOCK = 30, + RT_GEN_TEMP_BUF_SPINLOCK = 31, + RT_AWB_SPINLOCK = 32, + RT_FW_PS_SPINLOCK = 33, + RT_HW_TIMER_SPIN_LOCK = 34, + RT_MPT_WI_SPINLOCK = 35, + RT_P2P_SPIN_LOCK = 36, /* Protect P2P context */ + RT_DBG_SPIN_LOCK = 37, + RT_IQK_SPINLOCK = 38, + RT_PENDED_OID_SPINLOCK = 39, + RT_CHNLLIST_SPINLOCK = 40, + RT_INDIC_SPINLOCK = 41, /* protect indication */ + RT_RFD_SPINLOCK = 42, + RT_SYNC_IO_CNT_SPINLOCK = 43, + RT_LAST_SPINLOCK, +}; + +#include + +#if defined(__LITTLE_ENDIAN) +#define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE +#elif defined(__BIG_ENDIAN) +#define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG +#else +#error +#endif + +#define COND_ELSE 2 +#define COND_ENDIF 3 + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK7BITS 0x7f +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASK20BITS 0xfffff +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f +#define RFREGOFFSETMASK 0xfffff +#define MASKH3BYTES 0xffffff00 +#define MASKL3BYTES 0x00ffffff +#define MASKBYTE2HIGHNIBBLE 0x00f00000 +#define MASKBYTE3LOWNIBBLE 0x0f000000 +#define MASKL3BYTES 0x00ffffff +#define RFREGOFFSETMASK 0xfffff + +#include "phydm_features.h" + +#endif /* __ODM_TYPES_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c new file mode 100644 index 0000000000000000000000000000000000000000..4e7946019fcb952a36bc8f411a2e7e90c3fb2162 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c @@ -0,0 +1,1969 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool check_positive(struct phy_dm_struct *dm, const u32 condition1, + const u32 condition2, const u32 condition3, + const u32 condition4) +{ + u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/ + ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/ + ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/ + ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/ + + u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, + cond4 = condition4; + + u8 cut_version_for_para = + (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version; + u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type; + + u32 driver1 = cut_version_for_para << 24 | + (dm->support_interface & 0xF0) << 16 | + dm->support_platform << 16 | pkg_type_for_para << 12 | + (dm->support_interface & 0x0F) << 8 | _board_type; + + u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 | + (dm->type_alna & 0xFF) << 16 | + (dm->type_apa & 0xFF) << 24; + + u32 driver3 = 0; + + u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) | + (dm->type_alna & 0xFF00) << 8 | + (dm->type_apa & 0xFF00) << 16; + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, cond1, cond2, cond3, cond4); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, driver1, driver2, driver3, driver4); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Platform, Interface) = (0x%X, 0x%X)\n", + dm->support_platform, dm->support_interface); + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Board, Package) = (0x%X, 0x%X)\n", + dm->board_type, dm->package_type); + + /*============== value Defined Check ===============*/ + /*QFN type [15:12] and cut version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && + ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && + ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 bit_mask = 0; + + if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + bit_mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + bit_mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + bit_mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + bit_mask |= 0xFF000000; + + if (((cond2 & bit_mask) == (driver2 & bit_mask)) && + ((cond4 & bit_mask) == + (driver4 & + bit_mask))) /* board_type of each RF path is matched*/ + return true; + else + return false; + } else { + return false; + } +} + +/****************************************************************************** + * agc_tab.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_agc_tab[] = { + 0x8000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003, + 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003, + 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003, + 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003, + 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003, + 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003, + 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003, + 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003, + 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003, + 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003, + 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003, + 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003, + 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003, + 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, 0x81C, 0xF5000003, 0x81C, 0xF4020003, + 0x81C, 0xF3040003, 0x81C, 0xF2060003, 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, 0x81C, 0xEC120003, 0x81C, 0xEB140003, + 0x81C, 0xEA160003, 0x81C, 0xE9180003, 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, 0x81C, 0xE61E0003, 0x81C, 0xE5200003, + 0x81C, 0xE4220003, 0x81C, 0xE3240003, 0x81C, 0xE2260003, + 0x81C, 0xE1280003, 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, 0x81C, 0xC1300003, 0x81C, 0xC0320003, + 0x81C, 0xA4340003, 0x81C, 0xA3360003, 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, 0x81C, 0xA03C0003, 0x81C, 0x823E0003, + 0x81C, 0x81400003, 0x81C, 0x80420003, 0x81C, 0x64440003, + 0x81C, 0x63460003, 0x81C, 0x62480003, 0x81C, 0x614A0003, + 0x81C, 0x604C0003, 0x81C, 0x454E0003, 0x81C, 0x44500003, + 0x81C, 0x43520003, 0x81C, 0x42540003, 0x81C, 0x41560003, + 0x81C, 0x40580003, 0x81C, 0x055A0003, 0x81C, 0x045C0003, + 0x81C, 0x035E0003, 0x81C, 0x02600003, 0x81C, 0x01620003, + 0x81C, 0x00640003, 0x81C, 0x00660003, 0x81C, 0x00680003, + 0x81C, 0x006A0003, 0x81C, 0x006C0003, 0x81C, 0x006E0003, + 0x81C, 0x00700003, 0x81C, 0x00720003, 0x81C, 0x00740003, + 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003, + 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xF5000003, + 0x81C, 0xF4020003, 0x81C, 0xF3040003, 0x81C, 0xF2060003, + 0x81C, 0xF1080003, 0x81C, 0xF00A0003, 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, 0x81C, 0xED100003, 0x81C, 0xEC120003, + 0x81C, 0xEB140003, 0x81C, 0xEA160003, 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, 0x81C, 0xE4220003, 0x81C, 0xE3240003, + 0x81C, 0xE2260003, 0x81C, 0xE1280003, 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, 0x81C, 0xC1300003, + 0x81C, 0xC0320003, 0x81C, 0xA4340003, 0x81C, 0xA3360003, + 0x81C, 0xA2380003, 0x81C, 0xA13A0003, 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, 0x81C, 0x81400003, 0x81C, 0x80420003, + 0x81C, 0x64440003, 0x81C, 0x63460003, 0x81C, 0x62480003, + 0x81C, 0x614A0003, 0x81C, 0x604C0003, 0x81C, 0x454E0003, + 0x81C, 0x44500003, 0x81C, 0x43520003, 0x81C, 0x42540003, + 0x81C, 0x41560003, 0x81C, 0x40580003, 0x81C, 0x055A0003, + 0x81C, 0x045C0003, 0x81C, 0x035E0003, 0x81C, 0x02600003, + 0x81C, 0x01620003, 0x81C, 0x00640003, 0x81C, 0x00660003, + 0x81C, 0x00680003, 0x81C, 0x006A0003, 0x81C, 0x006C0003, + 0x81C, 0x006E0003, 0x81C, 0x00700003, 0x81C, 0x00720003, + 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003, + 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003, + 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003, + 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003, + 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003, + 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003, + 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003, + 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003, + 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003, + 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003, + 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003, + 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003, + 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003, + 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003, + 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, 0x81C, 0xFD000003, 0x81C, 0xFC020003, + 0x81C, 0xFB040003, 0x81C, 0xFA060003, 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, 0x81C, 0xF70C0003, 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, 0x81C, 0xF4120003, 0x81C, 0xF3140003, + 0x81C, 0xF2160003, 0x81C, 0xF1180003, 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, 0x81C, 0xEE1E0003, 0x81C, 0xED200003, + 0x81C, 0xEC220003, 0x81C, 0xEB240003, 0x81C, 0xEA260003, + 0x81C, 0xE9280003, 0x81C, 0xE82A0003, 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, 0x81C, 0xE5300003, 0x81C, 0xC8320003, + 0x81C, 0xC7340003, 0x81C, 0xC6360003, 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, 0x81C, 0xC33C0003, 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, 0x81C, 0xC0420003, 0x81C, 0xA5440003, + 0x81C, 0xA4460003, 0x81C, 0xA3480003, 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, 0x81C, 0x834E0003, 0x81C, 0x82500003, + 0x81C, 0x81520003, 0x81C, 0x80540003, 0x81C, 0x65560003, + 0x81C, 0x64580003, 0x81C, 0x635A0003, 0x81C, 0x625C0003, + 0x81C, 0x435E0003, 0x81C, 0x42600003, 0x81C, 0x41620003, + 0x81C, 0x40640003, 0x81C, 0x06660003, 0x81C, 0x05680003, + 0x81C, 0x046A0003, 0x81C, 0x036C0003, 0x81C, 0x026E0003, + 0x81C, 0x01700003, 0x81C, 0x00720003, 0x81C, 0x00740003, + 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003, + 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xFE000003, + 0x81C, 0xFD020003, 0x81C, 0xFC040003, 0x81C, 0xFB060003, + 0x81C, 0xFA080003, 0x81C, 0xF90A0003, 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, 0x81C, 0xF6100003, 0x81C, 0xF5120003, + 0x81C, 0xF4140003, 0x81C, 0xF3160003, 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, 0x81C, 0xF01C0003, 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, 0x81C, 0xED220003, 0x81C, 0xEC240003, + 0x81C, 0xEB260003, 0x81C, 0xEA280003, 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, 0x81C, 0xE72E0003, 0x81C, 0xE6300003, + 0x81C, 0xE5320003, 0x81C, 0xC8340003, 0x81C, 0xC7360003, + 0x81C, 0xC6380003, 0x81C, 0xC53A0003, 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, 0x81C, 0xC2400003, 0x81C, 0xC1420003, + 0x81C, 0xC0440003, 0x81C, 0xA3460003, 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, 0x81C, 0xA04C0003, 0x81C, 0x824E0003, + 0x81C, 0x81500003, 0x81C, 0x80520003, 0x81C, 0x64540003, + 0x81C, 0x63560003, 0x81C, 0x62580003, 0x81C, 0x445A0003, + 0x81C, 0x435C0003, 0x81C, 0x425E0003, 0x81C, 0x41600003, + 0x81C, 0x40620003, 0x81C, 0x05640003, 0x81C, 0x04660003, + 0x81C, 0x03680003, 0x81C, 0x026A0003, 0x81C, 0x016C0003, + 0x81C, 0x006E0003, 0x81C, 0x00700003, 0x81C, 0x00720003, + 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003, + 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003, + 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003, + 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003, + 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003, + 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003, + 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003, + 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003, + 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003, + 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003, + 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003, + 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003, + 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003, + 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003, + 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0x90011000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, 0x81C, 0xFE000003, 0x81C, 0xFD020003, + 0x81C, 0xFC040003, 0x81C, 0xFB060003, 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, 0x81C, 0xF80C0003, 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, 0x81C, 0xF5120003, 0x81C, 0xF4140003, + 0x81C, 0xF3160003, 0x81C, 0xF2180003, 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, 0x81C, 0xEF1E0003, 0x81C, 0xEE200003, + 0x81C, 0xED220003, 0x81C, 0xEC240003, 0x81C, 0xEB260003, + 0x81C, 0xEA280003, 0x81C, 0xE92A0003, 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, 0x81C, 0xE6300003, 0x81C, 0xE5320003, + 0x81C, 0xC8340003, 0x81C, 0xC7360003, 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, 0x81C, 0xC43C0003, 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, 0x81C, 0xC1420003, 0x81C, 0xC0440003, + 0x81C, 0xA3460003, 0x81C, 0xA2480003, 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, 0x81C, 0x824E0003, 0x81C, 0x81500003, + 0x81C, 0x80520003, 0x81C, 0x64540003, 0x81C, 0x63560003, + 0x81C, 0x62580003, 0x81C, 0x445A0003, 0x81C, 0x435C0003, + 0x81C, 0x425E0003, 0x81C, 0x41600003, 0x81C, 0x40620003, + 0x81C, 0x05640003, 0x81C, 0x04660003, 0x81C, 0x03680003, + 0x81C, 0x026A0003, 0x81C, 0x016C0003, 0x81C, 0x006E0003, + 0x81C, 0x00700003, 0x81C, 0x00720003, 0x81C, 0x00740003, + 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003, + 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xFD000003, + 0x81C, 0xFC020003, 0x81C, 0xFB040003, 0x81C, 0xFA060003, + 0x81C, 0xF9080003, 0x81C, 0xF80A0003, 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, 0x81C, 0xF5100003, 0x81C, 0xF4120003, + 0x81C, 0xF3140003, 0x81C, 0xF2160003, 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, 0x81C, 0xEF1C0003, 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, 0x81C, 0xEC220003, 0x81C, 0xEB240003, + 0x81C, 0xEA260003, 0x81C, 0xE9280003, 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, 0x81C, 0xE62E0003, 0x81C, 0xE5300003, + 0x81C, 0xC8320003, 0x81C, 0xC7340003, 0x81C, 0xC6360003, + 0x81C, 0xC5380003, 0x81C, 0xC43A0003, 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, 0x81C, 0xC1400003, 0x81C, 0xC0420003, + 0x81C, 0xA5440003, 0x81C, 0xA4460003, 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, 0x81C, 0xA14C0003, 0x81C, 0x834E0003, + 0x81C, 0x82500003, 0x81C, 0x81520003, 0x81C, 0x80540003, + 0x81C, 0x65560003, 0x81C, 0x64580003, 0x81C, 0x635A0003, + 0x81C, 0x625C0003, 0x81C, 0x435E0003, 0x81C, 0x42600003, + 0x81C, 0x41620003, 0x81C, 0x40640003, 0x81C, 0x06660003, + 0x81C, 0x05680003, 0x81C, 0x046A0003, 0x81C, 0x036C0003, + 0x81C, 0x026E0003, 0x81C, 0x01700003, 0x81C, 0x00720003, + 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003, + 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xFD000003, 0x81C, 0xFC020003, 0x81C, 0xFB040003, + 0x81C, 0xFA060003, 0x81C, 0xF9080003, 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, 0x81C, 0xF60E0003, 0x81C, 0xF5100003, + 0x81C, 0xF4120003, 0x81C, 0xF3140003, 0x81C, 0xF2160003, + 0x81C, 0xF1180003, 0x81C, 0xF01A0003, 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, 0x81C, 0xED200003, 0x81C, 0xEC220003, + 0x81C, 0xEB240003, 0x81C, 0xEA260003, 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, 0x81C, 0xE72C0003, 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, 0x81C, 0xC8320003, 0x81C, 0xC7340003, + 0x81C, 0xC6360003, 0x81C, 0xC5380003, 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, 0x81C, 0xC23E0003, 0x81C, 0xC1400003, + 0x81C, 0xC0420003, 0x81C, 0xA5440003, 0x81C, 0xA4460003, + 0x81C, 0xA3480003, 0x81C, 0xA24A0003, 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, 0x81C, 0x82500003, 0x81C, 0x81520003, + 0x81C, 0x80540003, 0x81C, 0x65560003, 0x81C, 0x64580003, + 0x81C, 0x635A0003, 0x81C, 0x625C0003, 0x81C, 0x435E0003, + 0x81C, 0x42600003, 0x81C, 0x41620003, 0x81C, 0x40640003, + 0x81C, 0x06660003, 0x81C, 0x05680003, 0x81C, 0x046A0003, + 0x81C, 0x036C0003, 0x81C, 0x026E0003, 0x81C, 0x01700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0xA0000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xFE000003, 0x81C, 0xFD020003, 0x81C, 0xFC040003, + 0x81C, 0xFB060003, 0x81C, 0xFA080003, 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, 0x81C, 0xF70E0003, 0x81C, 0xF6100003, + 0x81C, 0xF5120003, 0x81C, 0xF4140003, 0x81C, 0xF3160003, + 0x81C, 0xF2180003, 0x81C, 0xF11A0003, 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, 0x81C, 0xEE200003, 0x81C, 0xED220003, + 0x81C, 0xEC240003, 0x81C, 0xEB260003, 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, 0x81C, 0xE82C0003, 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, 0x81C, 0xE5320003, 0x81C, 0xC8340003, + 0x81C, 0xC7360003, 0x81C, 0xC6380003, 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, 0x81C, 0xC33E0003, 0x81C, 0xC2400003, + 0x81C, 0xC1420003, 0x81C, 0xC0440003, 0x81C, 0xA3460003, + 0x81C, 0xA2480003, 0x81C, 0xA14A0003, 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, 0x81C, 0x81500003, 0x81C, 0x80520003, + 0x81C, 0x64540003, 0x81C, 0x63560003, 0x81C, 0x62580003, + 0x81C, 0x445A0003, 0x81C, 0x435C0003, 0x81C, 0x425E0003, + 0x81C, 0x41600003, 0x81C, 0x40620003, 0x81C, 0x05640003, + 0x81C, 0x04660003, 0x81C, 0x03680003, 0x81C, 0x026A0003, + 0x81C, 0x016C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xE22C0103, + 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x64420103, 0x81C, 0x63440103, + 0x81C, 0x62460103, 0x81C, 0x61480103, 0x81C, 0x434A0103, + 0x81C, 0x424C0103, 0x81C, 0x414E0103, 0x81C, 0x40500103, + 0x81C, 0x22520103, 0x81C, 0x21540103, 0x81C, 0x20560103, + 0x81C, 0x04580103, 0x81C, 0x035A0103, 0x81C, 0x025C0103, + 0x81C, 0x015E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x81C, 0xFA000103, 0x81C, 0xF9020103, + 0x81C, 0xF8040103, 0x81C, 0xF7060103, 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, 0x81C, 0xF40C0103, 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, 0x81C, 0xF1120103, 0x81C, 0xF0140103, + 0x81C, 0xEF160103, 0x81C, 0xEE180103, 0x81C, 0xED1A0103, + 0x81C, 0xEC1C0103, 0x81C, 0xEB1E0103, 0x81C, 0xEA200103, + 0x81C, 0xE9220103, 0x81C, 0xE8240103, 0x81C, 0xE7260103, + 0x81C, 0xE6280103, 0x81C, 0xE52A0103, 0x81C, 0xC42C0103, + 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103, + 0x81C, 0xA4340103, 0x81C, 0xA3360103, 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, 0x81C, 0x833C0103, 0x81C, 0x823E0103, + 0x81C, 0x81400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103, + 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x06500103, + 0x81C, 0x05520103, 0x81C, 0x04540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103, + 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103, + 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, + 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103, + 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, 0x81C, 0xEE1E0103, 0x81C, 0xED200103, + 0x81C, 0xEC220103, 0x81C, 0xEB240103, 0x81C, 0xEA260103, + 0x81C, 0xE9280103, 0x81C, 0xE82A0103, 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, 0x81C, 0xE5300103, 0x81C, 0xE4320103, + 0x81C, 0xE3340103, 0x81C, 0xC6360103, 0x81C, 0xC5380103, + 0x81C, 0xC43A0103, 0x81C, 0xC33C0103, 0x81C, 0xC23E0103, + 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103, + 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0x834A0103, + 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x63500103, + 0x81C, 0x62520103, 0x81C, 0x61540103, 0x81C, 0x43560103, + 0x81C, 0x42580103, 0x81C, 0x245A0103, 0x81C, 0x235C0103, + 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x04620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xE22C0103, + 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x64420103, 0x81C, 0x63440103, + 0x81C, 0x62460103, 0x81C, 0x61480103, 0x81C, 0x434A0103, + 0x81C, 0x424C0103, 0x81C, 0x414E0103, 0x81C, 0x40500103, + 0x81C, 0x22520103, 0x81C, 0x21540103, 0x81C, 0x20560103, + 0x81C, 0x04580103, 0x81C, 0x035A0103, 0x81C, 0x025C0103, + 0x81C, 0x015E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90011000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, + 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103, + 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103, + 0x81C, 0xEE1C0103, 0x81C, 0xED1E0103, 0x81C, 0xEC200103, + 0x81C, 0xEB220103, 0x81C, 0xEA240103, 0x81C, 0xE9260103, + 0x81C, 0xE8280103, 0x81C, 0xE72A0103, 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, 0x81C, 0xE4300103, 0x81C, 0xE3320103, + 0x81C, 0xE2340103, 0x81C, 0xC5360103, 0x81C, 0xC4380103, + 0x81C, 0xC33A0103, 0x81C, 0xC23C0103, 0x81C, 0xA53E0103, + 0x81C, 0xA4400103, 0x81C, 0xA3420103, 0x81C, 0xA2440103, + 0x81C, 0xA1460103, 0x81C, 0x83480103, 0x81C, 0x824A0103, + 0x81C, 0x814C0103, 0x81C, 0x804E0103, 0x81C, 0x63500103, + 0x81C, 0x62520103, 0x81C, 0x61540103, 0x81C, 0x43560103, + 0x81C, 0x42580103, 0x81C, 0x415A0103, 0x81C, 0x405C0103, + 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x20620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, + 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103, + 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, 0x81C, 0xEE1E0103, 0x81C, 0xED200103, + 0x81C, 0xEC220103, 0x81C, 0xEB240103, 0x81C, 0xEA260103, + 0x81C, 0xE9280103, 0x81C, 0xE82A0103, 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, 0x81C, 0xE5300103, 0x81C, 0xE4320103, + 0x81C, 0xE3340103, 0x81C, 0xE2360103, 0x81C, 0xC5380103, + 0x81C, 0xC43A0103, 0x81C, 0xC33C0103, 0x81C, 0xC23E0103, + 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103, + 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0x834A0103, + 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x64500103, + 0x81C, 0x63520103, 0x81C, 0x62540103, 0x81C, 0x61560103, + 0x81C, 0x42580103, 0x81C, 0x415A0103, 0x81C, 0x405C0103, + 0x81C, 0x065E0103, 0x81C, 0x05600103, 0x81C, 0x04620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFE000103, 0x81C, 0xFD020103, + 0x81C, 0xFC040103, 0x81C, 0xFB060103, 0x81C, 0xFA080103, + 0x81C, 0xF90A0103, 0x81C, 0xF80C0103, 0x81C, 0xF70E0103, + 0x81C, 0xF6100103, 0x81C, 0xF5120103, 0x81C, 0xF4140103, + 0x81C, 0xF3160103, 0x81C, 0xF2180103, 0x81C, 0xF11A0103, + 0x81C, 0xF01C0103, 0x81C, 0xEF1E0103, 0x81C, 0xEE200103, + 0x81C, 0xED220103, 0x81C, 0xEC240103, 0x81C, 0xEB260103, + 0x81C, 0xEA280103, 0x81C, 0xE92A0103, 0x81C, 0xE82C0103, + 0x81C, 0xE72E0103, 0x81C, 0xE6300103, 0x81C, 0xE5320103, + 0x81C, 0xE4340103, 0x81C, 0xE3360103, 0x81C, 0xC6380103, + 0x81C, 0xC53A0103, 0x81C, 0xC43C0103, 0x81C, 0xC33E0103, + 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103, + 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x80500103, + 0x81C, 0x64520103, 0x81C, 0x63540103, 0x81C, 0x62560103, + 0x81C, 0x61580103, 0x81C, 0x605A0103, 0x81C, 0x235C0103, + 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x20620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0xA0000000, 0x00000000, + 0x81C, 0xFE000103, 0x81C, 0xFD020103, 0x81C, 0xFC040103, + 0x81C, 0xFB060103, 0x81C, 0xFA080103, 0x81C, 0xF90A0103, + 0x81C, 0xF80C0103, 0x81C, 0xF70E0103, 0x81C, 0xF6100103, + 0x81C, 0xF5120103, 0x81C, 0xF4140103, 0x81C, 0xF3160103, + 0x81C, 0xF2180103, 0x81C, 0xF11A0103, 0x81C, 0xF01C0103, + 0x81C, 0xEF1E0103, 0x81C, 0xEE200103, 0x81C, 0xED220103, + 0x81C, 0xEC240103, 0x81C, 0xEB260103, 0x81C, 0xEA280103, + 0x81C, 0xE92A0103, 0x81C, 0xE82C0103, 0x81C, 0xE72E0103, + 0x81C, 0xE6300103, 0x81C, 0xE5320103, 0x81C, 0xE4340103, + 0x81C, 0xE3360103, 0x81C, 0xC6380103, 0x81C, 0xC53A0103, + 0x81C, 0xC43C0103, 0x81C, 0xC33E0103, 0x81C, 0xA5400103, + 0x81C, 0xA4420103, 0x81C, 0xA3440103, 0x81C, 0xA2460103, + 0x81C, 0xA1480103, 0x81C, 0xA04A0103, 0x81C, 0x824C0103, + 0x81C, 0x814E0103, 0x81C, 0x80500103, 0x81C, 0x64520103, + 0x81C, 0x63540103, 0x81C, 0x62560103, 0x81C, 0x61580103, + 0x81C, 0x605A0103, 0x81C, 0x235C0103, 0x81C, 0x225E0103, + 0x81C, 0x21600103, 0x81C, 0x20620103, 0x81C, 0x03640103, + 0x81C, 0x02660103, 0x81C, 0x01680103, 0x81C, 0x006A0103, + 0x81C, 0x006C0103, 0x81C, 0x006E0103, 0x81C, 0x00700103, + 0x81C, 0x00720103, 0x81C, 0x00740103, 0x81C, 0x00760103, + 0x81C, 0x00780103, 0x81C, 0x007A0103, 0x81C, 0x007C0103, + 0x81C, 0x007E0103, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xF8000203, 0x81C, 0xF7020203, + 0x81C, 0xF6040203, 0x81C, 0xF5060203, 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, 0x81C, 0xF20C0203, 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, 0x81C, 0xEF120203, 0x81C, 0xEE140203, + 0x81C, 0xED160203, 0x81C, 0xEC180203, 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, 0x81C, 0xE91E0203, 0x81C, 0xE8200203, + 0x81C, 0xE7220203, 0x81C, 0xE6240203, 0x81C, 0xE5260203, + 0x81C, 0xE4280203, 0x81C, 0xE32A0203, 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, 0x81C, 0xC2300203, 0x81C, 0xC1320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x65420203, 0x81C, 0x64440203, + 0x81C, 0x63460203, 0x81C, 0x62480203, 0x81C, 0x614A0203, + 0x81C, 0x424C0203, 0x81C, 0x414E0203, 0x81C, 0x40500203, + 0x81C, 0x22520203, 0x81C, 0x21540203, 0x81C, 0x20560203, + 0x81C, 0x04580203, 0x81C, 0x035A0203, 0x81C, 0x025C0203, + 0x81C, 0x015E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x81C, 0xF9000203, 0x81C, 0xF8020203, + 0x81C, 0xF7040203, 0x81C, 0xF6060203, 0x81C, 0xF5080203, + 0x81C, 0xF40A0203, 0x81C, 0xF30C0203, 0x81C, 0xF20E0203, + 0x81C, 0xF1100203, 0x81C, 0xF0120203, 0x81C, 0xEF140203, + 0x81C, 0xEE160203, 0x81C, 0xED180203, 0x81C, 0xEC1A0203, + 0x81C, 0xEB1C0203, 0x81C, 0xEA1E0203, 0x81C, 0xE9200203, + 0x81C, 0xE8220203, 0x81C, 0xE7240203, 0x81C, 0xE6260203, + 0x81C, 0xE5280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203, + 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203, + 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203, + 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203, + 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203, + 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203, + 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x63420203, 0x81C, 0x62440203, + 0x81C, 0x61460203, 0x81C, 0x60480203, 0x81C, 0x424A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x06500203, + 0x81C, 0x05520203, 0x81C, 0x04540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203, + 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203, + 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203, + 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203, + 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203, + 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203, + 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203, + 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203, + 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203, + 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203, + 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203, + 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203, + 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000203, 0x81C, 0xFA020203, + 0x81C, 0xF9040203, 0x81C, 0xF8060203, 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, 0x81C, 0xF50C0203, 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, 0x81C, 0xF2120203, 0x81C, 0xF1140203, + 0x81C, 0xF0160203, 0x81C, 0xEF180203, 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, 0x81C, 0xEC1E0203, 0x81C, 0xEB200203, + 0x81C, 0xEA220203, 0x81C, 0xE9240203, 0x81C, 0xE8260203, + 0x81C, 0xE7280203, 0x81C, 0xE62A0203, 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, 0x81C, 0xE3300203, 0x81C, 0xE2320203, + 0x81C, 0xC6340203, 0x81C, 0xC5360203, 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, 0x81C, 0xC23C0203, 0x81C, 0xC13E0203, + 0x81C, 0xC0400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203, + 0x81C, 0xA1460203, 0x81C, 0xA0480203, 0x81C, 0x824A0203, + 0x81C, 0x814C0203, 0x81C, 0x804E0203, 0x81C, 0x63500203, + 0x81C, 0x62520203, 0x81C, 0x61540203, 0x81C, 0x60560203, + 0x81C, 0x24580203, 0x81C, 0x235A0203, 0x81C, 0x225C0203, + 0x81C, 0x215E0203, 0x81C, 0x20600203, 0x81C, 0x03620203, + 0x81C, 0x02640203, 0x81C, 0x01660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000203, 0x81C, 0xF7020203, + 0x81C, 0xF6040203, 0x81C, 0xF5060203, 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, 0x81C, 0xF20C0203, 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, 0x81C, 0xEF120203, 0x81C, 0xEE140203, + 0x81C, 0xED160203, 0x81C, 0xEC180203, 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, 0x81C, 0xE91E0203, 0x81C, 0xE8200203, + 0x81C, 0xE7220203, 0x81C, 0xE6240203, 0x81C, 0xE5260203, + 0x81C, 0xE4280203, 0x81C, 0xE32A0203, 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, 0x81C, 0xC2300203, 0x81C, 0xC1320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x65420203, 0x81C, 0x64440203, + 0x81C, 0x63460203, 0x81C, 0x62480203, 0x81C, 0x614A0203, + 0x81C, 0x424C0203, 0x81C, 0x414E0203, 0x81C, 0x40500203, + 0x81C, 0x22520203, 0x81C, 0x21540203, 0x81C, 0x20560203, + 0x81C, 0x04580203, 0x81C, 0x035A0203, 0x81C, 0x025C0203, + 0x81C, 0x015E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90011000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, + 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203, + 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, 0x81C, 0xEC1E0203, 0x81C, 0xEB200203, + 0x81C, 0xEA220203, 0x81C, 0xE9240203, 0x81C, 0xE8260203, + 0x81C, 0xE7280203, 0x81C, 0xE62A0203, 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, 0x81C, 0xE3300203, 0x81C, 0xE2320203, + 0x81C, 0xC6340203, 0x81C, 0xC5360203, 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, 0x81C, 0xA63C0203, 0x81C, 0xA53E0203, + 0x81C, 0xA4400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203, + 0x81C, 0xA1460203, 0x81C, 0x83480203, 0x81C, 0x824A0203, + 0x81C, 0x814C0203, 0x81C, 0x804E0203, 0x81C, 0x63500203, + 0x81C, 0x62520203, 0x81C, 0x61540203, 0x81C, 0x42560203, + 0x81C, 0x41580203, 0x81C, 0x405A0203, 0x81C, 0x225C0203, + 0x81C, 0x215E0203, 0x81C, 0x20600203, 0x81C, 0x04620203, + 0x81C, 0x03640203, 0x81C, 0x02660203, 0x81C, 0x01680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, + 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203, + 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, 0x81C, 0xED1E0203, 0x81C, 0xEC200203, + 0x81C, 0xEB220203, 0x81C, 0xEA240203, 0x81C, 0xE9260203, + 0x81C, 0xE8280203, 0x81C, 0xE72A0203, 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, 0x81C, 0xE4300203, 0x81C, 0xE3320203, + 0x81C, 0xE2340203, 0x81C, 0xE1360203, 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, 0x81C, 0xC33C0203, 0x81C, 0xC23E0203, + 0x81C, 0xC1400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203, + 0x81C, 0xA1460203, 0x81C, 0xA0480203, 0x81C, 0x834A0203, + 0x81C, 0x824C0203, 0x81C, 0x814E0203, 0x81C, 0x64500203, + 0x81C, 0x63520203, 0x81C, 0x62540203, 0x81C, 0x61560203, + 0x81C, 0x25580203, 0x81C, 0x245A0203, 0x81C, 0x235C0203, + 0x81C, 0x225E0203, 0x81C, 0x21600203, 0x81C, 0x04620203, + 0x81C, 0x03640203, 0x81C, 0x02660203, 0x81C, 0x01680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, + 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203, + 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, 0x81C, 0xED1E0203, 0x81C, 0xEC200203, + 0x81C, 0xEB220203, 0x81C, 0xEA240203, 0x81C, 0xE9260203, + 0x81C, 0xE8280203, 0x81C, 0xE72A0203, 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, 0x81C, 0xE4300203, 0x81C, 0xE3320203, + 0x81C, 0xE2340203, 0x81C, 0xC6360203, 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, 0x81C, 0xC33C0203, 0x81C, 0xA63E0203, + 0x81C, 0xA5400203, 0x81C, 0xA4420203, 0x81C, 0xA3440203, + 0x81C, 0xA2460203, 0x81C, 0xA1480203, 0x81C, 0x834A0203, + 0x81C, 0x824C0203, 0x81C, 0x814E0203, 0x81C, 0x64500203, + 0x81C, 0x63520203, 0x81C, 0x62540203, 0x81C, 0x61560203, + 0x81C, 0x60580203, 0x81C, 0x405A0203, 0x81C, 0x215C0203, + 0x81C, 0x205E0203, 0x81C, 0x03600203, 0x81C, 0x02620203, + 0x81C, 0x01640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0xA0000000, 0x00000000, + 0x81C, 0xFD000203, 0x81C, 0xFC020203, 0x81C, 0xFB040203, + 0x81C, 0xFA060203, 0x81C, 0xF9080203, 0x81C, 0xF80A0203, + 0x81C, 0xF70C0203, 0x81C, 0xF60E0203, 0x81C, 0xF5100203, + 0x81C, 0xF4120203, 0x81C, 0xF3140203, 0x81C, 0xF2160203, + 0x81C, 0xF1180203, 0x81C, 0xF01A0203, 0x81C, 0xEF1C0203, + 0x81C, 0xEE1E0203, 0x81C, 0xED200203, 0x81C, 0xEC220203, + 0x81C, 0xEB240203, 0x81C, 0xEA260203, 0x81C, 0xE9280203, + 0x81C, 0xE82A0203, 0x81C, 0xE72C0203, 0x81C, 0xE62E0203, + 0x81C, 0xE5300203, 0x81C, 0xE4320203, 0x81C, 0xE3340203, + 0x81C, 0xC6360203, 0x81C, 0xC5380203, 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, 0x81C, 0xA63E0203, 0x81C, 0xA5400203, + 0x81C, 0xA4420203, 0x81C, 0xA3440203, 0x81C, 0xA2460203, + 0x81C, 0xA1480203, 0x81C, 0x834A0203, 0x81C, 0x824C0203, + 0x81C, 0x814E0203, 0x81C, 0x64500203, 0x81C, 0x63520203, + 0x81C, 0x62540203, 0x81C, 0x61560203, 0x81C, 0x60580203, + 0x81C, 0x235A0203, 0x81C, 0x225C0203, 0x81C, 0x215E0203, + 0x81C, 0x20600203, 0x81C, 0x03620203, 0x81C, 0x02640203, + 0x81C, 0x01660203, 0x81C, 0x00680203, 0x81C, 0x006A0203, + 0x81C, 0x006C0203, 0x81C, 0x006E0203, 0x81C, 0x00700203, + 0x81C, 0x00720203, 0x81C, 0x00740203, 0x81C, 0x00760203, + 0x81C, 0x00780203, 0x81C, 0x007A0203, 0x81C, 0x007C0203, + 0x81C, 0x007E0203, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xF8000303, 0x81C, 0xF7020303, + 0x81C, 0xF6040303, 0x81C, 0xF5060303, 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, 0x81C, 0xF20C0303, 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, 0x81C, 0xEF120303, 0x81C, 0xEE140303, + 0x81C, 0xED160303, 0x81C, 0xEC180303, 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, 0x81C, 0xE91E0303, 0x81C, 0xCA200303, + 0x81C, 0xC9220303, 0x81C, 0xC8240303, 0x81C, 0xC7260303, + 0x81C, 0xC6280303, 0x81C, 0xC52A0303, 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, 0x81C, 0xC2300303, 0x81C, 0xC1320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x65420303, 0x81C, 0x64440303, + 0x81C, 0x63460303, 0x81C, 0x62480303, 0x81C, 0x614A0303, + 0x81C, 0x424C0303, 0x81C, 0x414E0303, 0x81C, 0x40500303, + 0x81C, 0x22520303, 0x81C, 0x21540303, 0x81C, 0x20560303, + 0x81C, 0x04580303, 0x81C, 0x035A0303, 0x81C, 0x025C0303, + 0x81C, 0x015E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x81C, 0xF9000303, 0x81C, 0xF8020303, + 0x81C, 0xF7040303, 0x81C, 0xF6060303, 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, 0x81C, 0xF30C0303, 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, 0x81C, 0xF0120303, 0x81C, 0xEF140303, + 0x81C, 0xEE160303, 0x81C, 0xED180303, 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, 0x81C, 0xEA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xC0320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303, + 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303, + 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303, + 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x06500303, + 0x81C, 0x05520303, 0x81C, 0x04540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303, + 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303, + 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303, + 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303, + 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303, + 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303, + 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303, + 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303, + 0x81C, 0xF0160303, 0x81C, 0xEF180303, 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, 0x81C, 0xEC1E0303, 0x81C, 0xEB200303, + 0x81C, 0xEA220303, 0x81C, 0xE9240303, 0x81C, 0xE8260303, + 0x81C, 0xE7280303, 0x81C, 0xE62A0303, 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, 0x81C, 0xE3300303, 0x81C, 0xE2320303, + 0x81C, 0xC6340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, 0x81C, 0xC23C0303, 0x81C, 0xC13E0303, + 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303, + 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303, + 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x63500303, + 0x81C, 0x62520303, 0x81C, 0x43540303, 0x81C, 0x42560303, + 0x81C, 0x41580303, 0x81C, 0x235A0303, 0x81C, 0x225C0303, + 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303, + 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000303, 0x81C, 0xF7020303, + 0x81C, 0xF6040303, 0x81C, 0xF5060303, 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, 0x81C, 0xF20C0303, 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, 0x81C, 0xEF120303, 0x81C, 0xEE140303, + 0x81C, 0xED160303, 0x81C, 0xEC180303, 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, 0x81C, 0xE91E0303, 0x81C, 0xCA200303, + 0x81C, 0xC9220303, 0x81C, 0xC8240303, 0x81C, 0xC7260303, + 0x81C, 0xC6280303, 0x81C, 0xC52A0303, 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, 0x81C, 0xC2300303, 0x81C, 0xC1320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x65420303, 0x81C, 0x64440303, + 0x81C, 0x63460303, 0x81C, 0x62480303, 0x81C, 0x614A0303, + 0x81C, 0x424C0303, 0x81C, 0x414E0303, 0x81C, 0x40500303, + 0x81C, 0x22520303, 0x81C, 0x21540303, 0x81C, 0x20560303, + 0x81C, 0x04580303, 0x81C, 0x035A0303, 0x81C, 0x025C0303, + 0x81C, 0x015E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90011000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303, + 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303, + 0x81C, 0xF0160303, 0x81C, 0xEE180303, 0x81C, 0xED1A0303, + 0x81C, 0xEC1C0303, 0x81C, 0xEB1E0303, 0x81C, 0xEA200303, + 0x81C, 0xE9220303, 0x81C, 0xE8240303, 0x81C, 0xE7260303, + 0x81C, 0xE6280303, 0x81C, 0xE52A0303, 0x81C, 0xE42C0303, + 0x81C, 0xE32E0303, 0x81C, 0xE2300303, 0x81C, 0xE1320303, + 0x81C, 0xC6340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, 0x81C, 0xA63C0303, 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303, + 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303, + 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x63500303, + 0x81C, 0x62520303, 0x81C, 0x61540303, 0x81C, 0x42560303, + 0x81C, 0x41580303, 0x81C, 0x405A0303, 0x81C, 0x225C0303, + 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303, + 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303, + 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303, + 0x81C, 0xF0160303, 0x81C, 0xEF180303, 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, 0x81C, 0xEC1E0303, 0x81C, 0xEB200303, + 0x81C, 0xEA220303, 0x81C, 0xE9240303, 0x81C, 0xE8260303, + 0x81C, 0xE7280303, 0x81C, 0xE62A0303, 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, 0x81C, 0xE3300303, 0x81C, 0xE2320303, + 0x81C, 0xE1340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, 0x81C, 0xC23C0303, 0x81C, 0xC13E0303, + 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303, + 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303, + 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x64500303, + 0x81C, 0x63520303, 0x81C, 0x62540303, 0x81C, 0x61560303, + 0x81C, 0x60580303, 0x81C, 0x235A0303, 0x81C, 0x225C0303, + 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303, + 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000303, 0x81C, 0xFB020303, + 0x81C, 0xFA040303, 0x81C, 0xF9060303, 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, 0x81C, 0xF60C0303, 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, 0x81C, 0xF3120303, 0x81C, 0xF2140303, + 0x81C, 0xF1160303, 0x81C, 0xF0180303, 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, 0x81C, 0xED1E0303, 0x81C, 0xEC200303, + 0x81C, 0xEB220303, 0x81C, 0xEA240303, 0x81C, 0xE9260303, + 0x81C, 0xE8280303, 0x81C, 0xE72A0303, 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, 0x81C, 0xE4300303, 0x81C, 0xE3320303, + 0x81C, 0xE2340303, 0x81C, 0xC6360303, 0x81C, 0xC5380303, + 0x81C, 0xC43A0303, 0x81C, 0xC33C0303, 0x81C, 0xA63E0303, + 0x81C, 0xA5400303, 0x81C, 0xA4420303, 0x81C, 0xA3440303, + 0x81C, 0xA2460303, 0x81C, 0x84480303, 0x81C, 0x834A0303, + 0x81C, 0x824C0303, 0x81C, 0x814E0303, 0x81C, 0x80500303, + 0x81C, 0x63520303, 0x81C, 0x62540303, 0x81C, 0x61560303, + 0x81C, 0x60580303, 0x81C, 0x225A0303, 0x81C, 0x055C0303, + 0x81C, 0x045E0303, 0x81C, 0x03600303, 0x81C, 0x02620303, + 0x81C, 0x01640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0xA0000000, 0x00000000, + 0x81C, 0xFC000303, 0x81C, 0xFB020303, 0x81C, 0xFA040303, + 0x81C, 0xF9060303, 0x81C, 0xF8080303, 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, 0x81C, 0xF50E0303, 0x81C, 0xF4100303, + 0x81C, 0xF3120303, 0x81C, 0xF2140303, 0x81C, 0xF1160303, + 0x81C, 0xF0180303, 0x81C, 0xEF1A0303, 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, 0x81C, 0xEC200303, 0x81C, 0xEB220303, + 0x81C, 0xEA240303, 0x81C, 0xE9260303, 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, 0x81C, 0xE62C0303, 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, 0x81C, 0xE3320303, 0x81C, 0xE2340303, + 0x81C, 0xC6360303, 0x81C, 0xC5380303, 0x81C, 0xC43A0303, + 0x81C, 0xC33C0303, 0x81C, 0xA63E0303, 0x81C, 0xA5400303, + 0x81C, 0xA4420303, 0x81C, 0xA3440303, 0x81C, 0xA2460303, + 0x81C, 0x84480303, 0x81C, 0x834A0303, 0x81C, 0x824C0303, + 0x81C, 0x814E0303, 0x81C, 0x80500303, 0x81C, 0x63520303, + 0x81C, 0x62540303, 0x81C, 0x61560303, 0x81C, 0x60580303, + 0x81C, 0x235A0303, 0x81C, 0x225C0303, 0x81C, 0x215E0303, + 0x81C, 0x20600303, 0x81C, 0x03620303, 0x81C, 0x02640303, + 0x81C, 0x01660303, 0x81C, 0x00680303, 0x81C, 0x006A0303, + 0x81C, 0x006C0303, 0x81C, 0x006E0303, 0x81C, 0x00700303, + 0x81C, 0x00720303, 0x81C, 0x00740303, 0x81C, 0x00760303, + 0x81C, 0x00780303, 0x81C, 0x007A0303, 0x81C, 0x007C0303, + 0x81C, 0x007E0303, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403, + 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403, + 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403, + 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403, + 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403, + 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403, + 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403, + 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403, + 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403, + 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403, + 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403, + 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403, + 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403, + 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403, + 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403, + 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x81C, 0xFF000403, + 0x81C, 0xF5000403, 0x81C, 0xF4020403, 0x81C, 0xF3040403, + 0x81C, 0xF2060403, 0x81C, 0xF1080403, 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, 0x81C, 0xEE0E0403, 0x81C, 0xED100403, + 0x81C, 0xEC120403, 0x81C, 0xEB140403, 0x81C, 0xEA160403, + 0x81C, 0xE9180403, 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, 0x81C, 0xE5200403, 0x81C, 0xE4220403, + 0x81C, 0xE3240403, 0x81C, 0xE2260403, 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, 0x81C, 0xC0320403, 0x81C, 0xA4340403, + 0x81C, 0xA3360403, 0x81C, 0xA2380403, 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, 0x81C, 0x823E0403, 0x81C, 0x81400403, + 0x81C, 0x80420403, 0x81C, 0x64440403, 0x81C, 0x63460403, + 0x81C, 0x62480403, 0x81C, 0x614A0403, 0x81C, 0x604C0403, + 0x81C, 0x454E0403, 0x81C, 0x44500403, 0x81C, 0x43520403, + 0x81C, 0x42540403, 0x81C, 0x41560403, 0x81C, 0x40580403, + 0x81C, 0x055A0403, 0x81C, 0x045C0403, 0x81C, 0x035E0403, + 0x81C, 0x02600403, 0x81C, 0x01620403, 0x81C, 0x00640403, + 0x81C, 0x00660403, 0x81C, 0x00680403, 0x81C, 0x006A0403, + 0x81C, 0x006C0403, 0x81C, 0x006E0403, 0x81C, 0x00700403, + 0x81C, 0x00720403, 0x81C, 0x00740403, 0x81C, 0x00760403, + 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403, + 0x81C, 0x007E0403, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, 0x81C, 0xF5000403, 0x81C, 0xF4020403, + 0x81C, 0xF3040403, 0x81C, 0xF2060403, 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, 0x81C, 0xEC120403, 0x81C, 0xEB140403, + 0x81C, 0xEA160403, 0x81C, 0xE9180403, 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, 0x81C, 0xE5200403, + 0x81C, 0xE4220403, 0x81C, 0xE3240403, 0x81C, 0xE2260403, + 0x81C, 0xE1280403, 0x81C, 0xE02A0403, 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, 0x81C, 0xC1300403, 0x81C, 0xC0320403, + 0x81C, 0xA4340403, 0x81C, 0xA3360403, 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, 0x81C, 0x823E0403, + 0x81C, 0x81400403, 0x81C, 0x80420403, 0x81C, 0x64440403, + 0x81C, 0x63460403, 0x81C, 0x62480403, 0x81C, 0x614A0403, + 0x81C, 0x604C0403, 0x81C, 0x454E0403, 0x81C, 0x44500403, + 0x81C, 0x43520403, 0x81C, 0x42540403, 0x81C, 0x41560403, + 0x81C, 0x40580403, 0x81C, 0x055A0403, 0x81C, 0x045C0403, + 0x81C, 0x035E0403, 0x81C, 0x02600403, 0x81C, 0x01620403, + 0x81C, 0x00640403, 0x81C, 0x00660403, 0x81C, 0x00680403, + 0x81C, 0x006A0403, 0x81C, 0x006C0403, 0x81C, 0x006E0403, + 0x81C, 0x00700403, 0x81C, 0x00720403, 0x81C, 0x00740403, + 0x81C, 0x00760403, 0x81C, 0x00780403, 0x81C, 0x007A0403, + 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403, + 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403, + 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403, + 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403, + 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403, + 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403, + 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403, + 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403, + 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403, + 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403, + 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403, + 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403, + 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403, + 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403, + 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403, + 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000403, + 0x81C, 0xFF000403, 0x81C, 0xFF020403, 0x81C, 0xFE040403, + 0x81C, 0xFD060403, 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, 0x81C, 0xF8100403, + 0x81C, 0xF7120403, 0x81C, 0xF6140403, 0x81C, 0xF5160403, + 0x81C, 0xF4180403, 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, 0x81C, 0xD4200403, 0x81C, 0xD3220403, + 0x81C, 0xD2240403, 0x81C, 0xB6260403, 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, 0x81C, 0xB0320403, 0x81C, 0xAF340403, + 0x81C, 0xAE360403, 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, + 0x81C, 0xA8420403, 0x81C, 0xA7440403, 0x81C, 0xA6460403, + 0x81C, 0xA5480403, 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, 0x81C, 0x84500403, 0x81C, 0x83520403, + 0x81C, 0x82540403, 0x81C, 0x81560403, 0x81C, 0x80580403, + 0x81C, 0x485A0403, 0x81C, 0x475C0403, 0x81C, 0x465E0403, + 0x81C, 0x45600403, 0x81C, 0x44620403, 0x81C, 0x0A640403, + 0x81C, 0x09660403, 0x81C, 0x08680403, 0x81C, 0x076A0403, + 0x81C, 0x066C0403, 0x81C, 0x056E0403, 0x81C, 0x04700403, + 0x81C, 0x03720403, 0x81C, 0x02740403, 0x81C, 0x01760403, + 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403, + 0x81C, 0x007E0403, 0x90012100, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, 0x81C, 0xFF000403, 0x81C, 0xFF020403, + 0x81C, 0xFE040403, 0x81C, 0xFD060403, 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, 0x81C, 0xF7120403, 0x81C, 0xF6140403, + 0x81C, 0xF5160403, 0x81C, 0xF4180403, 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, 0x81C, 0xD4200403, + 0x81C, 0xD3220403, 0x81C, 0xD2240403, 0x81C, 0xB6260403, + 0x81C, 0xB5280403, 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, 0x81C, 0xB1300403, 0x81C, 0xB0320403, + 0x81C, 0xAF340403, 0x81C, 0xAE360403, 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, 0x81C, 0xA8420403, 0x81C, 0xA7440403, + 0x81C, 0xA6460403, 0x81C, 0xA5480403, 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, 0x81C, 0x854E0403, 0x81C, 0x84500403, + 0x81C, 0x83520403, 0x81C, 0x82540403, 0x81C, 0x81560403, + 0x81C, 0x80580403, 0x81C, 0x485A0403, 0x81C, 0x475C0403, + 0x81C, 0x465E0403, 0x81C, 0x45600403, 0x81C, 0x44620403, + 0x81C, 0x0A640403, 0x81C, 0x09660403, 0x81C, 0x08680403, + 0x81C, 0x076A0403, 0x81C, 0x066C0403, 0x81C, 0x056E0403, + 0x81C, 0x04700403, 0x81C, 0x03720403, 0x81C, 0x02740403, + 0x81C, 0x01760403, 0x81C, 0x00780403, 0x81C, 0x007A0403, + 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403, + 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403, + 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403, + 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403, + 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403, + 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403, + 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403, + 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403, + 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403, + 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403, + 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403, + 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403, + 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403, + 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403, + 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403, + 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0x90011000, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000403, + 0x81C, 0xFF000403, 0x81C, 0xFF020403, 0x81C, 0xFE040403, + 0x81C, 0xFD060403, 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, 0x81C, 0xF8100403, + 0x81C, 0xF7120403, 0x81C, 0xF6140403, 0x81C, 0xF5160403, + 0x81C, 0xF4180403, 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, 0x81C, 0xD4200403, 0x81C, 0xD3220403, + 0x81C, 0xD2240403, 0x81C, 0xB6260403, 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, 0x81C, 0xB0320403, 0x81C, 0xAF340403, + 0x81C, 0xAE360403, 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, + 0x81C, 0xA8420403, 0x81C, 0xA7440403, 0x81C, 0xA6460403, + 0x81C, 0xA5480403, 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, 0x81C, 0x84500403, 0x81C, 0x83520403, + 0x81C, 0x82540403, 0x81C, 0x81560403, 0x81C, 0x80580403, + 0x81C, 0x485A0403, 0x81C, 0x475C0403, 0x81C, 0x465E0403, + 0x81C, 0x45600403, 0x81C, 0x44620403, 0x81C, 0x0A640403, + 0x81C, 0x09660403, 0x81C, 0x08680403, 0x81C, 0x076A0403, + 0x81C, 0x066C0403, 0x81C, 0x056E0403, 0x81C, 0x04700403, + 0x81C, 0x03720403, 0x81C, 0x02740403, 0x81C, 0x01760403, + 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403, + 0x81C, 0x007E0403, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, 0x81C, 0xFF000403, 0x81C, 0xFF020403, + 0x81C, 0xFE040403, 0x81C, 0xFD060403, 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, 0x81C, 0xF7120403, 0x81C, 0xF6140403, + 0x81C, 0xF5160403, 0x81C, 0xF4180403, 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, 0x81C, 0xD4200403, + 0x81C, 0xD3220403, 0x81C, 0xD2240403, 0x81C, 0xB6260403, + 0x81C, 0xB5280403, 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, 0x81C, 0xB1300403, 0x81C, 0xB0320403, + 0x81C, 0xAF340403, 0x81C, 0xAE360403, 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, 0x81C, 0xA8420403, 0x81C, 0xA7440403, + 0x81C, 0xA6460403, 0x81C, 0xA5480403, 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, 0x81C, 0x854E0403, 0x81C, 0x84500403, + 0x81C, 0x83520403, 0x81C, 0x82540403, 0x81C, 0x81560403, + 0x81C, 0x80580403, 0x81C, 0x485A0403, 0x81C, 0x475C0403, + 0x81C, 0x465E0403, 0x81C, 0x45600403, 0x81C, 0x44620403, + 0x81C, 0x0A640403, 0x81C, 0x09660403, 0x81C, 0x08680403, + 0x81C, 0x076A0403, 0x81C, 0x066C0403, 0x81C, 0x056E0403, + 0x81C, 0x04700403, 0x81C, 0x03720403, 0x81C, 0x02740403, + 0x81C, 0x01760403, 0x81C, 0x00780403, 0x81C, 0x007A0403, + 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xFF000403, + 0x81C, 0xFF020403, 0x81C, 0xFE040403, 0x81C, 0xFD060403, + 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, 0x81C, 0xF8100403, 0x81C, 0xF7120403, + 0x81C, 0xF6140403, 0x81C, 0xF5160403, 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, 0x81C, 0xD3220403, 0x81C, 0xD2240403, + 0x81C, 0xB6260403, 0x81C, 0xB5280403, 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, 0x81C, 0xB1300403, + 0x81C, 0xB0320403, 0x81C, 0xAF340403, 0x81C, 0xAE360403, + 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, 0x81C, 0xA8420403, + 0x81C, 0xA7440403, 0x81C, 0xA6460403, 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, 0x81C, 0x854E0403, + 0x81C, 0x84500403, 0x81C, 0x83520403, 0x81C, 0x82540403, + 0x81C, 0x81560403, 0x81C, 0x80580403, 0x81C, 0x485A0403, + 0x81C, 0x475C0403, 0x81C, 0x465E0403, 0x81C, 0x45600403, + 0x81C, 0x44620403, 0x81C, 0x0A640403, 0x81C, 0x09660403, + 0x81C, 0x08680403, 0x81C, 0x076A0403, 0x81C, 0x066C0403, + 0x81C, 0x056E0403, 0x81C, 0x04700403, 0x81C, 0x03720403, + 0x81C, 0x02740403, 0x81C, 0x01760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0xA0000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xFF000403, + 0x81C, 0xFF020403, 0x81C, 0xFE040403, 0x81C, 0xFD060403, + 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, 0x81C, 0xF8100403, 0x81C, 0xF7120403, + 0x81C, 0xF6140403, 0x81C, 0xF5160403, 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, 0x81C, 0xD3220403, 0x81C, 0xD2240403, + 0x81C, 0xB6260403, 0x81C, 0xB5280403, 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, 0x81C, 0xB1300403, + 0x81C, 0xB0320403, 0x81C, 0xAF340403, 0x81C, 0xAE360403, + 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, 0x81C, 0xA8420403, + 0x81C, 0xA7440403, 0x81C, 0xA6460403, 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, 0x81C, 0x854E0403, + 0x81C, 0x84500403, 0x81C, 0x83520403, 0x81C, 0x82540403, + 0x81C, 0x81560403, 0x81C, 0x80580403, 0x81C, 0x485A0403, + 0x81C, 0x475C0403, 0x81C, 0x465E0403, 0x81C, 0x45600403, + 0x81C, 0x44620403, 0x81C, 0x0A640403, 0x81C, 0x09660403, + 0x81C, 0x08680403, 0x81C, 0x076A0403, 0x81C, 0x066C0403, + 0x81C, 0x056E0403, 0x81C, 0x04700403, 0x81C, 0x03720403, + 0x81C, 0x02740403, 0x81C, 0x01760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0xB0000000, 0x00000000, 0xC50, 0x00000022, 0xC50, 0x00000020, + 0xE50, 0x00000022, 0xE50, 0x00000020, + +}; + +void odm_read_and_config_mp_8822b_agc_tab(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_agc_tab) / sizeof(u32); + u32 *array = array_mp_8822b_agc_tab; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_bb_agc_8822b(dm, v1, MASKDWORD, v2); + } + } +} + +u32 odm_get_version_mp_8822b_agc_tab(void) { return 67; } + +/****************************************************************************** + * phy_reg.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_phy_reg[] = { + 0x800, 0x9020D010, 0x804, 0x800181A0, 0x808, 0x0E028233, + 0x80C, 0x10000013, 0x810, 0x21101263, 0x814, 0x020C3D10, + 0x818, 0x84A10385, 0x81C, 0x1E1E081F, 0x820, 0x0001AAAA, + 0x824, 0x00030FE0, 0x828, 0x0000CCCC, 0x82C, 0x75CB7010, + 0x830, 0x79A0EA2A, 0x834, 0x072E6986, 0x838, 0x87766441, + 0x83C, 0x9194B2B6, 0x840, 0x171740E0, 0x844, 0x4D3D7CDB, + 0x848, 0x4AD0408B, 0x84C, 0x6AFBF7A5, 0x850, 0x28A74706, + 0x854, 0x0001520C, 0x858, 0x4060C000, 0x85C, 0x74010160, + 0x860, 0x68A7C321, 0x864, 0x79F27432, 0x868, 0x8CA7A314, + 0x86C, 0x778C2878, 0x870, 0x77777777, 0x874, 0x27612C2E, + 0x878, 0xC0003152, 0x87C, 0x5C8FC000, 0x880, 0x00000000, + 0x884, 0x00000000, 0x888, 0x00000000, 0x88C, 0x00000000, + 0x890, 0x00000000, 0x894, 0x00000000, 0x898, 0x00000000, + 0x89C, 0x00000000, 0x8A0, 0x00000013, 0x8A4, 0x7F7F7F7F, + 0x8A8, 0x2202033E, 0x8AC, 0xF00F000A, 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, 0x8B8, 0xEC0057F7, 0x8BC, 0xACB520A3, + 0x8C0, 0xFFE04020, 0x8C4, 0x47C00000, 0x8C8, 0x000251A5, + 0x8CC, 0x08108000, 0x8D0, 0x0000B800, 0x8D4, 0x860308A0, + 0x8D8, 0x21095612, 0x8DC, 0x00000000, 0x8E0, 0x32D16777, + 0x8E4, 0x4C098935, 0x8E8, 0xFFFFC42C, 0x8EC, 0x99999999, + 0x8F0, 0x00009999, 0x8F4, 0x00D80FA1, 0x8F8, 0x40000080, + 0x8FC, 0x00000130, 0x900, 0x00800000, 0x904, 0x00000000, + 0x908, 0x00000000, 0x90C, 0xD3000000, 0x910, 0x0000FC00, + 0x914, 0xC6380000, 0x918, 0x1C1028C0, 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, 0x924, 0x855A2500, 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFEB200, 0x930, 0xFFFFFFFE, 0x934, 0x001FFFFF, + 0x938, 0x00008480, 0x93C, 0xE41C0642, 0x940, 0x0E470430, + 0x944, 0x00000000, 0x948, 0xAC000000, 0x94C, 0x10000083, + 0x950, 0x32010080, 0x954, 0x84510080, 0x958, 0x00000001, + 0x95C, 0x04248000, 0x960, 0x00000000, 0x964, 0x00000000, + 0x968, 0x00000000, 0x96C, 0x00000000, 0x970, 0x00001FFF, + 0x974, 0x44000FFF, 0x978, 0x00000000, 0x97C, 0x00000000, + 0x980, 0x00000000, 0x984, 0x00000000, 0x988, 0x00000000, + 0x98C, 0x23440000, 0x990, 0x27100000, 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, 0x99C, 0xFFFFFFFF, 0x9A0, 0x000000FF, + 0x9A4, 0x80000088, 0x9A8, 0x0C2F0000, 0x9AC, 0x01560000, + 0x9B0, 0x70000000, 0x9B4, 0x00000000, 0x9B8, 0x00000000, + 0x9BC, 0x00000000, 0x9C0, 0x00000000, 0x9C4, 0x00000000, + 0x9C8, 0x00000000, 0x9CC, 0x00000000, 0x9D0, 0x00000000, + 0x9D4, 0x00000000, 0x9D8, 0x00000000, 0x9DC, 0x00000000, + 0x9E0, 0x00000000, 0x9E4, 0x02000402, 0x9E8, 0x000022D4, + 0x9EC, 0x00000000, 0x9F0, 0x00010080, 0x9F4, 0x00000000, + 0x9F8, 0x00000000, 0x9FC, 0xEFFFF7F7, 0xA00, 0x00D047C8, + 0xA04, 0x81FF800C, 0xA08, 0x8C838300, 0xA0C, 0x2E20100F, + 0xA10, 0x9500BB78, 0xA14, 0x1114D028, 0xA18, 0x00881117, + 0xA1C, 0x89140F00, 0xA20, 0x84880000, 0xA24, 0x384F6577, + 0xA28, 0x00001525, 0xA2C, 0x00920000, 0xA70, 0x101FFF00, + 0xA74, 0x00000148, 0xA78, 0x00000900, 0xA7C, 0x225B0606, + 0xA80, 0x218675B2, 0xA84, 0x80208C00, 0xA88, 0x040C0000, + 0xA8C, 0x12345678, 0xA90, 0xABCDEF00, 0xA94, 0x001B1B89, + 0xA98, 0x030A0000, 0xA9C, 0x00060000, 0xAA0, 0x00000000, + 0xAA4, 0x0004000F, 0xAA8, 0x00000200, 0xB00, 0xE1000440, + 0xB04, 0x00800000, 0xB08, 0xFF02030B, 0xB0C, 0x01EAA406, + 0xB10, 0x00030690, 0xB14, 0x006000FA, 0xB18, 0x00000002, + 0xB1C, 0x00000002, 0xB20, 0x4B00001F, 0xB24, 0x4E8E3E40, + 0xB28, 0x03020100, 0xB2C, 0x07060504, 0xB30, 0x0B0A0908, + 0xB34, 0x0F0E0D0C, 0xB38, 0x13121110, 0xB3C, 0x0000003A, + 0xB40, 0x00000000, 0xB44, 0x80000000, 0xB48, 0x3F0000FA, + 0xB4C, 0x88C80020, 0xB50, 0x00000000, 0xB54, 0x00004241, + 0xB58, 0xE0008208, 0xB5C, 0x41EFFFF9, 0xB60, 0x00000000, + 0xB64, 0x00200063, 0xB68, 0x0000003A, 0xB6C, 0x00000102, + 0xB70, 0x4E6D1870, 0xB74, 0x03020100, 0xB78, 0x07060504, + 0xB7C, 0x0B0A0908, 0xB80, 0x0F0E0D0C, 0xB84, 0x13121110, + 0xB88, 0x00000000, 0xB8C, 0x00000000, 0xC00, 0x00000007, + 0xC04, 0x00000020, 0xC08, 0x60403231, 0xC0C, 0x00012345, + 0xC10, 0x00000100, 0xC14, 0x01000000, 0xC18, 0x00000000, + 0xC1C, 0x40040053, 0xC20, 0x40020103, 0xC24, 0x00000000, + 0xC28, 0x00000000, 0xC2C, 0x00000000, 0xC30, 0x00000000, + 0xC34, 0x00000000, 0xC38, 0x00000000, 0xC3C, 0x00000000, + 0xC40, 0x00000000, 0xC44, 0x00000000, 0xC48, 0x00000000, + 0xC4C, 0x00000000, 0xC50, 0x00000020, 0xC54, 0x00000000, + 0xC58, 0xD8020402, 0xC5C, 0xDE000120, 0xC68, 0x5979993F, + 0xC6C, 0x0000122A, 0xC70, 0x99795979, 0xC74, 0x99795979, + 0xC78, 0x99799979, 0xC7C, 0x99791979, 0xC80, 0x19791979, + 0xC84, 0x19791979, 0xC88, 0x00000000, 0xC8C, 0x07000000, + 0xC94, 0x01000100, 0xC98, 0x201C8000, 0xC9C, 0x00000000, + 0xCA0, 0x0000A555, 0xCA4, 0x08040201, 0xCA8, 0x80402010, + 0xCAC, 0x00000000, 0xCB0, 0x77777777, 0xCB4, 0x00007777, + 0xCB8, 0x00000000, 0xCBC, 0x00000000, 0xCC0, 0x00000000, + 0xCC4, 0x00000000, 0xCC8, 0x00000000, 0xCCC, 0x00000000, + 0xCD0, 0x00000000, 0xCD4, 0x00000000, 0xCD8, 0x00000000, + 0xCDC, 0x00000000, 0xCE0, 0x00000000, 0xCE4, 0x00000000, + 0xCE8, 0x00000000, 0xCEC, 0x00000000, 0xE00, 0x00000007, + 0xE04, 0x00000020, 0xE08, 0x60403231, 0xE0C, 0x00012345, + 0xE10, 0x00000100, 0xE14, 0x01000000, 0xE18, 0x00000000, + 0xE1C, 0x40040053, 0xE20, 0x40020103, 0xE24, 0x00000000, + 0xE28, 0x00000000, 0xE2C, 0x00000000, 0xE30, 0x00000000, + 0xE34, 0x00000000, 0xE38, 0x00000000, 0xE3C, 0x00000000, + 0xE40, 0x00000000, 0xE44, 0x00000000, 0xE48, 0x00000000, + 0xE4C, 0x00000000, 0xE50, 0x00000020, 0xE54, 0x00000000, + 0xE58, 0xD8020402, 0xE5C, 0xDE000120, 0xE68, 0x5979993F, + 0xE6C, 0x0000122A, 0xE70, 0x99795979, 0xE74, 0x99795979, + 0xE78, 0x99799979, 0xE7C, 0x99791979, 0xE80, 0x19791979, + 0xE84, 0x19791979, 0xE88, 0x00000000, 0xE8C, 0x07000000, + 0xE94, 0x01000100, 0xE98, 0x201C8000, 0xE9C, 0x00000000, + 0xEA0, 0x0000A555, 0xEA4, 0x08040201, 0xEA8, 0x80402010, + 0xEAC, 0x00000000, 0xEB0, 0x77777777, 0xEB4, 0x00007777, + 0xEB8, 0x00000000, 0xEBC, 0x00000000, 0xEC0, 0x00000000, + 0xEC4, 0x00000000, 0xEC8, 0x00000000, 0xECC, 0x00000000, + 0xED0, 0x00000000, 0xED4, 0x00000000, 0xED8, 0x00000000, + 0xEDC, 0x00000000, 0xEE0, 0x00000000, 0xEE4, 0x00000000, + 0xEE8, 0x00000000, 0xEEC, 0x00000000, 0x1900, 0x00000000, + 0x1904, 0x00238000, 0x1908, 0x00000000, 0x190C, 0x00000000, + 0x1910, 0x00000000, 0x1914, 0x00000000, 0x1918, 0x00000000, + 0x191C, 0x00000000, 0x1920, 0x00000000, 0x1924, 0x00000000, + 0x1928, 0x00000000, 0x192C, 0x00000000, 0x1930, 0x00000000, + 0x1934, 0x00000000, 0x1938, 0x00000000, 0x193C, 0x00000000, + 0x1940, 0x00000000, 0x1944, 0x00000000, 0x1948, 0x00000000, + 0x194C, 0x00000000, 0x1950, 0x00000000, 0x1954, 0x00000000, + 0x1958, 0x00000000, 0x195C, 0x00000000, 0x1960, 0x00000000, + 0x1964, 0x00000000, 0x1968, 0x00000000, 0x196C, 0x00000000, + 0x1970, 0x00000000, 0x1974, 0x00000000, 0x1978, 0x00000000, + 0x197C, 0x00000000, 0x1980, 0x00000000, 0x1984, 0x03000000, + 0x1988, 0x21401E88, 0x198C, 0x00004000, 0x1990, 0x00000000, + 0x1994, 0x00000000, 0x1998, 0x00000053, 0x199C, 0x00000000, + 0x19A0, 0x00000000, 0x19A4, 0x00000000, 0x19A8, 0x00000000, + 0x19AC, 0x0E47E47F, 0x19B0, 0x00000000, 0x19B4, 0x0E47E47F, + 0x19B8, 0x00000000, 0x19BC, 0x00000000, 0x19C0, 0x00000000, + 0x19C4, 0x00000000, 0x19C8, 0x00000000, 0x19CC, 0x00000000, + 0x19D0, 0x00000000, 0x19D4, 0xAAAAAAAA, 0x19D8, 0x00000AAA, + 0x19DC, 0x133E0F37, 0x19E0, 0x00000000, 0x19E4, 0x00000000, + 0x19E8, 0x00000000, 0x19EC, 0x00000000, 0x19F0, 0x00000000, + 0x19F4, 0x00000000, 0x19F8, 0x01A00000, 0x19FC, 0x00000000, + 0x1C00, 0x00000100, 0x1C04, 0x01000000, 0x1C08, 0x00000100, + 0x1C0C, 0x01000000, 0x1C10, 0x00000100, 0x1C14, 0x01000000, + 0x1C18, 0x00000100, 0x1C1C, 0x01000000, 0x1C20, 0x00000100, + 0x1C24, 0x01000000, 0x1C28, 0x00000100, 0x1C2C, 0x01000000, + 0x1C30, 0x00000100, 0x1C34, 0x01000000, 0x1C38, 0x00000000, + 0x1C3C, 0x00000000, 0x1C40, 0x000C0100, 0x1C44, 0x000000F3, + 0x1C48, 0x1A8249A8, 0x1C4C, 0x1461C826, 0x1C50, 0x0001469E, + 0x1C54, 0x58D158D1, 0x1C58, 0x04490088, 0x1C5C, 0x04004400, + 0x1C60, 0x00000000, 0x1C64, 0x04004400, 0x1C68, 0x00000100, + 0x1C6C, 0x01000000, 0x1C70, 0x00000100, 0x1C74, 0x01000000, + 0x1C78, 0x00000000, 0x1C7C, 0x00000010, 0x1C80, 0x5FFF5FFF, + 0x1C84, 0x5FFF5FFF, 0x1C88, 0x5FFF5FFF, 0x1C8C, 0x5FFF5FFF, + 0x1C90, 0x5FFF5FFF, 0x1C94, 0x5FFF5FFF, 0x1C98, 0x5FFF5FFF, + 0x1C9C, 0x5FFF5FFF, 0x1CA0, 0x00000100, 0x1CA4, 0x01000000, + 0x1CA8, 0x00000100, 0x1CAC, 0x5FFF5FFF, 0x1CB0, 0x00000100, + 0x1CB4, 0x01000000, 0x1CB8, 0x00000000, 0x1CBC, 0x00000000, + 0x1CC0, 0x00000100, 0x1CC4, 0x01000000, 0x1CC8, 0x00000100, + 0x1CCC, 0x01000000, 0x1CD0, 0x00000100, 0x1CD4, 0x01000000, + 0x1CD8, 0x00000100, 0x1CDC, 0x01000000, 0x1CE0, 0x00000100, + 0x1CE4, 0x01000000, 0x1CE8, 0x00000100, 0x1CEC, 0x01000000, + 0x1CF0, 0x00000100, 0x1CF4, 0x01000000, 0x1CF8, 0x00000000, + 0x1CFC, 0x00000000, 0xC60, 0x70038040, 0xC60, 0x70038040, + 0xC60, 0x70146040, 0xC60, 0x70246040, 0xC60, 0x70346040, + 0xC60, 0x70446040, 0xC60, 0x70532040, 0xC60, 0x70646040, + 0xC60, 0x70738040, 0xC60, 0x70838040, 0xC60, 0x70938040, + 0xC60, 0x70A38040, 0xC60, 0x70B36040, 0xC60, 0x70C06040, + 0xC60, 0x70D06040, 0xC60, 0x70E76040, 0xC60, 0x70F06040, + 0xE60, 0x70038040, 0xE60, 0x70038040, 0xE60, 0x70146040, + 0xE60, 0x70246040, 0xE60, 0x70346040, 0xE60, 0x70446040, + 0xE60, 0x70532040, 0xE60, 0x70646040, 0xE60, 0x70738040, + 0xE60, 0x70838040, 0xE60, 0x70938040, 0xE60, 0x70A38040, + 0xE60, 0x70B36040, 0xE60, 0x70C06040, 0xE60, 0x70D06040, + 0xE60, 0x70E76040, 0xE60, 0x70F06040, 0xC64, 0x00800000, + 0xC64, 0x08800001, 0xC64, 0x00800002, 0xC64, 0x00800003, + 0xC64, 0x00800004, 0xC64, 0x00800005, 0xC64, 0x00800006, + 0xC64, 0x08800007, 0xC64, 0x00004000, 0xE64, 0x00800000, + 0xE64, 0x08800001, 0xE64, 0x00800002, 0xE64, 0x00800003, + 0xE64, 0x00800004, 0xE64, 0x00800005, 0xE64, 0x00800006, + 0xE64, 0x08800007, 0xE64, 0x00004000, 0x1B00, 0xF8000008, + 0x1B00, 0xF80A7008, 0x1B00, 0xF8015008, 0x1B00, 0xF8000008, + 0x1B04, 0xE24629D2, 0x1B08, 0x00000080, 0x1B0C, 0x00000000, + 0x1B10, 0x00010C00, 0x1B14, 0x00000000, 0x1B18, 0x00292903, + 0x1B1C, 0xA2193C32, 0x1B20, 0x01840008, 0x1B24, 0x01860008, + 0x1B28, 0x80060300, 0x1B2C, 0x00000003, 0x1B30, 0x20000000, + 0x1B34, 0x00000800, 0x1B3C, 0x20000000, 0x1BC0, 0x01000000, + 0x1BCC, 0x00000000, 0x1B00, 0xF800000A, 0x1B1C, 0xA2193C32, + 0x1B20, 0x01840008, 0x1B24, 0x01860008, 0x1B28, 0x80060300, + 0x1B2C, 0x00000003, 0x1B30, 0x20000000, 0x1B34, 0x00000800, + 0x1B3C, 0x20000000, 0x1BC0, 0x01000000, 0x1BCC, 0x00000000, + 0x1B00, 0xF8000000, 0x1B80, 0x00000007, 0x1B80, 0x090A0005, + 0x1B80, 0x090A0007, 0x1B80, 0x0FFE0015, 0x1B80, 0x0FFE0017, + 0x1B80, 0x00220025, 0x1B80, 0x00220027, 0x1B80, 0x00040035, + 0x1B80, 0x00040037, 0x1B80, 0x05C00045, 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, 0x1B80, 0x00070057, 0x1B80, 0x64000065, + 0x1B80, 0x64000067, 0x1B80, 0x00020075, 0x1B80, 0x00020077, + 0x1B80, 0x00080085, 0x1B80, 0x00080087, 0x1B80, 0x80000095, + 0x1B80, 0x80000097, 0x1B80, 0x090800A5, 0x1B80, 0x090800A7, + 0x1B80, 0x0F0200B5, 0x1B80, 0x0F0200B7, 0x1B80, 0x002200C5, + 0x1B80, 0x002200C7, 0x1B80, 0x000400D5, 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, 0x1B80, 0x05C000E7, 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, 0x1B80, 0x64020105, 0x1B80, 0x64020107, + 0x1B80, 0x00020115, 0x1B80, 0x00020117, 0x1B80, 0x00040125, + 0x1B80, 0x00040127, 0x1B80, 0x4A000135, 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, 0x1B80, 0x4B040147, 0x1B80, 0x85030155, + 0x1B80, 0x85030157, 0x1B80, 0x40090165, 0x1B80, 0x40090167, + 0x1B80, 0xE0210175, 0x1B80, 0xE0210177, 0x1B80, 0x4B050185, + 0x1B80, 0x4B050187, 0x1B80, 0x86030195, 0x1B80, 0x86030197, + 0x1B80, 0x400B01A5, 0x1B80, 0x400B01A7, 0x1B80, 0xE02101B5, + 0x1B80, 0xE02101B7, 0x1B80, 0x4B0001C5, 0x1B80, 0x4B0001C7, + 0x1B80, 0x000701D5, 0x1B80, 0x000701D7, 0x1B80, 0x4C0001E5, + 0x1B80, 0x4C0001E7, 0x1B80, 0x000401F5, 0x1B80, 0x000401F7, + 0x1B80, 0x30000205, 0x1B80, 0x30000207, 0x1B80, 0xFE000215, + 0x1B80, 0xFE000217, 0x1B80, 0xFF000225, 0x1B80, 0xFF000227, + 0x1B80, 0xE1750235, 0x1B80, 0xE1750237, 0x1B80, 0xF00D0245, + 0x1B80, 0xF00D0247, 0x1B80, 0xF10D0255, 0x1B80, 0xF10D0257, + 0x1B80, 0xF20D0265, 0x1B80, 0xF20D0267, 0x1B80, 0xF30D0275, + 0x1B80, 0xF30D0277, 0x1B80, 0xF40D0285, 0x1B80, 0xF40D0287, + 0x1B80, 0xF50D0295, 0x1B80, 0xF50D0297, 0x1B80, 0xF60D02A5, + 0x1B80, 0xF60D02A7, 0x1B80, 0xF70D02B5, 0x1B80, 0xF70D02B7, + 0x1B80, 0xF80D02C5, 0x1B80, 0xF80D02C7, 0x1B80, 0xF90D02D5, + 0x1B80, 0xF90D02D7, 0x1B80, 0xFA0D02E5, 0x1B80, 0xFA0D02E7, + 0x1B80, 0xFB0D02F5, 0x1B80, 0xFB0D02F7, 0x1B80, 0x00010305, + 0x1B80, 0x00010307, 0x1B80, 0x303D0315, 0x1B80, 0x303D0317, + 0x1B80, 0x30550325, 0x1B80, 0x30550327, 0x1B80, 0x30A00335, + 0x1B80, 0x30A00337, 0x1B80, 0x30A30345, 0x1B80, 0x30A30347, + 0x1B80, 0x30570355, 0x1B80, 0x30570357, 0x1B80, 0x30620365, + 0x1B80, 0x30620367, 0x1B80, 0x306D0375, 0x1B80, 0x306D0377, + 0x1B80, 0x30AD0385, 0x1B80, 0x30AD0387, 0x1B80, 0x30A70395, + 0x1B80, 0x30A70397, 0x1B80, 0x30BB03A5, 0x1B80, 0x30BB03A7, + 0x1B80, 0x30C603B5, 0x1B80, 0x30C603B7, 0x1B80, 0x30D103C5, + 0x1B80, 0x30D103C7, 0x1B80, 0xE11403D5, 0x1B80, 0xE11403D7, + 0x1B80, 0x4D0403E5, 0x1B80, 0x4D0403E7, 0x1B80, 0x208003F5, + 0x1B80, 0x208003F7, 0x1B80, 0x00000405, 0x1B80, 0x00000407, + 0x1B80, 0x4D000415, 0x1B80, 0x4D000417, 0x1B80, 0x55070425, + 0x1B80, 0x55070427, 0x1B80, 0xE10C0435, 0x1B80, 0xE10C0437, + 0x1B80, 0xE10C0445, 0x1B80, 0xE10C0447, 0x1B80, 0x4D040455, + 0x1B80, 0x4D040457, 0x1B80, 0x20880465, 0x1B80, 0x20880467, + 0x1B80, 0x02000475, 0x1B80, 0x02000477, 0x1B80, 0x4D000485, + 0x1B80, 0x4D000487, 0x1B80, 0x550F0495, 0x1B80, 0x550F0497, + 0x1B80, 0xE10C04A5, 0x1B80, 0xE10C04A7, 0x1B80, 0x4F0204B5, + 0x1B80, 0x4F0204B7, 0x1B80, 0x4E0004C5, 0x1B80, 0x4E0004C7, + 0x1B80, 0x530204D5, 0x1B80, 0x530204D7, 0x1B80, 0x520104E5, + 0x1B80, 0x520104E7, 0x1B80, 0xE11004F5, 0x1B80, 0xE11004F7, + 0x1B80, 0x4D080505, 0x1B80, 0x4D080507, 0x1B80, 0x57100515, + 0x1B80, 0x57100517, 0x1B80, 0x57000525, 0x1B80, 0x57000527, + 0x1B80, 0x4D000535, 0x1B80, 0x4D000537, 0x1B80, 0x00010545, + 0x1B80, 0x00010547, 0x1B80, 0xE1140555, 0x1B80, 0xE1140557, + 0x1B80, 0x00010565, 0x1B80, 0x00010567, 0x1B80, 0x30770575, + 0x1B80, 0x30770577, 0x1B80, 0x00230585, 0x1B80, 0x00230587, + 0x1B80, 0xE1680595, 0x1B80, 0xE1680597, 0x1B80, 0x000205A5, + 0x1B80, 0x000205A7, 0x1B80, 0x54E905B5, 0x1B80, 0x54E905B7, + 0x1B80, 0x0BA605C5, 0x1B80, 0x0BA605C7, 0x1B80, 0x002305D5, + 0x1B80, 0x002305D7, 0x1B80, 0xE16805E5, 0x1B80, 0xE16805E7, + 0x1B80, 0x000205F5, 0x1B80, 0x000205F7, 0x1B80, 0x4D300605, + 0x1B80, 0x4D300607, 0x1B80, 0x30900615, 0x1B80, 0x30900617, + 0x1B80, 0x30730625, 0x1B80, 0x30730627, 0x1B80, 0x00220635, + 0x1B80, 0x00220637, 0x1B80, 0xE1680645, 0x1B80, 0xE1680647, + 0x1B80, 0x00020655, 0x1B80, 0x00020657, 0x1B80, 0x54E80665, + 0x1B80, 0x54E80667, 0x1B80, 0x0BA60675, 0x1B80, 0x0BA60677, + 0x1B80, 0x00220685, 0x1B80, 0x00220687, 0x1B80, 0xE1680695, + 0x1B80, 0xE1680697, 0x1B80, 0x000206A5, 0x1B80, 0x000206A7, + 0x1B80, 0x4D3006B5, 0x1B80, 0x4D3006B7, 0x1B80, 0x309006C5, + 0x1B80, 0x309006C7, 0x1B80, 0x63F106D5, 0x1B80, 0x63F106D7, + 0x1B80, 0xE11406E5, 0x1B80, 0xE11406E7, 0x1B80, 0xE16806F5, + 0x1B80, 0xE16806F7, 0x1B80, 0x63F40705, 0x1B80, 0x63F40707, + 0x1B80, 0xE1140715, 0x1B80, 0xE1140717, 0x1B80, 0xE1680725, + 0x1B80, 0xE1680727, 0x1B80, 0x0BA80735, 0x1B80, 0x0BA80737, + 0x1B80, 0x63F80745, 0x1B80, 0x63F80747, 0x1B80, 0xE1140755, + 0x1B80, 0xE1140757, 0x1B80, 0xE1680765, 0x1B80, 0xE1680767, + 0x1B80, 0x0BA90775, 0x1B80, 0x0BA90777, 0x1B80, 0x63FC0785, + 0x1B80, 0x63FC0787, 0x1B80, 0xE1140795, 0x1B80, 0xE1140797, + 0x1B80, 0xE16807A5, 0x1B80, 0xE16807A7, 0x1B80, 0x63FF07B5, + 0x1B80, 0x63FF07B7, 0x1B80, 0xE11407C5, 0x1B80, 0xE11407C7, + 0x1B80, 0xE16807D5, 0x1B80, 0xE16807D7, 0x1B80, 0x630007E5, + 0x1B80, 0x630007E7, 0x1B80, 0xE11407F5, 0x1B80, 0xE11407F7, + 0x1B80, 0xE1680805, 0x1B80, 0xE1680807, 0x1B80, 0x63030815, + 0x1B80, 0x63030817, 0x1B80, 0xE1140825, 0x1B80, 0xE1140827, + 0x1B80, 0xE1680835, 0x1B80, 0xE1680837, 0x1B80, 0xF4D40845, + 0x1B80, 0xF4D40847, 0x1B80, 0x63070855, 0x1B80, 0x63070857, + 0x1B80, 0xE1140865, 0x1B80, 0xE1140867, 0x1B80, 0xE1680875, + 0x1B80, 0xE1680877, 0x1B80, 0xF5DB0885, 0x1B80, 0xF5DB0887, + 0x1B80, 0x630B0895, 0x1B80, 0x630B0897, 0x1B80, 0xE11408A5, + 0x1B80, 0xE11408A7, 0x1B80, 0xE16808B5, 0x1B80, 0xE16808B7, + 0x1B80, 0x630E08C5, 0x1B80, 0x630E08C7, 0x1B80, 0xE11408D5, + 0x1B80, 0xE11408D7, 0x1B80, 0xE16808E5, 0x1B80, 0xE16808E7, + 0x1B80, 0x4D3008F5, 0x1B80, 0x4D3008F7, 0x1B80, 0x55010905, + 0x1B80, 0x55010907, 0x1B80, 0x57040915, 0x1B80, 0x57040917, + 0x1B80, 0x57000925, 0x1B80, 0x57000927, 0x1B80, 0x96000935, + 0x1B80, 0x96000937, 0x1B80, 0x57080945, 0x1B80, 0x57080947, + 0x1B80, 0x57000955, 0x1B80, 0x57000957, 0x1B80, 0x95000965, + 0x1B80, 0x95000967, 0x1B80, 0x4D000975, 0x1B80, 0x4D000977, + 0x1B80, 0x6C070985, 0x1B80, 0x6C070987, 0x1B80, 0x7B200995, + 0x1B80, 0x7B200997, 0x1B80, 0x7A0009A5, 0x1B80, 0x7A0009A7, + 0x1B80, 0x790009B5, 0x1B80, 0x790009B7, 0x1B80, 0x7F2009C5, + 0x1B80, 0x7F2009C7, 0x1B80, 0x7E0009D5, 0x1B80, 0x7E0009D7, + 0x1B80, 0x7D0009E5, 0x1B80, 0x7D0009E7, 0x1B80, 0x000109F5, + 0x1B80, 0x000109F7, 0x1B80, 0x62850A05, 0x1B80, 0x62850A07, + 0x1B80, 0xE1140A15, 0x1B80, 0xE1140A17, 0x1B80, 0x00010A25, + 0x1B80, 0x00010A27, 0x1B80, 0x5C320A35, 0x1B80, 0x5C320A37, + 0x1B80, 0xE1640A45, 0x1B80, 0xE1640A47, 0x1B80, 0xE1420A55, + 0x1B80, 0xE1420A57, 0x1B80, 0x00010A65, 0x1B80, 0x00010A67, + 0x1B80, 0x5C320A75, 0x1B80, 0x5C320A77, 0x1B80, 0x63F40A85, + 0x1B80, 0x63F40A87, 0x1B80, 0x62850A95, 0x1B80, 0x62850A97, + 0x1B80, 0x0BB00AA5, 0x1B80, 0x0BB00AA7, 0x1B80, 0xE1140AB5, + 0x1B80, 0xE1140AB7, 0x1B80, 0xE1680AC5, 0x1B80, 0xE1680AC7, + 0x1B80, 0x5C320AD5, 0x1B80, 0x5C320AD7, 0x1B80, 0x63FC0AE5, + 0x1B80, 0x63FC0AE7, 0x1B80, 0x62850AF5, 0x1B80, 0x62850AF7, + 0x1B80, 0x0BB10B05, 0x1B80, 0x0BB10B07, 0x1B80, 0xE1140B15, + 0x1B80, 0xE1140B17, 0x1B80, 0xE1680B25, 0x1B80, 0xE1680B27, + 0x1B80, 0x63030B35, 0x1B80, 0x63030B37, 0x1B80, 0xE1140B45, + 0x1B80, 0xE1140B47, 0x1B80, 0xE1680B55, 0x1B80, 0xE1680B57, + 0x1B80, 0xF7040B65, 0x1B80, 0xF7040B67, 0x1B80, 0x630B0B75, + 0x1B80, 0x630B0B77, 0x1B80, 0xE1140B85, 0x1B80, 0xE1140B87, + 0x1B80, 0xE1680B95, 0x1B80, 0xE1680B97, 0x1B80, 0x00010BA5, + 0x1B80, 0x00010BA7, 0x1B80, 0x30DF0BB5, 0x1B80, 0x30DF0BB7, + 0x1B80, 0x00230BC5, 0x1B80, 0x00230BC7, 0x1B80, 0xE16D0BD5, + 0x1B80, 0xE16D0BD7, 0x1B80, 0x00020BE5, 0x1B80, 0x00020BE7, + 0x1B80, 0x54E90BF5, 0x1B80, 0x54E90BF7, 0x1B80, 0x0BA60C05, + 0x1B80, 0x0BA60C07, 0x1B80, 0x00230C15, 0x1B80, 0x00230C17, + 0x1B80, 0xE16D0C25, 0x1B80, 0xE16D0C27, 0x1B80, 0x00020C35, + 0x1B80, 0x00020C37, 0x1B80, 0x4D100C45, 0x1B80, 0x4D100C47, + 0x1B80, 0x30900C55, 0x1B80, 0x30900C57, 0x1B80, 0x30D90C65, + 0x1B80, 0x30D90C67, 0x1B80, 0x00220C75, 0x1B80, 0x00220C77, + 0x1B80, 0xE16D0C85, 0x1B80, 0xE16D0C87, 0x1B80, 0x00020C95, + 0x1B80, 0x00020C97, 0x1B80, 0x54E80CA5, 0x1B80, 0x54E80CA7, + 0x1B80, 0x0BA60CB5, 0x1B80, 0x0BA60CB7, 0x1B80, 0x00220CC5, + 0x1B80, 0x00220CC7, 0x1B80, 0xE16D0CD5, 0x1B80, 0xE16D0CD7, + 0x1B80, 0x00020CE5, 0x1B80, 0x00020CE7, 0x1B80, 0x4D100CF5, + 0x1B80, 0x4D100CF7, 0x1B80, 0x30900D05, 0x1B80, 0x30900D07, + 0x1B80, 0x5C320D15, 0x1B80, 0x5C320D17, 0x1B80, 0x54F00D25, + 0x1B80, 0x54F00D27, 0x1B80, 0x67F10D35, 0x1B80, 0x67F10D37, + 0x1B80, 0xE1420D45, 0x1B80, 0xE1420D47, 0x1B80, 0xE16D0D55, + 0x1B80, 0xE16D0D57, 0x1B80, 0x67F40D65, 0x1B80, 0x67F40D67, + 0x1B80, 0xE1420D75, 0x1B80, 0xE1420D77, 0x1B80, 0xE16D0D85, + 0x1B80, 0xE16D0D87, 0x1B80, 0x5C320D95, 0x1B80, 0x5C320D97, + 0x1B80, 0x54F10DA5, 0x1B80, 0x54F10DA7, 0x1B80, 0x0BA80DB5, + 0x1B80, 0x0BA80DB7, 0x1B80, 0x67F80DC5, 0x1B80, 0x67F80DC7, + 0x1B80, 0xE1420DD5, 0x1B80, 0xE1420DD7, 0x1B80, 0xE16D0DE5, + 0x1B80, 0xE16D0DE7, 0x1B80, 0x5C320DF5, 0x1B80, 0x5C320DF7, + 0x1B80, 0x54F10E05, 0x1B80, 0x54F10E07, 0x1B80, 0x0BA90E15, + 0x1B80, 0x0BA90E17, 0x1B80, 0x67FC0E25, 0x1B80, 0x67FC0E27, + 0x1B80, 0xE1420E35, 0x1B80, 0xE1420E37, 0x1B80, 0xE16D0E45, + 0x1B80, 0xE16D0E47, 0x1B80, 0x67FF0E55, 0x1B80, 0x67FF0E57, + 0x1B80, 0xE1420E65, 0x1B80, 0xE1420E67, 0x1B80, 0xE16D0E75, + 0x1B80, 0xE16D0E77, 0x1B80, 0x5C320E85, 0x1B80, 0x5C320E87, + 0x1B80, 0x54F20E95, 0x1B80, 0x54F20E97, 0x1B80, 0x67000EA5, + 0x1B80, 0x67000EA7, 0x1B80, 0xE1420EB5, 0x1B80, 0xE1420EB7, + 0x1B80, 0xE16D0EC5, 0x1B80, 0xE16D0EC7, 0x1B80, 0x67030ED5, + 0x1B80, 0x67030ED7, 0x1B80, 0xE1420EE5, 0x1B80, 0xE1420EE7, + 0x1B80, 0xE16D0EF5, 0x1B80, 0xE16D0EF7, 0x1B80, 0xF9CC0F05, + 0x1B80, 0xF9CC0F07, 0x1B80, 0x67070F15, 0x1B80, 0x67070F17, + 0x1B80, 0xE1420F25, 0x1B80, 0xE1420F27, 0x1B80, 0xE16D0F35, + 0x1B80, 0xE16D0F37, 0x1B80, 0xFAD30F45, 0x1B80, 0xFAD30F47, + 0x1B80, 0x5C320F55, 0x1B80, 0x5C320F57, 0x1B80, 0x54F30F65, + 0x1B80, 0x54F30F67, 0x1B80, 0x670B0F75, 0x1B80, 0x670B0F77, + 0x1B80, 0xE1420F85, 0x1B80, 0xE1420F87, 0x1B80, 0xE16D0F95, + 0x1B80, 0xE16D0F97, 0x1B80, 0x670E0FA5, 0x1B80, 0x670E0FA7, + 0x1B80, 0xE1420FB5, 0x1B80, 0xE1420FB7, 0x1B80, 0xE16D0FC5, + 0x1B80, 0xE16D0FC7, 0x1B80, 0x4D100FD5, 0x1B80, 0x4D100FD7, + 0x1B80, 0x30900FE5, 0x1B80, 0x30900FE7, 0x1B80, 0x00010FF5, + 0x1B80, 0x00010FF7, 0x1B80, 0x7B241005, 0x1B80, 0x7B241007, + 0x1B80, 0x7A401015, 0x1B80, 0x7A401017, 0x1B80, 0x79001025, + 0x1B80, 0x79001027, 0x1B80, 0x55031035, 0x1B80, 0x55031037, + 0x1B80, 0x310C1045, 0x1B80, 0x310C1047, 0x1B80, 0x7B1C1055, + 0x1B80, 0x7B1C1057, 0x1B80, 0x7A401065, 0x1B80, 0x7A401067, + 0x1B80, 0x550B1075, 0x1B80, 0x550B1077, 0x1B80, 0x310C1085, + 0x1B80, 0x310C1087, 0x1B80, 0x7B201095, 0x1B80, 0x7B201097, + 0x1B80, 0x7A0010A5, 0x1B80, 0x7A0010A7, 0x1B80, 0x551310B5, + 0x1B80, 0x551310B7, 0x1B80, 0x740110C5, 0x1B80, 0x740110C7, + 0x1B80, 0x740010D5, 0x1B80, 0x740010D7, 0x1B80, 0x8E0010E5, + 0x1B80, 0x8E0010E7, 0x1B80, 0x000110F5, 0x1B80, 0x000110F7, + 0x1B80, 0x57021105, 0x1B80, 0x57021107, 0x1B80, 0x57001115, + 0x1B80, 0x57001117, 0x1B80, 0x97001125, 0x1B80, 0x97001127, + 0x1B80, 0x00011135, 0x1B80, 0x00011137, 0x1B80, 0x4F781145, + 0x1B80, 0x4F781147, 0x1B80, 0x53881155, 0x1B80, 0x53881157, + 0x1B80, 0xE1221165, 0x1B80, 0xE1221167, 0x1B80, 0x54801175, + 0x1B80, 0x54801177, 0x1B80, 0x54001185, 0x1B80, 0x54001187, + 0x1B80, 0xE1221195, 0x1B80, 0xE1221197, 0x1B80, 0x548111A5, + 0x1B80, 0x548111A7, 0x1B80, 0x540011B5, 0x1B80, 0x540011B7, + 0x1B80, 0xE12211C5, 0x1B80, 0xE12211C7, 0x1B80, 0x548211D5, + 0x1B80, 0x548211D7, 0x1B80, 0x540011E5, 0x1B80, 0x540011E7, + 0x1B80, 0xE12D11F5, 0x1B80, 0xE12D11F7, 0x1B80, 0xBF1D1205, + 0x1B80, 0xBF1D1207, 0x1B80, 0x301D1215, 0x1B80, 0x301D1217, + 0x1B80, 0xE1001225, 0x1B80, 0xE1001227, 0x1B80, 0xE1051235, + 0x1B80, 0xE1051237, 0x1B80, 0xE1091245, 0x1B80, 0xE1091247, + 0x1B80, 0xE1101255, 0x1B80, 0xE1101257, 0x1B80, 0xE1641265, + 0x1B80, 0xE1641267, 0x1B80, 0x55131275, 0x1B80, 0x55131277, + 0x1B80, 0xE10C1285, 0x1B80, 0xE10C1287, 0x1B80, 0x55151295, + 0x1B80, 0x55151297, 0x1B80, 0xE11012A5, 0x1B80, 0xE11012A7, + 0x1B80, 0xE16412B5, 0x1B80, 0xE16412B7, 0x1B80, 0x000112C5, + 0x1B80, 0x000112C7, 0x1B80, 0x54BF12D5, 0x1B80, 0x54BF12D7, + 0x1B80, 0x54C012E5, 0x1B80, 0x54C012E7, 0x1B80, 0x54A312F5, + 0x1B80, 0x54A312F7, 0x1B80, 0x54C11305, 0x1B80, 0x54C11307, + 0x1B80, 0x54A41315, 0x1B80, 0x54A41317, 0x1B80, 0x4C181325, + 0x1B80, 0x4C181327, 0x1B80, 0xBF071335, 0x1B80, 0xBF071337, + 0x1B80, 0x54C21345, 0x1B80, 0x54C21347, 0x1B80, 0x54A41355, + 0x1B80, 0x54A41357, 0x1B80, 0xBF041365, 0x1B80, 0xBF041367, + 0x1B80, 0x54C11375, 0x1B80, 0x54C11377, 0x1B80, 0x54A31385, + 0x1B80, 0x54A31387, 0x1B80, 0xBF011395, 0x1B80, 0xBF011397, + 0x1B80, 0xE17213A5, 0x1B80, 0xE17213A7, 0x1B80, 0x54DF13B5, + 0x1B80, 0x54DF13B7, 0x1B80, 0x000113C5, 0x1B80, 0x000113C7, + 0x1B80, 0x54BF13D5, 0x1B80, 0x54BF13D7, 0x1B80, 0x54E513E5, + 0x1B80, 0x54E513E7, 0x1B80, 0x050A13F5, 0x1B80, 0x050A13F7, + 0x1B80, 0x54DF1405, 0x1B80, 0x54DF1407, 0x1B80, 0x00011415, + 0x1B80, 0x00011417, 0x1B80, 0x7F201425, 0x1B80, 0x7F201427, + 0x1B80, 0x7E001435, 0x1B80, 0x7E001437, 0x1B80, 0x7D001445, + 0x1B80, 0x7D001447, 0x1B80, 0x55011455, 0x1B80, 0x55011457, + 0x1B80, 0x5C311465, 0x1B80, 0x5C311467, 0x1B80, 0xE10C1475, + 0x1B80, 0xE10C1477, 0x1B80, 0xE1101485, 0x1B80, 0xE1101487, + 0x1B80, 0x54801495, 0x1B80, 0x54801497, 0x1B80, 0x540014A5, + 0x1B80, 0x540014A7, 0x1B80, 0xE10C14B5, 0x1B80, 0xE10C14B7, + 0x1B80, 0xE11014C5, 0x1B80, 0xE11014C7, 0x1B80, 0x548114D5, + 0x1B80, 0x548114D7, 0x1B80, 0x540014E5, 0x1B80, 0x540014E7, + 0x1B80, 0xE10C14F5, 0x1B80, 0xE10C14F7, 0x1B80, 0xE1101505, + 0x1B80, 0xE1101507, 0x1B80, 0x54821515, 0x1B80, 0x54821517, + 0x1B80, 0x54001525, 0x1B80, 0x54001527, 0x1B80, 0xE12D1535, + 0x1B80, 0xE12D1537, 0x1B80, 0xBFE91545, 0x1B80, 0xBFE91547, + 0x1B80, 0x301D1555, 0x1B80, 0x301D1557, 0x1B80, 0x00231565, + 0x1B80, 0x00231567, 0x1B80, 0x7B201575, 0x1B80, 0x7B201577, + 0x1B80, 0x7A001585, 0x1B80, 0x7A001587, 0x1B80, 0x79001595, + 0x1B80, 0x79001597, 0x1B80, 0xE16815A5, 0x1B80, 0xE16815A7, + 0x1B80, 0x000215B5, 0x1B80, 0x000215B7, 0x1B80, 0x000115C5, + 0x1B80, 0x000115C7, 0x1B80, 0x002215D5, 0x1B80, 0x002215D7, + 0x1B80, 0x7B2015E5, 0x1B80, 0x7B2015E7, 0x1B80, 0x7A0015F5, + 0x1B80, 0x7A0015F7, 0x1B80, 0x79001605, 0x1B80, 0x79001607, + 0x1B80, 0xE1681615, 0x1B80, 0xE1681617, 0x1B80, 0x00021625, + 0x1B80, 0x00021627, 0x1B80, 0x00011635, 0x1B80, 0x00011637, + 0x1B80, 0x549F1645, 0x1B80, 0x549F1647, 0x1B80, 0x54FF1655, + 0x1B80, 0x54FF1657, 0x1B80, 0x54001665, 0x1B80, 0x54001667, + 0x1B80, 0x00011675, 0x1B80, 0x00011677, 0x1B80, 0x5C311685, + 0x1B80, 0x5C311687, 0x1B80, 0x07141695, 0x1B80, 0x07141697, + 0x1B80, 0x540016A5, 0x1B80, 0x540016A7, 0x1B80, 0x5C3216B5, + 0x1B80, 0x5C3216B7, 0x1B80, 0x000116C5, 0x1B80, 0x000116C7, + 0x1B80, 0x5C3216D5, 0x1B80, 0x5C3216D7, 0x1B80, 0x071416E5, + 0x1B80, 0x071416E7, 0x1B80, 0x540016F5, 0x1B80, 0x540016F7, + 0x1B80, 0x5C311705, 0x1B80, 0x5C311707, 0x1B80, 0x00011715, + 0x1B80, 0x00011717, 0x1B80, 0x4C981725, 0x1B80, 0x4C981727, + 0x1B80, 0x4C181735, 0x1B80, 0x4C181737, 0x1B80, 0x00011745, + 0x1B80, 0x00011747, 0x1B80, 0x5C321755, 0x1B80, 0x5C321757, + 0x1B80, 0x62841765, 0x1B80, 0x62841767, 0x1B80, 0x66861775, + 0x1B80, 0x66861777, 0x1B80, 0x6C031785, 0x1B80, 0x6C031787, + 0x1B80, 0x7B201795, 0x1B80, 0x7B201797, 0x1B80, 0x7A0017A5, + 0x1B80, 0x7A0017A7, 0x1B80, 0x790017B5, 0x1B80, 0x790017B7, + 0x1B80, 0x7F2017C5, 0x1B80, 0x7F2017C7, 0x1B80, 0x7E0017D5, + 0x1B80, 0x7E0017D7, 0x1B80, 0x7D0017E5, 0x1B80, 0x7D0017E7, + 0x1B80, 0x090117F5, 0x1B80, 0x090117F7, 0x1B80, 0x0C011805, + 0x1B80, 0x0C011807, 0x1B80, 0x0BA61815, 0x1B80, 0x0BA61817, + 0x1B80, 0x00011825, 0x1B80, 0x00011827, 0x1B80, 0x00000006, + 0x1B80, 0x00000002, + +}; + +void odm_read_and_config_mp_8822b_phy_reg(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_phy_reg) / sizeof(u32); + u32 *array = array_mp_8822b_phy_reg; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_bb_phy_8822b(dm, v1, MASKDWORD, v2); + } + } +} + +u32 odm_get_version_mp_8822b_phy_reg(void) { return 67; } + +/****************************************************************************** + * phy_reg_pg.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_phy_reg_pg[] = { + 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, + 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, + 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, + 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, + 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, + 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, + 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, + 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, + 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, + 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, + 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, + 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, + 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, + 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, + 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, + 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, + 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, + 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, + 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, + 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, + 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, + 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, + 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, + 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, + 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, + 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, + 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, + 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, + 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, + 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, + 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, + 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, + 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, + 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, + 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, + 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, + 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, + 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, + 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, + 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, + 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, + 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, + 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, + 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, + 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, + 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, +}; + +void odm_read_and_config_mp_8822b_phy_reg_pg(struct phy_dm_struct *dm) +{ + u32 i = 0; + u32 array_len = sizeof(array_mp_8822b_phy_reg_pg) / sizeof(u32); + u32 *array = array_mp_8822b_phy_reg_pg; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + dm->phy_reg_pg_version = 1; + dm->phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE; + + for (i = 0; i < array_len; i += 6) { + u32 v1 = array[i]; + u32 v2 = array[i + 1]; + u32 v3 = array[i + 2]; + u32 v4 = array[i + 3]; + u32 v5 = array[i + 4]; + u32 v6 = array[i + 5]; + + odm_config_bb_phy_reg_pg_8822b(dm, v1, v2, v3, v4, v5, v6); + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h new file mode 100644 index 0000000000000000000000000000000000000000..53431998b47e78c06649e62b9c8fa48a95140f4d --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#ifndef __INC_MP_BB_HW_IMG_8822B_H +#define __INC_MP_BB_HW_IMG_8822B_H + +/****************************************************************************** + * agc_tab.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_agc_tab(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_agc_tab(void); + +/****************************************************************************** + * phy_reg.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_phy_reg(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_phy_reg(void); + +/****************************************************************************** + * phy_reg_pg.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_phy_reg_pg(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_phy_reg_pg(void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c new file mode 100644 index 0000000000000000000000000000000000000000..1a9daed2e6092824d2f4c93589096c3cb7406c9a --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c @@ -0,0 +1,222 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool check_positive(struct phy_dm_struct *dm, const u32 condition1, + const u32 condition2, const u32 condition3, + const u32 condition4) +{ + u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/ + ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/ + ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/ + ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/ + + u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, + cond4 = condition4; + + u8 cut_version_for_para = + (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version; + u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type; + + u32 driver1 = cut_version_for_para << 24 | + (dm->support_interface & 0xF0) << 16 | + dm->support_platform << 16 | pkg_type_for_para << 12 | + (dm->support_interface & 0x0F) << 8 | _board_type; + + u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 | + (dm->type_alna & 0xFF) << 16 | + (dm->type_apa & 0xFF) << 24; + + u32 driver3 = 0; + + u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) | + (dm->type_alna & 0xFF00) << 8 | + (dm->type_apa & 0xFF00) << 16; + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, cond1, cond2, cond3, cond4); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, driver1, driver2, driver3, driver4); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Platform, Interface) = (0x%X, 0x%X)\n", + dm->support_platform, dm->support_interface); + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Board, Package) = (0x%X, 0x%X)\n", + dm->board_type, dm->package_type); + + /*============== value Defined Check ===============*/ + /*QFN type [15:12] and cut version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && + ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && + ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 bit_mask = 0; + + if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + bit_mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + bit_mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + bit_mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + bit_mask |= 0xFF000000; + + if (((cond2 & bit_mask) == (driver2 & bit_mask)) && + ((cond4 & bit_mask) == + (driver4 & + bit_mask))) /* board_type of each RF path is matched*/ + return true; + else + return false; + } else { + return false; + } +} + +/****************************************************************************** + * mac_reg.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_mac_reg[] = { + 0x029, 0x000000F9, 0x420, 0x00000080, 0x421, 0x0000000F, + 0x428, 0x0000000A, 0x429, 0x00000010, 0x430, 0x00000000, + 0x431, 0x00000000, 0x432, 0x00000000, 0x433, 0x00000001, + 0x434, 0x00000004, 0x435, 0x00000005, 0x436, 0x00000007, + 0x437, 0x00000008, 0x43C, 0x00000004, 0x43D, 0x00000005, + 0x43E, 0x00000007, 0x43F, 0x00000008, 0x440, 0x0000005D, + 0x441, 0x00000001, 0x442, 0x00000000, 0x444, 0x00000010, + 0x445, 0x000000F0, 0x446, 0x00000001, 0x447, 0x000000FE, + 0x448, 0x00000000, 0x449, 0x00000000, 0x44A, 0x00000000, + 0x44B, 0x00000040, 0x44C, 0x00000010, 0x44D, 0x000000F0, + 0x44E, 0x0000003F, 0x44F, 0x00000000, 0x450, 0x00000000, + 0x451, 0x00000000, 0x452, 0x00000000, 0x453, 0x00000040, + 0x455, 0x00000070, 0x45E, 0x00000004, 0x49C, 0x00000010, + 0x49D, 0x000000F0, 0x49E, 0x00000000, 0x49F, 0x00000006, + 0x4A0, 0x000000E0, 0x4A1, 0x00000003, 0x4A2, 0x00000000, + 0x4A3, 0x00000040, 0x4A4, 0x00000015, 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, 0x4A7, 0x00000006, 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, 0x4AA, 0x00000000, 0x4AB, 0x00000000, + 0x7DA, 0x00000008, 0x1448, 0x00000006, 0x144A, 0x00000006, + 0x144C, 0x00000006, 0x144E, 0x00000006, 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, 0x4CA, 0x00000020, 0x4CB, 0x00000020, + 0x4CC, 0x000000FF, 0x4CD, 0x000000FF, 0x4CE, 0x00000001, + 0x4CF, 0x00000008, 0x500, 0x00000026, 0x501, 0x000000A2, + 0x502, 0x0000002F, 0x503, 0x00000000, 0x504, 0x00000028, + 0x505, 0x000000A3, 0x506, 0x0000005E, 0x507, 0x00000000, + 0x508, 0x0000002B, 0x509, 0x000000A4, 0x50A, 0x0000005E, + 0x50B, 0x00000000, 0x50C, 0x0000004F, 0x50D, 0x000000A4, + 0x50E, 0x00000000, 0x50F, 0x00000000, 0x512, 0x0000001C, + 0x514, 0x0000000A, 0x516, 0x0000000A, 0x521, 0x0000002F, + 0x525, 0x0000004F, 0x551, 0x00000010, 0x559, 0x00000002, + 0x55C, 0x00000050, 0x55D, 0x000000FF, 0x577, 0x0000000B, + 0x5BE, 0x00000064, 0x605, 0x00000030, 0x608, 0x0000000E, + 0x609, 0x00000022, 0x60C, 0x00000018, 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, 0x6A2, 0x000000FF, 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, 0x6A5, 0x000000FF, 0x6DE, 0x00000084, + 0x620, 0x000000FF, 0x621, 0x000000FF, 0x622, 0x000000FF, + 0x623, 0x000000FF, 0x624, 0x000000FF, 0x625, 0x000000FF, + 0x626, 0x000000FF, 0x627, 0x000000FF, 0x638, 0x00000050, + 0x63C, 0x0000000A, 0x63D, 0x0000000A, 0x63E, 0x0000000E, + 0x63F, 0x0000000E, 0x640, 0x00000040, 0x642, 0x00000040, + 0x643, 0x00000000, 0x652, 0x000000C8, 0x66E, 0x00000005, + 0x718, 0x00000040, 0x7D4, 0x00000098, + +}; + +void odm_read_and_config_mp_8822b_mac_reg(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_mac_reg) / sizeof(u32); + u32 *array = array_mp_8822b_mac_reg; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_mac_8822b(dm, v1, (u8)v2); + } + } +} + +u32 odm_get_version_mp_8822b_mac_reg(void) { return 67; } diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h new file mode 100644 index 0000000000000000000000000000000000000000..d02fdd7a4a5330775d99d41c2c5608cc7798d53b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#ifndef __INC_MP_MAC_HW_IMG_8822B_H +#define __INC_MP_MAC_HW_IMG_8822B_H + +/****************************************************************************** + * mac_reg.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_mac_reg(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_mac_reg(void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c new file mode 100644 index 0000000000000000000000000000000000000000..84cdc0644207b4d07ae0cb21cc821919463a9543 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c @@ -0,0 +1,4744 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool check_positive(struct phy_dm_struct *dm, const u32 condition1, + const u32 condition2, const u32 condition3, + const u32 condition4) +{ + u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/ + ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/ + ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/ + ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/ + + u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, + cond4 = condition4; + + u8 cut_version_for_para = + (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version; + u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type; + + u32 driver1 = cut_version_for_para << 24 | + (dm->support_interface & 0xF0) << 16 | + dm->support_platform << 16 | pkg_type_for_para << 12 | + (dm->support_interface & 0x0F) << 8 | _board_type; + + u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 | + (dm->type_alna & 0xFF) << 16 | + (dm->type_apa & 0xFF) << 24; + + u32 driver3 = 0; + + u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) | + (dm->type_alna & 0xFF00) << 8 | + (dm->type_apa & 0xFF00) << 16; + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, cond1, cond2, cond3, cond4); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, driver1, driver2, driver3, driver4); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Platform, Interface) = (0x%X, 0x%X)\n", + dm->support_platform, dm->support_interface); + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Board, Package) = (0x%X, 0x%X)\n", + dm->board_type, dm->package_type); + + /*============== value Defined Check ===============*/ + /*QFN type [15:12] and cut version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && + ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && + ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 bit_mask = 0; + + if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + bit_mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + bit_mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + bit_mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + bit_mask |= 0xFF000000; + + if (((cond2 & bit_mask) == (driver2 & bit_mask)) && + ((cond4 & bit_mask) == + (driver4 & + bit_mask))) /* board_type of each RF path is matched*/ + return true; + else + return false; + } else { + return false; + } +} + +/****************************************************************************** + * radioa.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_radioa[] = { + 0x000, 0x00030000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0xA0000000, 0x00000000, 0x001, 0x00040029, + 0xB0000000, 0x00000000, 0x018, 0x00010D24, 0x0EF, 0x00080000, + 0x033, 0x00000002, 0x03E, 0x0000003F, 0x03F, 0x000C0F4E, + 0x033, 0x00000001, 0x03E, 0x00000034, 0x03F, 0x0004080E, + 0x0EF, 0x00080000, 0x0DF, 0x00002449, 0x033, 0x00000024, + 0x03E, 0x0000003F, 0x03F, 0x00060FDE, 0x0EF, 0x00000000, + 0x0EF, 0x00080000, 0x033, 0x00000025, 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, 0x0EF, 0x00000000, 0x0EF, 0x00080000, + 0x033, 0x00000026, 0x03E, 0x00000037, 0x03F, 0x000DEFCE, + 0x0EF, 0x00000000, 0x07F, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, 0xB0000000, 0x00000000, 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C330, 0xA0000000, 0x00000000, 0x0B3, 0x000FC760, + 0xB0000000, 0x00000000, 0x0B4, 0x00099DD0, 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, 0x0B7, 0x00030018, 0x0B8, 0x00080800, + 0x0B9, 0x00000000, 0x0BA, 0x00008000, 0x0BB, 0x00000000, + 0x0BC, 0x00040030, 0x0BD, 0x00000000, 0x0BE, 0x00000000, + 0x0BF, 0x00000000, 0x0C0, 0x00000000, 0x0C1, 0x00000000, + 0x0C2, 0x00000000, 0x0C3, 0x00000000, 0x0C4, 0x00002402, + 0x0C5, 0x00000009, 0x0C6, 0x00040299, 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, 0x0C9, 0x0001C140, 0x0CA, 0x00000000, + 0x0CB, 0x00000000, 0x0CC, 0x00000000, 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, 0x0CF, 0x0006D200, 0x0DF, 0x00000009, + 0x018, 0x00010524, 0x089, 0x00000207, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0xA0000000, 0x00000000, + 0x08A, 0x000FF186, 0xB0000000, 0x00000000, 0x08B, 0x00061E3C, + 0x08C, 0x000112C7, 0x08D, 0x000F4988, 0x08E, 0x00064D40, + 0x0EF, 0x00020000, 0x033, 0x00000007, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0xA0000000, 0x00000000, + 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x00000006, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0xA0000000, 0x00000000, 0x03E, 0x00004080, 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, 0x033, 0x00000005, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004084, 0xA0000000, 0x00000000, + 0x03E, 0x000040C8, 0xB0000000, 0x00000000, 0x03F, 0x000C3186, + 0x033, 0x00000004, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004108, 0xA0000000, 0x00000000, 0x03E, 0x00004190, + 0xB0000000, 0x00000000, 0x03F, 0x000C3186, 0x033, 0x00000003, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x0000490C, + 0xA0000000, 0x00000000, 0x03E, 0x00004998, 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, 0x033, 0x00000002, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00005E00, 0xA0000000, 0x00000000, + 0x03E, 0x00005840, 0xB0000000, 0x00000000, 0x03F, 0x000C3186, + 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00005862, 0xA0000000, 0x00000000, 0x03E, 0x000058C2, + 0xB0000000, 0x00000000, 0x03F, 0x000C3186, 0x033, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00005948, + 0xA0000000, 0x00000000, 0x03E, 0x00005930, 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, 0x033, 0x0000000F, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0xA0000000, 0x00000000, + 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x0000000E, + 0x03E, 0x00004080, 0x03F, 0x000C3186, 0x033, 0x0000000D, + 0x03E, 0x000040C8, 0x03F, 0x000C3186, 0x033, 0x0000000C, + 0x03E, 0x00004190, 0x03F, 0x000C3186, 0x033, 0x0000000B, + 0x03E, 0x00004998, 0x03F, 0x000C3186, 0x033, 0x0000000A, + 0x03E, 0x00005840, 0x03F, 0x000C3186, 0x033, 0x00000009, + 0x03E, 0x000058C2, 0x03F, 0x000C3186, 0x033, 0x00000008, + 0x03E, 0x00005930, 0x03F, 0x000C3186, 0x033, 0x00000017, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0xA0000000, 0x00000000, 0x03E, 0x00004000, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C0006, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, 0x03F, 0x000C3186, 0xB0000000, 0x00000000, + 0x033, 0x00000016, 0x03E, 0x00004080, 0x03F, 0x000C3186, + 0x033, 0x00000015, 0x03E, 0x000040C8, 0x03F, 0x000C3186, + 0x033, 0x00000014, 0x03E, 0x00004190, 0x03F, 0x000C3186, + 0x033, 0x00000013, 0x03E, 0x00004998, 0x03F, 0x000C3186, + 0x033, 0x00000012, 0x03E, 0x00005840, 0x03F, 0x000C3186, + 0x033, 0x00000011, 0x03E, 0x000058C2, 0x03F, 0x000C3186, + 0x033, 0x00000010, 0x03E, 0x00005930, 0x03F, 0x000C3186, + 0x0EF, 0x00000000, 0x0EF, 0x00004000, 0x033, 0x00000000, + 0x03F, 0x0000000A, 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000006, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0xA0000000, 0x00000000, + 0x03F, 0x00000005, 0xB0000000, 0x00000000, 0x033, 0x00000002, + 0x03F, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x00000401, + 0x084, 0x00001209, 0x086, 0x000001A0, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0xA0000000, 0x00000000, + 0x087, 0x000E8180, 0xB0000000, 0x00000000, 0x088, 0x00070020, + 0x0DE, 0x00000010, 0x0EF, 0x00008000, 0x033, 0x0000000F, + 0x03F, 0x0000003C, 0x033, 0x0000000E, 0x03F, 0x00000038, + 0x033, 0x0000000D, 0x03F, 0x00000030, 0x033, 0x0000000C, + 0x03F, 0x00000028, 0x033, 0x0000000B, 0x03F, 0x00000020, + 0x033, 0x0000000A, 0x03F, 0x00000018, 0x033, 0x00000009, + 0x03F, 0x00000010, 0x033, 0x00000008, 0x03F, 0x00000008, + 0x033, 0x00000007, 0x03F, 0x0000003C, 0x033, 0x00000006, + 0x03F, 0x00000038, 0x033, 0x00000005, 0x03F, 0x00000030, + 0x033, 0x00000004, 0x03F, 0x00000028, 0x033, 0x00000003, + 0x03F, 0x00000020, 0x033, 0x00000002, 0x03F, 0x00000018, + 0x033, 0x00000001, 0x03F, 0x00000010, 0x033, 0x00000000, + 0x03F, 0x00000008, 0x0EF, 0x00000000, 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, 0x0FE, 0x00000000, 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, 0x0FE, 0x00000000, 0x0B0, 0x000FF0F8, + 0x018, 0x00018D24, 0xFFE, 0x00000000, 0xFFE, 0x00000000, + 0xFFE, 0x00000000, 0xFFE, 0x00000000, 0x018, 0x00010D24, + 0x01B, 0x00075A40, 0x0EE, 0x00000002, 0x033, 0x00000000, + 0x03F, 0x00000004, 0x033, 0x00000001, 0x03F, 0x00000004, + 0x033, 0x00000002, 0x03F, 0x00000004, 0x033, 0x00000003, + 0x03F, 0x00000004, 0x033, 0x00000004, 0x03F, 0x00000004, + 0x033, 0x00000005, 0x03F, 0x00000006, 0x033, 0x00000006, + 0x03F, 0x00000002, 0x033, 0x00000007, 0x03F, 0x00000000, + 0x0EE, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000062, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, 0x062, 0x0000D303, 0x063, 0x00000002, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D301, + 0x062, 0x0000D303, 0x063, 0x00000002, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D301, 0x062, 0x0000D303, + 0x063, 0x00000002, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D301, + 0x062, 0x0000D303, 0x063, 0x00000002, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D301, 0x062, 0x0000D303, + 0x063, 0x00000002, 0xA0000000, 0x00000000, 0x061, 0x0005D3D0, + 0x062, 0x0000D303, 0x063, 0x00000002, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000004A3, 0x030, 0x000014A3, 0x030, 0x000024A3, + 0x030, 0x000034A3, 0x030, 0x000044A3, 0x030, 0x000054A3, + 0x030, 0x000064A3, 0x030, 0x000074A3, 0x030, 0x000084A3, + 0x030, 0x000094A3, 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, + 0x0EF, 0x00000000, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000004A3, 0x030, 0x000014A3, + 0x030, 0x000024A3, 0x030, 0x000034A3, 0x030, 0x000044A3, + 0x030, 0x000054A3, 0x030, 0x000064A3, 0x030, 0x000074A3, + 0x030, 0x000084A3, 0x030, 0x000094A3, 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, 0x0EF, 0x00000000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000004A3, + 0x030, 0x000014A3, 0x030, 0x000024A3, 0x030, 0x000034A3, + 0x030, 0x000044A3, 0x030, 0x000054A3, 0x030, 0x000064A3, + 0x030, 0x000074A3, 0x030, 0x000084A3, 0x030, 0x000094A3, + 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, 0x0EF, 0x00000000, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000002A6, 0x030, 0x000012A6, 0x030, 0x000022A6, + 0x030, 0x000032A6, 0x030, 0x000042A6, 0x030, 0x000052A6, + 0x030, 0x000062A6, 0x030, 0x000072A6, 0x030, 0x000082A6, + 0x030, 0x000092A6, 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, + 0x0EF, 0x00000000, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000004A0, 0x030, 0x000014A0, + 0x030, 0x000024A0, 0x030, 0x000034A0, 0x030, 0x000044A0, + 0x030, 0x000054A0, 0x030, 0x000064A0, 0x030, 0x000074A0, + 0x030, 0x000084A0, 0x030, 0x000094A0, 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, 0x0EF, 0x00000000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000004A0, + 0x030, 0x000014A0, 0x030, 0x000024A0, 0x030, 0x000034A0, + 0x030, 0x000044A0, 0x030, 0x000054A0, 0x030, 0x000064A0, + 0x030, 0x000074A0, 0x030, 0x000084A0, 0x030, 0x000094A0, + 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, 0x0EF, 0x00000000, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0, + 0x030, 0x000034A0, 0x030, 0x000044A0, 0x030, 0x000054A0, + 0x030, 0x000064A0, 0x030, 0x000074A0, 0x030, 0x000084A0, + 0x030, 0x000094A0, 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, + 0x0EF, 0x00000000, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000002A1, 0x030, 0x000012A1, + 0x030, 0x000022A1, 0x030, 0x000032A1, 0x030, 0x000042A1, + 0x030, 0x000052A1, 0x030, 0x000062A1, 0x030, 0x000072A1, + 0x030, 0x000082A1, 0x030, 0x000092A1, 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, 0x0EF, 0x00000000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000002A6, + 0x030, 0x000012A6, 0x030, 0x000022A6, 0x030, 0x000032A6, + 0x030, 0x000042A6, 0x030, 0x000052A6, 0x030, 0x000062A6, + 0x030, 0x000072A6, 0x030, 0x000082A6, 0x030, 0x000092A6, + 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, 0x0EF, 0x00000000, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x00000384, 0x030, 0x00001384, 0x030, 0x00002384, + 0x030, 0x00003384, 0x030, 0x00004425, 0x030, 0x00005425, + 0x030, 0x00006425, 0x030, 0x00007425, 0x030, 0x000083A4, + 0x030, 0x000093A4, 0x030, 0x0000A3A4, 0x030, 0x0000B3A4, + 0x0EF, 0x00000000, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000003A3, 0x030, 0x000013A3, + 0x030, 0x000023A3, 0x030, 0x000033A3, 0x030, 0x00004355, + 0x030, 0x00005355, 0x030, 0x00006355, 0x030, 0x00007355, + 0x030, 0x00008314, 0x030, 0x00009314, 0x030, 0x0000A314, + 0x030, 0x0000B314, 0x0EF, 0x00000000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003A1, + 0x030, 0x000013A1, 0x030, 0x000023A1, 0x030, 0x000033A1, + 0x030, 0x000043A3, 0x030, 0x000053A3, 0x030, 0x000063A3, + 0x030, 0x000073A3, 0x030, 0x000083A5, 0x030, 0x000093A5, + 0x030, 0x0000A3A5, 0x030, 0x0000B3A5, 0x0EF, 0x00000000, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000002A1, 0x030, 0x000012A1, 0x030, 0x000022A1, + 0x030, 0x000032A1, 0x030, 0x000042A1, 0x030, 0x000052A1, + 0x030, 0x000062A1, 0x030, 0x000072A1, 0x030, 0x000082A1, + 0x030, 0x000092A1, 0x030, 0x0000A2A1, 0x030, 0x0000B2A1, + 0x0EF, 0x00000000, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x00000463, 0x030, 0x00001463, + 0x030, 0x00002463, 0x030, 0x00003463, 0x030, 0x00004545, + 0x030, 0x00005545, 0x030, 0x00006545, 0x030, 0x00007545, + 0x030, 0x00008565, 0x030, 0x00009565, 0x030, 0x0000A565, + 0x030, 0x0000B565, 0x0EF, 0x00000000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x00000303, + 0x030, 0x00001303, 0x030, 0x00002303, 0x030, 0x00003303, + 0x030, 0x000043A4, 0x030, 0x000053A4, 0x030, 0x000063A4, + 0x030, 0x000073A4, 0x030, 0x00008365, 0x030, 0x00009365, + 0x030, 0x0000A365, 0x030, 0x0000B365, 0x0EF, 0x00000000, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x00004343, 0x030, 0x00005343, + 0x030, 0x00006343, 0x030, 0x00007343, 0x030, 0x00008364, + 0x030, 0x00009364, 0x030, 0x0000A364, 0x030, 0x0000B364, + 0x0EF, 0x00000000, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000003A0, 0x030, 0x000013A0, + 0x030, 0x000023A0, 0x030, 0x000033A0, 0x030, 0x00004430, + 0x030, 0x00005430, 0x030, 0x00006430, 0x030, 0x00007430, + 0x030, 0x00008372, 0x030, 0x00009372, 0x030, 0x0000A372, + 0x030, 0x0000B372, 0x0EF, 0x00000000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003A0, + 0x030, 0x000013A0, 0x030, 0x000023A0, 0x030, 0x000033A0, + 0x030, 0x000043A1, 0x030, 0x000053A1, 0x030, 0x000063A1, + 0x030, 0x000073A1, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003D0, + 0x030, 0x000013D0, 0x030, 0x000023D0, 0x030, 0x000033D0, + 0x030, 0x000043D0, 0x030, 0x000053D0, 0x030, 0x000063D0, + 0x030, 0x000073D0, 0x030, 0x000083D0, 0x030, 0x000093D0, + 0x030, 0x0000A3D0, 0x030, 0x0000B3D0, 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A3, 0x030, 0x000013A3, + 0x030, 0x000023A3, 0x030, 0x000033A3, 0x030, 0x000043A3, + 0x030, 0x000053A3, 0x030, 0x000063A3, 0x030, 0x000073A3, + 0x030, 0x000083A3, 0x030, 0x000093A3, 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0xA0000000, 0x00000000, 0x0EF, 0x00000080, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000660, + 0x030, 0x00001443, 0x030, 0x00002221, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000776, + 0x030, 0x00001455, 0x030, 0x00002325, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000777, + 0x030, 0x00001442, 0x030, 0x00002222, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000775, + 0x030, 0x00001343, 0x030, 0x00002210, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000775, + 0x030, 0x00001422, 0x030, 0x00002210, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0xA0000000, 0x00000000, + 0x0EF, 0x00000040, 0x030, 0x00000764, 0x030, 0x00001632, + 0x030, 0x00002421, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000800, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C0C, 0x033, 0x00000021, + 0x03F, 0x00000C29, 0x033, 0x00000022, 0x03F, 0x00000C2C, + 0x033, 0x00000023, 0x03F, 0x00000C69, 0x033, 0x00000024, + 0x03F, 0x00000CA8, 0x033, 0x00000025, 0x03F, 0x00000CE8, + 0x033, 0x00000026, 0x03F, 0x00000CEB, 0x033, 0x00000027, + 0x03F, 0x00000CEE, 0x033, 0x00000028, 0x03F, 0x00000CF1, + 0x033, 0x00000029, 0x03F, 0x00000CF4, 0x033, 0x0000002A, + 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021, + 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849, + 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024, + 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000CA9, + 0x033, 0x00000026, 0x03F, 0x00000CEA, 0x033, 0x00000027, + 0x03F, 0x00000CED, 0x033, 0x00000028, 0x03F, 0x00000CF0, + 0x033, 0x00000029, 0x03F, 0x00000CF3, 0x033, 0x0000002A, + 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021, + 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F, + 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024, + 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0, + 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A, + 0x03F, 0x00000CF5, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021, + 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F, + 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024, + 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0, + 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A, + 0x03F, 0x00000CF5, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000429, 0x033, 0x00000021, + 0x03F, 0x00000828, 0x033, 0x00000022, 0x03F, 0x00000847, + 0x033, 0x00000023, 0x03F, 0x0000084A, 0x033, 0x00000024, + 0x03F, 0x00000C4B, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000CEA, 0x033, 0x00000027, + 0x03F, 0x00000CED, 0x033, 0x00000028, 0x03F, 0x00000CF0, + 0x033, 0x00000029, 0x03F, 0x00000CF3, 0x033, 0x0000002A, + 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021, + 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F, + 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024, + 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0, + 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A, + 0x03F, 0x00000CF5, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021, + 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849, + 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024, + 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000CEB, 0x033, 0x00000028, 0x03F, 0x00000CEE, + 0x033, 0x00000029, 0x03F, 0x00000CF1, 0x033, 0x0000002A, + 0x03F, 0x00000CF4, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021, + 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849, + 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024, + 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000CEB, 0x033, 0x00000028, 0x03F, 0x00000CEE, + 0x033, 0x00000029, 0x03F, 0x00000CF1, 0x033, 0x0000002A, + 0x03F, 0x00000CF4, 0xA0000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000080B, 0x033, 0x00000061, + 0x03F, 0x0000080E, 0x033, 0x00000062, 0x03F, 0x00000848, + 0x033, 0x00000063, 0x03F, 0x00000869, 0x033, 0x00000064, + 0x03F, 0x000008A9, 0x033, 0x00000065, 0x03F, 0x00000CE8, + 0x033, 0x00000066, 0x03F, 0x00000CEB, 0x033, 0x00000067, + 0x03F, 0x00000CEE, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000042B, 0x033, 0x00000061, + 0x03F, 0x0000082A, 0x033, 0x00000062, 0x03F, 0x00000849, + 0x033, 0x00000063, 0x03F, 0x0000084C, 0x033, 0x00000064, + 0x03F, 0x00000C4C, 0x033, 0x00000065, 0x03F, 0x00000CA9, + 0x033, 0x00000066, 0x03F, 0x00000CEA, 0x033, 0x00000067, + 0x03F, 0x00000CED, 0x033, 0x00000068, 0x03F, 0x00000CF0, + 0x033, 0x00000069, 0x03F, 0x00000CF3, 0x033, 0x0000006A, + 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061, + 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A, + 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064, + 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA, + 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067, + 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061, + 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A, + 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064, + 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA, + 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067, + 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000429, 0x033, 0x00000061, + 0x03F, 0x00000828, 0x033, 0x00000062, 0x03F, 0x00000847, + 0x033, 0x00000063, 0x03F, 0x0000084A, 0x033, 0x00000064, + 0x03F, 0x00000C4B, 0x033, 0x00000065, 0x03F, 0x00000C8A, + 0x033, 0x00000066, 0x03F, 0x00000CEA, 0x033, 0x00000067, + 0x03F, 0x00000CED, 0x033, 0x00000068, 0x03F, 0x00000CF0, + 0x033, 0x00000069, 0x03F, 0x00000CF3, 0x033, 0x0000006A, + 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061, + 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A, + 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064, + 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA, + 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067, + 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000042C, 0x033, 0x00000061, + 0x03F, 0x0000082B, 0x033, 0x00000062, 0x03F, 0x0000084A, + 0x033, 0x00000063, 0x03F, 0x0000084D, 0x033, 0x00000064, + 0x03F, 0x00000C4D, 0x033, 0x00000065, 0x03F, 0x00000C8B, + 0x033, 0x00000066, 0x03F, 0x00000C8E, 0x033, 0x00000067, + 0x03F, 0x00000CEC, 0x033, 0x00000068, 0x03F, 0x00000CEF, + 0x033, 0x00000069, 0x03F, 0x00000CF2, 0x033, 0x0000006A, + 0x03F, 0x00000CF5, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000042C, 0x033, 0x00000061, + 0x03F, 0x0000082B, 0x033, 0x00000062, 0x03F, 0x0000084A, + 0x033, 0x00000063, 0x03F, 0x0000084D, 0x033, 0x00000064, + 0x03F, 0x00000C4D, 0x033, 0x00000065, 0x03F, 0x00000C8B, + 0x033, 0x00000066, 0x03F, 0x00000C8E, 0x033, 0x00000067, + 0x03F, 0x00000CEC, 0x033, 0x00000068, 0x03F, 0x00000CEF, + 0x033, 0x00000069, 0x03F, 0x00000CF2, 0x033, 0x0000006A, + 0x03F, 0x00000CF5, 0xA0000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C0A, 0x033, 0x000000A1, + 0x03F, 0x00000C0D, 0x033, 0x000000A2, 0x03F, 0x00000C2A, + 0x033, 0x000000A3, 0x03F, 0x00000C2D, 0x033, 0x000000A4, + 0x03F, 0x00000C6A, 0x033, 0x000000A5, 0x03F, 0x00000CE8, + 0x033, 0x000000A6, 0x03F, 0x00000CEB, 0x033, 0x000000A7, + 0x03F, 0x00000CEE, 0x033, 0x000000A8, 0x03F, 0x00000CF1, + 0x033, 0x000000A9, 0x03F, 0x00000CF4, 0x033, 0x000000AA, + 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1, + 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848, + 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4, + 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000CA9, + 0x033, 0x000000A6, 0x03F, 0x00000CEA, 0x033, 0x000000A7, + 0x03F, 0x00000CED, 0x033, 0x000000A8, 0x03F, 0x00000CF0, + 0x033, 0x000000A9, 0x03F, 0x00000CF3, 0x033, 0x000000AA, + 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1, + 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F, + 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4, + 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF, + 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA, + 0x03F, 0x00000CF5, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1, + 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F, + 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4, + 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF, + 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA, + 0x03F, 0x00000CF5, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000429, 0x033, 0x000000A1, + 0x03F, 0x00000828, 0x033, 0x000000A2, 0x03F, 0x00000847, + 0x033, 0x000000A3, 0x03F, 0x0000084A, 0x033, 0x000000A4, + 0x03F, 0x00000C4B, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000CEA, 0x033, 0x000000A7, + 0x03F, 0x00000CED, 0x033, 0x000000A8, 0x03F, 0x00000CF0, + 0x033, 0x000000A9, 0x03F, 0x00000CF3, 0x033, 0x000000AA, + 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1, + 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F, + 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4, + 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF, + 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA, + 0x03F, 0x00000CF5, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1, + 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848, + 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4, + 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000CEB, 0x033, 0x000000A8, 0x03F, 0x00000CEE, + 0x033, 0x000000A9, 0x03F, 0x00000CF1, 0x033, 0x000000AA, + 0x03F, 0x00000CF4, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1, + 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848, + 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4, + 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000CEB, 0x033, 0x000000A8, 0x03F, 0x00000CEE, + 0x033, 0x000000A9, 0x03F, 0x00000CF1, 0x033, 0x000000AA, + 0x03F, 0x00000CF4, 0xA0000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000400, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C, + 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003, + 0x03F, 0x0000047C, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001, + 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C, + 0x033, 0x00000003, 0x03F, 0x0000047C, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000047C, + 0x033, 0x00000001, 0x03F, 0x0000047C, 0x033, 0x00000002, + 0x03F, 0x0000047C, 0x033, 0x00000003, 0x03F, 0x0000047C, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C, + 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003, + 0x03F, 0x0000047C, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001, + 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C, + 0x033, 0x00000003, 0x03F, 0x0000047C, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000047C, + 0x033, 0x00000001, 0x03F, 0x0000047C, 0x033, 0x00000002, + 0x03F, 0x0000047C, 0x033, 0x00000003, 0x03F, 0x0000047C, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C, + 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003, + 0x03F, 0x0000047C, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001, + 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C, + 0x033, 0x00000003, 0x03F, 0x0000047C, 0xA0000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x000004BB, 0x033, 0x00000001, + 0x03F, 0x000004BB, 0x033, 0x00000002, 0x03F, 0x000004BB, + 0x033, 0x00000003, 0x03F, 0x000004BB, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000100, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726, + 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002, + 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726, + 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003, + 0x03F, 0x00001726, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00001726, 0x033, 0x00000001, + 0x03F, 0x00001726, 0x033, 0x00000002, 0x03F, 0x00001726, + 0x033, 0x00000003, 0x03F, 0x00001726, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726, + 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002, + 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726, + 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003, + 0x03F, 0x00001726, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00001726, 0x033, 0x00000001, + 0x03F, 0x00001726, 0x033, 0x00000002, 0x03F, 0x00001726, + 0x033, 0x00000003, 0x03F, 0x00001726, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726, + 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002, + 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726, + 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003, + 0x03F, 0x00001726, 0xA0000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000F34, 0x033, 0x00000001, 0x03F, 0x00000F34, + 0x033, 0x00000002, 0x03F, 0x00000F34, 0x033, 0x00000003, + 0x03F, 0x00000F34, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0xA0000000, 0x00000000, 0x081, 0x0000F000, + 0x087, 0x00016040, 0x051, 0x00000C00, 0x052, 0x0007C241, + 0x053, 0x0001C069, 0x054, 0x00078032, 0x057, 0x0000CE0A, + 0x058, 0x00058750, 0xB0000000, 0x00000000, 0x0EF, 0x00000800, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0xA0000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0005142C, + 0x033, 0x00000001, 0x03F, 0x0005144B, 0x033, 0x00000002, + 0x03F, 0x0005144E, 0x033, 0x00000003, 0x03F, 0x00051C69, + 0x033, 0x00000004, 0x03F, 0x00051C6C, 0x033, 0x00000005, + 0x03F, 0x00051C6F, 0x033, 0x00000006, 0x03F, 0x00051CEB, + 0x033, 0x00000007, 0x03F, 0x00051CEE, 0x033, 0x00000008, + 0x03F, 0x00051CF1, 0x033, 0x00000009, 0x03F, 0x00051CF4, + 0x033, 0x0000000A, 0x03F, 0x00051CF7, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000010, 0x033, 0x00000000, + 0x008, 0x0009C060, 0x033, 0x00000001, 0x008, 0x0009C060, + 0x0EF, 0x00000000, 0x033, 0x000000A2, 0x0EF, 0x00080000, + 0x03E, 0x0000593F, 0x03F, 0x000C0F4F, 0x0EF, 0x00000000, + 0x033, 0x000000A3, 0x0EF, 0x00080000, 0x03E, 0x00005934, + 0x03F, 0x0005AFCF, 0x0EF, 0x00000000, + +}; + +void odm_read_and_config_mp_8822b_radioa(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_radioa) / sizeof(u32); + u32 *array = array_mp_8822b_radioa; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_rf_radio_a_8822b(dm, v1, v2); + } + } +} + +u32 odm_get_version_mp_8822b_radioa(void) { return 67; } + +/****************************************************************************** + * radiob.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_radiob[] = { + 0x000, 0x00030000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0xA0000000, 0x00000000, 0x001, 0x00040029, + 0xB0000000, 0x00000000, 0x018, 0x00010D24, 0x0EF, 0x00080000, + 0x033, 0x00000002, 0x03E, 0x0000003F, 0x03F, 0x000C0F4E, + 0x033, 0x00000001, 0x03E, 0x00000034, 0x03F, 0x0004080E, + 0x0EF, 0x00080000, 0x0DF, 0x00002449, 0x033, 0x00000024, + 0x03E, 0x0000003F, 0x03F, 0x00060FDE, 0x0EF, 0x00000000, + 0x0EF, 0x00080000, 0x033, 0x00000025, 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, 0x0EF, 0x00000000, 0x0EF, 0x00080000, + 0x033, 0x00000026, 0x03E, 0x00000037, 0x03F, 0x000DEFCE, + 0x0EF, 0x00000000, 0x0DF, 0x00000009, 0x018, 0x00010524, + 0x089, 0x00000207, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, 0xA0000000, 0x00000000, 0x08A, 0x000FF186, + 0xB0000000, 0x00000000, 0x08B, 0x00061E3C, 0x08C, 0x000112C7, + 0x08D, 0x000F4988, 0x08E, 0x00064D40, 0x0EF, 0x00020000, + 0x033, 0x00000007, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004080, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004080, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0xA0000000, 0x00000000, 0x03E, 0x00004000, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0xA0000000, 0x00000000, 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, 0x033, 0x00000006, 0x03E, 0x00004080, + 0x03F, 0x000C3186, 0x033, 0x00000005, 0x03E, 0x000040C8, + 0x03F, 0x000C3186, 0x033, 0x00000004, 0x03E, 0x00004190, + 0x03F, 0x000C3186, 0x033, 0x00000003, 0x03E, 0x00004998, + 0x03F, 0x000C3186, 0x033, 0x00000002, 0x03E, 0x00005840, + 0x03F, 0x000C3186, 0x033, 0x00000001, 0x03E, 0x000058C2, + 0x03F, 0x000C3186, 0x033, 0x00000000, 0x03E, 0x00005930, + 0x03F, 0x000C3186, 0x033, 0x0000000F, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0xA0000000, 0x00000000, + 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x0000000E, + 0x03E, 0x00004080, 0x03F, 0x000C3186, 0x033, 0x0000000D, + 0x03E, 0x000040C8, 0x03F, 0x000C3186, 0x033, 0x0000000C, + 0x03E, 0x00004190, 0x03F, 0x000C3186, 0x033, 0x0000000B, + 0x03E, 0x00004998, 0x03F, 0x000C3186, 0x033, 0x0000000A, + 0x03E, 0x00005840, 0x03F, 0x000C3186, 0x033, 0x00000009, + 0x03E, 0x000058C2, 0x03F, 0x000C3186, 0x033, 0x00000008, + 0x03E, 0x00005930, 0x03F, 0x000C3186, 0x033, 0x00000017, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0xA0000000, 0x00000000, 0x03E, 0x00004000, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000DFF86, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C0006, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, 0x03F, 0x000C3186, 0xB0000000, 0x00000000, + 0x033, 0x00000016, 0x03E, 0x00004080, 0x03F, 0x000C3186, + 0x033, 0x00000015, 0x03E, 0x000040C8, 0x03F, 0x000C3186, + 0x033, 0x00000014, 0x03E, 0x00004190, 0x03F, 0x000C3186, + 0x033, 0x00000013, 0x03E, 0x00004998, 0x03F, 0x000C3186, + 0x033, 0x00000012, 0x03E, 0x00005840, 0x03F, 0x000C3186, + 0x033, 0x00000011, 0x03E, 0x000058C2, 0x03F, 0x000C3186, + 0x033, 0x00000010, 0x03E, 0x00005930, 0x03F, 0x000C3186, + 0x0EF, 0x00000000, 0x0EF, 0x00004000, 0x033, 0x00000000, + 0x03F, 0x0000000A, 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000002, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0xA0000000, 0x00000000, + 0x03F, 0x00000005, 0xB0000000, 0x00000000, 0x033, 0x00000002, + 0x03F, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x00000401, + 0x084, 0x00001209, 0x086, 0x000001A0, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0xA0000000, 0x00000000, + 0x087, 0x000E8180, 0xB0000000, 0x00000000, 0x088, 0x00070020, + 0x0DE, 0x00000010, 0x0EF, 0x00008000, 0x033, 0x0000000F, + 0x03F, 0x0000003C, 0x033, 0x0000000E, 0x03F, 0x00000038, + 0x033, 0x0000000D, 0x03F, 0x00000030, 0x033, 0x0000000C, + 0x03F, 0x00000028, 0x033, 0x0000000B, 0x03F, 0x00000020, + 0x033, 0x0000000A, 0x03F, 0x00000018, 0x033, 0x00000009, + 0x03F, 0x00000010, 0x033, 0x00000008, 0x03F, 0x00000008, + 0x033, 0x00000007, 0x03F, 0x0000003C, 0x033, 0x00000006, + 0x03F, 0x00000038, 0x033, 0x00000005, 0x03F, 0x00000030, + 0x033, 0x00000004, 0x03F, 0x00000028, 0x033, 0x00000003, + 0x03F, 0x00000020, 0x033, 0x00000002, 0x03F, 0x00000018, + 0x033, 0x00000001, 0x03F, 0x00000010, 0x033, 0x00000000, + 0x03F, 0x00000008, 0x0EF, 0x00000000, 0x018, 0x00018D24, + 0xFFE, 0x00000000, 0xFFE, 0x00000000, 0xFFE, 0x00000000, + 0xFFE, 0x00000000, 0x018, 0x00010D24, 0x01B, 0x00075A40, + 0x0EE, 0x00000002, 0x033, 0x00000000, 0x03F, 0x00000004, + 0x033, 0x00000001, 0x03F, 0x00000004, 0x033, 0x00000002, + 0x03F, 0x00000004, 0x033, 0x00000003, 0x03F, 0x00000004, + 0x033, 0x00000004, 0x03F, 0x00000004, 0x033, 0x00000005, + 0x03F, 0x00000006, 0x033, 0x00000006, 0x03F, 0x00000002, + 0x033, 0x00000007, 0x03F, 0x00000000, 0x0EE, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000062, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0xA0000000, 0x00000000, 0x061, 0x0005D3D0, 0x062, 0x0000D303, + 0x063, 0x00000002, 0xB0000000, 0x00000000, 0x0EF, 0x00000200, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x030, 0x000004A3, + 0x030, 0x000014A3, 0x030, 0x000024A3, 0x030, 0x000034A3, + 0x030, 0x000044A3, 0x030, 0x000054A3, 0x030, 0x000064A3, + 0x030, 0x000074A3, 0x030, 0x000084A3, 0x030, 0x000094A3, + 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x030, 0x000004A3, 0x030, 0x000014A3, + 0x030, 0x000024A3, 0x030, 0x000034A3, 0x030, 0x000044A3, + 0x030, 0x000054A3, 0x030, 0x000064A3, 0x030, 0x000074A3, + 0x030, 0x000084A3, 0x030, 0x000094A3, 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A3, 0x030, 0x000014A3, 0x030, 0x000024A3, + 0x030, 0x000034A3, 0x030, 0x000044A3, 0x030, 0x000054A3, + 0x030, 0x000064A3, 0x030, 0x000074A3, 0x030, 0x000084A3, + 0x030, 0x000094A3, 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002A6, + 0x030, 0x000012A6, 0x030, 0x000022A6, 0x030, 0x000032A6, + 0x030, 0x000042A6, 0x030, 0x000052A6, 0x030, 0x000062A6, + 0x030, 0x000072A6, 0x030, 0x000082A6, 0x030, 0x000092A6, + 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x030, 0x000004A0, 0x030, 0x000014A0, + 0x030, 0x000024A0, 0x030, 0x000034A0, 0x030, 0x000044A0, + 0x030, 0x000054A0, 0x030, 0x000064A0, 0x030, 0x000074A0, + 0x030, 0x000084A0, 0x030, 0x000094A0, 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0, + 0x030, 0x000034A0, 0x030, 0x000044A0, 0x030, 0x000054A0, + 0x030, 0x000064A0, 0x030, 0x000074A0, 0x030, 0x000084A0, + 0x030, 0x000094A0, 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000004A0, + 0x030, 0x000014A0, 0x030, 0x000024A0, 0x030, 0x000034A0, + 0x030, 0x000044A0, 0x030, 0x000054A0, 0x030, 0x000064A0, + 0x030, 0x000074A0, 0x030, 0x000084A0, 0x030, 0x000094A0, + 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000002A1, 0x030, 0x000012A1, + 0x030, 0x000022A1, 0x030, 0x000032A1, 0x030, 0x000042A1, + 0x030, 0x000052A1, 0x030, 0x000062A1, 0x030, 0x000072A1, + 0x030, 0x000082A1, 0x030, 0x000092A1, 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A6, 0x030, 0x000012A6, 0x030, 0x000022A6, + 0x030, 0x000032A6, 0x030, 0x000042A6, 0x030, 0x000052A6, + 0x030, 0x000062A6, 0x030, 0x000072A6, 0x030, 0x000082A6, + 0x030, 0x000092A6, 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002F4, + 0x030, 0x000012F4, 0x030, 0x000022F4, 0x030, 0x000032F4, + 0x030, 0x00004365, 0x030, 0x00005365, 0x030, 0x00006365, + 0x030, 0x00007365, 0x030, 0x000082A4, 0x030, 0x000092A4, + 0x030, 0x0000A2A4, 0x030, 0x0000B2A4, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000004A4, 0x030, 0x000014A4, + 0x030, 0x000024A4, 0x030, 0x000034A4, 0x030, 0x000043A4, + 0x030, 0x000053A4, 0x030, 0x000063A4, 0x030, 0x000073A4, + 0x030, 0x000083A5, 0x030, 0x000093A5, 0x030, 0x0000A3A5, + 0x030, 0x0000B3A5, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A1, 0x030, 0x000013A1, 0x030, 0x000023A1, + 0x030, 0x000033A1, 0x030, 0x000043A4, 0x030, 0x000053A4, + 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x000083A6, + 0x030, 0x000093A6, 0x030, 0x0000A3A6, 0x030, 0x0000B3A6, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002A1, + 0x030, 0x000012A1, 0x030, 0x000022A1, 0x030, 0x000032A1, + 0x030, 0x000042A1, 0x030, 0x000052A1, 0x030, 0x000062A1, + 0x030, 0x000072A1, 0x030, 0x000082A1, 0x030, 0x000092A1, + 0x030, 0x0000A2A1, 0x030, 0x0000B2A1, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000382, 0x030, 0x00001382, + 0x030, 0x00002382, 0x030, 0x00003382, 0x030, 0x00004445, + 0x030, 0x00005445, 0x030, 0x00006445, 0x030, 0x00007445, + 0x030, 0x00008425, 0x030, 0x00009425, 0x030, 0x0000A425, + 0x030, 0x0000B425, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000303, 0x030, 0x00001303, 0x030, 0x00002303, + 0x030, 0x00003303, 0x030, 0x000043A4, 0x030, 0x000053A4, + 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x00008365, + 0x030, 0x00009365, 0x030, 0x0000A365, 0x030, 0x0000B365, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A1, + 0x030, 0x000013A1, 0x030, 0x000023A1, 0x030, 0x000033A1, + 0x030, 0x00004364, 0x030, 0x00005364, 0x030, 0x00006364, + 0x030, 0x00007364, 0x030, 0x00008564, 0x030, 0x00009564, + 0x030, 0x0000A564, 0x030, 0x0000B564, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000004A1, 0x030, 0x000014A1, + 0x030, 0x000024A1, 0x030, 0x000034A1, 0x030, 0x000043A1, + 0x030, 0x000053A1, 0x030, 0x000063A1, 0x030, 0x000073A1, + 0x030, 0x000083A1, 0x030, 0x000093A1, 0x030, 0x0000A3A1, + 0x030, 0x0000B3A1, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0, + 0x030, 0x000034A0, 0x030, 0x000043A1, 0x030, 0x000053A1, + 0x030, 0x000063A1, 0x030, 0x000073A1, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0xA0000000, 0x00000000, 0x030, 0x000002D0, 0x030, 0x000012D0, + 0x030, 0x000022D0, 0x030, 0x000032D0, 0x030, 0x000042D0, + 0x030, 0x000052D0, 0x030, 0x000062D0, 0x030, 0x000072D0, + 0x030, 0x000082D0, 0x030, 0x000092D0, 0x030, 0x0000A2D0, + 0x030, 0x0000B2D0, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000080, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x030, 0x00000203, 0x030, 0x00001203, 0x030, 0x00002203, + 0x030, 0x00003203, 0x030, 0x00004203, 0x030, 0x00005203, + 0x030, 0x00006203, 0x030, 0x00007203, 0x030, 0x00008203, + 0x030, 0x00009203, 0x030, 0x0000A203, 0x030, 0x0000B203, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x030, 0x00000203, + 0x030, 0x00001203, 0x030, 0x00002203, 0x030, 0x00003203, + 0x030, 0x00004203, 0x030, 0x00005203, 0x030, 0x00006203, + 0x030, 0x00007203, 0x030, 0x00008203, 0x030, 0x00009203, + 0x030, 0x0000A203, 0x030, 0x0000B203, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x030, 0x00000203, + 0x030, 0x00001203, 0x030, 0x00002203, 0x030, 0x00003203, + 0x030, 0x00004203, 0x030, 0x00005203, 0x030, 0x00006203, + 0x030, 0x00007203, 0x030, 0x00008203, 0x030, 0x00009203, + 0x030, 0x0000A203, 0x030, 0x0000B203, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, 0x030, 0x00001203, 0x030, 0x00002203, + 0x030, 0x00003203, 0x030, 0x00004203, 0x030, 0x00005203, + 0x030, 0x00006203, 0x030, 0x00007203, 0x030, 0x00008203, + 0x030, 0x00009203, 0x030, 0x0000A203, 0x030, 0x0000B203, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A3, 0x030, 0x000013A3, 0x030, 0x000023A3, + 0x030, 0x000033A3, 0x030, 0x000043A4, 0x030, 0x000053A4, + 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x000083A3, + 0x030, 0x000093A3, 0x030, 0x0000A3A3, 0x030, 0x0000B3A3, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0xA0000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000040, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004777, 0x030, 0x00005777, + 0x030, 0x00006777, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000660, 0x030, 0x00001341, + 0x030, 0x00002220, 0x030, 0x00004777, 0x030, 0x00005777, + 0x030, 0x00006777, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, 0x030, 0x00001452, 0x030, 0x00002220, + 0x030, 0x00004777, 0x030, 0x00005777, 0x030, 0x00006777, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, 0x030, 0x00001632, 0x030, 0x00002421, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000777, + 0x030, 0x00001442, 0x030, 0x00002222, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000764, 0x030, 0x00001632, + 0x030, 0x00002421, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000775, 0x030, 0x00001222, 0x030, 0x00002210, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000775, + 0x030, 0x00001422, 0x030, 0x00002210, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0xA0000000, 0x00000000, + 0x030, 0x00000764, 0x030, 0x00001632, 0x030, 0x00002421, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000800, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000828, 0x033, 0x00000021, 0x03F, 0x0000082B, + 0x033, 0x00000022, 0x03F, 0x00000868, 0x033, 0x00000023, + 0x03F, 0x00000889, 0x033, 0x00000024, 0x03F, 0x000008AA, + 0x033, 0x00000025, 0x03F, 0x00000CE8, 0x033, 0x00000026, + 0x03F, 0x00000CEB, 0x033, 0x00000027, 0x03F, 0x00000CEE, + 0x033, 0x00000028, 0x03F, 0x00000CF1, 0x033, 0x00000029, + 0x03F, 0x00000CF4, 0x033, 0x0000002A, 0x03F, 0x00000CF7, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x0000042A, 0x033, 0x00000021, 0x03F, 0x00000829, + 0x033, 0x00000022, 0x03F, 0x00000848, 0x033, 0x00000023, + 0x03F, 0x0000084B, 0x033, 0x00000024, 0x03F, 0x00000C4C, + 0x033, 0x00000025, 0x03F, 0x00000C8B, 0x033, 0x00000026, + 0x03F, 0x00000CEA, 0x033, 0x00000027, 0x03F, 0x00000CED, + 0x033, 0x00000028, 0x03F, 0x00000CF0, 0x033, 0x00000029, + 0x03F, 0x00000CF3, 0x033, 0x0000002A, 0x03F, 0x00000CF6, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000429, 0x033, 0x00000021, 0x03F, 0x00000828, + 0x033, 0x00000022, 0x03F, 0x00000847, 0x033, 0x00000023, + 0x03F, 0x0000084A, 0x033, 0x00000024, 0x03F, 0x00000C4B, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000CEA, 0x033, 0x00000027, 0x03F, 0x00000CED, + 0x033, 0x00000028, 0x03F, 0x00000CF0, 0x033, 0x00000029, + 0x03F, 0x00000CF3, 0x033, 0x0000002A, 0x03F, 0x00000CF6, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x0000042B, 0x033, 0x00000021, 0x03F, 0x0000082A, + 0x033, 0x00000022, 0x03F, 0x00000849, 0x033, 0x00000023, + 0x03F, 0x0000084C, 0x033, 0x00000024, 0x03F, 0x00000C4C, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000CEB, + 0x033, 0x00000028, 0x03F, 0x00000CEE, 0x033, 0x00000029, + 0x03F, 0x00000CF1, 0x033, 0x0000002A, 0x03F, 0x00000CF4, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x0000042B, 0x033, 0x00000021, 0x03F, 0x0000082A, + 0x033, 0x00000022, 0x03F, 0x00000849, 0x033, 0x00000023, + 0x03F, 0x0000084C, 0x033, 0x00000024, 0x03F, 0x00000C4C, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000CEB, + 0x033, 0x00000028, 0x03F, 0x00000CEE, 0x033, 0x00000029, + 0x03F, 0x00000CF1, 0x033, 0x0000002A, 0x03F, 0x00000CF4, + 0xA0000000, 0x00000000, 0x033, 0x00000020, 0x03F, 0x00000C09, + 0x033, 0x00000021, 0x03F, 0x00000C0C, 0x033, 0x00000022, + 0x03F, 0x00000C0F, 0x033, 0x00000023, 0x03F, 0x00000C2C, + 0x033, 0x00000024, 0x03F, 0x00000C2F, 0x033, 0x00000025, + 0x03F, 0x00000C8A, 0x033, 0x00000026, 0x03F, 0x00000C8D, + 0x033, 0x00000027, 0x03F, 0x00000C90, 0x033, 0x00000028, + 0x03F, 0x00000CD0, 0x033, 0x00000029, 0x03F, 0x00000CF2, + 0x033, 0x0000002A, 0x03F, 0x00000CF5, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000842, 0x033, 0x00000061, 0x03F, 0x00000845, + 0x033, 0x00000062, 0x03F, 0x00000866, 0x033, 0x00000063, + 0x03F, 0x000008A6, 0x033, 0x00000064, 0x03F, 0x000008C8, + 0x033, 0x00000065, 0x03F, 0x00000CE8, 0x033, 0x00000066, + 0x03F, 0x00000CEB, 0x033, 0x00000067, 0x03F, 0x00000CEE, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x0000042A, 0x033, 0x00000061, 0x03F, 0x00000829, + 0x033, 0x00000062, 0x03F, 0x00000848, 0x033, 0x00000063, + 0x03F, 0x0000084B, 0x033, 0x00000064, 0x03F, 0x00000C69, + 0x033, 0x00000065, 0x03F, 0x00000CA9, 0x033, 0x00000066, + 0x03F, 0x00000CEA, 0x033, 0x00000067, 0x03F, 0x00000CED, + 0x033, 0x00000068, 0x03F, 0x00000CF0, 0x033, 0x00000069, + 0x03F, 0x00000CF3, 0x033, 0x0000006A, 0x03F, 0x00000CF6, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000429, 0x033, 0x00000061, 0x03F, 0x00000828, + 0x033, 0x00000062, 0x03F, 0x00000847, 0x033, 0x00000063, + 0x03F, 0x0000084A, 0x033, 0x00000064, 0x03F, 0x00000C4B, + 0x033, 0x00000065, 0x03F, 0x00000C8A, 0x033, 0x00000066, + 0x03F, 0x00000CEA, 0x033, 0x00000067, 0x03F, 0x00000CED, + 0x033, 0x00000068, 0x03F, 0x00000CF0, 0x033, 0x00000069, + 0x03F, 0x00000CF3, 0x033, 0x0000006A, 0x03F, 0x00000CF6, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x0000042C, 0x033, 0x00000061, 0x03F, 0x0000082B, + 0x033, 0x00000062, 0x03F, 0x0000084A, 0x033, 0x00000063, + 0x03F, 0x0000084D, 0x033, 0x00000064, 0x03F, 0x00000C4E, + 0x033, 0x00000065, 0x03F, 0x00000C8C, 0x033, 0x00000066, + 0x03F, 0x00000C8F, 0x033, 0x00000067, 0x03F, 0x00000CEC, + 0x033, 0x00000068, 0x03F, 0x00000CEF, 0x033, 0x00000069, + 0x03F, 0x00000CF2, 0x033, 0x0000006A, 0x03F, 0x00000CF5, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x0000042C, 0x033, 0x00000061, 0x03F, 0x0000082B, + 0x033, 0x00000062, 0x03F, 0x0000084A, 0x033, 0x00000063, + 0x03F, 0x0000084D, 0x033, 0x00000064, 0x03F, 0x00000C4E, + 0x033, 0x00000065, 0x03F, 0x00000C8C, 0x033, 0x00000066, + 0x03F, 0x00000C8F, 0x033, 0x00000067, 0x03F, 0x00000CEC, + 0x033, 0x00000068, 0x03F, 0x00000CEF, 0x033, 0x00000069, + 0x03F, 0x00000CF2, 0x033, 0x0000006A, 0x03F, 0x00000CF5, + 0xA0000000, 0x00000000, 0x033, 0x00000060, 0x03F, 0x00000C0A, + 0x033, 0x00000061, 0x03F, 0x00000C0D, 0x033, 0x00000062, + 0x03F, 0x00000C2A, 0x033, 0x00000063, 0x03F, 0x00000C2D, + 0x033, 0x00000064, 0x03F, 0x00000C6A, 0x033, 0x00000065, + 0x03F, 0x00000CAA, 0x033, 0x00000066, 0x03F, 0x00000CAD, + 0x033, 0x00000067, 0x03F, 0x00000CB0, 0x033, 0x00000068, + 0x03F, 0x00000CF1, 0x033, 0x00000069, 0x03F, 0x00000CF4, + 0x033, 0x0000006A, 0x03F, 0x00000CF7, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000826, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x0000082C, 0x033, 0x000000A3, + 0x03F, 0x0000082F, 0x033, 0x000000A4, 0x03F, 0x0000086C, + 0x033, 0x000000A5, 0x03F, 0x00000CE8, 0x033, 0x000000A6, + 0x03F, 0x00000CEB, 0x033, 0x000000A7, 0x03F, 0x00000CEE, + 0x033, 0x000000A8, 0x03F, 0x00000CF1, 0x033, 0x000000A9, + 0x03F, 0x00000CF4, 0x033, 0x000000AA, 0x03F, 0x00000CF7, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3, + 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C, + 0x033, 0x000000A5, 0x03F, 0x00000CA9, 0x033, 0x000000A6, + 0x03F, 0x00000CEA, 0x033, 0x000000A7, 0x03F, 0x00000CED, + 0x033, 0x000000A8, 0x03F, 0x00000CF0, 0x033, 0x000000A9, + 0x03F, 0x00000CF3, 0x033, 0x000000AA, 0x03F, 0x00000CF6, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000429, 0x033, 0x000000A1, 0x03F, 0x00000828, + 0x033, 0x000000A2, 0x03F, 0x00000847, 0x033, 0x000000A3, + 0x03F, 0x0000084A, 0x033, 0x000000A4, 0x03F, 0x00000C4B, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000CEA, 0x033, 0x000000A7, 0x03F, 0x00000CED, + 0x033, 0x000000A8, 0x03F, 0x00000CF0, 0x033, 0x000000A9, + 0x03F, 0x00000CF3, 0x033, 0x000000AA, 0x03F, 0x00000CF6, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3, + 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000CEC, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3, + 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000CEC, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0xA0000000, 0x00000000, 0x033, 0x000000A0, 0x03F, 0x00000C09, + 0x033, 0x000000A1, 0x03F, 0x00000C0C, 0x033, 0x000000A2, + 0x03F, 0x00000C0F, 0x033, 0x000000A3, 0x03F, 0x00000C2C, + 0x033, 0x000000A4, 0x03F, 0x00000C2F, 0x033, 0x000000A5, + 0x03F, 0x00000C8A, 0x033, 0x000000A6, 0x03F, 0x00000C8D, + 0x033, 0x000000A7, 0x03F, 0x00000C90, 0x033, 0x000000A8, + 0x03F, 0x00000CEF, 0x033, 0x000000A9, 0x03F, 0x00000CF2, + 0x033, 0x000000AA, 0x03F, 0x00000CF5, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000400, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A, + 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002, + 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A, + 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003, + 0x03F, 0x0000265A, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000265A, 0x033, 0x00000001, + 0x03F, 0x0000265A, 0x033, 0x00000002, 0x03F, 0x0000265A, + 0x033, 0x00000003, 0x03F, 0x0000265A, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A, + 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002, + 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A, + 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003, + 0x03F, 0x0000265A, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000265A, 0x033, 0x00000001, + 0x03F, 0x0000265A, 0x033, 0x00000002, 0x03F, 0x0000265A, + 0x033, 0x00000003, 0x03F, 0x0000265A, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A, + 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002, + 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A, + 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003, + 0x03F, 0x0000265A, 0xA0000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x000004BB, 0x033, 0x00000001, 0x03F, 0x000004BB, + 0x033, 0x00000002, 0x03F, 0x000004BB, 0x033, 0x00000003, + 0x03F, 0x000004BB, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000100, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001, + 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745, + 0x033, 0x00000003, 0x03F, 0x00000745, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745, + 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002, + 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000745, 0x033, 0x00000001, 0x03F, 0x00000745, + 0x033, 0x00000002, 0x03F, 0x00000745, 0x033, 0x00000003, + 0x03F, 0x00000745, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001, + 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745, + 0x033, 0x00000003, 0x03F, 0x00000745, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745, + 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002, + 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000745, 0x033, 0x00000001, 0x03F, 0x00000745, + 0x033, 0x00000002, 0x03F, 0x00000745, 0x033, 0x00000003, + 0x03F, 0x00000745, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001, + 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745, + 0x033, 0x00000003, 0x03F, 0x00000745, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745, + 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002, + 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745, + 0xA0000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000F34, + 0x033, 0x00000001, 0x03F, 0x00000F34, 0x033, 0x00000002, + 0x03F, 0x00000F34, 0x033, 0x00000003, 0x03F, 0x00000F34, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0xA0000000, 0x00000000, 0x081, 0x0000F000, 0x087, 0x00016040, + 0x051, 0x00000C00, 0x052, 0x0007C241, 0x053, 0x0001C069, + 0x054, 0x00078032, 0x057, 0x0000CE0A, 0x058, 0x00058750, + 0xB0000000, 0x00000000, 0x0EF, 0x00000800, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0xA0000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0005142C, 0x033, 0x00000001, + 0x03F, 0x0005142F, 0x033, 0x00000002, 0x03F, 0x00051432, + 0x033, 0x00000003, 0x03F, 0x00051C87, 0x033, 0x00000004, + 0x03F, 0x00051C8A, 0x033, 0x00000005, 0x03F, 0x00051C8D, + 0x033, 0x00000006, 0x03F, 0x00051CEB, 0x033, 0x00000007, + 0x03F, 0x00051CEE, 0x033, 0x00000008, 0x03F, 0x00051CF1, + 0x033, 0x00000009, 0x03F, 0x00051CF4, 0x033, 0x0000000A, + 0x03F, 0x00051CF7, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000010, 0x033, 0x00000000, 0x008, 0x0009C060, + 0x033, 0x00000001, 0x008, 0x0009C060, 0x0EF, 0x00000000, + 0x033, 0x000000A2, 0x0EF, 0x00080000, 0x03E, 0x0000593F, + 0x03F, 0x000C0F4F, 0x0EF, 0x00000000, 0x033, 0x000000A3, + 0x0EF, 0x00080000, 0x03E, 0x00005934, 0x03F, 0x0005AFCF, + 0x0EF, 0x00000000, + +}; + +void odm_read_and_config_mp_8822b_radiob(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_radiob) / sizeof(u32); + u32 *array = array_mp_8822b_radiob; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_rf_radio_b_8822b(dm, v1, v2); + } + } +} + +u32 odm_get_version_mp_8822b_radiob(void) { return 67; } + +/****************************************************************************** + * txpowertrack.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 10, 11, 12, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, + 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 18, 18, 18}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type0.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type0_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type0_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type0_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type0(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type1.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 10, 11, 12, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, + 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 18, 18, 18}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type1_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type1_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type1_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type1(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type2.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type2(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type3_type5.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type3_type5( + struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type4.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type4(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type6.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 21, 21, 21}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, + 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21}, + {0, 1, 2, 2, 3, 4, 4, 5, 7, 7, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 20, 20, 20, 20}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type6_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type6_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type6_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type6(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type7.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 21, 21, 21}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, + 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21}, + {0, 1, 2, 2, 3, 4, 4, 5, 7, 7, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 20, 20, 20, 20}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type7_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type7_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type7_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type7(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type8.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type8(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type9.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type9_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type9_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type9_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type9(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpwr_lmt.TXT + ******************************************************************************/ + +static const char *const array_mp_8822b_txpwr_lmt[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "01", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "01", "30", "FCC", "2.4G", "20M", "CCK", "1T", "02", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "02", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "03", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "03", "28", "MKK", "2.4G", "20M", "CCK", "1T", "03", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "04", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "04", "30", "FCC", "2.4G", "20M", "CCK", "1T", "05", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "05", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "06", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "06", "28", "MKK", "2.4G", "20M", "CCK", "1T", "06", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "07", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "07", "30", "FCC", "2.4G", "20M", "CCK", "1T", "08", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "08", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "09", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "09", "28", "MKK", "2.4G", "20M", "CCK", "1T", "09", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "10", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "10", "30", "FCC", "2.4G", "20M", "CCK", "1T", "11", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "11", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "12", "26", "ETSI", "2.4G", "20M", "CCK", "1T", + "12", "28", "MKK", "2.4G", "20M", "CCK", "1T", "12", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "20", "ETSI", "2.4G", + "20M", "CCK", "1T", "13", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "13", "28", "FCC", "2.4G", "20M", "CCK", "1T", "14", + "63", "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", "MKK", + "2.4G", "20M", "CCK", "1T", "14", "32", "FCC", "2.4G", "20M", + "OFDM", "1T", "01", "26", "ETSI", "2.4G", "20M", "OFDM", "1T", + "01", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", "ETSI", "2.4G", + "20M", "OFDM", "1T", "02", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "02", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "03", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "03", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "04", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "04", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "05", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "05", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "06", + "34", "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "06", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "07", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "07", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "08", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "08", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "09", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "09", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "10", "30", "ETSI", "2.4G", "20M", "OFDM", "1T", + "10", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", "ETSI", "2.4G", + "20M", "OFDM", "1T", "11", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "11", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "12", + "22", "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "12", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "13", "14", "ETSI", "2.4G", "20M", "OFDM", "1T", + "13", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", "ETSI", "2.4G", + "20M", "OFDM", "1T", "14", "63", "MKK", "2.4G", "20M", "OFDM", + "1T", "14", "63", "FCC", "2.4G", "20M", "HT", "1T", "01", + "26", "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", "MKK", + "2.4G", "20M", "HT", "1T", "01", "34", "FCC", "2.4G", "20M", + "HT", "1T", "02", "30", "ETSI", "2.4G", "20M", "HT", "1T", + "02", "30", "MKK", "2.4G", "20M", "HT", "1T", "02", "34", + "FCC", "2.4G", "20M", "HT", "1T", "03", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "03", "30", "MKK", "2.4G", "20M", "HT", + "1T", "03", "34", "FCC", "2.4G", "20M", "HT", "1T", "04", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", "MKK", + "2.4G", "20M", "HT", "1T", "04", "34", "FCC", "2.4G", "20M", + "HT", "1T", "05", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "05", "30", "MKK", "2.4G", "20M", "HT", "1T", "05", "34", + "FCC", "2.4G", "20M", "HT", "1T", "06", "34", "ETSI", "2.4G", + "20M", "HT", "1T", "06", "30", "MKK", "2.4G", "20M", "HT", + "1T", "06", "34", "FCC", "2.4G", "20M", "HT", "1T", "07", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", "MKK", + "2.4G", "20M", "HT", "1T", "07", "34", "FCC", "2.4G", "20M", + "HT", "1T", "08", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "08", "30", "MKK", "2.4G", "20M", "HT", "1T", "08", "34", + "FCC", "2.4G", "20M", "HT", "1T", "09", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "09", "30", "MKK", "2.4G", "20M", "HT", + "1T", "09", "34", "FCC", "2.4G", "20M", "HT", "1T", "10", + "30", "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", "MKK", + "2.4G", "20M", "HT", "1T", "10", "34", "FCC", "2.4G", "20M", + "HT", "1T", "11", "26", "ETSI", "2.4G", "20M", "HT", "1T", + "11", "30", "MKK", "2.4G", "20M", "HT", "1T", "11", "34", + "FCC", "2.4G", "20M", "HT", "1T", "12", "20", "ETSI", "2.4G", + "20M", "HT", "1T", "12", "30", "MKK", "2.4G", "20M", "HT", + "1T", "12", "34", "FCC", "2.4G", "20M", "HT", "1T", "13", + "14", "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", "MKK", + "2.4G", "20M", "HT", "1T", "13", "34", "FCC", "2.4G", "20M", + "HT", "1T", "14", "63", "ETSI", "2.4G", "20M", "HT", "1T", + "14", "63", "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "26", "ETSI", "2.4G", + "20M", "HT", "2T", "01", "18", "MKK", "2.4G", "20M", "HT", + "2T", "01", "30", "FCC", "2.4G", "20M", "HT", "2T", "02", + "28", "ETSI", "2.4G", "20M", "HT", "2T", "02", "18", "MKK", + "2.4G", "20M", "HT", "2T", "02", "30", "FCC", "2.4G", "20M", + "HT", "2T", "03", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "03", "18", "MKK", "2.4G", "20M", "HT", "2T", "03", "30", + "FCC", "2.4G", "20M", "HT", "2T", "04", "30", "ETSI", "2.4G", + "20M", "HT", "2T", "04", "18", "MKK", "2.4G", "20M", "HT", + "2T", "04", "30", "FCC", "2.4G", "20M", "HT", "2T", "05", + "32", "ETSI", "2.4G", "20M", "HT", "2T", "05", "18", "MKK", + "2.4G", "20M", "HT", "2T", "05", "30", "FCC", "2.4G", "20M", + "HT", "2T", "06", "32", "ETSI", "2.4G", "20M", "HT", "2T", + "06", "18", "MKK", "2.4G", "20M", "HT", "2T", "06", "30", + "FCC", "2.4G", "20M", "HT", "2T", "07", "32", "ETSI", "2.4G", + "20M", "HT", "2T", "07", "18", "MKK", "2.4G", "20M", "HT", + "2T", "07", "30", "FCC", "2.4G", "20M", "HT", "2T", "08", + "30", "ETSI", "2.4G", "20M", "HT", "2T", "08", "18", "MKK", + "2.4G", "20M", "HT", "2T", "08", "30", "FCC", "2.4G", "20M", + "HT", "2T", "09", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "09", "18", "MKK", "2.4G", "20M", "HT", "2T", "09", "30", + "FCC", "2.4G", "20M", "HT", "2T", "10", "28", "ETSI", "2.4G", + "20M", "HT", "2T", "10", "18", "MKK", "2.4G", "20M", "HT", + "2T", "10", "30", "FCC", "2.4G", "20M", "HT", "2T", "11", + "26", "ETSI", "2.4G", "20M", "HT", "2T", "11", "18", "MKK", + "2.4G", "20M", "HT", "2T", "11", "30", "FCC", "2.4G", "20M", + "HT", "2T", "12", "20", "ETSI", "2.4G", "20M", "HT", "2T", + "12", "18", "MKK", "2.4G", "20M", "HT", "2T", "12", "30", + "FCC", "2.4G", "20M", "HT", "2T", "13", "14", "ETSI", "2.4G", + "20M", "HT", "2T", "13", "18", "MKK", "2.4G", "20M", "HT", + "2T", "13", "30", "FCC", "2.4G", "20M", "HT", "2T", "14", + "63", "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", "MKK", + "2.4G", "20M", "HT", "2T", "14", "63", "FCC", "2.4G", "40M", + "HT", "1T", "01", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "01", "63", "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "02", "63", "MKK", "2.4G", "40M", "HT", + "1T", "02", "63", "FCC", "2.4G", "40M", "HT", "1T", "03", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", "MKK", + "2.4G", "40M", "HT", "1T", "03", "34", "FCC", "2.4G", "40M", + "HT", "1T", "04", "26", "ETSI", "2.4G", "40M", "HT", "1T", + "04", "30", "MKK", "2.4G", "40M", "HT", "1T", "04", "34", + "FCC", "2.4G", "40M", "HT", "1T", "05", "30", "ETSI", "2.4G", + "40M", "HT", "1T", "05", "30", "MKK", "2.4G", "40M", "HT", + "1T", "05", "34", "FCC", "2.4G", "40M", "HT", "1T", "06", + "32", "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", "MKK", + "2.4G", "40M", "HT", "1T", "06", "34", "FCC", "2.4G", "40M", + "HT", "1T", "07", "30", "ETSI", "2.4G", "40M", "HT", "1T", + "07", "30", "MKK", "2.4G", "40M", "HT", "1T", "07", "34", + "FCC", "2.4G", "40M", "HT", "1T", "08", "26", "ETSI", "2.4G", + "40M", "HT", "1T", "08", "30", "MKK", "2.4G", "40M", "HT", + "1T", "08", "34", "FCC", "2.4G", "40M", "HT", "1T", "09", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", "MKK", + "2.4G", "40M", "HT", "1T", "09", "34", "FCC", "2.4G", "40M", + "HT", "1T", "10", "20", "ETSI", "2.4G", "40M", "HT", "1T", + "10", "30", "MKK", "2.4G", "40M", "HT", "1T", "10", "34", + "FCC", "2.4G", "40M", "HT", "1T", "11", "14", "ETSI", "2.4G", + "40M", "HT", "1T", "11", "30", "MKK", "2.4G", "40M", "HT", + "1T", "11", "34", "FCC", "2.4G", "40M", "HT", "1T", "12", + "63", "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", "MKK", + "2.4G", "40M", "HT", "1T", "12", "63", "FCC", "2.4G", "40M", + "HT", "1T", "13", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "13", "63", "MKK", "2.4G", "40M", "HT", "1T", "13", "63", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "14", "63", "MKK", "2.4G", "40M", "HT", + "1T", "14", "63", "FCC", "2.4G", "40M", "HT", "2T", "01", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", "MKK", + "2.4G", "40M", "HT", "2T", "01", "63", "FCC", "2.4G", "40M", + "HT", "2T", "02", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "02", "63", "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "24", "ETSI", "2.4G", + "40M", "HT", "2T", "03", "18", "MKK", "2.4G", "40M", "HT", + "2T", "03", "30", "FCC", "2.4G", "40M", "HT", "2T", "04", + "24", "ETSI", "2.4G", "40M", "HT", "2T", "04", "18", "MKK", + "2.4G", "40M", "HT", "2T", "04", "30", "FCC", "2.4G", "40M", + "HT", "2T", "05", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "05", "18", "MKK", "2.4G", "40M", "HT", "2T", "05", "30", + "FCC", "2.4G", "40M", "HT", "2T", "06", "28", "ETSI", "2.4G", + "40M", "HT", "2T", "06", "18", "MKK", "2.4G", "40M", "HT", + "2T", "06", "30", "FCC", "2.4G", "40M", "HT", "2T", "07", + "26", "ETSI", "2.4G", "40M", "HT", "2T", "07", "18", "MKK", + "2.4G", "40M", "HT", "2T", "07", "30", "FCC", "2.4G", "40M", + "HT", "2T", "08", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "08", "18", "MKK", "2.4G", "40M", "HT", "2T", "08", "30", + "FCC", "2.4G", "40M", "HT", "2T", "09", "26", "ETSI", "2.4G", + "40M", "HT", "2T", "09", "18", "MKK", "2.4G", "40M", "HT", + "2T", "09", "30", "FCC", "2.4G", "40M", "HT", "2T", "10", + "20", "ETSI", "2.4G", "40M", "HT", "2T", "10", "18", "MKK", + "2.4G", "40M", "HT", "2T", "10", "30", "FCC", "2.4G", "40M", + "HT", "2T", "11", "14", "ETSI", "2.4G", "40M", "HT", "2T", + "11", "18", "MKK", "2.4G", "40M", "HT", "2T", "11", "30", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", "ETSI", "2.4G", + "40M", "HT", "2T", "12", "63", "MKK", "2.4G", "40M", "HT", + "2T", "12", "63", "FCC", "2.4G", "40M", "HT", "2T", "13", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "13", "63", "MKK", + "2.4G", "40M", "HT", "2T", "13", "63", "FCC", "2.4G", "40M", + "HT", "2T", "14", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "14", "63", "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "30", "ETSI", "5G", + "20M", "OFDM", "1T", "36", "32", "MKK", "5G", "20M", "OFDM", + "1T", "36", "30", "FCC", "5G", "20M", "OFDM", "1T", "40", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", "MKK", + "5G", "20M", "OFDM", "1T", "40", "30", "FCC", "5G", "20M", + "OFDM", "1T", "44", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "44", "32", "MKK", "5G", "20M", "OFDM", "1T", "44", "30", + "FCC", "5G", "20M", "OFDM", "1T", "48", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "48", "32", "MKK", "5G", "20M", "OFDM", + "1T", "48", "30", "FCC", "5G", "20M", "OFDM", "1T", "52", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", "MKK", + "5G", "20M", "OFDM", "1T", "52", "28", "FCC", "5G", "20M", + "OFDM", "1T", "56", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "56", "32", "MKK", "5G", "20M", "OFDM", "1T", "56", "28", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "60", "32", "MKK", "5G", "20M", "OFDM", + "1T", "60", "28", "FCC", "5G", "20M", "OFDM", "1T", "64", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", "MKK", + "5G", "20M", "OFDM", "1T", "64", "28", "FCC", "5G", "20M", + "OFDM", "1T", "100", "26", "ETSI", "5G", "20M", "OFDM", "1T", + "100", "32", "MKK", "5G", "20M", "OFDM", "1T", "100", "32", + "FCC", "5G", "20M", "OFDM", "1T", "104", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "104", "32", "MKK", "5G", "20M", "OFDM", + "1T", "104", "32", "FCC", "5G", "20M", "OFDM", "1T", "108", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", "MKK", + "5G", "20M", "OFDM", "1T", "108", "32", "FCC", "5G", "20M", + "OFDM", "1T", "112", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "112", "32", "MKK", "5G", "20M", "OFDM", "1T", "112", "32", + "FCC", "5G", "20M", "OFDM", "1T", "116", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "116", "32", "MKK", "5G", "20M", "OFDM", + "1T", "116", "32", "FCC", "5G", "20M", "OFDM", "1T", "120", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", "MKK", + "5G", "20M", "OFDM", "1T", "120", "32", "FCC", "5G", "20M", + "OFDM", "1T", "124", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "124", "32", "MKK", "5G", "20M", "OFDM", "1T", "124", "32", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "128", "32", "MKK", "5G", "20M", "OFDM", + "1T", "128", "32", "FCC", "5G", "20M", "OFDM", "1T", "132", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", "MKK", + "5G", "20M", "OFDM", "1T", "132", "32", "FCC", "5G", "20M", + "OFDM", "1T", "136", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "136", "32", "MKK", "5G", "20M", "OFDM", "1T", "136", "32", + "FCC", "5G", "20M", "OFDM", "1T", "140", "28", "ETSI", "5G", + "20M", "OFDM", "1T", "140", "32", "MKK", "5G", "20M", "OFDM", + "1T", "140", "32", "FCC", "5G", "20M", "OFDM", "1T", "144", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "144", "32", "MKK", + "5G", "20M", "OFDM", "1T", "144", "63", "FCC", "5G", "20M", + "OFDM", "1T", "149", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "149", "63", "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "153", "63", "MKK", "5G", "20M", "OFDM", + "1T", "153", "63", "FCC", "5G", "20M", "OFDM", "1T", "157", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "157", "63", "MKK", + "5G", "20M", "OFDM", "1T", "157", "63", "FCC", "5G", "20M", + "OFDM", "1T", "161", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "161", "63", "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "165", "63", "MKK", "5G", "20M", "OFDM", + "1T", "165", "63", "FCC", "5G", "20M", "HT", "1T", "36", + "30", "ETSI", "5G", "20M", "HT", "1T", "36", "32", "MKK", + "5G", "20M", "HT", "1T", "36", "28", "FCC", "5G", "20M", + "HT", "1T", "40", "32", "ETSI", "5G", "20M", "HT", "1T", + "40", "32", "MKK", "5G", "20M", "HT", "1T", "40", "28", + "FCC", "5G", "20M", "HT", "1T", "44", "32", "ETSI", "5G", + "20M", "HT", "1T", "44", "32", "MKK", "5G", "20M", "HT", + "1T", "44", "28", "FCC", "5G", "20M", "HT", "1T", "48", + "32", "ETSI", "5G", "20M", "HT", "1T", "48", "32", "MKK", + "5G", "20M", "HT", "1T", "48", "28", "FCC", "5G", "20M", + "HT", "1T", "52", "32", "ETSI", "5G", "20M", "HT", "1T", + "52", "32", "MKK", "5G", "20M", "HT", "1T", "52", "28", + "FCC", "5G", "20M", "HT", "1T", "56", "32", "ETSI", "5G", + "20M", "HT", "1T", "56", "32", "MKK", "5G", "20M", "HT", + "1T", "56", "28", "FCC", "5G", "20M", "HT", "1T", "60", + "32", "ETSI", "5G", "20M", "HT", "1T", "60", "32", "MKK", + "5G", "20M", "HT", "1T", "60", "28", "FCC", "5G", "20M", + "HT", "1T", "64", "28", "ETSI", "5G", "20M", "HT", "1T", + "64", "32", "MKK", "5G", "20M", "HT", "1T", "64", "28", + "FCC", "5G", "20M", "HT", "1T", "100", "26", "ETSI", "5G", + "20M", "HT", "1T", "100", "32", "MKK", "5G", "20M", "HT", + "1T", "100", "32", "FCC", "5G", "20M", "HT", "1T", "104", + "32", "ETSI", "5G", "20M", "HT", "1T", "104", "32", "MKK", + "5G", "20M", "HT", "1T", "104", "32", "FCC", "5G", "20M", + "HT", "1T", "108", "32", "ETSI", "5G", "20M", "HT", "1T", + "108", "32", "MKK", "5G", "20M", "HT", "1T", "108", "32", + "FCC", "5G", "20M", "HT", "1T", "112", "32", "ETSI", "5G", + "20M", "HT", "1T", "112", "32", "MKK", "5G", "20M", "HT", + "1T", "112", "32", "FCC", "5G", "20M", "HT", "1T", "116", + "32", "ETSI", "5G", "20M", "HT", "1T", "116", "32", "MKK", + "5G", "20M", "HT", "1T", "116", "32", "FCC", "5G", "20M", + "HT", "1T", "120", "32", "ETSI", "5G", "20M", "HT", "1T", + "120", "32", "MKK", "5G", "20M", "HT", "1T", "120", "32", + "FCC", "5G", "20M", "HT", "1T", "124", "32", "ETSI", "5G", + "20M", "HT", "1T", "124", "32", "MKK", "5G", "20M", "HT", + "1T", "124", "32", "FCC", "5G", "20M", "HT", "1T", "128", + "32", "ETSI", "5G", "20M", "HT", "1T", "128", "32", "MKK", + "5G", "20M", "HT", "1T", "128", "32", "FCC", "5G", "20M", + "HT", "1T", "132", "32", "ETSI", "5G", "20M", "HT", "1T", + "132", "32", "MKK", "5G", "20M", "HT", "1T", "132", "32", + "FCC", "5G", "20M", "HT", "1T", "136", "32", "ETSI", "5G", + "20M", "HT", "1T", "136", "32", "MKK", "5G", "20M", "HT", + "1T", "136", "32", "FCC", "5G", "20M", "HT", "1T", "140", + "26", "ETSI", "5G", "20M", "HT", "1T", "140", "32", "MKK", + "5G", "20M", "HT", "1T", "140", "32", "FCC", "5G", "20M", + "HT", "1T", "144", "26", "ETSI", "5G", "20M", "HT", "1T", + "144", "63", "MKK", "5G", "20M", "HT", "1T", "144", "63", + "FCC", "5G", "20M", "HT", "1T", "149", "32", "ETSI", "5G", + "20M", "HT", "1T", "149", "63", "MKK", "5G", "20M", "HT", + "1T", "149", "63", "FCC", "5G", "20M", "HT", "1T", "153", + "32", "ETSI", "5G", "20M", "HT", "1T", "153", "63", "MKK", + "5G", "20M", "HT", "1T", "153", "63", "FCC", "5G", "20M", + "HT", "1T", "157", "32", "ETSI", "5G", "20M", "HT", "1T", + "157", "63", "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "32", "ETSI", "5G", + "20M", "HT", "1T", "161", "63", "MKK", "5G", "20M", "HT", + "1T", "161", "63", "FCC", "5G", "20M", "HT", "1T", "165", + "32", "ETSI", "5G", "20M", "HT", "1T", "165", "63", "MKK", + "5G", "20M", "HT", "1T", "165", "63", "FCC", "5G", "20M", + "HT", "2T", "36", "28", "ETSI", "5G", "20M", "HT", "2T", + "36", "20", "MKK", "5G", "20M", "HT", "2T", "36", "22", + "FCC", "5G", "20M", "HT", "2T", "40", "30", "ETSI", "5G", + "20M", "HT", "2T", "40", "20", "MKK", "5G", "20M", "HT", + "2T", "40", "22", "FCC", "5G", "20M", "HT", "2T", "44", + "30", "ETSI", "5G", "20M", "HT", "2T", "44", "20", "MKK", + "5G", "20M", "HT", "2T", "44", "22", "FCC", "5G", "20M", + "HT", "2T", "48", "30", "ETSI", "5G", "20M", "HT", "2T", + "48", "20", "MKK", "5G", "20M", "HT", "2T", "48", "22", + "FCC", "5G", "20M", "HT", "2T", "52", "30", "ETSI", "5G", + "20M", "HT", "2T", "52", "20", "MKK", "5G", "20M", "HT", + "2T", "52", "22", "FCC", "5G", "20M", "HT", "2T", "56", + "30", "ETSI", "5G", "20M", "HT", "2T", "56", "20", "MKK", + "5G", "20M", "HT", "2T", "56", "22", "FCC", "5G", "20M", + "HT", "2T", "60", "30", "ETSI", "5G", "20M", "HT", "2T", + "60", "20", "MKK", "5G", "20M", "HT", "2T", "60", "22", + "FCC", "5G", "20M", "HT", "2T", "64", "28", "ETSI", "5G", + "20M", "HT", "2T", "64", "20", "MKK", "5G", "20M", "HT", + "2T", "64", "22", "FCC", "5G", "20M", "HT", "2T", "100", + "26", "ETSI", "5G", "20M", "HT", "2T", "100", "20", "MKK", + "5G", "20M", "HT", "2T", "100", "30", "FCC", "5G", "20M", + "HT", "2T", "104", "30", "ETSI", "5G", "20M", "HT", "2T", + "104", "20", "MKK", "5G", "20M", "HT", "2T", "104", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "32", "ETSI", "5G", + "20M", "HT", "2T", "108", "20", "MKK", "5G", "20M", "HT", + "2T", "108", "30", "FCC", "5G", "20M", "HT", "2T", "112", + "32", "ETSI", "5G", "20M", "HT", "2T", "112", "20", "MKK", + "5G", "20M", "HT", "2T", "112", "30", "FCC", "5G", "20M", + "HT", "2T", "116", "32", "ETSI", "5G", "20M", "HT", "2T", + "116", "20", "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "32", "ETSI", "5G", + "20M", "HT", "2T", "120", "20", "MKK", "5G", "20M", "HT", + "2T", "120", "30", "FCC", "5G", "20M", "HT", "2T", "124", + "32", "ETSI", "5G", "20M", "HT", "2T", "124", "20", "MKK", + "5G", "20M", "HT", "2T", "124", "30", "FCC", "5G", "20M", + "HT", "2T", "128", "32", "ETSI", "5G", "20M", "HT", "2T", + "128", "20", "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "32", "ETSI", "5G", + "20M", "HT", "2T", "132", "20", "MKK", "5G", "20M", "HT", + "2T", "132", "30", "FCC", "5G", "20M", "HT", "2T", "136", + "30", "ETSI", "5G", "20M", "HT", "2T", "136", "20", "MKK", + "5G", "20M", "HT", "2T", "136", "30", "FCC", "5G", "20M", + "HT", "2T", "140", "26", "ETSI", "5G", "20M", "HT", "2T", + "140", "20", "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "144", "26", "ETSI", "5G", + "20M", "HT", "2T", "144", "63", "MKK", "5G", "20M", "HT", + "2T", "144", "63", "FCC", "5G", "20M", "HT", "2T", "149", + "32", "ETSI", "5G", "20M", "HT", "2T", "149", "63", "MKK", + "5G", "20M", "HT", "2T", "149", "63", "FCC", "5G", "20M", + "HT", "2T", "153", "32", "ETSI", "5G", "20M", "HT", "2T", + "153", "63", "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "32", "ETSI", "5G", + "20M", "HT", "2T", "157", "63", "MKK", "5G", "20M", "HT", + "2T", "157", "63", "FCC", "5G", "20M", "HT", "2T", "161", + "32", "ETSI", "5G", "20M", "HT", "2T", "161", "63", "MKK", + "5G", "20M", "HT", "2T", "161", "63", "FCC", "5G", "20M", + "HT", "2T", "165", "32", "ETSI", "5G", "20M", "HT", "2T", + "165", "63", "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "22", "ETSI", "5G", + "40M", "HT", "1T", "38", "30", "MKK", "5G", "40M", "HT", + "1T", "38", "30", "FCC", "5G", "40M", "HT", "1T", "46", + "30", "ETSI", "5G", "40M", "HT", "1T", "46", "30", "MKK", + "5G", "40M", "HT", "1T", "46", "30", "FCC", "5G", "40M", + "HT", "1T", "54", "30", "ETSI", "5G", "40M", "HT", "1T", + "54", "30", "MKK", "5G", "40M", "HT", "1T", "54", "30", + "FCC", "5G", "40M", "HT", "1T", "62", "24", "ETSI", "5G", + "40M", "HT", "1T", "62", "30", "MKK", "5G", "40M", "HT", + "1T", "62", "30", "FCC", "5G", "40M", "HT", "1T", "102", + "24", "ETSI", "5G", "40M", "HT", "1T", "102", "30", "MKK", + "5G", "40M", "HT", "1T", "102", "30", "FCC", "5G", "40M", + "HT", "1T", "110", "30", "ETSI", "5G", "40M", "HT", "1T", + "110", "30", "MKK", "5G", "40M", "HT", "1T", "110", "30", + "FCC", "5G", "40M", "HT", "1T", "118", "30", "ETSI", "5G", + "40M", "HT", "1T", "118", "30", "MKK", "5G", "40M", "HT", + "1T", "118", "30", "FCC", "5G", "40M", "HT", "1T", "126", + "30", "ETSI", "5G", "40M", "HT", "1T", "126", "30", "MKK", + "5G", "40M", "HT", "1T", "126", "30", "FCC", "5G", "40M", + "HT", "1T", "134", "30", "ETSI", "5G", "40M", "HT", "1T", + "134", "30", "MKK", "5G", "40M", "HT", "1T", "134", "30", + "FCC", "5G", "40M", "HT", "1T", "142", "30", "ETSI", "5G", + "40M", "HT", "1T", "142", "63", "MKK", "5G", "40M", "HT", + "1T", "142", "63", "FCC", "5G", "40M", "HT", "1T", "151", + "30", "ETSI", "5G", "40M", "HT", "1T", "151", "63", "MKK", + "5G", "40M", "HT", "1T", "151", "63", "FCC", "5G", "40M", + "HT", "1T", "159", "30", "ETSI", "5G", "40M", "HT", "1T", + "159", "63", "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "20", "ETSI", "5G", + "40M", "HT", "2T", "38", "20", "MKK", "5G", "40M", "HT", + "2T", "38", "22", "FCC", "5G", "40M", "HT", "2T", "46", + "30", "ETSI", "5G", "40M", "HT", "2T", "46", "20", "MKK", + "5G", "40M", "HT", "2T", "46", "22", "FCC", "5G", "40M", + "HT", "2T", "54", "30", "ETSI", "5G", "40M", "HT", "2T", + "54", "20", "MKK", "5G", "40M", "HT", "2T", "54", "22", + "FCC", "5G", "40M", "HT", "2T", "62", "22", "ETSI", "5G", + "40M", "HT", "2T", "62", "20", "MKK", "5G", "40M", "HT", + "2T", "62", "22", "FCC", "5G", "40M", "HT", "2T", "102", + "22", "ETSI", "5G", "40M", "HT", "2T", "102", "20", "MKK", + "5G", "40M", "HT", "2T", "102", "30", "FCC", "5G", "40M", + "HT", "2T", "110", "30", "ETSI", "5G", "40M", "HT", "2T", + "110", "20", "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "30", "ETSI", "5G", + "40M", "HT", "2T", "118", "20", "MKK", "5G", "40M", "HT", + "2T", "118", "30", "FCC", "5G", "40M", "HT", "2T", "126", + "30", "ETSI", "5G", "40M", "HT", "2T", "126", "20", "MKK", + "5G", "40M", "HT", "2T", "126", "30", "FCC", "5G", "40M", + "HT", "2T", "134", "30", "ETSI", "5G", "40M", "HT", "2T", + "134", "20", "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "142", "30", "ETSI", "5G", + "40M", "HT", "2T", "142", "63", "MKK", "5G", "40M", "HT", + "2T", "142", "63", "FCC", "5G", "40M", "HT", "2T", "151", + "30", "ETSI", "5G", "40M", "HT", "2T", "151", "63", "MKK", + "5G", "40M", "HT", "2T", "151", "63", "FCC", "5G", "40M", + "HT", "2T", "159", "30", "ETSI", "5G", "40M", "HT", "2T", + "159", "63", "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "20", "ETSI", "5G", + "80M", "VHT", "1T", "42", "30", "MKK", "5G", "80M", "VHT", + "1T", "42", "28", "FCC", "5G", "80M", "VHT", "1T", "58", + "20", "ETSI", "5G", "80M", "VHT", "1T", "58", "30", "MKK", + "5G", "80M", "VHT", "1T", "58", "28", "FCC", "5G", "80M", + "VHT", "1T", "106", "20", "ETSI", "5G", "80M", "VHT", "1T", + "106", "30", "MKK", "5G", "80M", "VHT", "1T", "106", "30", + "FCC", "5G", "80M", "VHT", "1T", "122", "30", "ETSI", "5G", + "80M", "VHT", "1T", "122", "30", "MKK", "5G", "80M", "VHT", + "1T", "122", "30", "FCC", "5G", "80M", "VHT", "1T", "138", + "30", "ETSI", "5G", "80M", "VHT", "1T", "138", "63", "MKK", + "5G", "80M", "VHT", "1T", "138", "63", "FCC", "5G", "80M", + "VHT", "1T", "155", "30", "ETSI", "5G", "80M", "VHT", "1T", + "155", "63", "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "18", "ETSI", "5G", + "80M", "VHT", "2T", "42", "20", "MKK", "5G", "80M", "VHT", + "2T", "42", "22", "FCC", "5G", "80M", "VHT", "2T", "58", + "18", "ETSI", "5G", "80M", "VHT", "2T", "58", "20", "MKK", + "5G", "80M", "VHT", "2T", "58", "22", "FCC", "5G", "80M", + "VHT", "2T", "106", "20", "ETSI", "5G", "80M", "VHT", "2T", + "106", "20", "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "30", "ETSI", "5G", + "80M", "VHT", "2T", "122", "20", "MKK", "5G", "80M", "VHT", + "2T", "122", "30", "FCC", "5G", "80M", "VHT", "2T", "138", + "30", "ETSI", "5G", "80M", "VHT", "2T", "138", "63", "MKK", + "5G", "80M", "VHT", "2T", "138", "63", "FCC", "5G", "80M", + "VHT", "2T", "155", "30", "ETSI", "5G", "80M", "VHT", "2T", + "155", "63", "MKK", "5G", "80M", "VHT", "2T", "155", "63"}; + +void odm_read_and_config_mp_8822b_txpwr_lmt(struct phy_dm_struct *dm) +{ + u32 i = 0; + u32 array_len = sizeof(array_mp_8822b_txpwr_lmt) / sizeof(u8 *); + u8 **array = (u8 **)array_mp_8822b_txpwr_lmt; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (i = 0; i < array_len; i += 7) { + u8 *regulation = array[i]; + u8 *band = array[i + 1]; + u8 *bandwidth = array[i + 2]; + u8 *rate = array[i + 3]; + u8 *rf_path = array[i + 4]; + u8 *chnl = array[i + 5]; + u8 *val = array[i + 6]; + + odm_config_bb_txpwr_lmt_8822b(dm, regulation, band, bandwidth, + rate, rf_path, chnl, val); + } +} + +/****************************************************************************** +* txpwr_lmt_type5.TXT +******************************************************************************/ + +static const char *const array_mp_8822b_txpwr_lmt_type5[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "01", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "01", "30", "FCC", "2.4G", "20M", "CCK", "1T", "02", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "02", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "03", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "03", "28", "MKK", "2.4G", "20M", "CCK", "1T", "03", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "04", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "04", "30", "FCC", "2.4G", "20M", "CCK", "1T", "05", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "05", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "06", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "06", "28", "MKK", "2.4G", "20M", "CCK", "1T", "06", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "07", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "07", "30", "FCC", "2.4G", "20M", "CCK", "1T", "08", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "08", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "09", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "09", "28", "MKK", "2.4G", "20M", "CCK", "1T", "09", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "10", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "10", "30", "FCC", "2.4G", "20M", "CCK", "1T", "11", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "11", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "12", "26", "ETSI", "2.4G", "20M", "CCK", "1T", + "12", "28", "MKK", "2.4G", "20M", "CCK", "1T", "12", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "20", "ETSI", "2.4G", + "20M", "CCK", "1T", "13", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "13", "28", "FCC", "2.4G", "20M", "CCK", "1T", "14", + "63", "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", "MKK", + "2.4G", "20M", "CCK", "1T", "14", "32", "FCC", "2.4G", "20M", + "OFDM", "1T", "01", "26", "ETSI", "2.4G", "20M", "OFDM", "1T", + "01", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", "ETSI", "2.4G", + "20M", "OFDM", "1T", "02", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "02", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "03", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "03", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "04", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "04", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "05", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "05", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "06", + "34", "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "06", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "07", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "07", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "08", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "08", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "09", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "09", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "10", "30", "ETSI", "2.4G", "20M", "OFDM", "1T", + "10", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", "ETSI", "2.4G", + "20M", "OFDM", "1T", "11", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "11", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "12", + "22", "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "12", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "13", "14", "ETSI", "2.4G", "20M", "OFDM", "1T", + "13", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", "ETSI", "2.4G", + "20M", "OFDM", "1T", "14", "63", "MKK", "2.4G", "20M", "OFDM", + "1T", "14", "63", "FCC", "2.4G", "20M", "HT", "1T", "01", + "26", "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", "MKK", + "2.4G", "20M", "HT", "1T", "01", "34", "FCC", "2.4G", "20M", + "HT", "1T", "02", "30", "ETSI", "2.4G", "20M", "HT", "1T", + "02", "30", "MKK", "2.4G", "20M", "HT", "1T", "02", "34", + "FCC", "2.4G", "20M", "HT", "1T", "03", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "03", "30", "MKK", "2.4G", "20M", "HT", + "1T", "03", "34", "FCC", "2.4G", "20M", "HT", "1T", "04", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", "MKK", + "2.4G", "20M", "HT", "1T", "04", "34", "FCC", "2.4G", "20M", + "HT", "1T", "05", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "05", "30", "MKK", "2.4G", "20M", "HT", "1T", "05", "34", + "FCC", "2.4G", "20M", "HT", "1T", "06", "34", "ETSI", "2.4G", + "20M", "HT", "1T", "06", "30", "MKK", "2.4G", "20M", "HT", + "1T", "06", "34", "FCC", "2.4G", "20M", "HT", "1T", "07", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", "MKK", + "2.4G", "20M", "HT", "1T", "07", "34", "FCC", "2.4G", "20M", + "HT", "1T", "08", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "08", "30", "MKK", "2.4G", "20M", "HT", "1T", "08", "34", + "FCC", "2.4G", "20M", "HT", "1T", "09", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "09", "30", "MKK", "2.4G", "20M", "HT", + "1T", "09", "34", "FCC", "2.4G", "20M", "HT", "1T", "10", + "30", "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", "MKK", + "2.4G", "20M", "HT", "1T", "10", "34", "FCC", "2.4G", "20M", + "HT", "1T", "11", "26", "ETSI", "2.4G", "20M", "HT", "1T", + "11", "30", "MKK", "2.4G", "20M", "HT", "1T", "11", "34", + "FCC", "2.4G", "20M", "HT", "1T", "12", "20", "ETSI", "2.4G", + "20M", "HT", "1T", "12", "30", "MKK", "2.4G", "20M", "HT", + "1T", "12", "34", "FCC", "2.4G", "20M", "HT", "1T", "13", + "14", "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", "MKK", + "2.4G", "20M", "HT", "1T", "13", "34", "FCC", "2.4G", "20M", + "HT", "1T", "14", "63", "ETSI", "2.4G", "20M", "HT", "1T", + "14", "63", "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "26", "ETSI", "2.4G", + "20M", "HT", "2T", "01", "18", "MKK", "2.4G", "20M", "HT", + "2T", "01", "30", "FCC", "2.4G", "20M", "HT", "2T", "02", + "28", "ETSI", "2.4G", "20M", "HT", "2T", "02", "18", "MKK", + "2.4G", "20M", "HT", "2T", "02", "30", "FCC", "2.4G", "20M", + "HT", "2T", "03", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "03", "18", "MKK", "2.4G", "20M", "HT", "2T", "03", "30", + "FCC", "2.4G", "20M", "HT", "2T", "04", "30", "ETSI", "2.4G", + "20M", "HT", "2T", "04", "18", "MKK", "2.4G", "20M", "HT", + "2T", "04", "30", "FCC", "2.4G", "20M", "HT", "2T", "05", + "32", "ETSI", "2.4G", "20M", "HT", "2T", "05", "18", "MKK", + "2.4G", "20M", "HT", "2T", "05", "30", "FCC", "2.4G", "20M", + "HT", "2T", "06", "32", "ETSI", "2.4G", "20M", "HT", "2T", + "06", "18", "MKK", "2.4G", "20M", "HT", "2T", "06", "30", + "FCC", "2.4G", "20M", "HT", "2T", "07", "32", "ETSI", "2.4G", + "20M", "HT", "2T", "07", "18", "MKK", "2.4G", "20M", "HT", + "2T", "07", "30", "FCC", "2.4G", "20M", "HT", "2T", "08", + "30", "ETSI", "2.4G", "20M", "HT", "2T", "08", "18", "MKK", + "2.4G", "20M", "HT", "2T", "08", "30", "FCC", "2.4G", "20M", + "HT", "2T", "09", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "09", "18", "MKK", "2.4G", "20M", "HT", "2T", "09", "30", + "FCC", "2.4G", "20M", "HT", "2T", "10", "28", "ETSI", "2.4G", + "20M", "HT", "2T", "10", "18", "MKK", "2.4G", "20M", "HT", + "2T", "10", "30", "FCC", "2.4G", "20M", "HT", "2T", "11", + "26", "ETSI", "2.4G", "20M", "HT", "2T", "11", "18", "MKK", + "2.4G", "20M", "HT", "2T", "11", "30", "FCC", "2.4G", "20M", + "HT", "2T", "12", "20", "ETSI", "2.4G", "20M", "HT", "2T", + "12", "18", "MKK", "2.4G", "20M", "HT", "2T", "12", "30", + "FCC", "2.4G", "20M", "HT", "2T", "13", "14", "ETSI", "2.4G", + "20M", "HT", "2T", "13", "18", "MKK", "2.4G", "20M", "HT", + "2T", "13", "30", "FCC", "2.4G", "20M", "HT", "2T", "14", + "63", "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", "MKK", + "2.4G", "20M", "HT", "2T", "14", "63", "FCC", "2.4G", "40M", + "HT", "1T", "01", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "01", "63", "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "02", "63", "MKK", "2.4G", "40M", "HT", + "1T", "02", "63", "FCC", "2.4G", "40M", "HT", "1T", "03", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", "MKK", + "2.4G", "40M", "HT", "1T", "03", "34", "FCC", "2.4G", "40M", + "HT", "1T", "04", "26", "ETSI", "2.4G", "40M", "HT", "1T", + "04", "30", "MKK", "2.4G", "40M", "HT", "1T", "04", "34", + "FCC", "2.4G", "40M", "HT", "1T", "05", "30", "ETSI", "2.4G", + "40M", "HT", "1T", "05", "30", "MKK", "2.4G", "40M", "HT", + "1T", "05", "34", "FCC", "2.4G", "40M", "HT", "1T", "06", + "32", "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", "MKK", + "2.4G", "40M", "HT", "1T", "06", "34", "FCC", "2.4G", "40M", + "HT", "1T", "07", "30", "ETSI", "2.4G", "40M", "HT", "1T", + "07", "30", "MKK", "2.4G", "40M", "HT", "1T", "07", "34", + "FCC", "2.4G", "40M", "HT", "1T", "08", "26", "ETSI", "2.4G", + "40M", "HT", "1T", "08", "30", "MKK", "2.4G", "40M", "HT", + "1T", "08", "34", "FCC", "2.4G", "40M", "HT", "1T", "09", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", "MKK", + "2.4G", "40M", "HT", "1T", "09", "34", "FCC", "2.4G", "40M", + "HT", "1T", "10", "20", "ETSI", "2.4G", "40M", "HT", "1T", + "10", "30", "MKK", "2.4G", "40M", "HT", "1T", "10", "34", + "FCC", "2.4G", "40M", "HT", "1T", "11", "14", "ETSI", "2.4G", + "40M", "HT", "1T", "11", "30", "MKK", "2.4G", "40M", "HT", + "1T", "11", "34", "FCC", "2.4G", "40M", "HT", "1T", "12", + "63", "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", "MKK", + "2.4G", "40M", "HT", "1T", "12", "63", "FCC", "2.4G", "40M", + "HT", "1T", "13", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "13", "63", "MKK", "2.4G", "40M", "HT", "1T", "13", "63", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "14", "63", "MKK", "2.4G", "40M", "HT", + "1T", "14", "63", "FCC", "2.4G", "40M", "HT", "2T", "01", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", "MKK", + "2.4G", "40M", "HT", "2T", "01", "63", "FCC", "2.4G", "40M", + "HT", "2T", "02", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "02", "63", "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "24", "ETSI", "2.4G", + "40M", "HT", "2T", "03", "18", "MKK", "2.4G", "40M", "HT", + "2T", "03", "30", "FCC", "2.4G", "40M", "HT", "2T", "04", + "24", "ETSI", "2.4G", "40M", "HT", "2T", "04", "18", "MKK", + "2.4G", "40M", "HT", "2T", "04", "30", "FCC", "2.4G", "40M", + "HT", "2T", "05", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "05", "18", "MKK", "2.4G", "40M", "HT", "2T", "05", "30", + "FCC", "2.4G", "40M", "HT", "2T", "06", "28", "ETSI", "2.4G", + "40M", "HT", "2T", "06", "18", "MKK", "2.4G", "40M", "HT", + "2T", "06", "30", "FCC", "2.4G", "40M", "HT", "2T", "07", + "26", "ETSI", "2.4G", "40M", "HT", "2T", "07", "18", "MKK", + "2.4G", "40M", "HT", "2T", "07", "30", "FCC", "2.4G", "40M", + "HT", "2T", "08", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "08", "18", "MKK", "2.4G", "40M", "HT", "2T", "08", "30", + "FCC", "2.4G", "40M", "HT", "2T", "09", "26", "ETSI", "2.4G", + "40M", "HT", "2T", "09", "18", "MKK", "2.4G", "40M", "HT", + "2T", "09", "30", "FCC", "2.4G", "40M", "HT", "2T", "10", + "20", "ETSI", "2.4G", "40M", "HT", "2T", "10", "18", "MKK", + "2.4G", "40M", "HT", "2T", "10", "30", "FCC", "2.4G", "40M", + "HT", "2T", "11", "14", "ETSI", "2.4G", "40M", "HT", "2T", + "11", "18", "MKK", "2.4G", "40M", "HT", "2T", "11", "30", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", "ETSI", "2.4G", + "40M", "HT", "2T", "12", "63", "MKK", "2.4G", "40M", "HT", + "2T", "12", "63", "FCC", "2.4G", "40M", "HT", "2T", "13", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "13", "63", "MKK", + "2.4G", "40M", "HT", "2T", "13", "63", "FCC", "2.4G", "40M", + "HT", "2T", "14", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "14", "63", "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "30", "ETSI", "5G", + "20M", "OFDM", "1T", "36", "32", "MKK", "5G", "20M", "OFDM", + "1T", "36", "30", "FCC", "5G", "20M", "OFDM", "1T", "40", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", "MKK", + "5G", "20M", "OFDM", "1T", "40", "30", "FCC", "5G", "20M", + "OFDM", "1T", "44", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "44", "32", "MKK", "5G", "20M", "OFDM", "1T", "44", "30", + "FCC", "5G", "20M", "OFDM", "1T", "48", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "48", "32", "MKK", "5G", "20M", "OFDM", + "1T", "48", "30", "FCC", "5G", "20M", "OFDM", "1T", "52", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", "MKK", + "5G", "20M", "OFDM", "1T", "52", "28", "FCC", "5G", "20M", + "OFDM", "1T", "56", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "56", "32", "MKK", "5G", "20M", "OFDM", "1T", "56", "28", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "60", "32", "MKK", "5G", "20M", "OFDM", + "1T", "60", "28", "FCC", "5G", "20M", "OFDM", "1T", "64", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", "MKK", + "5G", "20M", "OFDM", "1T", "64", "28", "FCC", "5G", "20M", + "OFDM", "1T", "100", "26", "ETSI", "5G", "20M", "OFDM", "1T", + "100", "32", "MKK", "5G", "20M", "OFDM", "1T", "100", "32", + "FCC", "5G", "20M", "OFDM", "1T", "104", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "104", "32", "MKK", "5G", "20M", "OFDM", + "1T", "104", "32", "FCC", "5G", "20M", "OFDM", "1T", "108", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", "MKK", + "5G", "20M", "OFDM", "1T", "108", "32", "FCC", "5G", "20M", + "OFDM", "1T", "112", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "112", "32", "MKK", "5G", "20M", "OFDM", "1T", "112", "32", + "FCC", "5G", "20M", "OFDM", "1T", "116", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "116", "32", "MKK", "5G", "20M", "OFDM", + "1T", "116", "32", "FCC", "5G", "20M", "OFDM", "1T", "120", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", "MKK", + "5G", "20M", "OFDM", "1T", "120", "32", "FCC", "5G", "20M", + "OFDM", "1T", "124", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "124", "32", "MKK", "5G", "20M", "OFDM", "1T", "124", "32", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "128", "32", "MKK", "5G", "20M", "OFDM", + "1T", "128", "32", "FCC", "5G", "20M", "OFDM", "1T", "132", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", "MKK", + "5G", "20M", "OFDM", "1T", "132", "32", "FCC", "5G", "20M", + "OFDM", "1T", "136", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "136", "32", "MKK", "5G", "20M", "OFDM", "1T", "136", "32", + "FCC", "5G", "20M", "OFDM", "1T", "140", "28", "ETSI", "5G", + "20M", "OFDM", "1T", "140", "32", "MKK", "5G", "20M", "OFDM", + "1T", "140", "32", "FCC", "5G", "20M", "OFDM", "1T", "144", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "144", "32", "MKK", + "5G", "20M", "OFDM", "1T", "144", "63", "FCC", "5G", "20M", + "OFDM", "1T", "149", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "149", "63", "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "153", "63", "MKK", "5G", "20M", "OFDM", + "1T", "153", "63", "FCC", "5G", "20M", "OFDM", "1T", "157", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "157", "63", "MKK", + "5G", "20M", "OFDM", "1T", "157", "63", "FCC", "5G", "20M", + "OFDM", "1T", "161", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "161", "63", "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "165", "63", "MKK", "5G", "20M", "OFDM", + "1T", "165", "63", "FCC", "5G", "20M", "HT", "1T", "36", + "30", "ETSI", "5G", "20M", "HT", "1T", "36", "32", "MKK", + "5G", "20M", "HT", "1T", "36", "28", "FCC", "5G", "20M", + "HT", "1T", "40", "32", "ETSI", "5G", "20M", "HT", "1T", + "40", "32", "MKK", "5G", "20M", "HT", "1T", "40", "28", + "FCC", "5G", "20M", "HT", "1T", "44", "32", "ETSI", "5G", + "20M", "HT", "1T", "44", "32", "MKK", "5G", "20M", "HT", + "1T", "44", "28", "FCC", "5G", "20M", "HT", "1T", "48", + "32", "ETSI", "5G", "20M", "HT", "1T", "48", "32", "MKK", + "5G", "20M", "HT", "1T", "48", "28", "FCC", "5G", "20M", + "HT", "1T", "52", "32", "ETSI", "5G", "20M", "HT", "1T", + "52", "32", "MKK", "5G", "20M", "HT", "1T", "52", "28", + "FCC", "5G", "20M", "HT", "1T", "56", "32", "ETSI", "5G", + "20M", "HT", "1T", "56", "32", "MKK", "5G", "20M", "HT", + "1T", "56", "28", "FCC", "5G", "20M", "HT", "1T", "60", + "32", "ETSI", "5G", "20M", "HT", "1T", "60", "32", "MKK", + "5G", "20M", "HT", "1T", "60", "28", "FCC", "5G", "20M", + "HT", "1T", "64", "28", "ETSI", "5G", "20M", "HT", "1T", + "64", "32", "MKK", "5G", "20M", "HT", "1T", "64", "28", + "FCC", "5G", "20M", "HT", "1T", "100", "26", "ETSI", "5G", + "20M", "HT", "1T", "100", "32", "MKK", "5G", "20M", "HT", + "1T", "100", "32", "FCC", "5G", "20M", "HT", "1T", "104", + "32", "ETSI", "5G", "20M", "HT", "1T", "104", "32", "MKK", + "5G", "20M", "HT", "1T", "104", "32", "FCC", "5G", "20M", + "HT", "1T", "108", "32", "ETSI", "5G", "20M", "HT", "1T", + "108", "32", "MKK", "5G", "20M", "HT", "1T", "108", "32", + "FCC", "5G", "20M", "HT", "1T", "112", "32", "ETSI", "5G", + "20M", "HT", "1T", "112", "32", "MKK", "5G", "20M", "HT", + "1T", "112", "32", "FCC", "5G", "20M", "HT", "1T", "116", + "32", "ETSI", "5G", "20M", "HT", "1T", "116", "32", "MKK", + "5G", "20M", "HT", "1T", "116", "32", "FCC", "5G", "20M", + "HT", "1T", "120", "32", "ETSI", "5G", "20M", "HT", "1T", + "120", "32", "MKK", "5G", "20M", "HT", "1T", "120", "32", + "FCC", "5G", "20M", "HT", "1T", "124", "32", "ETSI", "5G", + "20M", "HT", "1T", "124", "32", "MKK", "5G", "20M", "HT", + "1T", "124", "32", "FCC", "5G", "20M", "HT", "1T", "128", + "32", "ETSI", "5G", "20M", "HT", "1T", "128", "32", "MKK", + "5G", "20M", "HT", "1T", "128", "32", "FCC", "5G", "20M", + "HT", "1T", "132", "32", "ETSI", "5G", "20M", "HT", "1T", + "132", "32", "MKK", "5G", "20M", "HT", "1T", "132", "32", + "FCC", "5G", "20M", "HT", "1T", "136", "32", "ETSI", "5G", + "20M", "HT", "1T", "136", "32", "MKK", "5G", "20M", "HT", + "1T", "136", "32", "FCC", "5G", "20M", "HT", "1T", "140", + "26", "ETSI", "5G", "20M", "HT", "1T", "140", "32", "MKK", + "5G", "20M", "HT", "1T", "140", "32", "FCC", "5G", "20M", + "HT", "1T", "144", "26", "ETSI", "5G", "20M", "HT", "1T", + "144", "63", "MKK", "5G", "20M", "HT", "1T", "144", "63", + "FCC", "5G", "20M", "HT", "1T", "149", "32", "ETSI", "5G", + "20M", "HT", "1T", "149", "63", "MKK", "5G", "20M", "HT", + "1T", "149", "63", "FCC", "5G", "20M", "HT", "1T", "153", + "32", "ETSI", "5G", "20M", "HT", "1T", "153", "63", "MKK", + "5G", "20M", "HT", "1T", "153", "63", "FCC", "5G", "20M", + "HT", "1T", "157", "32", "ETSI", "5G", "20M", "HT", "1T", + "157", "63", "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "32", "ETSI", "5G", + "20M", "HT", "1T", "161", "63", "MKK", "5G", "20M", "HT", + "1T", "161", "63", "FCC", "5G", "20M", "HT", "1T", "165", + "32", "ETSI", "5G", "20M", "HT", "1T", "165", "63", "MKK", + "5G", "20M", "HT", "1T", "165", "63", "FCC", "5G", "20M", + "HT", "2T", "36", "28", "ETSI", "5G", "20M", "HT", "2T", + "36", "20", "MKK", "5G", "20M", "HT", "2T", "36", "22", + "FCC", "5G", "20M", "HT", "2T", "40", "30", "ETSI", "5G", + "20M", "HT", "2T", "40", "20", "MKK", "5G", "20M", "HT", + "2T", "40", "22", "FCC", "5G", "20M", "HT", "2T", "44", + "30", "ETSI", "5G", "20M", "HT", "2T", "44", "20", "MKK", + "5G", "20M", "HT", "2T", "44", "22", "FCC", "5G", "20M", + "HT", "2T", "48", "30", "ETSI", "5G", "20M", "HT", "2T", + "48", "20", "MKK", "5G", "20M", "HT", "2T", "48", "22", + "FCC", "5G", "20M", "HT", "2T", "52", "30", "ETSI", "5G", + "20M", "HT", "2T", "52", "20", "MKK", "5G", "20M", "HT", + "2T", "52", "22", "FCC", "5G", "20M", "HT", "2T", "56", + "30", "ETSI", "5G", "20M", "HT", "2T", "56", "20", "MKK", + "5G", "20M", "HT", "2T", "56", "22", "FCC", "5G", "20M", + "HT", "2T", "60", "30", "ETSI", "5G", "20M", "HT", "2T", + "60", "20", "MKK", "5G", "20M", "HT", "2T", "60", "22", + "FCC", "5G", "20M", "HT", "2T", "64", "28", "ETSI", "5G", + "20M", "HT", "2T", "64", "20", "MKK", "5G", "20M", "HT", + "2T", "64", "22", "FCC", "5G", "20M", "HT", "2T", "100", + "26", "ETSI", "5G", "20M", "HT", "2T", "100", "20", "MKK", + "5G", "20M", "HT", "2T", "100", "30", "FCC", "5G", "20M", + "HT", "2T", "104", "30", "ETSI", "5G", "20M", "HT", "2T", + "104", "20", "MKK", "5G", "20M", "HT", "2T", "104", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "32", "ETSI", "5G", + "20M", "HT", "2T", "108", "20", "MKK", "5G", "20M", "HT", + "2T", "108", "30", "FCC", "5G", "20M", "HT", "2T", "112", + "32", "ETSI", "5G", "20M", "HT", "2T", "112", "20", "MKK", + "5G", "20M", "HT", "2T", "112", "30", "FCC", "5G", "20M", + "HT", "2T", "116", "32", "ETSI", "5G", "20M", "HT", "2T", + "116", "20", "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "32", "ETSI", "5G", + "20M", "HT", "2T", "120", "20", "MKK", "5G", "20M", "HT", + "2T", "120", "30", "FCC", "5G", "20M", "HT", "2T", "124", + "32", "ETSI", "5G", "20M", "HT", "2T", "124", "20", "MKK", + "5G", "20M", "HT", "2T", "124", "30", "FCC", "5G", "20M", + "HT", "2T", "128", "32", "ETSI", "5G", "20M", "HT", "2T", + "128", "20", "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "32", "ETSI", "5G", + "20M", "HT", "2T", "132", "20", "MKK", "5G", "20M", "HT", + "2T", "132", "30", "FCC", "5G", "20M", "HT", "2T", "136", + "30", "ETSI", "5G", "20M", "HT", "2T", "136", "20", "MKK", + "5G", "20M", "HT", "2T", "136", "30", "FCC", "5G", "20M", + "HT", "2T", "140", "26", "ETSI", "5G", "20M", "HT", "2T", + "140", "20", "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "144", "26", "ETSI", "5G", + "20M", "HT", "2T", "144", "63", "MKK", "5G", "20M", "HT", + "2T", "144", "63", "FCC", "5G", "20M", "HT", "2T", "149", + "32", "ETSI", "5G", "20M", "HT", "2T", "149", "63", "MKK", + "5G", "20M", "HT", "2T", "149", "63", "FCC", "5G", "20M", + "HT", "2T", "153", "32", "ETSI", "5G", "20M", "HT", "2T", + "153", "63", "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "32", "ETSI", "5G", + "20M", "HT", "2T", "157", "63", "MKK", "5G", "20M", "HT", + "2T", "157", "63", "FCC", "5G", "20M", "HT", "2T", "161", + "32", "ETSI", "5G", "20M", "HT", "2T", "161", "63", "MKK", + "5G", "20M", "HT", "2T", "161", "63", "FCC", "5G", "20M", + "HT", "2T", "165", "32", "ETSI", "5G", "20M", "HT", "2T", + "165", "63", "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "22", "ETSI", "5G", + "40M", "HT", "1T", "38", "30", "MKK", "5G", "40M", "HT", + "1T", "38", "30", "FCC", "5G", "40M", "HT", "1T", "46", + "30", "ETSI", "5G", "40M", "HT", "1T", "46", "30", "MKK", + "5G", "40M", "HT", "1T", "46", "30", "FCC", "5G", "40M", + "HT", "1T", "54", "30", "ETSI", "5G", "40M", "HT", "1T", + "54", "30", "MKK", "5G", "40M", "HT", "1T", "54", "30", + "FCC", "5G", "40M", "HT", "1T", "62", "24", "ETSI", "5G", + "40M", "HT", "1T", "62", "30", "MKK", "5G", "40M", "HT", + "1T", "62", "30", "FCC", "5G", "40M", "HT", "1T", "102", + "24", "ETSI", "5G", "40M", "HT", "1T", "102", "30", "MKK", + "5G", "40M", "HT", "1T", "102", "30", "FCC", "5G", "40M", + "HT", "1T", "110", "30", "ETSI", "5G", "40M", "HT", "1T", + "110", "30", "MKK", "5G", "40M", "HT", "1T", "110", "30", + "FCC", "5G", "40M", "HT", "1T", "118", "30", "ETSI", "5G", + "40M", "HT", "1T", "118", "30", "MKK", "5G", "40M", "HT", + "1T", "118", "30", "FCC", "5G", "40M", "HT", "1T", "126", + "30", "ETSI", "5G", "40M", "HT", "1T", "126", "30", "MKK", + "5G", "40M", "HT", "1T", "126", "30", "FCC", "5G", "40M", + "HT", "1T", "134", "30", "ETSI", "5G", "40M", "HT", "1T", + "134", "30", "MKK", "5G", "40M", "HT", "1T", "134", "30", + "FCC", "5G", "40M", "HT", "1T", "142", "30", "ETSI", "5G", + "40M", "HT", "1T", "142", "63", "MKK", "5G", "40M", "HT", + "1T", "142", "63", "FCC", "5G", "40M", "HT", "1T", "151", + "30", "ETSI", "5G", "40M", "HT", "1T", "151", "63", "MKK", + "5G", "40M", "HT", "1T", "151", "63", "FCC", "5G", "40M", + "HT", "1T", "159", "30", "ETSI", "5G", "40M", "HT", "1T", + "159", "63", "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "20", "ETSI", "5G", + "40M", "HT", "2T", "38", "20", "MKK", "5G", "40M", "HT", + "2T", "38", "22", "FCC", "5G", "40M", "HT", "2T", "46", + "30", "ETSI", "5G", "40M", "HT", "2T", "46", "20", "MKK", + "5G", "40M", "HT", "2T", "46", "22", "FCC", "5G", "40M", + "HT", "2T", "54", "30", "ETSI", "5G", "40M", "HT", "2T", + "54", "20", "MKK", "5G", "40M", "HT", "2T", "54", "22", + "FCC", "5G", "40M", "HT", "2T", "62", "22", "ETSI", "5G", + "40M", "HT", "2T", "62", "20", "MKK", "5G", "40M", "HT", + "2T", "62", "22", "FCC", "5G", "40M", "HT", "2T", "102", + "22", "ETSI", "5G", "40M", "HT", "2T", "102", "20", "MKK", + "5G", "40M", "HT", "2T", "102", "30", "FCC", "5G", "40M", + "HT", "2T", "110", "30", "ETSI", "5G", "40M", "HT", "2T", + "110", "20", "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "30", "ETSI", "5G", + "40M", "HT", "2T", "118", "20", "MKK", "5G", "40M", "HT", + "2T", "118", "30", "FCC", "5G", "40M", "HT", "2T", "126", + "30", "ETSI", "5G", "40M", "HT", "2T", "126", "20", "MKK", + "5G", "40M", "HT", "2T", "126", "30", "FCC", "5G", "40M", + "HT", "2T", "134", "30", "ETSI", "5G", "40M", "HT", "2T", + "134", "20", "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "142", "30", "ETSI", "5G", + "40M", "HT", "2T", "142", "63", "MKK", "5G", "40M", "HT", + "2T", "142", "63", "FCC", "5G", "40M", "HT", "2T", "151", + "30", "ETSI", "5G", "40M", "HT", "2T", "151", "63", "MKK", + "5G", "40M", "HT", "2T", "151", "63", "FCC", "5G", "40M", + "HT", "2T", "159", "30", "ETSI", "5G", "40M", "HT", "2T", + "159", "63", "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "20", "ETSI", "5G", + "80M", "VHT", "1T", "42", "30", "MKK", "5G", "80M", "VHT", + "1T", "42", "28", "FCC", "5G", "80M", "VHT", "1T", "58", + "20", "ETSI", "5G", "80M", "VHT", "1T", "58", "30", "MKK", + "5G", "80M", "VHT", "1T", "58", "28", "FCC", "5G", "80M", + "VHT", "1T", "106", "20", "ETSI", "5G", "80M", "VHT", "1T", + "106", "30", "MKK", "5G", "80M", "VHT", "1T", "106", "30", + "FCC", "5G", "80M", "VHT", "1T", "122", "30", "ETSI", "5G", + "80M", "VHT", "1T", "122", "30", "MKK", "5G", "80M", "VHT", + "1T", "122", "30", "FCC", "5G", "80M", "VHT", "1T", "138", + "30", "ETSI", "5G", "80M", "VHT", "1T", "138", "63", "MKK", + "5G", "80M", "VHT", "1T", "138", "63", "FCC", "5G", "80M", + "VHT", "1T", "155", "30", "ETSI", "5G", "80M", "VHT", "1T", + "155", "63", "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "18", "ETSI", "5G", + "80M", "VHT", "2T", "42", "20", "MKK", "5G", "80M", "VHT", + "2T", "42", "22", "FCC", "5G", "80M", "VHT", "2T", "58", + "18", "ETSI", "5G", "80M", "VHT", "2T", "58", "20", "MKK", + "5G", "80M", "VHT", "2T", "58", "22", "FCC", "5G", "80M", + "VHT", "2T", "106", "20", "ETSI", "5G", "80M", "VHT", "2T", + "106", "20", "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "30", "ETSI", "5G", + "80M", "VHT", "2T", "122", "20", "MKK", "5G", "80M", "VHT", + "2T", "122", "30", "FCC", "5G", "80M", "VHT", "2T", "138", + "30", "ETSI", "5G", "80M", "VHT", "2T", "138", "63", "MKK", + "5G", "80M", "VHT", "2T", "138", "63", "FCC", "5G", "80M", + "VHT", "2T", "155", "30", "ETSI", "5G", "80M", "VHT", "2T", + "155", "63", "MKK", "5G", "80M", "VHT", "2T", "155", "63"}; + +void odm_read_and_config_mp_8822b_txpwr_lmt_type5(struct phy_dm_struct *dm) +{ + u32 i = 0; + u32 array_len = sizeof(array_mp_8822b_txpwr_lmt_type5) / sizeof(u8 *); + u8 **array = (u8 **)array_mp_8822b_txpwr_lmt_type5; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> odm_read_and_config_mp_8822b_txpwr_lmt_type5\n"); + + for (i = 0; i < array_len; i += 7) { + u8 *regulation = array[i]; + u8 *band = array[i + 1]; + u8 *bandwidth = array[i + 2]; + u8 *rate = array[i + 3]; + u8 *rf_path = array[i + 4]; + u8 *chnl = array[i + 5]; + u8 *val = array[i + 6]; + + odm_config_bb_txpwr_lmt_8822b(dm, regulation, band, bandwidth, + rate, rf_path, chnl, val); + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h new file mode 100644 index 0000000000000000000000000000000000000000..1340fa9f369b8e3b3ca289b36526cd859281804b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#ifndef __INC_MP_RF_HW_IMG_8822B_H +#define __INC_MP_RF_HW_IMG_8822B_H + +/****************************************************************************** + * radioa.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_radioa(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_radioa(void); + +/****************************************************************************** + * radiob.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_radiob(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_radiob(void); + +/****************************************************************************** + * txpowertrack.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack(void); + +/****************************************************************************** + * txpowertrack_type0.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type0(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type0(void); + +/****************************************************************************** + * txpowertrack_type1.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type1(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type1(void); + +/****************************************************************************** + * txpowertrack_type2.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type2(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type2(void); + +/****************************************************************************** + * txpowertrack_type3_type5.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type3_type5( + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type3_type5(void); + +/****************************************************************************** + * txpowertrack_type4.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type4(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type4(void); + +/****************************************************************************** + * txpowertrack_type6.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type6(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type6(void); + +/****************************************************************************** + * txpowertrack_type7.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type7(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type7(void); + +/****************************************************************************** + * txpowertrack_type8.TXT + *****************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type8(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type8(void); + +/****************************************************************************** + * txpowertrack_type9.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type9(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type9(void); + +/****************************************************************************** + * txpwr_lmt.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpwr_lmt(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpwr_lmt(void); + +/****************************************************************************** + * txpwr_lmt_type5.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpwr_lmt_type5(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpwr_lmt_type5(void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c new file mode 100644 index 0000000000000000000000000000000000000000..ae3e2278fefd3a71a2bd66795f449e7ce3bb1aab --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c @@ -0,0 +1,351 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool +get_mix_mode_tx_agc_bb_swing_offset_8822b(void *dm_void, + enum pwrtrack_method method, + u8 rf_path, u8 tx_power_index_offest) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + u8 bb_swing_upper_bound = cali_info->default_ofdm_index + 10; + u8 bb_swing_lower_bound = 0; + + s8 tx_agc_index = 0; + u8 tx_bb_swing_index = cali_info->default_ofdm_index; + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d, tx_power_index_offest=%d\n", + rf_path, cali_info->absolute_ofdm_swing_idx[rf_path], + tx_power_index_offest); + + if (tx_power_index_offest > 0XF) + tx_power_index_offest = 0XF; + + if (cali_info->absolute_ofdm_swing_idx[rf_path] >= 0 && + cali_info->absolute_ofdm_swing_idx[rf_path] <= + tx_power_index_offest) { + tx_agc_index = cali_info->absolute_ofdm_swing_idx[rf_path]; + tx_bb_swing_index = cali_info->default_ofdm_index; + } else if (cali_info->absolute_ofdm_swing_idx[rf_path] > + tx_power_index_offest) { + tx_agc_index = tx_power_index_offest; + cali_info->remnant_ofdm_swing_idx[rf_path] = + cali_info->absolute_ofdm_swing_idx[rf_path] - + tx_power_index_offest; + tx_bb_swing_index = cali_info->default_ofdm_index + + cali_info->remnant_ofdm_swing_idx[rf_path]; + + if (tx_bb_swing_index > bb_swing_upper_bound) + tx_bb_swing_index = bb_swing_upper_bound; + } else { + tx_agc_index = 0; + + if (cali_info->default_ofdm_index > + (cali_info->absolute_ofdm_swing_idx[rf_path] * (-1))) + tx_bb_swing_index = + cali_info->default_ofdm_index + + cali_info->absolute_ofdm_swing_idx[rf_path]; + else + tx_bb_swing_index = bb_swing_lower_bound; + + if (tx_bb_swing_index < bb_swing_lower_bound) + tx_bb_swing_index = bb_swing_lower_bound; + } + + cali_info->absolute_ofdm_swing_idx[rf_path] = tx_agc_index; + cali_info->bb_swing_idx_ofdm[rf_path] = tx_bb_swing_index; + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "MixMode Offset Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d cali_info->bb_swing_idx_ofdm[rf_path]=%d tx_power_index_offest=%d\n", + rf_path, cali_info->absolute_ofdm_swing_idx[rf_path], + cali_info->bb_swing_idx_ofdm[rf_path], tx_power_index_offest); + + return true; +} + +void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method, + u8 rf_path, u8 channel_mapped_index) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + u8 tx_power_index_offest = 0; + u8 tx_power_index = 0; + + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 channel = rtlphy->current_channel; + u8 band_width = rtlphy->current_chan_bw; + u8 tx_rate = 0xFF; + + if (!dm->mp_mode) { + u16 rate = *dm->forced_data_rate; + + if (!rate) /*auto rate*/ + tx_rate = dm->tx_rate; + else /*force rate*/ + tx_rate = (u8)rate; + } + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Call:%s tx_rate=0x%X\n", + __func__, tx_rate); + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "pRF->default_ofdm_index=%d pRF->default_cck_index=%d\n", + cali_info->default_ofdm_index, + cali_info->default_cck_index); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "pRF->absolute_ofdm_swing_idx=%d pRF->remnant_ofdm_swing_idx=%d pRF->absolute_cck_swing_idx=%d pRF->remnant_cck_swing_idx=%d rf_path=%d\n", + cali_info->absolute_ofdm_swing_idx[rf_path], + cali_info->remnant_ofdm_swing_idx[rf_path], + cali_info->absolute_cck_swing_idx[rf_path], + cali_info->remnant_cck_swing_idx, rf_path); + + if (dm->number_linked_client != 0) + tx_power_index = odm_get_tx_power_index( + dm, (enum odm_rf_radio_path)rf_path, tx_rate, + band_width, channel); + + if (tx_power_index >= 63) + tx_power_index = 63; + + tx_power_index_offest = 63 - tx_power_index; + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "tx_power_index=%d tx_power_index_offest=%d rf_path=%d\n", + tx_power_index, tx_power_index_offest, rf_path); + + if (method == + BBSWING) { /*use for mp driver clean power tracking status*/ + switch (rf_path) { + case ODM_RF_PATH_A: + odm_set_bb_reg( + dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + break; + case ODM_RF_PATH_B: + odm_set_bb_reg( + dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + break; + + default: + break; + } + } else if (method == MIX_MODE) { + switch (rf_path) { + case ODM_RF_PATH_A: + get_mix_mode_tx_agc_bb_swing_offset_8822b( + dm, method, rf_path, tx_power_index_offest); + odm_set_bb_reg( + dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "TXAGC(0xC94)=0x%x BBSwing(0xc1c)=0x%x BBSwingIndex=%d rf_path=%d\n", + odm_get_bb_reg(dm, 0xC94, + (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25))), + odm_get_bb_reg(dm, 0xc1c, 0xFFE00000), + cali_info->bb_swing_idx_ofdm[rf_path], rf_path); + break; + + case ODM_RF_PATH_B: + get_mix_mode_tx_agc_bb_swing_offset_8822b( + dm, method, rf_path, tx_power_index_offest); + odm_set_bb_reg( + dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "TXAGC(0xE94)=0x%x BBSwing(0xe1c)=0x%x BBSwingIndex=%d rf_path=%d\n", + odm_get_bb_reg(dm, 0xE94, + (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25))), + odm_get_bb_reg(dm, 0xe1c, 0xFFE00000), + cali_info->bb_swing_idx_ofdm[rf_path], rf_path); + break; + + default: + break; + } + } +} + +void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a, + u8 **temperature_down_a, u8 **temperature_up_b, + u8 **temperature_down_b) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 channel = rtlphy->current_channel; + + *temperature_up_a = cali_info->delta_swing_table_idx_2ga_p; + *temperature_down_a = cali_info->delta_swing_table_idx_2ga_n; + *temperature_up_b = cali_info->delta_swing_table_idx_2gb_p; + *temperature_down_b = cali_info->delta_swing_table_idx_2gb_n; + + if (channel >= 36 && channel <= 64) { + *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[0]; + *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[0]; + *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[0]; + *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[0]; + } else if (channel >= 100 && channel <= 144) { + *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[1]; + *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[1]; + *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[1]; + *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[1]; + } else if (channel >= 149 && channel <= 177) { + *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[2]; + *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[2]; + *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[2]; + *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[2]; + } +} + +static void _phy_lc_calibrate_8822b(struct phy_dm_struct *dm) +{ + u32 lc_cal = 0, cnt = 0; + + /*backup RF0x18*/ + lc_cal = odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK); + + /*Start LCK*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, + lc_cal | 0x08000); + + ODM_delay_ms(100); + + for (cnt = 0; cnt < 100; cnt++) { + if (odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, 0x8000) != 0x1) + break; + ODM_delay_ms(10); + } + + /*Recover channel number*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal); +} + +void phy_lc_calibrate_8822b(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + bool is_start_cont_tx = false, is_single_tone = false, + is_carrier_suppression = false; + u64 start_time; + u64 progressing_time; + + if (is_start_cont_tx || is_single_tone || is_carrier_suppression) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[LCK]continues TX ing !!! LCK return\n"); + return; + } + + start_time = odm_get_current_time(dm); + _phy_lc_calibrate_8822b(dm); + progressing_time = odm_get_progressing_time(dm, start_time); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[LCK]LCK progressing_time = %lld\n", progressing_time); +} + +void configure_txpower_track_8822b(struct txpwrtrack_cfg *config) +{ + config->swing_table_size_cck = TXSCALE_TABLE_SIZE; + config->swing_table_size_ofdm = TXSCALE_TABLE_SIZE; + config->threshold_iqk = IQK_THRESHOLD; + config->threshold_dpk = DPK_THRESHOLD; + config->average_thermal_num = AVG_THERMAL_NUM_8822B; + config->rf_path_count = MAX_PATH_NUM_8822B; + config->thermal_reg_addr = RF_T_METER_8822B; + + config->odm_tx_pwr_track_set_pwr = odm_tx_pwr_track_set_pwr8822b; + config->do_iqk = do_iqk_8822b; + config->phy_lc_calibrate = phy_lc_calibrate_8822b; + + config->get_delta_swing_table = get_delta_swing_table_8822b; +} + +void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main) +{ + /*BY SY Request */ + odm_set_bb_reg(dm, 0x4C, (BIT(24) | BIT(23)), 0x2); + odm_set_bb_reg(dm, 0x974, 0xff, 0xff); + + /*odm_set_bb_reg(dm, 0x1991, 0x3, 0x0);*/ + odm_set_bb_reg(dm, 0x1990, (BIT(9) | BIT(8)), 0x0); + + /*odm_set_bb_reg(dm, 0xCBE, 0x8, 0x0);*/ + odm_set_bb_reg(dm, 0xCBC, BIT(19), 0x0); + + odm_set_bb_reg(dm, 0xCB4, 0xff, 0x77); + + odm_set_bb_reg(dm, 0x70, MASKBYTE3, 0x0e); + odm_set_bb_reg(dm, 0x1704, MASKDWORD, 0x0000ff00); + odm_set_bb_reg(dm, 0x1700, MASKDWORD, 0xc00f0038); + + if (is_main) { + /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x2); WiFi */ + odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x2); /*WiFi */ + } else { + /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x1); BT*/ + odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x1); /*BT*/ + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..4f3bfe316ee9a115b0124bd820dbbbd93280fba6 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __HAL_PHY_RF_8822B_H__ +#define __HAL_PHY_RF_8822B_H__ + +#define AVG_THERMAL_NUM_8822B 4 +#define RF_T_METER_8822B 0x42 + +void configure_txpower_track_8822b(struct txpwrtrack_cfg *config); + +void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method, + u8 rf_path, u8 channel_mapped_index); + +void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a, + u8 **temperature_down_a, u8 **temperature_up_b, + u8 **temperature_down_b); + +void phy_lc_calibrate_8822b(void *dm_void); + +void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main); + +#endif /* #ifndef __HAL_PHY_RF_8822B_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c new file mode 100644 index 0000000000000000000000000000000000000000..26d1022e851c46fff0dd126b45fc6596d345b1f9 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c @@ -0,0 +1,1815 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +/* ======================================================================== */ +/* These following functions can be used for PHY DM only*/ + +static u32 reg82c_8822b; +static u32 reg838_8822b; +static u32 reg830_8822b; +static u32 reg83c_8822b; +static u32 rega20_8822b; +static u32 rega24_8822b; +static u32 rega28_8822b; +static enum odm_bw bw_8822b; +static u8 central_ch_8822b; + +static u32 cca_ifem_ccut[12][4] = { + /*20M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*40M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/ + {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x87746641, 0x00000000, 0x87746641}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ +static u32 cca_efem_ccut[12][4] = { + /*20M*/ + {0x75A76010, 0x75A76010, 0x75A76010, 0x75A75010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x87766651, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/ + {0x9194b2b9, 0x9194b2b9, 0x9194b2b9, 0x9194b2b9}, /*Reg83C*/ + /*40M*/ + {0x75A85010, 0x75A75010, 0x75A85010, 0x75A75010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x76BA7010, 0x75BA7010, 0x76BA7010, 0x75BA7010}, /*Reg82C*/ + {0x79a0ea28, 0x00000000, 0x79a0ea28, 0x00000000}, /*Reg830*/ + {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ +static u32 cca_ifem_ccut_rfetype5[12][4] = { + /*20M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x00000000, 0x87766461, 0x87766461}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*40M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/ + {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x76666641, 0x00000000, 0x76666641}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ +static u32 cca_ifem_ccut_rfetype3[12][4] = { + /*20M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x00000000, 0x87766461, 0x87766461}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*40M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/ + {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x76666641, 0x00000000, 0x76666641}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ + +static inline u32 phydm_check_bit_mask(u32 bit_mask, u32 data_original, + u32 data) +{ + u8 bit_shift; + + if (bit_mask != 0xfffff) { + for (bit_shift = 0; bit_shift <= 19; bit_shift++) { + if (((bit_mask >> bit_shift) & 0x1) == 1) + break; + } + return ((data_original) & (~bit_mask)) | (data << bit_shift); + } + return data; +} + +static bool phydm_rfe_8822b(struct phy_dm_struct *dm, u8 channel) +{ + if (dm->rfe_type == 4) { + /* Default setting is in PHY parameters */ + + if (channel <= 14) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57); + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x8); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x2); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x8); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x2); + + /* antenna switch table */ + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf050); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf050); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf055); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf055); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf550); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf550); + } + + } else if (channel > 35) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75); + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + /* antenna switch table */ + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005); + } + } else { + return false; + } + + } else if ((dm->rfe_type == 1) || (dm->rfe_type == 2) || + (dm->rfe_type == 7) || (dm->rfe_type == 9)) { + /* eFem */ + if (((dm->cut_version == ODM_CUT_A) || + (dm->cut_version == ODM_CUT_B)) && + (dm->rfe_type < 2)) { + if (channel <= 14) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x704570); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x704570); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x45); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x45); + } else if (channel > 35) { + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x174517); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x174517); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x45); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x45); + } else { + return false; + } + + /* delay 400ns for PAPE */ + odm_set_bb_reg(dm, 0x810, + MASKBYTE3 | BIT(20) | BIT(21) | BIT(22) | + BIT(23), + 0x211); + + /* antenna switch table */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa555); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa555); + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s: Using old RFE control pin setting for A-cut and B-cut\n", + __func__); + } else { + if (channel <= 14) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x705770); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x705770); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xcb8, BIT(4), 0); + odm_set_bb_reg(dm, 0xeb8, BIT(4), 0); + } else if (channel > 35) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x177517); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x177517); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xcb8, BIT(5), 0); + odm_set_bb_reg(dm, 0xeb8, BIT(5), 0); + } else { + return false; + } + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + /* antenna switch table */ + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005); + } + } + } else if ((dm->rfe_type == 0) || (dm->rfe_type == 3) || + (dm->rfe_type == 5) || (dm->rfe_type == 6) || + (dm->rfe_type == 8) || (dm->rfe_type == 10)) { + /* iFEM */ + if (channel <= 14) { + /* signal source */ + + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57); + + } else if (channel > 35) { + /* signal source */ + + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75); + + } else { + return false; + } + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | + BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | + BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + /* antenna switch table */ + if (channel <= 14) { + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005); + } + } else if (channel > 35) { + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa5a5); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa5a5); + } + } + + /* chip top mux */ + odm_set_bb_reg(dm, 0x64, BIT(29) | BIT(28), 0x3); + odm_set_bb_reg(dm, 0x4c, BIT(26) | BIT(25), 0x0); + odm_set_bb_reg(dm, 0x40, BIT(2), 0x1); + + /* from s0 or s1 */ + odm_set_bb_reg(dm, 0x1990, + (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), + 0x30); + odm_set_bb_reg(dm, 0x1990, (BIT(11) | BIT(10)), 0x3); + + /* input or output */ + odm_set_bb_reg(dm, 0x974, + (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), + 0x3f); + odm_set_bb_reg(dm, 0x974, (BIT(11) | BIT(10)), 0x3); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s: Update RFE control pin setting (ch%d, tx_path 0x%x, rx_path 0x%x)\n", + __func__, channel, dm->tx_ant_status, dm->rx_ant_status); + + return true; +} + +static void phydm_ccapar_by_rfe_8822b(struct phy_dm_struct *dm) +{ + u32 cca_ifem[12][4], cca_efem[12][4]; + u8 row, col; + u32 reg82c, reg830, reg838, reg83c; + + if (dm->cut_version == ODM_CUT_A) + return; + { + odm_move_memory(dm, cca_efem, cca_efem_ccut, 48 * 4); + if (dm->rfe_type == 5) + odm_move_memory(dm, cca_ifem, cca_ifem_ccut_rfetype5, + 48 * 4); + else if (dm->rfe_type == 3) + odm_move_memory(dm, cca_ifem, cca_ifem_ccut_rfetype3, + 48 * 4); + else + odm_move_memory(dm, cca_ifem, cca_ifem_ccut, 48 * 4); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s: Update CCA parameters for Ccut\n", __func__); + } + + if (bw_8822b == ODM_BW20M) + row = 0; + else if (bw_8822b == ODM_BW40M) + row = 4; + else + row = 8; + + if (central_ch_8822b <= 14) { + if ((dm->rx_ant_status == ODM_RF_A) || + (dm->rx_ant_status == ODM_RF_B)) + col = 0; + else + col = 1; + } else { + if ((dm->rx_ant_status == ODM_RF_A) || + (dm->rx_ant_status == ODM_RF_B)) + col = 2; + else + col = 3; + } + + if ((dm->rfe_type == 1) || (dm->rfe_type == 4) || (dm->rfe_type == 6) || + (dm->rfe_type == 7)) { + /*eFEM => RFE type 1 & RFE type 4 & RFE type 6 & RFE type 7*/ + reg82c = (cca_efem[row][col] != 0) ? cca_efem[row][col] : + reg82c_8822b; + reg830 = (cca_efem[row + 1][col] != 0) ? + cca_efem[row + 1][col] : + reg830_8822b; + reg838 = (cca_efem[row + 2][col] != 0) ? + cca_efem[row + 2][col] : + reg838_8822b; + reg83c = (cca_efem[row + 3][col] != 0) ? + cca_efem[row + 3][col] : + reg83c_8822b; + } else if ((dm->rfe_type == 2) || (dm->rfe_type == 9)) { + /*5G eFEM, 2G iFEM => RFE type 2, 5G eFEM => RFE type 9 */ + if (central_ch_8822b <= 14) { + reg82c = (cca_ifem[row][col] != 0) ? + cca_ifem[row][col] : + reg82c_8822b; + reg830 = (cca_ifem[row + 1][col] != 0) ? + cca_ifem[row + 1][col] : + reg830_8822b; + reg838 = (cca_ifem[row + 2][col] != 0) ? + cca_ifem[row + 2][col] : + reg838_8822b; + reg83c = (cca_ifem[row + 3][col] != 0) ? + cca_ifem[row + 3][col] : + reg83c_8822b; + } else { + reg82c = (cca_efem[row][col] != 0) ? + cca_efem[row][col] : + reg82c_8822b; + reg830 = (cca_efem[row + 1][col] != 0) ? + cca_efem[row + 1][col] : + reg830_8822b; + reg838 = (cca_efem[row + 2][col] != 0) ? + cca_efem[row + 2][col] : + reg838_8822b; + reg83c = (cca_efem[row + 3][col] != 0) ? + cca_efem[row + 3][col] : + reg83c_8822b; + } + } else { + /* iFEM =>RFE type 3 & RFE type 5 & RFE type 0 & RFE type 8 & + * RFE type 10 + */ + reg82c = (cca_ifem[row][col] != 0) ? cca_ifem[row][col] : + reg82c_8822b; + reg830 = (cca_ifem[row + 1][col] != 0) ? + cca_ifem[row + 1][col] : + reg830_8822b; + reg838 = (cca_ifem[row + 2][col] != 0) ? + cca_ifem[row + 2][col] : + reg838_8822b; + reg83c = (cca_ifem[row + 3][col] != 0) ? + cca_ifem[row + 3][col] : + reg83c_8822b; + } + + odm_set_bb_reg(dm, 0x82c, MASKDWORD, reg82c); + odm_set_bb_reg(dm, 0x830, MASKDWORD, reg830); + odm_set_bb_reg(dm, 0x838, MASKDWORD, reg838); + odm_set_bb_reg(dm, 0x83c, MASKDWORD, reg83c); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s: (Pkt%d, Intf%d, RFE%d), row = %d, col = %d\n", + __func__, dm->package_type, dm->support_interface, + dm->rfe_type, row, col); +} + +static void phydm_ccapar_by_bw_8822b(struct phy_dm_struct *dm, + enum odm_bw bandwidth) +{ + u32 reg82c; + + if (dm->cut_version != ODM_CUT_A) + return; + + /* A-cut */ + reg82c = odm_get_bb_reg(dm, 0x82c, MASKDWORD); + + if (bandwidth == ODM_BW20M) { + /* 82c[15:12] = 4 */ + /* 82c[27:24] = 6 */ + + reg82c &= (~(0x0f00f000)); + reg82c |= ((0x4) << 12); + reg82c |= ((0x6) << 24); + } else if (bandwidth == ODM_BW40M) { + /* 82c[19:16] = 9 */ + /* 82c[27:24] = 6 */ + + reg82c &= (~(0x0f0f0000)); + reg82c |= ((0x9) << 16); + reg82c |= ((0x6) << 24); + } else if (bandwidth == ODM_BW80M) { + /* 82c[15:12] 7 */ + /* 82c[19:16] b */ + /* 82c[23:20] d */ + /* 82c[27:24] 3 */ + + reg82c &= (~(0x0ffff000)); + reg82c |= ((0xdb7) << 12); + reg82c |= ((0x3) << 24); + } + + odm_set_bb_reg(dm, 0x82c, MASKDWORD, reg82c); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Update CCA parameters for Acut\n", __func__); +} + +static void phydm_ccapar_by_rxpath_8822b(struct phy_dm_struct *dm) +{ + if (dm->cut_version != ODM_CUT_A) + return; + + if ((dm->rx_ant_status == ODM_RF_A) || + (dm->rx_ant_status == ODM_RF_B)) { + /* 838[7:4] = 8 */ + /* 838[11:8] = 7 */ + /* 838[15:12] = 6 */ + /* 838[19:16] = 7 */ + /* 838[23:20] = 7 */ + /* 838[27:24] = 7 */ + odm_set_bb_reg(dm, 0x838, 0x0ffffff0, 0x777678); + } else { + /* 838[7:4] = 3 */ + /* 838[11:8] = 3 */ + /* 838[15:12] = 6 */ + /* 838[19:16] = 6 */ + /* 838[23:20] = 7 */ + /* 838[27:24] = 7 */ + odm_set_bb_reg(dm, 0x838, 0x0ffffff0, 0x776633); + } + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Update CCA parameters for Acut\n", __func__); +} + +static void phydm_rxdfirpar_by_bw_8822b(struct phy_dm_struct *dm, + enum odm_bw bandwidth) +{ + if (bandwidth == ODM_BW40M) { + /* RX DFIR for BW40 */ + odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x1); + odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x0); + odm_set_bb_reg(dm, 0xc20, BIT(31), 0x0); + odm_set_bb_reg(dm, 0xe20, BIT(31), 0x0); + } else if (bandwidth == ODM_BW80M) { + /* RX DFIR for BW80 */ + odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x2); + odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x1); + odm_set_bb_reg(dm, 0xc20, BIT(31), 0x0); + odm_set_bb_reg(dm, 0xe20, BIT(31), 0x0); + } else { + /* RX DFIR for BW20, BW10 and BW5*/ + odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x2); + odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x2); + odm_set_bb_reg(dm, 0xc20, BIT(31), 0x1); + odm_set_bb_reg(dm, 0xe20, BIT(31), 0x1); + } +} + +bool phydm_write_txagc_1byte_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u32 offset_txagc[2] = {0x1d00, 0x1d80}; + u8 rate_idx = (hw_rate & 0xfc), i; + u8 rate_offset = (hw_rate & 0x3); + u32 txagc_content = 0x0; + + /* For debug command only!!!! */ + + /* Error handling */ + if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, path); + return false; + } + + /* For HW limitation, We can't write TXAGC once a byte. */ + for (i = 0; i < 4; i++) { + if (i != rate_offset) + txagc_content = + txagc_content | (config_phydm_read_txagc_8822b( + dm, path, rate_idx + i) + << (i << 3)); + else + txagc_content = txagc_content | + ((power_index & 0x3f) << (i << 3)); + } + odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD, + txagc_content); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__, + path, hw_rate, (offset_txagc[path] + hw_rate), + power_index); + return true; +} + +void phydm_init_hw_info_by_rfe_type_8822b(struct phy_dm_struct *dm) +{ + u16 mask_path_a = 0x0303; + u16 mask_path_b = 0x0c0c; + /*u16 mask_path_c = 0x3030;*/ + /*u16 mask_path_d = 0xc0c0;*/ + + dm->is_init_hw_info_by_rfe = false; + + if ((dm->rfe_type == 1) || (dm->rfe_type == 6) || (dm->rfe_type == 7)) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_LNA_5G | + ODM_BOARD_EXT_PA | ODM_BOARD_EXT_PA_5G)); + + if (dm->rfe_type == 6) { + odm_cmn_info_init( + dm, ODM_CMNINFO_GPA, + (TYPE_GPA1 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_APA, + (TYPE_APA1 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA1 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA1 & (mask_path_a | mask_path_b))); + } else if (dm->rfe_type == 7) { + odm_cmn_info_init( + dm, ODM_CMNINFO_GPA, + (TYPE_GPA2 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_APA, + (TYPE_APA2 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA2 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA2 & (mask_path_a | mask_path_b))); + } else { + odm_cmn_info_init( + dm, ODM_CMNINFO_GPA, + (TYPE_GPA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_APA, + (TYPE_APA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + } + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true); + } else if (dm->rfe_type == 2) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA_5G | ODM_BOARD_EXT_PA_5G)); + odm_cmn_info_init(dm, ODM_CMNINFO_APA, + (TYPE_APA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true); + } else if (dm->rfe_type == 9) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA_5G)); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } else if ((dm->rfe_type == 3) || (dm->rfe_type == 5)) { + /* RFE type 3: 8822BS\8822BU TFBGA iFEM */ + /* RFE type 5: 8822BE TFBGA iFEM */ + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } else if (dm->rfe_type == 4) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_LNA_5G | + ODM_BOARD_EXT_PA | ODM_BOARD_EXT_PA_5G)); + odm_cmn_info_init(dm, ODM_CMNINFO_GPA, + (TYPE_GPA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_APA, + (TYPE_APA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true); + } else if (dm->rfe_type == 8) { + /* RFE type 8: TFBGA iFEM AP */ + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } else { + /* RFE Type 0 & 9 & 10: QFN iFEM */ + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } + + dm->is_init_hw_info_by_rfe = true; + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): RFE type (%d), Board type (0x%x), Package type (%d)\n", + __func__, dm->rfe_type, dm->board_type, dm->package_type); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): 5G ePA (%d), 5G eLNA (%d), 2G ePA (%d), 2G eLNA (%d)\n", + __func__, dm->ext_pa_5g, dm->ext_lna_5g, dm->ext_pa, + dm->ext_lna); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): 5G PA type (%d), 5G LNA type (%d), 2G PA type (%d), 2G LNA type (%d)\n", + __func__, dm->type_apa, dm->type_alna, dm->type_gpa, + dm->type_glna); +} + +s32 phydm_get_condition_number_8822B(struct phy_dm_struct *dm) +{ + s32 ret_val; + + odm_set_bb_reg(dm, 0x1988, BIT(22), 0x1); + ret_val = + (s32)odm_get_bb_reg(dm, 0xf84, (BIT(17) | BIT(16) | MASKLWORD)); + + if (bw_8822b == 0) { + ret_val = ret_val << (8 - 4); + ret_val = ret_val / 234; + } else if (bw_8822b == 1) { + ret_val = ret_val << (7 - 4); + ret_val = ret_val / 108; + } else if (bw_8822b == 2) { + ret_val = ret_val << (6 - 4); + ret_val = ret_val / 52; + } + + return ret_val; +} + +/* ======================================================================== */ + +/* ======================================================================== */ +/* These following functions can be used by driver*/ + +u32 config_phydm_read_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, u32 reg_addr, + u32 bit_mask) +{ + u32 readback_value, direct_addr; + u32 offset_read_rf[2] = {0x2800, 0x2c00}; + u32 power_RF[2] = {0x1c, 0xec}; + + /* Error handling.*/ + if (rf_path > ODM_RF_PATH_B) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, + rf_path); + return INVALID_RF_DATA; + } + + /* Error handling. Check if RF power is enable or not */ + /* 0xffffffff means RF power is disable */ + if (odm_get_mac_reg(dm, power_RF[rf_path], MASKBYTE3) != 0x7) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Read fail, RF is disabled\n", __func__); + return INVALID_RF_DATA; + } + + /* Calculate offset */ + reg_addr &= 0xff; + direct_addr = offset_read_rf[rf_path] + (reg_addr << 2); + + /* RF register only has 20bits */ + bit_mask &= RFREGOFFSETMASK; + + /* Read RF register directly */ + readback_value = odm_get_bb_reg(dm, direct_addr, bit_mask); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): RF-%d 0x%x = 0x%x, bit mask = 0x%x\n", __func__, + rf_path, reg_addr, readback_value, bit_mask); + return readback_value; +} + +bool config_phydm_write_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, + u32 reg_addr, u32 bit_mask, u32 data) +{ + u32 data_and_addr = 0, data_original = 0; + u32 offset_write_rf[2] = {0xc90, 0xe90}; + u32 power_RF[2] = {0x1c, 0xec}; + + /* Error handling.*/ + if (rf_path > ODM_RF_PATH_B) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, + rf_path); + return false; + } + + /* Read RF register content first */ + reg_addr &= 0xff; + bit_mask = bit_mask & RFREGOFFSETMASK; + + if (bit_mask != RFREGOFFSETMASK) { + data_original = config_phydm_read_rf_reg_8822b( + dm, rf_path, reg_addr, RFREGOFFSETMASK); + + /* Error handling. RF is disabled */ + if (!config_phydm_read_rf_check_8822b(data_original)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Write fail, RF is disable\n", + __func__); + return false; + } + + /* check bit mask */ + data = phydm_check_bit_mask(bit_mask, data_original, data); + } else if (odm_get_mac_reg(dm, power_RF[rf_path], MASKBYTE3) != 0x7) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Write fail, RF is disabled\n", __func__); + return false; + } + + /* Put write addr in [27:20] and write data in [19:00] */ + data_and_addr = ((reg_addr << 20) | (data & 0x000fffff)) & 0x0fffffff; + + /* Write operation */ + odm_set_bb_reg(dm, offset_write_rf[rf_path], MASKDWORD, data_and_addr); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): RF-%d 0x%x = 0x%x (original: 0x%x), bit mask = 0x%x\n", + __func__, rf_path, reg_addr, data, data_original, bit_mask); + return true; +} + +bool config_phydm_write_txagc_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u32 offset_txagc[2] = {0x1d00, 0x1d80}; + u8 rate_idx = (hw_rate & 0xfc); + + /* Input need to be HW rate index, not driver rate index!!!! */ + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + /* Error handling */ + if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, path); + return false; + } + + /* driver need to construct a 4-byte power index */ + odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD, + power_index); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__, + path, hw_rate, (offset_txagc[path] + hw_rate), + power_index); + return true; +} + +u8 config_phydm_read_txagc_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u8 read_back_data; + + /* Input need to be HW rate index, not driver rate index!!!! */ + + /* Error handling */ + if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, path); + return INVALID_TXAGC_DATA; + } + + /* Disable TX AGC report */ + odm_set_bb_reg(dm, 0x1998, BIT(16), 0x0); /* need to check */ + + /* Set data rate index (bit0~6) and path index (bit7) */ + odm_set_bb_reg(dm, 0x1998, MASKBYTE0, (hw_rate | (path << 7))); + + /* Enable TXAGC report */ + odm_set_bb_reg(dm, 0x1998, BIT(16), 0x1); + + /* Read TX AGC report */ + read_back_data = (u8)odm_get_bb_reg(dm, 0xd30, 0x7f0000); + + /* Driver have to disable TXAGC report after reading TXAGC + * (ref. user guide v11) + */ + odm_set_bb_reg(dm, 0x1998, BIT(16), 0x0); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): path-%d rate index 0x%x = 0x%x\n", __func__, path, + hw_rate, read_back_data); + return read_back_data; +} + +bool config_phydm_switch_band_8822b(struct phy_dm_struct *dm, u8 central_ch) +{ + u32 rf_reg18; + bool rf_reg_status = true; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()======================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + rf_reg_status = + rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18); + + if (central_ch <= 14) { + /* 2.4G */ + + /* Enable CCK block */ + odm_set_bb_reg(dm, 0x808, BIT(28), 0x1); + + /* Disable MAC CCK check */ + odm_set_bb_reg(dm, 0x454, BIT(7), 0x0); + + /* Disable BB CCK check */ + odm_set_bb_reg(dm, 0xa80, BIT(18), 0x0); + + /*CCA Mask*/ + odm_set_bb_reg(dm, 0x814, 0x0000FC00, 15); /*default value*/ + + /* RF band */ + rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8)))); + + /* RxHP dynamic control */ + if ((dm->rfe_type == 2) || (dm->rfe_type == 3) || + (dm->rfe_type == 5)) { + odm_set_bb_reg(dm, 0x8cc, MASKDWORD, 0x08108492); + odm_set_bb_reg(dm, 0x8d8, MASKDWORD, 0x29095612); + } + + } else if (central_ch > 35) { + /* 5G */ + + /* Enable BB CCK check */ + odm_set_bb_reg(dm, 0xa80, BIT(18), 0x1); + + /* Enable CCK check */ + odm_set_bb_reg(dm, 0x454, BIT(7), 0x1); + + /* Disable CCK block */ + odm_set_bb_reg(dm, 0x808, BIT(28), 0x0); + + /*CCA Mask*/ + odm_set_bb_reg(dm, 0x814, 0x0000FC00, 15); /*default value*/ + + /* RF band */ + rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8)))); + rf_reg18 = (rf_reg18 | BIT(8) | BIT(16)); + + /* RxHP dynamic control */ + if ((dm->rfe_type == 2) || (dm->rfe_type == 3) || + (dm->rfe_type == 5)) { + odm_set_bb_reg(dm, 0x8cc, MASKDWORD, 0x08100000); + odm_set_bb_reg(dm, 0x8d8, MASKDWORD, 0x21095612); + } + + } else { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Fail to switch band (ch: %d)\n", __func__, + central_ch); + return false; + } + + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->rf_type > ODM_1T1R) + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (!phydm_rfe_8822b(dm, central_ch)) + return false; + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch band (ch: %d), because writing RF register is fail\n", + __func__, central_ch); + return false; + } + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Success to switch band (ch: %d)\n", __func__, + central_ch); + return true; +} + +bool config_phydm_switch_channel_8822b(struct phy_dm_struct *dm, u8 central_ch) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + u32 rf_reg18 = 0, rf_reg_b8 = 0, rf_reg_be = 0xff; + bool rf_reg_status = true; + u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, + 0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6}; + u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff, + 0x0, 0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff, + 0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7}; + u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, + 0x0, 0x7, 0x7, 0x6, 0x5, 0x5, 0x0}; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()====================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + central_ch_8822b = central_ch; + rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + rf_reg_status = + rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18); + rf_reg18 = (rf_reg18 & (~(BIT(18) | BIT(17) | MASKBYTE0))); + + if (dm->cut_version == ODM_CUT_A) { + rf_reg_b8 = config_phydm_read_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xb8, RFREGOFFSETMASK); + rf_reg_status = rf_reg_status & + config_phydm_read_rf_check_8822b(rf_reg_b8); + } + + /* Switch band and channel */ + if (central_ch <= 14) { + /* 2.4G */ + + /* 1. RF band and channel*/ + rf_reg18 = (rf_reg18 | central_ch); + + /* 2. AGC table selection */ + odm_set_bb_reg(dm, 0x958, 0x1f, 0x0); + dig_tab->agc_table_idx = 0x0; + + /* 3. Set central frequency for clock offset tracking */ + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x96a); + + /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */ + if (dm->cut_version == ODM_CUT_A) + rf_reg_b8 = rf_reg_b8 | BIT(19); + + /* CCK TX filter parameters */ + if (central_ch == 14) { + odm_set_bb_reg(dm, 0xa20, MASKHWORD, 0x8488); + odm_set_bb_reg(dm, 0xa24, MASKDWORD, 0x00006577); + odm_set_bb_reg(dm, 0xa28, MASKLWORD, 0x0000); + } else { + odm_set_bb_reg(dm, 0xa20, MASKHWORD, + (rega20_8822b >> 16)); + odm_set_bb_reg(dm, 0xa24, MASKDWORD, rega24_8822b); + odm_set_bb_reg(dm, 0xa28, MASKLWORD, + (rega28_8822b & MASKLWORD)); + } + + } else if (central_ch > 35) { + /* 5G */ + + /* 1. RF band and channel*/ + rf_reg18 = (rf_reg18 | central_ch); + + /* 2. AGC table selection */ + if ((central_ch >= 36) && (central_ch <= 64)) { + odm_set_bb_reg(dm, 0x958, 0x1f, 0x1); + dig_tab->agc_table_idx = 0x1; + } else if ((central_ch >= 100) && (central_ch <= 144)) { + odm_set_bb_reg(dm, 0x958, 0x1f, 0x2); + dig_tab->agc_table_idx = 0x2; + } else if (central_ch >= 149) { + odm_set_bb_reg(dm, 0x958, 0x1f, 0x3); + dig_tab->agc_table_idx = 0x3; + } else { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (AGC) (ch: %d)\n", + __func__, central_ch); + return false; + } + + /* 3. Set central frequency for clock offset tracking */ + if ((central_ch >= 36) && (central_ch <= 48)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x494); + } else if ((central_ch >= 52) && (central_ch <= 64)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x453); + } else if ((central_ch >= 100) && (central_ch <= 116)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x452); + } else if ((central_ch >= 118) && (central_ch <= 177)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x412); + } else { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (fc_area) (ch: %d)\n", + __func__, central_ch); + return false; + } + + /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */ + if (dm->cut_version == ODM_CUT_A) { + if ((central_ch >= 57) && (central_ch <= 75)) + rf_reg_b8 = rf_reg_b8 & (~BIT(19)); + else + rf_reg_b8 = rf_reg_b8 | BIT(19); + } + } else { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (ch: %d)\n", + __func__, central_ch); + return false; + } + + /* Modify IGI for MP driver to aviod PCIE interference */ + if (dm->mp_mode && ((dm->rfe_type == 3) || (dm->rfe_type == 5))) { + if (central_ch == 14) + odm_write_dig(dm, 0x26); + else + odm_write_dig(dm, 0x20); + } + + /* Modify the setting of register 0xBE to reduce phase noise */ + if (central_ch <= 14) + rf_reg_be = 0x0; + else if ((central_ch >= 36) && (central_ch <= 64)) + rf_reg_be = low_band[(central_ch - 36) >> 1]; + else if ((central_ch >= 100) && (central_ch <= 144)) + rf_reg_be = middle_band[(central_ch - 100) >> 1]; + else if ((central_ch >= 149) && (central_ch <= 177)) + rf_reg_be = high_band[(central_ch - 149) >> 1]; + else + rf_reg_be = 0xff; + + if (rf_reg_be != 0xff) { + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xbe, + (BIT(17) | BIT(16) | BIT(15)), + rf_reg_be); + } else { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (ch: %d, Phase noise)\n", + __func__, central_ch); + return false; + } + + /* Fix channel 144 issue, ask by RFSI Alvin*/ + /* 00 when freq < 5400; 01 when 5400<=freq<=5720; 10 when freq > 5720; + * 2G don't care + */ + /* need to set 0xdf[18]=1 before writing RF18 when channel 144 */ + if (central_ch == 144) { + rf_reg_status = rf_reg_status & + config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xdf, BIT(18), 0x1); + rf_reg18 = (rf_reg18 | BIT(17)); + } else { + rf_reg_status = rf_reg_status & + config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xdf, BIT(18), 0x0); + + if (central_ch > 144) + rf_reg18 = (rf_reg18 | BIT(18)); + else if (central_ch >= 80) + rf_reg18 = (rf_reg18 | BIT(17)); + } + + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->cut_version == ODM_CUT_A) + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xb8, + RFREGOFFSETMASK, rf_reg_b8); + + if (dm->rf_type > ODM_1T1R) { + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->cut_version == ODM_CUT_A) + rf_reg_status = rf_reg_status & + config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0xb8, + RFREGOFFSETMASK, rf_reg_b8); + } + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (ch: %d), because writing RF register is fail\n", + __func__, central_ch); + return false; + } + + phydm_ccapar_by_rfe_8822b(dm); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Success to switch channel (ch: %d)\n", __func__, + central_ch); + return true; +} + +bool config_phydm_switch_bandwidth_8822b(struct phy_dm_struct *dm, + u8 primary_ch_idx, + enum odm_bw bandwidth) +{ + u32 rf_reg18; + bool rf_reg_status = true; + u8 IGI = 0; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()===================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + /* Error handling */ + if ((bandwidth >= ODM_BW_MAX) || + ((bandwidth == ODM_BW40M) && (primary_ch_idx > 2)) || + ((bandwidth == ODM_BW80M) && (primary_ch_idx > 4))) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d)\n", + __func__, bandwidth, primary_ch_idx); + return false; + } + + bw_8822b = bandwidth; + rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + rf_reg_status = + rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18); + + /* Switch bandwidth */ + switch (bandwidth) { + case ODM_BW20M: { + /* Small BW([7:6]) = 0, primary channel ([5:2]) = 0, + * rf mode([1:0]) = 20M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, ODM_BW20M); + + /* ADC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x1); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x1); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 | BIT(11) | BIT(10)); + + break; + } + case ODM_BW40M: { + /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel, + * rf mode([1:0]) = 40M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, + (((primary_ch_idx & 0xf) << 2) | ODM_BW40M)); + + /* CCK primary channel */ + if (primary_ch_idx == 1) + odm_set_bb_reg(dm, 0xa00, BIT(4), primary_ch_idx); + else + odm_set_bb_reg(dm, 0xa00, BIT(4), 0); + + /* ADC clock = 160M clock for BW40 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(17), 0x1); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(23) | BIT(22)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(29), 0x1); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10)))); + rf_reg18 = (rf_reg18 | BIT(11)); + + break; + } + case ODM_BW80M: { + /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel, + * rf mode([1:0]) = 80M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, + (((primary_ch_idx & 0xf) << 2) | ODM_BW80M)); + + /* ADC clock = 160M clock for BW80 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(13) | BIT(12)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(18), 0x1); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(25) | BIT(24)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(30), 0x1); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10)))); + rf_reg18 = (rf_reg18 | BIT(10)); + + break; + } + case ODM_BW5M: { + /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0, + * rf mode([1:0]) = 20M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, (BIT(6) | ODM_BW20M)); + + /* ADC clock = 40M clock */ + odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x2); + odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x0); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x2); + odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x0); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x0); + odm_set_bb_reg(dm, 0x8c8, BIT(31), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 | BIT(11) | BIT(10)); + + break; + } + case ODM_BW10M: { + /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0, + * rf mode([1:0]) = 20M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, (BIT(7) | ODM_BW20M)); + + /* ADC clock = 80M clock */ + odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x3); + odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x0); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x3); + odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x0); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x0); + odm_set_bb_reg(dm, 0x8c8, BIT(31), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 | BIT(11) | BIT(10)); + + break; + } + default: + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d)\n", + __func__, bandwidth, primary_ch_idx); + } + + /* Write RF register */ + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->rf_type > ODM_1T1R) + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d), because writing RF register is fail\n", + __func__, bandwidth, primary_ch_idx); + return false; + } + + /* Modify RX DFIR parameters */ + phydm_rxdfirpar_by_bw_8822b(dm, bandwidth); + + /* Modify CCA parameters */ + phydm_ccapar_by_bw_8822b(dm, bandwidth); + phydm_ccapar_by_rfe_8822b(dm); + + /* Toggle RX path to avoid RX dead zone issue */ + odm_set_bb_reg(dm, 0x808, MASKBYTE0, 0x0); + odm_set_bb_reg(dm, 0x808, MASKBYTE0, + (dm->rx_ant_status | (dm->rx_ant_status << 4))); + + /* Toggle IGI to let RF enter RX mode */ + IGI = (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), IGI - 2); + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), IGI - 2); + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), IGI); + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), IGI); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Success to switch bandwidth (bw: %d, primary ch: %d)\n", + __func__, bandwidth, primary_ch_idx); + return true; +} + +bool config_phydm_switch_channel_bw_8822b(struct phy_dm_struct *dm, + u8 central_ch, u8 primary_ch_idx, + enum odm_bw bandwidth) +{ + /* Switch band */ + if (!config_phydm_switch_band_8822b(dm, central_ch)) + return false; + + /* Switch channel */ + if (!config_phydm_switch_channel_8822b(dm, central_ch)) + return false; + + /* Switch bandwidth */ + if (!config_phydm_switch_bandwidth_8822b(dm, primary_ch_idx, bandwidth)) + return false; + + return true; +} + +bool config_phydm_trx_mode_8822b(struct phy_dm_struct *dm, + enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path) +{ + bool rf_reg_status = true; + u8 IGI; + u32 rf_reg33 = 0; + u16 counter = 0; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()=====================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + if ((tx_path & (~(ODM_RF_A | ODM_RF_B))) != 0) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Wrong TX setting (TX: 0x%x)\n", __func__, + tx_path); + return false; + } + + if ((rx_path & (~(ODM_RF_A | ODM_RF_B))) != 0) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Wrong RX setting (RX: 0x%x)\n", __func__, + rx_path); + return false; + } + + /* RF mode of path-A and path-B */ + /* Cannot shut down path-A, beacause synthesizer will be shut down when + * path-A is in shut down mode + */ + if ((tx_path | rx_path) & ODM_RF_A) + odm_set_bb_reg(dm, 0xc08, MASKLWORD, 0x3231); + else + odm_set_bb_reg(dm, 0xc08, MASKLWORD, 0x1111); + + if ((tx_path | rx_path) & ODM_RF_B) + odm_set_bb_reg(dm, 0xe08, MASKLWORD, 0x3231); + else + odm_set_bb_reg(dm, 0xe08, MASKLWORD, 0x1111); + + /* Set TX antenna by Nsts */ + odm_set_bb_reg(dm, 0x93c, (BIT(19) | BIT(18)), 0x3); + odm_set_bb_reg(dm, 0x80c, (BIT(29) | BIT(28)), 0x1); + + /* Control CCK TX path by 0xa07[7] */ + odm_set_bb_reg(dm, 0x80c, BIT(30), 0x1); + + /* TX logic map and TX path en for Nsts = 1, and CCK TX path*/ + if (tx_path & ODM_RF_A) { + odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x001); + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8); + } else if (tx_path & ODM_RF_B) { + odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x002); + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4); + } + + /* TX logic map and TX path en for Nsts = 2*/ + if ((tx_path == ODM_RF_A) || (tx_path == ODM_RF_B)) + odm_set_bb_reg(dm, 0x940, 0xfff0, 0x01); + else + odm_set_bb_reg(dm, 0x940, 0xfff0, 0x43); + + /* TX path enable */ + odm_set_bb_reg(dm, 0x80c, MASKBYTE0, ((tx_path << 4) | tx_path)); + + /* Tx2path for 1ss */ + if (!((tx_path == ODM_RF_A) || (tx_path == ODM_RF_B))) { + if (is_tx2_path || dm->mp_mode) { + /* 2Tx for OFDM */ + odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x043); + + /* 2Tx for CCK */ + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc); + } + } + + /* Always disable MRC for CCK CCA */ + odm_set_bb_reg(dm, 0xa2c, BIT(22), 0x0); + + /* Always disable MRC for CCK barker */ + odm_set_bb_reg(dm, 0xa2c, BIT(18), 0x0); + + /* CCK RX 1st and 2nd path setting*/ + if (rx_path & ODM_RF_A) + odm_set_bb_reg(dm, 0xa04, 0x0f000000, 0x0); + else if (rx_path & ODM_RF_B) + odm_set_bb_reg(dm, 0xa04, 0x0f000000, 0x5); + + /* RX path enable */ + odm_set_bb_reg(dm, 0x808, MASKBYTE0, ((rx_path << 4) | rx_path)); + + if ((rx_path == ODM_RF_A) || (rx_path == ODM_RF_B)) { + /* 1R */ + + /* Disable MRC for CCA */ + /* odm_set_bb_reg(dm, 0xa2c, BIT22, 0x0); */ + + /* Disable MRC for barker */ + /* odm_set_bb_reg(dm, 0xa2c, BIT18, 0x0); */ + + /* Disable CCK antenna diversity */ + /* odm_set_bb_reg(dm, 0xa00, BIT15, 0x0); */ + + /* Disable Antenna weighting */ + odm_set_bb_reg(dm, 0x1904, BIT(16), 0x0); + odm_set_bb_reg(dm, 0x800, BIT(28), 0x0); + odm_set_bb_reg(dm, 0x850, BIT(23), 0x0); + } else { + /* 2R */ + + /* Enable MRC for CCA */ + /* odm_set_bb_reg(dm, 0xa2c, BIT22, 0x1); */ + + /* Enable MRC for barker */ + /* odm_set_bb_reg(dm, 0xa2c, BIT18, 0x1); */ + + /* Disable CCK antenna diversity */ + /* odm_set_bb_reg(dm, 0xa00, BIT15, 0x0); */ + + /* Enable Antenna weighting */ + odm_set_bb_reg(dm, 0x1904, BIT(16), 0x1); + odm_set_bb_reg(dm, 0x800, BIT(28), 0x1); + odm_set_bb_reg(dm, 0x850, BIT(23), 0x1); + } + + /* Update TXRX antenna status for PHYDM */ + dm->tx_ant_status = (tx_path & 0x3); + dm->rx_ant_status = (rx_path & 0x3); + + /* MP driver need to support path-B TX\RX */ + + while (1) { + counter++; + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x80000); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, + RFREGOFFSETMASK, 0x00001); + + ODM_delay_us(2); + rf_reg33 = config_phydm_read_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, RFREGOFFSETMASK); + + if ((rf_reg33 == 0x00001) && + (config_phydm_read_rf_check_8822b(rf_reg33))) + break; + else if (counter == 100) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to set TRx mode setting, because writing RF mode table is fail\n", + __func__); + return false; + } + } + + if ((dm->mp_mode) || *dm->antenna_test || (dm->normal_rx_path)) { + /* 0xef 0x80000 0x33 0x00001 0x3e 0x00034 0x3f 0x4080e + * 0xef 0x00000 suggested by Lucas + */ + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x80000); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, + RFREGOFFSETMASK, 0x00001); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3e, + RFREGOFFSETMASK, 0x00034); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3f, + RFREGOFFSETMASK, 0x4080e); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x00000); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): MP mode or Antenna test mode!! support path-B TX and RX\n", + __func__); + } else { + /* 0xef 0x80000 0x33 0x00001 0x3e 0x00034 0x3f 0x4080c + * 0xef 0x00000 + */ + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x80000); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, + RFREGOFFSETMASK, 0x00001); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3e, + RFREGOFFSETMASK, 0x00034); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3f, + RFREGOFFSETMASK, 0x4080c); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x00000); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Normal mode!! Do not support path-B TX and RX\n", + __func__); + } + + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x00000); + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to set TRx mode setting (TX: 0x%x, RX: 0x%x), because writing RF register is fail\n", + __func__, tx_path, rx_path); + return false; + } + + /* Toggle IGI to let RF enter RX mode, + * because BB doesn't send 3-wire command when RX path is enable + */ + IGI = (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + odm_write_dig(dm, IGI - 2); + odm_write_dig(dm, IGI); + + /* Modify CCA parameters */ + phydm_ccapar_by_rxpath_8822b(dm); + phydm_ccapar_by_rfe_8822b(dm); + phydm_rfe_8822b(dm, central_ch_8822b); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Success to set TRx mode setting (TX: 0x%x, RX: 0x%x)\n", + __func__, tx_path, rx_path); + return true; +} + +bool config_phydm_parameter_init(struct phy_dm_struct *dm, + enum odm_parameter_init type) +{ + if (type == ODM_PRE_SETTING) { + odm_set_bb_reg(dm, 0x808, (BIT(28) | BIT(29)), 0x0); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Pre setting: disable OFDM and CCK block\n", + __func__); + } else if (type == ODM_POST_SETTING) { + odm_set_bb_reg(dm, 0x808, (BIT(28) | BIT(29)), 0x3); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Post setting: enable OFDM and CCK block\n", + __func__); + reg82c_8822b = odm_get_bb_reg(dm, 0x82c, MASKDWORD); + reg838_8822b = odm_get_bb_reg(dm, 0x838, MASKDWORD); + reg830_8822b = odm_get_bb_reg(dm, 0x830, MASKDWORD); + reg83c_8822b = odm_get_bb_reg(dm, 0x83c, MASKDWORD); + rega20_8822b = odm_get_bb_reg(dm, 0xa20, MASKDWORD); + rega24_8822b = odm_get_bb_reg(dm, 0xa24, MASKDWORD); + rega28_8822b = odm_get_bb_reg(dm, 0xa28, MASKDWORD); + } else { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s(): Wrong type!!\n", + __func__); + return false; + } + + return true; +} + +/* ======================================================================== */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..279ef06298e260d48180e97c365bfbe6d9496333 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __INC_PHYDM_API_H_8822B__ +#define __INC_PHYDM_API_H_8822B__ + +/*2016.08.01 (HW user guide version: R27, SW user guide version: R05, + * Modification: R31) + */ +#define PHY_CONFIG_VERSION_8822B "27.5.31" + +#define INVALID_RF_DATA 0xffffffff +#define INVALID_TXAGC_DATA 0xff + +#define config_phydm_read_rf_check_8822b(data) (data != INVALID_RF_DATA) +#define config_phydm_read_txagc_check_8822b(data) (data != INVALID_TXAGC_DATA) + +u32 config_phydm_read_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, u32 reg_addr, + u32 bit_mask); + +bool config_phydm_write_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, + u32 reg_addr, u32 bit_mask, u32 data); + +bool config_phydm_write_txagc_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate); + +u8 config_phydm_read_txagc_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path path, u8 hw_rate); + +bool config_phydm_switch_band_8822b(struct phy_dm_struct *dm, u8 central_ch); + +bool config_phydm_switch_channel_8822b(struct phy_dm_struct *dm, u8 central_ch); + +bool config_phydm_switch_bandwidth_8822b(struct phy_dm_struct *dm, + u8 primary_ch_idx, + enum odm_bw bandwidth); + +bool config_phydm_switch_channel_bw_8822b(struct phy_dm_struct *dm, + u8 central_ch, u8 primary_ch_idx, + enum odm_bw bandwidth); + +bool config_phydm_trx_mode_8822b(struct phy_dm_struct *dm, + enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path); + +bool config_phydm_parameter_init(struct phy_dm_struct *dm, + enum odm_parameter_init type); + +/* ======================================================================== */ +/* These following functions can be used for PHY DM only*/ + +bool phydm_write_txagc_1byte_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate); + +void phydm_init_hw_info_by_rfe_type_8822b(struct phy_dm_struct *dm); + +s32 phydm_get_condition_number_8822B(struct phy_dm_struct *dm); + +/* ======================================================================== */ + +#endif /* __INC_PHYDM_API_H_8822B__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c new file mode 100644 index 0000000000000000000000000000000000000000..d320311213ccad67fc510514136f521315a8c9ea --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c @@ -0,0 +1,1410 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +/*---------------------------Define Local Constant---------------------------*/ + +static bool _iqk_rx_iqk_by_path_8822b(void *, u8); + +static inline void phydm_set_iqk_info(struct phy_dm_struct *dm, + struct dm_iqk_info *iqk_info, u8 status) +{ + bool KFAIL = true; + + while (1) { + KFAIL = _iqk_rx_iqk_by_path_8822b(dm, ODM_RF_PATH_A); + if (status == 0) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S0RXK KFail = 0x%x\n", KFAIL); + else if (status == 1) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S1RXK KFail = 0x%x\n", KFAIL); + if (iqk_info->rxiqk_step == 5) { + dm->rf_calibrate_info.iqk_step++; + iqk_info->rxiqk_step = 1; + if (KFAIL && status == 0) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S0RXK fail code: %d!!!\n", + iqk_info->rxiqk_fail_code + [0][ODM_RF_PATH_A]); + else if (KFAIL && status == 1) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S1RXK fail code: %d!!!\n", + iqk_info->rxiqk_fail_code + [0][ODM_RF_PATH_A]); + break; + } + } + + iqk_info->kcount++; +} + +static inline void phydm_init_iqk_information(struct dm_iqk_info *iqk_info) +{ + u8 i, j, k, m; + + for (i = 0; i < 2; i++) { + iqk_info->iqk_channel[i] = 0x0; + + for (j = 0; j < SS_8822B; j++) { + iqk_info->lok_idac[i][j] = 0x0; + iqk_info->rxiqk_agc[i][j] = 0x0; + iqk_info->bypass_iqk[i][j] = 0x0; + + for (k = 0; k < 2; k++) { + iqk_info->iqk_fail_report[i][j][k] = true; + for (m = 0; m < 8; m++) { + iqk_info->iqk_cfir_real[i][j][k][m] = + 0x0; + iqk_info->iqk_cfir_imag[i][j][k][m] = + 0x0; + } + } + + for (k = 0; k < 3; k++) + iqk_info->retry_count[i][j][k] = 0x0; + } + } +} + +static inline void phydm_backup_iqk_information(struct dm_iqk_info *iqk_info) +{ + u8 i, j, k; + + iqk_info->iqk_channel[1] = iqk_info->iqk_channel[0]; + for (i = 0; i < 2; i++) { + iqk_info->lok_idac[1][i] = iqk_info->lok_idac[0][i]; + iqk_info->rxiqk_agc[1][i] = iqk_info->rxiqk_agc[0][i]; + iqk_info->bypass_iqk[1][i] = iqk_info->bypass_iqk[0][i]; + iqk_info->rxiqk_fail_code[1][i] = + iqk_info->rxiqk_fail_code[0][i]; + for (j = 0; j < 2; j++) { + iqk_info->iqk_fail_report[1][i][j] = + iqk_info->iqk_fail_report[0][i][j]; + for (k = 0; k < 8; k++) { + iqk_info->iqk_cfir_real[1][i][j][k] = + iqk_info->iqk_cfir_real[0][i][j][k]; + iqk_info->iqk_cfir_imag[1][i][j][k] = + iqk_info->iqk_cfir_imag[0][i][j][k]; + } + } + } + + for (i = 0; i < 4; i++) { + iqk_info->rxiqk_fail_code[0][i] = 0x0; + iqk_info->rxiqk_agc[0][i] = 0x0; + for (j = 0; j < 2; j++) { + iqk_info->iqk_fail_report[0][i][j] = true; + iqk_info->gs_retry_count[0][i][j] = 0x0; + } + for (j = 0; j < 3; j++) + iqk_info->retry_count[0][i][j] = 0x0; + } +} + +static inline void phydm_set_iqk_cfir(struct phy_dm_struct *dm, + struct dm_iqk_info *iqk_info, u8 path) +{ + u8 idx, i; + u32 tmp; + + for (idx = 0; idx < 2; idx++) { + odm_set_bb_reg(dm, 0x1b00, MASKDWORD, 0xf8000008 | path << 1); + + if (idx == 0) + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x3); + else + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x1); + + odm_set_bb_reg(dm, 0x1bd4, + BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16), + 0x10); + + for (i = 0; i < 8; i++) { + odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, + 0xe0000001 + (i * 4)); + tmp = odm_get_bb_reg(dm, 0x1bfc, MASKDWORD); + iqk_info->iqk_cfir_real[0][path][idx][i] = + (tmp & 0x0fff0000) >> 16; + iqk_info->iqk_cfir_imag[0][path][idx][i] = tmp & 0xfff; + } + } +} + +static inline void phydm_get_read_counter(struct phy_dm_struct *dm) +{ + u32 counter = 0x0; + + while (1) { + if (((odm_read_4byte(dm, 0x1bf0) >> 24) == 0x7f) || + (counter > 300)) + break; + + counter++; + ODM_delay_ms(1); + } + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]counter = %d\n", counter); +} + +/*---------------------------Define Local Constant---------------------------*/ + +void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value, + u8 threshold) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + odm_reset_iqk_result(dm); + + dm->rf_calibrate_info.thermal_value_iqk = thermal_value; + + phy_iq_calibrate_8822b(dm, true); +} + +static void _iqk_fill_iqk_report_8822b(void *dm_void, u8 channel) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u32 tmp1 = 0x0, tmp2 = 0x0, tmp3 = 0x0; + u8 i; + + for (i = 0; i < SS_8822B; i++) { + tmp1 = tmp1 + + ((iqk_info->iqk_fail_report[channel][i][TX_IQK] & 0x1) + << i); + tmp2 = tmp2 + + ((iqk_info->iqk_fail_report[channel][i][RX_IQK] & 0x1) + << (i + 4)); + tmp3 = tmp3 + ((iqk_info->rxiqk_fail_code[channel][i] & 0x3) + << (i * 2 + 8)); + } + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_set_bb_reg(dm, 0x1bf0, 0x0000ffff, tmp1 | tmp2 | tmp3); + + for (i = 0; i < 2; i++) + odm_write_4byte( + dm, 0x1be8 + (i * 4), + (iqk_info->rxiqk_agc[channel][(i * 2) + 1] << 16) | + iqk_info->rxiqk_agc[channel][i * 2]); +} + +static void _iqk_backup_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup, + u32 *BB_backup, u32 *backup_mac_reg, + u32 *backup_bb_reg) +{ + u32 i; + + for (i = 0; i < MAC_REG_NUM_8822B; i++) + MAC_backup[i] = odm_read_4byte(dm, backup_mac_reg[i]); + + for (i = 0; i < BB_REG_NUM_8822B; i++) + BB_backup[i] = odm_read_4byte(dm, backup_bb_reg[i]); +} + +static void _iqk_backup_rf_8822b(struct phy_dm_struct *dm, u32 RF_backup[][2], + u32 *backup_rf_reg) +{ + u32 i; + + for (i = 0; i < RF_REG_NUM_8822B; i++) { + RF_backup[i][ODM_RF_PATH_A] = odm_get_rf_reg( + dm, ODM_RF_PATH_A, backup_rf_reg[i], RFREGOFFSETMASK); + RF_backup[i][ODM_RF_PATH_B] = odm_get_rf_reg( + dm, ODM_RF_PATH_B, backup_rf_reg[i], RFREGOFFSETMASK); + } +} + +static void _iqk_agc_bnd_int_8822b(struct phy_dm_struct *dm) +{ + /*initialize RX AGC bnd, it must do after bbreset*/ + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_write_4byte(dm, 0x1b00, 0xf80a7008); + odm_write_4byte(dm, 0x1b00, 0xf8015008); + odm_write_4byte(dm, 0x1b00, 0xf8000008); +} + +static void _iqk_bb_reset_8822b(struct phy_dm_struct *dm) +{ + bool cca_ing = false; + u32 count = 0; + + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x0, RFREGOFFSETMASK, 0x10000); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x0, RFREGOFFSETMASK, 0x10000); + + while (1) { + odm_write_4byte(dm, 0x8fc, 0x0); + odm_set_bb_reg(dm, 0x198c, 0x7, 0x7); + cca_ing = (bool)odm_get_bb_reg(dm, 0xfa0, BIT(3)); + + if (count > 30) + cca_ing = false; + + if (cca_ing) { + ODM_delay_ms(1); + count++; + } else { + odm_write_1byte(dm, 0x808, 0x0); /*RX ant off*/ + odm_set_bb_reg(dm, 0xa04, + BIT(27) | BIT(26) | BIT(25) | BIT(24), + 0x0); /*CCK RX path off*/ + + /*BBreset*/ + odm_set_bb_reg(dm, 0x0, BIT(16), 0x0); + odm_set_bb_reg(dm, 0x0, BIT(16), 0x1); + + if (odm_get_bb_reg(dm, 0x660, BIT(16))) + odm_write_4byte(dm, 0x6b4, 0x89000006); + break; + } + } +} + +static void _iqk_afe_setting_8822b(struct phy_dm_struct *dm, bool do_iqk) +{ + if (do_iqk) { + odm_write_4byte(dm, 0xc60, 0x50000000); + odm_write_4byte(dm, 0xc60, 0x70070040); + odm_write_4byte(dm, 0xe60, 0x50000000); + odm_write_4byte(dm, 0xe60, 0x70070040); + + odm_write_4byte(dm, 0xc58, 0xd8000402); + odm_write_4byte(dm, 0xc5c, 0xd1000120); + odm_write_4byte(dm, 0xc6c, 0x00000a15); + odm_write_4byte(dm, 0xe58, 0xd8000402); + odm_write_4byte(dm, 0xe5c, 0xd1000120); + odm_write_4byte(dm, 0xe6c, 0x00000a15); + _iqk_bb_reset_8822b(dm); + } else { + odm_write_4byte(dm, 0xc60, 0x50000000); + odm_write_4byte(dm, 0xc60, 0x70038040); + odm_write_4byte(dm, 0xe60, 0x50000000); + odm_write_4byte(dm, 0xe60, 0x70038040); + + odm_write_4byte(dm, 0xc58, 0xd8020402); + odm_write_4byte(dm, 0xc5c, 0xde000120); + odm_write_4byte(dm, 0xc6c, 0x0000122a); + odm_write_4byte(dm, 0xe58, 0xd8020402); + odm_write_4byte(dm, 0xe5c, 0xde000120); + odm_write_4byte(dm, 0xe6c, 0x0000122a); + } +} + +static void _iqk_restore_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup, + u32 *BB_backup, u32 *backup_mac_reg, + u32 *backup_bb_reg) +{ + u32 i; + + for (i = 0; i < MAC_REG_NUM_8822B; i++) + odm_write_4byte(dm, backup_mac_reg[i], MAC_backup[i]); + for (i = 0; i < BB_REG_NUM_8822B; i++) + odm_write_4byte(dm, backup_bb_reg[i], BB_backup[i]); +} + +static void _iqk_restore_rf_8822b(struct phy_dm_struct *dm, u32 *backup_rf_reg, + u32 RF_backup[][2]) +{ + u32 i; + + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, RFREGOFFSETMASK, 0x0); + /*0xdf[4]=0*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xdf, RFREGOFFSETMASK, + RF_backup[0][ODM_RF_PATH_A] & (~BIT(4))); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xdf, RFREGOFFSETMASK, + RF_backup[0][ODM_RF_PATH_B] & (~BIT(4))); + + for (i = 1; i < RF_REG_NUM_8822B; i++) { + odm_set_rf_reg(dm, ODM_RF_PATH_A, backup_rf_reg[i], + RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_A]); + odm_set_rf_reg(dm, ODM_RF_PATH_B, backup_rf_reg[i], + RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_B]); + } +} + +static void _iqk_backup_iqk_8822b(struct phy_dm_struct *dm, u8 step) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 path; + u16 iqk_apply[2] = {0xc94, 0xe94}; + + if (step == 0x0) { + phydm_backup_iqk_information(iqk_info); + } else { + iqk_info->iqk_channel[0] = iqk_info->rf_reg18; + for (path = 0; path < 2; path++) { + iqk_info->lok_idac[0][path] = + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x58, RFREGOFFSETMASK); + iqk_info->bypass_iqk[0][path] = + odm_get_bb_reg(dm, iqk_apply[path], MASKDWORD); + + phydm_set_iqk_cfir(dm, iqk_info, path); + odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0); + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0); + } + } +} + +static void _iqk_reload_iqk_setting_8822b( + struct phy_dm_struct *dm, u8 channel, + u8 reload_idx /*1: reload TX, 2: reload LO, TX, RX*/ + ) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 i, path, idx; + u16 iqk_apply[2] = {0xc94, 0xe94}; + + for (path = 0; path < 2; path++) { + if (reload_idx == 2) { + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf, + BIT(4), 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x58, + RFREGOFFSETMASK, + iqk_info->lok_idac[channel][path]); + } + + for (idx = 0; idx < reload_idx; idx++) { + odm_set_bb_reg(dm, 0x1b00, MASKDWORD, + 0xf8000008 | path << 1); + odm_set_bb_reg(dm, 0x1b2c, MASKDWORD, 0x7); + odm_set_bb_reg(dm, 0x1b38, MASKDWORD, 0x20000000); + odm_set_bb_reg(dm, 0x1b3c, MASKDWORD, 0x20000000); + odm_set_bb_reg(dm, 0x1bcc, MASKDWORD, 0x00000000); + + if (idx == 0) + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), + 0x3); + else + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), + 0x1); + + odm_set_bb_reg(dm, 0x1bd4, BIT(20) | BIT(19) | BIT(18) | + BIT(17) | BIT(16), + 0x10); + + for (i = 0; i < 8; i++) { + odm_write_4byte( + dm, 0x1bd8, + ((0xc0000000 >> idx) + 0x3) + (i * 4) + + (iqk_info->iqk_cfir_real + [channel][path][idx][i] + << 9)); + odm_write_4byte( + dm, 0x1bd8, + ((0xc0000000 >> idx) + 0x1) + (i * 4) + + (iqk_info->iqk_cfir_imag + [channel][path][idx][i] + << 9)); + } + } + odm_set_bb_reg(dm, iqk_apply[path], MASKDWORD, + iqk_info->bypass_iqk[channel][path]); + + odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0); + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0); + } +} + +static bool _iqk_reload_iqk_8822b(struct phy_dm_struct *dm, bool reset) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 i; + bool reload = false; + + if (reset) { + for (i = 0; i < 2; i++) + iqk_info->iqk_channel[i] = 0x0; + } else { + iqk_info->rf_reg18 = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + + for (i = 0; i < 2; i++) { + if (iqk_info->rf_reg18 == iqk_info->iqk_channel[i]) { + _iqk_reload_iqk_setting_8822b(dm, i, 2); + _iqk_fill_iqk_report_8822b(dm, i); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]reload IQK result before!!!!\n"); + reload = true; + } + } + } + return reload; +} + +static void _iqk_rfe_setting_8822b(struct phy_dm_struct *dm, bool ext_pa_on) +{ + if (ext_pa_on) { + /*RFE setting*/ + odm_write_4byte(dm, 0xcb0, 0x77777777); + odm_write_4byte(dm, 0xcb4, 0x00007777); + odm_write_4byte(dm, 0xcbc, 0x0000083B); + odm_write_4byte(dm, 0xeb0, 0x77777777); + odm_write_4byte(dm, 0xeb4, 0x00007777); + odm_write_4byte(dm, 0xebc, 0x0000083B); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]external PA on!!!!\n"); + } else { + /*RFE setting*/ + odm_write_4byte(dm, 0xcb0, 0x77777777); + odm_write_4byte(dm, 0xcb4, 0x00007777); + odm_write_4byte(dm, 0xcbc, 0x00000100); + odm_write_4byte(dm, 0xeb0, 0x77777777); + odm_write_4byte(dm, 0xeb4, 0x00007777); + odm_write_4byte(dm, 0xebc, 0x00000100); + } +} + +static void _iqk_rf_setting_8822b(struct phy_dm_struct *dm) +{ + u8 path; + u32 tmp; + + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_write_4byte(dm, 0x1bb8, 0x00000000); + + for (path = 0; path < 2; path++) { + /*0xdf:B11 = 1,B4 = 0, B1 = 1*/ + tmp = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf, + RFREGOFFSETMASK); + tmp = (tmp & (~BIT(4))) | BIT(1) | BIT(11); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf, + RFREGOFFSETMASK, tmp); + + /*release 0x56 TXBB*/ + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x65, + RFREGOFFSETMASK, 0x09000); + + if (*dm->band_type == ODM_BAND_5G) { + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + RFREGOFFSETMASK, 0x00026); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e, + RFREGOFFSETMASK, 0x00037); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f, + RFREGOFFSETMASK, 0xdefce); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x0); + } else { + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + RFREGOFFSETMASK, 0x00026); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e, + RFREGOFFSETMASK, 0x00037); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f, + RFREGOFFSETMASK, 0x5efce); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x0); + } + } +} + +static void _iqk_configure_macbb_8822b(struct phy_dm_struct *dm) +{ + /*MACBB register setting*/ + odm_write_1byte(dm, 0x522, 0x7f); + odm_set_bb_reg(dm, 0x550, BIT(11) | BIT(3), 0x0); + odm_set_bb_reg(dm, 0x90c, BIT(15), + 0x1); /*0x90c[15]=1: dac_buf reset selection*/ + odm_set_bb_reg(dm, 0x9a4, BIT(31), + 0x0); /*0x9a4[31]=0: Select da clock*/ + /*0xc94[0]=1, 0xe94[0]=1: let tx through iqk*/ + odm_set_bb_reg(dm, 0xc94, BIT(0), 0x1); + odm_set_bb_reg(dm, 0xe94, BIT(0), 0x1); + /* 3-wire off*/ + odm_write_4byte(dm, 0xc00, 0x00000004); + odm_write_4byte(dm, 0xe00, 0x00000004); +} + +static void _iqk_lok_setting_8822b(struct phy_dm_struct *dm, u8 path) +{ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1bcc, 0x9); + odm_write_1byte(dm, 0x1b23, 0x00); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + odm_write_1byte(dm, 0x1b2b, 0x00); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x50df2); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xadc00); + /* WE_LUT_TX_LOK*/ + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4), + 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + BIT(1) | BIT(0), 0x0); + break; + case ODM_BAND_5G: + odm_write_1byte(dm, 0x1b2b, 0x80); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x5086c); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + /* WE_LUT_TX_LOK*/ + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4), + 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + BIT(1) | BIT(0), 0x1); + break; + } +} + +static void _iqk_txk_setting_8822b(struct phy_dm_struct *dm, u8 path) +{ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1bcc, 0x9); + odm_write_4byte(dm, 0x1b20, 0x01440008); + + if (path == 0x0) + odm_write_4byte(dm, 0x1b00, 0xf800000a); + else + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_write_4byte(dm, 0x1bcc, 0x3f); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x50df2); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xadc00); + odm_write_1byte(dm, 0x1b2b, 0x00); + break; + case ODM_BAND_5G: + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x500ef); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + odm_write_1byte(dm, 0x1b2b, 0x80); + break; + } +} + +static void _iqk_rxk1_setting_8822b(struct phy_dm_struct *dm, u8 path) +{ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + odm_write_1byte(dm, 0x1bcc, 0x9); + odm_write_1byte(dm, 0x1b2b, 0x00); + odm_write_4byte(dm, 0x1b20, 0x01450008); + odm_write_4byte(dm, 0x1b24, 0x01460c88); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x510e0); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xacc00); + break; + case ODM_BAND_5G: + odm_write_1byte(dm, 0x1bcc, 0x09); + odm_write_1byte(dm, 0x1b2b, 0x80); + odm_write_4byte(dm, 0x1b20, 0x00850008); + odm_write_4byte(dm, 0x1b24, 0x00460048); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x510e0); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xadc00); + break; + } +} + +static void _iqk_rxk2_setting_8822b(struct phy_dm_struct *dm, u8 path, + bool is_gs) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + if (is_gs) + iqk_info->tmp1bcc = 0x12; + odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc); + odm_write_1byte(dm, 0x1b2b, 0x00); + odm_write_4byte(dm, 0x1b20, 0x01450008); + odm_write_4byte(dm, 0x1b24, 0x01460848); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x510e0); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + break; + case ODM_BAND_5G: + if (is_gs) { + if (path == ODM_RF_PATH_A) + iqk_info->tmp1bcc = 0x12; + else + iqk_info->tmp1bcc = 0x09; + } + odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc); + odm_write_1byte(dm, 0x1b2b, 0x80); + odm_write_4byte(dm, 0x1b20, 0x00850008); + odm_write_4byte(dm, 0x1b24, 0x00460848); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x51060); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + break; + } +} + +static bool _iqk_check_cal_8822b(struct phy_dm_struct *dm, u32 IQK_CMD) +{ + bool notready = true, fail = true; + u32 delay_count = 0x0; + + while (notready) { + if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) { + fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26)); + notready = false; + } else { + ODM_delay_ms(1); + delay_count++; + } + + if (delay_count >= 50) { + fail = true; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]IQK timeout!!!\n"); + break; + } + } + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay count = 0x%x!!!\n", + delay_count); + return fail; +} + +static bool _iqk_rx_iqk_gain_search_fail_8822b(struct phy_dm_struct *dm, + u8 path, u8 step) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + bool fail = true; + u32 IQK_CMD = 0x0, rf_reg0, tmp, bb_idx; + u8 IQMUX[4] = {0x9, 0x12, 0x1b, 0x24}; + u8 idx; + + for (idx = 0; idx < 4; idx++) + if (iqk_info->tmp1bcc == IQMUX[idx]) + break; + + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1bcc, iqk_info->tmp1bcc); + + if (step == RXIQK1) + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d RXIQK GainSearch ============\n", + path); + + if (step == RXIQK1) + IQK_CMD = 0xf8000208 | (1 << (path + 4)); + else + IQK_CMD = 0xf8000308 | (1 << (path + 4)); + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]S%d GS%d_Trigger = 0x%x\n", + path, step, IQK_CMD); + + odm_write_4byte(dm, 0x1b00, IQK_CMD); + odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); + ODM_delay_ms(GS_delay_8822B); + fail = _iqk_check_cal_8822b(dm, IQK_CMD); + + if (step == RXIQK2) { + rf_reg0 = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0x0, + RFREGOFFSETMASK); + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> RF0x0 = 0x%x, tmp1bcc = 0x%x, idx = %d, 0x1b3c = 0x%x\n", + path, rf_reg0, iqk_info->tmp1bcc, idx, + odm_read_4byte(dm, 0x1b3c)); + tmp = (rf_reg0 & 0x1fe0) >> 5; + iqk_info->lna_idx = tmp >> 5; + bb_idx = tmp & 0x1f; + if (bb_idx == 0x1) { + if (iqk_info->lna_idx != 0x0) + iqk_info->lna_idx--; + else if (idx != 3) + idx++; + else + iqk_info->isbnd = true; + fail = true; + } else if (bb_idx == 0xa) { + if (idx != 0) + idx--; + else if (iqk_info->lna_idx != 0x7) + iqk_info->lna_idx++; + else + iqk_info->isbnd = true; + fail = true; + } else { + fail = false; + } + + if (iqk_info->isbnd) + fail = false; + + iqk_info->tmp1bcc = IQMUX[idx]; + + if (fail) { + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte( + dm, 0x1b24, + (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) | + (iqk_info->lna_idx << 10)); + } + } + + return fail; +} + +static bool _lok_one_shot_8822b(void *dm_void, u8 path) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 delay_count = 0; + bool LOK_notready = false; + u32 LOK_temp = 0; + u32 IQK_CMD = 0x0; + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========S%d LOK ==========\n", path); + + IQK_CMD = 0xf8000008 | (1 << (4 + path)); + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]LOK_Trigger = 0x%x\n", + IQK_CMD); + + odm_write_4byte(dm, 0x1b00, IQK_CMD); + odm_write_4byte(dm, 0x1b00, IQK_CMD + 1); + /*LOK: CMD ID = 0 {0xf8000018, 0xf8000028}*/ + /*LOK: CMD ID = 0 {0xf8000019, 0xf8000029}*/ + ODM_delay_ms(LOK_delay_8822B); + + delay_count = 0; + LOK_notready = true; + + while (LOK_notready) { + if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) + LOK_notready = false; + else + LOK_notready = true; + + if (LOK_notready) { + ODM_delay_ms(1); + delay_count++; + } + + if (delay_count >= 50) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d LOK timeout!!!\n", path); + break; + } + } + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> delay_count = 0x%x\n", path, delay_count); + if (ODM_COMP_CALIBRATION) { + if (!LOK_notready) { + LOK_temp = + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x58, RFREGOFFSETMASK); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]0x58 = 0x%x\n", LOK_temp); + } else { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==>S%d LOK Fail!!!\n", path); + } + } + iqk_info->lok_fail[path] = LOK_notready; + return LOK_notready; +} + +static bool _iqk_one_shot_8822b(void *dm_void, u8 path, u8 idx) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 delay_count = 0; + bool notready = true, fail = true; + u32 IQK_CMD = 0x0; + u16 iqk_apply[2] = {0xc94, 0xe94}; + + if (idx == TXIQK) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d WBTXIQK ============\n", + path); + else if (idx == RXIQK1) + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d WBRXIQK STEP1============\n", + path); + else + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d WBRXIQK STEP2============\n", + path); + + if (idx == TXIQK) { + IQK_CMD = 0xf8000008 | ((*dm->band_width + 4) << 8) | + (1 << (path + 4)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]TXK_Trigger = 0x%x\n", IQK_CMD); + /*{0xf8000418, 0xf800042a} ==> 20 WBTXK (CMD = 4)*/ + /*{0xf8000518, 0xf800052a} ==> 40 WBTXK (CMD = 5)*/ + /*{0xf8000618, 0xf800062a} ==> 80 WBTXK (CMD = 6)*/ + } else if (idx == RXIQK1) { + if (*dm->band_width == 2) + IQK_CMD = 0xf8000808 | (1 << (path + 4)); + else + IQK_CMD = 0xf8000708 | (1 << (path + 4)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]RXK1_Trigger = 0x%x\n", IQK_CMD); + /*{0xf8000718, 0xf800072a} ==> 20 WBTXK (CMD = 7)*/ + /*{0xf8000718, 0xf800072a} ==> 40 WBTXK (CMD = 7)*/ + /*{0xf8000818, 0xf800082a} ==> 80 WBTXK (CMD = 8)*/ + } else if (idx == RXIQK2) { + IQK_CMD = 0xf8000008 | ((*dm->band_width + 9) << 8) | + (1 << (path + 4)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]RXK2_Trigger = 0x%x\n", IQK_CMD); + /*{0xf8000918, 0xf800092a} ==> 20 WBRXK (CMD = 9)*/ + /*{0xf8000a18, 0xf8000a2a} ==> 40 WBRXK (CMD = 10)*/ + /*{0xf8000b18, 0xf8000b2a} ==> 80 WBRXK (CMD = 11)*/ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1b24, + (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) | + ((iqk_info->lna_idx & 0x7) << 10)); + } + odm_write_4byte(dm, 0x1b00, IQK_CMD); + odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); + ODM_delay_ms(WBIQK_delay_8822B); + + while (notready) { + if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) + notready = false; + else + notready = true; + + if (notready) { + ODM_delay_ms(1); + delay_count++; + } else { + fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26)); + break; + } + + if (delay_count >= 50) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d IQK timeout!!!\n", path); + break; + } + } + + if (dm->debug_components & ODM_COMP_CALIBRATION) { + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> 0x1b00 = 0x%x, 0x1b08 = 0x%x\n", + path, odm_read_4byte(dm, 0x1b00), + odm_read_4byte(dm, 0x1b08)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> delay_count = 0x%x\n", path, + delay_count); + if (idx != TXIQK) + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> RF0x0 = 0x%x, RF0x56 = 0x%x\n", + path, + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x0, RFREGOFFSETMASK), + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x56, RFREGOFFSETMASK)); + } + + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + + if (idx == TXIQK) + if (fail) + odm_set_bb_reg(dm, iqk_apply[path], BIT(0), 0x0); + + if (idx == RXIQK2) { + iqk_info->rxiqk_agc[0][path] = + (u16)(((odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x0, RFREGOFFSETMASK) >> + 5) & + 0xff) | + (iqk_info->tmp1bcc << 8)); + + odm_write_4byte(dm, 0x1b38, 0x20000000); + + if (!fail) + odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)), + 0x1); + else + odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)), + 0x0); + } + + if (idx == TXIQK) + iqk_info->iqk_fail_report[0][path][TXIQK] = fail; + else + iqk_info->iqk_fail_report[0][path][RXIQK] = fail; + + return fail; +} + +static bool _iqk_rx_iqk_by_path_8822b(void *dm_void, u8 path) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + bool KFAIL = true, gonext; + + switch (iqk_info->rxiqk_step) { + case 1: /*gain search_RXK1*/ + _iqk_rxk1_setting_8822b(dm, path); + gonext = false; + while (1) { + KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path, + RXIQK1); + if (KFAIL && + (iqk_info->gs_retry_count[0][path][GSRXK1] < 2)) + iqk_info->gs_retry_count[0][path][GSRXK1]++; + else if (KFAIL) { + iqk_info->rxiqk_fail_code[0][path] = 0; + iqk_info->rxiqk_step = 5; + gonext = true; + } else { + iqk_info->rxiqk_step++; + gonext = true; + } + if (gonext) + break; + } + break; + case 2: /*gain search_RXK2*/ + _iqk_rxk2_setting_8822b(dm, path, true); + iqk_info->isbnd = false; + while (1) { + KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path, + RXIQK2); + if (KFAIL && + (iqk_info->gs_retry_count[0][path][GSRXK2] < + rxiqk_gs_limit)) { + iqk_info->gs_retry_count[0][path][GSRXK2]++; + } else { + iqk_info->rxiqk_step++; + break; + } + } + break; + case 3: /*RXK1*/ + _iqk_rxk1_setting_8822b(dm, path); + gonext = false; + while (1) { + KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK1); + if (KFAIL && + (iqk_info->retry_count[0][path][RXIQK1] < 2)) + iqk_info->retry_count[0][path][RXIQK1]++; + else if (KFAIL) { + iqk_info->rxiqk_fail_code[0][path] = 1; + iqk_info->rxiqk_step = 5; + gonext = true; + } else { + iqk_info->rxiqk_step++; + gonext = true; + } + if (gonext) + break; + } + break; + case 4: /*RXK2*/ + _iqk_rxk2_setting_8822b(dm, path, false); + gonext = false; + while (1) { + KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK2); + if (KFAIL && + (iqk_info->retry_count[0][path][RXIQK2] < 2)) + iqk_info->retry_count[0][path][RXIQK2]++; + else if (KFAIL) { + iqk_info->rxiqk_fail_code[0][path] = 2; + iqk_info->rxiqk_step = 5; + gonext = true; + } else { + iqk_info->rxiqk_step++; + gonext = true; + } + if (gonext) + break; + } + break; + } + return KFAIL; +} + +static void _iqk_iqk_by_path_8822b(void *dm_void, bool segment_iqk) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + bool KFAIL = true; + u8 i, kcount_limit; + + if (*dm->band_width == 2) + kcount_limit = kcount_limit_80m; + else + kcount_limit = kcount_limit_others; + + while (1) { + switch (dm->rf_calibrate_info.iqk_step) { + case 1: /*S0 LOK*/ + _iqk_lok_setting_8822b(dm, ODM_RF_PATH_A); + _lok_one_shot_8822b(dm, ODM_RF_PATH_A); + dm->rf_calibrate_info.iqk_step++; + break; + case 2: /*S1 LOK*/ + _iqk_lok_setting_8822b(dm, ODM_RF_PATH_B); + _lok_one_shot_8822b(dm, ODM_RF_PATH_B); + dm->rf_calibrate_info.iqk_step++; + break; + case 3: /*S0 TXIQK*/ + _iqk_txk_setting_8822b(dm, ODM_RF_PATH_A); + KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_A, TXIQK); + iqk_info->kcount++; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S0TXK KFail = 0x%x\n", KFAIL); + + if (KFAIL && + (iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK] < + 3)) + iqk_info->retry_count[0][ODM_RF_PATH_A] + [TXIQK]++; + else + dm->rf_calibrate_info.iqk_step++; + break; + case 4: /*S1 TXIQK*/ + _iqk_txk_setting_8822b(dm, ODM_RF_PATH_B); + KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_B, TXIQK); + iqk_info->kcount++; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S1TXK KFail = 0x%x\n", KFAIL); + if (KFAIL && + iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK] < 3) + iqk_info->retry_count[0][ODM_RF_PATH_B] + [TXIQK]++; + else + dm->rf_calibrate_info.iqk_step++; + break; + case 5: /*S0 RXIQK*/ + phydm_set_iqk_info(dm, iqk_info, 0); + break; + case 6: /*S1 RXIQK*/ + phydm_set_iqk_info(dm, iqk_info, 1); + break; + } + + if (dm->rf_calibrate_info.iqk_step == 7) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========LOK summary ==========\n"); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_LOK_notready = %d, PathB_LOK1_notready = %d\n", + iqk_info->lok_fail[ODM_RF_PATH_A], + iqk_info->lok_fail[ODM_RF_PATH_B]); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========IQK summary ==========\n"); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_TXIQK_fail = %d, PathB_TXIQK_fail = %d\n", + iqk_info->iqk_fail_report[0][ODM_RF_PATH_A] + [TXIQK], + iqk_info->iqk_fail_report[0][ODM_RF_PATH_B] + [TXIQK]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_RXIQK_fail = %d, PathB_RXIQK_fail = %d\n", + iqk_info->iqk_fail_report[0][ODM_RF_PATH_A] + [RXIQK], + iqk_info->iqk_fail_report[0][ODM_RF_PATH_B] + [RXIQK]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_TXIQK_retry = %d, PathB_TXIQK_retry = %d\n", + iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK], + iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_RXK1_retry = %d, PathA_RXK2_retry = %d, PathB_RXK1_retry = %d, PathB_RXK2_retry = %d\n", + iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK1], + iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK2], + iqk_info->retry_count[0][ODM_RF_PATH_B][RXIQK1], + iqk_info->retry_count[0][ODM_RF_PATH_B] + [RXIQK2]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_GS1_retry = %d, PathA_GS2_retry = %d, PathB_GS1_retry = %d, PathB_GS2_retry = %d\n", + iqk_info->gs_retry_count[0][ODM_RF_PATH_A] + [GSRXK1], + iqk_info->gs_retry_count[0][ODM_RF_PATH_A] + [GSRXK2], + iqk_info->gs_retry_count[0][ODM_RF_PATH_B] + [GSRXK1], + iqk_info->gs_retry_count[0][ODM_RF_PATH_B] + [GSRXK2]); + for (i = 0; i < 2; i++) { + odm_write_4byte(dm, 0x1b00, + 0xf8000008 | i << 1); + odm_write_4byte(dm, 0x1b2c, 0x7); + odm_write_4byte(dm, 0x1bcc, 0x0); + } + break; + } + + if (segment_iqk && (iqk_info->kcount == kcount_limit)) + break; + } +} + +static void _iqk_start_iqk_8822b(struct phy_dm_struct *dm, bool segment_iqk) +{ + u32 tmp; + + /*GNT_WL = 1*/ + tmp = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK); + tmp = tmp | BIT(5) | BIT(0); + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK, tmp); + + tmp = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK); + tmp = tmp | BIT(5) | BIT(0); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK, tmp); + + _iqk_iqk_by_path_8822b(dm, segment_iqk); +} + +static void _iq_calibrate_8822b_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 i, j; + + if (iqk_info->iqk_times == 0) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]=====>PHY_IQCalibrate_8822B_Init\n"); + + for (i = 0; i < SS_8822B; i++) { + for (j = 0; j < 2; j++) { + iqk_info->lok_fail[i] = true; + iqk_info->iqk_fail[j][i] = true; + iqk_info->iqc_matrix[j][i] = 0x20000000; + } + } + + phydm_init_iqk_information(iqk_info); + } +} + +static void _phy_iq_calibrate_8822b(struct phy_dm_struct *dm, bool reset) +{ + u32 MAC_backup[MAC_REG_NUM_8822B], BB_backup[BB_REG_NUM_8822B], + RF_backup[RF_REG_NUM_8822B][SS_8822B]; + u32 backup_mac_reg[MAC_REG_NUM_8822B] = {0x520, 0x550}; + u32 backup_bb_reg[BB_REG_NUM_8822B] = { + 0x808, 0x90c, 0xc00, 0xcb0, 0xcb4, 0xcbc, 0xe00, + 0xeb0, 0xeb4, 0xebc, 0x1990, 0x9a4, 0xa04}; + u32 backup_rf_reg[RF_REG_NUM_8822B] = {0xdf, 0x8f, 0x65, 0x0, 0x1}; + bool segment_iqk = false, is_mp = false; + + struct dm_iqk_info *iqk_info = &dm->IQK_info; + + if (dm->mp_mode) + is_mp = true; + else if (dm->is_linked) + segment_iqk = true; + + if (!is_mp) + if (_iqk_reload_iqk_8822b(dm, reset)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========IQK strat!!!!!==========\n"); + + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]band_type = %s, band_width = %d, ExtPA2G = %d, ext_pa_5g = %d\n", + (*dm->band_type == ODM_BAND_5G) ? "5G" : "2G", *dm->band_width, + dm->ext_pa, dm->ext_pa_5g); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]Interface = %d, cut_version = %x\n", + dm->support_interface, dm->cut_version); + + iqk_info->iqk_times++; + + iqk_info->kcount = 0; + dm->rf_calibrate_info.iqk_total_progressing_time = 0; + dm->rf_calibrate_info.iqk_step = 1; + iqk_info->rxiqk_step = 1; + + _iqk_backup_iqk_8822b(dm, 0); + _iqk_backup_mac_bb_8822b(dm, MAC_backup, BB_backup, backup_mac_reg, + backup_bb_reg); + _iqk_backup_rf_8822b(dm, RF_backup, backup_rf_reg); + + while (1) { + if (!is_mp) + dm->rf_calibrate_info.iqk_start_time = + odm_get_current_time(dm); + + _iqk_configure_macbb_8822b(dm); + _iqk_afe_setting_8822b(dm, true); + _iqk_rfe_setting_8822b(dm, false); + _iqk_agc_bnd_int_8822b(dm); + _iqk_rf_setting_8822b(dm); + + _iqk_start_iqk_8822b(dm, segment_iqk); + + _iqk_afe_setting_8822b(dm, false); + _iqk_restore_mac_bb_8822b(dm, MAC_backup, BB_backup, + backup_mac_reg, backup_bb_reg); + _iqk_restore_rf_8822b(dm, backup_rf_reg, RF_backup); + + if (!is_mp) { + dm->rf_calibrate_info.iqk_progressing_time = + odm_get_progressing_time( + dm, + dm->rf_calibrate_info.iqk_start_time); + dm->rf_calibrate_info.iqk_total_progressing_time += + odm_get_progressing_time( + dm, + dm->rf_calibrate_info.iqk_start_time); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info.iqk_progressing_time); + } + + if (dm->rf_calibrate_info.iqk_step == 7) + break; + + iqk_info->kcount = 0; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay 50ms!!!\n"); + ODM_delay_ms(50); + }; + + _iqk_backup_iqk_8822b(dm, 1); + _iqk_fill_iqk_report_8822b(dm, 0); + + if (!is_mp) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]Total IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info.iqk_total_progressing_time); + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========IQK end!!!!!==========\n"); +} + +static void _phy_iq_calibrate_by_fw_8822b(void *dm_void, u8 clear) {} + +/*IQK version:v3.3, NCTL v0.6*/ +/*1.The new gainsearch method for RXIQK*/ +/*2.The new format of IQK report register: 0x1be8/0x1bec*/ +/*3. add the option of segment IQK*/ +void phy_iq_calibrate_8822b(void *dm_void, bool clear) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + dm->iqk_fw_offload = 0; + + /*FW IQK*/ + if (dm->iqk_fw_offload) { + if (!dm->rf_calibrate_info.is_iqk_in_progress) { + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = true; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + + dm->rf_calibrate_info.iqk_start_time = + odm_get_current_time(dm); + + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_set_bb_reg(dm, 0x1bf0, 0xff000000, 0xff); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]0x1bf0 = 0x%x\n", + odm_read_4byte(dm, 0x1bf0)); + + _phy_iq_calibrate_by_fw_8822b(dm, clear); + phydm_get_read_counter(dm); + + dm->rf_calibrate_info.iqk_progressing_time = + odm_get_progressing_time( + dm, + dm->rf_calibrate_info.iqk_start_time); + + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info.iqk_progressing_time); + + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = false; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + } else { + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "== Return the IQK CMD, because the IQK in Progress ==\n"); + } + + } else { + _iq_calibrate_8822b_init(dm_void); + + if (!dm->rf_calibrate_info.is_iqk_in_progress) { + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = true; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + if (dm->mp_mode) + dm->rf_calibrate_info.iqk_start_time = + odm_get_current_time(dm); + + _phy_iq_calibrate_8822b(dm, clear); + if (dm->mp_mode) { + dm->rf_calibrate_info.iqk_progressing_time = + odm_get_progressing_time( + dm, dm->rf_calibrate_info + .iqk_start_time); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info + .iqk_progressing_time); + } + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = false; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + } else { + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]== Return the IQK CMD, because the IQK in Progress ==\n"); + } + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..ea19deb512d57ab824961c92947a9b294a75ee34 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __PHYDM_IQK_8822B_H__ +#define __PHYDM_IQK_8822B_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define MAC_REG_NUM_8822B 2 +#define BB_REG_NUM_8822B 13 +#define RF_REG_NUM_8822B 5 + +#define LOK_delay_8822B 2 +#define GS_delay_8822B 2 +#define WBIQK_delay_8822B 2 + +#define TXIQK 0 +#define RXIQK 1 +#define SS_8822B 2 + +/*------------------------End Define Parameters-------------------------------*/ + +void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value, + u8 threshold); + +void phy_iq_calibrate_8822b(void *dm_void, bool clear); + +#endif /* #ifndef __PHYDM_IQK_8822B_H__*/ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c new file mode 100644 index 0000000000000000000000000000000000000000..644fca822c61cfaa3d289e02a3c5f57338d9308a --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c @@ -0,0 +1,168 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +void odm_config_rf_reg_8822b(struct phy_dm_struct *dm, u32 addr, u32 data, + enum odm_rf_radio_path RF_PATH, u32 reg_addr) +{ + if (addr == 0xffe) { + ODM_sleep_ms(50); + } else if (addr == 0xfe) { + ODM_delay_us(100); + } else { + odm_set_rf_reg(dm, RF_PATH, reg_addr, RFREGOFFSETMASK, data); + + /* Add 1us delay between BB/RF register setting. */ + ODM_delay_us(1); + } +} + +void odm_config_rf_radio_a_8822b(struct phy_dm_struct *dm, u32 addr, u32 data) +{ + u32 content = 0x1000; /* RF_Content: radioa_txt */ + u32 maskfor_phy_set = (u32)(content & 0xE000); + + odm_config_rf_reg_8822b(dm, addr, data, ODM_RF_PATH_A, + addr | maskfor_phy_set); + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> odm_config_rf_with_header_file: [RadioA] %08X %08X\n", + addr, data); +} + +void odm_config_rf_radio_b_8822b(struct phy_dm_struct *dm, u32 addr, u32 data) +{ + u32 content = 0x1001; /* RF_Content: radiob_txt */ + u32 maskfor_phy_set = (u32)(content & 0xE000); + + odm_config_rf_reg_8822b(dm, addr, data, ODM_RF_PATH_B, + addr | maskfor_phy_set); + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> odm_config_rf_with_header_file: [RadioB] %08X %08X\n", + addr, data); +} + +void odm_config_mac_8822b(struct phy_dm_struct *dm, u32 addr, u8 data) +{ + odm_write_1byte(dm, addr, data); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> odm_config_mac_with_header_file: [MAC_REG] %08X %08X\n", + addr, data); +} + +void odm_update_agc_big_jump_lmt_8822b(struct phy_dm_struct *dm, u32 addr, + u32 data) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + u8 rf_gain_idx = (u8)((data & 0xFF000000) >> 24); + u8 bb_gain_idx = (u8)((data & 0x00ff0000) >> 16); + u8 agc_table_idx = (u8)((data & 0x00000f00) >> 8); + static bool is_limit; + + if (addr != 0x81c) + return; + + if (bb_gain_idx > 0x3c) { + if ((rf_gain_idx == dig_tab->rf_gain_idx) && !is_limit) { + is_limit = true; + dig_tab->big_jump_lmt[agc_table_idx] = bb_gain_idx - 2; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "===> [AGC_TAB] big_jump_lmt [%d] = 0x%x\n", + agc_table_idx, + dig_tab->big_jump_lmt[agc_table_idx]); + } + } else { + is_limit = false; + } + + dig_tab->rf_gain_idx = rf_gain_idx; +} + +void odm_config_bb_agc_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data) +{ + odm_update_agc_big_jump_lmt_8822b(dm, addr, data); + + odm_set_bb_reg(dm, addr, bitmask, data); + + /* Add 1us delay between BB/RF register setting. */ + ODM_delay_us(1); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [AGC_TAB] %08X %08X\n", + __func__, addr, data); +} + +void odm_config_bb_phy_reg_pg_8822b(struct phy_dm_struct *dm, u32 band, + u32 rf_path, u32 tx_num, u32 addr, + u32 bitmask, u32 data) +{ + if (addr == 0xfe || addr == 0xffe) { + ODM_sleep_ms(50); + } else { + phy_store_tx_power_by_rate(dm->adapter, band, rf_path, tx_num, + addr, bitmask, data); + } + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [PHY_REG] %08X %08X %08X\n", + __func__, addr, bitmask, data); +} + +void odm_config_bb_phy_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data) +{ + if (addr == 0xfe) + ODM_sleep_ms(50); + else if (addr == 0xfd) + ODM_delay_ms(5); + else if (addr == 0xfc) + ODM_delay_ms(1); + else if (addr == 0xfb) + ODM_delay_us(50); + else if (addr == 0xfa) + ODM_delay_us(5); + else if (addr == 0xf9) + ODM_delay_us(1); + else + odm_set_bb_reg(dm, addr, bitmask, data); + + /* Add 1us delay between BB/RF register setting. */ + ODM_delay_us(1); + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [PHY_REG] %08X %08X\n", + __func__, addr, data); +} + +void odm_config_bb_txpwr_lmt_8822b(struct phy_dm_struct *dm, u8 *regulation, + u8 *band, u8 *bandwidth, u8 *rate_section, + u8 *rf_path, u8 *channel, u8 *power_limit) +{ + phy_set_tx_power_limit(dm, regulation, band, bandwidth, rate_section, + rf_path, channel, power_limit); +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..4817cf6b1ed9da06976fb9fc8451ae0e5166023e --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __INC_ODM_REGCONFIG_H_8822B +#define __INC_ODM_REGCONFIG_H_8822B + +void odm_config_rf_reg_8822b(struct phy_dm_struct *dm, u32 addr, u32 data, + enum odm_rf_radio_path RF_PATH, u32 reg_addr); + +void odm_config_rf_radio_a_8822b(struct phy_dm_struct *dm, u32 addr, u32 data); + +void odm_config_rf_radio_b_8822b(struct phy_dm_struct *dm, u32 addr, u32 data); + +void odm_config_mac_8822b(struct phy_dm_struct *dm, u32 addr, u8 data); + +void odm_update_agc_big_jump_lmt_8822b(struct phy_dm_struct *dm, u32 addr, + u32 data); + +void odm_config_bb_agc_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data); + +void odm_config_bb_phy_reg_pg_8822b(struct phy_dm_struct *dm, u32 band, + u32 rf_path, u32 tx_num, u32 addr, + u32 bitmask, u32 data); + +void odm_config_bb_phy_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data); + +void odm_config_bb_txpwr_lmt_8822b(struct phy_dm_struct *dm, u8 *regulation, + u8 *band, u8 *bandwidth, u8 *rate_section, + u8 *rf_path, u8 *channel, u8 *power_limit); + +#endif /* RTL8822B_SUPPORT == 1*/ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c new file mode 100644 index 0000000000000000000000000000000000000000..59adabda09de9bf0bf0ae30385392507e8f4c8cf --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c @@ -0,0 +1,225 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static void phydm_dynamic_switch_htstf_mumimo_8822b(struct phy_dm_struct *dm) +{ + /*if rssi > 40dBm, enable HT-STF gain controller, + *otherwise, if rssi < 40dBm, disable the controller + */ + /*add by Chun-Hung Ho 20160711 */ + if (dm->rssi_min >= 40) + odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x1); + else if (dm->rssi_min < 35) + odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x0); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s, rssi_min = %d\n", __func__, + dm->rssi_min); +} + +static void _set_tx_a_cali_value(struct phy_dm_struct *dm, u8 rf_path, + u8 offset, u8 tx_a_bias_offset) +{ + u32 modi_tx_a_value = 0; + u8 tmp1_byte = 0; + bool is_minus = false; + u8 comp_value = 0; + + switch (offset) { + case 0x0: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10124); + break; + case 0x1: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10524); + break; + case 0x2: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10924); + break; + case 0x3: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10D24); + break; + case 0x4: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30164); + break; + case 0x5: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30564); + break; + case 0x6: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30964); + break; + case 0x7: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30D64); + break; + case 0x8: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50195); + break; + case 0x9: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50595); + break; + case 0xa: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50995); + break; + case 0xb: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50D95); + break; + default: + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "Invalid TxA band offset...\n"); + return; + } + + /* Get TxA value */ + modi_tx_a_value = odm_get_rf_reg(dm, rf_path, 0x61, 0xFFFFF); + tmp1_byte = (u8)modi_tx_a_value & (BIT(3) | BIT(2) | BIT(1) | BIT(0)); + + /* check how much need to calibration */ + switch (tx_a_bias_offset) { + case 0xF6: + is_minus = true; + comp_value = 3; + break; + + case 0xF4: + is_minus = true; + comp_value = 2; + break; + + case 0xF2: + is_minus = true; + comp_value = 1; + break; + + case 0xF3: + is_minus = false; + comp_value = 1; + break; + + case 0xF5: + is_minus = false; + comp_value = 2; + break; + + case 0xF7: + is_minus = false; + comp_value = 3; + break; + + case 0xF9: + is_minus = false; + comp_value = 4; + break; + + /* do nothing case */ + case 0xF0: + default: + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "No need to do TxA bias current calibration\n"); + return; + } + + /* calc correct value to calibrate */ + if (is_minus) { + if (tmp1_byte >= comp_value) { + tmp1_byte -= comp_value; + /*modi_tx_a_value += tmp1_byte;*/ + } else { + tmp1_byte = 0; + } + } else { + tmp1_byte += comp_value; + if (tmp1_byte >= 7) + tmp1_byte = 7; + } + + /* Write back to RF reg */ + odm_set_rf_reg(dm, rf_path, 0x30, 0xFFFF, + (offset << 12 | (modi_tx_a_value & 0xFF0) | tmp1_byte)); +} + +static void _txa_bias_cali_4_each_path(struct phy_dm_struct *dm, u8 rf_path, + u8 efuse_value) +{ + /* switch on set TxA bias */ + odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x200); + + /* Set 12 sets of TxA value */ + _set_tx_a_cali_value(dm, rf_path, 0x0, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x1, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x2, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x3, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x4, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x5, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x6, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x7, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x8, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x9, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0xa, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0xb, efuse_value); + + /* switch off set TxA bias */ + odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x0); +} + +/* + * for 8822B PCIE D-cut patch only + * Normal driver and MP driver need this patch + */ + +void phydm_txcurrentcalibration(struct phy_dm_struct *dm) +{ + u8 efuse0x3D8, efuse0x3D7; + u32 orig_rf0x18_path_a = 0, orig_rf0x18_path_b = 0; + + /* save original 0x18 value */ + orig_rf0x18_path_a = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF); + orig_rf0x18_path_b = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF); + + /* define efuse content */ + efuse0x3D8 = dm->efuse0x3d8; + efuse0x3D7 = dm->efuse0x3d7; + + /* check efuse content to judge whether need to calibration or not */ + if (efuse0x3D7 == 0xFF) { + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "efuse content 0x3D7 == 0xFF, No need to do TxA cali\n"); + return; + } + + /* write RF register for calibration */ + _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_A, efuse0x3D7); + _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_B, efuse0x3D8); + + /* restore original 0x18 value */ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF, orig_rf0x18_path_a); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF, orig_rf0x18_path_b); +} + +void phydm_hwsetting_8822b(struct phy_dm_struct *dm) +{ + phydm_dynamic_switch_htstf_mumimo_8822b(dm); +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..af91a6f958edc2f47a890df0a0841c84bf5b2278 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __ODM_RTL8822B_H__ +#define __ODM_RTL8822B_H__ + +void phydm_hwsetting_8822b(struct phy_dm_struct *dm); + +#endif /* #define __ODM_RTL8822B_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..ad0d32fce0a9f5fb127f9e8c556330b5776ce7ba --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +/*RTL8822B PHY Parameters*/ +/* + * [Caution] + * Since 01/Aug/2015, the commit rules will be simplified. + * You do not need to fill up the version.h anymore, + * only the maintenance supervisor fills it before formal release. + */ +#define RELEASE_DATE_8822B 20161103 +#define COMMIT_BY_8822B "BB_JOE" +#define RELEASE_VERSION_8822B 67 diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.c b/drivers/staging/rtlwifi/phydm/rtl_phydm.c new file mode 100644 index 0000000000000000000000000000000000000000..85e490d3601f2cf49305c8e6f118b6403bf74b28 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.c @@ -0,0 +1,874 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" +#include + +static int _rtl_phydm_init_com_info(struct rtl_priv *rtlpriv, + enum odm_ic_type ic_type, + struct rtl_phydm_params *params) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + u8 odm_board_type = ODM_BOARD_DEFAULT; + u32 support_ability; + int i; + + dm->adapter = (void *)rtlpriv; + + odm_cmn_info_init(dm, ODM_CMNINFO_PLATFORM, ODM_CE); + + odm_cmn_info_init(dm, ODM_CMNINFO_IC_TYPE, ic_type); + + odm_cmn_info_init(dm, ODM_CMNINFO_INTERFACE, ODM_ITRF_PCIE); + + odm_cmn_info_init(dm, ODM_CMNINFO_MP_TEST_CHIP, params->mp_chip); + + odm_cmn_info_init(dm, ODM_CMNINFO_PATCH_ID, rtlhal->oem_id); + + odm_cmn_info_init(dm, ODM_CMNINFO_BWIFI_TEST, 1); + + if (rtlphy->rf_type == RF_1T1R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); + else if (rtlphy->rf_type == RF_1T2R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); + else if (rtlphy->rf_type == RF_2T2R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); + else if (rtlphy->rf_type == RF_2T2R_GREEN) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN); + else if (rtlphy->rf_type == RF_2T3R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T3R); + else if (rtlphy->rf_type == RF_2T4R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T4R); + else if (rtlphy->rf_type == RF_3T3R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T3R); + else if (rtlphy->rf_type == RF_3T4R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T4R); + else if (rtlphy->rf_type == RF_4T4R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_4T4R); + else + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_XTXR); + + /* 1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= */ + if (rtlhal->external_lna_2g != 0) { + odm_board_type |= ODM_BOARD_EXT_LNA; + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, 1); + } + if (rtlhal->external_lna_5g != 0) { + odm_board_type |= ODM_BOARD_EXT_LNA_5G; + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, 1); + } + if (rtlhal->external_pa_2g != 0) { + odm_board_type |= ODM_BOARD_EXT_PA; + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, 1); + } + if (rtlhal->external_pa_5g != 0) { + odm_board_type |= ODM_BOARD_EXT_PA_5G; + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, 1); + } + if (rtlpriv->cfg->ops->get_btc_status()) + odm_board_type |= ODM_BOARD_BT; + + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, odm_board_type); + /* 1 ============== End of BoardType ============== */ + + odm_cmn_info_init(dm, ODM_CMNINFO_GPA, rtlhal->type_gpa); + odm_cmn_info_init(dm, ODM_CMNINFO_APA, rtlhal->type_apa); + odm_cmn_info_init(dm, ODM_CMNINFO_GLNA, rtlhal->type_glna); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, rtlhal->type_alna); + + odm_cmn_info_init(dm, ODM_CMNINFO_RFE_TYPE, rtlhal->rfe_type); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_TRSW, 0); + + /*Add by YuChen for kfree init*/ + odm_cmn_info_init(dm, ODM_CMNINFO_REGRFKFREEENABLE, 2); + odm_cmn_info_init(dm, ODM_CMNINFO_RFKFREEENABLE, 0); + + /*Antenna diversity relative parameters*/ + odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_DIV, + &rtlefuse->antenna_div_cfg); + odm_cmn_info_init(dm, ODM_CMNINFO_RF_ANTENNA_TYPE, + rtlefuse->antenna_div_type); + odm_cmn_info_init(dm, ODM_CMNINFO_BE_FIX_TX_ANT, 0); + odm_cmn_info_init(dm, ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH, 0); + + /* (8822B) efuse 0x3D7 & 0x3D8 for TX PA bias */ + odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D7, params->efuse0x3d7); + odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D8, params->efuse0x3d8); + + /*Add by YuChen for adaptivity init*/ + odm_cmn_info_hook(dm, ODM_CMNINFO_ADAPTIVITY, + &rtlpriv->phydm.adaptivity_en); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE, + false); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DCBACKOFF, 0); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY, + false); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_L2H_INI, 0); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_IQKFWOFFLOAD, 0); + + /* Pointer reference */ + odm_cmn_info_hook(dm, ODM_CMNINFO_TX_UNI, + &rtlpriv->stats.txbytesunicast); + odm_cmn_info_hook(dm, ODM_CMNINFO_RX_UNI, + &rtlpriv->stats.rxbytesunicast); + odm_cmn_info_hook(dm, ODM_CMNINFO_BAND, &rtlhal->current_bandtype); + odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_RATE, + &rtlpriv->phydm.forced_data_rate); + odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_IGI_LB, + &rtlpriv->phydm.forced_igi_lb); + + odm_cmn_info_hook(dm, ODM_CMNINFO_SEC_CHNL_OFFSET, + &mac->cur_40_prime_sc); + odm_cmn_info_hook(dm, ODM_CMNINFO_BW, &rtlphy->current_chan_bw); + odm_cmn_info_hook(dm, ODM_CMNINFO_CHNL, &rtlphy->current_channel); + + odm_cmn_info_hook(dm, ODM_CMNINFO_SCAN, &mac->act_scanning); + odm_cmn_info_hook(dm, ODM_CMNINFO_POWER_SAVING, + &ppsc->dot11_psmode); /* may add new boolean flag */ + /*Add by Yuchen for phydm beamforming*/ + odm_cmn_info_hook(dm, ODM_CMNINFO_TX_TP, + &rtlpriv->stats.txbytesunicast_inperiod_tp); + odm_cmn_info_hook(dm, ODM_CMNINFO_RX_TP, + &rtlpriv->stats.rxbytesunicast_inperiod_tp); + odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_TEST, + &rtlpriv->phydm.antenna_test); + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, i, + NULL); + + phydm_init_debug_setting(dm); + + odm_cmn_info_init(dm, ODM_CMNINFO_FAB_VER, params->fab_ver); + odm_cmn_info_init(dm, ODM_CMNINFO_CUT_VER, params->cut_ver); + + /* after ifup, ability is updated again */ + support_ability = ODM_RF_CALIBRATION | ODM_RF_TX_PWR_TRACK; + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability); + + return 0; +} + +static int rtl_phydm_init_priv(struct rtl_priv *rtlpriv, + struct rtl_phydm_params *params) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_ic_type ic; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + ic = ODM_RTL8822B; + else + return 0; + + rtlpriv->phydm.internal = + kzalloc(sizeof(struct phy_dm_struct), GFP_KERNEL); + + _rtl_phydm_init_com_info(rtlpriv, ic, params); + + odm_init_all_timers(dm); + + return 1; +} + +static int rtl_phydm_deinit_priv(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + odm_cancel_all_timers(dm); + + kfree(rtlpriv->phydm.internal); + rtlpriv->phydm.internal = NULL; + + return 0; +} + +static bool rtl_phydm_load_txpower_by_rate(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + status = odm_config_bb_with_header_file(dm, CONFIG_BB_PHY_REG_PG); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_load_txpower_limit(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) { + odm_read_and_config_mp_8822b_txpwr_lmt(dm); + } else { + status = odm_config_rf_with_header_file(dm, CONFIG_RF_TXPWR_LMT, + 0); + if (status != HAL_STATUS_SUCCESS) + return false; + } + + return true; +} + +static int rtl_phydm_init_dm(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + u32 support_ability = 0; + + /* clang-format off */ + support_ability = 0 + | ODM_BB_DIG + | ODM_BB_RA_MASK + | ODM_BB_DYNAMIC_TXPWR + | ODM_BB_FA_CNT + | ODM_BB_RSSI_MONITOR + | ODM_BB_CCK_PD + /* | ODM_BB_PWR_SAVE*/ + | ODM_BB_CFO_TRACKING + | ODM_MAC_EDCA_TURBO + | ODM_RF_TX_PWR_TRACK + | ODM_RF_CALIBRATION + | ODM_BB_NHM_CNT + /* | ODM_BB_PWR_TRAIN*/ + ; + /* clang-format on */ + + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability); + + odm_dm_init(dm); + + return 0; +} + +static int rtl_phydm_deinit_dm(struct rtl_priv *rtlpriv) +{ + return 0; +} + +static int rtl_phydm_reset_dm(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + odm_dm_reset(dm); + + return 0; +} + +static bool rtl_phydm_parameter_init(struct rtl_priv *rtlpriv, bool post) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_parameter_init(dm, post ? ODM_POST_SETTING : + ODM_PRE_SETTING); + + return false; +} + +static bool rtl_phydm_phy_bb_config(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + status = odm_config_bb_with_header_file(dm, CONFIG_BB_PHY_REG); + if (status != HAL_STATUS_SUCCESS) + return false; + + status = odm_config_bb_with_header_file(dm, CONFIG_BB_AGC_TAB); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_phy_rf_config(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + enum hal_status status; + enum odm_rf_radio_path rfpath; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + status = odm_config_rf_with_header_file(dm, CONFIG_RF_RADIO, + rfpath); + if (status != HAL_STATUS_SUCCESS) + return false; + } + + status = odm_config_rf_with_tx_pwr_track_header_file(dm); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_phy_mac_config(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + status = odm_config_mac_with_header_file(dm); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_trx_mode(struct rtl_priv *rtlpriv, + enum radio_mask tx_path, enum radio_mask rx_path, + bool is_tx2_path) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_trx_mode_8822b(dm, + (enum odm_rf_path)tx_path, + (enum odm_rf_path)rx_path, + is_tx2_path); + + return false; +} + +static bool rtl_phydm_watchdog(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + u8 is_linked = false; + u8 bsta_state = false; + u8 is_bt_enabled = false; + + /* check whether do watchdog */ + rtlpriv->cfg->ops->get_hw_reg(rtlpriv->hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(rtlpriv->hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) + ; + else + return false; + + /* update common info before doing watchdog */ + if (mac->link_state >= MAC80211_LINKED) { + is_linked = true; + if (mac->vif && mac->vif->type == NL80211_IFTYPE_STATION) + bsta_state = true; + } + + if (rtlpriv->cfg->ops->get_btc_status()) + is_bt_enabled = !rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled( + rtlpriv); + + odm_cmn_info_update(dm, ODM_CMNINFO_LINK, is_linked); + odm_cmn_info_update(dm, ODM_CMNINFO_STATION_STATE, bsta_state); + odm_cmn_info_update(dm, ODM_CMNINFO_BT_ENABLED, is_bt_enabled); + + /* do watchdog */ + odm_dm_watchdog(dm); + + return true; +} + +static bool rtl_phydm_switch_band(struct rtl_priv *rtlpriv, u8 central_ch) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_switch_band_8822b(dm, central_ch); + + return false; +} + +static bool rtl_phydm_switch_channel(struct rtl_priv *rtlpriv, u8 central_ch) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_switch_channel_8822b(dm, central_ch); + + return false; +} + +static bool rtl_phydm_switch_bandwidth(struct rtl_priv *rtlpriv, + u8 primary_ch_idx, + enum ht_channel_width bandwidth) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_bw odm_bw = (enum odm_bw)bandwidth; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_switch_bandwidth_8822b(dm, primary_ch_idx, + odm_bw); + + return false; +} + +static bool rtl_phydm_iq_calibrate(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + phy_iq_calibrate_8822b(dm, false); + else + return false; + + return true; +} + +static bool rtl_phydm_clear_txpowertracking_state(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + odm_clear_txpowertracking_state(dm); + + return true; +} + +static bool rtl_phydm_pause_dig(struct rtl_priv *rtlpriv, bool pause) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (pause) + odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x1e); + else /* resume */ + odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, 0xff); + + return true; +} + +static u32 rtl_phydm_read_rf_reg(struct rtl_priv *rtlpriv, + enum radio_path rfpath, u32 addr, u32 mask) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_read_rf_reg_8822b(dm, odm_rfpath, addr, + mask); + + return -1; +} + +static bool rtl_phydm_write_rf_reg(struct rtl_priv *rtlpriv, + enum radio_path rfpath, u32 addr, u32 mask, + u32 data) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_write_rf_reg_8822b(dm, odm_rfpath, addr, + mask, data); + + return false; +} + +static u8 rtl_phydm_read_txagc(struct rtl_priv *rtlpriv, enum radio_path rfpath, + u8 hw_rate) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_read_txagc_8822b(dm, odm_rfpath, hw_rate); + + return -1; +} + +static bool rtl_phydm_write_txagc(struct rtl_priv *rtlpriv, u32 power_index, + enum radio_path rfpath, u8 hw_rate) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_write_txagc_8822b(dm, power_index, + odm_rfpath, hw_rate); + + return false; +} + +static bool rtl_phydm_c2h_content_parsing(struct rtl_priv *rtlpriv, u8 cmd_id, + u8 cmd_len, u8 *content) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (phydm_c2H_content_parsing(dm, cmd_id, cmd_len, content)) + return true; + + return false; +} + +static bool rtl_phydm_query_phy_status(struct rtl_priv *rtlpriv, u8 *phystrpt, + struct ieee80211_hdr *hdr, + struct rtl_stats *pstatus) +{ + /* NOTE: phystrpt may be NULL, and need to fill default value */ + + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct dm_per_pkt_info pktinfo; /* input of pydm */ + struct dm_phy_status_info phy_info; /* output of phydm */ + __le16 fc = hdr->frame_control; + + /* fill driver pstatus */ + ether_addr_copy(pstatus->psaddr, ieee80211_get_SA(hdr)); + + /* fill pktinfo */ + memset(&pktinfo, 0, sizeof(pktinfo)); + + pktinfo.data_rate = pstatus->rate; + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION) { + pktinfo.station_id = 0; + } else { + /* TODO: use rtl_find_sta() to find ID */ + pktinfo.station_id = 0xFF; + } + + pktinfo.is_packet_match_bssid = + (!ieee80211_is_ctl(fc) && + (ether_addr_equal(mac->bssid, + ieee80211_has_tods(fc) ? + hdr->addr1 : + ieee80211_has_fromds(fc) ? + hdr->addr2 : + hdr->addr3)) && + (!pstatus->hwerror) && (!pstatus->crc) && (!pstatus->icv)); + pktinfo.is_packet_to_self = + pktinfo.is_packet_match_bssid && + (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr)); + pktinfo.is_to_self = (!pstatus->icv) && (!pstatus->crc) && + (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr)); + pktinfo.is_packet_beacon = (ieee80211_is_beacon(fc) ? true : false); + + /* query phy status */ + if (phystrpt) + odm_phy_status_query(dm, &phy_info, phystrpt, &pktinfo); + else + memset(&phy_info, 0, sizeof(phy_info)); + + /* copy phy_info from phydm to driver */ + pstatus->rx_pwdb_all = phy_info.rx_pwdb_all; + pstatus->bt_rx_rssi_percentage = phy_info.bt_rx_rssi_percentage; + pstatus->recvsignalpower = phy_info.recv_signal_power; + pstatus->signalquality = phy_info.signal_quality; + pstatus->rx_mimo_signalquality[0] = phy_info.rx_mimo_signal_quality[0]; + pstatus->rx_mimo_signalquality[1] = phy_info.rx_mimo_signal_quality[1]; + pstatus->rx_packet_bw = + phy_info.band_width; /* HT_CHANNEL_WIDTH_20 <- ODM_BW20M */ + + /* fill driver pstatus */ + pstatus->packet_matchbssid = pktinfo.is_packet_match_bssid; + pstatus->packet_toself = pktinfo.is_packet_to_self; + pstatus->packet_beacon = pktinfo.is_packet_beacon; + + return true; +} + +static u8 rtl_phydm_rate_id_mapping(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + return phydm_rate_id_mapping(dm, wireless_mode, rf_type, bw); +} + +static bool rtl_phydm_get_ra_bitmap(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw, + u8 tx_rate_level, /* 0~6 */ + u32 *tx_bitmap_msb, + u32 *tx_bitmap_lsb) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + const u8 mimo_ps_enable = 0; + const u8 disable_cck_rate = 0; + + phydm_update_hal_ra_mask(dm, wireless_mode, rf_type, bw, mimo_ps_enable, + disable_cck_rate, tx_bitmap_msb, tx_bitmap_lsb, + tx_rate_level); + + return true; +} + +static u8 _rtl_phydm_get_macid(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + return 0; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + return sta->aid + 1; + + return 0; +} + +static bool rtl_phydm_add_sta(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_sta_info *sta_entry = (struct rtl_sta_info *)sta->drv_priv; + u8 mac_id = _rtl_phydm_get_macid(rtlpriv, sta); + + odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, mac_id, + sta_entry); + + return true; +} + +static bool rtl_phydm_del_sta(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + u8 mac_id = _rtl_phydm_get_macid(rtlpriv, sta); + + odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, mac_id, NULL); + + return true; +} + +static u32 rtl_phydm_get_version(struct rtl_priv *rtlpriv) +{ + u32 ver = 0; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + ver = RELEASE_VERSION_8822B; + + return ver; +} + +static bool rtl_phydm_modify_ra_pcr_threshold(struct rtl_priv *rtlpriv, + u8 ra_offset_direction, + u8 ra_threshold_offset) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + phydm_modify_RA_PCR_threshold(dm, ra_offset_direction, + ra_threshold_offset); + + return true; +} + +static u32 rtl_phydm_query_counter(struct rtl_priv *rtlpriv, + const char *info_type) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + static const struct query_entry { + const char *query_name; + enum phydm_info_query query_id; + } query_table[] = { +#define QUERY_ENTRY(name) {#name, name} + QUERY_ENTRY(PHYDM_INFO_FA_OFDM), + QUERY_ENTRY(PHYDM_INFO_FA_CCK), + QUERY_ENTRY(PHYDM_INFO_CCA_OFDM), + QUERY_ENTRY(PHYDM_INFO_CCA_CCK), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_CCK), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_LEGACY), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_HT), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_VHT), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_CCK), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_LEGACY), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_HT), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_VHT), + }; +#define QUERY_TABLE_SIZE ARRAY_SIZE(query_table) + + int i; + const struct query_entry *entry; + + if (!strcmp(info_type, "IQK_TOTAL")) + return dm->n_iqk_cnt; + + if (!strcmp(info_type, "IQK_OK")) + return dm->n_iqk_ok_cnt; + + if (!strcmp(info_type, "IQK_FAIL")) + return dm->n_iqk_fail_cnt; + + for (i = 0; i < QUERY_TABLE_SIZE; i++) { + entry = &query_table[i]; + + if (!strcmp(info_type, entry->query_name)) + return phydm_cmn_info_query(dm, entry->query_id); + } + + pr_err("Unrecognized info_type:%s!!!!:\n", info_type); + + return 0xDEADDEAD; +} + +static bool rtl_phydm_debug_cmd(struct rtl_priv *rtlpriv, char *in, u32 in_len, + char *out, u32 out_len) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + phydm_cmd(dm, in, in_len, 1, out, out_len); + + return true; +} + +static struct rtl_phydm_ops rtl_phydm_operation = { + /* init/deinit priv */ + .phydm_init_priv = rtl_phydm_init_priv, + .phydm_deinit_priv = rtl_phydm_deinit_priv, + .phydm_load_txpower_by_rate = rtl_phydm_load_txpower_by_rate, + .phydm_load_txpower_limit = rtl_phydm_load_txpower_limit, + + /* init hw */ + .phydm_init_dm = rtl_phydm_init_dm, + .phydm_deinit_dm = rtl_phydm_deinit_dm, + .phydm_reset_dm = rtl_phydm_reset_dm, + .phydm_parameter_init = rtl_phydm_parameter_init, + .phydm_phy_bb_config = rtl_phydm_phy_bb_config, + .phydm_phy_rf_config = rtl_phydm_phy_rf_config, + .phydm_phy_mac_config = rtl_phydm_phy_mac_config, + .phydm_trx_mode = rtl_phydm_trx_mode, + + /* watchdog */ + .phydm_watchdog = rtl_phydm_watchdog, + + /* channel */ + .phydm_switch_band = rtl_phydm_switch_band, + .phydm_switch_channel = rtl_phydm_switch_channel, + .phydm_switch_bandwidth = rtl_phydm_switch_bandwidth, + .phydm_iq_calibrate = rtl_phydm_iq_calibrate, + .phydm_clear_txpowertracking_state = + rtl_phydm_clear_txpowertracking_state, + .phydm_pause_dig = rtl_phydm_pause_dig, + + /* read/write reg */ + .phydm_read_rf_reg = rtl_phydm_read_rf_reg, + .phydm_write_rf_reg = rtl_phydm_write_rf_reg, + .phydm_read_txagc = rtl_phydm_read_txagc, + .phydm_write_txagc = rtl_phydm_write_txagc, + + /* RX */ + .phydm_c2h_content_parsing = rtl_phydm_c2h_content_parsing, + .phydm_query_phy_status = rtl_phydm_query_phy_status, + + /* TX */ + .phydm_rate_id_mapping = rtl_phydm_rate_id_mapping, + .phydm_get_ra_bitmap = rtl_phydm_get_ra_bitmap, + + /* STA */ + .phydm_add_sta = rtl_phydm_add_sta, + .phydm_del_sta = rtl_phydm_del_sta, + + /* BTC */ + .phydm_get_version = rtl_phydm_get_version, + .phydm_modify_ra_pcr_threshold = rtl_phydm_modify_ra_pcr_threshold, + .phydm_query_counter = rtl_phydm_query_counter, + + /* debug */ + .phydm_debug_cmd = rtl_phydm_debug_cmd, +}; + +struct rtl_phydm_ops *rtl_phydm_get_ops_pointer(void) +{ + return &rtl_phydm_operation; +} +EXPORT_SYMBOL(rtl_phydm_get_ops_pointer); + +/* ******************************************************** + * Define phydm callout function in below + * ******************************************************** + */ + +u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate, + enum ht_channel_width bandwidth, u8 channel) +{ + /* rate: DESC_RATE1M */ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + + return rtlpriv->cfg->ops->get_txpower_index(rtlpriv->hw, rf_path, rate, + bandwidth, channel); +} + +void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + + return rtlpriv->cfg->ops->set_tx_power_index_by_rs(rtlpriv->hw, ch, + path, rs); +} + +void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + + rtlpriv->cfg->ops->store_tx_power_by_rate( + rtlpriv->hw, band, rfpath, txnum, regaddr, bitmask, data); +} + +void phy_set_tx_power_limit(void *dm, u8 *regulation, u8 *band, u8 *bandwidth, + u8 *rate_section, u8 *rf_path, u8 *channel, + u8 *power_limit) +{ + struct rtl_priv *rtlpriv = + (struct rtl_priv *)((struct phy_dm_struct *)dm)->adapter; + + rtlpriv->cfg->ops->phy_set_txpower_limit(rtlpriv->hw, regulation, band, + bandwidth, rate_section, + rf_path, channel, power_limit); +} + +void rtl_hal_update_ra_mask(void *adapter, struct rtl_sta_info *psta, + u8 rssi_level) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + struct ieee80211_sta *sta = + container_of((void *)psta, struct ieee80211_sta, drv_priv); + + rtlpriv->cfg->ops->update_rate_tbl(rtlpriv->hw, sta, rssi_level, false); +} + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.h b/drivers/staging/rtlwifi/phydm/rtl_phydm.h new file mode 100644 index 0000000000000000000000000000000000000000..483d2418699b73b5e4a43b506f5fdc58fa11369e --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __RTL_PHYDM_H__ +#define __RTL_PHYDM_H__ + +struct rtl_phydm_ops *rtl_phydm_get_ops_pointer(void); + +#define rtlpriv_to_phydm(priv) \ + ((struct phy_dm_struct *)((priv)->phydm.internal)) + +u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate, + enum ht_channel_width bandwidth, u8 channel); +void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs); +void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum, + u32 regaddr, u32 bitmask, u32 data); +void phy_set_tx_power_limit(void *dm, u8 *regulation, u8 *band, u8 *bandwidth, + u8 *rate_section, u8 *rf_path, u8 *channel, + u8 *power_limit); + +void rtl_hal_update_ra_mask(void *adapter, struct rtl_sta_info *psta, + u8 rssi_level); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h b/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h new file mode 100644 index 0000000000000000000000000000000000000000..6cacca12d792c7de0f6f4030f553841866839eec --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_COM_TXBF_H__ +#define __HAL_COM_TXBF_H__ + +enum txbf_set_type { + TXBF_SET_SOUNDING_ENTER, + TXBF_SET_SOUNDING_LEAVE, + TXBF_SET_SOUNDING_RATE, + TXBF_SET_SOUNDING_STATUS, + TXBF_SET_SOUNDING_FW_NDPA, + TXBF_SET_SOUNDING_CLK, + TXBF_SET_TX_PATH_RESET, + TXBF_SET_GET_TX_RATE +}; + +enum txbf_get_type { + TXBF_GET_EXPLICIT_BEAMFORMEE, + TXBF_GET_EXPLICIT_BEAMFORMER, + TXBF_GET_MU_MIMO_STA, + TXBF_GET_MU_MIMO_AP +}; + +/* 2 HAL TXBF related */ +struct _HAL_TXBF_INFO { + u8 txbf_idx; + u8 ndpa_idx; + u8 BW; + u8 rate; + + struct timer_list txbf_fw_ndpa_timer; +}; + +#define hal_com_txbf_beamform_init(dm_void) NULL +#define hal_com_txbf_config_gtab(dm_void) NULL +#define hal_com_txbf_enter_work_item_callback(_adapter) NULL +#define hal_com_txbf_leave_work_item_callback(_adapter) NULL +#define hal_com_txbf_fw_ndpa_work_item_callback(_adapter) NULL +#define hal_com_txbf_clk_work_item_callback(_adapter) NULL +#define hal_com_txbf_rate_work_item_callback(_adapter) NULL +#define hal_com_txbf_fw_ndpa_timer_callback(_adapter) NULL +#define hal_com_txbf_status_work_item_callback(_adapter) NULL +#define hal_com_txbf_get(_adapter, _get_type, _pout_buf) + +#endif /* #ifndef __HAL_COM_TXBF_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h new file mode 100644 index 0000000000000000000000000000000000000000..5c92c4326f7e37467a0f7ff0bc023bfb07e34fc7 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_TXBF_8822B_H__ +#define __HAL_TXBF_8822B_H__ + +#define hal_txbf_8822b_enter(dm_void, idx) +#define hal_txbf_8822b_leave(dm_void, idx) +#define hal_txbf_8822b_status(dm_void, idx) +#define hal_txbf_8822b_fw_txbf(dm_void, idx) +#define hal_txbf_8822b_config_gtab(dm_void) + +void phydm_8822btxbf_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt); + +void phydm_8822b_sutxbfer_workaroud(void *dm_void, bool enable_su_bfer, u8 nc, + u8 nr, u8 ng, u8 CB, u8 BW, bool is_vht); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h new file mode 100644 index 0000000000000000000000000000000000000000..82aeac1ff3e0af23a1f714ad181036ef3da5fd0f --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_TXBF_INTERFACE_H__ +#define __HAL_TXBF_INTERFACE_H__ + +#define beamforming_get_ndpa_frame(dm, _pdu_os) +#define beamforming_get_report_frame(adapter, precv_frame) RT_STATUS_FAILURE +#define send_fw_ht_ndpa_packet(dm_void, RA, BW) +#define send_sw_ht_ndpa_packet(dm_void, RA, BW) +#define send_fw_vht_ndpa_packet(dm_void, RA, AID, BW) +#define send_sw_vht_ndpa_packet(dm_void, RA, AID, BW) +#define send_sw_vht_gid_mgnt_frame(dm_void, RA, idx) +#define send_sw_vht_bf_report_poll(dm_void, RA, is_final_poll) +#define send_sw_vht_mu_ndpa_packet(dm_void, BW) + +#endif diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h new file mode 100644 index 0000000000000000000000000000000000000000..c5ddd9cb9cd584d84faf3e05eb60ca6bc8a5e8bc --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_TXBF_JAGUAR_H__ +#define __HAL_TXBF_JAGUAR_H__ + +#define hal_txbf_8812a_set_ndpa_rate(dm_void, BW, rate) +#define hal_txbf_jaguar_enter(dm_void, idx) +#define hal_txbf_jaguar_leave(dm_void, idx) +#define hal_txbf_jaguar_status(dm_void, idx) +#define hal_txbf_jaguar_fw_txbf(dm_void, idx) +#define hal_txbf_jaguar_patch(dm_void, operation) +#define hal_txbf_jaguar_clk_8812a(dm_void) + +#endif /* #ifndef __HAL_TXBF_JAGUAR_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h b/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h new file mode 100644 index 0000000000000000000000000000000000000000..41358fce287577e330371662e1557b0267d7cf64 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __PHYDM_HAL_TXBF_API_H__ +#define __PHYDM_HAL_TXBF_API_H__ + +#define tx_bf_nr(a, b) ((a > b) ? (b) : (a)) + +u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 comp_steering_num_of_bfer); + +u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 comp_steering_num_of_bfer); + +u8 phydm_get_beamforming_sounding_info(void *dm_void, u16 *troughput, + u8 total_bfee_num, u8 *tx_rate); + +u8 phydm_get_ndpa_rate(void *dm_void); + +u8 phydm_get_mu_bfee_snding_decision(void *dm_void, u16 throughput); + +#endif diff --git a/drivers/staging/rtlwifi/ps.c b/drivers/staging/rtlwifi/ps.c new file mode 100644 index 0000000000000000000000000000000000000000..9172cee45f74e3ca7290f68db57e338e03bd107f --- /dev/null +++ b/drivers/staging/rtlwifi/ps.c @@ -0,0 +1,1007 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "base.h" +#include "ps.h" +#include +#include "btcoexist/rtl_btc.h" + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + + /*<1> reset trx ring */ + if (rtlhal->interface == INTF_PCI) + rtlpriv->intf_ops->reset_trx_ring(hw); + + if (is_hal_stop(rtlhal)) + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Driver is already down!\n"); + + /*<2> Enable Adapter */ + if (rtlpriv->cfg->ops->hw_init(hw)) + return false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + &rtlmac->retry_long); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/ + rtlpriv->cfg->ops->switch_channel(hw); + rtlpriv->cfg->ops->set_channel_access(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, + cfg80211_get_chandef_type(&hw->conf.chandef)); + + /*<3> Enable Interrupt */ + rtlpriv->cfg->ops->enable_interrupt(hw); + + /* */ + rtl_watch_dog_timer_callback((unsigned long)hw); + + return true; +} + +bool rtl_ps_disable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /*<1> Stop all timer */ + rtl_deinit_deferred_work(hw); + + /*<2> Disable Interrupt */ + rtlpriv->cfg->ops->disable_interrupt(hw); + tasklet_kill(&rtlpriv->works.irq_tasklet); + + /*<3> Disable Adapter */ + rtlpriv->cfg->ops->hw_disable(hw); + + return true; +} + +static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, + enum rf_pwrstate state_toset, + u32 changesource) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + bool actionallowed = false; + u16 rfwait_cnt = 0; + + /*Only one thread can change + *the RF state at one time, and others + *should wait to be executed. + */ + while (true) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "RF Change in progress! Wait to set..state_toset(%d).\n", + state_toset); + + /* Set RF after the previous action is done. */ + while (ppsc->rfchange_inprogress) { + rfwait_cnt++; + mdelay(1); + /*Wait too long, return false to avoid + *to be stuck here. + */ + if (rfwait_cnt > 100) + return false; + } + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + break; + } + } + + rtstate = ppsc->rfpwr_state; + + switch (state_toset) { + case ERFON: + ppsc->rfoff_reason &= (~changesource); + + if ((changesource == RF_CHANGE_BY_HW) && + (ppsc->hwradiooff)) { + ppsc->hwradiooff = false; + } + + if (!ppsc->rfoff_reason) { + ppsc->rfoff_reason = 0; + actionallowed = true; + } + break; + case ERFOFF: + if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) + ppsc->hwradiooff = true; + + ppsc->rfoff_reason |= changesource; + actionallowed = true; + break; + case ERFSLEEP: + ppsc->rfoff_reason |= changesource; + actionallowed = true; + break; + default: + pr_err("switch case %#x not processed\n", state_toset); + break; + } + + if (actionallowed) + rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + return actionallowed; +} + +static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + ppsc->swrf_processing = true; + + if (ppsc->inactive_pwrstate == ERFON && + rtlhal->interface == INTF_PCI) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + } + + rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, + RF_CHANGE_BY_IPS); + + if (ppsc->inactive_pwrstate == ERFOFF && + rtlhal->interface == INTF_PCI) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && + !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + } + + ppsc->swrf_processing = false; +} + +void rtl_ips_nic_off_wq_callback(void *data) +{ + struct rtl_works *rtlworks = + container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + if (mac->opmode != NL80211_IFTYPE_STATION) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "not station return\n"); + return; + } + + if (mac->p2p_in_use) + return; + + if (mac->link_state > MAC80211_NOLINK) + return; + + if (is_hal_stop(rtlhal)) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->cfg->ops->bt_coex_off_before_lps) + rtlpriv->cfg->ops->bt_coex_off_before_lps(hw); + + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + /* + *Do not enter IPS in the following conditions: + *(1) RF is already OFF or Sleep + *(2) swrf_processing (indicates the IPS is still under going) + *(3) Connectted (only disconnected can trigger IPS) + *(4) IBSS (send Beacon) + *(5) AP mode (send Beacon) + *(6) monitor mode (rcv packet) + */ + + if (rtstate == ERFON && + !ppsc->swrf_processing && + (mac->link_state == MAC80211_NOLINK) && + !mac->act_scanning) { + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "IPSEnter(): Turn off RF\n"); + + ppsc->inactive_pwrstate = ERFOFF; + ppsc->in_powersavemode = true; + + /* call before RF off */ + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, + ppsc->inactive_pwrstate); + + /*rtl_pci_reset_trx_ring(hw); */ + _rtl_ps_inactive_ps(hw); + } + } +} + +void rtl_ips_nic_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* because when link with ap, mac80211 will ask us + * to disable nic quickly after scan before linking, + * this will cause link failed, so we delay 100ms here + */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ips_nic_off_wq, MSECS(100)); +} + +/* NOTICE: any opmode should exc nic_on, or disable without + * nic_on may something wrong, like adhoc TP + */ +void rtl_ips_nic_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); + + mutex_lock(&rtlpriv->locks.ips_mutex); + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + if (rtstate != ERFON && + !ppsc->swrf_processing && + ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { + ppsc->inactive_pwrstate = ERFON; + ppsc->in_powersavemode = false; + _rtl_ps_inactive_ps(hw); + /* call after RF on */ + if (rtlpriv->phydm.ops) + rtlpriv->phydm.ops->phydm_reset_dm(rtlpriv); + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, + ppsc->inactive_pwrstate); + } + } + mutex_unlock(&rtlpriv->locks.ips_mutex); +} + +/*for FW LPS*/ + +/* + *Determine if we can set Fw into PS mode + *in current condition.Return TRUE if it + *can enter PS mode. + */ +static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u32 ps_timediff; + + ps_timediff = jiffies_to_msecs(jiffies - + ppsc->last_delaylps_stamp_jiffies); + + if (ps_timediff < 2000) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); + return false; + } + + if (mac->link_state != MAC80211_LINKED) + return false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return false; + + return true; +} + +/* Change current and default preamble mode.*/ +void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool enter_fwlps; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->dot11_psmode == rt_psmode && rt_psmode == EACTIVE) + return; + + /* Update power save mode configured. */ + ppsc->dot11_psmode = rt_psmode; + + /* + * + *1. Enter PS mode + * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode + * cmd to set Fw into PS mode. + *2. Leave PS mode + * Send H2C fw_pwrmode cmd to Fw to set Fw into Active + * mode and set RPWM to turn RF on. + */ + + if ((ppsc->fwctrl_lps) && ppsc->report_linked) { + if (ppsc->dot11_psmode == EACTIVE) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); + enter_fwlps = false; + ppsc->pwr_mode = FW_PS_ACTIVE_MODE; + ppsc->smart_ps = 0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_LPS_ACTION, + (u8 *)(&enter_fwlps)); + if (ppsc->p2p_ps_info.opp_ps) + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); + } else { + if (rtl_get_fwlps_doze(hw)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); + enter_fwlps = true; + ppsc->pwr_mode = ppsc->fwctrl_psmode; + ppsc->smart_ps = 2; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_LPS_ACTION, + (u8 *)(&enter_fwlps)); + + } else { + /* Reset the power save related parameters. */ + ppsc->dot11_psmode = EACTIVE; + } + } + } +} + +/* Interrupt safe routine to enter the leisure power save mode.*/ +static void rtl_lps_enter_core(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!ppsc->fwctrl_lps) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->link_info.busytraffic) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if (mac->cnt_after_linked < 5) + return; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + mutex_lock(&rtlpriv->locks.lps_mutex); + + /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because + * bt_ccoexist may ask to enter lps. + * In normal case, this constraint move to rtl_lps_set_psmode(). + */ + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Enter 802.11 power save mode...\n"); + rtl_lps_set_psmode(hw, EAUTOPS); + + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +/* Interrupt safe routine to leave the leisure power save mode.*/ +static void rtl_lps_leave_core(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + mutex_lock(&rtlpriv->locks.lps_mutex); + + if (ppsc->fwctrl_lps) { + if (ppsc->dot11_psmode != EACTIVE) { + /*FIX ME */ + /*rtlpriv->cfg->ops->enable_interrupt(hw); */ + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Busy Traffic,Leave 802.11 power save..\n"); + + rtl_lps_set_psmode(hw, EACTIVE); + } + } + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +/* For sw LPS*/ +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = data; + struct ieee80211_tim_ie *tim_ie; + u8 *tim; + u8 tim_len; + bool u_buffed; + bool m_buffed; + + if (mac->opmode != NL80211_IFTYPE_STATION) + return; + + if (!rtlpriv->psc.swctrl_lps) + return; + + if (rtlpriv->mac80211.link_state != MAC80211_LINKED) + return; + + if (!rtlpriv->psc.sw_ps_enabled) + return; + + if (rtlpriv->psc.fwctrl_lps) + return; + + if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + rtlpriv->psc.last_beacon = jiffies; + + tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); + if (!tim) + return; + + if (tim[1] < sizeof(*tim_ie)) + return; + + tim_len = tim[1]; + tim_ie = (struct ieee80211_tim_ie *)&tim[2]; + + if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) + rtlpriv->psc.dtim_counter = tim_ie->dtim_count; + + /* Check whenever the PHY can be turned off again. */ + + /* 1. What about buffered unicast traffic for our AID? */ + u_buffed = ieee80211_check_tim(tim_ie, tim_len, + rtlpriv->mac80211.assoc_id); + + /* 2. Maybe the AP wants to send multicast/broadcast data? */ + m_buffed = tim_ie->bitmap_ctrl & 0x01; + rtlpriv->psc.multi_buffered = m_buffed; + + /* unicast will process by mac80211 through + * set ~IEEE80211_CONF_PS, So we just check + * multicast frames here + */ + if (!m_buffed) { + /* back to low-power land. and delay is + * prevent null power save frame tx fail + */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ps_work, MSECS(5)); + } else { + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); + } +} + +void rtl_swlps_rf_awake(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (!rtlpriv->psc.swctrl_lps) + return; + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + mutex_lock(&rtlpriv->locks.lps_mutex); + rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +void rtl_swlps_rfon_wq_callback(void *data) +{ + struct rtl_works *rtlworks = + container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq); + struct ieee80211_hw *hw = rtlworks->hw; + + rtl_swlps_rf_awake(hw); +} + +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 sleep_intv; + + if (!rtlpriv->psc.sw_ps_enabled) + return; + + if ((rtlpriv->sec.being_setkey) || + (mac->opmode == NL80211_IFTYPE_ADHOC)) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5)) + return; + + if (rtlpriv->link_info.busytraffic) + return; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (rtlpriv->psc.rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return; + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + mutex_lock(&rtlpriv->locks.lps_mutex); + rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); + mutex_unlock(&rtlpriv->locks.lps_mutex); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && + !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + /* here is power save alg, when this beacon is DTIM + * we will set sleep time to dtim_period * n; + * when this beacon is not DTIM, we will set sleep + * time to sleep_intv = rtlpriv->psc.dtim_counter or + * MAX_SW_LPS_SLEEP_INTV(default set to 5) + */ + + if (rtlpriv->psc.dtim_counter == 0) { + if (hw->conf.ps_dtim_period == 1) + sleep_intv = hw->conf.ps_dtim_period * 2; + else + sleep_intv = hw->conf.ps_dtim_period; + } else { + sleep_intv = rtlpriv->psc.dtim_counter; + } + + if (sleep_intv > MAX_SW_LPS_SLEEP_INTV) + sleep_intv = MAX_SW_LPS_SLEEP_INTV; + + /* this print should always be dtim_conter = 0 & + * sleep = dtim_period, that meaons, we should + * awake before every dtim + */ + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); + + /* we tested that 40ms is enough for sw & hw sw delay */ + queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, + MSECS(sleep_intv * + mac->vif->bss_conf.beacon_int - 40)); +} + +void rtl_lps_change_work_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = + container_of(work, struct rtl_works, lps_change_work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->enter_ps) + rtl_lps_enter_core(hw); + else + rtl_lps_leave_core(hw); +} + +void rtl_lps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!in_interrupt()) + return rtl_lps_enter_core(hw); + rtlpriv->enter_ps = true; + schedule_work(&rtlpriv->works.lps_change_work); +} + +void rtl_lps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!in_interrupt()) + return rtl_lps_leave_core(hw); + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv->works.lps_change_work); +} + +void rtl_swlps_wq_callback(void *data) +{ + struct rtl_works *rtlworks = container_of_dwork_rtl(data, + struct rtl_works, + ps_work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool ps = false; + + ps = (hw->conf.flags & IEEE80211_CONF_PS); + + /* we can sleep after ps null send ok */ + if (rtlpriv->psc.state_inap) { + rtl_swlps_rf_sleep(hw); + + if (rtlpriv->psc.state && !ps) { + rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies - + rtlpriv->psc.last_action); + } + + if (ps) + rtlpriv->psc.last_slept = jiffies; + + rtlpriv->psc.last_action = jiffies; + rtlpriv->psc.state = ps; + } +} + +static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, + unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt = data; + struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info; + u8 *pos, *end, *ie; + u16 noa_len; + static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; + u8 noa_num, index, i, noa_index = 0; + bool find_p2p_ie = false, find_p2p_ps_ie = false; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + ie = NULL; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + return; + + if (pos[0] == 221 && pos[1] > 4) { + if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) { + ie = pos + 2 + 4; + break; + } + } + pos += 2 + pos[1]; + } + + if (!ie) + return; + find_p2p_ie = true; + /*to find noa ie*/ + while (ie + 1 < end) { + noa_len = READEF2BYTE((__le16 *)&ie[1]); + if (ie + 3 + ie[1] > end) + return; + + if (ie[0] == 12) { + find_p2p_ps_ie = true; + if ((noa_len - 2) % 13 != 0) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); + return; + } + noa_num = (noa_len - 2) / 13; + noa_index = ie[3]; + if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == + P2P_PS_NONE || noa_index != p2pinfo->noa_index) { + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "update NOA ie.\n"); + p2pinfo->noa_index = noa_index; + p2pinfo->opp_ps = (ie[4] >> 7); + p2pinfo->ctwindow = ie[4] & 0x7F; + p2pinfo->noa_num = noa_num; + index = 5; + for (i = 0; i < noa_num; i++) { + p2pinfo->noa_count_type[i] = + READEF1BYTE(ie + index); + index += 1; + p2pinfo->noa_duration[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_interval[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_start_time[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + } + + if (p2pinfo->opp_ps == 1) { + p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + /* Driver should wait LPS entering + * CTWindow + */ + if (rtlpriv->psc.fw_current_inpsmode) + rtl_p2p_ps_cmd(hw, + P2P_PS_ENABLE); + } else if (p2pinfo->noa_num > 0) { + p2pinfo->p2p_ps_mode = P2P_PS_NOA; + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } + } + break; + } + ie += 3 + noa_len; + } + + if (find_p2p_ie) { + if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) && + (!find_p2p_ps_ie)) + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } +} + +static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, + unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt = data; + struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info; + u8 noa_num, index, i, noa_index = 0; + u8 *pos, *end, *ie; + u16 noa_len; + static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; + + pos = (u8 *)&mgmt->u.action.category; + end = data + len; + ie = NULL; + + if (pos[0] == 0x7f) { + if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0) + ie = pos + 3 + 4; + } + + if (!ie) + return; + + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); + /*to find noa ie*/ + while (ie + 1 < end) { + noa_len = READEF2BYTE((__le16 *)&ie[1]); + if (ie + 3 + ie[1] > end) + return; + + if (ie[0] == 12) { + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", + ie, noa_len); + if ((noa_len - 2) % 13 != 0) { + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); + return; + } + noa_num = (noa_len - 2) / 13; + noa_index = ie[3]; + if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == + P2P_PS_NONE || noa_index != p2pinfo->noa_index) { + p2pinfo->noa_index = noa_index; + p2pinfo->opp_ps = (ie[4] >> 7); + p2pinfo->ctwindow = ie[4] & 0x7F; + p2pinfo->noa_num = noa_num; + index = 5; + for (i = 0; i < noa_num; i++) { + p2pinfo->noa_count_type[i] = + READEF1BYTE(ie + index); + index += 1; + p2pinfo->noa_duration[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_interval[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_start_time[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + } + + if (p2pinfo->opp_ps == 1) { + p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + /* Driver should wait LPS entering + * CTWindow + */ + if (rtlpriv->psc.fw_current_inpsmode) + rtl_p2p_ps_cmd(hw, + P2P_PS_ENABLE); + } else if (p2pinfo->noa_num > 0) { + p2pinfo->p2p_ps_mode = P2P_PS_NOA; + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } + } + break; + } + ie += 3 + noa_len; + } +} + +void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info; + + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "p2p state %x\n", p2p_ps_state); + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + p2pinfo->p2p_ps_state = p2p_ps_state; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + p2pinfo->noa_index = 0; + p2pinfo->ctwindow = 0; + p2pinfo->opp_ps = 0; + p2pinfo->noa_num = 0; + p2pinfo->p2p_ps_mode = P2P_PS_NONE; + if (rtlps->fw_current_inpsmode) { + if (rtlps->smart_ps == 0) { + rtlps->smart_ps = 2; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &rtlps->pwr_mode); + } + } + break; + case P2P_PS_ENABLE: + if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + p2pinfo->p2p_ps_state = p2p_ps_state; + + if (p2pinfo->ctwindow > 0) { + if (rtlps->smart_ps != 0) { + rtlps->smart_ps = 0; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &rtlps->pwr_mode); + } + } + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + } + break; + case P2P_PS_SCAN: + case P2P_PS_SCAN_DONE: + case P2P_PS_ALLSTASLEEP: + if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + p2pinfo->p2p_ps_state = p2p_ps_state; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + } + break; + default: + break; + } + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "ctwindow %x oppps %x\n", + p2pinfo->ctwindow, p2pinfo->opp_ps); + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "count %x duration %x index %x interval %x start time %x noa num %x\n", + p2pinfo->noa_count_type[0], + p2pinfo->noa_duration[0], + p2pinfo->noa_index, + p2pinfo->noa_interval[0], + p2pinfo->noa_start_time[0], + p2pinfo->noa_num); + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); +} + +void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = data; + + if (!mac->p2p) + return; + if (mac->link_state != MAC80211_LINKED) + return; + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + /* check if this really is a beacon */ + if (!(ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control) || + ieee80211_is_action(hdr->frame_control))) + return; + + if (ieee80211_is_action(hdr->frame_control)) + rtl_p2p_action_ie(hw, data, len - FCS_LEN); + else + rtl_p2p_noa_ie(hw, data, len - FCS_LEN); +} diff --git a/drivers/staging/rtlwifi/ps.h b/drivers/staging/rtlwifi/ps.h new file mode 100644 index 0000000000000000000000000000000000000000..6c187daced4ab9cffc1ca29f1bd904c932e1cc8c --- /dev/null +++ b/drivers/staging/rtlwifi/ps.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __REALTEK_RTL_PCI_PS_H__ +#define __REALTEK_RTL_PCI_PS_H__ + +#define MAX_SW_LPS_SLEEP_INTV 5 + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw); +bool rtl_ps_disable_nic(struct ieee80211_hw *hw); +void rtl_ips_nic_off(struct ieee80211_hw *hw); +void rtl_ips_nic_on(struct ieee80211_hw *hw); +void rtl_ips_nic_off_wq_callback(void *data); +void rtl_lps_enter(struct ieee80211_hw *hw); +void rtl_lps_leave(struct ieee80211_hw *hw); + +void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode); + +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_swlps_wq_callback(void *data); +void rtl_swlps_rfon_wq_callback(void *data); +void rtl_swlps_rf_awake(struct ieee80211_hw *hw); +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); +void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_lps_change_work_callback(struct work_struct *work); + +#endif diff --git a/drivers/staging/rtlwifi/pwrseqcmd.h b/drivers/staging/rtlwifi/pwrseqcmd.h new file mode 100644 index 0000000000000000000000000000000000000000..f411b7ebb08f6491e8fd572b51491f31774a0acb --- /dev/null +++ b/drivers/staging/rtlwifi/pwrseqcmd.h @@ -0,0 +1,94 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8723E_PWRSEQCMD_H__ +#define __RTL8723E_PWRSEQCMD_H__ + +#include "wifi.h" +/*--------------------------------------------- + * 3 The value of cmd: 4 bits + *--------------------------------------------- + */ +#define PWR_CMD_READ 0x00 +#define PWR_CMD_WRITE 0x01 +#define PWR_CMD_POLLING 0x02 +#define PWR_CMD_DELAY 0x03 +#define PWR_CMD_END 0x04 + +/* define the base address of each block */ +#define PWR_BASEADDR_MAC 0x00 +#define PWR_BASEADDR_USB 0x01 +#define PWR_BASEADDR_PCIE 0x02 +#define PWR_BASEADDR_SDIO 0x03 + +#define PWR_INTF_SDIO_MSK BIT(0) +#define PWR_INTF_USB_MSK BIT(1) +#define PWR_INTF_PCI_MSK BIT(2) +#define PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define PWR_FAB_TSMC_MSK BIT(0) +#define PWR_FAB_UMC_MSK BIT(1) +#define PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define PWR_CUT_TESTCHIP_MSK BIT(0) +#define PWR_CUT_A_MSK BIT(1) +#define PWR_CUT_B_MSK BIT(2) +#define PWR_CUT_C_MSK BIT(3) +#define PWR_CUT_D_MSK BIT(4) +#define PWR_CUT_E_MSK BIT(5) +#define PWR_CUT_F_MSK BIT(6) +#define PWR_CUT_G_MSK BIT(7) +#define PWR_CUT_ALL_MSK 0xFF + +enum pwrseq_delay_unit { + PWRSEQ_DELAY_US, + PWRSEQ_DELAY_MS, +}; + +struct wlan_pwr_cfg { + u16 offset; + u8 cut_msk; + u8 fab_msk:4; + u8 interface_msk:4; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 value; +}; + +#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset) +#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk) +#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk) +#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk) +#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base) +#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd) +#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk) +#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value) + +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, + u8 fab_version, u8 interface_type, + struct wlan_pwr_cfg pwrcfgcmd[]); + +#endif diff --git a/drivers/staging/rtlwifi/rc.c b/drivers/staging/rtlwifi/rc.c new file mode 100644 index 0000000000000000000000000000000000000000..65de0c7b5a673bc016bc91849c471def4ec236c1 --- /dev/null +++ b/drivers/staging/rtlwifi/rc.c @@ -0,0 +1,322 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "base.h" +#include "rc.h" + +/* + *Finds the highest rate index we can use + *if skb is special data like DHCP/EAPOL, we set should + *it to lowest rate CCK_1M, otherwise we set rate to + *highest rate based on wireless mode used for iwconfig + *show Tx rate. + */ +static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta, + struct sk_buff *skb, bool not_data) +{ + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_sta_info *sta_entry = NULL; + u16 wireless_mode = 0; + u8 nss; /* NSS -1 */ + + if (get_rf_type(rtlphy) >= RF_4T4R) + nss = 3; + else if (get_rf_type(rtlphy) >= RF_3T3R) + nss = 2; + else if (get_rf_type(rtlphy) >= RF_2T2R) + nss = 1; + else + nss = 0; + + /* + *this rate is no use for true rate, firmware + *will control rate at all it just used for + *1.show in iwconfig in B/G mode + *2.in rtl_get_tcb_desc when we check rate is + * 1M we will not use FW rate but user rate. + */ + + if (sta) { + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wireless_mode = sta_entry->wireless_mode; + } + + if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true, false) || + not_data) { + return 0; + } + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (wireless_mode == WIRELESS_MODE_B) { + return B_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_G) { + return G_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_N_24G) { + if (nss == 0) + return N_MODE_MCS7_RIX; + else + return N_MODE_MCS15_RIX; + } else if (wireless_mode == WIRELESS_MODE_AC_24G) { + if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + return AC_MODE_MCS8_RIX | (nss << 4); + else + return AC_MODE_MCS9_RIX | (nss << 4); + } + return 0; + } + if (wireless_mode == WIRELESS_MODE_A) { + return A_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_N_5G) { + if (nss == 0) + return N_MODE_MCS7_RIX; + else + return N_MODE_MCS15_RIX; + } else if (wireless_mode == WIRELESS_MODE_AC_5G) { + if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + return AC_MODE_MCS8_RIX | (nss << 4); + else + return AC_MODE_MCS9_RIX | (nss << 4); + } + return 0; +} + +static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta, + struct ieee80211_tx_rate *rate, + struct ieee80211_tx_rate_control *txrc, + u8 tries, s8 rix, int rtsctsenable, + bool not_data) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_sta_info *sta_entry = NULL; + u16 wireless_mode = 0; + u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0; + + if (sta) { + sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wireless_mode = sta_entry->wireless_mode; + } + rate->count = tries; + rate->idx = rix >= 0x00 ? rix : 0x00; + if (((rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) || + (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8822BE)) && + wireless_mode == WIRELESS_MODE_AC_5G) + rate->idx |= 0x10;/*2NSS for 8812AE, 8822BE*/ + + if (!not_data) { + if (txrc->short_preamble) + rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta && (sta->ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (sta && (sta->vht_cap.vht_supported)) + rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + } else { + if (mac->bw_80) + rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + else if (mac->bw_40) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + } + + if (sgi_20 || sgi_40 || sgi_80) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; + if (sta && sta->ht_cap.ht_supported && + ((wireless_mode == WIRELESS_MODE_N_5G) || + (wireless_mode == WIRELESS_MODE_N_24G))) + rate->flags |= IEEE80211_TX_RC_MCS; + if (sta && sta->vht_cap.vht_supported && + (wireless_mode == WIRELESS_MODE_AC_5G || + wireless_mode == WIRELESS_MODE_AC_24G || + wireless_mode == WIRELESS_MODE_AC_ONLY)) + rate->flags |= IEEE80211_TX_RC_VHT_MCS; + } +} + +static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, + void *priv_sta, + struct ieee80211_tx_rate_control *txrc) +{ + struct rtl_priv *rtlpriv = ppriv; + struct sk_buff *skb = txrc->skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *rates = tx_info->control.rates; + __le16 fc = rtl_get_fc(skb); + u8 try_per_rate, i, rix; + bool not_data = !ieee80211_is_data(fc); + + if (rate_control_send_low(sta, priv_sta, txrc)) + return; + + rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data); + try_per_rate = 1; + _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc, + try_per_rate, rix, 1, not_data); + + if (!not_data) { + for (i = 1; i < 4; i++) + _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i], + txrc, i, (rix - i), 1, + not_data); + } +} + +static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, + struct rtl_sta_info *sta_entry, u16 tid) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + if (mac->act_scanning) + return false; + + if (mac->opmode == NL80211_IFTYPE_STATION && + mac->cnt_after_linked < 3) + return false; + + if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP) + return true; + + return false; +} + +/*mac80211 Rate Control callbacks*/ +static void rtl_tx_status(void *ppriv, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = rtl_get_fc(skb); + struct rtl_sta_info *sta_entry; + + if (!priv_sta || !ieee80211_is_data(fc)) + return; + + if (rtl_is_special_data(mac->hw, skb, true, true)) + return; + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + return; + + if (sta) { + /* Check if aggregation has to be enabled for this tid */ + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + if ((sta->ht_cap.ht_supported) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + if (ieee80211_is_data_qos(fc)) { + u8 tid = rtl_get_tid(skb); + + if (_rtl_tx_aggr_check(rtlpriv, sta_entry, + tid)) { + sta_entry->tids[tid].agg.agg_state = + RTL_AGG_PROGRESS; + ieee80211_start_tx_ba_session(sta, tid, + 5000); + } + } + } + } +} + +static void rtl_rate_init(void *ppriv, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *priv_sta) +{ +} + +static void rtl_rate_update(void *ppriv, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *priv_sta, + u32 changed) +{ +} + +static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + return rtlpriv; +} + +static void rtl_rate_free(void *rtlpriv) +{ +} + +static void *rtl_rate_alloc_sta(void *ppriv, + struct ieee80211_sta *sta, gfp_t gfp) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_rate_priv *rate_priv; + + rate_priv = kzalloc(sizeof(*rate_priv), gfp); + if (!rate_priv) { + pr_err("Unable to allocate private rc structure\n"); + return NULL; + } + + rtlpriv->rate_priv = rate_priv; + + return rate_priv; +} + +static void rtl_rate_free_sta(void *rtlpriv, + struct ieee80211_sta *sta, void *priv_sta) +{ + struct rtl_rate_priv *rate_priv = priv_sta; + + kfree(rate_priv); +} + +static const struct rate_control_ops rtl_rate_ops = { + .name = "rtl_rc", + .alloc = rtl_rate_alloc, + .free = rtl_rate_free, + .alloc_sta = rtl_rate_alloc_sta, + .free_sta = rtl_rate_free_sta, + .rate_init = rtl_rate_init, + .rate_update = rtl_rate_update, + .tx_status = rtl_tx_status, + .get_rate = rtl_get_rate, +}; + +int rtl_rate_control_register(void) +{ + return ieee80211_rate_control_register(&rtl_rate_ops); +} + +void rtl_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rtl_rate_ops); +} diff --git a/drivers/staging/rtlwifi/rc.h b/drivers/staging/rtlwifi/rc.h new file mode 100644 index 0000000000000000000000000000000000000000..dcc8520866b7a691b68575c55e4bd73a4d00f118 --- /dev/null +++ b/drivers/staging/rtlwifi/rc.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_RC_H__ +#define __RTL_RC_H__ + +#define B_MODE_MAX_RIX 3 +#define G_MODE_MAX_RIX 11 +#define A_MODE_MAX_RIX 7 + +/* in mac80211 mcs0-mcs15 is idx0-idx15*/ +#define N_MODE_MCS7_RIX 7 +#define N_MODE_MCS15_RIX 15 + +/* in mac80211 vht mcs0-9 is in [3:0], nss is in [:4] */ +#define AC_MODE_MCS7_RIX 7 +#define AC_MODE_MCS8_RIX 8 +#define AC_MODE_MCS9_RIX 9 + +struct rtl_rate_priv { + u8 ht_cap; +}; + +int rtl_rate_control_register(void); +void rtl_rate_control_unregister(void); + +#endif diff --git a/drivers/staging/rtlwifi/regd.c b/drivers/staging/rtlwifi/regd.c new file mode 100644 index 0000000000000000000000000000000000000000..e0a3ff85edb6dde1d422c880eabd9c1fcda81600 --- /dev/null +++ b/drivers/staging/rtlwifi/regd.c @@ -0,0 +1,469 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "regd.h" + +static struct country_code_to_enum_rd allcountries[] = { + {COUNTRY_CODE_FCC, "US"}, + {COUNTRY_CODE_IC, "US"}, + {COUNTRY_CODE_ETSI, "EC"}, + {COUNTRY_CODE_SPAIN, "EC"}, + {COUNTRY_CODE_FRANCE, "EC"}, + {COUNTRY_CODE_MKK, "JP"}, + {COUNTRY_CODE_MKK1, "JP"}, + {COUNTRY_CODE_ISRAEL, "EC"}, + {COUNTRY_CODE_TELEC, "JP"}, + {COUNTRY_CODE_MIC, "JP"}, + {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, + {COUNTRY_CODE_WORLD_WIDE_13, "EC"}, + {COUNTRY_CODE_TELEC_NETGEAR, "EC"}, + {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL, "US"}, +}; + +/*Only these channels all allow active + *scan on all world regulatory domains + */ +#define RTL819x_2GHZ_CH01_11 \ + REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0) + +/*We enable active scan on these a case + *by case basis by regulatory domain + */ +#define RTL819x_2GHZ_CH12_13 \ + REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN) + +#define RTL819x_2GHZ_CH14 \ + REG_RULE(2484 - 10, 2484 + 10, 40, 0, 20, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_OFDM) + +/* 5G chan 36 - chan 64*/ +#define RTL819x_5GHZ_5150_5350 \ + REG_RULE(5150 - 10, 5350 + 10, 80, 0, 30, 0) +/* 5G chan 100 - chan 165*/ +#define RTL819x_5GHZ_5470_5850 \ + REG_RULE(5470 - 10, 5850 + 10, 80, 0, 30, 0) +/* 5G chan 149 - chan 165*/ +#define RTL819x_5GHZ_5725_5850 \ + REG_RULE(5725 - 10, 5850 + 10, 80, 0, 30, 0) + +#define RTL819x_5GHZ_ALL \ + (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) + +static const struct ieee80211_regdomain rtl_regdom_11 = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13 = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_no_midband = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_5GHZ_5150_5350, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_60_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13_5g_all = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_5GHZ_5150_5350, + RTL819x_5GHZ_5470_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_14 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + } +}; + +static bool _rtl_is_radar_freq(u16 center_freq) +{ + return center_freq >= 5260 && center_freq <= 5700; +} + +static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum nl80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (_rtl_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + reg_rule = freq_reg_info(wiphy, + ch->center_freq); + if (IS_ERR(reg_rule)) + continue; + /* + *If 11d had a rule for this channel ensure + *we enable adhoc/beaconing if it allows us to + *use it. Note that we would have disabled it + *by applying our static world regdomain by + *default during init, prior to calling our + *regulatory_hint(). + */ + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (!(reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan scan on Ch 12 and 13 */ +static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator + initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + + if (!wiphy->bands[NL80211_BAND_2GHZ]) + return; + sband = wiphy->bands[NL80211_BAND_2GHZ]; + + /* + *If no country IE has been received always enable active scan + *on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /*If a country IE has been received check its rule for this + *channel first before enabling active scan. The passive scan + *would have been enforced by the initial processing of our + *custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ + reg_rule = freq_reg_info(wiphy, ch->center_freq); + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ + reg_rule = freq_reg_info(wiphy, ch->center_freq); + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +/* + *Always apply Radar/DFS rules on + *freq range 5260 MHz - 5700 MHz + */ +static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[NL80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!_rtl_is_radar_freq(ch->center_freq)) + continue; + + /* + *We always enable radar detection/DFS on this + *frequency range. Additionally we also apply on + *this frequency range: + *- If STA mode does not yet have DFS supports disable + * active scanning + *- If adhoc mode does not support DFS yet then disable + * adhoc in the frequency. + *- If AP mode does not yet support radar detection/DFS + *do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct rtl_regulatory *reg) +{ + _rtl_reg_apply_beaconing_flags(wiphy, initiator); + _rtl_reg_apply_active_scan_flags(wiphy, initiator); +} + +static void _rtl_dump_channel_map(struct wiphy *wiphy) +{ + enum nl80211_band band; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; + sband = wiphy->bands[band]; + for (i = 0; i < sband->n_channels; i++) + ch = &sband->channels[i]; + } +} + +static int _rtl_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, + struct rtl_regulatory *reg) +{ + /* We always apply this */ + _rtl_reg_apply_radar_flags(wiphy); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); + break; + } + + _rtl_dump_channel_map(wiphy); + + return 0; +} + +static const struct ieee80211_regdomain *_rtl_regdomain_select( + struct rtl_regulatory *reg) +{ + switch (reg->country_code) { + case COUNTRY_CODE_FCC: + return &rtl_regdom_no_midband; + case COUNTRY_CODE_IC: + return &rtl_regdom_11; + case COUNTRY_CODE_TELEC_NETGEAR: + return &rtl_regdom_60_64; + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_ISRAEL: + return &rtl_regdom_12_13; + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_TELEC: + case COUNTRY_CODE_MIC: + return &rtl_regdom_14_60_64; + case COUNTRY_CODE_GLOBAL_DOMAIN: + return &rtl_regdom_14; + case COUNTRY_CODE_WORLD_WIDE_13: + case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL: + return &rtl_regdom_12_13_5g_all; + default: + return &rtl_regdom_no_midband; + } +} + +static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, + struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request * + request)) +{ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; + + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; + wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; + regd = _rtl_regdomain_select(reg); + wiphy_apply_custom_regulatory(wiphy, regd); + _rtl_reg_apply_radar_flags(wiphy); + _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(allcountries); i++) { + if (allcountries[i].countrycode == countrycode) + return &allcountries[i]; + } + return NULL; +} + +static u8 channel_plan_to_country_code(u8 channelplan) +{ + switch (channelplan) { + case 0x20: + case 0x21: + return COUNTRY_CODE_WORLD_WIDE_13; + case 0x22: + return COUNTRY_CODE_IC; + case 0x25: + return COUNTRY_CODE_ETSI; + case 0x32: + return COUNTRY_CODE_TELEC_NETGEAR; + case 0x41: + return COUNTRY_CODE_GLOBAL_DOMAIN; + case 0x7f: + return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL; + default: + return COUNTRY_CODE_MAX; /*Error*/ + } +} + +int rtl_regd_init(struct ieee80211_hw *hw, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct wiphy *wiphy = hw->wiphy; + struct country_code_to_enum_rd *country = NULL; + + if (!wiphy || !&rtlpriv->regd) + return -EINVAL; + + /* init country_code from efuse channel plan */ + rtlpriv->regd.country_code = + channel_plan_to_country_code(rtlpriv->efuse.channel_plan); + + RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM regdomain: 0x%0x country code: %d\n", + rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); + + if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { + RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); + + rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; + } + + country = _rtl_regd_find_country(rtlpriv->regd.country_code); + + if (country) { + rtlpriv->regd.alpha2[0] = country->iso_name[0]; + rtlpriv->regd.alpha2[1] = country->iso_name[1]; + } else { + rtlpriv->regd.alpha2[0] = '0'; + rtlpriv->regd.alpha2[1] = '0'; + } + + RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); + + _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); + + return 0; +} + +void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); + + _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); +} diff --git a/drivers/staging/rtlwifi/regd.h b/drivers/staging/rtlwifi/regd.h new file mode 100644 index 0000000000000000000000000000000000000000..5626015a6d0d61aa0300a8153c5f91e9e9819229 --- /dev/null +++ b/drivers/staging/rtlwifi/regd.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_REGD_H__ +#define __RTL_REGD_H__ + +/* for kernel 3.14 , both value are changed to IEEE80211_CHAN_NO_IR*/ +#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR +#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR + +struct country_code_to_enum_rd { + u16 countrycode; + const char *iso_name; +}; + +enum country_code_type_t { + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_MIC = 9, + COUNTRY_CODE_GLOBAL_DOMAIN = 10, + COUNTRY_CODE_WORLD_WIDE_13 = 11, + COUNTRY_CODE_TELEC_NETGEAR = 12, + COUNTRY_CODE_WORLD_WIDE_13_5G_ALL = 13, + + /*add new channel plan above this line */ + COUNTRY_CODE_MAX +}; + +int rtl_regd_init(struct ieee80211_hw *hw, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)); +void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); + +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/Makefile b/drivers/staging/rtlwifi/rtl8822be/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d535ff8febf1bda75bff1abe59aef261cab440ac --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/Makefile @@ -0,0 +1,7 @@ +rtl8822be-objs := \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + sw.o \ + trx.o diff --git a/drivers/staging/rtlwifi/rtl8822be/def.h b/drivers/staging/rtlwifi/rtl8822be/def.h new file mode 100644 index 0000000000000000000000000000000000000000..7942ddfdcf431dbc9c53e7876baa3856c1340997 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/def.h @@ -0,0 +1,82 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_DEF_H__ +#define __RTL8822B_DEF_H__ + +#define RX_DESC_NUM_8822BE 512 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 + +#define IS_HT_RATE(_rate) (_rate >= DESC_RATEMCS0) +#define IS_CCK_RATE(_rate) (_rate >= DESC_RATE1M && _rate <= DESC_RATE11M) +#define IS_OFDM_RATE(_rate) (_rate >= DESC_RATE6M && _rate <= DESC_RATE54M) +#define IS_1T_RATE(_rate) \ + ((_rate >= DESC_RATE1M && _rate <= DESC_RATEMCS7) || \ + (_rate >= DESC_RATEVHT1SS_MCS0 && _rate <= DESC_RATEVHT1SS_MCS9)) +#define IS_2T_RATE(_rate) \ + ((_rate >= DESC_RATEMCS8 && _rate <= DESC_RATEMCS15) || \ + (_rate >= DESC_RATEVHT2SS_MCS0 && _rate <= DESC_RATEVHT2SS_MCS9)) + +#define IS_1T_RATESEC(_rs) \ + ((_rs == CCK) || (_rs == OFDM) || (_rs == HT_MCS0_MCS7) || \ + (_rs == VHT_1SSMCS0_1SSMCS9)) +#define IS_2T_RATESEC(_rs) \ + ((_rs == HT_MCS8_MCS15) || (_rs == VHT_2SSMCS0_2SSMCS9)) + +enum rx_packet_type { + NORMAL_RX, + C2H_PACKET, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum vht_data_sc { + VHT_DATA_SC_DONOT_CARE = 0, + VHT_DATA_SC_20_UPPER_OF_80MHZ = 1, + VHT_DATA_SC_20_LOWER_OF_80MHZ = 2, + VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3, + VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4, + VHT_DATA_SC_20_RECV1 = 5, + VHT_DATA_SC_20_RECV2 = 6, + VHT_DATA_SC_20_RECV3 = 7, + VHT_DATA_SC_20_RECV4 = 8, + VHT_DATA_SC_40_UPPER_OF_80MHZ = 9, + VHT_DATA_SC_40_LOWER_OF_80MHZ = 10, +}; +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c new file mode 100644 index 0000000000000000000000000000000000000000..8e24da16752c23e1cddb447efe2cc25d6f65f73b --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/fw.c @@ -0,0 +1,968 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "fw.h" + +static bool _rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw *hw, + u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR_8822B); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +static void _rtl8822be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read; + u8 buf_index = 0; + bool bwrite_success = false; + u8 wait_h2c_limmit = 100; + u8 boxcontent[4], boxextcontent[4]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + /* 1. Prevent race condition in setting H2C cmd. + * (copy from MgntActSet_RF_State().) + */ + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! wait..H2C_ID=%d.\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_success) { + /* 2. Find the last BOX number which has been writen. */ + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX0_8822B; + box_extreg = REG_HMEBOX_E0_8822B; + break; + case 1: + box_reg = REG_HMEBOX1_8822B; + box_extreg = REG_HMEBOX_E1_8822B; + break; + case 2: + box_reg = REG_HMEBOX2_8822B; + box_extreg = REG_HMEBOX_E2_8822B; + break; + case 3: + box_reg = REG_HMEBOX3_8822B; + box_extreg = REG_HMEBOX_E3_8822B; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + + /* 3. Check if the box content is empty. */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_CR_8822B); + + if (u1b_tmp == 0xea) { + if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS_8822B) == + 0xea || + rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY_8822B) == + 0xea) + rtl_write_byte(rtlpriv, REG_SYS_CFG1_8822B + 3, + 0xff); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "REG_CR is unavaliable\n"); + break; + } + + wait_h2c_limmit = 100; + isfw_read = _rtl8822be_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING, + "Wait too long for FW clear MB%d!!!\n", + boxnum); + break; + } + udelay(10); + isfw_read = + _rtl8822be_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x130); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW clear MB%d!!! 0x130 = %2x\n", + boxnum, u1b_tmp); + } + + /* If Fw has not read the last H2C cmd, + * break and give up this H2C. + */ + if (!isfw_read) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C reg BOX[%d] fail,Fw don't read.\n", + boxnum); + break; + } + /* 4. Fill the H2C cmd into box */ + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", box_reg, + element_id); + + switch (cmd_len) { + case 1: + case 2: + case 3: + /*boxcontent[0] &= ~(BIT(7));*/ + memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index, + cmd_len); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + case 5: + case 6: + case 7: + /*boxcontent[0] |= (BIT(7));*/ + memcpy((u8 *)(boxextcontent), cmdbuffer + buf_index + 3, + cmd_len - 3); + memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index, + 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + + bwrite_success = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, + u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_cmdbuf[8]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "return H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, + "h2c cmd: len=%d %02X%02X%02X%02X %02X%02X%02X%02X\n", cmd_len, + tmp_cmdbuf[2], tmp_cmdbuf[1], tmp_cmdbuf[0], element_id, + tmp_cmdbuf[6], tmp_cmdbuf[5], tmp_cmdbuf[4], tmp_cmdbuf[3]); + + _rtl8822be_fill_h2c_command(hw, element_id, cmd_len, tmp_cmdbuf); +} + +void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw) +{ + u8 h2c_set_default_port_id[H2C_DEFAULT_PORT_ID_LEN]; + + SET_H2CCMD_DFTPID_PORT_ID(h2c_set_default_port_id, 0); + SET_H2CCMD_DFTPID_MAC_ID(h2c_set_default_port_id, 0); + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_DEFAULT_PORT_ID, + H2C_DEFAULT_PORT_ID_LEN, + h2c_set_default_port_id); +} + +void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[H2C_8822B_PWEMODE_LENGTH] = {0}; + static u8 prev_h2c[H2C_8822B_PWEMODE_LENGTH] = {0}; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rlbm, power_state = 0, byte5 = 0; + u8 awake_intvl; /* DTIM = (awake_intvl - 1) */ + u8 smart_ps = 0; + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false); + bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_lps_on(rtlpriv) : false); + + memset(u1_h2c_set_pwrmode, 0, H2C_8822B_PWEMODE_LENGTH); + + if (bt_ctrl_lps) + mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE); + + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n", + mode, bt_ctrl_lps); + + switch (mode) { + case FW_PS_MIN_MODE: + rlbm = 0; + awake_intvl = 2; + smart_ps = ppsc->smart_ps; + break; + case FW_PS_MAX_MODE: + rlbm = 1; + awake_intvl = 2; + smart_ps = ppsc->smart_ps; + break; + case FW_PS_DTIM_MODE: + rlbm = 2; + awake_intvl = ppsc->reg_max_lps_awakeintvl; + /* + * hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period + * is only used in swlps. + */ + smart_ps = ppsc->smart_ps; + break; + case FW_PS_ACTIVE_MODE: + rlbm = 0; + awake_intvl = 1; + break; + default: + rlbm = 2; + awake_intvl = 4; + smart_ps = ppsc->smart_ps; + break; + } + + if (rtlpriv->mac80211.p2p) { + awake_intvl = 2; + rlbm = 1; + } + + if (mode == FW_PS_ACTIVE_MODE) { + byte5 = 0x40; + power_state = FW_PWR_STATE_ACTIVE; + } else { + if (bt_ctrl_lps) { + byte5 = btc_ops->btc_get_lps_val(rtlpriv); + power_state = btc_ops->btc_get_rpwm_val(rtlpriv); + + if ((rlbm == 2) && (byte5 & BIT(4))) { + /* Keep awake interval to 1 to prevent from + * decreasing coex performance + */ + awake_intvl = 2; + rlbm = 2; + } + smart_ps = 0; + } else { + byte5 = 0x40; + power_state = FW_PWR_STATE_RF_OFF; + } + } + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); + SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, smart_ps); + SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, awake_intvl); + SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); + SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl8822be_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode, + H2C_8822B_PWEMODE_LENGTH); + + if (!memcmp(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH)) + return; + memcpy(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH); + + rtl8822be_set_default_port_id_cmd(hw); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_SETPWRMODE, + H2C_8822B_PWEMODE_LENGTH, u1_h2c_set_pwrmode); +} + +void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 parm[4] = {0, 0, 0, 0}; + /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect + * bit1=0-->update Media Status to MACID + * bit1=1-->update Media Status from MACID to MACID_End + * parm[1]: MACID, if this is INFRA_STA, MacID = 0 + * parm[2]: MACID_End + * parm[3]: bit2-0: port ID + */ + + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus); + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MSRRPT, 4, parm); +} + +static bool _rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw *hw, + struct sk_buff *skb, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + struct rtl_tx_buffer_desc *pbd_desc; + unsigned long flags; + struct sk_buff *pskb = NULL; + u8 *pdesc_or_bddesc; + dma_addr_t dma_addr; + + if (hw_queue != BEACON_QUEUE && hw_queue != H2C_QUEUE) + return false; + + ring = &rtlpci->tx_ring[hw_queue]; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + if (hw_queue == BEACON_QUEUE) { + pdesc = &ring->desc[0]; + pbd_desc = &ring->buffer_desc[0]; + pdesc_or_bddesc = (u8 *)pbd_desc; + + /* free previous beacon queue */ + pskb = __skb_dequeue(&ring->queue); + + if (!pskb) + goto free_prev_skb_done; + + dma_addr = rtlpriv->cfg->ops->get_desc( + hw, (u8 *)pbd_desc, true, HW_DESC_TXBUFF_ADDR); + + pci_unmap_single(rtlpci->pdev, dma_addr, skb->len, + PCI_DMA_TODEVICE); + kfree_skb(pskb); + +free_prev_skb_done: + ; + + } else { /* hw_queue == TXCMD_QUEUE */ + if (rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "get_available_desc fail hw_queue=%d\n", + hw_queue); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, + flags); + return false; + } + + pdesc = &ring->desc[ring->cur_tx_wp]; + pbd_desc = &ring->buffer_desc[ring->cur_tx_wp]; + pdesc_or_bddesc = (u8 *)pdesc; + } + + rtlpriv->cfg->ops->fill_tx_special_desc(hw, (u8 *)pdesc, (u8 *)pbd_desc, + skb, hw_queue); + + __skb_queue_tail(&ring->queue, skb); + + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc_or_bddesc, true, + HW_DESC_OWN, (u8 *)&hw_queue); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, hw_queue); + + return true; +} + +bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf, + u32 size) +{ + struct sk_buff *skb = NULL; + u8 u1b_tmp; + int count; + + skb = dev_alloc_skb(size); + memcpy((u8 *)skb_put(skb, size), buf, size); + + if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE)) + return false; + + /* These code isn't actually need, because halmac will check + * BCN_VALID + */ + + /* Polling Beacon Queue to send Beacon */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1); + count = 0; + while ((count < 20) && (u1b_tmp & BIT(4))) { + count++; + udelay(10); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1); + } + + if (count >= 20) + pr_err("%s polling beacon fail\n", __func__); + + return true; +} + +bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf, + u32 size) +{ + struct sk_buff *skb = NULL; + + /* without GFP_DMA, pci_map_single() may not work */ + skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA); + memcpy((u8 *)skb_put(skb, size), buf, size); + + return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE); +} + +/* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */ +#define BEACON_PG 0 /* ->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /* ->5 */ +#define QOS_NULL_PG 6 +#define BT_QOS_NULL_PG 7 + +#define TOTAL_RESERVED_PKT_LEN 1024 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */ + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65, + 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B, + 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06, + 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, + 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, + 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, + 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50, + 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, + 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00, + + /* page 1 beacon */ + 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 6 qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 7 BT-qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1_rsvd_page_loc[7] = {0}; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + u8 *qosnull; + u8 *btqosnull; + + memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc)); + + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *--------------------------------------------------------- + */ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG); + + /*--------------------------------------------------------- + * (4) probe response + *---------------------------------------------------------- + */ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG); + + /*--------------------------------------------------------- + * (5) QoS null data + *---------------------------------------------------------- + */ + qosnull = &reserved_page_packet[QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG); + + /*--------------------------------------------------------- + * (6) BT QoS null data + *---------------------------------------------------------- + */ + btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc, + BT_QOS_NULL_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1_rsvd_page_loc, 3); + + skb = dev_alloc_skb(totalpacketlen); + memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet, + totalpacketlen); + + rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n", + u1_rsvd_page_loc, 3); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE, + sizeof(u1_rsvd_page_loc), + u1_rsvd_page_loc); + } else + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} + +/* Should check FW support p2p or not. */ +static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, + u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = {ctwindow}; + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1, + u1_ctwindow_period); +} + +void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info; + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow); + } + /* hw only support 2 set of NoA */ + for (i = 0; i < p2pinfo->noa_num; i++) { + /* To control the register setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low + (50 * 1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4)); + p2p_ps_offload->offload_en = 1; + + if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1, + (u8 *)p2p_ps_offload); +} + +static +void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw, + u8 c2h_sub_cmd_id, + u8 c2h_cmd_len, + u8 *c2h_content_buf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_halmac_ops *halmac_ops; + + switch (c2h_sub_cmd_id) { + case 0x0F: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_TX_REPORT!\n"); + rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len); + break; + default: + /* indicate c2h pkt + rx desc to halmac */ + halmac_ops = rtlpriv->halmac.ops; + halmac_ops->halmac_c2h_handle(rtlpriv, + c2h_content_buf - 24 - 2 - 2, + c2h_cmd_len + 24 + 2 + 2); + break; + } +} + +void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id, + u8 c2h_cmd_len, u8 *tmp_buf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + + if (c2h_cmd_id == 0xFF) { + rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0], + c2h_cmd_len - 2, + tmp_buf + 2); + return; + } + + switch (c2h_cmd_id) { + case C2H_8822B_DBG: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_DBG!!\n"); + break; + case C2H_8822B_TXBF: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822B_TXBF!!\n"); + break; + case C2H_8822B_BT_INFO: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_BT_INFO!!\n"); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf, + c2h_cmd_len); + break; + case C2H_8822B_BT_MP: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_BT_MP!!\n"); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf, + c2h_cmd_len); + break; + default: + if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing( + rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf)) + break; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id); + break; + } +} + +void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0; + u8 *tmp_buf = NULL; + + c2h_cmd_id = buffer[0]; + c2h_cmd_seq = buffer[1]; + c2h_cmd_len = len - 2; + tmp_buf = buffer + 2; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n", + c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len); + + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len); + + switch (c2h_cmd_id) { + case C2H_8822B_BT_INFO: + case C2H_8822B_BT_MP: + rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf); + break; + default: + rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, + tmp_buf); + break; + } +} diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.h b/drivers/staging/rtlwifi/rtl8822be/fw.h new file mode 100644 index 0000000000000000000000000000000000000000..3ad7a66e80a34b263c2ea1866bd82b3c192119c7 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/fw.h @@ -0,0 +1,198 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B__FW__H__ +#define __RTL8822B__FW__H__ + +#define USE_OLD_WOWLAN_DEBUG_FW 0 + +#define H2C_8822B_RSVDPAGE_LOC_LEN 5 +#define H2C_8822B_PWEMODE_LENGTH 7 +#define H2C_8822B_JOINBSSRPT_LENGTH 1 +#define H2C_8822B_AP_OFFLOAD_LENGTH 3 +#define H2C_8822B_WOWLAN_LENGTH 3 +#define H2C_8822B_KEEP_ALIVE_CTRL_LENGTH 3 +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 1 +#else +#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 3 +#endif +#define H2C_8822B_AOAC_GLOBAL_INFO_LEN 2 +#define H2C_8822B_AOAC_RSVDPAGE_LOC_LEN 7 +#define H2C_DEFAULT_PORT_ID_LEN 2 + +/* Fw PS state for RPWM. + *BIT[2:0] = HW state + *BIT[3] = Protocol PS state, 1: register active state, 0: register sleep state + *BIT[4] = sub-state + */ +#define FW_PS_RF_ON BIT(2) +#define FW_PS_REGISTER_ACTIVE BIT(3) + +#define FW_PS_ACK BIT(6) +#define FW_PS_TOGGLE BIT(7) + +/* 8822B RPWM value*/ +/* BIT[0] = 1: 32k, 0: 40M*/ +#define FW_PS_CLOCK_OFF BIT(0) /* 32k */ +#define FW_PS_CLOCK_ON 0 /* 40M */ + +#define FW_PS_STATE_MASK (0x0F) +#define FW_PS_STATE_HW_MASK (0x07) +#define FW_PS_STATE_INT_MASK (0x3F) + +#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x)) + +#define FW_PS_STATE_ALL_ON_8822B (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_ON_8822B (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_OFF_8822B (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_OFF_LOW_PWR (FW_PS_CLOCK_OFF) + +/* For 8822B H2C PwrMode Cmd ID 5.*/ +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK) + +#define IS_IN_LOW_POWER_STATE_8822B(fw_ps_state) \ + (FW_PS_STATE(fw_ps_state) == FW_PS_CLOCK_OFF) + +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +enum rtl8822b_h2c_cmd { + H2C_8822B_RSVDPAGE = 0, + H2C_8822B_MSRRPT = 1, + H2C_8822B_SCAN = 2, + H2C_8822B_KEEP_ALIVE_CTRL = 3, + H2C_8822B_DISCONNECT_DECISION = 4, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_8822B_WO_WLAN = 5, +#endif + H2C_8822B_INIT_OFFLOAD = 6, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_8822B_REMOTE_WAKE_CTRL = 7, +#endif + H2C_8822B_AP_OFFLOAD = 8, + H2C_8822B_BCN_RSVDPAGE = 9, + H2C_8822B_PROBERSP_RSVDPAGE = 10, + + H2C_8822B_SETPWRMODE = 0x20, + H2C_8822B_PS_TUNING_PARA = 0x21, + H2C_8822B_PS_TUNING_PARA2 = 0x22, + H2C_8822B_PS_LPS_PARA = 0x23, + H2C_8822B_P2P_PS_OFFLOAD = 024, + H2C_8822B_DEFAULT_PORT_ID = 0x2C, + +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) + H2C_8822B_WO_WLAN = 0x80, + H2C_8822B_REMOTE_WAKE_CTRL = 0x81, + H2C_8822B_AOAC_GLOBAL_INFO = 0x82, + H2C_8822B_AOAC_RSVDPAGE = 0x83, +#endif + H2C_8822B_MACID_CFG = 0x40, + H2C_8822B_RSSI_REPORT = 0x42, + H2C_8822B_MACID_CFG_3SS = 0x46, + /*Not defined CTW CMD for P2P yet*/ + H2C_8822B_P2P_PS_CTW_CMD = 0x99, + MAX_8822B_H2CCMD +}; + +enum rtl8822b_c2h_evt { + C2H_8822B_DBG = 0x00, + C2H_8822B_LB = 0x01, + C2H_8822B_TXBF = 0x02, + C2H_8822B_TX_REPORT = 0x03, + C2H_8822B_BT_INFO = 0x09, + C2H_8822B_BT_MP = 0x0B, + C2H_8822B_RA_RPT = 0x0C, + MAX_8822B_C2HEVENT +}; + +/* H2C: 0x20 */ +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 7, __val) +#define SET_H2CCMD_PWRMODE_PARM_CLK_REQ(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val) +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 4, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 4, 4, __val) +#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 1, __val) +#define SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_RPT(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 2, 1, __val) +#define SET_H2CCMD_PWRMODE_PARM_PORT_ID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 5, 3, __val) +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 5, 0, 8, __val) + +/* H2C: 0x00 */ +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val) + +/* H2C: 0x01 */ +#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val) +#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val) +#define SET_H2CCMD_MSRRPT_PARM_MACID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd + 1, 0, 8, __val) +#define SET_H2CCMD_MSRRPT_PARM_MACID_END(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd + 2, 0, 8, __val) + +/* H2C: 0x2C */ +#define SET_H2CCMD_DFTPID_PORT_ID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)), 0, 8, (__val)) +#define SET_H2CCMD_DFTPID_MAC_ID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)) + 1, 0, 8, (__val)) + +void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, + u8 *cmdbuffer); +void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw); +void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len); +void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id, + u8 c2h_cmd_len, u8 *tmp_buf); +bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf, + u32 size); +bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf, + u32 size); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/hw.c b/drivers/staging/rtlwifi/rtl8822be/hw.c new file mode 100644 index 0000000000000000000000000000000000000000..74386003044f95eb728b16f3c36706cc4135384b --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/hw.c @@ -0,0 +1,2441 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "fw.h" +#include "led.h" +#include "hw.h" + +#define LLT_CONFIG 5 + +u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ +u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, + 138, 155, 171}; + +static void _rtl8822be_set_bcn_ctrl_reg(struct ieee80211_hw *hw, u8 set_bits, + u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL_8822B, + (u8)rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl8822be_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, tmp & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 1, 0x64); + tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2, tmp); +} + +static void _rtl8822be_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, tmp | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 1, 0xff); + tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2, tmp); +} + +static void _rtl8822be_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl8822be_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl8822be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val, + bool b_need_turn_off_ckk) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 count = 0, isr_regaddr, content; + bool b_schedule_timer = b_need_turn_off_ckk; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + + while (1) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (rtlhal->fw_clk_change_in_progress) { + while (rtlhal->fw_clk_change_in_progress) { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + count++; + udelay(100); + if (count > 1000) + return; + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + } + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + break; + } + } + + if (IS_IN_LOW_POWER_STATE_8822B(rtlhal->fw_ps_state)) { + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + if (FW_PS_IS_ACK(rpwm_val)) { + isr_regaddr = REG_HISR0_8822B; + content = rtl_read_dword(rtlpriv, isr_regaddr); + while (!(content & IMR_CPWM) && (count < 500)) { + udelay(50); + count++; + content = rtl_read_dword(rtlpriv, isr_regaddr); + } + + if (content & IMR_CPWM) { + rtl_write_word(rtlpriv, isr_regaddr, 0x0100); + rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_8822B; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Receive CPWM INT!!! PSState = %X\n", + rtlhal->fw_ps_state); + } + } + + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + + } else { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } +} + +static void _rtl8822be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + enum rf_pwrstate rtstate; + bool b_schedule_timer = false; + u8 queue; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + if (!rtlhal->allow_sw_to_change_hwclc) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); + if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) + return; + + for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { + ring = &rtlpci->tx_ring[queue]; + if (skb_queue_len(&ring->queue)) { + b_schedule_timer = true; + break; + } + } + + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + return; + } + + if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (!rtlhal->fw_clk_change_in_progress) { + rtlhal->fw_clk_change_in_progress = true; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); + rtl_write_word(rtlpriv, REG_HISR0_8822B, 0x0100); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } +} + +static void _rtl8822be_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= (FW_PS_STATE_RF_OFF_8822B | FW_PS_ACK); + _rtl8822be_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl8822be_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR; + _rtl8822be_set_fw_clock_off(hw, rpwm_val); +} + +void rtl8822be_fw_clk_off_timer_callback(unsigned long data) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *)data; + + _rtl8822be_set_fw_ps_rf_off_low_power(hw); +} + +static void _rtl8822be_fwlps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = false; + u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + + if (ppsc->low_power_enable) { + rpwm_val = (FW_PS_STATE_ALL_ON_8822B | FW_PS_ACK); /* RF on */ + _rtl8822be_set_fw_clock_on(hw, rpwm_val, false); + rtlhal->allow_sw_to_change_hwclc = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } else { + rpwm_val = FW_PS_STATE_ALL_ON_8822B; /* RF on */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } +} + +static void _rtl8822be_fwlps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = true; + u8 rpwm_val; + + if (ppsc->low_power_enable) { + rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlhal->allow_sw_to_change_hwclc = true; + _rtl8822be_set_fw_clock_off(hw, rpwm_val); + } else { + rpwm_val = FW_PS_STATE_RF_OFF_8822B; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + } +} + +void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON: { + enum rf_pwrstate rf_state; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rf_state)); + if (rf_state == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR_8822B); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + } break; + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF: { + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR_8822B + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B); + + *((u64 *)(val)) = tsf; + + } break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case not process %x\n", variable); + break; + } +} + +static void _rtl8822be_download_rsvd_page(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_regcr, tmp_reg422; + u8 bcnvalid_reg /*, txbc_reg*/; + u8 count = 0, dlbcn_count = 0; + bool b_recover = false; + + /*Set REG_CR_8822B bit 8. DMA beacon by SW.*/ + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR_8822B + 1); + rtl_write_byte(rtlpriv, REG_CR_8822B + 1, tmp_regcr | BIT(0)); + + /* Disable Hw protection for a time which revserd for Hw sending beacon. + * Fix download reserved page packet fail + * that access collision with the protection time. + * 2010.05.11. Added by tynli. + */ + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(4), 0); + + /* Set FWHW_TXQ_CTRL 0x422[6]=0 to + * tell Hw the packet is not a real beacon frame. + */ + tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, + tmp_reg422 & (~BIT(6))); + + if (tmp_reg422 & BIT(6)) + b_recover = true; + + do { + /* Clear beacon valid check bit */ + bcnvalid_reg = + rtl_read_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1); + bcnvalid_reg = bcnvalid_reg | BIT(7); + rtl_write_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1, + bcnvalid_reg); + + /* download rsvd page */ + rtl8822be_set_fw_rsvdpagepkt(hw, false); + + /* check rsvd page download OK. */ + bcnvalid_reg = + rtl_read_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1); + + count = 0; + while (!(BIT(7) & bcnvalid_reg) && count < 20) { + count++; + udelay(50); + bcnvalid_reg = rtl_read_byte( + rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1); + } + + dlbcn_count++; + } while (!(BIT(7) & bcnvalid_reg) && dlbcn_count < 5); + + if (!(BIT(7) & bcnvalid_reg)) + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, + "Download RSVD page failed!\n"); + + /* Enable Bcn */ + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, + tmp_reg422); +} + +void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *efuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_ETHER_ADDR: + rtlpriv->halmac.ops->halmac_set_mac_address(rtlpriv, 0, val); + break; + case HW_VAR_BASIC_RATE: { + u16 b_rate_cfg = ((u16 *)val)[0]; + + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + b_rate_cfg = (b_rate_cfg | 0xd) & (~BIT(1)); + rtl_write_byte(rtlpriv, REG_RRSR_8822B, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR_8822B + 1, + (b_rate_cfg >> 8) & 0xff); + } break; + case HW_VAR_BSSID: + rtlpriv->halmac.ops->halmac_set_bssid(rtlpriv, 0, val); + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_8822B + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX_8822B + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS_8822B + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS_8822B + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM_8822B, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM_8822B, + *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME: { + u8 e_aci; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_TRACE, "HW_VAR_SLOT_TIME %x\n", + val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT_8822B, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } + } break; + case HW_VAR_ACK_PREAMBLE: { + u8 reg_tmp; + u8 short_preamble = (bool)(*(u8 *)val); + + reg_tmp = (rtlpriv->mac80211.cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR_8822B + 2, reg_tmp); + rtlpriv->mac80211.short_preamble = short_preamble; + } break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG_8822B, *((u8 *)val)); + break; + case HW_VAR_AMPDU_FACTOR: { + u32 ampdu_len = (*((u8 *)val)); + + ampdu_len = (0x2000 << ampdu_len) - 1; + rtl_write_dword(rtlpriv, REG_AMPDU_MAX_LENGTH_8822B, ampdu_len); + } break; + case HW_VAR_AC_PARAM: { + u8 e_aci = *((u8 *)val); + + if (mac->vif && mac->vif->bss_conf.assoc && !mac->act_scanning) + rtl8822be_set_qos(hw, e_aci); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, + (u8 *)(&e_aci)); + } break; + case HW_VAR_ACM_CTRL: { + u8 e_aci = *((u8 *)val); + union aci_aifsn *aifs = (union aci_aifsn *)&mac->ac[0].aifs; + + u8 acm = aifs->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL_8822B); + + acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQ_EN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQ_EN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQ_EN; + break; + default: + RT_TRACE( + rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQ_EN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQ_EN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQ_EN); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case not process\n"); + break; + } + } + + RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL_8822B, acm_ctrl); + } break; + case HW_VAR_RCR: { + rtl_write_dword(rtlpriv, REG_RCR_8822B, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + } break; + case HW_VAR_RETRY_LIMIT: { + u8 retry_limit = ((u8 *)(val))[0]; + + rtl_write_word(rtlpriv, REG_RETRY_LIMIT_8822B, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + } break; + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, + (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + efuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + efuse->efuse_usedpercentage = *((u8 *)val); + break; + case HW_VAR_IO_CMD: + rtl8822be_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_SET_RPWM: + break; + case HW_VAR_H2C_FW_PWRMODE: + rtl8822be_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_RESUME_CLK_ON: + _rtl8822be_set_fw_ps_rf_on(hw); + break; + case HW_VAR_FW_LPS_ACTION: { + bool b_enter_fwlps = *((bool *)val); + + if (b_enter_fwlps) + _rtl8822be_fwlps_enter(hw); + else + _rtl8822be_fwlps_leave(hw); + } break; + case HW_VAR_H2C_FW_JOINBSSRPT: { + u8 mstatus = (*(u8 *)val); + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); + _rtl8822be_download_rsvd_page(hw); + } + rtl8822be_set_default_port_id_cmd(hw); + rtl8822be_set_fw_media_status_rpt_cmd(hw, mstatus); + } break; + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl8822be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_AID: { + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT_8822B); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT_8822B, + (u2btmp | mac->assoc_id)); + } break; + case HW_VAR_CORRECT_TSF: { + u8 btype_ibss = ((u8 *)(val))[0]; + + if (btype_ibss) + _rtl8822be_stop_tx_beacon(hw); + + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR_8822B, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR_8822B + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl8822be_resume_tx_beacon(hw); + } break; + case HW_VAR_KEEP_ALIVE: { + u8 array[2]; + + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_KEEP_ALIVE_CTRL, 2, array); + } break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case not process %x\n", variable); + break; + } +} + +static void _rtl8822be_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_led *led0 = &pcipriv->ledctl.sw_led0; + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl8822be_sw_led_on(hw, led0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl8822be_sw_led_on(hw, led0); + else + rtl8822be_sw_led_off(hw, led0); +} + +static bool _rtl8822be_init_trxbd(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + /*struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));*/ + + u8 bytetmp; + /*u16 wordtmp;*/ + u32 dwordtmp; + + /* Set TX/RX descriptor physical address -- HI part */ + if (!rtlpriv->cfg->mod_params->dma64) + goto dma64_end; + + rtl_write_dword(rtlpriv, REG_H2CQ_TXBD_DESA_8822B + 4, + ((u64)rtlpci->tx_ring[H2C_QUEUE].buffer_desc_dma) >> + 32); + rtl_write_dword(rtlpriv, REG_BCNQ_TXBD_DESA_8822B + 4, + ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) >> + 32); + rtl_write_dword(rtlpriv, REG_MGQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_VOQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_VIQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_BKQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_HI0Q_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma >> 32); + + rtl_write_dword(rtlpriv, REG_RXQ_RXBD_DESA_8822B + 4, + (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma >> 32); + +dma64_end: + /* Set TX/RX descriptor physical address(from OS API). */ + rtl_write_dword(rtlpriv, REG_H2CQ_TXBD_DESA_8822B, + ((u64)rtlpci->tx_ring[H2C_QUEUE].buffer_desc_dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BCNQ_TXBD_DESA_8822B, + ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + dwordtmp = rtl_read_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B); /* need? */ + rtl_write_dword(rtlpriv, REG_BKQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HI0Q_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + + rtl_write_dword(rtlpriv, REG_RXQ_RXBD_DESA_8822B, + (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + /* Reset R/W point */ + rtl_write_dword(rtlpriv, REG_BD_RWPTR_CLR_8822B, 0x3fffffff); + + /* Reset the H2CQ R/W point index to 0 */ + dwordtmp = rtl_read_dword(rtlpriv, REG_H2CQ_CSR_8822B); + rtl_write_dword(rtlpriv, REG_H2CQ_CSR_8822B, + (dwordtmp | BIT(8) | BIT(16))); + + bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 3); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 3, bytetmp | 0xF7); + + rtl_write_dword(rtlpriv, REG_INT_MIG_8822B, 0); + + rtl_write_dword(rtlpriv, REG_MCUTST_I_8822B, 0x0); + + rtl_write_word(rtlpriv, REG_H2CQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_MGQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VIQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_BEQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_BKQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI0Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI1Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI2Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI3Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI4Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI5Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI6Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI7Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + /*Rx*/ + rtl_write_word(rtlpriv, REG_RX_RXBD_NUM_8822B, + RX_DESC_NUM_8822BE | + ((RTL8822BE_SEG_NUM << 13) & 0x6000) | 0x8000); + + rtl_write_dword(rtlpriv, REG_BD_RWPTR_CLR_8822B, 0XFFFFFFFF); + + _rtl8822be_gen_refresh_led_state(hw); + + return true; +} + +static void _rtl8822be_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tmp; + + if (!ppsc->support_backdoor) + return; + + pci_read_config_byte(rtlpci->pdev, 0x70f, &tmp); + pci_write_config_byte(rtlpci->pdev, 0x70f, tmp | BIT(7)); + + pci_read_config_byte(rtlpci->pdev, 0x719, &tmp); + pci_write_config_byte(rtlpci->pdev, 0x719, tmp | BIT(3) | BIT(4)); +} + +void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + u8 tmp; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TX_ENC_ENABLE | SRC_RX_DEC_ENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TX_USE_DK; + sec_reg_value |= SCR_RX_USE_DK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + tmp = rtl_read_byte(rtlpriv, REG_CR_8822B + 1); + rtl_write_byte(rtlpriv, REG_CR_8822B + 1, tmp | BIT(1)); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n", + sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +static bool _rtl8822be_check_pcie_dma_hang(struct rtl_priv *rtlpriv) +{ + u8 tmp; + + /* write reg 0x350 Bit[26]=1. Enable debug port. */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3); + if (!(tmp & BIT(2))) { + rtl_write_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3, + (tmp | BIT(2))); + mdelay(100); /* Suggested by DD Justin_tsai. */ + } + + /* read reg 0x350 Bit[25] if 1 : RX hang + * read reg 0x350 Bit[24] if 1 : TX hang + */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3); + if ((tmp & BIT(0)) || (tmp & BIT(1))) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "CheckPcieDMAHang8822BE(): true!!\n"); + return true; + } else { + return false; + } +} + +static void _rtl8822be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv, + bool mac_power_on) +{ + u8 tmp; + bool release_mac_rx_pause; + u8 backup_pcie_dma_pause; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "ResetPcieInterfaceDMA8822BE()\n"); + + /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03" + * released by SD1 Alan. + * 2013.05.07, by tynli. + */ + + /* 1. disable register write lock + * write 0x1C bit[1:0] = 2'h0 + * write 0xCC bit[2] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL_8822B); + tmp &= ~(BIT(1) | BIT(0)); + rtl_write_byte(rtlpriv, REG_RSV_CTRL_8822B, tmp); + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B); + tmp |= BIT(2); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B, tmp); + + /* 2. Check and pause TRX DMA + * write 0x284 bit[18] = 1'b1 + * write 0x301 = 0xFF + */ + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL_8822B); + if (tmp & BIT(2)) { + /* Already pause before the function for another purpose. */ + release_mac_rx_pause = false; + } else { + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL_8822B, + (tmp | BIT(2))); + release_mac_rx_pause = true; + } + + backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1); + if (backup_pcie_dma_pause != 0xFF) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1, 0xFF); + + if (mac_power_on) { + /* 3. reset TRX function + * write 0x100 = 0x00 + */ + rtl_write_byte(rtlpriv, REG_CR_8822B, 0); + } + + /* 4. Reset PCIe DMA + * write 0x003 bit[0] = 0 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1, tmp); + + /* 5. Enable PCIe DMA + * write 0x003 bit[0] = 1 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1, tmp); + + if (mac_power_on) { + /* 6. enable TRX function + * write 0x100 = 0xFF + */ + rtl_write_byte(rtlpriv, REG_CR_8822B, 0xFF); + + /* We should init LLT & RQPN and + * prepare Tx/Rx descrptor address later + * because MAC function is reset. + */ + } + + /* 7. Restore PCIe autoload down bit + * write 0xF8 bit[17] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_STATUS2_8822B + 2); + tmp |= BIT(1); + rtl_write_byte(rtlpriv, REG_SYS_STATUS2_8822B + 2, tmp); + + /* In MAC power on state, BB and RF maybe in ON state, + * if we release TRx DMA here + * it will cause packets to be started to Tx/Rx, + * so we release Tx/Rx DMA later. + */ + if (!mac_power_on) { + /* 8. release TRX DMA + * write 0x284 bit[18] = 1'b0 + * write 0x301 = 0x00 + */ + if (release_mac_rx_pause) { + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL_8822B); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL_8822B, + (tmp & (~BIT(2)))); + } + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1, + backup_pcie_dma_pause); + } + + /* 9. lock system register + * write 0xCC bit[2] = 1'b0 + */ + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B); + tmp &= ~(BIT(2)); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B, tmp); +} + +int rtl8822be_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + int err = 0; + u8 tmp_u1b; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, " Rtl8822BE hw init\n"); + rtlpriv->rtlhal.being_init_adapter = true; + rtlpriv->intf_ops->disable_aspm(hw); + + if (_rtl8822be_check_pcie_dma_hang(rtlpriv)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "8822be dma hang!\n"); + _rtl8822be_reset_pcie_interface_dma(rtlpriv, + rtlhal->mac_func_enable); + rtlhal->mac_func_enable = false; + } + + /* init TRX BD */ + _rtl8822be_init_trxbd(hw); + + /* use halmac to init */ + err = rtlpriv->halmac.ops->halmac_init_hal(rtlpriv); + if (err) { + pr_err("halmac_init_hal failed\n"); + rtlhal->fw_ready = false; + return err; + } + + rtlhal->fw_ready = true; + + /* have to init after halmac init */ + tmp_u1b = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 2, (tmp_u1b | BIT(4))); + + /*rtl_write_word(rtlpriv, REG_PCIE_CTRL_8822B, 0x8000);*/ + rtlhal->rx_tag = 0; + + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ_8822B, 0x4); + + /*fw related variable initialize */ + ppsc->fw_current_inpsmode = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8822B; + rtlhal->fw_clk_change_in_progress = false; + rtlhal->allow_sw_to_change_hwclc = false; + rtlhal->last_hmeboxnum = 0; + + rtlphy->rfreg_chnlval[0] = + rtl_get_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = + rtl_get_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->backup_rf_0x1a = (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1, + RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[0] = + (rtlphy->rfreg_chnlval[0] & 0xfffff3ff) | BIT(10) | BIT(11); + + rtlhal->mac_func_enable = true; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv); + + /* reset cam / set security */ + rtl_cam_reset_all_entry(hw); + rtl8822be_enable_hw_security_config(hw); + + /* check RCR/ICV bit */ + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR_8822B, rtlpci->receive_config); + + /* clear rx ctrl frame */ + rtl_write_word(rtlpriv, REG_RXFLTMAP1_8822B, 0); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl8822be_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); + else + rtlpriv->btcoexist.btc_ops->btc_init_hw_config_wifi_only( + rtlpriv); + + rtlpriv->rtlhal.being_init_adapter = false; + + rtlpriv->phydm.ops->phydm_init_dm(rtlpriv); + + /* clear ISR, and IMR will be on later */ + rtl_write_dword(rtlpriv, REG_HISR0_8822B, + rtl_read_dword(rtlpriv, REG_HISR0_8822B)); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8822BE hw init %x\n", + err); + return 0; +} + +static u32 _rtl8822be_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + /*enum version_8822b version = VERSION_UNKNOWN;*/ + u32 version; + u32 value32; + + rtlphy->rf_type = RF_2T2R; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1_8822B); + + version = value32; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl8822be_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + bt_msr &= 0xfc; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + mode = MSR_ADHOC; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state is not cared here. + */ + if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl8822be_stop_tx_beacon(hw); + _rtl8822be_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl8822be_resume_tx_beacon(hw); + _rtl8822be_disable_bcn_sub_func(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + + rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG_8822B + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG_8822B + 1, 0x66); + return 0; +} + +void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + } +} + +int rtl8822be_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl8822be_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP && + type != NL80211_IFTYPE_MESH_POINT) + rtl8822be_set_check_bssid(hw, true); + } else { + rtl8822be_set_check_bssid(hw, false); + } + + return 0; +} + +void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + u32 ac_param; + + ac_param = rtl_get_hal_edca_param(hw, mac->vif, mac->mode, + &mac->edca_param[aci]); + + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM_8822B, ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM_8822B, ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM_8822B, ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM_8822B, ac_param); + break; + default: + WARN_ONCE(true, "invalid aci: %d !\n", aci); + break; + } +} + +void rtl8822be_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR0_8822B, + rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMR1_8822B, + rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMR3_8822B, + rtlpci->irq_mask[3] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl8822be_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR0_8822B, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMR1_8822B, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMR3_8822B, IMR_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +void rtl8822be_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8822be card disable\n"); + + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + + _rtl8822be_set_media_status(hw, opmode); + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + rtlpriv->phydm.ops->phydm_deinit_dm(rtlpriv); + + rtlpriv->halmac.ops->halmac_deinit_hal(rtlpriv); + + /* after power off we should do iqk again */ + if (!rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->phy.iqk_initialized = false; +} + +void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, + u32 *p_intb, u32 *p_intc, u32 *p_intd) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + *p_inta = + rtl_read_dword(rtlpriv, REG_HISR0_8822B) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, REG_HISR0_8822B, *p_inta); + + *p_intb = + rtl_read_dword(rtlpriv, REG_HISR1_8822B) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISR1_8822B, *p_intb); + + *p_intd = + rtl_read_dword(rtlpriv, REG_HISR3_8822B) & rtlpci->irq_mask[3]; + rtl_write_dword(rtlpriv, REG_HISR3_8822B, *p_intd); +} + +void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl8822be_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND_8822B, atim_window); + rtl_write_word(rtlpriv, REG_MBSSID_BCN_SPACE_8822B, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG_8822B, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK_8822B, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM_8822B, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtlpci->reg_bcn_ctrl_val |= BIT(3); + rtl_write_byte(rtlpriv, REG_BCN_CTRL_8822B, + (u8)rtlpci->reg_bcn_ctrl_val); +} + +void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", + bcn_interval); + rtl_write_word(rtlpriv, REG_MBSSID_BCN_SPACE_8822B, bcn_interval); +} + +void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr, + u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl8822be_disable_interrupt(hw); + rtl8822be_enable_interrupt(hw); +} + +static bool _rtl8822be_get_chnl_group(u8 chnl, u8 *group) +{ + bool in_24g; + + if (chnl <= 14) { + in_24g = true; + + if (chnl >= 1 && chnl <= 2) + *group = 0; + else if (chnl >= 3 && chnl <= 5) + *group = 1; + else if (chnl >= 6 && chnl <= 8) + *group = 2; + else if (chnl >= 9 && chnl <= 11) + *group = 3; + else if (chnl >= 12 && chnl <= 14) + *group = 4; + } else { + in_24g = false; + + if (chnl >= 36 && chnl <= 42) + *group = 0; + else if (chnl >= 44 && chnl <= 48) + *group = 1; + else if (chnl >= 50 && chnl <= 58) + *group = 2; + else if (chnl >= 60 && chnl <= 64) + *group = 3; + else if (chnl >= 100 && chnl <= 106) + *group = 4; + else if (chnl >= 108 && chnl <= 114) + *group = 5; + else if (chnl >= 116 && chnl <= 122) + *group = 6; + else if (chnl >= 124 && chnl <= 130) + *group = 7; + else if (chnl >= 132 && chnl <= 138) + *group = 8; + else if (chnl >= 140 && chnl <= 144) + *group = 9; + else if (chnl >= 149 && chnl <= 155) + *group = 10; + else if (chnl >= 157 && chnl <= 161) + *group = 11; + else if (chnl >= 165 && chnl <= 171) + *group = 12; + else if (chnl >= 173 && chnl <= 177) + *group = 13; + } + return in_24g; +} + +static inline bool power_valid(u8 power) +{ + if (power <= 63) + return true; + + return false; +} + +static inline s8 power_diff(s8 diff) +{ + /* bit sign number to 8 bit sign number */ + if (diff & BIT(3)) + diff |= 0xF0; + + return diff; +} + +static void _rtl8822be_read_power_value_fromprom(struct ieee80211_hw *hw, + struct txpower_info_2g *pwr2g, + struct txpower_info_5g *pwr5g, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 rf, addr = EEPROM_TX_PWR_INX_8822B, group, i = 0; + u8 power; + s8 diff; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "hal_ReadPowerValueFromPROM8822B(): PROMContent[0x%x]=0x%x\n", + (addr + 1), hwinfo[addr + 1]); + if (hwinfo[addr + 1] == 0xFF) /*YJ,add,120316*/ + autoload_fail = true; + + memset(pwr2g, 0, sizeof(struct txpower_info_2g)); + memset(pwr5g, 0, sizeof(struct txpower_info_5g)); + + if (autoload_fail) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "auto load fail : Use Default value!\n"); + for (rf = 0; rf < MAX_RF_PATH; rf++) { + /* 2.4G default value */ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + pwr2g->index_cck_base[rf][group] = 0x2D; + pwr2g->index_bw40_base[rf][group] = 0x2D; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr2g->bw20_diff[rf][0] = 0x02; + pwr2g->ofdm_diff[rf][0] = 0x04; + } else { + pwr2g->bw20_diff[rf][i] = 0xFE; + pwr2g->bw40_diff[rf][i] = 0xFE; + pwr2g->cck_diff[rf][i] = 0xFE; + pwr2g->ofdm_diff[rf][i] = 0xFE; + } + } + + /*5G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_5G; group++) + pwr5g->index_bw40_base[rf][group] = 0x2A; + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr5g->ofdm_diff[rf][0] = 0x04; + pwr5g->bw20_diff[rf][0] = 0x00; + pwr5g->bw80_diff[rf][0] = 0xFE; + pwr5g->bw160_diff[rf][0] = 0xFE; + } else { + pwr5g->ofdm_diff[rf][i] = 0xFE; + pwr5g->bw20_diff[rf][i] = 0xFE; + pwr5g->bw40_diff[rf][i] = 0xFE; + pwr5g->bw80_diff[rf][i] = 0xFE; + pwr5g->bw160_diff[rf][i] = 0xFE; + } + } + } + return; + } + + rtl_priv(hw)->efuse.txpwr_fromeprom = true; + + for (rf = 0; rf < 2 /*MAX_RF_PATH*/; rf++) { + /*2.4G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + power = hwinfo[addr++]; + if (power_valid(power)) + pwr2g->index_cck_base[rf][group] = power; + } + for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { + power = hwinfo[addr++]; + if (power_valid(power)) + pwr2g->index_bw40_base[rf][group] = power; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr2g->bw40_diff[rf][i] = 0; + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr2g->bw20_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr2g->ofdm_diff[rf][i] = power_diff(diff); + + pwr2g->cck_diff[rf][i] = 0; + + addr++; + } else { + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr2g->bw40_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr2g->bw20_diff[rf][i] = power_diff(diff); + + addr++; + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr2g->ofdm_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr2g->cck_diff[rf][i] = power_diff(diff); + + addr++; + } + } + + /*5G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_5G; group++) { + power = hwinfo[addr++]; + if (power_valid(power)) + pwr5g->index_bw40_base[rf][group] = power; + } + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr5g->bw40_diff[rf][i] = 0; + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->bw20_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->ofdm_diff[rf][i] = power_diff(diff); + + addr++; + } else { + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->bw40_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->bw20_diff[rf][i] = power_diff(diff); + + addr++; + } + } + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->ofdm_diff[rf][1] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->ofdm_diff[rf][2] = power_diff(diff); + + addr++; + + diff = hwinfo[addr] & 0x0F; + pwr5g->ofdm_diff[rf][3] = power_diff(diff); + + addr++; + + for (i = 0; i < MAX_TX_COUNT; i++) { + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->bw80_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->bw160_diff[rf][i] = power_diff(diff); + + addr++; + } + } +} + +static void _rtl8822be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pwr2g; + struct txpower_info_5g pwr5g; + u8 channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, + 138, 155, 171}; + u8 rf, group; + u8 i; + + _rtl8822be_read_power_value_fromprom(hw, &pwr2g, &pwr5g, autoload_fail, + hwinfo); + + for (rf = 0; rf < MAX_RF_PATH; rf++) { + for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) { + _rtl8822be_get_chnl_group(i + 1, &group); + + if (i == CHANNEL_MAX_NUMBER_2G - 1) { + efu->txpwrlevel_cck[rf][i] = + pwr2g.index_cck_base[rf][5]; + efu->txpwrlevel_ht40_1s[rf][i] = + pwr2g.index_bw40_base[rf][group]; + } else { + efu->txpwrlevel_cck[rf][i] = + pwr2g.index_cck_base[rf][group]; + efu->txpwrlevel_ht40_1s[rf][i] = + pwr2g.index_bw40_base[rf][group]; + } + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) { + _rtl8822be_get_chnl_group(channel5g[i], &group); + efu->txpwr_5g_bw40base[rf][i] = + pwr5g.index_bw40_base[rf][group]; + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) { + u8 upper, lower; + + _rtl8822be_get_chnl_group(channel5g_80m[i], &group); + upper = pwr5g.index_bw40_base[rf][group]; + lower = pwr5g.index_bw40_base[rf][group + 1]; + + efu->txpwr_5g_bw80base[rf][i] = (upper + lower) / 2; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + efu->txpwr_cckdiff[rf][i] = pwr2g.cck_diff[rf][i]; + efu->txpwr_legacyhtdiff[rf][i] = pwr2g.ofdm_diff[rf][i]; + efu->txpwr_ht20diff[rf][i] = pwr2g.bw20_diff[rf][i]; + efu->txpwr_ht40diff[rf][i] = pwr2g.bw40_diff[rf][i]; + + efu->txpwr_5g_ofdmdiff[rf][i] = pwr5g.ofdm_diff[rf][i]; + efu->txpwr_5g_bw20diff[rf][i] = pwr5g.bw20_diff[rf][i]; + efu->txpwr_5g_bw40diff[rf][i] = pwr5g.bw40_diff[rf][i]; + efu->txpwr_5g_bw80diff[rf][i] = pwr5g.bw80_diff[rf][i]; + } + } + + if (!autoload_fail) + efu->eeprom_thermalmeter = hwinfo[EEPROM_THERMAL_METER_8822B]; + else + efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + + if (efu->eeprom_thermalmeter == 0xff || autoload_fail) { + efu->apk_thermalmeterignore = true; + efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + } + + efu->thermalmeter[0] = efu->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "thermalmeter = 0x%x\n", + efu->eeprom_thermalmeter); + + if (!autoload_fail) { + efu->eeprom_regulatory = + hwinfo[EEPROM_RF_BOARD_OPTION_8822B] & 0x07; + if (hwinfo[EEPROM_RF_BOARD_OPTION_8822B] == 0xFF) + efu->eeprom_regulatory = 0; + } else { + efu->eeprom_regulatory = 0; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "eeprom_regulatory = 0x%x\n", + efu->eeprom_regulatory); +} + +static void _rtl8822be_read_pa_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) { + rtlhal->pa_type_2g = hwinfo[EEPROM_2G_5G_PA_TYPE_8822B]; + rtlhal->lna_type_2g = + hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B]; + if (rtlhal->pa_type_2g == 0xFF) + rtlhal->pa_type_2g = 0; + if (rtlhal->lna_type_2g == 0xFF) + rtlhal->lna_type_2g = 0; + + rtlhal->external_pa_2g = (rtlhal->pa_type_2g & BIT(4)) ? 1 : 0; + rtlhal->external_lna_2g = + (rtlhal->lna_type_2g & BIT(3)) ? 1 : 0; + + rtlhal->pa_type_5g = hwinfo[EEPROM_2G_5G_PA_TYPE_8822B]; + rtlhal->lna_type_5g = + hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B]; + if (rtlhal->pa_type_5g == 0xFF) + rtlhal->pa_type_5g = 0; + if (rtlhal->lna_type_5g == 0xFF) + rtlhal->lna_type_5g = 0; + + rtlhal->external_pa_5g = (rtlhal->pa_type_5g & BIT(0)) ? 1 : 0; + rtlhal->external_lna_5g = + (rtlhal->lna_type_5g & BIT(3)) ? 1 : 0; + } else { + rtlhal->external_pa_2g = 0; + rtlhal->external_lna_2g = 0; + rtlhal->external_pa_5g = 0; + rtlhal->external_lna_5g = 0; + } +} + +static void _rtl8822be_read_amplifier_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + u8 ext_type_pa_2g_a = + (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(2)) >> + 2; /* 0xBD[2] */ + u8 ext_type_pa_2g_b = + (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(6)) >> + 6; /* 0xBD[6] */ + u8 ext_type_pa_5g_a = + (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(2)) >> + 2; /* 0xBF[2] */ + u8 ext_type_pa_5g_b = + (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(6)) >> + 6; /* 0xBF[6] */ + u8 ext_type_lna_2g_a = (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(1) | BIT(0))) >> + 0; /* 0xBD[1:0] */ + u8 ext_type_lna_2g_b = (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(5) | BIT(4))) >> + 4; /* 0xBD[5:4] */ + u8 ext_type_lna_5g_a = (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(1) | BIT(0))) >> + 0; /* 0xBF[1:0] */ + u8 ext_type_lna_5g_b = (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(5) | BIT(4))) >> + 4; /* 0xBF[5:4] */ + + _rtl8822be_read_pa_type(hw, hwinfo, autoload_fail); + + /* [2.4G] Path A and B are both extPA */ + if ((rtlhal->pa_type_2g & (BIT(5) | BIT(4))) == (BIT(5) | BIT(4))) + rtlhal->type_gpa = ext_type_pa_2g_b << 2 | ext_type_pa_2g_a; + + /* [5G] Path A and B are both extPA */ + if ((rtlhal->pa_type_5g & (BIT(1) | BIT(0))) == (BIT(1) | BIT(0))) + rtlhal->type_apa = ext_type_pa_5g_b << 2 | ext_type_pa_5g_a; + + /* [2.4G] Path A and B are both extLNA */ + if ((rtlhal->lna_type_2g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3))) + rtlhal->type_glna = ext_type_lna_2g_b << 2 | ext_type_lna_2g_a; + + /* [5G] Path A and B are both extLNA */ + if ((rtlhal->lna_type_5g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3))) + rtlhal->type_alna = ext_type_lna_5g_b << 2 | ext_type_lna_5g_a; +} + +static void _rtl8822be_read_rfe_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) + rtlhal->rfe_type = hwinfo[EEPROM_RFE_OPTION_8822B]; + else + rtlhal->rfe_type = 0; + + if (rtlhal->rfe_type == 0xFF) + rtlhal->rfe_type = 0; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RFE Type: 0x%2x\n", + rtlhal->rfe_type); +} + +static void _rtl8822be_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_halmac_ops *halmac_ops = rtlpriv->halmac.ops; + u16 i, usvalue; + u8 *hwinfo; + u16 eeprom_id; + u32 efuse_size; + int err; + + if (rtlefuse->epromtype != EEPROM_BOOT_EFUSE) { + pr_err("RTL8822B Not boot from efuse!!"); + return; + } + + /* read logical efuse size (normalely, 0x0300) */ + err = halmac_ops->halmac_get_logical_efuse_size(rtlpriv, &efuse_size); + + if (err || !efuse_size) { + pr_err("halmac_get_logical_efuse_size err=%d efuse_size=0x%X", + err, efuse_size); + efuse_size = HWSET_MAX_SIZE; + } + + if (efuse_size > HWSET_MAX_SIZE) { + pr_err("halmac_get_logical_efuse_size efuse_size=0x%X > 0x%X", + efuse_size, HWSET_MAX_SIZE); + efuse_size = HWSET_MAX_SIZE; + } + + /* read efuse */ + hwinfo = kzalloc(efuse_size, GFP_KERNEL); + + err = halmac_ops->halmac_read_logical_efuse_map(rtlpriv, hwinfo, + efuse_size); + if (err) { + pr_err("%s: fail to get efuse map!\n", __func__); + goto label_end; + } + + /* copy to efuse_map (need?) */ + memcpy(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], hwinfo, + EFUSE_MAX_LOGICAL_SIZE); + memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], hwinfo, + EFUSE_MAX_LOGICAL_SIZE); + + /* parse content */ + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n", hwinfo, + HWSET_MAX_SIZE); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8822B_EEPROM_ID) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtlefuse->autoload_failflag = true; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + } + + if (rtlefuse->autoload_failflag) + goto label_end; + + /*VID DID SVID SDID*/ + rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; + rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; + rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; + rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM VID = 0x%4x\n", + rtlefuse->eeprom_vid); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM DID = 0x%4x\n", + rtlefuse->eeprom_did); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SVID = 0x%4x\n", + rtlefuse->eeprom_svid); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SMID = 0x%4x\n", + rtlefuse->eeprom_smid); + /*customer ID*/ + rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOM_ID_8822B]; + if (rtlefuse->eeprom_oemid == 0xFF) + rtlefuse->eeprom_oemid = 0; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); + /*EEPROM version*/ + rtlefuse->eeprom_version = *(u8 *)&hwinfo[EEPROM_VERSION_8822B]; + /*mac address*/ + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_8822BE + i]; + *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n", + rtlefuse->dev_addr); + + /* channel plan */ + rtlefuse->eeprom_channelplan = + *(u8 *)&hwinfo[EEPROM_CHANNEL_PLAN_8822B]; + + /* set channel plan from efuse */ + rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; + if (rtlefuse->channel_plan == 0xFF) + rtlefuse->channel_plan = 0x7f; /* use 2G + 5G as default */ + + /*tx power*/ + _rtl8822be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + rtl8822be_read_bt_coexist_info_from_hwpg( + hw, rtlefuse->autoload_failflag, hwinfo); + + /*amplifier type*/ + _rtl8822be_read_amplifier_type(hw, hwinfo, rtlefuse->autoload_failflag); + + /*rfe type*/ + _rtl8822be_read_rfe_type(hw, hwinfo, rtlefuse->autoload_failflag); + + /*board type*/ + rtlefuse->board_type = + (((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_8822B]) & 0xE0) >> 5); + if ((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_8822B]) == 0xFF) + rtlefuse->board_type = 0; + + if (rtlpriv->btcoexist.btc_info.btcoexist == 1) + rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */ + + /* phydm maintain rtlhal->board_type and rtlhal->package_type */ + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "board_type = 0x%x\n", + rtlefuse->board_type); + /*parse xtal*/ + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8822B]; + if (hwinfo[EEPROM_XTAL_8822B] == 0xFF) + rtlefuse->crystalcap = 0; /*0x20;*/ + + /*antenna diversity*/ + rtlefuse->antenna_div_type = 0; + rtlefuse->antenna_div_cfg = 0; + +label_end: + kfree(hwinfo); +} + +static void _rtl8822be_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + pcipriv->ledctl.led_opendrain = true; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); +} + +static void _rtl8822be_read_pa_bias(struct ieee80211_hw *hw, + struct rtl_phydm_params *params) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_halmac_ops *halmac_ops = rtlpriv->halmac.ops; + u32 size; + u8 *map = NULL; + + /* fill default values */ + params->efuse0x3d7 = 0xFF; + params->efuse0x3d8 = 0xFF; + + if (halmac_ops->halmac_get_physical_efuse_size(rtlpriv, &size)) + goto err; + + map = kmalloc(size, GFP_KERNEL); + if (!map) + goto err; + + if (halmac_ops->halmac_read_physical_efuse_map(rtlpriv, map, size)) + goto err; + + params->efuse0x3d7 = map[0x3d7]; + params->efuse0x3d8 = map[0x3d8]; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "efuse0x3d7 = 0x%2x, efuse0x3d8 = 0x%2x\n", + params->efuse0x3d7, params->efuse0x3d8); + +err: + kfree(map); +} + +void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw, + struct rtl_phydm_params *params) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl8822be_read_chip_version(hw); + + params->mp_chip = (rtlhal->version & BIT_RTL_ID_8822B) ? 0 : 1; + params->fab_ver = BIT_GET_VENDOR_ID_8822B(rtlhal->version) >> 2; + params->cut_ver = BIT_GET_CHIP_VER_8822B(rtlhal->version); + + /* fab_ver mapping */ + if (params->fab_ver == 2) + params->fab_ver = 1; + else if (params->fab_ver == 1) + params->fab_ver = 2; + + /* read PA bias: params->efuse0x3d7/efuse0x3d8 */ + _rtl8822be_read_pa_bias(hw, params); + + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_EEPROM_CTRL_8822B); + if (tmp_u1b & BIT(4)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl8822be_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + } + _rtl8822be_hal_customized_behavior(hw); + + rtlphy->rfpath_rx_enable[0] = true; + if (rtlphy->rf_type == RF_2T2R) + rtlphy->rfpath_rx_enable[1] = true; +} + +void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw) +{ + /* + * 8822b use halmac, so + * move rtl8822be_read_eeprom_info() to rtl8822be_init_sw_vars() + * after halmac_init_adapter(). + */ +} + +static u32 _rtl8822be_rate_to_bitmap_2ssvht(__le16 vht_rate) +{ + u8 i, j, tmp_rate; + u32 rate_bitmap = 0; + + for (i = j = 0; i < 4; i += 2, j += 10) { + tmp_rate = (le16_to_cpu(vht_rate) >> i) & 3; + + switch (tmp_rate) { + case 2: + rate_bitmap = rate_bitmap | (0x03ff << j); + break; + + case 1: + rate_bitmap = rate_bitmap | (0x01ff << j); + break; + + case 0: + rate_bitmap = rate_bitmap | (0x00ff << j); + break; + + default: + break; + } + } + + return rate_bitmap; +} + +static u8 _rtl8822be_get_vht_en(enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + u8 ret = 0; + + if (wirelessmode < WIRELESS_MODE_N_24G) { + ret = 0; + } else if (wirelessmode == WIRELESS_MODE_AC_24G) { + if (ratr_bitmap & 0xfff00000) /* Mix , 2SS */ + ret = 3; + else /* Mix, 1SS */ + ret = 2; + } else if (wirelessmode == WIRELESS_MODE_AC_5G) { + ret = 1; + } /* VHT */ + + return ret << 4; +} + +static u8 _rtl8822be_get_ra_ldpc(struct ieee80211_hw *hw, u8 mac_id, + struct rtl_sta_info *sta_entry, + enum wireless_mode wirelessmode) +{ + u8 b_ldpc = 0; + /*not support ldpc, do not open*/ + return b_ldpc << 2; +} + +static u8 _rtl8822be_get_ra_rftype(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rf_type = RF_1T1R; + + if (rtlphy->rf_type == RF_1T1R) { + rf_type = RF_1T1R; + } else if (wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_AC_24G || + wirelessmode == WIRELESS_MODE_AC_ONLY) { + if (ratr_bitmap & 0xffc00000) + rf_type = RF_2T2R; + } else if (wirelessmode == WIRELESS_MODE_N_5G || + wirelessmode == WIRELESS_MODE_N_24G) { + if (ratr_bitmap & 0xfff00000) + rf_type = RF_2T2R; + } + + return rf_type; +} + +static bool _rtl8822be_get_ra_shortgi(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 mac_id) +{ + bool b_short_gi = false; + u8 b_curshortgi_40mhz = + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; + u8 b_curshortgi_20mhz = + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; + u8 b_curshortgi_80mhz = 0; + + b_curshortgi_80mhz = + (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) ? 1 : 0; + + if (mac_id == 99 /*MAC_ID_STATIC_FOR_BROADCAST_MULTICAST*/) + b_short_gi = false; + + if (b_curshortgi_40mhz || b_curshortgi_80mhz || b_curshortgi_20mhz) + b_short_gi = true; + + return b_short_gi; +} + +static void rtl8822be_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap, ratr_bitmap_msb = 0; + u8 ratr_index; + enum wireless_mode wirelessmode = 0; + u8 curtxbw_40mhz = + (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; + bool b_shortgi = false; + u8 rate_mask[7]; + u8 macid = 0; + u8 rf_type; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + + RT_TRACE(rtlpriv, COMP_RATR, DBG_LOUD, "wireless mode = 0x%x\n", + wirelessmode); + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + curtxbw_40mhz = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + if (wirelessmode == WIRELESS_MODE_N_5G || + wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_A) + ratr_bitmap = (sta->supp_rates[NL80211_BAND_5GHZ]) << 4; + else + ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ]; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + + if (wirelessmode == WIRELESS_MODE_N_24G || + wirelessmode == WIRELESS_MODE_N_5G) + ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | + sta->ht_cap.mcs.rx_mask[0] << 12); + else if (wirelessmode == WIRELESS_MODE_AC_24G || + wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_AC_ONLY) + ratr_bitmap |= _rtl8822be_rate_to_bitmap_2ssvht( + sta->vht_cap.vht_mcs.rx_mcs_map) + << 12; + + b_shortgi = _rtl8822be_get_ra_shortgi(hw, sta, macid); + rf_type = _rtl8822be_get_ra_rftype(hw, wirelessmode, ratr_bitmap); + + ratr_index = rtlpriv->phydm.ops->phydm_rate_id_mapping( + rtlpriv, wirelessmode, rf_type, rtlphy->current_chan_bw); + sta_entry->ratr_index = ratr_index; + + rtlpriv->phydm.ops->phydm_get_ra_bitmap( + rtlpriv, wirelessmode, rf_type, rtlphy->current_chan_bw, + rssi_level, &ratr_bitmap_msb, &ratr_bitmap); + + RT_TRACE(rtlpriv, COMP_RATR, DBG_LOUD, "ratr_bitmap :%x\n", + ratr_bitmap); + + rate_mask[0] = macid; + rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00); + rate_mask[2] = + rtlphy->current_chan_bw | ((!update_bw) << 3) | + _rtl8822be_get_vht_en(wirelessmode, ratr_bitmap) | + _rtl8822be_get_ra_ldpc(hw, macid, sta_entry, wirelessmode); + + rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); + rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); + rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); + rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); + + RT_TRACE( + rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%08x, %02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], rate_mask[4], rate_mask[5], + rate_mask[6]); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MACID_CFG, 7, rate_mask); + + /* for h2c cmd 0x46, only modify cmd id & ra mask */ + /* Keep rate_mask0~2 of cmd 0x40, but clear byte3 and later */ + /* 8822B has no 3SS, so keep it zeros. */ + memset(rate_mask + 3, 0, 4); + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MACID_CFG_3SS, 7, rate_mask); + + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl8822be_update_hal_rate_mask(hw, sta, rssi_level, update_bw); +} + +void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + *valid = 1; + return true; +} + +void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, + bool is_group, u8 enc_algo, bool is_wepkey, + bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, + }; + static u8 cam_const_broad[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + return; + } + + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = + rtl_cam_get_free_entry(hw, p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hwsecurity cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "add one entry\n"); + if (is_pairwise) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry( + hw, rtlefuse->dev_addr, PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } +} + +void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + u32 val32; + + val32 = rtl_read_dword(rtlpriv, REG_WL_BT_PWR_CTRL_8822B); + if (val32 & BIT_BT_FUNC_EN_8822B) + rtlpriv->btcoexist.btc_info.btcoexist = 1; + else + rtlpriv->btcoexist.btc_info.btcoexist = 0; + + if (!auto_load_fail) { + value = hwinfo[EEPROM_RF_BT_SETTING_8822B]; + + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8822B; + rtlpriv->btcoexist.btc_info.ant_num = + (value & BIT(0) ? ANT_TOTAL_X1 : ANT_TOTAL_X2); + } else { + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8822B; + rtlpriv->btcoexist.btc_info.ant_num = ANT_TOTAL_X2; + } +} + +void rtl8822be_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8822be_suspend(struct ieee80211_hw *hw) {} + +void rtl8822be_resume(struct ieee80211_hw *hw) {} diff --git a/drivers/staging/rtlwifi/rtl8822be/hw.h b/drivers/staging/rtlwifi/rtl8822be/hw.h new file mode 100644 index 0000000000000000000000000000000000000000..a91c276c57949e6e13741020ffb640b15ed6c391 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/hw.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_HW_H__ +#define __RTL8822B_HW_H__ + +extern u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G]; +extern u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M]; + +void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw, + struct rtl_phydm_params *params); +void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw); +void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, + u32 *p_intb, u32 *p_intc, u32 *p_intd); +int rtl8822be_hw_init(struct ieee80211_hw *hw); +void rtl8822be_card_disable(struct ieee80211_hw *hw); +void rtl8822be_enable_interrupt(struct ieee80211_hw *hw); +void rtl8822be_disable_interrupt(struct ieee80211_hw *hw); +int rtl8822be_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type); +void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci); +void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw); +void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr, + u32 rm_msr); +void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw); +void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, + bool is_group, u8 enc_algo, bool is_wepkey, + bool clear_all); +void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl8822be_bt_reg_init(struct ieee80211_hw *hw); +void rtl8822be_suspend(struct ieee80211_hw *hw); +void rtl8822be_resume(struct ieee80211_hw *hw); +void rtl8822be_fw_clk_off_timer_callback(unsigned long data); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/led.c b/drivers/staging/rtlwifi/rtl8822be/led.c new file mode 100644 index 0000000000000000000000000000000000000000..f4b5af8ab1165d50bf24e5e7f11e893b986fd54c --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/led.c @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +static void _rtl8822be_init_led(struct ieee80211_hw *hw, struct rtl_led *pled, + enum rtl_led_pin ledpin) +{ + pled->hw = hw; + pled->ledpin = ledpin; + pled->ledon = false; +} + +void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2_8822B, pled->ledpin); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + break; + case LED_PIN_LED1: + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + pled->ledon = true; +} + +void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2_8822B, pled->ledpin); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + break; + case LED_PIN_LED1: + + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + pled->ledon = false; +} + +void rtl8822be_init_sw_leds(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + + _rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led0, LED_PIN_LED0); + _rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led1, LED_PIN_LED1); +} + +static void _rtl8822be_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_led *led0 = &pcipriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl8822be_sw_led_on(hw, led0); + break; + case LED_CTL_POWER_OFF: + rtl8822be_sw_led_off(hw, led0); + break; + default: + break; + } +} + +void rtl8822be_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + RT_TRACE(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n", ledaction); + _rtl8822be_sw_led_control(hw, ledaction); +} diff --git a/drivers/staging/rtlwifi/rtl8822be/led.h b/drivers/staging/rtlwifi/rtl8822be/led.h new file mode 100644 index 0000000000000000000000000000000000000000..9c0a2290df7d90af0c3f087ec751b78f0a301b07 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/led.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_LED_H__ +#define __RTL8822B_LED_H__ + +void rtl8822be_init_sw_leds(struct ieee80211_hw *hw); +void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl8822be_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/phy.c b/drivers/staging/rtlwifi/rtl8822be/phy.c new file mode 100644 index 0000000000000000000000000000000000000000..4cba2adc3165fa4c3f10051154b98c36fd80b608 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/phy.c @@ -0,0 +1,2233 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "../btcoexist/halbt_precomp.h" +#include "hw.h" +#include "../efuse.h" + +static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask); +static void +_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); + +static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl8822be_phy_set_io(struct ieee80211_hw *hw); + +static u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M}; +static u8 sizes_of_cck_retes = 4; +static u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, + DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, + DESC_RATE48M, DESC_RATE54M}; +static u8 sizes_of_ofdm_retes = 8; +static u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, + DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, + DESC_RATEMCS6, DESC_RATEMCS7}; +static u8 sizes_of_ht_retes_1t = 8; +static u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, + DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, + DESC_RATEMCS14, DESC_RATEMCS15}; +static u8 sizes_of_ht_retes_2t = 8; +static u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, + DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, + DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, + DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, + DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9}; +static u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, + DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, + DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, + DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, + DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9}; +static u8 sizes_of_vht_retes = 10; + +u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + + return returnvalue; +} + +void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask, + data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | + ((data << bitshift) & bitmask)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask, + data); +} + +u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 /*original_value,*/ readback_value /*, bitshift*/; + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath, + bitmask); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + readback_value = rtlpriv->phydm.ops->phydm_read_rf_reg( + rtlpriv, rfpath, regaddr, bitmask); + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + return readback_value; +} + +void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + rtlpriv->phydm.ops->phydm_write_rf_reg(rtlpriv, rfpath, regaddr, + bitmask, data); + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} + +static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((bitmask >> i) & 0x1) == 1) + break; + } + return i; +} + +bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv) +{ + return rtlpriv->phydm.ops->phydm_phy_mac_config(rtlpriv); +} + +bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 crystal_cap; + /* u32 tmp; */ + + rtstatus = rtlpriv->phydm.ops->phydm_phy_bb_config(rtlpriv); + + /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */ + crystal_cap = rtlefuse->crystalcap & 0x3F; + rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL_8822B, 0x7E000000, crystal_cap); + rtl_set_bbreg(hw, REG_AFE_PLL_CTRL_8822B, 0x7E, crystal_cap); + + /*rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);*/ /*unused*/ + + return rtstatus; +} + +bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return rtlpriv->phydm.ops->phydm_phy_rf_config(rtlpriv); +} + +bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv) +{ + struct ieee80211_hw *hw = rtlpriv->hw; + enum radio_mask txpath, rxpath; + bool tx2path; + bool ret = false; + + _rtl8822be_phy_init_bb_rf_register_definition(hw); + + rtlpriv->halmac.ops->halmac_phy_power_switch(rtlpriv, 1); + + /* beofre bb/rf config */ + rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 0); + + /* do bb/rf config */ + if (rtl8822be_phy_bb_config(hw) && rtl8822be_phy_rf_config(hw)) + ret = true; + + /* after bb/rf config */ + rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 1); + + /* set trx mode (keep it to be last, r17376) */ + txpath = RF_MASK_A | RF_MASK_B; + rxpath = RF_MASK_A | RF_MASK_B; + tx2path = false; + ret = rtlpriv->phydm.ops->phydm_trx_mode(rtlpriv, txpath, rxpath, + tx2path); + + return ret; +} + +static void _rtl8822be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 band, rfpath, txnum, rate; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) + for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath) + for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) + for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; + ++rate) + rtlphy->tx_power_by_rate_offset + [band][rfpath][txnum][rate] = 0; +} + +static void _rtl8822be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, + u8 rate_section, u8 txnum, + u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (path > RF90_PATH_D) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", + path); + return; + } + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid band %d in phy_SetTxPowerByRatBase()\n", + band); + return; + } + + if (rate_section >= MAX_RATE_SECTION || + (band == BAND_ON_5G && rate_section == CCK)) { + RT_TRACE( + rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid rate_section %d in phy_SetTxPowerByRatBase()\n", + rate_section); + return; + } + + if (band == BAND_ON_2_4G) + rtlphy->txpwr_by_rate_base_24g[path][txnum][rate_section] = + value; + else /* BAND_ON_5G */ + rtlphy->txpwr_by_rate_base_5g[path][txnum][rate_section - 1] = + value; +} + +static u8 _rtl8822be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, u8 txnum, + u8 rate_section) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 value; + + if (path > RF90_PATH_D) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in phy_GetTxPowerByRatBase()\n", + path); + return 0; + } + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid band %d in phy_GetTxPowerByRatBase()\n", + band); + return 0; + } + + if (rate_section >= MAX_RATE_SECTION || + (band == BAND_ON_5G && rate_section == CCK)) { + RT_TRACE( + rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid rate_section %d in phy_GetTxPowerByRatBase()\n", + rate_section); + return 0; + } + + if (band == BAND_ON_2_4G) + value = rtlphy->txpwr_by_rate_base_24g[path][txnum] + [rate_section]; + else /* BAND_ON_5G */ + value = rtlphy->txpwr_by_rate_base_5g[path][txnum] + [rate_section - 1]; + + return value; +} + +static void _rtl8822be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + struct { + enum rtl_desc_rate rate; + enum rate_section section; + } rate_sec_base[] = { + {DESC_RATE11M, CCK}, + {DESC_RATE54M, OFDM}, + {DESC_RATEMCS7, HT_MCS0_MCS7}, + {DESC_RATEMCS15, HT_MCS8_MCS15}, + {DESC_RATEVHT1SS_MCS7, VHT_1SSMCS0_1SSMCS9}, + {DESC_RATEVHT2SS_MCS7, VHT_2SSMCS0_2SSMCS9}, + }; + + u8 band, path, rs, tx_num, base; + u8 rate, section; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + for (path = RF90_PATH_A; path <= RF90_PATH_B; path++) { + for (rs = 0; rs < MAX_RATE_SECTION; rs++) { + rate = rate_sec_base[rs].rate; + section = rate_sec_base[rs].section; + + if (IS_1T_RATE(rate)) + tx_num = RF_1TX; + else + tx_num = RF_2TX; + + if (band == BAND_ON_5G && + RX_HAL_IS_CCK_RATE(rate)) + continue; + + base = rtlphy->tx_power_by_rate_offset + [band][path][tx_num][rate]; + _rtl8822be_phy_set_txpower_by_rate_base( + hw, band, path, section, tx_num, base); + } + } + } +} + +static void __rtl8822be_phy_cross_reference_core(struct ieee80211_hw *hw, + u8 regulation, u8 bw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rs, ref_rs; + s8 pwrlmt, ref_pwrlmt; + + for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) { + /*5G 20M 40M VHT and HT can cross reference*/ + if (bw != HT_CHANNEL_WIDTH_20 && bw != HT_CHANNEL_WIDTH_20_40) + continue; + + if (rs == HT_MCS0_MCS7) + ref_rs = VHT_1SSMCS0_1SSMCS9; + else if (rs == HT_MCS8_MCS15) + ref_rs = VHT_2SSMCS0_2SSMCS9; + else if (rs == VHT_1SSMCS0_1SSMCS9) + ref_rs = HT_MCS0_MCS7; + else if (rs == VHT_2SSMCS0_2SSMCS9) + ref_rs = HT_MCS8_MCS15; + else + continue; + + ref_pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][ref_rs] + [channel][RF90_PATH_A]; + if (ref_pwrlmt == MAX_POWER_INDEX) + continue; + + pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][rs][channel] + [RF90_PATH_A]; + if (pwrlmt != MAX_POWER_INDEX) + continue; + + rtlphy->txpwr_limit_5g[regulation][bw][rs][channel] + [RF90_PATH_A] = ref_pwrlmt; + } +} + +static void +_rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw) +{ + u8 regulation, bw, channel; + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; + ++channel) { + __rtl8822be_phy_cross_reference_core( + hw, regulation, bw, channel); + } + } + } +} + +static void __rtl8822be_txpwr_limit_to_index_2g(struct ieee80211_hw *hw, + u8 regulation, u8 bw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw40_pwr_base_dbm2_4G; + u8 rate_section; + s8 temp_pwrlmt; + enum rf_tx_num txnum; + s8 temp_value; + u8 rf_path; + + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; + ++rate_section) { + /* obtain the base dBm values in 2.4G band + * CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15 + */ + + temp_pwrlmt = + rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section] + [channel][RF90_PATH_A]; + txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX; + + if (temp_pwrlmt == MAX_POWER_INDEX) + continue; + + for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM; + ++rf_path) { + bw40_pwr_base_dbm2_4G = + _rtl8822be_phy_get_txpower_by_rate_base( + hw, BAND_ON_2_4G, rf_path, txnum, + rate_section); + + temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G; + rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section] + [channel][rf_path] = temp_value; + + RT_TRACE( + rtlpriv, COMP_INIT, DBG_TRACE, + "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n", + regulation, bw, rate_section, channel, + rtlphy->txpwr_limit_2_4g[regulation][bw] + [rate_section][channel] + [rf_path], + (temp_pwrlmt == 63) ? 0 : temp_pwrlmt / 2, + channel, rf_path, bw40_pwr_base_dbm2_4G); + } + } +} + +static void __rtl8822be_txpwr_limit_to_index_5g(struct ieee80211_hw *hw, + u8 regulation, u8 bw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw40_pwr_base_dbm5G; + u8 rate_section; + s8 temp_pwrlmt; + enum rf_tx_num txnum; + s8 temp_value; + u8 rf_path; + + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; + ++rate_section) { + /* obtain the base dBm values in 5G band + * OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15, + * VHT => 1SSMCS7, VHT 2T => 2SSMCS7 + */ + + temp_pwrlmt = + rtlphy->txpwr_limit_5g[regulation][bw][rate_section] + [channel][RF90_PATH_A]; + txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX; + + if (temp_pwrlmt == MAX_POWER_INDEX) + continue; + + for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM; + ++rf_path) { + bw40_pwr_base_dbm5G = + _rtl8822be_phy_get_txpower_by_rate_base( + hw, BAND_ON_5G, rf_path, txnum, + rate_section); + + temp_value = temp_pwrlmt - bw40_pwr_base_dbm5G; + rtlphy->txpwr_limit_5g[regulation][bw][rate_section] + [channel][rf_path] = temp_value; + + RT_TRACE( + rtlpriv, COMP_INIT, DBG_TRACE, + "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n", + regulation, bw, rate_section, channel, + rtlphy->txpwr_limit_5g[regulation][bw] + [rate_section][channel] + [rf_path], + temp_pwrlmt, channel, rf_path, + bw40_pwr_base_dbm5G); + } + } +} + +static void +_rtl8822be_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 regulation, bw, channel; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "=====> %s()\n", __func__); + + _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(hw); + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; + ++channel) { + __rtl8822be_txpwr_limit_to_index_2g( + hw, regulation, bw, channel); + } + } + } + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; + ++channel) { + __rtl8822be_txpwr_limit_to_index_5g( + hw, regulation, bw, channel); + } + } + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<===== %s()\n", __func__); +} + +static void _rtl8822be_phy_init_txpower_limit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i, j, k, l, m; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "=====> %s()!\n", __func__); + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m) + for (l = 0; l < MAX_RF_PATH_NUM; ++l) + rtlphy->txpwr_limit_2_4g[i][j] + [k][m] + [l] = + MAX_POWER_INDEX; + } + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m) + for (l = 0; l < MAX_RF_PATH_NUM; ++l) + rtlphy->txpwr_limit_5g[i][j][k] + [m][l] = + MAX_POWER_INDEX; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<===== %s()!\n", __func__); +} + +static void +_rtl8822be_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 base = 0, i = 0, value = 0, band = 0, path = 0, txnum = 0; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) { + for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { + for (txnum = RF_1TX; txnum <= RF_2TX; ++txnum) { + /* CCK */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATE11M]; + for (i = 0; i < sizeof(cck_rates); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [cck_rates[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [cck_rates[i]] = value - base; + } + + /* OFDM */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATE54M]; + for (i = 0; i < sizeof(ofdm_rates); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ofdm_rates[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ofdm_rates[i]] = value - base; + } + + /* HT MCS0~7 */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEMCS7]; + for (i = 0; i < sizeof(ht_rates_1t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_1t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_1t[i]] = value - base; + } + + /* HT MCS8~15 */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEMCS15]; + for (i = 0; i < sizeof(ht_rates_2t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_2t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_2t[i]] = value - base; + } + + /* VHT 1SS */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEVHT1SS_MCS7]; + for (i = 0; i < sizeof(vht_rates_1t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_1t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_1t[i]] = + value - base; + } + + /* VHT 2SS */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEVHT2SS_MCS7]; + for (i = 0; i < sizeof(vht_rates_2t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_2t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_2t[i]] = + value - base; + } + } + } + } + + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "<===%s()\n", __func__); +} + +static void +_rtl8822be_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) +{ + /* copy rate_section from + * tx_power_by_rate_offset[][rate] to txpwr_by_rate_base_24g/_5g[][rs] + */ + _rtl8822be_phy_store_txpower_by_rate_base(hw); + + /* convert tx_power_by_rate_offset[] to relative value */ + _rtl8822be_phy_convert_txpower_dbm_to_relative_value(hw); +} + +/* string is in decimal */ +static bool _rtl8822be_get_integer_from_string(char *str, u8 *pint) +{ + u16 i = 0; + *pint = 0; + + while (str[i] != '\0') { + if (str[i] >= '0' && str[i] <= '9') { + *pint *= 10; + *pint += (str[i] - '0'); + } else { + return false; + } + ++i; + } + + return true; +} + +static bool _rtl8822be_eq_n_byte(u8 *str1, u8 *str2, u32 num) +{ + if (num == 0) + return false; + while (num > 0) { + num--; + if (str1[num] != str2[num]) + return false; + } + return true; +} + +static char _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, + u8 band, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + char channel_index = -1; + u8 i = 0; + + if (band == BAND_ON_2_4G) { + channel_index = channel - 1; + } else if (band == BAND_ON_5G) { + for (i = 0; i < sizeof(rtl_channel5g) / sizeof(u8); ++i) { + if (rtl_channel5g[i] == channel) + channel_index = i; + } + } else { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s", + band, __func__); + } + + if (channel_index == -1) + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Channel %d of Band %d in %s", channel, band, + __func__); + + return channel_index; +} + +void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, + u8 *pband, u8 *pbandwidth, + u8 *prate_section, u8 *prf_path, + u8 *pchannel, u8 *ppower_limit) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 regulation = 0, bandwidth = 0, rate_section = 0, channel; + u8 channel_index; + char power_limit = 0, prev_power_limit, ret; + + if (!_rtl8822be_get_integer_from_string((char *)pchannel, &channel) || + !_rtl8822be_get_integer_from_string((char *)ppower_limit, + &power_limit)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Illegal index of pwr_lmt table [chnl %d][val %d]\n", + channel, power_limit); + } + + power_limit = + power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit; + + if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("FCC"), 3)) + regulation = 0; + else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("MKK"), 3)) + regulation = 1; + else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("ETSI"), 4)) + regulation = 2; + else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("WW13"), 4)) + regulation = 3; + + if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("CCK"), 3)) + rate_section = CCK; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("OFDM"), 4)) + rate_section = OFDM; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + rate_section = HT_MCS0_MCS7; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + rate_section = HT_MCS8_MCS15; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + rate_section = VHT_1SSMCS0_1SSMCS9; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + rate_section = VHT_2SSMCS0_2SSMCS9; + + if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("20M"), 3)) + bandwidth = HT_CHANNEL_WIDTH_20; + else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("40M"), 3)) + bandwidth = HT_CHANNEL_WIDTH_20_40; + else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("80M"), 3)) + bandwidth = HT_CHANNEL_WIDTH_80; + else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("160M"), 4)) + bandwidth = 3; + + if (_rtl8822be_eq_n_byte(pband, (u8 *)("2.4G"), 4)) { + ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G, + channel); + + if (ret == -1) + return; + + channel_index = ret; + + prev_power_limit = + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]; + + if (power_limit < prev_power_limit) + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A] = power_limit; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n", + regulation, bandwidth, rate_section, channel_index, + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]); + } else if (_rtl8822be_eq_n_byte(pband, (u8 *)("5G"), 2)) { + ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G, + channel); + + if (ret == -1) + return; + + channel_index = ret; + + prev_power_limit = + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]; + + if (power_limit < prev_power_limit) + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A] = power_limit; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n", + regulation, bandwidth, rate_section, channel, + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]); + + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Cannot recognize the band info in %s\n", pband); + return; + } +} + +bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool rtstatus = true; + + _rtl8822be_phy_init_tx_power_by_rate(hw); + + rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_by_rate(rtlpriv); + + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!"); + return false; + } + + _rtl8822be_phy_txpower_by_rate_configuration(hw); + + return true; +} + +bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + bool rtstatus = true; + + _rtl8822be_phy_init_txpower_limit(hw); + + if (rtlefuse->eeprom_regulatory == 1) + ; + else + return true; + + rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_limit(rtlpriv); + + if (!rtstatus) { + pr_err("RF TxPwr Limit Fail!!"); + return false; + } + + _rtl8822be_phy_convert_txpower_limit_to_power_index(hw); + + return true; +} + +static void _rtl8822be_get_rate_values_of_tx_power_by_rate( + struct ieee80211_hw *hw, u32 reg_addr, u32 bit_mask, u32 value, + u8 *rate, s8 *pwr_by_rate_val, u8 *rate_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 /*index = 0,*/ i = 0; + + switch (reg_addr) { + case 0xE00: /*rTxAGC_A_Rate18_06:*/ + case 0x830: /*rTxAGC_B_Rate18_06:*/ + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE04: /*rTxAGC_A_Rate54_24:*/ + case 0x834: /*rTxAGC_B_Rate54_24:*/ + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE08: /*rTxAGC_A_CCK1_Mcs32:*/ + rate[0] = DESC_RATE1M; + pwr_by_rate_val[0] = (s8)((((value >> (8 + 4)) & 0xF)) * 10 + + ((value >> 8) & 0xF)); + *rate_num = 1; + break; + + case 0x86C: /*rTxAGC_B_CCK11_A_CCK2_11:*/ + if (bit_mask == 0xffffff00) { + rate[0] = DESC_RATE2M; + rate[1] = DESC_RATE5_5M; + rate[2] = DESC_RATE11M; + for (i = 1; i < 4; ++i) { + pwr_by_rate_val[i - 1] = (s8)( + (((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 3; + } else if (bit_mask == 0x000000ff) { + rate[0] = DESC_RATE11M; + pwr_by_rate_val[0] = (s8)((((value >> 4) & 0xF)) * 10 + + (value & 0xF)); + *rate_num = 1; + } + break; + + case 0xE10: /*rTxAGC_A_Mcs03_Mcs00:*/ + case 0x83C: /*rTxAGC_B_Mcs03_Mcs00:*/ + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE14: /*rTxAGC_A_Mcs07_Mcs04:*/ + case 0x848: /*rTxAGC_B_Mcs07_Mcs04:*/ + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE18: /*rTxAGC_A_Mcs11_Mcs08:*/ + case 0x84C: /*rTxAGC_B_Mcs11_Mcs08:*/ + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE1C: /*rTxAGC_A_Mcs15_Mcs12:*/ + case 0x868: /*rTxAGC_B_Mcs15_Mcs12:*/ + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + + break; + + case 0x838: /*rTxAGC_B_CCK1_55_Mcs32:*/ + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + for (i = 1; i < 4; ++i) { + pwr_by_rate_val[i - 1] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 3; + break; + + case 0xC20: + case 0xE20: + case 0x1820: + case 0x1a20: + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + rate[3] = DESC_RATE11M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC24: + case 0xE24: + case 0x1824: + case 0x1a24: + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC28: + case 0xE28: + case 0x1828: + case 0x1a28: + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC2C: + case 0xE2C: + case 0x182C: + case 0x1a2C: + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC30: + case 0xE30: + case 0x1830: + case 0x1a30: + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC34: + case 0xE34: + case 0x1834: + case 0x1a34: + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC38: + case 0xE38: + case 0x1838: + case 0x1a38: + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC3C: + case 0xE3C: + case 0x183C: + case 0x1a3C: + rate[0] = DESC_RATEVHT1SS_MCS0; + rate[1] = DESC_RATEVHT1SS_MCS1; + rate[2] = DESC_RATEVHT1SS_MCS2; + rate[3] = DESC_RATEVHT1SS_MCS3; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC40: + case 0xE40: + case 0x1840: + case 0x1a40: + rate[0] = DESC_RATEVHT1SS_MCS4; + rate[1] = DESC_RATEVHT1SS_MCS5; + rate[2] = DESC_RATEVHT1SS_MCS6; + rate[3] = DESC_RATEVHT1SS_MCS7; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC44: + case 0xE44: + case 0x1844: + case 0x1a44: + rate[0] = DESC_RATEVHT1SS_MCS8; + rate[1] = DESC_RATEVHT1SS_MCS9; + rate[2] = DESC_RATEVHT2SS_MCS0; + rate[3] = DESC_RATEVHT2SS_MCS1; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC48: + case 0xE48: + case 0x1848: + case 0x1a48: + rate[0] = DESC_RATEVHT2SS_MCS2; + rate[1] = DESC_RATEVHT2SS_MCS3; + rate[2] = DESC_RATEVHT2SS_MCS4; + rate[3] = DESC_RATEVHT2SS_MCS5; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC4C: + case 0xE4C: + case 0x184C: + case 0x1a4C: + rate[0] = DESC_RATEVHT2SS_MCS6; + rate[1] = DESC_RATEVHT2SS_MCS7; + rate[2] = DESC_RATEVHT2SS_MCS8; + rate[3] = DESC_RATEVHT2SS_MCS9; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + default: + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + "Invalid reg_addr 0x%x in %s()\n", reg_addr, __func__); + break; + }; +} + +void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band, + u32 rfpath, u32 txnum, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i = 0, rates[4] = {0}, rate_num = 0; + s8 pwr_by_rate_val[4] = {0}; + + _rtl8822be_get_rate_values_of_tx_power_by_rate( + hw, regaddr, bitmask, data, rates, pwr_by_rate_val, &rate_num); + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", + band); + band = BAND_ON_2_4G; + } + if (rfpath >= MAX_RF_PATH) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", + rfpath); + rfpath = MAX_RF_PATH - 1; + } + if (txnum >= MAX_RF_PATH) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", + txnum); + txnum = MAX_RF_PATH - 1; + } + + for (i = 0; i < rate_num; ++i) { + u8 rate_idx = rates[i]; + + if (IS_1T_RATE(rates[i])) + txnum = RF_1TX; + else if (IS_2T_RATE(rates[i])) + txnum = RF_2TX; + else + WARN_ON(1); + + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_idx] = + pwr_by_rate_val[i]; + + RT_TRACE( + rtlpriv, COMP_INIT, DBG_LOUD, + "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][rate_idx %d] = 0x%x\n", + band, rfpath, txnum, rate_idx, + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum] + [rate_idx]); + } +} + +static void +_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8822B; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8822B; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8822BE; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8822BE; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8822B; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8822B; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8822B; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8822B; +} + +void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > + txpwr_dbm) + txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm( + hw, WIRELESS_MODE_N_24G, txpwr_level); + *powerlevel = txpwr_dbm; +} + +static bool _rtl8822be_phy_get_chnl_index(u8 channel, u8 *chnl_index) +{ + u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + u8 i = 0; + bool in_24g = true; + + if (channel <= 14) { + in_24g = true; + *chnl_index = channel - 1; + } else { + in_24g = false; + + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) { + if (rtl_channel5g[i] == channel) { + *chnl_index = i; + return in_24g; + } + } + } + return in_24g; +} + +static char _rtl8822be_phy_get_world_wide_limit(char *limit_table) +{ + char min = limit_table[0]; + u8 i = 0; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + if (limit_table[i] < min) + min = limit_table[i]; + } + return min; +} + +static char _rtl8822be_phy_get_txpower_limit(struct ieee80211_hw *hw, u8 band, + enum ht_channel_width bandwidth, + enum radio_path rf_path, u8 rate, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + short regulation = -1, rate_section = -1, channel_index = -1; + char power_limit = MAX_POWER_INDEX; + + if (rtlefuse->eeprom_regulatory == 2) + return MAX_POWER_INDEX; + + regulation = TXPWR_LMT_WW; + + switch (rate) { + case DESC_RATE1M: + case DESC_RATE2M: + case DESC_RATE5_5M: + case DESC_RATE11M: + rate_section = CCK; + break; + + case DESC_RATE6M: + case DESC_RATE9M: + case DESC_RATE12M: + case DESC_RATE18M: + case DESC_RATE24M: + case DESC_RATE36M: + case DESC_RATE48M: + case DESC_RATE54M: + rate_section = OFDM; + break; + + case DESC_RATEMCS0: + case DESC_RATEMCS1: + case DESC_RATEMCS2: + case DESC_RATEMCS3: + case DESC_RATEMCS4: + case DESC_RATEMCS5: + case DESC_RATEMCS6: + case DESC_RATEMCS7: + rate_section = HT_MCS0_MCS7; + break; + + case DESC_RATEMCS8: + case DESC_RATEMCS9: + case DESC_RATEMCS10: + case DESC_RATEMCS11: + case DESC_RATEMCS12: + case DESC_RATEMCS13: + case DESC_RATEMCS14: + case DESC_RATEMCS15: + rate_section = HT_MCS8_MCS15; + break; + + case DESC_RATEVHT1SS_MCS0: + case DESC_RATEVHT1SS_MCS1: + case DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT1SS_MCS3: + case DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT1SS_MCS5: + case DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT1SS_MCS7: + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT1SS_MCS9: + rate_section = VHT_1SSMCS0_1SSMCS9; + break; + + case DESC_RATEVHT2SS_MCS0: + case DESC_RATEVHT2SS_MCS1: + case DESC_RATEVHT2SS_MCS2: + case DESC_RATEVHT2SS_MCS3: + case DESC_RATEVHT2SS_MCS4: + case DESC_RATEVHT2SS_MCS5: + case DESC_RATEVHT2SS_MCS6: + case DESC_RATEVHT2SS_MCS7: + case DESC_RATEVHT2SS_MCS8: + case DESC_RATEVHT2SS_MCS9: + rate_section = VHT_2SSMCS0_2SSMCS9; + break; + + default: + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Wrong rate 0x%x\n", + rate); + break; + } + + if (band == BAND_ON_5G && rate_section == 0) + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong rate 0x%x: No CCK in 5G Band\n", rate); + + /* workaround for wrong index combination to obtain tx power limit, + * OFDM only exists in BW 20M + */ + if (rate_section == 1) + bandwidth = 0; + + /* workaround for wrong index combination to obtain tx power limit, + * CCK table will only be given in BW 20M + */ + if (rate_section == 0) + bandwidth = 0; + + /* workaround for wrong indxe combination to obtain tx power limit, + * HT on 80M will reference to HT on 40M + */ + if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G && + bandwidth == 2) + bandwidth = 1; + + if (band == BAND_ON_2_4G) + channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt( + hw, BAND_ON_2_4G, channel); + else if (band == BAND_ON_5G) + channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt( + hw, BAND_ON_5G, channel); + else if (band == BAND_ON_BOTH) + ; /* BAND_ON_BOTH don't care temporarily */ + + if (band >= BANDMAX || regulation == -1 || bandwidth == -1 || + rate_section == -1 || channel_index == -1) { + RT_TRACE( + rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n", + band, regulation, bandwidth, rf_path, rate_section, + channel_index); + return MAX_POWER_INDEX; + } + + if (band == BAND_ON_2_4G) { + char limits[10] = {0}; + u8 i = 0; + + for (i = 0; i < 4; ++i) + limits[i] = rtlphy->txpwr_limit_2_4g[i][bandwidth] + [rate_section] + [channel_index] + [rf_path]; + + power_limit = + (regulation == TXPWR_LMT_WW) ? + _rtl8822be_phy_get_world_wide_limit(limits) : + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section] + [channel_index] + [rf_path]; + + } else if (band == BAND_ON_5G) { + char limits[10] = {0}; + u8 i = 0; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) + limits[i] = + rtlphy->txpwr_limit_5g[i][bandwidth] + [rate_section] + [channel_index][rf_path]; + + power_limit = + (regulation == TXPWR_LMT_WW) ? + _rtl8822be_phy_get_world_wide_limit(limits) : + rtlphy->txpwr_limit_5g[regulation] + [channel_index] + [rate_section] + [channel_index][rf_path]; + } else + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "No power limit table of the specified band\n"); + + return power_limit; +} + +static char +_rtl8822be_phy_get_txpower_by_rate(struct ieee80211_hw *hw, u8 band, u8 path, + u8 rate /* enum rtl_desc8822b_rate */) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 tx_num; + char tx_pwr_diff = 0; + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) + return tx_pwr_diff; + + if (path > RF90_PATH_B) + return tx_pwr_diff; + + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9)) + tx_num = RF_2TX; + else + tx_num = RF_1TX; + + tx_pwr_diff = (char)(rtlphy->tx_power_by_rate_offset[band][path][tx_num] + [rate] & + 0xff); + + return tx_pwr_diff; +} + +u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate, + u8 bandwidth, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + u8 txpower = 0; + bool in_24g = false; + char limit; + char powerdiff_byrate = 0; + + if (((rtlhal->current_bandtype == BAND_ON_2_4G) && + (channel > 14 || channel < 1)) || + ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) { + index = 0; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Illegal channel!!\n"); + } + + /* 1. base tx power */ + in_24g = _rtl8822be_phy_get_chnl_index(channel, &index); + if (in_24g) { + if (RX_HAL_IS_CCK_RATE(rate)) + txpower = rtlefuse->txpwrlevel_cck[path][index]; + else if (rate >= DESC_RATE6M) + txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; + else + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "invalid rate\n"); + + if (rate >= DESC_RATE6M && rate <= DESC_RATE54M && + !RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht20diff[path][TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht20diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_80) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_2S]; + } + + } else { + if (rate >= DESC_RATE6M) + txpower = rtlefuse->txpwr_5g_bw40base[path][index]; + else + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING, + "INVALID Rate.\n"); + + if (rate >= DESC_RATE6M && rate <= DESC_RATE54M && + !RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw20diff[path] + [TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw20diff[path] + [TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw40diff[path] + [TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw40diff[path] + [TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_80) { + u8 i = 0; + + for (i = 0; i < sizeof(rtl_channel5g_80m) / sizeof(u8); + ++i) + if (rtl_channel5g_80m[i] == channel) + index = i; + + txpower = rtlefuse->txpwr_5g_bw80base[path][index]; + + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw80diff[path] + [TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw80diff[path] + [TX_2S]; + } + } + + /* 2. tx power by rate */ + if (rtlefuse->eeprom_regulatory != 2) + powerdiff_byrate = _rtl8822be_phy_get_txpower_by_rate( + hw, (u8)(!in_24g), path, rate); + + /* 3. tx power limit */ + if (rtlefuse->eeprom_regulatory == 1) + limit = _rtl8822be_phy_get_txpower_limit( + hw, (u8)(!in_24g), bandwidth, path, rate, + channel); + else + limit = MAX_POWER_INDEX; + + /* ----- */ + powerdiff_byrate = powerdiff_byrate > limit ? limit : powerdiff_byrate; + + txpower += powerdiff_byrate; + + if (txpower > MAX_POWER_INDEX) + txpower = MAX_POWER_INDEX; + + return txpower; +} + +static void _rtl8822be_phy_set_txpower_index(struct ieee80211_hw *hw, + u8 power_index, u8 path, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 shift = 0; + static u32 index; + + /* + * For 8822B, phydm api use 4 bytes txagc value + * driver must combine every four 1 byte to one 4 byte and send to phydm + */ + shift = rate & 0x03; + index |= ((u32)power_index << (shift * 8)); + + if (shift == 3) { + rate = rate - 3; + + if (!rtlpriv->phydm.ops->phydm_write_txagc(rtlpriv, index, path, + rate)) { + RT_TRACE(rtlpriv, COMP_TXAGC, DBG_LOUD, + "%s(index:%d, rfpath:%d, rate:0x%02x) fail\n", + __func__, index, path, rate); + + WARN_ON(1); + } + index = 0; + } +} + +static void _rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 *array, u8 path, + u8 channel, u8 size) +{ + struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy); + u8 i; + u8 power_index; + + for (i = 0; i < size; i++) { + power_index = rtl8822be_get_txpower_index( + hw, path, array[i], rtlphy->current_chan_bw, channel); + _rtl8822be_phy_set_txpower_index(hw, power_index, path, + array[i]); + } +} + +void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 channel, u8 path) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + /* + * Below order is *VERY* important! + * Because _rtl8822be_phy_set_txpower_index() do actually writing + * every four power values. + */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + _rtl8822be_phy_set_txpower_level_by_path( + hw, cck_rates, path, channel, sizes_of_cck_retes); + _rtl8822be_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel, + sizes_of_ofdm_retes); + _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel, + sizes_of_ht_retes_1t); + _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, channel, + sizes_of_ht_retes_2t); + _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, + channel, sizes_of_vht_retes); + _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_2t, path, + channel, sizes_of_vht_retes); +} + +void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel, + u8 path, enum rate_section rs) +{ + struct { + u8 *array; + u8 size; + } rs_ref[MAX_RATE_SECTION] = { + {cck_rates, sizes_of_cck_retes}, + {ofdm_rates, sizes_of_ofdm_retes}, + {ht_rates_1t, sizes_of_ht_retes_1t}, + {ht_rates_2t, sizes_of_ht_retes_2t}, + {vht_rates_1t, sizes_of_vht_retes}, + {vht_rates_2t, sizes_of_vht_retes}, + }; + + if (rs >= MAX_RATE_SECTION) + return; + + _rtl8822be_phy_set_txpower_level_by_path(hw, rs_ref[rs].array, path, + channel, rs_ref[rs].size); +} + +void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 path = 0; + + for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path) + rtl8822be_phy_set_txpower_level_by_path(hw, channel, path); +} + +static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_BACKUP_BAND1: + iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +static u8 _rtl8822be_phy_get_pri_ch_id(struct rtl_priv *rtlpriv) +{ + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 pri_ch_idx = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + /* primary channel is at lower subband of 80MHz & 40MHz */ + if ((mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) { + pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ; + /* primary channel is at + * lower subband of 80MHz & upper subband of 40MHz + */ + } else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) { + pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ; + /* primary channel is at + * upper subband of 80MHz & lower subband of 40MHz + */ + } else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) { + pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ; + /* primary channel is at + * upper subband of 80MHz & upper subband of 40MHz + */ + } else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) { + pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ; + } else { + if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) + pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) + pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ; + } + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + /* primary channel is at upper subband of 40MHz */ + if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER) + pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ; + /* primary channel is at lower subband of 40MHz */ + else if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) + pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else + ; + } + + return pri_ch_idx; +} + +void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + /* get primary channel index */ + u8 pri_ch_idx = _rtl8822be_phy_get_pri_ch_id(rtlpriv); + + /* 3.1 set MAC register */ + rtlpriv->halmac.ops->halmac_set_bandwidth( + rtlpriv, rtlphy->current_channel, pri_ch_idx, + rtlphy->current_chan_bw); + + /* 3.2 set BB/RF registet */ + rtlpriv->phydm.ops->phydm_switch_bandwidth( + rtlpriv, pri_ch_idx, rtlphy->current_chan_bw); + + if (!mac->act_scanning) + rtlpriv->phydm.ops->phydm_iq_calibrate(rtlpriv); + + rtlphy->set_bwmode_inprogress = false; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "FALSE driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 timeout = 1000, timecount = 0; + u8 channel = rtlphy->current_channel; + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + return 0; + } + while (rtlphy->lck_inprogress && timecount < timeout) { + mdelay(50); + timecount += 50; + } + + if (rtlphy->current_channel > 14) + rtlhal->current_bandtype = BAND_ON_5G; + else if (rtlphy->current_channel <= 14) + rtlhal->current_bandtype = BAND_ON_2_4G; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_switch_band_notify( + rtlpriv, rtlhal->current_bandtype, mac->act_scanning); + else + rtlpriv->btcoexist.btc_ops->btc_switch_band_notify_wifi_only( + rtlpriv, rtlhal->current_bandtype, mac->act_scanning); + + rtlpriv->phydm.ops->phydm_switch_band(rtlpriv, rtlphy->current_channel); + + rtlphy->sw_chnl_inprogress = true; + if (channel == 0) + channel = 1; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d, band type is %d\n", + rtlphy->current_channel, rtlhal->current_bandtype); + + rtlpriv->phydm.ops->phydm_switch_channel(rtlpriv, + rtlphy->current_channel); + + rtlpriv->phydm.ops->phydm_clear_txpowertracking_state(rtlpriv); + + rtl8822be_phy_set_txpower_level(hw, rtlphy->current_channel); + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); + rtlphy->sw_chnl_inprogress = false; + return 1; +} + +bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", iotype, + rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + pr_err("switch case not process\n"); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl8822be_phy_set_io(hw); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl8822be_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + break; + case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: + break; + default: + pr_err("switch case not process\n"); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "(%#x)\n", + rtlphy->current_io_type); +} + +static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL_8822B, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE_8822B, 0x00); +} + +static bool _rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus = false; + u32 initialize_count = 0; + + do { + initialize_count++; + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while ((!rtstatus) && (initialize_count < 10)); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl8822be_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + RT_TRACE( + rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE( + rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control( + hw, LED_CTL_POWER_OFF); + } + } + break; + default: + pr_err("switch case not process\n"); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl8822be_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/staging/rtlwifi/rtl8822be/phy.h b/drivers/staging/rtlwifi/rtl8822be/phy.h new file mode 100644 index 0000000000000000000000000000000000000000..5c33f16bcaa43df861b3a337a76faf08883452d5 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/phy.h @@ -0,0 +1,145 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822BE_PHY_H__ +#define __RTL8822BE_PHY_H__ + +/* It must always set to 4, otherwise read + * efuse table sequence will be wrong. + */ +#define MAX_TX_COUNT 4 +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +#define MAX_POWER_INDEX 0x3F + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 9 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 10 +#define index_mapping_NUM 15 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNA_DIVERSITY_VALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL8822BE_MAX_PATH_NUM 2 + +#define TARGET_CHNL_NUM_2G_5G_8822B 59 + +u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask); +void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); +u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw); +bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv); +bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv); +void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel); +void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); +void rtl8822be_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl8822be_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl8822be_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl8822be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 channel, u8 path); +void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold); +void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold); +void rtl8822be_reset_iqk_result(struct ieee80211_hw *hw); + +u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate, + u8 bandwidth, u8 channel); +void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel, + u8 path, enum rate_section rs); +void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band, + u32 rfpath, u32 txnum, u32 regaddr, + u32 bitmask, u32 data); +void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, + u8 *pband, u8 *pbandwidth, + u8 *prate_section, u8 *prf_path, + u8 *pchannel, u8 *ppower_limit); +bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw); +bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/reg.h b/drivers/staging/rtlwifi/rtl8822be/reg.h new file mode 100644 index 0000000000000000000000000000000000000000..0dca5dccf49a607a2d4de9f2054bb0b0360ab8b4 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/reg.h @@ -0,0 +1,1653 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_REG_H__ +#define __RTL8822B_REG_H__ + +#include "../halmac/halmac_reg_8822b.h" +#include "../halmac/halmac_bit_8822b.h" + +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +/* Page 0 */ +#define REG_LEDCFG2_8822B 0x004E /* need review */ +#define REG_SPS0_CTRL_8822B 0x0011 /* need review: swlps */ + +#define REG_EFUSE_ACCESS_8822B (REG_PMC_DBG_CTRL2_8822B + 3) /*0x00CF*/ +#define REG_AFE_XTAL_CTRL_8822B REG_AFE_CTRL1_8822B +#define REG_AFE_PLL_CTRL_8822B REG_AFE_CTRL2_8822B + +/* Page 1 */ + +#define MSR (REG_CR_8822B + 2) + +/* for MSR 0x102 */ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +/*----------------------------------------------------- + * + * 0x0200h ~ 0x027Fh TXDMA Configuration + * + *----------------------------------------------------- + */ + +/*----------------------------------------------------- + * + * 0x0280h ~ 0x02FFh RXDMA Configuration + * + *----------------------------------------------------- + */ +#define REG_RXDMA_CONTROL_8822B (REG_RXPKT_NUM_8822B + 2) /* 0x0286 */ + +/*----------------------------------------------------- + * + * 0x0300h ~ 0x03FFh PCIe + * + *----------------------------------------------------- + */ + +/* REG_HIMR3_8822B */ +#define IMR_H2CDOK BIT_SETH2CDOK_MASK_8822B + +/* spec version 11 + *----------------------------------------------------- + * + * 0x0400h ~ 0x047Fh Protocol Configuration + * + *----------------------------------------------------- + */ + +#define REG_MAX_AGGR_NUM_8822B (REG_PROT_MODE_CTRL_8822B + 2) /*0x04CA*/ + +/* for RRSR 0x440 */ +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) + +#define RRSR_ALL_CCK (RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M) +#define RRSR_ALL_OFDM_AG \ + (RRSR_6M | RRSR_9M | RRSR_12M | RRSR_18M | RRSR_24M | RRSR_36M | \ + RRSR_48M | RRSR_54M) + +/*----------------------------------------------------- + * + * 0x0500h ~ 0x05FFh EDCA Configuration + * + *----------------------------------------------------- + */ + +#define REG_SIFS_TRX_8822B (REG_SIFS_8822B + 2) /*0x0516*/ + +/*----------------------------------------------------- + * + * 0x0600h ~ 0x07FFh WMAC Configuration + * + *----------------------------------------------------- + */ + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +/* CAM definition */ + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +/*#define TOTAL_CAM_ENTRY 64*/ +/*#define HALF_CAM_ENTRY 32*/ + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +/********************************************* + * 8822BE IMR/ISR bits + ********************************************* + */ +#define IMR_DISABLED 0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +#define IMR_TIMER2 BIT(31) +#define IMR_TIMER1 BIT(30) +#define IMR_PSTIMEOUT BIT(29) +#define IMR_GTINT4 BIT(28) +#define IMR_GTINT3 BIT(27) +#define IMR_TBDER BIT(26) +#define IMR_TBDOK BIT(25) +#define IMR_TSF_BIT32_TOGGLE BIT(24) +#define IMR_BCNDMAINT0 BIT(20) +#define IMR_BCNDOK0 BIT(16) +#define IMR_HSISR_IND_ON_INT BIT(15) +#define IMR_BCNDMAINT_E BIT(14) +#define IMR_ATIMEND BIT(12) +#define IMR_HISR1_IND_INT BIT(11) +#define IMR_C2HCMD BIT(10) +#define IMR_CPWM2 BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_HIGHDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_BKDOK BIT(5) +#define IMR_BEDOK BIT(4) +#define IMR_VIDOK BIT(3) +#define IMR_VODOK BIT(2) +#define IMR_RDU BIT(1) +#define IMR_ROK BIT(0) + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +#define IMR_TXFIFO_TH_INT_8822B BIT_TXFIFO_TH_INT_8822B +#define IMR_BTON_STS_UPDATE_MASK_8822B BIT_BTON_STS_UPDATE_MASK_8822B +#define IMR_MCUERR BIT(28) +#define IMR_BCNDMAINT7 BIT(27) +#define IMR_BCNDMAINT6 BIT(26) +#define IMR_BCNDMAINT5 BIT(25) +#define IMR_BCNDMAINT4 BIT(24) +#define IMR_BCNDMAINT3 BIT(23) +#define IMR_BCNDMAINT2 BIT(22) +#define IMR_BCNDMAINT1 BIT(21) +#define IMR_BCNDOK7 BIT(20) +#define IMR_BCNDOK6 BIT(19) +#define IMR_BCNDOK5 BIT(18) +#define IMR_BCNDOK4 BIT(17) +#define IMR_BCNDOK3 BIT(16) +#define IMR_BCNDOK2 BIT(15) +#define IMR_BCNDOK1 BIT(14) +#define IMR_ATIMEND_E BIT(13) +#define IMR_ATIMEND BIT(12) +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_TXFOVW BIT(9) +#define IMR_RXFOVW BIT(8) +#define IMR_CPU_MGQ_TXDONE_MSK_8822B BIT_CPU_MGQ_TXDONE_MSK_8822B +#define IMR_PS_TIMER_C_MSK_8822B BIT_PS_TIMER_C_MSK_8822B +#define IMR_PS_TIMER_B_MSK_8822B BIT_PS_TIMER_B_MSK_8822B +#define IMR_PS_TIMER_A_MSK_8822B BIT_PS_TIMER_A_MSK_8822B +#define IMR_CPUMGQ_TX_TIMER_MSK_8822B BIT_CPUMGQ_TX_TIMER_MSK_8822B + +/********************************************* + * 8822BE EFUSE definition + ********************************************* + */ +#define HWSET_MAX_SIZE 1024 +#define EFUSE_MAX_SECTION 64 +#define EFUSE_REAL_CONTENT_LEN 1024 +#define EFUSE_OOB_PROTECT_BYTES 18 + +#define EEPROM_DEFAULT_THERMALMETER 0x12 + +#define RTL8822B_EEPROM_ID 0x8129 + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8822B 0xEE +#define PPG_THERMAL_OFFSET_8822B 0xEF + +#define EEPROM_TX_PWR_INX_8822B 0x10 + +#define EEPROM_CHANNEL_PLAN_8822B 0xB8 +#define EEPROM_XTAL_8822B 0xB9 +#define EEPROM_THERMAL_METER_8822B 0xBA +#define EEPROM_IQK_LCK_8822B 0xBB +#define EEPROM_2G_5G_PA_TYPE_8822B 0xBC +/* PATH A & PATH B */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B 0xBD +/* PATH C & PATH D */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_CD_8822B 0xBE +/* PATH A & PATH B */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B 0xBF +/* PATH C & PATH D */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_CD_8822B 0xC0 + +#define EEPROM_RF_BOARD_OPTION_8822B 0xC1 +#define EEPROM_FEATURE_OPTION_8822B 0xC2 +#define EEPROM_RF_BT_SETTING_8822B 0xC3 +#define EEPROM_VERSION_8822B 0xC4 +#define EEPROM_CUSTOM_ID_8822B 0xC5 +#define EEPROM_TX_BBSWING_2G_8822B 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8822B 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8822B 0xC9 +#define EEPROM_RFE_OPTION_8822B 0xCA +#define EEPROM_COUNTRY_CODE_8822B 0xCB + +#define EEPROM_VID 0xD6 +#define EEPROM_DID 0xD8 +#define EEPROM_SVID 0xDA +#define EEPROM_SMID 0xDC + +/* RTL8822BU */ +#define EEPROM_MAC_ADDR_8822BU 0x107 +#define EEPROM_VID_8822BU 0x100 +#define EEPROM_PID_8822BU 0x102 +#define EEPROM_USB_OPTIONAL_FUNCTION0_8822BU 0x104 +#define EEPROM_USB_MODE_8822BU 0x06 + +/* RTL8822BS */ +#define EEPROM_MAC_ADDR_8822BS 0x11A + +/* RTL8822BE */ +#define EEPROM_MAC_ADDR_8822BE 0xD0 + +/* ------------------------- */ + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_VHT_DACK BIT(26) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO_8822B 0xFE17 +#define REG_USB_SPECIAL_OPTION_8822B 0xFE55 +#define REG_USB_DMA_AGG_TO_8822B 0xFE5B +#define REG_USB_AGG_TO_8822B 0xFE5C +#define REG_USB_AGG_TH_8822B 0xFE5D + +#define REG_USB_VID_8822B 0xFE60 +#define REG_USB_PID_8822B 0xFE62 +#define REG_USB_OPTIONAL_8822B 0xFE64 +#define REG_USB_CHIRP_K_8822B 0xFE65 +#define REG_USB_PHY_8822B 0xFE66 +#define REG_USB_MAC_ADDR_8822B 0xFE70 +#define REG_USB_HRPWM_8822B 0xFE58 +#define REG_USB_HCPWM_8822B 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EN_PDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define EN_BT BIT(5) +#define EN_UART BIT(8) +#define UART_910 BIT(9) +#define EN_PMAC BIT(10) +#define SIC_SWRST BIT(11) +#define EN_SIC BIT(12) +#define SIC_23 BIT(13) +#define EN_HDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE_8822B (REG_CR_8822B + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x) & 0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x) & 0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x) & 0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x) & 0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x) & 0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x) & 0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HW_EN BIT(0) +#define ACMHW_BEQ_EN BIT(1) +#define ACMHW_VIQ_EN BIT(2) +#define ACMHW_VOQ_EN BIT(3) +#define ACMHW_BEQ_STATUS BIT(4) +#define ACMHW_VIQ_STATUS BIT(5) +#define ACMHW_VOQ_STATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EN_MBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TX_USE_DK BIT(0) +#define SCR_RX_USE_DK BIT(1) +#define SCR_TX_ENC_ENABLE BIT(2) +#define SRC_RX_DEC_ENABLE BIT(3) +#define SCR_SK_BY_A2 BIT(4) +#define SCR_NO_SKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 175 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 3000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1 << 7) | (1 << 6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HAL_8822B_HW_GPIO_WPS_BIT BIT(2) + +/*----------------------------------------------------- + * BB / RF register + *----------------------------------------------------- + */ + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c +#define RCCAONSEC 0x838 + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 +#define RL1PEAKTH 0x848 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFC_AREA 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RF_PARA_METER 0x878 +#define RFPGA0_XCD_RF_PARA_METER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +/*#define RFPGA0_XD_LSSIREADBACK 0x8ac*/ +#define RRFMOD 0x8ac +#define RHSSIREAD_8822BE 0x8b0 + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +/*#define REG_SC_CNT_8822B 0x8c4*/ +#define RADC_BUF_CLK 0x8c4 +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +/* PageB(0xB00) */ + +/*Page C*/ + +#define RA_TXPWRTRAING 0xc54 +#define RB_TXPWRTRAING 0xe54 + +#define RA_LSSIWRITE_8822B 0xc90 +#define RB_LSSIWRITE_8822B 0xe90 + +#define RA_PIREAD_8822B 0xd04 +#define RB_PIREAD_8822B 0xd44 +#define RA_SIREAD_8822B 0xd08 +#define RB_SIREAD_8822B 0xd48 + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#define RF_AC 0x00 + +#define RF_IQADJ_G1 0x01 +#define RF_IQADJ_G2 0x02 +#define RF_POW_TRSW 0x05 + +#define RF_GAIN_RX 0x06 +#define RF_GAIN_TX 0x07 + +#define RF_TXM_IDAC 0x08 +#define RF_BS_IQGEN 0x0F + +#define RF_MODE1 0x10 +#define RF_MODE2 0x11 + +#define RF_RX_AGC_HP 0x12 +#define RF_TX_AGC 0x13 +#define RF_BIAS 0x14 +#define RF_IPA 0x15 +#define RF_POW_ABILITY 0x17 +#define RF_MODE_AG 0x18 +#define RRFCHANNEL 0x18 +#define RF_CHNLBW 0x18 +#define RF_TOP 0x19 + +#define RF_RX_G1 0x1A +#define RF_RX_G2 0x1B + +#define RF_RX_BB2 0x1C +#define RF_RX_BB1 0x1D + +#define RF_RCK1 0x1E +#define RF_RCK2 0x1F + +#define RF_TX_G1 0x20 +#define RF_TX_G2 0x21 +#define RF_TX_G3 0x22 + +#define RF_TX_BB1 0x23 +#define RF_T_METER 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +#define RF_APK 0x63 + +#define RF_WE_LUT 0xEF + +#define BBBRESETB 0x100 +#define BGLOBALRESETB 0x200 +#define BOFDMTXSTART 0x4 +#define BCCKTXSTART 0x8 +#define BCRC32DEBUG 0x100 +#define BPMACLOOPBACK 0x10 +#define BTXLSIG 0xffffff +#define BOFDMTXRATE 0xf +#define BOFDMTXRESERVED 0x10 +#define BOFDMTXLENGTH 0x1ffe0 +#define BOFDMTXPARITY 0x20000 +#define BTXHTSIG1 0xffffff +#define BTXHTMCSRATE 0x7f +#define BTXHTBW 0x80 +#define BTXHTLENGTH 0xffff00 +#define BTXHTSIG2 0xffffff +#define BTXHTSMOOTHING 0x1 +#define BTXHTSOUNDING 0x2 +#define BTXHTRESERVED 0x4 +#define BTXHTAGGREATION 0x8 +#define BTXHTSTBC 0x30 +#define BTXHTADVANCECODING 0x40 +#define BTXHTSHORTGI 0x80 +#define BTXHTNUMBERHT_LTF 0x300 +#define BTXHTCRC8 0x3fc00 +#define BCOUNTERRESET 0x10000 +#define BNUMOFOFDMTX 0xffff +#define BNUMOFCCKTX 0xffff0000 +#define BTXIDLEINTERVAL 0xffff +#define BOFDMSERVICE 0xffff0000 +#define BTXMACHEADER 0xffffffff +#define BTXDATAINIT 0xff +#define BTXHTMODE 0x100 +#define BTXDATATYPE 0x30000 +#define BTXRANDOMSEED 0xffffffff +#define BCCKTXPREAMBLE 0x1 +#define BCCKTXSFD 0xffff0000 +#define BCCKTXSIG 0xff +#define BCCKTXSERVICE 0xff00 +#define BCCKLENGTHEXT 0x8000 +#define BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) ((_offset >= 0x800) && (_offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +/* Block & Path enable*/ +#define ROFDMCCKEN 0x808 +#define BCCKEN 0x10000000 +#define BOFDMEN 0x20000000 +/* Rx antenna*/ +#define RRXPATH 0x808 +#define BRXPATH 0xff +/* Tx antenna*/ +#define RTXPATH 0x80c +#define BTXPATH 0x0fffffff +/* for cck rx path selection*/ +#define RCCK_RX 0xa04 +#define BCCK_RX 0x0c000000 +/* Use LSIG for VHT length*/ +#define RVHTLEN_USE_LSIG 0x8c3 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#define B5GPAPEPOLARITY 0x40000000 +#define B2GPAPEPOLARITY 0x80000000 +#define BRFSW_TXDEFAULTANT 0x3 +#define BRFSW_TXOPTIONANT 0x30 +#define BRFSW_RXDEFAULTANT 0x300 +#define BRFSW_RXOPTIONANT 0x3000 +#define BRFSI_3WIREDATA 0x1 +#define BRFSI_3WIRECLOCK 0x2 +#define BRFSI_3WIRELOAD 0x4 +#define BRFSI_3WIRERW 0x8 +#define BRFSI_3WIRE 0xf + +#define BRFSI_RFENV 0x10 + +#define BRFSI_TRSW 0x20 +#define BRFSI_TRSWB 0x40 +#define BRFSI_ANTSW 0x100 +#define BRFSI_ANTSWB 0x200 +#define BRFSI_PAPE 0x400 +#define BRFSI_PAPE5G 0x800 +#define BBANDSELECT 0x1 +#define BHTSIG2_GI 0x80 +#define BHTSIG2_SMOOTHING 0x01 +#define BHTSIG2_SOUNDING 0x02 +#define BHTSIG2_AGGREATON 0x08 +#define BHTSIG2_STBC 0x30 +#define BHTSIG2_ADVCODING 0x40 +#define BHTSIG2_NUMOFHTLTF 0x300 +#define BHTSIG2_CRC8 0x3fc +#define BHTSIG1_MCS 0x7f +#define BHTSIG1_BANDWIDTH 0x80 +#define BHTSIG1_HTLENGTH 0xffff +#define BLSIG_RATE 0xf +#define BLSIG_RESERVED 0x10 +#define BLSIG_LENGTH 0x1fffe +#define BLSIG_PARITY 0x20 +#define BCCKRXPHASE 0x4 + +#define BLSSIREADADDRESS 0x7f800000 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#define BREGULATOR0STANDBY 0x1 +#define BREGULATORPLLSTANDBY 0x2 +#define BREGULATOR1STANDBY 0x4 +#define BPLLPOWERUP 0x8 +#define BDPLLPOWERUP 0x10 +#define BDA10POWERUP 0x20 +#define BAD7POWERUP 0x200 +#define BDA6POWERUP 0x2000 +#define BXTALPOWERUP 0x4000 +#define B40MDCLKPOWERUP 0x8000 +#define BDA6DEBUGMODE 0x20000 +#define BDA6SWING 0x380000 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCK_RX_RF_SETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 0x1f000000 +#define BPD_TH 0xf +#define BPD_TH_OPT2 0xc000 +#define BPWED_TH 0x700 +#define BIFMF_WIN_L 0x800 +#define BPD_OPTION 0x1000 +#define BMF_WIN_L 0xe000 +#define BBW_SEARCH_L 0x30000 +#define BWIN_ENH_L 0xc0000 +#define BBW_TH 0x700000 +#define BED_TH2 0x3800000 +#define BBW_OPTION 0x4000000 +#define BRADIO_TH 0x18000000 +#define BWINDOW_L 0xe0000000 +#define BSBD_OPTION 0x1 +#define BFRAME_TH 0x1c +#define BFS_OPTION 0x60 +#define BDC_SLOPE_CHECK 0x80 +#define BFGUARD_COUNTER_DC_L 0xe00 +#define BFRAME_WEIGHT_SHORT 0x7000 +#define BSUB_TUNE 0xe00000 +#define BFRAME_DC_LENGTH 0xe000000 +#define BSBD_START_OFFSET 0x30000000 +#define BFRAME_TH_2 0x7 +#define BFRAME_GI2_TH 0x38 +#define BGI2_SYNC_EN 0x40 +#define BSARCH_SHORT_EARLY 0x300 +#define BSARCH_SHORT_LATE 0xc00 +#define BSARCH_GI2_LATE 0x70000 +#define BCFOANTSUM 0x1 +#define BCFOACC 0x2 +#define BCFOSTARTOFFSET 0xc +#define BCFOLOOPBACK 0x70 +#define BCFOSUMWEIGHT 0x80 +#define BDAGCENABLE 0x10000 +#define BTXIQIMB_A 0x3ff +#define BTXIQIMB_b 0xfc00 +#define BTXIQIMB_C 0x3f0000 +#define BTXIQIMB_D 0xffc00000 +#define BTXIDCOFFSET 0xff +#define BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 0x4 +#define BRXHP_INI 0x7 +#define BRXHP_TRLNA 0x70 +#define BRXHP_RSSI 0x700 +#define BRXHP_BBP1 0x7000 +#define BRXHP_BBP2 0x70000 +#define BRXHP_BBP3 0x700000 +#define BRSSI_H 0x7f0000 +#define BRSSI_GEN 0x7f000000 +#define BRXSETTLE_TRSW 0x7 +#define BRXSETTLE_LNA 0x38 +#define BRXSETTLE_RSSI 0x1c0 +#define BRXSETTLE_BBP 0xe00 +#define BRXSETTLE_RXHP 0x7000 +#define BRXSETTLE_ANTSW_RSSI 0x38000 +#define BRXSETTLE_ANTSW 0xc0000 +#define BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 0x3800 +#define BRXPD_DELAY_TH1 0x38 +#define BRXPD_DELAY_TH2 0x1c0 +#define BRXPD_DC_COUNT_MAX 0x600 +#define BRXPD_DELAY_TH 0x8000 +#define BRXPROCESS_DELAY 0xf0000 +#define BRXSEARCHRANGE_GI2_EARLY 0x700000 +#define BRXFRAME_FUARD_COUNTER_L 0x3800000 +#define BRXSGI_GUARD_L 0xc000000 +#define BRXSGI_SEARCH_L 0x30000000 +#define BRXSGI_TH 0xc0000000 +#define BDFSCNT0 0xff +#define BDFSCNT1 0xff00 +#define BDFSFLAG 0xf0000 +#define BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 0x100 +#define BCFOEN 0x10000 +#define BCFOVALUE 0xfff00000 +#define BSIGTONE_RE 0x3f +#define BSIGTONE_IM 0x7f00 +#define BCOUNTER_CCA 0xffff +#define BCOUNTER_PARITYFAIL 0xffff0000 +#define BCOUNTER_RATEILLEGAL 0xffff +#define BCOUNTER_CRC8FAIL 0xffff0000 +#define BCOUNTER_MCSNOSUPPORT 0xffff +#define BCOUNTER_FASTSYNC 0xffff +#define BSHORTCFO 0xfff +#define BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 3 +#define BRX_HT_BW 0x1 +#define BRXSC 0x6 +#define BRX_HT 0x8 +#define BNB_INTF_DET_ON 0x1 +#define BINTF_WIN_LEN_CFG 0x30 +#define BNB_INTF_TH_CFG 0x1c0 +#define BRFGAIN 0x3f +#define BTABLESEL 0x40 +#define BTRSW 0x80 +#define BRXSNR_A 0xff +#define BRXSNR_B 0xff00 +#define BRXSNR_C 0xff0000 +#define BRXSNR_D 0xff000000 +#define BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BMASKBYTE0 0xff +#define BMASKBYTE1 0xff00 +#define BMASKBYTE2 0xff0000 +#define BMASKBYTE3 0xff000000 +#define BMASKHWORD 0xffff0000 +#define BMASKLWORD 0x0000ffff +#define BMASKDWORD 0xffffffff +#define BMASK12BITS 0xfff +#define BMASKH4BITS 0xf0000000 +#define BMASKOFDM_D 0xffc00000 +#define BMASKCCK 0x3f3f3f3f + +#define BRFREGOFFSETMASK 0xfffff + +/* WOL bit information */ +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_FW_DISCONNECT BIT(4) + +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/sw.c b/drivers/staging/rtlwifi/rtl8822be/sw.c new file mode 100644 index 0000000000000000000000000000000000000000..91b784b6d1c5d6a4dd8f64b17b37ec57812bbc30 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/sw.c @@ -0,0 +1,481 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "hw.h" +#include "sw.h" +#include "fw.h" +#include "trx.h" +#include "led.h" +#include "../btcoexist/rtl_btc.h" +#include "../halmac/rtl_halmac.h" +#include "../phydm/rtl_phydm.h" +#include +#include + +static void rtl8822be_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /*close ASPM for AMD defaultly */ + rtlpci->const_amdpci_aspm = 0; + + /* + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8822BE:3 RTL8822B:2 + * + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8822BE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +int rtl8822be_init_sw_vars(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + const char *fw_name; + struct rtl_phydm_params params; + + rtl8822be_bt_reg_init(hw); + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + rtlpriv->halmac.ops = rtl_halmac_get_ops_pointer(); + rtlpriv->halmac.ops->halmac_init_adapter(rtlpriv); + + /* should after halmac_init_adapter() */ + rtl8822be_read_eeprom_info(hw, ¶ms); + + /* need eeprom info */ + rtlpriv->phydm.ops = rtl_phydm_get_ops_pointer(); + rtlpriv->phydm.ops->phydm_init_priv(rtlpriv, ¶ms); + + rtlpriv->dm.dm_initialgain_enable = 1; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = 0; + /*rtlpriv->dm.thermalvalue = 0;*/ + rtlpriv->dm.useramask = 1; /* turn on RA */ + rtlpci->transmit_config = CFENDFORM | BIT(15); + + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + /*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/ + rtlpriv->rtlhal.bandset = BAND_ON_BOTH; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_VHT_DACK | + RCR_HTC_LOC_CTRL | + /*RCR_AMF |*/ + RCR_CBSSID_BCN | + RCR_CBSSID_DATA | + /*RCR_ACF |*/ + /*RCR_ADF |*/ + /*RCR_AICV |*/ + /*RCR_ACRC32 |*/ + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = (u32)(IMR_PSTIMEOUT | + /*IMR_TBDER |*/ + /*IMR_TBDOK |*/ + /*IMR_BCNDMAINT0 |*/ + IMR_GTINT3 | + IMR_HSISR_IND_ON_INT | + IMR_C2HCMD | + IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_RDU | + IMR_ROK | + 0); + + rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | IMR_TXFOVW | 0); + rtlpci->irq_mask[3] = (u32)(BIT_SETH2CDOK_MASK | 0); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 2; + rtlpriv->psc.reg_max_lps_awakeintvl = 2; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 + */ + rtl8822be_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = false; + + /*low power */ + rtlpriv->psc.low_power_enable = false; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x40000); + if (!rtlpriv->rtlhal.pfirmware) { + /*pr_err("Can't alloc buffer for fw\n");*/ + return 1; + } + + /* request fw */ + fw_name = "rtlwifi/rtl8822befw.bin"; + + rtlpriv->max_fw_size = 0x40000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + return 1; + } + + /* init table of tx power by rate & limit */ + rtl8822be_load_txpower_by_rate(hw); + rtl8822be_load_txpower_limit(hw); + + return 0; +} + +void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->halmac.ops->halmac_deinit_adapter(rtlpriv); + rtlpriv->phydm.ops->phydm_deinit_priv(rtlpriv); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +/* get bt coexist status */ +bool rtl8822be_get_btc_status(void) +{ + return true; +} + +static void rtl8822be_phydm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 tmp; + + tmp = rtl_read_dword(rtlpriv, 0xc00); + if (tmp & 0xFF000000) { /* Recover 0xC00: 0xF800000C --> 0x0000000C */ + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "found regaddr_c00=%08X\n", tmp); + tmp &= ~0xFF000000; + rtl_write_dword(rtlpriv, 0xc00, tmp); + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "apply regaddr_c00=%08X\n", tmp); + } + + rtlpriv->phydm.ops->phydm_watchdog(rtlpriv); +} + +static struct rtl_hal_ops rtl8822be_hal_ops = { + .init_sw_vars = rtl8822be_init_sw_vars, + .deinit_sw_vars = rtl8822be_deinit_sw_vars, + .read_eeprom_info = rtl8822be_read_eeprom_info_dummy, + .interrupt_recognized = rtl8822be_interrupt_recognized, + .hw_init = rtl8822be_hw_init, + .hw_disable = rtl8822be_card_disable, + .hw_suspend = rtl8822be_suspend, + .hw_resume = rtl8822be_resume, + .enable_interrupt = rtl8822be_enable_interrupt, + .disable_interrupt = rtl8822be_disable_interrupt, + .set_network_type = rtl8822be_set_network_type, + .set_chk_bssid = rtl8822be_set_check_bssid, + .set_qos = rtl8822be_set_qos, + .set_bcn_reg = rtl8822be_set_beacon_related_registers, + .set_bcn_intv = rtl8822be_set_beacon_interval, + .update_interrupt_mask = rtl8822be_update_interrupt_mask, + .get_hw_reg = rtl8822be_get_hw_reg, + .set_hw_reg = rtl8822be_set_hw_reg, + .update_rate_tbl = rtl8822be_update_hal_rate_tbl, + .pre_fill_tx_bd_desc = rtl8822be_pre_fill_tx_bd_desc, + .rx_desc_buff_remained_cnt = rtl8822be_rx_desc_buff_remained_cnt, + .rx_check_dma_ok = rtl8822be_rx_check_dma_ok, + .fill_tx_desc = rtl8822be_tx_fill_desc, + .fill_tx_special_desc = rtl8822be_tx_fill_special_desc, + .query_rx_desc = rtl8822be_rx_query_desc, + .radio_onoff_checking = rtl8822be_gpio_radio_on_off_checking, + .switch_channel = rtl8822be_phy_sw_chnl, + .set_channel_access = rtl8822be_update_channel_access_setting, + .set_bw_mode = rtl8822be_phy_set_bw_mode, + .dm_watchdog = rtl8822be_phydm_watchdog, + .scan_operation_backup = rtl8822be_phy_scan_operation_backup, + .set_rf_power_state = rtl8822be_phy_set_rf_power_state, + .led_control = rtl8822be_led_control, + .set_desc = rtl8822be_set_desc, + .get_desc = rtl8822be_get_desc, + .is_tx_desc_closed = rtl8822be_is_tx_desc_closed, + .get_available_desc = rtl8822be_get_available_desc, + .tx_polling = rtl8822be_tx_polling, + .enable_hw_sec = rtl8822be_enable_hw_security_config, + .set_key = rtl8822be_set_key, + .init_sw_leds = rtl8822be_init_sw_leds, + .get_bbreg = rtl8822be_phy_query_bb_reg, + .set_bbreg = rtl8822be_phy_set_bb_reg, + .get_rfreg = rtl8822be_phy_query_rf_reg, + .set_rfreg = rtl8822be_phy_set_rf_reg, + .fill_h2c_cmd = rtl8822be_fill_h2c_cmd, + .set_default_port_id_cmd = rtl8822be_set_default_port_id_cmd, + .get_btc_status = rtl8822be_get_btc_status, + .rx_command_packet = rtl8822be_rx_command_packet, + .c2h_content_parsing = rtl8822be_c2h_content_parsing, + /* ops for halmac cb */ + .halmac_cb_init_mac_register = rtl8822be_halmac_cb_init_mac_register, + .halmac_cb_init_bb_rf_register = + rtl8822be_halmac_cb_init_bb_rf_register, + .halmac_cb_write_data_rsvd_page = + rtl8822b_halmac_cb_write_data_rsvd_page, + .halmac_cb_write_data_h2c = rtl8822b_halmac_cb_write_data_h2c, + /* ops for phydm cb */ + .get_txpower_index = rtl8822be_get_txpower_index, + .set_tx_power_index_by_rs = rtl8822be_phy_set_tx_power_index_by_rs, + .store_tx_power_by_rate = rtl8822be_store_tx_power_by_rate, + .phy_set_txpower_limit = rtl8822be_phy_set_txpower_limit, +}; + +static struct rtl_mod_params rtl8822be_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = true, + .msi_support = true, + .dma64 = false, + .aspm_support = 1, + .disable_watchdog = false, + .debug_level = 0, + .debug_mask = 0, +}; + +static struct rtl_hal_cfg rtl8822be_hal_cfg = { + .bar_id = 2, + .write_readback = false, + .name = "rtl8822be_pci", + .ops = &rtl8822be_hal_ops, + .mod_params = &rtl8822be_mod_params, + .spec_ver = RTL_SPEC_NEW_RATEID | RTL_SPEC_SUPPORT_VHT | + RTL_SPEC_NEW_FW_C2H, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL_8822B, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN_8822B, + .maps[SYS_CLK] = REG_SYS_CLK_CTRL_8822B, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR0_8822B, + .maps[MAC_HIMRE] = REG_HIMR1_8822B, + + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS_8822B, + + .maps[EFUSE_TEST] = REG_LDO_EFUSE_CTRL_8822B, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL_8822B, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL_8822B, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD_8822B, + .maps[WCAMI] = REG_CAMWRITE_8822B, + .maps[RCAMO] = REG_CAMREAD_8822B, + .maps[CAMDBG] = REG_CAMDBG_8822B, + .maps[SECR] = REG_SECCFG_8822B, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + /* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/ + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + /* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/ + /* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/ + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_H2CDOK] = IMR_H2CDOK, + .maps[RTL_IMR_BDOK] = IMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, + + /*VHT hightest rate*/ + .maps[RTL_RC_VHT_RATE_1SS_MCS7] = DESC_RATEVHT1SS_MCS7, + .maps[RTL_RC_VHT_RATE_1SS_MCS8] = DESC_RATEVHT1SS_MCS8, + .maps[RTL_RC_VHT_RATE_1SS_MCS9] = DESC_RATEVHT1SS_MCS9, + .maps[RTL_RC_VHT_RATE_2SS_MCS7] = DESC_RATEVHT2SS_MCS7, + .maps[RTL_RC_VHT_RATE_2SS_MCS8] = DESC_RATEVHT2SS_MCS8, + .maps[RTL_RC_VHT_RATE_2SS_MCS9] = DESC_RATEVHT2SS_MCS9, +}; + +static const struct pci_device_id rtl8822be_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822, rtl8822be_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8822be_pci_ids); + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8822BE 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8822befw.bin"); + +module_param_named(swenc, rtl8822be_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl8822be_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8822be_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl8822be_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl8822be_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl8822be_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl8822be_mod_params.msi_support, bool, 0444); +module_param_named(dma64, rtl8822be_mod_params.dma64, bool, 0444); +module_param_named(aspm, rtl8822be_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl8822be_mod_params.disable_watchdog, + bool, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); +MODULE_PARM_DESC(dma64, "Set to 1 to use DMA 64 (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, + "Set to 1 to disable the watchdog (default 0)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl8822be_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8822be_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl8822be_driver); diff --git a/drivers/staging/rtlwifi/rtl8822be/sw.h b/drivers/staging/rtlwifi/rtl8822be/sw.h new file mode 100644 index 0000000000000000000000000000000000000000..931eba98bd809a29bfec12d1b22cd2f8fd932752 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/sw.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_SW_H__ +#define __RTL8822B_SW_H__ + +int rtl8822be_init_sw_vars(struct ieee80211_hw *hw); +void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw); +bool rtl8822be_get_btc_status(void); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/trx.c b/drivers/staging/rtlwifi/rtl8822be/trx.c new file mode 100644 index 0000000000000000000000000000000000000000..38f80e48a399b4cbafa764829f5e8cbc059ee942 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/trx.c @@ -0,0 +1,1015 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" +#include "fw.h" + +#include + +static u8 _rtl8822be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + switch (hw_queue) { + case BEACON_QUEUE: + return QSLT_BEACON; + case H2C_QUEUE: + return QSLT_CMD; + case MGNT_QUEUE: + return QSLT_MGNT; + case HIGH_QUEUE: + return QSLT_HIGH; + default: + return skb->priority; + } +} + +static void _rtl8822be_query_rxphystatus(struct ieee80211_hw *hw, u8 *phystrpt, + struct ieee80211_hdr *hdr, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->phydm.ops->phydm_query_phy_status(rtlpriv, phystrpt, hdr, + pstatus); + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + pstatus->signalstrength = + (u8)(rtl_signal_scale_mapping(hw, pstatus->rx_pwdb_all)); +} + +static void _rtl8822be_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, + u8 *p_phystrpt) +{ + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift + + 24; + + hdr = (struct ieee80211_hdr *)tmp_buf; + + /* query phy status */ + _rtl8822be_query_rxphystatus(hw, p_phystrpt, hdr, pstatus); + + /* packet statistics */ + if (pstatus->packet_beacon && pstatus->packet_matchbssid) + rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++; + + if (pstatus->packet_matchbssid && + ieee80211_is_data_qos(hdr->frame_control) && + !is_multicast_ether_addr(ieee80211_get_DA(hdr))) { + struct ieee80211_qos_hdr *hdr_qos = + (struct ieee80211_qos_hdr *)tmp_buf; + u16 tid = le16_to_cpu(hdr_qos->qos_ctrl) & 0xf; + + if (tid != 0 && tid != 3) + rtl_priv(hw)->dm.dbginfo.num_non_be_pkt++; + } + + /* signal statistics */ + if (p_phystrpt) + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void _rtl8822be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + u8 *virtualaddress) +{ + u32 dwtmp = 0; + + memset(virtualaddress, 0, 8); + + SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num); + if (ptcb_desc->empkt_num == 1) { + dwtmp = ptcb_desc->empkt_len[0]; + } else { + dwtmp = ptcb_desc->empkt_len[0]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[1]; + } + SET_EARLYMODE_LEN0(virtualaddress, dwtmp); + + if (ptcb_desc->empkt_num <= 3) { + dwtmp = ptcb_desc->empkt_len[2]; + } else { + dwtmp = ptcb_desc->empkt_len[2]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[3]; + } + SET_EARLYMODE_LEN1(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 5) { + dwtmp = ptcb_desc->empkt_len[4]; + } else { + dwtmp = ptcb_desc->empkt_len[4]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[5]; + } + SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF); + SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4); + if (ptcb_desc->empkt_num <= 7) { + dwtmp = ptcb_desc->empkt_len[6]; + } else { + dwtmp = ptcb_desc->empkt_len[6]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[7]; + } + SET_EARLYMODE_LEN3(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 9) { + dwtmp = ptcb_desc->empkt_len[8]; + } else { + dwtmp = ptcb_desc->empkt_len[8]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[9]; + } + SET_EARLYMODE_LEN4(virtualaddress, dwtmp); +} + +static bool rtl8822be_get_rxdesc_is_ht(struct ieee80211_hw *hw, u8 *pdesc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rx_rate = 0; + + rx_rate = GET_RX_DESC_RX_RATE(pdesc); + + RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate); + + if ((rx_rate >= DESC_RATEMCS0) && (rx_rate <= DESC_RATEMCS15)) + return true; + else + return false; +} + +static bool rtl8822be_get_rxdesc_is_vht(struct ieee80211_hw *hw, u8 *pdesc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rx_rate = 0; + + rx_rate = GET_RX_DESC_RX_RATE(pdesc); + + RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate); + + if (rx_rate >= DESC_RATEVHT1SS_MCS0) + return true; + else + return false; +} + +static u8 rtl8822be_get_rx_vht_nss(struct ieee80211_hw *hw, u8 *pdesc) +{ + u8 rx_rate = 0; + u8 vht_nss = 0; + + rx_rate = GET_RX_DESC_RX_RATE(pdesc); + + if ((rx_rate >= DESC_RATEVHT1SS_MCS0) && + (rx_rate <= DESC_RATEVHT1SS_MCS9)) + vht_nss = 1; + else if ((rx_rate >= DESC_RATEVHT2SS_MCS0) && + (rx_rate <= DESC_RATEVHT2SS_MCS9)) + vht_nss = 2; + + return vht_nss; +} + +bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, u8 *pdesc, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *p_phystrpt = NULL; + struct ieee80211_hdr *hdr; + + u32 phystatus = GET_RX_DESC_PHYST(pdesc); + + if (GET_RX_DESC_C2H(pdesc) == 0) + status->packet_report_type = NORMAL_RX; + else + status->packet_report_type = C2H_PACKET; + + status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc); + status->rx_drvinfo_size = + (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) * RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(GET_RX_DESC_SHIFT(pdesc) & 0x03); + status->icv = (u16)GET_RX_DESC_ICV_ERR(pdesc); + status->crc = (u16)GET_RX_DESC_CRC32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !GET_RX_DESC_SWDEC(pdesc); + status->rate = (u8)GET_RX_DESC_RX_RATE(pdesc); + status->isampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1); + status->isfirst_ampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1); + status->timestamp_low = GET_RX_DESC_TSFL(pdesc); + status->is_ht = rtl8822be_get_rxdesc_is_ht(hw, pdesc); + status->is_vht = rtl8822be_get_rxdesc_is_vht(hw, pdesc); + status->vht_nss = rtl8822be_get_rx_vht_nss(hw, pdesc); + status->is_cck = RX_HAL_IS_CCK_RATE(status->rate); + + status->macid = GET_RX_DESC_MACID(pdesc); + if (GET_RX_DESC_PATTERN_MATCH(pdesc)) + status->wake_match = BIT(2); + else if (GET_RX_DESC_MAGIC_WAKE(pdesc)) + status->wake_match = BIT(1); + else if (GET_RX_DESC_UNICAST_WAKE(pdesc)) + status->wake_match = BIT(0); + else + status->wake_match = 0; + if (status->wake_match) + RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", + status->wake_match); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + if (phystatus) + p_phystrpt = (skb->data + status->rx_bufshift + 24); + + hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + + status->rx_bufshift + 24); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + if (status->is_vht) + rx_status->encoding = RX_ENC_VHT; + + rx_status->nss = status->vht_nss; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + */ + /* So hw will not decryption robust management frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + */ + /* Notice: this is diff with windows define */ + rx_status->rate_idx = rtlwifi_rate_mapping( + hw, status->is_ht, status->is_vht, status->rate); + + rx_status->mactime = status->timestamp_low; + + _rtl8822be_translate_rx_signal_stuff(hw, skb, status, p_phystrpt); + + /* below info. are filled by _rtl8822be_translate_rx_signal_stuff() */ + if (!p_phystrpt) + goto label_no_physt; + + rx_status->signal = status->recvsignalpower; + + if (status->rx_packet_bw == HT_CHANNEL_WIDTH_20_40) + rx_status->bw = RATE_INFO_BW_40; + else if (status->rx_packet_bw == HT_CHANNEL_WIDTH_80) + rx_status->bw = RATE_INFO_BW_80; + +label_no_physt: + + return true; +} + +void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 first_seg; + u8 last_seg; + u16 total_len; + u16 read_cnt = 0; + + if (!header_desc) + return; + + do { + total_len = (u16)GET_RX_BUFFER_DESC_TOTAL_LENGTH(header_desc); + first_seg = (u8)GET_RX_BUFFER_DESC_FS(header_desc); + last_seg = (u8)GET_RX_BUFFER_DESC_LS(header_desc); + + if (read_cnt++ > 20) { + RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, + "RX chk DMA over %d times\n", read_cnt); + break; + } + + } while (total_len == 0 && first_seg == 0 && last_seg == 0); +} + +u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 desc_idx_hw = 0, desc_idx_host = 0, remind_cnt = 0; + u32 tmp_4byte = 0; + + u32 rw_mask = 0x1ff; + + tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_RXBD_IDX_8822B); + desc_idx_hw = (u16)((tmp_4byte >> 16) & rw_mask); + desc_idx_host = (u16)(tmp_4byte & rw_mask); + + /* may be no data, donot rx */ + if (desc_idx_hw == desc_idx_host) + return 0; + + remind_cnt = + (desc_idx_hw > desc_idx_host) ? + (desc_idx_hw - desc_idx_host) : + (RX_DESC_NUM_8822BE - (desc_idx_host - desc_idx_hw)); + + rtlpci->rx_ring[queue_index].next_rx_rp = desc_idx_host; + + return remind_cnt; +} + +static u16 get_desc_address_from_queue_index(u16 queue_index) +{ + /* + * Note: Access these registers will take a lot of cost. + */ + u16 desc_address = REG_BEQ_TXBD_IDX_8822B; + + switch (queue_index) { + case BK_QUEUE: + desc_address = REG_BKQ_TXBD_IDX_8822B; + break; + case BE_QUEUE: + desc_address = REG_BEQ_TXBD_IDX_8822B; + break; + case VI_QUEUE: + desc_address = REG_VIQ_TXBD_IDX_8822B; + break; + case VO_QUEUE: + desc_address = REG_VOQ_TXBD_IDX_8822B; + break; + case BEACON_QUEUE: + desc_address = REG_BEQ_TXBD_IDX_8822B; + break; + case H2C_QUEUE: + desc_address = REG_H2CQ_TXBD_IDX_8822B; + break; + case MGNT_QUEUE: + desc_address = REG_MGQ_TXBD_IDX_8822B; + break; + case HIGH_QUEUE: + desc_address = REG_HI0Q_TXBD_IDX_8822B; + break; + case HCCA_QUEUE: + desc_address = REG_BEQ_TXBD_IDX_8822B; + break; + default: + break; + } + return desc_address; +} + +/*free desc that can be used */ +u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx]; + + return calc_fifo_space(ring->cur_tx_rp, ring->cur_tx_wp, + TX_DESC_NUM_8822B); +} + +void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc, + u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t data_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 pkt_len = skb->len; + u16 desc_size = 48; /*tx desc size*/ + u32 psblen = 0; + u32 total_packet_size = 0; + u16 current_bd_desc; + u8 i = 0; + /*u16 real_desc_size = 0x28;*/ + u16 append_early_mode_size = 0; + u8 segmentnum = 1 << (RTL8822BE_SEG_NUM + 1); + dma_addr_t desc_dma_addr; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + + current_bd_desc = rtlpci->tx_ring[queue_index].cur_tx_wp; + + total_packet_size = desc_size + pkt_len; + + if (rtlpriv->rtlhal.earlymode_enable) { + if (queue_index < BEACON_QUEUE) { + append_early_mode_size = 8; + total_packet_size += append_early_mode_size; + } + } + + /* page number (round up) */ + psblen = (total_packet_size - 1) / 128 + 1; + + /* tx desc addr */ + desc_dma_addr = rtlpci->tx_ring[queue_index].dma + + (current_bd_desc * TX_DESC_SIZE); + + /* Reset */ + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, 0); + SET_TX_BUFF_DESC_PSB(tx_bd_desc, 0); + SET_TX_BUFF_DESC_OWN(tx_bd_desc, 0); + + for (i = 1; i < segmentnum; i++) { + SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, i, 0); + SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, i, 0); + SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, i, 0); + SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, i, 0, dma64); + } + + /* Clear all status */ + CLEAR_PCI_TX_DESC_CONTENT(desc, TX_DESC_SIZE); + + if (rtlpriv->rtlhal.earlymode_enable) { + if (queue_index < BEACON_QUEUE) + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size + 8); + else + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size); + } else { + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size); + } + SET_TX_BUFF_DESC_PSB(tx_bd_desc, psblen); + SET_TX_BUFF_DESC_ADDR_LOW_0(tx_bd_desc, desc_dma_addr); + SET_TX_BUFF_DESC_ADDR_HIGH_0(tx_bd_desc, ((u64)desc_dma_addr >> 32), + dma64); + + SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, 1, pkt_len); + SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, 1, 0); + SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, 1, data_addr); + SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, 1, + ((u64)data_addr >> 32), dma64); + + SET_TX_DESC_TXPKTSIZE(desc, (u16)(pkt_len)); +} + +static u8 rtl8822be_bw_mapping(struct ieee80211_hw *hw, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw_setting_of_desc = 0; + + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + "%s, current_chan_bw %d, packet_bw %d\n", __func__, + rtlphy->current_chan_bw, ptcb_desc->packet_bw); + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) + bw_setting_of_desc = 2; + else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) + bw_setting_of_desc = 1; + else + bw_setting_of_desc = 0; + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if ((ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) || + (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80)) + bw_setting_of_desc = 1; + else + bw_setting_of_desc = 0; + } else { + bw_setting_of_desc = 0; + } + + return bw_setting_of_desc; +} + +static u8 rtl8822be_sc_mapping(struct ieee80211_hw *hw, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 sc_setting_of_desc = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) + sc_setting_of_desc = + VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) + sc_setting_of_desc = + VHT_DATA_SC_40_UPPER_OF_80MHZ; + else + RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, + "%s: Not Correct Primary40MHz Setting\n", + __func__); + } else { + if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_setting_of_desc = + VHT_DATA_SC_20_LOWEST_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_setting_of_desc = + VHT_DATA_SC_20_LOWER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_setting_of_desc = + VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_setting_of_desc = + VHT_DATA_SC_20_UPPERST_OF_80MHZ; + else + RT_TRACE( + rtlpriv, COMP_SEND, DBG_LOUD, + "rtl8822be_sc_mapping: Not Correct Primary40MHz Setting\n"); + } + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20) { + if (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) { + sc_setting_of_desc = + VHT_DATA_SC_20_UPPER_OF_80MHZ; + } else if (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) { + sc_setting_of_desc = + VHT_DATA_SC_20_LOWER_OF_80MHZ; + } else { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } + } + } else { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } + + return sc_setting_of_desc; +} + +void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + u8 *pdesc_tx, u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 *pdesc = (u8 *)pdesc_tx; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 fw_qsel = _rtl8822be_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = + ((hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 short_gi = 0; + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error"); + return; + } + + if (pbd_desc_tx) + rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc_tx, pdesc, hw_queue, + skb, mapping); + + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + SET_TX_DESC_PKT_OFFSET(pdesc, 1); + SET_TX_DESC_OFFSET(pdesc, + USB_HWDESC_HEADER_LEN + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + _rtl8822be_insert_emcontent(ptcb_desc, + (u8 *)(skb->data)); + } + } else { + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + } + + /* tx report */ + rtl_get_tx_report(ptcb_desc, pdesc, hw); + + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G && + ptcb_desc->hw_rate < DESC_RATE6M) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_WARNING, + "hw_rate=0x%X is invalid in 5G\n", + ptcb_desc->hw_rate); + ptcb_desc->hw_rate = DESC_RATE6M; + } + SET_TX_DESC_DATARATE(pdesc, ptcb_desc->hw_rate); + + if (ptcb_desc->hw_rate > DESC_RATEMCS0) + short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; + else + short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + SET_TX_DESC_AGG_EN(pdesc, 1); + SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x1F); + } + SET_TX_DESC_SW_SEQ(pdesc, seq_number); + SET_TX_DESC_RTSEN(pdesc, ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? + 1 : + 0)); + SET_TX_DESC_HW_RTS_EN(pdesc, 0); + SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); + + SET_TX_DESC_RTSRATE(pdesc, ptcb_desc->rts_rate); + SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); + SET_TX_DESC_RTS_SHORT( + pdesc, + ((ptcb_desc->rts_rate <= DESC_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + if (ptcb_desc->tx_enable_sw_calc_duration) + SET_TX_DESC_NAVUSEHDR(pdesc, 1); + + SET_TX_DESC_DATA_BW(pdesc, rtl8822be_bw_mapping(hw, ptcb_desc)); + SET_TX_DESC_DATA_SC(pdesc, rtl8822be_sc_mapping(hw, ptcb_desc)); + + if (sta) { + u8 ampdu_density = sta->ht_cap.ampdu_density; + + SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *key = info->control.hw_key; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(pdesc, 0x0); + break; + } + } + + SET_TX_DESC_QSEL(pdesc, fw_qsel); + + if (rtlphy->current_channel > 14) { + /* OFDM 6M */ + SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 4); + SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 4); + } else { + /* CCK 1M */ + SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 0); + SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 0); + } + SET_TX_DESC_DISDATAFB(pdesc, + ptcb_desc->disable_ratefallback ? 1 : 0); + SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /*SET_TX_DESC_PWR_STATUS(pdesc, pwr_status);*/ + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (!ptcb_desc->use_driver_rate) { + /*SET_TX_DESC_RTS_RATE(pdesc, 0x08); */ + /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */ + } + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + SET_TX_DESC_RDG_EN(pdesc, 1); + SET_TX_DESC_HTC(pdesc, 1); + } + } + + SET_TX_DESC_PORT_ID(pdesc, 0); + SET_TX_DESC_MULTIPLE_PORT(pdesc, 0); + } + + SET_TX_DESC_LS(pdesc, (lastseg ? 1 : 0)); + if (rtlpriv->dm.useramask) { + SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index); + SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); + } else { + SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index); + SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index); + } + + SET_TX_DESC_MOREFRAG(pdesc, (lastseg ? 0 : 1)); + if (ptcb_desc->multicast || ptcb_desc->broadcast) { + SET_TX_DESC_BMC(pdesc, 1); + /* BMC must be not AGG */ + SET_TX_DESC_AGG_EN(pdesc, 0); + } + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); + + /* debug purpose: used to check tx desc is correct or not */ + /*rtlpriv->halmac.ops->halmac_chk_txdesc(rtlpriv, pdesc, + * skb->len + USB_HWDESC_HEADER_LEN); + */ +} + +void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc, + u8 *pbd_desc, struct sk_buff *skb, + u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue; + u8 txdesc_len = 48; + + dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + + if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error"); + return; + } + + rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc, pdesc, hw_queue, skb, + mapping); + + /* it should be BEACON_QUEUE or H2C_QUEUE, + * so skb=NULL is safe to assert + */ + fw_queue = _rtl8822be_map_hwqueue_to_fwqueue(NULL, hw_queue); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, txdesc_len); + + /* common part for BEACON and H2C */ + SET_TX_DESC_TXPKTSIZE((u8 *)pdesc, (u16)(skb->len)); + + SET_TX_DESC_QSEL(pdesc, fw_queue); + + if (hw_queue == H2C_QUEUE) { + /* fill H2C */ + SET_TX_DESC_OFFSET(pdesc, 0); + + } else { + /* fill beacon */ + SET_TX_DESC_OFFSET(pdesc, txdesc_len); + + SET_TX_DESC_DATARATE(pdesc, DESC_RATE1M); + + SET_TX_DESC_SW_SEQ(pdesc, 0); + + SET_TX_DESC_RATE_ID(pdesc, 7); + SET_TX_DESC_MACID(pdesc, 0); + + SET_TX_DESC_LS(pdesc, 1); + + SET_TX_DESC_OFFSET(pdesc, 48); + + SET_TX_DESC_USE_RATE(pdesc, 1); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", + pdesc, txdesc_len); +} + +void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 q_idx = *val; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: { + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx]; + u16 max_tx_desc = ring->entries; + + if (q_idx == BEACON_QUEUE) { + /* in case of beacon, pdesc is BD desc. */ + u8 *pbd_desc = pdesc; + + ring->cur_tx_wp = 0; + ring->cur_tx_rp = 0; + SET_TX_BUFF_DESC_OWN(pbd_desc, 1); + return; + } + + /* make sure tx desc is available by caller */ + ring->cur_tx_wp = ((ring->cur_tx_wp + 1) % max_tx_desc); + + rtl_write_word( + rtlpriv, + get_desc_address_from_queue_index( + q_idx), + ring->cur_tx_wp); + } break; + } + } else { + switch (desc_name) { + case HW_DESC_RX_PREPARE: + SET_RX_BUFFER_DESC_LS(pdesc, 0); + SET_RX_BUFFER_DESC_FS(pdesc, 0); + SET_RX_BUFFER_DESC_TOTAL_LENGTH(pdesc, 0); + + SET_RX_BUFFER_DESC_DATA_LENGTH( + pdesc, MAX_RECEIVE_BUFFER_SIZE + RX_DESC_SIZE); + + SET_RX_BUFFER_PHYSICAL_LOW( + pdesc, (*(dma_addr_t *)val) & DMA_BIT_MASK(32)); + SET_RX_BUFFER_PHYSICAL_HIGH( + pdesc, ((u64)(*(dma_addr_t *)val) >> 32), + dma64); + break; + default: + WARN_ONCE(true, "ERR rxdesc :%d not process\n", + desc_name); + break; + } + } +} + +u64 rtl8822be_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u64 ret = 0; + u8 *pbd_desc = pdesc; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + + if (istx) { + switch (desc_name) { + case HW_DESC_TXBUFF_ADDR: + ret = GET_TXBUFFER_DESC_ADDR_LOW(pbd_desc, 1); + ret |= (u64)GET_TXBUFFER_DESC_ADDR_HIGH(pbd_desc, 1, + dma64) << 32; + break; + default: + WARN_ONCE(true, "ERR txdesc :%d not process\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXPKT_LEN: + ret = GET_RX_DESC_PKT_LEN(pdesc); + break; + default: + WARN_ONCE(true, "ERR rxdesc :%d not process\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, + u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool ret = false; + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u16 cur_tx_rp, cur_tx_wp; + u16 tmp16; + + /* + * design rule: + * idx <= cur_tx_rp <= hw_rp <= cur_tx_wp = hw_wp + */ + + if (index == ring->cur_tx_rp) { + /* update only if sw_rp reach hw_rp */ + tmp16 = rtl_read_word( + rtlpriv, + get_desc_address_from_queue_index(hw_queue) + 2); + + cur_tx_rp = tmp16 & 0x01ff; + cur_tx_wp = ring->cur_tx_wp; + + /* don't need to update ring->cur_tx_wp */ + ring->cur_tx_rp = cur_tx_rp; + } + + if (index == ring->cur_tx_rp) + ret = false; /* no more */ + else + ret = true; /* more */ + + if (hw_queue == BEACON_QUEUE) + ret = true; + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) + ret = true; + + return ret; +} + +void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (hw_queue == BEACON_QUEUE) { + /* kick start */ + rtl_write_byte( + rtlpriv, REG_RX_RXBD_NUM_8822B + 1, + rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1) | + BIT(4)); + } +} + +u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw, + const struct rtl_stats *status, + struct sk_buff *skb) +{ + u32 result = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (status->packet_report_type) { + case NORMAL_RX: + result = 0; + break; + case C2H_PACKET: + rtl8822be_c2h_packet_handler(hw, skb->data, (u8)skb->len); + result = 1; + break; + default: + RT_TRACE(rtlpriv, COMP_RECV, DBG_TRACE, + "Unknown packet type %d\n", + status->packet_report_type); + break; + } + + return result; +} diff --git a/drivers/staging/rtlwifi/rtl8822be/trx.h b/drivers/staging/rtlwifi/rtl8822be/trx.h new file mode 100644 index 0000000000000000000000000000000000000000..db769f3c4cd6852e7ab4cdf0e6c270b7e1ac4a08 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/trx.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_TRX_H__ +#define __RTL8822B_TRX_H__ + +#include "../halmac/halmac_tx_desc_nic.h" +#include "../halmac/halmac_rx_desc_nic.h" + +#define TX_DESC_SIZE 64 + +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 48 +#define USB_HWDESC_HEADER_LEN 48 + +#define RX_DESC_SIZE 24 +#define MAX_RECEIVE_BUFFER_SIZE 8192 + +#define SET_EARLYMODE_PKTNUM(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __val) +#define SET_EARLYMODE_LEN0(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 4, 15, __val) +#define SET_EARLYMODE_LEN1(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 16, 2, __val) +#define SET_EARLYMODE_LEN1_1(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 19, 13, __val) +#define SET_EARLYMODE_LEN1_2(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 2, __val) +#define SET_EARLYMODE_LEN2(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 2, 15, __val) +#define SET_EARLYMODE_LEN2_1(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 2, 4, __val) +#define SET_EARLYMODE_LEN2_2(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 8, __val) +#define SET_EARLYMODE_LEN3(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 17, 15, __val) +#define SET_EARLYMODE_LEN4(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 20, 12, __val) + +/* TX/RX buffer descriptor */ + +/* for Txfilldescroptor8822be, fill the desc content. */ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pdesc, __offset, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 0, 16, __val) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pdesc, __offset, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 31, 1, __val) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pdesc, __offset, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32, __val) +#define SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(pbd, off, val, dma64) \ + (dma64 ? SET_BITS_TO_LE_4BYTE((pbd) + ((off) * 16) + 8, 0, 32, val) : 0) +#define GET_TXBUFFER_DESC_ADDR_LOW(__pdesc, __offset) \ + LE_BITS_TO_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32) +#define GET_TXBUFFER_DESC_ADDR_HIGH(pbd, off, dma64) \ + (dma64 ? LE_BITS_TO_4BYTE((pbd) + ((off) * 16) + 8, 0, 32) : 0) + +/* Dword 0 */ +#define SET_TX_BUFF_DESC_LEN_0(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) +#define SET_TX_BUFF_DESC_PSB(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 16, 15, __val) +#define SET_TX_BUFF_DESC_OWN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +/* Dword 1 */ +#define SET_TX_BUFF_DESC_ADDR_LOW_0(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + 4, 0, 32, __val) +/* Dword 2 */ +#define SET_TX_BUFF_DESC_ADDR_HIGH_0(bdesc, val, dma64) \ + SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(bdesc, 0, val, dma64) +/* Dword 3 / RESERVED 0 */ + +/* RX buffer */ + +/* DWORD 0 */ +#define SET_RX_BUFFER_DESC_DATA_LENGTH(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 0, 14, __val) +#define SET_RX_BUFFER_DESC_LS(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 15, 1, __val) +#define SET_RX_BUFFER_DESC_FS(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 1, __val) +#define SET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 15, __val) + +#define GET_RX_BUFFER_DESC_OWN(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 31, 1) +#define GET_RX_BUFFER_DESC_LS(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 15, 1) +#define GET_RX_BUFFER_DESC_FS(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 16, 1) +#define GET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 16, 15) + +/* DWORD 1 */ +#define SET_RX_BUFFER_PHYSICAL_LOW(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc + 4, 0, 32, __val) + +/* DWORD 2 */ +#define SET_RX_BUFFER_PHYSICAL_HIGH(__rx_status_desc, __val, dma64) \ + (dma64 ? SET_BITS_TO_LE_4BYTE((__rx_status_desc) + 8, 0, 32, __val) : 0) + +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ + do { \ + if (_size > TX_DESC_NEXT_DESC_OFFSET) \ + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ + else \ + memset(__pdesc, 0, _size); \ + } while (0) + +void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index); +u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, + u8 queue_index); +u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 queue_index); +void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc, + u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t addr); + +void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + u8 *pdesc_tx, u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc, + u8 *pbd_desc, struct sk_buff *skb, + u8 hw_queue); +bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, u8 *pdesc, + struct sk_buff *skb); +void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); +u64 rtl8822be_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, + u16 index); +void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl8822be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + bool firstseg, bool lastseg, + struct sk_buff *skb); +u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw, + const struct rtl_stats *status, + struct sk_buff *skb); +#endif diff --git a/drivers/staging/rtlwifi/stats.c b/drivers/staging/rtlwifi/stats.c new file mode 100644 index 0000000000000000000000000000000000000000..96eb14c92c011b28254a099f92b5a93ecca320d4 --- /dev/null +++ b/drivers/staging/rtlwifi/stats.c @@ -0,0 +1,260 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#include "wifi.h" +#include "stats.h" +#include + +u8 rtl_query_rxpwrpercentage(s8 antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} + +u8 rtl_evm_db_to_percentage(s8 value) +{ + s8 ret_val = clamp(-value, 0, 33) * 3; + + if (ret_val == 99) + ret_val = 100; + + return ret_val; +} + +static long rtl_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + + return retsig; +} + +static void rtl_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rfpath; + u32 last_rssi, tmpval; + + if (!pstatus->packet_toself && !pstatus->packet_beacon) + return; + + rtlpriv->stats.pwdb_all_cnt += pstatus->rx_pwdb_all; + rtlpriv->stats.rssi_calculate_cnt++; + + if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = rtlpriv->stats.ui_rssi.elements[ + rtlpriv->stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = + pstatus->signalstrength; + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, (u8)tmpval); + pstatus->rssi = rtlpriv->stats.signal_strength; + + if (pstatus->is_cck) + return; + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstatus->rx_mimo_signalstrength[rfpath]; + } + if (pstatus->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + rtlpriv->stats.rx_snr_db[rfpath] = pstatus->rx_snr[rfpath]; + rtlpriv->stats.rx_evm_dbm[rfpath] = + pstatus->rx_mimo_evm_dbm[rfpath]; + rtlpriv->stats.rx_cfo_short[rfpath] = + pstatus->cfo_short[rfpath]; + rtlpriv->stats.rx_cfo_tail[rfpath] = pstatus->cfo_tail[rfpath]; + } +} + +static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; + if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * + 5 + pstatus->recvsignalpower + weighting) / 6; +} + +static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *drv_priv = NULL; + struct ieee80211_sta *sta = NULL; + long undec_sm_pwdb; + + rcu_read_lock(); + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + sta = rtl_find_sta(hw, pstatus->psaddr); + + /* adhoc or ap mode */ + if (sta) { + drv_priv = (struct rtl_sta_info *)sta->drv_priv; + undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + } + + if (undec_sm_pwdb < 0) + undec_sm_pwdb = pstatus->rx_pwdb_all; + if (pstatus->rx_pwdb_all > (u32)undec_sm_pwdb) { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undec_sm_pwdb = undec_sm_pwdb + 1; + } else { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + + if (sta) + drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; + else + rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rcu_read_unlock(); + + rtl_update_rxsignalstatistics(hw, pstatus); +} + +static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm, n_stream, tmpval; + + if (pstatus->signalquality == 0) + return; + + if (rtlpriv->stats.ui_link_quality.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.ui_link_quality.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index]; + rtlpriv->stats.ui_link_quality.total_val -= last_evm; + } + rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; + rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index++] = + pstatus->signalquality; + if (rtlpriv->stats.ui_link_quality.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.ui_link_quality.index = 0; + tmpval = rtlpriv->stats.ui_link_quality.total_val / + rtlpriv->stats.ui_link_quality.total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + for (n_stream = 0; n_stream < 2; n_stream++) { + if (pstatus->rx_mimo_sig_qual[n_stream] != -1) { + if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { + rtlpriv->stats.rx_evm_percentage[n_stream] = + pstatus->rx_mimo_sig_qual[n_stream]; + } + rtlpriv->stats.rx_evm_percentage[n_stream] = + ((rtlpriv->stats.rx_evm_percentage[n_stream] + * (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_sig_qual[n_stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } +} + +void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, + struct rtl_stats *pstatus) +{ + if (!pstatus->packet_matchbssid) + return; + + rtl_process_ui_rssi(hw, pstatus); + rtl_process_pwdb(hw, pstatus); + rtl_process_ui_link_quality(hw, pstatus); +} diff --git a/drivers/staging/rtlwifi/stats.h b/drivers/staging/rtlwifi/stats.h new file mode 100644 index 0000000000000000000000000000000000000000..bd0108f93182b76ba7b04d81a0dc67e8ed964eb8 --- /dev/null +++ b/drivers/staging/rtlwifi/stats.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_STATS_H__ +#define __RTL_STATS_H__ + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +/* Rx smooth factor */ +#define RX_SMOOTH_FACTOR 20 + +u8 rtl_query_rxpwrpercentage(s8 antpower); +u8 rtl_evm_db_to_percentage(s8 value); +long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); +void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, + struct rtl_stats *pstatus); + +#endif diff --git a/drivers/staging/rtlwifi/wifi.h b/drivers/staging/rtlwifi/wifi.h new file mode 100644 index 0000000000000000000000000000000000000000..eb91c130b245cbf766d5d6e78c625a9216ac0891 --- /dev/null +++ b/drivers/staging/rtlwifi/wifi.h @@ -0,0 +1,3375 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_WIFI_H__ +#define __RTL_WIFI_H__ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define RF_CHANGE_BY_INIT 0 +#define RF_CHANGE_BY_IPS BIT(28) +#define RF_CHANGE_BY_PS BIT(29) +#define RF_CHANGE_BY_HW BIT(30) +#define RF_CHANGE_BY_SW BIT(31) + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 +#define IQK_THRESHOLD 8 + +#define MAX_KEY_LEN 61 +#define KEY_BUF_SIZE 5 + +/* QoS related. */ +/*aci: 0x00 Best Effort*/ +/*aci: 0x01 Background*/ +/*aci: 0x10 Video*/ +/*aci: 0x11 Voice*/ +/*Max: define total number.*/ +#define AC0_BE 0 +#define AC1_BK 1 +#define AC2_VI 2 +#define AC3_VO 3 +#define AC_MAX 4 +#define QOS_QUEUE_NUM 4 +#define RTL_MAC80211_NUM_QUEUE 5 +#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 +#define RTL_USB_MAX_RX_COUNT 100 +#define QBSS_LOAD_SIZE 5 +#define MAX_WMMELE_LENGTH 64 + +#define TOTAL_CAM_ENTRY 32 + +/*slot time for 11g. */ +#define RTL_SLOT_TIME_9 9 +#define RTL_SLOT_TIME_20 20 + +/*related to tcp/ip. */ +#define SNAP_SIZE 6 +#define PROTOC_TYPE_SIZE 2 + +/*related with 802.11 frame*/ +#define MAC80211_3ADDR_LEN 24 +#define MAC80211_4ADDR_LEN 30 + +#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ +#define CHANNEL_MAX_NUMBER_2G 14 +#define CHANNEL_MAX_NUMBER_5G 49 /* Please refer to + *"phy_GetChnlGroup8812A" and + * "Hal_ReadTxPowerInfo8812A" + */ +#define CHANNEL_MAX_NUMBER_5G_80M 7 +#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ +#define MAX_PG_GROUP 13 +#define CHANNEL_GROUP_MAX_2G 3 +#define CHANNEL_GROUP_IDX_5GL 3 +#define CHANNEL_GROUP_IDX_5GM 6 +#define CHANNEL_GROUP_IDX_5GH 9 +#define CHANNEL_GROUP_MAX_5G 9 +#define CHANNEL_MAX_NUMBER_2G 14 +#define AVG_THERMAL_NUM 8 +#define AVG_THERMAL_NUM_88E 4 +#define AVG_THERMAL_NUM_8723BE 4 +#define MAX_TID_COUNT 9 + +/* for early mode */ +#define FCS_LEN 4 +#define EM_HDR_LEN 8 + +enum rtl8192c_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + H2C_MACID_PS_MODE = 7, + H2C_P2P_PS_OFFLOAD = 8, + H2C_MAC_MODE_SEL = 9, + H2C_PWRM = 15, + H2C_P2P_PS_CTW_CMD = 24, + MAX_H2CCMD +}; + +#define MAX_TX_COUNT 4 +#define MAX_REGULATION_NUM 4 +#define MAX_RF_PATH_NUM 4 +#define MAX_RATE_SECTION_NUM 6 /* = MAX_RATE_SECTION */ +#define MAX_2_4G_BANDWIDTH_NUM 4 +#define MAX_5G_BANDWIDTH_NUM 4 +#define MAX_RF_PATH 4 +#define MAX_CHNL_GROUP_24G 6 +#define MAX_CHNL_GROUP_5G 14 + +#define TX_PWR_BY_RATE_NUM_BAND 2 +#define TX_PWR_BY_RATE_NUM_RF 4 +#define TX_PWR_BY_RATE_NUM_SECTION 12 +/* compatible with TX_PWR_BY_RATE_NUM_SECTION */ +#define TX_PWR_BY_RATE_NUM_RATE 84 +#define MAX_BASE_NUM_IN_PHY_REG_PG_24G 6 /* MAX_RATE_SECTION */ +#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 5 /* MAX_RATE_SECTION -1 */ + +#define BUFDESC_SEG_NUM 1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */ + +#define DEL_SW_IDX_SZ 30 + +/* For now, it's just for 8192ee + * but not OK yet, keep it 0 + */ +#define RTL8192EE_SEG_NUM BUFDESC_SEG_NUM +#define RTL8822BE_SEG_NUM BUFDESC_SEG_NUM + +enum rf_tx_num { + RF_1TX = 0, + RF_2TX, + RF_MAX_TX_NUM, + RF_TX_NUM_NONIMPLEMENT, +}; + +#define PACKET_NORMAL 0 +#define PACKET_DHCP 1 +#define PACKET_ARP 2 +#define PACKET_EAPOL 3 + +#define MAX_SUPPORT_WOL_PATTERN_NUM 16 +#define RSVD_WOL_PATTERN_NUM 1 +#define WKFMCAM_ADDR_NUM 6 +#define WKFMCAM_SIZE 24 + +#define MAX_WOL_BIT_MASK_SIZE 16 +/* MIN LEN keeps 13 here */ +#define MIN_WOL_PATTERN_SIZE 13 +#define MAX_WOL_PATTERN_SIZE 128 + +#define WAKE_ON_MAGIC_PACKET BIT(0) +#define WAKE_ON_PATTERN_MATCH BIT(1) + +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_AP_LOST BIT(4) +#define WOL_REASON_MAGIC_PKT BIT(5) +#define WOL_REASON_UNICAST_PKT BIT(6) +#define WOL_REASON_PATTERN_PKT BIT(7) +#define WOL_REASON_RTD3_SSID_MATCH BIT(8) +#define WOL_REASON_REALWOW_V2_WAKEUPPKT BIT(9) +#define WOL_REASON_REALWOW_V2_ACKLOST BIT(10) + +struct rtlwifi_firmware_header { + __le16 signature; + u8 category; + u8 function; + __le16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + __le16 ramcodesize; + __le16 rsvd2; + __le32 svnindex; + __le32 rsvd3; + __le32 rsvd4; + __le32 rsvd5; +}; + +struct txpower_info_2g { + u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + /*If only one tx, only BW20 and OFDM are used.*/ + u8 cck_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +struct txpower_info_5g { + u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_5G]; + /*If only one tx, only BW20, OFDM, BW80 and BW160 are used.*/ + u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +enum rate_section { + CCK = 0, + OFDM, + HT_MCS0_MCS7, + HT_MCS8_MCS15, + VHT_1SSMCS0_1SSMCS9, + VHT_2SSMCS0_2SSMCS9, + MAX_RATE_SECTION, +}; + +enum intf_type { + INTF_PCI = 0, + INTF_USB = 1, +}; + +enum radio_path { + RF90_PATH_A = 0, + RF90_PATH_B = 1, + RF90_PATH_C = 2, + RF90_PATH_D = 3, +}; + +enum radio_mask { + RF_MASK_A = BIT(0), + RF_MASK_B = BIT(1), + RF_MASK_C = BIT(2), + RF_MASK_D = BIT(3), +}; + +enum regulation_txpwr_lmt { + TXPWR_LMT_FCC = 0, + TXPWR_LMT_MKK = 1, + TXPWR_LMT_ETSI = 2, + TXPWR_LMT_WW = 3, + + TXPWR_LMT_MAX_REGULATION_NUM = 4 +}; + +enum rt_eeprom_type { + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}; + +enum ttl_status { + RTL_STATUS_INTERFACE_START = 0, +}; + +enum hardware_type { + HARDWARE_TYPE_RTL8192E, + HARDWARE_TYPE_RTL8192U, + HARDWARE_TYPE_RTL8192SE, + HARDWARE_TYPE_RTL8192SU, + HARDWARE_TYPE_RTL8192CE, + HARDWARE_TYPE_RTL8192CU, + HARDWARE_TYPE_RTL8192DE, + HARDWARE_TYPE_RTL8192DU, + HARDWARE_TYPE_RTL8723AE, + HARDWARE_TYPE_RTL8723U, + HARDWARE_TYPE_RTL8188EE, + HARDWARE_TYPE_RTL8723BE, + HARDWARE_TYPE_RTL8192EE, + HARDWARE_TYPE_RTL8821AE, + HARDWARE_TYPE_RTL8812AE, + HARDWARE_TYPE_RTL8822BE, + + /* keep it last */ + HARDWARE_TYPE_NUM +}; + +#define RTL_HW_TYPE(rtlpriv) (rtl_hal((struct rtl_priv *)rtlpriv)->hw_type) +#define IS_NEW_GENERATION_IC(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) >= HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8192CE(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192CE) +#define IS_HARDWARE_TYPE_8812(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8812AE) +#define IS_HARDWARE_TYPE_8821(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8821AE) +#define IS_HARDWARE_TYPE_8723A(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723AE) +#define IS_HARDWARE_TYPE_8723B(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723BE) +#define IS_HARDWARE_TYPE_8192E(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8822B(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8822BE) + +#define RX_HAL_IS_CCK_RATE(rxmcs) \ + ((rxmcs) == DESC_RATE1M || \ + (rxmcs) == DESC_RATE2M || \ + (rxmcs) == DESC_RATE5_5M || \ + (rxmcs) == DESC_RATE11M) + +enum scan_operation_backup_opt { + SCAN_OPT_BACKUP = 0, + SCAN_OPT_BACKUP_BAND0 = 0, + SCAN_OPT_BACKUP_BAND1, + SCAN_OPT_RESTORE, + SCAN_OPT_MAX +}; + +/*RF state.*/ +enum rf_pwrstate { + ERFON, + ERFSLEEP, + ERFOFF +}; + +struct bb_reg_def { + u32 rfintfs; + u32 rfintfi; + u32 rfintfo; + u32 rfintfe; + u32 rf3wire_offset; + u32 rflssi_select; + u32 rftxgain_stage; + u32 rfhssi_para1; + u32 rfhssi_para2; + u32 rfsw_ctrl; + u32 rfagc_control1; + u32 rfagc_control2; + u32 rfrxiq_imbal; + u32 rfrx_afe; + u32 rftxiq_imbal; + u32 rftx_afe; + u32 rf_rb; /* rflssi_readback */ + u32 rf_rbpi; /* rflssi_readbackpi */ +}; + +enum io_type { + IO_CMD_PAUSE_DM_BY_SCAN = 0, + IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0, + IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1, + IO_CMD_RESUME_DM_BY_SCAN = 2, +}; + +enum hw_variables { + HW_VAR_ETHER_ADDR = 0x0, + HW_VAR_MULTICAST_REG = 0x1, + HW_VAR_BASIC_RATE = 0x2, + HW_VAR_BSSID = 0x3, + HW_VAR_MEDIA_STATUS = 0x4, + HW_VAR_SECURITY_CONF = 0x5, + HW_VAR_BEACON_INTERVAL = 0x6, + HW_VAR_ATIM_WINDOW = 0x7, + HW_VAR_LISTEN_INTERVAL = 0x8, + HW_VAR_CS_COUNTER = 0x9, + HW_VAR_DEFAULTKEY0 = 0xa, + HW_VAR_DEFAULTKEY1 = 0xb, + HW_VAR_DEFAULTKEY2 = 0xc, + HW_VAR_DEFAULTKEY3 = 0xd, + HW_VAR_SIFS = 0xe, + HW_VAR_R2T_SIFS = 0xf, + HW_VAR_DIFS = 0x10, + HW_VAR_EIFS = 0x11, + HW_VAR_SLOT_TIME = 0x12, + HW_VAR_ACK_PREAMBLE = 0x13, + HW_VAR_CW_CONFIG = 0x14, + HW_VAR_CW_VALUES = 0x15, + HW_VAR_RATE_FALLBACK_CONTROL = 0x16, + HW_VAR_CONTENTION_WINDOW = 0x17, + HW_VAR_RETRY_COUNT = 0x18, + HW_VAR_TR_SWITCH = 0x19, + HW_VAR_COMMAND = 0x1a, + HW_VAR_WPA_CONFIG = 0x1b, + HW_VAR_AMPDU_MIN_SPACE = 0x1c, + HW_VAR_SHORTGI_DENSITY = 0x1d, + HW_VAR_AMPDU_FACTOR = 0x1e, + HW_VAR_MCS_RATE_AVAILABLE = 0x1f, + HW_VAR_AC_PARAM = 0x20, + HW_VAR_ACM_CTRL = 0x21, + HW_VAR_DIS_REQ_QSIZE = 0x22, + HW_VAR_CCX_CHNL_LOAD = 0x23, + HW_VAR_CCX_NOISE_HISTOGRAM = 0x24, + HW_VAR_CCX_CLM_NHM = 0x25, + HW_VAR_TXOPLIMIT = 0x26, + HW_VAR_TURBO_MODE = 0x27, + HW_VAR_RF_STATE = 0x28, + HW_VAR_RF_OFF_BY_HW = 0x29, + HW_VAR_BUS_SPEED = 0x2a, + HW_VAR_SET_DEV_POWER = 0x2b, + + HW_VAR_RCR = 0x2c, + HW_VAR_RATR_0 = 0x2d, + HW_VAR_RRSR = 0x2e, + HW_VAR_CPU_RST = 0x2f, + HW_VAR_CHECK_BSSID = 0x30, + HW_VAR_LBK_MODE = 0x31, + HW_VAR_AES_11N_FIX = 0x32, + HW_VAR_USB_RX_AGGR = 0x33, + HW_VAR_USER_CONTROL_TURBO_MODE = 0x34, + HW_VAR_RETRY_LIMIT = 0x35, + HW_VAR_INIT_TX_RATE = 0x36, + HW_VAR_TX_RATE_REG = 0x37, + HW_VAR_EFUSE_USAGE = 0x38, + HW_VAR_EFUSE_BYTES = 0x39, + HW_VAR_AUTOLOAD_STATUS = 0x3a, + HW_VAR_RF_2R_DISABLE = 0x3b, + HW_VAR_SET_RPWM = 0x3c, + HW_VAR_H2C_FW_PWRMODE = 0x3d, + HW_VAR_H2C_FW_JOINBSSRPT = 0x3e, + HW_VAR_H2C_FW_MEDIASTATUSRPT = 0x3f, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD = 0x40, + HW_VAR_FW_PSMODE_STATUS = 0x41, + HW_VAR_INIT_RTS_RATE = 0x42, + HW_VAR_RESUME_CLK_ON = 0x43, + HW_VAR_FW_LPS_ACTION = 0x44, + HW_VAR_1X1_RECV_COMBINE = 0x45, + HW_VAR_STOP_SEND_BEACON = 0x46, + HW_VAR_TSF_TIMER = 0x47, + HW_VAR_IO_CMD = 0x48, + + HW_VAR_RF_RECOVERY = 0x49, + HW_VAR_H2C_FW_UPDATE_GTK = 0x4a, + HW_VAR_WF_MASK = 0x4b, + HW_VAR_WF_CRC = 0x4c, + HW_VAR_WF_IS_MAC_ADDR = 0x4d, + HW_VAR_H2C_FW_OFFLOAD = 0x4e, + HW_VAR_RESET_WFCRC = 0x4f, + + HW_VAR_HANDLE_FW_C2H = 0x50, + HW_VAR_DL_FW_RSVD_PAGE = 0x51, + HW_VAR_AID = 0x52, + HW_VAR_HW_SEQ_ENABLE = 0x53, + HW_VAR_CORRECT_TSF = 0x54, + HW_VAR_BCN_VALID = 0x55, + HW_VAR_FWLPS_RF_ON = 0x56, + HW_VAR_DUAL_TSF_RST = 0x57, + HW_VAR_SWITCH_EPHY_WOWLAN = 0x58, + HW_VAR_INT_MIGRATION = 0x59, + HW_VAR_INT_AC = 0x5a, + HW_VAR_RF_TIMING = 0x5b, + + HAL_DEF_WOWLAN = 0x5c, + HW_VAR_MRC = 0x5d, + HW_VAR_KEEP_ALIVE = 0x5e, + HW_VAR_NAV_UPPER = 0x5f, + + HW_VAR_MGT_FILTER = 0x60, + HW_VAR_CTRL_FILTER = 0x61, + HW_VAR_DATA_FILTER = 0x62, +}; + +enum rt_media_status { + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +}; + +enum rt_oem_id { + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819X_CAMEO = 6, + RT_CID_819X_RUNTOP = 7, + RT_CID_819X_SENAO = 8, + RT_CID_TOSHIBA = 9, + RT_CID_819X_NETCORE = 10, + RT_CID_NETTRONIX = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_819X_ALPHA = 15, + RT_CID_819X_SITECOM = 16, + RT_CID_CCX = 17, + RT_CID_819X_LENOVO = 18, + RT_CID_819X_QMI = 19, + RT_CID_819X_EDIMAX_BELKIN = 20, + RT_CID_819X_SERCOMM_BELKIN = 21, + RT_CID_819X_CAMEO1 = 22, + RT_CID_819X_MSI = 23, + RT_CID_819X_ACER = 24, + RT_CID_819X_HP = 27, + RT_CID_819X_CLEVO = 28, + RT_CID_819X_ARCADYAN_BELKIN = 29, + RT_CID_819X_SAMSUNG = 30, + RT_CID_819X_WNC_COREGA = 31, + RT_CID_819X_FOXCOON = 32, + RT_CID_819X_DELL = 33, + RT_CID_819X_PRONETS = 34, + RT_CID_819X_EDIMAX_ASUS = 35, + RT_CID_NETGEAR = 36, + RT_CID_PLANEX = 37, + RT_CID_CC_C = 38, +}; + +enum hw_descs { + HW_DESC_OWN, + HW_DESC_RXOWN, + HW_DESC_TX_NEXTDESC_ADDR, + HW_DESC_TXBUFF_ADDR, + HW_DESC_RXBUFF_ADDR, + HW_DESC_RXPKT_LEN, + HW_DESC_RXERO, + HW_DESC_RX_PREPARE, +}; + +enum prime_sc { + PRIME_CHNL_OFFSET_DONT_CARE = 0, + PRIME_CHNL_OFFSET_LOWER = 1, + PRIME_CHNL_OFFSET_UPPER = 2, +}; + +enum rf_type { + RF_1T1R = 0, + RF_1T2R = 1, + RF_2T2R = 2, + RF_2T2R_GREEN = 3, + RF_2T3R = 4, + RF_2T4R = 5, + RF_3T3R = 6, + RF_3T4R = 7, + RF_4T4R = 8, +}; + +enum ht_channel_width { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_20_40 = 1, + HT_CHANNEL_WIDTH_80 = 2, + HT_CHANNEL_WIDTH_MAX, +}; + +/* Ref: 802.11i spec D10.0 7.3.2.25.1 + * Cipher Suites Encryption Algorithms + */ +enum rt_enc_alg { + NO_ENCRYPTION = 0, + WEP40_ENCRYPTION = 1, + TKIP_ENCRYPTION = 2, + RSERVED_ENCRYPTION = 3, + AESCCMP_ENCRYPTION = 4, + WEP104_ENCRYPTION = 5, + AESCMAC_ENCRYPTION = 6, /*IEEE802.11w */ +}; + +enum rtl_hal_state { + _HAL_STATE_STOP = 0, + _HAL_STATE_START = 1, +}; + +enum rtl_desc_rate { + DESC_RATE1M = 0x00, + DESC_RATE2M = 0x01, + DESC_RATE5_5M = 0x02, + DESC_RATE11M = 0x03, + + DESC_RATE6M = 0x04, + DESC_RATE9M = 0x05, + DESC_RATE12M = 0x06, + DESC_RATE18M = 0x07, + DESC_RATE24M = 0x08, + DESC_RATE36M = 0x09, + DESC_RATE48M = 0x0a, + DESC_RATE54M = 0x0b, + + DESC_RATEMCS0 = 0x0c, + DESC_RATEMCS1 = 0x0d, + DESC_RATEMCS2 = 0x0e, + DESC_RATEMCS3 = 0x0f, + DESC_RATEMCS4 = 0x10, + DESC_RATEMCS5 = 0x11, + DESC_RATEMCS6 = 0x12, + DESC_RATEMCS7 = 0x13, + DESC_RATEMCS8 = 0x14, + DESC_RATEMCS9 = 0x15, + DESC_RATEMCS10 = 0x16, + DESC_RATEMCS11 = 0x17, + DESC_RATEMCS12 = 0x18, + DESC_RATEMCS13 = 0x19, + DESC_RATEMCS14 = 0x1a, + DESC_RATEMCS15 = 0x1b, + DESC_RATEMCS15_SG = 0x1c, + DESC_RATEMCS32 = 0x20, + + DESC_RATEVHT1SS_MCS0 = 0x2c, + DESC_RATEVHT1SS_MCS1 = 0x2d, + DESC_RATEVHT1SS_MCS2 = 0x2e, + DESC_RATEVHT1SS_MCS3 = 0x2f, + DESC_RATEVHT1SS_MCS4 = 0x30, + DESC_RATEVHT1SS_MCS5 = 0x31, + DESC_RATEVHT1SS_MCS6 = 0x32, + DESC_RATEVHT1SS_MCS7 = 0x33, + DESC_RATEVHT1SS_MCS8 = 0x34, + DESC_RATEVHT1SS_MCS9 = 0x35, + DESC_RATEVHT2SS_MCS0 = 0x36, + DESC_RATEVHT2SS_MCS1 = 0x37, + DESC_RATEVHT2SS_MCS2 = 0x38, + DESC_RATEVHT2SS_MCS3 = 0x39, + DESC_RATEVHT2SS_MCS4 = 0x3a, + DESC_RATEVHT2SS_MCS5 = 0x3b, + DESC_RATEVHT2SS_MCS6 = 0x3c, + DESC_RATEVHT2SS_MCS7 = 0x3d, + DESC_RATEVHT2SS_MCS8 = 0x3e, + DESC_RATEVHT2SS_MCS9 = 0x3f, +}; + +enum rtl_var_map { + /*reg map */ + SYS_ISO_CTRL = 0, + SYS_FUNC_EN, + SYS_CLK, + MAC_RCR_AM, + MAC_RCR_AB, + MAC_RCR_ACRC32, + MAC_RCR_ACF, + MAC_RCR_AAP, + MAC_HIMR, + MAC_HIMRE, + MAC_HSISR, + + /*efuse map */ + EFUSE_TEST, + EFUSE_CTRL, + EFUSE_CLK, + EFUSE_CLK_CTRL, + EFUSE_PWC_EV12V, + EFUSE_FEN_ELDR, + EFUSE_LOADER_CLK_EN, + EFUSE_ANA8M, + EFUSE_HWSET_MAX_SIZE, + EFUSE_MAX_SECTION_MAP, + EFUSE_REAL_CONTENT_SIZE, + EFUSE_OOB_PROTECT_BYTES_LEN, + EFUSE_ACCESS, + + /*CAM map */ + RWCAM, + WCAMI, + RCAMO, + CAMDBG, + SECR, + SEC_CAM_NONE, + SEC_CAM_WEP40, + SEC_CAM_TKIP, + SEC_CAM_AES, + SEC_CAM_WEP104, + + /*IMR map */ + RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */ + RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */ + RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */ + RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */ + RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */ + RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */ + RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrupt 8 */ + RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrupt 7 */ + RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrupt 6 */ + RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrupt 5 */ + RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrupt 4 */ + RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrupt 3 */ + RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrupt 2 */ + RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrupt 1 */ + RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */ + RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */ + RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */ + RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */ + RTL_IMR_BCNINT, /*Beacon DMA Interrupt 0 */ + RTL_IMR_RXFOVW, /*Receive FIFO Overflow */ + RTL_IMR_RDU, /*Receive Descriptor Unavailable */ + RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ + RTL_IMR_H2CDOK, /*H2C Queue DMA OK Interrupt */ + RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrupt */ + RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ + RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/ + RTL_IMR_TBDOK, /*Transmit Beacon OK interrupt */ + RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ + RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ + RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */ + RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */ + RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ + RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ + RTL_IMR_ROK, /*Receive DMA OK Interrupt */ + RTL_IMR_HSISR_IND, /*HSISR Interrupt*/ + RTL_IBSS_INT_MASKS, /*(RTL_IMR_BCNINT | RTL_IMR_TBDOK | + * RTL_IMR_TBDER) + */ + RTL_IMR_C2HCMD, /*fw interrupt*/ + + /*CCK Rates, TxHT = 0 */ + RTL_RC_CCK_RATE1M, + RTL_RC_CCK_RATE2M, + RTL_RC_CCK_RATE5_5M, + RTL_RC_CCK_RATE11M, + + /*OFDM Rates, TxHT = 0 */ + RTL_RC_OFDM_RATE6M, + RTL_RC_OFDM_RATE9M, + RTL_RC_OFDM_RATE12M, + RTL_RC_OFDM_RATE18M, + RTL_RC_OFDM_RATE24M, + RTL_RC_OFDM_RATE36M, + RTL_RC_OFDM_RATE48M, + RTL_RC_OFDM_RATE54M, + + RTL_RC_HT_RATEMCS7, + RTL_RC_HT_RATEMCS15, + + RTL_RC_VHT_RATE_1SS_MCS7, + RTL_RC_VHT_RATE_1SS_MCS8, + RTL_RC_VHT_RATE_1SS_MCS9, + RTL_RC_VHT_RATE_2SS_MCS7, + RTL_RC_VHT_RATE_2SS_MCS8, + RTL_RC_VHT_RATE_2SS_MCS9, + + /*keep it last */ + RTL_VAR_MAP_MAX, +}; + +/*Firmware PS mode for control LPS.*/ +enum _fw_ps_mode { + FW_PS_ACTIVE_MODE = 0, + FW_PS_MIN_MODE = 1, + FW_PS_MAX_MODE = 2, + FW_PS_DTIM_MODE = 3, + FW_PS_VOIP_MODE = 4, + FW_PS_UAPSD_WMM_MODE = 5, + FW_PS_UAPSD_MODE = 6, + FW_PS_IBSS_MODE = 7, + FW_PS_WWLAN_MODE = 8, + FW_PS_PM_RADIO_OFF = 9, + FW_PS_PM_CARD_DISABLE = 10, +}; + +enum rt_psmode { + EACTIVE, /*Active/Continuous access. */ + EMAXPS, /*Max power save mode. */ + EFASTPS, /*Fast power save mode. */ + EAUTOPS, /*Auto power save mode. */ +}; + +/*LED related.*/ +enum led_ctl_mode { + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, +}; + +enum rtl_led_pin { + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_LED2 +}; + +/* QoS related.*/ +/* acm implementation method.*/ +enum acm_method { + EACMWAY0_SWANDHW = 0, + EACMWAY1_HW = 1, + EACMWAY2_SW = 2, +}; + +enum macphy_mode { + SINGLEMAC_SINGLEPHY = 0, + DUALMAC_DUALPHY, + DUALMAC_SINGLEPHY, +}; + +enum band_type { + BAND_ON_2_4G = 0, + BAND_ON_5G, + BAND_ON_BOTH, + BANDMAX +}; + +/* aci/aifsn Field. + * Ref: WMM spec 2.2.2: WME Parameter Element, p.12. + */ +union aci_aifsn { + u8 char_data; + + struct { + u8 aifsn:4; + u8 acm:1; + u8 aci:2; + u8 reserved:1; + } f; /* Field */ +}; + +/*mlme related.*/ +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20, + WIRELESS_MODE_AC_5G = 0x40, + WIRELESS_MODE_AC_24G = 0x80, + WIRELESS_MODE_AC_ONLY = 0x100, + WIRELESS_MODE_MAX = 0x800 +}; + +#define IS_WIRELESS_MODE_A(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_A) +#define IS_WIRELESS_MODE_B(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_B) +#define IS_WIRELESS_MODE_G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_G) +#define IS_WIRELESS_MODE_N_24G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_24G) +#define IS_WIRELESS_MODE_N_5G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_5G) + +enum ratr_table_mode { + RATR_INX_WIRELESS_NGB = 0, + RATR_INX_WIRELESS_NG = 1, + RATR_INX_WIRELESS_NB = 2, + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_A = 8, + RATR_INX_WIRELESS_AC_5N = 8, + RATR_INX_WIRELESS_AC_24N = 9, +}; + +enum ratr_table_mode_new { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, + RATEID_IDX_MIX1 = 11, + RATEID_IDX_MIX2 = 12, + RATEID_IDX_VHT_3SS = 13, + RATEID_IDX_BGN_3SS = 14, +}; + +enum rtl_link_state { + MAC80211_NOLINK = 0, + MAC80211_LINKING = 1, + MAC80211_LINKED = 2, + MAC80211_LINKED_SCANNING = 3, +}; + +enum act_category { + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +}; + +enum ba_action { + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +}; + +enum rt_polarity_ctl { + RT_POLARITY_LOW_ACT = 0, + RT_POLARITY_HIGH_ACT = 1, +}; + +/* After 8188E, we use V2 reason define. 88C/8723A use V1 reason. */ +enum fw_wow_reason_v2 { + FW_WOW_V2_PTK_UPDATE_EVENT = 0x01, + FW_WOW_V2_GTK_UPDATE_EVENT = 0x02, + FW_WOW_V2_DISASSOC_EVENT = 0x04, + FW_WOW_V2_DEAUTH_EVENT = 0x08, + FW_WOW_V2_FW_DISCONNECT_EVENT = 0x10, + FW_WOW_V2_MAGIC_PKT_EVENT = 0x21, + FW_WOW_V2_UNICAST_PKT_EVENT = 0x22, + FW_WOW_V2_PATTERN_PKT_EVENT = 0x23, + FW_WOW_V2_RTD3_SSID_MATCH_EVENT = 0x24, + FW_WOW_V2_REALWOW_V2_WAKEUPPKT = 0x30, + FW_WOW_V2_REALWOW_V2_ACKLOST = 0x31, + FW_WOW_V2_REASON_MAX = 0xff, +}; + +enum wolpattern_type { + UNICAST_PATTERN = 0, + MULTICAST_PATTERN = 1, + BROADCAST_PATTERN = 2, + DONT_CARE_DA = 3, + UNKNOWN_TYPE = 4, +}; + +enum package_type { + PACKAGE_DEFAULT, + PACKAGE_QFN68, + PACKAGE_TFBGA90, + PACKAGE_TFBGA80, + PACKAGE_TFBGA79 +}; + +enum rtl_spec_ver { + RTL_SPEC_NEW_RATEID = BIT(0), /* use ratr_table_mode_new */ + RTL_SPEC_SUPPORT_VHT = BIT(1), /* support VHT */ + RTL_SPEC_NEW_FW_C2H = BIT(2), /* new FW C2H (e.g. TX REPORT) */ +}; + +struct octet_string { + u8 *octet; + u16 length; +}; + +struct rtl_hdr_3addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __packed; + +struct rtl_info_element { + u8 id; + u8 len; + u8 data[0]; +} __packed; + +struct rtl_probe_rsp { + struct rtl_hdr_3addr header; + u32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + /* SSID, supported rates, FH params, DS params, + * CF params, IBSS params, TIM (if beacon), RSN + */ + struct rtl_info_element info_element[0]; +} __packed; + +struct rtl_beacon_keys { + /*u8 ssid[32];*/ + /*u32 ssid_len;*/ + u8 bcn_channel; + __le16 ht_cap_info; + u8 ht_info_infos_0_sco; /* bit0 & bit1 in infos[0] is 2nd ch offset */ + bool valid; +}; + +/*LED related.*/ +/*ledpin Identify how to implement this SW led.*/ +struct rtl_led { + void *hw; + enum rtl_led_pin ledpin; + bool ledon; +}; + +struct rtl_led_ctl { + bool led_opendrain; + struct rtl_led sw_led0; + struct rtl_led sw_led1; +}; + +struct rtl_qos_parameters { + __le16 cw_min; + __le16 cw_max; + u8 aifs; + u8 flag; + __le16 tx_op; +} __packed; + +struct rt_smooth_data { + u32 elements[100]; /*array to store values */ + u32 index; /*index to current array to store */ + u32 total_num; /*num of valid elements */ + u32 total_val; /*sum of valid elements */ +}; + +struct false_alarm_statistics { + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_crc8_fail; + u32 cnt_mcs_fail; + u32 cnt_fast_fsync_fail; + u32 cnt_sb_search_fail; + u32 cnt_ofdm_fail; + u32 cnt_cck_fail; + u32 cnt_all; + u32 cnt_ofdm_cca; + u32 cnt_cck_cca; + u32 cnt_cca_all; + u32 cnt_bw_usc; + u32 cnt_bw_lsc; +}; + +struct init_gain { + u8 xaagccore1; + u8 xbagccore1; + u8 xcagccore1; + u8 xdagccore1; + u8 cca; + +}; + +struct wireless_stats { + u64 txbytesunicast; + u64 txbytesmulticast; + u64 txbytesbroadcast; + u64 rxbytesunicast; + + u64 txbytesunicast_inperiod; + u64 rxbytesunicast_inperiod; + u32 txbytesunicast_inperiod_tp; + u32 rxbytesunicast_inperiod_tp; + u64 txbytesunicast_last; + u64 rxbytesunicast_last; + + long rx_snr_db[4]; + /* Correct smoothed ss in Dbm, only used + * in driver to report real power now. + */ + long recv_signal_power; + long signal_quality; + long last_sigstrength_inpercent; + + u32 rssi_calculate_cnt; + u32 pwdb_all_cnt; + + /* Transformed, in dbm. Beautified signal + * strength for UI, not correct. + */ + long signal_strength; + + u8 rx_rssi_percentage[4]; + u8 rx_evm_dbm[4]; + u8 rx_evm_percentage[2]; + + u16 rx_cfo_short[4]; + u16 rx_cfo_tail[4]; + + struct rt_smooth_data ui_rssi; + struct rt_smooth_data ui_link_quality; +}; + +struct rate_adaptive { + u8 rate_adaptive_disabled; + u8 ratr_state; + u16 reserve; + + u32 high_rssi_thresh_for_ra; + u32 high2low_rssi_thresh_for_ra; + u8 low2high_rssi_thresh_for_ra40m; + u32 low_rssi_thresh_for_ra40m; + u8 low2high_rssi_thresh_for_ra20m; + u32 low_rssi_thresh_for_ra20m; + u32 upper_rssi_threshold_ratr; + u32 middleupper_rssi_threshold_ratr; + u32 middle_rssi_threshold_ratr; + u32 middlelow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr; + u32 ultralow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr_40m; + u32 low_rssi_threshold_ratr_20m; + u8 ping_rssi_enable; + u32 ping_rssi_ratr; + u32 ping_rssi_thresh_for_ra; + u32 last_ratr; + u8 pre_ratr_state; + u8 ldpc_thres; + bool use_ldpc; + bool lower_rts_rate; + bool is_special_data; +}; + +struct regd_pair_mapping { + u16 reg_dmnenum; + u16 reg_5ghz_ctl; + u16 reg_2ghz_ctl; +}; + +struct dynamic_primary_cca { + u8 pricca_flag; + u8 intf_flag; + u8 intf_type; + u8 dup_rts_flag; + u8 monitor_flag; + u8 ch_offset; + u8 mf_state; +}; + +struct rtl_regulatory { + s8 alpha2[2]; + u16 country_code; + u16 max_power_level; + u32 tp_scale; + u16 current_rd; + u16 current_rd_ext; + s16 power_limit; + struct regd_pair_mapping *regpair; +}; + +struct rtl_rfkill { + bool rfkill_state; /*0 is off, 1 is on */ +}; + +/*for P2P PS**/ +#define P2P_MAX_NOA_NUM 2 + +enum p2p_role { + P2P_ROLE_DISABLE = 0, + P2P_ROLE_DEVICE = 1, + P2P_ROLE_CLIENT = 2, + P2P_ROLE_GO = 3 +}; + +enum p2p_ps_state { + P2P_PS_DISABLE = 0, + P2P_PS_ENABLE = 1, + P2P_PS_SCAN = 2, + P2P_PS_SCAN_DONE = 3, + P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */ +}; + +enum p2p_ps_mode { + P2P_PS_NONE = 0, + P2P_PS_CTWINDOW = 1, + P2P_PS_NOA = 2, + P2P_PS_MIX = 3, /* CTWindow and NoA */ +}; + +struct rtl_p2p_ps_info { + enum p2p_ps_mode p2p_ps_mode; /* indicate p2p ps mode */ + enum p2p_ps_state p2p_ps_state; /* indicate p2p ps state */ + u8 noa_index; /* Identifies instance of Notice of Absence timing. */ + /* Client traffic window. A period of time in TU after TBTT. */ + u8 ctwindow; + u8 opp_ps; /* opportunistic power save. */ + u8 noa_num; /* number of NoA descriptor in P2P IE. */ + /* Count for owner, Type of client. */ + u8 noa_count_type[P2P_MAX_NOA_NUM]; + /* Max duration for owner, preferred or min acceptable duration + * for client. + */ + u32 noa_duration[P2P_MAX_NOA_NUM]; + /* Length of interval for owner, preferred or max acceptable intervali + * of client. + */ + u32 noa_interval[P2P_MAX_NOA_NUM]; + /* schedule in terms of the lower 4 bytes of the TSF timer. */ + u32 noa_start_time[P2P_MAX_NOA_NUM]; +}; + +struct p2p_ps_offload_t { + u8 offload_en:1; + u8 role:1; /* 1: Owner, 0: Client */ + u8 ctwindow_en:1; + u8 noa0_en:1; + u8 noa1_en:1; + u8 allstasleep:1; + u8 discovery:1; + u8 reserved:1; +}; + +#define IQK_MATRIX_REG_NUM 8 +#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) + +struct iqk_matrix_regs { + bool iqk_done; + long value[1][IQK_MATRIX_REG_NUM]; +}; + +struct phy_parameters { + u16 length; + u32 *pdata; +}; + +enum hw_param_tab_index { + PHY_REG_2T, + PHY_REG_1T, + PHY_REG_PG, + RADIOA_2T, + RADIOB_2T, + RADIOA_1T, + RADIOB_1T, + MAC_REG, + AGCTAB_2T, + AGCTAB_1T, + MAX_TAB +}; + +struct rtl_phy { + struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ + struct init_gain initgain_backup; + enum io_type current_io_type; + + u8 rf_mode; + u8 rf_type; + u8 current_chan_bw; + u8 max_ht_chan_bw; + u8 max_vht_chan_bw; + u8 set_bwmode_inprogress; + u8 sw_chnl_inprogress; + u8 sw_chnl_stage; + u8 sw_chnl_step; + u8 current_channel; + u8 h2c_box_num; + u8 set_io_inprogress; + u8 lck_inprogress; + + /* record for power tracking */ + s32 reg_e94; + s32 reg_e9c; + s32 reg_ea4; + s32 reg_eac; + s32 reg_eb4; + s32 reg_ebc; + s32 reg_ec4; + s32 reg_ecc; + u8 rfpienable; + u8 reserve_0; + u16 reserve_1; + u32 reg_c04, reg_c08, reg_874; + u32 adda_backup[16]; + u32 iqk_mac_backup[IQK_MAC_REG_NUM]; + u32 iqk_bb_backup[10]; + bool iqk_initialized; + + bool rfpath_rx_enable[MAX_RF_PATH]; + u8 reg_837; + /* Dual mac */ + bool need_iqk; + struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM]; + + bool rfpi_enable; + bool iqk_in_progress; + + u8 pwrgroup_cnt; + u8 cck_high_power; + /* this is for 88E & 8723A */ + u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; + /* MAX_PG_GROUP groups of pwr diff by rates */ + u32 mcs_offset[MAX_PG_GROUP][16]; + u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RATE]; + /* compatible with TX_PWR_BY_RATE_NUM_SECTION*/ + u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_24G]; + u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_5G]; + u8 default_initialgain[4]; + + /* the current Tx power level */ + u8 cur_cck_txpwridx; + u8 cur_ofdm24g_txpwridx; + u8 cur_bw20_txpwridx; + u8 cur_bw40_txpwridx; + + s8 txpwr_limit_2_4g[MAX_REGULATION_NUM] + [MAX_2_4G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_2G] + [MAX_RF_PATH_NUM]; + s8 txpwr_limit_5g[MAX_REGULATION_NUM] + [MAX_5G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_5G] + [MAX_RF_PATH_NUM]; + + u32 rfreg_chnlval[2]; + bool apk_done; + u32 reg_rf3c[2]; /* pathA / pathB */ + + u32 backup_rf_0x1a;/*92ee*/ + /* bfsync */ + u8 framesync; + u32 framesync_c34; + + u8 num_total_rfpath; + struct phy_parameters hwparam_tables[MAX_TAB]; + u16 rf_pathmap; + + u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/ + enum rt_polarity_ctl polarity_ctl; +}; + +#define MAX_TID_COUNT 9 +#define RTL_AGG_STOP 0 +#define RTL_AGG_PROGRESS 1 +#define RTL_AGG_START 2 +#define RTL_AGG_OPERATIONAL 3 +#define RTL_AGG_OFF 0 +#define RTL_AGG_ON 1 +#define RTL_RX_AGG_START 1 +#define RTL_RX_AGG_STOP 0 +#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 +#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3 + +struct rtl_ht_agg { + u16 txq_id; + u16 wait_for_ba; + u16 start_idx; + u64 bitmap; + u32 rate_n_flags; + u8 agg_state; + u8 rx_agg_state; +}; + +struct rssi_sta { + /* for old dm */ + long undec_sm_pwdb; + long undec_sm_cck; + + /* for new phydm_mod */ + s32 undecorated_smoothed_pwdb; + s32 undecorated_smoothed_cck; + s32 undecorated_smoothed_ofdm; + u8 ofdm_pkt; + u8 cck_pkt; + u16 cck_sum_power; + u8 is_send_rssi; + u64 packet_map; + u8 valid_bit; +}; + +struct rtl_tid_data { + u16 seq_number; + struct rtl_ht_agg agg; +}; + +struct rtl_sta_info { + struct list_head list; + struct rtl_tid_data tids[MAX_TID_COUNT]; + /* just used for ap adhoc or mesh*/ + struct rssi_sta rssi_stat; + u8 rssi_level; + u16 wireless_mode; + u8 ratr_index; + u8 mimo_ps; + u8 mac_addr[ETH_ALEN]; +} __packed; + +struct rtl_priv; +struct rtl_io { + struct device *dev; + struct mutex bb_mutex; + + /*PCI MEM map */ + unsigned long pci_mem_end; /*shared mem end */ + unsigned long pci_mem_start; /*shared mem start */ + + /*PCI IO map */ + unsigned long pci_base_addr; /*device I/O address */ + + void (*write8_async)(struct rtl_priv *rtlpriv, u32 addr, u8 val); + void (*write16_async)(struct rtl_priv *rtlpriv, u32 addr, u16 val); + void (*write32_async)(struct rtl_priv *rtlpriv, u32 addr, u32 val); + void (*writeN_sync)(struct rtl_priv *rtlpriv, u32 addr, void *buf, + u16 len); + + u8 (*read8_sync)(struct rtl_priv *rtlpriv, u32 addr); + u16 (*read16_sync)(struct rtl_priv *rtlpriv, u32 addr); + u32 (*read32_sync)(struct rtl_priv *rtlpriv, u32 addr); + +}; + +struct rtl_mac { + u8 mac_addr[ETH_ALEN]; + u8 mac80211_registered; + u8 beacon_enabled; + + u32 tx_ss_num; + u32 rx_ss_num; + + struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; + enum nl80211_iftype opmode; + + /*Probe Beacon management */ + struct rtl_tid_data tids[MAX_TID_COUNT]; + enum rtl_link_state link_state; + struct rtl_beacon_keys cur_beacon_keys; + u8 new_beacon_cnt; + + int n_channels; + int n_bitrates; + + bool offchan_delay; + u8 p2p; /*using p2p role*/ + bool p2p_in_use; + + /*filters */ + u32 rx_conf; + u16 rx_mgt_filter; + u16 rx_ctrl_filter; + u16 rx_data_filter; + + bool act_scanning; + u8 cnt_after_linked; + bool skip_scan; + + /* early mode */ + /* skb wait queue */ + struct sk_buff_head skb_waitq[MAX_TID_COUNT]; + + u8 ht_stbc_cap; + u8 ht_cur_stbc; + + /*vht support*/ + u8 vht_enable; + u8 bw_80; + u8 vht_cur_ldpc; + u8 vht_cur_stbc; + u8 vht_stbc_cap; + u8 vht_ldpc_cap; + + /*RDG*/ + bool rdg_en; + + /*AP*/ + u8 bssid[ETH_ALEN] __aligned(2); + u32 vendor; + u8 mcs[16]; /* 16 bytes mcs for HT rates. */ + u32 basic_rates; /* b/g rates */ + u8 ht_enable; + u8 sgi_40; + u8 sgi_20; + u8 bw_40; + u16 mode; /* wireless mode */ + u8 slot_time; + u8 short_preamble; + u8 use_cts_protect; + u8 cur_40_prime_sc; + u8 cur_40_prime_sc_bk; + u8 cur_80_prime_sc; + u64 tsf; + u8 retry_short; + u8 retry_long; + u16 assoc_id; + bool hiddenssid; + + /*IBSS*/ + int beacon_interval; + + /*AMPDU*/ + u8 min_space_cfg; /*For Min spacing configurations */ + u8 max_mss_density; + u8 current_ampdu_factor; + u8 current_ampdu_density; + + /*QOS & EDCA */ + struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; + struct rtl_qos_parameters ac[AC_MAX]; + + /* counters */ + u64 last_txok_cnt; + u64 last_rxok_cnt; + u32 last_bt_edca_ul; + u32 last_bt_edca_dl; +}; + +struct btdm_8723 { + bool all_off; + bool agc_table_en; + bool adc_back_off_on; + bool b2_ant_hid_en; + bool low_penalty_rate_adaptive; + bool rf_rx_lpf_shrink; + bool reject_aggre_pkt; + bool tra_tdma_on; + u8 tra_tdma_nav; + u8 tra_tdma_ant; + bool tdma_on; + u8 tdma_ant; + u8 tdma_nav; + u8 tdma_dac_swing; + u8 fw_dac_swing_lvl; + bool ps_tdma_on; + u8 ps_tdma_byte[5]; + bool pta_on; + u32 val_0x6c0; + u32 val_0x6c8; + u32 val_0x6cc; + bool sw_dac_swing_on; + u32 sw_dac_swing_lvl; + u32 wlan_act_hi; + u32 wlan_act_lo; + u32 bt_retry_index; + bool dec_bt_pwr; + bool ignore_wlan_act; +}; + +struct bt_coexist_8723 { + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 c2h_bt_info; + bool c2h_bt_info_req_sent; + bool c2h_bt_inquiry_page; + u32 bt_inq_page_start_time; + u8 bt_retry_cnt; + u8 c2h_bt_info_original; + u8 bt_inquiry_page_cnt; + struct btdm_8723 btdm; +}; + +struct rtl_hal { + struct ieee80211_hw *hw; + bool driver_is_goingto_unload; + bool up_first_time; + bool first_init; + bool being_init_adapter; + bool bbrf_ready; + bool mac_func_enable; + bool pre_edcca_enable; + struct bt_coexist_8723 hal_coex_8723; + + enum intf_type interface; + u16 hw_type; /*92c or 92d or 92s and so on */ + u8 ic_class; + u8 oem_id; + u32 version; /*version of chip */ + u8 state; /*stop 0, start 1 */ + u8 board_type; + u8 package_type; + u8 external_pa; + + u8 pa_mode; + u8 pa_type_2g; + u8 pa_type_5g; + u8 lna_type_2g; + u8 lna_type_5g; + u8 external_pa_2g; + u8 external_lna_2g; + u8 external_pa_5g; + u8 external_lna_5g; + u8 type_glna; + u8 type_gpa; + u8 type_alna; + u8 type_apa; + u8 rfe_type; + + /*firmware */ + u32 fwsize; + u8 *pfirmware; + u16 fw_version; + u16 fw_subversion; + bool h2c_setinprogress; + u8 last_hmeboxnum; + bool fw_ready; + /*Reserve page start offset except beacon in TxQ. */ + u8 fw_rsvdpage_startoffset; + u8 h2c_txcmd_seq; + u8 current_ra_rate; + + /* FW Cmd IO related */ + u16 fwcmd_iomap; + u32 fwcmd_ioparam; + bool set_fwcmd_inprogress; + u8 current_fwcmd_io; + + struct p2p_ps_offload_t p2p_ps_offload; + bool fw_clk_change_in_progress; + bool allow_sw_to_change_hwclc; + u8 fw_ps_state; + /**/ + bool driver_going2unload; + + /*AMPDU init min space*/ + u8 minspace_cfg; /*For Min spacing configurations */ + + /* Dual mac */ + enum macphy_mode macphymode; + enum band_type current_bandtype; /* 0:2.4G, 1:5G */ + enum band_type current_bandtypebackup; + enum band_type bandset; + /* dual MAC 0--Mac0 1--Mac1 */ + u32 interfaceindex; + /* just for DualMac S3S4 */ + u8 macphyctl_reg; + bool earlymode_enable; + u8 max_earlymode_num; + /* Dual mac*/ + bool during_mac0init_radiob; + bool during_mac1init_radioa; + bool reloadtxpowerindex; + /* True if IMR or IQK have done + * for 2.4G in scan progress + */ + bool load_imrandiqk_setting_for2g; + + bool disable_amsdu_8k; + bool master_of_dmsp; + bool slave_of_dmsp; + + u16 rx_tag;/*for 92ee*/ + u8 rts_en; + + /*for wowlan*/ + bool wow_enable; + bool enter_pnp_sleep; + bool wake_from_pnp_sleep; + bool wow_enabled; + __kernel_time_t last_suspend_sec; + u32 wowlan_fwsize; + u8 *wowlan_firmware; + + u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/ + + bool real_wow_v2_enable; + bool re_init_llt_table; +}; + +struct rtl_security { + /*default 0 */ + bool use_sw_sec; + + bool being_setkey; + bool use_defaultkey; + /*Encryption Algorithm for Unicast Packet */ + enum rt_enc_alg pairwise_enc_algorithm; + /*Encryption Algorithm for Brocast/Multicast */ + enum rt_enc_alg group_enc_algorithm; + /*Cam Entry Bitmap */ + u32 hwsec_cam_bitmap; + u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN]; + /* local Key buffer, indx 0 is for + * pairwise key 1-4 is for agoup key. + */ + u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; + u8 key_len[KEY_BUF_SIZE]; + + /* The pointer of Pairwise Key, + * it always points to KeyBuf[4] + */ + u8 *pairwise_key; +}; + +#define ASSOCIATE_ENTRY_NUM 33 + +struct fast_ant_training { + u8 bssid[6]; + u8 antsel_rx_keep_0; + u8 antsel_rx_keep_1; + u8 antsel_rx_keep_2; + u32 ant_sum[7]; + u32 ant_cnt[7]; + u32 ant_ave[7]; + u8 fat_state; + u32 train_idx; + u8 antsel_a[ASSOCIATE_ENTRY_NUM]; + u8 antsel_b[ASSOCIATE_ENTRY_NUM]; + u8 antsel_c[ASSOCIATE_ENTRY_NUM]; + u32 main_ant_sum[ASSOCIATE_ENTRY_NUM]; + u32 aux_ant_sum[ASSOCIATE_ENTRY_NUM]; + u32 main_ant_cnt[ASSOCIATE_ENTRY_NUM]; + u32 aux_ant_cnt[ASSOCIATE_ENTRY_NUM]; + u8 rx_idle_ant; + bool becomelinked; +}; + +struct dm_phy_dbg_info { + s8 rx_snrdb[4]; + u64 num_qry_phy_status; + u64 num_qry_phy_status_cck; + u64 num_qry_phy_status_ofdm; + u16 num_qry_beacon_pkt; + u16 num_non_be_pkt; + s32 rx_evm[4]; +}; + +struct rtl_dm { + /*PHY status for Dynamic Management */ + long entry_min_undec_sm_pwdb; + long undec_sm_cck; + long undec_sm_pwdb; /*out dm */ + long entry_max_undec_sm_pwdb; + s32 ofdm_pkt_cnt; + bool dm_initialgain_enable; + bool dynamic_txpower_enable; + bool current_turbo_edca; + bool is_any_nonbepkts; /*out dm */ + bool is_cur_rdlstate; + bool txpower_trackinginit; + bool disable_framebursting; + bool cck_inch14; + bool txpower_tracking; + bool useramask; + bool rfpath_rxenable[4]; + bool inform_fw_driverctrldm; + bool current_mrc_switch; + u8 txpowercount; + u8 powerindex_backup[6]; + + u8 thermalvalue_rxgain; + u8 thermalvalue_iqk; + u8 thermalvalue_lck; + u8 thermalvalue; + u8 last_dtp_lvl; + u8 thermalvalue_avg[AVG_THERMAL_NUM]; + u8 thermalvalue_avg_index; + u8 tm_trigger; + bool done_txpower; + u8 dynamic_txhighpower_lvl; /*Tx high power level */ + u8 dm_flag; /*Indicate each dynamic mechanism's status. */ + u8 dm_flag_tmp; + u8 dm_type; + u8 dm_rssi_sel; + u8 txpower_track_control; + bool interrupt_migration; + bool disable_tx_int; + s8 ofdm_index[MAX_RF_PATH]; + u8 default_ofdm_index; + u8 default_cck_index; + s8 cck_index; + s8 delta_power_index[MAX_RF_PATH]; + s8 delta_power_index_last[MAX_RF_PATH]; + s8 power_index_offset[MAX_RF_PATH]; + s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_cck_idx; + bool modify_txagc_flag_path_a; + bool modify_txagc_flag_path_b; + + bool one_entry_only; + struct dm_phy_dbg_info dbginfo; + + /* Dynamic ATC switch */ + bool atc_status; + bool large_cfo_hit; + bool is_freeze; + int cfo_tail[2]; + int cfo_ave_pre; + int crystal_cap; + u8 cfo_threshold; + u32 packet_count; + u32 packet_count_pre; + u8 tx_rate; + + /*88e tx power tracking*/ + u8 swing_idx_ofdm[MAX_RF_PATH]; + u8 swing_idx_ofdm_cur; + u8 swing_idx_ofdm_base[MAX_RF_PATH]; + bool swing_flag_ofdm; + u8 swing_idx_cck; + u8 swing_idx_cck_cur; + u8 swing_idx_cck_base; + bool swing_flag_cck; + + s8 swing_diff_2g; + s8 swing_diff_5g; + + /* DMSP */ + bool supp_phymode_switch; + + /* DulMac */ + struct fast_ant_training fat_table; + + u8 resp_tx_path; + u8 path_sel; + u32 patha_sum; + u32 pathb_sum; + u32 patha_cnt; + u32 pathb_cnt; + + u8 pre_channel; + u8 *p_channel; + u8 linked_interval; + + u64 last_tx_ok_cnt; + u64 last_rx_ok_cnt; +}; + +#define EFUSE_MAX_LOGICAL_SIZE 512 + +struct rtl_efuse { + bool autoload_ok; + bool bootfromefuse; + u16 max_physical_size; + + u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; + u16 efuse_usedbytes; + u8 efuse_usedpercentage; +#ifdef EFUSE_REPG_WORKAROUND + bool efuse_re_pg_sec1flag; + u8 efuse_re_pg_data[8]; +#endif + + u8 autoload_failflag; + u8 autoload_status; + + short epromtype; + u16 eeprom_vid; + u16 eeprom_did; + u16 eeprom_svid; + u16 eeprom_smid; + u8 eeprom_oemid; + u16 eeprom_channelplan; + u8 eeprom_version; + u8 board_type; + u8 external_pa; + + u8 dev_addr[6]; + u8 wowlan_enable; + u8 antenna_div_cfg; + u8 antenna_div_type; + + bool txpwr_fromeprom; + u8 eeprom_crystalcap; + u8 eeprom_tssi[2]; + u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */ + u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX]; + u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_cck[MAX_RF_PATH][CHANNEL_GROUP_MAX_2G]; + u8 eeprom_chnlarea_txpwr_ht40_1s[MAX_RF_PATH][CHANNEL_GROUP_MAX]; + u8 eprom_chnl_txpwr_ht40_2sdf[MAX_RF_PATH][CHANNEL_GROUP_MAX]; + + u8 internal_pa_5g[2]; /* pathA / pathB */ + u8 eeprom_c9; + u8 eeprom_cc; + + /*For power group */ + u8 eeprom_pwrgroup[2][3]; + u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; + + u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G]; + /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + + /*--------------------------------------------------------* + * 8192CE\8192SE\8192DE\8723AE use the following 4 arrays, + * other ICs (8188EE\8723BE\8192EE\8812AE...) + * define new arrays in Windows code. + * BUT, in linux code, we use the same array for all ICs. + * + * The Correspondance relation between two arrays is: + * txpwr_cckdiff[][] == CCK_24G_Diff[][] + * txpwr_ht20diff[][] == BW20_24G_Diff[][] + * txpwr_ht40diff[][] == BW40_24G_Diff[][] + * txpwr_legacyhtdiff[][] == OFDM_24G_Diff[][] + * + * Sizes of these arrays are decided by the larger ones. + */ + s8 txpwr_cckdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_ht20diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_ht40diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_legacyhtdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + + u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M]; + s8 txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT]; + + u8 txpwr_safetyflag; /* Band edge enable flag */ + u16 eeprom_txpowerdiff; + u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */ + u8 antenna_txpwdiff[3]; + + u8 eeprom_regulatory; + u8 eeprom_thermalmeter; + u8 thermalmeter[2]; /*ThermalMeter, index 0 for RFIC0, 1 for RFIC1 */ + u16 tssi_13dbm; + u8 crystalcap; /* CrystalCap. */ + u8 delta_iqk; + u8 delta_lck; + + u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ + bool apk_thermalmeterignore; + + bool b1x1_recvcombine; + bool b1ss_support; + + /*channel plan */ + u8 channel_plan; +}; + +struct rtl_tx_report { + atomic_t sn; + u16 last_sent_sn; + unsigned long last_sent_time; + u16 last_recv_sn; +}; + +struct rtl_ps_ctl { + bool pwrdomain_protect; + bool in_powersavemode; + bool rfchange_inprogress; + bool swrf_processing; + bool hwradiooff; + /* just for PCIE ASPM + * If it supports ASPM, Offset[560h] = 0x40, + * otherwise Offset[560h] = 0x00. + */ + bool support_aspm; + bool support_backdoor; + + /*for LPS */ + enum rt_psmode dot11_psmode; /*Power save mode configured. */ + bool swctrl_lps; + bool leisure_ps; + bool fwctrl_lps; + u8 fwctrl_psmode; + /*For Fw control LPS mode */ + u8 reg_fwctrl_lps; + /*Record Fw PS mode status. */ + bool fw_current_inpsmode; + u8 reg_max_lps_awakeintvl; + bool report_linked; + bool low_power_enable;/*for 32k*/ + + /*for IPS */ + bool inactiveps; + + u32 rfoff_reason; + + /*RF OFF Level */ + u32 cur_ps_level; + u32 reg_rfps_level; + + /*just for PCIE ASPM */ + u8 const_amdpci_aspm; + bool pwrdown_mode; + + enum rf_pwrstate inactive_pwrstate; + enum rf_pwrstate rfpwr_state; /*cur power state */ + + /* for SW LPS*/ + bool sw_ps_enabled; + bool state; + bool state_inap; + bool multi_buffered; + u16 nullfunc_seq; + unsigned int dtim_counter; + unsigned int sleep_ms; + unsigned long last_sleep_jiffies; + unsigned long last_awake_jiffies; + unsigned long last_delaylps_stamp_jiffies; + unsigned long last_dtim; + unsigned long last_beacon; + unsigned long last_action; + unsigned long last_slept; + + /*For P2P PS */ + struct rtl_p2p_ps_info p2p_ps_info; + u8 pwr_mode; + u8 smart_ps; + + /* wake up on line */ + u8 wo_wlan_mode; + u8 arp_offload_enable; + u8 gtk_offload_enable; + /* Used for WOL, indicates the reason for waking event.*/ + u32 wakeup_reason; + /* Record the last waking time for comparison with setting key. */ + u64 last_wakeup_time; +}; + +struct rtl_stats { + u8 psaddr[ETH_ALEN]; + u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u8 rate; /* hw desc rate */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 length; + u8 signalquality; /*in 0-100 index. */ + /* + * Real power in dBm for this packet, + * no beautification and aggregation. + */ + s32 recvsignalpower; + s8 rxpower; /*in dBm Translate from PWdB */ + u8 signalstrength; /*in 0-100 index. */ + u16 hwerror:1; + u16 crc:1; + u16 icv:1; + u16 shortpreamble:1; + u16 antenna:1; + u16 decrypted:1; + u16 wakeup:1; + u32 timestamp_low; + u32 timestamp_high; + bool shift; + + u8 rx_drvinfo_size; + u8 rx_bufshift; + bool isampdu; + bool isfirst_ampdu; + bool rx_is40mhzpacket; + u8 rx_packet_bw; + u32 rx_pwdb_all; + u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ + s8 rx_mimo_signalquality[4]; + u8 rx_mimo_evm_dbm[4]; + u16 cfo_short[4]; /* per-path's Cfo_short */ + u16 cfo_tail[4]; + + s8 rx_mimo_sig_qual[4]; + u8 rx_pwr[4]; /* per-path's pwdb */ + u8 rx_snr[4]; /* per-path's SNR */ + u8 bandwidth; + u8 bt_coex_pwr_adjust; + bool packet_matchbssid; + bool is_cck; + bool is_ht; + bool packet_toself; + bool packet_beacon; /*for rssi */ + s8 cck_adc_pwdb[4]; /*for rx path selection */ + + bool is_vht; + bool is_short_gi; + u8 vht_nss; + + u8 packet_report_type; + + u32 macid; + u8 wake_match; + u32 bt_rx_rssi_percentage; + u32 macid_valid_entry[2]; +}; + +struct rt_link_detect { + /* count for roaming */ + u32 bcn_rx_inperiod; + u32 roam_times; + + u32 num_tx_in4period[4]; + u32 num_rx_in4period[4]; + + u32 num_tx_inperiod; + u32 num_rx_inperiod; + + bool busytraffic; + bool tx_busy_traffic; + bool rx_busy_traffic; + bool higher_busytraffic; + bool higher_busyrxtraffic; + + u32 tidtx_in4period[MAX_TID_COUNT][4]; + u32 tidtx_inperiod[MAX_TID_COUNT]; + bool higher_busytxtraffic[MAX_TID_COUNT]; +}; + +struct rtl_tcb_desc { + u8 packet_bw:2; + u8 multicast:1; + u8 broadcast:1; + + u8 rts_stbc:1; + u8 rts_enable:1; + u8 cts_enable:1; + u8 rts_use_shortpreamble:1; + u8 rts_use_shortgi:1; + u8 rts_sc:1; + u8 rts_bw:1; + u8 rts_rate; + + u8 use_shortgi:1; + u8 use_shortpreamble:1; + u8 use_driver_rate:1; + u8 disable_ratefallback:1; + + u8 use_spe_rpt:1; + + u8 ratr_index; + u8 mac_id; + u8 hw_rate; + + u8 last_inipkt:1; + u8 cmd_or_init:1; + u8 queue_index; + + /* early mode */ + u8 empkt_num; + /* The max value by HW */ + u32 empkt_len[10]; + bool tx_enable_sw_calc_duration; +}; + +struct rtl_wow_pattern { + u8 type; + u16 crc; + u32 mask[4]; +}; + +struct rtl_hal_ops { + int (*init_sw_vars)(struct ieee80211_hw *hw); + void (*deinit_sw_vars)(struct ieee80211_hw *hw); + void (*read_chip_version)(struct ieee80211_hw *hw); + void (*read_eeprom_info)(struct ieee80211_hw *hw); + void (*interrupt_recognized)(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); + int (*hw_init)(struct ieee80211_hw *hw); + void (*hw_disable)(struct ieee80211_hw *hw); + void (*hw_suspend)(struct ieee80211_hw *hw); + void (*hw_resume)(struct ieee80211_hw *hw); + void (*enable_interrupt)(struct ieee80211_hw *hw); + void (*disable_interrupt)(struct ieee80211_hw *hw); + int (*set_network_type)(struct ieee80211_hw *hw, + enum nl80211_iftype type); + void (*set_chk_bssid)(struct ieee80211_hw *hw, + bool check_bssid); + void (*set_bw_mode)(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); + u8 (*switch_channel)(struct ieee80211_hw *hw); + void (*set_qos)(struct ieee80211_hw *hw, int aci); + void (*set_bcn_reg)(struct ieee80211_hw *hw); + void (*set_bcn_intv)(struct ieee80211_hw *hw); + void (*update_interrupt_mask)(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); + void (*get_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*set_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*update_rate_tbl)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_leve, + bool update_bw); + void (*pre_fill_tx_bd_desc)(struct ieee80211_hw *hw, u8 *tx_bd_desc, + u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t addr); + void (*update_rate_mask)(struct ieee80211_hw *hw, u8 rssi_level); + u16 (*rx_desc_buff_remained_cnt)(struct ieee80211_hw *hw, + u8 queue_index); + void (*rx_check_dma_ok)(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index); + void (*fill_tx_desc)(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); + void (*fill_fake_txdesc)(struct ieee80211_hw *hw, u8 *pdesc, + u32 buffer_len, bool bispspoll); + void (*fill_tx_cmddesc)(struct ieee80211_hw *hw, u8 *pdesc, + bool firstseg, bool lastseg, + struct sk_buff *skb); + void (*fill_tx_special_desc)(struct ieee80211_hw *hw, + u8 *pdesc, u8 *pbd_desc, + struct sk_buff *skb, u8 hw_queue); + bool (*query_rx_desc)(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); + void (*set_channel_access)(struct ieee80211_hw *hw); + bool (*radio_onoff_checking)(struct ieee80211_hw *hw, u8 *valid); + void (*dm_watchdog)(struct ieee80211_hw *hw); + void (*scan_operation_backup)(struct ieee80211_hw *hw, u8 operation); + bool (*set_rf_power_state)(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + void (*led_control)(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + void (*set_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); + u64 (*get_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name); + bool (*is_tx_desc_closed)(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); + void (*tx_polling)(struct ieee80211_hw *hw, u8 hw_queue); + void (*enable_hw_sec)(struct ieee80211_hw *hw); + void (*set_key)(struct ieee80211_hw *hw, u32 key_index, + u8 *macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + void (*init_sw_leds)(struct ieee80211_hw *hw); + void (*deinit_sw_leds)(struct ieee80211_hw *hw); + u32 (*get_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); + void (*set_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); + u32 (*get_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); + void (*set_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); + void (*linked_set_reg)(struct ieee80211_hw *hw); + void (*chk_switch_dmdp)(struct ieee80211_hw *hw); + void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw); + void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw); + bool (*phy_rf6052_config)(struct ieee80211_hw *hw); + void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw, + u8 *powerlevel); + void (*phy_rf6052_set_ofdm_txpower)(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); + bool (*config_bb_with_headerfile)(struct ieee80211_hw *hw, + u8 configtype); + bool (*config_bb_with_pgheaderfile)(struct ieee80211_hw *hw, + u8 configtype); + void (*phy_lc_calibrate)(struct ieee80211_hw *hw, bool is2t); + void (*phy_set_bw_mode_callback)(struct ieee80211_hw *hw); + void (*dm_dynamic_txpower)(struct ieee80211_hw *hw); + void (*c2h_command_handle)(struct ieee80211_hw *hw); + void (*bt_wifi_media_status_notify)(struct ieee80211_hw *hw, + bool mstate); + void (*bt_coex_off_before_lps)(struct ieee80211_hw *hw); + void (*fill_h2c_cmd)(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); + void (*set_default_port_id_cmd)(struct ieee80211_hw *hw); + bool (*get_btc_status)(void); + bool (*is_fw_header)(struct rtlwifi_firmware_header *hdr); + u32 (*rx_command_packet)(struct ieee80211_hw *hw, + const struct rtl_stats *status, + struct sk_buff *skb); + void (*add_wowlan_pattern)(struct ieee80211_hw *hw, + struct rtl_wow_pattern *rtl_pattern, + u8 index); + u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx); + void (*c2h_content_parsing)(struct ieee80211_hw *hw, u8 tag, u8 len, + u8 *val); + /* ops for halmac cb */ + bool (*halmac_cb_init_mac_register)(struct rtl_priv *rtlpriv); + bool (*halmac_cb_init_bb_rf_register)(struct rtl_priv *rtlpriv); + bool (*halmac_cb_write_data_rsvd_page)(struct rtl_priv *rtlpriv, + u8 *buf, u32 size); + bool (*halmac_cb_write_data_h2c)(struct rtl_priv *rtlpriv, u8 *buf, + u32 size); + /* ops for phydm cb */ + u8 (*get_txpower_index)(struct ieee80211_hw *hw, u8 path, + u8 rate, u8 bandwidth, u8 channel); + void (*set_tx_power_index_by_rs)(struct ieee80211_hw *hw, + u8 channel, u8 path, + enum rate_section rs); + void (*store_tx_power_by_rate)(struct ieee80211_hw *hw, + u32 band, u32 rfpath, + u32 txnum, u32 regaddr, + u32 bitmask, u32 data); + void (*phy_set_txpower_limit)(struct ieee80211_hw *hw, u8 *pregulation, + u8 *pband, u8 *pbandwidth, + u8 *prate_section, u8 *prf_path, + u8 *pchannel, u8 *ppower_limit); +}; + +struct rtl_intf_ops { + /*com */ + void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); + int (*adapter_start)(struct ieee80211_hw *hw); + void (*adapter_stop)(struct ieee80211_hw *hw); + bool (*check_buddy_priv)(struct ieee80211_hw *hw, + struct rtl_priv **buddy_priv); + + int (*adapter_tx)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb, + struct rtl_tcb_desc *ptcb_desc); + void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); + int (*reset_trx_ring)(struct ieee80211_hw *hw); + bool (*waitq_insert)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb); + + /*pci */ + void (*disable_aspm)(struct ieee80211_hw *hw); + void (*enable_aspm)(struct ieee80211_hw *hw); + + /*usb */ +}; + +struct rtl_mod_params { + /* default: 0,0 */ + u64 debug_mask; + /* default: 0 = using hardware encryption */ + bool sw_crypto; + + /* default: 0 = DBG_EMERG (0)*/ + int debug_level; + + /* default: 1 = using no linked power save */ + bool inactiveps; + + /* default: 1 = using linked sw power save */ + bool swctrl_lps; + + /* default: 1 = using linked fw power save */ + bool fwctrl_lps; + + /* default: 0 = not using MSI interrupts mode + * submodules should set their own default value + */ + bool msi_support; + + /* default: 0 = dma 32 */ + bool dma64; + + /* default: 1 = enable aspm */ + int aspm_support; + + /* default 0: 1 means disable */ + bool disable_watchdog; + + /* default 0: 1 means do not disable interrupts */ + bool int_clear; + + /* select antenna */ + int ant_sel; +}; + +struct rtl_hal_usbint_cfg { + /* data - rx */ + u32 in_ep_num; + u32 rx_urb_num; + u32 rx_max_size; + + /* op - rx */ + void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); + void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); + + /* tx */ + void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); + int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *, + struct sk_buff *); + struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, + struct sk_buff_head *); + + /* endpoint mapping */ + int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); + u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); +}; + +struct rtl_hal_cfg { + u8 bar_id; + bool write_readback; + char *name; + char *alt_fw_name; + struct rtl_hal_ops *ops; + struct rtl_mod_params *mod_params; + struct rtl_hal_usbint_cfg *usb_interface_cfg; + enum rtl_spec_ver spec_ver; + + /* this map used for some registers or vars + * defined int HAL but used in MAIN + */ + u32 maps[RTL_VAR_MAP_MAX]; + +}; + +struct rtl_locks { + /* mutex */ + struct mutex conf_mutex; + struct mutex ips_mutex; /* mutex for enter/leave IPS */ + struct mutex lps_mutex; /* mutex for enter/leave LPS */ + + /*spin lock */ + spinlock_t irq_th_lock; + spinlock_t h2c_lock; + spinlock_t rf_ps_lock; + spinlock_t rf_lock; + spinlock_t waitq_lock; + spinlock_t entry_list_lock; + spinlock_t usb_lock; + spinlock_t c2hcmd_lock; + spinlock_t scan_list_lock; /* lock for the scan list */ + + /*FW clock change */ + spinlock_t fw_ps_lock; + + /*Dual mac*/ + spinlock_t cck_and_rw_pagea_lock; + + spinlock_t iqk_lock; +}; + +struct rtl_works { + struct ieee80211_hw *hw; + + /*timer */ + struct timer_list watchdog_timer; + struct timer_list dualmac_easyconcurrent_retrytimer; + struct timer_list fw_clockoff_timer; + struct timer_list fast_antenna_training_timer; + /*task */ + struct tasklet_struct irq_tasklet; + struct tasklet_struct irq_prepare_bcn_tasklet; + + /*work queue */ + struct workqueue_struct *rtl_wq; + struct delayed_work watchdog_wq; + struct delayed_work ips_nic_off_wq; + struct delayed_work c2hcmd_wq; + + /* For SW LPS */ + struct delayed_work ps_work; + struct delayed_work ps_rfon_wq; + struct delayed_work fwevt_wq; + + struct work_struct lps_change_work; + struct work_struct fill_h2c_cmd; +}; + +struct rtl_debug { + /* add for debug */ + struct dentry *debugfs_dir; + char debugfs_name[20]; + + char *msg_buf; +}; + +#define MIMO_PS_STATIC 0 +#define MIMO_PS_DYNAMIC 1 +#define MIMO_PS_NOLIMIT 3 + +struct rtl_dualmac_easy_concurrent_ctl { + enum band_type currentbandtype_backfordmdp; + bool close_bbandrf_for_dmsp; + bool change_to_dmdp; + bool change_to_dmsp; + bool switch_in_process; +}; + +struct rtl_dmsp_ctl { + bool activescan_for_slaveofdmsp; + bool scan_for_anothermac_fordmsp; + bool scan_for_itself_fordmsp; + bool writedig_for_anothermacofdmsp; + u32 curdigvalue_for_anothermacofdmsp; + bool changecckpdstate_for_anothermacofdmsp; + u8 curcckpdstate_for_anothermacofdmsp; + bool changetxhighpowerlvl_for_anothermacofdmsp; + u8 curtxhighlvl_for_anothermacofdmsp; + long rssivalmin_for_anothermacofdmsp; +}; + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + u8 pre_rfstate; + u8 cur_rfstate; + u8 initialize; + long rssi_val_min; +}; + +struct dig_t { + u32 rssi_lowthresh; + u32 rssi_highthresh; + u32 fa_lowthresh; + u32 fa_highthresh; + long last_min_undec_pwdb_for_dm; + long rssi_highpower_lowthresh; + long rssi_highpower_highthresh; + u32 recover_cnt; + u32 pre_igvalue; + u32 cur_igvalue; + long rssi_val; + u8 dig_enable_flag; + u8 dig_ext_port_stage; + u8 dig_algorithm; + u8 dig_twoport_algorithm; + u8 dig_dbgmode; + u8 dig_slgorithm_switch; + u8 cursta_cstate; + u8 presta_cstate; + u8 curmultista_cstate; + u8 stop_dig; + s8 back_val; + s8 back_range_max; + s8 back_range_min; + u8 rx_gain_max; + u8 rx_gain_min; + u8 min_undec_pwdb_for_dm; + u8 rssi_val_min; + u8 pre_cck_cca_thres; + u8 cur_cck_cca_thres; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + u8 pre_ccastate; + u8 cur_ccasate; + u8 large_fa_hit; + u8 forbidden_igi; + u8 dig_state; + u8 dig_highpwrstate; + u8 cur_sta_cstate; + u8 pre_sta_cstate; + u8 cur_ap_cstate; + u8 pre_ap_cstate; + u8 cur_pd_thstate; + u8 pre_pd_thstate; + u8 cur_cs_ratiostate; + u8 pre_cs_ratiostate; + u8 backoff_enable_flag; + s8 backoffval_range_max; + s8 backoffval_range_min; + u8 dig_min_0; + u8 dig_min_1; + u8 bt30_cur_igi; + bool media_connect_0; + bool media_connect_1; + + u32 antdiv_rssi_max; + u32 rssi_max; +}; + +struct rtl_global_var { + /* from this list we can get + * other adapter's rtl_priv + */ + struct list_head glb_priv_list; + spinlock_t glb_list_lock; +}; + +#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */ + +struct rtl_btc_info { + u8 bt_type; + u8 btcoexist; + u8 ant_num; + u8 single_ant_path; + + u8 ap_num; + bool in_4way; + unsigned long in_4way_ts; +}; + +struct bt_coexist_info { + struct rtl_btc_ops *btc_ops; + struct rtl_btc_info btc_info; + /* btc context */ + void *btc_context; + void *wifi_only_context; + /* EEPROM BT info. */ + u8 eeprom_bt_coexist; + u8 eeprom_bt_type; + u8 eeprom_bt_ant_num; + u8 eeprom_bt_ant_isol; + u8 eeprom_bt_radio_shared; + + u8 bt_coexistence; + u8 bt_ant_num; + u8 bt_coexist_type; + u8 bt_state; + u8 bt_cur_state; /* 0:on, 1:off */ + u8 bt_ant_isolation; /* 0:good, 1:bad */ + u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */ + u8 bt_service; + u8 bt_radio_shared_type; + u8 bt_rfreg_origin_1e; + u8 bt_rfreg_origin_1f; + u8 bt_rssi_state; + u32 ratio_tx; + u32 ratio_pri; + u32 bt_edca_ul; + u32 bt_edca_dl; + + bool init_set; + bool bt_busy_traffic; + bool bt_traffic_mode_set; + bool bt_non_traffic_mode_set; + + bool fw_coexist_all_off; + bool sw_coexist_all_off; + bool hw_coexist_all_off; + u32 cstate; + u32 previous_state; + u32 cstate_h; + u32 previous_state_h; + + u8 bt_pre_rssi_state; + u8 bt_pre_rssi_state1; + + u8 reg_bt_iso; + u8 reg_bt_sco; + bool balance_on; + u8 bt_active_zero_cnt; + bool cur_bt_disabled; + bool pre_bt_disabled; + + u8 bt_profile_case; + u8 bt_profile_action; + bool bt_busy; + bool hold_for_bt_operation; + u8 lps_counter; +}; + +struct rtl_btc_ops { + void (*btc_init_variables)(struct rtl_priv *rtlpriv); + void (*btc_init_variables_wifi_only)(struct rtl_priv *rtlpriv); + void (*btc_deinit_variables)(struct rtl_priv *rtlpriv); + void (*btc_init_hal_vars)(struct rtl_priv *rtlpriv); + void (*btc_power_on_setting)(struct rtl_priv *rtlpriv); + void (*btc_init_hw_config)(struct rtl_priv *rtlpriv); + void (*btc_init_hw_config_wifi_only)(struct rtl_priv *rtlpriv); + void (*btc_ips_notify)(struct rtl_priv *rtlpriv, u8 type); + void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type); + void (*btc_scan_notify)(struct rtl_priv *rtlpriv, u8 scantype); + void (*btc_scan_notify_wifi_only)(struct rtl_priv *rtlpriv, + u8 scantype); + void (*btc_connect_notify)(struct rtl_priv *rtlpriv, u8 action); + void (*btc_mediastatus_notify)(struct rtl_priv *rtlpriv, + enum rt_media_status mstatus); + void (*btc_periodical)(struct rtl_priv *rtlpriv); + void (*btc_halt_notify)(struct rtl_priv *rtlpriv); + void (*btc_btinfo_notify)(struct rtl_priv *rtlpriv, + u8 *tmp_buf, u8 length); + void (*btc_btmpinfo_notify)(struct rtl_priv *rtlpriv, + u8 *tmp_buf, u8 length); + bool (*btc_is_limited_dig)(struct rtl_priv *rtlpriv); + bool (*btc_is_disable_edca_turbo)(struct rtl_priv *rtlpriv); + bool (*btc_is_bt_disabled)(struct rtl_priv *rtlpriv); + void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv, + u8 pkt_type); + void (*btc_switch_band_notify)(struct rtl_priv *rtlpriv, u8 type, + bool scanning); + void (*btc_switch_band_notify_wifi_only)(struct rtl_priv *rtlpriv, + u8 type, bool scanning); + void (*btc_display_bt_coex_info)(struct rtl_priv *rtlpriv, + struct seq_file *m); + void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len); + u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv); + u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv); + bool (*btc_is_bt_ctrl_lps)(struct rtl_priv *rtlpriv); + void (*btc_get_ampdu_cfg)(struct rtl_priv *rtlpriv, u8 *reject_agg, + u8 *ctrl_agg_size, u8 *agg_size); + bool (*btc_is_bt_lps_on)(struct rtl_priv *rtlpriv); +}; + +struct rtl_halmac_ops { + int (*halmac_init_adapter)(struct rtl_priv *); + int (*halmac_deinit_adapter)(struct rtl_priv *); + int (*halmac_init_hal)(struct rtl_priv *); + int (*halmac_deinit_hal)(struct rtl_priv *); + int (*halmac_poweron)(struct rtl_priv *); + int (*halmac_poweroff)(struct rtl_priv *); + + int (*halmac_phy_power_switch)(struct rtl_priv *rtlpriv, u8 enable); + int (*halmac_set_mac_address)(struct rtl_priv *rtlpriv, u8 hwport, + u8 *addr); + int (*halmac_set_bssid)(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr); + + int (*halmac_get_physical_efuse_size)(struct rtl_priv *rtlpriv, + u32 *size); + int (*halmac_read_physical_efuse_map)(struct rtl_priv *rtlpriv, + u8 *map, u32 size); + int (*halmac_get_logical_efuse_size)(struct rtl_priv *rtlpriv, + u32 *size); + int (*halmac_read_logical_efuse_map)(struct rtl_priv *rtlpriv, u8 *map, + u32 size); + + int (*halmac_set_bandwidth)(struct rtl_priv *rtlpriv, u8 channel, + u8 pri_ch_idx, u8 bw); + + int (*halmac_c2h_handle)(struct rtl_priv *rtlpriv, u8 *c2h, u32 size); + + int (*halmac_chk_txdesc)(struct rtl_priv *rtlpriv, u8 *txdesc, + u32 size); +}; + +struct rtl_halmac_indicator { + struct completion *comp; + u32 wait_ms; + + u8 *buffer; + u32 buf_size; + u32 ret_size; + u32 status; +}; + +struct rtl_halmac { + struct rtl_halmac_ops *ops; /* halmac ops (halmac.ko own this object) */ + void *internal; /* internal context of halmac, i.e. PHALMAC_ADAPTER */ + struct rtl_halmac_indicator *indicator; /* size=10 */ + + /* flags */ + /* + * send_general_info + * 0: no need to call halmac_send_general_info() + * 1: need to call halmac_send_general_info() + */ + u8 send_general_info; +}; + +struct rtl_phydm_params { + u8 mp_chip; /* 1: MP chip, 0: test chip */ + u8 fab_ver; /* 0: TSMC, 1: UMC, ...*/ + u8 cut_ver; /* 0: A, 1: B, ..., 10: K */ + u8 efuse0x3d7; /* default: 0xff */ + u8 efuse0x3d8; /* default: 0xff */ +}; + +struct rtl_phydm_ops { + /* init/deinit priv */ + int (*phydm_init_priv)(struct rtl_priv *rtlpriv, + struct rtl_phydm_params *params); + int (*phydm_deinit_priv)(struct rtl_priv *rtlpriv); + bool (*phydm_load_txpower_by_rate)(struct rtl_priv *rtlpriv); + bool (*phydm_load_txpower_limit)(struct rtl_priv *rtlpriv); + + /* init hw */ + int (*phydm_init_dm)(struct rtl_priv *rtlpriv); + int (*phydm_deinit_dm)(struct rtl_priv *rtlpriv); + int (*phydm_reset_dm)(struct rtl_priv *rtlpriv); + bool (*phydm_parameter_init)(struct rtl_priv *rtlpriv, bool post); + bool (*phydm_phy_bb_config)(struct rtl_priv *rtlpriv); + bool (*phydm_phy_rf_config)(struct rtl_priv *rtlpriv); + bool (*phydm_phy_mac_config)(struct rtl_priv *rtlpriv); + bool (*phydm_trx_mode)(struct rtl_priv *rtlpriv, + enum radio_mask tx_path, enum radio_mask rx_path, + bool is_tx2_path); + /* watchdog */ + bool (*phydm_watchdog)(struct rtl_priv *rtlpriv); + + /* channel */ + bool (*phydm_switch_band)(struct rtl_priv *rtlpriv, u8 central_ch); + bool (*phydm_switch_channel)(struct rtl_priv *rtlpriv, u8 central_ch); + bool (*phydm_switch_bandwidth)(struct rtl_priv *rtlpriv, + u8 primary_ch_idx, + enum ht_channel_width width); + bool (*phydm_iq_calibrate)(struct rtl_priv *rtlpriv); + bool (*phydm_clear_txpowertracking_state)(struct rtl_priv *rtlpriv); + bool (*phydm_pause_dig)(struct rtl_priv *rtlpriv, bool pause); + + /* read/write reg */ + u32 (*phydm_read_rf_reg)(struct rtl_priv *rtlpriv, + enum radio_path rfpath, + u32 addr, u32 mask); + bool (*phydm_write_rf_reg)(struct rtl_priv *rtlpriv, + enum radio_path rfpath, + u32 addr, u32 mask, u32 data); + u8 (*phydm_read_txagc)(struct rtl_priv *rtlpriv, + enum radio_path rfpath, u8 hw_rate); + bool (*phydm_write_txagc)(struct rtl_priv *rtlpriv, u32 power_index, + enum radio_path rfpath, u8 hw_rate); + + /* RX */ + bool (*phydm_c2h_content_parsing)(struct rtl_priv *rtlpriv, u8 cmd_id, + u8 cmd_len, u8 *content); + bool (*phydm_query_phy_status)(struct rtl_priv *rtlpriv, u8 *phystrpt, + struct ieee80211_hdr *hdr, + struct rtl_stats *pstatus); + + /* TX */ + u8 (*phydm_rate_id_mapping)(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw); + bool (*phydm_get_ra_bitmap)(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw, + u8 tx_rate_level, /* 0~6 */ + u32 *tx_bitmap_msb, + u32 *tx_bitmap_lsb); + + /* STA */ + bool (*phydm_add_sta)(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta); + bool (*phydm_del_sta)(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta); + + /* BTC */ + u32 (*phydm_get_version)(struct rtl_priv *rtlpriv); + bool (*phydm_modify_ra_pcr_threshold)(struct rtl_priv *rtlpriv, + u8 ra_offset_direction, + u8 ra_threshold_offset); + u32 (*phydm_query_counter)(struct rtl_priv *rtlpriv, + const char *info_type); + + /* debug */ + bool (*phydm_debug_cmd)(struct rtl_priv *rtlpriv, char *in, u32 in_len, + char *out, u32 out_len); + +}; + +struct rtl_phydm { + struct rtl_phydm_ops *ops;/* phydm ops (phydm_mod.ko own this object) */ + void *internal; /* internal context of phydm, i.e. PHY_DM_STRUCT */ + + u8 adaptivity_en; + /* debug */ + u16 forced_data_rate; + u8 forced_igi_lb; + u8 antenna_test; +}; + +struct proxim { + bool proxim_on; + + void *proximity_priv; + int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status, + struct sk_buff *skb); + u8 (*proxim_get_var)(struct ieee80211_hw *hw, u8 type); +}; + +struct rtl_c2hcmd { + struct list_head list; + u8 tag; + u8 len; + u8 *val; +}; + +struct rtl_bssid_entry { + struct list_head list; + u8 bssid[ETH_ALEN]; + u32 age; +}; + +struct rtl_scan_list { + int num; + struct list_head list; /* sort by age */ +}; + +struct rtl_priv { + struct ieee80211_hw *hw; + struct completion firmware_loading_complete; + struct list_head list; + struct rtl_priv *buddy_priv; + struct rtl_global_var *glb_var; + struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl; + struct rtl_dmsp_ctl dmsp_ctl; + struct rtl_locks locks; + struct rtl_works works; + struct rtl_mac mac80211; + struct rtl_hal rtlhal; + struct rtl_regulatory regd; + struct rtl_rfkill rfkill; + struct rtl_io io; + struct rtl_phy phy; + struct rtl_dm dm; + struct rtl_security sec; + struct rtl_efuse efuse; + struct rtl_led_ctl ledctl; + struct rtl_tx_report tx_report; + struct rtl_scan_list scan_list; + struct rtl_ps_ctl psc; + struct rate_adaptive ra; + struct dynamic_primary_cca primarycca; + struct wireless_stats stats; + struct rt_link_detect link_info; + struct false_alarm_statistics falsealm_cnt; + struct rtl_rate_priv *rate_priv; + /* sta entry list for ap adhoc or mesh */ + struct list_head entry_list; + /* c2hcmd list for kthread level access */ + struct list_head c2hcmd_list; + struct rtl_debug dbg; + int max_fw_size; + + /*hal_cfg : for diff cards + *intf_ops : for diff interface usb/pcie + */ + struct rtl_hal_cfg *cfg; + const struct rtl_intf_ops *intf_ops; + + /* this var will be set by set_bit, + * and was used to indicate status of + * interface or hardware + */ + unsigned long status; + + /* tables for dm */ + struct dig_t dm_digtable; + struct ps_t dm_pstable; + + u32 reg_874; + u32 reg_c70; + u32 reg_85c; + u32 reg_a74; + bool reg_init; /* true if regs saved */ + bool bt_operation_on; + __le32 *usb_data; + int usb_data_index; + bool initialized; + bool enter_ps; /* true when entering PS */ + u8 rate_mask[5]; + + /* intel Proximity, should be alloc mem + * in intel Proximity module and can only + * be used in intel Proximity mode + */ + struct proxim proximity; + + /*for bt coexist use*/ + struct bt_coexist_info btcoexist; + + /* halmac for newer IC. (e.g. 8822B) */ + struct rtl_halmac halmac; + + /* phydm for newer IC. (e.g. 8822B) */ + struct rtl_phydm phydm; + + /* separate 92ee from other ICs, + * 92ee use new trx flow. + */ + bool use_new_trx_flow; + +#ifdef CONFIG_PM + struct wiphy_wowlan_support wowlan; +#endif + /* This must be the last item so + * that it points to the data allocated + * beyond this structure like: + * rtl_pci_priv or rtl_usb_priv + */ + u8 priv[0] __aligned(sizeof(void *)); +}; + +#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211)) +#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal)) +#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) +#define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) + +/*************************************** + * Bluetooth Co-existence Related + ***************************************/ + +enum bt_ant_num { + ANT_X2 = 0, + ANT_X1 = 1, +}; + +enum bt_co_type { + BT_2WIRE = 0, + BT_ISSC_3WIRE = 1, + BT_ACCEL = 2, + BT_CSR_BC4 = 3, + BT_CSR_BC8 = 4, + BT_RTL8756 = 5, + BT_RTL8723A = 6, + BT_RTL8821A = 7, + BT_RTL8723B = 8, + BT_RTL8192E = 9, + BT_RTL8812A = 11, + BT_RTL8822B = 12, +}; + +enum bt_total_ant_num { + ANT_TOTAL_X2 = 0, + ANT_TOTAL_X1 = 1 +}; + +enum bt_cur_state { + BT_OFF = 0, + BT_ON = 1, +}; + +enum bt_service_type { + BT_SCO = 0, + BT_A2DP = 1, + BT_HID = 2, + BT_HID_IDLE = 3, + BT_SCAN = 4, + BT_IDLE = 5, + BT_OTHER_ACTION = 6, + BT_BUSY = 7, + BT_OTHERBUSY = 8, + BT_PAN = 9, +}; + +enum bt_radio_shared { + BT_RADIO_SHARED = 0, + BT_RADIO_INDIVIDUAL = 1, +}; + +/**************************************** + * mem access macro define start + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. + ***************************************/ +/* Convert little data endian to host ordering */ +#define EF1BYTE(_val) \ + ((u8)(_val)) +#define EF2BYTE(_val) \ + (le16_to_cpu(_val)) +#define EF4BYTE(_val) \ + (le32_to_cpu(_val)) + +/* Read data from memory */ +#define READEF1BYTE(_ptr) \ + EF1BYTE(*((u8 *)(_ptr))) +/* Read le16 data from memory and convert to host ordering */ +#define READEF2BYTE(_ptr) \ + EF2BYTE(*(_ptr)) +#define READEF4BYTE(_ptr) \ + EF4BYTE(*(_ptr)) + +/* Create a bit mask + * Examples: + * BIT_LEN_MASK_32(0) => 0x00000000 + * BIT_LEN_MASK_32(1) => 0x00000001 + * BIT_LEN_MASK_32(2) => 0x00000003 + * BIT_LEN_MASK_32(32) => 0xFFFFFFFF + */ +#define BIT_LEN_MASK_32(__bitlen) \ + (0xFFFFFFFF >> (32 - (__bitlen))) +#define BIT_LEN_MASK_16(__bitlen) \ + (0xFFFF >> (16 - (__bitlen))) +#define BIT_LEN_MASK_8(__bitlen) \ + (0xFF >> (8 - (__bitlen))) + +/* Create an offset bit mask + * Examples: + * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 + * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 + */ +#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) +#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_16(__bitlen) << (__bitoffset)) +#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) + +/*Description: + * Return 4-byte value in host byte ordering from + * 4-byte pointer in little-endian system. + */ +#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ + (EF4BYTE(*((__le32 *)(__pstart)))) +#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ + (EF2BYTE(*((__le16 *)(__pstart)))) +#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ + (EF1BYTE(*((u8 *)(__pstart)))) + +/* Description: + * Translate subfield (continuous bits in little-endian) of 4-byte + * value to host byte ordering. + */ +#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_32(__bitlen) \ + ) +#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_16(__bitlen) \ + ) +#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_8(__bitlen) \ + ) + +/* Description: + * Mask subfield (continuous bits in little-endian) of 4-byte value + * and return the result in 4-byte value in host byte ordering. + */ +#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)) \ + ) +#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen)) \ + ) +#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \ + ) + +/* Description: + * Set subfield of little-endian 4-byte value to specified value. + */ +#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ + (*((__le32 *)(__pstart)) = \ + cpu_to_le32( \ + LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ + )) +#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ + (*((__le16 *)(__pstart)) = \ + cpu_to_le16( \ + LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ + )) +#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ + (*((u8 *)(__pstart)) = EF1BYTE \ + ( \ + LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ + )) + +#define N_BYTE_ALIGNMENT(__value, __alignment) ((__alignment == 1) ? \ + (__value) : (((__value + __alignment - 1) / \ + __alignment) * __alignment)) + +/**************************************** + * mem access macro define end + ****************************************/ + +#define byte(x, n) ((x >> (8 * n)) & 0xff) + +#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) +#define RTL_WATCH_DOG_TIME 2000 +#define MSECS(t) msecs_to_jiffies(t) +#define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) +#define rtl_dm(rtlpriv) (&((rtlpriv)->dm)) + +#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */ +/*NIC halt, re-initialize hw parameters*/ +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */ +#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ +/*Always enable ASPM and Clock Req in initialization.*/ +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) +/* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/ +#define RT_PS_LEVEL_ASPM BIT(7) +/*When LPS is on, disable 2R if no packet is received or transmitted.*/ +#define RT_RF_LPS_DISALBE_2R BIT(30) +#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ +#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \ + ((ppsc->cur_ps_level & _ps_flg) ? true : false) +#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level &= (~(_ps_flg))) +#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level |= _ps_flg) + +#define container_of_dwork_rtl(x, y, z) \ + container_of(to_delayed_work(x), y, z) + +#define FILL_OCTET_STRING(_os, _octet, _len) \ + (_os).octet = (u8 *)(_octet); \ + (_os).length = (_len) + +#define CP_MACADDR(des, src) \ + ((des)[0] = (src)[0], (des)[1] = (src)[1],\ + (des)[2] = (src)[2], (des)[3] = (src)[3],\ + (des)[4] = (src)[4], (des)[5] = (src)[5]) + +#define LDPC_HT_ENABLE_RX BIT(0) +#define LDPC_HT_ENABLE_TX BIT(1) +#define LDPC_HT_TEST_TX_ENABLE BIT(2) +#define LDPC_HT_CAP_TX BIT(3) + +#define STBC_HT_ENABLE_RX BIT(0) +#define STBC_HT_ENABLE_TX BIT(1) +#define STBC_HT_TEST_TX_ENABLE BIT(2) +#define STBC_HT_CAP_TX BIT(3) + +#define LDPC_VHT_ENABLE_RX BIT(0) +#define LDPC_VHT_ENABLE_TX BIT(1) +#define LDPC_VHT_TEST_TX_ENABLE BIT(2) +#define LDPC_VHT_CAP_TX BIT(3) + +#define STBC_VHT_ENABLE_RX BIT(0) +#define STBC_VHT_ENABLE_TX BIT(1) +#define STBC_VHT_TEST_TX_ENABLE BIT(2) +#define STBC_VHT_CAP_TX BIT(3) + +extern u8 channel5g[CHANNEL_MAX_NUMBER_5G]; + +extern u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M]; + +static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read8_sync(rtlpriv, addr); +} + +static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read16_sync(rtlpriv, addr); +} + +static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read32_sync(rtlpriv, addr); +} + +static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) +{ + rtlpriv->io.write8_async(rtlpriv, addr, val8); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read8_sync(rtlpriv, addr); +} + +static inline void rtl_write_byte_with_val32(struct ieee80211_hw *hw, + u32 addr, u32 val8) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, addr, (u8)val8); +} + +static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) +{ + rtlpriv->io.write16_async(rtlpriv, addr, val16); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read16_sync(rtlpriv, addr); +} + +static inline void rtl_write_dword(struct rtl_priv *rtlpriv, + u32 addr, u32 val32) +{ + rtlpriv->io.write32_async(rtlpriv, addr, val32); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read32_sync(rtlpriv, addr); +} + +static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = hw->priv; + + return rtlpriv->cfg->ops->get_bbreg(hw, regaddr, bitmask); +} + +static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = hw->priv; + + rtlpriv->cfg->ops->set_bbreg(hw, regaddr, bitmask, data); +} + +static inline void rtl_set_bbreg_with_dwmask(struct ieee80211_hw *hw, + u32 regaddr, u32 data) +{ + rtl_set_bbreg(hw, regaddr, 0xffffffff, data); +} + +static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = hw->priv; + + return rtlpriv->cfg->ops->get_rfreg(hw, rfpath, regaddr, bitmask); +} + +static inline void rtl_set_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = hw->priv; + + rtlpriv->cfg->ops->set_rfreg(hw, rfpath, regaddr, bitmask, data); +} + +static inline bool is_hal_stop(struct rtl_hal *rtlhal) +{ + return (rtlhal->state == _HAL_STATE_STOP); +} + +static inline void set_hal_start(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_START; +} + +static inline void set_hal_stop(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_STOP; +} + +static inline u8 get_rf_type(struct rtl_phy *rtlphy) +{ + return rtlphy->rf_type; +} + +static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb) +{ + return (struct ieee80211_hdr *)(skb->data); +} + +static inline __le16 rtl_get_fc(struct sk_buff *skb) +{ + return rtl_get_hdr(skb)->frame_control; +} + +static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr) +{ + return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; +} + +static inline u16 rtl_get_tid(struct sk_buff *skb) +{ + return rtl_get_tid_h(rtl_get_hdr(skb)); +} + +static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *bssid) +{ + return ieee80211_find_sta(vif, bssid); +} + +static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw, + u8 *mac_addr) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + return ieee80211_find_sta(mac->vif, mac_addr); +} + +#endif diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 482a29dd06f84493c3d526594b5ec26e21053de0..7cdce87f3051e1052f69c61a7a2db73c63714766 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -3064,7 +3064,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit mspro_rw_multi_sector\n"); + dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", + __func__); rtsx_trace(chip); return STATUS_FAIL; } @@ -3101,7 +3102,7 @@ static int mspro_read_format_progress(struct rtsx_chip *chip, u8 cnt, tmp; u8 data[8]; - dev_dbg(rtsx_dev(chip), "mspro_read_format_progress, short_data_len = %d\n", + dev_dbg(rtsx_dev(chip), "%s, short_data_len = %d\n", __func__, short_data_len); retval = ms_switch_clock(chip); diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index b8177f50fabcbb1d3b084550119e9572e02943b3..89e2cfe7d1cc0ffdef1334ca73a59729ca69f70b 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -205,16 +205,6 @@ static int device_reset(struct scsi_cmnd *srb) return SUCCESS; } -/* Simulate a SCSI bus reset by resetting the device's USB port. */ -static int bus_reset(struct scsi_cmnd *srb) -{ - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - - dev_info(&dev->pci->dev, "%s called\n", __func__); - - return SUCCESS; -} - /* * this defines our host template, with which we'll allocate hosts */ @@ -231,7 +221,6 @@ static struct scsi_host_template rtsx_host_template = { /* error and abort handlers */ .eh_abort_handler = command_abort, .eh_device_reset_handler = device_reset, - .eh_bus_reset_handler = bus_reset, /* queue commands only, only one command per LUN */ .can_queue = 1, @@ -999,7 +988,7 @@ static int rtsx_probe(struct pci_dev *pci, /* We come here if there are any problems */ errout: - dev_err(&pci->dev, "rtsx_probe() failed\n"); + dev_err(&pci->dev, "%s failed\n", __func__); release_everything(dev); return err; @@ -1009,7 +998,7 @@ static void rtsx_remove(struct pci_dev *pci) { struct rtsx_dev *dev = pci_get_drvdata(pci); - dev_info(&pci->dev, "rtsx_remove() called\n"); + dev_info(&pci->dev, "%s called\n", __func__); quiesce_and_remove_host(dev); release_everything(dev); diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 7f4107bffe31419b7769fd7a1cdba025dc7ded5a..4ad472dd9daffb767a5e3ffd200988b333819670 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -616,8 +616,8 @@ int rtsx_reset_chip(struct rtsx_chip *chip) else retval = rtsx_pre_handle_sdio_new(chip); - dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (rtsx_reset_chip)\n", - (unsigned int)(chip->need_reset)); + dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (%s)\n", + (unsigned int)(chip->need_reset), __func__); #else /* HW_AUTO_SWITCH_SD_BUS */ retval = rtsx_pre_handle_sdio_old(chip); #endif /* HW_AUTO_SWITCH_SD_BUS */ diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 36b5a11f21d2af4323f7e9484869e43f9980ac9b..a401b13f5f5e4923a6b2580eee50fff25b1d2b9d 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -414,7 +414,7 @@ void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, sense->ascq = ascq; if (sns_key_info0 != 0) { sense->sns_key_info[0] = SKSV | sns_key_info0; - sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8; + sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 4; sense->sns_key_info[2] = sns_key_info1 & 0x0f; } } diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index c2eb072cbe1df67d23644a9e976866369de486c1..4033a2cf7ac9b3b7028f84f7ea54f753a75536a4 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -910,8 +910,8 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) int retval; bool ddr_rx = false; - dev_dbg(rtsx_dev(chip), "sd_change_phase (sample_point = %d, tune_dir = %d)\n", - sample_point, tune_dir); + dev_dbg(rtsx_dev(chip), "%s (sample_point = %d, tune_dir = %d)\n", + __func__, sample_point, tune_dir); if (tune_dir == TUNE_RX) { SD_VP_CTL = SD_VPRX_CTL; @@ -1225,8 +1225,8 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, u8 func_group, int retval; u8 cmd[5], buf[64]; - dev_dbg(rtsx_dev(chip), "sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n", - mode, func_group, func_to_switch); + dev_dbg(rtsx_dev(chip), "%s (mode = %d, func_group = %d, func_to_switch = %d)\n", + __func__, mode, func_group, func_to_switch); cmd[0] = 0x40 | SWITCH; cmd[1] = mode; @@ -1654,7 +1654,7 @@ static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) return STATUS_SUCCESS; } -static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +static int mmc_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) { struct sd_info *sd_card = &chip->sd_card; int retval; @@ -1933,7 +1933,7 @@ static int sd_tuning_rx(struct rtsx_chip *chip) } else { if (CHK_MMC_DDR52(sd_card)) { - tuning_cmd = mmc_ddr_tunning_rx_cmd; + tuning_cmd = mmc_ddr_tuning_rx_cmd; } else { rtsx_trace(chip); return STATUS_FAIL; @@ -3575,8 +3575,8 @@ static int reset_mmc_only(struct rtsx_chip *chip) return STATUS_FAIL; } - dev_dbg(rtsx_dev(chip), "In reset_mmc_only, sd_card->sd_type = 0x%x\n", - sd_card->sd_type); + dev_dbg(rtsx_dev(chip), "In %s, sd_card->sd_type = 0x%x\n", + __func__, sd_card->sd_type); return STATUS_SUCCESS; } @@ -3699,11 +3699,11 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, int retval; if (srb->sc_data_direction == DMA_FROM_DEVICE) { - dev_dbg(rtsx_dev(chip), "sd_rw: Read %d %s from 0x%x\n", + dev_dbg(rtsx_dev(chip), "%s: Read %d %s from 0x%x\n", __func__, sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", start_sector); } else { - dev_dbg(rtsx_dev(chip), "sd_rw: Write %d %s to 0x%x\n", + dev_dbg(rtsx_dev(chip), "%s: Write %d %s to 0x%x\n", __func__, sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", start_sector); } @@ -3921,7 +3921,8 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, rtsx_clear_sd_error(chip); if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n"); + dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", + __func__); rtsx_trace(chip); return STATUS_FAIL; } @@ -3964,7 +3965,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n"); + dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", __func__); rtsx_trace(chip); return STATUS_FAIL; } diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c index 8b8cd955dfeb14894aa3321b7312fbdee212ac11..b5646b62ec9ee16bd85d2d1508fbe7ded221e9fb 100644 --- a/drivers/staging/rts5208/spi.c +++ b/drivers/staging/rts5208/spi.c @@ -520,7 +520,7 @@ int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) { struct spi_info *spi = &chip->spi; - dev_dbg(rtsx_dev(chip), "spi_get_status: err_code = 0x%x\n", + dev_dbg(rtsx_dev(chip), "%s: err_code = 0x%x\n", __func__, spi->err_code); rtsx_stor_set_xfer_buf(&spi->err_code, min_t(int, scsi_bufflen(srb), 1), srb); @@ -543,8 +543,10 @@ int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; spi->write_en = srb->cmnd[6]; - dev_dbg(rtsx_dev(chip), "spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n", - spi->spi_clock, spi->clk_div, spi->write_en); + dev_dbg(rtsx_dev(chip), "%s: ", __func__); + dev_dbg(rtsx_dev(chip), "spi_clock = %d, ", spi->spi_clock); + dev_dbg(rtsx_dev(chip), "clk_div = %d, ", spi->clk_div); + dev_dbg(rtsx_dev(chip), "write_en = %d\n", spi->write_en); return STATUS_SUCCESS; } diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c index 74d36f9a4c1d5cb1cdc708bc43b5630b102fe098..11ea0c658e28f7c24a9f6298f0f3db112594657c 100644 --- a/drivers/staging/rts5208/xd.c +++ b/drivers/staging/rts5208/xd.c @@ -885,7 +885,7 @@ static int xd_init_l2p_tbl(struct rtsx_chip *chip) struct xd_info *xd_card = &chip->xd_card; int size, i; - dev_dbg(rtsx_dev(chip), "xd_init_l2p_tbl: zone_cnt = %d\n", + dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__, xd_card->zone_cnt); if (xd_card->zone_cnt < 1) { @@ -1026,7 +1026,8 @@ static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) #ifdef XD_DELAY_WRITE retval = xd_delay_write(chip); if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "In xd_get_l2p_tbl, delay write fail!\n"); + dev_dbg(rtsx_dev(chip), "In %s, delay write fail!\n", + __func__); return BLK_NOT_FOUND; } #endif @@ -1434,7 +1435,7 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) u16 cur_lst_page_logoff, ent_lst_page_logoff; u8 redunt[11]; - dev_dbg(rtsx_dev(chip), "xd_build_l2p_tbl: %d\n", zone_no); + dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, zone_no); if (!xd_card->zone) { retval = xd_init_l2p_tbl(chip); @@ -1774,8 +1775,10 @@ static int xd_finish_write(struct rtsx_chip *chip, int retval, zone_no; u16 log_off; - dev_dbg(rtsx_dev(chip), "xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", - old_blk, new_blk, log_blk); + dev_dbg(rtsx_dev(chip), "%s ", __func__); + dev_dbg(rtsx_dev(chip), "old_blk = 0x%x, ", old_blk); + dev_dbg(rtsx_dev(chip), "new_blk = 0x%x, ", new_blk); + dev_dbg(rtsx_dev(chip), "log_blk = 0x%x\n", log_blk); if (page_off > xd_card->page_off) { rtsx_trace(chip); @@ -1960,7 +1963,7 @@ int xd_delay_write(struct rtsx_chip *chip) int retval; if (delay_write->delay_write_flag) { - dev_dbg(rtsx_dev(chip), "xd_delay_write\n"); + dev_dbg(rtsx_dev(chip), "%s\n", __func__); retval = xd_switch_clock(chip); if (retval != STATUS_SUCCESS) { rtsx_trace(chip); @@ -2002,7 +2005,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, xd_card->cleanup_counter = 0; - dev_dbg(rtsx_dev(chip), "xd_rw: scsi_sg_count = %d\n", + dev_dbg(rtsx_dev(chip), "%s: scsi_sg_count = %d\n", __func__, scsi_sg_count(srb)); ptr = (u8 *)scsi_sglist(srb); diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 256657077a46f26dff350eefc2830a98a514494b..3bc25e149034cbbe7fccd61bb30596d04b5bc5f9 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -21,329 +21,6 @@ #include "skein_base.h" #include "skein_block.h" -#ifndef SKEIN_USE_ASM -#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */ -#endif - -#ifndef SKEIN_LOOP -#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ -#endif - -#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */ -#define KW_TWK_BASE (0) -#define KW_KEY_BASE (3) -#define ks (kw + KW_KEY_BASE) -#define ts (kw + KW_TWK_BASE) - -#ifdef SKEIN_DEBUG -#define debug_save_tweak(ctx) \ -{ \ - ctx->h.tweak[0] = ts[0]; \ - ctx->h.tweak[1] = ts[1]; \ -} -#else -#define debug_save_tweak(ctx) -#endif - -#if !(SKEIN_USE_ASM & 256) -#undef RCNT -#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) -#else -#define SKEIN_UNROLL_256 (0) -#endif - -#if SKEIN_UNROLL_256 -#if (RCNT % SKEIN_UNROLL_256) -#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ -#endif -#endif -#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ - do { \ - X##p0 += X##p1; \ - X##p1 = rol64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rol64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - } while (0) - -#if SKEIN_UNROLL_256 == 0 -#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ - ROUND256(p0, p1, p2, p3, ROT, r_num) - -#define I256(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 5]; \ - X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ - X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ - X3 += ks[((R) + 4) % 5] + (R) + 1; \ - } while (0) -#else -/* looping version */ -#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num) - -#define I256(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1] + ts[r + (R) + 0];\ - X2 += ks[r + (R) + 2] + ts[r + (R) + 1];\ - X3 += ks[r + (R) + 3] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 4] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - } while (0) -#endif -#define R256_8_ROUNDS(R) \ - do { \ - R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ - R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ - R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ - R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ - I256(2 * (R)); \ - R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ - R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ - R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ - R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ - I256(2 * (R) + 1); \ - } while (0) - -#define R256_UNROLL_R(NN) \ - ((SKEIN_UNROLL_256 == 0 && \ - SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_256 > (NN))) - -#if (SKEIN_UNROLL_256 > 14) -#error "need more unrolling in skein_256_process_block" -#endif -#endif - -#if !(SKEIN_USE_ASM & 512) -#undef RCNT -#define RCNT (SKEIN_512_ROUNDS_TOTAL / 8) - -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_512 (((SKEIN_LOOP) / 10) % 10) -#else -#define SKEIN_UNROLL_512 (0) -#endif - -#if SKEIN_UNROLL_512 -#if (RCNT % SKEIN_UNROLL_512) -#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ -#endif -#endif -#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - do { \ - X##p0 += X##p1; \ - X##p1 = rol64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rol64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - X##p4 += X##p5; \ - X##p5 = rol64(X##p5, ROT##_2); \ - X##p5 ^= X##p4; \ - X##p6 += X##p7; \ - X##p7 = rol64(X##p7, ROT##_3); \ - X##p7 ^= X##p6; \ - } while (0) - -#if SKEIN_UNROLL_512 == 0 -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) - -#define I512(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 9]; \ - X1 += ks[((R) + 2) % 9]; \ - X2 += ks[((R) + 3) % 9]; \ - X3 += ks[((R) + 4) % 9]; \ - X4 += ks[((R) + 5) % 9]; \ - X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ - X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ - X7 += ks[((R) + 8) % 9] + (R) + 1; \ - } while (0) - -#else /* looping version */ -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - -#define I512(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1]; \ - X2 += ks[r + (R) + 2]; \ - X3 += ks[r + (R) + 3]; \ - X4 += ks[r + (R) + 4]; \ - X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ - X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ - X7 += ks[r + (R) + 7] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 8] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - } while (0) -#endif /* end of looped code definitions */ -#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ - do { \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ - I512(2 * (R)); \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ - I512(2 * (R) + 1); /* and key injection */ \ - } while (0) -#define R512_UNROLL_R(NN) \ - ((SKEIN_UNROLL_512 == 0 && \ - SKEIN_512_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_512 > (NN))) - -#if (SKEIN_UNROLL_512 > 14) -#error "need more unrolling in skein_512_process_block" -#endif -#endif - -#if !(SKEIN_USE_ASM & 1024) -#undef RCNT -#define RCNT (SKEIN_1024_ROUNDS_TOTAL / 8) -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_1024 ((SKEIN_LOOP) % 10) -#else -#define SKEIN_UNROLL_1024 (0) -#endif - -#if (SKEIN_UNROLL_1024 != 0) -#if (RCNT % SKEIN_UNROLL_1024) -#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ -#endif -#endif -#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, r_num) \ - do { \ - X##p0 += X##p1; \ - X##p1 = rol64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rol64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - X##p4 += X##p5; \ - X##p5 = rol64(X##p5, ROT##_2); \ - X##p5 ^= X##p4; \ - X##p6 += X##p7; \ - X##p7 = rol64(X##p7, ROT##_3); \ - X##p7 ^= X##p6; \ - X##p8 += X##p9; \ - X##p9 = rol64(X##p9, ROT##_4); \ - X##p9 ^= X##p8; \ - X##pA += X##pB; \ - X##pB = rol64(X##pB, ROT##_5); \ - X##pB ^= X##pA; \ - X##pC += X##pD; \ - X##pD = rol64(X##pD, ROT##_6); \ - X##pD ^= X##pC; \ - X##pE += X##pF; \ - X##pF = rol64(X##pF, ROT##_7); \ - X##pF ^= X##pE; \ - } while (0) - -#if SKEIN_UNROLL_1024 == 0 -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn) \ - -#define I1024(R) \ - do { \ - /* inject the key schedule value */ \ - X00 += ks[((R) + 1) % 17]; \ - X01 += ks[((R) + 2) % 17]; \ - X02 += ks[((R) + 3) % 17]; \ - X03 += ks[((R) + 4) % 17]; \ - X04 += ks[((R) + 5) % 17]; \ - X05 += ks[((R) + 6) % 17]; \ - X06 += ks[((R) + 7) % 17]; \ - X07 += ks[((R) + 8) % 17]; \ - X08 += ks[((R) + 9) % 17]; \ - X09 += ks[((R) + 10) % 17]; \ - X10 += ks[((R) + 11) % 17]; \ - X11 += ks[((R) + 12) % 17]; \ - X12 += ks[((R) + 13) % 17]; \ - X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ - X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ - X15 += ks[((R) + 16) % 17] + (R) + 1; \ - } while (0) -#else /* looping version */ -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn) \ - -#define I1024(R) \ - do { \ - /* inject the key schedule value */ \ - X00 += ks[r + (R) + 0]; \ - X01 += ks[r + (R) + 1]; \ - X02 += ks[r + (R) + 2]; \ - X03 += ks[r + (R) + 3]; \ - X04 += ks[r + (R) + 4]; \ - X05 += ks[r + (R) + 5]; \ - X06 += ks[r + (R) + 6]; \ - X07 += ks[r + (R) + 7]; \ - X08 += ks[r + (R) + 8]; \ - X09 += ks[r + (R) + 9]; \ - X10 += ks[r + (R) + 10]; \ - X11 += ks[r + (R) + 11]; \ - X12 += ks[r + (R) + 12]; \ - X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ - X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ - X15 += ks[r + (R) + 15] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 16] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - } while (0) - -#endif -#define R1024_8_ROUNDS(R) \ - do { \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ - 13, 14, 15, R1024_0, 8 * (R) + 1); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ - 05, 08, 01, R1024_1, 8 * (R) + 2); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ - 11, 10, 09, R1024_2, 8 * (R) + 3); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ - 03, 12, 07, R1024_3, 8 * (R) + 4); \ - I1024(2 * (R)); \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ - 13, 14, 15, R1024_4, 8 * (R) + 5); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ - 05, 08, 01, R1024_5, 8 * (R) + 6); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ - 11, 10, 09, R1024_6, 8 * (R) + 7); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ - 03, 12, 07, R1024_7, 8 * (R) + 8); \ - I1024(2 * (R) + 1); \ - } while (0) - -#define R1024_UNROLL_R(NN) \ - ((SKEIN_UNROLL_1024 == 0 && \ - SKEIN_1024_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_1024 > (NN))) - -#if (SKEIN_UNROLL_1024 > 14) -#error "need more unrolling in Skein_1024_Process_Block" -#endif -#endif - /***************************** SKEIN_256 ******************************/ #if !(SKEIN_USE_ASM & 256) void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h index ec1baea25c9e0942388c0cb6488a0b47e5f14f8b..b3bb3d24273bb443ddc158d2abbf14f87881e528 100644 --- a/drivers/staging/skein/skein_block.h +++ b/drivers/staging/skein/skein_block.h @@ -14,6 +14,329 @@ #include "skein_base.h" /* get the Skein API definitions */ +#ifndef SKEIN_USE_ASM +#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */ +#endif + +#ifndef SKEIN_LOOP +#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ +#endif + +#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */ +#define KW_TWK_BASE (0) +#define KW_KEY_BASE (3) +#define ks (kw + KW_KEY_BASE) +#define ts (kw + KW_TWK_BASE) + +#ifdef SKEIN_DEBUG +#define debug_save_tweak(ctx) \ +{ \ + ctx->h.tweak[0] = ts[0]; \ + ctx->h.tweak[1] = ts[1]; \ +} +#else +#define debug_save_tweak(ctx) +#endif + +#if !(SKEIN_USE_ASM & 256) +#undef RCNT +#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) +#else +#define SKEIN_UNROLL_256 (0) +#endif + +#if SKEIN_UNROLL_256 +#if (RCNT % SKEIN_UNROLL_256) +#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ +#endif +#endif +#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ + do { \ + X##p0 += X##p1; \ + X##p1 = rol64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rol64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + } while (0) + +#if SKEIN_UNROLL_256 == 0 +#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ + ROUND256(p0, p1, p2, p3, ROT, r_num) + +#define I256(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 5]; \ + X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ + X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ + X3 += ks[((R) + 4) % 5] + (R) + 1; \ + } while (0) +#else +/* looping version */ +#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num) + +#define I256(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1] + ts[r + (R) + 0];\ + X2 += ks[r + (R) + 2] + ts[r + (R) + 1];\ + X3 += ks[r + (R) + 3] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 4] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + } while (0) +#endif +#define R256_8_ROUNDS(R) \ + do { \ + R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ + R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ + R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ + R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ + I256(2 * (R)); \ + R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ + R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ + R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ + R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ + I256(2 * (R) + 1); \ + } while (0) + +#define R256_UNROLL_R(NN) \ + ((SKEIN_UNROLL_256 == 0 && \ + SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_256 > (NN))) + +#if (SKEIN_UNROLL_256 > 14) +#error "need more unrolling in skein_256_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 512) +#undef RCNT +#define RCNT (SKEIN_512_ROUNDS_TOTAL / 8) + +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_512 (((SKEIN_LOOP) / 10) % 10) +#else +#define SKEIN_UNROLL_512 (0) +#endif + +#if SKEIN_UNROLL_512 +#if (RCNT % SKEIN_UNROLL_512) +#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ +#endif +#endif +#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + do { \ + X##p0 += X##p1; \ + X##p1 = rol64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rol64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rol64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rol64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + } while (0) + +#if SKEIN_UNROLL_512 == 0 +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) + +#define I512(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 9]; \ + X1 += ks[((R) + 2) % 9]; \ + X2 += ks[((R) + 3) % 9]; \ + X3 += ks[((R) + 4) % 9]; \ + X4 += ks[((R) + 5) % 9]; \ + X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ + X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ + X7 += ks[((R) + 8) % 9] + (R) + 1; \ + } while (0) + +#else /* looping version */ +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + +#define I512(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1]; \ + X2 += ks[r + (R) + 2]; \ + X3 += ks[r + (R) + 3]; \ + X4 += ks[r + (R) + 4]; \ + X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ + X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ + X7 += ks[r + (R) + 7] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 8] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + } while (0) +#endif /* end of looped code definitions */ +#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ + do { \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ + I512(2 * (R)); \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ + I512(2 * (R) + 1); /* and key injection */ \ + } while (0) +#define R512_UNROLL_R(NN) \ + ((SKEIN_UNROLL_512 == 0 && \ + SKEIN_512_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_512 > (NN))) + +#if (SKEIN_UNROLL_512 > 14) +#error "need more unrolling in skein_512_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 1024) +#undef RCNT +#define RCNT (SKEIN_1024_ROUNDS_TOTAL / 8) +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_1024 ((SKEIN_LOOP) % 10) +#else +#define SKEIN_UNROLL_1024 (0) +#endif + +#if (SKEIN_UNROLL_1024 != 0) +#if (RCNT % SKEIN_UNROLL_1024) +#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ +#endif +#endif +#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, r_num) \ + do { \ + X##p0 += X##p1; \ + X##p1 = rol64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rol64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rol64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rol64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + X##p8 += X##p9; \ + X##p9 = rol64(X##p9, ROT##_4); \ + X##p9 ^= X##p8; \ + X##pA += X##pB; \ + X##pB = rol64(X##pB, ROT##_5); \ + X##pB ^= X##pA; \ + X##pC += X##pD; \ + X##pD = rol64(X##pD, ROT##_6); \ + X##pD ^= X##pC; \ + X##pE += X##pF; \ + X##pF = rol64(X##pF, ROT##_7); \ + X##pF ^= X##pE; \ + } while (0) + +#if SKEIN_UNROLL_1024 == 0 +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn) \ + +#define I1024(R) \ + do { \ + /* inject the key schedule value */ \ + X00 += ks[((R) + 1) % 17]; \ + X01 += ks[((R) + 2) % 17]; \ + X02 += ks[((R) + 3) % 17]; \ + X03 += ks[((R) + 4) % 17]; \ + X04 += ks[((R) + 5) % 17]; \ + X05 += ks[((R) + 6) % 17]; \ + X06 += ks[((R) + 7) % 17]; \ + X07 += ks[((R) + 8) % 17]; \ + X08 += ks[((R) + 9) % 17]; \ + X09 += ks[((R) + 10) % 17]; \ + X10 += ks[((R) + 11) % 17]; \ + X11 += ks[((R) + 12) % 17]; \ + X12 += ks[((R) + 13) % 17]; \ + X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ + X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ + X15 += ks[((R) + 16) % 17] + (R) + 1; \ + } while (0) +#else /* looping version */ +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn) \ + +#define I1024(R) \ + do { \ + /* inject the key schedule value */ \ + X00 += ks[r + (R) + 0]; \ + X01 += ks[r + (R) + 1]; \ + X02 += ks[r + (R) + 2]; \ + X03 += ks[r + (R) + 3]; \ + X04 += ks[r + (R) + 4]; \ + X05 += ks[r + (R) + 5]; \ + X06 += ks[r + (R) + 6]; \ + X07 += ks[r + (R) + 7]; \ + X08 += ks[r + (R) + 8]; \ + X09 += ks[r + (R) + 9]; \ + X10 += ks[r + (R) + 10]; \ + X11 += ks[r + (R) + 11]; \ + X12 += ks[r + (R) + 12]; \ + X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ + X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ + X15 += ks[r + (R) + 15] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 16] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + } while (0) + +#endif +#define R1024_8_ROUNDS(R) \ + do { \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ + 13, 14, 15, R1024_0, 8 * (R) + 1); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ + 05, 08, 01, R1024_1, 8 * (R) + 2); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ + 11, 10, 09, R1024_2, 8 * (R) + 3); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ + 03, 12, 07, R1024_3, 8 * (R) + 4); \ + I1024(2 * (R)); \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ + 13, 14, 15, R1024_4, 8 * (R) + 5); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ + 05, 08, 01, R1024_5, 8 * (R) + 6); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ + 11, 10, 09, R1024_6, 8 * (R) + 7); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ + 03, 12, 07, R1024_7, 8 * (R) + 8); \ + I1024(2 * (R) + 1); \ + } while (0) + +#define R1024_UNROLL_R(NN) \ + ((SKEIN_UNROLL_1024 == 0 && \ + SKEIN_1024_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_1024 > (NN))) + +#if (SKEIN_UNROLL_1024 > 14) +#error "need more unrolling in Skein_1024_Process_Block" +#endif +#endif + void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, size_t blk_cnt, size_t byte_cnt_add); void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 67956e24779ce6fea015da416422cdf5c834bf18..56f7be6af1f695a873c9acfe6619d3ec8dafd496 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1376,6 +1376,8 @@ static void reset_highlight_buffers(struct vc_data *); static int read_all_key; +static int in_keyboard_notifier; + static void start_read_all_timer(struct vc_data *vc, int command); enum { @@ -1408,7 +1410,10 @@ static void read_all_doc(struct vc_data *vc) cursor_track = read_all_mode; spk_reset_index_count(0); if (get_sentence_buf(vc, 0) == -1) { - kbd_fakekey2(vc, RA_DOWN_ARROW); + del_timer(&cursor_timer); + if (!in_keyboard_notifier) + speakup_fake_down_arrow(); + start_read_all_timer(vc, RA_DOWN_ARROW); } else { say_sentence_num(0, 0); synth_insert_next_index(0); @@ -2212,8 +2217,10 @@ static int keyboard_notifier_call(struct notifier_block *nb, int ret = NOTIFY_OK; static int keycode; /* to hold the current keycode */ + in_keyboard_notifier = 1; + if (vc->vc_mode == KD_GRAPHICS) - return ret; + goto out; /* * First, determine whether we are handling a fake keypress on @@ -2225,7 +2232,7 @@ static int keyboard_notifier_call(struct notifier_block *nb, */ if (speakup_fake_key_pressed()) - return ret; + goto out; switch (code) { case KBD_KEYCODE: @@ -2266,6 +2273,8 @@ static int keyboard_notifier_call(struct notifier_block *nb, break; } } +out: + in_keyboard_notifier = 0; return ret; } diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index fe340b07c482fac63410d57ed1b7c0d262e069c1..4d7d8f2f66ea1f2eec4cbef6878ea1ba6ab1ca4a 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -7,11 +7,6 @@ #include "spk_types.h" #include "spk_priv.h" -#define DEV_PREFIX_LP "lp" - -static const char * const lp_supported[] = { "acntsa", "bns", "dummy", - "txprt" }; - struct spk_ldisc_data { char buf; struct semaphore sem; @@ -20,6 +15,11 @@ struct spk_ldisc_data { static struct spk_synth *spk_ttyio_synth; static struct tty_struct *speakup_tty; +/* mutex to protect against speakup_tty disappearing from underneath us while + * we are using it. this can happen when the device physically unplugged, + * while in use. it also serialises access to speakup_tty. + */ +static DEFINE_MUTEX(speakup_tty_mutex); static int ser_to_dev(int ser, dev_t *dev_no) { @@ -36,24 +36,8 @@ static int get_dev_to_use(struct spk_synth *synth, dev_t *dev_no) { /* use ser only when dev is not specified */ if (strcmp(synth->dev_name, SYNTH_DEFAULT_DEV) || - synth->ser == SYNTH_DEFAULT_SER) { - /* for /dev/lp* check if synth is supported */ - if (strncmp(synth->dev_name, DEV_PREFIX_LP, - strlen(DEV_PREFIX_LP)) == 0) - if (match_string(lp_supported, ARRAY_SIZE(lp_supported), - synth->name) < 0) { - int i; - - pr_err("speakup: lp* is only supported on:"); - for (i = 0; i < ARRAY_SIZE(lp_supported); i++) - pr_cont(" %s", lp_supported[i]); - pr_cont("\n"); - - return -ENOTSUPP; - } - + synth->ser == SYNTH_DEFAULT_SER) return tty_dev_name_to_number(synth->dev_name, dev_no); - } return ser_to_dev(synth->ser, dev_no); } @@ -81,8 +65,10 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) static void spk_ttyio_ldisc_close(struct tty_struct *tty) { + mutex_lock(&speakup_tty_mutex); kfree(speakup_tty->disc_data); speakup_tty = NULL; + mutex_unlock(&speakup_tty_mutex); } static int spk_ttyio_receive_buf2(struct tty_struct *tty, @@ -158,7 +144,7 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) if (ret) return ret; - tty = tty_open_by_driver(dev, NULL, NULL); + tty = tty_kopen(dev); if (IS_ERR(tty)) return PTR_ERR(tty); @@ -210,9 +196,11 @@ void spk_ttyio_unregister_ldisc(void) static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) { + mutex_lock(&speakup_tty_mutex); if (in_synth->alive && speakup_tty && speakup_tty->ops->write) { int ret = speakup_tty->ops->write(speakup_tty, &ch, 1); + mutex_unlock(&speakup_tty_mutex); if (ret == 0) /* No room */ return 0; @@ -228,17 +216,50 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) } return 1; } + + mutex_unlock(&speakup_tty_mutex); + return 0; +} + +static int check_tty(struct tty_struct *tty) +{ + if (!tty) { + pr_warn("%s: I/O error, deactivating speakup\n", + spk_ttyio_synth->long_name); + /* No synth any more, so nobody will restart TTYs, and we thus + * need to do it ourselves. Now that there is no synth we can + * let application flood anyway + */ + spk_ttyio_synth->alive = 0; + speakup_start_ttys(); + return 1; + } + return 0; } static void spk_ttyio_send_xchar(char ch) { + mutex_lock(&speakup_tty_mutex); + if (check_tty(speakup_tty)) { + mutex_unlock(&speakup_tty_mutex); + return; + } + speakup_tty->ops->send_xchar(speakup_tty, ch); + mutex_unlock(&speakup_tty_mutex); } static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear) { + mutex_lock(&speakup_tty_mutex); + if (check_tty(speakup_tty)) { + mutex_unlock(&speakup_tty_mutex); + return; + } + speakup_tty->ops->tiocmset(speakup_tty, set, clear); + mutex_unlock(&speakup_tty_mutex); } static unsigned char ttyio_in(int timeout) @@ -278,8 +299,16 @@ static unsigned char spk_ttyio_in_nowait(void) static void spk_ttyio_flush_buffer(void) { + mutex_lock(&speakup_tty_mutex); + if (check_tty(speakup_tty)) { + mutex_unlock(&speakup_tty_mutex); + return; + } + if (speakup_tty->ops->flush_buffer) speakup_tty->ops->flush_buffer(speakup_tty); + + mutex_unlock(&speakup_tty_mutex); } int spk_ttyio_synth_probe(struct spk_synth *synth) @@ -308,7 +337,7 @@ void spk_ttyio_release(void) tty_ldisc_flush(speakup_tty); tty_unlock(speakup_tty); - tty_release_struct(speakup_tty, speakup_tty->index); + tty_kclose(speakup_tty); } EXPORT_SYMBOL_GPL(spk_ttyio_release); diff --git a/drivers/staging/typec/fusb302/Kconfig b/drivers/staging/typec/fusb302/Kconfig index fce099ff39feace7d8e1bc5df63e8984a01b18e0..48a4f2fcee034908fd31684cc4999b9d6b1cda55 100644 --- a/drivers/staging/typec/fusb302/Kconfig +++ b/drivers/staging/typec/fusb302/Kconfig @@ -1,6 +1,6 @@ config TYPEC_FUSB302 tristate "Fairchild FUSB302 Type-C chip driver" - depends on I2C + depends on I2C && POWER_SUPPLY help The Fairchild FUSB302 Type-C chip driver that works with Type-C Port Controller Manager to provide USB PD and USB diff --git a/drivers/staging/typec/fusb302/TODO b/drivers/staging/typec/fusb302/TODO index 4933a1d92c327b7d69366d8073605ed1f35de564..19b466eb585d7445b28aa16b10fae51e6d4f70ca 100644 --- a/drivers/staging/typec/fusb302/TODO +++ b/drivers/staging/typec/fusb302/TODO @@ -4,3 +4,7 @@ fusb302: - Find a non-hacky way to coordinate between PM and I2C access - Documentation? The FUSB302 datasheet provides information on the chip to help understand the code. But it may still be helpful to have a documentation. +- We may want to replace the "fcs,max-snk-microvolt", "fcs,max-snk-microamp", + "fcs,max-snk-microwatt" and "fcs,operating-snk-microwatt" device(tree) + properties with properties which are part of a generic type-c controller + devicetree binding. diff --git a/drivers/staging/typec/fusb302/fusb302.c b/drivers/staging/typec/fusb302/fusb302.c index 03a3809d18f0a6607557ea29926472c7f4d34442..fc6a3cf74eb3a92e0fac4119d7edc22218e5e6ab 100644 --- a/drivers/staging/typec/fusb302/fusb302.c +++ b/drivers/staging/typec/fusb302/fusb302.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -90,11 +92,13 @@ struct fusb302_chip { struct i2c_client *i2c_client; struct tcpm_port *tcpm_port; struct tcpc_dev tcpc_dev; + struct tcpc_config tcpc_config; struct regulator *vbus; int gpio_int_n; int gpio_int_n_irq; + struct extcon_dev *extcon; struct workqueue_struct *wq; struct delayed_work bc_lvl_handler; @@ -105,6 +109,11 @@ struct fusb302_chip { /* lock for sharing chip states */ struct mutex lock; + /* psy + psy status */ + struct power_supply *psy; + u32 current_limit; + u32 supply_voltage; + /* chip status */ enum toggling_mode toggling_mode; enum src_current_status src_current_status; @@ -515,6 +524,38 @@ static int tcpm_get_vbus(struct tcpc_dev *dev) return ret; } +static int tcpm_get_current_limit(struct tcpc_dev *dev) +{ + struct fusb302_chip *chip = container_of(dev, struct fusb302_chip, + tcpc_dev); + int current_limit = 0; + unsigned long timeout; + + if (!chip->extcon) + return 0; + + /* + * USB2 Charger detection may still be in progress when we get here, + * this can take upto 600ms, wait 800ms max. + */ + timeout = jiffies + msecs_to_jiffies(800); + do { + if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_SDP) == 1) + current_limit = 500; + + if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_CDP) == 1 || + extcon_get_state(chip->extcon, EXTCON_CHG_USB_ACA) == 1) + current_limit = 1500; + + if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_DCP) == 1) + current_limit = 2000; + + msleep(50); + } while (current_limit == 0 && time_before(jiffies, timeout)); + + return current_limit; +} + static int fusb302_set_cc_pull(struct fusb302_chip *chip, bool pull_up, bool pull_down) { @@ -841,11 +882,13 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge) chip->vbus_on = on; fusb302_log(chip, "vbus := %s", on ? "On" : "Off"); } - if (chip->charge_on == charge) + if (chip->charge_on == charge) { fusb302_log(chip, "charge is already %s", charge ? "On" : "Off"); - else + } else { chip->charge_on = charge; + power_supply_changed(chip->psy); + } done: mutex_unlock(&chip->lock); @@ -861,6 +904,11 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv) fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)", max_ma, mv); + chip->supply_voltage = mv; + chip->current_limit = max_ma; + + power_supply_changed(chip->psy); + return 0; } @@ -1187,9 +1235,9 @@ static const struct tcpc_config fusb302_tcpc_config = { .nr_src_pdo = ARRAY_SIZE(src_pdo), .snk_pdo = snk_pdo, .nr_snk_pdo = ARRAY_SIZE(snk_pdo), - .max_snk_mv = 9000, + .max_snk_mv = 5000, .max_snk_ma = 3000, - .max_snk_mw = 27000, + .max_snk_mw = 15000, .operating_snk_mw = 2500, .type = TYPEC_PORT_DRP, .default_role = TYPEC_SINK, @@ -1198,9 +1246,9 @@ static const struct tcpc_config fusb302_tcpc_config = { static void init_tcpc_dev(struct tcpc_dev *fusb302_tcpc_dev) { - fusb302_tcpc_dev->config = &fusb302_tcpc_config; fusb302_tcpc_dev->init = tcpm_init; fusb302_tcpc_dev->get_vbus = tcpm_get_vbus; + fusb302_tcpc_dev->get_current_limit = tcpm_get_current_limit; fusb302_tcpc_dev->set_cc = tcpm_set_cc; fusb302_tcpc_dev->get_cc = tcpm_get_cc; fusb302_tcpc_dev->set_polarity = tcpm_set_polarity; @@ -1646,6 +1694,43 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) return IRQ_HANDLED; } +static int fusb302_psy_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct fusb302_chip *chip = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = chip->charge_on; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = chip->supply_voltage * 1000; /* mV -> µV */ + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + val->intval = chip->current_limit * 1000; /* mA -> µA */ + break; + default: + return -ENODATA; + } + + return 0; +} + +static enum power_supply_property fusb302_psy_properties[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_MAX, +}; + +static const struct power_supply_desc fusb302_psy_desc = { + .name = "fusb302-typec-source", + .type = POWER_SUPPLY_TYPE_USB_TYPE_C, + .properties = fusb302_psy_properties, + .num_properties = ARRAY_SIZE(fusb302_psy_properties), + .get_property = fusb302_psy_get_property, +}; + static int init_gpio(struct fusb302_chip *chip) { struct device_node *node; @@ -1684,7 +1769,11 @@ static int fusb302_probe(struct i2c_client *client, { struct fusb302_chip *chip; struct i2c_adapter *adapter; + struct device *dev = &client->dev; + struct power_supply_config cfg = {}; + const char *name; int ret = 0; + u32 v; adapter = to_i2c_adapter(client->dev.parent); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { @@ -1699,8 +1788,43 @@ static int fusb302_probe(struct i2c_client *client, chip->i2c_client = client; i2c_set_clientdata(client, chip); chip->dev = &client->dev; + chip->tcpc_config = fusb302_tcpc_config; + chip->tcpc_dev.config = &chip->tcpc_config; mutex_init(&chip->lock); + if (!device_property_read_u32(dev, "fcs,max-sink-microvolt", &v)) + chip->tcpc_config.max_snk_mv = v / 1000; + + if (!device_property_read_u32(dev, "fcs,max-sink-microamp", &v)) + chip->tcpc_config.max_snk_ma = v / 1000; + + if (!device_property_read_u32(dev, "fcs,max-sink-microwatt", &v)) + chip->tcpc_config.max_snk_mw = v / 1000; + + if (!device_property_read_u32(dev, "fcs,operating-sink-microwatt", &v)) + chip->tcpc_config.operating_snk_mw = v / 1000; + + /* + * Devicetree platforms should get extcon via phandle (not yet + * supported). On ACPI platforms, we get the name from a device prop. + * This device prop is for kernel internal use only and is expected + * to be set by the platform code which also registers the i2c client + * for the fusb302. + */ + if (device_property_read_string(dev, "fcs,extcon-name", &name) == 0) { + chip->extcon = extcon_get_extcon_dev(name); + if (!chip->extcon) + return -EPROBE_DEFER; + } + + cfg.drv_data = chip; + chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg); + if (IS_ERR(chip->psy)) { + ret = PTR_ERR(chip->psy); + dev_err(chip->dev, "Error registering power-supply: %d\n", ret); + return ret; + } + ret = fusb302_debugfs_init(chip); if (ret < 0) return ret; @@ -1719,9 +1843,13 @@ static int fusb302_probe(struct i2c_client *client, goto destroy_workqueue; } - ret = init_gpio(chip); - if (ret < 0) - goto destroy_workqueue; + if (client->irq) { + chip->gpio_int_n_irq = client->irq; + } else { + ret = init_gpio(chip); + if (ret < 0) + goto destroy_workqueue; + } chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev); if (IS_ERR(chip->tcpm_port)) { diff --git a/drivers/staging/typec/pd.h b/drivers/staging/typec/pd.h index 510ef7279900617d5057f559b414239f99a36e03..30b32ad72acd725bac52cb28085eb85a539ae77d 100644 --- a/drivers/staging/typec/pd.h +++ b/drivers/staging/typec/pd.h @@ -278,6 +278,8 @@ static inline unsigned int rdo_max_power(u32 rdo) #define PD_T_VCONN_SOURCE_ON 100 #define PD_T_SINK_REQUEST 100 /* 100 ms minimum */ #define PD_T_ERROR_RECOVERY 100 /* minimum 25 is insufficient */ +#define PD_T_SRCSWAPSTDBY 625 /* Maximum of 650ms */ +#define PD_T_NEWSRC 250 /* Maximum of 275ms */ #define PD_T_DRP_TRY 100 /* 75 - 150 ms */ #define PD_T_DRP_TRYWAIT 600 /* 400 - 800 ms */ diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c index 20eb4ebcf8c3dba29f03fa58fa09169c281bf27c..8af62e74d54c6319678f315a48e302a761dbb71c 100644 --- a/drivers/staging/typec/tcpm.c +++ b/drivers/staging/typec/tcpm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -89,9 +90,11 @@ S(PR_SWAP_START), \ S(PR_SWAP_SRC_SNK_TRANSITION_OFF), \ S(PR_SWAP_SRC_SNK_SOURCE_OFF), \ + S(PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED), \ S(PR_SWAP_SRC_SNK_SINK_ON), \ S(PR_SWAP_SNK_SRC_SINK_OFF), \ S(PR_SWAP_SNK_SRC_SOURCE_ON), \ + S(PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP), \ \ S(VCONN_SWAP_ACCEPT), \ S(VCONN_SWAP_SEND), \ @@ -104,10 +107,14 @@ \ S(SNK_TRY), \ S(SNK_TRY_WAIT), \ + S(SNK_TRY_WAIT_DEBOUNCE), \ + S(SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS), \ S(SRC_TRYWAIT), \ + S(SRC_TRYWAIT_DEBOUNCE), \ S(SRC_TRYWAIT_UNATTACHED), \ \ S(SRC_TRY), \ + S(SRC_TRY_WAIT), \ S(SRC_TRY_DEBOUNCE), \ S(SNK_TRYWAIT), \ S(SNK_TRYWAIT_DEBOUNCE), \ @@ -115,7 +122,8 @@ S(BIST_RX), \ \ S(ERROR_RECOVERY), \ - S(ERROR_RECOVERY_WAIT_OFF) + S(PORT_RESET), \ + S(PORT_RESET_WAIT_OFF) #define GENERATE_ENUM(e) e #define GENERATE_STRING(s) #s @@ -196,6 +204,7 @@ struct tcpm_port { bool attached; bool connected; + enum typec_port_type port_type; bool vbus_present; bool vbus_never_low; bool vbus_source; @@ -230,6 +239,7 @@ struct tcpm_port { struct mutex swap_lock; /* swap command lock */ bool swap_pending; + bool non_pd_role_swap; struct completion swap_complete; int swap_status; @@ -281,6 +291,9 @@ struct tcpm_port { struct typec_altmode *partner_altmode[SVID_DISCOVERY_MAX]; struct typec_altmode *port_altmode[SVID_DISCOVERY_MAX]; + /* Deadline in jiffies to exit src_try_wait state */ + unsigned long max_wait; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -325,19 +338,26 @@ struct pd_rx_event { (tcpm_cc_is_audio((port)->cc2) && tcpm_cc_is_open((port)->cc1))) #define tcpm_try_snk(port) \ - ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK) + ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK && \ + (port)->port_type == TYPEC_PORT_DRP) #define tcpm_try_src(port) \ - ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE) + ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE && \ + (port)->port_type == TYPEC_PORT_DRP) static enum tcpm_state tcpm_default_state(struct tcpm_port *port) { - if (port->try_role == TYPEC_SINK) - return SNK_UNATTACHED; - else if (port->try_role == TYPEC_SOURCE) - return SRC_UNATTACHED; - else if (port->tcpc->config->default_role == TYPEC_SINK) + if (port->port_type == TYPEC_PORT_DRP) { + if (port->try_role == TYPEC_SINK) + return SNK_UNATTACHED; + else if (port->try_role == TYPEC_SOURCE) + return SRC_UNATTACHED; + else if (port->tcpc->config->default_role == TYPEC_SINK) + return SNK_UNATTACHED; + /* Fall through to return SRC_UNATTACHED */ + } else if (port->port_type == TYPEC_PORT_UFP) { return SNK_UNATTACHED; + } return SRC_UNATTACHED; } @@ -369,6 +389,7 @@ static bool tcpm_log_full(struct tcpm_port *port) (port->logbuffer_head + 1) % LOG_BUFFER_ENTRIES; } +__printf(2, 0) static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args) { char tmpbuffer[LOG_BUFFER_ENTRY_SIZE]; @@ -415,6 +436,7 @@ static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args) mutex_unlock(&port->logbuffer_lock); } +__printf(2, 3) static void tcpm_log(struct tcpm_port *port, const char *fmt, ...) { va_list args; @@ -430,6 +452,7 @@ static void tcpm_log(struct tcpm_port *port, const char *fmt, ...) va_end(args); } +__printf(2, 3) static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...) { va_list args; @@ -546,7 +569,9 @@ static void tcpm_debugfs_exit(struct tcpm_port *port) #else +__printf(2, 3) static void tcpm_log(const struct tcpm_port *port, const char *fmt, ...) { } +__printf(2, 3) static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...) { } static void tcpm_log_source_caps(struct tcpm_port *port) { } static int tcpm_debugfs_init(const struct tcpm_port *port) { return 0; } @@ -660,7 +685,10 @@ static u32 tcpm_get_current_limit(struct tcpm_port *port) break; case TYPEC_CC_RP_DEF: default: - limit = 0; + if (port->tcpc->get_current_limit) + limit = port->tcpc->get_current_limit(port->tcpc); + else + limit = 0; break; } @@ -1015,8 +1043,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, if (port->data_role == TYPEC_DEVICE && port->nr_snk_vdo) { for (i = 0; i < port->nr_snk_vdo; i++) - response[i + 1] - = cpu_to_le32(port->snk_vdo[i]); + response[i + 1] = port->snk_vdo[i]; rlen = port->nr_snk_vdo + 1; } break; @@ -1367,6 +1394,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, tcpm_set_current_limit(port, port->current_limit, port->supply_voltage); + port->explicit_contract = true; tcpm_set_state(port, SNK_READY, 0); } else { /* @@ -1377,7 +1405,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, SNK_TRANSITION_SINK_VBUS, 0); } break; - case PR_SWAP_SRC_SNK_SOURCE_OFF: + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: tcpm_set_state(port, PR_SWAP_SRC_SNK_SINK_ON, 0); break; case PR_SWAP_SNK_SRC_SINK_OFF: @@ -1451,7 +1479,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, tcpm_set_state(port, SOFT_RESET, 0); break; case PD_CTRL_DR_SWAP: - if (port->typec_caps.type != TYPEC_PORT_DRP) { + if (port->port_type != TYPEC_PORT_DRP) { tcpm_queue_message(port, PD_MSG_CTRL_REJECT); break; } @@ -1471,7 +1499,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, } break; case PD_CTRL_PR_SWAP: - if (port->typec_caps.type != TYPEC_PORT_DRP) { + if (port->port_type != TYPEC_PORT_DRP) { tcpm_queue_message(port, PD_MSG_CTRL_REJECT); break; } @@ -1846,7 +1874,7 @@ static bool tcpm_start_drp_toggling(struct tcpm_port *port) int ret; if (port->tcpc->start_drp_toggling && - port->typec_caps.type == TYPEC_PORT_DRP) { + port->port_type == TYPEC_PORT_DRP) { tcpm_log_force(port, "Start DRP toggling"); ret = port->tcpc->start_drp_toggling(port->tcpc, tcpm_rp_cc(port)); @@ -2099,10 +2127,16 @@ static inline enum tcpm_state ready_state(struct tcpm_port *port) static inline enum tcpm_state unattached_state(struct tcpm_port *port) { - if (port->pwr_role == TYPEC_SOURCE) + if (port->port_type == TYPEC_PORT_DRP) { + if (port->pwr_role == TYPEC_SOURCE) + return SRC_UNATTACHED; + else + return SNK_UNATTACHED; + } else if (port->port_type == TYPEC_PORT_DFP) { return SRC_UNATTACHED; - else - return SNK_UNATTACHED; + } + + return SNK_UNATTACHED; } static void tcpm_check_send_discover(struct tcpm_port *port) @@ -2119,13 +2153,29 @@ static void tcpm_swap_complete(struct tcpm_port *port, int result) if (port->swap_pending) { port->swap_status = result; port->swap_pending = false; + port->non_pd_role_swap = false; complete(&port->swap_complete); } } +static enum typec_pwr_opmode tcpm_get_pwr_opmode(enum typec_cc_status cc) +{ + switch (cc) { + case TYPEC_CC_RP_1_5: + return TYPEC_PWR_MODE_1_5A; + case TYPEC_CC_RP_3_0: + return TYPEC_PWR_MODE_3_0A; + case TYPEC_CC_RP_DEF: + default: + return TYPEC_PWR_MODE_USB; + } +} + static void run_state_machine(struct tcpm_port *port) { int ret; + enum typec_pwr_opmode opmode; + unsigned int msecs; port->enter_state = port->state; switch (port->state) { @@ -2133,14 +2183,15 @@ static void run_state_machine(struct tcpm_port *port) break; /* SRC states */ case SRC_UNATTACHED: - tcpm_swap_complete(port, -ENOTCONN); + if (!port->non_pd_role_swap) + tcpm_swap_complete(port, -ENOTCONN); tcpm_src_detach(port); if (tcpm_start_drp_toggling(port)) { tcpm_set_state(port, DRP_TOGGLING, 0); break; } tcpm_set_cc(port, tcpm_rp_cc(port)); - if (port->typec_caps.type == TYPEC_PORT_DRP) + if (port->port_type == TYPEC_PORT_DRP) tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK); break; case SRC_ATTACH_WAIT: @@ -2171,25 +2222,43 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, SNK_TRY_WAIT, PD_T_DRP_TRY); break; case SNK_TRY_WAIT: + if (tcpm_port_is_sink(port)) { + tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE, 0); + } else { + tcpm_set_state(port, SRC_TRYWAIT, 0); + port->max_wait = 0; + } + break; + case SNK_TRY_WAIT_DEBOUNCE: + tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS, + PD_T_PD_DEBOUNCE); + break; + case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS: if (port->vbus_present && tcpm_port_is_sink(port)) { tcpm_set_state(port, SNK_ATTACHED, 0); - break; - } - if (!tcpm_port_is_sink(port)) { - tcpm_set_state(port, SRC_TRYWAIT, - PD_T_PD_DEBOUNCE); - break; + } else { + tcpm_set_state(port, SRC_TRYWAIT, 0); + port->max_wait = 0; } - /* No vbus, cc state is sink or open */ - tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, PD_T_DRP_TRYWAIT); break; case SRC_TRYWAIT: tcpm_set_cc(port, tcpm_rp_cc(port)); - if (!port->vbus_present && tcpm_port_is_source(port)) - tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE); - else + if (port->max_wait == 0) { + port->max_wait = jiffies + + msecs_to_jiffies(PD_T_DRP_TRY); tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, PD_T_DRP_TRY); + } else { + if (time_is_after_jiffies(port->max_wait)) + tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, + jiffies_to_msecs(port->max_wait - + jiffies)); + else + tcpm_set_state(port, SNK_UNATTACHED, 0); + } + break; + case SRC_TRYWAIT_DEBOUNCE: + tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE); break; case SRC_TRYWAIT_UNATTACHED: tcpm_set_state(port, SNK_UNATTACHED, 0); @@ -2201,7 +2270,8 @@ static void run_state_machine(struct tcpm_port *port) ret < 0 ? 0 : PD_T_PS_SOURCE_ON); break; case SRC_STARTUP: - typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB); + opmode = tcpm_get_pwr_opmode(tcpm_rp_cc(port)); + typec_set_pwr_opmode(port->typec_port, opmode); port->pwr_opmode = TYPEC_PWR_MODE_USB; port->caps_count = 0; port->message_id = 0; @@ -2262,8 +2332,8 @@ static void run_state_machine(struct tcpm_port *port) #endif port->try_src_count = 0; + tcpm_swap_complete(port, 0); tcpm_typec_connect(port); - tcpm_check_send_discover(port); /* * 6.3.5 @@ -2273,14 +2343,11 @@ static void run_state_machine(struct tcpm_port *port) * - The system is not operating in PD mode * or * - Both partners are connected using a Type-C connector - * XXX How do we know that ? + * + * There is no actual need to send PD messages since the local + * port type-c and the spec does not clearly say whether PD is + * possible when type-c is connected to Type-A/B */ - if (port->pwr_opmode == TYPEC_PWR_MODE_PD && - !port->op_vsafe5v) { - tcpm_pd_send_control(port, PD_CTRL_PING); - tcpm_set_state_cond(port, SRC_READY, - PD_T_SOURCE_ACTIVITY); - } break; case SRC_WAIT_NEW_CAPABILITIES: /* Nothing to do... */ @@ -2288,14 +2355,15 @@ static void run_state_machine(struct tcpm_port *port) /* SNK states */ case SNK_UNATTACHED: - tcpm_swap_complete(port, -ENOTCONN); + if (!port->non_pd_role_swap) + tcpm_swap_complete(port, -ENOTCONN); tcpm_snk_detach(port); if (tcpm_start_drp_toggling(port)) { tcpm_set_state(port, DRP_TOGGLING, 0); break; } tcpm_set_cc(port, TYPEC_CC_RD); - if (port->typec_caps.type == TYPEC_PORT_DRP) + if (port->port_type == TYPEC_PORT_DRP) tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC); break; case SNK_ATTACH_WAIT: @@ -2320,39 +2388,52 @@ static void run_state_machine(struct tcpm_port *port) 0); else /* Wait for VBUS, but not forever */ - tcpm_set_state(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON); + tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON); break; case SRC_TRY: port->try_src_count++; tcpm_set_cc(port, tcpm_rp_cc(port)); - tcpm_set_state(port, SNK_TRYWAIT, PD_T_DRP_TRY); + port->max_wait = 0; + tcpm_set_state(port, SRC_TRY_WAIT, 0); + break; + case SRC_TRY_WAIT: + if (port->max_wait == 0) { + port->max_wait = jiffies + + msecs_to_jiffies(PD_T_DRP_TRY); + msecs = PD_T_DRP_TRY; + } else { + if (time_is_after_jiffies(port->max_wait)) + msecs = jiffies_to_msecs(port->max_wait - + jiffies); + else + msecs = 0; + } + tcpm_set_state(port, SNK_TRYWAIT, msecs); break; case SRC_TRY_DEBOUNCE: tcpm_set_state(port, SRC_ATTACHED, PD_T_PD_DEBOUNCE); break; case SNK_TRYWAIT: tcpm_set_cc(port, TYPEC_CC_RD); - tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, PD_T_CC_DEBOUNCE); + tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE); break; - case SNK_TRYWAIT_DEBOUNCE: - if (port->vbus_present) { + case SNK_TRYWAIT_VBUS: + /* + * TCPM stays in this state indefinitely until VBUS + * is detected as long as Rp is not detected for + * more than a time period of tPDDebounce. + */ + if (port->vbus_present && tcpm_port_is_sink(port)) { tcpm_set_state(port, SNK_ATTACHED, 0); break; } - if (tcpm_port_is_disconnected(port)) { - tcpm_set_state(port, SNK_UNATTACHED, - PD_T_PD_DEBOUNCE); - break; - } - if (tcpm_port_is_source(port)) - tcpm_set_state(port, SRC_ATTACHED, 0); - /* XXX Are we supposed to stay in this state ? */ + if (!tcpm_port_is_sink(port)) + tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0); break; - case SNK_TRYWAIT_VBUS: - tcpm_set_state(port, SNK_ATTACHED, PD_T_CC_DEBOUNCE); + case SNK_TRYWAIT_DEBOUNCE: + tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE); break; - case SNK_ATTACHED: ret = tcpm_snk_attach(port); if (ret < 0) @@ -2362,7 +2443,9 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_STARTUP: /* XXX: callback into infrastructure */ - typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB); + opmode = tcpm_get_pwr_opmode(port->polarity ? + port->cc2 : port->cc1); + typec_set_pwr_opmode(port->typec_port, opmode); port->pwr_opmode = TYPEC_PWR_MODE_USB; port->message_id = 0; port->rx_msgid = -1; @@ -2384,7 +2467,7 @@ static void run_state_machine(struct tcpm_port *port) * see USB power delivery specification, section 8.3.3.6.1.5.1). */ tcpm_set_state(port, hard_reset_state(port), - port->typec_caps.type == TYPEC_PORT_DRP ? + port->port_type == TYPEC_PORT_DRP ? PD_T_DB_DETECT : PD_T_NO_RESPONSE); break; case SNK_DISCOVERY_DEBOUNCE: @@ -2441,12 +2524,14 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_READY: port->try_snk_count = 0; - port->explicit_contract = true; - typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_PD); - port->pwr_opmode = TYPEC_PWR_MODE_PD; + if (port->explicit_contract) { + typec_set_pwr_opmode(port->typec_port, + TYPEC_PWR_MODE_PD); + port->pwr_opmode = TYPEC_PWR_MODE_PD; + } + tcpm_swap_complete(port, 0); tcpm_typec_connect(port); - tcpm_check_send_discover(port); break; @@ -2574,7 +2659,6 @@ static void run_state_machine(struct tcpm_port *port) TYPEC_HOST); port->send_discover = true; } - tcpm_swap_complete(port, 0); tcpm_set_state(port, ready_state(port), 0); break; @@ -2602,11 +2686,17 @@ static void run_state_machine(struct tcpm_port *port) case PR_SWAP_SRC_SNK_TRANSITION_OFF: tcpm_set_vbus(port, false); port->explicit_contract = false; + /* allow time for Vbus discharge, must be < tSrcSwapStdby */ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, - PD_T_PS_SOURCE_OFF); + PD_T_SRCSWAPSTDBY); break; case PR_SWAP_SRC_SNK_SOURCE_OFF: tcpm_set_cc(port, TYPEC_CC_RD); + /* allow CC debounce */ + tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED, + PD_T_CC_DEBOUNCE); + break; + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: /* * USB-PD standard, 6.2.1.4, Port Power Role: * "During the Power Role Swap Sequence, for the initial Source @@ -2622,7 +2712,6 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON); break; case PR_SWAP_SRC_SNK_SINK_ON: - tcpm_swap_complete(port, 0); tcpm_set_state(port, SNK_STARTUP, 0); break; case PR_SWAP_SNK_SRC_SINK_OFF: @@ -2633,6 +2722,15 @@ static void run_state_machine(struct tcpm_port *port) case PR_SWAP_SNK_SRC_SOURCE_ON: tcpm_set_cc(port, tcpm_rp_cc(port)); tcpm_set_vbus(port, true); + /* + * allow time VBUS ramp-up, must be < tNewSrc + * Also, this window overlaps with CC debounce as well. + * So, Wait for the max of two which is PD_T_NEWSRC + */ + tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP, + PD_T_NEWSRC); + break; + case PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP: /* * USB PD standard, 6.2.1.4: * "Subsequent Messages initiated by the Policy Engine, @@ -2642,7 +2740,6 @@ static void run_state_machine(struct tcpm_port *port) */ tcpm_set_pwr_role(port, TYPEC_SOURCE); tcpm_pd_send_control(port, PD_CTRL_PS_RDY); - tcpm_swap_complete(port, 0); tcpm_set_state(port, SRC_STARTUP, 0); break; @@ -2672,12 +2769,10 @@ static void run_state_machine(struct tcpm_port *port) case VCONN_SWAP_TURN_ON_VCONN: tcpm_set_vconn(port, true); tcpm_pd_send_control(port, PD_CTRL_PS_RDY); - tcpm_swap_complete(port, 0); tcpm_set_state(port, ready_state(port), 0); break; case VCONN_SWAP_TURN_OFF_VCONN: tcpm_set_vconn(port, false); - tcpm_swap_complete(port, 0); tcpm_set_state(port, ready_state(port), 0); break; @@ -2704,13 +2799,15 @@ static void run_state_machine(struct tcpm_port *port) break; case ERROR_RECOVERY: tcpm_swap_complete(port, -EPROTO); + tcpm_set_state(port, PORT_RESET, 0); + break; + case PORT_RESET: tcpm_reset_port(port); - tcpm_set_cc(port, TYPEC_CC_OPEN); - tcpm_set_state(port, ERROR_RECOVERY_WAIT_OFF, + tcpm_set_state(port, PORT_RESET_WAIT_OFF, PD_T_ERROR_RECOVERY); break; - case ERROR_RECOVERY_WAIT_OFF: + case PORT_RESET_WAIT_OFF: tcpm_set_state(port, tcpm_default_state(port), port->vbus_present ? PD_T_PS_SOURCE_OFF : 0); @@ -2799,10 +2896,12 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, tcpm_set_state(port, SRC_ATTACH_WAIT, 0); break; case SRC_ATTACHED: - if (tcpm_port_is_disconnected(port)) + case SRC_SEND_CAPABILITIES: + case SRC_READY: + if (tcpm_port_is_disconnected(port) || + !tcpm_port_is_source(port)) tcpm_set_state(port, SRC_UNATTACHED, 0); break; - case SNK_UNATTACHED: if (tcpm_port_is_sink(port)) tcpm_set_state(port, SNK_ATTACH_WAIT, 0); @@ -2869,52 +2968,43 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, case SRC_TRYWAIT: /* Hand over to state machine if needed */ if (!port->vbus_present && tcpm_port_is_source(port)) - new_state = SRC_ATTACHED; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) + tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0); + break; + case SRC_TRYWAIT_DEBOUNCE: + if (port->vbus_present || !tcpm_port_is_source(port)) tcpm_set_state(port, SRC_TRYWAIT, 0); break; - case SNK_TRY_WAIT: - if (port->vbus_present && tcpm_port_is_sink(port)) { - tcpm_set_state(port, SNK_ATTACHED, 0); - break; + case SNK_TRY_WAIT_DEBOUNCE: + if (!tcpm_port_is_sink(port)) { + port->max_wait = 0; + tcpm_set_state(port, SRC_TRYWAIT, 0); } - if (!tcpm_port_is_sink(port)) - new_state = SRC_TRYWAIT; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) - tcpm_set_state(port, SNK_TRY_WAIT, 0); break; - - case SRC_TRY: - tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0); + case SRC_TRY_WAIT: + if (tcpm_port_is_source(port)) + tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0); break; case SRC_TRY_DEBOUNCE: - tcpm_set_state(port, SRC_TRY, 0); + tcpm_set_state(port, SRC_TRY_WAIT, 0); break; case SNK_TRYWAIT_DEBOUNCE: - if (port->vbus_present) { - tcpm_set_state(port, SNK_ATTACHED, 0); - break; - } - if (tcpm_port_is_source(port)) { - tcpm_set_state(port, SRC_ATTACHED, 0); - break; - } - if (tcpm_port_is_disconnected(port) && - port->delayed_state != SNK_UNATTACHED) + if (tcpm_port_is_sink(port)) + tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0); + break; + case SNK_TRYWAIT_VBUS: + if (!tcpm_port_is_sink(port)) tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0); break; - + case SNK_TRYWAIT: + /* Do nothing, waiting for tCCDebounce */ + break; case PR_SWAP_SNK_SRC_SINK_OFF: case PR_SWAP_SRC_SNK_TRANSITION_OFF: case PR_SWAP_SRC_SNK_SOURCE_OFF: + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: + case PR_SWAP_SNK_SRC_SOURCE_ON: /* - * CC state change is expected here; we just turned off power. + * CC state change is expected in PR_SWAP * Ignore it. */ break; @@ -2928,12 +3018,11 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, static void _tcpm_pd_vbus_on(struct tcpm_port *port) { - enum tcpm_state new_state; - tcpm_log_force(port, "VBUS on"); port->vbus_present = true; switch (port->state) { case SNK_TRANSITION_SINK_VBUS: + port->explicit_contract = true; tcpm_set_state(port, SNK_READY, 0); break; case SNK_DISCOVERY: @@ -2959,27 +3048,28 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) /* Do nothing, waiting for timeout */ break; case SRC_TRYWAIT: - /* Hand over to state machine if needed */ - if (port->delayed_state != SRC_TRYWAIT_UNATTACHED) - tcpm_set_state(port, SRC_TRYWAIT, 0); + /* Do nothing, Waiting for Rd to be detected */ break; - case SNK_TRY_WAIT: - if (tcpm_port_is_sink(port)) { - tcpm_set_state(port, SNK_ATTACHED, 0); - break; - } - if (!tcpm_port_is_sink(port)) - new_state = SRC_TRYWAIT; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) - tcpm_set_state(port, SNK_TRY_WAIT, 0); + case SRC_TRYWAIT_DEBOUNCE: + tcpm_set_state(port, SRC_TRYWAIT, 0); + break; + case SNK_TRY_WAIT_DEBOUNCE: + /* Do nothing, waiting for PD_DEBOUNCE to do be done */ break; case SNK_TRYWAIT: - tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0); + /* Do nothing, waiting for tCCDebounce */ + break; + case SNK_TRYWAIT_VBUS: + if (tcpm_port_is_sink(port)) + tcpm_set_state(port, SNK_ATTACHED, 0); + break; + case SNK_TRYWAIT_DEBOUNCE: + /* Do nothing, waiting for Rp */ + break; + case SRC_TRY_WAIT: + case SRC_TRY_DEBOUNCE: + /* Do nothing, waiting for sink detection */ break; - default: break; } @@ -2987,8 +3077,6 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) static void _tcpm_pd_vbus_off(struct tcpm_port *port) { - enum tcpm_state new_state; - tcpm_log_force(port, "VBUS off"); port->vbus_present = false; port->vbus_never_low = false; @@ -3008,25 +3096,15 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) case SRC_TRYWAIT: /* Hand over to state machine if needed */ if (tcpm_port_is_source(port)) - new_state = SRC_ATTACHED; - else - new_state = SRC_TRYWAIT_UNATTACHED; - if (new_state != port->delayed_state) - tcpm_set_state(port, SRC_TRYWAIT, 0); + tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0); break; - case SNK_TRY_WAIT: - if (!tcpm_port_is_sink(port)) - new_state = SRC_TRYWAIT; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) - tcpm_set_state(port, SNK_TRY_WAIT, 0); + case SNK_TRY_WAIT_DEBOUNCE: + /* Do nothing, waiting for PD_DEBOUNCE to do be done */ break; + case SNK_TRYWAIT: case SNK_TRYWAIT_VBUS: - tcpm_set_state(port, SNK_TRYWAIT, 0); + case SNK_TRYWAIT_DEBOUNCE: break; - case SNK_ATTACH_WAIT: tcpm_set_state(port, SNK_UNATTACHED, 0); break; @@ -3042,13 +3120,13 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) /* Do nothing, expected */ break; - case ERROR_RECOVERY_WAIT_OFF: - tcpm_set_state(port, - port->pwr_role == TYPEC_SOURCE ? - SRC_UNATTACHED : SNK_UNATTACHED, - 0); + case PORT_RESET_WAIT_OFF: + tcpm_set_state(port, tcpm_default_state(port), 0); + break; + case SRC_TRY_WAIT: + case SRC_TRY_DEBOUNCE: + /* Do nothing, waiting for sink detection */ break; - default: if (port->pwr_role == TYPEC_SINK && port->attached) @@ -3142,7 +3220,7 @@ static int tcpm_dr_set(const struct typec_capability *cap, mutex_lock(&port->swap_lock); mutex_lock(&port->lock); - if (port->typec_caps.type != TYPEC_PORT_DRP || !port->pd_capable) { + if (port->port_type != TYPEC_PORT_DRP) { ret = -EINVAL; goto port_unlock; } @@ -3163,15 +3241,35 @@ static int tcpm_dr_set(const struct typec_capability *cap, * Reject data role swap request in this case. */ + if (!port->pd_capable) { + /* + * If the partner is not PD capable, reset the port to + * trigger a role change. This can only work if a preferred + * role is configured, and if it matches the requested role. + */ + if (port->try_role == TYPEC_NO_PREFERRED_ROLE || + port->try_role == port->pwr_role) { + ret = -EINVAL; + goto port_unlock; + } + port->non_pd_role_swap = true; + tcpm_set_state(port, PORT_RESET, 0); + } else { + tcpm_set_state(port, DR_SWAP_SEND, 0); + } + port->swap_status = 0; port->swap_pending = true; reinit_completion(&port->swap_complete); - tcpm_set_state(port, DR_SWAP_SEND, 0); mutex_unlock(&port->lock); - wait_for_completion(&port->swap_complete); + if (!wait_for_completion_timeout(&port->swap_complete, + msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT))) + ret = -ETIMEDOUT; + else + ret = port->swap_status; - ret = port->swap_status; + port->non_pd_role_swap = false; goto swap_unlock; port_unlock: @@ -3190,7 +3288,7 @@ static int tcpm_pr_set(const struct typec_capability *cap, mutex_lock(&port->swap_lock); mutex_lock(&port->lock); - if (port->typec_caps.type != TYPEC_PORT_DRP) { + if (port->port_type != TYPEC_PORT_DRP) { ret = -EINVAL; goto port_unlock; } @@ -3204,31 +3302,18 @@ static int tcpm_pr_set(const struct typec_capability *cap, goto port_unlock; } - if (!port->pd_capable) { - /* - * If the partner is not PD capable, reset the port to - * trigger a role change. This can only work if a preferred - * role is configured, and if it matches the requested role. - */ - if (port->try_role == TYPEC_NO_PREFERRED_ROLE || - port->try_role == port->pwr_role) { - ret = -EINVAL; - goto port_unlock; - } - tcpm_set_state(port, HARD_RESET_SEND, 0); - ret = 0; - goto port_unlock; - } - port->swap_status = 0; port->swap_pending = true; reinit_completion(&port->swap_complete); tcpm_set_state(port, PR_SWAP_SEND, 0); mutex_unlock(&port->lock); - wait_for_completion(&port->swap_complete); + if (!wait_for_completion_timeout(&port->swap_complete, + msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT))) + ret = -ETIMEDOUT; + else + ret = port->swap_status; - ret = port->swap_status; goto swap_unlock; port_unlock: @@ -3263,9 +3348,12 @@ static int tcpm_vconn_set(const struct typec_capability *cap, tcpm_set_state(port, VCONN_SWAP_SEND, 0); mutex_unlock(&port->lock); - wait_for_completion(&port->swap_complete); + if (!wait_for_completion_timeout(&port->swap_complete, + msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT))) + ret = -ETIMEDOUT; + else + ret = port->swap_status; - ret = port->swap_status; goto swap_unlock; port_unlock: @@ -3319,7 +3407,35 @@ static void tcpm_init(struct tcpm_port *port) * Some adapters need a clean slate at startup, and won't recover * otherwise. So do not try to be fancy and force a clean disconnect. */ - tcpm_set_state(port, ERROR_RECOVERY, 0); + tcpm_set_state(port, PORT_RESET, 0); +} + +static int tcpm_port_type_set(const struct typec_capability *cap, + enum typec_port_type type) +{ + struct tcpm_port *port = typec_cap_to_tcpm(cap); + + mutex_lock(&port->lock); + if (type == port->port_type) + goto port_unlock; + + port->port_type = type; + + if (!port->connected) { + tcpm_set_state(port, PORT_RESET, 0); + } else if (type == TYPEC_PORT_UFP) { + if (!(port->pwr_role == TYPEC_SINK && + port->data_role == TYPEC_DEVICE)) + tcpm_set_state(port, PORT_RESET, 0); + } else if (type == TYPEC_PORT_DFP) { + if (!(port->pwr_role == TYPEC_SOURCE && + port->data_role == TYPEC_HOST)) + tcpm_set_state(port, PORT_RESET, 0); + } + +port_unlock: + mutex_unlock(&port->lock); + return 0; } void tcpm_tcpc_reset(struct tcpm_port *port) @@ -3469,9 +3585,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) port->typec_caps.pr_set = tcpm_pr_set; port->typec_caps.vconn_set = tcpm_vconn_set; port->typec_caps.try_role = tcpm_try_role; + port->typec_caps.port_type_set = tcpm_port_type_set; port->partner_desc.identity = &port->partner_ident; - + port->port_type = tcpc->config->type; /* * TODO: * - alt_modes, set_alt_mode @@ -3485,7 +3602,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) } if (tcpc->config->alt_modes) { - struct typec_altmode_desc *paltmode = tcpc->config->alt_modes; + const struct typec_altmode_desc *paltmode = tcpc->config->alt_modes; i = 0; while (paltmode->svid && i < ARRAY_SIZE(port->port_altmode)) { diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h index 19c307d31a5a39267abe546451c89f953ccc0945..7e9a6b7b5cd6be4bb8e7b253c119a509b464929e 100644 --- a/drivers/staging/typec/tcpm.h +++ b/drivers/staging/typec/tcpm.h @@ -34,7 +34,8 @@ enum typec_cc_polarity { }; /* Time to wait for TCPC to complete transmit */ -#define PD_T_TCPC_TX_TIMEOUT 100 +#define PD_T_TCPC_TX_TIMEOUT 100 /* in ms */ +#define PD_ROLE_SWAP_TIMEOUT (MSEC_PER_SEC * 10) enum tcpm_transmit_status { TCPC_TX_SUCCESS = 0, @@ -72,7 +73,7 @@ struct tcpc_config { enum typec_role default_role; bool try_role_hw; /* try.{src,snk} implemented in hardware */ - struct typec_altmode_desc *alt_modes; + const struct typec_altmode_desc *alt_modes; }; enum tcpc_usb_switch { @@ -108,6 +109,13 @@ struct tcpc_dev { int (*init)(struct tcpc_dev *dev); int (*get_vbus)(struct tcpc_dev *dev); + /* + * This optional callback gets called by the tcpm core when configured + * as a snk and cc=Rp-def. This allows the tcpm to provide a fallback + * current-limit detection method for the cc=Rp-def case. E.g. some + * tcpcs may include BC1.2 charger detection and use that in this case. + */ + int (*get_current_limit)(struct tcpc_dev *dev); int (*set_cc)(struct tcpc_dev *dev, enum typec_cc_status cc); int (*get_cc)(struct tcpc_dev *dev, enum typec_cc_status *cc1, enum typec_cc_status *cc2); diff --git a/drivers/staging/unisys/Documentation/overview.txt b/drivers/staging/unisys/Documentation/overview.txt index e0466bfada2f895db38f138b2ecdc84a5ed2c95d..9ab30af265a5df6e01ccc95f8cf76edcfdfbd565 100644 --- a/drivers/staging/unisys/Documentation/overview.txt +++ b/drivers/staging/unisys/Documentation/overview.txt @@ -221,7 +221,7 @@ The following files exist under /sys/devices/visorbus/vbus:dev: The visorhba driver registers with visorbus as the function driver to handle virtual scsi disk devices, specified using the -VISOR_VHBA_CHANNEL_UUID type in the visorbus_register_visor_driver() +VISOR_VHBA_CHANNEL_GUID type in the visorbus_register_visor_driver() call. visorhba uses scsi_add_host() to expose a Linux block device (e.g., /sys/block/) in the guest environment for each s-Par virtual device. @@ -240,7 +240,7 @@ When compiled as a module, visorhba can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_VHBA_CHANNEL_UUID_STR + "visorbus:"+VISOR_VHBA_CHANNEL_GUID_STR i.e.: @@ -252,7 +252,7 @@ i.e.: The visornic driver registers with visorbus as the function driver to handle virtual network devices, specified using the -VISOR_VNIC_CHANNEL_UUID type in the visorbus_register_visor_driver() +VISOR_VNIC_CHANNEL_GUID type in the visorbus_register_visor_driver() call. visornic uses register_netdev() to expose a Linux device of class net (e.g., /sys/class/net/) in the guest environment for each s-Par virtual device. @@ -270,7 +270,7 @@ When compiled as a module, visornic can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_VNIC_CHANNEL_UUID_STR + "visorbus:"+VISOR_VNIC_CHANNEL_GUID_STR i.e.: @@ -282,7 +282,7 @@ i.e.: The visorinput driver registers with visorbus as the function driver to handle human input devices, specified using the -VISOR_KEYBOARD_CHANNEL_UUID and VISOR_MOUSE_CHANNEL_UUID +VISOR_KEYBOARD_CHANNEL_GUID and VISOR_MOUSE_CHANNEL_GUID types in the visorbus_register_visor_driver() call. visorinput uses input_register_device() to expose devices of class input (e.g., /sys/class/input/) for virtual keyboard and virtual mouse devices. @@ -307,8 +307,8 @@ When compiled as a module, visorinput can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_MOUSE_CHANNEL_UUID_STR - "visorbus:"+VISOR_KEYBOARD_CHANNEL_UUID_STR + "visorbus:"+VISOR_MOUSE_CHANNEL_GUID_STR + "visorbus:"+VISOR_KEYBOARD_CHANNEL_GUID_STR i.e.: diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index 692efcb38245fa5278ac7ece1b21875346991ae4..2babe93631f3e5780dda4de8d34151406edcbdd7 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -20,87 +21,48 @@ #include #include -#define __SUPERVISOR_CHANNEL_H__ - #define SIGNATURE_16(A, B) ((A) | ((B) << 8)) #define SIGNATURE_32(A, B, C, D) \ (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) -#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ - (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) - -#ifndef COVER -#define COVER(v, d) ((d) * DIV_ROUND_UP(v, d)) -#endif - #define VISOR_CHANNEL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') +/* + * enum channel_serverstate + * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state. + * @CHANNELSRV_READY: Channel has been initialized by server. + */ enum channel_serverstate { - CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ - CHANNELSRV_READY = 1 /* channel has been initialized by server */ + CHANNELSRV_UNINITIALIZED = 0, + CHANNELSRV_READY = 1 }; +/* + * enum channel_clientstate + * @CHANNELCLI_DETACHED: + * @CHANNELCLI_DISABLED: Client can see channel but is NOT allowed to use it + * unless given TBD* explicit request + * (should actually be < DETACHED). + * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach. + * @CHANNELCLI_ATTACHED: Idle, but client may want to use channel any time. + * @CHANNELCLI_BUSY: Client either wants to use or is using channel. + * @CHANNELCLI_OWNED: "No worries" state - client can access channel + * anytime. + */ enum channel_clientstate { CHANNELCLI_DETACHED = 0, - CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT - * allowed to use it unless given TBD - * explicit request (should actually be - * < DETACHED) - */ - CHANNELCLI_ATTACHING = 2, /* legacy EFI client request - * for EFI server to attach - */ - CHANNELCLI_ATTACHED = 3, /* idle, but client may want - * to use channel any time - */ - CHANNELCLI_BUSY = 4, /* client either wants to use or is - * using channel - */ - CHANNELCLI_OWNED = 5 /* "no worries" state - client can */ - /* access channel anytime */ + CHANNELCLI_DISABLED = 1, + CHANNELCLI_ATTACHING = 2, + CHANNELCLI_ATTACHED = 3, + CHANNELCLI_BUSY = 4, + CHANNELCLI_OWNED = 5 }; -#define VISOR_CHANNEL_SERVER_READY(ch) \ - (readl(&(ch)->srv_state) == CHANNELSRV_READY) - -#define VISOR_VALID_CHANNELCLI_TRANSITION(o, n) \ - (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \ - ? (1) : (0)) - -/* Values for VISORA_CHANNEL_PROTOCOL.CliErrorBoot: */ -/* throttling invalid boot channel statetransition error due to client - * disabled - */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01 - -/* throttling invalid boot channel statetransition error due to client - * not attached - */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02 - -/* throttling invalid boot channel statetransition error due to busy channel */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04 - -/* Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so - * that windows guest can look at the FeatureFlags in the io channel, - * and configure the windows driver to use interrupts or not based on - * this setting. This flag is set in uislib after the - * VISOR_VHBA_init_channel is called. All feature bits for all - * channels should be defined here. The io channel feature bits are - * defined right here +/* + * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that + * a guest can look at the FeatureFlags in the io channel, and configure the + * driver to use interrupts or not based on this setting. All feature bits for + * all channels should be defined here. The io channel feature bits are defined + * below. */ #define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1) #define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3) @@ -108,171 +70,124 @@ enum channel_clientstate { #define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5) #define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6) -/* Common Channel Header */ +/* + * struct channel_header - Common Channel Header + * @signature: Signature. + * @legacy_state: DEPRECATED - being replaced by. + * @header_size: sizeof(struct channel_header). + * @size: Total size of this channel in bytes. + * @features: Flags to modify behavior. + * @chtype: Channel type: data, bus, control, etc.. + * @partition_handle: ID of guest partition. + * @handle: Device number of this channel in client. + * @ch_space_offset: Offset in bytes to channel specific area. + * @version_id: Struct channel_header Version ID. + * @partition_index: Index of guest partition. + * @zone_uuid: Guid of Channel's zone. + * @cli_str_offset: Offset from channel header to null-terminated + * ClientString (0 if ClientString not present). + * @cli_state_boot: CHANNEL_CLIENTSTATE of pre-boot EFI client of this + * channel. + * @cmd_state_cli: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @cli_state_os: CHANNEL_CLIENTSTATE of Guest OS client of this channel. + * @ch_characteristic: CHANNEL_CHARACTERISTIC_. + * @cmd_state_srv: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @srv_state: CHANNEL_SERVERSTATE. + * @cli_error_boot: Bits to indicate err states for boot clients, so err + * messages can be throttled. + * @cli_error_os: Bits to indicate err states for OS clients, so err + * messages can be throttled. + * @filler: Pad out to 128 byte cacheline. + * @recover_channel: Please add all new single-byte values below here. + */ struct channel_header { - u64 signature; /* Signature */ - u32 legacy_state; /* DEPRECATED - being replaced by */ - /* SrvState, CliStateBoot, and CliStateOS below */ - u32 header_size; /* sizeof(struct channel_header) */ - u64 size; /* Total size of this channel in bytes */ - u64 features; /* Flags to modify behavior */ - uuid_le chtype; /* Channel type: data, bus, control, etc. */ - u64 partition_handle; /* ID of guest partition */ - u64 handle; /* Device number of this channel in client */ - u64 ch_space_offset; /* Offset in bytes to channel specific area */ - u32 version_id; /* struct channel_header Version ID */ - u32 partition_index; /* Index of guest partition */ - uuid_le zone_uuid; /* Guid of Channel's zone */ - u32 cli_str_offset; /* offset from channel header to - * nul-terminated ClientString (0 if - * ClientString not present) - */ - u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot - * EFI client of this channel - */ - u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in - * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) - */ - u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS - * client of this channel - */ - u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_ */ - u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in - * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) - */ - u32 srv_state; /* CHANNEL_SERVERSTATE */ - u8 cli_error_boot; /* bits to indicate err states for - * boot clients, so err messages can - * be throttled - */ - u8 cli_error_os; /* bits to indicate err states for OS - * clients, so err messages can be - * throttled - */ - u8 filler[1]; /* Pad out to 128 byte cacheline */ - /* Please add all new single-byte values below here */ + u64 signature; + u32 legacy_state; + /* SrvState, CliStateBoot, and CliStateOS below */ + u32 header_size; + u64 size; + u64 features; + guid_t chtype; + u64 partition_handle; + u64 handle; + u64 ch_space_offset; + u32 version_id; + u32 partition_index; + guid_t zone_guid; + u32 cli_str_offset; + u32 cli_state_boot; + u32 cmd_state_cli; + u32 cli_state_os; + u32 ch_characteristic; + u32 cmd_state_srv; + u32 srv_state; + u8 cli_error_boot; + u8 cli_error_os; + u8 filler[1]; u8 recover_channel; } __packed; #define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0) -/* Subheader for the Signal Type variation of the Common Channel */ +/* + * struct signal_queue_header - Subheader for the Signal Type variation of the + * Common Channel. + * @version: SIGNAL_QUEUE_HEADER Version ID. + * @chtype: Queue type: storage, network. + * @size: Total size of this queue in bytes. + * @sig_base_offset: Offset to signal queue area. + * @features: Flags to modify behavior. + * @num_sent: Total # of signals placed in this queue. + * @num_overflows: Total # of inserts failed due to full queue. + * @signal_size: Total size of a signal for this queue. + * @max_slots: Max # of slots in queue, 1 slot is always empty. + * @max_signals: Max # of signals in queue (MaxSignalSlots-1). + * @head: Queue head signal #. + * @num_received: Total # of signals removed from this queue. + * @tail: Queue tail signal. + * @reserved1: Reserved field. + * @reserved2: Reserved field. + * @client_queue: + * @num_irq_received: Total # of Interrupts received. This is incremented by the + * ISR in the guest windows driver. + * @num_empty: Number of times that visor_signal_remove is called and + * returned Empty Status. + * @errorflags: Error bits set during SignalReinit to denote trouble with + * client's fields. + * @filler: Pad out to 64 byte cacheline. + */ struct signal_queue_header { /* 1st cache line */ - u32 version; /* SIGNAL_QUEUE_HEADER Version ID */ - u32 chtype; /* Queue type: storage, network */ - u64 size; /* Total size of this queue in bytes */ - u64 sig_base_offset; /* Offset to signal queue area */ - u64 features; /* Flags to modify behavior */ - u64 num_sent; /* Total # of signals placed in this queue */ - u64 num_overflows; /* Total # of inserts failed due to - * full queue - */ - u32 signal_size; /* Total size of a signal for this queue */ - u32 max_slots; /* Max # of slots in queue, 1 slot is - * always empty - */ - u32 max_signals; /* Max # of signals in queue - * (MaxSignalSlots-1) - */ - u32 head; /* Queue head signal # */ + u32 version; + u32 chtype; + u64 size; + u64 sig_base_offset; + u64 features; + u64 num_sent; + u64 num_overflows; + u32 signal_size; + u32 max_slots; + u32 max_signals; + u32 head; /* 2nd cache line */ - u64 num_received; /* Total # of signals removed from this queue */ - u32 tail; /* Queue tail signal */ - u32 reserved1; /* Reserved field */ - u64 reserved2; /* Reserved field */ + u64 num_received; + u32 tail; + u32 reserved1; + u64 reserved2; u64 client_queue; - u64 num_irq_received; /* Total # of Interrupts received. This - * is incremented by the ISR in the - * guest windows driver - */ - u64 num_empty; /* Number of times that visor_signal_remove - * is called and returned Empty Status. - */ - u32 errorflags; /* Error bits set during SignalReinit - * to denote trouble with client's - * fields - */ - u8 filler[12]; /* Pad out to 64 byte cacheline */ + u64 num_irq_received; + u64 num_empty; + u32 errorflags; + u8 filler[12]; } __packed; -/* Generic function useful for validating any type of channel when it is - * received by the client that will be accessing the channel. - * Note that is only needed for callers in the EFI environment, and - * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. - */ -static inline int -visor_check_channel(struct channel_header *ch, - uuid_le expected_uuid, - char *chname, - u64 expected_min_bytes, - u32 expected_version, - u64 expected_signature) -{ - if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) { - /* caller wants us to verify type GUID */ - if (uuid_le_cmp(ch->chtype, expected_uuid) != 0) { - pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", - chname, &expected_uuid, - &expected_uuid, &ch->chtype); - return 0; - } - } - if (expected_min_bytes > 0) { /* verify channel size */ - if (ch->size < expected_min_bytes) { - pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, &expected_uuid, - (unsigned long long)expected_min_bytes, - ch->size); - return 0; - } - } - if (expected_version > 0) { /* verify channel version */ - if (ch->version_id != expected_version) { - pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", - chname, &expected_uuid, - (unsigned long)expected_version, - ch->version_id); - return 0; - } - } - if (expected_signature > 0) { /* verify channel signature */ - if (ch->signature != expected_signature) { - pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, &expected_uuid, - expected_signature, ch->signature); - return 0; - } - } - return 1; -} - -/* - * CHANNEL Guids - */ - +/* CHANNEL Guids */ /* {414815ed-c58c-11da-95a9-00e08161165f} */ -#define VISOR_VHBA_CHANNEL_UUID \ - UUID_LE(0x414815ed, 0xc58c, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vhba_channel_uuid = VISOR_VHBA_CHANNEL_UUID; -#define VISOR_VHBA_CHANNEL_UUID_STR \ +#define VISOR_VHBA_CHANNEL_GUID \ + GUID_INIT(0x414815ed, 0xc58c, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VHBA_CHANNEL_GUID_STR \ "414815ed-c58c-11da-95a9-00e08161165f" - -/* {8cd5994d-c58e-11da-95a9-00e08161165f} */ -#define VISOR_VNIC_CHANNEL_UUID \ - UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vnic_channel_uuid = VISOR_VNIC_CHANNEL_UUID; -#define VISOR_VNIC_CHANNEL_UUID_STR \ - "8cd5994d-c58e-11da-95a9-00e08161165f" - -/* {72120008-4AAB-11DC-8530-444553544200} */ -#define VISOR_SIOVM_UUID \ - UUID_LE(0x72120008, 0x4AAB, 0x11DC, \ - 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) -static const uuid_le visor_siovm_uuid = VISOR_SIOVM_UUID; - #endif diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index c7cb3fbde7b20f728b7f4af619ab473ba99863f1..a70760f48566bb8a5294166cc96e3ec9082d5499 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -1,5 +1,19 @@ -/* Copyright (C) 2010 - 2016 UNISYS CORPORATION */ -/* All rights reserved. */ +/* + * Copyright (C) 2010 - 2016 UNISYS CORPORATION + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + */ + #ifndef __IOCHANNEL_H__ #define __IOCHANNEL_H__ @@ -7,9 +21,7 @@ * Everything needed for IOPart-GuestPart communication is define in * this file. Note: Everything is OS-independent because this file is * used by Windows, Linux and possible EFI drivers. - */ - -/* + * * Communication flow between the IOPart and GuestPart uses the channel headers * channel state. The following states are currently being used: * UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED @@ -30,14 +42,10 @@ */ #include +#include -#include #include "channel.h" -#define VISOR_VHBA_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE -#define VISOR_VNIC_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE -#define VISOR_VSWITCH_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE - /* * Must increment these whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this @@ -47,82 +55,73 @@ */ #define VISOR_VHBA_CHANNEL_VERSIONID 2 #define VISOR_VNIC_CHANNEL_VERSIONID 2 -#define VISOR_VSWITCH_CHANNEL_VERSIONID 1 - -#define VISOR_VHBA_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, visor_vhba_channel_uuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, \ - VISOR_VHBA_CHANNEL_VERSIONID, \ - VISOR_VHBA_CHANNEL_SIGNATURE)) - -#define VISOR_VNIC_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, visor_vnic_channel_uuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, \ - VISOR_VNIC_CHANNEL_VERSIONID, \ - VISOR_VNIC_CHANNEL_SIGNATURE)) /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ -/* Defines and enums. */ -#define MINNUM(a, b) (((a) < (b)) ? (a) : (b)) -#define MAXNUM(a, b) (((a) > (b)) ? (a) : (b)) - -/* Define the two queues per data channel between iopart and ioguestparts. */ -/* Used by ioguestpart to 'insert' signals to iopart. */ +/* + * Define the two queues per data channel between iopart and ioguestparts. + * IOCHAN_TO_IOPART -- used by guest to 'insert' signals to iopart. + * IOCHAN_FROM_IOPART -- used by guest to 'remove' signals from IO part. + */ #define IOCHAN_TO_IOPART 0 -/* Used by ioguestpart to 'remove' signals from iopart, same previous queue. */ #define IOCHAN_FROM_IOPART 1 /* Size of cdb - i.e., SCSI cmnd */ #define MAX_CMND_SIZE 16 -#define MAX_SENSE_SIZE 64 +/* Unisys-specific DMA direction values */ +enum uis_dma_data_direction { + UIS_DMA_BIDIRECTIONAL = 0, + UIS_DMA_TO_DEVICE = 1, + UIS_DMA_FROM_DEVICE = 2, + UIS_DMA_NONE = 3 +}; +#define MAX_SENSE_SIZE 64 #define MAX_PHYS_INFO 64 -/* Various types of network packets that can be sent in cmdrsp. */ +/* + * enum net_types - Various types of network packets that can be sent in cmdrsp. + * @NET_RCV_POST: Submit buffer to hold receiving incoming packet. + * @NET_RCV: visornic -> uisnic. Incoming packet received. + * @NET_XMIT: uisnic -> visornic. For outgoing packet. + * @NET_XMIT_DONE: visornic -> uisnic. Outgoing packet xmitted. + * @NET_RCV_ENBDIS: uisnic -> visornic. Enable/Disable packet reception. + * @NET_RCV_ENBDIS_ACK: visornic -> uisnic. Acknowledge enable/disable packet. + * @NET_RCV_PROMISC: uisnic -> visornic. Enable/Disable promiscuous mode. + * @NET_CONNECT_STATUS: visornic -> uisnic. Indicate the loss or restoration of + * a network connection. + * @NET_MACADDR: uisnic -> visornic. Indicates the client has requested + * to update it's MAC address. + * @NET_MACADDR_ACK: MAC address acknowledge. + */ enum net_types { - NET_RCV_POST = 0, /* - * Submit buffer to hold receiving - * incoming packet - */ - /* visornic -> uisnic */ - NET_RCV, /* incoming packet received */ - /* uisnic -> visornic */ - NET_XMIT, /* for outgoing net packets */ - /* visornic -> uisnic */ - NET_XMIT_DONE, /* outgoing packet xmitted */ - /* uisnic -> visornic */ - NET_RCV_ENBDIS, /* enable/disable packet reception */ - /* visornic -> uisnic */ - NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet */ - /* reception */ - /* uisnic -> visornic */ - NET_RCV_PROMISC, /* enable/disable promiscuous mode */ - /* visornic -> uisnic */ - NET_CONNECT_STATUS, /* - * indicate the loss or restoration of a network - * connection - */ - /* uisnic -> visornic */ - NET_MACADDR, /* - * Indicates the client has requested to update - * it's MAC address - */ - NET_MACADDR_ACK, /* MAC address acknowledge */ - + NET_RCV_POST = 0, + NET_RCV, + NET_XMIT, + NET_XMIT_DONE, + NET_RCV_ENBDIS, + NET_RCV_ENBDIS_ACK, + /* Reception */ + NET_RCV_PROMISC, + NET_CONNECT_STATUS, + NET_MACADDR, + NET_MACADDR_ACK, }; -#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */ +/* Minimum eth data size */ +#define ETH_MIN_DATA_SIZE 46 #define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE) -#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */ +/* Maximum data size */ +#define VISOR_ETH_MAX_MTU 16384 #ifndef MAX_MACADDR_LEN -#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */ +/* Number of bytes in MAC address */ +#define MAX_MACADDR_LEN 6 #endif /* Various types of scsi task mgmt commands. */ @@ -154,12 +153,16 @@ struct guest_phys_info { u64 length; } __packed; -#define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info)) - +/* + * struct uisscsi_dest + * @channel: Bus number. + * @id: Target number. + * @lun: Logical unit number. + */ struct uisscsi_dest { - u32 channel; /* channel == bus number */ - u32 id; /* id == target number */ - u32 lun; /* lun == logical unit number */ + u32 channel; + u32 id; + u32 lun; } __packed; struct vhba_wwnn { @@ -168,61 +171,77 @@ struct vhba_wwnn { } __packed; /* - * WARNING: Values stired in this structure must contain maximum counts (not + * struct vhba_config_max + * @max_channel: Maximum channel for devices attached to this bus. + * @max_id: Maximum SCSI ID for devices attached to bus. + * @max_lun: Maximum SCSI LUN for devices attached to bus. + * @cmd_per_lun: Maximum number of outstanding commands per LUN. + * @max_io_size: Maximum io size for devices attached to this bus. Max io size + * is often determined by the resource of the hba. + * e.g Max scatter gather list length * page size / sector size. + * + * WARNING: Values stored in this structure must contain maximum counts (not * maximum values). + * + * 20 bytes */ -struct vhba_config_max {/* 20 bytes */ - u32 max_channel;/* maximum channel for devices attached to this bus */ - u32 max_id; /* maximum SCSI ID for devices attached to bus */ - u32 max_lun; /* maximum SCSI LUN for devices attached to bus */ - u32 cmd_per_lun;/* maximum number of outstanding commands per LUN */ - u32 max_io_size;/* maximum io size for devices attached to this bus */ - /* max io size is often determined by the resource of the hba. e.g */ - /* max scatter gather list length * page size / sector size */ +struct vhba_config_max { + u32 max_channel; + u32 max_id; + u32 max_lun; + u32 cmd_per_lun; + u32 max_io_size; } __packed; +/* + * struct uiscmdrsp_scsi + * + * @handle: The handle to the cmd that was received. Send it back as + * is in the rsp packet. + * @cmnd: The cdb for the command. + * @bufflen: Length of data to be transferred out or in. + * @guest_phys_entries: Number of entries in scatter-gather list. + * @struct gpi_list: Physical address information for each fragment. + * @data_dir: Direction of the data, if any. + * @struct vdest: Identifies the virtual hba, id, channel, lun to which + * cmd was sent. + * @linuxstat: Original Linux status used by Linux vdisk. + * @scsistat: The scsi status. + * @addlstat: Non-scsi status. + * @sensebuf: Sense info in case cmd failed. sensebuf holds the + * sense_data struct. See sense_data struct for more + * details. + * @*vdisk: Pointer to the vdisk to clean up when IO completes. + * @no_disk_result: Used to return no disk inquiry result when + * no_disk_result is set to 1 + * scsi.scsistat is SAM_STAT_GOOD + * scsi.addlstat is 0 + * scsi.linuxstat is SAM_STAT_GOOD + * That is, there is NO error. + */ struct uiscmdrsp_scsi { - u64 handle; /* the handle to the cmd that was received */ - /* send it back as is in the rsp packet. */ - u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */ - u32 bufflen; /* length of data to be transferred out or in */ - u16 guest_phys_entries; /* Number of entries in scatter-gather list */ - struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address - * information for each - * fragment - */ - enum dma_data_direction data_dir; /* direction of the data, if any */ - struct uisscsi_dest vdest; /* identifies the virtual hba, id, */ - /* channel, lun to which cmd was sent */ - + u64 handle; + u8 cmnd[MAX_CMND_SIZE]; + u32 bufflen; + u16 guest_phys_entries; + struct guest_phys_info gpi_list[MAX_PHYS_INFO]; + u32 data_dir; + struct uisscsi_dest vdest; /* Needed to queue the rsp back to cmd originator. */ - int linuxstat; /* original Linux status used by Linux vdisk */ - u8 scsistat; /* the scsi status */ - u8 addlstat; /* non-scsi status */ + int linuxstat; + u8 scsistat; + u8 addlstat; #define ADDL_SEL_TIMEOUT 4 - /* The following fields are need to determine the result of command. */ - u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */ - /* sensebuf holds the sense_data struct; */ - /* See sense_data struct for more details. */ - void *vdisk; /* Pointer to the vdisk to clean up when IO completes. */ + u8 sensebuf[MAX_SENSE_SIZE]; + void *vdisk; int no_disk_result; - /* - * Used to return no disk inquiry result - * when no_disk_result is set to 1, - * scsi.scsistat is SAM_STAT_GOOD - * scsi.addlstat is 0 - * scsi.linuxstat is SAM_STAT_GOOD - * That is, there is NO error. - */ } __packed; /* * Defines to support sending correct inquiry result when no disk is * configured. - */ - -/* + * * From SCSI SPC2 - * * If the target is not capable of supporting a device on this logical unit, the @@ -234,22 +253,35 @@ struct uiscmdrsp_scsi { * connected to this logical unit. */ -#define DEV_NOT_CAPABLE 0x7f /* - * peripheral qualifier of 0x3 - * peripheral type of 0x1f - * specifies no device but target present - */ - -#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 - * peripheral type of 0 - disk - * Specifies device capable, but - * not present - */ +/* + * Peripheral qualifier of 0x3 + * Peripheral type of 0x1f + * Specifies no device but target present + */ +#define DEV_NOT_CAPABLE 0x7f +/* + * Peripheral qualifier of 0x1 + * Peripheral type of 0 - disk + * Specifies device capable, but not present + */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 +/* HiSup = 1; shows support for report luns must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 -#define DEV_HISUPPORT 0x10 /* - * HiSup = 1; shows support for report luns - * must be returned for lun 0. - */ +/* + * Peripheral qualifier of 0x3 + * Peripheral type of 0x1f + * Specifies no device but target present + */ +#define DEV_NOT_CAPABLE 0x7f +/* + * Peripheral qualifier of 0x1 + * Peripheral type of 0 - disk + * Specifies device capable, but not present + */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 +/* HiSup = 1; shows support for report luns must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 /* * NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length @@ -258,11 +290,12 @@ struct uiscmdrsp_scsi { * inquiry result. */ #define NO_DISK_INQUIRY_RESULT_LEN 36 - -#define MIN_INQUIRY_RESULT_LEN 5 /* 5 bytes minimum for inquiry result */ +/* 5 bytes minimum for inquiry result */ +#define MIN_INQUIRY_RESULT_LEN 5 /* SCSI device version for no disk inquiry result */ -#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */ +/* indicates SCSI SPC2 (SPC3 is 5) */ +#define SCSI_SPC2_VER 4 /* Struct and Defines to support sense information. */ @@ -297,35 +330,48 @@ struct sense_data { u8 sense_key_specific[3]; } __packed; +/* + * struct net_pkt_xmt + * @len: Full length of data in the packet. + * @num_frags: Number of fragments in frags containing data. + * @struct phys_info frags: Physical page information. + * @ethhdr: The ethernet header. + * @struct lincsum: These are needed for csum at uisnic end. + * @valid: 1 = struct is valid - else ignore. + * @hrawoffv: 1 = hwrafoff is valid. + * @nhrawoffv: 1 = nhwrafoff is valid. + * @protocol: Specifies packet protocol. + * @csum: Value used to set skb->csum at IOPart. + * @hrawoff: Value used to set skb->h.raw at IOPart. hrawoff points to + * the start of the TRANSPORT LAYER HEADER. + * @nhrawoff: Value used to set skb->nh.raw at IOPart. nhrawoff points to + * the start of the NETWORK LAYER HEADER. + * + * NOTE: + * The full packet is described in frags but the ethernet header is + * separately kept in ethhdr so that uisnic doesn't have "MAP" the + * guest memory to get to the header. uisnic needs ethhdr to + * determine how to route the packet. + */ struct net_pkt_xmt { - int len; /* full length of data in the packet */ - int num_frags; /* number of fragments in frags containing data */ - struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */ - char ethhdr[ETH_HLEN]; /* the ethernet header */ + int len; + int num_frags; + struct phys_info frags[MAX_PHYS_INFO]; + char ethhdr[ETH_HLEN]; struct { - /* These are needed for csum at uisnic end */ - u8 valid; /* 1 = struct is valid - else ignore */ - u8 hrawoffv; /* 1 = hwrafoff is valid */ - u8 nhrawoffv; /* 1 = nhwrafoff is valid */ - __be16 protocol; /* specifies packet protocol */ - __wsum csum; /* value used to set skb->csum at IOPart */ - u32 hrawoff; /* value used to set skb->h.raw at IOPart */ - /* hrawoff points to the start of the TRANSPORT LAYER HEADER */ - u32 nhrawoff; /* value used to set skb->nh.raw at IOPart */ - /* nhrawoff points to the start of the NETWORK LAYER HEADER */ + u8 valid; + u8 hrawoffv; + u8 nhrawoffv; + __be16 protocol; + __wsum csum; + u32 hrawoff; + u32 nhrawoff; } lincsum; - - /* - * NOTE: - * The full packet is described in frags but the ethernet header is - * separately kept in ethhdr so that uisnic doesn't have "MAP" the - * guest memory to get to the header. uisnic needs ethhdr to - * determine how to route the packet. - */ } __packed; struct net_pkt_xmtdone { - u32 xmt_done_result; /* result of NET_XMIT */ + /* Result of NET_XMIT */ + u32 xmt_done_result; } __packed; /* @@ -341,14 +387,12 @@ struct net_pkt_xmtdone { ((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \ / RCVPOST_BUF_SIZE) -/* - * rcv buf size must be large enough to include ethernet data len + ethernet +/* rcv buf size must be large enough to include ethernet data len + ethernet * header len - we are choosing 2K because it is guaranteed to be describable. */ struct net_pkt_rcvpost { /* Physical page information for the single fragment 2K rcv buf */ struct phys_info frag; - /* * Ensures that receive posts are returned to the adapter which we sent * them from originally. @@ -358,172 +402,157 @@ struct net_pkt_rcvpost { } __packed; /* + * struct net_pkt_rcv + * @rcv_done_len: Length of the received data. + * @numrcvbufs: Contains the incoming data. Guest side MUST chain these + * together. + * @*rcvbuf: List of chained rcvbufa. Each entry is a receive buffer + * provided by NET_RCV_POST. NOTE: First rcvbuf in the + * chain will also be provided in net.buf. + * @unique_num: + * @rcvs_dropped_delta: + * * The number of rcvbuf that can be chained is based on max mtu and size of each * rcvbuf. */ struct net_pkt_rcv { - u32 rcv_done_len; /* length of received data */ - - /* - * numrcvbufs: contain the incoming data; guest side MUST chain these - * together. - */ + u32 rcv_done_len; u8 numrcvbufs; - - void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */ - - /* Each entry is a receive buffer provided by NET_RCV_POST. */ - /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */ + void *rcvbuf[MAX_NET_RCV_CHAIN]; u64 unique_num; u32 rcvs_dropped_delta; } __packed; struct net_pkt_enbdis { void *context; - u16 enable; /* 1 = enable, 0 = disable */ + /* 1 = enable, 0 = disable */ + u16 enable; } __packed; struct net_pkt_macaddr { void *context; - u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ + /* 6 bytes */ + u8 macaddr[MAX_MACADDR_LEN]; } __packed; -/* cmd rsp packet used for VNIC network traffic */ +/* + * struct uiscmdrsp_net - cmd rsp packet used for VNIC network traffic. + * @enum type: + * @*buf: + * @union: + * @struct xmt: Used for NET_XMIT. + * @struct xmtdone: Used for NET_XMIT_DONE. + * @struct rcvpost: Used for NET_RCV_POST. + * @struct rcv: Used for NET_RCV. + * @struct enbdis: Used for NET_RCV_ENBDIS, NET_RCV_ENBDIS_ACK, + * NET_RCV_PROMSIC, and NET_CONNECT_STATUS. + * @struct macaddr: + */ struct uiscmdrsp_net { enum net_types type; void *buf; union { - struct net_pkt_xmt xmt; /* used for NET_XMIT */ - struct net_pkt_xmtdone xmtdone; /* used for NET_XMIT_DONE */ - struct net_pkt_rcvpost rcvpost; /* used for NET_RCV_POST */ - struct net_pkt_rcv rcv; /* used for NET_RCV */ - struct net_pkt_enbdis enbdis; /* used for NET_RCV_ENBDIS, */ - /* NET_RCV_ENBDIS_ACK, */ - /* NET_RCV_PROMSIC, */ - /* and NET_CONNECT_STATUS */ + struct net_pkt_xmt xmt; + struct net_pkt_xmtdone xmtdone; + struct net_pkt_rcvpost rcvpost; + struct net_pkt_rcv rcv; + struct net_pkt_enbdis enbdis; struct net_pkt_macaddr macaddr; }; } __packed; +/* + * struct uiscmdrsp_scsitaskmgmt + * @enum tasktype: The type of task. + * @struct vdest: The vdisk for which this task mgmt is generated. + * @handle: This is a handle that the guest has saved off for its + * own use. The handle value is preserved by iopart and + * returned as in task mgmt rsp. + * @notify_handle: For Linux guests, this is a pointer to wait_queue_head + * that a thread is waiting on to see if the taskmgmt + * command has completed. When the rsp is received by + * guest, the thread receiving the response uses this to + * notify the thread waiting for taskmgmt command + * completion. It's value is preserved by iopart and + * returned as in the task mgmt rsp. + * @notifyresult_handle: This is a handle to the location in the guest where + * the result of the taskmgmt command (result field) is + * saved to when the response is handled. It's value is + * preserved by iopart and returned as is in the task mgmt + * rsp. + * @result: Result of taskmgmt command - set by IOPart. + */ struct uiscmdrsp_scsitaskmgmt { - /* The type of task. */ enum task_mgmt_types tasktype; - - /* The vdisk for which this task mgmt is generated. */ struct uisscsi_dest vdest; - - /* - * This is a handle that the guest has saved off for its own use. - * The handle value is preserved by iopart and returned as in task - * mgmt rsp. - */ u64 handle; - - /* - * For Linux guests, this is a pointer to wait_queue_head that a - * thread is waiting on to see if the taskmgmt command has completed. - * When the rsp is received by guest, the thread receiving the - * response uses this to notify the thread waiting for taskmgmt - * command completion. It's value is preserved by iopart and returned - * as in the task mgmt rsp. - */ u64 notify_handle; - - /* - * This is a handle to the location in the guest where the result of - * the taskmgmt command (result field) is saved to when the response - * is handled. It's value is preserved by iopart and returned as in - * the task mgmt rsp. - */ u64 notifyresult_handle; - - /* Result of taskmgmt command - set by IOPart - values are: */ char result; #define TASK_MGMT_FAILED 0 } __packed; -/* Used by uissd to send disk add/remove notifications to Guest. */ -/* Note that the vHba pointer is not used by the Client/Guest side. */ -struct uiscmdrsp_disknotify { - u8 add; /* 0-remove, 1-add */ - void *v_hba; /* channel info to route msg */ - u32 channel, id, lun; /* SCSI Path of Disk to added or removed */ -} __packed; - /* - * The following is used by virthba/vSCSI to send the Acquire/Release commands - * to the IOVM. + * struct uiscmdrsp_disknotify - Used by uissd to send disk add/remove + * notifications to Guest. + * @add: 0-remove, 1-add. + * @*v_hba: Channel info to route msg. + * @channel: SCSI Path of Disk to added or removed. + * @id: SCSI Path of Disk to added or removed. + * @lun: SCSI Path of Disk to added or removed. + * + * Note that the vHba pointer is not used by the Client/Guest side. */ -struct uiscmdrsp_vdiskmgmt { - /* The type of task */ - enum vdisk_mgmt_types vdisktype; - - /* The vdisk for which this task mgmt is generated */ - struct uisscsi_dest vdest; - - /* - * This is a handle that the guest has saved off for its own use. It's - * value is preserved by iopart and returned as in the task mgmt rsp. - */ - u64 handle; - - /* - * For Linux guests, this is a pointer to wait_queue_head that a - * thread is waiting on to see if the tskmgmt command has completed. - * When the rsp is received by guest, the thread receiving the - * response uses this to notify the thread waiting for taskmgmt - * command completion. It's value is preserved by iopart and returned - * as in the task mgmt rsp. - */ - u64 notify_handle; - - /* - * Handle to the location in guest where the result of the - * taskmgmt command (result field) is saved to when the response - * is handled. It's value is preserved by iopart and returned as in - * the task mgmt rsp. - */ - u64 notifyresult_handle; - - /* Result of taskmgmt command - set by IOPart - values are: */ - char result; +struct uiscmdrsp_disknotify { + u8 add; + void *v_hba; + u32 channel, id, lun; } __packed; /* Keeping cmd and rsp info in one structure for now cmd rsp packet for SCSI */ struct uiscmdrsp { char cmdtype; - -/* Describes what type of information is in the struct */ + /* Describes what type of information is in the struct */ #define CMD_SCSI_TYPE 1 #define CMD_NET_TYPE 2 #define CMD_SCSITASKMGMT_TYPE 3 #define CMD_NOTIFYGUEST_TYPE 4 -#define CMD_VDISKMGMT_TYPE 5 union { struct uiscmdrsp_scsi scsi; struct uiscmdrsp_net net; struct uiscmdrsp_scsitaskmgmt scsitaskmgmt; struct uiscmdrsp_disknotify disknotify; - struct uiscmdrsp_vdiskmgmt vdiskmgmt; }; /* Send the response when the cmd is done (scsi and scsittaskmgmt). */ void *private_data; - struct uiscmdrsp *next; /* General Purpose Queue Link */ - struct uiscmdrsp *activeQ_next; /* Pointer to the nextactive commands */ - struct uiscmdrsp *activeQ_prev; /* Pointer to the prevactive commands */ + /* General Purpose Queue Link */ + struct uiscmdrsp *next; + /* Pointer to the nextactive commands */ + struct uiscmdrsp *activeQ_next; + /* Pointer to the prevactive commands */ + struct uiscmdrsp *activeQ_prev; } __packed; +/* total = 28 bytes */ struct iochannel_vhba { - struct vhba_wwnn wwnn; /* 8 bytes */ - struct vhba_config_max max; /* 20 bytes */ -} __packed; /* total = 28 bytes */ + /* 8 bytes */ + struct vhba_wwnn wwnn; + /* 20 bytes */ + struct vhba_config_max max; +} __packed; + struct iochannel_vnic { - u8 macaddr[6]; /* 6 bytes */ - u32 num_rcv_bufs; /* 4 bytes */ - u32 mtu; /* 4 bytes */ - uuid_le zone_uuid; /* 16 bytes */ + /* 6 bytes */ + u8 macaddr[6]; + /* 4 bytes */ + u32 num_rcv_bufs; + /* 4 bytes */ + u32 mtu; + /* 16 bytes */ + guid_t zone_guid; } __packed; + /* * This is just the header of the IO channel. It is assumed that directly after * this header there is a large region of memory which contains the command and @@ -544,10 +573,11 @@ struct visor_io_channel { } __packed; /* INLINE functions for initializing and accessing I/O data channels. */ -#define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) +#define SIZEOF_CMDRSP (64 * DIV_ROUND_UP(sizeof(struct uiscmdrsp), 64)) /* Use 4K page sizes when passing page info between Guest and IOPartition. */ #define PI_PAGE_SIZE 0x1000 #define PI_PAGE_MASK 0x0FFF -#endif /* __IOCHANNEL_H__ */ +/* __IOCHANNEL_H__ */ +#endif diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index de0635542fbd029e7713d8470b87ee25859cd002..e4ee38c3dbe48436a6f1632b145e2e14cdc90c91 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -1,5 +1,4 @@ -/* visorbus.h - * +/* * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * @@ -23,7 +22,6 @@ * * There should be nothing in this file that is private to the visorbus * bus implementation itself. - * */ #ifndef __VISORBUS_H__ @@ -31,20 +29,16 @@ #include #include -#include -#include -#include -#include #include #include "channel.h" -struct visor_driver; struct visor_device; extern struct bus_type visorbus_type; typedef void (*visorbus_state_complete_func) (struct visor_device *dev, int status); + struct visorchipset_state { u32 created:1; u32 attached:1; @@ -54,11 +48,12 @@ struct visorchipset_state { /* Remaining bits in this 32-bit word are unused. */ }; -/** This struct describes a specific Supervisor channel, by providing its - * GUID, name, and sizes. +/* + * This struct describes a specific Supervisor channel, by providing its + * GUID, name, and sizes. */ struct visor_channeltype_descriptor { - const uuid_le guid; + const guid_t guid; const char *name; }; @@ -109,8 +104,7 @@ struct visor_driver { struct device_driver driver; }; -#define to_visor_driver(x) ((x) ? \ - (container_of(x, struct visor_driver, driver)) : (NULL)) +#define to_visor_driver(x) (container_of(x, struct visor_driver, driver)) /** * struct visor_device - A device type for things "plugged" into the visorbus @@ -125,8 +119,8 @@ struct visor_driver { * activity. * @being_removed: Indicates that the device is being removed from * the bus. Private bus driver use only. - * @visordriver_callback_lock: Used by the bus driver to lock when handling - * channel events. + * @visordriver_callback_lock: Used by the bus driver to lock when adding and + * removing devices. * @pausing: Indicates that a change towards a paused state. * is in progress. Only modified by the bus driver. * @resuming: Indicates that a change towards a running state @@ -141,37 +135,42 @@ struct visor_driver { * hypervisor requests. * @vbus_hdr_info: A pointer to header info. Private use by bus * driver. - * @partition_uuid: Indicates client partion id. This should be the + * @partition_guid: Indicates client partion id. This should be the * same across all visor_devices in the current * guest. Private use by bus driver only. */ struct visor_device { struct visorchannel *visorchannel; - uuid_le channel_type_guid; + guid_t channel_type_guid; /* These fields are for private use by the bus driver only. */ struct device device; struct list_head list_all; struct timer_list timer; bool timer_active; bool being_removed; - struct mutex visordriver_callback_lock; + struct mutex visordriver_callback_lock; /* synchronize probe/remove */ bool pausing; bool resuming; u32 chipset_bus_no; u32 chipset_dev_no; struct visorchipset_state state; - uuid_le inst; + guid_t inst; u8 *name; struct controlvm_message_header *pending_msg_hdr; void *vbus_hdr_info; - uuid_le partition_uuid; + guid_t partition_guid; struct dentry *debugfs_dir; struct dentry *debugfs_client_bus_info; }; #define to_visor_device(x) container_of(x, struct visor_device, device) +int visor_check_channel(struct channel_header *ch, struct device *dev, + const guid_t *expected_uuid, char *chname, + u64 expected_min_bytes, u32 expected_version, + u64 expected_signature); + int visorbus_register_visor_driver(struct visor_driver *drv); void visorbus_unregister_visor_driver(struct visor_driver *drv); int visorbus_read_channel(struct visor_device *dev, @@ -183,7 +182,8 @@ int visorbus_write_channel(struct visor_device *dev, int visorbus_enable_channel_interrupts(struct visor_device *dev); void visorbus_disable_channel_interrupts(struct visor_device *dev); -/* Levels of severity for diagnostic events, in order from lowest severity to +/* + * Levels of severity for diagnostic events, in order from lowest severity to * highest (i.e. fatal errors are the most severe, and should always be logged, * but info events rarely need to be logged except during debugging). The * values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid @@ -207,7 +207,7 @@ int visorchannel_signalremove(struct visorchannel *channel, u32 queue, int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg); bool visorchannel_signalempty(struct visorchannel *channel, u32 queue); -uuid_le visorchannel_get_uuid(struct visorchannel *channel); +const guid_t *visorchannel_get_guid(struct visorchannel *channel); #define BUS_ROOT_DEVICE UINT_MAX struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h index ed045eff0e3375d795f741c947e8c9fbf9dfac9e..32ff5c1bb6ba52d77e5f556f45f3a11a1aa6ca18 100644 --- a/drivers/staging/unisys/visorbus/controlvmchannel.h +++ b/drivers/staging/unisys/visorbus/controlvmchannel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -19,60 +20,55 @@ #include "channel.h" /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ -#define VISOR_CONTROLVM_CHANNEL_UUID \ - UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \ - 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) +#define VISOR_CONTROLVM_CHANNEL_GUID \ + GUID_INIT(0x2b3c2d10, 0x7ef5, 0x4ad8, \ + 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) -#define VISOR_CONTROLVM_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE #define CONTROLVM_MESSAGE_MAX 64 -/* Must increment this whenever you insert or delete fields within - * this channel struct. Also increment whenever you change the meaning - * of fields within this channel struct so as to break pre-existing - * software. Note that you can usually add fields to the END of the - * channel struct withOUT needing to increment this. +/* + * Must increment this whenever you insert or delete fields within this channel + * struct. Also increment whenever you change the meaning of fields within this + * channel struct so as to break pre-existing software. Note that you can + * usually add fields to the END of the channel struct withOUT needing to + * increment this. */ #define VISOR_CONTROLVM_CHANNEL_VERSIONID 1 -#define VISOR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, \ - VISOR_CONTROLVM_CHANNEL_UUID, \ - "controlvm", \ - sizeof(struct visor_controlvm_channel), \ - VISOR_CONTROLVM_CHANNEL_VERSIONID, \ - VISOR_CONTROLVM_CHANNEL_SIGNATURE)) - /* Defines for various channel queues */ -#define CONTROLVM_QUEUE_REQUEST 0 -#define CONTROLVM_QUEUE_RESPONSE 1 -#define CONTROLVM_QUEUE_EVENT 2 -#define CONTROLVM_QUEUE_ACK 3 +#define CONTROLVM_QUEUE_REQUEST 0 +#define CONTROLVM_QUEUE_RESPONSE 1 +#define CONTROLVM_QUEUE_EVENT 2 +#define CONTROLVM_QUEUE_ACK 3 /* Max num of messages stored during IOVM creation to be reused after crash */ #define CONTROLVM_CRASHMSG_MAX 2 +/* + * struct visor_segment_state + * @enabled: May enter other states. + * @active: Assigned to active partition. + * @alive: Configure message sent to service/server. + * @revoked: Similar to partition state ShuttingDown. + * @allocated: Memory (device/port number) has been selected by Command. + * @known: Has been introduced to the service/guest partition. + * @ready: Service/Guest partition has responded to introduction. + * @operating: Resource is configured and operating. + * @reserved: Natural alignment. + * + * Note: Don't use high bit unless we need to switch to ushort which is + * non-compliant. + */ struct visor_segment_state { - /* Bit 0: May enter other states */ u16 enabled:1; - /* Bit 1: Assigned to active partition */ u16 active:1; - /* Bit 2: Configure message sent to service/server */ u16 alive:1; - /* Bit 3: similar to partition state ShuttingDown */ u16 revoked:1; - /* Bit 4: memory (device/port number) has been selected by Command */ u16 allocated:1; - /* Bit 5: has been introduced to the service/guest partition */ u16 known:1; - /* Bit 6: service/Guest partition has responded to introduction */ u16 ready:1; - /* Bit 7: resource is configured and operating */ u16 operating:1; - /* Natural alignment*/ u16 reserved:8; -/* Note: don't use high bit unless we need to switch to ushort - * which is non-compliant - */ } __packed; static const struct visor_segment_state segment_state_running = { @@ -87,74 +83,101 @@ static const struct visor_segment_state segment_state_standby = { 1, 1, 0, 0, 1, 1, 1, 0 }; -/* Ids for commands that may appear in either queue of a ControlVm channel. +/* + * enum controlvm_id + * @CONTROLVM_INVALID: + * @CONTROLVM_BUS_CREATE: CP --> SP, GP. + * @CONTROLVM_BUS_DESTROY: CP --> SP, GP. + * @CONTROLVM_BUS_CONFIGURE: CP --> SP. + * @CONTROLVM_BUS_CHANGESTATE: CP --> SP, GP. + * @CONTROLVM_BUS_CHANGESTATE_EVENT: SP, GP --> CP. + * @CONTROLVM_DEVICE_CREATE: CP --> SP, GP. + * @CONTROLVM_DEVICE_DESTROY: CP --> SP, GP. + * @CONTROLVM_DEVICE_CONFIGURE: CP --> SP. + * @CONTROLVM_DEVICE_CHANGESTATE: CP --> SP, GP. + * @CONTROLVM_DEVICE_CHANGESTATE_EVENT: SP, GP --> CP. + * @CONTROLVM_DEVICE_RECONFIGURE: CP --> Boot. + * @CONTROLVM_CHIPSET_INIT: CP --> SP, GP. + * @CONTROLVM_CHIPSET_STOP: CP --> SP, GP. + * @CONTROLVM_CHIPSET_READY: CP --> SP. + * @CONTROLVM_CHIPSET_SELFTEST: CP --> SP. * - * Commands that are initiated by the command partition (CP), by an IO or - * console service partition (SP), or by a guest partition (GP)are: - * - issued on the RequestQueue queue (q #0) in the ControlVm channel - * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel + * Ids for commands that may appear in either queue of a ControlVm channel. * - * Events that are initiated by an IO or console service partition (SP) or - * by a guest partition (GP) are: - * - issued on the EventQueue queue (q #2) in the ControlVm channel - * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel + * Commands that are initiated by the command partition (CP), by an IO or + * console service partition (SP), or by a guest partition (GP) are: + * - issued on the RequestQueue queue (q #0) in the ControlVm channel + * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel + * + * Events that are initiated by an IO or console service partition (SP) or + * by a guest partition (GP) are: + * - issued on the EventQueue queue (q #2) in the ControlVm channel + * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel */ enum controlvm_id { CONTROLVM_INVALID = 0, - /* SWITCH commands required Parameter: SwitchNumber */ - /* BUS commands required Parameter: BusNumber */ - CONTROLVM_BUS_CREATE = 0x101, /* CP --> SP, GP */ - CONTROLVM_BUS_DESTROY = 0x102, /* CP --> SP, GP */ - CONTROLVM_BUS_CONFIGURE = 0x104, /* CP --> SP */ - CONTROLVM_BUS_CHANGESTATE = 0x105, /* CP --> SP, GP */ - CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, /* SP, GP --> CP */ -/* DEVICE commands required Parameter: BusNumber, DeviceNumber */ - - CONTROLVM_DEVICE_CREATE = 0x201, /* CP --> SP, GP */ - CONTROLVM_DEVICE_DESTROY = 0x202, /* CP --> SP, GP */ - CONTROLVM_DEVICE_CONFIGURE = 0x203, /* CP --> SP */ - CONTROLVM_DEVICE_CHANGESTATE = 0x204, /* CP --> SP, GP */ - CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, /* SP, GP --> CP */ - CONTROLVM_DEVICE_RECONFIGURE = 0x206, /* CP --> Boot */ -/* CHIPSET commands */ - CONTROLVM_CHIPSET_INIT = 0x301, /* CP --> SP, GP */ - CONTROLVM_CHIPSET_STOP = 0x302, /* CP --> SP, GP */ - CONTROLVM_CHIPSET_READY = 0x304, /* CP --> SP */ - CONTROLVM_CHIPSET_SELFTEST = 0x305, /* CP --> SP */ - + /* + * SWITCH commands required Parameter: SwitchNumber. + * BUS commands required Parameter: BusNumber + */ + CONTROLVM_BUS_CREATE = 0x101, + CONTROLVM_BUS_DESTROY = 0x102, + CONTROLVM_BUS_CONFIGURE = 0x104, + CONTROLVM_BUS_CHANGESTATE = 0x105, + CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, + /* DEVICE commands required Parameter: BusNumber, DeviceNumber */ + CONTROLVM_DEVICE_CREATE = 0x201, + CONTROLVM_DEVICE_DESTROY = 0x202, + CONTROLVM_DEVICE_CONFIGURE = 0x203, + CONTROLVM_DEVICE_CHANGESTATE = 0x204, + CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, + CONTROLVM_DEVICE_RECONFIGURE = 0x206, + /* CHIPSET commands */ + CONTROLVM_CHIPSET_INIT = 0x301, + CONTROLVM_CHIPSET_STOP = 0x302, + CONTROLVM_CHIPSET_READY = 0x304, + CONTROLVM_CHIPSET_SELFTEST = 0x305, }; +/* + * struct irq_info + * @reserved1: Natural alignment purposes + * @recv_irq_handle: Specifies interrupt handle. It is used to retrieve the + * corresponding interrupt pin from Monitor; and the interrupt + * pin is used to connect to the corresponding interrupt. + * Used by IOPart-GP only. + * @recv_irq_vector: Specifies interrupt vector. It, interrupt pin, and shared + * are used to connect to the corresponding interrupt. + * Used by IOPart-GP only. + * @recv_irq_shared: Specifies if the recvInterrupt is shared. It, interrupt + * pin and vector are used to connect to 0 = not shared; + * 1 = shared the corresponding interrupt. + * Used by IOPart-GP only. + * @reserved: Natural alignment purposes + */ struct irq_info { u64 reserved1; - - /* specifies interrupt handle. It is used to retrieve the - * corresponding interrupt pin from Monitor; and the - * interrupt pin is used to connect to the corresponding - * interrupt. Used by IOPart-GP only. - */ u64 recv_irq_handle; - - /* specifies interrupt vector. It, interrupt pin, and shared are - * used to connect to the corresponding interrupt. Used by - * IOPart-GP only. - */ u32 recv_irq_vector; - - /* specifies if the recvInterrupt is shared. It, interrupt pin - * and vector are used to connect to 0 = not shared; 1 = shared. - * the corresponding interrupt. Used by IOPart-GP only. - */ u8 recv_irq_shared; - u8 reserved[3]; /* Natural alignment purposes */ + u8 reserved[3]; } __packed; +/* + * struct efi_visor_indication + * @boot_to_fw_ui: Stop in UEFI UI + * @clear_nvram: Clear NVRAM + * @clear_cmos: Clear CMOS + * @boot_to_tool: Run install tool + * @reserved: Natural alignment + */ struct efi_visor_indication { - u64 boot_to_fw_ui:1; /* Bit 0: Stop in uefi ui */ - u64 clear_nvram:1; /* Bit 1: Clear NVRAM */ - u64 clear_cmos:1; /* Bit 2: Clear CMOS */ - u64 boot_to_tool:1; /* Bit 3: Run install tool */ - /* remaining bits are available */ - u64 reserved:60; /* Natural alignment */ + u64 boot_to_fw_ui:1; + u64 clear_nvram:1; + u64 clear_cmos:1; + u64 boot_to_tool:1; + /* Remaining bits are available */ + u64 reserved:60; } __packed; enum visor_chipset_feature { @@ -162,182 +185,248 @@ enum visor_chipset_feature { VISOR_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, }; -/* This is the common structure that is at the beginning of every - * ControlVm message (both commands and responses) in any ControlVm - * queue. Commands are easily distinguished from responses by - * looking at the flags.response field. +/* + * struct controlvm_message_header + * @id: See CONTROLVM_ID. + * @message_size: Includes size of this struct + size of message. + * @segment_index: Index of segment containing Vm message/information. + * @completion_status: Error status code or result of message completion. + * @struct flags: + * @failed: =1 in a response to signify failure. + * @response_expected: =1 in all messages that expect a response. + * @server: =1 in all bus & device-related messages where the + * message receiver is to act as the bus or device + * server. + * @test_message: =1 for testing use only (Control and Command + * ignore this). + * @partial_completion: =1 if there are forthcoming responses/acks + * associated with this message. + * @preserve: =1 this is to let us know to preserve channel + * contents. + * @writer_in_diag: =1 the DiagWriter is active in the Diagnostic + * Partition. + * @reserve: Natural alignment. + * @reserved: Natural alignment. + * @message_handle: Identifies the particular message instance. + * @payload_vm_offset: Offset of payload area from start of this instance. + * @payload_max_bytes: Maximum bytes allocated in payload area of ControlVm + * segment. + * @payload_bytes: Actual number of bytes of payload area to copy between + * IO/Command. If non-zero, there is a payload to copy. + * + * This is the common structure that is at the beginning of every + * ControlVm message (both commands and responses) in any ControlVm + * queue. Commands are easily distinguished from responses by + * looking at the flags.response field. */ struct controlvm_message_header { - u32 id; /* See CONTROLVM_ID. */ - /* For requests, indicates the message type. */ - /* For responses, indicates the type of message we are responding to. */ - - /* Includes size of this struct + size of message */ + u32 id; + /* + * For requests, indicates the message type. For responses, indicates + * the type of message we are responding to. + */ u32 message_size; - /* Index of segment containing Vm message/information */ u32 segment_index; - /* Error status code or result of message completion */ u32 completion_status; struct { - /* =1 in a response to signify failure */ u32 failed:1; - /* =1 in all messages that expect a response */ u32 response_expected:1; - /* =1 in all bus & device-related messages where the message - * receiver is to act as the bus or device server - */ u32 server:1; - /* =1 for testing use only (Control and Command ignore this */ u32 test_message:1; - /* =1 if there are forthcoming responses/acks associated - * with this message - */ u32 partial_completion:1; - /* =1 this is to let us know to preserve channel contents */ u32 preserve:1; - /* =1 the DiagWriter is active in the Diagnostic Partition */ u32 writer_in_diag:1; - /* Natural alignment */ u32 reserve:25; } __packed flags; - /* Natural alignment */ u32 reserved; - /* Identifies the particular message instance */ u64 message_handle; - /* request instances with the corresponding response instance. */ - /* Offset of payload area from start of this instance */ u64 payload_vm_offset; - /* Maximum bytes allocated in payload area of ControlVm segment */ u32 payload_max_bytes; - /* Actual number of bytes of payload area to copy between IO/Command */ u32 payload_bytes; - /* if non-zero, there is a payload to copy. */ } __packed; +/* + * struct controlvm_packet_device_create - For CONTROLVM_DEVICE_CREATE + * @bus_no: Bus # (0..n-1) from the msg receiver's end. + * @dev_no: Bus-relative (0..n-1) device number. + * @channel_addr: Guest physical address of the channel, which can be + * dereferenced by the receiver of this ControlVm command. + * @channel_bytes: Specifies size of the channel in bytes. + * @data_type_uuid: Specifies format of data in channel. + * @dev_inst_uuid: Instance guid for the device. + * @irq_info intr: Specifies interrupt information. + */ struct controlvm_packet_device_create { - u32 bus_no; /* bus # (0..n-1) from the msg receiver's end */ - u32 dev_no; /* bus-relative (0..n-1) device number */ - /* Guest physical address of the channel, which can be dereferenced by - * the receiver of this ControlVm command - */ + u32 bus_no; + u32 dev_no; u64 channel_addr; - u64 channel_bytes; /* specifies size of the channel in bytes */ - uuid_le data_type_uuid; /* specifies format of data in channel */ - uuid_le dev_inst_uuid; /* instance guid for the device */ - struct irq_info intr; /* specifies interrupt information */ -} __packed; /* for CONTROLVM_DEVICE_CREATE */ + u64 channel_bytes; + guid_t data_type_guid; + guid_t dev_inst_guid; + struct irq_info intr; +} __packed; +/* + * struct controlvm_packet_device_configure - For CONTROLVM_DEVICE_CONFIGURE + * @bus_no: Bus number (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + */ struct controlvm_packet_device_configure { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - /* Control uses header SegmentIndex field to access bus number... */ - u32 dev_no; /* bus-relative (0..n-1) device number */ -} __packed; /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; +} __packed; +/* Total 128 bytes */ struct controlvm_message_device_create { struct controlvm_message_header header; struct controlvm_packet_device_create packet; -} __packed; /* total 128 bytes */ +} __packed; +/* Total 56 bytes */ struct controlvm_message_device_configure { struct controlvm_message_header header; struct controlvm_packet_device_configure packet; -} __packed; /* total 56 bytes */ +} __packed; -/* This is the format for a message in any ControlVm queue. */ +/* + * struct controlvm_message_packet - This is the format for a message in any + * ControlVm queue. + * @struct create_bus: For CONTROLVM_BUS_CREATE. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_count: Indicates the max number of devices on this bus. + * @channel_addr: Guest physical address of the channel, which can be + * dereferenced by the receiver of this ControlVM + * command. + * @channel_bytes: Size of the channel. + * @bus_data_type_uuid: Indicates format of data in bus channel. + * @bus_inst_uuid: Instance uuid for the bus. + * + * @struct destroy_bus: For CONTROLVM_BUS_DESTROY. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @reserved: Natural alignment purposes. + * + * @struct configure_bus: For CONTROLVM_BUS_CONFIGURE. + * @bus_no: Bus # (0..n-1) from the receiver's perspective. + * @reserved1: For alignment purposes. + * @guest_handle: This is used to convert guest physical address to + * physical address. + * @recv_bus_irq_handle: Specifies interrupt info. It is used by SP to + * register to receive interrupts from the CP. This + * interrupt is used for bus level notifications. + * The corresponding sendBusInterruptHandle is kept + * in CP. + * + * @struct create_device: For CONTROLVM_DEVICE_CREATE. + * + * @struct destroy_device: For CONTROLVM_DEVICE_DESTROY. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + * + * @struct configure_device: For CONTROLVM_DEVICE_CONFIGURE. + * + * @struct reconfigure_device: For CONTROLVM_DEVICE_RECONFIGURE. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + * + * @struct bus_change_state: For CONTROLVM_BUS_CHANGESTATE. + * @bus_no: + * @struct state: + * @reserved: Natural alignment purposes. + * + * @struct device_change_state: For CONTROLVM_DEVICE_CHANGESTATE. + * @bus_no: + * @dev_no: + * @struct state: + * @struct flags: + * @phys_device: =1 if message is for a physical device. + * @reserved: Natural alignment. + * @reserved1: Natural alignment. + * @reserved: Natural alignment purposes. + * + * @struct device_change_state_event: For CONTROLVM_DEVICE_CHANGESTATE_EVENT. + * @bus_no: + * @dev_no: + * @struct state: + * @reserved: Natural alignment purposes. + * + * @struct init_chipset: For CONTROLVM_CHIPSET_INIT. + * @bus_count: Indicates the max number of busses. + * @switch_count: Indicates the max number of switches. + * @enum features: + * @platform_number: + * + * @struct chipset_selftest: For CONTROLVM_CHIPSET_SELFTEST. + * @options: Reserved. + * @test: Bit 0 set to run embedded selftest. + * + * @addr: A physical address of something, that can be dereferenced by the + * receiver of this ControlVm command. + * + * @handle: A handle of something (depends on command id). + */ struct controlvm_message_packet { union { struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - /* indicates the max number of devices on this bus */ u32 dev_count; - /* Guest physical address of the channel, which can be - * dereferenced by the receiver of this ControlVm command - */ u64 channel_addr; - u64 channel_bytes; /* size of the channel */ - /* indicates format of data in bus channel*/ - uuid_le bus_data_type_uuid; - uuid_le bus_inst_uuid; /* instance uuid for the bus */ - } __packed create_bus; /* for CONTROLVM_BUS_CREATE */ + u64 channel_bytes; + guid_t bus_data_type_guid; + guid_t bus_inst_guid; + } __packed create_bus; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 reserved; /* Natural alignment purposes */ - } __packed destroy_bus; /* for CONTROLVM_BUS_DESTROY */ + u32 reserved; + } __packed destroy_bus; struct { - /* bus # (0..n-1) from the receiver's perspective */ u32 bus_no; - u32 reserved1; /* for alignment purposes */ - /* This is used to convert guest physical address to physical address */ + u32 reserved1; u64 guest_handle; u64 recv_bus_irq_handle; - /* specifies interrupt info. It is used by SP - * to register to receive interrupts from the - * CP. This interrupt is used for bus level - * notifications. The corresponding - * sendBusInterruptHandle is kept in CP. - */ - } __packed configure_bus; /* for CONTROLVM_BUS_CONFIGURE */ - /* for CONTROLVM_DEVICE_CREATE */ + } __packed configure_bus; struct controlvm_packet_device_create create_device; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 dev_no; /* bus-relative (0..n-1) device # */ - } __packed destroy_device; /* for CONTROLVM_DEVICE_DESTROY */ - /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; + } __packed destroy_device; struct controlvm_packet_device_configure configure_device; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 dev_no; /* bus-relative (0..n-1) device # */ + u32 dev_no; } __packed reconfigure_device; - /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { u32 bus_no; struct visor_segment_state state; - u8 reserved[2]; /* Natural alignment purposes */ - } __packed bus_change_state; /* for CONTROLVM_BUS_CHANGESTATE */ + u8 reserved[2]; + } __packed bus_change_state; struct { u32 bus_no; u32 dev_no; struct visor_segment_state state; struct { - /* =1 if message is for a physical device */ u32 phys_device:1; - u32 reserved:31; /* Natural alignment */ - u32 reserved1; /* Natural alignment */ + u32 reserved:31; + u32 reserved1; } __packed flags; - u8 reserved[2]; /* Natural alignment purposes */ + u8 reserved[2]; } __packed device_change_state; - /* for CONTROLVM_DEVICE_CHANGESTATE */ struct { u32 bus_no; u32 dev_no; struct visor_segment_state state; - u8 reserved[6]; /* Natural alignment purposes */ + u8 reserved[6]; } __packed device_change_state_event; - /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { - /* indicates the max number of busses */ u32 bus_count; - /* indicates the max number of switches */ u32 switch_count; enum visor_chipset_feature features; - u32 platform_number; /* Platform Number */ - } __packed init_chipset; /* for CONTROLVM_CHIPSET_INIT */ + u32 platform_number; + } __packed init_chipset; struct { - u32 options; /* reserved */ - u32 test; /* bit 0 set to run embedded selftest */ + u32 options; + u32 test; } __packed chipset_selftest; - /* for CONTROLVM_CHIPSET_SELFTEST */ - /* a physical address of something, that can be dereferenced - * by the receiver of this ControlVm command - */ u64 addr; - /* a handle of something (depends on command id) */ u64 handle; }; } __packed; @@ -348,93 +437,139 @@ struct controlvm_message { struct controlvm_message_packet cmd; } __packed; +/* + * struct visor_controlvm_channel + * @struct header: + * @gp_controlvm: Guest phys addr of this channel. + * @gp_partition_tables: Guest phys addr of partition tables. + * @gp_diag_guest: Guest phys addr of diagnostic channel. + * @gp_boot_romdisk: Guest phys addr of (read* only) Boot + * ROM disk. + * @gp_boot_ramdisk: Guest phys addr of writable Boot RAM + * disk. + * @gp_acpi_table: Guest phys addr of acpi table. + * @gp_control_channel: Guest phys addr of control channel. + * @gp_diag_romdisk: Guest phys addr of diagnostic ROM disk. + * @gp_nvram: Guest phys addr of NVRAM channel. + * @request_payload_offset: Offset to request payload area. + * @event_payload_offset: Offset to event payload area. + * @request_payload_bytes: Bytes available in request payload area. + * @event_payload_bytes: Bytes available in event payload area. + * @control_channel_bytes: + * @nvram_channel_bytes: Bytes in PartitionNvram segment. + * @message_bytes: sizeof(CONTROLVM_MESSAGE). + * @message_count: CONTROLVM_MESSAGE_MAX. + * @gp_smbios_table: Guest phys addr of SMBIOS tables. + * @gp_physical_smbios_table: Guest phys addr of SMBIOS table. + * @gp_reserved: VISOR_MAX_GUESTS_PER_SERVICE. + * @virtual_guest_firmware_image_base: Guest physical address of EFI firmware + * image base. + * @virtual_guest_firmware_entry_point: Guest physical address of EFI firmware + * entry point. + * @virtual_guest_firmware_image_size: Guest EFI firmware image size. + * @virtual_guest_firmware_boot_base: GPA = 1MB where EFI firmware image is + * copied to. + * @virtual_guest_image_base: + * @virtual_guest_image_size: + * @prototype_control_channel_offset: + * @virtual_guest_partition_handle: + * @restore_action: Restore Action field to restore the + * guest partition. + * @dump_action: For Windows guests it shows if the + * visordisk is in dump mode. + * @nvram_fail_count: + * @saved_crash_message_count: = CONTROLVM_CRASHMSG_MAX. + * @saved_crash_message_offset: Offset to request payload area needed + * for crash dump. + * @installation_error: Type of error encountered during + * installation. + * @installation_text_id: Id of string to display. + * @installation_remaining_steps: Number of remaining installation steps + * (for progress bars). + * @tool_action: VISOR_TOOL_ACTIONS Installation Action + * field. + * @reserved: Alignment. + * @struct efi_visor_ind: + * @sp_reserved: + * @reserved2: Force signals to begin on 128-byte + * cache line. + * @struct request_queue: Guest partition uses this queue to send + * requests to Control. + * @struct response_queue: Control uses this queue to respond to + * service or guest partition request. + * @struct event_queue: Control uses this queue to send events + * to guest partition. + * @struct event_ack_queue: Service or guest partition uses this + * queue to ack Control events. + * @struct request_msg: Request fixed-size message pool - + * does not include payload. + * @struct response_msg: Response fixed-size message pool - + * does not include payload. + * @struct event_msg: Event fixed-size message pool - + * does not include payload. + * @struct event_ack_msg: Ack fixed-size message pool - + * does not include payload. + * @struct saved_crash_msg: Message stored during IOVM creation to + * be reused after crash. + */ struct visor_controlvm_channel { struct channel_header header; - u64 gp_controlvm; /* guest phys addr of this channel */ - u64 gp_partition_tables;/* guest phys addr of partition tables */ - u64 gp_diag_guest; /* guest phys addr of diagnostic channel */ - u64 gp_boot_romdisk;/* guest phys addr of (read* only) Boot ROM disk */ - u64 gp_boot_ramdisk;/* guest phys addr of writable Boot RAM disk */ - u64 gp_acpi_table; /* guest phys addr of acpi table */ - u64 gp_control_channel;/* guest phys addr of control channel */ - u64 gp_diag_romdisk;/* guest phys addr of diagnostic ROM disk */ - u64 gp_nvram; /* guest phys addr of NVRAM channel */ - u64 request_payload_offset; /* Offset to request payload area */ - u64 event_payload_offset; /* Offset to event payload area */ - /* Bytes available in request payload area */ + u64 gp_controlvm; + u64 gp_partition_tables; + u64 gp_diag_guest; + u64 gp_boot_romdisk; + u64 gp_boot_ramdisk; + u64 gp_acpi_table; + u64 gp_control_channel; + u64 gp_diag_romdisk; + u64 gp_nvram; + u64 request_payload_offset; + u64 event_payload_offset; u32 request_payload_bytes; - u32 event_payload_bytes;/* Bytes available in event payload area */ + u32 event_payload_bytes; u32 control_channel_bytes; - u32 nvram_channel_bytes; /* Bytes in PartitionNvram segment */ - u32 message_bytes; /* sizeof(CONTROLVM_MESSAGE) */ - u32 message_count; /* CONTROLVM_MESSAGE_MAX */ - u64 gp_smbios_table; /* guest phys addr of SMBIOS tables */ - u64 gp_physical_smbios_table; /* guest phys addr of SMBIOS table */ - /* VISOR_MAX_GUESTS_PER_SERVICE */ + u32 nvram_channel_bytes; + u32 message_bytes; + u32 message_count; + u64 gp_smbios_table; + u64 gp_physical_smbios_table; char gp_reserved[2688]; - - /* guest physical address of EFI firmware image base */ u64 virtual_guest_firmware_image_base; - - /* guest physical address of EFI firmware entry point */ u64 virtual_guest_firmware_entry_point; - - /* guest EFI firmware image size */ u64 virtual_guest_firmware_image_size; - - /* GPA = 1MB where EFI firmware image is copied to */ u64 virtual_guest_firmware_boot_base; u64 virtual_guest_image_base; u64 virtual_guest_image_size; u64 prototype_control_channel_offset; u64 virtual_guest_partition_handle; - /* Restore Action field to restore the guest partition */ u16 restore_action; - /* For Windows guests it shows if the visordisk is in dump mode */ u16 dump_action; u16 nvram_fail_count; - u16 saved_crash_message_count; /* = CONTROLVM_CRASHMSG_MAX */ - /* Offset to request payload area needed for crash dump */ + u16 saved_crash_message_count; u32 saved_crash_message_offset; - /* Type of error encountered during installation */ u32 installation_error; - u32 installation_text_id; /* Id of string to display */ - /* Number of remaining installation steps (for progress bars) */ + u32 installation_text_id; u16 installation_remaining_steps; - /* VISOR_TOOL_ACTIONS Installation Action field */ u8 tool_action; - u8 reserved; /* alignment */ + u8 reserved; struct efi_visor_indication efi_visor_ind; u32 sp_reserved; - /* Force signals to begin on 128-byte cache line */ u8 reserved2[28]; - /* guest partition uses this queue to send requests to Control */ struct signal_queue_header request_queue; - /* Control uses this queue to respond to service or guest - * partition requests - */ struct signal_queue_header response_queue; - /* Control uses this queue to send events to guest partition */ struct signal_queue_header event_queue; - /* Service or guest partition uses this queue to ack Control events */ struct signal_queue_header event_ack_queue; - /* Request fixed-size message pool - does not include payload */ - struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; - - /* Response fixed-size message pool - does not include payload */ - struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; - - /* Event fixed-size message pool - does not include payload */ - struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; - - /* Ack fixed-size message pool - does not include payload */ - struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; - - /* Message stored during IOVM creation to be reused after crash */ - struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; + struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; } __packed; -/* The following header will be located at the beginning of PayloadVmOffset for +/* + * struct visor_controlvm_parameters_header + * + * The following header will be located at the beginning of PayloadVmOffset for * various ControlVm commands. The receiver of a ControlVm command with a * PayloadVmOffset will dereference this address and then use connection_offset, * initiator_offset, and target_offset to get the location of UTF-8 formatted @@ -455,9 +590,10 @@ struct visor_controlvm_parameters_header { u32 client_length; u32 name_offset; u32 name_length; - uuid_le id; + guid_t id; u32 revision; - u32 reserved; /* Natural alignment */ + /* Natural alignment */ + u32 reserved; } __packed; /* General Errors------------------------------------------------------[0-99] */ @@ -467,72 +603,57 @@ struct visor_controlvm_parameters_header { #define CONTROLVM_RESP_KMALLOC_FAILED 3 #define CONTROLVM_RESP_ID_UNKNOWN 4 #define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5 - /* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */ #define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100 #define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101 - /* Maximum Limit----------------------------------------------------[200-299] */ -#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */ -#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */ +/* BUS_CREATE */ +#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 +/* DEVICE_CREATE */ +#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* Payload and Parameter Related------------------------------------[400-499] */ -#define CONTROLVM_RESP_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT, - * DEVICE_CONFIGURE - */ -#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 /* Multiple */ -#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */ -/* Specified[Packet Structure] Value-------------------------------[500-599] */ -#define CONTROLVM_RESP_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT, - * BUS_CONFIGURE, - * DEVICE_CREATE, - * DEVICE_CONFIG - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT*/ - /* DEVICE_CREATE, - * DEVICE_CONFIGURE, - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_CHANNEL_INVALID 502 /* DEVICE_CREATE, - * DEVICE_CONFIGURE - */ -/* Partition Driver Callback Interface----------------------[600-699] */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ -/* Unable to invoke VIRTPCI callback */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ -/* VIRTPCI Callback returned error */ +/* SWITCH_ATTACHEXTPORT, DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_PAYLOAD_INVALID 400 +/* Multiple */ +#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 +/* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 +/* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 +/* Specified[Packet Structure] Value--------------------------------[500-599] */ +/* SWITCH_ATTACHINTPORT */ +/* BUS_CONFIGURE, DEVICE_CREATE, DEVICE_CONFIG, DEVICE_DESTROY */ +#define CONTROLVM_RESP_BUS_INVALID 500 +/* SWITCH_ATTACHINTPORT*/ +/* DEVICE_CREATE, DEVICE_CONFIGURE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_DEVICE_INVALID 501 +/* DEVICE_CREATE, DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CHANNEL_INVALID 502 +/* Partition Driver Callback Interface------------------------------[600-699] */ +/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 +/* Unable to invoke VIRTPCI callback. VIRTPCI Callback returned error. */ +/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 +/* Generic device callback returned error. */ +/* SWITCH_ATTACHEXTPORT, SWITCH_DETACHEXTPORT, DEVICE_CONFIGURE */ #define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606 - /* SWITCH_ATTACHEXTPORT, - * SWITCH_DETACHEXTPORT - * DEVICE_CONFIGURE - */ - -/* generic device callback returned error */ /* Bus Related------------------------------------------------------[700-799] */ -#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */ +/* BUS_DESTROY */ +#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* Channel Related--------------------------------------------------[800-899] */ -#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO, - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */ +/* GET_CHANNELINFO, DEVICE_DESTROY */ +#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 +/* DEVICE_CREATE */ +#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* Chipset Shutdown Related---------------------------------------[1000-1099] */ #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000 #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 - /* Chipset Stop Related-------------------------------------------[1100-1199] */ #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100 #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101 - /* Device Related-------------------------------------------------[1400-1499] */ #define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400 -#endif /* __CONTROLVMCHANNEL_H__ */ +/* __CONTROLVMCHANNEL_H__ */ +#endif diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h index 01d7d517dba7498b09090543dc91b2d8f7ed6029..27e04de14818209ed75e8451eadc7d855bfb5b4e 100644 --- a/drivers/staging/unisys/visorbus/vbuschannel.h +++ b/drivers/staging/unisys/visorbus/vbuschannel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -15,26 +16,26 @@ #ifndef __VBUSCHANNEL_H__ #define __VBUSCHANNEL_H__ -/* The vbus channel is the channel area provided via the BUS_CREATE controlvm - * message for each virtual bus. This channel area is provided to both server - * and client ends of the bus. The channel header area is initialized by - * the server, and the remaining information is filled in by the client. - * We currently use this for the client to provide various information about - * the client devices and client drivers for the server end to see. +/* + * The vbus channel is the channel area provided via the BUS_CREATE controlvm + * message for each virtual bus. This channel area is provided to both server + * and client ends of the bus. The channel header area is initialized by + * the server, and the remaining information is filled in by the client. + * We currently use this for the client to provide various information about + * the client devices and client drivers for the server end to see. */ + #include #include #include "channel.h" /* {193b331b-c58f-11da-95a9-00e08161165f} */ -#define VISOR_VBUS_CHANNEL_UUID \ - UUID_LE(0x193b331b, 0xc58f, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID; +#define VISOR_VBUS_CHANNEL_GUID \ + GUID_INIT(0x193b331b, 0xc58f, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -#define VISOR_VBUS_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE - -/* Must increment this whenever you insert or delete fields within this channel +/* + * Must increment this whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this * channel struct so as to break pre-existing software. Note that you can * usually add fields to the END of the channel struct withOUT needing to @@ -43,42 +44,63 @@ static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID; #define VISOR_VBUS_CHANNEL_VERSIONID 1 /* + * struct visor_vbus_deviceinfo + * @devtype: Short string identifying the device type. + * @drvname: Driver .sys file name. + * @infostrs: Kernel vversion. + * @reserved: Pad size to 256 bytes. + * * An array of this struct is present in the channel area for each vbus. - * (See vbuschannel.h.) - * It is filled in by the client side to provide info about the device - * and driver from the client's perspective. + * (See vbuschannel.h.). It is filled in by the client side to provide info + * about the device and driver from the client's perspective. */ struct visor_vbus_deviceinfo { - u8 devtype[16]; /* short string identifying the device type */ - u8 drvname[16]; /* driver .sys file name */ - u8 infostrs[96]; /* kernel version */ - u8 reserved[128]; /* pad size to 256 bytes */ + u8 devtype[16]; + u8 drvname[16]; + u8 infostrs[96]; + u8 reserved[128]; } __packed; +/* + * struct visor_vbus_headerinfo + * @struct_bytes: Size of this struct in bytes. + * @device_info_struct_bytes: Size of VISOR_VBUS_DEVICEINFO. + * @dev_info_count: Num of items in DevInfo member. This is the + * allocated size. + * @chp_info_offset: Byte offset from beginning of this struct to the + * ChpInfo struct. + * @bus_info_offset: Byte offset from beginning of this struct to the + * BusInfo struct. + * @dev_info_offset: Byte offset from beginning of this struct to the + * DevInfo array. + * @reserved: Natural Alignment + */ struct visor_vbus_headerinfo { - u32 struct_bytes; /* size of this struct in bytes */ - u32 device_info_struct_bytes; /* sizeof(VISOR_VBUS_DEVICEINFO) */ - u32 dev_info_count; /* num of items in DevInfo member */ - /* (this is the allocated size) */ - u32 chp_info_offset; /* byte offset from beginning of this struct */ - /* to the ChpInfo struct (below) */ - u32 bus_info_offset; /* byte offset from beginning of this struct */ - /* to the BusInfo struct (below) */ - u32 dev_info_offset; /* byte offset from beginning of this struct */ - /* to the DevInfo array (below) */ + u32 struct_bytes; + u32 device_info_struct_bytes; + u32 dev_info_count; + u32 chp_info_offset; + u32 bus_info_offset; + u32 dev_info_offset; u8 reserved[104]; } __packed; +/* + * struct visor_vbus_channel + * @channel_header: Initialized by server. + * @hdr_info: Initialized by server. + * @chp_info: Describes client chipset device and driver. + * @bus_info: Describes client bus device and driver. + * @dev_info: Describes client device and driver for each device on the + * bus. + */ struct visor_vbus_channel { - struct channel_header channel_header; /* initialized by server */ - struct visor_vbus_headerinfo hdr_info; /* initialized by server */ - /* the remainder of this channel is filled in by the client */ + struct channel_header channel_header; + struct visor_vbus_headerinfo hdr_info; + /* The remainder of this channel is filled in by the client */ struct visor_vbus_deviceinfo chp_info; - /* describes client chipset device and driver */ struct visor_vbus_deviceinfo bus_info; - /* describes client bus device and driver */ struct visor_vbus_deviceinfo dev_info[0]; - /* describes client device and driver for each device on the bus */ } __packed; #endif diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 1c785dd19ddd89bf894287303e0e763d3e13b292..2bc7ff7bb96a5289ae299c711afaa2596888da9a 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1,5 +1,4 @@ -/* visorbus_main.c - * +/* * Copyright � 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -20,15 +19,14 @@ #include "visorbus.h" #include "visorbus_private.h" -#define MYDRVNAME "visorbus" +static const guid_t visor_vbus_channel_guid = VISOR_VBUS_CHANNEL_GUID; -/* Display string that is guaranteed to be no longer the 99 characters*/ +/* Display string that is guaranteed to be no longer the 99 characters */ #define LINESIZE 99 - -#define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c #define POLLJIFFIES_NORMALCHANNEL 10 -static bool initialized; /* stores whether bus_registration was successful */ +/* stores whether bus_registration was successful */ +static bool initialized; static struct dentry *visorbus_debugfs_dir; /* @@ -40,11 +38,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct visor_device *vdev; - uuid_le guid; + const guid_t *guid; vdev = to_visor_device(dev); - guid = visorchannel_get_uuid(vdev->visorchannel); - return sprintf(buf, "visorbus:%pUl\n", &guid); + guid = visorchannel_get_guid(vdev->visorchannel); + return sprintf(buf, "visorbus:%pUl\n", guid); } static DEVICE_ATTR_RO(modalias); @@ -53,15 +51,7 @@ static struct attribute *visorbus_dev_attrs[] = { NULL, }; -/* sysfs example for bridge-only sysfs files using device_type's */ -static const struct attribute_group visorbus_dev_group = { - .attrs = visorbus_dev_attrs, -}; - -static const struct attribute_group *visorbus_dev_groups[] = { - &visorbus_dev_group, - NULL, -}; +ATTRIBUTE_GROUPS(visorbus_dev); /* filled in with info about parent chipset driver when we register with it */ static struct visor_vbus_deviceinfo chipset_driverinfo; @@ -73,16 +63,70 @@ static LIST_HEAD(list_all_bus_instances); /* list of visor_device structs, linked via .list_all */ static LIST_HEAD(list_all_device_instances); -static int -visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) +/* + * Generic function useful for validating any type of channel when it is + * received by the client that will be accessing the channel. + * Note that is only needed for callers in the EFI environment, and + * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. + */ +int visor_check_channel(struct channel_header *ch, + struct device *dev, + const guid_t *expected_guid, + char *chname, + u64 expected_min_bytes, + u32 expected_version, + u64 expected_signature) +{ + if (!guid_is_null(expected_guid)) { + /* caller wants us to verify type GUID */ + if (!guid_equal(&ch->chtype, expected_guid)) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", + chname, expected_guid, expected_guid, + &ch->chtype); + return 0; + } + } + /* verify channel size */ + if (expected_min_bytes > 0) { + if (ch->size < expected_min_bytes) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, expected_guid, + (unsigned long long)expected_min_bytes, + ch->size); + return 0; + } + } + /* verify channel version */ + if (expected_version > 0) { + if (ch->version_id != expected_version) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", + chname, expected_guid, + (unsigned long)expected_version, + ch->version_id); + return 0; + } + } + /* verify channel signature */ + if (expected_signature > 0) { + if (ch->signature != expected_signature) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, expected_guid, expected_signature, + ch->signature); + return 0; + } + } + return 1; +} + +static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) { struct visor_device *dev; - uuid_le guid; + const guid_t *guid; dev = to_visor_device(xdev); - guid = visorchannel_get_uuid(dev->visorchannel); + guid = visorchannel_get_guid(dev->visorchannel); - return add_uevent_var(env, "MODALIAS=visorbus:%pUl", &guid); + return add_uevent_var(env, "MODALIAS=visorbus:%pUl", guid); } /* @@ -94,27 +138,21 @@ visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) * * Return: 1 iff the provided driver can control the specified device */ -static int -visorbus_match(struct device *xdev, struct device_driver *xdrv) +static int visorbus_match(struct device *xdev, struct device_driver *xdrv) { - uuid_le channel_type; + const guid_t *channel_type; int i; struct visor_device *dev; struct visor_driver *drv; dev = to_visor_device(xdev); + channel_type = visorchannel_get_guid(dev->visorchannel); drv = to_visor_driver(xdrv); - channel_type = visorchannel_get_uuid(dev->visorchannel); - if (!drv->channel_types) return 0; - for (i = 0; - (uuid_le_cmp(drv->channel_types[i].guid, NULL_UUID_LE) != 0) || - (drv->channel_types[i].name); - i++) - if (uuid_le_cmp(drv->channel_types[i].guid, - channel_type) == 0) + for (i = 0; !guid_is_null(&drv->channel_types[i].guid); i++) + if (guid_equal(&drv->channel_types[i].guid, channel_type)) return i + 1; return 0; @@ -122,7 +160,7 @@ visorbus_match(struct device *xdev, struct device_driver *xdrv) /* * This describes the TYPE of bus. - * (Don't confuse this with an INSTANCE of the bus.) + * (Don't confuse this with an INSTANCE of the bus.) */ struct bus_type visorbus_type = { .name = "visorbus", @@ -137,8 +175,7 @@ struct bus_type visorbus_type = { * involved with destroying the dev are complete * @xdev: struct device for the bus being released */ -static void -visorbus_release_busdevice(struct device *xdev) +static void visorbus_release_busdevice(struct device *xdev) { struct visor_device *dev = dev_get_drvdata(xdev); @@ -152,15 +189,11 @@ visorbus_release_busdevice(struct device *xdev) * each child device instance * @xdev: struct device for the visor device being released */ -static void -visorbus_release_device(struct device *xdev) +static void visorbus_release_device(struct device *xdev) { struct visor_device *dev = to_visor_device(xdev); - if (dev->visorchannel) { - visorchannel_destroy(dev->visorchannel); - dev->visorchannel = NULL; - } + visorchannel_destroy(dev->visorchannel); kfree(dev); } @@ -229,7 +262,7 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, struct device_driver *xdrv = dev->driver; struct visor_driver *drv = NULL; - if (!xbus || !xdrv) + if (!xdrv) return 0; i = xbus->match(dev, xdrv); if (!i) @@ -240,24 +273,16 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(typename); static struct attribute *channel_attrs[] = { - &dev_attr_physaddr.attr, - &dev_attr_nbytes.attr, - &dev_attr_clientpartition.attr, - &dev_attr_typeguid.attr, - &dev_attr_zoneguid.attr, - &dev_attr_typename.attr, - NULL + &dev_attr_physaddr.attr, + &dev_attr_nbytes.attr, + &dev_attr_clientpartition.attr, + &dev_attr_typeguid.attr, + &dev_attr_zoneguid.attr, + &dev_attr_typename.attr, + NULL }; -static struct attribute_group channel_attr_grp = { - .name = "channel", - .attrs = channel_attrs, -}; - -static const struct attribute_group *visorbus_channel_groups[] = { - &channel_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(channel); /* end implementation of specific channel attributes */ @@ -270,7 +295,8 @@ static const struct attribute_group *visorbus_channel_groups[] = { static ssize_t partition_handle_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 handle = visorchannel_get_clientpartition(vdev->visorchannel); @@ -280,16 +306,18 @@ static DEVICE_ATTR_RO(partition_handle); static ssize_t partition_guid_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); - return sprintf(buf, "{%pUb}\n", &vdev->partition_uuid); + return sprintf(buf, "{%pUb}\n", &vdev->partition_guid); } static DEVICE_ATTR_RO(partition_guid); static ssize_t partition_name_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); return sprintf(buf, "%s\n", vdev->name); @@ -298,7 +326,8 @@ static DEVICE_ATTR_RO(partition_name); static ssize_t channel_addr_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 addr = visorchannel_get_physaddr(vdev->visorchannel); @@ -308,7 +337,8 @@ static DEVICE_ATTR_RO(channel_addr); static ssize_t channel_bytes_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel); @@ -318,7 +348,8 @@ static DEVICE_ATTR_RO(channel_bytes); static ssize_t channel_id_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); int len = 0; @@ -330,24 +361,17 @@ static ssize_t channel_id_show(struct device *dev, } static DEVICE_ATTR_RO(channel_id); -static struct attribute *dev_attrs[] = { - &dev_attr_partition_handle.attr, - &dev_attr_partition_guid.attr, - &dev_attr_partition_name.attr, - &dev_attr_channel_addr.attr, - &dev_attr_channel_bytes.attr, - &dev_attr_channel_id.attr, - NULL -}; - -static struct attribute_group dev_attr_grp = { - .attrs = dev_attrs, +static struct attribute *visorbus_attrs[] = { + &dev_attr_partition_handle.attr, + &dev_attr_partition_guid.attr, + &dev_attr_partition_name.attr, + &dev_attr_channel_addr.attr, + &dev_attr_channel_bytes.attr, + &dev_attr_channel_id.attr, + NULL }; -static const struct attribute_group *visorbus_groups[] = { - &dev_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(visorbus); /* * BUS debugfs entries @@ -355,6 +379,7 @@ static const struct attribute_group *visorbus_groups[] = { * define & implement display of debugfs attributes under * /sys/kernel/debug/visorbus/visorbus. */ + /* * vbuschannel_print_devinfo() - format a struct visor_vbus_deviceinfo * and write it to a seq_file @@ -365,12 +390,12 @@ static const struct attribute_group *visorbus_groups[] = { * * Reads @devInfo, and writes it in human-readable notation to @seq. */ -static void -vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, - struct seq_file *seq, int devix) +static void vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, + struct seq_file *seq, int devix) { + /* uninitialized vbus device entry */ if (!isprint(devinfo->devtype[0])) - return; /* uninitialized vbus device entry */ + return; if (devix >= 0) seq_printf(seq, "[%d]", devix); @@ -392,12 +417,11 @@ vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) { - struct visor_device *vdev = seq->private; - struct visorchannel *channel = vdev->visorchannel; - - int i; + int i = 0; unsigned long off; struct visor_vbus_deviceinfo dev_info; + struct visor_device *vdev = seq->private; + struct visorchannel *channel = vdev->visorchannel; if (!channel) return 0; @@ -406,6 +430,7 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) "Client device / client driver info for %s partition (vbus #%u):\n", ((vdev->name) ? (char *)(vdev->name) : ""), vdev->chipset_bus_no); + if (visorchannel_read(channel, offsetof(struct visor_vbus_channel, chp_info), &dev_info, sizeof(dev_info)) >= 0) @@ -414,8 +439,8 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) offsetof(struct visor_vbus_channel, bus_info), &dev_info, sizeof(dev_info)) >= 0) vbuschannel_print_devinfo(&dev_info, seq, -1); + off = offsetof(struct visor_vbus_channel, dev_info); - i = 0; while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) { if (visorchannel_read(channel, off, &dev_info, sizeof(dev_info)) >= 0) @@ -441,8 +466,7 @@ static const struct file_operations client_bus_info_debugfs_fops = { .release = single_release, }; -static void -dev_periodic_work(unsigned long __opaque) +static void dev_periodic_work(unsigned long __opaque) { struct visor_device *dev = (struct visor_device *)__opaque; struct visor_driver *drv = to_visor_driver(dev->device.driver); @@ -451,8 +475,7 @@ dev_periodic_work(unsigned long __opaque) mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL); } -static int -dev_start_periodic_work(struct visor_device *dev) +static int dev_start_periodic_work(struct visor_device *dev) { if (dev->being_removed || dev->timer_active) return -EINVAL; @@ -464,8 +487,7 @@ dev_start_periodic_work(struct visor_device *dev) return 0; } -static void -dev_stop_periodic_work(struct visor_device *dev) +static void dev_stop_periodic_work(struct visor_device *dev) { if (!dev->timer_active) return; @@ -484,40 +506,39 @@ dev_stop_periodic_work(struct visor_device *dev) * * Return: 0 iff successful */ -static int -visordriver_remove_device(struct device *xdev) +static int visordriver_remove_device(struct device *xdev) { struct visor_device *dev; struct visor_driver *drv; dev = to_visor_device(xdev); drv = to_visor_driver(xdev->driver); + mutex_lock(&dev->visordriver_callback_lock); dev->being_removed = true; - if (drv->remove) - drv->remove(dev); + drv->remove(dev); mutex_unlock(&dev->visordriver_callback_lock); - dev_stop_periodic_work(dev); + dev_stop_periodic_work(dev); put_device(&dev->device); + return 0; } -/** +/* * visorbus_unregister_visor_driver() - unregisters the provided driver * @drv: the driver to unregister * * A visor function driver calls this function to unregister the driver, * i.e., within its module_exit function. */ -void -visorbus_unregister_visor_driver(struct visor_driver *drv) +void visorbus_unregister_visor_driver(struct visor_driver *drv) { driver_unregister(&drv->driver); } EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); -/** +/* * visorbus_read_channel() - reads from the designated channel into * the provided buffer * @dev: the device whose channel is read from @@ -530,15 +551,14 @@ EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); * * Return: integer indicating success (zero) or failure (non-zero) */ -int -visorbus_read_channel(struct visor_device *dev, unsigned long offset, - void *dest, unsigned long nbytes) +int visorbus_read_channel(struct visor_device *dev, unsigned long offset, + void *dest, unsigned long nbytes) { return visorchannel_read(dev->visorchannel, offset, dest, nbytes); } EXPORT_SYMBOL_GPL(visorbus_read_channel); -/** +/* * visorbus_write_channel() - writes the provided buffer into the designated * channel * @dev: the device whose channel is written to @@ -551,15 +571,14 @@ EXPORT_SYMBOL_GPL(visorbus_read_channel); * * Return: integer indicating success (zero) or failure (non-zero) */ -int -visorbus_write_channel(struct visor_device *dev, unsigned long offset, - void *src, unsigned long nbytes) +int visorbus_write_channel(struct visor_device *dev, unsigned long offset, + void *src, unsigned long nbytes) { return visorchannel_write(dev->visorchannel, offset, src, nbytes); } EXPORT_SYMBOL_GPL(visorbus_write_channel); -/** +/* * visorbus_enable_channel_interrupts() - enables interrupts on the * designated device * @dev: the device on which to enable interrupts @@ -567,8 +586,7 @@ EXPORT_SYMBOL_GPL(visorbus_write_channel); * Currently we don't yet have a real interrupt, so for now we just call the * interrupt function periodically via a timer. */ -int -visorbus_enable_channel_interrupts(struct visor_device *dev) +int visorbus_enable_channel_interrupts(struct visor_device *dev) { struct visor_driver *drv = to_visor_driver(dev->device.driver); @@ -581,13 +599,12 @@ visorbus_enable_channel_interrupts(struct visor_device *dev) } EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts); -/** +/* * visorbus_disable_channel_interrupts() - disables interrupts on the * designated device * @dev: the device on which to disable interrupts */ -void -visorbus_disable_channel_interrupts(struct visor_device *dev) +void visorbus_disable_channel_interrupts(struct visor_device *dev) { dev_stop_periodic_work(dev); } @@ -616,8 +633,7 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts); * Return: 0 if successful, otherwise the negative value returned by * device_add() indicating the reason for failure */ -static int -create_visor_device(struct visor_device *dev) +int create_visor_device(struct visor_device *dev) { int err; u32 chipset_bus_no = dev->chipset_bus_no; @@ -625,7 +641,7 @@ create_visor_device(struct visor_device *dev) mutex_init(&dev->visordriver_callback_lock); dev->device.bus = &visorbus_type; - dev->device.groups = visorbus_channel_groups; + dev->device.groups = channel_groups; device_initialize(&dev->device); dev->device.release = visorbus_release_device; /* keep a reference just for us (now 2) */ @@ -664,7 +680,10 @@ create_visor_device(struct visor_device *dev) goto err_put; list_add_tail(&dev->list_all, &list_all_device_instances); - return 0; /* success: reference kept via unmatched get_device() */ + dev->state.created = 1; + visorbus_response(dev, err, CONTROLVM_DEVICE_CREATE); + /* success: reference kept via unmatched get_device() */ + return 0; err_put: put_device(&dev->device); @@ -672,26 +691,27 @@ create_visor_device(struct visor_device *dev) return err; } -static void -remove_visor_device(struct visor_device *dev) +void remove_visor_device(struct visor_device *dev) { list_del(&dev->list_all); put_device(&dev->device); device_unregister(&dev->device); + visorbus_response(dev, 0, CONTROLVM_DEVICE_DESTROY); } -static int -get_vbus_header_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info) +static int get_vbus_header_info(struct visorchannel *chan, + struct device *dev, + struct visor_vbus_headerinfo *hdr_info) { int err; if (!visor_check_channel(visorchannel_get_header(chan), - visor_vbus_channel_uuid, + dev, + &visor_vbus_channel_guid, "vbus", sizeof(struct visor_vbus_channel), VISOR_VBUS_CHANNEL_VERSIONID, - VISOR_VBUS_CHANNEL_SIGNATURE)) + VISOR_CHANNEL_SIGNATURE)) return -EINVAL; err = visorchannel_read(chan, sizeof(struct channel_header), hdr_info, @@ -722,10 +742,9 @@ get_vbus_header_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_chp_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) +static void write_vbus_chp_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info) { int off = sizeof(struct channel_header) + hdr_info->chp_info_offset; @@ -748,10 +767,9 @@ write_vbus_chp_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_bus_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) +static void write_vbus_bus_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info) { int off = sizeof(struct channel_header) + hdr_info->bus_info_offset; @@ -775,10 +793,10 @@ write_vbus_bus_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_dev_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info, unsigned int devix) +static void write_vbus_dev_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info, + unsigned int devix) { int off = (sizeof(struct channel_header) + hdr_info->dev_info_offset) + @@ -807,14 +825,13 @@ static void bus_device_info_init( } /* - * fix_vbus_dev_info() - for a child device just created on a client bus, fill - * in information about the driver that is controlling - * this device into the appropriate slot within the - * vbus channel of the bus instance + * publish_vbus_dev_info() - for a child device just created on a client bus, + * fill in information about the driver that is + * controlling this device into the appropriate slot + * within the vbus channel of the bus instance * @visordev: struct visor_device for the desired device */ -static void -fix_vbus_dev_info(struct visor_device *visordev) +static void publish_vbus_dev_info(struct visor_device *visordev) { int i; struct visor_device *bdev; @@ -853,7 +870,6 @@ fix_vbus_dev_info(struct visor_device *visordev) bus_device_info_init(&dev_info, chan_type_name, visordrv->name); write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no); - write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo); write_vbus_bus_info(bdev->visorchannel, hdr_info, &clientbus_driverinfo); @@ -874,18 +890,14 @@ fix_vbus_dev_info(struct visor_device *visordev) * was successful with this device, otherwise a negative errno * value indicating failure reason */ -static int -visordriver_probe_device(struct device *xdev) +static int visordriver_probe_device(struct device *xdev) { int res; struct visor_driver *drv; struct visor_device *dev; - drv = to_visor_driver(xdev->driver); dev = to_visor_device(xdev); - - if (!drv->probe) - return -ENODEV; + drv = to_visor_driver(xdev->driver); mutex_lock(&dev->visordriver_callback_lock); dev->being_removed = false; @@ -894,14 +906,14 @@ visordriver_probe_device(struct device *xdev) if (res >= 0) { /* success: reference kept via unmatched get_device() */ get_device(&dev->device); - fix_vbus_dev_info(dev); + publish_vbus_dev_info(dev); } mutex_unlock(&dev->visordriver_callback_lock); return res; } -/** +/* * visorbus_register_visor_driver() - registers the provided visor driver * for handling one or more visor device * types (channel_types) @@ -952,8 +964,21 @@ visordriver_probe_device(struct device *xdev) */ int visorbus_register_visor_driver(struct visor_driver *drv) { + /* can't register on a nonexistent bus */ if (!initialized) - return -ENODEV; /* can't register on a nonexistent bus */ + return -ENODEV; + + if (!drv->probe) + return -EINVAL; + + if (!drv->remove) + return -EINVAL; + + if (!drv->pause) + return -EINVAL; + + if (!drv->resume) + return -EINVAL; drv->driver.name = drv->name; drv->driver.bus = &visorbus_type; @@ -985,8 +1010,7 @@ EXPORT_SYMBOL_GPL(visorbus_register_visor_driver); * Return: 0 for success, otherwise negative errno value indicating reason for * failure */ -static int -visorbus_create_instance(struct visor_device *dev) +int visorbus_create_instance(struct visor_device *dev) { int id = dev->chipset_bus_no; int err; @@ -1009,7 +1033,7 @@ visorbus_create_instance(struct visor_device *dev) &client_bus_info_debugfs_fops); dev_set_drvdata(&dev->device, dev); - err = get_vbus_header_info(dev->visorchannel, hdr_info); + err = get_vbus_header_info(dev->visorchannel, &dev->device, hdr_info); if (err < 0) goto err_debugfs_dir; @@ -1019,18 +1043,21 @@ visorbus_create_instance(struct visor_device *dev) list_add_tail(&dev->list_all, &list_all_bus_instances); + dev->state.created = 1; dev->vbus_hdr_info = (void *)hdr_info; write_vbus_chp_info(dev->visorchannel, hdr_info, &chipset_driverinfo); write_vbus_bus_info(dev->visorchannel, hdr_info, &clientbus_driverinfo); + visorbus_response(dev, err, CONTROLVM_BUS_CREATE); + return 0; err_debugfs_dir: debugfs_remove_recursive(dev->debugfs_dir); kfree(hdr_info); - dev_err(&dev->device, "visorbus_create_instance failed: %d\n", err); + dev_err(&dev->device, "%s failed: %d\n", __func__, err); return err; } @@ -1038,8 +1065,7 @@ visorbus_create_instance(struct visor_device *dev) * visorbus_remove_instance() - remove a device instance for the visorbus itself * @dev: struct visor_device indentifying the bus to remove */ -static void -visorbus_remove_instance(struct visor_device *dev) +void visorbus_remove_instance(struct visor_device *dev) { /* * Note that this will result in the release method for @@ -1049,20 +1075,17 @@ visorbus_remove_instance(struct visor_device *dev) * successfully been able to trace thru the code to see where/how * release() gets called. But I know it does. */ - if (dev->visorchannel) { - visorchannel_destroy(dev->visorchannel); - dev->visorchannel = NULL; - } + visorchannel_destroy(dev->visorchannel); kfree(dev->vbus_hdr_info); list_del(&dev->list_all); device_unregister(&dev->device); + visorbus_response(dev, 0, CONTROLVM_BUS_DESTROY); } /* * remove_all_visor_devices() - remove all child visorbus device instances */ -static void -remove_all_visor_devices(void) +static void remove_all_visor_devices(void) { struct list_head *listentry, *listtmp; @@ -1074,50 +1097,6 @@ remove_all_visor_devices(void) } } -int -visorchipset_bus_create(struct visor_device *dev) -{ - int err; - - err = visorbus_create_instance(dev); - - if (err < 0) - return err; - - visorbus_create_response(dev, err); - - return 0; -} - -void -visorchipset_bus_destroy(struct visor_device *dev) -{ - visorbus_remove_instance(dev); - visorbus_destroy_response(dev, 0); -} - -int -visorchipset_device_create(struct visor_device *dev_info) -{ - int err; - - err = create_visor_device(dev_info); - if (err < 0) - return err; - - visorbus_device_create_response(dev_info, err); - - return 0; -} - -void -visorchipset_device_destroy(struct visor_device *dev_info) -{ - remove_visor_device(dev_info); - - visorbus_device_destroy_response(dev_info, 0); -} - /* * pause_state_change_complete() - the callback function to be called by a * visorbus function driver when a @@ -1127,15 +1106,14 @@ visorchipset_device_destroy(struct visor_device *dev_info) * @status: 0 iff the pause state change completed successfully, otherwise * a negative errno value indicating the reason for failure */ -static void -pause_state_change_complete(struct visor_device *dev, int status) +static void pause_state_change_complete(struct visor_device *dev, int status) { if (!dev->pausing) return; dev->pausing = false; - - visorbus_device_pause_response(dev, status); + visorbus_device_changestate_response(dev, status, + segment_state_standby); } /* @@ -1147,8 +1125,7 @@ pause_state_change_complete(struct visor_device *dev, int status) * @status: 0 iff the resume state change completed successfully, otherwise * a negative errno value indicating the reason for failure */ -static void -resume_state_change_complete(struct visor_device *dev, int status) +static void resume_state_change_complete(struct visor_device *dev, int status) { if (!dev->resuming) return; @@ -1160,7 +1137,8 @@ resume_state_change_complete(struct visor_device *dev, int status) * which will presumably want to send some sort of response to * the initiator. */ - visorbus_device_resume_response(dev, status); + visorbus_device_changestate_response(dev, status, + segment_state_running); } /* @@ -1174,34 +1152,28 @@ resume_state_change_complete(struct visor_device *dev, int status) * via a callback function; see pause_state_change_complete() and * resume_state_change_complete(). */ -static int -visorchipset_initiate_device_pause_resume(struct visor_device *dev, - bool is_pause) +static int visorchipset_initiate_device_pause_resume(struct visor_device *dev, + bool is_pause) { int err; struct visor_driver *drv = NULL; - drv = to_visor_driver(dev->device.driver); - if (!drv) - return -ENODEV; - + /* If no driver associated with the device nothing to pause/resume */ + if (!dev->device.driver) + return 0; if (dev->pausing || dev->resuming) return -EBUSY; + drv = to_visor_driver(dev->device.driver); if (is_pause) { - if (!drv->pause) - return -EINVAL; - dev->pausing = true; err = drv->pause(dev, pause_state_change_complete); } else { - /* The vbus_dev_info structure in the channel was been - * cleared, make sure it is valid. + /* + * The vbus_dev_info structure in the channel was been cleared, + * make sure it is valid. */ - fix_vbus_dev_info(dev); - if (!drv->resume) - return -EINVAL; - + publish_vbus_dev_info(dev); dev->resuming = true; err = drv->resume(dev, resume_state_change_complete); } @@ -1209,7 +1181,7 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev, return err; } -/** +/* * visorchipset_device_pause() - start a pause operation for a visor device * @dev_info: struct visor_device identifying the device being paused * @@ -1217,13 +1189,11 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev, * that device. Success/failure result is returned asynchronously * via a callback function; see pause_state_change_complete(). */ -int -visorchipset_device_pause(struct visor_device *dev_info) +int visorchipset_device_pause(struct visor_device *dev_info) { int err; err = visorchipset_initiate_device_pause_resume(dev_info, true); - if (err < 0) { dev_info->pausing = false; return err; @@ -1232,7 +1202,7 @@ visorchipset_device_pause(struct visor_device *dev_info) return 0; } -/** +/* * visorchipset_device_resume() - start a resume operation for a visor device * @dev_info: struct visor_device identifying the device being resumed * @@ -1240,13 +1210,11 @@ visorchipset_device_pause(struct visor_device *dev_info) * that device. Success/failure result is returned asynchronously * via a callback function; see resume_state_change_complete(). */ -int -visorchipset_device_resume(struct visor_device *dev_info) +int visorchipset_device_resume(struct visor_device *dev_info) { int err; err = visorchipset_initiate_device_pause_resume(dev_info, false); - if (err < 0) { dev_info->resuming = false; return err; @@ -1255,8 +1223,7 @@ visorchipset_device_resume(struct visor_device *dev_info) return 0; } -int -visorbus_init(void) +int visorbus_init(void) { int err; @@ -1271,14 +1238,12 @@ visorbus_init(void) return err; initialized = true; - bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset"); return 0; } -void -visorbus_exit(void) +void visorbus_exit(void) { struct list_head *listentry, *listtmp; diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h index 98a5af19189db32e528982518777ddbc0338f47e..e878d65ab6683c8668868c14fa87c80d65387da1 100644 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ b/drivers/staging/unisys/visorbus/visorbus_private.h @@ -1,5 +1,4 @@ -/* visorbus_private.h - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -22,36 +21,27 @@ #include "controlvmchannel.h" #include "vbuschannel.h" +#include "visorbus.h" -/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the - * command line - */ - -int visorchipset_bus_create(struct visor_device *bus_info); -void visorchipset_bus_destroy(struct visor_device *bus_info); -int visorchipset_device_create(struct visor_device *dev_info); -void visorchipset_device_destroy(struct visor_device *dev_info); +int visorbus_create_instance(struct visor_device *dev); +void visorbus_remove_instance(struct visor_device *bus_info); +int create_visor_device(struct visor_device *dev_info); +void remove_visor_device(struct visor_device *dev_info); int visorchipset_device_pause(struct visor_device *dev_info); int visorchipset_device_resume(struct visor_device *dev_info); -void visorbus_create_response(struct visor_device *p, int response); -void visorbus_destroy_response(struct visor_device *p, int response); -void visorbus_device_create_response(struct visor_device *p, int response); -void visorbus_device_destroy_response(struct visor_device *p, int response); -void visorbus_device_resume_response(struct visor_device *p, int response); -void visorbus_device_pause_response(struct visor_device *p, int response); +void visorbus_response(struct visor_device *p, int response, int controlvm_id); +void visorbus_device_changestate_response(struct visor_device *p, int response, + struct visor_segment_state state); int visorbus_init(void); void visorbus_exit(void); /* visorchannel access functions */ - -struct visorchannel *visorchannel_create(u64 physaddr, - unsigned long channel_bytes, - gfp_t gfp, uuid_le guid); -struct visorchannel *visorchannel_create_with_lock(u64 physaddr, - unsigned long channel_bytes, - gfp_t gfp, uuid_le guid); +struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, + const guid_t *guid); +struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, + const guid_t *guid); void visorchannel_destroy(struct visorchannel *channel); int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, ulong nbytes); @@ -64,6 +54,6 @@ char *visorchannel_zoneid(struct visorchannel *channel, char *s); u64 visorchannel_get_clientpartition(struct visorchannel *channel); int visorchannel_set_clientpartition(struct visorchannel *channel, u64 partition_handle); -char *visorchannel_uuid_id(uuid_le *guid, char *s); +char *visorchannel_guid_id(const guid_t *guid, char *s); void *visorchannel_get_header(struct visorchannel *channel); #endif diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index 6885c2cb71359a1be2c581f1bb9cd2383e1e090a..2a000fee3119f23969833ca2c6c3edc0f04fe9fd 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -1,5 +1,4 @@ -/* visorchannel_funcs.c - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -26,13 +25,13 @@ #include "visorbus_private.h" #include "controlvmchannel.h" -#define MYDRVNAME "visorchannel" +#define VISOR_DRV_NAME "visorchannel" #define VISOR_CONSOLEVIDEO_CHANNEL_GUID \ - UUID_LE(0x3cd6e705, 0xd6a2, 0x4aa5, \ - 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) + GUID_INIT(0x3cd6e705, 0xd6a2, 0x4aa5, \ + 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) -static const uuid_le visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; +static const guid_t visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; struct visorchannel { u64 physaddr; @@ -40,18 +39,21 @@ struct visorchannel { void *mapped; bool requested; struct channel_header chan_hdr; - uuid_le guid; - bool needs_lock; /* channel creator knows if more than one */ - /* thread will be inserting or removing */ - spinlock_t insert_lock; /* protect head writes in chan_hdr */ - spinlock_t remove_lock; /* protect tail writes in chan_hdr */ - - uuid_le type; - uuid_le inst; + guid_t guid; + /* + * channel creator knows if more than one + * thread will be inserting or removing + */ + bool needs_lock; + /* protect head writes in chan_hdr */ + spinlock_t insert_lock; + /* protect tail writes in chan_hdr */ + spinlock_t remove_lock; + guid_t type; + guid_t inst; }; -void -visorchannel_destroy(struct visorchannel *channel) +void visorchannel_destroy(struct visorchannel *channel) { if (!channel) return; @@ -63,67 +65,58 @@ visorchannel_destroy(struct visorchannel *channel) kfree(channel); } -u64 -visorchannel_get_physaddr(struct visorchannel *channel) +u64 visorchannel_get_physaddr(struct visorchannel *channel) { return channel->physaddr; } -ulong -visorchannel_get_nbytes(struct visorchannel *channel) +ulong visorchannel_get_nbytes(struct visorchannel *channel) { return channel->nbytes; } -char * -visorchannel_uuid_id(uuid_le *guid, char *s) +char *visorchannel_guid_id(const guid_t *guid, char *s) { sprintf(s, "%pUL", guid); return s; } -char * -visorchannel_id(struct visorchannel *channel, char *s) +char *visorchannel_id(struct visorchannel *channel, char *s) { - return visorchannel_uuid_id(&channel->guid, s); + return visorchannel_guid_id(&channel->guid, s); } -char * -visorchannel_zoneid(struct visorchannel *channel, char *s) +char *visorchannel_zoneid(struct visorchannel *channel, char *s) { - return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s); + return visorchannel_guid_id(&channel->chan_hdr.zone_guid, s); } -u64 -visorchannel_get_clientpartition(struct visorchannel *channel) +u64 visorchannel_get_clientpartition(struct visorchannel *channel) { return channel->chan_hdr.partition_handle; } -int -visorchannel_set_clientpartition(struct visorchannel *channel, - u64 partition_handle) +int visorchannel_set_clientpartition(struct visorchannel *channel, + u64 partition_handle) { channel->chan_hdr.partition_handle = partition_handle; return 0; } /** - * visorchannel_get_uuid() - queries the UUID of the designated channel + * visorchannel_get_guid() - queries the GUID of the designated channel * @channel: the channel to query * - * Return: the UUID of the provided channel + * Return: the GUID of the provided channel */ -uuid_le -visorchannel_get_uuid(struct visorchannel *channel) +const guid_t *visorchannel_get_guid(struct visorchannel *channel) { - return channel->guid; + return &channel->guid; } -EXPORT_SYMBOL_GPL(visorchannel_get_uuid); +EXPORT_SYMBOL_GPL(visorchannel_get_guid); -int -visorchannel_read(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes) +int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, + ulong nbytes) { if (offset + nbytes > channel->nbytes) return -EIO; @@ -133,9 +126,8 @@ visorchannel_read(struct visorchannel *channel, ulong offset, return 0; } -int -visorchannel_write(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes) +int visorchannel_write(struct visorchannel *channel, ulong offset, void *dest, + ulong nbytes) { size_t chdr_size = sizeof(struct channel_header); size_t copy_size; @@ -154,8 +146,7 @@ visorchannel_write(struct visorchannel *channel, ulong offset, return 0; } -void * -visorchannel_get_header(struct visorchannel *channel) +void *visorchannel_get_header(struct visorchannel *channel) { return &channel->chan_hdr; } @@ -164,17 +155,22 @@ visorchannel_get_header(struct visorchannel *channel) * Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a * channel header */ -#define SIG_QUEUE_OFFSET(chan_hdr, q) \ - ((chan_hdr)->ch_space_offset + \ - ((q) * sizeof(struct signal_queue_header))) +static int sig_queue_offset(struct channel_header *chan_hdr, int q) +{ + return ((chan_hdr)->ch_space_offset + + ((q) * sizeof(struct signal_queue_header))); +} /* * Return offset of a specific queue entry (data) from the beginning of a * channel header */ -#define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \ - (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \ - ((slot) * (sig_hdr)->signal_size)) +static int sig_data_offset(struct channel_header *chan_hdr, int q, + struct signal_queue_header *sig_hdr, int slot) +{ + return (sig_queue_offset(chan_hdr, q) + sig_hdr->sig_base_offset + + (slot * sig_hdr->signal_size)); +} /* * Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back @@ -182,48 +178,47 @@ visorchannel_get_header(struct visorchannel *channel) */ #define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \ visorchannel_write(channel, \ - SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) + \ + sig_queue_offset(&channel->chan_hdr, queue) + \ offsetof(struct signal_queue_header, FIELD), \ &((sig_hdr)->FIELD), \ sizeof((sig_hdr)->FIELD)) -static int -sig_read_header(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr) +static int sig_read_header(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr) { if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) return -EINVAL; /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ return visorchannel_read(channel, - SIG_QUEUE_OFFSET(&channel->chan_hdr, queue), + sig_queue_offset(&channel->chan_hdr, queue), sig_hdr, sizeof(struct signal_queue_header)); } -static int -sig_read_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, void *data) +static int sig_read_data(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr, u32 slot, + void *data) { - int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, + int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, sig_hdr, slot); return visorchannel_read(channel, signal_data_offset, data, sig_hdr->signal_size); } -static int -sig_write_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, void *data) +static int sig_write_data(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr, u32 slot, + void *data) { - int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, + int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, sig_hdr, slot); return visorchannel_write(channel, signal_data_offset, data, sig_hdr->signal_size); } -static int -signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) +static int signalremove_inner(struct visorchannel *channel, u32 queue, + void *msg) { struct signal_queue_header sig_hdr; int error; @@ -246,9 +241,9 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, - * update host memory. + * update host memory. Required for channel sync. */ - mb(); /* required for channel synch */ + mb(); error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail); if (error) @@ -269,8 +264,8 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) * * Return: integer error code indicating the status of the removal */ -int -visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) +int visorchannel_signalremove(struct visorchannel *channel, u32 queue, + void *msg) { int rc; unsigned long flags; @@ -287,8 +282,7 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) } EXPORT_SYMBOL_GPL(visorchannel_signalremove); -static bool -queue_empty(struct visorchannel *channel, u32 queue) +static bool queue_empty(struct visorchannel *channel, u32 queue) { struct signal_queue_header sig_hdr; @@ -307,8 +301,7 @@ queue_empty(struct visorchannel *channel, u32 queue) * Return: boolean indicating whether any messages in the designated * channel/queue are present */ -bool -visorchannel_signalempty(struct visorchannel *channel, u32 queue) +bool visorchannel_signalempty(struct visorchannel *channel, u32 queue) { bool rc; unsigned long flags; @@ -324,8 +317,8 @@ visorchannel_signalempty(struct visorchannel *channel, u32 queue) } EXPORT_SYMBOL_GPL(visorchannel_signalempty); -static int -signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) +static int signalinsert_inner(struct visorchannel *channel, u32 queue, + void *msg) { struct signal_queue_header sig_hdr; int err; @@ -351,9 +344,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, - * update host memory. + * update host memory. Required for channel sync. */ - mb(); /* required for channel synch */ + mb(); err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head); if (err) @@ -370,17 +363,8 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) * for a data area in memory, but does NOT modify * this data area * @physaddr: physical address of start of channel - * @channel_bytes: size of the channel in bytes; this may 0 if the channel has - * already been initialized in memory (which is true for all - * channels provided to guest environments by the s-Par - * back-end), in which case the actual channel size will be - * read from the channel header in memory * @gfp: gfp_t to use when allocating memory for the data struct - * @guid: uuid that identifies channel type; this may 0 if the channel - * has already been initialized in memory (which is true for all - * channels provided to guest environments by the s-Par - * back-end), in which case the actual channel guid will be - * read from the channel header in memory + * @guid: GUID that identifies channel type; * @needs_lock: must specify true if you have multiple threads of execution * that will be calling visorchannel methods of this * visorchannel at the same time @@ -388,9 +372,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) * Return: pointer to visorchannel that was created if successful, * otherwise NULL */ -static struct visorchannel * -visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid, bool needs_lock) +static struct visorchannel *visorchannel_create_guts(u64 physaddr, gfp_t gfp, + const guid_t *guid, + bool needs_lock) { struct visorchannel *channel; int err; @@ -414,8 +398,8 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, * this. Remember that we haven't requested it so we don't try to * release later on. */ - channel->requested = request_mem_region(physaddr, size, MYDRVNAME); - if (!channel->requested && uuid_le_cmp(guid, visor_video_guid)) + channel->requested = request_mem_region(physaddr, size, VISOR_DRV_NAME); + if (!channel->requested && !guid_equal(guid, &visor_video_guid)) /* we only care about errors if this is not the video channel */ goto err_destroy_channel; @@ -428,36 +412,29 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, channel->physaddr = physaddr; channel->nbytes = size; - err = visorchannel_read(channel, 0, &channel->chan_hdr, - sizeof(struct channel_header)); + err = visorchannel_read(channel, 0, &channel->chan_hdr, size); if (err) goto err_destroy_channel; - - /* we had better be a CLIENT of this channel */ - if (channel_bytes == 0) - channel_bytes = (ulong)channel->chan_hdr.size; - if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) - guid = channel->chan_hdr.chtype; + size = (ulong)channel->chan_hdr.size; memunmap(channel->mapped); if (channel->requested) release_mem_region(channel->physaddr, channel->nbytes); channel->mapped = NULL; - channel->requested = request_mem_region(channel->physaddr, - channel_bytes, MYDRVNAME); - if (!channel->requested && uuid_le_cmp(guid, visor_video_guid)) + channel->requested = request_mem_region(channel->physaddr, size, + VISOR_DRV_NAME); + if (!channel->requested && !guid_equal(guid, &visor_video_guid)) /* we only care about errors if this is not the video channel */ goto err_destroy_channel; - channel->mapped = memremap(channel->physaddr, channel_bytes, - MEMREMAP_WB); + channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB); if (!channel->mapped) { - release_mem_region(channel->physaddr, channel_bytes); + release_mem_region(channel->physaddr, size); goto err_destroy_channel; } - channel->nbytes = channel_bytes; - channel->guid = guid; + channel->nbytes = size; + guid_copy(&channel->guid, guid); return channel; err_destroy_channel: @@ -465,20 +442,16 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, return NULL; } -struct visorchannel * -visorchannel_create(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid) +struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, + const guid_t *guid) { - return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid, - false); + return visorchannel_create_guts(physaddr, gfp, guid, false); } -struct visorchannel * -visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid) +struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, + const guid_t *guid) { - return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid, - true); + return visorchannel_create_guts(physaddr, gfp, guid, true); } /** @@ -490,8 +463,8 @@ visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes, * * Return: integer error code indicating the status of the insertion */ -int -visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg) +int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, + void *msg) { int rc; unsigned long flags; diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 22150564b4fbe466e4ed642ffd1b8919a37e533b..27ecf6fb49fd940021f6dedc25cf3a5ef849097a 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1,5 +1,4 @@ -/* visorchipset_main.c - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -15,19 +14,18 @@ */ #include -#include -#include -#include -#include -#include -#include #include #include "visorbus.h" #include "visorbus_private.h" -#include "vmcallinterface.h" -#define CURRENT_FILE_PC VISOR_BUS_PC_visorchipset_c +/* {72120008-4AAB-11DC-8530-444553544200} */ +#define VISOR_SIOVM_GUID GUID_INIT(0x72120008, 0x4AAB, 0x11DC, 0x85, 0x30, \ + 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) + +static const guid_t visor_vhba_channel_guid = VISOR_VHBA_CHANNEL_GUID; +static const guid_t visor_siovm_guid = VISOR_SIOVM_GUID; +static const guid_t visor_controlvm_channel_guid = VISOR_CONTROLVM_CHANNEL_GUID; #define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1 #define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100 @@ -42,9 +40,9 @@ #define UNISYS_VISOR_ID_EDX 0x34367261 /* - * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, - * we switch to slow polling mode. As soon as we get a controlvm - * message, we switch back to fast polling mode. + * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, we switch + * to slow polling mode. As soon as we get a controlvm message, we switch back + * to fast polling mode. */ #define MIN_IDLE_SECONDS 10 @@ -54,15 +52,39 @@ struct parser_context { u8 *curr; unsigned long bytes_remaining; bool byte_stream; - char data[0]; + struct visor_controlvm_parameters_header data; }; -struct vmcall_controlvm_addr { - struct vmcall_io_controlvm_addr_params params; - int err; - u64 physaddr; +/* VMCALL_CONTROLVM_ADDR: Used by all guests, not just IO. */ +#define VMCALL_CONTROLVM_ADDR 0x0501 + +enum vmcall_result { + VMCALL_RESULT_SUCCESS = 0, + VMCALL_RESULT_INVALID_PARAM = 1, + VMCALL_RESULT_DATA_UNAVAILABLE = 2, + VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, + VMCALL_RESULT_DEVICE_ERROR = 4, + VMCALL_RESULT_DEVICE_NOT_READY = 5 }; +/* + * struct vmcall_io_controlvm_addr_params - Structure for IO VMCALLS. Has + * parameters to VMCALL_CONTROLVM_ADDR + * interface. + * @address: The Guest-relative physical address of the ControlVm channel. + * This VMCall fills this in with the appropriate address. + * Contents provided by this VMCALL (OUT). + * @channel_bytes: The size of the ControlVm channel in bytes This VMCall fills + * this in with the appropriate address. Contents provided by + * this VMCALL (OUT). + * @unused: Unused Bytes in the 64-Bit Aligned Struct. + */ +struct vmcall_io_controlvm_addr_params { + u64 address; + u32 channel_bytes; + u8 unused[4]; +} __packed; + struct visorchipset_device { struct acpi_device *acpi_device; unsigned long poll_jiffies; @@ -80,7 +102,7 @@ struct visorchipset_device { */ struct controlvm_message controlvm_pending_msg; bool controlvm_pending_msg_valid; - struct vmcall_controlvm_addr controlvm_addr; + struct vmcall_io_controlvm_addr_params controlvm_params; }; static struct visorchipset_device *chipset_dev; @@ -124,7 +146,6 @@ static ssize_t toolaction_store(struct device *dev, offsetof(struct visor_controlvm_channel, tool_action), &tool_action, sizeof(u8)); - if (err) return err; return count; @@ -143,7 +164,6 @@ static ssize_t boottotool_show(struct device *dev, efi_visor_ind), &efi_visor_indication, sizeof(struct efi_visor_indication)); - if (err) return err; return sprintf(buf, "%u\n", efi_visor_indication.boot_to_tool); @@ -165,7 +185,6 @@ static ssize_t boottotool_store(struct device *dev, efi_visor_ind), &(efi_visor_indication), sizeof(struct efi_visor_indication)); - if (err) return err; return count; @@ -184,7 +203,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, &error, sizeof(u32)); if (err) return err; - return sprintf(buf, "%i\n", error); + return sprintf(buf, "%u\n", error); } static ssize_t error_store(struct device *dev, struct device_attribute *attr, @@ -219,7 +238,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, if (err) return err; - return sprintf(buf, "%i\n", text_id); + return sprintf(buf, "%u\n", text_id); } static ssize_t textid_store(struct device *dev, struct device_attribute *attr, @@ -277,67 +296,6 @@ static ssize_t remaining_steps_store(struct device *dev, } static DEVICE_ATTR_RW(remaining_steps); -static uuid_le -parser_id_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr = NULL; - - phdr = (struct visor_controlvm_parameters_header *)(ctx->data); - return phdr->id; -} - -static void parser_done(struct parser_context *ctx) -{ - chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; - kfree(ctx); -} - -static void * -parser_string_get(struct parser_context *ctx) -{ - u8 *pscan; - unsigned long nscan; - int value_length = -1; - void *value = NULL; - int i; - - pscan = ctx->curr; - nscan = ctx->bytes_remaining; - if (nscan == 0) - return NULL; - if (!pscan) - return NULL; - for (i = 0, value_length = -1; i < nscan; i++) - if (pscan[i] == '\0') { - value_length = i; - break; - } - if (value_length < 0) /* '\0' was not included in the length */ - value_length = nscan; - value = kmalloc(value_length + 1, GFP_KERNEL); - if (!value) - return NULL; - if (value_length > 0) - memcpy(value, pscan, value_length); - ((u8 *)(value))[value_length] = '\0'; - return value; -} - -static void * -parser_name_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr = NULL; - - phdr = (struct visor_controlvm_parameters_header *)(ctx->data); - - if (phdr->name_offset + phdr->name_length > ctx->param_bytes) - return NULL; - - ctx->curr = ctx->data + phdr->name_offset; - ctx->bytes_remaining = phdr->name_length; - return parser_string_get(ctx); -} - struct visor_busdev { u32 bus_no; u32 dev_no; @@ -347,11 +305,9 @@ static int match_visorbus_dev_by_id(struct device *dev, void *data) { struct visor_device *vdev = to_visor_device(dev); struct visor_busdev *id = data; - u32 bus_no = id->bus_no; - u32 dev_no = id->dev_no; - if ((vdev->chipset_bus_no == bus_no) && - (vdev->chipset_dev_no == dev_no)) + if ((vdev->chipset_bus_no == id->bus_no) && + (vdev->chipset_dev_no == id->dev_no)) return 1; return 0; @@ -364,9 +320,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, struct device *dev_start = NULL; struct visor_device *vdev = NULL; struct visor_busdev id = { - .bus_no = bus_no, - .dev_no = dev_no - }; + .bus_no = bus_no, + .dev_no = dev_no + }; if (from) dev_start = &from->device; @@ -377,9 +333,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, return vdev; } -static void -controlvm_init_response(struct controlvm_message *msg, - struct controlvm_message_header *msg_hdr, int response) +static void controlvm_init_response(struct controlvm_message *msg, + struct controlvm_message_header *msg_hdr, + int response) { memset(msg, 0, sizeof(struct controlvm_message)); memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header)); @@ -392,10 +348,10 @@ controlvm_init_response(struct controlvm_message *msg, } } -static int -controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, - int response, - enum visor_chipset_feature features) +static int controlvm_respond_chipset_init( + struct controlvm_message_header *msg_hdr, + int response, + enum visor_chipset_feature features) { struct controlvm_message outmsg; @@ -405,8 +361,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, CONTROLVM_QUEUE_REQUEST, &outmsg); } -static int -chipset_init(struct controlvm_message *inmsg) +static int chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; enum visor_chipset_feature features = 0; @@ -421,15 +376,15 @@ chipset_init(struct controlvm_message *inmsg) chipset_inited = 1; /* - * Set features to indicate we support parahotplug (if Command - * also supports it). + * Set features to indicate we support parahotplug (if Command also + * supports it). */ features = inmsg->cmd.init_chipset.features & VISOR_CHIPSET_FEATURE_PARA_HOTPLUG; /* - * Set the "reply" bit so Command knows this is a - * features-aware driver. + * Set the "reply" bit so Command knows this is a features-aware + * driver. */ features |= VISOR_CHIPSET_FEATURE_REPLY; @@ -440,9 +395,9 @@ chipset_init(struct controlvm_message *inmsg) return res; } -static int -controlvm_respond(struct controlvm_message_header *msg_hdr, int response, - struct visor_segment_state *state) +static int controlvm_respond(struct controlvm_message_header *msg_hdr, + int response, + struct visor_segment_state *state) { struct controlvm_message outmsg; @@ -464,8 +419,8 @@ enum crash_obj_type { CRASH_BUS, }; -static int -save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type) +static int save_crash_message(struct controlvm_message *msg, + enum crash_obj_type cr_type) { u32 local_crash_msg_offset; u16 local_crash_msg_count; @@ -529,10 +484,9 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type) return 0; } -static int -controlvm_responder(enum controlvm_id cmd_id, - struct controlvm_message_header *pending_msg_hdr, - int response) +static int controlvm_responder(enum controlvm_id cmd_id, + struct controlvm_message_header *pending_msg_hdr, + int response) { if (!pending_msg_hdr) return -EIO; @@ -543,14 +497,12 @@ controlvm_responder(enum controlvm_id cmd_id, return controlvm_respond(pending_msg_hdr, response, NULL); } -static int -device_changestate_responder(enum controlvm_id cmd_id, - struct visor_device *p, int response, - struct visor_segment_state response_state) +static int device_changestate_responder( + enum controlvm_id cmd_id, + struct visor_device *p, int response, + struct visor_segment_state response_state) { struct controlvm_message outmsg; - u32 bus_no = p->chipset_bus_no; - u32 dev_no = p->chipset_dev_no; if (!p->pending_msg_hdr) return -EIO; @@ -559,16 +511,15 @@ device_changestate_responder(enum controlvm_id cmd_id, controlvm_init_response(&outmsg, p->pending_msg_hdr, response); - outmsg.cmd.device_change_state.bus_no = bus_no; - outmsg.cmd.device_change_state.dev_no = dev_no; + outmsg.cmd.device_change_state.bus_no = p->chipset_bus_no; + outmsg.cmd.device_change_state.dev_no = p->chipset_dev_no; outmsg.cmd.device_change_state.state = response_state; return visorchannel_signalinsert(chipset_dev->controlvm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg); } -static int -visorbus_create(struct controlvm_message *inmsg) +static int visorbus_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -580,7 +531,7 @@ visorbus_create(struct controlvm_message *inmsg) bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (bus_info && (bus_info->state.created == 1)) { dev_err(&chipset_dev->acpi_device->dev, - "failed visorbus_create: already exists\n"); + "failed %s: already exists\n", __func__); err = -EEXIST; goto err_respond; } @@ -595,7 +546,7 @@ visorbus_create(struct controlvm_message *inmsg) bus_info->chipset_bus_no = bus_no; bus_info->chipset_dev_no = BUS_ROOT_DEVICE; - if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, visor_siovm_uuid) == 0) { + if (guid_equal(&cmd->create_bus.bus_inst_guid, &visor_siovm_guid)) { err = save_crash_message(inmsg, CRASH_BUS); if (err) goto err_free_bus_info; @@ -615,19 +566,17 @@ visorbus_create(struct controlvm_message *inmsg) } visorchannel = visorchannel_create(cmd->create_bus.channel_addr, - cmd->create_bus.channel_bytes, GFP_KERNEL, - cmd->create_bus.bus_data_type_uuid); - + &cmd->create_bus.bus_data_type_guid); if (!visorchannel) { err = -ENOMEM; goto err_free_pending_msg; } + bus_info->visorchannel = visorchannel; - /* Response will be handled by visorchipset_bus_create */ - err = visorchipset_bus_create(bus_info); - /* If visorchipset_bus_create didn't respond, need to respond here */ + /* Response will be handled by visorbus_create_instance on success */ + err = visorbus_create_instance(bus_info); if (err) goto err_destroy_channel; @@ -648,8 +597,7 @@ visorbus_create(struct controlvm_message *inmsg) return err; } -static int -visorbus_destroy(struct controlvm_message *inmsg) +static int visorbus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -683,8 +631,8 @@ visorbus_destroy(struct controlvm_message *inmsg) bus_info->pending_msg_hdr = pmsg_hdr; } - /* Response will be handled by visorchipset_bus_destroy */ - visorchipset_bus_destroy(bus_info); + /* Response will be handled by visorbus_remove_instance */ + visorbus_remove_instance(bus_info); return 0; err_respond: @@ -693,9 +641,60 @@ visorbus_destroy(struct controlvm_message *inmsg) return err; } -static int -visorbus_configure(struct controlvm_message *inmsg, - struct parser_context *parser_ctx) +static const guid_t *parser_id_get(struct parser_context *ctx) +{ + return &ctx->data.id; +} + +static void *parser_string_get(struct parser_context *ctx) +{ + u8 *pscan; + unsigned long nscan; + int value_length; + void *value; + int i; + + pscan = ctx->curr; + if (!pscan) + return NULL; + nscan = ctx->bytes_remaining; + if (nscan == 0) + return NULL; + + for (i = 0, value_length = -1; i < nscan; i++) + if (pscan[i] == '\0') { + value_length = i; + break; + } + /* '\0' was not included in the length */ + if (value_length < 0) + value_length = nscan; + + value = kmalloc(value_length + 1, GFP_KERNEL); + if (!value) + return NULL; + if (value_length > 0) + memcpy(value, pscan, value_length); + ((u8 *)(value))[value_length] = '\0'; + return value; +} + +static void *parser_name_get(struct parser_context *ctx) +{ + struct visor_controlvm_parameters_header *phdr = NULL; + + phdr = &ctx->data; + + if (phdr->name_offset + phdr->name_length > ctx->param_bytes) + return NULL; + + ctx->curr = (char *)&phdr + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; + return parser_string_get(ctx); +} + +static int visorbus_configure(struct controlvm_message *inmsg, + struct parser_context *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no; @@ -707,10 +706,12 @@ visorbus_configure(struct controlvm_message *inmsg, if (!bus_info) { err = -EINVAL; goto err_respond; - } else if (bus_info->state.created == 0) { + } + if (bus_info->state.created == 0) { err = -EINVAL; goto err_respond; - } else if (bus_info->pending_msg_hdr) { + } + if (bus_info->pending_msg_hdr) { err = -EIO; goto err_respond; } @@ -722,7 +723,9 @@ visorbus_configure(struct controlvm_message *inmsg, goto err_respond; if (parser_ctx) { - bus_info->partition_uuid = parser_id_get(parser_ctx); + const guid_t *partition_guid = parser_id_get(parser_ctx); + + guid_copy(&bus_info->partition_guid, partition_guid); bus_info->name = parser_name_get(parser_ctx); } @@ -732,14 +735,13 @@ visorbus_configure(struct controlvm_message *inmsg, err_respond: dev_err(&chipset_dev->acpi_device->dev, - "visorbus_configure exited with err: %d\n", err); + "%s exited with err: %d\n", __func__, err); if (inmsg->hdr.flags.response_expected == 1) controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); return err; } -static int -visorbus_device_create(struct controlvm_message *inmsg) +static int visorbus_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -757,7 +759,6 @@ visorbus_device_create(struct controlvm_message *inmsg) err = -ENODEV; goto err_respond; } - if (bus_info->state.created == 0) { dev_err(&chipset_dev->acpi_device->dev, "bus not created, id: %d\n", bus_no); @@ -781,17 +782,13 @@ visorbus_device_create(struct controlvm_message *inmsg) dev_info->chipset_bus_no = bus_no; dev_info->chipset_dev_no = dev_no; - dev_info->inst = cmd->create_device.dev_inst_uuid; - - /* not sure where the best place to set the 'parent' */ + guid_copy(&dev_info->inst, &cmd->create_device.dev_inst_guid); dev_info->device.parent = &bus_info->device; visorchannel = visorchannel_create_with_lock(cmd->create_device.channel_addr, - cmd->create_device.channel_bytes, GFP_KERNEL, - cmd->create_device.data_type_uuid); - + &cmd->create_device.data_type_guid); if (!visorchannel) { dev_err(&chipset_dev->acpi_device->dev, "failed to create visorchannel: %d/%d\n", @@ -800,9 +797,8 @@ visorbus_device_create(struct controlvm_message *inmsg) goto err_free_dev_info; } dev_info->visorchannel = visorchannel; - dev_info->channel_type_guid = cmd->create_device.data_type_uuid; - if (uuid_le_cmp(cmd->create_device.data_type_uuid, - visor_vhba_channel_uuid) == 0) { + guid_copy(&dev_info->channel_type_guid, &cmd->create_device.data_type_guid); + if (guid_equal(&cmd->create_device.data_type_guid, &visor_vhba_channel_guid)) { err = save_crash_message(inmsg, CRASH_DEV); if (err) goto err_destroy_visorchannel; @@ -819,8 +815,8 @@ visorbus_device_create(struct controlvm_message *inmsg) sizeof(struct controlvm_message_header)); dev_info->pending_msg_hdr = pmsg_hdr; } - /* visorchipset_device_create will send response */ - err = visorchipset_device_create(dev_info); + /* create_visor_device will send response */ + err = create_visor_device(dev_info); if (err) goto err_destroy_visorchannel; @@ -838,8 +834,7 @@ visorbus_device_create(struct controlvm_message *inmsg) return err; } -static int -visorbus_device_changestate(struct controlvm_message *inmsg) +static int visorbus_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -899,8 +894,7 @@ visorbus_device_changestate(struct controlvm_message *inmsg) return err; } -static int -visorbus_device_destroy(struct controlvm_message *inmsg) +static int visorbus_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -918,7 +912,6 @@ visorbus_device_destroy(struct controlvm_message *inmsg) err = -EINVAL; goto err_respond; } - if (dev_info->pending_msg_hdr) { /* only non-NULL if dev is still waiting on a response */ err = -EIO; @@ -936,7 +929,8 @@ visorbus_device_destroy(struct controlvm_message *inmsg) dev_info->pending_msg_hdr = pmsg_hdr; } - visorchipset_device_destroy(dev_info); + kfree(dev_info->name); + remove_visor_device(dev_info); return 0; err_respond: @@ -954,8 +948,7 @@ visorbus_device_destroy(struct controlvm_message *inmsg) * disable the specified device. The udev script then writes to * /sys/devices/platform/visorchipset/parahotplug, which causes the * parahotplug store functions to get called, at which point the - * appropriate CONTROLVM message is retrieved from the list and responded - * to. + * appropriate CONTROLVM message is retrieved from the list and responded to. */ #define PARAHOTPLUG_TIMEOUT_MS 2000 @@ -967,8 +960,7 @@ visorbus_device_destroy(struct controlvm_message *inmsg) * * Return: a unique integer value */ -static int -parahotplug_next_id(void) +static int parahotplug_next_id(void) { static atomic_t id = ATOMIC_INIT(0); @@ -982,8 +974,7 @@ parahotplug_next_id(void) * * Return: expected expiration time (in jiffies) */ -static unsigned long -parahotplug_next_expiration(void) +static unsigned long parahotplug_next_expiration(void) { return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS); } @@ -996,8 +987,8 @@ parahotplug_next_expiration(void) * * Return: the request containing the provided message */ -static struct parahotplug_request * -parahotplug_request_create(struct controlvm_message *msg) +static struct parahotplug_request *parahotplug_request_create( + struct controlvm_message *msg) { struct parahotplug_request *req; @@ -1016,14 +1007,14 @@ parahotplug_request_create(struct controlvm_message *msg) * parahotplug_request_destroy() - free a parahotplug_request * @req: the request to deallocate */ -static void -parahotplug_request_destroy(struct parahotplug_request *req) +static void parahotplug_request_destroy(struct parahotplug_request *req) { kfree(req); } static LIST_HEAD(parahotplug_request_list); -static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ +/* lock for above */ +static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* * parahotplug_request_complete() - mark request as complete @@ -1036,8 +1027,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ * * Return: 0 on success or -EINVAL on failure */ -static int -parahotplug_request_complete(int id, u16 active) +static int parahotplug_request_complete(int id, u16 active) { struct list_head *pos; struct list_head *tmp; @@ -1146,7 +1136,7 @@ static struct attribute *visorchipset_parahotplug_attrs[] = { NULL }; -static struct attribute_group visorchipset_parahotplug_group = { +static const struct attribute_group visorchipset_parahotplug_group = { .name = "parahotplug", .attrs = visorchipset_parahotplug_attrs }; @@ -1164,8 +1154,7 @@ static const struct attribute_group *visorchipset_dev_groups[] = { * Cause uevent to run the user level script to do the disable/enable specified * in the parahotplug_request. */ -static int -parahotplug_request_kickoff(struct parahotplug_request *req) +static int parahotplug_request_kickoff(struct parahotplug_request *req) { struct controlvm_message_packet *cmd = &req->msg.cmd; char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40], @@ -1194,14 +1183,12 @@ parahotplug_request_kickoff(struct parahotplug_request *req) * off a udev script * @inmsg: the message indicating whether to enable or disable */ -static int -parahotplug_process_message(struct controlvm_message *inmsg) +static int parahotplug_process_message(struct controlvm_message *inmsg) { struct parahotplug_request *req; int err; req = parahotplug_request_create(inmsg); - if (!req) return -ENOMEM; @@ -1220,10 +1207,9 @@ parahotplug_process_message(struct controlvm_message *inmsg) } /* - * For disable messages, add the request to the - * request list before kicking off the udev script. It - * won't get responded to until the script has - * indicated it's done. + * For disable messages, add the request to the request list before + * kicking off the udev script. It won't get responded to until the + * script has indicated it's done. */ spin_lock(¶hotplug_request_list_lock); list_add_tail(&req->list, ¶hotplug_request_list); @@ -1247,8 +1233,7 @@ parahotplug_process_message(struct controlvm_message *inmsg) * * Return: 0 on success, negative on failure */ -static int -chipset_ready_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_ready_uevent(struct controlvm_message_header *msg_hdr) { int res; @@ -1268,8 +1253,7 @@ chipset_ready_uevent(struct controlvm_message_header *msg_hdr) * * Return: 0 on success, negative on failure */ -static int -chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) { char env_selftest[20]; char *envp[] = { env_selftest, NULL }; @@ -1292,13 +1276,11 @@ chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) * * Return: 0 on success, negative on failure */ -static int -chipset_notready_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_notready_uevent(struct controlvm_message_header *msg_hdr) { - int res; - - res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, + int res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, KOBJ_OFFLINE); + if (msg_hdr->flags.response_expected) controlvm_respond(msg_hdr, res, NULL); @@ -1321,13 +1303,12 @@ static int unisys_vmcall(unsigned long tuple, unsigned long param) __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : "a"(tuple), "b"(reg_ebx), "c"(reg_ecx)); - if (result) goto error; return 0; - -error: /* Need to convert from VMCALL error codes to Linux */ +/* Need to convert from VMCALL error codes to Linux */ +error: switch (result) { case VMCALL_RESULT_INVALID_PARAM: return -EINVAL; @@ -1337,35 +1318,27 @@ static int unisys_vmcall(unsigned long tuple, unsigned long param) return -EFAULT; } } -static unsigned int -issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) -{ - chipset_dev->controlvm_addr.physaddr = virt_to_phys( - &chipset_dev->controlvm_addr.params); - chipset_dev->controlvm_addr.err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, - chipset_dev->controlvm_addr.physaddr); - if (chipset_dev->controlvm_addr.err) - return chipset_dev->controlvm_addr.err; - - *control_addr = chipset_dev->controlvm_addr.params.address; - *control_bytes = chipset_dev->controlvm_addr.params.channel_bytes; - - return 0; -} -static u64 controlvm_get_channel_address(void) +static int controlvm_channel_create(struct visorchipset_device *dev) { - u64 addr = 0; - u32 size = 0; - - if (issue_vmcall_io_controlvm_addr(&addr, &size)) - return 0; + struct visorchannel *chan; + u64 addr; + int err; - return addr; + err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, + virt_to_phys(&dev->controlvm_params)); + if (err) + return err; + addr = dev->controlvm_params.address; + chan = visorchannel_create_with_lock(addr, GFP_KERNEL, + &visor_controlvm_channel_guid); + if (!chan) + return -ENOMEM; + dev->controlvm_channel = chan; + return 0; } -static void -setup_crash_devices_work_queue(struct work_struct *work) +static void setup_crash_devices_work_queue(struct work_struct *work) { struct controlvm_message local_crash_bus_msg; struct controlvm_message local_crash_dev_msg; @@ -1444,87 +1417,44 @@ setup_crash_devices_work_queue(struct work_struct *work) visorbus_device_create(&local_crash_dev_msg); } -void -visorbus_create_response(struct visor_device *bus_info, int response) +void visorbus_response(struct visor_device *bus_info, int response, + int controlvm_id) { - if (response >= 0) - bus_info->state.created = 1; - - controlvm_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr, - response); + controlvm_responder(controlvm_id, bus_info->pending_msg_hdr, response); kfree(bus_info->pending_msg_hdr); bus_info->pending_msg_hdr = NULL; } -void -visorbus_destroy_response(struct visor_device *bus_info, int response) -{ - controlvm_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr, - response); - - kfree(bus_info->pending_msg_hdr); - bus_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_create_response(struct visor_device *dev_info, int response) -{ - if (response >= 0) - dev_info->state.created = 1; - - controlvm_responder(CONTROLVM_DEVICE_CREATE, dev_info->pending_msg_hdr, - response); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_destroy_response(struct visor_device *dev_info, int response) -{ - controlvm_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr, - response); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_pause_response(struct visor_device *dev_info, int response) +void visorbus_device_changestate_response(struct visor_device *dev_info, + int response, + struct visor_segment_state state) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - dev_info, response, - segment_state_standby); + dev_info, response, state); kfree(dev_info->pending_msg_hdr); dev_info->pending_msg_hdr = NULL; } -void -visorbus_device_resume_response(struct visor_device *dev_info, int response) +static void parser_done(struct parser_context *ctx) { - device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - dev_info, response, - segment_state_running); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; + chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; + kfree(ctx); } -static struct parser_context * -parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) +static struct parser_context *parser_init_stream(u64 addr, u32 bytes, + bool *retry) { - int allocbytes = sizeof(struct parser_context) + bytes; + int allocbytes; struct parser_context *ctx; + void *mapping; *retry = false; - /* - * alloc an 0 extra byte to ensure payload is - * '\0'-terminated - */ - allocbytes++; + /* alloc an extra byte to ensure payload is \0 terminated */ + allocbytes = bytes + 1 + (sizeof(struct parser_context) - + sizeof(struct visor_controlvm_parameters_header)); if ((chipset_dev->controlvm_payload_bytes_buffered + bytes) > MAX_CONTROLVM_PAYLOAD_BYTES) { *retry = true; @@ -1538,32 +1468,18 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) ctx->allocbytes = allocbytes; ctx->param_bytes = bytes; - ctx->curr = NULL; - ctx->bytes_remaining = 0; - ctx->byte_stream = false; - if (local) { - void *p; - - if (addr > virt_to_phys(high_memory - 1)) - goto err_finish_ctx; - p = __va((unsigned long)(addr)); - memcpy(ctx->data, p, bytes); - } else { - void *mapping = memremap(addr, bytes, MEMREMAP_WB); - - if (!mapping) - goto err_finish_ctx; - memcpy(ctx->data, mapping, bytes); - memunmap(mapping); - } - + mapping = memremap(addr, bytes, MEMREMAP_WB); + if (!mapping) + goto err_finish_ctx; + memcpy(&ctx->data, mapping, bytes); + memunmap(mapping); ctx->byte_stream = true; chipset_dev->controlvm_payload_bytes_buffered += ctx->param_bytes; return ctx; err_finish_ctx: - parser_done(ctx); + kfree(ctx); return NULL; } @@ -1580,19 +1496,16 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) * which to copy out controlvm payload data. * < 0 - error: ControlVM message was processed but an error occurred. */ -static int -handle_command(struct controlvm_message inmsg, u64 channel_addr) +static int handle_command(struct controlvm_message inmsg, u64 channel_addr) { struct controlvm_message_packet *cmd = &inmsg.cmd; u64 parm_addr; u32 parm_bytes; struct parser_context *parser_ctx = NULL; - bool local_addr; struct controlvm_message ackmsg; int err = 0; /* create parsing context if necessary */ - local_addr = (inmsg.hdr.flags.test_message == 1); parm_addr = channel_addr + inmsg.hdr.payload_vm_offset; parm_bytes = inmsg.hdr.payload_bytes; @@ -1601,25 +1514,19 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) * within our OS-controlled memory. We need to know that, because it * makes a difference in how we compute the virtual address. */ - if (parm_addr && parm_bytes) { + if (parm_bytes) { bool retry = false; - parser_ctx = - parser_init_byte_stream(parm_addr, parm_bytes, - local_addr, &retry); + parser_ctx = parser_init_stream(parm_addr, parm_bytes, &retry); if (!parser_ctx && retry) return -EAGAIN; } + controlvm_init_response(&ackmsg, &inmsg.hdr, CONTROLVM_RESP_SUCCESS); + err = visorchannel_signalinsert(chipset_dev->controlvm_channel, + CONTROLVM_QUEUE_ACK, &ackmsg); + if (err) + return err; - if (!local_addr) { - controlvm_init_response(&ackmsg, &inmsg.hdr, - CONTROLVM_RESP_SUCCESS); - err = visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_ACK, - &ackmsg); - if (err) - return err; - } switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: err = chipset_init(&inmsg); @@ -1641,8 +1548,8 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) err = parahotplug_process_message(&inmsg); } else { /* - * save the hdr and cmd structures for later use - * when sending back the response to Command + * save the hdr and cmd structures for later use when + * sending back the response to Command */ err = visorbus_device_changestate(&inmsg); break; @@ -1689,12 +1596,9 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) * * Return: 0 if valid message was retrieved or -error */ -static int -read_controlvm_event(struct controlvm_message *msg) +static int read_controlvm_event(struct controlvm_message *msg) { - int err; - - err = visorchannel_signalremove(chipset_dev->controlvm_channel, + int err = visorchannel_signalremove(chipset_dev->controlvm_channel, CONTROLVM_QUEUE_EVENT, msg); if (err) return err; @@ -1710,8 +1614,7 @@ read_controlvm_event(struct controlvm_message *msg) * parahotplug_process_list() - remove any request from the list that's been on * there too long and respond with an error */ -static void -parahotplug_process_list(void) +static void parahotplug_process_list(void) { struct list_head *pos; struct list_head *tmp; @@ -1737,8 +1640,7 @@ parahotplug_process_list(void) spin_unlock(¶hotplug_request_list_lock); } -static void -controlvm_periodic_work(struct work_struct *work) +static void controlvm_periodic_work(struct work_struct *work) { struct controlvm_message inmsg; int count = 0; @@ -1756,9 +1658,8 @@ controlvm_periodic_work(struct work_struct *work) if (chipset_dev->controlvm_pending_msg_valid) { /* - * we throttled processing of a prior - * msg, so try to process it again - * rather than reading a new one + * we throttled processing of a prior msg, so try to process + * it again rather than reading a new one */ inmsg = chipset_dev->controlvm_pending_msg; chipset_dev->controlvm_pending_msg_valid = false; @@ -1793,9 +1694,8 @@ controlvm_periodic_work(struct work_struct *work) if (time_after(jiffies, chipset_dev->most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) { /* - * it's been longer than MIN_IDLE_SECONDS since we - * processed our last controlvm message; slow down the - * polling + * it's been longer than MIN_IDLE_SECONDS since we processed + * our last controlvm message; slow down the polling */ if (chipset_dev->poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW) @@ -1812,41 +1712,36 @@ controlvm_periodic_work(struct work_struct *work) chipset_dev->poll_jiffies); } -static int -visorchipset_init(struct acpi_device *acpi_device) +static int visorchipset_init(struct acpi_device *acpi_device) { int err = -ENODEV; - u64 addr; - uuid_le uuid = VISOR_CONTROLVM_CHANNEL_UUID; struct visorchannel *controlvm_channel; chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL); if (!chipset_dev) goto error; - addr = controlvm_get_channel_address(); - if (!addr) - goto error; + err = controlvm_channel_create(chipset_dev); + if (err) + goto error_free_chipset_dev; acpi_device->driver_data = chipset_dev; - chipset_dev->acpi_device = acpi_device; chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; - controlvm_channel = visorchannel_create_with_lock(addr, - 0, GFP_KERNEL, uuid); - - if (!controlvm_channel) - goto error_free_chipset_dev; - - chipset_dev->controlvm_channel = controlvm_channel; err = sysfs_create_groups(&chipset_dev->acpi_device->dev.kobj, visorchipset_dev_groups); if (err < 0) goto error_destroy_channel; - if (!VISOR_CONTROLVM_CHANNEL_OK_CLIENT( - visorchannel_get_header(controlvm_channel))) + controlvm_channel = chipset_dev->controlvm_channel; + if (!visor_check_channel(visorchannel_get_header(controlvm_channel), + &chipset_dev->acpi_device->dev, + &visor_controlvm_channel_guid, + "controlvm", + sizeof(struct visor_controlvm_channel), + VISOR_CONTROLVM_CHANNEL_VERSIONID, + VISOR_CHANNEL_SIGNATURE)) goto error_delete_groups; /* if booting in a crash kernel */ @@ -1886,8 +1781,7 @@ visorchipset_init(struct acpi_device *acpi_device) return err; } -static int -visorchipset_exit(struct acpi_device *acpi_device) +static int visorchipset_exit(struct acpi_device *acpi_device) { visorbus_exit(); cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work); @@ -1928,12 +1822,11 @@ static __init int visorutil_spar_detect(void) return (ebx == UNISYS_VISOR_ID_EBX) && (ecx == UNISYS_VISOR_ID_ECX) && (edx == UNISYS_VISOR_ID_EDX); - } else { - return 0; } + return 0; } -static int init_unisys(void) +static int __init init_unisys(void) { int result; @@ -1948,7 +1841,7 @@ static int init_unisys(void) return 0; }; -static void exit_unisys(void) +static void __exit exit_unisys(void) { acpi_bus_unregister_driver(&unisys_acpi_driver); } diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h deleted file mode 100644 index cc70e1b16bda37e3fe754c93d2bdce19cf08650c..0000000000000000000000000000000000000000 --- a/drivers/staging/unisys/visorbus/vmcallinterface.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VMCALLINTERFACE_H__ -#define __VMCALLINTERFACE_H__ - -enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ - /* Note: when a new VMCALL is added: - * - the 1st 2 hex digits correspond to one of the - * VMCALL_MONITOR_INTERFACE types and - * - the next 2 hex digits are the nth relative instance of within a - * type - * E.G. for VMCALL_VIRTPART_RECYCLE_PART, - * - the 0x02 identifies it as a VMCALL_VIRTPART type and - * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART - * type of VMCALL - */ - /* used by all Guests, not just IO */ - VMCALL_CONTROLVM_ADDR = 0x0501, -}; - -enum vmcall_result { - VMCALL_RESULT_SUCCESS = 0, - VMCALL_RESULT_INVALID_PARAM = 1, - VMCALL_RESULT_DATA_UNAVAILABLE = 2, - VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, - VMCALL_RESULT_DEVICE_ERROR = 4, - VMCALL_RESULT_DEVICE_NOT_READY = 5 -}; - -/* Structures for IO VMCALLs */ -/* Parameters to VMCALL_CONTROLVM_ADDR interface */ -struct vmcall_io_controlvm_addr_params { - /* The Guest-relative physical address of the ControlVm channel. */ - /* This VMCall fills this in with the appropriate address. */ - u64 address; /* contents provided by this VMCALL (OUT) */ - /* the size of the ControlVm channel in bytes This VMCall fills this */ - /* in with the appropriate address. */ - u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ - u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ -} __packed; - -#endif /* __VMCALLINTERFACE_H__ */ diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index a6e7a6bbc428b740d01b5798a43b194f0e74341a..419dba89af065b431d7923cbad0de4c309262efa 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2012 - 2015 UNISYS CORPORATION +/* + * Copyright (c) 2012 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -14,7 +15,6 @@ */ #include -#include #include #include #include @@ -39,16 +39,16 @@ static struct visor_channeltype_descriptor visorhba_channel_types[] = { /* Note that the only channel type we expect to be reported by the * bus driver is the VISOR_VHBA channel. */ - { VISOR_VHBA_CHANNEL_UUID, "sparvhba" }, - { NULL_UUID_LE, NULL } + { VISOR_VHBA_CHANNEL_GUID, "sparvhba" }, + {} }; MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types); -MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_GUID_STR); struct visordisk_info { + struct scsi_device *sdev; u32 valid; - u32 channel, id, lun; /* Disk Path */ atomic_t ios_threshold; atomic_t error_count; struct visordisk_info *next; @@ -56,8 +56,10 @@ struct visordisk_info { struct scsipending { struct uiscmdrsp cmdrsp; - void *sent; /* The Data being tracked */ - char cmdtype; /* Type of pointer that is being stored */ + /* The Data being tracked */ + void *sent; + /* Type of pointer that is being stored */ + char cmdtype; }; /* Each scsi_host has a host_data area that contains this struct. */ @@ -71,7 +73,8 @@ struct visorhba_devdata { struct scsipending pending[MAX_PENDING_REQUESTS]; /* Start search for next pending free slot here */ unsigned int nextinsert; - spinlock_t privlock; /* lock to protect data in devdata */ + /* lock to protect data in devdata */ + spinlock_t privlock; bool serverdown; bool serverchangingstate; unsigned long long acquire_failed_cnt; @@ -101,25 +104,19 @@ struct visorhba_devices_open { struct visorhba_devdata *devdata; }; -#define for_each_vdisk_match(iter, list, match) \ - for (iter = &list->head; iter->next; iter = iter->next) \ - if ((iter->channel == match->channel) && \ - (iter->id == match->id) && \ - (iter->lun == match->lun)) - /* - * visor_thread_start - starts a thread for the device - * @threadfn: Function the thread starts - * @thrcontext: Context to pass to the thread, i.e. devdata - * @name: string describing name of thread + * visor_thread_start - Starts a thread for the device + * @threadfn: Function the thread starts + * @thrcontext: Context to pass to the thread, i.e. devdata + * @name: String describing name of thread * - * Starts a thread for the device. + * Starts a thread for the device. * - * Return the task_struct * denoting the thread on success, - * or NULL on failure + * Return: The task_struct * denoting the thread on success, + * or NULL on failure */ -static struct task_struct *visor_thread_start -(int (*threadfn)(void *), void *thrcontext, char *name) +static struct task_struct *visor_thread_start(int (*threadfn)(void *), + void *thrcontext, char *name) { struct task_struct *task; @@ -132,27 +129,27 @@ static struct task_struct *visor_thread_start } /* - * visor_thread_stop - stops the thread if it is running + * visor_thread_stop - Stops the thread if it is running + * @task: Description of process to stop */ static void visor_thread_stop(struct task_struct *task) { - if (!task) - return; /* no thread running */ kthread_stop(task); } /* - * add_scsipending_entry - save off io command that is pending in - * Service Partition - * @devdata: Pointer to devdata - * @cmdtype: Specifies the type of command pending - * @new: The command to be saved + * add_scsipending_entry - Save off io command that is pending in + * Service Partition + * @devdata: Pointer to devdata + * @cmdtype: Specifies the type of command pending + * @new: The command to be saved * - * Saves off the io command that is being handled by the Service - * Partition so that it can be handled when it completes. If new is - * NULL it is assumed the entry refers only to the cmdrsp. - * Returns insert_location where entry was added, - * -EBUSY if it can't + * Saves off the io command that is being handled by the Service + * Partition so that it can be handled when it completes. If new is + * NULL it is assumed the entry refers only to the cmdrsp. + * + * Return: Insert_location where entry was added on success, + * -EBUSY if it can't */ static int add_scsipending_entry(struct visorhba_devdata *devdata, char cmdtype, void *new) @@ -176,7 +173,8 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata, entry->cmdtype = cmdtype; if (new) entry->sent = new; - else /* wants to send cmdrsp */ + /* wants to send cmdrsp */ + else entry->sent = &entry->cmdrsp; devdata->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS; spin_unlock_irqrestore(&devdata->privlock, flags); @@ -185,15 +183,15 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata, } /* - * del_scsipending_ent - removes an entry from the pending array - * @devdata: Device holding the pending array - * @del: Entry to remove + * del_scsipending_ent - Removes an entry from the pending array + * @devdata: Device holding the pending array + * @del: Entry to remove * - * Removes the entry pointed at by del and returns it. - * Returns the scsipending entry pointed at + * Removes the entry pointed at by del and returns it. + * + * Return: The scsipending entry pointed to on success, NULL on failure */ -static void *del_scsipending_ent(struct visorhba_devdata *devdata, - int del) +static void *del_scsipending_ent(struct visorhba_devdata *devdata, int del) { unsigned long flags; void *sent; @@ -203,7 +201,6 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata, spin_lock_irqsave(&devdata->privlock, flags); sent = devdata->pending[del].sent; - devdata->pending[del].cmdtype = 0; devdata->pending[del].sent = NULL; spin_unlock_irqrestore(&devdata->privlock, flags); @@ -212,13 +209,14 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata, } /* - * get_scsipending_cmdrsp - return the cmdrsp stored in a pending entry - * @ddata: Device holding the pending array - * @ent: Entry that stores the cmdrsp + * get_scsipending_cmdrsp - Return the cmdrsp stored in a pending entry + * @ddata: Device holding the pending array + * @ent: Entry that stores the cmdrsp * - * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid - * if the "sent" field is not NULL - * Returns a pointer to the cmdrsp. + * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid + * if the "sent" field is not NULL. + * + * Return: A pointer to the cmdrsp, NULL on failure */ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, int ent) @@ -230,13 +228,15 @@ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, } /* - * simple_idr_get - associate a provided pointer with an int value - * 1 <= value <= INT_MAX, and return this int value; - * the pointer value can be obtained later by passing - * this int value to idr_find() - * @idrtable: the data object maintaining the pointer<-->int mappings - * @p: the pointer value to be remembered - * @lock: a spinlock used when exclusive access to idrtable is needed + * simple_idr_get - Associate a provided pointer with an int value + * 1 <= value <= INT_MAX, and return this int value; + * the pointer value can be obtained later by passing + * this int value to idr_find() + * @idrtable: The data object maintaining the pointer<-->int mappings + * @p: The pointer value to be remembered + * @lock: A spinlock used when exclusive access to idrtable is needed + * + * Return: The id number mapped to pointer 'p', 0 on failure */ static unsigned int simple_idr_get(struct idr *idrtable, void *p, spinlock_t *lock) @@ -249,16 +249,23 @@ static unsigned int simple_idr_get(struct idr *idrtable, void *p, id = idr_alloc(idrtable, p, 1, INT_MAX, GFP_NOWAIT); spin_unlock_irqrestore(lock, flags); idr_preload_end(); + /* failure */ if (id < 0) - return 0; /* failure */ - return (unsigned int)(id); /* idr_alloc() guarantees > 0 */ + return 0; + /* idr_alloc() guarantees > 0 */ + return (unsigned int)(id); } /* - * setup_scsitaskmgmt_handles - stash the necessary handles so that the - * completion processing logic for a taskmgmt - * cmd will be able to find who to wake up - * and where to stash the result + * setup_scsitaskmgmt_handles - Stash the necessary handles so that the + * completion processing logic for a taskmgmt + * cmd will be able to find who to wake up + * and where to stash the result + * @idrtable: The data object maintaining the pointer<-->int mappings + * @lock: A spinlock used when exclusive access to idrtable is needed + * @cmdrsp: Response from the IOVM + * @event: The event handle to associate with an id + * @result: The location to place the result of the event handle into */ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, struct uiscmdrsp *cmdrsp, @@ -273,8 +280,10 @@ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, } /* - * cleanup_scsitaskmgmt_handles - forget handles created by - * setup_scsitaskmgmt_handles() + * cleanup_scsitaskmgmt_handles - Forget handles created by + * setup_scsitaskmgmt_handles() + * @idrtable: The data object maintaining the pointer<-->int mappings + * @cmdrsp: Response from the IOVM */ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, struct uiscmdrsp *cmdrsp) @@ -286,20 +295,20 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, } /* - * forward_taskmgmt_command - send taskmegmt command to the Service - * Partition - * @tasktype: Type of taskmgmt command - * @scsidev: Scsidev that issued command + * forward_taskmgmt_command - Send taskmegmt command to the Service + * Partition + * @tasktype: Type of taskmgmt command + * @scsidev: Scsidev that issued command * - * Create a cmdrsp packet and send it to the Serivce Partition - * that will service this request. - * Returns whether the command was queued successfully or not. + * Create a cmdrsp packet and send it to the Serivce Partition + * that will service this request. + * + * Return: Int representing whether command was queued successfully or not */ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, - struct scsi_cmnd *scsicmd) + struct scsi_device *scsidev) { struct uiscmdrsp *cmdrsp; - struct scsi_device *scsidev = scsicmd->device; struct visorhba_devdata *devdata = (struct visorhba_devdata *)scsidev->host->hostdata; int notifyresult = 0xffff; @@ -347,12 +356,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, dev_dbg(&scsidev->sdev_gendev, "visorhba: taskmgmt type=%d success; result=0x%x\n", tasktype, notifyresult); - if (tasktype == TASK_MGMT_ABORT_TASK) - scsicmd->result = DID_ABORT << 16; - else - scsicmd->result = DID_RESET << 16; - - scsicmd->scsi_done(scsicmd); cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp); return SUCCESS; @@ -365,97 +368,105 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, } /* - * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK - * @scsicmd: The scsicmd that needs aborted - * - * Returns SUCCESS if inserted, failure otherwise + * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK + * @scsicmd: The scsicmd that needs aborted * + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_ABORT_TASK */ struct scsi_device *scsidev; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; + int rtn; scsidev = scsicmd->device; - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) - atomic_inc(&vdisk->error_count); - else - atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) + atomic_inc(&vdisk->error_count); + else + atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev); + if (rtn == SUCCESS) { + scsicmd->result = DID_ABORT << 16; + scsicmd->scsi_done(scsicmd); } - return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd); + return rtn; } /* - * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET - * @scsicmd: The scsicmd that needs aborted + * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET + * @scsicmd: The scsicmd that needs aborted * - * Returns SUCCESS if inserted, failure otherwise + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_LUN_RESET */ struct scsi_device *scsidev; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; + int rtn; scsidev = scsicmd->device; - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) - atomic_inc(&vdisk->error_count); - else - atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) + atomic_inc(&vdisk->error_count); + else + atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev); + if (rtn == SUCCESS) { + scsicmd->result = DID_RESET << 16; + scsicmd->scsi_done(scsicmd); } - return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd); + return rtn; } /* - * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each - * target on the bus - * @scsicmd: The scsicmd that needs aborted + * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each + * target on the bus + * @scsicmd: The scsicmd that needs aborted * - * Returns SUCCESS + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; + int rtn; scsidev = scsicmd->device; - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { + shost_for_each_device(scsidev, scsidev->host) { + vdisk = scsidev->hostdata; if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) atomic_inc(&vdisk->error_count); else atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); } - return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd); + rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev); + if (rtn == SUCCESS) { + scsicmd->result = DID_RESET << 16; + scsicmd->scsi_done(scsicmd); + } + return rtn; } /* - * visorhba_host_reset_handler - Not supported - * @scsicmd: The scsicmd that needs aborted + * visorhba_host_reset_handler - Not supported + * @scsicmd: The scsicmd that needs to be aborted * - * Not supported, return SUCCESS - * Returns SUCCESS + * Return: Not supported, return SUCCESS */ -static int -visorhba_host_reset_handler(struct scsi_cmnd *scsicmd) +static int visorhba_host_reset_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */ return SUCCESS; } /* - * visorhba_get_info - * @shp: Scsi host that is requesting information + * visorhba_get_info - Get information about SCSI device + * @shp: Scsi host that is requesting information * - * Returns string with info + * Return: String with visorhba information */ static const char *visorhba_get_info(struct Scsi_Host *shp) { @@ -464,19 +475,42 @@ static const char *visorhba_get_info(struct Scsi_Host *shp) } /* - * visorhba_queue_command_lck -- queues command to the Service Partition - * @scsicmd: Command to be queued - * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned + * dma_data_dir_linux_to_spar - convert dma_data_direction value to + * Unisys-specific equivalent + * @d: dma direction value to convert * - * Queues to scsicmd to the ServicePartition after converting it to a - * uiscmdrsp structure. + * Returns the Unisys-specific dma direction value corresponding to @d + */ +static u32 dma_data_dir_linux_to_spar(enum dma_data_direction d) +{ + switch (d) { + case DMA_BIDIRECTIONAL: + return UIS_DMA_BIDIRECTIONAL; + case DMA_TO_DEVICE: + return UIS_DMA_TO_DEVICE; + case DMA_FROM_DEVICE: + return UIS_DMA_FROM_DEVICE; + case DMA_NONE: + return UIS_DMA_NONE; + default: + return UIS_DMA_NONE; + } +} + +/* + * visorhba_queue_command_lck - Queues command to the Service Partition + * @scsicmd: Command to be queued + * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned * - * Returns success if queued to the Service Partition, otherwise - * failure. + * Queues to scsicmd to the ServicePartition after converting it to a + * uiscmdrsp structure. + * + * Return: 0 if successfully queued to the Service Partition, otherwise + * error code */ -static int -visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, - void (*visorhba_cmnd_done)(struct scsi_cmnd *)) +static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, + void (*visorhba_cmnd_done) + (struct scsi_cmnd *)) { struct uiscmdrsp *cmdrsp; struct scsi_device *scsidev = scsicmd->device; @@ -494,12 +528,10 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, insert_location = add_scsipending_entry(devdata, CMD_SCSI_TYPE, (void *)scsicmd); - if (insert_location < 0) return SCSI_MLQUEUE_DEVICE_BUSY; cmdrsp = get_scsipending_cmdrsp(devdata, insert_location); - cmdrsp->cmdtype = CMD_SCSI_TYPE; /* save the pending insertion location. Deletion from pending * will return the scsicmd pointer for completion @@ -513,9 +545,9 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, cmdrsp->scsi.vdest.id = scsidev->id; cmdrsp->scsi.vdest.lun = scsidev->lun; /* save datadir */ - cmdrsp->scsi.data_dir = scsicmd->sc_data_direction; + cmdrsp->scsi.data_dir = + dma_data_dir_linux_to_spar(scsicmd->sc_data_direction); memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE); - cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd); /* keep track of the max buffer length so far. */ @@ -555,13 +587,13 @@ static DEF_SCSI_QCMD(visorhba_queue_command) #endif /* - * visorhba_slave_alloc - called when new disk is discovered - * @scsidev: New disk + * visorhba_slave_alloc - Called when new disk is discovered + * @scsidev: New disk * - * Create a new visordisk_info structure and add it to our - * list of vdisks. + * Create a new visordisk_info structure and add it to our + * list of vdisks. * - * Returns success when created, otherwise error. + * Return: 0 on success, -ENOMEM on failure. */ static int visorhba_slave_alloc(struct scsi_device *scsidev) { @@ -569,51 +601,41 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev) * LLD can alloc any struct & do init if needed. */ struct visordisk_info *vdisk; - struct visordisk_info *tmpvdisk; struct visorhba_devdata *devdata; struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; + /* already allocated return success */ + if (scsidev->hostdata) + return 0; + + /* even though we errored, treat as success */ devdata = (struct visorhba_devdata *)scsihost->hostdata; if (!devdata) - return 0; /* even though we errored, treat as success */ - - for_each_vdisk_match(vdisk, devdata, scsidev) - return 0; /* already allocated return success */ + return 0; - tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC); - if (!tmpvdisk) + vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC); + if (!vdisk) return -ENOMEM; - tmpvdisk->channel = scsidev->channel; - tmpvdisk->id = scsidev->id; - tmpvdisk->lun = scsidev->lun; - vdisk->next = tmpvdisk; + vdisk->sdev = scsidev; + scsidev->hostdata = vdisk; return 0; } /* - * visorhba_slave_destroy - disk is going away - * @scsidev: scsi device going away - * - * Disk is going away, clean up resources. - * Returns void. + * visorhba_slave_destroy - Disk is going away, clean up resources. + * @scsidev: Scsi device to destroy */ static void visorhba_slave_destroy(struct scsi_device *scsidev) { /* midlevel calls this after device has been quiesced and * before it is to be deleted. */ - struct visordisk_info *vdisk, *delvdisk; - struct visorhba_devdata *devdata; - struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; + struct visordisk_info *vdisk; - devdata = (struct visorhba_devdata *)scsihost->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - delvdisk = vdisk->next; - vdisk->next = delvdisk->next; - kfree(delvdisk); - return; - } + vdisk = scsidev->hostdata; + scsidev->hostdata = NULL; + kfree(vdisk); } static struct scsi_host_template visorhba_driver_template = { @@ -635,10 +657,13 @@ static struct scsi_host_template visorhba_driver_template = { }; /* - * info_debugfs_show - debugfs interface to dump visorhba states + * info_debugfs_show - Debugfs interface to dump visorhba states + * @seq: The sequence file to write information to + * @v: Unused, but needed for use with seq file single_open invocation + * + * Presents a file in the debugfs tree named: /visorhba/vbus:dev/info. * - * This presents a file in the debugfs tree named: - * /visorhba/vbus:dev/info + * Return: SUCCESS */ static int info_debugfs_show(struct seq_file *seq, void *v) { @@ -679,12 +704,13 @@ static const struct file_operations info_debugfs_fops = { }; /* - * complete_taskmgmt_command - complete task management - * @cmdrsp: Response from the IOVM + * complete_taskmgmt_command - Complete task management + * @idrtable: The data object maintaining the pointer<-->int mappings + * @cmdrsp: Response from the IOVM + * @result: The result of the task management command * - * Service Partition returned the result of the task management - * command. Wake up anyone waiting for it. - * Returns void + * Service Partition returned the result of the task management + * command. Wake up anyone waiting for it. */ static void complete_taskmgmt_command(struct idr *idrtable, struct uiscmdrsp *cmdrsp, int result) @@ -693,7 +719,6 @@ static void complete_taskmgmt_command(struct idr *idrtable, idr_find(idrtable, cmdrsp->scsitaskmgmt.notify_handle); int *scsi_result_ptr = idr_find(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle); - if (unlikely(!(wq && scsi_result_ptr))) { pr_err("visorhba: no completion context; cmd will time out\n"); return; @@ -708,13 +733,12 @@ static void complete_taskmgmt_command(struct idr *idrtable, } /* - * visorhba_serverdown_complete - Called when we are done cleaning up - * from serverdown - * @work: work structure for this serverdown request + * visorhba_serverdown_complete - Called when we are done cleaning up + * from serverdown + * @devdata: Visorhba instance on which to complete serverdown * - * Called when we are done cleanning up from serverdown, stop processing - * queue, fail pending IOs. - * Returns void when finished cleaning up + * Called when we are done cleanning up from serverdown, stop processing + * queue, fail pending IOs. */ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) { @@ -758,12 +782,13 @@ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) } /* - * visorhba_serverdown - Got notified that the IOVM is down - * @devdata: visorhba that is being serviced by downed IOVM. + * visorhba_serverdown - Got notified that the IOVM is down + * @devdata: Visorhba that is being serviced by downed IOVM * - * Something happened to the IOVM, return immediately and - * schedule work cleanup work. - * Return SUCCESS or EINVAL + * Something happened to the IOVM, return immediately and + * schedule cleanup work. + * + * Return: 0 on success, -EINVAL on failure */ static int visorhba_serverdown(struct visorhba_devdata *devdata) { @@ -777,17 +802,15 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata) } /* - * do_scsi_linuxstat - scsi command returned linuxstat - * @cmdrsp: response from IOVM - * @scsicmd: Command issued. + * do_scsi_linuxstat - Scsi command returned linuxstat + * @cmdrsp: Response from IOVM + * @scsicmd: Command issued * - * Don't log errors for disk-not-present inquiries - * Returns void + * Don't log errors for disk-not-present inquiries. */ -static void -do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { - struct visorhba_devdata *devdata; struct visordisk_info *vdisk; struct scsi_device *scsidev; @@ -800,19 +823,17 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT)) return; /* Okay see what our error_count is here.... */ - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) { - atomic_inc(&vdisk->error_count); - atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); - } + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) { + atomic_inc(&vdisk->error_count); + atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); } } -static int set_no_disk_inquiry_result(unsigned char *buf, - size_t len, bool is_lun0) +static int set_no_disk_inquiry_result(unsigned char *buf, size_t len, + bool is_lun0) { - if (!buf || len < NO_DISK_INQUIRY_RESULT_LEN) + if (len < NO_DISK_INQUIRY_RESULT_LEN) return -EINVAL; memset(buf, 0, NO_DISK_INQUIRY_RESULT_LEN); buf[2] = SCSI_SPC2_VER; @@ -828,15 +849,14 @@ static int set_no_disk_inquiry_result(unsigned char *buf, } /* - * do_scsi_nolinuxstat - scsi command didn't have linuxstat - * @cmdrsp: response from IOVM - * @scsicmd: Command issued. + * do_scsi_nolinuxstat - Scsi command didn't have linuxstat + * @cmdrsp: Response from IOVM + * @scsicmd: Command issued * - * Handle response when no linuxstat was returned - * Returns void + * Handle response when no linuxstat was returned. */ -static void -do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; unsigned char *buf; @@ -846,7 +866,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) char *this_page_orig; int bufind = 0; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; scsidev = scsicmd->device; if ((cmdrsp->scsi.cmnd[0] == INQUIRY) && @@ -883,28 +902,25 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } kfree(buf); } else { - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->ios_threshold) > 0) { - atomic_dec(&vdisk->ios_threshold); - if (atomic_read(&vdisk->ios_threshold) == 0) - atomic_set(&vdisk->error_count, 0); - } + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->ios_threshold) > 0) { + atomic_dec(&vdisk->ios_threshold); + if (atomic_read(&vdisk->ios_threshold) == 0) + atomic_set(&vdisk->error_count, 0); } } } /* - * complete_scsi_command - complete a scsi command - * @uiscmdrsp: Response from Service Partition - * @scsicmd: The scsi command + * complete_scsi_command - Complete a scsi command + * @uiscmdrsp: Response from Service Partition + * @scsicmd: The scsi command * - * Response returned by the Service Partition, finish it and send - * completion to the scsi midlayer. - * Returns void. + * Response was returned by the Service Partition. Finish it and send + * completion to the scsi midlayer. */ -static void -complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void complete_scsi_command(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { /* take what we need out of cmdrsp and complete the scsicmd */ scsicmd->result = cmdrsp->scsi.linuxstat; @@ -917,24 +933,23 @@ complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } /* - * drain_queue - pull responses out of iochannel - * @cmdrsp: Response from the IOSP - * @devdata: device that owns this iochannel + * drain_queue - Pull responses out of iochannel + * @cmdrsp: Response from the IOSP + * @devdata: Device that owns this iochannel * - * Pulls responses out of the iochannel and process the responses. - * Restuns void + * Pulls responses out of the iochannel and process the responses. */ -static void -drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata) +static void drain_queue(struct uiscmdrsp *cmdrsp, + struct visorhba_devdata *devdata) { struct scsi_cmnd *scsicmd; while (1) { + /* queue empty */ if (visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, cmdrsp)) - break; /* queue empty */ - + break; if (cmdrsp->cmdtype == CMD_SCSI_TYPE) { /* scsicmd location is returned by the * deletion @@ -959,12 +974,14 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata) } /* - * process_incoming_rsps - Process responses from IOSP - * @v: void pointer to visorhba_devdata + * process_incoming_rsps - Process responses from IOSP + * @v: Void pointer to visorhba_devdata * - * Main function for the thread that processes the responses - * from the IO Service Partition. When the queue is empty, wait - * to check to see if it is full again. + * Main function for the thread that processes the responses + * from the IO Service Partition. When the queue is empty, wait + * to check to see if it is full again. + * + * Return: 0 on success, -ENOMEM on failure */ static int process_incoming_rsps(void *v) { @@ -991,14 +1008,15 @@ static int process_incoming_rsps(void *v) } /* - * visorhba_pause - function to handle visorbus pause messages - * @dev: device that is pausing. - * @complete_func: function to call when finished + * visorhba_pause - Function to handle visorbus pause messages + * @dev: Device that is pausing + * @complete_func: Function to call when finished + * + * Something has happened to the IO Service Partition that is + * handling this device. Quiet this device and reset commands + * so that the Service Partition can be corrected. * - * Something has happened to the IO Service Partition that is - * handling this device. Quiet this device and reset commands - * so that the Service Partition can be corrected. - * Returns SUCCESS + * Return: SUCCESS */ static int visorhba_pause(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -1011,13 +1029,14 @@ static int visorhba_pause(struct visor_device *dev, } /* - * visorhba_resume - function called when the IO Service Partition is back - * @dev: device that is pausing. - * @complete_func: function to call when finished + * visorhba_resume - Function called when the IO Service Partition is back + * @dev: Device that is pausing + * @complete_func: Function to call when finished * - * Yay! The IO Service Partition is back, the channel has been wiped - * so lets re-establish connection and start processing responses. - * Returns 0 on success, error on failure. + * Yay! The IO Service Partition is back, the channel has been wiped + * so lets re-establish connection and start processing responses. + * + * Return: 0 on success, -EINVAL on failure */ static int visorhba_resume(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -1033,7 +1052,6 @@ static int visorhba_resume(struct visor_device *dev, devdata->thread = visor_thread_start(process_incoming_rsps, devdata, "vhba_incming"); - devdata->serverdown = false; devdata->serverchangingstate = false; @@ -1041,11 +1059,12 @@ static int visorhba_resume(struct visor_device *dev, } /* - * visorhba_probe - device has been discovered, do acquire - * @dev: visor_device that was discovered + * visorhba_probe - Device has been discovered; do acquire + * @dev: visor_device that was discovered * - * A new HBA was discovered, do the initial connections of it. - * Return 0 on success, otherwise error. + * A new HBA was discovered; do the initial connections of it. + * + * Return: 0 on success, otherwise error code */ static int visorhba_probe(struct visor_device *dev) { @@ -1139,11 +1158,10 @@ static int visorhba_probe(struct visor_device *dev) } /* - * visorhba_remove - remove a visorhba device - * @dev: Device to remove + * visorhba_remove - Remove a visorhba device + * @dev: Device to remove * - * Removes the visorhba device. - * Returns void. + * Removes the visorhba device. */ static void visorhba_remove(struct visor_device *dev) { @@ -1181,10 +1199,12 @@ static struct visor_driver visorhba_driver = { }; /* - * visorhba_init - driver init routine + * visorhba_init - Driver init routine + * + * Initialize the visorhba driver and register it with visorbus + * to handle s-Par virtual host bus adapter. * - * Initialize the visorhba driver and register it with visorbus - * to handle s-Par virtual host bus adapter. + * Return: 0 on success, error code otherwise */ static int visorhba_init(void) { @@ -1207,9 +1227,9 @@ static int visorhba_init(void) } /* - * visorhba_exit - driver exit routine + * visorhba_exit - Driver exit routine * - * Unregister driver from the bus and free up memory. + * Unregister driver from the bus and free up memory. */ static void visorhba_exit(void) { diff --git a/drivers/staging/unisys/visorinput/ultrainputreport.h b/drivers/staging/unisys/visorinput/ultrainputreport.h index a4baea53c51880610b93a5a348d320ca62576ac7..53975a09535f9651c90931759c192ee9f70a459d 100644 --- a/drivers/staging/unisys/visorinput/ultrainputreport.h +++ b/drivers/staging/unisys/visorinput/ultrainputreport.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -20,44 +21,35 @@ /* These defines identify mouse and keyboard activity which is specified by the * firmware to the host using the cmsimpleinput protocol. @ingroup coretypes */ -#define INPUTACTION_XY_MOTION 1 /* only motion; arg1=x, arg2=y */ -#define INPUTACTION_MOUSE_BUTTON_DOWN 2 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_UP 3 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_CLICK 4 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 /* arg1: 1=left,2=center, - * 3=right - */ -#define INPUTACTION_WHEEL_ROTATE_AWAY 6 /* arg1: wheel rotation away from - * user - */ -#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 /* arg1: wheel rotation toward - * user - */ -#define INPUTACTION_KEY_DOWN 64 /* arg1: scancode, as follows: - * If arg1 <= 0xff, it's a 1-byte - * scancode and arg1 is that scancode. - * If arg1 > 0xff, it's a 2-byte - * scanecode, with the 1st byte in the - * low 8 bits, and the 2nd byte in the - * high 8 bits. E.g., the right ALT key - * would appear as x'38e0'. - */ -#define INPUTACTION_KEY_UP 65 /* arg1: scancode (in same format as - * inputaction_keyDown) - */ + /* only motion; arg1=x, arg2=y */ +#define INPUTACTION_XY_MOTION 1 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_DOWN 2 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_UP 3 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_CLICK 4 +/* arg1: 1=left,2=center 3=right */ +#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 +/* arg1: wheel rotation away from user */ +#define INPUTACTION_WHEEL_ROTATE_AWAY 6 +/* arg1: wheel rotation toward user */ +#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 +/* arg1: scancode, as follows: If arg1 <= 0xff, it's a 1-byte scancode and arg1 + * is that scancode. If arg1 > 0xff, it's a 2-byte scanecode, with the 1st + * byte in the low 8 bits, and the 2nd byte in the high 8 bits. + * E.g., the right ALT key would appear as x'38e0'. + */ +#define INPUTACTION_KEY_DOWN 64 +/* arg1: scancode (in same format as inputaction_keyDown) */ +#define INPUTACTION_KEY_UP 65 +/* arg1: scancode (in same format as inputaction_keyDown); MUST refer to one of + * the locking keys, like capslock, numlock, or scrolllock. + * arg2: 1 iff locking key should be in the LOCKED position (e.g., light is ON) + */ #define INPUTACTION_SET_LOCKING_KEY_STATE 66 - /* arg1: scancode (in same format - * as inputaction_keyDown); - * MUST refer to one of the - * locking keys, like capslock, - * numlock, or scrolllock - * arg2: 1 iff locking key should be - * in the LOCKED position - * (e.g., light is ON) - */ -#define INPUTACTION_KEY_DOWN_UP 67 /* arg1: scancode (in same format - * as inputaction_keyDown) - */ +/* arg1: scancode (in same format as inputaction_keyDown */ +#define INPUTACTION_KEY_DOWN_UP 67 struct visor_inputactivity { u16 action; diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 45bc340d4e9dff8bc6c68783dce3391ac59d0f0c..9d8cbc52de8b2efebf679d750fa713361607b215 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -1,5 +1,4 @@ -/* visorinput.c - * +/* * Copyright (C) 2011 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -21,11 +20,8 @@ * standard way the Linux expects for input drivers. */ -#include #include -#include #include -#include #include #include @@ -33,16 +29,16 @@ #include "ultrainputreport.h" /* Keyboard channel {c73416d0-b0b8-44af-b304-9d2ae99f1b3d} */ -#define VISOR_KEYBOARD_CHANNEL_UUID \ - UUID_LE(0xc73416d0, 0xb0b8, 0x44af, \ - 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d) -#define VISOR_KEYBOARD_CHANNEL_UUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d" +#define VISOR_KEYBOARD_CHANNEL_GUID \ + GUID_INIT(0xc73416d0, 0xb0b8, 0x44af, \ + 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d) +#define VISOR_KEYBOARD_CHANNEL_GUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d" /* Mouse channel {addf07d4-94a9-46e2-81c3-61abcdbdbd87} */ -#define VISOR_MOUSE_CHANNEL_UUID \ - UUID_LE(0xaddf07d4, 0x94a9, 0x46e2, \ - 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87) -#define VISOR_MOUSE_CHANNEL_UUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87" +#define VISOR_MOUSE_CHANNEL_GUID \ + GUID_INIT(0xaddf07d4, 0x94a9, 0x46e2, \ + 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87) +#define VISOR_MOUSE_CHANNEL_GUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87" #define PIXELS_ACROSS_DEFAULT 800 #define PIXELS_DOWN_DEFAULT 600 @@ -60,17 +56,19 @@ enum visorinput_device_type { */ struct visorinput_devdata { struct visor_device *dev; - struct mutex lock_visor_dev; /* lock for dev */ + /* lock for dev */ + struct mutex lock_visor_dev; struct input_dev *visorinput_dev; bool paused; bool interrupts_enabled; - unsigned int keycode_table_bytes; /* size of following array */ + /* size of following array */ + unsigned int keycode_table_bytes; /* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */ unsigned char keycode_table[0]; }; -static const uuid_le visor_keyboard_channel_uuid = VISOR_KEYBOARD_CHANNEL_UUID; -static const uuid_le visor_mouse_channel_uuid = VISOR_MOUSE_CHANNEL_UUID; +static const guid_t visor_keyboard_channel_guid = VISOR_KEYBOARD_CHANNEL_GUID; +static const guid_t visor_mouse_channel_guid = VISOR_MOUSE_CHANNEL_GUID; /* * Borrowed from drivers/input/keyboard/atakbd.c @@ -162,9 +160,8 @@ static const unsigned char visorkbd_keycode[KEYCODE_TABLE_BYTES] = { [81] = KEY_KP3, [82] = KEY_KP0, [83] = KEY_KPDOT, - [86] = KEY_102ND, /* enables UK backslash+pipe key, - * and FR lessthan+greaterthan key - */ + /* enables UK backslash+pipe key and FR lessthan+greaterthan key */ + [86] = KEY_102ND, [87] = KEY_F11, [88] = KEY_F12, [90] = KEY_KPLEFTPAREN, @@ -260,7 +257,6 @@ static void visorinput_close(struct input_dev *visorinput_dev) * interrupts should be disabled so when we resume we will * not re-enable them. */ - mutex_lock(&devdata->lock_visor_dev); devdata->interrupts_enabled = false; if (devdata->paused) @@ -276,15 +272,13 @@ static void visorinput_close(struct input_dev *visorinput_dev) * we can use to deliver keyboard inputs to Linux. We of course do this when * we see keyboard inputs coming in on a keyboard channel. */ -static struct input_dev * -setup_client_keyboard(void *devdata, /* opaque on purpose */ - unsigned char *keycode_table) +static struct input_dev *setup_client_keyboard(void *devdata, + unsigned char *keycode_table) { int i; - struct input_dev *visorinput_dev; + struct input_dev *visorinput_dev = input_allocate_device(); - visorinput_dev = input_allocate_device(); if (!visorinput_dev) return NULL; @@ -302,7 +296,8 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */ BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML); visorinput_dev->keycode = keycode_table; - visorinput_dev->keycodesize = 1; /* sizeof(unsigned char) */ + /* sizeof(unsigned char) */ + visorinput_dev->keycodesize = 1; visorinput_dev->keycodemax = KEYCODE_TABLE_BYTES; for (i = 1; i < visorinput_dev->keycodemax; i++) @@ -313,19 +308,18 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */ visorinput_dev->open = visorinput_open; visorinput_dev->close = visorinput_close; - input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */ + /* pre input_register! */ + input_set_drvdata(visorinput_dev, devdata); return visorinput_dev; } -static struct input_dev * -setup_client_mouse(void *devdata /* opaque on purpose */) +static struct input_dev *setup_client_mouse(void *devdata) { - struct input_dev *visorinput_dev = NULL; int xres, yres; struct fb_info *fb0; + struct input_dev *visorinput_dev = input_allocate_device(); - visorinput_dev = input_allocate_device(); if (!visorinput_dev) return NULL; @@ -354,14 +348,16 @@ setup_client_mouse(void *devdata /* opaque on purpose */) visorinput_dev->open = visorinput_open; visorinput_dev->close = visorinput_close; - input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */ + /* pre input_register! */ + input_set_drvdata(visorinput_dev, devdata); input_set_capability(visorinput_dev, EV_REL, REL_WHEEL); return visorinput_dev; } -static struct visorinput_devdata * -devdata_create(struct visor_device *dev, enum visorinput_device_type devtype) +static struct visorinput_devdata *devdata_create( + struct visor_device *dev, + enum visorinput_device_type devtype) { struct visorinput_devdata *devdata = NULL; unsigned int extra_bytes = 0; @@ -446,16 +442,15 @@ devdata_create(struct visor_device *dev, enum visorinput_device_type devtype) return NULL; } -static int -visorinput_probe(struct visor_device *dev) +static int visorinput_probe(struct visor_device *dev) { - uuid_le guid; + const guid_t *guid; enum visorinput_device_type devtype; - guid = visorchannel_get_uuid(dev->visorchannel); - if (uuid_le_cmp(guid, visor_mouse_channel_uuid) == 0) + guid = visorchannel_get_guid(dev->visorchannel); + if (guid_equal(guid, &visor_mouse_channel_guid)) devtype = visorinput_mouse; - else if (uuid_le_cmp(guid, visor_keyboard_channel_uuid) == 0) + else if (guid_equal(guid, &visor_keyboard_channel_guid)) devtype = visorinput_keyboard; else return -ENODEV; @@ -465,15 +460,13 @@ visorinput_probe(struct visor_device *dev) return 0; } -static void -unregister_client_input(struct input_dev *visorinput_dev) +static void unregister_client_input(struct input_dev *visorinput_dev) { if (visorinput_dev) input_unregister_device(visorinput_dev); } -static void -visorinput_remove(struct visor_device *dev) +static void visorinput_remove(struct visor_device *dev) { struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -499,9 +492,8 @@ visorinput_remove(struct visor_device *dev) * Make it so the current locking state of the locking key indicated by * is as indicated by (1=locked, 0=unlocked). */ -static void -handle_locking_key(struct input_dev *visorinput_dev, - int keycode, int desired_state) +static void handle_locking_key(struct input_dev *visorinput_dev, int keycode, + int desired_state) { int led; @@ -533,17 +525,15 @@ handle_locking_key(struct input_dev *visorinput_dev, * with 0xE0 in the low byte and the extended scancode value in the next * higher byte. */ -static int -scancode_to_keycode(int scancode) +static int scancode_to_keycode(int scancode) { if (scancode > 0xff) return visorkbd_ext_keycode[(scancode >> 8) & 0xff]; - return visorkbd_keycode[scancode]; + return visorkbd_keycode[scancode]; } -static int -calc_button(int x) +static int calc_button(int x) { switch (x) { case 1: @@ -562,15 +552,13 @@ calc_button(int x) * client guest partition. It is called periodically so we can obtain inputs * from the channel, and deliver them to the guest OS. */ -static void -visorinput_channel_interrupt(struct visor_device *dev) +static void visorinput_channel_interrupt(struct visor_device *dev) { struct visor_inputreport r; int scancode, keycode; struct input_dev *visorinput_dev; int xmotion, ymotion, button; int i; - struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); if (!devdata) @@ -626,7 +614,6 @@ visorinput_channel_interrupt(struct visor_device *dev) if (button < 0) break; input_report_key(visorinput_dev, button, 1); - input_sync(visorinput_dev); input_report_key(visorinput_dev, button, 0); input_sync(visorinput_dev); @@ -657,9 +644,8 @@ visorinput_channel_interrupt(struct visor_device *dev) } } -static int -visorinput_pause(struct visor_device *dev, - visorbus_state_complete_func complete_func) +static int visorinput_pause(struct visor_device *dev, + visorbus_state_complete_func complete_func) { int rc; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -681,7 +667,6 @@ visorinput_pause(struct visor_device *dev, * due to above, at this time no thread of execution will be * in visorinput_channel_interrupt() */ - devdata->paused = true; complete_func(dev, 0); rc = 0; @@ -691,9 +676,8 @@ visorinput_pause(struct visor_device *dev, return rc; } -static int -visorinput_resume(struct visor_device *dev, - visorbus_state_complete_func complete_func) +static int visorinput_resume(struct visor_device *dev, + visorbus_state_complete_func complete_func) { int rc; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -727,9 +711,9 @@ visorinput_resume(struct visor_device *dev, /* GUIDS for all channel types supported by this driver. */ static struct visor_channeltype_descriptor visorinput_channel_types[] = { - { VISOR_KEYBOARD_CHANNEL_UUID, "keyboard"}, - { VISOR_MOUSE_CHANNEL_UUID, "mouse"}, - { NULL_UUID_LE, NULL } + { VISOR_KEYBOARD_CHANNEL_GUID, "keyboard"}, + { VISOR_MOUSE_CHANNEL_GUID, "mouse"}, + {} }; static struct visor_driver visorinput_driver = { @@ -743,20 +727,8 @@ static struct visor_driver visorinput_driver = { .resume = visorinput_resume, }; -static int -visorinput_init(void) -{ - return visorbus_register_visor_driver(&visorinput_driver); -} - -static void -visorinput_cleanup(void) -{ - visorbus_unregister_visor_driver(&visorinput_driver); -} - -module_init(visorinput_init); -module_exit(visorinput_cleanup); +module_driver(visorinput_driver, visorbus_register_visor_driver, + visorbus_unregister_visor_driver); MODULE_DEVICE_TABLE(visorbus, visorinput_channel_types); @@ -764,5 +736,5 @@ MODULE_AUTHOR("Unisys"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("s-Par human input driver for virtual keyboard/mouse"); -MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_UUID_STR); -MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_GUID_STR); +MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_GUID_STR); diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 2891622eef18d34837a6177bc578e067fc118cc0..dc390eae2960a03a69c6a99f42269c769debb071 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -37,22 +37,28 @@ #define NAPI_WEIGHT 64 /* GUIDS for director channel type supported by this driver. */ +/* {8cd5994d-c58e-11da-95a9-00e08161165f} */ +#define VISOR_VNIC_CHANNEL_GUID \ + GUID_INIT(0x8cd5994d, 0xc58e, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VNIC_CHANNEL_GUID_STR \ + "8cd5994d-c58e-11da-95a9-00e08161165f" + static struct visor_channeltype_descriptor visornic_channel_types[] = { /* Note that the only channel type we expect to be reported by the * bus driver is the VISOR_VNIC channel. */ - { VISOR_VNIC_CHANNEL_UUID, "ultravnic" }, - { NULL_UUID_LE, NULL } + { VISOR_VNIC_CHANNEL_GUID, "ultravnic" }, + {} }; MODULE_DEVICE_TABLE(visorbus, visornic_channel_types); -/* - * FIXME XXX: This next line of code must be fixed and removed before +/* FIXME XXX: This next line of code must be fixed and removed before * acceptance into the 'normal' part of the kernel. It is only here as a place * holder to get module autoloading functionality working for visorbus. Code * must be added to scripts/mode/file2alias.c, etc., to get this working * properly. */ -MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_GUID_STR); struct chanstat { unsigned long got_rcv; @@ -68,10 +74,67 @@ struct chanstat { unsigned long extra_rcvbufs_sent; }; +/* struct visornic_devdata + * @enabled: 0 disabled 1 enabled to receive. + * @enab_dis_acked: NET_RCV_ENABLE/DISABLE acked by IOPART. + * @struct *dev: + * @struct *netdev: + * @struct net_stats: + * @interrupt_rcvd: + * @rsp_queue: + * @struct **rcvbuf: + * @incarnation_id: incarnation_id lets IOPART know about + * re-birth. + * @old_flags: flags as they were prior to + * set_multicast_list. + * @usage: count of users. + * @num_rcv_bufs: number of rcv buffers the vnic will post. + * @num_rcv_bufs_could_not_alloc: + * @num_rcvbuf_in_iovm: + * @alloc_failed_in_if_needed_cnt: + * @alloc_failed_in_repost_rtn_cnt: + * @max_outstanding_net_xmits: absolute max number of outstanding xmits + * - should never hit this. + * @upper_threshold_net_xmits: high water mark for calling + * netif_stop_queue(). + * @lower_threshold_net_xmits: high water mark for calling + * netif_wake_queue(). + * @struct xmitbufhead: xmitbufhead - head of the xmit buffer list + * sent to the IOPART end. + * @server_down_complete_func: + * @struct timeout_reset: + * @struct *cmdrsp_rcv: cmdrsp_rcv is used for posting/unposting rcv + * buffers. + * @struct *xmit_cmdrsp: xmit_cmdrsp - issues NET_XMIT - only one + * active xmit at a time. + * @server_down: IOPART is down. + * @server_change_state: Processing SERVER_CHANGESTATE msg. + * @going_away: device is being torn down. + * @struct *eth_debugfs_dir: + * @interrupts_rcvd: + * @interrupts_notme: + * @interrupts_disabled: + * @busy_cnt: + * @priv_lock: spinlock to access devdata structures. + * @flow_control_upper_hits: + * @flow_control_lower_hits: + * @n_rcv0: # rcvs of 0 buffers. + * @n_rcv1: # rcvs of 1 buffers. + * @n_rcv2: # rcvs of 2 buffers. + * @n_rcvx: # rcvs of >2 buffers. + * @found_repost_rcvbuf_cnt: # repost_rcvbuf_cnt. + * @repost_found_skb_cnt: # of found the skb. + * @n_repost_deficit: # of lost rcv buffers. + * @bad_rcv_buf: # of unknown rcv skb not freed. + * @n_rcv_packets_not_accepted: # bogs rcv packets. + * @queuefullmsg_logged: + * @struct chstat: + * @struct irq_poll_timer: + * @struct napi: + * @struct cmdrsp: + */ struct visornic_devdata { - /* 0 disabled 1 enabled to receive */ unsigned short enabled; - /* NET_RCV_ENABLE/DISABLE acked by IOPART */ unsigned short enab_dis_acked; struct visor_device *dev; @@ -80,59 +143,50 @@ struct visornic_devdata { atomic_t interrupt_rcvd; wait_queue_head_t rsp_queue; struct sk_buff **rcvbuf; - /* incarnation_id lets IOPART know about re-birth */ u64 incarnation_id; - /* flags as they were prior to set_multicast_list */ unsigned short old_flags; - atomic_t usage; /* count of users */ + atomic_t usage; - /* number of rcv buffers the vnic will post */ int num_rcv_bufs; int num_rcv_bufs_could_not_alloc; atomic_t num_rcvbuf_in_iovm; unsigned long alloc_failed_in_if_needed_cnt; unsigned long alloc_failed_in_repost_rtn_cnt; - /* absolute max number of outstanding xmits - should never hit this */ unsigned long max_outstanding_net_xmits; - /* high water mark for calling netif_stop_queue() */ unsigned long upper_threshold_net_xmits; - /* high water mark for calling netif_wake_queue() */ unsigned long lower_threshold_net_xmits; - /* xmitbufhead - head of the xmit buffer list sent to the IOPART end */ struct sk_buff_head xmitbufhead; visorbus_state_complete_func server_down_complete_func; struct work_struct timeout_reset; - /* cmdrsp_rcv is used for posting/unposting rcv buffers */ struct uiscmdrsp *cmdrsp_rcv; - /* xmit_cmdrsp - issues NET_XMIT - only one active xmit at a time */ struct uiscmdrsp *xmit_cmdrsp; - - bool server_down; /* IOPART is down */ - bool server_change_state; /* Processing SERVER_CHANGESTATE msg */ - bool going_away; /* device is being torn down */ + bool server_down; + bool server_change_state; + bool going_away; struct dentry *eth_debugfs_dir; u64 interrupts_rcvd; u64 interrupts_notme; u64 interrupts_disabled; u64 busy_cnt; - spinlock_t priv_lock; /* spinlock to access devdata structures */ + /* spinlock to access devdata structures. */ + spinlock_t priv_lock; /* flow control counter */ u64 flow_control_upper_hits; u64 flow_control_lower_hits; /* debug counters */ - unsigned long n_rcv0; /* # rcvs of 0 buffers */ - unsigned long n_rcv1; /* # rcvs of 1 buffers */ - unsigned long n_rcv2; /* # rcvs of 2 buffers */ - unsigned long n_rcvx; /* # rcvs of >2 buffers */ - unsigned long found_repost_rcvbuf_cnt; /* # repost_rcvbuf_cnt */ - unsigned long repost_found_skb_cnt; /* # of found the skb */ - unsigned long n_repost_deficit; /* # of lost rcv buffers */ - unsigned long bad_rcv_buf; /* # of unknown rcv skb not freed */ - unsigned long n_rcv_packets_not_accepted;/* # bogs rcv packets */ + unsigned long n_rcv0; + unsigned long n_rcv1; + unsigned long n_rcv2; + unsigned long n_rcvx; + unsigned long found_repost_rcvbuf_cnt; + unsigned long repost_found_skb_cnt; + unsigned long n_repost_deficit; + unsigned long bad_rcv_buf; + unsigned long n_rcv_packets_not_accepted; int queuefullmsg_logged; struct chanstat chstat; @@ -142,12 +196,11 @@ struct visornic_devdata { }; /* Returns next non-zero index on success or 0 on failure (i.e. out of room). */ -static u16 -add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, - u16 max_pi_arr_entries, struct phys_info pi_arr[]) +static u16 add_physinfo_entries(u64 inp_pfn, u16 inp_off, u16 inp_len, + u16 index, u16 max_pi_arr_entries, + struct phys_info pi_arr[]) { - u32 len; - u16 i, firstlen; + u16 i, len, firstlen; firstlen = PI_PAGE_SIZE - inp_off; if (inp_len <= firstlen) { @@ -171,29 +224,27 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, pi_arr[index].pi_len = firstlen; } else { pi_arr[index + i].pi_off = 0; - pi_arr[index + i].pi_len = - (u16)MINNUM(len, (u32)PI_PAGE_SIZE); + pi_arr[index + i].pi_len = min_t(u16, len, + PI_PAGE_SIZE); } } return index + i; } -/* - * visor_copy_fragsinfo_from_skb( - * @skb_in: skbuff that we are pulling the frags from - * @firstfraglen: length of first fragment in skb - * @frags_max: max len of frags array - * @frags: frags array filled in on output +/* visor_copy_fragsinfo_from_skb - copy fragment list in the SKB to a phys_info + * array that the IOPART understands + * @skb: Skbuff that we are pulling the frags from. + * @firstfraglen: Length of first fragment in skb. + * @frags_max: Max len of frags array. + * @frags: Frags array filled in on output. * - * Copy the fragment list in the SKB to a phys_info - * array that the IOPART understands. - * Return value indicates number of entries filled in frags - * Negative values indicate an error. + * Return: Positive integer indicating number of entries filled in frags on + * success, negative integer on error. */ -static int -visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen, - unsigned int frags_max, - struct phys_info frags[]) +static int visor_copy_fragsinfo_from_skb(struct sk_buff *skb, + unsigned int firstfraglen, + unsigned int frags_max, + struct phys_info frags[]) { unsigned int count = 0, frag, size, offset = 0, numfrags; unsigned int total_count; @@ -239,11 +290,10 @@ visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen, for (frag = 0; frag < numfrags; frag++) { count = add_physinfo_entries(page_to_pfn( - skb_frag_page(&skb_shinfo(skb)->frags[frag])), - skb_shinfo(skb)->frags[frag]. - page_offset, - skb_shinfo(skb)->frags[frag]. - size, count, frags_max, frags); + skb_frag_page(&skb_shinfo(skb)->frags[frag])), + skb_shinfo(skb)->frags[frag].page_offset, + skb_shinfo(skb)->frags[frag].size, count, + frags_max, frags); /* add_physinfo_entries only returns * zero if the frags array is out of room * That should never happen because we @@ -287,21 +337,15 @@ static const struct file_operations debugfs_enable_ints_fops = { .write = enable_ints_write, }; -/* - * visornic_serverdown_complete - IOPART went down, pause device - * @work: Work queue it was scheduled on +/* visornic_serverdown_complete - pause device following IOPART going down + * @devdata: Device managed by IOPART. * - * The IO partition has gone down and we need to do some cleanup - * for when it comes back. Treat the IO partition as the link - * being down. - * Returns void. + * The IO partition has gone down, and we need to do some cleanup for when it + * comes back. Treat the IO partition as the link being down. */ -static void -visornic_serverdown_complete(struct visornic_devdata *devdata) +static void visornic_serverdown_complete(struct visornic_devdata *devdata) { - struct net_device *netdev; - - netdev = devdata->netdev; + struct net_device *netdev = devdata->netdev; /* Stop polling for interrupts */ del_timer_sync(&devdata->irq_poll_timer); @@ -322,17 +366,17 @@ visornic_serverdown_complete(struct visornic_devdata *devdata) devdata->server_down_complete_func = NULL; } -/* - * visornic_serverdown - Command has notified us that IOPART is down - * @devdata: device that is being managed by IOPART +/* visornic_serverdown - Command has notified us that IOPART is down + * @devdata: Device managed by IOPART. + * @complete_func: Function to call when finished. + * + * Schedule the work needed to handle the server down request. Make sure we + * haven't already handled the server change state event. * - * Schedule the work needed to handle the server down request. Make - * sure we haven't already handled the server change state event. - * Returns 0 if we scheduled the work, -EINVAL on error. + * Return: 0 if we scheduled the work, negative integer on error. */ -static int -visornic_serverdown(struct visornic_devdata *devdata, - visorbus_state_complete_func complete_func) +static int visornic_serverdown(struct visornic_devdata *devdata, + visorbus_state_complete_func complete_func) { unsigned long flags; int err; @@ -369,16 +413,15 @@ visornic_serverdown(struct visornic_devdata *devdata, return err; } -/* - * alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition. - * @netdev: network adapter the rcv bufs are attached too. +/* alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition + * @netdev: Network adapter the rcv bufs are attached too. * - * Create an sk_buff (rcv_buf) that will be passed to the IO Partition - * so that it can write rcv data into our memory space. - * Return pointer to sk_buff + * Create an sk_buff (rcv_buf) that will be passed to the IO Partition + * so that it can write rcv data into our memory space. + * + * Return: Pointer to sk_buff. */ -static struct sk_buff * -alloc_rcv_buf(struct net_device *netdev) +static struct sk_buff *alloc_rcv_buf(struct net_device *netdev) { struct sk_buff *skb; @@ -400,18 +443,15 @@ alloc_rcv_buf(struct net_device *netdev) return skb; } -/* - * post_skb - post a skb to the IO Partition. - * @cmdrsp: cmdrsp packet to be send to the IO Partition - * @devdata: visornic_devdata to post the skb too - * @skb: skb to give to the IO partition +/* post_skb - post a skb to the IO Partition + * @cmdrsp: Cmdrsp packet to be send to the IO Partition. + * @devdata: visornic_devdata to post the skb to. + * @skb: Skb to give to the IO partition. * - * Send the skb to the IO Partition. - * Returns 0 or error + * Return: 0 on success, negative integer on error. */ -static int -post_skb(struct uiscmdrsp *cmdrsp, - struct visornic_devdata *devdata, struct sk_buff *skb) +static int post_skb(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, + struct sk_buff *skb) { int err; @@ -437,23 +477,20 @@ post_skb(struct uiscmdrsp *cmdrsp, atomic_inc(&devdata->num_rcvbuf_in_iovm); devdata->chstat.sent_post++; - return 0; } -/* - * send_enbdis - send NET_RCV_ENBDIS to IO Partition - * @netdev: netdevice we are enable/disable, used as context - * return value - * @state: enable = 1/disable = 0 - * @devdata: visornic device we are enabling/disabling +/* send_enbdis - Send NET_RCV_ENBDIS to IO Partition + * @netdev: Netdevice we are enabling/disabling, used as context return value. + * @state: Enable = 1/disable = 0. + * @devdata: Visornic device we are enabling/disabling. + * + * Send the enable/disable message to the IO Partition. * - * Send the enable/disable message to the IO Partition. - * Returns 0 or error + * Return: 0 on success, negative integer on error. */ -static int -send_enbdis(struct net_device *netdev, int state, - struct visornic_devdata *devdata) +static int send_enbdis(struct net_device *netdev, int state, + struct visornic_devdata *devdata) { int err; @@ -470,19 +507,17 @@ send_enbdis(struct net_device *netdev, int state, return 0; } -/* - * visornic_disable_with_timeout - Disable network adapter - * @netdev: netdevice to disable - * @timeout: timeout to wait for disable +/* visornic_disable_with_timeout - disable network adapter + * @netdev: netdevice to disable. + * @timeout: Timeout to wait for disable. * - * Disable the network adapter and inform the IO Partition that we - * are disabled, reclaim memory from rcv bufs. - * Returns 0 on success, negative for failure of IO Partition - * responding. + * Disable the network adapter and inform the IO Partition that we are disabled. + * Reclaim memory from rcv bufs. * + * Return: 0 on success, negative integer on failure of IO Partition responding. */ -static int -visornic_disable_with_timeout(struct net_device *netdev, const int timeout) +static int visornic_disable_with_timeout(struct net_device *netdev, + const int timeout) { struct visornic_devdata *devdata = netdev_priv(netdev); int i; @@ -493,7 +528,8 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) /* send a msg telling the other end we are stopping incoming pkts */ spin_lock_irqsave(&devdata->priv_lock, flags); devdata->enabled = 0; - devdata->enab_dis_acked = 0; /* must wait for ack */ + /* must wait for ack */ + devdata->enab_dis_acked = 0; spin_unlock_irqrestore(&devdata->priv_lock, flags); /* send disable and wait for ack -- don't hold lock when sending @@ -560,16 +596,16 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) return 0; } -/* - * init_rcv_bufs -- initialize receive bufs and send them to the IO Part - * @netdev: struct netdevice - * @devdata: visornic_devdata +/* init_rcv_bufs - initialize receive buffs and send them to the IO Partition + * @netdev: struct netdevice. + * @devdata: visornic_devdata. + * + * Allocate rcv buffers and post them to the IO Partition. * - * Allocate rcv buffers and post them to the IO Partition. - * Return 0 for success, and negative for failure. + * Return: 0 on success, negative integer on failure. */ -static int -init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) +static int init_rcv_bufs(struct net_device *netdev, + struct visornic_devdata *devdata) { int i, j, count, err; @@ -578,10 +614,12 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) */ for (i = 0; i < devdata->num_rcv_bufs; i++) { devdata->rcvbuf[i] = alloc_rcv_buf(netdev); + /* if we failed to allocate one let us stop */ if (!devdata->rcvbuf[i]) - break; /* if we failed to allocate one let us stop */ + break; } - if (i == 0) /* couldn't even allocate one -- bail out */ + /* couldn't even allocate one -- bail out */ + if (i == 0) return -ENOMEM; count = i; @@ -624,17 +662,17 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) return 0; } -/* - * visornic_enable_with_timeout - send enable to IO Part - * @netdev: struct net_device - * @timeout: Time to wait for the ACK from the enable +/* visornic_enable_with_timeout - send enable to IO Partition + * @netdev: struct net_device. + * @timeout: Time to wait for the ACK from the enable. * - * Sends enable to IOVM, inits, and posts receive buffers to IOVM - * timeout is defined in msecs (timeout of 0 specifies infinite wait) - * Return 0 for success, negative for failure. + * Sends enable to IOVM and inits, and posts receive buffers to IOVM. Timeout is + * defined in msecs (timeout of 0 specifies infinite wait). + * + * Return: 0 on success, negative integer on failure. */ -static int -visornic_enable_with_timeout(struct net_device *netdev, const int timeout) +static int visornic_enable_with_timeout(struct net_device *netdev, + const int timeout) { int err = 0; struct visornic_devdata *devdata = netdev_priv(netdev); @@ -695,20 +733,17 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) } netif_start_queue(netdev); - return 0; } -/* - * visornic_timeout_reset - handle xmit timeout resets - * @work work item that scheduled the work +/* visornic_timeout_reset - handle xmit timeout resets + * @work: Work item that scheduled the work. * - * Transmit Timeouts are typically handled by resetting the - * device for our virtual NIC we will send a Disable and Enable - * to the IOVM. If it doesn't respond we will trigger a serverdown. + * Transmit timeouts are typically handled by resetting the device for our + * virtual NIC; we will send a disable and enable to the IOVM. If it doesn't + * respond, we will trigger a serverdown. */ -static void -visornic_timeout_reset(struct work_struct *work) +static void visornic_timeout_reset(struct work_struct *work) { struct visornic_devdata *devdata; struct net_device *netdev; @@ -742,41 +777,36 @@ visornic_timeout_reset(struct work_struct *work) rtnl_unlock(); } -/* - * visornic_open - Enable the visornic device and mark the queue started - * @netdev: netdevice to start +/* visornic_open - enable the visornic device and mark the queue started + * @netdev: netdevice to start. * - * Enable the device and start the transmit queue. - * Return 0 for success + * Enable the device and start the transmit queue. + * + * Return: 0 on success. */ -static int -visornic_open(struct net_device *netdev) +static int visornic_open(struct net_device *netdev) { visornic_enable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT); - return 0; } -/* - * visornic_close - Disables the visornic device and stops the queues - * @netdev: netdevice to start +/* visornic_close - disables the visornic device and stops the queues + * @netdev: netdevice to stop. * - * Disable the device and stop the transmit queue. - * Return 0 for success + * Disable the device and stop the transmit queue. + * + * Return 0 on success. */ -static int -visornic_close(struct net_device *netdev) +static int visornic_close(struct net_device *netdev) { visornic_disable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT); - return 0; } -/* - * devdata_xmits_outstanding - compute outstanding xmits - * @devdata: visornic_devdata for device +/* devdata_xmits_outstanding - compute outstanding xmits + * @devdata: visornic_devdata for device * - * Return value is the number of outstanding xmits. + * Return: Long integer representing the number of outstanding xmits. */ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata) { @@ -787,14 +817,13 @@ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata) + devdata->chstat.sent_xmit + 1); } -/* - * vnic_hit_high_watermark - * @devdata: indicates visornic device we are checking - * @high_watermark: max num of unacked xmits we will tolerate, - * before we will start throttling +/* vnic_hit_high_watermark + * @devdata: Indicates visornic device we are checking. + * @high_watermark: Max num of unacked xmits we will tolerate before we will + * start throttling. * - * Returns true iff the number of unacked xmits sent to - * the IO partition is >= high_watermark. + * Return: True iff the number of unacked xmits sent to the IO Partition is >= + * high_watermark. False otherwise. */ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata, ulong high_watermark) @@ -802,15 +831,13 @@ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata, return (devdata_xmits_outstanding(devdata) >= high_watermark); } -/* - * vnic_hit_low_watermark - * @devdata: indicates visornic device we are checking - * @low_watermark: we will wait until the num of unacked xmits - * drops to this value or lower before we start - * transmitting again +/* vnic_hit_low_watermark + * @devdata: Indicates visornic device we are checking. + * @low_watermark: We will wait until the num of unacked xmits drops to this + * value or lower before we start transmitting again. * - * Returns true iff the number of unacked xmits sent to - * the IO partition is <= low_watermark. + * Return: True iff the number of unacked xmits sent to the IO Partition is <= + * low_watermark. */ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata, ulong low_watermark) @@ -818,20 +845,18 @@ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata, return (devdata_xmits_outstanding(devdata) <= low_watermark); } -/* - * visornic_xmit - send a packet to the IO Partition - * @skb: Packet to be sent - * @netdev: net device the packet is being sent from +/* visornic_xmit - send a packet to the IO Partition + * @skb: Packet to be sent. + * @netdev: Net device the packet is being sent from. + * + * Convert the skb to a cmdrsp so the IO Partition can understand it, and send + * the XMIT command to the IO Partition for processing. This function is + * protected from concurrent calls by a spinlock xmit_lock in the net_device + * struct. As soon as the function returns, it can be called again. * - * Convert the skb to a cmdrsp so the IO Partition can understand it. - * Send the XMIT command to the IO Partition for processing. This - * function is protected from concurrent calls by a spinlock xmit_lock - * in the net_device struct, but as soon as the function returns it - * can be called again. - * Returns NETDEV_TX_OK. + * Return: NETDEV_TX_OK. */ -static int -visornic_xmit(struct sk_buff *skb, struct net_device *netdev) +static int visornic_xmit(struct sk_buff *skb, struct net_device *netdev) { struct visornic_devdata *devdata; int len, firstfraglen, padlen; @@ -938,6 +963,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) * - everything else will be pass in frags & DMA'ed */ memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HLEN); + /* copy frags info - from skb->data we need to only provide access * beyond eth header */ @@ -991,46 +1017,39 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -/* - * visornic_get_stats - returns net_stats of the visornic device - * @netdev: netdevice +/* visornic_get_stats - returns net_stats of the visornic device + * @netdev: netdevice. * - * Returns the net_device_stats for the device + * Return: Pointer to the net_device_stats struct for the device. */ -static struct net_device_stats * -visornic_get_stats(struct net_device *netdev) +static struct net_device_stats *visornic_get_stats(struct net_device *netdev) { struct visornic_devdata *devdata = netdev_priv(netdev); return &devdata->net_stats; } -/* - * visornic_change_mtu - changes mtu of device. - * @netdev: netdevice - * @new_mtu: value of new mtu +/* visornic_change_mtu - changes mtu of device + * @netdev: netdevice. + * @new_mtu: Value of new mtu. + * + * The device's MTU cannot be changed by system; it must be changed via a + * CONTROLVM message. All vnics and pnics in a switch have to have the same MTU + * for everything to work. Currently not supported. * - * MTU cannot be changed by system, must be changed via - * CONTROLVM message. All vnics and pnics in a switch have - * to have the same MTU for everything to work. - * Currently not supported. - * Returns EINVAL + * Return: -EINVAL. */ -static int -visornic_change_mtu(struct net_device *netdev, int new_mtu) +static int visornic_change_mtu(struct net_device *netdev, int new_mtu) { return -EINVAL; } -/* - * visornic_set_multi - changes mtu of device. - * @netdev: netdevice +/* visornic_set_multi - set visornic device flags + * @netdev: netdevice. * - * Only flag we support currently is IFF_PROMISC - * Returns void + * The only flag we currently support is IFF_PROMISC. */ -static void -visornic_set_multi(struct net_device *netdev) +static void visornic_set_multi(struct net_device *netdev) { struct uiscmdrsp *cmdrsp; struct visornic_devdata *devdata = netdev_priv(netdev); @@ -1062,16 +1081,13 @@ visornic_set_multi(struct net_device *netdev) devdata->old_flags = netdev->flags; } -/* - * visornic_xmit_timeout - request to timeout the xmit - * @netdev +/* visornic_xmit_timeout - request to timeout the xmit + * @netdev: netdevice. * - * Queue the work and return. Make sure we have not already - * been informed the IO Partition is gone, if it is gone - * we will already timeout the xmits. + * Queue the work and return. Make sure we have not already been informed that + * the IO Partition is gone; if so, we will have already timed-out the xmits. */ -static void -visornic_xmit_timeout(struct net_device *netdev) +static void visornic_xmit_timeout(struct net_device *netdev) { struct visornic_devdata *devdata = netdev_priv(netdev); unsigned long flags; @@ -1097,20 +1113,20 @@ visornic_xmit_timeout(struct net_device *netdev) spin_unlock_irqrestore(&devdata->priv_lock, flags); } -/* - * repost_return - repost rcv bufs that have come back - * @cmdrsp: io channel command struct to post - * @devdata: visornic devdata for the device - * @skb: skb - * @netdev: netdevice +/* repost_return - repost rcv bufs that have come back + * @cmdrsp: IO channel command struct to post. + * @devdata: Visornic devdata for the device. + * @skb: Socket buffer. + * @netdev: netdevice. + * + * Repost rcv buffers that have been returned to us when we are finished + * with them. * - * Repost rcv buffers that have been returned to us when - * we are finished with them. - * Returns 0 for success, -1 for error. + * Return: 0 for success, negative integer on error. */ -static int -repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, - struct sk_buff *skb, struct net_device *netdev) +static int repost_return(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata, + struct sk_buff *skb, struct net_device *netdev) { struct net_pkt_rcv copy; int i = 0, cc, numreposted; @@ -1174,16 +1190,15 @@ repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, return status; } -/* - * visornic_rx - Handle receive packets coming back from IO Part - * @cmdrsp: Receive packet returned from IO Part +/* visornic_rx - handle receive packets coming back from IO Partition + * @cmdrsp: Receive packet returned from IO Partition. * - * Got a receive packet back from the IO Part, handle it and send - * it up the stack. - * Returns 1 iff an skb was received, otherwise 0 + * Got a receive packet back from the IO Partition; handle it and send it up + * the stack. + + * Return: 1 iff an skb was received, otherwise 0. */ -static int -visornic_rx(struct uiscmdrsp *cmdrsp) +static int visornic_rx(struct uiscmdrsp *cmdrsp) { struct visornic_devdata *devdata; struct sk_buff *skb, *prev, *curr; @@ -1236,7 +1251,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp) * firstfrag & set data_len to show rest see if we have to chain * frag_list. */ - if (skb->len > RCVPOST_BUF_SIZE) { /* do PRECAUTIONARY check */ + /* do PRECAUTIONARY check */ + if (skb->len > RCVPOST_BUF_SIZE) { if (cmdrsp->net.rcv.numrcvbufs < 2) { if (repost_return(cmdrsp, devdata, skb, netdev) < 0) dev_err(&devdata->netdev->dev, @@ -1244,23 +1260,24 @@ visornic_rx(struct uiscmdrsp *cmdrsp) return 0; } /* length rcvd is greater than firstfrag in this skb rcv buf */ - skb->tail += RCVPOST_BUF_SIZE; /* amount in skb->data */ - skb->data_len = skb->len - RCVPOST_BUF_SIZE; /* amount that - * will be in - * frag_list - */ + /* amount in skb->data */ + skb->tail += RCVPOST_BUF_SIZE; + /* amount that will be in frag_list */ + skb->data_len = skb->len - RCVPOST_BUF_SIZE; } else { /* data fits in this skb - no chaining - do * PRECAUTIONARY check */ - if (cmdrsp->net.rcv.numrcvbufs != 1) { /* should be 1 */ + /* should be 1 */ + if (cmdrsp->net.rcv.numrcvbufs != 1) { if (repost_return(cmdrsp, devdata, skb, netdev) < 0) dev_err(&devdata->netdev->dev, "repost_return failed"); return 0; } skb->tail += skb->len; - skb->data_len = 0; /* nothing rcvd in frag_list */ + /* nothing rcvd in frag_list */ + skb->data_len = 0; } off = skb_tail_pointer(skb) - skb->data; @@ -1286,7 +1303,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp) cc < cmdrsp->net.rcv.numrcvbufs; cc++) { curr = (struct sk_buff *)cmdrsp->net.rcv.rcvbuf[cc]; curr->next = NULL; - if (!prev) /* start of list- set head */ + /* start of list- set head */ + if (!prev) skb_shinfo(skb)->frag_list = curr; else prev->next = curr; @@ -1314,18 +1332,18 @@ visornic_rx(struct uiscmdrsp *cmdrsp) * sets up skb->pkt_type & it also PULLS out the eth header */ skb->protocol = eth_type_trans(skb, netdev); - eth = eth_hdr(skb); - skb->csum = 0; skb->ip_summed = CHECKSUM_NONE; do { + /* accept all packets */ if (netdev->flags & IFF_PROMISC) - break; /* accept all packets */ + break; if (skb->pkt_type == PACKET_BROADCAST) { + /* accept all broadcast packets */ if (netdev->flags & IFF_BROADCAST) - break; /* accept all broadcast packets */ + break; } else if (skb->pkt_type == PACKET_MULTICAST) { if ((netdev->flags & IFF_MULTICAST) && (netdev_mc_count(netdev))) { @@ -1367,8 +1385,7 @@ visornic_rx(struct uiscmdrsp *cmdrsp) */ skb = NULL; - /* - * whether the packet got dropped or handled, the skb is freed by + /* whether the packet got dropped or handled, the skb is freed by * kernel code, so we shouldn't free it. but we should repost a * new rcv buffer. */ @@ -1376,29 +1393,25 @@ visornic_rx(struct uiscmdrsp *cmdrsp) return 1; } -/* - * devdata_initialize - Initialize devdata structure - * @devdata: visornic_devdata structure to initialize - * #dev: visorbus_deviced it belongs to +/* devdata_initialize - initialize devdata structure + * @devdata: visornic_devdata structure to initialize. + * @dev: visorbus_device it belongs to. * - * Setup initial values for the visornic based on channel and default - * values. - * Returns a pointer to the devdata structure + * Setup initial values for the visornic, based on channel and default values. + * + * Return: A pointer to the devdata structure. */ -static struct visornic_devdata * -devdata_initialize(struct visornic_devdata *devdata, struct visor_device *dev) +static struct visornic_devdata *devdata_initialize( + struct visornic_devdata *devdata, + struct visor_device *dev) { devdata->dev = dev; devdata->incarnation_id = get_jiffies_64(); return devdata; } -/* - * devdata_release - Frees up references in devdata - * @devdata: struct to clean up - * - * Frees up references in devdata. - * Returns void +/* devdata_release - free up references in devdata + * @devdata: Struct to clean up. */ static void devdata_release(struct visornic_devdata *devdata) { @@ -1570,15 +1583,10 @@ static const struct file_operations debugfs_info_fops = { .read = info_debugfs_read, }; -/* - * send_rcv_posts_if_needed - * @devdata: visornic device - * - * Send receive buffers to the IO Partition. - * Returns void +/* send_rcv_posts_if_needed - send receive buffers to the IO Partition. + * @devdata: Visornic device. */ -static int -send_rcv_posts_if_needed(struct visornic_devdata *devdata) +static void send_rcv_posts_if_needed(struct visornic_devdata *devdata) { int i; struct net_device *netdev; @@ -1588,7 +1596,7 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata) /* don't do this until vnic is marked ready */ if (!(devdata->enabled && devdata->enab_dis_acked)) - return 0; + return; netdev = devdata->netdev; rcv_bufs_allocated = 0; @@ -1617,16 +1625,14 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata) } } devdata->num_rcv_bufs_could_not_alloc -= rcv_bufs_allocated; - return 0; } -/* - * drain_resp_queue - drains and ignores all messages from the resp queue - * @cmdrsp: io channel command response message - * @devdata: visornic device to drain +/* drain_resp_queue - drains and ignores all messages from the resp queue + * @cmdrsp: IO channel command response message. + * @devdata: Visornic device to drain. */ -static void -drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) +static void drain_resp_queue(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata) { while (!visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, @@ -1634,30 +1640,31 @@ drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) ; } -/* - * service_resp_queue - drains the response queue - * @cmdrsp: io channel command response message - * @devdata: visornic device to drain +/* service_resp_queue - drain the response queue + * @cmdrsp: IO channel command response message. + * @devdata: Visornic device to drain. + * @rx_work_done: + * @budget: * - * Drain the response queue of any responses from the IO partition. - * Process the responses as we get them. - * Returns when response queue is empty or when the thread stops. + * Drain the response queue of any responses from the IO Partition. Process the + * responses as we get them. */ -static void -service_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, - int *rx_work_done, int budget) +static void service_resp_queue(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata, + int *rx_work_done, int budget) { unsigned long flags; struct net_device *netdev; while (*rx_work_done < budget) { - /* TODO: CLIENT ACQUIRE -- Don't really need this at the - * moment - */ + /* TODO: CLIENT ACQUIRE -- Don't really need this at the + * moment + */ + /* queue empty */ if (visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, cmdrsp)) - break; /* queue empty */ + break; switch (cmdrsp->net.type) { case NET_RCV: @@ -1740,12 +1747,8 @@ static int visornic_poll(struct napi_struct *napi, int budget) struct visornic_devdata, napi); int rx_count = 0; - int err; - - err = send_rcv_posts_if_needed(devdata); - if (err) - return err; + send_rcv_posts_if_needed(devdata); service_resp_queue(devdata->cmdrsp, devdata, &rx_count, budget); /* If there aren't any more packets to receive stop the poll */ @@ -1755,16 +1758,13 @@ static int visornic_poll(struct napi_struct *napi, int budget) return rx_count; } -/* - * poll_for_irq - Checks the status of the response queue. - * @v: void pointer to the visronic devdata +/* poll_for_irq - checks the status of the response queue + * @v: Void pointer to the visronic devdata struct. * - * Main function of the vnic_incoming thread. Periodically check the - * response queue and drain it if needed. - * Returns when thread has stopped. + * Main function of the vnic_incoming thread. Periodically check the response + * queue and drain it if needed. */ -static void -poll_for_irq(unsigned long v) +static void poll_for_irq(unsigned long v) { struct visornic_devdata *devdata = (struct visornic_devdata *)v; @@ -1778,13 +1778,13 @@ poll_for_irq(unsigned long v) mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); } -/* - * visornic_probe - probe function for visornic devices - * @dev: The visor device discovered +/* visornic_probe - probe function for visornic devices + * @dev: The visor device discovered. + * + * Called when visorbus discovers a visornic device on its bus. It creates a new + * visornic ethernet adapter. * - * Called when visorbus discovers a visornic device on its - * bus. It creates a new visornic ethernet adapter. - * Returns 0 or negative for error. + * Return: 0 on success, or negative integer on error. */ static int visornic_probe(struct visor_device *dev) { @@ -1831,7 +1831,8 @@ static int visornic_probe(struct visor_device *dev) dev_set_drvdata(&dev->device, devdata); init_waitqueue_head(&devdata->rsp_queue); spin_lock_init(&devdata->priv_lock); - devdata->enabled = 0; /* not yet */ + /* not yet */ + devdata->enabled = 0; atomic_set(&devdata->usage, 1); /* Setup rcv bufs */ @@ -1852,9 +1853,10 @@ static int visornic_probe(struct visor_device *dev) goto cleanup_netdev; } - /* set the net_xmit outstanding threshold */ - /* always leave two slots open but you should have 3 at a minimum */ - /* note that max_outstanding_net_xmits must be > 0 */ + /* set the net_xmit outstanding threshold + * always leave two slots open but you should have 3 at a minimum + * note that max_outstanding_net_xmits must be > 0 + */ devdata->max_outstanding_net_xmits = max_t(unsigned long, 3, ((devdata->num_rcv_bufs / 3) - 2)); devdata->upper_threshold_net_xmits = @@ -1972,28 +1974,25 @@ static int visornic_probe(struct visor_device *dev) return err; } -/* - * host_side_disappeared - IO part is gone. - * @devdata: device object +/* host_side_disappeared - IO Partition is gone + * @devdata: Device object. * - * IO partition servicing this device is gone, do cleanup - * Returns void. + * IO partition servicing this device is gone; do cleanup. */ static void host_side_disappeared(struct visornic_devdata *devdata) { unsigned long flags; spin_lock_irqsave(&devdata->priv_lock, flags); - devdata->dev = NULL; /* indicate device destroyed */ + /* indicate device destroyed */ + devdata->dev = NULL; spin_unlock_irqrestore(&devdata->priv_lock, flags); } -/* - * visornic_remove - Called when visornic dev goes away - * @dev: visornic device that is being removed +/* visornic_remove - called when visornic dev goes away + * @dev: Visornic device that is being removed. * - * Called when DEVICE_DESTROY gets called to remove device. - * Returns void + * Called when DEVICE_DESTROY gets called to remove device. */ static void visornic_remove(struct visor_device *dev) { @@ -2023,8 +2022,8 @@ static void visornic_remove(struct visor_device *dev) cancel_work_sync(&devdata->timeout_reset); debugfs_remove_recursive(devdata->eth_debugfs_dir); - - unregister_netdev(netdev); /* this will call visornic_close() */ + /* this will call visornic_close() */ + unregister_netdev(netdev); del_timer_sync(&devdata->irq_poll_timer); netif_napi_del(&devdata->napi); @@ -2035,18 +2034,17 @@ static void visornic_remove(struct visor_device *dev) free_netdev(netdev); } -/* - * visornic_pause - Called when IO Part disappears - * @dev: visornic device that is being serviced - * @complete_func: call when finished. +/* visornic_pause - called when IO Part disappears + * @dev: Visornic device that is being serviced. + * @complete_func: Call when finished. + * + * Called when the IO Partition has gone down. Need to free up resources and + * wait for IO partition to come back. Mark link as down and don't attempt any + * DMA. When we have freed memory, call the complete_func so that Command knows + * we are done. If we don't call complete_func, the IO Partition will never + * come back. * - * Called when the IO Partition has gone down. Need to free - * up resources and wait for IO partition to come back. Mark - * link as down and don't attempt any DMA. When we have freed - * memory call the complete_func so that Command knows we are - * done. If we don't call complete_func, IO part will never - * come back. - * Returns 0 for success. + * Return: 0 on success. */ static int visornic_pause(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -2057,15 +2055,14 @@ static int visornic_pause(struct visor_device *dev, return 0; } -/* - * visornic_resume - Called when IO part has recovered - * @dev: visornic device that is being serviced - * @compelte_func: call when finished +/* visornic_resume - called when IO Partition has recovered + * @dev: Visornic device that is being serviced. + * @compelte_func: Call when finished. + * + * Called when the IO partition has recovered. Re-establish connection to the IO + * Partition and set the link up. Okay to do DMA again. * - * Called when the IO partition has recovered. Reestablish - * connection to the IO part and set the link up. Okay to do - * DMA again. - * Returns 0 for success. + * Returns 0 for success, negative integer on error. */ static int visornic_resume(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -2127,12 +2124,12 @@ static struct visor_driver visornic_driver = { .channel_interrupt = NULL, }; -/* - * visornic_init - Init function +/* visornic_init - init function * - * Init function for the visornic driver. Do initial driver setup - * and wait for devices. - * Returns 0 for success, negative for error. + * Init function for the visornic driver. Do initial driver setup and wait + * for devices. + * + * Return: 0 on success, negative integer on error. */ static int visornic_init(void) { @@ -2160,19 +2157,16 @@ static int visornic_init(void) cleanup_debugfs: debugfs_remove_recursive(visornic_debugfs_dir); - return err; } -/* - * visornic_cleanup - driver exit routine +/* visornic_cleanup - driver exit routine * - * Unregister driver from the bus and free up memory. + * Unregister driver from the bus and free up memory. */ static void visornic_cleanup(void) { visorbus_unregister_visor_driver(&visornic_driver); - debugfs_remove_recursive(visornic_debugfs_dir); } diff --git a/drivers/staging/vboxvideo/Kconfig b/drivers/staging/vboxvideo/Kconfig index a52746f9a670b6d4afde417c171c95e0826c810e..1f4182e2e980ad5cf1617d360125ca9de7efa68e 100644 --- a/drivers/staging/vboxvideo/Kconfig +++ b/drivers/staging/vboxvideo/Kconfig @@ -2,11 +2,14 @@ config DRM_VBOXVIDEO tristate "Virtual Box Graphics Card" depends on DRM && X86 && PCI select DRM_KMS_HELPER + select DRM_TTM + select GENERIC_ALLOCATOR help This is a KMS driver for the virtual Graphics Card used in Virtual Box virtual machines. - Although it is possible to builtin this module, it is advised - to build this driver as a module, so that it can be updated - independently of the kernel. Select M to built this driver as a - module and add support for these devices via drm/kms interfaces. + Although it is possible to build this driver built-in to the + kernel, it is advised to build it as a module, so that it can + be updated independently of the kernel. Select M to build this + driver as a module and add support for these devices via drm/kms + interfaces. diff --git a/drivers/staging/vboxvideo/TODO b/drivers/staging/vboxvideo/TODO index ce764309b079b4e22aaa57c14efda2f4bbb8751d..bd381d861ab3902975c24a30b1b48cee4caef71f 100644 --- a/drivers/staging/vboxvideo/TODO +++ b/drivers/staging/vboxvideo/TODO @@ -5,5 +5,5 @@ TODO: -Extend this TODO with the results of that review Please send any patches to Greg Kroah-Hartman , -Hans de Goede and -Michael Thayer . +Hans de Goede , Michael Thayer +and dri-devel@lists.freedesktop.org . diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index 92ae1560a16db685a96da6e61442d955dbdeba8e..e18642e5027edb57ef144d5484834642178a750b 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -36,7 +36,7 @@ #include "vbox_drv.h" -int vbox_modeset = -1; +static int vbox_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, vbox_modeset, int, 0400); @@ -232,7 +232,6 @@ static struct drm_driver driver = { .lastclose = vbox_driver_lastclose, .master_set = vbox_master_set, .master_drop = vbox_master_drop, - .set_busid = drm_pci_set_busid, .fops = &vbox_fops, .irq_handler = vbox_irq_handler, @@ -270,12 +269,12 @@ static int __init vbox_init(void) if (vbox_modeset == 0) return -EINVAL; - return drm_pci_init(&driver, &vbox_pci_driver); + return pci_register_driver(&vbox_pci_driver); } static void __exit vbox_exit(void) { - drm_pci_exit(&driver, &vbox_pci_driver); + pci_unregister_driver(&vbox_pci_driver); } module_init(vbox_init); diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 35f6d9f8c203845a44111fcff6dda469fd567cdb..8aed248db6e2330c08fe7c9f2673f9b2485b5e76 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -45,144 +45,20 @@ #include "vbox_drv.h" #include "vboxvideo.h" -#define VBOX_DIRTY_DELAY (HZ / 30) -/** - * Tell the host about dirty rectangles to update. - */ -static void vbox_dirty_update(struct vbox_fbdev *fbdev, - int x, int y, int width, int height) -{ - struct drm_gem_object *obj; - struct vbox_bo *bo; - int ret = -EBUSY; - bool store_for_later = false; - int x2, y2; - unsigned long flags; - struct drm_clip_rect rect; - - obj = fbdev->afb.obj; - bo = gem_to_vbox_bo(obj); - - /* - * try and reserve the BO, if we fail with busy - * then the BO is being moved and we should - * store up the damage until later. - */ - if (drm_can_sleep()) - ret = vbox_bo_reserve(bo, true); - if (ret) { - if (ret != -EBUSY) - return; - - store_for_later = true; - } - - x2 = x + width - 1; - y2 = y + height - 1; - spin_lock_irqsave(&fbdev->dirty_lock, flags); - - if (fbdev->y1 < y) - y = fbdev->y1; - if (fbdev->y2 > y2) - y2 = fbdev->y2; - if (fbdev->x1 < x) - x = fbdev->x1; - if (fbdev->x2 > x2) - x2 = fbdev->x2; - - if (store_for_later) { - fbdev->x1 = x; - fbdev->x2 = x2; - fbdev->y1 = y; - fbdev->y2 = y2; - spin_unlock_irqrestore(&fbdev->dirty_lock, flags); - return; - } - - fbdev->x1 = INT_MAX; - fbdev->y1 = INT_MAX; - fbdev->x2 = 0; - fbdev->y2 = 0; - - spin_unlock_irqrestore(&fbdev->dirty_lock, flags); - - /* - * Not sure why the original code subtracted 1 here, but I will keep - * it that way to avoid unnecessary differences. - */ - rect.x1 = x; - rect.x2 = x2 + 1; - rect.y1 = y; - rect.y2 = y2 + 1; - vbox_framebuffer_dirty_rectangles(&fbdev->afb.base, &rect, 1); - - vbox_bo_unreserve(bo); -} - -#ifdef CONFIG_FB_DEFERRED_IO -static void vbox_deferred_io(struct fb_info *info, struct list_head *pagelist) -{ - struct vbox_fbdev *fbdev = info->par; - unsigned long start, end, min, max; - struct page *page; - int y1, y2; - - min = ULONG_MAX; - max = 0; - list_for_each_entry(page, pagelist, lru) { - start = page->index << PAGE_SHIFT; - end = start + PAGE_SIZE - 1; - min = min(min, start); - max = max(max, end); - } - - if (min < max) { - y1 = min / info->fix.line_length; - y2 = (max / info->fix.line_length) + 1; - DRM_INFO("%s: Calling dirty update: 0, %d, %d, %d\n", - __func__, y1, info->var.xres, y2 - y1 - 1); - vbox_dirty_update(fbdev, 0, y1, info->var.xres, y2 - y1 - 1); - } -} - +#ifdef CONFIG_DRM_KMS_FB_HELPER static struct fb_deferred_io vbox_defio = { - .delay = VBOX_DIRTY_DELAY, - .deferred_io = vbox_deferred_io, + .delay = HZ / 30, + .deferred_io = drm_fb_helper_deferred_io, }; #endif -static void vbox_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct vbox_fbdev *fbdev = info->par; - - sys_fillrect(info, rect); - vbox_dirty_update(fbdev, rect->dx, rect->dy, rect->width, rect->height); -} - -static void vbox_copyarea(struct fb_info *info, const struct fb_copyarea *area) -{ - struct vbox_fbdev *fbdev = info->par; - - sys_copyarea(info, area); - vbox_dirty_update(fbdev, area->dx, area->dy, area->width, area->height); -} - -static void vbox_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct vbox_fbdev *fbdev = info->par; - - sys_imageblit(info, image); - vbox_dirty_update(fbdev, image->dx, image->dy, image->width, - image->height); -} - static struct fb_ops vboxfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = vbox_fillrect, - .fb_copyarea = vbox_copyarea, - .fb_imageblit = vbox_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -219,7 +95,6 @@ static int vboxfb_create(struct drm_fb_helper *helper, struct DRM_MODE_FB_CMD mode_cmd; struct drm_framebuffer *fb; struct fb_info *info; - struct device *device = &dev->pdev->dev; struct drm_gem_object *gobj; struct vbox_bo *bo; int size, ret; @@ -263,16 +138,16 @@ static int vboxfb_create(struct drm_fb_helper *helper, return ret; } - info = framebuffer_alloc(0, device); - if (!info) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return -PTR_ERR(info); + info->par = fbdev; fbdev->size = size; fb = &fbdev->afb.base; fbdev->helper.fb = fb; - fbdev->helper.fbdev = info; strcpy(info->fix.id, "vboxdrmfb"); @@ -284,17 +159,10 @@ static int vboxfb_create(struct drm_fb_helper *helper, FBINFO_MISC_ALWAYS_SETPAR; info->fbops = &vboxfb_ops; - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) - return -ENOMEM; - /* * This seems to be done for safety checking that the framebuffer * is not registered twice by different drivers. */ - info->apertures = alloc_apertures(1); - if (!info->apertures) - return -ENOMEM; info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); @@ -305,7 +173,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, info->screen_base = bo->kmap.virtual; info->screen_size = size; -#ifdef CONFIG_FB_DEFERRED_IO +#ifdef CONFIG_DRM_KMS_FB_HELPER info->fbdefio = &vbox_defio; fb_deferred_io_init(info); #endif @@ -317,22 +185,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, return 0; } -static void vbox_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ -} - -static void vbox_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - *red = regno; - *green = regno; - *blue = regno; -} - static struct drm_fb_helper_funcs vbox_fb_helper_funcs = { - .gamma_set = vbox_fb_gamma_set, - .gamma_get = vbox_fb_gamma_get, .fb_probe = vboxfb_create, }; @@ -342,6 +195,11 @@ void vbox_fbdev_fini(struct drm_device *dev) struct vbox_fbdev *fbdev = vbox->fbdev; struct vbox_framebuffer *afb = &fbdev->afb; +#ifdef CONFIG_DRM_KMS_FB_HELPER + if (fbdev->helper.fbdev && fbdev->helper.fbdev->fbdefio) + fb_deferred_io_cleanup(fbdev->helper.fbdev); +#endif + drm_fb_helper_unregister_fbi(&fbdev->helper); if (afb->obj) { @@ -358,7 +216,7 @@ void vbox_fbdev_fini(struct drm_device *dev) vbox_bo_unpin(bo); vbox_bo_unreserve(bo); } - drm_gem_object_unreference_unlocked(afb->obj); + drm_gem_object_put_unlocked(afb->obj); afb->obj = NULL; } drm_fb_helper_fini(&fbdev->helper); diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index d0c6ec75a3c719f64cb19f6a42cb91b2c7c2af34..80bd039fa08e9178e19ec876493f9cb64c324e88 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -40,7 +40,7 @@ static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb) struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb); if (vbox_fb->obj) - drm_gem_object_unreference_unlocked(vbox_fb->obj); + drm_gem_object_put_unlocked(vbox_fb->obj); drm_framebuffer_cleanup(fb); kfree(fb); @@ -198,7 +198,7 @@ static struct drm_framebuffer *vbox_user_framebuffer_create( err_free_vbox_fb: kfree(vbox_fb); err_unref_obj: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR(ret); } @@ -472,7 +472,7 @@ int vbox_dumb_create(struct drm_file *file, return ret; ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) return ret; @@ -525,7 +525,7 @@ vbox_dumb_mmap_offset(struct drm_file *file, bo = gem_to_vbox_bo(obj); *offset = vbox_bo_mmap_offset(bo); - drm_gem_object_unreference(obj); + drm_gem_object_put(obj); ret = 0; out_unlock: diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index f2b85f3256fab74a55397ce48fb78338744ee58e..257a778304107240763b338eeaee07b45c4cf700 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -54,14 +54,12 @@ static void vbox_do_modeset(struct drm_crtc *crtc, struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); struct vbox_private *vbox; int width, height, bpp, pitch; - unsigned int crtc_id; u16 flags; s32 x_offset, y_offset; vbox = crtc->dev->dev_private; width = mode->hdisplay ? mode->hdisplay : 640; height = mode->vdisplay ? mode->vdisplay : 480; - crtc_id = vbox_crtc->crtc_id; bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32; pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8; x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint; @@ -134,10 +132,6 @@ static int vbox_set_view(struct drm_crtc *crtc) return 0; } -static void vbox_crtc_load_lut(struct drm_crtc *crtc) -{ -} - static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); @@ -330,7 +324,6 @@ static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = { .mode_set = vbox_crtc_mode_set, /* .mode_set_base = vbox_crtc_mode_set_base, */ .disable = vbox_crtc_disable, - .load_lut = vbox_crtc_load_lut, .prepare = vbox_crtc_prepare, .commit = vbox_crtc_commit, }; @@ -578,9 +571,6 @@ static int vbox_mode_valid(struct drm_connector *connector, static void vbox_connector_destroy(struct drm_connector *connector) { - struct vbox_connector *vbox_connector; - - vbox_connector = to_vbox_connector(connector); drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); @@ -817,7 +807,7 @@ static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, out_unreserve_bo: vbox_bo_unreserve(bo); out_unref_obj: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index 34a905d40735feeec3e84536ace30131efd75565..4eb410a2a1a830a3889371e702a561cb296f566e 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -230,7 +230,7 @@ static void vbox_ttm_tt_unpopulate(struct ttm_tt *ttm) ttm_pool_unpopulate(ttm); } -struct ttm_bo_driver vbox_bo_driver = { +static struct ttm_bo_driver vbox_bo_driver = { .ttm_tt_create = vbox_ttm_tt_create, .ttm_tt_populate = vbox_ttm_tt_populate, .ttm_tt_unpopulate = vbox_ttm_tt_unpopulate, diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index 3637ddf909a4c2fce59e5c2f34d345925435a7f3..94654c0c7bba572f551e2e018cc57396b457b371 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c @@ -20,7 +20,7 @@ #include "bcm2835.h" /* hardware definition */ -static struct snd_pcm_hardware snd_bcm2835_playback_hw = { +static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, @@ -36,7 +36,7 @@ static struct snd_pcm_hardware snd_bcm2835_playback_hw = { .periods_max = 128, }; -static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { +static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S16_LE, @@ -438,7 +438,7 @@ static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, } /* operators */ -static struct snd_pcm_ops snd_bcm2835_playback_ops = { +static const struct snd_pcm_ops snd_bcm2835_playback_ops = { .open = snd_bcm2835_playback_open, .close = snd_bcm2835_playback_close, .ioctl = snd_bcm2835_pcm_lib_ioctl, @@ -450,7 +450,7 @@ static struct snd_pcm_ops snd_bcm2835_playback_ops = { .ack = snd_bcm2835_pcm_ack, }; -static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { +static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { .open = snd_bcm2835_playback_spdif_open, .close = snd_bcm2835_playback_close, .ioctl = snd_bcm2835_pcm_lib_ioctl, diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index a11e047734f954b9e9d3f1ec3ed24dfa5596b118..be936b8fe317599b132988f0a700ec7f7df15af6 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -642,7 +642,7 @@ static void bm2835_mmal_unlock(struct vb2_queue *vq) mutex_unlock(&dev->mutex); } -static struct vb2_ops bm2835_mmal_video_qops = { +static const struct vb2_ops bm2835_mmal_video_qops = { .queue_setup = queue_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, @@ -1456,7 +1456,7 @@ static const struct v4l2_file_operations camera0_fops = { .mmap = vb2_fop_mmap, }; -static struct video_device vdev_template = { +static const struct video_device vdev_template = { .name = "camera0", .fops = &camera0_fops, .ioctl_ops = &camera0_ioctl_ops, diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 0159ca4407d8a8faeba3918e260986fdc1c120c8..be08849175ea3622321136f3be66df8705e40772 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -612,18 +612,20 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, if (head_bytes > actual) head_bytes = actual; - memcpy((char *)page_address(pages[0]) + + memcpy((char *)kmap(pages[0]) + pagelist->offset, fragments, head_bytes); + kunmap(pages[0]); } if ((actual >= 0) && (head_bytes < actual) && (tail_bytes != 0)) { - memcpy((char *)page_address(pages[num_pages - 1]) + + memcpy((char *)kmap(pages[num_pages - 1]) + ((pagelist->offset + actual) & (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), fragments + g_cache_line_size, tail_bytes); + kunmap(pages[num_pages - 1]); } down(&g_free_fragments_mutex); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c index 7fa0310e7b9e3afd43f6cd665fa5732d1350599b..2e52f07bbaa97ee773d8acc49758c7306a5b7c66 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c @@ -51,7 +51,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size) sema_init(&queue->pop, 0); sema_init(&queue->push, 0); - queue->storage = kzalloc(size * sizeof(VCHIQ_HEADER_T *), GFP_KERNEL); + queue->storage = kcalloc(size, sizeof(VCHIQ_HEADER_T *), GFP_KERNEL); if (!queue->storage) { vchiu_queue_delete(queue); return 0; diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index f5db2b3d9045b85293fac3872acb00e3fa26ffbf..14034e342aa648df43a204c5b2d4eaeac7ca9ecc 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -649,19 +649,19 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, pr_debug("BASIC RATE: %X\n", priv->basic_rates); if (!CARDbIsOFDMinBasicRate((void *)priv)) { - pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); + pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx); if (wRateIdx > RATE_24M) wRateIdx = RATE_24M; return wRateIdx; } while (ui > RATE_11M) { if (priv->basic_rates & ((u32)0x1 << ui)) { - pr_debug("CARDwGetOFDMControlRate : %d\n", ui); + pr_debug("%s : %d\n", __func__, ui); return (unsigned short)ui; } ui--; } - pr_debug("CARDwGetOFDMControlRate: 6M\n"); + pr_debug("%s: 6M\n", __func__); return (unsigned short)RATE_24M; } diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 4aaa99bafcda4d96ab10733245c2dda4752df202..f7550b215f72d11d40c7129dda653945eb788cdf 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -809,7 +809,7 @@ void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl, if (byLocalID <= 1) return; - pr_debug("MACvSetKeyEntry\n"); + pr_debug("%s\n", __func__); offset = MISCFIFO_KEYETRY0; offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 4832666cc580eca1b417f4132a115f244b1b0363..74715c85485600c27b34b303e11b6c389698d9ba 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -83,7 +83,7 @@ #define CONFIG_PATH "/etc/vntconfiguration.dat" #define MAX_UINTS 8 -#define OPTION_DEFAULT { [0 ... MAX_UINTS-1] = -1} +#define OPTION_DEFAULT { [0 ... MAX_UINTS - 1] = -1} #define DUPLICATE_RX_CACHE_LENGTH 5 diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 282f665aacfa3ddc4cd34743b89fbcd9ed2bc125..093a6048bd223f0fb9898b17f3f51be3bfd88421 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -65,7 +65,7 @@ int vnt_download_firmware(struct vnt_private *priv) status = vnt_control_out(priv, 0, - 0x1200+ii, + 0x1200 + ii, 0x0000, length, buffer); diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 906d3454591d0674dff156422db6b0a683f1d2d1..cfc6c21315366898079a08c3d0eb49e7a14f9f50 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -46,6 +46,6 @@ int vnt_key_init_table(struct vnt_private *priv); int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - struct ieee80211_vif *vif, struct ieee80211_key_conf *key); + struct ieee80211_vif *vif, struct ieee80211_key_conf *key); #endif /* __KEY_H__ */ diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 095b8556730647718aba67bb8100aacfd3c68fee..cc6d8778fe5ba89220dd60e5b878a7bf5dc7c5f6 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -419,8 +419,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) int ii; for (ii = 0; ii < priv->num_tx_context; ii++) { - tx_context = kmalloc(sizeof(struct vnt_usb_send_context), - GFP_KERNEL); + tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL); if (!tx_context) goto free_tx; @@ -437,7 +436,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) } for (ii = 0; ii < priv->num_rcb; ii++) { - priv->rcb[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL); + priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL); if (!priv->rcb[ii]) { dev_err(&priv->usb->dev, "failed to allocate rcb no %d\n", ii); diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index e322b7d8c6170fb0a53649328b90a244799b213d..c466e0614bc4c223fef81f8dcc9b869682b9008c 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -74,16 +74,15 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE); if (listen_interval >= 2) { - /* clear always listen beacon */ vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN); /* first time set listen next beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN); - } else - + } else { /* always listen beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN); + } dev_dbg(&priv->usb->dev, "PS:Power Saving Mode Enable...\n"); } @@ -100,7 +99,6 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) void vnt_disable_power_saving(struct vnt_private *priv) { - /* disable power saving hw function */ vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0, 0, 0, NULL); diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 23581afb42112443a56341eb475075d344ae0745..3a9d19a0b84284926ddab622fd8ae4ba2d85e15b 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -611,7 +611,7 @@ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data) reg_data[3] = (u8)(data >> 24); vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, - 0, 0, ARRAY_SIZE(reg_data), reg_data); + 0, 0, ARRAY_SIZE(reg_data), reg_data); return true; } @@ -643,9 +643,9 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel) case RATE_48M: case RATE_54M: if (channel > CB_MAX_CHANNEL_24G) - power = priv->ofdm_a_pwr_tbl[channel-15]; + power = priv->ofdm_a_pwr_tbl[channel - 15]; else - power = priv->ofdm_pwr_tbl[channel-1]; + power = priv->ofdm_pwr_tbl[channel - 1]; break; } diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index dc11a05be8c43945f9fac1ab4745eaf1006569e7..23eaef45855629e052a84725109627be0f6bf0da 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -44,7 +44,7 @@ #define USB_CTL_WAIT 500 /* ms */ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) + u16 index, u16 length, u8 *buffer) { int status = 0; u8 *usb_buffer; @@ -82,7 +82,7 @@ void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) } int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) + u16 index, u16 length, u8 *buffer) { int status; u8 *usb_buffer; diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 2568dfc151819acd0806b7e6627d13e1334f7d25..7b620658ec3847fa7a1b4df0a3a7bd23c4e1c7a5 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1963,7 +1963,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wilc_get_vif_idx(vif)); if (result) { - netdev_err(vif->ndev, "Failed to SET incative time\n"); + netdev_err(vif->ndev, "Failed to SET inactive time\n"); return -EFAULT; } @@ -1976,7 +1976,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wilc_get_vif_idx(vif)); if (result) { - netdev_err(vif->ndev, "Failed to get incative time\n"); + netdev_err(vif->ndev, "Failed to get inactive time\n"); return -EFAULT; } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index dbb3e24615bedcebb70e10506e9ea3b71b64ba9e..119f3459b5bbf3f49c41179053d87fa36f1780d4 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -283,7 +283,8 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) static int linux_wlan_txq_task(void *vp) { - int ret, txq_count; + int ret; + u32 txq_count; struct wilc_vif *vif; struct wilc *wl; struct net_device *dev = vp; @@ -812,7 +813,7 @@ int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif) wilc_wlan_cleanup(dev); _fail_locks_: wlan_deinit_locks(dev); - netdev_err(dev, "WLAN Iinitialization FAILED\n"); + netdev_err(dev, "WLAN initialization FAILED\n"); } else { netdev_dbg(dev, "wilc1000 already initialized\n"); } diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 68fd5b3b8b2dc05737bed9d52bfca0c56dcf9772..ac5aaafa461cf33a0ff4cbb772b3fe70a3f5ca9a 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -214,48 +214,39 @@ static u32 get_rssi_avg(struct network_info *network_info) return rssi_v; } -static void refresh_scan(void *user_void, u8 all, bool direct_scan) +static void refresh_scan(struct wilc_priv *priv, bool direct_scan) { - struct wilc_priv *priv; - struct wiphy *wiphy; - struct cfg80211_bss *bss = NULL; + struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; int i; - int rssi = 0; - - priv = user_void; - wiphy = priv->dev->ieee80211_ptr->wiphy; for (i = 0; i < last_scanned_cnt; i++) { struct network_info *network_info; + s32 freq; + struct ieee80211_channel *channel; + int rssi; + struct cfg80211_bss *bss; network_info = &last_scanned_shadow[i]; - if (!network_info->found || all) { - s32 freq; - struct ieee80211_channel *channel; - - if (network_info) { - freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ); - channel = ieee80211_get_channel(wiphy, freq); - - rssi = get_rssi_avg(network_info); - if (memcmp("DIRECT-", network_info->ssid, 7) || - direct_scan) { - bss = cfg80211_inform_bss(wiphy, - channel, - CFG80211_BSS_FTYPE_UNKNOWN, - network_info->bssid, - network_info->tsf_hi, - network_info->cap_info, - network_info->beacon_period, - (const u8 *)network_info->ies, - (size_t)network_info->ies_len, - (s32)rssi * 100, - GFP_KERNEL); - cfg80211_put_bss(wiphy, bss); - } - } - } + if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan) + continue; + + freq = ieee80211_channel_to_frequency((s32)network_info->ch, + NL80211_BAND_2GHZ); + channel = ieee80211_get_channel(wiphy, freq); + rssi = get_rssi_avg(network_info); + bss = cfg80211_inform_bss(wiphy, + channel, + CFG80211_BSS_FTYPE_UNKNOWN, + network_info->bssid, + network_info->tsf_hi, + network_info->cap_info, + network_info->beacon_period, + (const u8 *)network_info->ies, + (size_t)network_info->ies_len, + (s32)rssi * 100, + GFP_KERNEL); + cfg80211_put_bss(wiphy, bss); } } @@ -442,7 +433,7 @@ static void CfgScanResult(enum scan_event scan_event, } } } else if (scan_event == SCAN_EVENT_DONE) { - refresh_scan(priv, 1, false); + refresh_scan(priv, false); mutex_lock(&priv->scan_req_lock); @@ -466,7 +457,7 @@ static void CfgScanResult(enum scan_event scan_event, }; update_scan_time(); - refresh_scan(priv, 1, false); + refresh_scan(priv, false); cfg80211_scan_done(priv->pstrScanReq, &info); priv->bCfgScanning = false; @@ -540,7 +531,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, } if (bNeedScanRefresh) - refresh_scan(priv, 1, true); + refresh_scan(priv, true); } cfg80211_connect_result(dev, pstrConnectInfo->bssid, diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index c89bf4301096029dca25f8b5670e24832f7fceda..7a36561a599e0785ba7c71873a2d189dd6837565 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -227,8 +227,8 @@ int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif); void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc, int flag); void wilc_netdev_cleanup(struct wilc *wilc); -int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio, - const struct wilc_hif_func *ops); +int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, + int gpio, const struct wilc_hif_func *ops); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); int wilc_wlan_get_firmware(struct net_device *dev); diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 018db2299d0cc5c8548716ccc8b6c6f835385518..f5a3a1ce21ce8f27eec3b28c4ee2aa8c874e9a04 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -413,8 +413,8 @@ struct hfa384x_join_request_data { /*-- Configuration Record: authenticateStation (data portion only) --*/ struct hfa384x_authenticate_station_data { u8 address[ETH_ALEN]; - u16 status; - u16 algorithm; + __le16 status; + __le16 algorithm; } __packed; /*-- Configuration Record: WPAData (data portion only) --*/ @@ -445,9 +445,9 @@ struct hfa384x_downloadbuffer { /*-- Information Record: commsquality --*/ struct hfa384x_commsquality { - u16 cq_curr_bss; - u16 asl_curr_bss; - u16 anl_curr_fc; + __le16 cq_curr_bss; + __le16 asl_curr_bss; + __le16 anl_curr_fc; } __packed; /*-- Information Record: dmbcommsquality --*/ @@ -598,51 +598,51 @@ struct hfa384x_rx_frame { /*-- Inquiry Frame, Diagnose: Communication Tallies --*/ struct hfa384x_comm_tallies_16 { - u16 txunicastframes; - u16 txmulticastframes; - u16 txfragments; - u16 txunicastoctets; - u16 txmulticastoctets; - u16 txdeferredtrans; - u16 txsingleretryframes; - u16 txmultipleretryframes; - u16 txretrylimitexceeded; - u16 txdiscards; - u16 rxunicastframes; - u16 rxmulticastframes; - u16 rxfragments; - u16 rxunicastoctets; - u16 rxmulticastoctets; - u16 rxfcserrors; - u16 rxdiscardsnobuffer; - u16 txdiscardswrongsa; - u16 rxdiscardswepundecr; - u16 rxmsginmsgfrag; - u16 rxmsginbadmsgfrag; + __le16 txunicastframes; + __le16 txmulticastframes; + __le16 txfragments; + __le16 txunicastoctets; + __le16 txmulticastoctets; + __le16 txdeferredtrans; + __le16 txsingleretryframes; + __le16 txmultipleretryframes; + __le16 txretrylimitexceeded; + __le16 txdiscards; + __le16 rxunicastframes; + __le16 rxmulticastframes; + __le16 rxfragments; + __le16 rxunicastoctets; + __le16 rxmulticastoctets; + __le16 rxfcserrors; + __le16 rxdiscardsnobuffer; + __le16 txdiscardswrongsa; + __le16 rxdiscardswepundecr; + __le16 rxmsginmsgfrag; + __le16 rxmsginbadmsgfrag; } __packed; struct hfa384x_comm_tallies_32 { - u32 txunicastframes; - u32 txmulticastframes; - u32 txfragments; - u32 txunicastoctets; - u32 txmulticastoctets; - u32 txdeferredtrans; - u32 txsingleretryframes; - u32 txmultipleretryframes; - u32 txretrylimitexceeded; - u32 txdiscards; - u32 rxunicastframes; - u32 rxmulticastframes; - u32 rxfragments; - u32 rxunicastoctets; - u32 rxmulticastoctets; - u32 rxfcserrors; - u32 rxdiscardsnobuffer; - u32 txdiscardswrongsa; - u32 rxdiscardswepundecr; - u32 rxmsginmsgfrag; - u32 rxmsginbadmsgfrag; + __le32 txunicastframes; + __le32 txmulticastframes; + __le32 txfragments; + __le32 txunicastoctets; + __le32 txmulticastoctets; + __le32 txdeferredtrans; + __le32 txsingleretryframes; + __le32 txmultipleretryframes; + __le32 txretrylimitexceeded; + __le32 txdiscards; + __le32 rxunicastframes; + __le32 rxmulticastframes; + __le32 rxfragments; + __le32 rxunicastoctets; + __le32 rxmulticastoctets; + __le32 rxfcserrors; + __le32 rxdiscardsnobuffer; + __le32 txdiscardswrongsa; + __le32 rxdiscardswepundecr; + __le32 rxmsginmsgfrag; + __le32 rxmsginbadmsgfrag; } __packed; /*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/ @@ -711,7 +711,7 @@ struct hfa384x_hscan_result { #define HFA384x_LINK_ASSOCFAIL ((u16)6) struct hfa384x_link_status { - u16 linkstatus; + __le16 linkstatus; } __packed; /*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/ @@ -733,13 +733,13 @@ struct hfa384x_assoc_status { struct hfa384x_auth_request { u8 sta_addr[ETH_ALEN]; - u16 algorithm; + __le16 algorithm; } __packed; /*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/ struct hfa384x_ps_user_count { - u16 usercnt; + __le16 usercnt; } __packed; struct hfa384x_key_id_changed { diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index ee5fa86e941d5c3496dd04032c1692ca94dc4efc..d1e8218f96fbbf810e1ad6fa607949a2f5c6a017 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -1344,16 +1344,14 @@ hfa384x_docmd(struct hfa384x *hw, if (result != 0) { kfree(ctlx); } else if (mode == DOWAIT) { - struct usbctlx_cmd_completor completor; + struct usbctlx_cmd_completor cmd_completor; + struct usbctlx_completor *completor; - result = - hfa384x_usbctlx_complete_sync(hw, ctlx, - init_cmd_completor(&completor, - &ctlx-> - inbuf. - cmdresp, - &cmd-> - result)); + completor = init_cmd_completor(&cmd_completor, + &ctlx->inbuf.cmdresp, + &cmd->result); + + result = hfa384x_usbctlx_complete_sync(hw, ctlx, completor); } done: diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index fc8ad33ade9ff6841ef4c36220467d13a79dd89a..c1b6d426bcad7d5e9252d8a29308dfe253d53f42 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -213,6 +213,7 @@ int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, netdev_warn(wlandev->netdev, "Host en-WEP failed, dropping frame (%d).\n", foo); + kfree(p80211_wep->data); return 2; } fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 021fb23ae9babfe6b31e87c1e66dbd192cb98f35..0f503652740fa3b350aff5639c789e26acdb6f34 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -258,7 +258,7 @@ static int p80211_convert_to_ether(struct wlandevice *wlandev, return 0; } - netdev_dbg(wlandev->netdev, "p80211_convert_to_ether failed.\n"); + netdev_dbg(wlandev->netdev, "%s failed.\n", __func__); return CONV_TO_ETHER_FAILED; } diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 1a0c786c7616ce54765f0961180c1ce6b4255a71..344bec8cc31b3ea2bf3044474b7d81e2445d3624 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -1016,7 +1016,8 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, kfree(rstmsg); kfree(rwrmsg); netdev_err(wlandev->netdev, - "writeimage: no memory for firmware download, aborting download\n"); + "%s: no memory for firmware download, aborting download\n", + __func__); return -ENOMEM; } @@ -1058,15 +1059,15 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { netdev_err(wlandev->netdev, - "writeimage state enable failed w/ result=%d, aborting download\n", - result); + "%s state enable failed w/ result=%d, aborting download\n", + __func__, result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { netdev_err(wlandev->netdev, - "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", - resultcode); + "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", + __func__, resultcode); result = 1; goto free_result; } @@ -1102,14 +1103,14 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, /* Check the results */ if (result) { netdev_err(wlandev->netdev, - "writeimage chunk write failed w/ result=%d, aborting download\n", - result); + "%s chunk write failed w/ result=%d, aborting download\n", + __func__, result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { - pr_err("writeimage()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n", - resultcode); + pr_err("%s()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n", + __func__, resultcode); result = 1; goto free_result; } @@ -1124,15 +1125,15 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { netdev_err(wlandev->netdev, - "writeimage state disable failed w/ result=%d, aborting download\n", - result); + "%s state disable failed w/ result=%d, aborting download\n", + __func__, result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { netdev_err(wlandev->netdev, - "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", - resultcode); + "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", + __func__, resultcode); result = 1; goto free_result; } diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index e16da34389cd435d4a0291f2de5438bd3c982e89..c9df45063ab36338e175a8476a37e990759ddcb8 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -991,9 +991,9 @@ static void prism2sta_inf_tallies(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf) { struct hfa384x *hw = wlandev->priv; - u16 *src16; + __le16 *src16; u32 *dst; - u32 *src32; + __le32 *src32; int i; int cnt; @@ -1005,12 +1005,12 @@ static void prism2sta_inf_tallies(struct wlandevice *wlandev, cnt = sizeof(struct hfa384x_comm_tallies_32) / sizeof(u32); if (inf->framelen > 22) { dst = (u32 *)&hw->tallies; - src32 = (u32 *)&inf->info.commtallies32; + src32 = (__le32 *)&inf->info.commtallies32; for (i = 0; i < cnt; i++, dst++, src32++) *dst += le32_to_cpu(*src32); } else { dst = (u32 *)&hw->tallies; - src16 = (u16 *)&inf->info.commtallies16; + src16 = (__le16 *)&inf->info.commtallies16; for (i = 0; i < cnt; i++, dst++, src16++) *dst += le16_to_cpu(*src16); } @@ -1136,7 +1136,7 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, unsigned int i, n; hw->channel_info.results.scanchannels = - le16_to_cpu(inf->info.chinforesult.scanchannels); + inf->info.chinforesult.scanchannels; for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { struct hfa384x_ch_info_result_sub *result; @@ -1147,16 +1147,16 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, continue; result = &inf->info.chinforesult.result[n]; - chan = le16_to_cpu(result->chid) - 1; + chan = result->chid - 1; if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) continue; chinforesult = &hw->channel_info.results.result[chan]; chinforesult->chid = chan; - chinforesult->anl = le16_to_cpu(result->anl); - chinforesult->pnl = le16_to_cpu(result->pnl); - chinforesult->active = le16_to_cpu(result->active); + chinforesult->anl = result->anl; + chinforesult->pnl = result->pnl; + chinforesult->active = result->active; pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", chan + 1, @@ -1447,7 +1447,7 @@ static void prism2sta_inf_linkstatus(struct wlandevice *wlandev, { struct hfa384x *hw = wlandev->priv; - hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus); + hw->link_status_new = inf->info.linkstatus.linkstatus; schedule_work(&hw->link_bh); } @@ -1561,7 +1561,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, */ ether_addr_copy(rec.address, inf->info.authreq.sta_addr); - rec.status = P80211ENUM_status_unspec_failure; + rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); /* * Authenticate based on the access mode. @@ -1578,7 +1578,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, for (i = 0; i < hw->authlist.cnt; i++) if (ether_addr_equal(rec.address, hw->authlist.addr[i])) { - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); break; } @@ -1590,7 +1590,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, * Allow all authentications. */ - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); break; case WLAN_ACCESS_ALLOW: @@ -1615,7 +1615,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, for (i = 0; i < cnt; i++, addr += ETH_ALEN) if (ether_addr_equal(rec.address, addr)) { - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); break; } @@ -1641,11 +1641,11 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, addr = hw->deny.addr1[0]; } - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); for (i = 0; i < cnt; i++, addr += ETH_ALEN) if (ether_addr_equal(rec.address, addr)) { - rec.status = P80211ENUM_status_unspec_failure; + rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); break; } @@ -1663,7 +1663,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, added = 0; - if (rec.status == P80211ENUM_status_successful) { + if (rec.status == cpu_to_le16(P80211ENUM_status_successful)) { for (i = 0; i < hw->authlist.cnt; i++) if (ether_addr_equal(rec.address, hw->authlist.addr[i])) @@ -1671,7 +1671,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, if (i >= hw->authlist.cnt) { if (hw->authlist.cnt >= WLAN_AUTH_MAX) { - rec.status = P80211ENUM_status_ap_full; + rec.status = cpu_to_le16(P80211ENUM_status_ap_full); } else { ether_addr_copy( hw->authlist.addr[hw->authlist.cnt], @@ -1688,7 +1688,6 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, * it was added. */ - rec.status = cpu_to_le16(rec.status); rec.algorithm = inf->info.authreq.algorithm; result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c index e583dd8a418b537eda69a9606fa8a3fc2c6a6207..d4fa41be80f9a1719574af28c8981ef8e8d287ca 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c @@ -1510,11 +1510,13 @@ cxgbit_pass_open_rpl(struct cxgbit_device *cdev, struct sk_buff *skb) if (!cnp) { pr_info("%s stid %d lookup failure\n", __func__, stid); - return; + goto rel_skb; } cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status); cxgbit_put_cnp(cnp); +rel_skb: + __kfree_skb(skb); } static void @@ -1530,11 +1532,13 @@ cxgbit_close_listsrv_rpl(struct cxgbit_device *cdev, struct sk_buff *skb) if (!cnp) { pr_info("%s stid %d lookup failure\n", __func__, stid); - return; + goto rel_skb; } cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status); cxgbit_put_cnp(cnp); +rel_skb: + __kfree_skb(skb); } static void @@ -1819,12 +1823,16 @@ static void cxgbit_set_tcb_rpl(struct cxgbit_device *cdev, struct sk_buff *skb) struct tid_info *t = lldi->tids; csk = lookup_tid(t, tid); - if (unlikely(!csk)) + if (unlikely(!csk)) { pr_err("can't find connection for tid %u.\n", tid); - else + goto rel_skb; + } else { cxgbit_wake_up(&csk->com.wr_wait, __func__, rpl->status); + } cxgbit_put_csk(csk); +rel_skb: + __kfree_skb(skb); } static void cxgbit_rx_data(struct cxgbit_device *cdev, struct sk_buff *skb) diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c index dda13f1af38e581f746e4528590510c07efb916f..514986b57c2d60ce19c1074f4d19d65dd550be2e 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_target.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c @@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, static void cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, - unsigned int nents) + unsigned int nents, u32 skip) { struct skb_seq_state st; const u8 *buf; @@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, } consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf, - buf_len, consumed); + buf_len, skip + consumed); } } @@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0]; u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE)); - cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents); + cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0); } cmd->write_data_done += pdu_cb->dlen; @@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk) cmd->se_cmd.data_length); if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) { + u32 skip = data_offset % PAGE_SIZE; + sg_off = data_offset / PAGE_SIZE; sg_start = &cmd->se_cmd.t_data_sg[sg_off]; - sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE)); + sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE)); - cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents); + cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip); } check_payload: diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 74e4975dd1b1e74d6c39517be102ccdc92614e80..5001261f5d69d759dd25161401510551d35c3da7 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -418,6 +418,7 @@ int iscsit_reset_np_thread( return 0; } np->np_thread_state = ISCSI_NP_THREAD_RESET; + atomic_inc(&np->np_reset_count); if (np->np_thread) { spin_unlock_bh(&np->np_thread_lock); @@ -2167,6 +2168,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->data_direction = DMA_NONE; + kfree(cmd->text_in_ptr); cmd->text_in_ptr = NULL; return 0; @@ -3487,9 +3489,9 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, return text_length; if (completed) { - hdr->flags |= ISCSI_FLAG_CMD_FINAL; + hdr->flags = ISCSI_FLAG_CMD_FINAL; } else { - hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE; + hdr->flags = ISCSI_FLAG_TEXT_CONTINUE; cmd->read_data_done += text_length; if (cmd->targ_xfer_tag == 0xFFFFFFFF) cmd->targ_xfer_tag = session_get_next_ttt(conn->sess); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index e9bdc8b86e7d1d71d77cf4388370af6fcf3fded7..dc13afbd4c88dec2390ca8e65b3332d2f78acd73 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) flush_signals(current); spin_lock_bh(&np->np_thread_lock); - if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { + if (atomic_dec_if_positive(&np->np_reset_count) >= 0) { np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; + spin_unlock_bh(&np->np_thread_lock); complete(&np->np_restart_comp); + return 1; } else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) { spin_unlock_bh(&np->np_thread_lock); goto exit; @@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) goto exit; } else if (rc < 0) { spin_lock_bh(&np->np_thread_lock); - if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { + if (atomic_dec_if_positive(&np->np_reset_count) >= 0) { + np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; spin_unlock_bh(&np->np_thread_lock); complete(&np->np_restart_comp); iscsit_put_transport(conn->conn_transport); diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index a91b7c25ffd411abba6932d0c5e6ce9556cce657..928127642574b2d4b90592dfcd3688477a7d7a96 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -896,13 +896,14 @@ static int core_alua_write_tpg_metadata( u32 md_buf_len) { struct file *file = filp_open(path, O_RDWR | O_CREAT | O_TRUNC, 0600); + loff_t pos = 0; int ret; if (IS_ERR(file)) { pr_err("filp_open(%s) for ALUA metadata failed\n", path); return -ENODEV; } - ret = kernel_write(file, md_buf, md_buf_len, 0); + ret = kernel_write(file, md_buf, md_buf_len, &pos); if (ret < 0) pr_err("Error writing ALUA metadata file: %s\n", path); fput(file); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 24cf11d9e50a5b457aae518e5e2c045705786a69..c629817a8854bea49a18c6b3f93f3f8923f99079 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -443,7 +443,7 @@ fd_do_prot_fill(struct se_device *se_dev, sector_t lba, sector_t nolb, for (prot = 0; prot < prot_length;) { sector_t len = min_t(sector_t, bufsize, prot_length - prot); - ssize_t ret = kernel_write(prot_fd, buf, len, pos + prot); + ssize_t ret = kernel_write(prot_fd, buf, len, &pos); if (ret != len) { pr_err("vfs_write to prot file failed: %zd\n", ret); diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index ee7c7fa55dad16ffc43d30fa701062c5f3c84aa4..07c814c42648faa00d7bca39ad339d7ef916ec99 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -338,7 +338,7 @@ iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num, int op, return NULL; } - bio->bi_bdev = ib_dev->ibd_bd; + bio_set_dev(bio, ib_dev->ibd_bd); bio->bi_private = cmd; bio->bi_end_io = &iblock_bio_done; bio->bi_iter.bi_sector = lba; @@ -395,7 +395,7 @@ iblock_execute_sync_cache(struct se_cmd *cmd) bio = bio_alloc(GFP_KERNEL, 0); bio->bi_end_io = iblock_end_io_flush; - bio->bi_bdev = ib_dev->ibd_bd; + bio_set_dev(bio, ib_dev->ibd_bd); bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; if (!immed) bio->bi_private = cmd; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 6d5def64db61d98be33effdacb9deaa55c2147a0..dd2cd8048582ce7520661b5ec3477a8e431b0f86 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1974,6 +1974,7 @@ static int __core_scsi3_write_aptpl_to_file( char path[512]; u32 pr_aptpl_buf_len; int ret; + loff_t pos = 0; memset(path, 0, 512); @@ -1993,7 +1994,7 @@ static int __core_scsi3_write_aptpl_to_file( pr_aptpl_buf_len = (strlen(buf) + 1); /* Add extra for NULL */ - ret = kernel_write(file, buf, pr_aptpl_buf_len, 0); + ret = kernel_write(file, buf, pr_aptpl_buf_len, &pos); if (ret < 0) pr_debug("Error writing APTPL metadata file: %s\n", path); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 36913734c6bc58ed326ac793dc19d3d265ec878d..02e8a5d8665837f415ac7b2d78e51067d1ef5b62 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -364,7 +364,7 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl) mutex_lock(&tpg->acl_node_mutex); if (acl->dynamic_node_acl) acl->dynamic_node_acl = 0; - list_del(&acl->acl_list); + list_del_init(&acl->acl_list); mutex_unlock(&tpg->acl_node_mutex); target_shutdown_sessions(acl); @@ -548,7 +548,7 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) * in transport_deregister_session(). */ list_for_each_entry_safe(nacl, nacl_tmp, &node_list, acl_list) { - list_del(&nacl->acl_list); + list_del_init(&nacl->acl_list); core_tpg_wait_for_nacl_pr_ref(nacl); core_free_device_list_for_node(nacl, se_tpg); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 97fed9a298bdc29a19d184ba49df458e04e4f9f1..836d552b0385e978bc1a0b98c59a3379c262fd61 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -466,7 +466,7 @@ static void target_complete_nacl(struct kref *kref) } mutex_lock(&se_tpg->acl_node_mutex); - list_del(&nacl->acl_list); + list_del_init(&nacl->acl_list); mutex_unlock(&se_tpg->acl_node_mutex); core_tpg_wait_for_nacl_pr_ref(nacl); @@ -538,7 +538,7 @@ void transport_free_session(struct se_session *se_sess) spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags); if (se_nacl->dynamic_stop) - list_del(&se_nacl->acl_list); + list_del_init(&se_nacl->acl_list); } mutex_unlock(&se_tpg->acl_node_mutex); diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 80ee130f8253ec44324ac2ba616cfd93beb1ba76..942d094269fba5db66ff7e791dcfaab1c6acec15 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -563,8 +563,6 @@ static int scatter_data_area(struct tcmu_dev *udev, block_remaining); to_offset = get_block_offset_user(udev, dbi, block_remaining); - offset = DATA_BLOCK_SIZE - block_remaining; - to += offset; if (*iov_cnt != 0 && to_offset == iov_tail(*iov)) { @@ -575,8 +573,10 @@ static int scatter_data_area(struct tcmu_dev *udev, (*iov)->iov_len = copy_bytes; } if (copy_data) { - memcpy(to, from + sg->length - sg_remaining, - copy_bytes); + offset = DATA_BLOCK_SIZE - block_remaining; + memcpy(to + offset, + from + sg->length - sg_remaining, + copy_bytes); tcmu_flush_dcache_range(to, copy_bytes); } sg_remaining -= copy_bytes; @@ -637,9 +637,8 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, copy_bytes = min_t(size_t, sg_remaining, block_remaining); offset = DATA_BLOCK_SIZE - block_remaining; - from += offset; tcmu_flush_dcache_range(from, copy_bytes); - memcpy(to + sg->length - sg_remaining, from, + memcpy(to + sg->length - sg_remaining, from + offset, copy_bytes); sg_remaining -= copy_bytes; @@ -1433,6 +1432,8 @@ static int tcmu_update_uio_info(struct tcmu_dev *udev) if (udev->dev_config[0]) snprintf(str + used, size - used, "/%s", udev->dev_config); + /* If the old string exists, free it */ + kfree(info->name); info->name = str; return 0; diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 58169e519422d36f28c93d8aa8e24acd70c93d43..7952357df9c862c9d9558522c3664d3d5059a572 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -224,13 +224,14 @@ static void optee_release(struct tee_context *ctx) if (!IS_ERR(shm)) { arg = tee_shm_get_va(shm, 0); /* - * If va2pa fails for some reason, we can't call - * optee_close_session(), only free the memory. Secure OS - * will leak sessions and finally refuse more sessions, but - * we will at least let normal world reclaim its memory. + * If va2pa fails for some reason, we can't call into + * secure world, only free the memory. Secure OS will leak + * sessions and finally refuse more sessions, but we will + * at least let normal world reclaim its memory. */ if (!IS_ERR(arg)) - tee_shm_va2pa(shm, arg, &parg); + if (tee_shm_va2pa(shm, arg, &parg)) + arg = NULL; /* prevent usage of parg below */ } list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, @@ -258,7 +259,7 @@ static void optee_release(struct tee_context *ctx) } } -static struct tee_driver_ops optee_ops = { +static const struct tee_driver_ops optee_ops = { .get_version = optee_get_version, .open = optee_open, .release = optee_release, @@ -268,13 +269,13 @@ static struct tee_driver_ops optee_ops = { .cancel_req = optee_cancel_req, }; -static struct tee_desc optee_desc = { +static const struct tee_desc optee_desc = { .name = DRIVER_NAME "-clnt", .ops = &optee_ops, .owner = THIS_MODULE, }; -static struct tee_driver_ops optee_supp_ops = { +static const struct tee_driver_ops optee_supp_ops = { .get_version = optee_get_version, .open = optee_open, .release = optee_release, @@ -282,7 +283,7 @@ static struct tee_driver_ops optee_supp_ops = { .supp_send = optee_supp_send, }; -static struct tee_desc optee_supp_desc = { +static const struct tee_desc optee_supp_desc = { .name = DRIVER_NAME "-supp", .ops = &optee_supp_ops, .owner = THIS_MODULE, diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index 13b7c98cdf25372dc8af14f6038b79181da42853..069c8e1429de8d2aaeb57e1cc51df58293d1d932 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -298,7 +298,7 @@ struct optee_smc_disable_shm_cache_result { OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE) /* - * Resume from RPC (for example after processing an IRQ) + * Resume from RPC (for example after processing a foreign interrupt) * * Call register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC @@ -383,19 +383,19 @@ struct optee_smc_disable_shm_cache_result { OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE) /* - * Deliver an IRQ in normal world. + * Deliver foreign interrupt to normal world. * * "Call" register usage: - * a0 OPTEE_SMC_RETURN_RPC_IRQ + * a0 OPTEE_SMC_RETURN_RPC_FOREIGN_INTR * a1-7 Resume information, must be preserved * * "Return" register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC. * a1-7 Preserved */ -#define OPTEE_SMC_RPC_FUNC_IRQ 4 -#define OPTEE_SMC_RETURN_RPC_IRQ \ - OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ) +#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR 4 +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR \ + OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR) /* * Do an RPC request. The supplied struct optee_msg_arg tells which diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index 8814eca060216a05c0b53cabc1c81fe74bc288a8..cef417f4f4d286768ea1733168d7bf04d90df462 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -140,11 +140,8 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg) msec_to_wait = arg->params[0].u.value.a; - /* set task's state to interruptible sleep */ - set_current_state(TASK_INTERRUPTIBLE); - - /* take a nap */ - msleep(msec_to_wait); + /* Go to interruptible sleep */ + msleep_interruptible(msec_to_wait); arg->ret = TEEC_SUCCESS; return; @@ -374,11 +371,11 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param) shm = reg_pair_to_ptr(param->a1, param->a2); tee_shm_free(shm); break; - case OPTEE_SMC_RPC_FUNC_IRQ: + case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR: /* - * An IRQ was raised while secure world was executing, - * since all IRQs are handled in Linux a dummy RPC is - * performed to let Linux take the IRQ through the normal + * A foreign interrupt was raised while secure world was + * executing, since they are handled in Linux a dummy RPC is + * performed to let Linux take the interrupt through the normal * vector. */ break; diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 5c60bf4423e68d4c7bf0b1b27f78c60bf72478bd..58a5009eacc388b45231d747e7d142163f38e627 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -90,8 +90,13 @@ static int tee_ioctl_version(struct tee_context *ctx, struct tee_ioctl_version_data vers; ctx->teedev->desc->ops->get_version(ctx->teedev, &vers); + + if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED) + vers.gen_caps |= TEE_GEN_CAP_PRIVILEGED; + if (copy_to_user(uvers, &vers, sizeof(vers))) return -EFAULT; + return 0; } diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index d356d7f025eb4cf92cc3c2f6615a2b8dad6f7e36..4bc7956cefc4afcde8e724f47346c2937e45e3e3 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -80,7 +80,7 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) size, vma->vm_page_prot); } -static struct dma_buf_ops tee_shm_dma_buf_ops = { +static const struct dma_buf_ops tee_shm_dma_buf_ops = { .map_dma_buf = tee_shm_op_map_dma_buf, .unmap_dma_buf = tee_shm_op_unmap_dma_buf, .release = tee_shm_op_release, diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index b5b5facb87473e4de8c30fa29a105251965cd027..07002df4f83acdde2efdf3f51299976ef25d2e1e 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -342,7 +342,7 @@ config X86_PKG_TEMP_THERMAL config INTEL_SOC_DTS_IOSF_CORE tristate - depends on X86 + depends on X86 && PCI select IOSF_MBI help This is becoming a common feature for Intel SoCs to expose the additional @@ -352,7 +352,7 @@ config INTEL_SOC_DTS_IOSF_CORE config INTEL_SOC_DTS_THERMAL tristate "Intel SoCs DTS thermal driver" - depends on X86 + depends on X86 && PCI select INTEL_SOC_DTS_IOSF_CORE select THERMAL_WRITABLE_TRIPS help @@ -473,4 +473,12 @@ config ZX2967_THERMAL the primitive temperature sensor embedded in zx2967 SoCs. This sensor generates the real time die temperature. +config UNIPHIER_THERMAL + tristate "Socionext UniPhier thermal driver" + depends on ARCH_UNIPHIER || COMPILE_TEST + depends on THERMAL_OF && MFD_SYSCON + help + Enable this to plug in UniPhier on-chip PVT thermal driver into the + thermal framework. The driver supports CPU thermal zone temperature + reporting and a couple of trip points. endif diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 094d7039981ca3eb2371562c16393fa35e19bd10..8b79bca23536578d031e530ad597188a960d7a3b 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -59,3 +59,4 @@ obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o +obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index e6863c84166275ee7a89b0de85c3767fc91bb271..a4d6a0e2e9938190a3bd0c6d081a02bbd6f209fd 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -145,7 +145,7 @@ static void bcm2835_thermal_debugfs(struct platform_device *pdev) debugfs_create_regset32("regset", 0444, data->debugfsdir, regset); } -static struct thermal_zone_of_device_ops bcm2835_thermal_ops = { +static const struct thermal_zone_of_device_ops bcm2835_thermal_ops = { .get_temp = bcm2835_thermal_get_temp, }; diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 9c3ce341eb97563822d510398b8b4d06c71af3f1..bd3572c41585caedde615301f7ff68d73c235b6c 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -206,7 +206,7 @@ static int hisi_thermal_get_temp(void *_sensor, int *temp) return 0; } -static struct thermal_zone_of_device_ops hisi_of_thermal_ops = { +static const struct thermal_zone_of_device_ops hisi_of_thermal_ops = { .get_temp = hisi_thermal_get_temp, }; diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index 51ceb80212a7a74e8afb7edda170c120361e648f..c719167e9f2829dedea376e21b51a773559e5866 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -228,7 +228,7 @@ static void get_single_name(acpi_handle handle, char *name) struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER}; if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer))) - pr_warn("Failed get name from handle\n"); + pr_warn("Failed to get device name from acpi handle\n"); else { memcpy(name, buffer.pointer, ACPI_NAME_SIZE); kfree(buffer.pointer); diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.h b/drivers/thermal/int340x_thermal/acpi_thermal_rel.h index f00700bc9d79fe3e2a481eb7c7c012af5956ee24..65075b1743294db65e8154b3eedf6bda8aa8f8a6 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.h +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.h @@ -34,10 +34,10 @@ struct trt { acpi_handle target; u64 influence; u64 sample_period; - u64 reverved1; - u64 reverved2; - u64 reverved3; - u64 reverved4; + u64 reserved1; + u64 reserved2; + u64 reserved3; + u64 reserved4; } __packed; #define ACPI_NR_ART_ELEMENTS 13 diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index a9ec94ed7a425a303280c3cdba589d71b642011c..8ee38f55c7f36c5e244711bb45bc3171b4d32ba1 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c @@ -16,6 +16,8 @@ #include #include "acpi_thermal_rel.h" +#define INT3400_THERMAL_TABLE_CHANGED 0x83 + enum int3400_thermal_uuid { INT3400_THERMAL_PASSIVE_1, INT3400_THERMAL_ACTIVE, @@ -104,7 +106,7 @@ static struct attribute *uuid_attrs[] = { NULL }; -static struct attribute_group uuid_attribute_group = { +static const struct attribute_group uuid_attribute_group = { .attrs = uuid_attrs, .name = "uuids" }; @@ -185,6 +187,35 @@ static int int3400_thermal_run_osc(acpi_handle handle, return result; } +static void int3400_notify(acpi_handle handle, + u32 event, + void *data) +{ + struct int3400_thermal_priv *priv = data; + char *thermal_prop[5]; + + if (!priv) + return; + + switch (event) { + case INT3400_THERMAL_TABLE_CHANGED: + thermal_prop[0] = kasprintf(GFP_KERNEL, "NAME=%s", + priv->thermal->type); + thermal_prop[1] = kasprintf(GFP_KERNEL, "TEMP=%d", + priv->thermal->temperature); + thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP="); + thermal_prop[3] = kasprintf(GFP_KERNEL, "EVENT=%d", + THERMAL_TABLE_CHANGED); + thermal_prop[4] = NULL; + kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE, + thermal_prop); + break; + default: + dev_err(&priv->adev->dev, "Unsupported event [0x%x]\n", event); + break; + } +} + static int int3400_thermal_get_temp(struct thermal_zone_device *thermal, int *temp) { @@ -290,6 +321,12 @@ static int int3400_thermal_probe(struct platform_device *pdev) if (result) goto free_zone; + result = acpi_install_notify_handler( + priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify, + (void *)priv); + if (result) + goto free_zone; + return 0; free_zone: @@ -306,6 +343,10 @@ static int int3400_thermal_remove(struct platform_device *pdev) { struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + acpi_remove_notify_handler( + priv->adev->handle, ACPI_DEVICE_NOTIFY, + int3400_notify); + if (!priv->rel_misc_dev_res) acpi_thermal_rel_misc_device_remove(priv->adev->handle); diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c index 1891f34ab7fcd746405fb6f7b7696c36c54133f2..f69ab026ba243cbdbe3e12a385fe66503e4f7ff8 100644 --- a/drivers/thermal/int340x_thermal/int3406_thermal.c +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c @@ -21,39 +21,33 @@ struct int3406_thermal_data { int upper_limit; - int upper_limit_index; int lower_limit; - int lower_limit_index; acpi_handle handle; struct acpi_video_device_brightness *br; struct backlight_device *raw_bd; struct thermal_cooling_device *cooling_dev; }; -static int int3406_thermal_to_raw(int level, struct int3406_thermal_data *d) -{ - int max_level = d->br->levels[d->br->count - 1]; - int raw_max = d->raw_bd->props.max_brightness; - - return level * raw_max / max_level; -} - -static int int3406_thermal_to_acpi(int level, struct int3406_thermal_data *d) -{ - int raw_max = d->raw_bd->props.max_brightness; - int max_level = d->br->levels[d->br->count - 1]; - - return level * max_level / raw_max; -} +/* + * According to the ACPI spec, + * "Each brightness level is represented by a number between 0 and 100, + * and can be thought of as a percentage. For example, 50 can be 50% + * power consumption or 50% brightness, as defined by the OEM." + * + * As int3406 device uses this value to communicate with the native + * graphics driver, we make the assumption that it represents + * the percentage of brightness only + */ +#define ACPI_TO_RAW(v, d) (d->raw_bd->props.max_brightness * v / 100) +#define RAW_TO_ACPI(v, d) (v * 100 / d->raw_bd->props.max_brightness) static int int3406_thermal_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct int3406_thermal_data *d = cooling_dev->devdata; - int index = d->lower_limit_index ? d->lower_limit_index : 2; - *state = d->br->count - 1 - index; + *state = d->upper_limit - d->lower_limit; return 0; } @@ -62,19 +56,15 @@ int3406_thermal_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) { struct int3406_thermal_data *d = cooling_dev->devdata; - int level, raw_level; + int acpi_level, raw_level; - if (state > d->br->count - 3) + if (state > d->upper_limit - d->lower_limit) return -EINVAL; - state = d->br->count - 1 - state; - level = d->br->levels[state]; + acpi_level = d->br->levels[d->upper_limit - state]; - if ((d->upper_limit && level > d->upper_limit) || - (d->lower_limit && level < d->lower_limit)) - return -EINVAL; + raw_level = ACPI_TO_RAW(acpi_level, d); - raw_level = int3406_thermal_to_raw(level, d); return backlight_device_set_brightness(d->raw_bd, raw_level); } @@ -83,27 +73,22 @@ int3406_thermal_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct int3406_thermal_data *d = cooling_dev->devdata; - int raw_level, level, i; - int *levels = d->br->levels; + int acpi_level; + int index; - raw_level = d->raw_bd->props.brightness; - level = int3406_thermal_to_acpi(raw_level, d); + acpi_level = RAW_TO_ACPI(d->raw_bd->props.brightness, d); /* - * There is no 1:1 mapping between the firmware interface level with the - * raw interface level, we will have to find one that is close enough. + * There is no 1:1 mapping between the firmware interface level + * with the raw interface level, we will have to find one that is + * right above it. */ - for (i = 2; i < d->br->count; i++) { - if (level < levels[i]) { - if (i == 2) - break; - if ((level - levels[i - 1]) < (levels[i] - level)) - i--; + for (index = d->lower_limit; index < d->upper_limit; index++) { + if (acpi_level <= d->br->levels[index]) break; - } } - *state = d->br->count - 1 - i; + *state = d->upper_limit - index; return 0; } @@ -117,7 +102,7 @@ static int int3406_thermal_get_index(int *array, int nr, int value) { int i; - for (i = 0; i < nr; i++) { + for (i = 2; i < nr; i++) { if (array[i] == value) break; } @@ -128,27 +113,20 @@ static void int3406_thermal_get_limit(struct int3406_thermal_data *d) { acpi_status status; unsigned long long lower_limit, upper_limit; - int index; status = acpi_evaluate_integer(d->handle, "DDDL", NULL, &lower_limit); - if (ACPI_SUCCESS(status)) { - index = int3406_thermal_get_index(d->br->levels, d->br->count, - lower_limit); - if (index > 0) { - d->lower_limit = (int)lower_limit; - d->lower_limit_index = index; - } - } + if (ACPI_SUCCESS(status)) + d->lower_limit = int3406_thermal_get_index(d->br->levels, + d->br->count, lower_limit); status = acpi_evaluate_integer(d->handle, "DDPC", NULL, &upper_limit); - if (ACPI_SUCCESS(status)) { - index = int3406_thermal_get_index(d->br->levels, d->br->count, - upper_limit); - if (index > 0) { - d->upper_limit = (int)upper_limit; - d->upper_limit_index = index; - } - } + if (ACPI_SUCCESS(status)) + d->upper_limit = int3406_thermal_get_index(d->br->levels, + d->br->count, upper_limit); + + /* lower_limit and upper_limit should be always set */ + d->lower_limit = d->lower_limit > 0 ? d->lower_limit : 2; + d->upper_limit = d->upper_limit > 0 ? d->upper_limit : d->br->count - 1; } static void int3406_notify(acpi_handle handle, u32 event, void *data) diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c index ff3b36f339e34fb0a2cbc261d9db0ccda6a9b528..f02341f7134d4e69314ebb4ae3419b75d8b4f839 100644 --- a/drivers/thermal/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c @@ -127,7 +127,7 @@ static struct attribute *power_limit_attrs[] = { NULL }; -static struct attribute_group power_limit_attribute_group = { +static const struct attribute_group power_limit_attribute_group = { .attrs = power_limit_attrs, .name = "power_limits" }; diff --git a/drivers/thermal/intel_pch_thermal.c b/drivers/thermal/intel_pch_thermal.c index 2b49e8d0fe9eb3befd7a43b2c70e66cceb77bc74..c60b1cfcc64e84651dba55f7595ab1cdc960d720 100644 --- a/drivers/thermal/intel_pch_thermal.c +++ b/drivers/thermal/intel_pch_thermal.c @@ -49,7 +49,7 @@ #define WPT_TSGPEN 0x84 /* General Purpose Event Enables */ /* Wildcat Point-LP PCH Thermal Register bit definitions */ -#define WPT_TEMP_TSR 0x00ff /* Temp TS Reading */ +#define WPT_TEMP_TSR 0x01ff /* Temp TS Reading */ #define WPT_TSC_CPDE 0x01 /* Catastrophic Power-Down Enable */ #define WPT_TSS_TSDSS 0x10 /* Thermal Sensor Dynamic Shutdown Status */ #define WPT_TSS_GPES 0x08 /* GPE status */ @@ -125,7 +125,7 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) *nr_trips = 0; /* Check if BIOS has already enabled thermal sensor */ - if (WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS)) { + if (WPT_TSEL_ETS & readb(ptd->hw_base + WPT_TSEL)) { ptd->bios_enabled = true; goto read_trips; } @@ -141,7 +141,7 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) } writeb(tsel|WPT_TSEL_ETS, ptd->hw_base + WPT_TSEL); - if (!(WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS))) { + if (!(WPT_TSEL_ETS & readb(ptd->hw_base + WPT_TSEL))) { dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n"); return -ENODEV; } @@ -174,9 +174,9 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) static int pch_wpt_get_temp(struct pch_thermal_device *ptd, int *temp) { - u8 wpt_temp; + u16 wpt_temp; - wpt_temp = WPT_TEMP_TSR & readl(ptd->hw_base + WPT_TEMP); + wpt_temp = WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP); /* Resolution of 1/2 degree C and an offset of -50C */ *temp = (wpt_temp * 1000 / 2 - 50000); @@ -387,7 +387,7 @@ static int intel_pch_thermal_resume(struct device *device) return ptd->ops->resume(ptd); } -static struct pci_device_id intel_pch_thermal_id[] = { +static const struct pci_device_id intel_pch_thermal_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_1), .driver_data = board_hsw, }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_2), diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 7737f14846f9e77b0515093d33d13a19c96bf13a..1e61c09153c9abf0d02eb43d4ff21ba925da9415 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -3,6 +3,7 @@ * Author: Hanyi Wu * Sascha Hauer * Dawei Chien + * Louis Yu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -111,9 +112,10 @@ /* * Layout of the fuses providing the calibration data - * These macros could be used for both MT8173 and MT2701. - * MT8173 has five sensors and need five VTS calibration data, - * and MT2701 has three sensors and need three VTS calibration data. + * These macros could be used for MT8173, MT2701, and MT2712. + * MT8173 has 5 sensors and needs 5 VTS calibration data. + * MT2701 has 3 sensors and needs 3 VTS calibration data. + * MT2712 has 4 sensors and needs 4 VTS calibration data. */ #define MT8173_CALIB_BUF0_VALID BIT(0) #define MT8173_CALIB_BUF1_ADC_GE(x) (((x) >> 22) & 0x3ff) @@ -124,6 +126,8 @@ #define MT8173_CALIB_BUF2_VTS_TSABB(x) (((x) >> 14) & 0x1ff) #define MT8173_CALIB_BUF0_DEGC_CALI(x) (((x) >> 1) & 0x3f) #define MT8173_CALIB_BUF0_O_SLOPE(x) (((x) >> 26) & 0x3f) +#define MT8173_CALIB_BUF0_O_SLOPE_SIGN(x) (((x) >> 7) & 0x1) +#define MT8173_CALIB_BUF1_ID(x) (((x) >> 9) & 0x1) /* MT2701 thermal sensors */ #define MT2701_TS1 0 @@ -136,11 +140,26 @@ /* The total number of temperature sensors in the MT2701 */ #define MT2701_NUM_SENSORS 3 -#define THERMAL_NAME "mtk-thermal" - /* The number of sensing points per bank */ #define MT2701_NUM_SENSORS_PER_ZONE 3 +/* MT2712 thermal sensors */ +#define MT2712_TS1 0 +#define MT2712_TS2 1 +#define MT2712_TS3 2 +#define MT2712_TS4 3 + +/* AUXADC channel 11 is used for the temperature sensors */ +#define MT2712_TEMP_AUXADC_CHANNEL 11 + +/* The total number of temperature sensors in the MT2712 */ +#define MT2712_NUM_SENSORS 4 + +/* The number of sensing points per bank */ +#define MT2712_NUM_SENSORS_PER_ZONE 4 + +#define THERMAL_NAME "mtk-thermal" + struct mtk_thermal; struct thermal_bank_cfg { @@ -215,6 +234,21 @@ static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = { static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 }; +/* MT2712 thermal sensor data */ +static const int mt2712_bank_data[MT2712_NUM_SENSORS] = { + MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4 +}; + +static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = { + TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3 +}; + +static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = { + TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3 +}; + +static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 }; + /** * The MT8173 thermal controller has four banks. Each bank can read up to * four temperature sensors simultaneously. The MT8173 has a total of 5 @@ -277,6 +311,31 @@ static const struct mtk_thermal_data mt2701_thermal_data = { .sensor_mux_values = mt2701_mux_values, }; +/** + * The MT2712 thermal controller has one bank, which can read up to + * four temperature sensors simultaneously. The MT2712 has a total of 4 + * temperature sensors. + * + * The thermal core only gets the maximum temperature of this one bank, + * so the bank concept wouldn't be necessary here. However, the SVS (Smart + * Voltage Scaling) unit makes its decisions based on the same bank + * data. + */ +static const struct mtk_thermal_data mt2712_thermal_data = { + .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL, + .num_banks = 1, + .num_sensors = MT2712_NUM_SENSORS, + .bank_data = { + { + .num_sensors = 4, + .sensors = mt2712_bank_data, + }, + }, + .msr = mt2712_msr, + .adcpnp = mt2712_adcpnp, + .sensor_mux_values = mt2712_mux_values, +}; + /** * raw_to_mcelsius - convert a raw ADC value to mcelsius * @mt: The thermal controller @@ -552,7 +611,11 @@ static int mtk_thermal_get_calibration_data(struct device *dev, mt->vts[MT8173_TS4] = MT8173_CALIB_BUF2_VTS_TS4(buf[2]); mt->vts[MT8173_TSABB] = MT8173_CALIB_BUF2_VTS_TSABB(buf[2]); mt->degc_cali = MT8173_CALIB_BUF0_DEGC_CALI(buf[0]); - mt->o_slope = MT8173_CALIB_BUF0_O_SLOPE(buf[0]); + if (MT8173_CALIB_BUF1_ID(buf[1]) & + MT8173_CALIB_BUF0_O_SLOPE_SIGN(buf[0])) + mt->o_slope = -MT8173_CALIB_BUF0_O_SLOPE(buf[0]); + else + mt->o_slope = MT8173_CALIB_BUF0_O_SLOPE(buf[0]); } else { dev_info(dev, "Device not calibrated, using default calibration values\n"); } @@ -571,6 +634,10 @@ static const struct of_device_id mtk_thermal_of_match[] = { { .compatible = "mediatek,mt2701-thermal", .data = (void *)&mt2701_thermal_data, + }, + { + .compatible = "mediatek,mt2712-thermal", + .data = (void *)&mt2712_thermal_data, }, { }, }; @@ -645,16 +712,16 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -EINVAL; } + ret = device_reset(&pdev->dev); + if (ret) + return ret; + ret = clk_prepare_enable(mt->clk_auxadc); if (ret) { dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret); return ret; } - ret = device_reset(&pdev->dev); - if (ret) - goto err_disable_clk_auxadc; - ret = clk_prepare_enable(mt->clk_peri_therm); if (ret) { dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret); @@ -705,6 +772,7 @@ static struct platform_driver mtk_thermal_driver = { module_platform_driver(mtk_thermal_driver); +MODULE_AUTHOR("Louis Yu "); MODULE_AUTHOR("Dawei Chien "); MODULE_AUTHOR("Sascha Hauer "); MODULE_AUTHOR("Hanyi Wu "); diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c index 4362a69ac88dcff8573e88e16fd6f3653432dd68..c866cc1659606726584e47b6e74ff59fe2d6aa51 100644 --- a/drivers/thermal/qoriq_thermal.c +++ b/drivers/thermal/qoriq_thermal.c @@ -188,7 +188,7 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data) tmu_write(data, TMR_DISABLE, &data->regs->tmr); } -static struct thermal_zone_of_device_ops tmu_tz_ops = { +static const struct thermal_zone_of_device_ops tmu_tz_ops = { .get_temp = tmu_get_temp, }; diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c index 37fcefd06d9f81b4eb1238634103b5e1ab06a5c3..203aca44a2bb4bdfd3bc3d6465446f0eadba1a4b 100644 --- a/drivers/thermal/rcar_gen3_thermal.c +++ b/drivers/thermal/rcar_gen3_thermal.c @@ -225,7 +225,7 @@ static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high) return 0; } -static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { +static const struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { .get_temp = rcar_gen3_thermal_get_temp, .set_trips = rcar_gen3_thermal_set_trips, }; diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 4c779651245351ea488cf20dec87199d755eb135..206035139110af98ab8010137be2ac2721f11bc3 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -320,6 +320,44 @@ static const struct tsadc_table rk3288_code_table[] = { {0, 125000}, }; +static const struct tsadc_table rk3328_code_table[] = { + {0, -40000}, + {296, -40000}, + {304, -35000}, + {313, -30000}, + {331, -20000}, + {340, -15000}, + {349, -10000}, + {359, -5000}, + {368, 0}, + {378, 5000}, + {388, 10000}, + {398, 15000}, + {408, 20000}, + {418, 25000}, + {429, 30000}, + {440, 35000}, + {451, 40000}, + {462, 45000}, + {473, 50000}, + {485, 55000}, + {496, 60000}, + {508, 65000}, + {521, 70000}, + {533, 75000}, + {546, 80000}, + {559, 85000}, + {572, 90000}, + {586, 95000}, + {600, 100000}, + {614, 105000}, + {629, 110000}, + {644, 115000}, + {659, 120000}, + {675, 125000}, + {TSADCV2_DATA_MASK, 125000}, +}; + static const struct tsadc_table rk3368_code_table[] = { {0, -40000}, {106, -40000}, @@ -790,6 +828,29 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = { }, }; +static const struct rockchip_tsadc_chip rk3328_tsadc_data = { + .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + .chn_num = 1, /* one channels for tsadc */ + + .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = { + .id = rk3328_code_table, + .length = ARRAY_SIZE(rk3328_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + static const struct rockchip_tsadc_chip rk3366_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ @@ -874,6 +935,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .compatible = "rockchip,rk3288-tsadc", .data = (void *)&rk3288_tsadc_data, }, + { + .compatible = "rockchip,rk3328-tsadc", + .data = (void *)&rk3328_tsadc_data, + }, { .compatible = "rockchip,rk3366-tsadc", .data = (void *)&rk3366_tsadc_data, diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 7b8ef09d2b3cfda5fc48b18c9a84965d15a00cc9..ed805c7c5ace3a121be27359bb4d08ee42634a4d 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1286,7 +1286,7 @@ static int exynos_map_dt_data(struct platform_device *pdev) return 0; } -static struct thermal_zone_of_device_ops exynos_sensor_ops = { +static const struct thermal_zone_of_device_ops exynos_sensor_ops = { .get_temp = exynos_get_temp, .set_emul_temp = exynos_tmu_set_emulation, }; diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 5a51c740e37238b31b9883d689aa67ffaea15704..2b1b0ba393a4b75b827fea732ea42f510563a29e 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -390,7 +390,7 @@ static void handle_critical_trips(struct thermal_zone_device *tz, if (trip_type == THERMAL_TRIP_CRITICAL) { dev_emerg(&tz->device, - "critical temperature reached(%d C),shutting down\n", + "critical temperature reached (%d C), shutting down\n", tz->temperature / 1000); mutex_lock(&poweroff_lock); if (!power_off_triggered) { @@ -836,11 +836,7 @@ static void thermal_release(struct device *dev) if (!strncmp(dev_name(dev), "thermal_zone", sizeof("thermal_zone") - 1)) { tz = to_thermal_zone(dev); - kfree(tz->trip_type_attrs); - kfree(tz->trip_temp_attrs); - kfree(tz->trip_hyst_attrs); - kfree(tz->trips_attribute_group.attrs); - kfree(tz->device.groups); + thermal_zone_destroy_device_groups(tz); kfree(tz); } else if (!strncmp(dev_name(dev), "cooling_device", sizeof("cooling_device") - 1)) { @@ -1213,10 +1209,8 @@ thermal_zone_device_register(const char *type, int trips, int mask, ida_init(&tz->ida); mutex_init(&tz->lock); result = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL); - if (result < 0) { - kfree(tz); - return ERR_PTR(result); - } + if (result < 0) + goto free_tz; tz->id = result; strlcpy(tz->type, type, sizeof(tz->type)); @@ -1232,18 +1226,15 @@ thermal_zone_device_register(const char *type, int trips, int mask, /* Add nodes that are always present via .groups */ result = thermal_zone_create_device_groups(tz, mask); if (result) - goto unregister; + goto remove_id; /* A new thermal zone needs to be updated anyway. */ atomic_set(&tz->need_update, 1); dev_set_name(&tz->device, "thermal_zone%d", tz->id); result = device_register(&tz->device); - if (result) { - ida_simple_remove(&thermal_tz_ida, tz->id); - kfree(tz); - return ERR_PTR(result); - } + if (result) + goto remove_device_groups; for (count = 0; count < trips; count++) { if (tz->ops->get_trip_type(tz, count, &trip_type)) @@ -1297,6 +1288,14 @@ thermal_zone_device_register(const char *type, int trips, int mask, ida_simple_remove(&thermal_tz_ida, tz->id); device_unregister(&tz->device); return ERR_PTR(result); + +remove_device_groups: + thermal_zone_destroy_device_groups(tz); +remove_id: + ida_simple_remove(&thermal_tz_ida, tz->id); +free_tz: + kfree(tz); + return ERR_PTR(result); } EXPORT_SYMBOL_GPL(thermal_zone_device_register); diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 2412b3759e16c0404b0dd803a9328c23ac6116a5..27e3b1df73608a860b82fcb5ec993f3aa0655821 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -71,6 +71,7 @@ int thermal_build_list_of_policies(char *buf); /* sysfs I/F */ int thermal_zone_create_device_groups(struct thermal_zone_device *, int); +void thermal_zone_destroy_device_groups(struct thermal_zone_device *); void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *); /* used only at binding time */ ssize_t diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index a694de907a266b6c9661545d77de513c0e890365..fb80c96d8f73a52a6d821a3bd57b78c08b6f5e26 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -605,6 +605,24 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) return 0; } +/** + * destroy_trip_attrs() - destroy attributes for trip points + * @tz: the thermal zone device + * + * helper function to free resources allocated by create_trip_attrs() + */ +static void destroy_trip_attrs(struct thermal_zone_device *tz) +{ + if (!tz) + return; + + kfree(tz->trip_type_attrs); + kfree(tz->trip_temp_attrs); + if (tz->ops->get_trip_hyst) + kfree(tz->trip_hyst_attrs); + kfree(tz->trips_attribute_group.attrs); +} + int thermal_zone_create_device_groups(struct thermal_zone_device *tz, int mask) { @@ -637,6 +655,17 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *tz, return 0; } +void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz) +{ + if (!tz) + return; + + if (tz->trips) + destroy_trip_attrs(tz); + + kfree(tz->device.groups); +} + /* sys I/F for cooling device */ static ssize_t thermal_cooling_device_type_show(struct device *dev, diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c new file mode 100644 index 0000000000000000000000000000000000000000..95704732f76050d8c3f3b6f83bc8e4cee08f189a --- /dev/null +++ b/drivers/thermal/uniphier_thermal.c @@ -0,0 +1,384 @@ +/** + * uniphier_thermal.c - Socionext UniPhier thermal driver + * + * Copyright 2014 Panasonic Corporation + * Copyright 2016-2017 Socionext Inc. + * All rights reserved. + * + * Author: + * Kunihiko Hayashi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thermal_core.h" + +/* + * block registers + * addresses are the offset from .block_base + */ +#define PVTCTLEN 0x0000 +#define PVTCTLEN_EN BIT(0) + +#define PVTCTLMODE 0x0004 +#define PVTCTLMODE_MASK 0xf +#define PVTCTLMODE_TEMPMON 0x5 + +#define EMONREPEAT 0x0040 +#define EMONREPEAT_ENDLESS BIT(24) +#define EMONREPEAT_PERIOD GENMASK(3, 0) +#define EMONREPEAT_PERIOD_1000000 0x9 + +/* + * common registers + * addresses are the offset from .map_base + */ +#define PVTCTLSEL 0x0900 +#define PVTCTLSEL_MASK GENMASK(2, 0) +#define PVTCTLSEL_MONITOR 0 + +#define SETALERT0 0x0910 +#define SETALERT1 0x0914 +#define SETALERT2 0x0918 +#define SETALERT_TEMP_OVF (GENMASK(7, 0) << 16) +#define SETALERT_TEMP_OVF_VALUE(val) (((val) & GENMASK(7, 0)) << 16) +#define SETALERT_EN BIT(0) + +#define PMALERTINTCTL 0x0920 +#define PMALERTINTCTL_CLR(ch) BIT(4 * (ch) + 2) +#define PMALERTINTCTL_SET(ch) BIT(4 * (ch) + 1) +#define PMALERTINTCTL_EN(ch) BIT(4 * (ch) + 0) +#define PMALERTINTCTL_MASK (GENMASK(10, 8) | GENMASK(6, 4) | \ + GENMASK(2, 0)) + +#define TMOD 0x0928 +#define TMOD_WIDTH 9 + +#define TMODCOEF 0x0e5c + +#define TMODSETUP0_EN BIT(30) +#define TMODSETUP0_VAL(val) (((val) & GENMASK(13, 0)) << 16) +#define TMODSETUP1_EN BIT(15) +#define TMODSETUP1_VAL(val) ((val) & GENMASK(14, 0)) + +/* SoC critical temperature */ +#define CRITICAL_TEMP_LIMIT (120 * 1000) + +/* Max # of alert channels */ +#define ALERT_CH_NUM 3 + +/* SoC specific thermal sensor data */ +struct uniphier_tm_soc_data { + u32 map_base; + u32 block_base; + u32 tmod_setup_addr; +}; + +struct uniphier_tm_dev { + struct regmap *regmap; + struct device *dev; + bool alert_en[ALERT_CH_NUM]; + struct thermal_zone_device *tz_dev; + const struct uniphier_tm_soc_data *data; +}; + +static int uniphier_tm_initialize_sensor(struct uniphier_tm_dev *tdev) +{ + struct regmap *map = tdev->regmap; + u32 val; + u32 tmod_calib[2]; + int ret; + + /* stop PVT */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLEN, + PVTCTLEN_EN, 0); + + /* + * Since SoC has a calibrated value that was set in advance, + * TMODCOEF shows non-zero and PVT refers the value internally. + * + * If TMODCOEF shows zero, the boards don't have the calibrated + * value, and the driver has to set default value from DT. + */ + ret = regmap_read(map, tdev->data->map_base + TMODCOEF, &val); + if (ret) + return ret; + if (!val) { + /* look for the default values in DT */ + ret = of_property_read_u32_array(tdev->dev->of_node, + "socionext,tmod-calibration", + tmod_calib, + ARRAY_SIZE(tmod_calib)); + if (ret) + return ret; + + regmap_write(map, tdev->data->tmod_setup_addr, + TMODSETUP0_EN | TMODSETUP0_VAL(tmod_calib[0]) | + TMODSETUP1_EN | TMODSETUP1_VAL(tmod_calib[1])); + } + + /* select temperature mode */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLMODE, + PVTCTLMODE_MASK, PVTCTLMODE_TEMPMON); + + /* set monitoring period */ + regmap_write_bits(map, tdev->data->block_base + EMONREPEAT, + EMONREPEAT_ENDLESS | EMONREPEAT_PERIOD, + EMONREPEAT_ENDLESS | EMONREPEAT_PERIOD_1000000); + + /* set monitor mode */ + regmap_write_bits(map, tdev->data->map_base + PVTCTLSEL, + PVTCTLSEL_MASK, PVTCTLSEL_MONITOR); + + return 0; +} + +static void uniphier_tm_set_alert(struct uniphier_tm_dev *tdev, u32 ch, + u32 temp) +{ + struct regmap *map = tdev->regmap; + + /* set alert temperature */ + regmap_write_bits(map, tdev->data->map_base + SETALERT0 + (ch << 2), + SETALERT_EN | SETALERT_TEMP_OVF, + SETALERT_EN | + SETALERT_TEMP_OVF_VALUE(temp / 1000)); +} + +static void uniphier_tm_enable_sensor(struct uniphier_tm_dev *tdev) +{ + struct regmap *map = tdev->regmap; + int i; + u32 bits = 0; + + for (i = 0; i < ALERT_CH_NUM; i++) + if (tdev->alert_en[i]) + bits |= PMALERTINTCTL_EN(i); + + /* enable alert interrupt */ + regmap_write_bits(map, tdev->data->map_base + PMALERTINTCTL, + PMALERTINTCTL_MASK, bits); + + /* start PVT */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLEN, + PVTCTLEN_EN, PVTCTLEN_EN); + + usleep_range(700, 1500); /* The spec note says at least 700us */ +} + +static void uniphier_tm_disable_sensor(struct uniphier_tm_dev *tdev) +{ + struct regmap *map = tdev->regmap; + + /* disable alert interrupt */ + regmap_write_bits(map, tdev->data->map_base + PMALERTINTCTL, + PMALERTINTCTL_MASK, 0); + + /* stop PVT */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLEN, + PVTCTLEN_EN, 0); + + usleep_range(1000, 2000); /* The spec note says at least 1ms */ +} + +static int uniphier_tm_get_temp(void *data, int *out_temp) +{ + struct uniphier_tm_dev *tdev = data; + struct regmap *map = tdev->regmap; + int ret; + u32 temp; + + ret = regmap_read(map, tdev->data->map_base + TMOD, &temp); + if (ret) + return ret; + + /* MSB of the TMOD field is a sign bit */ + *out_temp = sign_extend32(temp, TMOD_WIDTH - 1) * 1000; + + return 0; +} + +static const struct thermal_zone_of_device_ops uniphier_of_thermal_ops = { + .get_temp = uniphier_tm_get_temp, +}; + +static void uniphier_tm_irq_clear(struct uniphier_tm_dev *tdev) +{ + u32 mask = 0, bits = 0; + int i; + + for (i = 0; i < ALERT_CH_NUM; i++) { + mask |= (PMALERTINTCTL_CLR(i) | PMALERTINTCTL_SET(i)); + bits |= PMALERTINTCTL_CLR(i); + } + + /* clear alert interrupt */ + regmap_write_bits(tdev->regmap, + tdev->data->map_base + PMALERTINTCTL, mask, bits); +} + +static irqreturn_t uniphier_tm_alarm_irq(int irq, void *_tdev) +{ + struct uniphier_tm_dev *tdev = _tdev; + + disable_irq_nosync(irq); + uniphier_tm_irq_clear(tdev); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t uniphier_tm_alarm_irq_thread(int irq, void *_tdev) +{ + struct uniphier_tm_dev *tdev = _tdev; + + thermal_zone_device_update(tdev->tz_dev, THERMAL_EVENT_UNSPECIFIED); + + return IRQ_HANDLED; +} + +static int uniphier_tm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + struct device_node *parent; + struct uniphier_tm_dev *tdev; + const struct thermal_trip *trips; + int i, ret, irq, ntrips, crit_temp = INT_MAX; + + tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); + if (!tdev) + return -ENOMEM; + tdev->dev = dev; + + tdev->data = of_device_get_match_data(dev); + if (WARN_ON(!tdev->data)) + return -EINVAL; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + /* get regmap from syscon node */ + parent = of_get_parent(dev->of_node); /* parent should be syscon node */ + regmap = syscon_node_to_regmap(parent); + of_node_put(parent); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap (error %ld)\n", + PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + tdev->regmap = regmap; + + ret = uniphier_tm_initialize_sensor(tdev); + if (ret) { + dev_err(dev, "failed to initialize sensor\n"); + return ret; + } + + ret = devm_request_threaded_irq(dev, irq, uniphier_tm_alarm_irq, + uniphier_tm_alarm_irq_thread, + 0, "thermal", tdev); + if (ret) + return ret; + + platform_set_drvdata(pdev, tdev); + + tdev->tz_dev = devm_thermal_zone_of_sensor_register(dev, 0, tdev, + &uniphier_of_thermal_ops); + if (IS_ERR(tdev->tz_dev)) { + dev_err(dev, "failed to register sensor device\n"); + return PTR_ERR(tdev->tz_dev); + } + + /* get trip points */ + trips = of_thermal_get_trip_points(tdev->tz_dev); + ntrips = of_thermal_get_ntrips(tdev->tz_dev); + if (ntrips > ALERT_CH_NUM) { + dev_err(dev, "thermal zone has too many trips\n"); + return -E2BIG; + } + + /* set alert temperatures */ + for (i = 0; i < ntrips; i++) { + if (trips[i].type == THERMAL_TRIP_CRITICAL && + trips[i].temperature < crit_temp) + crit_temp = trips[i].temperature; + uniphier_tm_set_alert(tdev, i, trips[i].temperature); + tdev->alert_en[i] = true; + } + if (crit_temp > CRITICAL_TEMP_LIMIT) { + dev_err(dev, "critical trip is over limit(>%d), or not set\n", + CRITICAL_TEMP_LIMIT); + return -EINVAL; + } + + uniphier_tm_enable_sensor(tdev); + + return 0; +} + +static int uniphier_tm_remove(struct platform_device *pdev) +{ + struct uniphier_tm_dev *tdev = platform_get_drvdata(pdev); + + /* disable sensor */ + uniphier_tm_disable_sensor(tdev); + + return 0; +} + +static const struct uniphier_tm_soc_data uniphier_pxs2_tm_data = { + .map_base = 0xe000, + .block_base = 0xe000, + .tmod_setup_addr = 0xe904, +}; + +static const struct uniphier_tm_soc_data uniphier_ld20_tm_data = { + .map_base = 0xe000, + .block_base = 0xe800, + .tmod_setup_addr = 0xe938, +}; + +static const struct of_device_id uniphier_tm_dt_ids[] = { + { + .compatible = "socionext,uniphier-pxs2-thermal", + .data = &uniphier_pxs2_tm_data, + }, + { + .compatible = "socionext,uniphier-ld20-thermal", + .data = &uniphier_ld20_tm_data, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, uniphier_tm_dt_ids); + +static struct platform_driver uniphier_tm_driver = { + .probe = uniphier_tm_probe, + .remove = uniphier_tm_remove, + .driver = { + .name = "uniphier-thermal", + .of_match_table = uniphier_tm_dt_ids, + }, +}; +module_platform_driver(uniphier_tm_driver); + +MODULE_AUTHOR("Kunihiko Hayashi "); +MODULE_DESCRIPTION("UniPhier thermal driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c index a5670ad2cfc8150e903fdf0cad0ee24e5c7a4e43..6acce0bce7c02b3faf3fad01295197fb979d4701 100644 --- a/drivers/thermal/zx2967_thermal.c +++ b/drivers/thermal/zx2967_thermal.c @@ -111,7 +111,7 @@ static int zx2967_thermal_get_temp(void *data, int *temp) return ret; } -static struct thermal_zone_of_device_ops zx2967_of_thermal_ops = { +static const struct thermal_zone_of_device_ops zx2967_of_thermal_ops = { .get_temp = zx2967_thermal_get_temp, }; diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index 69c0232a22f833d0d2d23e4416deff15c8a8e8e3..fb40dd0588b9a7743e99e9af764772308d8d56c8 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -804,7 +804,7 @@ struct tb_cfg_result tb_cfg_reset(struct tb_ctl *ctl, u64 route, req->request_type = TB_CFG_PKG_RESET; req->response = &reply; req->response_size = sizeof(reply); - req->response_type = sizeof(TB_CFG_PKG_RESET); + req->response_type = TB_CFG_PKG_RESET; res = tb_cfg_request_sync(ctl, req, timeout_msec); diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c index 308b6e17c88aace0775b4ed0a5460097559d66ca..fe2f00ceafc5d7e1a3bbafea4224c838dc2158a4 100644 --- a/drivers/thunderbolt/eeprom.c +++ b/drivers/thunderbolt/eeprom.c @@ -333,6 +333,15 @@ static int tb_drom_parse_entry_port(struct tb_switch *sw, int res; enum tb_port_type type; + /* + * Some DROMs list more ports than the controller actually has + * so we skip those but allow the parser to continue. + */ + if (header->index > sw->config.max_port_number) { + dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n"); + return 0; + } + port = &sw->ports[header->index]; port->disabled = header->port_disabled; if (port->disabled) diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c index 8ee34029021986c94319e20adf4d36ce1d4ef374..53250fc057e1f355b490286ca545fcc2b8d4fb54 100644 --- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -13,9 +13,9 @@ */ #include -#include #include #include +#include #include #include #include @@ -102,11 +102,6 @@ static inline u64 get_route(u32 route_hi, u32 route_lo) return (u64)route_hi << 32 | route_lo; } -static inline bool is_apple(void) -{ - return dmi_match(DMI_BOARD_VENDOR, "Apple Inc."); -} - static bool icm_match(const struct tb_cfg_request *req, const struct ctl_pkg *pkg) { @@ -176,7 +171,7 @@ static int icm_request(struct tb *tb, const void *request, size_t request_size, static bool icm_fr_is_supported(struct tb *tb) { - return !is_apple(); + return !x86_apple_machine; } static inline int icm_fr_get_switch_index(u32 port) @@ -517,7 +512,7 @@ static bool icm_ar_is_supported(struct tb *tb) * Starting from Alpine Ridge we can use ICM on Apple machines * as well. We just need to reset and re-enable it first. */ - if (!is_apple()) + if (!x86_apple_machine) return true; /* @@ -904,7 +899,14 @@ static int icm_driver_ready(struct tb *tb) static int icm_suspend(struct tb *tb) { - return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0); + int ret; + + ret = nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0); + if (ret) + tb_info(tb, "Ignoring mailbox command error (%d) in %s\n", + ret, __func__); + + return 0; } /* @@ -1004,7 +1006,7 @@ static int icm_start(struct tb *tb) * don't provide images publicly either. To be on the safe side * prevent root switch NVM upgrade on Macs for now. */ - tb->root_switch->no_nvm_upgrade = is_apple(); + tb->root_switch->no_nvm_upgrade = x86_apple_machine; ret = tb_switch_add(tb->root_switch); if (ret) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index e9391bbd4036023c63d8b7ec90185f56f9523ade..53f40c57df59ccaefe0f69ab0d02977b3406e518 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -807,11 +807,11 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr, struct tb_switch *sw = tb_to_switch(dev); u8 key[TB_SWITCH_KEY_SIZE]; ssize_t ret = count; + bool clear = false; - if (count < 64) - return -EINVAL; - - if (hex2bin(key, buf, sizeof(key))) + if (!strcmp(buf, "\n")) + clear = true; + else if (hex2bin(key, buf, sizeof(key))) return -EINVAL; if (mutex_lock_interruptible(&switch_lock)) @@ -821,15 +821,19 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr, ret = -EBUSY; } else { kfree(sw->key); - sw->key = kmemdup(key, sizeof(key), GFP_KERNEL); - if (!sw->key) - ret = -ENOMEM; + if (clear) { + sw->key = NULL; + } else { + sw->key = kmemdup(key, sizeof(key), GFP_KERNEL); + if (!sw->key) + ret = -ENOMEM; + } } mutex_unlock(&switch_lock); return ret; } -static DEVICE_ATTR_RW(key); +static DEVICE_ATTR(key, 0600, key_show, key_store); static ssize_t nvm_authenticate_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 1b02ca0b6129d12bfd93dd111bf1204c8eee2c43..0b22ad9d68b4107ff199f9e0382ee6ccf30e2599 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "tb.h" #include "tb_regs.h" @@ -453,7 +453,7 @@ struct tb *tb_probe(struct tb_nhi *nhi) struct tb_cm *tcm; struct tb *tb; - if (!dmi_match(DMI_BOARD_VENDOR, "Apple Inc.")) + if (!x86_apple_machine) return NULL; tb = tb_domain_alloc(nhi, sizeof(*tcm)); diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 95103054c0e469faf05472a6f3aa6e84e132eee1..cc2b4d9433ed2ccf85406de35f53f69a58404973 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -392,6 +392,9 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE config GOLDFISH_TTY tristate "Goldfish TTY Driver" depends on GOLDFISH + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON help Console and system TTY driver for the Goldfish virtual platform. @@ -455,4 +458,9 @@ config MIPS_EJTAG_FDC_KGDB_CHAN help FDC channel number to use for KGDB. +config VCC + tristate "Sun Virtual Console Concentrator" + depends on SUN_LDOMS + help + Support for Sun logical domain consoles. endif # TTY diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 8689279afdf1b53169243f2629076fb9fb3e7a29..16330a819685947e6c74dd139cdb4bef6b3b1f5f 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -33,5 +33,6 @@ obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o obj-$(CONFIG_DA_TTY) += metag_da.o obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o +obj-$(CONFIG_VCC) += vcc.o obj-y += ipwireless/ diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 61fe8d6fd24e1bb0cf2cdfd2a4de67ceb05123bf..a1c7125cb968fdcbe9f69a5c29b306adff000b66 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -122,7 +122,7 @@ static int find_console_handle(void) stdout_irq = irq_of_parse_and_map(np, 0); if (stdout_irq == NO_IRQ) { - pr_err("ehv-bc: no 'interrupts' property in %s node\n", np->full_name); + pr_err("ehv-bc: no 'interrupts' property in %pOF node\n", np); return 0; } diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 996bd473dd03ea6f211f2338d8f95161e5f1da33..381e981dee06fd5afde362c59adf8cbcada717dd 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2007 Google, Inc. * Copyright (C) 2012 Intel, Inc. + * Copyright (C) 2017 Imagination Technologies Ltd. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -22,21 +23,23 @@ #include #include #include - -enum { - GOLDFISH_TTY_PUT_CHAR = 0x00, - GOLDFISH_TTY_BYTES_READY = 0x04, - GOLDFISH_TTY_CMD = 0x08, - - GOLDFISH_TTY_DATA_PTR = 0x10, - GOLDFISH_TTY_DATA_LEN = 0x14, - GOLDFISH_TTY_DATA_PTR_HIGH = 0x18, - - GOLDFISH_TTY_CMD_INT_DISABLE = 0, - GOLDFISH_TTY_CMD_INT_ENABLE = 1, - GOLDFISH_TTY_CMD_WRITE_BUFFER = 2, - GOLDFISH_TTY_CMD_READ_BUFFER = 3, -}; +#include +#include +#include + +/* Goldfish tty register's offsets */ +#define GOLDFISH_TTY_REG_BYTES_READY 0x04 +#define GOLDFISH_TTY_REG_CMD 0x08 +#define GOLDFISH_TTY_REG_DATA_PTR 0x10 +#define GOLDFISH_TTY_REG_DATA_LEN 0x14 +#define GOLDFISH_TTY_REG_DATA_PTR_HIGH 0x18 +#define GOLDFISH_TTY_REG_VERSION 0x20 + +/* Goldfish tty commands */ +#define GOLDFISH_TTY_CMD_INT_DISABLE 0 +#define GOLDFISH_TTY_CMD_INT_ENABLE 1 +#define GOLDFISH_TTY_CMD_WRITE_BUFFER 2 +#define GOLDFISH_TTY_CMD_READ_BUFFER 3 struct goldfish_tty { struct tty_port port; @@ -45,6 +48,8 @@ struct goldfish_tty { u32 irq; int opencount; struct console console; + u32 version; + struct device *dev; }; static DEFINE_MUTEX(goldfish_tty_lock); @@ -53,38 +58,107 @@ static u32 goldfish_tty_line_count = 8; static u32 goldfish_tty_current_line_count; static struct goldfish_tty *goldfish_ttys; -static void goldfish_tty_do_write(int line, const char *buf, unsigned count) +static void do_rw_io(struct goldfish_tty *qtty, + unsigned long address, + unsigned int count, + int is_write) { unsigned long irq_flags; - struct goldfish_tty *qtty = &goldfish_ttys[line]; void __iomem *base = qtty->base; + spin_lock_irqsave(&qtty->lock, irq_flags); - gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR, - base + GOLDFISH_TTY_DATA_PTR_HIGH); - writel(count, base + GOLDFISH_TTY_DATA_LEN); - writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_CMD); + gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR, + base + GOLDFISH_TTY_REG_DATA_PTR_HIGH); + writel(count, base + GOLDFISH_TTY_REG_DATA_LEN); + + if (is_write) + writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, + base + GOLDFISH_TTY_REG_CMD); + else + writel(GOLDFISH_TTY_CMD_READ_BUFFER, + base + GOLDFISH_TTY_REG_CMD); + spin_unlock_irqrestore(&qtty->lock, irq_flags); } +static void goldfish_tty_rw(struct goldfish_tty *qtty, + unsigned long addr, + unsigned int count, + int is_write) +{ + dma_addr_t dma_handle; + enum dma_data_direction dma_dir; + + dma_dir = (is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + if (qtty->version > 0) { + /* + * Goldfish TTY for Ranchu platform uses + * physical addresses and DMA for read/write operations + */ + unsigned long addr_end = addr + count; + + while (addr < addr_end) { + unsigned long pg_end = (addr & PAGE_MASK) + PAGE_SIZE; + unsigned long next = + pg_end < addr_end ? pg_end : addr_end; + unsigned long avail = next - addr; + + /* + * Map the buffer's virtual address to the DMA address + * so the buffer can be accessed by the device. + */ + dma_handle = dma_map_single(qtty->dev, (void *)addr, + avail, dma_dir); + + if (dma_mapping_error(qtty->dev, dma_handle)) { + dev_err(qtty->dev, "tty: DMA mapping error.\n"); + return; + } + do_rw_io(qtty, dma_handle, avail, is_write); + + /* + * Unmap the previously mapped region after + * the completion of the read/write operation. + */ + dma_unmap_single(qtty->dev, dma_handle, avail, dma_dir); + + addr += avail; + } + } else { + /* + * Old style Goldfish TTY used on the Goldfish platform + * uses virtual addresses. + */ + do_rw_io(qtty, addr, count, is_write); + } +} + +static void goldfish_tty_do_write(int line, const char *buf, + unsigned int count) +{ + struct goldfish_tty *qtty = &goldfish_ttys[line]; + unsigned long address = (unsigned long)(void *)buf; + + goldfish_tty_rw(qtty, address, count, 1); +} + static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) { struct goldfish_tty *qtty = dev_id; void __iomem *base = qtty->base; - unsigned long irq_flags; + unsigned long address; unsigned char *buf; u32 count; - count = readl(base + GOLDFISH_TTY_BYTES_READY); + count = readl(base + GOLDFISH_TTY_REG_BYTES_READY); if (count == 0) return IRQ_NONE; count = tty_prepare_flip_string(&qtty->port, &buf, count); - spin_lock_irqsave(&qtty->lock, irq_flags); - gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR, - base + GOLDFISH_TTY_DATA_PTR_HIGH); - writel(count, base + GOLDFISH_TTY_DATA_LEN); - writel(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_CMD); - spin_unlock_irqrestore(&qtty->lock, irq_flags); + + address = (unsigned long)(void *)buf; + goldfish_tty_rw(qtty, address, count, 0); + tty_schedule_flip(&qtty->port); return IRQ_HANDLED; } @@ -93,7 +167,7 @@ static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty) { struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); - writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_CMD); + writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD); return 0; } @@ -101,7 +175,7 @@ static void goldfish_tty_shutdown(struct tty_port *port) { struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); - writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_CMD); + writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD); } static int goldfish_tty_open(struct tty_struct *tty, struct file *filp) @@ -136,7 +210,7 @@ static int goldfish_tty_chars_in_buffer(struct tty_struct *tty) { struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; void __iomem *base = qtty->base; - return readl(base + GOLDFISH_TTY_BYTES_READY); + return readl(base + GOLDFISH_TTY_REG_BYTES_READY); } static void goldfish_tty_console_write(struct console *co, const char *b, @@ -227,7 +301,7 @@ static void goldfish_tty_delete_driver(void) static int goldfish_tty_probe(struct platform_device *pdev) { struct goldfish_tty *qtty; - int ret = -EINVAL; + int ret = -ENODEV; struct resource *r; struct device *ttydev; void __iomem *base; @@ -235,16 +309,22 @@ static int goldfish_tty_probe(struct platform_device *pdev) unsigned int line; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) - return -EINVAL; + if (!r) { + pr_err("goldfish_tty: No MEM resource available!\n"); + return -ENOMEM; + } base = ioremap(r->start, 0x1000); - if (base == NULL) - pr_err("goldfish_tty: unable to remap base\n"); + if (!base) { + pr_err("goldfish_tty: Unable to ioremap base!\n"); + return -ENOMEM; + } r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (r == NULL) + if (!r) { + pr_err("goldfish_tty: No IRQ resource available!\n"); goto err_unmap; + } irq = r->start; @@ -255,13 +335,17 @@ static int goldfish_tty_probe(struct platform_device *pdev) else line = pdev->id; - if (line >= goldfish_tty_line_count) - goto err_create_driver_failed; + if (line >= goldfish_tty_line_count) { + pr_err("goldfish_tty: Reached maximum tty number of %d.\n", + goldfish_tty_current_line_count); + ret = -ENOMEM; + goto err_unlock; + } if (goldfish_tty_current_line_count == 0) { ret = goldfish_tty_create_driver(); if (ret) - goto err_create_driver_failed; + goto err_unlock; } goldfish_tty_current_line_count++; @@ -271,17 +355,45 @@ static int goldfish_tty_probe(struct platform_device *pdev) qtty->port.ops = &goldfish_port_ops; qtty->base = base; qtty->irq = irq; + qtty->dev = &pdev->dev; + + /* + * Goldfish TTY device used by the Goldfish emulator + * should identify itself with 0, forcing the driver + * to use virtual addresses. Goldfish TTY device + * on Ranchu emulator (qemu2) returns 1 here and + * driver will use physical addresses. + */ + qtty->version = readl(base + GOLDFISH_TTY_REG_VERSION); + + /* + * Goldfish TTY device on Ranchu emulator (qemu2) + * will use DMA for read/write IO operations. + */ + if (qtty->version > 0) { + /* + * Initialize dma_mask to 32-bits. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "No suitable DMA available.\n"); + goto err_dec_line_count; + } + } - writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD); + writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD); ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, - "goldfish_tty", qtty); - if (ret) - goto err_request_irq_failed; - + "goldfish_tty", qtty); + if (ret) { + pr_err("goldfish_tty: No IRQ available!\n"); + goto err_dec_line_count; + } ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver, - line, &pdev->dev); + line, &pdev->dev); if (IS_ERR(ttydev)) { ret = PTR_ERR(ttydev); goto err_tty_register_device_failed; @@ -301,11 +413,11 @@ static int goldfish_tty_probe(struct platform_device *pdev) err_tty_register_device_failed: free_irq(irq, qtty); -err_request_irq_failed: +err_dec_line_count: goldfish_tty_current_line_count--; if (goldfish_tty_current_line_count == 0) goldfish_tty_delete_driver(); -err_create_driver_failed: +err_unlock: mutex_unlock(&goldfish_tty_lock); err_unmap: iounmap(base); @@ -330,6 +442,30 @@ static int goldfish_tty_remove(struct platform_device *pdev) return 0; } +static void gf_early_console_putchar(struct uart_port *port, int ch) +{ + __raw_writel(ch, port->membase); +} + +static void gf_early_write(struct console *con, const char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, gf_early_console_putchar); +} + +static int __init gf_earlycon_setup(struct earlycon_device *device, + const char *opt) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = gf_early_write; + return 0; +} + +OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup); + static const struct of_device_id goldfish_tty_of_match[] = { { .compatible = "google,goldfish-tty", }, {}, diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index b8d5ea0ae26b49e8814ac2f187a708a77a23f92f..fec457edad14800c5ed07476afe5f2a9986478c8 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig @@ -4,7 +4,7 @@ config HVC_DRIVER bool help Generic "hypervisor virtual console" infrastructure for various - hypervisors (pSeries, iSeries, Xen, lguest). + hypervisors (pSeries, iSeries, Xen). It will automatically be selected if one of the back-end console drivers is selected. diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 51079931109956178a0730716307c7c773f7c643..16331a90c1e89f3430e6c5e5909a05e7e8914aed 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -179,8 +179,8 @@ static int hvc_opal_probe(struct platform_device *dev) proto = HV_PROTOCOL_HVSI; ops = &hvc_opal_hvsi_ops; } else { - pr_err("hvc_opal: Unknown protocol for %s\n", - dev->dev.of_node->full_name); + pr_err("hvc_opal: Unknown protocol for %pOF\n", + dev->dev.of_node); return -ENXIO; } @@ -204,14 +204,14 @@ static int hvc_opal_probe(struct platform_device *dev) /* Instanciate now to establish a mapping index==vtermno */ hvc_instantiate(termno, termno, ops); } else { - pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n", - dev->dev.of_node->full_name, termno); + pr_err("hvc_opal: Device %pOF has duplicate terminal number #%d\n", + dev->dev.of_node, termno); return -ENXIO; } - pr_info("hvc%d: %s protocol on %s%s\n", termno, + pr_info("hvc%d: %s protocol on %pOF%s\n", termno, proto == HV_PROTOCOL_RAW ? "raw" : "hvsi", - dev->dev.of_node->full_name, + dev->dev.of_node, boot ? " (boot console)" : ""); irq = irq_of_parse_and_map(dev->dev.of_node, 0); @@ -222,8 +222,8 @@ static int hvc_opal_probe(struct platform_device *dev) } if (!irq) { - pr_err("hvc_opal: Unable to map interrupt for device %s\n", - dev->dev.of_node->full_name); + pr_err("hvc_opal: Unable to map interrupt for device %pOF\n", + dev->dev.of_node); return irq; } diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index b05dc508662795639d391aee29ed568c2e2fe75e..a1d272ac82bb49cc761df70b38ebc119ff5359e6 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -53,7 +53,7 @@ static const char hvc_driver_name[] = "hvc_console"; -static struct vio_device_id hvc_driver_table[] = { +static const struct vio_device_id hvc_driver_table[] = { {"serial", "hvterm1"}, #ifndef HVC_OLD_HVSI {"serial", "hvterm-protocol"}, @@ -312,12 +312,12 @@ static int hvc_vio_probe(struct vio_dev *vdev, proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; } else { - pr_err("hvc_vio: Unknown protocol for %s\n", vdev->dev.of_node->full_name); + pr_err("hvc_vio: Unknown protocol for %pOF\n", vdev->dev.of_node); return -ENXIO; } - pr_devel("hvc_vio_probe() device %s, using %s protocol\n", - vdev->dev.of_node->full_name, + pr_devel("hvc_vio_probe() device %pOF, using %s protocol\n", + vdev->dev.of_node, proto == HV_PROTOCOL_RAW ? "raw" : "hvsi"); /* Is it our boot one ? */ @@ -442,6 +442,14 @@ void __init hvc_vio_init_early(void) #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR void __init udbg_init_debug_lpar(void) { + /* + * If we're running as a hypervisor then we definitely can't call the + * hypervisor to print debug output (we *are* the hypervisor), so don't + * register if we detect that MSR_HV=1. + */ + if (mfmsr() & MSR_HV) + return; + hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = 0; hvterm_priv0.proto = HV_PROTOCOL_RAW; @@ -455,6 +463,10 @@ void __init udbg_init_debug_lpar(void) #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR_HVSI void __init udbg_init_debug_lpar_hvsi(void) { + /* See comment above in udbg_init_debug_lpar() */ + if (mfmsr() & MSR_HV) + return; + hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = CONFIG_PPC_EARLY_DEBUG_HVSI_VTERMNO; hvterm_priv0.proto = HV_PROTOCOL_HVSI; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 79cc5beea2da20fe8525b513af53a323027479d7..63c29fe9d21f1325a90bd48c47484ef21d1e57b2 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -189,7 +189,7 @@ MODULE_VERSION(HVCS_DRIVER_VERSION); * that will cause echoing or we'll go into recursive loop echoing chars back * and forth with the console drivers. */ -static struct ktermios hvcs_tty_termios = { +static const struct ktermios hvcs_tty_termios = { .c_iflag = IGNBRK | IGNPAR, .c_oflag = OPOST, .c_cflag = B38400 | CS8 | CREAD | HUPCL, @@ -675,7 +675,7 @@ static int khvcsd(void *unused) return 0; } -static struct vio_device_id hvcs_driver_table[] = { +static const struct vio_device_id hvcs_driver_table[] = { {"serial-server", "hvterm2"}, { "", "" } }; diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index b70187b46d9d3ea92a7327fd958cc231398a5cce..61ecdd6b2fc24479bdbfcd3a24f810604908d29b 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -150,7 +150,7 @@ static int isicom_probe(struct pci_dev *, const struct pci_device_id *); static void isicom_remove(struct pci_dev *); -static struct pci_device_id isicom_pci_tbl[] = { +static const struct pci_device_id isicom_pci_tbl[] = { { PCI_DEVICE(VENDOR_ID, 0x2028) }, { PCI_DEVICE(VENDOR_ID, 0x2051) }, { PCI_DEVICE(VENDOR_ID, 0x2052) }, diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index 234123b0c642adac44294201e9fccbe33476756a..a2dab3fb8751fa2956f611172e139b1a7b6ed45b 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -1110,7 +1110,7 @@ static int mips_ejtag_fdc_tty_cpu_up(struct mips_cdmm_device *dev) return ret; } -static struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = { +static const struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = { { .type = 0xfd }, { } }; diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 3b251f4e5df046e3d8028f4ed5a86deba5fa0b04..7f3d4cb0341be03fdb3e67f06097a495cd2971b5 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -88,7 +88,7 @@ static char *moxa_brdname[] = }; #ifdef CONFIG_PCI -static struct pci_device_id moxa_pcibrds[] = { +static const struct pci_device_id moxa_pcibrds[] = { { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218), .driver_data = MOXA_BOARD_C218_PCI }, { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320), diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 8bd6fb6d9391fe419e0a2553ffe6f82f59c469fe..7dd38047ba2352d5dde2845170ecfc3e149ec27d 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -145,7 +145,7 @@ static const struct mxser_cardinfo mxser_cards[] = { /* driver_data correspond to the lines in the structure above see also ISA probe function before you change something */ -static struct pci_device_id mxser_pcibrds[] = { +static const struct pci_device_id mxser_pcibrds[] = { { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, @@ -246,11 +246,11 @@ struct mxser_port { unsigned char err_shadow; struct async_icount icount; /* kernel counters for 4 input interrupts */ - int timeout; + unsigned int timeout; int read_status_mask; int ignore_status_mask; - int xmit_fifo_size; + unsigned int xmit_fifo_size; int xmit_head; int xmit_tail; int xmit_cnt; @@ -572,8 +572,9 @@ static void mxser_dtr_rts(struct tty_port *port, int on) static int mxser_set_baud(struct tty_struct *tty, long newspd) { struct mxser_port *info = tty->driver_data; - int quot = 0, baud; + unsigned int quot = 0, baud; unsigned char cval; + u64 timeout; if (!info->ioaddr) return -1; @@ -594,8 +595,13 @@ static int mxser_set_baud(struct tty_struct *tty, long newspd) quot = 0; } - info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); - info->timeout += HZ / 50; /* Add .02 seconds of slop */ + /* + * worst case (128 * 1000 * 10 * 18432) needs 35 bits, so divide in the + * u64 domain + */ + timeout = (u64)info->xmit_fifo_size * HZ * 10 * quot; + do_div(timeout, info->baud_base); + info->timeout = timeout + HZ / 50; /* Add .02 seconds of slop */ if (quot) { info->MCR |= UART_MCR_DTR; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2afe5fce68e32040c7e96a5b3f302d167bdbd75a..0a3c9665e015492f7fbeae5c33e1900961b817c6 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2607,6 +2607,14 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file, } } +#ifdef CONFIG_COMPAT +static long gsmld_compat_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return gsmld_ioctl(tty, file, cmd, arg); +} +#endif + /* * Network interface * @@ -2818,6 +2826,9 @@ static struct tty_ldisc_ops tty_ldisc_packet = { .flush_buffer = gsmld_flush_buffer, .read = gsmld_read, .write = gsmld_write, +#ifdef CONFIG_COMPAT + .compat_ioctl = gsmld_compat_ioctl, +#endif .ioctl = gsmld_ioctl, .poll = gsmld_poll, .receive_buf = gsmld_receive_buf, diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 284749fb0f6b96d3d6d667332e569ba0d745e048..26dcb3b60fb9917e04a30533977abc4cda531b1d 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -69,13 +69,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp) #ifdef CONFIG_UNIX98_PTYS if (tty->driver == ptm_driver) { mutex_lock(&devpts_mutex); - if (tty->link->driver_data) { - struct path *path = tty->link->driver_data; - - devpts_pty_kill(path->dentry); - path_put(path); - kfree(path); - } + if (tty->link->driver_data) + devpts_pty_kill(tty->link->driver_data); mutex_unlock(&devpts_mutex); } #endif @@ -607,25 +602,24 @@ static inline void legacy_pty_init(void) { } static struct cdev ptmx_cdev; /** - * pty_open_peer - open the peer of a pty - * @tty: the peer of the pty being opened + * ptm_open_peer - open the peer of a pty + * @master: the open struct file of the ptmx device node + * @tty: the master of the pty being opened + * @flags: the flags for open * - * Open the cached dentry in tty->link, providing a safe way for userspace - * to get the slave end of a pty (where they have the master fd and cannot - * access or trust the mount namespace /dev/pts was mounted inside). + * Provide a race free way for userspace to open the slave end of a pty + * (where they have the master fd and cannot access or trust the mount + * namespace /dev/pts was mounted inside). */ -static struct file *pty_open_peer(struct tty_struct *tty, int flags) -{ - if (tty->driver->subtype != PTY_TYPE_MASTER) - return ERR_PTR(-EIO); - return dentry_open(tty->link->driver_data, flags, current_cred()); -} - -static int pty_get_peer(struct tty_struct *tty, int flags) +int ptm_open_peer(struct file *master, struct tty_struct *tty, int flags) { int fd = -1; - struct file *filp = NULL; + struct file *filp; int retval = -EINVAL; + struct path path; + + if (tty->driver != ptm_driver) + return -EIO; fd = get_unused_fd_flags(0); if (fd < 0) { @@ -633,7 +627,16 @@ static int pty_get_peer(struct tty_struct *tty, int flags) goto err; } - filp = pty_open_peer(tty, flags); + /* Compute the slave's path */ + path.mnt = devpts_mntget(master, tty->driver_data); + if (IS_ERR(path.mnt)) { + retval = PTR_ERR(path.mnt); + goto err_put; + } + path.dentry = tty->link->driver_data; + + filp = dentry_open(&path, flags, current_cred()); + mntput(path.mnt); if (IS_ERR(filp)) { retval = PTR_ERR(filp); goto err_put; @@ -662,8 +665,6 @@ static int pty_unix98_ioctl(struct tty_struct *tty, return pty_get_pktmode(tty, (int __user *)arg); case TIOCGPTN: /* Get PT Number */ return put_user(tty->index, (unsigned int __user *)arg); - case TIOCGPTPEER: /* Open the other end */ - return pty_get_peer(tty, (int) arg); case TIOCSIG: /* Send signal to other side of pty */ return pty_signal(tty, (int) arg); } @@ -741,6 +742,11 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) } } +static void pty_show_fdinfo(struct tty_struct *tty, struct seq_file *m) +{ + seq_printf(m, "tty-index:\t%d\n", tty->index); +} + static const struct tty_operations ptm_unix98_ops = { .lookup = ptm_unix98_lookup, .install = pty_unix98_install, @@ -755,7 +761,8 @@ static const struct tty_operations ptm_unix98_ops = { .ioctl = pty_unix98_ioctl, .compat_ioctl = pty_unix98_compat_ioctl, .resize = pty_resize, - .cleanup = pty_cleanup + .cleanup = pty_cleanup, + .show_fdinfo = pty_show_fdinfo, }; static const struct tty_operations pty_unix98_ops = { @@ -791,7 +798,6 @@ static int ptmx_open(struct inode *inode, struct file *filp) { struct pts_fs_info *fsi; struct tty_struct *tty; - struct path *pts_path; struct dentry *dentry; int retval; int index; @@ -845,26 +851,16 @@ static int ptmx_open(struct inode *inode, struct file *filp) retval = PTR_ERR(dentry); goto err_release; } - /* We need to cache a fake path for TIOCGPTPEER. */ - pts_path = kmalloc(sizeof(struct path), GFP_KERNEL); - if (!pts_path) - goto err_release; - pts_path->mnt = filp->f_path.mnt; - pts_path->dentry = dentry; - path_get(pts_path); - tty->link->driver_data = pts_path; + tty->link->driver_data = dentry; retval = ptm_driver->ops->open(tty, filp); if (retval) - goto err_path_put; + goto err_release; tty_debug_hangup(tty, "opening (count=%d)\n", tty->count); tty_unlock(tty); return 0; -err_path_put: - path_put(pts_path); - kfree(pts_path); err_release: tty_unlock(tty); // This will also put-ref the fsi diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index ae1aaa0075d1c1b87cc339014ef3b61c34c4fb1e..c68fb3a8ea1c3ca0d26d275b877940714968a7e7 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -363,7 +363,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl) if (!of_get_property(node, "compatible", NULL)) continue; - dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name); + dev_dbg(&ctrl->dev, "adding child %pOF\n", node); serdev = serdev_device_alloc(ctrl); if (!serdev) diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 9b208bd686e6091488b8bfc6187264a964ff9005..804632b4a929260ee0f80f4c65a9ef4bb8bfe301 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -334,7 +334,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct return ret; } -static struct uart_ops serial21285_ops = { +static const struct uart_ops serial21285_ops = { .tx_empty = serial21285_tx_empty, .get_mctrl = serial21285_get_mctrl, .set_mctrl = serial21285_set_mctrl, diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 822be490676395d25849855774db4c1d858a0ba8..33a801353114c016ca7fe5fa0aebe507a3d2844b 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -223,12 +223,13 @@ static int aspeed_vuart_probe(struct platform_device *pdev) if (IS_ERR(vuart->clk)) { dev_warn(&pdev->dev, "clk or clock-frequency not defined\n"); - return PTR_ERR(vuart->clk); + rc = PTR_ERR(vuart->clk); + goto err_sysfs_remove; } rc = clk_prepare_enable(vuart->clk); if (rc < 0) - return rc; + goto err_sysfs_remove; clk = clk_get_rate(vuart->clk); } @@ -286,6 +287,8 @@ static int aspeed_vuart_probe(struct platform_device *pdev) err_clk_disable: clk_disable_unprepare(vuart->clk); irq_dispose_mapping(port.port.irq); +err_sysfs_remove: + sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); return rc; } diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index b5def356af63b70e3ebc2e23a48da0753e41b47e..d29b512a7d9fac1b182d1f63a0a34d3c181fc46d 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -497,6 +497,11 @@ static void univ8250_rsa_support(struct uart_ops *ops) #define univ8250_rsa_support(x) do { } while (0) #endif /* CONFIG_SERIAL_8250_RSA */ +static inline void serial8250_apply_quirks(struct uart_8250_port *up) +{ + up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0; +} + static void __init serial8250_isa_init_ports(void) { struct uart_8250_port *up; @@ -577,9 +582,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) up->port.dev = dev; - if (skip_txen_test) - up->port.flags |= UPF_NO_TXEN_TEST; - + serial8250_apply_quirks(up); uart_add_one_port(drv, &up->port); } } @@ -1006,9 +1009,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) if (up->port.dev) uart->port.dev = up->port.dev; - if (skip_txen_test) - uart->port.flags |= UPF_NO_TXEN_TEST; - if (up->port.flags & UPF_FIXED_TYPE) uart->port.type = up->port.type; @@ -1043,13 +1043,25 @@ int serial8250_register_8250_port(struct uart_8250_port *up) if (up->dl_write) uart->dl_write = up->dl_write; - if (serial8250_isa_config != NULL) - serial8250_isa_config(0, &uart->port, - &uart->capabilities); + if (uart->port.type != PORT_8250_CIR) { + if (serial8250_isa_config != NULL) + serial8250_isa_config(0, &uart->port, + &uart->capabilities); + + serial8250_apply_quirks(uart); + ret = uart_add_one_port(&serial8250_reg, + &uart->port); + if (ret == 0) + ret = uart->port.line; + } else { + dev_info(uart->port.dev, + "skipping CIR port at 0x%lx / 0x%llx, IRQ %d\n", + uart->port.iobase, + (unsigned long long)uart->port.mapbase, + uart->port.irq); - ret = uart_add_one_port(&serial8250_reg, &uart->port); - if (ret == 0) - ret = uart->port.line; + ret = 0; + } } mutex_unlock(&serial_mutex); @@ -1081,11 +1093,10 @@ void serial8250_unregister_port(int line) uart_remove_one_port(&serial8250_reg, &uart->port); if (serial8250_isa_devs) { uart->port.flags &= ~UPF_BOOT_AUTOCONF; - if (skip_txen_test) - uart->port.flags |= UPF_NO_TXEN_TEST; uart->port.type = PORT_UNKNOWN; uart->port.dev = &serial8250_isa_devs->dev; uart->capabilities = 0; + serial8250_apply_quirks(uart); uart_add_one_port(&serial8250_reg, &uart->port); } else { uart->port.dev = NULL; diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 787b1160d3a535aceafc40f742652deb9d5f2182..7e638997bfc2ca18b20ad3e97aec5656d4477755 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -529,7 +529,7 @@ static int dw8250_probe(struct platform_device *pdev) } } - data->rst = devm_reset_control_get_optional(dev, NULL); + data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(data->rst)) { err = PTR_ERR(data->rst); goto err_pclk; diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 82fc48eca1df705521c99036d1a0d7f6e7d63402..af72ec32e404736f965cbc3f39c6adce8b42a1df 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -37,7 +37,7 @@ #include #include -static unsigned int __init serial8250_early_in(struct uart_port *port, int offset) +static unsigned int serial8250_early_in(struct uart_port *port, int offset) { int reg_offset = offset; offset <<= port->regshift; @@ -60,7 +60,7 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse } } -static void __init serial8250_early_out(struct uart_port *port, int offset, int value) +static void serial8250_early_out(struct uart_port *port, int offset, int value) { int reg_offset = offset; offset <<= port->regshift; @@ -89,7 +89,7 @@ static void __init serial8250_early_out(struct uart_port *port, int offset, int #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -static void __init serial_putc(struct uart_port *port, int c) +static void serial_putc(struct uart_port *port, int c) { unsigned int status; @@ -103,7 +103,7 @@ static void __init serial_putc(struct uart_port *port, int c) } } -static void __init early_serial8250_write(struct console *console, +static void early_serial8250_write(struct console *console, const char *s, unsigned int count) { struct earlycon_device *device = console->data; diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index b5c98e5bf52402c2febb0b4d64d54dd19c739446..c55624703fdf04a74fc167b702a50212204e4c62 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -261,7 +261,7 @@ __xr17v35x_register_gpio(struct pci_dev *pcidev, } static const struct property_entry exar_gpio_properties[] = { - PROPERTY_ENTRY_U32("linux,first-pin", 0), + PROPERTY_ENTRY_U32("exar,first-pin", 0), PROPERTY_ENTRY_U32("ngpios", 16), { } }; @@ -326,7 +326,7 @@ static int iot2040_rs485_config(struct uart_port *port, } static const struct property_entry iot2040_gpio_properties[] = { - PROPERTY_ENTRY_U32("linux,first-pin", 10), + PROPERTY_ENTRY_U32("exar,first-pin", 10), PROPERTY_ENTRY_U32("ngpios", 1), { } }; @@ -601,7 +601,7 @@ static const struct exar8250_board pbn_exar_XR17V8358 = { (kernel_ulong_t)&bd \ } -static struct pci_device_id exar_pci_tbl[] = { +static const struct pci_device_id exar_pci_tbl[] = { CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index 63306de4390d6ebd6efe3ba46842a372e65ca96d..df2931e1e08682bb9f23d63f24badb562acf2c00 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c @@ -80,7 +80,7 @@ static int __init serial_init_chip(struct parisc_device *dev) return 0; } -static struct parisc_device_id serial_tbl[] = { +static const struct parisc_device_id serial_tbl[] __initconst = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, @@ -94,7 +94,7 @@ static struct parisc_device_id serial_tbl[] = { * which only knows about Lasi and then a second which will find all the * other serial ports. HPUX ignores this problem. */ -static struct parisc_device_id lasi_tbl[] = { +static const struct parisc_device_id lasi_tbl[] __initconst = { { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */ @@ -110,13 +110,13 @@ static struct parisc_device_id lasi_tbl[] = { MODULE_DEVICE_TABLE(parisc, serial_tbl); -static struct parisc_driver lasi_driver = { +static struct parisc_driver lasi_driver __refdata = { .name = "serial_1", .id_table = lasi_tbl, .probe = serial_init_chip, }; -static struct parisc_driver serial_driver = { +static struct parisc_driver serial_driver __refdata = { .name = "serial", .id_table = serial_tbl, .probe = serial_init_chip, diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 4d9dc10e265c9c0dd5d850bea791e25c4475ef55..464389b289006783d3d4bbd80b493be0e80f1d17 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -50,17 +50,17 @@ static const struct of_device_id of_match[]; static struct earlycon_device *early_device; -static uint8_t __init early_in(struct uart_port *port, int offset) +static uint8_t early_in(struct uart_port *port, int offset) { return readl(port->membase + (offset << 2)); } -static void __init early_out(struct uart_port *port, int offset, uint8_t value) +static void early_out(struct uart_port *port, int offset, uint8_t value) { writel(value, port->membase + (offset << 2)); } -static void __init ingenic_early_console_putc(struct uart_port *port, int c) +static void ingenic_early_console_putc(struct uart_port *port, int c) { uint8_t lsr; @@ -71,7 +71,7 @@ static void __init ingenic_early_console_putc(struct uart_port *port, int c) early_out(port, UART_TX, c); } -static void __init ingenic_early_console_write(struct console *console, +static void ingenic_early_console_write(struct console *console, const char *s, unsigned int count) { uart_console_write(&early_device->port, s, count, diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c new file mode 100644 index 0000000000000000000000000000000000000000..308977807994c75bccf7910348255d0633f8e95f --- /dev/null +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct serial_8250_men_mcb_data { + struct uart_8250_port uart; + int line; +}; + +/* + * The Z125 16550-compatible UART has no fixed base clock assigned + * So, depending on the board we're on, we need to adjust the + * parameter in order to really set the correct baudrate, and + * do so if possible without user interaction + */ +static u32 men_z125_lookup_uartclk(struct mcb_device *mdev) +{ + /* use default value if board is not available below */ + u32 clkval = 1041666; + + dev_info(&mdev->dev, "%s on board %s\n", + dev_name(&mdev->dev), + mdev->bus->name); + if (strncmp(mdev->bus->name, "F075", 4) == 0) + clkval = 1041666; + else if (strncmp(mdev->bus->name, "F216", 4) == 0) + clkval = 1843200; + else if (strncmp(mdev->bus->name, "G215", 4) == 0) + clkval = 1843200; + else + dev_info(&mdev->dev, + "board not detected, using default uartclk\n"); + + clkval = clkval << 4; + + return clkval; +} + +static int serial_8250_men_mcb_probe(struct mcb_device *mdev, + const struct mcb_device_id *id) +{ + struct serial_8250_men_mcb_data *data; + struct resource *mem; + + data = devm_kzalloc(&mdev->dev, + sizeof(struct serial_8250_men_mcb_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + mcb_set_drvdata(mdev, data); + data->uart.port.dev = mdev->dma_dev; + spin_lock_init(&data->uart.port.lock); + + data->uart.port.type = PORT_16550; + data->uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; + data->uart.port.iotype = UPIO_MEM; + data->uart.port.uartclk = men_z125_lookup_uartclk(mdev); + data->uart.port.regshift = 0; + data->uart.port.fifosize = 60; + + mem = mcb_get_resource(mdev, IORESOURCE_MEM); + if (mem == NULL) + return -ENXIO; + + data->uart.port.irq = mcb_get_irq(mdev); + + data->uart.port.membase = devm_ioremap_resource(&mdev->dev, mem); + if (IS_ERR(data->uart.port.membase)) + return PTR_ERR_OR_ZERO(data->uart.port.membase); + + data->uart.port.mapbase = (unsigned long) mem->start; + data->uart.port.iobase = data->uart.port.mapbase; + + /* ok, register the port */ + data->line = serial8250_register_8250_port(&data->uart); + if (data->line < 0) + return data->line; + + dev_info(&mdev->dev, "found 16Z125 UART: ttyS%d\n", data->line); + + return 0; +} + +static void serial_8250_men_mcb_remove(struct mcb_device *mdev) +{ + struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev); + + if (data) + serial8250_unregister_port(data->line); +} + +static const struct mcb_device_id serial_8250_men_mcb_ids[] = { + { .device = 0x7d }, + { } +}; +MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids); + +static struct mcb_driver mcb_driver = { + .driver = { + .name = "8250_men_mcb", + .owner = THIS_MODULE, + }, + .probe = serial_8250_men_mcb_probe, + .remove = serial_8250_men_mcb_remove, + .id_table = serial_8250_men_mcb_ids, +}; +module_mcb_driver(mcb_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MEN 16z125 8250 UART driver"); +MODULE_AUTHOR("Michael Moese bus_clk = devm_clk_get(&pdev->dev, "bus"); - if (IS_ERR(data->bus_clk)) - return PTR_ERR(data->bus_clk); - - return 0; + return PTR_ERR_OR_ZERO(data->bus_clk); } static int mtk8250_probe(struct platform_device *pdev) diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 0cf95fddccfcd98649a776903ecbe1a10363d6ec..1222c005fb9889ea21f279882f43c27da5a34c43 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev, int ret; memset(port, 0, sizeof *port); + + pm_runtime_enable(&ofdev->dev); + pm_runtime_get_sync(&ofdev->dev); + if (of_property_read_u32(np, "clock-frequency", &clk)) { /* Get clk rate through clk driver if present */ @@ -72,12 +77,13 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (IS_ERR(info->clk)) { dev_warn(&ofdev->dev, "clk or clock-frequency not defined\n"); - return PTR_ERR(info->clk); + ret = PTR_ERR(info->clk); + goto err_pmruntime; } ret = clk_prepare_enable(info->clk); if (ret < 0) - return ret; + goto err_pmruntime; clk = clk_get_rate(info->clk); } @@ -88,7 +94,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, ret = of_address_to_resource(np, 0, &resource); if (ret) { dev_warn(&ofdev->dev, "invalid address\n"); - goto out; + goto err_unprepare; } spin_lock_init(&port->lock); @@ -130,23 +136,23 @@ static int of_platform_serial_setup(struct platform_device *ofdev, dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", prop); ret = -EINVAL; - goto out; + goto err_dispose; } } info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL); if (IS_ERR(info->rst)) - goto out; + goto err_dispose; ret = reset_control_deassert(info->rst); if (ret) - goto out; + goto err_dispose; port->type = type; port->uartclk = clk; port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_FIXED_PORT | UPF_FIXED_TYPE; - if (of_find_property(np, "no-loopback-test", NULL)) + if (of_property_read_bool(np, "no-loopback-test")) port->flags |= UPF_SKIP_TEST; port->dev = &ofdev->dev; @@ -167,9 +173,13 @@ static int of_platform_serial_setup(struct platform_device *ofdev, port->handle_irq = fsl8250_handle_irq; return 0; -out: - if (info->clk) - clk_disable_unprepare(info->clk); +err_dispose: + irq_dispose_mapping(port->irq); +err_unprepare: + clk_disable_unprepare(info->clk); +err_pmruntime: + pm_runtime_put_sync(&ofdev->dev); + pm_runtime_disable(&ofdev->dev); return ret; } @@ -190,7 +200,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) if (!match) return -EINVAL; - if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) + if (of_property_read_bool(ofdev->dev.of_node, "used-by-rtas")) return -EBUSY; info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -201,7 +211,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) memset(&port8250, 0, sizeof(port8250)); ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info); if (ret) - goto out; + goto err_free; if (port8250.port.fifosize) port8250.capabilities = UART_CAP_FIFO; @@ -217,15 +227,19 @@ static int of_platform_serial_probe(struct platform_device *ofdev) ret = serial8250_register_8250_port(&port8250); if (ret < 0) - goto out; + goto err_dispose; info->type = port_type; info->line = ret; platform_set_drvdata(ofdev, info); return 0; -out: - kfree(info); +err_dispose: irq_dispose_mapping(port8250.port.irq); + pm_runtime_put_sync(&ofdev->dev); + pm_runtime_disable(&ofdev->dev); + clk_disable_unprepare(info->clk); +err_free: + kfree(info); return ret; } @@ -239,8 +253,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev) serial8250_unregister_port(info->line); reset_control_assert(info->rst); - if (info->clk) - clk_disable_unprepare(info->clk); + pm_runtime_put_sync(&ofdev->dev); + pm_runtime_disable(&ofdev->dev); + clk_disable_unprepare(info->clk); kfree(info); return 0; } @@ -254,9 +269,10 @@ static int of_serial_suspend(struct device *dev) serial8250_suspend_port(info->line); - if (info->clk && (!uart_console(port) || console_suspend_enabled)) + if (!uart_console(port) || console_suspend_enabled) { + pm_runtime_put_sync(dev); clk_disable_unprepare(info->clk); - + } return 0; } @@ -266,8 +282,10 @@ static int of_serial_resume(struct device *dev) struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; - if (info->clk && (!uart_console(port) || console_suspend_enabled)) + if (!uart_console(port) || console_suspend_enabled) { + pm_runtime_get_sync(dev); clk_prepare_enable(info->clk); + } serial8250_resume_port(info->line); @@ -295,6 +313,8 @@ static const struct of_device_id of_platform_serial_table[] = { .data = (void *)PORT_ALTR_16550_F64, }, { .compatible = "altr,16550-FIFO128", .data = (void *)PORT_ALTR_16550_F128, }, + { .compatible = "mediatek,mtk-btif", + .data = (void *)PORT_MTK_BTIF, }, { .compatible = "mrvl,mmp-uart", .data = (void *)PORT_XSCALE, }, { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, }, diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 00e51a0643884a0ef8179b68020ae63110333215..0c101a7470b0eedb6306f3bca609b097ecac7b27 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1548,7 +1548,7 @@ static int skip_tx_en_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { - port->port.flags |= UPF_NO_TXEN_TEST; + port->port.quirks |= UPQ_NO_TXEN_TEST; dev_dbg(&priv->dev->dev, "serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n", priv->dev->vendor, priv->dev->device, @@ -3384,17 +3384,8 @@ static const struct pci_device_id blacklist[] = { { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), }, }; -/* - * Given a complete unknown PCI device, try to use some heuristics to - * guess what the configuration might be, based on the pitiful PCI - * serial specs. Returns 0 on success, 1 on failure. - */ -static int -serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) +static int serial_pci_is_class_communication(struct pci_dev *dev) { - const struct pci_device_id *bldev; - int num_iomem, num_port, first_port = -1, i; - /* * If it is not a communications device or the programming * interface is greater than 6, give up. @@ -3407,6 +3398,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) (dev->class & 0xff) > 6) return -ENODEV; + return 0; +} + +static int serial_pci_is_blacklisted(struct pci_dev *dev) +{ + const struct pci_device_id *bldev; + /* * Do not access blacklisted devices that are known not to * feature serial ports or are handled by other modules. @@ -3419,6 +3417,19 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) return -ENODEV; } + return 0; +} + +/* + * Given a complete unknown PCI device, try to use some heuristics to + * guess what the configuration might be, based on the pitiful PCI + * serial specs. Returns 0 on success, -ENODEV on failure. + */ +static int +serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) +{ + int num_iomem, num_port, first_port = -1, i; + num_iomem = num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) { @@ -3639,6 +3650,14 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) board = &pci_boards[ent->driver_data]; + rc = serial_pci_is_class_communication(dev); + if (rc) + return rc; + + rc = serial_pci_is_blacklisted(dev); + if (rc) + return rc; + rc = pcim_enable_device(dev); pci_save_state(dev); if (rc) @@ -3723,7 +3742,7 @@ static int pciserial_resume_one(struct device *dev) static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one, pciserial_resume_one); -static struct pci_device_id serial_pci_tbl[] = { +static const struct pci_device_id serial_pci_tbl[] = { /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0, diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index a5fe0e66c60725bf227ea8acf2e93fe2adda5c4c..f0cc04f62b676870551e757b8f006b3e3ff4fa4a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -289,6 +289,14 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [PORT_MTK_BTIF] = { + .name = "MediaTek BTIF", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ @@ -553,8 +561,8 @@ static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) serial8250_out_MCR(p, mcr); } -static void serial8250_em485_handle_start_tx(unsigned long arg); -static void serial8250_em485_handle_stop_tx(unsigned long arg); +static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t); +static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t); void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) { @@ -609,12 +617,14 @@ int serial8250_em485_init(struct uart_8250_port *p) if (!p->em485) return -ENOMEM; - setup_timer(&p->em485->stop_tx_timer, - serial8250_em485_handle_stop_tx, (unsigned long)p); - setup_timer(&p->em485->start_tx_timer, - serial8250_em485_handle_start_tx, (unsigned long)p); + hrtimer_init(&p->em485->stop_tx_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + p->em485->stop_tx_timer.function = &serial8250_em485_handle_stop_tx; + p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx; + p->em485->port = p; p->em485->active_timer = NULL; - serial8250_em485_rts_after_send(p); return 0; @@ -639,8 +649,8 @@ void serial8250_em485_destroy(struct uart_8250_port *p) if (!p->em485) return; - del_timer(&p->em485->start_tx_timer); - del_timer(&p->em485->stop_tx_timer); + hrtimer_cancel(&p->em485->start_tx_timer); + hrtimer_cancel(&p->em485->stop_tx_timer); kfree(p->em485); p->em485 = NULL; @@ -1435,22 +1445,33 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p) serial_port_out(&p->port, UART_IER, p->ier); } } - -static void serial8250_em485_handle_stop_tx(unsigned long arg) +static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) { - struct uart_8250_port *p = (struct uart_8250_port *)arg; - struct uart_8250_em485 *em485 = p->em485; + struct uart_8250_em485 *em485; + struct uart_8250_port *p; unsigned long flags; + em485 = container_of(t, struct uart_8250_em485, stop_tx_timer); + p = em485->port; + serial8250_rpm_get(p); spin_lock_irqsave(&p->port.lock, flags); - if (em485 && - em485->active_timer == &em485->stop_tx_timer) { + if (em485->active_timer == &em485->stop_tx_timer) { __do_stop_tx_rs485(p); em485->active_timer = NULL; } spin_unlock_irqrestore(&p->port.lock, flags); serial8250_rpm_put(p); + return HRTIMER_NORESTART; +} + +static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec) +{ + long sec = msec / 1000; + long nsec = (msec % 1000) * 1000000; + ktime_t t = ktime_set(sec, nsec); + + hrtimer_start(hrt, t, HRTIMER_MODE_REL); } static void __stop_tx_rs485(struct uart_8250_port *p) @@ -1463,8 +1484,8 @@ static void __stop_tx_rs485(struct uart_8250_port *p) */ if (p->port.rs485.delay_rts_after_send > 0) { em485->active_timer = &em485->stop_tx_timer; - mod_timer(&em485->stop_tx_timer, jiffies + - p->port.rs485.delay_rts_after_send * HZ / 1000); + start_hrtimer_ms(&em485->stop_tx_timer, + p->port.rs485.delay_rts_after_send); } else { __do_stop_tx_rs485(p); } @@ -1494,8 +1515,8 @@ static inline void __stop_tx(struct uart_8250_port *p) if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) return; - del_timer(&em485->start_tx_timer); em485->active_timer = NULL; + hrtimer_cancel(&em485->start_tx_timer); __stop_tx_rs485(p); } @@ -1558,8 +1579,9 @@ static inline void start_tx_rs485(struct uart_port *port) if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) serial8250_stop_rx(&up->port); - del_timer(&em485->stop_tx_timer); em485->active_timer = NULL; + if (hrtimer_is_queued(&em485->stop_tx_timer)) + hrtimer_cancel(&em485->stop_tx_timer); mcr = serial8250_in_MCR(up); if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != @@ -1572,8 +1594,8 @@ static inline void start_tx_rs485(struct uart_port *port) if (up->port.rs485.delay_rts_before_send > 0) { em485->active_timer = &em485->start_tx_timer; - mod_timer(&em485->start_tx_timer, jiffies + - up->port.rs485.delay_rts_before_send * HZ / 1000); + start_hrtimer_ms(&em485->start_tx_timer, + up->port.rs485.delay_rts_before_send); return; } } @@ -1581,19 +1603,22 @@ static inline void start_tx_rs485(struct uart_port *port) __start_tx(port); } -static void serial8250_em485_handle_start_tx(unsigned long arg) +static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t) { - struct uart_8250_port *p = (struct uart_8250_port *)arg; - struct uart_8250_em485 *em485 = p->em485; + struct uart_8250_em485 *em485; + struct uart_8250_port *p; unsigned long flags; + em485 = container_of(t, struct uart_8250_em485, start_tx_timer); + p = em485->port; + spin_lock_irqsave(&p->port.lock, flags); - if (em485 && - em485->active_timer == &em485->start_tx_timer) { + if (em485->active_timer == &em485->start_tx_timer) { __start_tx(&p->port); em485->active_timer = NULL; } spin_unlock_irqrestore(&p->port.lock, flags); + return HRTIMER_NORESTART; } static void serial8250_start_tx(struct uart_port *port) @@ -2304,7 +2329,7 @@ int serial8250_do_startup(struct uart_port *port) * test if we receive TX irq. This way, we'll never enable * UART_BUG_TXEN. */ - if (up->port.flags & UPF_NO_TXEN_TEST) + if (up->port.quirks & UPQ_NO_TXEN_TEST) goto dont_test_tx_en; /* diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 746680ebf90c572b6e01ec3080555454477ac8d8..8a10b10e27aae9b25d6378c3b98235c611b7fbfe 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -29,12 +29,13 @@ * - MMIO32 (regshift = 2) * - FCR is not at 2, but 3 * - LCR and MCR are not at 3 and 4, they share 4 + * - No SCR (Instead, CHAR can be used as a scratch register) * - Divisor latch at 9, no divisor latch access bit */ #define UNIPHIER_UART_REGSHIFT 2 -/* bit[15:8] = CHAR (not used), bit[7:0] = FCR */ +/* bit[15:8] = CHAR, bit[7:0] = FCR */ #define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT)) /* bit[15:8] = LCR, bit[7:0] = MCR */ #define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT)) @@ -72,13 +73,18 @@ OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart", /* * The register map is slightly different from that of 8250. - * IO callbacks must be overridden for correct access to FCR, LCR, and MCR. + * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR. */ static unsigned int uniphier_serial_in(struct uart_port *p, int offset) { unsigned int valshift = 0; switch (offset) { + case UART_SCR: + /* No SCR for this hardware. Use CHAR as a scratch register */ + valshift = 8; + offset = UNIPHIER_UART_CHAR_FCR; + break; case UART_LCR: valshift = 8; /* fall through */ @@ -91,8 +97,8 @@ static unsigned int uniphier_serial_in(struct uart_port *p, int offset) } /* - * The return value must be masked with 0xff because LCR and MCR reside - * in the same register that must be accessed by 32-bit write/read. + * The return value must be masked with 0xff because some registers + * share the same offset that must be accessed by 32-bit write/read. * 8 or 16 bit access to this hardware result in unexpected behavior. */ return (readl(p->membase + offset) >> valshift) & 0xff; @@ -101,9 +107,13 @@ static unsigned int uniphier_serial_in(struct uart_port *p, int offset) static void uniphier_serial_out(struct uart_port *p, int offset, int value) { unsigned int valshift = 0; - bool normal = true; + bool normal = false; switch (offset) { + case UART_SCR: + /* No SCR for this hardware. Use CHAR as a scratch register */ + valshift = 8; + /* fall through */ case UART_FCR: offset = UNIPHIER_UART_CHAR_FCR; break; @@ -114,10 +124,10 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value) /* fall through */ case UART_MCR: offset = UNIPHIER_UART_LCR_MCR; - normal = false; break; default: offset <<= UNIPHIER_UART_REGSHIFT; + normal = true; break; } @@ -169,7 +179,7 @@ static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, dev_err(dev, "failed to get alias id\n"); return ret; } - port->line = priv->line = ret; + port->line = ret; /* Get clk rate through clk driver */ priv->clk = devm_clk_get(dev, NULL); @@ -249,8 +259,8 @@ static int uniphier_uart_probe(struct platform_device *pdev) up.dl_read = uniphier_serial_dl_read; up.dl_write = uniphier_serial_dl_write; - ret = serial8250_register_8250_port(&up); - if (ret < 0) { + priv->line = serial8250_register_8250_port(&up); + if (priv->line < 0) { dev_err(dev, "failed to register 8250 port\n"); clk_disable_unprepare(priv->clk); return ret; @@ -271,6 +281,40 @@ static int uniphier_uart_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused uniphier_uart_suspend(struct device *dev) +{ + struct uniphier8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(priv->line); + + serial8250_suspend_port(priv->line); + + if (!uart_console(&up->port) || console_suspend_enabled) + clk_disable_unprepare(priv->clk); + + return 0; +} + +static int __maybe_unused uniphier_uart_resume(struct device *dev) +{ + struct uniphier8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(priv->line); + int ret; + + if (!uart_console(&up->port) || console_suspend_enabled) { + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; + } + + serial8250_resume_port(priv->line); + + return 0; +} + +static const struct dev_pm_ops uniphier_uart_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume) +}; + static const struct of_device_id uniphier_uart_match[] = { { .compatible = "socionext,uniphier-uart" }, { /* sentinel */ } @@ -283,6 +327,7 @@ static struct platform_driver uniphier_uart_platform_driver = { .driver = { .name = "uniphier-uart", .of_match_table = uniphier_uart_match, + .pm = &uniphier_uart_pm_ops, }, }; module_platform_driver(uniphier_uart_platform_driver); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index a1161ec0256f99aa1721ff1de3dfcce6d369c599..a5c0ef1e7695fedc6e185e09454d9a5a55f358cb 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -155,6 +155,17 @@ config SERIAL_8250_CS If unsure, say N. +config SERIAL_8250_MEN_MCB + tristate "MEN Z125 UART device support" + depends on MCB && SERIAL_8250 + help + This enables support for FPGA based UARTs found on many MEN + boards. This driver enables support for the Z125 UARTs. + + To compile this driver as a module, chose M here: the + module will be called 8250_men_mcb. + + config SERIAL_8250_NR_UARTS int "Maximum number of 8250/16550 serial ports" depends on SERIAL_8250 diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index a44a99a3e623580fb6d70488aab599262dde40a7..6a18d2d768fe699bd9c6f6db7ff5d4e06d629df4 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o +obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 1f096e2bb398c07f5d420494c2e441ca8aecfb3b..b788fee54249deff289fe1512e5b87b5b306e51e 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1689,7 +1689,7 @@ config SERIAL_MVEBU_CONSOLE Otherwise, say 'N'. config SERIAL_OWL - bool "Actions Semi Owl serial port support" + tristate "Actions Semi Owl serial port support" depends on ARCH_ACTIONS || COMPILE_TEST select SERIAL_CORE help @@ -1705,7 +1705,7 @@ config SERIAL_OWL_CONSOLE default y help Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART - as the system console. Only earlycon is implemented currently. + as the system console. endmenu diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 24180adb1cbb8b873512c07c6b6884299b7d35d6..9ec4b8d2879f7df5f6372ad7f8fb4c7e4ab81f3d 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -814,7 +814,7 @@ static int pl010_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pl010_dev_pm_ops, pl010_suspend, pl010_resume); -static struct amba_id pl010_ids[] = { +static const struct amba_id pl010_ids[] = { { .id = 0x00041010, .mask = 0x000fffff, diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8a857bb34fbb26c6d60784d3fe7576730a9aa5b3..111e6a95077978c2c30bfe2a2de4a0d095e8d76e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -128,7 +128,7 @@ static struct vendor_data vendor_arm = { .get_fifosize = get_fifosize_arm, }; -static struct vendor_data vendor_sbsa = { +static const struct vendor_data vendor_sbsa = { .reg_offset = pl011_std_offsets, .fr_busy = UART01x_FR_BUSY, .fr_dsr = UART01x_FR_DSR, @@ -142,16 +142,8 @@ static struct vendor_data vendor_sbsa = { .fixed_options = true, }; -/* - * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as - * occasionally getting stuck as 1. To avoid the potential for a hang, check - * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART - * implementations, so only do so if an affected platform is detected in - * parse_spcr(). - */ -static bool qdf2400_e44_present = false; - -static struct vendor_data vendor_qdt_qdf2400_e44 = { +#ifdef CONFIG_ACPI_SPCR_TABLE +static const struct vendor_data vendor_qdt_qdf2400_e44 = { .reg_offset = pl011_std_offsets, .fr_busy = UART011_FR_TXFE, .fr_dsr = UART01x_FR_DSR, @@ -165,6 +157,7 @@ static struct vendor_data vendor_qdt_qdf2400_e44 = { .always_enabled = true, .fixed_options = true, }; +#endif static u16 pl011_st_offsets[REG_ARRAY_SIZE] = { [REG_DR] = UART01x_DR, @@ -2375,12 +2368,14 @@ static int __init pl011_console_match(struct console *co, char *name, int idx, resource_size_t addr; int i; - if (strcmp(name, "qdf2400_e44") == 0) { - pr_info_once("UART: Working around QDF2400 SoC erratum 44"); - qdf2400_e44_present = true; - } else if (strcmp(name, "pl011") != 0) { + /* + * Systems affected by the Qualcomm Technologies QDF2400 E44 erratum + * have a distinct console name, so make sure we check for that. + * The actual implementation of the erratum occurs in the probe + * function. + */ + if ((strcmp(name, "qdf2400_e44") != 0) && (strcmp(name, "pl011") != 0)) return -ENODEV; - } if (uart_parse_earlycon(options, &iotype, &addr, &options)) return -ENODEV; @@ -2734,11 +2729,17 @@ static int sbsa_uart_probe(struct platform_device *pdev) } uap->port.irq = ret; - uap->reg_offset = vendor_sbsa.reg_offset; - uap->vendor = qdf2400_e44_present ? - &vendor_qdt_qdf2400_e44 : &vendor_sbsa; +#ifdef CONFIG_ACPI_SPCR_TABLE + if (qdf2400_e44_present) { + dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); + uap->vendor = &vendor_qdt_qdf2400_e44; + } else +#endif + uap->vendor = &vendor_sbsa; + + uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; - uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM; + uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; @@ -2786,7 +2787,7 @@ static struct platform_driver arm_sbsa_uart_platform_driver = { }, }; -static struct amba_id pl011_ids[] = { +static const struct amba_id pl011_ids[] = { { .id = 0x00041011, .mask = 0x000fffff, diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 75eb083b3361c8fc47c910eecc316152e4e34e84..dd60ed96a0adfcfb3b5d1729af713dd22cb1b6c5 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -325,7 +325,7 @@ static int apbuart_verify_port(struct uart_port *port, return ret; } -static struct uart_ops grlib_apbuart_ops = { +static const struct uart_ops grlib_apbuart_ops = { .tx_empty = apbuart_tx_empty, .set_mctrl = apbuart_set_mctrl, .get_mctrl = apbuart_get_mctrl, diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 5ac06fcaa9c606408496215c6a782e9e25c03916..77fe306690c4174b775287e23a3340292f15dda6 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -549,8 +549,8 @@ static struct console arc_console = { .data = &arc_uart_driver }; -static __init void arc_early_serial_write(struct console *con, const char *s, - unsigned int n) +static void arc_early_serial_write(struct console *con, const char *s, + unsigned int n) { struct earlycon_device *dev = con->data; diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 583c9a0c7eccd439b3c457c6c9c767976c49deda..8c48c3784831b3605158ef38b15f17d1dae65b93 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -507,9 +507,14 @@ static void bcm_uart_set_termios(struct uart_port *port, { unsigned int ctl, baud, quot, ier; unsigned long flags; + int tries; spin_lock_irqsave(&port->lock, flags); + /* Drain the hot tub fully before we power it off for the winter. */ + for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--) + mdelay(10); + /* disable uart while changing speed */ bcm_uart_disable(port); bcm_uart_flush(port); diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index f6bcc19c99d5b8fe7a341d29d853c51238703d0d..9ac142cfc1f1b99a89cf21582472e05993664ed2 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1123,7 +1123,7 @@ static void cpm_put_poll_char(struct uart_port *port, } #endif /* CONFIG_CONSOLE_POLL */ -static struct uart_ops cpm_uart_pops = { +static const struct uart_ops cpm_uart_pops = { .tx_empty = cpm_uart_tx_empty, .set_mctrl = cpm_uart_set_mctrl, .get_mctrl = cpm_uart_get_mctrl, diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index c3651540e1ba1aefd89c2772b0ab849a939d8c13..98928f082d87eead8a8ea49ab0b773eb52313bd2 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -220,7 +220,7 @@ static int __init param_setup_earlycon(char *buf) if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) { earlycon_init_is_deferred = true; return 0; - } else { + } else if (!buf) { return early_init_dt_scan_chosen_stdout(); } } @@ -282,7 +282,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match, } } + val = of_get_flat_dt_prop(node, "current-speed", NULL); + if (val) + early_console_dev.baud = be32_to_cpu(*val); + if (options) { + early_console_dev.baud = simple_strtoul(options, NULL, 0); strlcpy(early_console_dev.options, options, sizeof(early_console_dev.options)); } diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 898dcb091a279fde22b40431acf6dfd8e5badfe8..f0252184291ed4a3ab49ab03ce634e7be8588bf4 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -117,7 +117,7 @@ #define UARTSFIFO_TXOF 0x02 #define UARTSFIFO_RXUF 0x01 -/* 32-bit register defination */ +/* 32-bit register definition */ #define UARTBAUD 0x00 #define UARTSTAT 0x04 #define UARTCTRL 0x08 @@ -521,6 +521,57 @@ static int lpuart_poll_get_char(struct uart_port *port) return readb(port->membase + UARTDR); } +static int lpuart32_poll_init(struct uart_port *port) +{ + unsigned long flags; + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); + u32 temp; + + sport->port.fifosize = 0; + + spin_lock_irqsave(&sport->port.lock, flags); + + /* Disable Rx & Tx */ + writel(0, sport->port.membase + UARTCTRL); + + temp = readl(sport->port.membase + UARTFIFO); + + /* Enable Rx and Tx FIFO */ + writel(temp | UARTFIFO_RXFE | UARTFIFO_TXFE, + sport->port.membase + UARTFIFO); + + /* flush Tx and Rx FIFO */ + writel(UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, + sport->port.membase + UARTFIFO); + + /* explicitly clear RDRF */ + if (readl(sport->port.membase + UARTSTAT) & UARTSTAT_RDRF) { + readl(sport->port.membase + UARTDATA); + writel(UARTFIFO_RXUF, sport->port.membase + UARTFIFO); + } + + /* Enable Rx and Tx */ + writel(UARTCTRL_RE | UARTCTRL_TE, sport->port.membase + UARTCTRL); + spin_unlock_irqrestore(&sport->port.lock, flags); + + return 0; +} + +static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c) +{ + while (!(readl(port->membase + UARTSTAT) & UARTSTAT_TDRE)) + barrier(); + + writel(c, port->membase + UARTDATA); +} + +static int lpuart32_poll_get_char(struct uart_port *port) +{ + if (!(readl(port->membase + UARTSTAT) & UARTSTAT_RDRF)) + return NO_POLL_CHAR; + + return readl(port->membase + UARTDATA); +} #endif static inline void lpuart_transmit_buffer(struct lpuart_port *sport) @@ -1025,6 +1076,11 @@ static int lpuart_config_rs485(struct uart_port *port, ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); writeb(modem, sport->port.membase + UARTMODEM); + /* clear unsupported configurations */ + rs485->delay_rts_before_send = 0; + rs485->delay_rts_after_send = 0; + rs485->flags &= ~SER_RS485_RX_DURING_TX; + if (rs485->flags & SER_RS485_ENABLED) { /* Enable auto RS-485 RTS mode */ modem |= UARTMODEM_TXRTSE; @@ -1220,7 +1276,6 @@ static void rx_dma_timer_init(struct lpuart_port *sport) static int lpuart_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - int ret; unsigned long flags; unsigned char temp; @@ -1235,11 +1290,6 @@ static int lpuart_startup(struct uart_port *port) sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) & UARTPFIFO_FIFOSIZE_MASK) + 1); - ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0, - DRIVER_NAME, sport); - if (ret) - return ret; - spin_lock_irqsave(&sport->port.lock, flags); lpuart_setup_watermark(sport); @@ -1277,7 +1327,6 @@ static int lpuart_startup(struct uart_port *port) static int lpuart32_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - int ret; unsigned long flags; unsigned long temp; @@ -1290,11 +1339,6 @@ static int lpuart32_startup(struct uart_port *port) sport->rxfifo_size = 0x1 << (((temp >> UARTFIFO_RXSIZE_OFF) & UARTFIFO_FIFOSIZE_MASK) - 1); - ret = devm_request_irq(port->dev, port->irq, lpuart32_int, 0, - DRIVER_NAME, sport); - if (ret) - return ret; - spin_lock_irqsave(&sport->port.lock, flags); lpuart32_setup_watermark(sport); @@ -1324,8 +1368,6 @@ static void lpuart_shutdown(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); - devm_free_irq(port->dev, port->irq, sport); - if (sport->lpuart_dma_rx_use) { del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); @@ -1344,7 +1386,6 @@ static void lpuart_shutdown(struct uart_port *port) static void lpuart32_shutdown(struct uart_port *port) { - struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long temp; unsigned long flags; @@ -1357,8 +1398,6 @@ static void lpuart32_shutdown(struct uart_port *port) lpuart32_write(port, temp, UARTCTRL); spin_unlock_irqrestore(&port->lock, flags); - - devm_free_irq(port->dev, port->irq, sport); } static void @@ -1782,6 +1821,11 @@ static const struct uart_ops lpuart32_pops = { .config_port = lpuart_config_port, .verify_port = lpuart_verify_port, .flush_buffer = lpuart_flush_buffer, +#if defined(CONFIG_CONSOLE_POLL) + .poll_init = lpuart32_poll_init, + .poll_get_char = lpuart32_poll_get_char, + .poll_put_char = lpuart32_poll_put_char, +#endif }; static struct lpuart_port *lpuart_ports[UART_NR]; @@ -2151,16 +2195,22 @@ static int lpuart_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &sport->port); - if (lpuart_is_32(sport)) + if (lpuart_is_32(sport)) { lpuart_reg.cons = LPUART32_CONSOLE; - else + ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0, + DRIVER_NAME, sport); + } else { lpuart_reg.cons = LPUART_CONSOLE; + ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0, + DRIVER_NAME, sport); + } + + if (ret) + goto failed_irq_request; ret = uart_add_one_port(&lpuart_reg, &sport->port); - if (ret) { - clk_disable_unprepare(sport->clk); - return ret; - } + if (ret) + goto failed_attach_port; sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx"); if (!sport->dma_tx_chan) @@ -2179,6 +2229,11 @@ static int lpuart_probe(struct platform_device *pdev) } return 0; + +failed_attach_port: +failed_irq_request: + clk_disable_unprepare(sport->clk); + return ret; } static int lpuart_remove(struct platform_device *pdev) @@ -2203,6 +2258,7 @@ static int lpuart_suspend(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); unsigned long temp; + bool irq_wake; if (lpuart_is_32(sport)) { /* disable Rx/Tx and interrupts */ @@ -2218,6 +2274,9 @@ static int lpuart_suspend(struct device *dev) uart_suspend_port(&lpuart_reg, &sport->port); + /* uart_suspend_port() might set wakeup flag */ + irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); + if (sport->lpuart_dma_rx_use) { /* * EDMA driver during suspend will forcefully release any @@ -2226,7 +2285,7 @@ static int lpuart_suspend(struct device *dev) * cannot resume as as expected, hence gracefully release the * Rx DMA path before suspend and start Rx DMA path on resume. */ - if (sport->port.irq_wake) { + if (irq_wake) { del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); } @@ -2241,7 +2300,7 @@ static int lpuart_suspend(struct device *dev) dmaengine_terminate_all(sport->dma_tx_chan); } - if (sport->port.suspended && !sport->port.irq_wake) + if (sport->port.suspended && !irq_wake) clk_disable_unprepare(sport->clk); return 0; @@ -2250,9 +2309,10 @@ static int lpuart_suspend(struct device *dev) static int lpuart_resume(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); + bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); unsigned long temp; - if (sport->port.suspended && !sport->port.irq_wake) + if (sport->port.suspended && !irq_wake) clk_prepare_enable(sport->clk); if (lpuart_is_32(sport)) { @@ -2269,7 +2329,7 @@ static int lpuart_resume(struct device *dev) } if (sport->lpuart_dma_rx_use) { - if (sport->port.irq_wake) { + if (irq_wake) { if (!lpuart_start_rx_dma(sport)) rx_dma_timer_init(sport); else diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 80934e7bd67f422629b8ea7c37fdf1f8afc188e6..dfeff3951f934627f8ed45e892ee5d30cec3216b 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -226,7 +226,6 @@ struct imx_port { dma_cookie_t rx_cookie; unsigned int tx_bytes; unsigned int dma_tx_nents; - wait_queue_head_t dma_wait; unsigned int saved_reg[10]; bool context_saved; }; @@ -458,7 +457,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport) } } - while (!uart_circ_empty(xmit) && !sport->dma_is_txing && + if (sport->dma_is_txing) + return; + + while (!uart_circ_empty(xmit) && !(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) { /* send xmit->buf[xmit->tail] * out the port here */ @@ -498,20 +500,12 @@ static void dma_tx_callback(void *data) sport->dma_is_txing = 0; - spin_unlock_irqrestore(&sport->port.lock, flags); - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); - if (waitqueue_active(&sport->dma_wait)) { - wake_up(&sport->dma_wait); - dev_dbg(sport->port.dev, "exit in %s.\n", __func__); - return; - } - - spin_lock_irqsave(&sport->port.lock, flags); if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port)) imx_dma_tx(sport); + spin_unlock_irqrestore(&sport->port.lock, flags); } @@ -1208,8 +1202,6 @@ static void imx_enable_dma(struct imx_port *sport) { unsigned long temp; - init_waitqueue_head(&sport->dma_wait); - /* set UCR1 */ temp = readl(sport->port.membase + UCR1); temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN; @@ -2332,6 +2324,7 @@ static int imx_serial_port_suspend(struct device *dev) serial_imx_enable_wakeup(sport, true); uart_suspend_port(&imx_reg, &sport->port); + disable_irq(sport->port.irq); /* Needed to enable clock in suspend_noirq */ return clk_prepare(sport->clk_ipg); @@ -2346,6 +2339,7 @@ static int imx_serial_port_resume(struct device *dev) serial_imx_enable_wakeup(sport, false); uart_resume_port(&imx_reg, &sport->port); + enable_irq(sport->port.irq); clk_unprepare(sport->clk_ipg); diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index a119f11bf2f4188fc76e3a4b1401d0287af00f5f..102d499814acc58e66ca5760a25dc0de1279660d 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -304,7 +304,7 @@ static void jsm_remove_one(struct pci_dev *pdev) kfree(brd); } -static struct pci_device_id jsm_pci_tbl[] = { +static const struct pci_device_id jsm_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9), 0, 0, 0 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9PRI), 0, 0, 1 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 218b7118e85d1288a8d812f05191be5ec5aaa684..5b3bd951199353655749b0a80cd0b5e2e019240c 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -854,7 +854,7 @@ m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } -static struct uart_ops m32r_sio_pops = { +static const struct uart_ops m32r_sio_pops = { .tx_empty = m32r_sio_tx_empty, .set_mctrl = m32r_sio_set_mctrl, .get_mctrl = m32r_sio_get_mctrl, diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 42e4a4c7597ff1af29b85260f453f6a5b1f6102d..07c0f98be3acedcd77183f0e1a6c9207db429ee0 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -424,7 +424,7 @@ static void meson_uart_config_port(struct uart_port *port, int flags) } } -static struct uart_ops meson_uart_ops = { +static const struct uart_ops meson_uart_ops = { .set_mctrl = meson_uart_set_mctrl, .get_mctrl = meson_uart_get_mctrl, .tx_empty = meson_uart_tx_empty, diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 3970d6a9aaca42e4dd459bd483b06599f77884fd..791c4c74f6d6adfbf31b1a756841ee02e7981d9d 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1347,7 +1347,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) } -static struct uart_ops mpc52xx_uart_ops = { +static const struct uart_ops mpc52xx_uart_ops = { .tx_empty = mpc52xx_uart_tx_empty, .set_mctrl = mpc52xx_uart_set_mctrl, .get_mctrl = mpc52xx_uart_get_mctrl, @@ -1634,8 +1634,8 @@ mpc52xx_console_setup(struct console *co, char *options) return -EINVAL; } - pr_debug("Console on ttyPSC%x is %s\n", - co->index, mpc52xx_uart_nodes[co->index]->full_name); + pr_debug("Console on ttyPSC%x is %pOF\n", + co->index, mpc52xx_uart_nodes[co->index]); /* Fetch register locations */ ret = of_address_to_resource(np, 0, &res); @@ -1755,8 +1755,8 @@ static int mpc52xx_uart_of_probe(struct platform_device *op) break; if (idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; - pr_debug("Found %s assigned to ttyPSC%x\n", - mpc52xx_uart_nodes[idx]->full_name, idx); + pr_debug("Found %pOF assigned to ttyPSC%x\n", + mpc52xx_uart_nodes[idx], idx); /* set the uart clock to the input clock of the psc, the different * prescalers are taken into account in the set_baudrate() methods @@ -1881,8 +1881,8 @@ mpc52xx_uart_of_enumerate(void) for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { if (mpc52xx_uart_nodes[i]) - pr_debug("%s assigned to ttyPSC%x\n", - mpc52xx_uart_nodes[i]->full_name, i); + pr_debug("%pOF assigned to ttyPSC%x\n", + mpc52xx_uart_nodes[i], i); } } diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 6788e7532dff942c16a4d6536d977839d11b1848..1db79ee8a886e60b67ec85be3fad0983469dffd3 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1175,11 +1175,6 @@ static int msm_startup(struct uart_port *port) snprintf(msm_port->name, sizeof(msm_port->name), "msm_serial%d", port->line); - ret = request_irq(port->irq, msm_uart_irq, IRQF_TRIGGER_HIGH, - msm_port->name, port); - if (unlikely(ret)) - return ret; - msm_init_clock(port); if (likely(port->fifosize > 12)) @@ -1206,7 +1201,21 @@ static int msm_startup(struct uart_port *port) msm_request_rx_dma(msm_port, msm_port->uart.mapbase); } + ret = request_irq(port->irq, msm_uart_irq, IRQF_TRIGGER_HIGH, + msm_port->name, port); + if (unlikely(ret)) + goto err_irq; + return 0; + +err_irq: + if (msm_port->is_uartdm) + msm_release_dma(msm_port); + + clk_disable_unprepare(msm_port->pclk); + clk_disable_unprepare(msm_port->clk); + + return ret; } static void msm_shutdown(struct uart_port *port) diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 8a4be4b73723381a6bcba7b89cb1137ed3b5ac96..2bff69e70e4bcc65b6e7dc4433079959c401772d 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -427,7 +427,7 @@ static struct console mux_console = { #define MUX_CONSOLE NULL #endif -static struct uart_ops mux_pops = { +static const struct uart_ops mux_pops = { .tx_empty = mux_tx_empty, .set_mctrl = mux_set_mctrl, .get_mctrl = mux_get_mctrl, @@ -503,7 +503,7 @@ static int __init mux_probe(struct parisc_device *dev) return 0; } -static int mux_remove(struct parisc_device *dev) +static int __exit mux_remove(struct parisc_device *dev) { int i, j; int port_count = (long)dev_get_drvdata(&dev->dev); @@ -536,13 +536,13 @@ static int mux_remove(struct parisc_device *dev) * This table only contains the parisc_device_id of known builtin mux * devices. All other mux cards will be detected by the generic mux_tbl. */ -static struct parisc_device_id builtin_mux_tbl[] = { +static const struct parisc_device_id builtin_mux_tbl[] __initconst = { { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */ { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */ { 0, } }; -static struct parisc_device_id mux_tbl[] = { +static const struct parisc_device_id mux_tbl[] __initconst = { { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D }, { 0, } }; @@ -550,18 +550,18 @@ static struct parisc_device_id mux_tbl[] = { MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl); MODULE_DEVICE_TABLE(parisc, mux_tbl); -static struct parisc_driver builtin_serial_mux_driver = { +static struct parisc_driver builtin_serial_mux_driver __refdata = { .name = "builtin_serial_mux", .id_table = builtin_mux_tbl, .probe = mux_probe, - .remove = mux_remove, + .remove = __exit_p(mux_remove), }; -static struct parisc_driver serial_mux_driver = { +static struct parisc_driver serial_mux_driver __refdata = { .name = "serial_mux", .id_table = mux_tbl, .probe = mux_probe, - .remove = mux_remove, + .remove = __exit_p(mux_remove), }; /** diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 1ea05ac57aa7197b4f690776acc609d376faade4..7754053deedac9064316dd74c290f29ec154f597 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1235,21 +1235,20 @@ static int serial_omap_poll_get_char(struct uart_port *port) #ifdef CONFIG_SERIAL_OMAP_CONSOLE #ifdef CONFIG_SERIAL_EARLYCON -static unsigned int __init omap_serial_early_in(struct uart_port *port, - int offset) +static unsigned int omap_serial_early_in(struct uart_port *port, int offset) { offset <<= port->regshift; return readw(port->membase + offset); } -static void __init omap_serial_early_out(struct uart_port *port, int offset, - int value) +static void omap_serial_early_out(struct uart_port *port, int offset, + int value) { offset <<= port->regshift; writew(value, port->membase + offset); } -static void __init omap_serial_early_putc(struct uart_port *port, int c) +static void omap_serial_early_putc(struct uart_port *port, int c) { unsigned int status; @@ -1262,8 +1261,8 @@ static void __init omap_serial_early_putc(struct uart_port *port, int c) omap_serial_early_out(port, UART_TX, c); } -static void __init early_omap_serial_write(struct console *console, - const char *s, unsigned int count) +static void early_omap_serial_write(struct console *console, const char *s, + unsigned int count) { struct earlycon_device *device = console->data; struct uart_port *port = &device->port; diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index 1b8008797a1b242365060fff4c2ef074bc335b5e..b9c85936533475a115205823b4bcdd4f6b13105b 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -20,6 +20,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -28,22 +29,66 @@ #include #include #include +#include +#include + +#define OWL_UART_PORT_NUM 7 +#define OWL_UART_DEV_NAME "ttyOWL" #define OWL_UART_CTL 0x000 +#define OWL_UART_RXDAT 0x004 #define OWL_UART_TXDAT 0x008 #define OWL_UART_STAT 0x00c +#define OWL_UART_CTL_DWLS_MASK GENMASK(1, 0) +#define OWL_UART_CTL_DWLS_5BITS (0x0 << 0) +#define OWL_UART_CTL_DWLS_6BITS (0x1 << 0) +#define OWL_UART_CTL_DWLS_7BITS (0x2 << 0) +#define OWL_UART_CTL_DWLS_8BITS (0x3 << 0) +#define OWL_UART_CTL_STPS_2BITS BIT(2) +#define OWL_UART_CTL_PRS_MASK GENMASK(6, 4) +#define OWL_UART_CTL_PRS_NONE (0x0 << 4) +#define OWL_UART_CTL_PRS_ODD (0x4 << 4) +#define OWL_UART_CTL_PRS_MARK (0x5 << 4) +#define OWL_UART_CTL_PRS_EVEN (0x6 << 4) +#define OWL_UART_CTL_PRS_SPACE (0x7 << 4) +#define OWL_UART_CTL_AFE BIT(12) #define OWL_UART_CTL_TRFS_TX BIT(14) #define OWL_UART_CTL_EN BIT(15) +#define OWL_UART_CTL_RXDE BIT(16) +#define OWL_UART_CTL_TXDE BIT(17) #define OWL_UART_CTL_RXIE BIT(18) #define OWL_UART_CTL_TXIE BIT(19) +#define OWL_UART_CTL_LBEN BIT(20) #define OWL_UART_STAT_RIP BIT(0) #define OWL_UART_STAT_TIP BIT(1) +#define OWL_UART_STAT_RXER BIT(2) +#define OWL_UART_STAT_TFER BIT(3) +#define OWL_UART_STAT_RXST BIT(4) +#define OWL_UART_STAT_RFEM BIT(5) #define OWL_UART_STAT_TFFU BIT(6) -#define OWL_UART_STAT_TRFL_MASK (0x1f << 11) +#define OWL_UART_STAT_CTSS BIT(7) +#define OWL_UART_STAT_RTSS BIT(8) +#define OWL_UART_STAT_TFES BIT(10) +#define OWL_UART_STAT_TRFL_MASK GENMASK(16, 11) #define OWL_UART_STAT_UTBB BIT(17) +static struct uart_driver owl_uart_driver; + +struct owl_uart_info { + unsigned int tx_fifosize; +}; + +struct owl_uart_port { + struct uart_port port; + struct clk *clk; +}; + +#define to_owl_uart_port(prt) container_of(prt, struct owl_uart_port, prt) + +static struct owl_uart_port *owl_uart_ports[OWL_UART_PORT_NUM]; + static inline void owl_uart_write(struct uart_port *port, u32 val, unsigned int off) { writel(val, port->membase + off); @@ -54,6 +99,397 @@ static inline u32 owl_uart_read(struct uart_port *port, unsigned int off) return readl(port->membase + off); } +static void owl_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + u32 ctl; + + ctl = owl_uart_read(port, OWL_UART_CTL); + + if (mctrl & TIOCM_LOOP) + ctl |= OWL_UART_CTL_LBEN; + else + ctl &= ~OWL_UART_CTL_LBEN; + + owl_uart_write(port, ctl, OWL_UART_CTL); +} + +static unsigned int owl_uart_get_mctrl(struct uart_port *port) +{ + unsigned int mctrl = TIOCM_CAR | TIOCM_DSR; + u32 stat, ctl; + + ctl = owl_uart_read(port, OWL_UART_CTL); + stat = owl_uart_read(port, OWL_UART_STAT); + if (stat & OWL_UART_STAT_RTSS) + mctrl |= TIOCM_RTS; + if ((stat & OWL_UART_STAT_CTSS) || !(ctl & OWL_UART_CTL_AFE)) + mctrl |= TIOCM_CTS; + return mctrl; +} + +static unsigned int owl_uart_tx_empty(struct uart_port *port) +{ + unsigned long flags; + u32 val; + unsigned int ret; + + spin_lock_irqsave(&port->lock, flags); + + val = owl_uart_read(port, OWL_UART_STAT); + ret = (val & OWL_UART_STAT_TFES) ? TIOCSER_TEMT : 0; + + spin_unlock_irqrestore(&port->lock, flags); + + return ret; +} + +static void owl_uart_stop_rx(struct uart_port *port) +{ + u32 val; + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~(OWL_UART_CTL_RXIE | OWL_UART_CTL_RXDE); + owl_uart_write(port, val, OWL_UART_CTL); + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_RIP; + owl_uart_write(port, val, OWL_UART_STAT); +} + +static void owl_uart_stop_tx(struct uart_port *port) +{ + u32 val; + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_TXDE); + owl_uart_write(port, val, OWL_UART_CTL); + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_TIP; + owl_uart_write(port, val, OWL_UART_STAT); +} + +static void owl_uart_start_tx(struct uart_port *port) +{ + u32 val; + + if (uart_tx_stopped(port)) { + owl_uart_stop_tx(port); + return; + } + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_TIP; + owl_uart_write(port, val, OWL_UART_STAT); + + val = owl_uart_read(port, OWL_UART_CTL); + val |= OWL_UART_CTL_TXIE; + owl_uart_write(port, val, OWL_UART_CTL); +} + +static void owl_uart_send_chars(struct uart_port *port) +{ + struct circ_buf *xmit = &port->state->xmit; + unsigned int ch; + + if (uart_tx_stopped(port)) + return; + + if (port->x_char) { + while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) + cpu_relax(); + owl_uart_write(port, port->x_char, OWL_UART_TXDAT); + port->icount.tx++; + port->x_char = 0; + } + + while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) { + if (uart_circ_empty(xmit)) + break; + + ch = xmit->buf[xmit->tail]; + owl_uart_write(port, ch, OWL_UART_TXDAT); + xmit->tail = (xmit->tail + 1) & (SERIAL_XMIT_SIZE - 1); + port->icount.tx++; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) + owl_uart_stop_tx(port); +} + +static void owl_uart_receive_chars(struct uart_port *port) +{ + u32 stat, val; + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~OWL_UART_CTL_TRFS_TX; + owl_uart_write(port, val, OWL_UART_CTL); + + stat = owl_uart_read(port, OWL_UART_STAT); + while (!(stat & OWL_UART_STAT_RFEM)) { + char flag = TTY_NORMAL; + + if (stat & OWL_UART_STAT_RXER) + port->icount.overrun++; + + if (stat & OWL_UART_STAT_RXST) { + /* We are not able to distinguish the error type. */ + port->icount.brk++; + port->icount.frame++; + + stat &= port->read_status_mask; + if (stat & OWL_UART_STAT_RXST) + flag = TTY_PARITY; + } else + port->icount.rx++; + + val = owl_uart_read(port, OWL_UART_RXDAT); + val &= 0xff; + + if ((stat & port->ignore_status_mask) == 0) + tty_insert_flip_char(&port->state->port, val, flag); + + stat = owl_uart_read(port, OWL_UART_STAT); + } + + spin_unlock(&port->lock); + tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock); +} + +static irqreturn_t owl_uart_irq(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + unsigned long flags; + u32 stat; + + spin_lock_irqsave(&port->lock, flags); + + stat = owl_uart_read(port, OWL_UART_STAT); + + if (stat & OWL_UART_STAT_RIP) + owl_uart_receive_chars(port); + + if (stat & OWL_UART_STAT_TIP) + owl_uart_send_chars(port); + + stat = owl_uart_read(port, OWL_UART_STAT); + stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP; + owl_uart_write(port, stat, OWL_UART_STAT); + + spin_unlock_irqrestore(&port->lock, flags); + + return IRQ_HANDLED; +} + +static void owl_uart_shutdown(struct uart_port *port) +{ + u32 val; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_RXIE + | OWL_UART_CTL_TXDE | OWL_UART_CTL_RXDE | OWL_UART_CTL_EN); + owl_uart_write(port, val, OWL_UART_CTL); + + spin_unlock_irqrestore(&port->lock, flags); + + free_irq(port->irq, port); +} + +static int owl_uart_startup(struct uart_port *port) +{ + u32 val; + unsigned long flags; + int ret; + + ret = request_irq(port->irq, owl_uart_irq, IRQF_TRIGGER_HIGH, + "owl-uart", port); + if (ret) + return ret; + + spin_lock_irqsave(&port->lock, flags); + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP + | OWL_UART_STAT_RXER | OWL_UART_STAT_TFER | OWL_UART_STAT_RXST; + owl_uart_write(port, val, OWL_UART_STAT); + + val = owl_uart_read(port, OWL_UART_CTL); + val |= OWL_UART_CTL_RXIE | OWL_UART_CTL_TXIE; + val |= OWL_UART_CTL_EN; + owl_uart_write(port, val, OWL_UART_CTL); + + spin_unlock_irqrestore(&port->lock, flags); + + return 0; +} + +static void owl_uart_change_baudrate(struct owl_uart_port *owl_port, + unsigned long baud) +{ + clk_set_rate(owl_port->clk, baud * 8); +} + +static void owl_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + struct ktermios *old) +{ + struct owl_uart_port *owl_port = to_owl_uart_port(port); + unsigned int baud; + u32 ctl; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + ctl = owl_uart_read(port, OWL_UART_CTL); + + ctl &= ~OWL_UART_CTL_DWLS_MASK; + switch (termios->c_cflag & CSIZE) { + case CS5: + ctl |= OWL_UART_CTL_DWLS_5BITS; + break; + case CS6: + ctl |= OWL_UART_CTL_DWLS_6BITS; + break; + case CS7: + ctl |= OWL_UART_CTL_DWLS_7BITS; + break; + case CS8: + default: + ctl |= OWL_UART_CTL_DWLS_8BITS; + break; + } + + if (termios->c_cflag & CSTOPB) + ctl |= OWL_UART_CTL_STPS_2BITS; + else + ctl &= ~OWL_UART_CTL_STPS_2BITS; + + ctl &= ~OWL_UART_CTL_PRS_MASK; + if (termios->c_cflag & PARENB) { + if (termios->c_cflag & CMSPAR) { + if (termios->c_cflag & PARODD) + ctl |= OWL_UART_CTL_PRS_MARK; + else + ctl |= OWL_UART_CTL_PRS_SPACE; + } else if (termios->c_cflag & PARODD) + ctl |= OWL_UART_CTL_PRS_ODD; + else + ctl |= OWL_UART_CTL_PRS_EVEN; + } else + ctl |= OWL_UART_CTL_PRS_NONE; + + if (termios->c_cflag & CRTSCTS) + ctl |= OWL_UART_CTL_AFE; + else + ctl &= ~OWL_UART_CTL_AFE; + + owl_uart_write(port, ctl, OWL_UART_CTL); + + baud = uart_get_baud_rate(port, termios, old, 9600, 3200000); + owl_uart_change_baudrate(owl_port, baud); + + /* Don't rewrite B0 */ + if (tty_termios_baud_rate(termios)) + tty_termios_encode_baud_rate(termios, baud, baud); + + port->read_status_mask |= OWL_UART_STAT_RXER; + if (termios->c_iflag & INPCK) + port->read_status_mask |= OWL_UART_STAT_RXST; + + uart_update_timeout(port, termios->c_cflag, baud); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void owl_uart_release_port(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return; + + if (port->flags & UPF_IOREMAP) { + devm_release_mem_region(port->dev, port->mapbase, + resource_size(res)); + devm_iounmap(port->dev, port->membase); + port->membase = NULL; + } +} + +static int owl_uart_request_port(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + if (!devm_request_mem_region(port->dev, port->mapbase, + resource_size(res), dev_name(port->dev))) + return -EBUSY; + + if (port->flags & UPF_IOREMAP) { + port->membase = devm_ioremap_nocache(port->dev, port->mapbase, + resource_size(res)); + if (!port->membase) + return -EBUSY; + } + + return 0; +} + +static const char *owl_uart_type(struct uart_port *port) +{ + return (port->type == PORT_OWL) ? "owl-uart" : NULL; +} + +static int owl_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + if (port->type != PORT_OWL) + return -EINVAL; + + if (port->irq != ser->irq) + return -EINVAL; + + return 0; +} + +static void owl_uart_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_OWL; + owl_uart_request_port(port); + } +} + +static const struct uart_ops owl_uart_ops = { + .set_mctrl = owl_uart_set_mctrl, + .get_mctrl = owl_uart_get_mctrl, + .tx_empty = owl_uart_tx_empty, + .start_tx = owl_uart_start_tx, + .stop_rx = owl_uart_stop_rx, + .stop_tx = owl_uart_stop_tx, + .startup = owl_uart_startup, + .shutdown = owl_uart_shutdown, + .set_termios = owl_uart_set_termios, + .type = owl_uart_type, + .config_port = owl_uart_config_port, + .request_port = owl_uart_request_port, + .release_port = owl_uart_release_port, + .verify_port = owl_uart_verify_port, +}; + #ifdef CONFIG_SERIAL_OWL_CONSOLE static void owl_console_putchar(struct uart_port *port, int ch) @@ -110,6 +546,57 @@ static void owl_uart_port_write(struct uart_port *port, const char *s, local_irq_restore(flags); } +static void owl_uart_console_write(struct console *co, const char *s, + u_int count) +{ + struct owl_uart_port *owl_port; + + owl_port = owl_uart_ports[co->index]; + if (!owl_port) + return; + + owl_uart_port_write(&owl_port->port, s, count); +} + +static int owl_uart_console_setup(struct console *co, char *options) +{ + struct owl_uart_port *owl_port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= OWL_UART_PORT_NUM) + return -EINVAL; + + owl_port = owl_uart_ports[co->index]; + if (!owl_port || !owl_port->port.membase) + return -ENODEV; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(&owl_port->port, co, baud, parity, bits, flow); +} + +static struct console owl_uart_console = { + .name = OWL_UART_DEV_NAME, + .write = owl_uart_console_write, + .device = uart_console_device, + .setup = owl_uart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &owl_uart_driver, +}; + +static int __init owl_uart_console_init(void) +{ + register_console(&owl_uart_console); + + return 0; +} +console_initcall(owl_uart_console_init); + static void owl_uart_early_console_write(struct console *co, const char *s, u_int count) @@ -132,4 +619,148 @@ owl_uart_early_console_setup(struct earlycon_device *device, const char *opt) OF_EARLYCON_DECLARE(owl, "actions,owl-uart", owl_uart_early_console_setup); -#endif /* CONFIG_SERIAL_OWL_CONSOLE */ +#define OWL_UART_CONSOLE (&owl_uart_console) +#else +#define OWL_UART_CONSOLE NULL +#endif + +static struct uart_driver owl_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "owl-uart", + .dev_name = OWL_UART_DEV_NAME, + .nr = OWL_UART_PORT_NUM, + .cons = OWL_UART_CONSOLE, +}; + +static const struct owl_uart_info owl_s500_info = { + .tx_fifosize = 16, +}; + +static const struct owl_uart_info owl_s900_info = { + .tx_fifosize = 32, +}; + +static const struct of_device_id owl_uart_dt_matches[] = { + { .compatible = "actions,s500-uart", .data = &owl_s500_info }, + { .compatible = "actions,s900-uart", .data = &owl_s900_info }, + { } +}; +MODULE_DEVICE_TABLE(of, owl_uart_dt_matches); + +static int owl_uart_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct owl_uart_info *info = NULL; + struct resource *res_mem; + struct owl_uart_port *owl_port; + int ret, irq; + + if (pdev->dev.of_node) { + pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); + match = of_match_node(owl_uart_dt_matches, pdev->dev.of_node); + if (match) + info = match->data; + } + + if (pdev->id < 0 || pdev->id >= OWL_UART_PORT_NUM) { + dev_err(&pdev->dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mem) { + dev_err(&pdev->dev, "could not get mem\n"); + return -ENODEV; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "could not get irq\n"); + return irq; + } + + if (owl_uart_ports[pdev->id]) { + dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); + return -EBUSY; + } + + owl_port = devm_kzalloc(&pdev->dev, sizeof(*owl_port), GFP_KERNEL); + if (!owl_port) + return -ENOMEM; + + owl_port->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(owl_port->clk)) { + dev_err(&pdev->dev, "could not get clk\n"); + return PTR_ERR(owl_port->clk); + } + + owl_port->port.dev = &pdev->dev; + owl_port->port.line = pdev->id; + owl_port->port.type = PORT_OWL; + owl_port->port.iotype = UPIO_MEM; + owl_port->port.mapbase = res_mem->start; + owl_port->port.irq = irq; + owl_port->port.uartclk = clk_get_rate(owl_port->clk); + if (owl_port->port.uartclk == 0) { + dev_err(&pdev->dev, "clock rate is zero\n"); + return -EINVAL; + } + owl_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY; + owl_port->port.x_char = 0; + owl_port->port.fifosize = (info) ? info->tx_fifosize : 16; + owl_port->port.ops = &owl_uart_ops; + + owl_uart_ports[pdev->id] = owl_port; + platform_set_drvdata(pdev, owl_port); + + ret = uart_add_one_port(&owl_uart_driver, &owl_port->port); + if (ret) + owl_uart_ports[pdev->id] = NULL; + + return ret; +} + +static int owl_uart_remove(struct platform_device *pdev) +{ + struct owl_uart_port *owl_port = platform_get_drvdata(pdev); + + uart_remove_one_port(&owl_uart_driver, &owl_port->port); + owl_uart_ports[pdev->id] = NULL; + + return 0; +} + +static struct platform_driver owl_uart_platform_driver = { + .probe = owl_uart_probe, + .remove = owl_uart_remove, + .driver = { + .name = "owl-uart", + .of_match_table = owl_uart_dt_matches, + }, +}; + +static int __init owl_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&owl_uart_driver); + if (ret) + return ret; + + ret = platform_driver_register(&owl_uart_platform_driver); + if (ret) + uart_unregister_driver(&owl_uart_driver); + + return ret; +} + +static void __init owl_uart_exit(void) +{ + platform_driver_unregister(&owl_uart_platform_driver); + uart_unregister_driver(&owl_uart_driver); +} + +module_init(owl_uart_init); +module_exit(owl_uart_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index d3796dc26fa9a4e4ffd2deec9ff1053bf7a4a3a3..d9123f9957058f4870008f2a5e1cf57368b377aa 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -46,11 +46,6 @@ enum { PCH_UART_HANDLED_LS_INT_SHIFT, }; -enum { - PCH_UART_8LINE, - PCH_UART_2LINE, -}; - #define PCH_UART_DRIVER_DEVICE "ttyPCH" /* Set the max number of UART port @@ -267,7 +262,7 @@ struct eg20t_port { /** * struct pch_uart_driver_data - private data structure for UART-DMA - * @port_type: The number of DMA channel + * @port_type: The type of UART port * @line_no: UART port line number (0, 1, 2...) */ struct pch_uart_driver_data { @@ -290,17 +285,17 @@ enum pch_uart_num_t { }; static struct pch_uart_driver_data drv_dat[] = { - [pch_et20t_uart0] = {PCH_UART_8LINE, 0}, - [pch_et20t_uart1] = {PCH_UART_2LINE, 1}, - [pch_et20t_uart2] = {PCH_UART_2LINE, 2}, - [pch_et20t_uart3] = {PCH_UART_2LINE, 3}, - [pch_ml7213_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7213_uart1] = {PCH_UART_2LINE, 1}, - [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, - [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, - [pch_ml7831_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, + [pch_et20t_uart0] = {PORT_PCH_8LINE, 0}, + [pch_et20t_uart1] = {PORT_PCH_2LINE, 1}, + [pch_et20t_uart2] = {PORT_PCH_2LINE, 2}, + [pch_et20t_uart3] = {PORT_PCH_2LINE, 3}, + [pch_ml7213_uart0] = {PORT_PCH_8LINE, 0}, + [pch_ml7213_uart1] = {PORT_PCH_2LINE, 1}, + [pch_ml7213_uart2] = {PORT_PCH_2LINE, 2}, + [pch_ml7223_uart0] = {PORT_PCH_8LINE, 0}, + [pch_ml7223_uart1] = {PORT_PCH_2LINE, 1}, + [pch_ml7831_uart0] = {PORT_PCH_8LINE, 0}, + [pch_ml7831_uart1] = {PORT_PCH_2LINE, 1}, }; #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE @@ -376,7 +371,7 @@ static const struct file_operations port_regs_ops = { }; #endif /* CONFIG_DEBUG_FS */ -static struct dmi_system_id pch_uart_dmi_table[] = { +static const struct dmi_system_id pch_uart_dmi_table[] = { { .ident = "CM-iTC", { @@ -1777,10 +1772,10 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, goto init_port_free_txbuf; switch (port_type) { - case PORT_UNKNOWN: + case PORT_PCH_8LINE: fifosize = 256; /* EG20T/ML7213: UART0 */ break; - case PORT_8250: + case PORT_PCH_2LINE: fifosize = 64; /* EG20T:UART1~3 ML7213: UART1~2*/ break; default: @@ -1804,7 +1799,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, priv->fifo_size = fifosize; priv->uartclk = pch_uart_get_uartclk(); - priv->port_type = PORT_MAX_8250 + port_type + 1; + priv->port_type = port_type; priv->port.dev = &pdev->dev; priv->port.iobase = iobase; priv->port.membase = NULL; @@ -1862,8 +1857,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv) { #ifdef CONFIG_DEBUG_FS - if (priv->debugfs) - debugfs_remove(priv->debugfs); + debugfs_remove(priv->debugfs); #endif uart_remove_one_port(&pch_uart_driver, &priv->port); free_page((unsigned long)priv->rxbuf.buf); diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 0da52947e59e0f7deec59244ad31f473be36349a..6ccdd018fb453c287a20de5f9469aa484dde21ba 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1671,8 +1671,8 @@ static int __init pmz_probe(void) if (!node_a && !node_b) { of_node_put(node_a); of_node_put(node_b); - printk(KERN_ERR "pmac_zilog: missing node %c for escc %s\n", - (!node_a) ? 'a' : 'b', node_p->full_name); + printk(KERN_ERR "pmac_zilog: missing node %c for escc %pOF\n", + (!node_a) ? 'a' : 'b', node_p); continue; } diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index cdd2f942317c59fe4ec04c022a004d871f551fde..b9c7a904c1eaf7716d2137d5bcded2a8c805c17d 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -889,7 +889,16 @@ static int sccnxp_probe(struct platform_device *pdev) goto err_out; uartclk = 0; } else { - clk_prepare_enable(clk); + ret = clk_prepare_enable(clk); + if (ret) + goto err_out; + + ret = devm_add_action_or_reset(&pdev->dev, + (void(*)(void *))clk_disable_unprepare, + clk); + if (ret) + goto err_out; + uartclk = clk_get_rate(clk); } @@ -988,7 +997,7 @@ static int sccnxp_probe(struct platform_device *pdev) uart_unregister_driver(&s->uart); err_out: if (!IS_ERR(s->regulator)) - return regulator_disable(s->regulator); + regulator_disable(s->regulator); return ret; } diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index d92a150c8733611ef9ddec62336268ff9d6456f8..cf9b736f26f88ead0afa6ac15e2b4b0e25127309 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1310,7 +1310,7 @@ static int tegra_uart_probe(struct platform_device *pdev) return PTR_ERR(tup->uart_clk); } - tup->rst = devm_reset_control_get(&pdev->dev, "serial"); + tup->rst = devm_reset_control_get_exclusive(&pdev->dev, "serial"); if (IS_ERR(tup->rst)) { dev_err(&pdev->dev, "Couldn't get the reset\n"); return PTR_ERR(tup->rst); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index f534a40aebdeeadba3f344f229f1b8ac067370d1..3a14cccbd7fffd6428d0a833afabe3045d017d09 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include /* @@ -165,6 +165,27 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) #define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) #define uart_clear_mctrl(port, clear) uart_update_mctrl(port, 0, clear) +static void uart_port_dtr_rts(struct uart_port *uport, int raise) +{ + int rs485_on = uport->rs485_config && + (uport->rs485.flags & SER_RS485_ENABLED); + int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND); + + if (raise) { + if (rs485_on && !RTS_after_send) { + uart_set_mctrl(uport, TIOCM_DTR); + uart_clear_mctrl(uport, TIOCM_RTS); + } else { + uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + } + } else { + unsigned int clear = TIOCM_DTR; + + clear |= (!rs485_on || !RTS_after_send) ? TIOCM_RTS : 0; + uart_clear_mctrl(uport, clear); + } +} + /* * Startup the port. This will be called once per open. All calls * will be serialised by the per-port mutex. @@ -214,7 +235,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, * port is open and ready to respond. */ if (init_hw && C_BAUD(tty)) - uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); + uart_port_dtr_rts(uport, 1); } /* @@ -272,7 +293,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) uport->cons->cflag = tty->termios.c_cflag; if (!tty || C_HUPCL(tty)) - uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + uart_port_dtr_rts(uport, 0); uart_port_shutdown(port); } @@ -744,7 +765,7 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo) if (HIGH_BITS_OFFSET) retinfo->port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; retinfo->irq = uport->irq; - retinfo->flags = uport->flags; + retinfo->flags = (__force int)uport->flags; retinfo->xmit_fifo_size = uport->fifosize; retinfo->baud_base = uport->uartclk / 16; retinfo->close_delay = jiffies_to_msecs(port->close_delay) / 10; @@ -818,7 +839,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, new_info->type != uport->type); old_flags = uport->flags; - new_flags = new_info->flags; + new_flags = (__force upf_t)new_info->flags; old_custom_divisor = uport->custom_divisor; if (!capable(CAP_SYS_ADMIN)) { @@ -1658,7 +1679,7 @@ static int uart_carrier_raised(struct tty_port *port) return 0; } -static void uart_dtr_rts(struct tty_port *port, int onoff) +static void uart_dtr_rts(struct tty_port *port, int raise) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; @@ -1666,12 +1687,7 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) uport = uart_port_ref(state); if (!uport) return; - - if (onoff) - uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); - else - uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); - + uart_port_dtr_rts(uport, raise); uart_port_deref(uport); } @@ -2083,8 +2099,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (tty_dev && device_may_wakeup(tty_dev)) { - if (!enable_irq_wake(uport->irq)) - uport->irq_wake = 1; + enable_irq_wake(uport->irq); put_device(tty_dev); mutex_unlock(&port->mutex); return 0; @@ -2147,10 +2162,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (!uport->suspended && device_may_wakeup(tty_dev)) { - if (uport->irq_wake) { + if (irqd_is_wakeup_set(irq_get_irq_data((uport->irq)))) disable_irq_wake(uport->irq); - uport->irq_wake = 0; - } put_device(tty_dev); mutex_unlock(&port->mutex); return 0; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index e08b16b070c0fb914916dd6c2f78fcf3546edfea..784dd42002eadbeb98bb15c23c776ffa10b483ef 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3073,8 +3073,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev, p->type = SCI_OF_TYPE(match->data); p->regtype = SCI_OF_REGTYPE(match->data); - if (of_find_property(np, "uart-has-rtscts", NULL)) - sp->has_rtscts = true; + sp->has_rtscts = of_property_read_bool(np, "uart-has-rtscts"); return p; } diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 90996ad97b3718cfa85a0505a47b7e8d7be770c9..e902494ebbd56773ba95d0677faa7d940e9a6ef8 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -63,6 +63,7 @@ /* interrupt clear register */ #define SPRD_ICLR 0x0014 +#define SPRD_ICLR_TIMEOUT BIT(13) /* line control register */ #define SPRD_LCR 0x0018 @@ -298,7 +299,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) return IRQ_NONE; } - serial_out(port, SPRD_ICLR, ~0); + if (ims & SPRD_IMSR_TIMEOUT) + serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) @@ -729,8 +731,8 @@ static int sprd_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(&pdev->dev, "not provide irq resource\n"); - return -ENODEV; + dev_err(&pdev->dev, "not provide irq resource: %d\n", irq); + return irq; } up->irq = irq; diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 6b0ca65027d00162e6a8099527878cdea3599f82..b313a792b149d6425a47a5ddaca318f0af8afe78 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -310,7 +310,7 @@ static void asc_receive_chars(struct uart_port *port) if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR) ignore_pe = true; - if (port->irq_wake) + if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) pm_wakeup_event(tport->tty->dev, 0); while ((status = asc_in(port, ASC_STA)) & ASC_STA_RBF) { diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 033856287ca21268ded24f646fc04d4f0354715c..03a583264d9ec78eec786930c7783b1047c82596 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1,5 +1,6 @@ /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics SA 2017 * Authors: Maxime Coquelin * Gerald Baeza * License terms: GNU General Public License (GPL), version 2 @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -110,14 +112,13 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded) unsigned long c; u32 sr; char flag; - static int last_res = RX_BUF_L; - if (port->irq_wake) + if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) pm_wakeup_event(tport->tty->dev, 0); - while (stm32_pending_rx(port, &sr, &last_res, threaded)) { + while (stm32_pending_rx(port, &sr, &stm32_port->last_res, threaded)) { sr |= USART_SR_DUMMY_RX; - c = stm32_get_char(port, &sr, &last_res); + c = stm32_get_char(port, &sr, &stm32_port->last_res); flag = TTY_NORMAL; port->icount.rx++; @@ -202,7 +203,7 @@ static void stm32_transmit_chars_pio(struct uart_port *port) ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, (isr & USART_SR_TXE), - 10, 100); + 10, 100000); if (ret) dev_err(port->dev, "tx empty not set\n"); @@ -326,6 +327,10 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr) sr = readl_relaxed(port->membase + ofs->isr); + if ((sr & USART_SR_WUF) && (ofs->icr != UNDEF_REG)) + writel_relaxed(USART_ICR_WUCF, + port->membase + ofs->icr); + if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch)) stm32_receive_chars(port, false); @@ -442,6 +447,7 @@ static int stm32_startup(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + struct stm32_usart_config *cfg = &stm32_port->info->cfg; const char *name = to_platform_device(port->dev)->name; u32 val; int ret; @@ -452,7 +458,18 @@ static int stm32_startup(struct uart_port *port) if (ret) return ret; + if (cfg->has_wakeup && stm32_port->wakeirq >= 0) { + ret = dev_pm_set_dedicated_wake_irq(port->dev, + stm32_port->wakeirq); + if (ret) { + free_irq(port->irq, port); + return ret; + } + } + val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; + if (stm32_port->fifoen) + val |= USART_CR1_FIFOEN; stm32_set_bits(port, ofs->cr1, val); return 0; @@ -467,8 +484,11 @@ static void stm32_shutdown(struct uart_port *port) val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; val |= BIT(cfg->uart_enable_bit); + if (stm32_port->fifoen) + val |= USART_CR1_FIFOEN; stm32_clr_bits(port, ofs->cr1, val); + dev_pm_clear_wake_irq(port->dev); free_irq(port->irq, port); } @@ -496,6 +516,8 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; cr1 |= BIT(cfg->uart_enable_bit); + if (stm32_port->fifoen) + cr1 |= USART_CR1_FIFOEN; cr2 = 0; cr3 = 0; @@ -518,7 +540,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); if (cflag & CRTSCTS) { port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; - cr3 |= USART_CR3_CTSE; + cr3 |= USART_CR3_CTSE | USART_CR3_RTSE; } usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud); @@ -659,6 +681,8 @@ static int stm32_init_port(struct stm32_port *stm32port, port->ops = &stm32_uart_ops; port->dev = &pdev->dev; port->irq = platform_get_irq(pdev, 0); + stm32port->wakeirq = platform_get_irq(pdev, 1); + stm32port->fifoen = stm32port->info->cfg.has_fifo; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); port->membase = devm_ioremap_resource(&pdev->dev, res); @@ -678,8 +702,10 @@ static int stm32_init_port(struct stm32_port *stm32port, return ret; stm32port->port.uartclk = clk_get_rate(stm32port->clk); - if (!stm32port->port.uartclk) + if (!stm32port->port.uartclk) { + clk_disable_unprepare(stm32port->clk); ret = -EINVAL; + } return ret; } @@ -693,8 +719,10 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) return NULL; id = of_alias_get_id(np, "serial"); - if (id < 0) - id = 0; + if (id < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", id); + return NULL; + } if (WARN_ON(id >= STM32_MAX_PORTS)) return NULL; @@ -702,6 +730,7 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) stm32_ports[id].hw_flow_control = of_property_read_bool(np, "st,hw-flow-ctrl"); stm32_ports[id].port.line = id; + stm32_ports[id].last_res = RX_BUF_L; return &stm32_ports[id]; } @@ -711,6 +740,8 @@ static const struct of_device_id stm32_match[] = { { .compatible = "st,stm32-uart", .data = &stm32f4_info}, { .compatible = "st,stm32f7-usart", .data = &stm32f7_info}, { .compatible = "st,stm32f7-uart", .data = &stm32f7_info}, + { .compatible = "st,stm32h7-usart", .data = &stm32h7_info}, + { .compatible = "st,stm32h7-uart", .data = &stm32h7_info}, {}, }; @@ -860,9 +891,15 @@ static int stm32_serial_probe(struct platform_device *pdev) if (ret) return ret; + if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0) { + ret = device_init_wakeup(&pdev->dev, true); + if (ret) + goto err_uninit; + } + ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port); if (ret) - return ret; + goto err_nowup; ret = stm32_of_dma_rx_probe(stm32port, pdev); if (ret) @@ -875,6 +912,15 @@ static int stm32_serial_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &stm32port->port); return 0; + +err_nowup: + if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0) + device_init_wakeup(&pdev->dev, false); + +err_uninit: + clk_disable_unprepare(stm32port->clk); + + return ret; } static int stm32_serial_remove(struct platform_device *pdev) @@ -882,6 +928,7 @@ static int stm32_serial_remove(struct platform_device *pdev) struct uart_port *port = platform_get_drvdata(pdev); struct stm32_port *stm32_port = to_stm32_port(port); struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + struct stm32_usart_config *cfg = &stm32_port->info->cfg; stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR); @@ -903,6 +950,9 @@ static int stm32_serial_remove(struct platform_device *pdev) TX_BUF_L, stm32_port->tx_buf, stm32_port->tx_dma_buf); + if (cfg->has_wakeup && stm32_port->wakeirq >= 0) + device_init_wakeup(&pdev->dev, false); + clk_disable_unprepare(stm32_port->clk); return uart_remove_one_port(&stm32_usart_driver, port); @@ -1008,11 +1058,66 @@ static struct uart_driver stm32_usart_driver = { .cons = STM32_SERIAL_CONSOLE, }; +#ifdef CONFIG_PM_SLEEP +static void stm32_serial_enable_wakeup(struct uart_port *port, bool enable) +{ + struct stm32_port *stm32_port = to_stm32_port(port); + struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + struct stm32_usart_config *cfg = &stm32_port->info->cfg; + u32 val; + + if (!cfg->has_wakeup || stm32_port->wakeirq < 0) + return; + + if (enable) { + stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); + stm32_set_bits(port, ofs->cr1, USART_CR1_UESM); + val = readl_relaxed(port->membase + ofs->cr3); + val &= ~USART_CR3_WUS_MASK; + /* Enable Wake up interrupt from low power on start bit */ + val |= USART_CR3_WUS_START_BIT | USART_CR3_WUFIE; + writel_relaxed(val, port->membase + ofs->cr3); + stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); + } else { + stm32_clr_bits(port, ofs->cr1, USART_CR1_UESM); + } +} + +static int stm32_serial_suspend(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + + uart_suspend_port(&stm32_usart_driver, port); + + if (device_may_wakeup(dev)) + stm32_serial_enable_wakeup(port, true); + else + stm32_serial_enable_wakeup(port, false); + + return 0; +} + +static int stm32_serial_resume(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + stm32_serial_enable_wakeup(port, false); + + return uart_resume_port(&stm32_usart_driver, port); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops stm32_serial_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(stm32_serial_suspend, stm32_serial_resume) +}; + static struct platform_driver stm32_serial_driver = { .probe = stm32_serial_probe, .remove = stm32_serial_remove, .driver = { .name = DRIVER_NAME, + .pm = &stm32_serial_pm_ops, .of_match_table = of_match_ptr(stm32_match), }, }; diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index cd97ceb76e4ffe6f48af1a614532bdf42318e2de..ffc0c5285e511ea6863473723c9343f8d9ddf1d4 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -1,5 +1,6 @@ /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics SA 2017 * Authors: Maxime Coquelin * Gerald Baeza * License terms: GNU General Public License (GPL), version 2 @@ -24,6 +25,8 @@ struct stm32_usart_offsets { struct stm32_usart_config { u8 uart_enable_bit; /* USART_CR1_UE */ bool has_7bits_data; + bool has_wakeup; + bool has_fifo; }; struct stm32_usart_info { @@ -74,6 +77,28 @@ struct stm32_usart_info stm32f7_info = { } }; +struct stm32_usart_info stm32h7_info = { + .ofs = { + .cr1 = 0x00, + .cr2 = 0x04, + .cr3 = 0x08, + .brr = 0x0c, + .gtpr = 0x10, + .rtor = 0x14, + .rqr = 0x18, + .isr = 0x1c, + .icr = 0x20, + .rdr = 0x24, + .tdr = 0x28, + }, + .cfg = { + .uart_enable_bit = 0, + .has_7bits_data = true, + .has_wakeup = true, + .has_fifo = true, + } +}; + /* USART_SR (F4) / USART_ISR (F7) */ #define USART_SR_PE BIT(0) #define USART_SR_FE BIT(1) @@ -93,6 +118,7 @@ struct stm32_usart_info stm32f7_info = { #define USART_SR_BUSY BIT(16) /* F7 */ #define USART_SR_CMF BIT(17) /* F7 */ #define USART_SR_SBKF BIT(18) /* F7 */ +#define USART_SR_WUF BIT(20) /* H7 */ #define USART_SR_TEACK BIT(21) /* F7 */ #define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \ USART_SR_FE | USART_SR_PE) @@ -113,6 +139,7 @@ struct stm32_usart_info stm32f7_info = { /* USART_CR1 */ #define USART_CR1_SBK BIT(0) #define USART_CR1_RWU BIT(1) /* F4 */ +#define USART_CR1_UESM BIT(1) /* H7 */ #define USART_CR1_RE BIT(2) #define USART_CR1_TE BIT(3) #define USART_CR1_IDLEIE BIT(4) @@ -134,6 +161,7 @@ struct stm32_usart_info stm32f7_info = { #define USART_CR1_EOBIE BIT(27) /* F7 */ #define USART_CR1_M1 BIT(28) /* F7 */ #define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27)) +#define USART_CR1_FIFOEN BIT(29) /* H7 */ /* USART_CR2 */ #define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */ @@ -175,6 +203,9 @@ struct stm32_usart_info stm32f7_info = { #define USART_CR3_DEM BIT(14) /* F7 */ #define USART_CR3_DEP BIT(15) /* F7 */ #define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */ +#define USART_CR3_WUS_MASK GENMASK(21, 20) /* H7 */ +#define USART_CR3_WUS_START_BIT BIT(21) /* H7 */ +#define USART_CR3_WUFIE BIT(22) /* H7 */ /* USART_GTPR */ #define USART_GTPR_PSC_MASK GENMASK(7, 0) @@ -203,9 +234,10 @@ struct stm32_usart_info stm32f7_info = { #define USART_ICR_RTOCF BIT(11) /* F7 */ #define USART_ICR_EOBCF BIT(12) /* F7 */ #define USART_ICR_CMCF BIT(17) /* F7 */ +#define USART_ICR_WUCF BIT(20) /* H7 */ #define STM32_SERIAL_NAME "ttyS" -#define STM32_MAX_PORTS 6 +#define STM32_MAX_PORTS 8 #define RX_BUF_L 200 /* dma rx buffer length */ #define RX_BUF_P RX_BUF_L /* dma rx buffer period */ @@ -221,8 +253,11 @@ struct stm32_port { struct dma_chan *tx_ch; /* dma tx channel */ dma_addr_t tx_dma_buf; /* dma tx buffer bus address */ unsigned char *tx_buf; /* dma tx buffer cpu address */ + int last_res; bool tx_dma_busy; /* dma tx busy */ bool hw_flow_control; + bool fifoen; + int wakeirq; }; static struct stm32_port stm32_ports[STM32_MAX_PORTS]; diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index b5e3195b3697334598f4f1171afe83825d6b0637..653a076d89d3274a3ed0151c433ddd09a227d400 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -819,7 +819,7 @@ static int sunsab_verify_port(struct uart_port *port, struct serial_struct *ser) return -EINVAL; } -static struct uart_ops sunsab_pops = { +static const struct uart_ops sunsab_pops = { .tx_empty = sunsab_tx_empty, .set_mctrl = sunsab_set_mctrl, .get_mctrl = sunsab_get_mctrl, diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 72df2e1b88afe209c8e9420a28f46eeb865b987a..95d34d7565c9aabe5f734c21070a505d77f10043 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -958,7 +958,7 @@ sunsu_type(struct uart_port *port) return uart_config[type].name; } -static struct uart_ops sunsu_pops = { +static const struct uart_ops sunsu_pops = { .tx_empty = sunsu_tx_empty, .set_mctrl = sunsu_set_mctrl, .get_mctrl = sunsu_get_mctrl, @@ -1212,8 +1212,8 @@ static int sunsu_kbd_ms_init(struct uart_sunsu_port *up) if (up->port.type == PORT_UNKNOWN) return -ENODEV; - printk("%s: %s port at %llx, irq %u\n", - up->port.dev->of_node->full_name, + printk("%pOF: %s port at %llx, irq %u\n", + up->port.dev->of_node, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", (unsigned long long) up->port.mapbase, up->port.irq); diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 481eb2989a1e1cbf3a4bbc3274a74c4bb359e3d9..55b7027757863c3337f20a685901f1928b5f756a 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1085,7 +1085,7 @@ static int qe_uart_verify_port(struct uart_port *port, * * Details on these functions can be found in Documentation/serial/driver */ -static struct uart_ops qe_uart_pops = { +static const struct uart_ops qe_uart_pops = { .tx_empty = qe_uart_tx_empty, .set_mctrl = qe_uart_set_mctrl, .get_mctrl = qe_uart_get_mctrl, diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index fde55dcdea5a18481d25301a8a463e1d16c08397..31a630ae0870efec120ec63cdb15464dc947682a 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1163,7 +1163,7 @@ static void cdns_uart_console_putchar(struct uart_port *port, int ch) writel(ch, port->membase + CDNS_UART_FIFO); } -static void __init cdns_early_write(struct console *con, const char *s, +static void cdns_early_write(struct console *con, const char *s, unsigned n) { struct earlycon_device *dev = con->data; diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 3fafc5a1b2e0387c5c160f7c213b56c60e34a7ea..3be9811012979cdcab809adbde204d74f9a8c472 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -884,7 +884,7 @@ static int synclink_init_one (struct pci_dev *dev, const struct pci_device_id *ent); static void synclink_remove_one (struct pci_dev *dev); -static struct pci_device_id synclink_pci_tbl[] = { +static const struct pci_device_id synclink_pci_tbl[] = { { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, /* terminate list */ diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 529c6e3cd5374b7f68e0a7fa5306232c2f0bce02..636b8ae29b465776952d6f4ec9ad18c220200755 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -95,7 +95,7 @@ MODULE_LICENSE("GPL"); #define MGSL_MAGIC 0x5401 #define MAX_DEVICES 32 -static struct pci_device_id pci_table[] = { +static const struct pci_device_id pci_table[] = { {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 9b4fb0251c1ab81552c3ac5a3b32be294d06051b..4fed9e7b281f0c5faad059783205b190be8b15d6 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -479,7 +479,7 @@ static char *driver_version = "$Revision: 4.38 $"; static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); static void synclinkmp_remove_one(struct pci_dev *dev); -static struct pci_device_id synclinkmp_pci_tbl[] = { +static const struct pci_device_id synclinkmp_pci_tbl[] = { { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_SCA, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, /* terminate list */ }; diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 4e7a4e9dcf4d3740b7c4655c37ec54d9ff93b76c..f8eba1c5412f9518a2c30bb3cf6ae365c8d9fbb1 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -361,6 +361,32 @@ int tty_insert_flip_string_flags(struct tty_port *port, } EXPORT_SYMBOL(tty_insert_flip_string_flags); +/** + * __tty_insert_flip_char - Add one character to the tty buffer + * @port: tty port + * @ch: character + * @flag: flag byte + * + * Queue a single byte to the tty buffering, with an optional flag. + * This is the slow path of tty_insert_flip_char. + */ +int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) +{ + struct tty_buffer *tb; + int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; + + if (!__tty_buffer_request_room(port, 1, flags)) + return 0; + + tb = port->buf.tail; + if (~tb->flags & TTYB_NORMAL) + *flag_buf_ptr(tb, tb->used) = flag; + *char_buf_ptr(tb, tb->used++) = ch; + + return 1; +} +EXPORT_SYMBOL(__tty_insert_flip_char); + /** * tty_schedule_flip - push characters to ldisc * @port: tty port to push from diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 974b13d244010de234d0350b9c45425251ff99c6..94cccb6efa32408a03e601225c89632540922ce3 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -280,7 +280,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) { #ifdef CHECK_TTY_COUNT struct list_head *p; - int count = 0; + int count = 0, kopen_count = 0; spin_lock(&tty->files_lock); list_for_each(p, &tty->tty_files) { @@ -291,10 +291,12 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) tty->driver->subtype == PTY_TYPE_SLAVE && tty->link && tty->link->count) count++; - if (tty->count != count) { - tty_warn(tty, "%s: tty->count(%d) != #fd's(%d)\n", - routine, tty->count, count); - return count; + if (tty_port_kopened(tty->port)) + kopen_count++; + if (tty->count != (count + kopen_count)) { + tty_warn(tty, "%s: tty->count(%d) != (#fd's(%d) + #kopen's(%d))\n", + routine, tty->count, count, kopen_count); + return (count + kopen_count); } #endif return 0; @@ -462,6 +464,14 @@ static int hung_up_tty_fasync(int fd, struct file *file, int on) return -ENOTTY; } +static void tty_show_fdinfo(struct seq_file *m, struct file *file) +{ + struct tty_struct *tty = file_tty(file); + + if (tty && tty->ops && tty->ops->show_fdinfo) + tty->ops->show_fdinfo(tty, m); +} + static const struct file_operations tty_fops = { .llseek = no_llseek, .read = tty_read, @@ -472,6 +482,7 @@ static const struct file_operations tty_fops = { .open = tty_open, .release = tty_release, .fasync = tty_fasync, + .show_fdinfo = tty_show_fdinfo, }; static const struct file_operations console_fops = { @@ -1512,6 +1523,38 @@ static int tty_release_checks(struct tty_struct *tty, int idx) return 0; } +/** + * tty_kclose - closes tty opened by tty_kopen + * @tty: tty device + * + * Performs the final steps to release and free a tty device. It is the + * same as tty_release_struct except that it also resets TTY_PORT_KOPENED + * flag on tty->port. + */ +void tty_kclose(struct tty_struct *tty) +{ + /* + * Ask the line discipline code to release its structures + */ + tty_ldisc_release(tty); + + /* Wait for pending work before tty destruction commmences */ + tty_flush_works(tty); + + tty_debug_hangup(tty, "freeing structure\n"); + /* + * The release_tty function takes care of the details of clearing + * the slots and preserving the termios structure. The tty_unlock_pair + * should be safe as we keep a kref while the tty is locked (so the + * unlock never unlocks a freed tty). + */ + mutex_lock(&tty_mutex); + tty_port_set_kopened(tty->port, 0); + release_tty(tty, tty->index); + mutex_unlock(&tty_mutex); +} +EXPORT_SYMBOL_GPL(tty_kclose); + /** * tty_release_struct - release a tty struct * @tty: tty device @@ -1785,6 +1828,56 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, return driver; } +/** + * tty_kopen - open a tty device for kernel + * @device: dev_t of device to open + * + * Opens tty exclusively for kernel. Performs the driver lookup, + * makes sure it's not already opened and performs the first-time + * tty initialization. + * + * Returns the locked initialized &tty_struct + * + * Claims the global tty_mutex to serialize: + * - concurrent first-time tty initialization + * - concurrent tty driver removal w/ lookup + * - concurrent tty removal from driver table + */ +struct tty_struct *tty_kopen(dev_t device) +{ + struct tty_struct *tty; + struct tty_driver *driver = NULL; + int index = -1; + + mutex_lock(&tty_mutex); + driver = tty_lookup_driver(device, NULL, &index); + if (IS_ERR(driver)) { + mutex_unlock(&tty_mutex); + return ERR_CAST(driver); + } + + /* check whether we're reopening an existing tty */ + tty = tty_driver_lookup_tty(driver, NULL, index); + if (IS_ERR(tty)) + goto out; + + if (tty) { + /* drop kref from tty_driver_lookup_tty() */ + tty_kref_put(tty); + tty = ERR_PTR(-EBUSY); + } else { /* tty_init_dev returns tty with the tty_lock held */ + tty = tty_init_dev(driver, index); + if (IS_ERR(tty)) + goto out; + tty_port_set_kopened(tty->port, 1); + } +out: + mutex_unlock(&tty_mutex); + tty_driver_kref_put(driver); + return tty; +} +EXPORT_SYMBOL_GPL(tty_kopen); + /** * tty_open_by_driver - open a tty device * @device: dev_t of device to open @@ -1801,7 +1894,7 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, * - concurrent tty driver removal w/ lookup * - concurrent tty removal from driver table */ -struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, +static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, struct file *filp) { struct tty_struct *tty; @@ -1824,6 +1917,12 @@ struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, } if (tty) { + if (tty_port_kopened(tty->port)) { + tty_kref_put(tty); + mutex_unlock(&tty_mutex); + tty = ERR_PTR(-EBUSY); + goto out; + } mutex_unlock(&tty_mutex); retval = tty_lock_interruptible(tty); tty_kref_put(tty); /* drop kref from tty_driver_lookup_tty() */ @@ -1846,7 +1945,6 @@ struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, tty_driver_kref_put(driver); return tty; } -EXPORT_SYMBOL_GPL(tty_open_by_driver); /** * tty_open - open a tty device @@ -2518,6 +2616,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCSSERIAL: tty_warn_deprecated_flags(p); break; + case TIOCGPTPEER: + /* Special because the struct file is needed */ + return ptm_open_peer(file, tty, (int)arg); default: retval = tty_jobctrl_ioctl(tty, real_tty, file, cmd, arg); if (retval != -ENOIOCTLCMD) diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c new file mode 100644 index 0000000000000000000000000000000000000000..ef01d24858cd659b9d667c964536fe6798bde6bb --- /dev/null +++ b/drivers/tty/vcc.c @@ -0,0 +1,1155 @@ +/* vcc.c: sun4v virtual channel concentrator + * + * Copyright (C) 2017 Oracle. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_MODULE_NAME "vcc" +#define DRV_MODULE_VERSION "1.1" +#define DRV_MODULE_RELDATE "July 1, 2017" + +static char version[] = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")"; + +MODULE_DESCRIPTION("Sun LDOM virtual console concentrator driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +struct vcc_port { + struct vio_driver_state vio; + + spinlock_t lock; + char *domain; + struct tty_struct *tty; /* only populated while dev is open */ + unsigned long index; /* index into the vcc_table */ + + u64 refcnt; + bool excl_locked; + + bool removed; + + /* This buffer is required to support the tty write_room interface + * and guarantee that any characters that the driver accepts will + * be eventually sent, either immediately or later. + */ + int chars_in_buffer; + struct vio_vcc buffer; + + struct timer_list rx_timer; + struct timer_list tx_timer; +}; + +/* Microseconds that thread will delay waiting for a vcc port ref */ +#define VCC_REF_DELAY 100 + +#define VCC_MAX_PORTS 1024 +#define VCC_MINOR_START 0 /* must be zero */ +#define VCC_BUFF_LEN VIO_VCC_MTU_SIZE + +#define VCC_CTL_BREAK -1 +#define VCC_CTL_HUP -2 + +static const char vcc_driver_name[] = "vcc"; +static const char vcc_device_node[] = "vcc"; +static struct tty_driver *vcc_tty_driver; + +static struct vcc_port *vcc_table[VCC_MAX_PORTS]; +static DEFINE_SPINLOCK(vcc_table_lock); + +int vcc_dbg; +int vcc_dbg_ldc; +int vcc_dbg_vio; + +module_param(vcc_dbg, uint, 0664); +module_param(vcc_dbg_ldc, uint, 0664); +module_param(vcc_dbg_vio, uint, 0664); + +#define VCC_DBG_DRV 0x1 +#define VCC_DBG_LDC 0x2 +#define VCC_DBG_PKT 0x4 + +#define vccdbg(f, a...) \ + do { \ + if (vcc_dbg & VCC_DBG_DRV) \ + pr_info(f, ## a); \ + } while (0) \ + +#define vccdbgl(l) \ + do { \ + if (vcc_dbg & VCC_DBG_LDC) \ + ldc_print(l); \ + } while (0) \ + +#define vccdbgp(pkt) \ + do { \ + if (vcc_dbg & VCC_DBG_PKT) { \ + int i; \ + for (i = 0; i < pkt.tag.stype; i++) \ + pr_info("[%c]", pkt.data[i]); \ + } \ + } while (0) \ + +/* Note: Be careful when adding flags to this line discipline. Don't + * add anything that will cause echoing or we'll go into recursive + * loop echoing chars back and forth with the console drivers. + */ +static const struct ktermios vcc_tty_termios = { + .c_iflag = IGNBRK | IGNPAR, + .c_oflag = OPOST, + .c_cflag = B38400 | CS8 | CREAD | HUPCL, + .c_cc = INIT_C_CC, + .c_ispeed = 38400, + .c_ospeed = 38400 +}; + +/** + * vcc_table_add() - Add VCC port to the VCC table + * @port: pointer to the VCC port + * + * Return: index of the port in the VCC table on success, + * -1 on failure + */ +static int vcc_table_add(struct vcc_port *port) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&vcc_table_lock, flags); + for (i = VCC_MINOR_START; i < VCC_MAX_PORTS; i++) { + if (!vcc_table[i]) { + vcc_table[i] = port; + break; + } + } + spin_unlock_irqrestore(&vcc_table_lock, flags); + + if (i < VCC_MAX_PORTS) + return i; + else + return -1; +} + +/** + * vcc_table_remove() - Removes a VCC port from the VCC table + * @index: Index into the VCC table + */ +static void vcc_table_remove(unsigned long index) +{ + unsigned long flags; + + if (WARN_ON(index >= VCC_MAX_PORTS)) + return; + + spin_lock_irqsave(&vcc_table_lock, flags); + vcc_table[index] = NULL; + spin_unlock_irqrestore(&vcc_table_lock, flags); +} + +/** + * vcc_get() - Gets a reference to VCC port + * @index: Index into the VCC table + * @excl: Indicates if an exclusive access is requested + * + * Return: reference to the VCC port, if found + * NULL, if port not found + */ +static struct vcc_port *vcc_get(unsigned long index, bool excl) +{ + struct vcc_port *port; + unsigned long flags; + +try_again: + spin_lock_irqsave(&vcc_table_lock, flags); + + port = vcc_table[index]; + if (!port) { + spin_unlock_irqrestore(&vcc_table_lock, flags); + return NULL; + } + + if (!excl) { + if (port->excl_locked) { + spin_unlock_irqrestore(&vcc_table_lock, flags); + udelay(VCC_REF_DELAY); + goto try_again; + } + port->refcnt++; + spin_unlock_irqrestore(&vcc_table_lock, flags); + return port; + } + + if (port->refcnt) { + spin_unlock_irqrestore(&vcc_table_lock, flags); + /* Threads wanting exclusive access will wait half the time, + * probably giving them higher priority in the case of + * multiple waiters. + */ + udelay(VCC_REF_DELAY/2); + goto try_again; + } + + port->refcnt++; + port->excl_locked = true; + spin_unlock_irqrestore(&vcc_table_lock, flags); + + return port; +} + +/** + * vcc_put() - Returns a reference to VCC port + * @port: pointer to VCC port + * @excl: Indicates if the returned reference is an exclusive reference + * + * Note: It's the caller's responsibility to ensure the correct value + * for the excl flag + */ +static void vcc_put(struct vcc_port *port, bool excl) +{ + unsigned long flags; + + if (!port) + return; + + spin_lock_irqsave(&vcc_table_lock, flags); + + /* check if caller attempted to put with the wrong flags */ + if (WARN_ON((excl && !port->excl_locked) || + (!excl && port->excl_locked))) + goto done; + + port->refcnt--; + + if (excl) + port->excl_locked = false; + +done: + spin_unlock_irqrestore(&vcc_table_lock, flags); +} + +/** + * vcc_get_ne() - Get a non-exclusive reference to VCC port + * @index: Index into the VCC table + * + * Gets a non-exclusive reference to VCC port, if it's not removed + * + * Return: pointer to the VCC port, if found + * NULL, if port not found + */ +static struct vcc_port *vcc_get_ne(unsigned long index) +{ + struct vcc_port *port; + + port = vcc_get(index, false); + + if (port && port->removed) { + vcc_put(port, false); + return NULL; + } + + return port; +} + +static void vcc_kick_rx(struct vcc_port *port) +{ + struct vio_driver_state *vio = &port->vio; + + assert_spin_locked(&port->lock); + + if (!timer_pending(&port->rx_timer) && !port->removed) { + disable_irq_nosync(vio->vdev->rx_irq); + port->rx_timer.expires = (jiffies + 1); + add_timer(&port->rx_timer); + } +} + +static void vcc_kick_tx(struct vcc_port *port) +{ + assert_spin_locked(&port->lock); + + if (!timer_pending(&port->tx_timer) && !port->removed) { + port->tx_timer.expires = (jiffies + 1); + add_timer(&port->tx_timer); + } +} + +static int vcc_rx_check(struct tty_struct *tty, int size) +{ + if (WARN_ON(!tty || !tty->port)) + return 1; + + /* tty_buffer_request_room won't sleep because it uses + * GFP_ATOMIC flag to allocate buffer + */ + if (test_bit(TTY_THROTTLED, &tty->flags) || + (tty_buffer_request_room(tty->port, VCC_BUFF_LEN) < VCC_BUFF_LEN)) + return 0; + + return 1; +} + +static int vcc_rx(struct tty_struct *tty, char *buf, int size) +{ + int len = 0; + + if (WARN_ON(!tty || !tty->port)) + return len; + + len = tty_insert_flip_string(tty->port, buf, size); + if (len) + tty_flip_buffer_push(tty->port); + + return len; +} + +static int vcc_ldc_read(struct vcc_port *port) +{ + struct vio_driver_state *vio = &port->vio; + struct tty_struct *tty; + struct vio_vcc pkt; + int rv = 0; + + tty = port->tty; + if (!tty) { + rv = ldc_rx_reset(vio->lp); + vccdbg("VCC: reset rx q: rv=%d\n", rv); + goto done; + } + + /* Read as long as LDC has incoming data. */ + while (1) { + if (!vcc_rx_check(tty, VIO_VCC_MTU_SIZE)) { + vcc_kick_rx(port); + break; + } + + vccdbgl(vio->lp); + + rv = ldc_read(vio->lp, &pkt, sizeof(pkt)); + if (rv <= 0) + break; + + vccdbg("VCC: ldc_read()=%d\n", rv); + vccdbg("TAG [%02x:%02x:%04x:%08x]\n", + pkt.tag.type, pkt.tag.stype, + pkt.tag.stype_env, pkt.tag.sid); + + if (pkt.tag.type == VIO_TYPE_DATA) { + vccdbgp(pkt); + /* vcc_rx_check ensures memory availability */ + vcc_rx(tty, pkt.data, pkt.tag.stype); + } else { + pr_err("VCC: unknown msg [%02x:%02x:%04x:%08x]\n", + pkt.tag.type, pkt.tag.stype, + pkt.tag.stype_env, pkt.tag.sid); + rv = -ECONNRESET; + break; + } + + WARN_ON(rv != LDC_PACKET_SIZE); + } + +done: + return rv; +} + +static void vcc_rx_timer(unsigned long index) +{ + struct vio_driver_state *vio; + struct vcc_port *port; + unsigned long flags; + int rv; + + port = vcc_get_ne(index); + if (!port) + return; + + spin_lock_irqsave(&port->lock, flags); + port->rx_timer.expires = 0; + + vio = &port->vio; + + enable_irq(vio->vdev->rx_irq); + + if (!port->tty || port->removed) + goto done; + + rv = vcc_ldc_read(port); + if (rv == -ECONNRESET) + vio_conn_reset(vio); + +done: + spin_unlock_irqrestore(&port->lock, flags); + vcc_put(port, false); +} + +static void vcc_tx_timer(unsigned long index) +{ + struct vcc_port *port; + struct vio_vcc *pkt; + unsigned long flags; + int tosend = 0; + int rv; + + port = vcc_get_ne(index); + if (!port) + return; + + spin_lock_irqsave(&port->lock, flags); + port->tx_timer.expires = 0; + + if (!port->tty || port->removed) + goto done; + + tosend = min(VCC_BUFF_LEN, port->chars_in_buffer); + if (!tosend) + goto done; + + pkt = &port->buffer; + pkt->tag.type = VIO_TYPE_DATA; + pkt->tag.stype = tosend; + vccdbgl(port->vio.lp); + + rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); + WARN_ON(!rv); + + if (rv < 0) { + vccdbg("VCC: ldc_write()=%d\n", rv); + vcc_kick_tx(port); + } else { + struct tty_struct *tty = port->tty; + + port->chars_in_buffer = 0; + if (tty) + tty_wakeup(tty); + } + +done: + spin_unlock_irqrestore(&port->lock, flags); + vcc_put(port, false); +} + +/** + * vcc_event() - LDC event processing engine + * @arg: VCC private data + * @event: LDC event + * + * Handles LDC events for VCC + */ +static void vcc_event(void *arg, int event) +{ + struct vio_driver_state *vio; + struct vcc_port *port; + unsigned long flags; + int rv; + + port = arg; + vio = &port->vio; + + spin_lock_irqsave(&port->lock, flags); + + switch (event) { + case LDC_EVENT_RESET: + case LDC_EVENT_UP: + vio_link_state_change(vio, event); + break; + + case LDC_EVENT_DATA_READY: + rv = vcc_ldc_read(port); + if (rv == -ECONNRESET) + vio_conn_reset(vio); + break; + + default: + pr_err("VCC: unexpected LDC event(%d)\n", event); + } + + spin_unlock_irqrestore(&port->lock, flags); +} + +static struct ldc_channel_config vcc_ldc_cfg = { + .event = vcc_event, + .mtu = VIO_VCC_MTU_SIZE, + .mode = LDC_MODE_RAW, + .debug = 0, +}; + +/* Ordered from largest major to lowest */ +static struct vio_version vcc_versions[] = { + { .major = 1, .minor = 0 }, +}; + +static struct tty_port_operations vcc_port_ops = { 0 }; + +static ssize_t vcc_sysfs_domain_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct vcc_port *port; + int rv; + + port = dev_get_drvdata(dev); + if (!port) + return -ENODEV; + + rv = scnprintf(buf, PAGE_SIZE, "%s\n", port->domain); + + return rv; +} + +static int vcc_send_ctl(struct vcc_port *port, int ctl) +{ + struct vio_vcc pkt; + int rv; + + pkt.tag.type = VIO_TYPE_CTRL; + pkt.tag.sid = ctl; + pkt.tag.stype = 0; + + rv = ldc_write(port->vio.lp, &pkt, sizeof(pkt.tag)); + WARN_ON(!rv); + vccdbg("VCC: ldc_write(%ld)=%d\n", sizeof(pkt.tag), rv); + + return rv; +} + +static ssize_t vcc_sysfs_break_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vcc_port *port; + unsigned long flags; + int rv = count; + int brk; + + port = dev_get_drvdata(dev); + if (!port) + return -ENODEV; + + spin_lock_irqsave(&port->lock, flags); + + if (sscanf(buf, "%ud", &brk) != 1 || brk != 1) + rv = -EINVAL; + else if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0) + vcc_kick_tx(port); + + spin_unlock_irqrestore(&port->lock, flags); + + return rv; +} + +static DEVICE_ATTR(domain, 0400, vcc_sysfs_domain_show, NULL); +static DEVICE_ATTR(break, 0200, NULL, vcc_sysfs_break_store); + +static struct attribute *vcc_sysfs_entries[] = { + &dev_attr_domain.attr, + &dev_attr_break.attr, + NULL +}; + +static struct attribute_group vcc_attribute_group = { + .name = NULL, + .attrs = vcc_sysfs_entries, +}; + +/** + * vcc_probe() - Initialize VCC port + * @vdev: Pointer to VIO device of the new VCC port + * @id: VIO device ID + * + * Initializes a VCC port to receive serial console data from + * the guest domain. Sets up a TTY end point on the control + * domain. Sets up VIO/LDC link between the guest & control + * domain endpoints. + * + * Return: status of the probe + */ +static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) +{ + struct mdesc_handle *hp; + struct vcc_port *port; + struct device *dev; + const char *domain; + char *name; + u64 node; + int rv; + + vccdbg("VCC: name=%s\n", dev_name(&vdev->dev)); + + if (!vcc_tty_driver) { + pr_err("VCC: TTY driver not registered\n"); + return -ENODEV; + } + + port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); + + rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, + ARRAY_SIZE(vcc_versions), NULL, name); + if (rv) + goto free_port; + + port->vio.debug = vcc_dbg_vio; + vcc_ldc_cfg.debug = vcc_dbg_ldc; + + rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); + if (rv) + goto free_port; + + spin_lock_init(&port->lock); + + port->index = vcc_table_add(port); + if (port->index == -1) { + pr_err("VCC: no more TTY indices left for allocation\n"); + goto free_ldc; + } + + /* Register the device using VCC table index as TTY index */ + dev = tty_register_device(vcc_tty_driver, port->index, &vdev->dev); + if (IS_ERR(dev)) { + rv = PTR_ERR(dev); + goto free_table; + } + + hp = mdesc_grab(); + + node = vio_vdev_node(hp, vdev); + if (node == MDESC_NODE_NULL) { + rv = -ENXIO; + mdesc_release(hp); + goto unreg_tty; + } + + domain = mdesc_get_property(hp, node, "vcc-domain-name", NULL); + if (!domain) { + rv = -ENXIO; + mdesc_release(hp); + goto unreg_tty; + } + port->domain = kstrdup(domain, GFP_KERNEL); + + mdesc_release(hp); + + rv = sysfs_create_group(&vdev->dev.kobj, &vcc_attribute_group); + if (rv) + goto free_domain; + + init_timer(&port->rx_timer); + port->rx_timer.function = vcc_rx_timer; + port->rx_timer.data = port->index; + + init_timer(&port->tx_timer); + port->tx_timer.function = vcc_tx_timer; + port->tx_timer.data = port->index; + + dev_set_drvdata(&vdev->dev, port); + + /* It's possible to receive IRQs in the middle of vio_port_up. Disable + * IRQs until the port is up. + */ + disable_irq_nosync(vdev->rx_irq); + vio_port_up(&port->vio); + enable_irq(vdev->rx_irq); + + return 0; + +free_domain: + kfree(port->domain); +unreg_tty: + tty_unregister_device(vcc_tty_driver, port->index); +free_table: + vcc_table_remove(port->index); +free_ldc: + vio_ldc_free(&port->vio); +free_port: + kfree(name); + kfree(port); + + return rv; +} + +/** + * vcc_remove() - Terminate a VCC port + * @vdev: Pointer to VIO device of the VCC port + * + * Terminates a VCC port. Sets up the teardown of TTY and + * VIO/LDC link between guest and primary domains. + * + * Return: status of removal + */ +static int vcc_remove(struct vio_dev *vdev) +{ + struct vcc_port *port = dev_get_drvdata(&vdev->dev); + + if (!port) + return -ENODEV; + + del_timer_sync(&port->rx_timer); + del_timer_sync(&port->tx_timer); + + /* If there's a process with the device open, do a synchronous + * hangup of the TTY. This *may* cause the process to call close + * asynchronously, but it's not guaranteed. + */ + if (port->tty) + tty_vhangup(port->tty); + + /* Get exclusive reference to VCC, ensures that there are no other + * clients to this port + */ + port = vcc_get(port->index, true); + + if (WARN_ON(!port)) + return -ENODEV; + + tty_unregister_device(vcc_tty_driver, port->index); + + del_timer_sync(&port->vio.timer); + vio_ldc_free(&port->vio); + sysfs_remove_group(&vdev->dev.kobj, &vcc_attribute_group); + dev_set_drvdata(&vdev->dev, NULL); + if (port->tty) { + port->removed = true; + vcc_put(port, true); + } else { + vcc_table_remove(port->index); + + kfree(port->vio.name); + kfree(port->domain); + kfree(port); + } + + return 0; +} + +static const struct vio_device_id vcc_match[] = { + { + .type = "vcc-port", + }, + {}, +}; +MODULE_DEVICE_TABLE(vio, vcc_match); + +static struct vio_driver vcc_driver = { + .id_table = vcc_match, + .probe = vcc_probe, + .remove = vcc_remove, + .name = "vcc", +}; + +static int vcc_open(struct tty_struct *tty, struct file *vcc_file) +{ + struct vcc_port *port; + + if (unlikely(!tty)) { + pr_err("VCC: open: Invalid TTY handle\n"); + return -ENXIO; + } + + if (tty->count > 1) + return -EBUSY; + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: open: Failed to find VCC port\n"); + return -ENODEV; + } + + if (unlikely(!port->vio.lp)) { + pr_err("VCC: open: LDC channel not configured\n"); + vcc_put(port, false); + return -EPIPE; + } + vccdbgl(port->vio.lp); + + vcc_put(port, false); + + if (unlikely(!tty->port)) { + pr_err("VCC: open: TTY port not found\n"); + return -ENXIO; + } + + if (unlikely(!tty->port->ops)) { + pr_err("VCC: open: TTY ops not defined\n"); + return -ENXIO; + } + + return tty_port_open(tty->port, tty, vcc_file); +} + +static void vcc_close(struct tty_struct *tty, struct file *vcc_file) +{ + if (unlikely(!tty)) { + pr_err("VCC: close: Invalid TTY handle\n"); + return; + } + + if (unlikely(tty->count > 1)) + return; + + if (unlikely(!tty->port)) { + pr_err("VCC: close: TTY port not found\n"); + return; + } + + tty_port_close(tty->port, tty, vcc_file); +} + +static void vcc_ldc_hup(struct vcc_port *port) +{ + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + if (vcc_send_ctl(port, VCC_CTL_HUP) < 0) + vcc_kick_tx(port); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void vcc_hangup(struct tty_struct *tty) +{ + struct vcc_port *port; + + if (unlikely(!tty)) { + pr_err("VCC: hangup: Invalid TTY handle\n"); + return; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: hangup: Failed to find VCC port\n"); + return; + } + + if (unlikely(!tty->port)) { + pr_err("VCC: hangup: TTY port not found\n"); + vcc_put(port, false); + return; + } + + vcc_ldc_hup(port); + + vcc_put(port, false); + + tty_port_hangup(tty->port); +} + +static int vcc_write(struct tty_struct *tty, const unsigned char *buf, + int count) +{ + struct vcc_port *port; + struct vio_vcc *pkt; + unsigned long flags; + int total_sent = 0; + int tosend = 0; + int rv = -EINVAL; + + if (unlikely(!tty)) { + pr_err("VCC: write: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: write: Failed to find VCC port"); + return -ENODEV; + } + + spin_lock_irqsave(&port->lock, flags); + + pkt = &port->buffer; + pkt->tag.type = VIO_TYPE_DATA; + + while (count > 0) { + /* Minimum of data to write and space available */ + tosend = min(count, (VCC_BUFF_LEN - port->chars_in_buffer)); + + if (!tosend) + break; + + memcpy(&pkt->data[port->chars_in_buffer], &buf[total_sent], + tosend); + port->chars_in_buffer += tosend; + pkt->tag.stype = tosend; + + vccdbg("TAG [%02x:%02x:%04x:%08x]\n", pkt->tag.type, + pkt->tag.stype, pkt->tag.stype_env, pkt->tag.sid); + vccdbg("DATA [%s]\n", pkt->data); + vccdbgl(port->vio.lp); + + /* Since we know we have enough room in VCC buffer for tosend + * we record that it was sent regardless of whether the + * hypervisor actually took it because we have it buffered. + */ + rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); + vccdbg("VCC: write: ldc_write(%d)=%d\n", + (VIO_TAG_SIZE + tosend), rv); + + total_sent += tosend; + count -= tosend; + if (rv < 0) { + vcc_kick_tx(port); + break; + } + + port->chars_in_buffer = 0; + } + + spin_unlock_irqrestore(&port->lock, flags); + + vcc_put(port, false); + + vccdbg("VCC: write: total=%d rv=%d", total_sent, rv); + + return total_sent ? total_sent : rv; +} + +static int vcc_write_room(struct tty_struct *tty) +{ + struct vcc_port *port; + u64 num; + + if (unlikely(!tty)) { + pr_err("VCC: write_room: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: write_room: Failed to find VCC port\n"); + return -ENODEV; + } + + num = VCC_BUFF_LEN - port->chars_in_buffer; + + vcc_put(port, false); + + return num; +} + +static int vcc_chars_in_buffer(struct tty_struct *tty) +{ + struct vcc_port *port; + u64 num; + + if (unlikely(!tty)) { + pr_err("VCC: chars_in_buffer: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: chars_in_buffer: Failed to find VCC port\n"); + return -ENODEV; + } + + num = port->chars_in_buffer; + + vcc_put(port, false); + + return num; +} + +static int vcc_break_ctl(struct tty_struct *tty, int state) +{ + struct vcc_port *port; + unsigned long flags; + + if (unlikely(!tty)) { + pr_err("VCC: break_ctl: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: break_ctl: Failed to find VCC port\n"); + return -ENODEV; + } + + /* Turn off break */ + if (state == 0) { + vcc_put(port, false); + return 0; + } + + spin_lock_irqsave(&port->lock, flags); + + if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0) + vcc_kick_tx(port); + + spin_unlock_irqrestore(&port->lock, flags); + + vcc_put(port, false); + + return 0; +} + +static int vcc_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct vcc_port *port_vcc; + struct tty_port *port_tty; + int ret; + + if (unlikely(!tty)) { + pr_err("VCC: install: Invalid TTY handle\n"); + return -ENXIO; + } + + if (tty->index >= VCC_MAX_PORTS) + return -EINVAL; + + ret = tty_standard_install(driver, tty); + if (ret) + return ret; + + port_tty = kzalloc(sizeof(struct tty_port), GFP_KERNEL); + if (!port_tty) + return -ENOMEM; + + port_vcc = vcc_get(tty->index, true); + if (!port_vcc) { + pr_err("VCC: install: Failed to find VCC port\n"); + tty->port = NULL; + kfree(port_tty); + return -ENODEV; + } + + tty_port_init(port_tty); + port_tty->ops = &vcc_port_ops; + tty->port = port_tty; + + port_vcc->tty = tty; + + vcc_put(port_vcc, true); + + return 0; +} + +static void vcc_cleanup(struct tty_struct *tty) +{ + struct vcc_port *port; + + if (unlikely(!tty)) { + pr_err("VCC: cleanup: Invalid TTY handle\n"); + return; + } + + port = vcc_get(tty->index, true); + if (port) { + port->tty = NULL; + + if (port->removed) { + vcc_table_remove(tty->index); + kfree(port->vio.name); + kfree(port->domain); + kfree(port); + } else { + vcc_put(port, true); + } + } + + tty_port_destroy(tty->port); + kfree(tty->port); + tty->port = NULL; +} + +static const struct tty_operations vcc_ops = { + .open = vcc_open, + .close = vcc_close, + .hangup = vcc_hangup, + .write = vcc_write, + .write_room = vcc_write_room, + .chars_in_buffer = vcc_chars_in_buffer, + .break_ctl = vcc_break_ctl, + .install = vcc_install, + .cleanup = vcc_cleanup, +}; + +#define VCC_TTY_FLAGS (TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_REAL_RAW) + +static int vcc_tty_init(void) +{ + int rv; + + pr_info("VCC: %s\n", version); + + vcc_tty_driver = tty_alloc_driver(VCC_MAX_PORTS, VCC_TTY_FLAGS); + if (IS_ERR(vcc_tty_driver)) { + pr_err("VCC: TTY driver alloc failed\n"); + return PTR_ERR(vcc_tty_driver); + } + + vcc_tty_driver->driver_name = vcc_driver_name; + vcc_tty_driver->name = vcc_device_node; + + vcc_tty_driver->minor_start = VCC_MINOR_START; + vcc_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; + vcc_tty_driver->init_termios = vcc_tty_termios; + + tty_set_operations(vcc_tty_driver, &vcc_ops); + + rv = tty_register_driver(vcc_tty_driver); + if (rv) { + pr_err("VCC: TTY driver registration failed\n"); + put_tty_driver(vcc_tty_driver); + vcc_tty_driver = NULL; + return rv; + } + + vccdbg("VCC: TTY driver registered\n"); + + return 0; +} + +static void vcc_tty_exit(void) +{ + tty_unregister_driver(vcc_tty_driver); + put_tty_driver(vcc_tty_driver); + vccdbg("VCC: TTY driver unregistered\n"); + + vcc_tty_driver = NULL; +} + +static int __init vcc_init(void) +{ + int rv; + + rv = vcc_tty_init(); + if (rv) { + pr_err("VCC: TTY init failed\n"); + return rv; + } + + rv = vio_register_driver(&vcc_driver); + if (rv) { + pr_err("VCC: VIO driver registration failed\n"); + vcc_tty_exit(); + } else { + vccdbg("VCC: VIO driver registered successfully\n"); + } + + return rv; +} + +static void __exit vcc_exit(void) +{ + vio_unregister_driver(&vcc_driver); + vccdbg("VCC: VIO driver unregistered\n"); + vcc_tty_exit(); + vccdbg("VCC: TTY driver unregistered\n"); +} + +module_init(vcc_init); +module_exit(vcc_exit); diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index d65a64c29b852af9ec47f48fe4d3e0024aa66743..5160a4a966b37dab4f16f0c5b5f35e34c8c95717 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -43,7 +43,6 @@ #include "usbatm.h" #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" -#define DRIVER_VERSION "0.4" #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" static const char cxacru_driver_name[] = "cxacru"; @@ -1380,4 +1379,3 @@ module_usb_driver(cxacru_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 5083eb5b0d5ed9f7d7dc90ee5309c4ae5e6d437a..3676adb40d89074e0cc3124859928ac43581ad20 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -40,8 +40,7 @@ #include "usbatm.h" #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.10" -#define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION +#define DRIVER_DESC "Alcatel SpeedTouch USB driver" static const char speedtch_driver_name[] = "speedtch"; @@ -738,7 +737,7 @@ static int speedtch_post_reset(struct usb_interface *intf) ** USB ** **********/ -static struct usb_device_id speedtch_usb_ids[] = { +static const struct usb_device_id speedtch_usb_ids[] = { {USB_DEVICE(0x06b9, 0x4061)}, {} }; @@ -962,4 +961,3 @@ module_usb_driver(speedtch_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index df67815f74e68020076c8b59bcecc8ba0bf3782d..ba7616395db26249ca6cf462fca24108abb4427c 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2212,7 +2212,7 @@ static int uea_boot(struct uea_softc *sc) ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); if (ret < 0) { uea_err(INS_TO_USBDEV(sc), - "urb submition failed with error %d\n", ret); + "urb submission failed with error %d\n", ret); goto err1; } @@ -2522,7 +2522,7 @@ static struct attribute *attrs[] = { &dev_attr_stat_firmid.attr, NULL, }; -static struct attribute_group attr_grp = { +static const struct attribute_group attr_grp = { .attrs = attrs, }; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 3e80aa3b917aa9017ffbc4f78f8601170582707f..8607af758bbd8c52b7841f52f383bd13e66aff87 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -93,8 +93,7 @@ static int usbatm_print_packet(struct usbatm_data *instance, const unsigned char #endif #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.10" -#define DRIVER_DESC "Generic USB ATM/DSL I/O, version " DRIVER_VERSION +#define DRIVER_DESC "Generic USB ATM/DSL I/O" static const char usbatm_driver_name[] = "usbatm"; @@ -174,7 +173,7 @@ static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __us static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb); static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t *pos, char *page); -static struct atmdev_ops usbatm_atm_devops = { +static const struct atmdev_ops usbatm_atm_devops = { .dev_close = usbatm_atm_dev_close, .open = usbatm_atm_open, .close = usbatm_atm_close, @@ -1315,7 +1314,6 @@ module_exit(usbatm_usb_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); /************ ** debug ** diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index a87597f88a8447a6dbcf5d2cba70fe076bc710e0..c73c1ec3005e50d630451a2215bfeb737e309213 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -228,4 +228,3 @@ module_exit(xusbatm_exit); MODULE_AUTHOR("Roman Kagan, Duncan Sands"); MODULE_DESCRIPTION("Driver for USB ADSL modems initialized in userspace"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c index c2d13968da821f60277b29f612b4a15b42daf8b7..30d3f346686e45d085ac991421fe8f87ba483196 100644 --- a/drivers/usb/c67x00/c67x00-hcd.c +++ b/drivers/usb/c67x00/c67x00-hcd.c @@ -305,7 +305,7 @@ static int c67x00_hcd_get_frame(struct usb_hcd *hcd) return temp_val ? (temp_val - 1) : HOST_FRAME_MASK; } -static struct hc_driver c67x00_hc_driver = { +static const struct hc_driver c67x00_hc_driver = { .description = "c67x00-hcd", .product_desc = "Cypress C67X00 Host Controller", .hcd_priv_size = sizeof(struct c67x00_hcd), diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 39fca5715ed335a3ddb59019187be45bd2805144..ddcbddf8361ad1c015d961ece04bd6431eb64129 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o obj-$(CONFIG_USB_CHIPIDEA_PCI) += ci_hdrc_pci.o obj-$(CONFIG_USB_CHIPIDEA_OF) += usbmisc_imx.o ci_hdrc_imx.o +obj-$(CONFIG_USB_CHIPIDEA_OF) += ci_hdrc_tegra.o diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 0bdfcdcbf7a5a4265ecb2be8570015c0e9d08e38..bb626120296ff23dfd60cc59428d3fb4d4c92fe9 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -251,7 +251,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (ret) goto err_mux; - ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi"); + ulpi_node = of_find_node_by_name(of_node_get(pdev->dev.of_node), "ulpi"); if (ulpi_node) { phy_node = of_get_next_available_child(ulpi_node, NULL); ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c index b635ab67490de3a93a9c0df0f17848376ae1d947..39414e4b2d814f4415abdebb7cde4fe59b72b3ba 100644 --- a/drivers/usb/chipidea/ci_hdrc_pci.c +++ b/drivers/usb/chipidea/ci_hdrc_pci.c @@ -170,5 +170,4 @@ module_pci_driver(ci_hdrc_pci_driver); MODULE_AUTHOR("MIPS - David Lopo "); MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller"); MODULE_LICENSE("GPL"); -MODULE_VERSION("June 2008"); MODULE_ALIAS("platform:ci13xxx_pci"); diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c new file mode 100644 index 0000000000000000000000000000000000000000..bfcee2702d50360b04e698d97a083bb55a6b9346 --- /dev/null +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016, NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include + +#include "ci.h" + +struct tegra_udc { + struct ci_hdrc_platform_data data; + struct platform_device *dev; + + struct usb_phy *phy; + struct clk *clk; +}; + +struct tegra_udc_soc_info { + unsigned long flags; +}; + +static const struct tegra_udc_soc_info tegra20_udc_soc_info = { + .flags = CI_HDRC_REQUIRES_ALIGNED_DMA, +}; + +static const struct tegra_udc_soc_info tegra30_udc_soc_info = { + .flags = 0, +}; + +static const struct tegra_udc_soc_info tegra114_udc_soc_info = { + .flags = 0, +}; + +static const struct tegra_udc_soc_info tegra124_udc_soc_info = { + .flags = 0, +}; + +static const struct of_device_id tegra_udc_of_match[] = { + { + .compatible = "nvidia,tegra20-udc", + .data = &tegra20_udc_soc_info, + }, { + .compatible = "nvidia,tegra30-udc", + .data = &tegra30_udc_soc_info, + }, { + .compatible = "nvidia,tegra114-udc", + .data = &tegra114_udc_soc_info, + }, { + .compatible = "nvidia,tegra124-udc", + .data = &tegra124_udc_soc_info, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, tegra_udc_of_match); + +static int tegra_udc_probe(struct platform_device *pdev) +{ + const struct tegra_udc_soc_info *soc; + struct tegra_udc *udc; + int err; + + udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); + if (!udc) + return -ENOMEM; + + soc = of_device_get_match_data(&pdev->dev); + if (!soc) { + dev_err(&pdev->dev, "failed to match OF data\n"); + return -EINVAL; + } + + udc->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); + if (IS_ERR(udc->phy)) { + err = PTR_ERR(udc->phy); + dev_err(&pdev->dev, "failed to get PHY: %d\n", err); + return err; + } + + udc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(udc->clk)) { + err = PTR_ERR(udc->clk); + dev_err(&pdev->dev, "failed to get clock: %d\n", err); + return err; + } + + err = clk_prepare_enable(udc->clk); + if (err < 0) { + dev_err(&pdev->dev, "failed to enable clock: %d\n", err); + return err; + } + + /* + * Tegra's USB PHY driver doesn't implement optional phy_init() + * hook, so we have to power on UDC controller before ChipIdea + * driver initialization kicks in. + */ + usb_phy_set_suspend(udc->phy, 0); + + /* setup and register ChipIdea HDRC device */ + udc->data.name = "tegra-udc"; + udc->data.flags = soc->flags; + udc->data.usb_phy = udc->phy; + udc->data.capoffset = DEF_CAPOFFSET; + + udc->dev = ci_hdrc_add_device(&pdev->dev, pdev->resource, + pdev->num_resources, &udc->data); + if (IS_ERR(udc->dev)) { + err = PTR_ERR(udc->dev); + dev_err(&pdev->dev, "failed to add HDRC device: %d\n", err); + goto fail_power_off; + } + + platform_set_drvdata(pdev, udc); + + return 0; + +fail_power_off: + usb_phy_set_suspend(udc->phy, 1); + clk_disable_unprepare(udc->clk); + return err; +} + +static int tegra_udc_remove(struct platform_device *pdev) +{ + struct tegra_udc *udc = platform_get_drvdata(pdev); + + usb_phy_set_suspend(udc->phy, 1); + clk_disable_unprepare(udc->clk); + + return 0; +} + +static struct platform_driver tegra_udc_driver = { + .driver = { + .name = "tegra-udc", + .of_match_table = tegra_udc_of_match, + }, + .probe = tegra_udc_probe, + .remove = tegra_udc_remove, +}; +module_platform_driver(tegra_udc_driver); + +MODULE_DESCRIPTION("NVIDIA Tegra USB device mode driver"); +MODULE_AUTHOR("Thierry Reding "); +MODULE_ALIAS("platform:tegra-udc"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index d162cc0bb8ceae29edfa1498ef766a8cafaae775..99425db9ba62b20beda2c08c0cd2e49639c87e52 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -52,6 +52,8 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev) if (!ci_pdata) { ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL); + if (!ci_pdata) + return -ENOMEM; *ci_pdata = ci_default_pdata; /* struct copy */ } diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index b17ed3a9a3045ff9d9c88aacca3d8b1ffc98a06e..43ea5fb87b9a8e9493ae38d5a0352f5920fc5d8f 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -736,7 +736,7 @@ static int ci_extcon_register(struct ci_hdrc *ci) id = &ci->platdata->id_extcon; id->ci = ci; - if (!IS_ERR(id->edev)) { + if (!IS_ERR_OR_NULL(id->edev)) { ret = devm_extcon_register_notifier(ci->dev, id->edev, EXTCON_USB_HOST, &id->nb); if (ret < 0) { @@ -747,7 +747,7 @@ static int ci_extcon_register(struct ci_hdrc *ci) vbus = &ci->platdata->vbus_extcon; vbus->ci = ci; - if (!IS_ERR(vbus->edev)) { + if (!IS_ERR_OR_NULL(vbus->edev)) { ret = devm_extcon_register_notifier(ci->dev, vbus->edev, EXTCON_USB, &vbus->nb); if (ret < 0) { @@ -887,7 +887,7 @@ static struct attribute *ci_attrs[] = { NULL, }; -static struct attribute_group ci_attr_group = { +static const struct attribute_group ci_attr_group = { .attrs = ci_attrs, }; diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 949183ede16fb15f7e32f812a81696da8a2f05f1..5ea0246f650d7044f941399c672f006c8806a3aa 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -193,7 +193,7 @@ static struct attribute *inputs_attrs[] = { NULL, }; -static struct attribute_group inputs_attr_group = { +static const struct attribute_group inputs_attr_group = { .name = "inputs", .attrs = inputs_attrs, }; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index d68b125796f987d7133fef50fc8486363a5ef305..fe8a90543ea375b4931ef3b6fa02cdd8a3574aae 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -944,7 +944,6 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) */ static int isr_setup_status_phase(struct ci_hdrc *ci) { - int retval; struct ci_hw_ep *hwep; /* @@ -960,9 +959,7 @@ static int isr_setup_status_phase(struct ci_hdrc *ci) ci->status->context = ci; ci->status->complete = isr_setup_status_complete; - retval = _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC); - - return retval; + return _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC); } /** @@ -1899,6 +1896,9 @@ static int udc_start(struct ci_hdrc *ci) ci->gadget.name = ci->platdata->name; ci->gadget.otg_caps = otg_caps; + if (ci->platdata->flags & CI_HDRC_REQUIRES_ALIGNED_DMA) + ci->gadget.quirk_avoids_skb_reserve = 1; + if (ci->is_otg && (otg_caps->hnp_support || otg_caps->srp_support || otg_caps->adp_support)) ci->gadget.is_otg = 1; diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8f972247b1c1ac4d41faebe390a4c9ac9a308960..3e865dbf878c74b2e904925798cd603e5cd0e979 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -26,10 +26,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v0.03" #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" @@ -194,8 +190,10 @@ static void wdm_in_callback(struct urb *urb) /* * only set a new error if there is no previous error. * Errors are only cleared during read/open + * Avoid propagating -EPIPE (stall) to userspace since it is + * better handled as an empty read */ - if (desc->rerr == 0) + if (desc->rerr == 0 && status != -EPIPE) desc->rerr = status; if (length + desc->length > desc->wMaxCommand) { diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 578f424decc22b9f340732f6f381fc0d23135e72..6ebfabfa0dc7a69f0c9afdb96948e0cb269045e0 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -1085,7 +1085,7 @@ static struct attribute *capability_attrs[] = { NULL, }; -static struct attribute_group capability_attr_grp = { +static const struct attribute_group capability_attr_grp = { .attrs = capability_attrs, }; @@ -1151,7 +1151,7 @@ static struct attribute *data_attrs[] = { NULL, }; -static struct attribute_group data_attr_grp = { +static const struct attribute_group data_attr_grp = { .attrs = data_attrs, }; diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index 5ef8da6e67c3fbc1ab82f8e7e24550ff4ef05ca1..552ff7ac5a6b7a13820e3ba81d3667e81f43c2b2 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -190,10 +190,7 @@ EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy); */ bool of_usb_host_tpl_support(struct device_node *np) { - if (of_find_property(np, "tpl-support", NULL)) - return true; - - return false; + return of_property_read_bool(np, "tpl-support"); } EXPORT_SYMBOL_GPL(of_usb_host_tpl_support); @@ -227,8 +224,8 @@ int of_usb_update_otg_caps(struct device_node *np, otg_caps->otg_rev = otg_rev; break; default: - pr_err("%s: unsupported otg-rev: 0x%x\n", - np->full_name, otg_rev); + pr_err("%pOF: unsupported otg-rev: 0x%x\n", + np, otg_rev); return -EINVAL; } } else { @@ -240,11 +237,11 @@ int of_usb_update_otg_caps(struct device_node *np, otg_caps->otg_rev = 0; } - if (of_find_property(np, "hnp-disable", NULL)) + if (of_property_read_bool(np, "hnp-disable")) otg_caps->hnp_support = false; - if (of_find_property(np, "srp-disable", NULL)) + if (of_property_read_bool(np, "srp-disable")) otg_caps->srp_support = false; - if (of_find_property(np, "adp-disable", NULL) || + if (of_property_read_bool(np, "adp-disable") || (otg_caps->otg_rev < 0x0200)) otg_caps->adp_support = false; diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 930e8f35f8df39255be60e2e8267f3acff72b2f9..4aa5195db8ea53172f4cc5ad04ea375cd1e4a91d 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -135,7 +135,7 @@ static void ulpi_dev_release(struct device *dev) kfree(to_ulpi_dev(dev)); } -static struct device_type ulpi_dev_type = { +static const struct device_type ulpi_dev_type = { .name = "ulpi_device", .groups = ulpi_dev_attr_groups, .release = ulpi_dev_release, diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 4be52c602e9b7a7de6a76ecb4be686cb12ec9950..68b54bd88d1eb009eddac3132402717a9c25f580 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -643,15 +643,23 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, } else if (header->bDescriptorType == USB_DT_INTERFACE_ASSOCIATION) { + struct usb_interface_assoc_descriptor *d; + + d = (struct usb_interface_assoc_descriptor *)header; + if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { + dev_warn(ddev, + "config %d has an invalid interface association descriptor of length %d, skipping\n", + cfgno, d->bLength); + continue; + } + if (iad_num == USB_MAXIADS) { dev_warn(ddev, "found more Interface " "Association Descriptors " "than allocated for in " "configuration %d\n", cfgno); } else { - config->intf_assoc[iad_num] = - (struct usb_interface_assoc_descriptor - *)header; + config->intf_assoc[iad_num] = d; iad_num++; } @@ -852,7 +860,7 @@ int usb_get_configuration(struct usb_device *dev) } if (dev->quirks & USB_QUIRK_DELAY_INIT) - msleep(100); + msleep(200); result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ebe27595c4afbc343285cdcfca0070720c5512be..4664e543cf2f88aa412615ffa5156148c67be23d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -140,6 +140,9 @@ module_param(usbfs_memory_mb, uint, 0644); MODULE_PARM_DESC(usbfs_memory_mb, "maximum MB allowed for usbfs buffers (0 = no limit)"); +/* Hard limit, necessary to avoid arithmetic overflow */ +#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000) + static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */ /* Check whether it's okay to allocate more memory for a transfer */ @@ -210,7 +213,7 @@ static void usbdev_vm_close(struct vm_area_struct *vma) dec_usb_memory_use_count(usbm, &usbm->vma_use_count); } -static struct vm_operations_struct usbdev_vm_ops = { +static const struct vm_operations_struct usbdev_vm_ops = { .open = usbdev_vm_open, .close = usbdev_vm_close }; @@ -623,6 +626,8 @@ static void async_completed(struct urb *urb) if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && as->status != -ENOENT) cancel_bulk_urbs(ps, as->bulk_addr); + + wake_up(&ps->wait); spin_unlock(&ps->lock); if (signr) { @@ -630,8 +635,6 @@ static void async_completed(struct urb *urb) put_pid(pid); put_cred(cred); } - - wake_up(&ps->wait); } static void destroy_async(struct usb_dev_state *ps, struct list_head *list) @@ -1460,6 +1463,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb USBDEVFS_URB_ZERO_PACKET | USBDEVFS_URB_NO_INTERRUPT)) return -EINVAL; + if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX) + return -EINVAL; if (uurb->buffer_length > 0 && !uurb->buffer) return -EINVAL; if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && @@ -1571,7 +1576,11 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb totlen += isopkt[u].length; } u *= sizeof(struct usb_iso_packet_descriptor); - uurb->buffer_length = totlen; + if (totlen <= uurb->buffer_length) + uurb->buffer_length = totlen; + else + WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d", + totlen, uurb->buffer_length); break; default: diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ab1bb3b538ac6175dd1fbe5babb686a6a8f4bc49..75ad6718858cad9d0c00023c4a273dd701a1d3a6 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -972,7 +972,7 @@ static struct attribute *usb_bus_attrs[] = { NULL, }; -static struct attribute_group usb_bus_attr_group = { +static const struct attribute_group usb_bus_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = usb_bus_attrs, }; @@ -1888,7 +1888,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev, /* No more submits can occur */ spin_lock_irq(&hcd_urb_list_lock); rescan: - list_for_each_entry (urb, &ep->urb_list, urb_list) { + list_for_each_entry_reverse(urb, &ep->urb_list, urb_list) { int is_in; if (urb->unlinked) @@ -2485,6 +2485,8 @@ void usb_hc_died (struct usb_hcd *hcd) } if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) { hcd = hcd->shared_hcd; + clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + set_bit(HCD_FLAG_DEAD, &hcd->flags); if (hcd->rh_registered) { clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6e6797d145dd80136c413129641bdbbae2f1e63b..b5c73361382325127e5412c8b04c748749849954 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2614,7 +2614,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define SET_CONFIG_TRIES (2 * (use_both_schemes + 1)) #define USE_NEW_SCHEME(i) ((i) / 2 == (int)old_scheme_first) -#define HUB_ROOT_RESET_TIME 50 /* times are in msec */ +#define HUB_ROOT_RESET_TIME 60 /* times are in msec */ #define HUB_SHORT_RESET_TIME 10 #define HUB_BH_RESET_TIME 50 #define HUB_LONG_RESET_TIME 200 @@ -4342,6 +4342,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, enum usb_device_speed oldspeed = udev->speed; const char *speed; int devnum = udev->devnum; + const char *driver_name; /* root hub ports have a slightly longer reset period * (from USB 2.0 spec, section 7.1.7.5) @@ -4409,11 +4410,23 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, else speed = usb_speed_string(udev->speed); + /* + * The controller driver may be NULL if the controller device + * is the middle device between platform device and roothub. + * This middle device may not need a device driver due to + * all hardware control can be at platform device driver, this + * platform device is usually a dual-role USB controller device. + */ + if (udev->bus->controller->driver) + driver_name = udev->bus->controller->driver->name; + else + driver_name = udev->bus->sysdev->driver->name; + if (udev->speed < USB_SPEED_SUPER) dev_info(&udev->dev, "%s %s USB device number %d using %s\n", (udev->config) ? "reset" : "new", speed, - devnum, udev->bus->controller->driver->name); + devnum, driver_name); /* Set up TT records, if needed */ if (hdev->tt) { @@ -4545,7 +4558,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, "%s SuperSpeed%s USB device number %d using %s\n", (udev->config) ? "reset" : "new", (udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "", - devnum, udev->bus->controller->driver->name); + devnum, driver_name); } /* cope with hardware quirkiness: @@ -4725,7 +4738,8 @@ hub_power_remaining(struct usb_hub *hub) static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, u16 portchange) { - int status, i; + int status = -ENODEV; + int i; unsigned unit_load; struct usb_device *hdev = hub->hdev; struct usb_hcd *hcd = bus_to_hcd(hdev->bus); @@ -4824,7 +4838,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, goto loop; if (udev->quirks & USB_QUIRK_DELAY_INIT) - msleep(1000); + msleep(2000); /* consecutive bus-powered hubs aren't reliable; they can * violate the voltage drop budget. if the new child has @@ -4929,9 +4943,10 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, done: hub_port_disable(hub, port1, 1); - if (hcd->driver->relinquish_port && !hub->hdev->parent) - hcd->driver->relinquish_port(hcd, port1); - + if (hcd->driver->relinquish_port && !hub->hdev->parent) { + if (status != -ENOTCONN && status != -ENODEV) + hcd->driver->relinquish_port(hcd, port1); + } } /* Handle physical or logical connection change events. diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index 16c19a31dad1fa529f0f1fc918b153aa4cf6b64b..1af8779421100bf17d87d54a7cd4b23664362092 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c @@ -149,8 +149,8 @@ static bool usbport_trig_port_observed(struct usbport_trig_data *usbport_data, count = of_count_phandle_with_args(led_np, "trigger-sources", "#trigger-source-cells"); if (count < 0) { - dev_warn(dev, "Failed to get trigger sources for %s\n", - led_np->full_name); + dev_warn(dev, "Failed to get trigger sources for %pOF\n", + led_np); return false; } @@ -205,6 +205,7 @@ static int usbport_trig_add_port(struct usbport_trig_data *usbport_data, } snprintf(port->port_name, len, "%s-port%d", hub_name, portnum); + sysfs_attr_init(&port->attr.attr); port->attr.attr.name = port->port_name; port->attr.attr.mode = S_IRUSR | S_IWUSR; port->attr.show = usbport_trig_port_show; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 4c38ea41ae969e6fac8ced209a655957322ba36f..371a07d874a370bc70ad6ef1499debac8b34b6fe 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -2069,6 +2069,10 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, elength = 1; goto next_desc; } + if ((buflen < elength) || (elength < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + break; + } if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 3116edfcdc18558aa768d248f1ff1881448ced09..82806e3112028f335a90ec34c0283a02c3f87e9b 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -57,8 +57,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Microsoft LifeCam-VX700 v2.0 */ { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech HD Pro Webcams C920 and C930e */ + /* Logitech HD Pro Webcams C920, C920-C and C930e */ { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, + { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, /* Logitech ConferenceCam CC3000e */ @@ -150,6 +151,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* appletouch */ { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */ + { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM }, + /* Avision AV600U */ { USB_DEVICE(0x0638, 0x0a13), .driver_info = USB_QUIRK_STRING_FETCH_255 }, @@ -214,6 +218,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x1a0a, 0x0200), .driver_info = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + /* Corsair Strafe RGB */ + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Acer C120 LED Projector */ { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM }, @@ -249,6 +256,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = { { USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME }, /* Logitech Optical Mouse M90/M100 */ { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index dfc68ed24db19bbba53f825bbe650894748d5551..d930bfda40101457dad980ec432c0b73d7193981 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -113,7 +113,7 @@ static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, { struct device_node *of_node = dev->of_node; - return sprintf(buf, "%s\n", of_node_full_name(of_node)); + return sprintf(buf, "%pOF\n", of_node); } static DEVICE_ATTR_RO(devspec); #endif diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index c4066cd77e47345bc1f31791ba9955c80a12d452..0d8e09ccb59c09e92b807ffdaf2fbf14f80fe018 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -4179,7 +4179,7 @@ static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) return ret; } -static struct usb_ep_ops dwc2_hsotg_ep_ops = { +static const struct usb_ep_ops dwc2_hsotg_ep_ops = { .enable = dwc2_hsotg_ep_enable, .disable = dwc2_hsotg_ep_disable, .alloc_request = dwc2_hsotg_ep_alloc_request, diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 740c7e86d31b912bf0f3c861a687b369acdc5b3d..c2631145f404943fc148b747c4620e0a5165153d 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4388,6 +4388,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); + if (dwc2_is_device_mode(hsotg)) + goto unlock; + if (hsotg->lx_state != DWC2_L0) goto unlock; @@ -4446,6 +4449,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); + if (dwc2_is_device_mode(hsotg)) + goto unlock; + if (hsotg->lx_state != DWC2_L2) goto unlock; diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 12ee23f53cdde17ea924344ff7e84d88cf9881cb..d2ed9523e77c8b26c336741d04e685cd28008d5b 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include /* USBSS register offsets */ #define USBSS_REVISION 0x0000 @@ -41,7 +41,6 @@ struct dwc3_keystone { struct device *dev; - struct clk *clk; void __iomem *usbss; }; @@ -106,17 +105,13 @@ static int kdwc3_probe(struct platform_device *pdev) if (IS_ERR(kdwc->usbss)) return PTR_ERR(kdwc->usbss); - kdwc->clk = devm_clk_get(kdwc->dev, "usb"); - if (IS_ERR(kdwc->clk)) { - dev_err(kdwc->dev, "unable to get usb clock\n"); - return PTR_ERR(kdwc->clk); - } + pm_runtime_enable(kdwc->dev); - error = clk_prepare_enable(kdwc->clk); + error = pm_runtime_get_sync(kdwc->dev); if (error < 0) { - dev_err(kdwc->dev, "unable to enable usb clock, error %d\n", + dev_err(kdwc->dev, "pm_runtime_get_sync failed, error %d\n", error); - return error; + goto err_irq; } irq = platform_get_irq(pdev, 0); @@ -147,7 +142,8 @@ static int kdwc3_probe(struct platform_device *pdev) err_core: kdwc3_disable_irqs(kdwc); err_irq: - clk_disable_unprepare(kdwc->clk); + pm_runtime_put_sync(kdwc->dev); + pm_runtime_disable(kdwc->dev); return error; } @@ -167,7 +163,9 @@ static int kdwc3_remove(struct platform_device *pdev) kdwc3_disable_irqs(kdwc); device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core); - clk_disable_unprepare(kdwc->clk); + pm_runtime_put_sync(kdwc->dev); + pm_runtime_disable(kdwc->dev); + platform_set_drvdata(pdev, NULL); return 0; diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index fe414e7a9c78cda7405db573f321da91d0d4eb5b..a26d1fde0f5e4b6f3613387da40aaca00f937477 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -96,7 +95,8 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) platform_set_drvdata(pdev, simple); simple->dev = dev; - ret = dwc3_of_simple_clk_init(simple, of_clk_get_parent_count(np)); + ret = dwc3_of_simple_clk_init(simple, of_count_phandle_with_args(np, + "clocks", "#clock-cells")); if (ret) return ret; @@ -177,6 +177,7 @@ static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, + { .compatible = "sprd,sc9860-dwc3" }, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index f5aaa0cf38734ccdfea16cfd29dbf2e8e1599cf1..3530795bbb8f0d7d934cc848d595433f7bd923ad 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -478,8 +478,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(dev, "missing IRQ resource\n"); - return -EINVAL; + dev_err(dev, "missing IRQ resource: %d\n", irq); + return irq; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7e995df7a797b4353ba18e17ed701c3bc2096c4e..54343fbd85eef112f38283ee0376f911a2bc2cb8 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -345,7 +345,7 @@ static int dwc3_pci_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -static struct dev_pm_ops dwc3_pci_dev_pm_ops = { +static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume, NULL) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 827e376bfa97106f1ccbeefcad40bc2a05357c8b..75e6cb044eb2b96d173a2c716bb29f5f4fd7f703 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -990,6 +990,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA, true); + req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; + /* Now prepare one extra TRB to align transfer size */ dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, maxpacket - rem, @@ -1015,6 +1017,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA, true); + req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; + /* Now prepare one extra TRB to align transfer size */ dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, 0, DWC3_TRBCTL_CONTROL_DATA, @@ -1029,6 +1033,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, dwc3_ep0_prepare_one_trb(dep, req->request.dma, req->request.length, DWC3_TRBCTL_CONTROL_DATA, false); + + req->trb = &dwc->ep0_trb[dep->trb_enqueue]; + ret = dwc3_ep0_start_trans(dep); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 6b299c7b765611e0cb6c0d30e5de50f8ef279cb7..f064f1549333dcd7dab10fd491e43cf31bac887e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -896,9 +896,40 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, if (!node) { trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; + /* + * USB Specification 2.0 Section 5.9.2 states that: "If + * there is only a single transaction in the microframe, + * only a DATA0 data packet PID is used. If there are + * two transactions per microframe, DATA1 is used for + * the first transaction data packet and DATA0 is used + * for the second transaction data packet. If there are + * three transactions per microframe, DATA2 is used for + * the first transaction data packet, DATA1 is used for + * the second, and DATA0 is used for the third." + * + * IOW, we should satisfy the following cases: + * + * 1) length <= maxpacket + * - DATA0 + * + * 2) maxpacket < length <= (2 * maxpacket) + * - DATA1, DATA0 + * + * 3) (2 * maxpacket) < length <= (3 * maxpacket) + * - DATA2, DATA1, DATA0 + */ if (speed == USB_SPEED_HIGH) { struct usb_ep *ep = &dep->endpoint; - trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1); + unsigned int mult = ep->mult - 1; + unsigned int maxp = usb_endpoint_maxp(ep->desc); + + if (length <= (2 * maxp)) + mult--; + + if (length <= maxp) + mult--; + + trb->size |= DWC3_TRB_SIZE_PCM1(mult); } } else { trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 35cc641d9f31bc46fcb91eaa42bc1ca3195b9e0b..31cce7805eb2e93706468409a39f287fdebd5f5a 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -130,7 +130,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS config U_SERIAL_CONSOLE bool "Serial gadget console support" - depends on USB_G_SERIAL + depends on USB_U_SERIAL help It supports the serial gadget can be used as a console. diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d21874b35cf6eba0021ef3f66d97a9b226907f6f..8b342587f8ad6eb3d79d25d602b741592ec911ab 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -46,7 +46,8 @@ static void ffs_data_get(struct ffs_data *ffs); static void ffs_data_put(struct ffs_data *ffs); /* Creates new ffs_data object. */ -static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); +static struct ffs_data *__must_check ffs_data_new(const char *dev_name) + __attribute__((malloc)); /* Opened counter handling. */ static void ffs_data_opened(struct ffs_data *ffs); @@ -780,11 +781,12 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, struct usb_request *req) { struct ffs_io_data *io_data = req->context; + struct ffs_data *ffs = io_data->ffs; ENTER(); INIT_WORK(&io_data->work, ffs_user_copy_worker); - schedule_work(&io_data->work); + queue_work(ffs->io_completion_wq, &io_data->work); } static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile) @@ -961,10 +963,9 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) /* In the meantime, endpoint got disabled or changed. */ ret = -ESHUTDOWN; } else if (halt) { - /* Halt */ - if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep)) - usb_ep_set_halt(ep->ep); - ret = -EBADMSG; + ret = usb_ep_set_halt(ep->ep); + if (!ret) + ret = -EBADMSG; } else if (unlikely(data_len == -EINVAL)) { /* * Sanity Check: even though data_len can't be used @@ -1501,7 +1502,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, if (unlikely(ret < 0)) return ERR_PTR(ret); - ffs = ffs_data_new(); + ffs = ffs_data_new(dev_name); if (unlikely(!ffs)) return ERR_PTR(-ENOMEM); ffs->file_perms = data.perms; @@ -1611,6 +1612,7 @@ static void ffs_data_put(struct ffs_data *ffs) BUG_ON(waitqueue_active(&ffs->ev.waitq) || waitqueue_active(&ffs->ep0req_completion.wait) || waitqueue_active(&ffs->wait)); + destroy_workqueue(ffs->io_completion_wq); kfree(ffs->dev_name); kfree(ffs); } @@ -1643,7 +1645,7 @@ static void ffs_data_closed(struct ffs_data *ffs) ffs_data_put(ffs); } -static struct ffs_data *ffs_data_new(void) +static struct ffs_data *ffs_data_new(const char *dev_name) { struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); if (unlikely(!ffs)) @@ -1651,6 +1653,12 @@ static struct ffs_data *ffs_data_new(void) ENTER(); + ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name); + if (!ffs->io_completion_wq) { + kfree(ffs); + return NULL; + } + refcount_set(&ffs->ref, 1); atomic_set(&ffs->opened, 0); ffs->state = FFS_READ_DESCRIPTORS; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 5eea44823ca06d06955eb2bc51782cac6cd345ec..d8e359ef6eb1d525e96c027868ce55ac6aa0f1e0 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -44,6 +44,7 @@ struct f_hidg { /* configuration */ unsigned char bInterfaceSubClass; unsigned char bInterfaceProtocol; + unsigned char protocol; unsigned short report_desc_length; char *report_desc; unsigned short report_length; @@ -527,7 +528,9 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_GET_PROTOCOL): VDBG(cdev, "get_protocol\n"); - goto stall; + length = min_t(unsigned int, length, 1); + ((u8 *) req->buf)[0] = hidg->protocol; + goto respond; break; case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 @@ -539,6 +542,17 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_SET_PROTOCOL): VDBG(cdev, "set_protocol\n"); + if (value > HID_REPORT_PROTOCOL) + goto stall; + length = 0; + /* + * We assume that programs implementing the Boot protocol + * are also compatible with the Report Protocol + */ + if (hidg->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) { + hidg->protocol = value; + goto respond; + } goto stall; break; @@ -768,6 +782,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) /* set descriptor dynamic values */ hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; + hidg->protocol = HID_REPORT_PROTOCOL; hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_ss_in_comp_desc.wBytesPerInterval = cpu_to_le16(hidg->report_length); diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index f95bddd6513f7e88e4d511508afef2b9c84c063b..5153e29870c3917fe4cdefc1e4c920536cdd4bf4 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -307,8 +307,6 @@ struct fsg_common { struct completion thread_notifier; struct task_struct *thread_task; - /* Callback functions. */ - const struct fsg_operations *ops; /* Gadget's private data. */ void *private_data; @@ -686,9 +684,8 @@ static int do_read(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *)bh->buf, - amount, &file_offset_tmp); + nread = kernel_read(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nread); if (signal_pending(current)) @@ -883,8 +880,8 @@ static int do_write(struct fsg_common *common) /* Perform the write */ file_offset_tmp = file_offset; - nwritten = vfs_write(curlun->filp, (char __user *)bh->buf, - amount, &file_offset_tmp); + nwritten = kernel_write(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nwritten); if (signal_pending(current)) @@ -1021,9 +1018,8 @@ static int do_verify(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); + nread = kernel_read(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); @@ -2440,6 +2436,7 @@ static void handle_exception(struct fsg_common *common) static int fsg_main_thread(void *common_) { struct fsg_common *common = common_; + int i; /* * Allow the thread to be killed by a signal, but set the signal mask @@ -2453,13 +2450,6 @@ static int fsg_main_thread(void *common_) /* Allow the thread to be frozen */ set_freezable(); - /* - * Arrange for userspace references to be interpreted as kernel - * pointers. That way we can pass a kernel pointer to a routine - * that expects a __user pointer and it will work okay. - */ - set_fs(get_ds()); - /* The main loop */ while (common->state != FSG_STATE_TERMINATED) { if (exception_in_progress(common) || signal_pending(current)) { @@ -2485,21 +2475,16 @@ static int fsg_main_thread(void *common_) common->thread_task = NULL; spin_unlock_irq(&common->lock); - if (!common->ops || !common->ops->thread_exits - || common->ops->thread_exits(common) < 0) { - int i; + /* Eject media from all LUNs */ - down_write(&common->filesem); - for (i = 0; i < ARRAY_SIZE(common->luns); i++) { - struct fsg_lun *curlun = common->luns[i]; - if (!curlun || !fsg_lun_is_open(curlun)) - continue; + down_write(&common->filesem); + for (i = 0; i < ARRAY_SIZE(common->luns); i++) { + struct fsg_lun *curlun = common->luns[i]; + if (curlun && fsg_lun_is_open(curlun)) fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - up_write(&common->filesem); } + up_write(&common->filesem); /* Let fsg_unbind() know the thread has exited */ complete_and_exit(&common->thread_notifier, 0); @@ -2690,13 +2675,6 @@ void fsg_common_remove_luns(struct fsg_common *common) } EXPORT_SYMBOL_GPL(fsg_common_remove_luns); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops) -{ - common->ops = ops; -} -EXPORT_SYMBOL_GPL(fsg_common_set_ops); - void fsg_common_free_buffers(struct fsg_common *common) { _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index d3902313b8ac44dd2a53ba16b346b0d585c3f2e1..dc05ca0c435969037811c75ac2b0e094cb66c155 100644 --- a/drivers/usb/gadget/function/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h @@ -60,17 +60,6 @@ struct fsg_module_parameters { struct fsg_common; /* FSF callback functions */ -struct fsg_operations { - /* - * Callback function to call when thread exits. If no - * callback is set or it returns value lower then zero MSF - * will force eject all LUNs it operates on (including those - * marked as non-removable or with prevent_medium_removal flag - * set). - */ - int (*thread_exits)(struct fsg_common *common); -}; - struct fsg_lun_opts { struct config_group group; struct fsg_lun *lun; @@ -142,9 +131,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun); void fsg_common_remove_luns(struct fsg_common *common); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops); - int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, unsigned int id, const char *name, const char **name_pfx); diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a5719f271bf0b77e5dfe0cbac1b796ba1fd188b7..5d3d7941d2c2227f5ae9d9f219d34bfd0156665f 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -98,6 +98,7 @@ struct f_midi { DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *); spinlock_t transmit_lock; unsigned int in_last_port; + unsigned char free_ref; struct gmidi_in_port in_ports_array[/* in_ports */]; }; @@ -108,6 +109,7 @@ static inline struct f_midi *func_to_midi(struct usb_function *f) } static void f_midi_transmit(struct f_midi *midi); +static void f_midi_rmidi_free(struct snd_rawmidi *rmidi); DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); @@ -163,6 +165,13 @@ static struct usb_endpoint_descriptor bulk_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; +static struct usb_ss_ep_comp_descriptor bulk_out_ss_comp_desc = { + .bLength = sizeof(bulk_out_ss_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + /* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */ static struct usb_ms_endpoint_descriptor_16 ms_out_desc = { /* .bLength = DYNAMIC */ @@ -180,6 +189,13 @@ static struct usb_endpoint_descriptor bulk_in_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; +static struct usb_ss_ep_comp_descriptor bulk_in_ss_comp_desc = { + .bLength = sizeof(bulk_in_ss_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + /* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */ static struct usb_ms_endpoint_descriptor_16 ms_in_desc = { /* .bLength = DYNAMIC */ @@ -755,13 +771,13 @@ static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up) clear_bit(substream->number, &midi->out_triggered); } -static struct snd_rawmidi_ops gmidi_in_ops = { +static const struct snd_rawmidi_ops gmidi_in_ops = { .open = f_midi_in_open, .close = f_midi_in_close, .trigger = f_midi_in_trigger, }; -static struct snd_rawmidi_ops gmidi_out_ops = { +static const struct snd_rawmidi_ops gmidi_out_ops = { .open = f_midi_out_open, .close = f_midi_out_close, .trigger = f_midi_out_trigger @@ -818,6 +834,8 @@ static int f_midi_register_card(struct f_midi *midi) SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; rmidi->private_data = midi; + rmidi->private_free = f_midi_rmidi_free; + midi->free_ref++; /* * Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT. @@ -853,7 +871,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_midi *midi = func_to_midi(f); struct usb_string *us; - int status, n, jack = 1, i = 0; + int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0; midi->gadget = cdev->gadget; tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi); @@ -895,7 +913,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail; /* allocate temporary function list */ - midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function), + midi_function = kcalloc((MAX_PORTS * 4) + 11, sizeof(*midi_function), GFP_KERNEL); if (!midi_function) { status = -ENOMEM; @@ -985,6 +1003,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) ms_in_desc.bNumEmbMIDIJack = midi->out_ports; /* ... and add them to the list */ + endpoint_descriptor_index = i; midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; midi_function[i++] = (struct usb_descriptor_header *) &ms_out_desc; midi_function[i++] = (struct usb_descriptor_header *) &bulk_in_desc; @@ -1009,13 +1028,34 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail_f_midi; } + if (gadget_is_superspeed(c->cdev->gadget)) { + bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024); + bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024); + i = endpoint_descriptor_index; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_out_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_out_ss_comp_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &ms_out_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_in_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_in_ss_comp_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &ms_in_desc; + f->ss_descriptors = usb_copy_descriptors(midi_function); + if (!f->ss_descriptors) + goto fail_f_midi; + } + kfree(midi_function); return 0; fail_f_midi: kfree(midi_function); - usb_free_descriptors(f->hs_descriptors); + usb_free_all_descriptors(f); fail: f_midi_unregister_card(midi); fail_register: @@ -1197,14 +1237,21 @@ static void f_midi_free(struct usb_function *f) midi = func_to_midi(f); opts = container_of(f->fi, struct f_midi_opts, func_inst); - kfree(midi->id); mutex_lock(&opts->lock); - kfifo_free(&midi->in_req_fifo); - kfree(midi); - --opts->refcnt; + if (!--midi->free_ref) { + kfree(midi->id); + kfifo_free(&midi->in_req_fifo); + kfree(midi); + --opts->refcnt; + } mutex_unlock(&opts->lock); } +static void f_midi_rmidi_free(struct snd_rawmidi *rmidi) +{ + f_midi_free(rmidi->private_data); +} + static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = f->config->cdev; @@ -1219,7 +1266,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) card = midi->card; midi->card = NULL; if (card) - snd_card_free(card); + snd_card_free_when_closed(card); usb_free_all_descriptors(f); } @@ -1263,6 +1310,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->buflen = opts->buflen; midi->qlen = opts->qlen; midi->in_last_port = 0; + midi->free_ref = 1; status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL); if (status) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 24e34cfcb4bd9104b444c47274bf63ca7c868359..45b334ceaf2e399987661652219f6af7032b139c 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -925,8 +925,6 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) */ ncm->port.is_zlp_ok = gadget_is_zlp_supported(cdev->gadget); - ncm->port.no_skb_reserve = - gadget_avoids_skb_reserve(cdev->gadget); ncm->port.cdc_filter = DEFAULT_FILTER; DBG(cdev, "activate ncm\n"); net = gether_connect(&ncm->port); diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8df244fc9d80daa4c7caf0da729bae2ac66137a2..ea0da35a44e2e9f3f2c0e11921568da68b70fafd 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -555,6 +555,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) size_t size; /* Amount of data in a TX request. */ size_t bytes_copied = 0; struct usb_request *req; + int value; DBG(dev, "printer_write trying to send %d bytes\n", (int)len); @@ -634,7 +635,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return -EAGAIN; } - if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); + value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); + if (value) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 16562e46112179b419a353a6508b6629c7d10d7e..e1d5853ef1e429743637ab546b229a02ee49245c 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -691,6 +691,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; } + rndis_iad_descriptor.bFunctionClass = rndis_opts->class; + rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass; + rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol; + /* * in drivers/usb/gadget/configfs.c:configfs_composite_bind() * configurations are bound in sequence with list_for_each_entry, @@ -866,11 +870,23 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis); /* f_rndis_opts_ifname */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); +/* f_rndis_opts_class */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, class); + +/* f_rndis_opts_subclass */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass); + +/* f_rndis_opts_protocol */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol); + static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_dev_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_qmult, &rndis_opts_attr_ifname, + &rndis_opts_attr_class, + &rndis_opts_attr_subclass, + &rndis_opts_attr_protocol, NULL, }; @@ -916,6 +932,10 @@ static struct usb_function_instance *rndis_alloc_inst(void) } INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); + opts->class = rndis_iad_descriptor.bFunctionClass; + opts->subclass = rndis_iad_descriptor.bFunctionSubClass; + opts->protocol = rndis_iad_descriptor.bFunctionProtocol; + descs[0] = &opts->rndis_os_desc; names[0] = "rndis"; config_group_init_type_name(&opts->func_inst.group, "", diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 5dd73b9e5172288b939d5361b5a8ea925a1a86d5..3971bbab88bd7ccf0282cd4a2ade6d636cfa1c8b 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -79,7 +79,7 @@ struct snd_uac_chip { unsigned int p_framesize; }; -static struct snd_pcm_hardware uac_pcm_hardware = { +static const struct snd_pcm_hardware uac_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, @@ -354,7 +354,7 @@ static int uac_pcm_null(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops uac_pcm_ops = { +static const struct snd_pcm_ops uac_pcm_ops = { .open = uac_pcm_open, .close = uac_pcm_null, .ioctl = snd_pcm_lib_ioctl, diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index a8b40d07e927bb78e835b40efeea9bb83fb19bf8..bdbc3fdc7c4ff4f395cecc1688e9fe58762e2fb0 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -1073,7 +1073,7 @@ struct net_device *gether_connect(struct gether *link) if (result == 0) { dev->zlp = link->is_zlp_ok; - dev->no_skb_reserve = link->no_skb_reserve; + dev->no_skb_reserve = gadget_avoids_skb_reserve(dev->gadget); DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult)); dev->header_len = link->header_len; diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 81d94a7ae4b4da5d04e17a0ea8e98080c4a62da9..c77145bd6b5b94f65b8531f2ab061c2770edbae5 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h @@ -64,7 +64,6 @@ struct gether { struct usb_ep *out_ep; bool is_zlp_ok; - bool no_skb_reserve; u16 cdc_filter; diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index c71133de17e71a950f532a7ab599a1c25abad705..e4c3f84af4c37d86fb0ca0905011dabbad751775 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -153,4 +153,39 @@ out: \ \ CONFIGFS_ATTR_RO(_f_##_opts_, ifname) +#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ + static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ + char *page) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret; \ + \ + mutex_lock(&opts->lock); \ + ret = sprintf(page, "%02x\n", opts->_n_); \ + mutex_unlock(&opts->lock); \ + \ + return ret; \ + } \ + \ + static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\ + const char *page, \ + size_t len) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret; \ + u8 val; \ + \ + mutex_lock(&opts->lock); \ + ret = sscanf(page, "%02hhx", &val); \ + if (ret > 0) { \ + opts->_n_ = val; \ + ret = len; \ + } \ + mutex_unlock(&opts->lock); \ + \ + return ret; \ + } \ + \ + CONFIGFS_ATTR(_f_##_opts_, _n_) + #endif /* __U_ETHER_CONFIGFS_H */ diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h index 540f1c48c1a8d1a8bf058609bc5f455e3cf1dc57..79f70ebf85dc351c77d25e3315619cce280ed544 100644 --- a/drivers/usb/gadget/function/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h @@ -279,6 +279,7 @@ struct ffs_data { } file_perms; struct eventfd_ctx *ffs_eventfd; + struct workqueue_struct *io_completion_wq; bool no_disconnect; struct work_struct reset_work; diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index 4eafd50505458cf10d2b58e48b8ba1dcd092ed4d..a35ee3c2545d9591aa4ef6b6b947cbedbe3f0093 100644 --- a/drivers/usb/gadget/function/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h @@ -29,6 +29,10 @@ struct f_rndis_opts { struct usb_os_desc rndis_os_desc; char rndis_ext_compat_id[16]; + u8 class; + u8 subclass; + u8 protocol; + /* * Read/write access to configfs attributes is handled by configfs. * diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 9b0805f55ad79b3a6b12069508ddc583d2765053..4176216d54be7589a1a84b2d39ce7d803c4d3299 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -537,7 +537,7 @@ static void gs_rx_push(unsigned long _port) } /* push data to (open) tty */ - if (req->actual) { + if (req->actual && tty) { char *packet = req->buf; unsigned size = req->actual; unsigned n; diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 684900fcfe24c3c5ab206568f24da857434a654f..5c28bee327e15440210eb33cfb427f7a1fd659b3 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -28,7 +28,7 @@ #include #include #include - +#include #include #include @@ -116,6 +116,7 @@ enum ep0_state { struct dev_data { spinlock_t lock; refcount_t count; + int udc_usage; enum ep0_state state; /* P: lock */ struct usb_gadgetfs_event event [N_EVENT]; unsigned ev_next; @@ -513,9 +514,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) INIT_WORK(&priv->work, ep_user_copy_worker); schedule_work(&priv->work); } - spin_unlock(&epdata->dev->lock); usb_ep_free_request(ep, req); + spin_unlock(&epdata->dev->lock); put_ep(epdata); } @@ -939,9 +940,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) struct usb_request *req = dev->req; if ((retval = setup_req (ep, req, 0)) == 0) { + ++dev->udc_usage; spin_unlock_irq (&dev->lock); retval = usb_ep_queue (ep, req, GFP_KERNEL); spin_lock_irq (&dev->lock); + --dev->udc_usage; } dev->state = STATE_DEV_CONNECTED; @@ -983,11 +986,14 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) retval = -EIO; else { len = min (len, (size_t)dev->req->actual); -// FIXME don't call this with the spinlock held ... + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); if (copy_to_user (buf, dev->req->buf, len)) retval = -EFAULT; else retval = len; + spin_lock_irq(&dev->lock); + --dev->udc_usage; clean_req (dev->gadget->ep0, dev->req); /* NOTE userspace can't yet choose to stall */ } @@ -1131,6 +1137,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) retval = setup_req (dev->gadget->ep0, dev->req, len); if (retval == 0) { dev->state = STATE_DEV_CONNECTED; + ++dev->udc_usage; spin_unlock_irq (&dev->lock); if (copy_from_user (dev->req->buf, buf, len)) retval = -EFAULT; @@ -1142,6 +1149,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) GFP_KERNEL); } spin_lock_irq(&dev->lock); + --dev->udc_usage; if (retval < 0) { clean_req (dev->gadget->ep0, dev->req); } else @@ -1243,9 +1251,21 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) struct usb_gadget *gadget = dev->gadget; long ret = -ENOTTY; - if (gadget->ops->ioctl) + spin_lock_irq(&dev->lock); + if (dev->state == STATE_DEV_OPENED || + dev->state == STATE_DEV_UNBOUND) { + /* Not bound to a UDC */ + } else if (gadget->ops->ioctl) { + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); + ret = gadget->ops->ioctl (gadget, code, value); + spin_lock_irq(&dev->lock); + --dev->udc_usage; + } + spin_unlock_irq(&dev->lock); + return ret; } @@ -1463,10 +1483,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (value < 0) break; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, dev->req, GFP_KERNEL); spin_lock (&dev->lock); + --dev->udc_usage; if (value < 0) { clean_req (gadget->ep0, dev->req); break; @@ -1490,8 +1512,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req->length = value; req->zero = value < w_length; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL); + spin_lock(&dev->lock); + --dev->udc_usage; + spin_unlock(&dev->lock); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); req->status = 0; @@ -1518,21 +1544,24 @@ static void destroy_ep_files (struct dev_data *dev) /* break link to FS */ ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles); list_del_init (&ep->epfiles); + spin_unlock_irq (&dev->lock); + dentry = ep->dentry; ep->dentry = NULL; parent = d_inode(dentry->d_parent); /* break link to controller */ + mutex_lock(&ep->lock); if (ep->state == STATE_EP_ENABLED) (void) usb_ep_disable (ep->ep); ep->state = STATE_EP_UNBOUND; usb_ep_free_request (ep->ep, ep->req); ep->ep = NULL; + mutex_unlock(&ep->lock); + wake_up (&ep->wait); put_ep (ep); - spin_unlock_irq (&dev->lock); - /* break link to dcache */ inode_lock(parent); d_delete (dentry); @@ -1603,6 +1632,11 @@ gadgetfs_unbind (struct usb_gadget *gadget) spin_lock_irq (&dev->lock); dev->state = STATE_DEV_UNBOUND; + while (dev->udc_usage > 0) { + spin_unlock_irq(&dev->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dev->lock); + } spin_unlock_irq (&dev->lock); destroy_ep_files (dev); diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index e99ab57ee3e589a5df5ed8e0c4063ff6861158fb..fcba59782f265fc216d44d4b0394f79f08b320a7 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -107,15 +107,6 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); -static unsigned long msg_registered; -static void msg_cleanup(void); - -static int msg_thread_exits(struct fsg_common *common) -{ - msg_cleanup(); - return 0; -} - static int msg_do_config(struct usb_configuration *c) { struct fsg_opts *opts; @@ -154,9 +145,6 @@ static struct usb_configuration msg_config_driver = { static int msg_bind(struct usb_composite_dev *cdev) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; struct fsg_opts *opts; struct fsg_config config; int status; @@ -173,8 +161,6 @@ static int msg_bind(struct usb_composite_dev *cdev) if (status) goto fail; - fsg_common_set_ops(opts->common, &ops); - status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); if (status) goto fail_set_cdev; @@ -256,18 +242,12 @@ MODULE_LICENSE("GPL"); static int __init msg_init(void) { - int ret; - - ret = usb_composite_probe(&msg_driver); - set_bit(0, &msg_registered); - - return ret; + return usb_composite_probe(&msg_driver); } module_init(msg_init); -static void msg_cleanup(void) +static void __exit msg_cleanup(void) { - if (test_and_clear_bit(0, &msg_registered)) - usb_composite_unregister(&msg_driver); + usb_composite_unregister(&msg_driver); } module_exit(msg_cleanup); diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index f9661cd627c8e7712c0ca251a1b670eba1528cf5..82c13fce9232729978214b69c0617c87a4edbbb3 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -436,5 +436,4 @@ module_usb_composite_driver(webcam_driver); MODULE_AUTHOR("Laurent Pinchart"); MODULE_DESCRIPTION("Webcam Video Gadget"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1.0"); diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 7cd5c969fcbe9724ec0892403f1a5bd1c7d01320..1e9567091d86073f6e77f85021531de142c055a2 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -273,6 +273,7 @@ config USB_SNP_CORE config USB_SNP_UDC_PLAT tristate "Synopsys USB 2.0 Device controller" depends on USB_GADGET && OF && HAS_DMA + depends on EXTCON || EXTCON=n select USB_GADGET_DUALSPEED select USB_SNP_CORE default ARCH_BCM_IPROC diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 98d71400f8a134442232196d47380fefb3b222fd..a884c022df7a5455e1f0c2746dd933afc55f65e3 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -29,6 +29,8 @@ #include #include "atmel_usba_udc.h" +#define USBA_VBUS_IRQFLAGS (IRQF_ONESHOT \ + | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING) #ifdef CONFIG_USB_GADGET_DEBUG_FS #include @@ -2361,7 +2363,7 @@ static int usba_udc_probe(struct platform_device *pdev) IRQ_NOAUTOEN); ret = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(udc->vbus_pin), NULL, - usba_vbus_irq_thread, IRQF_ONESHOT, + usba_vbus_irq_thread, USBA_VBUS_IRQFLAGS, "atmel_usba_udc", udc); if (ret) { udc->vbus_pin = -ENODEV; diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig index eb8b553923609fbd09a0631ae3eaed3b1c5fff87..c74ac25dddcd0d0ce32fe457a228a50f54ace36b 100644 --- a/drivers/usb/gadget/udc/bdc/Kconfig +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -1,6 +1,7 @@ config USB_BDC_UDC tristate "Broadcom USB3.0 device controller IP driver(BDC)" depends on USB_GADGET && HAS_DMA + default ARCH_BRCMSTB help BDC is Broadcom's USB3.0 device controller IP. If your SOC has a BDC IP diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h index 916d47135cac2d5a511679b0d8b2c3933f041ffe..6df0352cdc505a6701f984798af12442139a87df 100644 --- a/drivers/usb/gadget/udc/bdc/bdc.h +++ b/drivers/usb/gadget/udc/bdc/bdc.h @@ -27,8 +27,8 @@ #include #include -#define BRCM_BDC_NAME "bdc_usb3" -#define BRCM_BDC_DESC "BDC device controller driver" +#define BRCM_BDC_NAME "bdc" +#define BRCM_BDC_DESC "Broadcom USB Device Controller driver" #define DMA_ADDR_INVALID (~(dma_addr_t)0) @@ -83,14 +83,14 @@ #define BDC_DVCSA 0x50 #define BDC_DVCSB 0x54 -#define BDC_EPSTS0(n) (0x60 + (n * 0x10)) -#define BDC_EPSTS1(n) (0x64 + (n * 0x10)) -#define BDC_EPSTS2(n) (0x68 + (n * 0x10)) -#define BDC_EPSTS3(n) (0x6c + (n * 0x10)) -#define BDC_EPSTS4(n) (0x70 + (n * 0x10)) -#define BDC_EPSTS5(n) (0x74 + (n * 0x10)) -#define BDC_EPSTS6(n) (0x78 + (n * 0x10)) -#define BDC_EPSTS7(n) (0x7c + (n * 0x10)) +#define BDC_EPSTS0 0x60 +#define BDC_EPSTS1 0x64 +#define BDC_EPSTS2 0x68 +#define BDC_EPSTS3 0x6c +#define BDC_EPSTS4 0x70 +#define BDC_EPSTS5 0x74 +#define BDC_EPSTS6 0x78 +#define BDC_EPSTS7 0x7c #define BDC_SRRBAL(n) (0x200 + (n * 0x10)) #define BDC_SRRBAH(n) (0x204 + (n * 0x10)) #define BDC_SRRINT(n) (0x208 + (n * 0x10)) @@ -413,6 +413,9 @@ struct bdc { /* device lock */ spinlock_t lock; + /* generic phy */ + struct phy **phys; + int num_phys; /* num of endpoints for a particular instantiation of IP */ unsigned int num_eps; /* @@ -454,6 +457,7 @@ struct bdc { * Func Wake packet every 2.5 secs. Refer to USB3 spec section 8.5.6.4 */ struct delayed_work func_wake_notify; + struct clk *clk; }; static inline u32 bdc_readl(void __iomem *base, u32 offset) diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index e9bd8d4abca00df87aa35672728870d15ba3ba74..7a8af4b916cff8e9ba8d8c955d10472d047e3eec 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -24,9 +24,11 @@ #include #include #include +#include #include #include #include +#include #include "bdc.h" #include "bdc_dbg.h" @@ -444,6 +446,43 @@ static int bdc_hw_init(struct bdc *bdc) return 0; } +static int bdc_phy_init(struct bdc *bdc) +{ + int phy_num; + int ret; + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + ret = phy_init(bdc->phys[phy_num]); + if (ret) + goto err_exit_phy; + ret = phy_power_on(bdc->phys[phy_num]); + if (ret) { + phy_exit(bdc->phys[phy_num]); + goto err_exit_phy; + } + } + + return 0; + +err_exit_phy: + while (--phy_num >= 0) { + phy_power_off(bdc->phys[phy_num]); + phy_exit(bdc->phys[phy_num]); + } + + return ret; +} + +static void bdc_phy_exit(struct bdc *bdc) +{ + int phy_num; + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + phy_power_off(bdc->phys[phy_num]); + phy_exit(bdc->phys[phy_num]); + } +} + static int bdc_probe(struct platform_device *pdev) { struct bdc *bdc; @@ -452,12 +491,29 @@ static int bdc_probe(struct platform_device *pdev) int irq; u32 temp; struct device *dev = &pdev->dev; + struct clk *clk; + int phy_num; dev_dbg(dev, "%s()\n", __func__); + + clk = devm_clk_get(dev, "sw_usbd"); + if (IS_ERR(clk)) { + dev_info(dev, "Clock not found in Device Tree\n"); + clk = NULL; + } + + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL); if (!bdc) return -ENOMEM; + bdc->clk = clk; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bdc->regs = devm_ioremap_resource(dev, res); if (IS_ERR(bdc->regs)) { @@ -473,35 +529,66 @@ static int bdc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bdc); bdc->irq = irq; bdc->dev = dev; - dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + dev_dbg(dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + + bdc->num_phys = of_count_phandle_with_args(dev->of_node, + "phys", "#phy-cells"); + if (bdc->num_phys > 0) { + bdc->phys = devm_kcalloc(dev, bdc->num_phys, + sizeof(struct phy *), GFP_KERNEL); + if (!bdc->phys) + return -ENOMEM; + } else { + bdc->num_phys = 0; + } + dev_info(dev, "Using %d phy(s)\n", bdc->num_phys); + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + bdc->phys[phy_num] = devm_of_phy_get_by_index( + dev, dev->of_node, phy_num); + if (IS_ERR(bdc->phys[phy_num])) { + ret = PTR_ERR(bdc->phys[phy_num]); + dev_err(bdc->dev, + "BDC phy specified but not found:%d\n", ret); + return ret; + } + } + + ret = bdc_phy_init(bdc); + if (ret) { + dev_err(bdc->dev, "BDC phy init failure:%d\n", ret); + return ret; + } temp = bdc_readl(bdc->regs, BDC_BDCCAP1); if ((temp & BDC_P64) && !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { - dev_dbg(bdc->dev, "Using 64-bit address\n"); + dev_dbg(dev, "Using 64-bit address\n"); } else { - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(bdc->dev, "No suitable DMA config available, abort\n"); + dev_err(dev, + "No suitable DMA config available, abort\n"); return -ENOTSUPP; } - dev_dbg(bdc->dev, "Using 32-bit address\n"); + dev_dbg(dev, "Using 32-bit address\n"); } ret = bdc_hw_init(bdc); if (ret) { - dev_err(bdc->dev, "BDC init failure:%d\n", ret); - return ret; + dev_err(dev, "BDC init failure:%d\n", ret); + goto phycleanup; } ret = bdc_udc_init(bdc); if (ret) { - dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret); + dev_err(dev, "BDC Gadget init failure:%d\n", ret); goto cleanup; } return 0; cleanup: bdc_hw_exit(bdc); - +phycleanup: + bdc_phy_exit(bdc); return ret; } @@ -513,13 +600,56 @@ static int bdc_remove(struct platform_device *pdev) dev_dbg(bdc->dev, "%s ()\n", __func__); bdc_udc_exit(bdc); bdc_hw_exit(bdc); + bdc_phy_exit(bdc); + clk_disable_unprepare(bdc->clk); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int bdc_suspend(struct device *dev) +{ + struct bdc *bdc = dev_get_drvdata(dev); + clk_disable_unprepare(bdc->clk); return 0; } +static int bdc_resume(struct device *dev) +{ + struct bdc *bdc = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(bdc->clk); + if (ret) { + dev_err(bdc->dev, "err enabling the clock\n"); + return ret; + } + ret = bdc_reinit(bdc); + if (ret) { + dev_err(bdc->dev, "err in bdc reinit\n"); + return ret; + } + + return 0; +} + +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(bdc_pm_ops, bdc_suspend, + bdc_resume); + +static const struct of_device_id bdc_of_match[] = { + { .compatible = "brcm,bdc-v0.16" }, + { .compatible = "brcm,bdc" }, + { /* sentinel */ } +}; + static struct platform_driver bdc_driver = { .driver = { .name = BRCM_BDC_NAME, + .owner = THIS_MODULE, + .pm = &bdc_pm_ops, + .of_match_table = bdc_of_match, }, .probe = bdc_probe, .remove = bdc_remove, diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.c b/drivers/usb/gadget/udc/bdc/bdc_dbg.c index 5945dbc47825a9a83ef03c474e2228eecdf5651e..ac98f6f681b7ae1108d2119f064aa51245863b9b 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_dbg.c +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.c @@ -40,28 +40,28 @@ void bdc_dump_epsts(struct bdc *bdc) { u32 temp; - temp = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS0); dev_vdbg(bdc->dev, "BDC_EPSTS0:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS1); dev_vdbg(bdc->dev, "BDC_EPSTS1:0x%x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS2(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS2); dev_vdbg(bdc->dev, "BDC_EPSTS2:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS3(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS3); dev_vdbg(bdc->dev, "BDC_EPSTS3:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS4(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS4); dev_vdbg(bdc->dev, "BDC_EPSTS4:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS5(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS5); dev_vdbg(bdc->dev, "BDC_EPSTS5:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS6(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS6); dev_vdbg(bdc->dev, "BDC_EPSTS6:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS7(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS7); dev_vdbg(bdc->dev, "BDC_EPSTS7:0x%08x\n", temp); } diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff1ef24d1777a1fc4a73436cb456d2082d41de7e..bfd8f7ade9351b5f933525b90dd06d7ee547248d 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -777,9 +777,9 @@ static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) */ /* The current hw dequeue pointer */ - tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0); deq_ptr_64 = tmp_32; - tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1); deq_ptr_64 |= ((u64)tmp_32 << 32); /* we have the dma addr of next bd that will be fetched by hardware */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c index aae7458d8986945925093ada5b59143e0215a333..c8434614645695132a34dee946c559de752d2e5c 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_udc.c +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c @@ -249,6 +249,7 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) disconn = true; else if ((uspc & BDC_PCS) && !BDC_PST(uspc)) connected = true; + clear_flags |= BDC_PCC; } /* Change in VBus and VBus is present */ @@ -259,16 +260,16 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) bdc_softconn(bdc); usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED); } - clear_flags = BDC_VBC; + clear_flags |= BDC_VBC; } else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) { /* Hot reset, warm reset, 2.0 bus reset or disconn */ dev_dbg(bdc->dev, "Port reset or disconn\n"); bdc_uspc_disconnected(bdc, disconn); - clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC; + clear_flags |= BDC_PRC; } else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) { /* Change in Link state */ handle_link_state_change(bdc, uspc); - clear_flags = BDC_PSC|BDC_PCS; + clear_flags |= BDC_PSC; } /* diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index e6f04eee95c4d2d0dbbadd5e3f1f9601d8d491f9..d41d07aae0cec07294cd9917d8ccdbd57f1f29ca 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev, dev_err(dev, "failed to map buffer\n"); return -EFAULT; } + + req->dma_mapped = 1; } return 0; @@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev, is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->num_mapped_sgs = 0; - } else { + } else if (req->dma_mapped) { dma_unmap_single(dev, req->dma, req->length, is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + req->dma_mapped = 0; } } EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev); @@ -1130,6 +1133,7 @@ static int check_pending_gadget_drivers(struct usb_udc *udc) * @release: a gadget release function. * * Returns zero on success, negative errno otherwise. + * Calls the gadget release function in the latter case. */ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)) @@ -1137,10 +1141,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, struct usb_udc *udc; int ret = -ENOMEM; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); - if (!udc) - goto err1; - dev_set_name(&gadget->dev, "gadget"); INIT_WORK(&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent; @@ -1150,7 +1150,13 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, else gadget->dev.release = usb_udc_nop_release; - ret = device_register(&gadget->dev); + device_initialize(&gadget->dev); + + udc = kzalloc(sizeof(*udc), GFP_KERNEL); + if (!udc) + goto err1; + + ret = device_add(&gadget->dev); if (ret) goto err2; @@ -1197,10 +1203,10 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, device_del(&gadget->dev); err2: - put_device(&gadget->dev); kfree(udc); err1: + put_device(&gadget->dev); return ret; } EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release); @@ -1314,8 +1320,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->dev.driver = &driver->driver; udc->gadget->dev.driver = &driver->driver; - if (driver->max_speed < udc->gadget->max_speed) - usb_gadget_udc_set_speed(udc, driver->max_speed); + usb_gadget_udc_set_speed(udc, driver->max_speed); ret = driver->bind(udc->gadget, driver); if (ret) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 3c3760315910803c44202720de450dc9072a3458..b17618a55f1b9f0d9df4febe0d4a5307a746d005 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -237,6 +237,8 @@ struct dummy_hcd { struct usb_device *udev; struct list_head urbp_list; + struct urbp *next_frame_urbp; + u32 stream_en_ep; u8 num_stream[30 / 2]; @@ -253,11 +255,13 @@ struct dummy { */ struct dummy_ep ep[DUMMY_ENDPOINTS]; int address; + int callback_usage; struct usb_gadget gadget; struct usb_gadget_driver *driver; struct dummy_request fifo_req; u8 fifo_buf[FIFO_SIZE]; u16 devstatus; + unsigned ints_enabled:1; unsigned udc_suspended:1; unsigned pullup:1; @@ -375,11 +379,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) USB_PORT_STAT_CONNECTION) == 0) dum_hcd->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); - if ((dum_hcd->port_status & - USB_PORT_STAT_ENABLE) == 1 && - (dum_hcd->port_status & - USB_SS_PORT_LS_U0) == 1 && - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) && + (dum_hcd->port_status & + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) dum_hcd->active = 1; } } else { @@ -440,18 +443,27 @@ static void set_link_state(struct dummy_hcd *dum_hcd) (~dum_hcd->old_status) & dum_hcd->port_status; /* Report reset and disconnect events to the driver */ - if (dum->driver && (disconnect || reset)) { + if (dum->ints_enabled && (disconnect || reset)) { stop_activity(dum); + ++dum->callback_usage; + spin_unlock(&dum->lock); if (reset) usb_gadget_udc_reset(&dum->gadget, dum->driver); else dum->driver->disconnect(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } - } else if (dum_hcd->active != dum_hcd->old_active) { + } else if (dum_hcd->active != dum_hcd->old_active && + dum->ints_enabled) { + ++dum->callback_usage; + spin_unlock(&dum->lock); if (dum_hcd->old_active && dum->driver->suspend) dum->driver->suspend(&dum->gadget); else if (!dum_hcd->old_active && dum->driver->resume) dum->driver->resume(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } dum_hcd->old_status = dum_hcd->port_status; @@ -972,8 +984,11 @@ static int dummy_udc_start(struct usb_gadget *g, * can't enumerate without help from the driver we're binding. */ + spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; + dum->ints_enabled = 1; + spin_unlock_irq(&dum->lock); return 0; } @@ -984,6 +999,16 @@ static int dummy_udc_stop(struct usb_gadget *g) struct dummy *dum = dum_hcd->dum; spin_lock_irq(&dum->lock); + dum->ints_enabled = 0; + stop_activity(dum); + + /* emulate synchronize_irq(): wait for callbacks to finish */ + while (dum->callback_usage > 0) { + spin_unlock_irq(&dum->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dum->lock); + } + dum->driver = NULL; spin_unlock_irq(&dum->lock); @@ -1037,7 +1062,12 @@ static int dummy_udc_probe(struct platform_device *pdev) memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed = USB_SPEED_SUPER; + if (mod_data.is_super_speed) + dum->gadget.max_speed = USB_SPEED_SUPER; + else if (mod_data.is_high_speed) + dum->gadget.max_speed = USB_SPEED_HIGH; + else + dum->gadget.max_speed = USB_SPEED_FULL; dum->gadget.dev.parent = &pdev->dev; init_dummy_udc_hw(dum); @@ -1246,6 +1276,8 @@ static int dummy_urb_enqueue( list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); urb->hcpriv = urbp; + if (!dum_hcd->next_frame_urbp) + dum_hcd->next_frame_urbp = urbp; if (usb_pipetype(urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -1521,6 +1553,8 @@ static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ? dum->ss_hcd : dum->hs_hcd))) return NULL; + if (!dum->ints_enabled) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep[0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1762,6 +1796,7 @@ static void dummy_timer(unsigned long _dum_hcd) spin_unlock_irqrestore(&dum->lock, flags); return; } + dum_hcd->next_frame_urbp = NULL; for (i = 0; i < DUMMY_ENDPOINTS; i++) { if (!ep_info[i].name) @@ -1778,6 +1813,10 @@ static void dummy_timer(unsigned long _dum_hcd) int type; int status = -EINPROGRESS; + /* stop when we reach URBs queued after the timer interrupt */ + if (urbp == dum_hcd->next_frame_urbp) + break; + urb = urbp->urb; if (urb->unlinked) goto return_urb; @@ -1857,10 +1896,12 @@ static void dummy_timer(unsigned long _dum_hcd) * until setup() returns; no reentrancy issues etc. */ if (value > 0) { + ++dum->callback_usage; spin_unlock(&dum->lock); value = dum->driver->setup(&dum->gadget, &setup); spin_lock(&dum->lock); + --dum->callback_usage; if (value >= 0) { /* no delays (max 64KB data stage) */ @@ -2561,8 +2602,6 @@ static struct hc_driver dummy_hcd = { .product_desc = "Dummy host controller", .hcd_priv_size = sizeof(struct dummy_hcd), - .flags = HCD_USB3 | HCD_SHARED, - .reset = dummy_setup, .start = dummy_start, .stop = dummy_stop, @@ -2591,8 +2630,12 @@ static int dummy_hcd_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); dum = *((void **)dev_get_platdata(&pdev->dev)); - if (!mod_data.is_super_speed) + if (mod_data.is_super_speed) + dummy_hcd.flags = HCD_USB3 | HCD_SHARED; + else if (mod_data.is_high_speed) dummy_hcd.flags = HCD_USB2; + else + dummy_hcd.flags = HCD_USB11; hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); if (!hs_hcd) return -ENOMEM; @@ -2776,7 +2819,7 @@ static int __init init(void) if (retval < 0) { i--; while (i >= 0) - platform_device_del(the_udc_pdev[i]); + platform_device_del(the_udc_pdev[i--]); goto err_add_udc; } } diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 303328ce59ee0555b07bfac3d2c6a0fe64481e41..a3e72d690eef9532cb7d5d9338247355ff69d07a 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -62,7 +62,7 @@ static const char *const ep_name[] = { "ep3", }; -static struct usb_endpoint_descriptor qe_ep0_desc = { +static const struct usb_endpoint_descriptor qe_ep0_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 8a708d0a1042e9238b822f81074d504cc27c200a..4103bf7cf52abb30586754abfd2242f7a62a0cf6 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -39,7 +39,6 @@ #include "mv_udc.h" #define DRIVER_DESC "Marvell PXA USB Device Controller driver" -#define DRIVER_VERSION "8 Nov 2010" #define ep_dir(ep) (((ep)->ep_num == 0) ? \ ((ep)->udc->ep0_dir) : ((ep)->direction)) @@ -2427,5 +2426,4 @@ module_platform_driver(udc_driver); MODULE_ALIAS("platform:mv-udc"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Chao Xie "); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 62dc9c7798e78a034a9e63f8c3163fcebec9e57a..63a206122058968a1fb8fec424c0ca8022a1f0f6 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -8,6 +8,7 @@ * the Free Software Foundation; version 2 of the License. */ +#include #include #include #include @@ -20,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -347,6 +350,7 @@ struct renesas_usb3 { bool workaround_for_vbus; bool extcon_host; /* check id and set EXTCON_USB_HOST */ bool extcon_usb; /* check vbus and set EXTCON_USB */ + bool forced_b_device; }; #define gadget_to_renesas_usb3(_gadget) \ @@ -663,7 +667,9 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) spin_lock_irqsave(&usb3->lock, flags); usb3_set_mode(usb3, host); usb3_vbus_out(usb3, a_dev); - if (!host && a_dev) /* for A-Peripheral */ + /* for A-Peripheral or forced B-device mode */ + if ((!host && a_dev) || + (usb3->workaround_for_vbus && usb3->forced_b_device)) usb3_connect(usb3); spin_unlock_irqrestore(&usb3->lock, flags); } @@ -677,7 +683,7 @@ static void usb3_check_id(struct renesas_usb3 *usb3) { usb3->extcon_host = usb3_is_a_device(usb3); - if (usb3->extcon_host) + if (usb3->extcon_host && !usb3->forced_b_device) usb3_mode_config(usb3, true, true); else usb3_mode_config(usb3, false, false); @@ -838,21 +844,32 @@ static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep return usb3_req; } -static void usb3_request_done(struct renesas_usb3_ep *usb3_ep, - struct renesas_usb3_request *usb3_req, int status) +static void __usb3_request_done(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req, + int status) { struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); - unsigned long flags; dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n", usb3_ep->num, usb3_req->req.length, usb3_req->req.actual, status); usb3_req->req.status = status; - spin_lock_irqsave(&usb3->lock, flags); usb3_ep->started = false; list_del_init(&usb3_req->queue); - spin_unlock_irqrestore(&usb3->lock, flags); + spin_unlock(&usb3->lock); usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req); + spin_lock(&usb3->lock); +} + +static void usb3_request_done(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req, int status) +{ + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); + unsigned long flags; + + spin_lock_irqsave(&usb3->lock, flags); + __usb3_request_done(usb3_ep, usb3_req, status); + spin_unlock_irqrestore(&usb3->lock, flags); } static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3) @@ -1021,7 +1038,7 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_ep->ep.maxpacket); u8 *buf = usb3_req->req.buf + usb3_req->req.actual; u32 tmp = 0; - bool is_last; + bool is_last = !len ? true : false; if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) return -EBUSY; @@ -1042,7 +1059,8 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_write(usb3, tmp, fifo_reg); } - is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); + if (!is_last) + is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); /* Send the data */ usb3_set_px_con_send(usb3_ep, len, is_last); @@ -1133,7 +1151,8 @@ static void usb3_start_pipe0(struct renesas_usb3_ep *usb3_ep, usb3_set_p0_con_for_ctrl_read_data(usb3); } else { usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); - usb3_set_p0_con_for_ctrl_write_data(usb3); + if (usb3_req->req.length) + usb3_set_p0_con_for_ctrl_write_data(usb3); } usb3_p0_xfer(usb3_ep, usb3_req); @@ -2036,7 +2055,16 @@ static u32 usb3_calc_ramarea(int ram_size) static u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, const struct usb_endpoint_descriptor *desc) { - return usb3_ep->rammap_val | PN_RAMMAP_MPKT(usb_endpoint_maxp(desc)); + int i; + const u32 max_packet_array[] = {8, 16, 32, 64, 512}; + u32 mpkt = PN_RAMMAP_MPKT(1024); + + for (i = 0; i < ARRAY_SIZE(max_packet_array); i++) { + if (usb_endpoint_maxp(desc) <= max_packet_array[i]) + mpkt = PN_RAMMAP_MPKT(max_packet_array[i]); + } + + return usb3_ep->rammap_val | mpkt; } static int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, @@ -2181,7 +2209,7 @@ static void renesas_usb3_ep_fifo_flush(struct usb_ep *_ep) } } -static struct usb_ep_ops renesas_usb3_ep_ops = { +static const struct usb_ep_ops renesas_usb3_ep_ops = { .enable = renesas_usb3_ep_enable, .disable = renesas_usb3_ep_disable, @@ -2272,6 +2300,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, if (!usb3->driver) return -ENODEV; + if (usb3->forced_b_device) + return -EBUSY; + if (!strncmp(buf, "host", strlen("host"))) new_mode_is_host = true; else if (!strncmp(buf, "peripheral", strlen("peripheral"))) @@ -2299,6 +2330,70 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(role); +static int renesas_usb3_b_device_show(struct seq_file *s, void *unused) +{ + struct renesas_usb3 *usb3 = s->private; + + seq_printf(s, "%d\n", usb3->forced_b_device); + + return 0; +} + +static int renesas_usb3_b_device_open(struct inode *inode, struct file *file) +{ + return single_open(file, renesas_usb3_b_device_show, inode->i_private); +} + +static ssize_t renesas_usb3_b_device_write(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct renesas_usb3 *usb3 = s->private; + char buf[32]; + + if (!usb3->driver) + return -ENODEV; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "1", 1)) + usb3->forced_b_device = true; + else + usb3->forced_b_device = false; + + /* Let this driver call usb3_connect() anyway */ + usb3_check_id(usb3); + + return count; +} + +static const struct file_operations renesas_usb3_b_device_fops = { + .open = renesas_usb3_b_device_open, + .write = renesas_usb3_b_device_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3, + struct device *dev) +{ + struct dentry *root, *file; + + root = debugfs_create_dir(dev_name(dev), NULL); + if (IS_ERR_OR_NULL(root)) { + dev_info(dev, "%s: Can't create the root\n", __func__); + return; + } + + file = debugfs_create_file("b_device", 0644, root, usb3, + &renesas_usb3_b_device_fops); + if (!file) + dev_info(dev, "%s: Can't create debugfs mode\n", __func__); +} + /*------- platform_driver ------------------------------------------------*/ static int renesas_usb3_remove(struct platform_device *pdev) { @@ -2421,22 +2516,40 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev, } } -static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795 = { +static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795_es1 = { .ramsize_per_ramif = SZ_16K, .num_ramif = 2, .ramsize_per_pipe = SZ_4K, .workaround_for_vbus = true, }; +static const struct renesas_usb3_priv renesas_usb3_priv_gen3 = { + .ramsize_per_ramif = SZ_16K, + .num_ramif = 4, + .ramsize_per_pipe = SZ_4K, +}; + static const struct of_device_id usb3_of_match[] = { { .compatible = "renesas,r8a7795-usb3-peri", - .data = &renesas_usb3_priv_r8a7795, + .data = &renesas_usb3_priv_gen3, + }, + { + .compatible = "renesas,rcar-gen3-usb3-peri", + .data = &renesas_usb3_priv_gen3, }, { }, }; MODULE_DEVICE_TABLE(of, usb3_of_match); +static const struct soc_device_attribute renesas_usb3_quirks_match[] = { + { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = &renesas_usb3_priv_r8a7795_es1, + }, + { /* sentinel */ }, +}; + static const unsigned int renesas_usb3_cable[] = { EXTCON_USB, EXTCON_USB_HOST, @@ -2450,15 +2563,23 @@ static int renesas_usb3_probe(struct platform_device *pdev) const struct of_device_id *match; int irq, ret; const struct renesas_usb3_priv *priv; + const struct soc_device_attribute *attr; match = of_match_node(usb3_of_match, pdev->dev.of_node); if (!match) return -ENODEV; - priv = match->data; + + attr = soc_device_match(renesas_usb3_quirks_match); + if (attr) + priv = attr->data; + else + priv = match->data; irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENODEV; + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); if (!usb3) @@ -2516,6 +2637,8 @@ static int renesas_usb3_probe(struct platform_device *pdev) usb3->workaround_for_vbus = priv->workaround_for_vbus; + renesas_usb3_debugfs_init(usb3, &pdev->dev); + dev_info(&pdev->dev, "probed\n"); return 0; diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index 4643a01262b40db391624cd842669b50252d865a..394abd5d65c0236ed654461b2631be8c87549788 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -51,7 +51,6 @@ #include "s3c2410_udc.h" #define DRIVER_DESC "S3C2410 USB Device Controller Gadget" -#define DRIVER_VERSION "29 Apr 2007" #define DRIVER_AUTHOR "Herbert Pötzl , " \ "Arnaud Patard " @@ -1996,7 +1995,7 @@ static int __init udc_init(void) { int retval; - dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION); + dprintk(DEBUG_NORMAL, "%s\n", gadget_name); s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL); if (IS_ERR(s3c2410_udc_debugfs_root)) { @@ -2027,5 +2026,4 @@ module_exit(udc_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c index f7b4d0f159e4e4492bbfb6d5877370bb9275cda5..e8a5fdaee37d03564d85371b27bfe55614478f23 100644 --- a/drivers/usb/gadget/udc/snps_udc_plat.c +++ b/drivers/usb/gadget/udc/snps_udc_plat.c @@ -184,7 +184,7 @@ static int udc_plat_probe(struct platform_device *pdev) goto exit_phy; } - ret = extcon_get_cable_state_(udc->edev, EXTCON_USB); + ret = extcon_get_state(udc->edev, EXTCON_USB); if (ret < 0) { dev_err(dev, "Can't get cable state\n"); goto exit_extcon; @@ -273,7 +273,7 @@ static int udc_plat_suspend(struct device *dev) udc = dev_get_drvdata(dev); stop_udc(udc); - if (extcon_get_cable_state_(udc->edev, EXTCON_USB) > 0) { + if (extcon_get_state(udc->edev, EXTCON_USB) > 0) { dev_dbg(udc->dev, "device -> idle\n"); stop_udc(udc); } @@ -303,7 +303,7 @@ static int udc_plat_resume(struct device *dev) return ret; } - if (extcon_get_cable_state_(udc->edev, EXTCON_USB) > 0) { + if (extcon_get_state(udc->edev, EXTCON_USB) > 0) { dev_dbg(udc->dev, "idle -> device\n"); start_udc(udc); } diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 4a08b70c81aa8f31b7baa1c1ea122416448a6c03..d025cc06dda7936a4a66996af95ded8996e2886d 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -642,7 +642,7 @@ static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) #define ehci_start_port_reset NULL #endif /* CONFIG_USB_OTG */ -static struct ehci_driver_overrides ehci_fsl_overrides __initdata = { +static const struct ehci_driver_overrides ehci_fsl_overrides __initconst = { .extra_priv_size = sizeof(struct ehci_fsl), .reset = ehci_fsl_setup, }; diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 94ea9fff13e6d7328cd956f2b01dbe8c47eaa3c3..4d308533bc83510322448cd56045f4bb21a6042c 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -130,8 +130,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(dev, "EHCI irq failed\n"); - return -ENODEV; + dev_err(dev, "EHCI irq failed: %d\n", irq); + return irq; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index e90ddb5307653f7a61b3054def1e5e6c82217efb..ba557cdba8ef6c37ca1843ddfc25e7b2aa3dac21 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -55,8 +55,8 @@ static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) return &dr_mode_data[i]; } } - pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n", - np->full_name); + pr_warn("%pOF: Invalid 'dr_mode' property, fallback to host mode\n", + np); return &dr_mode_data[0]; /* mode not specified, use host */ } diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 1db0626c8bf415289fd7e8f0875e15e4aeff404e..da3b18038d2317ac362a15f583badc517ee9060b 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -614,7 +614,7 @@ static int wa_fill_descr(struct wahc *wa) return result; } -static struct hc_driver hwahc_hc_driver = { +static const struct hc_driver hwahc_hc_driver = { .description = "hwa-hcd", .product_desc = "Wireless USB HWA host controller", .hcd_priv_size = sizeof(struct hwahc) - sizeof(struct usb_hcd), @@ -860,7 +860,7 @@ static void hwahc_disconnect(struct usb_interface *usb_iface) usb_put_hcd(usb_hcd); } -static struct usb_device_id hwahc_id_table[] = { +static const struct usb_device_id hwahc_id_table[] = { /* Alereon 5310 */ { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01), .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC | diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index f542045dc2a624fb8e0f3b82c55dc7a177fd3e75..39ae7fb64b6feb9cf5d65dbff17042513d98758e 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1779,7 +1779,7 @@ static void imx21_hc_stop(struct usb_hcd *hcd) /* Driver glue */ /* =========================================== */ -static struct hc_driver imx21_hc_driver = { +static const struct hc_driver imx21_hc_driver = { .description = hcd_name, .product_desc = "IMX21 USB Host Controller", .hcd_priv_size = sizeof(struct imx21), @@ -1849,8 +1849,10 @@ static int imx21_probe(struct platform_device *pdev) if (!res) return -ENODEV; irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENXIO; + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } hcd = usb_create_hcd(&imx21_hc_driver, &pdev->dev, dev_name(&pdev->dev)); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index d089b3fb7a13dc8e02ad781765c78c87815e6a11..73fec38754f9185af223b90196a751b4d545b6d8 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1511,7 +1511,7 @@ static int isp116x_bus_resume(struct usb_hcd *hcd) #endif -static struct hc_driver isp116x_hc_driver = { +static const struct hc_driver isp116x_hc_driver = { .description = hcd_name, .product_desc = "ISP116x Host Controller", .hcd_priv_size = sizeof(struct isp116x), diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 0f2b4b358e1a74384c05b5bff3ffe0acdbf512f5..9b7e307e2d54266c063ea212c929a5b60ea5574d 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2591,7 +2591,7 @@ static int isp1362_hc_start(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static struct hc_driver isp1362_hc_driver = { +static const struct hc_driver isp1362_hc_driver = { .description = hcd_name, .product_desc = "ISP1362 Host Controller", .hcd_priv_size = sizeof(struct isp1362_hcd), diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 369869a29ebd4d2ead3fda4efcddeb1d745a6d5c..0ece9a9341e544afce19a89c3dffe7c3471d5a94 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1811,7 +1811,7 @@ max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) { } -static struct hc_driver max3421_hcd_desc = { +static const struct hc_driver max3421_hcd_desc = { .description = "max3421", .product_desc = DRIVER_DESC, .hcd_priv_size = sizeof(struct max3421_hcd), diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index a4d814b7f3806668362de8e04ba913fe98ff2b8e..91393ec7d8503c75b3985a695a6b9876caf300a6 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -53,7 +53,7 @@ #define DRIVER_DESC "OHCI OMAP driver" #ifdef CONFIG_TPS65010 -#include +#include #else #define LOW 0 diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index a8b8d8b8d9f39dcf28db1bf35da543245fe3d332..d4e0f7cd96fa4454276dbb55f71aa6b051691220 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -123,13 +123,12 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) * regular memory. The HCD_LOCAL_MEM flag does just that. */ - if (!dma_declare_coherent_memory(dev, mem->start, + retval = dma_declare_coherent_memory(dev, mem->start, mem->start - mem->parent->start, resource_size(mem), - DMA_MEMORY_MAP | - DMA_MEMORY_EXCLUSIVE)) { + DMA_MEMORY_EXCLUSIVE); + if (retval) { dev_err(dev, "cannot declare coherent memory\n"); - retval = -ENXIO; goto err1; } diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index cfcfadfc94fc25b8e10d788e59514c146d32ccc1..16d081a093bb0d628e943144d61821b5db7defec 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -227,13 +227,10 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) goto err_ioremap_regs; } - if (!dma_declare_coherent_memory(&dev->dev, sram->start, - sram->start, - resource_size(sram), - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) { - ret = -EBUSY; + ret = dma_declare_coherent_memory(&dev->dev, sram->start, sram->start, + resource_size(sram), DMA_MEMORY_EXCLUSIVE); + if (ret) goto err_dma_declare; - } if (cell->enable) { ret = cell->enable(dev); diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c8989c62a2621b88cf8b9d0c3001a37a31d5e151..6dda3623a276d34f0926ee225a6becee16226a47 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -98,6 +98,7 @@ enum amd_chipset_gen { AMD_CHIPSET_HUDSON2, AMD_CHIPSET_BOLTON, AMD_CHIPSET_YANGTZE, + AMD_CHIPSET_TAISHAN, AMD_CHIPSET_UNKNOWN, }; @@ -145,20 +146,26 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo) pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL); - if (!pinfo->smbus_dev) { - pinfo->sb_type.gen = NOT_AMD_CHIPSET; - return 0; + if (pinfo->smbus_dev) { + rev = pinfo->smbus_dev->revision; + if (rev >= 0x11 && rev <= 0x14) + pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2; + else if (rev >= 0x15 && rev <= 0x18) + pinfo->sb_type.gen = AMD_CHIPSET_BOLTON; + else if (rev >= 0x39 && rev <= 0x3a) + pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE; + } else { + pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x145c, NULL); + if (pinfo->smbus_dev) { + rev = pinfo->smbus_dev->revision; + pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN; + } else { + pinfo->sb_type.gen = NOT_AMD_CHIPSET; + return 0; + } } - - rev = pinfo->smbus_dev->revision; - if (rev >= 0x11 && rev <= 0x14) - pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2; - else if (rev >= 0x15 && rev <= 0x18) - pinfo->sb_type.gen = AMD_CHIPSET_BOLTON; - else if (rev >= 0x39 && rev <= 0x3a) - pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE; } - pinfo->sb_type.rev = rev; return 1; } @@ -260,11 +267,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev) { /* Make sure amd chipset type has already been initialized */ usb_amd_find_chipset_info(); - if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE) - return 0; - - dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n"); - return 1; + if (amd_chipset.sb_type.gen == AMD_CHIPSET_YANGTZE || + amd_chipset.sb_type.gen == AMD_CHIPSET_TAISHAN) { + dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n"); + return 1; + } + return 0; } EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk); @@ -439,7 +447,7 @@ static int usb_asmedia_wait_write(struct pci_dev *pdev) if ((value & ASMT_CONTROL_WRITE_BIT) == 0) return 0; - usleep_range(40, 60); + udelay(50); } dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); @@ -1014,7 +1022,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); * * Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS. * It signals to the BIOS that the OS wants control of the host controller, - * and then waits 5 seconds for the BIOS to hand over control. + * and then waits 1 second for the BIOS to hand over control. * If we timeout, assume the BIOS is broken and take control anyway. */ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) @@ -1061,9 +1069,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) if (val & XHCI_HC_BIOS_OWNED) { writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); - /* Wait for 5 seconds with 10 microsecond polling interval */ + /* Wait for 1 second with 10 microsecond polling interval */ timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, - 0, 5000, 10); + 0, 1000000, 10); /* Assume a buggy BIOS and take HC ownership anyway */ if (timeout) { @@ -1092,7 +1100,7 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) * operational or runtime registers. Wait 5 seconds and no more. */ timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_CNR, 0, - 5000, 10); + 5000000, 10); /* Assume a buggy HC and start HC initialization anyway */ if (timeout) { val = readl(op_reg_base + XHCI_STS_OFFSET); @@ -1150,3 +1158,23 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); + +bool usb_xhci_needs_pci_reset(struct pci_dev *pdev) +{ + /* + * Our dear uPD72020{1,2} friend only partially resets when + * asked to via the XHCI interface, and may end up doing DMA + * at the wrong addresses, as it keeps the top 32bit of some + * addresses from its previous programming under obscure + * circumstances. + * Give it a good wack at probe time. Unfortunately, this + * needs to happen before we've had a chance to discover any + * quirk, or the system will be in a rather bad state. + */ + if (pdev->vendor == PCI_VENDOR_ID_RENESAS && + (pdev->device == 0x0014 || pdev->device == 0x0015)) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(usb_xhci_needs_pci_reset); diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 6559944801987728a1db6ba31f09db51b92362e3..5582cbafecd4c1a3ddc5443d6cc9182a9b9bc89f 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -15,6 +15,7 @@ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev); void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev); void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); void sb800_prefetch(struct device *dev, int on); +bool usb_xhci_needs_pci_reset(struct pci_dev *pdev); #else struct pci_dev; static inline void usb_amd_quirk_pll_disable(void) {} diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 7bf78be1fd32503571df68999197008c85b64879..5e5fc9d7d533d22952e41c780b23f7b9b2ca783f 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2312,7 +2312,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd) #define r8a66597_bus_resume NULL #endif -static struct hc_driver r8a66597_hc_driver = { +static const struct hc_driver r8a66597_hc_driver = { .description = hcd_name, .hcd_priv_size = sizeof(struct r8a66597), .irq = r8a66597_irq, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index fd2a11473be79921416597ae87489d4606d26f55..24ad1d6cec251e0a6d1f5c4b7cc0d3792b914144 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1554,7 +1554,7 @@ sl811h_start(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static struct hc_driver sl811h_hc_driver = { +static const struct hc_driver sl811h_hc_driver = { .description = hcd_name, .hcd_priv_size = sizeof(struct sl811), diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 43d52931b5bf3509c7ca6255ddb82aa7b7c5cb98..c38855aed62c7df6ef3c7e134eae2c9b0e787da2 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2941,7 +2941,7 @@ static int u132_bus_resume(struct usb_hcd *hcd) #define u132_bus_suspend NULL #define u132_bus_resume NULL #endif -static struct hc_driver u132_hc_driver = { +static const struct hc_driver u132_hc_driver = { .description = hcd_name, .hcd_priv_size = sizeof(struct u132), .irq = NULL, diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index 5b3603c360ab423bebfa03b2e3642571f3dd1807..cf84269c3e6dc2260794c40735c6ce78492a9d67 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -213,7 +213,7 @@ static void whc_endpoint_reset(struct usb_hcd *usb_hcd, } -static struct hc_driver whc_hc_driver = { +static const struct hc_driver whc_hc_driver = { .description = "whci-hcd", .product_desc = "Wireless host controller", .hcd_priv_size = sizeof(struct whc) - sizeof(struct usb_hcd), diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 00721e8807ab472f1e886fff791e7bbbaeec3a13..da9158f171cbeaa99fa1d91f4363c1d5d63a0f3d 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -112,7 +112,7 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, /* If PSI table exists, add the custom speed attributes from it */ if (usb3_1 && xhci->usb3_rhub.psi_count) { - u32 ssp_cap_base, bm_attrib, psi; + u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp; int offset; ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE; @@ -139,6 +139,15 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, for (i = 0; i < xhci->usb3_rhub.psi_count; i++) { psi = xhci->usb3_rhub.psi[i]; psi &= ~USB_SSP_SUBLINK_SPEED_RSVD; + psi_exp = XHCI_EXT_PORT_PSIE(psi); + psi_mant = XHCI_EXT_PORT_PSIM(psi); + + /* Shift to Gbps and set SSP Link BIT(14) if 10Gpbs */ + for (; psi_exp < 3; psi_exp++) + psi_mant /= 1000; + if (psi_mant >= 10) + psi |= BIT(14); + if ((psi & PLT_MASK) == PLT_SYM) { /* Symmetric, create SSA RX and TX from one PSI entry */ put_unaligned_le32(psi, &buf[offset]); @@ -1179,6 +1188,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; } + /* + * For xHCI 1.1 according to section 4.19.1.2.4.1 a + * root hub port's transition to compliance mode upon + * detecting LFPS timeout may be controlled by an + * Compliance Transition Enabled (CTE) flag (not + * software visible). This flag is set by writing 0xA + * to PORTSC PLS field which will allow transition to + * compliance mode the next time LFPS timeout is + * encountered. A warm reset will clear it. + * + * The CTE flag is only supported if the HCCPARAMS2 CTC + * flag is set, otherwise, the compliance substate is + * automatically entered as on 1.0 and prior. + */ + if (link_state == USB_SS_PORT_LS_COMP_MOD) { + if (!HCC2_CTC(xhci->hcc_params2)) { + xhci_dbg(xhci, "CTC flag is 0, port already supports entering compliance mode\n"); + break; + } + + if ((temp & PORT_CONNECT)) { + xhci_warn(xhci, "Can't set compliance mode when port is connected\n"); + goto error; + } + + xhci_dbg(xhci, "Enable compliance mode transition for port %d\n", + wIndex); + xhci_set_link_state(xhci, port_array, wIndex, + link_state); + temp = readl(port_array[wIndex]); + break; + } + /* Software should not attempt to set * port link state above '3' (U3) and the port * must be enabled. @@ -1473,9 +1515,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd) t2 |= PORT_WKOC_E | PORT_WKCONN_E; t2 &= ~PORT_WKDISC_E; } - if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && - (hcd->speed < HCD_USB3)) - t2 &= ~PORT_WAKE_BITS; } else t2 &= ~PORT_WAKE_BITS; @@ -1521,15 +1560,14 @@ static bool xhci_port_missing_cas_quirk(int port_index, int xhci_bus_resume(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int max_ports, port_index; - __le32 __iomem **port_array; struct xhci_bus_state *bus_state; - u32 temp; + __le32 __iomem **port_array; unsigned long flags; - unsigned long port_was_suspended = 0; - bool need_usb2_u3_exit = false; + int max_ports, port_index; int slot_id; int sret; + u32 next_state; + u32 temp, portsc; max_ports = xhci_get_ports(hcd, &port_array); bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -1548,68 +1586,77 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp &= ~CMD_EIE; writel(temp, &xhci->op_regs->command); + /* bus specific resume for ports we suspended at bus_suspend */ + if (hcd->speed >= HCD_USB3) + next_state = XDEV_U0; + else + next_state = XDEV_RESUME; + port_index = max_ports; while (port_index--) { - /* Check whether need resume ports. If needed - resume port and disable remote wakeup */ - u32 temp; - - temp = readl(port_array[port_index]); + portsc = readl(port_array[port_index]); /* warm reset CAS limited ports stuck in polling/compliance */ if ((xhci->quirks & XHCI_MISSING_CAS) && (hcd->speed >= HCD_USB3) && xhci_port_missing_cas_quirk(port_index, port_array)) { xhci_dbg(xhci, "reset stuck port %d\n", port_index); + clear_bit(port_index, &bus_state->bus_suspended); continue; } - if (DEV_SUPERSPEED_ANY(temp)) - temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); - else - temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - if (test_bit(port_index, &bus_state->bus_suspended) && - (temp & PORT_PLS_MASK)) { - set_bit(port_index, &port_was_suspended); - if (!DEV_SUPERSPEED_ANY(temp)) { - xhci_set_link_state(xhci, port_array, - port_index, XDEV_RESUME); - need_usb2_u3_exit = true; + /* resume if we suspended the link, and it is still suspended */ + if (test_bit(port_index, &bus_state->bus_suspended)) + switch (portsc & PORT_PLS_MASK) { + case XDEV_U3: + portsc = xhci_port_state_to_neutral(portsc); + portsc &= ~PORT_PLS_MASK; + portsc |= PORT_LINK_STROBE | next_state; + break; + case XDEV_RESUME: + /* resume already initiated */ + break; + default: + /* not in a resumeable state, ignore it */ + clear_bit(port_index, + &bus_state->bus_suspended); + break; } - } else - writel(temp, port_array[port_index]); - } - - if (need_usb2_u3_exit) { - spin_unlock_irqrestore(&xhci->lock, flags); - msleep(USB_RESUME_TIMEOUT); - spin_lock_irqsave(&xhci->lock, flags); + /* disable wake for all ports, write new link state if needed */ + portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); + writel(portsc, port_array[port_index]); } - port_index = max_ports; - while (port_index--) { - if (!(port_was_suspended & BIT(port_index))) - continue; - /* Clear PLC to poll it later after XDEV_U0 */ - xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC); - xhci_set_link_state(xhci, port_array, port_index, XDEV_U0); + /* USB2 specific resume signaling delay and U0 link state transition */ + if (hcd->speed < HCD_USB3) { + if (bus_state->bus_suspended) { + spin_unlock_irqrestore(&xhci->lock, flags); + msleep(USB_RESUME_TIMEOUT); + spin_lock_irqsave(&xhci->lock, flags); + } + for_each_set_bit(port_index, &bus_state->bus_suspended, + BITS_PER_LONG) { + /* Clear PLC to poll it later for U0 transition */ + xhci_test_and_clear_bit(xhci, port_array, port_index, + PORT_PLC); + xhci_set_link_state(xhci, port_array, port_index, + XDEV_U0); + } } - port_index = max_ports; - while (port_index--) { - if (!(port_was_suspended & BIT(port_index))) - continue; - /* Poll and Clear PLC */ + /* poll for U0 link state complete, both USB2 and USB3 */ + for_each_set_bit(port_index, &bus_state->bus_suspended, BITS_PER_LONG) { sret = xhci_handshake(port_array[port_index], PORT_PLC, PORT_PLC, 10 * 1000); - if (sret) + if (sret) { xhci_warn(xhci, "port %d resume PLC timeout\n", port_index); + continue; + } xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC); slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1); if (slot_id) xhci_ring_device(xhci, slot_id); } - (void) readl(&xhci->op_regs->command); bus_state->next_statechange = jiffies + msecs_to_jiffies(5); diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 67d5dc79b6b50e6fbaa30cddface8602dded27ee..8fb60657ed4fd7a73525fd949518fc6bf4119ac4 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -795,6 +795,7 @@ static const struct dev_pm_ops xhci_mtk_pm_ops = { #ifdef CONFIG_OF static const struct of_device_id mtk_xhci_of_match[] = { { .compatible = "mediatek,mt8173-xhci"}, + { .compatible = "mediatek,mtk-xhci"}, { }, }; MODULE_DEVICE_TABLE(of, mtk_xhci_of_match); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 5b0fa553c8bc940e88a6db731cf6dfeb0c9fb971..76f392954733631c7b660cc806d87736fb2d8d15 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -54,11 +54,6 @@ #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 -#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 -#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba -#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb -#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc - #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 static const char hcd_name[] = "xhci_hcd"; @@ -142,13 +137,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_AMD) xhci->quirks |= XHCI_TRUST_TX_LENGTH; - if ((pdev->vendor == PCI_VENDOR_ID_AMD) && - ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) - xhci->quirks |= XHCI_U2_DISABLE_WAKE; - if (pdev->vendor == PCI_VENDOR_ID_INTEL) { xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_INTEL_HOST; @@ -284,6 +272,13 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) driver = (struct hc_driver *)id->driver_data; + /* For some HW implementation, a XHCI reset is just not enough... */ + if (usb_xhci_needs_pci_reset(dev)) { + dev_info(&dev->dev, "Resetting\n"); + if (pci_reset_function_locked(dev)) + dev_warn(&dev->dev, "Reset failed"); + } + /* Prevent runtime suspending between USB-2 and USB-3 initialization */ pm_runtime_get_noresume(&dev->dev); diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c04144b25a673a2f2438854ea4183dd7cc0b0fab..1cb6eaef4ae14efcee09e5adfe0e913e4e54525c 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -107,14 +107,6 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { }; static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { - .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2, - .init_quirk = xhci_rcar_init_quirk, - .plat_start = xhci_rcar_start, - .resume_quirk = xhci_rcar_resume_quirk, -}; - -static const struct xhci_plat_priv xhci_plat_renesas_rcar_r8a7796 = { - .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3, .init_quirk = xhci_rcar_init_quirk, .plat_start = xhci_rcar_start, .resume_quirk = xhci_rcar_resume_quirk, @@ -145,7 +137,7 @@ static const struct of_device_id usb_xhci_of_match[] = { .data = &xhci_plat_renesas_rcar_gen3, }, { .compatible = "renesas,xhci-r8a7796", - .data = &xhci_plat_renesas_rcar_r8a7796, + .data = &xhci_plat_renesas_rcar_gen3, }, { .compatible = "renesas,rcar-gen2-xhci", .data = &xhci_plat_renesas_rcar_gen2, @@ -186,14 +178,18 @@ static int xhci_plat_probe(struct platform_device *pdev) * 2. xhci_plat is child of a device from firmware (dwc3-plat) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; #ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && - sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; + else if (sysdev->bus == &pci_bus_type) + break; #endif + } + + if (!sysdev) + sysdev = &pdev->dev; /* Try to set 64-bit DMA first */ if (WARN_ON(!sysdev->dma_mask)) diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 07278228214b80066df2ea32a5828fdf1066f34d..198bc188ab255058111e7cd44c9a96cdfbd69180 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -13,13 +13,15 @@ #include #include #include +#include #include "xhci.h" #include "xhci-plat.h" #include "xhci-rcar.h" /* -* - The V3 firmware is for r8a7796 (with good performance). +* - The V3 firmware is for r8a7796 (with good performance) and r8a7795 es2.0 +* or later. * - The V2 firmware can be used on both r8a7795 (es1.x) and r8a7796. * - The V2 firmware is possible to use on R-Car Gen2. However, the V2 causes * performance degradation. So, this driver continues to use the V1 if R-Car @@ -67,6 +69,26 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3); #define RCAR_USB3_RX_POL_VAL BIT(21) #define RCAR_USB3_TX_POL_VAL BIT(4) +/* For soc_device_attribute */ +#define RCAR_XHCI_FIRMWARE_V2 BIT(0) /* FIRMWARE V2 */ +#define RCAR_XHCI_FIRMWARE_V3 BIT(1) /* FIRMWARE V3 */ + +static const struct soc_device_attribute rcar_quirks_match[] = { + { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = (void *)RCAR_XHCI_FIRMWARE_V2, + }, + { + .soc_id = "r8a7795", + .data = (void *)RCAR_XHCI_FIRMWARE_V3, + }, + { + .soc_id = "r8a7796", + .data = (void *)RCAR_XHCI_FIRMWARE_V3, + }, + { /* sentinel */ }, +}; + static void xhci_rcar_start_gen2(struct usb_hcd *hcd) { /* LCLK Select */ @@ -122,9 +144,23 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd) int retval, index, j, time; int timeout = 10000; u32 data, val, temp; + u32 quirks = 0; + const struct soc_device_attribute *attr; + const char *firmware_name; + + attr = soc_device_match(rcar_quirks_match); + if (attr) + quirks = (uintptr_t)attr->data; + + if (quirks & RCAR_XHCI_FIRMWARE_V2) + firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2; + else if (quirks & RCAR_XHCI_FIRMWARE_V3) + firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3; + else + firmware_name = priv->firmware_name; /* request R-Car USB3.0 firmware */ - retval = request_firmware(&fw, priv->firmware_name, dev); + retval = request_firmware(&fw, firmware_name, dev); if (retval) return retval; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cc368ad2b51e44c731a2926902f78de830e2f17a..a9443651ce0f32c4fafff6cdd7659a187f9923cd 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1572,7 +1572,7 @@ static void handle_port_status(struct xhci_hcd *xhci, { struct usb_hcd *hcd; u32 port_id; - u32 temp, temp1; + u32 portsc, cmd_reg; int max_ports; int slot_id; unsigned int faked_port_index; @@ -1636,26 +1636,28 @@ static void handle_port_status(struct xhci_hcd *xhci, /* Find the faked port hub number */ faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci, port_id); + portsc = readl(port_array[faked_port_index]); + + trace_xhci_handle_port_status(faked_port_index, portsc); - temp = readl(port_array[faked_port_index]); if (hcd->state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, "resume root hub\n"); usb_hcd_resume_root_hub(hcd); } - if (hcd->speed >= HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE) + if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) bus_state->port_remote_wakeup &= ~(1 << faked_port_index); - if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) { + if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) { xhci_dbg(xhci, "port resume event for port %d\n", port_id); - temp1 = readl(&xhci->op_regs->command); - if (!(temp1 & CMD_RUN)) { + cmd_reg = readl(&xhci->op_regs->command); + if (!(cmd_reg & CMD_RUN)) { xhci_warn(xhci, "xHC is not running.\n"); goto cleanup; } - if (DEV_SUPERSPEED_ANY(temp)) { + if (DEV_SUPERSPEED_ANY(portsc)) { xhci_dbg(xhci, "remote wake SS port %d\n", port_id); /* Set a flag to say the port signaled remote wakeup, * so we can tell the difference between the end of @@ -1683,8 +1685,8 @@ static void handle_port_status(struct xhci_hcd *xhci, } } - if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 && - DEV_SUPERSPEED_ANY(temp)) { + if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_U0 && + DEV_SUPERSPEED_ANY(portsc)) { xhci_dbg(xhci, "resume SS port %d finished\n", port_id); /* We've just brought the device into U0 through either the * Resume state after a device remote wakeup, or through the @@ -1714,7 +1716,7 @@ static void handle_port_status(struct xhci_hcd *xhci, * RExit to a disconnect state). If so, let the the driver know it's * out of the RExit state. */ - if (!DEV_SUPERSPEED_ANY(temp) && + if (!DEV_SUPERSPEED_ANY(portsc) && test_and_clear_bit(faked_port_index, &bus_state->rexit_ports)) { complete(&bus_state->rexit_done[faked_port_index]); diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index 8ce96de10e8a1cb0adbb1eb61b7abe3e5b084573..f20753b9962476b6bb9a1853c88fc33f0786bfcf 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -453,6 +453,29 @@ DEFINE_EVENT(xhci_log_ring, xhci_inc_deq, TP_PROTO(struct xhci_ring *ring), TP_ARGS(ring) ); + +DECLARE_EVENT_CLASS(xhci_log_portsc, + TP_PROTO(u32 portnum, u32 portsc), + TP_ARGS(portnum, portsc), + TP_STRUCT__entry( + __field(u32, portnum) + __field(u32, portsc) + ), + TP_fast_assign( + __entry->portnum = portnum; + __entry->portsc = portsc; + ), + TP_printk("port-%d: %s", + __entry->portnum, + xhci_decode_portsc(__entry->portsc) + ) +); + +DEFINE_EVENT(xhci_log_portsc, xhci_handle_port_status, + TP_PROTO(u32 portnum, u32 portsc), + TP_ARGS(portnum, portsc) +); + #endif /* __XHCI_TRACE_H */ /* this part must be outside header guard */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b2ff1ff1a02faff066374cafdf9fa5b531db5b81..ee198ea47f49e8dd1ddbc4aa0d9b50d58d516c86 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1703,7 +1703,8 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, if (xhci->quirks & XHCI_MTK_HOST) { ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); if (ret < 0) { - xhci_free_endpoint_ring(xhci, virt_dev, ep_index); + xhci_ring_free(xhci, virt_dev->eps[ep_index].new_ring); + virt_dev->eps[ep_index].new_ring = NULL; return ret; } } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e3e935291ed6fcb57be0402000a4beac6161a9ce..2b48aa4f6b767935c64bc66855e43195dce5b2b9 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -311,12 +311,19 @@ struct xhci_op_regs { */ #define PORT_PLS_MASK (0xf << 5) #define XDEV_U0 (0x0 << 5) +#define XDEV_U1 (0x1 << 5) #define XDEV_U2 (0x2 << 5) #define XDEV_U3 (0x3 << 5) +#define XDEV_DISABLED (0x4 << 5) +#define XDEV_RXDETECT (0x5 << 5) #define XDEV_INACTIVE (0x6 << 5) #define XDEV_POLLING (0x7 << 5) -#define XDEV_COMP_MODE (0xa << 5) +#define XDEV_RECOVERY (0x8 << 5) +#define XDEV_HOT_RESET (0x9 << 5) +#define XDEV_COMP_MODE (0xa << 5) +#define XDEV_TEST_MODE (0xb << 5) #define XDEV_RESUME (0xf << 5) + /* true: port has power (see HCC_PPC) */ #define PORT_POWER (1 << 9) /* bits 10:13 indicate device speed: @@ -728,6 +735,8 @@ struct xhci_ep_ctx { #define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) /* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */ #define EP_HAS_LSA (1 << 15) +/* hosts with LEC=1 use bits 31:24 as ESIT high bits. */ +#define CTX_TO_MAX_ESIT_PAYLOAD_HI(p) (((p) >> 24) & 0xff) /* ep_info2 bitmasks */ /* @@ -1674,7 +1683,7 @@ struct xhci_bus_state { static inline unsigned int hcd_index(struct usb_hcd *hcd) { - if (hcd->speed == HCD_USB3) + if (hcd->speed >= HCD_USB3) return 0; else return 1; @@ -1819,7 +1828,7 @@ struct xhci_hcd { /* For controller with a broken Port Disable implementation */ #define XHCI_BROKEN_PORT_PED (1 << 25) #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) -#define XHCI_U2_DISABLE_WAKE (1 << 27) +/* Reserved. It was XHCI_U2_DISABLE_WAKE */ #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) unsigned int num_active_eps; @@ -2392,6 +2401,87 @@ static inline const char *xhci_decode_slot_context(u32 info, u32 info2, return str; } + +static inline const char *xhci_portsc_link_state_string(u32 portsc) +{ + switch (portsc & PORT_PLS_MASK) { + case XDEV_U0: + return "U0"; + case XDEV_U1: + return "U1"; + case XDEV_U2: + return "U2"; + case XDEV_U3: + return "U3"; + case XDEV_DISABLED: + return "Disabled"; + case XDEV_RXDETECT: + return "RxDetect"; + case XDEV_INACTIVE: + return "Inactive"; + case XDEV_POLLING: + return "Polling"; + case XDEV_RECOVERY: + return "Recovery"; + case XDEV_HOT_RESET: + return "Hot Reset"; + case XDEV_COMP_MODE: + return "Compliance mode"; + case XDEV_TEST_MODE: + return "Test mode"; + case XDEV_RESUME: + return "Resume"; + default: + break; + } + return "Unknown"; +} + +static inline const char *xhci_decode_portsc(u32 portsc) +{ + static char str[256]; + int ret; + + ret = sprintf(str, "%s %s %s Link:%s ", + portsc & PORT_POWER ? "Powered" : "Powered-off", + portsc & PORT_CONNECT ? "Connected" : "Not-connected", + portsc & PORT_PE ? "Enabled" : "Disabled", + xhci_portsc_link_state_string(portsc)); + + if (portsc & PORT_OC) + ret += sprintf(str + ret, "OverCurrent "); + if (portsc & PORT_RESET) + ret += sprintf(str + ret, "In-Reset "); + + ret += sprintf(str + ret, "Change: "); + if (portsc & PORT_CSC) + ret += sprintf(str + ret, "CSC "); + if (portsc & PORT_PEC) + ret += sprintf(str + ret, "PEC "); + if (portsc & PORT_WRC) + ret += sprintf(str + ret, "WRC "); + if (portsc & PORT_OCC) + ret += sprintf(str + ret, "OCC "); + if (portsc & PORT_RC) + ret += sprintf(str + ret, "PRC "); + if (portsc & PORT_PLC) + ret += sprintf(str + ret, "PLC "); + if (portsc & PORT_CEC) + ret += sprintf(str + ret, "CEC "); + if (portsc & PORT_CAS) + ret += sprintf(str + ret, "CAS "); + + ret += sprintf(str + ret, "Wake: "); + if (portsc & PORT_WKCONN_E) + ret += sprintf(str + ret, "WCE "); + if (portsc & PORT_WKDISC_E) + ret += sprintf(str + ret, "WDE "); + if (portsc & PORT_WKOC_E) + ret += sprintf(str + ret, "WOE "); + + return str; +} + static inline const char *xhci_ep_state_string(u8 state) { switch (state) { @@ -2452,8 +2542,8 @@ static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq, u8 lsa; u8 hid; - esit = EP_MAX_ESIT_PAYLOAD_HI(info) << 16 | - EP_MAX_ESIT_PAYLOAD_LO(tx_info); + esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 | + CTX_TO_MAX_ESIT_PAYLOAD(tx_info); ep_state = info & EP_STATE_MASK; max_pstr = info & EP_MAXPSTREAMS_MASK; diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index a4dbb0cd80da191b2d5e7e541c007f2fd1b23b76..0b21ba757bba4a6dc0323dc1ae52d8972a52187d 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -137,10 +137,6 @@ #include "microtek.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v0.4.3" #define DRIVER_AUTHOR "John Fremlin , Oliver Neukum " #define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver" diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index ac31d19cc54bcee01cbde7e850d5744e53542777..8e59e0c02b8a421ecd6f2b88e75afc4001fde0e2 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -396,7 +396,6 @@ static int handshake(struct usb_hcd *hcd, u32 reg, /* reset a non-running (STS_HALT == 1) controller */ static int ehci_reset(struct usb_hcd *hcd) { - int retval; struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 command = reg_read32(hcd->regs, HC_USBCMD); @@ -405,9 +404,8 @@ static int ehci_reset(struct usb_hcd *hcd) reg_write32(hcd->regs, HC_USBCMD, command); hcd->state = HC_STATE_HALT; priv->next_statechange = jiffies; - retval = handshake(hcd, HC_USBCMD, - CMD_RESET, 0, 250 * 1000); - return retval; + + return handshake(hcd, HC_USBCMD, CMD_RESET, 0, 250 * 1000); } static struct isp1760_qh *qh_alloc(gfp_t flags) diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index dfd54ea4808faa1efbd98921887cf29b3bd3f1d3..1c0ada75c35d7f61f1a21945abe12c4915a17c0f 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -29,8 +29,6 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v0.0.13" #define DRIVER_AUTHOR "John Homppi" #define DRIVER_DESC "adutux (see www.ontrak.net)" diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index 15d4e64d3b65277df6e9e5ac79454a9320d9d108..abec6e604a62e2dafd1ee284fb2de416938125e7 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -42,12 +42,10 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data, dev_err(&(usb_if)->dev, format, ## arg) /* Version Information */ -#define DRIVER_VERSION "v0.1" #define DRIVER_AUTHOR "Keith Packard, keithp@keithp.com" #define DRIVER_DESC "Altus Metrum ChaosKey driver" #define DRIVER_SHORT "chaoskey" -MODULE_VERSION(DRIVER_VERSION); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 9d8bb8dacdcd114691ad36f5c9576982b6c2654f..63207c42acf610461c59762977bdf30ffc3468e8 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -20,7 +20,6 @@ #include #include -#define DRIVER_VERSION "v1.0" #define DRIVER_AUTHOR "Erik Rigtorp" #define DRIVER_DESC "Cypress USB Thermometer driver" diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 8291499d058178a27b3b951427e8ef5cf2fcb907..424ff12f3b51fe9cf66ae5e34a194bb78df38161 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -305,9 +305,9 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi); static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi); static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi) { - int result; if (ftdi->platform_dev.dev.parent) return -EBUSY; + ftdi_elan_get_kref(ftdi); ftdi->platform_data.potpg = 100; ftdi->platform_data.reset = NULL; @@ -324,8 +324,8 @@ static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi) request_module("u132_hcd"); dev_info(&ftdi->udev->dev, "registering '%s'\n", ftdi->platform_dev.name); - result = platform_device_register(&ftdi->platform_dev); - return result; + + return platform_device_register(&ftdi->platform_dev); } static void ftdi_elan_abandon_completions(struct usb_ftdi *ftdi) @@ -857,7 +857,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, target->actual = 0; target->non_null = (ed_length >> 15) & 0x0001; target->repeat_number = (ed_length >> 11) & 0x000F; - if (ed_type == 0x02) { + if (ed_type == 0x02 || ed_type == 0x03) { if (payload == 0 || target->abandoning > 0) { target->abandoning = 0; mutex_unlock(&ftdi->u132_lock); @@ -873,31 +873,6 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, mutex_unlock(&ftdi->u132_lock); return b; } - } else if (ed_type == 0x03) { - if (payload == 0 || target->abandoning > 0) { - target->abandoning = 0; - mutex_unlock(&ftdi->u132_lock); - ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, - payload); - ftdi->received = 0; - ftdi->expected = 4; - ftdi->ed_found = 0; - return ftdi->response; - } else { - ftdi->expected = 4 + payload; - ftdi->ed_found = 1; - mutex_unlock(&ftdi->u132_lock); - return b; - } - } else if (ed_type == 0x01) { - target->abandoning = 0; - mutex_unlock(&ftdi->u132_lock); - ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, - payload); - ftdi->received = 0; - ftdi->expected = 4; - ftdi->ed_found = 0; - return ftdi->response; } else { target->abandoning = 0; mutex_unlock(&ftdi->u132_lock); diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 81fcbf024c65837cb38f03ebed5124dfba1e40c2..39d8fedfaf3bf477b576b5ec1013858fe7af3fa6 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -33,8 +33,6 @@ #define HEADER "P5 225 289 255 " #define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1) -/* version information */ -#define DRIVER_VERSION "0.6" #define DRIVER_SHORT "idmouse" #define DRIVER_AUTHOR "Florian 'Floe' Echtler " #define DRIVER_DESC "Siemens ID Mouse FingerTIP Sensor Driver" diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 7ca4c7e0ea0ded0a651707546dc3eb04e71cc7bb..be588130368108de34109260594a2bc81efc815c 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -21,10 +21,8 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v0.4.0" #define DRIVER_AUTHOR "Christian Lucht " -#define DRIVER_DESC "USB IO-Warrior driver (Linux 2.6.x)" +#define DRIVER_DESC "USB IO-Warrior driver" #define USB_VENDOR_ID_CODEMERCS 1984 /* low speed iowarrior */ diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 9d9487c66f87a21e4a62b88250cdbc97e1e92313..680bddb3ce0593c793f8428302bfabf21427d667 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -112,7 +112,6 @@ static const struct usb_device_id ld_usb_table[] = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ld_usb_table); -MODULE_VERSION("V0.14"); MODULE_AUTHOR("Michael Hund "); MODULE_DESCRIPTION("LD USB Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 0782ac6f5edfaa0542dfe173bd6969c8bba77372..5628f678ab594810dceb607eb7a7424cc96f1675 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -88,8 +88,6 @@ #include -/* Version Information */ -#define DRIVER_VERSION "v0.96" #define DRIVER_AUTHOR "Juergen Stuber " #define DRIVER_DESC "LEGO USB Tower Driver" diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 2142132a1f82ee93881f3f938fa5f69352d2648d..ddddd6387f6642e5792479c535adf347f2bfb962 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c @@ -178,6 +178,25 @@ static ssize_t hot_reset_store(struct device *dev, } static DEVICE_ATTR_WO(hot_reset); +static ssize_t warm_reset_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_device *hdev = interface_to_usbdev(intf); + struct lvs_rh *lvs = usb_get_intfdata(intf); + int ret; + + ret = lvs_rh_set_port_feature(hdev, lvs->portnum, + USB_PORT_FEAT_BH_PORT_RESET); + if (ret < 0) { + dev_err(dev, "can't issue warm reset %d\n", ret); + return ret; + } + + return count; +} +static DEVICE_ATTR_WO(warm_reset); + static ssize_t u2_timeout_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -274,13 +293,35 @@ static ssize_t get_dev_desc_store(struct device *dev, } static DEVICE_ATTR_WO(get_dev_desc); +static ssize_t enable_compliance_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_device *hdev = interface_to_usbdev(intf); + struct lvs_rh *lvs = usb_get_intfdata(intf); + int ret; + + ret = lvs_rh_set_port_feature(hdev, + lvs->portnum | USB_SS_PORT_LS_COMP_MOD << 3, + USB_PORT_FEAT_LINK_STATE); + if (ret < 0) { + dev_err(dev, "can't enable compliance mode %d\n", ret); + return ret; + } + + return count; +} +static DEVICE_ATTR_WO(enable_compliance); + static struct attribute *lvs_attributes[] = { &dev_attr_get_dev_desc.attr, &dev_attr_u1_timeout.attr, &dev_attr_u2_timeout.attr, &dev_attr_hot_reset.attr, + &dev_attr_warm_reset.attr, &dev_attr_u3_entry.attr, &dev_attr_u3_exit.attr, + &dev_attr_enable_compliance.attr, NULL }; diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index b106ce76997bff2166100fb253afe8b02cc889f9..ddfebb144aaa44fd928c3177d378628a5538f6bc 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -43,10 +43,6 @@ #include "rio500_usb.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1" #define DRIVER_AUTHOR "Cesar Miquel " #define DRIVER_DESC "USB Rio 500 driver" diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 440d7fef58cc6d18f1b7e55f96ddba63b0a97043..30774e0aeadde4b88903ef688881ced60108ea03 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -610,13 +610,11 @@ static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type, u32 addr, u8 data) { struct sisusb_packet packet; - int ret; packet.header = (1 << (addr & 3)) | (type << 6); packet.address = addr & ~3; packet.data = data << ((addr & 3) << 3); - ret = sisusb_send_packet(sisusb, 10, &packet); - return ret; + return sisusb_send_packet(sisusb, 10, &packet); } static int sisusb_write_memio_word(struct sisusb_usb_data *sisusb, int type, @@ -1333,13 +1331,11 @@ static int sisusb_write_pci_config(struct sisusb_usb_data *sisusb, int regnum, u32 data) { struct sisusb_packet packet; - int ret; packet.header = 0x008f; packet.address = regnum | 0x10000; packet.data = data; - ret = sisusb_send_packet(sisusb, 10, &packet); - return ret; + return sisusb_send_packet(sisusb, 10, &packet); } static int sisusb_read_pci_config(struct sisusb_usb_data *sisusb, @@ -2982,14 +2978,11 @@ static long sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static long sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { - long retval; - switch (cmd) { case SISUSB_GET_CONFIG_SIZE: case SISUSB_GET_CONFIG: case SISUSB_COMMAND: - retval = sisusb_ioctl(f, cmd, arg); - return retval; + return sisusb_ioctl(f, cmd, arg); default: return -ENOIOCTLCMD; diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 9795457723d86cfbed9563c9d0c454575010cd11..1862ed15ce280087a6ea267d74cc6177e0004cd8 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -25,8 +25,6 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v1.1" #define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org" #define DRIVER_DESC "PlayStation 2 Trance Vibrator driver" diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index 91f66d68bcb7b55bd000e18ad551d8b6bc27ff7c..135c91c434bfb878d170011580ec6d275fc48368 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -114,7 +114,6 @@ #define DRIVER_NAME "usb251xb" #define DRIVER_DESC "Microchip USB 2.0 Hi-Speed Hub Controller" -#define DRIVER_VERSION "1.0" struct usb251xb { struct device *dev; diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 388fae6373db4dc27fad05f03e086c8558ba9852..3f6a28045b53809dc3b707031482144faf3dd38e 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -330,7 +330,7 @@ static struct attribute *dev_attrs[] = { NULL }; -static struct attribute_group dev_attr_grp = { +static const struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 5947373700a197a4e62bb62bbf5940c33271d610..8a13b2fcf3e135d0403f1e6d40641906e45277f9 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -52,10 +52,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v0.6" #define DRIVER_AUTHOR "Thomas M. Sailer, t.sailer@alumni.ethz.ch" #define DRIVER_DESC "USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip" @@ -816,8 +812,7 @@ static int __init uss720_init(void) if (retval) goto out; - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose " "driver to allow nonstandard\n"); printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over " diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 7b6dc23d77e9af22bc373f28ba1c1313e4eb1faa..b26fffc58446d5d77f49af755cf5faf2a225c26f 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -288,6 +288,7 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev) * MTU3_U3_IP_SLOT_DEFAULT for U3 IP * @may_wakeup: means device's remote wakeup is enabled * @is_self_powered: is reported in device status and the config descriptor + * @delayed_status: true when function drivers ask for delayed status * @ep0_req: dummy request used while handling standard USB requests * for GET_STATUS and SET_SEL * @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests @@ -327,6 +328,7 @@ struct mtu3 { unsigned u1_enable:1; unsigned u2_enable:1; unsigned is_u3_ip:1; + unsigned delayed_status:1; u8 address; u8 test_mode_nr; diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 11a0d3b84c5eaef31217fd0645edf197ed2f29da..560256115b23975e7d8f3c0ab0c3d6dea17df092 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -322,23 +322,65 @@ static const struct file_operations ssusb_mode_fops = { .release = single_release, }; +static int ssusb_vbus_show(struct seq_file *sf, void *unused) +{ + struct ssusb_mtk *ssusb = sf->private; + struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + + seq_printf(sf, "vbus state: %s\n(echo on/off)\n", + regulator_is_enabled(otg_sx->vbus) ? "on" : "off"); + + return 0; +} + +static int ssusb_vbus_open(struct inode *inode, struct file *file) +{ + return single_open(file, ssusb_vbus_show, inode->i_private); +} + +static ssize_t ssusb_vbus_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *sf = file->private_data; + struct ssusb_mtk *ssusb = sf->private; + struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + char buf[16]; + bool enable; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (kstrtobool(buf, &enable)) { + dev_err(ssusb->dev, "wrong setting\n"); + return -EINVAL; + } + + ssusb_set_vbus(otg_sx, enable); + + return count; +} + +static const struct file_operations ssusb_vbus_fops = { + .open = ssusb_vbus_open, + .write = ssusb_vbus_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static void ssusb_debugfs_init(struct ssusb_mtk *ssusb) { struct dentry *root; - struct dentry *file; root = debugfs_create_dir(dev_name(ssusb->dev), usb_debug_root); - if (IS_ERR_OR_NULL(root)) { - if (!root) - dev_err(ssusb->dev, "create debugfs root failed\n"); + if (!root) { + dev_err(ssusb->dev, "create debugfs root failed\n"); return; } ssusb->dbgfs_root = root; - file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, - ssusb, &ssusb_mode_fops); - if (!file) - dev_dbg(ssusb->dev, "create debugfs mode failed\n"); + debugfs_create_file("mode", 0644, root, ssusb, &ssusb_mode_fops); + debugfs_create_file("vbus", 0644, root, ssusb, &ssusb_vbus_fops); } static void ssusb_debugfs_exit(struct ssusb_mtk *ssusb) diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c index 9dd2441b4fa1a2f82d605522f4f8415574fe0cab..434fca58143c66b0050434971de49b6ef7a4ca0d 100644 --- a/drivers/usb/mtu3/mtu3_gadget.c +++ b/drivers/usb/mtu3/mtu3_gadget.c @@ -663,6 +663,7 @@ int mtu3_gadget_setup(struct mtu3 *mtu) mtu->g.sg_supported = 0; mtu->g.name = MTU3_DRIVER_NAME; mtu->is_active = 0; + mtu->delayed_status = false; mtu3_gadget_init_eps(mtu); @@ -727,4 +728,7 @@ void mtu3_gadget_reset(struct mtu3 *mtu) mtu->address = 0; mtu->ep0_state = MU3D_EP0_STATE_SETUP; mtu->may_wakeup = 0; + mtu->u1_enable = 0; + mtu->u2_enable = 0; + mtu->delayed_status = false; } diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c b/drivers/usb/mtu3/mtu3_gadget_ep0.c index 2d7427b48775663a68f2f12226112db10f6c29a4..958d74dd2b789593f06c7744def111b76a38424d 100644 --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c @@ -16,6 +16,8 @@ * */ +#include + #include "mtu3.h" /* ep0 is always mtu3->in_eps[0] */ @@ -150,6 +152,7 @@ static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy) csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL; mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr); + mtu->delayed_status = false; mtu->ep0_state = MU3D_EP0_STATE_SETUP; dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n", @@ -656,6 +659,9 @@ __acquires(mtu->lock) finish: if (mtu->test_mode) { ; /* nothing to do */ + } else if (handled == USB_GADGET_DELAYED_STATUS) { + /* handle the delay STATUS phase till receive ep_queue on ep0 */ + mtu->delayed_status = true; } else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */ mtu3_writel(mbase, U3D_EP0CSR, @@ -775,9 +781,6 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq) dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__, mep->name, decode_ep0_state(mtu), mreq->request.length); - if (!list_empty(&mep->req_list)) - return -EBUSY; - switch (mtu->ep0_state) { case MU3D_EP0_STATE_SETUP: case MU3D_EP0_STATE_RX: /* control-OUT data */ @@ -789,6 +792,20 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq) return -EINVAL; } + if (mtu->delayed_status) { + u32 csr; + + mtu->delayed_status = false; + csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS; + csr |= EP0_SETUPPKTRDY | EP0_DATAEND; + mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr); + /* needn't giveback the request for handling delay STATUS */ + return 0; + } + + if (!list_empty(&mep->req_list)) + return -EBUSY; + list_add_tail(&mreq->list, &mep->req_list); /* sequence #1, IN ... start writing the data */ diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c index cd4d0108785553bcdc33f80c789247b077b70281..e42d308b8dc2b7d573ceeec517f1129c72baf969 100644 --- a/drivers/usb/mtu3/mtu3_host.c +++ b/drivers/usb/mtu3/mtu3_host.c @@ -258,8 +258,8 @@ int ssusb_host_init(struct ssusb_mtk *ssusb, struct device_node *parent_dn) ret = of_platform_populate(parent_dn, NULL, NULL, parent_dev); if (ret) { - dev_dbg(parent_dev, "failed to create child devices at %s\n", - parent_dn->full_name); + dev_dbg(parent_dev, "failed to create child devices at %pOF\n", + parent_dn); return ret; } diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h index 212367295276a02b2592887bb70b7daf433153ed..06b29664470f11e2de1efbff5e6f1dcf16bfde42 100644 --- a/drivers/usb/mtu3/mtu3_hw_regs.h +++ b/drivers/usb/mtu3/mtu3_hw_regs.h @@ -462,10 +462,12 @@ #define SSUSB_U3_PORT_DIS BIT(0) /* U3D_SSUSB_U2_CTRL_0P */ +#define SSUSB_U2_PORT_VBUSVALID BIT(9) #define SSUSB_U2_PORT_OTG_SEL BIT(7) -#define SSUSB_U2_PORT_HOST_SEL BIT(2) +#define SSUSB_U2_PORT_HOST BIT(2) #define SSUSB_U2_PORT_PDN BIT(1) #define SSUSB_U2_PORT_DIS BIT(0) +#define SSUSB_U2_PORT_HOST_SEL (SSUSB_U2_PORT_VBUSVALID | SSUSB_U2_PORT_HOST) /* U3D_SSUSB_DEV_RST_CTRL */ #define SSUSB_DEV_SW_RST BIT(0) diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index 0d3ebb353e0828ce5f28e4ce0446956e1c11eba3..088e3e685c4f953b27c6fa67652b8da74c19f6fd 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -500,6 +500,7 @@ static const struct dev_pm_ops mtu3_pm_ops = { static const struct of_device_id mtu3_of_match[] = { {.compatible = "mediatek,mt8173-mtu3",}, + {.compatible = "mediatek,mtu3",}, {}, }; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 87cbd56cc7611d97476c17069090ca3b5f476b31..029692053dd3a4e50d47742751d3697f6e4d7a1e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1156,8 +1156,8 @@ static struct musb_fifo_cfg mode_2_cfg[] = { { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, }, -{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, }, -{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, }, +{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 960, }, +{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 1024, }, }; /* mode 3 - fits in 4KB */ @@ -2671,6 +2671,13 @@ static int musb_suspend(struct device *dev) { struct musb *musb = dev_to_musb(dev); unsigned long flags; + int ret; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } musb_platform_disable(musb); musb_disable_interrupts(musb); @@ -2721,14 +2728,6 @@ static int musb_resume(struct device *dev) if ((devctl & mask) != (musb->context.devctl & mask)) musb->port1_status = 0; - /* - * The USB HUB code expects the device to be in RPM_ACTIVE once it came - * out of suspend - */ - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - musb_start(musb); spin_lock_irqsave(&musb->lock, flags); @@ -2738,6 +2737,9 @@ static int musb_resume(struct device *dev) error); spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; } diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 9f22c5b8ce37dacd4e6012cc240f8711f65e576e..c748f4ac1154428428eee6853cd37c816a2ea910 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -465,6 +465,30 @@ static inline struct musb *gadget_to_musb(struct usb_gadget *g) return container_of(g, struct musb, g); } +static inline char *musb_ep_xfertype_string(u8 type) +{ + char *s; + + switch (type) { + case USB_ENDPOINT_XFER_CONTROL: + s = "ctrl"; + break; + case USB_ENDPOINT_XFER_ISOC: + s = "iso"; + break; + case USB_ENDPOINT_XFER_BULK: + s = "bulk"; + break; + case USB_ENDPOINT_XFER_INT: + s = "int"; + break; + default: + s = ""; + break; + } + return s; +} + #ifdef CONFIG_BLACKFIN static inline int musb_read_fifosize(struct musb *musb, struct musb_hw_ep *hw_ep, u8 epnum) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index bc6a9be2ccc55696cb703f04b97e3d0fb08ca59c..f6b526606ad1092494f3d8eaac6946bd77069ad2 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -1015,13 +1015,20 @@ static int dsps_suspend(struct device *dev) const struct dsps_musb_wrapper *wrp = glue->wrp; struct musb *musb = platform_get_drvdata(glue->musb); void __iomem *mbase; - - del_timer_sync(&glue->timer); + int ret; if (!musb) /* This can happen if the musb device is in -EPROBE_DEFER */ return 0; + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } + + del_timer_sync(&glue->timer); + mbase = musb->ctrl_base; glue->context.control = musb_readl(mbase, wrp->control); glue->context.epintr = musb_readl(mbase, wrp->epintr_set); @@ -1060,6 +1067,8 @@ static int dsps_resume(struct device *dev) musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) dsps_mod_timer(glue, -1); + pm_runtime_put(dev); + return 0; } #endif diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 1acc4864f9f6f0bf52cb5a084475fdab13bbab07..bc6d1717c9ec4d48bbfa61c35cabe740a0612365 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1105,11 +1105,7 @@ static int musb_gadget_enable(struct usb_ep *ep, pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n", musb_driver_name, musb_ep->end_point.name, - ({ char *s; switch (musb_ep->type) { - case USB_ENDPOINT_XFER_BULK: s = "bulk"; break; - case USB_ENDPOINT_XFER_INT: s = "int"; break; - default: s = "iso"; break; - } s; }), + musb_ep_xfertype_string(musb_ep->type), musb_ep->is_in ? "IN" : "OUT", musb_ep->dma ? "dma, " : "", musb_ep->packet_sz); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 76decb8011ebc2d37d3e7e64a394bd2bb6e5c8ba..b17450a598826eeb65915f7373fb10fdcd21b03c 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -139,6 +139,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) "Could not flush host TX%d fifo: csr: %04x\n", ep->epnum, csr)) return; + mdelay(1); } } @@ -2151,6 +2152,10 @@ static int musb_schedule( (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4; goto success; } else if (best_end < 0) { + dev_err(musb->controller, + "%s hwep alloc failed for %dx%d\n", + musb_ep_xfertype_string(qh->type), + qh->hb_mult, qh->maxpacket); return -ENOSPC; } @@ -2243,6 +2248,10 @@ static int musb_urb_enqueue( ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx) || (usb_pipeout(urb->pipe) && musb->hb_iso_tx); if (!ok) { + dev_err(musb->controller, + "high bandwidth %s (%dx%d) not supported\n", + musb_ep_xfertype_string(qh->type), + qh->hb_mult, qh->maxpacket & 0x7ff); ret = -EMSGSIZE; goto done; } diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index 042c5a8fd423d84a8a66418b227fabb0d60ef03a..c6052c814bcc24bb51bd4c1a82de48cfb8719de9 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -96,7 +96,7 @@ struct isp1301 { #if IS_REACHABLE(CONFIG_TPS65010) -#include +#include #else diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 8fb86a5f458e01275186dc83ff86e38b38fff35b..3d0dd2f9741571423522ee80c972d8db2ffec853 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -197,6 +197,7 @@ struct msm_otg { struct regulator *v3p3; struct regulator *v1p8; struct regulator *vddcx; + struct regulator_bulk_data supplies[3]; struct reset_control *phy_rst; struct reset_control *link_rst; @@ -1731,7 +1732,6 @@ static int msm_otg_reboot_notify(struct notifier_block *this, static int msm_otg_probe(struct platform_device *pdev) { - struct regulator_bulk_data regs[3]; int ret = 0; struct device_node *np = pdev->dev.of_node; struct msm_otg_platform_data *pdata; @@ -1817,17 +1817,18 @@ static int msm_otg_probe(struct platform_device *pdev) return motg->irq; } - regs[0].supply = "vddcx"; - regs[1].supply = "v3p3"; - regs[2].supply = "v1p8"; + motg->supplies[0].supply = "vddcx"; + motg->supplies[1].supply = "v3p3"; + motg->supplies[2].supply = "v1p8"; - ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); + ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(motg->supplies), + motg->supplies); if (ret) return ret; - motg->vddcx = regs[0].consumer; - motg->v3p3 = regs[1].consumer; - motg->v1p8 = regs[2].consumer; + motg->vddcx = motg->supplies[0].consumer; + motg->v3p3 = motg->supplies[1].consumer; + motg->v1p8 = motg->supplies[2].consumer; clk_set_rate(motg->clk, 60000000); diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 697a741a0cb1ed36ff336af31d8c3cd7d2fd32a5..0e315694adc907b80d2eedccc8943ec2f09bfb01 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -29,10 +29,8 @@ #include "phy-mv-usb.h" #define DRIVER_DESC "Marvell USB OTG transceiver driver" -#define DRIVER_VERSION "Jan 20, 2010" MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); static const char driver_name[] = "mv-otg"; @@ -650,7 +648,7 @@ static struct attribute *inputs_attrs[] = { NULL, }; -static struct attribute_group inputs_attr_group = { +static const struct attribute_group inputs_attr_group = { .name = "inputs", .attrs = inputs_attrs, }; diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c index b6a83a5cbad36357915202ab5490bb854f51803f..679afeaaa9a892afcd52ab0e11c2c8e2f0e46a1c 100644 --- a/drivers/usb/phy/phy-qcom-8x16-usb.c +++ b/drivers/usb/phy/phy-qcom-8x16-usb.c @@ -270,12 +270,9 @@ static int phy_8x16_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qphy); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - - qphy->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!qphy->regs) - return -ENOMEM; + qphy->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(qphy->regs)) + return PTR_ERR(qphy->regs); phy = &qphy->phy; phy->dev = &pdev->dev; diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index a31c8682e99864e57dcb66d0db7c1f1b249d4de9..8babd318c0ed3230eb96bb1d303d06c4ebca8eaa 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -326,7 +326,7 @@ static struct attribute *tahvo_attributes[] = { NULL }; -static struct attribute_group tahvo_attr_group = { +static const struct attribute_group tahvo_attr_group = { .attrs = tahvo_attributes, }; diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 628b600b02b174b4a06f6a6c80e40eb5b8ef3692..b5dc077ed7d3c6fa4b262798cc7c8dc467069f5c 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 032f5afaad4b1be30e64b0cb1f7644f9ba696b00..89f4ac4cd93e56614e59d6ee5fc6f1433b70c20b 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -18,6 +18,18 @@ #include +/* Default current range by charger type. */ +#define DEFAULT_SDP_CUR_MIN 2 +#define DEFAULT_SDP_CUR_MAX 500 +#define DEFAULT_SDP_CUR_MIN_SS 150 +#define DEFAULT_SDP_CUR_MAX_SS 900 +#define DEFAULT_DCP_CUR_MIN 500 +#define DEFAULT_DCP_CUR_MAX 5000 +#define DEFAULT_CDP_CUR_MIN 1500 +#define DEFAULT_CDP_CUR_MAX 5000 +#define DEFAULT_ACA_CUR_MIN 1500 +#define DEFAULT_ACA_CUR_MAX 5000 + static LIST_HEAD(phy_list); static LIST_HEAD(phy_bind_list); static DEFINE_SPINLOCK(phy_lock); @@ -77,6 +89,221 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) return ERR_PTR(-EPROBE_DEFER); } +static void usb_phy_set_default_current(struct usb_phy *usb_phy) +{ + usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN; + usb_phy->chg_cur.sdp_max = DEFAULT_SDP_CUR_MAX; + usb_phy->chg_cur.dcp_min = DEFAULT_DCP_CUR_MIN; + usb_phy->chg_cur.dcp_max = DEFAULT_DCP_CUR_MAX; + usb_phy->chg_cur.cdp_min = DEFAULT_CDP_CUR_MIN; + usb_phy->chg_cur.cdp_max = DEFAULT_CDP_CUR_MAX; + usb_phy->chg_cur.aca_min = DEFAULT_ACA_CUR_MIN; + usb_phy->chg_cur.aca_max = DEFAULT_ACA_CUR_MAX; +} + +/** + * usb_phy_notify_charger_work - notify the USB charger state + * @work - the charger work to notify the USB charger state + * + * This work can be issued when USB charger state has been changed or + * USB charger current has been changed, then we can notify the current + * what can be drawn to power user and the charger state to userspace. + * + * If we get the charger type from extcon subsystem, we can notify the + * charger state to power user automatically by usb_phy_get_charger_type() + * issuing from extcon subsystem. + * + * If we get the charger type from ->charger_detect() instead of extcon + * subsystem, the usb phy driver should issue usb_phy_set_charger_state() + * to set charger state when the charger state has been changed. + */ +static void usb_phy_notify_charger_work(struct work_struct *work) +{ + struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work); + char uchger_state[50] = { 0 }; + char *envp[] = { uchger_state, NULL }; + unsigned int min, max; + + switch (usb_phy->chg_state) { + case USB_CHARGER_PRESENT: + usb_phy_get_charger_current(usb_phy, &min, &max); + + atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy); + snprintf(uchger_state, ARRAY_SIZE(uchger_state), + "USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT"); + break; + case USB_CHARGER_ABSENT: + usb_phy_set_default_current(usb_phy); + + atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy); + snprintf(uchger_state, ARRAY_SIZE(uchger_state), + "USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT"); + break; + default: + dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n", + usb_phy->chg_state); + return; + } + + kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp); +} + +static void __usb_phy_get_charger_type(struct usb_phy *usb_phy) +{ + if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_SDP) > 0) { + usb_phy->chg_type = SDP_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_CDP) > 0) { + usb_phy->chg_type = CDP_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_DCP) > 0) { + usb_phy->chg_type = DCP_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_ACA) > 0) { + usb_phy->chg_type = ACA_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else { + usb_phy->chg_type = UNKNOWN_TYPE; + usb_phy->chg_state = USB_CHARGER_ABSENT; + } + + schedule_work(&usb_phy->chg_work); +} + +/** + * usb_phy_get_charger_type - get charger type from extcon subsystem + * @nb -the notifier block to determine charger type + * @state - the cable state + * @data - private data + * + * Determin the charger type from extcon subsystem which also means the + * charger state has been chaned, then we should notify this event. + */ +static int usb_phy_get_charger_type(struct notifier_block *nb, + unsigned long state, void *data) +{ + struct usb_phy *usb_phy = container_of(nb, struct usb_phy, type_nb); + + __usb_phy_get_charger_type(usb_phy); + return NOTIFY_OK; +} + +/** + * usb_phy_set_charger_current - set the USB charger current + * @usb_phy - the USB phy to be used + * @mA - the current need to be set + * + * Usually we only change the charger default current when USB finished the + * enumeration as one SDP charger. As one SDP charger, usb_phy_set_power() + * will issue this function to change charger current when after setting USB + * configuration, or suspend/resume USB. For other type charger, we should + * use the default charger current and we do not suggest to issue this function + * to change the charger current. + * + * When USB charger current has been changed, we need to notify the power users. + */ +void usb_phy_set_charger_current(struct usb_phy *usb_phy, unsigned int mA) +{ + switch (usb_phy->chg_type) { + case SDP_TYPE: + if (usb_phy->chg_cur.sdp_max == mA) + return; + + usb_phy->chg_cur.sdp_max = (mA > DEFAULT_SDP_CUR_MAX_SS) ? + DEFAULT_SDP_CUR_MAX_SS : mA; + break; + case DCP_TYPE: + if (usb_phy->chg_cur.dcp_max == mA) + return; + + usb_phy->chg_cur.dcp_max = (mA > DEFAULT_DCP_CUR_MAX) ? + DEFAULT_DCP_CUR_MAX : mA; + break; + case CDP_TYPE: + if (usb_phy->chg_cur.cdp_max == mA) + return; + + usb_phy->chg_cur.cdp_max = (mA > DEFAULT_CDP_CUR_MAX) ? + DEFAULT_CDP_CUR_MAX : mA; + break; + case ACA_TYPE: + if (usb_phy->chg_cur.aca_max == mA) + return; + + usb_phy->chg_cur.aca_max = (mA > DEFAULT_ACA_CUR_MAX) ? + DEFAULT_ACA_CUR_MAX : mA; + break; + default: + return; + } + + schedule_work(&usb_phy->chg_work); +} +EXPORT_SYMBOL_GPL(usb_phy_set_charger_current); + +/** + * usb_phy_get_charger_current - get the USB charger current + * @usb_phy - the USB phy to be used + * @min - the minimum current + * @max - the maximum current + * + * Usually we will notify the maximum current to power user, but for some + * special case, power user also need the minimum current value. Then the + * power user can issue this function to get the suitable current. + */ +void usb_phy_get_charger_current(struct usb_phy *usb_phy, + unsigned int *min, unsigned int *max) +{ + switch (usb_phy->chg_type) { + case SDP_TYPE: + *min = usb_phy->chg_cur.sdp_min; + *max = usb_phy->chg_cur.sdp_max; + break; + case DCP_TYPE: + *min = usb_phy->chg_cur.dcp_min; + *max = usb_phy->chg_cur.dcp_max; + break; + case CDP_TYPE: + *min = usb_phy->chg_cur.cdp_min; + *max = usb_phy->chg_cur.cdp_max; + break; + case ACA_TYPE: + *min = usb_phy->chg_cur.aca_min; + *max = usb_phy->chg_cur.aca_max; + break; + default: + *min = 0; + *max = 0; + break; + } +} +EXPORT_SYMBOL_GPL(usb_phy_get_charger_current); + +/** + * usb_phy_set_charger_state - set the USB charger state + * @usb_phy - the USB phy to be used + * @state - the new state need to be set for charger + * + * The usb phy driver can issue this function when the usb phy driver + * detected the charger state has been changed, in this case the charger + * type should be get from ->charger_detect(). + */ +void usb_phy_set_charger_state(struct usb_phy *usb_phy, + enum usb_charger_state state) +{ + if (usb_phy->chg_state == state || !usb_phy->charger_detect) + return; + + usb_phy->chg_state = state; + if (usb_phy->chg_state == USB_CHARGER_PRESENT) + usb_phy->chg_type = usb_phy->charger_detect(usb_phy); + else + usb_phy->chg_type = UNKNOWN_TYPE; + + schedule_work(&usb_phy->chg_work); +} +EXPORT_SYMBOL_GPL(usb_phy_set_charger_state); + static void devm_usb_phy_release(struct device *dev, void *res) { struct usb_phy *phy = *(struct usb_phy **)res; @@ -124,6 +351,44 @@ static int usb_add_extcon(struct usb_phy *x) "register VBUS notifier failed\n"); return ret; } + } else { + x->type_nb.notifier_call = usb_phy_get_charger_type; + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_SDP, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB SDP failed.\n"); + return ret; + } + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_CDP, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB CDP failed.\n"); + return ret; + } + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_DCP, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB DCP failed.\n"); + return ret; + } + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_ACA, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB ACA failed.\n"); + return ret; + } } if (x->id_nb.notifier_call) { @@ -145,6 +410,13 @@ static int usb_add_extcon(struct usb_phy *x) } } + usb_phy_set_default_current(x); + INIT_WORK(&x->chg_work, usb_phy_notify_charger_work); + x->chg_type = UNKNOWN_TYPE; + x->chg_state = USB_CHARGER_DEFAULT; + if (x->type_nb.notifier_call) + __usb_phy_get_charger_type(x); + return 0; } @@ -302,8 +574,8 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, node = of_parse_phandle(dev->of_node, phandle, index); if (!node) { - dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, - dev->of_node->full_name); + dev_dbg(dev, "failed to get %s phandle in %pOF node\n", phandle, + dev->of_node); return ERR_PTR(-ENODEV); } phy = devm_usb_get_phy_by_node(dev, node, NULL); diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index d1af831f43ebad07e86e1d62b0730eb0579ebb4c..68f26904c316d7269b5bccf6e328b07041c7033d 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -282,11 +282,26 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) { struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + int ret = 0; - if (!usbhs_pipe_is_dcp(pipe)) - usbhsf_fifo_barrier(priv, fifo); + if (!usbhs_pipe_is_dcp(pipe)) { + /* + * This driver checks the pipe condition first to avoid -EBUSY + * from usbhsf_fifo_barrier() with about 10 msec delay in + * the interrupt handler if the pipe is RX direction and empty. + */ + if (usbhs_pipe_is_dir_in(pipe)) + ret = usbhs_pipe_is_accessible(pipe); + if (!ret) + ret = usbhsf_fifo_barrier(priv, fifo); + } - usbhs_write(priv, fifo->ctr, BCLR); + /* + * if non-DCP pipe, this driver should set BCLR when + * usbhsf_fifo_barrier() returns 0. + */ + if (!ret) + usbhs_write(priv, fifo->ctr, BCLR); } static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 93fba9033b00a7136b85a9995d7da32a140c61e9..c068b673420b0bd4913b411346600508dd264955 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -639,14 +639,11 @@ static int usbhsg_ep_disable(struct usb_ep *ep) struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhs_pipe *pipe; unsigned long flags; - int ret = 0; spin_lock_irqsave(&uep->lock, flags); pipe = usbhsg_uep_to_pipe(uep); - if (!pipe) { - ret = -EINVAL; + if (!pipe) goto out; - } usbhsg_pipe_disable(uep); usbhs_pipe_free(pipe); @@ -767,7 +764,7 @@ static int usbhsg_ep_set_wedge(struct usb_ep *ep) return __usbhsg_ep_set_halt_wedge(ep, 1, 1); } -static struct usb_ep_ops usbhsg_ep_ops = { +static const struct usb_ep_ops usbhsg_ep_ops = { .enable = usbhsg_ep_enable, .disable = usbhsg_ep_disable, @@ -1085,7 +1082,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) ret = -ENOMEM; goto usbhs_mod_gadget_probe_err_gpriv; } - spin_lock_init(&uep->lock); gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED); dev_info(dev, "%stransceiver found\n", @@ -1135,6 +1131,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) uep->ep.name = uep->ep_name; uep->ep.ops = &usbhsg_ep_ops; INIT_LIST_HEAD(&uep->ep.ep_list); + spin_lock_init(&uep->lock); /* init DCP */ if (usbhsg_is_dcp(uep)) { diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index dfb346e9bd0c7cca4738ed174cda57203aaf2e83..e256351cb72d4925342424c1268a0186c282e0f5 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -1285,7 +1285,7 @@ static int usbhsh_bus_nop(struct usb_hcd *hcd) return 0; } -static struct hc_driver usbhsh_driver = { +static const struct hc_driver usbhsh_driver = { .description = usbhsh_hcd_name, .hcd_priv_size = sizeof(struct usbhsh_hpriv), diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 9396a8c14af80104e8841d98ca30d27ffb1fd88d..d811f0550c04c399c28c43f50c3651f7717ba124 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -401,7 +401,7 @@ static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host, u16 dir = 0; u16 epnum = 0; u16 shtnak = 0; - u16 type_array[] = { + static const u16 type_array[] = { [USB_ENDPOINT_XFER_BULK] = TYPE_BULK, [USB_ENDPOINT_XFER_INT] = TYPE_INT, [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO, diff --git a/drivers/usb/renesas_usbhs/rcar3.c b/drivers/usb/renesas_usbhs/rcar3.c index d544b331c9f2ce80d83095f30184e2102eda6ea6..02b67abfc2a16139a3230d1120a17a4a9ab1cc09 100644 --- a/drivers/usb/renesas_usbhs/rcar3.c +++ b/drivers/usb/renesas_usbhs/rcar3.c @@ -20,9 +20,13 @@ /* Low Power Status register (LPSTS) */ #define LPSTS_SUSPM 0x4000 -/* USB General control register 2 (UGCTRL2), bit[31:6] should be 0 */ +/* + * USB General control register 2 (UGCTRL2) + * Remarks: bit[31:11] and bit[9:6] should be 0 + */ #define UGCTRL2_RESERVED_3 0x00000001 /* bit[3:0] should be B'0001 */ #define UGCTRL2_USB0SEL_OTG 0x00000030 +#define UGCTRL2_VBUSSEL 0x00000400 static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data) { @@ -34,7 +38,8 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev, { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); - usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG); + usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG | + UGCTRL2_VBUSSEL); if (enable) { usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f64e914a8985495bf6ef51bb3de4772c40ffbf49..2d945c9f975c04d5cd7909e00a37017a97e8062e 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -142,6 +142,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ + { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ebe51f11105d8889d6144a72bbf719f14e4b1103..54bfef13966ac0d0145223ddb88891ddbcb494df 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2016,15 +2016,15 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d03, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c9ebefd8f35fdbe5491627f4df89b80c87aeabad..a585b477415dde58b38c9e2defe0d26c24552757 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -52,6 +52,8 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID), .driver_info = PL2303_QUIRK_ENDPOINT_HACK }, + { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC485), + .driver_info = PL2303_QUIRK_ENDPOINT_HACK }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) }, { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 09d9be88209e1ce6b1f53dc052a53c5e4c491336..3b5a15d1dc0dd50a0ebf9d925e33ef4cf8db0090 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -27,6 +27,7 @@ #define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID2 0x0547 #define ATEN_PRODUCT_ID 0x2008 +#define ATEN_PRODUCT_UC485 0x2021 #define ATEN_PRODUCT_ID2 0x2118 #define IODATA_VENDOR_ID 0x04bb diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 4176d1af9bf20582a748aea687ac08fbb2fb5eaf..ec83b3b5efa97177182cc6cd11ab39689c3bc98b 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -47,7 +47,6 @@ MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); MODULE_AUTHOR("wwang "); MODULE_LICENSE("GPL"); -MODULE_VERSION("1.03"); static int auto_delink_en = 1; module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 1a59f335b063e7e79f8ece2173f2f03574ce3a5b..a3ccb899df60c39dd537ae5d3664d937715d0338 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -834,13 +834,25 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) if (result == USB_STOR_TRANSPORT_GOOD) { srb->result = SAM_STAT_GOOD; srb->sense_buffer[0] = 0x0; + } + + /* + * ATA-passthru commands use sense data to report + * the command completion status, and often devices + * return Check Condition status when nothing is + * wrong. + */ + else if (srb->cmnd[0] == ATA_16 || + srb->cmnd[0] == ATA_12) { + /* leave the data alone */ + } /* * If there was a problem, report an unspecified * hardware error to prevent the higher layers from * entering an infinite retry loop. */ - } else { + else { srb->result = DID_ERROR << 16; if ((sshdr.response_code & 0x72) == 0x72) srb->sense_buffer[1] = HARDWARE_ERROR; diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index f58caa9e6a27e6e1a7161a66e5e9a97698cc1e1a..a155cd02bce240db83742f0299ab8ea12a56e7a8 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_host_interface *intf) intf->desc.bInterfaceProtocol == USB_PR_UAS); } -static int uas_find_uas_alt_setting(struct usb_interface *intf) +static struct usb_host_interface *uas_find_uas_alt_setting( + struct usb_interface *intf) { int i; @@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(struct usb_interface *intf) struct usb_host_interface *alt = &intf->altsetting[i]; if (uas_is_interface(alt)) - return alt->desc.bAlternateSetting; + return alt; } - return -ENODEV; + return NULL; } static int uas_find_endpoints(struct usb_host_interface *alt, @@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb_interface *intf, struct usb_device *udev = interface_to_usbdev(intf); struct usb_hcd *hcd = bus_to_hcd(udev->bus); unsigned long flags = id->driver_info; - int r, alt; - + struct usb_host_interface *alt; + int r; alt = uas_find_uas_alt_setting(intf); - if (alt < 0) + if (!alt) return 0; - r = uas_find_endpoints(&intf->altsetting[alt], eps); + r = uas_find_endpoints(alt, eps); if (r < 0) return 0; diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 5ef014ba6ae86917f34e6ebbd855845e3bf71732..63cf981ed81cf8c30eadae32bc36c40499566bdc 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -737,7 +737,7 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) return FAILED; } -static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) +static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd) { struct scsi_device *sdev = cmnd->device; struct uas_dev_info *devinfo = sdev->hostdata; @@ -848,7 +848,7 @@ static struct scsi_host_template uas_host_template = { .slave_alloc = uas_slave_alloc, .slave_configure = uas_slave_configure, .eh_abort_handler = uas_eh_abort_handler, - .eh_bus_reset_handler = uas_eh_bus_reset_handler, + .eh_device_reset_handler = uas_eh_device_reset_handler, .this_id = -1, .sg_tablesize = SG_NONE, .skip_settle_delay = 1, @@ -873,14 +873,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids); static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { - int alt; + struct usb_host_interface *alt; alt = uas_find_uas_alt_setting(intf); - if (alt < 0) - return alt; + if (!alt) + return -ENODEV; - return usb_set_interface(udev, - intf->altsetting[0].desc.bInterfaceNumber, alt); + return usb_set_interface(udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); } static int uas_configure_endpoints(struct uas_dev_info *devinfo) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 5a70c33ef0e0645d1c97a59021a6b400776dd473..eb06d88b41d6976b888317939bc2ae66a1394410 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1459,6 +1459,13 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Reported by Kris Lindgren */ +UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999, + "Seagate", + "External", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA", diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index cbea9f329e715aad97b23928d79579cdcf5e8c92..cde115359793001dcf18b8884c3c9e22eec0fa73 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -124,9 +124,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, /* Reported-by: Benjamin Tissoires */ UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, "Initio Corporation", - "", + "INIC-3069", USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_NO_ATA_1X), + US_FL_NO_ATA_1X | US_FL_IGNORE_RESIDUE), /* Reported-by: Tom Arild Naess */ UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999, diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 06615934fed1cc537694b03d023b613c95aea9f1..0dceb9fa3a0629af3bd1a1990508d2c32bb42db2 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -315,6 +315,7 @@ static int usb_stor_control_thread(void * __us) { struct us_data *us = (struct us_data *)__us; struct Scsi_Host *host = us_to_host(us); + struct scsi_cmnd *srb; for (;;) { usb_stor_dbg(us, "*** thread sleeping\n"); @@ -330,6 +331,7 @@ static int usb_stor_control_thread(void * __us) scsi_lock(host); /* When we are called with no command pending, we're done */ + srb = us->srb; if (us->srb == NULL) { scsi_unlock(host); mutex_unlock(&us->dev_mutex); @@ -398,14 +400,11 @@ static int usb_stor_control_thread(void * __us) /* lock access to the state */ scsi_lock(host); - /* indicate that the command is done */ - if (us->srb->result != DID_ABORT << 16) { - usb_stor_dbg(us, "scsi cmd done, result=0x%x\n", - us->srb->result); - us->srb->scsi_done(us->srb); - } else { + /* was the command aborted? */ + if (us->srb->result == DID_ABORT << 16) { SkipForAbort: usb_stor_dbg(us, "scsi command aborted\n"); + srb = NULL; /* Don't call srb->scsi_done() */ } /* @@ -429,6 +428,13 @@ static int usb_stor_control_thread(void * __us) /* unlock the device pointers */ mutex_unlock(&us->dev_mutex); + + /* now that the locks are released, notify the SCSI core */ + if (srb) { + usb_stor_dbg(us, "scsi cmd done, result=0x%x\n", + srb->result); + srb->scsi_done(srb); + } } /* for (;;) */ /* Wait until we are told to stop */ diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 660180a5d5c441fc96b3451954daf247095d7094..7170404e897983bd42219daf6609a980ffed73b2 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -302,7 +302,6 @@ static int __init usbip_host_init(void) goto err_create_file; } - pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; err_create_file: @@ -335,4 +334,3 @@ module_exit(usbip_host_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(USBIP_VERSION); diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index cab2b71a80d02737ed30b76b40576a51a6201a4a..2281f3562870a07edc3a95b0e370d9c4e14af019 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -763,7 +763,6 @@ static int __init usbip_core_init(void) { int ret; - pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); ret = usbip_init_eh(); if (ret) return ret; @@ -783,4 +782,3 @@ module_exit(usbip_core_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(USBIP_VERSION); diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index f8573a52e41a56b1f693757b3ef631f013d46123..3050fc99a417b5ec7b1d0fba580b421c7861f44e 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -34,8 +34,6 @@ #include #include -#define USBIP_VERSION "1.0.0" - #undef pr_fmt #ifdef DEBUG diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 2c4b2fd4040617a7583ccdb92d0cbbb05aaf5164..11b9a22799ccb3a9a871225aefc70174a6853e68 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1274,7 +1274,7 @@ static int vhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, return 0; } -static struct hc_driver vhci_hc_driver = { +static const struct hc_driver vhci_hc_driver = { .description = driver_name, .product_desc = driver_desc, .hcd_priv_size = sizeof(struct vhci_hcd), @@ -1516,7 +1516,6 @@ static int __init vhci_hcd_init(void) } } - pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; err_add_hcd: @@ -1542,4 +1541,3 @@ module_exit(vhci_hcd_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(USBIP_VERSION); diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 5778b640ba9cb46918e7ce6d33288f699cbb6e39..1b9f60a22e0b4167171d38a288316c4600e64b04 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -366,7 +366,11 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, sockfd_put(socket); dev_err(dev, "port %d already used\n", rhport); - return -EINVAL; + /* + * Will be retried from userspace + * if there's another free port. + */ + return -EBUSY; } dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index fb70cbef0671be96d49def75166e2a9d7f2d15e5..aa4e440e99754aade25d255c076e3448bce42137 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c @@ -586,7 +586,7 @@ static struct attribute *cbaf_dev_attrs[] = { NULL, }; -static struct attribute_group cbaf_dev_attr_group = { +static const struct attribute_group cbaf_dev_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = cbaf_dev_attrs, }; diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c index d4de56b93d68170d503f5be9c28bb6b06d41af45..78212f8180ce15e63533575eeed3940bddffdf27 100644 --- a/drivers/usb/wusbcore/dev-sysfs.c +++ b/drivers/usb/wusbcore/dev-sysfs.c @@ -114,7 +114,7 @@ static struct attribute *wusb_dev_attrs[] = { NULL, }; -static struct attribute_group wusb_dev_attr_group = { +static const struct attribute_group wusb_dev_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = wusb_dev_attrs, }; diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index a273a91cf6673e457a8e74b21a6606765e59d519..5338e42533c8d5c08b20086d8ddb00765215c067 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c @@ -244,7 +244,7 @@ static struct attribute *wusbhc_attrs[] = { NULL, }; -static struct attribute_group wusbhc_attr_group = { +static const struct attribute_group wusbhc_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = wusbhc_attrs, }; diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 35a1e777b4497ad0ad1cfa18db0834354732b128..9a53912bdfe9f73d4b7de6a1d3b74dd8a94dc8b6 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -825,6 +825,8 @@ static int hwarc_probe(struct usb_interface *iface, if (iface->cur_altsetting->desc.bNumEndpoints < 1) return -ENODEV; + if (!usb_endpoint_xfer_int(&iface->cur_altsetting->endpoint[0].desc)) + return -ENODEV; result = -ENOMEM; uwb_rc = uwb_rc_alloc(); diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index 97ee1b46db698f03dee8ea50beb00e864bff0579..b0816c753a63d5022fc1c9e6c595c276d69aec3d 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c @@ -228,7 +228,7 @@ static struct attribute *rc_attrs[] = { NULL, }; -static struct attribute_group rc_attr_group = { +static const struct attribute_group rc_attr_group = { .attrs = rc_attrs, }; diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 01c20a260a8b3f9d9a8ccc315d453f810eb3104c..39dd4ef53c77902db9f740ea3e88fd8bec5cb4ec 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c @@ -302,18 +302,22 @@ static int uwbd(void *param) /** Start the UWB daemon */ void uwbd_start(struct uwb_rc *rc) { - rc->uwbd.task = kthread_run(uwbd, rc, "uwbd"); - if (rc->uwbd.task == NULL) + struct task_struct *task = kthread_run(uwbd, rc, "uwbd"); + if (IS_ERR(task)) { + rc->uwbd.task = NULL; printk(KERN_ERR "UWB: Cannot start management daemon; " "UWB won't work\n"); - else + } else { + rc->uwbd.task = task; rc->uwbd.pid = rc->uwbd.task->pid; + } } /* Stop the UWB daemon and free any unprocessed events */ void uwbd_stop(struct uwb_rc *rc) { - kthread_stop(rc->uwbd.task); + if (rc->uwbd.task) + kthread_stop(rc->uwbd.task); uwbd_flush(rc); } diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 063c1ce6fa422e24d1bceb0ef10aeeccce864b96..f041b1a6cf665e6410917d3608de5fe0ac557476 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -226,7 +226,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev) if (ret) return ret; - vdev->reset_works = (pci_reset_function(pdev) == 0); + /* If reset fails because of the device lock, fail this path entirely */ + ret = pci_try_reset_function(pdev); + if (ret == -EAGAIN) { + pci_disable_device(pdev); + return ret; + } + + vdev->reset_works = !ret; pci_save_state(pdev); vdev->pci_saved_state = pci_store_saved_state(pdev); if (!vdev->pci_saved_state) diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 330a57024cbc5414b381b26e6ef80cf129cd7f9b..5628fe114347a9d710860022182a26893a87d5ab 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -839,7 +839,7 @@ static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos, /* Permissions for PCI Express capability */ static int __init init_pci_cap_exp_perm(struct perm_bits *perm) { - /* Alloc larger of two possible sizes */ + /* Alloc largest of possible sizes */ if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2)) return -ENOMEM; @@ -1243,11 +1243,16 @@ static int vfio_cap_len(struct vfio_pci_device *vdev, u8 cap, u8 pos) vdev->extended_caps = (dword != 0); } - /* length based on version */ - if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) + /* length based on version and type */ + if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) { + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END) + return 0xc; /* "All Devices" only, no link */ return PCI_CAP_EXP_ENDPOINT_SIZEOF_V1; - else + } else { + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END) + return 0x2c; /* No link */ return PCI_CAP_EXP_ENDPOINT_SIZEOF_V2; + } case PCI_CAP_ID_HT: ret = pci_read_config_byte(pdev, pos + 3, &byte); if (ret) diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c index 31372fbf6c5bab9edb4de52b62d662ec8e3cc2d1..62dfbfeaabfc59c3adcfbc9565e672f81bf21176 100644 --- a/drivers/vfio/platform/vfio_amba.c +++ b/drivers/vfio/platform/vfio_amba.c @@ -93,7 +93,7 @@ static int vfio_amba_remove(struct amba_device *adev) return -EINVAL; } -static struct amba_id pl330_ids[] = { +static const struct amba_id pl330_ids[] = { { 0, 0 }, }; diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 330d50582f400e7cd93d3242d91270e0d1fdbf66..f5a86f651f38e12874069281735169a1be26bede 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -85,6 +85,7 @@ struct vfio_group { struct list_head unbound_list; struct mutex unbound_lock; atomic_t opened; + wait_queue_head_t container_q; bool noiommu; struct kvm *kvm; struct blocking_notifier_head notifier; @@ -138,9 +139,10 @@ struct iommu_group *vfio_iommu_group_get(struct device *dev) iommu_group_set_name(group, "vfio-noiommu"); iommu_group_set_iommudata(group, &noiommu, NULL); ret = iommu_group_add_device(group, dev); - iommu_group_put(group); - if (ret) + if (ret) { + iommu_group_put(group); return NULL; + } /* * Where to taint? At this point we've added an IOMMU group for a @@ -337,6 +339,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) mutex_init(&group->unbound_lock); atomic_set(&group->container_users, 0); atomic_set(&group->opened, 0); + init_waitqueue_head(&group->container_q); group->iommu_group = iommu_group; #ifdef CONFIG_VFIO_NOIOMMU group->noiommu = (iommu_group_get_iommudata(iommu_group) == &noiommu); @@ -993,6 +996,23 @@ void *vfio_del_group_dev(struct device *dev) } } while (ret <= 0); + /* + * In order to support multiple devices per group, devices can be + * plucked from the group while other devices in the group are still + * in use. The container persists with this group and those remaining + * devices still attached. If the user creates an isolation violation + * by binding this device to another driver while the group is still in + * use, that's their fault. However, in the case of removing the last, + * or potentially the only, device in the group there can be no other + * in-use devices in the group. The user has done their due diligence + * and we should lay no claims to those devices. In order to do that, + * we need to make sure the group is detached from the container. + * Without this stall, we're potentially racing with a user process + * that may attempt to immediately bind this device to another driver. + */ + if (list_empty(&group->device_list)) + wait_event(group->container_q, !group->container); + vfio_group_put(group); return device_data; @@ -1298,6 +1318,7 @@ static void __vfio_group_unset_container(struct vfio_group *group) group->iommu_group); group->container = NULL; + wake_up(&group->container_q); list_del(&group->container_next); /* Detaching the last group deprivileges a container, remove iommu */ diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 8549cb111627f0b4bc64956df7c2b1e945bbfdc2..92155cce926d1c38bdfc5fb415b43ade481d1591 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1169,13 +1169,21 @@ static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base) INIT_LIST_HEAD(&group_resv_regions); iommu_get_group_resv_regions(group, &group_resv_regions); list_for_each_entry(region, &group_resv_regions, list) { + /* + * The presence of any 'real' MSI regions should take + * precedence over the software-managed one if the + * IOMMU driver happens to advertise both types. + */ + if (region->type == IOMMU_RESV_MSI) { + ret = false; + break; + } + if (region->type == IOMMU_RESV_SW_MSI) { *base = region->start; ret = true; - goto out; } } -out: list_for_each_entry_safe(region, next, &group_resv_regions, list) kfree(region); return ret; @@ -1265,8 +1273,8 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, INIT_LIST_HEAD(&domain->group_list); list_add(&group->next, &domain->group_list); - msi_remap = resv_msi ? irq_domain_check_msi_remap() : - iommu_capable(bus, IOMMU_CAP_INTR_REMAP); + msi_remap = irq_domain_check_msi_remap() || + iommu_capable(bus, IOMMU_CAP_INTR_REMAP); if (!allow_unsafe_interrupts && !msi_remap) { pr_warn("%s: No interrupt remapping support. Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n", diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 06d044862e589ff05194d695bfdc610ed7e62195..58585ec8699e8d46100ff5f5e175ab39a7842154 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -533,6 +533,7 @@ static void handle_tx(struct vhost_net *net) ubuf->callback = vhost_zerocopy_callback; ubuf->ctx = nvq->ubufs; ubuf->desc = nvq->upend_idx; + refcount_set(&ubuf->refcnt, 1); msg.msg_control = ubuf; msg.msg_controllen = sizeof(ubuf); ubufs = nvq->ubufs; @@ -634,8 +635,13 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk) preempt_enable(); - if (vhost_enable_notify(&net->dev, vq)) + if (!vhost_vq_avail_empty(&net->dev, vq)) vhost_poll_queue(&vq->poll); + else if (unlikely(vhost_enable_notify(&net->dev, vq))) { + vhost_disable_notify(&net->dev, vq); + vhost_poll_queue(&vq->poll); + } + mutex_unlock(&vq->mutex); len = peek_head_len(rvq, sk); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e4613a3c362dae8ffbb1e701b4dca51bb858625a..d6dbb28245e6d28129e6c7d18b52589d6ba2a2bb 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -308,7 +308,6 @@ static void vhost_vq_reset(struct vhost_dev *dev, vq->avail = NULL; vq->used = NULL; vq->last_avail_idx = 0; - vq->last_used_event = 0; vq->avail_idx = 0; vq->last_used_idx = 0; vq->signalled_used = 0; @@ -1272,7 +1271,7 @@ static struct vhost_umem *vhost_umem_alloc(void) if (!umem) return NULL; - umem->umem_tree = RB_ROOT; + umem->umem_tree = RB_ROOT_CACHED; umem->numem = 0; INIT_LIST_HEAD(&umem->umem_list); @@ -1402,7 +1401,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) r = -EINVAL; break; } - vq->last_avail_idx = vq->last_used_event = s.num; + vq->last_avail_idx = s.num; /* Forget the cached index value. */ vq->avail_idx = vq->last_avail_idx; break; @@ -2241,6 +2240,10 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) __u16 old, new; __virtio16 event; bool v; + /* Flush out used index updates. This is paired + * with the barrier that the Guest executes when enabling + * interrupts. */ + smp_mb(); if (vhost_has_feature(vq, VIRTIO_F_NOTIFY_ON_EMPTY) && unlikely(vq->avail_idx == vq->last_avail_idx)) @@ -2248,10 +2251,6 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) if (!vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX)) { __virtio16 flags; - /* Flush out used index updates. This is paired - * with the barrier that the Guest executes when enabling - * interrupts. */ - smp_mb(); if (vhost_get_avail(vq, flags, &vq->avail->flags)) { vq_err(vq, "Failed to get flags"); return true; @@ -2266,26 +2265,11 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) if (unlikely(!v)) return true; - /* We're sure if the following conditions are met, there's no - * need to notify guest: - * 1) cached used event is ahead of new - * 2) old to new updating does not cross cached used event. */ - if (vring_need_event(vq->last_used_event, new + vq->num, new) && - !vring_need_event(vq->last_used_event, new, old)) - return false; - - /* Flush out used index updates. This is paired - * with the barrier that the Guest executes when enabling - * interrupts. */ - smp_mb(); - if (vhost_get_avail(vq, event, vhost_used_event(vq))) { vq_err(vq, "Failed to get used event idx"); return true; } - vq->last_used_event = vhost16_to_cpu(vq, event); - - return vring_need_event(vq->last_used_event, new, old); + return vring_need_event(vhost16_to_cpu(vq, event), new, old); } /* This actually signals the guest, using eventfd. */ diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index f72095868b933735a08c3e6c343504ba112cfefd..d59a9cc65f9d2b9b05860d0b251105d122477a82 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -71,7 +71,7 @@ struct vhost_umem_node { }; struct vhost_umem { - struct rb_root umem_tree; + struct rb_root_cached umem_tree; struct list_head umem_list; int numem; }; @@ -115,9 +115,6 @@ struct vhost_virtqueue { /* Last index we used. */ u16 last_used_idx; - /* Last used evet we've seen */ - u16 last_used_event; - /* Used flags */ u16 used_flags; diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index 18134416b154af2428a3230a44e3822e37ed3ab6..e470da95d806fb27f63cd647e65ddbcfd3057a43 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -9,7 +9,8 @@ #include #include #include -#include +#include /* Only for legacy support */ +#include #include #include #include @@ -23,8 +24,7 @@ struct gpio_backlight { struct device *dev; struct device *fbdev; - int gpio; - int active; + struct gpio_desc *gpiod; int def_value; }; @@ -38,8 +38,7 @@ static int gpio_backlight_update_status(struct backlight_device *bl) bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) brightness = 0; - gpio_set_value_cansleep(gbl->gpio, - brightness ? gbl->active : !gbl->active); + gpiod_set_value_cansleep(gbl->gpiod, brightness); return 0; } @@ -61,23 +60,25 @@ static const struct backlight_ops gpio_backlight_ops = { static int gpio_backlight_probe_dt(struct platform_device *pdev, struct gpio_backlight *gbl) { - struct device_node *np = pdev->dev.of_node; - enum of_gpio_flags gpio_flags; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + enum gpiod_flags flags; + int ret; + + gbl->def_value = of_property_read_bool(np, "default-on"); + flags = gbl->def_value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - gbl->gpio = of_get_gpio_flags(np, 0, &gpio_flags); + gbl->gpiod = devm_gpiod_get(dev, NULL, flags); + if (IS_ERR(gbl->gpiod)) { + ret = PTR_ERR(gbl->gpiod); - if (!gpio_is_valid(gbl->gpio)) { - if (gbl->gpio != -EPROBE_DEFER) { - dev_err(&pdev->dev, + if (ret != -EPROBE_DEFER) { + dev_err(dev, "Error: The gpios parameter is missing or invalid.\n"); } - return gbl->gpio; + return ret; } - gbl->active = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; - - gbl->def_value = of_property_read_bool(np, "default-on"); - return 0; } @@ -89,7 +90,6 @@ static int gpio_backlight_probe(struct platform_device *pdev) struct backlight_device *bl; struct gpio_backlight *gbl; struct device_node *np = pdev->dev.of_node; - unsigned long flags = GPIOF_DIR_OUT; int ret; if (!pdata && !np) { @@ -109,22 +109,26 @@ static int gpio_backlight_probe(struct platform_device *pdev) if (ret) return ret; } else { + /* + * Legacy platform data GPIO retrieveal. Do not expand + * the use of this code path, currently only used by one + * SH board. + */ + unsigned long flags = GPIOF_DIR_OUT; + gbl->fbdev = pdata->fbdev; - gbl->gpio = pdata->gpio; - gbl->active = pdata->active_low ? 0 : 1; gbl->def_value = pdata->def_value; - } - - if (gbl->active) flags |= gbl->def_value ? GPIOF_INIT_HIGH : GPIOF_INIT_LOW; - else - flags |= gbl->def_value ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH; - ret = devm_gpio_request_one(gbl->dev, gbl->gpio, flags, - pdata ? pdata->name : "backlight"); - if (ret < 0) { - dev_err(&pdev->dev, "unable to request GPIO\n"); - return ret; + ret = devm_gpio_request_one(gbl->dev, pdata->gpio, flags, + pdata ? pdata->name : "backlight"); + if (ret < 0) { + dev_err(&pdev->dev, "unable to request GPIO\n"); + return ret; + } + gbl->gpiod = gpio_to_desc(pdata->gpio); + if (!gbl->gpiod) + return -EINVAL; } memset(&props, 0, sizeof(props)); diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 84a110a719cbd73256c326b13fe19619b6cfde74..96312c3afc079ce0bc13c7d8039c40f857edeedc 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo; static unsigned long kb3886bl_flags; #define KB3886BL_SUSPENDED 0x01 -static struct dmi_system_id kb3886bl_device_table[] __initdata = { +static const struct dmi_system_id kb3886bl_device_table[] __initconst = { { .ident = "Sahara Touch-iT", .matches = { diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c index 60d6c2ac87aa526b77d308532dc7289ddef85ab5..2030a6b77a09725e97bb1618b2695aea5c55f2a0 100644 --- a/drivers/video/backlight/lm3630a_bl.c +++ b/drivers/video/backlight/lm3630a_bl.c @@ -31,7 +31,8 @@ #define REG_FAULT 0x0B #define REG_PWM_OUTLOW 0x12 #define REG_PWM_OUTHIGH 0x13 -#define REG_MAX 0x1F +#define REG_FILTER_STRENGTH 0x50 +#define REG_MAX 0x50 #define INT_DEBOUNCE_MSEC 10 struct lm3630a_chip { @@ -80,7 +81,7 @@ static int lm3630a_chip_init(struct lm3630a_chip *pchip) usleep_range(1000, 2000); /* set Filter Strength Register */ - rval = lm3630a_write(pchip, 0x50, 0x03); + rval = lm3630a_write(pchip, REG_FILTER_STRENGTH, 0x03); /* set Cofig. register */ rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl); /* set boost control */ diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index 5d8bb8b201835ddf96ed1a5465ed25f682a2a9e8..a186bc677c7d8071a3bf23c3ef6b8b5b9278031b 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #define TWL_PWM0_ON 0x00 diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 002f1ce22bd02032062924b19d645ebc25302c93..9bd17682655a5397b6f6da806af79bddb50ba316 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -178,7 +178,7 @@ static int pwm_backlight_parse_dt(struct device *dev, return 0; } -static struct of_device_id pwm_backlight_of_match[] = { +static const struct of_device_id pwm_backlight_of_match[] = { { .compatible = "pwm-backlight" }, { } }; diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 7da1ad03acb57118392dad947ce46703c8abb2ff..d1d3796773aa2d4c77716f3ba5e2fcebf0ae5653 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -281,7 +281,7 @@ static void sti_rom_copy(unsigned long base, unsigned long count, void *dest) static char default_sti_path[21] __read_mostly; #ifndef MODULE -static int sti_setup(char *str) +static int __init sti_setup(char *str) { if (str) strlcpy (default_sti_path, str, sizeof (default_sti_path)); @@ -941,7 +941,7 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path) * in the additional address field addr[1] while on * older Systems the PDC stores it in page0->proc_sti */ -static int sticore_pa_init(struct parisc_device *dev) +static int __init sticore_pa_init(struct parisc_device *dev) { char pa_path[21]; struct sti_struct *sti = NULL; @@ -1009,7 +1009,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) } -static void sticore_pci_remove(struct pci_dev *pd) +static void __exit sticore_pci_remove(struct pci_dev *pd) { BUG(); } @@ -1029,7 +1029,7 @@ static struct pci_driver pci_sti_driver = { .name = "sti", .id_table = sti_pci_tbl, .probe = sticore_pci_init, - .remove = sticore_pci_remove, + .remove = __exit_p(sticore_pci_remove), }; static struct parisc_device_id sti_pa_tbl[] = { @@ -1037,8 +1037,9 @@ static struct parisc_device_id sti_pa_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00085 }, { 0, } }; +MODULE_DEVICE_TABLE(parisc, sti_pa_tbl); -static struct parisc_driver pa_sti_driver = { +static struct parisc_driver pa_sti_driver __refdata = { .name = "sti", .id_table = sti_pa_tbl, .probe = sticore_pa_init, diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 37f69c061210edf8a4b30799535555ed676fe2fd..487d5e336e1b6cdb9f1375577afbdb8fd8a8565d 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -69,7 +69,7 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy { struct fb_info *info = file->private_data; struct inode *inode = file_inode(file); - int err = filemap_write_and_wait_range(inode->i_mapping, start, end); + int err = file_write_and_wait_range(file, start, end); if (err) return err; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index a35f788b778bec421fc6a26dbe061b44f207fd4d..f741ba8df01b8e28f4331f988d2b04219bb103b6 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -1397,6 +1398,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) mutex_lock(&info->mm_lock); if (fb->fb_mmap) { int res; + + /* + * The framebuffer needs to be accessed decrypted, be sure + * SME protection is removed ahead of the call + */ + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); res = fb->fb_mmap(info, vma); mutex_unlock(&info->mm_lock); return res; @@ -1422,6 +1429,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) mutex_unlock(&info->mm_lock); vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + /* + * The framebuffer needs to be accessed decrypted, be sure + * SME protection is removed + */ + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); fb_pgprotect(file, vma, start); return vm_iomap_memory(vma, start, len); diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 1e784adb89b17534ce31751b546ef20801b2427f..3a010641f6304e7460d5d7207052699e1b9e216f 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -149,6 +149,10 @@ ATTRIBUTE_GROUPS(efifb); static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ +static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ +static struct resource *bar_resource; +static u64 bar_offset; + static int efifb_probe(struct platform_device *dev) { struct fb_info *info; @@ -203,6 +207,13 @@ static int efifb_probe(struct platform_device *dev) efifb_fix.smem_start |= ext_lfb_base; } + if (bar_resource && + bar_resource->start + bar_offset != efifb_fix.smem_start) { + dev_info(&efifb_pci_dev->dev, + "BAR has moved, updating efifb address\n"); + efifb_fix.smem_start = bar_resource->start + bar_offset; + } + efifb_defined.bits_per_pixel = screen_info.lfb_depth; efifb_defined.xres = screen_info.lfb_width; efifb_defined.yres = screen_info.lfb_height; @@ -370,15 +381,13 @@ static struct platform_driver efifb_driver = { builtin_platform_driver(efifb_driver); -#if defined(CONFIG_PCI) && !defined(CONFIG_X86) - -static bool pci_bar_found; /* did we find a BAR matching the efifb base? */ +#if defined(CONFIG_PCI) -static void claim_efifb_bar(struct pci_dev *dev, int idx) +static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset) { u16 word; - pci_bar_found = true; + efifb_pci_dev = dev; pci_read_config_word(dev, PCI_COMMAND, &word); if (!(word & PCI_COMMAND_MEMORY)) { @@ -389,12 +398,8 @@ static void claim_efifb_bar(struct pci_dev *dev, int idx) return; } - if (pci_claim_resource(dev, idx)) { - pci_dev_disabled = true; - dev_err(&dev->dev, - "BAR %d: failed to claim resource for efifb!\n", idx); - return; - } + bar_resource = &dev->resource[idx]; + bar_offset = offset; dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx); } @@ -405,7 +410,7 @@ static void efifb_fixup_resources(struct pci_dev *dev) u64 size = screen_info.lfb_size; int i; - if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) + if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) return; if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) @@ -421,7 +426,7 @@ static void efifb_fixup_resources(struct pci_dev *dev) continue; if (res->start <= base && res->end >= base + size - 1) { - claim_efifb_bar(dev, i); + record_efifb_bar_resource(dev, i, base - res->start); break; } } diff --git a/drivers/video/fbdev/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c index 9d2da146813ef0e2c88e8d4121657fa0400a76dd..796f4634c4c6f157a24769bf1aa34758840c82ec 100644 --- a/drivers/video/fbdev/omap/lcd_h3.c +++ b/drivers/video/fbdev/omap/lcd_h3.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "omapfb.h" diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c index 156a254705ea5e090bbd1e3c1915adb96264e238..ec78d61bc55122e3fca807a55f612ba740f077ce 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c @@ -664,7 +664,7 @@ static int hdmi_audio_register(struct device *dev) { struct omap_hdmi_audio_pdata pdata = { .dev = dev, - .dss_version = omapdss_get_version(), + .version = 4, .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), .ops = &hdmi_audio_ops, }; diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c index 4da36bcab97798c370971731c0541772b357378c..2e2fcc3d6d4f7b7ade7edcea0bb24463f062f799 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c @@ -695,7 +695,7 @@ static int hdmi_audio_register(struct device *dev) { struct omap_hdmi_audio_pdata pdata = { .dev = dev, - .dss_version = omapdss_get_version(), + .version = 5, .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), .ops = &hdmi_audio_ops, }; diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index ad05d25fb9fd7d8ba296465ffdb8b198220885a6..73676eb0244a7bd63d294619563d723992a93183 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -1860,19 +1860,18 @@ static int uvesafb_setup(char *options) } #endif /* !MODULE */ -static ssize_t show_v86d(struct device_driver *dev, char *buf) +static ssize_t v86d_show(struct device_driver *dev, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path); } -static ssize_t store_v86d(struct device_driver *dev, const char *buf, +static ssize_t v86d_store(struct device_driver *dev, const char *buf, size_t count) { strncpy(v86d_path, buf, PATH_MAX); return count; } - -static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d); +static DRIVER_ATTR_RW(v86d); static int uvesafb_init(void) { diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index d3eca879a0a85474f858e79b759d8b4920ba9709..d993df5586c00262d5f3be583e53baf27b26573a 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -841,8 +841,8 @@ static int __init fsl_hypervisor_init(void) handle = of_get_property(np, "interrupts", NULL); irq = irq_of_parse_and_map(np, 0); if (!handle || (irq == NO_IRQ)) { - pr_err("fsl-hv: no 'interrupts' property in %s node\n", - np->full_name); + pr_err("fsl-hv: no 'interrupts' property in %pOF node\n", + np); continue; } @@ -869,8 +869,8 @@ static int __init fsl_hypervisor_init(void) */ dbisr->partition = ret = get_parent_handle(np); if (ret < 0) { - pr_err("fsl-hv: node %s has missing or " - "malformed parent\n", np->full_name); + pr_err("fsl-hv: node %pOF has missing or " + "malformed parent\n", np); kfree(dbisr); continue; } @@ -881,8 +881,8 @@ static int __init fsl_hypervisor_init(void) ret = request_irq(irq, fsl_hv_isr, 0, np->name, dbisr); if (ret < 0) { - pr_err("fsl-hv: could not request irq %u for node %s\n", - irq, np->full_name); + pr_err("fsl-hv: could not request irq %u for node %pOF\n", + irq, np); kfree(dbisr); continue; } diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 623f72334fa55727f175ddd1f32358c3c6fc223e..cff773f15b7e2e6bbabe904c8370206e4a1714b9 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -2,8 +2,8 @@ config VIRTIO tristate ---help--- This option is selected by any driver which implements the virtio - bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_LGUEST, - CONFIG_RPMSG or CONFIG_S390_GUEST. + bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG + or CONFIG_S390_GUEST. menu "Virtio drivers" diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 007a4f3660862e1aa6e9a16207ae54bbbab61d58..1c4797e53f686b03323e4316d443c256854268dc 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -107,6 +107,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, { struct virtio_pci_device *vp_dev = to_vp_device(vdev); const char *name = dev_name(&vp_dev->vdev.dev); + unsigned flags = PCI_IRQ_MSIX; unsigned i, v; int err = -ENOMEM; @@ -126,10 +127,13 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, GFP_KERNEL)) goto error; + if (desc) { + flags |= PCI_IRQ_AFFINITY; + desc->pre_vectors++; /* virtio config vector */ + } + err = pci_alloc_irq_vectors_affinity(vp_dev->pci_dev, nvectors, - nvectors, PCI_IRQ_MSIX | - (desc ? PCI_IRQ_AFFINITY : 0), - desc); + nvectors, flags, desc); if (err < 0) goto error; vp_dev->msix_enabled = 1; diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 5e1b548828e60745ba87581d2b9bcb6380b092f8..eb30f3e09a4775b3f046ccc698f18a05210f17ad 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -296,7 +296,6 @@ static inline int virtqueue_add(struct virtqueue *_vq, } #endif - BUG_ON(total_sg > vq->vring.num); BUG_ON(total_sg == 0); head = vq->free_head; @@ -305,8 +304,10 @@ static inline int virtqueue_add(struct virtqueue *_vq, * buffers, then go indirect. FIXME: tune this threshold */ if (vq->indirect && total_sg > 1 && vq->vq.num_free) desc = alloc_indirect(_vq, total_sg, gfp); - else + else { desc = NULL; + WARN_ON_ONCE(total_sg > vq->vring.num && !vq->indirect); + } if (desc) { /* Use a single buffer which doesn't continue */ @@ -391,7 +392,7 @@ static inline int virtqueue_add(struct virtqueue *_vq, vq->desc_state[head].data = data; if (indirect) vq->desc_state[head].indir_desc = desc; - if (ctx) + else vq->desc_state[head].indir_desc = ctx; /* Put entry in available array (but don't update avail->idx until they diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index fd2e9da27c4bf7ff6b3171d59d3704b3e6470ae7..f661695fb589f9f21abac7e4470decb65afdf3e0 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c @@ -95,7 +95,8 @@ static struct { struct ds1wm_data { void __iomem *map; - int bus_shift; /* # of shifts to calc register offsets */ + unsigned int bus_shift; /* # of shifts to calc register offsets */ + bool is_hw_big_endian; struct platform_device *pdev; const struct mfd_cell *cell; int irq; @@ -115,12 +116,65 @@ struct ds1wm_data { static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, u8 val) { - __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift)); + if (ds1wm_data->is_hw_big_endian) { + switch (ds1wm_data->bus_shift) { + case 0: + iowrite8(val, ds1wm_data->map + (reg << 0)); + break; + case 1: + iowrite16be((u16)val, ds1wm_data->map + (reg << 1)); + break; + case 2: + iowrite32be((u32)val, ds1wm_data->map + (reg << 2)); + break; + } + } else { + switch (ds1wm_data->bus_shift) { + case 0: + iowrite8(val, ds1wm_data->map + (reg << 0)); + break; + case 1: + iowrite16((u16)val, ds1wm_data->map + (reg << 1)); + break; + case 2: + iowrite32((u32)val, ds1wm_data->map + (reg << 2)); + break; + } + } } static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg) { - return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift)); + u32 val = 0; + + if (ds1wm_data->is_hw_big_endian) { + switch (ds1wm_data->bus_shift) { + case 0: + val = ioread8(ds1wm_data->map + (reg << 0)); + break; + case 1: + val = ioread16be(ds1wm_data->map + (reg << 1)); + break; + case 2: + val = ioread32be(ds1wm_data->map + (reg << 2)); + break; + } + } else { + switch (ds1wm_data->bus_shift) { + case 0: + val = ioread8(ds1wm_data->map + (reg << 0)); + break; + case 1: + val = ioread16(ds1wm_data->map + (reg << 1)); + break; + case 2: + val = ioread32(ds1wm_data->map + (reg << 2)); + break; + } + } + dev_dbg(&ds1wm_data->pdev->dev, + "ds1wm_read_register reg: %d, 32 bit val:%x\n", reg, val); + return (u8)val; } @@ -455,6 +509,7 @@ static int ds1wm_probe(struct platform_device *pdev) struct ds1wm_driver_data *plat; struct resource *res; int ret; + u8 inten; if (!pdev) return -ENODEV; @@ -473,9 +528,6 @@ static int ds1wm_probe(struct platform_device *pdev) if (!ds1wm_data->map) return -ENOMEM; - /* calculate bus shift from mem resource */ - ds1wm_data->bus_shift = resource_size(res) >> 3; - ds1wm_data->pdev = pdev; ds1wm_data->cell = mfd_get_cell(pdev); if (!ds1wm_data->cell) @@ -484,6 +536,26 @@ static int ds1wm_probe(struct platform_device *pdev) if (!plat) return -ENODEV; + /* how many bits to shift register number to get register offset */ + if (plat->bus_shift > 2) { + dev_err(&ds1wm_data->pdev->dev, + "illegal bus shift %d, not written", + ds1wm_data->bus_shift); + return -EINVAL; + } + + ds1wm_data->bus_shift = plat->bus_shift; + /* make sure resource has space for 8 registers */ + if ((8 << ds1wm_data->bus_shift) > resource_size(res)) { + dev_err(&ds1wm_data->pdev->dev, + "memory resource size %d to small, should be %d\n", + (int)resource_size(res), + 8 << ds1wm_data->bus_shift); + return -EINVAL; + } + + ds1wm_data->is_hw_big_endian = plat->is_hw_big_endian; + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) return -ENXIO; @@ -491,15 +563,30 @@ static int ds1wm_probe(struct platform_device *pdev) ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0); ds1wm_data->reset_recover_delay = plat->reset_recover_delay; + /* Mask interrupts, set IAS before claiming interrupt */ + inten = ds1wm_read_register(ds1wm_data, DS1WM_INT_EN); + ds1wm_write_register(ds1wm_data, + DS1WM_INT_EN, ds1wm_data->int_en_reg_none); + if (res->flags & IORESOURCE_IRQ_HIGHEDGE) irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING); if (res->flags & IORESOURCE_IRQ_LOWEDGE) irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING); + if (res->flags & IORESOURCE_IRQ_HIGHLEVEL) + irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_HIGH); + if (res->flags & IORESOURCE_IRQ_LOWLEVEL) + irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_LOW); ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr, IRQF_SHARED, "ds1wm", ds1wm_data); - if (ret) + if (ret) { + dev_err(&ds1wm_data->pdev->dev, + "devm_request_irq %d failed with errno %d\n", + ds1wm_data->irq, + ret); + return ret; + } ds1wm_up(ds1wm_data); @@ -509,6 +596,13 @@ static int ds1wm_probe(struct platform_device *pdev) if (ret) goto err; + dev_dbg(&ds1wm_data->pdev->dev, + "ds1wm: probe successful, IAS: %d, rec.delay: %d, clockrate: %d, bus-shift: %d, is Hw Big Endian: %d\n", + plat->active_high, + plat->reset_recover_delay, + plat->clock_rate, + ds1wm_data->bus_shift, + ds1wm_data->is_hw_big_endian); return 0; err: diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index d49681cd29af924ec9af6797573313a853e2397c..5b3e017d9276801ba645a3dca2b07b19cccf2b86 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c @@ -70,6 +70,8 @@ MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \ #define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */ #define DS2482_REG_CFG_APU 0x01 /* active pull-up */ +/* extra configurations - e.g. 1WS */ +int extra_config; /** * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only). @@ -403,7 +405,7 @@ static u8 ds2482_w1_reset_bus(void *data) /* If the chip did reset since detect, re-config it */ if (err & DS2482_REG_STS_RST) ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, - ds2482_calculate_config(0x00)); + ds2482_calculate_config(extra_config)); } mutex_unlock(&pdev->access_lock); @@ -429,8 +431,7 @@ static u8 ds2482_w1_set_pullup(void *data, int delay) ds2482_wait_1wire_idle(pdev); /* note: it seems like both SPU and APU have to be set! */ retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, - ds2482_calculate_config(DS2482_REG_CFG_SPU | - DS2482_REG_CFG_APU)); + ds2482_calculate_config(extra_config|DS2482_REG_CFG_SPU|DS2482_REG_CFG_APU)); ds2482_wait_1wire_idle(pdev); } @@ -483,7 +484,7 @@ static int ds2482_probe(struct i2c_client *client, /* Set all config items to 0 (off) */ ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, - ds2482_calculate_config(0x00)); + ds2482_calculate_config(extra_config)); mutex_init(&data->access_lock); @@ -558,4 +559,7 @@ module_i2c_driver(ds2482_driver); MODULE_AUTHOR("Ben Gardner "); MODULE_DESCRIPTION("DS2482 driver"); +module_param(extra_config, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS"); + MODULE_LICENSE("GPL"); diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index 46ccb2fc4f60da05c71087c913687f09f0767043..c423bdb982bbad900cc2205edec4cf2477c1072b 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -1088,7 +1088,7 @@ static void ds_disconnect(struct usb_interface *intf) kfree(dev); } -static struct usb_device_id ds_id_table [] = { +static const struct usb_device_id ds_id_table[] = { { USB_DEVICE(0x04fa, 0x2490) }, { }, }; diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index fb68465908f21371a31f0656d101996d568cb26c..3c945f9f5f0feab61b92b1443818e5470d2d7c2f 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig @@ -65,6 +65,14 @@ config W1_SLAVE_DS2423 Say Y here if you want to use a 1-wire counter family device (DS2423). +config W1_SLAVE_DS2805 + tristate "112-byte EEPROM support (DS28E05)" + help + Say Y here if you want to use a 1-wire + is a 112-byte user-programmable EEPROM is + organized as 7 pages of 16 bytes each with 64bit + unique number. Requires OverDrive Speed to talk to. + config W1_SLAVE_DS2431 tristate "1kb EEPROM family support (DS2431)" help @@ -140,10 +148,4 @@ config W1_SLAVE_DS28E04 If you are unsure, say N. -config W1_SLAVE_BQ27000 - tristate "BQ27000 slave support" - help - Say Y here if you want to use a hdq - bq27000 slave support. - endmenu diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index 54c63e4203024d2dcc34dd69f31665f19f01aa9e..36b22fb2d3a1d9d467208adc595f47064ac11929 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile @@ -10,10 +10,10 @@ obj-$(CONFIG_W1_SLAVE_DS2413) += w1_ds2413.o obj-$(CONFIG_W1_SLAVE_DS2406) += w1_ds2406.o obj-$(CONFIG_W1_SLAVE_DS2423) += w1_ds2423.o obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o +obj-$(CONFIG_W1_SLAVE_DS2805) += w1_ds2805.o obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o obj-$(CONFIG_W1_SLAVE_DS2438) += w1_ds2438.o obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o -obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c deleted file mode 100644 index 8046ac45381a7c241f77610621b6a314c204eb0d..0000000000000000000000000000000000000000 --- a/drivers/w1/slaves/w1_bq27000.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * drivers/w1/slaves/w1_bq27000.c - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define W1_FAMILY_BQ27000 0x01 - -#define HDQ_CMD_READ (0) -#define HDQ_CMD_WRITE (1<<7) - -static int F_ID; -module_param(F_ID, int, S_IRUSR); -MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); - -static int w1_bq27000_read(struct device *dev, unsigned int reg) -{ - u8 val; - struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev); - - mutex_lock(&sl->master->bus_mutex); - w1_write_8(sl->master, HDQ_CMD_READ | reg); - val = w1_read_8(sl->master); - mutex_unlock(&sl->master->bus_mutex); - - return val; -} - -static struct bq27xxx_platform_data bq27000_battery_info = { - .read = w1_bq27000_read, - .name = "bq27000-battery", - .chip = BQ27000, -}; - -static int w1_bq27000_add_slave(struct w1_slave *sl) -{ - int ret; - struct platform_device *pdev; - - pdev = platform_device_alloc("bq27000-battery", -1); - if (!pdev) { - ret = -ENOMEM; - return ret; - } - ret = platform_device_add_data(pdev, - &bq27000_battery_info, - sizeof(bq27000_battery_info)); - if (ret) - goto pdev_add_failed; - pdev->dev.parent = &sl->dev; - - ret = platform_device_add(pdev); - if (ret) - goto pdev_add_failed; - - dev_set_drvdata(&sl->dev, pdev); - - goto success; - -pdev_add_failed: - platform_device_put(pdev); -success: - return ret; -} - -static void w1_bq27000_remove_slave(struct w1_slave *sl) -{ - struct platform_device *pdev = dev_get_drvdata(&sl->dev); - - platform_device_unregister(pdev); -} - -static struct w1_family_ops w1_bq27000_fops = { - .add_slave = w1_bq27000_add_slave, - .remove_slave = w1_bq27000_remove_slave, -}; - -static struct w1_family w1_bq27000_family = { - .fid = W1_FAMILY_BQ27000, - .fops = &w1_bq27000_fops, -}; - -static int __init w1_bq27000_init(void) -{ - if (F_ID) - w1_bq27000_family.fid = F_ID; - - return w1_register_family(&w1_bq27000_family); -} - -static void __exit w1_bq27000_exit(void) -{ - w1_unregister_family(&w1_bq27000_family); -} - -module_init(w1_bq27000_init); -module_exit(w1_bq27000_exit); - -MODULE_AUTHOR("Texas Instruments Ltd"); -MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c index 6487fb772a2072295fc842839cbd13de00e39c8d..bf641a191d077a1e6c1c238cdf52c3df1ed816e8 100644 --- a/drivers/w1/slaves/w1_ds2438.c +++ b/drivers/w1/slaves/w1_ds2438.c @@ -51,7 +51,7 @@ #define DS2438_CURRENT_MSB 0x06 #define DS2438_THRESHOLD 0x07 -int w1_ds2438_get_page(struct w1_slave *sl, int pageno, u8 *buf) +static int w1_ds2438_get_page(struct w1_slave *sl, int pageno, u8 *buf) { unsigned int retries = W1_DS2438_RETRIES; u8 w1_buf[2]; @@ -85,7 +85,7 @@ int w1_ds2438_get_page(struct w1_slave *sl, int pageno, u8 *buf) return -1; } -int w1_ds2438_get_temperature(struct w1_slave *sl, int16_t *temperature) +static int w1_ds2438_get_temperature(struct w1_slave *sl, int16_t *temperature) { unsigned int retries = W1_DS2438_RETRIES; u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/]; @@ -127,7 +127,7 @@ int w1_ds2438_get_temperature(struct w1_slave *sl, int16_t *temperature) return ret; } -int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value) +static int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value) { unsigned int retries = W1_DS2438_RETRIES; u8 w1_buf[3]; @@ -186,7 +186,8 @@ int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value) return -1; } -uint16_t w1_ds2438_get_voltage(struct w1_slave *sl, int adc_input, uint16_t *voltage) +static uint16_t w1_ds2438_get_voltage(struct w1_slave *sl, + int adc_input, uint16_t *voltage) { unsigned int retries = W1_DS2438_RETRIES; u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/]; diff --git a/drivers/w1/slaves/w1_ds2805.c b/drivers/w1/slaves/w1_ds2805.c new file mode 100644 index 0000000000000000000000000000000000000000..29348d283a65561d0dde50581deb80d059164ff1 --- /dev/null +++ b/drivers/w1/slaves/w1_ds2805.c @@ -0,0 +1,313 @@ +/* + * w1_ds2805 - w1 family 0d (DS28E05) driver + * + * Copyright (c) 2016 Andrew Worsley amworsley@gmail.com + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define W1_EEPROM_DS2805 0x0D + +#define W1_F0D_EEPROM_SIZE 128 +#define W1_F0D_PAGE_BITS 3 +#define W1_F0D_PAGE_SIZE (1< size) + return 0; + + if ((off + count) > size) + return size - off; + + return count; +} + +/* + * Read a block from W1 ROM two times and compares the results. + * If they are equal they are returned, otherwise the read + * is repeated W1_F0D_READ_RETRIES times. + * + * count must not exceed W1_F0D_READ_MAXLEN. + */ +static int w1_f0d_readblock(struct w1_slave *sl, int off, int count, char *buf) +{ + u8 wrbuf[3]; + u8 cmp[W1_F0D_READ_MAXLEN]; + int tries = W1_F0D_READ_RETRIES; + + do { + wrbuf[0] = W1_F0D_READ_EEPROM; + wrbuf[1] = off & 0x7f; + wrbuf[2] = 0; + + if (w1_reset_select_slave(sl)) + return -1; + + w1_write_block(sl->master, wrbuf, sizeof(wrbuf)); + w1_read_block(sl->master, buf, count); + + if (w1_reset_select_slave(sl)) + return -1; + + w1_write_block(sl->master, wrbuf, sizeof(wrbuf)); + w1_read_block(sl->master, cmp, count); + + if (!memcmp(cmp, buf, count)) + return 0; + } while (--tries); + + dev_err(&sl->dev, "proof reading failed %d times\n", + W1_F0D_READ_RETRIES); + + return -1; +} + +static ssize_t w1_f0d_read_bin(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + int todo = count; + + count = w1_f0d_fix_count(off, count, W1_F0D_EEPROM_SIZE); + if (count == 0) + return 0; + + mutex_lock(&sl->master->mutex); + + /* read directly from the EEPROM in chunks of W1_F0D_READ_MAXLEN */ + while (todo > 0) { + int block_read; + + if (todo >= W1_F0D_READ_MAXLEN) + block_read = W1_F0D_READ_MAXLEN; + else + block_read = todo; + + if (w1_f0d_readblock(sl, off, block_read, buf) < 0) { + count = -EIO; + break; + } + + todo -= W1_F0D_READ_MAXLEN; + buf += W1_F0D_READ_MAXLEN; + off += W1_F0D_READ_MAXLEN; + } + + mutex_unlock(&sl->master->mutex); + + return count; +} + +/* + * Writes to the scratchpad and reads it back for verification. + * Then copies the scratchpad to EEPROM. + * The data must be aligned at W1_F0D_SCRATCH_SIZE bytes and + * must be W1_F0D_SCRATCH_SIZE bytes long. + * The master must be locked. + * + * @param sl The slave structure + * @param addr Address for the write + * @param len length must be <= (W1_F0D_PAGE_SIZE - (addr & W1_F0D_PAGE_MASK)) + * @param data The data to write + * @return 0=Success -1=failure + */ +static int w1_f0d_write(struct w1_slave *sl, int addr, int len, const u8 *data) +{ + int tries = W1_F0D_READ_RETRIES; + u8 wrbuf[3]; + u8 rdbuf[W1_F0D_SCRATCH_SIZE]; + u8 cs; + + if ((addr & 1) || (len != 2)) { + dev_err(&sl->dev, "%s: bad addr/len - addr=%#x len=%d\n", + __func__, addr, len); + return -1; + } + +retry: + + /* Write the data to the scratchpad */ + if (w1_reset_select_slave(sl)) + return -1; + + wrbuf[0] = W1_F0D_WRITE_EEPROM; + wrbuf[1] = addr & 0xff; + wrbuf[2] = 0xff; /* ?? from Example */ + + w1_write_block(sl->master, wrbuf, sizeof(wrbuf)); + w1_write_block(sl->master, data, len); + + w1_read_block(sl->master, rdbuf, sizeof(rdbuf)); + /* Compare what was read against the data written */ + if ((rdbuf[0] != data[0]) || (rdbuf[1] != data[1])) { + + if (--tries) + goto retry; + + dev_err(&sl->dev, + "could not write to eeprom, scratchpad compare failed %d times\n", + W1_F0D_READ_RETRIES); + pr_info("%s: rdbuf = %#x %#x data = %#x %#x\n", + __func__, rdbuf[0], rdbuf[1], data[0], data[1]); + + return -1; + } + + /* Trigger write out to EEPROM */ + w1_write_8(sl->master, W1_F0D_RELEASE); + + /* Sleep for tprog ms to wait for the write to complete */ + msleep(W1_F0D_TPROG_MS); + + /* Check CS (Command Status) == 0xAA ? */ + cs = w1_read_8(sl->master); + if (cs != W1_F0D_CS_OK) { + dev_err(&sl->dev, "save to eeprom failed = CS=%#x\n", cs); + return -1; + } + + return 0; +} + +static ssize_t w1_f0d_write_bin(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct w1_slave *sl = kobj_to_w1_slave(kobj); + int addr, len; + int copy; + + count = w1_f0d_fix_count(off, count, W1_F0D_EEPROM_SIZE); + if (count == 0) + return 0; + + mutex_lock(&sl->master->mutex); + + /* Can only write data in blocks of the size of the scratchpad */ + addr = off; + len = count; + while (len > 0) { + + /* if len too short or addr not aligned */ + if (len < W1_F0D_SCRATCH_SIZE || addr & W1_F0D_SCRATCH_MASK) { + char tmp[W1_F0D_SCRATCH_SIZE]; + + /* read the block and update the parts to be written */ + if (w1_f0d_readblock(sl, addr & ~W1_F0D_SCRATCH_MASK, + W1_F0D_SCRATCH_SIZE, tmp)) { + count = -EIO; + goto out_up; + } + + /* copy at most to the boundary of the PAGE or len */ + copy = W1_F0D_SCRATCH_SIZE - + (addr & W1_F0D_SCRATCH_MASK); + + if (copy > len) + copy = len; + + memcpy(&tmp[addr & W1_F0D_SCRATCH_MASK], buf, copy); + if (w1_f0d_write(sl, addr & ~W1_F0D_SCRATCH_MASK, + W1_F0D_SCRATCH_SIZE, tmp) < 0) { + count = -EIO; + goto out_up; + } + } else { + + copy = W1_F0D_SCRATCH_SIZE; + if (w1_f0d_write(sl, addr, copy, buf) < 0) { + count = -EIO; + goto out_up; + } + } + buf += copy; + addr += copy; + len -= copy; + } + +out_up: + mutex_unlock(&sl->master->mutex); + + return count; +} + +static struct bin_attribute w1_f0d_bin_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUSR, + }, + .size = W1_F0D_EEPROM_SIZE, + .read = w1_f0d_read_bin, + .write = w1_f0d_write_bin, +}; + +static int w1_f0d_add_slave(struct w1_slave *sl) +{ + return sysfs_create_bin_file(&sl->dev.kobj, &w1_f0d_bin_attr); +} + +static void w1_f0d_remove_slave(struct w1_slave *sl) +{ + sysfs_remove_bin_file(&sl->dev.kobj, &w1_f0d_bin_attr); +} + +static struct w1_family_ops w1_f0d_fops = { + .add_slave = w1_f0d_add_slave, + .remove_slave = w1_f0d_remove_slave, +}; + +static struct w1_family w1_family_2d = { + .fid = W1_EEPROM_DS2805, + .fops = &w1_f0d_fops, +}; + +static int __init w1_f0d_init(void) +{ + pr_info("%s()\n", __func__); + return w1_register_family(&w1_family_2d); +} + +static void __exit w1_f0d_fini(void) +{ + pr_info("%s()\n", __func__); + w1_unregister_family(&w1_family_2d); +} + +module_init(w1_f0d_init); +module_exit(w1_f0d_fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Andrew Worsley amworsley@gmail.com"); +MODULE_DESCRIPTION("w1 family 0d driver for DS2805, 1kb EEPROM"); diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index cb3fc3c6b0d17a4615c2f522bd5fe4d15d4d7919..259525c3382a783b0139de698a2c813b88f0e152 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -59,6 +60,12 @@ struct w1_therm_family_data { atomic_t refcnt; }; +struct therm_info { + u8 rom[9]; + u8 crc; + u8 verdict; +}; + /* return the address of the refcnt in the family data */ #define THERM_REFCNT(family_data) \ (&((struct w1_therm_family_data *)family_data)->refcnt) @@ -107,19 +114,72 @@ static struct attribute *w1_ds28ea00_attrs[] = { &dev_attr_w1_seq.attr, NULL, }; + ATTRIBUTE_GROUPS(w1_therm); ATTRIBUTE_GROUPS(w1_ds28ea00); +#if IS_REACHABLE(CONFIG_HWMON) +static int w1_read_temp(struct device *dev, u32 attr, int channel, + long *val); + +static umode_t w1_is_visible(const void *_data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + return attr == hwmon_temp_input ? 0444 : 0; +} + +static int w1_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + switch (type) { + case hwmon_temp: + return w1_read_temp(dev, attr, channel, val); + default: + return -EOPNOTSUPP; + } +} + +static const u32 w1_temp_config[] = { + HWMON_T_INPUT, + 0 +}; + +static const struct hwmon_channel_info w1_temp = { + .type = hwmon_temp, + .config = w1_temp_config, +}; + +static const struct hwmon_channel_info *w1_info[] = { + &w1_temp, + NULL +}; + +static const struct hwmon_ops w1_hwmon_ops = { + .is_visible = w1_is_visible, + .read = w1_read, +}; + +static const struct hwmon_chip_info w1_chip_info = { + .ops = &w1_hwmon_ops, + .info = w1_info, +}; +#define W1_CHIPINFO (&w1_chip_info) +#else +#define W1_CHIPINFO NULL +#endif + static struct w1_family_ops w1_therm_fops = { .add_slave = w1_therm_add_slave, .remove_slave = w1_therm_remove_slave, .groups = w1_therm_groups, + .chip_info = W1_CHIPINFO, }; static struct w1_family_ops w1_ds28ea00_fops = { .add_slave = w1_therm_add_slave, .remove_slave = w1_therm_remove_slave, .groups = w1_ds28ea00_groups, + .chip_info = W1_CHIPINFO, }; static struct w1_family w1_therm_family_DS18S20 = { @@ -422,33 +482,31 @@ static ssize_t w1_slave_store(struct device *device, return ret ? : size; } -static ssize_t w1_slave_show(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t read_therm(struct device *device, + struct w1_slave *sl, struct therm_info *info) { - struct w1_slave *sl = dev_to_w1_slave(device); struct w1_master *dev = sl->master; - u8 rom[9], crc, verdict, external_power; - int i, ret, max_trying = 10; - ssize_t c = PAGE_SIZE; + u8 external_power; + int ret, max_trying = 10; u8 *family_data = sl->family_data; ret = mutex_lock_interruptible(&dev->bus_mutex); if (ret != 0) - goto post_unlock; + goto error; - if (!sl->family_data) { + if (!family_data) { ret = -ENODEV; - goto pre_unlock; + goto mt_unlock; } /* prevent the slave from going away in sleep */ atomic_inc(THERM_REFCNT(family_data)); - memset(rom, 0, sizeof(rom)); + memset(info->rom, 0, sizeof(info->rom)); while (max_trying--) { - verdict = 0; - crc = 0; + info->verdict = 0; + info->crc = 0; if (!w1_reset_select_slave(sl)) { int count = 0; @@ -474,47 +532,69 @@ static ssize_t w1_slave_show(struct device *device, sleep_rem = msleep_interruptible(tm); if (sleep_rem != 0) { ret = -EINTR; - goto post_unlock; + goto dec_refcnt; } ret = mutex_lock_interruptible(&dev->bus_mutex); if (ret != 0) - goto post_unlock; + goto dec_refcnt; } else if (!w1_strong_pullup) { sleep_rem = msleep_interruptible(tm); if (sleep_rem != 0) { ret = -EINTR; - goto pre_unlock; + goto dec_refcnt; } } if (!w1_reset_select_slave(sl)) { w1_write_8(dev, W1_READ_SCRATCHPAD); - count = w1_read_block(dev, rom, 9); + count = w1_read_block(dev, info->rom, 9); if (count != 9) { dev_warn(device, "w1_read_block() " "returned %u instead of 9.\n", count); } - crc = w1_calc_crc8(rom, 8); + info->crc = w1_calc_crc8(info->rom, 8); - if (rom[8] == crc) - verdict = 1; + if (info->rom[8] == info->crc) + info->verdict = 1; } } - if (verdict) + if (info->verdict) break; } +dec_refcnt: + atomic_dec(THERM_REFCNT(family_data)); +mt_unlock: + mutex_unlock(&dev->bus_mutex); +error: + return ret; +} + +static ssize_t w1_slave_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct w1_slave *sl = dev_to_w1_slave(device); + struct therm_info info; + u8 *family_data = sl->family_data; + int ret, i; + ssize_t c = PAGE_SIZE; + u8 fid = sl->family->fid; + + ret = read_therm(device, sl, &info); + if (ret) + return ret; + for (i = 0; i < 9; ++i) - c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]); + c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", info.rom[i]); c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n", - crc, (verdict) ? "YES" : "NO"); - if (verdict) - memcpy(family_data, rom, sizeof(rom)); + info.crc, (info.verdict) ? "YES" : "NO"); + if (info.verdict) + memcpy(family_data, info.rom, sizeof(info.rom)); else dev_warn(device, "Read failed CRC check\n"); @@ -523,16 +603,42 @@ static ssize_t w1_slave_show(struct device *device, ((u8 *)family_data)[i]); c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", - w1_convert_temp(rom, sl->family->fid)); + w1_convert_temp(info.rom, fid)); ret = PAGE_SIZE - c; + return ret; +} -pre_unlock: - mutex_unlock(&dev->bus_mutex); +#if IS_REACHABLE(CONFIG_HWMON) +static int w1_read_temp(struct device *device, u32 attr, int channel, + long *val) +{ + struct w1_slave *sl = dev_get_drvdata(device); + struct therm_info info; + u8 fid = sl->family->fid; + int ret; + + switch (attr) { + case hwmon_temp_input: + ret = read_therm(device, sl, &info); + if (ret) + return ret; + + if (!info.verdict) { + ret = -EIO; + return ret; + } + + *val = w1_convert_temp(info.rom, fid); + ret = 0; + break; + default: + ret = -EOPNOTSUPP; + break; + } -post_unlock: - atomic_dec(THERM_REFCNT(family_data)); return ret; } +#endif #define W1_42_CHAIN 0x99 #define W1_42_CHAIN_OFF 0x3C diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 74471e7aa5cc42d82305967bc5a1795363fb5895..0c2a5a8327bd0c38b514c000ed9827656359f193 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -568,7 +569,7 @@ static struct attribute *w1_master_default_attrs[] = { NULL }; -static struct attribute_group w1_master_defattr_group = { +static const struct attribute_group w1_master_defattr_group = { .attrs = w1_master_default_attrs, }; @@ -649,9 +650,24 @@ static int w1_family_notify(unsigned long action, struct w1_slave *sl) return err; } } - + if (IS_REACHABLE(CONFIG_HWMON) && fops->chip_info) { + struct device *hwmon + = hwmon_device_register_with_info(&sl->dev, + "w1_slave_temp", sl, + fops->chip_info, + NULL); + if (IS_ERR(hwmon)) { + dev_warn(&sl->dev, + "could not create hwmon device\n"); + } else { + sl->hwmon = hwmon; + } + } break; case BUS_NOTIFY_DEL_DEVICE: + if (IS_REACHABLE(CONFIG_HWMON) && fops->chip_info && + sl->hwmon) + hwmon_device_unregister(sl->hwmon); if (fops->remove_slave) sl->family->fops->remove_slave(sl); if (fops->groups) @@ -729,6 +745,8 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) atomic_set(&sl->refcnt, 1); atomic_inc(&sl->master->refcnt); dev->slave_count++; + dev_info(&dev->dev, "Attaching one wire slave %02x.%012llx crc %02x\n", + rn->family, (unsigned long long)rn->id, rn->crc); /* slave modules need to be loaded in a context with unlocked mutex */ mutex_unlock(&dev->mutex); diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c index 53da001f0838eeb09303bce1725d316068b369c1..7dd0da644a7f68fc7b1163d1eb12d07fd8c04f3b 100644 --- a/drivers/watchdog/asm9260_wdt.c +++ b/drivers/watchdog/asm9260_wdt.c @@ -82,7 +82,7 @@ static unsigned int asm9260_wdt_gettimeleft(struct watchdog_device *wdd) counter = ioread32(priv->iobase + HW_WDTV); - return DIV_ROUND_CLOSEST(counter, priv->wdt_freq); + return counter / priv->wdt_freq; } static int asm9260_wdt_updatetimeout(struct watchdog_device *wdd) @@ -296,7 +296,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev) if (ret) return ret; - priv->rst = devm_reset_control_get(&pdev->dev, "wdt_rst"); + priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst"); if (IS_ERR(priv->rst)) return PTR_ERR(priv->rst); diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index 1c652582de40036ed44d21d8c8d67bded52aa643..79cc766cd30fdc411e112c1a318d32589627c7b6 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -23,9 +23,21 @@ struct aspeed_wdt { u32 ctrl; }; +struct aspeed_wdt_config { + u32 ext_pulse_width_mask; +}; + +static const struct aspeed_wdt_config ast2400_config = { + .ext_pulse_width_mask = 0xff, +}; + +static const struct aspeed_wdt_config ast2500_config = { + .ext_pulse_width_mask = 0xfffff, +}; + static const struct of_device_id aspeed_wdt_of_table[] = { - { .compatible = "aspeed,ast2400-wdt" }, - { .compatible = "aspeed,ast2500-wdt" }, + { .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config }, + { .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config }, { }, }; MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); @@ -36,12 +48,45 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); #define WDT_CTRL 0x0C #define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) #define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) +#define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 5) #define WDT_CTRL_1MHZ_CLK BIT(4) #define WDT_CTRL_WDT_EXT BIT(3) #define WDT_CTRL_WDT_INTR BIT(2) #define WDT_CTRL_RESET_SYSTEM BIT(1) #define WDT_CTRL_ENABLE BIT(0) +/* + * WDT_RESET_WIDTH controls the characteristics of the external pulse (if + * enabled), specifically: + * + * * Pulse duration + * * Drive mode: push-pull vs open-drain + * * Polarity: Active high or active low + * + * Pulse duration configuration is available on both the AST2400 and AST2500, + * though the field changes between SoCs: + * + * AST2400: Bits 7:0 + * AST2500: Bits 19:0 + * + * This difference is captured in struct aspeed_wdt_config. + * + * The AST2500 exposes the drive mode and polarity options, but not in a + * regular fashion. For read purposes, bit 31 represents active high or low, + * and bit 30 represents push-pull or open-drain. With respect to write, magic + * values need to be written to the top byte to change the state of the drive + * mode and polarity bits. Any other value written to the top byte has no + * effect on the state of the drive mode or polarity bits. However, the pulse + * width value must be preserved (as desired) if written. + */ +#define WDT_RESET_WIDTH 0x18 +#define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31) +#define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24) +#define WDT_ACTIVE_LOW_MAGIC (0x5A << 24) +#define WDT_RESET_WIDTH_PUSH_PULL BIT(30) +#define WDT_PUSH_PULL_MAGIC (0xA8 << 24) +#define WDT_OPEN_DRAIN_MAGIC (0x8A << 24) + #define WDT_RESTART_MAGIC 0x4755 /* 32 bits at 1MHz, in milliseconds */ @@ -138,8 +183,13 @@ static const struct watchdog_info aspeed_wdt_info = { static int aspeed_wdt_probe(struct platform_device *pdev) { + const struct aspeed_wdt_config *config; + const struct of_device_id *ofdid; struct aspeed_wdt *wdt; struct resource *res; + struct device_node *np; + const char *reset_type; + u32 duration; int ret; wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); @@ -164,20 +214,88 @@ static int aspeed_wdt_probe(struct platform_device *pdev) wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT; watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev); + np = pdev->dev.of_node; + + ofdid = of_match_node(aspeed_wdt_of_table, np); + if (!ofdid) + return -EINVAL; + config = ofdid->data; + + wdt->ctrl = WDT_CTRL_1MHZ_CLK; + /* * Control reset on a per-device basis to ensure the - * host is not affected by a BMC reboot, so only reset - * the SOC and not the full chip + * host is not affected by a BMC reboot */ - wdt->ctrl = WDT_CTRL_RESET_MODE_SOC | - WDT_CTRL_1MHZ_CLK | - WDT_CTRL_RESET_SYSTEM; + ret = of_property_read_string(np, "aspeed,reset-type", &reset_type); + if (ret) { + wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; + } else { + if (!strcmp(reset_type, "cpu")) + wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU; + else if (!strcmp(reset_type, "soc")) + wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC; + else if (!strcmp(reset_type, "system")) + wdt->ctrl |= WDT_CTRL_RESET_SYSTEM; + else if (strcmp(reset_type, "none")) + return -EINVAL; + } + if (of_property_read_bool(np, "aspeed,external-signal")) + wdt->ctrl |= WDT_CTRL_WDT_EXT; + + writel(wdt->ctrl, wdt->base + WDT_CTRL); if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { aspeed_wdt_start(&wdt->wdd); set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); } + if (of_device_is_compatible(np, "aspeed,ast2500-wdt")) { + u32 reg = readl(wdt->base + WDT_RESET_WIDTH); + + reg &= config->ext_pulse_width_mask; + if (of_property_read_bool(np, "aspeed,ext-push-pull")) + reg |= WDT_PUSH_PULL_MAGIC; + else + reg |= WDT_OPEN_DRAIN_MAGIC; + + writel(reg, wdt->base + WDT_RESET_WIDTH); + + reg &= config->ext_pulse_width_mask; + if (of_property_read_bool(np, "aspeed,ext-active-high")) + reg |= WDT_ACTIVE_HIGH_MAGIC; + else + reg |= WDT_ACTIVE_LOW_MAGIC; + + writel(reg, wdt->base + WDT_RESET_WIDTH); + } + + if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) { + u32 max_duration = config->ext_pulse_width_mask + 1; + + if (duration == 0 || duration > max_duration) { + dev_err(&pdev->dev, "Invalid pulse duration: %uus\n", + duration); + duration = max(1U, min(max_duration, duration)); + dev_info(&pdev->dev, "Pulse duration set to %uus\n", + duration); + } + + /* + * The watchdog is always configured with a 1MHz source, so + * there is no need to scale the microsecond value. However we + * need to offset it - from the datasheet: + * + * "This register decides the asserting duration of wdt_ext and + * wdt_rstarm signal. The default value is 0xFF. It means the + * default asserting duration of wdt_ext and wdt_rstarm is + * 256us." + * + * This implies a value of 0 gives a 1us pulse. + */ + writel(duration - 1, wdt->base + WDT_RESET_WIDTH); + } + ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd); if (ret) { dev_err(&pdev->dev, "failed to register\n"); diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c index c1b8e534fb5585ad52c2b4d9693981d33b448dff..f88f546e8050048b21719a51cb48ad7ec1556aa7 100644 --- a/drivers/watchdog/bcm7038_wdt.c +++ b/drivers/watchdog/bcm7038_wdt.c @@ -136,7 +136,9 @@ static int bcm7038_wdt_probe(struct platform_device *pdev) wdt->clk = devm_clk_get(dev, NULL); /* If unable to get clock, use default frequency */ if (!IS_ERR(wdt->clk)) { - clk_prepare_enable(wdt->clk); + err = clk_prepare_enable(wdt->clk); + if (err) + return err; wdt->rate = clk_get_rate(wdt->clk); /* Prevent divide-by-zero exception */ if (!wdt->rate) diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 05c000081e9da8c54fdf443055aa2257941c9456..064cf7b6c1c58b7851b986de83a4afe77c7138a0 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c @@ -52,12 +52,12 @@ static int wdt_timeout; static int nowayout = WATCHDOG_NOWAYOUT; -module_param(wdt_timeout, int, 0); +module_param(wdt_timeout, int, 0644); MODULE_PARM_DESC(wdt_timeout, "Watchdog time in seconds. (default=" __MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")"); -module_param(nowayout, int, 0); +module_param(nowayout, int, 0644); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); @@ -368,7 +368,7 @@ static int cdns_wdt_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, wdt); - dev_dbg(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", + dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", wdt->regs, cdns_wdt_device->timeout, nowayout ? ", nowayout" : ""); diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 38dd60f0cfcc636d0b5df5197c06ffcb9f09adbf..4410337f4f7fcfff64cb7b58b764e74315899868 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c @@ -218,7 +218,7 @@ static const struct watchdog_info coh901327_ident = { .identity = DRV_NAME, }; -static struct watchdog_ops coh901327_ops = { +static const struct watchdog_ops coh901327_ops = { .owner = THIS_MODULE, .start = coh901327_start, .stop = coh901327_stop, diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 4691c5509129ec51f3df37e63b3af584a833929d..2a20fc163ed0b50b1d078b4179dcced844ad2159 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c @@ -36,11 +36,6 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; #define DA9063_WDG_TIMEOUT wdt_timeout[3] #define DA9063_RESET_PROTECTION_MS 256 -struct da9063_watchdog { - struct da9063 *da9063; - struct watchdog_device wdtdev; -}; - static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) { unsigned int i; @@ -61,14 +56,14 @@ static int _da9063_wdt_set_timeout(struct da9063 *da9063, unsigned int regval) static int da9063_wdt_start(struct watchdog_device *wdd) { - struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); unsigned int selector; int ret; - selector = da9063_wdt_timeout_to_sel(wdt->wdtdev.timeout); - ret = _da9063_wdt_set_timeout(wdt->da9063, selector); + selector = da9063_wdt_timeout_to_sel(wdd->timeout); + ret = _da9063_wdt_set_timeout(da9063, selector); if (ret) - dev_err(wdt->da9063->dev, "Watchdog failed to start (err = %d)\n", + dev_err(da9063->dev, "Watchdog failed to start (err = %d)\n", ret); return ret; @@ -76,13 +71,13 @@ static int da9063_wdt_start(struct watchdog_device *wdd) static int da9063_wdt_stop(struct watchdog_device *wdd) { - struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); int ret; - ret = regmap_update_bits(wdt->da9063->regmap, DA9063_REG_CONTROL_D, + ret = regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_D, DA9063_TWDSCALE_MASK, DA9063_TWDSCALE_DISABLE); if (ret) - dev_alert(wdt->da9063->dev, "Watchdog failed to stop (err = %d)\n", + dev_alert(da9063->dev, "Watchdog failed to stop (err = %d)\n", ret); return ret; @@ -90,13 +85,13 @@ static int da9063_wdt_stop(struct watchdog_device *wdd) static int da9063_wdt_ping(struct watchdog_device *wdd) { - struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); int ret; - ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, + ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F, DA9063_WATCHDOG); if (ret) - dev_alert(wdt->da9063->dev, "Failed to ping the watchdog (err = %d)\n", + dev_alert(da9063->dev, "Failed to ping the watchdog (err = %d)\n", ret); return ret; @@ -105,14 +100,14 @@ static int da9063_wdt_ping(struct watchdog_device *wdd) static int da9063_wdt_set_timeout(struct watchdog_device *wdd, unsigned int timeout) { - struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); unsigned int selector; int ret; selector = da9063_wdt_timeout_to_sel(timeout); - ret = _da9063_wdt_set_timeout(wdt->da9063, selector); + ret = _da9063_wdt_set_timeout(da9063, selector); if (ret) - dev_err(wdt->da9063->dev, "Failed to set watchdog timeout (err = %d)\n", + dev_err(da9063->dev, "Failed to set watchdog timeout (err = %d)\n", ret); else wdd->timeout = wdt_timeout[selector]; @@ -123,13 +118,13 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd, static int da9063_wdt_restart(struct watchdog_device *wdd, unsigned long action, void *data) { - struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); + struct da9063 *da9063 = watchdog_get_drvdata(wdd); int ret; - ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, + ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F, DA9063_SHUTDOWN); if (ret) - dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n", + dev_alert(da9063->dev, "Failed to shutdown (err = %d)\n", ret); return ret; @@ -152,7 +147,7 @@ static const struct watchdog_ops da9063_watchdog_ops = { static int da9063_wdt_probe(struct platform_device *pdev) { struct da9063 *da9063; - struct da9063_watchdog *wdt; + struct watchdog_device *wdd; if (!pdev->dev.parent) return -EINVAL; @@ -161,27 +156,25 @@ static int da9063_wdt_probe(struct platform_device *pdev) if (!da9063) return -EINVAL; - wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); - if (!wdt) + wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL); + if (!wdd) return -ENOMEM; - wdt->da9063 = da9063; - - wdt->wdtdev.info = &da9063_watchdog_info; - wdt->wdtdev.ops = &da9063_watchdog_ops; - wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT; - wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT; - wdt->wdtdev.min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS; - wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT; - wdt->wdtdev.parent = &pdev->dev; + wdd->info = &da9063_watchdog_info; + wdd->ops = &da9063_watchdog_ops; + wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT; + wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT; + wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS; + wdd->timeout = DA9063_WDG_TIMEOUT; + wdd->parent = &pdev->dev; - wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; + wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS; - watchdog_set_restart_priority(&wdt->wdtdev, 128); + watchdog_set_restart_priority(wdd, 128); - watchdog_set_drvdata(&wdt->wdtdev, wdt); + watchdog_set_drvdata(wdd, da9063); - return devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev); + return devm_watchdog_register_device(&pdev->dev, wdd); } static struct platform_driver da9063_wdt_driver = { diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c index 6f591084bb7af2fb64510171a8ba872c919f53b1..806a04a676b7ee6c369da99d6d09f0ecd50d1fd1 100644 --- a/drivers/watchdog/diag288_wdt.c +++ b/drivers/watchdog/diag288_wdt.c @@ -213,7 +213,7 @@ static const struct watchdog_ops wdt_ops = { .set_timeout = wdt_set_timeout, }; -static struct watchdog_info wdt_info = { +static const struct watchdog_info wdt_info = { .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .firmware_version = 0, .identity = "z Watchdog", diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index c4f65873bfa453b1385d2a1371ba10c741df2be9..347f0389b0899d4183021254203e0a0938600267 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -306,15 +306,16 @@ static int iTCO_wdt_ping(struct watchdog_device *wd_dev) iTCO_vendor_pre_keepalive(p->smi_res, wd_dev->timeout); - /* Reset the timeout status bit so that the timer - * needs to count down twice again before rebooting */ - outw(0x0008, TCO1_STS(p)); /* write 1 to clear bit */ - /* Reload the timer by writing to the TCO Timer Counter register */ - if (p->iTCO_version >= 2) + if (p->iTCO_version >= 2) { outw(0x01, TCO_RLD(p)); - else if (p->iTCO_version == 1) + } else if (p->iTCO_version == 1) { + /* Reset the timeout status bit so that the timer + * needs to count down twice again before rebooting */ + outw(0x0008, TCO1_STS(p)); /* write 1 to clear bit */ + outb(0x01, TCO_RLD(p)); + } spin_unlock(&p->io_lock); return 0; @@ -327,8 +328,11 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t) unsigned char val8; unsigned int tmrval; - /* The timer counts down twice before rebooting */ - tmrval = seconds_to_ticks(p, t) / 2; + tmrval = seconds_to_ticks(p, t); + + /* For TCO v1 the timer counts down twice before rebooting */ + if (p->iTCO_version == 1) + tmrval /= 2; /* from the specs: */ /* "Values of 0h-3h are ignored and should not be attempted" */ @@ -381,8 +385,6 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev) spin_lock(&p->io_lock); val16 = inw(TCO_RLD(p)); val16 &= 0x3ff; - if (!(inw(TCO1_STS(p)) & 0x0008)) - val16 += (inw(TCOv2_TMR(p)) & 0x3ff); spin_unlock(&p->io_lock); time_left = ticks_to_seconds(p, val16); diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index dd1e7eaef50fce8ebf514a35e3f49b36509e2419..e96faea24925bf76fd9bda0feb1d7a1c46e17236 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -253,7 +253,7 @@ static const struct watchdog_info ident = { .identity = WATCHDOG_NAME, }; -static struct watchdog_ops wdt_ops = { +static const struct watchdog_ops wdt_ops = { .owner = THIS_MODULE, .start = wdt_start, .stop = wdt_stop, diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index e0823677d8c17a1b4733d1c111c3415f01b0ca72..7f43cefa0eae39505c28aebca4aaf9c1dffa3a9d 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c @@ -4,6 +4,7 @@ * by the Free Software Foundation. * * Copyright (C) 2010 John Crispin + * Copyright (C) 2017 Hauke Mehrtens * Based on EP93xx wdt driver */ @@ -17,9 +18,20 @@ #include #include #include +#include +#include #include +#define LTQ_XRX_RCU_RST_STAT 0x0014 +#define LTQ_XRX_RCU_RST_STAT_WDT BIT(31) + +/* CPU0 Reset Source Register */ +#define LTQ_FALCON_SYS1_CPU0RS 0x0060 +/* reset cause mask */ +#define LTQ_FALCON_SYS1_CPU0RS_MASK 0x0007 +#define LTQ_FALCON_SYS1_CPU0RS_WDT 0x02 + /* * Section 3.4 of the datasheet * The password sequence protects the WDT control register from unintended @@ -186,16 +198,70 @@ static struct miscdevice ltq_wdt_miscdev = { .fops = <q_wdt_fops, }; +typedef int (*ltq_wdt_bootstatus_set)(struct platform_device *pdev); + +static int ltq_wdt_bootstatus_xrx(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *rcu_regmap; + u32 val; + int err; + + rcu_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap"); + if (IS_ERR(rcu_regmap)) + return PTR_ERR(rcu_regmap); + + err = regmap_read(rcu_regmap, LTQ_XRX_RCU_RST_STAT, &val); + if (err) + return err; + + if (val & LTQ_XRX_RCU_RST_STAT_WDT) + ltq_wdt_bootstatus = WDIOF_CARDRESET; + + return 0; +} + +static int ltq_wdt_bootstatus_falcon(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *rcu_regmap; + u32 val; + int err; + + rcu_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, + "lantiq,rcu"); + if (IS_ERR(rcu_regmap)) + return PTR_ERR(rcu_regmap); + + err = regmap_read(rcu_regmap, LTQ_FALCON_SYS1_CPU0RS, &val); + if (err) + return err; + + if ((val & LTQ_FALCON_SYS1_CPU0RS_MASK) == LTQ_FALCON_SYS1_CPU0RS_WDT) + ltq_wdt_bootstatus = WDIOF_CARDRESET; + + return 0; +} + static int ltq_wdt_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct clk *clk; + ltq_wdt_bootstatus_set ltq_wdt_bootstatus_set; + int ret; ltq_wdt_membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ltq_wdt_membase)) return PTR_ERR(ltq_wdt_membase); + ltq_wdt_bootstatus_set = of_device_get_match_data(&pdev->dev); + if (ltq_wdt_bootstatus_set) { + ret = ltq_wdt_bootstatus_set(pdev); + if (ret) + return ret; + } + /* we do not need to enable the clock as it is always running */ clk = clk_get_io(); if (IS_ERR(clk)) { @@ -205,10 +271,6 @@ ltq_wdt_probe(struct platform_device *pdev) ltq_io_region_clk_rate = clk_get_rate(clk); clk_put(clk); - /* find out if the watchdog caused the last reboot */ - if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) - ltq_wdt_bootstatus = WDIOF_CARDRESET; - dev_info(&pdev->dev, "Init done\n"); return misc_register(<q_wdt_miscdev); } @@ -222,7 +284,9 @@ ltq_wdt_remove(struct platform_device *pdev) } static const struct of_device_id ltq_wdt_match[] = { - { .compatible = "lantiq,wdt" }, + { .compatible = "lantiq,wdt", .data = NULL}, + { .compatible = "lantiq,xrx100-wdt", .data = ltq_wdt_bootstatus_xrx }, + { .compatible = "lantiq,falcon-wdt", .data = ltq_wdt_bootstatus_falcon }, {}, }; MODULE_DEVICE_TABLE(of, ltq_wdt_match); diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c index 68c41fa2be27bde7fdea632bdc72840b8de61fcf..2c9f53eaff4f576312837c83d18c3357d45ad096 100644 --- a/drivers/watchdog/max77620_wdt.c +++ b/drivers/watchdog/max77620_wdt.c @@ -201,7 +201,7 @@ static int max77620_wdt_remove(struct platform_device *pdev) return 0; } -static struct platform_device_id max77620_wdt_devtype[] = { +static const struct platform_device_id max77620_wdt_devtype[] = { { .name = "max77620-watchdog", }, { }, }; diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index b29c6fde7473ac78cfeed0790c07b761c27239c8..ea60b29494fb693bf7898e3f456b6ff8e9dfdb6f 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -670,7 +670,7 @@ static int mei_wdt_remove(struct mei_cl_device *cldev) #define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \ 0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB) -static struct mei_cl_device_id mei_wdt_tbl[] = { +static const struct mei_cl_device_id mei_wdt_tbl[] = { { .uuid = MEI_UUID_WD, .version = MEI_CL_VERSION_ANY }, /* required last entry */ { } diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index 491b9bf13d849d2f2bc578538e113073b757f70f..304274c67735440b6360a4097fe8f09bb04a43ce 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c @@ -155,7 +155,9 @@ static const struct watchdog_ops meson_wdt_ops = { static const struct of_device_id meson_wdt_dt_ids[] = { { .compatible = "amlogic,meson6-wdt", .data = &meson6_wdt_data }, + { .compatible = "amlogic,meson8-wdt", .data = &meson6_wdt_data }, { .compatible = "amlogic,meson8b-wdt", .data = &meson8b_wdt_data }, + { .compatible = "amlogic,meson8m2-wdt", .data = &meson8b_wdt_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids); diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c index 48a06067075d56c2f90358527cdd351575992ea1..db38f801721871566251a1f34374236444a65d69 100644 --- a/drivers/watchdog/mt7621_wdt.c +++ b/drivers/watchdog/mt7621_wdt.c @@ -105,7 +105,7 @@ static int mt7621_wdt_bootcause(void) return 0; } -static struct watchdog_info mt7621_wdt_info = { +static const struct watchdog_info mt7621_wdt_info = { .identity = "Mediatek Watchdog", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, }; @@ -135,7 +135,7 @@ static int mt7621_wdt_probe(struct platform_device *pdev) if (IS_ERR(mt7621_wdt_base)) return PTR_ERR(mt7621_wdt_base); - mt7621_wdt_reset = devm_reset_control_get(&pdev->dev, NULL); + mt7621_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(mt7621_wdt_reset)) reset_control_deassert(mt7621_wdt_reset); diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index b5cdceb36cff785fa93d87390fea1aa8ae9cfb49..0ec419a3f7ed1786dab15392d718e2a73bceb2da 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c @@ -1,7 +1,7 @@ /* * Octeon Watchdog driver * - * Copyright (C) 2007, 2008, 2009, 2010 Cavium Networks + * Copyright (C) 2007-2017 Cavium, Inc. * * Converted to use WATCHDOG_CORE by Aaro Koskinen . * @@ -59,20 +59,23 @@ #include #include #include -#include -#include #include -#include #include #include -#include -#include #include #include #include #include +#include +#include +#include + +/* Watchdog interrupt major block number (8 MSBs of intsn) */ +#define WD_BLOCK_NUMBER 0x01 + +static int divisor; /* The count needed to achieve timeout_sec. */ static unsigned int timeout_cnt; @@ -84,7 +87,7 @@ static unsigned int max_timeout_sec; static unsigned int timeout_sec; /* Set to non-zero when userspace countdown mode active */ -static int do_coundown; +static bool do_countdown; static unsigned int countdown_reset; static unsigned int per_cpu_countdown[NR_CPUS]; @@ -92,152 +95,38 @@ static cpumask_t irq_enabled_cpus; #define WD_TIMO 60 /* Default heartbeat = 60 seconds */ +#define CVMX_GSERX_SCRATCH(offset) (CVMX_ADD_IO_SEG(0x0001180090000020ull) + ((offset) & 15) * 0x1000000ull) + static int heartbeat = WD_TIMO; -module_param(heartbeat, int, S_IRUGO); +module_param(heartbeat, int, 0444); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0 < heartbeat, default=" __MODULE_STRING(WD_TIMO) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, bool, S_IRUGO); +module_param(nowayout, bool, 0444); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -static u32 nmi_stage1_insns[64] __initdata; -/* We need one branch and therefore one relocation per target label. */ -static struct uasm_label labels[5] __initdata; -static struct uasm_reloc relocs[5] __initdata; - -enum lable_id { - label_enter_bootloader = 1 -}; +static int disable; +module_param(disable, int, 0444); +MODULE_PARM_DESC(disable, + "Disable the watchdog entirely (default=0)"); -/* Some CP0 registers */ -#define K0 26 -#define C0_CVMMEMCTL 11, 7 -#define C0_STATUS 12, 0 -#define C0_EBASE 15, 1 -#define C0_DESAVE 31, 0 +static struct cvmx_boot_vector_element *octeon_wdt_bootvector; void octeon_wdt_nmi_stage2(void); -static void __init octeon_wdt_build_stage1(void) -{ - int i; - int len; - u32 *p = nmi_stage1_insns; -#ifdef CONFIG_HOTPLUG_CPU - struct uasm_label *l = labels; - struct uasm_reloc *r = relocs; -#endif - - /* - * For the next few instructions running the debugger may - * cause corruption of k0 in the saved registers. Since we're - * about to crash, nobody probably cares. - * - * Save K0 into the debug scratch register - */ - uasm_i_dmtc0(&p, K0, C0_DESAVE); - - uasm_i_mfc0(&p, K0, C0_STATUS); -#ifdef CONFIG_HOTPLUG_CPU - if (octeon_bootloader_entry_addr) - uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), - label_enter_bootloader); -#endif - /* Force 64-bit addressing enabled */ - uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX); - uasm_i_mtc0(&p, K0, C0_STATUS); - -#ifdef CONFIG_HOTPLUG_CPU - if (octeon_bootloader_entry_addr) { - uasm_i_mfc0(&p, K0, C0_EBASE); - /* Coreid number in K0 */ - uasm_i_andi(&p, K0, K0, 0xf); - /* 8 * coreid in bits 16-31 */ - uasm_i_dsll_safe(&p, K0, K0, 3 + 16); - uasm_i_ori(&p, K0, K0, 0x8001); - uasm_i_dsll_safe(&p, K0, K0, 16); - uasm_i_ori(&p, K0, K0, 0x0700); - uasm_i_drotr_safe(&p, K0, K0, 32); - /* - * Should result in: 0x8001,0700,0000,8*coreid which is - * CVMX_CIU_WDOGX(coreid) - 0x0500 - * - * Now ld K0, CVMX_CIU_WDOGX(coreid) - */ - uasm_i_ld(&p, K0, 0x500, K0); - /* - * If bit one set handle the NMI as a watchdog event. - * otherwise transfer control to bootloader. - */ - uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); - uasm_i_nop(&p); - } -#endif - - /* Clear Dcache so cvmseg works right. */ - uasm_i_cache(&p, 1, 0, 0); - - /* Use K0 to do a read/modify/write of CVMMEMCTL */ - uasm_i_dmfc0(&p, K0, C0_CVMMEMCTL); - /* Clear out the size of CVMSEG */ - uasm_i_dins(&p, K0, 0, 0, 6); - /* Set CVMSEG to its largest value */ - uasm_i_ori(&p, K0, K0, 0x1c0 | 54); - /* Store the CVMMEMCTL value */ - uasm_i_dmtc0(&p, K0, C0_CVMMEMCTL); - - /* Load the address of the second stage handler */ - UASM_i_LA(&p, K0, (long)octeon_wdt_nmi_stage2); - uasm_i_jr(&p, K0); - uasm_i_dmfc0(&p, K0, C0_DESAVE); - -#ifdef CONFIG_HOTPLUG_CPU - if (octeon_bootloader_entry_addr) { - uasm_build_label(&l, p, label_enter_bootloader); - /* Jump to the bootloader and restore K0 */ - UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); - uasm_i_jr(&p, K0); - uasm_i_dmfc0(&p, K0, C0_DESAVE); - } -#endif - uasm_resolve_relocs(relocs, labels); - - len = (int)(p - nmi_stage1_insns); - pr_debug("Synthesized NMI stage 1 handler (%d instructions)\n", len); - - pr_debug("\t.set push\n"); - pr_debug("\t.set noreorder\n"); - for (i = 0; i < len; i++) - pr_debug("\t.word 0x%08x\n", nmi_stage1_insns[i]); - pr_debug("\t.set pop\n"); - - if (len > 32) - panic("NMI stage 1 handler exceeds 32 instructions, was %d\n", - len); -} - static int cpu2core(int cpu) { #ifdef CONFIG_SMP - return cpu_logical_map(cpu); + return cpu_logical_map(cpu) & 0x3f; #else return cvmx_get_core_num(); #endif } -static int core2cpu(int coreid) -{ -#ifdef CONFIG_SMP - return cpu_number_map(coreid); -#else - return 0; -#endif -} - /** * Poke the watchdog when an interrupt is received * @@ -248,13 +137,14 @@ static int core2cpu(int coreid) */ static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id) { - unsigned int core = cvmx_get_core_num(); - int cpu = core2cpu(core); + int cpu = raw_smp_processor_id(); + unsigned int core = cpu2core(cpu); + int node = cpu_to_node(cpu); - if (do_coundown) { + if (do_countdown) { if (per_cpu_countdown[cpu] > 0) { /* We're alive, poke the watchdog */ - cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1); per_cpu_countdown[cpu]--; } else { /* Bad news, you are about to reboot. */ @@ -263,7 +153,7 @@ static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id) } } else { /* Not open, just ping away... */ - cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1); } return IRQ_HANDLED; } @@ -338,10 +228,10 @@ void octeon_wdt_nmi_stage3(u64 reg[32]) u64 cp0_epc = read_c0_epc(); /* Delay so output from all cores output is not jumbled together. */ - __delay(100000000ull * coreid); + udelay(85000 * coreid); octeon_wdt_write_string("\r\n*** NMI Watchdog interrupt on Core 0x"); - octeon_wdt_write_hex(coreid, 1); + octeon_wdt_write_hex(coreid, 2); octeon_wdt_write_string(" ***\r\n"); for (i = 0; i < 32; i++) { octeon_wdt_write_string("\t"); @@ -364,33 +254,98 @@ void octeon_wdt_nmi_stage3(u64 reg[32]) octeon_wdt_write_hex(cp0_cause, 16); octeon_wdt_write_string("\r\n"); - octeon_wdt_write_string("\tsum0\t0x"); - octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_SUM0(coreid * 2)), 16); - octeon_wdt_write_string("\ten0\t0x"); - octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)), 16); - octeon_wdt_write_string("\r\n"); + /* The CIU register is different for each Octeon model. */ + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { + octeon_wdt_write_string("\tsrc_wd\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_SRC_PPX_IP2_WDOG(coreid)), 16); + octeon_wdt_write_string("\ten_wd\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_EN_PPX_IP2_WDOG(coreid)), 16); + octeon_wdt_write_string("\r\n"); + octeon_wdt_write_string("\tsrc_rml\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_SRC_PPX_IP2_RML(coreid)), 16); + octeon_wdt_write_string("\ten_rml\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_EN_PPX_IP2_RML(coreid)), 16); + octeon_wdt_write_string("\r\n"); + octeon_wdt_write_string("\tsum\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(coreid)), 16); + octeon_wdt_write_string("\r\n"); + } else if (!octeon_has_feature(OCTEON_FEATURE_CIU3)) { + octeon_wdt_write_string("\tsum0\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_SUM0(coreid * 2)), 16); + octeon_wdt_write_string("\ten0\t0x"); + octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)), 16); + octeon_wdt_write_string("\r\n"); + } octeon_wdt_write_string("*** Chip soft reset soon ***\r\n"); + + /* + * G-30204: We must trigger a soft reset before watchdog + * does an incomplete job of doing it. + */ + if (OCTEON_IS_OCTEON3() && !OCTEON_IS_MODEL(OCTEON_CN70XX)) { + u64 scr; + unsigned int node = cvmx_get_node_num(); + unsigned int lcore = cvmx_get_local_core_num(); + union cvmx_ciu_wdogx ciu_wdog; + + /* + * Wait for other cores to print out information, but + * not too long. Do the soft reset before watchdog + * can trigger it. + */ + do { + ciu_wdog.u64 = cvmx_read_csr_node(node, CVMX_CIU_WDOGX(lcore)); + } while (ciu_wdog.s.cnt > 0x10000); + + scr = cvmx_read_csr_node(0, CVMX_GSERX_SCRATCH(0)); + scr |= 1 << 11; /* Indicate watchdog in bit 11 */ + cvmx_write_csr_node(0, CVMX_GSERX_SCRATCH(0), scr); + cvmx_write_csr_node(0, CVMX_RST_SOFT_RST, 1); + } +} + +static int octeon_wdt_cpu_to_irq(int cpu) +{ + unsigned int coreid; + int node; + int irq; + + coreid = cpu2core(cpu); + node = cpu_to_node(cpu); + + if (octeon_has_feature(OCTEON_FEATURE_CIU3)) { + struct irq_domain *domain; + int hwirq; + + domain = octeon_irq_get_block_domain(node, + WD_BLOCK_NUMBER); + hwirq = WD_BLOCK_NUMBER << 12 | 0x200 | coreid; + irq = irq_find_mapping(domain, hwirq); + } else { + irq = OCTEON_IRQ_WDOG0 + coreid; + } + return irq; } static int octeon_wdt_cpu_pre_down(unsigned int cpu) { unsigned int core; - unsigned int irq; + int node; union cvmx_ciu_wdogx ciu_wdog; core = cpu2core(cpu); - irq = OCTEON_IRQ_WDOG0 + core; + node = cpu_to_node(cpu); /* Poke the watchdog to clear out its state */ - cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1); /* Disable the hardware. */ ciu_wdog.u64 = 0; - cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); + cvmx_write_csr_node(node, CVMX_CIU_WDOGX(core), ciu_wdog.u64); - free_irq(irq, octeon_wdt_poke_irq); + free_irq(octeon_wdt_cpu_to_irq(cpu), octeon_wdt_poke_irq); return 0; } @@ -399,31 +354,56 @@ static int octeon_wdt_cpu_online(unsigned int cpu) unsigned int core; unsigned int irq; union cvmx_ciu_wdogx ciu_wdog; + int node; + struct irq_domain *domain; + int hwirq; core = cpu2core(cpu); + node = cpu_to_node(cpu); + + octeon_wdt_bootvector[core].target_ptr = (u64)octeon_wdt_nmi_stage2; /* Disable it before doing anything with the interrupts. */ ciu_wdog.u64 = 0; - cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); + cvmx_write_csr_node(node, CVMX_CIU_WDOGX(core), ciu_wdog.u64); per_cpu_countdown[cpu] = countdown_reset; - irq = OCTEON_IRQ_WDOG0 + core; + if (octeon_has_feature(OCTEON_FEATURE_CIU3)) { + /* Must get the domain for the watchdog block */ + domain = octeon_irq_get_block_domain(node, WD_BLOCK_NUMBER); + + /* Get a irq for the wd intsn (hardware interrupt) */ + hwirq = WD_BLOCK_NUMBER << 12 | 0x200 | core; + irq = irq_create_mapping(domain, hwirq); + irqd_set_trigger_type(irq_get_irq_data(irq), + IRQ_TYPE_EDGE_RISING); + } else + irq = OCTEON_IRQ_WDOG0 + core; if (request_irq(irq, octeon_wdt_poke_irq, IRQF_NO_THREAD, "octeon_wdt", octeon_wdt_poke_irq)) panic("octeon_wdt: Couldn't obtain irq %d", irq); + /* Must set the irq affinity here */ + if (octeon_has_feature(OCTEON_FEATURE_CIU3)) { + cpumask_t mask; + + cpumask_clear(&mask); + cpumask_set_cpu(cpu, &mask); + irq_set_affinity(irq, &mask); + } + cpumask_set_cpu(cpu, &irq_enabled_cpus); /* Poke the watchdog to clear out its state */ - cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1); /* Finally enable the watchdog now that all handlers are installed */ ciu_wdog.u64 = 0; ciu_wdog.s.len = timeout_cnt; ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */ - cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); + cvmx_write_csr_node(node, CVMX_CIU_WDOGX(core), ciu_wdog.u64); return 0; } @@ -432,17 +412,20 @@ static int octeon_wdt_ping(struct watchdog_device __always_unused *wdog) { int cpu; int coreid; + int node; + + if (disable) + return 0; for_each_online_cpu(cpu) { coreid = cpu2core(cpu); - cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1); + node = cpu_to_node(cpu); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(coreid), 1); per_cpu_countdown[cpu] = countdown_reset; - if ((countdown_reset || !do_coundown) && + if ((countdown_reset || !do_countdown) && !cpumask_test_cpu(cpu, &irq_enabled_cpus)) { /* We have to enable the irq */ - int irq = OCTEON_IRQ_WDOG0 + coreid; - - enable_irq(irq); + enable_irq(octeon_wdt_cpu_to_irq(cpu)); cpumask_set_cpu(cpu, &irq_enabled_cpus); } } @@ -472,7 +455,7 @@ static void octeon_wdt_calc_parameters(int t) countdown_reset = periods > 2 ? periods - 2 : 0; heartbeat = t; - timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * timeout_sec) >> 8; + timeout_cnt = ((octeon_get_io_clock_rate() / divisor) * timeout_sec) >> 8; } static int octeon_wdt_set_timeout(struct watchdog_device *wdog, @@ -481,20 +464,25 @@ static int octeon_wdt_set_timeout(struct watchdog_device *wdog, int cpu; int coreid; union cvmx_ciu_wdogx ciu_wdog; + int node; if (t <= 0) return -1; octeon_wdt_calc_parameters(t); + if (disable) + return 0; + for_each_online_cpu(cpu) { coreid = cpu2core(cpu); - cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1); + node = cpu_to_node(cpu); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(coreid), 1); ciu_wdog.u64 = 0; ciu_wdog.s.len = timeout_cnt; ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */ - cvmx_write_csr(CVMX_CIU_WDOGX(coreid), ciu_wdog.u64); - cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1); + cvmx_write_csr_node(node, CVMX_CIU_WDOGX(coreid), ciu_wdog.u64); + cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(coreid), 1); } octeon_wdt_ping(wdog); /* Get the irqs back on. */ return 0; @@ -503,13 +491,13 @@ static int octeon_wdt_set_timeout(struct watchdog_device *wdog, static int octeon_wdt_start(struct watchdog_device *wdog) { octeon_wdt_ping(wdog); - do_coundown = 1; + do_countdown = 1; return 0; } static int octeon_wdt_stop(struct watchdog_device *wdog) { - do_coundown = 0; + do_countdown = 0; octeon_wdt_ping(wdog); return 0; } @@ -540,14 +528,25 @@ static enum cpuhp_state octeon_wdt_online; */ static int __init octeon_wdt_init(void) { - int i; int ret; - u64 *ptr; + + octeon_wdt_bootvector = cvmx_boot_vector_get(); + if (!octeon_wdt_bootvector) { + pr_err("Error: Cannot allocate boot vector.\n"); + return -ENOMEM; + } + + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) + divisor = 0x200; + else if (OCTEON_IS_MODEL(OCTEON_CN78XX)) + divisor = 0x400; + else + divisor = 0x100; /* * Watchdog time expiration length = The 16 bits of LEN * represent the most significant bits of a 24 bit decrementer - * that decrements every 256 cycles. + * that decrements every divisor cycle. * * Try for a timeout of 5 sec, if that fails a smaller number * of even seconds, @@ -555,8 +554,7 @@ static int __init octeon_wdt_init(void) max_timeout_sec = 6; do { max_timeout_sec--; - timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * - max_timeout_sec) >> 8; + timeout_cnt = ((octeon_get_io_clock_rate() / divisor) * max_timeout_sec) >> 8; } while (timeout_cnt > 65535); BUG_ON(timeout_cnt == 0); @@ -576,16 +574,10 @@ static int __init octeon_wdt_init(void) return ret; } - /* Build the NMI handler ... */ - octeon_wdt_build_stage1(); - - /* ... and install it. */ - ptr = (u64 *) nmi_stage1_insns; - for (i = 0; i < 16; i++) { - cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8); - cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, ptr[i]); + if (disable) { + pr_notice("disabled\n"); + return 0; } - cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000); cpumask_clear(&irq_enabled_cpus); @@ -607,6 +599,10 @@ static int __init octeon_wdt_init(void) static void __exit octeon_wdt_cleanup(void) { watchdog_unregister_device(&octeon_wdt); + + if (disable) + return; + cpuhp_remove_state(octeon_wdt_online); /* @@ -617,7 +613,7 @@ static void __exit octeon_wdt_cleanup(void) } MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Cavium Networks "); -MODULE_DESCRIPTION("Cavium Networks Octeon Watchdog driver."); +MODULE_AUTHOR("Cavium Inc. "); +MODULE_DESCRIPTION("Cavium Inc. OCTEON Watchdog driver."); module_init(octeon_wdt_init); module_exit(octeon_wdt_cleanup); diff --git a/drivers/watchdog/octeon-wdt-nmi.S b/drivers/watchdog/octeon-wdt-nmi.S index 8a900a5e3233eefdae4fd994102a0dd179ddb512..97f6eb7b5a8e04f209beb0cbde29b831863e6cd0 100644 --- a/drivers/watchdog/octeon-wdt-nmi.S +++ b/drivers/watchdog/octeon-wdt-nmi.S @@ -3,20 +3,40 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2007 Cavium Networks + * Copyright (C) 2007-2017 Cavium, Inc. */ #include #include -#define SAVE_REG(r) sd $r, -32768+6912-(32-r)*8($0) +#define CVMSEG_BASE -32768 +#define CVMSEG_SIZE 6912 +#define SAVE_REG(r) sd $r, CVMSEG_BASE + CVMSEG_SIZE - ((32 - r) * 8)($0) NESTED(octeon_wdt_nmi_stage2, 0, sp) .set push .set noreorder .set noat - /* Save all registers to the top CVMSEG. This shouldn't + /* Clear Dcache so cvmseg works right. */ + cache 1,0($0) + /* Use K0 to do a read/modify/write of CVMMEMCTL */ + dmfc0 k0, $11, 7 + /* Clear out the size of CVMSEG */ + dins k0, $0, 0, 6 + /* Set CVMSEG to its largest value */ + ori k0, k0, 0x1c0 | 54 + /* Store the CVMMEMCTL value */ + dmtc0 k0, $11, 7 + /* + * Restore K0 from the debug scratch register, it was saved in + * the boot-vector code. + */ + dmfc0 k0, $31 + + /* + * Save all registers to the top CVMSEG. This shouldn't * corrupt any state used by the kernel. Also all registers - * should have the value right before the NMI. */ + * should have the value right before the NMI. + */ SAVE_REG(0) SAVE_REG(1) SAVE_REG(2) @@ -49,16 +69,22 @@ SAVE_REG(29) SAVE_REG(30) SAVE_REG(31) + /* Write zero to all CVMSEG locations per Core-15169 */ + dli a0, CVMSEG_SIZE - (33 * 8) +1: sd zero, CVMSEG_BASE(a0) + daddiu a0, a0, -8 + bgez a0, 1b + nop /* Set the stack to begin right below the registers */ - li sp, -32768+6912-32*8 + dli sp, CVMSEG_BASE + CVMSEG_SIZE - (32 * 8) /* Load the address of the third stage handler */ - dla a0, octeon_wdt_nmi_stage3 + dla $25, octeon_wdt_nmi_stage3 /* Call the third stage handler */ - jal a0 + jal $25 /* a0 is the address of the saved registers */ move a0, sp /* Loop forvever if we get here. */ -1: b 1b +2: b 2b nop .set pop END(octeon_wdt_nmi_stage2) diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index fae7fe929ea38c299352cac82db0b161167f58f4..1cf286945b7a121dfcee7682e6fa7b0d55b84984 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -51,9 +51,16 @@ struct xwdt_device { static int xilinx_wdt_start(struct watchdog_device *wdd) { + int ret; u32 control_status_reg; struct xwdt_device *xdev = watchdog_get_drvdata(wdd); + ret = clk_enable(xdev->clk); + if (ret) { + dev_err(wdd->parent, "Failed to enable clock\n"); + return ret; + } + spin_lock(&xdev->spinlock); /* Clean previous status and enable the watchdog timer */ @@ -85,6 +92,9 @@ static int xilinx_wdt_stop(struct watchdog_device *wdd) iowrite32(0, xdev->base + XWT_TWCSR1_OFFSET); spin_unlock(&xdev->spinlock); + + clk_disable(xdev->clk); + pr_info("Stopped!\n"); return 0; @@ -167,11 +177,6 @@ static int xwdt_probe(struct platform_device *pdev) if (IS_ERR(xdev->base)) return PTR_ERR(xdev->base); - rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &pfreq); - if (rc) - dev_warn(&pdev->dev, - "The watchdog clock frequency cannot be obtained\n"); - rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval", &xdev->wdt_interval); if (rc) @@ -186,6 +191,26 @@ static int xwdt_probe(struct platform_device *pdev) watchdog_set_nowayout(xilinx_wdt_wdd, enable_once); + xdev->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(xdev->clk)) { + if (PTR_ERR(xdev->clk) != -ENOENT) + return PTR_ERR(xdev->clk); + + /* + * Clock framework support is optional, continue on + * anyways if we don't find a matching clock. + */ + xdev->clk = NULL; + + rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency", + &pfreq); + if (rc) + dev_warn(&pdev->dev, + "The watchdog clock freq cannot be obtained\n"); + } else { + pfreq = clk_get_rate(xdev->clk); + } + /* * Twice of the 2^wdt_interval / freq because the first wdt overflow is * ignored (interrupt), reset is only generated at second wdt overflow @@ -197,14 +222,6 @@ static int xwdt_probe(struct platform_device *pdev) spin_lock_init(&xdev->spinlock); watchdog_set_drvdata(xilinx_wdt_wdd, xdev); - xdev->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(xdev->clk)) { - if (PTR_ERR(xdev->clk) == -ENOENT) - xdev->clk = NULL; - else - return PTR_ERR(xdev->clk); - } - rc = clk_prepare_enable(xdev->clk); if (rc) { dev_err(&pdev->dev, "unable to enable clock\n"); @@ -223,6 +240,8 @@ static int xwdt_probe(struct platform_device *pdev) goto err_clk_disable; } + clk_disable(xdev->clk); + dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n", xdev->base, xilinx_wdt_wdd->timeout); @@ -245,6 +264,43 @@ static int xwdt_remove(struct platform_device *pdev) return 0; } +/** + * xwdt_suspend - Suspend the device. + * + * @dev: handle to the device structure. + * Return: 0 always. + */ +static int __maybe_unused xwdt_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct xwdt_device *xdev = platform_get_drvdata(pdev); + + if (watchdog_active(&xdev->xilinx_wdt_wdd)) + xilinx_wdt_stop(&xdev->xilinx_wdt_wdd); + + return 0; +} + +/** + * xwdt_resume - Resume the device. + * + * @dev: handle to the device structure. + * Return: 0 on success, errno otherwise. + */ +static int __maybe_unused xwdt_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct xwdt_device *xdev = platform_get_drvdata(pdev); + int ret = 0; + + if (watchdog_active(&xdev->xilinx_wdt_wdd)) + ret = xilinx_wdt_start(&xdev->xilinx_wdt_wdd); + + return ret; +} + +static SIMPLE_DEV_PM_OPS(xwdt_pm_ops, xwdt_suspend, xwdt_resume); + /* Match table for of_platform binding */ static const struct of_device_id xwdt_of_match[] = { { .compatible = "xlnx,xps-timebase-wdt-1.00.a", }, @@ -259,6 +315,7 @@ static struct platform_driver xwdt_driver = { .driver = { .name = WATCHDOG_NAME, .of_match_table = xwdt_of_match, + .pm = &xwdt_pm_ops, }, }; diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 5615f40139246a19de1be39df6f6ca60b7a705b9..b9e376c8e2e36afa6fa7c7f172470b77033627e8 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -74,7 +74,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" #define USB_PCWD_PRODUCT_ID 0x1140 /* table of devices that work with this driver */ -static struct usb_device_id usb_pcwd_table[] = { +static const struct usb_device_id usb_pcwd_table[] = { { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c index 4f47b5e9095662cfdb0ff928118fcbf17668d566..780971318810d4a989b0cf58979f93676f2aa42b 100644 --- a/drivers/watchdog/qcom-wdt.c +++ b/drivers/watchdog/qcom-wdt.c @@ -162,6 +162,8 @@ static int qcom_wdt_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOMEM; /* We use CPU0's DGT for the watchdog */ if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index cf61c92f7ecd63bce40034e9b7b8d13ed70dc4bf..831ef83f6de15bce49cbb0839124f0c6cd1a7b60 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -1,8 +1,8 @@ /* * Watchdog driver for Renesas WDT watchdog * - * Copyright (C) 2015-16 Wolfram Sang, Sang Engineering - * Copyright (C) 2015-16 Renesas Electronics Corporation + * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering + * Copyright (C) 2015-17 Renesas Electronics Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -23,10 +23,22 @@ #define RWTCSRA_WOVF BIT(4) #define RWTCSRA_WRFLG BIT(5) #define RWTCSRA_TME BIT(7) +#define RWTCSRB 8 #define RWDT_DEFAULT_TIMEOUT 60U -static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024 }; +/* + * In probe, clk_rate is checked to be not more than 16 bit * biggest clock + * divider (12 bits). d is only a factor to fully utilize the WDT counter and + * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits. + */ +#define MUL_BY_CLKS_PER_SEC(p, d) \ + DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks]) + +/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */ +#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate) + +static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); @@ -36,8 +48,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" struct rwdt_priv { void __iomem *base; struct watchdog_device wdev; - struct clk *clk; - unsigned int clks_per_sec; + unsigned long clk_rate; u8 cks; }; @@ -55,7 +66,7 @@ static int rwdt_init_timeout(struct watchdog_device *wdev) { struct rwdt_priv *priv = watchdog_get_drvdata(wdev); - rwdt_write(priv, 65536 - wdev->timeout * priv->clks_per_sec, RWTCNT); + rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), RWTCNT); return 0; } @@ -64,8 +75,9 @@ static int rwdt_start(struct watchdog_device *wdev) { struct rwdt_priv *priv = watchdog_get_drvdata(wdev); - clk_prepare_enable(priv->clk); + pm_runtime_get_sync(wdev->parent); + rwdt_write(priv, 0, RWTCSRB); rwdt_write(priv, priv->cks, RWTCSRA); rwdt_init_timeout(wdev); @@ -82,7 +94,7 @@ static int rwdt_stop(struct watchdog_device *wdev) struct rwdt_priv *priv = watchdog_get_drvdata(wdev); rwdt_write(priv, priv->cks, RWTCSRA); - clk_disable_unprepare(priv->clk); + pm_runtime_put(wdev->parent); return 0; } @@ -92,7 +104,7 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) struct rwdt_priv *priv = watchdog_get_drvdata(wdev); u16 val = readw_relaxed(priv->base + RWTCNT); - return DIV_ROUND_CLOSEST(65536 - val, priv->clks_per_sec); + return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); } static const struct watchdog_info rwdt_ident = { @@ -112,8 +124,8 @@ static int rwdt_probe(struct platform_device *pdev) { struct rwdt_priv *priv; struct resource *res; - unsigned long rate; - unsigned int clks_per_sec; + struct clk *clk; + unsigned long clks_per_sec; int ret, i; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -125,36 +137,40 @@ static int rwdt_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - priv->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + pm_runtime_enable(&pdev->dev); - rate = clk_get_rate(priv->clk); - if (!rate) - return -ENOENT; + pm_runtime_get_sync(&pdev->dev); + priv->clk_rate = clk_get_rate(clk); + pm_runtime_put(&pdev->dev); + + if (!priv->clk_rate) { + ret = -ENOENT; + goto out_pm_disable; + } for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { - clks_per_sec = DIV_ROUND_UP(rate, clk_divs[i]); - if (clks_per_sec) { - priv->clks_per_sec = clks_per_sec; + clks_per_sec = priv->clk_rate / clk_divs[i]; + if (clks_per_sec && clks_per_sec < 65536) { priv->cks = i; break; } } - if (!clks_per_sec) { + if (i < 0) { dev_err(&pdev->dev, "Can't find suitable clock divider\n"); - return -ERANGE; + ret = -ERANGE; + goto out_pm_disable; } - pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - priv->wdev.info = &rwdt_ident, priv->wdev.ops = &rwdt_ops, priv->wdev.parent = &pdev->dev; priv->wdev.min_timeout = 1; - priv->wdev.max_timeout = 65536 / clks_per_sec; + priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); platform_set_drvdata(pdev, priv); @@ -167,13 +183,14 @@ static int rwdt_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); ret = watchdog_register_device(&priv->wdev); - if (ret < 0) { - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - return ret; - } + if (ret < 0) + goto out_pm_disable; return 0; + + out_pm_disable: + pm_runtime_disable(&pdev->dev); + return ret; } static int rwdt_remove(struct platform_device *pdev) @@ -181,7 +198,6 @@ static int rwdt_remove(struct platform_device *pdev) struct rwdt_priv *priv = platform_get_drvdata(pdev); watchdog_unregister_device(&priv->wdev); - pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c index 05524baf7dccba28fa84360a909bea22127f0ddc..98967f0a7d10e239e51080e5489b656bbdff084b 100644 --- a/drivers/watchdog/rt2880_wdt.c +++ b/drivers/watchdog/rt2880_wdt.c @@ -119,7 +119,7 @@ static int rt288x_wdt_bootcause(void) return 0; } -static struct watchdog_info rt288x_wdt_info = { +static const struct watchdog_info rt288x_wdt_info = { .identity = "Ralink Watchdog", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, }; @@ -152,7 +152,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev) if (IS_ERR(rt288x_wdt_clk)) return PTR_ERR(rt288x_wdt_clk); - rt288x_wdt_reset = devm_reset_control_get(&pdev->dev, NULL); + rt288x_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rt288x_wdt_reset)) reset_control_deassert(rt288x_wdt_reset); diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c index b34d3d5ba632398e357261bd5e666b9e9efc2157..8e4e2fc13f87a5db0480914c3937e06da99f03e6 100644 --- a/drivers/watchdog/sc1200wdt.c +++ b/drivers/watchdog/sc1200wdt.c @@ -342,7 +342,7 @@ static int __init sc1200wdt_probe(void) #if defined CONFIG_PNP -static struct pnp_device_id scl200wdt_pnp_devices[] = { +static const struct pnp_device_id scl200wdt_pnp_devices[] = { /* National Semiconductor PC87307/PC97307 watchdog component */ {.id = "NSC0800", .driver_data = 0}, {.id = ""}, diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index e7a715e820217eb82a90cc8e5eed54d6d826e22c..03805bc5d67ad515769b29be60bb722355fa0da9 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -281,7 +281,7 @@ static int __maybe_unused sp805_wdt_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, sp805_wdt_resume); -static struct amba_id sp805_wdt_ids[] = { +static const struct amba_id sp805_wdt_ids[] = { { .id = 0x00141805, .mask = 0x00ffffff, diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index 6c501b7dba29570501b8926baacc0d4d7820fdd0..be64a8699de3d07d8638db4a7aa207304583ed98 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -140,7 +140,7 @@ static const struct watchdog_info stm32_iwdg_info = { .identity = "STM32 Independent Watchdog", }; -static struct watchdog_ops stm32_iwdg_ops = { +static const struct watchdog_ops stm32_iwdg_ops = { .owner = THIS_MODULE, .start = stm32_iwdg_start, .ping = stm32_iwdg_ping, diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index 17c25daebcceb6678467890593a0023b7167f82b..811e43c39ec4e0322f4b98db7175c8ce1a3538de 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c @@ -112,7 +112,7 @@ static const struct watchdog_info ts72xx_wdt_ident = { .identity = "TS-72XX WDT", }; -static struct watchdog_ops ts72xx_wdt_ops = { +static const struct watchdog_ops ts72xx_wdt_ops = { .owner = THIS_MODULE, .start = ts72xx_wdt_start, .stop = ts72xx_wdt_stop, diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index 9bf3cc0f396106c730383ab561f4457876c6af85..569fe85e52da75363e7a3b7f3239745521b9b7ff 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index d9ba0496713c447eda0ab3ff4f7da69f10191bdb..7817836bff5546dd0ab6362f7e7e4a35530306a5 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c @@ -429,7 +429,7 @@ static int __init wdt_init(void) { int ret; int chip; - const char * const chip_name[] = { + static const char * const chip_name[] = { "W83627HF", "W83627S", "W83697HF", diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index b4e0cea5a64eec8c292762d3a390a492e447c282..d3594aa3a3743dea1f67878a38bee4d75d43ce85 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c @@ -737,7 +737,7 @@ static int ziirave_wdt_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id ziirave_wdt_id[] = { +static const struct i2c_device_id ziirave_wdt_id[] = { { "rave-wdt", 0 }, { } }; diff --git a/drivers/watchdog/zx2967_wdt.c b/drivers/watchdog/zx2967_wdt.c index 69ec5855584b1a2a894fd061ad6bf7cdc87018cd..9261f7c77f6de111006fe2f373f51dead5b50df1 100644 --- a/drivers/watchdog/zx2967_wdt.c +++ b/drivers/watchdog/zx2967_wdt.c @@ -229,7 +229,7 @@ static int zx2967_wdt_probe(struct platform_device *pdev) } clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ); - rstc = devm_reset_control_get(dev, NULL); + rstc = devm_reset_control_get_exclusive(dev, NULL); if (IS_ERR(rstc)) { dev_err(dev, "failed to get rstc"); ret = PTR_ERR(rstc); diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index f15bb3b789d52dd2024d3efa3f48aafc643ef3ae..4545561954ee4fad756cdf38dd55778f91041fe0 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -196,6 +196,18 @@ config XEN_PCIDEV_BACKEND If in doubt, say m. +config XEN_PVCALLS_BACKEND + bool "XEN PV Calls backend driver" + depends on INET && XEN && XEN_BACKEND + default n + help + Experimental backend for the Xen PV Calls protocol + (https://xenbits.xen.org/docs/unstable/misc/pvcalls.html). It + allows PV Calls frontends to send POSIX calls to the backend, + which implements them. + + If in doubt, say n. + config XEN_SCSI_BACKEND tristate "XEN SCSI backend driver" depends on XEN && XEN_BACKEND && TARGET_CORE diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 8feab810aed9222b97bd5959b42e6f09ffaaf83d..caaa15dc37bc594ec6facb4276d1a543ab7f2de2 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -7,9 +7,6 @@ obj-y += xenbus/ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_features.o := $(nostackp) -CFLAGS_efi.o += -fshort-wchar -LDFLAGS += $(call ld-option, --no-wchar-size-warning) - dom0-$(CONFIG_ARM64) += arm-device.o dom0-$(CONFIG_PCI) += pci.o dom0-$(CONFIG_USB_SUPPORT) += dbgp.o @@ -38,6 +35,7 @@ obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o obj-$(CONFIG_XEN_EFI) += efi.o obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsiback.o obj-$(CONFIG_XEN_AUTO_XLATE) += xlate_mmu.o +obj-$(CONFIG_XEN_PVCALLS_BACKEND) += pvcalls-back.o xen-evtchn-y := evtchn.o xen-gntdev-y := gntdev.o xen-gntalloc-y := gntalloc.o diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index ab609255a0f35f02aaa401ecb0be925a2b4b5ba9..f77e499afdddb02c2d7595459a70b15f3a8c56d5 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -664,9 +664,11 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages) */ BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE); - ret = xen_alloc_p2m_entry(page_to_pfn(page)); - if (ret < 0) - goto out_undo; + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + ret = xen_alloc_p2m_entry(page_to_pfn(page)); + if (ret < 0) + goto out_undo; + } #endif } else { ret = add_ballooned_pages(nr_pages - pgno); diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c index 4da69dbf7dcad7f2e2898dd807a118596f86058a..1bdd02a6d6ac757c5a500db192b3d7923c316753 100644 --- a/drivers/xen/biomerge.c +++ b/drivers/xen/biomerge.c @@ -10,8 +10,7 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page)); unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page)); - return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && - ((bfn1 == bfn2) || ((bfn1+1) == bfn2)); + return bfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == bfn2; #else /* * XXX: Add support for merging bio_vec when using different page diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index bae1f5d36c26e8eac1a7ce9473a3ca7999b90642..1ab4bd11f5f3f01f34b1a0055f836c9a0ce755ba 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -574,7 +574,7 @@ static void shutdown_pirq(struct irq_data *data) static void enable_pirq(struct irq_data *data) { - startup_pirq(data); + enable_dynirq(data); } static void disable_pirq(struct irq_data *data) @@ -1653,10 +1653,8 @@ void xen_callback_vector(void) return; } pr_info("Xen HVM callback vector for event delivery is enabled\n"); - /* in the restore case the vector has already been allocated */ - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, - xen_hvm_callback_vector); + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, + xen_hvm_callback_vector); } } #else diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c index 3c41470c7fc4f123b845bc611bb6ea1d48aabc92..76b318e88382e1e83448f8a42caac995651bd4a9 100644 --- a/drivers/xen/events/events_fifo.c +++ b/drivers/xen/events/events_fifo.c @@ -432,12 +432,12 @@ static int xen_evtchn_cpu_dead(unsigned int cpu) int __init xen_evtchn_fifo_init(void) { - int cpu = get_cpu(); + int cpu = smp_processor_id(); int ret; ret = evtchn_fifo_alloc_control_block(cpu); if (ret < 0) - goto out; + return ret; pr_info("Using FIFO-based ABI\n"); @@ -446,7 +446,6 @@ int __init xen_evtchn_fifo_init(void) cpuhp_setup_state_nocalls(CPUHP_XEN_EVTCHN_PREPARE, "xen/evtchn:prepare", xen_evtchn_cpu_prepare, xen_evtchn_cpu_dead); -out: - put_cpu(); + return ret; } diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index 1bf55a32a4b378d7b5f907b73051c8f36eb937f6..3fa40c723e8e95cb85d8c4ee5449ac716cb43e63 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c @@ -294,7 +294,7 @@ static long gntalloc_ioctl_alloc(struct gntalloc_file_private_data *priv, goto out; } - gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_TEMPORARY); + gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_KERNEL); if (!gref_ids) { rc = -ENOMEM; goto out; diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index f3bf8f4e2d6cef09101b53aa9f1a69563b206287..82360594fa8e49bcbad179a6bb349564286cf203 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -484,13 +484,6 @@ static void mn_invl_range_start(struct mmu_notifier *mn, mutex_unlock(&priv->lock); } -static void mn_invl_page(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long address) -{ - mn_invl_range_start(mn, mm, address, address + PAGE_SIZE); -} - static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm) { @@ -522,7 +515,6 @@ static void mn_release(struct mmu_notifier *mn, static const struct mmu_notifier_ops gntdev_mmu_ops = { .release = mn_release, - .invalidate_page = mn_invl_page, .invalidate_range_start = mn_invl_range_start, }; diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index 1275df83070f2186388cdf09aab3bbf1facf1326..5d7dcad0b0a0d345336e9489bc9acc71a9cefb6b 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -175,7 +175,7 @@ static int platform_pci_probe(struct pci_dev *pdev, return ret; } -static struct pci_device_id platform_pci_tbl[] = { +static const struct pci_device_id platform_pci_tbl[] = { {PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,} diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c new file mode 100644 index 0000000000000000000000000000000000000000..b209cd44bb8dce76fe44e10e0349af51fee7880c --- /dev/null +++ b/drivers/xen/pvcalls-back.c @@ -0,0 +1,1240 @@ +/* + * (c) 2017 Stefano Stabellini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define PVCALLS_VERSIONS "1" +#define MAX_RING_ORDER XENBUS_MAX_RING_GRANT_ORDER + +struct pvcalls_back_global { + struct list_head frontends; + struct semaphore frontends_lock; +} pvcalls_back_global; + +/* + * Per-frontend data structure. It contains pointers to the command + * ring, its event channel, a list of active sockets and a tree of + * passive sockets. + */ +struct pvcalls_fedata { + struct list_head list; + struct xenbus_device *dev; + struct xen_pvcalls_sring *sring; + struct xen_pvcalls_back_ring ring; + int irq; + struct list_head socket_mappings; + struct radix_tree_root socketpass_mappings; + struct semaphore socket_lock; +}; + +struct pvcalls_ioworker { + struct work_struct register_work; + struct workqueue_struct *wq; +}; + +struct sock_mapping { + struct list_head list; + struct pvcalls_fedata *fedata; + struct sockpass_mapping *sockpass; + struct socket *sock; + uint64_t id; + grant_ref_t ref; + struct pvcalls_data_intf *ring; + void *bytes; + struct pvcalls_data data; + uint32_t ring_order; + int irq; + atomic_t read; + atomic_t write; + atomic_t io; + atomic_t release; + void (*saved_data_ready)(struct sock *sk); + struct pvcalls_ioworker ioworker; +}; + +struct sockpass_mapping { + struct list_head list; + struct pvcalls_fedata *fedata; + struct socket *sock; + uint64_t id; + struct xen_pvcalls_request reqcopy; + spinlock_t copy_lock; + struct workqueue_struct *wq; + struct work_struct register_work; + void (*saved_data_ready)(struct sock *sk); +}; + +static irqreturn_t pvcalls_back_conn_event(int irq, void *sock_map); +static int pvcalls_back_release_active(struct xenbus_device *dev, + struct pvcalls_fedata *fedata, + struct sock_mapping *map); + +static void pvcalls_conn_back_read(void *opaque) +{ + struct sock_mapping *map = (struct sock_mapping *)opaque; + struct msghdr msg; + struct kvec vec[2]; + RING_IDX cons, prod, size, wanted, array_size, masked_prod, masked_cons; + int32_t error; + struct pvcalls_data_intf *intf = map->ring; + struct pvcalls_data *data = &map->data; + unsigned long flags; + int ret; + + array_size = XEN_FLEX_RING_SIZE(map->ring_order); + cons = intf->in_cons; + prod = intf->in_prod; + error = intf->in_error; + /* read the indexes first, then deal with the data */ + virt_mb(); + + if (error) + return; + + size = pvcalls_queued(prod, cons, array_size); + if (size >= array_size) + return; + spin_lock_irqsave(&map->sock->sk->sk_receive_queue.lock, flags); + if (skb_queue_empty(&map->sock->sk->sk_receive_queue)) { + atomic_set(&map->read, 0); + spin_unlock_irqrestore(&map->sock->sk->sk_receive_queue.lock, + flags); + return; + } + spin_unlock_irqrestore(&map->sock->sk->sk_receive_queue.lock, flags); + wanted = array_size - size; + masked_prod = pvcalls_mask(prod, array_size); + masked_cons = pvcalls_mask(cons, array_size); + + memset(&msg, 0, sizeof(msg)); + msg.msg_iter.type = ITER_KVEC|WRITE; + msg.msg_iter.count = wanted; + if (masked_prod < masked_cons) { + vec[0].iov_base = data->in + masked_prod; + vec[0].iov_len = wanted; + msg.msg_iter.kvec = vec; + msg.msg_iter.nr_segs = 1; + } else { + vec[0].iov_base = data->in + masked_prod; + vec[0].iov_len = array_size - masked_prod; + vec[1].iov_base = data->in; + vec[1].iov_len = wanted - vec[0].iov_len; + msg.msg_iter.kvec = vec; + msg.msg_iter.nr_segs = 2; + } + + atomic_set(&map->read, 0); + ret = inet_recvmsg(map->sock, &msg, wanted, MSG_DONTWAIT); + WARN_ON(ret > wanted); + if (ret == -EAGAIN) /* shouldn't happen */ + return; + if (!ret) + ret = -ENOTCONN; + spin_lock_irqsave(&map->sock->sk->sk_receive_queue.lock, flags); + if (ret > 0 && !skb_queue_empty(&map->sock->sk->sk_receive_queue)) + atomic_inc(&map->read); + spin_unlock_irqrestore(&map->sock->sk->sk_receive_queue.lock, flags); + + /* write the data, then modify the indexes */ + virt_wmb(); + if (ret < 0) + intf->in_error = ret; + else + intf->in_prod = prod + ret; + /* update the indexes, then notify the other end */ + virt_wmb(); + notify_remote_via_irq(map->irq); + + return; +} + +static void pvcalls_conn_back_write(struct sock_mapping *map) +{ + struct pvcalls_data_intf *intf = map->ring; + struct pvcalls_data *data = &map->data; + struct msghdr msg; + struct kvec vec[2]; + RING_IDX cons, prod, size, array_size; + int ret; + + cons = intf->out_cons; + prod = intf->out_prod; + /* read the indexes before dealing with the data */ + virt_mb(); + + array_size = XEN_FLEX_RING_SIZE(map->ring_order); + size = pvcalls_queued(prod, cons, array_size); + if (size == 0) + return; + + memset(&msg, 0, sizeof(msg)); + msg.msg_flags |= MSG_DONTWAIT; + msg.msg_iter.type = ITER_KVEC|READ; + msg.msg_iter.count = size; + if (pvcalls_mask(prod, array_size) > pvcalls_mask(cons, array_size)) { + vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); + vec[0].iov_len = size; + msg.msg_iter.kvec = vec; + msg.msg_iter.nr_segs = 1; + } else { + vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); + vec[0].iov_len = array_size - pvcalls_mask(cons, array_size); + vec[1].iov_base = data->out; + vec[1].iov_len = size - vec[0].iov_len; + msg.msg_iter.kvec = vec; + msg.msg_iter.nr_segs = 2; + } + + atomic_set(&map->write, 0); + ret = inet_sendmsg(map->sock, &msg, size); + if (ret == -EAGAIN || (ret >= 0 && ret < size)) { + atomic_inc(&map->write); + atomic_inc(&map->io); + } + if (ret == -EAGAIN) + return; + + /* write the data, then update the indexes */ + virt_wmb(); + if (ret < 0) { + intf->out_error = ret; + } else { + intf->out_error = 0; + intf->out_cons = cons + ret; + prod = intf->out_prod; + } + /* update the indexes, then notify the other end */ + virt_wmb(); + if (prod != cons + ret) + atomic_inc(&map->write); + notify_remote_via_irq(map->irq); +} + +static void pvcalls_back_ioworker(struct work_struct *work) +{ + struct pvcalls_ioworker *ioworker = container_of(work, + struct pvcalls_ioworker, register_work); + struct sock_mapping *map = container_of(ioworker, struct sock_mapping, + ioworker); + + while (atomic_read(&map->io) > 0) { + if (atomic_read(&map->release) > 0) { + atomic_set(&map->release, 0); + return; + } + + if (atomic_read(&map->read) > 0) + pvcalls_conn_back_read(map); + if (atomic_read(&map->write) > 0) + pvcalls_conn_back_write(map); + + atomic_dec(&map->io); + } +} + +static int pvcalls_back_socket(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + int ret; + struct xen_pvcalls_response *rsp; + + fedata = dev_get_drvdata(&dev->dev); + + if (req->u.socket.domain != AF_INET || + req->u.socket.type != SOCK_STREAM || + (req->u.socket.protocol != IPPROTO_IP && + req->u.socket.protocol != AF_INET)) + ret = -EAFNOSUPPORT; + else + ret = 0; + + /* leave the actual socket allocation for later */ + + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.socket.id = req->u.socket.id; + rsp->ret = ret; + + return 0; +} + +static void pvcalls_sk_state_change(struct sock *sock) +{ + struct sock_mapping *map = sock->sk_user_data; + struct pvcalls_data_intf *intf; + + if (map == NULL) + return; + + intf = map->ring; + intf->in_error = -ENOTCONN; + notify_remote_via_irq(map->irq); +} + +static void pvcalls_sk_data_ready(struct sock *sock) +{ + struct sock_mapping *map = sock->sk_user_data; + struct pvcalls_ioworker *iow; + + if (map == NULL) + return; + + iow = &map->ioworker; + atomic_inc(&map->read); + atomic_inc(&map->io); + queue_work(iow->wq, &iow->register_work); +} + +static struct sock_mapping *pvcalls_new_active_socket( + struct pvcalls_fedata *fedata, + uint64_t id, + grant_ref_t ref, + uint32_t evtchn, + struct socket *sock) +{ + int ret; + struct sock_mapping *map; + void *page; + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (map == NULL) + return NULL; + + map->fedata = fedata; + map->sock = sock; + map->id = id; + map->ref = ref; + + ret = xenbus_map_ring_valloc(fedata->dev, &ref, 1, &page); + if (ret < 0) + goto out; + map->ring = page; + map->ring_order = map->ring->ring_order; + /* first read the order, then map the data ring */ + virt_rmb(); + if (map->ring_order > MAX_RING_ORDER) { + pr_warn("%s frontend requested ring_order %u, which is > MAX (%u)\n", + __func__, map->ring_order, MAX_RING_ORDER); + goto out; + } + ret = xenbus_map_ring_valloc(fedata->dev, map->ring->ref, + (1 << map->ring_order), &page); + if (ret < 0) + goto out; + map->bytes = page; + + ret = bind_interdomain_evtchn_to_irqhandler(fedata->dev->otherend_id, + evtchn, + pvcalls_back_conn_event, + 0, + "pvcalls-backend", + map); + if (ret < 0) + goto out; + map->irq = ret; + + map->data.in = map->bytes; + map->data.out = map->bytes + XEN_FLEX_RING_SIZE(map->ring_order); + + map->ioworker.wq = alloc_workqueue("pvcalls_io", WQ_UNBOUND, 1); + if (!map->ioworker.wq) + goto out; + atomic_set(&map->io, 1); + INIT_WORK(&map->ioworker.register_work, pvcalls_back_ioworker); + + down(&fedata->socket_lock); + list_add_tail(&map->list, &fedata->socket_mappings); + up(&fedata->socket_lock); + + write_lock_bh(&map->sock->sk->sk_callback_lock); + map->saved_data_ready = map->sock->sk->sk_data_ready; + map->sock->sk->sk_user_data = map; + map->sock->sk->sk_data_ready = pvcalls_sk_data_ready; + map->sock->sk->sk_state_change = pvcalls_sk_state_change; + write_unlock_bh(&map->sock->sk->sk_callback_lock); + + return map; +out: + down(&fedata->socket_lock); + list_del(&map->list); + pvcalls_back_release_active(fedata->dev, fedata, map); + up(&fedata->socket_lock); + return NULL; +} + +static int pvcalls_back_connect(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + int ret = -EINVAL; + struct socket *sock; + struct sock_mapping *map; + struct xen_pvcalls_response *rsp; + struct sockaddr *sa = (struct sockaddr *)&req->u.connect.addr; + + fedata = dev_get_drvdata(&dev->dev); + + if (req->u.connect.len < sizeof(sa->sa_family) || + req->u.connect.len > sizeof(req->u.connect.addr) || + sa->sa_family != AF_INET) + goto out; + + ret = sock_create(AF_INET, SOCK_STREAM, 0, &sock); + if (ret < 0) + goto out; + ret = inet_stream_connect(sock, sa, req->u.connect.len, 0); + if (ret < 0) { + sock_release(sock); + goto out; + } + + map = pvcalls_new_active_socket(fedata, + req->u.connect.id, + req->u.connect.ref, + req->u.connect.evtchn, + sock); + if (!map) { + ret = -EFAULT; + sock_release(map->sock); + } + +out: + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.connect.id = req->u.connect.id; + rsp->ret = ret; + + return 0; +} + +static int pvcalls_back_release_active(struct xenbus_device *dev, + struct pvcalls_fedata *fedata, + struct sock_mapping *map) +{ + disable_irq(map->irq); + if (map->sock->sk != NULL) { + write_lock_bh(&map->sock->sk->sk_callback_lock); + map->sock->sk->sk_user_data = NULL; + map->sock->sk->sk_data_ready = map->saved_data_ready; + write_unlock_bh(&map->sock->sk->sk_callback_lock); + } + + atomic_set(&map->release, 1); + flush_work(&map->ioworker.register_work); + + xenbus_unmap_ring_vfree(dev, map->bytes); + xenbus_unmap_ring_vfree(dev, (void *)map->ring); + unbind_from_irqhandler(map->irq, map); + + sock_release(map->sock); + kfree(map); + + return 0; +} + +static int pvcalls_back_release_passive(struct xenbus_device *dev, + struct pvcalls_fedata *fedata, + struct sockpass_mapping *mappass) +{ + if (mappass->sock->sk != NULL) { + write_lock_bh(&mappass->sock->sk->sk_callback_lock); + mappass->sock->sk->sk_user_data = NULL; + mappass->sock->sk->sk_data_ready = mappass->saved_data_ready; + write_unlock_bh(&mappass->sock->sk->sk_callback_lock); + } + sock_release(mappass->sock); + flush_workqueue(mappass->wq); + destroy_workqueue(mappass->wq); + kfree(mappass); + + return 0; +} + +static int pvcalls_back_release(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + struct sock_mapping *map, *n; + struct sockpass_mapping *mappass; + int ret = 0; + struct xen_pvcalls_response *rsp; + + fedata = dev_get_drvdata(&dev->dev); + + down(&fedata->socket_lock); + list_for_each_entry_safe(map, n, &fedata->socket_mappings, list) { + if (map->id == req->u.release.id) { + list_del(&map->list); + up(&fedata->socket_lock); + ret = pvcalls_back_release_active(dev, fedata, map); + goto out; + } + } + mappass = radix_tree_lookup(&fedata->socketpass_mappings, + req->u.release.id); + if (mappass != NULL) { + radix_tree_delete(&fedata->socketpass_mappings, mappass->id); + up(&fedata->socket_lock); + ret = pvcalls_back_release_passive(dev, fedata, mappass); + } else + up(&fedata->socket_lock); + +out: + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->u.release.id = req->u.release.id; + rsp->cmd = req->cmd; + rsp->ret = ret; + return 0; +} + +static void __pvcalls_back_accept(struct work_struct *work) +{ + struct sockpass_mapping *mappass = container_of( + work, struct sockpass_mapping, register_work); + struct sock_mapping *map; + struct pvcalls_ioworker *iow; + struct pvcalls_fedata *fedata; + struct socket *sock; + struct xen_pvcalls_response *rsp; + struct xen_pvcalls_request *req; + int notify; + int ret = -EINVAL; + unsigned long flags; + + fedata = mappass->fedata; + /* + * __pvcalls_back_accept can race against pvcalls_back_accept. + * We only need to check the value of "cmd" on read. It could be + * done atomically, but to simplify the code on the write side, we + * use a spinlock. + */ + spin_lock_irqsave(&mappass->copy_lock, flags); + req = &mappass->reqcopy; + if (req->cmd != PVCALLS_ACCEPT) { + spin_unlock_irqrestore(&mappass->copy_lock, flags); + return; + } + spin_unlock_irqrestore(&mappass->copy_lock, flags); + + sock = sock_alloc(); + if (sock == NULL) + goto out_error; + sock->type = mappass->sock->type; + sock->ops = mappass->sock->ops; + + ret = inet_accept(mappass->sock, sock, O_NONBLOCK, true); + if (ret == -EAGAIN) { + sock_release(sock); + goto out_error; + } + + map = pvcalls_new_active_socket(fedata, + req->u.accept.id_new, + req->u.accept.ref, + req->u.accept.evtchn, + sock); + if (!map) { + ret = -EFAULT; + sock_release(sock); + goto out_error; + } + + map->sockpass = mappass; + iow = &map->ioworker; + atomic_inc(&map->read); + atomic_inc(&map->io); + queue_work(iow->wq, &iow->register_work); + +out_error: + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.accept.id = req->u.accept.id; + rsp->ret = ret; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&fedata->ring, notify); + if (notify) + notify_remote_via_irq(fedata->irq); + + mappass->reqcopy.cmd = 0; +} + +static void pvcalls_pass_sk_data_ready(struct sock *sock) +{ + struct sockpass_mapping *mappass = sock->sk_user_data; + struct pvcalls_fedata *fedata; + struct xen_pvcalls_response *rsp; + unsigned long flags; + int notify; + + if (mappass == NULL) + return; + + fedata = mappass->fedata; + spin_lock_irqsave(&mappass->copy_lock, flags); + if (mappass->reqcopy.cmd == PVCALLS_POLL) { + rsp = RING_GET_RESPONSE(&fedata->ring, + fedata->ring.rsp_prod_pvt++); + rsp->req_id = mappass->reqcopy.req_id; + rsp->u.poll.id = mappass->reqcopy.u.poll.id; + rsp->cmd = mappass->reqcopy.cmd; + rsp->ret = 0; + + mappass->reqcopy.cmd = 0; + spin_unlock_irqrestore(&mappass->copy_lock, flags); + + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&fedata->ring, notify); + if (notify) + notify_remote_via_irq(mappass->fedata->irq); + } else { + spin_unlock_irqrestore(&mappass->copy_lock, flags); + queue_work(mappass->wq, &mappass->register_work); + } +} + +static int pvcalls_back_bind(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + int ret; + struct sockpass_mapping *map; + struct xen_pvcalls_response *rsp; + + fedata = dev_get_drvdata(&dev->dev); + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (map == NULL) { + ret = -ENOMEM; + goto out; + } + + INIT_WORK(&map->register_work, __pvcalls_back_accept); + spin_lock_init(&map->copy_lock); + map->wq = alloc_workqueue("pvcalls_wq", WQ_UNBOUND, 1); + if (!map->wq) { + ret = -ENOMEM; + goto out; + } + + ret = sock_create(AF_INET, SOCK_STREAM, 0, &map->sock); + if (ret < 0) + goto out; + + ret = inet_bind(map->sock, (struct sockaddr *)&req->u.bind.addr, + req->u.bind.len); + if (ret < 0) + goto out; + + map->fedata = fedata; + map->id = req->u.bind.id; + + down(&fedata->socket_lock); + ret = radix_tree_insert(&fedata->socketpass_mappings, map->id, + map); + up(&fedata->socket_lock); + if (ret) + goto out; + + write_lock_bh(&map->sock->sk->sk_callback_lock); + map->saved_data_ready = map->sock->sk->sk_data_ready; + map->sock->sk->sk_user_data = map; + map->sock->sk->sk_data_ready = pvcalls_pass_sk_data_ready; + write_unlock_bh(&map->sock->sk->sk_callback_lock); + +out: + if (ret) { + if (map && map->sock) + sock_release(map->sock); + if (map && map->wq) + destroy_workqueue(map->wq); + kfree(map); + } + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.bind.id = req->u.bind.id; + rsp->ret = ret; + return 0; +} + +static int pvcalls_back_listen(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + int ret = -EINVAL; + struct sockpass_mapping *map; + struct xen_pvcalls_response *rsp; + + fedata = dev_get_drvdata(&dev->dev); + + down(&fedata->socket_lock); + map = radix_tree_lookup(&fedata->socketpass_mappings, req->u.listen.id); + up(&fedata->socket_lock); + if (map == NULL) + goto out; + + ret = inet_listen(map->sock, req->u.listen.backlog); + +out: + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.listen.id = req->u.listen.id; + rsp->ret = ret; + return 0; +} + +static int pvcalls_back_accept(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + struct sockpass_mapping *mappass; + int ret = -EINVAL; + struct xen_pvcalls_response *rsp; + unsigned long flags; + + fedata = dev_get_drvdata(&dev->dev); + + down(&fedata->socket_lock); + mappass = radix_tree_lookup(&fedata->socketpass_mappings, + req->u.accept.id); + up(&fedata->socket_lock); + if (mappass == NULL) + goto out_error; + + /* + * Limitation of the current implementation: only support one + * concurrent accept or poll call on one socket. + */ + spin_lock_irqsave(&mappass->copy_lock, flags); + if (mappass->reqcopy.cmd != 0) { + spin_unlock_irqrestore(&mappass->copy_lock, flags); + ret = -EINTR; + goto out_error; + } + + mappass->reqcopy = *req; + spin_unlock_irqrestore(&mappass->copy_lock, flags); + queue_work(mappass->wq, &mappass->register_work); + + /* Tell the caller we don't need to send back a notification yet */ + return -1; + +out_error: + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.accept.id = req->u.accept.id; + rsp->ret = ret; + return 0; +} + +static int pvcalls_back_poll(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + struct pvcalls_fedata *fedata; + struct sockpass_mapping *mappass; + struct xen_pvcalls_response *rsp; + struct inet_connection_sock *icsk; + struct request_sock_queue *queue; + unsigned long flags; + int ret; + bool data; + + fedata = dev_get_drvdata(&dev->dev); + + down(&fedata->socket_lock); + mappass = radix_tree_lookup(&fedata->socketpass_mappings, + req->u.poll.id); + up(&fedata->socket_lock); + if (mappass == NULL) + return -EINVAL; + + /* + * Limitation of the current implementation: only support one + * concurrent accept or poll call on one socket. + */ + spin_lock_irqsave(&mappass->copy_lock, flags); + if (mappass->reqcopy.cmd != 0) { + ret = -EINTR; + goto out; + } + + mappass->reqcopy = *req; + icsk = inet_csk(mappass->sock->sk); + queue = &icsk->icsk_accept_queue; + data = queue->rskq_accept_head != NULL; + if (data) { + mappass->reqcopy.cmd = 0; + ret = 0; + goto out; + } + spin_unlock_irqrestore(&mappass->copy_lock, flags); + + /* Tell the caller we don't need to send back a notification yet */ + return -1; + +out: + spin_unlock_irqrestore(&mappass->copy_lock, flags); + + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->u.poll.id = req->u.poll.id; + rsp->ret = ret; + return 0; +} + +static int pvcalls_back_handle_cmd(struct xenbus_device *dev, + struct xen_pvcalls_request *req) +{ + int ret = 0; + + switch (req->cmd) { + case PVCALLS_SOCKET: + ret = pvcalls_back_socket(dev, req); + break; + case PVCALLS_CONNECT: + ret = pvcalls_back_connect(dev, req); + break; + case PVCALLS_RELEASE: + ret = pvcalls_back_release(dev, req); + break; + case PVCALLS_BIND: + ret = pvcalls_back_bind(dev, req); + break; + case PVCALLS_LISTEN: + ret = pvcalls_back_listen(dev, req); + break; + case PVCALLS_ACCEPT: + ret = pvcalls_back_accept(dev, req); + break; + case PVCALLS_POLL: + ret = pvcalls_back_poll(dev, req); + break; + default: + { + struct pvcalls_fedata *fedata; + struct xen_pvcalls_response *rsp; + + fedata = dev_get_drvdata(&dev->dev); + rsp = RING_GET_RESPONSE( + &fedata->ring, fedata->ring.rsp_prod_pvt++); + rsp->req_id = req->req_id; + rsp->cmd = req->cmd; + rsp->ret = -ENOTSUPP; + break; + } + } + return ret; +} + +static void pvcalls_back_work(struct pvcalls_fedata *fedata) +{ + int notify, notify_all = 0, more = 1; + struct xen_pvcalls_request req; + struct xenbus_device *dev = fedata->dev; + + while (more) { + while (RING_HAS_UNCONSUMED_REQUESTS(&fedata->ring)) { + RING_COPY_REQUEST(&fedata->ring, + fedata->ring.req_cons++, + &req); + + if (!pvcalls_back_handle_cmd(dev, &req)) { + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY( + &fedata->ring, notify); + notify_all += notify; + } + } + + if (notify_all) { + notify_remote_via_irq(fedata->irq); + notify_all = 0; + } + + RING_FINAL_CHECK_FOR_REQUESTS(&fedata->ring, more); + } +} + +static irqreturn_t pvcalls_back_event(int irq, void *dev_id) +{ + struct xenbus_device *dev = dev_id; + struct pvcalls_fedata *fedata = NULL; + + if (dev == NULL) + return IRQ_HANDLED; + + fedata = dev_get_drvdata(&dev->dev); + if (fedata == NULL) + return IRQ_HANDLED; + + pvcalls_back_work(fedata); + return IRQ_HANDLED; +} + +static irqreturn_t pvcalls_back_conn_event(int irq, void *sock_map) +{ + struct sock_mapping *map = sock_map; + struct pvcalls_ioworker *iow; + + if (map == NULL || map->sock == NULL || map->sock->sk == NULL || + map->sock->sk->sk_user_data != map) + return IRQ_HANDLED; + + iow = &map->ioworker; + + atomic_inc(&map->write); + atomic_inc(&map->io); + queue_work(iow->wq, &iow->register_work); + + return IRQ_HANDLED; +} + +static int backend_connect(struct xenbus_device *dev) +{ + int err, evtchn; + grant_ref_t ring_ref; + struct pvcalls_fedata *fedata = NULL; + + fedata = kzalloc(sizeof(struct pvcalls_fedata), GFP_KERNEL); + if (!fedata) + return -ENOMEM; + + fedata->irq = -1; + err = xenbus_scanf(XBT_NIL, dev->otherend, "port", "%u", + &evtchn); + if (err != 1) { + err = -EINVAL; + xenbus_dev_fatal(dev, err, "reading %s/event-channel", + dev->otherend); + goto error; + } + + err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-ref", "%u", &ring_ref); + if (err != 1) { + err = -EINVAL; + xenbus_dev_fatal(dev, err, "reading %s/ring-ref", + dev->otherend); + goto error; + } + + err = bind_interdomain_evtchn_to_irq(dev->otherend_id, evtchn); + if (err < 0) + goto error; + fedata->irq = err; + + err = request_threaded_irq(fedata->irq, NULL, pvcalls_back_event, + IRQF_ONESHOT, "pvcalls-back", dev); + if (err < 0) + goto error; + + err = xenbus_map_ring_valloc(dev, &ring_ref, 1, + (void **)&fedata->sring); + if (err < 0) + goto error; + + BACK_RING_INIT(&fedata->ring, fedata->sring, XEN_PAGE_SIZE * 1); + fedata->dev = dev; + + INIT_LIST_HEAD(&fedata->socket_mappings); + INIT_RADIX_TREE(&fedata->socketpass_mappings, GFP_KERNEL); + sema_init(&fedata->socket_lock, 1); + dev_set_drvdata(&dev->dev, fedata); + + down(&pvcalls_back_global.frontends_lock); + list_add_tail(&fedata->list, &pvcalls_back_global.frontends); + up(&pvcalls_back_global.frontends_lock); + + return 0; + + error: + if (fedata->irq >= 0) + unbind_from_irqhandler(fedata->irq, dev); + if (fedata->sring != NULL) + xenbus_unmap_ring_vfree(dev, fedata->sring); + kfree(fedata); + return err; +} + +static int backend_disconnect(struct xenbus_device *dev) +{ + struct pvcalls_fedata *fedata; + struct sock_mapping *map, *n; + struct sockpass_mapping *mappass; + struct radix_tree_iter iter; + void **slot; + + + fedata = dev_get_drvdata(&dev->dev); + + down(&fedata->socket_lock); + list_for_each_entry_safe(map, n, &fedata->socket_mappings, list) { + list_del(&map->list); + pvcalls_back_release_active(dev, fedata, map); + } + + radix_tree_for_each_slot(slot, &fedata->socketpass_mappings, &iter, 0) { + mappass = radix_tree_deref_slot(slot); + if (!mappass) + continue; + if (radix_tree_exception(mappass)) { + if (radix_tree_deref_retry(mappass)) + slot = radix_tree_iter_retry(&iter); + } else { + radix_tree_delete(&fedata->socketpass_mappings, + mappass->id); + pvcalls_back_release_passive(dev, fedata, mappass); + } + } + up(&fedata->socket_lock); + + unbind_from_irqhandler(fedata->irq, dev); + xenbus_unmap_ring_vfree(dev, fedata->sring); + + list_del(&fedata->list); + kfree(fedata); + dev_set_drvdata(&dev->dev, NULL); + + return 0; +} + +static int pvcalls_back_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + int err, abort; + struct xenbus_transaction xbt; + +again: + abort = 1; + + err = xenbus_transaction_start(&xbt); + if (err) { + pr_warn("%s cannot create xenstore transaction\n", __func__); + return err; + } + + err = xenbus_printf(xbt, dev->nodename, "versions", "%s", + PVCALLS_VERSIONS); + if (err) { + pr_warn("%s write out 'versions' failed\n", __func__); + goto abort; + } + + err = xenbus_printf(xbt, dev->nodename, "max-page-order", "%u", + MAX_RING_ORDER); + if (err) { + pr_warn("%s write out 'max-page-order' failed\n", __func__); + goto abort; + } + + err = xenbus_printf(xbt, dev->nodename, "function-calls", + XENBUS_FUNCTIONS_CALLS); + if (err) { + pr_warn("%s write out 'function-calls' failed\n", __func__); + goto abort; + } + + abort = 0; +abort: + err = xenbus_transaction_end(xbt, abort); + if (err) { + if (err == -EAGAIN && !abort) + goto again; + pr_warn("%s cannot complete xenstore transaction\n", __func__); + return err; + } + + if (abort) + return -EFAULT; + + xenbus_switch_state(dev, XenbusStateInitWait); + + return 0; +} + +static void set_backend_state(struct xenbus_device *dev, + enum xenbus_state state) +{ + while (dev->state != state) { + switch (dev->state) { + case XenbusStateClosed: + switch (state) { + case XenbusStateInitWait: + case XenbusStateConnected: + xenbus_switch_state(dev, XenbusStateInitWait); + break; + case XenbusStateClosing: + xenbus_switch_state(dev, XenbusStateClosing); + break; + default: + WARN_ON(1); + } + break; + case XenbusStateInitWait: + case XenbusStateInitialised: + switch (state) { + case XenbusStateConnected: + backend_connect(dev); + xenbus_switch_state(dev, XenbusStateConnected); + break; + case XenbusStateClosing: + case XenbusStateClosed: + xenbus_switch_state(dev, XenbusStateClosing); + break; + default: + WARN_ON(1); + } + break; + case XenbusStateConnected: + switch (state) { + case XenbusStateInitWait: + case XenbusStateClosing: + case XenbusStateClosed: + down(&pvcalls_back_global.frontends_lock); + backend_disconnect(dev); + up(&pvcalls_back_global.frontends_lock); + xenbus_switch_state(dev, XenbusStateClosing); + break; + default: + WARN_ON(1); + } + break; + case XenbusStateClosing: + switch (state) { + case XenbusStateInitWait: + case XenbusStateConnected: + case XenbusStateClosed: + xenbus_switch_state(dev, XenbusStateClosed); + break; + default: + WARN_ON(1); + } + break; + default: + WARN_ON(1); + } + } +} + +static void pvcalls_back_changed(struct xenbus_device *dev, + enum xenbus_state frontend_state) +{ + switch (frontend_state) { + case XenbusStateInitialising: + set_backend_state(dev, XenbusStateInitWait); + break; + + case XenbusStateInitialised: + case XenbusStateConnected: + set_backend_state(dev, XenbusStateConnected); + break; + + case XenbusStateClosing: + set_backend_state(dev, XenbusStateClosing); + break; + + case XenbusStateClosed: + set_backend_state(dev, XenbusStateClosed); + if (xenbus_dev_is_online(dev)) + break; + device_unregister(&dev->dev); + break; + case XenbusStateUnknown: + set_backend_state(dev, XenbusStateClosed); + device_unregister(&dev->dev); + break; + + default: + xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend", + frontend_state); + break; + } +} + +static int pvcalls_back_remove(struct xenbus_device *dev) +{ + return 0; +} + +static int pvcalls_back_uevent(struct xenbus_device *xdev, + struct kobj_uevent_env *env) +{ + return 0; +} + +static const struct xenbus_device_id pvcalls_back_ids[] = { + { "pvcalls" }, + { "" } +}; + +static struct xenbus_driver pvcalls_back_driver = { + .ids = pvcalls_back_ids, + .probe = pvcalls_back_probe, + .remove = pvcalls_back_remove, + .uevent = pvcalls_back_uevent, + .otherend_changed = pvcalls_back_changed, +}; + +static int __init pvcalls_back_init(void) +{ + int ret; + + if (!xen_domain()) + return -ENODEV; + + ret = xenbus_register_backend(&pvcalls_back_driver); + if (ret < 0) + return ret; + + sema_init(&pvcalls_back_global.frontends_lock, 1); + INIT_LIST_HEAD(&pvcalls_back_global.frontends); + return 0; +} +module_init(pvcalls_back_init); + +static void __exit pvcalls_back_fin(void) +{ + struct pvcalls_fedata *fedata, *nfedata; + + down(&pvcalls_back_global.frontends_lock); + list_for_each_entry_safe(fedata, nfedata, + &pvcalls_back_global.frontends, list) { + backend_disconnect(fedata->dev); + } + up(&pvcalls_back_global.frontends_lock); + + xenbus_unregister_driver(&pvcalls_back_driver); +} + +module_exit(pvcalls_back_fin); diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index 5fbfd9cfb6d63e61c1c89e6a9deb071ce6de2d32..5b3d57fc82d39bc8fdbcfb89582589a2be854357 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c @@ -169,6 +169,9 @@ static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data) static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data) { struct pci_bar_info *bar = data; + unsigned int pos = (offset - PCI_BASE_ADDRESS_0) / 4; + const struct resource *res = dev->resource; + u32 mask; if (unlikely(!bar)) { pr_warn(DRV_NAME ": driver data not found for %s\n", @@ -179,7 +182,13 @@ static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data) /* A write to obtain the length must happen as a 32-bit write. * This does not (yet) support writing individual bytes */ - if (value == ~0) + if (res[pos].flags & IORESOURCE_IO) + mask = ~PCI_BASE_ADDRESS_IO_MASK; + else if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64)) + mask = 0; + else + mask = ~PCI_BASE_ADDRESS_MEM_MASK; + if ((value | mask) == ~0U) bar->which = 1; else { u32 tmpval; diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 6331a95691a44d553b01e8dfbbdb9fb7d42c8e88..9e480fdebe1f059419e8864c473e3c6ee2f02cb4 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -1172,8 +1172,8 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, return err; } -static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf, - size_t count) +static ssize_t new_slot_store(struct device_driver *drv, const char *buf, + size_t count) { int domain, bus, slot, func; int err; @@ -1189,10 +1189,10 @@ static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf, err = count; return err; } -static DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add); +static DRIVER_ATTR_WO(new_slot); -static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf, - size_t count) +static ssize_t remove_slot_store(struct device_driver *drv, const char *buf, + size_t count) { int domain, bus, slot, func; int err; @@ -1208,9 +1208,9 @@ static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf, err = count; return err; } -static DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove); +static DRIVER_ATTR_WO(remove_slot); -static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf) +static ssize_t slots_show(struct device_driver *drv, char *buf) { struct pcistub_device_id *pci_dev_id; size_t count = 0; @@ -1231,9 +1231,9 @@ static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf) return count; } -static DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL); +static DRIVER_ATTR_RO(slots); -static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf) +static ssize_t irq_handlers_show(struct device_driver *drv, char *buf) { struct pcistub_device *psdev; struct xen_pcibk_dev_data *dev_data; @@ -1260,11 +1260,10 @@ static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf) spin_unlock_irqrestore(&pcistub_devices_lock, flags); return count; } -static DRIVER_ATTR(irq_handlers, S_IRUSR, pcistub_irq_handler_show, NULL); +static DRIVER_ATTR_RO(irq_handlers); -static ssize_t pcistub_irq_handler_switch(struct device_driver *drv, - const char *buf, - size_t count) +static ssize_t irq_handler_state_store(struct device_driver *drv, + const char *buf, size_t count) { struct pcistub_device *psdev; struct xen_pcibk_dev_data *dev_data; @@ -1301,11 +1300,10 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv, err = count; return err; } -static DRIVER_ATTR(irq_handler_state, S_IWUSR, NULL, - pcistub_irq_handler_switch); +static DRIVER_ATTR_WO(irq_handler_state); -static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf, - size_t count) +static ssize_t quirks_store(struct device_driver *drv, const char *buf, + size_t count) { int domain, bus, slot, func, reg, size, mask; int err; @@ -1323,7 +1321,7 @@ static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf, return err; } -static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf) +static ssize_t quirks_show(struct device_driver *drv, char *buf) { int count = 0; unsigned long flags; @@ -1366,11 +1364,10 @@ static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf) return count; } -static DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, - pcistub_quirk_add); +static DRIVER_ATTR_RW(quirks); -static ssize_t permissive_add(struct device_driver *drv, const char *buf, - size_t count) +static ssize_t permissive_store(struct device_driver *drv, const char *buf, + size_t count) { int domain, bus, slot, func; int err; @@ -1431,8 +1428,7 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf) spin_unlock_irqrestore(&pcistub_devices_lock, flags); return count; } -static DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, - permissive_add); +static DRIVER_ATTR_RW(permissive); static void pcistub_exit(void) { diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 82a8866758ee0d5ac235430059f74a7bb56b09f8..a1c17000129ba1cb4465df0bc679a0756f8937a3 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -519,64 +519,6 @@ static int __xenbus_map_ring(struct xenbus_device *dev, return err; } -static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev, - grant_ref_t *gnt_refs, - unsigned int nr_grefs, - void **vaddr) -{ - struct xenbus_map_node *node; - struct vm_struct *area; - pte_t *ptes[XENBUS_MAX_RING_GRANTS]; - phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS]; - int err = GNTST_okay; - int i; - bool leaked; - - *vaddr = NULL; - - if (nr_grefs > XENBUS_MAX_RING_GRANTS) - return -EINVAL; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - - area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, ptes); - if (!area) { - kfree(node); - return -ENOMEM; - } - - for (i = 0; i < nr_grefs; i++) - phys_addrs[i] = arbitrary_virt_to_machine(ptes[i]).maddr; - - err = __xenbus_map_ring(dev, gnt_refs, nr_grefs, node->handles, - phys_addrs, - GNTMAP_host_map | GNTMAP_contains_pte, - &leaked); - if (err) - goto failed; - - node->nr_handles = nr_grefs; - node->pv.area = area; - - spin_lock(&xenbus_valloc_lock); - list_add(&node->next, &xenbus_valloc_pages); - spin_unlock(&xenbus_valloc_lock); - - *vaddr = area->addr; - return 0; - -failed: - if (!leaked) - free_vm_area(area); - else - pr_alert("leaking VM area %p size %u page(s)", area, nr_grefs); - - kfree(node); - return err; -} - struct map_ring_valloc_hvm { unsigned int idx; @@ -725,6 +667,65 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr) } EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree); +#ifdef CONFIG_XEN_PV +static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev, + grant_ref_t *gnt_refs, + unsigned int nr_grefs, + void **vaddr) +{ + struct xenbus_map_node *node; + struct vm_struct *area; + pte_t *ptes[XENBUS_MAX_RING_GRANTS]; + phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS]; + int err = GNTST_okay; + int i; + bool leaked; + + *vaddr = NULL; + + if (nr_grefs > XENBUS_MAX_RING_GRANTS) + return -EINVAL; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return -ENOMEM; + + area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, ptes); + if (!area) { + kfree(node); + return -ENOMEM; + } + + for (i = 0; i < nr_grefs; i++) + phys_addrs[i] = arbitrary_virt_to_machine(ptes[i]).maddr; + + err = __xenbus_map_ring(dev, gnt_refs, nr_grefs, node->handles, + phys_addrs, + GNTMAP_host_map | GNTMAP_contains_pte, + &leaked); + if (err) + goto failed; + + node->nr_handles = nr_grefs; + node->pv.area = area; + + spin_lock(&xenbus_valloc_lock); + list_add(&node->next, &xenbus_valloc_pages); + spin_unlock(&xenbus_valloc_lock); + + *vaddr = area->addr; + return 0; + +failed: + if (!leaked) + free_vm_area(area); + else + pr_alert("leaking VM area %p size %u page(s)", area, nr_grefs); + + kfree(node); + return err; +} + static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr) { struct xenbus_map_node *node; @@ -788,6 +789,12 @@ static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr) return err; } +static const struct xenbus_ring_ops ring_ops_pv = { + .map = xenbus_map_ring_valloc_pv, + .unmap = xenbus_unmap_ring_vfree_pv, +}; +#endif + struct unmap_ring_vfree_hvm { unsigned int idx; @@ -916,11 +923,6 @@ enum xenbus_state xenbus_read_driver_state(const char *path) } EXPORT_SYMBOL_GPL(xenbus_read_driver_state); -static const struct xenbus_ring_ops ring_ops_pv = { - .map = xenbus_map_ring_valloc_pv, - .unmap = xenbus_unmap_ring_vfree_pv, -}; - static const struct xenbus_ring_ops ring_ops_hvm = { .map = xenbus_map_ring_valloc_hvm, .unmap = xenbus_unmap_ring_vfree_hvm, @@ -928,8 +930,10 @@ static const struct xenbus_ring_ops ring_ops_hvm = { void __init xenbus_ring_ops_init(void) { +#ifdef CONFIG_XEN_PV if (!xen_feature(XENFEAT_auto_translated_physmap)) ring_ops = &ring_ops_pv; else +#endif ring_ops = &ring_ops_hvm; } diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index e460802149555b6f0d5def7659d8e8207828eb53..3e59590c7254ddc8f1a08f4232262a74a29e3711 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -857,6 +857,8 @@ static int xenwatch_thread(void *unused) struct list_head *ent; struct xs_watch_event *event; + xenwatch_pid = current->pid; + for (;;) { wait_event_interruptible(watch_events_waitq, !list_empty(&watch_events)); @@ -925,7 +927,6 @@ int xs_init(void) task = kthread_run(xenwatch_thread, NULL, "xenwatch"); if (IS_ERR(task)) return PTR_ERR(task); - xenwatch_pid = task->pid; /* shutdown watches for kexec boot */ xs_reset_watches(); diff --git a/firmware/3com/typhoon.bin.ihex b/firmware/3com/typhoon.bin.ihex deleted file mode 100644 index d7a83bea0c3ba61fb8592363f728249abe79a5ad..0000000000000000000000000000000000000000 --- a/firmware/3com/typhoon.bin.ihex +++ /dev/null @@ -1,2819 +0,0 @@ -:10000000545950484F4F4E000200000009000000B4 -:100010000000FFFFCB99B1D44CB8D04B3202D4EEE4 -:10002000737E0B139BC0AEF440010000E8FC00009F -:100030000000FFFF390000EA050000EA040000EAC2 -:10004000030000EA020000EA010000EA320200EACE -:10005000C51400EA07002DE90E00A0E100100FE131 -:10006000D0209FE512FF2FE1FEFFFFEA010080E0B4 -:10007000042081E4010050E1FCFFFF1A0EF0A0E132 -:1000800000A0A0E10EB0A0E10000A0E3A8109FE551 -:10009000000081E5A4109FE5000081E50116A0E3C2 -:1000A000000091E5010080E3000081E5D700A0E3B6 -:1000B00000F021E188D09FE5DB00A0E300F021E122 -:1000C0007CD09FE5D200A0E300F021E174D09FE551 -:1000D000D100A0E300F021E16CD09FE59B1400EB80 -:1000E000D300A0E300F021E160D09FE560009FE530 -:1000F00060109FE560209FE5DBFFFFEB5C009FE564 -:100100005C109FE50020A0E3D7FFFFEB54009FE5C4 -:1001100054109FE5D4FFFFEB0A00A0E10BF0A0E133 -:10012000D310A0E301F021E1D4FFFFEB3CA09FE559 -:100130001AFF2FE1C6FFFFEA1521FFFF0C00100098 -:100140001C0010003C380080FC370080FC3F008021 -:100150007C340080800F000080300080ADDEADDE9A -:10016000B0BB000024AB20404829000028050080D7 -:10017000BDBA214000000000FFFF000000000000A9 -:1001800000000000FFFF00000000000058570000C2 -:10019000864B00006001FFFFB0B5071C124D002424 -:1001A000286800281ED0381C104904F07BFD2968FF -:1001B000C0460860002815D038010D4940181923A1 -:1001C000DB01C018416B80290CD2013141632868E2 -:1001D000C169C0462960390741600462C762B0BC8A -:1001E00008BC1847201CFAE7E8170080EE0500005D -:1001F000A01C008002490A68C046C26108607047BE -:10020000E81700807047000070470000704700004A -:1002100000000FE10010A0E1C01081E301F021E136 -:100220001EFF2FE100F021E11EFF2FE100000FE192 -:10023000C00080E300F021E11EFF2FE100000FE18C -:10024000C000C0E300F021E11EFF2FE100000FE13C -:10025000400080E300F021E11EFF2FE100000FE1EC -:10026000800010E3800080E300F021E10000001234 -:100270001EFF2FE1000050E300000FE18000C013DB -:1002800000F021E11EFF2FE100000FE18000C0E33C -:1002900000F021E11EFF2FE1910000E01EFF2FE1A1 -:1002A000012080E0010080E01EFF2FE180B5084FB3 -:1002B000642804D3642038630020C04303E038631B -:1002C000044905F001FB7863B86380BC08BC18479B -:1002D000680E00808813000080B4104B00221F6B52 -:1002E000642F03D209680968490802D2101C80BC37 -:1002F0007047191CDB6B4F6BBB4205D24068000492 -:10030000000C1818C863F1E74168054B19434160B8 -:100310000448C16B0131C1630220E8E7680E008028 -:10032000000000800C2B008090B5071C154C0020AD -:10033000216B64290BD2B96E490808D3216CA26BDA -:10034000914207D2FA1D3932528B8918216490BC30 -:1003500008BC1847786A396BC0464862386B02F0AF -:100360002DFE381C02F0E8FA0120BB231B01E11826 -:10037000C87305490A6C12180A6404498A6D121878 -:100380008A65E4E7680E00800C2B0080A42A0080B8 -:1003900080B40A48C06D02231840094A0021002891 -:1003A00003D0D163116480BC7047064807687B1C8A -:1003B00003600A2FF7D30160F3E70000A42A00804E -:1003C000680E0080E001008070470204120C000CEF -:1003D00010180A04120C090C51180818010C05D049 -:1003E0000104090C000C0818010CF9D10004000CE0 -:1003F000704780B40022002918D04F087B1E002FC0 -:1004000006D00788BA1802301F1C013B002FF8D114 -:10041000490803D300880006000E8218100C05D08E -:100420001004000C110C4218100CF9D11004000C2F -:1004300080BC704780B58389C789FB18078AFB1881 -:10044000478AFB18407A0002C718380C05D03804D8 -:10045000000C3B0CC718380CF9D1081C111CFFF715 -:10046000C8FF011C381CFFF7B0FF80BC08BC184750 -:1004700090B5022382681A400027002A0FD00A4A4A -:100480009369013393610A688B689A1800681C1895 -:1004900057810969101CFFF7ACFFC0436081381C0D -:1004A00090BC08BC184700000C2B008090B50423BA -:1004B00082681A400027002A11D04A6852090ED3D8 -:1004C000094A136A01331362CB6802689C1801233E -:1004D0009B07083A1A43126800F02EF82082381C55 -:1004E00090BC08BC184700000C2B008090B58023FE -:1004F00082681A400024002A15D04A68920912D353 -:100500000B4AD3690133D361CB6802689F1801237A -:100510009B07083A1A43126800F00EF8002800D131 -:100520000448C046F880201C90BC08BC1847000056 -:100530000C2B0080FFFF0000B0B5141C051C0F1C25 -:100540003869B96841183868FFF753FFC0430104A0 -:10055000090C201CFFF739FF041CB86879694018A2 -:10056000696888420CD22A681218091A101C00F017 -:1005700005F9C0430104090C201CFFF726FF041CE9 -:10058000E0430004000CB0BC08BC184780B5071C51 -:10059000B86BC0081AD3B86AF96B4018796C00F0D0 -:1005A000EDF8C0430104090C0A4807D02023B969BB -:1005B0001943B961016B0131016307E0FF23013386 -:1005C000B9691943B961416A01314162002080BCB7 -:1005D00008BC18470C2B008080B5071CB86B41097C -:1005E0001CD3C0081AD3F81D3930007B062815D15A -:1005F000381C00F053F8011C0A4807D04023B969A1 -:100600001943B961816B0131816307E001239B02CA -:10061000B9691943B961C16A0131C162002080BC66 -:1006200008BC18470C2B0080B0B5071CB86B8109BB -:100630002CD3C0082AD3F81D3930007B112825D1CE -:10064000B86A396C401801239B07063018430068CC -:1006500005042D0C0F4C11D0381C00F01FF8002899 -:100660000CD0A84202D10C4B984207D08023B86925 -:100670001843B861606B0130606307E001235B02DF -:10068000B8691843B861A06A0130A0620020B0BC0C -:1006900008BC18470C2B0080FFFF0000F0B5FFB02E -:1006A00099B0041CE06B616C091803AA8518A36A51 -:1006B00000208A080132979207D082009F5803AE2B -:1006C000B750979A01308242F7D8606A01239B079E -:1006D000043018430068C046029002AF3F8803A868 -:1006E000FFF787FEC0430104090C381CFFF76DFEBD -:1006F000071CE06BA16C4018616A01239B0708315D -:1007000019430968C046019101A90988013188424D -:100710000CD2A26A1218091A101C00F02FF8C0435C -:100720000104090C381CFFF750FE071CA889E98951 -:100730000818298A0818698A0818697A09020818A5 -:10074000A16C626C891A0A04120C1102120A11437C -:100750000904090C0918080C05D00804000C090C40 -:100760004118080CF9D1381CFFF72FFEC0430004D4 -:10077000000C7FB019B0F0BC08BC1847B0B4002220 -:1007800000292ED083079B0FDC0047180425EF1BA0 -:10079000BF07BF0FFF008008800059180331890888 -:1007A0004D1E02C8E140A1406B1E002D09D00C0473 -:1007B000240CA218090C8A1802C81C1C013B002C2E -:1007C000F5D1B940081CF8400104090C8918000C47 -:1007D0004218100C05D01004000C110C4218100C1B -:1007E000F9D11004000CB0BC7047000090B4002098 -:1007F0000127114942001218D20053189C680123A6 -:100800009B0723431B681B031B0B8A581203120B05 -:1008100093420CD101300428ECD30848C06A01038C -:10082000090B0748006F0003000B814202D0381CFF -:1008300090BC70470020FBE7A803008000401440F4 -:10084000680E008098B4144AC04600928300134892 -:10085000C05807033F0B1248C0580203120B11483F -:10086000C0580003000B104CE45801239B0723439E -:100870001B689B00CC000121984201D1081C09E0B3 -:10088000984203D9101ADA1B801800E0181A844223 -:10089000F4D3002098BC704755555555200400806E -:1008A00028040080080400801804008080B4130429 -:1008B00000D0013A80000B1C13490F58C0463B6022 -:1008C0000B58C0465A600A580832104B1B589A42BF -:1008D00001D30F4A12580F4B1F5801239B073B436C -:1008E0001B689B0017033F0B9F4206D10A48C16853 -:1008F0000131C160012080BC7047084B1B58C046C5 -:100900001A600A500020F6E70804008028040080DE -:100910002004008018040080A08220401004008081 -:10092000FF5F2DE948FEFFEB01B6A0E301B18BE2CA -:10093000028AA0E3017AA0E301A9A0E30156A0E3A3 -:10094000C8609FE5C8909FE514409BE5000054E314 -:100950002C00000A030A14E31100000A0C0096E5BB -:10096000000050E32100000A010A14E30500000A18 -:100970001C0096E5010AC0E31C0086E51C0085E525 -:10098000147085E5060000EA020A14E30400000A78 -:100990001C0096E5020AC0E31C0086E51C0085E504 -:1009A000148085E5010914E30400000A1C0096E5A3 -:1009B0000109C0E31C0086E51C0085E514A085E55F -:1009C000020014E34000001B010014E35400001B6C -:1009D000020B14E36700001B010B14E32000001B53 -:1009E000180099E5010080E2180089E5D5FFFFEACB -:1009F0001C0096E5010AC0E31C0086E51C0085E5A5 -:100A0000147085E5E1FFFFEAFF5FBDE804F05EE2F8 -:100A1000680E00800883204010101FE5143091E517 -:100A20000020C3E1142081E50116A0E30C2081E53C -:100A30000B12A0E3000081E518109FE5B024D1E17E -:100A4000012082E2B024C1E13C2091E5000082E176 -:100A50003C0081E51EFF2FE1A0822040FFFFFFEA5E -:100A6000FEFFFFEA010BA0E30116A0E3140081E5FD -:100A7000001A81E1242091E570001FE500000000CC -:100A8000242080E5281091E500000000281080E572 -:100A90002C2090E5012082E22C2080E53F0001E23D -:100AA0003F0050E31EFF2F1118009FE5001090E556 -:100AB000011081E2001080E50218A0E30B02A0E320 -:100AC000001080E51EFF2FE1300400800106A0E346 -:100AD000010180E2001090E5010811E30B10A0E392 -:100AE000021981E20500001A002090E54228B0E1D9 -:100AF0000500001A000090E5020C10E30200000A55 -:100B00000607A0E34C1180E5030000EA0C009FE516 -:100B100000000000401080E5FFFFFFEAFEFFFFEA53 -:100B2000000000800106A0E3010180E2001090E5D2 -:100B3000010811E30C10A0E3021981E20500001A7C -:100B4000002090E54228B0E10500001A000090E581 -:100B5000020C10E30200000A0607A0E34C1180E536 -:100B6000030000EA4C001FE500000000401080E593 -:100B7000FFFFFFEAFEFFFFEA021BA0E30106A0E37E -:100B8000141080E51EFF2FE180211FE5143092E54F -:100B900000000000003080E51C0092E5000000002D -:100BA000000081E50010A0E3141082E50106A0E337 -:100BB0001C1082E50C1080E51C1092E5000000007E -:100BC0001C1080E51EFF2FE1C0211FE50000000082 -:100BD0001C1082E50116A0E3140082E50C0081E5FB -:100BE0001C0092E5000000001C0081E51EFF2FE1C3 -:100BF00080B50F1C381C00F017F8002802D0381CF4 -:100C000000F092F8002080BC08BC184780B50F1C8B -:100C1000381C00F009F8002802D0381C00F084F8D5 -:100C2000002080BC08BC1847F0B407683A78D207A7 -:100C3000D20F0024002A03D0FF220132426000E0DC -:100C400044603A7B7B7B1B021A43812A08D1012333 -:100C50005B0242681A4342600422BF18826000E0CF -:100C600084603A7B7B7B1B021A43082A06D1062349 -:100C700041681943416081680E313CE0C123DB00CB -:100C80009A4203D14168244B19433EE0234B9A42D8 -:100C900004D101231B034168194336E01302120AF1 -:100CA0001206120E1A431204120C2E3A1C4B9A42D0 -:100CB0002DD80125426815434560BA7BFB7B1B029A -:100CC0001A43184B9A4222D1FB1D093344CB9B0790 -:100CD000DB0EDA405B4220339E401643032E18D1D0 -:100CE000397D7B7D1B021943082907D10421294343 -:100CF000416081681631816001210AE0C123DB0077 -:100D0000994204D1012189032943416000E08460B4 -:100D10000021081CF0BC70470240000081800000E8 -:100D2000AE050000AAAA000080B44268D1083FD3F3 -:100D300001688368591802398F783F073F0F052FE4 -:100D400003D1DA1D0D32C26005E0BF00DB19C360BC -:100D500008231A4342608A781207120F9200026138 -:100D60000A794B791B021A431302120A1206120E59 -:100D70001A431204120C4261CA7A062A03D11023C4 -:100D800042681A4310E0112A03D1202342681A4313 -:100D90000AE0332A03D1402342681A4304E0322A8E -:100DA00003D1802342681A434260C97AC046017663 -:100DB00080BC70470A78C04602604B781B021A4319 -:100DC00002608B781B041A430260C978090611433C -:100DD0000160704780B5071C4868800926D3B86A4F -:100DE000C968401801239B070230184300680004BB -:100DF000000C11239B02984218D1786A396BC046C7 -:100E00004862386B02F0DAF8381C01F095FD0120D9 -:100E10000749C046C87307494A6C12184A64064914 -:100E20008A6D12188A6580BC08BC18470020FAE752 -:100E3000181A00800C2B0080A42A0080810719D08A -:100E40008008800001239B07011D18430068194397 -:100E500009680202120E1206000AFF231B04184042 -:100E600010430A0A1206120E104309021B0A194007 -:100E70000843704701239B071843006801060202DC -:100E8000FF231B041A401143020A1B0A1A40114394 -:100E9000000E0843EDE70000F0B50423816B194014 -:100EA0000022002946D0C71D3937397B332901D0AC -:100EB00032293FD1016BC0464A65C41D2D34CD1D7A -:100EC0002D3500229300E658C046EE500132072A25 -:100ED000F8D3826AC0464A63826AC0468A627A8BC5 -:100EE000CB1D39335A83406AC046486212480127F5 -:100EF0004268002A10D1C268002A13D14269002A30 -:100F00000DD10161C160016A022902D3203007714D -:100F10000CE000F013F809E0C268002A02D1016178 -:100F2000C16003E00269C04651650161381CF0BC34 -:100F300008BC1847101CFAE76C06008080B51E49F3 -:100F40000022CB68002B34D0C81DF9308362CB68F7 -:100F50009B6AC046C362CF697B00DF197F02174BD3 -:100F6000FF18FF37653783630763CB1DFF335A33A1 -:100F70001A72CB69002B01D0CA6101E00123CB6159 -:100F80000F1CC968496A098901314163F81DFF30A6 -:100F90003A30426002828260C260381C00F0CEFAB1 -:100FA000386A01303862381C00F00AF880BC08BC8E -:100FB0001847101CFAE700006C060080ACAB20401C -:100FC000F0B5071CF91DF931886AC21D2D320123C5 -:100FD0009B0708321A43C86A12681204120C801860 -:100FE0008279C3791B021A431302120A1206120EE7 -:100FF0001A431204120C02389204920C0026254D5A -:10100000EC1DFF343A34002A04D0208A01239B02CD -:1010100018432BE001239B07C21D0D321A431268AF -:1010200012041230184300680004000C1043031C23 -:10103000F81DFF304A308278C86B191C02F002F8A4 -:10104000002804DA208AFF23013318430EE0F91D3B -:10105000FF313A3108600104090C381C00F01CF81B -:10106000002814D1208A01235B0218432082218AA0 -:10107000381C00F0A2FBE86801239B07543018439A -:101080000068C046E860301CF0BC08BC184701206E -:10109000FAE700006C060080F8B5071CFC1DF93467 -:1010A000A06BA66AC51D0D353848C06A4B0059189B -:1010B0004901421801208007104300680004000C19 -:1010C000009001239B07D01D053018430068381C91 -:1010D000291C00F0C2FAA888410701D0002051E085 -:1010E00029890918606B8142F8D86989EA888918CA -:1010F0008142F3D80098012825D1E06AF16B4018AD -:10110000716CFA1DCD3201F033F9FA1DFF323A321B -:10111000E06A51694018C31D0333002081005E5806 -:10112000C919FF3101314E6101300428F6D3E06A5C -:1011300051694018C11D0531002000224300CA52E8 -:1011400001300628FAD3291C114A0020FFF7AEFB14 -:1011500001225204606B02430120216BFFF7A6FBC2 -:1011600001225204606B02430020E16AFFF79EFBFC -:10117000A16B084A0120FFF799FB03200649C046EE -:1011800048620120F8BC08BC184700004C2A0080C7 -:101190005400030014000F006C070080F0B58DB000 -:1011A0000020B54AD51DF935686201200005B34914 -:1011B000C0460860A86AC41D2D34B148C06AD71D56 -:1011C000FF373A3739684B00591849014018012355 -:1011D0009B07C11D05311943096808301843006891 -:1011E000C0460990FF231B021840000A0A900A9883 -:1011F000A44E012859D1286BA2688018A24A2169FF -:101200000904090C01F026F9286B79694018C11D01 -:10121000053100208200984BD318FF3301335B69FE -:10122000C0468B5001300428F4D30020311C8200CA -:10123000561801239B0733431B6804AEB35001309B -:101240000328F4D300200890904942008B5AB25AE8 -:10125000934213D08E48C1890131C181B8680028FA -:1012600003D1388A1023184371E0388A4023184389 -:101270006DE000F011F901F067FFF5E0013006289C -:10128000E3D3089800280CD1B868411CB960002845 -:1012900003D1388A0123184302E0388A0423184313 -:1012A000388278680130786062E00A9802285FD15D -:1012B0000998400C73D301239B07E01D01301843AC -:1012C0000068E11D0D311943096840180C3800040D -:1012D000000C00218A006B4BD61801239B07334377 -:1012E0001B6804AEB35001310329F3D30021831EE0 -:1012F0000C93684A166BC0460B968A000C9B9B1891 -:101300000B9E9E1901239B0733431B686E46B35007 -:1013100001310429F1D369468B1C07930021089100 -:1013200004AE4A00079B9B5AB25A934211D05848C8 -:10133000C1890131C181F868411CF960002803D1DD -:10134000388A2023184302E0388A802318433882E1 -:101350008FE701310629E4D3089900290DD1F968F6 -:101360004A1CFA60002904D1398A0223194303E098 -:101370000CE0398A082319433982296B08180123A4 -:101380009B07013818430068C046207601239B075D -:10139000E01D1130184300680106090E00E019E055 -:1013A00035482A6BC046EA6204294FD10121C61D87 -:1013B000FF365A3631720A9902291ED10999090E4F -:1013C00049061AD1E11D0531194309680906090EBC -:1013D00008391AE001239B07E01D0130184300681B -:1013E000E11D0D311943096840180004000CF9682B -:1013F0004A1CFA600029BCD1B6E701239B07E11D16 -:101400000531194309680906090EA160E86AC0465A -:101410002060201CFFF788FC207E332801D0322872 -:1014200011D10121144CC046F960B960201C00F0B4 -:1014300085F8286BA96AC0468862201CFFF7C0FDAA -:10144000002811D10EE00020307211E0332901D0C4 -:1014500032290DD1071C00F071F8381CFFF7B0FDE0 -:10146000002801D101F070FE0DB0F0BC08BC184797 -:1014700000F012F8F6E700006C060080000000B0F3 -:101480004C2A0080ACAB20404007008082070080DF -:101490000C2B00806C070080F0B5254841680131B5 -:1014A0004160244FF91DF9310024886AFA68C0466A -:1014B00094610422FB68C046DA601022FB68C046D3 -:1014C0009A61FA1DFF325A32137A1B4A002B0BD055 -:1014D000158A2E0A360233232B409B001E43CC2351 -:1014E0002B409B0833431382128AFB68C046DA8381 -:1014F0004A6BFB68C046DA810A6BC0468262C462EE -:10150000C31D39334A6BC0465A83042302681A4309 -:101510000260886A01F032FAF86801239B075430B0 -:1015200018430068C046F860F0BC08BC18470000CB -:101530000C2B00806C060080AC07008080B5C11DBC -:10154000F9318A6A01239B07D11D45311943096886 -:101550000B061B0E0127C11DFF314A31332B05D16C -:101560008B70011C101C00F00FF806E0322B08D124 -:101570008B70011C101C00F03CF8381C80BC08BCAF -:10158000184700208870F9E790B4CA1DF932332754 -:10159000CC1DFF344A34D36AC046A770FF314131B5 -:1015A000076CC0464F61FB18391C9F1E01239B0727 -:1015B000FC1C23431B681B061B0E9B001B041B0CFF -:1015C000C9180831016401239B07B91C1943096834 -:1015D00034300176F81D0130184300680004B91D4D -:1015E0001943D06309680904090C0843D06390BC0F -:1015F0007047B0B5CA1DF932C51D2D353220CF1D3B -:10160000FF374A37D36AC046B870CC1DFF343A342E -:10161000E868C04660611030E8606069C018871EE5 -:1016200001239B07381D184300680004B91C1943A7 -:10163000D06309680904090C0843D063F81D03301E -:10164000FFF7FCFB2062F81D0730FFF7F7FB606235 -:1016500000202876B0BC08BC1847F7B581B00198C7 -:10166000C71DF937B86A01239B07D41D05342343EE -:101670001C68FF23FE3323407F6B3F043B430B601A -:1016800034301C1C80232340019FFF374137002B3F -:101690003CD00C23009300239D00AE1836696D18D2 -:1016A0006E610133052BF7D300239D00AE18766AD7 -:1016B0006D18AE620133052BF7D3019BFF33513315 -:1016C0009B78332B0ED101239B07C51D01352B437E -:1016D0001B68C0464B8101239B07C51D0D352B435D -:1016E0001B6816E07B69C0464B8101239B07C51D23 -:1016F0000D352B431B687D695D1B01239B07C61DB0 -:10170000013633431B68EB180C3B02E000230093C7 -:101710004B81CB80630949D301239B07C41D05344A -:1017200023431B68C0460B8101239B07C41D0D3456 -:1017300023431B680C891B1B009C1C1B01239B075C -:1017400008301843006820188880386A040EFF2388 -:101750001B0403401B0A1C43FF231B0203401B0204 -:10176000234300061843C860786A070EFF231B0452 -:1017700003401B0A1F43FF231B0203401B023B4382 -:10178000000618430861D06BC046C863906BC04622 -:101790000864506CC0464864106CC0468864D06CC5 -:1017A000C046C864906CC046086502E000230B8107 -:1017B0008B8004B0F0BC08BC184700B50F4A938971 -:1017C00001339381C21DF9320423906AC046C3607D -:1017D00010238361CB0A01D318238361C183516B2A -:1017E000C046C181516BC21D393251830423016847 -:1017F0001943016001F0C2F808BC18470C2B0080A7 -:10180000B0B51B4C206A02281BD20020E71D1937F7 -:101810003871E168E01DF930002915D0426A002ACC -:1018200012D101250AE0FFF789FB002809D1206ABF -:10183000022800D33D71E068002802D038790028E2 -:10184000F1D0B0BC08BC1847406A0028F9D1002983 -:10185000F7D16069002804D00648006803F0A8FCAE -:10186000EFE760680028ECD000F05AF8E9E70000E4 -:101870006C06008034040080B0B5071C2023B868D3 -:1018800018400124002500280BD1386A002803D114 -:10189000281CB0BC08BC18471F48016E0131016606 -:1018A00003E04868C423184003D1386A00F00CFCF8 -:1018B0002FE0381C00F01CFC381C00F07BFAB868E4 -:1018C000C00802D3386A00F0D1FBB868396AC04654 -:1018D0008860386AC046C56010484168002911D147 -:1018E000C168002909D14169002906D1396AC04679 -:1018F0008160416000F014F80BE0396AC0468160F5 -:10190000416006E0396A8268C046D160396AC046E3 -:101910008160201CBDE70000A42A00806C060080C6 -:1019200090B50B4C6768002F0FD0381C00F012F8F0 -:1019300000280AD16068C068C0466060381C00F0AA -:10194000C3FB002090BC08BC18470120FAE7000048 -:101950006C060080F0B5071CFE1D4936307840004B -:10196000C019858B334C344B9D423CD0381C211C14 -:101970002A1C00F01DF93148806A5821694340183B -:1019800001239B07184300680004000C2C4D01281C -:101990001AD13078C019C11D1931087A3A688018F7 -:1019A000097BEA1D213200F0E3FC3078C0192030B9 -:1019B000007939684018C11D05310020002342001C -:1019C0008B5201300628FAD3A08841070BD1218918 -:1019D000091878680004000C814204D86189E28803 -:1019E0008918814203D90020F0BC08BC1847211C8B -:1019F000144A0020FEF75AFF01225204786802437D -:101A000001203968FEF752FF012252047868024330 -:101A100000203968FEF74AFF0B490C4A0120FEF707 -:101A200045FF0120E91D193148710221EA1DF932F3 -:101A30005162D9E728AC2040FFFF00004C2A00800B -:101A40006C0600805400030014AC20401400070012 -:101A5000F0B583B000214F48C21DF9325162012117 -:101A6000C9044D4AC0461160C11D19314979002988 -:101A700004D14A48006803F09BFB87E0454847686B -:101A8000FC1D493421784800C019808B444A926A71 -:101A900058235843151801239B07EA1D05321A43A2 -:101AA000126808352B431D68FF231B022B401B0ABD -:101AB0003C4D012B24D1C819C11D1931087A3A684F -:101AC0008018394A097B00F0C5FC2078C019203005 -:101AD0000079396841180020820053199B6E6E46C8 -:101AE000B35001300328F7D3CA1D053269460020E0 -:101AF0004300CD5AC046D55201300628F8D32DE018 -:101B0000022B2BD1110A29D300218A0053199B6E75 -:101B10006E46B35001310329F7D321784900C91922 -:101B2000098F3A688B186A4600214D00565BC04603 -:101B30005E5301310629F8D319498A6A13181A6DC0 -:101B4000009D5540194AD66875401D65896A081878 -:101B5000416D029B59409269514041652078411E78 -:101B6000217000280DD0381CFFF7F4FE00280DD19D -:101B7000084A5068C068C0465060381C00F0A4FA9B -:101B800002E0381C00F073FA01F0DEFA03B0F0BC9A -:101B900008BC18476C060080000000B038040080C4 -:101BA0004C2A0080ACAB2040940600800883204083 -:101BB000F0B582B0694B9F6A58235A43BA18C31DC7 -:101BC00049331F7801239B07D41D013423431D682B -:101BD00043681C0401239B07D61D053633431B684D -:101BE0001C4342231C430C60FF2636022E40012377 -:101BF0005B029E4274D16B0C2BD3C31920331B792B -:101C0000C0464B817B001B181B8F4C891B1BCB8054 -:101C10000024A6000196B318DE1D093601239B0798 -:101C200033431B68019E761873610134052CF0D391 -:101C30000024A6000096B318DE1D1D3601239B0765 -:101C400033431B68009E7618B3620134052CF0D331 -:101C500006E000234B81CB8040239C430C60231C77 -:101C60006B0E4AD3C31920331B7910330B817B00D1 -:101C70001B181B8F0F89DB1B8B8001239B07D41D37 -:101C8000353423431B68C046CB6301239B07D41D17 -:101C9000313423431B68C0460B64AB0E21D20123B1 -:101CA0009B07D41D3D3423431B68C0464B6401236E -:101CB0009B07D41D393423431B68C0468B64012322 -:101CC0009B07D41D453423431B68C046CB640123C6 -:101CD0009B07D41D413423431B68C0460B6500E0BD -:101CE0000FE0FB1F013B1B041B0C0768FF18036977 -:101CF000081C391C00F034F82CE000230B818B8089 -:101D000028E000238B800B81C31920331B7AC04647 -:101D10004B817B001818008EC046C88000208700C9 -:101D2000BB18DC1D093401239B0723431B687F1864 -:101D30007B6101300528F2D300208700BB18DC1D31 -:101D40001D3401239B0723431B687F18BB620130AE -:101D50000528F2D302B0F0BC08BC18474C2A00801A -:101D600080B41F1C3B0C18D2176D114BC046DF60AE -:101D7000526DC0461A61C7601A69C0460261D868D0 -:101D8000C0460880D868000C48801869C046888022 -:101D90001869000CC88080BC70474A8812040B8800 -:101DA0001A43C2608A88C988090411430161F2E7B5 -:101DB0002C070080F1B588B000220898006A089BC3 -:101DC0009968490A02D30127FF0300E00027038B2B -:101DD000002B19D0A349896A1C1C58236343C918D6 -:101DE00001239B075839194309680904090C022982 -:101DF00002D108231F4307E0418B002902D00C23A6 -:101E00001F4301E004231F43838A002B18D0954908 -:101E1000896A1C1C58236343C91801239B0758393E -:101E2000194309680904090C022901D10F4307E08D -:101E3000C18A002902D003231F4301E001231F436D -:101E4000C11D393107914B890C891C192404240CBC -:101E5000089D2D68C0460195C9887D081AD31A1CB3 -:101E6000C31D19331A72079A9289C0461A73079ACA -:101E70001289C04602860487828A013A828301223F -:101E80001971089B1B685B185B789B001B041B0C7B -:101E900008335918BB0847D3079B5B8985180695FB -:101EA00020352B72079B9B89C0462B73079B1B8990 -:101EB0002E1C55002D1805952B86002A01D0C38AAB -:101EC00000E0838A013B059DC046AB833171654BC1 -:101ED0009D6A059B9E8B58237343EB18DD1D0135CE -:101EE00001239B072B431D682B0E5B0601D1083194 -:101EF00000E0103181235B021D409D4203D1E31FAE -:101F0000053B1C04240C059BC0461C87089B1B68D2 -:101F10001B19103B9B7B069D40352B702B780233A1 -:101F2000E31A1C04240C0132BB089B076DD08318F4 -:101F3000203304931972019B5D1801239B072B43E7 -:101F40001B681B071B0F9B00049EC0463373009544 -:101F50002B781B071B0F9B00049DC0462B73009D15 -:101F6000EB78AD781B021D432B022D0A2D062D0E9A -:101F70002B4355002D182B86049BC0465972049B99 -:101F80001B7B2E1C049DC0466B73338EC04673862C -:101F9000009D2B781B071B0F9B001B041B0C591863 -:101FA00004253D400ED03487038B013BB383131CC3 -:101FB0001B1820331971019B5B185B789B00591823 -:101FC000083101323B0937D3002D01D0438B00E0AB -:101FD000038B55002D18013BAB83831803932033EB -:101FE0001971204B9D6A53001B1802939E8B582336 -:101FF0007343EB18DD1D013501239B072B431D683F -:102000002B0E5B0602D1083101E015E0103181236F -:102010005B021D409D4203D1E31F053B1C04240CC1 -:10202000029BC0461C87089B1B681B19103B9B7BAF -:10203000039C403423700132079BC046D980511E57 -:10204000C31D493319700761042A06D2064953009B -:102050001B1899830132042AF9D309B0F0BC08BCDB -:10206000184700004C2A0080FFFF0000704780B531 -:102070008CB0071C12480168013101603868C04605 -:1020800000907868C0460190B868C04602900D483C -:102090004168C968C0464160381C00F04FF8B86814 -:1020A000400906D31023029818430290684602F0B4 -:1020B000E1FF684602F09AFE0CB080BC08BC1847ED -:1020C0000C2B00806C06008000B58CB00168C04607 -:1020D00000914168054B1943019100F02FF86846C3 -:1020E00002F084FE0CB008BC18470000000000A0FD -:1020F000026A0368C04613604068C04650604032C0 -:102100004868C0469080C868C046D0804869C046CC -:1021100010818868C0465081087EC0469073086967 -:10212000C0469081704704490868002800D1704774 -:10213000C268C0460A60FAE76C06008002490A6875 -:10214000C046C260086070476C060080B0B40022D0 -:10215000124F7C7F01347C770323FC1D19343862D5 -:10216000796223720E4C25686B0C05D223681B0C18 -:1021700010D12468A30A0DD301230A4FC046FB6285 -:10218000094F0A4BC046DF6099605860101C186008 -:102190000132FBE7101C38640132FBE700000080CD -:1021A00000001040C000180002810000400118002B -:1021B000F0B5474F3868474E474D07235B02EC1890 -:1021C00000281DD1206B013020634449C0460860BF -:1021D00043484169002913D0C11D6931097B002999 -:1021E0000ED001239B07016D19430968C046816128 -:1021F000C269914204D0F16C0131F16401F050FEEA -:102200003868012817D137484169002913D0C11D0A -:102210006931097B00290ED001239B07016D194309 -:102220000968C0468161C269914204D0F16C0131F4 -:10223000F16401F035FE386802282FD1BB231B0161 -:10224000EE18707B002803D00020707300F04AFD68 -:10225000307B002802D0786802F0AAFF1B23DB0144 -:10226000E818C08B04260640E06AB04214D0F86833 -:102270000130F860192811D31B48017B00290DD1CA -:10228000FF3041304078002808D1B86802F090FF54 -:102290000020F860E66201E00020F860386803285A -:1022A0000BD1EC1D7934E06B800802D3022002F0E0 -:1022B00007FC0223E06B9843E06338680130386024 -:1022C000032801D900203860F0BC08BC1847000082 -:1022D0003C040080A0822040680E0080400118006D -:1022E000642D0080E42C008028050080B0B41D48D7 -:1022F000848A1D4A138AC11D093101279C4203D1DA -:10230000438A548AA34210D00B78002B0DD04B780F -:10231000002B0AD0448B938A9C4204DC134BC046AA -:102320005F60978201E001339382C38B5C1CC4839E -:10233000848BA3420EDB848A058B0023AC4205DA32 -:10234000448AC58AAC4201DA4B7000E04F70438288 -:102350008382C383418AC0465182808AC0461082EC -:10236000B0BC7047E80E00803C04008040011800BB -:10237000F7B591B06B46841E129914291AD9002022 -:1023800081006758C046575001300006000E1028E3 -:10239000F6D3002105208700D6594F1C3D062D0E8F -:1023A0000F1CBF00DE51291C01300006000E102852 -:1023B000F1D309E0002081006358C046535001303A -:1023C0000006000E0628F6D30020E070207260722E -:1023D000A072207360731299142937D969468E1C34 -:1023E00091780907090F890014390D062D16002769 -:1023F000002D1BDDF01910A900F03DF800280ED0CB -:10240000002010A90978002909DD0022391872542A -:1024100001300006000E10A909788842F6DB10A8EA -:102420000078381807063F0EAF42E3DB6846E21D2E -:102430000D320021AB085F1C08D08B00C458C04689 -:10244000D45001310906090E8F42F6D814B0F0BC01 -:1024500008BC184790B4871E002089084B1C08D080 -:1024600081005458C0467C5001300006000E834263 -:10247000F6D890BC704780B40278D206D20E002302 -:102480000127012A01DC0F7011E04078C046087076 -:10249000142A04D10848017A0131017207E0022AA6 -:1024A00005D0052A03D0062A01D0152A02D1181C0E -:1024B00080BC7047381CFBE7E082204000B50F4825 -:1024C00001231B06416999431A094161D16000212A -:1024D000A12252039161191C094AC04611601B23B5 -:1024E000DB01C0188069002803D002F061FE08BC3F -:1024F00018470448418801314180F8E7680E0080A0 -:10250000000000B0E082204070470000F0B586B0C7 -:10251000954AD068D71D7937012809D13889002814 -:1025200006D1D06F022301689943016014203881DD -:102530008E4C616A8E48C36B5918C163A06A192317 -:10254000DB01D418A062216A0903090B814205D17D -:10255000012040048749C0460860F3E0BB8A581C4C -:10256000B8823D8B01200021AB4204DBD31D8933AF -:102570005870B982F98333239B01D31805935B69A3 -:102580000F2B73D200217C4FC0463961216A8A68C3 -:102590001204120C4B681E0C3604FD1F093D002E60 -:1025A00005D13B2A03D30123DB029A4201D9A87348 -:1025B000C8E001239B07083119430968C04603910D -:1025C00003A9098801310904090C798249090531F7 -:1025D0000906090E694EC04602966948436AC0461C -:1025E0000193836AC0460093C21D113280690003C3 -:1025F000000B9268B3071A431268904201D1012080 -:102600000DE0904205D9009B181A019BD21A82183E -:1026100000E0121A01200901914200D30020012894 -:1026200065D151492069002862D005994869013077 -:1026300048610220216AC046086000F0A7FC786368 -:10264000BE604949226AA36BD318666BB34200D9B6 -:10265000226BC046BA62BA6A0C32FA620022FA6190 -:1026600003AA5288D20903D3012200E07BE000E0F4 -:1026700000227A607A68C0460260788A414E6028FB -:1026800004DCB083788AC046F08308E06020B08321 -:10269000798AF86A4218636B9A4203D8F183002260 -:1026A0003A6305E0216BC0463963616B081AF08319 -:1026B0002D49786B4268C046BA608268C046FA60AD -:1026C0000269C0467A614069C046B8612E4BC8189D -:1026D000049000F037F9049800F088F800F0F6FA5A -:1026E000788AF18B884204D1F96A081804E038E04E -:1026F00032E03A6B1018401A810702D0800880003F -:102700000430616B091AA26B914200D2206BC04663 -:102710002062E87B002808D00022EA730599486906 -:1027200001384861786B00F073FA1848806A8006B7 -:10273000800E01280AD1206A0003000B0B4CA16A0D -:10274000884203D006B0F0BC08BC18470120400402 -:102750000849C046086006E0E068002801D000F0A3 -:10276000B5FA0120A873EDE7680E00800040144020 -:10277000A42A0080000000B0281A00805555555545 -:10278000A8030080681A0080C40B000000001040FD -:1027900080B5071C786A4089FF210131014010484B -:1027A00002D1816C01318164796A4989490B02D275 -:1027B000416C013141640B48416A01314162786AE0 -:1027C000396BC0464862386B00F0F8FB381C00F0EB -:1027D000B3F801200449C046C87380BC08BC184740 -:1027E000A42A0080A0822040181A0080F8B5071C97 -:1027F0000022F91D61310D1C786AC04600904089A5 -:10280000030C01D2400A03D2381CFFF7C1FF67E076 -:102810003548C06B00091FD3087840081CD200203F -:102820004300CC5A314E9E1933239B01F3181B8869 -:102830009C420ED0B869396BC0468861F868396B24 -:10284000C046C860381C00F027F9381C00F074F846 -:1028500046E001300328E3DB022043005C18E488F3 -:10286000224E9E1933239B01F3181B889C4203D1EF -:1028700001230138D842F0DC0123D842C4D01B4EDA -:102880000B231B02F0184069002824D07D630098B8 -:102890004089000C1FD200242D239B01F018C06B2F -:1028A000351C002817D0FE1D2D36A20052192D23ED -:1028B0009B01D218D26B381C311C02F07BFC012822 -:1028C0000ED00134A00040192D239B01C018C06B0D -:1028D0000028EAD101E0012A02D0381C00F008F8F3 -:1028E000F8BC08BC18470000E81A0080680E008099 -:1028F00080B5071CB869396BC0468861F868396BC8 -:10290000C046C860786A4089010C0ED2400A0CD3D8 -:102910003868400802D3381C02F00CFC381C00F068 -:10292000BBF8381C00F008F802E0381CFFF730FF55 -:10293000012080BC08BC18470121006B406AC046DA -:1029400001607047B0B4C11D3931098B8908090491 -:10295000090C846AC21D6132002000290CDD870049 -:102960003D1901239B072B431B68C046D3510130FF -:102970000004000C8842F2DBB0BC7047F0B5A0B098 -:1029800001239B07C11D213119430968C0460B91E2 -:10299000C11D533119431F91096801AFFA1D393226 -:1029A0001E9217AB59803A4901239B070A6A1343C9 -:1029B000CC1D113489690903090B2269E568C046F9 -:1029C0001D95FC1D3934648B640905342406240EDE -:1029D0001C94561A1B961C9C2E4AC0460092012637 -:1029E0001D9D1A68914201D1321C0BE0914203D91E -:1029F000521B1B9EB51800E0551A01222401AC425F -:102A000000D30022012AE6D1910701430968C0469C -:102A100039609307011D19430968C0467960C11DDB -:102A2000013119430968C046B9601F9909681E9AA7 -:102A3000C0465183C11D1D3119430968C046386322 -:102A40007962C11D113119430968C046B961C11DC0 -:102A5000053119430968C046F960C11D1731194392 -:102A60000968C046F9830E3018430068C046F881F3 -:102A70003868400802D3381C02F05CFB381C00F0B8 -:102A80000BF8381CFFF758FF20B0F0BC08BC184703 -:102A9000A803008055555555F8B5071CF81D393069 -:102AA000418B394A914200DD4283428BC0460092FD -:102AB00001203A1D06CABB6A02F00EFF334AC04627 -:102AC0000092334E306A334CE16D4118386BC31DB0 -:102AD00005330120726A02F0FBFEE06D183000251C -:102AE000B16A814201D8E56500E0E0652F239B01D2 -:102AF000201CE16DE41822689200274BC0469950D3 -:102B00002648C16B4A0805D349084900C163012022 -:102B100001F0D6FF224A1F48C11D89310B78002BD6 -:102B200002D04978002900D11E4AC0460092206890 -:102B30008000194BC31805CEC11D1131012002F0D0 -:102B4000C7FE1448216801312160172900D3256090 -:102B5000396BC0460D65796A3A6BC04651623323C2 -:102B60009B01C0188168002903D1396BC046816080 -:102B700004E0396BC268C0461165396BC046C1605C -:102B8000F8BC08BC18470000EA0500001800140251 -:102B90007C290080680E008044822040E80E00807E -:102BA0000400000204000003F0B5114EFF250135BA -:102BB000104FC0463560786901387861BC68002CD8 -:102BC00010D0206DC046B860201C00F021F8201CF9 -:102BD00000F004FA0848806A000C0007E9D1F0BC54 -:102BE00008BC18470548C1790131C171F7E70000F9 -:102BF000000000B0281B008000001040A082204090 -:102C0000012080030149C04608607047000000B001 -:102C100090B5071C3868C00809D31D48016A0139FE -:102C2000016220300079002801D0FEF7E9FD012380 -:102C30009B07F81D1D3018430068164C616A8142DD -:102C400021D1011C194309680904090C01291AD171 -:102C500000F022F86062606A216A884205D0012192 -:102C60008907014309680904F2D051218903626A86 -:102C7000236B9A4202D1606BA26B801A0438C86041 -:102C800090BC08BC18470020796AC0460860F7E786 -:102C90006C060080E81A008001239B07C11D0131EA -:102CA000194309680904090C08180D30810702D07E -:102CB00080088000043004498A6B12184B6B9A42DA -:102CC00000D9086B70470000E81A008000B504487E -:102CD000C068102801D300F005F808BC18470000B0 -:102CE000E81A008088B50C4F3879002811D10B49BB -:102CF000102002F0F5FD00280BD001203871084AA1 -:102D0000C046009207484268074B0168002002F065 -:102D1000DFFD88BC08BC1847F81A0080F52CFFFFBF -:102D2000100035027C2900804480204090B50120AD -:102D300040021049C04608600F4F1021F81D3D3079 -:102D400002F04CFC1923DB01FC18E068002801D0DC -:102D500000F014F80020C9231B01F9180871E0687D -:102D6000102804D30120BB231B01F918487390BC21 -:102D700008BC1847000000B0680E0080F8B537485E -:102D80001923DB01C118C968354D102900D910215C -:102D900069623248C16C006E814207D9081A07097E -:102DA0000024686AB84212D2071C10E081422AD27D -:102DB0002C4A526B101A0709686AB84205D90C09E7 -:102DC0003919884203D2C41B01E00024071C3E19B4 -:102DD0003001254902F084FD00283DD02348002C15 -:102DE0001AD11E493A016F62096E8C181D4D6B6B2A -:102DF000A34200D8E41A1E4B1A430092EA6A511803 -:102E00002A6B031C20E01B48016B01310163002089 -:102E10006862F8BC08BC1847104924013F01112220 -:102E200052053A436E6200920E4DEA6A096E5118DD -:102E3000031C061C00202A6B02F04AFD0C4A2243A8 -:102E40000092BB19E96A2A6B002002F041FD034899 -:102E5000C046046600F010F80120DAE7680E008032 -:102E6000281B00807C2900805D2EFFFF44802040CD -:102E700000003602A08220400448016E044A8030DF -:102E8000D1600223C16B1943C1637047680E008093 -:102E900090EE2040F0B584B0012080021C49C0466D -:102EA000086000271B4E33239B01F518686A002831 -:102EB0001DD9194C6846102102F090FB684600F0BD -:102EC00033F8002804D015494869013048610AE008 -:102ED0001349607B01306073887901308871114833 -:102EE000006802F065F9686A0137B842E2D8BB238E -:102EF0001B01F018817B002903D000218173FFF7AB -:102F000005FBFFF7E3FE04B0F0BC08BC1847000067 -:102F1000000000B0680E0080B0822040088320408E -:102F2000A08220405804008090B4174F1923DB0181 -:102F3000F9180022CB68002B23D0013BCB60332350 -:102F40009B01FF18BB691C6DC046BC610468C0468C -:102F50005C604468C0469C608468C0461C61C06870 -:102F6000C04658611A650869421C0A61002803D0EE -:102F7000386AC046036500E0FB613B62181C90BCE8 -:102F80007047101CFBE70000680E00800A4A3323DC -:102F90009B01D118C8691923DB01D2181369002BD2 -:102FA00006D0013B1361CA69126DC046CA61704701 -:102FB00000211161FBE70000680E0080064A1169DC -:102FC0004B1C13614032002901D0D16900E000217F -:102FD0000165D06170470000E81A0080064AD16898 -:102FE0004B1CD3604032002901D0916900E00021E0 -:102FF0000165906170470000E81A008090B40021DC -:103000000F4A9789926A4B001B189B8A002B12D09B -:10301000BB4210DC1C1C58236343D318DC1F493C03 -:1030200001239B0723431B681B061B0E032B02D0A7 -:10303000002090BC704701310429E4D30120F8E757 -:103040004C2A0080F7B586B03D4A071CD1698F40F5 -:10305000031C146AE3405F40079E8E407740CF40D8 -:103060009469C0460594031CA34000251469C0461A -:103070000494002C5DD91C1C324E26439469E64012 -:10308000331C0396536AC0460293D26AC04601922B -:10309000BB00029AD258131C059CE340039CA34238 -:1030A0003ED18A40CA40141C63001B195B01019A7F -:1030B000D21801239B07D61D013633431B681B061C -:1030C0001B0E032B2CD101239B07D61D51363343F6 -:1030D0001B68079E1E40009601239B07D61D49369C -:1030E00033431B6883421BD101239B07D61D4D36FA -:1030F00033431B68009EB34212D101239B071A433E -:1031000012681204120C089B322B04D1022A07D138 -:10311000200400140FE0089B332B01D1012AF7D0C3 -:10312000049A0137974200D30027049A0135AA4236 -:10313000AED80020C04309B0F0BC08BC184700005E -:103140004C2A008000000080F0B5274D68690028F7 -:1031500006D02648006802F02BF8F0BC08BC1847DF -:10316000234C0026A068234F002816D00FE0286AC1 -:10317000022802D3012038710FE0A660FDF7DEFEC1 -:103180000028EAD1286A022801D301203871E868B2 -:10319000002802D038790028E9D0686800281BD0C0 -:1031A0000120A060FEF7BCFB0028D6D1686800288B -:1031B000F6D111E00028D0D1286A022802D30120DC -:1031C0003871CAE7A660FDF7B9FE0028C5D1286AA4 -:1031D000022801D301203871E8680028BDD0387971 -:1031E0000028E7D0B9E700006C0600805C0400808E -:1031F0004C2A00808C060080704700007047000059 -:103200007047000090B540201D49C046086001F09D -:103210009DFC03231B07416819400C0F6101091B2A -:103220008900184A8F1801213980816AC046796562 -:10323000416AC0467967B96CFA6C8918B964002193 -:10324000F964BA6B3B6DD218BA633965426A2032B1 -:103250005171796D7A6FD26DC0461160FCF7CAFF6B -:103260002001094940181923DB01C018416B0139BD -:103270004163786F01F0C6FB90BC08BC18470000A2 -:10328000000000B05C2B0080A01C0080F0B5402046 -:103290001249C046086001F059FC071C406803232E -:1032A0001B071840060F7001801B80000C49441852 -:1032B000B86AC0466065786AC0466067806F051D61 -:1032C000E563B969281C02F089F9381C211C321CFD -:1032D0002B1C00F020F8F0BC08BC1847000000B020 -:1032E0005C2B0080F0B54B6F9B6F1F1DCF63056893 -:1032F00000238469A40808D09C002E59C0463E5182 -:103300008469A40801339C42F6D83B1C00F003F802 -:10331000F0BC08BC1847FFB581B0041C1D1C0F1C75 -:103320004648016901310161F91D5131BD650091C6 -:10333000201CFDF75DFCF86D400936D2B86D067BA8 -:10334000437B1B021E431721490201730B0A43737F -:103350000099201CFDF74CFCB86DC0460673330A7B -:103360004373F86D400920D260680104090C03988A -:1033700001F0CCFC6068324B18436060201C01F007 -:1033800035FD00257D60BD603D647D64201CFCF73B -:1033900031FF38884023184338807D622948C04671 -:1033A000B862381C00F0A0FB44E0206801239B07B2 -:1033B000083818430068C046786460680204120C3C -:1033C000786E0126C11D0D318A4202D23A64081C72 -:1033D0000EE041198989F023194009098900401834 -:1033E000F860F96161680904090C814216D23964F8 -:1033F00063681904090C401A033080088200A06138 -:10340000206809189B186360C31F053B381C00F037 -:10341000B6FA7E80201C00F0BFFB0BE0B968081AEA -:1034200000257862BD62381C00F03CFC201C391C71 -:1034300000F064F805B0F0BC08BC18470C2B008005 -:1034400000000080010000C0F0B5041C0F1C386CA7 -:10345000F96B0D18216841180020A269002A0BD9C8 -:103460008200561801239B0733431B68C046AB50AC -:10347000A26901308242F3D8786EF96B0918898904 -:10348000F0231940090989004018F860F9612068A3 -:1034900001239B07083818430168786CFCF795FFF7 -:1034A000786460680104090CF868814219D23964B3 -:1034B00063681904090C401A033080088200A06177 -:1034C000206809189B186360C31F053B381C00F077 -:1034D00056FA01207880201C00F05EFBF0BC08BC8E -:1034E0001847B968081A78620020B862381C00F0E2 -:1034F000D9FB201C391C00F001F8EFE7F0B584B0CF -:10350000041C0F1C8E4841690131416103200007F2 -:1035100061680840060F0A04120C20681118FB6845 -:10352000D21A7B689D1AC31F053B381C2A1C00F069 -:1035300026FA00207880201C00F02EFB60684019DD -:103540000104090C6060301C01F0E0FB7D4E0B2390 -:103550001B02F0180069002819D000252D239B01BB -:10356000F018C068002812D0AA0092192D239B01E0 -:10357000D218D268201C391C01F01CFE0135A800AD -:1035800080192D239B01C018C0680028ECD1F86B6E -:10359000011F8A1CFA63FA687D6C00F0BBF9C04316 -:1035A0000104090C281CFCF710FF0390F96B3A6E1C -:1035B0008E182068121801927A6E8D1811180291D7 -:1035C000C81D0930E060B1880802090A0906090E21 -:1035D00008430004000C78616868010EFF221204A1 -:1035E0000240120A1143FF2212020240120211434A -:1035F000000608433861A88909231B021840B861F6 -:10360000A8899843A881A8890299C046888100208A -:103610007080B080708168602882B96E301CFCF7C1 -:10362000E8FE3886FA69301C291CFCF703FF78860F -:103630003D8E788E0399FCF7C8FE00906068000408 -:10364000000C396E411A0904090C7A6E821A1304AF -:103650001B0C1A021B0A1A431604360CBA68824263 -:1036600001D2002000E0101AB86008020912090611 -:10367000090E08430104090C0198C0464180281C2A -:10368000FCF7A3FE051C0098311CFCF79EFE061CEF -:1036900078690004000C0102000A08430104090CC7 -:1036A0000198C0468180281CFCF78FFE79690131A2 -:1036B000C0437961019AC04650813869010EFF22EA -:1036C00012040240120A1143FF22120202401202A7 -:1036D000114300060143301CFCF777FE39697A6814 -:1036E00089183961B968002909D102998989BA69AB -:1036F0001143029AC0469181B969FCF766FE2082A7 -:1037000000206082F86D410816D3800A0AD36068F1 -:1037100010380104090C0802090A08432168C04650 -:10372000088209E060680C380104090C0802090AE3 -:1037300008432168C046888104B0F0BC08BC184723 -:103740000C2B0080680E0080F1B584B06E4D2869A6 -:10375000012204998A409043286104984301181A71 -:103760008000161C69494418E06BC0460090A068B0 -:10377000002801D1002626E06548416901314161F8 -:103780000498FCF709FD071C03D128693043286120 -:10379000B5E0A0686568A84200D2051CA16CA942EA -:1037A00016D2401A626A101A00266062A660A662EB -:1037B00020884823184320800D1C09D1381CFCF7B1 -:1037C00019FD032060806660201C00F08DF996E0F2 -:1037D000E16838680918C31F053B201C02392A1C00 -:1037E00000F0CDF8381C00F0D7F9E0684619786889 -:1037F000304378600498311C01F088FA216E0098FB -:1038000008180190701A0004000C616E711A0A0405 -:10381000120C1102120A11430904090C029101024F -:10382000000A08430104090C0198C0464180208E1B -:10383000FCF7CBFD061C608E0299FCF7C6FD0390D9 -:1038400060690104090C0802090A08430104090C13 -:103850000198C0468180301CFCF7B7FD61690131D9 -:10386000C04361610199C0464881606E0099461865 -:103870002069010EFF2212040240120A1143FF22A6 -:1038800012020240120211430006014371600398C4 -:10389000FCF79BFD216949192161A168491BA160C1 -:1038A00006D1B189A2691143B181A169FCF78DFDEF -:1038B0003882616E386809180E31F960E268009943 -:1038C000043800F04CF802207882E06D410816D3ED -:1038D000800A0AD3786810380104090C0802090A22 -:1038E00008433968C046C88109E078680C3801048B -:1038F000090C0802090A08433968C046488105B026 -:10390000F0BC08BC18470000D02C00805C2B008065 -:103910000C2B0080F7B5031C0F1C00201C6826042C -:10392000311C1D1DFCF751FD40C7029AD11C8908AE -:1039300001394A1E029200290DD0210C10CD22041B -:103940000A43111C161CFCF740FD40C702994A1E91 -:1039500002920029F1D103B0F0BC08BC18478008DE -:10396000800089088900033293085A1E002B05D075 -:1039700008C908C0131C013A002BF9D17047FFB5E4 -:1039800086B0171C00260698806CC01B0699C0469E -:1039900088640120C0050699896BC046019106998B -:1039A0004C6B67E02168C04602916168C046039194 -:1039B000A168C046049102A94988B94208D202AD63 -:1039C0006D8802A949887F1A002102AB598019E04D -:1039D00002A94988C91B02AB59803D1C002701215F -:1039E0004906079B9A07920F0DD0EB06DB0E08D015 -:1039F0001E2B08D31E2B02D1032A04D101E0022A78 -:103A000001D301260021294301430A1C0091002013 -:103A10000399049A079B01F05BFF079949190791E5 -:103A2000002E0AD01D4AC04600921D48016D426D0D -:103A30000020079B01F04CFF002602A840880028C8 -:103A40000CD00398401903900298C0462060039858 -:103A5000C04660600498C046A06003E00198013849 -:103A6000019010340698C046446301980699C046F8 -:103A700088630020002F02D00199002992D1094AC1 -:103A8000C04600920648016D426D0020099B01F07E -:103A90001FFF0AB0F0BC08BC18470000010000027C -:103AA0007C2900800400530290B50C1C071C386868 -:103AB00001239B07083818430168388AFCF785FC06 -:103AC000C043F968C0460880788A3968081A3860A7 -:103AD000381C01F08BF9381CFCF78CFB201CFFF71D -:103AE00033FE90BC08BC184780B501888A0921D3F1 -:103AF000CA091FD28A081DD3002101804180476F67 -:103B0000406DFA1D19325171FA6DC04610603A6E5F -:103B1000C04610600C48C0468163C16B490849002B -:103B2000C163012000F0CCFF381C00F06BFF80BCAB -:103B300008BC184780231943018001884909F6D23F -:103B400000F0B0F8F3E70000E80E0080F0B5071CC5 -:103B5000101C0D1C00245E1E002B19D00168C046ED -:103B6000396041880C194168C04679608168C04657 -:103B7000B960C168C046F96010301037E96A814207 -:103B800002D8281C00F0ECFF311C013E0029E5D1D1 -:103B9000201CF0BC08BC18470021C16105490A6817 -:103BA000002A01D1086002E04A68C046D06148603E -:103BB00070470000D02C008003490868002802D01C -:103BC000C269C0460A607047D02C0080002181671E -:103BD00005498A68002A01D1886002E0CA68C046A7 -:103BE0009067C86070470000D02C00800349886847 -:103BF000002802D0826FC0468A607047D02C0080B7 -:103C000000B580201349C0460860FFF7D5FF0028A3 -:103C10001BD003231B07416819400A0F5101891A61 -:103C200089000D4BC9184B88002B04D1111CFFF7DC -:103C30003BFF08BC1847012B02D1FFF705FCF8E752 -:103C4000022BF6D1FFF74EFBF3E70448016D01317B -:103C50000165EEE7000000B05C2B0080A0822040F0 -:103C600000B520200D49C0460860FFF7BFFF0028BF -:103C70000ED0018820231943018001881023994325 -:103C800001800188090A01D3FFF72EFF08BC1847FD -:103C90000348016D01310165F8E70000000000B044 -:103CA000A082204098B5071C2248C04600902248B8 -:103CB000C31D4133416D826D806C0003000B9C6815 -:103CC00001239B0723431B68984200D10CE09842D4 -:103CD00003D9101A591A411800E0191A01201029A5 -:103CE00000D8002000281FD0786AF96AC046086012 -:103CF000B86AF96AC0464860104AC0460092FB6A3A -:103D00000F48426D0320396A01F0E2FD3888102324 -:103D1000184338803888402398433880381CFFF790 -:103D200055FF98BC08BC1847388840231843388092 -:103D3000F7E7000055555555A8030080080011020B -:103D40007C290080B0B540202C49C046086000F0B6 -:103D5000FDFE071C406803231B071840050F680180 -:103D6000401B8000264944182088022318432080E5 -:103D70002088410834D3400840002080A06CE16CCA -:103D80004018A0640020E064A16B226D8918A16333 -:103D90002065B86AC046606503231B077868184031 -:103DA000786061683631942904D8382318437860E4 -:103DB000382003E09423184378609420B861396870 -:103DC00078680204120C201CCB1F053BFFF7D7FDBF -:103DD00002206080381CFFF7DFFEB0BC08BC18472B -:103DE000381CFCF707FA2801064940181923DB01A3 -:103DF000C018416B01394163EFE70000000000B0DB -:103E00005C2B0080A01C008090B500270F4C0DE0BB -:103E1000426B013A4263002A05DC026BC0464263F2 -:103E2000C06A01F0C6F901370B2F07D2380100191B -:103E300033239B01C018816A0029E9D10120400683 -:103E40000349C046086090BC08BC1847680E008053 -:103E5000000000B01048C1680131C1600F49C86856 -:103E6000012817D1C81D79300289002A12D0013AE1 -:103E700002810289002A0DD14289002A08D1C96F26 -:103E800002230A681A430A6004210181012100E02B -:103E9000002141817047000008832040680E0080A7 -:103EA000B0B5071C0123F81D693003731E48C21DFD -:103EB0007932548A611C5182D58A0021AC4204DBDC -:103EC000C41D893463705182D18301239B073A6DED -:103ED0001A431268C046BA61FB699A4206D1F86C6F -:103EE0001249C0460860B0BC08BC184779614169F6 -:103EF000FA6C9143416101200005C16038690228D4 -:103F0000F1D0B869F969411A01D5786D4118381CAA -:103F100000F00EF8F9690918F961786D8142E2D371 -:103F2000081AF861DFE70000680E0080000000B0AA -:103F3000F8B5041C0F1CFF2321339F4201D9FF2732 -:103F40002137E16E381C01F0CBFC2D4D002813D138 -:103F5000E01D4930017A012319430172294AC04604 -:103F600000922948016D426D00202B1C01F0B0FC2D -:103F70000020F8BC08BC18472069013020612349A3 -:103F8000C81DB930026B92005118C0310F61016B2E -:103F900001318907890F0163206BC219616D8A4263 -:103FA00003D8232212053A4305E0091A7E1A07D1E5 -:103FB000232212050A430092616E0918A26E10E0D6 -:103FC000112252050A430092616E09180020A26E68 -:103FD0002B1C01F07DFC2322120532430092616EFE -:103FE000A26E00202B1C01F073FC206BC01900098D -:103FF0000001616D814200D8401A2063381CB8E787 -:104000004480204004001B027C290080680E008050 -:1040100080B50120C0030D49C04608600C49C81D89 -:104020004930027A0027002A03D00772081CFFF7E4 -:1040300037FF0849C81D4930027A002A03D00772A9 -:10404000081CFFF72DFF80BC08BC1847000000B01B -:10405000642D0080E42C008090B5071C10201849C6 -:10406000C0460860F8680130F8601648C41DB934CD -:10407000616B89000918C03109697A689200D21908 -:104080005164616B89000818C0300169786880004C -:10409000C019C06B01F0A2FA01237868584078601B -:1040A000606B01308007800F6063F81D1930407924 -:1040B000002802D1381C00F007F890BC08BC184753 -:1040C000000000B0680E008090B5071C3948C06839 -:1040D000002805D0B86AC068800901D3022000E03A -:1040E000786FFCF759F8041C06D10120F91D19312D -:1040F000087190BC08BC1847F86C2F49C04608608E -:10410000BA6A381C211C00F059F86762002803D1F4 -:10411000201C00F00BFDECE7F96D0968091809098E -:1041200009017A6D8A4200D8891AA162B9688900AA -:10413000C9194A6C002A07D04A6C121A4A648008CE -:104140008000B96A0818B8623868B96A8000C01976 -:10415000426B91420ED300214164B86A39688900EC -:10416000C919496B401AB862B9688900C919C96B85 -:104170004018B862B8688100C919496C0029B8D1E3 -:10418000B96AFA6B9142B4D03A6C9142B1D0012332 -:104190005840B8608000C019C06BC046B862F8686B -:1041A000002801D00138F86038690028A1D0013812 -:1041B00038619EE768190080000000B0F7B590B044 -:1041C000041C0D1C00200590029000220192F94869 -:1041D000C06AC046A861A06881000919496BC04641 -:1041E0002060E162129AD068C046A860129A5178A5 -:1041F000C0460C91F048C0460390D71D0937E06ACD -:10420000C11B0909E31D19330C9AC0460F93EB4BF0 -:10421000C0460E93914201D3B84221D8E1680229E9 -:104220001ED201200F99C04648710020039901F069 -:1042300057FB002803D10E9BD86B0130D8630120B7 -:10424000800600276860AF61DD4AC0460092DD4805 -:10425000016D426DDC4B002001F03AFB381C5CE341 -:10426000B84203D8201C00F07BFC071CD748C0686C -:10427000002864D038784007400F032860D10598A3 -:1042800001300006000E05903878F023184058D110 -:10429000E06AC01B00090C99884202D2E06802283B -:1042A00005D3CB49886800F083FF061C06D1039B29 -:1042B000281C391C221C00F08BFC16E12E62F868C9 -:1042C00000280DD0B889002803D0C149C96800F082 -:1042D00070FFF889002803D0BD49C96800F069FF64 -:1042E0007A68C0467261B968C046B161301CB8498D -:1042F000096800F05EFF002817D1301CB4494968F6 -:1043000000F057FF1037E06AB84203D8201C00F0D5 -:1043100027FC071C6868AF4B184368600020A86141 -:10432000AC23A8689843A860B0E0A869A82801D287 -:10433000A820A8611037E06AB8426CD89CE0A5E0DC -:10434000A4E0102868D103231B0768681840010FF8 -:104350004801401A8000A04A821801927888420BD6 -:1043600031D3820B2FD39D48C04603900220019A7F -:10437000C046108078880005000D019AC046506044 -:10438000B868019AC04690607868019AC046106289 -:104390000020019AC0469064019AC046906388024A -:1043A0008F494018019AC0465063019A50683630D0 -:1043B000942801D8382000E09420A8611037E06AE2 -:1043C000B84228D858E07A88920B03D38548C04673 -:1043D000039023E0012212030240834B1DD003937C -:1043E0000005000D019AC0465060B868019AC046A9 -:1043F00090607868019AC04610620020019AC04619 -:104400009064019AC0469063880275494018019AE9 -:10441000C046506302E033E02AE0039301200F9985 -:10442000C0464871129A50780599431A0B93103779 -:10443000E06AB84203D8201C00F092FB071C019AE6 -:10444000506B916B090140180B9B211C3A1CFFF724 -:104450007DFB019AC046D064019A0B9BC046136550 -:1044600001235B066868184368600020A8610DE0BE -:104470001037E06AB84203D8201C00F071FB071C1B -:1044800038784007400F032800D1F8E6A86903995F -:1044900001F026FA00282AD1381C211C00F079FBF3 -:1044A000A868800904D3301C4949496800F081FE9E -:1044B0004149002001F014FA002804D10E9BD86B6A -:1044C0000130D86311E001200F99C0464871800681 -:1044D00000276860AF613A4AC04600923948016DD2 -:1044E000426D394B002001F0F3F9002015E20598E8 -:1044F0000C99081A0004000C0C900B900C980028E2 -:1045000003D001200F99C04648712868C046049026 -:1045100000260020089000220A920C9801380D9085 -:10452000A3E078888A1B1204120C904205DD0792E2 -:10453000801A0004000C089000E0079008980028FA -:1045400007D10D980A9A904207DD079830188842E3 -:1045500003D80120400506901CE01120400506907C -:10456000A8688C23184002D12048C0460690B107A5 -:10457000890F0FD00798C006C00E08D01E2809DB8F -:104580001E2802D1032905D101E0022902D301200E -:104590000290DEE70A9A002A04D10123DB0506987F -:1045A00018430690079806990843021C0090049847 -:1045B00083191DE0E80E00800149FFFF280F0080ED -:1045C000040012027C290080448020406819008089 -:1045D00060040080000000805C2B00805532FFFFEB -:1045E000AC5E21400D3DFFFFCD31FFFF00003202E8 -:1045F00000203A1D06CA01F06BF907983618029898 -:10460000002816D0A8688C23184004D109235B0425 -:104610000698184306900698C24A024300920498EE -:104620008319C148016D426D002001F051F900204D -:104630000290089800280BD10B9B013B0B9310377D -:10464000E06AB8420CD8201C00F08AFA071C07E088 -:104650007868079A801878607888079A801A788036 -:104660000A9A501C0204120C0A920C980A9A82426E -:1046700003DAA969B14200D953E7A869B0426BD106 -:10468000A868010969D2089A002A56D00C990A9A9A -:104690008A423EDBB107890F0CD0089AD206D20EAF -:1046A0000BD01E2A06DB1E2A02D1032905D001E009 -:1046B000022902D20299002921D0089AC04600920C -:1046C0000498831900203A1D06CA01F001F90898E0 -:1046D0003618A8688C23184002D00120400600E05C -:1046E0009248012202430092049883198E48016D7A -:1046F000426D002001F0ECF80020029015E08C23C0 -:10470000184002D00120400600E08848089A024381 -:1047100000E0089AC04600920498831900203A1DD0 -:1047200006CA01F0D5F8089836181037E06AB84282 -:1047300003D8201C00F014FA071C6868800E6BD2A6 -:104740000A98C04609900C9988425CDA0D9809993C -:10475000884203D07A881EE05FE05EE0788801221C -:1047600052060243A9688C23194002D109235B0435 -:104770001A43B107890F0ED0C306DB0E08D01E2BDB -:1047800009DB1E2B02D1032905D101E0022902D346 -:1047900001210291021C0998002802D10123DB05A6 -:1047A0001A4300920498831900203A1D06CA01F0AA -:1047B0008FF87888861910370298002814D0A868D6 -:1047C0008C23184002D00120400600E05748012207 -:1047D00002430092049883195348016D426D0020F2 -:1047E00001F076F800200290E06AB84203D8201C5D -:1047F00000F0B6F9071C099801300004000C09907C -:104800000C998842A2DB686830430104090C686097 -:10481000E86A00F07BFA28E027E0A868000914D3D2 -:104820006868800E15D2019A002A12D0019A506B46 -:104830000B9B211C3A1CFFF789F9019AC046906432 -:10484000019A0B9BC046936303E0E86A311C00F0B9 -:104850005DFA686830436860A869B04205D9000411 -:10486000000C801B00F0EEF9AE61A8688C231840A4 -:104870000BD02F4AC04600920498C31F053B2A481C -:10488000016D426D002001F023F801239B07206D8C -:1048900018430068C046A061E169814212D02269D4 -:1048A000022A0FD2411A01D5606D4118201CFFF772 -:1048B0003FFBE1694018E061616D884224D3401AF2 -:1048C000E06121E081421FD1206902281CD2012031 -:1048D000606118484169E26C0A4342618169E36C96 -:1048E0009943816101210905CA608069C046086158 -:1048F0008B02206D18430068C046A061E1698142C7 -:1049000002D0201CFFF7CCFA281C00F00FF90C98FD -:104910000599401800011030686113B0F0BC08BC64 -:1049200018470000010000027C29008000001202EC -:1049300004005202680E0080F0B540202D49C046A8 -:10494000086000F003F9071C8169446AA06F00F059 -:1049500045FE0020E11D193148717968C90E09D35F -:10496000F86A000124494018244BC0180168013935 -:10497000016036E0E16D0968226EC0461160204E8C -:10498000F51D79350123E96B1943E963B96AE26DD5 -:10499000C0461160B96A226EC04611606169002983 -:1049A00004D1A96B0131A963082907D3A8630120A9 -:1049B00000F086F8E86B40084000E8637868810EF4 -:1049C0000FD20B231B02F118C968002906D000087A -:1049D00004D2201C391C00F043F802E0381C00F01F -:1049E00005FA381CFBF706FC201C00F00BF8F0BCA5 -:1049F00008BC1847000000B0A01C0080B40C0000E8 -:104A0000680E008080B5071CF81D19300179002957 -:104A100004D000210171381CFFF756FBF86802280A -:104A20000DD0B8688000C219506C002811D0B86A47 -:104A3000417809011031526B101A884205D3381C95 -:104A4000FFF742FB80BC08BC1847381CFFF728FA68 -:104A5000F8E778688000C019C06BC046B862F1E71B -:104A6000B0B587B00F1C806FC04600900024134D76 -:104A70000B231B02E8188069002817D06946A200A2 -:104A800052190B231B02D2189269381C00F092FBBA -:104A9000002809D10134A00040190B231B02C018C3 -:104AA00080690028EAD101E0012802D0381C00F01A -:104AB0009DF907B0B0BC08BC18470000680E008024 -:104AC000B8B5C207D20F164C164901D0082208E02B -:104AD000820805D30C22A4180B68DF1D153703E0EC -:104AE0001C220B68DF1D09370F4B1D78002D13D0DA -:104AF0005B78002B10D001235B061A43002801D1FC -:104B00005B081A4300924A680120391C231C00F0FC -:104B1000DFFEB8BC08BC184703231B061A43F1E7A5 -:104B200090EE20407C290080F80E00800021C161B9 -:104B300005498A68002A01D1886002E0CA68C04637 -:104B4000D061C86070470000280F00800349886862 -:104B5000002802D0C269C0468A607047280F0080D2 -:104B6000011C0123886858408860CA68013ACA60FD -:104B70000A69013A80000A614218D06B536BC04643 -:104B8000CB620B689B005918496C536CC91851646F -:104B900070478A6892005218D36B834217D1D01D98 -:104BA0003D300A6892005218526C03689A1A0260EB -:104BB0000123886858408860CA680132CA600A695F -:104BC0000132800040180A61406BC046C8627047DD -:104BD000B8B5041C1D1C171C081C391CFFF7D9FF95 -:104BE0000020291C00F07CFE0120F91D19314871BC -:104BF000800660600020A061064AC0460092064818 -:104C0000016D426D054B002000F062FEB8BC08BC8F -:104C100018470000040012027C29008044802040D4 -:104C200006490A681018086001235B02984203D9FC -:104C300003490A7901320A7170470000E42D0080AF -:104C4000A08220408008800006490A681018086089 -:104C500001235B02984203D903490A7901320A71A0 -:104C600070470000E42D0080A082204003308008BF -:104C7000800006490A681018086001235B02984208 -:104C800003D903490A7901320A717047E42D008083 -:104C9000A0822040024841790131417170470000F3 -:104CA000A082204090B48200174B9A588B0702D004 -:104CB00089080B1D01E08908CB1C1169D768124CCB -:104CC000800020584068B94203D1814219D9116847 -:104CD00017E00024B94209D9814212D91168781A23 -:104CE00000D50330801098420BD807E0814205D8E8 -:104CF000781A00D503308010984202D8201C90BC4E -:104D00007047C81D0530FAE77004008080B5800048 -:104D10000F4A1758880702D08808043001E0880835 -:104D2000033039697A68914209D93968C0463961D6 -:104D3000F9687A68914202D93968C046F960810001 -:104D4000386900F0D1FD386180BC08BC184700000C -:104D50007004008090B50321090701400C0F010485 -:104D6000090C012292070240A3001C4FFF5889073B -:104D7000890F0004000C8008002900D00130002AAF -:104D800001D0023000E00330F9687A68914202D91C -:104D90003968C046F9608100F86800F0A5FDF86048 -:104DA0000F480069002805D00120A04002D0201C37 -:104DB000FEF7CAFC0B49C81D193003790022002BED -:104DC00005D10949C81D19300379002B03D00271A0 -:104DD000081CFFF779F990BC08BC184770040080E4 -:104DE000D02C0080642D0080E42C0080B0B52B49CD -:104DF0000979002903D14168294B19434160816831 -:104E0000490802D30921090401E00D2109040CC855 -:104E1000083819438768BB0A03D343685B0800D38B -:104E20000131406803231B071840070FF8001D4C91 -:104E300000192368C01850300079012810D160682B -:104E400001280DD0101C00F071F838010019192349 -:104E5000DB01C018416B01394163B0BC08BC184785 -:104E6000380100191923DB01C018036B5D1C0563B1 -:104E7000BD022D19DB00EB1880331963DA62816BF8 -:104E8000013181630121B940226811432160016B26 -:104E90008029E2D300210163DFE70000280F0080B2 -:104EA00000000080A01C0080F0B51F4E7068002834 -:104EB00036D10024B168481CC9008919B060326835 -:104EC000891860310D7B082800D3B460280180194F -:104ED0001923DB01C018876B002F21D0C16A4B1C3E -:104EE000AA029219C90051188031C362CA6A096BBB -:104EF000013F8763802B00D3C462002F06D10127B6 -:104F0000AF403B1CDB4337683B403360436B013BA6 -:104F10004363101C371C00F009F878680028C9D0DA -:104F2000F0BC08BC18470000A01C0080F0B5CD0FF5 -:104F3000ED07012400272E4B2E4A002D1DD0D86AE4 -:104F40000130D862101C5269002A12D00269531C29 -:104F50009200121803619161416901314161026956 -:104F60000F2A00D307610F2900D34460F0BC08BCAE -:104F70001847081CFFF7EEFEF8E715696E1CAD0038 -:104F8000AD181661A96155690135556116690F2E75 -:104F900000D317610F2D00D354608C02A40A164F62 -:104FA0003A6FFD68F91D7931012D0CD1DB6D5B087D -:104FB00009D30B89002B06D1FD6F033B2E683340CC -:104FC0002B6014230B8110608007800A20430304A8 -:104FD00000D001385060096A0832914200D8074A6F -:104FE000000D02D35120800382613A67BEE70000C2 -:104FF000A42A0080A01C0080680E008024A7204006 -:10500000B0B5002804D10120C0051649C04608608B -:10501000154C00256769002F16D0E068411C800000 -:105020000019E1608069013FFFF794FEE0680F28F6 -:1050300000D3E560E068800000198069000801D3B2 -:10504000002FEAD1676103E00848016D0131016575 -:1050500065602068002801D0FFF726FFB0BC08BCBF -:1050600018470000000000B0A01C0080A082204073 -:1050700000207047B0B41023826813400021002B39 -:1050800015D00C4B1A401201812414430268156894 -:10509000131D80CB1B68043A026020C280C208C284 -:1050A0001460426801239B0704321A434260081CC3 -:1050B000B0BC704700F0FF0FF0B48268530934D3DE -:1050C0001B4B1A4012018126164303681D681F1DE1 -:1050D00010CF3F68043B036020C310C380C31E6031 -:1050E00043681F1D01239B073B434360CB6B181F85 -:1050F000C86380CB80C01C681F1D031D0460381C62 -:105100003F68C0461F601F1D43681C04240C812398 -:1051100023433B604068000C000410437860086E35 -:1051200004300866486E043048660020F0BC7047C2 -:1051300000F0FF0F80B4816A01239B07CA1D05326E -:105140001A431268CF1D01373B431B68C046CB6032 -:1051500001239B070F1D3B431B68C0468B60012347 -:105160009B070B431B680CC10262016BC0460A62BD -:105170000423816919438161026BC0469161816A90 -:1051800004318162026BC0469162C11D39314A8B84 -:10519000043A4A83498B026B40325183C1890439F6 -:1051A000C181C168006BC046C160002080BC7047EF -:1051B00000470847104718472047284730473847D7 -:1051C00030402DE90CC09DE50C48A0E12448B0E139 -:1051D0001E00000A01C04CE21840A0E364519FE5A4 -:1051E000945020E0005090E5144090E5003085E5B3 -:1051F00004C085E5081085E50C2085E5101090E5D4 -:10520000105085E2010055E10C509055040055E125 -:105210000500000A041090E5005080E5005081E58B -:105220000000A0E33040BDE81EFF2FE1003093E511 -:10523000082090E5013183E3023683E3030055E162 -:10524000143080E5F2FFFF1A0100A0E3F4FFFFEA4B -:1052500001061CE3F1FFFF0AEC109FE502C6CCE358 -:10526000542091E5E4309FE5501091E5D9FFFFEA25 -:10527000F0472DE920C09DE50C68A0E12668B0E16B -:105280002500000A1840A0E3B8509FE5940000E014 -:10529000050080E0084090E5048090E50070A0E300 -:1052A0001FC0A0E302C48CE3005090E5109090E58D -:1052B00014A090E5003085E504C085E5081085E57B -:1052C0000C2085E5105085E2090055E10C50905501 -:1052D0000A0055E11500000A037017E2201081E270 -:1052E000203083E20A00000A006096E2017087E243 -:1052F0000900000A206046E2200056E3ECFFFFCAE6 -:105300000070A0E301C046E202C48CE30060A0E3A9 -:10531000E7FFFFEA005088E5F2FFFFEA0010A0E394 -:10532000005080E50100A0E1F047BDE81EFF2FE13D -:1053300000A094E50A0055E114A080E5E5FFFF1AFE -:105340000110A0E3F5FFFFEAA80300807C2900809C -:105350000080204068829FE50B92A0E364A29FE555 -:1053600058B09AE50EF0A0E154B09AE51EFF2FE187 -:105370003F402DE900004FE11F0000E2120050E322 -:105380005400000A00000FE18000C0E300F021E1BA -:105390000450A0E3004099E5090000EA020014E38C -:1053A0005300001B800014E35900001B200014E38D -:1053B0005900001B020714E35900001B010614E307 -:1053C0005900001B080014E34500001B020514E30C -:1053D0004A00001B020814E34B00001BE50E14E317 -:1053E0000700000A042098E50C1098E5043052E20A -:1053F0003C30A0B3043088E5020091E70FE0A0E163 -:1054000010FF2FE1015055E20300000A004099E52A -:105410000C009AE5000014E11BFF2F1108009AE52B -:10542000000014E10B00000A010C14E398019F1521 -:105430000FE0A01110FF2F11020414E38C019F153F -:105440000FE0A01110FF2F11010914E380019F1537 -:105450000FE0A01110FF2F1104009AE5000014E1E5 -:105460001600000A54E08FE2040014E340009A158D -:1054700010FF2F11020A14E344009A1510FF2F1198 -:10548000020914E348009A1510FF2F11010214E3DA -:105490004C009A1510FF2F11010414E350009A15C7 -:1054A00010FF2F11010A14E32100001B020014E376 -:1054B0000E00001B10009AE5000014E11C00001B08 -:1054C000004099E50450A0E3004094E21BFF2F1137 -:1054D0003F40BDE804F05EE2C00080E300F061E11F -:1054E000FAFFFFEA18009AE51C109AE511FF2FE178 -:1054F00054B09AE51C109AE514009AE511FF2FE1CB -:1055000020109AE50000A0E311FF2FE124109AE596 -:1055100011FF2FE128109AE511FF2FE12C109AE5D9 -:1055200011FF2FE130109AE511FF2FE134109AE5B9 -:1055300011FF2FE1FEFFFFEA38E09AE53C109AE503 -:1055400018009AE511FF2FE138E09AE53C109AE542 -:1055500014009AE511FF2FE164209FE5003092E5E9 -:10556000003053E00A0000BA003082E50C0092E5FA -:10557000083092E5001091E20300000A031080E772 -:10558000043053E23C30A0B3083082E50100A0E3D0 -:105590001EFF2FE13C109FE5000091E5010080E235 -:1055A000000081E50000A0E3F8FFFFEA10009FE59E -:1055B000081090E5041051E23C10A0B3081080E5FB -:1055C0001EFF2FE1E42D0080CC040080712BFFFF33 -:1055D000D13DFFFFC92BFFFFA0822040C91C8908D5 -:1055E00089000123854A5B07184313685B18136021 -:1055F000001F81A35B1A18470420A0E50420A0E542 -:105600000420A0E50420A0E50420A0E50420A0E5F6 -:105610000420A0E50420A0E50420A0E50420A0E5E6 -:105620000420A0E50420A0E50420A0E50420A0E5D6 -:105630000420A0E50420A0E50420A0E50420A0E5C6 -:105640000420A0E50420A0E50420A0E50420A0E5B6 -:105650000420A0E50420A0E50420A0E50420A0E5A6 -:105660000420A0E50420A0E50420A0E50420A0E596 -:105670000420A0E50420A0E50420A0E50420A0E586 -:105680000420A0E50420A0E50420A0E50420A0E576 -:105690000420A0E50420A0E50420A0E50420A0E566 -:1056A0000420A0E50420A0E50420A0E50420A0E556 -:1056B0000420A0E50420A0E50420A0E50420A0E546 -:1056C0000420A0E50420A0E50420A0E50420A0E536 -:1056D0000420A0E50420A0E50420A0E50420A0E526 -:1056E0000420A0E50420A0E50420A0E50420A0E516 -:1056F0000420A0E50420A0E50420A0E50420A0E506 -:105700000420A0E50420A0E50420A0E50420A0E5F5 -:105710000420A0E50420A0E50420A0E50420A0E5E5 -:105720000420A0E50420A0E50420A0E50420A0E5D5 -:105730000420A0E50420A0E50420A0E50420A0E5C5 -:105740000420A0E50420A0E50420A0E50420A0E5B5 -:105750000420A0E50420A0E50420A0E50420A0E5A5 -:105760000420A0E50420A0E50420A0E50420A0E595 -:105770000420A0E50420A0E50420A0E50420A0E585 -:105780000420A0E50420A0E50420A0E50420A0E575 -:105790000420A0E50420A0E50420A0E50420A0E565 -:1057A0000420A0E50420A0E50420A0E50420A0E555 -:1057B0000420A0E50420A0E50420A0E50420A0E545 -:1057C0000420A0E50420A0E50420A0E50420A0E535 -:1057D0000420A0E50420A0E50420A0E50420A0E525 -:1057E0000420A0E50420A0E50420A0E50420A0E515 -:1057F0000420A0E50420A0E51EFF2FE1E42D008099 -:1058000098009FE598109FE5012040E094309FE5C7 -:10581000000091E5030050E10300001A041081E24A -:10582000042052E20000000AF8FFFFEA78009FE53A -:10583000002080E574009FE574109FE5012040E0A2 -:1058400060309FE5000091E5030050E10300001A7D -:10585000041081E2042052E20000000AF8FFFFEA8F -:1058600050009FE5002080E54C009FE54C109FE52F -:10587000012040E02C309FE5000091E5030050E15D -:105880000300001A041081E2042052E20000000A22 -:10589000F8FFFFEA28009FE5002080E51EFF2FE1CA -:1058A0007C34008080300080ADDEADDEC00400803E -:1058B000FC37008080340080C4040080FC3F0080FE -:1058C00040380080C80400807847000071EAFFEA91 -:1058D0007847000039FEFFEA7847000063FEFFEAE0 -:1058E000784700001BFFFFEA784700006BEAFFEAF9 -:1058F00000000000FFFF00000000008028040000FE -:10590000F83D00000001008000FF000000000000E2 -:10591000B90BFFFF00000000D50BFFFF03FF06548B -:10592000030000007504FFFF00000000A105FFFF59 -:1059300004FF075403000000B504FFFF000000004F -:10594000F105FFFF05FF0554030000003904FFFFC8 -:10595000000000005505FFFF01FF040003000000E8 -:105960004118FFFF00000000610EFFFF02FF020868 -:1059700000000000A102FFFF00000000F102FFFF95 -:10598000FFFF0144030000000000000000000000D1 -:105990009D0DFFFF0600FF00000000003D50FFFFCF -:1059A0008150FFFF00000000FFFFFF00000000002B -:1059B000000000000000000000000000FFFFFF00EA -:1059C00000000000000000000000000000000000D7 -:1059D000FFFFFF00000000000000000000000000CA -:1059E00000000000000000000000000048050080EA -:1059F000117521401B7521403175214049752140A9 -:105A000055752140637521407D752140A975214060 -:105A10006D762140C5762140D3762140DD76214048 -:105A2000E776214099772140A7772140B57721403B -:105A3000617821405F7C2140E97C2140897D2140C3 -:105A4000BD7E2140C97E2140297F21408D7F21409C -:105A5000B97F2140DD7F21401D80214045802140CC -:105A60008D8021409D802140C5802140D5802140EE -:105A70001D8121405B812140B18121401182214063 -:105A80001B8221401F8221408D822140D9822140EA -:105A9000318321406D832140D183214009842140FD -:105AA0001984214051842140618421407584214022 -:105AB0009D842140A7842140B18421401585214047 -:105AC0004585214051852140C5852140CF85214014 -:105AD000D9852140E3852140ED852140F78521408E -:105AE000018621400B8621401586214001892140F5 -:105AF0001F86214029862140338621403D86214052 -:105B0000658621406F862140D1862140DB86214079 -:105B1000E5862140EF862140F98621409D74214091 -:105B20000387214069872140B5872140F9872140BB -:105B3000098821409D742140558821405988214081 -:105B40005D882140B5882140DD882140E9882140D9 -:105B5000ED882140F1882140F5882140F9882140D5 -:105B6000FD8821402D852140898521409D7421405B -:105B70009D7421400D8921409D742140E174214094 -:105B80009D7421409D7421409D7421409D7421404D -:105B90009D7421409D7421406B782140F57B21400C -:105BA000317C2140000000000000000000000000E7 -:105BB000000000005C0118405801184024A3204058 -:105BC00024A7204000000000000000006C011840E5 -:105BD000680118402483204024A3204000000000D6 -:105BE000000000007C01184078011840000000000F -:105BF0000000000000000000000000008C011840C0 -:105C00008801184024A9204024AB20400000000057 -:105C10000000000000000000080012001800120040 -:105C20000C0012001C00120024A82040A4A8204050 -:105C3000A4A8204024A9204000000000D1A82140B1 -:105C40002DAA21400000000089702140C9A12140F7 -:105C50000000000000000000010000000000000043 -:105C600057892140D1A82140C52FFFFF0521FFFF03 -:105C7000EF20FFFF59A72140342E0080482E0080DE -:105C80005C2E008030333A31313A31310030372FD9 -:105C900032332F3031003030303031353639004337 -:105CA0006F707972696768742028632920323030F8 -:105CB000312033436F6D20436F72706F726174696E -:105CC0006F6E0A00081000030000000000000000D2 -:105CD000000000008C53FFFF27F07DFD0001000253 -:105CE000DA0E820001406404642D0080E42C008000 -:105CF000693EFFFFC94FFFFFD524FFFFC93BFFFFF0 -:105D0000293CFFFF191AFFFF6511FFFFCC53FFFF6E -:105D10002140FFFF8970214049722140D93FFFFF98 -:105D2000219A21408524FFFF6453FFFF8C53FFFF1E -:105D300000000000FFFF0000803000800000000035 -:105D4000FFFF000000002040B05000007B0E00006C -:105D5000006E21400000000000000000ED8921409D -:105D60008B892140A58C2140058D2140CD8D21407E -:105D70008B8B2140A98E2140158F2140698B2140BA -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA0000000000059BD2140C1BD21402DBE214051 -:105DB00000200A4A0B231B02D1182D239B01D31864 -:105DC0008861D860D8638032C86008614861D06259 -:105DD0000348C0464860886070470000680E008035 -:105DE000FE030000F0B584B00C1C051C00230093DA -:105DF000FFF7DEFF68490B231B02CF1878682840A5 -:105E00000022F8603A61BA6822407A610C1C4109AC -:105E100003D2510901D2800A02D3604800F0C2F8CF -:105E20000120F968490903D27969490900D20020A3 -:105E30000006000E03F0D4FAF868002870D00023A2 -:105E400002930193544A01231843F8600020D51DA2 -:105E500079350395012400214F4DFA68224039D04D -:105E60008A00521892004E4B9B5C1E1C834204D049 -:105E70004B4BD3185B7883422CD1494BD218D37843 -:105E8000039DED6AAB4202D9039DC046EB625368A5 -:105E90005B0801D30123009386420AD19568029BD7 -:105EA0005E1C02969B003C4E9E190B231B02F318AE -:105EB0009D61537883420DD1D268019B5D1C019591 -:105EC0009B00354D5D192D239B01EB18DA603A6973 -:105ED00001323A61640001310B29BDD30130092838 -:105EE000B8D30020029B99002B4A89180B231B0270 -:105EF000C9188861019B990089182D239B01C91835 -:105F0000C860009B002B0CD1810089180B231B0259 -:105F1000C918CB69C0468B6101300B28F4D308E067 -:105F200007E0039DE86A302803D23020039DC04675 -:105F3000E862194A786900282AD000210123184311 -:105F40007861002001240022134E7B69234010D089 -:105F500093009B189B00124D5B199D78854208D1D8 -:105F60001D690B1C9B009E192D239B01F318DD63FB -:105F70000131640001320B2AE6D301300928E1D354 -:105F800000208900044A89182D239B01C918C86381 -:105F900004B0F0BC08BC1847680E00803053FFFF07 -:105FA0000001008000470847104718477847C0465F -:105FB00018C09FE51CFF2FE17847C04610C09FE541 -:105FC0001CFF2FE17847C04608C09FE51CFF2FE16A -:105FD0003852FFFF8851FFFFD5B02140F0B50420B3 -:105FE0001A49012508601A4FBB231B01F8180573D5 -:105FF0001848416B2C0500207A6E174B8A421DD041 -:10600000197B002917D1D91DFF313A3149781E1C5F -:10601000002910D1B06010207060104A1049FFF7BD -:10602000C3FF002807D035730423B8691843B8614B -:10603000206100F017F8F0BC08BC1847187304235F -:10604000B8699843B8612061F5E70000000000B02E -:10605000680E008000011840280500802055FFFFD1 -:106060007D712140F8B5154F396C1548406E0C1AFA -:10607000144E7168144DA14206D8144A0A43009286 -:10608000B96B0918FA6B11E01122520522430092F4 -:10609000B96B09180020FA6B2B1CFFF78DFF706895 -:1060A000001B0A4A02430092B96BFA6B00202B1CBA -:1060B000FFF782FFF8BC08BC184700007C2900806D -:1060C000680E0080280500804480204000003702D0 -:1060D000F0B52B4FB8687968C0192030294AFFF70E -:1060E00063FF0120C0022849C0460860B968381C17 -:1060F000264D0024264EEF1D7937002931D1316815 -:106100000A78120A03D20473F0BC08BC1847497815 -:1061100000290CD1051C406800F03EF9306800F001 -:1061200067F8002826D12C73FFF758FF22E00901F9 -:10613000071C4160081C174A1749FFF735FF002864 -:1061400007D13C730423A86998439904A8610861A6 -:10615000DAE7102000F020F91020B860FFF782FF86 -:10616000D2E7051C406800F017F9306800F040F8ED -:106170000028D8D00223F86B1843F863C4E7000066 -:1061800028050080A555FFFF000000B0680E0080C4 -:10619000E40100802055FFFF7D71214090B5012072 -:1061A00040031049002708600F4CE01DFF303A30D3 -:1061B0004770E06980000019006900F0D7F8E069D5 -:1061C000002801D0E76101E00120E06107480223D7 -:1061D000C16B1943C1632773FFF700FF90BC08BC74 -:1061E00018470000000000B028050080E80E00807D -:1061F00080B584B0071C78886D2803DB381C00F05C -:10620000F7F817E080000D490958381CFFF7CBFE5E -:1062100000280FD13978C9090CD36946381C00F021 -:10622000CFF86846002100F00BF8002801D10120CA -:1062300000E0002004B080BC08BC1847E8010080E2 -:10624000F0B582B0021C414BDD1DFF353A352F7889 -:10625000002F01D0002700E001272F702F78FB00CE -:10626000DB195B013A4FDC1940780001C71D093783 -:1062700000208300D658C046E65001300428F8D3E9 -:1062800000290FD00022BB08019383420BD9131CB5 -:106290009B00CB588600A351019B01300132834201 -:1062A000F5D800E010272B48026D806E2A49824203 -:1062B00003D8821ACB6C9A1A00E0121ABA4205D897 -:1062C0002648816B01318163012037E0C319CA6C14 -:1062D000934208D8224A3A4300920A1C496C091892 -:1062E000926C231C12E0161A00961B49496C09187F -:1062F0001948826C0320231CFFF75EFEB81B184A66 -:1063000002430092A3191448826C416C0320FFF7EA -:1063100053FE01200D49C04668708A6992005218E8 -:1063200017618A69002A02D000278F6100E0886126 -:106330000C480223C16B1943C163002001270A499D -:10634000C0464F7302B0F0BC08BC18472805008057 -:1063500050BA2040680E00807C290080A082204036 -:1063600000001902E80E0080181A008007498A6EA2 -:106370001018074AD26C13041B0C834200D8801AF1 -:106380008866886E0349C04648617047680E008081 -:106390007C29008090EE204006494A6E1018064A7B -:1063A000126C824200D8801A4866486E0349C04683 -:1063B00008617047680E00807C29008090EE2040C4 -:1063C00005220A608288C0468A8000224A7040887E -:1063D000C0464880CA808A60CA6070470522026051 -:1063E0000022828042704180C2808260C260704719 -:1063F00080B584B0071C0E48416B0131416369468A -:10640000381CFFF7DDFF3868C0460090452000AB20 -:1064100018700127DF8068460021FFF711FF002870 -:1064200001D1381C00E0002004B080BC08BC184733 -:10643000A082204000B584B0C188094AC04691813D -:106440006946FFF7BDFF0120400201AB5880684656 -:106450000021FFF7F5FE012004B008BC184700003A -:10646000E80E008000B5FFF7C3FF08BC1847012005 -:106470000349C0460871A121490388600020704784 -:10648000280F008000200449C0460871FF21A12286 -:106490005203013191607047280F00800220A12132 -:1064A000490388600020704701204002A121490370 -:1064B000886000207047C088C006C00EA121490333 -:1064C00048610249C046C86300207047E81A00804E -:1064D00080B584B008490F6B6946FFF771FFF80675 -:1064E000C00E01AB588068460021FFF7A9FE0120CD -:1064F00004B080BC08BC18478000144080B585B04B -:10650000071C6946381CFFF75BFFF88804A903F0F5 -:10651000C9FF01AB588001A8408800280FD001A80E -:1065200040888008033880080130043B5870049884 -:106530000168C04602914068C046039005E000A88B -:1065400000784023184300AB18700498C11D013136 -:106550006846FFF775FE012005B080BC08BC1847EF -:1065600090B584B0144F397B002920D1F91DFF313B -:106570003A31497800291AD110490522009208229F -:1065800000AB5A809880062000AB58700024DC8055 -:106590000868C04602904868C046039001203873DE -:1065A00068460831FFF74CFE002800D03C7304B069 -:1065B00090BC08BC1847000028050080A42A008071 -:1065C00090B584B0071C6946381CFFF7F9FEBA681D -:1065D0000D4C0E48002A05D10D49FFF7E4FC0028B8 -:1065E0000CDA05E0B9880B4BFFF7DFFC002805DA71 -:1065F00001AB5C8068460021FFF722FE002004B05A -:1066000090BC08BC18470000FFFF00000D76214039 -:10661000C1BD214059BD214000B5C08803F02EFF07 -:10662000002008BC184700B5FFF7E2FE08BC184779 -:1066300000B5FFF7DDFE08BC184700B5011C0220BD -:1066400000F002F808BC1847B0B5C6B0071C081C1B -:106650006946FFF7B5FE2148FFF7A4FC041C204A59 -:106660000021381CFFF7A0FC002827D004A91D4AF0 -:10667000381CFFF799FC04A80023012F06D10CAAAF -:1066800002320021136001311029FBD30168042973 -:1066900004D9890803398908013100E0191C00ABCD -:1066A000597006A90978C046D9800068C046029092 -:1066B0000798C0460390043308AD02E0452000ABC4 -:1066C00018700949201CFFF76EFC6846291CFFF76B -:1066D000B7FD012046B0B0BC08BC18472402FFFF3C -:1066E00059B121409DAF21403C02FFFF00B5011C84 -:1066F000022000F010F808BC184700B5011C01206A -:10670000FFF7A2FF08BC184700B5011C012000F0EC -:1067100002F808BC1847F0B5C7B0041C0F1C381CA1 -:1067200001A9FFF74DFE2148FFF73CFC0090787867 -:106730000001BA680430FC2A25D8FF2309339842A7 -:1067400021D8192C1FD8FD88F868C0460590F91D7E -:10675000093106AB00207E78002E0DDD40C940C314 -:1067600040C940C340C940C340C940C301300004D0 -:10677000000C7E788642F1DC201C05A92B1CFFF75B -:1067800021FC002805D001A800784023184301AB64 -:10679000187007490098FFF706FC002101A8FFF7D1 -:1067A0004FFD012047B0F0BC08BC18472402FFFF92 -:1067B0003C02FFFF00B5FFF71BFE08BC1847F0B511 -:1067C000C6B0071CFC88254D6868013069466860C2 -:1067D000381CFFF7F5FD102C08D300A800784023E3 -:1067E000184300AB18700220D88017E07878820038 -:1067F000FB1D09330020B968002A15D940CB0F1CB6 -:106800000131BE420DD000AA127840231A4300ABDA -:106810001A700422DA800290039104336846002142 -:1068200015E001309042E9D300AB5C7002946968D6 -:10683000C0460391A20000201033002A05D90F1C86 -:1068400080C3013001319042F9D3684604A9FFF7B3 -:10685000F7FC012046B0F0BC08BC18479C03008040 -:1068600090B4234800680121420900D30021002789 -:106870003A1C430B00D2022211431E4A2024D36843 -:10688000012B2ED1800A00D200240C43201C1B2394 -:10689000DB01D118898B090B00D204273843D16F53 -:1068A0000968090A07D2D11D793109680968090AFE -:1068B00001D308231843E3231B01D1188979032945 -:1068C00002D1FF23013318430B49096A10224B0AF6 -:1068D00000D2002210438907890F8901084390BC28 -:1068E0007047400C00D200240C43201CECE7000051 -:1068F00000001040680E0080C0001840F0B53A4C0F -:10690000201C04F007FA3948E3231B01C718B979A2 -:10691000374EC51D7935062962D202A35B5C5B0048 -:106920009F44001C030E1E374E550120B8710020F5 -:10693000B060FFF795FF0523984300F06FF80CE077 -:10694000FFF78EFFC00806D3B068411CB1600A286B -:1069500003D9042000E00220B8716422201C2BE03F -:10696000061CC06F80230168194301600320B871C1 -:10697000201C204A002104F099F9F06F04230168DB -:10698000994301602868016819430160F0BC08BCA4 -:1069900018470521B971296804230A689A430A60D7 -:1069A000C06F016819430160FFF75AFF08231843BD -:1069B00000F034F8201C104A002104F077F9E5E7D4 -:1069C000FFF74EFF0423184300F028F8DEE700200D -:1069D000296860230A689A430A60FFF7E3FAD5E75B -:1069E0000620B871D2E70000A9792140680E008026 -:1069F0009C030080307500001027000000B50020C7 -:106A00000449C046887104480122002104F04EF96F -:106A100008BC1847981C0080A979214090B5071C34 -:106A200031480068790803D31023011C994301E021 -:106A3000102101432D4CE268012A05D12279002A58 -:106A400002D001239B021943814202D0012000059C -:106A50000160E068012820D11B23DB01E018808B56 -:106A6000F90804D30123DB02011C994301E0012151 -:106A7000C902814202D0002002F01AFB380907D374 -:106A8000E06F8023016899430160E018006800E02E -:106A9000E06F80230168194301601548016A780995 -:106AA00003D3FF200130084303E0FF23081C013318 -:106AB000984380088000BA099207920F10438842D9 -:106AC00002D00C49C0460862E168012908D1790A60 -:106AD00006D3FF2304331840032801D1FFF78EFFAC -:106AE00090BC08BC1847000000001040680E0080F1 -:106AF000C0001840C000180080B5FFF7B1FE800943 -:106B00001BD20F48E3231B01C1184A79002A14D174 -:106B100001224A7100278030006860230168994390 -:106B20000160084806E0022002F08CFC072002F019 -:106B30005BFC381CFFF736FAF5E780BC08BC184749 -:106B4000680E0080F401FFFF00B584B06946FFF7CE -:106B500037FCFFF785FE01AB588008480068C04647 -:106B600002900748006AC046039068460021FFF77C -:106B700067FB012004B008BC18470000000010406B -:106B8000C000184080B584B0071C6946381CFFF768 -:106B900017FCF888FFF742FFFFF762FE01AB588051 -:106BA00068460021FFF74CFB012004B080BC08BC04 -:106BB0001847B0B5C6B0C7886946FFF701FC012485 -:106BC0001A4B9F420AD900A800784023184300AB13 -:106BD00018700220D8806846002120E01448FFF792 -:106BE000E1F9051C134A381C04A9FFF7DDF9124925 -:106BF000281CFFF7D8F9012F06D10CA9002000228C -:106C00000A6001301028FBD3102000AB58700498A4 -:106C1000C04602900598C0460390684606A9FFF753 -:106C20000FFB201C46B0B0BC08BC1847FF01000099 -:106C30002402FFFF9DAF21403C02FFFFF0B5C6B02C -:106C4000071C6946381CFFF7BBFBFC8878780125D8 -:106C5000102801D1192C09D900A800784023184325 -:106C600000AB18700220D880043327E0B868C04613 -:106C70000490F868C046059006AAFB1D0933002160 -:106C8000787800280DDD002040CB40C201300004A0 -:106C9000000C0428F8DB481C0104090C78788842B1 -:106CA000F1DC0B48FFF77EF9071C0A4A201C04A9F7 -:106CB000FFF77AF90849381CFFF775F96846002193 -:106CC000FFF7BEFA281C46B0F0BC08BC184700000D -:106CD0002402FFFFC5AF21403C02FFFFF0B584B0A6 -:106CE000041C0027E688A26847490879002808D0D4 -:106CF000002E01D0012E01D1012701E0042E00D188 -:106D0000032601254148052E66D202A39B5D5B0048 -:106D10009F44001C0306080C10000580002303E0BC -:106D2000058005E000230380438006E00023038004 -:106D3000458002E0FF2301330380CB1D79339E8918 -:106D400001235B029E4202DBD207D20F00E0012248 -:106D50006D235B01C9188988FF23E133994301231F -:106D600019430688FF339E420DD1FF20E1300843CE -:106D7000002A04D101239B029843011C20E0012139 -:106D8000890201431CE0012E0AD14088012804D168 -:106D900060231943002A13D00CE0202319430FE08D -:106DA000002E0DD14088012808D1FF2381331943DB -:106DB000002A05D001239B02194301E080231943D7 -:106DC000042002F075F909214902002002F070F94F -:106DD000002F02D1002012E0FFE76946201CFFF7D8 -:106DE000EFFA00A800784023184300AB1870022087 -:106DF000D880684600210433FFF722FA281C04B02B -:106E0000F0BC08BC18470000680E0080881C008099 -:106E1000C0885121890308620020704780B5164F51 -:106E2000F868012807D137239B01F818408A802190 -:106E300001431B2007E06D235B01F818808B0121C3 -:106E400049030143102002F033F9012071235B0153 -:106E5000F918088048801B23DB01F818808B012378 -:106E60001B039843412109020143002002F020F94D -:106E7000002080BC08BC1847680E008080B5174F02 -:106E8000F868012808D137239B01F818408A80232D -:106E90009843011C1B2008E06D235B01F818808BD0 -:106EA00001235B039843011C102002F001F9FF202D -:106EB00071235B01F918013008801B23DB01F818EE -:106EC000808B41231B029843092149020143002082 -:106ED00002F0EEF8002080BC08BC1847680E008065 -:106EE00080B584B00849CF6A6946FFF769FAB805EA -:106EF000800D01AB588068460021FFF7A1F9012001 -:106F000004B080BC08BC184740001440C0889F23D0 -:106F100018400549C96A1B235B011940084303490E -:106F2000C046C86200207047400014404000140072 -:106F300080B584B00D490F6A012F01D1FF0307E02E -:106F4000022F01D13F0303E0002F01D10127FF02EF -:106F50006946FFF735FA01AB5F8068460021FFF70D -:106F60006FF9012004B080BC08BC18470020144011 -:106F7000C288A1204003002101235B039A4201D172 -:106F8000022204E00123DB039A4202D101220262C1 -:106F900000E00162081C704790B584B0071C02F045 -:106FA0009FF86946041C381CFFF70AFA01AB5C80A5 -:106FB000094FF86DC046029068460021FFF740F97E -:106FC000F86DC007C00F0549C046C862012004B073 -:106FD00090BC08BC18470000A42A0080681C0080F0 -:106FE000C0880249C04648610020704780001400F4 -:106FF00000B584B06946FFF7E3F90648C06801AB05 -:10700000588068460021FFF71BF9012004B008BC36 -:107010001847000080001440C0880249C046C8607C -:10702000002070478000140080B584B069468768EE -:10703000FFF7C6F9202F07D278000C4940181B2310 -:10704000DB01C018808B06E000A8007840231843BD -:1070500000AB1870022001AB588068460021FFF792 -:10706000EFF8012004B080BC08BC1847680E00800F -:1070700000B584B0C1888268202A04D2101C02F0B6 -:1070800017F8002010E06946FFF79AF900A8007889 -:107090004023184300AB18700220D88068460021B6 -:1070A0000433FFF7CDF8012004B008BC184790B5B1 -:1070B00084B0C7886946FFF783F91048FEF772FF6E -:1070C0000220391C02F0F2FF002806D00220391CF1 -:1070D00002F036FF01AB588002E0452000AB18708B -:1070E0000749201CFEF75FFF68460021FFF7A8F85C -:1070F000012004B090BC08BC184700002402FFFF28 -:107100003C02FFFFB0B584B0C78869468468FFF7CA -:1071100057F91048FEF746FF0F4A0220391CFEF7C8 -:1071200043FF002806D00D4B0220391C221CFEF71D -:107130003CFF02E0452000AB18700949281CFEF70F -:1071400032FF68460021FFF77BF8012004B0B0BC95 -:1071500008BC18472402FFFF59B1214059B0214013 -:107160003C02FFFF00B5FFF743F908BC18470020B9 -:10717000704780B4C288194BA1214903002A03D16A -:10718000186B1023984304E0012A04D1186B1023D4 -:10719000184348611FE0022A1DD1C2688768002099 -:1071A0003B1CC340DB07DB0F9B0203430B61013039 -:1071B0000004000C2028F3DB0020131CC340DB0775 -:1071C000DB0F9B02C71D19373B430B6101300004E5 -:1071D000000C2028F1DB002080BC704780001440A8 -:1071E00080B4C28881681002120A10430204120C93 -:1071F0000C48C04602600C4BC0461A800A0C1702AD -:1072000012123A431204120C42605A800904090C0B -:107210000A02090A11430904090C816099800020BF -:1072200080BC704740001400281B0080B0B584B0BB -:1072300013490A681204120C1302121213434A680B -:107240001204120C1F1C1302121213438968090442 -:10725000090C0A02091211430C04240C69461D1C76 -:10726000FFF7AEF801AB5F80280420430290684628 -:107270000021FEF7E5FF012004B0B0BC08BC1847B0 -:1072800040001440C18882680802090A08430004CB -:10729000000C0A49C046C860100C030200121843D3 -:1072A0000004000C08611004000C0202000A1043E4 -:1072B0000004000C486100207047000040001400EA -:1072C00090B584B0164BD9680904090C0A0209125A -:1072D00011431A691204120C170212123A435B6925 -:1072E0001B041B0C1F021B123B431F043F0C0523F6 -:1072F0000093848801AB1C800024043B5C704088B0 -:1073000000AB5880D980100438430290039468463B -:107310000021FEF795FF012004B090BC08BC18477F -:107320004000144000B584B00B498A6A05210091E1 -:10733000818801AB19800021043B5970408800AB63 -:107340005880DA80029103916846FEF779FF0120A8 -:1073500004B008BC18470000C0001440C0880249AF -:10736000C046886200207047C000140000B584B099 -:107370000B490A6A05210091818801AB198000211F -:10738000043B5970408800AB5880DA800291039129 -:107390006846FEF755FF012004B008BC18470000FE -:1073A000C0001440C0880249C046086200207047EF -:1073B000C000140000B5C0880249FEF7F4FD0020AB -:1073C00008BC18477502FFFF00B584B06946FEF798 -:1073D000F7FF0648006B01AB588068460021FEF7B6 -:1073E0002FFF012004B008BC18470000680E008081 -:1073F00000B5FEF7FDFF08BC184700B5FEF7F8FF23 -:1074000008BC184700B5FEF7F3FF08BC184780B565 -:10741000071C1048FEF7C6FD01204002A1214903C8 -:10742000886000210C48C04601710C480268520C6B -:1074300005D20268120C06D10068800A03D30848FE -:10744000C046C76002E00748C0460764081C80BC0D -:1074500008BC1847D5942140280F00800000104038 -:10746000400118000000008000B501200349C0461B -:1074700008721220FFF7CBFF08BC1847881C008059 -:1074800000B501200349C04648721520FFF7BFFF31 -:1074900008BC1847881C008000B501F0F9FF0120E6 -:1074A00008BC184780B584B0071CF88802F0FEF8C5 -:1074B00000280CD16946381CFEF782FF064801AB54 -:1074C000588068460021FEF7BBFE012000E0002046 -:1074D00004B080BC08BC1847FFFF000080B584B032 -:1074E0006946FEF76DFF012701AB5F80094881897E -:1074F0000904C2891143029181880904C0880843A4 -:10750000039068460021FEF79BFE381C04B080BC47 -:1075100008BC18474C2A008000B5FEF769FF08BC7C -:10752000184700B5FEF764FF08BC184700B5FEF722 -:107530005FFF08BC184700B5FEF75AFF08BC1847A4 -:1075400000B5FEF755FF08BC184700B5FEF750FF21 -:1075500008BC184700B5FEF74BFF08BC184700B53C -:10756000FEF746FF08BC184700B5FEF741FF08BC10 -:10757000184700B5FEF73CFF08BC184700B5FEF7FA -:1075800037FF08BC184700B5FEF732FF08BC1847A4 -:1075900000B58CB008A9FEF713FF694608A802F0F1 -:1075A000A9FF022008AB5870694608A8FEF748FEFC -:1075B00001200CB008BC184700B5FEF719FF08BC45 -:1075C000184790B584B0071C6946381CFEF7F8FED2 -:1075D000FA8812490124C81D8930002A0FD004708E -:1075E0004470B868000C8031C882B868C04608830F -:1075F000F868000C4883F868C046888302E00021E0 -:1076000001704170064801AB588068460021FEF7C2 -:1076100017FE201C04B090BC08BC1847680E008000 -:10762000FFFF000000B5FEF7E3FE08BC184700B5F9 -:10763000FEF7DEFE08BC184700B5FEF7D9FE08BC11 -:10764000184700B5FEF7D4FE08BC184700B5FEF792 -:10765000CFFE08BC184790B584B0071C6946381C9B -:10766000FEF7AEFEF8880324E40404430323DB049E -:107670009C4202D30F4B9C4206D90F4801AB588065 -:1076800068460021FEF7DCFD0120800720430068EA -:10769000002100AB5970FA88C046DA80029003914D -:1076A00068460433FEF7CCFD012004B090BC08BC52 -:1076B00018470000E0001800FFFF000080B584B00C -:1076C000071C6946381CFEF77BFEF8880323DB04A1 -:1076D0001843984202D30A4B984208D9094801AB93 -:1076E000588068460021FEF7ABFD012003E0B96831 -:1076F000C0460160002004B080BC08BC18470000F0 -:10770000E0001800FFFF000080B586B002A9FEF778 -:1077100057FE012702AB5F700020D8800A484168FD -:10772000C04604918168C0460591C168C046009179 -:107730004069C0460190694602A8FEF781FD381CE9 -:1077400006B080BC08BC18476819008000B5C16845 -:107750008068FEF747FB002008BC184700207047F0 -:1077600090B584B0041C0F1C68465021FEF736FE0D -:1077700001AB5C80029768460021FEF761FD04B012 -:1077800090BC08BC184780B584B0071C68465121DE -:10779000FEF724FE01AB5F8068460021FEF750FD36 -:1077A00004B080BC08BC1847002070470020704718 -:1077B00090B584B0002712490968124A126B102351 -:1077C0001A400124002A00D001278A0C03D33A046E -:1077D000120C02271743C90C03D33904090C0427E0 -:1077E0000F436946FEF7ECFD01AB5F806846002160 -:1077F000FEF726FD201C04B090BC08BC1847000012 -:1078000000001040C000184000B584B06946FEF783 -:10781000D7FD0648C06D01AB588068460021FEF7D1 -:107820000FFD012004B008BC18470000A42A008006 -:1078300000B5FEF7DDFD08BC184770470020704713 -:1078400000207047002070470020704700207047DC -:107850000020704700B5FEF7CBFD08BC18470000BC -:1078600080B585B001A9FEF7ABFD002001AB5870D3 -:107870000C49C9680127012902D10397049701E047 -:1078800003970490684601F033FD02AB0098C046B0 -:107890005880002101A8FEF7D3FC381C05B080BC3D -:1078A00008BC1847680E0080704704490020002279 -:1078B0000A70013001316828FAD37047A082204055 -:1078C0000022884203D3401A01328842FBD2101CA6 -:1078D0007047884202D3401A8842FCD2704790B465 -:1078E000011CFF27042927DA0020144A43001B1833 -:1078F000DB00D458630C1AD24B005918C9005758F2 -:1079000043001B18DB00D75089189A184F68C046EF -:1079100057608B68C04693600B69C04613614B6922 -:10792000C0465361C968C046D16090BC7047013001 -:107930000006000E0428D9DB381CF6E740AB2040D7 -:10794000F7B5C4B0041C0020469A112111406ED036 -:1079500000277900C919C900574A5158490C03D268 -:1079600001300006000E04E0791C0F063F0E042FC4 -:10797000EFDB00285BD0002600220092402300218C -:10798000002002AA00F088FA04A9002082008A5888 -:107990001206120EA24203D1721C1606360E04E025 -:1079A00001300006000E1028F0DB002E3DD0042C24 -:1079B0003ED1800008584001800D00220092102323 -:1079C000002102AA00F068FA0021019102A805999D -:1079D000490C890529D0C1680A06120E459B9A42B6 -:1079E00011D1C0684001860D002200920C230021B5 -:1079F000301C02AA00F050FA0199029D481C0106B1 -:107A0000090E01910EE04801860D0022009210231C -:107A10000021301C02AA00F03FFA02A80599490C87 -:107A20008905D8D1019900290FD1FF203DE040E020 -:107A3000800008584001860D002200920C2300218E -:107A4000301C02AA00F028FA029D01200004469A88 -:107A500010437900C919C900174AC0465050301C5C -:107A60008E1870601020042C00D00C20041CB06014 -:107A700000202021469A1140202900D0281C306186 -:107A80002819FF21FF3008300931FFF719FF4301A2 -:107A90001818C000001B706100205021469A114048 -:107AA000502900D1281CF060381C47B0F0BC08BC3D -:107AB0001847FF20F9E7000040AB204080B40023C6 -:107AC0000022002906D9875C7B401B061B0E013271 -:107AD0008A42F8D3D8430006000E80BC7047F0B548 -:107AE000C6B0042807DA41000918C9004591414A87 -:107AF00051584B0C02D20020C04376E001235B04B6 -:107B0000194043001818C0003A4A1418002961D0DF -:107B1000002102912069A168451830D0FF21681E1C -:107B20000931FFF7CDFE616840180190019881424C -:107B300002D1A668AF1B09E00026FF21281C0931ED -:107B4000FFF7C7FE071C01D1FF270937002200926B -:107B50000198311C03AA3B1C00F09EF903A8391CB4 -:107B6000FFF7ACFFC043029948400106090E02919D -:107B7000ED1BA068A84200D10025002DCED80299A7 -:107B8000CF43002200920C230021606803AA00F07A -:107B900083F92069C04603900598000A000239065F -:107BA000090E08430590FF231B02984305900C2102 -:107BB00003A8FFF783FFFF231B02059999430006E3 -:107BC000000E0002084305900C230021606803AA00 -:107BD00000F0CAF900204599064AC0465050C143FA -:107BE0006160A160E1602161616146B0F0BC08BCE8 -:107BF0001847000040AB2040B0B44C42002900DBE5 -:107C00000C1C0027FF43042821DA124D43001818EA -:107C1000C0004019012A05D0022A09D0032A16D132 -:107C200001690BE0002912DB02698A420FD305E0EB -:107C3000002907DAC168A14209D3091BC160C068E5 -:107C4000B0BC7047C168091902699142F6D9381C65 -:107C5000F6E7000040AB2040F0B584B0171C0D1CC7 -:107C60000021029142001218D2002C498B581B06A9 -:107C70001B0E01930023DB43042802DA019840081D -:107C800001D2181C46E05418E068C21921698A42E2 -:107C900000D90F1A002F3CD9A068E1684018FF21D5 -:107CA0000931FFF70DFE61684618A068E1684018C9 -:107CB000FF210931FFF70DFEC219FF2109318A4268 -:107CC00014D9019AC04600920B1A0393011C301C70 -:107CD0002A1C00F0E1F8E068039BC018E060039BF9 -:107CE0005D19FF1A02981818029010E0019AC04618 -:107CF0000092011C301C2A1C3B1C00F0CDF8E068EF -:107D0000C019ED19E0600298C01902900027002FF9 -:107D1000C2D8029804B0F0BC08BC184740AB204061 -:107D2000F0B583B0171C0D1C002101914200121800 -:107D3000D200029230498A581206120E0024E443FF -:107D4000042801DA500901D2201C51E0029A54188B -:107D5000E068C2196069824201D92269871A002F3E -:107D600045D9254EA068E1684018FF210931FFF789 -:107D7000A7FD616840180090A068E1684018FF21E5 -:107D80000931FFF7A6FD029AB15801235B0419439C -:107D9000B150C119FF220932914213D9131A011CA3 -:107DA00000982A1C1E1C00F0DFF8E0688019751985 -:107DB000E0602169884200D92061BF1B019830181A -:107DC000019012E0011C009E301C2A1C3B1C00F09C -:107DD000CBF8E068C019ED19E0602169884200D94C -:107DE00020610198C01901900027002FB9D801988F -:107DF00003B0F0BC08BC184740AB2040B0B5C3B0DE -:107E00000C1C0027FA43042806DA41000918C900AF -:107E1000144845586B0C04D2101C43B0B0BC08BCCD -:107E2000184762091BD300220092081840680C23EF -:107E3000002101AA00F030F8112C0DD0122C0DD029 -:107E4000132C05D0142C0AD103980004070E06E069 -:107E5000039807063F0E02E0019F00E0029F381CD6 -:107E6000DBE7000040AB20400349002000220A5419 -:107E700001306028FBD3704740AB204000B502F0D2 -:107E80006FFA572002F0CCF902F040F9000AFBD358 -:107E900002F04EFA08BC1847F0B582B0079D141CDA -:107EA0001F1C304AD26F202316689E431660331C75 -:107EB000FF2201322A4040020843050A061C000C3A -:107EC0000190002A20D002F04BFA532002F0A8F9CA -:107ED0000198C046009002F0A3F9281C02F0A0F916 -:107EE000301C02F09DF902F023FAFFF7C7FF02F001 -:107EF00037FA542002F094F9009802F091F9281C06 -:107F000002F08EF9301C14E002F02AFA522002F03E -:107F100087F9019802F084F9281C02F081F9301CDD -:107F200002F07EF9002002F07BF9002002F078F9DF -:107F3000002002F075F9002002F072F9002F05D937 -:107F400002F0E4F820700134013FF9D102F0F0F9B9 -:107F5000044AD06F202301681943016002B0F0BCCD -:107F600008BC1847680E0080F0B582B0141C1F1CB6 -:107F700042020A43151C012854D02C49C86F202303 -:107F800002689A430260C86F402301681943016088 -:107F900002F0E6F9532002F043F9280C061C02F027 -:107FA0003FF9280A0190009002F03AF9281C02F0EB -:107FB00037F902F0BDF9FFF761FF02F0D1F9842033 -:107FC00002F02EF9301C02F02BF9009802F028F98B -:107FD000281C02F025F9002F05D92078013402F081 -:107FE0001FF9013FF9D102F0A3F902F0B9F983209A -:107FF00002F016F9301C02F013F9019802F010F9A2 -:10800000281C02F00DF902F093F9FFF737FF07493A -:10801000C86F402302689A430260C86F202301683A -:108020001943016002B0F0BC08BC1847680E00801C -:108030007047000080B501F08FF8064FC046F86029 -:1080400001F0F2F8788001F0B1F8387180BC08BC1A -:1080500018470000680E008000B501F005F90249DC -:10806000C046088008BC1847680E00800B48C168ED -:10807000012911D1C16F02230A681A430A60C16F36 -:1080800080230A681A430A60C118086882230268BC -:108090001A4302600020088170470000680E0080CB -:1080A000F0B44A49CA1D9D32002000278300D750F2 -:1080B00001301728FAD3464C00208200A750013027 -:1080C0002028FAD3434A00208300D75001302028CB -:1080D000FAD3A76197614F658F653F4DC0462F600A -:1080E0006F60AF60AF61EF602F616F610020C10012 -:1080F00009184901354BC9188600CB1DF933344C9A -:108100003419E36311235B01CB1863630D239B01D7 -:10811000CB18B418E36323235B01C91861630130F2 -:108120000228E4DB2948C11DF931294CC046A1626F -:10813000616B0D239B01E162C1189162516BC046D6 -:10814000D1620821E1642549C046216524490B69B3 -:10815000C0466365C31D4D33E36525668B68C04625 -:108160006366CB68C046A3661E4BC046E3662767BE -:108170000B23DB01C318A36767670126E31D69337F -:108180006661E7611F730223D364174BC046136512 -:10819000CB69C0465365C31D5133D3652B1D136690 -:1081A0004B69C04653668969C04691660F49C0460F -:1081B000D16616670F23DB01C01890675667D76139 -:1081C000D01D693056610773F0BC7047680E00809F -:1081D000E42C0080642D008090EE204030011800D7 -:1081E0007C2900800055FFFF380118001055FFFF63 -:1081F00090B400211E4ABB231B01D718F973192321 -:10820000DB01D0180124CD231B01D318C1611C70E0 -:1082100033239B01D3189960B97359612F239B01B4 -:10822000D3181960134B5127BF0303633B60846964 -:10823000E4184463043C7C600124E40284630E4C33 -:10824000C046BC60046BC04644628469E4180B4BB2 -:10825000E318FB60036BC0468362436AC046036257 -:10826000C16351649164D165D16690BC70470000D0 -:10827000680E008000002040FC070000FCF7FFFFB4 -:1082800090B400221B49C9231B01C81802710120A8 -:10829000BB231B01CB1858731748031C0027DC1D98 -:1082A000C1341C65231C01373F2FF8D31A651923ED -:1082B000DB01CF1833239B01CB183A619861402032 -:1082C000F860DA611A62CA640A660C48C046C26085 -:1082D0000B48006BC006C00EF8630A480168C04630 -:1082E00019804168C04659808068C046988090BC1B -:1082F00070470000680E008090BC204090EE204047 -:10830000800014404000144000200A49C046087311 -:10831000CB1DFF333A338861C8611870064AC046E6 -:1083200010655066906608705870BB231B01D11809 -:108330000873704728050080680E0080F0B42F494C -:108340002F4AC046116101239B02C81850612D4875 -:10835000C0461062DB00C3185362002313635363EB -:10836000294A2A4FD41DFF34FA3414C7083F3B6111 -:108370001C1F7C61264FC0463960B8617961F86284 -:108380003B637B64BA64FA65224FFE1DF936224DC9 -:10839000EC1D793426625126B6033761246AC04643 -:1083A00074612F671D4D09277F04EC1D75347C60B7 -:1083B0003D601B4CC0463C61E61D75367E61194F21 -:1083C000C0467C603D600F1C0021FF2401341D1C51 -:1083D0008B00FD500131A142FAD3011C002001277E -:1083E000FF028300CD500130B842FAD30020810053 -:1083F000555001308028FAD3F0BC704724A32040A8 -:10840000400118002483204024A920408001180046 -:10841000A803008024A72040680E008024A82040E4 -:10842000A4A8204008040080B8B52C48FDF7BAFD88 -:1084300001202B490A68520C06D20A68120C02D19C -:108440000A68920A00D200200406240E254AD71D8D -:108450000D37002300209D0078510133042BFAD3FF -:1084600001273F055061F860D061F8610023DB43CC -:1084700093613B6113623B6200271B4B8D68C046D2 -:1084800000958D69C0460095002C0BD0DD6BC04671 -:1084900000959D6BC04600955D6BC04600951D6BB9 -:1084A000C04600950137402FE8D300276C460123D2 -:1084B0005B071C4301E0206001370D682B0902D2E5 -:1084C000802FF8D301E0802F03D308494B6E01338E -:1084D0004B66D062B8BC08BC18470000F401FFFF2F -:1084E00000001040680E008000011840A08220406B -:1084F00090B400210E4F0F4A00204C01641AA400D2 -:10850000A318586098601864586410535880CC00C1 -:10851000E4199867DC6201310329EED30649C046AD -:10852000086048608860C860086190BC70470000BF -:10853000AC6621405C2B0080D02C00806421054873 -:10854000C04601630021C943416381630021C163C7 -:1085500001647047680E008080B4012040020A491F -:10856000C04608603C20486088600848C046C86033 -:108570000020074A8700CB68C046DA510130102836 -:10858000F8D380BC70470000E42D0080F42D0080FB -:108590005D4CFFFF1249134867239B01CA1806C0B0 -:1085A0000838114BCA18C160826001610F49104838 -:1085B000A7239B01CA1806C008380E4BCA18C16011 -:1085C000826001610C480D4967239B01C21805C1F7 -:1085D0000839054BC218C8608A60086170470000FE -:1085E000AC1E2140482E0080FC1F0000ACEE204055 -:1085F000342E0080FC2F0000AC3E21405C2E008019 -:1086000090B40021404C00200A0112191923DB010B -:10861000D218D06210635063906301310329F3D301 -:108620003A49C04608634863886320600121E31D1E -:108630005933606019711872987198725971587233 -:10864000D871D872E21D4932117319709073987005 -:1086500051735970D073D8701171117290719072FA -:1086600050715072D071D07218730222E71D6937B1 -:108670003A709973BA7058737870D873F87039710A -:108680003A72B971B97278717A72F971F972397393 -:10869000E31D79331A70B973997078735A70F9734E -:1086A000D9701A711A7299719A7258715A72D97175 -:1086B000DA721973E71D89373A709973B970587374 -:1086C0007A70D973F97039713A72B971B972787177 -:1086D0007A72F971F9723A73E31D99331A70B973AA -:1086E0009A7078735A70F973DA7019711A729971F5 -:1086F000997258715A72D971D9722061E0606061C3 -:10870000A06090BC70470000A01C0080E8190080A9 -:10871000812000020149C04688627047C0001400F1 -:1087200009490A4BC818043BC91808600021C21D3A -:108730002932C261101C01310829F8D3C11F29391F -:108740000020C86170470000680E008084090000A6 -:1087500006480749C0460880488000208880C880B5 -:1087600088600449C046486188617047FFFF000087 -:108770004C2A00806C06008000210648C21D193278 -:10878000C1600161C16101621171FF30013041625C -:10879000704700006C06008009480A4BC04618600C -:1087A0000021C21D4D32C260101C01311429F8D3C2 -:1087B000C11F4D390020C8605860986070470000A4 -:1087C000D80700806C06008000B50B490B48FDF708 -:1087D000EAFB0B48006A0123DB0398430949C046C2 -:1087E00008620948C168012904D1C06F802301686B -:1087F0001943016008BC1847C1BD2140759821404C -:10880000C0001840C0001800680E008000B50F4876 -:10881000C168012904D1C06F8023016899430160B8 -:108820000B4B0C480C4A0021FDF7BFFB0B48418D58 -:10883000013141850021C1850948006A0123DB031C -:1088400018430849C046086208BC1847680E0080F3 -:1088500059BD214075982140B80B000000000080F0 -:10886000C0001840C0001800F0B51B4C1026E0688E -:10887000012808D16088002805D12079002802D17C -:108880001920A06700E0A667002007235B02E51817 -:10889000C143E86169625908A1277F0379600F210C -:1088A0007960E11DB93108710120B8604002B860FB -:1088B00000F04CFA00F0F0FA0420B860072078616C -:1088C0007E601B23DB01E018C08B04231840E862A4 -:1088D000F0BC08BC18470000680E008090B4021C71 -:1088E0000020FF2301339A4208D0012900D1012042 -:1088F000002A01D10223184390BC70471B4AD76855 -:108900001A4B19791C1C37239B01E318012F0DD139 -:108910005788002F0AD100290AD1598B0A0900D3A0 -:1089200002204909E8D301231843E5E7002903D0D1 -:10893000988A8007800FDFE76D235B01D1188A8852 -:10894000FF27013717400A49C98803D04B0A01D3D2 -:108950000320D1E7130A03D30B0A01D30220CBE78C -:10896000D209C9D3C909C7D30120C5E7680E008061 -:10897000081C0080F0B5C1B0012000075249C04674 -:10898000086052484269400DA1214903486050489F -:10899000C06A504B1843002103031B0B4E4C276F3A -:1089A0003D032D0BE71D7937AB421CD0E31D793316 -:1089B0001B6AC046409301239B0703431B68CC00FE -:1089C0006E46335101239B07061D33431B686C44DD -:1089D000636008300131409B834200D83F48030365 -:1089E0001B0BAB42E7D1002001231B0313403C4C7F -:1089F00003D0636A0133636209E0130B03D3236A74 -:108A00000133236203E0374B5C6D01345C65002960 -:108A100009D0031CDC00231C6B445C680130230D6F -:108A200001D28842F5D1304C25686B0C05D2236801 -:108A30001B0C08D12468A30A05D320242B4BC04665 -:108A40005C6200245C62254B234C5126B6032367ED -:108A500033613D6AC04675610225A12676037560C3 -:108A60000125B560E61DB9363571884221D0251C37 -:108A7000C3006C46E4582E6F6B4434605B682C6F07 -:108A8000C04663602B6F08332B673C6AA34202D356 -:108A9000124BC0462B67031CDB006B445C68013043 -:108AA000230D04D35124A4032B6FC046A361884235 -:108AB000DED1100B03D30E490120FDF774FA41B04B -:108AC000F0BC08BC18470000000000B000011440D2 -:108AD0000040144000002040680E008024A7204081 -:108AE000A42A0080A082204000001040C00018008E -:108AF000C94FFFFFF0B40021002307220624474F8F -:108B0000C0463C613A610133202BF9D304253D6115 -:108B100005233B613C613A613C613A613D613B61E7 -:108B20003F4DAB6FDE0802231E40042333433B61FD -:108B3000052333433B61AB6F9E0802231E40042391 -:108B400033433B61052333433B61AB6F5E08022334 -:108B50001E40042333433B61052333433B6102231F -:108B6000AE6F1E40042333433B61052333433B6117 -:108B7000AB6F5D0002231D4004232B433B610523A3 -:108B80002B433B61C50802231D4004232B433B615B -:108B900005232B433B61850802231D4004232B43FF -:108BA0003B6105232B433B61450802231D40042301 -:108BB0002B433B6105232B433B61022505400423E6 -:108BC0002B433B6105232B433B61400002231840AC -:108BD000042303433B6105231843386100253D61AD -:108BE00001233B613D613B6100203D610D4B1B69F1 -:108BF00049001E1C02233340194301233B6101300D -:108C00001028F2D302203861032038613C613A61B8 -:108C10003C613A6138614808F0BC7047800014003C -:108C2000680E008080001440F0B40024072306275B -:108C3000444AC046176113610134202CF9D304263D -:108C4000166105241461176107231361166114610D -:108C5000176113613C4B9B6FDD0802231D402B1CE9 -:108C60003343136125431561374B9B6F9D080223E6 -:108C70001D402B1C3343136125431561324B9B6F01 -:108C80005D0802231D402B1C3343136125431561EE -:108C90002D4B9D6F02231D402B1C33431361254335 -:108CA0001561294B9B6F5D0002231D402B1C334334 -:108CB000136125431561C50802231D402B1C334356 -:108CC000136125431561850802231D402B1C334386 -:108CD000136125431561450802231D402B1C3343B6 -:108CE000136125431561022505402B1C3343136195 -:108CF00025431561400002231840031C33431361D0 -:108D000020431061176107231361166114614C0041 -:108D100000200F21251CCD4002231D4004232B439E -:108D2000136105232B431361013001391028F1D35E -:108D30001761072313611761136103201061F0BCF1 -:108D40007047000080001400680E0080F0B54F4DA1 -:108D5000082102202A1CFDF727F94D4C71235B01E5 -:108D6000E71838801A2102202A1CFDF71DF97880A7 -:108D7000207900280BD000203880E068012810D12D -:108D80004448006801239B02184399020860E06888 -:108D9000012806D16088002803D1F9211220FFF7AD -:108DA00043FF0121C9030020FFF73EFF00257D2678 -:108DB000F60000E001350020FFF79CFE000C01D317 -:108DC000B542F7D3002505E0032109030020FFF792 -:108DD0002BFF01350020FFF78DFE400B01D2B5427D -:108DE000F2D30420FFF786FEFF23E13398430121ED -:108DF00001433888FF230133984203D12F235B01BD -:108E0000194316E0012809D17888012803D12323CA -:108E10005B0119430DE0202319430AE0002808D123 -:108E20007888012803D10B23DB01194301E080235B -:108E300019430420FFF7F8FE092149020020FFF73B -:108E4000F3FEE06800280CD100211B20FFF7ECFEA8 -:108E50001A20FFF74FFE0121C90301431A20FFF733 -:108E6000E3FE002703E0082F01D30F2F08D9381C99 -:108E7000FFF740FE790009191B23DB01C91888831D -:108E80000137202FEFD3F0BC08BC1847EDAF2140CD -:108E9000680E00800000104081B013480168C04691 -:108EA00000914168C04600918168C0460091C16848 -:108EB000C04600910169C04600914169C0460091D9 -:108EC0008169C0460091C169C0460091016AC046EF -:108ED0000091416AC0460091816AC0460091C06A13 -:108EE000C046009001B0704700081440F0B583B050 -:108EF000684D1B23DB01EF18F88B0422024002921D -:108F000071235B01E8180188C04601914088C04682 -:108F10000090002403E0082C01D30F2C08D9201C5A -:108F2000FFF7E8FD610049191B23DB01C91888839D -:108F30000134202CEFD3584CE069002815D0574E4F -:108F40002025013D5349E06930400BD068004018AE -:108F500037239B01C018818B281CFFF765FEE06951 -:108F6000B043E0617608002DEBD10120FFF7C2FD90 -:108F70004849C046F883F88BC20825D3CA68012A3D -:108F800013D10A79002A1FD1498800291CD10199DF -:108F9000434A002905D0012916D1518BC90813D2A3 -:108FA0000FE0518B09090FD20BE00A79002A0BD18F -:108FB0006D235B01C9188A88C988114049090907CE -:108FC00002D104239843F883F88B04210140029ACC -:108FD0001FD0B98B4A0B27D3800925D3FF230198D3 -:108FE0000133984220D000250098012800D10502C5 -:108FF0000198002802D101235B031D43A94213D02D -:109000000020291CFFF710FEBD830020C0436062D2 -:109010000AE0B88B400B07D2092149020020FFF774 -:1090200003FE09204002B883F88BC0082DD31D48E9 -:10903000C76A01980099FFF751FCC207D20F1A497D -:1090400003D00423CD6D2B4303E00423CD6D9D435A -:109050002B1CCB65830803D30223CD6D2B4303E088 -:109060000223CD6D9D432B1CCB65616A81420CD0E0 -:1090700060620E48002A03D0FF212131394303E00A -:10908000FF2321339F43391CC16203B0F0BC08BCED -:1090900018470000680E0080681C008000000080F7 -:1090A000281C008040001440A42A008040001400C6 -:1090B00090B4012220280FD243000F1C07495C18EE -:1090C00037239B01E3189F83824007235B02C91863 -:1090D000101CCA691043C86190BC7047680E0080BC -:1090E0000B4840690B49C98B04220A400A4906D043 -:1090F0000123DB0298430123CA6D1A4305E00123D3 -:10910000DB021843CA6D52085200CA65704700005E -:1091100080001440E81B0080A42A008000B584B0C1 -:10912000FFF7DEFF011C05200090002001AB188036 -:10913000043B58701B2200AB5A80D9800549C96D89 -:10914000C0460291039068460021FDF779F804B00B -:1091500008BC1847A42A00800F480168490C05D2B2 -:109160000168090C06D10068800A03D30B48006827 -:10917000000C01E00A48806C0004000C094B984286 -:1091800005D00233984202D0074B984201D101200A -:1091900070470020FCE7000000001040000018406D -:1091A00000000080049900000799000090B4012499 -:1091B000211C18480268520C06D20268120C02D117 -:1091C0000068800A00D200210906090E124F134AD6 -:1091D00002D03868000C00E0906C0004000C104BCA -:1091E000984208D00233984205D00E4B984202D0E4 -:1091F000023B98420CD1002902D0F86A000C00E032 -:10920000D06C400A00D200242006000E90BC7047AB -:109210000020FBE700001040000018400000008024 -:1092200004990000079900000C480168490C05D218 -:109230000168090C05D10068800A02D308488068DB -:1092400001E00848406C0004000C0021032803D012 -:10925000400801D301207047081CFCE700001040C3 -:109260000000184000000080F0B501271A4C256866 -:10927000FFF772FF031C194A022101261848012B2F -:109280001BD1CB041E605523036000234360066896 -:10929000552E1BD1AA26066043600368AA2B15D160 -:1092A0000923036005230F4FC0463B6003230E4F85 -:1092B000C0463B601160076808E008232360042370 -:1092C0000A4FC0463B60116006602768C0462560B3 -:1092D000381CF0BC08BC18470000204000002440A7 -:1092E0000000224000002A400000264000002840E4 -:1092F00080B5071CFFF730FF012805D11948006829 -:109300001949496B084022E018480168490C05D208 -:109310000168090C06D10068800A03D3144800686C -:10932000000C01E01348806C0004000C124BC018C4 -:1093300008280BD201A31B5C5B009F4405030703B5 -:1093400007070503032002E0012000E000200121BF -:109350003860800700D100210806000E80BC08BCE0 -:1093600018470000346E21400000114000001040FA -:109370000000184000000080FE66FFFFF0B582B0DC -:10938000071C01200190FFF7E7FE012813D1382FB9 -:1093900001D0A82F07D10026F643341CA82F02D1F4 -:1093A000301C0096351C1120000406624462856260 -:1093B0000099C046C16200210848C0460160382FAC -:1093C00001D0A82F05D101210160A82F01D10321CF -:1093D0000160019802B0F0BC08BC1847346E21400F -:1093E000704700007047000090B5071C124C2168C0 -:1093F000124881420BD00023211CE21DC13200E043 -:1094000008C19142FCD32060C820A0806772380157 -:1094100000F018F827720A48C046E060092F00DB08 -:109420000027E019017D01310175E0880130E080FD -:10943000012090BC08BC184700000080EEFFC0D09F -:109440000810000380B4084AD11D89310B7A202B03 -:1094500001D300230B72071C087A431C0B7280187F -:109460009030477280BC704700000080074901229D -:109470001204086802400120002A06D10A68120C72 -:1094800002D10968890A00D200207047000010400C -:1094900090B5071C094C381C211CFCF791FF381CA7 -:1094A00000F00EF80123D84201D1000CE080002129 -:1094B000201CFCF7C5FE90BC08BC1847C4662140C0 -:1094C000F8B5071C797A76480023764C01295DD1DE -:1094D000A288C0460092A1898A4274DAFA7A002AE8 -:1094E00015D07A6C002A12D08A4210D8009A511CEA -:1094F000A180A188C0464181786C6B4EC046F08047 -:10950000A06A5823796C59434018C11A28E0228870 -:1095100001321204120C22808A4200DB23800022D6 -:10952000002969DD5F4CA46A5E4B1D8858236B439C -:10953000E318DE1D013601239B0733431B681B061E -:1095400015D15849009A01328A808A88C0464281E2 -:1095500008880130544EC046F080582068432118D6 -:10956000381C00F039FBF0880004001495E04D4BE6 -:1095700001352D042D0C1D808D4201DB00251D8041 -:109580000132120412149142CEDC81E0E188E289BA -:10959000914218DAF97A00292FD0796C4904490CE4 -:1095A00079642AD0E289914227D8E1880131E180AB -:1095B000E188C04681810123DB03786C18433A4E71 -:1095C000C046F08000E063E0E06A796C4B00591817 -:1095D00049014018C11F5939381C00F00FFBE06ADF -:1095E000796C4A0052185201801801390904090C9B -:1095F000603800F089FBB6E74AE061880131090470 -:10960000090C6180E289914200DB63800021002A1D -:109610003EDD244CE46A234B5D886B005B195B01E3 -:10962000E318DE1D013601239B0733431B681B062D -:1096300020D11C4EF1880131F180F188C046818132 -:1096400070880123DB03013018431749C046C880E6 -:109650006800401940012118381C00F0CFFA7188C9 -:109660004A0052185201F06A801800F04DFB0E4972 -:10967000C88879E70B4B01352D042D0C5D80954290 -:1096800001DB00255D800131090409148A42C2DC36 -:109690000189013101810020C043F8BC08BC184792 -:1096A0004C2B00804C2A0080C4662140F0B4061C7C -:1096B0000123DB0333400124444F0020444A454D3D -:1096C000D11D3931002B41D0E303F31A73D0EE8959 -:1096D0009E4271D3EE88002E6DD0ED6A5E1E73003F -:1096E0009B195B01ED18AE683606360E032E02D0CC -:1096F000CE890136CE814035AD8BAD00354E766AD0 -:10970000C0467051558901355581324EF26AD218E2 -:109710009060F26AD2189063F26AD218D063F26A4B -:10972000D2181064F26AD2185064F26AD2189064A7 -:10973000F26AD218D064F0880138F080F088C04610 -:1097400088812449002839D14F8037E0002E38D94C -:10975000AB89B34230D3AB88002B2CD05389013373 -:1097600053812A1CAD6A5823013E7343ED18AE683D -:109770003606360E032E02D0CE890136CE81A86081 -:10978000956AED18A863956AED18E863956AED1877 -:109790002864956AED186864956AED18A864956A5E -:1097A000EB18D8649088013890809088C046488132 -:1097B000002803D101E004E003E01780201CF0BC86 -:1097C0007047CA890132CA81F9E70000FFFF000033 -:1097D0000C2B00804C2A008000B50021416010490C -:1097E0004A68002A10D1CA68002A04D0CA1D19325A -:1097F0001279002A08D04A69002A0BD18861486191 -:1098000000F010F808BC18474A69002A02D18861A4 -:109810004861F7E78A69C04650608861F2E7000056 -:109820006C060080B0B52A48406900284CD0082258 -:10983000C1680A400027274BD91DB931002A11D031 -:109840000422254CC0460C61244CC0464C62244C7A -:10985000C0468C62234CC046CC62234CC0460C638D -:109860004F6312E00522214CC0460C61204CC046DB -:109870004C62204CC0468C621F4CC046CC621F4CD0 -:10988000C0460C631E4CC0464C634024CC824F83C0 -:109890001C4F0021002A0CD98C0005196D6A7D40EF -:1098A000E418FF340134656201319142F4D3102988 -:1098B00007D28A00D218FF320132576201311029D3 -:1098C000F7D3114900F022F8B0BC08BC18470000DB -:1098D0006C060080ACAB20402801400001234567A6 -:1098E00089ABCDEFFEDCBA987654321020014000EF -:1098F00067452301EFCDAB8998BADCFE1032547670 -:10990000C3D2E1F03636363630802040B0B50F1C79 -:10991000154DE91DC931154C231C154A0020FCF7D3 -:1099200044FBE91DFF311E31231C0D1C114A01208F -:10993000FCF73BFB291C231C0E4A0020FCF735FBDF -:10994000391C231C0C4A0120FCF72FFB00210B487B -:10995000C21D193251710121FF3001304162081CD2 -:10996000B0BC08BC18470000ACAB20407508FFFF36 -:109970002800030040000200140007006C0600806D -:10998000F0B5374A506901239B0708301843006837 -:109990000106090E334B012949D11F68191C324BAE -:1099A0009F4204D1FFF73EFFF0BC08BC18470023DC -:1099B0009F00CC595569EF193C610133052BF7D352 -:1099C000000A0002022318435369C0469860506998 -:1099D0000823C2681340254FFA1DB932002B02D06C -:1099E0000423234C01E00523224CC046146140248B -:1099F000D48200245483204C0022002B0CD99500E3 -:109A00004619766A6640ED19FF3501356E620132FE -:109A10009A42F4D3102A07D29300DB19FF330133A3 -:109A20005C620132102AF7D3FFF770FFBCE7002118 -:109A30008F00DC595569EF197C6201310529F7D394 -:109A4000000A0002032318435169C0468860506928 -:109A50004068C04650610948FCF7A4FAA4E700003A -:109A60006C0600803080204067452301ACAB20406D -:109A700028014000200140005C5C5C5C1131FFFF6C -:109A8000F0B5071C3B483C4C08212060A180002019 -:109A90002081E18060813948C046E0603848C04696 -:109AA00020613848C04660613748C046A0613748E9 -:109AB000C046E0613648C04620623648C046606213 -:109AC0003548C046A0623548C046E0623448C046CA -:109AD00020633448C04660633348C046A0633348BF -:109AE000C046E0633248C04620643248C0466064E5 -:109AF0003148C046A0643148C046E0643048C046A2 -:109B000020653049C868020489694A40E31D7933F9 -:109B10000904C943C0434840E11DB931DA63086014 -:109B2000294D211C2B1C294A0020FCF73EFA284A0B -:109B3000E11DB53101202B1C0E1CFCF736FA244A1E -:109B40000020311C2B1CFCF730FAE11D4D312B1C81 -:109B5000204A0120FCF729FAE01D5D300168002948 -:109B6000FCD0606DC0463865206EC0467865F0BC9C -:109B700008BC1847800008008CB92040818148BD8E -:109B80007956238C930C82951D0E12CF9B3BC0E916 -:109B9000E6557C8299F67802D1D72573728C331002 -:109BA000F703F1426C9B4AA7828E23A990B1828E63 -:109BB000DC3FFB2900622245882BF1851261D173BD -:109BC0006EB11116088320407508FFFF5400030092 -:109BD000080002001400030080B50F1C391C00F0BF -:109BE00033F8381CFFF74CFF03480189013101812C -:109BF00080BC08BC184700000C2B008090B5041CEA -:109C00000F1C201C391C00F01FF8E068010EFF2219 -:109C100012040240120A1143FF22120202401202F1 -:109C200011430006084338652069C04678656069BD -:109C3000C046B865034801890131018190BC08BC68 -:109C4000184700000C2B008090B5002293001F18CD -:109C5000BF695B185F620132052AF7D3077AFB08F8 -:109C600003D30023920052181362076BC0468F6320 -:109C7000C76AC046CF63876BC0460F64476BC04658 -:109C80004F64076CC0468F64C26BC046CA64C2880A -:109C9000C0460A80827A1206037A1B041A43C388DC -:109CA0001B021A43437ADB071A438A60171C837A24 -:109CB0005A0805D314221C1CA30802D2152200E066 -:109CC0000022007A430810D3C00802D38820104332 -:109CD00001E0802010433A0A120201231A43C860AF -:109CE0008A60081CFFF778FD05E0380A00020323AC -:109CF00018438860CA60034801890131018190BC22 -:109D000008BC18470C2B0080F0B4026D144C151CD5 -:109D1000E769BD40131C266AF3405D402E1C456D6B -:109D2000BD406E402B1C351CFD402F1CBB00656ADE -:109D3000EB58002B08D0236901379F4200D300273E -:109D4000BE00AE59002EF7D1A469A2401143054BC5 -:109D50001943BA00A95040308783F0BC7047000017 -:109D60004C2A00800000008080B4002200230029DB -:109D700005D907787A40013001338B42F9D3D043BB -:109D80000006000E80BC7047F0B5071C0024FF26BB -:109D90000936201C00F09AF800F0B8F9051C00F014 -:109DA000C7FA3D70281C01370134B442F1D3F0BC2E -:109DB00008BC184780B500F093F800F0A7F9071C1D -:109DC00000F0B6FA380AF6D380BC08BC1847F3B5E1 -:109DD00082B002984102532000F064F800F0A8FA23 -:109DE000FFF7E8FF0024002001902E2000900025BE -:109DF00000270298012804D10098844201D300264C -:109E000009E00198411C019100F060F800F07EF932 -:109E1000061C00F08DFAF800864035430134013706 -:109E2000042FE6D3039920C10391FF2309339C42F9 -:109E3000DDD304B0F0BC08BC1847F0B5041C0F1CFF -:109E4000012C2AD01648C06F4023016819430160D5 -:109E5000002620CFB100842000F024F8281C00F058 -:109E6000DFF9280A00F0DCF9280C00F0D9F9280EF7 -:109E700000F0D6F900F05CFA0136422EE9D3610217 -:109E8000832000F00FF800F053FAFFF793FF044827 -:109E9000C06F4023016899430160F0BC08BC1847BB -:109EA000680E008090B5041C0F1C00F059FA201CAD -:109EB00000F0B6F9380C00F0B3F9380A00F0B0F948 -:109EC000381C00F0ADF990BC08BC184700B5011C67 -:109ED0005420FFF7E7FF002000F0A2F908BC184764 -:109EE00000B500F03DFA572000F09AF908BC184779 -:109EF00090B5084FFA6F202314689C431460231C0C -:109F0000FFF765FFF86F202301681943016090BCDB -:109F100008BC1847680E008090B5084FFA6F2023E0 -:109F200014689C431460231CFFF787FFF86F2023FD -:109F300001681943016090BC08BC1847680E008096 -:109F4000F0B5041C0F1C184EF06F202301689943D4 -:109F5000016061025320FFF7A5FF00F0E9F9FFF768 -:109F600029FFF81D0530012C03D1222F01D3002732 -:109F70000FE0441CFFF7AAFF00F0C8F8071C00F030 -:109F8000D7F9201CFFF7A2FF00F0C0F8051C00F075 -:109F9000CFF9F06F2023016819430160280238438C -:109FA000F0BC08BC18470000680E0080F0B5C2B0D5 -:109FB000141C0D1C071C012F2FD07902194EF06FB5 -:109FC000202302689A4302605320FFF76BFF00F0E2 -:109FD000AFF9FFF7EFFE6846FFF7D6FE6A46E81DC9 -:109FE00005301454210A68444170684600990C30C9 -:109FF000FFF7BAFE02AB18700020587068460C21BB -:10A00000FFF7B2FE02AB58706946381CFFF715FF28 -:10A01000F06F202301681943016042B0F0BC08BC16 -:10A0200018470000680E0080FFB5C2B0071C012F62 -:10A0300001D1012036E06B460020C44310C301303B -:10A040004228FBD368460C30031C0024002A0AD99E -:10A050000E88C04606700E883612467002300231F5 -:10A0600002349442F4D30092181C111CFFF77CFEBA -:10A07000041C0020019002AB1C7058709D70684653 -:10A080000C21FFF771FE02AB5870459B1D062D0E8B -:10A09000AC4203D16946381CFFF73EFF0120AC42B9 -:10A0A00000D1002046B0F0BC08BC1847B0B5C2B023 -:10A0B0000F1C4102144CE06F202302689A43026097 -:10A0C0005320FFF7EFFE00F033F9FFF773FE684609 -:10A0D000FFF75AFEE06F20230168194302AD0160CB -:10A0E0006D78002402AB5C7068460C21FFF73CFEE3 -:10A0F000A84202D10098874201D3201C00E0012031 -:10A1000042B0B0BC08BC1847680E0080FC466047EF -:10A110000000A0E3B4229FE5B4329FE50110A0E364 -:10A12000001082E5001082E50010A0E3001082E537 -:10A13000001082E5001093E5810380E10110A0E3A7 -:10A14000001082E5001082E50010A0E3001082E517 -:10A15000001082E5001093E5010380E10110A0E307 -:10A16000001082E5001082E50010A0E3001082E5F7 -:10A17000001082E5001093E5810280E10110A0E368 -:10A18000001082E5001082E50010A0E3001082E5D7 -:10A19000001082E5001093E5010280E10110A0E3C8 -:10A1A000001082E5001082E50010A0E3001082E5B7 -:10A1B000001082E5001093E5810180E10110A0E329 -:10A1C000001082E5001082E50010A0E3001082E597 -:10A1D000001082E5001093E5010180E10110A0E389 -:10A1E000001082E5001082E50010A0E3001082E577 -:10A1F000001082E5001093E5810080E10110A0E3EA -:10A20000001082E5001082E50010A0E3001082E556 -:10A21000001082E5001093E5010080E11EFF2FE1B0 -:10A22000FC466047A4219FE5A8319FE5A013A0E16B -:10A23000001083E50110A0E3001082E5001082E524 -:10A240000010A0E3001082E5001082E52013A0E1D9 -:10A25000001083E50110A0E3001082E5001082E504 -:10A260000010A0E3001082E5001082E5A012A0E13A -:10A27000001083E50110A0E3001082E5001082E5E4 -:10A280000010A0E3001082E5001082E52012A0E19A -:10A29000001083E50110A0E3001082E5001082E5C4 -:10A2A0000010A0E3001082E5001082E5A011A0E1FB -:10A2B000001083E50110A0E3001082E5001082E5A4 -:10A2C0000010A0E3001082E5001082E52011A0E15B -:10A2D000001083E50110A0E3001082E5001082E584 -:10A2E0000010A0E3001082E5001082E5A010A0E1BC -:10A2F000001083E50110A0E3001082E5001082E564 -:10A300000010A0E3001082E5001082E50010A0E13B -:10A31000001083E50110A0E3001082E5001082E543 -:10A320000010A0E3001082E5001082E51EFF2FE17F -:10A33000FC466047A0309FE50110A0E3001083E5D4 -:10A34000001083E5001083E5001083E5001083E52D -:10A35000001083E5001083E5001083E51EFF2FE168 -:10A36000FC46604770309FE50010A0E3001083E5D5 -:10A37000001083E5001083E5001083E5001083E5FD -:10A38000001083E5001083E5001083E51EFF2FE138 -:10A39000FC46604734209FE53C309FE50010A0E379 -:10A3A000001082E5001082E50110A0E3001083E5B3 -:10A3B000001083E5001083E5001083E5001083E5BD -:10A3C000001083E5001083E5001083E51EFF2FE1F8 -:10A3D000F80018400401184000011840FC00184023 -:10A3E00080B500F00CF80027381C00F047F8781C06 -:10A3F00007043F0C0C2FF7DD80BC08BC18471D4834 -:10A4000002681D498B69D218026002668A6A436835 -:10A410009B184360934202D2826801328260C26814 -:10A420000B6AD218C2604269CB68D2184261C26915 -:10A430008B68D218C26102690B69D2180261826905 -:10A440000B68D2188261026BCB69D21802634A6A28 -:10A45000436B9B184363934202D2826B0132826347 -:10A46000C26B4B69D218C263026CC96A511801648D -:10A4700070470000A42A00800008144088B569468F -:10A4800000F017F881080AD00020002907D900221F -:10A490008300009FC046FA5001308842F8D388BC40 -:10A4A00008BC184700B500F004F80004000C08BC14 -:10A4B0001847002200280AD001280AD002280CD010 -:10A4C000032802D107481C220860101C7047064868 -:10A4D00004E0064850220860F7E705486822086053 -:10A4E000F3E7000008832040A42A00800C2B0080A2 -:10A4F000A082204080B40322C280154AC0468260F8 -:10A50000144A12880132C2600020134A135CC0460C -:10A510000B70013001310828F8D320220A70013174 -:10A5200000200E4B1F5CC0460F700130013108281F -:10A53000F8D30A7001310020094A135CC0460B7041 -:10A54000013001310828F8D30020087080BC704722 -:10A5500008100003680E00807C04008085040080E1 -:10A560008E04008000B501230A48C11D89314B705B -:10A5700000220A7064218030C182018343837D21DF -:10A58000C9008183C28304480122002100F08EFBB0 -:10A5900008BC1847680E0080B522FFFF00B5FFF722 -:10A5A000E1FF13480222002100F080FB0123D84282 -:10A5B0000AD11048C11D3931CA880132CA80817957 -:10A5C00001318171FDF770F90B48C068012805D190 -:10A5D0000A487D22D200002100F068FB0848FBF702 -:10A5E000E1FC08482822002100F060FB08BC184765 -:10A5F0007921FFFFA0822040680E0080A57B2140CA -:10A60000952CFFFF5903FFFF00B510200F49C046EE -:10A6100008600F4A0F486421FBF7C6FC0E48012270 -:10A62000120401680A400821002A05D10268120CB0 -:10A6300007D10068800A04D30848C046C16008BC3E -:10A6400018470748C0460164F9E70000000000B061 -:10A65000A555FFFF7C290080000010404001180034 -:10A6600000000080F8B527480122120401680A4062 -:10A670000721002A05D10268120C06D10068800A61 -:10A6800003D32148C046C16002E02048C0460164AF -:10A690001F48FBF787FC1F48C16BFF29FCD1816B6A -:10A6A000426B161C0F1C1C4C102360691843606120 -:10A6B000A16999431D04A161E860A069C0462861B1 -:10A6C000164A17496420FBF76FFC164AC0460092F1 -:10A6D000154B0020391C321CFBF76EFC1348C16877 -:10A6E0000829FCD11248FBF75DFC102360699843F0 -:10A6F0006061E8600120E3231B01E118C871F8BC28 -:10A7000008BC1847000010404001180000000080FD -:10A710000402FFFF00011840680E00802055FFFF73 -:10A72000B5B621406400300244802040400118400A -:10A73000F401FFFF00B5FDF701FF0648FBF732FC0F -:10A74000FDF7D6FEFEF704F8FEF716F8FEF724F83C -:10A7500008BC18479103FFFF90B5FDF76BFC344F21 -:10A760000024F968F81D793001290FD13149C0461C -:10A77000F9673149C04601603049C0460C604C6001 -:10A780008C60CC600C614C618C6104E0F91D7D3102 -:10A79000F96712C008380068602301681943016036 -:10A7A000F86F2023016819430160F86F40230168A6 -:10A7B0009943016000F054F8FDF74EFC00F05EF99B -:10A7C000FDF773F8FFF70CFEFDF72EFEFDF7B6FD63 -:10A7D000FDF7C2FEFDF754FDFDF70AFDFDF794FD00 -:10A7E00000F01AFAFDF79CFFFDF70AFFFDF7D2FE15 -:10A7F000FDF73CFCFBF7DCFAFFF79CFF71235B01E4 -:10A80000F8180472447207235B02F8180463F868AE -:10A81000012802D1A820FEF7B1FD0948C0464462D4 -:10A8200000F018FA0748FBF7BDFB90BC08BC1847BE -:10A83000680E008000011140040111400001110068 -:10A84000C0001800158F214000B50448FBF7AAFB93 -:10A85000FDF75EFFFDF724FC08BC18471599214061 -:10A86000FA210348C046416240214162704700001E -:10A87000C000180007484169074B194341618269CC -:10A880009A43826101221205D1608069C04610613D -:10A8900070470000680E0080FEAF9A1000B50248B5 -:10A8A000FBF780FB08BC1847C857FFFFF0B5244CE6 -:10A8B00001210904206801400920224E224D00296F -:10A8C00005D12168090C04D12168890A01D3F060FF -:10A8D00000E028641D48FBF765FB1D4F1D49886992 -:10A8E00001308861387A002802D1787A00281FD098 -:10A8F0001948FBF757FB1948FBF754FB0028FAD11E -:10A90000387A002802D01648FBF74CFB01210904D5 -:10A91000206801401420002905D12168090C04D1C8 -:10A920002168890A01D3F06001E02864FFE7FEE7AF -:10A93000FFF765FD0B48FBF735FBFFF7AFFFCDE7F2 -:10A940000000104040011800000000800402FFFFDA -:10A95000881C008008832040F401FFFFB507FFFF3B -:10A960000000FFFF999F21400020074A01210905AF -:10A970005061C860D061C8610323DB04034A012130 -:10A98000D1635860FCE70000680E0080C00018002A -:10A9900080B5C0B0012200210A20FCF7D1FF071CBE -:10A9A000FF2F28D06946FF22381C0132FDF754F9E9 -:10A9B000FF23013398421BD10D98000918D3381C8E -:10A9C000FDF78DF80E4901221204086802400D4877 -:10A9D00005D10A68120C06D10968890A03D30A490D -:10A9E000C046C86002E00949C0460864FFF7BCFFE2 -:10A9F000381CFDF774F840B080BC08BC1847000054 -:10AA00000000104007800000400118000000008096 -:10AA100000B5174901221204086802400620002AE6 -:10AA200005D10A68120C06D10968890A03D31149B5 -:10AA3000C046C86002E01049C04608640320FEF723 -:10AA4000D3FCFBF70DFF01231843FBF7E7FFFFF7EC -:10AA500083FEFFF79DFFFFF705FEFFF7F5FEFFF70B -:10AA600009FFFFF79BFDFFF721FF08BC1847000017 -:10AA7000000010404001180000000080F0B4464A79 -:10AA80000121C903454D1923DB01EC18A161288878 -:10AA90004004434BC018871A0420AF60414EC046A3 -:10AAA000B0610820C8234343BB4221D941003D4E39 -:10AAB000C0463161B66920239B1B3A4EC046F36104 -:10AAC000103B33628B00FF1A4008814217D3B82332 -:10AAD0004343BB4208D9411E324BC0469981D981BC -:10AAE0004000023858610AE001308142EFD206E0AE -:10AAF0002C4EB3690133B36140008842D2D92A4950 -:10AB00000020A3699B0807D0284B8700CB51A76979 -:10AB1000BF0801308742F8D82249C0468A628C8932 -:10AB200058206043871800200022002C0ADD58239B -:10AB300043438C6AE31801300004000C9A608B894F -:10AB40008342F4DCCF62CC89600000194001C71950 -:10AB50000020002C0BDD43001B185B01CC6AE318BE -:10AB600001300004000C9A60CB898342F3DC4F6211 -:10AB700000200B69002B07D987004B6AC046DA51C9 -:10AB80000B6901308342F7D8496A800008180438FD -:10AB90002861F0BC70470000B0BE2140680E008004 -:10ABA000000020404C2A00800000204000ADDE0064 -:10ABB0000A4801231B06416999431A094161D16082 -:10ABC0000021A122520391611B23DB01C018816186 -:10ABD000012000065905086070470000680E0080DB -:10ABE00080B4021C0B481B23DB01C3189A610123AC -:10ABF0001B0642691A43426187699F4301231B0573 -:10AC00008761DA608069C0461861A12040038161D4 -:10AC100080BC7047680E008080B5FFF7C9FF002038 -:10AC200000F020F800200949002203015F183323B7 -:10AC30009B01FB189A6201300B28F6D304480122CD -:10AC4000002100F033F880BC08BC1847680E008073 -:10AC50001D3EFFFF00B5024800F004F808BC18478D -:10AC6000A861000080B4012212050F4BA121490305 -:10AC700000280ED0C861181C59695301194341615D -:10AC800087699F438761D1608069C046106180BC3D -:10AC90007047181C5F6901235B069F434761D760BB -:10ACA0000020C861F3E70000680E0080B0B4071C04 -:10ACB0000020174C03011D1933239B01EB189D6ADB -:10ACC000BD4205D11D6B954202D1DB6A8B421CD07F -:10ACD00001300B28EED3002003011D1933239B0103 -:10ACE000EB189B6A002B09D103011C1933239B012C -:10ACF000E3181A63D9625A639F6202E001300B289D -:10AD0000EAD30B2801D10020C043B0BC704700003B -:10AD1000680E008090B4011C00220120164F01E053 -:10AD2000002A07D10301DC1933239B01E3189B6937 -:10AD30008B4211D10201D21933239B01D218936A9D -:10AD4000C0469361D36AC046D361136BC046136299 -:10AD5000536BC0465362012201300B28E0D3074BEE -:10AD6000002A02D19A688A4203D10021996090BCDE -:10AD700070470020C043FAE7680E0080E81B00809F -:10AD80000B2817DA0C4901235B068A691343012259 -:10AD900012058B6113610001401833239B01C01819 -:10ADA000036BC0464363530188699843886110610F -:10ADB000012070470020FCE7680E008090B4084A2C -:10ADC000D0690021074FD369834202D9FC1A2018A9 -:10ADD00000E0C01A0918181CB942F4D990BC704799 -:10ADE00000201440A861000090B5071C0024002F2B -:10ADF00004D3FFF7E3FF0134BC42FAD990BC08BC8E -:04AE000018470000EF -:00000001FF -/* ver 03.001.008 */ -/* - * Copyright 1999-2004 3Com Corporation. All Rights Reserved. - * - * Redistribution and use in source and binary forms of the 3c990img.h - * microcode software are permitted provided that the following conditions - * are met: - * 1. Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of 3Com may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY 3COM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h - * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY - * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS - * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) - * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN - * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE - */ diff --git a/firmware/Makefile b/firmware/Makefile index fa3e81c2a97b269f2065a45b8045d4944427c1d1..fa0808853883e3715ec413a54602f37ae3432121 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -9,144 +9,6 @@ fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) fw-external-y := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE)) -# There are three cases to care about: -# 1. Building kernel with CONFIG_FIRMWARE_IN_KERNEL=y -- $(fw-shipped-y) should -# include the firmware files to include, according to .config -# 2. 'make modules_install', which will install firmware for modules, and -# _also_ for the in-kernel drivers when CONFIG_FIRMWARE_IN_KERNEL=n -# 3. 'make firmware_install', which installs all firmware, unconditionally. - -# For the former two cases we want $(fw-shipped-y) and $(fw-shipped-m) to be -# accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). -# But be aware that the config file might not be included at all. - -ifdef CONFIG_ACENIC_OMIT_TIGON_I -acenic-objs := acenic/tg2.bin -fw-shipped- += acenic/tg1.bin -else -acenic-objs := acenic/tg1.bin acenic/tg2.bin -endif -fw-shipped-$(CONFIG_ACENIC) += $(acenic-objs) -fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ - adaptec/starfire_tx.bin -fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin -fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.9.0.fw \ - bnx2x/bnx2x-e1h-6.2.9.0.fw \ - bnx2x/bnx2x-e2-6.2.9.0.fw -fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \ - bnx2/bnx2-rv2p-09-6.0.17.fw \ - bnx2/bnx2-rv2p-09ax-6.0.17.fw \ - bnx2/bnx2-mips-06-6.2.1.fw \ - bnx2/bnx2-rv2p-06-6.0.15.fw -fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin -fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ - cxgb3/t3c_psram-1.1.0.bin \ - cxgb3/ael2005_opt_edc.bin \ - cxgb3/ael2005_twx_edc.bin \ - cxgb3/ael2020_twx_edc.bin -fw-shipped-$(CONFIG_DRM_MGA) += matrox/g200_warp.fw matrox/g400_warp.fw -fw-shipped-$(CONFIG_DRM_R128) += r128/r128_cce.bin -fw-shipped-$(CONFIG_DRM_RADEON) += radeon/R100_cp.bin radeon/R200_cp.bin \ - radeon/R300_cp.bin radeon/R420_cp.bin \ - radeon/RS690_cp.bin radeon/RS600_cp.bin \ - radeon/R520_cp.bin \ - radeon/R600_pfp.bin radeon/R600_me.bin \ - radeon/RV610_pfp.bin radeon/RV610_me.bin \ - radeon/RV630_pfp.bin radeon/RV630_me.bin \ - radeon/RV620_pfp.bin radeon/RV620_me.bin \ - radeon/RV635_pfp.bin radeon/RV635_me.bin \ - radeon/RV670_pfp.bin radeon/RV670_me.bin \ - radeon/RS780_pfp.bin radeon/RS780_me.bin \ - radeon/RV770_pfp.bin radeon/RV770_me.bin \ - radeon/RV730_pfp.bin radeon/RV730_me.bin \ - radeon/RV710_pfp.bin radeon/RV710_me.bin -fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin -fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin -fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ - e100/d102e_ucode.bin -fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin -fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \ - cis/DP83903.cis cis/NE2K.cis \ - cis/tamarack.cis cis/PE-200.cis \ - cis/PE520.cis -fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis -fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis -fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \ - cis/COMpad2.cis cis/COMpad4.cis \ - cis/SW_555_SER.cis cis/SW_7xx_SER.cis \ - cis/SW_8xx_SER.cis -fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin -fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ - advansys/3550.bin advansys/38C0800.bin -fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ - qlogic/12160.bin -fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin -fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw -fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp -fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ - ess/maestro3_assp_minisrc.fw -fw-shipped-$(CONFIG_SND_SB16_CSP) += sb16/mulaw_main.csp sb16/alaw_main.csp \ - sb16/ima_adpcm_init.csp \ - sb16/ima_adpcm_playback.csp \ - sb16/ima_adpcm_capture.csp -fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ - yamaha/ds1e_ctrl.fw -fw-shipped-$(CONFIG_SND_WAVEFRONT) += yamaha/yss225_registers.bin -fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin -fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \ - tigon/tg3_tso5.bin -fw-shipped-$(CONFIG_TYPHOON) += 3com/typhoon.bin -fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ - emi26/bitstream.fw -fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \ - emi62/spdif.fw emi62/midi.fw -fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ - kaweth/new_code_fix.bin \ - kaweth/trigger_code_fix.bin -ifdef CONFIG_FIRMWARE_IN_KERNEL -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19) += keyspan/usa19.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QI) += keyspan/usa19qi.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QW) += keyspan/usa19qw.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19W) += keyspan/usa19w.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28) += keyspan/usa28.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XA) += keyspan/usa28xa.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XB) += keyspan/usa28xb.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw -else -fw-shipped- += keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ - keyspan/usa19qi.fw keyspan/usa19qw.fw keyspan/usa19w.fw \ - keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ - keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw -endif -fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw \ - mts_cdma.fw mts_gsm.fw mts_edge.fw -fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \ - edgeport/down.fw edgeport/down2.fw -fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += edgeport/down3.bin -fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ - # whiteheat_loader_debug.fw -fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw -fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw -fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw -fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin -fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin - -fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) - -quiet_cmd_ihex = IHEX $@ - cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@ - -quiet_cmd_ihex2fw = IHEX2FW $@ - cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ - -quiet_cmd_h16tofw = H16TOFW $@ - cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@ - quiet_cmd_fwbin = MK_FW $@ cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ @@ -179,46 +41,14 @@ wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \ include/config/x86_32.h include/config/x86_64.h \ firmware/Makefile) -$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) - $(call cmd,fwbin,$(patsubst %.gen.S,%,$@)) $(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \ include/config/extra/firmware/dir.h $(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@)) # The .o files depend on the binaries directly; the .S files don't. -$(patsubst %,$(obj)/%.gen.o, $(fw-shipped-y)): %.gen.o: % $(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/% -# .ihex is used just as a simple way to hold binary files in a source tree -# where binaries are frowned upon. They are directly converted with objcopy. -$(obj)/%: $(obj)/%.ihex - $(call cmd,ihex) - -# Don't depend on ihex2fw if we're installing and it already exists. -# Putting it after | in the dependencies doesn't seem sufficient when -# we're installing after a cross-compile, because ihex2fw has dependencies -# on stuff like /usr/lib/gcc/ppc64-redhat-linux/4.3.0/include/stddef.h and -# thus wants to be rebuilt. Which it can't be, if the prebuilt kernel tree -# is exported read-only for someone to run 'make install'. -ifeq ($(INSTALL):$(wildcard $(obj)/ihex2fw),install:$(obj)/ihex2fw) -ihex2fw_dep := -else -ihex2fw_dep := $(obj)/ihex2fw -endif - -# .HEX is also Intel HEX, but where the offset and length in each record -# is actually meaningful, because the firmware has to be loaded in a certain -# order rather than as a single binary blob. Thus, we convert them into our -# more compact binary representation of ihex records () -$(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep) - $(call cmd,ihex2fw) - -# .H16 is our own modified form of Intel HEX, with 16-bit length for records. -$(obj)/%.fw: $(obj)/%.H16 $(ihex2fw_dep) - $(call cmd,h16tofw) - obj-y += $(patsubst %,%.gen.o, $(fw-external-y)) -obj-$(CONFIG_FIRMWARE_IN_KERNEL) += $(patsubst %,%.gen.o, $(fw-shipped-y)) ifeq ($(KBUILD_SRC),) # Makefile.build only creates subdirectories for O= builds, but external @@ -226,13 +56,8 @@ ifeq ($(KBUILD_SRC),) _dummy := $(foreach d,$(addprefix $(obj)/,$(dir $(fw-external-y))), $(shell [ -d $(d) ] || mkdir -p $(d))) endif -# Remove .S files and binaries created from ihex -# (during 'make clean' .config isn't included so they're all in $(fw-shipped-)) -targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \ - $(shell find $(obj) -name \*.gen.S 2>/dev/null)) - +targets := $(patsubst $(obj)/%,%, \ + $(shell find $(obj) -name \*.gen.S 2>/dev/null)) # Without this, built-in.o won't be created when it's empty, and the # final vmlinux link will fail. obj- := dummy - -hostprogs-y := ihex2fw diff --git a/firmware/README.AddingFirmware b/firmware/README.AddingFirmware deleted file mode 100644 index bcb5f46aff832ed16e72478cb7bab61e7c932561..0000000000000000000000000000000000000000 --- a/firmware/README.AddingFirmware +++ /dev/null @@ -1,45 +0,0 @@ - - DO NOT ADD FIRMWARE TO THIS DIRECTORY. - ====================================== - -This directory is only here to contain firmware images extracted from old -device drivers which predate the common use of request_firmware(). - -As we update those drivers to use request_firmware() and keep a clean -separation between code and firmware, we put the extracted firmware -here. - -This directory is _NOT_ for adding arbitrary new firmware images. The -place to add those is the separate linux-firmware repository: - - git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git - -That repository contains all these firmware images which have been -extracted from older drivers, as well various new firmware images which -we were never permitted to include in a GPL'd work, but which we _have_ -been permitted to redistribute under separate cover. - -To submit firmware to that repository, please send either a git binary -diff or preferably a git pull request to: - linux-firmware@kernel.org -and also cc: to related mailing lists. - -Your commit should include an update to the WHENCE file clearly -identifying the licence under which the firmware is available, and -that it is redistributable. If the licence is long and involved, it's -permitted to include it in a separate file and refer to it from the -WHENCE file. -And if it were possible, a changelog of the firmware itself. - -Ideally, your commit should contain a Signed-Off-By: from someone -authoritative on the licensing of the firmware in question (i.e. from -within the company that owns the code). - - -WARNING: -======= - -Don't send any "CONFIDENTIALITY STATEMENT" in your e-mail, patch or -request. Otherwise your firmware _will never be accepted_. - -Maintainers are really busy, so don't expect a prompt reply. diff --git a/firmware/WHENCE b/firmware/WHENCE deleted file mode 100644 index de6f22e008f1fbe428282e4e157378d9a6132fd3..0000000000000000000000000000000000000000 --- a/firmware/WHENCE +++ /dev/null @@ -1,854 +0,0 @@ - ********** - * WHENCE * - ********** - -This file attempts to document the origin and licensing information, -if known, for each piece of firmware distributed for use with the Linux -kernel. - --------------------------------------------------------------------------- - -Driver: ambassador -- Madge Ambassador (Collage PCI 155 Server) ATM NIC. - -File: firmware/atmsar11.fw - -Licence: Allegedly GPLv2+, but no source visible. Marked: - - Madge Ambassador ATM Adapter microcode. - Copyright (C) 1995-1999 Madge Networks Ltd. - - This microcode data is placed under the terms of the GNU General - Public License. The GPL is contained in /usr/doc/copyright/GPL on a - Debian system and in the file COPYING in the Linux kernel source. - - We would prefer you not to distribute modified versions without - consultation and not to ask for assembly/other microcode source. - --------------------------------------------------------------------------- - -Driver: korg1212 -- Korg 1212 IO audio device - -File: korg/k1212.dsp - -Licence: Unknown - -Found in alsa-firmware package in hex form; no licensing information. - --------------------------------------------------------------------------- - -Driver: maestro3 -- ESS Allegro Maestro3 audio device - -File: ess/maestro3_assp_kernel.fw -File: ess/maestro3_assp_minisrc.fw - -Licence: Unknown - -Found in alsa-firmware package in hex form with a comment claiming to -be GPLv2+, but without source -- and with another comment saying "ESS -drops binary dsp code images on our heads, but we don't get to see -specs on the dsp." - --------------------------------------------------------------------------- - -Driver: ymfpci -- Yamaha YMF724/740/744/754 audio devices - -File: yamaha/ds1_ctrl.fw -File: yamaha/ds1_dsp.fw -File: yamaha/ds1e_ctrl.fw - -Licence: Unknown - -Found alsa-firmware package in hex form, with the following comment: - Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved. - --------------------------------------------------------------------------- - -Driver: SCSI_ADVANSYS - AdvanSys SCSI - -File: advansys/mcode.bin -File: advansys/3550.bin -File: advansys/38C0800.bin -File: advansys/38C1600.bin - -Licence: BSD, no source available. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: SCSI_QLOGIC_1280 - Qlogic QLA 1240/1x80/1x160 SCSI support - -File: qlogic/1040.bin -File: qlogic/1280.bin -File: qlogic/12160.bin - -Licence: Allegedly GPLv2+, but no source visible. Marked: - - QLOGIC LINUX SOFTWARE - QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x - Copyright (C) 2001 Qlogic Corporation (www.qlogic.com) - --------------------------------------------------------------------------- - -Driver: kaweth -- USB KLSI KL5USB101-based Ethernet device - -File: kaweth/new_code.bin -File: kaweth/new_code_fix.bin -File: kaweth/trigger_code.bin -File: kaweth/trigger_code_fix.bin - -Licence: Unknown - -Found in hex form in the kernel source. - --------------------------------------------------------------------------- - -Driver: ttusb-budget -- Technotrend/Hauppauge Nova-USB devices - -File: ttusb-budget/dspbootcode.bin - -Licence: Unknown - -Found in hex form in the kernel source. - --------------------------------------------------------------------------- - -Driver: keyspan -- USB Keyspan USA-xxx serial device - -File: keyspan/mpr.fw -File: keyspan/usa18x.fw -File: keyspan/usa19.fw -File: keyspan/usa19qi.fw -File: keyspan/usa19qw.fw -File: keyspan/usa19w.fw -File: keyspan/usa28.fw -File: keyspan/usa28xa.fw -File: keyspan/usa28xb.fw -File: keyspan/usa28x.fw -File: keyspan/usa49w.fw -File: keyspan/usa49wlc.fw - -Converted from Intel HEX files, used in our binary representation of ihex. - -Original licence information: - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - --------------------------------------------------------------------------- - -Driver: keyspan_pda -- USB Keyspan PDA single-port serial device - -File: keyspan_pda/keyspan_pda.fw -Source: keyspan_pda/keyspan_pda.S - -File: keyspan_pda/xircom_pgs.fw -Source: keyspan_pda/xircom_pgs.S - -Licence: GPLv2+ - -Compiled from original 8051 source into Intel HEX, used in our binary ihex form. - --------------------------------------------------------------------------- - -Driver: emi26 -- EMI 2|6 USB Audio interface - -File: emi26/bitstream.fw -Info: VERSION=1.1.1.131 DATE=2001dec06 - -File: emi26/firmware.fw -Info: VERSION=1.0.2.916 DATE=12.02.2002 - -File: emi26/loader.fw - -Converted from Intel HEX files, used in our binary representation of ihex. - -Original licence information: -/* - * This firmware is for the Emagic EMI 2|6 Audio Interface - * - * The firmware contained herein is Copyright (c) 1999-2002 Emagic - * as an unpublished work. This notice does not imply unrestricted - * or public access to this firmware which is a trade secret of Emagic, - * and which may not be reproduced, used, sold or transferred to - * any third party without Emagic's written consent. All Rights Reserved. - * - * Permission is hereby granted for the distribution of this firmware - * image as part of a Linux or other Open Source operating system kernel - * in text or binary form as required. - * - * This firmware may not be modified and may only be used with the - * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of - * any driver which includes this firmware, in whole or in part, - * requires the inclusion of this statement. - */ - --------------------------------------------------------------------------- - -Driver: emi62 -- EMI 6|2m USB Audio interface - -File: emi62/bitstream.fw -Info: VERSION=1.0.0.191 DATE= 2002oct28 - -File: emi62/loader.fw -Source: EMILOAD.HEX -Info: VERSION=1.0.2.002 DATE=10.01.2002 - -File: emi62/midi.fw -Source: EMI62MFW.HEX -Info: VERSION=1.04.062 DATE=16.10.2002 - -File: emi62/spdif.fw -Source: EMI62SFW.HEX -Info: VERSION=1.04.062 DATE=16.10.2002 - -Converted from Intel HEX files, used in our binary representation of ihex. - -Original licence information: None - --------------------------------------------------------------------------- - -Driver: ti_usb_3410_5052 -- USB TI 3410/5052 serial device - -File: ti_3410.fw -Info: firmware 9/10/04 FW3410_Special_StartWdogOnStartPort - -File: ti_5052.fw -Info: firmware 9/18/04 - -Licence: Allegedly GPLv2+, but no source visible. Marked: - Copyright (C) 2004 Texas Instruments - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: ti_usb_3410_5052 -- Multi-Tech USB cell modems - -File: mts_cdma.fw -File: mts_gsm.fw -File: mts_edge.fw - -Licence: "all firmware components are redistributable in binary form" - per support@multitech.com - Copyright (C) 2005 Multi-Tech Systems, Inc. - -Found in hex form in ftp://ftp.multitech.com/wireless/wireless_linux.zip - --------------------------------------------------------------------------- - -Driver: whiteheat -- USB ConnectTech WhiteHEAT serial device - -File: whiteheat.fw -Version: 4.06 - -File: whiteheat_loader.fw -File: whiteheat_loader_debug.fw - -Licence: Allegedly GPLv2, but no source visible. Marked: - Copyright (C) 2000-2002 ConnectTech Inc - -Debug loader claims the following behaviour: - Port 1 LED flashes when the vend_ax program is running - Port 2 LED flashes when any SETUP command arrives - Port 3 LED flashes when any valid VENDOR request occurs - Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs - -Converted from Intel HEX files, used in our binary representation of ihex. - --------------------------------------------------------------------------- - -Driver: CPiA2 -- cameras based on Vision's CPiA2 - -File: cpia2/stv0672_vp4.bin - -Licence: Allegedly GPLv2+, but no source visible. Marked: - Copyright (C) 2001 STMicroelectronics, Inc. - Contact: steve.miller@st.com - Description: This file contains patch data for the CPiA2 (stv0672) VP4. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: DABUSB -- Digital Audio Broadcasting (DAB) Receiver for USB and Linux - -File: dabusb/firmware.fw -File: dabusb/bitstream.bin - -Licence: Distributable - - * Copyright (C) 1999 BayCom GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that redistributions of source - * code retain the above copyright notice and this comment without - * modification. - --------------------------------------------------------------------------- - -Driver: USB_VICAM -- USB 3com HomeConnect (aka vicam) - -File: vicam/firmware.fw - -Licence: Unknown - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: USB_SERIAL_EDGEPORT - USB Inside Out Edgeport Serial Driver - -File: edgeport/boot.fw -File: edgeport/boot2.fw -File: edgeport/down.fw -File: edgeport/down2.fw - -Licence: Allegedly GPLv2+, but no source visible. Marked: -//************************************************************** -//* Edgeport/4 Binary Image -//* Generated by HEX2C v1.06 -//* Copyright (C) 1998 Inside Out Networks, All rights reserved. -//************************************************************** - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: USB_SERIAL_EDGEPORT_TI - USB Inside Out Edgeport Serial Driver -(TI Devices) - -File: edgeport/down3.bin - -Licence: -//************************************************************** -//* Edgeport Binary Image (for TI based products) -//* Generated by TIBin2C v2.00 (watchport) -//* Copyright (C) 2001 Inside Out Networks, All rights reserved. -//************************************************************** - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: ATARI_DSP56K - Atari DSP56k support - -File: dsp56k/bootstrap.bin -Source: dsp56k/bootstrap.asm - -Licence: GPLv2 or later - -DSP56001 assembler, possibly buildable with a56 from -http://www.zdomain.com/a56.html - --------------------------------------------------------------------------- - -Driver: SND_SB16_CSP - Sound Blaster 16/AWE CSP support - -File: sb16/mulaw_main.csp -File: sb16/alaw_main.csp -File: sb16/ima_adpcm_init.csp -File: sb16/ima_adpcm_playback.csp -File: sb16/ima_adpcm_capture.csp - -Licence: Allegedly GPLv2+, but no source visible. Marked: -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - */ - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: CASSINI - Sun Cassini - -File: sun/cassini.bin - -Licence: Unknown - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter - -File: cxgb3/t3b_psram-1.1.0.bin.ihex -File: cxgb3/t3c_psram-1.1.0.bin.ihex -file: cxgb3/t3fw-7.4.0.bin.ihex - -License: GPLv2 or OpenIB.org BSD license, no source visible - --------------------------------------------------------------------------- - -Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter - -File: cxgb3/ael2005_opt_edc.bin.ihex -File: cxgb3/ael2005_twx_edc.bin.ihex -File: cxgb3/ael2020_twx_edc.bin.ihex - -Licence: - * Copyright (c) 2007-2009 NetLogic Microsystems, Inc. - * - * Permission is hereby granted for the distribution of this firmware - * data in hexadecimal or equivalent format, provided this copyright - * notice is accompanying it. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: e100 -- Intel PRO/100 Ethernet NIC - -File: e100/d101m_ucode.bin -File: e100/d101s_ucode.bin -File: e100/d102e_ucode.bin - -Licence: Unknown - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: acenic -- Alteon AceNIC Gigabit Ethernet card - -File: acenic/tg1.bin -File: acenic/tg2.bin - -Licence: Unknown - -Found in hex form in kernel source, but source allegedly available at -http://alteon.shareable.org/ - --------------------------------------------------------------------------- - -Driver: tigon3 -- Broadcom Tigon3 based gigabit Ethernet cards - -File: tigon/tg3.bin -File: tigon/tg3_tso.bin -File: tigon/tg3_tso5.bin - -Licence: - * Firmware is: - * Derived from proprietary unpublished source code, - * Copyright (C) 2000-2003 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware - * data in hexadecimal or equivalent format, provided this copyright - * notice is accompanying it. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: ADAPTEC_STARFIRE - Adaptec Starfire/DuraLAN support - -File: adaptec/starfire_rx.bin -File: adaptec/starfire_tx.bin - -Licence: Allegedly GPLv2, but no source visible. - -Found in hex form in kernel source, with the following notice: - - BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE IT IS LICENSED "AS IS" AND - THERE IS NO WARRANTY FOR THE PROGRAM, INCLUDING BUT NOT LIMITED TO THE - IMPLIED WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR A PARTICULAR PURPOSE - (TO THE EXTENT PERMITTED BY APPLICABLE LAW). USE OF THE PROGRAM IS AT YOUR - OWN RISK. IN NO EVENT WILL ADAPTEC OR ITS LICENSORS BE LIABLE TO YOU FOR - DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES - ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM. - --------------------------------------------------------------------------- - -Driver: TEHUTI - Tehuti Networks 10G Ethernet - -File: tehuti/bdx.bin - -Licence: - - Copyright (C) 2007 Tehuti Networks Ltd. - - Permission is hereby granted for the distribution of this firmware data - in hexadecimal or equivalent format, provided this copyright notice is - accompanying it. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: TYPHOON - 3cr990 series Typhoon - -File: 3com/typhoon.bin - -Licence: -/* - * Copyright 1999-2004 3Com Corporation. All Rights Reserved. - * - * Redistribution and use in source and binary forms of the 3c990img.h - * microcode software are permitted provided that the following conditions - * are met: - * 1. Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of 3Com may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY 3COM ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h - * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY - * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS - * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) - * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN - * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE - */ - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: YAM - YAM driver for AX.25 - -File: yam/1200.bin -File: yam/9600.bin - -Licence: - * (C) F6FBB 1998 - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter - -File: cis/LA-PCM.cis - cis/PCMLM28.cis - cis/DP83903.cis - cis/NE2K.cis - cis/tamarack.cis - cis/PE-200.cis - cis/PE520.cis - -Licence: GPL - -Originally developed by the pcmcia-cs project - --------------------------------------------------------------------------- - -Driver: PCMCIA_3C589 - 3Com PCMCIA adapter - -File: cis/3CXEM556.cis - -Licence: GPL - -Originally developed by the pcmcia-cs project - --------------------------------------------------------------------------- - -Driver: PCMCIA_3C574 - 3Com PCMCIA adapter - -File: cis/3CCFEM556.cis - -Licence: GPL - -Originally developed by the pcmcia-cs project - --------------------------------------------------------------------------- - -Driver: SERIAL_8250_CS - Serial PCMCIA adapter - -File: cis/MT5634ZLX.cis - cis/RS-COM-2P.cis - cis/COMpad2.cis - cis/COMpad4.cis - cis/SW_555_SER.cis - cis/SW_7xx_SER.cis - cis/SW_8xx_SER.cis - -Licence: GPL - -Originally developed by the pcmcia-cs project - --------------------------------------------------------------------------- - -Driver: PCMCIA_SMC91C92 - SMC 91Cxx PCMCIA - -File: ositech/Xilinx7OD.bin - -Licence: Allegedly GPL, but no source visible. Marked: - This file contains the firmware of Seven of Diamonds from OSITECH. - (Special thanks to Kevin MacPherson of OSITECH) - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: SCSI_QLOGICPTI - PTI Qlogic, ISP Driver - -File: qlogic/isp1000.bin - -Licence: Unknown - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: MYRI_SBUS - MyriCOM Gigabit Ethernet - -File: myricom/lanai.bin - -Licence: Unknown - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: bnx2x: Broadcom Everest - -File: bnx2x/bnx2x-e1-6.2.9.0.fw -File: bnx2x/bnx2x-e1h-6.2.9.0.fw -File: bnx2x/bnx2x-e2-6.2.9.0.fw - -License: - Copyright (c) 2007-2011 Broadcom Corporation - - This file contains firmware data derived from proprietary unpublished - source code, Copyright (c) 2007-2011 Broadcom Corporation. - - Permission is hereby granted for the distribution of this firmware data - in hexadecimal or equivalent format, provided this copyright notice is - accompanying it. - - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: BNX2 - Broadcom NetXtremeII - -File: bnx2/bnx2-mips-06-6.2.1.fw -File: bnx2/bnx2-rv2p-06-6.0.15.fw -File: bnx2/bnx2-mips-09-6.2.1a.fw -File: bnx2/bnx2-rv2p-09-6.0.17.fw -File: bnx2/bnx2-rv2p-09ax-6.0.17.fw - -Licence: - - This file contains firmware data derived from proprietary unpublished - source code, Copyright (c) 2004 - 2010 Broadcom Corporation. - - Permission is hereby granted for the distribution of this firmware data - in hexadecimal or equivalent format, provided this copyright notice is - accompanying it. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: DVB AV7110 -- AV7110 cards - -File: av7110/bootcode.bin - -Licence: GPLv2 or later - -ARM assembly source code available at https://linuxtv.org/downloads/firmware/Boot.S - --------------------------------------------------------------------------- - -Driver: wavefront - ISA WaveFront sound card - -File: yamaha/yss225_registers.bin - -Licence: Allegedly GPLv2+, but no source visible. - -Found in hex form in kernel source, with the following comment: - Copyright (c) 1998-2002 by Paul Davis - --------------------------------------------------------------------------- - -Driver: mga - Matrox G200/G400/G550 - -File: matrox/g200_warp.fw -File: matrox/g400_warp.fw - -Licence: - -Copyright 1999 Matrox Graphics Inc. -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: r128 - ATI Rage 128 - -File: r128/r128_cce.bin - -Licence: - -Copyright 2000 Advanced Micro Devices, Inc. - - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - -Found in decimal form in kernel source. - --------------------------------------------------------------------------- - -Driver: radeon - ATI Radeon - -File: radeon/R100_cp.bin -File: radeon/R200_cp.bin -File: radeon/R300_cp.bin -File: radeon/R420_cp.bin -File: radeon/RS600_cp.bin -File: radeon/RS690_cp.bin -File: radeon/R520_cp.bin -File: radeon/R600_pfp.bin -File: radeon/R600_me.bin -File: radeon/RV610_pfp.bin -File: radeon/RV610_me.bin -File: radeon/RV630_pfp.bin -File: radeon/RV630_me.bin -File: radeon/RV620_pfp.bin -File: radeon/RV620_me.bin -File: radeon/RV635_pfp.bin -File: radeon/RV635_me.bin -File: radeon/RV670_pfp.bin -File: radeon/RV670_me.bin -File: radeon/RS780_pfp.bin -File: radeon/RS780_me.bin -File: radeon/RV770_pfp.bin -File: radeon/RV770_me.bin -File: radeon/RV730_pfp.bin -File: radeon/RV730_me.bin -File: radeon/RV710_pfp.bin -File: radeon/RV710_me.bin - -Licence: - - * Copyright 2007-2009 Advanced Micro Devices, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - -Driver: ib_qib - QLogic Infiniband - -File: qlogic/sd7220.fw - -Licence: - - * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - -Found in hex form in kernel source. - --------------------------------------------------------------------------- diff --git a/firmware/acenic/tg1.bin.ihex b/firmware/acenic/tg1.bin.ihex deleted file mode 100644 index bef2659d36454b873161e63381b983dfa54201f4..0000000000000000000000000000000000000000 --- a/firmware/acenic/tg1.bin.ihex +++ /dev/null @@ -1,4573 +0,0 @@ -:100000000C040B0000004000000040001000000342 -:10001000000000000000000D0000000D3C1D00016C -:100020008FBD5C5403A0F0213C100000261040005E -:100030000C00100C000000000000000D27BDFFD8D0 -:100040003C1CC0003C1B0013377BD8000000D021B3 -:100050003C17001336F7541802E02021340583E8DA -:10006000AFBF00240C002488AFB000200C0023E8B0 -:10007000000000003C040001248451A42405000178 -:1000800002E03021000038213C10000126107E5093 -:10009000AFB000100C002403AFBB00143C02000FF3 -:1000A0003442FFFF020210240362102B10400009AB -:1000B000240500033C040001248451B002003021D7 -:1000C000036038213C020010AFA200100C00240392 -:1000D000AFA00014000020213405C0003C01000145 -:1000E00000370821A02083B03C010001003708211F -:1000F000A02083B23C01000100370821A02083B377 -:100100003C01000100370821AC2083B4A2E004D8F0 -:10011000000418C02484000100771021AC40727CD8 -:1001200000771021AC40728002E31021A445727C5C -:100130002C8200201440FFF7000418C0000020218A -:100140003405C000000418C0248400010077102189 -:10015000AC40737C00771021AC40738002E3102127 -:10016000A445737C2C8200805440FFF7000418C023 -:10017000AF800054AF80011C8F82004434420040A5 -:10018000AF8200448F82004434420020AF8200449A -:100190008F420218304200021040000900000000A7 -:1001A0008F4202203C030002346300040043102508 -:1001B000AEE204C48F42021C0800107434420004F2 -:1001C0008F4202203C0300023463000600431025E6 -:1001D000AEE204C48F42021C34420006AEE204CCFC -:1001E0008F420218304200101040000A0000000048 -:1001F0008F42021C34420004AEE204C88F42022047 -:100200003C03000A34630004004310250800108AF0 -:10021000AEE204C08F4202203C03000A34630006B1 -:1002200000431025AEE204C08F42021C3442000697 -:10023000AEE204C88F4202183042020010400003B0 -:100240002402000108001091A2E27248A2E0724864 -:1002500024020001AF8200A0AF8200B08F8300545F -:100260008F82005408001099246300648F82005428 -:10027000006210232C4200651440FFFC00000000C7 -:10028000AF8000448F4202088F43020CAEE20010A0 -:10029000AEE300148EE400108EE5001426E2003078 -:1002A000AEE2002824020490AEE20018AF84009071 -:1002B000AF8500948EE20028AF8200B496E2001A67 -:1002C000AF82009C8F8200B08EE304CC00431025E7 -:1002D000AF8200B08F8200B0304200041440FFFDB6 -:1002E000000000008EE204508EE30454AEE304FCF0 -:1002F0008EE204FC2442E0002C4220011440000D58 -:1003000026E400308EE204508EE304543C040001E5 -:10031000248451BC3C050001AFA00010AFA0001424 -:100320008EE704FC34A5F0000C00240300603021AB -:1003300026E400300C0024882405040027440080B3 -:100340000C0024882405008026E4777C0C00248897 -:10035000240504008F42025C26E40094AEE20060B3 -:100360008F4202602745020024060008AEE20068C2 -:10037000240200060C00249AAEE200643C023B9A80 -:100380003442CA000000202124030002AEE30074BE -:10039000AEE30070AEE2006C240203E8AEE20104BA -:1003A00024020001AEE30100AEE2010C3C030001B7 -:1003B0000064182190635C2002E410212484000171 -:1003C000A043009C2C82000F1440FFF800000000A6 -:1003D0008F82004002E418212484000100021702E9 -:1003E00024420030A062009C02E41021A040009C46 -:1003F00096E2046A30420003144000090000000045 -:1004000096E2047A30420003504001313C03080078 -:1004100096E2046A304200031040002A3C020700C2 -:1004200096E2047A30420003104000263C020700A6 -:1004300096E3047A96E2046A146200223C02070002 -:100440008EE204C024030001A2E34E2034420E00D9 -:10045000AEE204C08F420218304201001040000595 -:10046000000000003C0200012442E1680800111D68 -:10047000000211003C0200012442D35C0002110082 -:10048000000211823C030800004310253C010001DA -:10049000AC2212383C0200012442F6800002110016 -:1004A000000211823C030800004310253C010001BA -:1004B000AC2212788EE2000034424000080012386C -:1004C000AEE2000034423000AFA200188EE206080F -:1004D0008F43022824420001304900FF512300E2EB -:1004E000AFA000108EE20608000210C000571021D5 -:1004F0008FA300188FA4001CAC43060CAC4406105C -:100500008F8701202762380024E800200102102B89 -:1005100050400001276830008F820128110200043A -:10052000000000008F820124150200070000102146 -:100530008EE201A40000302124420001AEE201A4B9 -:10054000080011A08EE201A48EE40608000420C079 -:10055000008018218EE404308EE5043400A32821A5 -:1005600000A3302B0082202100862021ACE4000073 -:10057000ACE500048EE3060824020008A4E2000EA5 -:100580002402000DACE20018ACE9001C000318C006 -:100590002463060C02E31021ACE200088EE204C4DE -:1005A000ACE20010AF88012092E24E2014400037E8 -:1005B000240600018EE24E30000210C02442503862 -:1005C00002E220218C830000240200071462001F35 -:1005D000000000008EE34E308EE24E341062001BAD -:1005E000240300408C82000424420001AC820004F9 -:1005F0008EE24E348EE54E30244200011043000757 -:10060000000000008EE24E342442000110A20005DA -:10061000000000000800118A0000000014A000057E -:10062000000000008F82012824420020AF820128B0 -:100630008F8201288C8200042C420011504000134C -:10064000AC800000080011A0000000008EE24E30D7 -:100650002403004024420001504300030000102105 -:100660008EE24E3024420001AEE24E308EE24E3039 -:10067000000210C02442503802E220212402000768 -:10068000AC82000024020001AC82000454C0000CC3 -:10069000AEE906083C040001248451C8AFA0001054 -:1006A000AFA000148EE606088F4702283C0500091B -:1006B0000C00240334A5F000080012230000000001 -:1006C0008F830120276238002466002000C2102B8F -:1006D00050400001276630008F82012810C20004BC -:1006E000000000008F82012414C2000700000000F7 -:1006F0008EE201A40000302124420001AEE201A4F8 -:10070000080012078EE201A48EE20608AC62001C0B -:100710008EE404A08EE504A42462001CAC620008F0 -:1007200024020008A462000E24020011AC6200182A -:10073000AC640000AC6500048EE204C4AC6200103E -:10074000AF86012092E24E201440003724060001BB -:100750008EE24E30000210C02442503802E22021C6 -:100760008C830000240200121462001F00000000AD -:100770008EE34E308EE24E341062001B24030040A4 -:100780008C82000424420001AC8200048EE24E34CC -:100790008EE54E30244200011043000700000000A7 -:1007A0008EE24E342442000110A200050000000039 -:1007B000080011F10000000014A000050000000076 -:1007C0008F82012824420020AF8201288F820128D5 -:1007D0008C8200042C42001150400013AC800000B9 -:1007E00008001207000000008EE24E302403004093 -:1007F0002442000150430003000010218EE24E30DD -:1008000024420001AEE24E308EE24E30000210C0B3 -:100810002442503802E2202124020012AC8200005F -:1008200024020001AC82000414C0001B0000000080 -:100830003C040001248451D0AFA00010AFA00014EC -:100840008EE606088F4702283C0500090C002403A9 -:1008500034A5F0018EE201B024420001AEE201B005 -:10086000080012238EE201B03C040001248451DC14 -:10087000AFA000148EE606088F4702283C05000949 -:100880000C00240334A5F0058EE201AC24420001E3 -:10089000AEE201AC8EE201AC8EE201603C040001EC -:1008A000248451E83405F00124420001AEE20160E5 -:1008B0008EE201600000302100003821AFA000105E -:1008C0000C002403AFA00014080012380000000040 -:1008D0003C0200012442F5A800021100000211822E -:1008E000004310253C010001AC22127896E2045A24 -:1008F00030420003104000253C050FFF8EE204C883 -:1009000034A5FFFF34420A00AEE204C88EE304C8F7 -:100910003C040001248451F424020001A2E204EC0E -:10092000A2E204ED3C020002006218253C02000134 -:100930002442A3900045102400021082AEE304C8B4 -:100940003C030800004310253C010001AC221220AA -:100950003C0200012442ADD4004510240002108264 -:10096000004310253C010001AC22128096E6045A97 -:100970000000382124050011AFA000100C00240352 -:10098000AFA0001408001268000000003C02000143 -:100990002442A9D400021100000211823C03080085 -:1009A000004310253C010001AC22128096E2046A4B -:1009B00030420010144000090000000096E2047A62 -:1009C00030420010104001120000000096E2046A5C -:1009D00030420010104000053C02070096E2047A05 -:1009E00030420010144001023C0207003442300043 -:1009F000AFA200188EE206088F43022824420001AD -:100A0000304900FF512300E2AFA000108EE206083B -:100A1000000210C0005710218FA300188FA4001CE3 -:100A2000AC43060CAC4406108F87012027623800C7 -:100A300024E800200102102B5040000127683000FC -:100A40008F82012811020004000000008F8201241F -:100A500015020007000010218EE201A400003021E1 -:100A600024420001AEE201A4080012EA8EE201A4D1 -:100A70008EE40608000420C0008018218EE40430B3 -:100A80008EE5043400A3282100A3302B008220210E -:100A900000862021ACE40000ACE500048EE30608EB -:100AA00024020008A4E2000E2402000DACE20018AB -:100AB000ACE9001C000318C02463060C02E31021FB -:100AC000ACE200088EE204C4ACE20010AF88012062 -:100AD00092E24E2014400037240600018EE24E3090 -:100AE000000210C02442503802E220218C83000012 -:100AF000240200071462001F000000008EE34E3045 -:100B00008EE24E341062001B240300408C820004ED -:100B100024420001AC8200048EE24E348EE54E3059 -:100B20002442000110430007000000008EE24E3412 -:100B30002442000110A2000500000000080012D4A9 -:100B40000000000014A00005000000008F820128B2 -:100B500024420020AF8201288F8201288C82000469 -:100B60002C42001150400013AC800000080012EA33 -:100B7000000000008EE24E302403004024420001B9 -:100B800050430003000010218EE24E302442000149 -:100B9000AEE24E308EE24E30000210C02442503899 -:100BA00002E2202124020007AC820000240200019E -:100BB000AC82000454C0000CAEE906083C040001FD -:100BC000248451C8AFA00010AFA000148EE6060820 -:100BD0008F4702283C0500090C00240334A5F000CF -:100BE0000800136D000000008F8301202762380089 -:100BF0002466002000C2102B504000012766300000 -:100C00008F82012810C20004000000008F8201249E -:100C100014C20007000000008EE201A40000302191 -:100C200024420001AEE201A4080013518EE201A4A7 -:100C30008EE20608AC62001C8EE404A08EE504A4DB -:100C40002462001CAC62000824020008A462000EAA -:100C500024020011AC620018AC640000AC65000412 -:100C60008EE204C4AC620010AF86012092E24E20F6 -:100C700014400037240600018EE24E30000210C0FE -:100C80002442503802E220218C830000240200120A -:100C90001462001F000000008EE34E308EE24E34DE -:100CA0001062001B240300408C82000424420001D7 -:100CB000AC8200048EE24E348EE54E3024420001B8 -:100CC00010430007000000008EE24E342442000171 -:100CD00010A20005000000000800133B0000000007 -:100CE00014A00005000000008F820128244200208B -:100CF000AF8201288F8201288C8200042C420011CF -:100D000050400013AC8000000800135100000000A8 -:100D10008EE24E3024030040244200015043000381 -:100D2000000010218EE24E3024420001AEE24E302F -:100D30008EE24E30000210C02442503802E22021E0 -:100D400024020012AC82000024020001AC820004E4 -:100D500014C0001B000000003C040001248451D09A -:100D6000AFA00010AFA000148EE606088F4702283F -:100D70003C0500090C00240334A5F0018EE201B00B -:100D800024420001AEE201B00800136D8EE201B012 -:100D90003C040001248451DCAFA000148EE6060858 -:100DA0008F4702283C0500090C00240334A5F005F8 -:100DB0008EE201AC24420001AEE201AC8EE201AC55 -:100DC0008EE201603C040001248451E83405F00205 -:100DD00024420001AEE201608EE201600000302199 -:100DE00000003821AFA000100C002403AFA00014B5 -:100DF00096E6047A96E7046A3C04000124845200D3 -:100E000024050012AFA000100C002403AFA00014B2 -:100E10000C004500000000000C002318000000003A -:100E20003C06000134C63800AEE00608AF40022898 -:100E3000AF40022C96E304588EE400003C0512D823 -:100E400034A5C35827623800AEE2725827623800D2 -:100E5000AEE2726027623800AEE27264036610216F -:100E6000AEE272702402FFFFAEE004D4AEE004E014 -:100E7000AEE004E4AEE004F0A2E004F4AEE00E0C58 -:100E8000AEE00E18AEE00E10AEE00E14AEE00E1C9A -:100E9000AEE0724CAEE05244AEE05240AEE0523CA6 -:100EA000AEE07250AEE07254AEE0725CAEE07268DA -:100EB000AEE004D02463FFFF00852025AEE304F8F4 -:100EC000AEE40000AF800060AF8200643C0201002D -:100ED000AFA200188EE206088F43022824420001C8 -:100EE000304900FF512300E2AFA000108EE2060857 -:100EF000000210C0005710218FA300188FA4001CFF -:100F0000AC43060CAC4406108F87012027623800E2 -:100F100024E800200102102B504000012768300017 -:100F20008F82012811020004000000008F8201243A -:100F300015020007000010218EE201A400003021FC -:100F400024420001AEE201A4080014228EE201A4B2 -:100F50008EE40608000420C0008018218EE40430CE -:100F60008EE5043400A3282100A3302B0082202129 -:100F700000862021ACE40000ACE500048EE3060806 -:100F800024020008A4E2000E2402000DACE20018C6 -:100F9000ACE9001C000318C02463060C02E3102116 -:100FA000ACE200088EE204C4ACE20010AF8801207D -:100FB00092E24E2014400037240600018EE24E30AB -:100FC000000210C02442503802E220218C8300002D -:100FD000240200071462001F000000008EE34E3060 -:100FE0008EE24E341062001B240300408C82000409 -:100FF00024420001AC8200048EE24E348EE54E3075 -:101000002442000110430007000000008EE24E342D -:101010002442000110A20005000000000800140C8A -:101020000000000014A00005000000008F820128CD -:1010300024420020AF8201288F8201288C82000484 -:101040002C42001150400013AC8000000800142214 -:10105000000000008EE24E302403004024420001D4 -:1010600050430003000010218EE24E302442000164 -:10107000AEE24E308EE24E30000210C024425038B4 -:1010800002E2202124020007AC82000024020001B9 -:10109000AC82000454C0000CAEE906083C04000118 -:1010A000248451C8AFA00010AFA000148EE606083B -:1010B0008F4702283C0500090C00240334A5F000EA -:1010C000080014A5000000008F830120276238006B -:1010D0002466002000C2102B50400001276630001B -:1010E0008F82012810C20004000000008F820124BA -:1010F00014C20007000000008EE201A400003021AD -:1011000024420001AEE201A4080014898EE201A489 -:101110008EE20608AC62001C8EE404A08EE504A4F6 -:101120002462001CAC62000824020008A462000EC5 -:1011300024020011AC620018AC640000AC6500042D -:101140008EE204C4AC620010AF86012092E24E2011 -:1011500014400037240600018EE24E30000210C019 -:101160002442503802E220218C8300002402001225 -:101170001462001F000000008EE34E308EE24E34F9 -:101180001062001B240300408C82000424420001F2 -:10119000AC8200048EE24E348EE54E3024420001D3 -:1011A00010430007000000008EE24E34244200018C -:1011B00010A20005000000000800147300000000E9 -:1011C00014A00005000000008F82012824420020A6 -:1011D000AF8201288F8201288C8200042C420011EA -:1011E00050400013AC80000008001489000000008B -:1011F0008EE24E302403004024420001504300039D -:10120000000010218EE24E3024420001AEE24E304A -:101210008EE24E30000210C02442503802E22021FB -:1012200024020012AC82000024020001AC820004FF -:1012300014C0001B000000003C040001248451D0B5 -:10124000AFA00010AFA000148EE606088F4702285A -:101250003C0500090C00240334A5F0018EE201B026 -:1012600024420001AEE201B0080014A58EE201B0F4 -:101270003C040001248451DCAFA000148EE6060873 -:101280008F4702283C0500090C00240334A5F00513 -:101290008EE201AC24420001AEE201AC8EE201AC70 -:1012A0008EE2015424420001AEE201540C0014DC31 -:1012B0008EE201548F8200A0304200041440FFFDF2 -:1012C000000000008F8200403042000114400008FE -:1012D000000000008F43010424020001106200049A -:1012E000000000008F420264104000060000000071 -:1012F0008EE2017C24420001AEE2017C080014C5AC -:101300008EE2017C8F82004434420004AF820044AC -:101310008EE2017824420001AEE201788EE201788B -:101320008F8200D88F8300D400431023AEE2726C0A -:101330008EE2726C1C4000033C030001004310214C -:10134000AEE2726C0C004064000000000C004440EF -:10135000AF8002288FBF00248FB0002003E0000878 -:1013600027BD002803E000080000000003E000089B -:101370000000000000000000000000002402002C1B -:10138000AF820050AEE072748F420238AEE27278E3 -:101390008F82005424420067AF820058AEE07B8801 -:1013A000AEE07B8CAEE07B843C010001003708217D -:1013B000AC2083BC3C0100010037082103E0000899 -:1013C000A02083B927BDFFD8AFBF0024AFB0002055 -:1013D0008F8200543C0300018C635CD82442006778 -:1013E0001060000DAF8200583C0200010057102130 -:1013F000904283B8104000053C0302003C0100010C -:101400000037082108001503A02083B88EE20000F1 -:1014100000431025AEE200008F4202183042010066 -:10142000104000C6000000008F8200B0304200046F -:10143000104000C2000000003C03000100771821AA -:101440008C6383D08F820104146200B4000000001A -:101450003C030001007718218C6383D48F8200B491 -:10146000146200AE000000008F8200B03C030080D8 -:10147000004310241040000D000000008F82011C6A -:1014800034420002AF82011C8F8200B02403FFFBB4 -:1014900000431024AF8200B08F82011C2403FFFDA3 -:1014A00000431024080015CCAF82011C3C0300014E -:1014B000007718218C6383D08F820104146200822C -:1014C000000000003C030001007718218C6383D4E6 -:1014D0008F8200B41462007C000000003C07000111 -:1014E00000F738218CE783D08F8200B03C040001E4 -:1014F00024845270AFA00014AFA200108F8600B0F9 -:101500003C0500050C00240334A509008F82011C52 -:1015100034420002AF82011C8F8301048F8200B02D -:1015200034420001AF8200B0AF8301048F830120F9 -:10153000276238002466002000C2102B50400001B2 -:10154000276630008F82012810C2000400000000CE -:101550008F82012414C20006000000008EE201A464 -:1015600024420001AEE201A4080015A08EE201A40D -:101570008F4402088F45020C26E20030AC6200085E -:1015800024020400A462000E2402000FAC620018C2 -:10159000AC60001CAC640000AC6500048EE204C4C6 -:1015A000AC620010AF86012092E24E20144000375A -:1015B000000000008EE24E30000210C0244250387D -:1015C00002E220218C830000240200071462001F25 -:1015D000000000008EE34E308EE24E341062001B9D -:1015E000240300408C82000424420001AC820004E9 -:1015F0008EE24E348EE54E30244200011043000747 -:10160000000000008EE24E342442000110A20005CA -:10161000000000000800158A0000000014A000056A -:10162000000000008F82012824420020AF820128A0 -:101630008F8201288C8200042C420011504000133C -:10164000AC800000080015A0000000008EE24E30C3 -:1016500024030040244200015043000300001021F5 -:101660008EE24E3024420001AEE24E308EE24E3029 -:10167000000210C02442503802E220212402000758 -:10168000AC82000024020001AC8200048F82011CA5 -:101690002403FFFD00431024AF82011C8EE201E40D -:1016A0003C07000100F738218CE783D02442000179 -:1016B000AEE201E48EE201E43C0400012484527CA9 -:1016C000080015BDAFA000108F8201043C0100018D -:1016D00000370821AC2283D08F8200B43C07000180 -:1016E00000F738218CE783D03C0400012484528425 -:1016F0003C01000100370821AC2283D4AFA00010C8 -:10170000AFA000148F8600B03C0500050C00240338 -:1017100034A50900080015CC000000008F820104E8 -:101720003C01000100370821AC2283D08F8200B435 -:101730003C01000100370821AC2283D48EE2727490 -:1017400092E304F42442006714600006AEE272746F -:101750008EE272748F4302340043102B1440007BDE -:10176000000000008EE304E48EE204F8146200043A -:101770000000000092E204F450400074A2E004F47F -:101780008F830120276238002466002000C2102BBE -:1017900050400001276630008F82012810C20004EB -:1017A000000000008F82012414C200070000000026 -:1017B0008EE201A40000802124420001AEE201A4D7 -:1017C000080016378EE201A48EE204E4AC62001C2D -:1017D0008EE404B08EE504B42462001CAC62000800 -:1017E00024020008A462000E24020011AC6200185A -:1017F000AC640000AC6500048EE204C4AC6200106E -:10180000AF86012092E24E201440003724100001E0 -:101810008EE24E30000210C02442503802E22021F5 -:101820008C830000240200121462001F00000000DC -:101830008EE34E308EE24E341062001B24030040D3 -:101840008C82000424420001AC8200048EE24E34FB -:101850008EE54E30244200011043000700000000D6 -:101860008EE24E342442000110A200050000000068 -:10187000080016210000000014A000050000000070 -:101880008F82012824420020AF8201288F82012804 -:101890008C8200042C42001150400013AC800000E8 -:1018A00008001637000000008EE24E30240300408E -:1018B0002442000150430003000010218EE24E300C -:1018C00024420001AEE24E308EE24E30000210C0E3 -:1018D0002442503802E2202124020012AC8200008F -:1018E00024020001AC8200045600000B2410000109 -:1018F0008EE204E43C0400012484528CAFA0001466 -:10190000AFA200108EE606088F4702283C050009AA -:101910000C00240334A5F006160000032402000185 -:1019200008001650A2E204F48EE201702442000185 -:10193000AEE201708EE201708EE204E4A2E004F4F3 -:10194000AEE004F0AEE07274AEE204F88EE20E1C7B -:101950001040006D000000008F83012027623800D6 -:101960002466002000C2102B504000012766300082 -:101970008F82012810C20004000000008F82012421 -:1019800014C20007000000008EE201A400008021C4 -:1019900024420001AEE201A4080016AD8EE201A4CB -:1019A0008EE2724CAC62001C8EE404A88EE504AC9E -:1019B0002462001CAC62000824020008A462000E2D -:1019C00024020011AC620018AC640000AC65000495 -:1019D0008EE204C4AC620010AF86012092E24E2079 -:1019E00014400037241000018EE24E30000210C077 -:1019F0002442503802E220218C830000240200128D -:101A00001462001F000000008EE34E308EE24E3460 -:101A10001062001B240300408C8200042442000159 -:101A2000AC8200048EE24E348EE54E30244200013A -:101A300010430007000000008EE24E3424420001F3 -:101A400010A200050000000008001697000000002A -:101A500014A00005000000008F820128244200200D -:101A6000AF8201288F8201288C8200042C42001151 -:101A700050400013AC800000080016AD00000000CC -:101A80008EE24E3024030040244200015043000304 -:101A9000000010218EE24E3024420001AEE24E30B2 -:101AA0008EE24E30000210C02442503802E2202163 -:101AB00024020012AC82000024020001AC82000467 -:101AC0005600000B241000018EE2724C3C04000111 -:101AD00024845298AFA00014AFA200108EE6724C7E -:101AE0008F4702803C0500090C00240334A5F00850 -:101AF00056000001AEE00E1C8EE20174244200018B -:101B0000AEE201748EE201748EE24E2410400019A0 -:101B100000000000AEE04E248F8200403042000101 -:101B200014400008000000008F430104240200015B -:101B300010620004000000008F42026410400006A2 -:101B4000000000008EE2017C24420001AEE2017C34 -:101B5000080016DA8EE2017C8F82004434420004D1 -:101B6000AF8200448EE2017824420001AEE20178A7 -:101B70008EE201788EE272782442FF99AEE27278AA -:101B80008EE272781C4002AD000000008F420238E5 -:101B9000104002AA000000003C0200010057102182 -:101BA000904283E0144002A5000000008F420080B4 -:101BB000AEE2004C8F4200C0AEE200488F4200848B -:101BC000AEE200388F420084AEE202448F420088C9 -:101BD000AEE202488F42008CAEE2024C8F4200908F -:101BE000AEE202508F420094AEE202548F4200985F -:101BF000AEE202588F42009CAEE2025C8F4200A02F -:101C0000AEE202608F4200A4AEE202648F4200A8FE -:101C1000AEE202688F4200ACAEE2026C8F4200B0CE -:101C2000AEE202708F4200B4AEE202748F4200B89E -:101C3000AEE202788F4200BC24040001AEE2027CD6 -:101C4000AEE0003C00041080005710218EE3003C01 -:101C50008C42024424840001006218212C82000F6F -:101C6000AEE3003C1440FFF8000410808F4200CC2B -:101C7000AEE200508F4200D0AEE200548F830120CC -:101C8000276238002466002000C2102B504000015B -:101C9000276630008F82012810C200040000000077 -:101CA0008F82012414C20007000000008EE201A40C -:101CB0000000802124420001AEE201A40800177553 -:101CC0008EE201A48F4402088F45020C26E2003008 -:101CD000AC62000824020400A462000E2402000F7B -:101CE000AC620018AC60001CAC640000AC65000481 -:101CF0008EE204C4AC620010AF86012092E24E2056 -:101D000014400037241000018EE24E30000210C053 -:101D10002442503802E220218C8300002402000774 -:101D20001462001F000000008EE34E308EE24E343D -:101D30001062001B240300408C8200042442000136 -:101D4000AC8200048EE24E348EE54E302442000117 -:101D500010430007000000008EE24E3424420001D0 -:101D600010A20005000000000800175F000000003E -:101D700014A00005000000008F82012824420020EA -:101D8000AF8201288F8201288C8200042C4200112E -:101D900050400013AC8000000800177500000000E0 -:101DA0008EE24E30240300402442000150430003E1 -:101DB000000010218EE24E3024420001AEE24E308F -:101DC0008EE24E30000210C02442503802E2202140 -:101DD00024020007AC82000024020001AC8200044F -:101DE000120002123C020400AFA200183C020001E3 -:101DF00000571021904283B01040010B00000000FA -:101E00008EE206088F43022824420001304A00FF78 -:101E1000514300FDAFA000108EE20608000210C082 -:101E2000005710218FA300188FA4001CAC43060C90 -:101E3000AC4406108F8300548F8200542469003212 -:101E4000012210232C4200331040006A0000582168 -:101E500024180008240F000D240D0007240C004056 -:101E6000240E00018F8701202762380024E800201B -:101E70000102102B50400001276830008F8201289A -:101E800011020004000000008F82012415020007E7 -:101E9000000010218EE201A40000802124420001F4 -:101EA000AEE201A4080017F38EE201A48EE4060856 -:101EB000000420C0008018218EE404308EE5043434 -:101EC00000A3282100A3302B00822021008620219E -:101ED000ACE40000ACE500048EE20608A4F8000EB5 -:101EE000ACEF0018ACEA001C000210C02442060C43 -:101EF00002E21021ACE200088EE204C4ACE2001061 -:101F0000AF88012092E24E201440003324100001DB -:101F10008EE24E30000210C02442503802E22021EE -:101F20008C820000144D001F000000008EE34E3034 -:101F30008EE24E341062001B000000008C82000410 -:101F400024420001AC8200048EE24E348EE34E3017 -:101F500024420001104C0007000000008EE24E34C5 -:101F6000244200011062000500000000080017E094 -:101F70000000000014600005000000008F820128AE -:101F800024420020AF8201288F8201288C82000425 -:101F90002C42001150400010AC800000080017F3E4 -:101FA000000000008EE24E3024420001504C00033D -:101FB000000010218EE24E3024420001AEE24E308D -:101FC0008EE24E30000210C02442503802E220213E -:101FD000AC8D0000AC8E000456000006240B0001FE -:101FE0008F820054012210232C4200331440FF9DA5 -:101FF00000000000316300FF24020001146200773A -:102000003C050009AEEA06088F8300548F82005415 -:1020100024690032012210232C4200331040006159 -:1020200000005821240D0008240C0011240800127F -:1020300024070040240A00018F8301202762380012 -:102040002466002000C2102B50400001276630009B -:102050008F82012810C20004000000008F8201243A -:1020600014C20007000000008EE201A400008021DD -:1020700024420001AEE201A40800185F8EE201A430 -:102080008EE20608AC62001C8EE404A08EE504A477 -:102090002462001CAC620008A46D000EAC6C001839 -:1020A000AC640000AC6500048EE204C4AC620010B5 -:1020B000AF86012092E24E2014400033241000012C -:1020C0008EE24E30000210C02442503802E220213D -:1020D0008C8200001448001F000000008EE34E3088 -:1020E0008EE24E341062001B000000008C8200045F -:1020F00024420001AC8200048EE24E348EE34E3066 -:102100002442000110470007000000008EE24E3418 -:102110002442000110620005000000000800184C75 -:102120000000000014600005000000008F820128FC -:1021300024420020AF8201288F8201288C82000473 -:102140002C42001150400010AC8000000800185FC5 -:10215000000000008EE24E30244200015047000390 -:10216000000010218EE24E3024420001AEE24E30DB -:102170008EE24E30000210C02442503802E220218C -:10218000AC880000AC8A000456000006240B000155 -:102190008F820054012210232C4200331440FFA6EA -:1021A00000000000316300FF2402000114620003FC -:1021B0003C0500090800197C241000013C040001C2 -:1021C000248452A4AFA00010AFA000148F86012079 -:1021D0008F8701240800187B34A5F0113C0400010E -:1021E000248452B0AFA00010AFA000148F8601204D -:1021F0008F87012434A5F0100C00240300008021F7 -:102200000800197C000000003C040001248452BC3A -:10221000AFA000148EE606088F4702283C0500098F -:102220000800197534A5F00F8EE206088F430228C6 -:1022300024420001304900FF512300E2AFA000100A -:102240008EE20608000210C0005710218FA300186C -:102250008FA4001CAC43060CAC4406108F870120F1 -:102260002762380024E800200102102B50400001B2 -:10227000276830008F82012811020004000000004E -:102280008F82012415020007000010218EE201A4B4 -:102290000000802124420001AEE201A4080018F7EA -:1022A0008EE201A48EE40608000420C000801821FC -:1022B0008EE404308EE5043400A3282100A3302BE3 -:1022C0000082202100862021ACE40000ACE500045F -:1022D0008EE3060824020008A4E2000E2402000D8A -:1022E000ACE20018ACE9001C000318C02463060C23 -:1022F00002E31021ACE200088EE204C4ACE200105C -:10230000AF88012092E24E201440003724100001D3 -:102310008EE24E30000210C02442503802E22021EA -:102320008C830000240200071462001F00000000DC -:102330008EE34E308EE24E341062001B24030040C8 -:102340008C82000424420001AC8200048EE24E34F0 -:102350008EE54E30244200011043000700000000CB -:102360008EE24E342442000110A20005000000005D -:10237000080018E10000000014A0000500000000A3 -:102380008F82012824420020AF8201288F820128F9 -:102390008C8200042C42001150400013AC800000DD -:1023A000080018F7000000008EE24E3024030040C1 -:1023B0002442000150430003000010218EE24E3001 -:1023C00024420001AEE24E308EE24E30000210C0D8 -:1023D0002442503802E2202124020007AC8200008F -:1023E00024020001AC8200045600000CAEE906088D -:1023F0003C040001248452C8AFA00010AFA0001418 -:102400008EE606088F4702283C0500090C002403CD -:1024100034A5F0000800197C000000008F83012023 -:10242000276238002466002000C2102B50400001B3 -:10243000276630008F82012810C2000400000000CF -:102440008F82012414C20007000000008EE201A464 -:102450000000802124420001AEE201A40800195EC0 -:102460008EE201A48EE20608AC62001C8EE404A099 -:102470008EE504A42462001CAC620008240200085B -:10248000A462000E24020011AC620018AC640000CB -:10249000AC6500048EE204C4AC620010AF8601207B -:1024A00092E24E2014400037241000018EE24E309C -:1024B000000210C02442503802E220218C83000028 -:1024C000240200121462001F000000008EE34E3050 -:1024D0008EE24E341062001B240300408C82000404 -:1024E00024420001AC8200048EE24E348EE54E3070 -:1024F0002442000110430007000000008EE24E3429 -:102500002442000110A20005000000000800194844 -:102510000000000014A00005000000008F820128C8 -:1025200024420020AF8201288F8201288C8200047F -:102530002C42001150400013AC8000000800195ECE -:10254000000000008EE24E302403004024420001CF -:1025500050430003000010218EE24E30244200015F -:10256000AEE24E308EE24E30000210C024425038AF -:1025700002E2202124020012AC82000024020001A9 -:10258000AC8200045600001D241000013C04000130 -:10259000248452D0AFA00010AFA000148EE606082D -:1025A0008F4702283C0500090C00240334A5F001E4 -:1025B0008EE201B024420001AEE201B00800197CB5 -:1025C0008EE201B03C040001248452DCAFA0001470 -:1025D0008EE606088F4702283C05000934A5F00561 -:1025E0000C002403000000008EE201AC00008021FA -:1025F00024420001AEE201AC8EE201AC1200000CFC -:10260000240200013C01000100370821A02083B012 -:102610008F4202388EE3015824630001AEE3015873 -:102620008EE301580800198CAEE272782402000192 -:102630003C01000100370821A02283B03C020001C8 -:102640008C425CD810400187000000008EE27B8441 -:1026500024430001284200C9144001A4AEE37B8456 -:102660008EE204D43042000214400119AEE07B84B3 -:102670008EE204D43C0306003463100034420002AE -:10268000AEE204D4AFA300188EE206088F430228FE -:1026900024420001304A00FF514300FDAFA000106A -:1026A0008EE20608000210C0005710218FA3001808 -:1026B0008FA4001CAC43060CAC4406108F8300545E -:1026C0008F82005424690032012210232C420033EF -:1026D0001040006A0000582124180008240F000D43 -:1026E000240D0007240C0040240E00018F870120D8 -:1026F0002762380024E800200102102B504000011E -:10270000276830008F8201281102000400000000B9 -:102710008F82012415020007000010218EE201A41F -:102720000000802124420001AEE201A408001A1535 -:102730008EE201A48EE40608000420C00080182167 -:102740008EE404308EE5043400A3282100A3302B4E -:102750000082202100862021ACE40000ACE50004CA -:102760008EE20608A4F8000EACEF0018ACEA001CDC -:10277000000210C02442060C02E21021ACE2000864 -:102780008EE204C4ACE20010AF88012092E24E2039 -:1027900014400033241000018EE24E30000210C0BD -:1027A0002442503802E220218C820000144D001F88 -:1027B000000000008EE34E308EE24E341062001BAB -:1027C000000000008C82000424420001AC8200045E -:1027D0008EE24E348EE34E3024420001104C00074E -:1027E000000000008EE24E34244200011062000519 -:1027F0000000000008001A0200000000146000053C -:10280000000000008F82012824420020AF820128AE -:102810008F8201288C8200042C420011504000104D -:10282000AC80000008001A15000000008EE24E3057 -:1028300024420001504C0003000010218EE24E3073 -:1028400024420001AEE24E308EE24E30000210C053 -:102850002442503802E22021AC8D0000AC8E0004EE -:1028600056000006240B00018F8200540122102321 -:102870002C4200331440FF9D00000000316300FF34 -:102880002402000154620078AFA00010AEEA0608EE -:102890008F8300548F820054246900320122102358 -:1028A0002C4200331040006100005821240D000824 -:1028B000240C00112408001224070040240A0001FF -:1028C0008F830120276238002466002000C2102B6D -:1028D00050400001276630008F82012810C200049A -:1028E000000000008F82012414C2000700000000D5 -:1028F0008EE201A40000802124420001AEE201A486 -:1029000008001A818EE201A48EE20608AC62001C67 -:102910008EE404A08EE504A42462001CAC620008CE -:10292000A46D000EAC6C0018AC640000AC65000433 -:102930008EE204C4AC620010AF86012092E24E2009 -:1029400014400033241000018EE24E30000210C00B -:102950002442503802E220218C8200001448001FDB -:10296000000000008EE34E308EE24E341062001BF9 -:10297000000000008C82000424420001AC820004AC -:102980008EE24E348EE34E302442000110470007A1 -:10299000000000008EE24E34244200011062000567 -:1029A0000000000008001A6E00000000146000051E -:1029B000000000008F82012824420020AF820128FD -:1029C0008F8201288C8200042C420011504000109C -:1029D000AC80000008001A81000000008EE24E303A -:1029E0002442000150470003000010218EE24E30C7 -:1029F00024420001AEE24E308EE24E30000210C0A2 -:102A00002442503802E22021AC880000AC8A000445 -:102A100056000006240B00018F820054012210236F -:102A20002C4200331440FFA600000000316300FF79 -:102A30002402000110620022000000003C0400019A -:102A4000248452A4AFA00010AFA000148F860120F0 -:102A50008F8701243C0500090C00240334A5F011E4 -:102A600008001AAD000000003C040001248452B0AC -:102A7000AFA000148F8601208F8701243C05000938 -:102A80000C00240334A5F01008001AAD000000006B -:102A90003C040001248452BCAFA000148EE606085A -:102AA0008F4702283C0500090C00240334A5F00FD1 -:102AB0008EE201AC24420001AEE201AC8EE201AC38 -:102AC0008EE2015C24420001AEE2015C8EE2015C18 -:102AD0008EE204D430420001104000550000000096 -:102AE0008F42021830420080104000290000000090 -:102AF0008F82004434420040AF8200448EE27B7CEF -:102B0000004028218EE200C08EE300C424060000AD -:102B10002407FFFF00002021004610241444000D6C -:102B2000006718241465000B000000008EE27B8013 -:102B3000004028218EE200E08EE300E40000202126 -:102B40000046102414440003006718241065000B8D -:102B5000000000008EE200C08EE300C48EE400E0BE -:102B60008EE500E4AEE37B7CAEE57B808F820044A3 -:102B70003842002008001B38AF8200448F82004496 -:102B80002403FFDF0043102408001B38AF820044F9 -:102B90008F8200442403FFDF00431024AF820044EF -:102BA0008EE27B7C004028218EE200C08EE300C4D0 -:102BB000240600002407FFFF000020210046102407 -:102BC0001444000D006718241465000B0000000079 -:102BD0008EE27B80004028218EE200E08EE300E45C -:102BE000000020210046102414440003006718242C -:102BF0001065000B000000008EE200C08EE300C4F0 -:102C00008EE400E08EE500E4AEE37B7CAEE57B8005 -:102C10008F8200443842004008001B38AF820044D5 -:102C20008F8200443442004008001B38AF820044C9 -:102C30008F82004434420040AF8200448EE27B8C9D -:102C4000244300012842001514400028AEE37B8C89 -:102C50008F82004438420020AF82004408001B38B5 -:102C6000AEE07B8C8EE204D43042000110400011B3 -:102C7000000000008F42021830420080104000091E -:102C8000000000008F82004434420020AF820044E4 -:102C90008F8200442403FFBF0043102408001B362A -:102CA000AF8200448F8200443442006008001B362B -:102CB000AF8200448F82004434420040AF8200441F -:102CC0008EE27B88244300012842138914400005CA -:102CD000AEE37B888F82004438420020AF820044FC -:102CE000AEE07B880C004603000000008FBF00248C -:102CF0008FB0002003E0000827BD002827BDFFB8E3 -:102D0000AFBF0044AFB60040AFB5003CAFB4003831 -:102D1000AFB30034AFB20030AFB1002CAFB0002879 -:102D20008F96006432C200041040000C240200049C -:102D3000AF8200648F420114AEE204E08F82006033 -:102D400034420008AF8200608EE2016C2442000130 -:102D5000AEE2016C080022F48EE2016C32C2000186 -:102D60001040000424020001AF820064080022F435 -:102D70000000000032C200021440000C3C050003B9 -:102D80003C0400012484535434A5000102C03021C6 -:102D900000003821AFA000100C002403AFA00014E5 -:102DA0002402FFF8080022F4AF8200648F43022C53 -:102DB0008F42010C5062000CAFA000108F42022C19 -:102DC00000021080005A10218C420300AFA20020A4 -:102DD0008F42022C24070001244200013042003FB0 -:102DE00008001B80AF42022C3C0400012484536085 -:102DF000AFA000148F46022C8F47010C3C05000346 -:102E00000C00240334A5F01F0000382114E0000357 -:102E100000000000080022EDAF96006493A200209D -:102E20002443FFFF2C62001110400658000310805D -:102E30003C010001002208218C22541800400008A7 -:102E4000000000008FA2002030420FFFAEE20E0C07 -:102E50008F82006034420200AF8200608EE201186F -:102E600024420001AEE20118080022E88EE20118B7 -:102E70008FA20020240300013C010001003708213B -:102E8000A02383B130420FFFAEE252388F82006040 -:102E900034420100AF8200608EE20144244200010E -:102EA000AEE20144080022E88EE201448FA2002035 -:102EB0000002120000022502240200011082000517 -:102EC00024020002108200092402FFFE08001BC930 -:102ED000AFA000108EE204D4AEE40070AEE4007443 -:102EE0003442000108001BBDAEE204D48EE304D4DA -:102EF000AEE40070AEE4007400621824AEE304D4C3 -:102F00008F8400540004144200041C8200431021EA -:102F100000041CC20043102300041D0200431021C2 -:102F200000041D420043102308001BD0AEE20078CD -:102F30003C0400012484536CAFA000148FA6002031 -:102F40003C0500030C00240334A500048EE20110AC -:102F500024420001AEE20110080022E88EE20110D6 -:102F6000274402120C0022FE240500063049001FEF -:102F7000000920C002E410219442727C30424000DB -:102F80001040000A0097102197430212A443727E5A -:102F90008F43021400971021AC43728002E4182181 -:102FA0003402800008001C79A462727C9443727E13 -:102FB000974202121462000602E4102100971021C9 -:102FC0008C4372808F4202141062009F02E4102131 -:102FD0009442727C304280001040002A2406FFFF99 -:102FE00000002021000410C002E210219442737CF2 -:102FF000304240005440000500803021248400010C -:103000002C8200801440FFF8000410C004C100109E -:10301000000618C0000610C0005718218C63737C8E -:1030200000571021AFA300108C4273803C040001B4 -:1030300024845378AFA200148F4702143C05000388 -:103040000C00240334A5001308001C903C02080067 -:103050009744021200771021A444737E8F44021417 -:103060000077102102E31821AC4473803402800001 -:10307000A462737C000910C002E2102108001C79D0 -:10308000A446727C02E410219445727C08001C2E38 -:10309000000510C09443737E97420212146200062A -:1030A000000510C0009710218C4373808F420214DA -:1030B00010620065000510C002E210219445737C87 -:1030C000000510C002E210219442737C304280005F -:1030D0001040FFF000971021000520C0009710213C -:1030E0009443737E97420212146200062406FFFF87 -:1030F000009710218C4373808F420214106200539A -:103100003C02080000002021000410C002E210214F -:103110009442737C304240005440000500803021CE -:10312000248400012C8200801440FFF8000410C0A9 -:1031300004C10023000618C0000910C00057182160 -:103140008C63727C00571021AFA300108C427280F8 -:103150003C04000124845384AFA200148F4702145E -:103160003C0500030C00240334A5F01708001C9054 -:103170003C0208008F43021000B71021AC43777C5B -:103180008F43021400B71021AC4377803C0200014A -:10319000005710218C4283B4244200013C010001FD -:1031A00000370821AC2283B43C03000100771821CA -:1031B0008C6383B402E5102108001C82A443777C51 -:1031C0009744021200771021A444737E8F440214A6 -:1031D0000077102102E31821AC4473803402800090 -:1031E000A462737C000510C002E21021A446737C27 -:1031F00000002021000428C002E510219442777CC1 -:103200001040FFDC248400012C8200805440FFFA2F -:10321000000428C092E204D81040000624020001F5 -:103220008EE304DC012210040062182508001C8FC4 -:10323000AEE304DC8F830228240200010122100483 -:1032400000621825AF8302283C02080034421000B7 -:10325000AFA200188EE206088F4302282442000124 -:10326000304A00FF514300FDAFA000108EE2060877 -:10327000000210C0005710218FA300188FA4001C5B -:10328000AC43060CAC4406108F8300548F8200546C -:1032900024690032012210232C4200331040006ABE -:1032A0000000582124100008240F000D240D0007F1 -:1032B000240C0040240E00018F8701202762380073 -:1032C00024E800200102102B504000012768300044 -:1032D0008F82012811020004000000008F82012467 -:1032E00015020007000010218EE201A40000382121 -:1032F00024420001AEE201A408001D088EE201A4F0 -:103300008EE40608000420C0008018218EE40430FA -:103310008EE5043400A3282100A3302B0082202155 -:1033200000862021ACE40000ACE500048EE2060833 -:10333000A4F0000EACEF0018ACEA001C000210C0B4 -:103340002442060C02E21021ACE200088EE204C422 -:10335000ACE20010AF88012092E24E20144000330E -:10336000240700018EE24E30000210C02442503883 -:1033700002E220218C820000144D001F000000009A -:103380008EE34E308EE24E341062001B00000000CF -:103390008C82000424420001AC8200048EE24E3490 -:1033A0008EE34E3024420001104C00070000000064 -:1033B0008EE24E342442000110620005000000003D -:1033C00008001CF50000000014600005000000006B -:1033D0008F82012824420020AF8201288F82012899 -:1033E0008C8200042C42001150400010AC80000080 -:1033F00008001D08000000008EE24E30244200014B -:10340000504C0003000010218EE24E302442000197 -:10341000AEE24E308EE24E30000210C024425038F0 -:1034200002E22021AC8D0000AC8E000454E00006C6 -:10343000240B00018F820054012210232C42003300 -:103440001440FF9D00000000316300FF24020001D2 -:1034500054620078AFA00010AEEA06088F830054D3 -:103460008F82005424690032012210232C42003341 -:103470001040006100005821240E0008240D0011A6 -:10348000240A001224080040240C00018F8301202C -:10349000276238002466002000C2102B5040000133 -:1034A000276630008F82012810C20004000000004F -:1034B0008F82012414C20007000000008EE201A4E4 -:1034C0000000382124420001AEE201A408001D746E -:1034D0008EE201A48EE20608AC62001C8EE404A019 -:1034E0008EE504A42462001CAC620008A46E000EE9 -:1034F000AC6D0018AC640000AC6500048EE204C43E -:10350000AC620010AF86012092E24E2014400033DE -:10351000240700018EE24E30000210C024425038D1 -:1035200002E220218C820000144A001F00000000EB -:103530008EE34E308EE24E341062001B000000001D -:103540008C82000424420001AC8200048EE24E34DE -:103550008EE34E30244200011048000700000000B6 -:103560008EE24E342442000110620005000000008B -:1035700008001D610000000014600005000000004C -:103580008F82012824420020AF8201288F820128E7 -:103590008C8200042C42001150400010AC800000CE -:1035A00008001D74000000008EE24E30244200012D -:1035B00050480003000010218EE24E3024420001EA -:1035C000AEE24E308EE24E30000210C0244250383F -:1035D00002E22021AC8A0000AC8C000454E000061A -:1035E000240B00018F820054012210232C4200334F -:1035F0001440FFA600000000316300FF2402000118 -:1036000010620022000000003C040001248453905A -:10361000AFA00010AFA000148F8601208F87012477 -:103620003C0500090C00240334A5F01108001DA07E -:10363000000000003C0400012484539CAFA000144F -:103640008F8601208F8701243C0500090C0024038C -:1036500034A5F01008001DA0000000003C0400018B -:10366000248453A8AFA000148EE606088F470228D2 -:103670003C0500090C00240334A5F00F8EE201ACD8 -:1036800024420001AEE201AC8EE201AC8EE20124E4 -:1036900024420001AEE2012408001F978EE20124BB -:1036A000274402120C0022FE240500063049001FA8 -:1036B000000928C002E510219442727C304280004B -:1036C0001040002F02E510219442727C30424000ED -:1036D0001440001C00B710219443727E97420212DE -:1036E0001462001800B710218C4372808F420214BC -:1036F00054620016AFA2001092E204D810400007F6 -:10370000240200018EE304DC0122100400021027D1 -:103710000062182408001DC9AEE304DC8F83022870 -:10372000012210040002102700621824AF8302282F -:10373000000910C002E218213402C00008001E4E29 -:10374000A462727C8F420214AFA20010000910C064 -:10375000005710218C42727C3C040001248453B435 -:103760003C050003AFA200148F47021034A5F01CE3 -:103770000C0024030120302108001E833C020800B5 -:1037800000B710219443727E97420212146200190E -:10379000000918C000B710218C4372808F420214B8 -:1037A00014620014000918C002E510219447727CCD -:1037B000000720C0009710219443737E00B71021AA -:1037C000A443727E009710218C43738000B71021B0 -:1037D000AC43728002E410219443737C02E5102113 -:1037E000A443727C02E418213402C00008001E4E7B -:1037F000A462737C02E310219447727C00003021A4 -:10380000000720C002E410219442737C0000402194 -:10381000304280001440002500E028210060502143 -:10382000340BC000009710219443737E974202121C -:103830005462001500E02821009710218C4373800A -:103840008F4202145462001000E02821110000068B -:1038500002E410219443737C000510C002E21021A1 -:1038600008001E1AA443737C9443737C02EA10215F -:10387000A443727C000710C002E21021A44B737CA9 -:1038800008001E2824060001000510C002E21021D5 -:103890009447737C000720C002E410219442737C9B -:1038A000304280001040FFDF2508000130C200FFD9 -:1038B0001440002500002021000720C0009710219F -:1038C0009443737E974202121462000F000910C0E5 -:1038D000009710218C4373808F4202141462000AF7 -:1038E000000910C002E418213402C00015000015C0 -:1038F000A462737C000910C002E218213402800027 -:1039000008001E4EA462727C005710218C42727C0B -:103910003C040001248453C03C050003AFA2001006 -:10392000000710C0005710218C42737C34A5001E84 -:10393000012030210C002403AFA2001408001E83D4 -:103940003C02080000002021000428C000B710211C -:103950009443777E974202125462002B2484000124 -:1039600000B710218C4377808F42021454620026E6 -:10397000248400013C020001005710218C4283B4D2 -:103980002442FFFF3C01000100370821AC2283B430 -:103990003C020001005710218C4283B4008090212A -:1039A0000242102B1040000E24B1777C24B07784A3 -:1039B00002F0202102F128210C00249024060008A6 -:1039C000263100083C020001005710218C4283B4CC -:1039D000265200010242102B1440FFF52610000869 -:1039E0003C040001009720218C8483B42405000846 -:1039F000000420C02484777C0C00248802E4202169 -:103A000008001E833C0208002C8200801440FFCF77 -:103A1000000428C03C02080034422000AFA2001875 -:103A20008EE206088F43022824420001304A00FF3C -:103A3000514300FDAFA000108EE20608000210C046 -:103A4000005710218FA300188FA4001CAC43060C54 -:103A5000AC4406108F8300548F82005424690032D6 -:103A6000012210232C4200331040006A000058212C -:103A700024100008240F000D240D0007240C004022 -:103A8000240E00018F8701202762380024E80020DF -:103A90000102102B50400001276830008F8201285E -:103AA00011020004000000008F82012415020007AB -:103AB000000010218EE201A4000038212442000100 -:103AC000AEE201A408001EFB8EE201A48EE406080B -:103AD000000420C0008018218EE404308EE50434F8 -:103AE00000A3282100A3302B008220210086202162 -:103AF000ACE40000ACE500048EE20608A4F0000E81 -:103B0000ACEF0018ACEA001C000210C02442060C06 -:103B100002E21021ACE200088EE204C4ACE2001024 -:103B2000AF88012092E24E201440003324070001A8 -:103B30008EE24E30000210C02442503802E22021B2 -:103B40008C820000144D001F000000008EE34E30F8 -:103B50008EE24E341062001B000000008C820004D4 -:103B600024420001AC8200048EE24E348EE34E30DB -:103B700024420001104C0007000000008EE24E3489 -:103B800024420001106200050000000008001EE849 -:103B90000000000014600005000000008F82012872 -:103BA00024420020AF8201288F8201288C820004E9 -:103BB0002C42001150400010AC80000008001EFB99 -:103BC000000000008EE24E3024420001504C000301 -:103BD000000010218EE24E3024420001AEE24E3051 -:103BE0008EE24E30000210C02442503802E2202102 -:103BF000AC8D0000AC8E000454E00006240B0001E4 -:103C00008F820054012210232C4200331440FF9D68 -:103C100000000000316300FF2402000154620078BC -:103C2000AFA00010AEEA06088F8300548F820054C4 -:103C300024690032012210232C420033104000611D -:103C400000005821240E0008240D0011240A00123F -:103C500024080040240C00018F83012027623800D3 -:103C60002466002000C2102B50400001276630005F -:103C70008F82012810C20004000000008F820124FE -:103C800014C20007000000008EE201A400003821E9 -:103C900024420001AEE201A408001F678EE201A4E5 -:103CA0008EE20608AC62001C8EE404A08EE504A43B -:103CB0002462001CAC620008A46E000EAC6D0018FB -:103CC000AC640000AC6500048EE204C4AC62001079 -:103CD000AF86012092E24E201440003324070001F9 -:103CE0008EE24E30000210C02442503802E2202101 -:103CF0008C820000144A001F000000008EE34E304A -:103D00008EE24E341062001B000000008C82000422 -:103D100024420001AC8200048EE24E348EE34E3029 -:103D20002442000110480007000000008EE24E34DB -:103D300024420001106200050000000008001F542A -:103D40000000000014600005000000008F820128C0 -:103D500024420020AF8201288F8201288C82000437 -:103D60002C42001150400010AC80000008001F677A -:103D7000000000008EE24E30244200015048000353 -:103D8000000010218EE24E3024420001AEE24E309F -:103D90008EE24E30000210C02442503802E2202150 -:103DA000AC8A0000AC8C000454E00006240B000137 -:103DB0008F820054012210232C4200331440FFA6AE -:103DC00000000000316300FF2402000110620022A5 -:103DD000000000003C04000124845390AFA00010B8 -:103DE000AFA000148F8601208F8701243C050009B5 -:103DF0000C00240334A5F01108001F9300000000FC -:103E00003C0400012484539CAFA000148F86012041 -:103E10008F8701243C0500090C00240334A5F01011 -:103E200008001F93000000003C040001248453A8F4 -:103E3000AFA000148EE606088F4702283C05000953 -:103E40000C00240334A5F00F8EE201AC24420001E3 -:103E5000AEE201AC8EE201AC8EE201282442000108 -:103E6000AEE201288EE201288EE2016424420001C4 -:103E7000AEE20164080022E88EE201648FA2002015 -:103E80000002120000021D0224020001106200055F -:103E9000240200021062000D0000000008001FB79D -:103EA000AFA0001092E204D81440000624020001E2 -:103EB0008F820228AEE204DC2402FFFFAF820228D8 -:103EC0002402000108001FBEA2E204D892E204D836 -:103ED0005040000CA2E004D88EE204DCAF8202283D -:103EE00008001FBEA2E004D83C040001248453C88B -:103EF000AFA000148FA600203C0500030C00240393 -:103F000034A5F0098EE2013C24420001AEE2013CFE -:103F1000080022E88EE2013C8FA20020000212007D -:103F20000002250224020001108200052402000282 -:103F30001082000F0000000008001FE3AFA0001077 -:103F40008F8202203C0308FF3463FFFF00431024EC -:103F500034420008AF820220240200013C0100012B -:103F600000370821A02283B208001FEAAEE401084E -:103F70008F8202203C0308FF3463FFF700431024C4 -:103F8000AF8202203C01000100370821A02083B24B -:103F900008001FEAAEE401083C040001248453D465 -:103FA000AFA000148FA600203C0500030C002403E2 -:103FB00034A5F00A8EE2012C24420001AEE2012C6D -:103FC000080022E88EE2012C8FA2002000021200DD -:103FD00000021D02240200011062000524020002FA -:103FE0001062000E0000000008002011AFA00010B9 -:103FF0008F8202203C0308FF3463FFFF004310243C -:1040000034420008AF820220240200013C0100017A -:104010000037082108002018A02283B33C020001C9 -:1040200000571021904283B23C0100010037082163 -:104030001440000EA02083B38F8202203C0308FFAF -:104040003463FFF70043102408002018AF820220D9 -:104050003C040001248453E0AFA000148FA600208C -:104060003C0500030C00240334A5F00B8EE2011480 -:1040700024420001AEE20114080022E88EE201149D -:1040800027840208274502000C00249A2406000811 -:1040900026E40094274502000C00249A2406000818 -:1040A0008EE2013424420001AEE20134080022E82D -:1040B0008EE201348F460248000020210C00510896 -:1040C000240500048EE2013024420001AEE20130FA -:1040D000080022E88EE201308EF301CC8EF401D08C -:1040E0008EF501D88EE2014026E400302442000122 -:1040F000AEE201408EF001408EF100748EF200704D -:104100000C00248824050400AEF301CCAEF401D0E9 -:10411000AEF501D8AEF00140AEF10074AEF2007021 -:104120008F42025C26E40094AEE200608F4202609F -:104130002745020024060008AEE2006824020006BB -:104140000C00249AAEE200643C023B9A3442CA005E -:10415000AEE2006C240203E8240400022403000100 -:10416000AEE20104AEE40100AEE3010C8F82022056 -:10417000304200081040000400000000AEE30108D7 -:104180000800206100002021AEE401080000202189 -:104190003C0300010064182190635C3002E41021AC -:1041A00024840001A043009C2C82000F1440FFF8DF -:1041B000000000008F82004002E4182124840001E6 -:1041C0000002170224420030A062009C02E4102189 -:1041D000080022E8A040009C240200013C010001EC -:1041E00000370821A02283E0240B040024080014D7 -:1041F000240A0040240900018F8301002762300057 -:104200002466002000C2102B5040000127662800C1 -:104210008F82010810C20004000000008F82010498 -:1042200014C2000726E200308EE201A80000382107 -:1042300024420001AEE201A8080020A88EE201A8F5 -:104240008EE404B88EE504BCAC620008A46B000EDA -:10425000AC680018AC60001CAC640000AC650004E5 -:104260008EE204CCAC620010AF86010092E204EC56 -:104270001440000E240700018EE24E282442000163 -:10428000504A0003000010218EE24E282442000113 -:10429000AEE24E288EE24E28000210C024424E3874 -:1042A00002E21021AC480000AC49000410E0FFD24B -:1042B00000000000080022E8000000003C020900A5 -:1042C000AEE05238AEE0523CAEE05240AEE0524476 -:1042D000AEE001D03C01000100370821A02083B1ED -:1042E000AFA200188EE206088F4302282442000184 -:1042F000304A00FF514300FDAFA000108EE20608D7 -:10430000000210C0005710218FA300188FA4001CBA -:10431000AC43060CAC4406108F8300548F820054CB -:1043200024690032012210232C4200331040006A1D -:104330000000582124100008240F000D240D000750 -:10434000240C0040240E00018F87012027623800D2 -:1043500024E800200102102B5040000127683000A3 -:104360008F82012811020004000000008F820124C6 -:1043700015020007000010218EE201A40000382180 -:1043800024420001AEE201A40800212C8EE201A427 -:104390008EE40608000420C0008018218EE404305A -:1043A0008EE5043400A3282100A3302B00822021B5 -:1043B00000862021ACE40000ACE500048EE2060893 -:1043C000A4F0000EACEF0018ACEA001C000210C014 -:1043D0002442060C02E21021ACE200088EE204C482 -:1043E000ACE20010AF88012092E24E20144000336E -:1043F000240700018EE24E30000210C024425038E3 -:1044000002E220218C820000144D001F00000000F9 -:104410008EE34E308EE24E341062001B000000002E -:104420008C82000424420001AC8200048EE24E34EF -:104430008EE34E3024420001104C000700000000C3 -:104440008EE24E342442000110620005000000009C -:1044500008002119000000001460000500000000A1 -:104460008F82012824420020AF8201288F820128F8 -:104470008C8200042C42001150400010AC800000DF -:104480000800212C000000008EE24E302442000182 -:10449000504C0003000010218EE24E3024420001F7 -:1044A000AEE24E308EE24E30000210C02442503850 -:1044B00002E22021AC8D0000AC8E000454E0000626 -:1044C000240B00018F820054012210232C42003360 -:1044D0001440FF9D00000000316300FF2402000132 -:1044E00054620078AFA00010AEEA06088F83005433 -:1044F0008F82005424690032012210232C420033A1 -:104500001040006100005821240E0008240D001105 -:10451000240A001224080040240C00018F8301208B -:10452000276238002466002000C2102B5040000192 -:10453000276630008F82012810C2000400000000AE -:104540008F82012414C20007000000008EE201A443 -:104550000000382124420001AEE201A408002198A5 -:104560008EE201A48EE20608AC62001C8EE404A078 -:104570008EE504A42462001CAC620008A46E000E48 -:10458000AC6D0018AC640000AC6500048EE204C49D -:10459000AC620010AF86012092E24E20144000333E -:1045A000240700018EE24E30000210C02442503831 -:1045B00002E220218C820000144A001F000000004B -:1045C0008EE34E308EE24E341062001B000000007D -:1045D0008C82000424420001AC8200048EE24E343E -:1045E0008EE34E3024420001104800070000000016 -:1045F0008EE24E34244200011062000500000000EB -:104600000800218500000000146000050000000083 -:104610008F82012824420020AF8201288F82012846 -:104620008C8200042C42001150400010AC8000002D -:1046300008002198000000008EE24E302442000164 -:1046400050480003000010218EE24E302442000149 -:10465000AEE24E308EE24E30000210C0244250389E -:1046600002E22021AC8A0000AC8C000454E0000679 -:10467000240B00018F820054012210232C420033AE -:104680001440FFA600000000316300FF2402000177 -:1046900010620022000000003C04000124845390BA -:1046A000AFA00010AFA000148F8601208F870124D7 -:1046B0003C0500090C00240334A5F011080021C4B6 -:1046C000000000003C0400012484539CAFA00014AF -:1046D0008F8601208F8701243C0500090C002403EC -:1046E00034A5F010080021C4000000003C040001C3 -:1046F000248453A8AFA000148EE606088F47022832 -:104700003C0500090C00240334A5F00F8EE201AC37 -:1047100024420001AEE201AC8EE201AC8EE2012047 -:1047200024420001AEE201208EE201208EE2016807 -:1047300024420001AEE20168080022E88EE201682E -:104740008F42025C26E40094AEE200608F42026079 -:1047500027450200240600080C00249AAEE20068F7 -:104760008F8202203042000814400002240200011F -:1047700024020002AEE201088EE2011C2442000184 -:10478000AEE2011C080022E88EE2011C3C0400019C -:10479000248453ECAFA00010AFA000148FA600201B -:1047A0003C0500030C00240334A5F00F93A2002065 -:1047B0003C0307003463100000431025AFA200182B -:1047C0008EE206088F43022824420001304900FF90 -:1047D000512300E2AFA000108EE20608000210C0D4 -:1047E000005710218FA300188FA4001CAC43060CA7 -:1047F000AC4406108F8701202762380024E800208F -:104800000102102B50400001276830008F820128E0 -:1048100011020004000000008F820124150200072D -:10482000000010218EE201A4000038212442000182 -:10483000AEE201A40800225D8EE201A48EE4060827 -:10484000000420C0008018218EE404308EE504347A -:1048500000A3282100A3302B0082202100862021E4 -:10486000ACE40000ACE500048EE306082402000876 -:10487000A4E2000E2402000DACE20018ACE9001C1A -:10488000000318C02463060C02E31021ACE2000808 -:104890008EE204C4ACE20010AF88012092E24E2008 -:1048A00014400037240700018EE24E30000210C091 -:1048B0002442503802E220218C83000024020007A9 -:1048C0001462001F000000008EE34E308EE24E3472 -:1048D0001062001B240300408C820004244200016B -:1048E000AC8200048EE24E348EE54E30244200014C -:1048F00010430007000000008EE24E342442000105 -:1049000010A200050000000008002247000000007F -:1049100014A00005000000008F820128244200201E -:10492000AF8201288F8201288C8200042C42001162 -:1049300050400013AC8000000800225D0000000021 -:104940008EE24E3024030040244200015043000315 -:10495000000010218EE24E3024420001AEE24E30C3 -:104960008EE24E30000210C02442503802E2202174 -:1049700024020007AC82000024020001AC82000483 -:1049800054E0000CAEE906083C040001248453F412 -:10499000AFA00010AFA000148EE606088F470228D3 -:1049A0003C0500090C00240334A5F000080022E0B7 -:1049B000000000008F830120276238002466002059 -:1049C00000C2102B50400001276630008F82012862 -:1049D00010C20004000000008F82012414C20007EE -:1049E000000000008EE201A40000382124420001F2 -:1049F000AEE201A4080022C48EE201A48EE2060801 -:104A0000AC62001C8EE404A08EE504A42462001CA9 -:104A1000AC62000824020008A462000E2402001107 -:104A2000AC620018AC640000AC6500048EE204C403 -:104A3000AC620010AF86012092E24E201440003795 -:104A4000240700018EE24E30000210C0244250388C -:104A500002E220218C830000240200121462001F55 -:104A6000000000008EE34E308EE24E341062001BD8 -:104A7000240300408C82000424420001AC82000424 -:104A80008EE24E348EE54E30244200011043000782 -:104A9000000000008EE24E342442000110A2000506 -:104AA00000000000080022AE0000000014A0000575 -:104AB000000000008F82012824420020AF820128DC -:104AC0008F8201288C8200042C4200115040001378 -:104AD000AC800000080022C4000000008EE24E30CE -:104AE0002403004024420001504300030000102131 -:104AF0008EE24E3024420001AEE24E308EE24E3065 -:104B0000000210C02442503802E220212402001288 -:104B1000AC82000024020001AC82000414E0001BFF -:104B2000000000003C040001248453FCAFA00010EE -:104B3000AFA000148EE606088F4702283C05000946 -:104B40000C00240334A5F0018EE201B024420001E0 -:104B5000AEE201B0080022E08EE201B03C040001A8 -:104B600024845408AFA000148EE606088F4702285C -:104B70003C0500090C00240334A5F0058EE201ACCD -:104B800024420001AEE201AC8EE201AC8EE20150A3 -:104B900024420001AEE201508EE201508EE201603B -:104BA00024420001AEE201608EE201608F43022CDC -:104BB0008F42010C1462000924020002AF820064DB -:104BC0008F82006414400005000000008F43022C17 -:104BD0008F42010C1462F875000000008FBF004482 -:104BE0008FB600408FB5003C8FB400388FB30034CF -:104BF0008FB200308FB1002C8FB0002803E0000886 -:104C000027BD004827BDFFF82408FFFF10A00014AF -:104C1000000048213C0AEDB8354A83209087000007 -:104C200024840001000030210107102630420001D9 -:104C30001040000200081842006A18260060402157 -:104C400024C600012CC200081440FFF700073842B8 -:104C5000252900010125102B1440FFF00000000061 -:104C60000100102103E0000827BD000827BDFFE870 -:104C700027642800AFBF00100C0024882405100012 -:104C800024020021AF800100AF800104AF80010841 -:104C9000AF800110AF800114AF800118AF800120F8 -:104CA000AF800124AF800128AF800130AF80013494 -:104CB000AF800138AEE04E28AEE04E2CAEE04E3074 -:104CC000AEE04E34AF82011C8F42021830420040E9 -:104CD00010400004000000008F82011C34420004D8 -:104CE000AF82011C8FBF001003E0000827BD001831 -:104CF00027BDFFE0AFBF00188F820104AFA20010F4 -:104D00008F8201003C050002AFA200148F8600B024 -:104D10008F87011C3C040001248454C00C00240330 -:104D200034A5F0008F8300B03C027F00006218249D -:104D30003C020400106200290043102B14400008BC -:104D40003C0220003C020100106200243C020200F0 -:104D50001062001100000000080023740000000031 -:104D6000106200083C0240001462001C00000000B9 -:104D70008EE2019024420001AEE20190080023740B -:104D80008EE201908EE2018C24420001AEE2018CA1 -:104D9000080023748EE2018C8F82011C34420002D1 -:104DA000AF82011C8F8301048F8200B03442000166 -:104DB000AF8200B0AF8301048F82011C2403FFFD8A -:104DC00000431024AF82011C8EE201A024420001A6 -:104DD000AEE201A0080023778EE201A08F8200B02E -:104DE00034420001AF8200B08FBF001803E000081A -:104DF00027BD002027BDFFE0AFBF001CAFB00018EB -:104E00008F820120AFA200108F8201243C05000197 -:104E1000AFA200148F8600A08F87011C3C04000104 -:104E2000248454CC0C00240334A5F0008F8300A00C -:104E30003C027F00006218243C0204001062005310 -:104E4000000080210043102B144000083C04200087 -:104E50003C0201001062004D3C0202001062003A68 -:104E600000000000080023E00000000010640003C0 -:104E70003C02400014620045000000008F8200A048 -:104E80000044102410400006000000008EE201944F -:104E900024420001AEE20194080023A98EE20194AD -:104EA0008EE2019824420001AEE201988EE2019860 -:104EB0008F82011C34420002AF82011C8F82011CD0 -:104EC000304202001040001B000000008F8300A051 -:104ED0008F8401248F8200AC14400007240200015B -:104EE0003C0200013442F0000062102450400001F6 -:104EF00024100001240200011200000DAF8200A066 -:104F00008F8201242442FFE0AF8201248F8201249A -:104F10008F820124276330000043102B10400005CE -:104F2000276237E0AF820124080023CA0000000096 -:104F3000AF8401248F82011C2403FFFD0043102451 -:104F4000080023E3AF82011C8F82011C344200025F -:104F5000AF82011C8F8301248F8200A034420001A4 -:104F6000AF8200A0AF8301248F82011C2403FFFDC8 -:104F700000431024AF82011C8EE2019C24420001F8 -:104F8000AEE2019C080023E38EE2019C8F8200A028 -:104F900034420001AF8200A08FBF001C8FB0001808 -:104FA00003E0000827BD0020000000003C020001D3 -:104FB0008C425C5827BDFFE8AFBF001414400012BC -:104FC000AFB000103C10000126105DD0020020217F -:104FD0000C0024882405200026021FE03C0100016B -:104FE000AC225D943C010001AC225D90AF420250C6 -:104FF00024022000AF500254AF42025824020001A4 -:105000003C010001AC225C588FBF00148FB000102F -:1050100003E0000827BD00183C0300018C635D9489 -:105020008C8200008FA800108FA90014AC620000D1 -:105030003C0200018C425D948C830004AC4300046C -:10504000AC4500088F8400542443FFE0AC460010B8 -:10505000AC470014AC480018AC49001C3C010001EE -:10506000AC235D94AC44000C3C02000124425DD0B2 -:105070000062182B10600005000000003C020001D7 -:105080008C425D903C010001AC225D943C03000128 -:105090008C635D943C0200018C425C40AC62000079 -:1050A0003C0300018C635D943C0200018C425C4037 -:1050B000AC62000403E00008AF4302503C0300016F -:1050C0008C635D943C0200018C425C4027BDFFD0A4 -:1050D000AFB400208FB40040AFB00010008080213A -:1050E000AFB500248FB500448FA40048AFB10014C1 -:1050F00000A08821AFBF0028AFB3001CAFB20018DA -:10510000AC6200003C0500018CA55D943C020001EE -:105110008C425C4000C0902100E098211080000685 -:10512000ACA2000424A500080C002490240600185A -:105130000800244E0000000024A400080C0024886D -:10514000240500183C0200018C425D943C050001DE -:1051500024A55DD02442FFE03C010001AC225D9417 -:105160000045102B10400005000000003C0200012B -:105170008C425D903C010001AC225D943C03000137 -:105180008C635D948E020000AC6200003C03000161 -:105190008C635D948E020004AC620004AC71000864 -:1051A0008F8400542462FFE03C010001AC225D9436 -:1051B0000045102BAC720010AC730014AC740018D6 -:1051C000AC75001C10400005AC64000C3C020001F2 -:1051D0008C425D903C010001AC225D943C030001D7 -:1051E0008C635D943C0200018C425C40AC62000028 -:1051F0003C0300018C635D943C0200018C425C40E6 -:10520000AC620004AF4302508FBF00288FB500246A -:105210008FB400208FB3001C8FB200188FB1001420 -:105220008FB0001003E0000827BD003010A000057B -:1052300000000000AC80000024A5FFFC14A0FFFDCE -:105240002484000403E000080000000010C00007F0 -:10525000000000008C8200002484000424C6FFFCAF -:10526000ACA2000014C0FFFB24A5000403E000086A -:105270000000000010C00007000000008CA2000029 -:1052800024A5000424C6FFFCAC82000014C0FFFB70 -:105290002484000403E000080000000003E000088C -:1052A0000000000027BDFFD8AFBF00208EE304E45C -:1052B0008EE204E010620436000000008EE204E496 -:1052C0008EE304FC00021100006260219587000853 -:1052D0008D8A00008D8B0004958D000A8EE2725C31 -:1052E0008EE3726C30E4FFFF004410210062182B43 -:1052F0001060001531A200048F8200D88EE372582E -:1053000000431023AEE2726C8EE2726C1C4000030C -:105310003C03000100431021AEE2726C8EE2725C2D -:105320008EE3726C004410210062182B106000069E -:1053300031A200048EE201B824420001AEE201B8BD -:10534000080028E18EE201B81040024031A20200BC -:105350001040014D0000482196E2045A30420010EE -:1053600010400149000000008F84010027623000D6 -:105370002485002000A2102B504000012765280042 -:105380008F82010810A20004000000008F82010437 -:1053900014A200062402000C8EE201A8244200019F -:1053A000AEE201A80800252C8EE201A8AC8A00001C -:1053B000AC8B00048EE3726424060005A482000E08 -:1053C000AC860018AC8300088EE204E4AC82001CBA -:1053D0008EE204C8AC820010AF85010092E204ECBA -:1053E00014400036240900018EE24E28000210C04D -:1053F00024424E3802E220218C8200001446001F15 -:10540000000000008EE34E288EE24E2C1062001B3E -:10541000240300408C82000424420001AC8200047A -:105420008EE24E2C8EE54E282442000110430007E8 -:10543000000000008EE24E2C2442000110A2000564 -:1054400000000000080025160000000014A0000560 -:10545000000000008F82010824420020AF82010872 -:105460008F8201088C8200042C42001150400013EE -:10547000AC8000000800252C000000008EE24E28C1 -:105480002403004024420001504300030000102187 -:105490008EE24E2824420001AEE24E288EE24E28D3 -:1054A000000210C024424E3802E2202124020005EE -:1054B000AC82000024020001AC8200041520000A26 -:1054C0003C040001AFAB00108EE272643C040001AA -:1054D000248457303C050004AFA200148EE604E497 -:1054E000080028BE34A5F1148EE2726434843800BA -:1054F00003641821244200100043102B1440007351 -:10550000000000008EE27264244800100364102141 -:105510000102102B144000023C02FFFF0102402157 -:105520008F8501002762300024A6002000C2102BC6 -:1055300050400001276628008F82010810C2000435 -:10554000000000008F82010414C200072563000CD4 -:105550008EE201A80000482124420001AEE201A829 -:10556000080025A08EE201A82C64000C0144102143 -:10557000ACA20000ACA3000424E2FFF4A4A2000E3D -:1055800024020006ACA80008ACA200188EE204E4D5 -:10559000ACA2001C8EE204C83C03000200431025AC -:1055A000ACA20010AF86010092E204EC1440003778 -:1055B000240900018EE24E28000210C024424E3819 -:1055C00002E220218C830000240200051462001FE7 -:1055D000000000008EE34E288EE24E2C1062001B6D -:1055E000240300408C82000424420001AC820004A9 -:1055F0008EE24E2C8EE54E28244200011043000717 -:10560000000000008EE24E2C2442000110A2000592 -:10561000000000000800258A0000000014A000051A -:10562000000000008F82010824420020AF820108A0 -:105630008F8201088C8200042C420011504000131C -:10564000AC800000080025A0000000008EE24E287B -:1056500024030040244200015043000300001021B5 -:105660008EE24E2824420001AEE24E288EE24E2801 -:10567000000210C024424E3802E22021240200051C -:10568000AC82000024020001AC8200041520000A54 -:105690002508FFFCAFAB00108EE272643C040001F1 -:1056A000248457303C050004AFA200148EE604E4C5 -:1056B000080028BE34A5F12534028100A5020000AF -:1056C0009582000E0800261DA50200028F850100AC -:1056D0002762300024A6002000C2102B5040000199 -:1056E000276628008F82010810C200040000000015 -:1056F0008F82010414C200072563000C8EE201A80A -:105700000000482124420001AEE201A80800260D55 -:105710008EE201A82C64000C01441021ACA2000010 -:10572000ACA300048EE3726424E2FFF4A4A2000E92 -:1057300024020006ACA2001824630010ACA30008E9 -:105740008EE204E4ACA2001C8EE204C83C0300021A -:1057500000431025ACA20010AF86010092E204ECD9 -:1057600014400037240900018EE24E28000210C0C8 -:1057700024424E3802E220218C83000024020005DE -:105780001462001F000000008EE34E288EE24E2CB3 -:105790001062001B240300408C820004244200019C -:1057A000AC8200048EE24E2C8EE54E28244200018D -:1057B00010430007000000008EE24E2C244200013E -:1057C00010A2000500000000080025F700000000FE -:1057D00014A00005000000008F8201082442002070 -:1057E000AF8201088F8201088C8200042C420011D4 -:1057F00050400013AC8000000800260D000000009F -:105800008EE24E282403004024420001504300034E -:10581000000010218EE24E2824420001AEE24E2804 -:105820008EE24E28000210C024424E3802E22021AF -:1058300024020005AC82000024020001AC820004B6 -:105840001520000A34028100AFAB00108EE27264B2 -:105850003C040001248457303C050004AFA200142E -:105860008EE604E4080028BE34A5F0158EE37264C9 -:10587000A462000C8EE372649582000EA462000E96 -:105880000800268124E700048F840100276230008D -:105890002485002000A2102B50400001276528001D -:1058A0008F82010810A20004000000008F82010412 -:1058B00014A20007240200068EE201A8000048217D -:1058C00024420001AEE201A8080026778EE201A87A -:1058D000AC8A0000AC8B00048EE37264A487000ED7 -:1058E000AC820018AC8300088EE204E4AC82001C99 -:1058F0008EE204C83C03000200431025AC82001075 -:10590000AF85010092E204EC144000372409000145 -:105910008EE24E28000210C024424E3802E22021BE -:105920008C830000240200051462001F00000000A8 -:105930008EE34E288EE24E2C1062001B24030040A2 -:105940008C82000424420001AC8200048EE24E2CC2 -:105950008EE54E282442000110430007000000009D -:105960008EE24E2C2442000110A20005000000002F -:10597000080026610000000014A0000500000000DF -:105980008F82010824420020AF8201088F82010823 -:105990008C8200042C42001150400013AC800000A7 -:1059A00008002677000000008EE24E282403004005 -:1059B0002442000150430003000010218EE24E28D3 -:1059C00024420001AEE24E288EE24E28000210C0B2 -:1059D00024424E3802E2202124020005AC8200005D -:1059E00024020001AC820004152000093C050004DB -:1059F000AFAB00108EE272643C0400012484573087 -:105A0000AFA200148EE604E4080028BE34A5F0041A -:105A10008EE2725C30E7FFFF00471021AEE2725C5D -:105A20008EE204E48EE304FC8EE47258000211005E -:105A300000431021AC44000C8EE27258AFA2001853 -:105A40008EE3725CAFA3001C8EE2725C2C42003CC1 -:105A500010400004246200012403FFFE00431024D0 -:105A6000AFA2001C8EE272643C06000134C638000E -:105A70008EE3725C2405FFF80047102124420007E2 -:105A80000045102424630007AEE272588EE2726C67 -:105A90008EE472580065182400431023AEE2726C45 -:105AA000036610210082202B148000043C03FFFFBA -:105AB0008EE2725800431021AEE272588EE27258A4 -:105AC000AEE272648F8200F024470008276218005B -:105AD00000E2102B50400001276710008F8200F475 -:105AE00014E20007000000008EE201B4000048212B -:105AF00024420001AEE201B4080026C48EE201B4E3 -:105B00008F8200F0240900018FA300188FA4001CCD -:105B1000AC430000AC440004AF8700F01520001235 -:105B2000000D11428F8200F0AFA200108F8200F4AE -:105B30003C0400012484573CAFA200148FA6001837 -:105B40008FA7001C3C0500040C00240334A5F005BD -:105B50008EE2008824420001AEE200888EE20088D6 -:105B6000080028D3AEE0725C304300032402000238 -:105B70001062001628620003104000052402000194 -:105B80001062000800000000080027030000000069 -:105B90002402000310620017000000000800270321 -:105BA000000000008EE200E88EE300EC24630001B8 -:105BB0002C64000100441021AEE200E8AEE300ECEA -:105BC0008EE200E8080027038EE300EC8EE200F08E -:105BD0008EE300F4246300012C64000100441021D2 -:105BE000AEE200F0AEE300F48EE200F0080027031E -:105BF0008EE300F48EE200F88EE300FC24630001E3 -:105C00002C64000100441021AEE200F8AEE300FC79 -:105C10008EE200F88EE300FC8EE2725C8EE400E01F -:105C20008EE500E4004018210000102100A3282187 -:105C300000A3302B0082202100862021AEE400E06A -:105C4000AEE500E4080028D3AEE0725C30E2FFFF6E -:105C5000104001C131A202001040014D0000482156 -:105C600096E2045A30420010104001490000000042 -:105C70008F840100276230002485002000A2102BB1 -:105C800050400001276528008F82010810A20004FF -:105C9000000000008F82010414A200062402000C00 -:105CA0008EE201A824420001AEE201A80800276E9E -:105CB0008EE201A8AC8A0000AC8B00048EE3726413 -:105CC00024060005A482000EAC860018AC830008F0 -:105CD0008EE204E4AC82001C8EE204C8AC820010A8 -:105CE000AF85010092E204EC144000362409000163 -:105CF0008EE24E28000210C024424E3802E22021DB -:105D00008C8200001446001F000000008EE34E2825 -:105D10008EE24E2C1062001B240300408C82000493 -:105D200024420001AC8200048EE24E2C8EE54E2807 -:105D30002442000110430007000000008EE24E2CB8 -:105D40002442000110A200050000000008002758AE -:105D50000000000014A00005000000008F82010870 -:105D600024420020AF8201088F8201088C82000447 -:105D70002C42001150400013AC8000000800276E38 -:105D8000000000008EE24E2824030040244200015F -:105D900050430003000010218EE24E2824420001EF -:105DA000AEE24E288EE24E28000210C024424E3849 -:105DB00002E2202124020005AC820000240200013E -:105DC000AC8200041520000A3C040001AFAB0010B7 -:105DD0008EE272643C040001248457303C050004C8 -:105DE000AFA200148EE604E4080028BE34A5F01427 -:105DF0008EE2726434843800036418212442001057 -:105E00000043102B14400073000000008EE2726407 -:105E100024480010036410210102102B14400002DA -:105E20003C02FFFF010240218F8501002762300004 -:105E300024A6002000C2102B504000012766280035 -:105E40008F82010810C20004000000008F8201044C -:105E500014C200072563000C8EE201A8000048214F -:105E600024420001AEE201A8080027E28EE201A868 -:105E70002C64000C01441021ACA20000ACA300046F -:105E800024E2FFF4A4A2000E24020006ACA800083D -:105E9000ACA200188EE204E4ACA2001C8EE204C89E -:105EA0003C03000200431025ACA20010AF860100A5 -:105EB00092E204EC14400037240900018EE24E28DF -:105EC000000210C024424E3802E220218C830000E0 -:105ED000240200051462001F000000008EE34E281B -:105EE0008EE24E2C1062001B240300408C820004C2 -:105EF00024420001AC8200048EE24E2C8EE54E2836 -:105F00002442000110430007000000008EE24E2CE6 -:105F10002442000110A2000500000000080027CC68 -:105F20000000000014A00005000000008F8201089E -:105F300024420020AF8201088F8201088C82000475 -:105F40002C42001150400013AC800000080027E2F2 -:105F5000000000008EE24E2824030040244200018D -:105F600050430003000010218EE24E28244200011D -:105F7000AEE24E288EE24E28000210C024424E3877 -:105F800002E2202124020005AC820000240200016C -:105F9000AC8200041520000A2508FFFCAFAB0010FE -:105FA0008EE272643C040001248457303C050004F6 -:105FB000AFA200148EE604E4080028BE34A5F01554 -:105FC00034028100A50200009582000E0800285FBF -:105FD000A50200028F8501002762300024A6002060 -:105FE00000C2102B50400001276628008F82010854 -:105FF00010C20004000000008F82010414C20007D8 -:106000002563000C8EE201A8000048212442000113 -:10601000AEE201A80800284F8EE201A82C64000C13 -:1060200001441021ACA20000ACA300048EE3726412 -:1060300024E2FFF4A4A2000E24020006ACA2001881 -:1060400024630010ACA300088EE204E4ACA2001CA0 -:106050008EE204C83C03000200431025ACA20010ED -:10606000AF86010092E204EC1440003724090001DD -:106070008EE24E28000210C024424E3802E2202157 -:106080008C830000240200051462001F0000000041 -:106090008EE34E288EE24E2C1062001B240300403B -:1060A0008C82000424420001AC8200048EE24E2C5B -:1060B0008EE54E2824420001104300070000000036 -:1060C0008EE24E2C2442000110A2000500000000C8 -:1060D000080028390000000014A00005000000009E -:1060E0008F82010824420020AF8201088F820108BC -:1060F0008C8200042C42001150400013AC80000040 -:106100000800284F000000008EE24E2824030040C3 -:106110002442000150430003000010218EE24E286B -:1061200024420001AEE24E288EE24E28000210C04A -:1061300024424E3802E2202124020005AC820000F5 -:1061400024020001AC8200041520000A3402810000 -:10615000AFAB00108EE272643C040001248457301F -:106160003C050004AFA200148EE604E4080028BE3B -:1061700034A5F0168EE37264A462000C8EE37264A0 -:106180009582000EA462000E080028C224E70004D5 -:106190008F83010027623000246400200082102BCE -:1061A00050400001276428008F82010810820004FB -:1061B000000000008F8201041482000724050005FE -:1061C0008EE201A80000482124420001AEE201A8AD -:1061D000080028B68EE201A8AC6A0000AC6B00048F -:1061E0008EE27264A467000EAC650018AC62000811 -:1061F0008EE204E4AC62001C8EE204C8AC620010C3 -:10620000AF84010092E204EC14400036240900013E -:106210008EE24E28000210C024424E3802E22021B5 -:106220008C8200001445001F000000008EE34E2801 -:106230008EE24E2C1062001B240300408C8200046E -:1062400024420001AC8200048EE24E2C8EE54E28E2 -:106250002442000110430007000000008EE24E2C93 -:106260002442000110A2000500000000080028A040 -:106270000000000014A00005000000008F8201084B -:1062800024420020AF8201088F8201088C82000422 -:106290002C42001150400013AC800000080028B6CA -:1062A000000000008EE24E2824030040244200013A -:1062B00050430003000010218EE24E2824420001CA -:1062C000AEE24E288EE24E28000210C024424E3824 -:1062D00002E2202124020005AC8200002402000119 -:1062E000AC8200041520000B3C0500043C040001B6 -:1062F00024845748AFAB0010AFA000148EE604E42E -:1063000034A5F0170C00240330E7FFFF080028E154 -:10631000000000008EE272643C05000130E4FFFFE3 -:1063200000441021AEE272648EE2725C8EE372640D -:1063300034A5380000441021AEE2725C03651021E0 -:106340000062182B146000043C03FFFF8EE27264AD -:1063500000431021AEE272648EE304E496E2045836 -:10636000246300012442FFFF00621824AEE304E42A -:106370008EE304E48EE204E01462000500000000F5 -:106380008F8200602403FFF700431024AF82006077 -:106390008FBF002003E0000827BD002827BDFFE0D5 -:1063A000AFBF00188EE304E88EE204E010620189BA -:1063B000000000008EE204E88EE304FC00021100FD -:1063C000006218219467000892E204ED8C680000D6 -:1063D0008C69000410400023946A000A8EE204C80D -:1063E00034460400314202001040001F000000004B -:1063F00096E2045A304200101040001B3C0280001C -:106400003C01000100370821AC2283D88EE272647F -:106410009464000E3C05000134A5380024420004B9 -:10642000AEE272648EE372640004240003651021FE -:106430003C01000100370821AC2483DC0062182BEA -:106440001460000524E700048EE272643C03FFFF41 -:1064500000431021AEE272648EE2726408002917D4 -:10646000AEE272588EE604C88EE2726C30E4FFFF32 -:106470000044102A10400015000000008F8200D850 -:106480008EE3725800431023AEE2726C8EE2726C9F -:106490001C4000070044102A8EE2726C3C0300018D -:1064A00000431021AEE2726C8EE2726C0044102A3E -:1064B00010400006000000008EE201B824420001F6 -:1064C000AEE201B808002A728EE201B83C02000177 -:1064D000005710218C4283D85440000124E7FFFC70 -:1064E00031420004104000B930E2FFFF3C020001DD -:1064F000005710218C4283D81040002F00005021FB -:106500008F840100276230002485002000A2102B18 -:1065100050400001276528008F82010810A2003238 -:10652000000000008F82010410A2002F2402001539 -:10653000AC880000AC8900048EE37264A487000E6E -:10654000AC820018AC8300088EE204E83C03000132 -:10655000007718218C6383DCAC8600100043102583 -:10656000AC82001CAF85010092E204EC144000668E -:10657000240A00018EE24E28240300402442000138 -:1065800050430003000010218EE24E2824420001F7 -:10659000AEE24E288EE24E28000210C024424E3851 -:1065A00002E2182124020015AC620000240200015E -:1065B000080029BFAC6200048F840100276230000C -:1065C0002485002000A2102B5040000127652800E0 -:1065D0008F82010810A20004000000008F820104D5 -:1065E00014A20006240200068EE201A82442000143 -:1065F000AEE201A8080029BF8EE201A8AC88000025 -:10660000AC8900048EE37264A487000EAC8200188B -:10661000AC8300088EE204E8AC860010AC82001C5B -:10662000AF85010092E204EC14400037240A000117 -:106630008EE24E28000210C024424E3802E2202191 -:106640008C830000240200051462001F000000007B -:106650008EE34E288EE24E2C1062001B2403004075 -:106660008C82000424420001AC8200048EE24E2C95 -:106670008EE54E2824420001104300070000000070 -:106680008EE24E2C2442000110A200050000000002 -:10669000080029A90000000014A000050000000067 -:1066A0008F82010824420020AF8201088F820108F6 -:1066B0008C8200042C42001150400013AC8000007A -:1066C000080029BF000000008EE24E28240300408D -:1066D0002442000150430003000010218EE24E28A6 -:1066E00024420001AEE24E288EE24E28000210C085 -:1066F00024424E3802E2202124020005AC82000030 -:1067000024020001AC8200041540000A24020001AA -:10671000AFA900108EE272643C040001248457305B -:106720003C050004AFA200148EE604E408002A4FE2 -:1067300034A5F204A2E204ED8EE204E88EE304FC48 -:106740008EE472583C06000134C638003C0100015A -:1067500000370821AC2083D83C0100010037082114 -:10676000AC2083DC0002110000431021AC44000C7B -:106770008EE272642405FFF830E3FFFF004310212E -:10678000244200070045102424630007AEE272583B -:106790008EE2726C8EE47258006518240043102358 -:1067A000AEE2726C036610210082202B148000047C -:1067B0003C03FFFF8EE2725800431021AEE2725894 -:1067C0008EE2725808002A64AEE2726410400073D0 -:1067D000000000008F830100276230002464002045 -:1067E0000082102B14400002000050212764280072 -:1067F0008F82010810820004000000008F820104D3 -:1068000014820006240500058EE201A8244200013E -:10681000AEE201A808002A468EE201A8AC6800009A -:10682000AC6900048EE27264A467000EAC650018C7 -:10683000AC6200088EE204E8AC660010AC62001C9A -:10684000AF84010092E204EC14400036240A0001F7 -:106850008EE24E28000210C024424E3802E220216F -:106860008C8200001445001F000000008EE34E28BB -:106870008EE24E2C1062001B240300408C82000428 -:1068800024420001AC8200048EE24E2C8EE54E289C -:106890002442000110430007000000008EE24E2C4D -:1068A0002442000110A200050000000008002A3068 -:1068B0000000000014A00005000000008F82010805 -:1068C00024420020AF8201088F8201088C820004DC -:1068D0002C42001150400013AC80000008002A46F2 -:1068E000000000008EE24E282403004024420001F4 -:1068F00050430003000010218EE24E282442000184 -:10690000AEE24E288EE24E28000210C024424E38DD -:1069100002E2202124020005AC82000024020001D2 -:10692000AC8200041540000C30E5FFFF3C04000180 -:10693000248457483C050004AFA90010AFA0001400 -:106940008EE604E434A5F2370C00240330E7FFFFA1 -:1069500008002A72000000008EE2726400451021D7 -:10696000AEE272648EE2726C8EE372643C040001EB -:1069700034843800A2E004ED00451023AEE2726CCE -:10698000036410210062182B146000043C03FFFF15 -:106990008EE2726400431021AEE272648EE304E87A -:1069A00096E20458246300012442FFFF0062182489 -:1069B000AEE304E88EE304E88EE204E0146200052E -:1069C000000000008F8200602403FFF700431024C2 -:1069D000AF8200608FBF001803E0000827BD0020D1 -:1069E00027BDFFE0AFBF001CAFB000188F820100D1 -:1069F0008EE34E2C8F8201048F8501082402004013 -:106A00002463000150620003000010218EE24E2C2E -:106A100024420001AEE24E2C8EE24E2C8EE34E2C30 -:106A2000000210C024424E3802E220218EE24E289D -:106A30008C8700041462000700A030218F820108B7 -:106A400024420020AF8201088F82010808002AA298 -:106A5000AC8000008EE24E2C240300402442000152 -:106A600050430003000010218EE24E2C244200010E -:106A7000000210C024424E3802E220218C82000421 -:106A80008F8301080002114000621821AF830108C2 -:106A9000AC8000008CC200182443FFFE2C6200135F -:106AA000104000C1000310803C01000100220821B9 -:106AB0008C22577000400008000000008EE204F0B5 -:106AC00000471021AEE204F08EE204F08F43023C56 -:106AD0000043102B144000BE000000008EE304E4CD -:106AE0008EE204F8506200BAA2E004F48F83012021 -:106AF000276238002466002000C2102B504000019D -:106B0000276630008F82012810C2000400000000B8 -:106B10008F82012414C20007000000008EE201A44D -:106B20000000802124420001AEE201A408002B12E3 -:106B30008EE201A48EE204E4AC62001C8EE404B098 -:106B40008EE504B42462001CAC6200082402000834 -:106B5000A462000E24020011AC620018AC640000B4 -:106B6000AC6500048EE204C4AC620010AF86012064 -:106B700092E24E2014400037241000018EE24E3085 -:106B8000000210C02442503802E220218C83000011 -:106B9000240200121462001F000000008EE34E3039 -:106BA0008EE24E341062001B240300408C820004ED -:106BB00024420001AC8200048EE24E348EE54E3059 -:106BC0002442000110430007000000008EE24E3412 -:106BD0002442000110A200050000000008002AFC69 -:106BE0000000000014A00005000000008F820128B2 -:106BF00024420020AF8201288F8201288C82000469 -:106C00002C42001150400013AC80000008002B12F1 -:106C1000000000008EE24E302403004024420001B8 -:106C200050430003000010218EE24E302442000148 -:106C3000AEE24E308EE24E30000210C02442503898 -:106C400002E2202124020012AC8200002402000192 -:106C5000AC8200045600000B241000018EE204E414 -:106C60003C04000124845754AFA00014AFA20010CC -:106C70008EE606088F4702283C0500090C00240315 -:106C800034A5F006160000032402000108002B7151 -:106C9000A2E204F48EE2017024420001AEE201702F -:106CA0008EE201708EE204E4A2E004F4AEE004F0AF -:106CB000AEE204F88F42023C50400045AEE07274F0 -:106CC0008EE2018424420001AEE201848EE201845E -:106CD00008002B71AEE072748EE2050424030040BC -:106CE0002442000150430003000010218EE20504FD -:106CF00024420001AEE205048EE205048CC30018B4 -:106D000000021080005710218C4405082402000363 -:106D10001462000F000000003C0200010057102127 -:106D2000904283B110400014000000008EE201D0B8 -:106D30008EE3524000441021AEE201D08EE201D831 -:106D400000641821306300FF08002B59AEE3524065 -:106D50008EE201CC8EE30E1000441021AEE201CC95 -:106D60008EE201D800641821306301FFAEE30E10FB -:106D700000441021AEE201D88EE20000344200400F -:106D800008002B71AEE200008EE2014C3C010001D4 -:106D900000370821A02083E024420001AEE2014C2C -:106DA00008002B718EE2014C94C7000E8CC2001CAF -:106DB0003C04000124845760AFA60014AFA2001069 -:106DC0008CC600183C0500080C00240334A50910EB -:106DD0008FBF001C8FB0001803E0000827BD002003 -:106DE00027BDFF98AFBF0060AFBE005CAFB60058D4 -:106DF000AFB50054AFB40050AFB3004CAFB20048D1 -:106E0000AFB10044AFB000408F8301088F8201040E -:106E1000AFA00024106203E7AFA0002C3C1E0001CD -:106E200037DE38003C0BFFFF8F9301088E6200189D -:106E30008F8301042443FFFE2C620014104003CF13 -:106E4000000310803C010001002208218C2257C061 -:106E500000400008000000009663000E8EE2725CA5 -:106E60008EE404F000431021AEE2725C8E63001CDD -:106E700096E2045824840001AEE404F02463000187 -:106E80002442FFFF00621824AEE304E48F42023C78 -:106E90000082202B148003B9000000008F830120A2 -:106EA000276238002466002000C2102B50400001E9 -:106EB000276630008F82012810C200040000000005 -:106EC0008F82012414C20007000000008EE201A49A -:106ED0000000802124420001AEE201A408002BFE44 -:106EE0008EE201A48EE204E4AC62001C8EE404B0E5 -:106EF0008EE504B42462001CAC6200082402000881 -:106F0000A462000E24020011AC620018AC64000000 -:106F1000AC6500048EE204C4AC620010AF860120B0 -:106F200092E24E2014400037241000018EE24E30D1 -:106F3000000210C02442503802E220218C8300005D -:106F4000240200121462001F000000008EE34E3085 -:106F50008EE24E341062001B240C00408C82000430 -:106F600024420001AC8200048EE24E348EE34E30A7 -:106F700024420001104C0007000000008EE24E3455 -:106F800024420001106200050000000008002BE808 -:106F90000000000014600005000000008F8201283E -:106FA00024420020AF8201288F8201288C820004B5 -:106FB0002C42001150400013AC80000008002BFE52 -:106FC000000000008EE24E30240C004024420001FC -:106FD000504C0003000010218EE24E30244200018C -:106FE000AEE24E308EE24E30000210C024425038E5 -:106FF00002E2202124020012240C0001AC820000D5 -:10700000AC8C00045600000D241000018EE204E454 -:107010003C04000124845754AFA00014AFA2001018 -:107020008EE606088F4702283C05000934A5F006C5 -:107030000C002403AFAB00388FAB00381200030AFA -:10704000240C000108002F1900000000966C001CA1 -:10705000AFAC002C9662001E3C0C8000AFAC00244C -:10706000AE62001C8E75001C8EE204FC8EE404FCF3 -:1070700000151900006210218C52000C92E27B98DE -:10708000006418219476000A1440000332C2000202 -:10709000AEF27BA4AEF57B9C1040004B000080213B -:1070A00096E2045A304200021040004700000000FF -:1070B0008E63001C8EE204FC00032100008210217C -:1070C0008C42000C037E1821244200220043102B26 -:1070D0001440000A240500148EE204FC00821021F2 -:1070E0008C44000CAFAB00380C002F752484000ECC -:1070F0008FAB003808002C523050FFFF8EE204FCAA -:10710000008210218C42000C9450000E9443001019 -:10711000944400129445001402038021020480214B -:107120000205802194430016944400189445001AE7 -:107130000203802102048021020580219443001C67 -:107140009444001E94420020020380210204802106 -:107150000202802100101C023202FFFF0062802127 -:107160008E63001C8EE204FC001024020003290040 -:1071700000A210218C43000C3202FFFF008280210C -:10718000037E1021246300180062182B146000098C -:10719000000000008EE204FC00A210218C43000CD1 -:1071A000001010273C01FFFF0023082108002C6F6E -:1071B000A42200188EE204FC00A210218C43000CD3 -:1071C00000101027A462001896E2045A00008821DB -:1071D00030420008144000630000A0218E63001CB0 -:1071E0008EE204FC0003310000C210218C42000C2E -:1071F000037E1821244200220043102B1440003546 -:10720000000000008EE204FC00C210218C42000C41 -:1072100024470010037E102100E2102B5040000193 -:1072200000EB38218EE204FC94F1000000C2102132 -:107230008C42000C24470016037E102100E2102B24 -:10724000144000022634FFEC00EB38218EE204FCEF -:1072500090E3000100C210218C42000C2447001A68 -:10726000037E102100E2102B1440000202838821CB -:1072700000EB382194E2000024E70002022288217A -:10728000037E102100E2102B5040000100EB38215A -:1072900094E2000024E7000202228821037E1021EC -:1072A00000E2102B5040000100EB382194E2000076 -:1072B00024E7000202228821037E102100E2102B25 -:1072C0005040000100EB382194E2000008002CD06F -:1072D000022288218EE204FC00C210218C43000CA3 -:1072E0008EE204FC947100108EE304FC00C21021B5 -:1072F0008C44000C00C318218C62000C2634FFEC77 -:10730000908400178EE304FC9442001A02848821C2 -:1073100000C318218C65000C8EE304FC0222882136 -:107320008EE204FC00C3182100C210218C44000C22 -:107330008C62000C94A3001C9484001E94420020D4 -:1073400002238821022488210222882100111C02A4 -:107350003222FFFF0062882100111C023222FFFF4F -:107360000062882132C20001104000B2000000001B -:1073700096E2045A30420001104000AE32C2008052 -:10738000104000080000000092E27B9814400005C5 -:1073900000000000240C0001A2EC7B98AEF57B9C61 -:1073A000AEF27BA48EE304FC001511000043102113 -:1073B0008C47000C037E182124E2000E0043102BA2 -:1073C0001440000800E020212405000E0C002F7559 -:1073D000AFAB00383042FFFF8FAB003808002D09FB -:1073E0000202802194E6000024E7000294E50000F8 -:1073F00024E7000294E3000024E7000294E2000086 -:1074000024E7000294E4000024E700020206802141 -:1074100002058021020380210202802194E2000003 -:1074200094E30002020480210202802102038021F1 -:1074300000101C023202FFFF0062802100101C02BB -:107440003202FFFF8EE47B9C0062802114950004D1 -:107450003205FFFF9662001608002D17005120210B -:107460009662001600542021000414023083FFFFAE -:1074700000432021008520230004140200822021E3 -:107480003084FFFF508000013404FFFF8EE27BA4B4 -:1074900024430017037E10210062102B504000018E -:1074A000006B182190630000240200111462003167 -:1074B000240200068EE27BA4037E182124420028C9 -:1074C0000043102B14400018000000008EE27B9C4B -:1074D00012A2000A32C201008EE27BA43C01FFFF2F -:1074E00000220821942200280082202100041C028E -:1074F0003082FFFF0062202132C2010014400004EC -:107500000004102792E27B98144000020004102728 -:107510003044FFFF8EE27BA43C01FFFF00220821E4 -:1075200008002D8AA42400288EE27B9C12A2000869 -:1075300032C201008EE27BA4944200280082202106 -:1075400000041C023082FFFF0062202132C20100D1 -:10755000144000040004102792E27B9814400002BB -:10756000000410273044FFFF8EE27BA408002D8A20 -:10757000A44400281462002F037E18218EE27BA40D -:10758000244200320043102B144000180000000079 -:107590008EE27B9C12A2000A32C201008EE27BA422 -:1075A0003C01FFFF002208219422003200822021AA -:1075B00000041C023082FFFF0062202132C2010061 -:1075C000144000040004102792E27B98144000024B -:1075D000000410273044FFFF8EE27BA43C01FFFF34 -:1075E0000022082108002D8AA42400328EE27B9C10 -:1075F00012A2000832C201008EE27BA49442003243 -:107600000082202100041C023082FFFF0062202142 -:1076100032C20100144000040004102792E27B985B -:1076200014400002000410273044FFFF8EE27BA4C8 -:10763000A44400328FAC00241180002C037E18215A -:107640008E420000AE42FFFC2642000A0043102B8F -:107650001440001B3403810026430004037E1021E4 -:107660000062102B1440000300602021006B1821E1 -:10767000006020218C62000024630004AE42000000 -:10768000037E10210062102B50400001006B182176 -:107690008C620000AC82000034028100A462000011 -:1076A00024630002037E10210062102B5040000171 -:1076B000006B182197AC002E08002DB4A46C0000BC -:1076C0008E4200048E440008A643000897AC002EAA -:1076D000A64C000AAE420000AE4400049662000EC2 -:1076E0002652FFFC24420004A662000E9662000EA1 -:1076F0008EE3725C00621821AEE3725CAFB20018D8 -:107700008EE3725CAFA3001C8EE2725C2C42003CE4 -:1077100010400004246200012403FFFE00431024F3 -:10772000AFA2001C32C200801040000C32C2010027 -:107730008EE27BA824430001000210C000571021F4 -:10774000AEE37BA88FA300188FA4001CAC437BACD6 -:10775000AC447BB008002EA0AEE0725C104000721A -:10776000000000008EE27BA824430001000210C04C -:1077700000571021AEE37BA88FA300188FA4001C34 -:10778000AC437BACAC447BB08EE27BA81040006382 -:1077900000004821000050218F8200F0244800089A -:1077A000276218000102102B5040000127681000CA -:1077B0008F8200F415020007000000008EE201B481 -:1077C0000000802124420001AEE201B408002DFA3D -:1077D0008EE201B48F8300F02410000101571021C4 -:1077E0008C447BAC8C457BB0AC640000AC65000481 -:1077F000AF8800F01600000602EA10218EE2008831 -:1078000024420001AEE2008808002E3F8EE200888C -:107810008C427BB08EE400E08EE500E48EE67B9C3B -:10782000004018210000102100A3282100A3382BBC -:1078300000822021008720218EE204FC00C9302133 -:1078400000063100AEE400E0AEE500E400C2302105 -:1078500094C2000A240C00020002114230430003CB -:10786000106C00162862000310400005240C000173 -:10787000106C00080000000008002E3F000000000F -:10788000240C0003106C00170000000008002E3FBD -:10789000000000008EE200E88EE300EC24630001AB -:1078A0002C64000100441021AEE200E8AEE300ECDD -:1078B0008EE200E808002E3F8EE300EC8EE200F03E -:1078C0008EE300F4246300012C64000100441021C5 -:1078D000AEE200F0AEE300F48EE200F008002E3FCE -:1078E0008EE300F48EE200F88EE300FC24630001D6 -:1078F0002C64000100441021AEE200F8AEE300FC6D -:107900008EE200F88EE300FC8EE27BA825290001C0 -:107910000122102B1440FFA0254A0008A2E07B980A -:1079200008002E9FAEE07BA88F8200F0244700085D -:107930002762180000E2102B50400001276710005A -:107940008F8200F414E20007000000008EE201B410 -:107950000000802124420001AEE201B408002E5D47 -:107960008EE201B48F8200F0241000018FA3001872 -:107970008FA4001CAC430000AC440004AF8700F0AF -:1079800016000007000000008EE20088244200017B -:10799000AEE200888EE2008808002EA0AEE0725CA5 -:1079A0008EE2725C8EE400E08EE500E4240C0002BE -:1079B000004018210000102100A3282100A3302B33 -:1079C000008220210086202100161142304300034E -:1079D000AEE400E0AEE500E4106C00172C6200039A -:1079E00010400005240C0001106C0008000000008D -:1079F00008002EA0AEE0725C240C0003106C00198D -:107A00000000000008002EA0AEE0725C8EE200E8EC -:107A10008EE300EC246300012C640001004410217B -:107A2000AEE200E8AEE300EC8EE200E88EE300ECAC -:107A300008002EA0AEE0725C8EE200F08EE300F44F -:107A4000246300012C64000100441021AEE200F028 -:107A5000AEE300F48EE200F08EE300F408002EA006 -:107A6000AEE0725C8EE200F88EE300FC246300015D -:107A70002C64000100441021AEE200F8AEE300FCEB -:107A80008EE200F88EE300FCAEE0725C8E62001CB9 -:107A900096E304588EE404F0244200012463FFFFBF -:107AA0000043102424840001AEE204E4AEE404F0B8 -:107AB0008F42023C0082202B148000B000000000A6 -:107AC0008F830120276238002466002000C2102B1B -:107AD00050400001276630008F82012810C2000448 -:107AE000000000008F82012414C200070000000083 -:107AF0008EE201A40000802124420001AEE201A434 -:107B000008002F078EE201A48EE204E4AC62001CA0 -:107B10008EE404B08EE504B42462001CAC6200085C -:107B200024020008A462000E24020011AC620018B6 -:107B3000AC640000AC6500048EE204C4AC620010CA -:107B4000AF86012092E24E2014400037241000013D -:107B50008EE24E30000210C02442503802E2202152 -:107B60008C830000240200121462001F0000000039 -:107B70008EE34E308EE24E341062001B240C004027 -:107B80008C82000424420001AC8200048EE24E3458 -:107B90008EE34E3024420001104C0007000000002C -:107BA0008EE24E3424420001106200050000000005 -:107BB00008002EF100000000146000050000000025 -:107BC0008F82012824420020AF8201288F82012861 -:107BD0008C8200042C42001150400013AC80000045 -:107BE00008002F07000000008EE24E30240C0040F9 -:107BF00024420001504C0003000010218EE24E3060 -:107C000024420001AEE24E308EE24E30000210C03F -:107C10002442503802E2202124020012240C0001E8 -:107C2000AC820000AC8C00045600000D2410000152 -:107C30008EE204E43C04000124845754AFA00014F5 -:107C4000AFA200108EE606088F4702283C05000907 -:107C500034A5F0060C002403AFAB00388FAB00381E -:107C600016000003240C000108002F5CA2EC04F4B1 -:107C70008EE2017024420001AEE201708EE20170DA -:107C80008EE204E4A2E004F4AEE004F0AEE072742C -:107C9000AEE204F88F42023C1040003800000000C1 -:107CA0008EE2018424420001AEE2018408002F5CD0 -:107CB0008EE201848EE20504240C0040244200017F -:107CC000504C0003000010218EE205042442000104 -:107CD000AEE205048EE205048E630018240C000356 -:107CE0000002108000571021146C000F8C4405080E -:107CF0003C02000100571021904283B11040001453 -:107D0000000000008EE201D08EE3524000441021BA -:107D1000AEE201D08EE201D800641821306300FF8A -:107D200008002F4FAEE352408EE201CC8EE30E10DE -:107D300000441021AEE201CC8EE201D8006418218B -:107D4000306301FFAEE30E1000441021AEE201D813 -:107D50008EE200003442004008002F5CAEE20000DA -:107D60008EE2014C3C01000100370821A02083E095 -:107D700024420001AEE2014C8EE2014C8F820108E8 -:107D800024420020AF8201088F8201088F820108FF -:107D9000276330000043102B1440000227622800A4 -:107DA000AF8201088F8301088F8201041462FC1ED8 -:107DB000000000008FBF00608FBE005C8FB60058CF -:107DC0008FB500548FB400508FB3004C8FB2004871 -:107DD0008FB100448FB0004003E0000827BD006869 -:107DE0000005284310A0000D000030213C030001D5 -:107DF000346338003C07FFFF036310210082102B1F -:107E00005040000100872021948200002484000259 -:107E100024A5FFFF14A0FFF800C2302100061C02B9 -:107E200030C2FFFF0062302100061C0230C2FFFF9B -:107E30000062302103E0000830C2FFFF27BDFF8849 -:107E4000240F0001AFBF0070AFBE006CAFB600687A -:107E5000AFB50064AFB40060AFB3005CAFB2005820 -:107E6000AFB10054AFB00050A3A00027AFAF002CBB -:107E70008EE204D400008021304200011440002A28 -:107E8000A3A000378F8700E08F8800C48F8200E8AE -:107E900000E220232C8210005040000124841000B6 -:107EA000000420C2008018218EE400C88EE500CCBA -:107EB0000000102100A3282100A3302B00822021E4 -:107EC00000862021AEE400C8AEE500CC8F8300C858 -:107ED0003C02000A3442EFFF010320230044102B30 -:107EE000104000033C02000A3442F00000822021CE -:107EF000008018218EE400C08EE500C4000010212F -:107F000000A3282100A3302B0082202100862021FD -:107F1000AEE400C0AEE500C4AF8800C8AF8700E49F -:107F2000080034CCAF8700E83C0200010057102164 -:107F3000904283C01040000B000000003C14000180 -:107F40000297A0218E9483C43C13000102779821EC -:107F50008E7383C83C1200010257902108003193B0 -:107F60008E5283CC8F8300E08F8200E410430007A1 -:107F7000000088218F8200E4241100018C4300005E -:107F80008C440004AFA30018AFA4001C1620000E00 -:107F90003C02FFFF8F8200C4AFA200108F8200C896 -:107FA0003C04000124845870AFA200148F8600E0C6 -:107FB0008F8700E43C0500060C00240334A5F00084 -:107FC000080034CC000000008FA3001C8FB2001802 -:107FD0003074FFFF2694FFFC00621024104000580C -:107FE000024098213C020080006210241040000AE8 -:107FF0003C0400408EE2007C24420001AEE2007CA2 -:108000008EE2007C8EE201FC24420001AEE201FC23 -:10801000080034C68EE201FC3C0600043C0B000163 -:108020003C0A00023C0500103C0900088EE200807A -:108030003C0800203407800024420001AEE20080AA -:108040008EE200808FA2001C0044182410660021DC -:1080500000C3102B1440000700000000106B00113B -:1080600000000000106A0015000000000800304900 -:10807000000420421065002300A3102B14400005CB -:1080800000000000106900190000000008003049DD -:108090000004204210680021000000000800304960 -:1080A000000420428EE2003424420001AEE200349B -:1080B0008EE2003408003049000420428EE201ECD8 -:1080C00024420001AEE201EC8EE201EC08003049EE -:1080D000000420428EE201F024420001AEE201F0F1 -:1080E0008EE201F008003049000420428EE201F4E3 -:1080F00024420001AEE201F48EE201F408003049AE -:10810000000420428EE2003024420001AEE2003042 -:108110008EE2003008003049000420428EE201F86F -:1081200024420001AEE201F88EE201F80004204290 -:108130001087047C000000000800300E00000000E2 -:108140003C02000100571021904283B21440008489 -:10815000240200013C03000100771821906383B3DF -:108160001462007F3C0201008E4300000062102474 -:108170001040006F2402FFFF14620005241000016C -:10818000964300043402FFFF1062007500000000F7 -:1081900092E204D814400072000000003C0200018A -:1081A000005710218C4283B4284200051040002063 -:1081B000000038213C020001005710218C4283B49A -:1081C000184000160000282196660000000520C017 -:1081D000009710219442777E1446000900971021E1 -:1081E0009443778096620002146200050097102184 -:1081F00094437782966200045062000824070001CD -:108200003C020001005710218C4283B424A50001D8 -:1082100000A2102A5440FFEE000520C030E200FF0B -:108220001040044000000000080030D500000000AD -:10823000024020210C0022FE240500063044001FCD -:10824000000428C002E510219442727C30424000B4 -:108250001440043400B710219443727E96620000EB -:108260001462000B000418C000B710219443728000 -:108270009662000214620006000418C000B71021C4 -:10828000944372829662000410620035000418C0A4 -:1082900002E310219442727C304280001440042199 -:1082A00002E31021944B727C96670000000B28C0FB -:1082B00000B710219442737E080030B700003021CF -:1082C000000420C002E410219443737C02E41021D6 -:1082D000944B737C3063800014600010000B28C046 -:1082E00000B710219442737E1447FFF501602021EE -:1082F00000B7102194437380966200025462FFF12C -:10830000000420C000B710219443738296620004D9 -:108310005462FFEC000420C02406000130C200FFBC -:108320001040040000000000080030D500000000EC -:108330009743020296420000146203FA0000000014 -:108340009743020496420002146203F60000000004 -:108350009743020696420004146203F200000000F4 -:10836000924200003A030001304200010043102411 -:10837000104000742402FFFF8E63000014620004AA -:108380003402FFFF966300041062006F240F0002A6 -:108390003C02000100571021904283B21440006A51 -:1083A000240F000392E204D854400068AFAF002CC1 -:1083B0003C020001005710218C4283B42842000582 -:1083C00010400020000038213C020001005710211D -:1083D0008C4283B4184000160000282196660000E5 -:1083E000000520C0009710219442777E14460009B2 -:1083F0000097102194437780966200021462000572 -:10840000009710219443778296620004506200081E -:10841000240700013C020001005710218C4283B464 -:1084200024A5000100A2102A5440FFEE000520C040 -:1084300030E200FF14400044240F0003080034C65B -:1084400000000000024020210C0022FE240500064E -:108450003044001F000428C002E510219442727CC1 -:1084600030424000144003AF00B710219443727EA5 -:10847000966200001462000B000418C000B71021BF -:10848000944372809662000214620006000418C0D1 -:1084900000B7102194437282966200041062002794 -:1084A000000418C002E310219442727C3042800024 -:1084B0001440039C02E31021944B727C96670000E9 -:1084C000000B28C000B710219442737E0800313C95 -:1084D00000003021000420C002E410219443737C8A -:1084E00002E41021944B737C306380001460001010 -:1084F000000B28C000B710219442737E1447FFF58B -:108500000160202100B7102194437380966200021D -:108510005462FFF1000420C000B71021944373821D -:10852000966200045462FFEC000420C0240600019F -:1085300030C200FF1040037B000000000800314FF4 -:10854000240F0003240F0001AFAF002C8F42026004 -:108550000054102B1040003A000000008F8300E40C -:108560008F8200E01062000324630008AF8300E400 -:10857000AF8300E88EE400C08EE500C402801821BD -:108580000000102100A3282100A3302B008220210D -:1085900000862021AEE400C0AEE500C48EE20058A3 -:1085A00024420001AEE200588EE200588EE2007CC8 -:1085B00024420001AEE2007C8EE2007C8F8200E06B -:1085C000AFA200108F8200E43C040001248458789C -:1085D000AFA200148FA600188FA7001C3C05000650 -:1085E0000C00240334A5F003080034CC0000000084 -:1085F0008EE25240AFA200108EE252443C040001D1 -:1086000024845884AFA200148EE60E108EE70E1854 -:108610003C0500060C00240334A5F0028EE201C0E4 -:1086200024420001AEE201C08EE200008EE301C0F0 -:108630002403FFBF0043102408003470AEE20000A2 -:1086400096E204680054102B104000030000000064 -:10865000240F0001A3AF0027128003012416000796 -:1086600024150040241E0001240E00128EE2724CDC -:108670008F43028024420001304207FF106202D380 -:108680000000000093A2002710400014000000002A -:108690008EE352408EE252441062000926ED5244AD -:1086A0008EE652448EE35244000211402442524866 -:1086B00002E2802124630001080031BF306B00FF1B -:1086C00092E272481440FFCA000000008EE201E00E -:1086D00024420001AEE201E08EE201E08EE30E10E2 -:1086E0008EE20E181062FFC226ED0E188EE60E18EE -:1086F0008EE30E180002114024420E2002E2802177 -:1087000024630001306B01FF96E2046A30420010DE -:1087100010400019000000009642000C340F810048 -:10872000144F0015000000003C020001005710210A -:10873000904283C014400010000000009642000EDA -:10874000A60200168E4200088E4300048E440000EC -:108750002694FFFCAE42000CAE430008AE44000479 -:108760009602000E26730004240F0001A3AF003709 -:1087700034420200A602000E8E0200008E030004A6 -:108780003C04000134843800306A0007026A9823F0 -:10879000036410210262102B10400005028AA02100 -:1087A00002641023036218233C0200200043982334 -:1087B000268200072404FFF89603000A0044602480 -:1087C000006A1821006C102B104000020180382133 -:1087D00000603821AE1300188F88012024E20007C2 -:1087E0000044382427623800250900200122102B7C -:1087F00050400001276930008F82012811220004B7 -:10880000000000008F82012415220007014018217A -:108810008EE201A40000882124420001AEE201A4FE -:108820000800324C8EE201A48E0400008E05000484 -:1088300000001021AD130008A507000EAD160018AA -:10884000AD06001C00A3302B00A3282300822023A8 -:1088500000862023AD040000AD0500048EE204C0B4 -:10886000AD020010AF89012092E24E201440003387 -:10887000241100018EE24E30000210C02442503814 -:1088800002E220218C8200001456001F000000002C -:108890008EE34E308EE24E341062001B000000006A -:1088A0008C82000424420001AC8200048EE24E342B -:1088B0008EE34E30244200011055000700000000F6 -:1088C0008EE24E34244200011062000500000000D8 -:1088D00008003239000000001460000500000000AC -:1088E0008F82012824420020AF8201288F82012834 -:1088F0008C8200042C42001150400010AC8000001B -:108900000800324C000000008EE24E30244200018C -:1089100050550003000010218EE24E302442000129 -:10892000AEE24E308EE24E30000210C0244250388B -:1089300002E22021AC960000AC9E00041620001834 -:108940003C0500068E0200183C0400012484589067 -:10895000AFA200108E0200008E03000434A5F009BF -:10896000020030210C002403AFA3001493A20037AF -:1089700010400216340F81008E4200048E4300081E -:108980008E44000CA64F000CAE420000AE43000423 -:10899000AE4400089602001608003470A642000E8D -:1089A00014EC0168028A1823960C000A9603000E44 -:1089B000028A1023A602000A34620004A602000EF6 -:1089C0008F88012027623800250900200122102B02 -:1089D00014400002306AFFFF276930008F820128AF -:1089E00011220004000000008F82012415220007DC -:1089F000240400208EE201A400008821244200010A -:108A0000AEE201A4080032CA8EE201A48EE5724CE7 -:108A10008EE604908EE70494A504000E240400045E -:108A2000AD100008AD0400180005294000A0182171 -:108A30000000102100E3382100E3202B00C2302188 -:108A400000C43021AD060000AD0700048EE2724C78 -:108A5000AD02001C8EE204C4AD020010AF890120FB -:108A600092E24E2014400033241100018EE24E3079 -:108A7000000210C02442503802E220218C82000003 -:108A80001456001F000000008EE34E308EE24E347C -:108A90001062001B000000008C82000424420001D0 -:108AA000AC8200048EE24E348EE34E30244200014C -:108AB00010550007000000008EE24E3424420001F1 -:108AC0001062000500000000080032B7000000003E -:108AD00014600005000000008F820128244200205D -:108AE000AF8201288F8201288C8200042C42001161 -:108AF00050400010AC800000080032CA00000000A6 -:108B00008EE24E3024420001505500030000102137 -:108B10008EE24E3024420001AEE24E308EE24E3004 -:108B2000000210C02442503802E22021AC9600001E -:108B3000AC9E00041620000D00000000A60C000AE8 -:108B4000A60A000E8F820100AFA200108F820104DE -:108B50003C0400012484589C3C050006AFA200148C -:108B60008EE6724C0800343B34A5F00B3C0100014A -:108B700000370821A02083C0ADAB00008EE201D8F1 -:108B80008EE3724C2442FFFFAEE201D88EE201D8A0 -:108B900024630001306307FF26E2524415A2000659 -:108BA000AEE3724C8EE201D02442FFFFAEE201D070 -:108BB000080032EF8EE201D08EE201CC2442FFFFAA -:108BC000AEE201CC8EE201CC8F4202401040007335 -:108BD000000000008EE20E1C24420001AEE20E1CDA -:108BE0008F4302400043102B144001760000A02167 -:108BF0008F830120276238002466002000C2102BDA -:108C000050400001276630008F82012810C2000406 -:108C1000000000008F82012414C200070000000041 -:108C20008EE201A40000882124420001AEE201A4EA -:108C30000800334F8EE201A48EE2724CAC62001C3D -:108C40008EE404A88EE504AC2462001CAC6200082B -:108C500024020008A462000E24020011AC62001875 -:108C6000AC640000AC6500048EE204C4AC62001089 -:108C7000AF86012092E24E201440003324110001FF -:108C80008EE24E30000210C02442503802E2202111 -:108C90008C820000144E001F000000008EE34E3056 -:108CA0008EE24E341062001B000000008C82000433 -:108CB00024420001AC8200048EE24E348EE34E303A -:108CC0002442000110550007000000008EE24E34DF -:108CD0002442000110620005000000000800333C3F -:108CE0000000000014600005000000008F820128D1 -:108CF00024420020AF8201288F8201288C82000448 -:108D00002C42001150400010AC8000000800334F8E -:108D1000000000008EE24E30244200015055000356 -:108D2000000010218EE24E3024420001AEE24E30AF -:108D30008EE24E30000210C02442503802E2202160 -:108D4000AC8E0000AC9E00045620000D24110001E2 -:108D50008EE2724C3C040001248458A8AFA0001499 -:108D6000AFA200108EE6724C8F4702803C050009CE -:108D700034A5F0080C002403AFAE00488FAE0048C5 -:108D800056200001AEE00E1C8EE201882442000154 -:108D9000AEE20188080033C88EE201888F8301208B -:108DA000276238002466002000C2102B50400001CA -:108DB000276630008F82012810C2000400000000E6 -:108DC0008F82012414C20007000000008EE201A47B -:108DD0000000882124420001AEE201A4080033BA59 -:108DE0008EE201A48EE2724CAC62001C8EE404A8F8 -:108DF0008EE504AC2462001CAC620008240200086A -:108E0000A462000E24020011AC620018AC640000E1 -:108E1000AC6500048EE204C4AC620010AF86012091 -:108E200092E24E2014400033241100018EE24E30B5 -:108E3000000210C02442503802E220218C8200003F -:108E4000144E001F000000008EE34E308EE24E34C0 -:108E50001062001B000000008C820004244200010C -:108E6000AC8200048EE24E348EE34E302442000188 -:108E700010550007000000008EE24E34244200012D -:108E80001062000500000000080033A70000000089 -:108E900014600005000000008F8201282442002099 -:108EA000AF8201288F8201288C8200042C4200119D -:108EB00050400010AC800000080033BA00000000F1 -:108EC0008EE24E3024420001505500030000102174 -:108ED0008EE24E3024420001AEE24E308EE24E3041 -:108EE000000210C02442503802E22021AC8E000063 -:108EF000AC9E00041620000D000000008EE2724CB3 -:108F00003C040001248458A8AFA00014AFA20010B4 -:108F10008EE6724C8F4702803C05000934A5F008AC -:108F20000C002403AFAE00488FAE00488EE20174FF -:108F300024420001AEE201748EE201740800346E36 -:108F40000000A021960C000A0183102B5440000160 -:108F500001801821A603000A8F88012027623800AB -:108F6000250900200122102B504000012769300004 -:108F70008F82012811220004000000008F8201244A -:108F800015220007240400208EE201A4000088219D -:108F900024420001AEE201A40800342F8EE201A4B5 -:108FA0008EE5724C8EE604908EE70494A504000EC4 -:108FB00024040004AD100008AD0400180005294089 -:108FC00000A018210000102100E3382100E3202B2D -:108FD00000C2302100C43021AD060000AD070004FE -:108FE0008EE2724CAD02001C8EE204C4AD02001091 -:108FF000AF89012092E24E20144000332411000179 -:109000008EE24E30000210C02442503802E220218D -:109010008C8200001456001F000000008EE34E30CA -:109020008EE24E341062001B000000008C820004AF -:1090300024420001AC8200048EE24E348EE34E30B6 -:109040002442000110550007000000008EE24E345B -:109050002442000110620005000000000800341CDA -:109060000000000014600005000000008F8201284D -:1090700024420020AF8201288F8201288C820004C4 -:109080002C42001150400010AC8000000800342F2A -:10909000000000008EE24E302442000150550003D3 -:1090A000000010218EE24E3024420001AEE24E302C -:1090B0008EE24E30000210C02442503802E22021DD -:1090C000AC960000AC9E00041620001D00000000BD -:1090D000A60C000A8F820100AFA200108F8201044B -:1090E0003C0400012484589C3C050006AFA20014F7 -:1090F0008EE6724C34A5F00D0C00240302003821DA -:1091000093A2003710400031340F81008E420004DA -:109110008E4300088E44000CA64F000CAE420000A7 -:10912000AE430004AE44000896020016A642000EAC -:109130009602000E3042FDFF08003470A602000EB9 -:109140008EE201D82442FFFFAEE201D88EE201D8C0 -:109150008EE201CC3C04001F3C01000100370821D5 -:10916000A03E83C02442FFFFAEE201CC9603000A7A -:109170003484FFFF8EE201CC006A1821026398213B -:109180000093202B108000033C02FFF534421000B6 -:1091900002629821ADAB00008EE2724C24420001C5 -:1091A000304207FFAEE2724C8F4202401040000492 -:1091B0000283A0238EE20E1C24420001AEE20E1CAC -:1091C000A3A000271680FD290000000012800024C3 -:1091D000000000003C01000100370821AC3483C4CA -:1091E0003C01000100370821AC3383C83C01000179 -:1091F00000370821AC3283CC93A20037104000081E -:10920000000000003C020001005710218C4283CC7A -:10921000244200043C01000100370821AC2283CC29 -:109220008EE2724C8F43028024420001304207FFDD -:1092300014620006000000008EE201C42442000116 -:10924000AEE201C4080034CC8EE201C48EE201BC5F -:1092500024420001AEE201BC080034CC8EE201BC25 -:1092600097A4001E2484FFFC008018218EE400C017 -:109270008EE500C40000102100A3282100A3302B9C -:109280000082202100862021AEE400C0AEE500C4AB -:109290008FAF002C2402000211E2000F29E200032C -:1092A000144000172402000315E20015000000001E -:1092B0008EE200D08EE300D4246300012C64000110 -:1092C00000441021AEE200D0AEE300D48EE200D024 -:1092D000080034C68EE300D48EE200D88EE300DCB2 -:1092E000246300012C64000100441021AEE200D888 -:1092F000AEE300DC8EE200D8080034C68EE300DC6A -:109300008EE200C88EE300CC246300012C640001CF -:1093100000441021AEE200C8AEE300CC8EE200C8EB -:109320008EE300CC8F8300E48F8200E010620003A4 -:1093300024630008AF8300E4AF8300E88FBF0070B0 -:109340008FBE006C8FB600688FB500648FB400606C -:109350008FB3005C8FB200588FB100548FB00050B3 -:1093600003E0000827BD007827BDFFB0AFB500447B -:109370000000A821AFB0003000008021AFBF004C3A -:10938000AFB60048AFB40040AFB3003CAFB2003856 -:10939000AFB100348EE204D4241400013042000145 -:1093A0001440002A0000B0218F8700E08F8800C49D -:1093B0008F8200E800E220232C8210005040000140 -:1093C00024841000000420C2008018218EE400C80C -:1093D0008EE500CC0000102100A3282100A3302B33 -:1093E0000082202100862021AEE400C8AEE500CC3A -:1093F0008F8300C83C02000A3442EFFF01032023A0 -:109400000044102B104000033C02000A3442F000DC -:1094100000822021008018218EE400C08EE500C467 -:109420000000102100A3282100A3302B008220215E -:1094300000862021AEE400C0AEE500C4AF8800C8BD -:10944000AF8700E408003850AF8700E83C02000115 -:1094500000571021904283C01040000B0000000014 -:109460003C130001027798218E7383C43C110001E4 -:10947000023788218E3183C83C12000102579021A7 -:10948000080036E88E5283CC8F8300E08F8200E4A0 -:1094900010430007000048218F8200E424090001E6 -:1094A0008C4300008C440004AFA30018AFA4001C40 -:1094B0001520000E3C02FFFF8F8200C4AFA20010F7 -:1094C0008F8200C83C04000124845870AFA20014AD -:1094D0008F8600E08F8700E43C0500060C00240323 -:1094E00034A5F00008003850000000008FA3001CD5 -:1094F0008FB200183073FFFF2673FFFC0062102448 -:1095000010400058024088213C0200800062102474 -:109510001040000A3C0400408EE2007C244200011E -:10952000AEE2007C8EE2007C8EE201FC244200016F -:10953000AEE201FC0800384A8EE201FC3C06000461 -:109540003C0B00013C0A00023C0500103C090008ED -:109550008EE200803C080020340780002442000195 -:10956000AEE200808EE200808FA2001C004418242E -:109570001066002100C3102B1440000700000000FB -:10958000106B001100000000106A001500000000C0 -:1095900008003592000420421065002300A3102B20 -:1095A00014400005000000001069001900000000D0 -:1095B00008003592000420421068002100000000DD -:1095C00008003592000420428EE20034244200015B -:1095D000AEE200348EE200340800359200042042EE -:1095E0008EE201EC24420001AEE201EC8EE201ECDD -:1095F00008003592000420428EE201F0244200016E -:10960000AEE201F08EE201F0080035920004204243 -:109610008EE201F424420001AEE201F48EE201F494 -:1096200008003592000420428EE2003024420001FE -:10963000AEE200308EE20030080035920004204295 -:109640008EE201F824420001AEE201F88EE201F858 -:1096500000042042108702B70000000008003557C0 -:10966000000000003C02000100571021904283B22C -:1096700014400084240200013C03000100771821FB -:10968000906383B31462007F3C0201008E430000AC -:10969000006210241040006F2402FFFF14620005D6 -:1096A00024100001964300043402FFFF106200758D -:1096B0000000000092E204D8144000720000000094 -:1096C0003C020001005710218C4283B4284200055F -:1096D00010400020000038213C02000100571021FA -:1096E0008C4283B418400016000028219626000002 -:1096F000000520C0009710219442777E144600098F -:10970000009710219443778096220002146200058E -:10971000009710219443778296220004506200083B -:10972000240700013C020001005710218C4283B441 -:1097300024A5000100A2102A5440FFEE000520C01D -:1097400030E200FF1040027B000000000800361EDF -:1097500000000000024020210C0022FE240500062B -:109760003044001F000428C002E510219442727C9E -:10977000304240001440026F00B710219443727EC3 -:10978000962200001462000B000418C000B71021DC -:10979000944372809622000214620006000418C0EE -:1097A00000B71021944372829622000410620035A3 -:1097B000000418C002E310219442727C3042800001 -:1097C0001440025C02E310219448727C962700004A -:1097D000000828C000B710219442737E08003600AC -:1097E00000003021000420C002E410219443737C67 -:1097F00002E410219448737C3063800014600010F0 -:10980000000828C000B710219442737E1447FFF56A -:109810000100202100B7102194437380962200029A -:109820005462FFF1000420C000B7102194437382FA -:10983000962200045462FFEC000420C024060001BC -:1098400030C200FF1040023B000000000800361E3E -:1098500000000000974302029642000014620235A5 -:109860000000000097430204964200021462023195 -:109870000000000097430206964200041462022D85 -:1098800000000000924200003A0300013042000153 -:1098900000431024104000742402FFFF8E230000B8 -:1098A000146200043402FFFF962300041062006F6C -:1098B000241400023C02000100571021904283B2A0 -:1098C0001440006A2414000392E204D81440006794 -:1098D000000000003C020001005710218C4283B4BC -:1098E0002842000510400020000038213C02000101 -:1098F000005710218C4283B4184000160000282124 -:1099000096260000000520C0009710219442777E23 -:109910001446000900971021944377809622000294 -:109920001462000500971021944377829622000468 -:1099300050620008240700013C020001005710217A -:109940008C4283B424A5000100A2102A5440FFEEEB -:10995000000520C030E200FF14400044241400033E -:109960000800384A00000000024020210C0022FEBE -:10997000240500063044001F000428C002E5102121 -:109980009442727C30424000144001EA00B710213A -:109990009443727E962200001462000B000418C0EB -:1099A00000B71021944372809622000214620006D0 -:1099B000000418C000B7102194437282962200045C -:1099C00010620027000418C002E310219442727C48 -:1099D00030428000144001D702E310219448727C89 -:1099E00096270000000828C000B710219442737E1B -:1099F0000800368500003021000420C002E4102158 -:109A00009443737C02E410219448737C306380009B -:109A100014600010000828C000B710219442737E23 -:109A20001447FFF50100202100B7102194437380F3 -:109A3000962200025462FFF1000420C000B71021FA -:109A400094437382962200045462FFEC000420C009 -:109A50002406000130C200FF104001B600000000E3 -:109A60000800369824140003241400018F42026079 -:109A70000053102B10400049000000008F8300E4C9 -:109A80008F8200E01062000324630008AF8300E4CB -:109A9000AF8300E88EE400C08EE500C402601821A8 -:109AA0000000102100A3282100A3302B00822021D8 -:109AB00000862021AEE400C0AEE500C48EE200586E -:109AC00024420001AEE200588EE200588EE2007C93 -:109AD00024420001AEE2007C8EE2007C8F8200E036 -:109AE000AFA200108F8200E43C0400012484587867 -:109AF000AFA200148FA600188FA7001C3C0500061B -:109B00000C00240334A5F0030800385000000000C6 -:109B10008EE25240AFA200108EE252443C0400019B -:109B200024845884AFA200148EE60E108EE70E181F -:109B30000C00240334A5F0028EE201C0244200018F -:109B4000AEE201C08EE200008EE301C02403FFBF3D -:109B500000431024080037F8AEE200008EE25240C5 -:109B6000AFA200108EE252443C04000124845884C9 -:109B7000AFA200148EE60E108EE70E183C0500060C -:109B80000C00240334A5F0028EE201C0244200013F -:109B9000AEE201C0080037F88EE201C096E2046828 -:109BA0000053102B544000013C158000126001311D -:109BB0003C0C001F358CFFFF8EE2724C8F430280FD -:109BC00024420001304207FF10620108000000003B -:109BD00012A00014000000008EE352408EE25244B6 -:109BE0001062000926EE52448EEB52448EE352443A -:109BF000000211402442524802E280212463000105 -:109C000008003712306800FF92E272481440FFC02B -:109C10003C0500068EE201E024420001AEE201E0D4 -:109C20008EE201E08EE30E108EE20E181062FFCB82 -:109C300026EE0E188EEB0E180000A8218EE30E18EB -:109C40000002114024420E2002E280212463000120 -:109C5000306801FF96E2046A30420010104000179D -:109C6000340281009643000C1462001400000000CE -:109C70003C02000100571021904283C01440000FA5 -:109C8000000000009642000EA60200168E42000858 -:109C90008E4300048E4400002673FFFCAE42000C8D -:109CA000AE430008AE4400049602000E26310004C4 -:109CB0002416000134420200A602000E9603000A98 -:109CC000026050210073102B1040000202606821D6 -:109CD000006050212D42003D1040002A0000382134 -:109CE0009623000C2402080054620027AE110018CD -:109CF0003C02000100571021904283C054400022D2 -:109D0000AE110018262200170182102B10400013FC -:109D1000000000003C02FFF5005110219042101796 -:109D2000384300062C630001384200112C42000128 -:109D30000062182510600013262200100182102BEB -:109D40001040000E000000003C07FFF500F1382134 -:109D500094E710100800375E24E7000E92220017E7 -:109D6000384300062C630001384200112C420001E8 -:109D70000062182550600004AE11001896270010EC -:109D800024E7000EAE1100183C020001005710211C -:109D9000904283C00002102B14E0000200024EC06B -:109DA000014038218F83012027623800246600207B -:109DB00000C2102B50400001276630008F8201281E -:109DC00010C20004000000008F82012414C20007AA -:109DD0002402000B8EE201A400004821244200016D -:109DE000AEE201A4080037BF8EE201A48E04000099 -:109DF0008E050004AC62001801751025004910257D -:109E0000AC710008A467000EAC62001CAC640000DA -:109E1000AC6500048EE204C0AC620010AF86012085 -:109E200092E24E2014400038240900018EE24E30A8 -:109E3000000210C02442503802E220218C8300002E -:109E40002402000714620020000000008EE34E3060 -:109E50008EE24E341062001C000000008C82000470 -:109E600024420001AC8200048EE34E348EE54E3075 -:109E7000240200402463000110620007000000007B -:109E80008EE24E342442000110A2000500000000C2 -:109E9000080037A90000000014A000050000000021 -:109EA0008F82012824420020AF8201288F8201285E -:109EB0008C8200042C42001150400013AC80000042 -:109EC000080037BF000000008EE24E30240300403F -:109ED0002442000150430003000010218EE24E3066 -:109EE00024420001AEE24E308EE24E30000210C03D -:109EF0002442503802E2202124020007AC820000F4 -:109F000024020001AC820004152000183C05000664 -:109F10008E0200183C04000124845890AFA2001067 -:109F20008E0200008E03000434A5F00902003021E7 -:109F30000C002403AFA3001432C200FF1040002B1A -:109F4000340281008E4300048E4400088E45000CCC -:109F5000A642000CAE430000AE440004AE4500082B -:109F600096020016080037F8A642000E154D000AAA -:109F7000000000009602000EA613000A34420004FE -:109F8000A602000E3C01000100370821A02083C07A -:109F9000080037F6000098219604000A0093102B61 -:109FA00010400002026018210080182124020001E4 -:109FB000A603000A3C01000100370821A02283C04B -:109FC0009604000A022488210191102B10400003FE -:109FD0003C02FFF5344210000222882102649823DB -:109FE0000000A8211660FEF4ADC800001260002138 -:109FF00032C200FF3C01000100370821AC3383C4AA -:10A000003C01000100370821AC3183C83C0100014C -:10A010000037082110400008AC3283CC3C0200011C -:10A02000005710218C4283CC244200043C010001E3 -:10A0300000370821AC2283CC8EE2724C8F43028021 -:10A040002442000114620006000000008EE201C4F8 -:10A0500024420001AEE201C4080038508EE201C47F -:10A060008EE201BC24420001AEE201BC080038507F -:10A070008EE201BC97A4001E2484FFFC00801821FE -:10A080008EE400C08EE500C40000102100A328214A -:10A0900000A3302B00822021008620212402000210 -:10A0A000AEE400C0AEE500C41282000F2A820003B5 -:10A0B000144000172402000316820015000000005F -:10A0C0008EE200D08EE300D4246300012C640001F2 -:10A0D00000441021AEE200D0AEE300D48EE200D006 -:10A0E0000800384A8EE300D48EE200D88EE300DC0C -:10A0F000246300012C64000100441021AEE200D86A -:10A10000AEE300DC8EE200D80800384A8EE300DCC3 -:10A110008EE200C88EE300CC246300012C640001B1 -:10A1200000441021AEE200C8AEE300CC8EE200C8CD -:10A130008EE300CC8F8300E48F8200E01062000386 -:10A1400024630008AF8300E4AF8300E88FBF004CB6 -:10A150008FB600488FB500448FB400408FB3003CE9 -:10A160008FB200388FB100348FB0003003E00008A8 -:10A1700027BD005027BDFF90AFB600600000B021A2 -:10A18000AFBF0068AFBE0064AFB5005CAFB40058AD -:10A19000AFB30054AFB20050AFB1004CAFB0004805 -:10A1A0008EE204D400008821241500013042000111 -:10A1B0001440002AA3A0002F8F8700E08F8800C4DE -:10A1C0008F8200E800E220232C8210005040000122 -:10A1D00024841000000420C2008018218EE400C8EE -:10A1E0008EE500CC0000102100A3282100A3302B15 -:10A1F0000082202100862021AEE400C8AEE500CC1C -:10A200008F8300C83C02000A3442EFFF0103202381 -:10A210000044102B104000033C02000A3442F000BE -:10A2200000822021008018218EE400C08EE500C449 -:10A230000000102100A3282100A3302B0082202140 -:10A2400000862021AEE400C0AEE500C4AF8800C89F -:10A25000AF8700E408003C5BAF8700E83C020001E8 -:10A2600000571021904283C01040000B00000000F6 -:10A270003C130001027798218E7383C43C100001C7 -:10A28000021780218E1083C83C12000102579021D2 -:10A2900008003A598E5283CC8F8300E08F8200E40D -:10A2A00010430007000038218F8200E424070001DA -:10A2B0008C4300008C440004AFA30018AFA4001C22 -:10A2C00014E0000E3C02FFFF8F8200C4AFA200101A -:10A2D0008F8200C83C040001248458B4AFA200144B -:10A2E0008F8600E08F8700E43C0500060C00240305 -:10A2F00034A5F20008003C5B000000008FA3001CA6 -:10A300008FB200183073FFFF2673FFFC0062102429 -:10A3100010400058024080213C020080006210245E -:10A320001040000A3C0400408EE2007C2442000100 -:10A33000AEE2007C8EE2007C8EE201FC2442000151 -:10A34000AEE201FC08003C558EE201FC3C06000434 -:10A350003C0B00013C0A00023C0500103C090008CF -:10A360008EE200803C080020340780002442000177 -:10A37000AEE200808EE200808FA2001C0044182410 -:10A380001066002100C3102B1440000700000000DD -:10A39000106B001100000000106A001500000000A2 -:10A3A00008003916000420421065002300A3102B7A -:10A3B00014400005000000001069001900000000B2 -:10A3C0000800391600042042106800210000000037 -:10A3D00008003916000420428EE2003424420001B5 -:10A3E000AEE200348EE20034080039160004204248 -:10A3F0008EE201EC24420001AEE201EC8EE201ECBF -:10A4000008003916000420428EE201F024420001C7 -:10A41000AEE201F08EE201F008003916000420429D -:10A420008EE201F424420001AEE201F48EE201F476 -:10A4300008003916000420428EE200302442000158 -:10A44000AEE200308EE200300800391600042042EF -:10A450008EE201F824420001AEE201F88EE201F83A -:10A46000000420421087033E00000000080038DB93 -:10A47000000000003C02000100571021904283B20E -:10A4800014400084240200013C03000100771821DD -:10A49000906383B31462007F3C0201008E4300008E -:10A4A000006210241040006F2402FFFF14620005B8 -:10A4B00024110001964300043402FFFF106200756E -:10A4C0000000000092E204D8144000720000000076 -:10A4D0003C020001005710218C4283B42842000541 -:10A4E00010400020000038213C02000100571021DC -:10A4F0008C4283B418400016000028219606000004 -:10A50000000520C0009710219442777E1446000970 -:10A510000097102194437780960200021462000590 -:10A52000009710219443778296020004506200083D -:10A53000240700013C020001005710218C4283B423 -:10A5400024A5000100A2102A5440FFEE000520C0FF -:10A5500030E200FF1040030200000000080039A2B2 -:10A5600000000000024020210C0022FE240500060D -:10A570003044001F000428C002E510219442727C80 -:10A5800030424000144002F600B710219443727E1E -:10A59000960200001462000B000418C000B71021DE -:10A5A000944372809602000214620006000418C0F0 -:10A5B00000B71021944372829602000410620035A5 -:10A5C000000418C002E310219442727C30428000E3 -:10A5D000144002E302E31021944D727C96070000C0 -:10A5E000000D28C000B710219442737E0800398402 -:10A5F00000003021000420C002E410219443737C49 -:10A6000002E41021944D737C3063800014600010CC -:10A61000000D28C000B710219442737E1447FFF547 -:10A6200001A0202100B710219443738096020002FC -:10A630005462FFF1000420C000B7102194437382DC -:10A64000960200045462FFEC000420C024060001BE -:10A6500030C200FF104002C200000000080039A212 -:10A66000000000009743020296420000146202BC00 -:10A67000000000009743020496420002146202B8F0 -:10A68000000000009743020696420004146202B4E0 -:10A6900000000000924200003A2300013042000115 -:10A6A00000431024104000742402FFFF8E030000BA -:10A6B000146200043402FFFF960300041062006F6E -:10A6C000241500023C02000100571021904283B281 -:10A6D0001440006A2415000392E204D81440006775 -:10A6E000000000003C020001005710218C4283B49E -:10A6F0002842000510400020000038213C020001E3 -:10A70000005710218C4283B4184000160000282105 -:10A7100096060000000520C0009710219442777E25 -:10A720001446000900971021944377809602000296 -:10A73000146200050097102194437782960200046A -:10A7400050620008240700013C020001005710215C -:10A750008C4283B424A5000100A2102A5440FFEECD -:10A76000000520C030E200FF14400044241500031F -:10A7700008003C5500000000024020210C0022FE91 -:10A78000240500063044001F000428C002E5102103 -:10A790009442727C304240001440027100B7102194 -:10A7A0009443727E960200001462000B000418C0ED -:10A7B00000B71021944372809602000214620006D2 -:10A7C000000418C000B7102194437282960200045E -:10A7D00010620027000418C002E310219442727C2A -:10A7E000304280001440025E02E31021944D727CDE -:10A7F00096070000000D28C000B710219442737E18 -:10A8000008003A0900003021000420C002E41021B1 -:10A810009443737C02E41021944D737C3063800078 -:10A8200014600010000D28C000B710219442737E00 -:10A830001447FFF501A0202100B710219443738035 -:10A84000960200025462FFF1000420C000B71021FC -:10A8500094437382960200045462FFEC000420C00B -:10A860002406000130C200FF1040023D000000003D -:10A8700008003A1C24150003241500018F420260D1 -:10A880000053102B10400036000000008F8300E4BE -:10A890008F8200E01062000324630008AF8300E4AD -:10A8A000AF8300E88EE400C08EE500C4026018218A -:10A8B0000000102100A3282100A3302B00822021BA -:10A8C00000862021AEE400C0AEE500C48EE2005850 -:10A8D00024420001AEE200588EE200588EE2007C75 -:10A8E00024420001AEE2007C8EE2007C8F8200E018 -:10A8F000AFA200108F8200E43C040001248458C001 -:10A90000AFA200148FA600188FA7001C3C050006FC -:10A910000C00240334A5F20308003C5B0000000097 -:10A920008EE25240AFA200108EE252443C0400017D -:10A93000248458CCAFA200148EE60E108EE70E18B9 -:10A940003C0500060C00240334A5F2028EE201C08F -:10A9500024420001AEE201C008003C028EE201C0C8 -:10A9600096E204680053102B544000013C1680000E -:10A97000126001CB3C0E001F35CEFFFF3C0FFFF5F0 -:10A9800035EF1000241E00408EE2724C8F4302808F -:10A9900024420001304207FF1062019E00000000C7 -:10A9A00012C00012000000008EE352408EE25244BA -:10A9B0001062000A26F852448EF45244AFB80024C4 -:10A9C0008EE35244000211402442524802E28821A0 -:10A9D0002463000108003A85306D00FF8EE201E03B -:10A9E00024420001AEE201E08EE201E08EE30E10AF -:10A9F0008EE20E181062FFCA26F80E188EF40E189A -:10AA00000000B021AFB800248EE30E180002114000 -:10AA100024420E2002E2882124630001306D01FFF0 -:10AA200096E2046A3042001010400018340281009F -:10AA30009643000C14620015000000003C02000167 -:10AA400000571021904283C0144000100000000005 -:10AA50009642000EA62200168E4200088E43000485 -:10AA60008E4400002673FFFCAE42000CAE4300088B -:10AA7000AE4400049622000E2610000424180001A3 -:10AA8000A3B8002F34420200A622000E8E2200003E -:10AA90008E2300043C04000134843800020030217D -:10AAA000306A0007020A8023036410210202102B7F -:10AAB00010400005026A9821020410230362182343 -:10AAC0003C02002000438023266200079623000AF0 -:10AAD0002418FFF80058C824006A18210079102BA8 -:10AAE00010400002032060210060602101801821D5 -:10AAF000246200072418FFF800586024026C102B11 -:10AB000014400004019328230183282308003AC33A -:10AB100000C3102100D31021004A202301C4102BB0 -:10AB200054400001008F202125420040004C102B92 -:10AB3000144000350000582194C3000C2402080082 -:10AB400054620032AE2600183C020001005710216A -:10AB5000904283C05440002DAE26001824C2001736 -:10AB600001C2102B10400013000000003C02FFF552 -:10AB70000046102190421017384300062C63000154 -:10AB8000384200112C4200010062182510600014A8 -:10AB900024C2001001C2102B1040000E0000000063 -:10ABA0003C0BFFF501665821956B101008003AF434 -:10ABB0002562000E90C20017384300062C63000186 -:10ABC000384200112C420001006218251060000577 -:10ABD0000160182194CB00102562000E004A582114 -:10ABE00001601821246200072418FFF80058582437 -:10ABF00000C31021004A202301C4102B1040000282 -:10AC000001632823008F2021AE2600183C0200019A -:10AC100000571021904283C00002102B000216C082 -:10AC200015600002AFA2004401805821308200016B -:10AC3000104000070000402190880000248400019B -:10AC400001C4102B1040000224A5FFFF008F20211B -:10AC500050A0001200081C022CA20002544000095F -:10AC600024A5FFFF948200002484000201024021F9 -:10AC700001C4102B1040000624A5FFFE08003B2154 -:10AC8000008F20219082000000021200010240216A -:10AC900014A0FFF22CA2000200081C023102FFFFE8 -:10ACA000006240213108FFFF0140282111400011BE -:10ACB000020020212CA200025440000924A5FFFF1D -:10ACC00094820000248400020102402101C4102B60 -:10ACD0001040000624A5FFFE08003B38008F20210D -:10ACE00090820000000212000102402114A0FFF235 -:10ACF0002CA2000200081C023102FFFF006240216A -:10AD000000081C023102FFFF8F89012000624021F0 -:10AD100027623800252300200062102B1440000217 -:10AD20003108FFFF276330008F8201281062000482 -:10AD3000000000008F8201241462000701402821D6 -:10AD40008EE201A40000382124420001AEE201A4F9 -:10AD500008003BC98EE201A48E2600008E27000465 -:10AD6000000814003448000BAD300008A52B000E7D -:10AD7000AD2800188FB8004400002021029610254D -:10AD800000581025AD22001C00E5102B00E53823EB -:10AD900000C4302300C23023AD260000AD270004DC -:10ADA0008EE204C0AD220010AF83012092E24E205B -:10ADB0001440005F240700012502FFEE2C42000230 -:10ADC00014400003240200111502002400000000BA -:10ADD0008EE24E30000210C02442503802E22021A0 -:10ADE0008C830000240200121462000F0000000097 -:10ADF0008EE34E308EE24E341062000B00000000F5 -:10AE00008C82000424420001AC8200048EE24E34A5 -:10AE10008EE34E3024420001105E002A0000000044 -:10AE200008003BA8000000008EE24E3024420001E2 -:10AE3000505E0003000010218EE24E3024420001DB -:10AE4000AEE24E308EE24E30000210C02442503846 -:10AE500002E2202108003BC6240200128EE24E309E -:10AE6000000210C02442503802E220218C830000EE -:10AE7000240200071462001F000000008EE34E3021 -:10AE80008EE24E341062001B000000008C82000431 -:10AE900024420001AC8200048EE24E348EE34E3038 -:10AEA00024420001105E0007000000008EE24E34D4 -:10AEB00024420001106200050000000008003BB4BD -:10AEC0000000000014600005000000008F820128CF -:10AED00024420020AF8201288F8201288C82000446 -:10AEE0002C42001150400012AC80000008003BC909 -:10AEF000000000008EE24E3024420001505E00034C -:10AF0000000010218EE24E3024420001AEE24E30AD -:10AF10008EE24E30000210C02442503802E220215E -:10AF200024020007AC82000024020001AC8200046D -:10AF300014E000193C0500063C04000124845890EC -:10AF40008E22001834A5F209AFA200108E22000054 -:10AF50008E23000402203021016038210C002403DC -:10AF6000AFA3001493A2002F1040002A34028100E6 -:10AF70008E4300048E4400088E45000CA642000C4F -:10AF8000AE430000AE440004AE4500089622001611 -:10AF900008003C02A642000E1599000A026A182316 -:10AFA0009622000EA623000A34420004A622000EB8 -:10AFB0003C01000100370821A02083C008003BFFAE -:10AFC000000098219624000A0083102B54400001B1 -:10AFD0000080182124020001A623000A3C01000180 -:10AFE00000370821A02283C09622000A004A1821B7 -:10AFF0000203802101D0102B54400001020F802158 -:10B00000026398230000B0218FB800241660FE5E12 -:10B01000AF0D000012600022000000003C010001A2 -:10B0200000370821AC3383C43C01000100370821FC -:10B03000AC3083C83C01000100370821AC3283CC1E -:10B0400093A2002F10400008000000003C02000105 -:10B05000005710218C4283CC244200043C010001A3 -:10B0600000370821AC2283CC8F4302808EE2724CE1 -:10B0700014620006000000008EE201C424420001B8 -:10B08000AEE201C408003C5B8EE201C48EE201BC6A -:10B0900024420001AEE201BC08003C5B8EE201BC30 -:10B0A00097A4001E2484FFFC008018218EE400C0B9 -:10B0B0008EE500C40000102100A3282100A3302B3E -:10B0C000008220210086202124020002AEE400C07C -:10B0D000AEE500C412A2000F2AA20003144000171C -:10B0E0002402000316A20015000000008EE200D02A -:10B0F0008EE300D4246300012C640001004410217D -:10B10000AEE200D0AEE300D48EE200D008003C55A1 -:10B110008EE300D48EE200D88EE300DC24630001CD -:10B120002C64000100441021AEE200D8AEE300DC44 -:10B130008EE200D808003C558EE300DC8EE200C8A9 -:10B140008EE300CC246300012C6400010044102134 -:10B15000AEE200C8AEE300CC8EE200C88EE300CCC5 -:10B160008F8300E48F8200E01062000324630008F4 -:10B17000AF8300E4AF8300E88FBF00688FBE006438 -:10B180008FB600608FB5005C8FB400588FB3005449 -:10B190008FB200508FB1004C8FB0004803E0000820 -:10B1A00027BD007027BDFFE0AFBF00188EE30E146F -:10B1B0008EE20E0C10620074000000008EE30E0C94 -:10B1C0008EE20E1400622023048200012484020017 -:10B1D0008EE30E188EE20E140043102B1440000470 -:10B1E000240202008EE30E1408003C7D0043182365 -:10B1F0008EE20E188EE30E14004310232443FFFF4B -:10B20000008048210069102A544000010060482154 -:10B210008F8701002762300024E800200102102BF4 -:10B2200050400001276828008F82010811020004A5 -:10B23000000000008F8201041502000700001021A9 -:10B240008EE201A80000202124420001AEE201A804 -:10B2500008003CBF8EE201A88EE40E1400042140D9 -:10B26000008018218EE404608EE5046400A3282188 -:10B2700000A3302B0082202100862021ACE40000B6 -:10B28000ACE500048EE30E1400091140A4E2000EA8 -:10B2900024020002ACE200180003194024630E20CF -:10B2A00002E31021ACE200088EE20E14ACE2001CB6 -:10B2B0008EE204CCACE20010AF88010092E204EC14 -:10B2C00014400011240400018EE24E2824030040A3 -:10B2D0002442000150430003000010218EE24E285A -:10B2E00024420001AEE24E288EE24E28000210C039 -:10B2F00024424E3802E2182124020002AC6200000F -:10B3000024020001AC6200041480000E24030040FB -:10B310008EE20E14AFA200108EE20E183C0500075C -:10B32000AFA200148EE60E0C8EE70E103C04000156 -:10B33000248458D40C00240334A5F00108003CDD1B -:10B34000000000008EE2050024420001504300038B -:10B35000000010218EE2050024420001AEE205004B -:10B360008EE205000002108000571021AC4905084C -:10B370008EE20E1400491021304201FFAEE20E149D -:10B380008EE30E148EE20E0C146200050000000025 -:10B390008F8200602403FDFF00431024AF82006011 -:10B3A0008FBF001803E0000827BD002027BDFFE085 -:10B3B000AFBF00188EE3523C8EE252381062007428 -:10B3C000000000008EE352388EE2523C00622023DF -:10B3D00004820001248401008EE352448EE2523C38 -:10B3E0000043102B14400004240201008EE3523C61 -:10B3F00008003CFF004318238EE252448EE3523C87 -:10B40000004310232443FFFF008048210069102AD5 -:10B4100054400001006048218F87010027623000FE -:10B4200024E800200102102B50400001276828006A -:10B430008F82010811020004000000008F820104C5 -:10B4400015020007000010218EE201A80000202153 -:10B4500024420001AEE201A808003D418EE201A8AD -:10B460008EE4523C00042140008018218EE40470D8 -:10B470008EE5047400A3282100A3302B0082202134 -:10B4800000862021ACE40000ACE500048EE3523CD1 -:10B4900000091140A4E2000E24020003ACE20018EF -:10B4A000000319402463524802E31021ACE2000873 -:10B4B0008EE2523CACE2001C8EE204CCACE2001006 -:10B4C000AF88010092E204EC144000112404000152 -:10B4D0008EE24E2824030040244200015043000322 -:10B4E000000010218EE24E2824420001AEE24E28D8 -:10B4F0008EE24E28000210C024424E3802E218218B -:10B5000024020003AC62000024020001AC620004CB -:10B510001480000E240300408EE2523CAFA20010C3 -:10B520008EE252443C050007AFA200148EE652386A -:10B530008EE752403C040001248458E00C002403B0 -:10B5400034A5F01008003D5F000000008EE2050009 -:10B550002442000150430003000010218EE2050048 -:10B5600024420001AEE205008EE2050000021080D8 -:10B5700000571021AC4905088EE2523C00491021C9 -:10B58000304200FFAEE2523C8EE3523C8EE2523833 -:10B5900014620005000000008F8200602403FEFF9B -:10B5A00000431024AF8200608FBF001803E0000842 -:10B5B00027BD00208F8201208EE34E348F8201242C -:10B5C0008F8601282402004024630001506200039A -:10B5D000000010218EE24E3424420001AEE24E34CF -:10B5E0008EE24E348EE44E348EE34E30000210C0B4 -:10B5F000244250381483000702E228218F82012858 -:10B6000024420020AF8201288F82012808003D9249 -:10B61000ACA000008EE24E3424030040244200011E -:10B6200050430003000010218EE24E3424420001FA -:10B63000000210C02442503802E228218CA20004EB -:10B640008F8301280002114000621821AF83012876 -:10B65000ACA000008CC200182443FFFE2C62001234 -:10B6600010400008000310803C0100010022082166 -:10B670008C2258F000400008000000002402000165 -:10B68000AEE24E2403E000080000000027BDFFC822 -:10B69000AFBF0030AFB5002CAFB40028AFB300246B -:10B6A000AFB20020AFB1001CAFB000188F830128EB -:10B6B0008F820124106202B0000098213C11001F0B -:10B6C0003631FFFF3C12FFF53652100024150012F0 -:10B6D000241400408F8C01288F82012824420020EE -:10B6E000AF8201289182001B8F8301282443FFFE33 -:10B6F0002C6200121040029C000310803C010001EB -:10B70000002208218C225948004000080000000057 -:10B710008F42021830420100104000070000000074 -:10B720009583001695820018006218230003140206 -:10B7300000431021A58200168D82001C3C0380006E -:10B740003044FFFF004368243C03080000431824F2 -:10B7500011A00004AD84001C0004114008003DD875 -:10B76000244252480004114024420E2002E2582193 -:10B770009562000E3042FFFC10600004A562000ECE -:10B780009584001608003EC0000000008D69001876 -:10B7900000004021952A000025290002952700007D -:10B7A0002529000295260000252900029525000084 -:10B7B0002529000295240000252900029523000078 -:10B7C0002529000295220000252900020147502169 -:10B7D000014650210145502101445021014350218F -:10B7E00001425021000A1C023142FFFF0062502139 -:10B7F000000A1C023142FFFF0062502196E2046AF7 -:10B80000314EFFFF30420002104000440000502142 -:10B81000252200140222102B1040001401201821B0 -:10B820002405000A000020210223102B54400001AF -:10B8300000721821946200002463000224A5FFFF17 -:10B8400014A0FFF90082202100041C023082FFFFB7 -:10B8500000622021000414023083FFFF0043102106 -:10B860003042FFFF08003E3301425021952A00007C -:10B8700025290002952800002529000295270000AF -:10B8800025290002952600002529000295250000A3 -:10B890002529000295230000252900029522000099 -:10B8A0002529000295240000252900020148502185 -:10B8B00001475021014650210145502101435021AB -:10B8C000014250219522000095230002014450219D -:10B8D0000142502101435021000A1C023142FFFF66 -:10B8E00000625021000A1C023142FFFF0062502119 -:10B8F0003148FFFF510000013408FFFF8D6200183E -:10B900009443000C2402080054620005A56800104E -:10B910009562000E34420002A562000EA568001078 -:10B9200096E2046A000028213042000814400056C4 -:10B93000000030218D630018246200240222102BA5 -:10B9400010400034246900100229102B54400001DB -:10B950000132482195250000246900140229102B8A -:10B960001040000224A5FFEC01324821952200007E -:10B9700030420FFF144000032529000208003E60FA -:10B98000241300010000982100A030210229102B6F -:10B990005440000101324821912200012529000272 -:10B9A00000A228210229102B544000010132482115 -:10B9B000252900020229102B5440000101324821A0 -:10B9C000952200002529000200A228210229102B1F -:10B9D000544000010132482195220000252900022F -:10B9E00000A228210229102B5440000101324821D5 -:10B9F000952200002529000200A228210229102BEF -:10BA000054400001013248219522000008003E996F -:10BA100000A2282194650010946200142469001685 -:10BA200030420FFF1440000324A5FFEC08003E8CB9 -:10BA3000241300010000982100A03021912300016F -:10BA400025290004952200002529000295240000E4 -:10BA50002529000200A3282100A228219522000008 -:10BA60009523000200A4282100A2282100A3282158 -:10BA700000051C0230A2FFFF0062282100051C0205 -:10BA800030A2FFFF0062282196E2046A30420001E2 -:10BA90001040001E0000202195820016004E202339 -:10BAA0000004140200822021326200FF5040000294 -:10BAB000008620210085202100041402008220211C -:10BAC0003084FFFF508000013404FFFF8D620018B6 -:10BAD000244300170223102B544000010072182148 -:10BAE00090620000384300112C63000138420006C8 -:10BAF0002C420001006218251060000400000000C4 -:10BB00009562000E34420001A562000E9562000E9F -:10BB1000240A00023042000410400002A564001212 -:10BB2000240A00048F88012027623800250900209C -:10BB30000122102B50400001276930008F8201281C -:10BB400011220004000000008F820124152200074A -:10BB5000240400208EE201A4000080212442000180 -:10BB6000AEE201A408003F4F8EE201A48EE5724CC4 -:10BB70008EE604908EE70494AD0B0008A504000E39 -:10BB8000AD0A00180005294000A01821000010216E -:10BB900000E3382100E3202B00C2302100C4302113 -:10BBA000AD060000AD0700048EE2724C004D10257A -:10BBB000AD02001C8EE204C4AD020010AF8901206A -:10BBC00092E24E2014400060241000012543FFEE55 -:10BBD0002C630002394200112C420001006218253A -:10BBE00010600024000000008EE24E30000210C001 -:10BBF0002442503802E220218C8200001455000FAC -:10BC0000000000008EE34E308EE24E341062000BD6 -:10BC1000000000008C82000424420001AC82000479 -:10BC20008EE24E348EE34E30244200011054002B3D -:10BC30000000000008003F2E000000008EE24E30A1 -:10BC40002442000150540003000010218EE24E30C7 -:10BC500024420001AEE24E308EE24E30000210C0AF -:10BC60002442503802E220212402000108003F4E05 -:10BC7000AC9500008EE24E30000210C024425038D5 -:10BC800002E220218C830000240200071462001FBE -:10BC9000000000008EE34E308EE24E341062001B36 -:10BCA000000000008C82000424420001AC820004E9 -:10BCB0008EE24E348EE34E302442000110540007D1 -:10BCC000000000008EE24E342442000110620005A4 -:10BCD0000000000008003F3A00000000146000056A -:10BCE000000000008F82012824420020AF8201283A -:10BCF0008F8201288C8200042C42001150400012D7 -:10BD0000AC80000008003F4F000000008EE24E3083 -:10BD10002442000150540003000010218EE24E30F6 -:10BD200024420001AEE24E308EE24E30000210C0DE -:10BD30002442503802E2202124020007AC82000095 -:10BD400024020001AC8200041600000D0000000077 -:10BD50008F8201203C04000124845938AFA00014D4 -:10BD6000AFA200108D86001C8F8701243C050008BF -:10BD70000C00240334A50001080040570000000017 -:10BD80008EE2724C24420001304207FF11A00006EF -:10BD9000AEE2724C8EE201D02442FFFFAEE201D04F -:10BDA00008003F6B8EE201D08EE201CC2442FFFFFF -:10BDB000AEE201CC8EE201CC8EE201D82442FFFF3C -:10BDC000AEE201D8080040578EE201D88F4202400F -:10BDD000104000E5000000008EE20E1C244200012D -:10BDE00008004057AEE20E1C9582001EAD82001C7A -:10BDF0008F42024010400072000000008EE20E1CD4 -:10BE000024420001AEE20E1C8F4302400043102B7F -:10BE1000144000D5000000008F8301202762380005 -:10BE20002466002000C2102B50400001276630001D -:10BE30008F82012810C20004000000008F820124BC -:10BE400014C20007000000008EE201A4000080215F -:10BE500024420001AEE201A408003FDA8EE201A410 -:10BE60008EE2724CAC62001C8EE404A88EE504AC39 -:10BE70002462001CAC62000824020008A462000EC8 -:10BE800024020011AC620018AC640000AC65000430 -:10BE90008EE204C4AC620010AF86012092E24E2014 -:10BEA00014400034241000018EE24E30000210C015 -:10BEB0002442503802E220218C8200001455001FD9 -:10BEC000000000008EE34E308EE24E341062001B04 -:10BED000000000008C82000424420001AC820004B7 -:10BEE0008EE24E348EE34E3024420001105400079F -:10BEF000000000008EE24E34244200011062000572 -:10BF00000000000008003FC60000000014600005AB -:10BF1000000000008F82012824420020AF82012807 -:10BF20008F8201288C8200042C42001150400011A5 -:10BF3000AC80000008003FDA000000008EE24E30C6 -:10BF40002442000150540003000010218EE24E30C4 -:10BF500024420001AEE24E308EE24E30000210C0AC -:10BF60002442503802E2202124020001AC95000056 -:10BF7000AC8200045600000B241000018EE2724CCB -:10BF80003C040001248458A8AFA00014AFA2001004 -:10BF90008EE6724C8F4702803C0500090C0024039A -:10BFA00034A5F00856000001AEE00E1C8EE20188B8 -:10BFB00024420001AEE20188080040508EE2018870 -:10BFC0008F830120276238002466002000C2102BD6 -:10BFD00050400001276630008F82012810C2000403 -:10BFE000000000008F82012414C20007000000003E -:10BFF0008EE201A40000802124420001AEE201A4EF -:10C00000080040448EE201A48EE2724CAC62001C37 -:10C010008EE404A88EE504AC2462001CAC62000827 -:10C0200024020008A462000E24020011AC62001871 -:10C03000AC640000AC6500048EE204C4AC62001085 -:10C04000AF86012092E24E201440003424100001FB -:10C050008EE24E30000210C02442503802E220210D -:10C060008C8200001455001F000000008EE34E304B -:10C070008EE24E341062001B000000008C8200042F -:10C0800024420001AC8200048EE24E348EE34E3036 -:10C090002442000110540007000000008EE24E34DC -:10C0A000244200011062000500000000080040303A -:10C0B0000000000014600005000000008F820128CD -:10C0C00024420020AF8201288F8201288C82000444 -:10C0D0002C42001150400011AC8000000800404488 -:10C0E000000000008EE24E30244200015054000354 -:10C0F000000010218EE24E3024420001AEE24E30AC -:10C100008EE24E30000210C02442503802E220215C -:10C1100024020001AC950000AC8200041600000B64 -:10C12000000000008EE2724C3C040001248458A8F8 -:10C13000AFA00014AFA200108EE6724C8F470280B1 -:10C140003C0500090C00240334A5F0088EE20174BC -:10C1500024420001AEE20174080040578EE20174EF -:10C1600024020001AEE24E248F8301288F82012435 -:10C170001462FD58000000008FBF00308FB5002C06 -:10C180008FB400288FB300248FB200208FB1001C21 -:10C190008FB0001803E0000827BD003827BDFFE876 -:10C1A000278402082745020024060008AFBF0014B8 -:10C1B0000C00249AAFB000100000202124100001D0 -:10C1C0002402241FAF900210AF900200AF8002043F -:10C1D000AF8202148F460248240300043C02004050 -:10C1E0003C010001AC235CC43C010001AC235CC8F1 -:10C1F0003C010001AC205D9C3C010001AC225CC014 -:10C200003C010001AC235CC80C005108240500046B -:10C210000C004822000000008EE200003C03FEFFFC -:10C220003463FFFD00431024AEE200003C023C00FA -:10C23000AF82021C3C01000100370821AC3083AC06 -:10C240008FBF00148FB0001003E0000827BD001856 -:10C2500027BDFFE03C05000834A50400AFBF00186F -:10C26000AFA00010AFA000148F8602003C040001B4 -:10C27000248459F00C002403000038218EE202804F -:10C2800024420001AEE202808EE202808F8302002F -:10C290003C023F00006218248FBF00183C020400DB -:10C2A00003E0000827BD002027BDFFD8AFBF002056 -:10C2B000AFB1001CAFB000188F9002208EE20214C4 -:10C2C0000000382124420001AEE202148EE2021482 -:10C2D0003C02030002021024104000273C1104001D -:10C2E0000C00429B000000003C02010002021024EE -:10C2F00010400007000000008EE2021824420001F6 -:10C30000AEE202188EE20218080040C63C03FDFFB0 -:10C310008EE2021C24420001AEE2021C8EE2021CEC -:10C320003C03FDFF3463FFFF3C0808FF3508FFFFB7 -:10C330008EE200003C040001248459FC3C05000806 -:10C340000200302100431024AEE200008F82022060 -:10C35000000038213C03030000481024004310254E -:10C36000AF820220AFA000100C002403AFA0001485 -:10C370000800429600000000021110241040001F27 -:10C380003C0240008F830224240214021462000B3A -:10C390003C03FDFF3C04000124845A083C050008CE -:10C3A000AFA00010AFA000148F86022434A5FFFFB9 -:10C3B0000C002403000038213C03FDFF8EE2000046 -:10C3C0003463FFFF02002021004310240C004E5470 -:10C3D000AEE200008EE2022024420001AEE2022022 -:10C3E0008EE202208F8202203C0308FF3463FFFFAD -:10C3F0000043102408004295005110250202102429 -:10C4000010400142000000008EE2022C2442000194 -:10C41000AEE2022C8EE2022C8F8202203C0308FF47 -:10C420003463FFFF0043102434420004AF82022033 -:10C430008F8300548F8200540800410E2463000251 -:10C440008F820054006210232C4200031440FFFC32 -:10C45000000000008F8600E08F8400E430C20007F7 -:10C4600010400012000000008F8300E42402FFF857 -:10C4700000C210241043000D000000008F82005401 -:10C480008F8300E014C30009244400508F820054BD -:10C49000008210232C4200511040000400000000D4 -:10C4A0008F8200E010C2FFF9000000008F8202209E -:10C4B0003C0308FF3463FFFD00431024AF820220D9 -:10C4C0008F8600E030C20007104000032402FFF80E -:10C4D00000C23024AF8600E08F8300C43C02001FFE -:10C4E0003442FFFF246800080048102B104000036E -:10C4F0003C02FFF534421000010240218F8B00C83E -:10C500008F8501208F8401240800414500006021AF -:10C51000276238000082102B504000012764300051 -:10C5200010A40010318200FF8C82001838430007ED -:10C530002C6300013842000B2C42000100621825D8 -:10C540005060FFF3248400208EE20240240C00019E -:10C5500024420001AEE202408EE202408C8B0008D1 -:10C56000318200FF14400065000000003C02000121 -:10C5700000571021904283C014400060000000006A -:10C580008F8400E400C41023000218C30462000179 -:10C59000246302008F8900C410600005240200019A -:10C5A0001062000900000000080041870000000040 -:10C5B0008EE202300120582124420001AEE2023016 -:10C5C000080041BC8EE202308EE202343C05000AD3 -:10C5D00024420001AEE202348C8B000034A5F0004E -:10C5E0008EE20234012B182300A3102B54400001CB -:10C5F000006518212C62233F144000400000000019 -:10C600008F8200E824420008AF8200E88F8200E8B1 -:10C610008F8200E40120582124420008AF8200E408 -:10C62000080041BC8F8200E48EE202383C03000A1D -:10C6300024420001AEE202388C8400003463F00032 -:10C640008EE20238008838230067102B5440000126 -:10C6500000E338213C02000334420D400047102B18 -:10C660001040000300000000080041BC0080582179 -:10C670008F8200E424440008AF8400E48F8400E447 -:10C68000108600183C05000A34A5F0003C0A00039F -:10C69000354A0D408EE2007C24420001AEE2007C6F -:10C6A0008C8300008EE2007C0068382300A7102BEA -:10C6B0005440000100E538210147102B5440000789 -:10C6C000006058218F8200E424440008AF8400E415 -:10C6D0008F8400E41486FFEF00000000148600053C -:10C6E0000000000001205821AF8600E4080041BC92 -:10C6F000AF8600E8AF8400E4AF8400E88F8200C812 -:10C700003C03000A3463F000004838230067102B14 -:10C710005440000100E338213C02000334420D3F45 -:10C720000047102B544000070000602101683823A7 -:10C730000067102B5440000300E33821080041CF6C -:10C740003C0200033C02000334420D3F0047102B23 -:10C7500014400016318200FF144000060000000063 -:10C760003C02000100571021904283C01040000F8E -:10C77000000000008EE2023C3C04FDFF8EE300005E -:10C780003484FFFF24420001AEE2023C8EE2023C10 -:10C7900024020001006418243C0100010037082134 -:10C7A000A02283B80800422CAEE30000AF8B00C883 -:10C7B0008F8300C88F8200C43C04000A3484F000D8 -:10C7C000006238230087102B5440000100E4382118 -:10C7D0003C02000334420D400047102B2CE30001C3 -:10C7E0000043102510400008000000008F82022046 -:10C7F0003C0308FF3463FFFF004310243C03400068 -:10C8000000431025AF8202208F8600E08F8400E471 -:10C8100010C4002A000000008EE2007C24420001C7 -:10C82000AEE2007C8EE2007C24C2FFF8AF8200E022 -:10C830003C0200018C427E303C0300088F8600E001 -:10C84000004310241040001D0000000010C4001B15 -:10C85000240DFFF83C0A000A354AF0003C0C008029 -:10C86000248500082762280050A2000127651800CF -:10C870008C8800048C8200008CA900003103FFFF2B -:10C8800000431021004D102424430010006B102B96 -:10C8900054400001006A1821012B102B5440000164 -:10C8A000012A482110690002010C1025AC82000405 -:10C8B00000A0202114C4FFEB248500088F820220F1 -:10C8C0003C0308FF3463FFFF00431024344200029E -:10C8D000AF8202208F8300548F82005408004237B9 -:10C8E000246300018F820054006210232C42000256 -:10C8F0001440FFFC000000008F8202203C0308FF70 -:10C900003463FFFB00431024AF8202200601005570 -:10C91000000000008EE2022824420001AEE202285C -:10C920008EE202288F8202203C0308FF3463FFFF5F -:10C930000043102434420004AF8202208F8300544D -:10C940008F82005408004251246300028F820054F9 -:10C95000006210232C4200031440FFFC0000000082 -:10C960008F8600E030C20007104000120000000077 -:10C970008F8300E42402FFF800C210241043000D4E -:10C98000000000008F8200548F8300E014C3000970 -:10C99000244400328F820054008210232C42003342 -:10C9A00010400004000000008F8200E010C2FFF978 -:10C9B000000000008F8202203C0308FF3463FFFD6B -:10C9C00000431024AF8202208F8600E030C20007AF -:10C9D000104000032402FFF800C23024AF8600E0BC -:10C9E000240301F58F8200E800673823000718C090 -:10C9F00000431021AF8200E88F8200E8AF8200E49C -:10CA00008EE2007C3C0408FF3484FFFF00471021C5 -:10CA1000AEE2007C8F8202203C038000346300027F -:10CA20000044102400431025AF8202208F8300545D -:10CA30008F8200540800428D246300018F820054CD -:10CA4000006210232C4200021440FFFC0000000092 -:10CA50008F8202203C0308FF3463FFFB0043102455 -:10CA6000AF8202208FBF00208FB1001C8FB0001852 -:10CA700003E0000827BD00283C0200018C425CD87E -:10CA800027BDFFD810400012AFBF00203C040001BA -:10CA900024845A143C050008240200013C010001D2 -:10CAA00000370821AC2283ACAFA00010AFA0001467 -:10CAB0008F86022034A504983C010001AC205CD88C -:10CAC0003C010001AC225CCC0C00240300003821A6 -:10CAD0008F4202683C037FFF3463FFFF0043102452 -:10CAE000AF4202688EE204D08EE404D42403FFFE39 -:10CAF00000431024308400021080011EAEE204D0F6 -:10CB00008EE204D42403FFFD00431024AEE204D4DB -:10CB10008F8200443C03060034632000344200202E -:10CB2000AF820044AFA300188EE206088F430228AC -:10CB300024420001304A00FF514300FEAFA0001024 -:10CB40008EE20608000210C0005710218FA30018C3 -:10CB50008FA4001CAC43060CAC4406108F83005419 -:10CB60008F82005424690032012210232C420033AA -:10CB70001040006A0000582124180008240F000DFE -:10CB8000240D0007240C0040240E00018F87012093 -:10CB90002762380024E800200102102B50400001D9 -:10CBA000276830008F820128110200040000000075 -:10CBB0008F82012415020007000010218EE201A4DB -:10CBC0000000282124420001AEE201A40800433DF8 -:10CBD0008EE201A48EE40608000420C00080182123 -:10CBE0008EE404308EE5043400A3282100A3302B0A -:10CBF0000082202100862021ACE40000ACE5000486 -:10CC00008EE20608A4F8000EACEF0018ACEA001C97 -:10CC1000000210C02442060C02E21021ACE200081F -:10CC20008EE204C4ACE20010AF88012092E24E20F4 -:10CC300014400033240500018EE24E30000210C083 -:10CC40002442503802E220218C820000144D001F43 -:10CC5000000000008EE34E308EE24E341062001B66 -:10CC6000000000008C82000424420001AC82000419 -:10CC70008EE24E348EE34E3024420001104C000709 -:10CC8000000000008EE24E342442000110620005D4 -:10CC9000000000000800432A0000000014600005A6 -:10CCA000000000008F82012824420020AF8201286A -:10CCB0008F8201288C8200042C4200115040001009 -:10CCC000AC8000000800433D000000008EE24E30C2 -:10CCD00024420001504C0003000010218EE24E302F -:10CCE00024420001AEE24E308EE24E30000210C00F -:10CCF0002442503802E22021AC8D0000AC8E0004AA -:10CD000054A00006240B00018F820054012210233E -:10CD10002C4200331440FF9D00000000316300FFEF -:10CD20002402000154620079AFA00010AEEA0608A8 -:10CD30008F8300548F820054246900320122102313 -:10CD40002C4200331040006100005821240D0008DF -:10CD5000240C00112408001224070040240A0001BA -:10CD60008F830120276238002466002000C2102B28 -:10CD700050400001276630008F82012810C2000455 -:10CD8000000000008F82012414C200070000000090 -:10CD90008EE201A40000282124420001AEE201A499 -:10CDA000080043A98EE201A48EE20608AC62001CD2 -:10CDB0008EE404A08EE504A42462001CAC6200088A -:10CDC000A46D000EAC6C0018AC640000AC650004EF -:10CDD0008EE204C4AC620010AF86012092E24E20C5 -:10CDE00014400033240500018EE24E30000210C0D2 -:10CDF0002442503802E220218C8200001448001F97 -:10CE0000000000008EE34E308EE24E341062001BB4 -:10CE1000000000008C82000424420001AC82000467 -:10CE20008EE24E348EE34E3024420001104700075C -:10CE3000000000008EE24E34244200011062000522 -:10CE40000000000008004396000000001460000588 -:10CE5000000000008F82012824420020AF820128B8 -:10CE60008F8201288C8200042C4200115040001057 -:10CE7000AC800000080043A9000000008EE24E30A4 -:10CE80002442000150470003000010218EE24E3082 -:10CE900024420001AEE24E308EE24E30000210C05D -:10CEA0002442503802E22021AC880000AC8A000401 -:10CEB00054A00006240B00018F820054012210238D -:10CEC0002C4200331440FFA600000000316300FF35 -:10CED0002402000154620003AFA00010080043D6F2 -:10CEE000000000003C04000124845A20AFA000147C -:10CEF0008F8601208F8701243C0500090C00240344 -:10CF000034A5F011080043D6000000003C040001E5 -:10CF100024845A2CAFA000148F8601208F8701240F -:10CF20003C0500090C00240334A5F010080043D68A -:10CF3000000000003C04000124845A38AFA0001413 -:10CF40008EE606088F4702283C0500090C002403E2 -:10CF500034A5F00F8EE201AC24420001AEE201AC38 -:10CF60008EE201AC8EE2015C24420001AEE2015C83 -:10CF70008EE2015C8FBF002003E0000827BD00287F -:10CF80003C0200018C425CD827BDFFE01440000D3C -:10CF9000AFBF00183C04000124845A443C0500083B -:10CFA000AFA00010AFA000148F86022034A5049912 -:10CFB000240200013C010001AC225CD80C002403D7 -:10CFC000000038218EE204D03C03000100771821D4 -:10CFD000946383B23442000110600007AEE204D0D3 -:10CFE0008F8202203C0308FF3463FFFF00431024BC -:10CFF00034420008AF820220000020210C0052A21F -:10D0000024050004AF4202688FBF001803E0000847 -:10D0100027BD00200000000000000000000000000C -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D100000000000000000000000000003C120001D0 -:10D11000265212003C1400018E945C503C10000119 -:10D12000261011203C15C00036B500608E8A000024 -:10D130008EB30000026A400B0248000A0200F82188 -:10D14000000000000000000D0000000000000000D2 -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000080014D62C -:10D2100000000000080014D83C0A0001080014D8DF -:10D220003C0A0002080014D800000000080024A6F0 -:10D2300000000000080014D83C0A0003080014D8BD -:10D240003C0A000408002F8C00000000080014D8DD -:10D250003C0A000508003CE80000000008003C66AD -:10D2600000000000080014D83C0A0006080014D88A -:10D270003C0A0007080014D800000000080014D879 -:10D2800000000000080014D80000000008002A7503 -:10D2900000000000080014D83C0A000B080014D855 -:10D2A0003C0A000C080014D83C0A000D0800237A40 -:10D2B000000000000800233900000000080014D816 -:10D2C0003C0A000E08001B3C00000000080024A4DB -:10D2D00000000000080014D83C0A000F080040A716 -:10D2E000000000000800409100000000080014D871 -:10D2F0003C0A0010080014EE00000000080014D8DA -:10D300003C0A0011080014D83C0A0012080014D886 -:10D310003C0A0013000000000000000000000000B4 -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D400000000000000000000000000003C030001DC -:10D4100034633800240500802404001F2406FFFF25 -:10D4200024020001AF80021CAF820200AF82022002 -:10D4300003631021AF8200C003631021AF8200C4D8 -:10D4400003631021AF8200C827623800AF8200D08A -:10D4500027623800AF8200D427623800AF8200D83C -:10D4600027621800AF8200E027621800AF8200E454 -:10D4700027621800AF8200E827621000AF8200F038 -:10D4800027621000AF8200F427621000AF8200F81C -:10D49000ACA000002484FFFF1486FFFD24A5000437 -:10D4A0008F8300403C02F000006218243C025000D0 -:10D4B0001062000C0043102B144000063C02600078 -:10D4C0003C024000106200082402080008004539B0 -:10D4D0000000000010620004240208000800453922 -:10D4E00000000000240207003C010001AC225CDCCB -:10D4F00003E000080000000027BDFFD8AFBF0024F4 -:10D50000AFB000208F8300548F8200543C01000193 -:10D51000AC205CC408004545246300648F8200543D -:10D52000006210232C4200651440FFFC0000000044 -:10D530000C004D71000000002404000100002821AF -:10D5400027A60018340280000C00498EA7A20018FC -:10D550008F8300548F820054080045562463006472 -:10D560008F820054006210232C4200651440FFFC9F -:10D5700024040001240500010C00494C27A60018D2 -:10D580008F8300548F820054080045622463006436 -:10D590008F820054006210232C4200651440FFFC6F -:10D5A00024040001240500010C00494C27A60018A2 -:10D5B0008F8300548F8200540800456E24630064FA -:10D5C0008F820054006210232C4200651440FFFC3F -:10D5D000240400013C06000124C65DA00C00494C57 -:10D5E000240500028F8300548F8200540800457B7D -:10D5F000246300648F820054006210232C42006573 -:10D600001440FFFC24040001240500033C10000129 -:10D6100026105DA20C00494C0200302197A600188C -:10D620003C07000194E75DA03C04000124845AB04B -:10D63000AFA00014960200003C05000D34A50100C7 -:10D640000C002403AFA2001097A200181040004C59 -:10D6500024036040960200003042FFF01443000AA9 -:10D66000240200203C03000194635DA05462000981 -:10D6700024027830240200033C010001AC225CC487 -:10D68000080045AC240200053C03000194635DA042 -:10D69000240278301462000F240300103C020001C1 -:10D6A00094425DA23042FFF01443000A24020003BA -:10D6B0003C010001AC225CC4240200063C010001D4 -:10D6C000AC225DB03C010001AC225DBC080045E627 -:10D6D0003C09FFF03C0200018C425CC43C030001A9 -:10D6E00094635DA0344200013C010001AC225CC4A3 -:10D6F000240200151462000F000000003C0200012B -:10D7000094425DA23042FFF03843F4202C630001C4 -:10D710003842F4302C4200010062182510600005E8 -:10D72000240200033C010001AC225DBC080045E678 -:10D730003C09FFF03C03000194635DA024027810D3 -:10D740001462000B240200023C02000194425DA21C -:10D750003042FFF0144000062402000224020004BC -:10D760003C010001AC225DBC080045E63C09FFF02D -:10D770003C010001AC225DBC080045E63C09FFF01D -:10D780003C0200018C425CC4240300013C01000106 -:10D79000AC235DBC344200043C010001AC225CC4FB -:10D7A0003C09FFF03529BDC03C0600018CC65CC4B5 -:10D7B0003C04000124845AB0240200013C01000111 -:10D7C000AC225CCC8F8200543C0700018CE75DBC2E -:10D7D0003C03000194635DA03C08000195085DA234 -:10D7E0003C05000D34A501003C010001AC205CC8E3 -:10D7F000004910213C010001AC225DACAFA3001038 -:10D800000C002403AFA800148FBF00248FB00020A9 -:10D8100003E0000827BD002827BDFFE83C05000104 -:10D820008CA55CC8240600042402000114A2001484 -:10D83000AFBF00103C0200018C427E3C30428000B1 -:10D84000104000053C04000F3C0300018C635DBCEC -:10D8500008004617348442403C0400043C030001A5 -:10D860008C635DBC348493E02402000514620016CE -:10D87000000000003C04003D0800462F34840900ED -:10D880003C0200018C427E3830428000104000058E -:10D890003C04001E3C0300018C635DBC0800462A6A -:10D8A000348484803C04000F3C0300018C635DBC25 -:10D8B000348442402402000514620003000000008A -:10D8C0003C04007A348412003C0200018C425DACBE -:10D8D0008F83005400441021004310230044102B78 -:10D8E00014400037000000003C0200018C425CD074 -:10D8F00014400033000000003C01000110C000256E -:10D90000AC205CE03C0900018D295CC424070001C7 -:10D910003C0440003C08000125087E3C250AFFFC31 -:10D920000005284214A0000224C6FFFF24050008B9 -:10D9300000A91024104000100000000014A70008E7 -:10D94000000000008D020000004410241040000A76 -:10D95000000000003C0100010800465BAC255CE0D3 -:10D960008D4200000044102410400003000000001D -:10D970003C010001AC275CE03C0200018C425CE011 -:10D980000006182B2C420001004310245440FFE5F0 -:10D99000000528428F8200543C0300018C635CE048 -:10D9A0003C010001AC225DAC1060002A24020001A1 -:10D9B0003C010001AC255CC83C010001AC225CCC00 -:10D9C0003C0200018C425CE010400022000000009C -:10D9D0003C0200018C425CCC1040000A2402000191 -:10D9E0003C010001AC205CCC3C0100010037082167 -:10D9F000AC2283AC3C010001AC205D4C3C01000139 -:10DA0000AC225D043C030001007718218C6383ACD9 -:10DA10002402000810620005240200010C00469553 -:10DA20000000000008004692000000003C030001D6 -:10DA30008C635CC8106200072402000E3C030001E6 -:10DA40008C637DD010620003000000000C004E5477 -:10DA50008F8402208FBF001003E0000827BD00184C -:10DA600027BDFFE03C02FDFFAFBF00188EE30000C2 -:10DA70003C0500018CA55CC83C0400018C845CF072 -:10DA80003442FFFF0062182414A40008AEE3000033 -:10DA90003C030001007718218C6383AC3C02000139 -:10DAA0008C425CF410620008000000003C0200019F -:10DAB000005710218C4283AC3C010001AC255CF086 -:10DAC0003C010001AC225CF43C0300018C635CC8A7 -:10DAD00024020002106201692C620003104000055C -:10DAE0002402000110620008000000000800481C29 -:10DAF0000000000024020004106200B124020001B2 -:10DB00000800481D000000003C02000100571021E1 -:10DB10008C4283AC2443FFFF2C6200081040015A62 -:10DB2000000310803C010001002208218C225AC809 -:10DB300000400008000000003C0300018C635DBC55 -:10DB40002402000514620014000000003C020001E1 -:10DB50008C425CD41040000A240200030C004822CE -:10DB600000000000240200023C01000100370821EF -:10DB7000AC2283AC3C010001080046E0AC205CD440 -:10DB80003C01000100370821AC2283AC3C010001BC -:10DB90000800481FAC205C600C0048220000000018 -:10DBA0003C0200018C425CD43C010001AC205C6072 -:10DBB000104000DD240200023C0100010037082172 -:10DBC000AC2283AC3C0100010800481FAC205CD4AF -:10DBD0003C0300018C635DBC240200051462000359 -:10DBE000240200013C010001AC225D000C0049CF81 -:10DBF000000000003C0300018C635D000800478EBC -:10DC0000240200113C0500018CA55CC83C06000103 -:10DC10008CC67E3C0C005108000020212402000527 -:10DC20003C010001AC205CD43C010001003708211C -:10DC30000800481FAC2283AC3C04000124845ABC79 -:10DC40003C05000F34A50100000030210000382100 -:10DC5000AFA000100C002403AFA000140800481F60 -:10DC6000000000008F8202203C03F70000431025D3 -:10DC7000080047B7AF8202208F8202203C030004D5 -:10DC800000431024144000A9240200078F8300548D -:10DC90003C0200018C425DA42463D8F000431023B1 -:10DCA0002C422710144000F8240200010800481DEF -:10DCB000000000003C0500018CA55CC80C0052A2CD -:10DCC000000020210C005386000020213C030001AD -:10DCD0008C637E34046100EA240200013C020008E7 -:10DCE0000062102410400006000000008F82021421 -:10DCF0003C03FFFF00431024080047413442251F26 -:10DD00008F8202143C03FFFF004310243442241F7F -:10DD1000AF8202148EE200003C0302000043102593 -:10DD2000AEE200008F8202202403FFFB0043102498 -:10DD3000AF8202208F82022034420002AF82022092 -:10DD4000240200083C01000100370821AC2283AC0A -:10DD50008F8202203C03000400431024144000057D -:10DD6000000000008F8202203C03F70000431025D2 -:10DD7000AF8202203C0300018C635DBC24020005DD -:10DD80001462000A000000003C02000194425DA2FF -:10DD900024429FBC2C4200041040000424040018BC -:10DDA000240500020C004D93240600200C0043DDE6 -:10DDB000000000003C0100010800481FAC205D503D -:10DDC0003C020001005710218C4283AC2443FFFF2A -:10DDD0002C620008104000AC000310803C010001E0 -:10DDE000002208218C225AE80040000800000000B0 -:10DDF0000C00429B000000003C010001AC205CCC08 -:10DE0000AF8002043C0100010C004822AC207E20BF -:10DE1000240200013C010001AC225CE42402000267 -:10DE20003C010001003708210800481FAC2283ACE8 -:10DE30000C00489F000000003C0300018C635CE480 -:10DE40002402000914620090240200033C01000136 -:10DE5000003708210800481FAC2283AC3C020001B7 -:10DE60008C427E3830424000104000050000000027 -:10DE70008F8200443C03FFFF0800479F34637FFF0D -:10DE80008F8200442403FF7F00431024AF820044AC -:10DE90008F830054080047B9240200048F83005484 -:10DEA0003C0200018C425DA42463D8F0004310239F -:10DEB0002C42271014400074240200053C0100018C -:10DEC000003708210800481FAC2283AC8F82022053 -:10DED0003C03F70000431025AF820220AF8002040C -:10DEE0003C010001AC207E208F83005424020006F8 -:10DEF0003C01000100370821AC2283AC3C01000149 -:10DF00000800481FAC235DA48F8300543C0200012D -:10DF10008C425DA42463FFF6004310232C42000AC8 -:10DF20001440005900000000240200073C010001D9 -:10DF3000003708210800481FAC2283AC8F820220E2 -:10DF40003C04F70000441025AF8202208F8202209B -:10DF50003C03030000431024144000050000182176 -:10DF60008F8202202403000100441025AF8202208A -:10DF700010600043240200018F8202143C03FFFF63 -:10DF80003C0400018C845D98004310243442251F1A -:10DF9000AF820214240200083C010001003708216E -:10DFA0001080000BAC2283AC3C0200018C425D74FB -:10DFB00014400007240200013C010001AC227DD086 -:10DFC0000C004E548F8402200800480C0000000012 -:10DFD0008F8202203C0300080043102414400017E5 -:10DFE0002402000E3C010001AC227DD08EE2000034 -:10DFF000000020213C030200004310250C00538642 -:10E00000AEE200008F8202202403FFFB00431024B5 -:10E01000AF8202208F820220344200020C0043DDD6 -:10E02000AF8202203C0500018CA55CC80C0052A206 -:10E03000000020210800481F000000003C020001F1 -:10E040008C425D7410400010000000003C02000192 -:10E050008C425D702442FFFF3C010001AC225D70E8 -:10E0600014400009240200023C010001AC205D7450 -:10E070003C0100010800481FAC225D702402000131 -:10E080003C010001AC225CCC8FBF001803E000080B -:10E0900027BD00208F8202008F8202208F82022003 -:10E0A00034420004AF8202208F8202003C0600014D -:10E0B0008CC65CC834420004AF8202002402000215 -:10E0C00010C2003A2CC200031040000524020001D7 -:10E0D00010C20008000000000800486800000000AE -:10E0E0002402000410C20013240200010800486842 -:10E0F000000000003C0300018C635CB83C0200019E -:10E100008C425CC03C0400018C845CDC3C0500015A -:10E110008CA55CBCAF860200AF860220346300226F -:10E1200000441025004510253442000208004867CD -:10E13000AF8302003C0300018C635D98AF82020054 -:10E1400010600009AF8202203C0200018C425D7425 -:10E15000144000053C033F003C0200018C425CB0CF -:10E160000800485B346300E03C0200018C425CB074 -:10E170003C033F00346300E200431025AF820200FD -:10E180003C0300018C635CB43C04F7003C020001DA -:10E190008C425CC03C0500018CA55CDC0064182549 -:10E1A0000043102500451025AF82022003E000083F -:10E1B000000000008F8202203C0300018C635CC8D9 -:10E1C00034420004AF820220240200011062000FDA -:10E1D000000000008F8300548F82005424630002EB -:10E1E000006210232C4200031040001100000000C8 -:10E1F0008F820054006210232C4200031040000C58 -:10E200000000000008004879000000008F830054DF -:10E210008F82005408004885246300078F820054D1 -:10E22000006210232C4200081440FFFC0000000094 -:10E230008F8400E0308200071040000D00000000D5 -:10E240008F8200548F8300E014830009244500323C -:10E250008F82005400A210232C420033104000048F -:10E26000000000008F8200E01082FFF90000000033 -:10E270008F8202202403FFFD00431024AF8202207E -:10E2800003E00008000000003C0300018C635CE434 -:10E290003C0200018C425CE8506200042463FFFFF2 -:10E2A0003C010001AC235CE82463FFFF2C62000901 -:10E2B0001040009D000310803C0100010022082155 -:10E2C0008C225B0800400008000000008F820044A0 -:10E2D00034428080AF8200448F8300540800493864 -:10E2E000240200028F8300543C0200018C425DA88E -:10E2F0002463D8F0004310232C4227101440008AD6 -:10E300002402000308004945000000008F820044F9 -:10E310003C03FFFF34637FFF00431024AF820044BF -:10E320008F83005408004938240200048F8300546E -:10E330003C0200018C425DA82463FFF600431023D9 -:10E340002C42000A144000782402000508004945C8 -:10E35000000000008F8202203C03F70000431025DC -:10E36000AF8202208F8202202403FFFB004310248F -:10E37000AF8202208F82022034420002AF8202204C -:10E380003C023F00344200E0AF8202008F82020074 -:10E390002403FFFD00431024AF8202002404000187 -:10E3A0003405FFFFAF8402048F8300548F82005432 -:10E3B000080048EC246300018F820054006210239F -:10E3C0002C4200021440FFFC000000008F82022457 -:10E3D0000004204000A4102B1040FFF200000000B9 -:10E3E0008F8202203C03F70000431025AF820220F9 -:10E3F0008F8202143C03FFFF004310243442251F88 -:10E40000AF8202148F8202202403FFFB00431024FA -:10E41000AF8202208F8202203C04F700348400087F -:10E4200034420002AF8202208F8202203C033F0070 -:10E43000346300E200441025AF820220AF83020063 -:10E440008F8400F0276217F81482000224850008E8 -:10E45000276510008F8200F410A200073C038000A3 -:10E46000346300403C02000124425C70AC82000036 -:10E47000AC830004AF8500F08F8300540800493856 -:10E48000240200068F8300543C0200018C425DA8E8 -:10E490002463FFF6004310232C42000A144000229C -:10E4A0002402000708004945000000008F8200E0B8 -:10E4B000AF8200E48F8200E0AF8200E88F8202200A -:10E4C00034420004AF8202208F8202202403FFF72F -:10E4D00000431024AF8202208F82004434428080A7 -:10E4E000AF8200448F830054240200083C010001E5 -:10E4F000AC225CE43C01000108004947AC235DA864 -:10E500008F8300543C0200018C425DA82463D8F044 -:10E51000004310232C42271014400003240200095A -:10E520003C010001AC225CE403E0000800000000B4 -:10E5300000000000000000000000000027BDFFD820 -:10E54000AFB2001800809021AFB3001C00A098214A -:10E55000AFB1001400C08821AFB0001000008021CE -:10E56000AFBF0020A62000000C004D4B240400018A -:10E57000261000012E0200201440FFFB00000000C6 -:10E580000C004D4B000020210C004D4B24040001D9 -:10E590000C004D4B240400010C004D4B00002021C9 -:10E5A000241000100250102410400002000020210E -:10E5B000240400010C004D4B001080421600FFFAAD -:10E5C0000250102424100010027010241040000289 -:10E5D00000002021240400010C004D4B001080425B -:10E5E0001600FFFA027010240C004D7134108000E8 -:10E5F0000C004D71000000000C004D2B00000000CD -:10E600005040000500108042962200000050102566 -:10E61000A6220000001080421600FFF70000000054 -:10E620000C004D71000000008FBF00208FB3001C54 -:10E630008FB200188FB100148FB0001003E00008F3 -:10E6400027BD002827BDFFD8AFB100140080882166 -:10E65000AFB2001800A09021AFB3001C00C09821F9 -:10E66000AFB0001000008021AFBF00200C004D4B68 -:10E6700024040001261000012E0200201440FFFB9C -:10E68000000000000C004D4B000020210C004D4B01 -:10E69000240400010C004D4B000020210C004D4BC8 -:10E6A0002404000124100010023010241040000245 -:10E6B00000002021240400010C004D4B001080427A -:10E6C0001600FFFA0230102424100010025010240B -:10E6D0001040000200002021240400010C004D4BDA -:10E6E000001080421600FFFA025010240C004D4B1F -:10E6F000240400010C004D4B000020213410800048 -:10E7000096620000005010241040000200002021FA -:10E71000240400010C004D4B001080421600FFF84D -:10E72000000000000C004D71000000008FBF0020B1 -:10E730008FB3001C8FB200188FB100148FB000107F -:10E7400003E0000827BD00283C0300018C635D0046 -:10E750003C0200018C425D4827BDFFD8AFBF0020BE -:10E76000AFB1001C10620003AFB000183C01000103 -:10E77000AC235D482463FFFF2C6200131040034963 -:10E78000000310803C010001002208218C225B3034 -:10E7900000400008000000000C004D7100008021C6 -:10E7A00034028000A7A2001027B100100C004D4BCE -:10E7B00024040001261000012E0200201440FFFB5B -:10E7C000000000000C004D4B000020210C004D4BC0 -:10E7D000240400010C004D4B000020210C004D4B87 -:10E7E0002404000124100010320200011040000235 -:10E7F00000002021240400010C004D4B0010804239 -:10E800001600FFFA32020001241000100C004D4BDC -:10E8100000002021001080421600FFFC00000000D4 -:10E820000C004D4B240400010C004D4B0000202136 -:10E830003410800096220000005010241040000286 -:10E8400000002021240400010C004D4B00108042E8 -:10E850001600FFF8000000000C004D7100000000E1 -:10E8600008004D242402000227B10010A7A00010C8 -:10E87000000080210C004D4B2404000126100001F3 -:10E880002E0200201440FFFB000000000C004D4B46 -:10E89000000020210C004D4B240400010C004D4BC6 -:10E8A000240400010C004D4B000020212410001016 -:10E8B0003202000110400002000020212404000167 -:10E8C0000C004D4B001080421600FFFA320200018E -:10E8D000241000100C004D4B00002021001080423D -:10E8E0001600FFFC000000000C004D713410800089 -:10E8F0000C004D71000000000C004D2B00000000CA -:10E900005040000500108042962200000050102563 -:10E91000A6220000001080421600FFF70000000051 -:10E920000C004D710000000097A2001030428000E2 -:10E93000144002DC2402000308004D240000000003 -:10E9400024021200A7A2001027B1001000008021AD -:10E950000C004D4B24040001261000012E02002063 -:10E960001440FFFB000000000C004D4B0000202174 -:10E970000C004D4B240400010C004D4B00002021E5 -:10E980000C004D4B24040001241000103202000141 -:10E990001040000200002021240400010C004D4B17 -:10E9A000001080421600FFFA32020001241000100D -:10E9B0000C004D4B00002021001080421600FFFC8F -:10E9C000000000000C004D4B240400010C004D4BD6 -:10E9D00000002021341080009622000000501024F6 -:10E9E0001040000200002021240400010C004D4BC7 -:10E9F000001080421600FFF8000000000C004D716E -:10EA0000000000008F83005408004D16240200040B -:10EA10008F8300543C0200018C425DB82463FF9C4C -:10EA2000004310232C4200641440029E2402000282 -:10EA30003C0300018C635DBC106202972C620003F2 -:10EA40001440029624020011240200031062000503 -:10EA500024020004106202912402000F08004D24D9 -:10EA60002402001108004D24240200052402001491 -:10EA7000A7A2001027B10010000080210C004D4B10 -:10EA800024040001261000012E0200201440FFFB88 -:10EA9000000000000C004D4B000020210C004D4BED -:10EAA000240400010C004D4B000020210C004D4BB4 -:10EAB0002404000124100010320200011040000262 -:10EAC00000002021240400010C004D4B0010804266 -:10EAD0001600FFFA32020001241000103202001268 -:10EAE0001040000200002021240400010C004D4BC6 -:10EAF000001080421600FFFA320200120C004D4B4B -:10EB0000240400010C004D4B000020213410800033 -:10EB10009622000000501024104000020000202126 -:10EB2000240400010C004D4B001080421600FFF839 -:10EB3000000000000C004D71000000008F830054A5 -:10EB400008004D16240200068F8300543C02000189 -:10EB50008C425DB82463FF9C004310232C42006468 -:10EB6000144002502402000708004D240000000059 -:10EB700024020006A7A2001027B100100000802187 -:10EB80000C004D4B24040001261000012E02002031 -:10EB90001440FFFB000000000C004D4B0000202142 -:10EBA0000C004D4B240400010C004D4B00002021B3 -:10EBB0000C004D4B2404000124100010320200010F -:10EBC0001040000200002021240400010C004D4BE5 -:10EBD000001080421600FFFA3202000124100010DB -:10EBE0003202001310400002000020212404000122 -:10EBF0000C004D4B001080421600FFFA3202001349 -:10EC00000C004D4B240400010C004D4B0000202152 -:10EC100034108000962200000050102410400002A2 -:10EC200000002021240400010C004D4B0010804204 -:10EC30001600FFF8000000000C004D7100000000FD -:10EC40008F83005408004D16240200088F8300545F -:10EC50003C0200018C425DB82463FF9C00431023FA -:10EC60002C4200641440020F2402000908004D24C5 -:10EC70000000000027B10010A7A0001000008021B4 -:10EC80000C004D4B24040001261000012E02002030 -:10EC90001440FFFB000000000C004D4B0000202141 -:10ECA0000C004D4B240400010C004D4B24040001CA -:10ECB0000C004D4B000020212410001032020001F6 -:10ECC0001040000200002021240400010C004D4BE4 -:10ECD000001080421600FFFA3202000124100010DA -:10ECE000320200181040000200002021240400011C -:10ECF0000C004D4B001080421600FFFA3202001843 -:10ED00000C004D71341080000C004D7100000000AB -:10ED10000C004D2B00000000504000050010804208 -:10ED20009622000000501025A6220000001080420C -:10ED30001600FFF7000000000C004D71000080215C -:10ED400097A2001027B1001034420001A7A20010C2 -:10ED50000C004D4B24040001261000012E0200205F -:10ED60001440FFFB000000000C004D4B0000202170 -:10ED70000C004D4B240400010C004D4B00002021E1 -:10ED80000C004D4B2404000124100010320200013D -:10ED90001040000200002021240400010C004D4B13 -:10EDA000001080421600FFFA320200012410001009 -:10EDB000320200181040000200002021240400014B -:10EDC0000C004D4B001080421600FFFA3202001872 -:10EDD0000C004D4B240400010C004D4B0000202181 -:10EDE00034108000962200000050102410400002D1 -:10EDF00000002021240400010C004D4B0010804233 -:10EE00001600FFF8000000000C004D71000000002B -:10EE10008F83005408004D162402000A8F8300548B -:10EE20003C0200018C425DB82463FF9C0043102328 -:10EE30002C4200641440019B2402000B08004D2466 -:10EE40000000000027B10010A7A0001000008021E2 -:10EE50000C004D4B24040001261000012E0200205E -:10EE60001440FFFB000000000C004D4B000020216F -:10EE70000C004D4B240400010C004D4B24040001F8 -:10EE80000C004D4B00002021241000103202000124 -:10EE90001040000200002021240400010C004D4B12 -:10EEA000001080421600FFFA320200012410001008 -:10EEB000320200171040000200002021240400014B -:10EEC0000C004D4B001080421600FFFA3202001772 -:10EED0000C004D71341080000C004D7100000000DA -:10EEE0000C004D2B00000000504000050010804237 -:10EEF0009622000000501025A6220000001080423B -:10EF00001600FFF7000000000C004D71000080218A -:10EF100097A2001027B1001034420700A7A20010EA -:10EF20000C004D4B24040001261000012E0200208D -:10EF30001440FFFB000000000C004D4B000020219E -:10EF40000C004D4B240400010C004D4B000020210F -:10EF50000C004D4B2404000124100010320200016B -:10EF60001040000200002021240400010C004D4B41 -:10EF7000001080421600FFFA320200012410001037 -:10EF8000320200171040000200002021240400017A -:10EF90000C004D4B001080421600FFFA32020017A1 -:10EFA0000C004D4B240400010C004D4B00002021AF -:10EFB00034108000962200000050102410400002FF -:10EFC00000002021240400010C004D4B0010804261 -:10EFD0001600FFF8000000000C004D71000000005A -:10EFE0008F83005408004D162402000C8F830054B8 -:10EFF0003C0200018C425DB82463FF9C0043102357 -:10F000002C420064144001272402001208004D2401 -:10F010000000000027B10010A7A000100000802110 -:10F020000C004D4B24040001261000012E0200208C -:10F030001440FFFB000000000C004D4B000020219D -:10F040000C004D4B240400010C004D4B2404000126 -:10F050000C004D4B00002021241000103202000152 -:10F060001040000200002021240400010C004D4B40 -:10F07000001080421600FFFA320200012410001036 -:10F08000320200141040000200002021240400017C -:10F090000C004D4B001080421600FFFA32020014A3 -:10F0A0000C004D71341080000C004D710000000008 -:10F0B0000C004D2B00000000504000050010804265 -:10F0C0009622000000501025A62200000010804269 -:10F0D0001600FFF7000000000C004D7100008021B9 -:10F0E00097A2001027B1001034420010A7A2001010 -:10F0F0000C004D4B24040001261000012E020020BC -:10F100001440FFFB000000000C004D4B00002021CC -:10F110000C004D4B240400010C004D4B000020213D -:10F120000C004D4B24040001241000103202000199 -:10F130001040000200002021240400010C004D4B6F -:10F14000001080421600FFFA320200012410001065 -:10F1500032020014104000020000202124040001AB -:10F160000C004D4B001080421600FFFA32020014D2 -:10F170000C004D4B240400010C004D4B00002021DD -:10F18000341080009622000000501024104000022D -:10F1900000002021240400010C004D4B001080428F -:10F1A0001600FFF8000000000C004D710000000088 -:10F1B0008F83005408004D16240200138F830054DF -:10F1C0003C0200018C425DB82463FF9C0043102385 -:10F1D0002C420064144000B32402000D08004D24AA -:10F1E0000000000027B10010A7A00010000080213F -:10F1F0000C004D4B24040001261000012E020020BB -:10F200001440FFFB000000000C004D4B00002021CB -:10F210000C004D4B240400010C004D4B2404000154 -:10F220000C004D4B00002021241000103202000180 -:10F230001040000200002021240400010C004D4B6E -:10F24000001080421600FFFA320200012410001064 -:10F2500032020018104000020000202124040001A6 -:10F260000C004D4B001080421600FFFA32020018CD -:10F270000C004D71341080000C004D710000000036 -:10F280000C004D2B00000000504000050010804293 -:10F290009622000000501025A62200000010804297 -:10F2A0001600FFF7000000000C004D7100008021E7 -:10F2B00097A2001027B100103042FFFEA7A2001055 -:10F2C0000C004D4B24040001261000012E020020EA -:10F2D0001440FFFB000000000C004D4B00002021FB -:10F2E0000C004D4B240400010C004D4B000020216C -:10F2F0000C004D4B240400012410001032020001C8 -:10F300001040000200002021240400010C004D4B9D -:10F31000001080421600FFFA320200012410001093 -:10F3200032020018104000020000202124040001D5 -:10F330000C004D4B001080421600FFFA32020018FC -:10F340000C004D4B240400010C004D4B000020210B -:10F35000341080009622000000501024104000025B -:10F3600000002021240400010C004D4B00108042BD -:10F370001600FFF8000000000C004D7100000000B6 -:10F380008F83005408004D162402000E240208400A -:10F39000A7A2001027B10010000080210C004D4BE7 -:10F3A00024040001261000012E0200201440FFFB5F -:10F3B000000000000C004D4B000020210C004D4BC4 -:10F3C000240400010C004D4B000020210C004D4B8B -:10F3D0002404000124100010320200011040000239 -:10F3E00000002021240400010C004D4B001080423D -:10F3F0001600FFFA3202000124100010320200133E -:10F400001040000200002021240400010C004D4B9C -:10F41000001080421600FFFA320200130C004D4B20 -:10F42000240400010C004D4B00002021341080000A -:10F4300096220000005010241040000200002021FD -:10F44000240400010C004D4B001080421600FFF810 -:10F45000000000000C004D71000000008F8300547C -:10F46000240200103C010001AC225D003C010001BF -:10F4700008004D26AC235DB88F8300543C02000188 -:10F480008C425DB82463FF9C004310232C4200642F -:10F490001440000400000000240200113C0100019F -:10F4A000AC225D008FBF00208FB1001C8FB0001810 -:10F4B00003E0000827BD00288F8500448F820044A8 -:10F4C0003C030001004310253C030008AF820044C8 -:10F4D0008F8400548F82005400A3282408004D37E5 -:10F4E000248400018F820054008210232C420002E9 -:10F4F0001440FFFC000000008F8200443C03FFFE2C -:10F500003463FFFF00431024AF8200448F83005414 -:10F510008F82005408004D45246300018F820054FF -:10F52000006210232C4200021440FFFC0000000087 -:10F5300003E0000800A010218F8300443C02FFF08C -:10F540003442FFFF00042480006218243C020002C1 -:10F550000082202500641825AF8300448F82004478 -:10F560003C03FFFE3463FFFF00431024AF820044DE -:10F570008F8300548F82005408004D5E2463000185 -:10F580008F820054006210232C4200021440FFFCC2 -:10F59000000000008F8200443C030001004310255E -:10F5A000AF8200448F8300548F82005408004D6B5B -:10F5B000246300018F820054006210232C42000259 -:10F5C0001440FFFC0000000003E000080000000001 -:10F5D0008F8200443C03FFF03463FFFF004310249C -:10F5E000AF8200448F8200443C0300010043102599 -:10F5F000AF8200448F8300548F82005408004D7FF7 -:10F60000246300018F820054006210232C42000208 -:10F610001440FFFC000000008F8200443C03FFFE0A -:10F620003463FFFF00431024AF8200448F830054F3 -:10F630008F82005408004D8D246300018F82005496 -:10F64000006210232C4200021440FFFC0000000066 -:10F6500003E000080000000027BDFFC8AFB300248E -:10F6600000809821AFB5002C00A0A821AFB20020E7 -:10F6700000C0902132A2FFFFAFBF0030AFB400281E -:10F68000AFB1001CAFB0001814400034A7B2001096 -:10F690003271FFFF27B20010000080210C004D4B9B -:10F6A00024040001261000012E0200201440FFFB5C -:10F6B000000000000C004D4B000020210C004D4BC1 -:10F6C000240400010C004D4B000020210C004D4B88 -:10F6D0002404000124100010320200011040000236 -:10F6E00000002021240400010C004D4B001080423A -:10F6F0001600FFFA3202000124100010023010241C -:10F700001040000200002021240400010C004D4B99 -:10F71000001080421600FFFA023010240C004D4BFE -:10F72000240400010C004D4B000020213410800007 -:10F7300096420000005010241040000200002021DA -:10F74000240400010C004D4B001080421200007593 -:10F750000000000008004DC9000000003274FFFFE7 -:10F7600027B10010A7A00010000080210C004D4B15 -:10F7700024040001261000012E0200201440FFFB8B -:10F78000000000000C004D4B000020210C004D4BF0 -:10F79000240400010C004D4B240400010C004D4BCF -:10F7A000000020212410001032020001104000024D -:10F7B00000002021240400010C004D4B0010804269 -:10F7C0001600FFFA320200012410001002901024EB -:10F7D0001040000200002021240400010C004D4BC9 -:10F7E000001080421600FFFA029010240C004D71A8 -:10F7F000341080000C004D71000000000C004D2BF7 -:10F8000000000000504000050010804296220000D9 -:10F8100000501025A6220000001080421600FFF7BD -:10F82000000000000C004D710000000032A5FFFF39 -:10F830002402000154A200042402000297A2001036 -:10F8400008004E140052102514A200063271FFFF6A -:10F8500097A200100012182700431024A7A200103E -:10F860003271FFFF27B20010000080210C004D4BC9 -:10F8700024040001261000012E0200201440FFFB8A -:10F88000000000000C004D4B000020210C004D4BEF -:10F89000240400010C004D4B000020210C004D4BB6 -:10F8A0002404000124100010320200011040000264 -:10F8B00000002021240400010C004D4B0010804268 -:10F8C0001600FFFA3202000124100010023010244A -:10F8D0001040000200002021240400010C004D4BC8 -:10F8E000001080421600FFFA023010240C004D4B2D -:10F8F000240400010C004D4B000020213410800036 -:10F900009642000000501024104000020000202108 -:10F91000240400010C004D4B001080421600FFF83B -:10F92000000000000C004D71000000008FBF00308F -:10F930008FB5002C8FB400288FB300248FB2002025 -:10F940008FB1001C8FB0001803E0000827BD0038FD -:10F9500000000000000000000000000027BDFFE8DC -:10F96000AFBF00103C030001007718218C6383AC0B -:10F97000240200081462022C008030213C020001A5 -:10F980008C425D9814400033000000008F850224F3 -:10F9900038A300202C63000138A200102C42000183 -:10F9A000006218251460000D38A300302C6300019C -:10F9B00038A204002C4200010062182514600007E0 -:10F9C00038A304022C63000138A204042C42000175 -:10F9D0000062182510600005000000000C00429B2A -:10F9E0000000000008004E8D2402000E0C0043DDD4 -:10F9F000000000003C0500018CA55CC80C0052A270 -:10FA0000000020213C0300018C635CC82402000438 -:10FA1000146200052403FFFB3C0200018C425CC41D -:10FA200008004E892403FFF73C0200018C425CC4AD -:10FA3000004310243C010001AC225CC42402000EEF -:10FA40003C0100010C00429BAC227DD00800508795 -:10FA5000000000008F8202203C03040000431024B9 -:10FA6000104000272403FFBF8F8502243C020001C1 -:10FA70008C427DDC00A32024004310241482000C5F -:10FA8000000000003C0200018C427DE024420001A5 -:10FA90003C010001AC227DE02C4200021440000831 -:10FAA000240200013C01000108004EADAC227E00A2 -:10FAB0003C010001AC207DE03C010001AC207E0057 -:10FAC0003C0200018C427E001040000630A2004043 -:10FAD00010400004240200013C01000108004EB85F -:10FAE000AC227E043C010001AC207E043C010001FC -:10FAF000AC257DDC3C01000108004EC8AC207E1026 -:10FB0000240200013C010001AC227E103C010001F6 -:10FB1000AC207E003C010001AC207DE03C010001F6 -:10FB2000AC207E043C010001AC207DDC3C030001E4 -:10FB30008C637DD03C0200018C427DD410620003B6 -:10FB40003C0202003C010001AC237DD400C2102421 -:10FB5000104000072463FFFF8F820220240300016E -:10FB60003C010001AC235CCC080050853C03F7004D -:10FB70002C62000E104001A8000310803C0100011F -:10FB8000002208218C225B80004000080000000059 -:10FB90003C010001AC207E003C010001AC207DE076 -:10FBA0003C010001AC207DDC3C010001AC207E0466 -:10FBB0003C010001AC207DF83C010001AC207DF04F -:10FBC0000C00486AAF800224240200023C010001BC -:10FBD000AC227DD03C0200018C427E1014400056C5 -:10FBE0003C03FDFF8EE200003463FFFF004310245E -:10FBF0000C00429BAEE20000AF8002048F82020044 -:10FC00002403FFFD00431024AF8202003C010001E9 -:10FC1000AC207E208F8300543C0200018C427DF892 -:10FC2000240400013C010001AC247E0C24420001AC -:10FC30003C010001AC227DF82C4200043C01000193 -:10FC4000AC237DF414400006240200033C010001B3 -:10FC5000AC245CCC3C01000108005083AC207DF852 -:10FC60003C01000108005083AC227DD08F830054FA -:10FC70003C0200018C427DF42463D8F00043102341 -:10FC80002C42271014400003240200043C01000110 -:10FC9000AC227DD03C0200018C427E101440002634 -:10FCA0003C03FDFF8EE200003463FFFF004310249D -:10FCB00008005083AEE200003C0400018C845D9C8F -:10FCC0003C0100010C00508AAC207DE83C020001A0 -:10FCD0008C427E1CAF8202043C0200018C427E10EA -:10FCE000144000153C03FDFF8EE200003463FFFF6B -:10FCF00000431024AEE200008F8202043042003044 -:10FD00001440013C240200023C0300018C637E1C71 -:10FD1000240200053C010001AC227DD03C01000121 -:10FD200008005083AC237E203C0200018C427E10F0 -:10FD3000104000103C03FDFF3C0200018C425D6C52 -:10FD4000244200013C010001AC225D6C2C42000207 -:10FD500014400131240200013C010001AC225D7419 -:10FD60003C010001AC205D6C3C01000108005083A7 -:10FD7000AC225CCC8EE200003463FFFF0043102411 -:10FD8000AEE200003C0200018C427E0010400122E5 -:10FD9000000000003C0200018C427DDC1040011E8E -:10FDA000000000003C010001AC227E082402000398 -:10FDB0003C010001AC227DE0080050242402000632 -:10FDC0003C010001AC207DE88F82020434420040F7 -:10FDD000AF8202043C0200018C427E202403000713 -:10FDE0003C010001AC237DD0344200403C010001C5 -:10FDF000AC227E203C0200018C427E0010400005B7 -:10FE0000000000003C0200018C427DDC104000F943 -:10FE1000240200023C05000124A57DE08CA2000024 -:10FE20002C424E21104000F3240200023C0200014B -:10FE30008C427E04104000F82404FFBF3C02000105 -:10FE40008C427DDC3C0300018C637E08004410245E -:10FE50000064182410430004240200013C01000146 -:10FE600008005083AC227DD024020003ACA2000025 -:10FE7000240200083C010001AC227DD03C020001BC -:10FE80008C427E0C1040000C240200013C04000156 -:10FE90000C0050978C847DDC3C0200018C427E2853 -:10FEA00014400005240200013C0200018C427E2423 -:10FEB00010400006240200013C010001AC225CCC91 -:10FEC0003C01000108005083AC207DF83C02000199 -:10FED0008C427DF03C0300018C637DDC2C420001F0 -:10FEE000000210C0306300083C010001AC227DF02C -:10FEF0003C010001AC237DEC8F83005424020009F7 -:10FF00003C010001AC227DD03C010001080050837F -:10FF1000AC237DF48F8300543C0200018C427DF4BD -:10FF20002463D8F0004310232C422710144000A86B -:10FF3000000000003C0200018C427E0010400005E1 -:10FF4000000000003C0200018C427DDC104000A952 -:10FF5000240200023C03000124637DE08C62000067 -:10FF60002C424E21104000A3240200023C0200015A -:10FF70008C427E0C1040000E000000003C0200018C -:10FF80008C427DDC3C010001AC207E0C30420080C4 -:10FF90001040002F2402000C8F82020430420080A7 -:10FFA0001440000C24020003080050112402000C2D -:10FFB0003C0200018C427DDC304200801440000590 -:10FFC000240200038F820204304200801040001F90 -:10FFD00024020003AC6200002402000A3C0100017C -:10FFE000AC227DD03C04000124847E188C82000069 -:10FFF0003C0300018C637DF000431025AF820204B6 -:020000021000EC -:100000008C8300003C0400018C847DF02402000BF2 -:100010003C010001AC227DD0006418253C010001A8 -:10002000AC237E203C05000124A57DE08CA20000CD -:100030002C424E211040006F240200023C020001BD -:100040008C427E1010400005000000002402000CCD -:100050003C01000108005083AC227DD03C0200012D -:100060008C427E001040006C000000003C04000147 -:100070008C847DDC1080005E308200083C0300012F -:100080008C637DEC10620064240200033C010001DB -:10009000AC247E08ACA20000240200063C01000152 -:1000A00008005083AC227DD08F82020034420002CF -:1000B000AF8202008F8300542402000D3C01000136 -:1000C000AC227DD03C010001AC237DF48F83005431 -:1000D0003C0200018C427DF42463D8F000431023DD -:1000E0002C4227101440003A000000003C0200019E -:1000F0008C427E10104000292402000E3C030001B7 -:100100008C637E243C01000114600015AC227DD07C -:100110000C0043DD000000003C0500018CA55CC81C -:100120000C0052A2000020213C0300018C635CC83B -:1001300024020004146200052403FFFB3C020001BA -:100140008C425CC4080050522403FFF73C020001BB -:100150008C425CC4004310243C010001AC225CC40E -:100160008EE200003C03020000431025AEE20000D6 -:100170008F8202243C010001AC227E2C8F8202205F -:100180002403FFFB00431024AF8202208F82022051 -:100190003442000208005083AF8202203C0200017A -:1001A0008C427E0010400005000000003C0200016F -:1001B0008C427DDC1040000F240200023C02000152 -:1001C0008C427DE02C424E211040000A24020002A5 -:1001D0003C0200018C427E001040000F0000000035 -:1001E0003C0200018C427DDC1440000B000000004A -:1001F000240200023C01000108005083AC227DD0A3 -:100200003C0200018C427E00104000030000000010 -:100210000C00429B000000008F8202203C03F7008C -:1002200000431025AF8202208FBF001003E00008BA -:1002300027BD00183C03000124637E288C62000067 -:1002400010400005344220003C010001AC227E1C1D -:1002500008005095AC6000003C010001AC247E1CFD -:1002600003E000080000000027BDFFE030820030FE -:10027000AFBF00183C010001AC227E24144000678F -:100280003C02FFFF34421F0E008210241440006124 -:1002900024020030308220001040005D3083800056 -:1002A00000031A0230820001000212003C04000127 -:1002B0008C845D9C00621825000331C23C03000160 -:1002C00024635D78308280000002120230840001D5 -:1002D0000004220000441025000239C200061080EC -:1002E0000043102100471021904300002402000128 -:1002F00010620025000000001060000724020002C8 -:1003000010620013240200031062002C3C05000F51 -:10031000080050F9000000008F8202002403FEFF55 -:1003200000431024AF8202008F8202203C03FFFEB4 -:100330003463FFFF00431024AF8202203C01000120 -:10034000AC207E443C01000108005104AC207E4CEE -:100350008F82020034420100AF8202008F820220AD -:100360003C03FFFE3463FFFF00431024AF820220F2 -:10037000240201003C010001AC227E443C0100014A -:1003800008005104AC207E4C8F8202002403FEFF43 -:1003900000431024AF8202008F8202203C03000140 -:1003A00000431025AF8202203C010001AC207E44B6 -:1003B0003C01000108005104AC237E4C8F820200F6 -:1003C00034420100AF8202008F8202203C03000110 -:1003D00000431025AF820220240201003C010001ED -:1003E000AC227E443C01000108005104AC237E4C49 -:1003F00034A5FFFF3C04000124845BB8AFA30010C8 -:100400000C002403AFA000140800510400000000F9 -:10041000240200303C010001AC227E288FBF00186E -:1004200003E0000827BD00200000000027BDFFC832 -:10043000AFB2002800809021AFB3002C00A098211B -:10044000AFB0002000C080213C04000124845BD0B8 -:100450003C0500093C0200018C425CC834A59001B7 -:100460000240302102603821AFBF0030AFB100241C -:10047000A7A0001AAFB000140C002403AFA2001014 -:1004800024020002126200832E6200031040000565 -:10049000240200011262000A000000000800529BC2 -:1004A0000000000024020004126200FA2402000886 -:1004B000126200F93C02FFEC0800529B00000000B1 -:1004C0003C0200018C425CC4304200021440000433 -:1004D000001289403C02FFFB3442FFFF02028024ED -:1004E0003C01000100310821AC307E3C3C02400060 -:1004F000020210241040004E001023C2308400304D -:10050000001013823042001C3C03000124635D088C -:1005100000431021008238213C02002002021024F6 -:1005200010400006240201003C01000100310821B6 -:10053000AC227E40080051503C0200803C0100018A -:1005400000310821AC207E403C02008002021024D1 -:1005500010400006001219403C0200013C0100015D -:10056000002308210800515CAC227E480012114093 -:100570003C01000100220821AC207E4894E40000E8 -:100580003C0300018C635DBC240200051062001076 -:10059000A7A400183202400010400002348240003C -:1005A000A7A200182404000194E20002240500041C -:1005B00024E60002344200010C00498EA4E200024D -:1005C00024040001000028210C00498E27A60018F1 -:1005D0003C0200018C425CC8241100013C01000176 -:1005E000AC315CD414530004320280000C00429BF6 -:1005F00000000000320280001040011F00000000D7 -:100600000C00429B000000003C0300018C635DBCB9 -:100610002402000510620118240200023C010001BE -:10062000AC315CCC3C0100010800529BAC225CC8A0 -:10063000240400012405000427B0001A0C00498E90 -:100640000200302124040001000028210C00498E02 -:10065000020030213C020001005110218C427E3406 -:100660003C0400018C845CC83C03BFFF3463FFFF83 -:100670003C010001AC335CD4004310243C01000178 -:1006800000310821109300FAAC227E340800529BFE -:10069000000000003C02200002021024104000056F -:1006A000240200013C010001AC225D98080051AD1C -:1006B000001289403C010001AC205D980012894085 -:1006C0003C01000100310821AC307E383C02400082 -:1006D0000202102414400016000000003C02000139 -:1006E0008C425D9810400008240400042405000199 -:1006F0000C004D9324062000240200013C0100015F -:1007000000370821AC2283AC3C02000100511021CB -:100710008C427E303C03BFFF3463FFFF0043102454 -:100720003C0100010031082108005299AC227E30C2 -:100730003C0200018C425D98104000283C0300A060 -:10074000020310245443000D3C0200203C0200012F -:100750008C425D9C240301003C0100010031082112 -:10076000AC237E443C0300013C0100010031082120 -:10077000AC237E4C080051F03442040002021024E5 -:1007800010400008240301003C0200018C425D9CE3 -:100790003C01000100310821AC237E44080051F0E7 -:1007A000344208003C020080020210241040002E57 -:1007B0003C0300013C0200018C425D9C3C010001B5 -:1007C00000310821AC237E4C34420C003C01000176 -:1007D000AC225D9C08005218240400013C02002059 -:1007E0000202102410400006240201003C01000116 -:1007F00000310821AC227E44080052013C020080F6 -:100800003C01000100310821AC207E443C02008004 -:100810000202102410400007001219403C0200019F -:100820003C01000100230821AC227E4C0800520F3D -:1008300024040001001211403C01000100220821A3 -:10084000AC207E4C240400010000282127B0001EAB -:100850000C00494C02003021240400010000282132 -:100860000C00494C02003021240400012405000141 -:1008700027B0001C0C00494C020030212404000168 -:10088000240500010C00494C020030210800529957 -:10089000000000003C02FFEC3442FFFF0202802413 -:1008A0003C02000802028025001211403C010001B8 -:1008B00000220821AC307E383C02200002021024C5 -:1008C00010400009000000003C0200018C425D74F1 -:1008D00014400005240200013C010001AC225D9897 -:1008E0000800523A3C0240003C010001AC205D98F7 -:1008F0003C024000020210241440001E00000000D0 -:100900003C0200018C425D983C010001AC205CE09F -:1009100010400007240220203C010001AC225D9C15 -:10092000240200013C01000100370821AC2283AC05 -:100930003C04BFFF001219403C020001004310219B -:100940008C427E303C0500018CA55CC83484FFFFDE -:10095000004410243C01000100230821AC227E3019 -:100960002402000110A20044000000000800529977 -:10097000000000003C0200018C425D981040001C09 -:10098000240220003C010001AC225D9C3C0300A03D -:100990000203102414430005001211403402A00089 -:1009A0003C01000108005294AC225D9C3C03000114 -:1009B000006218218C637E383C0200200062102403 -:1009C00010400004240220013C0100010800529460 -:1009D000AC225D9C3C020080006210241040001F8D -:1009E0003402A0013C01000108005294AC225D9C3D -:1009F0003C0200200202102410400007001219409F -:100A0000240201003C01000100230821AC227E44A5 -:100A1000080052883C020080001211403C01000195 -:100A200000220821AC207E443C02008002021024F7 -:100A300010400006001219403C0200013C01000178 -:100A40000023082108005294AC227E4C0012114071 -:100A50003C01000100220821AC207E4C3C03000137 -:100A60008C635CC8240200011062000300000000D7 -:100A70000C00429B000000008FBF00308FB3002CA1 -:100A80008FB200288FB100248FB0002003E000084F -:100A900027BD003827BDFFD8AFB2002000809021CD -:100AA000AFB1001C0000882124020002AFBF002467 -:100AB000AFB00018A7A0001210A200D3A7A000108A -:100AC0002CA20003104000052402000110A2000A1D -:100AD00000128140080053800220102124020004EB -:100AE00010A2007D2402000810A2007C0012294000 -:100AF00008005380022010213C03000100701821DF -:100B00008C637E3C3C0240000062102414400009CB -:100B1000240400013C027FFF3442FFFF006288246E -:100B20003C01000100300821AC317E3408005380C4 -:100B300002201021240500010C00494C27A60010BA -:100B400024040001240500010C00494C27A60010D4 -:100B500097A2001030420004104000343C114000C5 -:100B60003C0200018C425DBC2443FFFF2C62000666 -:100B700010400034000310803C01000100220821D5 -:100B80008C225BE00040000800000000240400010B -:100B90002405001127B000120C00494C020030213E -:100BA00024040001240500110C00494C02003021EE -:100BB00097A5001230A24000104000023C04001033 -:100BC0003C0400083C0300010800530130A28000EF -:100BD000240400012405001427B000120C00494C25 -:100BE0000200302124040001240500140C00494CAB -:100BF0000200302197A5001230A210001040000220 -:100C00003C0400103C0400083C03000130A2080032 -:100C1000544000013C0300023C02800002221025E7 -:100C2000006418250800530E004388253C1100017C -:100C3000023088218E317E3C3C027FFF3442FFFF30 -:100C4000022288243C0200018C425CD81040001D26 -:100C5000001211403C0200018C425D9810400002DD -:100C60003C02200002228825001211403C010001B4 -:100C7000002208218C227E40104000033C0200200C -:100C800008005322022288253C02FFDF3442FFFF86 -:100C900002228824001211403C0100010022082198 -:100CA0008C227E48104000033C0200800800532D37 -:100CB000022288253C02FF7F3442FFFF0222882463 -:100CC000001211403C01000100220821AC317E34A9 -:100CD0000800538002201021001229403C0300012B -:100CE000006518218C637E383C02400000621024AD -:100CF000144000083C027FFF3442FFFF006288245A -:100D00003C01000100250821AC317E3008005380F1 -:100D1000022010213C0200018C425CD810400033BC -:100D20003C11C00C3C0200018C425D743C04C00CC0 -:100D3000348420003C0300018C635D980002102B7A -:100D40000002102300441024106000030051882585 -:100D50003C022000022288253C02000100451021AF -:100D60008C427E44104000033C0200200800535D8A -:100D7000022288253C02FFDF3442FFFF0222882442 -:100D8000001211403C010001002208218C227E4CFF -:100D9000104000033C0200800800536802228825AE -:100DA0003C02FF7F3442FFFF022288243C02000104 -:100DB0008C425D60104000023C020800022288253F -:100DC0003C0200018C425D64104000023C020400C1 -:100DD000022288253C0200018C425D68104000061A -:100DE0003C0201000800537B022288253C027FFF61 -:100DF0003442FFFF00628824001211403C010001D0 -:100E000000220821AC317E30022010218FBF002447 -:100E10008FB200208FB1001C8FB0001803E00008D3 -:100E200027BD002827BDFFD8AFB400200080A02137 -:100E3000AFBF0024AFB3001CAFB20018AFB10014B5 -:100E4000AFB000108F9002003C0300018C635CC8BF -:100E50008F93022024020002106200632C620003C0 -:100E600010400005240200011062000A001419401D -:100E70000800544800000000240200041062005AD8 -:100E800024020008106200590014914008005448E0 -:100E9000000000003C040001008320218C847E3C83 -:100EA0003C110001022388218E317E343C02400037 -:100EB000008210241040003E3C0200080222102450 -:100EC00010400020361000023C02000100431021B7 -:100ED0008C427E4010400005361000203610010084 -:100EE0003C020020080053BD022288252402FEFF98 -:100EF000020280243C02FFDF3442FFFF02228824EA -:100F0000001411403C010001002208218C227E487F -:100F1000104000053C020001026298253C0200805E -:100F2000080053DC022288253C02FFFE3442FFFF0A -:100F3000026298243C02FF7F3442FFFF080053DC2A -:100F4000022288242402FEDF020280243C02FFFEEB -:100F50003442FFFF026298243C02FF5F3442FFFFED -:100F6000022288243C01000100230821AC207E409D -:100F70003C01000100230821AC207E480C00486A97 -:100F800000000000AF900200AF9302208F82022089 -:100F90002403FFFB00431024AF8202208F82022033 -:100FA00034420002AF820220080053F300141140C3 -:100FB0008F8202002403FFFD004310240C00486AC6 -:100FC000AF8202003C02BFFF3442FFFF0C00429B95 -:100FD00002228824001411403C0100010022082153 -:100FE00008005448AC317E34001491403C040001A8 -:100FF000009220218C847E383C110001023288212D -:101000008E317E303C0240000082102414400011DA -:10101000000000003C0200018C425D981440000674 -:101020003C02BFFF8F820200344200020C00486A7B -:10103000AF8202003C02BFFF3442FFFF0C00429B24 -:10104000022288243C010001003208210800544893 -:10105000AC317E303C0200018C425D9810400005AE -:101060003C0200203C0200018C425D741040002BC9 -:101070003C0200200082102410400007361000209F -:10108000240201003C01000100320821AC227E4410 -:1010900008005428361001003C01000100320821EC -:1010A000AC207E442402FEFF020280243C02008029 -:1010B0000082102410400007001419403C02000177 -:1010C0003C01000100230821AC227E4C0800543969 -:1010D00002629825001411403C0100010022082101 -:1010E000AC207E4C3C02FFFE3442FFFF026298249B -:1010F0000C00486A00000000AF900200AF9302208D -:101100008F8202202403FFFB00431024AF820220C1 -:101110008F82022034420002AF820220001411406C -:101120003C01000100220821AC317E308FBF002439 -:101130008FB400208FB3001C8FB200188FB1001441 -:101140008FB0001003E0000827BD00282448656127 -:101150006465723A202F70726F6A656374732F72C0 -:1011600063732F73772F67652F2E2F6E69632F663A -:10117000772F636F6D6D6F6E2F66776D61696E2E61 -:10118000632C7620312E312E322E313120313939F7 -:10119000382F30342F32372032323A31333A34322A -:1011A00020736875616E6720457870202400000008 -:1011B0007468655F4441574E00000000535441433A -:1011C0004B5F312000000000426164536E64526E38 -:1011D000670000003F456E71457674003F6E6F51A9 -:1011E00064457650000000006576526E6746756C67 -:1011F0006C000000496C6C436F6E66527800000012 -:1012000053656E64436B53756D00000052656376E1 -:10121000566C616E0000000000000000244865610B -:101220006465723A202F70726F6A656374732F72EF -:1012300063732F73772F67652F2E2F6E69632F6669 -:10124000772F636F6D6D6F6E2F74696D65722E638E -:101250002C7620312E312E322E3820313939382F4C -:1012600030372F33312031373A35383A343520731F -:101270006875616E6720457870202400542D446D98 -:101280006152643100000000542D446D61424200FF -:10129000542D446D613200003F6E6F5164547845A7 -:1012A000000000003F6E6F5164527845000000005E -:1012B000656E714D4576504661696C00656E714D85 -:1012C00045764661696C00006661696C456E454D06 -:1012D000000000003F456E71457674003F6E6F510F -:1012E00064457650000000006576526E6746756C66 -:1012F0006C00000000000000000000002448656150 -:101300006465723A202F70726F6A656374732F720E -:1013100063732F73772F67652F2E2F6E69632F6688 -:10132000772F636F6D6D6F6E2F636F6D6D616E6480 -:101330002E632C7620312E312E322E313020313951 -:1013400039382F31312F31382031373A31313A3174 -:101350003820736875616E6720457870202400001E -:101360003F4D626F78457674000000004E4F636F0A -:101370006D616E6400000000687374655F455252D1 -:1013800000000000412D45727242756300000000AC -:101390004552524F522D416464000000656E714DFC -:1013A0004576504661696C00656E714D45764661C3 -:1013B000696C00006661696C456E454D0000000077 -:1013C000442D4572724C617374000000442D4572C7 -:1013D000723200006D4373744D6445525200000038 -:1013E00070726F6D4D6445525200000046696C7416 -:1013F0004D64455252000000636D645F45525200D7 -:101400003F456E71457674003F6E6F51644576506E -:10141000000000006576526E6746756C6C00000037 -:101420000000000000006EA000007FBC00006E38CD -:1014300000008734000082B00000878000008780B1 -:1014400000006F540000769400007F0C000080A81C -:10145000000080740000878000007E70000080CC57 -:1014600000006E64000081CC00000000244865612B -:101470006465723A202F70726F6A656374732F729D -:1014800063732F73772F67652F2E2F6E69632F6617 -:10149000772F636F6D6D6F6E2F646D612E632C7689 -:1014A00020312E312E322E3320313939382F30343D -:1014B0002F32372032323A31333A34312073687563 -:1014C000616E67204578702024000000646D6172B1 -:1014D0006441544E00000000646D61777241544EC7 -:1014E00000000000000000000000000024486561CA -:1014F0006465723A202F70726F6A656374732F721D -:1015000063732F73772F67652F2E2F6E69632F6696 -:10151000772F636F6D6D6F6E2F74726163652E63CD -:101520002C7620312E312E322E3220313939382F7F -:1015300030342F32372032323A31333A353020735B -:101540006875616E672045787020240024486561C5 -:101550006465723A202F70726F6A656374732F72BC -:1015600063732F73772F67652F2E2F6E69632F6636 -:10157000772F636F6D6D6F6E2F646174612E632CB6 -:101580007620312E312E322E3220313939382F301B -:10159000342F32372032323A31333A3430207368C4 -:1015A00075616E67204578702024000046575F56AD -:1015B000455253494F4E3A2023312046726920410B -:1015C000707220372031373A35353A34382050445C -:1015D000542032303030000046575F434F4D504961 -:1015E0004C455F54494D453A2031373A35353A3408 -:1015F0003800000046575F434F4D50494C455F420D -:10160000593A2064657672637300000046575F4361 -:101610004F4D50494C455F484F53543A20636F6DCE -:10162000707574650000000046575F434F4D504988 -:101630004C455F444F4D41494E3A20656E672E61DF -:101640006374656F6E2E636F6D00000046575F43D5 -:101650004F4D50494C45523A20676363207665727E -:1016600073696F6E20322E372E32000000000000AA -:101670000000000000000000000000002448656138 -:101680006465723A202F70726F6A656374732F728B -:1016900063732F73772F67652F2E2F6E69632F6605 -:1016A000772F636F6D6D6F6E2F6D656D2E632C766A -:1016B00020312E312E322E3220313939382F30342C -:1016C0002F32372032323A31333A3434207368754E -:1016D000616E672045787020240000002448656111 -:1016E0006465723A202F70726F6A656374732F722B -:1016F00063732F73772F67652F2E2F6E69632F66A5 -:10170000772F636F6D6D6F6E2F73656E642E632C14 -:101710007620312E312E322E313120313939382F89 -:1017200031322F32322031373A31373A3535207362 -:101730006875616E6720457870202400736E64645C -:10174000654E6F51200000006E6F454E515F54583A -:1017500000000000736E6464744E6F51200000003E -:101760003F6E6F516454784500000000756E6B72D7 -:101770006474797065000000000000000000ACCCCB -:101780000000ACCC0000AD9C0000AAB00000AAB0E4 -:101790000000AD9C0000AD9C0000AD9C0000AD9C25 -:1017A0000000AD9C0000AD9C0000AD9C0000AD9C15 -:1017B0000000AD9C0000AD9C0000AD9C0000AD9C05 -:1017C0000000AD9C0000AD7C000000000000BCA843 -:1017D0000000BCA80000BD700000AE4C0000B05876 -:1017E0000000BD700000BD700000BD700000BD7045 -:1017F0000000BD700000BD700000BD700000BD7035 -:101800000000BD700000BD700000BD700000BD7024 -:101810000000BD700000BD540000B0402448656168 -:101820006465723A202F70726F6A656374732F72E9 -:1018300063732F73772F67652F2E2F6E69632F6663 -:10184000772F636F6D6D6F6E2F726563762E632CCD -:101850007620312E312E322E313920313939382F40 -:1018600030372F32342032313A33303A303520732A -:101870006875616E6720457870202400706B52781F -:101880004552520066726D324C617267650000000D -:1018900072784E6F527842640000000072785144B2 -:1018A0006D61444600000000727851446D6142460B -:1018B000000000003F6E6F51645278450000000048 -:1018C000706B5278455252730000000066726D32A0 -:1018D0004C7267530000000072784E6F42645300F0 -:1018E0003F724264446D6146000000003F724A420C -:1018F00064446D4600000000000000000000F6781F -:101900000000F6780000F6780000F6780000F6781F -:101910000000F6780000F6780000F6780000F6780F -:101920000000F6780000F6780000F6780000F678FF -:101930000000F6780000F6780000F6700000F670FF -:101940000000F670572D444D41456E4600000000E2 -:10195000000000000000FDC00001015C0000FDDC93 -:101960000001015C0001015C0001015C0001015CFF -:101970000001015C0001015C0000F7040001015C52 -:101980000001015C0001015C0001015C0001015CDF -:101990000001015400010154000101542448656113 -:1019A0006465723A202F70726F6A656374732F7268 -:1019B00063732F73772F67652F2E2F6E69632F66E2 -:1019C000772F636F6D6D6F6E2F6D61632E632C7655 -:1019D00020312E312E322E313220313939382F300C -:1019E000342F32372032323A31333A34322073686E -:1019F00075616E6720457870202400006D61637406 -:101A00007841544E000000004E7453796E264C6BA2 -:101A10000000000072656D61737372740000000055 -:101A20006C696E6B444F574E00000000656E714D3F -:101A30004576504661696C00656E714D457646612C -:101A4000696C00006661696C456E454D00000000E0 -:101A50006C696E6B55500000000000002448656101 -:101A60006465723A202F70726F6A656374732F72A7 -:101A700063732F73772F67652F2E2F6E69632F6621 -:101A8000772F636F6D6D6F6E2F636B73756D2E6344 -:101A90002C7620312E312E322E3220313939382F0A -:101AA00030342F32372032323A31333A33392073DF -:101AB0006875616E672045787020240050726F62EF -:101AC00065506879000000006C6E6B4153535254AE -:101AD0000000000000011B2C00011BC400011BF8CA -:101AE00000011C2C00011C5800011C6C00011CA8EA -:101AF0000001207C00011DE400011E2400011E5095 -:101B000000011E9000011EC000011EFC00011F30DC -:101B10000001207C000122C0000122D80001230026 -:101B2000000123200001234800012478000124A0A3 -:101B3000000124F40001251C000000000001278C96 -:101B40000001285C0001293400012A0400012A60F8 -:101B500000012B3C00012B6400012C4000012C688B -:101B600000012E1000012E3800012FE0000131D8B5 -:101B70000001346C000133800001346C00013498A2 -:101B800000013008000131B00000000000013B847A -:101B900000013BC800013C6000013CAC00013D1C61 -:101BA00000013DB400013DE800013E7000013F0826 -:101BB00000013FD8000140180001409C000140C0D6 -:101BC000000141F4646F42617365506700000000DA -:101BD00000000000000000000000000073746D6150 -:101BE000634C4E4B000000000000000000014C3828 -:101BF00000014C3800014B8000014BC400014C38FF -:101C000000014C380000000000000000000000004F -:101C100000000000000000000000000000000000C4 -:101C2000000000000000000000000000416C74652E -:101C30006F6E204163654E4943205600416C7465C8 -:101C40006F6E204163654E49432056004242424236 -:101C50000000000000000000000000000013541805 -:101C60000013E7FC0000000000000000000000007E -:101C70000000000000000000000000000060CF0035 -:101C800000000060CF000000000000000000000025 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000030000000001 -:101CE00000000001000000000000000000000000F3 -:101CF00000000001000000000000000100000000E2 -:101D000000000000000000000000000000000001D2 -:101D100000000001000000000000000000000000C2 -:101D20000000000000000000010000002100000091 -:101D30001200014000000000000000002000000030 -:101D4000120000A0000000001200006012000180DC -:101D5000120001E000000000000000000000000090 -:101D60000000000100000000000000000000000072 -:101D70000000000000000000000000000000000261 -:101D8000000000000000000000030001000000014E -:0C1D900000030201000000000000000041 -:00000001FF -/* tg1 firmware v12.4.11 */ diff --git a/firmware/acenic/tg2.bin.ihex b/firmware/acenic/tg2.bin.ihex deleted file mode 100644 index a9ff4f431f22e1164d8e6b9785ab85b98df5f466..0000000000000000000000000000000000000000 --- a/firmware/acenic/tg2.bin.ihex +++ /dev/null @@ -1,4844 +0,0 @@ -:100000000C040B0000004000000040000000000055 -:1000100010000003000000000000000D0000000DB3 -:100020003C1D00018FBD6D2003A0F0213C1000009D -:10003000261040000C0010C0000000000000000D61 -:100040003C1D00018FBD6D2403A0F0213C10000079 -:10005000261040000C0017E0000000000000000D1A -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000002000008E5 -:10011000000000000800172F3C0A00010800172FFC -:100120003C0A00020800172F0000000008002CAC59 -:100130000000000008002C4F000000000800172FEE -:100140003C0A00040800328A0000000008001A522D -:10015000000000000800394D00000000080038F4DD -:10016000000000000800172F3C0A0006080039BBF9 -:100170003C0A00070800172F3C0A00080800172F48 -:100180003C0A000908003A130000000008002EA6EF -:10019000000000000800172F3C0A000B0800172F72 -:1001A0003C0A000C0800172F3C0A000D080028FB31 -:1001B0000000000008002890000000000800172F31 -:1001C0003C0A000E0800208C0000000008001964A2 -:1001D0000000000008001A040000000008003CA60F -:1001E0000000000008003C94000000000800172FE9 -:1001F000000000000800191A000000000800172F76 -:10020000000000000800172F3C0A00130800172FF9 -:100210003C0A001400000000000000000000000084 -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000027BDFFE02A -:100310003C1CC000AFBF001CAFB000188F82014072 -:1003200024030003AF8300EC344200040C002B20B4 -:10033000AF8201403C0100C00C001763AC203FFCC1 -:10034000004018213C0200103C010001AC236E9CCF -:10035000106200110043102B144000023C020020E8 -:100360003C0200081062000C240501003C0600015C -:100370008CC66E9C3C04000124845C74000038210F -:10038000AFA000100C002B3BAFA000143C020020DB -:100390003C010001AC226E9C240200083C010001DB -:1003A000AC226EB42402001F3C010001AC226EC4DA -:1003B000240200163C010001AC226E983C05FFFEB1 -:1003C00034A56F083C0200018C426E9C3C03000285 -:1003D000246390103C0400018C846CC400431023FF -:1003E00014800002004580212610FA382402F00013 -:1003F000020280240C00178502002021020228231B -:100400003C0400200082182300651823247BB000E0 -:100410003C03FFFE3463BF080363B8213C0600BF02 -:1004200034C6F0003C0700018CE76CC03C0300BF01 -:100430003463E000008520233C010001AC246EA859 -:10044000008220233C010001AC256E90000528426B -:100450003C010001AC226E8427620FFC3C010001CC -:10046000AC226D2027621FFC00DB3023007B1823A9 -:100470003C010001AC246E883C010001AC256EAC4F -:100480003C010001AC226D24AF86015010E0001148 -:10049000AF8302503C1D00018FBD6CCC03A0F02146 -:1004A0000C001749000000003C0200018C426CD097 -:1004B0003C0300018C636CD42442FE0024630200E0 -:1004C0003C010001AC226CD03C0100011000000492 -:1004D000AC236CD43C1D00018FBD6D2003A0F02126 -:1004E0003C0200018C426CC41040000D26FAFA3820 -:1004F0003C0200018C426CD03C0300018C636CD444 -:100500003C1A00018F5A6CD42442FA38246305C87F -:100510003C010001AC226CD03C010001AC236CD446 -:100520003C0200018C426CC8144000030000000033 -:100530003C010001AC206CD00C0011510000000007 -:100540008FBF001C8FB0001803E0000827BD0020FB -:100550003C0200018C426CD03C0300018C636CD4E3 -:1005600027BDFF98AFB000483C1000018E1066B860 -:10057000AFB200503C12000026524100AFBF0060F5 -:10058000AFBE005CAFB50058AFB30054AFB1004C84 -:10059000AFA20034AFA30030AFA00010AFA0001492 -:1005A0008F8600403C04000124845C802405020006 -:1005B0003C010001AC326E800C002B3B0200382164 -:1005C0008F8300403C02F000006218243C0260006F -:1005D0001062000BA3A0003F240E00013C040001A8 -:1005E00024845C88A3AE003FAFA00010AFA000142D -:1005F0008F860040240503000C002B3B02003821AD -:100600008F8202403C03000100431025AF8202406C -:10061000AF8000488F8200481440000500000000B1 -:10062000AF8000488F8200481040000400000000A6 -:10063000AF8000481000000302E02021AF80004C92 -:1006400002E020213C0500010C002BA834A540F855 -:10065000034020210C002BA8240505C83C02000102 -:100660008C426EA83C0D00018DAD6E883C030001EC -:100670008C636E843C0800018D086E903C0900017B -:100680008D296EAC3C0A00018D4A6EB43C0B000112 -:100690008D6B6EC43C0C00018D8C6E983C04000187 -:1006A00024845C9424050400AF42013C8F42013C49 -:1006B0002406000124070001AF400000AF4D0138BF -:1006C000AF430144AF480148AF49014CAF4A015024 -:1006D000AF4B0154AF4C01582442FF80AF42014060 -:1006E00024020001AFA200100C002B3BAFA00014AD -:1006F0008F420138AFA200108F42013CAFA200141C -:100700008F4601448F4701483C04000124845CA0CB -:100710000C002B3B24050500AFB70010AFBA001446 -:100720008F46014C8F4701503C04000124845CAC8F -:100730000C002B3B240506003C0200018C426E9C01 -:10074000036038213C06000224C690102448FFFFB5 -:100750000106182400E810240043102B1040000666 -:10076000240509003C04000124845CB8AFA80010F3 -:100770000C002B3BAFA000148F82000CAFA2001026 -:100780008F82003CAFA200148F8600008F87000488 -:100790003C04000124845CC40C002B3B24051000A5 -:1007A0008C0202208C0302248C0602188C07021C87 -:1007B0003C04000124845CCC24051100AFA200108D -:1007C0000C002B3BAFA30014AF800054AF80011C82 -:1007D0008C020218304200021040000900000000A4 -:1007E0008C0202203C030002346300040043102505 -:1007F000AF42000C8C02021C1000000834420004BE -:100800008C0202203C0300023463000600431025E2 -:10081000AF42000C8C02021C34420006AF420014AE -:100820008C020218304200101040000A0000000044 -:100830008C02021C34420004AF4200108C020220E1 -:100840003C03000A34630004004310251000000933 -:10085000AF4200088C0202203C03000A3463000609 -:1008600000431025AF4200088C02021C34420006EF -:10087000AF42001024020001AF8200A0AF8200B09E -:100880008F8300548F820054AF8000D0AF8000C0AF -:1008900010000002246300648F8200540062102361 -:1008A0002C4200651440FFFC000000008C0402088C -:1008B0008C05020C26E20028AEE2002024020490FF -:1008C000AEE20010AEE40008AEE5000C26E400083D -:1008D0008C8200008C830004AF820090AF83009470 -:1008E0008C820018AF8200B49482000AAF82009C10 -:1008F0008F420014AF8200B08F8200B030420004FB -:100900001440FFFD000000008F8200B03C03EF00A8 -:100910000043102410400021000000008F8200B42A -:10092000AFA200108F8200908F8300943C040001DE -:1009300024845CD4AFA300148F8600B08F87009C02 -:100940003C0500010C002B3B34A5200D3C040001AC -:1009500024845CE0240203C0AFA20010AFA0001406 -:100960008F8601443C07000124E75CE80C002B3B28 -:100970003405DEAD8F82011C34420002AF82011CBF -:100980008F82022034420004AF8202208F82014015 -:100990003C03000100431025AF82014096E204723F -:1009A00096E6045296E70462AFA2001096E2048233 -:1009B0003C04000124845D14240512000C002B3B30 -:1009C000AFA2001496F0045232020001104000025F -:1009D0000000B02124160001320200025440000140 -:1009E00036D60002320200085440000136D6000418 -:1009F000320200105440000136D6000832020020B6 -:100A00005440000136D6001032020040544000012C -:100A100036D60020320200805440000136D6004015 -:100A200096E6048230C202005440000136D64000EF -:100A300096E304723062020010400003306201004D -:100A40001000000336D620005440000136D61000B6 -:100A500096F0046232C24000144000043207009B4A -:100A600030C2009B14E20007240E000132C22000B5 -:100A70001440000D320200013062009B10E20009B8 -:100A8000240E00013C04000124845D202405130091 -:100A900002003821A3AE003FAFA300100C002B3B97 -:100AA000AFA00014320200015440000136D600808D -:100AB000320200025440000136D601003202000822 -:100AC0005440000136D602003202001054400001AA -:100AD00036D60400320200805440000136D60800A9 -:100AE0008C02021830420200104000023C02000852 -:100AF00002C2B0258C0202183042080010400002E9 -:100B00003C02008002C2B0258C0202183042040070 -:100B1000104000023C02010002C2B0258C02021803 -:100B200030420100104000023C02020002C2B02527 -:100B30008C02021830420080104000023C02040087 -:100B400002C2B0258C020218304220001040000280 -:100B50003C02001002C2B0258C0202183042400054 -:100B6000104000023C02002002C2B0258C02021894 -:100B700030421000104000023C02004002C2B0258A -:100B80008EE204988EE3049CAF420160AF4301649F -:100B90008EE204A08EE304A4AF420168AF43016C6F -:100BA0008EE204A88EE304ACAF420170AF4301743F -:100BB0008EE204288EE3042CAF420178AF43017C1F -:100BC0008EE204488EE3044CAF420180AF430184BF -:100BD0008EE204588EE3045CAF420188AF43018C7F -:100BE0008EE204688EE3046CAF420190AF4301943F -:100BF0008EE204788EE3047CAF420198AF43019CFF -:100C00008EE204888EE3048CAF4201A0AF4301A4BE -:100C10008EE204B08EE304B424040080AF4201A845 -:100C2000AF4301AC0C002BA8240500808C02025CB1 -:100C300027440224AF4201F08C0202602405020026 -:100C4000240600080C002BBFAF4201F83C043B9A7D -:100C50003484CA0000003821240200062403000264 -:100C6000AF4201F4240203E8AF430204AF430200A1 -:100C7000AF4401FCAF42029424020001AF43029052 -:100C8000AF42029C3C0300010067182190636CD8BE -:100C90000347102124E70001A043022C2CE2000F9F -:100CA0001440FFF80347182124E700013C08000125 -:100CB000350840F88F8200403C04000124845D2CFC -:100CC000240514000002170224420030A062022C06 -:100CD00003471021A040022C8C07021802C03021CB -:100CE000240205C8AFA200100C002B3BAFA80014D3 -:100CF0003C04000124845D383C05000024A55C8090 -:100D00002406001027B100300220382127B3003418 -:100D10000C0017A3AFB300103C0300018C636CC838 -:100D20001060000A004080218FA300302405FF00DE -:100D30008FA20034246400FF008520240083182340 -:100D400000431023AFA20034AFA400303C040001E4 -:100D500024845D443C05000024A5410024060108CC -:100D6000022038210C0017A3AFB3001000409021DF -:100D700032C200033C010001AC326E8010400045DD -:100D8000022038218F8200503C03001000431024C1 -:100D900010400016000000008C0202183042004093 -:100DA0001040000F240200018F8200508C030218B3 -:100DB000240E00013C04000124845D50A3AE003FDA -:100DC000AFA20010AFA300148F87004024051500C8 -:100DD0000C002B3B02C0302110000004000000007A -:100DE0003C01000100370821A02240F43C0400012E -:100DF00024845D5C3C05000124A55B403C060001A9 -:100E000024C65BAC00C530238F42001027B30030EE -:100E10000260382127B1003434420A00AF4200108A -:100E20000C0017A3AFB100103C04000124845D70D6 -:100E30003C05000124A5B7143C06000124C6BA9065 -:100E400000C5302302603821AF4201080C0017A30F -:100E5000AFB100103C04000124845D8C3C0500010E -:100E600024A5BE583C06000124C6C90000C5302395 -:100E7000026038213C010001AC226EF40C0017A383 -:100E8000AFB100103C04000124845DA410000024D4 -:100E9000240516003C04000124845DAC3C050001DF -:100EA00024A5A10C3C06000124C6A23800C53023AD -:100EB0000C0017A3AFB300103C04000124845DBCF8 -:100EC0003C05000124A5B2B03C06000124C6B70CC5 -:100ED00000C5302302203821AF4201080C0017A3BF -:100EE000AFB300103C04000124845DD03C05000138 -:100EF00024A5BA983C06000124C6BE5000C5302384 -:100F0000022038213C010001AC226EF40C0017A332 -:100F1000AFB300103C04000124845DE424051650A6 -:100F200002C03021000038213C010001AC226EF8E3 -:100F3000AFA000100C002B3BAFA0001432C2002069 -:100F40001040002127A700303C04000124845DF0FC -:100F50003C05000124A5B13C3C06000124C6B2A812 -:100F600000C5302324022000AF42001C27A2003419 -:100F70000C0017A3AFA20010000219000003198291 -:100F80003C04080000641825AE4300282403001028 -:100F9000AF43003C96E30450AF4300408F43004012 -:100FA0003C04000124845E04AFA00014AFA3001031 -:100FB0008F47001C240516603C010001AC226EF036 -:100FC0001000002532C600208EE204488EE3044C57 -:100FD000AF43001C8F42001C2442E0002C42200141 -:100FE0001440000A240E00013C04000124845E1019 -:100FF000A3AE003FAFA00010AFA000148F46001CAE -:10100000240517000C002B3B000038213C02000097 -:1010100024425CBC00021100000211823C03080063 -:1010200000431025AE42002824020008AF42003CD5 -:1010300096E20450AF4200408F4200403C04000161 -:1010400024845E1CAFA00014AFA200108F47001CC8 -:101050002405180032C600200C002B3B00000000C5 -:101060003C050FFF3C0300018C636EF434A5FFFFC9 -:10107000024030213C0200018C426EF83C04080022 -:101080000065182400031882006418250045102408 -:101090000002108200441025ACC2008032C20180E0 -:1010A00010400056ACC300208F82005C3C030080DF -:1010B000004310241040000D000000008F820050FB -:1010C000AFA200108F82005C240E00013C040001DE -:1010D00024845E28A3AE003FAFA200148F87004097 -:1010E000240519000C002B3B02C030218F820050D8 -:1010F0003C030010004310241040001600000000C4 -:101100008C020218304200401040000F24020001FF -:101110008F8200508C030218240E00013C04000151 -:1011200024845D50A3AE003FAFA20010AFA3001413 -:101130008F870040240520000C002B3B02C030218B -:1011400010000004000000003C01000100370821ED -:10115000A02240F43C04000124845E343C050001DC -:1011600024A55AC03C06000124C65B3800C53023C4 -:101170008F42000827B300300260382127B10034C5 -:1011800034420E00AF4200080C0017A3AFB10010AC -:101190003C04000124845E4C3C05000124A5D8B425 -:1011A0003C06000124C6E3C800C530230260382194 -:1011B000AF42010C0C0017A3AFB100103C040001BA -:1011C00024845E643C05000124A5E9AC3C060001D2 -:1011D00024C6F0F000C53023026038213C01000134 -:1011E000AC226F040C0017A3AFB100103C04000147 -:1011F00024845E7C10000027240521003C040001AB -:1012000024845E843C05000124A59FC83C0600019F -:1012100024C6A10400C5302327B1003002203821A4 -:1012200027B300340C0017A3AFB300103C04000137 -:1012300024845E943C05000124A5CAD43C06000128 -:1012400024C6D8AC00C5302302203821AF42010C9F -:101250000C0017A3AFB300103C04000124845EA46B -:101260003C05000124A5E84C3C06000124C6E9A485 -:1012700000C53023022038213C010001AC226F045C -:101280000C0017A3AFB300103C04000124845EB827 -:101290002405215002C03021000038213C0100010A -:1012A000AC226F10AFA000100C002B3BAFA00014BD -:1012B0003C110FFF3C0300018C636F043631FFFFCC -:1012C000024098213C0200018C426F103C0E080045 -:1012D0000071182400031882006E18250051102494 -:1012E00000021082004E1025AE630038AE62007816 -:1012F0008C02021830420040144000042402000115 -:101300003C01000100370821A02240F43C04000108 -:1013100024845EC43C05000124A5E3D03C06000102 -:1013200024C6E52C00C5302327BE003003C0382179 -:1013300027B500340C0017A3AFB500103C01000125 -:10134000AC226EFC00511024000210823C0E0800FA -:10135000004E1025AE62005032C220001040000640 -:1013600003C038213C02000024425CBC022210244D -:101370001000000F000210823C04000124845ED89B -:101380003C05000124A5E5343C06000124C6E6E442 -:1013900000C530230C0017A3AFB500103C010001BD -:1013A000AC226F1400511024000210823C0E080081 -:1013B000004E1025AE62004832C2400010400005C9 -:1013C00027A700303C02000024425CBC1000000E45 -:1013D000000211003C04000124845EF03C05000181 -:1013E00024A5E6EC3C06000124C6E84400C53023F1 -:1013F00027A200340C0017A3AFA200103C0100018B -:10140000AC226F0800021100000211823C030800A8 -:1014100000431025AE4200603C04000124845F08B4 -:101420003C05000124A582303C06000124C68650FC -:1014300000C5302327B100300220382127B3003403 -:101440000C0017A3AFB300103C0E0FFF35CEFFFF0B -:101450003C04000124845F143C05000024A564685A -:101460003C06000024C6658800C5302302203821D0 -:101470000240F0213C010001AC226EDC004E102441 -:10148000000210823C15080000551025AFAE004444 -:10149000AFC200B80C0017A3AFB300103C040001AA -:1014A00024845F203C05000024A565903C060000D4 -:1014B00024C668088FAE004400C5302302203821BE -:1014C0003C010001AC226ED0004E102400021082BC -:1014D00000551025AFC200E80C0017A3AFB30010F1 -:1014E0003C04000124845F383C05000024A56810FA -:1014F0003C06000024C669408FAE004400C530237E -:10150000022038213C010001AC226EC8004E10249C -:101510000002108200551025AFC200C00C0017A3B6 -:10152000AFB300103C04000124845F503C0500016F -:1015300024A5FAD03C06000124C6FBA88FAE0044C7 -:1015400000C53023022038213C010001AC226ED4BA -:10155000004E10240002108200551025AFC200C8B2 -:101560000C0017A3AFB300103C04000124845F5C9F -:101570003C05000124A5C93C3C06000124C6CA2044 -:1015800000C5302302203821AF4201100C0017A300 -:10159000AFB300103C04000124845F6C3C050001E3 -:1015A00024A5C9103C06000124C6C93400C5302357 -:1015B00002203821AF4201240C0017A3AFB3001062 -:1015C0003C04000124845F7C3C05000124A55A8072 -:1015D0003C06000124C65AAC00C530230220382145 -:1015E000AF420120AF4201140C0017A3AFB30010AB -:1015F0003C04000124845F883C05000124A5F29886 -:101600003C06000124C6F6B400C530230220382170 -:10161000AF4201180C0017A3AFB300108FAE004407 -:101620003C010001AC226F18004E10240002108211 -:10163000005510250C003FC3AFC200D00C003C4049 -:10164000000000000C0027A800000000AC000228E9 -:10165000AC00022C96E204502442FFFFAF42003857 -:1016600096E20460AF42008032C2400014400003A2 -:101670000000000096E20480AF42008496E70490E8 -:1016800050E000012407080024E2FFFFAF42008879 -:10169000AF42007C2402080010E2000F32C240007A -:1016A000104000032402040010E2000B00000000C0 -:1016B000240E00013C04000124845F98A3AE003F87 -:1016C00096E604902405217002C03821AFA00010D6 -:1016D0000C002B3BAFA000148F4301388F4401381E -:1016E00024020001A34205C2AF430094AF44009816 -:1016F000AFA00010AFA000148F4600808F47008479 -:101700003C04000124845FA40C002B3B2405220030 -:101710000C0024A43C1108003C1433D83694CB5858 -:101720003C020800344200803C04000124845FB085 -:101730003C05000024A55D003C06000024C65D1C9D -:1017400000C5302327A70030AF8200602402FFFFCE -:10175000AF82006427A200340C0017A3AFA20010D0 -:101760003C010001AC226EB800021100000211829F -:10177000005110250C0018FCAE4200008F82024080 -:101780003C03000100431025AF8202403C020000F0 -:1017900024424034AF820244AF8002408F82006016 -:1017A00000511024144000053C0308008F820060A3 -:1017B000004310241040FFFD000000000C003C4DD1 -:1017C000000088213C020100AFA200208F530018C6 -:1017D000240200FF56620001267100018C020228DB -:1017E0001622000E001330C08F42033C2442000139 -:1017F000AF42033C8F42033C8C0202283C040001B0 -:1018000024845C243C050009AFA00014AFA20010A2 -:101810008FA600201000003F34A5010000D7102142 -:101820008FA300208FA40024AC4304C0AC4404C4A4 -:1018300000C018218F4401788F45017C00001021E1 -:1018400024070004AFA70010AFB100148F48000CAC -:1018500024C604C002E63021AFA800188F48010C4E -:101860002407000800A3282100A3482B0082202180 -:101870000100F809008920211440000B240700080A -:101880008F820120AFA200108F8201243C0400014E -:1018900024845C2C3C050009AFA200148FA6002014 -:1018A0001000001C34A502008F4401608F450164C4 -:1018B0008F43000CAF5100188F86012024020010C6 -:1018C000AFA20010AFB10014AFA300188F42010CFB -:1018D0000040F80924C6001C14400010000000005D -:1018E0008F42034024420001AF4203408F42034035 -:1018F0008F820120AFA200108F8201243C040001DE -:1019000024845C343C050009AFA200148FA600209B -:1019100034A503000C002B3B026038218F4202E407 -:1019200024420001AF4202E48F4202E493A2003F4E -:10193000104000693C02070034423000AFA200288A -:101940008F530018240200FF126200020000882159 -:10195000267100018C0202281622000E001330C0EE -:101960008F42033C24420001AF42033C8F42033CC0 -:101970008C0202283C04000124845C243C050009FC -:10198000AFA00014AFA200108FA600281000003FE7 -:1019900034A5010000D710218FA300288FA4002CAC -:1019A000AC4304C0AC4404C400C018218F44017887 -:1019B0008F45017C0000102124070004AFA7001010 -:1019C000AFB100148F48000C24C604C002E63021D9 -:1019D000AFA800188F48010C2407000800A3282195 -:1019E00000A3482B008220210100F8090089202152 -:1019F0001440000B240700088F820120AFA20010C2 -:101A00008F8201243C04000124845C2C3C050009E5 -:101A1000AFA200148FA600281000001C34A50200FD -:101A20008F4401608F4501648F43000CAF51001853 -:101A30008F86012024020010AFA20010AFB1001465 -:101A4000AFA300188F42010C0040F80924C6001C07 -:101A500014400010000000008F42034024420001A7 -:101A6000AF4203408F4203408F820120AFA200109B -:101A70008F8201243C04000124845C343C0500096D -:101A8000AFA200148FA6002834A503000C002B3B46 -:101A9000026038218F4202F024420001AF4202F07E -:101AA0008F4202F03C04000124845FC0AFA000100C -:101AB000AFA000148FA60028240523000C002B3BA8 -:101AC0000000382110000004000000008C020264B5 -:101AD00010400005000000008F8200A0304200048A -:101AE0001440FFFA000000008F82004434420004DA -:101AF000AF8200448F42030824420001AF42030832 -:101B00008F4203088F8200D88F8300D400431023B4 -:101B10002442FF80AF4200908F4200902842FF8114 -:101B200010400006240200018F4200908F430144C0 -:101B300000431021AF42009024020001AF42008C0C -:101B400032C2000810400006000000008F8202141C -:101B50003C0381003042FFFF00431025AF82021496 -:101B60003C0300018C636D94306200021040000958 -:101B7000306200013C04000124845FCC3C0500007D -:101B800024A56D503C06000024C671C81000001248 -:101B900000C5302310400009000000003C04000193 -:101BA00024845FDC3C05000024A571D03C060000C5 -:101BB00024C676781000000800C530233C040001DC -:101BC00024845FEC3C05000024A569483C06000025 -:101BD00024C66D4800C5302327A7003027A2003453 -:101BE0000C0017A3AFA200103C010001AC226ECC88 -:101BF0003C0200018C426ECC3C0308000002110044 -:101C00000002118200431025AE4200408F8200A0E6 -:101C1000AFA200108F8200B0AFA200148F86005CCC -:101C20008F87011C3C04000124845FFC3C010001FF -:101C3000AC366EA43C010001AC206E943C01000166 -:101C4000AC3C6E8C3C010001AC3B6EBC3C01000125 -:101C5000AC376EC03C010001AC3A6EA00C002B3BCF -:101C6000240524008F820200AFA200108F82022080 -:101C7000AFA200148F8600448F8700503C040001FF -:101C8000248460080C002B3B240525008F83006012 -:101C90000074100B0242000A0200F821000000004C -:101CA0000000000D8FBF00608FBE005C8FB5005834 -:101CB0008FB300548FB200508FB1004C8FB00048EA -:101CC00003E0000827BD006827BDFFE03C040001D9 -:101CD00024846014240526000000302100003821EF -:101CE000AFBF0018AFA000100C002B3BAFA000143A -:101CF0008FBF001803E0000827BD002003E00008A4 -:101D00000000000003E000080000000000000000E8 -:101D100000000000000000000000000000000000C3 -:101D200003E000080000000003E0000800000000DD -:101D300027BDFDE027A500183C04DEAD3484BEEFCE -:101D4000AFBF02188F8201503C03001F3463FFFFB6 -:101D5000AFA4001800A2282300A328248CA200000E -:101D60001044000A00000000AFA500108CA2000083 -:101D7000AFA200148F8601508F8702503C040001EF -:101D80002484601C0C002B3B240527008FBF021805 -:101D900003E0000827BD022027BDFFE03C06ABBAE8 -:101DA00034C6BABEAFB000183C1000043C07007F38 -:101DB00034E7FFFFAFBF001C001028408E04000076 -:101DC0008CA30000ACA00000AE0600008CA20000B6 -:101DD000ACA3000010460005AE04000000A0802166 -:101DE00000F0102B1040FFF5001028403C040001CB -:101DF00024846028240528000200302100003821B6 -:101E0000AFA000100C002B3BAFA00014020010216B -:101E10008FBF001C8FB0001803E0000827BD002012 -:101E20008C0202243047003F10E000100080302177 -:101E3000000028212403002000E3102410400002A9 -:101E40000006304200A62821000318421460FFFB60 -:101E500000E310242402F00000A228243402FFFF33 -:101E60000045102B144000033C0200011000000844 -:101E70003C0200013442FFFF008518230043102B71 -:101E80001440000300A010213C02FFFE008210213C -:101E900003E000080000000027BDFFD0AFB5002818 -:101EA0008FB50040AFB2002000A09021AFB1001C60 -:101EB00024C60003AFBF002CAFB30024AFB000189E -:101EC0008EA200002403FFFC00C380240050102BCE -:101ED0001440001B00E088218E330000AFB00010DA -:101EE0008EA20000AFA200148E270000240530004F -:101EF0000C002B3B024030218E230000007020217B -:101F00000064102B10400007024028218CA2000022 -:101F1000AC620000246300040064102B1440FFFB3B -:101F200024A500048EA2000000501023AEA20000E1 -:101F30008E220000005010211000000BAE22000085 -:101F40002402002DA0820000AFB000108EA200007D -:101F500002409821AFA200148E2700002405310012 -:101F60000C002B3B02603021026010218FBF002C3F -:101F70008FB500288FB300248FB200208FB1001CD2 -:101F80008FB0001803E0000827BD003027BDFFE830 -:101F90003C1CC0003C05FFFE3C0300018C636E84CA -:101FA0003C0400018C846E9034A5BF0824021FFC01 -:101FB0003C010001AC226CD03C0200C03C0100019D -:101FC000AC226CD43C020020AFBF00103C0100C02A -:101FD000AC201FFC0043102300441023245BB000FE -:101FE0000365B8213C1D00018FBD6CCC03A0F0211E -:101FF0003C0400C0348402003C1A00C03C0300C012 -:10200000346307C824021DFC3C010001AC226CD0E3 -:10201000240218343C010001AC246CD43C010001C2 -:10202000AC226CD03C010001AC236CD40C00180D28 -:10203000375A02008FBF001003E0000827BD0018C8 -:1020400027BDFFC83C04000124846034240532000D -:102050003C0200018C426CD03C0300018C636CD4C8 -:102060000000302103603821AFBF0030AFB3002C37 -:10207000AFB20028AFB10024AFB00020AFA2001C67 -:10208000AFA30018AFB700100C002B3BAFBA001481 -:102090000C001916000000008F8202403442000438 -:1020A000AF82024024020001AF4200003C02000166 -:1020B00000571021904240F4104000922403FFFC8E -:1020C0003C1000012610AC733C1200012652A84CB3 -:1020D00002121023004380248FA3001C3C04000143 -:1020E000248460400070102B1440001A27B300189D -:1020F0008FB100182405300002403021AFB000102D -:10210000AFA300140C002B3B022038218FA3001832 -:10211000007020210064102B104000070240302185 -:102120008CC20000AC620000246300040064102B29 -:102130001440FFFB24C600048FA2001C0050102393 -:10214000AFA2001C8E620000005010211000000A97 -:10215000AE6200000240882124053100AFB00010BB -:10216000AFA300148FA70018022030212402002DF5 -:102170000C002B3BA0820000240700208FA3001C32 -:102180003C0400012484605C241200203C01000116 -:10219000AC316EB02C6200201440001D27B1001835 -:1021A0008FB00018240530003C06000124C66F5093 -:1021B000AFA70010AFA300140C002B3B0200382186 -:1021C0008FA300183C04000124846F502465002074 -:1021D0000065102B10400007000000008C820000FA -:1021E000AC620000246300040065102B1440FFFB68 -:1021F000248400048FA2001C00521023AFA2001CF4 -:102200008E220000005210211000000BAE220000B0 -:102210003C10000126106F5024053100AFA70010BC -:10222000AFA300148FA70018020030212402002D54 -:102230000C002B3BA0820000240700203C0400017E -:10224000248460708FA3001C241200203C01000134 -:10225000AC306EE42C6200201440001D27B1001841 -:102260008FB00018240530003C06000124C66F70B2 -:10227000AFA70010AFA300140C002B3B02003821C5 -:102280008FA300183C04000124846F702465002093 -:102290000065102B10400007000000008C82000039 -:1022A000AC620000246300040065102B1440FFFBA7 -:1022B000248400048FA2001C00521023AFA2001C33 -:1022C0008E220000005210211000000BAE220000F0 -:1022D0003C10000126106F7024053100AFA70010DC -:1022E000AFA300148FA70018020030212402002D94 -:1022F0000C002B3BA08200003C01000110000031CB -:10230000AC306EE03C1000012610821F3C12000130 -:102310002652809C02121023004380248FA3001CAD -:102320003C040001248460840070102B1440001AC7 -:1023300027B300188FB10018240530000240302167 -:10234000AFB00010AFA300140C002B3B02203821CB -:102350008FA30018007020210064102B104000078C -:10236000024030218CC20000AC62000024630004F3 -:102370000064102B1440FFFB24C600048FA2001C35 -:1023800000501023AFA2001C8E62000000501021EC -:102390001000000AAE6200000240882124053100CE -:1023A000AFB00010AFA300148FA700180220302197 -:1023B0002402002D0C002B3BA08200003C010001F8 -:1023C000AC316EB03C0300018C636EB0240204009B -:1023D0000060F809AF8200708FBF00308FB3002C0F -:1023E0008FB200288FB100248FB0002003E00008D6 -:1023F00027BD003800000000000000008F82004070 -:102400003C03F000004310243C036000144300062A -:10241000000000008F8200502403FF80004310243E -:1024200034420055AF8200508F820054244203E8AA -:10243000AF820058240201F4AF4200E024020004FD -:10244000AF4200E824020002AF4001B0AF4000E418 -:10245000AF4200DCAF4000D8AF4000D403E000083A -:10246000AF4000D08F8200542442000503E00008F2 -:10247000AF82007827BDFFE8AFBF00108F82005405 -:10248000244203E8AF8200583C02080002C2102434 -:10249000104000043C02F7FF3442FFFF02C2B024A8 -:1024A000369400403C0200018C426DA81040001799 -:1024B0003C0202003C0300018C636F1C106000169C -:1024C0000282A0253C0200018C426E44144000129E -:1024D0003C0202003C0200018C426D943042000339 -:1024E0001440000D3C0202008F8302243C020002D3 -:1024F0008C428FEC106200083C0202000C003DAFE1 -:1025000000000000100000043C0202000C00419694 -:10251000000000003C02020002C210241040000330 -:10252000000000000C001F4B000000008F4200D88C -:102530008F4300DC24420001AF4200D80043102B3F -:102540001440000300000000AF4000D83694008023 -:102550008C0302381060000C000000008F4201B0B4 -:10256000244203E8AF4201B00043102B14400006A0 -:1025700000000000934205C5144000030000000065 -:102580000C001DA0000000008FBF001003E0000839 -:1025900027BD001803E000080000000027BDFFD899 -:1025A000AFBF00208F43002C8F42003810620059CB -:1025B000000000003C02000100571021904240F052 -:1025C00010400026240700088F4401708F450174D5 -:1025D0008F48000C8F86012024020020AFA200103B -:1025E000AFA30014AFA800188F42010C0040F809F7 -:1025F00024C6001C14400011240200013C0100010B -:1026000000370821A02240F08F820124AFA20010E1 -:102610008F8201283C04000124846128AFA20014A9 -:102620008F46002C8F8701203C0500090C002B3BB6 -:1026300034A509001000005C000000008F42030078 -:1026400024420001AF4203008F4203008F42002C5E -:10265000A34005C110000027AF4200388F4401702D -:102660008F4501748F43002C8F48000C8F8601200A -:1026700024020080AFA20010AFA30014AFA800187E -:102680008F42010C0040F80924C6001C14400011C0 -:10269000240200013C01000100370821A02240F182 -:1026A0008F820124AFA200108F8201283C04000118 -:1026B00024846134AFA200148F46002C8F87012040 -:1026C0003C0500090C002B3B34A51100100000361E -:1026D000000000008F4203008F43002C24420001C1 -:1026E000AF4203008F42030024020001A34205C150 -:1026F000AF4300383C01000100370821A02040F121 -:102700003C01000100370821A02040F01000002605 -:10271000AF400034934205C11040001D000000008E -:10272000A34005C18F8200403042000114400008E0 -:10273000000020218C0301042402000150620005E6 -:10274000240400018C020264104000030080102168 -:102750002404000100801021104000060000000049 -:102760008F42030C24420001AF42030C100000080A -:102770008F42030C8F82004434420004AF82004435 -:102780008F42030824420001AF4203088F4203082E -:102790003C01000100370821A02040F03C0100016D -:1027A00000370821A02040F18F42000010400007B0 -:1027B00000000000AF80004C8F82004C1040FFFDF5 -:1027C000000000001000000500000000AF8000487D -:1027D0008F8200481040FFFD000000008F820060E3 -:1027E0003C03FF7F3463FFFF00431024AF8200608F -:1027F0008F420000104000030000000010000002A3 -:10280000AF80004CAF8000488FBF002003E000087D -:1028100027BD002803E000080000000027BDFFD806 -:10282000AFBF00208F4300448F42007C106200291C -:10283000240700088F4401688F45016C8F48000C05 -:102840008F86012024020040AFA20010AFA3001425 -:10285000AFA800188F42010C0040F80924C6001CE4 -:1028600014400011240200013C010001003708213E -:10287000A02240F28F820124AFA200108F82012893 -:102880003C0400012484613CAFA200148F46004444 -:102890008F8701203C0500090C002B3B34A5130059 -:1028A0001000000F000000008F42030424420001CA -:1028B000AF4203048F4203048F420044AF42007CC6 -:1028C0003C01000100370821A02040F21000000464 -:1028D000AF4000783C01000100370821A02040F201 -:1028E0008F4200001040000700000000AF80004C45 -:1028F0008F82004C1040FFFD00000000100000051A -:1029000000000000AF8000488F8200481040FFFDAB -:10291000000000008F8200603C03FEFF3463FFFF75 -:1029200000431024AF8200608F420000104000037B -:102930000000000010000002AF80004CAF80004893 -:102940008FBF002003E0000827BD002803E0000837 -:10295000000000003C0200018C426DA827BDFFA8CA -:10296000AFBF0050AFBE004CAFB50048AFB300449E -:10297000AFB20040AFB1003CAFB00038104000D55E -:102980008F9000448F4200D0244300012842000B66 -:10299000144000E4AF4300D08F42000430420002F4 -:1029A0001440009CAF4000D08F4200043C03000163 -:1029B0008C636D9834420002AF420004240200018F -:1029C000146200033C020600100000023442300092 -:1029D00034421000AFA200208F4A0018AFAA003482 -:1029E00027AA0020AFAA002C8FAA0034240200FFDF -:1029F0001142000200001821254300018C02022828 -:102A0000006098211662000E3C0500098F42033CCD -:102A100024420001AF42033C8F42033C8C02022857 -:102A20008FA700343C0400012484610CAFA0001483 -:102A3000AFA200108FA600201000007034A5050082 -:102A40008FAA0034000A38C000F710218FA300209D -:102A50008FA40024AC4304C0AC4404C48F8300544E -:102A60008F820054247103E8022210232C4203E9D0 -:102A70001040001B0000A82100E09021265E04C049 -:102A80008F4401788F45017C02401821240A0004FC -:102A9000AFAA0010AFB300148F48000C0000102143 -:102AA00002FE3021AFA800188F48010C240700084F -:102AB00000A3282100A3482B008220210100F8094F -:102AC0000089202154400006241500018F82005403 -:102AD000022210232C4203E91440FFE90000000009 -:102AE00032A200FF54400018AF5300188F42037801 -:102AF00024420001AF4203788F4203788F82012085 -:102B00008FAA002C8FA70034AFA200108F8201245F -:102B10003C04000124846118AFA200148D4600001B -:102B20003C0500091000003534A506008F4203085B -:102B30002415000124420001AF4203088F4203081C -:102B40001000001E32A200FF8F8300548F820054B9 -:102B5000247103E8022210232C4203E910400016DE -:102B60000000A8213C1E0020241200108F42000CFF -:102B70008F4401608F4501648F860120AFB2001041 -:102B8000AFB30014005E1025AFA200188F42010CF5 -:102B9000240700080040F80924C6001C1440FFE385 -:102BA000000000008F820054022210232C4203E90F -:102BB0001440FFEE0000000032A200FF144000119C -:102BC0003C0500098F42037824420001AF4203789C -:102BD0008F4203788F8201208FAA002C8FA70034A8 -:102BE000AFA200108F8201243C04000124846120E4 -:102BF000AFA200148D46000034A507000C002B3B4B -:102C0000000000008F4202EC24420001AF4202ECBF -:102C10008F4202EC8F4200043042000150400029F4 -:102C2000361000403C02040002C210241040001381 -:102C30002404FFDF8F4202508F4302548F4401B4BB -:102C400014640006361000408F4202708F430274F5 -:102C50008F4401B8106400072402FFDF8F42025046 -:102C60008F4302548F4402708F450274100000128B -:102C70003A1000201000002B020280248F420250E4 -:102C80008F4302548F4501B414650006020480246A -:102C90008F4202708F4302748F4401B85064002148 -:102CA000361000408F4202508F4302548F4402700E -:102CB0008F4502743A100040AF4301B41000001970 -:102CC000AF4501B88F4200D4244300011000001129 -:102CD000284200338F4200043042000110400009B6 -:102CE0003C02040002C21024104000042402FFDF52 -:102CF000020280241000000B361000401000000972 -:102D0000361000608F4200D436100040244300018A -:102D1000284201F514400003AF4300D4AF4000D473 -:102D20003A100020AF9000442402FF7F0282A024CA -:102D30008FBF00508FBE004C8FB500488FB300444A -:102D40008FB200408FB1003C8FB0003803E0000824 -:102D500027BD005803E00008000000003C0200010D -:102D60008C426DA827BDFFB0AFBF0048AFBE004486 -:102D7000AFB50040AFB3003CAFB20038AFB10034E4 -:102D8000104000C7AFB000308F4200D02443000194 -:102D90002842000B144000DAAF4300D08F420004F9 -:102DA0003042000214400097AF4000D08F42000430 -:102DB0003C0300018C636D9834420002AF42000472 -:102DC00024020001146200033C020600100000020D -:102DD0003442300034421000AFA20020000018211D -:102DE0008F5E001827AA0020240200FF13C20002F1 -:102DF000AFAA002C27C300018C020228006090219A -:102E00001642000E001E38C08F42033C24420001CF -:102E1000AF42033C8F42033C8C0202283C04000179 -:102E20002484610C3C050009AFA00014AFA200107F -:102E30008FA600201000006D34A5050000F71021BA -:102E40008FA300208FA40024AC4304C0AC4404C46E -:102E50008F8300548F820054247003E802021023F1 -:102E60002C4203E91040001B0000982100E088215B -:102E7000263504C08F4401788F45017C022018213B -:102E8000240A0004AFAA0010AFB200148F48000C4F -:102E90000000102102F53021AFA800188F48010C66 -:102EA0002407000800A3282100A3482B008220212A -:102EB0000100F80900892021544000062413000174 -:102EC0008F820054020210232C4203E91440FFE9D0 -:102ED00000000000326200FF54400017AF5200189B -:102EE0008F42037824420001AF4203788F42037877 -:102EF0008F8201208FAA002CAFA200108F820124A4 -:102F00003C040001248461183C050009AFA20014B0 -:102F10008D4600001000003534A506008F420308DE -:102F20002413000124420001AF4203088F4203082A -:102F30001000001E326200FF8F8300548F82005405 -:102F4000247003E8020210232C4203E9104000160B -:102F5000000098213C150020241100108F42000C25 -:102F60008F4401608F4501648F860120AFB100104E -:102F7000AFB2001400551025AFA200188F42010C0B -:102F8000240700080040F80924C6001C1440FFE391 -:102F9000000000008F820054020210232C4203E93B -:102FA0001440FFEE00000000326200FF14400011E8 -:102FB000000000008F42037824420001AF420378F2 -:102FC0008F4203788F8201208FAA002CAFA20010BD -:102FD0008F8201243C040001248461203C05000907 -:102FE000AFA200148D46000034A507000C002B3B57 -:102FF00003C038218F4202EC24420001AF4202ECB0 -:103000008F4202EC8F420004304200011040001851 -:10301000240400018F4202508F4302548F4501B4B3 -:103020003C01000114650006A0246CF18F4202707F -:103030008F4302748F4401B8106400210000000027 -:103040008F4202508F4302543C04000190846CF084 -:103050008F4602708F47027438840001AF4301B479 -:10306000AF4701B83C01000110000025A0246CF01E -:103070008F4200D43C010001A0206CF024430001E9 -:10308000284200331440001EAF4300D43C0200012C -:1030900090426CF1AF4000D410000017384200019C -:1030A0008F42000430420001104000080000000080 -:1030B0000C00565A000020213C010001A0206CF1B8 -:1030C0003C0100011000000EA0206CF08F4200D4E3 -:1030D0003C010001A0206CF024430001284201F5CE -:1030E00014400007AF4300D43C02000190426CF151 -:1030F000AF4000D4004210263C010001A0226CF138 -:103100003C0300018C636D98240200021462000CE1 -:103110003C0300023C03000190636CF124020001B7 -:103120005462001F000020213C02000190426CF01C -:103130001443001B24040005100000192404000699 -:103140003C0200028C428FF4004310241040000B1C -:10315000240200013C03000190636CF154620010F2 -:10316000000020213C02000190426CF01443000C4E -:10317000240400031000000A240400043C0300019E -:1031800090636CF114620006000020213C020001F3 -:1031900090426CF024040001504400012404000219 -:1031A0000C00565A000000002402FF7F0282A02477 -:1031B0008FBF00488FBE00448FB500408FB3003CE6 -:1031C0008FB200388FB100348FB0003003E00008B8 -:1031D00027BD005003E00008000000003C02000191 -:1031E0008C426DA827BDFFB0AFBF0048AFBE004402 -:1031F000AFB50040AFB3003CAFB20038AFB1003460 -:10320000104000DEAFB000308F4200D03C0400011F -:103210008C846D98244300012842000BAF4400E8E1 -:10322000144000FEAF4300D08F4200043042000241 -:1032300014400095AF4000D08F4200043442000299 -:10324000AF42000424020001148200033C02060085 -:10325000100000023442300034421000AFA20020BF -:10326000000018218F5E001827AA0020240200FF0A -:1032700013C20002AFAA002C27C300018C0202284F -:10328000006090211642000E001E38C08F42033CA1 -:1032900024420001AF42033C8F42033C8C020228CF -:1032A0003C0400012484610C3C050009AFA000141B -:1032B000AFA200108FA600201000006D34A50500FD -:1032C00000F710218FA300208FA40024AC4304C07A -:1032D000AC4404C48F8300548F820054247003E8EC -:1032E000020210232C4203E91040001B0000982129 -:1032F00000E08821263504C08F4401788F45017C89 -:1033000002201821240A0004AFAA0010AFB2001452 -:103310008F48000C0000102102F53021AFA80018E2 -:103320008F48010C2407000800A3282100A3482B84 -:10333000008220210100F809008920215440000664 -:10334000241300018F820054020210232C4203E94F -:103350001440FFE900000000326200FF54400017F3 -:10336000AF5200188F42037824420001AF42037825 -:103370008F4203788F8201208FAA002CAFA2001009 -:103380008F8201243C040001248461183C0500095B -:10339000AFA200148D4600001000003534A50600D1 -:1033A0008F4203082413000124420001AF420308A6 -:1033B0008F4203081000001E326200FF8F8300540A -:1033C0008F820054247003E8020210232C4203E988 -:1033D00010400016000098213C1500202411001018 -:1033E0008F42000C8F4401608F4501648F8601205D -:1033F000AFB10010AFB2001400551025AFA20018F5 -:103400008F42010C240700080040F80924C6001C64 -:103410001440FFE3000000008F82005402021023DA -:103420002C4203E91440FFEE00000000326200FF6E -:1034300014400011000000008F4203782442000174 -:10344000AF4203788F4203788F8201208FAA002C2D -:10345000AFA200108F8201243C040001248461206B -:103460003C050009AFA200148D46000034A50700FA -:103470000C002B3B03C038218F4202EC2442000198 -:10348000AF4202EC8F4202EC8F4200043042000156 -:10349000104000333C02040002C210241040001708 -:1034A00000000000934205C08F4402508F45025433 -:1034B0008F4301B43442002014A30006A34205C088 -:1034C0008F4202708F4302748F4401B81064000869 -:1034D000000000008F4202508F430254934405C005 -:1034E0008F4602708F470274100000163884004027 -:1034F000934205C010000048304200BF934205C00F -:103500008F4402508F4502548F4301B4304200BFB4 -:1035100014A30006A34205C08F4202708F430274B9 -:103520008F4401B81064000B000000008F4202506D -:103530008F430254934405C08F4602708F47027434 -:1035400038840020AF4301B4AF4701B81000003306 -:10355000A34405C0934205C01000002F3442002050 -:10356000934205C08F4300D434420020A34205C0DB -:103570002462000110000023286300338F4200E41E -:103580008F4300E024420001AF4200E40043102AD0 -:1035900014400006240300018F4200E81443000297 -:1035A000AF4000E424030004AF4300E88F4200046E -:1035B000304200011040000D3C02040002C2102401 -:1035C0001040000700000000934205C03442004054 -:1035D000A34205C0934205C01000000F304200DF37 -:1035E000934205C01000000C34420060934205C0B5 -:1035F0008F4300D434420020A34205C0246200015E -:10360000286300FB14600005AF4200D4934205C05C -:10361000AF4000D438420040A34205C0934205C0E9 -:103620008F4300E83042007FA34205C0240200011E -:103630001462000500000000934405C0000421024C -:1036400010000003348400F0934405C03484000F5C -:103650000C005640000000002402FF7F0282A024DC -:103660008FBF00488FBE00448FB500408FB3003C31 -:103670008FB200388FB100348FB0003003E0000803 -:1036800027BD005003E000080000000027BDFFB088 -:10369000274401C026E30028246504000065102BA0 -:1036A000AFBF0048AFBE0044AFB50040AFB3003C71 -:1036B000AFB20038AFB1003410400007AFB00030F7 -:1036C0008C820000AC620000246300040065102BB3 -:1036D0001440FFFB248400048C020080AEE200440E -:1036E0008C0200C0AEE200408C020084AEE20030EA -:1036F0008C020084AEE2023C8C020088AEE2024002 -:103700008C02008CAEE202448C020090AEE20248D1 -:103710008C020094AEE2024C8C020098AEE20250A1 -:103720008C02009CAEE202548C0200A0AEE2025871 -:103730008C0200A4AEE2025C8C0200A8AEE2026041 -:103740008C0200ACAEE202648C0200B0AEE2026811 -:103750008C0200B4AEE2026C8C0200B8AEE20270E1 -:103760008C0200BC24040001AEE20274AEE000341E -:1037700000041080005710218EE300348C42023C7C -:1037800024840001006218212C82000FAEE3003473 -:103790001440FFF8000410808C0200CCAEE2004818 -:1037A0008C0200D0AEE2004C8C0200E0AEE201F8E8 -:1037B0008C0200E4AEE201FC8C0200E8AEE2020002 -:1037C0008C0200ECAEE202048C0200F0AEE20208D1 -:1037D0008EE400C08EE500C48C0200FC0045102B76 -:1037E0001040000B000000008EE200C08EE300C419 -:1037F0002404000124050000006518210065302B19 -:103800000044102100461021AEE200C0AEE300C427 -:103810008C0200FC8EE400C08EE500C42408FFFF8B -:1038200024090000004018210000102100882024F5 -:1038300000A928240082202500A32825AEE400C08A -:10384000AEE500C48EE400D08EE500D48C0200F416 -:103850000045102B1040000B000000008EE200D04D -:103860008EE300D424040001240500000065182123 -:103870000065302B0044102100461021AEE200D03C -:10388000AEE300D48C0200F48EE400D08EE500D4C8 -:1038900000401821000010210088202400A92824BD -:1038A0000082202500A32825AEE400D0AEE500D498 -:1038B0008EE400C88EE500CC8C0200F80045102B89 -:1038C0001040000B000000008EE200C88EE300CC28 -:1038D0002404000124050000006518210065302B38 -:1038E0000044102100461021AEE200C8AEE300CC37 -:1038F0008C0200F88EE400C88EE500CC0040182150 -:10390000000010210088202400A9282400822025FE -:1039100000A3282524020008AEE400C8AEE500CCD0 -:10392000AFA20010AFA000148F42000C8C0402085C -:103930008C05020CAFA200188F42010C26E600286D -:103940000040F80924070400104000F03C02040085 -:10395000AFA20020934205C6104000890000182144 -:103960008F5E001827AA0020240200FF13C2000265 -:10397000AFAA002C27C300018C020228006090210E -:103980001642000E001E38C08F42033C2442000144 -:10399000AF42033C8F42033C8C0202283C040001EE -:1039A0002484610C3C050009AFA00014AFA20010F4 -:1039B0008FA600201000006B34A5050000F7102131 -:1039C0008FA300208FA40024AC4304C0AC4404C4E3 -:1039D0008F8300548F820054247003E80202102366 -:1039E0002C4203E91040001B0000982100E08821D0 -:1039F000263504C08F4401788F45017C02201821B0 -:103A0000240A0004AFAA0010AFB200148F48000CC3 -:103A10000000102102F53021AFA800188F48010CDA -:103A20002407000800A3282100A3482B008220219E -:103A30000100F809008920215440000624130001E8 -:103A40008F820054020210232C4203E91440FFE944 -:103A500000000000326200FF54400017AF5200180F -:103A60008F42037824420001AF4203788F420378EB -:103A70008F8201208FAA002CAFA200108F82012418 -:103A80003C040001248461183C050009AFA2001425 -:103A90008D4600001000003334A506008F42030855 -:103AA0002413000124420001AF4203088F4203089F -:103AB0001000001C326200FF8F8300548F8200547C -:103AC000247003E8020210232C4203E91040001482 -:103AD00000009821241100108F42000C8F440160D7 -:103AE0008F4501648F860120AFB10010AFB2001482 -:103AF000AFA200188F42010C240700080040F8090B -:103B000024C6001C1440FFE5000000008F82005412 -:103B1000020210232C4203E91440FFEF00000000D2 -:103B2000326200FF54400012240200018F420378E9 -:103B300024420001AF4203788F4203788F82012034 -:103B40008FAA002CAFA200108F8201243C04000138 -:103B5000248461203C050009AFA200148D460000BA -:103B600034A507000C002B3B03C0382100001021B6 -:103B70001440005B240200011000006500000000FA -:103B80008F510018240200FF122200020000802141 -:103B9000263000018C0202281602000E001130C0EF -:103BA0008F42033C24420001AF42033C8F42033C5E -:103BB0008C0202283C040001248460F43C050009C6 -:103BC000AFA00014AFA200108FA600201000003F8D -:103BD00034A5010000D710218FA300208FA400245A -:103BE000AC4304C0AC4404C400C018218F44017825 -:103BF0008F45017C0000102124070004AFA70010AE -:103C0000AFB000148F48000C24C604C002E6302177 -:103C1000AFA800188F48010C2407000800A3282132 -:103C200000A3482B008220210100F80900892021EF -:103C30001440000B240700088F820120AFA200105F -:103C40008F8201243C040001248460FC3C050009AF -:103C5000AFA200148FA600201000001C34A50200A3 -:103C60008F4401608F4501648F43000CAF500018F2 -:103C70008F86012024020010AFA20010AFB0001404 -:103C8000AFA300188F42010C0040F80924C6001CA5 -:103C900054400011240200018F42034024420001DD -:103CA000AF4203408F4203408F820120AFA2001039 -:103CB0008F8201243C040001248461043C05000936 -:103CC000AFA200148FA6002034A503000C002B3BEC -:103CD00002203821000010211040000D24020001B4 -:103CE0008F4202E8A34005C6AF4001B02442000164 -:103CF000AF4202E88F4202E88EE201502442000106 -:103D0000AEE20150100000038EE2015024020001D7 -:103D1000A34205C68FBF00488FBE00448FB5004048 -:103D20008FB3003C8FB200388FB100348FB00030B9 -:103D300003E0000827BD005027BDFFD8AFBF00201B -:103D40008F8200B030420004104000680000000084 -:103D50008F4301288F8201041462000500000000D7 -:103D60008F4301308F8200B4106200060000000013 -:103D70008F820104AF4201288F8200B41000005BE3 -:103D8000AF4201308F8200B03C030080004310241A -:103D90001040000D000000008F82011C3442000220 -:103DA000AF82011C8F8200B02403FFFB004310246C -:103DB000AF8200B08F82011C2403FFFD004310245A -:103DC0001000004AAF82011C8F4301288F8201043A -:103DD00014620005000000008F4301308F8200B4A0 -:103DE00010620010000000008F820104AF42012821 -:103DF0008F8200B48F430128AF420130AFA300107F -:103E00008F4201303C04000124846144AFA20014BD -:103E10008F86011C8F8700B03C0500051000003123 -:103E200034A509008F420128AFA200108F42013053 -:103E30003C04000124846150AFA200148F86011C51 -:103E40008F8700B03C0500050C002B3B34A510000B -:103E50008F82011C34420002AF82011C8F83010457 -:103E60008F8200B034420001AF8200B0240200080B -:103E7000AF830104AFA20010AFA000148F42000C6A -:103E80008C0402088C05020CAFA200188F42010CB2 -:103E900026E600280040F809240704008F82011C50 -:103EA0002403FFFD00431024AF82011C8EE201DCDD -:103EB00024420001AEE201DC8EE201DC8F420128E7 -:103EC000AFA200108F4201303C0400012484615CE9 -:103ED000AFA200148F86011C8F8700B03C0500053F -:103EE00034A511000C002B3B000000008F8200A0C5 -:103EF0003042000410400069000000008F43012C94 -:103F00008F82012414620005000000008F430134F9 -:103F10008F8200A410620006000000008F8201243E -:103F2000AF42012C8F8200A41000005CAF4201342C -:103F30008F8200A03C030080004310241040000D3D -:103F4000000000008F82011C34420002AF82011C7D -:103F50008F8200A02403FFFB00431024AF8200A047 -:103F60008F82011C2403FFFD004310241000004B2E -:103F7000AF82011C8F43012C8F8201241462000543 -:103F8000000000008F4301348F8200A410620010F3 -:103F9000000000008F820124AF42012C8F8200A418 -:103FA0008F43012CAF420134AFA300108F42013484 -:103FB0003C04000124846168AFA200148F86011CB8 -:103FC0008F8700A03C0500051000003234A51200C8 -:103FD0008F42012CAFA200108F4201343C0400013B -:103FE00024846174AFA200148F86011C8F8700A007 -:103FF0003C0500050C002B3B34A513008F82011CEF -:1040000034420002AF82011C8F8301248F8200A002 -:1040100034420001AF8200A024020080AF8301245B -:10402000AFA20010AFA000148F4200148C0402084D -:104030008C05020CAFA200188F4201083C0600015B -:1040400024C66ED80040F809240700048F82011CA2 -:104050002403FFFD00431024AF82011C8EE201DC2B -:1040600024420001AEE201DC8EE201DC8F42012C31 -:10407000AFA200108F4201343C040001248461800F -:10408000AFA200148F86011C8F8700A03C0500059D -:1040900034A514000C002B3B000000008FBF002053 -:1040A00003E0000827BD00283C0810002407000199 -:1040B0003C0600803C0501008F82007000481024FF -:1040C0001040FFFD000000008F82005424420005D4 -:1040D000AF8200788C040234108000160000182192 -:1040E0003C020001005710218C4240E824420005A8 -:1040F0003C01000100370821AC2240E83C020001ED -:10410000005710218C4240E80044102B1440000955 -:10411000000000003C0300803C0100010037082142 -:10412000AC2040E83C010001003708211000000BE2 -:10413000A02740F03C02000100571021904240F0BF -:1041400054400006006618253C020001005710216B -:10415000904240F154400001006618258C04023062 -:1041600010800013000000003C02000100571021E5 -:104170008C4240EC244200053C010001003708213C -:10418000AC2240EC3C020001005710218C4240EC74 -:104190000044102B14400006000000003C01000108 -:1041A00000370821AC2040EC1000000600651825FF -:1041B0003C02000100571021904240F2544000019F -:1041C000006518251060FFBC000000008F42000051 -:1041D0001040000700000000AF80004C8F82004CB0 -:1041E0001040FFFD0000000010000005000000006E -:1041F000AF8000488F8200481040FFFD00000000A3 -:104200008F82006000431025AF8200608F42000063 -:1042100010400003000000001000FFA7AF80004C1A -:104220001000FFA5AF80004803E000080000000078 -:1042300000000000000000000000000027BDFFE0BB -:10424000AFBF00188F86006430C200041040002504 -:10425000240400048C020114AF420020AF840064E7 -:104260008F4202FC24420001AF4202FC8F4202FC5A -:104270008F820064304200041440000500000000FA -:104280008C0301148F4200201462FFF20000000032 -:104290008F420000104000078F43003CAF80004C6D -:1042A0008F82004C1040FFFD000000001000000550 -:1042B00000000000AF8000488F8200481040FFFDE2 -:1042C000000000008F82006000431025AF82006074 -:1042D0008F42000010400073000000001000006FCB -:1042E0000000000030C20008104000202404000834 -:1042F0008C02011CAF420048AF8400648F4202A8C8 -:1043000024420001AF4202A88F4202A88F820064BB -:104310003042000814400005000000008C03011C1E -:104320008F4200481462FFF2000000008F4200003C -:104330001040000700000000AF80004C8F82004C4E -:104340001040FFFD0000000010000005000000000C -:10435000AF8000488F8200481040FFFD0000000041 -:104360008F8200601000FFD93442020030C200206A -:1043700010400023240400208C02012CAF4200686E -:10438000AF8400648F4202D824420001AF4202D8B9 -:104390008F4202D88F820064304200201440000512 -:1043A00032C240008C03012C8F4200681462FFF27D -:1043B00032C24000144000023C02000102C2B0259B -:1043C0008F4200001040000700000000AF80004C4A -:1043D0008F82004C1040FFFD00000000100000051F -:1043E00000000000AF8000488F8200481040FFFDB1 -:1043F000000000008F8200601000FFB4344208000B -:1044000030C2001010400029240400108C02012446 -:10441000AF420058AF8400648F4202D424420001AE -:10442000AF4202D48F4202D48F8200643042001027 -:104430001440000532C220008C0301248F42005832 -:104440001462FFF232C220005040000136D68000D4 -:104450008F4200001040000700000000AF80004CB9 -:104460008F82004C1040FFFD00000000100000058E -:1044700000000000AF8000488F8200481040FFFD20 -:10448000000000008F82006034420100AF820060B3 -:104490008F42000010400003000000001000006C7C -:1044A000AF80004C1000006AAF80004830C20001AD -:1044B0001040000424020001AF8200641000006478 -:1044C0000000000030C200021440000B3C05000355 -:1044D0003C0400012484624434A505000000382116 -:1044E000AFA000100C002B3BAFA000142402FFC0B3 -:1044F00010000057AF8200648C05022C8C02010C66 -:1045000010A20048000510808C46030024A2000180 -:104510003045003F24020003AC05022C00061E02B9 -:1045200010620005240200101062001D30C20FFF4F -:1045300010000039000000008F4302A88F440000E3 -:1045400030C20FFFAF42004824630001AF4302A80E -:10455000108000078F4202A8AF80004C8F82004C71 -:104560001040FFFD000000001000000500000000EA -:10457000AF8000488F8200481040FFFD000000001F -:104580008F82006034420200AF8200608F420000E0 -:104590001040001F000000001000001B0000000081 -:1045A000AF42005832C220005040000136D6800091 -:1045B0008F4202D48F43000024420001AF4202D454 -:1045C000106000078F4202D4AF80004C8F82004CF5 -:1045D0001040FFFD0000000010000005000000007A -:1045E000AF8000488F8200481040FFFD00000000AF -:1045F0008F82006034420100AF8200608F42000071 -:10460000104000030000000010000006AF80004CC6 -:1046100010000004AF8000480C00219600C020214B -:10462000004028218C02010C14A200022402000286 -:10463000AF8200648F8200643042000214400004A4 -:10464000000000008C02010C14A2FFAC000000006E -:104650008FBF001803E0000827BD002003E000081A -:104660000000000027BDFFA0AFB000400080802107 -:10467000001016022442FFFF304300FF2C6200139B -:10468000AFBF0058AFBE0054AFB50050AFB3004C41 -:10469000AFB20048AFB10044104001F3AFA5003401 -:1046A000000310803C010001002208218C22628856 -:1046B00000400008000000000010130230440FFF0B -:1046C0002402000110820005240200021082000C66 -:1046D0002402FFFE100000243C0500038F43000469 -:1046E0003C0200018C426F04AF440200AF4402045C -:1046F0003C0400018C846E801000000934630001CA -:104700008F430004AF440200AF4402043C040001A4 -:104710008C846E80006218243C0200012442CA2866 -:104720000002110000021182AF4300043C030800A4 -:1047300000431025AC8200388F84005400041442DA -:1047400000041C820043102100041CC200431023FB -:1047500000041D020043102100041D4200431023E9 -:1047600010000009AF4202083C040001248462509A -:1047700034A510000200302100003821AFA0001045 -:104780000C002B3BAFA000148F4202A0244200017A -:10479000AF4202A01000021F8F4202A027B00028E3 -:1047A00002002021240502100C002BBF2406000863 -:1047B0000C00251802002021100002160000000045 -:1047C0008FAA003427A40028000A1880254200017F -:1047D0003042003FAFA200348C6503008FAA003442 -:1047E000000210808C430300254200013042003F4C -:1047F000AFA20034AC02022CAFA500280C00251893 -:10480000AFA3002C100002030000000027B0002816 -:1048100002002021240502100C002BBF24060008F2 -:104820000C00265702002021100001FA00000000B1 -:104830008FAA003427A40028000A1880254200010E -:104840003042003FAFA200348C6503008FAA0034D1 -:10485000000210808C430300254200013042003FDB -:10486000AFA20034AC02022CAFA500280C002657E2 -:10487000AFA3002C100001E700000000001013029D -:1048800030430FFF240200011062000524020002E1 -:104890001062001E3C020002100000333C050003C1 -:1048A0003C03000202C310245440003702C3B02569 -:1048B0008F8202283C01000100370821AC2238D841 -:1048C0008F82022C3C01000100370821AC2238DC29 -:1048D0008F8202303C01000100370821AC2238E011 -:1048E0008F8202343C01000100370821AC2238E4F9 -:1048F0002402FFFFAF820228AF82022CAF82023077 -:10490000AF8202341000002002C3B02502C210247E -:10491000104000123C02FFFD3C0200010057102134 -:104920008C4238D8AF8202283C0200010057102187 -:104930008C4238DCAF82022C3C020001005710216F -:104940008C4238E0AF8202303C0200010057102157 -:104950008C4238E4AF8202343C02FFFD3442FFFF58 -:104960001000000902C2B0243C0400012484625CEF -:1049700034A511000200302100003821AFA0001042 -:104980000C002B3BAFA000148F4202CC244200014C -:10499000AF4202CC1000019F8F4202CC00101302E4 -:1049A00030450FFF2402000110A20005240200027E -:1049B00010A2000D3C0408FF100000143C05000389 -:1049C0003C0208FF3442FFFF8F8302203C040004B6 -:1049D00002C4B0250062182434630008AF830220AB -:1049E00010000012AF4502983484FFF73C03FFFB30 -:1049F0008F8202203463FFFF02C3B02400441024DE -:104A0000AF82022010000009AF4502983C0400016B -:104A10002484626834A5120002003021000038218D -:104A2000AFA000100C002B3BAFA000148F4202BCC3 -:104A300024420001AF4202BC100001768F4202BC4A -:104A400027840208240502000C002BBF240600085E -:104A500027440224240502000C002BBF2406000872 -:104A60008F4202C424420001AF4202C41000016917 -:104A70008F4202C40010130230430FFF24020001D2 -:104A8000106200112862000250400005240200025A -:104A90001060000700000000100000170000000078 -:104AA0001062000F00000000100000130000000062 -:104AB0008C060248000020210C005104240500044B -:104AC00010000007000000008C06024800002021B2 -:104AD0000C00510424050004100000100000000028 -:104AE0008C06024C000020210C005104240500011A -:104AF0001000000A000000003C04000124846274DD -:104B00003C05000334A513000200302100003821C9 -:104B1000AFA000100C002B3BAFA000148F4202C0CE -:104B200024420001AF4202C01000013A8F4202C08D -:104B30000C002426000000001000013600000000D8 -:104B400024020001A34205C5241001008F4401A8DE -:104B50008F4501ACAFB00010AFA000148F4200141D -:104B6000AFA200188F42010826E600280040F8098D -:104B7000240704001040FFF500000000100001258C -:104B8000000000003C03FFFF34637FFF8F42036897 -:104B90008F44036002C3B02400001821AF400058C6 -:104BA000AF40005CAF400060AF40006400441023A1 -:104BB000AF4203683C020900AF400360AFA200208F -:104BC0008F5E001827AA0020240200FF13C20002F3 -:104BD000AFAA003C27C300018C020228006090218C -:104BE0001642000E001E38C08F42033C24420001D2 -:104BF000AF42033C8F42033C8C0202283C0400017C -:104C00002484620C3C050009AFA00014AFA2001080 -:104C10008FA600201000006B34A5050000F71021BE -:104C20008FA300208FA40024AC4304C0AC4404C470 -:104C30008F8300548F820054247003E802021023F3 -:104C40002C4203E91040001B0000982100E088215D -:104C5000263504C08F4401788F45017C022018213D -:104C6000240A0004AFAA0010AFB200148F48000C51 -:104C70000000102102F53021AFA800188F48010C68 -:104C80002407000800A3282100A3482B008220212C -:104C90000100F80900892021544000062413000176 -:104CA0008F820054020210232C4203E91440FFE9D2 -:104CB00000000000326200FF54400017AF5200189D -:104CC0008F42037824420001AF4203788F42037879 -:104CD0008F8201208FAA003CAFA200108F82012496 -:104CE0003C040001248462183C050009AFA20014B2 -:104CF0008D4600001000003334A506008F420308E3 -:104D00002413000124420001AF4203088F4203082C -:104D10001000001C326200FF8F8300548F82005409 -:104D2000247003E8020210232C4203E9104000140F -:104D300000009821241100108F42000C8F44016064 -:104D40008F4501648F860120AFB10010AFB200140F -:104D5000AFA200188F42010C240700080040F80998 -:104D600024C6001C1440FFE5000000008F820054A0 -:104D7000020210232C4203E91440FFEF0000000060 -:104D8000326200FF14400011000000008F420378DF -:104D900024420001AF4203788F4203788F820120C2 -:104DA0008FAA003CAFA200108F8201243C040001B6 -:104DB000248462203C050009AFA200148D46000047 -:104DC00034A507000C002B3B03C038218F4202B0F2 -:104DD00024420001AF4202B08F4202B08F4202F87B -:104DE00024420001AF4202F81000008A8F4202F80C -:104DF0008C02025C27440224AF4201F08C02026064 -:104E000024050200240600080C002BBFAF4201F865 -:104E10008F82022030420008144000022402000168 -:104E200024020002AF4202988F4202AC24420001E9 -:104E3000AF4202AC100000778F4202AC3C0200FF90 -:104E40003442FFFF0202182432C2018014400006DF -:104E50003402FFFB0043102B14400003000000004D -:104E60001000006CAF4300BC3C040001248462804D -:104E70003C05000334A51500020030210000382154 -:104E8000AFA000100C002B3BAFA000143C020700A9 -:104E90003442100000101E0200621825AFA300204B -:104EA0008F510018240200FF12220002000080210E -:104EB000263000018C0202281602000E001130C0BC -:104EC0008F42033C24420001AF42033C8F42033C2B -:104ED0008C0202283C040001248461F43C05000992 -:104EE000AFA00014AFA200108FA600201000003F5A -:104EF00034A5010000D710218FA300208FA4002427 -:104F0000AC4304C0AC4404C400C018218F440178F1 -:104F10008F45017C0000102124070004AFA700107A -:104F2000AFB000148F48000C24C604C002E6302144 -:104F3000AFA800188F48010C2407000800A32821FF -:104F400000A3482B008220210100F80900892021BC -:104F50001440000B240700088F820120AFA200102C -:104F60008F8201243C040001248461FC3C0500097B -:104F7000AFA200148FA600201000001C34A5020070 -:104F80008F4401608F4501648F43000CAF500018BF -:104F90008F86012024020010AFA20010AFB00014D1 -:104FA000AFA300188F42010C0040F80924C6001C72 -:104FB00014400010000000008F4203402442000112 -:104FC000AF4203408F4203408F820120AFA2001006 -:104FD0008F8201243C040001248462043C05000902 -:104FE000AFA200148FA6002034A503000C002B3BB9 -:104FF000022038218F4202E024420001AF4202E049 -:105000008F4202E08F4202F024420001AF4202F0E0 -:105010008F4202F08FA200348FBF00588FBE005421 -:105020008FB500508FB3004C8FB200488FB1004451 -:105030008FB0004003E0000827BD006027BDFFF8E7 -:105040002408FFFF10A00014000048213C0AEDB81E -:10505000354A83209087000024840001000030211D -:1050600001071026304200011040000200081842DB -:10507000006A18260060402124C600012CC20008E6 -:105080001440FFF700073842252900010125102BA5 -:105090001440FFF0000000000100102103E00008B0 -:1050A00027BD000827BDFFB0AFBF0048AFBE00441A -:1050B000AFB50040AFB3003CAFB20038AFB1003481 -:1050C000AFB000308F870220AFA700248F87020087 -:1050D000AFA7002C8F8202203C0308FF3463FFFF40 -:1050E0000043102434420004AF8202208F82020069 -:1050F0003C03C0FF3463FFFF00431024344200042C -:10510000AF8202008F5303588F55035C8F5E03609C -:105110008F470364AFA700148F470368AFA7001C35 -:105120008F4202D0274401C024420001AF4202D086 -:105130008F5002D08F5102048F5202000C002BA816 -:1051400024050400AF530358AF55035CAF5E036002 -:105150008FA70014AF4703648FA7001CAF470368F5 -:10516000AF5002D0AF510204AF5202008C02025C79 -:1051700027440224AF4201F08C02026024050200A1 -:1051800024060008AF4201F8240200060C002BBFE1 -:10519000AF4201F43C023B9A3442CA00AF4201FCE8 -:1051A000240203E82404000224030001AF42029415 -:1051B000AF440290AF43029C8F820220304200082D -:1051C0001040000400000000AF43029810000003EC -:1051D00000003021AF440298000030213C03000160 -:1051E0000066182190636D000346102124C600015B -:1051F000A043022C2CC2000F1440FFF803461821D4 -:1052000024C600018F820040240400802405008011 -:105210000002170224420030A062022C0346102133 -:105220000C002BA8A040022C8FA7002430E2000421 -:1052300014400006000000008F8202203C0308FF9B -:105240003463FFFB00431024AF8202208FA7002CA1 -:1052500030E2000414400006000000008F820200CB -:105260003C03C0FF3463FFFB00431024AF82020005 -:105270008FBF00488FBE00448FB500408FB3003C05 -:105280008FB200388FB100348FB0003003E00008D7 -:1052900027BD00500000000000000000AF400104E6 -:1052A00024040001000410C002E21821248200013D -:1052B0003C01000100230821A42234D00040202119 -:1052C0002C8200801440FFF8000410C0240200016A -:1052D0003C01000100370821A42038D0AF42010072 -:1052E000AF800228AF80022CAF800230AF80023442 -:1052F00003E000080000000027BDFFE8AFBF001476 -:10530000AFB000108F420104284200051040002673 -:10531000008080213C0200018F430104344230D0E0 -:1053200002E22021000318C00062182102E31821C4 -:105330000083102B1040001500001021960700007C -:1053400024840006246600069482FFFC14470009AA -:10535000000028219483FFFE9602000214620006DA -:1053600000A0102194820000960300040043102640 -:105370002C45000100A010211440000924840008DD -:105380000086102B1440FFF000001021304200FF77 -:1053900014400030240200011000002E00001021F3 -:1053A0001000FFFA24020001020020210C00240C4E -:1053B000240500063042007F000218C002E31021DD -:1053C0003C01000100220821942230D01040FFF25D -:1053D00002E310213C06000100C2302194C630D007 -:1053E00010C0FFED3C080001350834D296070000DC -:1053F000000610C000572021008820219482000060 -:10540000144700090000282194830002960200023C -:105410001462000600A01021948200049603000488 -:10542000004310262C45000100A010211440000765 -:10543000000610C002E210213C06000100C230212B -:1054400094C634D014C0FFEB000610C010C0FFD2C9 -:10545000240200018FBF00148FB0001003E0000889 -:1054600027BD001803E000080000000027BDFFB0C2 -:1054700000801021AFB00030245000020200202133 -:1054800024050006AFB1003400408821AFBF0048BA -:10549000AFBE0044AFB50040AFB3003C0C00240CDD -:1054A000AFB200383047007F000710C002E2102181 -:1054B0003C05000100A2282194A530D050A0001C7A -:1054C00000A030213C090001352934D29628000281 -:1054D000000510C00057202100892021948200007F -:1054E0001448000900003021948300029602000253 -:1054F0001462000600C01021948200049603000488 -:10550000004310262C46000100C010211440000763 -:10551000000510C002E210213C05000100A2282174 -:1055200094A534D014A0FFEB000510C000A03021DA -:1055300010C00014000610C0005718213C010001E3 -:10554000002308218C2334D000571021AFA3001072 -:105550003C010001002208218C2234D43C040001CB -:1055600024846394AFA200148E2600008E270004CA -:105570003C0500040C002B3B34A504001000006324 -:105580003C0208008F45010010A00006000510C075 -:1055900002E210213C01000100220821942234D0B3 -:1055A000AF42010000A0302114C00011000628C045 -:1055B000000710C002E21021AFA700103C0100015B -:1055C00000220821942230D03C040001248463A0EE -:1055D000AFA200148E2600008E2700043C050004B4 -:1055E0000C002B3B34A50500100000483C020800CD -:1055F00000B718213C02000196040000344234D266 -:1056000000621821A46400008E020002000720C07E -:10561000AC62000202E410213C0300010062182188 -:10562000946330D002E510213C01000100220821E2 -:10563000A42334D002E410213C01000100220821FF -:10564000A42630D08F420104244200012842008069 -:105650001040000F3C0200028F4201043C04000194 -:10566000348430D296030000000210C0005710218D -:1056700000441021A44300008E030002AC4300024A -:105680008F42010424420001AF4201043C020002A7 -:1056900002C2102410400011000721423C03000107 -:1056A000346338D824020003004410230002108021 -:1056B0000057202100832021005710210043102192 -:1056C00030E5001F8C4300002402000100A21004FA -:1056D000006218251000000CAC83000024020003B7 -:1056E0000044102300021080005C2821005C10217F -:1056F00030E4001F8C4302282402000100821004C1 -:1057000000621825ACA302283C02080034421000B5 -:1057100000001821AFA200208F5E001827AA0020E9 -:10572000240200FF13C20002AFAA002C27C300010D -:105730008C020228006090211642000E001E38C024 -:105740008F42033C24420001AF42033C8F42033CA2 -:105750008C0202283C0400012484635C3C0500099F -:10576000AFA00014AFA200108FA600201000006BA5 -:1057700034A5050000F710218FA300208FA400247A -:10578000AC4304C0AC4404C48F8300548F820054E3 -:10579000247003E8020210232C4203E91040001B8E -:1057A0000000982100E08821263504C08F4401784C -:1057B0008F45017C02201821240A0004AFAA0010A2 -:1057C000AFB200148F48000C0000102102F5302108 -:1057D000AFA800188F48010C2407000800A3282157 -:1057E00000A3482B008220210100F8090089202114 -:1057F00054400006241300018F820054020210233B -:105800002C4203E91440FFE900000000326200FF6F -:1058100054400017AF5200188F4203782442000111 -:10582000AF4203788F4203788F8201208FAA002C29 -:10583000AFA200108F8201243C040001248463681D -:105840003C050009AFA200148D4600001000003393 -:1058500034A506008F4203082413000124420001EE -:10586000AF4203088F4203081000001C326200FFA1 -:105870008F8300548F820054247003E802021023A7 -:105880002C4203E91040001400009821241100105C -:105890008F42000C8F4401608F4501648F86012088 -:1058A000AFB10010AFB20014AFA200188F42010CCC -:1058B000240700080040F80924C6001C1440FFE536 -:1058C000000000008F820054020210232C4203E9E2 -:1058D0001440FFEF00000000326200FF144000118E -:1058E000000000008F42037824420001AF42037899 -:1058F0008F4203788F8201208FAA002CAFA2001064 -:105900008F8201243C040001248463703C0500095B -:10591000AFA200148D46000034A507000C002B3BFD -:1059200003C038218F4202B424420001AF4202B4C6 -:105930008F4202B48F4202F424420001AF4202F4CB -:105940008F4202F48FBF00488FBE00448FB50040E5 -:105950008FB3003C8FB200388FB100348FB000306D -:1059600003E0000827BD005027BDFFA000801021E4 -:10597000AFB00040245000020200202124050006A0 -:10598000AFB1004400408821AFBF0058AFBE005403 -:10599000AFB50050AFB3004C0C00240CAFB20048C0 -:1059A0003048007F000810C002E210213C060001D0 -:1059B00000C2302194C630D010C0001C0000382135 -:1059C0003C0A0001354A34D296290002000610C074 -:1059D00000572021008A20219482000014490009E8 -:1059E000000028219483000296020002146200063F -:1059F00000A01021948200049603000400431026A6 -:105A00002C45000100A0102114400008000610C021 -:105A100000C0382102E210213C06000100C2302102 -:105A200094C634D014C0FFEA000610C014C00011A0 -:105A3000AFA70028000810C002E21021AFA8001094 -:105A40003C01000100220821942230D03C040001D6 -:105A5000248463ACAFA200148E2600008E270004BD -:105A60003C0500040C002B3B34A509001000007518 -:105A70003C02080010E0000C000610C002E21021F9 -:105A80003C03000100621821946334D0000710C069 -:105A900002E210213C01000100220821A42334D09D -:105AA0001000000B3C04000102E210213C03000145 -:105AB00000621821946334D0000810C002E2102163 -:105AC0003C01000100220821A42330D03C04000145 -:105AD000348430D08F430100000610C002E2102150 -:105AE0003C01000100220821A42334D08F4201048C -:105AF00002E438210000282118400029AF460100A7 -:105B000024E6000694C3FFFC96020000146200091C -:105B10000000202194C3FFFE9602000214620006DA -:105B20000080102194C20000960300040043102658 -:105B30002C440001008010215040001424A50001D5 -:105B40008F4201042442FFFF00A2102A1040000BE4 -:105B500024E40004948200068C830008A482FFFEE3 -:105B6000AC8300008F42010424A500012442FFFF02 -:105B700000A2102A1440FFF7248400088F42010479 -:105B80002442FFFF10000006AF4201048F420104CF -:105B900024C6000800A2102A1440FFDA24E70008F7 -:105BA000000810C002E210213C010001002208217F -:105BB000942230D0144000233C0208003C02000232 -:105BC00002C2102410400012000821423C030001D0 -:105BD000346338D8240200030044102300021080EC -:105BE000005720210083202100571021004310215D -:105BF0003105001F240300018C42000000A318049B -:105C000000031827004310241000000DAC82000090 -:105C1000240200030044102300021080005C2821AD -:105C2000005C10213104001F240300018C42022873 -:105C3000008318040003182700431024ACA2022894 -:105C40003C0208003442200000001821AFA20020CE -:105C50008F5E001827AB0020240200FF13C2000251 -:105C6000AFAB003427C300018C02022800609021F2 -:105C70001642000E001E38C08F42033C2442000131 -:105C8000AF42033C8F42033C8C0202283C040001DB -:105C90002484635C3C050009AFA00014AFA200108F -:105CA0008FA600201000006B34A5050000F710211E -:105CB0008FA300208FA40024AC4304C0AC4404C4D0 -:105CC0008F8300548F820054247003E80202102353 -:105CD0002C4203E91040001B0000982100E08821BD -:105CE000263504C08F4401788F45017C022018219D -:105CF000240B0004AFAB0010AFB200148F48000CAF -:105D00000000102102F53021AFA800188F48010CC7 -:105D10002407000800A3282100A3482B008220218B -:105D20000100F809008920215440000624130001D5 -:105D30008F820054020210232C4203E91440FFE931 -:105D400000000000326200FF54400017AF520018FC -:105D50008F42037824420001AF4203788F420378D8 -:105D60008F8201208FAB0034AFA200108F820124FC -:105D70003C040001248463683C050009AFA20014C0 -:105D80008D6600001000003334A506008F42030822 -:105D90002413000124420001AF4203088F4203088C -:105DA0001000001C326200FF8F8300548F82005469 -:105DB000247003E8020210232C4203E9104000146F -:105DC00000009821241100108F42000C8F440160C4 -:105DD0008F4501648F860120AFB10010AFB200146F -:105DE000AFA200188F42010C240700080040F809F8 -:105DF00024C6001C1440FFE5000000008F82005400 -:105E0000020210232C4203E91440FFEF00000000BF -:105E1000326200FF14400011000000008F4203783E -:105E200024420001AF4203788F4203788F82012021 -:105E30008FAB0034AFA200108F8201243C0400011C -:105E4000248463703C050009AFA200148D66000035 -:105E500034A507000C002B3B03C038218F4202B849 -:105E600024420001AF4202B88F4202B88F4202F4CE -:105E700024420001AF4202F48F4202F48FBF005867 -:105E80008FBE00548FB500508FB3004C8FB20048C6 -:105E90008FB100448FB0004003E0000827BD0060D0 -:105EA00000000000000000000000000027BDFFE02F -:105EB00027644000AFBF00180C002BA82405100079 -:105EC0003C03000134632CC03C04000134842EC820 -:105ED00024020020AF82011C02E31021AF800100E8 -:105EE000AF800104AF800108AF800110AF800114C2 -:105EF000AF800118AF800120AF800124AF8001285E -:105F0000AF800130AF800134AF800138AF4200EC88 -:105F100002E31021AF4200F002E41021AF4200F48E -:105F200002E41021AF4200F83C02000100571021AA -:105F3000904240F41440001C3C0500018F82011C7B -:105F40003C040001248464703C05000134420001DB -:105F5000AF82011CAFA00010AFA000148F86011CFF -:105F600034A501000C002B3B000038218C020218E4 -:105F70003042004010400014000000008F82011CDD -:105F80003C0400012484647C3C050001344200048C -:105F9000AF82011CAFA00010AFA000148F86011CBF -:105FA0001000000734A502003C040001248464842E -:105FB000AFA00010AFA000148F86011C34A5030011 -:105FC0000C002B3B000038218FBF001803E00008B5 -:105FD00027BD00208FA900108F83012C8FAA0014E9 -:105FE0008FAB00181060000A27624FE014620002B5 -:105FF00024680020276848008F82012811020004CD -:10600000000000008F82012415020007000000003C -:106010008F4303340000102124630001AF43033495 -:10602000100000398F430334AC640000AC650004F9 -:10603000AC660008A467000EAC690018AC6A001CCE -:10604000AC6B0010AC620014AF8801208F4200FCE2 -:106050008F4400F42442FFFFAF4200FC8C8200001A -:10606000104900053042FF8F104000193122FF8F88 -:10607000104000183C0200018C8300042C620010C8 -:10608000104000133C02000124630001AC830004B3 -:106090008F4300F8344230C802E2102154620004F9 -:1060A000246200083C02000134422EC802E21021A2 -:1060B00014440015240200018F820128244200208C -:1060C000AF8201288F8201281000000F24020001F6 -:1060D0003C020001344230C802E210215482000424 -:1060E000248200083C02000134422EC802E2102142 -:1060F0000040202124020001AF4400F4AC890000DC -:10610000AC8200042402000103E00008000000004B -:1061100003E00008000000008FA900108F83010C2D -:106120008FAA00148FAB00181060000A276247E0A6 -:106130001462000224680020276840008F82010852 -:1061400011020004000000008F8201041502000704 -:10615000000000008F430338000010212463000179 -:10616000AF430338100000358F430338AC640000A0 -:10617000AC650004AC660008A467000EAC690018AA -:10618000AC6A001CAC6B0010AC620014AF8801005C -:106190008F4400EC8C820000304200061040001951 -:1061A00031220006104000183C0200018C830004DC -:1061B0002C620010104000133C0200012463000117 -:1061C000AC8300048F4300F034422EC002E2102161 -:1061D00054620004246200083C02000134422CC0D6 -:1061E00002E2102114440015240200018F820108EC -:1061F00024420020AF8201088F8201081000000FA6 -:10620000240200013C02000134422EC002E21021AF -:1062100054820004248200083C02000134422CC055 -:1062200002E210210040202124020001AF4400ECD2 -:10623000AC890000AC8200042402000103E00008E5 -:106240000000000003E000080000000027BDFFD8A8 -:106250003C0400012484648C3C050001AFBF002491 -:10626000AFB20020AFB1001CAFB000188F90010496 -:106270008F9100B08F92011C34A525008F82010000 -:106280000240302102203821AFA200100C002B3B2D -:10629000AFB000148E020008AFA200108E02000CF6 -:1062A0003C04000124846498AFA200148E06000010 -:1062B0008E0700043C0500010C002B3B34A5251083 -:1062C0008E020018AFA200108E02001C3C040001D8 -:1062D000248464A4AFA200148E0600108E0700145C -:1062E0003C0500010C002B3B34A525203C027F001F -:1062F000022210243C030800544300163C03020011 -:106300008F82009C3042FFFF144000123C030200C9 -:106310003C040001248464B03C05000234A5F03044 -:10632000000030210000382136420002AF82011CFB -:1063300036220001AF8200B0AF900104AF92011C81 -:10634000AFA000100C002B3BAFA0001410000024E5 -:106350000000000002C310241040000D022310248E -:106360001040000B36420002AF82011C36220001B1 -:10637000AF8200B0AF900104AF92011C8F42033096 -:1063800024420001AF420330100000158F42033059 -:106390003C040001248464B8240202A9AFA20010C6 -:1063A000AFA000148F8601443C07000124E764C0BD -:1063B0000C002B3B3405DEAD8F82011C3442000201 -:1063C000AF82011C8F82022034420004AF8202207F -:1063D0008F8201403C03000100431025AF82014041 -:1063E0008FBF00248FB200208FB1001C8FB0001827 -:1063F00003E0000827BD002827BDFFD83C040001AA -:10640000248464E83C050001AFBF0024AFB2002043 -:10641000AFB1001CAFB000188F9001248F9100A085 -:106420008F92011C34A526008F820120024030216A -:1064300002203821AFA200100C002B3BAFB000149B -:106440008E020008AFA200108E02000C3C04000176 -:10645000248464F4AFA200148E0600008E070004AA -:106460003C0500010C002B3B34A526108E020018C1 -:10647000AFA200108E02001C3C04000124846500C1 -:10648000AFA200148E0600108E0700143C05000118 -:106490000C002B3B34A526203C027F000222102456 -:1064A0003C030800544300163C0302008F8200ACFA -:1064B0003042FFFF144000123C0302003C04000184 -:1064C0002484650C3C05000134A5F0300000302127 -:1064D0000000382136420002AF82011C3622000142 -:1064E000AF8200A0AF900124AF92011CAFA00010BA -:1064F0000C002B3BAFA00014100000240000000093 -:1065000002C310241040000D022310241040000B81 -:1065100036420002AF82011C36220001AF8200A089 -:10652000AF900124AF92011C8F42032C2442000142 -:10653000AF42032C100000158F42032C3C040001D5 -:10654000248464B8240202E2AFA20010AFA00014B9 -:106550008F8601443C07000124E764C00C002B3BFC -:106560003405DEAD8F82011C34420002AF82011C73 -:106570008F82022034420004AF8202208F820140C9 -:106580003C03000100431025AF8201408FBF00246F -:106590008FB200208FB1001C8FB0001803E00008FC -:1065A00027BD00280000602100005021000030219C -:1065B0000000282100006821000048210000782107 -:1065C000000070218F8801248F8701041580002E20 -:1065D0008F8B011C11A00014316208008F820120F2 -:1065E00010460029000000003C0400018C846EE489 -:1065F0008CC200008CC30004AC820000AC83000499 -:106600008CC20008AC82000894C2000EA482000E66 -:106610008CC20010240C0001AC8200108CC200144B -:106620001000001224C600201040001700000000D7 -:106630003C0400018C846EE48D0200008D03000494 -:10664000AC820000AC8300048D020008AC8200081C -:106650009502000EA482000E8D0200102506002077 -:10666000AC8200108D020014240C000100C018211F -:10667000AC82001427624FE00043102B544000010D -:1066800027634800006030211540002F316201006F -:1066900011200014316280008F8201001045002A11 -:1066A000316201003C0400018C846EE08CA2000089 -:1066B0008CA30004AC820000AC8300048CA2000810 -:1066C000AC82000894A2000EA482000E8CA20010DE -:1066D000240A0001AC8200108CA2001410000012E9 -:1066E00024A5002010400018316201003C04000184 -:1066F0008C846EE08CE200008CE30004AC8200002D -:10670000AC8300048CE20008AC82000894E2000E26 -:10671000A482000E8CE2001024E50020AC82001060 -:106720008CE20014240A000100A01821AC8200149D -:10673000276247E00043102B5440000127634000CC -:1067400000602821316201005440001D31621000B8 -:1067500011A0000931A20800104000042502002009 -:106760008F8200A8A5E2000025020020AF8201244C -:106770008F8801240000682111800011316210000F -:106780003C0400018C846EE48C8200008C83000445 -:10679000AF820080AF8300848C820008AF8200A4A7 -:1067A0009482000EAF8200AC8C8200100000602149 -:1067B000AF8200A08C8D00108C8F0014316210000D -:1067C0001440FF82000000001120000F3122080059 -:1067D000104000043C0200028F8200B8A5C20000F5 -:1067E0003C020002012210241040000424E2002098 -:1067F0008F8200B4AF8200D424E20020AF82010473 -:106800008F870104000048211140FF700000000044 -:106810003C0400018C846EE08C8200008C830004B8 -:10682000AF820090AF8300948C820008AF8200B4E6 -:106830009482000EAF82009C8C82001000005021D8 -:10684000AF8200B08C8900101000FF608C8E0014A5 -:1068500003E0000800000000000060210000582153 -:106860000000302100002821000068210000502194 -:1068700000007821000070218F8801248F87010497 -:106880003C1801001580002E8F89011C11A00014F6 -:10689000312208008F8201201046002900000000EC -:1068A0003C0400018C846EE48CC200008CC30004A4 -:1068B000AC820000AC8300048CC20008AC820008EB -:1068C00094C2000EA482000E8CC20010240C0001A1 -:1068D000AC8200108CC200141000001224C60020EC -:1068E00010400017000000003C0400018C846EE49E -:1068F0008D0200008D030004AC820000AC83000414 -:106900008D020008AC8200089502000EA482000EE1 -:106910008D02001025060020AC8200108D020014AC -:10692000240C000100C01821AC82001427624FE043 -:106930000043102B544000012763480000603021C1 -:106940001560002F31220100114000143122800017 -:106950008F8201001045002A312201003C04000111 -:106960008C846EE08CA200008CA30004AC8200003A -:10697000AC8300048CA20008AC82000894A2000E34 -:10698000A482000E8CA20010240B0001AC82001027 -:106990008CA200141000001224A500201040001842 -:1069A000312201003C0400018C846EE08CE2000086 -:1069B0008CE30004AC820000AC8300048CE200088D -:1069C000AC82000894E2000EA482000E8CE200105B -:1069D00024E50020AC8200108CE20014240B00019E -:1069E00000A01821AC820014276247E00043102B5E -:1069F000544000012763400000602821312201003B -:106A00005440001D3122100011A0000931A20800DD -:106A100010400004250200208F8200A8A5E200009B -:106A200025020020AF8201248F8801240000682104 -:106A300011800011312210003C0400018C846EE4AE -:106A40008C8200008C830004AF820080AF830084BE -:106A50008C820008AF8200A49482000EAF8200AC4A -:106A60008C82001000006021AF8200A08C8D00108D -:106A70008C8F00143122100014400022000000000E -:106A80001140000F31420800104000043C02000297 -:106A90008F8200B8A5C200003C020002014210240F -:106AA0001040000424E200208F8200B4AF8200D4A2 -:106AB00024E20020AF8201048F87010400005021EE -:106AC00011600010000000003C0400018C846EE0A6 -:106AD0008C8200008C830004AF820090AF8300940E -:106AE0008C820008AF8200B49482000EAF82009CBA -:106AF0008C82001000005821AF8200B08C8A0010F8 -:106B00008C8E00148F8200703C0310000043102410 -:106B10001040FF5C000000008F82005424420005FA -:106B2000AF8200788C040234108000160000182117 -:106B30003C020001005710218C4240E8244200052D -:106B40003C01000100370821AC2240E83C02000172 -:106B5000005710218C4240E80044102B14400009DB -:106B6000240200013C0300803C01000100370821A1 -:106B7000AC2040E83C010001003708211000000C67 -:106B8000A02240F03C02000100571021904240F04A -:106B9000144000063C0200803C0200010057102116 -:106BA000904240F1104000023C0200800062182533 -:106BB0008C04023010800013000000003C02000131 -:106BC000005710218C4240EC244200053C0100019A -:106BD00000370821AC2240EC3C0200010057102194 -:106BE0008C4240EC0044102B1440000600000000D2 -:106BF0003C01000100370821AC2040EC10000006E9 -:106C0000007818253C02000100571021904240F204 -:106C100054400001007818251060FF1A00000000A1 -:106C20008F4200001040000700000000AF80004CC1 -:106C30008F82004C1040FFFD000000001000000596 -:106C400000000000AF8000488F8200481040FFFD28 -:106C5000000000008F82006000431025AF820060BA -:106C60008F42000010400003000000001000FF05EC -:106C7000AF80004C1000FF03AF80004803E0000825 -:106C80000000000000000000000000003C020001C5 -:106C90008C426D2827BDFFE8AFBF001414400012DE -:106CA000AFB000103C10000126106F9002002021B0 -:106CB0000C002BA82405200026021FE03C01000147 -:106CC000AC226EEC3C010001AC226EE8AC0202503A -:106CD00024022000AC100254AC020258240200012D -:106CE0003C010001AC226D288FBF00148FB0001052 -:106CF00003E0000827BD00183C0900018D296EEC57 -:106D00008C8200008FA300108FA80014AD22000019 -:106D10008C820004AD250008AD2200048F8200544F -:106D2000AD260010AD270014AD230018AD28001CBF -:106D3000AD22000C2529FFE03C02000124426F90A7 -:106D40000122102B10400003000000003C0900014C -:106D50008D296EE83C0200018C426D10AD220000CE -:106D60003C0200018C426D103C010001AC296EEC2C -:106D7000AD220004AC09025003E00008000000004E -:106D800027BDFFD0AFB000103C1000018E106EEC9C -:106D90003C0200018C426D10AFB1001400808821CC -:106DA000AFBE00248FBE00408FA40048AFB20018D1 -:106DB00000A09021AFBF0028AFB50020AFB3001CEA -:106DC000AE0200003C0200018C426D1000C0982110 -:106DD00000E0A82110800006AE020004260500088D -:106DE0000C002BB324060018100000052610FFE04D -:106DF000260400080C002BA8240500182610FFE02C -:106E00003C03000124636F900203102B1040000329 -:106E1000000000003C1000018E106EE88E22000081 -:106E2000AE0200008E220004AE120008AE02000482 -:106E30008F820054AE130010AE150014AE1E001861 -:106E40008FA80044AE08001CAE02000C2610FFE024 -:106E50000203102B10400003000000003C10000152 -:106E60008E106EE83C0200018C426D10AE020000F4 -:106E70003C0200018C426D103C010001AC306EEC14 -:106E8000AE020004AC1002508FBF00288FBE002459 -:106E90008FB500208FB3001C8FB200188FB1001483 -:106EA0008FB0001003E0000827BD003000851821D6 -:106EB0000083102B1040000600000000AC80000092 -:106EC000248400040083102B5440FFFDAC8000009C -:106ED00003E000080000000000A6182100A3102B0A -:106EE00010400007000000008C820000ACA20000EF -:106EF00024A5000400A3102B1440FFFB24840004ED -:106F000003E0000800000000008618210083102B19 -:106F100010400007000000008CA20000AC820000BE -:106F2000248400040083102B1440FFFB24A50004DC -:106F300003E00008000000000006308000861821F1 -:106F40000083102B1040000600000000AC850000FC -:106F5000248400040083102B5440FFFDAC85000006 -:106F600003E00008000000000000000026E5002803 -:106F700000A03021274301C08F4D03588F47035C89 -:106F80008F4803608F4903648F4A03688F4B020464 -:106F90008F4C0200246404000064102B1040000891 -:106FA0003C0208FF8CC20000AC62000024630004B5 -:106FB0000064102B1440FFFB24C600043C0208FFB1 -:106FC0003442FFFF3C03C0FFAF4D0358AF47035CA3 -:106FD000AF480360AF490364AF4A0368AF4B020494 -:106FE000AF4C02008F8402203463FFFF8F860200C3 -:106FF000008210243442000400C3182434630004C7 -:10700000AF820220AF8302008CA20214AC02008483 -:107010008CA20218AC0200888CA2021CAC02008C6C -:107020008CA20220AC0200908CA20224AC0200943C -:107030008CA20228AC0200988CA2022CAC02009C0C -:107040008CA20230AC0200A08CA20234AC0200A4DC -:107050008CA20238AC0200A88CA2023CAC0200ACAC -:107060008CA20240AC0200B08CA20244AC0200B47C -:107070008CA20248AC0200B88CA2024CAC0200BC4C -:107080008CA2001CAC0200808CA20018AC0200C0D4 -:107090008CA20020AC0200CC8CA20024AC0200D058 -:1070A0008CA201D0AC0200E08CA201D4AC0200E4BE -:1070B0008CA201D8AC0200E88CA201DCAC0200EC8E -:1070C0008CA201E0AC0200F08CA200988CA3009C82 -:1070D000AC0300FC8CA200A88CA300ACAC0300F4B1 -:1070E0008CA200A08CA300A430840004AC0300F8A0 -:1070F0001480000730C200048F8202203C0308FF86 -:107100003463FFFB00431024AF82022030C200042E -:1071100014400006000000008F8202003C03C0FF04 -:107120003463FFFB00431024AF8202008F4202DC75 -:10713000A34005C524420001AF4202DC8F4202DCBD -:1071400003E000080000000027BDFFD8AFBF002407 -:10715000AFB000208F4300248F420020106200381F -:10716000000000008F4300208F4200240062202393 -:1071700004810003000000008F42004000822021B3 -:107180008F4300308F4200240043102B1440000531 -:10719000000000008F4300408F42002410000005D3 -:1071A000006210238F4200308F43002400431023DD -:1071B0002442FFFF00406021008C102A544000014F -:1071C000008060218F4A00248F4900408F480024AE -:1071D0008F4401808F4501848F4600248F4B001C13 -:1071E00024070001AFA7001000084100010018218A -:1071F000014C50212529FFFF01498024AFB0001424 -:107200008F4700140000102100063100AFA70018BE -:1072100000A3282100A3382B0082202100872021F1 -:107220008F420108016630210040F809000C390046 -:1072300054400001AF5000248F4300248F420020AF -:1072400014620018000000008F4200001040000788 -:1072500000000000AF80004C8F82004C1040FFFD0A -:10726000000000001000000500000000AF80004892 -:107270008F8200481040FFFD000000008F820060F8 -:107280002403FFEF00431024AF8200608F42000010 -:10729000104000030000000010000002AF80004C0E -:1072A000AF8000488FBF00248FB0002003E00008AB -:1072B00027BD002803E000080000000027BDFFC034 -:1072C00032C20020AFBF0038AFB30034AFB20030DD -:1072D000AFB1002C10400004AFB000288F5300283D -:1072E00010000002000000008F5300208F42003089 -:1072F000105300EB000211008F43001C006280213C -:107300008E0400008E050004961200088F42009043 -:107310009611000A3246FFFF0046102A104000175F -:10732000000000008F8200D88F4300980043102394 -:107330002442DCBEAF4200908F4200902842DCBF66 -:1073400010400005000000008F4200908F43014470 -:1073500000431021AF4200908F4200900046102A57 -:1073600010400006000000008F4203482442000144 -:10737000AF420348100000E18F4203488F8200FCB7 -:1073800014400006000000008F4203442442000124 -:10739000AF420344100000D98F420344934205C218 -:1073A0001040000B32C200081040000832220200D8 -:1073B000104000063C0340009602000EAF4300ACB4 -:1073C0000002140010000002AF4200B0AF4000AC59 -:1073D000322200041040007F3222080010400003D7 -:1073E0003247FFFF100000022402002024020004A4 -:1073F000AFA200108F420030AFA200148F420010E5 -:107400003C03000200431025AFA200188F460098ED -:107410008F4201080040F80900000000104000B74A -:10742000000000008F42009C8F4300940242102114 -:10743000AF42009CAE03000C8F4200AC104000082D -:107440003C0340008F42009400431025AFA200206F -:107450008F42009C8F4300B01000000400431025B1 -:107460008F420094AFA200208F42009CAFA2002464 -:107470008F8200FC8FA300208FA40024AC43000067 -:10748000AC44000424420008AF8200F08F42009C0C -:107490008F4402708F4502740040182100001021B3 -:1074A00000A3282100A3302B008220210086202168 -:1074B0003223006024020040AF440270AF450274E2 -:1074C000106200172C6200411040000524020020C9 -:1074D00010620008240200011000002600000000D5 -:1074E0002402006010620019240200011000002133 -:1074F000000000008F4202788F43027C2463000169 -:107500002C64000100441021AF420278AF43027C9A -:107510008F4202788F43027C100000162402000183 -:107520008F4202808F430284246300012C64000197 -:1075300000441021AF420280AF4302848F42028098 -:107540008F4302841000000B240200018F42028846 -:107550008F43028C246300012C640001004410213D -:10756000AF420288AF43028C8F4202888F43028C65 -:1075700024020001A34205C28F4200983244FFFF5B -:107580002406FFF88F45013C0044102124420007E7 -:107590000046102424840007AF4200948F420090DC -:1075A0008F43009400862024004410230065182B8C -:1075B00014600005AF4200908F4200948F43014455 -:1075C00000431023AF4200948F4200941000002328 -:1075D000AF40009C3247FFFF50E0002232C2002043 -:1075E000144000022402001024020002AFA2001086 -:1075F0008F420030AFA200148F420010AFA20018DB -:107600008F4600988F4201080040F80900000000F2 -:107610001040003A3245FFFF8F4200988F430090A0 -:107620008F46013C00451021AF4200988F42009CDC -:107630008F440098A34005C200651823AF43009013 -:10764000004510210086202B14800005AF42009CCD -:107650008F4200988F43014400431023AF420098AB -:1076600032C2002010400005000000008F42035885 -:107670002442FFFFAF4203588F4203588F4200302D -:107680008F430040244200012463FFFF0043102485 -:10769000AF4200308F420030145300180000000049 -:1076A0008F4200001040000700000000AF80004C37 -:1076B0008F82004C1040FFFD00000000100000050C -:1076C00000000000AF8000488F8200481040FFFD9E -:1076D000000000008F8200602403FFF700431024A5 -:1076E000AF8200608F4200001040000300000000E5 -:1076F00010000002AF80004CAF8000488FBF003800 -:107700008FB300348FB200308FB1002C8FB00028BF -:1077100003E0000827BD004003E00008000000006F -:1077200027BDFFD032C20020AFBF002CAFB200286F -:10773000AFB1002410400004AFB000208F520028E9 -:1077400010000002000000008F5200208F42003025 -:10775000105200B5000211008F43001C006280210E -:107760008E0400008E050004961100088F420090E0 -:107770009607000A3226FFFF0046102A1040001725 -:10778000000000008F8200D88F4300980043102330 -:107790002442DC46AF4200908F4200902842DC47F2 -:1077A00010400005000000008F4200908F4301440C -:1077B00000431021AF4200908F4200900046102AF3 -:1077C00010400006000000008F42034824420001E0 -:1077D000AF420348100000AB8F4203488F8600FC85 -:1077E00010C0000C000000008F8200F42403FFF89A -:1077F0000043102400461023000218C35860000103 -:10780000246301008F42008C0043102B14400006BB -:10781000000712C28F42034424420001AF420344D6 -:10782000100000988F420344934305C21060000F7C -:10783000304600018F4200103448040032C2000874 -:107840001040000830E20200104000063C034000F7 -:107850009602000EAF4300AC0002140010000004BA -:10786000AF4200B010000002AF4000AC8F480010E3 -:1078700030E20004104000453227FFFF8F4900AC82 -:107880001120000530C200FF144000062402004011 -:10789000100000042402000814400002240200200A -:1078A00024020004AFA200108F4300301120000416 -:1078B000AFA300148F4200B000621025AFA20014E5 -:1078C0003C02000201021025AFA200188F4600986A -:1078D0008F4201080040F8090000000010400069D4 -:1078E0003224FFFF8F42008C8F430094244200011A -:1078F000AF42008C24020001AE03000CA34205C27B -:107900008F4200982406FFF88F45013C0044102167 -:10791000244200070046102424840007AF4200944C -:107920008F4200908F43009400862024004410234F -:107930000065182B14600005AF4200908F42009440 -:107940008F43014400431023AF4200948F430094BF -:107950008F4201400043102B10400009000000003E -:107960008F43013C8F4400948F4200908F45013833 -:107970000064182300431023AF420090AF450094E9 -:107980008F4200941000001FAF42009810E0001DCD -:1079900030C200FF14400002240200102402000242 -:1079A000AFA200108F420030AFA80018AFA20014A1 -:1079B0008F4600988F4201080040F809000000003F -:1079C000104000303225FFFF8F4200988F44013C69 -:1079D00000451021AF4200988F4200908F430098DD -:1079E000A34005C2004510230064182B1460000555 -:1079F000AF4200908F4200988F4301440043102310 -:107A0000AF4200988F4200308F4300402442000173 -:107A10002463FFFF00431024AF4200308F42003048 -:107A200014520018000000008F42000010400007B0 -:107A300000000000AF80004C8F82004C1040FFFD22 -:107A4000000000001000000500000000AF800048AA -:107A50008F8200481040FFFD000000008F82006010 -:107A60002403FFF700431024AF8200608F42000020 -:107A7000104000030000000010000002AF80004C26 -:107A8000AF8000488FBF002C8FB200288FB1002438 -:107A90008FB0002003E0000827BD003003E000089D -:107AA0000000000027BDFFD83C02000134422EC078 -:107AB000AFBF00208F4300F08F84010802E2102145 -:107AC00054620004246200083C02000134422CC0CD -:107AD00002E2102100401821AF4300F0AC6000002A -:107AE0008F4200EC8C660004146200043C0200012A -:107AF000248200201000000FAF8201088F4300F0A5 -:107B000034422EC002E210215462000424620008B4 -:107B10003C02000134422CC002E210210040182136 -:107B20008C6200040002114000821021AF82010823 -:107B3000AC6000008C85001830A200361040006C4C -:107B400030A200018C82001C8F4300408F4400341F -:107B5000244200012463FFFF0043102400862021FB -:107B6000AF42002C30A2003014400006AF44003475 -:107B70008F4200348C03023C0043102B144000B4AD -:107B80000000000032C20010104000282407000846 -:107B90008F4401708F4501748F43002C8F48000C77 -:107BA0008F86012024020080AFA20010AFA3001432 -:107BB000AFA800188F42010C0040F80924C6001C31 -:107BC00014400011240200013C010001003708218B -:107BD000A02240F18F820124AFA200108F820128E1 -:107BE0003C040001248467C4AFA200148F46002C1B -:107BF0008F8701203C0500090C002B3B34A51100A8 -:107C000010000036000000008F4203008F43002C5C -:107C100024420001AF4203008F420300240200010E -:107C2000A34205C110000026AF4300388F44017005 -:107C30008F4501748F43002C8F48000C8F860120E4 -:107C400024020020AFA20010AFA30014AFA80018B8 -:107C50008F42010C0040F80924C6001C144000119A -:107C6000240200013C01000100370821A02240F05D -:107C70008F820124AFA200108F8201283C040001F2 -:107C8000248467B8AFA200148F46002C8F87012090 -:107C90003C0500090C002B3B34A509001000000F27 -:107CA000000000008F42030024420001AF420300A5 -:107CB0008F4203008F42002CA34005C1AF42003821 -:107CC0003C01000100370821A02040F13C010001E7 -:107CD00000370821A02040F0AF4000348F42031449 -:107CE00024420001AF420314100000598F420314D4 -:107CF0001040002230A270008C85001C8F420028AA -:107D000000A2202304810003000000008F420040F5 -:107D1000008220218F4203588F430000AF45002886 -:107D20000044102110600007AF420358AF80004CA0 -:107D30008F82004C1040FFFD000000001000000585 -:107D400000000000AF8000488F8200481040FFFD17 -:107D5000000000008F82006034420008AF820060A3 -:107D60008F420000104000030000000010000038A7 -:107D7000AF80004C10000036AF8000481040002F4C -:107D800030A210001040000C30A240008C83001C78 -:107D90008F420050006220230482000124840200EC -:107DA0008F42035C00441021AF42035C8F420368A2 -:107DB0001000001AAF4300501040000C32C2800087 -:107DC0008C83001C8F42007000622023048200011B -:107DD000248404008F42036400441021AF420364F2 -:107DE0008F4203681000000DAF4300701040000E7A -:107DF0003C0208008C83001C8F420060006220233C -:107E000004820001248401008F4203600044102199 -:107E1000AF4203608F420368AF430060004410210B -:107E2000AF4203683C02080002C210245040000820 -:107E300036940040100000060000000030A201004F -:107E400010400003000000000C002BD800000000D0 -:107E50008FBF002003E0000827BD002803E00008D2 -:107E60000000000027BDFFA8AFBF0050AFBE004C10 -:107E7000AFB50048AFB30044AFB20040AFB1003C73 -:107E8000AFB000388F91010826220020AF82010890 -:107E90008E3200180000A82132420024104001BA9E -:107EA0000000F0218E26001C8F43001C00061100EC -:107EB000006218218C70000C9604000C962D0016A0 -:107EC0009473000A2C8305DD388288702C420001EF -:107ED00000621825106000150000282132C2004001 -:107EE00010400015240208009603001414620012CA -:107EF0003402AAAA9603000E146200070000202193 -:107F00009603001024020300146200040080102174 -:107F1000960200122C4400010080102154400006FB -:107F200024050016100000040000000024020800D0 -:107F3000508200012405000E934205C3144000083E -:107F400000005821240B000132620180AF4500A8D7 -:107F5000AF5000A010400002AF4600A4A34B05C3E1 -:107F600010A0008502054021910200000000382188 -:107F70003042000F0002508032C200021040001256 -:107F8000010A1821326200021040001032C20001C2 -:107F900001002021948200002484000200E23821A4 -:107FA0000083102B1440FFFB30E2FFFF00071C0290 -:107FB0000062382100071C0230E2FFFF0062382116 -:107FC00000071027A502000A32C200011040006A13 -:107FD0003262000110400068000000008F4200A8DB -:107FE00010400065000000008F4200A08F4300A8F1 -:107FF00000431021904C0009318900FF392300060D -:108000000003182B392200110002102B00621824E3 -:108010001060000C3C0500068F4200A43C040001E7 -:10802000248467D4AFA200108F4200A034A546007C -:10803000012038210C002B3BAFA200141000004E91 -:108040000000000032C20004144000130000282188 -:10805000316200FF1440000400000000950200029D -:108060001000000D004A28239505000C9502000E13 -:108070009503001000A2282100A3282195030012D7 -:10808000910400099502000200A3282100A42821E0 -:10809000004A102300A2282102002021948200001F -:1080A0002484000200E238210088102B1440FFFBDA -:1080B00000071C0230E2FFFF0062382100071C02AB -:1080C00030E2FFFF0062382101A5282100051C02D3 -:1080D00030A2FFFF0062282100051C0230A2FFFF32 -:1080E0000062282100A728230005140200A22821ED -:1080F00030A5FFFF50A000013405FFFF316200FFF3 -:1081000014400008318300FF8F4300A08F4200A875 -:1081100000624021910200003042000F00025080B6 -:10812000318300FF2402000614620003010A1021BB -:10813000100000022444001024440006316200FFB5 -:1081400014400006000000009482000000A22821D4 -:1081500000051C0230A2FFFF00622821934205C3E4 -:10816000104000033262010050400003A48500006B -:1081700000052827A48500009622000E8F43009C4E -:108180000062182132A200FF10400007AF43009C9C -:108190003C02400002021025AFA200208F42009C4A -:1081A00010000003005E1025AFB000208F42009C3D -:1081B000AFA2002432620080104000103262010041 -:1081C0008F4200B424430001000210C00057102168 -:1081D000AF4300B48FA300208FA400243C01000112 -:1081E00000220821AC2338E83C01000100220821CC -:1081F000AC2438EC100000A532C20020104000640E -:10820000000000008F4200B424430001000210C0AF -:1082100000571021AF4300B48FA300208FA4002487 -:108220003C01000100220821AC2338E83C01000198 -:1082300000220821AC2438EC8F4200B410400051D9 -:10824000000038213C090001352938E83C08001FAE -:108250003508FFFF240BFFFF340AFFFF000710C0A3 -:1082600000571021004910218C4300008C44000469 -:10827000AFA30028AFA4002C8F8200FC8FA300289E -:108280008FA4002CAC430000AC440004244200083E -:10829000AF8200F08F42008C2442FFFFAF42008C7F -:1082A00097A2002E8F4402708F450274004018215F -:1082B0000000102100A3282100A3302B00822021E0 -:1082C00000862021AF440270AF4502748FA20028BF -:1082D0000048102490430000306300011460000B3C -:1082E000004020218F4202788F43027C24630001EA -:1082F0002C64000100441021AF420278AF43027C9D -:108300008F4202781000001A8F43027C8C8200009A -:10831000144B000E0000000094820004144A000B6D -:10832000000000008F4202888F43028C246300010A -:108330002C64000100441021AF420288AF43028C3C -:108340008F4202881000000A8F43028C8F42028005 -:108350008F430284246300012C6400010044102137 -:10836000AF420280AF4302848F4202808F43028477 -:108370008F4200B424E7000100E2102B1440FFB844 -:10838000000710C0A34005C31000003FAF4000B479 -:108390008F8200FC8FA300208FA40024AC43000038 -:1083A000AC44000424420008AF8200F08F42009CDD -:1083B0008F46008C8F4402708F4502740040182154 -:1083C0000000102124C6FFFFAF46008C00A3282127 -:1083D00000A3302B0082202100862021AF440270B0 -:1083E000AF45027492020000304200011440000CBC -:1083F0002402FFFF8F4202788F43027C2463000136 -:108400002C64000100441021AF420278AF43027C8B -:108410008F4202788F43027C1000001C32C2002081 -:108420008E0300001462000F3402FFFF9603000465 -:108430001462000C000000008F4202888F43028CFF -:10844000246300012C64000100441021AF42028823 -:10845000AF43028C8F4202888F43028C1000000BC6 -:1084600032C200208F4202808F43028424630001C5 -:108470002C64000100441021AF420280AF4302840B -:108480008F4202808F43028432C2002010400005D8 -:10849000AF40009C8F4203582442FFFFAF42035875 -:1084A0008F4203588E22001C8F430040244200015B -:1084B0002463FFFF00431024AF42002C32420060CF -:1084C0001440000832C200108F42003424420001E0 -:1084D000AF4200348C03023C0043102B14400102D5 -:1084E00032C2001010400018240700088F440170A9 -:1084F0008F4501748F43002C8F48000C8F8601201C -:1085000024020080AFA20010AFA30014AFA800188F -:108510008F42010C0040F80924C6001C104000479F -:10852000240200018F4203008F43002C24420001EB -:10853000AF4203008F42030024020001A34205C1A1 -:108540001000007CAF4300388F4401708F450174E8 -:108550008F43002C8F48000C8F86012024020020BE -:10856000AFA20010AFA30014AFA800188F42010CF7 -:108570000040F80924C6001C1040005724020001E6 -:10858000100000650000000032420012104000752B -:10859000324200019622000E8F43009C0062182197 -:1085A00032C2002010400005AF43009C8F420358A8 -:1085B0002442FFFFAF4203588F4203588E22001C13 -:1085C0008F430040244200012463FFFF0043102436 -:1085D000AF42002C324200101440000832C200109A -:1085E0008F42003424420001AF4200348C03023C2D -:1085F0000043102B144000BC32C200101040002871 -:10860000240700088F4401708F4501748F43002CAC -:108610008F48000C8F86012024020080AFA200103A -:10862000AFA30014AFA800188F42010C0040F80956 -:1086300024C6001C14400011240200013C0100016A -:1086400000370821A02240F18F820124AFA2001040 -:108650008F8201283C040001248467C4AFA2001467 -:108660008F46002C8F8701203C0500090C002B3B16 -:1086700034A5110010000036000000008F420300F6 -:108680008F43002C24420001AF4203008F420300BD -:1086900024020001A34205C110000026AF430038A8 -:1086A0008F4401708F4501748F43002C8F48000C5C -:1086B0008F86012024020020AFA20010AFA3001477 -:1086C000AFA800188F42010C0040F80924C6001C16 -:1086D00014400011240200013C0100010037082170 -:1086E000A02240F08F820124AFA200108F820128C7 -:1086F0003C040001248467B8AFA200148F46002C0C -:108700008F8701203C0500090C002B3B34A5090094 -:108710001000000F000000008F42030024420001FF -:10872000AF4203008F4203008F42002CA34005C1DB -:10873000AF4200383C01000100370821A02040F181 -:108740003C01000100370821A02040F0AF40003478 -:108750008F42031424420001AF4203141000006250 -:108760008F42031410400022324270008E25001CFC -:108770008F42002800A22023048100030000000093 -:108780008F420040008220218F4203588F43000017 -:10879000AF4500280044102110600007AF42035885 -:1087A000AF80004C8F82004C1040FFFD00000000A5 -:1087B0001000000500000000AF8000488F820048D4 -:1087C0001040FFFD000000008F820060344200086E -:1087D000AF8200608F4200001040000300000000E4 -:1087E00010000041AF80004C1000003FAF800048F7 -:1087F0001040002F324210001040000C3242400066 -:108800008E23001C8F42005000622023048200014E -:10881000248402008F42035C00441021AF42035CB9 -:108820008F4203681000001AAF4300501040000C44 -:1088300032C280008E23001C8F4200700062202311 -:1088400004820001248404008F4203640044102148 -:10885000AF4203648F4203681000000DAF43007005 -:108860001040000E3C0208008E23001C8F42006066 -:108870000062202304820001248401008F420360EF -:1088800000441021AF4203608F420368AF43006091 -:1088900000441021AF4203683C02080002C21024C9 -:1088A00050400011369400401000000F00000000FE -:1088B0003242004810400007241500018E22001C9F -:1088C0003C03FFFF0043F0243042FFFF1000FD7522 -:1088D000AE22001C324201001040000300000000E4 -:1088E0000C002BD8000000008FBF00508FBE004C42 -:1088F0008FB500488FB300448FB200408FB1003C69 -:108900008FB0003803E0000827BD005803E00008DE -:108910000000000000000000000000008F8300E461 -:108920008F8200E02404FFF8004410240062102627 -:108930000002102B0002102303E000080062102444 -:1089400003E000080000000027BDFFE0AFBF001CEF -:10895000AFB000188F8600C48F8400E08F8500E4DC -:108960002402FFF80082182410A3000927623FF8B0 -:1089700014A2000224A200082762300000408021D7 -:1089800016030005308200041040000400C02021BE -:1089900010000022000010218E0400008F42011CF4 -:1089A00014A20003000000008F420120AF42011416 -:1089B0008CA300008F420148008318230043102B32 -:1089C00010400003000000008F420148006218219F -:1089D00094A20006244200500062102B1440000FA5 -:1089E00000A01021AFA40010AFA300148CA60000BB -:1089F0008CA700043C0400010C002B3B24846894E9 -:108A00008F42020C24420001AF42020C8F42020C42 -:108A100000001021AF9000E8AF9000E48FBF001C71 -:108A20008FB0001803E0000827BD002003E0000815 -:108A3000000000008F8400E08F8800C48F8300E86E -:108A40002402FFF80082382400E320232C82100047 -:108A50005040000124841000000420C2008018212E -:108A60008F4402588F45025C0000102100A328218A -:108A700000A3302B0082202100862021AF44025821 -:108A8000AF45025C8F8300C88F4201480103202359 -:108A90000082102B14400004008018218F420148EE -:108AA00000822021008018218F4402508F450254FB -:108AB0000000102100A3282100A3302B00822021D8 -:108AC00000862021AF440250AF450254AF8800C851 -:108AD000AF8700E4AF8700E803E000080000000073 -:108AE00027BDFF30240A0001AFBF00C8AFBE00C4DD -:108AF000AFB500C0AFB300BCAFB200B8AFB100B407 -:108B0000AFB000B0A3A00097AFA00044AFAA005C34 -:108B1000934205C4A7A0008E1040000AA7A00086BB -:108B20008F4B00C4AFAB00648F4A00C0AFAA006C8B -:108B30008F4B00CCAFAB00748F4A00C810000129E6 -:108B4000AFAA007C8F4201140040F8090000000029 -:108B50000040302110C0034F000000008CC2000014 -:108B60008CC30004AFA20020AFA300248FAB00246D -:108B70008FAA00203162FFFF2442FFFCAFA2006CED -:108B80003C02000602C21024AFAB007C144000156A -:108B9000AFAA006491420000304200011040001171 -:108BA0002402FFFF8D430000146200043402FFFF23 -:108BB000954300041062000B000000000C0024BB71 -:108BC0008FA40064304200FF144000060000000043 -:108BD0008F4201180040F809000000001000032D2A -:108BE000000000008FA200243C03FFBF3463FFFF9E -:108BF000004310243C03FFFF0043182414600003CB -:108C0000AFA2002410000040000018213C020080A8 -:108C10000062102410400007000000008F42038C07 -:108C200024420001AF42038C8F42038C10000036B7 -:108C3000240300018F42021024420001AF420210BF -:108C40008F4202103C020001006210241040000616 -:108C50003C0200028F4201C424420001AF4201C421 -:108C60008F4201C43C020002006210241040000642 -:108C70003C0200048F42037C24420001AF42037C8B -:108C80008F42037C3C020004006210241040000666 -:108C90003C0200088F42038024420001AF4203805F -:108CA0008F4203803C02000800621024104000063E -:108CB0003C0200108F42038424420001AF4203842F -:108CC0008F4203843C020010006210241040000612 -:108CD0003C0200208F4201C024420001AF4201C08B -:108CE0008F4201C03C0200200062102410400006A8 -:108CF000240300018F42038824420001AF4203880D -:108D00008F420388240300018C0202608FAB006C49 -:108D1000004B102B10400014307000FF8F4201E810 -:108D200024420001AF4201E88F4201E88FAA007C93 -:108D30008F8200E0354A0100AFAA007CAFA200108C -:108D40008F8200E4241000013C040001248468A008 -:108D5000AFA200148FA600208FA700243C050007B7 -:108D60000C002B3B34A50800120000103C020080D0 -:108D700002C210241440000E32C204008FAB007CEB -:108D80003C020080344201000162102410400005C2 -:108D9000000000008F42020C24420001AF42020C8E -:108DA0008F42020C100002B08FA3006C32C204008C -:108DB00010400015340281008FAA00649543000C16 -:108DC000146200123C020100240B0200A7AB008ECB -:108DD0009542000E8D4300088D4400048D4500002F -:108DE0008FAA006C8FAB0064254AFFFCAFAA006C11 -:108DF000A7A20086AD63000CAD640008AD65000459 -:108E0000256B0004AFAB00643C02010002C21024D9 -:108E100010400004000000008FAA006C254A0004E6 -:108E2000AFAA006C8F4200BC5040000AAFA0007493 -:108E30008FAB006C004B102B50400006AFA00074AD -:108E40008F4200BC01621023AFA200748F4A00BCA5 -:108E5000AFAA006C8F4200808FAB006C004B102BD0 -:108E60001040005632C280001040005E240A000309 -:108E700032C210001040005BAFAA005C1000005826 -:108E8000240B00048F4203502403FFBF0283A0245D -:108E900024420001AF4203501000024F8F420350A2 -:108EA00002C2B0252402FFBF0282A0248F830128C2 -:108EB0003C040001248468D026620001AFA20014A3 -:108EC000AFA300108F8601208F8701243C05000787 -:108ED0000C002B3B34A522501000023F0000000084 -:108EE00002C2B0252402FFBF0282A0248F83012882 -:108EF0003C040001248468D024020002AFA20014C4 -:108F0000AFA300108F8601208F8701243C05000746 -:108F10000C002B3B34A524501000022F0000000051 -:108F20008EA200008EA300043C040001248468E8A3 -:108F3000AFB00010AFBE00148EA7001834A52800F3 -:108F40000C002B3B006030211000022300000000C9 -:108F5000A6B1000A8F8201243C040001248468F039 -:108F6000AFBE0014AFA200108F4600448F870120CF -:108F70003C0500070C002B3B34A530001000021606 -:108F800000000000A6B1000AA6B2000E8F820124E4 -:108F90003C040001248468FCAFBE0014AFA20010A2 -:108FA0008F4600448F8701203C0500070C002B3BB7 -:108FB00034A5320010000208000000008F42008437 -:108FC0008FAA006C004A102B144000073C020001DD -:108FD00002C210241040000400000000240B000214 -:108FE000AFAB005C8FAA006C1140021B27AB0020C6 -:108FF000AFAB00A43C0A001F354AFFFFAFAA009C9C -:109000008FAB005C240A0001556A0021240A00028B -:109010008F4300548F4200501062000B274B0054C6 -:109020008F5E00543403ECC0AFAB004C27C200018C -:10903000304201FFAFA20054001E11400043102136 -:109040001000006B02E2A8218F4200448FAA006C3E -:109050003C040001248468ACAFAA0014AFA2001045 -:109060008F4600548F4700503C0500070C002B3BF7 -:1090700034A513008F4303502402FFBF0282A024B3 -:1090800024630001AF430350100001D38F4203500B -:10909000156A001D000000008F4300748F420070AD -:1090A0001062000A274B00748F5E0074AFAB004C57 -:1090B00027C20001304203FFAFA20054001E11403E -:1090C00024426CC01000004A02E2A8218F420044F2 -:1090D0008FAA006C3C040001248468B83C0500079A -:1090E000AFAA0014AFA200108F4600748F47007023 -:1090F00034A51500240B00010C002B3BAFAB005C2A -:109100001000FFC3000000008F4300648F42006026 -:109110001062001A274A00648F5E00648FAB005C07 -:10912000AFAA004C27C20001304200FFAFA200549A -:10913000240200041562000E001E1140001E118062 -:1091400024420CC002E21021AFA200449442002A43 -:109150008FAA00448FAB006C004B102B10400024F2 -:1091600025550020240A000110000021A3AA009721 -:1091700024424CC01000001E02E2A8218F4200448D -:109180008FAB006C3C040001248468C4AFAB0014B6 -:10919000AFA200108F4600648F4700603C050007B7 -:1091A0000C002B3B34A518003C02000802C210241E -:1091B0001440FF34000000008F420370240A0001B5 -:1091C000AFAA005C24420001AF4203701000FF9080 -:1091D0008F42037027A3003600131040006218214D -:1091E000946200000044102110000020A4620000DE -:1091F0008FAB0064AEAB001893A2009710400072D2 -:10920000000098218FAA00448FA4006C8FA300A4B3 -:1092100025420020AFA2002825420008AFA200305E -:1092200025420010AFAA002CAFA200349542002ABC -:10923000A7A2003895420018A7A2003A9542001A4A -:10924000A7A2003C9542001CA7A2003E9462001811 -:1092500024630002008220231880FFDE26730001B1 -:109260002E6200041440FFF9000000008F4200FC51 -:109270002665000100A2102A1440002B24030001DF -:109280008F83012C10600023000000008F820124D6 -:109290000043102300022143588000012484004031 -:1092A0008F820128004310230002194358600001F7 -:1092B000246300400064102A544000010060202113 -:1092C000AF4400FC8F4200FC00A2102A10400011A5 -:1092D0002403000110000015306200FF8FAB006412 -:1092E00096070018AFAB00108E2200083C04000166 -:1092F000248468DC8C4300048C42000034A52400E4 -:10930000024030210C002B3BAFA300141000002BB7 -:10931000000000008F4203340000182124420001A5 -:10932000AF4203348F420334306200FF5040FEDC12 -:109330003C02080012600021000090218FB100A4BF -:10934000022080218E220008960700188FA6006454 -:109350008C4400008C450004240A0001AFAA0010D0 -:10936000AFBE00148F420008AFA200188F42010C5C -:109370000040F809000000001040FFD83C0500073D -:10938000960200188FAB00648FAA009C01625821DE -:10939000014B102B10400004AFAB00648F4201481A -:1093A00001625823AFAB0064261000022652000170 -:1093B0000253102B1440FFE3263100048FB0006CE1 -:1093C0001000003697B100388F4200FC24050002DF -:1093D00000A2102A1440001B240300018F83012CDB -:1093E00010600013000000008F820124004310234E -:1093F0000002214358800001248400408F8201280C -:109400000043102300021943586000012463004008 -:109410000064102A5440000100602021AF4400FC89 -:109420008F4200FC00A2102A144000062403000111 -:109430008F4203340000182124420001AF4203345C -:109440008F420334306200FF1040FEA53C0208004A -:1094500096B1000A8FB0006C3223FFFF0070102B12 -:1094600054400001006080218EA400008EA50004FD -:10947000240B0001AFAB0010AFBE00148F420008F8 -:109480008FA60064AFA200188F42010C0040F809BB -:10949000020038211040FEA23C05000796A3000EF2 -:1094A00097AA008E1140000700609021934205C4E6 -:1094B000144000040000000097AB0086006A1825E5 -:1094C000A6AB00168FAA007C3C02FFFF01421024CD -:1094D00010400003000A140234630400A6A2001422 -:1094E0008FAB006C560B0072A6A3000E3462000412 -:1094F000A6A2000E8FAA0074016A1021A6A2000A7B -:109500008F4300448F4401A08F4501A434028000A2 -:10951000AFA200108F42004402A030212407002097 -:10952000AFA200148F42000C0003194000604821D4 -:10953000AFA200188F42010C0000402100A9282191 -:1095400000A9182B008820210040F8090083202161 -:109550005040FE7FA6B2000E8F420368AFA0006CA1 -:10956000A34005C42442FFFFAF4203688FAB005CF9 -:10957000240A00018F420368156A0006240A0002CB -:109580008F42035C2442FFFFAF42035C1000000CDB -:109590008F42035C156A0006000000008F420364DE -:1095A0002442FFFFAF420364100000058F420364B2 -:1095B0008F4203602442FFFFAF4203608F4203608B -:1095C0008FAA00548FAB004CAD6A00008F4200445C -:1095D0008F4400888F430078244200010044102407 -:1095E00024630001AF420044AF4300788C02024084 -:1095F0000062182B14600075240700088F4401686E -:109600008F45016C8F4300448F48000C8F860120EA -:1096100024020040AFA20010AFA30014AFA80018AE -:109620008F42010C0040F80924C6001C14400011B0 -:10963000240B00013C01000100370821A02B40F25F -:109640008F820124AFA200108F8201283C04000108 -:109650002484688CAFA200148F4600448F870120B9 -:109660003C0500090C002B3B34A513001000000B37 -:10967000000000008F42030424420001AF420304B3 -:109680008F4203048F420044AF42007C3C01000142 -:1096900000370821A02040F2AF4000788F42031825 -:1096A00024420001AF420318100000488F42031803 -:1096B000A6B0000A8F4300448F4401A08F4501A447 -:1096C00034028000AFA200108F42004402A030217B -:1096D00024070020AFA200148F42000C00031940A1 -:1096E00000604821AFA200188F42010C0000402109 -:1096F00000A9282100A9182B008820210040F80982 -:10970000008320211040FE1F240A0001A34A05C443 -:109710008FAB006C8FAA006401705823AFAB006C54 -:109720008FAB009C01505021016A102B10400004A7 -:10973000AFAA00648F42014801425023AFAA0064DF -:109740008F4203682442FFFFAF4203688FAA005C88 -:10975000240B00018F420368154B0006240B000206 -:109760008F42035C2442FFFFAF42035C1000000CF9 -:109770008F42035C114B0006000000008F42036023 -:109780002442FFFFAF420360100000058F420360D8 -:109790008F4203642442FFFFAF4203648F4203649D -:1097A0008FAB00548FAA004CAD4B00008F42004499 -:1097B0008F4400888F430078244200010044102425 -:1097C00024630001AF420044AF4300788FAA006CCD -:1097D0001540FE0B000000008FAB006C1160001EF6 -:1097E00000000000934205C4104000090000000082 -:1097F0008FAA0064AF4A00C4AF4B00C08FAB007C9F -:10980000AF4B00C88FAA00741000000EAF4A00CC06 -:1098100097AB008E1160000B340381008FA20020F3 -:109820008C46000CA443000C97AA00868C440004CC -:109830008C450008A44A000EAC440000AC4500046E -:10984000AC4600088F42034C24420001AF42034C57 -:10985000100000108F42034C8FAB007C3164FFFF7F -:109860002484FFFC008018218F4402508F4502544D -:109870008F4601180000102100A3282100A3382BD7 -:109880000082202100872021AF44025000C0F80947 -:10989000AF4502548FBF00C88FBE00C48FB500C053 -:1098A0008FB300BC8FB200B88FB100B48FB000B0DE -:1098B00003E0000827BD00D003E00008000000001E -:1098C00027BDFF38240B0001AFBF00C0AFBE00BCF6 -:1098D000AFB500B8AFB300B4AFB200B0AFB100AC39 -:1098E000AFB000A8A3A00087AFA00044AFAB005C5E -:1098F000934205C4A7A0007610400007A7A0007EF1 -:109900008F4C00C0AFAC00648F4B00C88F5E00C4AA -:1099100010000130AFAB006C8F4201140040F80919 -:10992000000000000040302110C002A10000000033 -:109930008CC200008CC30004AFA20020AFA300249F -:109940008FAC00248FBE00203182FFFF2442FFFC39 -:10995000AFA200643C02000602C2102414400015AD -:10996000AFAC006C93C20000304200011040001107 -:109970002402FFFF8FC30000146200043402FFFFC3 -:1099800097C300041062000B000000000C0024BB11 -:1099900003C02021304200FF1440000600000000F8 -:1099A0008F4201180040F8090000000010000280FA -:1099B000000000008FA200243C03FFBF3463FFFFC0 -:1099C000004310243C03FFFF0043182414600003ED -:1099D000AFA2002410000040000080213C02008063 -:1099E0000062102410400007000000008F42038C2A -:1099F00024420001AF42038C8F42038C10000036DA -:109A0000241000018F42021024420001AF420210D4 -:109A10008F4202103C020001006210241040000638 -:109A20003C0200028F4201C424420001AF4201C443 -:109A30008F4201C43C020002006210241040000664 -:109A40003C0200048F42037C24420001AF42037CAD -:109A50008F42037C3C020004006210241040000688 -:109A60003C0200088F42038024420001AF42038081 -:109A70008F4203803C020008006210241040000660 -:109A80003C0200108F42038424420001AF42038451 -:109A90008F4203843C020010006210241040000634 -:109AA0003C0200208F4201C024420001AF4201C0AD -:109AB0008F4201C03C0200200062102410400006CA -:109AC000241000018F42038824420001AF42038822 -:109AD0008F420388241000018C0202608FAB006467 -:109AE000004B102B10400015320200FF8F4201E89E -:109AF00024420001AF4201E88F4201E88FAC006CC4 -:109B00008F8200E0358C0100AFAC006CAFA200107A -:109B10008F8200E4241000013C040001248468A02A -:109B2000AFA200148FA600208FA700243C050007D9 -:109B30000C002B3B34A53600320200FF1040001011 -:109B40003C02008002C210241440000E32C2040005 -:109B50008FAB006C3C020080344201000162102493 -:109B600010400005000000008F42020C244200015A -:109B7000AF42020C8F42020C100002028FA300645D -:109B800032C20400104000123402810097C3000C5E -:109B90001462000F00000000240C0200A7AC007645 -:109BA00097C2000E8FC300088FC400048FAB0064FF -:109BB0008FC50000256BFFFCAFAB0064A7A2007E41 -:109BC000AFC3000CAFC40008AFC5000427DE00041B -:109BD0008FA70064320200FF144000343C020100F1 -:109BE00097C4000C2C8305DD388288702C4200015C -:109BF00000621825106000150000282132C20800FC -:109C0000104000152402080097C3001414620012CB -:109C10003402AAAA97C3000E146200070000202194 -:109C200097C3001024020300146200040080102176 -:109C300097C200122C4400010080102154400006FD -:109C40002405001610000004000000002402080093 -:109C5000508200012405000E10A0001303C520212E -:109C6000248300093C02001F3442FFFF0043102BF5 -:109C700010400003000000008F42014800621823DA -:109C800090620000384300062C6300013842001146 -:109C90002C42000100621825106000043C02010003 -:109CA00094820002004538213C02010002C21024C7 -:109CB0005040000EAFA700648FAC006410EC0008A9 -:109CC0003C0500073C040001248469088FA6006459 -:109CD00034A54000AFA000100C002B3BAFA0001437 -:109CE0008FAB0064256B0004AFAB00648F42008033 -:109CF0008FAC0064004C102B1040002C32C280004E -:109D000010400034240B000332C210001040003118 -:109D1000AFAB005C1000002E240C00048F420350F7 -:109D20002403FFBF0283A02424420001AF4203505A -:109D3000100001738F4203503C02080002C2B0259C -:109D40002402FFBF0282A0248F8301283C0400016B -:109D5000248468D026620001AFA20014AFA30010D3 -:109D60008F8601208F8701243C0500070C002B3BC8 -:109D700034A5530010000162000000008EA2000014 -:109D80008EA300043C040001248468E8AFB00010F6 -:109D9000AFB100148EA7001834A559000C002B3B5E -:109DA0000060302110000156000000008F42008446 -:109DB0008FAB0064004B102B144000073C020001E5 -:109DC00002C210241040000400000000240C000215 -:109DD000AFAC005C8FAB00641160016627AC002063 -:109DE000AFAC008C8FAB005C240C0001556C0021E3 -:109DF000240C00028F4300548F4200501062000B6D -:109E0000274B00548F5100543403ECC0AFAB004CCF -:109E100026220001304201FFAFA200540011114080 -:109E2000004310211000006B02E2A8218F42004481 -:109E30008FAC00643C040001248468ACAFAC001417 -:109E4000AFA200108F4600548F4700503C0500071A -:109E50000C002B3B34A543008F4303502402FFBF6B -:109E60000282A02424630001AF43035010000124A8 -:109E70008F420350156C001D000000008F430074DA -:109E80008F4200701062000A274B00748F510074DB -:109E9000AFAB004C26220001304203FFAFA20054BA -:109EA0000011114024426CC01000004A02E2A821B7 -:109EB0008F4200448FAC00643C040001248468B8E5 -:109EC0003C050007AFAC0014AFA200108F46007431 -:109ED0008F47007034A54500240B00010C002B3B7C -:109EE000AFAB005C1000FFC3000000008F430064B4 -:109EF0008F4200601062001A274C00648F5100648A -:109F00008FAB005CAFAC004C26220001304200FF5A -:109F1000AFA20054240200041562000E001111408B -:109F20000011118024420CC002E21021AFA20044B3 -:109F30009442002A8FAC00448FAB0064004B102B7E -:109F40001040002425950020240C00011000002161 -:109F5000A3AC008724424CC01000001E02E2A821DE -:109F60008F4200448FAB00643C040001248468C429 -:109F7000AFAB0014AFA200108F4600648F470060A3 -:109F80003C0500070C002B3B34A548003C020008B0 -:109F900002C210241440FF61000000008F420370D1 -:109FA000240C0001AFAC005C24420001AF420370FE -:109FB0001000FF908F42037027A30036001310405B -:109FC0000062182194620000004410211000001F5C -:109FD000A4620000AEBE001893A200871040008467 -:109FE000000098218FAB00448FA400648FA3008CE5 -:109FF00025620020AFA2002825620008AFA2003031 -:10A0000025620010AFAB002CAFA200349562002A8D -:10A01000A7A2003895620018A7A2003A9562001A1C -:10A02000A7A2003C9562001CA7A2003E9462001803 -:10A0300024630002008220231880FFDF26730001C2 -:10A040002E6200041440FFF9000000008F4200FC63 -:10A050000262102A14400030240300018F83012C77 -:10A0600010600028000000008F82012400431023AC -:10A070000002214358800001248400408F8201287F -:10A08000004310230002194358600001246300407C -:10A090000064102A5440000100602021AF4400FCFD -:10A0A0008F4200FC0262102A1040001624030001B7 -:10A0B0001000001A306200FF8FAC008C00101040BE -:10A0C000004C10219447001800101080004C102103 -:10A0D000AFBE00108C4200083C040001248468DC00 -:10A0E0003C0500078C4300048C42000034A5550059 -:10A0F000020030210C002B3BAFA3001410000039EC -:10A10000000000008F4203340000182124420001A7 -:10A11000AF4203348F420334306200FF1040FF0629 -:10A12000000080218F4300082402FBFF1260002DF5 -:10A13000006250243C0B4000022B40258FB1008C64 -:10A140002669FFFF022090218E4200089627001802 -:10A150008C4400008C45000456090004240B0001C7 -:10A16000240C000210000002AFAC0010AFAB0010D6 -:10A1700016000004AFA800148F420008100000026F -:10A18000AFA20018AFAA00188F42010C03C0302103 -:10A19000AFA80098AFA9009C0040F809AFAA00A0A2 -:10A1A0008FA800988FA9009C8FAA00A01040FFC222 -:10A1B0003C02001F962300183442FFFF03C3F02126 -:10A1C000005E102B10400003263100028F42014830 -:10A1D00003C2F023261000010213102B1440FFDAF3 -:10A1E000265200048FB000641000001A0000000026 -:10A1F00096A3000A8FB000640070102B5440000139 -:10A20000006080218EA400008EA500048FAB005C4E -:10A21000240C0002AFAC0010934305C4000B1700E0 -:10A2200010600003022230253C02080000C23025E5 -:10A23000AFA600148F420008AFA200188F42010C95 -:10A2400003C030210040F809020038211040FECB45 -:10A250003C05000797AC00761180000796A3000E1E -:10A26000934205C4144000040000000097AB007E38 -:10A27000006C1825A6AB00168FAC006C3C02FFFFEB -:10A280000182102410400003000C14023463040007 -:10A29000A6A20014A6B0000A8FAB0064560B0006FD -:10A2A00003D0F02134620004AFA00064A6A2000E27 -:10A2B0001000000DA34005C48FAC00643C02001FD9 -:10A2C0003442FFFF005E102B01906023AFAC0064AE -:10A2D000A6A3000E240B000110400003A34B05C4ED -:10A2E0008F42014803C2F0238FAB00548FAC004C67 -:10A2F000AD8B00008FAC00641580FEBA000000003A -:10A300008FAB00641160001B00000000934205C485 -:10A310001040000600000000AF5E00C4AF4B00C05C -:10A320008FAC006C1000000EAF4C00C897AB0076ED -:10A330001160000B340381008FA200208C46000CBA -:10A34000A443000C97AC007E8C4400048C450008AC -:10A35000A44C000EAC440000AC450004AC46000820 -:10A360008F42034C24420001AF42034C1000001006 -:10A370008F42034C8FAB006C3164FFFF2484FFFCE1 -:10A38000008018218F4402508F4502548F460118D7 -:10A390000000102100A3282100A3382B00822021D7 -:10A3A00000872021AF44025000C0F809AF45025495 -:10A3B0008FBF00C08FBE00BC8FB500B88FB300B494 -:10A3C0008FB200B08FB100AC8FB000A803E00008DE -:10A3D00027BD00C803E000080000000027BDFFD82B -:10A3E000AFBF0024AFB000208F43004C8F42004825 -:10A3F00010620034000000008F4300488F42004C80 -:10A400000062202304820001248402008F43005450 -:10A410008F42004C0043102B144000042402020021 -:10A420008F43004C10000005004310238F4200545E -:10A430008F43004C004310232442FFFF0040502173 -:10A44000008A102A54400001008050218F49004C9E -:10A450008F48004C8F4401888F45018C8F46004CFB -:10A4600024071000AFA70010000841400100182188 -:10A47000012A4821313001FFAFB000148F4700148A -:10A480000000102100063140AFA7001800A32821CA -:10A4900000A3382B00822021008720213402ECC049 -:10A4A00000C230218F42010802E630210040F80945 -:10A4B000000A394054400001AF50004C8F43004C1B -:10A4C0008F42004814620018000000008F42000014 -:10A4D0001040000700000000AF80004C8F82004C4D -:10A4E0001040FFFD0000000010000005000000000B -:10A4F000AF8000488F8200481040FFFD0000000040 -:10A500008F8200602403FDFF00431024AF820060AF -:10A510008F42000010400003000000001000000205 -:10A52000AF80004CAF8000488FBF00248FB0002068 -:10A5300003E0000827BD002803E000080000000039 -:10A5400027BDFFD8AFBF0024AFB000208F43005C11 -:10A550008F42005810620049000000008F430058ED -:10A560008F42005C006220230482000124840100E9 -:10A570008F4300648F42005C0043102B14400004A2 -:10A58000240201008F43005C1000000500431023EB -:10A590008F4200648F43005C004310232442FFFF7E -:10A5A000004038210087102A5440000100803821E3 -:10A5B0008F42005C00471021305000FF32C2100073 -:10A5C00010400015240820008F49005C8F44019042 -:10A5D0008F4501948F46005C00073980AFA80010BA -:10A5E000AFB000148F4800140009498001201821E1 -:10A5F0000000102100A3282100A3482B0082202165 -:10A600000089202100063180AFA800188F42010880 -:10A610001000001424C60CC08F49005C8F440190C8 -:10A620008F4501948F46005C00073940AFA80010A9 -:10A63000AFB000148F4800140009494001201821D0 -:10A640000000102100A3282100A3482B0082202114 -:10A650000089202100063140AFA800188F42010870 -:10A6600024C64CC00040F80902E6302154400001E5 -:10A67000AF50005C8F43005C8F420058146200189A -:10A68000000000008F4200001040000700000000A2 -:10A69000AF80004C8F82004C1040FFFD0000000096 -:10A6A0001000000500000000AF8000488F820048C5 -:10A6B0001040FFFD000000008F8200602403FEFFB9 -:10A6C00000431024AF8200608F420000104000035E -:10A6D0000000000010000002AF80004CAF80004876 -:10A6E0008FBF00248FB0002003E0000827BD0028A2 -:10A6F00003E000080000000027BDFFD8AFBF002422 -:10A70000AFB000208F43006C8F42006810620033AE -:10A71000000000008F4300688F42006C006220231D -:10A7200004820001248404008F4300748F42006C73 -:10A730000043102B14400004240204008F43006CDB -:10A7400010000005004310238F4200748F43006CFB -:10A75000004310232442FFFF00405021008A102AAA -:10A7600054400001008050218F49006C8F48006CDC -:10A770008F4401988F45019C8F46006C2407400050 -:10A78000AFA700100008414001001821012A48210C -:10A79000313003FFAFB000148F47001400001021C8 -:10A7A0000006314024C66CC0AFA7001800A32821C2 -:10A7B00000A3382B00822021008720218F4201082E -:10A7C00002E630210040F809000A394054400001F7 -:10A7D000AF50006C8F43006C8F4200681462001809 -:10A7E000000000008F420000104000070000000041 -:10A7F000AF80004C8F82004C1040FFFD0000000035 -:10A800001000000500000000AF8000488F82004863 -:10A810001040FFFD000000008F8200602403F7FF5E -:10A8200000431024AF8200608F42000010400003FC -:10A830000000000010000002AF80004CAF80004814 -:10A840008FBF00248FB0002003E0000827BD002840 -:10A8500003E00008000000008F4200FC3C03000100 -:10A860008F4400F8346330C824420001AF4200FC3A -:10A870008F85012802E310215482000424820008FD -:10A880003C02000134422EC802E21021004018218F -:10A89000AF4300F8AC6000008F4200F41462000483 -:10A8A0003C02000124A200201000000FAF8201280A -:10A8B0008F4300F8344230C802E210215462000491 -:10A8C000246200083C02000134422EC802E210213A -:10A8D000004018218C6200040002114000A21021E7 -:10A8E000AF820128AC6000008CA3001830620070B9 -:10A8F0001040002D30620020104000043C02001087 -:10A9000002C210241040000D000000003062004020 -:10A91000104000043C02002002C210241040000736 -:10A9200000000000306200101040001F3C02004098 -:10A9300002C210241440001C000000008F8200405E -:10A940003042000114400008000020218C03010463 -:10A950002402000150620005240400018C020264FC -:10A960001040000300801021240400010080102109 -:10A9700010400006000000008F42030C244200013A -:10A98000AF42030C100000088F42030C8F8200447A -:10A9900034420004AF8200448F4203082442000185 -:10A9A000AF4203088F42030803E0000800000000E4 -:10A9B00003E000080000000027BDFF98AFBF006063 -:10A9C000AFBE005CAFB50058AFB30054AFB200509B -:10A9D000AFB1004CAFB000488F4200FC24420001F0 -:10A9E000AF4200FC8F88012825020020AF82012899 -:10A9F0008D030018306200701040002E306200207D -:10AA0000104000043C02001002C210241040000D4F -:10AA10000000000030620040104000043C020020B2 -:10AA200002C2102410400007000000003062001035 -:10AA3000104001A93C02004002C21024144001A6AB -:10AA4000000000008F8200403042000114400008E6 -:10AA5000000020218C030104240200015062000543 -:10AA6000240400018C0202641040000300801021C5 -:10AA700024040001008010211040000600000000A6 -:10AA80008F42030C24420001AF42030C10000192DC -:10AA90008F42030C8F82004434420004AF82004492 -:10AAA0008F42030824420001AF4203081000018ACC -:10AAB0008F420308306200021040014B3C02080044 -:10AAC0008D1E001C001E5702AFAA0034950A001606 -:10AAD00003C22024AFAA00248FAA0034240200015C -:10AAE0001542000633DEFFFF001E11403403ECC0A8 -:10AAF000004310211000001002E2A82124020002ED -:10AB00001542000524020003001E114024426CC0BF -:10AB10001000000902E2A82115420005001E118064 -:10AB2000001E114024424CC01000000302E2A82184 -:10AB30000057102124550CE096A2000E304AFFFC6D -:10AB40003042040010400003AFAA002C100000E1C6 -:10AB500000008821108000040000882197B10026A1 -:10AB6000100000DDA6B100128EB30018966A000C2A -:10AB7000A7AA003E97A5003E2CA305DD38A2887049 -:10AB80002C420001006218251060001500002021F1 -:10AB900032C2080010400015240208009663001419 -:10ABA000146200123402AAAA9663000E146200070F -:10ABB00000002821966300102402030014620004A0 -:10ABC00000A01021966200122C45000100A0102167 -:10ABD0005440000624040016100000040000000089 -:10ABE0002402080050A200012404000E108000B9C5 -:10ABF00002649021924200003042000F00028080E7 -:10AC000032C2010010400020025018213C020020F6 -:10AC10000043102B1440000E024020210000282188 -:10AC2000948200002484000200A228210083102BBB -:10AC30001440FFFB30A2FFFF00051C020062282128 -:10AC400000051C0230A2FFFF10000009006228214D -:10AC50008F4701488F420110001028423C06002017 -:10AC60000040F809AFA800403045FFFF8FA8004022 -:10AC700050A000013405FFFF8FAA002C354A0002C6 -:10AC800010000002AFAA002C0000282132C2008070 -:10AC900010400090A6A50010264300093C02001FAA -:10ACA0003442FFFF0043102B10400003000000005F -:10ACB0008F420148006218239066000030C200FFF6 -:10ACC000384300062C630001384200112C42000179 -:10ACD000006218251060007F24020800000088210F -:10ACE00097A3003E1462000F0260202196710000BD -:10ACF0009662000296630004966400060222882190 -:10AD00000223882102248821966200089663000AA3 -:10AD10009664000C0222882102238821100000077B -:10AD200002248821948200002484000202228821C7 -:10AD30000092102B1440FFFB0000000000111C02C9 -:10AD40003222FFFF0062882100111C023222FFFF25 -:10AD50000062882132C2020010400003264400062F -:10AD60001000003E000080213C05001F34A5FFFFBD -:10AD700000A4102B10400003000000008F42014887 -:10AD8000008220239482000030421FFF1040000404 -:10AD90002644000C96420002100000300050802330 -:10ADA0009642000226430014005080233C020020FB -:10ADB0000043102B1440000A00D080219642000C62 -:10ADC000020280219642000E964300109644001223 -:10ADD0000202802102038021100000200204802151 -:10ADE00000A4102B10400003000000008F42014817 -:10ADF0000082202394820000248400020202802129 -:10AE000000A4102B10400003000000008F420148F6 -:10AE10000082202394820000248400020202802108 -:10AE200000A4102B10400003000000008F420148D6 -:10AE300000822023948200002484000202028021E8 -:10AE400000A4102B10400003000000008F420148B6 -:10AE50000082202394820000020280213C02010033 -:10AE600002C210241040000E000000008FAA002C27 -:10AE7000314200041040000A000000009504000E5A -:10AE8000026420210C003EEC2484FFFC3042FFFFD2 -:10AE90000222882100111C023222FFFF0062882159 -:10AEA0008FAA002401518823001114020222882154 -:10AEB0000230882100111402022288213231FFFF62 -:10AEC000522000013411FFFF8FAA002C354A0001E7 -:10AED000AFAA002CA6B1001297AA002EA6AA000EB7 -:10AEE0008FAA002C314200041040000224091000F7 -:10AEF000340980008F4800448F4401A08F4501A48D -:10AF0000AFA900108F4900440008414001001821FA -:10AF1000AFA900148F48000C02A0302124070020A4 -:10AF2000AFA800188F48010C0000102100A32821B1 -:10AF300000A3482B008220210100F809008920216C -:10AF40001440000B000000008F8201283C04000127 -:10AF500024846914AFBE0014AFA200108F860124B0 -:10AF60008F8701203C0500070C002B3B34A599205E -:10AF70008F4203682442FFFFAF4203688F420044C0 -:10AF80008F4300882442000100431024AF42004454 -:10AF90008FAA00348F440368240200011542000682 -:10AFA000240200028F42035C2442FFFFAF42035C95 -:10AFB000100000498F42035C1542000600000000AB -:10AFC0008F4203642442FFFFAF420364100000423B -:10AFD0008F4203648F4203602442FFFFAF4203604D -:10AFE0001000003D8F4203603062100010400005E9 -:10AFF000306280008F420078244200011000003649 -:10B00000AF42007810400034000000008F4200780A -:10B0100024420001AF4200788C0302400043102B11 -:10B020001440002D240700088F4401688F45016CEF -:10B030008F4300448F48000C8F860120240200407B -:10B04000AFA20010AFA30014AFA800188F42010CEC -:10B050000040F80924C6001C14400011240200011D -:10B060003C01000100370821A02240F28F82012418 -:10B07000AFA200108F8201283C0400012484688C58 -:10B08000AFA200148F4600448F8701203C050009C1 -:10B090000C002B3B34A513001000000B0000000037 -:10B0A0008F42030424420001AF4203048F42030491 -:10B0B0008F420044AF42007C3C0100010037082170 -:10B0C000A02040F2AF4000788F42031824420001D4 -:10B0D000AF4203188F4203188FBF00608FBE005C21 -:10B0E0008FB500588FB300548FB200508FB1004C11 -:10B0F0008FB0004803E0000827BD006803E00008A7 -:10B100000000000000000000000000008F42013C31 -:10B11000AF8200C08F42013CAF8200C48F42013C2D -:10B12000AF8200C88F420138AF8200D08F42013811 -:10B13000AF8200D48F42013803E00008AF8200D80C -:10B1400027BDFFE02784020824050200AFBF0018D6 -:10B150000C002BBF240600088C0202040C004012D5 -:10B16000AF8202103C0200018C426D94304200021A -:10B170001040000E000020218C060248240200022C -:10B180003C010001AC226D980C0051042405000222 -:10B19000000020218C060248240200013C0100012D -:10B1A000AC226D9810000011240500018C060248A5 -:10B1B000240200043C010001AC226D980C005104F3 -:10B1C000240500043C0200018C426D9430420001D1 -:10B1D00010400008240200013C010001AC226D98DF -:10B1E00000002021240500013C06601B0C005104D6 -:10B1F000000000003C040001248469D08F4201500B -:10B200008F4301543C0500088F4601580002164048 -:10B21000000319403463040300431025000633C0C3 -:10B2200000461025AF82021CAFA00010AFA0001492 -:10B230008F86021C34A502000C002B3B0000382135 -:10B240003C010001AC206D903C010001AC206DA8D8 -:10B250008FBF001803E0000827BD002027BDFFE0D6 -:10B260003C05000834A50300AFBF0018AFA00010D4 -:10B27000AFA000148F8602003C040001248469DC26 -:10B280000C002B3B000038218F42041024420001A7 -:10B29000AF4204108F4204108FBF001803E0000873 -:10B2A00027BD002027BDFFD8AFBF0020AFB1001CD5 -:10B2B000AFB000188F4203A424420001AF4203A4A0 -:10B2C0008F4203A48F9002208F8200E0AFA2001073 -:10B2D0008F8200E4AFA200148F8600C48F8700C85D -:10B2E0003C040001248469E80C002B3B0200282167 -:10B2F0003C04400002041024504000B43C0401000F -:10B300008F4203BC24420001AF4203BC8F4203BC06 -:10B310008F8700C48F8300C88F42014800671823BD -:10B320000043102B10400003000000008F42014832 -:10B330000062182110600005000000008F42014CDF -:10B340000043102B1040000B000000008F8200E033 -:10B350008F430124AF42011CAF4301148F820220AE -:10B360003C0308FF3463FFFB00431024100000CEB1 -:10B37000004410258F8202203C0308FF3463FFFF46 -:10B380000043102434420004AF8202208F8200E088 -:10B390008F430124AF42011CAF4301148F8600C8C4 -:10B3A0008F8401208F8301241000000500002821D4 -:10B3B0001462000224620020276248000040182125 -:10B3C0001064000C30A200FF8C62001830420003B1 -:10B3D0001040FFF727624FE08F4203D024050001A1 -:10B3E00024420001AF4203D08F4203D08C66000894 -:10B3F00030A200FF1440005800000000934205C432 -:10B4000014400055000000008F8700C48F8800E0C2 -:10B410008F8400E42402FFF8010240240104102379 -:10B42000000218C3046200012463020010600005DA -:10B430002402000110620009000000001000001F3B -:10B44000000000008F4203C000E0302124420001D0 -:10B45000AF4203C0100000408F4203C08F4203C4BC -:10B4600024420001AF4203C48C8600008F42014891 -:10B470008F4303C400E618230043102B1040000440 -:10B480002C62233F8F420148006218212C62233F27 -:10B4900014400031000000008F42020C24420001E1 -:10B4A000AF42020C8F42020C00E0302124820008DF -:10B4B000AF8200E410000028AF8200E88F4203C88A -:10B4C00024420001AF4203C88F4203C88C850000AC -:10B4D0008F42014800A718230043102B104000039F -:10B4E000000000008F420148006218218F42014C89 -:10B4F0000043102B5440000A00A030218F42020C60 -:10B5000024420001AF42020C8F42020C2482000848 -:10B51000AF8200E48F8400E41488FFECAF8400E87D -:10B520001488000D27623000148200022482FFF884 -:10B5300027623FF8944300063C02001F3442FFFF9D -:10B5400000C330210046102B104000030000000013 -:10B550008F42014800C23023AF8600C88F8300C4E9 -:10B560008F42014800C318230043102B10400003F2 -:10B57000000000008F4201480062182110600005A1 -:10B58000000000008F42014C0043102B5040000887 -:10B590003C02FDFF8F8202203C0308FF3463FFFB67 -:10B5A000004310243C0340001000003F00431025DE -:10B5B0008F4303CC3442FFFF0282A02424630001A6 -:10B5C000AF4303CC100000398F4203CC0204102497 -:10B5D0001040000E3C1102008F4203A824420001DB -:10B5E000AF4203A88F4203A88F8202203C0308FFCA -:10B5F0003463FFFF00431024004410250C003DAFCE -:10B60000AF82022010000029000000000211102467 -:10B61000504000083C1104008F4203AC244200015A -:10B62000AF4203AC0C003DAF8F4203AC10000019D9 -:10B6300000000000021110241040001C0000000057 -:10B640008F83022424021402146200093C050008BE -:10B650003C040001248469F4AFA00010AFA00014E2 -:10B660008F86022434A505000C002B3B00003821F6 -:10B670008F4203B024420001AF4203B08F4203B0B7 -:10B680008F82022002002021344200020C004E9CD6 -:10B69000AF8202208F8202203C0308FF3463FFFF49 -:10B6A0000043102400511025AF8202208FBF0020DC -:10B6B0008FB1001C8FB0001803E0000827BD0028E0 -:10B6C00003E00008000000003C0200018C426DA86D -:10B6D00027BDFFB0AFBF0048AFBE0044AFB50040CC -:10B6E000AFB3003CAFB20038AFB100341040000F30 -:10B6F000AFB000303C04000124846A003C0500081F -:10B70000AFA00010AFA000148F86022034A5060061 -:10B71000240200013C010001AC206DA83C010001A5 -:10B72000AC226D9C0C002B3B000038213C037FFFBA -:10B730008C0202683463FFFF3C04FDFF00431024C9 -:10B74000AC0202688F4200043484FFFF30420002E2 -:10B75000104000920284A0243C040600348420009F -:10B760008F420004000028212403FFFD0043102421 -:10B77000AF420004AFA400208F5E001827AA00206B -:10B78000240200FF13C20002AFAA002C27C500014B -:10B790008C02022800A090211642000E001E38C024 -:10B7A0008F42033C24420001AF42033C8F42033CE2 -:10B7B0008C0202283C040001248469983C0500099D -:10B7C000AFA00014AFA200108FA600201000006DE3 -:10B7D00034A5050000F710218FA300208FA40024BA -:10B7E000AC4304C0AC4404C48F8300548F82005423 -:10B7F000247003E8020210232C4203E91040001BCE -:10B800000000982100E08821263504C08F4401788B -:10B810008F45017C02201821240A0004AFAA0010E1 -:10B82000AFB200148F48000C0000102102F5302147 -:10B83000AFA800188F48010C2407000800A3282196 -:10B8400000A3482B008220210100F8090089202153 -:10B8500054400006241300018F820054020210237A -:10B860002C4203E91440FFE900000000326200FFAF -:10B8700054400017AF5200188F4203782442000151 -:10B88000AF4203788F4203788F8201208FAA002C69 -:10B89000AFA200108F8201243C040001248469A41B -:10B8A0003C050009AFA200148D46000010000035D1 -:10B8B00034A506008F42030824130001244200012E -:10B8C000AF4203088F4203081000001E326200FFDF -:10B8D0008F8300548F820054247003E802021023E7 -:10B8E0002C4203E910400016000098213C1500206E -:10B8F000241100108F42000C8F4401608F450164B9 -:10B900008F860120AFB10010AFB200140055102592 -:10B91000AFA200188F42010C240700080040F8096C -:10B9200024C6001C1440FFE3000000008F82005476 -:10B93000020210232C4203E91440FFEE0000000035 -:10B94000326200FF14400011000000008F420378B3 -:10B9500024420001AF4203788F4203788F82012096 -:10B960008FAA002CAFA200108F8201243C0400019A -:10B97000248469AC3C050009AFA200148D46000088 -:10B9800034A507000C002B3B03C038218F4202EC8A -:10B9900024420001AF4202EC8F4202EC8FBF00480C -:10B9A0008FBE00448FB500408FB3003C8FB200388B -:10B9B0008FB100348FB0003003E0000827BD005085 -:10B9C0003C0200018C426DA827BDFFE01440000D31 -:10B9D000AFBF00183C04000124846A0C3C05000839 -:10B9E000AFA00010AFA000148F86022034A507007E -:10B9F000240200013C010001AC226DA80C002B3B8D -:10BA0000000038213C02000402C21024104000074C -:10BA1000000000008F8202203C0308FF3463FFFF18 -:10BA20000043102434420008AF8202203C0500018C -:10BA30008CA56D982402000114A2000700002021AB -:10BA40000C00529B24050001AC02026C8C03026CBA -:10BA5000100000063C0200070C00529B0000202151 -:10BA6000AC0202688C0302683C02000700621824E2 -:10BA70003C0200025062000D3C0205F50043102B11 -:10BA8000144000063C0200043C0200011062000960 -:10BA90003C0200981000000B000000001462000936 -:10BAA0003C023B9A100000043442CA00100000021D -:10BAB0003442E10034429680AF4201FC8F4201FCE7 -:10BAC000AEE200648FBF001803E0000827BD00202D -:10BAD0000000000000000000000000000086102BA5 -:10BAE000504000010087202300C410230002484377 -:10BAF0000125102B1040001B00091040008240213E -:10BB00000088102B104000070000182194820000CC -:10BB100024840002006218210088102B1440FFFBCF -:10BB2000000000000060202100C7302300A910237E -:10BB30000002104000C2282100C5102B1040000751 -:10BB40000000182194C2000024C6000200621821DF -:10BB500000C5102B1440FFFB000000001000000D7A -:10BB60000083202100051040008228210085102B31 -:10BB70001040000700001821948200002484000275 -:10BB8000006218210085102B1440FFFB000000000C -:10BB90000060202100041C023082FFFF006220218F -:10BBA00000041C023082FFFF0062202103E0000835 -:10BBB0003082FFFF03E00008000000000080282121 -:10BBC00030A200011040002B3C03001F3463FFFF34 -:10BBD00024A200040062102B544000070065102BC3 -:10BBE00090A2000190A4000390A3000090A5000281 -:10BBF0001000002A00441021104000030000000043 -:10BC00008F42014800A2282390A4000024A500012F -:10BC10000065102B10400003000000008F42014817 -:10BC200000A2282390A2000024A500010002120017 -:10BC3000008220210065102B10400003000000004E -:10BC40008F42014800A2282390A2000024A50001F1 -:10BC5000008220210065102B10400003000000002E -:10BC60008F42014800A2282390A200001000002D5E -:10BC7000000212003463FFFF24A200040062102BB4 -:10BC80005440000A0065102B90A2000090A400020E -:10BC900090A3000190A500030044102100021200AF -:10BCA00000651821100000200043202110400003EF -:10BCB000000000008F42014800A2282390A200004B -:10BCC00024A50001000222000065102B1040000393 -:10BCD000000000008F42014800A2282390A200002B -:10BCE00024A50001008220210065102B10400003D4 -:10BCF000000000008F42014800A2282390A200000B -:10BD000024A5000100021200008220210065102BF2 -:10BD100010400003000000008F42014800A22823C9 -:10BD200090A200000082202100041C023082FFFF4C -:10BD30000062202100041C023082FFFF00622021EB -:10BD400003E000083082FFFF000000008F82022025 -:10BD500034420002AF8202203C0200028C428FF883 -:10BD60003042400010400054240400018F82020041 -:10BD700024067FFF8F830200304500022402FFFD6E -:10BD800000621824AF830200AF8402048F83005442 -:10BD90008F82005410000002246300018F8200543F -:10BDA000006210232C4200021440FFFC000000003F -:10BDB0008F8202241444004D0004204000C4102B44 -:10BDC0001040FFF1000000008F82020000451025A6 -:10BDD000AF8202008F82022034428000AF820220B4 -:10BDE0008F8300548F8200541000000224630001EE -:10BDF0008F820054006210232C4200021440FFFC8A -:10BE0000000000008F8202203C0300040043102445 -:10BE10001440000F000000008F8202203C03FFFF4F -:10BE200034637FFF00431024AF8202208F830054CD -:10BE30008F82005410000002246300018F8200549E -:10BE4000006210232C4200021440FFFC000000009E -:10BE50008F8202203C030004004310241440000D94 -:10BE6000000000008F82022034428000AF82022056 -:10BE70008F8300548F82005410000002246300015D -:10BE80008F820054006210232C4200021440FFFCF9 -:10BE9000000000008F8202203C03000400431024B5 -:10BEA0001040001B000010218F830220240200019B -:10BEB000100000153C04F7008F8202203C04F700BC -:10BEC00000441025AF8202208F8202202403FFFD50 -:10BED00000431024AF8202208F8202203C03030023 -:10BEE000004310241440000300000000100000086C -:10BEF000000010218F82022034420002AF82022013 -:10BF00008F8302202402000100641825AF830220E1 -:10BF100003E0000800000000000020213C050100B3 -:10BF200024020001AF80021CAF820200AF82022017 -:10BF300027625000AF8200C027625000AF8200C469 -:10BF400027625000AF8200C827625000AF8200D045 -:10BF500027625000AF8200D427625000AF8200D821 -:10BF600027623000AF8200E027623000AF8200E439 -:10BF700027623000AF8200E827622800AF8200F01D -:10BF800027622800AF8200F427622800AF8200F801 -:10BF9000000418C02484000103631021AC45300460 -:10BFA00003631021AC403000288202001440FFF9E6 -:10BFB000000418C000002021000418C024840001DF -:10BFC00003631021AC40280403631021AC40280017 -:10BFD000288201001440FFF9000418C0AF80023C21 -:10BFE0002403008024040100AC60000024630004EA -:10BFF0000064102B5440FFFDAC6000008F830040B4 -:10C000003C02F000006218243C0250001062000C58 -:10C010000043102B144000063C0260003C0240002C -:10C020001062000824020800100000080000000050 -:10C030001062000424020800100000040000000048 -:10C04000240207003C010001AC226DAC03E00008B3 -:10C05000000000003C0200018C426DBC27BDFFD0F7 -:10C06000AFBF002CAFB20028AFB10024AFB00020AA -:10C070003C01000110400005AC206D940C004D9E69 -:10C08000000000003C010001AC206DBC8F83005417 -:10C090008F82005410000002246300648F820054D9 -:10C0A000006210232C4200651440FFFC00000000D9 -:10C0B0000C004DB9000000002404000100002821FC -:10C0C00027A60018340280000C0045BEA7A2001865 -:10C0D0008F8300548F820054100000022463006498 -:10C0E0008F820054006210232C4200651440FFFC34 -:10C0F00024040001240500010C00457C27A600183B -:10C100008F8300548F820054100000022463006467 -:10C110008F820054006210232C4200651440FFFC03 -:10C1200024040001240500010C00457C27A600180A -:10C130008F8300548F820054100000022463006437 -:10C140008F820054006210232C4200651440FFFCD3 -:10C15000240400013C06000124C66F240C00457C29 -:10C16000240500028F8300548F82005410000002C7 -:10C17000246300648F820054006210232C42006507 -:10C180001440FFFC24040001240500033C100001BE -:10C1900026106F260C00457C0200302197A600185F -:10C1A0003C07000194E76F243C04000124846AE00A -:10C1B000AFA00014960200003C05000D34A501005C -:10C1C0000C002B3BAFA2001097A200181040004DAE -:10C1D00024036040960200003042FFF01443000C3C -:10C1E000240200203C03000194636F241462000BBE -:10C1F00024027830240200033C010001AC226D943B -:10C20000240200053C0100011000003FAC226F3405 -:10C210003C03000194636F24240278301462000C04 -:10C22000240300103C02000194426F263042FFF0CC -:10C2300014430007240200033C010001AC226D946A -:10C24000240200063C0100011000002FAC226F34D4 -:10C250003C0200018C426D943C03000194636F2406 -:10C26000344200013C010001AC226D94240200150F -:10C270001462000B000000003C02000194426F2693 -:10C280003042FFF03843F4202C6300013842F43090 -:10C290002C420001006218251460001B24020003D8 -:10C2A0003C03000194636F2424027810146200168A -:10C2B000240200023C02000194426F263042FFF04B -:10C2C00014400011240200021000000F2402000498 -:10C2D0003C0200018C426D94344200083C01000194 -:10C2E000AC226D941000005E240200043C020001A8 -:10C2F0008C426D94344200043C010001100000AFF8 -:10C30000AC226D94240200013C010001AC226F407C -:10C310003C0200018C426D9430420002144000B295 -:10C320003C09FFF024020E00AF8202388F840054D3 -:10C330008F820054240300083C010001AC236D9857 -:10C3400010000002248401F48F8200540082102324 -:10C350002C4201F51440FFFC3C0200C8344201FBB2 -:10C36000AF8202388F8300548F8200541000000285 -:10C37000246301F48F820054006210232C4201F5E3 -:10C380001440FFFC00008021241200012411000948 -:10C390000C004482000000003C010001AC326DB48E -:10C3A0000C004547000000003C0200018C426DB4C7 -:10C3B0001451FFFB3C0200C8344201F6AF82023840 -:10C3C0008F8300548F820054100000022463000AFF -:10C3D0008F820054006210232C42000B1440FFFC9B -:10C3E000000000008F820220240400013442000279 -:10C3F000AF8202208F83020024057FFF2402FFFD0D -:10C4000000621824AF830200AF8402048F830054BB -:10C410008F82005410000002246300018F820054B8 -:10C42000006210232C4200021440FFFC00000000B8 -:10C430008F8202241444000534028000000420404E -:10C4400000A4102B1040FFF0340280001082FFA0E7 -:10C45000261000012E0200141440FFCD2402000417 -:10C460003C010001AC226D980000802124120009DB -:10C470003C11FFFF36313F7F0C004482000000007A -:10C48000240200013C010001AC226DB40C004547C0 -:10C49000000000003C0200018C426DB41452FFFB0E -:10C4A000000000008F82004400511024344250806C -:10C4B000AF8200448F8300548F820054100000022A -:10C4C0002463000A8F820054006210232C42000B68 -:10C4D0001440FFFC000000008F8200440051102433 -:10C4E0003442F080AF8200448F8300548F82005426 -:10C4F000100000022463000A8F820054006210239F -:10C500002C42000B1440FFFC000000008F82022030 -:10C510003C03F70000431025AF8202208F830054B4 -:10C520008F82005410000002246300648F82005444 -:10C53000006210232C4200651440FFFC0000000044 -:10C540008F8202202404000134420002AF820220C4 -:10C550008F83020024057FFF2402FFFD0062182460 -:10C56000AF830200AF8402048F8300548F82005493 -:10C5700010000002246300018F8200540062102327 -:10C580002C4200021440FFFC000000008F820224B5 -:10C5900014440005340280000004204000A4102B45 -:10C5A0001040FFF0340280001082FF50261000017E -:10C5B0002E0200641440FFB0000000003C020001A5 -:10C5C0008C426D9430420004144000073C09FFF097 -:10C5D0008F8200443C03FFFF34633F7F00431024FD -:10C5E000AF8200443C09FFF03529BDC03C06000184 -:10C5F0008CC66D943C04000124846AE0240200018E -:10C600003C010001AC226D9C8F8200543C0700016C -:10C610008CE76F403C03000194636F243C080001E9 -:10C6200095086F263C05000D34A501003C01000172 -:10C63000AC206D98004910213C010001AC226F3004 -:10C64000AFA300100C002B3BAFA800148FBF002C31 -:10C650008FB200288FB100248FB0002003E00008C3 -:10C6600027BD003027BDFFE83C0500018CA56D9873 -:10C67000240600042402000114A20014AFBF00101D -:10C680003C0200028C428FFC3042800010400005CA -:10C690003C04000F3C0300018C636F401000000558 -:10C6A000348442403C0400043C0300018C636F402E -:10C6B000348493E024020005146200160000000098 -:10C6C0003C04003D10000013348409003C020002C9 -:10C6D0008C428FF830428000104000053C04001E60 -:10C6E0003C0300018C636F4010000005348484809B -:10C6F0003C04000F3C0300018C636F4034844240D3 -:10C700002402000514620003000000003C04007ACB -:10C71000348412003C0200018C426F308F8300543D -:10C7200000441021004310230044102B1440004CFF -:10C73000000000003C0200018C426DA01440004843 -:10C74000000000003C01000110C00025AC206DB0CD -:10C750003C0900018D296D94240700013C04400030 -:10C760003C08000225088FFC250AFFFC0005284232 -:10C7700014A0000224C6FFFF2405000800A910240D -:10C78000104000100000000014A700080000000086 -:10C790008D020000004410241040000A0000000038 -:10C7A0003C01000110000007AC256DB08D42000077 -:10C7B0000044102410400003000000003C01000170 -:10C7C000AC276DB03C0200018C426DB00006182B06 -:10C7D0002C420001004310245440FFE5000528428C -:10C7E0008F8200543C0300018C636DB03C0100015A -:10C7F000AC226F301060003B240200053C030001B6 -:10C800008C636F403C010001AC256D9814620012EE -:10C81000240200013C0200028C428FF83C032000FD -:10C820003463500000431024144000062402000129 -:10C830003C010001AC206F1C3C010001AC226D9852 -:10C84000240200013C010001AC226E243C010001E5 -:10C85000AC226DA4240200013C010001AC226D9CBD -:10C860003C0200018C426DB01040001E0000000030 -:10C870003C0200018C426D9C104000082402000123 -:10C880003C010001AC206D9CAEE204B83C0100010B -:10C89000AC206E1C3C010001AC226DD48EE304B8C8 -:10C8A0002402000810620005240200010C00423935 -:10C8B000000000001000000B000000003C0300011D -:10C8C0008C636D98106200072402000E3C03000286 -:10C8D0008C638F9010620003000000000C004E9CDF -:10C8E0008F8402208FBF001003E0000827BD0018CE -:10C8F00027BDFFE03C03FDFF3C0400018C846D98E4 -:10C900003C0200018C426DC03463FFFF0283A0240F -:10C9100014820006AFBF00188EE304B83C02000189 -:10C920008C426DC410620006000000008EE204B864 -:10C930003C010001AC246DC03C010001AC226DC47F -:10C940003C0300018C636D98240200021062019C7C -:10C950002C62000310400005240200011062000A4E -:10C960000000000010000226000000002402000465 -:10C97000106200B6240200081062010A24020001BD -:10C980001000021F000000008EE204B82443FFFFE5 -:10C990002C6200081040021C000310803C010001C2 -:10C9A000002208218C226AF80040000800000000E4 -:10C9B0003C0300018C636F402402000514620010E8 -:10C9C000000000003C0200018C426DA410400008F1 -:10C9D000240200030C004482000000002402000234 -:10C9E000AEE204B83C01000110000002AC206DA4CE -:10C9F000AEE204B83C01000110000203AC206D302F -:10CA00000C004482000000003C0200018C426DA436 -:10CA10003C010001AC206D301440017A2402000278 -:10CA20001000019D240200073C0300018C636F404D -:10CA30002402000514620003240200013C010001ED -:10CA4000AC226DD00C0045FF000000003C0300014B -:10CA50008C636DD010000174240200113C050001AC -:10CA60008CA56D983C0600028CC68FFC0C0051040E -:10CA700000002021240200053C010001AC206DA42F -:10CA8000100001E1AEE204B83C04000124846AEC29 -:10CA90003C05000F34A501000000302100003821C2 -:10CAA000AFA000100C002B3BAFA00014100001D66B -:10CAB000000000008F8202203C0300040043102489 -:10CAC00014400175240200078F8300543C020001CA -:10CAD0008C426F282463D8F0004310232C42271087 -:10CAE00014400003240200013C010001AC226D9CB3 -:10CAF0003C0200028C428FFC30425000104001C2C8 -:10CB0000000000008F820220304280001040017D32 -:10CB10000000000010000175000000003C0500014D -:10CB20008CA56D980C00529B000020210C00551B19 -:10CB3000000020213C0300028C638FF4046101B0EB -:10CB4000240200013C02000800621024104000068C -:10CB5000000000008F8202143C03FFFF00431024FA -:10CB6000100000053442251F8F8202143C03FFFF92 -:10CB7000004310243442241FAF8202148F8202200B -:10CB80003C03020034420002AF820220240200086B -:10CB9000AEE204B88F8202200283A0253C03000489 -:10CBA0000043102414400016000000003C02000264 -:10CBB0008C428FFC304250001040000D00000000FD -:10CBC0008F820220304280001040000600000000EA -:10CBD0008F8202203C03FFFF34637FFF10000003BD -:10CBE000004310248F82022034428000AF82022052 -:10CBF0008F8202203C03F70000431025AF82022001 -:10CC00003C0300018C636F40240200051462000A9B -:10CC1000000000003C02000194426F2624429FBCA9 -:10CC20002C420004104000042404001824050002D3 -:10CC30000C004DDB240600200C003E6D00000000BF -:10CC40003C01000110000170AC206E208EE204B89F -:10CC50002443FFFF2C6200081040016B000310808A -:10CC60003C010001002208218C226B1800400008C2 -:10CC7000000000000C004547000000003C030001DC -:10CC80008C636DB4100000E8240200093C0200022D -:10CC90008C428FF830424000104000040000000039 -:10CCA0008F820044100000063442F0808F820044DE -:10CCB0003C03FFFF34633F7F004310243442A080D5 -:10CCC000AF8200448F830054100000EA2402000465 -:10CCD0008F8300543C0200018C426F282463D8F0FB -:10CCE000004310232C422710144001472402000562 -:10CCF000100000D8000000008F8202203C03F700E3 -:10CD000000431025AF820220AF8002043C010002E4 -:10CD1000100000D6AC208FE08F8300543C0200014D -:10CD20008C426F282463FFF6004310232C42000A34 -:10CD30001440013524020007100000D70000000055 -:10CD40000C003F50000000001040012D24020001A3 -:10CD50008F8202143C03FFFF3C0400018C846F1C93 -:10CD6000004310243442251FAF820214240200081D -:10CD700010800005AEE204B83C0200018C426E4413 -:10CD800010400064240200018F8202203C0300084E -:10CD9000004310241040006A3C020200100000789A -:10CDA000000000008EE204B82443FFFF2C6200075D -:10CDB00010400115000310803C01000100220821F1 -:10CDC0008C226B3800400008000000000C003DAFD2 -:10CDD000000000003C010001AC206D9CAF8002040B -:10CDE0003C0100020C004482AC208FE024020001D0 -:10CDF0003C010001AC226DB42402000210000102CB -:10CE0000AEE204B80C004547000000003C030001FE -:10CE10008C636DB410000084240200093C020002FF -:10CE20008C428FF830424000104000033C0200C8A2 -:10CE300010000002344201F6344201FEAF82023893 -:10CE40008F8300541000008B240200048F83005451 -:10CE50003C0200018C426F282463D8F00043102369 -:10CE60002C422710144000E824020005100000792D -:10CE7000000000008F8202203C03F70000431025D1 -:10CE8000AF820220AF8002043C0100021000007754 -:10CE9000AC208FE08F8300543C0200018C426F284D -:10CEA0002463FFF6004310232C42000A144000D6EE -:10CEB0002402000710000078000000000C003F5022 -:10CEC00000000000104000CE240200018F820214F6 -:10CED0003C03FFFF3C0400018C846F1C00431024C2 -:10CEE0003442251FAF820214240200081080000F74 -:10CEF000AEE204B83C0200018C426E441440000BC8 -:10CF0000000000008F82022034420002AF82022023 -:10CF1000240200013C010002AC228F900C004E9CC8 -:10CF20008F84022010000016000000008F82022073 -:10CF30003C03000800431024144000113C0202008E -:10CF40000282A0252402000E3C010002AC228F9038 -:10CF50000C00551B000020218F8202203442000269 -:10CF60000C003E6DAF8202203C0500018CA56D983F -:10CF70000C00529B00002021100000A300000000C4 -:10CF80003C0200018C426E441040009F00000000F3 -:10CF90003C0200018C426E402442FFFF3C01000134 -:10CFA000AC226E4014400098240200023C010001B3 -:10CFB000AC206E443C01000110000093AC226E4096 -:10CFC0008EE204B82443FFFF2C6200071040008E5D -:10CFD000000310803C010001002208218C226B58C4 -:10CFE00000400008000000003C0200018C426DA4DB -:10CFF00010400018240200050C00448200000000CC -:10D0000024020002AEE204B83C0100011000007EE0 -:10D01000AC206DA40C004963000000003C0300013B -:10D020008C636DD42402000614620077240200038E -:10D0300010000075AEE204B83C0500018CA56D98A7 -:10D040003C0600028CC68FF80C0051040000202121 -:10D05000240200051000006CAEE204B88F820220AA -:10D060003C03F70000431025AF8202208F83005459 -:10D0700024020006AEE204B83C0100011000006288 -:10D08000AC236F288F8202203C030004004310244D -:10D0900010400003240200071000005BAEE204B859 -:10D0A0008F8300543C0200018C426F282463D8F027 -:10D0B000004310232C4227101440000324020001D7 -:10D0C0003C010001AC226D9C3C0200028C428FF8B6 -:10D0D000304250001040004C000000008F820220BF -:10D0E0003042800010400007000000008F820220C4 -:10D0F0003C03FFFF34637FFF004310241000004215 -:10D10000AF8202208F820220344280001000003E55 -:10D11000AF8202203C0500018CA56D980C00529B4B -:10D12000000020210C00551B000020213C020002C1 -:10D130008C428FF004410032240200018F820214DD -:10D140003C03FFFF004310243442251FAF8202142A -:10D1500024020008AEE204B88F82022034420002AA -:10D16000AF8202208F8202203C030004004310247F -:10D1700014400016000000003C0200028C428FF8B0 -:10D18000304250001040000D000000008F8202204D -:10D190003042800010400006000000008F82022014 -:10D1A0003C03FFFF34637FFF1000000300431024A3 -:10D1B0008F82022034428000AF8202208F820220C0 -:10D1C0003C03F70000431025AF8202203C0200011F -:10D1D00094426F2624429FBC2C420004104000045D -:10D1E00024040018240500020C004DDB2406002056 -:10D1F0000C003E6D00000000100000030000000065 -:10D200003C010001AC226D9C8FBF001803E00008B8 -:10D2100027BD00208F8202008F8202208F82022091 -:10D2200034420004AF8202208F8202003C050001DC -:10D230008CA56D9834420004AF82020024020002E3 -:10D2400010A2004B2CA20003104000052402000194 -:10D2500010A2000A00000000100000B10000000051 -:10D260002402000410A200722402000810A200850B -:10D270003C02F0FF100000AA000000008F83005065 -:10D280003C02F0FF3442FFFF3C0400018C846F40FD -:10D29000006218243C0207000062182524020E00D8 -:10D2A0002484FFFB2C840002AF830050AF85020072 -:10D2B000AF85022014800006AF8202388F820044BE -:10D2C0003C03FFFF34633F7F00431024AF820044E0 -:10D2D0003C0300018C636F402402000514620004CB -:10D2E000000000008F82004434425000AF820044AE -:10D2F0003C0200018C426D883C0300018C636F404E -:10D30000344200222463FFFC2C6300021460000CF2 -:10D31000AF8202003C0200018C426DAC3C03000174 -:10D320008C636D903C0400018C846D8C34428000D1 -:10D3300000621825006418251000000A34620002FB -:10D340003C0200018C426D903C0300018C636DAC8B -:10D350003C0400018C846D8C004310250044102592 -:10D3600034420002AF8202201000002F240200018C -:10D3700024020E01AF8202388F8300503C02F0FF7E -:10D380003442FFFF3C0400018C846F1C00621824AF -:10D390003C020D000062182524020001AF830050FA -:10D3A000AF820200AF820220108000053C033F00E4 -:10D3B0003C0200018C426D80100000043463007058 -:10D3C0003C0200018C426D803463007200431025E2 -:10D3D000AF8202003C0300018C636D843C02F700C5 -:10D3E000006218253C0200018C426D903C04000153 -:10D3F0008C846DAC3C0500018CA56F40004310256A -:10D4000000441025AF8202202402000514A2000669 -:10D41000240200018F8200442403AFFF0043102444 -:10D42000AF820044240200011000003DAF820238A8 -:10D430008F8300503C02F0FF3442FFFF3C040001A8 -:10D440008C846F1C006218243C020A0000621825BC -:10D4500024020001AF830050AF8202001080001E42 -:10D46000AF8202203C0200018C426E441440001A3C -:10D470003C033F003C0200018C426D801000001A0A -:10D48000346300E08F8300503C0400018C846F1CE7 -:10D490003442FFFF006218241080000FAF83005059 -:10D4A0003C0200018C426E441440000B3C043F00DF -:10D4B0003C0300018C636D80348400E02402000191 -:10D4C000AF820200AF82022000641825AF83020001 -:10D4D000100000083C05F7003C0200018C426D8002 -:10D4E0003C033F00346300E200431025AF8202009A -:10D4F0003C05F70034A580003C0300018C636D847B -:10D500003C0200018C426D903C0400018C846DACA7 -:10D51000006518250043102500441025AF82022025 -:10D5200003E00008000000003C0300018C636DB4C0 -:10D530003C0200018C426DB810620003240200021C -:10D540003C010001AC236DB81062001D2C62000389 -:10D55000104000252402000114620023240200046C -:10D560003C0300018C636D981062000624020008E1 -:10D570001462000C3C0200C8344201FB1000000998 -:10D58000AF82023824020E01AF8202388F8200443B -:10D590003C03FFFF34633F7F00431024344200808C -:10D5A000AF8200448F830054240200023C0100013A -:10D5B000AC226DB43C0100011000000BAC236F2CB9 -:10D5C0008F8300543C0200018C426F2C2463D8F0FE -:10D5D000004310232C4227101440000324020009AA -:10D5E0003C010001AC226DB403E000080000000023 -:10D5F00000000000000000000000000027BDFFD870 -:10D60000AFB2001800809021AFB3001C00A0982199 -:10D61000AFB1001400C08821AFB00010000080211D -:10D62000AFBF0020A62000000C004D7824040001AC -:10D63000261000012E0200201440FFFB0000000015 -:10D640000C004D78000020210C004D7824040001CE -:10D650000C004D78240400010C004D7800002021BE -:10D66000241000100250102410400002000020215D -:10D67000240400010C004D78001080421600FFFACF -:10D6800002501024241000100270102410400002D8 -:10D6900000002021240400010C004D78001080427D -:10D6A0001600FFFA027010240C004DB934108000EF -:10D6B0000C004DB9000000000C004D5800000000A7 -:10D6C00050400005001080429622000000501025B6 -:10D6D000A6220000001080421600FFF700000000A4 -:10D6E0000C004DB9000000008FBF00208FB3001C5C -:10D6F0008FB200188FB100148FB0001003E0000843 -:10D7000027BD002827BDFFD8AFB1001400808821B5 -:10D71000AFB2001800A09021AFB3001C00C0982148 -:10D72000AFB0001000008021AFBF00200C004D788A -:10D7300024040001261000012E0200201440FFFBEB -:10D74000000000000C004D78000020210C004D78F6 -:10D75000240400010C004D78000020210C004D78BD -:10D760002404000124100010023010241040000294 -:10D7700000002021240400010C004D78001080429C -:10D780001600FFFA0230102424100010025010245A -:10D790001040000200002021240400010C004D78FC -:10D7A000001080421600FFFA025010240C004D7841 -:10D7B000240400010C004D7800002021341080006A -:10D7C000966200000050102410400002000020214A -:10D7D000240400010C004D78001080421600FFF870 -:10D7E000000000000C004DB9000000008FBF0020B9 -:10D7F0008FB3001C8FB200188FB100148FB00010CF -:10D8000003E0000827BD00283C0400018C846DD093 -:10D810003C0200018C426E1827BDFFD8AFBF00202C -:10D82000AFB1001C10820003AFB000183C01000132 -:10D83000AC246E183C0300018C636F402402000589 -:10D84000146200052483FFFF0C0049630000000000 -:10D850001000034C000000002C620013104003492C -:10D86000000310803C010001002208218C226B8003 -:10D8700000400008000000000C004DB900008021AD -:10D8800034028000A7A2001027B100100C004D78D0 -:10D8900024040001261000012E0200201440FFFB8A -:10D8A000000000000C004D78000020210C004D7895 -:10D8B000240400010C004D78000020210C004D785C -:10D8C0002404000124100010320200011040000264 -:10D8D00000002021240400010C004D78001080423B -:10D8E0001600FFFA32020001241000100C004D78DF -:10D8F00000002021001080421600FFFC0000000004 -:10D900000C004D78240400010C004D78000020210B -:10D9100034108000962200000050102410400002B5 -:10D9200000002021240400010C004D7800108042EA -:10D930001600FFF8000000000C004DB900000000C8 -:10D940001000030E2402000227B10010A7A000104F -:10D95000000080210C004D782404000126100001F5 -:10D960002E0200201440FFFB000000000C004D7848 -:10D97000000020210C004D78240400010C004D789B -:10D98000240400010C004D78000020212410001018 -:10D990003202000110400002000020212404000196 -:10D9A0000C004D78001080421600FFFA3202000190 -:10D9B000241000100C004D7800002021001080423F -:10D9C0001600FFFC000000000C004DB93410800070 -:10D9D0000C004DB9000000000C004D580000000084 -:10D9E0005040000500108042962200000050102593 -:10D9F000A6220000001080421600FFF70000000081 -:10DA00000C004DB90000000097A2001030428000C9 -:10DA1000144002DC24020003100002D800000000C1 -:10DA200024021200A7A2001027B1001000008021DC -:10DA30000C004D7824040001261000012E02002065 -:10DA40001440FFFB000000000C004D780000202176 -:10DA50000C004D78240400010C004D7800002021BA -:10DA60000C004D7824040001241000103202000143 -:10DA70001040000200002021240400010C004D7819 -:10DA8000001080421600FFFA32020001241000103C -:10DA90000C004D7800002021001080421600FFFC91 -:10DAA000000000000C004D78240400010C004D78AB -:10DAB0000000202134108000962200000050102425 -:10DAC0001040000200002021240400010C004D78C9 -:10DAD000001080421600FFF8000000000C004DB955 -:10DAE000000000008F8300541000029624020004FE -:10DAF0008F8300543C0200018C426F3C2463FF9CE6 -:10DB0000004310232C4200641440029E24020002B1 -:10DB10003C0300018C636F40106202972C6200038B -:10DB20001440029624020011240200031062000532 -:10DB300024020004106202912402000F1000028FE0 -:10DB4000240200111000028D24020005240200149A -:10DB5000A7A2001027B10010000080210C004D7812 -:10DB600024040001261000012E0200201440FFFBB7 -:10DB7000000000000C004D78000020210C004D78C2 -:10DB8000240400010C004D78000020210C004D7889 -:10DB90002404000124100010320200011040000291 -:10DBA00000002021240400010C004D780010804268 -:10DBB0001600FFFA32020001241000103202001297 -:10DBC0001040000200002021240400010C004D78C8 -:10DBD000001080421600FFFA320200120C004D784D -:10DBE000240400010C004D78000020213410800036 -:10DBF0009622000000501024104000020000202156 -:10DC0000240400010C004D78001080421600FFF83B -:10DC1000000000000C004DB9000000008F8300548C -:10DC200010000248240200068F8300543C020001C9 -:10DC30008C426F3C2463FF9C004310232C42006401 -:10DC400014400250240200071000024C00000000A3 -:10DC500024020006A7A2001027B1001000008021B6 -:10DC60000C004D7824040001261000012E02002033 -:10DC70001440FFFB000000000C004D780000202144 -:10DC80000C004D78240400010C004D780000202188 -:10DC90000C004D7824040001241000103202000111 -:10DCA0001040000200002021240400010C004D78E7 -:10DCB000001080421600FFFA32020001241000100A -:10DCC0003202001310400002000020212404000151 -:10DCD0000C004D78001080421600FFFA320200134B -:10DCE0000C004D78240400010C004D780000202128 -:10DCF00034108000962200000050102410400002D2 -:10DD000000002021240400010C004D780010804206 -:10DD10001600FFF8000000000C004DB900000000E4 -:10DD20008F83005410000207240200088F830054E0 -:10DD30003C0200018C426F3C2463FF9C0043102393 -:10DD40002C4200641440020F240200091000020B50 -:10DD50000000000027B10010A7A0001000008021E3 -:10DD60000C004D7824040001261000012E02002032 -:10DD70001440FFFB000000000C004D780000202143 -:10DD80000C004D78240400010C004D78240400019F -:10DD90000C004D78000020212410001032020001F8 -:10DDA0001040000200002021240400010C004D78E6 -:10DDB000001080421600FFFA320200012410001009 -:10DDC000320200181040000200002021240400014B -:10DDD0000C004D78001080421600FFFA3202001845 -:10DDE0000C004DB9341080000C004DB9000000004B -:10DDF0000C004D580000000050400005001080420B -:10DE00009622000000501025A6220000001080423B -:10DE10001600FFF7000000000C004DB90000802143 -:10DE200097A2001027B1001034420001A7A20010F1 -:10DE30000C004D7824040001261000012E02002061 -:10DE40001440FFFB000000000C004D780000202172 -:10DE50000C004D78240400010C004D7800002021B6 -:10DE60000C004D782404000124100010320200013F -:10DE70001040000200002021240400010C004D7815 -:10DE8000001080421600FFFA320200012410001038 -:10DE9000320200181040000200002021240400017A -:10DEA0000C004D78001080421600FFFA3202001874 -:10DEB0000C004D78240400010C004D780000202156 -:10DEC0003410800096220000005010241040000200 -:10DED00000002021240400010C004D780010804235 -:10DEE0001600FFF8000000000C004DB90000000013 -:10DEF0008F830054100001932402000A8F83005482 -:10DF00003C0200018C426F3C2463FF9C00431023C1 -:10DF10002C4200641440019B2402000B1000019766 -:10DF20000000000027B10010A7A000100000802111 -:10DF30000C004D7824040001261000012E02002060 -:10DF40001440FFFB000000000C004D780000202171 -:10DF50000C004D78240400010C004D7824040001CD -:10DF60000C004D7800002021241000103202000126 -:10DF70001040000200002021240400010C004D7814 -:10DF8000001080421600FFFA320200012410001037 -:10DF9000320200171040000200002021240400017A -:10DFA0000C004D78001080421600FFFA3202001774 -:10DFB0000C004DB9341080000C004DB90000000079 -:10DFC0000C004D5800000000504000050010804239 -:10DFD0009622000000501025A6220000001080426A -:10DFE0001600FFF7000000000C004DB90000802172 -:10DFF00097A2001027B1001034420700A7A200101A -:10E000000C004D7824040001261000012E0200208F -:10E010001440FFFB000000000C004D7800002021A0 -:10E020000C004D78240400010C004D7800002021E4 -:10E030000C004D782404000124100010320200016D -:10E040001040000200002021240400010C004D7843 -:10E05000001080421600FFFA320200012410001066 -:10E0600032020017104000020000202124040001A9 -:10E070000C004D78001080421600FFFA32020017A3 -:10E080000C004D78240400010C004D780000202184 -:10E09000341080009622000000501024104000022E -:10E0A00000002021240400010C004D780010804263 -:10E0B0001600FFF8000000000C004DB90000000041 -:10E0C0008F8300541000011F2402000C8F83005422 -:10E0D0003C0200018C426F3C2463FF9C00431023F0 -:10E0E0002C42006414400127240200121000012376 -:10E0F0000000000027B10010A7A000100000802140 -:10E100000C004D7824040001261000012E0200208E -:10E110001440FFFB000000000C004D78000020219F -:10E120000C004D78240400010C004D7824040001FB -:10E130000C004D7800002021241000103202000154 -:10E140001040000200002021240400010C004D7842 -:10E15000001080421600FFFA320200012410001065 -:10E1600032020014104000020000202124040001AB -:10E170000C004D78001080421600FFFA32020014A5 -:10E180000C004DB9341080000C004DB900000000A7 -:10E190000C004D5800000000504000050010804267 -:10E1A0009622000000501025A62200000010804298 -:10E1B0001600FFF7000000000C004DB900008021A0 -:10E1C00097A2001027B1001034420010A7A200103F -:10E1D0000C004D7824040001261000012E020020BE -:10E1E0001440FFFB000000000C004D7800002021CF -:10E1F0000C004D78240400010C004D780000202113 -:10E200000C004D782404000124100010320200019B -:10E210001040000200002021240400010C004D7871 -:10E22000001080421600FFFA320200012410001094 -:10E2300032020014104000020000202124040001DA -:10E240000C004D78001080421600FFFA32020014D4 -:10E250000C004D78240400010C004D7800002021B2 -:10E26000341080009622000000501024104000025C -:10E2700000002021240400010C004D780010804291 -:10E280001600FFF8000000000C004DB9000000006F -:10E290008F830054100000AB240200138F830054BE -:10E2A0003C0200018C426F3C2463FF9C004310231E -:10E2B0002C420064144000B32402000D100000AF93 -:10E2C0000000000027B10010A7A00010000080216E -:10E2D0000C004D7824040001261000012E020020BD -:10E2E0001440FFFB000000000C004D7800002021CE -:10E2F0000C004D78240400010C004D78240400012A -:10E300000C004D7800002021241000103202000182 -:10E310001040000200002021240400010C004D7870 -:10E32000001080421600FFFA320200012410001093 -:10E3300032020018104000020000202124040001D5 -:10E340000C004D78001080421600FFFA32020018CF -:10E350000C004DB9341080000C004DB900000000D5 -:10E360000C004D5800000000504000050010804295 -:10E370009622000000501025A622000000108042C6 -:10E380001600FFF7000000000C004DB900008021CE -:10E3900097A2001027B100103042FFFEA7A2001084 -:10E3A0000C004D7824040001261000012E020020EC -:10E3B0001440FFFB000000000C004D7800002021FD -:10E3C0000C004D78240400010C004D780000202141 -:10E3D0000C004D78240400012410001032020001CA -:10E3E0001040000200002021240400010C004D78A0 -:10E3F000001080421600FFFA3202000124100010C3 -:10E400003202001810400002000020212404000104 -:10E410000C004D78001080421600FFFA32020018FE -:10E420000C004D78240400010C004D7800002021E0 -:10E43000341080009622000000501024104000028A -:10E4400000002021240400010C004D7800108042BF -:10E450001600FFF8000000000C004DB9000000009D -:10E460008F830054100000372402000E240208405D -:10E47000A7A2001027B10010000080210C004D78E9 -:10E4800024040001261000012E0200201440FFFB8E -:10E49000000000000C004D78000020210C004D7899 -:10E4A000240400010C004D78000020210C004D7860 -:10E4B0002404000124100010320200011040000268 -:10E4C00000002021240400010C004D78001080423F -:10E4D0001600FFFA3202000124100010320200136D -:10E4E0001040000200002021240400010C004D789F -:10E4F000001080421600FFFA320200130C004D7823 -:10E50000240400010C004D7800002021341080000C -:10E51000962200000050102410400002000020212C -:10E52000240400010C004D78001080421600FFF812 -:10E53000000000000C004DB9000000008F83005463 -:10E54000240200103C010001AC226DD03C0100010E -:10E550001000000CAC236F3C8F8300543C02000180 -:10E560008C426F3C2463FF9C004310232C420064C8 -:10E570001440000400000000240200113C010001CE -:10E58000AC226DD08FBF00208FB1001C8FB000185F -:10E5900003E0000827BD00283C0300018C636D9850 -:10E5A00027BDFFC824020002AFBF0034AFB2003065 -:10E5B000AFB1002C14620004AFB000283C1200027E -:10E5C000100000038E528FF83C1200028E528FFC16 -:10E5D0003C0300018C636DD43C0200018C426E1C34 -:10E5E000506200042463FFFF3C010001AC236E1C59 -:10E5F0002463FFFF2C6200061040037700031080A5 -:10E600003C010001002208218C226BD80040000848 -:10E610000000000000002021000028210C004DDB3C -:10E6200034068000240400102405000224060002A1 -:10E63000240200020C004DDBA7A2001824020002F5 -:10E640003C01000110000364AC226DD427B1001816 -:10E65000A7A00018000080210C004D7824040001C0 -:10E66000261000012E0200201440FFFB00000000D5 -:10E670000C004D78000020210C004D78240400018E -:10E680000C004D78240400010C004D78000020217E -:10E69000241000103202000110400002000020216E -:10E6A000240400010C004D78001080421600FFFA8F -:10E6B00032020001241000100C004D7800002021CF -:10E6C000001080421600FFFC000000000C004DB955 -:10E6D000341080000C004DB9000000000C004D58B3 -:10E6E000000000005040000500108042962200000B -:10E6F00000501025A6220000001080421600FFF7EF -:10E70000000000000C004DB90000000097A20018A6 -:10E710003042800014400004240200033C01000148 -:10E72000AC226DD4240200033C0100011000032A36 -:10E73000AC226DD42404001024050002240600023B -:10E74000240200020C004DDBA7A200183C030001CC -:10E750008C636E2024020001146201E1000080211C -:10E7600027B10018A7A000180C004D782404000160 -:10E77000261000012E0200201440FFFB00000000C4 -:10E780000C004D78000020210C004D78240400017D -:10E790000C004D78240400010C004D78000020216D -:10E7A000241000103202000110400002000020215D -:10E7B000240400010C004D78001080421600FFFA7E -:10E7C0003202000124100010320200181040000232 -:10E7D00000002021240400010C004D78001080422C -:10E7E0001600FFFA320200180C004DB934108000F8 -:10E7F0000C004DB9000000000C004D580000000056 -:10E800005040000500108042962200000050102564 -:10E81000A6220000001080421600FFF70000000052 -:10E820000C004DB90000802127B10018A7A00018E6 -:10E830000C004D7824040001261000012E02002057 -:10E840001440FFFB000000000C004D780000202168 -:10E850000C004D78240400010C004D7824040001C4 -:10E860000C004D780000202124100010320200011D -:10E870001040000200002021240400010C004D780B -:10E88000001080421600FFFA32020001241000102E -:10E890003202001810400002000020212404000170 -:10E8A0000C004D78001080421600FFFA320200186A -:10E8B0000C004DB9341080000C004DB90000000070 -:10E8C0000C004D5800000000504000050010804230 -:10E8D0009622000000501025A62200000010804261 -:10E8E0001600FFF7000000000C004DB90000802169 -:10E8F00024040018000028210C004DDB2406040429 -:10E90000A7A0001A0C004D78240400012610000175 -:10E910002E0200201440FFFB000000000C004D7888 -:10E92000000020210C004D78240400010C004D78DB -:10E93000240400010C004D78000020212410001058 -:10E9400032020001104000020000202124040001D6 -:10E950000C004D78001080421600FFFA32020001D0 -:10E960002410001032020018104000020000202184 -:10E97000240400010C004D78001080421600FFFABC -:10E98000320200180C004DB9341080000C004DB953 -:10E99000000000000C004D58000000005040000531 -:10E9A0000010804297A2001A00501025A7A2001A5A -:10E9B000001080421600FFF7000000000C004DB967 -:10E9C00000008021A7A0001A0C004D78240400014B -:10E9D000261000012E0200201440FFFB0000000062 -:10E9E0000C004D78000020210C004D78240400011B -:10E9F0000C004D78240400010C004D78000020210B -:10EA000024100010320200011040000200002021FA -:10EA1000240400010C004D78001080421600FFFA1B -:10EA200032020001241000103202001810400002CF -:10EA300000002021240400010C004D7800108042C9 -:10EA40001600FFFA320200180C004DB93410800095 -:10EA50000C004DB9000000000C004D5800000000F3 -:10EA6000504000050010804297A2001A0050102567 -:10EA7000A7A2001A001080421600FFF70000000055 -:10EA80000C004DB900008021A7A0001C0C004D789F -:10EA900024040001261000012E0200201440FFFB78 -:10EAA000000000000C004D78000020210C004D7883 -:10EAB000240400010C004D78240400010C004D7862 -:10EAC00000002021241000100C004D7800002021AF -:10EAD000001080421600FFFC00000000241000100F -:10EAE0003202001E10400002000020212404000118 -:10EAF0000C004D78001080421600FFFA3202001E12 -:10EB00000C004DB9341080000C004DB9000000001D -:10EB10000C004D58000000005040000500108042DD -:10EB200097A2001C00501025A7A2001C00108042D4 -:10EB30001600FFF7000000000C004DB90000802116 -:10EB4000A7A0001C0C004D78240400012610000131 -:10EB50002E0200201440FFFB000000000C004D7846 -:10EB6000000020210C004D78240400010C004D7899 -:10EB7000240400010C004D78000020212410001016 -:10EB80000C004D7800002021001080421600FFFC90 -:10EB900000000000241000103202001E104000028D -:10EBA00000002021240400010C004D780010804258 -:10EBB0001600FFFA3202001E0C004DB9341080001E -:10EBC0000C004DB9000000000C004D580000000082 -:10EBD000504000050010804297A2001C00501025F4 -:10EBE000A7A2001C001080421600FFF700000000E2 -:10EBF0000C004DB90000802124020002A7A2001ED3 -:10EC00000C004D7824040001261000012E02002083 -:10EC10001440FFFB000000000C004D780000202194 -:10EC20000C004D78240400010C004D7800002021D8 -:10EC30000C004D7824040001241000100C004D78C5 -:10EC400000002021001080421600FFFC00000000A0 -:10EC5000241000103202001E10400002000020218B -:10EC6000240400010C004D78001080421600FFFAC9 -:10EC70003202001E0C004D78240400010C004D7877 -:10EC8000000020213410800097A2001E00501024A4 -:10EC90001040000200002021240400010C004D78E7 -:10ECA000001080421600FFF8000000000C004DB973 -:10ECB00000008021A7A000200C004D782404000152 -:10ECC000261000012E0200201440FFFB000000006F -:10ECD0000C004D78000020210C004D782404000128 -:10ECE0000C004D78240400010C004D780000202118 -:10ECF000241000100C004D780000202100108042EC -:10ED00001600FFFC00000000241000103202001E5C -:10ED10001040000200002021240400010C004D7866 -:10ED2000001080421600FFFA3202001E0C004DB99E -:10ED3000341080000C004DB9000000000C004D584C -:10ED400000000000504000050010804297A2002003 -:10ED500000501025A7A20020001080421600FFF7E7 -:10ED6000000000000C004DB900008021A7A0002089 -:10ED70000C004D7824040001261000012E02002012 -:10ED80001440FFFB000000000C004D780000202123 -:10ED90000C004D78240400010C004D78240400017F -:10EDA0000C004D7800002021241000100C004D783C -:10EDB00000002021001080421600FFFC000000002F -:10EDC000241000103202001E10400002000020211A -:10EDD000240400010C004D78001080421600FFFA58 -:10EDE0003202001E0C004DB9341080000C004DB9E9 -:10EDF000000000000C004D580000000050400005CD -:10EE00000010804297A2002000501025A7A20020E9 -:10EE1000001080421600FFF7000000000C004DB902 -:10EE200000008021A7A000220C004D7824040001DE -:10EE3000261000012E0200201440FFFB00000000FD -:10EE40000C004D78000020210C004D7824040001B6 -:10EE50000C004D78000020210C004D7824040001A6 -:10EE6000241000100C004D7800002021001080427A -:10EE70001600FFFC00000000241000100C004D786C -:10EE800000002021001080421600FFFC000000005E -:10EE90000C004D78240400010C004D780000202166 -:10EEA0003410800097A2002200501024104000026D -:10EEB00000002021240400010C004D780010804245 -:10EEC0001600FFF8000000000C004DB90000000023 -:10EED00024040018240500020C004DDB2406000465 -:10EEE0003C1000018E106E24240200011602011D48 -:10EEF000000000003C02000194426F263C0100012A -:10EF0000AC206E2424429FBC2C4200041040000C14 -:10EF100024040009240500010C004DDB2406040034 -:10EF200024040018240500010C004DDB24060020F9 -:10EF300024040018240500010C004DDB24062000E9 -:10EF40003C02400002421024104001233C022000F9 -:10EF50000242102410400004000000003C010001A7 -:10EF600010000003AC306F1C3C010001AC206F1C92 -:10EF70003C0300018C636F3424020005146200F925 -:10EF8000000000003C0200018C426F1C1040006732 -:10EF90003C0200040242102410400011A7A00018F7 -:10EFA0003C02000802421024104000022402020029 -:10EFB000A7A200183C0200100242102410400004D6 -:10EFC0000000000097A2001834420100A7A2001818 -:10EFD00097A600182404000910000004000028214E -:10EFE0002404000900002821000030210C004DDB22 -:10EFF0000000000024020001A7A2001A3C02000841 -:10F00000024210241040000C3C0200020242102474 -:10F010001040000224020101A7A2001A3C020001D4 -:10F0200002421024104000053C02001097A2001A72 -:10F0300034420040A7A2001A3C02001002421024F1 -:10F040001040000E3C020002024210241040000555 -:10F050003C02000197A2001A34420080A7A2001AC5 -:10F060003C02000102421024104000053C0300A0B5 -:10F0700097A2001A34420020A7A2001A3C0300A065 -:10F0800002431024544300043C02002097A2001ABB -:10F090001000000C344204000242102450400004CE -:10F0A0003C02008097A2001A1000000634420800BB -:10F0B00002421024104000040000000097A2001A31 -:10F0C00034420C00A7A2001A97A6001A24040004D8 -:10F0D0000C004DDB000028213C02000402421024F9 -:10F0E00010400004A7A0001C32425000144000044D -:10F0F00000000000324240001040000500002021C6 -:10F100000C004CF902402021100000960000000085 -:10F1100097A6001C0000282134C612000C004DDB0D -:10F12000A7A6001C1000008F00000000024210245F -:10F1300010400004A7A00018324250001440000400 -:10F140000000000032424000104000053C02001068 -:10F150000C004CF90240202110000019A7A0001A51 -:10F1600002421024104000040000000097A2001882 -:10F1700010000004A7A2001897A200183442010052 -:10F18000A7A200183C020001024210241040000413 -:10F190000000000097A2001810000004A7A20018A9 -:10F1A00097A2001834422000A7A2001897A60018C2 -:10F1B000000020210C004DDB00002821A7A0001A30 -:10F1C000000080210C004D7824040001261000016D -:10F1D0002E0200201440FFFB000000000C004D78C0 -:10F1E000000020210C004D78240400010C004D7813 -:10F1F000240400010C004D78000020212410001090 -:10F20000320200011040000200002021240400010D -:10F210000C004D78001080421600FFFA3202000107 -:10F22000241000100C004D780000202100108042B6 -:10F230001600FFFC000000000C004DB934108000E7 -:10F240000C004DB9000000000C004D5800000000FB -:10F25000504000050010804297A2001A005010256F -:10F26000A7A2001A001080421600FFF7000000005D -:10F270000C004DB900008021A7A0001A0C004D78A9 -:10F2800024040001261000012E0200201440FFFB80 -:10F29000000000000C004D78000020210C004D788B -:10F2A000240400010C004D78240400010C004D786A -:10F2B0000000202124100010320200011040000242 -:10F2C00000002021240400010C004D780010804231 -:10F2D0001600FFFA32020001241000100C004D78D5 -:10F2E00000002021001080421600FFFC00000000FA -:10F2F0000C004DB9341080000C004DB90000000026 -:10F300000C004D58000000005040000500108042E5 -:10F3100097A2001A00501025A7A2001A00108042E0 -:10F320001600FFF7000000000C004DB900000000BF -:10F330003C04000124846BCC97A6001897A7001A00 -:10F340003C0200018C426D983C0300018C636F1CF1 -:10F350003C05000D34A50205AFA200100C002B3BAC -:10F36000AFA300148F830054240200043C01000169 -:10F37000AC226DD43C01000110000017AC236F38A3 -:10F380008F8300543C0200018C426F382463FF9C41 -:10F39000004310232C4200641440000F00000000C2 -:10F3A0008F820220240300053C010001AC236DD4B0 -:10F3B0003C03F7000043102510000007AF82022035 -:10F3C000240200063C010001AC226DD4240200118D -:10F3D0003C010001AC226DD08FBF00348FB20030F1 -:10F3E0008FB1002C8FB0002803E0000827BD003843 -:10F3F00027BDFFD8AFB0001800808021AFB1001C3E -:10F40000000088213202400010400013AFBF0020EE -:10F410003C020010020210242C42000100021023C2 -:10F42000304341003C020001020210241440000657 -:10F43000347140003C020002020210241440000219 -:10F440003471600034714040000020210000282108 -:10F45000100000360220302132021000104000352A -:10F4600000002021000028210C004DDB2406004074 -:10F4700024040018000028210C004DDB24060C0099 -:10F4800024040017000028210C004DDB2406040092 -:10F4900024040016000028210C004DDB2406000681 -:10F4A00024040017000028210C004DDB2406250051 -:10F4B00024040016000028210C004DDB2406000661 -:10F4C00024040017000028210C004DDB2406460010 -:10F4D00024040016000028210C004DDB2406000641 -:10F4E00024040017000028210C004DDB24066700CF -:10F4F00024040016000028210C004DDB2406000621 -:10F500002404001F000028210C004DDB24060010FD -:10F5100024040009000028210C004DDB24061500FE -:10F52000240400090000282124061D000C004DDBE6 -:10F53000000000003C04000124846BF03C05000E38 -:10F5400034A501000200302102203821AFA00010B4 -:10F550000C002B3BAFA000148FBF00208FB1001C0C -:10F560008FB0001803E0000827BD00288F850044F5 -:10F570008F8200443C030001004310253C03000837 -:10F58000AF8200448F8400548F82005400A328244B -:10F5900010000002248400018F8200540082102396 -:10F5A0002C4200021440FFFC000000008F82004447 -:10F5B0003C03FFFE3463FFFF00431024AF8200448E -:10F5C0008F8300548F8200541000000224630001D6 -:10F5D0008F820054006210232C4200021440FFFC72 -:10F5E0000000000003E0000800A010218F83004409 -:10F5F0003C02FFF03442FFFF000424800062182424 -:10F600003C0200020082202500641825AF830044DC -:10F610008F8200443C03FFFE3463FFFF004310244D -:10F62000AF8200448F8300548F8200541000000288 -:10F63000246300018F820054006210232C420002D8 -:10F640001440FFFC000000008F8200443C030001D6 -:10F6500000431025AF8200448F8300548F820054F2 -:10F6600010000002246300018F8200540062102306 -:10F670002C4200021440FFFC0000000003E00008E0 -:10F68000000000008F8200442403FF7F0043102409 -:10F69000AF8200448F8300548F8200541000000218 -:10F6A000246300018F820054006210232C42000268 -:10F6B0001440FFFC000000008F82004434420080B0 -:10F6C000AF8200448F8300548F82005410000002E8 -:10F6D000246300018F820054006210232C42000238 -:10F6E0001440FFFC0000000003E0000800000000E0 -:10F6F0008F8200443C03FFF03463FFFF004310247B -:10F70000AF8200448F8200443C0300010043102577 -:10F71000AF8200448F8300548F8200541000000297 -:10F72000246300018F820054006210232C420002E7 -:10F730001440FFFC000000008F8200443C03FFFEE9 -:10F740003463FFFF00431024AF8200448F830054D2 -:10F750008F82005410000002246300018F82005445 -:10F76000006210232C4200021440FFFC0000000045 -:10F7700003E000080000000027BDFFC8AFB300246D -:10F7800000809821AFBE002C00A0F021AFB2002075 -:10F7900000C0902133C2FFFFAFBF0030AFB50028DB -:10F7A000AFB1001CAFB0001814400034A7B2001075 -:10F7B0003271FFFF27B20010000080210C004D784D -:10F7C00024040001261000012E0200201440FFFB3B -:10F7D000000000000C004D78000020210C004D7846 -:10F7E000240400010C004D78000020210C004D780D -:10F7F0002404000124100010320200011040000215 -:10F8000000002021240400010C004D7800108042EB -:10F810001600FFFA320200012410001002301024FA -:10F820001040000200002021240400010C004D784B -:10F83000001080421600FFFA023010240C004D78B0 -:10F84000240400010C004D780000202134108000B9 -:10F8500096420000005010241040000200002021B9 -:10F86000240400010C004D78001080421200007545 -:10F87000000000001000FFF6000000003275FFFFDE -:10F8800027B10010A7A00010000080210C004D78C7 -:10F8900024040001261000012E0200201440FFFB6A -:10F8A000000000000C004D78000020210C004D7875 -:10F8B000240400010C004D78240400010C004D7854 -:10F8C000000020212410001032020001104000022C -:10F8D00000002021240400010C004D78001080421B -:10F8E0001600FFFA320200012410001002B01024AA -:10F8F0001040000200002021240400010C004D787B -:10F90000001080421600FFFA02B010240C004DB91E -:10F91000341080000C004DB9000000000C004D5860 -:10F9200000000000504000050010804296220000B8 -:10F9300000501025A6220000001080421600FFF79C -:10F94000000000000C004DB90000000033C5FFFFAF -:10F950002402000154A200042402000297A2001015 -:10F96000100000060052102514A200063271FFFF9D -:10F9700097A200100012182700431024A7A200101D -:10F980003271FFFF27B20010000080210C004D787B -:10F9900024040001261000012E0200201440FFFB69 -:10F9A000000000000C004D78000020210C004D7874 -:10F9B000240400010C004D78000020210C004D783B -:10F9C0002404000124100010320200011040000243 -:10F9D00000002021240400010C004D78001080421A -:10F9E0001600FFFA32020001241000100230102429 -:10F9F0001040000200002021240400010C004D787A -:10FA0000001080421600FFFA023010240C004D78DE -:10FA1000240400010C004D780000202134108000E7 -:10FA200096420000005010241040000200002021E7 -:10FA3000240400010C004D78001080421600FFF8ED -:10FA4000000000000C004DB9000000008FBF003026 -:10FA50008FBE002C8FB500288FB300248FB20020FA -:10FA60008FB1001C8FB0001803E0000827BD0038DC -:10FA700000000000000000000000000027BDFFE8BB -:10FA8000AFBF00108EE304B824020008146201E046 -:10FA9000000000003C0200018C426F1C1440000575 -:10FAA000000000000C003DAF8F840224100001D83C -:10FAB000000000008F8202203C0300080043102455 -:10FAC00010400026240200018F8402248F8202202D -:10FAD0003C03040000431024104000060000000016 -:10FAE0003C010002AC208FA03C0100021000000B82 -:10FAF000AC208FC03C03000224638FA08C62000006 -:10FB000024420001AC6200002C42000214400003B9 -:10FB1000240200013C010002AC228FC03C02000222 -:10FB20008C428FC01040000630820040104000041C -:10FB3000240200013C01000210000003AC228FC42B -:10FB40003C010002AC208FC43C010002AC248F9C1D -:10FB50003C0100021000000BAC208FD03C010002E1 -:10FB6000AC228FD03C010002AC208FC03C010002CF -:10FB7000AC208FA03C010002AC208FC43C010002ED -:10FB8000AC208F9C3C0300028C638F903C020002EF -:10FB90008C428F94506200042463FFFF3C010002FA -:10FBA000AC238F942463FFFF2C62000E104001945D -:10FBB000000310803C010001002208218C226C000F -:10FBC0000040000800000000240200023C01000286 -:10FBD000AC208FC03C010002AC208FA03C01000291 -:10FBE000AC208F9C3C010002AC208FC43C01000281 -:10FBF000AC208FB83C010002AC208FB0AF80022453 -:10FC00003C010002AC228F903C0200028C428FD05B -:10FC10001440004F3C02FDFF3442FFFF0C003DAF9B -:10FC20000282A024AF8002048F8202002403FFFD21 -:10FC300000431024AF8202003C010002AC208FE0A0 -:10FC40008F8300543C0200028C428FB824040001D0 -:10FC50003C010002AC248FCC244200013C01000294 -:10FC6000AC228FB82C4200043C010002AC238FB4BC -:10FC700014400006240200033C010001AC246D9CEA -:10FC80003C0100021000015EAC208FB83C01000274 -:10FC90001000015BAC228F908F8300543C02000265 -:10FCA0008C428FB42463D8F0004310232C422710D9 -:10FCB00014400003240200043C010002AC228F9097 -:10FCC0003C0200028C428FD0144000213C02FDFF18 -:10FCD0003442FFFF1000014A0282A0243C040001CC -:10FCE0008C846F203C0100020C005084AC208FA853 -:10FCF0003C0200028C428FDCAF8202043C02000214 -:10FD00008C428FD0144000123C03FDFF8F8202040E -:10FD10003463FFFF304200301440012F0283A024DF -:10FD20003C0300028C638FDC240200053C010002CE -:10FD3000AC228F903C01000210000131AC238FE017 -:10FD40003C0200028C428FD0104000103C02FDFFAC -:10FD50003C0200018C426E3C244200013C01000147 -:10FD6000AC226E3C2C42000214400125240200010A -:10FD70003C010001AC226E443C010001AC206E3C11 -:10FD80003C0100011000011EAC226D9C3C030002EE -:10FD90008C638FC03442FFFF106001190282A024DF -:10FDA0003C0200028C428F9C1040011500000000B4 -:10FDB0003C010002AC228FC8240200033C01000277 -:10FDC000AC228FA0100000B8240200063C01000203 -:10FDD000AC208FA88F82020434420040AF8202041C -:10FDE0003C0200028C428FE0240300073C01000229 -:10FDF000AC238F90344200403C010002AC228FE0E3 -:10FE00003C0200028C428FC0104000050000000040 -:10FE10003C0200028C428F9C104000F02402000241 -:10FE20003C05000224A58FA08CA200002C424E218C -:10FE3000104000EA240200023C0200028C428FC4FF -:10FE4000104000EF2404FFBF3C0200028C428F9C54 -:10FE50003C0300028C638FC8004410240064182403 -:10FE600010430004240200013C010002100000E4E1 -:10FE7000AC228F9024020003ACA2000024020008F0 -:10FE80003C010002AC228F903C0200028C428FCCDD -:10FE90001040000C240200013C0400020C005091B0 -:10FEA0008C848F9C3C0200028C428FE81440000539 -:10FEB000240200013C0200028C428FE41040000644 -:10FEC000240200013C010001AC226D9C3C010002B7 -:10FED000100000CBAC208FB83C0200028C428FB0E7 -:10FEE0003C0300028C638F9C2C420001000210C076 -:10FEF000306300083C010002AC228FB03C010002DC -:10FF0000AC238FAC8F830054240200093C01000213 -:10FF1000AC228F903C010002100000B9AC238FB4DA -:10FF20008F8300543C0200028C428FB42463D8F0CB -:10FF3000004310232C4227101440009F00000000B3 -:10FF40003C0200028C428FC01040000500000000FF -:10FF50003C0200028C428F9C104000A02402000250 -:10FF60003C03000224638FA08C6200002C424E21CF -:10FF70001040009A240200023C0200028C428FCC06 -:10FF80001040000E000000003C0200028C428F9CDA -:10FF90003C010002AC208FCC304200801040002F8A -:10FFA0002402000C8F820204304200801440000CB6 -:10FFB00024020003100000292402000C3C0200026D -:10FFC0008C428F9C304200801440000524020003C4 -:10FFD0008F820204304200801040001F2402000380 -:10FFE000AC6200002402000A3C010002AC228F90A7 -:10FFF0003C04000224848FD88C8200003C03000261 -:020000021000EC -:100000008C638FB000431025AF8202048C83000004 -:100010003C0400028C848FB02402000B3C010002DF -:10002000AC228F90006418253C010002AC238FE0C5 -:100030003C05000224A58FA08CA200002C424E217A -:1000400010400066240200023C0200028C428FD065 -:1000500010400005000000002402000C3C010002DA -:1000600010000067AC228F903C0200028C428FC0CF -:1000700010400063000000003C0400028C848F9C50 -:1000800010800055308200083C0300028C638FAC66 -:100090001062005B240200033C010002AC248FC804 -:1000A000ACA20000240200063C0100021000005433 -:1000B000AC228F908F82020034420002AF82020095 -:1000C0008F8300542402000D3C010002AC228F906B -:1000D0003C010002AC238FB48F8300543C02000229 -:1000E0008C428FB42463D8F0004310232C42271095 -:1000F00014400031000000003C0200028C428FD00E -:10010000104000202402000E3C0300028C638FE4A8 -:100110003C01000214600015AC228F900C003E6D73 -:10012000000000003C0500018CA56D980C00529B5E -:10013000000020213C0300018C636D982402000420 -:10014000146200052403FFFB3C0200018C426D9405 -:10015000100000032403FFF73C0200018C426D9461 -:10016000004310243C010001AC226D948F830224D3 -:100170003C0202003C010002AC238FEC1000002086 -:100180000282A0253C0200028C428FC01040000574 -:10019000000000003C0200028C428F9C1040000FC7 -:1001A000240200023C0200028C428FA02C424E210D -:1001B0001040000A240200023C0200028C428FC060 -:1001C0001040000F000000003C0200028C428F9C97 -:1001D0001440000B00000000240200023C01000259 -:1001E00010000007AC228F903C0200028C428FC0AE -:1001F00010400003000000000C003DAF00000000B4 -:100200008F8202203C03F70000431025AF820220BA -:100210008FBF001003E0000827BD00183C03000258 -:1002200024638FE88C6200001040000534422000F7 -:100230003C010002AC228FDC10000003AC60000027 -:100240003C010002AC248FDC03E000080000000049 -:1002500027BDFFE030820030AFBF00183C01000234 -:10026000AC228FE4144000673C02FFFF34421F0EB3 -:1002700000821024144000612402003030822000EB -:100280001040005D3083800000031A0230820001BC -:10029000000212003C0400018C846F2000621825CB -:1002A000000331C23C03000124636E4830828000A9 -:1002B00000021202308400010004220000441025D4 -:1002C000000239C2000610800043102100471021AF -:1002D000904300002402000110620025000000008D -:1002E00010600007240200021062001324020003C1 -:1002F0001062002C3C05000F1000003700000000C9 -:100300008F8202002403FEFF00431024AF8202000C -:100310008F8202203C03FFFE3463FFFF0043102462 -:10032000AF8202203C010002AC2090043C0100029C -:1003300010000034AC20900C8F8202003442010087 -:10034000AF8202008F8202203C03FFFE3463FFFF76 -:1003500000431024AF820220240201003C0100026D -:10036000AC2290043C01000210000026AC20900C4E -:100370008F8202002403FEFF00431024AF8202009C -:100380008F8202203C03000100431025AF8202202F -:100390003C010002AC2090043C0100021000001956 -:1003A000AC23900C8F82020034420100AF82020025 -:1003B0008F8202203C03000100431025AF820220FF -:1003C000240201003C010002AC2290043C01000226 -:1003D0001000000CAC23900C34A5FFFF3C0400017E -:1003E00024846C38AFA300100C002B3BAFA000148A -:1003F0001000000400000000240200303C01000254 -:10040000AC228FE88FBF001803E0000827BD002052 -:1004100000000000000000000000000027BDFFC831 -:10042000AFB2002800809021AFB3002C00A098212B -:10043000AFB0002000C080213C04000124846C5037 -:100440003C0500093C0200018C426D9834A59001E6 -:100450000240302102603821AFBF0030AFB100242C -:10046000A7A0001AAFB000140C002B3BAFA20010E5 -:1004700024020002126200832E6200031040000575 -:10048000240200011262000A000000001000017343 -:100490000000000024020004126200F82402000898 -:1004A000126200F73C02FFEC1000016C000000003B -:1004B0003C0200018C426D94304200021440000462 -:1004C000001289403C02FFFB3442FFFF02028024FD -:1004D0003C01000200310821AC308FFC3C0240009E -:1004E000020210241040004E001023C2308400305D -:1004F000001013823042001C3C03000124636DD8BD -:1005000000431021008238213C0200200202102406 -:1005100010400006240201003C01000200310821C5 -:10052000AC229000100000053C0200803C0100025B -:1005300000310821AC2090003C020080020210240F -:1005400010400006001219403C0200013C0100026C -:100550000023082110000005AC2290080012114071 -:100560003C01000200220821AC20900894E4000025 -:100570003C0300018C636F402402000510620010F0 -:10058000A7A400183202400010400002348240004C -:10059000A7A200182404000194E20002240500042C -:1005A00024E60002344200010C0045BEA4E2000231 -:1005B00024040001000028210C0045BE27A60018D5 -:1005C0003C0200018C426D98241100013C010001A5 -:1005D000AC316DA414530004320280000C003DAF16 -:1005E00000000000320280001040011C00000000EA -:1005F0000C003DAF000000003C0300018C636F4025 -:100600002402000510620115240200023C010001D1 -:10061000AC316D9C3C01000110000110AC226D98C2 -:10062000240400012405000427B0001A0C0045BE74 -:100630000200302124040001000028210C0045BEE6 -:10064000020030213C020002005110218C428FF444 -:100650003C0400018C846D983C03BFFF3463FFFFB2 -:100660003C010001AC336DA4004310243C010002A6 -:1006700000310821109300F7AC228FF4100000F72E -:10068000000000003C02200002021024104000057F -:10069000240200013C010001AC226F1C1000000488 -:1006A000001289403C010001AC206F1C00128940FF -:1006B0003C01000200310821AC308FF83C024000C0 -:1006C0000202102414400014000000003C0200014B -:1006D0008C426F1C10400006240400042405000115 -:1006E0000C004DDB2406200024020001AEE204B819 -:1006F0003C020002005110218C428FF03C03BFFFEE -:100700003463FFFF004310243C0100020031082144 -:10071000100000D0AC228FF03C0200018C426F1C14 -:10072000104000283C0300A0020310245443000D95 -:100730003C0200203C0200018C426F202403010097 -:100740003C01000200310821AC2390043C0300016D -:100750003C01000200310821AC23900C1000001570 -:100760003442040002021024104000082403010057 -:100770003C0200018C426F203C0100020031082144 -:10078000AC2390041000000B344208003C020080AF -:10079000020210241040002E3C0300013C02000124 -:1007A0008C426F203C01000200310821AC23900CE8 -:1007B00034420C003C010001AC226F2010000025E7 -:1007C000240400013C020020020210241040000614 -:1007D000240201003C01000200310821AC229004F7 -:1007E000100000053C0200803C010002003108219D -:1007F000AC2090043C02008002021024104000074C -:10080000001219403C0200013C01000200230821B3 -:10081000AC22900C100000062404000100121140CC -:100820003C01000200220821AC20900C24040001AD -:100830000000282127B0001E0C00457C020030215A -:1008400024040001000028210C00457C0200302116 -:10085000240400012405000127B0001C0C00457C85 -:100860000200302124040001240500010C00457C15 -:100870000200302110000077000000003C02FFEC75 -:100880003442FFFF020280243C020008020280255D -:10089000001211403C01000200220821AC308FF808 -:1008A0003C02200002021024104000090000000059 -:1008B0003C0200018C426E441440000524020001F9 -:1008C0003C010001AC226F1C100000043C024000FF -:1008D0003C010001AC206F1C3C02400002021024CD -:1008E0001440001D24020E013C0300018C636F1CA8 -:1008F000AF8202383C010001AC206DB010600005F1 -:10090000240220203C010001AC226F2024020001BF -:10091000AEE204B83C04BFFF001219403C020002E2 -:10092000004310218C428FF03C0500018CA56D988E -:100930003484FFFF004410243C01000200230821FE -:10094000AC228FF02402000110A20044000000003D -:1009500010000040000000003C0200018C426F1CAF -:100960001040001C240220003C010001AC226F203A -:100970003C0300A0020310241443000500121140A0 -:100980003402A0003C0100011000002DAC226F20B9 -:100990003C030002006218218C638FF83C020020A7 -:1009A0000062102410400004240220013C010001D8 -:1009B00010000023AC226F203C0200800062102453 -:1009C0001040001F3402A0013C0100011000001C77 -:1009D000AC226F203C0200200202102410400007CD -:1009E00000121940240201003C01000200230821EA -:1009F000AC229004100000063C020080001211405E -:100A00003C01000200220821AC2090043C0200803E -:100A10000202102410400006001219403C0200019E -:100A20003C0100020023082110000005AC22900CBC -:100A3000001211403C01000200220821AC20900C61 -:100A40003C0300018C636D982402000110620003D6 -:100A5000000000000C003DAF000000008FBF003020 -:100A60008FB3002C8FB200288FB100248FB00020EC -:100A700003E0000827BD003827BDFFB0AFB3003C3E -:100A800000009821AFB500400000A821AFB10034AC -:100A90000000882124020002AFBF0048AFBE00441E -:100AA000AFB20038AFB00030AFA4002CA7A0001A3E -:100AB000A7A00018A7A00020A7A0001EA7A00022A2 -:100AC00010A20130A7A0001C2CA2000310400005BA -:100AD0002402000110A2000A3C0240001000025D46 -:100AE000022010212402000410A2020A240200089D -:100AF00010A202080220102110000256000000007F -:100B00008FA8002C000881403C03000200701821CF -:100B10008C638FFC0062102414400009240400013F -:100B20003C027FFF3442FFFF006288243C01000248 -:100B300000300821AC318FF4100002460220102151 -:100B4000240500010C00457C27A6001824040001A0 -:100B5000240500010C00457C27A6001897A2001868 -:100B600030420004104000D93C1140003C0200011A -:100B70008C426F402443FFFF2C620006104000D9D6 -:100B8000000310803C010001002208218C226C68C7 -:100B900000400008000000002404000124050011AA -:100BA00027B0001A0C00457C02003021240400010B -:100BB000240500110C00457C0200302197A3001A87 -:100BC00030624000104000023C1500103C15000847 -:100BD00030628000104000AA3C130001100000A801 -:100BE0003C130002240400012405001427B0001A5D -:100BF0000C00457C0200302124040001240500146F -:100C00000C00457C0200302197A3001A30621000CE -:100C1000104000023C1500103C150008306208002E -:100C2000104000973C130001100000953C13000297 -:100C3000240400012405001927B0001C0C00457C89 -:100C40000200302124040001240500190C00457C19 -:100C50000200302197A2001C304307002402040048 -:100C600010620027286204011040000E24020200D6 -:100C70001062001F286202011040000524020100DA -:100C80005062001E3C1300011000001E24040001ED -:100C900024020300506200193C13000210000019E6 -:100CA00024040001240206001062000D28620601DF -:100CB00010400005240205005062000B3C130002A6 -:100CC0001000001024040001240207001462000D2B -:100CD000240400013C1300041000000A3C15000825 -:100CE000100000063C130004100000053C1500082D -:100CF0003C130001100000023C1500083C150010D8 -:100D0000240400012405001827B0001E0C00457CB7 -:100D10000200302124040001240500180C00457C49 -:100D2000020030218FA8002C97A7001E0008114058 -:100D30003C06000200C230218CC68FF497A200222C -:100D40003C10000126106C5C02002021AFA20010B4 -:100D500097A2001C3C05000C34A503030C002B3BA0 -:100D6000AFA200143C020004166200103C02000115 -:100D70008F84005424030001240200023C0100017E -:100D8000AC236D9C3C010001AC226D983C0100013C -:100D9000AC236DA43C010001AC236E243C01000196 -:100DA000AC246F301000004F02B388251662003962 -:100DB0003C0280003C0200018C426E201440001E68 -:100DC0002404001800002021000028210C004DDB25 -:100DD000340680008F8300548F82005402B388252C -:100DE00010000002246300328F820054006210233E -:100DF0002C4200331440FFFC000000008F8300549D -:100E0000240200013C010001AC226E203C010001E3 -:100E1000AC226D9C3C010001AC226D983C010001AC -:100E2000AC226DA43C010001AC226E243C01000107 -:100E30001000002CAC236F30000028210C004DDB8B -:100E400024060404000020212405001E27A6001803 -:100E5000240200020C0045BEA7A2001800002021B9 -:100E60000000282127A600180C0045BEA7A00018E6 -:100E700024040018240500020C004DDB24060004A5 -:100E80003C0280000222102502B318251000001534 -:100E90000043882502221025027518250043882565 -:100EA0000200202197A6001C3C0700018CE76D98EA -:100EB0003C05000C34A50326AFB300100C002B3BFF -:100EC000AFB1001410000007000000003C11000248 -:100ED000023088218E318FFC3C027FFF3442FFFFBD -:100EE000022288243C0200018C426DA81040001EA2 -:100EF000000000003C0200018C426F1C1040000208 -:100F00003C022000022288258FA8002C00081140F6 -:100F10003C010002002208218C22900010400003B6 -:100F20003C02002010000005022288253C02FFDF61 -:100F30003442FFFF022288248FA8002C00081140B1 -:100F40003C010002002208218C229008104000037E -:100F50003C02008010000004022288253C02FF7F32 -:100F60003442FFFF022288248FA8002C0008114081 -:100F70003C01000200220821AC318FF41000013541 -:100F8000022010218FA8002C0008F1403C03000231 -:100F9000007E18218C638FF83C0240000062102410 -:100FA00014400009240400013C027FFF3442FFFF8B -:100FB000006288243C010002003E0821AC318FF021 -:100FC0001000012402201021000028210C00457C83 -:100FD00027A6001824040001000028210C00457CED -:100FE00027A60018240400012405000127B20020D0 -:100FF0000C00457C0240302124040001240500013E -:101000000C00457C0240302124040001240500042A -:1010100027B1001E0C00457C022030212404000171 -:10102000240500040C00457C02203021240400012A -:101030002405000527B000220C00457C0200302169 -:1010400024040001240500050C00457C0200302129 -:1010500024040001240500100C00457C27A600187C -:1010600024040001240500100C00457C27A600186C -:10107000240400012405000A0C00457C02403021B4 -:10108000240400012405000A0C00457C02403021A4 -:1010900024040001240500180C00457C02203021A6 -:1010A00024040001240500180C00457C0220302196 -:1010B00024040001240500010C00457C27A600182B -:1010C00024040001240500010C00457C27A600181B -:1010D00097A2001830420004104000663C11400006 -:1010E0003C0300018C636F34240200051462006726 -:1010F000240400012405001927B0001C0C00457CC5 -:101100000200302124040001240500190C00457C54 -:101110000200302197A2001C304307002402040083 -:1011200010620027286204011040000E2402020011 -:101130001062001F28620201104000052402010015 -:101140005062001E3C1300011000001E3C0200040F -:1011500024020300506200193C1300021000001921 -:101160003C020004240206001062000D2862060101 -:1011700010400005240205005062000B3C130002E1 -:10118000100000103C020004240207001462000D4D -:101190003C0200043C1300041000000A3C15000847 -:1011A000100000063C130004100000053C15000868 -:1011B0003C130001100000023C1500083C15001013 -:1011C0003C020004126200173C0280008F8200542F -:1011D000241000013C010001AC306D9C3C01000179 -:1011E000AC306D983C010001AC306DA43C010001B5 -:1011F000AC306E243C010001AC226F303C02000197 -:101200001662002202758825000020210000282196 -:101210000C004DDB340680003C0100011000001B77 -:10122000AC306E200222102502B318250043882519 -:1012300097A6001C3C0200018C426F1C3C07000179 -:101240008CE76D983C04000124846C5CAFA2001014 -:1012500097A2001E3C05000C34A503233C010001AD -:10126000AC206E200C002B3BAFA200141000000736 -:10127000000000003C110002023E88218E318FF0F8 -:101280003C027FFF3442FFFF022288243C0200011F -:101290008C426DA810400069000000003C02000173 -:1012A0008C426F1C104000023C0220000222882564 -:1012B0008FA8002C000811403C01000200220821E8 -:1012C0008C229004104000033C0200201000000516 -:1012D000022288253C02FFDF3442FFFF02228824DD -:1012E0008FA8002C000811403C01000200220821B8 -:1012F0008C22900C104000033C0200801000004F34 -:10130000022288253C02FF7F3442FFFF1000004B81 -:10131000022288248FA8002C000829403C030002E8 -:10132000006518218C638FF83C0240000062102495 -:10133000144000083C027FFF3442FFFF0062882413 -:101340003C01000200250821AC318FF01000004163 -:10135000022010213C0200018C426DA81040003494 -:101360003C11C00C3C0200018C426E443C04C00C99 -:10137000348420003C0300018C636F1C0002102B9E -:10138000000210230044102410600003005188253F -:101390003C022000022288253C0200020045102168 -:1013A0008C429004104000033C0200201000000416 -:1013B000022288253C02FFDF3442FFFF02228824FC -:1013C0008FA8002C000811403C01000200220821D7 -:1013D0008C22900C104000033C020080100000049E -:1013E000022288253C02FF7F3442FFFF022288242C -:1013F0003C0200018C426E30104000023C020800AA -:10140000022288253C0200018C426E34104000020A -:101410003C020400022288253C0200018C426E3806 -:10142000104000063C020100100000040222882542 -:101430003C027FFF3442FFFF006288248FA8002C0B -:10144000000811403C01000200220821AC318FF05D -:10145000022010218FBF00488FBE00448FB500408E -:101460008FB3003C8FB200388FB100348FB00030A2 -:1014700003E0000827BD005027BDFFD0AFB2002811 -:1014800000809021AFBF002CAFB10024AFB000208E -:101490008F8402003C1000018E106D988F86022010 -:1014A000240200021202005C2E020003104000051C -:1014B000240200011202000A001219401000010C5F -:1014C0000000000024020004120200BF24020008F1 -:1014D000120200BE00128940100001050000000049 -:1014E0003C05000200A328218CA58FFC3C100002C3 -:1014F000020380218E108FF43C02400000A21024D1 -:10150000104000383C020008020210241040002065 -:10151000348400023C020002004310218C429000FF -:101520001040000534840020348401003C02002077 -:1015300010000006020280252402FEFF0082202403 -:101540003C02FFDF3442FFFF020280240012114000 -:101550003C010002002208218C2290081040000566 -:101560003C02000100C230253C0200801000001641 -:10157000020280253C02FFFE3442FFFF00C23024FD -:101580003C02FF7F3442FFFF1000000F0202802464 -:101590002402FEDF008220243C02FFFE3442FFFFD3 -:1015A00000C230243C02FF5F3442FFFF020280246D -:1015B0003C01000200230821AC2090003C01000205 -:1015C00000230821AC209008AF840200AF860220DF -:1015D0008F82022034420002AF8202201000000AF3 -:1015E000001211403C02BFFF3442FFFF8F83020014 -:1015F000020280242402FFFD006218240C003DAF8B -:10160000AF830200001211403C01000200220821B9 -:10161000100000B7AC308FF43C0200018C426F1C0C -:101620001040006924050004240400010C00457CDE -:1016300027A6001824040001240500050C00457CA1 -:1016400027A6001A97A3001897A2001A3C040001CD -:1016500024846E4830630C0000031A8230420C0070 -:1016600000021282A7A2001A00021080004410217A -:1016700000431021A7A30018904800002402000195 -:101680003103FFFF106200292862000210400005AC -:101690000000000010600009000000001000003D84 -:1016A0000000000010700013240200031062002CE0 -:1016B0000000000010000037000000008F820200D0 -:1016C0002403FEFF00431024AF8202008F82022019 -:1016D0003C03FFFE3463FFFF00431024AF8202206F -:1016E0003C010002AC2090043C01000210000032DA -:1016F000AC20900C8F82020034420100AF820200C5 -:101700008F8202203C03FFFE3463FFFF004310245E -:10171000AF820220240201003C010002AC229004AE -:101720003C01000210000024AC20900C8F820200CB -:101730002403FEFF00431024AF8202008F820220A8 -:101740003C03000100431025AF8202203C0100024F -:10175000AC2090043C01000210000017AC23900C58 -:101760008F82020034420100AF8202008F82022089 -:101770003C03000100431025AF8202202402010037 -:101780003C010002AC2290043C0100021000000A5F -:10179000AC23900C3C04000124846C8097A6001AB2 -:1017A00097A700183C05000134A5FFFFAFA8001063 -:1017B0000C002B3BAFA000148F82020034420002C9 -:1017C0001000004BAF820200001289403C0500026D -:1017D00000B128218CA58FF83C1000020211802155 -:1017E0008E108FF03C02400000A210241440001024 -:1017F000000000003C0200018C426F1C14400005F8 -:101800003C02BFFF8F82020034420002AF8202001E -:101810003C02BFFF3442FFFF0C003DAF02028024B8 -:101820003C0100020031082110000031AC308FF083 -:101830003C0200018C426F1C104000053C0200205D -:101840003C0200018C426E44104000253C02002006 -:1018500000A210241040000734840020240201005C -:101860003C01000200310821AC2290041000000667 -:10187000348401003C01000200310821AC209004B6 -:101880002402FEFF008220243C02008000A21024DB -:1018900010400007001219403C0200013C01000208 -:1018A00000230821AC22900C1000000800C2302553 -:1018B000001211403C01000200220821AC20900CD3 -:1018C0003C02FFFE3442FFFF00C23024AF8402001E -:1018D000AF8602208F82022034420002AF820220B3 -:1018E000001211403C01000200220821AC308FF0B0 -:1018F0008FBF002C8FB200288FB100248FB0002042 -:1019000003E0000827BD003000000000000018219F -:10191000308400FF2405FFDF2406FFBF00641007AA -:101920003042000110400004000000008F8200449B -:1019300010000003344200408F820044004610240F -:10194000AF8200448F82004434420020AF820044C2 -:101950008F82004400451024AF82004424630001BC -:10196000286200085440FFEE0064100703E00008FE -:10197000000000002C8200081040001B0000000046 -:101980002405FFDF2406FFBF000418803C0200018D -:1019900024426E60006218212464000490620000FA -:1019A00010400004000000008F820044100000037B -:1019B000344200408F82004400461024AF8200442D -:1019C0008F82004434420020AF8200448F82004462 -:1019D00000451024AF820044246300010064102BF2 -:1019E0001440FFEE0000000003E0000800000000CB -:1019F0000000000000000000000000008F8400C410 -:101A00008F8600E08F8700E42402FFF800C22824BC -:101A100010E5001A27623FF814E2000224E80008EB -:101A200027683000550500048D0A000030C200040C -:101A300014400012008050218CE900008F42013CCC -:101A4000014948230049182B94EB0006106000025E -:101A500025630050004948210123182B5040000302 -:101A60008F4201FC03E0000800E01021AF8800E88D -:101A700024420001AF4201FCAF8800E403E000080B -:101A80000000102103E00008000000008F8300E444 -:101A900027623FF81062000424620008AF8200E869 -:101AA00003E00008AF8200E427623000AF8200E864 -:101AB00003E00008AF8200E403E00008000000003B -:101AC0000000000000000000000000008F880120DE -:101AD00027624FE08F8301281502000225090020AC -:101AE00027694800112300128FA20010AD040000E6 -:101AF000AD050004AD060008A507000E8FA3001475 -:101B0000AD0200188FA20018AD03001C25030016BB -:101B1000AD020010AD030014AF8901208F4300FC1B -:101B2000240200012463FFFF03E00008AF4300FC30 -:101B30008F430324000010212463000103E0000808 -:101B4000AF43032403E00008000000008F88010079 -:101B5000276247E08F830108150200022509002053 -:101B6000276940001123000F8FA20010AD04000070 -:101B7000AD050004AD060008A507000E8FA30014F4 -:101B8000AD0200188FA20018AD03001C250300163B -:101B9000AD020010AD030014AF89010003E000089E -:101BA000240200018F430328000010212463000158 -:101BB00003E00008AF43032803E000080000000032 -:101BC00000000000000000000000000024486561E3 -:101BD0006465723A202F70726F6A656374732F7236 -:101BE00063732F73772F67652F2E2F6E69632F66B0 -:101BF00077322F636F6D6D6F6E2F66776D61696ED3 -:101C00002E632C7620312E312E322E343520313970 -:101C100039392F30312F32342030303A31303A35A3 -:101C20003520736875616E67204578702024000048 -:101C3000657674526E674600516576744600000002 -:101C400051657674505F46004D657674526E6746F6 -:101C5000000000004D516576744600004D516576D8 -:101C6000505F46005173436F6E495F4600000000AD -:101C70005173436F6E734600517250726F64460029 -:101C80006261644D656D537A0000000068775665A7 -:101C900072000000626164487756657200000000BF -:101CA0002A2A4441574E5F41000000007478527860 -:101CB0004266537A00000000626641746E4D726B9A -:101CC000000000007265645A6F6E6531000000000C -:101CD000706369436F6E660067656E436F6E660082 -:101CE0002A646D615244666C000000002A50414E27 -:101CF00049432A002E2E2F2E2E2F2E2E2F2E2E2F02 -:101D00002E2E2F7372632F6E69632F6677322F63C7 -:101D10006F6D6D6F6E2F66776D61696E2E6300005B -:101D2000726362466C616773000000006261645216 -:101D30007852636200000000676C6F62466C6773E4 -:101D4000000000002B5F646973705F6C6F6F700040 -:101D50002B65765F68616E646C65720063616E749A -:101D600031446D61000000002B715F646D615F7430 -:101D70006F5F6E69635F636B73756D002B685F7374 -:101D8000656E645F646174615F72656164795F63ED -:101D90006B73756D000000002B685F646D615F728E -:101DA000645F6173736973745F636B73756D000057 -:101DB00074436B736D4F6E002B715F646D615F7464 -:101DC0006F5F6E69630000002B685F73656E645F10 -:101DD000646174615F726561647900002B685F649F -:101DE0006D615F72645F61737369737400000000FA -:101DF00074436B736D4F6666000000002B685F7361 -:101E0000656E645F62645F72656164790000000002 -:101E10006873745352696E67000000006261645316 -:101E200052696E67000000006E69635352696E6705 -:101E30000000000077446D61416C6C4100000000BF -:101E40002B715F646D615F746F5F686F73745F6344 -:101E50006B73756D000000002B685F6D61635F72CE -:101E6000785F636F6D705F636B73756D000000006A -:101E70002B685F646D615F77725F61737369737400 -:101E80005F636B73756D000072436B736D4F6E0013 -:101E90002B715F646D615F746F5F686F73740000B6 -:101EA0002B685F6D61635F72785F636F6D700000B8 -:101EB0002B685F646D615F77725F617373697374C0 -:101EC0000000000072436B736D4F666600000000F7 -:101ED0002B685F726563765F62645F7265616479C7 -:101EE000000000002B685F726563765F6A756D6243 -:101EF0006F5F62645F726561647900002B685F7276 -:101F00006563765F6D696E695F62645F7265616467 -:101F1000790000002B6D685F636F6D6D616E64000A -:101F20002B685F74696D6572000000002B685F6448 -:101F30006F5F7570646174655F74785F636F6E73F3 -:101F4000000000002B685F646F5F757064617465EA -:101F50005F72785F70726F64000000002B636B73B8 -:101F6000756D3136000000002B7065656B5F6D612B -:101F7000635F72785F7761002B7065656B5F6D6181 -:101F8000635F7278000000002B6465715F6D6163B0 -:101F90005F7278002B685F6D61635F72785F617458 -:101FA000746E0000626164526574537A0000000030 -:101FB000727842644266537A000000002B6E756CA2 -:101FC0006C5F68616E646C657200000066774F70CC -:101FD0004661696C000000002B685F757064617475 -:101FE000655F6C65643400002B685F7570646174B4 -:101FF000655F6C65643600002B685F7570646174A2 -:10200000655F6C6564320000696E74537461746559 -:10201000000000002A2A696E697443700000000005 -:102020002373637265616D0069537461636B4572FC -:102030000000000070726F62654D656D0000000069 -:102040002A2A4441574E5F42000000002B73775FFD -:10205000646D615F6173736973745F706C75735FD6 -:1020600074696D65720000002B267072656C6F617B -:10207000645F77725F646573637200002B26707211 -:10208000656C6F61645F72645F64657363720000A6 -:102090002B685F68665F74696D65720024486561CE -:1020A0006465723A202F70726F6A656374732F7261 -:1020B00063732F73772F67652F2E2F6E69632F66DB -:1020C00077322F636F6D6D6F6E2F74696D65722E31 -:1020D000632C7620312E312E322E33352031393992 -:1020E000392F30312F32372031393A30393A3530C3 -:1020F0002068617965732045787020240000000015 -:10210000657674526E67460051657674460000002D -:1021100051657674505F46004D657674526E674621 -:10212000000000004D516576744600004D51657603 -:10213000505F46005173436F6E495F4600000000D8 -:102140005173436F6E734600517250726F64460054 -:10215000542D446D6152643200000000542D446DD2 -:102160006152643100000000542D446D615264429C -:1021700000000000542D446D6157723200000000D1 -:10218000542D446D6157723100000000542D446D90 -:1021900061577242000000000000000024486561A1 -:1021A0006465723A202F70726F6A656374732F7260 -:1021B00063732F73772F67652F2E2F6E69632F66DA -:1021C00077322F636F6D6D6F6E2F636F6D6D616E04 -:1021D000642E632C7620312E312E322E323820316F -:1021E0003939392F30312F32302031393A34393AB8 -:1021F000343920736875616E67204578702024003B -:10220000657674526E67460051657674460000002C -:1022100051657674505F46004D657674526E674620 -:10222000000000004D516576744600004D51657602 -:10223000505F46005173436F6E495F4600000000D7 -:102240005173436F6E734600517250726F64460053 -:102250003F48636D644D6278000000003F636D6429 -:1022600048737453000000003F636D644D634D6418 -:10227000000000003F636D6450726F6D000000004D -:102280003F636D644C696E6B000000003F636D64DA -:1022900045727200000086AC00008E5C00008E5C0F -:1022A00000008DE400008B7800008E3000008E5C12 -:1022B00000008790000088000000899000008A6874 -:1022C00000008A3400008E5C0000887000008B24BF -:1022D00000008E5C00008B34000087B4000088246E -:1022E00000000000000000000000000024486561BC -:1022F0006465723A202F70726F6A656374732F720F -:1023000063732F73772F67652F2E2F6E69632F6688 -:1023100077322F636F6D6D6F6E2F6D636173742EE7 -:10232000632C7620312E312E322E38203139393837 -:102330002F31322F30382030323A33363A3336208C -:10234000736875616E672045787020240000000076 -:10235000657674526E6746005165767446000000DB -:1023600051657674505F46004D657674526E6746CF -:10237000000000004D516576744600004D516576B1 -:10238000505F46005173436F6E495F460000000086 -:102390005173436F6E734600517250726F64460002 -:1023A0006164644D63447570000000006164644DB5 -:1023B0006346756C0000000064656C4D634E6F45AC -:1023C00000000000000000000000000024486561DB -:1023D0006465723A202F70726F6A656374732F722E -:1023E00063732F73772F67652F2E2F6E69632F66A8 -:1023F00077322F636F6D6D6F6E2F646D612E632C5E -:102400007620312E312E322E323420313939382F88 -:1024100031322F32312030303A33333A3039207371 -:102420006875616E67204578702024006576745267 -:102430006E674600516576744600000051657674FB -:10244000505F46004D657674526E6746000000008E -:102450004D516576744600004D516576505F4600DB -:102460005173436F6E495F46000000005173436F24 -:102470006E734600517250726F6446007377446DFC -:10248000614F66660000000031446D614F6E0000D0 -:102490007377446D614F6E002372446D6141544EF9 -:1024A0000000000072446D6141544E300000000095 -:1024B00072446D6141544E310000000072446D6100 -:1024C000344762002A50414E49432A002E2E2F2EB7 -:1024D0002E2F2E2E2F2E2E2F2E2E2F7372632F6E19 -:1024E00069632F6677322F636F6D6D6F6E2F646D2A -:1024F000612E63002377446D6141544E000000005B -:1025000077446D6141544E300000000077446D61A6 -:1025100041544E310000000077446D613447620041 -:102520000000000000000000000000002448656179 -:102530006465723A202F70726F6A656374732F72CC -:1025400063732F73772F67652F2E2F6E69632F6646 -:1025500077322F636F6D6D6F6E2F74726163652EAE -:10256000632C7620312E312E322E352031393938F8 -:102570002F30392F33302031383A35303A32382045 -:10258000736875616E672045787020240000000034 -:102590000000000000000000000000002448656109 -:1025A0006465723A202F70726F6A656374732F725C -:1025B00063732F73772F67652F2E2F6E69632F66D6 -:1025C00077322F636F6D6D6F6E2F646174612E6350 -:1025D0002C7620312E312E322E31322031393939BC -:1025E0002F30312F32302031393A34393A353120D9 -:1025F000736875616E6720457870202400000000C4 -:1026000046575F56455253494F4E3A202331204694 -:1026100072692041707220372031373A35373A35A8 -:1026200032205044542032303030000046575F434F -:102630004F4D50494C455F54494D453A2031373A4A -:1026400035373A353200000046575F434F4D504909 -:102650004C455F42593A206465767263730000000E -:1026600046575F434F4D50494C455F484F53543A8E -:1026700020636F6D707574650000000046575F43FE -:102680004F4D50494C455F444F4D41494E3A2065AE -:102690006E672E616374656F6E2E636F6D00000050 -:1026A00046575F434F4D50494C45523A206763634C -:1026B0002076657273696F6E20322E372E320000DD -:1026C00000000000120411000000000024486561B1 -:1026D0006465723A202F70726F6A656374732F722B -:1026E00063732F73772F67652F2E2F6E69632F66A5 -:1026F00077322F636F6D6D6F6E2F6D656D2E632C4E -:102700007620312E312E322E3520313939382F3086 -:10271000392F33302031383A35303A303820736829 -:1027200075616E672045787020240000244865613B -:102730006465723A202F70726F6A656374732F72CA -:1027400063732F73772F67652F2E2F6E69632F6644 -:1027500077322F636F6D6D6F6E2F73656E642E63AE -:102760002C7620312E312E322E3434203139393826 -:102770002F31322F32312030303A33333A31382052 -:10278000736875616E672045787020240000000032 -:10279000657674526E674600516576744600000097 -:1027A00051657674505F46004D657674526E67468B -:1027B000000000004D516576744600004D5165766D -:1027C000505F46005173436F6E495F460000000042 -:1027D0005173436F6E734600517250726F644600BE -:1027E00069736E745463705500000000244865617D -:1027F0006465723A202F70726F6A656374732F720A -:1028000063732F73772F67652F2E2F6E69632F6683 -:1028100077322F636F6D6D6F6E2F726563762E63E7 -:102820002C7620312E312E322E3533203139393964 -:102830002F30312F31362030323A35353A3433208B -:10284000736875616E672045787020240000000071 -:10285000657674526E6746005165767446000000D6 -:1028600051657674505F46004D657674526E6746CA -:10287000000000004D516576744600004D516576AC -:10288000505F46005173436F6E495F460000000081 -:102890005173436F6E734600517250726F644600FD -:1028A000724D616343686B300000000072784672BD -:1028B0006D324C670000000072784E6F53744264B2 -:1028C0000000000072784E6F4D6942640000000005 -:1028D00072784E6F4A6D4264000000007278436B5C -:1028E000446D614600000000727851446D457846A1 -:1028F00000000000727851446D61460072785144C6 -:102900004C42644600000000727851446D426446B7 -:1029100000000000727843726350616400000000A0 -:1029200072536D51446D614600000000244865619A -:102930006465723A202F70726F6A656374732F72C8 -:1029400063732F73772F67652F2E2F6E69632F6642 -:1029500077322F636F6D6D6F6E2F6D61632E632CF9 -:102960007620312E312E322E323220313939382F25 -:1029700031322F30382030323A33363A3330207308 -:102980006875616E67204578702024006576745202 -:102990006E67460051657674460000005165767496 -:1029A000505F46004D657674526E67460000000029 -:1029B0004D516576744600004D516576505F460076 -:1029C0005173436F6E495F46000000005173436FBF -:1029D0006E734600517250726F6446006D616354AD -:1029E000687265730000000023744D616341544EAA -:1029F0000000000023724D616341544E000000004E -:102A000072656D4173737274000000006C696E6BC7 -:102A1000444F574E000000006C696E6B555000002B -:102A20000000000000000000000000002448656174 -:102A30006465723A202F70726F6A656374732F72C7 -:102A400063732F73772F67652F2E2F6E69632F6641 -:102A500077322F636F6D6D6F6E2F636B73756D2E95 -:102A6000632C7620312E312E322E392031393939EE -:102A70002F30312F31342030303A30333A3438204F -:102A8000736875616E67204578702024000000002F -:102A9000657674526E674600516576744600000094 -:102AA00051657674505F46004D657674526E674688 -:102AB000000000004D516576744600004D5165766A -:102AC000505F46005173436F6E495F46000000003F -:102AD0005173436F6E734600517250726F644600BB -:102AE00000000000000000000000000050726F6253 -:102AF00065506879000000006C6E6B41535352546E -:102B000000000000000109A400010A1C00010A5095 -:102B100000010A7C0001105000010AA800010B10FE -:102B2000000111FC00010DC000010C6800010C80C7 -:102B300000010CC400010CEC00010D0C00010D346F -:102B4000000111FC00010DC000010DF800010E1084 -:102B500000010E4000010E6800010E8800010EB059 -:102B60000000000000010FDC000110080001102C23 -:102B7000000111FC00011050000110780001110843 -:102B80000000000000000000000000000001186CC0 -:102B90000001193C00011A1400011AE400011B4055 -:102BA00000011C1C00011C4400011D2000011D48E7 -:102BB00000011EF000011F18000120C0000122B812 -:102BC0000001254C000124600001254C00012578FE -:102BD000000120E8000122907273745F676D6969DB -:102BE00000000000000126080001264000012728FF -:102BF00000013374000133B4000133CC7365746C8D -:102C00006F6F7000000000000000000000013BBC7E -:102C100000013BFC00013C8C00013CD000013D3434 -:102C200000013DC000013DF400013E7C00013F1465 -:102C300000013FE400014024000140A8000140CC15 -:102C4000000141DC646F4261736550670000000061 -:102C500000000000000000000000000073746D61BF -:102C6000634C4E4B000000006765746D636C6E6BC7 -:102C70000000000000014ED800014ED800014B8C2E -:102C800000014BD800014C2400014ED87365746DCF -:102C90006163616374000000000000000000000038 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000103 -:102CD000000000010000000100C001FC00003FFCFA -:102CE00000C00000416C74656F6E204163654E4901 -:102CF000432056000000000000000000000000001B -:102D0000000000000000000000000000416C74653D -:102D10006F6E204163654E49432056004242424255 -:102D2000000000000000000000000000001FFFFC89 -:102D3000001FFF7C000000000000000000000000F9 -:102D40000000000000000000000000000060CF0054 -:102D500000000060CF000000000000000000000044 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000030000000020 -:102DB0000000000100000000000000000000000012 -:102DC0000000000100000000000000010000000001 -:102DD00000000000000000000000000000000001F2 -:102DE00000000001000000000000000000000000E2 -:102DF00000000000000000000100000021000000B1 -:102E0000120001400000000000000000200000004F -:102E1000120000A0000000001200006012000180FB -:102E2000120001E0000000000000000000000000AF -:102E30000000000100000000000000000000000091 -:102E40000000000000000000000000000000000280 -:102E5000000000000000000000030001000000016D -:102E60000003020100000000000000000101010158 -:102E70000101010000010100010100010001000148 -:0C2E800001000101000001010000000041 -:00000001FF -/* tg2 firmware v12.4.11 */ diff --git a/firmware/adaptec/starfire_rx.bin.ihex b/firmware/adaptec/starfire_rx.bin.ihex deleted file mode 100644 index 6b1fae0d18eb11c3795202511c2043ee7474806a..0000000000000000000000000000000000000000 --- a/firmware/adaptec/starfire_rx.bin.ihex +++ /dev/null @@ -1,53 +0,0 @@ -:10000000010003DC00000000040004210000008661 -:10001000800000150000180E8100001500006664C5 -:100020001A0040AB00000B06142000110000000075 -:10003000142040220000AAAA14204022000003003D -:1000400014204022000000001A0040AB00000B14F6 -:1000500014200011000000008300001500000002C1 -:10006000040000210000000000000010000000005B -:1000700004000421000000870000001000000000C0 -:1000800000000010000000000000801500000000CB -:100090000000003E00000000000000100000000012 -:1000A0008200001500004000009E8050000000000B -:1000B000030080150000000086008015000000008D -:1000C00082000015000080000100001C00000000FC -:1000D000000050A00000010C4E20D011000060086C -:1000E0001420D012000040080000F09000007000C2 -:1000F0000000C8B0000030000000404000000000D8 -:10010000001080150000000000A2C1500000400057 -:1001100000A400B000000014000000200000000057 -:100120002500400D0000252500047220000031004C -:10013000009340700000000000000020000000005C -:1001400000924460000001842B20C01100000000D8 -:100150000000C42000000540360140180000422D78 -:100160001420001100000000009244600000018390 -:100170003200001F0000003402AC00150000000235 -:1001800000A601100000000842200011000000003D -:1001900000924060000001030000001E000000000B -:1001A00000000020000001000000001E0000000010 -:1001B00000924460000000860000408000000000C3 -:1001C0000092C0700000000000924060000001003A -:1001D0000000C8900000500000A6C1100000000000 -:1001E00000B0C09000000012021C001500000000CA -:1001F0003200001F0000003400924460000005102F -:100200004421001100000000420000110000000025 -:1002100083000015000000400092446000000508C3 -:100220004501401800004545008080500000000056 -:10023000622080120000000082000015000008000B -:100240001520001100000000000000100000000058 -:10025000000000100000000000000010000000007E -:10026000000000100000000000000010000000006E -:10027000800000150000EEA4810000150000005F62 -:1002800000000060000000000000412000000000AD -:1002900000004A000000400000924460000001900D -:1002A0005601401A000059561400001100000000C9 -:1002B0000093405000000018009300500000001808 -:1002C0003601403A0000002D000643A9000000005E -:1002D0000000C420000001405601401A0000595699 -:1002E00014000011000000000000001000000000D9 -:1002F0000000001000000000000642A900000000FD -:1003000000024420000001835601401A00005956A3 -:1003100082000015000020001520001100000000E0 -:1003200082000015000000101520001100000000E0 -:1003300082000015000000101520001100000000D0 -:00000001FF diff --git a/firmware/adaptec/starfire_tx.bin.ihex b/firmware/adaptec/starfire_tx.bin.ihex deleted file mode 100644 index 6b1fae0d18eb11c3795202511c2043ee7474806a..0000000000000000000000000000000000000000 --- a/firmware/adaptec/starfire_tx.bin.ihex +++ /dev/null @@ -1,53 +0,0 @@ -:10000000010003DC00000000040004210000008661 -:10001000800000150000180E8100001500006664C5 -:100020001A0040AB00000B06142000110000000075 -:10003000142040220000AAAA14204022000003003D -:1000400014204022000000001A0040AB00000B14F6 -:1000500014200011000000008300001500000002C1 -:10006000040000210000000000000010000000005B -:1000700004000421000000870000001000000000C0 -:1000800000000010000000000000801500000000CB -:100090000000003E00000000000000100000000012 -:1000A0008200001500004000009E8050000000000B -:1000B000030080150000000086008015000000008D -:1000C00082000015000080000100001C00000000FC -:1000D000000050A00000010C4E20D011000060086C -:1000E0001420D012000040080000F09000007000C2 -:1000F0000000C8B0000030000000404000000000D8 -:10010000001080150000000000A2C1500000400057 -:1001100000A400B000000014000000200000000057 -:100120002500400D0000252500047220000031004C -:10013000009340700000000000000020000000005C -:1001400000924460000001842B20C01100000000D8 -:100150000000C42000000540360140180000422D78 -:100160001420001100000000009244600000018390 -:100170003200001F0000003402AC00150000000235 -:1001800000A601100000000842200011000000003D -:1001900000924060000001030000001E000000000B -:1001A00000000020000001000000001E0000000010 -:1001B00000924460000000860000408000000000C3 -:1001C0000092C0700000000000924060000001003A -:1001D0000000C8900000500000A6C1100000000000 -:1001E00000B0C09000000012021C001500000000CA -:1001F0003200001F0000003400924460000005102F -:100200004421001100000000420000110000000025 -:1002100083000015000000400092446000000508C3 -:100220004501401800004545008080500000000056 -:10023000622080120000000082000015000008000B -:100240001520001100000000000000100000000058 -:10025000000000100000000000000010000000007E -:10026000000000100000000000000010000000006E -:10027000800000150000EEA4810000150000005F62 -:1002800000000060000000000000412000000000AD -:1002900000004A000000400000924460000001900D -:1002A0005601401A000059561400001100000000C9 -:1002B0000093405000000018009300500000001808 -:1002C0003601403A0000002D000643A9000000005E -:1002D0000000C420000001405601401A0000595699 -:1002E00014000011000000000000001000000000D9 -:1002F0000000001000000000000642A900000000FD -:1003000000024420000001835601401A00005956A3 -:1003100082000015000020001520001100000000E0 -:1003200082000015000000101520001100000000E0 -:1003300082000015000000101520001100000000D0 -:00000001FF diff --git a/firmware/advansys/3550.bin.ihex b/firmware/advansys/3550.bin.ihex deleted file mode 100644 index 6809b0d84e4ff39d47a0635aed69b96766110aea..0000000000000000000000000000000000000000 --- a/firmware/advansys/3550.bin.ihex +++ /dev/null @@ -1,317 +0,0 @@ -:10000000DD2DD504000000F200F0001618E400FC1D -:10001000010048E4BE18188003F6020000FAFFFF52 -:10002000280E9EE7FF0082E700EA00F601E609E7F6 -:1000300055F001F601FA08000300040018F410005E -:1000400000EC85F0BC00D5F08E0C385400E61EF0B4 -:1000500086F0B4009857D0010C1C3E1C0C00BB006D -:10006000AA18028032F001FC880CC6120213184054 -:10007000005701EA3C006C016E0104123E570080FB -:1000800003E6B600C00001013E01DA0F221008129B -:10009000024AB95403581B8030E44BE4200032007C -:1000A0003E00800024013C0168016A017001720178 -:1000B000740176017801620A920C2C102E1006133E -:1000C0004C1CBB553C5604804AE402EE5BF0B1F098 -:1000D00003F706F703FC0F004000BE000001B00864 -:1000E00030136415321C381C4E1C10440248004C5E -:1000F00004EA5DF004F602FC0500340036009800C6 -:10010000CC0020014E014E0B1E0E0C100A120413DF -:100110004013301C004EBD56068300DC05F009F08C -:1001200059F0A7F0B8F00EF70600190033009B0055 -:10013000A400B500BA00D000E100E700DE03560AD3 -:10014000140E021004100A1036100A131213521360 -:1001500010151415AC16201C341C361C08443844E9 -:1001600091440A454846014868548355B0570158A0 -:10017000835905E60BF00CF05CF04BF404F805F83D -:1001800002FA03FA04FC05FC07000A000D001C003B -:100190009E00A800AA00B900E00022012601790112 -:1001A0007A01C001C2017C025A03EA04E807680828 -:1001B0006908BA08E909060B3A0E00101A10ED108A -:1001C000F11006120C1316131E1382134214D614C8 -:1001D0008A15C617D2176B18121C461C9C32004099 -:1001E0000E47484741488948804C00544455E555DE -:1001F00014567757BF57405C0680089003A1FE9CB9 -:10020000F02902FEB80CFF100000D0FECC1800CF81 -:10021000FE8001FF030000FE9315FE0F05FF38006E -:1002200000FE572400FE48004FFF04000010FF09A5 -:100230000000FF080101FF08FFFFFF270000FF107B -:10024000FFFFFF0F0000FE7856FE3412FF21000072 -:10025000FE04F7CF2A670B01FECE0EFE04F7CF6730 -:100260000B3C2AFE3DF0FE0202FE20F09CFE91F0C7 -:10027000FEF001FE90F0FEF001FE8FF09C05513B78 -:1002800002FED40C01FE440DFEDD12FEFC10FE2821 -:100290001C05FEA600FED3124718FEA600B5FE48B8 -:1002A000F0FE8602FE49F0FEA002FE4AF0FEBE020B -:1002B000FE46F0FE5002FE47F0FE5602FE43F0FE00 -:1002C0004402FE44F0FE4802FE45F0FE4C02170BCD -:1002D000A0170618960229FE001CDEFE021CDDFE99 -:1002E0001E1CFEE91001FE2017FEE710FE06FCC7EB -:1002F0000A6B019E0229144D379701FE640F0A6BA9 -:100300000182FEBD100A6B0182FEAD10FE161CFEBE -:10031000581C170618962A2529FE3DF0FE020221D8 -:10032000FE9402FE5A1CEAFE141C14FE300037979D -:1003300001FE540F1706189602D01E20071034FE37 -:10034000691017061896FE04EC20463D1220FE05A3 -:10035000F6C701FE5216094A4C35112D3C8A01E6BA -:1003600002290A40010E07005D016FFE1810FE41D0 -:10037000580A99010EFEC85464FE0C0301E60229D6 -:100380002A46FE02E827F8FE9E43F7FE27F0FEDC31 -:1003900001FE074BFE20F09CFE401C25D2FE26F0FD -:1003A000FE5603FEA0F0FE4403FE11F09CFEEF108B -:1003B000FE9FF0FE6403EB0FFE1100025A2AFE4876 -:1003C0001CEB09041DFE1813231E98AC12980A405A -:1003D000010EAC7501FEBC1511CA25D2FE01F0D28A -:1003E000FE82F0FE9203EC11FEE40065FEA40325FC -:1003F000321FFEB4030143FE06F0FEC4038D81FEEE -:100400000AF0FE7A060222056B2816FEF604142C6A -:1004100001338FFE660202D1EB2A671AFE671BF8D2 -:10042000F7FE481C70016E870A40010E070016D3C4 -:100430000ACA010E7460597627056B28FE10121443 -:100440002C01338FFE660202D1BC7DBD7F25226563 -:10045000FE3C041FFE380468FEA000FE9B57FE4EC3 -:10046000122BFF02001001081FFEE0042B01081FE1 -:1004700022302ED5FE4C44FE4C1260FE4448132C14 -:10048000FE4C5464D3467627FAEFFE621309041D2E -:10049000FE2A132F077EA5FE2010132CFE4C546459 -:1004A000D3FAEF8609041DFE08132F077E6E090498 -:1004B0001DFE1C1214920904063B14C401338FFE66 -:1004C000700C02222B11FEE600FE1C90F903149220 -:1004D00001330229FE425B671AFE4659F8F7FE8790 -:1004E00080FE31E44F09040BFE7813FE2080071ACA -:1004F000FE7012490406FE601305FEA2002816FED7 -:100500008005FE31E46A49040BFE4A1305FEA00093 -:1005100028FE42125E01082532F1010826FE9805E8 -:1005200011FEE3002349FE4AF0FE6A05FE49F0FE93 -:1005300064058324FE2100A124FE2200A0244CFE99 -:100540000948010826FE9805FEE2084904C53B015A -:1005500086240612CC37FE270109041DFE2212470D -:1005600001A714920904063B14C401338FFE700CDA -:10057000022205FE9C0028FE3E12055028FE36137E -:100580004701A726FE08060A06490419FE02125F63 -:1005900001FEAA141FFEFE05119A014311FEE5009B -:1005A0000550B40C5005C628FE6212053F28FE5ABD -:1005B0001301FE141801FE6618FE4348B719136CA8 -:1005C000FF020057488B1C3D85B7694701A726FEEF -:1005D000720649041BDF890A4D01FED8141FFE680C -:1005E00006119A014311FEE500053FB40C3F1706C2 -:1005F00001A7EC7270016E8711FEE200010825323E -:10060000FE0AF0FEA6068CFE5C07FE06F0FE6407FE -:100610008D81022209040BFE2E12151A0108150005 -:1006200001081500010815000108FE99A40108152C -:100630000002FE320861041BFE381209041B6E150D -:10064000FE1B000108150001081500010815000136 -:100650000815060108150002D9664CFE3A555FFEE2 -:100660009A814B1DBAFE32070A1DFE096FAFFECA02 -:1006700045FE3212622C85667B01082532FE0AF0A7 -:10068000FE32078D818CFE5C070222014302FE8A46 -:1006900006151902FE8A06FE9CF7D4FE2C90FEAECB -:1006A0009077FECA070C541855094A6A351E200770 -:1006B00010FE0E1274FE808037206327FE0610FEA7 -:1006C00083E7C4A1FE0340094A4F3501A8ADFE1FD0 -:1006D00040125801A5FE0850FE8A50FE4451FEC645 -:1006E0005183FBFE8A900C521853FE0C90FE8E90A4 -:1006F000FE4050FEC2500C39183AFE4A1009046AF6 -:10070000FE2A12FE2C90FEAE900C54185509044F90 -:100710008501A8FE1F801258FE4490FEC6900C561C -:100720001857FBFE8A900C521853FE4090FEC29060 -:100730000C39183A0C38184E094A19352A13FE4E4E -:100740001165FE4808FE9EF0FE5C08B116322A7361 -:10075000DDB8FE8008B9FE9E088CFE7408FE06F027 -:10076000FE7A088D8102220143FEC9101519FEC9C7 -:1007700010610406FE101261040B4509040BFE68AB -:1007800012FE2E1C02FE240A6104064561040BFEC3 -:100790005212FE2C1CFEAAF0FE1E09FEACF0FEBE9C -:1007A00008FE8A10AAFEF310FEADF0FECA0802FE93 -:1007B000240AABFEE710FE2BF09DE91CFE00FEFEB6 -:1007C0001C12B5FED2F09DFE76181C1A169D05CBA4 -:1007D0001C06169DB86DB96DAAABFEB110705E2BEC -:1007E000149201330FFE3500FE01F05A0F7C025ABD -:1007F000FE74181CFE00F8166D671B01FE440D3BCD -:1008000001E61E2774671A026D09040B21FE060A11 -:1008100009046AFE8212090419FE66131E58ACFC14 -:10082000FE8380FEC844FE2E13FE0491FE86916373 -:1008300027FE4059FEC15977D7055431550C7B1816 -:100840007CBE54BF5501A8AD63271258C038C14EB5 -:1008500079566857F4F5FE04FA38FE05FA4E01A5FC -:10086000A2230C7B0C7C79566857FE1210090419E0 -:1008700016D77939683A0904FEF700350552315325 -:10088000FE1058FE9158FE1459FE9559026D090448 -:100890001916D70904FEF70035FE3A55FE19815F97 -:1008A000FE1090FE9290FED7102F079B16FEC608F2 -:1008B000119B09040BFE14130539313A77FEC60863 -:1008C000FE0C58FE8D58026D2347FE1980DE090488 -:1008D0000BFE1A12FE6C19FE1941E9B5FED1F0D9D2 -:1008E000147A01330FFE4400FE8E10FE6C19BE39DF -:1008F000FEED19BF3AFE0C51FE8E51E91CFE00FFC1 -:1009000034FE7410B5FED2F0FEB20AFE76181C1A40 -:100910008405CB1C06FE08130FFE1600025AFED1FA -:10092000F0FEC40A147A01330FFE1700FE4210FED7 -:10093000CEF0FECA0AFE3C10FECDF0FED60A0FFE37 -:100940002200025AFECBF0FEE20A0FFE2400025AF9 -:10095000FED0F0FEEC0A0F93DCFECFF0FEF60A0F9D -:100960004CFE1010FECCF0D96104193B0FFE1200B2 -:100970002A13FE4E1165FE0C0BFE9EF0FE200BB1FD -:1009800016322A73DDB822B9222AEC65FE2C0B251B -:10099000328CFE480B8D81B8D4B9D402220143FEBB -:1009A000DB1011FEE800AAAB70BC7DBD7FFE89F0B4 -:1009B00022302ED8BC7DBD7F01081F22302ED6B13B -:1009C000450FFE4200025A7806FE814916FE380C99 -:1009D00009040BFE44130F004B0BFE54124BFE2870 -:1009E0000021FEA60C0A40010E07005D3EFE280015 -:1009F000FEE21001E701E80A9901FE320E59112DBD -:100A0000016F02290FFE44004B0BDF3E0BFEB410BA -:100A100001863E0BFEAA100186FE1982FE3446A313 -:100A20003E0B0FFE4300FE9610094A0B3501E7010D -:100A3000E859112D016F670B593C8A02FE2A030900 -:100A4000040B843E0B0F00FE5C1061041BFE581269 -:100A500009041BFE5013FE1C1CFE9DF0FE5C0CFEE8 -:100A60001C1CFE9DF0FE620C094A1B35FEA9100FEE -:100A7000FE1500FE04E60B5F5C0FFE1300FE101077 -:100A80000FFE4700A10FFE4100A00FFE240087AA21 -:100A9000AB70056B2821D15FFE04E61BFE9D41FE75 -:100AA0001C425901DA0229EA140B3795A914FE31C8 -:100AB00000379701FE540F02D03CFE06ECC9EE3E13 -:100AC0001DFECE45343CFE06EAC9FE474B89FE7545 -:100AD000570551FE9856FE38120A42010EFE444850 -:100AE0004609041DFE1A130A40010E47FE41580A2A -:100AF00099010EFE49548EFE2A0D02FE2A030A5168 -:100B0000FEEE14EE3E1DFECE45343CFECE47FEAD5D -:100B10001302291E200710FE9E1223124D1294125A -:100B2000CE1E2D47372DB1E0FEBCF0FEEC0D1306B6 -:100B3000124D01FEE21505FE380131FE3A0177FE45 -:100B4000F00DFE02ECCE62005DFE04EC2046FE05D8 -:100B5000F6FE340101FE5216FBFE48F40DFE18139A -:100B6000AFFE02EACE627AFEC513141B3795A95C6C -:100B700005FE38011CFEF0FF0CFE600105FE3A0187 -:100B80000CFE62013D12202406122D112D8A13063F -:100B90000323031E4DFEF7121E94AC1294077AFE37 -:100BA0007113FE241C141A3795A9FED910B6FE0342 -:100BB000DCFE7357FE805D03B6FE03DCFE5B57FE72 -:100BC000805D03FE0357B623FE00CC03FE0357B639 -:100BD000750309044CFE2213FE1C800706FE1A133F -:100BE000FE1E80E1FE1D80A4FE0C90FE0E13FE0E84 -:100BF00090A3FE3C90FE30F40BFE3C50A001FE8220 -:100C0000162F072DE001FEBC1509041D4501E70163 -:100C1000E811FEE90009044CFE2C1301FE1416FE37 -:100C20001E1CFE1490FE96900CFE640118FE6601D8 -:100C300009044FFE1212FE038074FE01EC20FE80B8 -:100C4000401220632711C8591E20ED762003FE08AC -:100C50001C05FEAC00FE065805FEAE00FE0758055A -:100C6000FEB000FE085805FEB200FE0958FE0A1C40 -:100C7000246912C9230C500C3F1340485F171DFE16 -:100C8000904DFE915421FE080F3E10134248174C20 -:100C9000FE904DFE915421FE1E0F24101220782C40 -:100CA000461E20ED762011C8F6FED6F0FE320FEA81 -:100CB00070FE141CFE101CFE181C033CFE0C14EEEF -:100CC000FE07E61DFECE47FEF513030186782C468F -:100CD000FAEFFE42132F072DFE34130A42010EB025 -:100CE000FE3612F0FE454801E3FE00CCB0FEF313E1 -:100CF0003D750710A30A80010EFE805C016FFE0E99 -:100D000010077E45F6FED6F0FE6C0F03FE445874C5 -:100D1000FE01EC97FE9E40FE9DE700FE9CE71B76E1 -:100D20002701DAFEDD102ABC7DBD7F302ED5071BE2 -:100D3000FE4812070BFE5612071AFE301207C216A3 -:100D4000FE3E1107FE230016FE4A11070616FEA8F6 -:100D5000110719FE12120700162214C201339F2B2D -:100D600001088C43032BFE62080ACA01FE320E11F1 -:100D70007E02292B2F079BFED9137939683A77FE1B -:100D8000FC1009046AFE7212C038C14EF4F58EFEE2 -:100D9000C6101E58FE2613057B317C77FE820C0C94 -:100DA000541855230C7B0C7C01A82469731258013C -:100DB000A5C038C14EFE0455FEA555FE04FA38FE06 -:100DC00005FA4EFE911005563157FE4056FEE1568B -:100DD0000C56185783C038C14EF4F505523153FEF6 -:100DE0000056FEA1560C52185309046AFE1E121E2C -:100DF00058FE1F4005543155FE2C50FEAE5005568E -:100E00003157FE4450FEC65005523153FE0850FE85 -:100E10008A500539313AFE4050FEC250025C240629 -:100E200012CD025B2B01081F44302ED5070621444A -:100E30002F079B215B016E1C3D164409040BE279D0 -:100E400039683AFE0A5534FE8B55BE39BF3AFE0C5E -:100E500051FE8E51025BFE1981AFFE1941025B2BE0 -:100E6000010825321FA2302ED84B1AFEA6124B0BBA -:100E70003B0244010825321FA2302ED6071A214416 -:100E800001081FA2302EFEE809FEC2496005FE9C43 -:100E9000002884490419349FFEBB454B00453E069B -:100EA000783DFEDA14016E87FE4B45E22F079AE18A -:100EB00005C62884053F28345E025BFEC05DFEF84F -:100EC00014FE03170550B40C505E2B0108265C017C -:100ED000FEAA14025C010825321F44302ED60706F4 -:100EE000214401FE8E13FE4258FE8214FEA4148794 -:100EF000FE4AF40B1644FE4AF406FE0C122F079A23 -:100F000085025B053FB40C3F5E2B0108265C01FEA9 -:100F1000D814025C130665FECA1226FEE01272F1B6 -:100F200001082372038FFEDC1225FEDC121FFECAAD -:100F3000125E2B0108FED510136CFF020057488B80 -:100F40001CFEFF7FFE3056FE005C03136CFF0200A8 -:100F500057488B1C3DFE3056FE005C03136CFF02AD -:100F60000057488B03136CFF020057488BFE0B5849 -:100F7000030A5001820A3F018203FC1C10FF030098 -:100F800054FE00F41948FE007DFE017DFE027DFE48 -:100F9000037C63270C521853BE56BF5703FE6208EA -:100FA000FE824AFEE11AFE835A740301FE1418FE03 -:100FB00042485F608901081FFEA214302ED8010844 -:100FC0001FFEA214302EFEE80AFEC15905C628FEF7 -:100FD000CC1249041BFEC41323621BE24BC364FE04 -:100FE000E8133B130617C378DBFE7810FF02835526 -:100FF000A1FF028355621AA4BBFE30008EE4172CB9 -:101000001306FE5610620BE1BBFE64008EE40AFE7E -:10101000640017931306FE28106206FE6013BBFEE1 -:10102000C8008EE40AFEC800174D130683BBFE906D -:1010300001BAFE4E1489FE1210FE43F494FE56F0DF -:10104000FE6014FE04F46CFE43F493FEF310F90109 -:10105000FE22131C3DFE1013FE0017FE4DE469BA7C -:10106000FE9C14B769FE1C10FE0017FE4DE419BA71 -:10107000FE9C14B719836023FE4DF400DF8913062C -:10108000FEB456FEC3580360130B03150601082671 -:10109000E5150B010826E5151A010826E572FE89FB -:1010A000490108031506010826A6151A010826A6F7 -:1010B0001506010826A6FE8949010826A672FE89A2 -:1010C0004A01080360031ECC0706FE4413AD12CC90 -:1010D000FE49F4003B729F5EFE01ECFE2701F10128 -:1010E000082F07FEE300FE20131FFE5A152312CD22 -:1010F00001431ECD070645094A0635030A42010E83 -:10110000ED880710A40A80010E880A51019E030A87 -:1011100080010E88FE80E710071084FE455801E329 -:1011200088030A42010E880A51019E030A42010EF9 -:10113000FE8080F2FE49E410A40A80010EF20A51FA -:1011400001820317107166FE6001FE18DFFE19DED2 -:10115000FE241CFE1DF71D90FEF61501FEFC16E098 -:10116000911D66FE2C01FE2F1903AE21FEE615FE31 -:10117000DA1017107105FE6401FE00F419FE18580C -:1011800005FE6601FE19589119FE3C90FE30F406EA -:10119000FE3C5066FE3800FE0F79FE1CF71990FEEB -:1011A0004016FEB6143403AE21FE1816FE9C10172E -:1011B0001071FE835AFE18DFFE19DEFE1DF738900F -:1011C000FE6216FE9414FE10139138661BFEAF19D2 -:1011D000FE98E70003AE21FE5616FE6C1017107144 -:1011E000FE30BCFEB2BC91C5661BFE0F79FE1CF73B -:1011F000C590FE9A16FE5C143403AE21FE8616FEE0 -:101200004210FE02F61071FE18FE54FE19FE55FC47 -:10121000FE1DF74F90FEC016FE3614FE1C13914FB4 -:1012200047FE8358FEAF19FE80E710FE81E71011DC -:10123000FEDD006327036327FE124521FEB016146E -:10124000063795A90229FE39F0FE04172303FE7E16 -:10125000181C1A5D130D037105CB1C06FEEF12FE60 -:10126000E110782C462F072DFE3C13FE8214FE421F -:10127000133C8A0A42010EB0FE3E12F0FE454801C0 -:10128000E3FE00CCB0FEF3133D750710A30A800106 -:101290000EF2016FFE1610077E85FE4014FE24122A -:1012A000F6FED6F0FE2417170B03FE9CE70B0FFE8D -:1012B000150059762701DA1706033C8A094A1D35BD -:1012C000112D016F170603FE3890FEBA9079C7689A -:1012D000C8FE485534FEC955031E98731298030A78 -:1012E00099010EF00A40010EFE494416FEF01773F4 -:1012F00075030A42010E0710450A51019E0A40017A -:101300000E737503FE4EE41A64FE241805FE900069 -:10131000FE3A455BFE4EE4C264FE361805FE9200BE -:10132000FE02E61BDCFE4EE4FE0B0064FE481805E0 -:10133000FE9400FE02E619FE081005FE9600FE026D -:10134000E62CFE4E45FE0C12AFFF046854DE1C690D -:1013500003077AFE5AF0FE741824FE0900FE3410CA -:10136000071BFE5AF0FE821824C3FE2610071A5DE2 -:10137000242CDC070B5D2493FE0E1007065D244D24 -:101380009FAD0314FE09000133FE04FE7D057FF9C5 -:101390000325FECA18FE14F00865FEC61803FF1ADE -:0213A00000004B -:00000001FF -/* Microcode buffer is kept after initialization for error recovery. */ diff --git a/firmware/advansys/38C0800.bin.ihex b/firmware/advansys/38C0800.bin.ihex deleted file mode 100644 index a60b447ff74a6f55e820b3a24e12b60863d4a97d..0000000000000000000000000000000000000000 --- a/firmware/advansys/38C0800.bin.ihex +++ /dev/null @@ -1,336 +0,0 @@ -:10000000D83F0D05000000F200F000FC001618E4D7 -:10001000010048E4188003F60200CE1900FAFFFF41 -:100020001C0F00F69EE7FF0082E700EA01FA01E6F6 -:1000300009E755F001F60300040010001EF085F0FA -:1000400018F40800BC00385400ECD5F0820D00E62E -:1000500086F0B1F0985701FCB400D4010C1C3E1C92 -:100060003C00BB000010BA19028032F07C0D021374 -:10007000BA131840005701EA02FC03FC3E006C0171 -:100080006E0174017601B9543E57008003E6B60054 -:10009000C00001013E017A01CA08CE1016110412F7 -:1000A0000812024ABB553C5603581B8030E44BE40F -:1000B0005DF002FA200032004000800024013C0183 -:1000C00068016A017001720178017C01620A860D83 -:1000D00006134C1C04804AE402EE5BF003F70C00AC -:1000E0000F004700BE00000120115C16321C381CB6 -:1000F0004E1C1044004C04EA5CF0A7F004F603FA2E -:100100000500340036009800CC0020014E014A0B57 -:10011000420C120F0C1022110A120413301C024858 -:10012000004E42544455BD56068300DC05F009F0EC -:1001300059F0B8F04BF406F70EF704FC05FC060086 -:10014000190033009B00A400B500BA00D000E10004 -:10015000E700E203080F021004100A100A130C1340 -:1001600012132414341404160816A417201C341C6B -:10017000361C0844384491440A45484601486854AE -:100180003A558355E555B0570158835905E60BF0AC -:100190000CF004F805F807000A001C001E009E0081 -:1001A000A800AA00B900E0002201260179017E0121 -:1001B000C401C60180025E03EE049A06F8076208D5 -:1001C00068086908D608E909FA0B2E0F12101A10F0 -:1001D000ED10F1102A1106120C123E121013161314 -:1001E0001E134614761482143615CA156B18BE18E1 -:1001F000CA18E619121C461C9C3200400E47FE9C91 -:10020000F02B02FEAC0DFF100000D7FEE81900D65F -:10021000FE8401FF030000FE9315FE0F05FF38006A -:1002200000FE572400FE4C005BFF04000011FF0994 -:100230000000FF080101FF08FFFFFF270000FF107B -:10024000FFFFFF110000FE7856FE3412FF21000070 -:10025000FE04F7D62C990A01FEC20FFE04F7D699C8 -:100260000A422CFE3DF0FE0602FE20F0A7FE91F0B1 -:10027000FEF401FE90F0FEF401FE8FF0A7035D4D49 -:1002800002FEC80D01FE380EFEDD12FEFC10FE2837 -:100290001C03FEA600FED3124114FEA600C2FE48B7 -:1002A000F0FE8A02FE49F0FEA402FE4AF0FEC202FF -:1002B000FE46F0FE5402FE47F0FE5A02FE43F0FEF8 -:1002C0004802FE44F0FE4C02FE45F0FE5002180AC1 -:1002D000AA180614A1022BFE001CE7FE021CE6FE73 -:1002E0001E1CFEE91001FE1818FEE710FE06FCCEEB -:1002F000097001A8022B155939A201FE5810097086 -:100300000187FEBD1009700187FEAD10FE161CFEB0 -:10031000581C180614A12C1C2BFE3DF0FE060223CF -:10032000FE9802FE5A1CF8FE141C15FE300039A27D -:1003300001FE4810180614A102D72220071135FE2D -:100340006910180614A1FE04EC204F431320FE058B -:10035000F6CE01FE4A1708545837122F429201FE7A -:100360008216022B0946010E0700660173FE181063 -:10037000FE415809A4010EFEC8546BFE100301FE95 -:100380008216022B2C4FFE02E82AFEBF57FE9E4328 -:10039000FE7757FE27F0FEE001FE074BFE20F0A798 -:1003A000FE401C1CD9FE26F0FE5A03FEA0F0FE48BB -:1003B00003FE11F0A7FEEF10FE9FF0FE6803F91098 -:1003C000FE110002652CFE481CF908051BFE1813DF -:1003D0002122A3B713A30946010EB77801FEB41674 -:1003E00012D11CD9FE01F0D9FE82F0FE9603FA125A -:1003F000FEE40027FEA8031C341DFEB803014BFEDB -:1004000006F0FEC8039586FE0AF0FE8A0602240363 -:10041000702817FEFA04156D01367BFE6A0202D8B9 -:10042000F92C9919FE671BFEBF57FE7757FE481C33 -:100430007401AF8C0946010E070017DA09D1010ECD -:100440008D5164792A037028FE1012156D01367BD8 -:10045000FE6A0202D8C781C8831C2427FE40041DFF -:10046000FE3C043BFEA000FE9B57FE4E122DFF02F9 -:100470000010010B1DFEE4042D010B1D243331DEA1 -:10048000FE4C44FE4C1251FE44480F6FFE4C546B20 -:10049000DA4F792AFE0680FE4847FE621308051BE4 -:1004A000FE2A13320782FE5213FE20100F6FFE4CFD -:1004B000546BDAFE0680FE4847FE401308051BFE1B -:1004C0000813320782FE301308051BFE1C12159D0F -:1004D0000805064D15FE0D0001367BFE640D022455 -:1004E0002D12FEE600FE1C90FE405C04159D0136B8 -:1004F000022BFE425B9919FE4659FEBF57FE775705 -:10050000FE8780FE31E45B08050AFE8413FE20802E -:100510000719FE7C12530506FE6C1303FEA2002889 -:1005200017FE9005FE31E45A53050AFE561303FEEA -:10053000A00028FE4E1267FF02001027FE48051C8F -:1005400034FE8948FF02001027FE560526FEA80546 -:1005500012FEE3002153FE4AF0FE7605FE49F0FE4E -:1005600070058825FE2100AB25FE2200AA2558FE35 -:100570000948FF02001027FE860526FEA805FEE2B8 -:10058000085305CB4D01B0250613D339FE270108CA -:10059000051BFE22124101B2159D0805064D15FEF0 -:1005A0000D0001367BFE640D022403FE9C0028EB47 -:1005B000035C28FE36134101B226FE1806090653D5 -:1005C000051FFE02125001FE9E151DFE0E0612A50D -:1005D000014B12FEE500035CC10C5C03CD28FE62FA -:1005E00012034528FE5A1301FE0C1901FE7619FE6E -:1005F0004348C4CC0F71FF02005752931E438BC473 -:100600006E4101B226FE820653051AE9910959018D -:10061000FECC151DFE780612A5014B12FEE5000367 -:1006200045C10C45180601B2FA767401AF8C12FE72 -:10063000E20027DB1C34FE0AF0FEB60694FE6C07CF -:10064000FE06F0FE74079586022408050AFE2E12A7 -:100650001619010B1600010B1600010B1600010BF9 -:10066000FE99A4010B160002FE420868051AFE3826 -:100670001208051AFE301316FE1B00010B160001AE -:100680000B1600010B1600010B1606010B160002DB -:10069000E26C58BE50FE9A81551B7AFE4207091B38 -:1006A000FE096FBAFECA45FE3212696D8B6C7F2758 -:1006B000FE54071C34FE0AF0FE4207958694FE6C39 -:1006C000070224014B02DB161F02DBFE9CF7DCFE57 -:1006D0002C90FEAE9056FEDA070C60146108545A56 -:1006E0003722200711FE0E128DFE808039206A2AE3 -:1006F000FE0610FE83E7FE4800ABFE034008545B95 -:100700003701B3B8FE1F40136201EFFE0850FE8AA6 -:1007100050FE4451FEC65188FE0890FE8A900C5E41 -:10072000145FFE0C90FE8E90FE4050FEC2500C3DB9 -:10073000143EFE4A1008055AFE2A12FE2C90FEAE08 -:10074000900C60146108055B8B01B3FE1F8013627F -:10075000FE4490FEC6900C3F1440FE0890FE8A9026 -:100760000C5E145FFE4090FEC2900C3D143E0C2EB9 -:10077000143C210C490C6308541F372C0FFE4E11FA -:1007800027DDFE9EF0FE7608BC17342C77E6C5FE0A -:100790009A08C6FEB80894FE8E08FE06F0FE94087D -:1007A00095860224014BFEC910161FFEC91068056C -:1007B00006FE101268050A4E08050AFE9012FE2E6B -:1007C0001C02FE180B6805064E68050AFE7A12FE2A -:1007D0002C1CFEAAF0FED209FEACF0FE000902FEBF -:1007E000DE09FEB7F0FEFC08FE02F61A50FE701895 -:1007F000FEF118FE4055FEE155FE1058FE9158FEE0 -:100800001459FE95591C85FE8CF0FEFC08FEACF0D8 -:10081000FEF008B5FECB10FEADF0FE0C0902FE188E -:100820000BB6FEBF10FE2BF085F41EFE00FEFE1C74 -:1008300012C2FED2F085FE76181E19178503D21E4D -:10084000061785C54AC64AB5B6FE891074672D15C8 -:100850009D013610FE3500FE01F06510800265FE38 -:100860009880FE19E40AFE1A1251FE1982FE6C18D5 -:10087000FE4454BEFE1981FE74188F9017FECE08F8 -:10088000024A08055AEC032E293C0C3F14409B2ECB -:100890009C3CFE6C18FEED18FE4454FEE5543A3FB5 -:1008A0003B40034929638FFEE354FE7418FEF5189C -:1008B0008FFEE35490C056FECE08024AFE37F0FE8B -:1008C000DA09FE8BF0FE6009024A08050A23FEFAE7 -:1008D0000A3A493B6356FE3E0A0FFEC007419800A4 -:1008E000ADFE0159FE52F0FE0C0A8F7AFE240A3A40 -:1008F000498FFEE35457497D63FE1458FE95580214 -:100900004A3A493B63FE1459FE9559BE574957630D -:10091000024A08055AFE821208051FFE661322626B -:10092000B7FE03A1FE8380FEC844FE2E13FE049191 -:10093000FE86916A2AFE4059FEC15956E00360299D -:10094000610C7F148057607D6101B3B86A2A13621D -:100950009B2E9C3C3A3F3B4090C0FE04FA2EFE0585 -:10096000FA3C01EFFE3610210C7F0C803A3F3B40F1 -:10097000E408051F17E03A3D3B3E0805FEF7003747 -:10098000035E295FFE1058FE915857497D6302FEB1 -:10099000F40908051F17E00805FEF70037BEFE1929 -:1009A0008150FE1090FE9290FED3103207A617FEE3 -:1009B000080912A608050AFE1413033D293E56FE37 -:1009C0000809FE0C58FE8D58024A2141FE1980E7A5 -:1009D00008050AFE1A12FE6C19FE1941F4C2FED176 -:1009E000F0E2157E013610FE4400FE8E10FE6C19FA -:1009F000573DFEED197D3EFE0C51FE8E51F41EFE5C -:100A000000FF35FE7410C2FED2F0FEA60BFE761873 -:100A10001E198A03D21E06FE081310FE1600026578 -:100A2000FED1F0FEB80B157E013610FE1700FE4217 -:100A300010FECEF0FEBE0BFE3C10FECDF0FECA0B4B -:100A400010FE22000265FECBF0FED60B10FE240045 -:100A50000265FED0F0FEE00B109EE5FECFF0FEEA50 -:100A60000B1058FE1010FECCF0E268051F4D10FE72 -:100A700012002C0FFE4E1127FE000CFE9EF0FE14FD -:100A80000CBC17342C77E6C524C6242CFA27FE208C -:100A90000C1C3494FE3C0C9586C5DCC6DC0224019B -:100AA0004BFEDB1012FEE800B5B674C781C883FEAA -:100AB00089F0243331E1C781C88327FE660C1D24E9 -:100AC0003331DFBC4E10FE420002657C06FE8149D8 -:100AD00017FE2C0D08050AFE44131000550AFE549B -:100AE0001255FE280023FE9A0D0946010E070066E6 -:100AF00044FE2800FEE21001F501F609A401FE26DD -:100B00000F64122F0173022B10FE4400550AE944B2 -:100B10000AFEB41001B0440AFEAA1001B0FE198208 -:100B2000FE3446AC440A10FE4300FE961008540AF8 -:100B30003701F501F664122F0173990A644292029B -:100B4000FE2E0308050A8A440A1000FE5C106805A0 -:100B50001AFE581208051AFE5013FE1C1CFE9DF0CA -:100B6000FE500DFE1C1CFE9DF0FE560D08541A375B -:100B7000FEA91010FE1500FE04E60A50FE2E10100D -:100B8000FE1300FE1010106FAB10FE4100AA10FE05 -:100B900024008CB5B67403702823D850FE04E61ADE -:100BA000FE9D41FE1C426401E3022BF8150A39A0A8 -:100BB000B415FE310039A201FE481002D742FE06EC -:100BC000ECD0FC441BFECE453542FE06EAD0FE4783 -:100BD0004B91FE7557035DFE9856FE381209480189 -:100BE0000EFE44484F08051BFE1A130946010E412C -:100BF000FE415809A4010EFE495496FE1E0E02FE47 -:100C00002E03095DFEEE14FC441BFECE453542FE6C -:100C1000CE47FEAD13022B22200711FE9E12211398 -:100C200059139F13D5222F41392FBCADFEBCF0FEC6 -:100C3000E00E0F06135901FEDA1603FE380129FEF5 -:100C40003A0156FEE40EFE02ECD5690066FE04ECA5 -:100C5000204FFE05F6FE340101FE4A17FE0890FE05 -:100C600048F40DFE1813BAFE02EAD5697EFEC513DC -:100C7000151A39A0B4FE2E1003FE38011EFEF0FF37 -:100C80000CFE600103FE3A010CFE620143132025B5 -:100C900006132F122F920F060421042259FEF71279 -:100CA000229FB7139F077EFE7113FE241C1519396E -:100CB000A0B4FED910C3FE03DCFE7357FE805D04B2 -:100CC000C3FE03DCFE5B57FE805D04FE0357C321B9 -:100CD000FE00CC04FE0357C37804080558FE221317 -:100CE000FE1C800706FE1A13FE1E80EDFE1D80AE60 -:100CF000FE0C90FE0E13FE0E90ACFE3C90FE30F407 -:100D00000AFE3C50AA01FE7A1732072FAD01FEB44D -:100D10001608051B4E01F501F612FEE900080558FC -:100D2000FE2C1301FE0C17FE1E1CFE1490FE969066 -:100D30000CFE640114FE660108055BFE1212FE0340 -:100D4000808DFE01EC20FE804013206A2A12CF64C1 -:100D50002220FB792004FE081C03FEAC00FE06588E -:100D600003FEAE00FE075803FEB000FE085803FE67 -:100D7000B200FE0958FE0A1C256E13D0210C5C0C33 -:100D8000450F465250181BFE904DFE915423FEFC19 -:100D90000F44110F48521858FE904DFE915423E411 -:100DA000251113207C6F4F2220FB792012CFFE14D7 -:100DB00056FED6F0FE2610F874FE141CFE101CFE23 -:100DC000181C0442FE0C14FCFE07E61BFECE47FE78 -:100DD000F5130401B07C6F4FFE0680FE4847FE42CB -:100DE0001332072FFE34130948010EBBFE3612FEE4 -:100DF0004148FE454801F0FE00CCBBFEF3134378AA -:100E00000711AC0984010EFE805C0173FE0E100711 -:100E1000824EFE1456FED6F0FE601004FE44588D3D -:100E2000FE01ECA2FE9E40FE9DE700FE9CE71A79C3 -:100E30002A01E3FEDD102CC781C8833331DE071A97 -:100E4000FE4812070AFE56120719FE301207C9178C -:100E5000FE321207FE230017EB070617FE9C12074F -:100E60001FFE12120700172415C90136A92D010B08 -:100E7000944B042DDD09D101FE260F1282022B2D89 -:100E80003207A6FED9133A3D3B3E56FEF011080547 -:100E90005AFE72129B2E9C3C90C096FEBA112262A2 -:100EA000FE2613037F298056FE760D0C6014612107 -:100EB0000C7F0C8001B3256E77136201EF9B2E9C93 -:100EC0003CFE0455FEA555FE04FA2EFE05FA3CFE36 -:100ED0009110033F2940FE4056FEE1560C3F14405E -:100EE000889B2E9C3C90C0035E295FFE0056FEA1AD -:100EF000560C5E145F08055AFE1E122262FE1F4049 -:100F000003602961FE2C50FEAE50033F2940FE4491 -:100F100050FEC650035E295FFE0850FE8A50033D16 -:100F2000293EFE4050FEC2500289250613D40272AB -:100F30002D010B1D4C3331DE0706234C3207A6234F -:100F40007201AF1E43174C08050AEE3A3D3B3EFEC8 -:100F50000A5535FE8B55573D7D3EFE0C51FE8E5198 -:100F60000272FE1981BAFE194102722D010B1C3466 -:100F70001DE83331E15519FEA612550A4D024C0108 -:100F80000B1C341DE83331DF0719234C010B1DE81E -:100F90003331FEE809FEC2495103FE9C00288A5302 -:100FA000051F35A9FEBB4555004E44067C43FEDABD -:100FB0001401AF8CFE4B45EE3207A5ED03CD288A18 -:100FC00003452835670272FEC05DFEF814FE031764 -:100FD000035CC10C5C672D010B268901FE9E150286 -:100FE00089010B1C341D4C3331DF0706234C01F102 -:100FF000FE4258F1FEA4148CFE4AF40A174CFE4A35 -:10100000F406EA3207A58B02720345C10C45672D31 -:10101000010B268901FECC1502890F0627FEBE139F -:1010200026FED41376FE8948010B2176047BFED080 -:10103000131CFED0131DFEBE13672D010BFED51031 -:101040000F71FF02005752931EFEFF7FFE3056FEC7 -:10105000005C040F71FF02005752931E43FE30568E -:10106000FE005C040F71FF0200575293040F71FFE2 -:101070000200575293FE0B5804095C018709450191 -:101080008704FE03A11E11FF030054FE00F41F524B -:10109000FE007DFE017DFE027DFE037C6A2A0C5E61 -:1010A000145F573F7D4004DDFE824AFEE11AFE8355 -:1010B0005A8D0401FE0C19FE4248505191010B1D3E -:1010C000FE96153331E1010B1DFE96153331FEE816 -:1010D0000AFEC15903CD28FECC1253051AFEC413D3 -:1010E00021691AEE55CA6BFEDC144D0F0618CA7C36 -:1010F00030FE7810FF028355ABFF0283556919AEAD -:1011000098FE300096F2186D0F06FE5610690AED33 -:1011100098FE640096F209FE6400189E0F06FE28F1 -:10112000106906FE601398FEC80096F209FEC8001A -:1011300018590F068898FE90017AFE421591E4FE38 -:1011400043F49FFE56F0FE5415FE04F471FE43F482 -:101150009EFEF310FE405C01FE16141E43ECFE00E2 -:1011600017FE4DE46E7AFE9015C46EFE1C10FE0054 -:1011700017FE4DE4CC7AFE9015C4CC885121FE4D6B -:10118000F400E9910F06FEB456FEC35804510F0A4D -:10119000041606010B26F3160A010B26F316190195 -:1011A0000B26F376FE8949010B041606010B26B1C6 -:1011B0001619010B26B11606010B26B1FE8949014D -:1011C0000B26B176FE894A010B04510422D307068F -:1011D000FE4813B813D3FE49F4004D76A967FE010B -:1011E000ECFE2701FE8948FF02001027FE2E163272 -:1011F00007FEE300FE20131DFE52162113D4014BFF -:1012000022D407064E08540637040948010EFB8E07 -:101210000711AE0984010E8E095D01A8040984013D -:101220000E8EFE80E71107118AFE455801F08E04EC -:101230000948010E8E095D01A8040948010EFE80CF -:1012400080FE804CFE49E411AE0984010EFE804C04 -:10125000095D0187041811756CFE6001FE18DFFE40 -:1012600019DEFE241CFE1DF71B97FEEE1601FEF490 -:1012700017AD9A1B6CFE2C01FE2F1904B923FEDE5C -:1012800016FEDA1018117503FE6401FE00F41FFE4D -:10129000185803FE6601FE19589A1FFE3C90FE3056 -:1012A000F406FE3C506CFE3800FE0F79FE1CF71F62 -:1012B00097FE3817FEB6143504B923FE1017FE9CAE -:1012C00010181175FE835AFE18DFFE19DEFE1DF799 -:1012D0002E97FE5A17FE9414EC9A2E6C1AFEAF1934 -:1012E000FE98E70004B923FE4E17FE6C1018117526 -:1012F000FE30BCFEB2BC9ACB6C1AFE0F79FE1CF716 -:10130000CB97FE9217FE5C143504B923FE7E17FEC0 -:101310004210FE02F61175FE18FE60FE19FE61FE17 -:1013200003A1FE1DF75B97FEB817FE3614FE1C13D3 -:101330009A5B41FE8358FEAF19FE80E711FE81E7FC -:101340001112FEDD006A2A046A2AFE124523FEA855 -:1013500017150639A0B4022BFE39F0FEFC17210444 -:10136000FE7E181E19660F0D047503D21E06FEEFD1 -:1013700012FEE1107C6F4F32072FFE3C13F1FE424C -:101380001342920948010EBBEBFE4148FE4548015D -:10139000F0FE00CCBBFEF31343780711AC098401C7 -:1013A0000EFE804C0173FE161007828BFE4014FE69 -:1013B0002412FE1456FED6F0FE1C18180A04FE9CD9 -:1013C000E70A10FE150064792A01E3180604429228 -:1013D00008541B37122F0173180604FE3890FEBA0A -:1013E000903ACE3BCFFE485535FEC9550422A3772F -:1013F00013A30409A4010EFE41480946010EFE494B -:101400004417FEE8187778040948010E07114E09C1 -:101410005D01A80946010E777804FE4EE4196BFEC3 -:101420001C1903FE9000FE3A45FE2C10FE4EE4C946 -:101430006BFE2E1903FE9200FE02E61AE5FE4EE454 -:10144000FE0B006BFE401903FE9400FE02E61FFE39 -:10145000081003FE9600FE02E66DFE4E45EABAFF56 -:10146000046854E71E6EFE081CFE6719FE0A1CFE87 -:101470001AF4FE0004EAFE48F4197AFE74190F19F2 -:1014800004077EFE5AF0FE841925FE0900FE341082 -:10149000071AFE5AF0FE921925CAFE261007196691 -:1014A000256DE5070A66259EFE0E1007066625597E -:1014B000A9B80415FE09000136FE04FE810383FE6F -:1014C000405C041CF7FE14F00B27FED6191CF77BBA -:0C14D000F7FE82F0FEDA1904FFCC0000E9 -:00000001FF -/* Microcode buffer is kept after initialization for error recovery. */ diff --git a/firmware/advansys/38C1600.bin.ihex b/firmware/advansys/38C1600.bin.ihex deleted file mode 100644 index 18c7c486204638dacc583c5801b21b3effb624c8..0000000000000000000000000000000000000000 --- a/firmware/advansys/38C1600.bin.ihex +++ /dev/null @@ -1,398 +0,0 @@ -:1000000077EF0406000000F2001600FC001000F07C -:1000100018E40100041E48E403F6F7132E1E020044 -:100020000717C05F00FAFFFF040000F609E782E748 -:1000300085F086F04E109EE7FF0055F001F60300B4 -:10004000985701E600EA00EC01FA18F40800F01DE8 -:10005000385432F01000C20E1EF0D5F0BC004BE454 -:1000600000E6B1F0B40002133E1CC8473E00D801C0 -:1000700006130C1C5E1E0057C85701FCBC0EA212D2 -:10008000B9540080620A5A12C8153E1E1840BD5667 -:1000900003E601EA5CF00F0020006C016E0104121F -:1000A0000413BB553C563E5703584AE44000B60083 -:1000B000BB00C000000101013E01580A44100A12B1 -:1000C0004C1C4E1C024A30E405E60C003C0080004B -:1000D00024013C0168016A0170017201740176011A -:1000E00078017C01C60E0C10AC12AE12161A321C2E -:1000F0006E1E02483A55C95702EE5BF003F706F749 -:1001000003FC06001E00BE00E1000C12181A701A53 -:10011000301C381C1044004CB057405C4DE404EADD -:100120005DF0A7F004F602FC05000900190032009A -:1001300033003400360098009E00CC0020014E01B0 -:1001400079013C09680D021004103A1008120A13D4 -:100150004016501600174A19004E0054015800DC92 -:1001600005F009F059F0B8F048F40EF70A009B00CA -:100170009C00A400B500BA00D000E700F0036908B5 -:10018000E9095C0CB612BC19D81B201C341C361CA7 -:10019000421D0844384491440A45484689486854F9 -:1001A0008355835931E402E607F008F00BF00CF0B8 -:1001B0004BF404F805F802FA03FA04FC05FC070006 -:1001C000A800AA00B900E000E500220126016001B4 -:1001D0007A018201C801CA0186026A031805B207C2 -:1001E0006808100D06100A100E1012106010ED10A5 -:1001F000F310061210121E120C130E131013FE9C95 -:10020000F03505FEEC0EFF100000E9FE341F00E89B -:10021000FE8801FF030000FE9315FE0F05FF380066 -:1002200000FE572400FE4C0065FF0400001AFF0981 -:100230000000FF080101FF08FFFFFF270000FF107B -:10024000FFFFFF130000FE7856FE3412FF2100006E -:10025000FE04F7E8377D0D01FE4A11FE04F7E87D44 -:100260000D5137FE3DF0FE0C02FE20F0BCFE91F079 -:10027000FEF801FE90F0FEF801FE8FF0BC03674D22 -:1002800005FE080F01FE780FFEDD1205FE0E03FECF -:10029000281C03FEA600FED1123E22FEA600ACFEE4 -:1002A00048F0FE9002FE49F0FEAA02FE4AF0FEC8A7 -:1002B00002FE46F0FE5A02FE47F0FE6002FE43F0E8 -:1002C000FE4E02FE44F0FE5202FE45F0FE56021CB7 -:1002D0000DA21C0722B70535FE001CFEF110FE0220 -:1002E0001CF5FE1E1CFEE910015FFEE710FE06FC79 -:1002F000DE0A8101A305351F9547B801FEE4110A06 -:1003000081015CFEBD100A81015CFEAD10FE161C71 -:10031000FE581C1C0722B7372A35FE3DF0FE0C02A2 -:100320002BFE9E02FE5A1CFE121CFE141C1FFE30E9 -:100330000047B801FED4111C0722B705E9212C099A -:100340001A31FE69101C0722B7FE04EC2C6001FE76 -:100350001E1E202CFE05F6DE01FE621B010C614A0A -:100360004415565101FE9E1E01FE961A05350A5788 -:1003700001180900360185FE1810FE41580ABA011D -:1003800018FEC8547BFE1C0301FE961A0535376023 -:10039000FE02E830FEBF57FE9E43FE7757FE27F071 -:1003A000FEE401FE074BFE20F0BCFE401C2AEBFEE3 -:1003B00026F0FE6603FEA0F0FE5403FE11F0BCFE24 -:1003C000EF10FE9FF0FE7403FE461C19FE1100059F -:1003D0007037FE481CFE461C010C0628FE1813262A -:1003E00021B9C720B90A570118C78901FEC81A15D3 -:1003F000E12AEBFE01F0EBFE82F0FEA403FE9C324C -:1004000015FEE4002FFEB6032A3C16FEC60301418A -:10041000FE06F0FED603AFA0FE0AF0FEA2070529F5 -:1004200003811E1BFE24051F6301428FFE7002051F -:10043000EAFE461C377D1DFE671BFEBF57FE775741 -:10044000FE481C7501A6860A57011809001BEC0A14 -:10045000E101187750408D3003811EF81F6301427F -:100460008FFE700205EAD799D89C2A292FFE4E04E8 -:1004700016FE4A047EFEA000FE9B57FE541232FF79 -:10048000020010010816FE02053201081629272570 -:10049000EEFE4C44FE581250FE44481334FE4C54B9 -:1004A0007BEC608D3001FE4E1EFE4847FE7C130142 -:1004B0000C0628FE32130143099BFE6813FE26102A -:1004C0001334FE4C547BEC01FE4E1EFE4847FE5496 -:1004D00013010C0628A50143099BFE4013010C06DD -:1004E00028F91F7F010C06074D1FFE0D0001428FEA -:1004F000FEA40E05293215FEE6000FFE1C9004FE38 -:100500009C933A0B0E8B021F7F01420535FE425B26 -:100510007D1DFE4659FEBF57FE77570FFE878004AC -:10052000FE8783FEC9470B0ED065010C060DFE98B1 -:10053000130FFE208004FEA083330B0E091DFE84E2 -:100540001201380607FE701303FEA2001E1BFEDA1E -:1005500005D0540138060DFE581303FEA0001EFE00 -:1005600050125EFF0200102FFE90052A3CCCFF02C5 -:1005700000102FFE9E0517FEF40515FEE300260170 -:1005800038FE4AF0FEC005FE49F0FEBA05712EFEA7 -:100590002100F12EFE2200A22E4AFE0948FF020091 -:1005A000102FFED00517FEF405FEE208013806FE06 -:1005B0001C004D01A72E0720E447FE2701010C0671 -:1005C00028FE24123E01841F7F010C06074D1FFEEA -:1005D0000D0001428FFEA40E052903E61EFECA137C -:1005E00003B61EFE401203661EFE38133E0184173A -:1005F000FE72060A0701380624FE02124F01FE565B -:100600001916FE68061582014115E203668A106616 -:10061000039A1EFE701203551EFE681301C60912CE -:1006200048FE92062E1201FEAC1DFE434862801366 -:1006300058FF02005752AD233F4E62493E018417D6 -:10064000FEEA0601380612F7450A9501FE841916DE -:10065000FEE0061582014115E203558A10551C077C -:100660000184FEAE10036F1EFE9E133E0184039AAA -:100670001EFE1A1201380612FC01C601FEAC1DFE58 -:1006800043486280F0450A9503B61EF801380624F7 -:1006900036FE02F60771788C004D62493E2D934E6E -:1006A000D00D17FE9A0701FEC01916FE90072620EE -:1006B0009E1582014115E2219E0907FB03E6FE58C3 -:1006C0005710E605FE2A06036F8A106F1C07018487 -:1006D000FE9C325F7501A68615FEE2002FED2A3CD6 -:1006E000FE0AF0FECE07AEFE9608FE06F0FE9E085D -:1006F000AFA00529010C060DFE2E12141D010814D1 -:100700000001081400010814000108FE99A4010862 -:10071000140005FEC60901760612FE3A12010C0607 -:1007200012FE301314FE1B0001081400010814000F -:1007300001081400010814070108140005EF7C4AA1 -:10074000784F0FFE9A8104FE9A83FECB470B0E2D45 -:100750002848FE6C080A28FE096FCAFECA45FE3208 -:100760001253634E7C972FFE7E082A3CFE0AF0FE51 -:100770006C08AFA0AEFE96080529014105ED1424D2 -:1007800005EDFE9CF79F01FEAE1EFE185801FEBE51 -:100790001EFE9958FE7818FEF9188EFE1609106A8A -:1007A000226B010C615444212C091AF87701FE7E5A -:1007B0001E472C7A30F0FE83E7FE3F0071FE0340B7 -:1007C000010C61654401C2C8FE1F40206E01FE6A33 -:1007D00016FE0850FE8A50FE4451FEC651FE10100F -:1007E00001FECE1E01FEDE1E1068226901FEEE1E15 -:1007F00001FEFE1EFE4050FEC250104B224CFE8AEF -:1008000010010C0654FE501201FEAE1E01FEBE1E6B -:10081000106A226B010C06654E01C20FFE1F800498 -:10082000FE9F83330B0E206E0FFE449004FEC49394 -:100830003A0BFEC69004FEC693790B0E106C226D27 -:1008400001FECE1E01FEDE1E106822690FFE4090E2 -:1008500004FEC0933A0BFEC29004FEC293790B0EC5 -:10086000104B224C10642234010C6124443713FED7 -:100870004E112FFEDE09FE9EF0FEF209FE01481B1E -:100880003C3788F5D4FE1E0AD5FE420AD2FE1E0A67 -:10089000D3FE420AAEFE120AFE06F0FE180AAFA010 -:1008A00005290141FEC1101424FEC110017606077E -:1008B000FE14120176060D5D010C060DFE7412FE8B -:1008C0002E1C05FE1A0C017606075D0176060D4109 -:1008D000FE2C1CFEAAF0FECE0AFEACF0FE660AFE5E -:1008E0009210C4F6FEADF0FE720A05FE1A0CC5FEAB -:1008F000E710FE2BF0BFFE6B1823FE00FEFE1C125D -:10090000ACFED2F0BFFE7618231D1BBF03E3230706 -:100910001BBFD45BD55BD25BD35BC4C5FEA910758E -:100920005E321F7F014219FE3500FE01F0701998FA -:100930000570FE741823FE00F81B5B7D1201FE7823 -:100940000F4D01FE961A2130777D1D055B010C06C7 -:100950000D2BFEE20B010C0654FEA612010C062420 -:10096000FE8813216EC701FE1E1F0FFE838004FE4A -:100970008383FEC9470B0EFEC844FE42130FFE04DC -:100980009104FE8493FECA570BFE869104FE869363 -:10099000FECB570B0E7A30FE4059FEC1598E4003F4 -:1009A0006A3B6B10972298D96ADA6B01C2C87A3019 -:1009B000206EDB64DC34916C7E6DFE4455FEE555A3 -:1009C000FE04FA64FE05FA3401FE6A16A3261097A7 -:1009D0001098916C7E6DFE1410010C06241B409142 -:1009E0004B7E4C010C06FEF7004403683B69FE1089 -:1009F00058FE9158FE1459FE9559055B010C0624CA -:100A00001B40010C06FEF700447801FE8E1E4F0FBE -:100A1000FE109004FE90933A0BFE929004FE929387 -:100A2000790B0EFEBD10014309BB1BFE6E0A15BB00 -:100A3000010C060DFE1413034B3B4C8EFE6E0AFE9A -:100A40000C58FE8D58055B263E0FFE198004FE995A -:100A500083330B0EFEE510010C060DFE1A12FE6C20 -:100A600019FE1941FE6B18ACFED1F0EF1F92014246 -:100A700019FE4400FE9010FE6C19D94BFEED19DAF8 -:100A80004CFE0C51FE8E51FE6B1823FE00FF31FE12 -:100A90007610ACFED2F0FEBA0CFE7618231D5D0374 -:100AA000E32307FE081319FE16000570FED1F0FEC1 -:100AB000CC0C1F92014219FE17005CFECEF0FED254 -:100AC0000CFE3E10FECDF0FEDE0C19FE220005707D -:100AD000FECBF0FEEA0C19FE24000570FED0F0FEFD -:100AE000F40C1994FE1C10FECFF0FEFE0C194AF314 -:100AF000FECCF0EF017606244D19FE12003713FEEE -:100B00004E112FFE160DFE9EF0FE2A0DFE01481B13 -:100B10003C3788F5D429D529D229D32937FE9C32F0 -:100B20002FFE3E0D2A3CAEFE620DAFA0D49FD59F96 -:100B3000D29FD39F05290141FED31015FEE800C4C2 -:100B4000C575D799D89CFE89F0292725BED799D895 -:100B50009C2FFE8C0D16292725BDFE0148A419FEE9 -:100B6000420005709007FE81491BFE640E010C06D1 -:100B70000DFE441319002D0DFE54122DFE28002BDE -:100B8000FEDA0E0A57011809003646FE2800FEFA62 -:100B90001001FEF41C01FE001D0ABA01FE581040AF -:100BA00015560185053519FE44002D0DF7460DFE3D -:100BB000CC1001A7460DFEC21001A70FFE1982043A -:100BC000FE9983FECC470B0EFE3446A5460D19FE5A -:100BD0004300FEA210010C610D4401FEF41C01FE55 -:100BE000001D40155601857D0D405101FE9E1E05DC -:100BF000FE3A03010C060D5D460D1900FE62100160 -:100C0000760612FE5C12010C0612FE5213FE1C1C2C -:100C1000FE9DF0FE8E0EFE1C1CFE9DF0FE940E014D -:100C20000C611244FE9F1019FE1500FE04E60D4FE4 -:100C3000FE2E1019FE1300FE101019FE4700F119C8 -:100C4000FE4100A219FE240086C4C57503811E2B37 -:100C5000EA4FFE04E612FE9D41FE1C424001F405EF -:100C600035FE121C1F0D47B5C31FFE310047B801EA -:100C7000FED41105E951FE06ECE0FE0E474628FEC3 -:100C8000CE453151FE06EAE0FE474B45FE7557035F -:100C900067FE9856FE38120A5A0118FE4448600151 -:100CA0000C0628FE18130A5701183EFE41580ABACE -:100CB000FEFA14FE4954B0FE5E0F05FE3A030A67C1 -:100CC000FEE014FE0E474628FECE453151FECE47CB -:100CD000FEAD130535212C091AFE98122620962008 -:100CE000E7FE081CFE7C19FEFD19FE0A1C03E5FE4A -:100CF0004855A53BFE6201FEC95531FE741001FE48 -:100D0000F01A03FE38013BFE3A018EFE1E10FE0271 -:100D1000ECE7530036FE04EC2C60FE05F6FE3401D1 -:100D200001FE621B01FECE1EB211FE1813CAFE02A6 -:100D3000EAE75392FEC3131F1247B5C3FE2A1003FE -:100D4000FE380123FEF0FF10E503FE3A0110FE62BB -:100D50000101FE1E1E202C155601FE9E1E130702C9 -:100D600026022196C720960992FE79131F1D47B5CA -:100D7000C3FEE110CFFE03DCFE7357FE805D02CFA1 -:100D8000FE03DCFE5B57FE805D02FE0357CF26FEAE -:100D900000CC02FE0357CF8902010C064AFE4E1317 -:100DA0000FFE1C8004FE9C83330B0E0907FE3A13D2 -:100DB0000FFE1E8004FE9E83330B0EFE2A130FFED1 -:100DC0001D8004FE9D83FEF9130EFE1C1301FEEE32 -:100DD0001EACFE141301FEFE1EFE8158FA01FE0E2B -:100DE0001FFE30F40DFE3C50A201FE921B01430990 -:100DF00056FB01FEC81A010C0628A401FEF41C01D2 -:100E0000FE001D15FEE900010C064AFE4E1301FE10 -:100E1000221BFE1E1C0FFE149004FE94933A0BFE40 -:100E2000969004FE9693790B0E10FE640122FE66E6 -:100E300001010C0665F90FFE038004FE8383330B6A -:100E40000E77FE01EC2CFE8040202C7A3015DF401E -:100E5000212CFE00408D2C02FE081C03FEAC00FE7F -:100E6000065803FEAE00FE075803FEB000FE085809 -:100E700003FEB200FE0958FE0A1C2E4920E026108F -:100E8000661055106F1357524F1C28FE904DFE915F -:100E9000542BFE8811461A135A521C4AFE904DFEDE -:100EA00091542BFE9E112E1A202C903460212CFE82 -:100EB00000408D2C15DFFE1456FED6F0FEB211FE5A -:100EC000121C75FE141CFE101CFE181C0251FE0C98 -:100ED00014FE0E47FE07E628FECE47FEF51302017C -:100EE000A7903460FE0680FE4847FE4213FE028053 -:100EF0000956FE34130A5A0118CBFE3612FE414839 -:100F0000FE454801FEB216FE00CCCBFEF3133F892E -:100F1000091AA50A9D0118FE805C0185F2099BA4AF -:100F2000FE1456FED6F0FEEC1102FE445877FE0188 -:100F3000ECB8FE9E40FE9DE700FE9CE7128D30015E -:100F4000F4FEDD1037D799D89C2725EE0912FE480C -:100F500012090DFE5612091DFE301209DD1BFEC4DA -:100F60001309FE23001BFED01309071BFE341409CE -:100F700024FE121209001B291FDD0142A1320108C3 -:100F8000AE410232FE62080AE101FE5810159B05CF -:100F90003532014309BBFED713914B7E4C8EFE8048 -:100FA00013010C0654FE7212DB64DC34FE4455FE61 -:100FB000E555B0FE4A13216EFE261303973B988E2B -:100FC000FEB60E106A226B261097109801C22E49A9 -:100FD00088206E01FE6A16DB64DC34FE0455FEA533 -:100FE00055FE04FA64FE05FA34FE8F10036C3B6D67 -:100FF000FE4056FEE156106C226D71DB64DC34FE5F -:101000004455FEE55503683B69FE0056FEA15610A7 -:10101000682269010C0654F9216EFE1F40036A3BE9 -:101020006BFE2C50FEAE50036C3B6DFE4450FEC672 -:101030005003683B69FE0850FE8A50034B3B4CFE50 -:101040004050FEC25005732E07209E0572320108E3 -:10105000163D2725EE09072B3D014309BB2B7201E5 -:10106000A6233F1B3D010C060DFE1E13914B7E4C2B -:10107000FE0A5531FE8B55D94BDA4CFE0C51FE8ED3 -:1010800051057201FE8E1ECAFE1941057232010819 -:101090002A3C16C02725BE2D1DC02D0D832D7F1B7C -:1010A000FE6615053D01082A3C16C02725BD091D11 -:1010B0002B3D010816C02725FEE809FEC249500352 -:1010C000B61E830138062431A1FEBB452D00A4467F -:1010D00007903F01FEF81501A686FE4B45FE201342 -:1010E00001430982FE1613039A1E5D03551E315EED -:1010F0000572FEC05D01A7FE031703668A10665ED7 -:10110000320108177301FE5619057301082A3C16AF -:101110003D2725BD09072B3D01FEBE16FE4258FEA8 -:10112000E81401A686FE4AF40D1B3DFE4AF407FEB4 -:101130000E12014309824E057203558A10555E3224 -:101140000108177301FE8419057301082A3C163D36 -:101150002725BD09122B3D01FEE8178BFEAA14FEC0 -:10116000B61486A8B20D1B3DB207FE0E120143094C -:10117000824E0572036F8A106F5E32010817730189 -:10118000FEC019057313072FFECC1517FEE2155F7D -:10119000CC0108265F028FFEDE152AFEDE1516FE44 -:1011A000CC155E320108FED5101358FF02005752CD -:1011B000AD23FEFF7FFE3056FE005C021358FF0297 -:1011C000005752AD233FFE3056FE005C021358FF1D -:1011D00002005752AD021358FF02005752FE005E44 -:1011E000021358FF02005752ADFE0B58020A660167 -:1011F0005C0A55015C0A6F015C0201FE1E1F231A86 -:10120000FF030054FE00F424520FFE007C04FE078E -:101210007C3A0B0EFE0071FEF918FE7A19FEFB19DE -:10122000FE1AF700FE1BF7007A3010682269D96CAD -:10123000DA6D02FE6208FE824AFEE11AFE835A77E8 -:101240000201C6FE42484F5045010816FEE017272E -:1012500025BE010816FEE0172725FEE80AFEC15943 -:10126000039A1EFEDA1201380612FED0132653121C -:1012700048FE0817D1125312FE1E132DB47BFE2612 -:10128000174D13071CB49004FE7810FF028355F12C -:10129000FF028355531DFE1213D6FE3000B0FE80B0 -:1012A000171C631307FE5610530DFE1613D6FE646B -:1012B00000B0FE80170AFE64001C941307FE28107D -:1012C0005307FE6013D6FEC800B0FE80170AFEC8A2 -:1012D000001C95130771D6FE900148FE8C1745F34C -:1012E000FE43F496FE56F0FE9E17FE04F458FE43AD -:1012F000F494F68B01FE2416233FFCA88C4948FE8B -:10130000DA176249FE1C10A88C8048FEDA1762804A -:10131000715026FE4DF400F7451307FEB456FEC388 -:10132000580250130D02503E784F45010816A92768 -:1013300025BEFE03EAFE7E01010816A92725FEE967 -:101340000A010816A92725FEE90AFE05EAFE7F0123 -:10135000010816A92725FE6909FE02EAFE8001019F -:101360000816A92725FEE80847FE810103B61E835B -:101370000138062431A278F2530736FE34F43FA137 -:1013800078039A1E830138061231F04F45FE901003 -:10139000FE405A233FFB8C4948FEAA186249718CD3 -:1013A0008048FEAA186280FEB456FE405D01C60168 -:1013B000FEAC1DFE0217FEC845FE5AF0FEC018FE28 -:1013C00043482D9336FE34F4FE0011FE40102DB438 -:1013D00036FE34F404FE34102DFE0B00364663FE58 -:1013E0002810FEC049FF020054B2FE900148FEFAE8 -:1013F0001845FE1CF43FF3FE40F496FE56F0FE0C3A -:1014000019FE04F458FE40F494F63E2D934ED00D90 -:1014100021FE7F01FEC846FE24138C005D2621FEBE -:101420007E01FEC845FE141321FE8001FE4845FAE8 -:1014300021FE8101FEC8444E260213070278455062 -:10144000130D021407010817FE8219140D01081765 -:10145000FE8219141D010817FE82195FFE894901D9 -:1014600008021407010817C1141D010817C1140749 -:10147000010817C1FE8949010817C15FFE894A01A9 -:1014800008025002140701081774147F010817742A -:10149000141201081774FE89490108177414000119 -:1014A000081774FE894A01081774FE0949010817D4 -:1014B000745FCC01080221E40907FE4C13C820E444 -:1014C000FE49F4004D5FA15EFE01ECFE2701CCFF5A -:1014D0000200102FFE3E1A014309FEE300FE221314 -:1014E00016FE641A26209E0141219E09075D010C0B -:1014F000610744020A5A0118FE0040AA091AFE12A6 -:10150000130A9D0118AA0A6701A3020A9D0118AADD -:10151000FE80E71A091A5DFE455801FEB216AA02BE -:101520000A5A0118AA0A6701A3020A5A011801FE01 -:101530007E1EFE804CFE49E41AFE12130A9D01181D -:10154000FE804C0A67015C021C1A877CE5FE18DFEE -:10155000FE19DEFE241CFE1DF728B1FE041B01FE51 -:101560002A1CFAB3287CFE2C01FE2F1902C92BFE7F -:10157000F41AFEFA101C1A8703FE6401FE00F4241C -:10158000FE185803FE6601FE1958B32401FE0E1F13 -:10159000FE30F407FE3C507CFE3800FE0F79FE1C46 -:1015A000F724B1FE501BFED4143102C92BFE261BBA -:1015B000FEBA101C1A87FE835AFE18DFFE19DEFEE3 -:1015C0001DF754B1FE721BFEB214FCB3547C12FE24 -:1015D000AF19FE98E70002C92BFE661BFE8A101C9D -:1015E0001A878B0FFE309004FEB0933A0BFE18580A -:1015F000FE329004FEB2933A0BFE19580EA8B34A7D -:101600007C12FE0F79FE1CF74AB1FEC61BFE5E146B -:101610003102C92BFE961B5CFE02F61A87FE18FEED -:101620006AFE19FE6B01FE1E1FFE1DF765B1FEEE80 -:101630001BFE3614FE1C13B3653EFE8358FEAF1925 -:10164000FE80E71AFE81E71A15FEDD007A30027A85 -:1016500030FE12452BFEDC1B1F0747B5C30535FEC8 -:1016600039F0752602FE7E18231D361311028703FA -:10167000E32307FEEF12FEE110903460FE028009C2 -:1016800056FE3C13FE8214FE421351FE06830A5A94 -:101690000118CBFE3E12FE4148FE454801FEB2163F -:1016A000FE00CCCBFEF3133F89091AA50A9D011851 -:1016B000FE804C0185FE1610099B4EFE4014FE2450 -:1016C00012FE1456FED6F0FE521C1C0D02FE9CE7C4 -:1016D0000D19FE1500408D3001F41C070251FE0665 -:1016E00083FE1880612844155601851C0702FE38C8 -:1016F00090FEBA9091DE7EDFFE485531FEC955025C -:1017000021B98820B9020ABA0118FE41480A5701D6 -:1017100018FE49441BFE1E1D8889020A5A01180939 -:101720001AA40A6701A30A570118888902FE4EE429 -:101730001D7BFE521D03FE9000FE3A45FE2C10FE5E -:101740004EE4DD7BFE641D03FE9200D112FE1A10F2 -:10175000FE4EE4FE0B007BFE761D03FE9400D124BA -:10176000FE081003FE9600D163FE4E4583CAFF04B7 -:101770006854FEF1102349FE081CFE6719FE0A1C7E -:10178000FE1AF4FE000483B21D48FEAA1D131D02BA -:101790000992FE5AF0FEBA1D2E93FE34100912FE75 -:1017A0005AF0FEC81D2EB4FE2610091D362E63FE0B -:1017B0001A10090D362E94F20907362E95A1C8028B -:1017C0001F930142FE04FE99039C8B022AFE1C1EFD -:1017D000FE14F0082FFE0C1E2AFE1C1E8FFE1C1E7F -:1017E000FE82F0FE101E020F3F04FE8083330B0EBC -:1017F000020FFE188004FE9883330B0E020FFE02C8 -:101800008004FE8283330B0E020FFE068004FE86E8 -:1018100083330B0E020FFE1B8004FE9B83330B0EE3 -:10182000020FFE048004FE8483330B0E020FFE8041 -:101830008004FE8083FEC9470B0E020FFE1981044F -:10184000FE9983FECA470B0E020FFE068304FE8636 -:1018500083FECE470B0E020FFE2C9004FEAC933A93 -:101860000B0E020FFEAE9004FEAE93790B0E020F2C -:10187000FE089004FE88933A0B0E020FFE8A900435 -:10188000FE8A93790B0E020FFE0C9004FE8C933AA5 -:101890000B0E020FFE8E9004FE8E93790B0E020F3C -:1018A000FE3C9004FEBC933A0B0E028B0FFE0380AD -:0E18B00004FE8383330B770EA802FF66000050 -:00000001FF -/* Microcode buffer is kept after initialization for error recovery. */ diff --git a/firmware/advansys/mcode.bin.ihex b/firmware/advansys/mcode.bin.ihex deleted file mode 100644 index cd160d9386673641246cfe060ed6733140d3fed0..0000000000000000000000000000000000000000 --- a/firmware/advansys/mcode.bin.ihex +++ /dev/null @@ -1,147 +0,0 @@ -:100000003F452C01010301190F0000000000000012 -:10001000000000000F0F0F0F0F0F0F0F0000000068 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:100040000000000000000000C3120D0501000000C8 -:1000500000FF000000000000FF80FFFF0100000023 -:10006000000000000000002300000000000700FF67 -:1000700000000000FFFFFF00000000000000E48817 -:100080000000000080734804360000A2C2008073A4 -:1000900003233640B600360005D60CD212DA00A291 -:1000A000C20092801E985000F5004898DF23366009 -:1000B000B60092804F00F5004898EF233660B600F6 -:1000C000928080629280004615EE13EA020109D800 -:1000D000CD044D0000A3D600A6977F2304618401C0 -:1000E000E684D2C18073CD044D0000A3DA01A69747 -:1000F000C681C28880738077000101A1FE004F0095 -:10010000849707A6080100330300C288030301DEB9 -:10011000C288CE006960CE0002034A6000A2780166 -:10012000806307A62401788103038063E20007A6A9 -:10013000340100330400C2880307020104CA0D23FE -:1001400068984D04048505D80D236898CD041523BF -:10015000F888FB23026182018063020306A3620127 -:1001600000330A00C2884E0007A36E0100330B0063 -:10017000C288CD04362D00331A00C288500488810D -:1001800006AB820188814E0007A39201500000A3B4 -:100190003C0100057C814697020105C60423A001AD -:1001A0001523A101BE81FD23026182010ADA4A0002 -:1001B000066100A0B4018063CD04362D00331B001E -:1001C000C28806236898CD04E684060100A2D40103 -:1001D000576000A0DA01E6848023A001E6848073E2 -:1001E0004B00066100A2000204010CDE020103CCF8 -:1001F0004F008497FC810823024182014F006297DF -:1002000048048480F0970046560003C00123E800AC -:1002100081730629034206E203EE6BEB1123F88893 -:100220000498F0808073807707A42A027C9506A644 -:10023000340203A64C044682040103D8B4986A969B -:100240004682FE95806783038063B62D02A66C020A -:1002500007A65A0206A65E0203A66202C2887C9521 -:100260004882609648820423A0011423A1013C84A3 -:1002700004010CDCE0232561EF0014014F04A80108 -:100280006F00A5010323A40106239C01242B1C015C -:1002900002A6AA0207A65A0206A65E0203A6200428 -:1002A00001A6B40200A6B40200331200C288000EF8 -:1002B0008063004300A08C024D0404010BDCE723A3 -:1002C00004618401103112351401EC006C38003FD8 -:1002D0000000EA821823046118A0E2020401A2C807 -:1002E00000331F00C28808310A350C390E3D7E9854 -:1002F000B62D01A6140300A6140307A60C0306A638 -:10030000100303A6200402A66C0200333300C28847 -:100310007C95EE826096EE82829880427E9864E4BC -:1003200004012DC83105070100A2540300438701D1 -:10033000050586987E9800A6160307A64C0303A61B -:100340003C0406A6500301A6160300332500C2880C -:100350007C95328360963283040110CE07C8050570 -:10036000EB0400330020C020816272830001050588 -:10037000FFA27A03B1010823B2012E8305051501FE -:1003800000A29A03EC006E0095016C38003F00005B -:1003900001A6960300A69603108480427E9801A6CB -:1003A000A40300A6BC031084A898804201A6A4035D -:1003B00007A6B203D4837C95A88300332F00C2889C -:1003C000A898804200A6BC0307A6CA03D4837C95E4 -:1003D000C08300332600C288382B80328036042345 -:1003E000A0011223A101108407F006A4F403806B7E -:1003F000806705238303806303A60E0407A6060413 -:1004000006A60A0400331700C2887C95F483609620 -:10041000F483208407F006A42004806B8067052302 -:1004200083038063B62D03A63C0407A6340406A606 -:10043000380400333000C2887C9520846096208484 -:100440001D0106CC00330084C0200023EA00816235 -:10045000A20D806307A65A0400331800C288030364 -:100460008063A30107A46404230100A286040AA0F8 -:100470007604E00000331D00C2880BA08204E00077 -:1004800000331E00C2884223F888002322A3E6041A -:10049000082322A3A204282322A3AE04022322A31A -:1004A000C4044223F8884A00066100A0AE04452334 -:1004B000F888049800A2C004B49800330082C020D9 -:1004C0008162E8814723F88804010BDE0498B49820 -:1004D00000330081C0208162140100A00002432388 -:1004E000F8880423A0014423A10180734D0003A3D5 -:1004F000F40400332700C288040104DC0223A201B3 -:100500000423A001049826954B00F6004F044F00E9 -:1005100000A3220500057600066100A21C050A85DD -:100520004697CD04248548048480020103DA8023A1 -:10053000820134850223A0014A00066100A2400521 -:100540001D0104D6FF2386414B60CB00FF238001B1 -:1005500049008101040102C830018001F704030150 -:1005600049048001C90000050001FFA0600577046F -:100570000123EA005D00FEC700620023EA00006379 -:1005800007A4F805030302A08E05F48500332D00AF -:10059000C28804A0B80580630023DF004A0006611A -:1005A00000A2A4051D0106D60223024182015000CB -:1005B00062970485042302418201048508A0BE05D8 -:1005C000F48503A0C405F48501A0CE0588008063EE -:1005D000CC8607A0EE055F00002BDF0800A2E60531 -:1005E0008067806301A27A067C8506236898482389 -:1005F000F88807238000068780637C850023DF005E -:1006000000634A00066100A236061D0116D4C0230D -:1006100007418303806306A61C0600333700C288A7 -:100620001D0101D620236360830380630223DF0062 -:1006300007A67C05EF046F0000634B000641CB006A -:100640005200066100A24E061D0103CAC0230741E5 -:1006500000631D0104CC00330083C020816280232D -:1006600007410063806708238303806300630123DD -:10067000DF0006A6840607A67C058067806300333A -:100680000040C020816200630000FE958303806308 -:1006900006A6940607A67C05000001A01407002BFF -:1006A000400E8063010006A6AA0607A67C05400E40 -:1006B0008063004300A0A20606A6BC0607A67C0530 -:1006C0008067400E806307A67C050023DF0000637F -:1006D00007A6D60600332A00C28803038063890078 -:1006E0000A2B07A6E80600332900C288004300A2AF -:1006F000F406C00E8063DE86C00E00330080C0208A -:100700008162040102DA80637C85807B806306A6B7 -:100710008C0600332C00C2880CA22E07FE958303A2 -:10072000806306A62C0707A67C0500333D00C2881F -:1007300000008067830380630CA0440707A67C0544 -:10074000BF2304618401E6840063F0040101F10029 -:100750000001F20001058001720471008101700442 -:10076000800581050063F004F20072040101F100CC -:1007700070008101700471008101720080017104B8 -:100780007000800170040063F004F2007204000144 -:10079000F10070008001700471008001720081011D -:1007A000710470008101700400630023B3018305AC -:1007B000A301A201A1010123A0010001C80003A11E -:1007C000C40700330700C28880058105040111C8F1 -:1007D0004800B001B1010823B201050148040043FB -:1007E00000A2E4070005DA870001C800FF238001AA -:1007F00005050063F7041A09F6086E040002804339 -:100800007608800277040063F7041A09F6086E047C -:10081000000200A0140816880043760880027704BE -:100820000063F3040023F40074008043F400CF401D -:1008300000A2440874040201F7C9F6D9000101A11D -:10084000240804982695248873040063F30475042F -:100850005A88020104D84697049826954A8875005C -:1008600000A3640800054E8873040063807B8063E6 -:1008700006A6760800333E00C28880678303806343 -:100880000063382B9C88382B928832093105929866 -:100890000505B209006300320036003A003E0063ED -:1008A00080328036803A803EB43D0063382B40323F -:1008B0004036403A403E00635A20C94000A0B40888 -:1008C0005D00FEC300638073E6200223E8008273AC -:1008D000FFFD80731323F8886620C0200423A00145 -:1008E000A123A1018162E28880738077680000A261 -:1008F000800003C2F1C74123F8881123A10104231A -:04090000A001E684E8 -:00000001FF -/* Microcode buffer is kept after initialization for error recovery. */ diff --git a/firmware/atmsar11.HEX b/firmware/atmsar11.HEX deleted file mode 100644 index dfddc190ac240cb6105d1d32dd088247d650d75a..0000000000000000000000000000000000000000 --- a/firmware/atmsar11.HEX +++ /dev/null @@ -1,204 +0,0 @@ -:04000000A0D0F0009C -:2C008000401A680000000000335B007C13600005335B10003C1AA0C0375A018003400008000000001760FFFB335B400020 -:2C00AC00401A700013600003241B0FC0AF9B45002508000803400008420000108F810C9032220002104000033C03A0D174 -:2C00D8002463F8100060F809242100011000001AAF810C9082020011AF900C480441000A34420080967D000296020012A4 -:2C01040000000000105D00110000000004110161A66200021000000DAE62000C34848000A20200114D01FFFF000000005E -:2C0130008F834C0000000000AF830FEC00E0F80903E03821000414000440FFF700000000AF80460C8E1000084D01FFFF36 -:2C015C00000000008F834C004900001DAF830FEC8F820CBC8F9D0C4C2442000197BE0000AF820CBC13C00009ACA200D872 -:2C018800A7A000003C0100D1003E08259422002C0411013FA4220002AC22000CAC2000108F9E0C5427BD000217BE00028C -:2C01B4008CA200C08F9D0C508F970FC8AF9D0C4C12E20005878040023C02A0D12442F94C0040F8090000000000E0F8094A -:2C01E00003E038214500FFDC8E11000C3C1300D1001111022C4304001060FFB900021180026298218E76003C32220008C1 -:2C020C001440FFB78E7700348E7500303C03CFB016C0000302D5102B041100BE000000001040FFA6007018264D01FFFFE5 -:2C023800000000008F824C00AF974C00AF820FECAC7600100260902132220002104000078F944A009602003A3484000492 -:2C02640014400003AF820FBC3C029000AF820FBC8E10000832943F008E11000C2694FF00128000733C1300D14901007162 -:2C0290003237000816E0006F001111022C4304001060006C0002B980000417400440003A027798211272002326D60030E0 -:2C02BC00AE56003C8E76003C8E7700348E7500303C03CFB016C0000302D5102B0411009100000000104000602E8210006B -:2C02E80014400009007018264D01FFFF000000008F824C00AF974C00AC760010AE4200341000FFD0AF80460C00E0F8090D -:2C03140003E038213C03CFB000701826AE4600344D01FFFF000000008F824C00AF974C00AF820FECAC7600101000FFC382 -:2C034000AF80460C02D5102B104000423C17CFB02E8210001440000602F0B8264D01FFFF00000000AEF600101000FFB8E9 -:2C036C00AF80460C00E0F80903E038214D01FFFF000000008F824C00AF864C00AEF60010AF820FEC1000FFAEAF80460C7F -:2C0398003084FFFB8E5700383242FFC000021182A7820FB8AF970FB4865D002A865E0008A79D0FBA279D0F1833DE00604B -:2C03C40003BEE821001EF0C203BEE8218F970C584D01FFFF000000008F834C008FA2001C12E300033C030C403C1EC0008B -:2C03F000AF9E0FBCAC620FB48FA300182442000C14430002AF80460C8FA20014AE40003CAFA2001C8E76003C8E7700340D -:2C041C008E7500303C03CFB016C0000302D5102B0411003C00000000007018264D01FFFF00000000ACA500E410400032D6 -:2C044800AF974C001000FF7FAC760010000417400440000726D60030AE56003C00E0F80903E03821AF80460C1000FF393E -:2C047400AE4600348E5700383242FFC000021182A7820FB8AF970FB48F970C5800E0F80903E0382112E600033C030C4029 -:2C04A0003C02C000AF820FBC865D002A865E0008A79D0FBA279D0F1833DE006003BEE821001EF0C203BEE8218FA2001C23 -:2C04CC004D01FFFF000000008F974C00AC620FB43084FFFB8FA300182442000C14430002AF80460C8FA20014AE40003CC2 -:2C04F800AFA2001C4D01FFFF00000000ACA500E41000FF13AF974C0000E0F80903E038211000FF0F000000001040005B50 -:2C052400867E0008279D0F1833DE006003BEE821001E10C203A2E8218FB700088FA2000C8EF6000412E2002886620008BC -:2C05500082030010000217400441001924630001106000173C02D1B0005010264D01FFFF000000008F9E4C00AC56001008 -:2C057C0026D6FFFE860200103C03CFB034632000A662002A8EE2000026F70008AE6200388FA20020AFB700082417FFFF46 -:2C05A80002C2A8214D01FFFF00000000AF9E4C0003E00008AE7500308EE2000026F70008AE6200388FA20020AFB70008DB -:2C05D4002417FFFFA677002A02C2A8213C03CFB003E00008AE750030001E18C2006518218C6300C88FA200100000000064 -:2C0600000062B0231EC000038FA1000412C0001B0022B0232EC30041146000023C1500402416004000161E80000318829E -:2C062C00007518254D01FFFF000000008F954C00001EB84000771821AC624D00005610211441000227830D008FA200004D -:2C06580002E3B821AFA2001002D71821AFA3000C4D01FFFF000000008EF600041000FFB5AF954C003C16DEADAE76003C82 -:2C068400AE60003826D5FFFF0000102103E00008AE7500302C430AB2106000052C4324B21000000424020AB210000002AF -:2C06B000240224B11060FFFD304301FF000318403C1DA0D127BDD6CC007D1821946300000002EA4200031C0027BDFFFBC1 -:2C06DC0003E0000803A3100624030FC0AF83450010000002012060213C0CCFB011E000560189602685FE00000000000089 -:2C07080013C000473C02CFB007C0002D001E1F8004610034001E1FC0046000093C02D3B000E0F80903E038214D01FFFF10 -:2C073400000000008F864C008F990FEC1000000BAF994C0001E2782600E0F80903E038214D01FFFF000000008F864C001B -:2C076000AF994C00ADEF20103C02D3B001E278268F820FC08F830FC4AF824D008DE20004A5E00000AC6200008C62000094 -:2C078C0024020380AF824D008F824D008F820F1424630004146200022419FFFF8F830F10ACA500E4AF830FC44D01FFFF93 -:2C07B800000000008F824C801000001FADE2003C00E0F80903E038214D01FFFF00000000A5E000008F864C001580002238 -:2C07E400AF8F45401000001701E2782600E0F80903E038214D01FFFF000000008F864C00AF994C00ADEF20103C02CFB097 -:2C08100001E27826A5E000004D01FFFF00000000100000078F994C0000E0F80903E038214D01FFFF000000008F864C0015 -:2C083C008F990FEC1580000AAF8F45000000782110000014AF19001400E0F80903E038214D01FFFF000000001180FFF8C1 -:2C0868008F864C0085220000012078210440000A8D290008130B0004000C1602AF1900148D7900140160C021AF994C0084 -:2C089400AD8E40103042003F01C27021000417800440018B8F824A0030818000304200041440FF8D8D4B00001020000C47 -:2C08C00030847FFF8F820C480120F021244300348C5D000C24420004AFDD000C1462FFFC27DE0004A52100001000FF82E0 -:2C08EC00250800081160005800000000857D00088D63000C9562000A8D41000407A1002600621821A563000A00031C026D -:2C091800041101A0000318C0001D16C00441001F27A2008000021CC00461000E0040E82127BD0080956200009563000293 -:2C0944003442000CAD22000C24020100A52200109562002CA5230014A5220012A520001634028000A5220000A57D0008D2 -:2C09700007A0000C8F820C4C8F830C502441FFE80023F02B13C000020020102124420400945E00002441FFFE17C0FFF994 -:2C099C00AD620010A44B0000142B001CAD400000AD400004254A00083142007F1440000E00041780044100038F820FE03A -:2C09C800100000063484000134840002244200083442100038421000AF820FE0354A0100394A010039420080AF820FE4B9 -:2C09F400001D14C00441000333A2EFFF1000FF3CA562000807A0009F33A2FFFE10000021A56200088D620024001D1CC01D -:2C0A200004610004AD42000033A3EFFF1000FF31A563000807A0000533A3FFFEA56300088D4B00001000FFAA000000001E -:2C0A4C001000008E25080008254A00083142007F1440000E00041780044100038F820FE010000006348400013484000274 -:2C0A7800244200083442100038421000AF820FE0354A0100394A010039420080AF820FE4110000038D4B00001000FF9303 -:2C0AA4002508FFF88F820FD88F830FDC8F810FD41062001D246200084D01FFFF000000008F8C4C00847F00003C1E00D11C -:2C0AD00033FD03FF001D5980017E5821857E0008001DE900001E0F0003E1F82507E00003AF820FDC879E0CA0278B0C986E -:2C0AFC0007C100423C0208403C01F7B08D62002000230826AC2200008C620004946300022442FFF8004310211000004E12 -:2C0B2800AD6200208F820FD087830CA014220007278B0C98410000513C018000ACA100E08CA100C4000000001022004C4E -:2C0B54000022E8238F9F0F0C07A10002AF810FD403E2E8232FA30041146000023C1E0040241D0040001D1E800003188256 -:2C0B8000007E18254D01FFFF000000008F8C4C00AC624CC0005D1021145F000227830CC08F820F0803A3F021AF820FD059 -:2C0BAC00AF9E0FD84D01FFFF000000001000FFC3246200088D63000C8D7D0010A563000A13A0000200031C02A7A00000F8 -:2C0BD800000318C0041100EF006818214D01FFFF000000008F820C448F830C40AD620010A5630004A563000610000021FC -:2C0C0400AF8C4C00A57D00008C7D000494630002AC5D4C4027A20008AD62001803A3E82127BDFFF4AD7D001C27BD0004D4 -:2C0C3000AD7D002037C18001001E17C00441FFE0A56100084D01FFFF000000008F820C448F830C40AD620010A563000478 -:2C0C5C00A56300068F820FD88F830FDC4D01FFFF000000001462FF9524620008AF8C4C0087830CA0278B0C980461FE97F8 -:2C0C88000004170004400005956200001178000600000000AF0E0010A70D00043084FFF7956D00048D6E001025ADFFD075 -:2C0CB40005A1FE8FAD22000C3C0CFFB001896026000D182225AD00308D7E00188D61001C4D01FFFF00000000103E0036B9 -:2C0CE0008F9D4C003C010840AC3E4C4027DE000811A00017AD7E0018000DF600019E60254D01FFFF00000000AD8E40105F -:2C0D0C008F8D0C40957E00068F8E0C4403CDF021A57E0006000CF782000C0E0203C1F021001E0F80000C6200000C6202C2 -:2C0D38000181602533DE003C019E60213401000110000008A5210000957E00064D01FFFF000000008F8D0C408F8E0C44CD -:2C0D640003CDF021A57E00064D01FFFF0000000001A3F02B17C000080003F60001A36823019E6025018960264D01FFF7CF -:2C0D9000000000001000FE58AF9D4C008D7E00188D61001C00000000143EFFCE006D18234D01FFFF000000002C61000864 -:2C0DBC001020001795610008000000000001FF8007E0000B34210002006D182100031E000183602501896026240D002CC0 -:2C0DE800A56100084D01FFFF000000001000FE40AF9D4C003C1F0C40AFFE4FA83021FFFDA56100083C0CD3CF358CE0006E -:2C0E140010000008340300023C1F0C40AFFE4FA811A0FFF9000DF60034030003019E6025018960263484000834420002C4 -:2C0E4000AD22000C95620006A5230000AD2200384D01FFFF00000000857E00088F820FA897830FACAD22000433C17FFFA6 -:2C0E6C00AD600010A56100081060FE20AF9D4C00A57E00080003190030633FF0A56300008F820FB03C030840AC624C4007 -:2C0E980024430008AD63001897830FAE2442FFF400621821AD63001C4D01FFFF000000008F8D0C408F830C44A56D000474 -:2C0EC400A56D0006AD6300101000FE0AAF9D4C008F820FE000040FC08C4300000421001B8F9F0FE48C5D0004AC4000043A -:2C0EF0001060000EAC400000000000009462002800000000005F10208C4100040000000010200003AC43000410000002B6 -:2C0F1C00AC230024AC43000017A3FFF48C6300248F820FE03BFF0080244200083442100038421000AF820FE0AF9F0FE46E -:2C0F48001000FE573084FFFE1060001000000000947D00280000000003BFE8208FA10004AFA30004102000038C5E000439 -:2C0F740010000002AC230024AFA300008C61002417C3FE48AC410000AC400004AC4000001000FE443084FFFD2C6201006F -:2C0FA0001440000E006A10213143007F01431823004318233062007FA562002800621823000319028F820FE02463FFF8BF -:2C0FCC000062182134631000100000033863100034430100386301008C6200040000000010400003AC6B000403E000089A -:0C0FF800AC4B002403E00008AC6B0000D0 -:02000004A0D08A -:2CD5000000000002A0D0E00000000000000010000000000600000008000000000000000800000002A0D0D64800000000F7 -:2CD52C00000008880000000000000000000000000000000024313200243132002431320000000000244D43522420436FB2 -:2CD558007079726967687420286329204D61646765204E6574776F726B73204C746420313939352E20416C6C207269674C -:2CD584006874732072657365727665642E004D6164676520416D6261737361646F722076312E303100000000000000012C -:2CD5B00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000004E -:2CD5DC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:2CD608000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6 -:0CD6340000000000FFF0400000000000BB -:2CF000000C343E2D000000003C1CA0D1279C56383C1DA0D127BDDFD03C08A0D12508DFD0AF8780080C343C1300000000E4 -:2CF02C00240400030097000D3C08BFC0350802308D08000000000000010000080000000027BDFFD0AFBF001CAFB1001864 -:2CF05800AFB000143C11FFF0000080213C18005637183B7926190200172000020319001A0007000D2401FFFF172100056B -:2CF08400000000003C01800017010002000000000006000D00001012001018403C05A0D124A5D6CC00A32021A4820000C5 -:2CF0B000261000012A0102001420FFEA000000003C06A0D124C6F9E43C07A0D124E7D648ACE600003C08A0D12508FB14D9 -:2CF0DC00ACE800043C09A0D12529FC94ACE900083C0AA0D1254AFCD4ACEA000C3C0BA0D1256BFBA8ACEB00103C0CA0D15C -:2CF10800258CFBC4ACEC00143C0DA0D125ADFBE0ACED00183C0EA0D125CEFBFCACEE001C3C0FA0D125EFFC18ACEF0020AD -:2CF134003C18A0D12718FC34ACF800243C19A0D12739FC50ACF900283C02A0D12442FC60ACE2002C3C03A0D12463FC70A6 -:2CF16000ACE300303C04A0D12484FC80ACE400343C05A0D124A5FCB4ACE500383C06A0D124C6FE08ACE6003C3C08A0D111 -:2CF18C002508FE90ACE800403C09A0D12529FA38ACE900443C0AA0D1254AFA74ACEA0048241000133C0BA0D1256BF9D8E7 -:2CF1B800001060803C0EA0D125CED64801CC6821ADAB0000261000012A0100201420FFF6000000008F988000000000006F -:2CF1E400AF0001008F828000241903FFA4590202000080218F86800024030FFF0010204024C7038000E42821A4A30000C1 -:2CF21000261000012A0100081420FFF7000000008F89800034089C40AD2803A08F8B80003C0A00FF354AFFFFAD6A03A4FC -:2CF23C00000080218F8F8000240C0FFF0010684025F80300030D7021A5CC0000261000012A0100081420FFF700000000AB -:2CF268008F82800034199C40AC5903208F8480003C0300FF3463FFFFAC8303248F868000240502FFA4C502023C08A0C00C -:2CF29400350801803C09A0D12529D5B8250A00288D0B00008D0C0004AD2B0000AD2C000425080008150AFFFA252900081B -:2CF2C0004002600000000000AFA20028240300223C04A0E034840014AC8300008FA500280000000034A6100100C01021CB -:2CF2EC00AFA600283C07FFBF34E7FFFF00C7382400E01021AFA7002840876000000000003C0800023508D8903C09FFFE59 -:2CF3180035290130AD2800008FAA00283C0BF000014B582501601021AFAB002801606021408C6000000000000000802141 -:2CF3440000107080022E7821ADE00000261000012A0104001420FFFA00000000241800013C19A0E8AF380000240200117C -:2CF370003C03A0F034630017A06200003C04F0EB348400703C05FFF034A54A00ACA400003C06FCEB34C60070ACA6000027 -:2CF39C003C07FFF034E74700ACE00000000080213C08FFF035080FC03C09FFF035294500AD280000261000012A01000433 -:2CF3C8001420FFF800000000000080213C0ADEAD001059803C0100D1002B0821AC2A003C3C0100D1002B0821AC200030C1 -:2CF3F4003C0100D1002B0821AC200038240DFFFF3C0100D1002B0821AC2D0014001071003C0100D1002B0821A42E000054 -:2CF420003C0100D1002B0821A4200004241800203C0100D1002B0821A43800083C0100D1002B0821AC200010261000017F -:2CF44C002A0104001420FFE00000000000008021001018C03C05A0D124A5E00000A32021AC8000003C07A0D124E7E000BF -:2CF4780024E8000401033021ACC00000261000012A0100091420FFF300000000240903803C0AFFF0354A4D00AD4900005F -:2CF4A4003C0CA080358C009CAD8000003C0DA08035AD00A0ADA000003C0E11003C0FA08035EF00A8ADEE000041010003A0 -:2CF4D000000000004100FFFF000000003C18A080371800E08F1900003C01A0D1AC39D6C80C343D43032020218FB00014DE -:2CF4FC008FBF001C8FB1001803E0000827BD00300080B8213C1CFFF0A3800C84A3800C888F90440000002021AF800CBC7E -:2CF52800240200A827830F002C5D004017A0000C3C1DFFB003A3E826AFB740000000000000000000000000004D01FFFFF6 -:2CF55400000000002442FFC0246300401000FFF326F700401040000D000000000002EE003C01004003A1E8253C01FFF099 -:2CF5800003A1E82603A3E826AFB740000000000000000000000000004D01FFFF000000003C05A0808F820F08000000007E -:2CF5AC00AF820FD4AF820FD0ACA200C48F820F100000000000021D82AF830FC000031D80004310233C01A0800041102542 -:2CF5D800AF820FC4AF820F108F820F1400000000004310233C01A08000411025AF820F1424030003279D0F1824BE00C823 -:2CF6040027810D008FA2000000000000AFA20010AFC20000AFA10008AFA1000C8FA2001400000000AFA2001C27BD0024B4 -:2CF6300027DE0004242100401460FFF32463FFFF8F820F0000000000AF820FC8ACA200C0278208002403000FAC4000002C -:2CF65C00244200041460FFFD2463FFFF8F830FC000000000AF834D008F834D008F830F148F820F102463FFFCAC40000091 -:2CF688001443FFFE2442000424020380AF824D00279D0F1827A100908FA200148FA3001800000000006218232C7F004017 -:2CF6B40017E000093C1F004037FF080003A0F0214D01FFFF00000000AFE20000244200401000FFF62463FFC01060000659 -:2CF6E00037FF080000031E0003E3F8254D01FFFF00000000AFE2000027BD002417A1FFE800000000000038218FC200145A -:2CF70C008FC3001800000000006218232C7F004013E000043C1F004000030E001000000203E1F8252403004037FF080084 -:2CF73800241E03E7000008214D01FFFF00000000AFE20000002308214900FFFB000000008780400217C0FFF827DEFFFFCA -:2CF7640014E0000434E7400003E7F8251000FFF0AF810C60AF810C5C3C01A0D18C22D6C8000000003C01A080AC2200E0E7 -:2CF790003C01A0808C2000E0AF800FB4A7800FB8A7800FBAA7800FBCA7800FBE27820CC0AF820FDCAF820FD83C02A0D156 -:2CF7BC002442DACCAF820C4CAF820C5024420400AF820C542402001E3C03FFF0247D0040AC7D000803A018211440FFFC55 -:2CF7E8002442FFFF3C1DFFF0AC7D00083C02C7043442DD7BAF820C583C07000024E7015808343FA9000000008E620038B9 -:2CF8140000000000144000058F830C9412A000222463000110000020AF830C94AF820FB43262FFC0000211828663002A70 -:2CF84000A7820FB83C02A000AF820FBCA7830FBA867E0008279D0F1833DE006003BEE821001EF0C203BEE8218FA2001CC6 -:2CF86C003C030C404D01FFFF000000008F974C00AC620FB48FA300182442000C14430003000000008FA2001400000000FB -:2CF89800AFA2001C4D01FFFF00000000ACA500E4AF974C0003E00008AE60003C3C0DA0D125ADD50011A00021000000005C -:2CF8C4008DA90000000000001120001D000000008DAA00048DAB00088DAC000C0009474005010004000000003C08A0D185 -:2CF8F0002508D638014850210009478005010007000000001180000D00000000AD400000254A00041000FFFB258CFFFC66 -:2CF91C0011800007000000008D6E0000256B0004AD4E0000254A00041000FFF9258CFFFC1000FFE125AD001003E00008B9 -:2CF94800000000003C021040AC574FF0000000000000000000000000000000004D01FFFF000000008F820FFC000000005B -:2CF974003042001F000210803C17A0D102E2B82126F7D6488EF700000000000002E00008000000002402FFFFAF820FFCB9 -:2CF9A0008F970FC83C021040AC570FF08F820F0426F7001016E20004AF970FC88F970F0000000000AF970FC84D01FFFFA6 -:2CF9CC000000000003E00008000000003C1FA0D127FFF02C1000FFED8F970FF03C0200D132F703FF0017B98002E2B825AA -:2CF9F800AEE0003C2402FFFFAEE20030AEE2001497830FF497820FF83C1D000027BD0698A6E30008A6E20002AF9F0FE819 -:2CFA240003A0F809A6E2002C8F9F0FE81000FFD9AEE2000C8F970FF03C0200D132F703FF0017B98002E2B82597820FF429 -:2CFA50003C03000024630698A6E20002AF9F0FE80060F809A6E2002C8F9F0FE81000FFCAAEE2000C8F970FF03C0200D174 -:2CFA7C0032F703FF0017B98002E2B82597820FF40000000096E30008A6E2000800431026304200601040FFBD8EE2003CF2 -:2CFAA800AEE0003C1040FFBA3C028800AF820FBC8EE20038AEE0003830630060279D0F1803A3E821000318C203A3E82116 -:2CFAD4008FA3001C1040FFAFAF820FB43C020C40AC430FB48FA200182463000C14430003000000008FA30014000000000E -:2CFB0000AFA3001C4D01FFFF000000001000FFA2000000008F970FF03C0200D1A7970FB80017B98032F7FFC002E2B82140 -:2CFB2C00AEE000303C02DEAD8EE3003CAEE2003C8EE200381060FF95AEE000383C038800AF830FBC86E3000827970F1821 -:2CFB58003063006002E3B821000318C202E3B8218EE3001C1040FF8AAF820FB43C020C40AC430FB48EE200182463000C84 -:2CFB840014430003000000008EE3001400000000AEE3001C4D01FFFF000000001000FF7D000000008F820FF08F970FF4B8 -:2CFBB0009041000000000000003708251000FF76A04100008F820FF08F970FF49441000000000000003708251000FF6F9E -:2CFBDC00A44100008F820FF08F970FF48C41000000000000003708251000FF68AC4100008F820FF08F970FF49041000040 -:2CFC080002E0B827003708241000FF61A04100008F820FF08F970FF49441000002E0B827003708241000FF5AA4410000DB -:2CFC34008F820FF08F970FF48C41000002E0B827003708241000FF53AC4100008F820FF08F970FF41000FF4FA05700009D -:2CFC60008F820FF08F970FF41000FF4BA45700008F820FF08F970FF41000FF47AC5700008F820FF0000000008C4200007A -:2CFC8C001000FF42AF820FF43C01A0C28C22C00000000000AF820FF03C01A0C28C22C0041000FF3AAF820FF43C01A0D14E -:2CFCB8008C22D5AC00000000AF820FF03C01A0D18C22D5B01000FF32AF820FF43C02A0F0AC400000905701530000000076 -:2CFCE400A3970C809057015700000000A3970C819057015B00000000A3970C879057015F00000000A3970C8690570163BA -:2CFD10000000000032F70007A3970C859057019300000000A3970C8B9057019700000000A3970C8A9057019B00000000AE -:2CFD3C0032F70007A3970C899057000B0000000032F700E000170942905700470000000032F700780037082590570067BE -:2CFD68000000000032F7000F0017B9C000370825905700C70000000032F7002F0017BAC000370825905701470000000019 -:2CFD940032F7001E0017BC0000370825905701830000000032F700600017BC0000370825AF810C8C3C0218408F970FC83F -:2CFDC000000000008F970FF000000000AC570C800000000000000000000000000000000000000000000000004D01FFFF17 -:2CFDEC00000000003C02A0D12442F998AF800C90AF800C94004000080000000087970FF03C1300D1A67700083C030000C2 -:2CFE180024630520AF9F0FE80060F809240200018F9F0FE81040FEDA97970FF027830F18007718210017B8C202E3B821FB -:2CFE44003C028800AF820FBC8E620038A7800FB8AF820FB48EE3001C3C020C40AC430FB48EE200182463000C1443000487 -:2CFE7000AEE3001C8EE3001400000000AEE3001C4D01FFFF000000001000FFDF000000008F820C5C8F830C60AF820FF026 -:2CFE9C001000FEBEAF830FF423890800012018212402000F206C0040AC6C0008018018211440FFFC2042FFFFAC69000884 -:2CFEC800278B0C98A56000002403FFFFAD6300143402000134420020A5620008278A0E000140102100001821AC40000038 -:2CFEF400246300042C6C01001580FFFC244200043C02A0D12442E000AF820FE03C1800D1012060210000682100007821C6 -:28FF20000000582100004021400260000000000034424001408260003C020000244206F800400008000000007A -:00000001FF -/* - Madge Ambassador ATM Adapter microcode. - Copyright (C) 1995-1999 Madge Networks Ltd. - - This microcode data is placed under the terms of the GNU General - Public License. The GPL is contained in /usr/doc/copyright/GPL on a - Debian system and in the file COPYING in the Linux kernel source. - - We would prefer you not to distribute modified versions without - consultation and not to ask for assembly/other microcode source. -*/ - -First record is start address in a __be32. diff --git a/firmware/av7110/Boot.S b/firmware/av7110/Boot.S deleted file mode 100644 index d562fdc2908f5fb6be8a1d96d05fa56f3522ca9d..0000000000000000000000000000000000000000 --- a/firmware/av7110/Boot.S +++ /dev/null @@ -1,109 +0,0 @@ -/* - Boot.S: boot loader for Siemens DVB-S card - - Copyright (C) 2001 Convergence integrated media GmbH - Written by Ralph Metzler - - Copyright (C) 2006 Matthieu CASTET - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - -*/ - -/* - check AV711x_3_1.pdf for some hardware infos - build it with : - $ cc -mbig-endian -c Boot.S - $ ld -Ttext 0x2c000000 -EB -o Boot Boot.o - $ objcopy -Obinary Boot -*/ - - .text - .align - .globl _start -_start: - b reset // reset vector - movs pc, r14 // undefined - subs pc, r14, #4 // SWI - subs pc, r14, #4 // prefetch abort - subs pc, r14, #8 // data abort - subs pc, r14, #4 // reserved - subs pc, r14, #4 // IRQ - subs pc, r14, #4 // FIQ - - .word tbl // table needed by firmware ROM -tbl: .word (endtbl - tbl) - .word 0 - .word conf -endtbl: .word 0 -conf: .word 0xa5a55a5a - .word 0x001f1555 - .word 0x00000009 - -reset: ldr r13, buffer - ldr r4, flag - mov r0, #0 - str r0, [r4] - str r0, [r4, #4] - - ldr r1, wait_address - ldr r2, flag_address - ldr r3, sram - -copycode: // copy the code HW Sram - ldmia r1!, {r5-r12} - stmia r3!, {r5-r12} - cmp r1, r2 - ble copycode - ldr pc, sram // jump to the copied code - -wait: ldrh r1, [r4] // wait for flag!=0 - cmp r1, #0 - beq wait - - mov r1, r13 // buffer address - ldr r3, [r4,#4] // destaddr - - ldrh r2, [r4,#2] // get segment length - add r2, r2, #63 // round length to next 64 bytes - movs r2, r2, lsr #6 // and divide by 64 - moveq r0, #2 // if 0, set flag to 2, else signal - strh r0, [r4] // that buffer is accepted by setting to 0 - beq wait - -copyloop: - ldmia r1!, {r5-r12} - stmia r3!, {r5-r12} - ldmia r1!, {r5-r12} - stmia r3!, {r5-r12} - subs r2, r2, #1 - bne copyloop - - eor r13, r13, #0x1400 // switch to other buffer - b wait - -// flag is stored at 0x2c0003f8, length at 0x2c0003fa, -// destaddr at 0x2c0003fc - -flag: .word 0x2c0003f8 - - -// buffer 1 is at 0x2c000400, buffer 2 at 0x2c001000 - -buffer: .word 0x2c000400 - -sram: .word 0x9e000800 -wait_address: .word wait -flag_address: .word flag diff --git a/firmware/av7110/bootcode.bin.ihex b/firmware/av7110/bootcode.bin.ihex deleted file mode 100644 index 26a2993e0723e8abff92c71f41c921b420ab383b..0000000000000000000000000000000000000000 --- a/firmware/av7110/bootcode.bin.ihex +++ /dev/null @@ -1,15 +0,0 @@ -:10000000EA00000EE1B0F00EE25EF004E25EF00401 -:10001000E25EF008E25EF004E25EF004E25EF0040C -:100020002C0000240000000C000000002C00003414 -:1000300000000000A5A55A5A001F15550000000930 -:10004000E59FD07CE59F4074E3A00000E5840000BC -:10005000E5840004E59F1070E59F2070E59F306403 -:10006000E8B11FE0E8A31FE0E1510002DAFFFFFB67 -:10007000E59FF050E1D410B0E35100000AFFFFFC0F -:10008000E1A0100DE5943004E1D420B2E282203FDB -:10009000E1B0232203A00002E1C400B00AFFFFF494 -:1000A000E8B11FE0E8A31FE0E8B11FE0E8A31FE00C -:1000B000E25220011AFFFFF9E22DDB05EAFFFFEC17 -:1000C0002C0003F82C0004009E0008002C00007493 -:0400D0002C0000C040 -:00000001FF diff --git a/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex deleted file mode 100644 index 4c43b26af0a66ac0c294917040e34cff3310509b..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-mips-06-6.2.1.fw.ihex +++ /dev/null @@ -1,5818 +0,0 @@ -:10000000080001180800000000004A68000000C84D -:1000100000000000000000000000000008004A6826 -:100020000000001400004B30080000A00800000091 -:100030000000569400004B44080058200000008443 -:100040000000A1D808005694000001580000A25CEE -:100050000800321008000000000072D00000A3B4B5 -:10006000000000000000000000000000080072D046 -:100070000000002400011684080004900800040019 -:10008000000017D4000116A80000000000000000C6 -:100090000000000000000000000000000000000060 -:1000A000080000A80800000000003BFC00012E7CB6 -:1000B0000000000000000000000000000000000040 -:0800C000000000000000000038 -:0800C8000A00004600000000E0 -:1000D000000000000000000D636F6D362E322E31DF -:1000E0000000000006020102000000000000000302 -:1000F000000000C800000032000000030000000003 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E0000000000010000003000000000000000DEF -:1001F0000000000D3C02080024424AA03C03080015 -:1002000024634B9CAC4000000043202B1480FFFD76 -:10021000244200043C1D080037BD7FFC03A0F021F0 -:100220003C100800261001183C1C0800279C4AA01E -:100230000E000168000000000000000D27470100CB -:1002400090E3000B2402001A94E5000814620028D1 -:10025000000020218CE200003C0308008C63004475 -:1002600094E60014000211C20002104030A4000203 -:10027000005A10212463000130A50004A446008028 -:100280003C010800AC23004410A000190004202BFE -:100290008F4202B804410008240400013C02080017 -:1002A0008C420060244200013C010800AC22006046 -:1002B00003E00008008010218CE2002094E3001687 -:1002C00000002021AF4202808CE20004A743028498 -:1002D000AF4202883C021000AF4202B83C02080064 -:1002E0008C42005C244200013C010800AC22005C0E -:1002F00003E00008008010212747010090E3000B75 -:100300002402000394E50008146200280000202164 -:100310008CE200003C0308008C63004494E6001467 -:10032000000211C20002104030A40002005A102145 -:100330002463000130A50004A44600803C010800AD -:10034000AC23004410A000190004202B8F4202B8F7 -:1003500004410008240400013C0208008C420060B3 -:10036000244200013C010800AC22006003E00008C8 -:10037000008010218CE2002094E300160000202170 -:10038000AF4202808CE20004A7430284AF4202889D -:100390003C021000AF4202B83C0208008C42005CF4 -:1003A000244200013C010800AC22005C03E000088C -:1003B000008010218F4301002402010050620003DD -:1003C000000311C20000000D000311C20002104022 -:1003D000005A1021A440008003E000080000102112 -:1003E0009362000003E00008AF80000003E0000813 -:1003F0000000102103E00008000010212402010089 -:1004000014820008000000003C0208008C4200FC3E -:10041000244200013C010800AC2200FC0A0000DD7F -:1004200030A200203C0208008C42008424420001DB -:100430003C010800AC22008430A2002010400008DB -:1004400030A300103C0208008C4201082442000145 -:100450003C010800AC22010803E000080000000095 -:1004600010600008000000003C0208008C420104FB -:10047000244200013C010800AC22010403E0000812 -:10048000000000003C0208008C42010024420001F0 -:100490003C010800AC22010003E00008000000005D -:1004A00027BDFFE8AFBF0010274401009483000878 -:1004B000306200041040001B306600028F4202B818 -:1004C00004410008240500013C0208008C42006041 -:1004D000244200013C010800AC2200600A0001290E -:1004E0008FBF00108C82002094830016000028210A -:1004F000AF4202808C820004A7430284AF4202888C -:100500003C021000AF4202B83C0208008C42005C82 -:10051000244200013C010800AC22005C0A000129D1 -:100520008FBF001010C00006006028218F4401001A -:100530000E0000CD000000000A0001282405000183 -:100540008F8200088F4301045043000700002821D8 -:100550008F4401000E0000CD000000008F42010416 -:10056000AF820008000028218FBF001000A01021DA -:1005700003E0000827BD001827BDFFE8AFBF001447 -:10058000AFB00010974201083043700024022000F1 -:100590001062000B286220011440002F000010217F -:1005A00024024000106200250000000024026000C8 -:1005B00010620026000010210A0001658FBF0014A0 -:1005C00027500100920200091040001A2403000184 -:1005D0003C0208008C420020104000160000182148 -:1005E0000E00049300000000960300083C0608007B -:1005F00094C64B5E8E0400188F8200209605000C76 -:1006000000031C0000661825AC440000AC45000443 -:1006100024040001AC400008AC40000CAC400010C9 -:10062000AC400014AC4000180E0004B8AC43001CF1 -:10063000000018210A000164006010210E0003254B -:10064000000000000A000164000010210E000EE905 -:1006500000000000000010218FBF00148FB00010B8 -:1006600003E0000827BD001827BDFFE0AFB2001867 -:100670003C036010AFBF001CAFB10014AFB000105E -:100680008C6450002402FF7F3C1A800000822024EA -:100690003484380C24020037AC6450003C1208004B -:1006A00026524AD8AF42000824020C80AF420024F0 -:1006B0003C1B80083C06080024C60324024010218D -:1006C0002404001D2484FFFFAC4600000481FFFDCC -:1006D000244200043C020800244204B03C0108000B -:1006E000AC224AE03C020800244202303C010800EF -:1006F000AC224AE43C020800244201743C03080096 -:100700002463032C3C040800248403D83C0508001F -:1007100024A538F03C010800AC224B403C02080004 -:10072000244202EC3C010800AC264B243C010800AA -:10073000AC254B343C010800AC234B3C3C01080089 -:10074000AC244B443C010800AC224B483C0108005F -:10075000AC234ADC3C010800AC204AE83C0108001C -:10076000AC204AEC3C010800AC204AF03C010800F7 -:10077000AC204AF43C010800AC204AF83C010800D7 -:10078000AC204AFC3C010800AC204B003C010800B6 -:10079000AC244B043C010800AC204B083C01080091 -:1007A000AC204B0C3C010800AC204B103C01080075 -:1007B000AC204B143C010800AC204B183C01080055 -:1007C000AC264B1C3C010800AC264B203C01080029 -:1007D000AC254B303C010800AC234B380E000623FF -:1007E000000000003C028000344200708C42000097 -:1007F000AF8200143C0308008C6300208F82000449 -:10080000104300043C0280000E00045BAF83000430 -:100810003C028000344600703C0308008C6300A05A -:100820003C0208008C4200A4104300048F84001492 -:100830003C010800AC2300A4A743009E8CCA000022 -:100840003C0308008C6300BC3C0208008C4200B8EA -:100850000144202300641821000040210064202B63 -:1008600000481021004410213C010800AC2300BCCA -:100870003C010800AC2200B88F5100003222000772 -:100880001040FFDCAF8A00148CC600003C05080055 -:100890008CA500BC3C0408008C8400B800CA30233E -:1008A00000A628210000102100A6302B0082202164 -:1008B00000862021322700013C010800AC2500BC45 -:1008C0003C010800AC2400B810E0001F32220002F6 -:1008D0008F420100AF4200208F420104AF4200A8C6 -:1008E0009342010B0E0000C6305000FF2E02001E86 -:1008F00054400004001010800E0000C90A000213CA -:1009000000000000005210218C4200000040F80955 -:1009100000000000104000053C0240008F4301042D -:100920003C026020AC4300143C024000AF4201385E -:100930003C0208008C420034244200013C010800C3 -:10094000AC220034322200021040000E3222000499 -:100950008F4201400E0000C6AF4200200E000295FB -:10096000000000003C024000AF4201783C02080059 -:100970008C420038244200013C010800AC220038BF -:10098000322200041040FF983C0280008F42018018 -:100990000E0000C6AF4200208F43018024020F00EA -:1009A00014620005000000008F420188A742009CED -:1009B0000A0002483C0240009362000024030050F9 -:1009C000304200FF144300083C0240000E00027B4E -:1009D00000000000544000043C0240000E000D7571 -:1009E000000000003C024000AF4201B83C02080099 -:1009F0008C42003C244200013C010800AC22003C37 -:100A00000A0001C83C0280003C0290003442000110 -:100A100000822025AF4400208F4200200440FFFECA -:100A20000000000003E00008000000003C0280001D -:100A3000344200010082202503E00008AF4400207A -:100A400027BDFFE0AFB10014AFB0001000808821D7 -:100A5000AFBF00180E00025030B000FF9362007D5F -:100A60000220202102028025A370007D8F70007477 -:100A70003C0280000E000259020280241600000988 -:100A80008FBF00188F4201F80440FFFE24020002CD -:100A9000AF5101C0A34201C43C021000AF4201F8B3 -:100AA0008FBF00188FB100148FB0001003E0000852 -:100AB00027BD002027BDFFE8AFBF0010974201848B -:100AC0008F440188304202001040000500002821B8 -:100AD0000E000FAA000000000A00028D240500018C -:100AE0003C02FF0004800005008218243C02040040 -:100AF000506200019362003E240500018FBF001088 -:100B000000A0102103E0000827BD0018A360002208 -:100B10008F4401400A00025E2405000127BDFFE862 -:100B2000AFBF0014AFB0001093620000304400FF6C -:100B300038830020388200300003182B0002102B6D -:100B40000062182410600003240200501482008008 -:100B50008FBF001493620005304200011040007CFA -:100B60008FBF0014934201482443FFFF2C6200050D -:100B7000104000788FB00010000310803C03080084 -:100B800024634A68004310218C42000000400008A2 -:100B9000000000000E0002508F4401408F70000CD6 -:100BA0008F4201441602000224020001AF62000CD1 -:100BB0000E0002598F4401408F420144145000043A -:100BC0008FBF00148FB000100A000F2027BD00183F -:100BD0008F62000C0A0003040000000097620010FE -:100BE0008F4301443042FFFF1462001A00000000EE -:100BF00024020001A76200108F4202380443001053 -:100C00008F4201403C02003F3446F0003C0560004A -:100C10003C04FFC08CA22BBC0044182400461024C6 -:100C20000002130200031D82106200390000000060 -:100C30008F4202380440FFF7000000008F4201405D -:100C4000AF4202003C021000AF4202380A00032209 -:100C50008FBF0014976200100A0003040000000018 -:100C60000E0002508F440140976200128F430144EE -:100C70003050FFFF1603000224020001A762001299 -:100C80000E0002598F4401408F42014416020004B5 -:100C90008FBF00148FB000100A00029127BD00180A -:100CA000976200120A00030400000000976200141B -:100CB0008F4301443042FFFF14620006240200010A -:100CC0008FBF00148FB00010A76200140A00124AF0 -:100CD00027BD0018976200141440001D8FBF001438 -:100CE0000A00031C00000000976200168F430144B5 -:100CF0003042FFFF1462000B240200018FBF00147A -:100D00008FB00010A76200160A000B1227BD001852 -:100D10009742007824420004A76200100A000322D0 -:100D20008FBF001497620016240300013042FFFFBA -:100D3000144300078FBF00143C0208008C4200706F -:100D4000244200013C010800AC2200708FBF001457 -:100D50008FB0001003E0000827BD001827BDFFE892 -:100D6000AFBF0014AFB000108F50010093620000BD -:100D700093430109304400FF2402001F106200A5C4 -:100D80002862002010400018240200382862000A5F -:100D90001040000C2402000B286200081040002CB8 -:100DA00000000000046000E52862000214400028F2 -:100DB00024020006106200268FBF00140A00041FE0 -:100DC0008FB000101062005E2862000B144000DC3F -:100DD0008FBF00142402000E106200738FB0001049 -:100DE0000A00041F00000000106200C028620039E1 -:100DF0001040000A2402008024020036106200CA5B -:100E000028620037104000B424020035106200C18F -:100E10008FBF00140A00041F8FB000101062002B57 -:100E20002862008110400006240200C82402003914 -:100E3000106200B48FBF00140A00041F8FB00010AE -:100E4000106200998FBF00140A00041F8FB00010B9 -:100E50003C0208008C420020104000B98FBF0014F3 -:100E60000E000493000000008F4201008F830020D9 -:100E70009745010C97460108AC6200008F420104BF -:100E80003C04080094844B5E00052C00AC62000416 -:100E90008F4201180006340000C43025AC620008FF -:100EA0008F42011C24040001AC62000C9342010A31 -:100EB00000A22825AC650010AC600014AC600018DE -:100EC000AC66001C0A0003F58FBF00143C0208004A -:100ED0008C4200201040009A8FBF00140E00049333 -:100EE00000000000974401083C03080094634B5E37 -:100EF0009745010C000422029746010E8F820020C4 -:100F0000000426000083202500052C003C030080FF -:100F100000A6282500832025AC400000AC4000043A -:100F2000AC400008AC40000CAC450010AC400014D4 -:100F3000AC400018AC44001C0A0003F42404000177 -:100F40009742010C14400015000000009362000558 -:100F50003042001014400011000000000E0002504A -:100F6000020020219362000502002021344200107B -:100F70000E000259A36200059362000024030020C2 -:100F8000304200FF1043006D020020218FBF00148B -:100F90008FB000100A000FC027BD00180000000D20 -:100FA0000A00041E8FBF00143C0208008C4200207F -:100FB000104000638FBF00140E0004930000000077 -:100FC0008F4201048F8300209744010C3C050800E8 -:100FD00094A54B5EAC6200009762002C00042400D4 -:100FE0003042FFFF008220253C02400E00A228254F -:100FF000AC640004AC600008AC60000CAC60001095 -:10100000AC600014AC600018AC65001C0A0003F46E -:10101000240400010E00025002002021A7600008F5 -:101020000E00025902002021020020210E00025E63 -:10103000240500013C0208008C42002010400040C2 -:101040008FBF00140E000493000000009742010CB3 -:101050008F8300203C05080094A54B5E000214001D -:10106000AC700000AC620004AC6000088F64004CFF -:101070003C02401F00A22825AC64000C8F62005087 -:1010800024040001AC6200108F620054AC620014B2 -:10109000AC600018AC65001C8FBF00148FB000104E -:1010A0000A0004B827BD0018240200205082002541 -:1010B0008FB000100E000F0A020020211040002007 -:1010C0008FBF0014020020218FB0001000002821E3 -:1010D0000A00025E27BD0018020020218FBF001405 -:1010E0008FB000100A00058027BD00189745010C3D -:1010F000020020218FBF00148FB000100A0005A04D -:1011000027BD0018020020218FB000100A0005C57D -:1011100027BD00189345010D020020218FB000105B -:101120000A00060F27BD0018020020218FBF0014FF -:101130008FB000100A0005EB27BD00188FBF001408 -:101140008FB0001003E0000827BD00188F4202781E -:101150000440FFFE2402000234840080AF440240B9 -:10116000A34202443C02100003E00008AF420278B0 -:101170003C04080094844B6A3C0208008C424B7487 -:101180003083FFFF000318C000431021AF42003C32 -:101190003C0208008C424B70AF4200383C020050C9 -:1011A00034420008AF4200300000000000000000A0 -:1011B000000000008F420000304200201040FFFD80 -:1011C000000000008F4204003C010800AC224B608C -:1011D0008F4204043C010800AC224B643C02002016 -:1011E000AF420030000000003C02080094424B680F -:1011F0003C03080094634B6C3C05080094A54B6EBF -:1012000024840001004310213083FFFF3C010800CB -:10121000A4224B683C010800A4244B6A1465000317 -:10122000000000003C010800A4204B6A03E0000815 -:10123000000000003C05000A27BDFFE80345282107 -:101240003C04080024844B50AFBF00100E00051D65 -:101250002406000A3C02080094424B523C0308005A -:1012600094634B6E3042000F244200030043180485 -:1012700024027FFF0043102B10400002AF83001CAC -:101280000000000D0E00042A000000003C020800CF -:1012900094424B5A8FBF001027BD001803E000088E -:1012A000A74200A23C02000A034210219443000618 -:1012B0003C02080094424B5A3C010800A4234B56C0 -:1012C000004310238F83001C00021400000214034B -:1012D0000043102B03E000083842000127BDFFE85F -:1012E000AFBF00103C02000A0342102194420006E6 -:1012F0003C010800A4224B560E00047700000000B9 -:101300005440FFF93C02000A8FBF001003E00008C0 -:1013100027BD001827BDFFE8AFBF00100E000477FF -:101320000000000010400003000000000E000485D3 -:10133000000000003C0208008C424B608FBF001090 -:1013400027430400AF4200383C0208008C424B6443 -:1013500027BD0018AF830020AF42003C3C020005CF -:10136000AF42003003E00008AF8000188F82001801 -:101370003C0300060002114000431025AF4200303C -:101380000000000000000000000000008F4200008C -:10139000304200101040FFFD27420400AF820020C1 -:1013A00003E00008AF8000183C0608008CC64B64C0 -:1013B0008F8500188F8300203C02080094424B5A0E -:1013C00027BDFFE024A50001246300202442000182 -:1013D00024C70020AFB10014AFB00010AFBF001899 -:1013E000AF850018AF8300203C010800A4224B5AAF -:1013F000309000FF3C010800AC274B6404C100089A -:101400000000882104E00006000000003C02080003 -:101410008C424B60244200013C010800AC224B602E -:101420003C02080094424B5A3C03080094634B680A -:101430000010202B004310262C42000100441025F0 -:10144000144000048F830018240200101462000F5F -:10145000000000000E0004A9241100013C03080054 -:1014600094634B5A3C02080094424B681462000398 -:10147000000000000E00042A000000001600000317 -:10148000000000000E000493000000003C03080070 -:1014900094634B5E3C02080094424B5C2463000161 -:1014A0003064FFFF3C010800A4234B5E148200035C -:1014B000000000003C010800A4204B5E1200000662 -:1014C000000000003C02080094424B5AA74200A2D0 -:1014D0000A00050B022010210E0004770000000016 -:1014E00010400004022010210E00048500000000BE -:1014F000022010218FBF00188FB100148FB0001090 -:1015000003E0000827BD00203084FFFF30A5FFFF67 -:101510000000182110800007000000003082000148 -:101520001040000200042042006518210A00051343 -:101530000005284003E000080060102110C00006EC -:1015400024C6FFFF8CA2000024A50004AC8200008A -:101550000A00051D2484000403E0000800000000C8 -:1015600010A0000824A3FFFFAC86000000000000CC -:10157000000000002402FFFF2463FFFF1462FFFA53 -:101580002484000403E0000800000000240200019D -:10159000AF62000CA7620010A7620012A7620014DD -:1015A00003E00008A76200163082007F034210218A -:1015B0003C08000E004818213C0208008C42002024 -:1015C00027BDFFD82407FF80AFB3001CAFB20018BF -:1015D000AFB10014AFB00010AFBF00200080802179 -:1015E00030B100FF0087202430D200FF1040002FD0 -:1015F00000009821AF44002C9062000024030050AA -:10160000304200FF1443000E000000003C020800BE -:101610008C4200E00202102100471024AF42002C4F -:101620003C0208008C4200E0020210213042007FA0 -:101630000342102100481021944200D43053FFFF90 -:101640000E000493000000003C02080094424B5E30 -:101650008F8300200011340000C2302500122C00BE -:101660003C02400000C2302534A50001AC700000EF -:101670008FBF0020AC6000048FB20018AC7300086C -:101680008FB10014AC60000C8FB3001CAC6500106F -:101690008FB00010AC60001424040001AC6000188E -:1016A00027BD00280A0004B8AC66001C8FBF0020CC -:1016B0008FB3001C8FB200188FB100148FB00010D0 -:1016C00003E0000827BD00289343010F2402001007 -:1016D0001062000E2865001110A0000724020012FD -:1016E000240200082405003A1062000600003021A0 -:1016F00003E0000800000000240500351462FFFC30 -:10170000000030210A000538000000008F420074FC -:1017100024420FA003E00008AF62000C27BDFFE8E1 -:10172000AFBF00100E00025E240500018FBF001045 -:1017300024020001A762001227BD00182402000144 -:1017400003E00008A360002227BDFFE0AFB1001452 -:10175000AFB00010AFBF001830B1FFFF0E00025055 -:10176000008080219362003F24030004304200FF88 -:101770001443000C02002021122000082402000A59 -:101780000E00053100000000936200052403FFFEF7 -:1017900000431024A362000524020012A362003F4C -:1017A000020020210E000259A360008116200003D0 -:1017B000020020210E0005950000000002002021FB -:1017C000322600FF8FBF00188FB100148FB00010B9 -:1017D000240500380A00053827BD002027BDFFE09A -:1017E000AFBF001CAFB20018AFB10014AFB0001013 -:1017F0000E000250008080210E0005310000000024 -:101800009362003F24120018305100FF123200038F -:101810000200202124020012A362003F936200050F -:101820002403FFFE004310240E000259A3620005AA -:10183000020020212405002016320007000030217C -:101840008FBF001C8FB200188FB100148FB0001032 -:101850000A00025E27BD00208FBF001C8FB2001857 -:101860008FB100148FB00010240500390A0005382C -:1018700027BD002027BDFFE8AFB00010AFBF0014A8 -:101880009742010C2405003600808021144000108E -:10189000304600FF0E00025000000000240200123B -:1018A000A362003F93620005344200100E00053130 -:1018B000A36200050E00025902002021020020212F -:1018C0000E00025E240500200A000604000000004D -:1018D0000E000538000000000E000250020020211A -:1018E000936200232403FF9F020020210043102461 -:1018F0008FBF00148FB00010A36200230A000259AA -:1019000027BD001827BDFFE0AFBF0018AFB100141E -:10191000AFB0001030B100FF0E00025000808021F7 -:10192000240200120E000531A362003F0E0002598E -:101930000200202102002021022030218FBF001848 -:101940008FB100148FB00010240500350A0005384F -:1019500027BD0020A380002C03E00008A380002DF9 -:101960008F4202780440FFFE8F820034AF42024073 -:1019700024020002A34202443C02100003E00008DB -:10198000AF4202783C0360008C6254003042000891 -:101990001440FFFD000000008C625408AF82000C70 -:1019A00024020052AC605408AC645430AC6254342D -:1019B0002402000803E00008AC6254003C0260000E -:1019C0008C42540030420008104000053C03600087 -:1019D0008C625400304200081440FFFD00000000FB -:1019E0008F83000C3C02600003E00008AC43540805 -:1019F00090A3000024020005008040213063003FD6 -:101A000000004821146200050000502190A2001C33 -:101A100094A3001E304900FF306AFFFFAD00000CA8 -:101A2000AD000010AD000024950200148D05001CCF -:101A30008D0400183042FFFF0049102300021100FE -:101A4000000237C3004038210086202300A2102B5B -:101A50000082202300A72823AD05001CAD04001838 -:101A6000A5090014A5090020A50A001603E0000836 -:101A7000A50A00228F4201F80440FFFE2402000262 -:101A8000AF4401C0A34201C43C02100003E00008BF -:101A9000AF4201F83C0208008C4200B427BDFFE8C9 -:101AA000AFBF001424420001AFB000103C01080099 -:101AB000AC2200B48F4300243C02001F30AA00FF78 -:101AC0003442FF8030D800FF006280240080F8217B -:101AD00030EF00FF1158003B01405821240CFF80DB -:101AE0003C19000A3163007F000310C00003194055 -:101AF000006218213C0208008C4200DC25680001CD -:101B0000310D007F03E21021004310213043007F9C -:101B100003431821004C102400794821AF420024CF -:101B20008D220024016C1824006C7026AD22000C5C -:101B30008D220024310800FFAD22001095220014F0 -:101B4000952300208D27001C3042FFFF3063FFFFEC -:101B50008D2600180043102300021100000227C345 -:101B60000040282100C4302300E2102B00C23023A3 -:101B700000E53823AD27001CAD2600189522002073 -:101B8000A522001495220022154B000AA52200165A -:101B90008D2300248D220008254600013145008058 -:101BA0001462000430C4007F108F000238AA008045 -:101BB00000C0502151AF000131C800FF1518FFC906 -:101BC000010058218F8400343082007F03421821A5 -:101BD0003C02000A006218212402FF8000822024B7 -:101BE000AF440024A06A0079A06A00838C62005090 -:101BF0008F840034AC6200708C6500743C027FFFFF -:101C00003442FFFF00A228240E00066BAC6500746E -:101C1000AF5000248FBF00148FB0001003E0000805 -:101C200027BD001827BDFFC0AFBE0038AFB70034D6 -:101C3000AFB5002CAFB20020AFB1001CAFB00018A0 -:101C4000AFBF003CAFB60030AFB40028AFB3002444 -:101C50008F4500248F4600288F43002C3C02001F34 -:101C60003442FF800062182400C230240080A82182 -:101C7000AFA3001400A2F0240E00062FAFA60010A0 -:101C80003C0208008C4200E02410FF8003608821A1 -:101C900002A2102100501024AF4200243C02080090 -:101CA0008C4200E002A210213042007F0342182142 -:101CB0003C02000A00629021924200D293630084A9 -:101CC000305700FF306300FF24020001106200342F -:101CD000036020212402000214620036000000008C -:101CE0000E001216024028219223008392220083C4 -:101CF0003063007F3042007F000210C000031940B3 -:101D0000006218213C0208008C4200DC02A2102173 -:101D10000043382100F01024AF42002892250078BB -:101D20009224008330E2007F034218213C02000C21 -:101D300014850007006280212402FFFFA24200F107 -:101D40002402FFFFA64200F20A0007272402FFFF39 -:101D500096020020A24200F196020022A64200F262 -:101D60008E020024AE4200F492220083A24200F0D0 -:101D70008E4200C8AE4200FC8E4200C4AE4200F863 -:101D80008E220050AE4201008E4200CCAE420104D1 -:101D9000922200853042003F0A0007823442004010 -:101DA0000E00123902402821922200850A00078283 -:101DB0003042003F936200852403FFDF3042003F42 -:101DC000A36200859362008500431024A36200850E -:101DD0009363008393620078307400FF304200FF09 -:101DE00010540036240AFF803C0C000C3283007F24 -:101DF000000310C000031940006218213C020800D3 -:101E00008C4200DC268800013109007F02A21021EB -:101E10000043382130E2007F0342182100EA1024F9 -:101E2000AF420028006C80218E020024028A182410 -:101E3000006A5826AE02000C8E020024310800FF12 -:101E4000AE02001096020014960300208E07001CBC -:101E50003042FFFF3063FFFF8E060018004310235F -:101E600000021100000227C30040282100C43023D3 -:101E700000E2102B00C2302300E53823AE07001C1F -:101E8000AE06001896020020A60200149602002258 -:101E9000A602001692220079304200FF105400077B -:101EA0000000000051370001316800FF92220078E5 -:101EB000304200FF1448FFCD0100A0219222008390 -:101EC000A22200798E2200500A0007E2AE220070A2 -:101ED000A22200858E22004C2405FF80AE42010C18 -:101EE0009222008534420020A2220085924200D135 -:101EF0003C0308008C6300DC305400FF3C02080007 -:101F00008C4200E400143140001420C002A31821C8 -:101F100000C4202102A210210064382100461021B3 -:101F20000045182400E52824AF450028AF43002CC5 -:101F30003042007F924400D030E3007F03422821EA -:101F4000034318213C02000C006280213C02000E79 -:101F5000309600FF00A298211296002A000000008F -:101F60008E02000C02002021026028211040002572 -:101F7000261000280E00064A000000009262000DA4 -:101F800026830001307400FF3042007FA262000D02 -:101F90002404FF801697FFF0267300203C020800FF -:101FA0008C4200DC0000A02102A210210044102479 -:101FB000AF4200283C0208008C4200E43C030800C9 -:101FC0008C6300DC02A2102100441024AF42002CDC -:101FD0003C0208008C4200E402A318213063007F19 -:101FE00002A210213042007F034220210343182126 -:101FF0003C02000C006280213C02000E0A0007A493 -:10200000008298218E4200D8AE2200508E4200D825 -:10201000AE22007092250083924600D19223008365 -:10202000924400D12402FF8000A228243063007F64 -:10203000308400FF00A628250064182A10600002E2 -:1020400030A500FF38A50080A2250083A2250079D5 -:102050000E00063D000000009222007E02A020211A -:10206000A222007A8E2300743C027FFF3442FFFFDD -:10207000006218240E00066BAE2300748FA20010BD -:10208000AF5E00248FBF003CAF4200288FBE0038F7 -:102090008FA200148FB700348FB600308FB5002C9C -:1020A0008FB400288FB300248FB200208FB1001CA2 -:1020B0008FB0001827BD004003E00008AF42002C9D -:1020C00090A2000024420001A0A200003C030800EE -:1020D0008C6300F4304200FF1443000F0080302175 -:1020E000A0A000003C0208008C4200E48F84003471 -:1020F000008220213082007F034218213C02000C24 -:10210000006218212402FF8000822024ACC300005A -:1021100003E00008AF4400288C8200002442002025 -:1021200003E00008AC82000094C200003C080800F4 -:10213000950800CA30E7FFFF008048210102102106 -:10214000A4C2000094C200003042FFFF00E2102B46 -:1021500054400001A4C7000094A200003C03080002 -:102160008C6300CC24420001A4A2000094A20000D1 -:102170003042FFFF544300078F8600280107102BD1 -:10218000A4A000005440000101003821A4C70000B1 -:102190008F8600288CC4001CAF44003C94A2000031 -:1021A0008F43003C3042FFFF000210C00062182144 -:1021B000AF43003C8F42003C008220231880000483 -:1021C000000000008CC200180A00084324420001ED -:1021D0008CC20018AF4200383C020050344200105C -:1021E000AF420030000000000000000000000000CE -:1021F0008F420000304200201040FFFD0000000030 -:102200008F420404AD2200048F420400AD2200007E -:102210003C020020AF42003003E000080000000054 -:1022200027BDFFE0AFB20018AFB10014AFB000108F -:10223000AFBF001C94C2000000C080213C12080007 -:10224000965200C624420001A60200009603000038 -:1022500094E2000000E03021144300058FB100300B -:102260000E000818024038210A000875000000001E -:102270008C8300048C820004244200400461000727 -:10228000AC8200048C8200040440000400000000C2 -:102290008C82000024420001AC8200009602000003 -:1022A0003042FFFF50520001A600000096220000BD -:1022B00024420001A62200008F82002896230000FD -:1022C00094420016144300048FBF001C2402000136 -:1022D000A62200008FBF001C8FB200188FB100141F -:1022E0008FB0001003E0000827BD00208F89002870 -:1022F00027BDFFE0AFBF00188D220028274804004B -:1023000030E700FFAF4200388D22002CAF8800304C -:10231000AF42003C3C020005AF420030000000002C -:1023200000000000000000000000000000000000AD -:10233000000000008C82000C8C82000CAD020000BA -:102340008C820010AD0200048C820018AD020008DF -:102350008C82001CAD02000C8CA20014AD02001097 -:102360008C820020AD02001490820005304200FFF4 -:1023700000021200AD0200188CA20018AD02001C71 -:102380008CA2000CAD0200208CA20010AD02002433 -:102390008CA2001CAD0200288CA20020AD02002CF3 -:1023A000AD060030AD000034978300263402FFFFF5 -:1023B00014620002006020213404FFFF10E00011CD -:1023C000AD04003895230036952400362402000120 -:1023D0003063FFFF000318C20069182190650040B8 -:1023E000308400070082100400451025A0620040E0 -:1023F0008F820028944200563042FFFF0A0008DC1A -:10240000AD02003C952300369524003624020001DD -:102410003063FFFF000318C2006918219065004077 -:1024200030840007008210040002102700451024A9 -:10243000A0620040AD00003C000000000000000071 -:10244000000000003C02000634420040AF42003071 -:102450000000000000000000000000008F420000AB -:10246000304200101040FFFD8F860028AF880030FA -:1024700024C2005624C7003C24C4002824C50032CE -:1024800024C600360E000856AFA200108FBF0018F9 -:1024900003E0000827BD00208F8300243C060800CD -:1024A0008CC600E88F82003430633FFF0003198040 -:1024B00000461021004310212403FF803046007F96 -:1024C00000431024AF420028034618213C02000CB0 -:1024D0000062302190C2000D30A500FF00003821BD -:1024E00034420010A0C2000D8F8900288F8A00247A -:1024F00095230036000A13823048000324020001AD -:10250000A4C3000E1102000B2902000210400005B6 -:10251000240200021100000C240300010A0009201B -:102520000000182111020006000000000A00092026 -:10253000000018218CC2002C0A000920244300014D -:102540008CC20014244300018CC200180043102BDD -:1025500050400009240700012402002714A20003B0 -:10256000000000000A00092C240700019522003E0B -:1025700024420001A522003E000A138230430003DA -:102580002C62000210400009008028211460000421 -:102590000000000094C200360A00093C3046FFFFEC -:1025A0008CC600380A00093C008028210000302138 -:1025B0003C04080024844B780A00088900000000CD -:1025C000274901008D22000C9523000601202021BF -:1025D000000216023046003F3063FFFF240200274E -:1025E00000C0282128C7002810C2000EAF83002495 -:1025F00010E00008240200312402002110C200096A -:102600002402002510C200079382002D0A00095BF6 -:102610000000000010C200059382002D0A00095B33 -:10262000000000000A0008F4000000000A0006266E -:102630000000000095230006912400058D25000C64 -:102640008D2600108D2700188D28001C8D29002054 -:10265000244200013C010800A4234B7E3C010800F9 -:10266000A0244B7D3C010800AC254B843C010800B4 -:10267000AC264B883C010800AC274B903C0108007D -:10268000AC284B943C010800AC294B9803E00008AF -:10269000A382002D8F87002827BDFFC0AFB3003471 -:1026A000AFB20030AFB1002CAFB00028AFBF0038E0 -:1026B0003C0208008C4200D094E3003030B0FFFFB1 -:1026C000005010073045FFFF3063FFFF00C0982126 -:1026D000A7A200103C110800963100C614A3000602 -:1026E0003092FFFF8CE2002424420030AF42003CD5 -:1026F0000A0009948CE2002094E200323042FFFF8D -:1027000054A2000827A400188CE2002C24420030B8 -:10271000AF42003C8CE20028AF4200380A0009A218 -:102720008F84002827A5001027A60020022038212A -:102730000E000818A7A000208FA200182442003025 -:10274000AF4200388FA2001CAF42003C8F840028AB -:102750003C020005AF42003094820034274304005D -:102760003042FFFF0202102B14400007AF830030FD -:1027700094820054948300340202102100431023F9 -:102780000A0009B63043FFFF94830054948200345A -:102790000223182100501023006218233063FFFF2A -:1027A000948200163042FFFF144300030000000033 -:1027B0000A0009C424030001948200163042FFFF7E -:1027C0000043102B104000058F82003094820016C9 -:1027D000006210233043FFFF8F820030AC530000B3 -:1027E000AC400004AC520008AC43000C3C020006B4 -:1027F00034420010AF420030000000000000000032 -:10280000000000008F420000304200101040FFFD29 -:10281000001018C2006418219065004032040007BF -:10282000240200018FBF00388FB300348FB2003014 -:102830008FB1002C8FB000280082100400451025B5 -:1028400027BD004003E00008A062004027BDFFA8AC -:10285000AFB60050AFB5004CAFB40048AFB30044C2 -:10286000AFB1003CAFBF0054AFB20040AFB00038D2 -:102870008C9000003C0208008C4200E88F860034F7 -:10288000960300022413FF8000C2302130633FFF13 -:102890000003198000C3382100F3102490B2000017 -:1028A000AF42002C9203000230E2007F034230214D -:1028B0003C02000E00C28821306300C024020040A8 -:1028C0000080A82100A0B021146200260000A021F1 -:1028D0008E3400388E2200181440000224020001B9 -:1028E000AE2200189202000D304200201440001564 -:1028F0008F8200343C0308008C6300DC001238C077 -:10290000001231400043102100C730210046382119 -:1029100030E300073C02008030E6007800C230253A -:102920000343182100F31024AF4208002463090078 -:10293000AF4608108E2200188C6300080043102157 -:10294000AE2200188E22002C8E2300182442000193 -:102950000062182B1060003D000000000A000A7899 -:1029600000000000920300022402FFC00043102474 -:10297000304200FF1440000524020001AE2200187E -:10298000962200360A000A613054FFFF8E2200149E -:1029900024420001AE22001892020000000216003C -:1029A0000002160304410029000000009602000204 -:1029B00027A4001000802821A7A20016960200027A -:1029C00024070001000030213042FFFFAF820024C5 -:1029D0000E000889AFA0001C960300023C0408000A -:1029E0008C8400E88F82003430633FFF000319803D -:1029F00000441021004310213043007F3C05000CAF -:102A00000053102403431821AF4200280065182109 -:102A10009062000D001221403042007FA062000D44 -:102A20003C0308008C6300E48F82003400431021D3 -:102A30000044382130E2007F03421021004510217C -:102A400000F31824AF430028AEA200009222000D2C -:102A5000304200101040001302A020218F83002874 -:102A60008EA40000028030219462003E2442FFFFC9 -:102A7000A462003E948400029625000E3084FFFF7D -:102A80000E00097330A5FFFF8F82002894430034A5 -:102A90009622000E1443000302A02021240200010C -:102AA000A382002C02C028210E0007FE00000000B7 -:102AB0008FBF00548FB600508FB5004C8FB40048C4 -:102AC0008FB300448FB200408FB1003C8FB000380C -:102AD00003E0000827BD00588F82002827BDFFD0E3 -:102AE000AFB40028AFB20020AFBF002CAFB30024BA -:102AF000AFB1001CAFB00018904400D0904300D19B -:102B00000000A021309200FFA3A30010306300FF5B -:102B10008C5100D88C5300DC1072002B2402000171 -:102B20003C0308008C6300E493A400108F820034FF -:102B30002406FF800004214000431021004410219E -:102B40003043007F00461024AF4200280343182181 -:102B50003C02000C006218218C62000427A40014BF -:102B600027A50010022280210270102304400015C6 -:102B7000AFA300149062000D00C21024304200FF89 -:102B800014400007020088219062000D344200408A -:102B90000E0007FEA062000D0A000ABD93A20010FD -:102BA0000E0009E1241400018F830028AC7000D8C6 -:102BB00093A20010A06200D193A200101452FFD87B -:102BC0000000000024020001168200048FBF002CC8 -:102BD0000E000626000000008FBF002C8FB40028D6 -:102BE0008FB300248FB200208FB1001C8FB000186B -:102BF00003E0000827BD003027BDFFD8AFB3001C9D -:102C0000AFB20018AFB10014AFB00010AFBF0020DA -:102C10000080982100E0802130B1FFFF0E00049376 -:102C200030D200FF000000000000000000000000A3 -:102C30008F820020AC510000AC520004AC5300085D -:102C4000AC40000CAC400010AC400014AC4000188C -:102C50003C03080094634B5E02038025AC50001CCB -:102C6000000000000000000000000000240400013B -:102C70008FBF00208FB3001C8FB200188FB10014DB -:102C80008FB000100A0004B827BD002827BDFFE858 -:102C9000AFB00010AFBF001430A5FFFF30C600FF7B -:102CA0000080802124020C80AF420024000000003C -:102CB0000000000000000000000000000000000014 -:102CC0000E000ACC000000003C040800248400E050 -:102CD0008C8200002403FF808FBF001402021021A9 -:102CE00000431024AF4200248C8200003C03000A01 -:102CF000020280213210007F035010218FB000109B -:102D00000043102127BD001803E00008AF8200280F -:102D100027BDFFE8AFBF00108F4401403C0308000F -:102D20008C6300E02402FF80AF840034008318210C -:102D300000621024AF4200243C02000803424021FC -:102D4000950500023063007F3C02000A034318210E -:102D50000062182130A5FFFF3402FFFF0000302180 -:102D60003C07602010A20006AF8300282402FFFF6A -:102D7000A5020002946500D40E000AF130A5FFFF01 -:102D80008FBF001024020C8027BD001803E000084C -:102D9000AF4200243C020008034240219502000299 -:102DA0003C0A0800954A00C63046FFFF14C00007E1 -:102DB0003402FFFF8F8200288F8400343C0760209C -:102DC000944500D40A000B5A30A5FFFF10C200241E -:102DD0008F87002894E2005494E400163045FFFFEA -:102DE00000A6102300A6182B3089FFFF10600004F6 -:102DF0003044FFFF00C51023012210233044FFFFA1 -:102E0000008A102B1040000C012A1023240200011C -:102E1000A50200162402FFFFA502000294E500D4DB -:102E20008F8400340000302130A5FFFF3C07602074 -:102E30000A000AF1000000000044102A10400008B7 -:102E4000000000009502001630420001104000040E -:102E5000000000009742007E24420014A5020016E4 -:102E600003E00008000000008F84002827BDFFE079 -:102E7000AFBF0018948200349483003E1060001AA3 -:102E80003048FFFF9383002C2402000114620027C6 -:102E90008FBF00188F820028000818C23108000771 -:102EA000006218212447003A244900542444002099 -:102EB000244500302446003490620040304200FF38 -:102EC0000102100730420001104000168FBF0018A9 -:102ED0000E000856AFA900108F82002894420034DB -:102EE0000A000B733048FFFF94830036948200344D -:102EF0001043000E8FBF001894820036A482003465 -:102F000094820056A48200548C82002CAC8200244F -:102F100094820032A48200309482003CA482003A61 -:102F20008FBF00180A000B3327BD002003E0000804 -:102F300027BD002027BDFFE8AFBF00108F4A01006A -:102F40003C0508008CA500E03C02080090424B8440 -:102F50003C0C0800958C4B7E01452821304B003FEE -:102F600030A2007F03424021396900323C02000A4E -:102F70003963003F2C630001010240212D2900012B -:102F80002402FF8000A2282401234825AF8A0034B0 -:102F900000801821AF450024000030210080282146 -:102FA00024070001AF8800283C04080024844B78E3 -:102FB000AF8C002415200007A380002D24020020E0 -:102FC0005562000F006020213402FFFF5582000C83 -:102FD000006020212402002015620005000000008E -:102FE0008C6300142402FFFF106200070000000041 -:102FF0000E000889000000000A000BD0000000004D -:103000000E0008F4016028210E000B68000000008B -:103010008FBF001024020C8027BD001803E00008B9 -:10302000AF4200243C0208008C4200E027BDFFA014 -:10303000AFB1003C008210212411FF80AFBE0058C8 -:10304000AFB70054AFB20040AFB00038AFBF005CC4 -:10305000AFB60050AFB5004CAFB40048AFB30044BA -:10306000005110248F4800248F4900288F470028E2 -:10307000AF4200243C0208008C4200E00080902116 -:1030800024060006008210213042007F03421821EE -:103090003C02000A006280213C02001F3442FF8093 -:1030A00000E2382427A40010260500F00122F024B5 -:1030B0000102B8240E00051DAFA700308FA2001832 -:1030C000AE0200C48FA2001CAE0200C88FA2002472 -:1030D000AE0200CC93A40010920300D12402FF8022 -:1030E0000082102400431025304900FF3083007F08 -:1030F0003122007F0062102A10400004000310C03B -:1031000001311026304900FF000310C000031940B0 -:10311000006218213C0208008C4200DC920400D2BC -:10312000024210210043102100511024AF42002818 -:1031300093A300103063007F000310C00003194008 -:10314000006218213C0208008C4200DC024210217F -:10315000004310213042007F034218213C02000C42 -:10316000006240218FA300142402FFFF1062003090 -:10317000309500FF93A2001195030014304400FF26 -:103180003063FFFF0064182B1060000D000000008A -:10319000950400148D07001C8D0600183084FFFF75 -:1031A00000442023000421000000102100E4382105 -:1031B00000E4202B00C230210A000C4A00C4302158 -:1031C000950400148D07001C8D0600183084FFFF45 -:1031D000008220230004210000001021008018211B -:1031E00000C2302300E4202B00C4302300E3382346 -:1031F000AD07001CAD06001893A20011A502001433 -:1032000097A20012A50200168FA20014AD020010B2 -:103210008FA20014AD02000C93A20011A5020020A1 -:1032200097A20012A50200228FA20014AD02002472 -:103230002406FF80024610243256007FAF4200244D -:10324000035618213C02000A006280218E02004CC5 -:103250008FA200203124007F000428C0AE0200505D -:103260008FA200200004214000852821AE020070BA -:1032700093A2001001208821A202008393A20010D3 -:10328000A2020079920200853042003FA20200852E -:103290003C0208008C4200DC024210210045102153 -:1032A00000461024AF42002C3C0208008C4200E48F -:1032B0003C0308008C6300DC024210210044102112 -:1032C00000461024AF4200283C0208008C4200E473 -:1032D00002431821006518210242102100441021E8 -:1032E0003042007F3063007F93A50010034220210D -:1032F000034318213C02000E006240213C02000CF6 -:1033000010B1008C008248213233007F1660001912 -:103310002404FF803C0208008C4200DC02421021A1 -:1033200000441024AF42002C3C0208008C4200E410 -:103330003C0308008C6300DC02421021004410248E -:10334000AF4200283C0208008C4200E402431821EE -:103350003063007F024210213042007F034220216F -:10336000034318213C02000E006240213C02000C85 -:10337000008248219124000D2414FF8000001021B8 -:1033800000942025A124000D950400029505001449 -:103390008D07001C3084FFFF30A5FFFF8D0600184D -:1033A000008520230004210000E4382100C23021E0 -:1033B00000E4202B00C43021AD07001CAD0600182E -:1033C00095020002A5020014A50000168D02000857 -:1033D000AD0200108D020008AD02000C9502000243 -:1033E000A5020020A50000228D020008AD020024E5 -:1033F0009122000D30420040104000422622000180 -:103400003C0208008C4200E0A3B300283C10000AF4 -:103410000242102100541024AF4200243C02080054 -:103420008C4200E0A380002C27A4002C0242102133 -:103430003042007F03421821007018218C6200D8AE -:103440008D26000427A50028AFA9002C00461021D6 -:10345000AC6200D80E0009E1AF83002893A30028D6 -:103460008F8200280E000626A04300D10E000B68B4 -:103470000000000002541024AF4200243C02080067 -:103480008C4200DC00132940001320C000A420213E -:10349000024210210044102100541024AF42002C9D -:1034A0003C0208008C4200E43C0308008C6300DC12 -:1034B00003563021024210210045102100541024EF -:1034C000AF4200283C0208008C4200E4024318216D -:1034D0000064182102421021004510213042007F73 -:1034E0003063007F03422021034318213C02000E79 -:1034F000006240213C02000C00D080210082482163 -:10350000262200013043007F14750005304400FF7F -:103510002403FF800223102400431026304400FFC0 -:1035200093A2001000808821250800281444FF760B -:103530002529002093A400108FA300142402FFFF6C -:103540001062000A308900FF2482000124830001F8 -:103550003042007F14550005306900FF2403FF80CE -:103560000083102400431026304900FF92020078A7 -:10357000305300FF11330032012088213C02080043 -:103580008C4200DC3225007F000520C00005294068 -:1035900000A42021024210212406FF8000441021B3 -:1035A00000461024AF42002C3C0308008C6300DC72 -:1035B0003C0208008C4200E4024318210242102120 -:1035C0000045102100641821004610243063007F5C -:1035D000AF420028034318213C02000E0062402144 -:1035E0003C0208008C4200E48D06000C0100202102 -:1035F00002421021004510213042007F0342182171 -:103600003C02000C0062482110C0000D012028215E -:103610000E00064A000000002402FF800222182447 -:1036200026240001006228263082007F1455000203 -:10363000308300FF30A300FF1473FFD000608821A7 -:103640008E0300743C027FFF3442FFFF00621824A7 -:10365000AE0300740E00066B02402021AF57002419 -:103660008FA20030AF5E00288FBF005C8FBE005875 -:103670008FB700548FB600508FB5004C8FB4004800 -:103680008FB300448FB200408FB1003C8FB0003840 -:1036900027BD006003E00008AF42002C27BDFFD823 -:1036A000AFB1001CAFBF0020AFB000182751018898 -:1036B000922200032408FF803C03000A3047007F69 -:1036C000A3A700108F4601803C0208008C4200E056 -:1036D000AF86003400C2282100A81024AF42002485 -:1036E0009224000030A2007F0342102100431021E9 -:1036F000AF8200283084007F24020002148200255B -:10370000000719403C0208008C4200E400C210216E -:103710000043282130A2007F0342182100A8102472 -:10372000AF4200283C02000C006218219062000D9C -:10373000AFA3001400481025A062000D8FA3001451 -:103740009062000D304200405040006A8FBF002060 -:103750008F860028A380002C27A400148CC200D8D8 -:103760008C63000427A50010004310210E0009E11E -:10377000ACC200D893A300108F8200280E0006264A -:10378000A04300D10E000B68000000000A000E0BE1 -:103790008FBF00200E00062F00C020210E00063D26 -:1037A000000000003C020008034280219223000137 -:1037B0009202007B1443004F8FBF00209222000032 -:1037C0003044007F24020004108200172882000584 -:1037D00010400006240200052402000310820007A6 -:1037E0008FB1001C0A000E0C0000000010820012B5 -:1037F0008FBF00200A000E0C8FB1001C92050083C1 -:10380000920600788E0700748F84003430A500FF84 -:1038100000073E0230C600FF0E00067330E7007F4F -:103820000A000E0B8FBF00200E000BD78F840034D0 -:103830000A000E0B8FBF002024020C80AF42002430 -:103840009202003E30420040104000200000000084 -:103850009202003E00021600000216030441000618 -:10386000000000008F8400340E0005A024050093A2 -:103870000A000E0B8FBF00209202003F24030018A5 -:10388000304200FF1443000C8F84003424050039BB -:103890000E000538000030210E0002508F840034E5 -:1038A00024020012A202003F0E0002598F8400344D -:1038B0000A000E0B8FBF0020240500360E000538CD -:1038C000000030210A000E0B8FBF00200E000250B6 -:1038D0008F8400349202000534420020A2020005C9 -:1038E0000E0002598F8400340E000FC08F84003404 -:1038F0008FBF00208FB1001C8FB0001824020C80F5 -:1039000027BD002803E00008AF42002427BDFFE8E0 -:10391000AFB00010AFBF001427430100946200084D -:103920000002140000021403044100020000802180 -:103930002410000194620008304200801040001AF8 -:10394000020010219462000830422000104000164E -:10395000020010218C6300183C021C2D344219ED2A -:10396000240600061062000F3C0760213C0208009C -:103970008C4200D4104000078F8200288F830028DB -:10398000906200623042000F34420040A062006248 -:103990008F8200288F840034944500D40E000AF1F1 -:1039A00030A5FFFF020010218FBF00148FB0001060 -:1039B00003E0000827BD001827BDFFE0AFB10014E9 -:1039C000AFB00010A380002CAFBF00188F450100DE -:1039D0003C0308008C6300E02402FF80AF850034C4 -:1039E00000A318213064007F0344202100621824C2 -:1039F0003C02000A00822021AF430024275001002E -:103A00008E0200148C8300DCAF8400280043102356 -:103A100018400004000088218E0200140E000A8461 -:103A2000AC8200DC9202000B24030002304200FF53 -:103A30001443002F0000000096020008304300FFEE -:103A40002402008214620005240200840E00093E54 -:103A5000000000000A000E97000000001462000938 -:103A6000240200818F8200288F8400343C0760216B -:103A7000944500D49206000530A5FFFF0A000E868B -:103A800030C600FF14620027000000009202000A06 -:103A9000304300FF306200201040000430620040DC -:103AA0008F8400340A000E82240600401040000477 -:103AB000000316008F8400340A000E8224060041A1 -:103AC00000021603044100178F84003424060042CC -:103AD0008F8200283C076019944500D430A5FFFF71 -:103AE0000E000AF1000000000A000E97000000001E -:103AF0009202000B24030016304200FF1043000620 -:103B0000000000009202000B24030017304200FF67 -:103B100014430004000000000E000E11000000001D -:103B2000004088210E000B68000000009202000A8D -:103B3000304200081040000624020C808F850028C7 -:103B40003C0400080E0011EE0344202124020C80E6 -:103B5000AF4200248FBF0018022010218FB0001048 -:103B60008FB1001403E0000827BD002027BDFFE847 -:103B7000AFBF0014AFB000108F5000243C0308000A -:103B80008C6300E08F4501002402FF8000A3182110 -:103B90003064007F03442021006218243C02000AA4 -:103BA00000822021AF850034AF4300249082006260 -:103BB000AF8400283042000F34420050A0820062DF -:103BC0003C02001F3442FF800E00062602028024C1 -:103BD000AF5000248FBF00148FB0001003E0000826 -:103BE00027BD00183C0208008C4200201040001D38 -:103BF0002745010090A300093C0200080342202150 -:103C000024020018546200033C0200080A000ED887 -:103C10002402000803422021240200161462000539 -:103C20002402001724020012A082003F0A000EE2C4 -:103C300094A700085462000694A700089362000548 -:103C40002403FFFE00431024A362000594A700088C -:103C500090A6001B8CA4000094A500060A000ACCC4 -:103C600000073C0003E000080000000027440100BA -:103C700094820008304500FF38A3008238A20084F7 -:103C80002C6300012C420001006218251060000620 -:103C9000240200839382002D1040000D00000000DC -:103CA0000A000B9B0000000014A2000524A2FF8064 -:103CB0008F4301043C02602003E00008AC43001481 -:103CC000304200FF2C420002104000032402002278 -:103CD0000A000E3C0000000014A2000300000000D7 -:103CE0000A000EA9000000000A000EC70000000034 -:103CF0009363007E9362007A144300090000202140 -:103D00009362000024030050304200FF144300047B -:103D1000240400019362007E24420001A362007E1D -:103D200003E00008008010218F4201F80440FFFEEC -:103D300024020002AF4401C0A34201C43C021000AF -:103D400003E00008AF4201F827BDFFE8AFBF001055 -:103D50009362003F2403000A304200FF14430046F0 -:103D6000000000008F6300548F62004C1062007DE1 -:103D7000036030219362000024030050304200FFB2 -:103D80001443002F000000008F4401403C02080053 -:103D90008C4200E02403FF800082102100431024A5 -:103DA000AF4200243C0208008C4200E08F650054C2 -:103DB0003C03000A008220213084007F034410214C -:103DC00000431021AC4501089762003C8F63004C12 -:103DD0003042FFFF0002104000621821AF63005C18 -:103DE0008F6300548F64004C9762003C006418237A -:103DF0003042FFFF00031843000210400043102A26 -:103E000010400006000000008F6200548F63004CD9 -:103E1000004310230A000F58000210439762003C31 -:103E20003042FFFF00021040ACC2006424020001D7 -:103E3000A0C0007CA0C2008424020C80AF420024F9 -:103E40000E000F0A8F440140104000478FBF001042 -:103E50008F4301408F4201F80440FFFE240200021C -:103E6000AF4301C0A34201C43C021000AF4201F8BD -:103E70000A000FA88FBF00109362003F24030010B8 -:103E8000304200FF14430004000000008F44014052 -:103E90000A000F94000028219362003F24030016BB -:103EA000304200FF1443000424020014A362003FC8 -:103EB0000A000FA2000000008F62004C8F630050C8 -:103EC00000431023044100288FBF0010936200813B -:103ED00024420001A3620081936200812C4200040D -:103EE00014400010000000009362003F240300040F -:103EF000304200FF14430006000000008F440140E0 -:103F00008FBF0010240500930A0005A027BD0018EC -:103F10008F440140240500938FBF00100A00060F54 -:103F200027BD00188F4401400E0002500000000021 -:103F30008F6200542442FFFFAF6200548F62005032 -:103F40002442FFFFAF6200500E0002598F4401402F -:103F50008F4401408FBF0010240500040A00025E58 -:103F600027BD00188FBF001003E0000827BD001810 -:103F70008F4201889363007E00021402304400FFE8 -:103F8000306300FF1464000D0000000093620080A5 -:103F9000304200FF1044000900000000A3640080CC -:103FA0009362000024030050304200FF14430004D9 -:103FB000000000000A0006D78F440180A36400803F -:103FC00003E000080000000027BDFFE8AFB00010CC -:103FD000AFBF00149362000524030030304200306C -:103FE00014430089008080213C0208008C4200209C -:103FF00010400080020020210E0004930000000009 -:104000008F850020ACB000009362003E9363003FB8 -:10401000304200FF00021200306300FF0043102511 -:10402000ACA2000493620082000216000002160394 -:1040300004410005000000003C0308008C630048B8 -:104040000A000FE6000000009362003E304200408C -:10405000144000030000182193620081304300FFE8 -:104060009362008200031E00304200FF0002140031 -:1040700000621825ACA300088F620040ACA2000CBF -:104080008F620048ACA200108F62004CACA20014FA -:104090008F6200508F63004C0043102304410003E3 -:1040A000000000000A000FFA8F62004C8F6200507F -:1040B000ACA200183C02080094424B5E3C03C00BCB -:1040C00000002021004310250E0004B8ACA2001C03 -:1040D0008F6200548F840020AC8200008F620058F1 -:1040E000AC8200048F62005CAC8200088F620060CA -:1040F0008F43007400431021AC82000C8F62006477 -:10410000AC820010976300689762006A00031C008D -:104110003042FFFF00621825AC83001493620082D6 -:1041200024030080304200FF14430003000000001D -:104130000A00102EAC8000188F63000C24020001CE -:104140001062000E2402FFFF9362003E30420040E6 -:104150001440000A2402FFFF8F63000C8F4200749A -:10416000006218233C020800006210241440000280 -:10417000000028210060282100051043AC820018AF -:104180003C02080094424B5E3C03C00C000020211E -:10419000004310258F8300200E0004B8AC62001C81 -:1041A0008F6200188F8300203C05080094A54B5EA9 -:1041B00024040001AC620000AC6000048F66006C57 -:1041C0003C02400D00A22825AC6600088F6200DC8E -:1041D000AC62000CAC600010936200050002160097 -:1041E000AC620014AC6000180E0004B8AC65001C92 -:1041F000020020218FBF00148FB00010A3600005C3 -:104200000A00042127BD00188FBF00148FB00010D2 -:1042100003E0000827BD00189742007C30C600FF6D -:10422000A08600843047FFFF2402000514C2000B63 -:1042300024E3465090A201122C42000710400007D0 -:1042400024E30A0090A30112240200140062100467 -:1042500000E210210A0010663047FFFF3067FFFFC1 -:1042600003E00008A4870014AC87004C8CA201086E -:104270000080402100A0482100E2102330C600FF4A -:104280001840000393AA001324E2FFFCACA201082B -:1042900030C2000110400008000000008D020050F4 -:1042A00000E2102304410013240600058D0200548F -:1042B00010E20010000000008D02005414E2001A09 -:1042C000000000003C0208008C4200D83042002070 -:1042D0001040000A2402000191030078910200833B -:1042E000144300062402000101002021012028219E -:1042F000240600040A00105400000000A1000084FD -:1043000011400009A50200148F4301008F4201F8FB -:104310000440FFFE24020002AF4301C0A34201C4D7 -:104320003C021000AF4201F803E00008000000006A -:1043300027BDFFE88FA90028AFBF001000804021F3 -:1043400000E918231860007330C600FFA080007CCD -:10435000A08000818CA2010800E210230440004DDF -:10436000000000008C8200509483003C8C84006428 -:10437000004748233063FFFF012318210083202BCF -:1043800010800004000000008D0200640A0010B7D5 -:1043900000E210219502003C3042FFFF0122102173 -:1043A00000E21021AD02005C9502003C8D03005C30 -:1043B0003042FFFF0002104000E210210043102BAA -:1043C00010400003000000000A0010C68D02005CCF -:1043D0009502003C3042FFFF0002104000E2102135 -:1043E000AD02005CA1000084AD07004C8CA2010866 -:1043F00000E210231840000224E2FFFCACA20108F6 -:1044000030C200011040000A000000008D02005080 -:1044100000E2102304410004010020218D02005419 -:1044200014E20003000000000A0010E82406000562 -:104430008D02005414E200478FBF00103C020800B8 -:104440008C4200D8304200201040000A24020001B3 -:1044500091030078910200831443000624020001B6 -:1044600001002021240600048FBF00100A00105410 -:1044700027BD0018A1000084A50200148F4301008D -:104480008F4201F80440FFFE240200020A00110DD1 -:10449000000000008C82005C004910230043102BB8 -:1044A00054400001AC87005C9502003C3042FFFFA5 -:1044B0000062102B14400007240200029502003C09 -:1044C0008D03005C3042FFFF00621821AD03005CE9 -:1044D00024020002AD07004CA10200840E000F0A66 -:1044E0008F4401001040001B8FBF00108F4301005C -:1044F0008F4201F80440FFFE24020002AF4301C0D6 -:10450000A34201C43C021000AF4201F80A0011238B -:104510008FBF001030C200101040000E8FBF00107F -:104520008C83005C9482003C006918233042FFFFBA -:10453000006218213C023FFF3444FFFF0083102B30 -:10454000544000010080182101231021AD02005CBD -:104550008FBF001003E0000827BD001827BDFFE84B -:104560008FAA0028AFBF00100080402100EA482336 -:104570001920002130C600FF8C83005C8C8200640F -:10458000006A18230043102B5040001000691821C6 -:1045900094A2011001221021A4A2011094A20110E2 -:1045A0003042FFFF0043102B1440000A3C023FFF43 -:1045B00094A2011000431023A4A201109482003C95 -:1045C0003042FFFF0A00114200621821A4A001102E -:1045D0003C023FFF3444FFFF0083102B5440000196 -:1045E0000080182100671021AD02005CA100007C52 -:1045F0000A00118AA100008130C200101040003C66 -:10460000000000008C820050004A1023184000383F -:10461000000000009082007C24420001A082007C07 -:104620009082007C3C0308008C630024304200FF31 -:104630000043102B1440005C8FBF00108CA20108B7 -:1046400000E2102318400058000000008C83005442 -:104650009482003C006A18233042FFFF0003184395 -:10466000000210400043102A104000050000000026 -:104670008C820054004A10230A001171000210437A -:104680009482003C3042FFFF00021040AD02006403 -:104690009502003C8D0400649503003C3042FFFF0E -:1046A00000021040008220213063FFFF00831821A8 -:1046B00001431021AD02005C8D020054ACA2010840 -:1046C00024020002A10200840E000F0A8F440100A0 -:1046D000104000358FBF00108F4301008F4201F85A -:1046E0000440FFFE240200020A0011B30000000093 -:1046F000AD07004C8CA2010800E210231840000214 -:1047000024E2FFFCACA2010830C200011040000A04 -:10471000000000008D02005000E21023044100045C -:10472000010020218D02005414E20003000000006B -:104730000A0011AA240600058D02005414E2001A92 -:104740008FBF00103C0208008C4200D8304200208D -:104750001040000A240200019103007891020083B6 -:104760001443000624020001010020212406000455 -:104770008FBF00100A00105427BD0018A10000844C -:10478000A50200148F4301008F4201F80440FFFE90 -:1047900024020002AF4301C0A34201C43C02100046 -:1047A000AF4201F88FBF001003E0000827BD0018DA -:1047B0008FAA00108C8200500080402130C600FF7C -:1047C000004A102300A048211840000700E01821EB -:1047D00024020001A0800084A0A00112A482001481 -:1047E0000A001125AFAA0010A0800081AD07004C7F -:1047F0008CA2010800E210231840000224E2FFFC12 -:10480000ACA2010830C20001104000080000000006 -:104810008D0200500062102304410013240600059D -:104820008D02005410620010000000008D02005440 -:1048300014620011000000003C0208008C4200D805 -:10484000304200201040000A240200019103007849 -:10485000910200831443000624020001010020217C -:1048600001202821240600040A0010540000000042 -:10487000A1000084A502001403E00008000000006D -:1048800027BDFFE0AFBF0018274201009046000A95 -:104890008C4800148C8B004C9082008430C900FF3F -:1048A00001681823304A00FF1C60001A2D460006DC -:1048B000240200010142100410C00016304300031E -:1048C000012030210100382114600007304C000C19 -:1048D00015800009304200301440000B8FBF0018D3 -:1048E0000A001214000000000E001125AFAB0010EA -:1048F0000A0012148FBF00180E00109AAFAB001000 -:104900000A0012148FBF0018AFAB00100E0011BACE -:10491000AFAA00148FBF001803E0000827BD0020D5 -:1049200024020003A08200848C82005403E000086B -:10493000ACA201083C0200080342182190620081E9 -:10494000240600433C07601924420001A062008154 -:10495000906300813C0208008C4200C0306300FF7D -:10496000146200102403FF803C0208008C4200E027 -:104970000082102100431024AF4200243C020800B2 -:104980008C4200E03C03000A008210213042007F8C -:104990000342102100431021944500D40A000AF17B -:1049A00030A5FFFF03E000080000000027BDFFE086 -:1049B000AFBF0018AFB10014AFB000108F4201803C -:1049C0000080802100A088210E00121B00402021C1 -:1049D000A20000848E0200548FBF00188FB0001018 -:1049E000AE2201088FB1001403E0000827BD0020AB -:1049F00027BDFFE03C020008AFB00010AFBF0018B9 -:104A0000AFB10014034280218F5101409203008412 -:104A10008E0400508E02004C14820040306600FF6D -:104A20003C0208008C4200E02403FF800222102197 -:104A300000431024AF4200243C0208008C4200E0F6 -:104A40009744007C92050081022210213042007FB1 -:104A5000034218213C02000A0062182114A0000B36 -:104A60003084FFFF2402000554C20014248205DCB8 -:104A70009062011224420001A062011224020C8003 -:104A8000AF4200240A00127324020005A060011244 -:104A90002402000514C20009248205DC9202008170 -:104AA0002C4200075040000524820A009203008136 -:104AB0002402001400621004008210213044FFFF21 -:104AC000A60400140E00121B022020219602003CB6 -:104AD0008E03004C022020213042FFFF00021040D4 -:104AE000006218210E000250AE03005C9202007DAD -:104AF00002202021344200400E000259A202007D13 -:104B00008F4201F80440FFFE24020002AF5101C0B1 -:104B1000A34201C43C021000AF4201F88FBF00184D -:104B20008FB100148FB0001003E0000827BD0020F3 -:104B300008000ACC08000B1408000B9808000BE4CE -:044B400008000C203D -:0C4B44000A000028000000000000000033 -:104B50000000000D6370362E322E31000000000080 -:104B60000602010400000000000000000000000038 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000002005 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000001F4 -:104BC0000000002B000000000000000400030D4066 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000001000000300000000B2 -:104BF0000000000D0000000D3C020800244258A4F3 -:104C00003C03080024635F70AC4000000043202B8D -:104C10001480FFFD244200043C1D080037BD7FFCCA -:104C200003A0F0213C100800261000A03C1C080046 -:104C3000279C58A40E0001AC000000000000000DED -:104C400027BDFFE83C096018AFBF00108D2C500055 -:104C5000240DFF7F24080031018D5824356A380C5B -:104C600024070C003C1A8000AD2A50003C04800A46 -:104C7000AF4800083C1B8008AF4700240E00091510 -:104C8000AF8400100E0008D8000000000E000825B8 -:104C9000000000000E001252000000003C046016EC -:104CA0008C8500003C06FFFF3C02535300A61824ED -:104CB0001062004734867C0094C201F2A780002C69 -:104CC00010400003A78000CC38581E1EA798002C67 -:104CD00094C201F810400004978300CC38591E1E7E -:104CE000A79900CC978300CC2C7F006753E000018C -:104CF000240300669784002C2C82040114400002D7 -:104D000000602821240404003C0760008CE904387A -:104D10002403103C3128FFFF1103001F30B9FFFFAF -:104D200057200010A38000CE24020050A38200CEA2 -:104D3000939F00CE53E0000FA78500CCA78000CC46 -:104D4000978500CC8FBF0010A780002CA78000346F -:104D5000A78000E63C010800AC25008003E00008C5 -:104D600027BD0018939F00CE57E0FFF5A78000CC29 -:104D7000A78500CC978500CC8FBF0010A784002C9E -:104D8000A7800034A78000E63C010800AC25008025 -:104D900003E0000827BD0018A38000CE8CCB003CA8 -:104DA000316A00011140000E0000000030A7FFFF33 -:104DB00010E0FFDE240200508CCC00C831860001D8 -:104DC00014C0FFDC939F00CE0A00007A2402005139 -:104DD0008C8F00043C0E60000A00005D01EE302163 -:104DE0008CEF0808240D5708000F740211CD000441 -:104DF00030B8FFFF240500660A00007B240404008D -:104E00001700FFCC939F00CE0A00007A24020050C6 -:104E10008F8600103089FFFF000939408CC30010D5 -:104E20003C08005000E82025AF4300388CC5001432 -:104E300027420400AF82001CAF45003CAF44003065 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60008F4B0000316A00201140FFFD0000000060 -:104E700003E00008000000008F840010948A001AEC -:104E80008C8700243149FFFF000940C000E8302131 -:104E9000AF46003C8C8500248F43003C00A31023C8 -:104EA00018400029000000008C8B002025620001C2 -:104EB0003C0D005035AC0008AF420038AF4C00301C -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE0008F4F000031EE002011C0FFFD00000000D8 -:104EF0008F4A04003C080020AC8A00108F4904044B -:104F0000AC890014AF4800300000000094860018FF -:104F10009487001C00C71821A48300189485001AE8 -:104F200024A20001A482001A9498001A9499001EE9 -:104F3000133800030000000003E000080000000038 -:104F400003E00008A480001A8C8200200A0000DC24 -:104F50003C0D00500A0000CD000000003C0308009A -:104F60008C6300208F82001827BDFFE810620008C4 -:104F7000AFBF00100E000104AF8300183C0308000F -:104F80008C63002024040001106400048F89001049 -:104F90008FBF001003E0000827BD00188FBF00106E -:104FA0003C076012A520000A9528000A34E500108D -:104FB00027BD00183106FFFF03E00008ACA60090F3 -:104FC0003C0208008C42002027BDFFC8AFBF003460 -:104FD000AFBE0030AFB7002CAFB60028AFB500248D -:104FE000AFB40020AFB3001CAFB20018AFB10014D3 -:104FF00010400050AFB000108F840010948600065F -:105000009483000A00C3282330B6FFFF12C0004A71 -:105010008FBF003494890018948A000A012A402323 -:105020003102FFFF02C2382B14E0000202C020212F -:10503000004020212C8C0005158000020080A0215A -:10504000241400040E0000B3028020218F8700107A -:1050500002809821AF80001494ED000A028088211C -:105060001280004E31B2FFFF3C1770003C1540002B -:105070003C1E60008F8F001C8DEE000001D71824AD -:10508000507500500220202102A3802B160000350D -:105090003C182000507800470220202124100001F5 -:1050A0008F83001414600039029158230230F823D2 -:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D -:1050C0008F8700103C110020AF510030000000001D -:1050D00094E6000A3C1E601237D5001002662821B3 -:1050E000A4E5000A94E2000A94F2000A94F400187D -:1050F0003057FFFF1292003BAEB700908CED0014CA -:105100008CE400100013714001AE4021000E5FC31B -:10511000010E502B008B4821012A1821ACE8001405 -:10512000ACE3001002D3382330F6FFFF16C0FFB9FE -:105130008F8400108FBF00348FBE00308FB7002CDB -:105140008FB600288FB500248FB400208FB3001CC9 -:105150008FB200188FB100148FB0001003E0000868 -:1051600027BD0038107E001B000000001477FFCC24 -:10517000241000010E00159B000000008F83001416 -:105180001060FFCB0230F823029158238F87001064 -:10519000017020210A0001973093FFFF8F830014D4 -:1051A0001460FFCB3C110020AF5100300A000163B6 -:1051B000000000000E00077D024028210A00015770 -:1051C000004080210E00033A024028210A000157C6 -:1051D000004080210E001463022020210A000157A4 -:1051E000004080210E0000CD000000000A0001797F -:1051F00002D3382327BDFFE8AFB00010AFBF0014C3 -:105200000E00003F000000003C028000345000709F -:105210000A0001BA8E0600008F4F000039EE00012F -:1052200031C20001104000248F8600A88E070000C4 -:105230003C0C08008D8C003C3C0908008D2900388E -:1052400000E66823018D28210000502100AD302B9D -:10525000012A4021010620213C010800AC25003C28 -:10526000AF8700A83C010800AC2400380E000106FE -:10527000000000003C0308008C6300701060FFE633 -:10528000006020213C0508008CA500683C06080051 -:105290008CC6006C0E00152A000000003C010800BE -:1052A000AC2000708F4F000039EE000131C20001C8 -:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6 -:1052C0003C0508008CA5003C3C0408008C84003898 -:1052D000014B482300A938210082182100E9402B06 -:1052E000006810213C010800AC27003C3C0108008C -:1052F000AC2200388F5F01002419FF0024180C0035 -:1053000003F9202410980012AF840000AF4400205D -:10531000936D0000240C002031A600FF10CC001279 -:10532000240E005010CE00043C194000AF59013843 -:105330000A0001B3000000000E0011C800000000C8 -:105340003C194000AF5901380A0001B300000000C9 -:105350000E00011F000000003C194000AF59013849 -:105360000A0001B3000000008F58010000802821CE -:10537000330F00FF01E020210E0002F1AF8F000487 -:105380003C194000AF5901380A0001B30000000089 -:1053900000A4102B2403000110400009000030215C -:1053A0000005284000A4102B04A0000300031840AF -:1053B0005440FFFC000528405060000A0004182BF0 -:1053C0000085382B54E000040003184200C3302548 -:1053D00000852023000318421460FFF900052842CD -:1053E0000004182B03E0000800C310218F4201B80D -:1053F0000440FFFE00000000AF4401803C031000A9 -:1054000024040040AF450184A3440188A3460189D8 -:10541000A747018A03E00008AF4301B83084FFFFCB -:105420000080382130A5FFFF000020210A00022A59 -:10543000240600803087FFFF8CA40000240600387B -:105440000A00022A000028218F8300388F8600304E -:105450001066000B008040213C07080024E75A1822 -:10546000000328C000A710218C4400002463000121 -:10547000108800053063000F5466FFFA000328C04F -:1054800003E00008000010213C07080024E75A1C34 -:1054900000A7302103E000088CC200003C0390000C -:1054A0003462000100822025AF4400208F45002097 -:1054B00004A0FFFE0000000003E000080000000060 -:1054C0003C038000346200010082202503E00008D4 -:1054D000AF44002027BDFFE0AFB100143091FFFFC3 -:1054E000AFB00010AFBF00181220001300A0802141 -:1054F0008CA2000024040002240601401040000F8A -:10550000004028210E000C5C00000000000010216B -:10551000AE000000022038218FBF00188FB10014A8 -:105520008FB0001000402021000028210000302111 -:105530000A00022A27BD00208CA200000220382188 -:105540008FBF00188FB100148FB0001000402021D1 -:1055500000002821000030210A00022A27BD002077 -:1055600000A010213087FFFF8CA500048C440000B0 -:105570000A00022A2406000627BDFFE0AFB0001093 -:10558000AFBF0018AFB100149363003E00808021CC -:105590000080282130620040000020211040000FD0 -:1055A0008E1100000E000851022020219367000098 -:1055B0002404005030E500FF50A400128E0F0000BC -:1055C000022020218FBF00188FB100148FB000106F -:1055D000A762013C0A00091127BD00200E000287C6 -:1055E000000000000E0008510220202193670000F7 -:1055F0002404005030E500FF14A4FFF20220202113 -:105600008E0F00003C1008008E1000503C0D000C66 -:10561000240BFF8001F05021314E007F01DA602120 -:10562000018D4021014B4824AF4900280220202150 -:105630008FBF00188FB100148FB00010A50200D6E4 -:1056400027BD00200A000911AF8800D027BDFFE068 -:10565000AFBF0018AFB10014AFB0001093660001E7 -:10566000008080210E00025630D1000493640005B2 -:10567000001029C2A765000034830040A363000521 -:105680000E00025F020020210E00091302002021FB -:1056900024020001AF62000C02002821A762001062 -:1056A00024040002A762001224060140A76200142D -:1056B0000E000C5CA76200161620000F8FBF0018AA -:1056C000978C00343C0B08008D6B00782588FFFF19 -:1056D0003109FFFF256A0001012A382B10E000067E -:1056E000A78800343C0F6006240E001635ED00102C -:1056F000ADAE00508FBF00188FB100148FB00010F6 -:1057000003E0000827BD002027BDFFE0AFB1001473 -:10571000AFBF0018AFB0001000A088211080000AB1 -:105720003C03600024020080108200120000000090 -:105730000000000D8FBF00188FB100148FB0001053 -:1057400003E0000827BD00208C682BF80500FFFE51 -:1057500000000000AC712BC08FBF00188FB1001487 -:105760008FB000103C09100027BD002003E00008A6 -:10577000AC692BF80E00025600A0202193650005AD -:10578000022020210E00025F30B000FF2403003E03 -:105790001603FFE7000000008F4401780480FFFE3D -:1057A000240700073C061000AF51014002202021D1 -:1057B000A34701448FBF00188FB100148FB00010B1 -:1057C000AF4601780A0002C227BD002027BDFFE8CE -:1057D000AFBF0014AFB000108F50002000000000D9 -:1057E0000E000913AF440020AF5000208FBF0014FB -:1057F0008FB0001003E0000827BD00183084FFFFC1 -:10580000008038212406003500A020210A00022A49 -:10581000000028213084FFFF008038212406003654 -:1058200000A020210A00022A0000282127BDFFD065 -:10583000AFB3001C3093FFFFAFB50024AFB2001828 -:10584000AFBF0028AFB40020AFB10014AFB000105C -:1058500030B5FFFF12600027000090218F90001CE0 -:105860008E0300003C0680002402004000033E023C -:1058700000032C0230E4007F006688241482001D9F -:1058800030A500FF8F8300282C68000A510000100B -:105890008F910014000358803C0C0800258C56940E -:1058A000016C50218D49000001200008000000001B -:1058B00002B210213045FFFF0E000236240400849E -:1058C000162000028F90001CAF8000288F910014DA -:1058D000260C002026430001018080213072FFFF4A -:1058E00016200004AF8C001C0253502B1540FFDC27 -:1058F00000000000024010218FBF00288FB5002457 -:105900008FB400208FB3001C8FB200188FB1001429 -:105910008FB0001003E0000827BD0030240E0034D3 -:1059200014AE00F9000000009203000E241F168040 -:105930003C07000CA36300219202000D0347C8211D -:105940003C066000A3620020961100123C0A7FFF13 -:10595000354CFFFFA771003C960B00102403000597 -:105960003168FFFFAF6800848E05001CAF5F002820 -:105970008F3800008CC4444803057826008F3021FE -:10598000AF66004C8F69004C24CE00013C057F00BF -:10599000AF6900508F740050AF740054AF66007050 -:1059A000AF6E00588F6D005824140050AF6D005C2E -:1059B000A3600023AF6C0064A36300378E02001461 -:1059C000AF6200488F710048AF7100248E0B001841 -:1059D000AF6B006C9208000CA3680036937F003E0A -:1059E00037F90020A379003E8F78007403058024E6 -:1059F000360F4000AF6F007493640000308900FFE1 -:105A0000513402452404FF803C04080024845A9841 -:105A10000E00028D000000003C1008008E105A9805 -:105A20000E00025602002021240600042407000173 -:105A3000A366007D020020210E00025FA36700051F -:105A40008F5F017807E0FFFE240B0002AF5001409A -:105A5000A34B01448F90001C3C081000AF48017814 -:105A60000A000362AF8000282CAD003751A0FF98D8 -:105A70008F9100140005A0803C180800271856BC20 -:105A8000029878218DEE000001C00008000000009F -:105A90002418000614B80011000000003C0808009B -:105AA0008D085A9824040005AF4800208E1F001866 -:105AB000AF7F00188F79004CAF79001C8F650050C4 -:105AC000122000C0AF6500700A000362AF84002896 -:105AD0002406000710A60083240300063C050800E6 -:105AE00024A55A980E000264240400818F90001CA3 -:105AF0000011102B0A000362AF8200282407000463 -:105B000014A7FFF6240500503C1808008F185A9877 -:105B1000AF5800208E0F0008AF6F00408E090008BC -:105B2000AF6900448E14000CAF7400488E0E001054 -:105B3000AF6E004C8E0D0010AF6D00848E0A001405 -:105B4000AF6A00508E0C0018AF6C00548E04001C1D -:105B5000AF64005893630000306B00FF116501D8FB -:105B6000000000008F7400488F6900400289702394 -:105B700005C000042404008C1620FFDE240200036C -:105B8000240400823C05080024A55A980E000287D0 -:105B9000000000008F90001C000010210A0003622A -:105BA000AF820028240F000514AFFFCC240520008D -:105BB0003C0708008CE75A98AF4700208E06000487 -:105BC000AF66005C9208000824100008A36800215A -:105BD0008F9F001C93F90009A37900208F86001C79 -:105BE00090D8000A330400FF10900011000000005C -:105BF0002885000914A0006924020002240A00205C -:105C0000108A000B34058000288D002115A00008A3 -:105C100024054000240E0040108E00053C050001C4 -:105C200024140080109400023C050002240540006A -:105C30008F7800743C19FF00031980240205782531 -:105C4000AF6F007490C4000BA36400818F84001CAC -:105C50009489000C11200192000000009490000C27 -:105C60002406FFBF24050004A770003C908F000E9F -:105C7000A36F003E8F84001C9089000FA369003F32 -:105C80008F8B001C8D6E00108F54007401D468231C -:105C9000AF6D00608D6A0014AF6A0064956C0018E7 -:105CA000A76C00689563001AA763006A8D62001CE8 -:105CB000AF62006C9167000EA367003E9368003EE0 -:105CC0000106F8241220014BA37F003E8F90001C98 -:105CD0000A000362AF8500282407002214A7FF7F73 -:105CE000240300073C0B08008D6B5A981220000C0F -:105CF000AF4B00200A000362AF830028240C00335E -:105D000010AC0014240A00283C05080024A55A9869 -:105D10000E00023C240400810A0003EB8F90001C5B -:105D20003C04080024845A980E00028D00000000F4 -:105D30009363000024110050306200FF10510135C0 -:105D4000000000008F90001C000018210A00036270 -:105D5000AF8300283C0D08008DAD5A9824040081C3 -:105D6000AF4D00203C05080024A55A980E00023CC7 -:105D7000A36A00348F90001C240200090A00036209 -:105D8000AF82002802B288213225FFFF0E000236C2 -:105D9000240400840A0003628F90001C1082FFA478 -:105DA00024050400288B000311600170240C0004FA -:105DB000240300015483FF9E240540000A00043B95 -:105DC000240501003C04080024845A988F62004C8A -:105DD0000E00028D8F6300508F90001C0000202168 -:105DE0000A000362AF8400288E1000042404008A95 -:105DF000AF50002093790005333800021700015F8F -:105E0000020028219368002302002821311F00206E -:105E100017E0015A2404008D9367003F2406001206 -:105E200030E200FF10460155240400810E000256A6 -:105E30000200202193630023240500040200202196 -:105E4000346B0042A36B00230E00025FA365007D4C -:105E50008F4401780480FFFE240A0002AF50014005 -:105E6000A34A01448F90001C3C0C1000AF4C0178F9 -:105E70000A0003EC0011102B8E1000042404008A89 -:105E8000AF500020936E000531CD000215A0001622 -:105E900002002821936F003F2414000402002821EF -:105EA00031E900FF11340010240400810E00025675 -:105EB000020020219362002324080012241FFFFE09 -:105EC00034460020A3660023A368003F93790005B1 -:105ED00002002021033FC0240E00025FA3780005CA -:105EE00002002821000020210E00033400000000E1 -:105EF0000A0003EB8F90001C8E1000043C03000886 -:105F00000343A021AF500020928B000024050050D5 -:105F1000316400FF10850161240700880200202100 -:105F2000000028210E00022A2406000E928D000097 -:105F3000240EFF800200282101AE8025A2900000DF -:105F4000240400040E000C5C240600300A0003EB5D -:105F50008F90001C8E0800043C14080026945A9868 -:105F60003C010800AC285A98AF480020921F00035B -:105F700033F9000413200002240200122402000658 -:105F8000A362003F920B001B2404FFC03165003F59 -:105F900000A43825A367003E9206000330C200012A -:105FA00014400132000000008E020008AE8200089A -:105FB0003C0208008C425AA010400131000249C244 -:105FC000A76900088E14000C240C0001240300149F -:105FD000AF74002C8E0E0010AF6E0030960D0016C0 -:105FE000A76D0038960A0014A76A003AAF6C000C3F -:105FF000A76C0010A76C0012A76C0014A76C001609 -:1060000012200136A3630034920F000331F0000226 -:106010002E1100018F90001C262200080A00036246 -:10602000AF8200288E0400043C0E0008034E30218D -:10603000AF4400208E05000890CD0000240C0050D5 -:1060400031AA00FF114C00862407008824060009AD -:106050000E00022A000000000A0003EB8F90001CD3 -:106060008E04001C0E00024100000000104000F4ED -:10607000004050218F89001C240700890140202105 -:106080008D25001C240600010E00022A00000000DD -:106090000A0003EB8F90001C960D00023C140800D0 -:1060A00026945A9831AA0004514000B83C10600070 -:1060B0008E0E001C3C010800AC2E5A98AF4E0020FA -:1060C000920700102408001430E200FF144800D6A4 -:1060D00000000000960B00023163000114600165AE -:1060E000000000008E020004AE8200083C1408008C -:1060F0008E945AA01280015B000000008F7400741F -:106100003C0380002404000102835825AF6B007417 -:10611000A3600005AF64000C3C0708008CE75AA0A0 -:106120008F86001CA7640010000711C2A76400122C -:10613000A7640014A7640016A76200088CC80008B2 -:1061400024040002AF68002C8CC5000CAF65003041 -:1061500090DF0010A37F00348F99001C9330001152 -:10616000A37000358F98001C930F0012A36F0036A8 -:106170008F89001C912E0013A36E00378F90001C96 -:10618000960D0014A76D0038960A0016A76A003A0B -:106190008E0C0018AF6C00245620FDCCAF84002874 -:1061A0003C05080024A55A980E0002640000202136 -:1061B0008F90001C0A0004A7000020218E1000040C -:1061C00024070081AF500020936900233134001070 -:1061D000128000170000000002002021000028218A -:1061E0002406001F0E00022A000000000A0003EB34 -:1061F0008F90001C3C05080024A55A980E000287C9 -:10620000240400828F90001C000028210A000362F1 -:10621000AF8500283C0408008C845A980E0014E8CE -:10622000000000008F90001C0A000482000018216A -:106230000E00025602002021937800230200202144 -:10624000370F00100E00025FA36F002300003821FB -:1062500002002021000028210A0005A82406001FB2 -:10626000920F000C31E90001112000030000000032 -:106270009618000EA4D8002C921F000C33F90002CF -:1062800013200005000038218E0200149608001229 -:10629000ACC2001CA4C8001A0A0005432406000969 -:1062A0003C05080024A55A980E0002872404008BA0 -:1062B0008F90001C0011282B0A000362AF85002874 -:1062C000AF6000843C0A08008D4A5A983C0D0800D3 -:1062D0008DAD0050240CFF803C02000C014D1821B4 -:1062E000006C2024AF4400288E070014306B007F20 -:1062F000017A282100A2C821AF2700D88E060014F9 -:10630000AF9900D0AF2600DC8E080010251FFFFEDD -:106310000A000408AF3F01083C0508008CA55A9804 -:106320003C1908008F39005024CCFFFE00B9C02171 -:1063300003047824AF4F00283C1408008E945A9828 -:106340003C0908008D2900500289702131CD007F61 -:1063500001BA502101478021AE0600D8AF9000D08D -:10636000AE0000DC0A0003B1AE0C0108548CFE3014 -:10637000240540000A00043B240510000E00032EF3 -:10638000000000000A0003EB8F90001C8E0F442CCD -:106390003C186C62370979703C010800AC205A98AF -:1063A00015E9000824050140979F00349786002CCA -:1063B0000280282103E6C82B132000112404009238 -:1063C000240501400E000C7A240400023C01080060 -:1063D000AC225A98AF4200203C0508008CA55A9880 -:1063E00010A00005240400830E00084500000000F2 -:1063F00010400009240400833C05080024A55A9895 -:106400000E000264000000008F90001C0011202B81 -:106410000A000362AF8400280E0008490000000053 -:106420000A00055F8F90001C0E00084D0000000060 -:106430003C05080024A55A980A00062F2404008B66 -:10644000240400040E000C7A240500301440002AB5 -:10645000004050218F89001C240700830140202127 -:106460008D25001C0A000551240600018E04000839 -:106470000E000241000000000A00051BAE82000869 -:106480003C05080024A55A980E00023C240400870D -:106490008F90001C0A0005360011102B8F830038E6 -:1064A0008F8600301066FE9D000038213C070800F2 -:1064B00024E75A1C000320C0008728218CAC000070 -:1064C00011900061246A00013143000F5466FFFA05 -:1064D000000320C00A0004F6000038213C05080033 -:1064E00024A55A980E000287240400828F90001C75 -:1064F0000A000536000010213C0B0008034B202148 -:106500002403005024070001AF420020A0830000B4 -:10651000A08700018F82001C90480004A08800180A -:106520008F85001C90A60005A08600198F9F001C77 -:1065300093F90006A099001A8F90001C921800078A -:10654000A098001B8F94001C928F0008A08F001C45 -:106550008F89001C912E0009A08E001D8F8D001CBC -:1065600091AC000AA08C001E8F8B001C3C0C080014 -:10657000258C5A1C9163000B3C0B0800256B5A18A4 -:10658000A083001F8F87001C90E8000CA0880020CB -:106590008F82001C9045000D24024646A0850021F4 -:1065A0008F86001C90DF000EA09F00228F99001C98 -:1065B0009330000FA09000238F98001C93140010BC -:1065C000A09400248F8F001C91E90011A089002560 -:1065D0008F89001C8F8E00308F900038952D00140D -:1065E000000E18C025C80001A48D002895270016AC -:1065F000006C3021006BC821A487002A9525001863 -:106600003108000FA485002CA482002E8D3F001CB1 -:10661000ACCA0000AF88003011100006AF3F000088 -:10662000000038218D25001C014020210A00055161 -:1066300024060001250C00013184000F00003821E0 -:106640000A0006B8AF8400383C07080024E75A184F -:106650000087302100003821ACA000000A0004F6B9 -:10666000ACC000003C05080024A55A980A00062F7B -:10667000240400878E0400040E0002410000000084 -:106680000A00056AAE8200083084FFFF30C600FFB2 -:106690008F4201B80440FFFE00064400010430258B -:1066A0003C07200000C720253C031000AF400180BC -:1066B000AF450184AF44018803E00008AF4301B84F -:1066C00027BDFFE8AFB00010AFBF00143C0760006B -:1066D000240600021080000600A080210010102B6C -:1066E0008FBF00148FB0001003E0000827BD001812 -:1066F0003C09600EAD2000348CE5201C8F82001C0C -:106700002408FFFC00A81824ACE3201C0E0006D1CE -:106710008C45000C0010102B8FBF00148FB00010A0 -:1067200003E0000827BD00183C02600E344701005A -:1067300024090018274A040000000000000000009F -:10674000000000003C06005034C30200AF44003893 -:10675000AF45003CAF430030014018218F4B000093 -:10676000316800201100FFFD2406007F2408FFFF90 -:106770008C6C000024C6FFFF24630004ACEC000016 -:1067800014C8FFFB24E70004000000000000000024 -:10679000000000003C0F0020AF4F00300000000060 -:1067A00024AD020001A5702B2529FFFF008E2021BA -:1067B0001520FFE101A0282103E0000800000000EF -:1067C00027BDFFE0AFB10014AFBF0018AFB000109D -:1067D0003C05600E8CA20034008088211440000625 -:1067E0003C0460008C87201C2408FFFC00E8302457 -:1067F00034C30001AC83201C8F8B001C24090001D2 -:10680000ACA90034956900028D6500148D70000CF0 -:106810002D2400818D6700048D660008108000071C -:106820008D6A00102D2C00041580000E30CE00075C -:10683000312D000311A0000B000000002404008B88 -:10684000020028210E0006D1240600030011102B9F -:106850008FBF00188FB100148FB0001003E0000844 -:1068600027BD002015C0FFF62404008B3C03002048 -:10687000AF4300300000000024020001AF8200148A -:106880000000000000000000000000003C1F01505C -:10689000013FC825253800033C0F600EAF47003884 -:1068A00000181882AF46003C35E8003CAF59003074 -:1068B000274704008F4400003086002010C0FFFDF1 -:1068C00000000000106000082466FFFF2403FFFFA3 -:1068D0008CEB000024C6FFFF24E70004AD0B000092 -:1068E00014C3FFFB250800043C08600EAD09003806 -:1068F0000000000000000000000000003C07002035 -:10690000AF470030000000000E0006F901402021D2 -:1069100002002821000020210E0006D124060003D9 -:106920000011102B8FBF00188FB100148FB0001012 -:1069300003E0000827BD002027BDFFE0AFB200182C -:106940003092FFFFAFB10014AFBF001CAFB000101A -:106950001640000D000088210A0007AA022010211D -:1069600024050001508500278CE5000C0000000D77 -:10697000262300013071FFFF24E200200232382B71 -:1069800010E00019AF82001C8F8200141440001622 -:106990008F87001C3C0670003C0320008CE5000043 -:1069A00000A62024148300108F84003C00054402BC -:1069B0003C09800000A980241480FFE9310600FF13 -:1069C0002CCA00095140FFEB262300010006688015 -:1069D0003C0E080025CE579801AE60218D8B00003B -:1069E0000160000800000000022010218FBF001C81 -:1069F0008FB200188FB100148FB0001003E00008B0 -:106A000027BD00200E0006D1240400841600FFD804 -:106A10008F87001C0A00078BAF80003C90EF0002BC -:106A200000002021240600090E0006D1000F2E00D0 -:106A30008F87001C0010102B0A00078BAF82003CD0 -:106A4000020028210E0006DF240400018F87001CAD -:106A50000A00078BAF82003C020028210E0006DFEF -:106A6000000020210A0007C38F87001C0E00071FAB -:106A7000020020210A0007C38F87001C30B0FFFFEF -:106A8000001019C08F5801B80700FFFE3C1F2004FA -:106A90003C191000AF430180AF400184AF5F018813 -:106AA000AF5901B80A00078C262300013082FFFF8E -:106AB00014400003000018210004240224030010E5 -:106AC000308500FF14A000053087000F2466000801 -:106AD0000004220230C300FF3087000F14E00005DD -:106AE000308900032468000400042102310300FF00 -:106AF0003089000315200005388B0001246A00024C -:106B000000042082314300FF388B00013164000112 -:106B100010800002246C0001318300FF03E00008B4 -:106B200000601021308BFFFF000B394230E600FF80 -:106B30003C09080025295998000640800109602178 -:106B40008D8700003164001F240A0001008A1804A8 -:106B500030A500FF00E3202514A000020003102749 -:106B600000E22024240F000100CF700401096821F5 -:106B7000000E282714800005ADA400008F86000CAD -:106B800000A6102403E00008AF82000C8F88000CE0 -:106B900001C8102503E00008AF82000C3C06001F6E -:106BA0003C0360003084FFFF34C5FF8024020020D6 -:106BB000AC602008AC60200CAC602010AC652014E8 -:106BC000AC642018AC62200000000000000000004F -:106BD00003E000080000000027BDFFE82402FFFFDB -:106BE000AFBF0010AF82000C000020213C0608005F -:106BF00024C659982405FFFF248900010004408021 -:106C00003124FFFF010618212C87002014E0FFFA31 -:106C1000AC6500000E0008160000202124020001CF -:106C20003C04600024050020AC822018AC852000C4 -:106C3000000000000000000000000000244A0001E5 -:106C40003142FFFF2C46040014C0FFF78FBF001035 -:106C500003E0000827BD00188F8300082C620400A1 -:106C600003E00008384200018F830008246200011D -:106C700003E00008AF8200088F8300082462FFFF52 -:106C800003E00008AF82000827BDFFE0AFB10014A9 -:106C9000AFBF0018AFB000108F6B00303C06600033 -:106CA00000808821ACCB20088F6A002C3C02800039 -:106CB00024030008ACCA200C9769003A9768003892 -:106CC00000092C003107FFFF00A72025ACC42010CD -:106CD000ACC22014ACC32000000000000000000083 -:106CE000000000003C0360008C6D200031AC000807 -:106CF0001580FFF9000000008C6E201405C00020F4 -:106D0000000000000E0007DA8F84000C00024080B3 -:106D10003C09080025295998010938218CE4000014 -:106D20000E0007DA00028140020220213090FFFFAE -:106D3000020020210E0007F8000028213C0C8000F2 -:106D4000022C58253210FFFF3C116000240A00205D -:106D5000AE2B2014AE302018AE2A20000000000018 -:106D60000000000000000000020010218FBF00188A -:106D70008FB100148FB0001003E0000827BD002081 -:106D80008C6620143C02001F3443FF803C1FFFE848 -:106D900000C3C02437F9080003198021001079C20C -:106DA0003C0C8000022C582531F0FFFF3C116000A4 -:106DB000240A0020AE2B2014AE302018AE2A20006A -:106DC0000000000000000000000000000200102190 -:106DD0008FBF00188FB100148FB0001003E00008BF -:106DE00027BD002027BDFFE8AFB000103402FFFF31 -:106DF0003090FFFFAFBF00141202000602002021F6 -:106E00000E00081600000000020020210E0007F806 -:106E1000240500018F8400088FBF00148FB000107C -:106E20002483FFFF27BD001803E00008AF8300089C -:106E3000000439C230E6003F00043B42000718401E -:106E4000240210002CC4002024C8FFE0AF42002C14 -:106E5000246300011480000330A900FF00071840DC -:106E6000310600FF0003608024080001019A5821C8 -:106E70003C0A000E00C82804016A382111200005D0 -:106E8000000530278CE900000125302503E00008CB -:106E9000ACE600008CEE000001C6682403E00008A8 -:106EA000ACED000027BDFFE8AFBF0014AFB000108D -:106EB0003C0460008C8508083403F00030A2F00028 -:106EC00050430006240200018C8708083404E000C7 -:106ED00030E6F00010C4001E24020002AF82004021 -:106EE0003C1060003C0A0200AE0A0814240910009D -:106EF0003C08000E8E03440003482021AF49002CBB -:106F0000240501200E000CC0000030218F830040BA -:106F1000106000043C021691240B0001106B000E5F -:106F20003C023D2C344F0090AE0F44088FBF00143C -:106F30008FB000103C0C6000240E10003C0D0200CD -:106F400027BD0018AD8E442003E00008AD8D081069 -:106F50000A0008E7AF8000403C0218DA344F009086 -:106F6000AE0F44088FBF00148FB000103C0C6000BF -:106F7000240E10003C0D020027BD0018AD8E4420E9 -:106F800003E00008AD8D08100A0008BB24050001CD -:106F90000A0008BB000028213C08080025085DA461 -:106FA0002404FFFF010018212402001E2442FFFFD9 -:106FB000AC6400000441FFFD246300043C070800AA -:106FC00024E75E208CE5FFFC2404001C240600015D -:106FD000308A001F0146480424840001000910275C -:106FE0002C8300201460FFFA00A22824ACE5FFFCEB -:106FF0003C05666634A4616E3C06080024C65EE06B -:10700000AF840058AF88009C2404FFFF00C0182103 -:107010002402001F2442FFFFAC6400000441FFFD76 -:10702000246300043C0766663C05080024A55EA0B6 -:10703000AF86004834E6616EAF8600982404FFFFF7 -:1070400000A018212402000F2442FFFFAC640000BE -:107050000441FFFD246300043C0B66663C06080007 -:1070600024C65E203568616EAF8500A4AF880070CD -:107070002404FFFF00C018212402001F2442FFFF48 -:10708000AC6400000441FFFD246300043C0D66660F -:107090003C0A0800254A5F6035AC616EAF860090FF -:1070A000AF8C005C2404FFFF014018212402000380 -:1070B0002442FFFFAC6400000441FFFD2463000490 -:1070C0003C09080025295F708D27FFFC2404000679 -:1070D000240500013099001F0325C0042484000109 -:1070E000001878272C8E002015C0FFFA00EF3824F6 -:1070F000AD27FFFC3C09666624030400240403DC7E -:1071000024050200240600663522616E3C08080052 -:1071100025085AA4AF820074AF830044AF83006C8B -:10712000AF830050AF830084AF8A008CAF840064CB -:10713000AF85004CAF860054AF840078AF85006007 -:10714000AF86008001001821240200022442FFFFC4 -:10715000AC6000000441FFFD24630004240400032C -:107160002403000C3C0A0800254A5AB0AF8A006884 -:107170000A00098E2405FFFF000418802484000102 -:10718000006858212C8700C014E0FFFBAD650000AB -:107190003C0E666635CD616E240C17A024081800DD -:1071A000AF8D0088AF8C009403E00008AF88007CAE -:1071B0002484007F000421C200004021000030210F -:1071C00000003821000028210A0009A5AF8400A092 -:1071D0001060000624E7000100C4302124A500014E -:1071E0002CC20BF51440FFFA2CA300663C090800E2 -:1071F00025295F6001201821240200032442FFFF9B -:10720000AC6000000441FFFD2463000410E0001A9C -:1072100024E3FFFF0003294210A0000A0000202100 -:107220002406FFFF3C03080024635F602484000100 -:107230000085502BAC660000250800011540FFFBBF -:107240002463000430E2001F10400008000868803A -:10725000240C0001004C38040008588001692821E2 -:1072600024E6FFFF03E00008ACA6000001A94021CE -:107270002409FFFFAD09000003E000080000000042 -:10728000AF4400283C04000C034420210005288260 -:107290000A000CC000003021000421803C03600083 -:1072A000AC6410080000000000052980AC65100CDB -:1072B0000000000003E000088C62100C27BDFFE80E -:1072C0000080282124040038AFBF00140E0009D527 -:1072D000AFB0001024040E00AF4400283C10000C96 -:1072E00003502021240500100E000CC000003021A6 -:1072F00003501021AC400000AC40000424040038CE -:107300008FBF00148FB0001024053FFF27BD001869 -:107310000A0009D58C430000000421803C03600072 -:10732000AC641008000000008C62100C03E0000840 -:107330000002118227BDFFC8AFB400208F940068FF -:10734000AFBE0030AFB7002CAFB600280000B821A8 -:107350000080B021241E00C0AFBF0034AFB50024B0 -:10736000AFB3001CAFB20018AFB10014AFB0001043 -:107370000A000A12AFA5003C504000018F9400683B -:1073800027DEFFFF13C00028269400048E92000021 -:107390003C03080024635DA01240FFF70283102B1A -:1073A0003C04080024845AA4028410230002A8C0CC -:1073B000000098210A000A212411000100118840D0 -:1073C000122000260000000002B380210251282470 -:1073D0000200202110A0FFF9267300010E0009DE33 -:1073E000000000000016684032EC000101AC2021D2 -:1073F0000E0009D5020028218F89009426F700018C -:107400008FA6003C3AEB0001316A00012528FFFFFE -:107410000011382702CAB021AF88009416E6FFE7B2 -:1074200002479024AE92000002E010218FBF00348A -:107430008FBE00308FB7002C8FB600288FB5002488 -:107440008FB400208FB3001C8FB200188FB10014CE -:107450008FB0001003E0000827BD00383C0E080084 -:1074600025CE5DA0028E102B0A000A0DAE92000000 -:1074700027BDFFD8AFB10014AFB00010AFBF0020E0 -:10748000AFB3001CAFB2001800A0882110A0001FED -:10749000000480403C13080026735AA40A000A5ACC -:1074A0002412000112200019261000010E0009F517 -:1074B00002002021000231422444FFA0000618806F -:1074C0003045001F2C8217A1007318212631FFFFC1 -:1074D0001040FFF400B230048C690000020020214B -:1074E00024053FFF012640241500FFEE0126382524 -:1074F0000E0009D5AC6700008F8A009426100001A9 -:10750000254700011620FFE9AF8700948FBF0020B8 -:107510008FB3001C8FB200188FB100148FB0001011 -:1075200003E0000827BD00288F85009C00805821BB -:107530000000402100004821240A001F3C0C0800E4 -:10754000258C5E1C3C0D080025AD5DA48CA60000BA -:1075500050C000140000402100AD1023000238C0CC -:10756000240300010A000A930000202115000003F3 -:1075700000E410212448202400004821252900018E -:10758000512B00132506DFDC106000062484000167 -:1075900000C3702415C0FFF5000318400A000A91CB -:1075A0000000402110AC002624A300040060282124 -:1075B000254AFFFF1540FFE5AF85009C512B0004D5 -:1075C0002506DFDC0000402103E000080100102157 -:1075D0000006614230C5001F000C50803C070800C7 -:1075E00024E75DA424040001014730211120000F8D -:1075F00000A420043C05080024A55E20148000059A -:107600002529FFFF24C6000410C50011000000005A -:10761000240400018CCF00000004C0270004204097 -:1076200001F868241520FFF5ACCD00008F99007893 -:1076300001001021032B482303E00008AF890078E4 -:107640003C05080024A55DA40A000A9B0000402117 -:107650003C06080024C65DA40A000AB42404000104 -:10766000308800FF240200021102000A24030003F4 -:107670001103005C8F8900A4240400041104005F3E -:1076800024050005110500670000182103E000082B -:10769000006010218F8900483C0C0800258C5EE0BA -:1076A0003C04080024845F60240300201060000F65 -:1076B00000005821240D0002240E00033C0F080096 -:1076C00025EF5EE08D27000014E0000B30F9FFFF8E -:1076D000252900040124C02B53000001018048210A -:1076E0002463FFFF5460FFF88D270000016018211C -:1076F00003E0000800601021132000323C0500FF69 -:1077000030E200FF004030211040004200005021D4 -:1077100024050001000020210005C84000A6C02467 -:1077200017000003332500FF14A0FFFB2484000191 -:10773000012CC023001828C000AA6021008C502111 -:107740003144001F240C0001008C18040003102792 -:1077500000E23024110D0041AD260000110E004C56 -:10776000000A1840110D00368F87006C510E00562C -:107770008F8C0060240D0004110D005A8F8E008440 -:10778000240E0005150EFFDA01601821240B1430B9 -:1077900011400006000018218F8400A0246300011E -:1077A000006A402B1500FFFD016458218F8A00807C -:1077B000AF89008C016018212549FFFF0A000AEB00 -:1077C000AF89008000E52024000736021080FFD03A -:1077D000240A001800075402314600FF0A000AF389 -:1077E000240A00103C0C0800258C5EA03C04080014 -:1077F00024845EE00A000ADA240300103C0C08002E -:10780000258C5E203C04080024845EA00A000AD96E -:107810008F89009000071A02306600FF0A000AF301 -:10782000240A00088F89008C3C0C0800258C5F60BE -:107830003C04080024845F700A000ADA2403000470 -:10784000000A4080250B003024E6FFFF016018216C -:10785000AF8900480A000AEBAF86006C000AC982B3 -:10786000001978803C07080024E75EA001E720218A -:10787000000A18428C8F00003079001F032C380456 -:107880000007C02701F860240A000B08AC8C000038 -:10789000000331420006288000AF28213062001F1B -:1078A0008CB8000024630001004CC804000321428E -:1078B000001938270004108003073024004F2021CE -:1078C0000A000B4CACA60000000A68C025AB0032D1 -:1078D000258AFFFF01601821AF8900A40A000AEB86 -:1078E000AF8A0060254B1030AF89009001601821ED -:1078F00025C9FFFF0A000AEBAF8900843086000724 -:107900002CC2000610400014000000000006408059 -:107910003C030800246357BC010338218CE40000B9 -:1079200000800008000000002409000310A9000ED8 -:1079300000000000240A000510AA000B000000004F -:10794000240B000110AB0008000000008F8C00A089 -:1079500010AC00050000000003E00008000010214A -:107960000A000A7900A020210A000AC700C02021CD -:1079700027BDFFE8308400FF240300021083000BC2 -:10798000AFBF0010240600031086003A240800044C -:1079900010880068240E0005108E007F2CAF143074 -:1079A0008FBF001003E0000827BD00182CA2003094 -:1079B0001440FFFC8FBF001024A5FFD0000531C28A -:1079C000000668803C07080024E75EE001A730213C -:1079D0008CC900000005288230AC001F240B000178 -:1079E000018B50048F840048012A4025ACC8000058 -:1079F0008C83000050600001AF8600488F98006CB7 -:107A000030AE000124A6FFFF270F000115C00002C1 -:107A1000AF8F006C24A600010006414200082080C0 -:107A2000008718218C79000030C2001F2406000155 -:107A30000046F804033F382410E0FFDA8FBF00103F -:107A40000005C182001870803C0F080025EF5EA081 -:107A500001CF48218D2B00000005684231A5001F91 -:107A600000A66004016C502527BD001803E0000843 -:107A7000AD2A00002CA7003014E0FFCA8FBF001011 -:107A800030B900071723FFC724A8FFCE00086A02F9 -:107A9000000D60803C0B0800256B5EA0018B30213F -:107AA0008CC40000000828C230AA001F240800016E -:107AB000014848048F8200A400891825ACC3000047 -:107AC0008C5F000053E00001AF8600A40005704009 -:107AD000000E7942000F28803C04080024845EE0F8 -:107AE00000A418218C6B000025DF000131CD001FA0 -:107AF000001F514201A86004016C4825000A108053 -:107B0000AC690000004428218CA600008F9800601A -:107B100033F9001F8FBF00100328380400C77825F1 -:107B2000270E000127BD0018ACAF000003E00008DD -:107B3000AF8E006024A5EFD02CB804001300FF998D -:107B40008FBF001000053142000658803C0A080033 -:107B5000254A5E20016A30218CC4000030A3001F3A -:107B600024090001006910048F9900900082F82513 -:107B7000ACDF00008F27000050E00001AF860090CE -:107B80008F8D00848FBF001027BD001825AC000129 -:107B900003E00008AF8C008415E0FF828FBF001067 -:107BA0008F8600A0000610400046F821001F21002B -:107BB00003E4C8210019384024F8143000B8402BE1 -:107BC0001100FF788FBF001024A4EBD00E00021329 -:107BD00000C0282100027942000F70803C0D08008F -:107BE00025AD5F6001CD20218C8B0000304C001F43 -:107BF00024060001018618048F89008C016350253A -:107C0000AC8A00008D25000050A00001AF84008CDC -:107C10008F9800808FBF001027BD00182708000133 -:107C200003E00008AF88008030A5000724030003AC -:107C300010A3001028A2000414400008240700022A -:107C40002403000410A300152408000510A8000F49 -:107C50008F8500A003E000080000000014A7FFFDCE -:107C60000080282114C3FFFB240400020A000B8BB0 -:107C700000000000240900050080282110C9FFFB36 -:107C80002404000303E000080000000014C5FFF115 -:107C9000008028210A000B8B24040005240A00011F -:107CA0000080282110CAFFF12404000403E000082A -:107CB0000000000027BDFFE0AFB00010000581C24A -:107CC0002603FFD024C5003F2C6223D024C6007FAA -:107CD000AFB20018AFB10014AFBF001C309100FF6D -:107CE000000691C2000529820200202110400008F0 -:107CF0002403FFFF0E000A4B0000000002002021B9 -:107D0000022028210E000C390240302100001821E9 -:107D10008FBF001C8FB200188FB100148FB00010FD -:107D20000060102103E0000827BD002027BDFFD818 -:107D300024A2007FAFB3001CAFB20018000299C2AA -:107D4000309200FF24A3003F02402021026028213E -:107D5000AFB10014AFB00010AFBF00200E000B6E2B -:107D60000003898200408021004020210220282138 -:107D700014400009000018218FBF00208FB3001CA1 -:107D80008FB200188FB100148FB000100060102166 -:107D900003E0000827BD00280E0009FC00000000D9 -:107DA00000402821020020211051FFF3001019C0CB -:107DB0000E000A4B00000000020020210240282192 -:107DC0000E000C39026030218FBF00208FB3001CE1 -:107DD0008FB200188FB100148FB00010000018216E -:107DE0000060102103E0000827BD00283084FFFF59 -:107DF00030A5FFFF1080000700001821308200012D -:107E00001040000200042042006518211480FFFB8E -:107E10000005284003E000080060102110C00007A2 -:107E2000000000008CA2000024C6FFFF24A500046F -:107E3000AC82000014C0FFFB2484000403E00008AF -:107E40000000000010A0000824A3FFFFAC86000083 -:107E500000000000000000002402FFFF2463FFFF79 -:107E60001462FFFA2484000403E00008000000000C -:107E700030A5FFFF8F4201B80440FFFE3C076015AC -:107E800000A730253C031000AF440180AF400184BF -:107E9000AF46018803E00008AF4301B88F8500D0EA -:107EA0002C864000008018218CA700840087102BAE -:107EB00014400010000000008CA800842D06400033 -:107EC00050C0000F240340008CAA0084008A482B75 -:107ED000512000018CA3008400035A42000B208033 -:107EE0003C05080024A558200085182103E000085F -:107EF0008C62000014C0FFF4000000002403400066 -:107F000000035A42000B20803C05080024A558209D -:107F10000085182103E000088C6200008F8300D0E8 -:107F2000906600D024C50001A06500D08F8500D0E8 -:107F3000906400D090A200D210440017000000000E -:107F4000936C00788F8B00BC318A00FFA16A000C13 -:107F500025490001938700C4312200FF3048007F8B -:107F60001107000B00026827A36200788F4E01788A -:107F700005C0FFFE8F9900B0241800023C0F1000CE -:107F8000AF590140A358014403E00008AF4F017806 -:107F90000A000D0931A20080A0A000D00A000CFF49 -:107FA000000000008F8700D027BDFFC8AFBF0030A2 -:107FB000AFB7002CAFB60028AFB50024AFB4002097 -:107FC000AFB3001CAFB20018AFB10014AFB00010D7 -:107FD00094E300E094E200E2104300D72405FFFFA1 -:107FE0003C047FFF3497FFFF2415FF800A000DF04B -:107FF0003C16000E108A00D18FBF00308F9100B068 -:108000003C1808008F18005C001230C0001291402C -:108010000311702101D57824AF4F002C94EC00E2BD -:1080200031CD007F01BA5821318A7FFF0176482186 -:10803000000A804002091021945300003C08080007 -:108040008D0800580246C02132733FFF001319808B -:10805000010320210224282130BF007F03FAC82118 -:1080600000B5A024AF54002C0336A0218E87001049 -:108070008E8F003003785821256D008800EF702323 -:10808000240C0002AE8E0010AF8D00ACA16C0088F5 -:10809000976A003C8E8400308F9100AC0E000CD6A5 -:1080A0003150FFFF00024B80020940253C02420094 -:1080B00001022025AE2400048E8300048F8D00ACC5 -:1080C0008E860000240E0008ADA3001CADA600188B -:1080D000ADA0000CADA00010929F000A33F900FF84 -:1080E000A5B90014968500083C1F000CA5A5001634 -:1080F0009298000A331100FFA5B100209690000865 -:1081000024180005A5B00022ADA00024928F000B1A -:108110002410C00031E700FFA5A70002A1AE0001B6 -:108120008E8C00308F8B00AC8F8400B0AD6C00085B -:108130003C0A08008D4A005401444821013540247E -:10814000AF4800283C0208008C4200540044302113 -:1081500030C3007F007AC821033F282102458821CF -:10816000AF9100BCAF8500C0A23800008F8A00BC70 -:108170002403FFBF2418FFDF954F000201F03824CD -:1081800000F37025A54E0002914D000231AC003F76 -:10819000358B0040A14B00028F8600BC8F8900D038 -:1081A000ACC000048D28007C3C098000ACC80008ED -:1081B00090C4000D3082007FA0C2000D8F8500BCEE -:1081C00090BF000D03E3C824A0B9000D8F9100BC3F -:1081D0009233000D02789024A232000D8E9000346C -:1081E0008F8B00BCAD7000108E87002C8E8F0030FE -:1081F00000EF7023AD6E0014916D001831AC007F5C -:10820000A16C00188F9F00BC8E8A00308FE8001888 -:10821000015720240109302400C41025AFE20018C2 -:108220009283000AA3E3001C969900088F8500BC86 -:108230008F9800D0A4B9001E8E9000308E8400303C -:108240000E0002138F0500848F8500D0000291403C -:108250000002990090AF00BC0253882100403021F9 -:1082600031E7000210E0000302118021000290803B -:108270000212802190B900BC3327000410E00002F4 -:108280000006F880021F80218E9800308F8B00BC82 -:1082900024068000330F0003000F702331CD00034C -:1082A000020D6021AD6C000494A400E294AA00E2E7 -:1082B00094B000E231497FFF2522000130537FFF57 -:1082C0000206182400734025A4A800E294A400E24A -:1082D0003C1408008E94006030917FFF123400221D -:1082E000000000000E000CF6000000008F8700D098 -:1082F0000000282194F300E094F000E21213000F34 -:108300008FBF003090E900D090E800D1313200FFFB -:10831000310400FF0244302B14C0FF36264A00010E -:1083200090EE00D2264B000131CD00FF008D602180 -:10833000158BFF338F9100B08FBF00308FB7002CAB -:108340008FB600288FB500248FB400208FB3001C97 -:108350008FB200188FB100148FB0001000A0102150 -:1083600003E0000827BD003894A300E20066402423 -:10837000A4A800E290A400E290B900E2309100FFCE -:108380000011A1C20014F827001F39C03332007F4A -:10839000024730250A000DE8A0A600E23084FFFF66 -:1083A00030A5FFFFAF440018AF45001C03E00008F4 -:1083B0008F42001427BDFFB8AFB000208F9000D0CF -:1083C0003084FFFFAFA40010AFBF0044AFBE004039 -:1083D000AFB7003CAFB60038AFB50034AFB4003033 -:1083E000AFB3002CAFB20028AFB10024A7A0001893 -:1083F000920600D1920500D030C400FF30A300FFE8 -:108400000064102B10400122AFA00014920900D08C -:108410008FB50010312800FF0088382324F4FFFFB7 -:108420000014882B0015982B02339024524001260B -:108430008FB40014961E0012961F00108FB7001004 -:1084400003DFC823001714000019C400000224032E -:108450000018140302E2B02A52C00001004020219B -:108460000284282B10A0000200801821028018210D -:1084700000033C0000071C033064FFFF2C8600094A -:1084800014C000020060B821241700088E0A0008FA -:10849000001769808E09000C31ABFFFF3C0C001007 -:1084A000016C402527520400AF4A0038AF9200B853 -:1084B000AF49003CAF480030000000000000000061 -:1084C00000000000000000000000000000000000AC -:1084D00000000000000000008F4F000031EE00207F -:1084E00011C0FFFD0017982A027110240A000E83A4 -:1084F0000000B02155E001019258000131130080C5 -:10850000126001CF012020219655001232A5FFFFF5 -:108510000E000CCBA7B500188F9000D00291A023BD -:1085200026CD00018F9100B8000DB4000016B403F1 -:108530002638004002D7582A0014882B2405000151 -:108540000300902101711024AF9800B8AFA500146A -:10855000104001BC8F8900B03C0C08008D8C005489 -:10856000240BFF80921E00D001895021014B28244A -:10857000921900D0AF4500288E4700103C08080033 -:108580008D0800583C1808008F18005430E33FFF56 -:108590000003218001043021012658212402FF809C -:1085A0000162F824920C00D0AF5F002C92480000CA -:1085B00033D100FF333500FF0309982100117140CA -:1085C000001578C0326D007F01CF382101BA282113 -:1085D000318300FF3164007F3C0A000C00AA88212F -:1085E0000367F02100033140009A10213108003F59 -:1085F0003C1F000E00D1C021005F982127D90088C0 -:108600002D150008AF9100C0AF9900ACAF9800BC29 -:10861000AF9300B412A0018A00008821240E00014B -:10862000010E4004310D005D11A0FFB2310F0002B8 -:108630008E4A00283C0300803C04FFEFAE6A000035 -:108640008E450024A260000A3488FFFFAE65000456 -:108650009247002C3C1FFF9F37FEFFFFA267000CD4 -:108660008E62000C3C180040A267000B00433025CE -:1086700000C8C824033E88240238A825AE75000C23 -:108680008E490004AE6000183C0F00FFAE69001474 -:108690008E4D002C35EEFFFF8F8B00B001AE6024B5 -:1086A000AE6C00108E470008A660000896450012C8 -:1086B000AE6700208E42000C30B03FFF00105180AA -:1086C000AE6200248E5E0014014B182130A400011C -:1086D000AE7E00288E590018000331C2000443808A -:1086E000AE79002C8E51001C00C8F821A67F001C1A -:1086F000AE710030965800028E550020A678001EFC -:10870000AE75003492490033313000045600000544 -:10871000925000008F8C00D08D8B007CAE6B0030AF -:10872000925000008F8F00BCA1F00000924E0033E9 -:1087300031CD000251A00007925E00018F8900BC7C -:108740002418FF80913100000311A825A1350000F5 -:10875000925E00018F9900BC2409FFBF240BFFDF4C -:10876000A33E00018F9500BC92B8000D3311007F2D -:10877000A2B1000D8F8E00BC91D0000D02097824AB -:10878000A1CF000D8F8800BC8E6D0014910A000DE2 -:108790002DAC0001000C2940014B382400E51825C0 -:1087A000A103000D964200128F8800BC8F8700D075 -:1087B000A50200028E45000490FF00BC30A4000317 -:1087C0000004302330DE000300BE102133F9000224 -:1087D00017200002244400342444003090E200BCFE -:1087E00000A2302430DF000417E0000224830004DC -:1087F000008018218F8F00AC24090002AD03000413 -:10880000A1E90000924E003F8F8D00ACA1AE0001A7 -:108810008F9500AC924C003F8E440004A6AC000241 -:10882000976B003C0E000CD63170FFFF00025380A6 -:10883000020A38253C05420000E51825AEA30004D5 -:108840008F8600AC8E480038ACC800188E440034C7 -:10885000ACC4001CACC0000CACC00010A4C0001420 -:10886000A4C00016A4C00020A4C00022ACC00024F4 -:108870008E6400145080000124040001ACC4000880 -:108880000E000CF6241100010A000E768F9000D025 -:10889000920F00D2920E00D08FB5001031EB00FF86 -:1088A00031CD00FF008D6023016C50212554FFFF66 -:1088B0000014882B0015982B023390241640FEDDFF -:1088C000000000008FB400148FBF00448FBE004032 -:1088D0003A8200018FB7003C8FB600388FB5003464 -:1088E0008FB400308FB3002C8FB200288FB10024DA -:1088F0008FB0002003E0000827BD0048331100209E -:10890000122000EF24150001921E00BC241F00015C -:108910000000A82133D900011320000DAFBF001CB7 -:108920008E4400148E0800840088102B144000022E -:10893000008030218E0600848E03006400C3A82BC3 -:1089400016A0000200C020218E0400640080A8212F -:108950008E4700148E05006400E5302B14C0000221 -:1089600000E020218E0400640095F02313C0000471 -:108970008FAC001C240A0002AFAA001C8FAC001CA4 -:10898000028C582B156000A8000018218E4F00386B -:108990008E6D000C3C0E0080AE6F00008E4A0034DD -:1089A0003C10FF9F01AE5825AE6A00049246003F7E -:1089B000360CFFFF016C38243C0500203C03FFEF20 -:1089C000A266000B00E510253468FFFF8F8700B812 -:1089D0000048F8243C04000803E4C825AE79000CE4 -:1089E0008CF80014AE60001802BE7821AE78001436 -:1089F0008CF10018AE71001C8CE90008AE690024EF -:108A00008CEE000CAE6F002CAE600028AE6E002025 -:108A1000A6600038A660003A8CED001401B58023F2 -:108A2000021E902312400011AE72001090EA003D29 -:108A30008E6500048E640000000A310000A6C82183 -:108A4000000010210326402B0082F82103E8C021FA -:108A5000AE790004AE78000090F1003DA271000AEA -:108A60008F8900B895320006A67200088F9800AC76 -:108A70002419000202A02021A31900009769003CDC -:108A80008F9200AC0E000CD63131FFFF00027B80CC -:108A90008F8500B8022F68253C0E420001AE80256C -:108AA000AE5000048F8400AC8CAC0038AC8C001845 -:108AB0008CAB0034AC8B001CAC80000CAC80001084 -:108AC000A4800014A4800016A4800020A4800022AA -:108AD000AC80002490A7003FA487000212A00135BB -:108AE0002403000153C0000290A2003D90A2003E6A -:108AF00024480001A08800018F9F00ACAFF500085A -:108B00008F8300D024070034906600BC30C500027B -:108B100050A00001240700308F9200B88F8A00BC5B -:108B2000906D00BC924B00002412C00032A50003DF -:108B3000A14B00008F8600B88F8800BC240200047F -:108B400090C400010045182330790003A1040001FE -:108B50008F8A00BC8F9F00B800F53821955800021D -:108B600097E9001200F9382103128824312F3FFFC2 -:108B7000022F7025A54E00029150000231A800047A -:108B8000320C003F358B0040A14B000212A00002C6 -:108B90008F8500BC00E838218F8E00D0ACA7000480 -:108BA000240BFFBF8DCD007C2EA400012403FFDF2A -:108BB000ACAD000890B0000D00044140320C007FC5 -:108BC000A0AC000D8F8600BC90CA000D014B102494 -:108BD000A0C2000D8F8700BC90E5000D00A3F82413 -:108BE00003E8C825A0F9000D8F9100B88F8D00BC57 -:108BF0008E380020ADB800108E290024ADA90014D5 -:108C00008E2F0028ADAF00188E2E002C0E000CF613 -:108C1000ADAE001C8FB0001C240C0002120C00EE44 -:108C20008F9000D08FA3001C006088211460000288 -:108C30000060A8210000A02156A0FE390291A023C7 -:108C40000014882B8FA90010960700103C1E0020EE -:108C50000136402302C750213112FFFFA60A00103F -:108C6000AFB20010AF5E0030000000009617001099 -:108C7000961300121277008F000000008E05000C82 -:108C80008E0B00080016698000AD7021000DC7C36F -:108C900001CDA82B0178782101F56021AE0E000CE2 -:108CA000AE0C00088FB300100013B82B02378024DD -:108CB0001200FF048F9000D00A000E3C000000005C -:108CC0008E4D0038A6600008240B0003AE6D000036 -:108CD0008E500034A260000A8F9800B8AE70000475 -:108CE0003C0500809311003FA26B000C8E6F000CBE -:108CF0003C0EFF9FA271000B01E5102535CCFFFF54 -:108D00003C03FFEF8F9200B8004C30243464FFFF27 -:108D100000C4F824AE7F000C8E590014964800124F -:108D20008F8A00B0AE7900108E490014AE60001832 -:108D3000AE600020AE690014AE6000248E470018BB -:108D400031093FFF0009F180AE6700288E4D000811 -:108D500003CA802131180001AE6D00308E4F000C27 -:108D60008F8C00AC001089C200185B80022B282178 -:108D7000240E0002A665001CA6600036AE6F002C13 -:108D8000A18E00009763003C8F8A00AC3C04420037 -:108D90003062FFFF00443025AD4600048F9F00B8CD -:108DA000240700012411C0008FF30038240600348A -:108DB000AD5300188FF90034AD59001CAD40000CC4 -:108DC000AD400010A5400014A5400016A5400020AD -:108DD000A5400022AD400024A5550002A147000196 -:108DE0008F9E00AC8F8800B88F9200BCAFD5000872 -:108DF000910D0000A24D00008F9000B88F8B00BC39 -:108E000092180001A17800018F8400BC94850002B3 -:108E100000B1782401E97025A48E0002908C000234 -:108E20003183003FA08300028F8300D08F8400BC79 -:108E3000906200BC305300025260000124060030F2 -:108E4000AC8600048C6F007C2403FFBF02A0882145 -:108E5000AC8F0008908E000D31CC007FA08C000DEF -:108E60008F8600BC90C2000D00432024A0C4000DDA -:108E70008F8900BC913F000D37F90020A139000D0A -:108E80008F8800B88F9300BC8D070020AE6700105C -:108E90008D0A0024AE6A00148D1E0028AE7E0018D4 -:108EA0008D12002C0E000CF6AE72001C0A00103D54 -:108EB0008F9000D0960E00148E03000431CCFFFF7B -:108EC000000C10C000622021AF44003C8E1F000443 -:108ED0008F46003C03E6C8231B20003C0000000036 -:108EE0008E0F000025E200013C05001034B500089B -:108EF000AF420038AF550030000000000000000015 -:108F00000000000000000000000000000000000061 -:108F100000000000000000008F580000330B00200C -:108F20001160FFFD000000008F5304003C0D002085 -:108F3000AE1300088F570404AE17000CAF4D00307D -:108F4000000000003C0608008CC600442416000106 -:108F500010D600BD00000000961F00123C0508005E -:108F60008CA5004000BFC821A61900129609001464 -:108F700025270001A6070014960A00143144FFFFBC -:108F80005486FF498FB30010A60000140E000E1681 -:108F900030A5FFFF3C0408008C84002496030012D7 -:108FA0000044102300623023A60600120A00105964 -:108FB0008FB30010A08300018F8200AC2404000155 -:108FC000AC4400080A000FF08F8300D08E0200002E -:108FD0000A0010EA3C0500108F8200C08FA7001C19 -:108FE000921800D0920B00D0920E00D0331100FFE7 -:108FF000316900FF00117940000928C001E56021B6 -:1090000031C300FF036C50210003314000C2C8216E -:10901000255F0088AF9F00ACAF9900BCA1470088D6 -:109020009768003C03C020218F9100AC0E000CD645 -:109030003110FFFF00026B80020DC0253C0442008E -:109040008F8D00B803045825AE2B00048DA900387D -:109050008F8B00AC0000882100118100AD690018E1 -:109060008DAF00343C087FFF3504FFFFAD6F001C5F -:1090700091AC003E8D65001C8D660018000C190037 -:10908000000C770200A33821020E102500E3F82B14 -:1090900000C2C821033F5021AD67001CAD6A001813 -:1090A000AD60000CAD60001091B8003E24050005D5 -:1090B00003C45024A578001495A9000403C02021FE -:1090C000A569001691AF003EA56F002095B1000480 -:1090D000A5710022AD60002491AE003FA56E000294 -:1090E00091B0003E91AC003D01901023244300015B -:1090F000A16300018F8600AC8F9F00BCACDE00082E -:10910000A3E500008F9000BC8F9900B82405FFBF35 -:1091100096070002973800120247782433093FFF70 -:1091200001E98825A6110002921200022418FFDF2F -:10913000324E003F35CD0040A20D00028F8600BCAC -:109140008F8C00D02412FFFFACC000048D8B007CFC -:109150003C0C8000ACCB000890C2000D3043007F77 -:10916000A0C3000D8F8700BC90FF000D03E5C8244D -:10917000A0F9000D8F9100BC9229000D01387824D0 -:10918000A22F000D8F9000BCAE120010AE1500147F -:10919000920E00182415FF8002AE6825A20D00185B -:1091A0008F8500BC8F8300B88CAB0018016C102435 -:1091B000004A3025ACA600189068003EA0A8001C0C -:1091C0008F9F00B88F8700BC8F9800D097F900045C -:1091D000A4F9001E0E0002138F0500848F8600D0B4 -:1091E000000279400002490090D200BC01E98821C8 -:1091F000004028213255000212A0000303D1202193 -:109200000002A8800095202190CD00BC31B200045E -:109210001240000333DF0003000540800088202156 -:10922000240600048F9E00BC00DFC8233327000300 -:1092300000875021AFCA00040E000CF6A665003866 -:109240000A0010388F9000D0961E00123C080800CB -:109250008D080024011E9021A61200120A00105948 -:109260008FB3001027BDFFE03C1808008F18005096 -:10927000AFB00010AFBF0018AFB10014AF8400B0A2 -:1092800093710074030478212410FF8031EE007F75 -:109290003225007F01F0582401DA68213C0C000AD5 -:1092A000A38500C401AC2821AF4B002494A9001071 -:1092B0009768000690A600620080382124020030E2 -:1092C0000109202330C300F0AF8500D010620019DF -:1092D0003090FFFF90AE0062240DFFF0240A005092 -:1092E00001AE6024318B00FF116A002F00000000E6 -:1092F00016000007241F0C00AF5F00248FB100147C -:109300008FBF00188FB0001003E0000827BD0020B9 -:109310000E000E1C02002021241F0C00AF5F002451 -:109320008FB100148FBF00188FB0001003E0000849 -:1093300027BD002094A200E094A400E290BF011396 -:10934000008218263079FFFF33E700C014E00009DF -:109350002F31000116000038000000005620FFE603 -:10936000241F0C000E000D18000000000A0011ED73 -:10937000241F0C001620FFDE000000000E000D1858 -:10938000000000001440FFDC241F0C001600002227 -:109390008F8300D0906901133122003FA062011336 -:1093A0000A0011ED241F0C0094AF00D48F8600D466 -:1093B00000E02821240400050E000C5C31F0FFFFC2 -:1093C0001440000524030003979100E600001821D3 -:1093D0002625FFFFA78500E68F5801B80700FFFE8E -:1093E0003C196013AF400180241F0C00AF50018472 -:1093F000007938253C101000AF4701888FB1001468 -:10940000AF5001B8AF5F00248FB000108FBF0018BD -:1094100003E0000827BD00200E000E1C02002021E2 -:109420005040FFB5241F0C008F8300D090690113BA -:109430000A0012163122003F0E000E1C02002021ED -:109440001440FFAD241F0C00122000078F8300D0B2 -:10945000906801133106003F34C20040A06201133E -:109460000A0011ED241F0C000E000D180000000072 -:109470005040FFA1241F0C008F8300D0906801137F -:109480003106003F0A00124634C20040AF9B00C8BC -:1094900003E00008AF8000EC3089FFFF0009404284 -:1094A0002D020041000921801440000200095040B3 -:1094B00024080040000830C0000811400046582130 -:1094C000256701A800E2C821272F007F2418FF800C -:1094D00001F818240064302100CA702125CC00FF57 -:1094E000240DFF00018D202425650088240A0088B2 -:1094F0003C010800AC2A004C3C010800AC2500509F -:10950000AF8400D43C010800AC2900603C01080095 -:10951000AC2800643C010800AC2700543C01080062 -:10952000AC2300583C010800AC26005C03E00008B6 -:1095300000000000308300FF30C6FFFF30E400FF72 -:109540008F4201B80440FFFE00034C00012438257F -:109550003C08600000E820253C031000AF45018076 -:10956000AF460184AF44018803E00008AF4301B86F -:109570008F86001C3C096012352700108CCB00043C -:109580003C0C600E35850010316A00062D48000144 -:10959000ACE800C48CC40004ACA431808CC20008C8 -:1095A00094C30002ACA2318403E00008A78300E466 -:1095B0003C0308008C6300508F8400E88F86001CF9 -:1095C0002402FF800064C0210302C824AF59002890 -:1095D0008CCD00043305007F00BA78213C0E000CCE -:1095E00001EE2821ACAD00588CC80008AF8500D032 -:1095F0003C076012ACA8005C8CCC001034E8001072 -:10960000ACAC000C8CCB000CACAB000894AA0014E2 -:109610003C0208008C42004425490001A4A9001422 -:1096200094A400143083FFFF106200178F8400D0D1 -:109630003C0A08008D4A0040A4AA00128CCE0018F3 -:10964000AC8E00248CCD0014AC8D00208CC700188B -:10965000AC87002C8CCC001424060001AC8C0028B4 -:109660008D0B00BC5166001A8D0200B48D0200B84B -:10967000A482003A948F003AA48F003C948800D4CE -:1096800003E000083102FFFF3C0908008D29002497 -:10969000A4A000148F8400D0A4A900128CCE0018BE -:1096A000AC8E00248CCD0014AC8D00208CC700182B -:1096B000AC87002C8CCC001424060001AC8C002854 -:1096C0008D0B00BC5566FFEA8D0200B88D0200B418 -:1096D000A482003A948F003AA48F003C948800D46E -:1096E00003E000083102FFFF8F86001C3C0C0800DD -:1096F0008D8C0050240BFF808CCD00083C03000CA7 -:10970000000D51C0018A4021010B4824AF8A00E8B6 -:10971000AF49002890C700073105007F00BA10212B -:109720000043282130E4000410800039AF8500D0C8 -:1097300090CF000731EE000811C000380000000093 -:109740008CD9000C8CC400140324C02B13000030EF -:10975000000000008CC2000CACA200648CCD00188C -:109760002402FFF8ACAD00688CCC0010ACAC0080DB -:109770008CCB000CACAB00848CCA001CACAA007C67 -:1097800090A900BC01224024A0A800BC90C30007FF -:109790003067000810E000048F8500D090AF00BC57 -:1097A00035EE0001A0AE00BC90D9000733380001AF -:1097B000130000088F8300D08F8700D0240400346A -:1097C00090E800BC35030002A0E300BC8F8300D00A -:1097D000AC6400C090C900073126000210C000052B -:1097E00000000000906A00BC35420004A06200BC8A -:1097F0008F8300D09065011330AD003FA06D011341 -:109800008F8C00D0958B00D403E000083162FFFFFD -:109810008CC200140A001305000000000A001306A1 -:10982000ACA0006427BDFFD8AFB000108F90001C23 -:10983000AFBF0024AFB40020AFB20018AFB1001426 -:10984000AFB3001C9613000E3C07600A3C14600680 -:109850003264FFFF369300100E00125534F40410EA -:109860008F8400D43C11600E0E00099B363100102D -:10987000920E00153C0708008CE700603C12601255 -:1098800031CD000FA38D00F08E0E00048E0D000868 -:1098900096080012961F00109619001A9618001EBE -:1098A000960F001C310CFFFF33EBFFFF332AFFFF45 -:1098B0003309FFFF31E6FFFF3C010800AC2B0040FD -:1098C0003C010800AC2C00243C010800AC2A0044F8 -:1098D000AE293178AE26317C92020015960300162F -:1098E00036520010304400FF3065FFFF3C06080090 -:1098F0008CC60064AE243188AE4500B492080014D2 -:1099000096190018241F0001011FC004332FFFFF08 -:109910003C0508008CA50058AE5800B8AE4F00BCFE -:10992000920C0014AF8E00D8AF8D00DC318B00FF9D -:10993000AE4B00C0920A0015AE670048AE66004C00 -:10994000314900FFAE4900C8AE65007C3C03080009 -:109950008C6300503C0408008C84004C3C080800D8 -:109960008D0800543C0208008C42005C8FBF00242C -:10997000AE6300808FB00010AE8300748FB3001C04 -:10998000AE22319CAE4200DCAE2731A0AE2631A41F -:10999000AE24318CAE233190AE283194AE2531986F -:1099A000AE870050AE860054AE8500708FB10014B3 -:1099B000AE4700E0AE4600E4AE4400CCAE4300D07B -:1099C000AE4800D4AE4500D88FB400208FB2001846 -:1099D00003E0000827BD002827BDFFE0AFB1001459 -:1099E000AFBF0018241100010E000845AFB00010F1 -:1099F00010510005978400E6978300CC0083102B5C -:109A0000144000088F8500D4240700028FBF00187F -:109A10008FB100148FB0001000E0102103E00008A7 -:109A200027BD00200E000C7A24040005AF8200E858 -:109A30001040FFF6240700020E0008498F90001C1A -:109A4000979F00E68F9900E88F8D00C827EF0001EF -:109A5000240E0050AF590020A78F00E6A1AE0000F1 -:109A60003C0C08008D8C00648F8600C8240A80009E -:109A7000000C5E00ACCB0074A4C0000694C9000AC0 -:109A8000241FFF803C0D000C012AC024A4D8000A2A -:109A900090C8000A24182000011F1825A0C3000A3E -:109AA0008F8700C8A0E000788F8500C800003821AB -:109AB000A0A000833C0208008C4200508F8400E884 -:109AC0000044782101FFC824AF590028960B0002FA -:109AD00031EE007F01DA6021018D3021A4CB00D46A -:109AE000960A0002AF8600D03C0E000425492401EE -:109AF000A4C900E68E080004ACC800048E03000868 -:109B0000ACC30000A4C00010A4C00014A0C000D0CA -:109B10008F8500D02403FFBFA0A000D13C04080023 -:109B20008C8400648F8200D0A04400D28E1F000C71 -:109B30008F8A00D0978F00E4AD5F001C8E19001053 -:109B400024100030AD590018A5400030A551005434 -:109B5000A5510056A54F0016AD4E0068AD580080C7 -:109B6000AD580084914D006231AC000F358B001070 -:109B7000A14B00628F8600D090C900633128007F1E -:109B8000A0C800638F8400D02406FFFF9085006387 -:109B900000A31024A08200638F9100D000E0102168 -:109BA000923F00BC37F90001A23900BC8F8A00D077 -:109BB000938F00F0AD580064AD5000C0914E00D3BB -:109BC000000F690031CC000F018D5825A14B00D347 -:109BD0008F8500D08F8900DCACA900E88F8800D881 -:109BE0008FBF00188FB100148FB0001027BD002068 -:109BF000ACA800ECA4A600D6A4A000E0A4A000E2BB -:109C000003E000080000000027BDFFE0AFB0001037 -:109C10008F90001CAFB10014AFBF00188E19000464 -:109C20003C1808008F180050240FFF80001989C0CD -:109C30000238702131CD007F01CF602401BA50215C -:109C40003C0B000CAF4C0028014B4021950900D47F -:109C5000950400D68E0700043131FFFFAF8800D095 -:109C60000E000913000721C08E0600048F8300C870 -:109C7000000629C0AF4500209064003E30820040BD -:109C8000144000068F8400D0341FFFFF948300D659 -:109C90003062FFFF145F000400000000948400D6CF -:109CA0000E0008A83084FFFF8E050004022030213A -:109CB0008FBF00188FB100148FB000102404002251 -:109CC00000003821000529C00A00127C27BD0020B1 -:109CD00027BDFFE0AFB100143091FFFFAFB000101F -:109CE000AFBF00181220001D000080218F86001CCD -:109CF0008CC500002403000600053F020005140285 -:109D000030E4000714830015304500FF2CA800063E -:109D10001100004D000558803C0C0800258C57D4DC -:109D2000016C50218D490000012000080000000056 -:109D30008F8E00EC240D000111CD005900000000B1 -:109D4000260B00013170FFFF24CA00200211202BD6 -:109D5000014030211480FFE6AF8A001C0200102170 -:109D60008FBF00188FB100148FB0001003E00008FF -:109D700027BD0020938700CE14E00038240400148F -:109D80000E001338000000008F86001C2402000122 -:109D90000A00147FAF8200EC8F8900EC24080002D7 -:109DA0001128003B2404001300002821000030216A -:109DB000240700010E00127C000000000A00147F3E -:109DC0008F86001C8F8700EC2405000214E5FFF647 -:109DD000240400120E0012E9000000008F8500E844 -:109DE00000403021240400120E00127C00003821B3 -:109DF0000A00147F8F86001C8F8300EC241F000351 -:109E0000147FFFD0260B00010E00129B0000000003 -:109E10008F8500E800403021240200022404001055 -:109E200000003821AF8200EC0E00127C0000000020 -:109E30000A00147F8F86001C8F8F00EC240600021E -:109E400011E6000B0000000024040010000028218F -:109E5000000030210A00149C240700010000282182 -:109E60000E00127C000030210A00147F8F86001C37 -:109E70000E0013A500000000144000128F99001C72 -:109E80008F86001C240200030A00147FAF8200ECBE -:109E90000E001431000000000A00147F8F86001CA1 -:109EA0000E00128B000000002402000224040014A3 -:109EB0000000282100003021000038210A0014B9D8 -:109EC000AF8200EC004038212404001097380002D3 -:109ED000000028210E00127C3306FFFF0A00147FC9 -:109EE0008F86001C8F8400C83C077FFF34E6FFFF8D -:109EF0008C8500742402000100A61824AC83007431 -:109F000003E00008A082000510A000362CA200800B -:109F1000274A04003C0B000524090080104000077C -:109F20002408008030A6000F00C540212D030081C9 -:109F30001460000200A0482124080080AF4B0030CC -:109F400000000000000000000000000011000009F7 -:109F500000003821014030218C8D000024E70004EE -:109F600000E8602BACCD0000248400041580FFFACB -:109F700024C60004000000000000000000000000F3 -:109F80003C0E0006010E3825AF47003000000000EF -:109F900000000000000000008F4F000031E80010BA -:109FA0001100FFFD000000008F42003C8F43003C89 -:109FB0000049C8210323C02B130000040000000047 -:109FC0008F4C003825860001AF4600388F47003C93 -:109FD00000A9282300E96821AF4D003C14A0FFCE62 -:109FE0002CA2008003E000080000000027BDFFD085 -:109FF0003C020002AFB100143C11000CAF45003828 -:10A00000AFB3001CAF46003C00809821AF42003047 -:10A0100024050088AF44002803512021AFBF002849 -:10A02000AFB50024AFB40020AFB200180E0014F199 -:10A03000AFB000103C1F08008FFF004C3C18080018 -:10A040008F1800642410FF8003F3A82132B9007F29 -:10A0500002B078240018A0C0033A70210018914083 -:10A0600001D12021AF4F00280E0014F10254282105 -:10A070003C0D08008DAD00502405012001B358218E -:10A08000316C007F01705024019A48210131202158 -:10A090000E0014F1AF4A00283C0808008D08005457 -:10A0A0003C0508008CA500640113382130E6007FD0 -:10A0B00000F0182400DA202100912021AF4300286D -:10A0C0000E0014F1000529403C0208008C420058A3 -:10A0D0003C1008008E1000601200001C0053882104 -:10A0E0002415FF800A0015743C14000C3226007FF2 -:10A0F0000235182400DA202102402821AF4300282D -:10A10000009420210E0014F12610FFC01200000F51 -:10A11000023288212E05004110A0FFF42412100005 -:10A120003226007F001091800235182400DA2021A9 -:10A1300002402821AF430028009420210E0014F192 -:10A14000000080211600FFF3023288213C0B08003A -:10A150008D6B005C240AFF802405000201734021FE -:10A16000010A4824AF4900283C0408009484006296 -:10A170003110007F021A88213C07000C0E000CAA47 -:10A180000227982100402821026020218FBF00284B -:10A190008FB500248FB400208FB3001C8FB200183D -:10A1A0008FB100148FB000100A0014F127BD0030E9 -:10A1B0008F83001C8C62000410400003000000002C -:10A1C00003E00008000000008C6400108C650008AB -:08A1D0000A00152A8C66000C40 -:08A1D800000000000000001B64 -:10A1E0000000000F0000000A000000080000000648 -:10A1F000000000050000000500000004000000044D -:10A200000000000300000003000000030000000342 -:10A210000000000300000002000000020000000235 -:10A220000000000200000002000000020000000226 -:10A230000000000200000002000000020000000216 -:10A240000000000200000002000000020000000206 -:0CA25000000000010000000100000001FF -:04A25C0008000F24C3 -:10A2600008000D6C08000FB80800106008000F4CC3 -:10A2700008000F8C0800119408000D88080011B820 -:10A2800008000DD8080015540800151C08000D889A -:10A2900008000D8808000D880800124008001240D0 -:10A2A00008000D8808000D88080014E008000D88DB -:10A2B00008000D8808000D8808000D88080013B4F8 -:10A2C00008000D8808000D8808000D8808000D881A -:10A2D00008000D8808000D8808000D8808000D880A -:10A2E00008000D8808000D8808000D8808000D88FA -:10A2F00008000D8808000D8808000FAC08000D88C4 -:10A3000008000D880800167808000D8808000D88E0 -:10A3100008000D8808000D8808000D8808000D88C9 -:10A3200008000D8808000D8808000D8808000D88B9 -:10A3300008000D8808000D8808000D8808000D88A9 -:10A3400008000D8808000D8808000D88080014100A -:10A3500008000D8808000D8808001334080012A4B6 -:10A3600008001E2C08001EFC08001F1408001F28EF -:10A3700008001F3808001E2C08001E2C08001E2C88 -:10A3800008001ED808002E1408002E1C08002DE41A -:10A3900008002DF008002DFC08002E08080052F4DB -:10A3A000080052B40800528008005254080052308D -:04A3B000080051EC64 -:0CA3B4000A000C84000000000000000003 -:10A3C0000000000D727870362E322E310000000031 -:10A3D0000602010300000000000000010000000070 -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000008000000000000000000B -:10D5A000000000000000000000000000000000007B -:10D5B00000000000000000000000000A0000000061 -:10D5C0000000000000000000100000030000000048 -:10D5D0000000000D0000000D3C02080024427320F2 -:10D5E0003C030800246377ACAC4000000043202BD0 -:10D5F0001480FFFD244200043C1D080037BD7FFC61 -:10D6000003A0F0213C100800261032103C1C08003A -:10D61000279C73200E0010FE000000000000000D8B -:10D6200030A5FFFF30C600FF274301808F4201B8BD -:10D630000440FFFE24020002AC640000A465000860 -:10D64000A066000AA062000B3C021000AC67001844 -:10D6500003E00008AF4201B83C0360008C624FF861 -:10D660000440FFFE3C020200AC644FC0AC624FC4F9 -:10D670003C02100003E00008AC624FF89482000CFA -:10D680002486001400A0382100021302000210803A -:10D690000082402100C8102B1040005700000000FD -:10D6A00090C300002C6200095040005190C200015C -:10D6B000000310803C030800246372D00043102153 -:10D6C0008C420000004000080000000090C30001F0 -:10D6D0002402000A1462003A000000000106102330 -:10D6E0002C42000A1440003624C600028CE20000DE -:10D6F00034420100ACE2000090C2000090C300017F -:10D7000090C4000290C5000300031C000002160034 -:10D710000043102500042200004410250045102578 -:10D7200024C60004ACE2000490C2000090C30001D3 -:10D7300090C4000290C500030002160000031C0004 -:10D740000043102500042200004410250045102548 -:10D7500024C600040A000CB8ACE2000890C3000123 -:10D76000240200041462001624C6000290C20000C5 -:10D7700090C400018CE30000000212000044102558 -:10D780003463000424C60002ACE2000C0A000CB8AA -:10D79000ACE3000090C300012402000314620008FF -:10D7A00024C600028CE2000090C3000024C60001E1 -:10D7B00034420008A0E300100A000CB8ACE20000FC -:10D7C00003E000082402000190C3000124020002CB -:10D7D0001062000224C40002010020210A000CB8DB -:10D7E000008030210A000CB824C6000190C200015C -:10D7F0000A000CB800C2302103E00008000010212C -:10D8000027BDFFE8AFBF0014AFB000100E00130239 -:10D8100000808021936200052403FFFE0200202186 -:10D82000004310248FBF00148FB00010A3620005C6 -:10D830000A00130B27BD001827BDFFE8AFB000108A -:10D84000AFBF00140E000F3C0080802193620000E7 -:10D8500024030050304200FF14430004240201005E -:10D86000AF4201800A000D3002002021AF4001804C -:10D87000020020218FBF00148FB000100A000FE7B4 -:10D8800027BD001827BDFF80AFBE0078AFB700747A -:10D89000AFB20060AFBF007CAFB60070AFB5006C38 -:10D8A000AFB40068AFB30064AFB1005CAFB0005874 -:10D8B0008F5001283C0208008C4231A02403FF80D5 -:10D8C0009365003F0202102100431024AF42002460 -:10D8D0003C0208008C4231A09364000530B200FF86 -:10D8E000020210213042007F034218210004202749 -:10D8F0003C02000A0062182130840001AF8300144A -:10D900000000F0210000B82114800053AFA00050A7 -:10D9100093430116934401128F450104306300FFC5 -:10D920003C020001308400FF00A2282403431021A0 -:10D9300003441821245640002467400014A001CD60 -:10D940002402000193620000304300FF2402002003 -:10D950001062000524020050106200060000000062 -:10D960000A000D74000000000000000D0A000D7D8B -:10D97000AFA000303C1E080027DE736C0A000D7D4E -:10D98000AFA000303C0208008C4200DC24420001C1 -:10D990003C010800AC2200DC0E00139F00000000D8 -:10D9A0000A000F318FBF007C8F4201043C0300202E -:10D9B00092D3000D004310240002202B00042140CC -:10D9C000AFA400308F4301043C02004000621824E1 -:10D9D000146000023485004000802821326200205B -:10D9E000AFA500301440000234A6008000A0302112 -:10D9F00010C0000BAFA6003093C500088F67004C25 -:10DA00000200202100052B0034A5008130A5F08103 -:10DA10000E000C9B30C600FF0A000F2E0000000015 -:10DA20009362003E304200401040000F2402000488 -:10DA300056420007240200120200202100E02821A3 -:10DA40000E0013F702C030210A000F318FBF007C97 -:10DA500016420005000000000E000D2100002021EC -:10DA60000A000F318FBF007C9743011A96C4000E45 -:10DA700093620035326500043075FFFF00442004D6 -:10DA8000AFA400548ED1000410A000158ED400085D -:10DA90009362003E3042004010400007000000004A -:10DAA0000E0013E0022020211040000D00000000B5 -:10DAB0000A000F2E000000008F6200440222102393 -:10DAC0000440016A000000008F6200480222102317 -:10DAD00004410166240400160A000E218FC20004CE -:10DAE0008F6200480222102304400008000000005A -:10DAF0003C0208008C423100244200013C01080035 -:10DB0000AC2231000A000F23000000008F620040A9 -:10DB100002221023184000128F8400143C020800D7 -:10DB20008C423100327300FC0000A8212442000125 -:10DB30003C010800AC2231008F6300409482011C3C -:10DB4000022318233042FFFF0043102A50400010E8 -:10DB50002402000C8F6200400A000DF20222102302 -:10DB60009483011C9762003C0043102B1040000678 -:10DB7000000000009482011C00551023A482011CA7 -:10DB80000A000DF72402000CA480011C2402000CE2 -:10DB9000AFA200308F620040005120231880000D9A -:10DBA00002A4102A1440012600000000149500066B -:10DBB00002A410233A620001304200011440012007 -:10DBC0000000000002A41023022488210A000E098C -:10DBD0003055FFFF00002021326200021040001A81 -:10DBE000326200109362003E30420040504000110B -:10DBF0008FC200040E00130202002021240200182C -:10DC0000A362003F936200052403FFFE020020216F -:10DC1000004310240E00130BA362000524040039F6 -:10DC2000000028210E0013C9240600180A000F3036 -:10DC300024020001240400170040F809000000003D -:10DC40000A000F302402000110400108000000000B -:10DC50008F63004C8F620054028210231C4001032A -:10DC600002831023044200010060A021AFA4001829 -:10DC7000AFB10010AFB50014934201208F65004092 -:10DC80009763003C304200FF034210210044102102 -:10DC90008FA400543063FFFF244240000083182B00 -:10DCA0008FA40030AFA20020AFA50028008320255C -:10DCB000AFA40030AFA50024AFA0002CAFB4003457 -:10DCC0009362003E30420008504000118FC20000B5 -:10DCD00002C0202127A500380E000CB2AFA00038EA -:10DCE0005440000B8FC200008FA200383042010068 -:10DCF000504000078FC200008FA3003C8F6200607D -:10DD00000062102304430001AF6300608FC2000073 -:10DD10000040F80927A400108FA200303042000212 -:10DD200054400001327300FE9362003E30420040D6 -:10DD3000104000378FA200248F6200541682001A10 -:10DD40003262000124020014124200102A4200151F -:10DD500010400006240200162402000C12420007A4 -:10DD6000326200010A000E7D000000001242000530 -:10DD7000326200010A000E7D000000000A000E78E9 -:10DD80002417000E0A000E78241700100A000E7CDB -:10DD900024170012936200232403FFBD00431024C4 -:10DDA000A362002332620001104000198FA20024F8 -:10DDB0002402000C1242000E2A42000D1040000600 -:10DDC0002402000E2402000A124200078FA200243F -:10DDD0000A000E9524420001124200088FA200247E -:10DDE0000A000E95244200010A000E932417000831 -:10DDF0002402000E16E20002241700162417001059 -:10DE00008FA2002424420001AFA200248FA200248C -:10DE10008FA300148F76004000431021AF620040B2 -:10DE20008F8200149442011C104000090000000081 -:10DE30008F6200488F6400409763003C00441023C9 -:10DE40003063FFFF0043102A104000088FA20054E7 -:10DE5000936400368F6300403402FFFC008210049C -:10DE600000621821AF6300488FA200548FA60030D3 -:10DE70000282902130C200081040000E0000000015 -:10DE80008F6200581642000430C600FF9742011A04 -:10DE90005040000134C6001093C500088FA700341D -:10DEA0000200202100052B0034A500800E000C9BF1 -:10DEB00030A5F0808F620040005610231840001BF0 -:10DEC0008FA200183C0208008C42319830420010AA -:10DED0001040000D24020001976200681440000AFF -:10DEE000240200018F8200149442011C1440000699 -:10DEF00024020001A76200689742007A244200646D -:10DF00000A000EE9A7620012A76200120E001302B7 -:10DF1000020020219362007D2403000102002021E1 -:10DF2000344200010A000EE7AFA300501840000A77 -:10DF3000000000000E001302020020219362007D09 -:10DF40002403000102002021AFA30050344200044A -:10DF50000E00130BA362007D9362003E304200402E -:10DF60001440000C326200011040000A0000000062 -:10DF70008F6300408FC20004240400182463000152 -:10DF80000040F809AF6300408FA200300A000F3054 -:10DF9000304200048F620058105200100000000050 -:10DFA0008F620018022210231C4000082404000184 -:10DFB0008F62001816220009000000008F62001C0A -:10DFC000028210230440000500000000AF720058D8 -:10DFD000AFA40050AF710018AF74001C12E0000B2A -:10DFE0008FA200500E00130202002021A377003FF1 -:10DFF0000E00130B0200202102E030212404003720 -:10E000000E0013C9000028218FA200501040000309 -:10E01000000000000E000CA90200202112A0000543 -:10E02000000018218FA2003030420004504000113F -:10E0300000601021240300010A000F30006010214D -:10E040000E001302020020219362007D02002021B5 -:10E05000344200040E00130BA362007D0E000CA9D5 -:10E06000020020210A000F3024020001AF400044CA -:10E07000240200018FBF007C8FBE00788FB7007430 -:10E080008FB600708FB5006C8FB400688FB30064DA -:10E090008FB200608FB1005C8FB0005803E00008C1 -:10E0A00027BD00808F4201B80440FFFE2402080013 -:10E0B000AF4201B803E00008000000003C02000885 -:10E0C00003421021944200483084FFFF2484001250 -:10E0D0003045FFFF10A0001700A4102B10400016C1 -:10E0E00024020003934201202403001AA343018B5E -:10E0F000304200FF2446FFFE8F82000000A6182B4E -:10E100003863000100021382004310241040000510 -:10E110008F84000434820001A746019403E00008C4 -:10E12000AF8200042402FFFE0082102403E00008F6 -:10E13000AF8200042402000303E00008A342018B25 -:10E1400027BDFFE0AFB10014AFB00010AFBF0018A3 -:10E1500030B0FFFF30D1FFFF8F4201B80440FFFE17 -:10E1600000000000AF440180AF4400200E000F42C9 -:10E17000020020218F8300008F840004A750019AA1 -:10E18000A750018EA74301908F8300083082800042 -:10E19000AF4301A8A75101881040000E8F820004F0 -:10E1A00093420116304200FC24420004005A102120 -:10E1B0008C4240003042FFFF144000068F82000472 -:10E1C0003C02FFFF34427FFF00821024AF82000434 -:10E1D0008F8200042403BFFF00431024A74201A63E -:10E1E0009743010C8F42010400031C003042FFFFE3 -:10E1F00000621825AF4301AC3C021000AF4201B8E9 -:10E200008FBF00188FB100148FB0001003E000081A -:10E2100027BD00208F470070934201128F830000BA -:10E2200027BDFFF0304200FF00022882306201006B -:10E23000000030211040004324A40003306240005D -:10E24000104000103062200000041080005A10219D -:10E250008C43400024A4000400041080AFA30000FD -:10E26000005A10218C424000AFA2000493420116D4 -:10E27000304200FC005A10218C4240000A000FC0BE -:10E28000AFA200081040002F0000302100041080D1 -:10E29000005A10218C43400024A400040004108084 -:10E2A000AFA30000005A10218C424000AFA000082C -:10E2B000AFA200048FA80008000030210000202138 -:10E2C000240A00083C0908002529010003A41021A4 -:10E2D000148A000300042A001100000A0000000054 -:10E2E00090420000248400012C83000C00A2102125 -:10E2F00000021080004910218C4200001460FFF3DE -:10E3000000C230263C0408008C8431048F42007027 -:10E310002C83002010600009004738233C030800CC -:10E32000246331080004108000431021248300017D -:10E33000AC4700003C010800AC233104AF86000864 -:10E340002406000100C0102103E0000827BD0010D2 -:10E350003C0208008C42003827BDFFD0AFB5002436 -:10E36000AFB40020AFB10014AFBF0028AFB3001CA2 -:10E37000AFB20018AFB00010000088213C150800B3 -:10E3800026B50038144000022454FFFF0000A021ED -:10E390009742010E8F8400003042FFFF308340001F -:10E3A0001060000A245200043C0200200082102465 -:10E3B00050400007308280008F8200042403BFFF9A -:10E3C000008318240A0010103442100030828000AC -:10E3D0001040000A3C020020008210241040000778 -:10E3E0008F8200043C03FFFF34637FFF0083182407 -:10E3F00034428000AF820004AF8300000E000F980B -:10E400000000000014400007000000009743011EB8 -:10E410009742011C3063FFFF0002140000621825C0 -:10E42000AF8300089742010C8F4340003045FFFF47 -:10E430003402FFFF14620003000000000A001028ED -:10E44000241100208F42400030420100544000015E -:10E45000241100108F8400003082100050400014FE -:10E4600036310001308200201440000B3C021000C5 -:10E47000008210245040000E363100013C030E0093 -:10E480003C020DFF008318243442FFFF0043102B91 -:10E4900050400007363100013C0208008C42002C3D -:10E4A000244200013C010800AC22002C363100055A -:10E4B0003C0608008CC6003454C000238F85000041 -:10E4C0008F820004304240005440001F8F850000BE -:10E4D0003C021F01008210243C0310005443001A28 -:10E4E0008F85000030A20200144000178F850000C5 -:10E4F0003250FFFF363100028F4201B80440FFFE68 -:10E5000000000000AF400180020020210E000F42F9 -:10E51000AF4000208F8300042402BFFFA750019A60 -:10E52000006218248F820000A750018EA751018835 -:10E53000A74301A6A74201903C021000AF4201B8D8 -:10E540000A0010F5000010213C02100000A2102467 -:10E550001040003A0000000010C0000F0000000052 -:10E5600030A201001040000C3C0302003C020F00EE -:10E5700000A2102410430008000000008F82000851 -:10E58000005410240055102190420004244200043D -:10E590000A00109F000221C00000000000051602C2 -:10E5A0003050000F3A0300022E4203EF38420001C0 -:10E5B0002C6300010062182414600073240200011F -:10E5C0003C0308008C6300D02E06000C386200016A -:10E5D0002C4200010046102414400015001021C0F8 -:10E5E0002602FFFC2C4200045440001100002021B0 -:10E5F000386200022C420001004610241040000343 -:10E60000000512420A00109F000020210010182B64 -:10E610000043102450400006001021C000002021BB -:10E620003245FFFF0E000F633226FFFB001021C0B2 -:10E630003245FFFF0A0010F2362600028F424000EA -:10E640003C0308008C630024304201001040004667 -:10E6500030620001322200043070000D14400002CC -:10E660002413000424130002000512C238420001E2 -:10E670002E4303EF304200013863000100431025B0 -:10E68000104000033231FFFB2402FFFB0202802412 -:10E6900010C000183202000130A201001040001525 -:10E6A000320200013C020F0000A210243C030200D1 -:10E6B0001043000F8F8200082403FFFE0203802412 -:10E6C00000541024005510219042000402333025DC -:10E6D0002442000412000002000221C03226FFFF83 -:10E6E0000E000F633245FFFF1200002700001021CB -:10E6F000320200011040000D320200042402000129 -:10E7000012020002023330253226FFFF00002021D2 -:10E710000E000F633245FFFF2402FFFE0202802439 -:10E7200012000019000010213202000410400016EF -:10E7300024020001240200041202000202333025E8 -:10E740003226FFFF3245FFFF0E000F632404010055 -:10E750002402FFFB020280241200000B00001021A3 -:10E760000A0010F5240200011040000700001021EB -:10E770003245FFFF36260002000020210E000F6305 -:10E7800000000000000010218FBF00288FB500247A -:10E790008FB400208FB3001C8FB200188FB100140B -:10E7A0008FB0001003E0000827BD003027BDFFD068 -:10E7B000AFB000103C04600CAFBF002CAFB6002817 -:10E7C000AFB50024AFB40020AFB3001CAFB2001847 -:10E7D000AFB100148C8250002403FF7F3C1A8000EC -:10E7E000004310243442380CAC8250002402000351 -:10E7F0003C106000AF4200088E0208083C1B8008F5 -:10E800003C010800AC2000203042FFF038420010EC -:10E810002C4200010E001B85AF8200183C04FFFF54 -:10E820003C020400348308063442000CAE0219484E -:10E83000AE03194C3C0560168E0219808CA30000B3 -:10E840003442020000641824AE0219803C02535383 -:10E850001462000334A47C008CA200040050202128 -:10E860008C82007C8C830078AF820010AF83000C18 -:10E870008F55000032A200031040FFFD32A20001BC -:10E880001040013D32A200028F420128AF42002019 -:10E890008F4201048F430100AF8200000E000F3C45 -:10E8A000AF8300043C0208008C4200C01040000806 -:10E8B0008F8400003C0208008C4200C42442000106 -:10E8C0003C010800AC2200C40A00126900000000EC -:10E8D0003C020010008210241440010C8F830004BD -:10E8E0003C0208008C4200203C0308008C63003886 -:10E8F00000008821244200013C010800AC220020D5 -:10E900003C16080026D60038146000022474FFFF6D -:10E910000000A0219742010E308340003042FFFFEB -:10E920001060000A245200043C02002000821024DF -:10E9300050400007308280008F8200042403BFFF14 -:10E94000008318240A0011703442100030828000C5 -:10E950001040000A3C0200200082102410400007F2 -:10E960008F8200043C03FFFF34637FFF0083182481 -:10E9700034428000AF820004AF8300000E000F9885 -:10E980000000000014400007000000009743011E33 -:10E990009742011C3063FFFF00021400006218253B -:10E9A000AF8300089742010C8F4340003045FFFFC2 -:10E9B0003402FFFF14620003000000000A00118807 -:10E9C000241100208F4240003042010054400001D9 -:10E9D000241100108F840000308210005040001479 -:10E9E00036310001308200201440000B3C02100040 -:10E9F000008210245040000E363100013C030E000E -:10EA00003C020DFF008318243442FFFF0043102B0B -:10EA100050400007363100013C0208008C42002CB7 -:10EA2000244200013C010800AC22002C36310005D4 -:10EA30003C0608008CC6003454C000238F850000BB -:10EA40008F820004304240005440001F8F85000038 -:10EA50003C021F01008210243C0310005443001AA2 -:10EA60008F85000030A20200144000178F8500003F -:10EA70003250FFFF363100028F4201B80440FFFEE2 -:10EA800000000000AF400180020020210E000F4274 -:10EA9000AF4000208F8300042402BFFFA750019ADB -:10EAA000006218248F820000A750018EA7510188B0 -:10EAB000A74301A6A74201903C021000AF4201B853 -:10EAC0000A001267000010213C02100000A210246E -:10EAD0001040003A0000000010C0000F00000000CD -:10EAE00030A201001040000C3C0302003C020F0069 -:10EAF00000A2102410430008000000008F820008CC -:10EB000000541024005610219042000424420004B6 -:10EB10000A0011FF000221C00000000000051602DB -:10EB20003050000F3A0300022E4203EF384200013A -:10EB30002C63000100621824146000852402000187 -:10EB40003C0308008C6300D02E06000C38620001E4 -:10EB50002C4200010046102414400015001021C072 -:10EB60002602FFFC2C42000454400011000020212A -:10EB7000386200022C42000100461024504000037D -:10EB8000000512420A0011FF000020210010182B7E -:10EB90000043102450400006001021C00000202136 -:10EBA0003245FFFF0E000F633226FFFB001021C02D -:10EBB0003245FFFF0A001252362600028F42400003 -:10EBC0003C0308008C6300243042010010400046E2 -:10EBD00030620001322200043070000D1440000247 -:10EBE0002413000424130002000512C2384200015D -:10EBF0002E4303EF3042000138630001004310252B -:10EC0000104000033231FFFB2402FFFB020280248C -:10EC100010C000183202000130A20100104000159F -:10EC2000320200013C020F0000A210243C0302004B -:10EC30001043000F8F8200082403FFFE020380248C -:10EC40000054102400561021904200040233302555 -:10EC50002442000412000002000221C03226FFFFFD -:10EC60000E000F633245FFFF120000390000102133 -:10EC7000320200011040000D3202000424020001A3 -:10EC800012020002023330253226FFFF000020214D -:10EC90000E000F633245FFFF2402FFFE02028024B4 -:10ECA0001200002B00001021320200041040002846 -:10ECB0002402000124020004120200020233302563 -:10ECC0003226FFFF3245FFFF0E000F6324040100D0 -:10ECD0002402FFFB020280241200001D000010210C -:10ECE0000A001267240200015040001900001021A0 -:10ECF0003245FFFF36260002000020210E000F6380 -:10ED0000000000000A001267000010212402BFFF6B -:10ED1000006210241040000800000000240287FF59 -:10ED200000621024144000083C020060008210249D -:10ED300010400005000000000E000D34000000002F -:10ED40000A001267000000000E0012C70000000059 -:10ED5000104000063C0240008F4301243C0260202A -:10ED6000AC430014000000003C024000AF420138F8 -:10ED70000000000032A200021040FEBD00000000B2 -:10ED80008F4201403C044000AF4200208F430148C5 -:10ED90003C02700000621824106400420000000071 -:10EDA0000083102B144000063C0260003C0220004F -:10EDB000106200073C0240000A0012C3000000007D -:10EDC0001062003C3C0240000A0012C30000000038 -:10EDD0008F4501408F4601448F42014800021402D2 -:10EDE000304300FF240200041462000A274401801B -:10EDF0008F4201B80440FFFE2402001CAC850000D5 -:10EE0000A082000B3C021000AF4201B80A0012C3FE -:10EE10003C0240002402000914620012000616029F -:10EE2000000229C0AF4500208F4201B80440FFFE18 -:10EE30002402000124030003AF450180A343018B9A -:10EE4000A740018EA740019AA7400190AF4001A8BA -:10EE5000A7420188A74201A6AF4001AC3C021000C6 -:10EE6000AF4201B88F4201B80440FFFE000000002D -:10EE7000AC8500008F42014800021402A482000801 -:10EE800024020002A082000B8F420148A4820010DD -:10EE90003C021000AC860024AF4201B80A0012C345 -:10EEA0003C0240000E001310000000000A0012C3D4 -:10EEB0003C0240000E001BBA000000003C02400073 -:10EEC000AF420178000000000A00112F000000008E -:10EED0008F4201003042003E144000112402000124 -:10EEE000AF4000488F420100304207C0104000058B -:10EEF00000000000AF40004CAF40005003E00008AD -:10EF000024020001AF400054AF4000408F42010096 -:10EF10003042380054400001AF4000442402000158 -:10EF200003E00008000000008F4201B80440FFFE2B -:10EF300024020001AF440180AF400184A74501884D -:10EF4000A342018A24020002A342018B9742014A94 -:10EF500014C00004A7420190AF4001A40A0012EFC0 -:10EF60003C0210008F420144AF4201A43C02100059 -:10EF7000AF4001A803E00008AF4201B88F4201B8DA -:10EF80000440FFFE24020002AF440180AF4401842C -:10EF9000A7450188A342018AA342018B9742014AF7 -:10EFA000A7420190AF4001A48F420144AF4201A8A3 -:10EFB0003C02100003E00008AF4201B83C029000A0 -:10EFC0003442000100822025AF4400208F420020FF -:10EFD0000440FFFE0000000003E000080000000005 -:10EFE0003C028000344200010082202503E000083A -:10EFF000AF44002027BDFFE8AFBF0014AFB0001042 -:10F000008F50014093430149934201489344014882 -:10F01000306300FF304200FF00021200006228252A -:10F020002402001910620076308400802862001AE1 -:10F030001040001C24020020240200081062007707 -:10F04000286200091040000E2402000B2402000177 -:10F0500010620034286200025040000524020006BD -:10F0600050600034020020210A00139A00000000C2 -:10F0700010620030020020210A00139A00000000F4 -:10F080001062003B2862000C504000022402000E77 -:10F090002402000910620056020020210A00139A7F -:10F0A0000000000010620056286200211040000F8E -:10F0B000240200382402001C106200582862001D3F -:10F0C000104000062402001F2402001B1062004CA6 -:10F0D000000000000A00139A000000001062004ABD -:10F0E000020020210A00139A00000000106200456F -:10F0F0002862003910400007240200802462FFCB00 -:10F100002C42000210400045020020210A00139604 -:10F110000000302110620009000000000A00139A6C -:10F12000000000001480003D020020210A0013901E -:10F130008FBF00140A001396240600018F4201B805 -:10F140000440FFFE24020002A342018BA745018870 -:10F150009742014AA74201908F420144A74201927F -:10F160003C021000AF4201B80A00139C8FBF00148C -:10F170009742014A144000290000000093620005F4 -:10F180003042000414400025000000000E0013026D -:10F190000200202193620005020020213442000475 -:10F1A0000E00130BA36200059362000530420004B9 -:10F1B00014400002000000000000000D93620000F7 -:10F1C00024030020304200FF14430014000000001C -:10F1D0008F4201B80440FFFE24020005AF500180B9 -:10F1E000A342018B3C0210000A00139AAF4201B8FF -:10F1F0008FBF00148FB000100A0012F227BD001854 -:10F200000000000D02002021000030218FBF0014FB -:10F210008FB000100A0012DD27BD00180000000D9D -:10F220008FBF00148FB0001003E0000827BD001846 -:10F2300027BDFFE8AFBF00100E000F3C000000002C -:10F24000AF4001808FBF0010000020210A000FE7AF -:10F2500027BD00183084FFFF30A5FFFF00001821F4 -:10F260001080000700000000308200011040000202 -:10F2700000042042006518210A0013AB0005284055 -:10F2800003E000080060102110C0000624C6FFFF44 -:10F290008CA2000024A50004AC8200000A0013B573 -:10F2A0002484000403E000080000000010A000080F -:10F2B00024A3FFFFAC860000000000000000000057 -:10F2C0002402FFFF2463FFFF1462FFFA248400047A -:10F2D00003E0000800000000308300FF30A500FFBD -:10F2E00030C600FF274701808F4201B80440FFFE6F -:10F2F000000000008F42012834634000ACE20000AF -:10F3000024020001ACE00004A4E30008A0E2000A2B -:10F3100024020002A0E2000B3C021000A4E5001051 -:10F32000ACE00024ACE00028A4E6001203E00008F2 -:10F33000AF4201B827BDFFE8AFBF00109362003FA6 -:10F3400024030012304200FF1043000D00803021E2 -:10F350008F620044008210230440000A8FBF001017 -:10F360008F620048240400390000282100C21023C5 -:10F3700004410004240600120E0013C9000000001E -:10F380008FBF00102402000103E0000827BD001811 -:10F3900027BDFFC8AFB20030AFB1002CAFBF003403 -:10F3A000AFB0002890C5000D0080902130A400105F -:10F3B0001080000B00C088218CC300088F620054AD -:10F3C0001062000730A20005144000B524040001BB -:10F3D0000E000D21000020210A0014BB0040202156 -:10F3E00030A200051040000930A30012108000ACCC -:10F3F000240400018E2300088F620054146200A9C7 -:10F400008FBF00340A00142C240400382402001298 -:10F41000146200A3240400010220202127A500106B -:10F420000E000CB2AFA000101040001102402021CD -:10F430008E220008AF620084AF6000400E0013020D -:10F44000000000009362007D024020213442002031 -:10F450000E00130BA362007D0E000CA902402021B8 -:10F46000240400382405008D0A0014B82406001274 -:10F470009362003E304200081040000F8FA200103F -:10F4800030420100104000078FA300148F6200601B -:10F490000062102304430008AF6300600A001441B7 -:10F4A00000000000AF6000609362003E2403FFF79D -:10F4B00000431024A362003E9362003E30420008E5 -:10F4C000144000022406000300003021936200343F -:10F4D000936300378F640084304200FF306300FF85 -:10F4E00000661821000318800043282100A4202B67 -:10F4F0001080000B000000009763003C8F620084C6 -:10F500003063FFFF004510230062182B14600004D5 -:10F51000000000008F6200840A00145D0045802313 -:10F520009762003C3050FFFF8FA300103062000450 -:10F5300010400004000628808FA2001C0A001465F9 -:10F540000202102B2E02021850400003240202185F -:10F550000A00146E020510233063000410600003DB -:10F56000004510238FA2001C00451023004080217D -:10F570002C42008054400001241000800E00130231 -:10F580000240202124020001AF62000C9362003E81 -:10F59000001020403042007FA362003E8E22000413 -:10F5A00024420001AF620040A770003C8F6200500F -:10F5B0009623000E00431021AF6200588F62005066 -:10F5C00000441021AF62005C8E220004AF6200187C -:10F5D0008E220008AF62001C8FA20010304200088B -:10F5E0005440000A93A20020A360003693620036C4 -:10F5F0002403FFDFA36200359362003E0043102422 -:10F60000A362003E0A0014988E220008A36200350F -:10F610008E220008AF62004C8F6200248F6300408E -:10F6200000431021AF6200489362000024030050A1 -:10F63000304200FF144300122403FF803C02080004 -:10F640008C4231A00242102100431024AF42002816 -:10F650003C0208008C4231A08E2400083C03000CC0 -:10F66000024210213042007F03421021004310214A -:10F67000AC4400D88E230008AF820014AC4300DCF9 -:10F680000E00130B02402021240400380000282122 -:10F690002406000A0E0013C9000000002404000123 -:10F6A0008FBF00348FB200308FB1002C8FB0002894 -:10F6B0000080102103E0000827BD003827BDFFF8B7 -:10F6C00027420180AFA20000308A00FF8F4201B8BC -:10F6D0000440FFFE000000008F4601283C020800A5 -:10F6E0008C4231A02403FF80AF86004800C2102165 -:10F6F00000431024AF4200243C0208008C4231A099 -:10F700008FA900008FA8000000C210213042007FA6 -:10F71000034218213C02000A00621821946400D4BC -:10F720008FA700008FA5000024020002AF83001401 -:10F73000A0A2000B8FA30000354260003084FFFFC1 -:10F74000A4E200083C021000AD260000AD04000455 -:10F75000AC60002427BD0008AF4201B803E00008F8 -:10F76000240200018F88003C938200288F830014BC -:10F770003C07080024E7777800481023304200FF58 -:10F78000304900FC246500888F860040304A000321 -:10F790001120000900002021248200048CA3000015 -:10F7A000304400FF0089102AACE3000024A50004C7 -:10F7B0001440FFF924E70004114000090000202153 -:10F7C0002482000190A30000304400FF008A102B27 -:10F7D000A0E3000024A500011440FFF924E7000184 -:10F7E00030C20003144000048F85003C3102000346 -:10F7F0001040000D0000000010A0000900002021B2 -:10F800002482000190C30000304400FF0085102BCB -:10F81000A0E3000024C600011440FFF924E7000122 -:10F8200003E00008000000001100FFFD000020219F -:10F83000248200048CC30000304400FF0088102B99 -:10F84000ACE3000024C600041440FFF924E70004E0 -:10F8500003E00008000000008F83003C9382002832 -:10F8600030C600FF30A500FF00431023304300FFE7 -:10F870008F820014008038210043102114C0000240 -:10F88000244800880083382130E20003144000053A -:10F8900030A2000314400003306200031040000D4A -:10F8A0000000000010A000090000202124820001B7 -:10F8B00090E30000304400FF0085102BA1030000FE -:10F8C00024E700011440FFF92508000103E00008C7 -:10F8D0000000000010A0FFFD000020212482000491 -:10F8E0008CE30000304400FF0085102BAD030000C6 -:10F8F00024E700041440FFF92508000403E0000891 -:10F90000000000000080482130AAFFFF30C600FF41 -:10F9100030E7FFFF274801808F4201B80440FFFE17 -:10F920008F820048AD0200008F420124AD02000426 -:10F930008D220020A5070008A102000A240200165B -:10F94000A102000B934301208D2200088D240004A6 -:10F95000306300FF004310219783003A00441021D8 -:10F960008D250024004310233C0308008C6331A044 -:10F970008F840014A502000C246300E82402FFFF1A -:10F98000A50A000EA5030010A5060012AD0500187B -:10F99000AD020024948201142403FFF73042FFFFDC -:10F9A000AD0200288C820118AD02002C3C02100030 -:10F9B000AD000030AF4201B88D220020004310247A -:10F9C00003E00008AD2200208F82001430E7FFFF23 -:10F9D00000804821904200D330A5FFFF30C600FFD1 -:10F9E0000002110030420F0000E238252748018054 -:10F9F0008F4201B80440FFFE8F820048AD02000034 -:10FA00008F420124AD0200048D220020A5070008CA -:10FA1000A102000A24020017A102000B9343012057 -:10FA20008D2200088D240004306300FF0043102164 -:10FA30009783003A004410218F8400140043102360 -:10FA40003C0308008C6331A0A502000CA505000E44 -:10FA5000246300E8A5030010A5060012AD00001401 -:10FA60008D220024AD0200188C82005CAD02001CC7 -:10FA70008C820058AD0200202402FFFFAD0200245A -:10FA8000948200E63042FFFFAD02002894820060BD -:10FA9000948300BE30427FFF3063FFFF00021200FC -:10FAA00000431021AD02002C3C021000AD000030DC -:10FAB000AF4201B8948200BE2403FFF700A21021D8 -:10FAC000A48200BE8D2200200043102403E0000821 -:10FAD000AD220020274301808F4201B80440FFFE81 -:10FAE0008F8200249442001C3042FFFF000211C0AC -:10FAF000AC62000024020019A062000B3C0210005E -:10FB0000AC60003003E00008AF4201B88F87002CE2 -:10FB100030C300FF8F4201B80440FFFE8F820048CF -:10FB200034636000ACA2000093820044A0A20005F0 -:10FB30008CE20010A4A20006A4A300088C8200207E -:10FB40002403FFF7A0A2000A24020002A0A2000BD7 -:10FB50008CE20000ACA200108CE20004ACA2001405 -:10FB60008CE2001CACA200248CE20020ACA2002895 -:10FB70008CE2002CACA2002C8C820024ACA20018D9 -:10FB80003C021000AF4201B88C82002000431024D8 -:10FB900003E00008AC8200208F86001427BDFFE838 -:10FBA000AFBF0014AFB0001090C20063304200201D -:10FBB0001040000830A500FF8CC2007C2403FFDF4A -:10FBC00024420001ACC2007C90C2006300431024B8 -:10FBD000A0C2006310A000238F830014275001806F -:10FBE000020028210E0015D6240600828F82001400 -:10FBF000904200633042004050400019A38000440E -:10FC00008F83002C8F4201B80440FFFE8F82004892 -:10FC1000AE02000024026082A60200082402000254 -:10FC2000A202000B8C620008AE0200108C62000C75 -:10FC3000AE0200148C620014AE0200188C62001830 -:10FC4000AE0200248C620024AE0200288C620028E0 -:10FC5000AE02002C3C021000AF4201B8A380004469 -:10FC60008F8300148FBF00148FB000109062006368 -:10FC700027BD00183042007FA06200639782003ADF -:10FC80008F86003C8F850014938300280046102344 -:10FC9000A782003AA4A000E490A400638F820040F1 -:10FCA000AF83003C2403FFBF0046102100832024C3 -:10FCB000AF820040A0A400638F820014A04000BD6A -:10FCC0008F82001403E00008A44000BE8F8A001455 -:10FCD00027BDFFE0AFB10014AFB000108F88003C2B -:10FCE000AFBF00189389001C954200E430D100FF9B -:10FCF0000109182B0080802130AC00FF3047FFFF46 -:10FD00000000582114600003310600FF012030215B -:10FD1000010958239783003A0068102B1440003CD7 -:10FD20000000000014680007240200018E02002079 -:10FD30002403FFFB34E7800000431024AE020020C0 -:10FD40002402000134E70880158200053165FFFFB9 -:10FD50000E001554020020210A00169102002021F5 -:10FD60000E001585020020218F8400482743018062 -:10FD70008F4201B80440FFFE24020018AC6400006A -:10FD8000A062000B8F840014948200E6A46200102D -:10FD90003C021000AC600030AF4201B894820060B9 -:10FDA00024420001A4820060948200603C030800A9 -:10FDB0008C63318830427FFF5443000F02002021C2 -:10FDC000948200602403800000431024A482006019 -:10FDD0009082006090830060304200FF000211C2F8 -:10FDE00000021027000211C03063007F0062182556 -:10FDF000A083006002002021022028218FBF00186C -:10FE00008FB100148FB000100A0015F927BD002033 -:10FE1000914200632403FF8000431025A142006348 -:10FE20009782003A3048FFFF110000209383001CA6 -:10FE30008F840014004B1023304600FF948300E4AD -:10FE40002402EFFF0168282B00621824A48300E439 -:10FE500014A000038E020020010058210000302170 -:10FE60002403FFFB34E7800000431024AE0200208F -:10FE700024020001158200053165FFFF0E001554B4 -:10FE8000020020210A0016B99783003A0E0015855A -:10FE9000020020219783003A8F82003CA780003A1D -:10FEA00000431023AF82003C9383001C8F82001418 -:10FEB0008FBF00188FB100148FB0001027BD002035 -:10FEC00003E00008A04300BD938200442403000126 -:10FED00027BDFFE8004330042C420020AFB00010E3 -:10FEE000AFBF00142410FFFE10400005274501801D -:10FEF0003C0208008C4231900A0016D600461024BD -:10FF00003C0208008C423194004610241440000743 -:10FF1000240600848F8300142410FFFF9062006287 -:10FF20003042000F34420040A06200620E0015D63D -:10FF300000000000020010218FBF00148FB00010DD -:10FF400003E0000827BD00188F83002427BDFFE0D1 -:10FF5000AFB20018AFB10014AFB00010AFBF001CBB -:10FF60009062000D00A0902130D100FF3042007F50 -:10FF7000A062000D8F8500148E4300180080802140 -:10FF80008CA2007C146200052402000E90A2006383 -:10FF9000344200200A0016FFA0A200630E0016C51E -:10FFA000A38200442403FFFF104300472404FFFF03 -:10FFB00052200045000020218E4300003C0200102A -:10FFC00000621024504000043C020008020020217E -:10FFD0000A00170E24020015006210245040000988 -:10FFE0008E45000002002021240200140E0016C5D8 -:10FFF000A38200442403FFFF104300332404FFFFC7 -:020000040001F9 -:100000008E4500003C02000200A2102410400016A1 -:100010003C0200048F8600248CC200148CC30010A4 -:100020008CC40014004310230044102B50400005E2 -:10003000020020218E43002C8CC2001010620003AD -:10004000020020210A00173F240200123C02000493 -:1000500000A210245040001C00002021020020219A -:100060000A00173F2402001300A2102410400006CB -:100070008F8300248C620010504000130000202168 -:100080000A001739020020218C6200105040000441 -:100090008E42002C020020210A00173F240200118A -:1000A00050400009000020210200202124020017F6 -:1000B0000E0016C5A38200442403FFFF1043000274 -:1000C0002404FFFF000020218FBF001C8FB2001806 -:1000D0008FB100148FB000100080102103E00008E1 -:1000E00027BD00208F83001427BDFFD8AFB40020A8 -:1000F000AFB3001CAFB20018AFB10014AFB0001026 -:10010000AFBF0024906200638F91002C2412FFFF88 -:100110003442004092250000A06200638E2200104D -:100120000080982130B0003F105200060360A021EB -:100130002402000D0E0016C5A38200441052005484 -:100140002404FFFF8F8300148E2200188C63007C30 -:1001500010430007026020212402000E0E0016C585 -:10016000A38200442403FFFF104300492404FFFF3F -:1001700024040020120400048F83001490620063A2 -:1001800034420020A06200638F85003410A000205C -:1001900000000000560400048F8200140260202139 -:1001A0000A0017902402000A9683000A9442006015 -:1001B0003042FFFF144300048F8200202404FFFD1F -:1001C0000A0017B7AF82003C3C0208008C42318C19 -:1001D0000045102B14400006026020210000282159 -:1001E0000E001646240600010A0017B70000202161 -:1001F0002402002D0E0016C5A38200442403FFFF35 -:10020000104300232404FFFF0A0017B70000202139 -:10021000160400058F8400148E2300142402FFFFAF -:100220005062001802602021948200602442000184 -:10023000A4820060948200603C0308008C633188D3 -:1002400030427FFF5443000F0260202194820060FF -:100250002403800000431024A48200609082006088 -:1002600090830060304200FF000211C2000210279C -:10027000000211C03063007F00621825A083006077 -:10028000026020210E0015F9240500010000202144 -:100290008FBF00248FB400208FB3001C8FB20018D2 -:1002A0008FB100148FB000100080102103E000080F -:1002B00027BD00288F83001427BDFFE8AFB00010D2 -:1002C000AFBF0014906200638F87002C00808021F4 -:1002D000344200408CE60010A06200633C0308003A -:1002E0008C6331B030C23FFF0043102B1040004EF2 -:1002F0008F8500302402FF8090A3000D004310245E -:10030000304200FF504000490200202100061382C5 -:10031000304800032402000255020044020020215C -:1003200094A2001C8F85001424030023A4A20114AE -:100330008CE60000000616023042003F1043001019 -:100340003C0300838CE300188CA2007C1062000642 -:100350002402000E0E0016C5A38200442403FFFFF2 -:10036000104300382404FFFF8F8300149062006361 -:1003700034420020A06200630A0017FC8F8300242F -:1003800000C31024144300078F83002490A200624E -:100390003042000F34420020A0A20062A38800383F -:1003A0008F8300249062000D3042007FA062000D18 -:1003B0008F83003410600018020020218F840030E9 -:1003C0008C8200100043102B1040000924020018FA -:1003D000020020210E0016C5A38200442403FFFF63 -:1003E000104300182404FFFF0A00182400002021F5 -:1003F0008C820010240500010200202100431023FC -:100400008F830024240600010E001646AC62001003 -:100410000A001824000020210E0015F9240500010F -:100420000A00182400002021020020212402000DCF -:100430008FBF00148FB0001027BD00180A0016C52A -:10044000A38200448FBF00148FB0001000801021E1 -:1004500003E0000827BD001827BDFFC8AFB2002089 -:10046000AFBF0034AFB60030AFB5002CAFB400283A -:10047000AFB30024AFB1001CAFB000188F46012805 -:100480003C0308008C6331A02402FF80AF86004843 -:1004900000C318213065007F03452821006218241D -:1004A0003C02000AAF43002400A2282190A200626F -:1004B00000809021AF850014304200FF000211023D -:1004C000A382003890A200BC304200021440000217 -:1004D00024030034240300308F820014A3830028F7 -:1004E000938300388C4200C0A3800044AF82003C5C -:1004F00024020004106203148F84003C8E44000424 -:10050000508003118F84003C8E4200103083FFFF27 -:10051000A784003A106002F7AF8200408F84001475 -:100520002403FF809082006300621024304200FFA9 -:10053000144002C79785003A9383003824020002D2 -:1005400030B6FFFF14620005000088219382002866 -:100550002403FFFD0A001B11AF82003C8F82003C88 -:1005600002C2102B144002998F8400400E0014EC3C -:1005700000000000938300283C040800248477785E -:10058000240200341462002EAF84002C3C0A0800C0 -:100590008D4A77A82402FFFFAFA200100080382107 -:1005A0002405002F3C09080025297378240800FF42 -:1005B0002406FFFF90E2000024A3FFFF00062202B2 -:1005C00000C21026304200FF0002108000491021B6 -:1005D0008C420000306500FF24E7000114A8FFF5FD -:1005E0000082302600061027AFA20014AFA2001030 -:1005F0000000282127A7001027A6001400C51023FB -:100600009044000324A2000100A71821304500FFF8 -:100610002CA200041440FFF9A06400008FA2001077 -:100620001142000724020005024020210E0016C5D9 -:10063000A38200442403FFFF104300642404FFFF4F -:100640003C0208009042777C104000098F82001421 -:10065000024020212402000C0E0016C5A382004493 -:100660002403FFFF104300592404FFFF8F8200146E -:10067000A380001C3C0308008C63777C8C440080C2 -:100680003C0200FF3442FFFF006218240083202B4D -:1006900010800008AF83003402402021240200199A -:1006A0000E0016C5A38200442403FFFF1043004739 -:1006B0002404FFFF8F87003C9782003A8F85003427 -:1006C000AF8700200047202310A0003BA784003AFA -:1006D0008F86001430A200030002102390C300BCD8 -:1006E0003050000300B0282100031882307300014D -:1006F0000013108000A228213C0308008C6331A065 -:100700008F8200483084FFFF0085202B004310219A -:1007100010800011244200888F84002C1082000E6B -:100720003C033F013C0208008C42777800431024D0 -:100730003C0325001443000630E500FF8C820000D6 -:10074000ACC200888C8200100A0018E9ACC2009884 -:100750000E001529000030219382001C8F850014A3 -:100760008F830040020238218F82003CA387001C47 -:1007700094A400E4006218218F82003434841000B5 -:10078000AF83004000503021A4A400E41260000EAA -:10079000AF86003C24E20004A382001C94A200E483 -:1007A00024C30004AF83003C34422000A4A200E430 -:1007B0000A001906000020218F820040AF80003C13 -:1007C00000471021AF820040000020212414FFFFC9 -:1007D000109402092403FFFF3C0808008D08778865 -:1007E0003C0208008C4231B03C03080090637778EB -:1007F00031043FFF0082102B1040001B3067003F88 -:100800003C0208008C4231A88F83004800042180FC -:1008100000621821006418213062007F0342282101 -:100820003C02000C00A228213C020080344200015E -:100830003066007800C230252402FF800062102458 -:10084000AF42002830640007AF4208048F820014D2 -:100850000344202124840940AF460814AF850024B6 -:10086000AF840030AC4301189383003824020003A6 -:10087000146201C7240200012402002610E201C90B -:1008800028E2002710400013240200322402002234 -:1008900010E201C428E200231040000824020024D2 -:1008A0002402002010E201B02402002110E2013FE6 -:1008B000024020210A001AF32402000B10E201B9C1 -:1008C0002402002510E20010024020210A001AF341 -:1008D0002402000B10E201A628E2003310400006BB -:1008E0002402003F2402003110E200920240202145 -:1008F0000A001AF32402000B10E2019D024020219D -:100900000A001AF32402000B8F90002C3C0308000D -:100910008C6331B08F8500308E0400100000A82158 -:100920008CB3001430823FFF0043102B8CB10020A9 -:10093000504001870240202190A3000D2402FF8037 -:1009400000431024304200FF50400181024020212A -:1009500000041382304200031440017D0240202134 -:1009600094A3001C8F8200148E040028A443011459 -:100970008CA20010026218231064000302402021A0 -:100980000A00197C2402001F8F82003400621021AB -:100990000262102B104000088F83002402402021A7 -:1009A000240200180E0016C5A38200441054016CE6 -:1009B0002404FFFF8F8300248F8400348C62001096 -:1009C0000224882100441023AC6200108F8200149E -:1009D000AC7100208C4200680051102B10400009BF -:1009E0008F830030024020212402001D0E0016C516 -:1009F000A38200442403FFFF104301592404FFFF96 -:100A00008F8300308E0200248C6300241043000783 -:100A1000024020212402001C0E0016C5A3820044BF -:100A20002403FFFF1043014E2404FFFF8F840024A2 -:100A30008C82002424420001AC8200241233000482 -:100A40008F8200148C4200685622000E8E02000035 -:100A50008E0200003C030080004310241440000D6F -:100A60002402001A024020210E0016C5A382004471 -:100A70002403FFFF1043013A2404FFFF0A0019BAC0 -:100A80008E0200143C0300800043102450400003F9 -:100A90008E020014AC8000208E0200142411FFFF8F -:100AA000105100062402001B024020210E0016C532 -:100AB000A38200441051012A2404FFFF8E0300008A -:100AC0003C02000100621024104000123C02008031 -:100AD0000062102414400008024020212402001A61 -:100AE0000E0016C5A38200442403FFFF1043011C1F -:100AF0002404FFFF02402021020028210E0016E5F9 -:100B0000240600012403FFFF104301152404FFFF06 -:100B1000241500018F83002402A0302102402021EF -:100B20009462003624050001244200010A001AD70D -:100B3000A46200368F90002C3C0308008C6331B017 -:100B40008E13001032623FFF0043102B10400089CB -:100B50008F8400302402FF809083000D0043102416 -:100B6000304200FF104000842402000D0013138265 -:100B700030420003240300011443007F2402000DCF -:100B80009082000D30420008544000048F820034EF -:100B9000024020210A001A082402002450400004C8 -:100BA0008E03000C024020210A001A0824020027AC -:100BB0008C82002054620006024020218E0300082F -:100BC0008C820024506200098E0200140240202111 -:100BD000240200200E0016C5A382004410540071A8 -:100BE0002403FFFF0A001A3D8F8400242411FFFF15 -:100BF000145100048F860014024020210A001A3884 -:100C0000240200258E0300188CC2007C10620003B1 -:100C10002402000E0A001A38024020218E0300240C -:100C20008C82002810620003240200210A001A3876 -:100C3000024020218E0500288C82002C10A2000387 -:100C40002402001F0A001A38024020218E03002CC3 -:100C500014600003240200230A001A3802402021F5 -:100C60008CC200680043102B1040000324020026B1 -:100C70000A001A38024020218C82001400651821D5 -:100C80000043102B104000088F84002402402021D4 -:100C9000240200220E0016C5A38200441051004118 -:100CA0002403FFFF8F8400242403FFF79082000DAC -:100CB00000431024A082000D8F8600143C0308001E -:100CC0008C6331AC8F82004894C400E08F8500248F -:100CD0000043102130847FFF000420400044102195 -:100CE0003043007F034320213C03000E008320217A -:100CF0002403FF8000431024AF42002CA493000083 -:100D00008CA2002824420001ACA200288CA2002C56 -:100D10008E03002C00431021ACA2002C8E02002C6C -:100D2000ACA200308E020014ACA2003494A2003AAF -:100D300024420001A4A2003A94C600E03C0208004C -:100D40008C4231B024C4000130837FFF1462000F55 -:100D500000803021240280000082302430C2FFFF56 -:100D6000000213C2304200FF000210270A001A7668 -:100D7000000233C02402000D024020210E0016C5DF -:100D8000A38200440A001A7C004018218F820014BC -:100D900002402021240500010E0015F9A44600E0C0 -:100DA000000018210A001B0E006088218F90002C83 -:100DB0003C0308008C6331B08E05001030A23FFF69 -:100DC0000043102B104000612402FF808F8400300C -:100DD0009083000D00431024304200FF5040005C1F -:100DE000024020218F8200341040000B0005138246 -:100DF0008F8200149763000A944200603042FFFF24 -:100E000014430005000513828F8200202404FFFD97 -:100E10000A001AEBAF82003C304200031440000E7F -:100E20000000000092020002104000058E03002422 -:100E300050600015920300030A001AA70240202107 -:100E40008C82002450620010920300030240202193 -:100E50000A001AAF2402000F9082000D30420008F1 -:100E60005440000992030003024020212402001094 -:100E70000E0016C5A38200442403FFFF1043003870 -:100E80002404FFFF92030003240200025462000CBA -:100E9000920200038F820034544000099202000342 -:100EA000024020212402002C0E0016C5A38200441B -:100EB0002403FFFF1043002A2404FFFF92020003D3 -:100EC0000200282102402021384600102CC60001D3 -:100ED0002C4200010E0016E5004630252410FFFFCD -:100EE0001050001F2404FFFF8F8300341060001394 -:100EF000024020213C0208008C42318C0043102B20 -:100F00001440000700000000000028212406000112 -:100F10000E001646000000000A001AEB0000202117 -:100F20002402002D0E0016C5A38200441050000CB0 -:100F30002404FFFF0A001AEB000020210E0015F91F -:100F4000240500010A001AEB0000202102402021A4 -:100F50002402000D0E0016C5A3820044004020218B -:100F60000A001B0E008088211514000E00000000EE -:100F70000E00174C024020210A001B0E0040882161 -:100F80000E0016C5A38200440A001B0E00408821F3 -:100F900014620017022018212402002314E2000525 -:100FA0002402000B0E0017C0024020210A001B0E75 -:100FB0000040882102402021A38200440E0016C573 -:100FC0002411FFFF0A001B0F0220182130A500FF8B -:100FD0000E001529240600019783003A8F82003CF9 -:100FE000A780003A00431023AF82003C0220182162 -:100FF0001220003E9782003A2402FFFD5462003E18 -:101000008E4300208E4200048F830014005610236C -:10101000AE420004906200633042007FA062006331 -:101020008E4200208F840014A780003A34420002D0 -:10103000AE420020A48000E4908200632403FFBF3E -:1010400000431024A08200630A001B518E4300203D -:101050009082006300621024304200FF10400023A1 -:101060009782003A90820088908300BD2485008892 -:101070003042003F2444FFE02C820020A383001C68 -:1010800010400019AF85002C2402000100821804D2 -:10109000306200191440000C3C028000344200020F -:1010A000006210241440000B306200201040000F3A -:1010B0009782003A90A600010240202124050001F9 -:1010C0000A001B4B30C60001024020210A001B4AC7 -:1010D00024050001024020210000282124060001EF -:1010E0000E001646000000009782003A1440FD0CE6 -:1010F0008F8400148E4300203062000410400012E0 -:101100008F84003C2402FFFB00621024AE420020CA -:10111000274301808F4201B80440FFFE8F820048C0 -:10112000AC6200008F420124AC62000424026083A0 -:10113000A462000824020002A062000B3C0210001E -:10114000AF4201B88F84003C8F8300148FBF0034FE -:101150008FB600308FB5002C8FB400288FB30024D9 -:101160008FB200208FB1001C8FB000182402000144 -:1011700027BD003803E00008AC6400C030A500FFC4 -:101180002403000124A900010069102B1040000C69 -:1011900000004021240A000100A31023004A380463 -:1011A00024630001308200010069302B10400002EE -:1011B000000420420107402554C0FFF800A310237B -:1011C00003E00008010010213C020800244260A452 -:1011D0003C010800AC22736C3C0208002442530816 -:1011E0003C010800AC2273702402000627BDFFE01A -:1011F0003C010800A02273743C021EDCAFB2001850 -:10120000AFB10014AFBF001CAFB0001034526F413B -:1012100000008821240500080E001B7202202021F6 -:10122000001180803C07080024E773780002160054 -:1012300002071821AC6200000000282124A200014E -:101240003045FFFF8C6200002CA60008044100021C -:10125000000220400092202614C0FFF8AC64000079 -:10126000020780218E0400000E001B72240500205E -:10127000262300013071FFFF2E2301001460FFE5DB -:10128000AE0200008FBF001C8FB200188FB1001497 -:101290008FB0001003E0000827BD002027BDFFD855 -:1012A000AFB3001CAFB20018AFBF0020AFB1001445 -:1012B000AFB000108F5101408F48014800089402E0 -:1012C000324300FF311300FF8F4201B80440FFFE9C -:1012D00027500180AE1100008F420144AE0200048D -:1012E00024020002A6120008A202000B240200142D -:1012F000AE1300241062002528620015104000087B -:101300002402001524020010106200302402001292 -:10131000106200098FBF00200A001CAD8FB3001CB3 -:101320001062007024020022106200378FBF00207C -:101330000A001CAD8FB3001C3C0208008C4231A097 -:101340002403FF800222102100431024AF42002416 -:101350003C0208008C4231A0022210213042007F62 -:10136000034218213C02000A00621821166000BCEA -:10137000AF830014906200623042000F34420030AC -:10138000A06200620A001CAC8FBF00203C04600019 -:101390008C832C083C02F0033442FFFF00621824C7 -:1013A000AC832C083C0208008C4231A08C832C08B2 -:1013B000244200740002108200021480006218258A -:1013C000AC832C080A001CAC8FBF00203C02080034 -:1013D0008C4231A02403FF800222102100431024FC -:1013E000AF4200243C0208008C4231A03C03000ABA -:1013F000022210213042007F0342102100431021BD -:101400000A001CABAF8200143C0208008C4231A0E1 -:101410002405FF800222102100451024AF42002441 -:101420003C0208008C4231A0022210213042007F91 -:10143000034218213C02000A0062182190620063F6 -:1014400000A21024304200FF10400085AF8300143A -:1014500024620088944300123C0208008C4231A8A8 -:1014600030633FFF00031980022210210043102146 -:101470003043007F03432021004510243C03000C2F -:1014800000832021AF4200289082000D00A210248A -:10149000304200FF10400072AF8400249082000DA3 -:1014A000304200101440006F8FBF00200E0015C89E -:1014B000000000008F4201B80440FFFE0000000061 -:1014C000AE1100008F420144AE020004240200026B -:1014D000A6120008A202000BAE1300240A001CACE6 -:1014E0008FBF00202406FF8002261024AF42002078 -:1014F0003C0208008C4231A031043FFF00042180EF -:101500000222102100461024AF4200243C030800B0 -:101510008C6331A83C0208008C4231A03227007F46 -:101520000223182102221021006418213042007F7A -:101530003064007F034228213C02000A0066182420 -:1015400000A22821034420213C02000C008220211B -:10155000AF4300283C020008034718210062902195 -:10156000AF850014AF8400240E0015C8010080214F -:101570008F4201B80440FFFE8F8200248F84001444 -:10158000274501809042000DACB10000A4B00006D8 -:10159000000216000002160300021027000237C2E4 -:1015A00014C00016248200889442001232033FFFC8 -:1015B00030423FFF14430012240260829083006394 -:1015C0002402FF8000431024304200FF5040000CF2 -:1015D00024026082908200623042000F3442004058 -:1015E000A082006224026084A4A200082402000DEC -:1015F000A0A200050A001C963C022700240260827B -:10160000A4A20008A0A000053C02270000061C00C0 -:101610000062182524020002A0A2000BACA3001057 -:10162000ACA00014ACA00024ACA00028ACA0002CFE -:101630008E42004C8F840024ACA200189083000DD1 -:101640002402FF8000431024304200FF10400005B8 -:101650008FBF00209082000D3042007FA082000DDD -:101660008FBF00208FB3001C8FB200188FB1001401 -:101670008FB000103C02100027BD002803E00008D6 -:04168000AF4201B8BC -:0C1684000800343008003430080033A89F -:10169000080033E0080034140800343808003438F7 -:0816A00008003438080033187B -:0816A8000A000124000000000B -:1016B000000000000000000D747061362E322E31E3 -:1016C0000000000006020101000000000000000010 -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:101730000000000000000000000000001000000396 -:10174000000000000000000D0000000D3C02080039 -:1017500024421C003C03080024632094AC40000099 -:101760000043202B1480FFFD244200043C1D080090 -:1017700037BD2FFC03A0F0213C1008002610049078 -:101780003C1C0800279C1C000E00015C00000000AF -:101790000000000D3084FFFF308200078F850018A5 -:1017A00010400002248300073064FFF800853021D8 -:1017B00030C41FFF03441821247B4000AF85001C68 -:1017C000AF84001803E00008AF4400843084FFFFBA -:1017D000308200078F8500208F860028104000028D -:1017E000248300073064FFF8008520210086182B31 -:1017F00014600002AF8500240086202303442821C2 -:1018000034068000AF840020AF44008000A6202171 -:1018100003E00008AF84003827BDFFD8AFB3001C39 -:10182000AFB20018AFB00010AFBF0024AFB40020BB -:10183000AFB100143C0860088D1450002418FF7FDD -:101840003C1A8000029898243672380CAD12500071 -:101850008F5100083C07601C3C08600036300001D6 -:10186000AF500008AF800018AF400080AF40008448 -:101870008CE600088D0F08083C0760168CEC000011 -:1018800031EEFFF039CA00103C0DFFFF340B800031 -:101890003C030080034B48212D440001018D282486 -:1018A0003C0253533C010800AC230420AF890038AC -:1018B000AF860028AF840010275B400014A200030D -:1018C00034E37C008CF90004032818218C7F007C11 -:1018D0008C6500783C0280003C0B08008D6B048C0A -:1018E0003C0A08008D4A048834520070AF85003CE1 -:1018F000AF9F00403C13080026731C440240A02107 -:101900008E4800008F46000038C30001306400019B -:1019100010800017AF880034028048218D2F00000E -:101920003C0508008CA5045C3C1808008F1804587E -:1019300001E8102300A280210000C8210202402BF0 -:1019400003198821022838213C010800AC30045CCE -:101950003C010800AC2704588F4E000039CD00012F -:1019600031AC00011580FFED01E04021AF8F003464 -:101970008E5100003C0708008CE7045C3C0D080019 -:101980008DAD04580228802300F0602100007021F2 -:101990000190302B01AE1821006620213C01080087 -:1019A000AC2C045C3C010800AC2404588F460108B0 -:1019B0008F47010030C92000AF860000AF87000CC0 -:1019C0001120000A00C040213C1808008F18042C88 -:1019D000270800013C010800AC28042C3C184000FA -:1019E000AF5801380A000196000000009749010431 -:1019F00000002821014550213122FFFF01625821BA -:101A00000162F82B015F502130D902003C0108002F -:101A1000AC2B048C3C010800AC2A0488172000156C -:101A200024040F0010E400130000000024080D003F -:101A300010E8023B30CD000611A0FFE93C18400041 -:101A4000936E00002409001031C400F01089027167 -:101A500024020070108202E58F880014250F000117 -:101A6000AF8F00143C184000AF5801380A000196AF -:101A700000000000974C01041180FFD93C18400081 -:101A800030C34000146000A1000000008F460178C0 -:101A900004C0FFFE8F87003824100800240F0008C0 -:101AA0008CE30008AF500178A74F0140A7400142E6 -:101AB000974E01048F86000031C9FFFF30CD000131 -:101AC00011A002E1012040212531FFFE241800026F -:101AD000A75801463228FFFFA75101483C190800CA -:101AE0008F39043C172002D08F8C000C30DF00208F -:101AF00017E00002240400092404000130C20C0095 -:101B0000240504005045000134840004A744014A20 -:101B10003C1108008E3104203C1800483C100001A4 -:101B20000238182530CF00020070282511E000048B -:101B3000000018213C19010000B9282524030001E8 -:101B400030DF000453E00005AF8300083C060010BE -:101B500000A6282524030001AF830008AF4510002C -:101B60000000000000000000000000000000000075 -:101B70008F83000810600023000000008F451000D4 -:101B800004A1FFFE000000001060001E0000000025 -:101B90008F4410003C0C0020008C102410400019D1 -:101BA0008F8E000031CD000211A000160000000051 -:101BB000974F101415E0001300000000975910080B -:101BC0003338FFFF27110006001118820003308010 -:101BD00000C7282132300001322300031200032CF9 -:101BE0008CA200000000000D00C7F821AFE2000049 -:101BF0003C0508008CA5043024A600013C01080027 -:101C0000AC2604308F6D00003402FFFFAF8D00045E -:101C10008CEC0000118202A6000020218CED000057 -:101C200031AC01001180028A000000003C02080073 -:101C30008C4204743C0308008C63044C3C1F080075 -:101C40008FFF04703C1808008F18044800483821A2 -:101C50000068802100E8282B03E430210208402B93 -:101C60000304882100C57021022878213C01080066 -:101C7000AC30044C3C010800AC2F04483C01080087 -:101C8000AC2704743C010800AC2E04708F8400184B -:101C90000120302131290007249F000833F91FFF5C -:101CA00003594021AF84001CAF990018251B400048 -:101CB000AF590084112000038F83002024C2000745 -:101CC0003046FFF88F84002800C3282100A4302B61 -:101CD00014C00002AF83002400A428230345602120 -:101CE000340D8000018D10213C0F1000AF850020C5 -:101CF000AF820038AF450080AF4F01788F88001465 -:101D0000250F00010A0001EFAF8F00148F62000859 -:101D10008F670000240500300007760231C300F011 -:101D2000106500A7240F0040546FFF4C8F880014EB -:101D30008F4B01780560FFFE0000000030CA0200F2 -:101D400015400003000612820000000D00061282FA -:101D5000304D0003000D4900012D18210003808043 -:101D6000020D402100086080019380218E1F000039 -:101D700017E00002000000000000000D8F6E00045C -:101D800005C202BD92070006920E000592020004F1 -:101D90003C090001000E18800070F8218FED00183A -:101DA000277100082448000501A96021000830823D -:101DB000AFEC0018022020210E00059E260500141D -:101DC000920A00068F7900043C0B7FFF000A2080F6 -:101DD000009178218DF800043566FFFF0326282442 -:101DE00003053821ADE70004920E0005920D0004B2 -:101DF000960C0008000E10800051C8218F230000AF -:101E0000974901043C07FFFF006758243128FFFF72 -:101E1000010DF82103EC50233144FFFF016430250C -:101E2000AF26000092030007241800011078027505 -:101E3000240F0003106F0285000000008E050010C3 -:101E40002419000AA7590140A7450142921800042D -:101E50008F860000240F0001A7580144A7400146C7 -:101E60009747010430D100023C050041A7470148D3 -:101E700000001821A74F014A1220000330CB0004B4 -:101E80003C0501412403000151600005AF830008B7 -:101E90003C06001000A6282524030001AF8300089B -:101EA000AF4510000000000000000000000000002E -:101EB000000000008F8A00081140000400000000AC -:101EC0008F4410000481FFFE000000008F6B0000B3 -:101ED000920800043C1108008E310444AF8B0004CA -:101EE00097590104311800FF3C0E08008DCE0440C4 -:101EF0003325FFFF03053821022760210000102150 -:101F0000250F000A31E8FFFF0187482B01C2682135 -:101F100001A9F821311000073C010800AC2C044451 -:101F20003C010800AC3F0440120000038F8C0018F5 -:101F30002506000730C8FFF8010C682131BF1FFFDC -:101F4000AF8C001CAF9F0018AF5F00849744010462 -:101F5000035F80213084FFFF308A000711400003B7 -:101F6000261B4000248900073124FFF88F820020BF -:101F70008F850028008220210085702B15C000026B -:101F8000AF820024008520233C0B08008D6B048C5D -:101F90003C0A08008D4A04880344882134038000E9 -:101FA000022310213C0F1000AF840020AF820038C4 -:101FB000AF440080AF4F01780A0002968F8800146A -:101FC0008F5001780600FFFE30D10200162000037A -:101FD000000612820000000D00061282305F00032E -:101FE000001F1900007F302100062080009FC821BB -:101FF00000194880013380218E1800001300000270 -:10200000000000000000000D8F6C000C058001FB3B -:102010008F870038240E0001AE0E00008CE300080C -:10202000A20000078F65000400055402314D00FF37 -:1020300025A80005000830822CCB00411560000265 -:10204000A20A00040000000D8F7800043C03FFFF8B -:1020500000E02821330BFFFF256C000B000C1082E1 -:1020600000022080008748218D3F000026040014D4 -:10207000A618000803E3C8240E00059EAD39000031 -:102080008F4F01083C11100001F1382410E001AB22 -:1020900000000000974D01049208000725AAFFECFC -:1020A000350600023144FFFFA2060007960600082D -:1020B0002CC7001354E0000592030007921100079B -:1020C000362F0001A20F0007920300072418000119 -:1020D000107801C224090003106901D58F880038E7 -:1020E00030CBFFFF257100020011788331E400FF3F -:1020F00000042880A20F000500A848218D2D0000B3 -:10210000974A01043C0EFFFF01AEF8243143FFFF64 -:10211000006B1023244CFFFE03ECC825AD390000F2 -:10212000920600053C03FFF63462FFFF30D800FF43 -:102130000018388000F08821922F00143C04FF7FA3 -:102140003487FFFF31EE000F01C65821316500FFD3 -:1021500000055080015068218DAC00200148F82115 -:10216000A20B00060182C824AE0C000CAFF9000CD3 -:10217000920900068E11000C032778240009C08004 -:102180000310702195C60026030828210227202469 -:10219000AE04000CADCF0020ADC60024ACA60010EC -:1021A0008F8800003C0B08008D6B048C3C0A0800F3 -:1021B0008D4A0488241F001024190002A75F0140E3 -:1021C000A7400142A7400144A7590146974901048D -:1021D00024070001310600022538FFFEA7580148F8 -:1021E0003C050009A747014A10C000030000182160 -:1021F0003C05010924030001310C00045180000555 -:10220000AF8300083C08001000A828252403000123 -:10221000AF830008AF451000000000000000000080 -:1022200000000000000000009205000424AE00023F -:1022300031CD0007000D182330620007AE020010F8 -:102240008F90000812000004000000008F4F100063 -:1022500005E1FFFE000000008F7100008F8E001866 -:102260003C0308008C630444AF91000497450104CB -:1022700025CF001031E61FFF30A2FFFFAF8E001CFC -:10228000AF860018AF4600842449FFFE3C0C0800CE -:102290008D8C0440974D010401208021000947C323 -:1022A0000070C02131A9FFFF0310F82B0188C8215D -:1022B000033F202103463821313100073C0108004B -:1022C000AC3804443C010800AC2404401220000354 -:1022D00024FB40002527000730E9FFF88F86002007 -:1022E0008F8400280126382100E4C02B170000024B -:1022F000AF86002400E438230347202134198000EE -:10230000009910213C0F1000AF870020AF820038E9 -:10231000AF470080AF4F01780A0002968F88001403 -:102320009747010410E0FDAE3C1840008F5801783B -:102330000700FFFE30C5400010A000033C1F00084E -:102340000000000D3C1F0008AF5F01402410080092 -:102350008F860000AF5001789744010430D9000106 -:10236000132000ED3086FFFF24CCFFFE240D000279 -:10237000A74D0146A74C01488F9100182408000D75 -:10238000A748014A8F630000262F000831E21FFF93 -:102390000342702130C90007AF830004AF91001CD5 -:1023A000AF82001800C03821AF4200841120000322 -:1023B00025DB400024D800073307FFF88F85002075 -:1023C0008F84002800E5302100C4382B14E000027F -:1023D000AF85002400C430238F8400140346F82105 -:1023E000340C8000AF86002003EC8021AF460080D3 -:1023F000249900013C0610003C184000AF460178CB -:10240000AF900038AF990014AF5801380A00019618 -:10241000000000008F630000975101043067FFFF48 -:102420003228FFFF8F4F017805E0FFFE30EC0007F8 -:10243000000CF82333F0000724F9FFFE2404000AFF -:10244000A7440140A7500142A7590144A7400146B3 -:10245000A74801488F45010830B800201700000246 -:10246000240300092403000130CD0002A743014AE0 -:102470003C04004111A00003000018213C0401416C -:102480002403000130C9000451200005AF83000877 -:102490003C0600100086202524030001AF830008BD -:1024A000AF44100000000000000000000000000029 -:1024B000000000008F8E000811C000040000000022 -:1024C0008F4210000441FFFE000000008F7F0000DB -:1024D000276400088F91003CAF9F0004948500089A -:1024E0009490000A9499000C30AFFFFF0010C400D4 -:1024F0003323FFFF11F100A6030320253C0E080043 -:102500008DCE04443C0C08008D8C044000E88821EA -:102510002626FFFE01C628210000682100A6F82B10 -:10252000018D2021009F80213C010800AC2504443E -:102530003C010800AC30044024E200083042FFFFB8 -:102540003047000710E000038F830018244F000776 -:1025500031E2FFF83106FFFF30C800070043802159 -:1025600032191FFF0359C021AF83001CAF99001817 -:10257000271B4000AF590084110000038F8C0020FE -:1025800024C5000730A6FFF88F84002800CC28213E -:1025900000A4F82B17E00002AF8C002400A428232D -:1025A000AF850020AF4500803C0408008C840434D3 -:1025B00003454821340E8000012E6821108000055B -:1025C000AF8D0038939100172406000E12260011DB -:1025D0002407043F3C021000AF4201788F880014AA -:1025E000250F00010A0001EFAF8F00140E0005C493 -:1025F00000E020218F8800143C0B08008D6B048CB8 -:102600003C0A08008D4A0488250F00010A0001EFEA -:10261000AF8F00143C021000A7470148AF42017879 -:102620000A0004CE8F88001424040F001184003D9A -:1026300030CE002015C0000224030009240300014D -:102640000A00021AA743014A0A00020DA7400146E8 -:1026500094EF000894F1000A94F0000C8F8C003C79 -:10266000001174003207FFFF31EDFFFF11AC00379E -:1026700001C720253C1808008F1804443C0F0800AF -:102680008DEF0440000080210308682101A8382B49 -:1026900001F0702101C760213C010800AC2D044409 -:1026A0003C010800AC2C04400A00027A8F84001818 -:1026B0003C0208008C42047C3C0308008C630454F8 -:1026C0003C1F08008FFF04783C1808008F18045046 -:1026D000004838210068802100E8282B03E43021DD -:1026E0000208402B0304882100C5702102287821AC -:1026F0003C010800AC3004543C010800AC2F0450ED -:102700003C010800AC27047C3C010800AC2E047896 -:102710000A00027A8F840018A74001460A00043597 -:102720008F91001830CD002015A0FFC52403000DA7 -:10273000240300050A00021AA743014A974E010428 -:1027400025C5FFF00A00038130A4FFFF8F980040E9 -:102750001498FFC8000010213C0508008CA5046CEB -:102760003C1F08008FFF046800A8C8210328302BF5 -:1027700003E22021008640213C010800AC39046CB2 -:102780003C010800AC2804680A00027A8F84001813 -:102790008F8C0040148CFF5900E8C8213C180800B9 -:1027A0008F18046C3C1108008E3104682723FFFE4B -:1027B00003034821000010210123302B0222702145 -:1027C00001C668213C010800AC29046C3C010800EA -:1027D000AC2D04680A0004A524E200088F880038A4 -:1027E0003C03FFFF8D02000C0043F82403E4C825DE -:1027F000AD19000C0A00038F30CBFFFF0A0003C3A2 -:10280000AE000000974A0104920400048E26000CDA -:10281000014458212579FFF200C7C0243325FFFF6A -:1028200003053825AE27000C0A0002E68E050010CD -:102830003C0DFFFF8D0A0010014D582401646025F6 -:10284000AD0C00100A00038F30CBFFFF974301044B -:10285000920E00048E290010006E1021244DFFEE10 -:102860000127602431A8FFFF0188F825AE3F001042 -:102870000A0002E68E0500108E0F000CAE0000006C -:1028800000078880023028210A0002B8ACAF00207F -:102890001460000D3058FFFF3C04FFFF0044682423 -:1028A00001A47026000E602B000D102B004CF824A4 -:1028B00013E00002000000000000000D8CAF0000DB -:1028C0000A00025001E410253B03FFFF0003882BA0 -:1028D0000018802B0211202410800002000000004C -:1028E0000000000D8CB900000A0002503722FFFFE3 -:1028F0003084FFFF30A5FFFF108000070000182183 -:1029000030820001104000020004204200651821BE -:102910001480FFFB0005284003E000080060102140 -:1029200010C00007000000008CA2000024C6FFFFBA -:1029300024A50004AC82000014C0FFFB2484000422 -:1029400003E000080000000010A0000824A3FFFF1F -:10295000AC86000000000000000000002402FFFF21 -:102960002463FFFF1462FFFA2484000403E00008DC -:1029700000000000308EFFFF30D8FFFF00057C0014 -:1029800001F8602539CDFFFF01AC5021014C582BD7 -:10299000014B4821000944023127FFFF00E83021A4 -:1029A0000006240230C5FFFF00A418213862FFFF93 -:1029B00003E000083042FFFF3C0C08008D8C0484CB -:1029C000240BFF8027BDFFD001845021014B4824F8 -:1029D000AF4900203C0808008D080484AFB20020F5 -:1029E000AFB00018AFBF0028AFB30024AFB1001CD8 -:1029F000936600040104382130E4007F009A10211E -:102A00003C0300080043902130C500200360802172 -:102A10003C080111277B000814A000022646007024 -:102A20002646006C9213000497510104920F000493 -:102A30003267000F322EFFFF31ED004001C728231F -:102A400011A0000500004821925900BC3338000451 -:102A50001700009000000000924300BC307F00048B -:102A600013E0000F0000000010A0000D00000000A7 -:102A7000960E0002240AFF8000A7602125CDFFFEEC -:102A8000A74D1016920B0004014B2024308200FF4A -:102A900010400085010C40253C0F0400010F40252B -:102AA0008F5301780660FFFE2404000AA74401400A -:102AB000960D00022404000931AC0007000C5823D5 -:102AC000316A0007A74A0142960200022443FFFE32 -:102AD000A7430144A7400146975F0104A75F01484F -:102AE0008F590108333800205300000124040001ED -:102AF000920F000431EE001015C000023483001064 -:102B000000801821A743014A0000000000000000D7 -:102B10000000000000000000AF48100000000000AE -:102B20000000000000000000000000008F511000B5 -:102B30000621FFFE3113FFFF1260000300000000BA -:102B40008F481018ACC8000096030006307FFFFFC6 -:102B500027F900020019988200138880023B302177 -:102B60008CD800001520005700183402920300048E -:102B70002405FF8000A3F82433F100FF1220002C6D -:102B800000000000924700BC30F200021240002812 -:102B900000000000974B100C2562FFFEA7421016A4 -:102BA000000000003C0A040035490030AF49100025 -:102BB0000000000000000000000000000000000015 -:102BC0008F4C10000581FFFE000000009749100C9B -:102BD0008F51101C00C020213127FFFF24F200304C -:102BE000001218820003288000BBF8213226FFFF64 -:102BF000AFF100000E0005B300112C020013C880D5 -:102C0000033B98218E78000000027400AFB80010DA -:102C10008FA80010310FFFFFAFAF00108FA400107E -:102C200001C46825AFAD00108FA60010AE6600008D -:102C300097730008976D000A9766000C8F8A003C16 -:102C4000000D5C0030CCFFFF3262FFFF104A0036FF -:102C5000016C2025960600023C10100024D30008C9 -:102C60000E00013B3264FFFF974C01040E00014946 -:102C70003184FFFFAF5001788FBF00288FB300244D -:102C80008FB200208FB1001C8FB0001803E0000845 -:102C900027BD003010A0FF700000000024A5FFFC3D -:102CA0000A0005EC240900048CD10000AF51101873 -:102CB0008F5301780660FF7A2404000A0A00060197 -:102CC0000000000000A7C8218F8800388F4E101C1C -:102CD0000019C0820018788001E82021AC8E000025 -:102CE000000E2C0200C020210E0005B331C6FFFFEC -:102CF000023B28218CAD000000025400004030212E -:102D0000AFAD00108FAC0010318BFFFFAFAB0010E8 -:102D10008FA2001001424825AFA900108FA7001014 -:102D20000A000631ACA700008F8F0040148FFFC946 -:102D30000000000097420104960B00023C050800C9 -:102D40008CA5046C3049FFFF316AFFFF3C1108007D -:102D50008E310468012A382124F2FFFE00B240219E -:102D60000012FFC30112C82B023FC021031920210A -:102D70003C010800AC28046C3C010800AC24046849 -:102D80000A00066B0000000000A4102B1040000990 -:102D9000240300010005284000A4102B04A0000318 -:102DA000000318405440FFFC000528401060000755 -:102DB000000000000085302B14C000020003184200 -:102DC000008520231460FFFB0005284203E0000873 -:102DD000008010218F85002C27BDFFE800053027DB -:102DE0002CC300012CA40002008310251040000316 -:102DF000AFBF00102405007FAF85002C00052827F9 -:102E000030A5FFFF0E000592240426F58F830030C5 -:102E1000240402BD004030210083382B10E000095B -:102E200024050001000420400083102B04800003CF -:102E3000000528405440FFFC0004204010A000087A -:102E400000C350210064402B1500000200052842F9 -:102E50000064182314A0FFFB0004204200C350218B -:102E60008FBF0010000A4C02312200FF27BD00185E -:0C2E7000AF8A002C03E00008AF8900309E -:042E7C000A00002A1E -:102E800000000000000000000000000D74787036A3 -:102E90002E322E310000000006020100000000006A -:102EA000000001360000EA600000000000000000A1 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000016DC -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F1000000000000000138800000000000005DC35 -:102F2000000000000000000010000003000000008E -:102F30000000000D0000000D3C02080024423C206F -:102F40003C03080024633DD4AC4000000043202B28 -:102F50001480FFFD244200043C1D080037BD7FFCA7 -:102F600003A0F0213C100800261000A83C1C08001B -:102F7000279C3C200E0002BA000000000000000D5B -:102F80008F8300383C088000350700708CE5000016 -:102F9000008330253C02900000C22025AF85003020 -:102FA000AF4400208F4900200520FFFE3C03800035 -:102FB000346200708C4500008F8600303C19080098 -:102FC0008F39007C3C0E08008DCE007800A62023AF -:102FD00003245821000078210164682B01CF60216F -:102FE000018D50213C010800AC2B007C3C01080005 -:102FF000AC2A007803E00008000000000A0000414D -:10300000240400018F8400383C05800034A20001B4 -:103010000082182503E00008AF43002003E0000809 -:10302000000010213084FFFF30A5FFFF1080000753 -:1030300000001821308200011040000200042042EC -:10304000006518211480FFFB0005284003E00008FC -:103050000060102110C00007000000008CA20000DA -:1030600024C6FFFF24A50004AC82000014C0FFFBAF -:103070002484000403E000080000000010A0000801 -:1030800024A3FFFFAC860000000000000000000049 -:103090002402FFFF2463FFFF1462FFFA248400046C -:1030A00003E0000800000000308AFFFF93A800132F -:1030B000A74A014497490E1630C600FF3C02100093 -:1030C000A7490146AF450148A3460152A748015A06 -:1030D000AF4701608FA400188FA30014A7440158C4 -:1030E000AF43015403E00008AF42017803E0000859 -:1030F000000000003C038000346200708C49000036 -:103100008F8800002484000727BDFFF83084FFF873 -:10311000AF890030974D008A31ACFFFFAFAC0000A3 -:103120008FAB0000016850232547FFFF30E61FFFEB -:1031300000C4282B14A0FFF73C0C8000358B0070D6 -:103140008D6A00003C0708008CE700843C060800FC -:103150008CC6008000081082014918230002788084 -:1031600000E370210000202101C3C82B00C4C0214E -:1031700001FA4021031948212502400027BD00081B -:103180003C010800AC2E00843C010800AC29008002 -:1031900003E00008000000008F8200002486000782 -:1031A00030C5FFF800A2182130641FFF03E00008BB -:1031B000AF8400008F8700388F8A004027BDFFB89A -:1031C0008F860044AFB60040AFBF0044AFB5003CAF -:1031D000AFB40038AFB30034AFB20030AFB1002CA1 -:1031E000AFB000288F4501048D4900ACAF47008087 -:1031F0008CC8002000A938230000B021AF480E1071 -:103200008F440E1000004821AF440E148CC20024DD -:10321000AF420E188F430E18AF430E1C10E001256D -:103220002D230001936B0008116000D40000000002 -:10323000976E001031CDFFFF00ED602B158000CFA1 -:103240000000000097700010320FFFFFAF4F0E001C -:103250008F520000325100081220FFFD00000000D4 -:1032600097540E088F460E043285FFFF30B30001DD -:1032700012600132000000000000000D30B8A040D4 -:1032800024150040131500C030A9A0001120012D05 -:1032900000000000937F000813E000080000000019 -:1032A00097630010306BFFFF00CB402B1100000331 -:1032B00030AC00401180012300000000A785003CD5 -:1032C000AF8600349366000800E02821AFA70020F5 -:1032D00014C0012427B30020AF60000C9782003C8B -:1032E0003047400014E00002240300162403000EBF -:1032F00024194007A363000AAF790014938A003EA3 -:103300008F740014315800070018AA4002959025C8 -:10331000AF7200149784003C8F700014309100103D -:1033200002117825AF6F0014978E003C31CD000854 -:1033300011A00147000028218F6700143C021000F3 -:103340003C0C810000E22825AF65001497460E0A68 -:103350002408000E3405FFFC30C3FFFF006C582525 -:10336000AF6B0004A3680002937F000A27E9000402 -:10337000A369000A9786003C9363000A30CC1F00C3 -:10338000000C598301634021251F0028A37F0009F9 -:1033900097490E0CA769001093790009272A0002AB -:1033A000315800070018A82332B10007A371000BA1 -:1033B00093740009976400108F910034978F003C3C -:1033C000329200FF024480210205702131ED00405D -:1033D00011A0000531C4FFFF0091282B3C12800092 -:1033E00010A000140000A0210224382B14E0011BBF -:1033F0008FA500208F4D0E14AF4D0E108F420E1C66 -:10340000AF420E18AF440E008F4F000031EE00089F -:1034100011C0FFFD0000000097540E0800808821B5 -:1034200000009021A794003C8F500E04241400014A -:10343000AF900034976400103095FFFF8E68000055 -:103440000111F82317E00009AE7F00008F6500141A -:103450008F8B004434A60040AF6600148F4C0E10D2 -:10346000AD6C00208F430E18AD63002493670008F5 -:1034700014E000D2000000000E00009E24040010A2 -:103480008F8900483C08320000402821312600FF87 -:103490000006FC0003E8502525390001AF990048DB -:1034A000AC4A0000937800099370000A330400FFCF -:1034B00000047400320F00FF01CF6825AC4D0004FA -:1034C0008F820048064000EAACA20008ACA0000CC5 -:1034D0009783003C306B0008156000022628000628 -:1034E00026280002974E0E148F450E1C8F6700048D -:1034F000936D000231C4FFFF31A200FFAFA20010A4 -:103500008F6C0014AFA800180E00008BAFAC001435 -:10351000240400100E0000C7000000008E7200009E -:1035200016400005000000008F6400142405FFBF52 -:1035300000859824AF7300148F79000C033538216F -:10354000AF67000C9375000816A00008000000008B -:1035500012800006000000008F7F00143C0BEFFF7C -:103560003568FFFE03E84824AF690014A37400081F -:103570008FA500200A00024602202021AF470E003E -:103580000A0000F5000000008F5901780720FFFEB7 -:10359000241F08008F840000AF5F0178974B008ADA -:1035A000316AFFFF014448232528FFFF31021FFF36 -:1035B0002C4300081460FFF9000000008F8E0048C3 -:1035C0008F8D003800C048210344202125C600010A -:1035D000240C0F00AF86004800E938232486400001 -:1035E00031CA00FF11AC0005240800019391003E90 -:1035F0003230000700107A4035E80001000AAC00C4 -:103600003C18010002B8A025AC9440008F930048FC -:1036100030B2003630A40008ACD30004108000970C -:1036200001123025974E0E0A8F8D00003C0281005A -:1036300031CCFFFF25AB0008018240253C03100080 -:1036400031651FFF25390006241F000EAF480160B9 -:1036500000C33025A75F015AAF850000A759015864 -:1036600014E0000A8F93003824120F0052720002F7 -:103670002416000134C600408F580E108F94004469 -:10368000AE9800208F550E18AE9500248F450E146D -:10369000AF4501448F590E1CAF590148A34A01524E -:1036A0003C0A1000AF460154AF4A017814E0FEDD39 -:1036B0002D2300010076A025128000178FBF004443 -:1036C0008F84003824160F0010960084000000003C -:1036D0008F45017804A0FFFE24150F001095006EA1 -:1036E000000000008F470E14240202403C1F10000F -:1036F000AF4701448F440E1CAF440148A340015220 -:10370000A740015AAF400160A7400158AF420154A1 -:10371000AF5F01788FBF00448FB600408FB5003C8B -:103720008FB400388FB300348FB200308FB1002CCB -:103730008FB0002803E0000827BD004814C0FED069 -:1037400030B8A0408F420E148F84004400004821FE -:10375000AC8200208F510E1CAC9100240A00020E96 -:103760002D2300018F910034978A003C3C12800089 -:103770000220A821315800401700FF300000A0218E -:10378000976900108F9200343139FFFF13320035F2 -:1037900000002021008048211480FEA000A03821D4 -:1037A0008F420E148F840044AC8200208F510E1C77 -:1037B000AC9100240A00020E2D230001936A000937 -:1037C0009378000B315000FF330F00FF020F702180 -:1037D00025C2000A3050FFFF0E00009E020020218B -:1037E0008F8600483C1F410024CD0001AF8D00486A -:1037F000936C000930C600FF00064400318300FFCF -:10380000246B0002010B4825013FC825AC5900007C -:103810008F67000C97440E1400F22825AC45000475 -:103820008F450E1C8F670004936A00023084FFFFEF -:10383000315800FFAFB800108F6F0014AFB10018FF -:103840000E00008BAFAF00140A0001A60200202179 -:10385000AF6000040A00013EA36000020A000246B5 -:1038600000002021000090210A00017024140001B2 -:103870003C1280000A000195ACB2000C8F91000050 -:1038800025240002A744015826300008320F1FFFEC -:103890000A0001F9AF8F0000AF40014C1120002C4D -:1038A000000000008F590E10AF5901448F430E18CD -:1038B000240200403C1F1000AF430148A3400152C6 -:1038C000A740015AAF400160A7400158AF420154E0 -:1038D000AF5F01780A0002278FBF00441120000665 -:1038E0000000000097460E0830CC00401580000212 -:1038F000000000000000000D8F4D017805A0FFFEC4 -:103900000000000097530E103C120500240E20000A -:10391000326AFFFF0152C025AF58014C8F4F0E1481 -:103920003C021000AF4F01448F500E1CAF500148B5 -:10393000A34001528F840038A740015AAF40016074 -:10394000A7400158AF4E01540A000215AF4201785A -:103950008F490E14AF4901448F430E1C0A00028E9A -:10396000240200403C0E20FF27BDFFE03C1A8000EF -:103970003C0F800835CDFFFDAFBF001CAFB2001873 -:10398000AFB10014AFB00010AF8F0040AF4D0E00CC -:103990000000000000000000000000000000000027 -:1039A000000000003C0C00FF358BFFFDAF4B0E000C -:1039B0003C0660048CC95000240AFF7F3C11600063 -:1039C000012A40243507380CACC750008E24043837 -:1039D00024050009AF4500083083FFFF38622F71CE -:1039E0002450C0B3AF8000480E000068AF800000D4 -:1039F00052000001AE20442C0E0004353C11800022 -:103A00000E000ED9363000708F8A00403C1208003C -:103A100026523C88020088218E0800008F5F00003B -:103A20003BF900013338000113000017AF88003064 -:103A3000022048218D2700003C0F08008DEF006C0C -:103A40003C0C08008D8C006800E8C02301F8282198 -:103A50000000682100B8302B018D582101664021FB -:103A60003C010800AC25006C3C010800AC28006853 -:103A70008F44000038830001306200011440FFEDE4 -:103A800000E04021AF8700308E0C00003C050800AC -:103A90008CA5006C3C0408008C84006801883023ED -:103AA00000A638210000102100E6402B00821821DA -:103AB0000068F8213C010800AC27006C3C010800BC -:103AC000AC3F00688F49010025590088AF99004438 -:103AD000AF890038AF4900208E070000AF87003063 -:103AE0008F4D017805A0FFFE000000008E0600004B -:103AF0003C0B08008D6B00743C0408008C84007043 -:103B000000C728230165F8210000102103E5402BA0 -:103B10000082382100E8C821240908003C0108007F -:103B2000AC3F00743C010800AC390070AF4901782B -:103B300093580108A398003E938F003E31EE000198 -:103B400015C000158F830038240E0D00106E00196B -:103B5000240F0F00106F001D00000000915900009D -:103B600024180050332900FF113800043C1F400086 -:103B7000AF5F01380A0002E7000000000E00090EE6 -:103B8000000000008F8A00403C1F4000AF5F0138FA -:103B90000A0002E700000000938D003E31AC0006F1 -:103BA000000C51000E0000CE0152D8210A00034340 -:103BB0008F8A00403C1B0800277B3D080E0000CE8A -:103BC000000000000A0003438F8A00403C1B0800ED -:103BD000277B3D280E0000CE000000000A000343B2 -:103BE0008F8A004090AA00018FAB00108CAC0010AF -:103BF0003C0300FF8D680004AD6C00208CAD001408 -:103C000000E060213462FFFFAD6D00248CA7001836 -:103C10003C09FF000109C024AD6700288CAE001CE0 -:103C20000182C82403197825AD6F0004AD6E002C05 -:103C30008CAD0008314A00FFAD6D001C94A9000254 -:103C40003128FFFFAD68001090A70000A5600002BA -:103C5000A1600004A167000090A30002306200FF91 -:103C60000002198210600005240500011065000E95 -:103C70000000000003E00008A16A00018CD80028C1 -:103C8000354A0080AD7800188CCF0014AD6F001459 -:103C90008CCE0030AD6E00088CC4002CA16A0001EF -:103CA00003E00008AD64000C8CCD001CAD6D001865 -:103CB0008CC90014AD6900148CC80024AD680008DC -:103CC0008CC70020AD67000C8CC200148C8300648C -:103CD0000043C82B13200007000000008CC2001412 -:103CE000144CFFE400000000354A008003E00008A7 -:103CF000A16A00018C8200640A00039900000000A0 -:103D000090AA000027BDFFF88FA9001CA3AA0000FD -:103D10008FAE00003C0FFF808FA8001835E2FFFF38 -:103D20008CCD002C01C26024AFAC0000A1200004A7 -:103D300000E06021A7A000028FB800008D270004DA -:103D40000188182100A0582100C05021006D2826AC -:103D50003C06FF7F3C0F00FF2CAD000135EEFFFF5E -:103D600034D9FFFF3C02FF0003193024000D1DC0B1 -:103D7000010EC82400E2C02400C370250319782571 -:103D8000AD2E0000AD2F00048D450024AFAE000025 -:103D9000AD2500088D4D00202405FFFFAD2D000C42 -:103DA000956800023107FFFFAD27001091660018EB -:103DB00030C200FF000219C2506000018D4500347E -:103DC000AD2500148D67000827BD0008AD27001C35 -:103DD0008C8B00CCAD2C0028AD20002CAD2B00240A -:103DE000AD20001803E00008AD20002027BDFFE053 -:103DF000AFB20018AFB10014AFB00010AFBF001CDD -:103E00009098000000C088213C0D00FF330F007F18 -:103E1000A0CF0000908E000135ACFFFF3C0AFF00F0 -:103E2000A0CE000194A6001EA22000048CAB0014BA -:103E30008E29000400A08021016C2824012A40243E -:103E40000080902101052025A6260002AE24000452 -:103E500026050020262400080E0000762406000215 -:103E600092470000260500282624001400071E00A3 -:103E70000003160324060004044000032403FFFF8C -:103E8000965900023323FFFF0E000076AE23001088 -:103E9000262400248FBF001C8FB200188FB100149D -:103EA0008FB0001024050003000030210A000080BC -:103EB00027BD002027BDFFD8AFB1001CAFB0001850 -:103EC000AFBF002090A80000240200018FB0003C8A -:103ED0003103003F00808821106200148FAA00384F -:103EE000240B0005506B0016AFAA001000A0202183 -:103EF00000C028210E0003DC02003021922400BC07 -:103F0000308300021060000326060030ACC00000C1 -:103F100024C600048FBF00208FB1001C8FB0001892 -:103F200000C0102103E0000827BD0028014038210F -:103F30000E00035AAFB000100A0004200000000079 -:103F40000E0003A1AFB000140A000420000000001E -:103F50003C02000A034218213C04080024843D6C02 -:103F60002405001A000030210A000080AF830054AD -:103F70003C038000346200708C48000000A058218F -:103F800000C04821308A00FFAF8800308F4401789C -:103F90000480FFFE3C0C8000358600708CC500005C -:103FA0003C0308008C6300743C1808008F180070F4 -:103FB00000A82023006468210000C82101A4782BF8 -:103FC0000319702101CF60213C010800AC2D007461 -:103FD0003C010800AC2C00708F480E14AF4801441F -:103FE000AF47014CA34A0152A74B01589346010821 -:103FF00030C5000854A0000135291000934B09007A -:1040000024070050316A00FF11470007000000003C -:104010008F450E1CAF450148AF4901543C091000C3 -:1040200003E00008AF490178934D010831A800086A -:104030001100001000000000934F010831EE001045 -:1040400051C00001352900083C04080090843DD08F -:10405000A34401508F4309A4AF4301488F4209A0F4 -:10406000AF420144AF4901543C09100003E000088D -:10407000AF4901783C1908008F393D8C333800086E -:104080005700FFF1352900080A0004730000000002 -:1040900024070040AF470814AF4008108F4209447E -:1040A0008F4309508F4409548F45095C8F46094C52 -:1040B000AF820064AF830050AF84004CAF85005CDA -:1040C00003E00008AF8600609346010930C5007F19 -:1040D000000518C0000521400083102103E00008FE -:1040E000244200883C09080091293D9124A800023F -:1040F0003C05110000093C0000E8302500C51825EA -:1041000024820008AC83000003E00008AC800004B7 -:104110009347010B8F4A002C974F09083C18000E5B -:104120000358482131EEFFFF000E41C0AF48002C7C -:1041300097430908952C001A0080402124030001B0 -:10414000318BFFFFAC8B00008D2D001C00A058218F -:1041500000C06021AC8D00048D24002030E70040B9 -:10416000AD04000891220019304400031083004878 -:104170002885000214A00062240600021086005662 -:1041800024190003109900660000000010E0003AB6 -:10419000000000003C07080094E73D8624E200018F -:1041A000934F0934934709219525002A31EE00FFEA -:1041B000000E488230ED00FF978700580009360056 -:1041C000000D1C003044FFFF00C310250044C02533 -:1041D00000A778213C19400003197025000F4C00FE -:1041E000AD090004AD0E0000934D09203C0300060C -:1041F00025090014000D360000C32025AD04000879 -:104200008F59092C24E5000130A27FFFAD19000C65 -:104210008F580930A782005825020028AD180010D9 -:104220008F4F0938AD0F0014AD2B00048F4E09409D -:10423000AD2E0008934D09373C05080090A53D9030 -:104240008F4409488F46094031A700FF00EC182130 -:10425000008678230003C7000005CC000319602501 -:1042600031E8FFFC01885825AD2B000CAD20001073 -:1042700003E00008AF4A002C3C0D080095AD3D86D8 -:104280003C0E080095CE3D800A0004C901AE102105 -:104290003C05080094A53D8A3C06080094C63D8074 -:1042A0003C18080097183D7C952E002400A6782124 -:1042B00001F86823000E240025A2FFF200821825D1 -:1042C00024190800AD03000CAD190014AD00001056 -:1042D0000A0004C425080018952600249525002806 -:1042E0000006C40000057C00370E810035ED080093 -:1042F000AD0E000CAD0D00100A0004C4250800141A -:104300001480FFA200000000952400240004140083 -:1043100034430800AD03000C0A0004C42508001053 -:104320003C03080094633D8A3C05080094A53D8049 -:104330003C06080094C63D7C953900249538002839 -:10434000006520210086782300196C000018740095 -:1043500025E2FFEE01C2202535A3810024190800C3 -:10436000AD03000CAD040010AD190018AD00001431 -:104370000A0004C42508001C03E00008240201F41C -:1043800027BDFFE8AFB00010AFBF00140E00006003 -:104390000080802124050040AF4508148F83005021 -:1043A0008F84004C8F85005C0070182100641023FE -:1043B00018400004AF830050AF6300548F66005470 -:1043C000AF86004C1200000C000000008F44007407 -:1043D000936800813409FA002D07000710E00005FA -:1043E00000891021936C0081240B01F4018B50048F -:1043F00001441021AF62000C8F4E095C01C5682397 -:1044000019A000048FBF00148F4F095CAF8F005CB0 -:104410008FBF00148FB000100A00006227BD001883 -:104420008F8400648F8300508F82004CAF640044FF -:10443000AF63005003E00008AF6200543C0380000B -:10444000346200708C43000027BDFFF8308700FF06 -:1044500030A900FF30C800FFAF8300308F440178DF -:104460000480FFFE3C028000345900708F38000049 -:10447000A3A700033C0708008CE700748FAC000082 -:104480003C0608008CC60070030378233C0E7FFFB7 -:1044900000EFC82135CDFFFF00005021018D2824F9 -:1044A00000CA1821000847C0032F202B00A81025A0 -:1044B0000064C021AFA200003C010800AC390074C8 -:1044C0003C010800AC380070934F010AA3A0000221 -:1044D0003C0E80FFA3AF00018FAC0000312B007FAA -:1044E00035CDFFFF018D4824000B5600012A4025E1 -:1044F000240730002406FF803C05100027BD00087B -:10450000AF48014CAF470154A7400158A3460152A0 -:1045100003E00008AF45017827BDFFE8AFBF0014F6 -:10452000AFB000108F6500743C068000309000FF33 -:1045300000A620250E000060AF64007493630005A0 -:10454000346200080E000062A36200050200202110 -:104550008FBF00148FB00010240500052406000151 -:104560000A00057027BD001827BDFFE03C0380004E -:10457000AFB00010AFBF0018AFB1001434620070CC -:104580008C470000309000FF30A800FFAF8700305C -:104590008F4401780480FFFE3C18800037110070C2 -:1045A0008E2F00003C0D08008DAD00743C0A080001 -:1045B0008D4A007001E7702301AE282100005821C8 -:1045C00000AE302B014B4821012638213C01080068 -:1045D000AC250074000088213C010800AC27007065 -:1045E0001100000F000000008F6200742619FFFF09 -:1045F0003208007F0002FE0233E5007F150000064E -:10460000332200FF2407FF800207202624A3FFFF98 -:1046100000838025320200FF004080212411100811 -:104620000E000060000000008F49081831250004CA -:1046300014A0FFFD3218007F001878C000187140E8 -:1046400001CF682125AC0088AF4C0818274A0980A3 -:104650008D4B0020AF4B01448D460024AF460148EE -:10466000A35001500E000062A74001580220102103 -:104670008FBF00188FB100148FB0001003E0000846 -:1046800027BD002027BDFFE8308400FFAFBF00102A -:104690000E0005BB30A500FF8F8300508FBF0010B8 -:1046A000344500402404FF903C02100027BD001850 -:1046B000AF43014CA3440152AF45015403E000084D -:1046C000AF4201789343093E306200081040000D6C -:1046D0003C0901013528080AAC8800008F470074A6 -:1046E000AC8700043C06080090C63D9030C5001021 -:1046F00050A00006AC8000088F6A0060AC8A0008F9 -:104700002484000C03E00008008010210A00062227 -:104710002484000C27BDFFE8AFBF0014AFB0001029 -:104720009346093F00A050210005288000853823CA -:1047300030C200FF240300063C09080095293D868D -:1047400024E8FFD8240500041043003724060002A3 -:104750009750093C3C0F020400063400320EFFFF64 -:1047600001CF6825AC8D0000934C093E318B0020B1 -:104770001160000800000000934309363C02010369 -:10478000345F0300307900FF033FC0252405000893 -:10479000AC98000493430934935909210005F88229 -:1047A000306200FF0002C082332F00FF00186E004D -:1047B000000F740001AE6025018920253C094000EE -:1047C00000898025ACF0FFD8934309378F4F094803 -:1047D0008F580940306200FF004AC821033F702112 -:1047E00001F86023000E6F0001A650253185FFFC03 -:1047F000001F58800145482501683821AD09002077 -:104800000E00006024F00028240400040E00006262 -:10481000A364003F020010218FBF00148FB000106E -:1048200003E0000827BD00180A0006352406001220 -:1048300027BDFFD024090010AFB60028AFB5002473 -:10484000AFB40020AFB10014AFB000103C010800BD -:10485000A0293D90AFBF002CAFB3001CAFB2001831 -:1048600097480908309400FF3C02000E3107FFFF13 -:10487000000731C0AF46002C974409089344010B50 -:1048800030B500FF03428021308300300000B021AA -:104890001060012500008821240C00043C01080060 -:1048A000A02C3D90934B093E000B5600000A2E03AE -:1048B00004A0016000000000AF400048934F010BCE -:1048C00031EE002011C00006000000009358093EA0 -:1048D00000189E00001396030640018900000000A6 -:1048E0009344010B30830040106000038F9300500D -:1048F0008F8200502453FFFF9347093E30E60008A3 -:1049000014C0000224120003000090219619002C0C -:1049100093580934934F0937A7990058330C00FF77 -:1049200031EE00FF024E6821000D5880016C5021CD -:10493000015140213C010800A4283D869205001841 -:1049400030A900FF010918213C010800A4233D887B -:104950009211001816200002000000000000000D57 -:104960003C010800A4233D8A3C010800A4203D80AE -:104970003C010800A4203D7C935F010B3063FFFFE6 -:1049800033F00040120000022464000A2464000B8B -:104990003091FFFF0E00009E022020219358010B52 -:1049A0003C08080095083D8A0040202100185982E3 -:1049B000316700010E00049A01072821934C010B76 -:1049C0008F4B002C974E09083C0F000E034F4021DF -:1049D00031CDFFFF000D51C0AF4A002C97430908AD -:1049E0009505001A004038212404000130A9FFFF7A -:1049F000AC4900008D06001C00404821318A00406F -:104A0000AC4600048D020020ACE2000891030019BE -:104A100030630003106400EC2879000217200118AD -:104A2000241000021070010C241F0003107F011ECF -:104A300000000000114000DE000000003C090800FA -:104A400095293D8625220001935F0934934E092163 -:104A50009504002A33F900FF0019C08231CF00FF0E -:104A6000978E005800184600000F6C00010D80253D -:104A70003045FFFF02051025008E50213C03400009 -:104A800000433025000A6400ACEC0004ACE60000F2 -:104A9000935F09203C19000624EC0014001FC60097 -:104AA00003197825ACEF00088F48092C25CD0001AB -:104AB00031A57FFFACE8000C8F500930A785005866 -:104AC00024E80028ACF000108F4409380100802150 -:104AD000ACE40014AD9300048F530940AD9300087B -:104AE000934A09373C19080093393D908F43094890 -:104AF0008F460940314200FF0052F82100667023C2 -:104B0000001F7F000019C40001F8282531CDFFFCEB -:104B100000AD2025AD84000CAD800010AF4B002C03 -:104B2000934B093E317300081260000D3C060101F1 -:104B300034CC080AACEC00288F530074AD13000489 -:104B40003C0B0800916B3D903167001050E0000372 -:104B5000AD0000088F6A0060AD0A00082510000C47 -:104B600012C0003D000000009343093F24160006D8 -:104B700024060004306200FF105600C9240700021A -:104B80009758093C3C0F0204330DFFFF01AF40254D -:104B9000AE0800009345093E30A4002010800008B4 -:104BA00000000000935309363C0B0103357F0300DE -:104BB000327900FF033F7025AE0E00042406000882 -:104BC000934F093493480921312AFFFF31ED00FF4B -:104BD000000D1082310300FF0002B60000032C001C -:104BE00002C56025018A9825001220803C094000FA -:104BF0000204502302695825AD4BFFD8935F093753 -:104C00008F4F09488F58094033F900FF0332702154 -:104C10000006B08201D668210007440001F828236D -:104C2000000D1F000068302530A2FFFC2547FFD88B -:104C300000C260250016808002074821ACEC0020ED -:104C4000253000280E00006024120004A372003FEB -:104C50000E000062000000009347010B30F200409C -:104C6000124000053C1900FF8E180000372EFFFF90 -:104C7000030E3024AE0600000E0000C702202021E3 -:104C80003C10080092103D90321100031220000FDA -:104C900002A028218F89005025330001AF930050D6 -:104CA000AF7300508F6B00540173F8231BE00002B8 -:104CB000026020218F640054AF6400548F4C007454 -:104CC000258401F4AF64000C02A028210280202179 -:104CD000A76000680E0005BB3C1410008F850050D3 -:104CE00034550006AF45014C8F8A00488FBF002C19 -:104CF0008FB3001C25560001AF9600488FB20018F4 -:104D0000A34A01528FB60028AF5501548FB1001449 -:104D1000AF5401788FB500248FB400208FB00010FD -:104D200003E0000827BD00309358093E00189E009C -:104D3000001396030642003624110002934409230F -:104D4000308300021060FEDD8F8600608F8200508D -:104D500014C2FEDA000000000E0000600000000037 -:104D60009369003F24070016312800FF1107000C4B -:104D7000240500083C0C0800918C3D90358B000107 -:104D80003C010800A02B3D90936A003F314300FF97 -:104D900010650065240D000A106D005E2402000CF1 -:104DA0000E000062000000000A00069000000000F3 -:104DB0003C09080095293D863C0A0800954A3D803B -:104DC0000A0006F3012A10213C09080095293D8AB2 -:104DD0003C04080094843D803C06080094C63D7C59 -:104DE00095030024012410210046F8230003CC0081 -:104DF00027F0FFF20330C025240F0800ACF8000CA8 -:104E0000ACEF0014ACE000100A0006EE24E7001836 -:104E10003C010800A0313D90935F093E241600013B -:104E200033F900201720FEA5241100080A0006907F -:104E3000241100048F6E00848F4D094011A0FE9E46 -:104E4000AF8E0050240F00143C010800A02F3D90AD -:104E50000A00068F00000000950E0024950D002822 -:104E6000000E6400000D2C003589810034A6080076 -:104E7000ACE9000CACE600100A0006EE24E70014D2 -:104E80001460FEEC000000009502002400021C00EB -:104E900034640800ACE4000C0A0006EE24E70010BD -:104EA0000A000741240700123C02080094423D8A90 -:104EB0003C06080094C63D803C03080094633D7C9A -:104EC00095100024951900280046F82103E3C0231B -:104ED00000106C0000197400270FFFEE01CF282589 -:104EE00035AC8100ACEC000CACE5001024070800E8 -:104EF000AD2700182527001C0A0006EEAD2000147F -:104F00008F7F004CAF7F00548F7900540A000699C0 -:104F1000AF790050A362003F0E0000620000000065 -:104F20000A00069000000000240200140A0008276E -:104F3000A362003F27BDFFE8308400FFAFBF001031 -:104F40000E0005BB30A500FF9378007E9379007FAB -:104F5000936E00809368007A332F00FF001866007C -:104F6000000F6C0031CB00FF018D4825000B520073 -:104F70008FBF0010012A3825310600FF344470002D -:104F800000E628252402FF813C03100027BD0018FD -:104F9000AF45014CAF440154A342015203E0000865 -:104FA000AF43017827BDFFD8AFB20018AFB10014EE -:104FB000AFB00010AFBF0020AFB3001C9342010997 -:104FC000308600FF30B000FF000618C23204000235 -:104FD0003071000114800005305200FF9367000516 -:104FE00030E5000810A0000D30C80010024020215C -:104FF0000E0005A702202821240400018FBF0020F5 -:105000008FB3001C8FB200188FB100148FB0001046 -:105010000080102103E0000827BD002815000032A1 -:105020000000000093430109000028213062007F46 -:10503000000220C00002F94003E49821267900888C -:10504000033B98218E7800248E6F0008130F0046D2 -:10505000000000008F640084241800020004FD8218 -:1050600033F900031338007C0000000093660083CE -:10507000934A0109514600043205007C10A00060EB -:10508000000000003205007C14A0005302402021E3 -:1050900016200006320400018E7F00248F5901047F -:1050A00017F9FFD600002021320400011080000A09 -:1050B000024020218F4209408F9300641053000664 -:1050C000000000000E00066D022028218F430940D9 -:1050D000AF630044024020210E0006020220282176 -:1050E0000A000860240400013C0908008D290064BE -:1050F000252600013C010800AC26006416000012C1 -:10510000000000008F6D00843C0E00C001AE6024E2 -:1051100015800005024020210E00082E02202821C3 -:105120000A00086024040001240500040E00057034 -:1051300024060001024020210E00082E0220282112 -:105140000A000860240400010E000041240400014C -:10515000936B007D020B50250E000062A36A007D58 -:105160000A0008A38F6D00848F6600748F480104C5 -:105170008E67002400064E021507FFB63126007F19 -:10518000936B008326440001308A007F1146004360 -:10519000316300FF5464FFB08F6400842645000132 -:1051A00030B1007F30A200FF122600042405000168 -:1051B000004090210A00087624110001240FFF808E -:1051C000024F702401CF9026324200FF0040902110 -:1051D0000A000876241100010E00066D0220282125 -:1051E000321800301300FFAA321000820240202142 -:1051F0000E0005A7022028210A00086024040001EF -:105200008F6E00743C0F80002405000301CF9025B1 -:10521000AF72007493710083240600010E000570C4 -:10522000322400FF0E00004124040001936D007D34 -:10523000020D60250E000062A36C007D3C0B08008F -:105240008D6B0054257000013C010800AC30005407 -:105250000A000860240400018F6800743C09800083 -:105260002405000401093825AF67007493630083A7 -:10527000240600010E000570306400FF0E0000419E -:10528000240400019362007D020298250E00006252 -:10529000A373007D0A00086024040001324D0080E1 -:1052A00039AC0080546CFF6C8F6400840A0008C91C -:1052B0002645000127BDFFC83C0A0008AFBF0030EB -:1052C000AFB5002CAFB40028AFB30024AFB20020BC -:1052D000AFB1001CAFB00018034AD8212409004028 -:1052E000AF490814AF4008108F4209448F4309505A -:1052F0008F4609548F47095C8F48094C9344010835 -:105300009345010BAF820064308400FF30A500FF9D -:10531000AF830050AF86004CAF87005C0E00084A98 -:10532000AF8800601440017D8FBF0030A760006827 -:10533000934D0900240B00503C15080026B53D484C -:1053400031AC00FF3C12080026523D58118B00037F -:10535000000000000000A8210000902193510109E5 -:105360008F9F005024040010322E007F000E68C072 -:10537000000E6140018D282124B40088AF54081824 -:105380008F4901048F4A09A43C0B000E034BC02136 -:10539000012A10233C010800AC223D6C8F430958C0 -:1053A0003C010800A0243D9097470908007F302366 -:1053B0003C010800AC263D7030E8FFFF0008C9C082 -:1053C0003C010800AC3F3D94AF59002C97420908BE -:1053D0009710002C8EB10000930F001803749821D1 -:1053E000A7900058AF9300440220F80931F000FF65 -:1053F000304E000215C001B2304F000111E0014FE4 -:10540000000000009343093E3066000814C000020B -:10541000241400030000A0218F5809A424130001C4 -:105420003C010800AC383D98934F0934935109373B -:1054300031EC00FF322E00FF028E6821000D288023 -:1054400000AC5021015058213C010800A42B3D889C -:105450003C010800A42A3D8693490934312200FF0B -:1054600002022021249000103C010800A4303D8459 -:10547000240700068F9F00503C010800AC273D8C9C -:105480008F88005C8F59095800008021011F282354 -:1054900004A00149033F20230480014700A4302BCE -:1054A00010C00149000000003C010800AC253D701F -:1054B0008E4200000040F809000000003043000266 -:1054C000146000F80040882130440001548000102E -:1054D0008E4200043C0908008D293D743C0AC0003E -:1054E000012A8025AF500E008F45000030AB000828 -:1054F0001160FFFD00000000974D0E082410000110 -:10550000A78D003C8F4C0E04AF8C00348E420004FB -:105510000040F8090000000002228825322E000217 -:1055200015C00180000000003C09080095293D7C61 -:105530003C06080094C63D883C0A0800954A3D7E1A -:105540003C1908008F393D74012660213C18080081 -:105550008F183D983C03080094633D92018A2021F6 -:105560008F4E09400329F821248F000203E32821EC -:10557000031968213C010800A42C3D8AAF8E006409 -:105580003C010800AC2D3D983C010800A4253D805D -:105590000E00009E31E4FFFF8F870048004020216D -:1055A0003C010800A0273D918E42000824E800013C -:1055B000AF8800480040F809000000009344010B48 -:1055C0008F4C002C974A09083C0B000E034B4021DE -:1055D0003149FFFF000919C08F8B0050AF43002CE9 -:1055E000974309089506001A00403821308A004088 -:1055F00030DFFFFFAC5F00008D19001C0040482128 -:10560000AC5900048D180020AC580008910F001907 -:1056100031E30003107300F0000000002862000274 -:105620001440010924050002106500FD240D00034B -:10563000106D010D00000000114000D900000000B5 -:105640003C0A0800954A3D8625420001934D0934E5 -:1056500093580921950E002A31A300FF00032082F0 -:10566000331F00FF9798005800047E00001FCC00F5 -:1056700001F940253049FFFF0109102501D83021EB -:105680003C0540000045502500066C00ACED0004D0 -:10569000ACEA0000934309203C04000624ED00140A -:1056A0000003FE0003E4C825ACF900088F49092C6B -:1056B000270F000131EE7FFFACE9000C8F48093065 -:1056C000A78E005824E90028ACE800108F4509385F -:1056D00001204021ACE50014ADAB00048F4209402D -:1056E000ADA20008934B09373C1F080093FF3D9083 -:1056F0008F4309488F4A0940316600FF00D42021BA -:10570000006A78230004C700001FCC000319282575 -:1057100031EEFFFC00AE1025ADA2000CADA00010D4 -:10572000AF4C002C934C093E318B00085160000FA8 -:105730008E58000C3C06010134CA080AACEA002865 -:105740008F4B0074AD2B00043C0C0800918C3D90F5 -:105750003187001050E00003AD2000088F62006028 -:10576000AD2200082528000C8E58000C0300F80913 -:10577000010020213C19080097393D8A3C1F080090 -:1057800097FF3D7E033F782125E900020E0000C708 -:105790003124FFFF3C0E08008DCE3D6C3C08080014 -:1057A0008D083D7401C828233C010800AC253D6CE0 -:1057B00014A00006000000003C0308008C633D8C30 -:1057C000346400403C010800AC243D8C12000070A1 -:1057D0008F8C00448F470E108F900044AE0700203E -:1057E0008F4D0E18AE0D00243C10080096103D8021 -:1057F0000E0000600000000024020040AF420814C8 -:105800008F8600508F8A004C00D01821006A5823E0 -:1058100019600004AF830050AF6300548F650054DB -:10582000AF85004C1200000C000000008F44007493 -:10583000936800813409FA002D0E000711C000059D -:1058400000891821937F0081241901F403F9780459 -:1058500001E41821AF63000C8F44095C8F83005C66 -:105860000083C0231B000003000000008F50095C70 -:10587000AF90005C0E000062000000008F8C0050B2 -:105880008E4700103C010800AC2C3D9400E0F80964 -:10589000000000003C0D08008DAD3D6C55A0FEF5EC -:1058A000240700068F450024975909088F8B006450 -:1058B0008F9400503C0F001F978200588F86005431 -:1058C0008F93004C3328FFFF35E9FF8000A9502457 -:1058D000000871C032320100AF4E0024A4C2002C77 -:1058E000AF4A0024AF6B0044AF740050AF73005454 -:1058F0001640008032380010570000868EA4000445 -:10590000322300405460001B8EB100088EB0000CA2 -:105910000200F809000000008FBF00308FB5002C96 -:105920008FB400288FB300248FB200208FB1001CE9 -:105930008FB0001803E0000827BD00389347010925 -:105940008F8800380007FE0003E8C825AF590080A3 -:105950008F5809A08F5309A4AFB80010AF580E1488 -:105960008FB40010AF540E10AF530E1C0A00096222 -:10597000AF530E180220F809000000008EB0000C92 -:105980000200F809000000000A000AA88FBF0030DA -:10599000A5800020A59300220A000A5BAD93002495 -:1059A0003C09080095293D863C06080094C63D80C8 -:1059B0000A0009F4012610213C010800AC203D70CA -:1059C0000A00098E8E4200003C010800AC243D70A4 -:1059D0000A00098E8E4200003C03080094633D8A51 -:1059E0003C04080094843D803C1F080097FF3D7CE8 -:1059F000951800240064C821033F782300186C0028 -:105A000025EEFFF201AE2825AC45000C240208006B -:105A1000ACE20014ACE000100A0009EF24E7001823 -:105A200095060024950900280006240000091C00A2 -:105A3000349F810034790800ACFF000CACF90010F1 -:105A40000A0009EF24E700141460FEFB00000000C8 -:105A50009518002400187C0035EE0800ACEE000C10 -:105A60000A0009EF24E700103C07080094E73D8096 -:105A70003C04080094843D8A3C03080094633D7C08 -:105A800095190024951800280087F82103E378234E -:105A90002407080000192C0000186C0025EEFFEE0A -:105AA00001AE302534A28100AD2700182527001C47 -:105AB000AD22000CAD2600100A0009EFAD20001445 -:105AC00093520109000028210E000602324400FF13 -:105AD0008FBF00308FB5002C8FB400288FB3002407 -:105AE0008FB200208FB1001C8FB0001803E00008B7 -:105AF00027BD0038935F010933E400FF0E00066DF7 -:105B000000002821323800105300FF7E322300406D -:105B10008EA400040080F809000000000A000AA218 -:105B2000322300401200FF5F000000008F540E146B -:105B30008F920044AE5400208F530E1C0A000A8A34 -:105B4000AE5300248F82001C008040213C040100E1 -:105B50009047008530E3002010600009000000003D -:105B60003C0708008CE73D948F83001800E3202356 -:105B7000048000089389000414E30003010020213D -:105B800003E00008008010213C04010003E000084D -:105B9000008010211120000B006738238F8C00201B -:105BA00024090034918B00BC316A0002514000018D -:105BB0002409003000E9682B15A0FFF10100202125 -:105BC00000E938232419FFFC00B9C02400F9782427 -:105BD00000F8702B15C0FFEA01E8202130C2000355 -:105BE0000002182314C000123069000300003021A5 -:105BF00000A9702101C6682100ED602B1180FFE033 -:105C00003C0401002D2F00010006482B010538211E -:105C100001E9302414C0FFDA24E4FFFC2419FFFC5E -:105C200000B9C0240308202103E0000800801021EF -:105C30008F8B002024060004916A00BC31440004CC -:105C40001480FFEC00A970210A000B5E00003021D7 -:105C500027BDFFE8AFBF00108F460100934A01093E -:105C60003C1F08008FFF00902407FF80314F00FF8A -:105C700031E8007F0008614003E6C821032CC02101 -:105C800027090120012770243C010800A02F3DD0E6 -:105C9000AF4E080C3C0D08008DAD00903C04008018 -:105CA0003482000301A65821016C182124650120CB -:105CB00030AA007801424025AF48081C3C1F08006C -:105CC0008FFF00908F88004003E6C0213319000742 -:105CD00003074824033A7821AF49002825E909C081 -:105CE000952E00023C0D08008DAD008C3C0A08008A -:105CF0008D4A009031CC3FFF01A61821000C59803D -:105D0000006B282100A72024AF44002C952200021C -:105D10003C1F08008FFF008C9107008530593FFF22 -:105D200003E678210019C1800146702101F868213D -:105D300031CC007F31AB007F019A2821017A5021BC -:105D40003C03000C3C04000E00A328210144102158 -:105D500030E6002027470980AF82002CAF88001C66 -:105D6000AF890024AF85002010C00006AF8700284F -:105D70008D0200508CA4010C0044302318C0007721 -:105D800000000000910C0085240DFFDF018D3824F8 -:105D9000A10700858F8B001C8F8900248F87002826 -:105DA0008D65004CAF850018912F000D31EE00205D -:105DB00011C000170000000024090001A38900049D -:105DC000AF80000C8CE400248F85000C240A0008AE -:105DD000AF800008AF8000103C010800A42A3D7E7F -:105DE0003C010800A4203D920E000B32000030213F -:105DF0008F8500248FBF0010AF82001490A8000D83 -:105E000027BD00180008394203E0000830E2000115 -:105E1000913F00022418000133F900FF001921828C -:105E200010980039240800021088005B8F86002C2F -:105E30008CE5002414A0001B8F9F002091220000FD -:105E4000240A00053046003F10CA00472404000120 -:105E50008F860008A3840004AF860010AF86000C74 -:105E60008CE400248F85000C240A00083C01080003 -:105E7000A42A3D7E3C010800A4203D920E000B3276 -:105E8000000000008F8500248FBF0010AF82001437 -:105E900090A8000D27BD00180008394203E0000853 -:105EA00030E200018CF800088CF900248FEE00C469 -:105EB000A38000048CE40024AF8E000C8F85000CBE -:105EC0008F86000803197823240A0008AF8F00107A -:105ED0003C010800A42A3D7E3C010800A4203D921C -:105EE0000E000B32000000008F8500248FBF0010D1 -:105EF000AF82001490A8000D27BD00180008394299 -:105F000003E0000830E20001912300003062003F0E -:105F1000104400278F8500208CE400241480002189 -:105F2000000000008D2E00183C187FFF8F85002098 -:105F3000370FFFFF01CF1824AF8300088F9F0008A1 -:105F40008CA8008403E8C82B1720000203E020215E -:105F50008CA400840A000BEDAF8400088CA3010C14 -:105F60000A000BCBAF8300188D2C00188F86000819 -:105F70003C0D7FFF8F89002035A3FFFF018358244C -:105F800024040001AF8B0010AD2000CCA3840004DA -:105F90000A000BF9AF86000C8CCA00140A000BED46 -:105FA000AF8A00088CA300C80A000C30AF83000839 -:105FB0008F84002C8CAC00648C8D0014018D582BC8 -:105FC00011600004000000008CA200640A000C3084 -:105FD000AF8200088C8200140A000C30AF820008E7 -:105FE0008F85000C27BDFFE0AFBF0018AFB10014D4 -:105FF00014A00007AFB000108F8600242402000513 -:1060000090C400003083003F106200B68F840020EF -:106010008F91000800A080218F8C00283C0508008B -:106020008CA53D708D8B000431663FFF00C5502B61 -:106030005540000100C02821938D000411A0007379 -:1060400000B0F82B8F98002024040034930F00BC7C -:1060500031EE000251C000012404003000A4C82B1E -:10606000172000D10000000000A4282300B0F82B66 -:106070003C010800A4243D7C17E0006802002021B8 -:106080003C0308008C633D6C0083102B54400001DE -:10609000008018218F8800243C010800AC233D7447 -:1060A000000048219104000D308300205060000161 -:1060B0008F490E188F8300140123382B10E00059EC -:1060C000000000003C0408008C843D7400895821C5 -:1060D000006B502B114000560090602B006930235C -:1060E00000C020213C010800AC263D7412000003D2 -:1060F000241FFFFC1090008A32270003009FC82451 -:106100003C010800AC393D743C010800A4203D92DC -:106110008F84000C120400078F830020AF910008C9 -:10612000020020218C7100CCAF90000C26300001C1 -:10613000AC7000CC3C0208008C423D748F8A001089 -:10614000240700180082202301422823AF84000C7A -:1061500010800002AF850010240700108F86001CFD -:106160003C010800A0273D902407004090CC00850A -:10617000318B00C0116700408F8D001414A00015F2 -:1061800000002021934A01098F420974314500FF24 -:106190000002260224A300013090007F3071007FAE -:1061A0001230007A2407FF80A0C300833C09080056 -:1061B0008D293D8C8F880024240D0002352C000889 -:1061C0003C010800A02D3DD13C010800AC2C3D8CC9 -:1061D00024040010910E000D31C6002010C00005EF -:1061E00000801821240800013C010800AC283D74FF -:1061F000348300018FBF00188FB100148FB00010DE -:106200000060102103E0000827BD00203C010800C9 -:10621000A4203D7C13E0FF9A020020210A000C819B -:1062200000A020213C0408008C843D740090602B69 -:106230001180FFAE000000003C0F080095EF3D7C90 -:1062400001E4702101C6682B11A000072C82000414 -:106250003C1F60008FF954043338003F1700FFE5FE -:10626000240300422C8200041040FFA024030042BB -:106270000A000CDF8FBF0018152DFFC000000000C2 -:106280008CDF00743C0380002405FF8003E3C825F5 -:10629000ACD9007490D80085240E000424040010AA -:1062A000330F003F01E54025A0C800858F880024FA -:1062B0003C010800A02E3DD1240300019106000DF1 -:1062C00030C9002015200003000000003C03080036 -:1062D0008C633D743C010800AC233D6C0A000CD675 -:1062E000000000008F8700108C88008400E8282BB5 -:1062F00014A0000200E088218C9100842409000190 -:10630000A38900048F440E18022028210E000B32AE -:1063100002203021022080210A000C67AF82001485 -:1063200000071823306600033C010800A4263D92B4 -:10633000122000058F8C0020918B00BC316A000474 -:106340001540001524CD00043C0F080095EF3D9248 -:1063500001E4702100AE302B50C0FF6E8F84000C22 -:106360002C85000514A0FFA32403004230980003ED -:1063700017000002009818232483FFFC3C0108004A -:10638000AC233D740A000CA30000000000A75824B1 -:106390000A000CCB016718263C010800A42D3D9291 -:1063A0000A000D33000000003C010800AC203D74E1 -:1063B0000A000CDE240300428F83001014600007E3 -:1063C000000010218F88002424050005910600009C -:1063D00030C400FF108500030000000003E0000847 -:1063E00000000000910A0018314900FF000939C27D -:1063F00014E0FFFA8F85001C3C04080094843D7C67 -:106400003C0308008C633D943C1908008F393D74AF -:106410003C0F080095EF3D920064C0218CAD005404 -:106420000319702101CF6021018D58231960001DCF -:1064300000000000910E001C8F8C002C974B0E105A -:1064400031CD00FF8D850004016D30238D88000063 -:1064500030CEFFFF000E510000AAC82100003821F5 -:1064600001072021032A182B0083C021AD990004C5 -:10647000AD980000918F000A01CF6821A18D000A1C -:106480008F88002C974B0E12A50B0008950A003838 -:1064900025490001A50900389107000D34E60008E0 -:1064A000A106000D03E000080000000027BDFFE08A -:1064B000938700048F8F00248FAD00143C0E7FFF64 -:1064C0008F89000C35C8FFFFAFBF001CAFB00018AC -:1064D00001A8182491EA000D000717C03C1FBFFF58 -:1064E000006258252D2E00018F90001837F9FFFF0C -:1064F0003C1808008F183D943C0F080095EF3D8A2A -:1065000001796824000E47803C07EFFF3C05F0FF4F -:1065100001A818253149002034E2FFFF34ACFFFF09 -:106520000310582327A500102406000225EA0002C4 -:106530000062182400808021152000020000402104 -:106540008F480E1CA7AA0012056000372407000020 -:1065500030FF00FF001FCF008F8B001C0079382513 -:10656000AFA70014916F00853C08080091083D9189 -:106570003C18DFFF31EE00C0370AFFFF000E182B7A -:106580003C1F080097FF3D8400EA6824A3A800117F -:106590000003174001A248258FB90010AFA90014CD -:1065A0003C0A0800914A3D93A7BF00168FA800142B -:1065B000032CC0243C0B01003C0F0FFF030B1825DC -:1065C0003147000335EEFFFF010C68240007160079 -:1065D000006EF8243C09700001A2C82503E9582583 -:1065E000AFB90014AFAB00100E000076A3A00015E9 -:1065F0008F8C0024260200089186000D30C40020F4 -:10660000108000068FBF001C3C05080094A53D804B -:1066100024B0FFFF3C010800A4303D808FB000187B -:1066200003E0000827BD00208F9800140118502BAC -:106630005540FFC7240700010A000DB630FF00FFD8 -:106640009382000427BDFFE0AFBF00181040000F89 -:10665000008050218F880024240B00058F890008BA -:10666000910700008F8400200100282130E3003FC3 -:106670008F86002C106B000800003821AFA9001095 -:106680000E00040EAFAA0014A38000048FBF0018F0 -:1066900003E0000827BD00208D1900183C0F0800FA -:1066A0008DEF3D748F9800103C027FFF8D08001421 -:1066B000345FFFFF033F682401F8702101AE6023BF -:1066C00001883821AFA900100E00040EAFAA0014F3 -:1066D0000A000E04A38000048F8700243C050800F4 -:1066E00094A53D923C0208008C423D8C90E6000D42 -:1066F0000005240030C300201060002C0044402519 -:106700008F85001C00006021240B000190A30085F0 -:1067100000004821240A00013C0F800035EE007083 -:106720008DC70000AF8700308F5801780700FFFE4B -:106730003C038000347900708F3800003C0508006D -:106740008CA500743C0D08008DAD00700307782304 -:1067500000AF38210000102100EF302B01A22021D2 -:10676000008618213C010800AC2700743C01080099 -:10677000AC230070AF4B01483C1908008F393D94A1 -:10678000A7490144A74A0146AF59014C3C0B0800F8 -:10679000916B3D91A34B0152AF4801543C0810004E -:1067A000A74C015803E00008AF4801788F4B0E1C3E -:1067B0003C0A08008D4A3D7497490E16974D0E14F9 -:1067C00001456021312AFFFF0A000E2731A9FFFF92 -:1067D0008F8300249064000D308200201040002937 -:1067E000000000000000482100005021000040216E -:1067F0003C07800034EB00708D670000AF870030ED -:106800008F4C01780580FFFE3C0D800035AC007098 -:106810008D8B00003C0508008CA500743C0408002A -:106820008C8400700167302300A6782100001021BD -:1068300001E6C82B0082C021031970213C01080029 -:10684000AC2F00743C010800AC2E0070AF49014829 -:106850003C0D08008DAD3D94A7480144240900403B -:10686000A74A01463C081000240AFF91AF4D014C95 -:10687000A34A0152AF490154A740015803E0000860 -:10688000AF4801788F490E1897460E1297450E10A3 -:1068900030CAFFFF0A000E5D30A8FFFF8F8300247F -:1068A00027BDFFF89064000D308200201040003AB0 -:1068B00000000000240B000100004821240A000110 -:1068C0003C088000350700708CE30000AF83003087 -:1068D0008F4C01780580FFFE3C0E80003C040800D0 -:1068E00090843DD035C700708CEC00003C0508005A -:1068F0008CA50074A3A400033C1908008F39007014 -:106900008FAD00000183302300A638210000102144 -:106910000322782100E6C02B01F8602101AE40255A -:10692000AFA800003C010800AC2700743C0108003F -:10693000AC2C00709346010A3C04080090843DD1C1 -:10694000A3A00002A3A600018FA300003C0580FFC6 -:106950003099007F34A2FFFF006278240019C6003E -:1069600001F87025240D3000AF4E014C27BD000802 -:10697000AF4D0154A7400158AF4B0148A74901440E -:10698000A74A01463C091000240AFF80A34A01528D -:1069900003E00008AF4901788F4B0E1897460E129E -:1069A00097450E1030CAFFFF0A000E9130A9FFFF75 -:1069B0008F85001C2402008090A40085308300C0D5 -:1069C000106200058F8600208F8800088F87000CDA -:1069D000ACC800C8ACC700C403E000080000000059 -:1069E0003C0A0800254A39543C09080025293A2068 -:1069F0003C08080025082DD43C07080024E73B3458 -:106A00003C06080024C637C43C05080024A5353CD4 -:106A10003C040800248431643C0308002463385C8F -:106A20003C020800244236303C010800AC2A3D50AC -:106A30003C010800AC293D4C3C010800AC283D4815 -:106A40003C010800AC273D543C010800AC263D64E5 -:106A50003C010800AC253D5C3C010800AC243D58DD -:106A60003C010800AC233D683C010800AC223D60BD -:086A700003E000080000000033 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex deleted file mode 100644 index 05e710248d2c234158970590e9fae9cc6713a013..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex +++ /dev/null @@ -1,6512 +0,0 @@ -:10000000080001180800000000005594000000C816 -:1000100000000000000000000000000008005594EF -:10002000000000380000565C080000A00800000036 -:100030000000574400005694080059200000008436 -:100040000000ADD808005744000001C00000AE5CBD -:100050000800321008000000000092340000B01CBC -:1000600000000000000000000000000008009234C2 -:100070000000033C00014250080004900800040006 -:10008000000012FC0001458C000000000000000090 -:1000900000000000080016FC000000040001588861 -:1000A000080000A80800000000003D000001588C76 -:1000B00000000000000000000000000008003D00FB -:0800C000000000300001958CE6 -:0800C8000A00004600000000E0 -:1000D000000000000000000D636F6D362E322E31DF -:1000E00061000000060201020000000000000003A1 -:1000F000000000C800000032000000030000000003 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E0000000000010000003000000000000000DEF -:1001F0000000000D3C020800244256083C030800A1 -:1002000024635754AC4000000043202B1480FFFDB2 -:10021000244200043C1D080037BD9FFC03A0F021D0 -:100220003C100800261001183C1C0800279C5608AA -:100230000E000256000000000000000D27BDFFB4B4 -:10024000AFA10000AFA20004AFA30008AFA4000C50 -:10025000AFA50010AFA60014AFA70018AFA8001CF0 -:10026000AFA90020AFAA0024AFAB0028AFAC002C90 -:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 -:10028000AFB90040AFBC0044AFBF00480E001544FA -:10029000000000008FBF00488FBC00448FB90040B1 -:1002A0008FB8003C8FAF00388FAE00348FAD003078 -:1002B0008FAC002C8FAB00288FAA00248FA90020C0 -:1002C0008FA8001C8FA700188FA600148FA5001000 -:1002D0008FA4000C8FA300088FA200048FA1000040 -:1002E00027BD004C3C1B60108F7A5030377B502864 -:1002F00003400008AF7A00008F82002427BDFFE092 -:10030000AFB00010AFBF0018AFB100148C42000CAA -:100310003C1080008E110100104000348FBF001887 -:100320000E000D84000000008F85002024047FFF54 -:100330000091202BACB100008E030104960201084D -:1003400000031C003042FFFF00621825ACA300042C -:100350009202010A96030114304200FF3063FFFF4E -:100360000002140000431025ACA200089603010C03 -:100370009602010E00031C003042FFFF00621825A8 -:10038000ACA3000C960301109602011200031C009E -:100390003042FFFF00621825ACA300108E02011846 -:1003A000ACA200148E02011CACA20018148000083C -:1003B0008F820024978200003C0420050044182509 -:1003C00024420001ACA3001C0A0000C6A782000062 -:1003D0003C0340189442001E00431025ACA2001CB0 -:1003E0000E000DB8240400018FBF00188FB1001457 -:1003F0008FB000100000102103E0000827BD00208E -:100400003C0780008CE202B834E50100044100089A -:10041000240300013C0208008C42006024420001D9 -:100420003C010800AC22006003E0000800601021DD -:100430003C0208008C42005C8CA4002094A30016AF -:100440008CA6000494A5000E24420001ACE40280B6 -:100450002463FFFC3C010800AC22005C3C0210005D -:10046000A4E30284A4E5028600001821ACE6028819 -:10047000ACE202B803E000080060102127BDFFE0F5 -:100480003C028000AFB0001034420100AFBF001C3E -:10049000AFB20018AFB100148C43000094450008BF -:1004A0002462FE002C42038110400003000381C23D -:1004B0000A00010226100004240201001462000553 -:1004C0003C1180003C02800890420004305000FF44 -:1004D0003C11800036320100964300143202000FB6 -:1004E00000021500004310253C0308008C63004403 -:1004F00030A40004AE220080246300013C01080007 -:10050000AC2300441080000730A200028FBF001C03 -:100510008FB200188FB100148FB000100A0000CE07 -:1005200027BD00201040002D0000182130A20080BF -:1005300010400005362200708E44001C0E000C672F -:10054000240500A0362200708C4400008F82000C2D -:10055000008210232C43012C10600004AF82001095 -:10056000240300010A000145AF84000C8E42000400 -:100570003C036020AF84000CAC6200143C02080015 -:100580008C42005850400015000018218C62000475 -:10059000240301FE304203FF144300100000182121 -:1005A0002E020004104000032E0200080A00014041 -:1005B0000000802114400003000000000A000140F8 -:1005C0002610FFF90000000D2402000202021004B0 -:1005D0003C036000AC626914000018218FBF001C4E -:1005E0008FB200188FB100148FB00010006010217E -:1005F00003E0000827BD00203C0480008C8301003C -:1006000024020100506200033C0280080000000D3B -:100610003C02800890430004000010213063000F6A -:1006200000031D0003E00008AC8300800004188074 -:100630002782FF9C00621821000410C00044102390 -:100640008C640000000210C03C030800246356E4E0 -:10065000004310213C038000AC64009003E00008DC -:10066000AF8200243C0208008C42011410400019A3 -:100670003084400030A2007F000231C03C02020002 -:100680001080001400A218253C026020AC43001426 -:100690003C0408008C8456B83C0308008C630110AD -:1006A0003C02800024050900AC4500200086202182 -:1006B000246300013C028008AC4400643C01080053 -:1006C000AC2301103C010800AC2456B803E000083C -:1006D000000000003C02602003E00008AC4500146C -:1006E00003E000080000102103E0000800001021D2 -:1006F00030A2000810400008240201003C0208005B -:100700008C42010C244200013C010800AC22010C87 -:1007100003E0000800000000148200080000000050 -:100720003C0208008C4200FC244200013C0108000D -:10073000AC2200FC0A0001A330A200203C02080009 -:100740008C420084244200013C010800AC22008459 -:1007500030A200201040000830A200103C02080027 -:100760008C420108244200013C010800AC2201082F -:1007700003E0000800000000104000080000000036 -:100780003C0208008C420104244200013C010800A4 -:10079000AC22010403E00008000000003C02080055 -:1007A0008C420100244200013C010800AC220100FF -:1007B00003E000080000000027BDFFE0AFB1001417 -:1007C0003C118000AFB20018AFBF001CAFB00010EA -:1007D0003632010096500008320200041040000733 -:1007E000320300028FBF001C8FB200188FB10014BB -:1007F0008FB000100A0000CE27BD00201060000B53 -:10080000020028218E2401000E00018A0000000051 -:100810003202008010400003240500A10E000C6786 -:100820008E44001C0A0001E3240200018E2301040F -:100830008F82000810430006020028218E24010048 -:100840000E00018A000000008E220104AF82000821 -:10085000000010218FBF001C8FB200188FB1001450 -:100860008FB0001003E0000827BD00202C82000498 -:1008700014400002000018212483FFFD240200021E -:10088000006210043C03600003E00008AC626914DD -:1008900027BDFFE0AFBF001CAFB20018AFB100141E -:1008A000AFB000103C048000948201083043700017 -:1008B000240220001062000A2862200154400052E5 -:1008C0008FBF001C24024000106200482402600018 -:1008D0001062004A8FBF001C0A0002518FB200183C -:1008E00034820100904300098C5000189451000C90 -:1008F000240200091062001C0000902128620009F7 -:10090000144000218F8200242402000A5062001249 -:10091000323100FF2402000B1062000F00000000C3 -:100920002402000C146200188F8200243C0208008C -:100930008C4256B824030900AC83002000501021DB -:100940003C038008AC6200643C010800AC2256B84D -:100950000A0002508FBF001C0E0001E900102602A1 -:100960000A0002308F8200240E0001E900102602E6 -:100970003C0380089462001A8C72000C3042FFFF26 -:10098000020280258F8200248C42000C5040001E01 -:100990008FBF001C0E000D84000000003C02800090 -:1009A00034420100944300088F82002400031C009D -:1009B0009444001E8F82002000641825AC50000073 -:1009C00024040001AC510004AC520008AC40000CFF -:1009D000AC400010AC400014AC4000180E000DB844 -:1009E000AC43001C0A0002508FBF001C0E000440E4 -:1009F000000000000A0002508FBF001C0E000C9F78 -:100A0000000000008FBF001C8FB200188FB10014CF -:100A10008FB000100000102103E0000827BD002067 -:100A200027BDFFD8AFB400203C036010AFBF002447 -:100A3000AFB3001CAFB20018AFB10014AFB00010DC -:100A40008C6450002402FF7F3C1408002694563822 -:100A5000008220243484380CAC6450003C028000B6 -:100A6000240300370E0014B0AC4300083C07080014 -:100A700024E70618028010212404001D2484FFFFAF -:100A8000AC4700000481FFFD244200043C02080042 -:100A9000244207C83C010800AC2256403C02080032 -:100AA000244202303C030800246306203C04080072 -:100AB000248403B43C05080024A506F03C06080085 -:100AC00024C62C9C3C010800AC2256803C02080045 -:100AD000244205303C010800AC2756843C01080044 -:100AE000AC2656943C010800AC23569C3C010800FF -:100AF000AC2456A03C010800AC2556A43C010800DB -:100B0000AC2256A83C010800AC23563C3C0108002E -:100B1000AC2456443C010800AC2056603C0108005F -:100B2000AC2556643C010800AC2056703C0108001E -:100B3000AC27567C3C010800AC2656903C010800CE -:100B4000AC2356980E00056E00000000AF80000C2C -:100B50003C0280008C5300008F8300043C0208009C -:100B60008C420020106200213262000700008821C0 -:100B70002792FF9C3C100800261056E43C02080017 -:100B80008C42002024050001022518040043202483 -:100B90008F820004004310245044000C26310001D1 -:100BA00010800008AF9000248E4300003C028000BB -:100BB000AC4300900E000D4BAE05000C0A0002C1C4 -:100BC00026310001AE00000C263100012E22000269 -:100BD000261000381440FFE9265200043C020800A9 -:100BE0008C420020AF820004326200071040FFD91F -:100BF0003C028000326200011040002D326200028F -:100C00003C0580008CA2010000002021ACA2002045 -:100C10008CA301042C42078110400008ACA300A85B -:100C200094A2010824032000304270001443000302 -:100C30003C02800890420005304400FF0E0001593C -:100C4000000000003C0280009042010B304300FF96 -:100C50002C62001E54400004000310800E00018628 -:100C60000A0002EC00000000005410218C42000039 -:100C70000040F80900000000104000043C02800021 -:100C80008C4301043C026020AC4300143C02080089 -:100C90008C4200343C0440003C03800024420001AC -:100CA000AC6401383C010800AC220034326200021E -:100CB00010400010326200043C1080008E0201409F -:100CC000000020210E000159AE0200200E00038317 -:100CD000000000003C024000AE0201783C02080027 -:100CE0008C420038244200013C010800AC2200384C -:100CF000326200041040FF973C0280003C108000EC -:100D00008E020180000020210E000159AE02002059 -:100D10008E03018024020F00546200073C02800809 -:100D20008E0201883C0300E03042FFFF00431025A3 -:100D30000A000328AE020080344200809042000086 -:100D400024030050304200FF14430007000000005D -:100D50000E000362000000001440000300000000C9 -:100D60000E000971000000003C0208008C42003CAB -:100D70003C0440003C03800024420001AC6401B804 -:100D80003C010800AC22003C0A0002A33C028000A7 -:100D90003C02900034420001008220253C02800089 -:100DA000AC4400203C0380008C6200200440FFFE25 -:100DB0000000000003E00008000000003C0280008A -:100DC000344300010083202503E00008AC440020E8 -:100DD00027BDFFE0AFB10014AFB000100080882144 -:100DE000AFBF00180E00033230B000FF8F83FF94B6 -:100DF000022020219062002502028025A07000259B -:100E00008C7000183C0280000E00033D020280241A -:100E10001600000B8FBF00183C0480008C8201F884 -:100E20000440FFFE348201C024030002AC510000E4 -:100E3000A04300043C021000AC8201F88FBF0018F0 -:100E40008FB100148FB0001003E0000827BD002010 -:100E500027BDFFE83C028000AFBF00103442018094 -:100E6000944300048C4400083063020010600005C5 -:100E7000000028210E00100C000000000A0003787A -:100E8000240500013C02FF000480000700821824B2 -:100E90003C02040014620004240500018F82FF94C8 -:100EA00090420008240500018FBF001000A010210F -:100EB00003E0000827BD00188F82FF982405000179 -:100EC000A040001A3C028000344201400A00034264 -:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E -:100EE000AFB20018AFB10014AFB0001090A2000074 -:100EF000304400FF38830020388200300003182B74 -:100F00000002102B0062182410600003240200501D -:100F1000148200A88FBF001C90A20005304200017F -:100F2000104000A48FBF001C3C02800034420140EE -:100F3000904200082443FFFF2C6200051040009EF1 -:100F40008FB20018000310803C030800246355ACE6 -:100F5000004310218C420000004000080000000007 -:100F60003C028000345101400E0003328E24000008 -:100F70008F92FF948E2200048E50000C1602000205 -:100F800024020001AE42000C0E00033D8E2400003E -:100F90008E220004145000068FBF001C8FB2001870 -:100FA0008FB100148FB000100A000F7827BD002009 -:100FB0008E42000C0A000419000000003C0480006E -:100FC0003482014094A300108C4200043063FFFF80 -:100FD0001443001C0000000024020001A4A2001021 -:100FE0008C8202380441000F3C0380003C02003F29 -:100FF0003448F0003C0760003C06FFC08CE22BBC8C -:1010000000461824004810240002130200031D8229 -:10101000106200583C0280008C8202380440FFF7C6 -:101020003C038000346201408C44000034620200C2 -:10103000AC4400003C021000AC6202380A00043BE1 -:101040008FBF001C94A200100A00041900000000C9 -:10105000240200201482000F3C0280003C03800028 -:1010600094A20012346301408C6300043042FFFFFD -:10107000146200050000000024020001A4A2001276 -:101080000A0004028FBF001C94A200120A00041977 -:1010900000000000345101400E0003328E24000095 -:1010A0008F92FF948E230004964200123050FFFF6F -:1010B0001603000224020001A64200120E00033DA6 -:1010C0008E2400008E220004160200068FBF001C32 -:1010D0008FB200188FB100148FB000100A00037C8B -:1010E00027BD0020964200120A00041900000000EB -:1010F0003C03800094A20014346301408C6300041C -:101100003042FFFF14620008240200018FBF001C60 -:101110008FB200188FB100148FB00010A4A2001479 -:101120000A00146327BD002094A20014144000217B -:101130008FBF001C0A000435000000003C03800043 -:1011400094A20016346301408C6300043042FFFF18 -:101150001462000D240200018FBF001C8FB2001822 -:101160008FB100148FB00010A4A200160A000B1457 -:1011700027BD00209442007824420004A4A200105D -:101180000A00043B8FBF001C94A200162403000138 -:101190003042FFFF144300078FBF001C3C020800D1 -:1011A0008C420070244200013C010800AC22007017 -:1011B0008FBF001C8FB200188FB100148FB00010C9 -:1011C00003E0000827BD002027BDFFD8AFB20018FC -:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB -:1011E000AFB000103C028000345101008C5001006F -:1011F0009242000092230009304400FF2402001FA5 -:10120000106200AB28620020104000192402003850 -:101210002862000A1040000D2402000B286200081A -:101220001040002E8F820024046001042862000216 -:101230001440002A8F820024240200061062002637 -:101240008FBF00200A00055F8FB3001C1062006092 -:101250002862000B144000FA8FBF00202402000E09 -:10126000106200788F8200240A00055F8FB3001C93 -:10127000106200D2286200391040000A2402008067 -:1012800024020036106200E528620037104000C3D7 -:1012900024020035106200D98FBF00200A00055FCC -:1012A0008FB3001C1062002D2862008110400006E0 -:1012B000240200C824020039106200C98FBF002038 -:1012C0000A00055F8FB3001C106200A28FBF0020D0 -:1012D0000A00055F8FB3001C8F8200248C42000C33 -:1012E000104000D78FBF00200E000D8400000000CA -:1012F0003C038000346301008C6200008F85002075 -:10130000946700089466000CACA200008C64000492 -:101310008F82002400063400ACA400049448001E10 -:101320008C62001800073C0000E83825ACA20008D9 -:101330008C62001C24040001ACA2000C9062000A24 -:1013400000C23025ACA60010ACA00014ACA0001860 -:10135000ACA7001C0A00051D8FBF00208F8200244F -:101360008C42000C104000B68FBF00200E000D8490 -:10137000000000008F820024962400089625000CAF -:101380009443001E000422029626000E8F82002045 -:10139000000426000083202500052C003C0300806B -:1013A00000A6282500832025AC400000AC400004A6 -:1013B000AC400008AC40000CAC450010AC40001440 -:1013C000AC400018AC44001C0A00051C24040001B9 -:1013D0009622000C14400018000000009242000504 -:1013E0003042001014400014000000000E000332D0 -:1013F0000200202192420005020020213442001008 -:101400000E00033DA242000592420000240300208A -:10141000304200FF10430089020020218FBF0020CE -:101420008FB3001C8FB200188FB100148FB0001062 -:101430000A00107527BD00280000000D0A00055E97 -:101440008FBF00208C42000C1040007D8FBF002019 -:101450000E000D84000000008E2200048F84002006 -:101460009623000CAC8200003C0280089445002CBE -:101470008F82002400031C0030A5FFFF9446001E4D -:101480003C02400E0065182500C23025AC830004E4 -:10149000AC800008AC80000CAC800010AC80001464 -:1014A000AC800018AC86001C0A00051C2404000156 -:1014B0000E000332020020218F93FF9802002021AA -:1014C0000E00033DA660000C020020210E00034226 -:1014D000240500018F8200248C42000C104000582B -:1014E0008FBF00200E000D84000000009622000C2B -:1014F0008F83002000021400AC700000AC62000476 -:10150000AC6000088E4400388F820024AC64000C6C -:101510008E46003C9445001E3C02401FAC66001005 -:1015200000A228258E62000424040001AC6200148D -:10153000AC600018AC65001C8FBF00208FB3001C8E -:101540008FB200188FB100148FB000100A000DB8D0 -:1015500027BD0028240200201082003A8FB3001C0F -:101560000E000F5E00000000104000358FBF00200D -:101570003C0480008C8201F80440FFFE348201C0EC -:1015800024030002AC500000A04300043C02100001 -:10159000AC8201F80A00055E8FBF00200200202106 -:1015A0008FBF00208FB3001C8FB200188FB10014C2 -:1015B0008FB000100A000EA727BD00289625000C4A -:1015C000020020218FBF00208FB3001C8FB20018B3 -:1015D0008FB100148FB000100A000ECC27BD002878 -:1015E000020020218FB3001C8FB200188FB10014AD -:1015F0008FB000100A000EF727BD00289225000DBD -:10160000020020218FB3001C8FB200188FB100148C -:101610008FB000100A000F4827BD002802002021CB -:101620008FBF00208FB3001C8FB200188FB1001441 -:101630008FB000100A000F1F27BD00288FBF0020A9 -:101640008FB3001C8FB200188FB100148FB0001040 -:1016500003E0000827BD00283C0580008CA202782A -:101660000440FFFE34A2024024030002AC44000008 -:10167000A04300043C02100003E00008ACA2027882 -:10168000A380001803E00008A38000193C03800039 -:101690008C6202780440FFFE8F82001CAC62024024 -:1016A00024020002A06202443C02100003E0000891 -:1016B000AC6202783C02600003E000088C425404F3 -:1016C0009083003024020005008040213063003FF9 -:1016D0000000482114620005000050219082004C57 -:1016E0009483004E304900FF306AFFFFAD00000CCC -:1016F000AD000010AD000024950200148D05001C03 -:101700008D0400183042FFFF004910230002110031 -:10171000000237C3004038210086202300A2102B8E -:101720000082202300A72823AD05001CAD0400186B -:10173000A5090014A5090020A50A001603E0000869 -:10174000A50A002203E000080000000027BDFFD822 -:10175000AFB200183C128008AFB40020AFB3001C39 -:10176000AFB10014AFBF0024AFB00010365101007C -:101770003C0260008C4254049222000C3C1408008D -:10178000929400F7304300FF2402000110620032FF -:101790000080982124020002146200353650008037 -:1017A0000E00143D000000009202004C2403FF8054 -:1017B0003C0480003042007F000211C024420240FD -:1017C0000262102100431824AC8300949245000863 -:1017D0009204004C3042007F3C03800614850007D1 -:1017E000004380212402FFFFA22200112402FFFFF8 -:1017F000A62200120A0005D22402FFFF9602002052 -:10180000A222001196020022A62200128E020024BB -:101810003C048008AE2200143485008090A2004C65 -:1018200034830100A06200108CA2003CAC6200185E -:101830008C820068AC6200F48C820064AC6200F0C0 -:101840008C82006CAC6200F824020001A0A2006847 -:101850000A0005EE3C0480080E001456000000004B -:1018600036420080A04000680A0005EE3C04800873 -:10187000A2000068A20000690A0006293C02800854 -:10188000348300808C62003834850100AC62006CC7 -:1018900024020001A062006990A200D59083000894 -:1018A000305100FF3072007F12320019001111C058 -:1018B00024420240026210212403FF8000431824C6 -:1018C0003C048000AC8300943042007F3C038006DF -:1018D000004380218E02000C1040000D02002021E8 -:1018E0000E00057E0000000026220001305100FF9E -:1018F0009203003C023410260002102B0002102339 -:101900003063007F022288240A0005F8A203003C0D -:101910003C088008350401008C8200E03507008017 -:10192000ACE2003C8C8200E0AD02000090E5004C8F -:10193000908600D590E3004C908400D52402FF806F -:1019400000A228243063007F308400FF00A62825F1 -:101950000064182A1060000230A500FF38A500803E -:10196000A0E5004CA10500093C0280089043000E50 -:10197000344400803C058000A043000A8C8300189A -:101980003C027FFF3442FFFF00621824AC83001842 -:101990008CA201F80440FFFE00000000ACB301C0BF -:1019A0008FBF00248FB400208FB3001C8FB20018AB -:1019B0008FB100148FB0001024020002A0A201C455 -:1019C00027BD00283C02100003E00008ACA201F88B -:1019D00090A2000024420001A0A200003C030800E5 -:1019E0008C6300F4304200FF144300020080302179 -:1019F000A0A0000090A200008F84001C000211C073 -:101A00002442024024830040008220212402FF80DF -:101A1000008220243063007F3C02800A006218218B -:101A20003C028000AC44002403E00008ACC300008A -:101A300094820006908300058C85000C8C86001033 -:101A40008C8700188C88001C8C8400203C010800C6 -:101A5000A42256C63C010800A02356C53C0108003C -:101A6000AC2556CC3C010800AC2656D03C01080001 -:101A7000AC2756D83C010800AC2856DC3C010800D5 -:101A8000AC2456E003E00008000000003C0280089F -:101A9000344201008C4400343C038000346504006F -:101AA000AC6400388C420038AF850028AC62003C42 -:101AB0003C020005AC6200300000000000000000A5 -:101AC00003E00008000000003C020006308400FF34 -:101AD000008220253C028000AC4400300000000061 -:101AE00000000000000000003C0380008C62000049 -:101AF000304200101040FFFD3462040003E0000893 -:101B0000AF82002894C200003C080800950800CA73 -:101B100030E7FFFF0080482101021021A4C200002D -:101B200094C200003042FFFF00E2102B544000013D -:101B3000A4C7000094A200003C0308008C6300CC02 -:101B400024420001A4A2000094A200003042FFFF42 -:101B5000144300073C0280080107102BA4A00000DA -:101B60005440000101003821A4C700003C02800855 -:101B7000344601008CC3002894A200003C0480007D -:101B80003042FFFE000210C000621021AC82003C17 -:101B90008C82003C006218231860000400000000E2 -:101BA0008CC200240A0006BA244200018CC2002420 -:101BB000AC8200383C020050344200103C038000EC -:101BC000AC620030000000000000000000000000D7 -:101BD0008C620000304200201040FFFD0000000039 -:101BE00094A200003C04800030420001000210C0BA -:101BF000004410218C430400AD2300008C420404F7 -:101C0000AD2200043C02002003E00008AC8200305A -:101C100027BDFFE0AFB20018AFB10014AFB00010A5 -:101C2000AFBF001C94C2000000C080213C1208001D -:101C3000965200C624420001A6020000960300004E -:101C400094E2000000E03021144300058FB1003021 -:101C50000E00068F024038210A0006F10000000045 -:101C60008C8300048C82000424420040046100073D -:101C7000AC8200048C8200040440000400000000D8 -:101C80008C82000024420001AC8200009602000019 -:101C90003042FFFF50520001A600000096220000D3 -:101CA00024420001A62200003C02800834420100C8 -:101CB000962300009442003C144300048FBF001C94 -:101CC00024020001A62200008FBF001C8FB2001862 -:101CD0008FB100148FB0001003E0000827BD002072 -:101CE00027BDFFE03C028008AFBF0018344201006E -:101CF0008C4800343C03800034690400AC68003830 -:101D00008C42003830E700FFAF890028AC62003C0D -:101D10003C020005AC620030000000000000000042 -:101D200000000000000000000000000000000000B3 -:101D30008C82000C8C82000C97830016AD22000070 -:101D40008C82001000604021AD2200048C820018BB -:101D5000AD2200088C82001CAD22000C8CA2001465 -:101D6000AD2200108C820020AD220014908200056C -:101D7000304200FF00021200AD2200188CA20018B1 -:101D8000AD22001C8CA2000CAD2200208CA2001001 -:101D9000AD2200248CA2001CAD2200288CA20020C1 -:101DA000AD22002C3402FFFFAD260030AD20003400 -:101DB000506200013408FFFFAD28003850E00011E8 -:101DC0003C0280083C048008348401009482005066 -:101DD0003042FFFFAD22003C9483004494850044D0 -:101DE000240200013063FFFF000318C200641821C1 -:101DF0009064006430A5000700A210040A00075C8C -:101E00000044102534420100AD20003C94430044BE -:101E1000944400443063FFFF000318C2006218219D -:101E200030840007906500642402000100821004E1 -:101E30000002102700451024A0620064000000008A -:101E400000000000000000003C0200063442004098 -:101E50003C038000AC620030000000000000000085 -:101E6000000000008C620000304200101040FFFDB6 -:101E70003C06800834C201503463040034C7014A70 -:101E800034C4013434C5014034C60144AFA200104B -:101E90000E0006D2AF8300288FBF001803E00008B1 -:101EA00027BD00208F8300143C0608008CC600E884 -:101EB0008F82001C30633FFF000319800046102111 -:101EC000004310212403FF80004318243C068000B7 -:101ED000ACC300283042007F3C03800C004330211B -:101EE00090C2000D30A500FF0000382134420010E0 -:101EF000A0C2000D8F8900143C028008344201000A -:101F00009443004400091382304800032402000176 -:101F1000A4C3000E1102000B2902000210400005AC -:101F2000240200021100000C240300010A0007A48F -:101F30000000182111020006000000000A0007A49A -:101F4000000018218CC2002C0A0007A424430001C1 -:101F50008CC20014244300018CC200180043102BD3 -:101F60005040000A240700012402002714A20003A5 -:101F70003C0380080A0007B1240700013463010014 -:101F80009462004C24420001A462004C00091382B8 -:101F9000304300032C620002104000090080282119 -:101FA000146000040000000094C200340A0007C15D -:101FB0003046FFFF8CC600380A0007C10080282188 -:101FC000000030213C040800248456C00A000706A3 -:101FD0000000000027BDFF90AFB60068AFB50064F9 -:101FE000AFB40060AFB3005CAFB20058AFB1005403 -:101FF000AFBF006CAFB000508C9000000080B021EB -:102000003C0208008C4200E8960400328F83001CDA -:102010002414FF8030843FFF0062182100042180D7 -:1020200000641821007410243C13800000A090214B -:1020300090A50000AE620028920400323C02800CA1 -:102040003063007F00628821308400C02402004099 -:10205000148200320000A8218E3500388E2200182C -:102060001440000224020001AE2200189202003C3B -:10207000304200201440000E8F83001C000511C068 -:102080002442024000621821306400783C02008043 -:102090000082202500741824AE630800AE64081086 -:1020A0008E2200188E03000800431021AE22001873 -:1020B0008E22002C8E230018244200010062182B6F -:1020C0001060004300000000924200002442000122 -:1020D000A24200003C0308008C6300F4304200FF81 -:1020E00050430001A2400000924200008F84001C77 -:1020F000000211C024420240248300403063007F6C -:10210000008220213C02800A0094202400621821D1 -:10211000AE6400240A0008D2AEC30000920300326D -:102120002402FFC000431024304200FF1440000589 -:1021300024020001AE220018962200340A00084250 -:102140003055FFFF8E22001424420001AE220018F9 -:102150009202003000021600000216030441001C27 -:10216000000000009602003227A400100080282101 -:10217000A7A20016960200320000302124070001B9 -:102180003042FFFFAF8200140E000706AFA0001C14 -:10219000960200328F83001C3C0408008C8400E807 -:1021A00030423FFF000211800064182100621821B4 -:1021B00000741024AE62002C3063007F3C02800E5D -:1021C000006218219062000D3042007FA062000D75 -:1021D0009222000D304200105040007892420000E0 -:1021E0003C028008344401009482004C8EC30000FD -:1021F0003C130800967300C62442FFFFA482004CE3 -:10220000946200329623000E3054FFFF3070FFFFBF -:102210003C0308008C6300D000701807A7A30038A7 -:102220009482003E3063FFFF3042FFFF14620007DC -:10223000000000008C8200303C038000244200300B -:10224000AC62003C0A00086A8C82002C9482004038 -:102250003042FFFF5462000927A400408C820038FE -:102260003C03800024420030AC62003C8C8200348D -:10227000AC6200380A0008793C03800027A50038CA -:1022800027A60048026038210E00068FA7A000484C -:102290008FA300403C02800024630030AC43003830 -:1022A0008FA30044AC43003C3C0380003C0200058B -:1022B000AC6200303C028008344401009482004249 -:1022C000346304003042FFFF0202102B1440000769 -:1022D000AF8300289482004E9483004202021021B2 -:1022E000004310230A00088F3043FFFF9483004E01 -:1022F00094820042026318210050102300621823C8 -:102300003063FFFF3C028008344401009482003CAB -:102310003042FFFF14430003000000000A00089F42 -:10232000240300019482003C3042FFFF0062102B26 -:10233000144000058F8200289482003C0062102324 -:102340003043FFFF8F820028AC550000AC400004F2 -:10235000AC540008AC43000C3C02000634420010B0 -:102360003C038000AC620030000000000000000070 -:10237000000000008C620000304200101040FFFDA1 -:102380003C04800834840100001018C20064182145 -:102390009065006432020007240600010046100424 -:1023A00000451025A0620064948300429622000E2E -:1023B00050430001A386001892420000244200010D -:1023C000A24200003C0308008C6300F4304200FF8E -:1023D00050430001A2400000924200008F84001C84 -:1023E000000211C0244202402483004000822021C8 -:1023F0002402FF80008220243063007F3C02800A98 -:10240000006218213C028000AC440024AEC30000EE -:102410008FBF006C8FB600688FB500648FB400600A -:102420008FB3005C8FB200588FB100548FB0005052 -:1024300003E0000827BD007027BDFFD8AFB3001C24 -:10244000AFB20018AFB10014AFB00010AFBF0020A2 -:102450000080982100E0802130B1FFFF0E000D8444 -:1024600030D200FF0000000000000000000000006B -:102470008F8200208F830024AC510000AC520004F6 -:10248000AC530008AC40000CAC400010AC40001451 -:10249000AC4000189463001E02038025AC50001C61 -:1024A0000000000000000000000000002404000103 -:1024B0008FBF00208FB3001C8FB200188FB10014A3 -:1024C0008FB000100A000DB827BD002830A5FFFF0F -:1024D0000A0008DC30C600FF3C02800834430100DB -:1024E0009462000E3C080800950800C63046FFFFC5 -:1024F00014C000043402FFFF946500EA0A000929B1 -:102500008F84001C10C20027000000009462004E5F -:102510009464003C3045FFFF00A6102300A6182B52 -:102520003087FFFF106000043044FFFF00C5102318 -:1025300000E210233044FFFF0088102B1040000EF3 -:1025400000E810233C028008344401002403000109 -:1025500034420080A44300162402FFFFA482000E30 -:10256000948500EA8F84001C0000302130A5FFFF15 -:102570000A0009013C0760200044102A10400009AD -:102580003C0280083443008094620016304200010F -:10259000104000043C0280009442007E244200145B -:1025A000A462001603E000080000000027BDFFE061 -:1025B0003C028008AFBF001CAFB0001834420100DD -:1025C000944300429442004C104000193068FFFFD1 -:1025D0009383001824020001146200298FBF001C9D -:1025E0003C06800834D00100000810C200501021C1 -:1025F000904200643103000734C70148304200FFB5 -:10260000006210073042000134C9014E34C4012C6D -:1026100034C5013E1040001634C601420E0006D2F9 -:10262000AFA90010960200420A0009463048FFFF99 -:102630003C028008344401009483004494820042A8 -:102640001043000F8FBF001C94820044A4820042FC -:1026500094820050A482004E8C820038AC820030FC -:1026600094820040A482003E9482004AA4820048E2 -:102670008FBF001C8FB000180A00090427BD00207E -:102680008FB0001803E0000827BD002027BDFFA081 -:10269000AFB1004C3C118000AFBF0058AFB3005445 -:1026A000AFB20050AFB000483626018890C2000398 -:1026B0003044007FA3A400108E32018090C200003D -:1026C0003043007F240200031062003BAF92001CE5 -:1026D00028620004104000062402000424020002C4 -:1026E000106200098FBF00580A000B0F8FB300540F -:1026F0001062004D240200051062014E8FBF005889 -:102700000A000B0F8FB30054000411C002421021C5 -:102710002404FF8024420240004410242643004049 -:10272000AE2200243063007F3C02800A0062182140 -:102730009062003CAFA3003C00441025A062003C26 -:102740008FA3003C9062003C304200401040016C7E -:102750008FBF00583C108008A3800018361001007D -:102760008E0200E08C63003427A4003C27A50010F3 -:10277000004310210E0007C3AE0200E093A2001038 -:102780003C038000A20200D58C6202780440FFFE68 -:102790008F82001CAC62024024020002A06202444C -:1027A0003C021000AC6202780E0009390000000003 -:1027B0000A000B0E8FBF00583C05800890C3000133 -:1027C00090A2000B1443014E8FBF005834A4008028 -:1027D0008C8200189082004C90A200083C0260009D -:1027E0008C4254048C8300183C027FFF3442FFFF6C -:1027F000006218243C0208008C4200B4AC8300182C -:102800003C038000244200013C010800AC2200B4DB -:102810008C6201F80440FFFE8F82001CAC6201C094 -:102820000A000AD6240200023C10800890C300016E -:102830009202000B144301328FBF005827A40018E6 -:1028400036050110240600033C0260008C4254044B -:102850000E000E470000000027A40028360501F0F6 -:102860000E000E47240600038FA200283603010045 -:10287000AE0200648FA2002CAE0200688FA200306E -:10288000AE02006C93A40018906300D52402FF8070 -:102890000082102400431025304900FF3084007F5F -:1028A0003122007F0082102A544000013929008023 -:1028B000000411C0244202402403FF800242102180 -:1028C00000431024AE220094264200403042007F94 -:1028D0003C038006004340218FA3001C2402FFFF1D -:1028E000AFA800403C130800927300F71062003359 -:1028F00093A2001995030014304400FF3063FFFFDA -:102900000064182B106000100000000095040014F3 -:102910008D07001C8D0600183084FFFF0044202323 -:102920000004210000E438210000102100E4202BE5 -:1029300000C2302100C43021AD07001CAD060018D4 -:102940000A000A2F93A20019950400148D07001C99 -:102950008D0600183084FFFF008220230004210030 -:10296000000010210080182100C2302300E4202B39 -:1029700000C4302300E33823AD07001CAD06001867 -:1029800093A200198FA30040A462001497A2001A1A -:10299000A46200168FA2001CAC6200108FA2001C63 -:1029A000AC62000C93A20019A462002097A2001A46 -:1029B000A46200228FA2001CAC6200243C048008A8 -:1029C000348300808C6200388FA20020012088218F -:1029D000AC62003C8FA20020AC82000093A20018E1 -:1029E000A062004C93A20018A0820009A0600068B9 -:1029F00093A20018105100512407FF803229007F54 -:102A0000000911C024420240024210213046007FDA -:102A10003C03800000471024AC6200943C02800616 -:102A200000C2302190C2003CAFA60040000020212F -:102A300000471025A0C2003C8FA80040950200026C -:102A4000950300148D07001C3042FFFF3063FFFF29 -:102A50008D060018004310230002110000E2382107 -:102A600000E2102B00C4302100C23021AD07001C51 -:102A7000AD06001895020002A5020014A50000167C -:102A80008D020008AD0200108D020008AD02000C9E -:102A900095020002A5020020A50000228D02000878 -:102AA000AD0200249102003C304200401040001A68 -:102AB000262200013C108008A3A90038A38000183A -:102AC000361001008E0200E08D03003427A4004080 -:102AD00027A50038004310210E0007C3AE0200E016 -:102AE00093A200383C038000A20200D58C620278D9 -:102AF0000440FFFE8F82001CAC62024024020002F0 -:102B0000A06202443C021000AC6202780E00093957 -:102B100000000000262200013043007F14730004EF -:102B2000004020212403FF8002231024004320269C -:102B300093A200180A000A4B309100FF93A40018DA -:102B40008FA3001C2402FFFF1062000A308900FFDF -:102B500024820001248300013042007F14530005C9 -:102B6000306900FF2403FF800083102400431026F7 -:102B7000304900FF3C028008904200080120882173 -:102B8000305000FF123000193222007F000211C0C5 -:102B900002421021244202402403FF8000431824F3 -:102BA0003C048000AC8300943042007F3C038006EC -:102BB000004310218C43000C004020211060000BCA -:102BC000AFA200400E00057E000000002623000199 -:102BD0002405FF803062007F145300020225202468 -:102BE000008518260A000AAF307100FF3C048008F7 -:102BF000348400808C8300183C027FFF3442FFFF46 -:102C000000621824AC8300183C0380008C6201F839 -:102C10000440FFFE00000000AC7201C0240200026C -:102C2000A06201C43C021000AC6201F80A000B0E65 -:102C30008FBF00583C04800890C300019082000BB5 -:102C40001443002F8FBF0058349000809202000878 -:102C500030420040104000200000000092020008B6 -:102C60000002160000021603044100050240202164 -:102C70000E000ECC240500930A000B0E8FBF0058E7 -:102C80009202000924030018304200FF1443000D93 -:102C900002402021240500390E000E64000030217E -:102CA0000E0003328F84001C8F82FF9424030012D5 -:102CB000A04300090E00033D8F84001C0A000B0E88 -:102CC0008FBF0058240500360E000E64000030212E -:102CD0000A000B0E8FBF00580E0003320240202165 -:102CE000920200058F84001C344200200E00033D38 -:102CF000A20200050E0010758F84001C8FBF0058C3 -:102D00008FB300548FB200508FB1004C8FB0004889 -:102D100003E0000827BD00603C0280083445010044 -:102D20003C0280008C42014094A3000E0000302140 -:102D300000402021AF82001C3063FFFF3402FFFF00 -:102D4000106200063C0760202402FFFFA4A2000ED0 -:102D500094A500EA0A00090130A5FFFF03E000087E -:102D60000000000027BDFFC83C0280003C06800830 -:102D7000AFB5002CAFB1001CAFBF0030AFB400281E -:102D8000AFB30024AFB20020AFB00018345101003F -:102D900034C501008C4301008E2200148CA400E491 -:102DA0000000A821AF83001C0044102318400052EB -:102DB000A38000188E22001400005021ACA200E471 -:102DC00090C3000890A200D53073007FA3A200102A -:102DD0008CB200E08CB400E4304200FF1053003BA2 -:102DE00093A200108F83001C2407FF80000211C0F3 -:102DF0000062102124420240246300400047102456 -:102E00003063007F3C0980003C08800A006818217C -:102E1000AD2200248C62003427A4001427A50010E2 -:102E2000024280210290102304400028AFA3001426 -:102E30009062003C00E21024304200FF1440001970 -:102E4000020090219062003C34420040A062003CAD -:102E50008F86001C93A3001024C200403042007FE4 -:102E6000004828213C0208008C4200F42463000141 -:102E7000306400FF14820002A3A30010A3A000107E -:102E800093A20010AFA50014000211C0244202401A -:102E900000C2102100471024AD2200240A000B4577 -:102EA00093A200100E0007C3000000003C0280083F -:102EB00034420100AC5000E093A30010240A00014A -:102EC000A04300D50A000B4593A200102402000184 -:102ED000154200093C0380008C6202780440FFFE2A -:102EE0008F82001CAC62024024020002A0620244F5 -:102EF0003C021000AC6202789222000B2403000214 -:102F0000304200FF144300720000000096220008C7 -:102F1000304300FF24020082146200402402008437 -:102F20003C028000344901008D22000C95230006EC -:102F3000000216023063FFFF3045003F24020027E5 -:102F400010A2000FAF83001428A200281040000830 -:102F5000240200312402002110A2000924020025CD -:102F600010A20007938200190A000BBD00000000A8 -:102F700010A20007938200190A000BBD0000000098 -:102F80000E000777012020210A000C3D0000000000 -:102F90003C0380008C6202780440FFFE8F82001C9C -:102FA000AC62024024020002A06202443C02100013 -:102FB000AC6202780A000C3D000000009523000678 -:102FC000912400058D25000C8D2600108D270018FA -:102FD0008D28001C8D290020244200013C0108009E -:102FE000A42356C63C010800A02456C53C01080095 -:102FF000AC2556CC3C010800AC2656D03C0108005C -:10300000AC2756D83C010800AC2856DC3C0108002F -:10301000AC2956E00A000C3DA38200191462000A94 -:10302000240200813C02800834420100944500EAF9 -:10303000922600058F84001C30A5FFFF30C600FFDC -:103040000A000BFE3C0760211462005C00000000D7 -:103050009222000A304300FF306200201040000737 -:10306000306200403C02800834420100944500EA8E -:103070008F84001C0A000BFC24060040104000074F -:10308000000316003C02800834420100944500EA27 -:103090008F84001C0A000BFC24060041000216036A -:1030A000044100463C02800834420100944500EA95 -:1030B0008F84001C2406004230A5FFFF3C076019E6 -:1030C0000E000901000000000A000C3D0000000095 -:1030D0009222000B24040016304200FF1044000628 -:1030E0003C0680009222000B24030017304200FFB0 -:1030F000144300320000000034C5010090A2000B10 -:10310000304200FF1444000B000080218CA20020FC -:103110008CA400202403FF800043102400021140EF -:103120003084007F004410253C032000004310251C -:10313000ACC2083094A2000800021400000214037C -:10314000044200012410000194A2000830420080D3 -:103150005040001A0200A82194A20008304220002A -:10316000504000160200A8218CA300183C021C2D20 -:10317000344219ED106200110200A8213C0208003F -:103180008C4200D4104000053C0280082403000457 -:1031900034420100A04300FC3C028008344201009C -:1031A000944500EA8F84001C2406000630A5FFFF2A -:1031B0000E0009013C0760210200A8210E00093918 -:1031C000000000009222000A304200081040000473 -:1031D00002A010210E0013790000000002A01021AF -:1031E0008FBF00308FB5002C8FB400288FB3002420 -:1031F0008FB200208FB1001C8FB0001803E00008D0 -:1032000027BD00382402FF80008220243C02900069 -:1032100034420007008220253C028000AC4400209C -:103220003C0380008C6200200440FFFE0000000090 -:1032300003E00008000000003C0380002402FF803F -:10324000008220243462000700822025AC64002024 -:103250008C6200200440FFFE0000000003E0000834 -:103260000000000027BDFFD8AFB3001CAFB10014B1 -:10327000AFB00010AFBF0020AFB200183C1180000B -:103280003C0280088E32002034530100AE2400201E -:10329000966300EA000514003C074000004738250B -:1032A00000A08021000030210E0009013065FFFFE1 -:1032B000240200A1160200022402FFFFA2620009FC -:1032C000AE3200208FBF00208FB3001C8FB20018D9 -:1032D0008FB100148FB0001003E0000827BD002854 -:1032E0003C0280082403000527BDFFE834420100AA -:1032F000A04300FCAFBF00103C0280008C420100E4 -:10330000240500A1004020210E000C67AF82001CA4 -:103310003C0380008C6202780440FFFE8F82001C18 -:103320008FBF001027BD0018AC62024024020002CB -:10333000A06202443C021000AC62027803E0000884 -:103340000000000027BDFFE83C068000AFBF001072 -:1033500034C7010094E20008304400FF3883008243 -:10336000388200842C6300012C4200010062182581 -:103370001060002D24020083938200195040003B0E -:103380008FBF00103C020800904256CC8CC4010054 -:103390003C06080094C656C63045003F38A30032AC -:1033A00038A2003F2C6300012C4200010062182566 -:1033B000AF84001CAF860014A380001914600007BE -:1033C00000E020212402002014A2001200000000CE -:1033D0003402FFFF14C2000F00000000240200208E -:1033E00014A2000500E028218CE300142402FFFF52 -:1033F0005062000B8FBF00103C040800248456C0AC -:10340000000030210E000706240700010A000CD638 -:103410008FBF00100E000777000000008FBF001064 -:103420000A00093927BD001814820004240200850F -:103430008CC501040A000CE1000020211482000662 -:103440002482FF808CC50104240440008FBF00103B -:103450000A00016727BD0018304200FF2C4200021D -:1034600010400004240200228FBF00100A000B2726 -:1034700027BD0018148200048F8200248FBF001023 -:103480000A000C8627BD00188C42000C1040001E5C -:1034900000E0282190E300092402001814620003D0 -:1034A000240200160A000CFC240300081462000722 -:1034B00024020017240300123C02800834420080DA -:1034C000A04300090A000D0994A7000854620007F0 -:1034D00094A700088F82FF942404FFFE9043000508 -:1034E00000641824A043000594A7000890A6001BC0 -:1034F0008CA4000094A500068FBF001000073C00BC -:103500000A0008DC27BD00188FBF001003E0000888 -:1035100027BD00188F8500243C04800094A2002A57 -:103520008CA30034000230C02402FFF000C210243B -:1035300000621821AC83003C8CA200303C03800068 -:10354000AC8200383C02005034420010AC620030C3 -:103550000000000000000000000000008C6200007D -:10356000304200201040FFFD30C20008104000062D -:103570003C0280008C620408ACA200208C62040C27 -:103580000A000D34ACA200248C430400ACA300203C -:103590008C420404ACA200243C0300203C028000C6 -:1035A000AC4300303C0480008C8200300043102487 -:1035B0001440FFFD8F8600243C020040AC820030A6 -:1035C00094C3002A94C2002894C4002C94C5002EF1 -:1035D00024630001004410213064FFFFA4C20028CE -:1035E00014850002A4C3002AA4C0002A03E0000836 -:1035F000000000008F84002427BDFFE83C05800404 -:1036000024840010AFBF00100E000E472406000AED -:103610008F840024948200129483002E3042000F85 -:10362000244200030043180424027FFF0043102BB0 -:1036300010400002AC8300000000000D0E000D13CE -:10364000000000008F8300248FBF001027BD0018EA -:10365000946200149463001A3042000F00021500B7 -:10366000006218253C02800003E00008AC4300A083 -:103670008F8300243C028004944400069462001A64 -:103680008C650000A4640016004410233042FFFF44 -:103690000045102B03E00008384200018F8400240D -:1036A0003C0780049486001A8C85000094E2000692 -:1036B000A482001694E3000600C310233042FFFFEB -:1036C0000045102B384200011440FFF8A483001677 -:1036D00003E00008000000008F8400243C02800406 -:1036E000944200069483001A8C850000A482001680 -:1036F000006210233042FFFF0045102B38420001CA -:103700005040000D8F850024006030213C0780046C -:1037100094E20006A482001694E3000600C310237E -:103720003042FFFF0045102B384200011440FFF8E3 -:10373000A48300168F8500243C03800034620400BB -:103740008CA40020AF820020AC6400388CA200243E -:10375000AC62003C3C020005AC62003003E00008B3 -:10376000ACA000048F8400243C0300068C8200047B -:1037700000021140004310253C038000AC62003081 -:103780000000000000000000000000008C6200004B -:10379000304200101040FFFD34620400AC80000491 -:1037A00003E00008AF8200208F86002427BDFFE0E1 -:1037B000AFB10014AFB00010AFBF00188CC300044D -:1037C0008CC500248F820020309000FF94C4001A22 -:1037D00024630001244200202484000124A7002047 -:1037E000ACC30004AF820020A4C4001AACC70024FC -:1037F00004A100060000882104E2000594C2001A1A -:103800008CC2002024420001ACC2002094C2001AE5 -:1038100094C300282E040001004310262C4200010E -:10382000004410245040000594C2001A24020001F4 -:10383000ACC2000894C2001A94C300280010202BC8 -:10384000004310262C4200010044102514400007BC -:10385000000000008CC20008144000042402001084 -:103860008CC300041462000F8F8500240E000DA786 -:10387000241100018F820024944300289442001AEE -:1038800014430003000000000E000D1300000000B0 -:10389000160000048F8500240E000D840000000037 -:1038A0008F85002494A2001E94A4001C24420001D1 -:1038B0003043FFFF14640002A4A2001EA4A0001E57 -:1038C0001200000A3C02800494A2001494A3001A7F -:1038D0003042000F00021500006218253C028000F3 -:1038E000AC4300A00A000E1EACA0000894420006E3 -:1038F00094A3001A8CA40000A4A200160062102356 -:103900003042FFFF0044102B384200011040000DF0 -:1039100002201021006030213C07800494E2000660 -:10392000A4A2001694E3000600C310233042FFFF58 -:103930000044102B384200011440FFF8A4A30016E5 -:10394000022010218FBF00188FB100148FB000101B -:1039500003E0000827BD002003E00008000000008D -:103960008F82002C3C03000600021140004310250A -:103970003C038000AC62003000000000000000004A -:10398000000000008C620000304200101040FFFD7B -:1039900034620400AF82002803E00008AF80002CEE -:1039A00003E000080000102103E000080000000010 -:1039B0003084FFFF30A5FFFF0000182110800007B2 -:1039C000000000003082000110400002000420428C -:1039D000006518210A000E3D0005284003E000089C -:1039E0000060102110C0000624C6FFFF8CA200005A -:1039F00024A50004AC8200000A000E4724840004C1 -:103A000003E000080000000010A0000824A3FFFF4E -:103A1000AC86000000000000000000002402FFFF50 -:103A20002463FFFF1462FFFA2484000403E000080B -:103A3000000000003C0280083442008024030001A2 -:103A4000AC43000CA4430010A4430012A443001490 -:103A500003E00008A44300168F82002427BDFFD88E -:103A6000AFB3001CAFB20018AFB10014AFB000107C -:103A7000AFBF00208C47000C248200802409FF8007 -:103A80003C08800E3043007F008080213C0A80008B -:103A9000004920240068182130B100FF30D200FF17 -:103AA00010E000290000982126020100AD44002CFE -:103AB000004928243042007F004820219062000005 -:103AC00024030050304200FF1443000400000000B3 -:103AD000AD45002C948200EA3053FFFF0E000D84A8 -:103AE000000000008F8200248F83002000112C0032 -:103AF0009442001E001224003484000100A22825F4 -:103B00003C02400000A22825AC7000008FBF0020BE -:103B1000AC6000048FB20018AC7300088FB10014C1 -:103B2000AC60000C8FB3001CAC6400108FB00010B0 -:103B3000AC60001424040001AC60001827BD00280C -:103B40000A000DB8AC65001C8FBF00208FB3001CAD -:103B50008FB200188FB100148FB0001003E000087E -:103B600027BD00283C06800034C201009043000FAE -:103B7000240200101062000E2865001110A000073A -:103B800024020012240200082405003A10620006F4 -:103B90000000302103E0000800000000240500358B -:103BA0001462FFFC000030210A000E6400000000D7 -:103BB0008CC200748F83FF9424420FA003E000089E -:103BC000AC62000C27BDFFE8AFBF00100E0003423F -:103BD000240500013C0480088FBF0010240200016E -:103BE00034830080A462001227BD00182402000163 -:103BF00003E00008A080001A27BDFFE0AFB2001864 -:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 -:103C10000E000332008088213C028008345000806E -:103C20009202000924030004304200FF1443000CF8 -:103C30003C028008124000082402000A0E000E5BBD -:103C400000000000920200052403FFFE0043102440 -:103C5000A202000524020012A20200093C02800810 -:103C600034420080022020210E00033DA0400027A6 -:103C700016400003022020210E000EBF00000000AD -:103C800002202021324600FF8FBF001C8FB2001897 -:103C90008FB100148FB00010240500380A000E64A4 -:103CA00027BD002027BDFFE0AFBF001CAFB200184A -:103CB000AFB10014AFB000100E00033200808021BD -:103CC0000E000E5B000000003C02800834450080BE -:103CD00090A2000924120018305100FF1232000394 -:103CE0000200202124020012A0A2000990A20005D7 -:103CF0002403FFFE004310240E00033DA0A2000594 -:103D00000200202124050020163200070000302187 -:103D10008FBF001C8FB200188FB100148FB000103D -:103D20000A00034227BD00208FBF001C8FB200187D -:103D30008FB100148FB00010240500390A000E6402 -:103D400027BD002027BDFFE83C028000AFB0001077 -:103D5000AFBF0014344201009442000C2405003629 -:103D60000080802114400012304600FF0E00033214 -:103D7000000000003C02800834420080240300124E -:103D8000A043000990430005346300100E000E5B51 -:103D9000A04300050E00033D020020210200202167 -:103DA0000E000342240500200A000F3C0000000022 -:103DB0000E000E64000000000E00033202002021FD -:103DC0003C0280089043001B2405FF9F0200202135 -:103DD000006518248FBF00148FB00010A043001B93 -:103DE0000A00033D27BD001827BDFFE0AFBF001844 -:103DF000AFB10014AFB0001030B100FF0E000332BD -:103E0000008080213C02800824030012344200809C -:103E10000E000E5BA04300090E00033D02002021AE -:103E200002002021022030218FBF00188FB1001422 -:103E30008FB00010240500350A000E6427BD002055 -:103E40003C0480089083000E9082000A1443000B0B -:103E5000000028218F82FF942403005024050001D4 -:103E600090420000304200FF1443000400000000B4 -:103E70009082000E24420001A082000E03E00008A0 -:103E800000A010213C0380008C6201F80440FFFE7A -:103E900024020002AC6401C0A06201C43C02100014 -:103EA00003E00008AC6201F827BDFFE0AFB20018E4 -:103EB0003C128008AFB10014AFBF001CAFB00010BF -:103EC00036510080922200092403000A304200FF8C -:103ED0001443003E000000008E4300048E22003890 -:103EE000506200808FBF001C92220000240300500B -:103EF000304200FF144300253C0280008C42014008 -:103F00008E4300043642010002202821AC43001CED -:103F10009622005C8E2300383042FFFF00021040E2 -:103F200000621821AE23001C8E4300048E2400384A -:103F30009622005C006418233042FFFF0003184300 -:103F4000000210400043102A10400006000000004C -:103F50008E4200048E230038004310230A000FAA6B -:103F6000000220439622005C3042FFFF0002204006 -:103F70003C0280083443010034420080ACA4002C91 -:103F8000A040002424020001A062000C0E000F5E7D -:103F900000000000104000538FBF001C3C02800056 -:103FA0008C4401403C0380008C6201F80440FFFE19 -:103FB00024020002AC6401C0A06201C43C021000F3 -:103FC000AC6201F80A0010078FBF001C92220009A2 -:103FD00024030010304200FF144300043C02800020 -:103FE0008C4401400A000FEE0000282192220009B3 -:103FF00024030016304200FF14430006240200147C -:10400000A22200093C0280008C4401400A001001F9 -:104010008FBF001C8E2200388E23003C00431023EB -:10402000044100308FBF001C92220027244200016F -:10403000A2220027922200272C42000414400016DE -:104040003C1080009222000924030004304200FF4B -:10405000144300093C0280008C4401408FBF001CC7 -:104060008FB200188FB100148FB000102405009398 -:104070000A000ECC27BD00208C440140240500938B -:104080008FBF001C8FB200188FB100148FB00010CA -:104090000A000F4827BD00208E0401400E000332A5 -:1040A000000000008E4200042442FFFFAE420004E4 -:1040B0008E22003C2442FFFFAE22003C0E00033D56 -:1040C0008E0401408E0401408FBF001C8FB2001887 -:1040D0008FB100148FB00010240500040A000342C1 -:1040E00027BD00208FB200188FB100148FB00010D0 -:1040F00003E0000827BD00203C0680008CC2018838 -:104100003C038008346500809063000E00021402B6 -:10411000304400FF306300FF1464000E3C0280084E -:1041200090A20026304200FF104400098F82FF94C5 -:10413000A0A400262403005090420000304200FF5B -:1041400014430006000000000A0005A18CC4018091 -:104150003C02800834420080A044002603E00008AE -:104160000000000027BDFFE030E700FFAFB20018FD -:10417000AFBF001CAFB10014AFB0001000809021A1 -:1041800014E0000630C600FF000000000000000D33 -:10419000000000000A001060240001163C038008A3 -:1041A0009062000E304200FF14460023346200800B -:1041B00090420026304200FF1446001F000000001D -:1041C0009062000F304200FF1446001B0000000008 -:1041D0009062000A304200FF144600038F90FF9463 -:1041E0000000000D8F90FF948F82FF983C1180009B -:1041F000AE05003CAC450000A066000A0E0003328C -:104200008E240100A20000240E00033D8E24010034 -:104210003C0380008C6201F80440FFFE240200028F -:10422000AC7201C0A06201C43C021000AC6201F893 -:104230000A0010618FBF001C000000000000000D8C -:10424000000000002400013F8FBF001C8FB2001847 -:104250008FB100148FB0001003E0000827BD0020CC -:104260008F83FF943C0280008C44010034420100A3 -:104270008C65003C9046001B0A00102724070001B3 -:104280003C0280089043000E9042000A0043102632 -:10429000304200FF03E000080002102B27BDFFE0C2 -:1042A0003C028008AFB10014AFB00010AFBF0018DF -:1042B0003450008092020005240300303042003068 -:1042C00014430085008088218F8200248C42000CDA -:1042D000104000828FBF00180E000D840000000007 -:1042E0008F860020ACD100009202000892030009E2 -:1042F000304200FF00021200306300FF004310252F -:10430000ACC200049202004D000216000002160327 -:1043100004410005000000003C0308008C630048D5 -:104320000A00109F3C1080089202000830420040B2 -:10433000144000030000182192020027304300FFC0 -:104340003C108008361100809222004D00031E00B0 -:10435000304200FF0002140000621825ACC30008C0 -:104360008E2400308F820024ACC4000C8E250034D3 -:104370009443001E3C02C00BACC50010006218251F -:104380008E22003800002021ACC200148E22003C96 -:10439000ACC200180E000DB8ACC3001C8E020004A5 -:1043A0008F8400203C058000AC8200008E2200201B -:1043B000AC8200048E22001CAC8200088E220058C1 -:1043C0008CA3007400431021AC82000C8E22002CC0 -:1043D000AC8200108E2200408E23004400021400A4 -:1043E00000431025AC8200149222004D240300806B -:1043F000304200FF1443000400000000AC800018AD -:104400000A0010E38F8200248E23000C2402000196 -:104410001062000E2402FFFF92220008304200408A -:104420001440000A2402FFFF8E23000C8CA20074AB -:10443000006218233C0208000062102414400002AD -:10444000000028210060282100051043AC820018DC -:104450008F820024000020219443001E3C02C00CE7 -:10446000006218258F8200200E000DB8AC43001C9E -:104470003C038008346201008C4200008F850020DC -:10448000346300808FBF0018ACA20000ACA0000411 -:104490008C6400488F8200248FB10014ACA4000803 -:1044A000ACA0000CACA00010906300059446001E68 -:1044B0003C02400D00031E0000C23025ACA30014D6 -:1044C0008FB00010ACA0001824040001ACA6001CA2 -:1044D0000A000DB827BD00208FBF00188FB100144F -:1044E0008FB0001003E0000827BD00203C028000D0 -:1044F0009443007C3C02800834460100308400FF75 -:104500003065FFFF2402000524A34650A0C4000C20 -:104510005482000C3065FFFF90C2000D2C42000752 -:104520001040000724A30A0090C3000D24020014C9 -:104530000062100400A210210A00111F3045FFFF85 -:104540003065FFFF3C0280083442008003E0000831 -:10455000A44500143C03800834680080AD05003891 -:10456000346701008CE2001C308400FF00A210239D -:104570001840000330C600FF24A2FFFCACE2001C80 -:1045800030820001504000083C0380088D02003C4E -:1045900000A2102304410012240400058C620004D0 -:1045A00010A2000F3C0380088C62000414A2001EBD -:1045B000000000003C0208008C4200D8304200207D -:1045C000104000093C0280083462008090630008BB -:1045D0009042004C144300043C0280082404000470 -:1045E0000A00110900000000344300803442010039 -:1045F000A040000C24020001A462001410C0000AB4 -:104600003C0280008C4401003C0380008C6201F875 -:104610000440FFFE24020002AC6401C0A06201C499 -:104620003C021000AC6201F803E00008000000004A -:1046300027BDFFE800A61823AFBF00101860008058 -:10464000308800FF3C02800834470080A0E000244E -:1046500034440100A0E000278C82001C00A210233B -:1046600004400056000000008CE2003C94E3005C33 -:104670008CE4002C004530233063FFFF00C3182179 -:104680000083202B1080000400E018218CE2002C15 -:104690000A00117800A2102194E2005C3042FFFF72 -:1046A00000C2102100A21021AC62001C3C02800854 -:1046B000344400809482005C8C83001C3042FFFFF5 -:1046C0000002104000A210210043102B10400004F3 -:1046D000000000008C82001C0A00118B3C06800840 -:1046E0009482005C3042FFFF0002104000A21021C3 -:1046F0003C06800834C3010034C70080AC82001C33 -:10470000A060000CACE500388C62001C00A21023F5 -:104710001840000224A2FFFCAC62001C3102000120 -:10472000104000083C0380088CE2003C00A21023EB -:1047300004410012240400058CC2000410A20010E1 -:104740008FBF00108C62000414A2004F8FBF0010B6 -:104750003C0208008C4200D8304200201040000A81 -:104760003C02800834620080906300089042004C54 -:10477000144300053C028008240400048FBF00108D -:104780000A00110927BD001834430080344201009B -:10479000A040000C24020001A46200143C0280002E -:1047A0008C4401003C0380008C6201F80440FFFE51 -:1047B000240200020A0011D8000000008CE2001C54 -:1047C000004610230043102B54400001ACE5001CB0 -:1047D00094E2005C3042FFFF0062102B144000079F -:1047E0002402000294E2005C8CE3001C3042FFFFD4 -:1047F00000621821ACE3001C24020002ACE5003882 -:104800000E000F5EA082000C1040001F8FBF001032 -:104810003C0280008C4401003C0380008C6201F863 -:104820000440FFFE24020002AC6401C0A06201C487 -:104830003C021000AC6201F80A0011F08FBF0010BA -:1048400031020010104000108FBF00103C028008A1 -:10485000344500808CA3001C94A2005C00661823E1 -:104860003042FFFF006218213C023FFF3444FFFF4B -:104870000083102B544000010080182100C3102138 -:10488000ACA2001C8FBF001003E0000827BD001879 -:1048900027BDFFE800C0402100A63023AFBF0010B5 -:1048A00018C00026308A00FF3C028008344900808E -:1048B0008D24001C8D23002C008820230064182BDD -:1048C0001060000F344701008CE2002000461021E8 -:1048D000ACE200208CE200200044102B1440000BBE -:1048E0003C023FFF8CE2002000441023ACE2002099 -:1048F0009522005C3042FFFF0A0012100082202146 -:10490000ACE00020008620213C023FFF3443FFFF43 -:104910000064102B54400001006020213C028008FC -:104920003442008000851821AC43001CA0400024C4 -:10493000A04000270A0012623C03800831420010A8 -:10494000104000433C0380083C06800834C40080CB -:104950008C82003C004810235840003E34660080A2 -:104960009082002424420001A0820024908200242E -:104970003C0308008C630024304200FF0043102BEE -:10498000144000688FBF001034C201008C42001C2C -:1049900000A2102318400063000000008CC3000434 -:1049A0009482005C006818233042FFFF0003184324 -:1049B000000210400043102A1040000500000000D3 -:1049C0008CC20004004810230A0012450002104364 -:1049D0009482005C3042FFFF000210403C068008D9 -:1049E000AC82002C34C5008094A2005C8CA4002C06 -:1049F00094A3005C3042FFFF00021040008220219F -:104A00003063FFFF0083202101041021ACA2001CB1 -:104A10008CC2000434C60100ACC2001C2402000297 -:104A20000E000F5EA0C2000C1040003E8FBF0010B1 -:104A30003C0280008C4401003C0380008C6201F841 -:104A40000440FFFE240200020A001292000000004F -:104A500034660080ACC50038346401008C82001CD0 -:104A600000A210231840000224A2FFFCAC82001C0C -:104A7000314200015040000A3C0380088CC2003CD7 -:104A800000A2102304430014240400058C620004D7 -:104A900014A200033C0380080A00128424040005C9 -:104AA0008C62000414A2001F8FBF00103C0208009B -:104AB0008C4200D8304200201040000A3C0280089E -:104AC00034620080906300089042004C144300055B -:104AD0003C028008240400048FBF00100A00110962 -:104AE00027BD00183443008034420100A040000C70 -:104AF00024020001A46200143C0280008C440100E6 -:104B00003C0380008C6201F80440FFFE2402000296 -:104B1000AC6401C0A06201C43C021000AC6201F8A8 -:104B20008FBF001003E0000827BD001827BDFFE875 -:104B30003C0A8008AFBF0010354900808D22003C40 -:104B400000C04021308400FF004610231840009D23 -:104B500030E700FF354701002402000100A63023A2 -:104B6000A0E0000CA0E0000DA522001418C0002455 -:104B7000308200108D23001C8D22002C0068182329 -:104B80000043102B1040000F000000008CE20020BA -:104B900000461021ACE200208CE200200043102BE4 -:104BA0001440000B3C023FFF8CE200200043102326 -:104BB000ACE200209522005C3042FFFF0A0012C1E7 -:104BC00000621821ACE00020006618213C023FFF83 -:104BD0003446FFFF00C3102B5440000100C01821D1 -:104BE0003C0280083442008000651821AC43001C60 -:104BF000A0400024A04000270A00130F3C038008B7 -:104C0000104000403C0380088D22003C00481023E7 -:104C10005840003D34670080912200242442000166 -:104C2000A1220024912200243C0308008C6300246C -:104C3000304200FF0043102B1440009A8FBF001039 -:104C40008CE2001C00A21023184000960000000017 -:104C50008D4300049522005C006818233042FFFF5A -:104C600000031843000210400043102A10400005C2 -:104C7000012020218D420004004810230A0012F276 -:104C8000000210439522005C3042FFFF00021040FA -:104C90003C068008AC82002C34C5008094A2005CE5 -:104CA0008CA4002C94A3005C3042FFFF0002104053 -:104CB000008220213063FFFF0083182101031021AF -:104CC000ACA2001C8CC2000434C60100ACC2001CA3 -:104CD000240200020E000F5EA0C2000C1040007102 -:104CE0008FBF00103C0280008C4401003C03800018 -:104CF0008C6201F80440FFFE240200020A0013390E -:104D00000000000034670080ACE500383466010024 -:104D10008CC2001C00A210231840000224A2FFFC39 -:104D2000ACC2001C30820001504000083C038008E7 -:104D30008CE2003C00A2102304430051240400052F -:104D40008C62000410A2003E3C0380088C620004C8 -:104D500054A200548FBF00103C0208008C4200D8BF -:104D600030420020104000063C028008346200807F -:104D7000906300089042004C104300403C028008C1 -:104D80003443008034420100A040000C24020001A2 -:104D9000A46200143C0280008C4401003C038000AB -:104DA0008C6201F80440FFFE24020002AC6401C0E2 -:104DB000A06201C43C021000AC6201F80A00137743 -:104DC0008FBF001024020005A120002714E2000A72 -:104DD0003C038008354301009062000D2C42000620 -:104DE000504000053C0380089062000D2442000101 -:104DF000A062000D3C03800834670080ACE50038F9 -:104E0000346601008CC2001C00A21023184000026E -:104E100024A2FFFCACC2001C308200015040000AFA -:104E20003C0380088CE2003C00A2102304410014E3 -:104E3000240400058C62000414A200033C038008D3 -:104E40000A00136E240400058C62000414A20015ED -:104E50008FBF00103C0208008C4200D83042002076 -:104E60001040000A3C028008346200809063000811 -:104E70009042004C144300053C02800824040004C6 -:104E80008FBF00100A00110927BD001834430080AD -:104E900034420100A040000C24020001A46200146E -:104EA0008FBF001003E0000827BD00183C0B8008EE -:104EB00027BDFFE83C028000AFBF00103442010074 -:104EC000356A00809044000A356901008C45001461 -:104ED0008D4800389123000C308400FF0105102319 -:104EE0001C4000B3306700FF2CE20006504000B1C8 -:104EF0008FBF00102402000100E2300430C2000322 -:104F00005440000800A8302330C2000C144000A117 -:104F100030C20030144000A38FBF00100A00143BC1 -:104F20000000000018C00024308200108D43001CD7 -:104F30008D42002C006818230043102B1040000FF6 -:104F4000000000008D22002000461021AD2200202C -:104F50008D2200200043102B1440000B3C023FFF29 -:104F60008D22002000431023AD2200209542005CDA -:104F70003042FFFF0A0013AF00621821AD2000206D -:104F8000006618213C023FFF3446FFFF00C3102B90 -:104F90005440000100C018213C02800834420080C7 -:104FA00000651821AC43001CA0400024A04000274D -:104FB0000A0013FD3C038008104000403C038008B9 -:104FC0008D42003C004810231840003D34670080AB -:104FD0009142002424420001A14200249142002475 -:104FE0003C0308008C630024304200FF0043102B78 -:104FF000144000708FBF00108D22001C00A21023EF -:105000001840006C000000008D6300049542005CB5 -:10501000006818233042FFFF0003184300021040CD -:105020000043102A10400005014020218D62000439 -:10503000004810230A0013E0000210439542005C70 -:105040003042FFFF000210403C068008AC82002C7A -:1050500034C5008094A2005C8CA4002C94A3005C56 -:105060003042FFFF00021040008220213063FFFF2A -:105070000083182101031021ACA2001C8CC2000483 -:1050800034C60100ACC2001C240200020E000F5EF8 -:10509000A0C2000C104000478FBF00103C028000EF -:1050A0008C4401003C0380008C6201F80440FFFE48 -:1050B000240200020A00142D000000003467008062 -:1050C000ACE50038346601008CC2001C00A210233D -:1050D0001840000224A2FFFCACC2001C3082000178 -:1050E0005040000A3C0380088CE2003C00A21023E0 -:1050F00004430014240400058C62000414A200037D -:105100003C0380080A00141F240400058C6200047C -:1051100014A200288FBF00103C0208008C4200D867 -:10512000304200201040000A3C02800834620080B7 -:10513000906300089042004C144300053C02800834 -:10514000240400048FBF00100A00110927BD0018B5 -:105150003443008034420100A040000C24020001CE -:10516000A46200143C0280008C4401003C038000D7 -:105170008C6201F80440FFFE24020002AC6401C00E -:10518000A06201C43C021000AC6201F80A00143BAA -:105190008FBF00108FBF0010010030210A00115A8C -:1051A00027BD0018010030210A00129927BD001800 -:1051B0008FBF001003E0000827BD00183C038008E3 -:1051C0003464010024020003A082000C8C620004FD -:1051D00003E00008AC82001C3C05800834A300807A -:1051E0009062002734A501002406004324420001F8 -:1051F000A0620027906300273C0208008C42004810 -:10520000306300FF146200043C07602194A500EAAB -:105210000A00090130A5FFFF03E0000800000000BC -:1052200027BDFFE8AFBF00103C0280000E00144411 -:105230008C4401803C02800834430100A060000CD3 -:105240008C4200048FBF001027BD001803E0000847 -:10525000AC62001C27BDFFE03C028008AFBF001815 -:10526000AFB10014AFB000103445008034460100E7 -:105270003C0880008D09014090C3000C8CA4003CC8 -:105280008CA200381482003B306700FF9502007C3E -:1052900090A30027146000093045FFFF2402000599 -:1052A00054E200083C04800890C2000D2442000132 -:1052B000A0C2000D0A00147F3C048008A0C0000DAD -:1052C0003C048008348201009042000C2403000555 -:1052D000304200FF1443000A24A205DC348300801E -:1052E000906200272C4200075040000524A20A00CB -:1052F00090630027240200140062100400A2102111 -:105300003C108008361000803045FFFF012020212E -:105310000E001444A60500149602005C8E030038AB -:105320003C1180003042FFFF000210400062182153 -:10533000AE03001C0E0003328E24014092020025B1 -:1053400034420040A20200250E00033D8E2401409D -:105350008E2401403C0380008C6201F80440FFFE73 -:1053600024020002AC6401C0A06201C43C0210002F -:10537000AC6201F88FBF00188FB100148FB000101D -:1053800003E0000827BD00203C0360103C02080039 -:1053900024420174AC62502C8C6250003C048000AA -:1053A00034420080AC6250003C0208002442547C2D -:1053B0003C010800AC2256003C020800244254384C -:1053C0003C010800AC2256043C020002AC840008F8 -:1053D000AC82000C03E000082402000100A0302190 -:1053E0003C1C0800279C56083C0200023C050400B7 -:1053F00000852826008220260004102B2CA5000101 -:105400002C840001000210803C0308002463560035 -:105410000085202500431821108000030000102182 -:10542000AC6600002402000103E000080000000058 -:105430003C1C0800279C56083C0200023C05040066 -:1054400000852826008220260004102B2CA50001B0 -:105450002C840001000210803C03080024635600E5 -:105460000085202500431821108000050000102130 -:105470003C02080024425438AC62000024020001BF -:1054800003E00008000000003C0200023C030400AE -:1054900000821026008318262C4200012C63000194 -:1054A000004310251040000B000028213C1C080080 -:1054B000279C56083C0380008C62000824050001EC -:1054C00000431025AC6200088C62000C00441025DB -:1054D000AC62000C03E0000800A010213C1C080096 -:1054E000279C56083C0580008CA3000C0004202754 -:1054F000240200010064182403E00008ACA3000C9F -:105500003C020002148200063C0560008CA208D018 -:105510002403FFFE0043102403E00008ACA208D0DF -:105520003C02040014820005000000008CA208D098 -:105530002403FFFD00431024ACA208D003E00008C0 -:10554000000000003C02601A344200108C430080CE -:1055500027BDFFF88C440084AFA3000093A3000094 -:10556000240200041462001AAFA4000493A20001F4 -:105570001040000797A300023062FFFC3C0380004C -:10558000004310218C4200000A001536AFA200042F -:105590003062FFFC3C03800000431021AC4400005B -:1055A000A3A000003C0560008CA208D02403FFFEED -:1055B0003C04601A00431024ACA208D08FA300045E -:1055C0008FA2000034840010AC830084AC82008081 -:1055D00003E0000827BD000827BDFFE8AFBF0010AB -:1055E0003C1C0800279C56083C0280008C43000CA1 -:1055F0008C420004004318243C0200021060001496 -:10560000006228243C0204003C04000210A00005B3 -:10561000006210243C0208008C4256000A00155B10 -:1056200000000000104000073C0404003C02080099 -:105630008C4256040040F809000000000A00156082 -:10564000000000000000000D3C1C0800279C5608CC -:0C5650008FBF001003E0000827BD001809 -:04565C008008024080 -:1056600080080100800800808008000000000C8095 -:105670000000320008000E9808000EF408000F88A1 -:1056800008001028080010748008010080080080BD -:04569000800800008E -:0C5694000A0000280000000000000000D8 -:1056A0000000000D6370362E322E316100000000C4 -:1056B00006020104000000000000000000000000DD -:1056C000000000000000000038003C000000000066 -:1056D00000000000000000000000000000000020AA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:10570000000000000000000021003800000000013F -:105710000000002B000000000000000400030D400A -:105720000000000000000000000000000000000079 -:105730000000000000000000100000030000000056 -:105740000000000D0000000D3C020800244259AC8E -:105750003C03080024635BF4AC4000000043202BB2 -:105760001480FFFD244200043C1D080037BD9FFC4F -:1057700003A0F0213C100800261000A03C1C0800EB -:10578000279C59AC0E0002F6000000000000000D3E -:1057900027BDFFB4AFA10000AFA20004AFA3000873 -:1057A000AFA4000CAFA50010AFA60014AFA700185F -:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF -:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F -:1057D000AFB8003CAFB90040AFBC0044AFBF004819 -:1057E0000E000820000000008FBF00488FBC00445E -:1057F0008FB900408FB8003C8FAF00388FAE0034B7 -:105800008FAD00308FAC002C8FAB00288FAA002406 -:105810008FA900208FA8001C8FA700188FA6001446 -:105820008FA500108FA4000C8FA300088FA2000486 -:105830008FA1000027BD004C3C1B60188F7A5030B0 -:10584000377B502803400008AF7A000000A01821E1 -:1058500000801021008028213C0460003C0760008B -:105860002406000810600006348420788C42000072 -:10587000ACE220088C63000003E00008ACE3200CDD -:105880000A000F8100000000240300403C02600079 -:1058900003E00008AC4320003C0760008F86000452 -:1058A0008CE520740086102100A2182B14600007DC -:1058B000000028218F8AFDA024050001A1440013C7 -:1058C0008F89000401244021AF88000403E0000810 -:1058D00000A010218F84FDA08F8500049086001306 -:1058E00030C300FF00A31023AF82000403E00008D0 -:1058F000A08000138F84FDA027BDFFE8AFB000108B -:10590000AFBF001490890011908700112402002875 -:10591000312800FF3906002830E300FF2485002CE1 -:105920002CD00001106200162484001C0E00006EB2 -:10593000000000008F8FFDA03C05600024020204DF -:1059400095EE003E95ED003C000E5C0031ACFFFF93 -:10595000016C5025ACAA2010520000012402000462 -:10596000ACA22000000000000000000000000000C9 -:105970008FBF00148FB0001003E0000827BD00188F -:105980000A0000A6000028218F85FDA027BDFFD8B2 -:10599000AFBF0020AFB3001CAFB20018AFB100140E -:1059A000AFB000100080982190A4001124B0001C1A -:1059B00024B1002C308300FF386200280E000090D4 -:1059C0002C5200010E00009800000000020020216F -:1059D0001240000202202821000028210E00006E43 -:1059E000000000008F8DFDA03C0880003C05600099 -:1059F00095AC003E95AB003C02683025000C4C0095 -:105A0000316AFFFF012A3825ACA7201024020202C8 -:105A1000ACA6201452400001240200028FBF0020D7 -:105A20008FB3001C8FB200188FB100148FB000101C -:105A300027BD002803E00008ACA2200027BDFFE03E -:105A4000AFB20018AFB10014AFB00010AFBF001C70 -:105A50003C1160008E2320748F82000430D0FFFF41 -:105A600030F2FFFF1062000C2406008F0E00006E63 -:105A7000000000003C06801F0010440034C5FF00F9 -:105A80000112382524040002AE2720100000302126 -:105A9000AE252014AE2420008FBF001C8FB200184A -:105AA0008FB100148FB0001000C0102103E0000877 -:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 -:105AC000AFBF0018AFB100140E00006E30F1FFFF41 -:105AD00000102400009180253C036000AC70201071 -:105AE0008FBF00188FB100148FB000102402000483 -:105AF000AC62200027BD002003E000080000102158 -:105B000027BDFFE03C046018AFBF0018AFB1001420 -:105B1000AFB000108C8850002403FF7F34028071E6 -:105B20000103382434E5380C241F00313C1980006F -:105B3000AC8550003C11800AAC8253BCAF3F0008DA -:105B40000E00054CAF9100400E00050A3C116000AC -:105B50000E00007D000000008E3008083C0F570941 -:105B60002418FFF00218602435EEE00035EDF00057 -:105B7000018E5026018D58262D4600012D69000109 -:105B8000AF86004C0E000D09AF8900503C06601630 -:105B90008CC700003C0860148D0500A03C03FFFF8B -:105BA00000E320243C02535300052FC2108200550D -:105BB00034D07C00960201F2A780006C10400003F4 -:105BC000A780007C384B1E1EA78B006C960201F844 -:105BD000104000048F8D0050384C1E1EA78C007C96 -:105BE0008F8D005011A000058F83004C240E0020E3 -:105BF000A78E007CA78E006C8F83004C1060000580 -:105C00009785007C240F0020A78F007CA78F006C55 -:105C10009785007C2CB8008153000001240500808A -:105C20009784006C2C91040152200001240404008C -:105C30001060000B3C0260008FBF00188FB1001491 -:105C40008FB0001027BD0020A784006CA785007CC2 -:105C5000A380007EA780007403E00008A780009264 -:105C60008C4704382419103C30FFFFFF13F9000360 -:105C700030A8FFFF1100004624030050A380007EDF -:105C80009386007E50C00024A785007CA780007CFE -:105C90009798007CA780006CA7800074A780009272 -:105CA0003C010800AC3800800E00078700000000AF -:105CB0003C0F60008DED0808240EFFF03C0B600ED9 -:105CC000260C0388356A00100000482100002821B6 -:105CD00001AE20243C105709AF8C0010AF8A004859 -:105CE000AF89001810900023AF8500148FBF0018F3 -:105CF0008FB100148FB0001027BD002003E0000812 -:105D0000AF80005400055080014648218D260004D4 -:105D10000A00014800D180219798007CA784006C7C -:105D2000A7800074A78000923C010800AC38008076 -:105D30000E000787000000003C0F60008DED080892 -:105D4000240EFFF03C0B600E260C0388356A001011 -:105D5000000048210000282101AE20243C105709F2 -:105D6000AF8C0010AF8A0048AF8900181490FFDF95 -:105D7000AF85001424110001AF9100548FBF0018AB -:105D80008FB100148FB0001003E0000827BD002081 -:105D90000A00017BA383007E3083FFFF8F880040D1 -:105DA0008F87003C000321403C0580003C020050EE -:105DB000008248253C0660003C0A010034AC040027 -:105DC0008CCD08E001AA58241160000500000000F5 -:105DD0008CCF08E024E7000101EA7025ACCE08E092 -:105DE0008D19001001805821ACB900388D180014AD -:105DF000ACB8003CACA9003000000000000000007E -:105E00000000000000000000000000000000000092 -:105E100000000000000000003C0380008C640000D3 -:105E2000308200201040FFFD3C0F60008DED08E047 -:105E30003C0E010001AE18241460FFE100000000D8 -:105E4000AF87003C03E00008AF8B00588F8500400F -:105E5000240BFFF03C06800094A7001A8CA90024B4 -:105E600030ECFFFF000C38C000EB5024012A402129 -:105E7000ACC8003C8CA400248CC3003C00831023DD -:105E800018400033000000008CAD002025A2000166 -:105E90003C0F0050ACC2003835EE00103C068000CC -:105EA000ACCE003000000000000000000000000048 -:105EB00000000000000000000000000000000000E2 -:105EC000000000003C0480008C9900003338002062 -:105ED0001300FFFD30E20008104000173C0980006D -:105EE0008C880408ACA800108C83040CACA30014AC -:105EF0003C1900203C188000AF19003094AE001807 -:105F000094AF001C01CF3021A4A6001894AD001A54 -:105F100025A70001A4A7001A94AB001A94AC001E98 -:105F2000118B00030000000003E0000800000000E7 -:105F300003E00008A4A0001A8D2A0400ACAA0010F7 -:105F40008D240404ACA400140A0002183C1900209B -:105F50008CA200200A0002003C0F00500A0001EE53 -:105F60000000000027BDFFE8AFBF00100E000232A6 -:105F7000000000008F8900408FBF00103C038000AC -:105F8000A520000A9528000A9527000427BD0018BF -:105F90003105FFFF30E6000F0006150000A22025A6 -:105FA00003E00008AC6400803C0508008CA50020DC -:105FB0008F83000C27BDFFE8AFB00010AFBF001407 -:105FC00010A300100000802124040001020430040A -:105FD00000A6202400C3102450440006261000010F -:105FE000001018802787FDA41480000A006718217C -:105FF000261000012E0900025520FFF38F83000CAC -:10600000AF85000C8FBF00148FB0001003E00008B4 -:1060100027BD00188C6800003C058000ACA8002457 -:106020000E000234261000013C0508008CA500205B -:106030000A0002592E0900022405000100851804F7 -:106040003C0408008C84002027BDFFC8AFBF00348B -:1060500000831024AFBE0030AFB7002CAFB60028CD -:10606000AFB50024AFB40020AFB3001CAFB200182E -:10607000AFB1001410400051AFB000108F84004049 -:10608000948700069488000A00E8302330D5FFFF8B -:1060900012A0004B8FBF0034948B0018948C000A20 -:1060A000016C50233142FFFF02A2482B1520000251 -:1060B00002A02021004020212C8F000515E00002C5 -:1060C00000809821241300040E0001C102602021E9 -:1060D0008F87004002609021AF80004494F4000A52 -:1060E000026080211260004E3291FFFF3C1670006A -:1060F0003C1440003C1E20003C1760008F99005863 -:106100008F380000031618241074004F0283F82BF8 -:1061100017E0003600000000107E00478F86004424 -:1061200014C0003A2403000102031023022320219B -:106130003050FFFF1600FFF13091FFFF8F870040C6 -:106140003C1100203C108000AE11003094EB000A9E -:106150003C178000024B5021A4EA000A94E9000A8F -:1061600094E800043123FFFF3106000F00062D00E4 -:106170000065F025AEFE008094F3000A94F6001846 -:1061800012D30036001221408CFF00148CF4001052 -:1061900003E468210000C02101A4782B029870213B -:1061A00001CF6021ACED0014ACEC001002B238233A -:1061B00030F5FFFF16A0FFB88F8400408FBF00347A -:1061C0008FBE00308FB7002C8FB600288FB500240B -:1061D0008FB400208FB3001C8FB200188FB1001451 -:1061E0008FB0001003E0000827BD00381477FFCC03 -:1061F0008F8600440E000EE202002021004018218C -:106200008F86004410C0FFC9020310230270702360 -:106210008F87004001C368210A0002E431B2FFFF0A -:106220008F86004414C0FFC93C1100203C10800040 -:106230000A0002AEAE1100300E00046602002021FA -:106240000A0002DB00401821020020210E0009395B -:10625000022028210A0002DB004018210E0001EE76 -:10626000000000000A0002C702B2382327BDFFC8A1 -:10627000AFB7002CAFB60028AFB50024AFB40020F4 -:10628000AFB3001CAFB20018AFB10014AFB0001034 -:10629000AFBF00300E00011B241300013C047FFF40 -:1062A0003C0380083C0220003C010800AC20007048 -:1062B0003496FFFF34770080345200033C1512C03F -:1062C000241400013C1080002411FF800E000245C0 -:1062D000000000008F8700488F8B00188F89001402 -:1062E0008CEA00EC8CE800E8014B302B01092823F4 -:1062F00000A6102314400006014B18231440000E82 -:106300003C05800002A3602B1180000B0000000000 -:106310003C0560008CEE00EC8CED00E88CA4180CC1 -:10632000AF8E001804800053AF8D00148F8F0010C3 -:10633000ADF400003C0580008CBF00003BF900017B -:10634000333800011700FFE13C0380008C6201003C -:1063500024060C0010460009000000008C680100B3 -:106360002D043080548000103C0480008C690100B2 -:106370002D2331811060000C3C0480008CAA0100A8 -:1063800011460004000020218CA6010024C5FF81D5 -:1063900030A400FF8E0B01000E000269AE0B00243A -:1063A0000A00034F3C0480008C8D01002DAC3300AB -:1063B00011800022000000003C0708008CE70098D4 -:1063C00024EE00013C010800AC2E00983C04800043 -:1063D0008C8201001440000300000000566000148D -:1063E0003C0440008C9F01008C9801000000982123 -:1063F00003F1C82400193940330F007F00EF7025E6 -:1064000001D26825AC8D08308C8C01008C85010090 -:10641000258B0100017130240006514030A3007F1C -:106420000143482501324025AC8808303C04400037 -:10643000AE0401380A00030E000000008C99010030 -:10644000240F0020AC99002092F80000330300FFD5 -:10645000106F000C241F0050547FFFDD3C048000AF -:106460008C8401000E00154E000000000A00034F4E -:106470003C04800000963824ACA7180C0A000327BF -:106480008F8F00108C8501000E0008F72404008017 -:106490000A00034F3C04800000A4102B24030001D9 -:1064A00010400009000030210005284000A4102BF6 -:1064B00004A00003000318405440FFFC00052840DE -:1064C0005060000A0004182B0085382B54E00004AB -:1064D0000003184200C33025008520230003184222 -:1064E0001460FFF9000528420004182B03E000089F -:1064F00000C310213084FFFF30C600FF3C0780003E -:106500008CE201B80440FFFE00064C000124302557 -:106510003C08200000C820253C031000ACE00180AE -:10652000ACE50184ACE4018803E00008ACE301B809 -:106530003C0660008CC5201C2402FFF03083020062 -:10654000308601001060000E00A2282434A500014E -:106550003087300010E0000530830C0034A50004C3 -:106560003C04600003E00008AC85201C1060FFFDC7 -:106570003C04600034A5000803E00008AC85201C42 -:1065800054C0FFF334A500020A0003B03087300086 -:1065900027BDFFE8AFB00010AFBF00143C0760009C -:1065A000240600021080001100A080218F83005873 -:1065B0000E0003A78C6400188F8200580000202171 -:1065C000240600018C45000C0E000398000000001A -:1065D0001600000224020003000010218FBF0014E7 -:1065E0008FB0001003E0000827BD00188CE8201CC5 -:1065F0002409FFF001092824ACE5201C8F870058EE -:106600000A0003CD8CE5000C3C02600E00804021A6 -:1066100034460100240900180000000000000000BA -:10662000000000003C0A00503C0380003547020097 -:10663000AC68003834640400AC65003CAC670030E2 -:106640008C6C0000318B00201160FFFD2407FFFFE0 -:106650002403007F8C8D00002463FFFF248400044A -:10666000ACCD00001467FFFB24C60004000000004E -:10667000000000000000000024A402000085282B78 -:106680003C0300203C0E80002529FFFF010540212E -:10669000ADC300301520FFE00080282103E0000892 -:1066A000000000008F82005827BDFFD8AFB3001C48 -:1066B000AFBF0020AFB20018AFB10014AFB00010F0 -:1066C00094460002008098218C5200182CC300814F -:1066D0008C4800048C4700088C51000C8C49001039 -:1066E000106000078C4A00142CC4000414800013AE -:1066F00030EB000730C5000310A0001000000000C0 -:106700002410008B02002021022028210E00039873 -:10671000240600031660000224020003000010217A -:106720008FBF00208FB3001C8FB200188FB10014F0 -:106730008FB0001003E0000827BD00281560FFF1AE -:106740002410008B3C0C80003C030020241F00011F -:10675000AD830030AF9F0044000000000000000047 -:10676000000000002419FFF024D8000F031978243A -:106770003C1000D0AD88003801F0702524CD000316 -:106780003C08600EAD87003C35850400AD8E0030BE -:10679000000D38823504003C3C0380008C6B000007 -:1067A000316200201040FFFD0000000010E00008F2 -:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 -:1067C00024A50004AC8800001467FFFB24840004A7 -:1067D0003C05600EACA60038000000000000000080 -:1067E000000000008F8600543C0400203C0780001D -:1067F000ACE4003054C000060120202102402021DA -:106800000E0003A7000080210A00041D02002021C1 -:106810000E0003DD01402821024020210E0003A7C5 -:10682000000080210A00041D0200202127BDFFE096 -:10683000AFB200183092FFFFAFB10014AFBF001C21 -:10684000AFB000101640000D000088210A0004932C -:106850000220102124050003508500278CE5000C40 -:106860000000000D262800013111FFFF24E2002066 -:106870000232802B12000019AF8200588F82004430 -:10688000144000168F8700583C0670003C0320001F -:106890008CE5000000A62024148300108F84006083 -:1068A000000544023C09800000A980241480FFE90F -:1068B000310600FF2CCA000B5140FFEB26280001D7 -:1068C000000668803C0E080025CE575801AE6021B6 -:1068D0008D8B0000016000080000000002201021E4 -:1068E0008FBF001C8FB200188FB100148FB0001042 -:1068F00003E0000827BD00200E0003982404008454 -:106900001600FFD88F8700580A000474AF8000601B -:10691000020028210E0003BF240400018F870058C5 -:106920000A000474AF820060020028210E0003BF39 -:10693000000020210A0004A38F8700580E000404E1 -:10694000020020218F8700580A000474AF82006083 -:1069500030AFFFFF000F19C03C0480008C9001B8DD -:106960000600FFFE3C1920043C181000AC83018097 -:10697000AC800184AC990188AC9801B80A00047518 -:106980002628000190E2000390E30002000020218D -:106990000002FE0000033A0000FF2825240600083C -:1069A0000E000398000000001600FFDC2402000324 -:1069B0008F870058000010210A000474AF82006025 -:1069C00090E8000200002021240600090A0004C308 -:1069D00000082E0090E4000C240900FF308500FF21 -:1069E00010A900150000302190F9000290F8000372 -:1069F000308F00FF94EB000400196E000018740043 -:106A0000000F62000186202501AE5025014B28258C -:106A10003084FF8B0A0004C32406000A90E30002BE -:106A200090FF0004000020210003360000DF28252D -:106A30000A0004C32406000B0A0004D52406008BB8 -:106A4000000449C23127003F000443423C02800059 -:106A500000082040240316802CE60020AC43002CC4 -:106A600024EAFFE02482000114C0000330A900FFE3 -:106A700000801021314700FF000260803C0D800043 -:106A8000240A0001018D20213C0B000E00EA28049D -:106A9000008B302111200005000538278CCE000026 -:106AA00001C5382503E00008ACC700008CD8000001 -:106AB0000307782403E00008ACCF000027BDFFE007 -:106AC000AFB10014AFB00010AFBF00183C076000BA -:106AD0008CE408083402F0003C1160003083F000C0 -:106AE000240501C03C04800E000030211062000625 -:106AF000241000018CEA08083149F0003928E00030 -:106B00000008382B000780403C0D0200AE2D081411 -:106B1000240C16803C0B80008E2744000E000F8B47 -:106B2000AD6C002C120000043C02169124050001FB -:106B3000120500103C023D2C345800E0AE384408E9 -:106B40003C1108008E31007C8FBF00183C066000AD -:106B500000118540360F16808FB100148FB00010E1 -:106B60003C0E020027BD0020ACCF442003E000080B -:106B7000ACCE08103C0218DA345800E0AE384408B5 -:106B80003C1108008E31007C8FBF00183C0660006D -:106B900000118540360F16808FB100148FB00010A1 -:106BA0003C0E020027BD0020ACCF442003E00008CB -:106BB000ACCE08100A0004EB240500010A0004EB27 -:106BC0000000282124020400A7820024A780001CC2 -:106BD000000020213C06080024C65A582405FFFF67 -:106BE00024890001000440803124FFFF01061821A0 -:106BF0002C87002014E0FFFAAC6500002404040098 -:106C0000A7840026A780001E000020213C06080063 -:106C100024C65AD82405FFFF248D0001000460809B -:106C200031A4FFFF018658212C8A00201540FFFA6D -:106C3000AD650000A7800028A7800020A780002263 -:106C4000000020213C06080024C65B582405FFFFF5 -:106C5000249900010004C0803324FFFF030678213B -:106C60002C8E000415C0FFFAADE500003C05600065 -:106C70008CA73D002403E08F00E31024344601403C -:106C800003E00008ACA63D002487007F000731C266 -:106C900024C5FFFF000518C2246400013082FFFFF5 -:106CA000000238C0A78400303C010800AC27003047 -:106CB000AF80002C0000282100002021000030219E -:106CC0002489000100A728213124FFFF2CA81701E7 -:106CD000110000032C8300801460FFF924C600011A -:106CE00000C02821AF86002C10C0001DA786002AF6 -:106CF00024CAFFFF000A11423C08080025085B581F -:106D00001040000A00002021004030212407FFFF2E -:106D1000248E00010004688031C4FFFF01A86021B7 -:106D20000086582B1560FFFAAD87000030A2001FC7 -:106D30005040000800043080240300010043C804D0 -:106D400000041080004878212738FFFF03E0000886 -:106D5000ADF8000000C820212405FFFFAC8500002D -:106D600003E000080000000030A5FFFF30C6FFFF71 -:106D700030A8001F0080602130E700FF0005294295 -:106D80000000502110C0001D24090001240B000147 -:106D900025180001010B2004330800FF0126782686 -:106DA000390E00202DED00012DC2000101A2182591 -:106DB0001060000D014450250005C880032C4021BF -:106DC0000100182110E0000F000A20278D040000A8 -:106DD000008A1825AD03000024AD00010000402109 -:106DE0000000502131A5FFFF252E000131C9FFFF12 -:106DF00000C9102B1040FFE72518000103E0000830 -:106E0000000000008D0A0000014440240A0005D162 -:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC -:106E2000AFB00010AFBF001430E7FFFF00005021EB -:106E30003410FFFF0000602124AF001F00C0482174 -:106E4000241800012419002005E0001601E010219B -:106E50000002F943019F682A0009702B01AE40240B -:106E600011000017000C18800064102110E00005CC -:106E70008C4B000000F840040008382301675824B8 -:106E800000003821154000410000402155600016E7 -:106E90003169FFFF258B0001316CFFFF05E1FFEC3D -:106EA00001E0102124A2003E0002F943019F682A5C -:106EB0000009702B01AE40241500FFEB000C188078 -:106EC000154600053402FFFF020028210E0005B51B -:106ED00000003821020010218FBF00148FB0001075 -:106EE00003E0000827BD00181520000301601821E9 -:106EF000000B1C0224080010306A00FF154000053A -:106F0000306E000F250D000800031A0231A800FFA3 -:106F1000306E000F15C00005307F000325100004FF -:106F200000031902320800FF307F000317E000055C -:106F3000386900012502000200031882304800FF72 -:106F4000386900013123000110600004310300FFA3 -:106F5000250A0001314800FF310300FF000C6940A1 -:106F600001A34021240A000110CAFFD53110FFFF00 -:106F7000246E000131C800FF1119FFC638C9000195 -:106F80002D1F002053E0001C258B0001240D000163 -:106F90000A000648240E002051460017258B0001E8 -:106FA00025090001312800FF2D0900205120001281 -:106FB000258B000125430001010D5004014B1024D5 -:106FC000250900011440FFF4306AFFFF3127FFFF5D -:106FD00010EE000C2582FFFF304CFFFF0000502117 -:106FE0003410FFFF312800FF2D0900205520FFF24B -:106FF00025430001258B0001014648260A000602B0 -:10700000316CFFFF00003821000050210A000654B7 -:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 -:10702000AFB10014001039423211FFE000071080A8 -:10703000AFB3001C00B1282330D3FFFFAFB200185C -:1070400030A5FFFF00809021026030210044202104 -:10705000AFBF00200E0005E03207001F022288218A -:107060003403FFFF0240202102002821026030216A -:1070700000003821104300093231FFFF02201021A7 -:107080008FBF00208FB3001C8FB200188FB1001487 -:107090008FB0001003E0000827BD00280E0005E0B7 -:1070A0000000000000408821022010218FBF002036 -:1070B0008FB3001C8FB200188FB100148FB0001076 -:1070C00003E0000827BD0028000424003C03600002 -:1070D000AC603D0810A00002348210063482101605 -:1070E00003E00008AC623D0427BDFFE0AFB0001034 -:1070F000309000FF2E020006AFBF001810400008BD -:10710000AFB10014001030803C03080024635784A2 -:1071100000C328218CA400000080000800000000AB -:10712000000020218FBF00188FB100148FB0001015 -:107130000080102103E0000827BD00209791002A5D -:1071400016200051000020213C020800904200332C -:107150000A0006BB00000000978D002615A0003134 -:10716000000020210A0006BB2402000897870024A3 -:1071700014E0001A00001821006020212402000100 -:107180001080FFE98FBF0018000429C2004530219C -:1071900000A6582B1160FFE43C0880003C0720004B -:1071A000000569C001A76025AD0C00203C038008E4 -:1071B0002402001F2442FFFFAC6000000441FFFDD9 -:1071C0002463000424A5000100A6702B15C0FFF560 -:1071D000000569C00A0006A58FBF00189787001C2C -:1071E0003C04080024845A58240504000E0006605C -:1071F00024060001978B002424440001308AFFFFFD -:107200002569FFFF2D48040000402821150000409B -:10721000A789002424AC3800000C19C00A0006B964 -:10722000A780001C9787001E3C04080024845AD8BD -:10723000240504000E00066024060001979900262C -:10724000244400013098FFFF272FFFFF2F0E04007A -:107250000040882115C0002CA78F0026A780001EA3 -:107260003A020003262401003084FFFF0E00068D41 -:107270002C4500010011F8C027F00100001021C0CA -:107280000A0006BB240200089785002E978700227B -:107290003C04080024845B580E00066024060001AC -:1072A0009787002A8F89002C2445000130A8FFFF12 -:1072B00024E3FFFF0109302B0040802114C0001897 -:1072C000A783002AA7800022978500300E000F7543 -:1072D00002002021244A05003144FFFF0E00068DE4 -:1072E000240500013C05080094A500320E000F752E -:1072F00002002021244521003C0208009042003376 -:107300000A0006BB000521C00A0006F3A784001E80 -:1073100024AC3800000C19C00A0006B9A784001C70 -:107320000A00070DA7850022308400FF27BDFFE873 -:107330002C820006AFBF0014AFB000101040001543 -:1073400000A03821000440803C0308002463579CBF -:10735000010328218CA40000008000080000000028 -:1073600024CC007F000751C2000C59C23170FFFFCE -:107370002547C40030E5FFFF2784001C02003021B0 -:107380000E0005B52407000197860028020620217B -:10739000A78400288FBF00148FB0001003E00008FE -:1073A00027BD00183C0508008CA50030000779C2F5 -:1073B0000E00038125E4DF003045FFFF3C04080098 -:1073C00024845B58240600010E0005B52407000143 -:1073D000978E002A8FBF00148FB0001025CD0001BA -:1073E00027BD001803E00008A78D002A0007C9C2C6 -:1073F0002738FF00001878C231F0FFFF3C04080076 -:1074000024845AD802002821240600010E0005B564 -:1074100024070001978D0026260E0100000E84002F -:1074200025AC00013C0B6000A78C0026AD603D0838 -:1074300036040006000030213C0760008CE23D0469 -:10744000305F000617E0FFFD24C9000100061B00A5 -:10745000312600FF006440252CC50004ACE83D0443 -:1074600014A0FFF68FBF00148FB0001003E00008D7 -:1074700027BD0018000751C22549C8002406000195 -:10748000240700013C04080024845A580E0005B566 -:107490003125FFFF978700248FBF00148FB00010A5 -:1074A00024E6000127BD001803E00008A786002499 -:1074B0003C0660183C090800252900FCACC9502C8A -:1074C0008CC850003C0580003C020002350700805B -:1074D000ACC750003C04080024841FE03C030800B3 -:1074E00024631F98ACA50008ACA2000C3C01080066 -:1074F000AC2459A43C010800AC2359A803E00008BF -:107500002402000100A030213C1C0800279C59AC3B -:107510003C0C04003C0B0002008B3826008C4026FB -:107520002CE200010007502B2D050001000A4880C5 -:107530003C030800246359A4004520250123182199 -:107540001080000300001021AC660000240200013E -:1075500003E00008000000003C1C0800279C59AC18 -:107560003C0B04003C0A0002008A3026008B3826BF -:107570002CC200010006482B2CE5000100094080C8 -:107580003C030800246359A4004520250103182169 -:1075900010800005000010213C0C0800258C1F986D -:1075A000AC6C00002402000103E0000800000000B1 -:1075B0003C0900023C080400008830260089382677 -:1075C0002CC30001008028212CE400010083102539 -:1075D0001040000B000030213C1C0800279C59ACD7 -:1075E0003C0A80008D4E00082406000101CA68256F -:1075F000AD4D00088D4C000C01855825AD4B000C9D -:1076000003E0000800C010213C1C0800279C59AC76 -:107610003C0580008CA6000C0004202724020001F9 -:1076200000C4182403E00008ACA3000C3C020002D4 -:107630001082000B3C0560003C070400108700032B -:107640000000000003E00008000000008CA908D042 -:10765000240AFFFD012A402403E00008ACA808D05A -:107660008CA408D02406FFFE0086182403E000083E -:10767000ACA308D03C05601A34A600108CC300806F -:1076800027BDFFF88CC50084AFA3000093A40000C1 -:107690002402001010820003AFA5000403E00008DC -:1076A00027BD000893A7000114E0001497AC000266 -:1076B00097B800023C0F8000330EFFFC01CF682119 -:1076C000ADA50000A3A000003C0660008CC708D058 -:1076D0002408FFFE3C04601A00E82824ACC508D04A -:1076E0008FA300048FA200003499001027BD00086A -:1076F000AF22008003E00008AF2300843C0B800031 -:10770000318AFFFC014B48218D2800000A00080C3B -:10771000AFA8000427BDFFE8AFBF00103C1C080065 -:10772000279C59AC3C0580008CA4000C8CA2000462 -:107730003C0300020044282410A0000A00A31824DF -:107740003C0604003C0400021460000900A610245A -:107750001440000F3C0404000000000D3C1C080015 -:10776000279C59AC8FBF001003E0000827BD00180C -:107770003C0208008C4259A40040F80900000000B7 -:107780003C1C0800279C59AC0A0008358FBF00102C -:107790003C0208008C4259A80040F8090000000093 -:1077A0000A00083B000000003C0880008D0201B880 -:1077B0000440FFFE35090180AD2400003C031000A9 -:1077C00024040040AD250004A1240008A1260009DE -:1077D000A527000A03E00008AD0301B83084FFFFCD -:1077E0000080382130A5FFFF000020210A00084555 -:1077F000240600803087FFFF8CA400002406003898 -:107800000A000845000028218F8300788F860070C9 -:107810001066000B008040213C07080024E75B68ED -:10782000000328C000A710218C440000246300013D -:10783000108800053063000F5466FFFA000328C06B -:1078400003E00008000010213C07080024E75B6CFF -:1078500000A7302103E000088CC200003C03900028 -:1078600034620001008220253C038000AC640020CB -:107870008C65002004A0FFFE0000000003E000086B -:10788000000000003C0280003443000100832025FA -:1078900003E00008AC44002027BDFFE0AFB10014B6 -:1078A0003091FFFFAFB00010AFBF001812200013DF -:1078B00000A080218CA20000240400022406020003 -:1078C0001040000F004028210E0007250000000096 -:1078D00000001021AE000000022038218FBF0018E8 -:1078E0008FB100148FB0001000402021000028212B -:1078F000000030210A00084527BD00208CA20000AE -:10790000022038218FBF00188FB100148FB00010F3 -:107910000040202100002821000030210A000845F5 -:1079200027BD002000A010213087FFFF8CA5000498 -:107930008C4400000A000845240600068F83FD9C45 -:1079400027BDFFE8AFBF0014AFB00010906700087C -:10795000008010210080282130E600400000202116 -:1079600010C000088C5000000E0000BD0200202155 -:10797000020020218FBF00148FB000100A000548BC -:1079800027BD00180E0008A4000000000E0000BD76 -:1079900002002021020020218FBF00148FB00010B0 -:1079A0000A00054827BD001827BDFFE0AFB0001052 -:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 -:1079C00092060001008088210E00087230D2000467 -:1079D00092040005001129C2A6050000348300406E -:1079E000A20300050E00087C022020210E00054A9B -:1079F0000220202124020001AE02000C02202821D6 -:107A0000A602001024040002A602001224060200AE -:107A1000A60200140E000725A60200161640000F4D -:107A20008FBF001C978C00743C0B08008D6B007896 -:107A30002588FFFF3109FFFF256A0001012A382B45 -:107A400010E00006A78800743C0F6006240E0016A4 -:107A500035ED0010ADAE00508FBF001C8FB2001886 -:107A60008FB100148FB0001003E0000827BD002084 -:107A700027BDFFE0AFB10014AFBF0018AFB00010DA -:107A80001080000400A088212402008010820007DA -:107A9000000000000000000D8FBF00188FB100141F -:107AA0008FB0001003E0000827BD00200E00087210 -:107AB00000A020218F86FD9C0220202190C500057A -:107AC0000E00087C30B000FF2403003E1603FFF1D7 -:107AD0003C0680008CC401780480FFFE34C801405D -:107AE000240900073C071000AD11000002202021EE -:107AF000A10900048FBF00188FB100148FB00010CF -:107B0000ACC701780A0008C527BD002027BDFFE0EB -:107B1000AFB00010AFBF0018AFB100143C10800030 -:107B20008E110020000000000E00054AAE04002067 -:107B3000AE1100208FBF00188FB100148FB000105D -:107B400003E0000827BD00203084FFFF00803821BB -:107B50002406003500A020210A0008450000282145 -:107B60003084FFFF008038212406003600A0202149 -:107B70000A0008450000282127BDFFD0AFB500242A -:107B80003095FFFFAFB60028AFB40020AFBF002C88 -:107B9000AFB3001CAFB20018AFB10014AFB000100B -:107BA00030B6FFFF12A000270000A0218F920058DE -:107BB0008E4300003C0680002402004000033E0289 -:107BC00000032C0230E4007F006698241482001D1C -:107BD00030A500FF8F8300682C68000A1100001098 -:107BE0008F8D0044000358803C0C0800258C57B84A -:107BF000016C50218D4900000120000800000000A8 -:107C000002D4302130C5FFFF0E0008522404008446 -:107C1000166000028F920058AF8000688F8D00447C -:107C20002659002026980001032090213314FFFFDD -:107C300015A00004AF9900580295202B1480FFDC9A -:107C400000000000028010218FBF002C8FB600289A -:107C50008FB500248FB400208FB3001C8FB20018A2 -:107C60008FB100148FB0001003E0000827BD003072 -:107C70002407003414A70149000000009247000EB9 -:107C80008F9FFDA08F90FD9C24181600A3E700197C -:107C90009242000D3C0880003C07800CA3E20018D3 -:107CA000964A00123C0D60003C117FFFA60A005C62 -:107CB000964400103623FFFF240200053099FFFF91 -:107CC000AE1900548E46001CAD1800288CEF000041 -:107CD0008DAE444801E6482601C93021AE06003881 -:107CE0008E05003824CB00013C0E7F00AE05003C21 -:107CF0008E0C003CAFEC0004AE0B00208E13002075 -:107D0000AE13001CA3E0001BAE03002CA3E2001284 -:107D10008E4A001424130050AE0A00348E0400343E -:107D2000AFE400148E590018AE1900489258000CA8 -:107D3000A218004E920D000835AF0020A20F0008D7 -:107D40008E090018012E282434AC4000AE0C001817 -:107D5000920B0000317200FF1253027F2403FF8058 -:107D60003C04080024845BE80E0008AA0000000020 -:107D70003C1108008E315BE80E00087202202021C1 -:107D80002405000424080001A2050025022020216A -:107D90000E00087CA20800053C0580008CB001782C -:107DA0000600FFFE8F92005834AE0140240F0002FF -:107DB0003C091000ADD10000A1CF0004ACA90178AE -:107DC0000A000962AF8000682CAD003751A0FF9413 -:107DD0008F8D0044000580803C110800263157E05B -:107DE000021178218DEE000001C0000800000000A3 -:107DF0002411000414B1008C3C0780003C080800EA -:107E00008D085BE88F86FD9CACE800208E4500085D -:107E10008F99FDA0240D0050ACC500308E4C000899 -:107E2000ACCC00508E4B000CACCB00348E43001019 -:107E3000ACC300388E4A0010ACCA00548E42001405 -:107E4000ACC2003C8E5F0018AF3F00048E50001C97 -:107E5000ACD0002090C40000309800FF130D024AFF -:107E6000000000008CC400348CD00030009030231F -:107E700004C000F12404008C126000EE2402000310 -:107E80000A000962AF8200682419000514B900666F -:107E90003C0580003C0808008D085BE88F86FD9C4F -:107EA000ACA800208E4C00048F8AFDA0240720007F -:107EB000ACCC001C924B000824120008A14B001906 -:107EC0008F82005890430009A14300188F85005805 -:107ED00090BF000A33E400FF1092001028890009C7 -:107EE000152000BA240E0002240D0020108D000B76 -:107EF000340780002898002117000008240740005C -:107F000024100040109000053C0700012419008057 -:107F1000109900023C070002240740008CC20018A0 -:107F20003C03FF00004350240147F825ACDF001854 -:107F300090B2000BA0D200278F8300589464000CED -:107F4000108001FE000000009467000C3C1F8000C0 -:107F50002405FFBFA4C7005C9063000E2407000443 -:107F6000A0C300088F820058904A000FA0CA0009E1 -:107F70008F8900588D3200108FE400740244C823AA -:107F8000ACD900588D300014ACD0002C95380018B6 -:107F9000330DFFFFACCD00409531001A322FFFFFAB -:107FA000ACCF00448D2E001CACCE00489128000EB2 -:107FB000A0C8000890CC000801855824126001B6C2 -:107FC000A0CB00088F9200580A000962AF870068B2 -:107FD0002406000614A600143C0E80003C0F080086 -:107FE0008DEF5BE88F85FD98ADCF00208E4900189E -:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B -:1080000024040005ACA800048CCC003C1260008164 -:10801000AD6C00000A000962AF84006824110007FB -:1080200010B1004B240400063C05080024A55BE8C1 -:108030000E000881240400818F9200580013102B39 -:108040000A000962AF820068241F002314BFFFF6F4 -:108050003C0C80003C0508008CA55BE88F8BFDA0E4 -:10806000AD8500208F91FD9C8E4600042564002084 -:1080700026450014AE260028240600030E000F81BA -:10808000257000308F87005802002021240600034D -:108090000E000F8124E500083C04080024845BE8FE -:1080A0000E0008AA0000000092230000240A0050DD -:1080B000306200FF544AFFE18F9200580E000F6CAF -:1080C000000000000A000A6A8F920058240800335A -:1080D00014A800323C0380003C1108008E315BE89C -:1080E0008F8FFDA0AC7100208E420008240D002867 -:1080F0008F89FD9CADE200308E4A000C24060009F9 -:10810000ADEA00348E5F0010ADFF00388E440014DD -:10811000ADE400208E590018ADF900248E58001CE3 -:10812000ADF80028A1ED00118E4E00041260003160 -:10813000AD2E00288F9200580A000962AF860068B1 -:10814000240D002214ADFFB8000000002404000735 -:108150003C1008008E105BE83C188000AF10002037 -:108160005660FEAEAF8400683C04080024845BE8DF -:108170000E0008AA241300508F84FD9C90920000EA -:10818000325900FF1333014B000000008F9200585A -:10819000000020210A000962AF8400683C05080045 -:1081A00024A55BE80E000858240400810A000A6A2E -:1081B0008F92005802D498213265FFFF0E000852BA -:1081C000240400840A0009628F920058108EFF5325 -:1081D000240704002887000310E00179241100041B -:1081E000240F0001548FFF4D240740000A000A228B -:1081F000240701003C05080024A55BE80E0008A444 -:10820000240400828F920058000030210A00096285 -:10821000AF8600683C04080024845BE88CC2003808 -:108220000E0008AA8CC3003C8F9200580A000AC0B6 -:1082300000002021240400823C05080024A55BE8FE -:108240000E0008A4000000008F92005800001021CA -:108250000A000962AF8200688E5000048F91FD9C75 -:108260003C078000ACF00020922C00050200282181 -:10827000318B0002156001562404008A8F92FDA004 -:108280002404008D9245001B30A6002014C001502C -:1082900002002821922E00092408001231C900FF93 -:1082A0001128014B240400810E00087202002021D5 -:1082B0009258001B240F000402002021370D0042B9 -:1082C000A24D001B0E00087CA22F00253C0580005B -:1082D0008CA401780480FFFE34B90140241F000201 -:1082E000AF300000A33F00048F9200583C101000F4 -:1082F000ACB001780A000A6B0013102B8E500004FA -:108300008F91FD9C3C038000AC700020922A0005F8 -:108310000200282131420002144000172404008A80 -:10832000922C00092412000402002821318B00FF46 -:1083300011720011240400810E0008720200202135 -:108340008F89FDA0240800122405FFFE912F001B39 -:108350000200202135EE0020A12E001BA2280009DA -:108360009226000500C538240E00087CA2270005CF -:1083700002002821000020210E0009330000000027 -:108380000A000A6A8F9200588E4C00043C07800055 -:108390003C10080026105BE8ACEC00203C01080013 -:1083A000AC2C5BE8924B0003317100041220013BBE -:1083B0008F84FD9C24020006A0820009924F001BBE -:1083C000240EFFC031E9003F012E4025A08800089F -:1083D0009245000330A6000114C0013200000000E5 -:1083E0008E420008AE0200083C0208008C425BF09E -:1083F000104001318F90FDA0000219C28F8DFD9CAD -:10840000A603000C8E4A000C24180001240400145A -:10841000AE0A002C8E420010AE02001C965F0016C1 -:10842000A61F003C96590014A619003EADB8000CDA -:10843000A5B80010A5B80012A5B80014A5B800167C -:1084400012600144A2040011925100033232000272 -:108450002E5300018F920058266200080A0009621C -:10846000AF8200688E4400043C1980003C068008FE -:10847000AF2400208E45000890D80000240D005045 -:10848000331100FF122D009C2407008824060009E8 -:108490000E000845000000000A000A6A8F9200588A -:1084A0008E5000043C0980003C118008AD30002053 -:1084B0009228000024050050310400FF10850110AF -:1084C0002407008802002021000028210E00084512 -:1084D0002406000E922D00002418FF80020028219F -:1084E00001B8802524040004240600300E0007256E -:1084F000A23000000A000A6A8F9200588E500004D1 -:108500008F91FDA03C028000AC500020923F001BE8 -:1085100033F900101320006C240700810200202191 -:10852000000028212406001F0E000845000000005E -:108530000A000A6A8F9200588E44001C0E00085DE3 -:1085400000000000104000E3004048218F880058E0 -:1085500024070089012020218D05001C240600012C -:108560000E000845000000000A000A6A8F920058B9 -:10857000964900023C10080026105BE831280004F0 -:10858000110000973C0460008E4E001C3C0F8000E0 -:10859000ADEE00203C010800AC2E5BE896470002DF -:1085A00030E40001148000E6000000008E42000468 -:1085B000AE0200083C1008008E105BF0120000ECC8 -:1085C0003C0F80008F92FD9C241000018E4E0018FD -:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 -:1085E000A2400005AE50000C3C0808008D085BF06E -:1085F0008F840058A6500010000839C2A6500012FF -:10860000A6500014A6500016A5A7000C8C8C0008DC -:108610008F8B00588F8A0058ADAC002C8D63000CF6 -:1086200024070002ADA3001C91460010A1A6001172 -:108630008F82005890450011A3E500088F990058DB -:1086400093380012A258004E8F910058922F0013B9 -:10865000A1AF00128F920058964E0014A5AE003CB8 -:1086600096490016A5A9003E8E480018ADA8001432 -:108670005660FD6AAF8700683C05080024A55BE8EA -:108680000E000881000020218F9200580000382140 -:108690000A000962AF8700683C05080024A55BE872 -:1086A0000E0008A4240400828F9200580A000A4D8C -:1086B000000038210E000F6C000000008F9200585F -:1086C0000A000AC0000020210E00087202002021CA -:1086D0009223001B02002021346A00100E00087C47 -:1086E000A22A001B000038210200202100002821BE -:1086F0000A000BA52406001F9242000C305F000107 -:1087000013E0000300000000964A000EA4CA002CEB -:10871000924B000C316300025060000600003821CB -:108720008E470014964C0012ACC7001CA4CC001A53 -:10873000000038210A000B7F240600093C050800D0 -:1087400024A55BE80E0008A42404008B8F92005837 -:108750000A000A4D0013382B3C0C08008D8C5BE896 -:1087600024DFFFFE25930100326B007F016790211B -:1087700002638824AD110028AE4600E0AE4000E45C -:108780000A0009B3AE5F001CACC000543C0D0800E9 -:108790008DAD5BE83C18800C37090100ACED00287A -:1087A0008E510014AD3100E08E4F0014AD2F00E467 -:1087B0008E4E001025C7FFFE0A0009F4AD27001CED -:1087C0005491FDD6240740000A000A222407100015 -:1087D0000E00092D000000000A000A6A8F9200585E -:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 -:1087F000AC205BE810710062000000003C196C6264 -:1088000037387970147800082404000297850074C2 -:108810009782006C2404009200A2F82B13E0001948 -:1088200002002821240400020E00069524050200FF -:108830003C068000ACC200203C010800AC225BE892 -:108840001040000D8F8C0058240A002824040003D7 -:10885000918B0010316300FF546A00012404000171 -:108860000E0000810000000010400004240400837A -:108870000A000BC28F920058240400833C050800B4 -:1088800024A55BE80E000881000000008F920058CC -:108890000013382B0A000962AF8700680A000B49F1 -:1088A000240200128E4400080E00085D0000000043 -:1088B0000A000B55AE0200083C05080024A55BE841 -:1088C0000E000858240400878F9200580A000B728B -:1088D0000013102B240400040E000695240500301C -:1088E0001440002A004048218F8800582407008344 -:1088F000012020218D05001C0A000BB32406000175 -:108900008F8300788F8600701066FEEE000038219D -:108910003C07080024E75B6C000320C00087282187 -:108920008CAE000011D0005D246F000131E3000F18 -:108930005466FFFA000320C00A000B8C00003821A7 -:108940008E4400040E00085D000000000A000BC801 -:10895000AE0200083C05080024A55BE80E0008A450 -:10896000240400828F9200580A000B72000010212C -:108970003C05080024A55BE80A000C7C2404008761 -:108980008C83442C0A000C5B3C196C628F88005865 -:108990003C0780083C0C8000240B0050240A000196 -:1089A000AD820020A0EB0000A0EA000191030004CA -:1089B000A0E3001891040005A0E400199106000648 -:1089C0003C04080024845B6CA0E6001A91020007B6 -:1089D0003C06080024C65B68A0E2001B9105000865 -:1089E000A0E5001C911F0009A0FF001D9119000ABD -:1089F000A0F9001E9118000BA0F8001F9112000CA6 -:108A0000A0F200209111000DA0F100219110000EA4 -:108A1000A0F00022910F000FA0EF0023910E001094 -:108A2000A0EE0024910D0011A0ED0025950C00147E -:108A3000A4EC0028950B00168F8A00708F920078A6 -:108A4000A4EB002A95030018000A10C02545000178 -:108A5000A4E3002C8D1F001C0044C0210046C82147 -:108A600030A5000FAF3F0000AF09000010B20006B4 -:108A7000AF850070000038218D05001C01202021E9 -:108A80000A000BB32406000124AD000131A7000F3A -:108A9000AF8700780A000CF9000038213C06080076 -:108AA00024C65B680086902100003821ACA000003D -:108AB0000A000B8CAE4000003C0482013C036000C5 -:108AC00034820E02AC603D68AF80009803E000087D -:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 -:108AE000001018422C620041AFBF00141440000275 -:108AF00024040080240300403C010800AC300060E6 -:108B00003C010800AC2300640E000F7500602821B2 -:108B1000244802BF2409FF8001092824001039805D -:108B2000001030408FBF00148FB0001000A720212C -:108B300000861821AF8300803C010800AC25005856 -:108B40003C010800AC24005C03E0000827BD0018CD -:108B5000308300FF30C6FFFF30E400FF3C08800098 -:108B60008D0201B80440FFFE000354000144382583 -:108B70003C09600000E920253C031000AD050180A0 -:108B8000AD060184AD04018803E00008AD0301B81F -:108B90008F8500583C0A6012354800108CAC0004E8 -:108BA0003C0D600E35A60010318B00062D690001CA -:108BB000AD0900C48CA70004ACC731808CA20008AA -:108BC00094A40002ACC231848CA3001C0460000396 -:108BD000A784009003E00008000000008CAF00189C -:108BE000ACCF31D08CAE001C03E00008ACCE31D449 -:108BF0008F8500588F87FF288F86FF308CAE00044A -:108C00003C0F601235E80010ACEE00788CAD000827 -:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 -:108C2000ACCB004894CA00543C0208008C4200447B -:108C300025490001A4C9005494C400543083FFFFA7 -:108C400010620017000000003C0208008C42004047 -:108C5000A4C200528CA30018ACE300308CA2001414 -:108C6000ACE2002C8CB90018ACF900388CB80014B8 -:108C700024050001ACF800348D0600BC50C5001975 -:108C80008D0200B48D0200B8A4E2004894E40048CC -:108C9000A4E4004A94E800EA03E000083102FFFF80 -:108CA0003C0208008C420024A4C00054A4C200521C -:108CB0008CA30018ACE300308CA20014ACE2002CB2 -:108CC0008CB90018ACF900388CB8001424050001E8 -:108CD000ACF800348D0600BC54C5FFEB8D0200B823 -:108CE0008D0200B4A4E2004894E40048A4E4004AE1 -:108CF00094E800EA03E000083102FFFF8F86005885 -:108D00003C0480008CC900088CC80008000929C0F8 -:108D1000000839C0AC87002090C30007306200040F -:108D20001040003EAF85009490CB0007316A0008E8 -:108D30001140003D8F87FF2C8CCD000C8CCE001491 -:108D400001AE602B11800036000000008CC2000CC8 -:108D5000ACE200708CCB00188F85FF288F88FF3025 -:108D6000ACEB00748CCA00102402FFF8ACAA00D847 -:108D70008CC9000CAD0900608CC4001CACA400D0F0 -:108D800090E3007C0062C824A0F9007C90D8000722 -:108D9000330F000811E000040000000090ED007C9B -:108DA00035AC0001A0EC007C90CF000731EE000153 -:108DB00011C000060000000090E3007C241800347D -:108DC00034790002A0F9007CACB800DC90C2000746 -:108DD0003046000210C000040000000090E8007C53 -:108DE00035040004A0E4007C90ED007D3C0B600E97 -:108DF000356A001031AC003FA0EC007D8D4931D4C4 -:108E00003127000110E00002240E0001A0AE00098D -:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 -:108E20000A000DAF8CC200140A000DB0ACE0007057 -:108E30008F8C005827BDFFD8AFB3001CAFB200180D -:108E4000AFB00010AFBF0020AFB10014918F00157C -:108E50003C13600E3673001031EB000FA38B009CA7 -:108E60008D8F00048D8B0008959F0012959900103E -:108E70009584001A9598001E958E001C33EDFFFF17 -:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 -:108E90003C010800AC2D00243C010800AC29004432 -:108EA0003C010800AC2A0040AE683178AE67317CE6 -:108EB00091850015959100163C12601236520010F3 -:108EC00030A200FF3230FFFFAE623188AE5000B4F6 -:108ED00091830014959F0018240600010066C804C1 -:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 -:108EF000AF8F00843C08600631CD00FFAE4D00C04E -:108F0000918A00159584000E3C07600A314900FFE4 -:108F1000AF8B00883084FFFFAE4900C835110010C8 -:108F20000E000D1034F004103C0208008C4200606A -:108F30003C0308008C6300643C0608008CC60058A3 -:108F40003C0508008CA5005C8F8400808FBF00204A -:108F5000AE23004CAE65319CAE030054AE4500DC40 -:108F6000AE6231A0AE6331A4AE663198AE22004845 -:108F70008FB3001CAE0200508FB10014AE4200E06F -:108F8000AE4300E4AE4600D88FB000108FB2001898 -:108F90000A00057D27BD0028978500929783007CF5 -:108FA00027BDFFE8AFB0001000A3102BAFBF001427 -:108FB000240400058F900058104000552409000239 -:108FC0000E0006958F850080AF8200942404000374 -:108FD0001040004F240900023C0680000E00008172 -:108FE000ACC2002024070001240820001040004DDE -:108FF00024040005978E00928F8AFF2C24090050CC -:1090000025C50001A7850092A14900003C0D08007C -:109010008DAD0064240380008F84FF28000D66005E -:10902000AD4C0018A5400006954B000A8F85FF3017 -:109030002402FF8001633024A546000A915F000AE4 -:109040000000482103E2C825A159000AA0A0000899 -:10905000A140004CA08000D5961800029783009094 -:109060003C020004A49800EA960F00022418FFBFF7 -:1090700025EE2401A48E00BE8E0D0004ACAD00448C -:109080008E0C0008ACAC0040A4A00050A4A000547A -:109090008E0B000C240C0030AC8B00288E060010C8 -:1090A000AC860024A480003EA487004EA487005014 -:1090B000A483003CAD420074AC8800D8ACA800602A -:1090C000A08700FC909F00D433F9007FA09900D4C2 -:1090D000909000D402187824A08F00D4914E007C88 -:1090E00035CD0001A14D007C938B009CAD480070F4 -:1090F000AC8C00DCA08B00D68F8800888F87008422 -:10910000AC8800C4AC8700C8A5400078A540007AB0 -:109110008FBF00148FB000100120102103E0000861 -:1091200027BD00188F8500940E0007258F860080CC -:109130000A000E9F2409000227BDFFE0AFB0001017 -:109140008F900058AFB10014AFBF00188E09000413 -:109150000E00054A000921C08E0800048F84FF28F4 -:109160008F82FF30000839C03C068000ACC7002069 -:10917000948500EA904300131460001C30B1FFFF97 -:109180008F8CFF2C918B0008316A00401540000B3A -:10919000000000008E0D0004022030218FBF001857 -:1091A0008FB100148FB00010240400220000382179 -:1091B000000D29C00A000D2F27BD00200E000098C9 -:1091C000000000008E0D0004022030218FBF001827 -:1091D0008FB100148FB00010240400220000382149 -:1091E000000D29C00A000D2F27BD00200E000090A1 -:1091F000000000008E0D0004022030218FBF0018F7 -:109200008FB100148FB00010240400220000382118 -:10921000000D29C00A000D2F27BD002027BDFFE04B -:10922000AFB200183092FFFFAFB00010AFBF001C0C -:10923000AFB100141240001E000080218F8600583C -:109240008CC500002403000600053F02000514023F -:1092500030E4000714830016304500FF2CA80006F8 -:1092600011000040000558803C0C0800258C58BCBB -:10927000016C50218D490000012000080000000011 -:109280008F8E0098240D000111CD005024020002A1 -:10929000AF820098260900013130FFFF24C800206A -:1092A0000212202B010030211480FFE5AF88005806 -:1092B000020010218FBF001C8FB200188FB1001464 -:1092C0008FB0001003E0000827BD00209387007EC8 -:1092D00054E00034000030210E000DE700000000D3 -:1092E0008F8600580A000EFF240200018F87009825 -:1092F0002405000210E50031240400130000282199 -:1093000000003021240700010E000D2F0000000096 -:109310000A000F008F8600588F83009824020002F5 -:109320001462FFF6240400120E000D9A00000000E3 -:109330008F85009400403021240400120E000D2F70 -:10934000000038210A000F008F8600588F83009894 -:109350002411000310710029241F0002107FFFCE8A -:1093600026090001240400100000282100003021FB -:109370000A000F1D240700018F91009824060002A7 -:109380001626FFF9240400100E000E410000000014 -:10939000144000238F9800588F8600580A000EFF53 -:1093A00024020003240400140E000D2F00002821C5 -:1093B0008F8600580A000EFF240200020E000EA93C -:1093C000000000000A000F008F8600580E000D3FBD -:1093D00000000000241900022404001400002821C9 -:1093E0000000302100003821AF9900980E000D2FA9 -:1093F000000000000A000F008F8600580E000D5775 -:10940000000000008F8500942419000200403021E4 -:1094100024040010000038210A000F56AF9900986C -:109420000040382124040010970F0002000028217A -:109430000E000D2F31E6FFFF8F8600580A000F0047 -:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D -:109450008C8500182402000100A61824AC83001893 -:1094600003E00008A08200053084FFFF30A5FFFF65 -:109470001080000700001821308200011040000217 -:1094800000042042006518211480FFFB00052840DD -:1094900003E000080060102110C000070000000079 -:1094A0008CA2000024C6FFFF24A50004AC820000AB -:1094B00014C0FFFB2484000403E000080000000047 -:1094C00010A0000824A3FFFFAC86000000000000ED -:1094D000000000002402FFFF2463FFFF1462FFFA74 -:1094E0002484000403E0000800000000000411C010 -:1094F00003E000082442024027BDFFE8AFB000109F -:1095000000808021AFBF00140E000F9600A0202124 -:1095100000504821240AFF808FBF00148FB0001034 -:10952000012A30243127007F3C08800A3C042100B6 -:1095300000E8102100C428253C03800027BD001846 -:10954000AC650024AF820038AC400000AC6500245C -:1095500003E00008AC4000403C0D08008DAD005811 -:1095600000056180240AFF8001A45821016C482174 -:10957000012A30243127007F3C08800C3C04210064 -:1095800000E8102100C428253C038000AC650028B9 -:10959000AF82003403E00008AC40002430A5FFFF98 -:1095A0003C0680008CC201B80440FFFE3C086015F8 -:1095B00000A838253C031000ACC40180ACC0018475 -:1095C000ACC7018803E00008ACC301B83C0D08003B -:1095D0008DAD005800056180240AFF8001A4582148 -:1095E000016C4021010A4824000931403107007F05 -:1095F00000C728253C04200000A418253C02800058 -:10960000AC43083003E00008AF80003427BDFFE81A -:10961000AFB0001000808021AFBF00140E000F9685 -:1096200000A0202100504821240BFF80012B502452 -:10963000000A39403128007F3C0620008FBF00140B -:109640008FB0001000E8282534C2000100A21825C0 -:109650003C04800027BD0018AC83083003E00008FC -:10966000AF8000383C0580088CA700603C0680086D -:109670000087102B144000112C8340008CA8006040 -:109680002D0340001060000F240340008CC90060CF -:109690000089282B14A00002008018218CC30060D0 -:1096A00000035A42000B30803C0A0800254A59202A -:1096B00000CA202103E000088C8200001460FFF340 -:1096C0002403400000035A42000B30803C0A08008B -:1096D000254A592000CA202103E000088C8200009E -:1096E0003C05800890A60008938400AB24C20001CA -:1096F000304200FF3043007F1064000C0002382726 -:10970000A0A200083C0480008C85017804A0FFFE24 -:109710008F8A00A0240900023C081000AC8A014096 -:10972000A089014403E00008AC8801780A00101BFE -:1097300030E2008027BDFFD8AFB200188F9200A49E -:10974000AFBF0020AFB3001CAFB00010AFB100142A -:109750008F9300348E5900283C1000803C0EFFEFA0 -:10976000AE7900008E580024A260000A35CDFFFFBC -:10977000AE7800049251002C3C0BFF9F356AFFFF2E -:10978000A271000C8E6F000C3C080040A271000B0F -:1097900001F06025018D4824012A382400E8302595 -:1097A000AE66000C8E450004AE6000183C0400FF5D -:1097B000AE6500148E43002C3482FFFFA6600008C3 -:1097C0000062F824AE7F00108E5900088F9000A030 -:1097D000964E0012AE7900208E51000C31D83FFF1A -:1097E00000187980AE7100248E4D001401F06021C4 -:1097F00031CB0001AE6D00288E4A0018000C41C22A -:10980000000B4B80AE6A002C8E46001C01093821EB -:10981000A667001CAE660030964500028E4400200C -:10982000A665001EAE64003492430033306200042B -:1098300054400006924700003C0280083443010077 -:109840008C7F00D0AE7F0030924700008F860038BA -:10985000A0C700309245003330A4000250800007BA -:10986000925100018F880038240BFF80910A00304C -:10987000014B4825A1090030925100018F9000381A -:10988000240CFFBF2404FFDFA21100318F8D0038AC -:109890003C1880083711008091AF003C31EE007F0A -:1098A000A1AE003C8F890038912B003C016C502404 -:1098B000A12A003C8F9F00388E68001493E6003C7C -:1098C0002D0700010007114000C4282400A218251C -:1098D000A3E3003C8F87003896590012A4F90032A8 -:1098E0008E450004922E007C30B0000300107823D7 -:1098F00031ED000300AD102131CC000215800002D3 -:1099000024460034244600303C0280083443008062 -:10991000907F007C00BFC824333800041700000289 -:1099200024C2000400C010218F98003824190002BE -:10993000ACE20034A3190000924F003F8F8E003834 -:109940003C0C8008358B0080A1CF00018F9100383E -:10995000924D003F8E440004A62D0002956A005CE3 -:109960000E000FF43150FFFF00024B800209382532 -:109970003C08420000E82825AE2500048E4400384B -:109980008F850038ACA400188E460034ACA6001CAD -:10999000ACA0000CACA00010A4A00014A4A0001661 -:1099A000A4A00020A4A00022ACA000248E62001479 -:1099B00050400001240200018FBF00208FB3001C23 -:1099C0008FB200188FB100148FB00010ACA2000845 -:1099D0000A00101327BD002827BDFFC83C058008DA -:1099E00034A40080AFBF0034AFBE0030AFB7002C4E -:1099F000AFB60028AFB50024AFB40020AFB3001C51 -:109A0000AFB20018AFB10014AFB00010948300786B -:109A10009482007A104300512405FFFF0080F0215A -:109A20000A0011230080B821108B004D8FBF003435 -:109A30008F8600A03C1808008F18005C2411FF805E -:109A40003C1680000306782101F18024AED0002C62 -:109A500096EE007A31EC007F3C0D800E31CB7FFF1B -:109A6000018D5021000B4840012AA82196A4000036 -:109A70003C0808008D0800582405FF8030953FFF02 -:109A800001061821001539800067C8210325F82434 -:109A90003C02010003E290253338007F3C11800C2A -:109AA000AED20028031190219250000D320F000415 -:109AB00011E0003702E0982196E3007A96E8007AF8 -:109AC00096E5007A2404800031077FFF24E300013B -:109AD00030627FFF00A4F82403E2C825A6F9007ACB -:109AE00096E6007A3C1408008E94006030D67FFF22 -:109AF00012D400C1000000008E5800188F8400A00E -:109B000002A028212713FFFF0E000FCEAE53002C1A -:109B100097D5007897D4007A12950010000028217C -:109B20003C098008352401003C0A8008914800085F -:109B3000908700D53114007F30E400FF0284302B81 -:109B400014C0FFB9268B0001938E00AB268C000158 -:109B5000008E682115ACFFB78F8600A08FBF003440 -:109B60008FBE00308FB7002C8FB600288FB5002431 -:109B70008FB400208FB3001C8FB200188FB1001477 -:109B80008FB0001000A0102103E0000827BD0038AE -:109B900000C020210E000F99028028218E4B00105A -:109BA0008E4C00308F84003824090002016C502351 -:109BB000AE4A0010A089000096E3005C8E4400309D -:109BC0008F9100380E000FF43070FFFF00024380C9 -:109BD000020838253C02420000E22825AE25000498 -:109BE0008E5F00048F8A00388E590000240B000815 -:109BF000AD5F001CAD590018AD40000CAD40001029 -:109C00009246000A240400052408C00030D000FF5A -:109C1000A550001496580008A55800169251000A45 -:109C20003C188008322F00FFA54F0020964E0008F8 -:109C300037110100A54E0022AD400024924D000BCB -:109C400031AC00FFA54C0002A14B00018E49003051 -:109C50008F830038240BFFBFAC690008A06400307C -:109C60008F9000382403FFDF9607003200E8282495 -:109C700000B51025A6020032921F003233F9003FD2 -:109C800037260040A20600328F8C0038AD800034A9 -:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F -:109CA00031CD007FA18D003C8F84003835EEFFFF61 -:109CB000908A003C014B4824A089003C8F850038E5 -:109CC00090A8003C01033824A0A7003C8E42003439 -:109CD0008F9100383C038008AE2200408E59002C42 -:109CE0008E5F0030033F3023AE26004492300048A0 -:109CF0003218007FA23800488F8800388E4D00301F -:109D00008D0C004801AE582401965024014B482583 -:109D1000AD0900489244000AA104004C964700088F -:109D20008F850038A4A7004E8E5000308E4400303E -:109D30000E0003818C65006092F9007C0002F940FE -:109D4000004028210002110003E2302133360002D6 -:109D500012C00003020680210005B0800216802197 -:109D6000926D007C31B30004126000020005708027 -:109D7000020E80218E4B00308F8800382405800031 -:109D8000316A0003000A4823312400030204182129 -:109D9000AD03003496E4007A96F0007A96F1007AEA -:109DA00032027FFF2447000130FF7FFF0225C824D5 -:109DB000033F3025A6E6007A96F8007A3C120800A8 -:109DC0008E520060330F7FFF11F200180000000078 -:109DD0008F8400A00E000FCE02A028218F8400A047 -:109DE0000E000FDE028028210E001013000000007C -:109DF0000A00111F0000000096F1007A022480245E -:109E0000A6F0007A92EF007A92EB007A31EE00FF32 -:109E1000000E69C2000D6027000C51C03169007F3F -:109E2000012A20250A001119A2E4007A96E6007A98 -:109E300000C5C024A6F8007A92EF007A92F3007A67 -:109E400031F200FF001271C2000E6827000DB1C090 -:109E5000326C007F01962825A2E5007A0A0011D015 -:109E60008F8400A03C0380003084FFFF30A5FFFFFB -:109E7000AC640018AC65001C03E000088C620014A0 -:109E800027BDFFA03C068008AFBF005CAFBE0058F6 -:109E9000AFB70054AFB60050AFB5004CAFB40048F8 -:109EA000AFB30044AFB20040AFB1003CAFB0003838 -:109EB00034C80100910500D590C700083084FFFF29 -:109EC00030A500FF30E2007F0045182AAFA4001043 -:109ED000A7A00018A7A0002610600055AFA000148E -:109EE00090CA00083149007F00A9302324D3FFFF26 -:109EF0000013802B8FB400100014902B02128824C2 -:109F0000522000888FB300143C03800894790052DB -:109F1000947E00508FB60010033EC0230018BC0092 -:109F2000001714030016FC0002C2A82A16A00002A3 -:109F3000001F2C030040282100133C0000072403CD -:109F400000A4102A5440000100A020212885000907 -:109F500014A000020080A021241400083C0C8008FA -:109F60008D860048001459808D88004C3C03800089 -:109F70003169FFFF3C0A0010012A202534710400DA -:109F8000AC660038AF9100A4AC68003CAC64003013 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB0008C6E000031CD002011A0FFFD0014782A26 -:109FC00001F01024104000390000A8213C16800840 -:109FD00092D700083C1280008E44010032F6007FC8 -:109FE0000E000F9902C028218E3900108E44010006 -:109FF0000000902133373FFF0E000FB102E028210F -:10A00000923800003302003F2C500008520000102C -:10A0100000008821000210803C030800246358E4FB -:10A020000043F8218FFE000003C00008000000007C -:10A0300090CF0008938C00AB31EE007F00AE682318 -:10A04000018D58210A0012172573FFFF0000882197 -:10A050003C1E80008FC401000E000FCE02E02821BC -:10A060008FC401000E000FDE02C028211220000F55 -:10A070000013802B8F8B00A426A400010004AC00E9 -:10A08000027298230015AC032578004002B4B02A70 -:10A090000013802B241700010300882102D0102414 -:10A0A000AF9800A41440FFC9AFB700143C07800864 -:10A0B00094E200508FAE00103C05800002A288217F -:10A0C0003C060020A4F10050ACA6003094F40050EF -:10A0D00094EF005201D51823306CFFFF11F4001EDD -:10A0E000AFAC00108CEF004C001561808CF500487F -:10A0F00001EC28210000202100AC582B02A4C02133 -:10A10000030BB021ACE5004CACF600488FB4001056 -:10A110000014902B021288241620FF7C3C03800838 -:10A120008FB300148FBF005C8FBE00583A620001ED -:10A130008FB700548FB600508FB5004C8FB40048D5 -:10A140008FB300448FB200408FB1003C8FB0003815 -:10A1500003E0000827BD006094FE00548CF2004428 -:10A1600033C9FFFE0009C8C00259F821ACBF003C4A -:10A170008CE800448CAD003C010D50231940003B9D -:10A18000000000008CF7004026E20001ACA200387D -:10A190003C05005034A700103C038000AC67003041 -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C0008C7800003316002012C0FFFD3C1180087F -:10A1D000962200543C1580003C068008304E000159 -:10A1E000000E18C0007578218DEC04003C070800B3 -:10A1F0008CE700443C040020ACCC00488DF40404FF -:10A20000240B0001ACD4004C10EB0260AEA4003073 -:10A21000963900523C0508008CA5004000B99021F9 -:10A22000A6320052963F005427ED0001A62D00549F -:10A230009626005430C4FFFF5487FF2F8FB40010C0 -:10A2400030A5FFFF0E0011F4A62000543C070800C3 -:10A250008CE70024963E00520047B82303D74823DA -:10A26000A62900520A0012198FB400108CE2004097 -:10A270000A0012BE00000000922400012407000121 -:10A280003085007F14A7001C97AD00268E2B00148C -:10A29000240CC000316A3FFF01AC48243C06080092 -:10A2A0008CC60060012A402531043FFF0086882BC0 -:10A2B00012200011A7A800263C0508008CA5005814 -:10A2C0008F9100A0000439802402FF8000B1182182 -:10A2D0000067F82103E2F02433F8007F3C1280008D -:10A2E0003C19800EAE5E002C0319702191D0000D38 -:10A2F000360F0004A1CF000D0E001028241200011B -:10A30000241100013C1E80008FC401000E000FCEFE -:10A3100002E028218FC401000E000FDE02C02821B8 -:10A320001620FF558F8B00A40A0012860013802B85 -:10A330008F8600A490C80001310400201080019194 -:10A34000241000013C048008348B0080916A007C5A -:10A350008F9E0034AFA0002C314900011120000F66 -:10A36000AFB000288CCD00148C8E006001AE602B45 -:10A370001580000201A038218C8700603C188008FD -:10A38000370300808C70007000F0782B15E000021D -:10A3900000E020218C640070AFA4002C3C028008F7 -:10A3A000344500808CD200148CBF0070025FC82B33 -:10A3B00017200002024020218CA400708FA7002CDF -:10A3C0000087182310600003AFA3003024050002AB -:10A3D000AFA500288FA400280264882B162000BA9D -:10A3E000000018218CD000388FCE000C3C0F00806C -:10A3F000AFD000008CCD00343C0CFF9F01CF58251E -:10A40000AFCD000490CA003F3586FFFF01662024CF -:10A410003C0900203C08FFEFA3CA000B0089382547 -:10A420003511FFFF00F118243C0500088F8700A4B8 -:10A430000065C825AFD9000C8CE20014AFC000182D -:10A440008FA60030AFC200148CF800188FB0002C1B -:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A -:10A4600003326824AFCF00248CEC000C020670216C -:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B -:10A48000AFCC0020AFC000288CEA00148FAB002CAA -:10A49000014B48230126402311000011AFC80010D2 -:10A4A00090EB003D8FC900048FC80000000B5100E5 -:10A4B000012A28210000102100AA882B010218215E -:10A4C0000071F821AFC50004AFDF000090F2003D3D -:10A4D000A3D2000A8F9900A497380006A7D80008D5 -:10A4E0008F910038240800023C038008A228000055 -:10A4F0003465008094BF005C8FA4002C33F0FFFF14 -:10A500000E000FF48F9200380002CB808F8500A4DC -:10A51000021978253C18420001F87025AE4E00045F -:10A520008F8400388CAD0038AC8D00188CAC0034B2 -:10A53000AC8C001CAC80000CAC800010A48000141B -:10A54000A4800016A4800020A4800022AC800024F7 -:10A5500090A6003F8FA7002CA486000250E0019235 -:10A56000240700018FA200305040000290A2003D5D -:10A5700090A2003E244A0001A08A00018F84003886 -:10A580008FA9002CAC8900083C128008364D008051 -:10A5900091AC007C3186000214C000022407003414 -:10A5A000240700308F8500A43C198008373F0080C5 -:10A5B00090B0000093F9007C240E0004A0900030BD -:10A5C0008F8F00A48FB8002C8F8D003891F200017E -:10A5D0003304000301C46023A1B200318F8E003820 -:10A5E0008F8600A42402C00095CA003294C90012CC -:10A5F0008FAB002C0142402431233FFF010388250B -:10A60000A5D1003291D000323185000300EBF82152 -:10A610003218003F370F0040A1CF00328FA4002C2A -:10A6200003E5382133280004108000028F850038AC -:10A6300000E838213C0A8008ACA700343549010005 -:10A640008D2800D08FA3002C2419FFBFACA80038A0 -:10A6500090B1003C2C640001240FFFDF3227007F03 -:10A66000A0A7003C8F98003800049140931F003C45 -:10A6700003F98024A310003C8F8C0038918E003C9D -:10A6800001CF682401B23025A186003C8F8900A447 -:10A690008F8800388D2B0020AD0B00408D220024C8 -:10A6A000AD0200448D2A0028AD0A00488D23002CFD -:10A6B0000E001013AD03004C8FB1002824070002D8 -:10A6C000122700118FA300280003282B00058023E8 -:10A6D0000270982400608021006090210A00126FAF -:10A6E0000010882B962900128F8400A00000902172 -:10A6F0003125FFFFA7A900180E000FC22411000189 -:10A700000A00131D3C1E80003C0B80003C12800898 -:10A710008D640100924900088F92FF340E000F995A -:10A720003125007F8F9900388FA700288FA4003033 -:10A73000A3270000965F005C33F0FFFF0E000FF4CC -:10A740008F91003800026B80020D80253C0842008A -:10A750008F8D00A402085025AE2A00048DA5003874 -:10A760008F8A003800007821000F1100AD450018D5 -:10A770008DB800343C047FFF3488FFFFAD58001CC7 -:10A7800091A6003E8D4C001C8D4900180006190052 -:10A79000000677020183C821004E58250323882B29 -:10A7A000012B382100F1F821AD59001CAD5F0018D4 -:10A7B000AD40000CAD40001091B0003E8FA40030C1 -:10A7C00024090005A550001495A500042419C00013 -:10A7D00000884024A545001691B8003EA5580020E9 -:10A7E00095AF0004A54F0022AD40002491AE003F7C -:10A7F000A54E000291A6003E91AC003D01861023BB -:10A80000244B0001A14B00018F9100388FA3003031 -:10A810003C028008344B0100AE230008A22900301E -:10A820008F8C00388F8700A4959F003294F000121F -:10A830002407FFBF033FC02432053FFF03057825EF -:10A84000A58F0032918E00322418FFDF31CD003FFA -:10A8500035A60040A18600328F910038240DFFFFFD -:10A86000240CFF80AE2000348D6A00D0AE2A003860 -:10A870009223003C3069007FA229003C8F90003871 -:10A880003C0380009219003C0327F824A21F003CDF -:10A890008F8E003891C5003C00B87824A1CF003CD1 -:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA -:10A8B000AD46004491420048004C5825A14B004849 -:10A8C0008F9000388F9900A48E09004801238824B6 -:10A8D00002283825AE070048933F003EA21F004CD7 -:10A8E0008F9800A48F8F003897050004A5E5004ECF -:10A8F0000E0003818DC500609246007C8FAC003055 -:10A9000000026940000291000040282130CB000283 -:10A9100001B21021156000AA018230213C0E80088E -:10A9200035C20080904C007C31830004106000032D -:10A930008FB900300005788000CF3021241F00043B -:10A940008F910038332D000303ED8023320800037C -:10A9500000C85021AE2A00343C188000A7C500383A -:10A960003C0680088F04010090DE00080E000FDE18 -:10A9700033C5007F0E001013000000000A00140D04 -:10A980008FA300288F9800348CC90038241F00033F -:10A99000A7000008AF0900008CC50034A300000A1E -:10A9A0008F9900A4AF0500043C080080932D003F60 -:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D -:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E -:10A9D00003D170243646FFFF01C61824AF03000CD4 -:10A9E0008F2C0014972900128F8400A0AF0C001048 -:10A9F0008F2F0014AF000018AF000020AF0F00141D -:10AA0000AF0000248F270018312F3FFF000F59801F -:10AA1000AF0700288F2500080164F821312D0001BF -:10AA2000AF0500308F31000C8F920038001F51C2EB -:10AA3000000D438001481021241E00023C068008BE -:10AA4000A702001CA7000034AF11002CA25E00007A -:10AA500034D20080964E005C8F9900383C0342004F -:10AA600031CCFFFF01833825AF2700048F8B00A472 -:10AA7000240500012402C0008D640038240700343E -:10AA8000AF2400188D690034AF29001CAF20000CE2 -:10AA9000AF200010A7200014A7200016A720002038 -:10AAA000A7200022AF200024A7300002A325000128 -:10AAB0008F8800388F9F00A4AD10000893ED000030 -:10AAC000A10D00308F8A00A48F98003891510001A9 -:10AAD000A31100318F8B0038957E003203C27024A1 -:10AAE00001CF6025A56C0032916300323064003FD5 -:10AAF000A16400329249007C3125000214A00002BA -:10AB00008F840038240700303C198008AC8700345B -:10AB1000373201008E5F00D0240AFFBF020090216F -:10AB2000AC9F0038908D003C31A8007FA088003C8D -:10AB30008F9E003893C2003C004A8824A3D1003C79 -:10AB40008F8300380010882B9066003C34CE0020A4 -:10AB5000A06E003C8F8400A48F9800388C8C00205D -:10AB6000AF0C00408C8F0024AF0F00448C8700286E -:10AB7000AF0700488C8B002CAF0B004C0E0010135D -:10AB80003C1E80000A0012700000000094C80052B1 -:10AB90003C0A08008D4A002401488821A4D10052B3 -:10ABA0000A0012198FB40010A08700018F840038AA -:10ABB000240B0001AC8B00080A0013BE3C12800875 -:10ABC000000520800A0014A200C4302127BDFFE048 -:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 -:10ABE000AFB1001435B200808E4C001835A80100BA -:10ABF000964B000695A70050910900FC000C5602E8 -:10AC0000016728233143007F312600FF240200031F -:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC -:10AC2000910600FC2412000530C200FF10520033D0 -:10AC300000000000160000098FBF001C8FB2001832 -:10AC40008FB100148FB00010240D0C003C0C80005C -:10AC500027BD002003E00008AD8D00240E0011FB8D -:10AC6000020020218FBF001C8FB200188FB100148A -:10AC70008FB00010240D0C003C0C800027BD00207C -:10AC800003E00008AD8D0024965800789651007AB4 -:10AC9000924E007D0238782631E8FFFF31C400C0B3 -:10ACA000148000092D11000116000037000000007B -:10ACB0005620FFE28FBF001C0E0010D100000000E4 -:10ACC0000A00156A8FBF001C1620FFDA0000000082 -:10ACD0000E0010D1000000001440FFD88FBF001CF0 -:10ACE0001600002200000000925F007D33E2003F6A -:10ACF000A242007D0A00156A8FBF001C950900EA78 -:10AD00008F86008000802821240400050E0007257E -:10AD10003130FFFF978300923C0480002465FFFFE1 -:10AD2000A78500928C8A01B80540FFFE0000000054 -:10AD3000AC8001808FBF001CAC9001848FB20018E2 -:10AD40008FB100148FB000103C0760133C0B100053 -:10AD5000240D0C003C0C800027BD0020AC8701882E -:10AD6000AC8B01B803E00008AD8D00240E0011FB90 -:10AD7000020020215040FFB18FBF001C925F007D78 -:10AD80000A00159733E2003F0E0011FB020020215C -:10AD90001440FFAA8FBF001C122000070000000013 -:10ADA0009259007D3330003F36020040A242007DC0 -:10ADB0000A00156A8FBF001C0E0010D100000000B1 -:10ADC0005040FF9E8FBF001C9259007D3330003FE2 -:08ADD0000A0015C6360200401E -:08ADD800000000000000001B58 -:10ADE0000000000F0000000A00000008000000063C -:10ADF0000000000500000005000000040000000441 -:10AE00000000000300000003000000030000000336 -:10AE10000000000300000002000000020000000229 -:10AE2000000000020000000200000002000000021A -:10AE3000000000020000000200000002000000020A -:10AE400000000002000000020000000200000002FA -:0CAE5000000000010000000100000001F3 -:04AE5C008008010069 -:10AE6000800800808008000000000C000000308096 -:10AE7000080011D00800127C08001294080012A8E3 -:10AE8000080012BC080011D0080011D0080012F010 -:10AE90000800132C080013400800138808001A8CBF -:10AEA00008001A8C08001AC408001AC408001AD82E -:10AEB00008001AA808001D0008001CCC08001D5836 -:10AEC00008001D5808001DE008001D108008024001 -:10AED000080027340800256C0800275C080027F4C8 -:10AEE0000800293C0800298808002AAC080029B479 -:10AEF00008002A38080025DC08002EDC08002EA4F3 -:10AF000008002588080025880800258808002B20CF -:10AF100008002B20080025880800258808002DD06F -:10AF2000080025880800258808002588080025884D -:10AF300008002E0C080025880800258808002588B0 -:10AF4000080025880800258808002588080025882D -:10AF5000080025880800258808002588080025881D -:10AF6000080025880800258808002588080029A8E9 -:10AF7000080025880800258808002E680800258814 -:10AF800008002588080025880800258808002588ED -:10AF900008002588080025880800258808002588DD -:10AFA00008002588080025880800258808002588CD -:10AFB00008002588080025880800258808002588BD -:10AFC00008002CF4080025880800258808002C6853 -:10AFD00008002BC408003CE408003CB808003C848E -:10AFE00008003C5808003C3808003BEC8008010091 -:10AFF00080080080800800008008008008004C6401 -:10B0000008004C9C08004BE408004C6408004C64A9 -:0CB01000080049B808004C6408005050CB -:04B01C000A000C8496 -:10B0200000000000000000000000000D7278703683 -:10B030002E322E31610000000602010300000000E4 -:10B0400000000001000000000000000000000000FF -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000809F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E220000000000A000000000000000000000000E4 -:10E2300010000003000000000000000D0000000DB1 -:10E240003C020801244295A03C030801246397DCAA -:10E25000AC4000000043202B1480FFFD244200044A -:10E260003C1D080037BD9FFC03A0F0213C100800B6 -:10E27000261032103C1C0801279C95A00E0012BEEF -:10E28000000000000000000D3C02800030A5FFFFF0 -:10E2900030C600FF344301803C0880008D0901B87E -:10E2A0000520FFFE00000000AC6400002404000212 -:10E2B000A4650008A066000AA064000BAC67001803 -:10E2C0003C03100003E00008AD0301B83C0560000A -:10E2D0008CA24FF80440FFFE00000000ACA44FC029 -:10E2E0003C0310003C040200ACA44FC403E000084F -:10E2F000ACA34FF89486000C00A050212488001491 -:10E3000000062B0200051080004448210109182B4B -:10E310001060001100000000910300002C6400094F -:10E320005080000991190001000360803C0D080134 -:10E3300025AD9234018D58218D67000000E0000862 -:10E340000000000091190001011940210109302B42 -:10E3500054C0FFF29103000003E000080000102108 -:10E360000A000CCC25080001910F0001240E000AC0 -:10E3700015EE00400128C8232F38000A1700003D81 -:10E38000250D00028D580000250F0006370E0100F4 -:10E39000AD4E0000910C000291AB000191A400026F -:10E3A00091A60003000C2E00000B3C0000A71025D6 -:10E3B00000041A000043C8250326C025AD580004F8 -:10E3C000910E000691ED000191E7000291E5000336 -:10E3D000000E5E00000D6400016C30250007220075 -:10E3E00000C41025004518252508000A0A000CCC99 -:10E3F000AD430008910F000125040002240800022B -:10E4000055E80001012020210A000CCC00804021A9 -:10E41000910C0001240B0003158B00160000000076 -:10E420008D580000910E000225080003370D0008EA -:10E43000A14E00100A000CCCAD4D00009119000156 -:10E44000240F0004172F000B0000000091070002AA -:10E45000910400038D43000000072A0000A410254A -:10E460003466000425080004AD42000C0A000CCC00 -:10E47000AD46000003E000082402000127BDFFE8CC -:10E48000AFBF0014AFB000100E00164E0080802108 -:10E490003C0480083485008090A600052403FFFE1C -:10E4A0000200202100C310248FBF00148FB0001081 -:10E4B000A0A200050A00165827BD001827BDFFE8D6 -:10E4C000AFB00010AFBF00140E000FD40080802149 -:10E4D0003C06800834C5008090A40000240200504F -:10E4E000308300FF106200073C09800002002021F9 -:10E4F0008FBF00148FB00010AD2001800A00108F74 -:10E5000027BD0018240801003C07800002002021DC -:10E510008FBF00148FB00010ACE801800A00108F8C -:10E5200027BD001827BDFF783C058008AFBE0080DE -:10E53000AFB7007CAFB3006CAFB10064AFBF008475 -:10E54000AFB60078AFB50074AFB40070AFB200687A -:10E55000AFB0006034A600803C0580008CB201287A -:10E5600090C400098CA701043C020001309100FF17 -:10E5700000E218240000B8210000F021106000071C -:10E58000000098213C0908008D2931F02413000176 -:10E59000252800013C010800AC2831F0ACA0008423 -:10E5A00090CC0005000C5827316A0001154000721C -:10E5B000AFA0005090CD00002406002031A400FF41 -:10E5C00010860018240E0050108E009300000000EA -:10E5D0003C1008008E1000DC260F00013C010800F2 -:10E5E000AC2F00DC0E0016C7000000000040182110 -:10E5F0008FBF00848FBE00808FB7007C8FB60078FD -:10E600008FB500748FB400708FB3006C8FB2006848 -:10E610008FB100648FB000600060102103E000083B -:10E6200027BD00880000000D3C1F8000AFA0003017 -:10E6300097E501168FE201043C04002030B9FFFF8A -:10E64000004438240007182B00033140AFA60030E7 -:10E650008FF5010437F80C003C1600400338802188 -:10E6600002B6A02434C40040128000479215000D69 -:10E6700032A800201500000234860080008030217E -:10E6800014C0009FAFA600303C0D800835A6008066 -:10E6900090CC0008318B0040516000063C06800899 -:10E6A000240E0004122E00A8240F0012122F003294 -:10E6B0003C06800834C401003C0280009447011AE3 -:10E6C0009619000E909F00088E18000830E3FFFF97 -:10E6D00003F9B00432B40004AFB6005CAFA3005835 -:10E6E0008E1600041280002EAFB8005434C3008090 -:10E6F000906800083105004014A0002500000000CB -:10E700008C70005002D090230640000500000000ED -:10E710008C71003402D1A82306A201678EE20008A2 -:10E72000126000063C1280003C1508008EB531F4E2 -:10E7300026B600013C010800AC3631F4AE4000447E -:10E74000240300018FBF00848FBE00808FB7007C40 -:10E750008FB600788FB500748FB400708FB3006CE3 -:10E760008FB200688FB100648FB00060006010212C -:10E7700003E0000827BD00880E000D2800002021BE -:10E780000A000D75004018210A000D9500C02021D7 -:10E790000E00171702C020211440FFE10000000006 -:10E7A0003C0B8008356400808C8A003402CA482300 -:10E7B0000520001D000000003C1E08008FDE310017 -:10E7C00027D700013C010800AC3731001260000679 -:10E7D000024020213C1408008E9431F42690000160 -:10E7E0003C010800AC3031F40E00164E3C1E80088F -:10E7F00037CD008091B700250240202136EE00047D -:10E800000E001658A1AE00250E000CAC02402021CF -:10E810000A000DCA240300013C17080126F796A040 -:10E820000A000D843C1F80008C86003002C66023E5 -:10E830001980000C2419000C908F004F3C14080024 -:10E840008E94310032B500FC35ED0001268E0001BA -:10E850003C010800AC2E3100A08D004FAFA0005845 -:10E860002419000CAFB900308C9800300316A02397 -:10E870001A80010B8FA300580074F82A17E0FFD309 -:10E88000000000001074002A8FA5005802D4B021A7 -:10E8900000B410233044FFFFAFA4005832A8000298 -:10E8A0001100002E32AB00103C15800836B00080FD -:10E8B0009216000832D30040526000FB8EE200083E -:10E8C0000E00164E02402021240A0018A20A000958 -:10E8D000921100052409FFFE024020210229902404 -:10E8E0000E001658A2120005240400390000282149 -:10E8F0000E0016F2240600180A000DCA24030001B7 -:10E9000092FE000C3C0A800835490080001EBB00C6 -:10E910008D27003836F10081024020213225F08118 -:10E920000E000C9B30C600FF0A000DC10000000065 -:10E930003AA7000130E300011460FFA402D4B02123 -:10E940000A000E1D00000000024020210E001734B6 -:10E95000020028210A000D75004018211160FF7087 -:10E960003C0F80083C0D800835EE00808DC40038D7 -:10E970008FA300548DA60004006660231D80FF68ED -:10E98000000000000064C02307020001AFA400548F -:10E990003C1F08008FFF31E433F9000113200015FC -:10E9A0008FAC00583C07800094E3011A10600012FD -:10E9B0003C0680080E002161024020213C03080132 -:10E9C000906396D13064000214800145000000007D -:10E9D000306C0004118000078FAC0058306600FBDB -:10E9E0003C010801A02696D132B500FCAFA000582A -:10E9F0008FAC00583C06800834D30080AFB40018B8 -:10EA0000AFB60010AFAC00143C088000950B01209D -:10EA10008E6F0030966A005C8FA3005C8FBF003061 -:10EA20003169FFFF3144FFFF8FAE005401341021E4 -:10EA3000350540000064382B0045C82103E7C02598 -:10EA4000AFB90020AFAF0028AFB80030AFAF00249F -:10EA5000AFA0002CAFAE0034926D000831B40008B6 -:10EA6000168000BB020020218EE200040040F8095D -:10EA700027A400108FAF003031F300025660000170 -:10EA800032B500FE3C048008349F008093F90008F2 -:10EA900033380040530000138FA400248C850004F9 -:10EAA0008FA7005410A700D52404001432B0000131 -:10EAB0001200000C8FA400242414000C1234011A3C -:10EAC0002A2D000D11A001022413000E240E000AAD -:10EAD000522E0001241E00088FAF002425E40001FF -:10EAE000AFA400248FAA00143C0B80083565008079 -:10EAF000008A48218CB10030ACA9003090A4004EAF -:10EB00008CA700303408FFFF0088180400E3F821C8 -:10EB1000ACBF00348FA600308FB900548FB8005CB2 -:10EB200030C200081040000B033898218CAC002044 -:10EB3000119300D330C600FF92EE000C8FA7003473 -:10EB400002402021000E6B0035B400800E000C9BAB -:10EB50003285F0803C028008345000808E0F0030F7 -:10EB600001F1302318C00097264800803C070800B8 -:10EB70008CE731E42404FF80010418243118007F5D -:10EB80003C1F80003C19800430F10001AFE300908D -:10EB900012200006031928213C030801906396D136 -:10EBA00030690008152000C6306A00F73C10800864 -:10EBB00036040080908C004F318B000115600042BC -:10EBC000000000003C0608008CC6319830CE0010D2 -:10EBD00051C0004230F9000190AF006B55E0003F9A -:10EBE00030F9000124180001A0B8006B3C1180002E -:10EBF0009622007A24470064A48700123C0D800806 -:10EC000035A5008090B40008329000401600000442 -:10EC10003C03800832AE000115C0008B00000000EC -:10EC2000346400808C86002010D3000A3463010015 -:10EC30008C67000002C7782319E000978FBF00544B -:10EC4000AC93002024130001AC760000AFB3005059 -:10EC5000AC7F000417C0004E000000008FA90050D8 -:10EC60001520000B000000003C030801906396D1C2 -:10EC7000306A00011140002E8FAB0058306400FE56 -:10EC80003C010801A02496D10A000D75000018214E -:10EC90000E000CAC024020210A000F1300000000FF -:10ECA0000A000E200000A0210040F80924040017EB -:10ECB0000A000DCA240300010040F80924040016CC -:10ECC0000A000DCA240300019094004F240DFFFE9A -:10ECD000028D2824A085004F30F900011320000682 -:10ECE0003C0480083C030801906396D1307F0010FB -:10ECF00017E00051306800EF34900080240A0001D2 -:10ED0000024020210E00164EA60A00129203002592 -:10ED100024090001AFA90050346200010240202103 -:10ED20000E001658A20200250A000EF93C0D8008BC -:10ED30001160FE83000018218FA5003030AC000464 -:10ED40001180FE2C8FBF00840A000DCB240300012C -:10ED500027A500380E000CB6AFA000385440FF4382 -:10ED60008EE200048FB40038329001005200FF3F61 -:10ED70008EE200048FA3003C8E6E0058006E682364 -:10ED800005A3FF39AE6300580A000E948EE200041A -:10ED90000E00164E024020213C038008346800809B -:10EDA000024020210E001658A11E000903C0302188 -:10EDB000240400370E0016F2000028210A000F116B -:10EDC0008FA900508FAB00185960FF8D3C0D800853 -:10EDD0000E00164E02402021920C00252405000151 -:10EDE000AFA5005035820004024020210E001658C5 -:10EDF000A20200250A000EF93C0D800812240059D9 -:10EE00002A2300151060004D240900162408000C68 -:10EE10005628FF2732B000013C0A8008914C001BA5 -:10EE20002406FFBD241E000E01865824A14B001BA2 -:10EE30000A000EA532B000013C010801A02896D1BD -:10EE40000A000EF93C0D80088CB500308EFE0008DB -:10EE50002404001826B6000103C0F809ACB600303F -:10EE60003C030801906396D13077000116E0FF81E2 -:10EE7000306A00018FB200300A000D753243000481 -:10EE80003C1080009605011A50A0FF2B34C60010DC -:10EE90000A000EC892EE000C8C6200001456FF6D42 -:10EEA000000000008C7800048FB9005403388823D8 -:10EEB0000621FF638FBF00540A000F0E0000000000 -:10EEC0003C010801A02A96D10A000F3030F9000158 -:10EED0001633FF028FAF00240A000EB0241E00106C -:10EEE0000E00164E024020213C0B80083568008041 -:10EEF00091090025240A0001AFAA0050353300040F -:10EF0000024020210E001658A11300253C050801DF -:10EF100090A596D130A200FD3C010801A02296D117 -:10EF20000A000E6D004018212411000E53D1FEEA94 -:10EF3000241E00100A000EAF241E00165629FEDC07 -:10EF400032B000013C0A8008914C001B2406FFBD32 -:10EF5000241E001001865824A14B001B0A000EA598 -:10EF600032B000010A000EA4241E00123C038000EF -:10EF70008C6201B80440FFFE24040800AC6401B8B0 -:10EF800003E000080000000030A5FFFF30C6FFFFCF -:10EF90003C0780008CE201B80440FFFE34EA0180A7 -:10EFA000AD440000ACE400203C0480089483004899 -:10EFB0003068FFFF11000016AF88000824AB001274 -:10EFC000010B482B512000133C04800034EF01005A -:10EFD00095EE00208F890000240D001A31CCFFFF30 -:10EFE00031274000A14D000B10E000362583FFFEC5 -:10EFF0000103C02B170000348F9900048F88000490 -:10F00000A5430014350700010A001003AF87000470 -:10F010003C04800024030003348201808F890000B7 -:10F020008F870004A043000B3C088000350C018052 -:10F03000A585000EA585001A8F85000C30EB800099 -:10F04000A5890010AD850028A58600081160000F75 -:10F050008F85001435190100972A00163158FFFCDE -:10F06000270F000401E870218DCD400031A6FFFF7D -:10F0700014C000072403BFFF3C02FFFF34487FFF9A -:10F0800000E83824AF8700048F8500142403BFFFF5 -:10F090003C04800000E3582434830180A46B0026E4 -:10F0A000AC69002C10A0000300054C02A465001000 -:10F0B000A46900263C071000AC8701B803E00008F3 -:10F0C000000000008F990004240AFFFE032A382460 -:10F0D0000A001003AF87000427BDFFE88FA20028B5 -:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99 -:10F0F000AF820014AF8000040E000FDBAF80000071 -:10F100008FBF001027BD001803E00008AF80001477 -:10F110003C06800034C4007034C701008C8A0000B3 -:10F1200090E500128F84000027BDFFF030A300FFA0 -:10F13000000318823082400010400037246500032D -:10F140000005C8800326C0218F0E4000246F0004F4 -:10F15000000F6880AFAE000001A660218D8B4000DB -:10F16000AFAB000494E900163128FFFC01063821FA -:10F170008CE64000AFA600088FA9000800003021EF -:10F18000000028213C07080024E701000A0010675E -:10F19000240800089059000024A500012CAC000CA4 -:10F1A0000079C0210018788001E770218DCD000022 -:10F1B0001180000600CD302603A5102114A8FFF50C -:10F1C00000051A005520FFF4905900003C0480000F -:10F1D000348700703C0508008CA531048CE30000E6 -:10F1E0002CA2002010400009006A38230005488046 -:10F1F0003C0B0800256B3108012B402124AA00019B -:10F20000AD0700003C010800AC2A310400C0102109 -:10F2100003E0000827BD0010308220001040000BE2 -:10F2200000055880016648218D24400024680004B0 -:10F2300000083880AFA4000000E618218C6540006B -:10F24000AFA000080A001057AFA500040000000D91 -:10F250000A0010588FA9000827BDFFE03C07800076 -:10F2600034E60100AFBF001CAFB20018AFB100140C -:10F27000AFB0001094C5000E8F87000030A4FFFFD0 -:10F280002483000430E2400010400010AF830028C7 -:10F290003C09002000E940241100000D30EC800002 -:10F2A0008F8A0004240BBFFF00EB38243543100085 -:10F2B000AF87000030F220001640000B3C1900041C -:10F2C000241FFFBF0A0010B7007F102430EC80001D -:10F2D000158000423C0E002030F220001240FFF862 -:10F2E0008F8300043C19000400F9C0241300FFF5CB -:10F2F000241FFFBF34620040AF82000430E20100EF -:10F300001040001130F010008F83002C10600006B8 -:10F310003C0F80003C05002000E52024148000C044 -:10F320003C0800043C0F800035EE010095CD001E26 -:10F3300095CC001C31AAFFFF000C5C00014B482556 -:10F34000AF89000C30F010001200000824110001F9 -:10F3500030F100201620008B3C18100000F890249B -:10F36000164000823C040C002411000130E801002A -:10F370001500000B3C0900018F85000430A94000F6 -:10F38000152000073C0900013C0C1F0100EC58242B -:10F390003C0A1000116A01183C1080003C09000171 -:10F3A00000E9302410C000173C0B10003C18080086 -:10F3B0008F1800243307000214E0014024030001E9 -:10F3C0008FBF001C8FB200188FB100148FB00010D7 -:10F3D0000060102103E0000827BD002000EE682433 -:10F3E00011A0FFBE30F220008F8F00043C11FFFF00 -:10F3F00036307FFF00F0382435E380000A0010A685 -:10F40000AF87000000EB102450400065AF8000245F -:10F410008F8C002C3C0D0F0000ED18241580008807 -:10F42000AF83001030E8010011000086938F0010B8 -:10F430003C0A0200106A00833C1280003650010032 -:10F44000920500139789002A3626000230AF00FF8C -:10F4500025EE0004000E19C03C0480008C9801B811 -:10F460000700FFFE34880180AD0300003C198008CE -:10F47000AC830020973100483225FFFF10A0015CCB -:10F48000AF8500082523001200A3F82B53E0015993 -:10F490008F850004348D010095AC00202402001AF1 -:10F4A00030E44000318BFFFFA102000B108001927D -:10F4B0002563FFFE00A3502B154001908F8F0004A1 -:10F4C000A50300148F88000435050001AF850004F2 -:10F4D0003C08800035190180A729000EA729001AD1 -:10F4E0008F89000C30B18000A7270010AF290028B9 -:10F4F000A72600081220000E3C04800035020100FF -:10F50000944C0016318BFFFC256400040088182100 -:10F510008C7F400033E6FFFF14C000053C048000F0 -:10F520003C0AFFFF354D7FFF00AD2824AF85000466 -:10F53000240EBFFF00AE402434850180A4A800261D -:10F54000ACA7002C3C071000AC8701B800001821C4 -:10F550008FBF001C8FB200188FB100148FB0001045 -:10F560000060102103E0000827BD00203C020BFFD3 -:10F5700000E41824345FFFFF03E3C82B5320FF7B14 -:10F58000241100013C0608008CC6002C24C5000193 -:10F590003C010800AC25002C0A0010D42411000501 -:10F5A0008F85002410A0002FAF80001090A30000D2 -:10F5B000146000792419000310A0002A30E601002D -:10F5C00010C000CC8F860010241F000210DF00C97D -:10F5D0008F8B000C3C0708008CE7003824E4FFFF09 -:10F5E00014E0000201641824000018213C0D0800FA -:10F5F00025AD0038006D1021904C00048F85002847 -:10F6000025830004000321C030A5FFFF3626000239 -:10F610000E000FDB000000000A00114D0000182151 -:10F6200000E8302414C0FF403C0F80000E00103D65 -:10F63000000000008F8700000A0010CAAF82000C93 -:10F64000938F00103C18080127189620000F90C0D7 -:10F6500002588021AF9000248F85002414A0FFD38E -:10F66000AF8F00103C0480008C86400030C5010044 -:10F6700010A000BC322300043C0C08008D8C002438 -:10F6800024120004106000C23190000D3C04800080 -:10F690008C8D40003402FFFF11A201003231FFFBCC -:10F6A0008C884000310A01005540000124110010EF -:10F6B00030EE080011C000BE2419FFFB8F9800280F -:10F6C0002F0F03EF51E000010219802430E90100FF -:10F6D00011200014320800018F87002C14E000FB79 -:10F6E0008F8C000C3C05800034AB0100917F00132F -:10F6F00033E300FF246A00042403FFFE0203802496 -:10F70000000A21C012000002023230253226FFFF1B -:10F710000E000FDB9785002A1200FF290000182138 -:10F72000320800011100000D32180004240E0001FF -:10F73000120E0002023230253226FFFF9785002A82 -:10F740000E000FDB00002021240FFFFE020F80249B -:10F750001200FF1B00001821321800045300FF188C -:10F760002403000102323025241200045612000145 -:10F770003226FFFF9785002A0E000FDB24040100CC -:10F780002419FFFB021988241220FF0D0000182104 -:10F790000A0010E9240300011079009C00003021C8 -:10F7A00090AD00012402000211A200BE30EA004028 -:10F7B00090B90001241800011338007F30E900409F -:10F7C0008CA600049785002A00C020210E000FDBC4 -:10F7D0003626000200004021010018218FBF001CC6 -:10F7E0008FB200188FB100148FB00010006010218C -:10F7F00003E0000827BD0020360F010095EE000C45 -:10F8000031CD020015A0FEE63C0900013C1880083D -:10F81000971200489789002A362600023248FFFFD7 -:10F82000AF8800083C0380008C7101B80620FFFE01 -:10F83000346A0180AD4000001100008E3C0F800052 -:10F84000253F0012011FC82B1320008B240E00033C -:10F85000346C0100958B00202402001A30E4400033 -:10F860003163FFFFA142000B108000A72463FFFE5D -:10F870000103682B15A000A52408FFFE34A5000194 -:10F88000A5430014AF8500043C0480002412BFFF90 -:10F8900000B2802434850180A4A9000EA4A9001A16 -:10F8A000A4A60008A4B00026A4A700103C071000DE -:10F8B000AC8701B80A00114D000018213C038000FC -:10F8C00034640100949F000E3C1908008F3900D861 -:10F8D0002404008033E5FFFF273100013C010800CC -:10F8E000AC3100D80E000FDB240600030A00114DD6 -:10F8F00000001821240A000210CA00598F85002830 -:10F900003C0308008C6300D0240E0001106E005EE2 -:10F910002CCF000C24D2FFFC2E5000041600002136 -:10F9200000002021241800021078001B2CD9000CA4 -:10F9300024DFFFF82FE900041520FF330000202109 -:10F9400030EB020051600004000621C054C00022C8 -:10F9500030A5FFFF000621C030A5FFFF0A00117D82 -:10F96000362600023C0908008D29002431300001B0 -:10F970005200FEF7000018219785002A3626000263 -:10F980000E000FDB000020210A00114D000018219D -:10F990000A00119C241200021320FFE624DFFFF866 -:10F9A0000000202130A5FFFF0A00117D362600024D -:10F9B0000A0011AC021980245120FF828CA6000499 -:10F9C0003C05080190A5962110A0FF7E24080001A7 -:10F9D0000A0011F0010018210E000FDB3226000191 -:10F9E0008F8600108F8500280A00124F000621C064 -:10F9F0008F8500043C18800024120003371001801A -:10FA0000A212000B0A00112E3C08800090A30001F6 -:10FA1000241100011071FF70240800012409000264 -:10FA20005069000430E60040240800010A0011F08B -:10FA30000100182150C0FFFD240800013C0C80008B -:10FA4000358B01009563001094A40002307FFFFF06 -:10FA5000509FFF62010018210A001284240800014F -:10FA60002CA803EF1100FE56240300010A001239EE -:10FA700000000000240E000335EA0180A14E000BB7 -:10FA80000A00121C3C04800011E0FFA2000621C005 -:10FA900030A5FFFF0A00117D362600020A0011A5DD -:10FAA000241100201140FFC63C1280003650010096 -:10FAB000960F001094AE000231E80FFF15C8FFC08A -:10FAC000000000000A0011E690B900013C060800A1 -:10FAD0008CC6003824C4FFFF14C00002018418241F -:10FAE000000018213C0D080025AD0038006D1021E4 -:10FAF0000A0011B6904300048F8F0004240EFFFE0D -:10FB00000A00112C01EE28242408FFFE0A00121A14 -:10FB100000A8282427BDFFC8AFB00010AFBF003435 -:10FB20003C10600CAFBE0030AFB7002CAFB6002861 -:10FB3000AFB50024AFB40020AFB3001CAFB20018C3 -:10FB4000AFB100148E0E5000240FFF7F3C068000E2 -:10FB500001CF682435AC380C240B0003AE0C5000E8 -:10FB6000ACCB00083C010800AC2000200E001819A6 -:10FB7000000000003C0A0010354980513C06601628 -:10FB8000AE09537C8CC700003C0860148D0500A0B2 -:10FB90003C03FFFF00E320243C02535300051FC237 -:10FBA0001482000634C57C000003A08002869821E0 -:10FBB0008E7200043C116000025128218CBF007C31 -:10FBC0008CA200783C1E600037C420203C05080150 -:10FBD00024A59264AF820018AF9F001C0E0016DDB2 -:10FBE0002406000A3C190001273996203C01080030 -:10FBF000AC3931DC0E0020D4AF8000148FD7080858 -:10FC00002418FFF03C15570902F8B02412D502F56C -:10FC100024040001AF80002C3C1480003697018042 -:10FC20003C1E080127DE9624369301008E900000CA -:10FC30003205000310A0FFFD3207000110E000882C -:10FC4000320600028E7100283C048000AE91002034 -:10FC50008E6500048E66000000A0382100C040219F -:10FC60008C8301B80460FFFE3C0B0010240A0800DE -:10FC700000AB4824AC8A01B8552000E0240BBFFF3C -:10FC80009675000E3C1208008E52002030AC4000E9 -:10FC900032AFFFFF264E000125ED00043C010800B5 -:10FCA000AC2E0020118000E8AF8D00283C18002009 -:10FCB00000B8B02412C000E530B980002408BFFFAE -:10FCC00000A8382434C81000AF87000030E62000B8 -:10FCD00010C000E92409FFBF3C03000400E328240E -:10FCE00010A00002010910243502004030EA010092 -:10FCF00011400010AF8200048F8B002C11600007B0 -:10FD00003C0D002000ED6024118000043C0F000435 -:10FD100000EF702411C00239000000009668001E38 -:10FD20009678001C3115FFFF0018B40002B690252C -:10FD3000AF92000C30F910001320001324150001BD -:10FD400030FF002017E0000A3C04100000E41024FB -:10FD50001040000D3C0A0C003C090BFF00EA18247F -:10FD60003525FFFF00A3302B10C0000830ED010047 -:10FD70003C0C08008D8C002C24150005258B0001FF -:10FD80003C010800AC2B002C30ED010015A0000B4D -:10FD90003C0500018F85000430AE400055C00007CF -:10FDA0003C0500013C161F0100F690243C0F10009A -:10FDB000124F01CE000000003C05000100E5302498 -:10FDC00010C000AF3C0C10003C1F08008FFF002447 -:10FDD00033E90002152000712403000100601021A6 -:10FDE000104000083C0680003C08800035180100E7 -:10FDF0008F0F00243C056020ACAF00140000000011 -:10FE00003C0680003C194000ACD9013800000000DD -:10FE10005220001332060002262B0140262C0080BF -:10FE2000240EFF80016E2024018E6824000D1940ED -:10FE3000318A007F0004A9403172007F3C16200007 -:10FE400036C20002006A482502B2382500E2882541 -:10FE50000122F825ACDF0830ACD1083032060002B0 -:10FE600010C0FF723C188000370501408CA80000CC -:10FE700024100040AF08002090AF000831E300706C -:10FE8000107000D428790041532000082405006038 -:10FE9000241100201071000E3C0A40003C09800033 -:10FEA000AD2A01780A001304000000001465FFFB6E -:10FEB0003C0A40000E001FF1000000003C0A400018 -:10FEC0003C098000AD2A01780A00130400000000FC -:10FED00090A90009241F00048CA70000312800FF0E -:10FEE000111F01B22503FFFA2C7200061240001404 -:10FEF0003C0680008CA9000494A4000A310500FF90 -:10FF000000095E022D6A00083086FFFF15400002DE -:10FF10002567000424070003240C000910AC01FA33 -:10FF200028AD000A11A001DE2410000A240E0008EA -:10FF300010AE0028000731C000C038213C06800008 -:10FF40008CD501B806A0FFFE34D20180AE47000078 -:10FF500034CB0140916E0008240300023C0A4000AB -:10FF600031C400FF00046A0001A86025A64C000807 -:10FF7000A243000B9562000A3C0810003C09800077 -:10FF8000A64200108D670004AE470024ACC801B83B -:10FF9000AD2A01780A001304000000003C0A80002A -:10FFA000354401009483000E3C0208008C4200D8C6 -:10FFB000240400803065FFFF245500013C01080047 -:10FFC000AC3500D80E000FDB240600030A001370C6 -:10FFD000000018210009320230D900FF2418000166 -:10FFE0001738FFD5000731C08F910020262200016D -:10FFF000AF8200200A0013C800C0382100CB2024A3 -:020000040001F9 -:10000000AF85000010800008AF860004240D87FF34 -:1000100000CD6024158000083C0E006000AE302446 -:1000200010C00005000000000E000D42000000009E -:100030000A001371000000000E0016050000000009 -:100040000A0013710000000030B980005320FF1F28 -:10005000AF8500003C02002000A2F82453E0FF1B03 -:10006000AF8500003C07FFFF34E47FFF00A4382485 -:100070000A00132B34C880000A001334010910242D -:1000800000EC58245160005AAF8000248F8D002C62 -:100090003C0E0F0000EE182415A00075AF83001071 -:1000A00030EF010011E00073939800103C12020041 -:1000B000107200703C06800034D9010093280013B0 -:1000C0009789002A36A60002311800FF271600047F -:1000D000001619C03C0480008C8501B804A0FFFE06 -:1000E00034880180AD0300003C158008AC830020FB -:1000F00096BF004833E5FFFF10A001BCAF850008A4 -:100100002523001200A3102B504001B98F85000455 -:10011000348D010095AC0020240B001A30E440001F -:10012000318AFFFFA10B000B108001BA2543FFFEAF -:1001300000A3702B15C001B88F9600048F8F0004A8 -:10014000A503001435E50001AF8500043C088000DC -:1001500035150180A6A9000EA6A9001A8F89000CEA -:1001600030BF8000A6A70010AEA90028A6A60008F0 -:1001700013E0000F3C0F8000350C0100958B00163A -:10018000316AFFFC25440004008818218C6240007D -:100190003046FFFF14C000072416BFFF3C0EFFFFD0 -:1001A00035CD7FFF00AD2824AF8500043C0F8000D3 -:1001B0002416BFFF00B6902435E50180A4B20026C6 -:1001C000ACA7002C3C071000ADE701B80A00137083 -:1001D000000018210E00165D000000003C0A4000DF -:1001E0003C098000AD2A01780A00130400000000D9 -:1001F0008F85002410A00027AF80001090A300007E -:10020000106000742409000310690101000030210E -:1002100090AE0001240D000211CD014230EF0040EC -:1002200090A90001241F0001113F000930E20040A5 -:100230008CA600049785002A00C020210E000FDB49 -:1002400036A60002000040210A00137001001821A8 -:100250005040FFF88CA600043C07080190E7962167 -:1002600010E0FFF4240800010A00137001001821B7 -:10027000939800103C1F080127FF96200018C8C063 -:10028000033F4021AF8800248F85002414A0FFDBAA -:10029000AF9800103C0480008C86400030C50100FF -:1002A00010A0008732AB00043C0C08008D8C0024A9 -:1002B00024160004156000033192000D241600027C -:1002C0003C0480008C8E4000340DFFFF11CD0113E3 -:1002D00032B5FFFB8C984000330F010055E0000160 -:1002E0002415001030E80800110000382409FFFB35 -:1002F0008F9F00282FF903EF53200001024990241B -:1003000030E2010010400014325F00018F87002CA2 -:1003100014E0010E8F8C000C3C0480003486010038 -:1003200090C5001330AA00FF25430004000321C03C -:100330002419FFFE025990241240000202B6302513 -:1003400032A6FFFF0E000FDB9785002A1240FEA3A6 -:1003500000001821325F000113E0000D3247000455 -:10036000240900011249000202B6302532A6FFFF1F -:100370009785002A0E000FDB000020212402FFFEDB -:10038000024290241240FE950000182132470004DA -:1003900050E0FE922403000102B63025241600042A -:1003A0005656000132A6FFFF9785002A0E000FDB8C -:1003B000240401002403FFFB0243A82412A0FE87AB -:1003C000000018210A001370240300010A0014B968 -:1003D0000249902410A0FFAF30E5010010A00017E3 -:1003E0008F8600102403000210C300148F84000CB9 -:1003F0003C0608008CC6003824CAFFFF14C0000267 -:10040000008A1024000010213C0E080025CE003880 -:10041000004E682191AC00048F850028258B0004D4 -:10042000000B21C030A5FFFF36A600020E000FDB37 -:10043000000000000A00137000001821240F0002C1 -:1004400010CF0088241600013C0308008C6300D004 -:100450001076008D8F85002824D9FFFC2F280004FA -:100460001500006300002021241F0002107F005DA2 -:100470002CC9000C24C3FFF82C6200041440FFE9CF -:100480000000202130EA020051400004000621C093 -:1004900054C0000530A5FFFF000621C030A5FFFFB6 -:1004A0000A00150436A600020E000FDB32A600017A -:1004B0008F8600108F8500280A001520000621C0B5 -:1004C0003C0A08008D4A0024315200015240FE438C -:1004D000000018219785002A36A600020E000FDBC7 -:1004E000000020210A001370000018219668000CFB -:1004F000311802005700FE313C0500013C1F800806 -:1005000097F900489789002A36A600023328FFFF92 -:10051000AF8800083C0380008C7501B806A0FFFE80 -:100520003C04800034820180AC400000110000B621 -:1005300024180003252A0012010A182B106000B2AB -:1005400000000000966F00203C0E8000240D001A71 -:1005500031ECFFFF35CA018030EB4000A14D000BAC -:10056000116000B02583FFFE0103902B164000AE02 -:100570002416FFFE34A50001A5430014AF85000436 -:100580002419BFFF00B94024A6E9000EA6E9001A0D -:10059000A6E60008A6E80026A6E700103C07100023 -:1005A000AE8701B80A001370000018213C048000D7 -:1005B0008C8201B80440FFFE349601802415001C93 -:1005C000AEC70000A2D5000B3C071000AC8701B8F5 -:1005D0003C0A40003C098000AD2A01780A0013045F -:1005E000000000005120FFA424C3FFF800002021D8 -:1005F00030A5FFFF0A00150436A600020E00103DCC -:10060000000000008F8700000A001346AF82000C34 -:1006100090A30001241500011075FF0B24080001B0 -:10062000240600021066000430E2004024080001A5 -:100630000A001370010018215040FFFD240800013A -:100640003C0C8000358B0100956A001094A40002D8 -:100650003143FFFF5083FDE1010018210A00158599 -:10066000240800018F8500282CB203EF1240FDDB27 -:10067000240300013C0308008C6300D02416000111 -:100680001476FF7624D9FFFC2CD8000C1300FF72DF -:10069000000621C030A5FFFF0A00150436A600029F -:1006A00010B00037240F000B14AFFE23000731C039 -:1006B000312600FF00065600000A4E0305220047BF -:1006C00030C6007F0006F8C03C16080126D69620EA -:1006D00003F68021A2000001A20000003C0F600090 -:1006E0008DF918202405000100C588040011302769 -:1006F0000326C024000731C000C03821ADF81820FF -:100700000A0013C8A60000028F850020000731C030 -:1007100024A2FFFF0A0013F6AF8200200A0014B2E1 -:100720002415002011E0FECC3C1980003728010080 -:100730009518001094B6000233120FFF16D2FEC6B1 -:10074000000000000A00148290A900013C0B080080 -:100750008D6B0038256DFFFF15600002018D1024A0 -:10076000000010213C080800250800380048C0217E -:10077000930F000425EE00040A0014C5000E21C0EA -:1007800000065202241F00FF115FFDEB000731C07D -:10079000000A20C03C0E080125CE9620008EA8211C -:1007A000009E602100095C02240D00013C076000EE -:1007B000A2AD0000AD860000A2AB00018CF21820B3 -:1007C00024030001014310040242B025ACF61820B6 -:1007D00000C038210A0013C8A6A900020A0015AA01 -:1007E000AF8000200A0012FFAF84002C8F85000428 -:1007F0003C1980002408000337380180A308000B4F -:100800000A00144D3C088000A2F8000B0A00155A9B -:100810002419BFFF8F9600042412FFFE0A00144B18 -:1008200002D228242416FFFE0A00155800B62824F8 -:100830003C038000346401008C85000030A2003E3F -:100840001440000800000000AC6000488C870000E5 -:1008500030E607C010C0000500000000AC60004C8E -:10086000AC60005003E0000824020001AC600054BA -:10087000AC6000408C880000310438001080FFF923 -:10088000000000002402000103E00008AC60004406 -:100890003C0380008C6201B80440FFFE3467018095 -:1008A000ACE4000024080001ACE00004A4E500086A -:1008B00024050002A0E8000A34640140A0E5000B12 -:1008C0009483000A14C00008A4E30010ACE00024E4 -:1008D0003C07800034E901803C041000AD20002872 -:1008E00003E00008ACE401B88C8600043C0410006E -:1008F000ACE600243C07800034E90180AD200028EC -:1009000003E00008ACE401B83C0680008CC201B8EA -:100910000440FFFE34C7018024090002ACE400005B -:10092000ACE40004A4E50008A0E9000A34C50140D5 -:10093000A0E9000B94A8000A3C041000A4E80010F1 -:10094000ACE000248CA30004ACE3002803E0000822 -:10095000ACC401B83C039000346200010082202541 -:100960003C038000AC6400208C65002004A0FFFEE6 -:100970000000000003E00008000000003C028000CE -:10098000344300010083202503E00008AC4400202C -:1009900027BDFFE03C098000AFBF0018AFB10014D5 -:1009A000AFB00010352801408D10000091040009FF -:1009B0009107000891050008308400FF30E600FF31 -:1009C00000061A002C820081008330251040002A86 -:1009D00030A50080000460803C0D080125AD928C9C -:1009E000018D58218D6A00000140000800000000C0 -:1009F0003C038000346201409445000A14A0001EAC -:100A00008F91FCBC9227000530E6000414C0001A48 -:100A1000000000000E00164E02002021922A000560 -:100A200002002021354900040E001658A2290005B5 -:100A30009228000531040004148000020000000028 -:100A40000000000D922D0000240B002031AC00FFAF -:100A5000158B00093C0580008CAE01B805C0FFFE77 -:100A600034B10180AE3000003C0F100024100005AE -:100A7000A230000BACAF01B80000000D8FBF001812 -:100A80008FB100148FB0001003E0000827BD0020D4 -:100A90000200202100C028218FBF00188FB1001450 -:100AA0008FB00010240600010A00161D27BD00208B -:100AB0000000000D0200202100C028218FBF001877 -:100AC0008FB100148FB00010000030210A00161DF5 -:100AD00027BD002014A0FFE8000000000200202134 -:100AE0008FBF00188FB100148FB0001000C02821F4 -:100AF0000A00163B27BD00203C0780008CEE01B8A1 -:100B000005C0FFFE34F00180241F0002A21F000B6D -:100B100034F80140A60600089719000A3C0F10009F -:100B2000A61900108F110004A6110012ACEF01B835 -:100B30000A0016998FBF001827BDFFE8AFBF00104D -:100B40000E000FD4000000003C0280008FBF001098 -:100B500000002021AC4001800A00108F27BD001842 -:100B60003084FFFF30A5FFFF108000070000182130 -:100B7000308200011040000200042042006518216C -:100B80001480FFFB0005284003E0000800601021EE -:100B900010C00007000000008CA2000024C6FFFF68 -:100BA00024A50004AC82000014C0FFFB24840004D0 -:100BB00003E000080000000010A0000824A3FFFFCD -:100BC000AC86000000000000000000002402FFFFCF -:100BD0002463FFFF1462FFFA2484000403E000088A -:100BE000000000003C03800027BDFFF83462018054 -:100BF000AFA20000308C00FF30AD00FF30CE00FF10 -:100C00003C0B80008D6401B80480FFFE00000000F2 -:100C10008FA900008D6801288FAA00008FA700000F -:100C20008FA400002405000124020002A085000A10 -:100C30008FA30000359940003C051000A062000B16 -:100C40008FB800008FAC00008FA600008FAF0000AF -:100C500027BD0008AD280000AD400004AD80002491 -:100C6000ACC00028A4F90008A70D0010A5EE0012E2 -:100C700003E00008AD6501B83C06800827BDFFE829 -:100C800034C50080AFBF001090A7000924020012F5 -:100C900030E300FF1062000B008030218CA8005070 -:100CA00000882023048000088FBF00108CAA003425 -:100CB000240400390000282100CA4823052000052B -:100CC000240600128FBF00102402000103E0000878 -:100CD00027BD00180E0016F2000000008FBF0010A4 -:100CE0002402000103E0000827BD001827BDFFC84B -:100CF000AFB20030AFB00028AFBF0034AFB1002CAE -:100D000000A0802190A5000D30A6001010C000109A -:100D1000008090213C0280088C4400048E0300086F -:100D20001064000C30A7000530A6000510C0009329 -:100D3000240400018FBF00348FB200308FB1002C2B -:100D40008FB000280080102103E0000827BD003884 -:100D500030A7000510E0000F30AB001210C00006F5 -:100D6000240400013C0980088E0800088D25000439 -:100D70005105009C240400388FBF00348FB200302E -:100D80008FB1002C8FB000280080102103E00008F4 -:100D900027BD0038240A0012156AFFE6240400016A -:100DA0000200202127A500100E000CB6AFA00010F5 -:100DB0001440007C3C19800837240080909800087B -:100DC000331100081220000A8FA7001030FF010025 -:100DD00013E000A48FA300148C8600580066102333 -:100DE000044000043C0A8008AC8300588FA7001020 -:100DF0003C0A800835480080910900083124000829 -:100E00001480000224080003000040213C1F8008D9 -:100E100093F1001193F9001237E600808CCC005456 -:100E2000333800FF03087821322D00FF000F708057 -:100E300001AE282100AC582B1160006F00000000AB -:100E400094CA005C8CC900543144FFFF0125102373 -:100E50000082182B14600068000000008CCB005446 -:100E60000165182330EC00041180006C000830800C -:100E70008FA8001C0068102B1040006230ED0004A9 -:100E8000006610232C46008010C00002004088211C -:100E9000241100800E00164E024020213C0D8008D7 -:100EA00035A6008024070001ACC7000C90C80008DC -:100EB0000011484035A70100310C007FA0CC00088C -:100EC0008E05000424AB0001ACCB0030A4D1005C43 -:100ED0008CCA003C9602000E01422021ACC40020C6 -:100EE0008CC3003C0069F821ACDF001C8E190004A3 -:100EF000ACF900008E180008ACF800048FB10010A7 -:100F0000322F000855E0004793A60020A0C0004EF5 -:100F100090D8004E2411FFDFA0F8000890CF000801 -:100F200001F17024A0CE00088E0500083C0B80085B -:100F300035690080AD2500388D6A00148D2200309F -:100F40002419005001422021AD24003491230000D7 -:100F5000307F00FF13F90036264F01000E001658AF -:100F60000240202124040038000028210E0016F23F -:100F70002406000A0A001757240400010E000D2859 -:100F8000000020218FBF00348FB200308FB1002CC1 -:100F90008FB00028004020210080102103E00008CD -:100FA00027BD00388E0E00083C0F800835F0008009 -:100FB000AE0E005402402021AE0000300E00164E4E -:100FC00000000000920D00250240202135AC0020D9 -:100FD0000E001658A20C00250E000CAC0240202179 -:100FE000240400382405008D0E0016F22406001299 -:100FF0000A0017572404000194C5005C0A001792E8 -:1010000030A3FFFF2407021811A0FF9E00E6102363 -:101010008FAE001C0A00179A01C610230A0017970A -:101020002C620218A0E600080A0017C48E0500080A -:101030002406FF8001E6C0243C118000AE38002861 -:101040008E0D000831E7007F3C0E800C00EE602121 -:10105000AD8D00E08E080008AF8C00380A0017D074 -:10106000AD8800E4AC800058908500082403FFF7A9 -:1010700000A33824A08700080A0017758FA7001066 -:101080003C05080024A560A83C04080024846FF4F3 -:101090003C020800244260B0240300063C01080121 -:1010A000AC2596A03C010801AC2496A43C010801A3 -:1010B000AC2296A83C010801A02396AC03E00008EE -:1010C0000000000003E00008240200013C02800050 -:1010D000308800FF344701803C0680008CC301B893 -:1010E0000460FFFE000000008CC501282418FF806A -:1010F0003C0D800A24AF010001F8702431EC007F20 -:10110000ACCE0024018D2021ACE50000948B00EAD8 -:101110003509600024080002316AFFFFACEA0004D0 -:1011200024020001A4E90008A0E8000BACE00024C0 -:101130003C071000ACC701B8AF84003803E00008DA -:10114000AF85006C938800488F8900608F820038DB -:1011500030C600FF0109382330E900FF01221821C1 -:1011600030A500FF2468008810C000020124382147 -:101170000080382130E400031480000330AA00030B -:101180001140000D312B000310A0000900001021B8 -:1011900090ED0000244E000131C200FF0045602B9D -:1011A000A10D000024E700011580FFF925080001CA -:1011B00003E00008000000001560FFF300000000DD -:1011C00010A0FFFB000010218CF80000245900043F -:1011D000332200FF0045782BAD18000024E70004FF -:1011E00015E0FFF92508000403E0000800000000F6 -:1011F00093850048938800588F8700600004320070 -:101200003103007F00E5102B30C47F001040000F39 -:10121000006428258F8400383C0980008C8A00EC0B -:10122000AD2A00A43C03800000A35825AC6B00A0AD -:101230008C6C00A00580FFFE000000008C6D00ACEF -:10124000AC8D00EC03E000088C6200A80A00188254 -:101250008F840038938800593C0280000080502120 -:10126000310300FEA383005930ABFFFF30CC00FFF9 -:1012700030E7FFFF344801803C0980008D2401B82D -:101280000480FFFE8F8D006C24180016AD0D000049 -:101290008D2201248F8D0038AD0200048D5900206D -:1012A000A5070008240201C4A119000AA118000B17 -:1012B000952F01208D4E00088D4700049783005C18 -:1012C0008D59002401CF302100C7282100A32023FD -:1012D0002418FFFFA504000CA50B000EA5020010AA -:1012E000A50C0012AD190018AD18002495AF00E848 -:1012F0003C0B10002407FFF731EEFFFFAD0E002876 -:101300008DAC0084AD0C002CAD2B01B88D460020B7 -:1013100000C7282403E00008AD4500208F8800386E -:101320000080582130E7FFFF910900D63C02800081 -:1013300030A5FFFF312400FF00041A00006750258C -:1013400030C600FF344701803C0980008D2C01B875 -:101350000580FFFE8F82006C240F0017ACE20000B6 -:101360008D390124ACF900048D780020A4EA00082E -:10137000241901C4A0F8000AA0EF000B9523012056 -:101380008D6E00088D6D00049784005C01C35021B0 -:10139000014D602101841023A4E2000CA4E5000E9D -:1013A000A4F90010A4E60012ACE000148D7800242B -:1013B000240DFFFFACF800188D0F007CACEF001C73 -:1013C0008D0E00783C0F1000ACEE0020ACED002438 -:1013D000950A00BE240DFFF73146FFFFACE600285A -:1013E000950C00809504008231837FFF0003CA00C2 -:1013F0003082FFFF0322C021ACF8002CAD2F01B8D2 -:10140000950E00828D6A002000AE3021014D282407 -:10141000A506008203E00008AD6500203C028000C4 -:10142000344501803C0480008C8301B80460FFFED9 -:101430008F8A0044240600199549001C3128FFFFBB -:10144000000839C0ACA70000A0A6000B3C051000A6 -:1014500003E00008AC8501B88F87004C0080402174 -:1014600030C400FF3C0680008CC201B80440FFFE7F -:101470008F89006C9383006834996000ACA90000E8 -:10148000A0A300058CE20010240F00022403FFF744 -:10149000A4A20006A4B900088D180020A0B8000A74 -:1014A000A0AF000B8CEE0000ACAE00108CED000481 -:1014B000ACAD00148CEC001CACAC00248CEB002018 -:1014C000ACAB00288CEA002C3C071000ACAA002C26 -:1014D0008D090024ACA90018ACC701B88D05002007 -:1014E00000A3202403E00008AD0400208F8600380C -:1014F00027BDFFE0AFB10014AFBF0018AFB00010C0 -:1015000090C300D430A500FF3062002010400008D6 -:10151000008088218CCB00D02409FFDF256A0001E0 -:10152000ACCA00D090C800D401093824A0C700D4A8 -:1015300014A000403C0C80008F840038908700D4B9 -:101540002418FFBF2406FFEF30E3007FA08300D400 -:10155000979F005C8F8200608F8D003803E2C82364 -:10156000A799005CA5A000BC91AF00D401F870243D -:10157000A1AE00D48F8C0038A18000D78F8A0038AC -:10158000A5400082AD4000EC914500D400A658244F -:10159000A14B00D48F9000348F8400609786005C4C -:1015A0000204282110C0000FAF850034A38000582A -:1015B0003C0780008E2C000894ED01208E2B000447 -:1015C000018D5021014B8021020620233086FFFF30 -:1015D00030C8000F3909000131310001162000091F -:1015E000A3880058938600488FBF00188FB100145D -:1015F0008FB0001027BD0020AF85006403E0000815 -:10160000AF86006000C870238FBF00189386004823 -:101610008FB100148FB0001034EF0C00010F28219F -:1016200027BD0020ACEE0084AF85006403E0000815 -:10163000AF86006035900180020028210E00190F4E -:10164000240600828F840038908600D430C5004084 -:1016500050A0FFBAA38000688F85004C3C06800034 -:101660008CCD01B805A0FFFE8F89006C2408608234 -:1016700024070002AE090000A6080008A207000B1C -:101680008CA300083C0E1000AE0300108CA2000CCE -:10169000AE0200148CBF0014AE1F00188CB90018E5 -:1016A000AE1900248CB80024AE1800288CAF002896 -:1016B000AE0F002CACCE01B80A001948A380006818 -:1016C0008F8A003827BDFFE0AFB10014AFB0001023 -:1016D0008F880060AFBF00189389003C954200BC22 -:1016E00030D100FF0109182B0080802130AC00FFB1 -:1016F0003047FFFF0000582114600003310600FF4F -:1017000001203021010958239783005C0068202BB9 -:101710001480002700000000106800562419000102 -:101720001199006334E708803165FFFF0E0018C08F -:10173000020020218F83006C3C07800034E601808A -:101740003C0580008CAB01B80560FFFE240A001840 -:101750008F840038ACC30000A0CA000B948900BE7F -:101760003C081000A4C90010ACC00030ACA801B8FF -:101770009482008024430001A4830080949F008011 -:101780003C0608008CC6318833EC7FFF1186005E72 -:101790000000000002002021022028218FBF001835 -:1017A0008FB100148FB000100A00193427BD00203B -:1017B000914400D42403FF8000838825A15100D4E4 -:1017C0009784005C3088FFFF51000023938C003C1D -:1017D0008F8500382402EFFF008B782394AE00BC85 -:1017E0000168502B31E900FF01C26824A4AD00BCA0 -:1017F00051400039010058213C1F800037E60100AC -:101800008CD800043C190001031940245500000144 -:1018100034E740008E0A00202403FFFB241100015E -:1018200001432024AE0400201191002D34E78000F4 -:1018300002002021012030210E0018C03165FFFF79 -:101840009787005C8F890060A780005C0127802358 -:10185000AF900060938C003C8F8B00388FBF0018D6 -:101860008FB100148FB0001027BD002003E00008E6 -:10187000A16C00D73C0D800035AA01008D48000402 -:101880003C0900010109282454A0000134E740006C -:101890008E0F00202418FFFB34E7800001F870242D -:1018A00024190001AE0E00201599FF9F34E708802F -:1018B000020020210E00188E3165FFFF020020215A -:1018C000022028218FBF00188FB100148FB00010A4 -:1018D0000A00193427BD00200A0019F7000048212A -:1018E00002002021012030210E00188E3165FFFFFB -:1018F0009787005C8F890060A780005C01278023A8 -:101900000A001A0EAF900060948C0080241F8000A3 -:10191000019F3024A4860080908B0080908F0080EF -:10192000316700FF0007C9C20019C027001871C045 -:1019300031ED007F01AE2825A08500800A0019DF67 -:1019400002002021938500682403000127BDFFE8E1 -:1019500000A330042CA20020AFB00010AFBF0014D1 -:1019600000C01821104000132410FFFE3C0708009F -:101970008CE7319000E610243C088000350501809A -:1019800014400005240600848F890038240A0004CE -:101990002410FFFFA12A00FC0E00190F0000000018 -:1019A000020010218FBF00148FB0001003E0000868 -:1019B00027BD00183C0608008CC631940A001A574F -:1019C00000C310248F87004427BDFFE0AFB200188A -:1019D000AFB10014AFB00010AFBF001C30D000FF9B -:1019E00090E6000D00A088210080902130C5007F86 -:1019F000A0E5000D8F8500388E2300188CA200D042 -:101A00001062002E240A000E0E001A4AA38A0068F3 -:101A10002409FFFF104900222404FFFF5200002088 -:101A2000000020218E2600003C0C001000CC582421 -:101A3000156000393C0E000800CE682455A0003F18 -:101A4000024020213C18000200D880241200001F10 -:101A50003C0A00048F8700448CE200148CE30010E1 -:101A60008CE500140043F82303E5C82B1320000580 -:101A7000024020218E24002C8CF1001010910031A6 -:101A80000240202124020012A38200680E001A4A9C -:101A90002412FFFF105200022404FFFF0000202147 -:101AA0008FBF001C8FB200188FB100148FB00010D0 -:101AB0000080102103E0000827BD002090A800D47A -:101AC000350400200A001A80A0A400D400CA4824CB -:101AD0001520000B8F8B00448F8D00448DAC0010BF -:101AE0001580000B024020218E2E002C51C0FFECEF -:101AF00000002021024020210A001A9B2402001726 -:101B00008D66001050C0FFE6000020210240202119 -:101B10000A001A9B24020011024020212402001511 -:101B20000E001A4AA3820068240FFFFF104FFFDC4B -:101B30002404FFFF0A001A8A8E2600000A001AC138 -:101B4000240200143C08000400C8382450E0FFD4EC -:101B500000002021024020210A001A9B24020013C9 -:101B60008F85003827BDFFD8AFB3001CAFB2001877 -:101B7000AFB10014AFB00010AFBF002090A700D4E9 -:101B80008F90004C2412FFFF34E2004092060000C8 -:101B9000A0A200D48E0300100080982110720006CD -:101BA00030D1003F2408000D0E001A4AA3880068B7 -:101BB000105200252404FFFF8F8A00388E09001878 -:101BC0008D4400D01124000702602021240C000E57 -:101BD0000E001A4AA38C0068240BFFFF104B001A5A -:101BE0002404FFFF24040020122400048F8D0038F9 -:101BF00091AF00D435EE0020A1AE00D48F85005403 -:101C000010A00019000000001224004A8F9800382C -:101C10008F92FCBC971000809651000A5230004809 -:101C20008F9300403C1F08008FFF318C03E5C82BC9 -:101C30001720001E02602021000028210E0019A993 -:101C400024060001000020218FBF00208FB3001C5C -:101C50008FB200188FB100148FB0001000801021D7 -:101C600003E0000827BD00285224002A8E05001436 -:101C70008F840038948A008025490001A48900805F -:101C8000948800803C0208008C42318831077FFF35 -:101C900010E2000E00000000026020210E00193446 -:101CA000240500010A001B0B000020212402002D46 -:101CB0000E001A4AA38200682403FFFF1443FFE1C9 -:101CC0002404FFFF0A001B0C8FBF002094990080A2 -:101CD000241F800024050001033FC024A498008035 -:101CE00090920080908E0080325100FF001181C2DE -:101CF00000107827000F69C031CC007F018D582576 -:101D0000A08B00800E001934026020210A001B0BFA -:101D1000000020212406FFFF54A6FFD68F84003840 -:101D2000026020210E001934240500010A001B0B5B -:101D300000002021026020210A001B252402000A45 -:101D40002404FFFD0A001B0BAF9300608F8800384E -:101D500027BDFFE8AFB00010AFBF0014910A00D458 -:101D60008F87004C00808021354900408CE60010B0 -:101D7000A10900D43C0208008C4231B030C53FFFBD -:101D800000A2182B106000078F850050240DFF80E3 -:101D900090AE000D01AE6024318B00FF156000088D -:101DA0000006C382020020212403000D8FBF00140F -:101DB0008FB0001027BD00180A001A4AA3830068DC -:101DC00033060003240F000254CFFFF70200202146 -:101DD00094A2001C8F85003824190023A4A200E8D7 -:101DE0008CE8000000081E02307F003F13F9003528 -:101DF0003C0A00838CE800188CA600D0110600086D -:101E0000000000002405000E0E001A4AA385006899 -:101E10002407FFFF104700182404FFFF8F850038B8 -:101E200090A900D435240020A0A400D48F8C0044B5 -:101E3000918E000D31CD007FA18D000D8F83005458 -:101E40001060001C020020218F8400508C9800102C -:101E50000303782B11E0000D241900180200202143 -:101E6000A39900680E001A4A2410FFFF10500002C8 -:101E70002404FFFF000020218FBF00148FB000104A -:101E80000080102103E0000827BD00188C86001098 -:101E90008F9F00440200202100C31023AFE20010F6 -:101EA000240500010E0019A9240600010A001B9751 -:101EB000000020210E001934240500010A001B97A0 -:101EC00000002021010A5824156AFFD98F8C004494 -:101ED000A0A600FC0A001B84A386005A30A500FFC0 -:101EE0002406000124A9000100C9102B1040000C99 -:101EF00000004021240A000100A61823308B0001B5 -:101F000024C60001006A3804000420421160000267 -:101F100000C9182B010740251460FFF800A61823FC -:101F200003E000080100102127BDFFD8AFB0001862 -:101F30008F90004CAFB1001CAFBF00202403FFFF07 -:101F40002411002FAFA30010920600002405000802 -:101F500026100001006620260E001BB0308400FF12 -:101F600000021E003C021EDC34466F410A001BD8F2 -:101F70000000102110A00009008018212445000154 -:101F800030A2FFFF2C4500080461FFFA0003204047 -:101F90000086202614A0FFF9008018210E001BB037 -:101FA000240500208FA300102629FFFF313100FFF8 -:101FB00000034202240700FF1627FFE20102182651 -:101FC00000035027AFAA0014AFAA00100000302170 -:101FD00027A8001027A7001400E6782391ED00033E -:101FE00024CE000100C8602131C600FF2CCB0004C4 -:101FF0001560FFF9A18D00008FA200108FBF002097 -:102000008FB1001C8FB0001803E0000827BD002826 -:1020100027BDFFD0AFB3001CAFB00010AFBF00288A -:10202000AFB50024AFB40020AFB20018AFB10014B8 -:102030003C0C80008D880128240FFF803C06800A1C -:1020400025100100250B0080020F68243205007F57 -:10205000016F7024AD8E009000A62821AD8D002464 -:1020600090A600FC3169007F3C0A8004012A1821F7 -:10207000A386005A9067007C00809821AF830030CF -:1020800030E20002AF88006CAF85003800A0182154 -:10209000144000022404003424040030A3840048C7 -:1020A0008C7200DC30D100FF24040004AF92006089 -:1020B00012240004A38000688E7400041680001EA1 -:1020C0003C0880009386005930C7000150E0000FA3 -:1020D0008F8600608CA400848CA800842413FF8069 -:1020E00000936024000C49403110007F01307825B6 -:1020F0003C19200001F9682530DF00FE3C03800018 -:10210000AC6D0830A39F00598F8600608FBF0028F8 -:102110008FB500248FB400208FB3001C8FB200183D -:102120008FB100148FB000102402000127BD0030D1 -:1021300003E00008ACA600DC8E7F000895020120B9 -:102140008E67001003E2C8213326FFFF30D8000F4E -:1021500033150001AF87003416A00058A39800582B -:1021600035090C000309382100D81823AD03008479 -:10217000AF8700648E6A00043148FFFF1100007EC3 -:10218000A78A005C90AC00D42407FF8000EC3024C8 -:1021900030CB00FF1560004B9786005C938E005A91 -:1021A000240D000230D5FFFF11CD02A20000A021B6 -:1021B0008F85006002A5802B160000BC9388004824 -:1021C0003C11800096240120310400FF1485008812 -:1021D0008F8400648F9800343312000356400085CA -:1021E00030A500FF8F900064310C00FF24060034FE -:1021F00011860095AF90004C9204000414800119E0 -:102200008F8E0038A380003C8E0D00048DC800D84E -:102210003C0600FF34CCFFFF01AC30240106182B34 -:1022200014600121AF8600548F8700609798005C8E -:10223000AF8700400307402310C000C7A788005C99 -:102240008F91003030C3000300035823922A007C92 -:102250003171000302261021000A20823092000111 -:102260000012488000492821311FFFFF03E5C82BD9 -:10227000132001208F8800388F8500348F880064F8 -:102280001105025A3C0E3F018E0600003C0C250051 -:1022900000CE682411AC01638F84004C30E500FF50 -:1022A0000E00184A000030218F8800388F870060A8 -:1022B0008F8500340A001DB78F8600540A001C5613 -:1022C000AF87006490AC00D400EC2024309000FF75 -:1022D000120000169386005990B5008890B400D77C -:1022E00024A8008832A2003F2446FFE02CD1002021 -:1022F000A394003C1220000CAF88004C240E000177 -:1023000000CE2004308A00191540012B3C068000C5 -:1023100034D80002009858241560022E3092002014 -:1023200016400234000000009386005930CE0001B0 -:1023300011C0000F9788005C8CA900848CAF0084CA -:102340002410FF800130C8240019194031ED007FAE -:10235000006D38253C1F200000FF902530CB00FE8B -:102360003C188000AF120830A38B00599788005C9E -:102370001500FF84000000008E630020306C000414 -:102380001180FF51938600592404FFFB0064302420 -:102390003C038000AE660020346601808C7301B877 -:1023A0000660FFFE8F8E006C346A01003C15000150 -:1023B000ACCE00008C62012424076085ACC200040E -:1023C0008D54000402958824522000012407608364 -:1023D000241200023C1810003C0B8000A4C7000827 -:1023E000A0D2000BAD7801B80A001C2B93860059CF -:1023F00030A500FF0E00184A240600018F88006CEB -:102400003C05800034A90900250201889388004812 -:10241000304A0007304B00783C0340802407FF809F -:102420000163C825014980210047F824310C00FFD1 -:1024300024060034ACBF0800AF90004CACB90810C3 -:102440005586FF6E920400048F8400388E11003090 -:10245000908E00D431CD001015A000108F83006045 -:102460002C6F000515E000E400000000909800D4F7 -:102470002465FFFC331200101640000830A400FF52 -:102480008F9F00648F99003413F90004388700018E -:1024900030E20001144001C8000000000E001BC320 -:1024A000000000000A001DF8000000008F84006496 -:1024B00030C500FF0E00184A24060001938E004824 -:1024C000240A003411CA00A08F8500388F8600606E -:1024D0009783005C3062FFFF00C28823AF910060E9 -:1024E000A780005C1280FF90028018212414FFFD59 -:1024F0005474FFA28E6300208E6900042403FFBF82 -:10250000240BFFEF0135C823AE79000490AF00D44F -:1025100031ED007FA0AD00D48E6600208F9800388A -:10252000A780005C34DF0002AE7F0020A70000BC63 -:10253000931200D402434024A30800D48F9500389E -:10254000AEA000EC92AE00D401CB5024A2AA00D4DD -:102550000A001CD78F8500388F910034AF8000604F -:1025600002275821AF8B0034000020212403FFFFF5 -:10257000108301B48F8500388E0C00103C0D0800CC -:102580008DAD31B09208000031843FFF008D802B6B -:1025900012000023310D003F3C1908008F3931A88B -:1025A0008F9F006C000479802408FF80033F202166 -:1025B000008FC821938500590328F8243C06008029 -:1025C0003C0F800034D80001001F91403331007F60 -:1025D0008F8600380251502535EE0940332B0078A4 -:1025E000333000073C0310003C02800C017890253A -:1025F000020E48210143C0250222382134AE0001D9 -:10260000ADFF0804AF890050ADF20814AF87004455 -:10261000ADFF0028ACD90084ADF80830A38E005976 -:102620009383005A240700035067002825A3FFE086 -:10263000240C0001146CFFAB8F850038241100239B -:1026400011B10084000000002402000B0260202170 -:102650000E001A4AA38200680040A0210A001D3221 -:102660008F85003802602021240B000C0E001A4ACE -:10267000A38B0068240AFFFF104AFFBC2404FFFF5D -:102680008F8E0038A380003C8E0D00048DC800D8CA -:102690003C0600FF34CCFFFF01AC30240106182BB0 -:1026A0001060FEE1AF860054026020212412001960 -:1026B0000E001A4AA3920068240FFFFF104FFFABD1 -:1026C0002404FFFF0A001C838F8600542C74002012 -:1026D0001280FFDE2402000B000328803C11080159 -:1026E0002631949000B148218D2D000001A00008F2 -:1026F000000000008F85003400A710219385003C66 -:10270000AF82003402251821A383003C951F00BC32 -:102710000226282137F91000A51900BC5240FF926B -:10272000AF850060246A0004A38A003C950900BCC0 -:1027300024A40004AF84006035322000A51200BC40 -:102740000A001D54000020218F8600602CCB00055C -:102750001560FF609783005C3072FFFF00D240235A -:102760002D18000513000003306400FF24DFFFFC78 -:1027700033E400FF8F8500648F86003410A60004C8 -:10278000388F000131ED000115A001380000000074 -:102790008F840038908C00D435870010A08700D437 -:1027A0008F8500388F8600609783005CACA000ECBA -:1027B0000A001D2F3062FFFF8CAA00848CB50084B4 -:1027C0003C041000014710240002894032B4007F0D -:1027D0000234302500C460253C0880002405000137 -:1027E00002602021240600010E0019A9AD0C08305A -:1027F0000A001CC38F8500388C8200EC1222FE7EFA -:102800000260202124090005A38900680E001A4AED -:102810002411FFFF1451FE782404FFFF0A001D5508 -:102820002403FFFF8F8F004C8F8800388DF8000045 -:10283000AD1800888DE70010AD0700988F87006005 -:102840000A001DB78F8600542407FFFF118700057B -:10285000000000000E001B4C026020210A001D90A9 -:102860000040A0210E001AD1026020210A001D9014 -:102870000040A0218F90004C3C0908008D2931B008 -:102880008E11001032323FFF0249682B11A0000C5C -:10289000240AFF808F85005090AE000D014E102459 -:1028A000304C00FF11800007026020210011C3821C -:1028B00033030003240B0001106B0105000000002E -:1028C000026020212418000D0E001A4AA398006807 -:1028D000004020218F8500380A001D320080A02191 -:1028E0008F90004C3C0A08008D4A31B08F85005013 -:1028F0008E0400100000A0218CB1001430823FFF34 -:10290000004A602B8CB200205180FFEE0260202133 -:1029100090B8000D240BFF800178702431C300FFB4 -:102920005060FFE80260202100044382310600036A -:1029300014C0FFE40260202194BF001C8F9900386E -:102940008E060028A73F00E88CAF0010022F20233E -:1029500014C40139026020218F83005400C3682110 -:10296000022D382B14E00135240200188F8A004410 -:102970008F820030024390218D4B00100163702341 -:10298000AD4E0010AD5200208C4C00740192282BEB -:1029900014A00156026020218F8400508E0800246C -:1029A0008C86002411060007026020212419001CD7 -:1029B0000E001A4AA3990068240FFFFF104FFFC5AD -:1029C0002404FFFF8F8400448C87002424FF00012F -:1029D000AC9F0024125101338F8D00308DB10074F3 -:1029E000123201303C0B00808E0E000001CB5024CF -:1029F00015400075000000008E0300142411FFFF35 -:102A000010710006026020212418001B0E001A4AD3 -:102A1000A39800681051FFAF2404FFFF8E0300004D -:102A20003C0800010068302410C000133C04008002 -:102A30000064A024168000090200282102602021E1 -:102A40002419001A0E001A4AA3990068240FFFFFE8 -:102A5000104FFFA02404FFFF020028210260202164 -:102A60000E001A6A240600012410FFFF1050FF997F -:102A70002404FFFF241400018F9F004402602021E2 -:102A80000280302197F1003424050001262700013F -:102A9000A7E700340E0019A9000000000000202163 -:102AA0008F8500380A001D320080A0218F90004CD5 -:102AB0003C1408008E9431B08E07001030E83FFFC0 -:102AC0000114302B10C000618F860050241FFF803E -:102AD00090C5000D03E52024309200FF5240005CB9 -:102AE000026020218F8D005411A0000700078B8207 -:102AF0008F8500388F89FCBC94AF00809539000A1F -:102B0000132F00F68F870040322C000315800063DE -:102B10000000000092020002104000D700000000F8 -:102B20008E0A0024154000D8026020219204000380 -:102B300024060002308800FF15060005308500FFDE -:102B40008F940054528000F202602021308500FFF3 -:102B500038AD00102DA400012CBF000103E4302586 -:102B6000020028210E001A6A026020212410FFFFB3 -:102B7000105000BE8F8500388F830054106000C451 -:102B8000240500013C1908008F39318C0323782B70 -:102B900015E000B12409002D026020210000282149 -:102BA0000E0019A9240600018F85003800001821A5 -:102BB0000A001D320060A0210E0018750000000000 -:102BC0000A001DF800000000AC8000200A001E78FA -:102BD0008E03001400002821026020210E0019A994 -:102BE000240600010A001CC38F8500380A001DB7A7 -:102BF0008F8800388CB000848CB900843C031000AE -:102C00000207482400096940332F007F01AFF825EF -:102C100003E32825ACC50830910700012405000115 -:102C2000026020210E0019A930E600010A001CC331 -:102C30008F850038938F00482403FFFD0A001D3460 -:102C4000AF8F00600A001D342403FFFF02602021C3 -:102C50002410000D0E001A4AA390006800401821AD -:102C60008F8500380A001D320060A0210E00187503 -:102C7000000000009783005C8F8600603070FFFFCB -:102C800000D048232D3900051320FE128F8500380F -:102C9000ACA200EC0A001D2F3062FFFF90C3000DB4 -:102CA000307800085700FFA2920400030260202140 -:102CB000240200100E001A4AA38200682403FFFFBA -:102CC0005443FF9B920400030A001F128F850038B3 -:102CD00090A8000D3106000810C000958F94005494 -:102CE0001680009E026020218E0F000C8CA4002014 -:102CF00055E40005026020218E1F00088CB90024D5 -:102D000013F9003A02602021240200200E001A4A22 -:102D1000A38200682405FFFF1045FEEE2404FFFF98 -:102D20008F8F0044240CFFF72403FF8091E9000DEE -:102D30003C14800E3C0B8000012CC824A1F9000D2E -:102D40008F8F00303C0708008CE731AC8F8D006C12 -:102D500095E500788F99004400ED902130BF7FFF0A -:102D6000001F20400244302130C8007F00C3C0242F -:102D700001147021AD78002CA5D100008F2A002805 -:102D800025420001AF2200288F29002C8E0C002C38 -:102D9000012C6821AF2D002C8E07002CAF270030AE -:102DA0008E050014AF250034973F003A27E4000158 -:102DB000A724003A95F200783C1008008E1031B03C -:102DC0002643000130717FFF1230005C006030212B -:102DD0008F83003002602021240500010E00193489 -:102DE000A46600780A001EA1000020218E070014AE -:102DF0002412FFFF10F200638F8C00388E09001838 -:102E00008D8D00D0152D005D026020218E0A0024DA -:102E10008CA2002811420053240200210E001A4AFD -:102E2000A38200681452FFBE2404FFFF8F85003880 -:102E30000A001D320080A0212402001F0E001A4A41 -:102E4000A38200682409FFFF1049FEA22404FFFFAB -:102E50000A001E548F830054026020210E001A4A7B -:102E6000A38900681450FF518F8500382403FFFFA9 -:102E70000A001D320060A0218CCE00248E0B00249D -:102E8000116EFF2A026020210A001F262402000F73 -:102E90000E001934026020218F8500380A001EE5DB -:102EA000000018218E0900003C05008001259024B7 -:102EB0001640FF452402001A026020210E001A4A23 -:102EC000A3820068240CFFFF144CFECB2404FFFFF8 -:102ED0008F8500380A001D320080A0212403FFFDE9 -:102EE0000060A0210A001D32AF8700602418001D79 -:102EF0000E001A4AA39800682403FFFF1443FEA69D -:102F00002404FFFF8F8500380A001D320080A021B5 -:102F10002412002C0E001A4AA39200682403FFFF1B -:102F20001043FF508F8500380A001ECC9204000326 -:102F3000026020210A001F3C24020024240B800090 -:102F4000006B702431CAFFFF000A13C2305100FF2A -:102F5000001180270A001F6D001033C00A001F3CBB -:102F6000240200278E0600288CAE002C10CE00080C -:102F7000026020210A001F802402001F0A001F8017 -:102F80002402000E026020210A001F802402002576 -:102F90008E04002C1080000D8F8300308C7800741C -:102FA0000304582B5560000C026020218CA80014EB -:102FB0000086A0210114302B10C0FF5A8F8F0044CF -:102FC000026020210A001F802402002202602021CA -:102FD0000A001F80240200230A001F80240200260A -:102FE00027BDFFD8AFB3001CAFB10014AFBF0020A6 -:102FF000AFB20018AFB000103C0280008C5201400C -:103000008C4B01483C048000000B8C02322300FFF3 -:10301000317300FF8C8501B804A0FFFE349001805D -:10302000AE1200008C8701442464FFF024060002E5 -:103030002C830013AE070004A6110008A206000BA3 -:10304000AE1300241060004F8FBF002000044880A2 -:103050003C0A0801254A9510012A40218D040000F0 -:1030600000800008000000003C0308008C6331A8C9 -:1030700031693FFF0009998000728021021370219D -:103080002405FF80264D0100264C00803C02800074 -:1030900031B1007F3198007F31CA007F3C1F800A28 -:1030A0003C1980043C0F800C01C5202401A530246C -:1030B00001853824014F1821AC460024023F4021ED -:1030C00003194821AC470090AC440028AF8300446A -:1030D000AF880038AF8900300E00190001608021F0 -:1030E0003C0380008C6B01B80560FFFE8F870044B5 -:1030F0008F8600383465018090E8000DACB2000086 -:10310000A4B0000600082600000416030002902761 -:10311000001227C21080008124C20088241F608210 -:10312000A4BF0008A0A0000524020002A0A2000B7A -:103130008F8B0030000424003C0827000088902575 -:10314000ACB20010ACA00014ACA00024ACA00028CD -:10315000ACA0002C8D6900382413FF80ACA90018A6 -:1031600090E3000D02638024320500FF10A00005EB -:103170008FBF002090ED000D31AC007FA0EC000D62 -:103180008FBF00208FB3001C8FB200188FB10014C6 -:103190008FB000103C0A10003C0E800027BD0028B4 -:1031A00003E00008ADCA01B8265F01002405FF80D6 -:1031B00033F8007F3C06800003E578243C19800A40 -:1031C00003192021ACCF0024908E00D400AE6824D7 -:1031D00031AC00FF11800024AF840038248E0088B9 -:1031E00095CD00123C0C08008D8C31A831AB3FFF0F -:1031F00001924821000B5180012A40210105202421 -:10320000ACC400283107007F3C06800C00E620217A -:103210009083000D00A31024304500FF10A0FFD8BC -:10322000AF8400449098000D330F001015E0FFD5D7 -:103230008FBF00200E001900000000003C0380003A -:103240008C7901B80720FFFE00000000AE120000DC -:103250008C7F0144AE1F0004A61100082411000257 -:10326000A211000BAE1300243C130801927396D0F8 -:10327000327000015200FFC38FBF00200E00213DBD -:10328000024020210A00205A8FBF00203C1260001B -:103290008E452C083C03F0033462FFFF00A2F824A3 -:1032A000AE5F2C088E582C083C1901C003199825D4 -:1032B000AE532C080A00205A8FBF0020264D010073 -:1032C00031AF007F3C10800A240EFF8001F02821DE -:1032D00001AE60243C0B8000AD6C00241660FFA89A -:1032E000AF85003824110003A0B100FC0A00205A69 -:1032F0008FBF002026480100310A007F3C0B800A66 -:103300002409FF80014B3021010920243C07800063 -:10331000ACE400240A002059AF860038944E001215 -:10332000320C3FFF31CD3FFF15ACFF7D241F608283 -:1033300090D900D42418FF800319782431EA00FFC3 -:103340001140FF770000000024070004A0C700FC24 -:103350008F870044241160842406000DA4B1000866 -:10336000A0A600050A002044240200023C0400013B -:10337000248496BC24030014240200FE3C010800AF -:10338000AC2431EC3C010800AC2331E83C010801DD -:10339000A42296D83C040801248496D80000182161 -:1033A00000643021A0C30004246300012C6500FFE9 -:1033B00054A0FFFC006430213C07080024E7010012 -:1033C00003E00008AF87007800A058210080482162 -:1033D0000000102114A00012000050210A00213921 -:1033E000000000003C010801A42096D83C0508011B -:1033F00094A596D88F8200783C0C0801258C96D82D -:1034000000E2182100AC2021014B302BA0890004E0 -:1034100000001021A460000810C0003901004821FC -:103420008F8600780009384000E940210008388084 -:1034300000E6282190A8000B90B9000A000820405F -:1034400000881021000218800066C021A319000A1C -:103450008F85007800E5782191EE000A91E6000B57 -:10346000000E684001AE6021000C20800085102114 -:10347000A046000B3C030801906396D21060002226 -:103480002462FFFF8F8300383C010801A02296D2FE -:10349000906C00FF1180000400000000906E00FF9F -:1034A00025CDFFFFA06D00FF3C190801973996D884 -:1034B000272300013078FFFF2F0F00FF11E0FFC925 -:1034C000254A00013C010801A42396D83C050801C7 -:1034D00094A596D88F8200783C0C0801258C96D84C -:1034E00000E2182100AC2021014B302BA089000400 -:1034F00000001021A460000814C0FFC90100482189 -:1035000003E000080000000003E0000824020002BD -:1035100027BDFFE0248501002407FF80AFB0001025 -:10352000AFBF0018AFB1001400A718243C108000F2 -:1035300030A4007F3C06800A008628218E110024DA -:10354000AE03002490A200FF14400008AF850038AD -:10355000A0A000098FBF0018AE1100248FB1001485 -:103560008FB0001003E0000827BD002090A900FDE7 -:1035700090A800FF312400FF0E0020EB310500FF72 -:103580008F8500388FBF0018A0A00009AE1100245D -:103590008FB100148FB0001003E0000827BD002099 -:1035A00027BDFFD0AFB20020AFB1001CAFB00018F4 -:1035B000AFBF002CAFB40028AFB300243C0980009B -:1035C0009533011635320C00952F011A3271FFFF29 -:1035D000023280218E08000431EEFFFF248B0100AF -:1035E000010E6821240CFF8025A5FFFF016C5024EB -:1035F0003166007F3C07800AAD2A002400C73021D5 -:10360000AF850074AF8800703C010801A02096D1FE -:1036100090C300090200D02100809821306300FF90 -:103620002862000510400048AF8600382864000278 -:103630001480008E24140001240D00053C010801B3 -:10364000A02D96B590CC00FD3C010801A02096B6B7 -:103650003C010801A02096B790CB000A240AFF8005 -:10366000318500FF014B4824312700FF10E0000C9A -:10367000000058213C128008365100808E2F003007 -:103680008CD0005C01F0702305C0018E8F87007024 -:1036900090D4000A3284007FA0C4000A8F860038CC -:1036A0003C118008363000808E0F00308F8700700C -:1036B00000EF702319C000EE0000000090D4000954 -:1036C00024120002328400FF109202470000000022 -:1036D0008CC2005800E2F82327F9FFFF1B200130BD -:1036E0000000000090C500092408000430A300FF7A -:1036F00010680057240A00013C010801A02A96B571 -:1037000090C900FF252700013C010801A02796B4BD -:103710003C030801906396B5240600051066006A14 -:103720002C780005130000C4000090210003F880ED -:103730003C0408012484955C03E4C8218F25000023 -:1037400000A0000800000000241800FF1078005CB2 -:103750000000000090CC000A90CA00093C08080153 -:10376000910896D13187008000EA48253C01080184 -:10377000A02996BC90C500FD3C140801929496D2F5 -:10378000311100013C010801A02596BD90DF00FE2B -:103790003C010801A03F96BE90D200FF3C01080109 -:1037A000A03296BF8CD900543C010801AC3996C0B8 -:1037B0008CD000583C010801AC3096C48CC3005C2E -:1037C0003C010801AC3496CC3C010801AC2396C8FE -:1037D000162000088FBF002C8FB400288FB3002460 -:1037E0008FB200208FB1001C8FB0001803E00008DA -:1037F00027BD00303C1180009624010E0E000FD42E -:103800003094FFFF3C0B08018D6B96D40260382189 -:1038100002802821AE2B01803C1308018E7396B4E0 -:1038200001602021240600830E00102FAFB300108A -:103830008FBF002C8FB400288FB300248FB20020DC -:103840008FB1001C8FB0001803E0000827BD0030C6 -:103850003C1808008F1831FC270F00013C010800BC -:10386000AC2F31FC0A0021CE000000001474FFB917 -:1038700000000000A0C000FF3C0508008CA531E45A -:103880003C0308008C6331E03C0208008C423204A7 -:103890008F99003834A80001241F00023C01080160 -:1038A000AC2396D43C010801A02896D03C01080125 -:1038B000A02296D3A33F00090A0021878F860038F3 -:1038C0000E00213D000000000A0021CE8F86003846 -:1038D0003C1F080193FF96B42419000113F9022933 -:1038E0008F8700703C100801921096B83C060801C2 -:1038F00090C696B610C000050200A0213C04080145 -:10390000908496B9109001E48F8700780010884069 -:103910008F9F0078023048210009C880033F702142 -:1039200095D80008270F0001A5CF00083C04080126 -:10393000908496B93C05080190A596B60E0020EB40 -:10394000000000008F8700780230202100043080C2 -:1039500000C720218C8500048F82007400A24023C0 -:1039600005020006AC8200048C8A00008F83007080 -:10397000014310235C400001AC8300008F860038B7 -:1039800090CB00FF2D6C00025580002D2414000107 -:103990000230F821001F40800107282190B9000B58 -:1039A0008CAE00040019C04003197821000F188064 -:1039B000006710218C4D000001AE88232630FFFFE8 -:1039C0005E00001F241400018C4400048CAA000037 -:1039D000008A482319200019240E00043C01080124 -:1039E000A02E96B590AD000B8CAB0004000D884066 -:1039F000022D802100101080004710218C4400040B -:103A000001646023058202009443000890DF00FEF9 -:103A100090B9000B33E500FF54B900040107A02161 -:103A2000A0D400FE8F8700780107A0219284000BAC -:103A30000E0020EB240500018F86003824140001BD -:103A4000125400962E500001160000423C08FFFF61 -:103A5000241900021659FF3F00000000A0C000FF1B -:103A60008F860038A0D200090A0021CE8F86003848 -:103A700090C700092404000230E300FF1064016FC6 -:103A800024090004106901528F8800748CCE005400 -:103A9000010E682325B100010620017524180004D9 -:103AA0003C010801A03896B53C010801A02096B45D -:103AB00090D400FD90D200FF2E4F000215E0FF14BD -:103AC000328400FF000438408F89007890DF00FFC7 -:103AD00000E41021000220800089C8212FE50002A7 -:103AE0009324000B14A0FF0A2407000200041840CE -:103AF0000064802100105880016928218CAC0004EA -:103B0000010C50230540FF02000000003C030801A7 -:103B1000906396B614600005246F00013C01080113 -:103B2000A02496B93C010801A02796B73C010801E2 -:103B3000A02F96B690CE00FF24E7000131CD00FF04 -:103B400001A7882B1220FFE990A4000B0A0021BDD9 -:103B5000000000003C0508018CA596B43C1200044E -:103B600000A8F82413F20006240200053C0908010D -:103B7000912996B5152000022402000324020005B5 -:103B80003C010801A02296D190C700FF14E001205B -:103B900024020002A0C200090A0021CE8F8600384C -:103BA00090CC00FF1180FEDA240A00018F8C007493 -:103BB0008F890078240F0003018068211160001EA6 -:103BC000240E0002000540400105A02100142080C1 -:103BD000008990218E510004019180230600FECCC3 -:103BE000000000003C020801904296B61440000517 -:103BF000245800013C010801A02A96B73C010801A5 -:103C0000A02596B93C010801A03896B690DF00FFC8 -:103C1000010510210002C88033E500FF254A00019C -:103C20000329202100AA402B1500FEB99085000B26 -:103C30001560FFE5000540400005404001051821E2 -:103C4000000310803C010801A02A96B43C01080141 -:103C5000A02596B8004918218C64000400E4F823DC -:103C600027F9FFFF1F20FFE9000000008C63000020 -:103C700000E358230560013A01A3882310E30117EC -:103C80000184C0231B00FEA2000000003C010801CB -:103C9000A02E96B50A0022FC240B0001240E00047D -:103CA000A0CE00093C0D08008DAD31F88F8600389C -:103CB00025A200013C010800AC2231F80A0021CE07 -:103CC000000000008CD9005C00F9C0231F00FE7BBF -:103CD000000000008CDF005C10FFFF658F84007423 -:103CE0008CC3005C00834023250200011C40FF6060 -:103CF000000000008CC9005C2487000100E9282B2B -:103D000010A0FE943C0D80008DAB01043C0C000122 -:103D1000016C50241140FE8F240200103C01080168 -:103D2000A02296D10A0021CE000000008F910074DD -:103D30008F86003826220001ACC2005C0A0022896E -:103D4000241400018F8700382404FF80000088219C -:103D500090E9000A2414000101243025A0E6000A9D -:103D60003C05080190A596B63C040801908496B9DC -:103D70000E0020EB000000008F8600388F85007851 -:103D800090C800FD310700FF000740400107F821FF -:103D9000001FC0800305C8219323000BA0C300FDB2 -:103DA0008F8500788F86003803056021918F000B86 -:103DB000000F704001CF6821000D808002051021A6 -:103DC0008C4B0000ACCB00548D8400048F830074B6 -:103DD0000064502319400002248200012462000183 -:103DE00001074821ACC2005C0009308000C54021B9 -:103DF00000E02021240500010E0020EB9110000BB3 -:103E00008F86003890C500FF10A0FF0C0010704096 -:103E10008F85007801D06821000D10800045582161 -:103E20008D6400008F8C00740184502325470001AD -:103E300004E0FF02263100013C030801906396B6BE -:103E40002E2F0002247800013C010801A03896B60C -:103E50003C010801A03496B711E0FEF802003821B9 -:103E60000A00235C000740408F8400388F83007471 -:103E70008C85005800A340230502FE9AAC830058AD -:103E80000A002232000000003C07080190E796D2A9 -:103E9000240200FF10E200BE8F8600383C110801AA -:103EA000963196DA3C030801246396D82625000152 -:103EB0003230FFFF30ABFFFF020360212D6A00FFAD -:103EC0001540008D918700043C010801A42096DA7A -:103ED0008F8800380007484001272821911800FFEB -:103EE000000530802405000127140001A11400FF03 -:103EF0003C120801925296D28F8800788F8E007003 -:103F0000264F000100C820213C010801A02F96D2B5 -:103F1000AC8E00008F8D0074A4850008AC8D000469 -:103F20003C030801906396B4146000770000902170 -:103F30003C010801A02596B4A087000B8F8C007867 -:103F400000CC5021A147000A8F820038A04700FD15 -:103F50008F840038A08700FE8F8600388F9F007006 -:103F6000ACDF00548F990074ACD900588F8D007865 -:103F70000127C02100185880016DA021928F000AEE -:103F8000000F704001CF182100038880022D80218E -:103F9000A207000B8F86007801666021918A000BD2 -:103FA000000A1040004A20210004288000A6402179 -:103FB000A107000A3C07800834E900808D22003008 -:103FC0008F860038ACC2005C0A00228924140001EC -:103FD00090CA00FF1540FEAD8F880074A0C4000990 -:103FE0000A0021CE8F860038A0C000FD8F980038CF -:103FF00024060001A30000FE3C010801A02696B59E -:104000003C010801A02096B40A0021BD0000000078 -:1040100090CB00FF3C040801908496D3316C00FFE4 -:104020000184502B1540000F2402000324020004D9 -:10403000A0C200090A0021CE8F86003890C3000A72 -:104040002410FF8002035824316C00FF1180FDC151 -:10405000000000003C010801A02096B50A0021BD27 -:1040600000000000A0C200090A0021CE8F8600389F -:1040700090D4000A2412FF8002544824312800FF03 -:104080001500FFF4240200083C010801A02296D18B -:104090000A0021CE00000000001088408F8B0070C5 -:1040A000023018210003688001A72021AC8B00009A -:1040B0008F8A0074240C0001A48C0008AC8A0004D0 -:1040C0003C05080190A596B62402000110A2FE1E30 -:1040D00024A5FFFF0A0022489084000B0184A0233E -:1040E0001A80FD8B000000003C010801A02E96B54F -:1040F0000A0022FC240B00013C010801A42596DAE9 -:104100000A0023AE8F880038240B0001106B0022B8 -:104110008F9800388F85003890BF00FF33F900FF7B -:104120001079002B000000003C1F080193FF96B897 -:10413000001FC840033FC0210018A08002887821DA -:1041400091EE000AA08E000A8F8D00783C030801D2 -:10415000906396B800CD88210A0023D4A223000BD7 -:10416000263000010600003101A490230640002BF8 -:10417000240200033C010801A02F96B50A0022FC8E -:10418000240B00018F8900380A002232AD27005429 -:104190000A00228824120001931400FDA094000B51 -:1041A0008F8800388F8F0078910E00FE00CF682135 -:1041B000A1AE000A8F910038A22700FD8F83007006 -:1041C0008F900038AE0300540A0023D58F8D0078FD -:1041D00090B000FEA090000A8F8B00388F8C007882 -:1041E000916A00FD00CC1021A04A000B8F8400389A -:1041F000A08700FE8F8600748F850038ACA600581B -:104200000A0023D58F8D007894B80008ACA4000470 -:10421000030378210A00227CA4AF00083C010801B6 -:10422000A02296B50A0021BD0000000090CF000931 -:10423000240D000431EE00FF11CDFD8524020001A4 -:104240003C010801A02296B50A0021BD0000000033 -:10425000080033440800334408003420080033F4D5 -:10426000080033D808003328080033280800332812 -:104270000800334C8008010080080080800800009E -:104280005F865437E4AC62CC50103A4536621985EB -:10429000BF14C0E81BC27A1E84F4B556094EA6FEB0 -:1042A0007DDA01E7C04D748108005A7408005AB8DD -:1042B00008005A5C08005A5C08005A5C08005A5C06 -:1042C00008005A7408005A5C08005A5C08005AC07A -:1042D00008005A5C080059D408005A5C08005A5C6F -:1042E00008005AC008005A5C08005A5C08005A5C72 -:1042F00008005A5C08005A5C08005A5C08005A5CC6 -:1043000008005A5C08005A5C08005A5C08005A947D -:1043100008005A5C08005A9408005A5C08005A5C6D -:1043200008005A5C08005A9808005A9408005A5C21 -:1043300008005A5C08005A5C08005A5C08005A5C85 -:1043400008005A5C08005A5C08005A5C08005A5C75 -:1043500008005A5C08005A5C08005A5C08005A5C65 -:1043600008005A5C08005A5C08005A5C08005A5C55 -:1043700008005A5C08005A5C08005A5C08005A9809 -:1043800008005A9808005A5C08005A9808005A5CBD -:1043900008005A5C08005A5C08005A5C08005A5C25 -:1043A00008005A5C08005A5C08005A5C08005A5C15 -:1043B00008005A5C08005A5C08005A5C08005A5C05 -:1043C00008005A5C08005A5C08005A5C08005A5CF5 -:1043D00008005A5C08005A5C08005A5C08005A5CE5 -:1043E00008005A5C08005A5C08005A5C08005A5CD5 -:1043F00008005A5C08005A5C08005A5C08005A5CC5 -:1044000008005A5C08005A5C08005A5C08005A5CB4 -:1044100008005A5C08005A5C08005A5C08005A5CA4 -:1044200008005A5C08005A5C08005A5C08005A5C94 -:1044300008005A5C08005A5C08005A5C08005A5C84 -:1044400008005A5C08005A5C08005A5C08005A5C74 -:1044500008005A5C08005A5C08005A5C08005A5C64 -:1044600008005A5C08005A5C08005A5C08005A5C54 -:1044700008005A5C08005A5C08005A5C08005A5C44 -:1044800008005A5C08005A5C08005A5C08005A5C34 -:1044900008005A5C08005A5C08005A5C08005A5C24 -:1044A00008005A5C08005A5C08005ADC0800782CA6 -:1044B00008007A90080078380800762C08007838D0 -:1044C000080078C4080078380800762C0800762C9C -:1044D0000800762C0800762C0800762C0800762C34 -:1044E0000800762C0800762C0800762C0800762C24 -:1044F00008007858080078480800762C0800762CC8 -:104500000800762C0800762C0800762C0800762C03 -:104510000800762C0800762C0800762C0800762CF3 -:104520000800762C0800762C08007848080082D80D -:1045300008008164080082A008008164080082707D -:104540000800804C080081640800816408008164D0 -:1045500008008164080081640800816408008164A7 -:104560000800816408008164080081640800816497 -:10457000080081640800818C08008D1008008E6C92 -:0C45800008008E4C080088B408008D284C -:04458C000A000124FC -:1045900000000000000000000000000D7470613693 -:1045A0002E322E31610000000602010100000000E1 -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:1046200010000003000000000000000D0000000D5D -:104630003C020800244217203C03080024632A108F -:10464000AC4000000043202B1480FFFD24420004F6 -:104650003C1D080037BD2FFC03A0F0213C100800D2 -:10466000261004903C1C0800279C17200E000262B4 -:10467000000000000000000D2402FF8027BDFFE0C5 -:1046800000821024AFB00010AF420020AFBF00186E -:10469000AFB10014936500043084007F03441821F7 -:1046A0003C0200080062182130A500200360802130 -:1046B0003C080111277B000814A000022466005C5E -:1046C00024660058920200049743010492040004F7 -:1046D0003047000F3063FFFF30840040006728231D -:1046E00010800009000048219202000530420004B9 -:1046F000104000050000000010A0000300000000B2 -:1047000024A5FFFC240900049202000530420004A5 -:10471000104000120000000010A000100000000077 -:104720009602000200A72021010440252442FFFE3A -:10473000A7421016920300042402FF8000431024B5 -:10474000304200FF104000033C0204000A000174E4 -:10475000010240258CC20000AF4210188F42017840 -:104760000440FFFE2402000AA74201409602000214 -:1047700024040009304200070002102330420007E1 -:10478000A7420142960200022442FFFEA7420144D2 -:10479000A740014697420104A74201488F42010801 -:1047A0003042002050400001240400019202000425 -:1047B00030420010144000023483001000801821A1 -:1047C000A743014A000000000000000000000000B4 -:1047D00000000000AF4810000000000000000000D2 -:1047E00000000000000000008F4210000441FFFEA6 -:1047F0003102FFFF10400007000000009202000499 -:104800003042004014400003000000008F421018A6 -:10481000ACC20000960200063042FFFF24420002B4 -:10482000000210430002104003628821962200001B -:104830001120000D3044FFFF00A710218F830038A6 -:104840008F45101C000210820002108000431021CE -:10485000AC45000030A6FFFF0E00058D00052C02C0 -:1048600000402021A6220000920300042402FF80C1 -:1048700000431024304200FF1040001F00000000E1 -:1048800092020005304200021040001B00000000B0 -:104890009742100C2442FFFEA742101600000000B1 -:1048A0003C02040034420030AF421000000000001F -:1048B0000000000000000000000000008F42100017 -:1048C0000441FFFE000000009742100C8F45101CB1 -:1048D0003042FFFF244200300002108200021080AC -:1048E000005B1021AC45000030A6FFFF0E00058DD7 -:1048F00000052C02A6220000960400022484000871 -:104900000E0001E93084FFFF974401040E0001F717 -:104910003084FFFF8FBF00188FB100148FB00010DC -:104920003C02100027BD002003E00008AF420178E0 -:104930003084FFFF308200078F8500241040000282 -:10494000248300073064FFF800A4102130421FFFC9 -:1049500003421821247B4000AF850028AF82002449 -:1049600003E00008AF4200843084FFFF3082000F74 -:104970008F85002C8F860034104000022483000FA6 -:104980003064FFF000A410210046182BAF850030E2 -:104990000046202314600002AF82002CAF84002C5C -:1049A0008F82002C340480000342182100641821F7 -:1049B000AF83003803E00008AF4200808F8200140C -:1049C000104000088F8200048F82FFDC1440000535 -:1049D0008F8200043C02FFBF3442FFFF008220248C -:1049E0008F82000430430006240200021062000F90 -:1049F0003C0201012C620003504000052402000427 -:104A00001060000F3C0200010A00023000000000AC -:104A100010620005240200061462000C3C02011121 -:104A20000A000229008210253C0200110082102594 -:104A3000AF421000240200010A000230AF82000CD5 -:104A400000821025AF421000AF80000C0000000073 -:104A5000000000000000000003E00008000000006B -:104A60008F82000C10400004000000008F421000F4 -:104A70000441FFFE0000000003E000080000000009 -:104A80008F8200102443F800000231C224C2FFF0DC -:104A90002C63030110600003000210420A00025759 -:104AA000AC8200008F85001800C5102B1440000B4D -:104AB0000000182100C51023244700018F82001C2C -:104AC00000A210212442FFFF0046102B5440000496 -:104AD0002402FFFF0A000257AC8700002402FFFFF8 -:104AE0000A000260AC8200008C82000000021940C3 -:104AF000006218210003188000621821000318804A -:104B00003C0208002442175C0062182103E0000800 -:104B10000060102127BDFFD8AFBF0020AFB1001C3F -:104B2000AFB000183C0460088C8250002403FF7F63 -:104B30003C066000004310243442380CAC82500024 -:104B40008CC24C1C3C1A8000000216023042000F3E -:104B500010400007AF82001C8CC34C1C3C02001F9D -:104B60003442FC0000621824000319C2AF8300180D -:104B70008F420008275B400034420001AF4200082A -:104B8000AF8000243C02601CAF400080AF40008436 -:104B90008C4500088CC308083402800003422021A1 -:104BA0002402FFF0006218243C0200803C0108004F -:104BB000AC2204203C025709AF8400381462000480 -:104BC000AF850034240200010A000292AF82001473 -:104BD000AF8000148F4200003842000130420001D3 -:104BE0001440FFFC8F8200141040001600000000EB -:104BF00097420104104000058F83000014600007F5 -:104C00002462FFFF0A0002A72C62000A2C62001037 -:104C1000504000048F83000024620001AF82000036 -:104C20008F8300002C62000A144000032C620007EE -:104C30000A0002AEAF80FFDC104000022402000137 -:104C4000AF82FFDC8F4301088F44010030622000F7 -:104C5000AF83000410400008AF8400103C0208003D -:104C60008C42042C244200013C010800AC22042C9C -:104C70000A00058A3C0240003065020014A00003CF -:104C800024020F001482026024020D0097420104E6 -:104C9000104002C83C02400030624000144000ADA9 -:104CA0008F8200388C4400088F4201780440FFFE58 -:104CB00024020800AF42017824020008A742014004 -:104CC000A7400142974201048F8400043051FFFF46 -:104CD0003082000110400007022080212623FFFEC1 -:104CE000240200023070FFFFA74201460A0002DBE7 -:104CF000A7430148A74001463C0208008C42043CFF -:104D00001440000D8F8300103082002014400002F8 -:104D10002403000924030001006020218F83001078 -:104D2000240209005062000134840004A744014AAF -:104D30000A0002F60000000024020F0014620005C1 -:104D400030820020144000062403000D0A0002F502 -:104D50002403000514400002240300092403000179 -:104D6000A743014A3C0208008C4204203C0400484E -:104D70000E00020C004420250E0002350000000049 -:104D80008F82000C1040003E000000008F42100097 -:104D90003C03002000431024104000398F8200049F -:104DA000304200021040003600000000974210140C -:104DB0001440003300000000974210088F8800382C -:104DC0003042FFFF244200060002188200033880B0 -:104DD00000E83021304300018CC400001060000462 -:104DE000304200030000000D0A00033700E81021E4 -:104DF000544000103084FFFF3C05FFFF0085202455 -:104E0000008518260003182B0004102B00431024E3 -:104E10001040000500000000000000000000000D30 -:104E200000000000240002228CC200000A000336A9 -:104E3000004520253883FFFF0003182B0004102BAA -:104E40000043102410400005000000000000000096 -:104E50000000000D000000002400022B8CC20000A6 -:104E60003444FFFF00E81021AC4400003C0208007D -:104E70008C420430244200013C010800AC22043082 -:104E80008F6200008F840038AF8200088C8300009E -:104E90003402FFFF1462000F000010213C050800DF -:104EA0008CA504543C0408008C84045000B02821D4 -:104EB00000B0302B00822021008620213C01080018 -:104EC000AC2504543C010800AC2404500A000580C1 -:104ED000240400088C820000304201001040000FC2 -:104EE000000010213C0508008CA5044C3C0408007F -:104EF0008C84044800B0282100B0302B008220218F -:104F0000008620213C010800AC25044C3C0108002F -:104F1000AC2404480A000580240400083C0508006D -:104F20008CA504443C0408008C84044000B0282173 -:104F300000B0302B00822021008620213C01080097 -:104F4000AC2504443C010800AC2404400A00058060 -:104F5000240400088F6200088F620000000216021D -:104F6000304300F0240200301062000524020040AB -:104F7000106200E08F8200200A00058824420001B0 -:104F800014A0000500000000000000000000000D5B -:104F900000000000240002568F4201780440FFFE0A -:104FA000000000000E00023D27A400101440000580 -:104FB00000408021000000000000000D0000000003 -:104FC0002400025D8E020000104000050000000079 -:104FD000000000000000000D00000000240002603E -:104FE0008F62000C04430003240200010A00042E17 -:104FF000AE000000AE0200008F8200388C4800082E -:10500000A20000078F65000C8F64000430A3FFFF2F -:105010000004240200852023308200FF0043102179 -:1050200024420005000230832CC20081A605000A3C -:1050300014400005A2040004000000000000000D60 -:1050400000000000240002788F8500380E0005ABB8 -:10505000260400148F6200048F430108A602000892 -:105060003C021000006218241060000800000000DC -:1050700097420104920300072442FFEC34630002CC -:105080003045FFFF0A0003C3A20300079742010453 -:105090002442FFF03045FFFF960600082CC20013A3 -:1050A00054400005920300079202000734420001B9 -:1050B000A20200079203000724020001106200050B -:1050C000240200031062000B8F8200380A0003E004 -:1050D00030C6FFFF8F8200383C04FFFF8C43000C7A -:1050E0000064182400651825AC43000C0A0003E096 -:1050F00030C6FFFF3C04FFFF8C43001000641824FF -:1051000000651825AC43001030C6FFFF24C2000222 -:1051100000021083A20200058F830038304200FF96 -:1051200000021080004328218CA800008CA20000FF -:1051300024030004000217021443001200000000C0 -:10514000974201043C03FFFF010318243042FFFF94 -:10515000004610232442FFFE00624025ACA8000058 -:1051600092030005306200FF000210800050102101 -:10517000904200143042000F004310210A00041531 -:10518000A20200068CA40004974201049603000AC0 -:105190003088FFFF3042FFFF004610232442FFD635 -:1051A0000002140001024025ACA80004920200078E -:1051B000920400052463002800031883006418216A -:1051C00034420004A2030006A20200078F820004FA -:1051D0002403FFFB3442000200431024AF8200048A -:1051E000920300068F87003800031880007010219A -:1051F0008C4400203C02FFF63442FFFF0082402432 -:1052000000671821AE04000CAC68000C9205000683 -:105210003C03FF7F8E02000C0005288000B0202197 -:105220003463FFFF010330249488002600A728215F -:1052300000431024AE02000CAC860020AC88002491 -:10524000ACA8001024020010A74201402402000272 -:10525000A7400142A7400144A742014697420104EA -:105260003C0400082442FFFEA7420148240200013A -:105270000E00020CA742014A9603000A92020004A3 -:105280000043102124420002304200070002102394 -:10529000304200070E000235AE0200108F6200009F -:1052A0003C0308008C63044424040010AF8200080F -:1052B000974201043042FFFF2442FFFE00403821A4 -:1052C000000237C33C0208008C42044000671821EA -:1052D0000067282B00461021004510213C010800E2 -:1052E000AC2304443C010800AC2204400A0005152C -:1052F0000000000014A000050000000000000000F5 -:105300000000000D000000002400030A8F42017815 -:105310000440FFFE000000000E00023D27A4001420 -:105320001440000500408021000000000000000D36 -:1053300000000000240003118E020000544000060B -:1053400092020007000000000000000D00000000B5 -:105350002400031C920200073042000410400005A4 -:105360008F8200042403FFFB344200020043102418 -:10537000AF8200048F620004044300089202000719 -:10538000920200068E03000CAE00000000021080A6 -:1053900000501021AC43002092020007304200046C -:1053A000544000099602000A920200053C030001E5 -:1053B00000021080005010218C46001800C33021DC -:1053C000AC4600189602000A9206000427710008F5 -:1053D0000220202100C2302124C600052605001429 -:1053E0000E0005AB00063082920400068F650004B3 -:1053F0003C027FFF00042080009120218C83000468 -:105400003442FFFF00A2282400651821AC83000469 -:105410009202000792040005920300043042000447 -:105420001040001496070008308400FF000420801C -:10543000009120218C860004974201049605000A01 -:10544000306300FF3042FFFF004310210045102170 -:1054500030E3FFFF004310232442FFD830C6FFFF94 -:105460000002140000C23025AC8600040A0004C902 -:1054700092030007308500FF0005288000B1282135 -:105480008CA4000097420104306300FF3042FFFF0C -:1054900000431021004710233C03FFFF008320241A -:1054A0003042FFFF00822025ACA4000092030007D9 -:1054B0002402000110620006000000002402000324 -:1054C00010620011000000000A0004EC8E030010BE -:1054D00097420104920300049605000A8E24000CF2 -:1054E00000431021004510212442FFF23C03FFFF3E -:1054F000008320243042FFFF00822025AE24000CD0 -:105500000A0004EC8E030010974201049203000489 -:105510009605000A8E24001000431021004510213A -:105520002442FFEE3C03FFFF008320243042FFFFB4 -:1055300000822025AE2400108E0300102402000AF1 -:10554000A7420140A74301429603000A92020004C9 -:105550003C04004000431021A7420144A7400146FB -:1055600097420104A7420148240200010E00020CE8 -:10557000A742014A0E000235000000008F620000C1 -:105580009203000400002021AF820008974201042A -:105590009606000A3042FFFF0062182100602821B1 -:1055A0003C0308008C6304443C0208008C42044025 -:1055B00000651821004410210065382B0047102198 -:1055C0003C010800AC2304443C010800AC22044028 -:1055D00092040004008620212484000A3084FFFF06 -:1055E0000E0001E900000000974401043084FFFF31 -:1055F0000E0001F7000000003C021000AF420178ED -:105600000A0005878F82002014820027306200067E -:1056100097420104104000673C02400030624000A5 -:105620001040000500000000000000000000000D18 -:1056300000000000240004208F4201780440FFFE97 -:1056400024020800AF42017824020008A74201406A -:10565000A74001428F8200049743010430420001B9 -:10566000104000073070FFFF2603FFFE24020002F7 -:10567000A7420146A74301480A00053F2402000D46 -:10568000A74001462402000DA742014A8F62000094 -:1056900024040008AF8200080E0001E900000000A9 -:1056A0000A00051902002021104000423C0240007F -:1056B00093620000304300F02402001010620005E5 -:1056C00024020070106200358F8200200A000588D5 -:1056D000244200018F620000974301043050FFFF15 -:1056E0003071FFFF8F4201780440FFFE3202000755 -:1056F00000021023304200072403000A2604FFFEA4 -:10570000A7430140A7420142A7440144A7400146E4 -:10571000A75101488F420108304200201440000286 -:105720002403000924030001A743014A0E00020CD0 -:105730003C0400400E000235000000003C07080059 -:105740008CE70444021110212442FFFE3C060800AD -:105750008CC604400040182100E3382100001021CD -:105760008F65000000E3402B00C2302126040008B2 -:1057700000C830213084FFFFAF8500083C010800DD -:10578000AC2704443C010800AC2604400E0001E9AB -:10579000000000000A000519022020210E00013B34 -:1057A000000000008F82002024420001AF82002010 -:1057B0003C024000AF4201380A00029200000000A3 -:1057C0003084FFFF30C6FFFF00052C0000A628250F -:1057D0003882FFFF004510210045282B004510218D -:1057E00000021C023042FFFF0043102100021C0295 -:1057F0003042FFFF004310213842FFFF03E0000862 -:105800003042FFFF3084FFFF30A5FFFF000018216A -:1058100010800007000000003082000110400002EC -:1058200000042042006518210A0005A10005284057 -:1058300003E000080060102110C0000624C6FFFF2E -:105840008CA2000024A50004AC8200000A0005AB75 -:105850002484000403E000080000000010A00008F9 -:1058600024A3FFFFAC860000000000000000000041 -:105870002402FFFF2463FFFF1462FFFA2484000464 -:0858800003E000080000000035 -:04588800000000011B -:04588C000A00002AE4 -:1058900000000000000000000000000D7478703669 -:1058A0002E322E31610000000602010000000000CF -:1058B000000001360000EA60000000000000000067 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000016A2 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:10592000000000000000138800000000000005DCFB -:105930000000000000000000100000030000000054 -:105940000000000D0000000D3C02080024423D68EC -:105950003C0308002463401CAC4000000043202BA3 -:105960001480FFFD244200043C1D080037BD7FFC6D -:1059700003A0F0213C100800261000A83C1C0800E1 -:10598000279C3D680E00044E000000000000000D42 -:1059900027BDFFB4AFA10000AFA20004AFA3000871 -:1059A000AFA4000CAFA50010AFA60014AFA700185D -:1059B000AFA8001CAFA90020AFAA0024AFAB0028FD -:1059C000AFAC002CAFAD0030AFAE0034AFAF00389D -:1059D000AFB8003CAFB90040AFBC0044AFBF004817 -:1059E0000E000591000000008FBF00488FBC0044EE -:1059F0008FB900408FB8003C8FAF00388FAE0034B5 -:105A00008FAD00308FAC002C8FAB00288FAA002404 -:105A10008FA900208FA8001C8FA700188FA6001444 -:105A20008FA500108FA4000C8FA300088FA2000484 -:105A30008FA1000027BD004C3C1B60048F7A5030C2 -:105A4000377B502803400008AF7A00008F86003C67 -:105A50003C0390003C0280000086282500A32025FE -:105A6000AC4400203C0380008C67002004E0FFFE73 -:105A70000000000003E00008000000000A000070C1 -:105A8000240400018F85003C3C0480003483000125 -:105A900000A3102503E00008AC82002003E000080A -:105AA000000010213084FFFF30A5FFFF10800007A9 -:105AB0000000182130820001104000020004204242 -:105AC000006518211480FFFB0005284003E0000852 -:105AD0000060102110C00007000000008CA2000030 -:105AE00024C6FFFF24A50004AC82000014C0FFFB05 -:105AF0002484000403E000080000000010A0000857 -:105B000024A3FFFFAC86000000000000000000009E -:105B10002402FFFF2463FFFF1462FFFA24840004C1 -:105B200003E000080000000090AA00318FAB0010D5 -:105B30008CAC00403C0300FF8D680004AD6C00207D -:105B40008CAD004400E060213462FFFFAD6D0024A5 -:105B50008CA700483C09FF000109C024AD6700285C -:105B60008CAE004C0182C82403197825AD6F000467 -:105B7000AD6E002C8CAD0038314A00FFAD6D001CBD -:105B800094A900323128FFFFAD68001090A70030C3 -:105B9000A5600002A1600004A167000090A300328C -:105BA000306200FF00021982106000052405000128 -:105BB0001065000E0000000003E00008A16A00016B -:105BC0008CD80028354A0080AD7800188CCF00149E -:105BD000AD6F00148CCE0030AD6E00088CC4002C6C -:105BE000A16A000103E00008AD64000C8CCD001C2C -:105BF000AD6D00188CC90014AD6900148CC8002468 -:105C0000AD6800088CC70020AD67000C8CC2001482 -:105C10008C8300700043C82B132000070000000095 -:105C20008CC20014144CFFE400000000354A0080D0 -:105C300003E00008A16A00018C8200700A0000E6FF -:105C4000000000009089003027BDFFF88FA8001CDD -:105C5000A3A900008FA300003C0DFF8035A2FFFF29 -:105C60008CAC002C00625824AFAB0000A1000004F3 -:105C700000C05821A7A000028D06000400A0482102 -:105C80000167C8218FA50000008050213C18FF7FCC -:105C9000032C20263C0E00FF2C8C0001370FFFFF49 -:105CA00035CDFFFF3C02FF0000AFC82400EDC0244B -:105CB00000C27824000C1DC00323682501F870255C -:105CC000AD0D0000AD0E00048D240024AFAD00002A -:105CD000AD0400088D2C00202404FFFFAD0C000C47 -:105CE0009547003230E6FFFFAD06001091450048B1 -:105CF00030A200FF000219C2506000018D24003460 -:105D0000AD0400148D4700388FAA001827BD000885 -:105D1000AD0B0028AD0A0024AD07001CAD00002C1F -:105D2000AD00001803E00008AD00002027BDFFE033 -:105D3000AFB20018AFB10014AFB00010AFBF001C7D -:105D40009098003000C088213C0D00FF330F007F89 -:105D5000A0CF0000908E003135ACFFFF3C0AFF0061 -:105D6000A0CE000194A6001EA22000048CAB00145B -:105D70008E29000400A08021016C2824012A4024DF -:105D80000080902101052025A6260002AE240004F3 -:105D900026050020262400080E000092240600029A -:105DA00092470030260500282624001400071E0014 -:105DB0000003160324060004044000032403FFFF2D -:105DC000965900323323FFFF0E000092AE230010DD -:105DD000262400248FBF001C8FB200188FB100143E -:105DE0008FB0001024050003000030210A00009C41 -:105DF00027BD002027BDFFD8AFB1001CAFB00018F1 -:105E0000AFBF002090A900302402000100E0502123 -:105E10003123003F00A040218FB000400080882146 -:105E200000C04821106200148FA70038240B000521 -:105E300000A0202100C02821106B00130200302197 -:105E40000E000128000000009225007C30A4000212 -:105E50001080000326030030AE000030260300341B -:105E60008FBF00208FB1001C8FB000180060102180 -:105E700003E0000827BD00280E0000A7AFB0001007 -:105E80000A00016F000000008FA3003C01002021E8 -:105E90000120282101403021AFA300100E0000EEA8 -:105EA000AFB000140A00016F000000003C06800043 -:105EB00034C20E008C4400108F850044ACA4002036 -:105EC0008C43001803E00008ACA300243C068000CB -:105ED00034C20E008C4400148F850044ACA4002012 -:105EE0008C43001C03E00008ACA300249382000C48 -:105EF0001040001B2483000F2404FFF000643824AA -:105F000010E00019978B00109784000E9389000D04 -:105F10003C0A601C0A0001AC0164402301037021AB -:105F2000006428231126000231C2FFFF30A2FFFFC8 -:105F30000047302B50C0000E00E448218D4D000C6E -:105F400031A3FFFF00036400000C2C0304A1FFF346 -:105F50000000302130637FFF0A0001A42406000105 -:105F600003E00008000000009784000E00E44821D0 -:105F70003123FFFF3168FFFF0068382B54E0FFF842 -:105F8000A783000E938A000D11400005240F000125 -:105F9000006BC023A380000D03E00008A798000E4B -:105FA000006BC023A38F000D03E00008A798000E2C -:105FB00003E000080000000027BDFFE8AFB00010BC -:105FC0003C10800036030140308BFFFF93AA002B6A -:105FD000AFBF0014A46B000436040E0094880016B2 -:105FE00030C600FF8FA90030A4680006AC65000829 -:105FF000A0660012A46A001AAC6700208FA5002CCE -:10600000A4690018012020210E000198AC6500143D -:106010003C021000AE0201788FBF00148FB0001058 -:1060200003E0000827BD00188F85000024840007C6 -:1060300027BDFFF83084FFF83C06800094CB008A2F -:10604000316AFFFFAFAA00008FA90000012540239D -:106050002507FFFF30E31FFF0064102B1440FFF7FC -:1060600000056882000D288034CC400000AC10216F -:1060700003E0000827BD00088F8200002486000787 -:1060800030C5FFF800A2182130641FFF03E00008AC -:10609000AF8400008F87003C8F84004427BDFFB091 -:1060A000AFB70044AFB40038AFB1002CAFBF004869 -:1060B000AFB60040AFB5003CAFB30034AFB2003074 -:1060C000AFB000283C0B80008C860024AD670080B8 -:1060D0008C8A002035670E0035690100ACEA00109B -:1060E0008C8800248D2500040000B821ACE800183D -:1060F0008CE3001000A688230000A021ACE300146C -:106100008CE20018ACE2001C122000FE00E0B0217E -:10611000936C0008118000F400000000976F0010DD -:1061200031EEFFFF022E682B15A000EF00000000EB -:10613000977200103250FFFFAED000003C03800089 -:106140008C740000329300081260FFFD0000000014 -:1061500096D800088EC700043305FFFF30B5000154 -:1061600012A000E4000000000000000D30BFA040BD -:106170002419004013F9011B30B4A000128000DF85 -:106180000000000093730008126000080000000087 -:10619000976D001031ACFFFF00EC202B1080000346 -:1061A00030AE004011C000D500000000A7850040BF -:1061B000AF8700389363000802202821AFB1002088 -:1061C000146000F527B40020AF60000C978F0040EA -:1061D00031F1400016200002240300162403000EB3 -:1061E00024054007A363000AAF650014938A0042A8 -:1061F0008F7000143155000100151240020248252D -:10620000AF690014979F00408F78001433F9001095 -:1062100003194025AF6800149792004032470008E8 -:1062200010E0016E000000008F6700143C121000A7 -:106230003C11800000F27825AF6F001436230E0069 -:10624000946E000A3C0D81002406000E31CCFFFF45 -:10625000018D2025AF640004A36600029373000A39 -:106260003406FFFC266B0004A36B000A97980040DD -:10627000330820001100015F000000003C05800091 -:1062800034A90E00979900409538000C978700407C -:10629000001940423312C0003103000300127B0397 -:1062A00030F11000006F68250011720301AE602507 -:1062B000000C20C0A764001297930040936A000A64 -:1062C000001359823175003C02AA10212450003C71 -:1062D000A3700009953F000C33F93FFFA779001028 -:1062E00097700012936900090130F82127E5000238 -:1062F00030B900070019C02333080007A368000B5A -:106300009371000997720012976F0010322700FFF7 -:106310008F910038978D004000F21821006F702196 -:1063200001C6602131A6004010C000053185FFFF85 -:1063300000B1102B3C128000104000170000982183 -:106340000225A82B56A0013E8FA500203C0480000A -:10635000348A0E008D5300143C068000AD530010AB -:106360008D4B001CAD4B0018AD4500008CCD0000DE -:1063700031AC00081180FFFD34CE0E0095C300083B -:1063800000A0882100009021A78300408DC6000452 -:1063900024130001AF860038976F001031F5FFFF1E -:1063A0008E9F000003F1282310A0011FAE8500007E -:1063B00093620008144000DD000000000E0001E7B9 -:1063C000240400108F900048004028213C02320035 -:1063D000320600FF000654000142F825260900019C -:1063E000AF890048ACBF000093790009977800128C -:1063F000936F000A332800FF3303FFFF01033821A6 -:1064000000076C0031EE00FF01AE6025ACAC00046B -:106410008F840048978B0040316A20001140010AA8 -:10642000ACA4000897640012308BFFFF06400108FF -:10643000ACAB000C978E004031C5000814A00002E0 -:1064400026280006262800023C1F800037E70E00A1 -:1064500094F900148CE5001C8F6700049378000207 -:106460003324FFFF330300FFAFA300108F6F00142E -:10647000AFA800180E0001CBAFAF00142404001029 -:106480000E0001FB000000008E9200001640000587 -:10649000000000008F7800142403FFBF0303A02432 -:1064A000AF7400148F67000C00F5C821AF79000CA1 -:1064B0009375000816A00008000000001260000696 -:1064C000000000008F6800143C0AEFFF3549FFFE12 -:1064D0000109F824AF7F0014A37300088FA50020E2 -:1064E0000A00034F02202021AED100000A00022D35 -:1064F0003C03800014E0FF1E30BFA0400E0001905E -:106500000000A0212E9100010237B02512C0001812 -:106510008FBF00488F87003C24170F0010F700D46E -:106520003C0680008CD901780720FFFE241F0F0055 -:1065300010FF00F634CA0E008D56001434C7014017 -:1065400024080240ACF600048D49001C3C141000E5 -:10655000ACE90008A0E00012A4E0001AACE00020C2 -:10656000A4E00018ACE80014ACD401788FBF004858 -:106570008FB700448FB600408FB5003C8FB4003811 -:106580008FB300348FB200308FB1002C8FB0002851 -:1065900003E0000827BD00508F9100389788004025 -:1065A0003C1280000220A8213107004014E0FF7C4B -:1065B00000009821977900108F9200383338FFFF40 -:1065C000131200A8000020210080A021108000F3F9 -:1065D00000A088211620FECE000000000A00031F44 -:1065E0002E9100013C0380008C6201780440FFFE84 -:1065F000240808008F860000AC6801783C03800006 -:10660000946D008A31ACFFFF01865823256AFFFF95 -:1066100031441FFF2C8900081520FFF900000000FD -:106620008F8F0048347040008F83003C00E0A02131 -:10663000240E0F0025E70001AF87004800D030216D -:10664000023488233C08800031F500FF106E0005FD -:106650002407000193980042331300010013924075 -:1066600036470001001524003C0A0100008A482535 -:10667000ACC900008F82004830BF003630B9000836 -:10668000ACC200041320009900FF982535120E00BB -:106690009650000A8F8700003C0F81003203FFFFF5 -:1066A00024ED000835060140006F60253C0E100007 -:1066B00031AB1FFF269200062405000EACCC002053 -:1066C000026E9825A4C5001AAF8B0000A4D2001852 -:1066D000162000083C1080008F89003C24020F0027 -:1066E0005122000224170001367300400E00018879 -:1066F0003C10800036060E008CCB0014360A014098 -:1067000002402021AD4B00048CC5001CAD450008A3 -:10671000A1550012AD5300140E0001983C15100055 -:10672000AE1501780A00035200000000936F0009C3 -:10673000976E0012936D000B31E500FF00AE202133 -:1067400031AC00FF008C80212602000A3050FFFF90 -:106750000E0001E7020020218F8600483C03410023 -:106760003C05800024CB0001AF8B0048936A0009F0 -:106770009769001230C600FF315F00FF3128FFFF2C -:1067800003E8382124F900020006C4000319782523 -:1067900001E37025AC4E00008F6D000C34A40E0098 -:1067A000948B001401B26025AC4C00048C85001C55 -:1067B0008F670004936A00023164FFFF314900FFD4 -:1067C000AFA900108F680014AFB100180E0001CB04 -:1067D000AFA800140A0002FD02002021AF600004EF -:1067E000A360000297980040330820001500FEA324 -:1067F00000003021A760001297840040936B000ACC -:106800003C10800030931F0000135183014BA821DE -:1068100026A20028A362000936090E00953F000C4D -:106820000A000295A77F00108F70001436090040FF -:106830000E000188AF6900140A0002C900000000C0 -:106840000A00034F000020210641FEFAACA0000C14 -:106850008CAC000C3C0D8000018D90250A0002EAF2 -:10686000ACB2000C000090210A0002C52413000104 -:10687000128000073C028000344B0E009566000831 -:1068800030D3004012600049000000003C06800048 -:106890008CD001780600FFFE34C50E0094B50010C0 -:1068A0003C03050034CC014032B8FFFF03039025C0 -:1068B000AD92000C8CAF0014240D20003C0410009D -:1068C000AD8F00048CAE001CAD8E0008A1800012BC -:1068D000A580001AAD800020A5800018AD8D0014A1 -:1068E000ACC401780A0003263C0680008F9F00009C -:1068F000351801402692000227F9000833281FFFAF -:10690000A71200180A000391AF8800003C02800023 -:1069100034450140ACA0000C1280001B34530E0023 -:1069200034510E008E370010ACB700048E240018CE -:106930003C0B8000ACA400083570014024040040EA -:10694000A20000128FBF0048A600001A8FB70044B3 -:10695000AE0000208FB60040A60000188FB5003CA6 -:10696000AE0400148FB400388FB300348FB20030FF -:106970008FB1002C8FB000283C02100027BD0050C2 -:1069800003E00008AD6201788E660014ACA6000436 -:106990008E64001C0A00042A3C0B80000E0001904B -:1069A0002E9100010A0003200237B02500000000EC -:1069B0000000000D00000000240003690A0004012B -:1069C0003C06800027BDFFD8AFBF00203C098000F7 -:1069D0003C1F20FFAFB200183C07600035320E00AC -:1069E0002402001037F9FFFDACE23008AFB3001C01 -:1069F000AFB10014AFB00010AE59000000000000AD -:106A00000000000000000000000000000000000086 -:106A10003C1800FF3713FFFDAE5300003C0B600431 -:106A20008D7050002411FF7F3C0E0002021178246B -:106A300035EC380C35CD0109ACED4C18240A0009B1 -:106A4000AD6C50008CE80438AD2A0008AD2000146D -:106A50008CE54C1C3106FFFF38C42F7100051E0267 -:106A60003062000F2486C0B310400007AF820008D8 -:106A70008CE54C1C3C09001F3528FC0000A818249C -:106A8000000321C2AF8400048CF108083C0F5709B1 -:106A90002412F0000232702435F0001001D060267C -:106AA00001CF68262DAA00012D8B0001014B38254E -:106AB00050E00009A380000C3C1F601C8FF8000808 -:106AC00024190001A399000C33137C00A793001034 -:106AD000A780000EA380000DAF80004814C0000303 -:106AE000AF8000003C066000ACC0442C0E0005B92D -:106AF0003C1080000E000F1A361101003C120800F5 -:106B000026523DD03C13080026733E508E030000F1 -:106B100038640001308200011440FFFC3C0B800A05 -:106B20008E2600002407FF8024C90240312A007FFE -:106B3000014B402101272824AE060020AF880044E5 -:106B4000AE0500243C048000AF86003C8C8C0178AC -:106B50000580FFFE24180800922F0008AC980178E9 -:106B6000A38F0042938E004231CD000111A0000F8F -:106B700024050D0024DFF8002FF903011320001C69 -:106B8000000629C224A4FFF0000410420002314094 -:106B90000E00020200D2D8213C0240003C068000D8 -:106BA000ACC201380A0004A00000000010C5002398 -:106BB000240D0F0010CD00273C1F800837F90080FE -:106BC00093380000240E0050330F00FF15EEFFF342 -:106BD0003C0240000E000A36000000003C0240006B -:106BE0003C068000ACC201380A0004A0000000008E -:106BF0008F83000400A3402B1500000B8F8B00082F -:106C0000006B50212547FFFF00E5482B15200006AB -:106C100000A36023000C19400E0002020073D8216B -:106C20000A0004C43C0240000000000D0E000202F5 -:106C3000000000000A0004C43C0240003C1B0800A5 -:106C4000277B3F500E000202000000000A0004C42F -:106C50003C0240003C1B0800277B3F700E000202F4 -:106C6000000000000A0004C43C0240003C0660042E -:106C70003C09080025290104ACC9502C8CC85000DF -:106C80003C0580003C02000235070080ACC7500084 -:106C90003C040800248415A43C0308002463155C0C -:106CA000ACA50008ACA2000C3C010800AC243D607F -:106CB0003C010800AC233D6403E00008240200010D -:106CC00000A030213C1C0800279C3D683C0C0400BF -:106CD0003C0B0002008B3826008C40262CE2000181 -:106CE0000007502B2D050001000A48803C030800D6 -:106CF00024633D60004520250123182110800003F6 -:106D000000001021AC6600002402000103E000082E -:106D1000000000003C1C0800279C3D683C0B040060 -:106D20003C0A0002008A3026008B38262CC2000163 -:106D30000006482B2CE50001000940803C030800B8 -:106D400024633D60004520250103182110800005C3 -:106D5000000010213C0C0800258C155CAC6C000078 -:106D60002402000103E00008000000003C090002CA -:106D70003C08040000883026008938262CC3000116 -:106D8000008028212CE40001008310251040000B16 -:106D9000000030213C1C0800279C3D683C0A800014 -:106DA0008D4E00082406000101CA6825AD4D00087B -:106DB0008D4C000C01855825AD4B000C03E00008FC -:106DC00000C010213C1C0800279C3D683C05800049 -:106DD0008CA6000C000420272402000100C4182403 -:106DE00003E00008ACA3000C3C0200021082000B80 -:106DF0003C0560003C070400108700030000000011 -:106E000003E00008000000008CA908D0240AFFFD60 -:106E1000012A402403E00008ACA808D08CA408D0C4 -:106E20002406FFFE0086182403E00008ACA308D067 -:106E30003C05601A34A600108CC3008027BDFFF803 -:106E40008CC50084AFA3000093A4000024020001BD -:106E500010820003AFA5000403E0000827BD00086E -:106E600093A7000114E0001497AC000297B8000249 -:106E70003C0F8000330EFFFC01CF6821ADA5000060 -:106E8000A3A000003C0660008CC708D02408FFFEC9 -:106E90003C04601A00E82824ACC508D08FA3000485 -:106EA0008FA200003499001027BD0008AF22008097 -:106EB00003E00008AF2300843C0B8000318AFFFC14 -:106EC000014B48218D2800000A00057DAFA8000471 -:106ED00027BDFFE8AFBF00103C1C0800279C3D68A1 -:106EE0003C0580008CA4000C8CA200043C03000232 -:106EF0000044282410A0000A00A318243C06040023 -:106F00003C0400021460000900A610241440000F85 -:106F10003C0404000000000D3C1C0800279C3D6858 -:106F20008FBF001003E0000827BD00183C020800D6 -:106F30008C423D600040F809000000003C1C080045 -:106F4000279C3D680A0005A68FBF00103C02080080 -:106F50008C423D640040F809000000000A0005ACC6 -:106F600000000000000411C003E0000824420240B9 -:106F70003C04080024843FB42405001A0A00009C45 -:106F80000000302127BDFFE0AFB000103C108000B2 -:106F9000AFBF0018AFB100143611010092220009F2 -:106FA0000E0005B63044007F8E3F00008F89003C04 -:106FB0003C0F008003E26021258800400049F82151 -:106FC000240DFF80310E00783198007835F90001EA -:106FD00035F100020319382501D14825010D30246F -:106FE00003ED5824018D2824240A00402404008045 -:106FF000240300C0AE0B0024AE000810AE0A081433 -:10700000AE040818AE03081CAE050804AE0708203D -:10701000AE060808AE090824360909009539000CA7 -:107020003605098033ED007F3338FFFF001889C033 -:10703000AE110800AE0F0828952C000C8FBF001869 -:107040008FB10014318BFFFF000B51C0AE0A002C32 -:107050008CA400508FB000108CA3003C8D2700043E -:107060008CA8001C8CA600383C0E800A01AE1021B2 -:1070700027BD0020AF820044AF840050AF8300548E -:10708000AF87004CAF88005C03E00008AF8600606B -:107090003C09080091293FD924A800023C051100B1 -:1070A00000093C0000E8302500C5182524820008AE -:1070B000AC83000003E00008AC8000043C098000C1 -:1070C000352309009128010B906A00112402002841 -:1070D00000804821314700FF00A0702100C06821D6 -:1070E0003108004010E20002340C86DD240C080058 -:1070F0003C0A800035420A9A94470000354B0A9CAE -:1071000035460AA030F9FFFFAD3900008D78000048 -:10711000354B0A8024040001AD3800048CCF0000F8 -:10712000AD2F00089165001930A300031064009092 -:1071300028640002148000AF240500021065009E40 -:10714000240F0003106F00B435450AA4240A080078 -:10715000118A0048000000005100003D3C0B8000F7 -:107160003C048000348309009067001230E200FF85 -:10717000004D7821000FC880272400013C0A8000C0 -:10718000354F090091E50019354C09808D8700289D -:1071900030A300FF00031500004758250004C40079 -:1071A0003C19600001793025370806FFAD26000044 -:1071B000AD2800048DEA002C25280028AD2A0008FF -:1071C0008DEC0030AD2C000C8DE50034AD250010A9 -:1071D0008DE400383C05800034AC093CAD2400143B -:1071E0008DE3001CAD2300188DE70020AD27001CA7 -:1071F0008DE20024AD2200208DF9002834A2010088 -:10720000AD3900248D830000AD0E000434B90900AF -:10721000AD0300008C47000C25020014AD070008E8 -:10722000932B00123C04080090843FD8AD0000105E -:10723000317800FF030D302100064F0000047C0070 -:10724000012F702535CDFFFC03E00008AD0D000CCB -:1072500035780900930600123C05080094A53FC844 -:1072600030C800FF010D5021000A60800A00063C72 -:10727000018520211500005B000000003C0808008B -:1072800095083FCE3C06080094C63FC80106102171 -:107290003C0B80003579090093380011932A0019BE -:1072A00035660A80330800FF94CF002A0008608208 -:1072B000314500FF978A0058000C1E00000524008D -:1072C0003047FFFF006410250047C02501EA302148 -:1072D0003C0B4000030B402500066400AD28000075 -:1072E000AD2C0004932500183C030006252800144B -:1072F00000053E0000E31025AD2200088F24002C7D -:107300003C05800034AC093CAD24000C8F38001CD7 -:1073100034A20100254F0001AD3800108D8300001C -:10732000AD0E000431EB7FFFAD0300008C47000C75 -:1073300034B90900A78B0058AD070008932B001241 -:107340003C04080090843FD825020014317800FFE7 -:10735000030D302100064F0000047C00012F702532 -:1073600035CDFFFCAD00001003E00008AD0D000CB2 -:107370003C02080094423FD23C05080094A53FC857 -:1073800035440AA43C07080094E73FC4948B0000EE -:107390000045C8210327C023000B1C002706FFF26D -:1073A00000665025AD2A000CAD200010AD2C001455 -:1073B0000A00063025290018354F0AA495E500007B -:1073C000956400280005140000043C003459810035 -:1073D00000EC5825AD39000CAD2B00100A0006302A -:1073E000252900143C0C0800958C3FCE0A0006812C -:1073F000258200015460FF56240A080035580AA46B -:107400009706000000061C00006C5025AD2A000CF9 -:107410000A000630252900103C03080094633FD27F -:107420003C07080094E73FC83C0F080095EF3FC4B5 -:1074300094A400009579002800671021004F58237C -:1074400000041C00001934002578FFEE00D87825D0 -:10745000346A8100AD2A000CAD2F0010AD2000145D -:10746000AD2C00180A0006302529001C03E0000896 -:10747000240207D027BDFFE0AFB20018AFB100145F -:10748000AFB00010AFBF001C0E00007C0080882150 -:107490008F8800548F87004C3C05800834B20080F0 -:1074A000011128213C10800024020080240300C028 -:1074B00000A72023AE0208183C068008AE03081C73 -:1074C00018800004AF850054ACC500048CC90004CA -:1074D000AF89004C12200009360409800E0006F81E -:1074E00000000000924C00278E0B007401825004B3 -:1074F000014B3021AE46000C360409808C8E001CF6 -:107500008F8F005C01CF682319A000048FBF001C7F -:107510008C90001CAF90005C8FBF001C8FB20018D5 -:107520008FB100148FB000100A00007E27BD00202C -:107530008F8600508F8300548F82004C3C0580085A -:1075400034A40080AC860050AC83003C03E000080B -:10755000ACA200043C0308008C63005427BDFFF874 -:10756000308400FF2462000130A500FF3C010800C8 -:10757000AC22005430C600FF3C0780008CE8017844 -:107580000500FFFE3C0C7FFFA3A400038FAA0000B0 -:10759000358BFFFF014B4824000627C001244025FE -:1075A000AFA8000034E201009043000AA3A000024B -:1075B0003C1980FFA3A300018FAF000030AE007F15 -:1075C0003738FFFF01F86024000E6E003C0A0020EF -:1075D00034E50140018D5825354920002406FF80FF -:1075E0003C04100027BD0008ACAB000CACA9001493 -:1075F000A4A00018A0A6001203E00008ACE40178E3 -:10760000308800FF30A700FF3C0380008C620178C7 -:107610000440FFFE3C0C8000358A0A008D4B0020A0 -:107620003584014035850980AC8B00048D490024E8 -:107630000007302B00061540AC890008A088001018 -:1076400090A3004CA083002D03E00008A480001844 -:1076500027BDFFE8308400FFAFBF00100E00075DBC -:1076600030A500FF8F8300548FBF00103C068000C0 -:1076700034C50140344700402404FF903C02100010 -:1076800027BD0018ACA3000CA0A40012ACA70014E6 -:1076900003E00008ACC2017827BDFFE03C08800889 -:1076A000AFBF001CAFB20018AFB10014AFB00010F4 -:1076B000351000808E0600183C078000309200FFD5 -:1076C00000C72025AE0400180E00007C30B100FF7A -:1076D00092030005346200080E00007EA20200053D -:1076E000024020210E0007710220282102402021A3 -:1076F0008FBF001C8FB200188FB100148FB0001024 -:1077000024050005240600010A00073227BD0020D9 -:107710003C05800034A309809066000830C2000850 -:107720001040000F3C0A01013549080AAC890000ED -:107730008CA80074AC8800043C07080090E73FD890 -:1077400030E5001050A00008AC8000083C0D800817 -:1077500035AC00808D8B0058AC8B00082484000C65 -:1077600003E00008008010210A0007B52484000C03 -:1077700027BDFFE83C098000AFB00010AFBF001488 -:107780003526098090C800092402000600A058216F -:10779000310300FF35270900008080212405000403 -:1077A0001062007B2408000294CF005C3C0E0204AF -:1077B00031EDFFFF01AE6025AE0C000090CA00085D -:1077C00031440020108000080000000090C2004EEC -:1077D0003C1F010337F90300305800FF031930251F -:1077E00024050008AE06000490F9001190E600128E -:1077F00090E40011333800FF0018708230CF00FF92 -:1078000001CF5021014B6821308900FF31AAFFFFD1 -:1078100039230028000A60801460002C020C4823E1 -:1078200090E400123C198000372F0100308C00FFDB -:10783000018B1821000310800045F821001F8400EF -:10784000360706FFAD270004373F090093EC00110F -:1078500093EE0012372609800005C0828DE4000CEB -:107860008CC5003431CD00FF01AB10210058182128 -:1078700000A4F8230008840000033F0000F0302536 -:1078800033F9FFFF318F00FC00D97025015820210A -:1078900001E9682100045080ADAE000C0E00007CB0 -:1078A000012A80213C088008240B00043505008053 -:1078B0000E00007EA0AB0009020010218FBF001453 -:1078C0008FB0001003E0000827BD001890EC0011F5 -:1078D00090E300193C18080097183FCE318200FF52 -:1078E0000002F882307000FF001FCE0000103C0044 -:1078F0000327302500D870253C0F400001CF6825B4 -:107900003C198000AD2D0000373F090093EC0011B9 -:1079100093EE0012372F0100372609800005C08240 -:107920008DE4000C8CC5003431CD00FF01AB10217B -:107930000058182100A4F8230008840000033F0029 -:1079400000F0302533F9FFFF318F00FC00D970259E -:107950000158202101E9682100045080ADAE000CDF -:107960000E00007C012A80213C088008240B0004C2 -:10797000350500800E00007EA0AB0009020010213A -:107980008FBF00148FB0001003E0000827BD00185F -:107990000A0007C72408001227BDFFD03C0380005F -:1079A000AFB60028AFB50024AFB40020AFB10014CB -:1079B000AFBF002CAFB3001CAFB20018AFB00010C7 -:1079C0003467010090E6000B309400FF30B500FFF3 -:1079D00030C200300000B021104000990000882122 -:1079E000346409809088000800082E0000051E03FA -:1079F000046000C0240400048F8600543C01080089 -:107A0000A0243FD83C0C8000AD8000483C0480009E -:107A1000348E010091CD000B31A5002010A000078D -:107A20003C0780003493098092720008001286009F -:107A300000107E0305E000C43C1F800834EC010008 -:107A4000918A000B34EB09809169000831440040B1 -:107A50000004402B3123000800C898231460000262 -:107A600024120003000090213C10800036180A8088 -:107A700036040900970E002C9083001190890012A3 -:107A800093050018307F00FF312800FF02481021C5 -:107A90000002C880930D0018033F782101F13021C6 -:107AA00030B100FF00D11821A78E00583C0108001A -:107AB000A4263FCE3C010800A4233FD015A000021D -:107AC000000000000000000D920B010B3065FFFF6D -:107AD0003C010800A4233FD2316A00403C01080069 -:107AE000A4203FC83C010800A4203FC4114000026C -:107AF00024A4000A24A4000B3091FFFF0E0001E72C -:107B0000022020219206010B3C0C0800958C3FD2EC -:107B1000004020210006698231A700010E00060105 -:107B20000187282100402021026028210E00060C38 -:107B3000024030210E0007A10040202116C000693C -:107B4000004020219212010B3256004012C0000565 -:107B50003C0500FF8C93000034AEFFFF026E8024D2 -:107B6000AC9000000E0001FB022020213C0F080019 -:107B700091EF3FD831F10003122000163C1380082A -:107B80008F8200543C09800835280080245F000162 -:107B9000AD1F003C3C0580088CB9000403E02021A7 -:107BA000033FC0231B000002AF9F00548CA40004BD -:107BB0000E0006F8ACA400043C0780008CEB0074B7 -:107BC0003C04800834830080004B5021AC6A000CD8 -:107BD0003C138008367000800280202102A02821FA -:107BE000A200006B0E00075D3C1480008F920054D1 -:107BF000368C0140AD92000C8F8600483C15100079 -:107C0000344D000624D60001AF9600488FBF002CEB -:107C1000A18600128FB60028AD8D00148FB3001C12 -:107C2000AE9501788FB200188FB500248FB4002074 -:107C30008FB100148FB0001003E0000827BD0030A2 -:107C400034640980908F0008000F7600000E6E03E8 -:107C500005A00033347F090093F8001B241900109D -:107C60003C010800A0393FD8331300021260FF67BF -:107C70008F8600548F8200601446FF653C048000AC -:107C80000E00007C000000003C0480083485008069 -:107C900090A8000924060016310300FF1066000DAD -:107CA0000000000090AB00093C07080090E73FD8B7 -:107CB00024090008316400FF34EA00013C01080097 -:107CC000A02A3FD81089002F240C000A108C00280D -:107CD0002402000C0E00007E000000000A00086074 -:107CE0008F8600540E0007B9024028210A0008AE12 -:107CF000004020213C0B8008356A00808D460054EE -:107D00008CE9000C1120FF3DAF86005424070014BD -:107D10003C010800A0273FD80A00085F3C0C800007 -:107D200090910008241200023C010800A0323FD8C4 -:107D3000323000201200000B241600018F86005400 -:107D40000A0008602411000837F800808F0200380C -:107D5000AFE200048FF90004AF19003C0A00086C80 -:107D60003C0780008F8600540A000860241100043C -:107D7000A0A200090E00007E000000000A000860BA -:107D80008F860054240200140A00093AA0A20009B8 -:107D900027BDFFE8AFB000103C108000AFBF00145B -:107DA00036020100904400090E00075D2405000121 -:107DB0003C0480089099000E34830080909F000F4F -:107DC000906F00269089000A33F800FF00196E00BA -:107DD0000018740031EC00FF01AE5025000C5A0071 -:107DE000014B3825312800FF36030140344560003F -:107DF00000E830252402FF813C041000AC66000C32 -:107E00008FBF0014AC650014A0620012AE040178AC -:107E10008FB0001003E0000827BD001827BDFFE861 -:107E2000308400FFAFBF00100E00075D30A500FFDB -:107E30003C05800034A40140344700402406FF92F2 -:107E4000AC870014A08600128F8300548FBF0010EF -:107E50003C02100027BD0018AC83000C03E00008B2 -:107E6000ACA2017827BDFFD8AFB00010308400FF6E -:107E700030B000FF3C058000AFB10014AFBF002060 -:107E8000AFB3001CAFB20018000410C234A601004A -:107E900032030002305100011460000790D2000943 -:107EA0003C098008353300809268000531070008DE -:107EB00010E0000C308A0010024020210E000783E1 -:107EC00002202821240200018FBF00208FB3001C54 -:107ED0008FB200188FB100148FB0001003E00008BB -:107EE00027BD00281540003434A50A008CB80024B2 -:107EF0008CAF0008130F004B000038213C0D8008A8 -:107F000035B30080926C006824060002318B00FFBC -:107F1000116600843C06800034C201009263004C6C -:107F200090590009307F00FF53F900043213007CA0 -:107F300010E00069000000003213007C5660005C15 -:107F40000240202116200009320D00013C0C800067 -:107F500035840100358B0A008D6500248C86000471 -:107F600014A6FFD900001021320D000111A0000E4F -:107F7000024020213C188000371001008E0F000CB9 -:107F80008F8E005011EE0008000000000E00084324 -:107F9000022028218E19000C3C1F800837F0008039 -:107FA000AE190050024020210E0007710220282146 -:107FB0000A00098F240200013C0508008CA500641A -:107FC00024A400013C010800AC2400641600000D4C -:107FD00000000000022028210E000771024020212D -:107FE000926E0068240C000231CD00FF11AC00221B -:107FF000024020210E000941000000000A00098F04 -:10800000240200010E00007024040001926B002580 -:10801000020B30250E00007EA26600250A0009D35F -:10802000022028218E6200188CDF00048CB9002405 -:1080300000021E0217F9FFB13065007F9268004C04 -:10804000264400013093007F12650040310300FF99 -:108050001464FFAB3C0D80082647000130F1007F1F -:1080600030E200FF1225000B2407000100409021A0 -:108070000A00099C24110001240500040E000732A7 -:10808000240600010E000941000000000A00098FCB -:10809000240200012405FF8002452024008590264B -:1080A000324200FF004090210A00099C2411000187 -:1080B0000E000843022028213207003010E0FFA103 -:1080C00032100082024020210E0007830220282166 -:1080D0000A00098F240200018E6900180240202145 -:1080E00002202821012640250E000964AE680018F0 -:1080F0009264004C24050003240600010E000732A0 -:10810000308400FF0E0000702404000192710025ED -:10811000021150250E00007EA26A00250A00098F78 -:10812000240200018E6F00183C18800002402021BC -:1081300001F87025022028210E000771AE6E00188C -:108140009264004C0A000A1B24050004324A008095 -:10815000394900801469FF6A3C0D80080A0009F45F -:108160002647000127BDFFC0AFB000183C108000BB -:10817000AFBF0038AFB70034AFB60030AFB5002C9A -:10818000AFB40028AFB30024AFB200200E0005BE8C -:10819000AFB1001C360201009045000B0E000976BD -:1081A00090440008144000E78FBF00383C08800866 -:1081B00035070080A0E0006B3606098090C50000FE -:1081C000240300503C17080026F73F9030A400FF1E -:1081D0003C13080026733FA0108300033C1080006E -:1081E0000000B82100009821241F00103611010062 -:1081F00036120A00361509808E5800248E34000489 -:108200008EAF00208F8C00543C010800A03F3FD867 -:1082100036190A80972B002C8EF60000932A00183E -:108220000298702301EC68233C010800AC2E3FB497 -:108230003C010800AC2D3FB83C010800AC2C3FDCF1 -:10824000A78B005802C0F809315400FF30490002E2 -:10825000152000E930420001504000C49227000977 -:1082600092A9000831280008150000022415000317 -:108270000000A8213C0A80003543090035440A006B -:108280008C8D00249072001190700012907F00116C -:10829000325900FF321100FF02B110210002C080EC -:1082A00033EF00FF0319B021028F702102D4602147 -:1082B00025CB00103C010800A4363FCE3C0108004D -:1082C000AC2D3FE03C010800A42C3FD03C0108004D -:1082D000A42B3FCC355601003554098035510E0092 -:1082E0008F8700548F89005C8E850020240800064B -:1082F000012730233C010800AC283FD400A72823E5 -:1083000004C000B50000902104A000B300C5502BAC -:10831000114000B5000000003C010800AC263FB849 -:108320008E6200000040F8090000000030460002A4 -:1083300014C0007400408021304B000155600011D2 -:108340008E6200043C0D08008DAD3FBC3C0EC000A9 -:108350003C04800001AE6025AE2C00008C9800002B -:10836000330F000811E0FFFD00000000963F0008F9 -:1083700024120001A79F00408E390004AF990038F5 -:108380008E6200040040F80900000000020280250F -:1083900032030002146000B3000000003C09080032 -:1083A00095293FC43C06080094C63FD03C0A08000B -:1083B000954A3FC63C0708008CE73FBC0126702168 -:1083C0003C0308008C633FE03C08080095083FDA56 -:1083D00001CA20218ED9000C00E92821249F000227 -:1083E00000A878210067C02133E4FFFFAF99005057 -:1083F0003C010800AC383FE03C010800A42F3FC816 -:108400003C010800A42E3FD20E0001E7000000004E -:108410008F8D0048004020213C010800A02D3FD94D -:108420008E62000825AC0001AF8C00480040F809BE -:10843000000000008F85005402A030210E00060CC1 -:10844000004020210E0007A1004020218E6B000C6F -:108450000160F809004020213C0A0800954A3FD2FB -:108460003C06080094C63FC6014648212528000264 -:108470000E0001FB3104FFFF3C0508008CA53FB452 -:108480003C0708008CE73FBC00A720233C01080004 -:10849000AC243FB414800006000000003C02080039 -:1084A0008C423FD4344B00403C010800AC2B3FD4FD -:1084B000124000438F8E00448E2D00108F92004496 -:1084C000AE4D00208E2C0018AE4C00243C04080059 -:1084D00094843FC80E0006FA000000008F9F0054ED -:1084E0008E6700103C010800AC3F3FDC00E0F8095B -:1084F000000000003C1908008F393FB41720FF79B5 -:108500008F870054979300583C11800E321601005B -:108510000E000729A633002C16C0004532030010B8 -:108520005460004C8EE50004320800405500001DE8 -:108530008EF000088EE4000C0080F80900000000B6 -:108540008FBF00388FB700348FB600308FB5002C46 -:108550008FB400288FB300248FB200208FB1001C8D -:108560008FB0001803E0000827BD00408F86003C54 -:1085700036110E0000072E0000A62025AE04008054 -:108580008E4300208E500024AFA30010AE230014B1 -:108590008FB20010AE320010AE30001C0A000A7517 -:1085A000AE3000180200F809000000008EE4000C54 -:1085B0000080F809000000000A000B2E8FBF003871 -:1085C00024180001240F0001A5C00020A5D8002216 -:1085D0000A000B10ADCF00243C010800AC203FB8CE -:1085E0000A000AA68E6200003C010800AC253FB8D4 -:1085F0000A000AA68E620000922400090E0007718C -:10860000000028218FBF00388FB700348FB60030AC -:108610008FB5002C8FB400288FB300248FB20020B8 -:108620008FB1001C8FB0001803E0000827BD004088 -:108630003C14800092950109000028210E00084397 -:1086400032A400FF320300105060FFB8320800402F -:108650008EE5000400A0F809000000000A000B28C5 -:10866000320800405240FFA8979300588E340014FF -:108670008F930044AE7400208E35001CAE7500242C -:108680000A000B1F979300588F820014000421806A -:1086900003E00008008210213C07800834E20080DB -:1086A0009043006900804021106000093C040100F3 -:1086B0003C0708008CE73FDC8F83003000E3202379 -:1086C000048000089389001C14E3000301002021AA -:1086D00003E00008008010213C04010003E00008D2 -:1086E000008010211120000B006738233C0D800012 -:1086F00035AC0980918B007C316A0002114000206A -:108700002409003400E9702B15C0FFF1010020217D -:1087100000E938232403FFFC00A3C82400E3C0249D -:1087200000F9782B15E0FFEA0308202130C400038C -:108730000004102314C0001430490003000030214D -:1087400000A9782101E6702100EE682B11A0FFE05E -:108750003C0401002D3800010006C82B010548210A -:108760000319382414E0FFDA2524FFFC2402FFFC5F -:1087700000A218240068202103E0000800801021D6 -:108780000A000B9E240900303C0C800035860980CD -:1087900090CB007C316A00041540FFE924060004F8 -:1087A0000A000BAD000030213C0308008C63005C24 -:1087B0008F82001827BDFFE0AFBF0018AFB10014D3 -:1087C00010620005AFB00010000329C024A402808D -:1087D000AF840014AF8300183C10800036020A00FA -:1087E00094450032361101000E000B7F30A43FFF8C -:1087F0008E240000241FFF803C1100800082C021D5 -:10880000031F60243309007F000CC9400329402561 -:10881000330E0078362F00033C0D1000010D50255B -:1088200001CF5825AE0C002836080980AE0C080C84 -:10883000AE0B082CAE0A0830910300693C06800C90 -:108840000126382110600006AF8700348D09003CF6 -:108850008D03006C0123382318E000820000000023 -:108860003C0B8008356A00803C108000A140006904 -:10887000360609808CC200383C06800034C50A00E8 -:1088800090A8003C310C00201180001AAF8200300B -:10889000240D00013C0E800035D10A00A38D001C80 -:1088A000AF8000248E2400248F850024240D00082E -:1088B000AF800020AF8000283C010800A42D3FC6F7 -:1088C0003C010800A4203FDA0E000B830000302199 -:1088D0009228003C8FBF00188FB100148FB0001099 -:1088E00000086142AF82002C27BD002003E0000891 -:1088F0003182000190B80032240E0001330F00FFD6 -:10890000000F2182108E004124190002109900648A -:1089100034C40AC03C03800034640A008C8F0024F5 -:1089200015E0001E34660900909F003024180005F1 -:1089300033F9003F1338004E240300018F860020D6 -:10894000A383001CAF860028AF8600243C0E800065 -:1089500035D10A008E2400248F850024240D0008C0 -:108960003C010800A42D3FC63C010800A4203FDACA -:108970000E000B83000000009228003C8FBF0018FF -:108980008FB100148FB0001000086142AF82002C3C -:1089900027BD002003E00008318200018C8A000816 -:1089A0008C8B00248CD000643C0E800035D10A00F2 -:1089B000014B2823AF900024A380001CAF85002822 -:1089C0008E2400248F8600208F850024240D00082B -:1089D0003C010800A42D3FC63C010800A4203FDA5A -:1089E0000E000B83000000009228003C8FBF00188F -:1089F0008FB100148FB0001000086142AF82002CCC -:108A000027BD002003E000083182000190A2003061 -:108A10003051003F5224002834C50AC08CB00024D5 -:108A20001600002234CB09008CA600483C0A7FFFC8 -:108A30003545FFFF00C510243C0E8000AF820020AA -:108A400035C509008F8800208CAD0060010D602BBA -:108A500015800002010020218CA400600A000C2275 -:108A6000AF8400208D02006C0A000BFC3C068000E5 -:108A70008C8200488F8600203C097FFF3527FFFF4E -:108A8000004788243C04800824030001AF9100289B -:108A9000AC80006CA383001C0A000C30AF8600245D -:108AA0008C9F00140A000C22AF9F00208D6200688A -:108AB0000A000C6C3C0E800034C409808C89007064 -:108AC0008CA300140123382B10E0000400000000E8 -:108AD0008C8200700A000C6C3C0E80008CA200148A -:108AE0000A000C6C3C0E80008F85002427BDFFE03F -:108AF000AFBF0018AFB1001414A00008AFB0001051 -:108B00003C04800034870A0090E60030240200050F -:108B100030C3003F106200B9348409008F910020F7 -:108B200000A080213C048000348E0A008DCD00041A -:108B30003C0608008CC63FB831A73FFF00E6602B1B -:108B40005580000100E03021938F001C11E0007877 -:108B500000D0282B349F098093F9007C3338000221 -:108B6000130000792403003400C3102B144000D9F3 -:108B70000000000000C3302300D0282B3C01080077 -:108B8000A4233FC414A0006E020018213C04080076 -:108B90008C843FB40064402B55000001006020210C -:108BA0003C05800034A90A00912A003C3C010800E1 -:108BB000AC243FBC31430020146000030000482176 -:108BC00034AB0E008D6900188F88002C0128202BF3 -:108BD0001080005F000000003C0508008CA53FBC31 -:108BE00000A96821010D602B1180005C00B0702B82 -:108BF0000109382300E028213C010800AC273FBCD4 -:108C000012000003240AFFFC10B0008D3224000380 -:108C100000AA18243C010800A4203FDA3C01080007 -:108C2000AC233FBC006028218F840024120400067E -:108C30003C0B80088D6C006C02002021AF9100205D -:108C400025900001AD70006C8F8D00280085882371 -:108C5000AF91002401A52023AF8400281220000238 -:108C600024070018240700103C18800837060080ED -:108C700090CF00683C010800A0273FD824070001DE -:108C800031EE00FF11C700470000000014800018FB -:108C9000000028213C06800034D1098034CD010039 -:108CA00091A600098E2C001824C40001000C860235 -:108CB0003205007F308B007F1165007F2407FF8025 -:108CC0003C19800837290080A124004C3C0808008A -:108CD0008D083FD4241800023C010800A038401938 -:108CE000350F00083C010800AC2F3FD424050010CC -:108CF0003C02800034440A009083003C307F002016 -:108D000013E0000500A02021240A00013C01080016 -:108D1000AC2A3FBC34A400018FBF00188FB10014EF -:108D20008FB000100080102103E0000827BD002054 -:108D30003C010800A4203FC410A0FF9402001821A9 -:108D40000A000CC000C018210A000CB72403003030 -:108D50003C0508008CA53FBC00B0702B11C0FFA8DB -:108D6000000000003C19080097393FC40325C021CA -:108D70000307782B11E000072CAA00043C036000D5 -:108D80008C625404305F003F17E0FFE3240400428C -:108D90002CAA00041140FF9A240400420A000D246A -:108DA0008FBF00181528FFB9000000008CCA0018FA -:108DB0003C1F800024020002015F1825ACC300188C -:108DC00037F90A00A0C200689329003C240400047B -:108DD00000A01021312800203C010800A0244019E7 -:108DE0001100000224050010240200013C010800CB -:108DF000AC223FB40A000D1A3C0280008F88002884 -:108E00008C8900600109282B14A000020100882130 -:108E10008C9100603C048000348B0E008D6400183F -:108E2000240A00010220282102203021A38A001CEC -:108E30000E000B83022080210A000CA6AF82002CBA -:108E40000004582312200007316400033C0E800008 -:108E500035C7098090ED007C31AC00041580001905 -:108E6000248F00043C010800A4243FDA3C1F0800C2 -:108E700097FF3FDA03E5C82100D9C02B1300FF6B31 -:108E80008F8400242CA6000514C0FFA324040042F4 -:108E900030A200031440000200A2182324A3FFFC08 -:108EA0003C010800AC233FBC3C010800A4203FDA91 -:108EB0000A000CE70060282100C770240A000D0D8D -:108EC00001C720263C010800A42F3FDA0A000D78D4 -:108ED000000000003C010800AC203FBC0A000D234C -:108EE000240400428F8300283C05800034AA0A0035 -:108EF0001460000600001021914700302406000590 -:108F000030E400FF108600030000000003E00008CA -:108F100000000000914B0048316900FF000941C288 -:108F20001500FFFA3C0680083C04080094843FC406 -:108F30003C0308008C633FDC3C1908008F393FBCC0 -:108F40003C0F080095EF3FDA0064C0218CCD00048F -:108F50000319702101CF602134AB0E00018D28234D -:108F600018A0001D00000000914F004C8F8C0034B1 -:108F7000956D001031EE00FF8D89000401AE3023A5 -:108F80008D8A000030CEFFFF000E29000125C82188 -:108F900000003821014720210325182B0083C02120 -:108FA000AD990004AD980000918F000A01CF6821AF -:108FB000A18D000A956500128F8A0034A54500082E -:108FC000954B003825690001A54900389148000DEE -:108FD00035070008A147000D03E00008000000006D -:108FE00027BDFFD8AFB000189388001C8FB00014C5 -:108FF0003C0A80003C197FFF8F8700243738FFFF31 -:10900000AFBF0020AFB1001C355F0A000218182462 -:1090100093EB003C00087FC03C02BFFF006F60255F -:109020002CF000013449FFFF3C1F08008FFF3FDC9C -:109030008F9900303C18080097183FD20189782496 -:10904000001047803C07EFFF3C05F0FF01E81825C2 -:109050003C1180003169002034E2FFFF34ADFFFF96 -:10906000362E098027A500102406000203F960238C -:10907000270B0002354A0E00006218240080802170 -:1090800015200002000040218D48001CA7AB0012F3 -:10909000058000392407000030E800FF00083F0089 -:1090A000006758253C028008AFAB0014344F0080A5 -:1090B00091EA00683C08080091083FD93C09DFFFAD -:1090C000352CFFFF000AF82B3C02080094423FCCED -:1090D000A3A80011016CC024001FCF40031918255C -:1090E0008FA70010AFA300143C0C0800918C3FDB4D -:1090F000A7A200168FAB001400ED48243C0F01001E -:109100003C0A0FFF012FC82531980003355FFFFF90 -:10911000016D40243C027000033F382400181E00FB -:1091200000E2482501037825AFAF0014AFA9001075 -:1091300091CC007C0E000092A3AC0015362D0A00E5 -:1091400091A6003C30C400201080000626020008D2 -:109150003C11080096313FC8262EFFFF3C01080055 -:10916000A42E3FC88FBF00208FB1001C8FB0001805 -:1091700003E0000827BD00288F8B002C010B502B2B -:109180005540FFC5240700010A000E0430E800FF27 -:109190009383001C3C02800027BDFFD834480A009E -:1091A00000805021AFBF002034460AC001002821B2 -:1091B0001060000E3444098091070030240B000534 -:1091C0008F89002030EC003F118B000B000038210C -:1091D000AFA900103C0B80088D69006CAFAA001885 -:1091E0000E00015AAFA90014A380001C8FBF0020FD -:1091F00003E0000827BD00288D1F00483C18080028 -:109200008F183FBC8F9900283C027FFF8D080044D7 -:109210003443FFFFAFA900103C0B80088D69006C40 -:1092200003E370240319782101CF682301A83821B2 -:10923000AFAA00180E00015AAFA900140A000E5878 -:10924000A380001C3C05800034A60A0090C7003CA7 -:109250003C06080094C63FDA3C0208008C423FD42A -:1092600030E30020000624001060001E0044382572 -:109270003C0880083505008090A300680000482164 -:109280002408000100002821240400013C0680007D -:109290008CCD017805A0FFFE34CF0140ADE8000879 -:1092A0003C0208008C423FDCA5E50004A5E4000672 -:1092B000ADE2000C3C04080090843FD93C038008D8 -:1092C00034790080A1E40012ADE70014A5E900188C -:1092D0009338004C3C0E1000A1F8002D03E000086C -:1092E000ACCE017834A90E008D28001C3C0C08007F -:1092F0008D8C3FBC952B0016952A001401864821C1 -:109300003164FFFF0A000E803145FFFF3C048000FE -:1093100034830A009065003C30A200201040001900 -:1093200034870E0000004021000038210000202179 -:109330003C0680008CC901780520FFFE34CA01403C -:1093400034CF010091EB0009AD4800083C0E080045 -:109350008DCE3FDC240DFF91240C00403C08100012 -:10936000A5440004A5470006AD4E000CA14D001217 -:10937000AD4C0014A5400018A14B002D03E00008DF -:10938000ACC801788CE8001894E6001294E4001050 -:1093900030C7FFFF0A000EA93084FFFF3C048000A5 -:1093A00034830A009065003C30A200201040002762 -:1093B00027BDFFF82409000100003821240800011E -:1093C0003C0680008CCA01780540FFFE3C0280FF0D -:1093D00034C40100908D00093C0C0800918C4019A8 -:1093E000A3AD00038FAB00003185007F3459FFFF30 -:1093F00001665025AFAA00009083000AA3A00002D6 -:1094000000057E00A3A300018FB8000034CB01400B -:10941000240C30000319702401CF6825AD6D000CB9 -:1094200027BD0008AD6C0014A5600018AD690008E8 -:10943000A56700042409FF80A56800063C08100009 -:10944000A169001203E00008ACC8017834870E005F -:109450008CE9001894E6001294E4001030C8FFFF75 -:109460000A000ECD3087FFFF27BDFFE0AFB100142B -:109470003C118000AFB00010AFBF001836380A00B2 -:10948000970F0032363001000E000B7F31E43FFFB2 -:109490008E0E0000240DFF803C04200001C25821E4 -:1094A000016D6024000C4940316A007F012A40258B -:1094B000010438253C048008AE270830348600803B -:1094C00090C500682403000230A200FF104300048E -:1094D0008F9F00208F990024AC9F0068AC99006496 -:1094E0008FBF00188FB100148FB0001003E0000888 -:1094F00027BD00203C0A0800254A3A803C090800A4 -:1095000025293B103C08080025082F1C3C070800B3 -:1095100024E73BDC3C06080024C639043C0508006F -:1095200024A536583C0408002484325C3C0308001F -:10953000246339B83C020800244237543C01080037 -:10954000AC2A3F983C010800AC293F943C0108003C -:10955000AC283F903C010800AC273F9C3C01080030 -:10956000AC263FAC3C010800AC253FA43C01080000 -:10957000AC243FA03C010800AC233FB03C010800F4 -:0C958000AC223FA803E00008000000003F -:04958C008000094012 -:109590008000090080080100800800808008000029 -:1095A000800E0000800800808008000080000A8093 -:0C95B00080000A00800009808000090093 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex deleted file mode 100644 index dcc443e210f5262552287cf7079f7f12710e5774..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex +++ /dev/null @@ -1,366 +0,0 @@ -:1000000000000000000008F800000058000000098F -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000CF000000950000000050000000066 -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F0106000F000000080500FFFF50 -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000008078000000000000C2F80000115 -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E1000200000008AC00000107 -:1000C00000000010203F003B00000010213F000313 -:1000D0000000001020BF0015000000188000FFFD88 -:1000E0000000000C1F800002000000188000FFF9D3 -:1000F00000000008B1000001000000082C8000B0E2 -:10010000000000082D000008000000082D800001FC -:10011000000000188000003C0000000B2FDF0002F0 -:100120000000000C1F800002000000002C070000EF -:100130000000001091DE0000000000188000FFEFBA -:100140000000000B2FDF00020000000C1F800000E9 -:10015000000000002C0700000000001091DE0000ED -:10016000000000188000FFEA0000000C1F80000261 -:10017000000000188000FFE80000000802240025AD -:1001800000000018000400000000001880000000BB -:10019000000000188000001B0000001880000042D2 -:1001A000000000188000000000000018800000001F -:1001B000000000188000000000000018800000000F -:1001C00000000018800000000000001880000000FF -:1001D00000000018800000000000001880000000EF -:1001E00000000018800000000000001880000000DF -:1001F000000000188000008E000000188000000041 -:1002000000000018800000000000001880000000BE -:1002100000000018800000000000001880000000AE -:10022000000000188000000000000018800000009E -:10023000000000188000008D00000018800000B74A -:10024000000000188000008400000018800000DA20 -:10025000000000188000002B000000188000000043 -:10026000000000188000006B0000001091D4000016 -:100270000000000C298000010000000C1F8000011C -:10028000000000082A0000020000000807800000AB -:10029000000000188000FFC4000000080380010077 -:1002A00000000010B73C0E000000001880000000A5 -:1002B000000000180002000000000000068200009C -:1002C00000000010B18F000400000010B18F140373 -:1002D000000000082A0000010000001091D4000076 -:1002E000000000000780140000000018000D00004E -:1002F00000000000050200000000001091DE000078 -:1003000000000018000A0000000000000682000043 -:100310000000001091DE0000000000090561FFFFF1 -:1003200000000010918A00020000000830E1FFFF89 -:10033000000000188000FFA9000000010561140002 -:1003400000000010918A000200000008B0E10001E6 -:1003500000000018000D00000000000006820000F0 -:100360000000001091DE0000000000090562FFFFA0 -:1003700000000010918A0002000000083162FFFFB7 -:10038000000000188000FF9F0000000105621400BB -:1003900000000010918A000200000008B162000114 -:1003A00000000018000D000000000010B1A0B01304 -:1003B0000000000B2FDF0002000000002C200000D6 -:1003C000000000082C800000000000082D00000044 -:1003D0000000001091D40000000000080500005546 -:1003E000000000188000FFDB000000082D80011CC9 -:1003F00000000010001F0000000000188000FFE255 -:100400000000000F476000080000000F060E00010A -:10041000000000000F580000000000000A64000007 -:10042000000000000AE50000000000090B66FFFF65 -:10043000000000000D6100000000001880000015A1 -:100440000000000F476000080000000B2FDF0002D3 -:10045000000000082C800000000000082D000000B3 -:100460000000001091D40000000000082D80011C45 -:100470000000000F060E000100000010001F000029 -:10048000000000000F580000000000188000FFD09E -:10049000000000000A640000000000000AE50000FF -:1004A000000000090B66FFFF000000000D61000066 -:1004B00000000000026200000000000002E00000F6 -:1004C0000000000B2FDF00020000000030050000DC -:1004D000000000003104000000000000309A00001D -:1004E000000000100060000A00000008051600016E -:1004F00000000010BA9A140300000000030000007E -:100500000000001880000006000000188000FF6C4A -:1005100000000010B60614040000000803060001E5 -:10052000000000082A000001000000188000FF7190 -:10053000000000000C961800000000090C99FFFF55 -:1005400000000004CC99340000000010BA992C027D -:10055000000000080F8000000000000C298000014E -:100560000000000C295200010000000C295200007C -:100570000000000822800002000000080200000EB7 -:10058000000000080280001A00000010B1C40A0236 -:1005900000000008020000030000000C1F800001A2 -:1005A000000000002ADF0000000000002A00080010 -:1005B000000000188000FF600000000B2FDF000229 -:1005C0000000001091D40000000000082A00000183 -:1005D000000000002C2000000000001091D400005A -:1005E000000000082C800000000000082D00000022 -:1005F000000000082D80011C000000188000FF9FF3 -:10060000000000082C800006000000082D000006F5 -:1006100000000000308000000000000031000000F9 -:10062000000000082D8000060000000C2980000159 -:100630000000000C1F8000010000001091DE00008F -:10064000000000002ADF0000000000082A0000105F -:100650000000000807800000000000188000FF4B29 -:100660000000001091D4000000000008050000AA5E -:10067000000000188000FF890000000C29800001A4 -:100680000000000C1F800001000000082A00000983 -:10069000000000188000FF440000001091D400000A -:1006A0000000000805000055000000188000FF82CF -:1006B0000000001091A0B00200000010B1E6620737 -:1006C0000000000B2FDF0002000000002C310000B2 -:1006D000000000092CB1007F000000082CD90000A8 -:1006E000000000082D000000000000082D80010D12 -:1006F00000000010B1A8000600000010205F0000FC -:10070000000000002C200000000000002CA70000CA -:10071000000000082D000010000000082D800108D6 -:10072000000000188000FF7A00000010B1A6001041 -:1007300000000010001F00000000000F0F30000735 -:10074000000000000A600000000000000AE1000054 -:100750000000000F4B620008000000090B1600FFAC -:10076000000000000D620000000000090D1A00FFEB -:1007700000000010073000030000000C0D1A0008F4 -:100780000000000C0B1600080000000F4CE30018DE -:10079000000000000C992C0000000004CC993400EB -:1007A000000000080F8000000000000C29800001FC -:1007B0000000000033310000000000082200001695 -:1007C000000000002ADF0000000000082A00000CE2 -:1007D00000000010009F0000000000002C2000001E -:1007E0000000000C1F800001000000188000FF19AD -:1007F0000000001091D4000000000008050000AACD -:10080000000000188000FF570000000F472200087A -:1008100000000009070E000F00000008070E000886 -:1008200000000008028000010000000702851C0093 -:1008300000000008828500010000000002854C00D5 -:100840000000000742851C0000000003C3AA5200FC -:100850000000000003B10E00000000074B071C0061 -:100860000000000F0F3000070000000F0A96000381 -:10087000000000000A955C00000000004A005A00D9 -:10088000000000000C960A00000000090C99FFFF10 -:10089000000000080D00FFFF00000010BA992C02B4 -:1008A000000000080F80000500000010B1A800083B -:1008B00000000010205F00000000000B2FDF00028E -:1008C000000000002C200000000000002CA7000009 -:1008D000000000082D000010000000082D80010815 -:1008E000000000188000FF420000000C2980000179 -:1008F00000000010001F00000000000C1F8000011D -:10090000000000002ADF0000000000082A00000D9F -:10091000000000188000FEF40000001091D40000D8 -:100920000000000805000055000000188000FF329C -:100930000000000C298000010000000C1F80000155 -:10094000000000082A000007000000188000FEEDEB -:1009500000000010B18000040000001F0106000F1D -:1009600000000008050000FF000000180002000061 -:10097000000000002A00000000000010B1D40000B8 -:100980000000001091DE0000000000102053000065 -:1009900000000010001F0000000000002F80AA00CF -:1009A0000000000C29800001000000080254000E25 -:1009B000000000002C400000000000000F4000007C -:1009C0000000001800040000000000188000001162 -:1009D000000000188000001200000018800000389D -:1009E00000000018800000DF00000018800000DE1A -:1009F00000000018800000DD00000018800000DD0D -:100A0000000000188000000000000018800000F6C0 -:100A100000000018800000D90000001880000000CD -:100A200000000018800000FA000000188000014853 -:100A3000000000188000005A00000018800000C468 -:100A400000000018800000C500000018800000D2DF -:100A5000000000002A000000000000188000FFE4F1 -:100A6000000000002A0000000000000C29800000A7 -:100A7000000000188000FFE10000001800020000E4 -:100A8000000000000502000000000010B99A2C21AF -:100A900000000010205F0000000000002C1E00007D -:100AA000000000082C800006000000082D00000651 -:100AB000000000082D80010200000000000000007E -:100AC0000000001091DE0000000000000D61000039 -:100AD00000000018000A00000000000005020000ED -:100AE00000000010B99A2C1600000010205F0000D2 -:100AF0000000000009D80000000000002C1E0000CB -:100B0000000000082C8000B2000000082D00000A40 -:100B1000000000082D80010200000000000000001D -:100B20000000001091DE0000000000000D620000D7 -:100B3000000000002C13000000000018000A000054 -:100B4000000000000502000000000010B99A2C0906 -:100B500000000010205F0000000000002C1E0000BC -:100B6000000000082C800006000000082D00006A2C -:100B7000000000082D8001020000000000000000BD -:100B80000000001091DE0000000000000D7A00005F -:100B900000000018000A0000000000002A00000009 -:100BA0000000000822000001000000000D610000AC -:100BB0000000001021C2002400000010B1C6000295 -:100BC00000000010234200A2000000090B66FFFF96 -:100BD00000000010BA9A2C20000000000A640000F7 -:100BE000000000000AE50000000000000C0000000A -:100BF000000000000B800000000000080CC600127E -:100C0000000000188000FFD0000000080F800003E3 -:100C1000000000000000000000000010009F000025 -:100C2000000000082711001200000000669000007C -:100C300000000010B198000300000010001F000029 -:100C4000000000080F8000040000000822000003DC -:100C5000000000082C80000C000000082D00000C93 -:100C600000000010009F00000000001091C6000569 -:100C700000000010001F000000000010BA9A2C03B2 -:100C8000000000080F800004000000188000FFFD35 -:100C900000000000259600000000000C29800000E4 -:100CA0000000000032140000000000003295000037 -:100CB0000000000573662C000000000031E32E00E8 -:100CC000000000082D800010000000188000FF9632 -:100CD00000000000230000000000000925E6FFFFDF -:100CE000000000082200000B0000000C6952000008 -:100CF0000000000C29800000000000188000FF9018 -:100D0000000000002A000000000000082C800040C5 -:100D1000000000082D000020000000082D80011CAC -:100D200000000008220000010000001091DE000019 -:100D30000000000F42EA001000000010004F000405 -:100D400000000010B746920000000008024900129F -:100D500000000010B5840A00000000000D610000D2 -:100D600000000010BA663457000000088305001226 -:100D700000000010004F00020000000003490000C6 -:100D80000000000183068C000000000083C60C00F8 -:100D900000000010B1870013000000000B6E00007F -:100DA000000000090569FFFF00000010918A0002A1 -:100DB0000000000834E9FFFF000000188000FF7504 -:100DC000000000010569140000000010918A000273 -:100DD00000000008B4E9000100000010BAE92C4846 -:100DE0000000000086692C000000000002000000E6 -:100DF0000000000902EAFFFF00000010000C0002E2 -:100E00000000000002040A000000000F460C000170 -:100E10000000000F0285000100000010918C01FC11 -:100E200000000010B7040E3F000000000D6100003C -:100E3000000000000A640000000000000AE5000055 -:100E4000000000090B66FFFF000000000C0000001E -:100E5000000000000B800000000000080C8600125B -:100E6000000000080F8000030000000C2952000061 -:100E700000000010009F0000000000082711001271 -:100E80000000000066900000000000002306000043 -:100E900000000010B198000500000010001F0000C5 -:100EA000000000080F8000040000000000000000A7 -:100EB00000000010001F00000000000032140000BD -:100EC00000000000329500000000000031E32E0019 -:100ED0000000000573662C0000000000259600004D -:100EE00000000010B18700160000000C29800000EF -:100EF0000000000F0F6B0007000000000D690000EC -:100F0000000000000A6C0000000000000AED000074 -:100F1000000000000B6E0000000000000B800000CD -:100F2000000000000C870000000000080F80000394 -:100F300000000010205300000000000C6952000166 -:100F400000000010001F00000000000022C58C00FF -:100F500000000000231B000000000000271100001B -:100F6000000000002690000000000010B8170E03DB -:100F70000000000C29800000000000188000FFF62F -:100F800000000010B1980002000000080F8000046B -:100F9000000000082200001A000000082C80000C4D -:100FA000000000082D00000C000000082D8000103B -:100FB00000000010001F0000000000000D6E000087 -:100FC00000000003E7CF34000000000C298000007F -:100FD0000000001091DE000000000010B187000743 -:100FE00000000000361400000000000036950000EC -:100FF0000000000037160000000000082C800050A0 -:10100000000000082D000030000000082D80000CBA -:10101000000000188000FF2D0000000023000000E9 -:101020000000000925E6FFFF000000000B6E000035 -:1010300000000003E7CF2C00000000082200001B86 -:101040000000000C695200000000000C2980000024 -:10105000000000188000FF25000000002A000000AA -:10106000000000188000FF23000000002A0000009C -:101070000000000C298000000000001091DE00003C -:10108000000000082C80001A000000082D00001A43 -:101090000000000573660000000000082D800002BB -:1010A00000000000318000000000001091DE000010 -:1010B000000000082C80000C000000082D00000C2F -:1010C000000000082D800004000000188000FF16BA -:1010D0000000001880000000000000188000FF14CD -:1010E000000000002A00000000000010001F0000A7 -:1010F000000000000F008000000000080F800007C3 -:10110000000000188000001B00000000280A0000FA -:101110000000000005020000000000082200000995 -:1011200000000000290000000000000F65680010AA -:1011300000000000248A000000000003F66C940008 -:1011400000000010B972A0040000000C73E7001941 -:101150000000000C21420004000000003CF80000E8 -:101160000000000C29800000000000102053000047 -:1011700000000008220000080000000C614200048A -:1011800000000018000A0000000000000502000036 -:101190000000000C6142000000000010014200034A -:1011A0000000000C33E7001D0000000C614200024B -:1011B00000000018000A0000000000002A000000E3 -:1011C00000000010001F00000000000F0F47000784 -:1011D000000000080F8000080000000C29800000BB -:1011E00000000010009F0000000000188000FEF2C8 -:1011F0000000000033510000000000002A00000041 -:1012000000000010B1C600230000000F0F500007BF -:10121000000000000A600000000000000AE1000079 -:101220000000000F4B620008000000090B1600FFD1 -:101230000000000F4C620010000000000D62000072 -:10124000000000090D1A00FF000000100750000305 -:101250000000000C0D1A00080000000C0B1600081E -:10126000000000000CC60000000000000B80000021 -:101270000000000006980000000000080F80000336 -:101280000000001006C200040000000C290000024B -:1012900000000010264200020000000C295200034A -:1012A000000000082200000100000010009F000064 -:1012B00000000000231B00000000000027111A009E -:1012C00000000000669000000000000C29520000A1 -:1012D00000000010B19732090000000C29800000C6 -:1012E00000000000069800000000001020530000DD -:1012F0000000000C295200030000000022C58C00F1 -:1013000000000010001F0000000000080F80000314 -:10131000000000188000FFF300000010B1C80013A7 -:1013200000000010B1C600030000000C298000007E -:1013300000000010205300000000000C29520000A3 -:101340000000000C295200030000001006C2000239 -:101350000000000C295200020000000022C58C0091 -:1013600000000000276500000000000026E40000E7 -:10137000000000082200001600000010B1C60003A3 -:10138000000000002348000000000010B1800005AC -:1013900000000000234800000000000C298000002D -:1013A0000000000F0F50000700000018800000121E -:1013B00000000008220000160000000C2980000038 -:1013C0000000000030140000000000003095000014 -:1013D0000000001007500003000000090B1600FF7A -:1013E000000000090D1A00FF0000000F3116000870 -:1013F000000000003162340000000003F1623000A0 -:1014000000000010205F0000000000002C510000D0 -:10141000000000092CD1007F000000082CD900003A -:10142000000000082D000000000000082D80000CC6 -:1014300000000000000000000000001091DE00002D -:101440000000001005C20004000000080F80000723 -:10145000000000003300000000000010009F0000AA -:10146000000000188000FEA3000000002A00000019 -:101470000000000F0F50000700000010B1C6002D43 -:101480000000000F4742000800000009070E000F8F -:1014900000000008070E000800000010001F0000F8 -:1014A00000000008090000010000000709121C00EC -:1014B00000000003CBCA9200000000000B97A200BE -:1014C0000000000742171C00000000000B04000091 -:1014D0000000000F0A840003000000000A959C0031 -:1014E000000000004A009A0000000008821200017B -:1014F000000000010C170800000000000C978C0091 -:101500000000000002180000000000080D00FFFFAE -:10151000000000080F8000060000000C29000000F9 -:101520000000001006C200040000000C2952000256 -:1015300000000010264200020000000C29520003A7 -:10154000000000082200000100000010009F0000C1 -:1015500000000010B197320C00000000231B0000B7 -:101560000000000027110800000000006690000045 -:101570000000000C2980000000000000021800009C -:1015800000000010205300000000000C295200034E -:101590000000000022C5360000000010001F0000FF -:1015A000000000080F800006000000188000FFF413 -:1015B00000000000231B00000000000027110800AD -:1015C000000000006690000000000010B1C8000B91 -:1015D0000000000C298000000000001020530000D3 -:1015E0000000000C295200000000000C29520003EA -:1015F0000000001006C200020000000C2952000288 -:101600000000000022C58C000000000027650000DB -:101610000000000026E40000000000002348000055 -:1016200000000008220000170000000C29800000C4 -:1016300000000010001F0000000000188000FE687D -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex deleted file mode 100644 index 435203d6430567293e662f8a1a31976d204530de..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex +++ /dev/null @@ -1,392 +0,0 @@ -:1000000000000000000008F800000058000000098F -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000E88000009500000000500000000CC -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F05060011000000080500FFFF4A -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000008078000000000000C2F80000115 -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E1000200000008AC00000107 -:1000C00000000010203F003B00000010213F000313 -:1000D0000000001020BF0015000000188000FFFD88 -:1000E0000000000C1F800002000000188000FFF9D3 -:1000F00000000008B1000001000000082C80010C85 -:10010000000000082D000008000000082D800001FC -:10011000000000188000003C0000000B2FDF0002F0 -:100120000000000C1F800002000000002C070000EF -:100130000000001091DE0000000000188000FFEFBA -:100140000000000B2FDF00020000000C1F800000E9 -:10015000000000002C0700000000001091DE0000ED -:10016000000000188000FFEA0000000C1F80000261 -:10017000000000188000FFE80000000802240025AD -:1001800000000018000400000000001880000000BB -:10019000000000188000001B0000001880000042D2 -:1001A000000000188000000000000018800000001F -:1001B000000000188000000000000018800000000F -:1001C00000000018800000000000001880000000FF -:1001D00000000018800000000000001880000000EF -:1001E00000000018800000000000001880000000DF -:1001F000000000188000008E000000188000000041 -:1002000000000018800000000000001880000000BE -:1002100000000018800000000000001880000000AE -:10022000000000188000000000000018800000009E -:10023000000000188000008D00000018800000B74A -:10024000000000188000008400000018800000DA20 -:10025000000000188000002B000000188000000043 -:10026000000000188000006B0000001091D4000016 -:100270000000000C298000010000000C1F8000011C -:10028000000000082A0000020000000807800000AB -:10029000000000188000FFC4000000080380010077 -:1002A00000000010B73C0E000000001880000000A5 -:1002B000000000180002000000000000068200009C -:1002C00000000010B18F000400000010B18F140373 -:1002D000000000082A0000010000001091D4000076 -:1002E000000000000780140000000018000D00004E -:1002F00000000000050200000000001091DE000078 -:1003000000000018000A0000000000000682000043 -:100310000000001091DE0000000000090561FFFFF1 -:1003200000000010918A00020000000830E1FFFF89 -:10033000000000188000FFA9000000010561140002 -:1003400000000010918A000200000008B0E10001E6 -:1003500000000018000D00000000000006820000F0 -:100360000000001091DE0000000000090562FFFFA0 -:1003700000000010918A0002000000083162FFFFB7 -:10038000000000188000FF9F0000000105621400BB -:1003900000000010918A000200000008B162000114 -:1003A00000000018000D000000000010B1A0B01304 -:1003B0000000000B2FDF0002000000002C200000D6 -:1003C000000000082C800000000000082D00000044 -:1003D0000000001091D40000000000080500005546 -:1003E000000000188000FFDB000000082D80011CC9 -:1003F00000000010001F0000000000188000FFE255 -:100400000000000F476000080000000F060E00010A -:10041000000000000F580000000000000A64000007 -:10042000000000000AE50000000000090B66FFFF65 -:10043000000000000D6100000000001880000015A1 -:100440000000000F476000080000000B2FDF0002D3 -:10045000000000082C800000000000082D000000B3 -:100460000000001091D40000000000082D80011C45 -:100470000000000F060E000100000010001F000029 -:10048000000000000F580000000000188000FFD09E -:10049000000000000A640000000000000AE50000FF -:1004A000000000090B66FFFF000000000D61000066 -:1004B00000000000026200000000000002E00000F6 -:1004C0000000000B2FDF00020000000030050000DC -:1004D000000000003104000000000000309A00001D -:1004E000000000100060000A00000008051600016E -:1004F00000000010BA9A140300000000030000007E -:100500000000001880000006000000188000FF6C4A -:1005100000000010B60614040000000803060001E5 -:10052000000000082A000001000000188000FF7190 -:10053000000000000C961800000000090C99FFFF55 -:1005400000000004CC99340000000010BA992C027D -:10055000000000080F8000000000000C298000014E -:100560000000000C295200010000000C295200007C -:100570000000000822800002000000080200000EB7 -:10058000000000080280001A00000010B1C40A0236 -:1005900000000008020000030000000C1F800001A2 -:1005A000000000002ADF0000000000002A00080010 -:1005B000000000188000FF600000000B2FDF000229 -:1005C0000000001091D40000000000082A00000183 -:1005D000000000002C2000000000001091D400005A -:1005E000000000082C800000000000082D00000022 -:1005F000000000082D80011C000000188000FF9FF3 -:10060000000000082C800006000000082D000006F5 -:1006100000000000308000000000000031000000F9 -:10062000000000082D8000060000000C2980000159 -:100630000000000C1F8000010000001091DE00008F -:10064000000000002ADF0000000000082A0000105F -:100650000000000807800000000000188000FF4B29 -:100660000000001091D4000000000008050000AA5E -:10067000000000188000FF890000000C29800001A4 -:100680000000000C1F800001000000082A00000983 -:10069000000000188000FF440000001091D400000A -:1006A0000000000805000055000000188000FF82CF -:1006B0000000001091A0B00200000010B1E6620737 -:1006C0000000000B2FDF0002000000002C310000B2 -:1006D000000000092CB1007F000000082CD90000A8 -:1006E000000000082D000000000000082D80010D12 -:1006F00000000010B1A8000600000010205F0000FC -:10070000000000002C200000000000002CA70000CA -:10071000000000082D000010000000082D800108D6 -:10072000000000188000FF7A00000010B1A6001041 -:1007300000000010001F00000000000F0F30000735 -:10074000000000000A600000000000000AE1000054 -:100750000000000F4B620008000000090B1600FFAC -:10076000000000000D620000000000090D1A00FFEB -:1007700000000010073000030000000C0D1A0008F4 -:100780000000000C0B1600080000000F4CE30018DE -:10079000000000000C992C0000000004CC993400EB -:1007A000000000080F8000000000000C29800001FC -:1007B0000000000033310000000000082200001695 -:1007C000000000002ADF0000000000082A00000CE2 -:1007D00000000010009F0000000000002C2000001E -:1007E0000000000C1F800001000000188000FF19AD -:1007F0000000001091D4000000000008050000AACD -:10080000000000188000FF570000000F472200087A -:1008100000000009070E000F00000008070E000886 -:1008200000000008028000010000000702851C0093 -:1008300000000008828500010000000002854C00D5 -:100840000000000742851C0000000003C3AA5200FC -:100850000000000003B10E00000000074B071C0061 -:100860000000000F0F3000070000000F0A96000381 -:10087000000000000A955C00000000004A005A00D9 -:10088000000000000C960A00000000090C99FFFF10 -:10089000000000080D00FFFF00000010BA992C02B4 -:1008A000000000080F80000500000010B1A800083B -:1008B00000000010205F00000000000B2FDF00028E -:1008C000000000002C200000000000002CA7000009 -:1008D000000000082D000010000000082D80010815 -:1008E000000000188000FF420000000C2980000179 -:1008F00000000010001F00000000000C1F8000011D -:10090000000000002ADF0000000000082A00000D9F -:10091000000000188000FEF40000001091D40000D8 -:100920000000000805000055000000188000FF329C -:100930000000000C298000010000000C1F80000155 -:10094000000000082A000007000000188000FEEDEB -:1009500000000010B18000040000001F0506001117 -:1009600000000008050000FF000000180002000061 -:10097000000000002A00000000000010B1D40000B8 -:100980000000001091DE0000000000102053000065 -:1009900000000010001F0000000000002F80AA00CF -:1009A0000000000C29800001000000080254000F24 -:1009B000000000002C400000000000000F4000007C -:1009C000000000092952003F000000180004000048 -:1009D00000000018800000110000001880000012C4 -:1009E000000000188000003800000018800001118D -:1009F0000000001880000110000000188000010FA6 -:100A0000000000188000010F0000001880000000A6 -:100A10000000001880000128000000188000010B71 -:100A20000000001880000000000000188000012C69 -:100A3000000000188000017A000000188000005AB1 -:100A400000000018800000C400000018800000C5ED -:100A50000000001880000104000000002A000000CF -:100A6000000000188000FFE3000000002A000000E2 -:100A70000000000C29800000000000188000FFE04A -:100A80000000001800020000000000000502000045 -:100A900000000010B99A2C2100000010205F000017 -:100AA000000000002C1E0000000000082C80000642 -:100AB000000000082D000006000000082D80010243 -:100AC00000000000000000000000001091DE0000A7 -:100AD000000000000D61000000000018000A000086 -:100AE000000000000502000000000010B99A2C165A -:100AF00000000010205F00000000000009D8000086 -:100B0000000000002C1E0000000000082C80010ED8 -:100B1000000000082D00000A000000082D800102DE -:100B200000000000000000000000001091DE000046 -:100B3000000000000D620000000000002C13000007 -:100B400000000018000A000000000000050200007C -:100B500000000010B99A2C0900000010205F00006E -:100B6000000000002C1E0000000000082C80000681 -:100B7000000000082D00006A000000082D8001021E -:100B800000000000000000000000001091DE0000E6 -:100B9000000000000D7A000000000018000A0000AC -:100BA000000000002A0000000000000822000001F0 -:100BB000000000000D6100000000001021C20024B0 -:100BC00000000010B1C6000200000010234200A285 -:100BD000000000090B66FFFF00000010BA9A2C20ED -:100BE000000000000A640000000000000AE50000A8 -:100BF000000000000C000000000000000B8000005E -:100C0000000000080CC60012000000188000FFD091 -:100C1000000000080F80000300000000000000003A -:100C200000000010009F00000000000827110012C3 -:100C3000000000006690000000000010B198000362 -:100C400000000010001F0000000000080F800004DA -:100C50000000000822000003000000082C80000CA7 -:100C6000000000082D00000C00000010009F000094 -:100C70000000001091C6000500000010001F0000D9 -:100C800000000010BA9A2C03000000080F80000436 -:100C9000000000188000FFFD000000002596000005 -:100CA0000000000C29800000000000003214000049 -:100CB00000000000329500000000000573662C0063 -:100CC0000000000031E32E00000000082D8000101D -:100CD000000000188000FF950000000023000000C5 -:100CE0000000000925E6FFFF000000082200000BBD -:100CF0000000000C695200000000000C2980000078 -:100D0000000000188000FF8F000000002A00000093 -:100D1000000000082C800040000000082D0000208A -:100D2000000000082D80011C0000000822000001C6 -:100D30000000001091DE00000000000F42EA0010E9 -:100D400000000010004F000400000010B7469200A1 -:100D5000000000080249001200000010B5840A00DB -:100D6000000000000D61000000000010BA6634575A -:100D7000000000088305001200000010004F000270 -:100D800000000000034900000000000183068C0001 -:100D90000000000083C60C0000000010B1870013A3 -:100DA000000000000B6E0000000000090569FFFF55 -:100DB00000000010918A00020000000834E9FFFFE3 -:100DC000000000188000FF74000000010569140095 -:100DD00000000010918A000200000008B4E9000140 -:100DE00000000010BAE92C480000000086692C00C1 -:100DF00000000000020000000000000902EAFFFFFE -:100E000000000010000C00020000000002040A00B4 -:100E10000000000F460C00010000000F02850001D9 -:100E200000000010918C01FC00000010B7040E3F80 -:100E3000000000000D610000000000000A640000D6 -:100E4000000000000AE50000000000090B66FFFF3B -:100E5000000000000C000000000000000B800000FB -:100E6000000000080C860012000000080F8000033C -:100E70000000000C2952000000000010009F00003C -:100E8000000000082711001200000000669000001A -:100E9000000000002306000000000010B1980005CB -:100EA00000000010001F0000000000080F80000478 -:100EB000000000000000000000000010001F000003 -:100EC0000000000032140000000000003295000015 -:100ED0000000000031E32E000000000573662C00C6 -:100EE000000000002596000000000010B1870016E9 -:100EF0000000000C298000000000000F0F6B0007AD -:100F0000000000000D690000000000000A6C0000F5 -:100F1000000000000AED0000000000000B6E000061 -:100F2000000000000B800000000000000C870000A3 -:100F3000000000080F800003000000102053000094 -:100F40000000000C6952000100000010001F0000AA -:100F50000000000022C58C0000000000231B0000E0 -:100F60000000000027110000000000002690000093 -:100F700000000010B8170E030000000C29800000CC -:100F8000000000188000FFF600000010B198000279 -:100F9000000000080F800004000000082200001A72 -:100FA000000000082C80000C000000082D00000C40 -:100FB000000000082D80001000000010001F00003D -:100FC000000000000D6E000000000003E7CF3400B9 -:100FD0000000000C298000000000001091DE0000DD -:100FE00000000010B1870007000000003614000068 -:100FF00000000000369500000000000037160000D9 -:10100000000000082C800050000000082D00003077 -:10101000000000082D80000C000000188000FF2C4C -:1010200000000000230000000000000925E6FFFF8B -:10103000000000000B6E000000000003E7CF2C0052 -:10104000000000082200001B0000000C6952000094 -:101050000000000C29800000000000188000FF2420 -:10106000000000002A000000000000188000FF229D -:10107000000000002A0000000000000C2980000091 -:101080000000001091DE0000000000082C80001A13 -:10109000000000082D00001A000000057366000023 -:1010A000000000082D8000020000000031800000D8 -:1010B0000000001091DE0000000000082C80000CF1 -:1010C000000000082D00000C000000082D80000426 -:1010D000000000188000FF150000000806660001EF -:1010E00000000010BA9A197F000000000A64000096 -:1010F000000000000AE50000000000090B66FFFF89 -:10110000000000000C000000000000000B80000048 -:10111000000000080CC60012000000188000FF2E1E -:10112000000000080F800003000000000000000025 -:1011300000000010009F00000000000827110012AE -:10114000000000006690000000000010919B32003B -:10115000000000100293000000000010B19800038E -:1011600000000010001F0000000000080F800004B5 -:101170000000000C2980000000000010001F00008B -:1011800000000010BA9A2C000000000031E32E008D -:10119000000000000B800000000000008CCC8C00E0 -:1011A00000000010B5CC8C02000000080C8000018B -:1011B000000000188000FF1B000000080F800003E3 -:1011C00000000010205300000000000C69520001D4 -:1011D0000000000022C58C0000000010009F0000ED -:1011E0000000000027110000000000002690000011 -:1011F00000000000231B000000000010B198000355 -:1012000000000010001F0000000000080F80000414 -:101210000000000822000003000000082C80000CE1 -:10122000000000082D00000C00000010009F0000CE -:1012300000000000259600000000000C298000003E -:101240000000000032140000000000003295000091 -:101250000000000573662C000000000031E32E0042 -:10126000000000082D800010000000188000FEE241 -:10127000000000188000FEE1000000002A000000CD -:1012800000000010001F0000000000000F008000A0 -:10129000000000080F800007000000188000001BFD -:1012A00000000000280A0000000000000502000005 -:1012B00000000008220000090000000029000000D2 -:1012C0000000000F6568001000000000248A000084 -:1012D00000000003F66C940000000010B972A00436 -:1012E0000000000C73E700190000000C214200040C -:1012F000000000003CF800000000000C2980000005 -:101300000000001020530000000000082200000828 -:101310000000000C6142000400000018000A0000F8 -:1013200000000000050200000000000C6142000007 -:1013300000000010014200030000000C33E7001D14 -:101340000000000C6142000200000018000A0000CA -:10135000000000002A00000000000010001F000034 -:101360000000000F0F470007000000080F80000872 -:101370000000000C2980000000000010009F000009 -:10138000000000188000FEBF000000003351000084 -:10139000000000002A00000000000010B1C6002379 -:1013A0000000000F0F500007000000000A6000005E -:1013B000000000000AE100000000000F4B6200087E -:1013C000000000090B1600FF0000000F4C62001027 -:1013D000000000000D620000000000090D1A00FF6F -:1013E00000000010075000030000000C0D1A000858 -:1013F0000000000C0B160008000000000CC60000E6 -:10140000000000000B8000000000000006980000B3 -:10141000000000080F8000030000001006C2000456 -:101420000000000C2900000200000010264200020B -:101430000000000C295200030000000822000001F7 -:1014400000000010009F000000000000231B0000AF -:101450000000000027111A00000000006690000044 -:101460000000000C2952000000000010B197320962 -:101470000000000C29800000000000000698000019 -:1014800000000010205300000000000C295200034F -:101490000000000022C58C0000000010001F0000AA -:1014A000000000080F800003000000188000FFF318 -:1014B00000000010B1C8001300000010B1C6000306 -:1014C0000000000C298000000000001020530000E4 -:1014D0000000000C295200000000000C29520003FB -:1014E0000000001006C200020000000C2952000299 -:1014F0000000000022C58C000000000027650000ED -:101500000000000026E40000000000082200001691 -:1015100000000010B1C600030000000023480000D6 -:1015200000000010B180000500000000234800000A -:101530000000000C298000000000000F0F50000781 -:1015400000000018800000120000000822000016B1 -:101550000000000C29800000000000003014000092 -:10156000000000003095000000000010075000034C -:10157000000000090B1600FF000000090D1A00FF13 -:101580000000000F31160008000000003162340036 -:1015900000000003F162300000000010205F000036 -:1015A000000000002C510000000000092CD1007F39 -:1015B000000000082CD90000000000082D000000E9 -:1015C000000000082D80000C00000000000000005A -:1015D0000000001091DE00000000001005C20004B1 -:1015E000000000080F80000700000000330000002A -:1015F00000000010009F0000000000188000FE7036 -:10160000000000002A0000000000000F0F5000073B -:1016100000000010B1C6002D0000000F4742000876 -:1016200000000009070E000F00000008070E000868 -:1016300000000010001F0000000000080900000169 -:101640000000000709121C0000000003CBCA920032 -:10165000000000000B97A2000000000742171C00CA -:10166000000000000B0400000000000F0A840003CB -:10167000000000000A959C00000000004A009A004B -:101680000000000882120001000000010C17080091 -:10169000000000000C978C00000000000218000001 -:1016A000000000080D00FFFF000000080F8000068A -:1016B0000000000C290000000000001006C2000419 -:1016C0000000000C29520002000000102642000217 -:1016D0000000000C29520003000000082200000155 -:1016E00000000010009F000000000010B197320CB5 -:1016F00000000000231B000000000000271108006C -:1017000000000000669000000000000C298000002E -:10171000000000000218000000000010205300002C -:101720000000000C295200030000000022C5360012 -:1017300000000010001F0000000000080F800006DD -:10174000000000188000FFF400000000231B0000D0 -:101750000000000027110800000000006690000053 -:1017600000000010B1C8000B0000000C2980000030 -:1017700000000010205300000000000C295200005F -:101780000000000C295200030000001006C20002F5 -:101790000000000C295200020000000022C58C004D -:1017A00000000000276500000000000026E40000A3 -:1017B000000000002348000000000008220000177D -:1017C0000000000C2980000000000010001F000035 -:0817D000000000188000FE3546 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex deleted file mode 100644 index d2f275788f166b79e13d6e888c1142cb49fb7b9a..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex +++ /dev/null @@ -1,425 +0,0 @@ -:100000000000000000000970000000580000000916 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000001010000009C80000000500000000CA -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F03060011000000080500FFFF4C -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000008078000000000000C2F80000115 -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E1000200000008AC00000107 -:1000C00000000010203F003B00000010213F000313 -:1000D0000000001020BF0015000000188000FFFD88 -:1000E0000000000C1F800002000000188000FFF9D3 -:1000F00000000008B1000001000000082C80010C85 -:10010000000000082D000008000000082D800001FC -:10011000000000188000004F0000000B2FDF0002DD -:100120000000000C1F800002000000002C070000EF -:100130000000001091DE0000000000188000FFEFBA -:100140000000000B2FDF00020000000C1F800000E9 -:10015000000000002C0700000000001091DE0000ED -:10016000000000188000FFEA0000000C1F80000261 -:10017000000000188000FFE80000000802240025AD -:1001800000000018000400000000001880000000BB -:10019000000000188000001B0000001880000055BF -:1001A000000000188000000000000018800000001F -:1001B000000000188000000000000018800000000F -:1001C00000000018800000000000001880000000FF -:1001D00000000018800000000000001880000000EF -:1001E00000000018800000000000001880000000DF -:1001F000000000188000009D000000188000000032 -:1002000000000018800000000000001880000000BE -:1002100000000018800000000000001880000000AE -:10022000000000188000000000000018800000009E -:10023000000000188000009C00000018800000C62C -:10024000000000188000009300000018800000E902 -:10025000000000188000003E000000188000000030 -:10026000000000188000007A0000001091D4000007 -:100270000000000C298000010000000C1F8000011C -:10028000000000082A0000020000000807800000AB -:10029000000000188000FFC4000000080380010077 -:1002A00000000010B73C0E000000001880000000A5 -:1002B000000000000202000000000000029A00009E -:1002C00000000000060C2C0000000004C60C3400E6 -:1002D00000000010001F000000000010BA8C2C0C61 -:1002E000000000080696000400000009068DFFFCCF -:1002F00000000004CD051A0000000004CC9A18008C -:100300000000001020D700000000000C2B56000059 -:1003100000000000000000000000000000000000DD -:100320000000001020D70000000000080F8000012E -:1003300000000010B18001F400000010001F000058 -:100340000000000C6B5600000000001800040000C4 -:10035000000000000682000000000010B18F0004C1 -:1003600000000010B18F1403000000082A000001F3 -:100370000000001091D4000000000000078014006D -:1003800000000018000D0000000000000502000041 -:100390000000001091DE000000000018000A0000BC -:1003A00000000000068200000000001091DE000046 -:1003B000000000090561FFFF00000010918A0002A3 -:1003C0000000000830E1FFFF000000188000FF96E9 -:1003D000000000010561140000000010918A000275 -:1003E00000000008B0E1000100000018000D00004E -:1003F00000000000068200000000001091DE0000F6 -:10040000000000090562FFFF00000010918A000251 -:10041000000000083162FFFF000000188000FF8C20 -:10042000000000010562140000000010918A000223 -:1004300000000008B162000100000018000D00007B -:1004400000000010B1A0B0130000000B2FDF00026D -:10045000000000002C200000000000082C8000009C -:10046000000000082D0000000000001091D40000E2 -:100470000000000805000055000000188000FFDBA8 -:10048000000000082D80011C00000010001F00006B -:10049000000000188000FFE20000000F4760000825 -:1004A0000000000F060E0001000000000F580000C1 -:1004B000000000000A640000000000000AE50000DF -:1004C000000000090B66FFFF000000000D61000046 -:1004D00000000018800000150000000F47600008B1 -:1004E0000000000B2FDF0002000000082C8000003D -:1004F000000000082D0000000000001091D4000052 -:10050000000000082D80011C0000000F060E0001F5 -:1005100000000010001F0000000000000F58000045 -:10052000000000188000FFD0000000000A640000F6 -:10053000000000000AE50000000000090B66FFFF54 -:10054000000000000D6100000000000002620000D9 -:100550000000000002E000000000000B2FDF00029E -:100560000000000030050000000000003104000021 -:1005700000000000309A0000000000100060000A37 -:10058000000000080516000100000010BA9A1403CC -:1005900000000000030000000000001880000006BA -:1005A000000000188000FF5900000010B606140477 -:1005B0000000000803060001000000082A000001F6 -:1005C000000000188000FF5E000000188000FF9D02 -:1005D0000000000C298000010000000C29520001DD -:1005E0000000000C295200000000000822800002D8 -:1005F000000000080200000E000000080280001A3F -:1006000000000010B1C40A0200000008020000034C -:100610000000000C1F800001000000002ADF000025 -:10062000000000002A000800000000188000FF51B0 -:100630000000000B2FDF00020000001091D400002A -:10064000000000082A000001000000002C2000002B -:100650000000001091D40000000000082C80000071 -:10066000000000082D000000000000082D80011C83 -:10067000000000188000FFA3000000082C80000686 -:10068000000000082D00000600000000308000007F -:100690000000000031000000000000082D8000066E -:1006A0000000000C298000010000000C1F800001E8 -:1006B0000000001091DE0000000000002ADF0000B2 -:1006C000000000082A000010000000080780000059 -:1006D000000000188000FF3C0000001091D40000D2 -:1006E00000000008050000AA000000188000FF8D2F -:1006F0000000000C298000010000000C1F80000198 -:10070000000000082A000009000000188000FF35E2 -:100710000000001091D40000000000080500005502 -:10072000000000188000FF860000001091A0B002B9 -:1007300000000010B1E662070000000B2FDF00028E -:10074000000000002C310000000000092CB1007FE7 -:10075000000000082CD90000000000082D00000057 -:10076000000000082D80010D00000010B1A8000657 -:1007700000000010205F0000000000002C2000009E -:10078000000000002CA70000000000082D00001051 -:10079000000000082D800108000000188000FF7E86 -:1007A00000000010B1A6001000000010001F0000A3 -:1007B0000000000F0F300007000000000A6000007A -:1007C000000000000AE100000000000F4B6200087A -:1007D000000000090B1600FF000000000D62000081 -:1007E000000000090D1A00FF000000100730000390 -:1007F0000000000C0D1A00080000000C0B16000889 -:100800000000000F4CE30018000000000C992C00C1 -:1008100000000004CC993400000000080F800000A4 -:100820000000000C298000010000000033310000AE -:100830000000000822000016000000002ADF00006F -:10084000000000082A00000C00000010009F0000BB -:10085000000000002C2000000000000C1F800001A0 -:10086000000000188000FF0A0000001091D4000072 -:1008700000000008050000AA000000188000FF5BCF -:100880000000000F4722000800000009070E000FBB -:1008900000000008070E00080000000802800001A8 -:1008A0000000000702851C0000000008828500018E -:1008B0000000000002854C000000000742851C007B -:1008C00000000003C3AA52000000000003B10E00A4 -:1008D000000000074B071C000000000F0F3000074E -:1008E0000000000F0A960003000000000A955C005B -:1008F000000000004A005A00000000000C960A00A8 -:10090000000000090C99FFFF000000080D00FFFF28 -:1009100000000010BA992C02000000080F800005AA -:1009200000000010B1A8000800000010205F0000C7 -:100930000000000B2FDF0002000000002C20000050 -:10094000000000002CA70000000000082D0000108F -:10095000000000082D800108000000188000FF46FC -:100960000000000C2980000100000010001F0000A2 -:100970000000000C1F800001000000002ADF0000C2 -:10098000000000082A00000D000000188000FEE5AD -:100990000000001091D40000000000080500005580 -:1009A000000000188000FF360000000C29800001C4 -:1009B0000000000C1F800001000000082A00000752 -:0809C000000000188000FEDEBB -:0809C80000000010B1800004E2 -:1009D0000000001F0306001100000008050000FFD2 -:1009E0000000001800020000000000002A000000C3 -:1009F00000000010B1D400000000001091DE0000E3 -:100A0000000000102053000000000010001F000034 -:100A10000000000C6BD70001000000002F80AA002E -:100A20000000000C298000010000000802540010A2 -:100A3000000000002C400000000000000F400000FB -:100A4000000000092952003F0000001800040000C7 -:100A50000000001880000011000000188000001243 -:100A600000000018800000470000001880000137D7 -:100A700000000018800001360000001880000135D9 -:100A80000000001880000135000000188000000000 -:100A9000000000188000014F0000001880000131A4 -:100AA00000000018800000000000001880000155C0 -:100AB00000000018800001A6000000188000006DF2 -:100AC00000000018800000E400000018800000E52D -:100AD000000000188000012A000000002A00000029 -:100AE000000000188000FFE2000000002A00000063 -:100AF0000000000C29800000000000188000FFDFCB -:100B00000000000003820000000000188000FFDAEF -:100B1000000000010C161400000000008C181400E6 -:100B20000000001091980003000000080C960002DD -:100B300000000010B1800003000000080C960001C6 -:100B4000000000000C000000000000000D19000073 -:100B5000000000080F8000010000000000000000FD -:100B600000000010001F00000000000C6BD7000107 -:100B700000000010011301F300000018000700003E -:100B8000000000000502000000000010B99A2C21AE -:100B900000000010205F0000000000002C1E00007C -:100BA000000000082C800006000000082D00000650 -:100BB000000000082D80010200000000000000007D -:100BC0000000001091DE0000000000000D61000038 -:100BD00000000018000A00000000000005020000EC -:100BE00000000010B99A2C1600000010205F0000D1 -:100BF0000000000009D80000000000002C1E0000CA -:100C0000000000082C80010E000000082D00000AE2 -:100C1000000000082D80010200000000000000001C -:100C20000000001091DE0000000000000D620000D6 -:100C3000000000002C13000000000018000A000053 -:100C4000000000000502000000000010B99A2C0905 -:100C500000000010205F0000000000002C1E0000BB -:100C6000000000082C800006000000082D00006A2B -:100C7000000000082D8001020000000000000000BC -:100C80000000001091DE0000000000000D7A00005E -:100C900000000018000A0000000000002A00000008 -:100CA0000000000822000001000000000D610000AB -:100CB0000000001021C2002800000010B1C6000290 -:100CC00000000010234200B3000000090B66FFFF84 -:100CD00000000010BA9A2C24000000000A640000F2 -:100CE000000000000AE50000000000000C00000009 -:100CF000000000000B800000000000080CC600127D -:100D0000000000188000FFD0000000080F800003E2 -:100D1000000000000000000000000010001F0000A4 -:100D20000000000C6BD70001000000082711001222 -:100D3000000000006690000000000010B198000460 -:100D400000000010001F00000000000C6BD7000125 -:100D5000000000080F8000040000000822000003CB -:100D6000000000082C80000C000000082D00000C82 -:100D700000000010001F00000000000C6BD70001F5 -:100D80000000001091C6000600000010001F0000C7 -:100D90000000000C6BD7000100000010BA9A2C0371 -:100DA000000000080F800004000000188000FFFC15 -:100DB00000000000259600000000000C29800000C3 -:100DC0000000000032140000000000003295000016 -:100DD0000000000573662C000000000031E32E00C7 -:100DE000000000082D800010000000188000FF8126 -:100DF00000000000230000000000000925E6FFFFBE -:100E0000000000082200000B0000000C69520000E6 -:100E10000000000C29800000000000188000FF7B0B -:100E2000000000002A000000000000082C800040A4 -:100E3000000000082D000020000000082D80011C8B -:100E400000000008220000010000001091DE0000F8 -:100E50000000000F42EA001000000010004F0004E4 -:100E600000000010B746920000000008024900127E -:100E700000000010B5840A00000000000D610000B1 -:100E800000000010BA6634640000000883050012F8 -:100E900000000010004F00020000000003490000A5 -:100EA0000000000183068C000000000083C60C00D7 -:100EB00000000010B1870013000000000B6E00005E -:100EC000000000090569FFFF00000010918A000280 -:100ED0000000000834E9FFFF000000188000FF60F8 -:100EE000000000010569140000000010918A000252 -:100EF00000000008B4E9000100000010BAE92C5518 -:100F00000000000086692C000000000002000000C4 -:100F10000000000902EAFFFF00000010000C0002C0 -:100F20000000000002040A000000000F460C00014F -:100F30000000000F0285000100000010918C01FCF0 -:100F400000000010B7040E4C000000000D6100000E -:100F5000000000000A640000000000000AE5000034 -:100F6000000000090B66FFFF000000000C000000FD -:100F7000000000000B800000000000080C8600123A -:100F8000000000080F8000030000000C2952000040 -:100F900000000010001F00000000000C6BD70001D3 -:100FA00000000008271100120000000066900000F9 -:100FB000000000002306000000000010B1980007A8 -:100FC00000000010001F00000000000C6BD70001A3 -:100FD000000000080F800004000000000000000076 -:100FE00000000010001F00000000000C6BD7000183 -:100FF00000000000321400000000000032950000E4 -:101000000000000031E32E000000000573662C0094 -:10101000000000002596000000000010B187001FAE -:101020000000000C298000000000000F0F6B00077B -:10103000000000000D690000000000000A6C0000C4 -:10104000000000000AED0000000000000B6E000030 -:10105000000000000B800000000000000C87000072 -:10106000000000188000FF2F000000010C16140083 -:10107000000000008C181400000000080C9600010D -:101080000000001091980002000000080C99000177 -:10109000000000000D190000000000000C0000001E -:1010A000000000080F800001000000102053000025 -:1010B0000000000C6952000100000010001F000039 -:1010C0000000000C6BD700010000000022C58C005E -:1010D00000000000231200000000000027110000A3 -:1010E000000000002690000000000010B8170E035A -:1010F0000000000C29800000000000188000FFEDB7 -:101100000000000082970E0000000000A3120A00F9 -:10111000000000082200001A000000082C80000CCB -:10112000000000082D00000C000000082D800010B9 -:1011300000000010001F00000000000C6BD7000131 -:10114000000000000D6E000000000003E7CF340037 -:101150000000000C298000000000001091DE00005B -:1011600000000010B18700070000000036140000E6 -:101170000000000036950000000000003716000057 -:10118000000000082C800050000000082D000030F6 -:10119000000000082D80000C000000188000FF0BEC -:1011A00000000000230000000000000925E6FFFF0A -:1011B000000000000B6E000000000003E7CF2C00D1 -:1011C000000000082200001B0000000C6952000013 -:1011D0000000000C29800000000000188000FF03C0 -:1011E000000000002A000000000000188000FF013D -:1011F000000000002A0000000000000C2980000010 -:101200000000001091DE0000000000082C80001A91 -:10121000000000082D00001A0000000573660000A1 -:10122000000000082D800002000000003180000056 -:101230000000001091DE0000000000082C80000C6F -:10124000000000082D00000C000000082D800004A4 -:10125000000000188000FEF400000008066600018F -:1012600000000010BA9A1972000000000A64000021 -:10127000000000000AE50000000000090B66FFFF07 -:10128000000000000C000000000000000B800000C7 -:10129000000000080CC60012000000188000FF1DAE -:1012A000000000080F8000030000000000000000A4 -:1012B00000000010001F00000000000C6BD70001B0 -:1012C00000000008271100120000000066900000D6 -:1012D00000000010919B32000000001002930000FB -:1012E00000000010B198000300000010001F000073 -:1012F0000000000C6BD70001000000080F80000404 -:101300000000000C2980000000000010001F0000F9 -:101310000000000C6BD7000100000010BA9A2C00EE -:101320000000000031E32E00000000000B800000F0 -:10133000000000008CCC8C0000000010B5CC8C02AA -:10134000000000080C800001000000188000FF076A -:10135000000000080F800003000000102053000070 -:101360000000000C695200010000000022C58C0042 -:1013700000000010001F00000000000C6BD70001EF -:10138000000000002711000000000000269000006F -:1013900000000000231B000000000010B1980003B3 -:1013A00000000010001F00000000000C6BD70001BF -:1013B000000000080F800004000000082200000365 -:1013C000000000082C80000C000000082D00000C1C -:1013D00000000010001F00000000000C6BD700018F -:1013E00000000000259600000000000C298000008D -:1013F00000000000321400000000000032950000E0 -:101400000000000573662C000000000031E32E0090 -:10141000000000082D800010000000188000FEBBB6 -:10142000000000188000FEBA000000002A00000042 -:1014300000000010001F00000000000C6BD700012E -:10144000000000000F008000000000080F8000076F -:10145000000000188000001C00000000280A0000A6 -:101460000000000005020000000000082200000942 -:1014700000000000290000000000000F6568001057 -:1014800000000000248A000000000003F66C9400B5 -:1014900000000010B972A0040000000C73E70019EE -:1014A0000000000C21420004000000003CF8000095 -:1014B0000000000C298000000000001020530000F4 -:1014C00000000008220000080000000C6142000437 -:1014D00000000018000A00000000000005020000E3 -:1014E0000000000C614200000000001001420003F7 -:1014F0000000000C33E7001D0000000C61420002F8 -:1015000000000018000A0000000000002A0000008F -:1015100000000010001F00000000000C6BD700014D -:101520000000000F0F470007000000080F800008B0 -:101530000000000C2980000000000010001F0000C7 -:101540000000000C6BD70001000000188000FE9521 -:101550000000000033510000000000002A000000DD -:1015600000000010B1C600250000000F0F5000075A -:10157000000000000A600000000000000AE1000016 -:101580000000000F4B620008000000090B1600FF6E -:101590000000000F4C620010000000000D6200000F -:1015A000000000090D1A00FF0000001007500003A2 -:1015B0000000000C0D1A00080000000C0B160008BB -:1015C000000000000CC60000000000000B800000BE -:1015D0000000000006980000000000080F800003D3 -:1015E0000000001006C200040000000C29000002E8 -:1015F00000000010264200020000000C29520003E7 -:10160000000000082200000100000010001F000080 -:101610000000000C6BD7000100000000231B00003D -:101620000000000027111A00000000006690000072 -:101630000000000C2952000000000010B197320A8F -:101640000000000C29800000000000000698000047 -:1016500000000010205300000000000C295200037D -:101660000000000022C58C0000000010001F0000D8 -:101670000000000C6BD70001000000080F80000381 -:10168000000000188000FFF100000010B1C8001336 -:1016900000000010B1C600030000000C298000000B -:1016A00000000010205300000000000C2952000030 -:1016B0000000000C295200030000001006C20002C6 -:1016C0000000000C295200020000000022C58C001E -:1016D00000000000276500000000000026E4000074 -:1016E000000000082200001600000010B1C6000330 -:1016F000000000002348000000000010B180000539 -:1017000000000000234800000000000C29800000B9 -:101710000000000F0F5000070000001880000012AA -:1017200000000008220000160000000C29800000C4 -:1017300000000000301400000000000030950000A0 -:101740000000001007500003000000090B1600FF06 -:10175000000000090D1A00FF0000000F31160008FC -:10176000000000003162340000000003F16230002C -:1017700000000010205F0000000000002C5100005D -:10178000000000092CD1007F000000082CD90000C7 -:10179000000000082D000000000000082D80000C53 -:1017A00000000000000000000000001091DE0000BA -:1017B0000000001005C20005000000080F800007AF -:1017C000000000003300000000000010001F0000B7 -:1017D0000000000C6BD70001000000188000FE43E1 -:1017E000000000002A0000000000000F0F5000075A -:1017F00000000010B1C600300000000F4742000892 -:1018000000000009070E000F00000008070E000886 -:1018100000000010001F00000000000C6BD700014A -:1018200000000008090000010000000709121C0068 -:1018300000000003CBCA9200000000000B97A2003A -:101840000000000742171C00000000000B0400000D -:101850000000000F0A840003000000000A959C00AD -:10186000000000004A009A000000000882120001F7 -:10187000000000010C170800000000000C978C000D -:101880000000000002180000000000080D00FFFF2B -:10189000000000080F8000060000000C2900000076 -:1018A0000000001006C200040000000C29520002D3 -:1018B00000000010264200020000000C2952000324 -:1018C000000000082200000100000010001F0000BE -:1018D0000000000C6BD7000100000010B197320D22 -:1018E00000000000231B000000000000271108007A -:1018F00000000000669000000000000C298000003D -:10190000000000000218000000000010205300003A -:101910000000000C295200030000000022C5360020 -:1019200000000010001F00000000000C6BD7000139 -:10193000000000080F800006000000188000FFF281 -:1019400000000000231B0000000000002711080019 -:10195000000000006690000000000010B1C8000BFD -:101960000000000C2980000000000010205300003F -:101970000000000C295200000000000C2952000356 -:101980000000001006C200020000000C29520002F4 -:101990000000000022C58C00000000002765000048 -:1019A0000000000026E400000000000023480000C2 -:1019B00000000008220000170000000C2980000031 -:1019C00000000010001F00000000000C6BD7000199 -:0819D000000000188000FE0475 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex deleted file mode 100644 index 0ed7f589118496bdf6dd6f96867bf06d90242f9d..0000000000000000000000000000000000000000 --- a/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex +++ /dev/null @@ -1,9484 +0,0 @@ -:1000000000003BB0000000680000070C00003C202E -:1000100000001AF8000043300000007C00005E3051 -:1000200000007A2C00005EB0000000B00000D8E0B4 -:10003000000080200000D99800000088000159C00D -:100040000000398800015A5000000090000193E040 -:100050000000AC040001947800000FFC0002408016 -:100060000000000400025080020400480000000F5D -:100070000204005400000045020400580000000083 -:100080000204005C0000000602040070000000048E -:1000900002040078000000000204007C1217000037 -:1000A00002040080221700000204008432170000BE -:1000B00006040088000000050204009C12150000E0 -:1000C000020400A022150000020400A43215000062 -:1000D000060400A800000004020400B8021000009A -:1000E000020400BC00100000020400C01010000058 -:1000F000020400C420100000020400C830100000F8 -:10010000060400CC00000004020400DC0010000023 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000060400EC00000004A1 -:100130000104012400000000010401280000000067 -:100140000104012C00000000010401300000000047 -:1001500002040004000000FF02040008000000FF89 -:100160000204000C000000FF02040010000000FF69 -:1001700002040014000000FF02040018000000FF49 -:100180000204001C000000FF02040020000000FF29 -:10019000020400240000003E0204002800000000C9 -:1001A0000204002C0000003F020400300000003F69 -:1001B000020400340000003F020400380000000088 -:1001C0000204003C0000003F020400400000003F29 -:1001D000020400440000003F020420080000021155 -:1001E0000204200C0000020002042010000002049F -:1001F00002042014000002190204201C0000FFFF6A -:10020000020420200000FFFF020420240000FFFF62 -:10021000020420280000FFFF0604203800000080B0 -:100220000204223807FFFFFF0204223C0000003FC7 -:100230000204224007FFFFFF020422440000000FD7 -:1002400001042248000000000104224C00000000CC -:1002500001042250000000000104225400000000AC -:1002600001042258000000000104225C000000008C -:10027000010422600000000001042264000000006C -:1002800001042268000000000104226C000000004C -:10029000010422700000000001042274000000002C -:1002A00001042278000000000104227C000000000C -:1002B000020424BC000000010C042000000003E83C -:1002C0000A042000000000010B0420000000000AC6 -:1002D0000605400000000D0002050044000000205B -:1002E00002050048000000320205009002150020BF -:1002F000020500940215002002050098000000305D -:100300000205009C08100000020500A00000003358 -:10031000020500A400000030020500A80000003122 -:10032000020500AC00000002020500B0000000055C -:10033000020500B400000006020500B8000000023B -:10034000020500BC00000002020500C00000000021 -:10035000020500C400000005020500C800000002FC -:10036000020500CC00000002020500D000000002DF -:10037000020500D400000001020501140000000184 -:100380000205011C0000000102050120000000021E -:1003900002050204000000010205020C00000040FA -:1003A00002050210000000400205021C00000020AF -:1003B00002050220000000130205022400000020B4 -:1003C000060502400000000A04050280002000002B -:1003D000020500500000000702050054000000075D -:1003E00002050058000000000205005C0000000843 -:1003F0000605006000000004020500D800000006A9 -:10040000020500E00000000D020500E40000002DE0 -:10041000020500E800000000020500EC00000020DA -:10042000020500F000000000020500F400000020BA -:10043000020500F800000000020500FC000000209A -:100440000205000400000001020500080000000190 -:100450000205000C00000001020500100000000170 -:100460000205001400000001020500180000000150 -:100470000205001C00000001020500200000000130 -:100480000205002400000001020500280000000110 -:100490000205002C000000010205003000000001F0 -:1004A00002050034000000010205003800000001D0 -:1004B0000205003C000000010205004000000001B0 -:1004C0000406100002000020020600DC000000010B -:1004D000010600D80000000004060200000302200C -:1004E000020600DC0000000002060068000000B800 -:1004F0000206007800000114010600B800000000A8 -:10050000010600C8000000000206006C000000B8F0 -:100510000206007C00000114010600BC000000007F -:10052000010600CC0000000007180400007B00005A -:100530000818076000140223071C00002A040000AA -:10054000071C800032110A82071D00001E0C1707CD -:10055000081D4550575602250118000000000000F4 -:10056000011800040000000001180008000000004D -:100570000118000C0000000001180010000000002D -:100580000118001400000000021800200000000103 -:1005900002180024000000020218002800000003D6 -:1005A0000218002C000000000218003000000004B7 -:1005B000021800340000000102180038000000009A -:1005C0000218003C00000001021800400000000476 -:1005D000021800440000000002180048000000015A -:1005E0000218004C00000003021800500000000038 -:1005F0000218005400000001021800580000000416 -:100600000218005C000000000218006000000001F9 -:1006100002180064000000030218006800000000D7 -:100620000218006C000000010218007000000004B5 -:100630000218007400000000021800780000000496 -:100640000218007C00000003061800800000000271 -:10065000021800A400003FFF021800A8000003FFDA -:1006600002180224000000000218023400000000FA -:100670000218024C00000000021802E4000000FF13 -:100680000618100000000400021B8BC000000001CF -:10069000021B800000000034021B80400000001894 -:1006A000021B80800000000C021B80C000000020A4 -:1006B0000C1B83000007A1200A1B830000000138E7 -:1006C0000B1B8300000013880A1B834000000000FE -:1006D0000C1B8340000001F40B1B8340000000054D -:1006E000021B83800007A120021B83C0000001F4CD -:1006F000061A100000000273041A19CC0001022728 -:10070000061A2008000000C8061A20000000000297 -:10071000041A499800040228061A2E280000000234 -:10072000061A2E2000000002061A0800000000022F -:10073000061A080800000004061A08180000000243 -:10074000041A08B00002022C061A2FD0000000067E -:10075000041A2FE80002022E041A2FC000040230EF -:10076000041A300000010234061A300400000003AD -:10077000041A301000010235061A3014000000037C -:10078000041A302000010236061A3024000000034B -:10079000041A303000010237061A3034000000031A -:1007A000041A304000010238061A304400000003E9 -:1007B000041A305000010239061A305400000003B8 -:1007C000041A30600001023A061A30640000000387 -:1007D000041A30700001023B061A30740000000356 -:1007E000041A30800001023C061A30840000000325 -:1007F000041A30900001023D061A309400000003F4 -:10080000041A30A00001023E061A30A400000003C2 -:10081000041A30B00001023F061A30B40000000391 -:10082000041A30C000010240061A30C40000000360 -:10083000041A30D000010241061A30D4000000032F -:10084000041A30E000010242061A30E400000003FE -:10085000041A30F000010243061A30F400000003CD -:10086000041A310000010244061A3104000000039A -:10087000041A311000010245061A31140000000369 -:10088000041A312000010246061A31240000000338 -:10089000041A313000010247061A31340000000307 -:1008A000041A314000010248061A314400000003D6 -:1008B000041A315000010249061A315400000003A5 -:1008C000041A31600001024A061A31640000000374 -:1008D000041A31700001024B061A31740000000343 -:1008E000041A31800001024C061A31840000000312 -:1008F000041A31900001024D061A319400000003E1 -:10090000041A31A00001024E061A31A400000003AF -:10091000041A31B00001024F061A31B4000000037E -:10092000041A31C000010250061A31C4000000034D -:10093000041A31D000010251061A31D4000000031C -:10094000041A31E000010252061A31E400000003EB -:10095000041A31F000010253061A31F400000003BA -:10096000041A320000010254061A32040000000387 -:10097000041A321000010255061A32140000000356 -:10098000041A322000010256061A32240000000325 -:10099000041A323000010257061A323400000003F4 -:1009A000041A324000010258061A324400000003C3 -:1009B000041A325000010259061A32540000000392 -:1009C000041A32600001025A061A32640000000361 -:1009D000041A32700001025B061A32740000000330 -:1009E000041A32800001025C061A328400000003FF -:1009F000041A32900001025D061A329400000003CE -:100A0000041A32A00001025E061A32A4000000039C -:100A1000041A32B00001025F061A32B4000000036B -:100A2000041A32C000010260061A32C4000000033A -:100A3000041A32D000010261061A32D40000000309 -:100A4000041A32E000010262061A32E400000003D8 -:100A5000041A32F000010263061A32F400000003A7 -:100A6000041A330000010264061A33040000000374 -:100A7000041A331000010265061A33140000000343 -:100A8000041A332000010266061A33240000000312 -:100A9000041A333000010267061A333400000003E1 -:100AA000041A334000010268061A334400000003B0 -:100AB000041A335000010269061A3354000000037F -:100AC000041A33600001026A061A3364000000034E -:100AD000041A33700001026B061A3374000000031D -:100AE000041A33800001026C061A338400000003EC -:100AF000041A33900001026D061A339400000003BB -:100B0000041A33A00001026E061A33A40000000389 -:100B1000041A33B00001026F061A33B40000000358 -:100B2000041A33C000010270061A33C40000000327 -:100B3000041A33D000010271061A33D400000003F6 -:100B4000041A33E000010272061A33E400000003C5 -:100B5000041A33F000010273061A33F40000000394 -:100B6000041A340000010274061A34040000000361 -:100B7000041A341000010275061A34140000000330 -:100B8000041A342000010276061A342400000003FF -:100B9000041A343000010277061A343400000003CE -:100BA000041A344000010278061A3444000000039D -:100BB000041A345000010279061A3454000000036C -:100BC000041A34600001027A061A3464000000033B -:100BD000041A34700001027B061A3474000000030A -:100BE000041A34800001027C061A348400000003D9 -:100BF000041A34900001027D061A349400000003A8 -:100C0000041A34A00001027E061A34A40000000376 -:100C1000041A34B00001027F061A34B40000000345 -:100C2000041A34C000010280061A34C40000000314 -:100C3000041A34D000010281061A34D400000003E3 -:100C4000041A34E000010282061A34E400000003B2 -:100C5000041A34F000010283061A34F40000000381 -:100C6000041A350000010284061A3504000000034E -:100C7000041A351000010285061A3514000000031D -:100C8000041A352000010286061A352400000003EC -:100C9000041A353000010287061A353400000003BB -:100CA000041A354000010288061A3544000000038A -:100CB000041A355000010289061A35540000000359 -:100CC000041A35600001028A061A35640000000328 -:100CD000041A35700001028B061A357400000003F7 -:100CE000041A35800001028C061A358400000003C6 -:100CF000041A35900001028D061A35940000000395 -:100D0000041A35A00001028E061A35A40000000363 -:100D1000041A35B00001028F061A35B40000000332 -:100D2000041A35C000010290061A35C40000000301 -:100D3000041A35D000010291061A35D400000003D0 -:100D4000041A35E000010292061A35E4000000039F -:100D5000041A35F000010293061A35F4000000036E -:100D6000041A360000010294061A3604000000033B -:100D7000041A361000010295061A3614000000030A -:100D8000041A362000010296061A362400000003D9 -:100D9000041A363000010297061A363400000003A8 -:100DA000041A364000010298061A36440000000377 -:100DB000041A365000010299061A36540000000346 -:100DC000041A36600001029A061A36640000000315 -:100DD000041A36700001029B061A367400000003E4 -:100DE000041A36800001029C061A368400000003B3 -:100DF000041A36900001029D061A36940000000382 -:100E0000041A36A00001029E061A36A40000000350 -:100E1000041A36B00001029F061A36B4000000031F -:100E2000041A36C0000102A0061A36C400000003EE -:100E3000041A36D0000102A1061A36D400000003BD -:100E4000041A36E0000102A2061A36E4000000038C -:100E5000041A36F0000102A3061A36F4000000035B -:100E6000041A3700000102A4061A37040000000328 -:100E7000041A3710000102A5061A371400000003F7 -:100E8000041A3720000102A6061A372400000003C6 -:100E9000041A3730000102A7061A37340000000395 -:100EA000041A3740000102A8061A37440000000364 -:100EB000041A3750000102A9061A37540000000333 -:100EC000041A3760000102AA061A37640000000302 -:100ED000041A3770000102AB061A377400000003D1 -:100EE000041A3780000102AC061A378400000003A0 -:100EF000041A3790000102AD061A3794000000036F -:100F0000041A37A0000102AE061A37A4000000033D -:100F1000041A37B0000102AF061A37B4000000030C -:100F2000041A37C0000102B0061A37C400000003DB -:100F3000041A37D0000102B1061A37D400000003AA -:100F4000041A37E0000102B2061A37E40000000379 -:100F5000041A37F0000102B3061A37F40000000348 -:100F6000041A3800000102B4061A38040000000315 -:100F7000041A3810000102B5061A381400000003E4 -:100F8000041A3820000102B6061A382400000003B3 -:100F9000041A3830000102B7061A38340000000382 -:100FA000041A3840000102B8061A38440000000351 -:100FB000041A3850000102B9061A38540000000320 -:100FC000041A3860000102BA061A386400000003EF -:100FD000041A3870000102BB061A387400000003BE -:100FE000041A3880000102BC061A3884000000038D -:100FF000041A3890000102BD061A3894000000035C -:10100000041A38A0000102BE061A38A4000000032A -:10101000041A38B0000102BF061A38B400000003F9 -:10102000041A38C0000102C0061A38C400000003C8 -:10103000041A38D0000102C1061A38D40000000397 -:10104000041A38E0000102C2061A38E40000000366 -:10105000041A38F0000102C3061A38F40000000335 -:10106000041A3900000102C4061A39040000000302 -:10107000041A3910000102C5061A391400000003D1 -:10108000041A3920000102C6061A392400000003A0 -:10109000041A3930000102C7061A3934000000036F -:1010A000041A3940000102C8061A3944000000033E -:1010B000041A3950000102C9061A3954000000030D -:1010C000041A3960000102CA061A396400000003DC -:1010D000041A3970000102CB061A397400000003AB -:1010E000041A3980000102CC061A3984000000037A -:1010F000041A3990000102CD061A39940000000349 -:10110000041A39A0000102CE061A39A40000000317 -:10111000041A39B0000102CF061A39B400000003E6 -:10112000041A39C0000102D0061A39C400000003B5 -:10113000041A39D0000102D1061A39D40000000384 -:10114000041A39E0000102D2061A39E40000000353 -:10115000041A39F0000102D3061A39F40000000322 -:10116000041A3A00000102D4061A3A0400000003EF -:10117000041A3A10000102D5061A3A1400000003BE -:10118000041A3A20000102D6061A3A24000000038D -:10119000041A3A30000102D7061A3A34000000035C -:1011A000041A3A40000102D8061A3A44000000032B -:1011B000041A3A50000102D9061A3A5400000003FA -:1011C000041A3A60000102DA061A3A6400000003C9 -:1011D000041A3A70000102DB061A3A740000000398 -:1011E000041A3A80000102DC061A3A840000000367 -:1011F000041A3A90000102DD061A3A940000000336 -:10120000041A3AA0000102DE061A3AA40000000304 -:10121000041A3AB0000102DF061A3AB400000003D3 -:10122000041A3AC0000102E0061A3AC400000003A2 -:10123000041A3AD0000102E1061A3AD40000000371 -:10124000041A3AE0000102E2061A3AE40000000340 -:10125000041A3AF0000102E3061A3AF4000000030F -:10126000041A3B00000102E4061A3B0400000003DC -:10127000041A3B10000102E5061A3B1400000003AB -:10128000041A3B20000102E6061A3B24000000037A -:10129000041A3B30000102E7061A3B340000000349 -:1012A000041A3B40000102E8061A3B440000000318 -:1012B000041A3B50000102E9061A3B5400000003E7 -:1012C000041A3B60000102EA061A3B6400000003B6 -:1012D000041A3B70000102EB061A3B740000000385 -:1012E000041A3B80000102EC061A3B840000000354 -:1012F000041A3B90000102ED061A3B940000000323 -:10130000041A3BA0000102EE061A3BA400000003F1 -:10131000041A3BB0000102EF061A3BB400000003C0 -:10132000041A3BC0000102F0061A3BC4000000038F -:10133000041A3BD0000102F1061A3BD4000000035E -:10134000041A3BE0000102F2061A3BE4000000032D -:10135000041A3BF0000102F3061A3BF400000003FC -:10136000041A3C00000102F4061A3C0400000003C9 -:10137000041A3C10000102F5061A3C140000000398 -:10138000041A3C20000102F6061A3C240000000367 -:10139000041A3C30000102F7061A3C340000000336 -:1013A000041A3C40000102F8061A3C440000000305 -:1013B000041A3C50000102F9061A3C5400000003D4 -:1013C000041A3C60000102FA061A3C6400000003A3 -:1013D000041A3C70000102FB061A3C740000000372 -:1013E000041A3C80000102FC061A3C840000000341 -:1013F000041A3C90000102FD061A3C940000000310 -:10140000041A3CA0000102FE061A3CA400000003DE -:10141000041A3CB0000102FF061A3CB400000003AD -:10142000041A3CC000010300061A3CC4000000037B -:10143000041A3CD000010301061A3CD4000000034A -:10144000041A3CE000010302061A3CE40000000319 -:10145000041A3CF000010303061A3CF400000003E8 -:10146000041A3D0000010304061A3D0400000003B5 -:10147000041A3D1000010305061A3D140000000384 -:10148000041A3D2000010306061A3D240000000353 -:10149000041A3D3000010307061A3D340000000322 -:1014A000041A3D4000010308061A3D4400000003F1 -:1014B000041A3D5000010309061A3D5400000003C0 -:1014C000041A3D600001030A061A3D64000000038F -:1014D000041A3D700001030B061A3D74000000035E -:1014E000041A3D800001030C061A3D84000000032D -:1014F000041A3D900001030D061A3D9400000003FC -:10150000041A3DA00001030E061A3DA400000003CA -:10151000041A3DB00001030F061A3DB40000000399 -:10152000041A3DC000010310061A3DC40000000368 -:10153000041A3DD000010311061A3DD40000000337 -:10154000041A3DE000010312061A3DE40000000306 -:10155000041A3DF000010313061A3DF400000003D5 -:10156000041A3E0000010314061A3E0400000003A2 -:10157000041A3E1000010315061A3E140000000371 -:10158000041A3E2000010316061A3E240000000340 -:10159000041A3E3000010317061A3E34000000030F -:1015A000041A3E4000010318061A3E4400000003DE -:1015B000041A3E5000010319061A3E5400000003AD -:1015C000041A3E600001031A061A3E64000000037C -:1015D000041A3E700001031B061A3E74000000034B -:1015E000041A3E800001031C061A3E84000000031A -:1015F000041A3E900001031D061A3E9400000003E9 -:10160000041A3EA00001031E061A3EA400000003B7 -:10161000041A3EB00001031F061A3EB40000000386 -:10162000041A3EC000010320061A3EC40000000355 -:10163000041A3ED000010321061A3ED40000000324 -:10164000041A3EE000010322061A3EE400000003F3 -:10165000041A3EF000010323061A3EF400000003C2 -:10166000041A3F0000010324061A3F04000000038F -:10167000041A3F1000010325061A3F14000000035E -:10168000041A3F2000010326061A3F24000000032D -:10169000041A3F3000010327061A3F3400000003FC -:1016A000041A3F4000010328061A3F4400000003CB -:1016B000041A3F5000010329061A3F54000000039A -:1016C000041A3F600001032A061A3F640000000369 -:1016D000041A3F700001032B061A3F740000000338 -:1016E000041A3F800001032C061A3F840000000307 -:1016F000041A3F900001032D061A3F9400000003D6 -:10170000041A3FA00001032E061A3FA400000003A4 -:10171000041A3FB00001032F061A3FB40000000373 -:10172000041A3FC000010330061A3FC40000000342 -:10173000041A3FD000010331061A3FD40000000311 -:10174000041A3FE000010332061A3FE400000007DC -:10175000041A4CB000080333061A400000000124AC -:10176000021A492000000000061A2500000000109F -:10177000061A258000000012061A09C00000004861 -:10178000061A080000000002061A082000000012D5 -:10179000041A2FB00002033B041A4CF00002033D70 -:1017A000061A500000000004061A449000000124AC -:1017B000021A492400000000061A2540000000100B -:1017C000061A25C800000012061A0AE000000048A8 -:1017D000061A081000000002061A0868000000122D -:1017E000041A2FB80002033F041A4CF80002034108 -:1017F000061A5010000000040200A468000AFFDC72 -:101800000200A280000000010200A294071D29111D -:101810000200A298000000000200A29C009C042488 -:101820000200A2A0000000000200A2A40000020921 -:101830000200A4FCFF000000020100B4000000014F -:10184000020100B800000001020100DC00000001FC -:10185000020101000000000102010104000000017A -:101860000201007C0030000002010084000000281A -:101870000201008C000000000201013000000004A1 -:101880000201025C000000010201032800000000C8 -:101890000201055400000030020100C400000001F4 -:1018A000020100CC00000001020100F8000000016C -:1018B000020100F000000001020100800030000081 -:1018C00002010088000000280201009000000000D2 -:1018D0000201013400000004020102DC00000001EA -:1018E0000201032C0000000002010564000000302A -:1018F000020100C800000001020100D00000000148 -:10190000020100FC00000001020100F400000001DF -:10191000020C100000000028020C200800000A1130 -:10192000020C200C00000A00020C201000000A0427 -:10193000020C201C0000FFFF020C20200000FFFF13 -:10194000020C20240000FFFF020C20280000FFFFF3 -:10195000020C203800000020020C203C0000002176 -:10196000020C204000000022020C20440000002352 -:10197000020C204800000024020C204C000000252E -:10198000020C205000000026020C2054000000270A -:10199000020C205800000028020C205C00000029E6 -:1019A000020C20600000002A020C20640000002BC2 -:1019B000020C20680000002C020C206C0000002D9E -:1019C000020C20700000002E020C20740000002F7A -:1019D000020C207800000010060C207C0000004F54 -:1019E000020C21B800000001020C21BC0000000123 -:1019F000020C21C000000001020C21C40000000103 -:101A0000020C21C800000001020C21CC00000001E2 -:101A1000020C21D000000001020C21D400000001C2 -:101A2000020C21D800000001020C21DC00000001A2 -:101A3000020C21E000000001020C21E40000000182 -:101A4000020C21E800000001020C21EC0000000162 -:101A5000020C21F000000001020C21F40000000142 -:101A6000020C21F800000001060C21FC0000000F10 -:101A7000020C223807FFFFFF020C223C0000003F4F -:101A8000020C224007FFFFFF020C22440000000F5F -:101A9000010C224800000000010C224C0000000054 -:101AA000010C225000000000010C22540000000034 -:101AB000010C225800000000010C225C0000000014 -:101AC000010C226000000000010C226400000000F4 -:101AD000010C226800000000010C226C00000000D4 -:101AE000010C227000000000010C227400000000B4 -:101AF000010C227800000000010C227C0000000094 -:101B0000020C24BC000000010C0C2000000003E8C3 -:101B10000A0C2000000000010B0C20000000000A4D -:101B2000020C400800000562020C400C0000055148 -:101B3000020C401000000555020C40140000057214 -:101B4000020C401C0000FFFF020C40200000FFFFC1 -:101B5000020C40240000FFFF020C40280000FFFFA1 -:101B6000020C403800000046020C403C0000000C13 -:101B7000060C40400000005E020C41B8000000016D -:101B8000060C41BC0000001F020C423807FFFFFF9B -:101B9000020C423C0000003F020C424007FFFFFFE6 -:101BA000020C42440000000F010C424800000000FB -:101BB000010C424C00000000010C425000000000EB -:101BC000010C425400000000010C425800000000CB -:101BD000010C425C00000000010C426000000000AB -:101BE000010C426400000000010C4268000000008B -:101BF000010C426C00000000010C4270000000006B -:101C0000010C427400000000010C4278000000004A -:101C1000010C427C00000000010C4280000000002A -:101C2000020C44C0000000010C0C4000000003E85E -:101C30000A0C4000000000010B0C40000000000AEC -:101C4000060D400000000A00020D004400000032B2 -:101C5000020D008C02150020020D009002150020DC -:101C6000020D009408100000020D009800000033DF -:101C7000020D009C00000002020D00A00000000008 -:101C8000020D00A400000005020D00A800000005E0 -:101C9000060D00AC00000002020D00B400000002BE -:101CA000020D00B800000003020D00BC000000029D -:101CB000020D00C000000001020D00C8000000027B -:101CC000020D00CC00000002020D015C00000001CA -:101CD000020D016400000001020D01680000000215 -:101CE000020D020400000001020D020C00000020A1 -:101CF000020D021000000040020D0214000000401E -:101D0000020D022000000003020D02240000001852 -:101D1000060D028000000012040D030000180343AA -:101D2000060D03600000000C020D004C00000001D5 -:101D3000020D005000000002020D005400000000DF -:101D4000020D005800000008060D005C00000004B1 -:101D5000020D00C400000004020D0114000000097F -:101D6000020D011800000029020D011C0000000AEC -:101D7000020D01200000002A020D012400000000D5 -:101D8000020D012800000020020D012C00000000BF -:101D9000020D013000000020020D0134000000009F -:101DA000020D013800000020020D013C000000007F -:101DB000020D014000000020020D0144000000005F -:101DC000020D014800000020020D00040000000187 -:101DD000020D000800000001020D000C00000001CF -:101DE000020D001000000001020D001400000001AF -:101DF000020D001800000001020D001C000000018F -:101E0000020D002000000001020D0024000000016E -:101E1000020D002800000001020D002C000000014E -:101E2000020D003000000001020D0034000000012E -:101E3000020D003800000001020D003C000000010E -:101E4000060E200000000800020E004C00000032C8 -:101E5000020E009402150020020E009802150020C8 -:101E6000020E009C00000030020E00A008100000CE -:101E7000020E00A400000033020E00A80000003093 -:101E8000020E00AC00000031020E00B000000002A3 -:101E9000020E00B400000004020E00B800000000B2 -:101EA000020E00BC00000002020E00C00000000292 -:101EB000020E00C400000000020E00C80000000274 -:101EC000020E00CC00000007020E00D0000000024D -:101ED000020E00D400000002020E00D80000000133 -:101EE000020E014400000001020E014C000000013E -:101EF000020E015000000002020E02040000000168 -:101F0000020E020C00000040020E02100000004011 -:101F1000020E021C00000004020E0220000000203D -:101F2000020E02240000000E020E02280000001B18 -:101F3000060E030000000012040E0280001B035B6B -:101F4000060E02EC00000005020E00540000000C1A -:101F5000020E00580000000C020E005C00000000A1 -:101F6000020E006000000010060E00640000000475 -:101F7000020E00DC00000003020E01100000000F42 -:101F8000020E01140000002F020E011800000000D4 -:101F9000020E011C00000020020E000400000001DF -:101FA000020E000800000001020E000C00000001FB -:101FB000020E001000000001020E001400000001DB -:101FC000020E001800000001020E001C00000001BB -:101FD000020E002000000001020E0024000000019B -:101FE000020E002800000001020E002C000000017B -:101FF000020E003000000001020E0034000000015B -:10200000020E003800000001020E003C000000013A -:10201000020E004000000001020E0044000000011A -:102020000730040000AF0000083007680013037693 -:10203000073400003305000007348000327F0CC2F3 -:10204000073500001A951962083539E058C403783D -:10205000013000000000000001300004000000001A -:1020600001300008000000000130000C00000000FA -:1020700001300010000000000130001400000000DA -:1020800002300020000000010230002400000002A5 -:1020900002300028000000030230002C0000000085 -:1020A0000230003000000004023000340000000163 -:1020B00002300038000000000230003C0000000147 -:1020C0000230004000000004023000440000000024 -:1020D00002300048000000010230004C0000000304 -:1020E00002300050000000000230005400000001E7 -:1020F00002300058000000040230005C00000000C4 -:1021000002300060000000010230006400000003A3 -:1021100002300068000000000230006C0000000186 -:102120000230007000000004023000740000000063 -:1021300002300078000000040230007C0000000340 -:102140000630008000000002023000A400003FFFC3 -:10215000023000A8000003FF02300224000000004B -:1021600002300234000000000230024C0000000087 -:10217000023002E40000FFFF0630200000000800EB -:1021800002338BC000000001023380000000001AFF -:10219000023380400000004E0233808000000010B7 -:1021A000023380C0000000200C3383000007A12010 -:1021B0000A338300000001380B33830000001388CA -:1021C0000A338340000000000C338340000001F418 -:1021D0000B33834000000005023383800007A120F9 -:1021E000023383C0000001F406322A88000000C2D6 -:1021F00006322008000000C806322000000000025D -:10220000063223E80000004004322E580004037A0E -:10221000063250A000000004063250B80000000250 -:102220000632508000000006043250980002037EFF -:10223000063250000000002006323000000004008A -:1022400006321C0000000004043218300002038033 -:10225000063224E8000000B402322DB00000000075 -:1022600006324000000000B40632300000000020BA -:10227000063231000000002006323200000000204B -:102280000632330000000020063234000000002037 -:102290000632350000000020063236000000002023 -:1022A000063237000000002006323800000000200F -:1022B000063239000000002006323A0000000020FB -:1022C00006323B000000002006323C0000000020E7 -:1022D00006323D000000002006323E0000000020D3 -:1022E00006323F000000002006321C1000000002F1 -:1022F000063245A000000024063227B8000000B4D2 -:1023000002322DB400000000063242D0000000B4BA -:1023100006323080000000200632318000000020AC -:102320000632328000000020063233800000002098 -:102330000632348000000020063235800000002084 -:102340000632368000000020063237800000002070 -:10235000063238800000002006323980000000205C -:1023600006323A800000002006323B800000002048 -:1023700006323C800000002006323D800000002034 -:1023800006323E800000002006323F800000002020 -:1023900006321C20000000020632463000000024F5 -:1023A0000720040000870000082007800010038237 -:1023B000072400003165000007248000081D0C5A26 -:1023C00008248EB06C9003840120000000000000FF -:1023D00001200004000000000120000800000000AF -:1023E0000120000C0000000001200010000000008F -:1023F0000120001400000000022000200000000165 -:102400000220002400000002022000280000000337 -:102410000220002C00000000022000300000000418 -:1024200002200034000000010220003800000000FB -:102430000220003C000000010220004000000004D7 -:1024400002200044000000000220004800000001BB -:102450000220004C00000003022000500000000099 -:102460000220005400000001022000580000000477 -:102470000220005C0000000002200060000000015B -:102480000220006400000003022000680000000039 -:102490000220006C00000001022000700000000417 -:1024A00002200074000000000220007800000004F8 -:1024B0000220007C000000030620008000000002D3 -:1024C000022000A400003FFF022000A8000003FF3C -:1024D000022002240000000002200234000000005C -:1024E0000220024C00000000022002E40000FFFF76 -:1024F000062020000000080002238BC0000000011D -:10250000022380000000001002238040000000121F -:102510000223808000000030022380C00000000EF3 -:102520000C2383000007A1200A2383000000013848 -:102530000B238300000013880A238340000000005F -:102540000C238340000001F40B23834000000005AE -:10255000022383800007A120022383C0000001F42E -:10256000062250000000004206222008000000C899 -:10257000062220000000000206224000000000C6E3 -:1025800004224318000503860622432C0000000B9A -:10259000042243580005038B0622436C0000000B05 -:1025A0000422439800050390062243AC0000000B70 -:1025B000042243D800050395062243EC0000000BDB -:1025C000042244180005039A0622442C0000000B44 -:1025D000042244580005039F0622446C0000000BAF -:1025E00004224498000503A4062244AC0000000B1A -:1025F000042244D8000503A9062244EC0000000B85 -:1026000004224518000503AE0622452C0000000BED -:1026100004224558000503B30622456C0000000B58 -:1026200004224598000503B8062245AC0000000BC3 -:10263000042245D8000503BD062245EC0000000B2E -:1026400004224618000503C20622462C0000000B97 -:1026500004224658000503C70622466C0000000B02 -:1026600004224698000503CC062246AC0000000B6D -:10267000042246D8000503D1062246EC0000000BD8 -:1026800004224718000503D60622472C0000000B41 -:1026900004224758000503DB0622476C0000000BAC -:1026A00004224798000503E0062247AC0000000B17 -:1026B000042247D8000503E5062247EC0000000B82 -:1026C00004224818000503EA0622482C0000000BEB -:1026D00004224858000503EF0622486C0000000B56 -:1026E00004224898000503F4062248AC0000000BC1 -:1026F000042248D8000503F9062248EC0000000B2C -:1027000004224918000503FE0622492C0000000B94 -:1027100004224958000504030622496C0000000BFE -:102720000422499800050408062249AC0000000B69 -:10273000042249D80005040D062249EC0000000BD4 -:1027400004224A180005041206224A2C0000000B3D -:1027500004224A580005041706224A6C0000000BA8 -:1027600004224A980005041C06224AAC0000000B13 -:1027700004224AD80005042106224AEC0000000584 -:1027800006224B000000001704224B5C00010426C7 -:1027900006224B600000000304224B6C000104275A -:1027A000062238000000004006223000000002002F -:1027B000042251C00004042806221000000000C0BA -:1027C000062215C00000024004221EC80008042C86 -:1027D0000622390000000008022251180000000003 -:1027E000062251D00000000606221300000000025D -:1027F00006221410000000300622392000000008D4 -:102800000222511C00000000062251E800000006D0 -:102810000622130800000002062214D00000003037 -:102820000216100000000028021700080000000235 -:102830000217002C000000030217003C00000004F7 -:1028400002170044000000000217004800000002C8 -:102850000217004C0000009002170050000000908A -:102860000217005400800090021700580810000062 -:10287000021700600000008A021700640000008058 -:1028800002170068000000810217006C0000008041 -:10289000021700700000000602170078000007D041 -:1028A0000217007C0000076C02170038007C10043F -:1028B000021700040000000F06164024000000026A -:1028C000021640700000001C0216420800000001C1 -:1028D0000216421000000001021642200000000112 -:1028E00002164228000000010216423000000001DA -:1028F000021642380000000102164260000000018A -:102900000C16401C0003D0900A16401C0000009CCE -:102910000B16401C000009C40216403000000008DD -:10292000021640340000000C02164038000000106F -:102930000216404400000020021640000000000182 -:10294000021640D8000000010216400800000001F5 -:102950000216400C000000010216401000000001A9 -:10296000021642400000000002164248000000002B -:1029700006164270000000020216425000000000DD -:1029800002164258000000000616428000000002B5 -:1029900002166008000006140216600C0000060013 -:1029A00002166010000006040216601C0000FFFF03 -:1029B000021660200000FFFF021660240000FFFFE7 -:1029C000021660280000FFFF021660380000002099 -:1029D0000216603C00000020061660400000000265 -:1029E00002166048000000230216604C000000241C -:1029F00002166050000000250216605400000026F8 -:102A000002166058000000270216605C00000029D2 -:102A1000021660600000002A021660640000002BAD -:102A2000021660680000002C0216606C0000002D89 -:102A30000616607000000012021660B80000000167 -:102A4000021660BC00000001061660C00000003ED7 -:102A5000021661B800000001061661BC0000001FEC -:102A60000216623807FFFFFF0216623C0000003FBB -:102A70000216624007FFFFFF021662440000000FCB -:102A800001166248000000000116624C00000000C0 -:102A900001166250000000000116625400000000A0 -:102AA00001166258000000000116625C0000000080 -:102AB0000116626000000000011662640000000060 -:102AC00001166268000000000116626C0000000040 -:102AD0000116627000000000011662740000000020 -:102AE00001166278000000000116627C0000000000 -:102AF000021664BC000000010C166000000003E830 -:102B00000A166000000000010B1660000000000AB9 -:102B100002168040000000060216804400000005F6 -:102B2000021680480000000A0216804C00000005D2 -:102B30000216805400000002021680CC000000043F -:102B4000021680D000000004021680D400000004A9 -:102B5000021680D800000004021680DC0000000489 -:102B6000021680E000000004021680E40000000469 -:102B7000021680E800000004021688040000000429 -:102B8000021680300000007C021680340000003DF8 -:102B9000021680380000003F0216803C0000009CB6 -:102BA000021680F000000007061680F40000000501 -:102BB0000216880C010101010216810800000000C4 -:102BC0000216810C000000040216811000000004AF -:102BD0000216811400000002021688100801200469 -:102BE00002168118000000050216811C0000000575 -:102BF0000216812000000005021681240000000555 -:102C00000216882C200810010216812800000008F6 -:102C10000216812C00000006021681300000000719 -:102C200002168134000000000216883001010120E4 -:102C300006168138000000040216883401010101E3 -:102C400006168148000000040216883801010101BF -:102C500006168158000000040216883C010101019B -:102C6000061681680000000302168174000000014E -:102C7000021688400101010102168178000000015E -:102C80000216817C00000001021681800000000114 -:102C9000021681840000000102168844010101012E -:102CA00002168188000000010216818C00000004D9 -:102CB00002168190000000040216819400000002B8 -:102CC00002168848080120040216819800000005B9 -:102CD0000216819C00000005021681A0000000057C -:102CE000021681A4000000050216881420081001B5 -:102CF000021681A800000008021681AC0000000640 -:102D0000021681B000000007021681B40000000125 -:102D10000216881801010120021681B80000000186 -:102D2000021681BC00000001021681C000000001F3 -:102D3000021681C4000000010216881C0101010175 -:102D4000021681C800000001021681CC00000001BB -:102D5000021681D000000001021681D4000000019B -:102D60000216882001010101021681D8000000012D -:102D7000021681DC00000001021681E00000000163 -:102D8000021681E4000000010216882401010101FD -:102D9000021681E800000001021681EC000000012B -:102DA000021681F0000000010216882801010101CD -:102DB00002168240FFFF003F061682440000000218 -:102DC0000216824CFFFF003F0216825000000100F5 -:102DD000021682540000010006168258000000020C -:102DE00002168260000000C002168264000000C06B -:102DF0000216826800001E000216826C00001E008F -:102E0000021682700000400002168274000040002A -:102E100002168278000080000216827C000080008A -:102E2000021682800000200002168284000020002A -:102E30000616828800000007021682A40000000126 -:102E4000061682A80000000A021681F400000C0891 -:102E5000021681F800000040021681FC000001000B -:102E600002168200000000200216820400000017F3 -:102E700002168208000000800216820C0000020088 -:102E8000021682100000000002168218FFFF01FFE8 -:102E900002168214FFFF01FF0216823C000000139D -:102EA000021680900000013F021680600000014081 -:102EB00002168064000001400616806800000002CF -:102EC00002168070000000C0061680740000000723 -:102ED0000216809C00000048021680A000000048F6 -:102EE000061680A400000002021680AC0000004814 -:102EF000061680B00000000702168238000080002D -:102F000002168234000025E40216809400007FFF40 -:102F100002168220000000070216821C0000000733 -:102F2000021682280000000002168224FFFFFFFF25 -:102F300002168230000000000216822CFFFFFFFF05 -:102F4000021680EC000000FF0214000000000001E7 -:102F50000214000C000000010214004000000001F7 -:102F60000214004400007FFF0214000C0000000067 -:102F700002140000000000000214006C00000000B9 -:102F800002140004000000010214003000000001DF -:102F900002140004000000000214005C00000000A5 -:102FA00002140008000000010214003400000001B7 -:102FB000021400080000000002140060000000007D -:102FC00006028000000020000202005800000032CB -:102FD000020200A003150020020200A40315002035 -:102FE000020200A801000030020200AC081000003C -:102FF000020200B000000033020200B40000003002 -:10300000020200B800000031020200BC0000000310 -:10301000020200C000000006020200C4000000031B -:10302000020200C800000003020200CC00000002FF -:10303000020200D000000000020200D400000002E2 -:10304000020200DC00000000020200E000000006B6 -:10305000020200E400000004020200E80000000296 -:10306000020200EC00000002020200F00000000179 -:10307000020200FC00000006020201200000000025 -:103080000202013400000002020201B0000000014F -:103090000202020C00000001020202140000000102 -:1030A00002020218000000020202040400000001F3 -:1030B0000202040C00000040020204100000004064 -:1030C0000202041C00000004020204200000002090 -:1030D0000202042400000002020204280000001F73 -:1030E00006020500000000120402048000200434DF -:1030F000020200600000000F0202006400000007EE -:1031000002020068000000000202006C0000000ED5 -:103110000602007000000004020200F40000000437 -:103120000202000400000001020200080000000189 -:103130000202000C00000001020200100000000169 -:103140000202001400000001020200180000000149 -:103150000202001C00000001020200200000000129 -:103160000202002400000001020200280000000109 -:103170000202002C000000010202003000000001E9 -:1031800002020034000000010202003800000001C9 -:103190000202003C000000010202004000000001A9 -:1031A0000202004400000001020200480000000189 -:1031B0000202004C00000001020200500000000169 -:1031C00002020108000000C802020118000000020B -:1031D000020201C400000000020201CC0000000055 -:1031E000020201D400000002020201DC0000000221 -:1031F000020201E4000000FF020201EC000000FFF7 -:103200000202010C000000C80202011C00000002C2 -:10321000020201C800000000020201D0000000000C -:10322000020201D800000002020201E000000002D8 -:10323000020201E8000000FF020201F0000000FFAE -:1032400007280400008E00000828076800130454B3 -:10325000072C000033C80000072C800038050CF351 -:10326000072D000038B61AF5072D800007762923B0 -:10327000082D8CB04E6A04560128000000000000A2 -:1032800001280004000000000128000800000000E0 -:103290000128000C000000000128001000000000C0 -:1032A0000128001400000000022800200000000196 -:1032B0000228002400000002022800280000000369 -:1032C0000228002C0000000002280030000000044A -:1032D000022800340000000102280038000000002D -:1032E0000228003C00000001022800400000000409 -:1032F00002280044000000000228004800000001ED -:103300000228004C000000030228005000000000CA -:1033100002280054000000010228005800000004A8 -:103320000228005C0000000002280060000000018C -:10333000022800640000000302280068000000006A -:103340000228006C00000001022800700000000448 -:103350000228007400000000022800780000000429 -:103360000228007C00000003062800800000000204 -:10337000022800A400003FFF022800A8000003FF6D -:10338000022802240000000002280234000000008D -:103390000228024C00000000022802E40000FFFFA7 -:1033A0000628200000000800022B8BC0000000014E -:1033B000022B800000000000022B8040000000185B -:1033C000022B80800000000C022B80C000000066F1 -:1033D0000C2B83000007A1200A2B8300000001387A -:1033E0000B2B8300000013880A2B83400000000091 -:1033F0000C2B8340000001F40B2B834000000005E0 -:10340000022B83800007A120022B83C0000001F45F -:10341000062A3D4800000004042A3D5800020458D2 -:10342000062A3D6000000006062A30000000004821 -:10343000062A2008000000C8062A2000000000021A -:10344000062A31280000008E062A33680000000397 -:10345000042A33740001045A062A3A780000000254 -:10346000042A3A800002045B042A3A700002045DD8 -:10347000042A3E280002045F042A3EB000040461CE -:10348000042A250000020465062A25080000010020 -:10349000062A297000000004042A29600004046739 -:1034A000042A2F480002046B062A3378000000D853 -:1034B000022A3A3800000000062A3A88000000324A -:1034C000042A3D880010046D062A502000000002E6 -:1034D000062A503000000002062A500000000002B8 -:1034E000062A501000000002022A50B80000000115 -:1034F000062A50480000000E042A3D780002047D90 -:10350000062A3C1800000026022A50400000000055 -:10351000062A36D8000000D8022A3A3C00000000F3 -:10352000062A3B5000000032042A3DC80010047FE8 -:10353000062A502800000002062A50380000000227 -:10354000062A500800000002062A50180000000257 -:10355000022A50BC00000001062A50800000000E24 -:10356000042A3D800002048F062A3CB00000002699 -:10357000022A504400000000021010080000000160 -:103580000210101000000264021010000003D000AE -:10359000021010040000003D091018000200049100 -:1035A00009101100001006910610114000000008DB -:1035B00009101160000806A1061011800000000229 -:1035C00009101188000606A9061011A000000018B5 -:1035D000021010100000000006102400000000E09F -:1035E0000210201C0000000002102020000000013A -:1035F000021020C0000000010210200400000001A1 -:10360000021020080000000109103C00000506AF70 -:1036100009103C20000506B409103800000506B961 -:1036200002104028000000100210404400003FFF3C -:103630000210405800280000021040840084924A82 -:1036400006104C000000010002104058000000006D -:103650000610806800000004021080000000108046 -:1036600006108028000000020210803800000010C0 -:10367000021080400000FFFF021080440000FFFFA6 -:1036800002108050000000000210810000000000C5 -:10369000061081200000000202108008000002B520 -:1036A0000210801000000000061082000000004A96 -:1036B000021081080001FFFF061081400000000297 -:1036C0000210800000001A80061090000000002404 -:1036D000061091200000004A061093700000004A76 -:1036E000061095C00000004A0210800400001080FF -:1036F00006108030000000020210803C0000001024 -:10370000021080480000FFFF0210804C0000FFFF05 -:10371000021080540000000002108104000000002C -:1037200006108128000000020210800C000002B583 -:103730000210801400000000061084000000004AFF -:103740000210810C0001FFFF0610814800000002FA -:103750000210800400001A800610909000000024DF -:10376000061092480000004A061094980000004A93 -:10377000061096E80000004A0212049000E383401D -:103780000212051400003C10021205200000000285 -:1037900002120494FFFFFFFF02120498FFFFFFFFD5 -:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5 -:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95 -:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75 -:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D -:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D -:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D -:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4 -:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC -:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C -:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C -:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C -:1038500002120500FFFFFFFF02120504FFFFFFFF3A -:1038600002120508FFFFFFFF0212050CFFFFFFFF1A -:1038700002120510FFFFFFFF021204D4FFFF3330D6 -:10388000021204D8FFFF3340021204B4F0003000EB -:1038900002120390000000080212039C00000008BE -:1038A000061203A000000002021203BC0000000484 -:1038B000021203C400000004021203D00000000042 -:1038C000021203DC000000000212036C0000000181 -:1038D000021203680000003F021201BC0000004019 -:1038E000021201C000001808021201C400000803FF -:1038F000021201C800000803021201CC00000040BF -:10390000021201D000000003021201D400000803DB -:10391000021201D800000803021201DC00000803B3 -:10392000021201E000010003021201E4000008039A -:10393000021201E800000803021201EC000000037B -:10394000021201F000000003021201F40000000363 -:10395000021201F800000003021201FC0000000343 -:103960000212020000000003021202040000000321 -:1039700002120208000000030212020C0000000301 -:1039800002120210000000030212021400000003E1 -:1039900002120218000000030212021C00000003C1 -:1039A00002120220000000030212022400000003A1 -:1039B00002120228000024030212022C0000002F31 -:1039C0000212023000000009021202340000001945 -:1039D00002120238000001840212023C000001833E -:1039E0000212024000000306021202440000001905 -:1039F00002120248000000060212024C00000306F8 -:103A000002120250000003060212025400000306D4 -:103A10000212025800000C860212025C000003062B -:103A20000212026000000306021202640000000697 -:103A300002120268000000060212026C000000067A -:103A4000021202700000000602120274000000065A -:103A500002120278000000060212027C000000063A -:103A6000021202800000000602120284000000061A -:103A700002120288000000060212028C00000006FA -:103A800002120290000000060212029400000006DA -:103A900002120298000000060212029C00000006BA -:103AA000021202A000000306021202A4000000138A -:103AB000021202A800000006021202B00000100468 -:103AC000021202B400001004021203240010644029 -:103AD0000212032800106440021201B0000000012D -:103AE0000600A000000000160200A06CBF5C0000F1 -:103AF0000200A070FFF51FEF0200A0740000FFFF9E -:103B00000200A078F00003E00200A07C00000000AA -:103B10000200A0800000A0000600A08400000005B4 -:103B20000200A0980FE000000600A09C0000001416 -:103B30000200A0EC555400000200A0F05555555568 -:103B40000200A0F4000055550200A0F8F0000000AB -:103B50000200A0FC555400000200A1005555555527 -:103B60000200A104000055550200A108F000000069 -:103B70000600A22C000000040200A0600000030761 -:103B80000200A10CBF5C00000200A110FFF51FEFB6 -:103B90000200A1140000FFFF0200A118F00003E0E2 -:103BA0000200A11C000000000200A1200000A000F3 -:103BB0000600A124000000050200A1380FE000006B -:103BC0000600A13C000000140200A18C5554000026 -:103BD0000200A190555555550200A194000055557D -:103BE0000200A198F00000000200A19C55540000C2 -:103BF0000200A1A0555555550200A1A4000055553D -:103C00000200A1A8F00000000600A23C0000000491 -:103C10000200A06400000307000000000000000094 -:103C20000000002E00000000000000000000000066 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000002E004D00000000C9 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA00000000000004D008B00000000000000003C -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD000008B009000900094009400980000000079 -:103CE00000000000000000000000000000000000D4 -:103CF000000000000000000000000000009802DE4C -:103D000002DE02E802E802F200000000000000000B -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD000000000000000000002F202FA00000000F3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E300002FA02FF02FF030A030A03150000000052 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000031503160000000001 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB000000000000316035700000000000000008F -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE0000357037B000000000000000000000000FA -:103EF00000000000000000000000000000000000C2 -:103F0000000000000000000000000000037B03BB75 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F3000000000000000000003BB03F700000000C9 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000003F7043D043D045204520467BE -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F9000046704ED04ED04F204F204F700000000ED -:103FA0000000000000000000000000000000000011 -:103FB00000000000000000000000000004F704F80A -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE000000000000000000004F8050A00000000C6 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000050A051F051F052205220525D1 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:1040400005250555000000000000000000000000EC -:104050000000000000000000000000000000000060 -:10406000000000000000000000000000055505DC15 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:10409000000000000000000005DC05E305E305E783 -:1040A00005E705EB00000000000000000000000034 -:1040B0000000000000000000000000000000000000 -:1040C0000000000005EB062B062B06330633063BEB -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F000063B068806880695069506A20000000085 -:1041000000000000000000000000000000000000AF -:1041100000000000000000000000000006A206AE43 -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000006AE06B40000000001 -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:104170000000000006B406B70000000000000000C8 -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A00006B706BD0000000000000000000000008F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000006BD06BE68 -:1041D00006BE06D006D006E2000000000000000087 -:1041E00000000000000000000000000000000000CF -:1041F000000000000000000006E2074F0000000081 -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:1042200000000000074F0750075007630763077639 -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:1043300000010000000204C00003098000040E40D8 -:1043400000051300000617C000071C80000821406C -:1043500000092600000A2AC0000B2F80000C344000 -:10436000000D3900000E3DC0000F42800010474094 -:1043700000114C00001250C00013558000145A4028 -:1043800000155F00001663C00017688000186D40BC -:1043900000197200001A76C0001B7B80001C804050 -:1043A000001D8500001E89C0001F8E800000934004 -:1043B00000002000000040000000600000008000BD -:1043C0000000A0000000C0000000E00000010000AC -:1043D0000001200000014000000160000001800099 -:1043E0000001A0000001C0000001E0000002000088 -:1043F0000002200000024000000260000002800075 -:104400000002A0000002C0000002E0000003000063 -:104410000003200000034000000360000003800050 -:104420000003A0000003C0000003E000000400003F -:10443000000420000004400000046000000480002C -:104440000004A0000004C0000004E000000500001B -:104450000005200000054000000560000005800008 -:104460000005A0000005C0000005E00000060000F7 -:1044700000062000000640000006600000068000E4 -:104480000006A0000006C0000006E00000070000D3 -:1044900000072000000740000007600000078000C0 -:1044A0000007A0000007C0000007E00000080000AF -:1044B000000820000008400000086000000880009C -:1044C0000008A0000008C0000008E000000900008B -:1044D0000009200000094000000960000009800078 -:1044E0000009A0000009C0000009E000000A000067 -:1044F000000A2000000A4000000A6000000A800054 -:10450000000AA000000AC000000AE000000B000042 -:10451000000B2000000B4000000B6000000B80002F -:10452000000BA000000BC000000BE000000C00001E -:10453000000C2000000C4000000C6000000C80000B -:10454000000CA000000CC000000CE000000D0000FA -:10455000000D2000000D4000000D6000000D8000E7 -:10456000000DA000000DC000000DE000000E0000D6 -:10457000000E2000000E4000000E6000000E8000C3 -:10458000000EA000000EC000000EE000000F0000B2 -:10459000000F2000000F4000000F6000000F80009F -:1045A000000FA000000FC000000FE000001000008E -:1045B000001020000010400000106000001080007B -:1045C0000010A0000010C0000010E000001100006A -:1045D0000011200000114000001160000011800057 -:1045E0000011A0000011C0000011E0000012000046 -:1045F0000012200000124000001260000012800033 -:104600000012A0000012C0000012E0000013000021 -:10461000001320000013400000136000001380000E -:104620000013A0000013C0000013E00000140000FD -:1046300000142000001440000014600000148000EA -:104640000014A0000014C0000014E00000150000D9 -:1046500000152000001540000015600000158000C6 -:104660000015A0000015C0000015E00000160000B5 -:1046700000162000001640000016600000168000A2 -:104680000016A0000016C0000016E0000017000091 -:10469000001720000017400000176000001780007E -:1046A0000017A0000017C0000017E000001800006D -:1046B000001820000018400000186000001880005A -:1046C0000018A0000018C0000018E0000019000049 -:1046D0000019200000194000001960000019800036 -:1046E0000019A0000019C0000019E000001A000025 -:1046F000001A2000001A4000001A6000001A800012 -:10470000001AA000001AC000001AE000001B000000 -:10471000001B2000001B4000001B6000001B8000ED -:10472000001BA000001BC000001BE000001C0000DC -:10473000001C2000001C4000001C6000001C8000C9 -:10474000001CA000001CC000001CE000001D0000B8 -:10475000001D2000001D4000001D6000001D8000A5 -:10476000001DA000001DC000001DE000001E000094 -:10477000001E2000001E4000001E6000001E800081 -:10478000001EA000001EC000001EE000001F000070 -:10479000001F2000001F4000001F6000001F80005D -:1047A000001FA000001FC000001FE000002000004C -:1047B0000020200000204000002060000020800039 -:1047C0000020A0000020C0000020E0000021000028 -:1047D0000021200000214000002160000021800015 -:1047E0000021A0000021C0000021E0000022000004 -:1047F00000222000002240000022600000228000F1 -:104800000022A0000022C0000022E00000230000DF -:1048100000232000002340000023600000238000CC -:104820000023A0000023C0000023E00000240000BB -:1048300000242000002440000024600000248000A8 -:104840000024A0000024C0000024E0000025000097 -:104850000025200000254000002560000025800084 -:104860000025A0000025C0000025E0000026000073 -:104870000026200000264000002660000026800060 -:104880000026A0000026C0000026E000002700004F -:10489000002720000027400000276000002780003C -:1048A0000027A0000027C0000027E000002800002B -:1048B0000028200000284000002860000028800018 -:1048C0000028A0000028C0000028E0000029000007 -:1048D00000292000002940000029600000298000F4 -:1048E0000029A0000029C0000029E000002A0000E3 -:1048F000002A2000002A4000002A6000002A8000D0 -:10490000002AA000002AC000002AE000002B0000BE -:10491000002B2000002B4000002B6000002B8000AB -:10492000002BA000002BC000002BE000002C00009A -:10493000002C2000002C4000002C6000002C800087 -:10494000002CA000002CC000002CE000002D000076 -:10495000002D2000002D4000002D6000002D800063 -:10496000002DA000002DC000002DE000002E000052 -:10497000002E2000002E4000002E6000002E80003F -:10498000002EA000002EC000002EE000002F00002E -:10499000002F2000002F4000002F6000002F80001B -:1049A000002FA000002FC000002FE000003000000A -:1049B00000302000003040000030600000308000F7 -:1049C0000030A0000030C0000030E00000310000E6 -:1049D00000312000003140000031600000318000D3 -:1049E0000031A0000031C0000031E00000320000C2 -:1049F00000322000003240000032600000328000AF -:104A00000032A0000032C0000032E000003300009D -:104A1000003320000033400000336000003380008A -:104A20000033A0000033C0000033E0000034000079 -:104A30000034200000344000003460000034800066 -:104A40000034A0000034C0000034E0000035000055 -:104A50000035200000354000003560000035800042 -:104A60000035A0000035C0000035E0000036000031 -:104A7000003620000036400000366000003680001E -:104A80000036A0000036C0000036E000003700000D -:104A900000372000003740000037600000378000FA -:104AA0000037A0000037C0000037E00000380000E9 -:104AB00000382000003840000038600000388000D6 -:104AC0000038A0000038C0000038E00000390000C5 -:104AD00000392000003940000039600000398000B2 -:104AE0000039A0000039C0000039E000003A0000A1 -:104AF000003A2000003A4000003A6000003A80008E -:104B0000003AA000003AC000003AE000003B00007C -:104B1000003B2000003B4000003B6000003B800069 -:104B2000003BA000003BC000003BE000003C000058 -:104B3000003C2000003C4000003C6000003C800045 -:104B4000003CA000003CC000003CE000003D000034 -:104B5000003D2000003D4000003D6000003D800021 -:104B6000003DA000003DC000003DE000003E000010 -:104B7000003E2000003E4000003E6000003E8000FD -:104B8000003EA000003EC000003EE000003F0000EC -:104B9000003F2000003F4000003F6000003F8000D9 -:104BA000003FA000003FC000003FE000003FE001E8 -:104BB00000000000000001FF0000020000007FF87C -:104BC00000007FF80000016A0000150000000001ED -:104BD0000000FF00000000000000FF0000000000D7 -:104BE00000000000140AFF000000000100000000A7 -:104BF00000201001000000000100860000000100FC -:104C00000000860200008604000086060000860878 -:104C10000000860A0000860C0000860E0000861048 -:104C20000000861200008614000086160000861818 -:104C30000000861A0000861C0000861E00008620E8 -:104C400000008622000086240000862600008628B8 -:104C50000000862A0000862C0000862E0000863088 -:104C60000000863200008634000086360000863858 -:104C70000000863A0000863C0000863E0000864028 -:104C800000008642000086440000864600008648F8 -:104C90000000864A0000864C0000864E00008650C8 -:104CA0000000865200008654000086560000865898 -:104CB0000000865A0000865C0000865E0000866068 -:104CC0000000866200008664000086660000866838 -:104CD0000000866A0000866C0000866E0000867008 -:104CE00000008672000086740000867600008678D8 -:104CF0000000867A0000867C0000867E00008680A8 -:104D00000000868200008684000086860000868877 -:104D10000000868A0000868C0000868E0000869047 -:104D20000000869200008694000086960000869817 -:104D30000000869A0000869C0000869E000086A0E7 -:104D4000000086A2000086A4000086A6000086A8B7 -:104D5000000086AA000086AC000086AE000086B087 -:104D6000000086B2000086B4000086B6000086B857 -:104D7000000086BA000086BC000086BE000086C027 -:104D8000000086C2000086C4000086C6000086C8F7 -:104D9000000086CA000086CC000086CE000086D0C7 -:104DA000000086D2000086D4000086D6000086D897 -:104DB000000086DA000086DC000086DE000086E067 -:104DC000000086E2000086E4000086E6000086E837 -:104DD000000086EA000086EC000086EE000086F007 -:104DE000000086F2000086F4000086F6000086F8D7 -:104DF000000086FA000086FC000086FE00008700A6 -:104E00000000870200008704000087060000870872 -:104E10000000870A0000870C0000870E0000871042 -:104E20000000871200008714000087160000871812 -:104E30000000871A0000871C0000871E00008720E2 -:104E400000008722000087240000872600008728B2 -:104E50000000872A0000872C0000872E0000873082 -:104E60000000873200008734000087360000873852 -:104E70000000873A0000873C0000873E0000874022 -:104E800000008742000087440000874600008748F2 -:104E90000000874A0000874C0000874E00008750C2 -:104EA0000000875200008754000087560000875892 -:104EB0000000875A0000875C0000875E0000876062 -:104EC0000000876200008764000087660000876832 -:104ED0000000876A0000876C0000876E0000877002 -:104EE00000008772000087740000877600008778D2 -:104EF0000000877A0000877C0000877E00008780A2 -:104F00000000878200008784000087860000878871 -:104F10000000878A0000878C0000878E0000879041 -:104F20000000879200008794000087960000879811 -:104F30000000879A0000879C0000879E000087A0E1 -:104F4000000087A2000087A4000087A6000087A8B1 -:104F5000000087AA000087AC000087AE000087B081 -:104F6000000087B2000087B4000087B6000087B851 -:104F7000000087BA000087BC000087BE000087C021 -:104F8000000087C2000087C4000087C6000087C8F1 -:104F9000000087CA000087CC000087CE000087D0C1 -:104FA000000087D2000087D4000087D6000087D891 -:104FB000000087DA000087DC000087DE000087E061 -:104FC000000087E2000087E4000087E6000087E831 -:104FD000000087EA000087EC000087EE000087F001 -:104FE000000087F2000087F4000087F6000087F8D1 -:104FF000000087FA000087FC000087FEFFFFFFFF2C -:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 -:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399 -:1050200000BEBC20000000000000000500000003DE -:1050300000BEBC20000000000000000500002000B1 -:10504000000040C000006180000082400000A3001A -:105050000000C3C00000E4800001054000012600FC -:10506000000146C000016780000188400001A900DE -:105070000001C9C00001EA8000020B4000022C00C0 -:1050800000024CC000026D8000028E400002AF00A2 -:105090000002CFC00002F08000001140000080003C -:1050A000000103800001870000020A8000028E00D8 -:1050B00000031180000395000004188000049C0088 -:1050C00000051F800005A300000626800006AA0038 -:1050D00000072D800007B100000834800008B800E8 -:1050E00000093B800009BF00000A4280000AC60098 -:1050F000000B4980000BCD00000C5080000CD40048 -:10510000000D578000005B0000007FF800007FF872 -:1051100000000166000015000000FF000000000014 -:105120000000FF0000000000000019000000000067 -:1051300000000000FFFFFFFF00007FF800007FF885 -:1051400000000361000015000000FF000FFFFFFFDB -:105150000000FF000FFFFFFF000000FF0000FF0046 -:105160000FFFFFFF0000FF000FFFFFFF000000FF29 -:105170000000FF000FFFFFFF0000FF000FFFFFFF19 -:10518000000000FF0000FF000FFFFFFF0000FF0016 -:105190000FFFFFFF000000FF0000FF000FFFFFFFF9 -:1051A0000000FF000FFFFFFF000000FF0000FF00F6 -:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9 -:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9 -:1051D000000000FF0000FF000FFFFFFF0000FF00C6 -:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9 -:1051F0000000FF000FFFFFFF000000FF0000FF00A6 -:105200000FFFFFFF0000FF000FFFFFFF000000FF88 -:105210000000FF000FFFFFFF0000FF000FFFFFFF78 -:10522000000000FF0000FF000FFFFFFF0000FF0075 -:105230000FFFFFFF000000FF0000FF000FFFFFFF58 -:105240000000FF000FFFFFFF000000FF0000FF0055 -:105250000FFFFFFF0000FF000FFFFFFF000000FF38 -:105260000000FF000FFFFFFF0000FF000FFFFFFF28 -:10527000000000FF0000FF000FFFFFFF0000FF0025 -:105280000FFFFFFF000000FF0000FF000FFFFFFF08 -:105290000000FF000FFFFFFF000000FF0000FF0005 -:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8 -:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8 -:1052C000000000FF0000FF000FFFFFFF0000FF00D5 -:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8 -:1052E0000000FF000FFFFFFF000000FF0000FF00B5 -:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98 -:105300000000FF000FFFFFFF0000FF000FFFFFFF87 -:10531000000000FF0000FF000FFFFFFF0000FF0084 -:105320000FFFFFFF000000FF0000FF000FFFFFFF67 -:105330000000FF000FFFFFFF000000FF0000FF0064 -:105340000FFFFFFF0000FF000FFFFFFF000000FF47 -:105350000000FF000FFFFFFF0000FF000FFFFFFF37 -:10536000000000FF0000FF000FFFFFFF0000FF0034 -:105370000FFFFFFF000000FF0000FF000FFFFFFF17 -:105380000000FF000FFFFFFF000000FF0000FF0014 -:105390000FFFFFFF0000FF000FFFFFFF000000FFF7 -:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7 -:1053B000000000FF0000FF000FFFFFFF0000FF00E4 -:1053C0000FFFFFFF000000FF000000FF000000FFD4 -:1053D0000000FF00000000000000FF0000000000CF -:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:1054000000001000000020800000310000004180FA -:1054100000005200000062800000730000008380E2 -:10542000000094000000A4800000B5000000C580CA -:105430000000D6000000E6800000F70000010780B1 -:105440000001180000012880000139000001498096 -:1054500000015A0000016A8000017B0000018B807E -:1054600000019C000001AC800001BD000001CD8066 -:105470000001DE000001EE8000000F0000000000CF -:1054800000007FF800007FF80000021D00001500FA -:1054900010000000000028AD00010001FFFFFFFF29 -:1054A000FFFFFFFF00090206CCCCCCC17058103CB6 -:1054B000000000000000FF00000000000000FF00EE -:1054C000000000000000000000000001CCCC020140 -:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1 -:1054E000FFFFFFFF0000FFFF000000000000FFFFC4 -:1054F000000000000000FFFF000000000000FFFFB0 -:10550000000000000000FFFF000000000000FFFF9F -:10551000000000000000FFFF000000000000FFFF8F -:1055200000000000000E0000011600D60000FFFF82 -:10553000000000000000FFFF000000000000FFFF6F -:10554000000000000000FFFF000000000000FFFF5F -:10555000000000000000FFFF000000000000FFFF4F -:10556000000000000000FFFF0000000000720000CB -:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B -:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F -:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1 -:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E -:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C -:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D -:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2 -:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6 -:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00 -:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6 -:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7 -:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE -:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19 -:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E -:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC -:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E -:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D -:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E -:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F -:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D -:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B -:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C -:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1 -:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5 -:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF -:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5 -:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6 -:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD -:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19 -:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D -:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B -:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D -:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1 -:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91 -:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1 -:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70 -:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1 -:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F -:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91 -:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D -:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71 -:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08 -:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50 -:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0 -:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30 -:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0 -:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10 -:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70 -:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA -:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C -:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D -:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B -:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29 -:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A -:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF -:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3 -:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD -:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3 -:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90 -:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE -:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2 -:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE -:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8 -:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B -:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB -:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B -:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D -:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A -:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28 -:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19 -:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE -:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2 -:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC -:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2 -:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3 -:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA -:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82 -:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD -:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8 -:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A -:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE -:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E -:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE -:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D -:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE -:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C -:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E -:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A -:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E -:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05 -:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D -:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD -:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D -:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD -:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D -:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D -:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED -:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D -:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD -:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C -:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD -:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B -:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D -:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29 -:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D -:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04 -:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C -:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC -:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C -:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC -:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C -:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C -:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC -:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C -:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC -:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B -:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC -:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A -:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C -:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28 -:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C -:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03 -:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B -:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB -:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B -:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB -:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B -:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B -:105D7000CDCDCDCD000C0000000700C00002813069 -:105D8000000B81580002021000010230000F024097 -:105D900000010330000C0000000800C00002814038 -:105DA000000B81680002022000010240000702503F -:105DB000000202C000100000000801000002818003 -:105DC000000B81A80002026000018280000E829810 -:105DD0000008038000028000000B8028000200E021 -:105DE000000101000000811000000118CCCCCCCCD7 -:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3 -:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2 -:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2 -:105E2000CCCCCCCC00002000000000000000000022 -:105E30001F8B080000000000000BFB51CFC0F003D7 -:105E40008ABB5819180238107C7AE0A58C94E9DFD7 -:105E5000C8CCC0B00388AF02F17E66D2F5B34A2346 -:105E6000D8F7241818182419184E893130EC9244A8 -:105E700088E702D5084A3130DC858A0500D967A554 -:105E8000E81B4EA39836F8BB3A2AFF912A84CE87A6 -:105E900089A3C93F86CA6F5480D03FD5B19BBB0947 -:105EA0002A0F00FE694F6760030000000000000039 -:105EB0001F8B080000000000000BED7D0B7854D50F -:105EC000B9E8DACFD933994C7642422610700703ED -:105ED000040D30208FA85427E1D1E0E5E8F0462EEC -:105EE000CA80AF0892448D356D39373B6412020287 -:105EF0008ECAA1B4A53A207AA247DBD4464B7BF5E3 -:105F0000DC206A73DAD37B9152A52DB6413D281669 -:105F100068F49403BDD796BBFE7FAD3DD97B672661 -:105F20000F5FDF395F1B3EDD597BAFBDD6BFFEF78C -:105F3000FAFF7FEDA8A297A8971072117EAE256494 -:105F40009D4008C9EBBD5AF78916AD26B9845405A2 -:105F500055632B7DB65E0A1B8DD3E8FD4BC4D01371 -:105F600004EE8F9B432611A2C07B05844C85FF4D18 -:105F70002744CE691D1EF5D37BD2AA2CB85AE3590B -:105F8000D72A99107D2A3CDF362ED5F3E4FC09A5EB -:105F9000A75B23F873710C21F5C76F9CFF8AD5A608 -:105FA000FF8D2499B9272FA7BFCC24332F4A847C97 -:105FB00054B828ABD3483FDE070D5DBA3C9690F34A -:105FC0000D2BE6BF32B6EFF3F512A96D2FED7BFF77 -:105FD0002AA2215E8866AA9189BDEB5E4F48A72759 -:105FE0008790CD859BD87A7329B2AEA4F7DBFE45A6 -:105FF000974B7AE15C2FD37E53FBAE871013C7B566 -:10600000C649BE9FE872BCEF7E2F391E7F9FC8F441 -:10601000DF0C42B00B5DFF74217A2DDCF7142E32B9 -:1060200047D0F6FA67CA49B4343DFC497A7D42F854 -:10603000ADF7D2D291F7FB687F530BA1EF9D54E3EC -:10604000D75F45F9E8BDEF4BA14DC0477BC6CF21D7 -:10605000017A9F303EB2E8746A7FD3F054FC918E8F -:106060004E7F4FBCC87F167F5589ABB23AC927E730 -:10607000AF3B80BF326CFCD5BEB8DFF13E297FC597 -:10608000DCFCC5F171BA9DAD9FEC1EC6E8C2E9E526 -:10609000A64F5ABA7CD2F7FAF2D316C0ABA77DB19D -:1060A0003982A4E0270EAF45AF4F0BEF407C444848 -:1060B0001CE94C484482F97BEFB36B469921009F61 -:1060C000D1E6615847904D4582B7B6DC2D52380372 -:1060D00024D13AAE88B6BBD72C00B803C7E79F02DD -:1060E00079680E5568B3E97AF569C643F3E835A3D4 -:1060F0005417603D5B89084A808E576D969702BDA4 -:1061000008B69F366F099B80071226643821F7F185 -:106110003511221A326DABF0EB9854EB504927C37E -:106120008770D1D3F7FD74EB577BDF23178BE0FF2C -:10613000F71058DF40EF91287BCFA4FF00DF39AE86 -:1061400071F439B46DE3FB00B1B5E9F3A3F00BE2F0 -:10615000FBEE2F64BE6CB24F33A87E504B443D0122 -:10616000FD89912DD37646255544F03C480E528A40 -:106170000C489766422ADB811F493B5938B117BE4C -:106180005344C0F514DCBE734D0B555DE7CAFC21CA -:10619000E0F3A04EC8B09CBEEBD9D6401979BCAD97 -:1061A0001D7A0EF93F46F9680C7DDF0C317BB8B5DE -:1061B000E4653D6A93EF0C41E07CE9E60F62C83389 -:1061C00040CC8055E8B5440C7B039F9E3F64171E6E -:1061D00007CB1FFEA88D3E64E8F40A72BF61B0FCD5 -:1061E000F169E7B3E8DA57AE1A2DBA6A84D2614B87 -:1061F000F1A294FE477ABAEE23D03FA384841329F8 -:10620000DE1B25085C0E4C87BEC12BA58F9424EFA6 -:10621000BD0E7A49F93356ECED071F52AE131FD667 -:10622000B8DE7AC97897AA4422EB228CA7C2789468 -:106230004FB7041F3609958773C0DB141F527C4A81 -:1062400027B44931413EA43F9D026D7B83E1C45692 -:10625000E48304D2C582CF63880EFCCAB93E479B53 -:10626000AC30053BFCDE7A15E150D147A0E3E87481 -:10627000408A0AD94F3A816F2D7E0536B87829B405 -:10628000BFEEE08356632A4945078B5F01AD8C5F03 -:10629000BF3E38FDE29E6F8913DE41BFE7978D93C5 -:1062A000363B94FE3D999CB4E84391580503D8F8D9 -:1062B00060B3420E089309692A5C46A2F4EE667840 -:1062C00044ED580B5C0BC03F9C8A7A81B40932C004 -:1062D00069D95512CCC17ED30503C713B55AD42B47 -:1062E000923FCCEC2B7F9E1E2E36FF70231ED629AC -:1062F0007EF3493C2C52FA505D19EA24A037C304BE -:10630000F88084185F48DC4FB7DE8F717EF692A369 -:10631000F83ED5AEA68EF6CC29C77325FA908EB37B -:10632000A584243C48A7B8066DB94426B02FA0FA2E -:10633000C95F40FB6759EC2F2D0801FC59DCBE9268 -:10634000599CBF05AACF289EFDD39CF2ED73C9BF0F -:10635000CCED711F7D96663F615DDDFEDB6302F76C -:10636000DF32881FE9CDDF27FED4FEAAE5B75978D2 -:10637000CD1309E293FC54493C51C4D746DBF7BC2A -:10638000959D80759B159135CD140FE6DB42A809CC -:10639000E829877BB2E8F3934F4AB85FCA5B567F20 -:1063A00009CCB7BDC11C5B6CF307B7CBB51AE09B3A -:1063B000F28566B7173790E80B826DFFE509B68C5A -:1063C0002D1E86FCF7767709980A01F9CFEB8F0529 -:1063D0005F05B9E4F793F8B1B7A5BEEDDC7CC2ED7B -:1063E000E50DE5613A6F2BE8AE11F8D814283CAD05 -:1063F00005ACFD93C6E1E5603F5B3359FBA3C6776F -:10640000C28DC817512D42EFD5138E972E8A17A42F -:10641000BF916FB7AFEEAB7BFD3B64DD077CB6D7BA -:106420009F735D09D8CF32310468DF1B3BA2AFB147 -:10643000E1E39B9E8A37001F2349422040BF582E2C -:10644000CA8FE5CF01E341BB80CB5321398CFD4698 -:10645000477ACA15B8B5427F19AE2DC1E7B2519E31 -:10646000C81CFD24CABF245CBC7CF0F29E6EBD013A -:10647000814452F9F3F74B392857816974DD0EBD19 -:106480005EA8233FF271BF063402FD914D619A0C64 -:106490007A24BE229262BC9F0822F6D3C01E5C41C1 -:1064A000D150B8ACECDFE87A352D3CE5550A97279A -:1064B000D71F32116C66270C2E039E78A306F82591 -:1064C000472502F2AF158623B7019F924858A0F7DF -:1064D000B56038B4D5E8BB3E9530FB9043AF179913 -:1064E0007C13E87F4F9E8EFD09D80B6B5D63002EF9 -:1064F00015E1FA0CE89D2B4E1F98CE23487B3918E6 -:10650000B374F4FEACE99CEE7D377D030293AFFBE0 -:106510009BCE874D2A4F2DC7055102A5182F46BA8D -:10652000689C2EE795A8067EE396AF8A641F6D3FB0 -:106530005ADFBF9F12033FC563B39B3AA3DFC8BBBB -:10654000F4A9C042E9DEDB7597589948C14F9522FE -:10655000D3FB5BEE7A383E16E8F98A73BFA7AC0A24 -:10656000A35F4AF77D95400FEB3D6F31B34F643F1A -:106570005D0FEDAF707FE47CDEA22C92621EEBBA61 -:10658000C7057F21C5732AB9B94FE2FED54E36BE85 -:10659000E5EF9C2FE87F7C0B3F172A4572B814C9A2 -:1065A000EA23A57C3114EF8549BF3B0FDB1EFE2893 -:1065B000512BFA08D8BDC2CE72B82AA4A711F8741C -:1065C0009748AA52C1B7561211BEC230DD7A50BDEB -:1065D0005F688AA099C8BD9281F7F357D51E5428E9 -:1065E0005D5A47911098994B603CD0AB07BD683F0E -:1065F000D55C92F0523DFD5AD1574CB0CB7A21096F -:10660000032C7A2DEC39E97FD4BE1AF4B9B2316A81 -:10661000225CC108EE110E152D437AB750FFCEC390 -:1066200016E2E0A71653EC04BE8DD3F1C11F8C1BFC -:106630001528AFE782D4F2C3CFC7147E6BBF712990 -:10664000C485282901CE0932C2494762F4D4195EB3 -:1066500046EE9E453AA9DD69CDDE85F2605E495081 -:106660005E6572D814C0CEC80953A4F0C6AA983E7D -:106670005072E382DD8EED21D107ED7C23EB9DE8A6 -:10668000FFB5FE595A910AAFD522D36FF7717D78C5 -:106690005E699F8FFE4633958FA2BEFDC39C0EDFC1 -:1066A0008E2D7A703CEA336697ACE75D82E18863B1 -:1066B0008EBCA0E27ADC7ECD3CEED7B41452BF068D -:1066C000E59D2C003F2683F3470B608F3EF76493D4 -:1066D0008449E1C8007F86FA25A494F9251AFD07AC -:1066E000FA2F7F85D39FF1B8FC9674FECCD784C86F -:1066F0000F50DF515505F0EF16E2F3C701BE0BE86E -:106700007ED2E8BBEE2EBE9F9C2B6D2B6AA1703D06 -:10671000962B3AF861349797C78879E2227D1E2F2D -:10672000140D803B5E2FE23ACE19CC6F27EF7A1D15 -:1067300076A2D95CA4119BFED9C1E5695B83E69082 -:106740005BF7D5AFC6A391147A4BE7F4C99815C689 -:10675000F8873F9440FAC33A53F9E90F945668FD1D -:10676000E93FB9445D83F82BAC3825C3B5CCBD5F98 -:106770004A3DAEFB4AEC7EA694BEDF60AF5B289E2E -:10678000DE561CFE78A704FB2E93A0FFE70D5153A5 -:106790001580AB3E1CE0F786A8B8C1B5BBBC12EEB5 -:1067A0001BB3221AC891659FBDA1C856B89FF52595 -:1067B000790BD0CB5B2E8A12A59F269B24C7263748 -:1067C00053E1A68DBF33A9BAB4E3438B7EA512FC77 -:1067D00054522892B1148ECD1F3768763A75D16D18 -:1067E00008DBB73AF9265EDFBF9EFDB47CF173D1BA -:1067F0008A8738E9853FF67808A77392FE7DE21A0A -:10680000FF39E8AD71FA19947E9B0CA027D3177459 -:10681000E385FE435C33C3D08E1B8668DAF4D8C7A9 -:10682000620EE241BE20A35EDABDA6250CF4D2E9D9 -:1068300018405A7A0DA7B2DB5D828A7245F5C655BB -:10684000D27454C802C43FE74A1B91DE8F517A8349 -:106850001E7B8CD4765DCCED957F2DAAA21FDFD553 -:10686000689637160F456F52F8A85F47F630FFE578 -:1068700012CB7FF97BCA2783F057CE53A3C1EDB16A -:1068800017F84AEEA62C4DE12ADCC8EC26F86A3946 -:10689000B46D50BBD729F4F2A387CFA394260E8FF3 -:1068A000477A3BEDD363852F0B1EB06FC5CCBEA9D5 -:1068B000666718F44CA098DA2782F66735E06744DB -:1068C00049BC1CDA2377CFC3757C1BFC503FD8171B -:1068D00082F8F8A698683429CD7CE148A728C1FE43 -:1068E00099E0FECEA29F7B5E6AF5909EBE6C712FF2 -:1068F000D029507B189669B77BD5525EAF3D1C51AD -:10690000D289EAD6ED2FA4F513FE2CF1FDD8CCC622 -:10691000306D8F825FA93FB9537CBC11F663114F74 -:10692000B81EE9EEDA4724E3503CDEBDB6CC122AAD -:1069300063F96FE83C7776291400027E80648F0348 -:10694000DD097689EA9BB5DCAEDD4A2201787886DE -:1069500088185F3B438E04AEB0F1E14E4965F3B455 -:106960002A6F43FCDE8AEFDE16676D4BFFDCB1DB7E -:10697000D9BE9D2C1A0EF1DBDB772AB8FE3B5DFBFE -:10698000D698A4E3B87790DA16C043B342D04F58F4 -:10699000AB1319E2B11B7EF89D19B04FF836B72B37 -:1069A0001F50FE326CFA679D3FA1C27EF69D8E2B72 -:1069B000965D4DE0FD44CB08D89767939476F496A6 -:1069C00056277C03C1EF8697904DFDC221B7092958 -:1069D000E3874F4982236E58AF052641D0E4BC9728 -:1069E0005DCD0AA63FCCDF7A134DE0274A06EF5F64 -:1069F0003B99E5396A67C275A0F77EC6FDD1A1BE95 -:106A00007738CD7B1BB46E15F8BF46362B05B137F2 -:106A10005EA529B5E19120C707CA3B471247BFD6FB -:106A200041F6AB14FBE9E786F794AE99E2E4BE7059 -:106A3000DF40A26F81DC9D17A3D51827E0707B0093 -:106A4000CF125C65A427C64F8A605E7FAB9005714C -:106A5000940EF44FBC86ECA0778DA507A85E82B893 -:106A60004F4689F3B93BAED293A46B27CA1786442D -:106A7000E992029ABF53027FB14C3E9DEC4FE7ABC7 -:106A800086754DC64EA85FEAB87EA926C683B3A612 -:106A9000A17C61BCAE6EFE1813E0A8CB3342A60108 -:106AA0006A3414C6315C7C5573412009DBFEBB4659 -:106AB000EE51418E6AA8FEB6DFBF27C8E2C9E9F4ED -:106AC000B64234C35F027EAD88789274DAB6ADFB0D -:106AD000A3B850D9CEF655594BFAD917DF1364F144 -:106AE000E2B55BC666B1B88B535F9DE5F6E127CF93 -:106AF0003CAE76839E79FAC4F5B0CEF5FF53221AE8 -:106B00009DF7EC3399A413ED464205BBB1AE434A61 -:106B1000690F096962F9F3EF6522BDD63DE7492C9B -:106B2000A0EFAF7BE19D4984C2777653CF6B23C141 -:106B30009F7E5A607171B37BD2627A7F9D4C56A75B -:106B40008AB34C90D93EE4F48F325680FC0A6D072C -:106B50006FC671DB972B6057AD7E86AC20BFD27EAF -:106B600068B7CDA784C45821157C2C1F71FA2981E0 -:106B7000C17740C1FDDFBAB6BD6A94C251D3F621D8 -:106B8000EA8BD9DF7B360078A8392039FCB89A36F1 -:106B9000A9D33309AF27E00A71566106F009E797D8 -:106BA0008E0D185FAD6E7FE0432900EF3BF516C5F3 -:106BB0004BA813F0FAA6145A00ED1FFC63C0A0A85E -:106BC000FAE0F01301C02B1D778D9A05717C277FA9 -:106BD000C3F81772FA8E47391DF3BD35ED5BD87CCB -:106BE0002EBDF801FC52D0370E1B919D7974D23620 -:106BF000B83CEFFA67CF3D6AD2F94E3FF7FB474DFD -:106C00000AF75D7FF9F747BF0E72F9CF5E1DF47A80 -:106C1000CDD3BF0C101B1FAE9359FCE0EC28BA85F6 -:106C2000A2FDCEFECA930087E0EC4BEF8D36E87AEA -:106C3000CF7EFF4FC30DDABFEEA5B9F9B0FEBAE7BC -:106C400067E7F7E7C7009F263C76B81238BE714069 -:106C500060CEC28BFCEAA2CBA18E43A301CE33C788 -:106C60003CB83FABA1F7EAA7029D36A09D85F6464A -:106C70008ADFEA67367F08FAA12F9ECD912206BFF0 -:106C8000A81A0C029DDF9987F4223D681FDDFD6B79 -:106C90008E523A4E4E4FB773E46315F45CCD335BBE -:106CA000D87C2EBA9D815FAEEC4BB7CD2EBA9D231A -:106CB000773D560089D78E618E3C8275ED8D9F475A -:106CC000B222FDE8074BFE07C22BE659285C4BE5D4 -:106CD000F0376490A3E73292745D00747DF6DC684F -:106CE00042F9E27DA5E766B0073D2F79F47DF4FE19 -:106CF000BA97DE44B93AFBFCEBAA81768CF805EA38 -:106D0000579E25C99FC3E06756339F93D4ECCFECC1 -:106D1000F4047AE9539D58586904F0FE09BC9F6059 -:106D2000FC5E9D38B8444841AFD7E5314CFF27F2AF -:106D3000102F1BF6FF46257E271D8532A0E389799B -:106D4000703F1D1DADF5EBB0FE99367AEE6772EA25 -:106D5000EE5F4DE511EC5D92AE09E14D92422ECF12 -:106D6000EEF5C860EFCE825F95326FCAFC99A1E65E -:106D7000577E263BEBAF92F9158E87F4FCC1E47B7E -:106D8000A0F50D157F3F920D1CD78DC7D31FA7D639 -:106D9000F7EF717D514DCCCA1197F6F5436412316E -:106DA0004716F5C27B1A36A894FF4E3F2D613CA8CA -:106DB000A5FD10EA6DB79EA84E13DFBC20333FA19E -:106DC000FAC0C149A0CF4EBFFC23E4CFEA674EA86A -:106DD000102F7EADED076A7769AF3C803D48D8EC57 -:106DE000C1E9EF1E9CC4F4001D3F059D14858D5F15 -:106DF000F3A273FC9A673E748CBFDE6C47FF60A001 -:106E0000793E90C3CB61BD1F1C5608E8D10FDAA5AF -:106E1000CA547EED07DC1E5A786A797DDE6F200F3A -:106E200036ED88CF00BBD9B1299CBF1DFCB5230A24 -:106E300001BD4DE4F0EF3DB4DDF1BACF80FC74C785 -:106E400091659261DB87FED085CF9947CDD9997442 -:106E5000BC99DD9169E0A2BAF546D971BAAFB2F139 -:106E600041DDEB95F9A0EF611F6A8C87F94241D8AB -:106E7000E74A8179952C7F2DEADE94F69A8DA7F862 -:106E80002318AF5274311923837147924423C45796 -:106E900089DFEFCE4F44347B1E6AC5E183B0C5CC99 -:106EA0005DFC62018C132031FD24FA9F2474B11F14 -:106EB000FFCB9D8FB0F09994BF34F9890CFDE6E0CB -:106EC00041D277BCBE7998A806F1ED16FFDAD6223A -:106ED0005B1EA625D8270F3357A178681548CA78B6 -:106EE000ED78A562BE9287BBE368AAE737294CAE6E -:106EF000AE25DDF7AE0138232C9F33CB85AF2F7144 -:106F00007CFDF364BA70AA42CBC1B3A2F89DBD2444 -:106F10001C53E8FDB9AB7A2E7F19BBF37C8E395E2A -:106F2000BC983178FC0D356F17F12CBA5D1944DE31 -:106F30002E5DFEB8170E93EFC7731C798C436FDD7F -:106F4000AF75639EA1B6B5C816F71BDEE92561CC07 -:106F5000E319E81F0EEFBCF39BB741DC39B730E40F -:106F6000257DC7912F5C8D71232B9F2F17863B2189 -:106F7000DE2FEB46B984F32C0F437E61B3C1F205DB -:106F80009B83FDC7F56628D16605E351D7E0B8A21B -:106F9000C6EB0F06B9CE6F2C0E209E0314CF20EF48 -:106FA000B8FF81F51D1778DEBCDB94207F78221BAB -:106FB000F305019994403CE0BCE00B6DC27C823348 -:106FC0006F9E8E7FB7CB26E6CD5B8D3E79F3EF28A3 -:106FD000B67C8396266FAEF99760DE5C23367FB76A -:106FE000A8B75FAFDCB9F2E63016C665B6CF86B893 -:106FF0004C733671E4CD9B41F0AF22E439E5EAD918 -:107000005877E6E5CFCD59B3C3F63639FE32B679B7 -:10701000FCE98FCDE73641FFDC91A416EBD4E40800 -:10702000596AD383EF292C4EBB4109FF50B1D71DBC -:10703000717EB0F23F87DE7A0FF90AAE63285E9B5D -:10704000295F7990AF4E11BB5EB5AE16FF341BFDC4 -:10705000F3857A610AC6CD92EDA0897C110846C3FA -:10706000E114EF4DF230B9B7E60D94513D4AE54DCC -:107070003122988F5275BAE135060F7F3AB82C3E0F -:107080006D36C6B03A289D60FD5EFA754C63714C52 -:10709000887051B876DD787BA83F3FC75AE70C254A -:1070A0007CD28EF7DC4B52D7EF56AB6CDDCD9155D1 -:1070B0002CBF5EE5CCA742FADA1E679D2E44FF5D29 -:1070C000C13821CBA78A5A84E7474C2B3E1E4CC6B9 -:1070D000C30DA833BCCB047DA8AC6A3705B8E6B2B3 -:1070E0007C4AAE16FD58B1D90759EF6672EBCA0F4C -:1070F000CE954E0F09BF565DDCD6061DFDF42D0D55 -:10710000416C6F6E30F0DAD210C6FB6E3A361B2F30 -:10711000076FC1BA341FC665D38DFF604308C789A6 -:107120003594B1F178DE9C90CC26E02B55B4E46523 -:1071300018B6FD127F6E163481FC6D17D8F36B5AAA -:107140002E4579B3F86787D17F5C5A4ACC403E1808 -:10715000EAF87DF9F527B8CEE6597ED4AF03C951D8 -:1071600056279B77B0F328497BC1E6D9314BC379C9 -:1071700076E40E304F9CCD3330FC0C5FDB0E9EC2AC -:107180003A0485F203A828450FA7AED3E3F2D677D9 -:107190001C0FEAF9E620AB0B538BFD6150FECD06C8 -:1071A000CF3716B27CA35A32BC02EEABA1CBB04EA5 -:1071B0005C2DF5633E4F2D1E7E0BB4B71DDCA25730 -:1071C00080FD2814435E03EC76379173516C307E5A -:1071D000AB1697DC06FD7590630AC7280FDB6FA915 -:1071E000C557DD01EF1F9CF29AD144FB3717FA42D5 -:1071F0001E90B76ED9C1FF83D61385CE3C1A91A9D4 -:10720000BEA0FA6BDB94DB4B503E355B9D648A7A03 -:10721000419BDED8A0DAF4864AE6988087747A87A4 -:10722000DADFFBD4BCBEE358EF6F5022F52AEA85C3 -:107230000871D6BBA7CE675BF400370BF2917230B2 -:1072400059A7B7A060786F7EDBAAD373E7B5E3F4E4 -:107250005FAABCB6BBFEFCB3AAD3DBA926EBF446FF -:10726000419DDE8F1512EA84BCFC2FA5D03EA32FD2 -:10727000DFB9C7739FB7A0FE8F06FB9C7472F9330A -:10728000D5993F2D88BAE87EABD731DF2B202FA5CB -:1072900003EB979155CE7146D53AEB6A2FA9CF7182 -:1072A000B48BCC118EFE97B68E713C1F1BBFCCF1F8 -:1072B0007CFCEEA98EF684C4558EFE97B75538DA5D -:1072C00013DBAF73F49F7C6091A33DA573A5A3FF6F -:1072D000155D6B1DCFA71F5EE7783EF3D83D8EF698 -:1072E00095DD5F73F4AFA7EE900A729BCBEB9073C2 -:1072F000F3457B9EB6358FDA25BACFDF9147190665 -:10730000E3DFACAE4B658F937943F77BB2A1867513 -:10731000CCFB8F9B035722D7A13D958DE11506DE4F -:107320009F310FAE649AB3BE5635587D32ECE39C64 -:10733000F502CE3A6355DA86793ACFF12F77099381 -:10734000FAD2552D74CAC160EB9415C3F5DE10E571 -:10735000E2BC2517A3A85C60FCED6309CFB5CCC9DE -:1073600044FFC2B69F423C5AFBA96B34120317D3A9 -:10737000928BF2553D235FC56ED63ECA230EA52ED5 -:10738000CE92BF804DEFC37EC5D233CD6583D3AFE0 -:1073900052E20A873FE9BE3605D6A5D38F051E9B6C -:1073A0007FEFD68F339448213CD7E4B0496CF11A73 -:1073B00052AB38E01E2C9C9FD40EDC45198EA4D015 -:1073C000E32AA9C5BAAB9615610C02903AE2E0D364 -:1073D0009D8BFF47198C4BFDC219CE7532BFD0ED86 -:1073E0004F53FD86FEF40EEA4FA3BD73E947AAA7EB -:1073F0004C5EFF65303F82E943F73A3F2F3FFADFAB -:10740000C059ED875E81A25025EE0FF34402FBC305 -:10741000E6599120C4E7ACBA79EBBD56CFA5384EFA -:107420002C5715217E19EB9A8BF1FA262DAAB13C27 -:107430007114C769CA16F5547562751E962FD6EA7F -:107440001F18BBBF9FB88BA69268AA78DA4E0FCBE5 -:1074500007C5F4B55D604733F35403F6DCAD074F61 -:1074600045208E2497C93AECD70905E61D5B7E8F2F -:107470009028C699B4A0887657ABDF81F30F04EF4C -:10748000CD1E819FFBD8D22FBC5E3575DC251DBC7F -:107490005B00DE6903C3EB05788B60FE6D387F8D82 -:1074A000C748897F85842B6703DD4E7C3982E95686 -:1074B000CA36201F3BCAD8BE9C1A02077F5BFB1C42 -:1074C000CADF0F7BF2B07E15F9DA3AE770A347C73F -:1074D000792CBA92C21C8C6B04A2B1B1C594DF3274 -:1074E000A36C3FDFAB9F181F652A6102F12CD92FD7 -:1074F000627E50E5F110ABDF1F383E9B667523BD01 -:10750000365F29934D426F9D75AC90AE6B72EFBAAA -:10751000FE8F279BF1279FD7479664615D8AF44CC5 -:10752000B03FBDEDE3F872EBEFEF79B8FE2E20052A -:107530004C7F972E877C77BA71DC7E4C3D8FF30EA3 -:10754000BDBE9E9F2FF0DFD30571262BCE4782D381 -:1075500052C6E57BF1CAF295BDF45D6E7452FAC96C -:10756000D3A7629EDC3AAF40D599B35E98D3D7A239 -:10757000AB15472741163FB2E8EC4DE2734FBFF819 -:10758000F482BC5CD1179FBFF2F07CC37F317CBE1C -:10759000023E0DBD6666B2F3E9E4D05709E6A50ADE -:1075A0009D7268BD67F1BB7BFD7FFA2FCA4FD6FA8B -:1075B0002D7E48DFDF4CB9AFB1F2AB999CDF343898 -:1075C000654515CFAB656FB75E0AFBD7A01FF77D8A -:1075D0009965313CDFAB105307BD9069ED6BF879CD -:1075E00023AB5EC957EAF4CB34D7FE45E575517D30 -:1075F000CEDB72FFCD7D8E2A895F17BD266B69F2C7 -:1076000063833C7FB48BE7EB0AEAE28DB01F2EB8B0 -:1076100095D5FBEF51C86AA8AF1C51658ABE5CC8FE -:10762000DF147D3F83AEBFE0C5871A4702496E3540 -:107630008AC0CD7846331C76B8E0AE78B98F3D9FCE -:1076400002E33CA531BD5B5019C773CE4DCF8FCF40 -:10765000023FE195B796EB101FF828B718F74F6770 -:107660005EF08441FF9FC921555817F6C2CCD7C0A0 -:107670008FFF7D43578E6CE39333DF7D7D86428998 -:1076800074E6B9D767C848AC8463FE0D177F310331 -:10769000E0362B48492DE4EF7495C0B8351ACB97E6 -:1076A00059F53EBB86AB2D70FDA9379BC513F3C5BD -:1076B0001DD0AE878018F80D3C9E7FF5696339D4E4 -:1076C0005F66772902D4E33D2498A69F5ECF9F781A -:1076D00048003F4BEDAC85300BBD1F3A042837C73F -:1076E000B27DC9F922525244F5BEEF70ED78F4A78D -:1076F0005DF54E16FFCBB309E6FB7A6ED41260AF90 -:10770000B7CBC6375681FD5E25633DCE76F930CACC -:10771000859B8EC7BD639CF5B93C1E7DE8AD3BE201 -:10772000E5F4FD7BA688C8AFFE1353B2480AF9DD25 -:10773000DE5086F3070ADEAE2C07B03EA67767F46C -:10774000EE93FC3231B3A889548A4453A178F1975F -:1077500011F2B68DEF5A4412D6E9F3171A088ED3F8 -:10776000D1A0E1B5AD411F5B4C3706DF6A08E27579 -:10777000678381D7871B4AF0F9830D2187DCC37C9F -:107780006F97F0760A7FE5F3BA3ED040E7B5C1B116 -:107790006B22957A4AAF5D3C1FF540E9D4ACB5FD4C -:1077A000C4C1F634740D9B3396230BEA4DEBF4BD44 -:1077B0005BFB817F4FA3B07A11F83577CB917DA821 -:1077C0001FA3058B6CFA91FA6D0584B2E2BD2D23DF -:1077D000E6CC29407944799976388AFE7841302E72 -:1077E000401CB1E028BB6F9DB7407A5141FB61EE70 -:1077F0001C4101BD594ADA012CB5344A2A68FF9967 -:10780000794BCAE13E99E8BC3F4365F20DE356D09F -:10781000EB6C2DF2236D3A7CA763B7F92C5DCF1F7B -:107820003B3C06E4791E7CF94F2AEC0B62BF5235D3 -:10783000F0630A5E3C81750F31A15B85CAD8E35ABB -:10784000F51C99EA19DC0C627C952A16CA2731D0FE -:10785000B118FFEC89CDF1C37997E8297BFF5DBEB4 -:10786000E8DDFCE448580B523E4AE62FD6C7C27406 -:10787000D3F902CF5F1CD7D6C5CC4268D3FE53588C -:107880003B46DF7F213B3A52CC86A28BAA58D79742 -:10789000A06DF5AF8A41BDED9B5CEF107FB408E4AD -:1078A0002DD9D6693BD3D696599B68EC6AAD77C380 -:1078B000A13FBD067AAEFA45A11D40A37A8FE1FF34 -:1078C000C0435877DBD6D0A5C7144E7F8B0E542407 -:1078D000270409D6D3A909213186EA8F09FCFB14B4 -:1078E00005D3C24623E8D7841202BD19F231BF7115 -:1078F00042828E6393AB0969BE8382795FA0E336CF -:107900005637ECE6AF67BD2C3F504FCCAD90072308 -:10791000CF283AE623799CF2B465E7F87EF52E2F5E -:107920006B2A9B4CDF65A07FD6C818075B5F142FBE -:1079300057E93CEB7F5414A29615F24A58D7B03E53 -:10794000BB7DF854969772B41FE275B4C16C331BBB -:10795000CE0F541F786834D4055493F8CD5F037864 -:10796000FF95E51F4F1DBC32EB6ADADE40DB107F6E -:10797000DDD0F1BA1AA5FD8671B8AB3BA65C07EB6A -:10798000ABDE2612B188C967783CC573387E994C46 -:10799000F9E49AAD23E77A299D9F1A13D645CA07C1 -:1079A0002B7DE39A3568ABFA04909B95BE89CDC0D8 -:1079B00057EB27F2EF359089AF86655E2F45F96268 -:1079C000D8968618D427EC5F59791D98D9E122936F -:1079D0005BCA88983F94B26398B7F843333BEF0291 -:1079E00029FD8D940EC532E992E97597CAE867B60C -:1079F000C8182FA6F75B95A940977818CF57B432CF -:107A0000BD3FF6450FC69D8B6BC377A25FA097E283 -:107A10003E653449FE605EFA12F88D8E335E27E5CE -:107A2000700EE1C75E162F2C5EB16C3DBC27652E33 -:107A3000F1E1BE5C62E7A0C8B7599C7A979868D715 -:107A400040CE03C548DF5D01C617E6C3A5C817FBD6 -:107A5000C58ACBEE86B8A4B066EBBF005DB38B09D8 -:107A6000D015EEDF43EFEFE7F494B2433AD06F3F27 -:107A7000A7672C219A501F63DD7F41587B27C8DB05 -:107A80003AEFF373348AD7E19E707C18A5C39DDE6C -:107A9000E763C102A4C3188DE2FDCE2D1D316D1424 -:107AA0001DA7313C42B7B5C7FF997A23989FEC4098 -:107AB0007996B31F5E07F24E9FBFA2D1753E95C364 -:107AC000F5057F5E3C26A93FC284DA1AA9B1579F0B -:107AD00068D43E14DBFACFA1FAE0C947591DFBF583 -:107AE000743E9077BA0ECCFFF64C9013509FE5A3EE -:107AF000B080DFE29B3806EBF3E8BA09F8253D13C6 -:107B000065B4B3561CDB3341C4F812F4077EF08D24 -:107B100062FDA9A044406FCA8532EE5765694F786F -:107B20008201E16396D715F485786ED55B62CBE36D -:107B300092DE3A606C17E1676E1CEDB19EEE029129 -:107B4000FA95B9C7170AA3E9787778B9BF9D4BFDB5 -:107B50006D7A7FBD97E9A5FB23E69721C4418CEEA2 -:107B600002D44F243215AEF93715E747FBB14B7DF0 -:107B7000FDEA6EF41F76F8539FD39CEE63FBF92663 -:107B8000FF111DF8AD9E50F907B9D019BF59FAC3BE -:107B90003A9FE0AE27B6F48992CDD65837BF221F60 -:107BA000F480CCEB93643DA4437D6579E634F4FB2B -:107BB0009EF432BD271DBCF20638A7A1FE2BCB0BCD -:107BC000EDF146319ED45340DA815FE56098D8F3F9 -:107BD000BF963E6869D0F0FAC4D4711520274F4C87 -:107BE0001D5EA153193834E9C75D90673AB787C95C -:107BF000EFB9C3B7E1F9C773268B37015B615CB29C -:107C0000F3113CAFFBB81C7910EB6AA13E8282B441 -:107C10002DDB59BF55CCF16272FDD4ACB0E79B1B94 -:107C200058FC58BD7039C6B554AEC73DD15BF1DCC8 -:107C30008687DA32385FA911D364DF3B6078D00AD7 -:107C40009DDFC3502F4CC2F74D2F8B1F59F522EEED -:107C5000BA100B9E191C9EBEE7329CF4B0F65F165C -:107C60001DACF7EB8470BEDE0FDFD45C9048C2160B -:107C7000FFE8ADEF56F1FE59A88BCF823A9E68FC23 -:107C8000EA22908304EE8FBCFE3A42F8F795904FBB -:107C900083728FBD0E3DC35517DF475E0C67DB5DFA -:107CA00017B11E9883D7F1613DAB4CBE29507A9F26 -:107CB000C9F8ED0CF06B6BA87AD02040249B3ACC2D -:107CC0007F96FBFBF28B7787471A363E170CC73E31 -:107CD000A1FAC0428C23D4ECF763BD7F35E8BFC95D -:107CE000706EC0ECF238CE0B843BA13E4F39C0C65B -:107CF0007B12E0A1F7FFA85715C0BA8FC3FE270F6C -:107D0000EC495462875E0E231E62DEF031A2337DA1 -:107D100026539E88655BFAAC3A061B865D2A71F88D -:107D20004BBB7CBCEDAB8EC54A7BEB3F8E6BFF0F34 -:107D3000F59B55DF715CFB0FF48776A9F14ED07788 -:107D4000E60B1E03EC177D1FCFEF9A2B4BD00EC412 -:107D50008AC808C0C32BD92AEAB9D8F39E7DA0E708 -:107D6000666BD13735DBBEE14CF61BA361FF956234 -:107D70003CD331DEA8A18D47E7EF00BC5ACF5FC9E5 -:107D8000DE85E716E97B06E60D0B0F8F5E43DBC34E -:107D90005FF0E0B9216BBFE9E6CB7C2E5F2DAEF33F -:107DA000802AC89B1FF46D2DCA9927E8CC8359728D -:107DB000A75E98E0C8073C097696D24F95A310A21B -:107DC000A4CF4BF1B9C9F9AC85D723A49F2727CD00 -:107DD0003C57A03CA79F67069777C2E558D693DF2C -:107DE00085E9E7DCA03B4FE2D653D6D5D253DFE29C -:107DF000FC2993E8153E3ACFBA44FB3C1FBE1D9DBB -:107E0000047EF0071A3B0755D2F6D0CB609EBFE93F -:107E100009DFEF9D8EE7BEFEC99B37747958E923D1 -:107E2000BC2EB38F1E62FED5ADCC5FAD9B3F15FD62 -:107E3000BBBAED6374FB3945F7B5EA4286430F0DD3 -:107E4000F31AFC7B7B26EAA3AA0B017CFED9CDE7C3 -:107E5000759C5FE93B9F1F9F5BF3DDE5D2B38726EF -:107E6000FD74179C73AFFBBE227A6CF3D47D9FD751 -:107E7000FF7BA9DE75CA7B18E45D2E22C9FA2ED0DD -:107E80000FDB54AB1D6E9E330BFC5A9B7E2803FF09 -:107E9000ABF77DF8CEDD361FEF6F56A6EE9FE1EA19 -:107EA0003FC61A7F21F677C393D43FB01FA3FDE5E9 -:107EB0003F7B2CF8507F3D24BAC6CBB1E6BF11C73B -:107EC000B3FCEE8BDADA574D19F8345E0EFBA79E41 -:107ED000DB8801DF9F785C0EF94276BED518BF566D -:107EE0005DB8D441EF5EBC8F73DC7FAF21E8A8D7CB -:107EF000BD235A8775DA1779FCA98A7AE6F8DE9EDF -:107F0000918E3ADDBFC1F149E1B83A0D1CD77CC171 -:107F1000701439E4B3178E62C7FD4F0AC7428DE96A -:107F2000AFE5FC3A5767E766E71A42A889DE9A4B45 -:107F3000EF7B29AF7F995E357A9D2B13D38FDF4579 -:107F40004DB0FEB40DFBFB1BFE7CEFBBD762A22A3B -:107F5000E8A82B90789DB75BEFC0396F56EFA63934 -:107F6000BE0F675D7D12ABD774DFFFD0C7F0F28D17 -:107F7000CBAB09F8D3D4574F796E6D975FE0DFFB39 -:107F80000C8A8E38376F5B75BE9F155C72069BEF4F -:107F90001B975F4F20AE2BE7A6FEBEDD413F83BFA0 -:107FA000450B639D784CEFFFBB349F149EE14978ED -:107FB000AE413C4969F0546BC1A3B3BC604BF0F3D4 -:107FC00081A724C3A25BFFF8D9CAE126172E413E40 -:107FD00092389D5A60FF96A2BF95FF68D13E5FF828 -:107FE000C383A4EF73195F0C7D170D92BEC55C0EA1 -:107FF0005AF4CF179E5B0709CF7516BF05C348AF6C -:10800000CF0B9EAF0C129E6316BD8CCF173FAD49B0 -:10801000FEEF1F9EBF70B8F333581CA4A5849D27A4 -:10802000F14991078B8481E5C257ECDC676B853E93 -:10803000679DCDBBCEBAAF74EBFC355F673A795A1A -:10804000A924F2807EC71A583CE00DBE3FF9755551 -:108050005326C6E75DF3B404F765F617B7F9EF5595 -:10806000CE73B903C9F1A40C96FFB931EA7C6FF95C -:108070008A0C571D9989FD2CFCA51BEFAF056F617C -:1080800048620E026F145F5945FDEC1B3E6B7CA5E8 -:1080900093BBA1E22BA60F0D5F03C9FB5786882F68 -:1080A0004B5EFF5AF1950FF89AFE37FE1A2CBE165A -:1080B000FD4D1E8784AF5B872A8FDCAFFD6BC5D774 -:1080C00060E5D1BD6FA3FBBB507FDF17F8ACF1E7D4 -:1080D0009EFFD3E2D11A6F659A7D5E3A7C0E0487CB -:1080E00075FDD03748BCBAF79F5F345E5DF37F6A99 -:1080F000BCF2F1868CD701E0B0AEF220E5DBF2EB0A -:10810000DAD4D4DF111D97C9BEE3365EA83D321F15 -:10811000F2C77F27617EFAC89E391BECF540E33237 -:1081200099BF7DA472F606889F9E8B6460EDD9513D -:1081300031F4F36990575EC4DE738F7F84E3CB9391 -:10814000996DC57FF380AE47238BFB954752695BE2 -:1081500017E68D6CF495FAE2FB0831B64F833CC408 -:1081600082D47058744E37EF50E97B34F2F890F4B3 -:10817000CF40EBFD0FFF9841EA9F04F6CB25C9BF26 -:10818000BB7319E0B34D64F570C7E156017CD78D20 -:1081900060A7E52BF2F7029DEECE64F9C30ED5D8A9 -:1081A00000F913CFE2050F6452BA1D5D9A2DD8CFA6 -:1081B0005FCEC964FBAF19AB52EFBB16723EE87DD0 -:1081C0005F20E353F07798F75BBA8A7D7F8CC8E134 -:1081D000518B6CE74ED7BB9EF7A1476600E1389AFA -:1081E000E6DCFF02FEFEF225FDBF4F6AD9F77D28CF -:1081F000DF8DB29F7B4DF219978F33FEE8D24C7A18 -:108200007D43887EE73EE0A3097E766E4826455092 -:108210007F658D932B934E95E2FD5DC5180579CD55 -:1082200014E3DC9C393DFD38E9F06AADC79A074498 -:1082300011BED333576371C46961426641FCD013E8 -:10824000BA9BE50F191FE4F03AC499B5198946D8CD -:10825000F7CA749D36783BFEEFECFF06CF3B8E8865 -:108260003A9E6F77E16120FDD094C9F2C9B952748A -:108270009317F226AB8594DFB1DB98C9FEDED1A45B -:10828000CC64BD14CE336E675481EF5F2C9359FEDE -:108290008B90E8A885B6F927717E73BF972BB17ACA -:1082A00023F22693E7B67DEB46A5929F5F70399D3A -:1082B0009459E2A8735C12B95B01F95CB260A162E7 -:1082C000F8E1B981E32FE570B4A9D15153FCBD7831 -:1082D0004AAB87387E3A8E459BE0BB1FABEB05ACC3 -:1082E0001328DDC8F86EF5C683E2067ADDCBE56FAC -:1082F00021D0C036DE77395DDBF6F94603FC6DC967 -:10830000FC0D1D98C271F36E82F99027B79F6E81A4 -:108310007C48B74078FEE4C64AA86BE8E6F56D2FC6 -:10832000D3E78D80BF397928DFE3367E5807FAB965 -:108330004325785EE6775B3C09384F60F14B524F3E -:108340006C3CDF00F5C38FA89D13816FF29A6AEF32 -:108350004B953F7D89D3E18FFE48562A3FD0BA5ACC -:10836000FADCEAB748369454FD1757BAEC1A877B03 -:1083700098A7F30C4991C74CF261A27F3FED975C3F -:108380008FFFC295E75D722C759CF1579C7FDB12C5 -:1083900015EBD16E991E3C8762C163E12BD76478DF -:1083A0005AB64472E8DBD50B325C7E0FC3EB0D1E70 -:1083B000E35158C723FB7E3A11CF51B9EC834F8A62 -:1083C000AAF0FC0ED2A9809E785F32F0FA4683F3C1 -:1083D000EFBCBC41A2DBA783FDAC9752CAD51F39C5 -:1083E000FFBCB1E296A5087F4CD201FE13AB865DBF -:1083F0005F06FA65851282EFA69F88DD9B799B6DEB -:10840000FD49BFC605D7AFAB6EE9D76E2D5FE1A4BE -:108410005B9BCAFC02F33A268777521E9D85FCD5EA -:10842000BD7D269DFF482267CA56D69DC0DF995A5A -:10843000CC7F7F5F8CEE9849F5CD2991E549CCAF93 -:1084400030BDB16467A41952A7A7EAAF78A99BF61B -:10845000F30618DFFDB6BE7FFBE8E6A7713B9DFE85 -:10846000DE8C634485F7A375A9EDC1B7F50CFEF763 -:10847000C442A341BFDCB43175BFFF05CC4CE13928 -:10848000F517A92A557CF22A9DC1BB3A92FAFDAB99 -:10849000F44CF61CEC520A3C9F0B64703DA78F060F -:1084A0003DBD3A0DBC1F060208EF3BCDF7DF04755A -:1084B00020EFBBBE03FF4E80F1C5C100E3EF53FBCD -:1084C000562A7940A71641077E783B3B3401F86D68 -:1084D0004DEC049E7739C0F1FCA62F3225301DE407 -:1084E00065D1DC3C4A978E55242418E9F5FF9501A7 -:1084F000E637E4F2782DB57FEF82FDA3AFBE8BFEA9 -:10850000871C1E7DE34456020575E0A744731DD603 -:1085100019EEF3B1BA52129A6EF7E3BFCCE138B557 -:108520007F68F45E1A71F9417DFCBF7835CEBB3FA0 -:108530004387BA94239552E7B514C893FB33F0FBF5 -:10854000B86EB94837FF50FDC053FB87E6070EB43D -:10855000EE0D81A241F981E72A1FD9310DE4488D42 -:108560004F4AA57F2D3D7D94C7DFDDFC635DBFCA0B -:10857000F9E8FD44FF70DDB1DB09CF4DB54E782C35 -:1085800079793FD1E45B0378229D13ED7E299933FD -:108590007D003BCBF253E9E0DCEED213C07940879B -:1085A0003BB9BEF96DFD23013B1DDCEB3F25F2FD20 -:1085B000C1A3AC2E776C644D459ED1CB9FDFFA9C56 -:1085C000F8D2B233EE71FEB3F3A165E706E2C3DC85 -:1085D00034799C4970D099BEBF46D655C8D74F0A4A -:1085E00018AC4DF47970548B94F1BA51628C86F3C7 -:1085F0005FA7F6F9F0EF43995B3D89B15404DEDFE4 -:1086000077F504FB7A7EC5F974F5926CFCFCC4FB2B -:1086100062687E3ED69D49F81DB7378EE5CC83F65D -:10862000238745D0D0E4A6BA3512ACEF8D00DB77B6 -:10863000AEDEF83AFA8343E5F3D5B54EFB7F155F1E -:1086400047D2CF927BA601FFA4C3C36B1C0F4B2361 -:108650000BE7827EBE65A380FAF627300E5DC82D3B -:108660007218F5368931FB48348A0F6A424EC022AF -:10867000001FFFC0BF5B254754FB39B9DBB6DD3FA8 -:1086800017FC43B7BCACC8627C5C91C5ECC29BBE16 -:10869000E81F40DF5BFAF96DA1F6603EEDB231A054 -:1086A0005BDF094639B5D6B391C345FDB467F1FB2D -:1086B000C57C7DA4C7C56F62BCFAC780FF0A0DFDEB -:1086C000029F87EA7DA88B7EDC877554965C59FEF5 -:1086D0008EFBFD6572D4E13766661539FC77B71FEE -:1086E000F2377B91BAFF15595FACBDB836EBB3B129 -:1086F00017C3389FB9ED4652AE5BD8799013C73E89 -:108700009A9B4AAE239F100EB73CBFBFCFC7BE9BFC -:108710007C4D26EA9DDEFD547E02F6CB6EB980FDCF -:10872000147CF7E3917D3F9B0875BD27B6DF7F532F -:108730002A7ACED299DF44BAF31DF1BCB50182F595 -:10874000DF84CEF7846D7CEBBDA4BC0C10BF5CB69F -:10875000F24ADC4FBEB1F2EAD16B4AFBEE2BFAF4DF -:1087600017A2FFB014E66DE4FBE91D9EAA7DA9F6F1 -:10877000811CAF7DE3C44EFF7EE9C6F266D8526F1E -:10878000CAB8E64BD114F327F7351B53C7E31EE4F1 -:108790007A2AB9AF31E9BE86E2A37B9514289BD62D -:1087A000BBAFE9363F9F7DCDEF48CFCF67A2FCA797 -:1087B00086EF7B167FA9D11D5752F84ED1FD8F0948 -:1087C000F223D2F7805FBE957ABFF6387FEF771B32 -:1087D00087A8AF8E39F733E9E4EF7B9F91FCB5A909 -:1087E0003DA3400FFC6EEFC76FDD0FEBD9EB437C71 -:1087F000BBC789E812DF5FF8906F2DFBDCA132FD6B -:10880000FFBBBF1B817F37DB2D1F84C4AFBF8A3EF8 -:108810003FBE4F9C02DF596CDB9751956A9FB35E58 -:1088200017787CC919EF21DCBF5BCAF94DDFF774FB -:10883000AD3D1EFD26D757561CE07F67313BBB641C -:10884000C14215E23DB725E34D04372BFA65857B20 -:10885000E1FB17BFE4E7B9CCB59929CFC7FD86E3A3 -:1088600077A038C48A55CE38C19205FDDB9B938929 -:10887000D47559163FA79B6FA8F6A52D31B4BCD867 -:1088800040EB1CA10FCEBE2C25B55F8278C73212FB -:1088900052E0BA84D44EFC3145E5C9DD8B119E5FB0 -:1088A0005A7FFFF8E37B27DAFD98FF0F11FE85A1C1 -:1088B00000800000000000001F8B08000000000086 -:1088C000000BDD7D0B7854459670DDBEFD4AD24924 -:1088D0003A9DEEBC091D020818620742001FD02114 -:1088E0004482B2DA810041519A87184948A2E2CA0B -:1088F000FEBA438720467466C2AA8CBFE3B80D82D5 -:10890000EB286AA2D1418CD8A0F8D8D59DA0AE8B17 -:10891000B3E846C7415E4322A32BB3CB0CFF39A774 -:10892000AAD2F7DE744370C7FDF6FBE338D7BAB7B7 -:108930009EE77D4E9DAAB63915C63C8C7D5B73FBC8 -:108940005F4D628CFDABB579BCD3C1D859FC9B1E81 -:108950007DFECB3AC6221731F6E13A3B8BD8A01CFC -:1089600036558563D4FB53AA8931E8E85FE1C14AF3 -:10897000190B2D50C33B94C1F5B2705CACB7785E57 -:108980006A30463FF2B9A04665113BA3BFB3F06F12 -:10899000CD9C245DF922A753F4D39A182C62EC885D -:1089A0001CF7513EEE91307F2FFBBB488C7B247C23 -:1089B000EE716F7E04C61D131DE78666FDB8BD2CE3 -:1089C000B48AB9619C70A2734701C3FF8CD8264456 -:1089D000DBEF759A08AEEC48A689653076876C1B8C -:1089E00067BC0F057C8DF56BCC7E8B161FB7A77A05 -:1089F00069FEB25C33473F4F6F8A938FCB9CF981FE -:108A000064C68E6E4BF4133CA6258747C13C2BED04 -:108A10002CE480793EF8E4C59FB1118C2D13F8AF9A -:108A2000097C6D41781C35F5DF938CEBFAC0E4DCF2 -:108A30000143951DF45BB4F0BB2B85C3EFE8F673DF -:108A4000C3EFAE143ECF7955FAF9CD3F98A82B1B52 -:108A5000D7FBEF7F7BEF04ECF7DFFFF63B8BB6FF36 -:108A600005A77359243D5A5E52ABF8C34583C77DB1 -:108A700029D53A24B8BF6480E392D3F9D4BF5B65AB -:108A8000CD1D31D655EEB453FDF981728B07E0B997 -:108A9000FC6EC5A74017339CBC9FE566E6EF80F9E6 -:108AA00030B337BF1AE0EE696DBE2310A39FFF23DA -:108AB000E0FD8D23901A8BCFE4F363410FB2DE0209 -:108AC00073D012ABFEC25A3D7C7B19AB8A35FF1FB7 -:108AD0003B395F0E951EE5F8C6FA439DC7DD820E51 -:108AE000D36D91DF33155E9C807ECA2E605C437D22 -:108AF000E3B8F73BF5F8338E7FF4CF6A5D2C38BCD2 -:108B000026F83F1800FA89F93D99BE7FC0DA1B7735 -:108B1000137F27F9762018B62FFF09A09DAD9C7D05 -:108B2000C75BF09A25A614D0FA16070E5412BB9D07 -:108B300079B018F1FE6DD5833F2985A91DB5065B77 -:108B400093A1C1D1F58A2FE41D3CCE07B84E90A366 -:108B50001FA13CBD08FB639C6E67C2FF65333646B0 -:108B6000F5D7A3506177D9BC3B347CEB5EFBDD3A93 -:108B700056CCD853D6C0FA64783FFAEEAFD73094CB -:108B8000792C4CF3FEC2E2BB85E0CD18F1FDA16D5E -:108B90008EAD9BA05E6A0A97938CF9F203E335725F -:108BA000C2ECA4F250F1F3611CFC5CA89C92EB8C2B -:108BB000370E409EE6377786A34D4965ACCBEABDBC -:108BC00009D7D33F3BC1B90D5038D7EABF1AE1F3FB -:108BD000C10193A9A580BA35239DCEE343B0826B32 -:108BE0000AEE1F578AF2C7E24F80A954431B36157D -:108BF000E868862384FD957E38E719C4CF83B536AF -:108C0000AF8AFD4DF37EAA4279EE5536EF7AE8AF92 -:108C1000AC67C45E37F43F7F8EE264D07EE6EC51F1 -:108C20009E5E585FD25AE8270747B8B7AAC2CCD889 -:108C3000D3F89F97323E6180C55C45965F6C9B0977 -:108C4000F2609CA7CBE40050AF4C7BB1CD0EFDDEB3 -:108C5000D312C872A6C1D236DFD7661FC658468661 -:108C6000BF67BA8FB1D99BEFAFB25F01EB7C54B451 -:108C70000F3DD0E6CF63EC5553B04081EFCD9B77ED -:108C80005499015EEE4239FE2B6DFECB613D57DDFE -:108C9000B2630DF4BF25ED9FAACC38EFC572FC9EE0 -:108CA000AA8A9130FFCB65F95FEC385F77926C0F41 -:108CB000F39DC298654474FEE62C18DF25CB9F54C3 -:108CC000CD84F13F2E6FAE30C3F8C7D2FEBDAD6884 -:108CD0002C6393E7943BFD50EEDBFC1F5549809FCE -:108CE0002E06740AE53F6C3E4DF377AB26DE7FE837 -:108CF0008F34BFB2C5A171F85D617F6AAB8275AF79 -:108D0000B6F7BE85E4DAB43664CF4091A4703AB1C8 -:108D10005B9AFDB9003BCBAEF2482E4DA79DD36BBD -:108D20005E643CEAB181F218288FD794B378B96BAE -:108D30003D5B124BDE76BAB81EEE4A8CFDBD228D2D -:108D4000CB03801BE993D483CCBF33865E1997E6AF -:108D5000A07EF627B290DD15E5B76B8187A7005F8F -:108D6000323B9FA7EC6790FE48E3729F85AE75216A -:108D7000DFCCC12E60E9853E258474CD9A93C2A3D1 -:108D8000907658C43C0FF5876AA2F97A5465493544 -:108D9000F49791C8829DF0F4A4332A437B7FA723E4 -:108DA000DADF7B82EE2B0B03DBB1BFCACCEC92D6B1 -:108DB00082683F30EF0DF609BA799BA7B8F0FBDC6B -:108DC000925B8B34F02CE2EB003AA07630CC33D3BC -:108DD000810FBA7AC68DD804F3FB06E5AE27BAAE8A -:108DE000B29EB91606F5B6B8843CF1F2F69E0A2E8C -:108DF0007FFA6F4D0A6F43FEB4FB4A104FB2DD0D90 -:108E000002EE15F7CEF919D66BE8B1301BD45BD35F -:108E1000599EC9CEA1171B4E5FC6C213356573C4D8 -:108E20008A72A7E1F4347A5F71EF7B56E453ECC7A2 -:108E30000BEB5A93E0CFF421DC5A63E39FB1169A0F -:108E400047C3E934169AA87DCFE114EDDF4DDFCF9B -:108E5000B7AE687F2A0BA79FAB3F2B7D1F80BB5906 -:108E6000C0DD1A7B9E1B04FD20BC4D1AFA9A2FE828 -:108E70000DA49F1FE5E1A16B8AB6A1BC8F8EBB9E9E -:108E8000FAEF32031ED10EEC49F4A25D5C66E6F205 -:108E9000B3ACC7E50C2951FA907421F1DAE56A2EDA -:108EA000A7F5562BCE6D0583E775BF9C97D0A79984 -:108EB0008B83EA52CDFC243F40FF5DA2FFD229C440 -:108EC0003FBFE0F4027C7303F22FDA2DB80E5F642B -:108ED000FCDCE4C1F33F0DE4854FC02387FF5F391D -:108EE000C2A80724DC06C33FF73CF8CCA7EF653DDA -:108EF000FBACB8CE86387CFB802B85DA651E8CA453 -:108F000078A1DE19617774754C4CB80CF9628E89C2 -:108F1000A108C375A3BD5A36206FAF7C7706C8DBA6 -:108F2000CC8132C85B2FE26140FE46ECF668FD1F43 -:108F3000B9AE9CBD01E4B5DB06F82F223BD4CE349C -:108F4000FEC4EE346EBF4D09B29876CBDFB9927590 -:108F500072ECFFAEAD60BF85F599D3B8DE9FD21B32 -:108F600052102F92AF8D72EA13C18F1F8BE7FFBC97 -:108F70009C52CE23A7AA859CE2EFF783998FF53206 -:108F80003222E315D089CBDE9D380AFD99DBB2543D -:108F9000EF97C057F314DFB067A1DF1ABBF79E64E9 -:108FA0006F944E6A98DDEB40B883D17416F5FE9C41 -:108FB000042AE31FDA25A7DA154E87CC9B5A333EE5 -:108FC000BE1C92F3B82DCB4AE32DBB6F546A503BC5 -:108FD0003FA127AEB5459E658583F95C9661FEABE2 -:108FE0004DAAE6BB83EBB3B1C9FE6FD2D00E555884 -:108FF0002DCDC7602F3904DF19EDA587B16F0FFDA7 -:109000002F62233E3691739AD9660B33DE24847E19 -:109010006A660713FC1A313568E8C0EECAA3792CDA -:109020005E081F2F01A6B4BF71C9971A3E7A07E7E1 -:10903000437A213209F934C1C57476DE623590A7CE -:10904000A0DD9A69F3A19C013C111CF62730730244 -:109050008CFB363C116F95EAAD7B2D6EA403C5D712 -:109060004AD0DF2AFC5616417D73EDF424B25BD959 -:1090700099DB4756033C3C499C6EA11FBBE8C74E99 -:109080007422E4DEAFF3C76E43FD24E5A7C4033BBF -:10909000A3527FF2FB7EA53ACF09E5FD9E8B4A5A8B -:1090A00015BDFD83F650D47E4ABF6F16F0E3E4AAE7 -:1090B0008E880958A825E4997D27D4AF4CE26B1E11 -:1090C000E9E27A707F41484DC1FE46C13AE0D55B86 -:1090D00089C1A26647141F60E304117F1956783ACC -:1090E000387FE0739F8BF3D99C748E942DE9BC9CE0 -:1090F00091C2EB1BE9ED49F17D95C2F1BBA99CCB77 -:109100000963BDE92EDEDF6A7BA82A6384D6BE0A26 -:1091100030A44333E37696DF25E8A482C3ABE2DED6 -:10912000C5A9A837BFED999FCA8AA272F41E25E887 -:10913000F441FD7B2C819F52BCE35F5486FE883551 -:109140002DE87441BDF4A4D8FEF24D621EE9E84F4B -:1091500043BD9F087FC772FA62F2B317BAB83C4B9F -:10916000C9AA21798E30F4A29FC2FA434E0DFE5255 -:10917000A798747E83E57431B5BF70BBA1248EDDE2 -:1091800050AAB31BE4B846FBE1D37559347FD9FE2E -:1091900086AC8F2A99A6FE8DACF71EECEFC635B9CA -:1091A000BA38513CBBE32E011FB4134231E765D5F9 -:1091B000BDFF14FCC49076FC237CFCE8B849C06871 -:1091C000D171FD2EFFDD2EE2A7CB9D872F864702B2 -:1091D000BC5749DF90DC07BDE4DFEA207D5485F20F -:1091E0005AFA47C8F7CE54A4F1F20DAE491AFD2839 -:1091F000DA19E5D09F453CE3CF4E6EFFA51E94F6ED -:1092000062A25751A2FA66B0BE127AC62017CF6783 -:109210005F03BD86B4FADFD8EF53AEEF6B5716C6C7 -:10922000A18FD1FF237665D9E541753CCACD2A854A -:109230008D82C7E4997A3DDFEDE2FE47B72B49A75F -:10924000E7E72ED6D78B60BD49F84C1A92BFA2D55E -:10925000438A8AF28EF7D728E8A1E0D807562FC8AC -:10926000DFFF1276D017E9FEB791AE3624A614A31D -:109270007ED8FAA78A315B61DEFDEF5B7CDBB0BB99 -:109280005D9C3ECA17AD6935C37B4B87E2B4318D17 -:10929000DE5ADB79C90A58EF0792FEDD7C1D0DEE20 -:1092A0008875248C9BD3C0C7CFEBD8AB9835F22DF3 -:1092B000AF8ED73BE4B2E8F45EAF287F26FD0F16F1 -:1092C0006EA92CC5FA7EF326107D391D0AC583735D -:1092D0009A01004007393EDEBFC31756961745D79F -:1092E000D966AA2E42BDD09691E443BD30D61D3C2E -:1092F0008CF4DF70281241304D3ED46346FBAEC281 -:10930000EDFF0ADFCB757A55670ECAD5A4437C7E84 -:10931000ED067A070B59D0F9362E6F55F60E437CC1 -:10932000A0EC80F132D68F21BD24EB67B8849EC8B3 -:1093300060C117C8AE626D8CF0C5681D19EB47930C -:109340007D2FF119B5A3C64E403BAAF0818879194B -:10935000B4DBFD58ECF8BC45E81158074BF744D78F -:10936000118F2FA41E93F52C71FC6849EF4955B15C -:10937000ED53D000F4BD7C91FB3A5C77C3062BB370 -:109380002951F857B803E9389F9C8EAD0AC246D2DE -:10939000D706D7D34A2EACEFF65B985365F1E7DBDF -:1093A000B0F6C54B5668FC2DE89FF0B1D5CAEAB4BB -:1093B000FA54FA1317A773FD73A73B3002C76DDC8D -:1093C000B5D98AF8BD65FBE7566DBC7BD03A8608F7 -:1093D0002FA58EFB290DB5F630AEB37C9199F057D1 -:1093E000BFC11A4679D4B0B33362427BFA6EE6430A -:1093F0007E6FE8E87C2B07E092DBE09FA47AA3FD78 -:10940000E53684159C4F0610610FF979112BEA6738 -:10941000235DA33D8C76C95B099CDF4F943B420AD8 -:10942000C0EF8425D880F54E6427F942055178BFF6 -:10943000DD39EB1D05583AF9055B049F6DA66D59A2 -:1094400076A8D736CEEA433AAA700767A5037C5CB4 -:10945000E64017B64F7327FB5AA0ADD7C626907EBD -:109460001E221C261BE861F2DD9C4FFE263D45DADC -:109470007B13500E2D4D4F96F612C9A7B72C7C1DAD -:109480001B189FEF3E977F01D1ABD345E3E63444F1 -:1094900014B4F78DE346E9C9BFF842E81BEC3C2B56 -:1094A000CAF57A2167CA176D577EABA1837A3064FB -:1094B000905E72766E55D00F84EF2D956EAACF6CAC -:1094C000286776F2FD887AF87E9346AEC875C49018 -:1094D0002FB7217C1D877ADEE4F22542F427E76B63 -:1094E000C4E78FD2B91D77259805F4DE1A1AE385F3 -:1094F000FEDE1A9148FD497E37F2E78F049DE7D4DE -:109500006E57306EE04EE276A39C9FACF745FA8C26 -:10951000F5389FC9553D0487D5B566C29B9C4FA5BC -:10952000353012FDAF76D1DFBE859F597BA1FCD0CF -:10953000AF0E103DAE6E57FCE417B41FB0CEC7F8A7 -:109540005CE8972AC663AFE62609DBF2D201D22394 -:109550005777F138C1EAAE4EF37247944E0B8EED59 -:10956000BB11E96C75878D2528883FBE5E239D82DF -:109570007C21BA67212BED67817C0C913C65C1028F -:10958000F447A4FCDD27EC4BE6E0EF9F10F396FDDB -:1095900046E56602D17BC1B109FBEC00CFD53EC5E3 -:1095A00007A612D8DBBC1EF41F21F9CBD808F4CBD8 -:1095B00064FF46F8FD5AC8D518787E3E3D861E9158 -:1095C0007AB5E0F1190C9F127F660177D9EF9E748E -:1095D000BE9FB527DD4CFD6F28E7F1EB0D16AE3FC2 -:1095E00036B4D8C3C8D76FA75DF98E520C707259C4 -:1095F00023F8DC6F5AD680DFF7E7F079B499D68F7D -:1096000069E6FAEBF574C25F0AE3F289CBA3875EE1 -:10961000E4F2A421E4203FB12158B382F61FDC0913 -:109620003EB4F759F04DEBFCE4283D18F1EB7D61B9 -:10963000AFD50BDFAFEEE07C10855B5847B720E776 -:1096400008EFFB5C723F2258807005FFBD05E30CFC -:10965000D27F4F591C08257B07F36BBAF0DF27092F -:10966000FFDD32C5FE17F5DFEBD7FE5336965765A3 -:10967000BD4B4FC92FE027EAF8EA84F0DB0E08BCA7 -:10968000FF41D04B7D6907F143FD97CDC4478E2A3A -:109690002E4F1C87F47290B11F8BF53F40FD54266E -:1096A000755CA9A23FFCF78AB395C59FF7CD4AF335 -:1096B0003F4F45BC74AAB42FC5CE80555F06704D90 -:1096C000103010F52C6E1EF73EF1142002F9D2DC9A -:1096D0006C3D97FD7BBE7E59E42305F15D2F607DD7 -:1096E0006267C5D4DF613CF1A954DF2858FAF19DC7 -:1096F000F3FEE677D0FEC4F6E93ED4D3EED600D131 -:109700004FBF27C1877143B70A962DD0434BC71B64 -:109710002997E1BED833974C40B999E7E67C79ECBC -:1097200045752DC267FD3F3C3F0DBFD7879574B48B -:109730001B4F3CF5F77F46BD58B7BD093D0DD6FA26 -:10974000CCEB64879BC25BF9FBA752C9BE3CFAC451 -:10975000E66908F7D68E56FA7EEC89AD54DEF70F2F -:10976000CFEFF94FB43702293EAC77ECC5CD3FFAC5 -:109770004FA4F39A141FAEA32168E6FBB692BE8DE8 -:1097800072AB732FF1A9A497AB51EF229C6AB9FC7D -:1097900091F4FC85D8575A56E1684379F6C5A6E49A -:1097A000BA58F144BF582FC65C488ED52A144F6B67 -:1097B00003AAC1B8465B229B82CFA4A2883517C6F4 -:1097C00059B8B8731AD93DA1CF5762FD79BB12D8E9 -:1097D000268ABF61F016EC7F2275C6C683183C0C42 -:1097E0007E32F4BEFD2CD8D71F5B309643FDE9ECEA -:1097F000FF796DEFFE11E5688DBD77AFC71B7DDF8B -:1098000026E234509FF44ED99AD8F1D02AB743D0EB -:109810002DD79B395DD5795E921336DF288D5D3A61 -:10982000EC60F32610432CA7AEE74A5CC75563965D -:109830004E24BAC0381FEA9F9083FA5F8D714AE0C8 -:10984000B3456ECE4F194EE6BE14C6AF3433B703E0 -:109850009F8C7D642139B283FA05FB83EC2AEFEB00 -:109860000B77A03DB2C512CC9E84FDB409BDB59D59 -:10987000CF1BDA3B71BF14FA735E3A81FAE9B1B8D3 -:10988000A87D88B79FB5BD4589CE1728351FF51629 -:10989000F657EA403D13AA25FC78ADB4AE635825CF -:1098A0009BD65D7CC3F828FF1AE33B28CF701FF8D6 -:1098B0004E77F96DEE49D1A78CFB18E1F9327E871E -:1098C000757FEBF6D3933D95AED32BF1EC957D0BE5 -:1098D0004F72FDFBEAE7246F1A918E71FCE0973A14 -:1098E000FDBB5CD2F12B9F131D2FDFC5F56FE3AEDF -:1098F000122BD2EDF1757EF65B30401BC53EEB16A8 -:10990000A57725C5795E497062FCEEA4D037F50FC6 -:109910007C7E18F74747ECCA26BFFEE42B09B5D872 -:10992000CF7E9389E0B97FDBC55B5B15ED3CB93F2A -:10993000007630916A23D8A9DC0E5EB119FDB3D54B -:1099400075CC87FCDF68A09FC65D07885EA41D5CA0 -:10995000F0F8DC15DCFE4CF025A0FF3693DBA30C01 -:10996000EC51AC9F3633DC6225FA2A2943FADAB788 -:1099700070CF46D4E38D339913FBDF32CCFF4A2EF0 -:10998000AD476198CFB2C5D23EC30CEDB7547A9DB6 -:10999000004980DB76B27BD918ABD0732BC85E6EE2 -:1099A000CCBADE477C669407AFB490DDD5E84DA411 -:1099B000F95CBD4BB98DDB230EC6E7AF107D5E1D94 -:1099C000BE2C8CFBCABF17F093703C69E9B911E15A -:1099D00071F2252044F87EF54C4EAF69333B488E3A -:1099E000BCFDCA2CD2E3922E935FB6913E77999D2F -:1099F0008A8FF4DA3C9B16AFED16AE97D2849E297F -:109A00007C80E33722F82922F440C46DD5C75B9CE3 -:109A1000A162D4BBBF17F8273182F25DC893D52B62 -:109A200022C44F0D3B797F6E9BBFE4760DFDBA2BB0 -:109A3000B85E94717FDC07A88E212F7EE7E6FAB12D -:109A4000E0F1659BD15EBE0AF08E2A25678C90A35B -:109A5000401708B79CBA00D1C155EE9B7D6A01ED55 -:109A60001F909FD8DF6265B1E23C47851CF5A407D3 -:109A70004A31DEECC94C263BC7A3969B12B05D89E8 -:109A8000E2DBE6A5FD4DB2F3FA3DD9BE6D3A7E0F9D -:109A9000949AA0DE918C648EE7F0AFCD73C7231F3C -:109AA0007AA59FAEB3FB06FBDBDC6E9CD31E2A4679 -:109AB0003F44EE5F4838845B126BB5F2B34FC02170 -:109AC0003C96C7F3C1BE7750FCDA09E3A05FBFED57 -:109AD000B227B85FDF4AE31F74F3784625AC0FED79 -:109AE000364F61600DD7A7C9BE58F0B853E079DF93 -:109AF000C21B4BD0AF6CAC71F890DF1E7A55594643 -:109B0000F48CC141F4B7832B080F0CF080FCC082A9 -:109B1000DC2F6D6C0E8463D37B35F15F23F29F42A3 -:109B2000F44EF176A0F730A777AEFFA4DF8FF2B145 -:109B30003AC67EA8942F8DD6DED148C7921F1AA7A9 -:109B4000F58E46B80D559E9CB400FF23FF001C9077 -:109B50007F24BF24EFE67CB2A9C55B8EDF37553288 -:109B600067AB461F19FD259C27FA9D52AE8F7507DE -:109B70000A3D1807304536621E8594C38DBBEF1B26 -:109B80001D2BCF4DCA61BB99CB377B3829DCAAA1ED -:109B90002FDCDB4B9E404FCADB495A1B3B2E52E663 -:109BA000718878FDD0F222325097A3BCD996144622 -:109BB0007925E344C67EC778145D3C46FA2DB8BFCC -:109BC00080F5E77A38BD547AB89CB85E3CE5FC2550 -:109BD000FD7B4DC1CF319F289EFE92EDFE52712B31 -:109BE000398ED4A346FCCBFD115C4F7551FC7AED48 -:109BF0007BB97C32D2E372C1275E5C2BD47B4EEC06 -:109C0000670DC62FEF87D59A75F96F6DA6CEBA5836 -:109C1000F12FB9BFC11E320F29BF6EEF3A9E47F533 -:109C20009CC8A7658BCDBA7C2A87CFDB82F1D3197C -:109C3000F6821295C6E571ACE469EC6BD4C3C5BB82 -:109C4000DAC7609E9227A0DF1FC9AC4DD4ED3F64F8 -:109C5000075DBA726E5D8EAEFEB0E611BAEFC3D785 -:109C60008ED37D2F084DD0950BDB2ED5D51FD53E3D -:109C7000439F8FFBC855BAFA63C37375E54D2D1D1D -:109C8000B588978B9FBA4ED76E86D9692E01B88E4C -:109C9000EF58A6CF1333C033F5CF6A4C3A7CD2537A -:109CA00040789D61D6E70B5FB24B0F0F4C8BC3FE24 -:109CB0008A99E86FDA9109E7CA632D66E66F7A65DB -:109CC000FB82C1F4C0ECBDBE400C3F53D2B92C1B8B -:109CD000F7B1A4FCB850FA8B374F497FF1BEC78368 -:109CE000DBBB1EB90FC3E16219804BADEF5C70B1F5 -:109CF0009C0F2E0CE092FCFDE162EC6F7D5223E59F -:109D0000037F84058D7DDC2BF84896178452B91E9D -:109D10000ACC3B8F1DCDE3C0411BDF9F347EB7676C -:109D200070B9361AE640F019225F7F26F070281EBF -:109D30005FAFFD7A7F26CAEF2A467EB3B3B9E56BE3 -:109D4000D45B4BCC1186F4FF9058CF169117FAC80C -:109D50003A27F5F3A8D87F7C6C9D97DE3FBE6E0C4A -:109D60003DC3EB7CF47EDBBA29F4DC0EF61C3E9F8F -:109D70005C5745CFA7D605A8DED3EB6AE9B9735D7A -:109D800090CF6B10BE5819D93981F498F1D2A52122 -:109D9000754878626A5E4C7D19B71F75F139F3C852 -:109DA000D71E5A34FB4D0DFF666524BB0F630EE3CF -:109DB000643619F733CFD7FEBB75B5B3DF1C3574E6 -:109DC0003E92F4C4CEA48F8EC5D741913FF9BB8794 -:109DD000CF6E0A15C5875794CE62C3A9C67E3207D7 -:109DE0009DF562B41934ED0F1AF8B826981AD36E9F -:109DF000A811F4596BE3FBEF8B0CFCFD92F8FE52BB -:109E000006D7779FC49133576798A43F6FA1FDC0D1 -:109E1000417CF7932B62C1777F8657C7C78B820639 -:109E2000BC1AFAF9C4D23ECC1783CFCED78F5C9F31 -:109E3000B1DDC3195C6EBDF8FF297F7E725332F924 -:109E40000F08378F66FD9FDC94541B2B2EF35A06A8 -:109E5000DF0705EB9C15B8C8D40F59D1561CC3BCFD -:109E60007C9F77A413E343320F203EBD9A298E4492 -:109E7000305407C315F0E1B51642FFE68171226642 -:109E80001CC7678AEA59CCA9619A731EEA607A8076 -:109E9000F6212BE5EFF4E6D0BEFF05D213531F1BCE -:109EA00075AE7DBA41ED2F50CEECF881E58CE473B0 -:109EB00076E6C151B1F4642D8E7D29AC63CBD4FB21 -:109EC00049CE9CA7DF0B855FADDA4BFBD64386DF1F -:109ED0002EF790E2526BED29C50CFCBAEF12F83365 -:109EE0003483F1F3589F2584D1CE3F20E6098EFFBD -:109EF00025DCAF6E9E8CCF7FCE0A7C9801ED975902 -:109F0000B99F383EC3FF119613C53EB035D3BA1181 -:109F10009FCCC9D7718958C74693371FD7F1A5E29F -:109F20001B8B7E8AD314F6E1338545C6F3BCBB7028 -:109F300010FDB3F48B13BDE8DF268E66AC87E2E13B -:109F4000BE048C9B5993FAFF7124F2FBEB268C30F4 -:109F5000B2E79D7CBECF3F924BFB2AE801A17C2853 -:109F6000C6F730F54D688743FB6B59F018CEEFA864 -:109F7000D31E32C1BC8A677FE1C27CA8E7BB67D031 -:109F80003E42E4293564C5730B3D27FEEE6AE8EFD7 -:109F9000921E0BC59B2F612AC9F37A337B00F926E9 -:109FA0001E3C8FFF75ECFCAE2B32B9DC93795BC69F -:109FB000EF79E2FBF13879C48E4CAE17647E8C45A4 -:109FC000E6C778FCE7CC8FB118F2632CE600C37DBE -:109FD00060CB407ECC6246F931D08F363FE6F88CBC -:109FE000D8F3708B79584E27C5E93785DE1F1F716E -:109FF000EE755A4E27E8F2ACA3ED1DF43E5E7ECE20 -:10A000007831FEF138F9496307FACF66A1746D3BE8 -:10A010002F9FF7C03879F4DD62C8F3897EE7F93DF8 -:10A020001BD2389DECCD72BA9742D74B59AF05E998 -:10A030007489C36DC1F85180F93AE9DC8ED9D2DF59 -:10A040002BF96E04D6337F8176B609242DDAD94BED -:10A05000D65ABEE8D5C8A96ABFBECCB0BE46EE6E21 -:10A06000CA6234DFC4716328AFEF14F3A63ACF217C -:10A070003717DB55BB59B3DE4371EC865B05FC0E2D -:10A0800065C786DF7599DCEE88771EE2D6CC14DDD5 -:10A0900039BDDB9DE7969708DF60BAB67F231EDCEB -:10A0A000F4FD7C70F6E0E61AC6D1CA159EBFFF1714 -:10A0B00087779A3857C5CF05580C79E89BB2B8FC1A -:10A0C0008BCE9BE7A17FE40CDC9E8972D1EC1DADA9 -:10A0D0003D07D065F6274D80E72121778C70D99D0B -:10A0E000C9ED37E3BABB443E7DA2CA9A3B35F0378F -:10A0F000AEF73941E7B2FE060BDFBF82BF801DF02D -:10A100007203E372EFE1CC11222F3CCD8CF270315F -:10A11000EF82DDE07C8BF693249C07C14FC0DD0805 -:10A12000C700F3DE8879DBE783674796FF6184CB5E -:10A13000D203895694FF37DAFBF7A38FDADB63FA91 -:10A1400078243C3F778C3CBC9DE1FEDB9897F7C1BF -:10A1500033658A8FE751B09964EF28A15CF5ECC5AF -:10A1600043B77736A604C7207F7C29F2AEA53EDA36 -:10A1700098736C34E6CF7B5DE5ABB23C1477F7A700 -:10A18000231DBD66E374F408F404E5A63D63B7A29D -:10A190009E79302B5887F5641E1FF3F78FC63C84D9 -:10A1A0000B8513FC59908ECE07A7273219E1E75093 -:10A1B0004A6C3AF94D1C3A31F2079D2F2BFDE1F81C -:10A1C00043C253EE5BC8F9D565713A944F093763C2 -:10A1D000FE505D9649D4E3F9880F660508CE7DC32D -:10A1E000BE3E9C00733F64C8F792CF93421E9D6FA2 -:10A1F000FD12DE3F941C3E94187B7EA6ACA1E1E7E5 -:10A20000879A5FBD9C5F71ECF965660D0D7E01D686 -:10A21000FF59DA0FA0C700CFF58867B6A19FE4E326 -:10A220002157EC79960D799E41CB0FA16F257DB317 -:10A23000D0D23ADAAFCF4A8CB95FBF00FC27F47FA7 -:10A240008CFBF6727F1EE407ADB7C6DE7F633AE291 -:10A250007DA65877068BA4E17EE61E1BC5FF8DEB1D -:10A26000BF42D011C0AB82E035A79FE2188746C736 -:10A27000960B15C6FA6D7C9C78E70BAECE528674B1 -:10A28000BE80950629FE576E774454C0C36D021FE9 -:10A29000D6DC553EB40FCBB3DE3B88EB04F89F18F9 -:10A2A00080A7269FEFD8BA779C232DF1E576BDFADB -:10A2B0004259738CF5043DC11BB3347E50FD53EFFE -:10A2C0003A476AF0359EF59AF8F9E87E93CE2FCE9C -:10A2D0006417E41757639F988FE00A903E40FD8013 -:10A2E0007A67E3EEA925884CB433309FA73F3991B4 -:10A2F000E4686BCEA563BC1A7886B2A47DA9C6B10A -:10A300001BFF7BF9FF51BB49D1D9AFD1FECDF45E24 -:10A31000E2A7DCF18F31F111F4F8EF213DE6F26FA5 -:10A32000C4A7117EA17B2F4FA3F30508BFE9D1FE7F -:10A3300006F01F07CF1D1E7F3BF6D720CED1283257 -:10A340008F6F205E61761EB647E13D54BC248A784B -:10A350001AD80D8F211D586D821F9983CE874BBB54 -:10A360008519EC1B3686FBB73764BDF7478CF76C55 -:10A370004CE12CBBF14709E4072E519C565C37D8C1 -:10A380001F9FFE1CEA0759E4D3BBC83F9476469250 -:10A390007A3669E8F394FEF2F9F2A9F7A13D06F3E3 -:10A3A000996172D0FEE63E585F36C88D1956FE2C74 -:10A3B0009F055405FDCD50F3BA7B615EDFB2338952 -:10A3C00057C0F3A78CC361CD81DFB9D01F9D61B6A3 -:10A3D0001CD3CA2D63BCE38DAC6437E151C43BBED2 -:10A3E00065737E7D31C2E57217C1A5F8959999DA3A -:10A3F00078CB40BC43AC635E682997A7063927E554 -:10A4000099C9CEEF11617EE6756650DC88C33DA424 -:10A41000303394AF90657452A07CB9409282ED6164 -:10A42000DD5788275B16CC423983693C381E787F1C -:10A4300059F86C9DEAF3E273BA1230F3798479DE4D -:10A44000216BCEC3FA267BAFCACFE7C10C32B0BDB9 -:10A450001C8F9793457943CDA91B6FF20E8E633005 -:10A460004732D9BD5631AFA34E47C804EF6D8EC8F1 -:10A4700051CA4F154F63BCE33B532884F9D977AADF -:10A48000619A6F128B447A303E61071098288EF0E3 -:10A4900007E403F06E1A719E09CE5391BB18E6399A -:10A4A000FA152CA71BF491C7B186F29E3D01B3416A -:10A4B0000F0515E49BCC5AE37BBD7EB2B343741EFB -:10A4C000488904B2CEA69F3F5E638CD35866701451 -:10A4D000F7DFC2EDDE8F13793B4917E9D95CFF3610 -:10A4E000BAAC8CF25D32EC76B4DB4F261FC12397F9 -:10A4F000A837DA506FD82D7E8287D41FABBB6E652C -:10A50000889FC65DD50CE5E86F14BEFF19BA41A15E -:10A510003C05796F436D117B1F5AB2A6EC1134CE06 -:10A52000FC7782373440B9E63D363E02F54AA6074D -:10A530002AF17E96D6F1CCB71ECAAD09C1675FC2BB -:10A54000F51C50A99F26712E963167FD4EE87FEBD2 -:10A5500075C37C9B704915FD1B310FA8FF3EE6C4F7 -:10A56000BC9141747A06D607F87F02CB30EFA6156E -:10A57000C15FDC01F5B3DF633EAA23BEA32F82785F -:10A5800053043DE0FBE9F0BE49D04D61B7C2F7EF9F -:10A59000DD36CA9F600733895FE6DBF9384DDDE5BC -:10A5A000D74E827915F64C24321E09F531BF093396 -:10A5B0000C787E1D237FD9587F24D6F752B48AE7C2 -:10A5C000D5E458E9FE2326E4DC6403BF5D16A57FCD -:10A5D000FA5E22CA4D421FE9F804FB01FFDC5FC6A8 -:10A5E000B7F3A99D9BF3838FC93FCEB797B2E81FFE -:10A5F000F65B111D87E4EF4CF16DFFA2D994D73DB6 -:10A60000D91CD98B7C7D9978968827F2B51DE0B846 -:10A61000D0DCBCDF03EB495BCB7C2D38CA626F2BEF -:10A62000F657CA022AC2B9CC795F2BCE6FEAE20391 -:10A63000E9485F4F6617123D5D6EF715260089B435 -:10A640004EF1F99CF0AA76B14270995F6B0F63FEF0 -:10A65000DAFC81FB7A82050B806F160615718E3E3F -:10A6600058B058138F95797D0B6CE047C7DA77CED9 -:10A67000E67A5CB66F12E74EE4F76DD90E9E5F99ED -:10A680007D655336E557F07C67E0FBDBB22745E597 -:10A69000088C4BF928F398DF82EB9A27F856F2FDE5 -:10A6A0007CFFED64B7CE0FE8EDCFDF281CDFA145BE -:10A6B0000AD9830B6BCF6D9FB664CBFDDE3C27C5FB -:10A6C000B799D4479CAEA4DC9E8B7A1CE56D15E847 -:10A6D0006D8D7DBCF8CE3369D42EF3C9D56787471D -:10A6E000CFB93419CEB9348A732E4DBB5A2C1948C0 -:10A6F000EFE29C4B53F7E71BB5F97D124E83CFB9C0 -:10A70000F4535EE3026B782F9EFF59B00AD608F52A -:10A71000DF10E722DEC4731113A274947C5D4284BF -:10A72000E7CDF9297F2FCF99E4C37C9336D304CAB0 -:10A73000176A4B49F669F37336B53457623D99276A -:10A7400024CFB52C88B31FFC9C906B5B149EAF1577 -:10A750005A6427787B5476507B4EDF5318A03CB95F -:10A76000A66C2F8DB345C41130AF74223CC3608EEC -:10A77000717CF1F646F900FD6DC0FE2A0A7D941F3A -:10A780005391CAF3CC3CE98192DB8AA2FDD674F3E3 -:10A79000BCBC9AC0D76FF1FCDAEA5284A7519E4B39 -:10A7A000FA32CA75A0BF7D488FDF99B8DE89CAF733 -:10A7B000C0A29BA0BFBEF7AD943FC7EEF62B1668B4 -:10A7C000F7E2BB4E1F9EA7DB501EA8AEA4EF663A71 -:10A7D000EF9751CB2236F85EFA9E751BE6EDD5B1A8 -:10A7E000762BF65767D05BAB1C6F5A913F576DB70E -:10A7F00044E99161BEA1AF10055DC3CE41710F92D6 -:10A800003F522E19E9988DD4CB9F12296F412E709B -:10A810007DB598EB39F6A482F19FBEE423AAF09FA0 -:10A8200049DE4D9242CA20E72775BF4DF6CA3490E3 -:10A830000FE89F29582EA6FA5406F93906F3472F38 -:10A840006389445F83EC0431AFD28179737B48CA5A -:10A85000C5F2298CE17D06122F300ED1B3DCAF9BFF -:10A8600084F7F0C0F33231EE9D267F5144413CB174 -:10A87000B0A910ED8820D93B46FBA7CCDE9C6487AD -:10A88000F54D61ED241727EF7F93E424E0F92CCAFE -:10A8900099D798C4B3CF8E72A61213FF547CEAF1F5 -:10A8A00034CBF19019E1342BCB888F9019E13ADB4E -:10A8B0003B084F744EC01F074F7E2947985E8E1489 -:10A8C000B033FC5CF27D6FDD817EEFF9EC900F3DE3 -:10A8D000C1AC1C929F7A7B245E5E5D418EE382F266 -:10A8E000EAFA2CDC4FB894F5AEDCA90CA68B93FBEE -:10A8F000D7AA591AFA9174B95BE4D92BAF8BBCDD96 -:10A90000D264D27351BDC8F15F264A97225D69F0C7 -:10A910007FC5AE84880AF45622DA5F8AF43021AA11 -:10A9200017232687D70AE36E547C6D6A0CBC67B880 -:10A93000BCA4FF269AFC2AD953CC978E7806BC4F2C -:10A9400043784DB177B49A619E87ADBE9FA3BF5245 -:10A95000CEBC84F772837EA970D498913F2BEC46CD -:10A96000FCFA09EF95CE41EF4DDF07EFC311EF522F -:10A970007F0CC1FE04BC2FCC89B15F180FEFC1EF73 -:10A98000897723BE25DF7726382B1C18D7ADE3F94E -:10A99000C413DF1FD98AE58CD50574CEA533CDF756 -:10A9A000067D6FE6DF4B7BFC2ADE9F58B806BE4370 -:10A9B000B9B3205081E5A6B50AC9CB491F055BB1E3 -:10A9C0003CF26EFEBD647DF31B780F595388B7DFF0 -:10A9D0007D7423DD2711DE28DA97B75760B9A98D7A -:10A9E000B7FF2AD91E42FFBAEC60B815DF8F7D8011 -:10A9F000CF43DA75D3059D752A2FBC41EDDA79BBBB -:10AA00009BDFB227927C1276DA34B1CEE98FF175F2 -:10AA1000BA7F7B559517E8F0A6FE9005E9E0B0A94E -:10AA2000A18CE4651C7FAB5C69CFC3E72C900B8CD9 -:10AA3000F00DF43982E79B6E83211ECBE17686CC44 -:10AA4000D3C47CF16A0DBE1ECBE17127592FC3C55B -:10AA5000785EF1A3C964B7CA3CD2C8CF98827100AE -:10AA60005C23E9D73879A5B30A9B495FCE1A2EF348 -:10AA7000497BCDCB60DC92B37FB832967FFD8418E2 -:10AA8000F788C87F97EFEBC20526F43F3A9178E844 -:10AA90001EB3DAF7D12EE94C63BA7B423A0B78B990 -:10AAA000F3D19A1FB7E5017C4DCDE6100AFD7C85F8 -:10AAB000EE3DB9A68745525306CF7F96994578DE7D -:10AAC000039FFFCA56EBB64D1A3B7DBE141B978FF2 -:10AAD000223D5223F024E5C57C812FE0EFDDC8DF65 -:10AAE0000BECCD64172E12F2FD1616A638C52D06F6 -:10AAF000FEAE777CF399C984F1303D1FAF86E970D3 -:10AB0000BDD0FFF82700FFBA47929DA8E75777E826 -:10AB1000EBD53DF2FE416E5FE9F9BC4EF27958CFBC -:10AB2000E76038703EFFD938DA7F91E7FA12ECFD22 -:10AB30009F855874BD03FADDC07F0978CE6F0CFA8B -:10AB40002D269E5F28CA72DC53ED5C0F87400F0BE9 -:10AB50003F8744EDA943B3C3480F25827F251F9744 -:10AB6000087D3E485F5719FD9887883F268A928462 -:10AB7000BBD4CFD00FE967796E10F4F2FB7EF2EF11 -:10AB8000C1FFC4798ED3F3CB2605E47341D45F01B2 -:10AB9000BC7D8D7803796CE7718A7686F22CAEDD08 -:10ABA000EF5813D3EE074947FB0083EDFD88CE8EA7 -:10ABB00037E22B9E5D3F80AF04B09792D08F67C481 -:10ABC0001FFF88CF21E475809C76E4C690D3D67DA4 -:10ABD000BC5EFFD6048A17C8F8B8E437258FDBD5EA -:10ABE000EF66F95DB9B8FF20FA3F74EB2CDAAFFEDF -:10ABF00086F969BF1AF38D7263E44BE07EF5064D6A -:10AC00009CF4505AECB8F5F05CCEEF4B72F9BAC632 -:10AC10007BFC5E1CEF8895C7C58F248A670ADF57C7 -:10AC2000B83897C7B9978867B9781E1179D8475C43 -:10AC3000FA78BAAC5721C6F9729DDDBE412357BCE4 -:10AC40003FB335A3BEF2148ABCF5359C5EFB5E496A -:10AC5000DBAABDAFED9ADCF22508474FA1DF9A8D44 -:10AC6000719657B85E6834F75A31BFE41A77702A84 -:10AC70007E6FF432FF0BD88FB7D73A0FE0DC27F6A0 -:10AC8000E9FB2CDCDFE84BE04F39AF6B72AB97E0B0 -:10AC90007AFB6EED25F93050AEEE25FEBF2637402B -:10ACA000E3F6CD97DF45F9C7BCCC847F582EF882F8 -:10ACB000E2BC31E2BA83E3B8FAFB679AACB1F7972A -:10ACC000595EB22E3E7B43378F1BDE68671B73E1F4 -:10ACD000FB92EE4CF21FEA5242A39D14C7FBEFC554 -:10ACE0005DFB86F5D0BA3695F7E73F5A4AFBB814B4 -:10ACF000F759DDFD36C9B9D5924FBAF47C522FF021 -:10AD00007BBEFD0F635C7C08FCB32616FFBC8CFA8F -:10AD1000C91285FF6D220FA9526DA8C0B8D0A91520 -:10AD20008CCEBFDEF6AE4AF474DBB30ADD0721ED4C -:10AD3000B3D502BEF1D683E707BC1AF981E707BC99 -:10AD40001AFF0CCF0F68CB787E405B1FCF0F68BF18 -:10AD5000E3F901ED773C3FA02D97B0E5AD18676BA7 -:10AD60006A63CEB0979F27D0B6C7F304DA329E2726 -:10AD7000D0B6C7F304DAF229C6E178EA3195E2F4F5 -:10AD800078AE40DBFEE677276621DD7425F03C32A5 -:10AD900016F2F714015C5608B8E079036D7FC753CB -:10ADA000AE7C8701DDADE85939079F97EC5AA5EBDA -:10ADB000AF5E6D203A64ED5CEE36C33F243FD52292 -:10ADC00015E7F1ED2E85A517E0FDE106FDD9BD796A -:10ADD000238A9E5BC2FAF7F54C13AF2D181C977FA0 -:10ADE0003957E421E6B01C6D9C264A070E5F04D754 -:10ADF000FF91EA8B450725ECA2548ACFBCA362ECF5 -:10AE0000817DC59AB75CAE68E2F70678D8B2F4F4F3 -:10AE100090E0D5D343D2183D3D24FBF4F4903A455D -:10AE20004F0F69FE71E7846F7A959E3E8CF09D020C -:10AE3000FF207C27E0CD9018578275629CF72F0584 -:10AE4000DF2F72C5BE8780EFB7ECF20A87973ED737 -:10AE5000D8CBA2F649E93BCDB4496B8C7B4A384A42 -:10AE60003B41C62F2731EEA7DBF1BC6521DA01DCBF -:10AE70007F43FD8F7C7ED8CAFD36A420949337B1E2 -:10AE800020C9A39B0CFAFF66C74356D4FF83D60B99 -:10AE90001617DE1B685C2FDA514C134F32EA7FA580 -:10AEA0005B892417E372BBA55C0E9E2563C7AF0CBC -:10AEB000455EFCDEE1B7E579681C662FD3C57B6390 -:10AEC000DA73721E122E727C1B6B56B3909EC718DB -:10AED000ED2FBDBF2CFD6BEA54138F96FEB1F44FDE -:10AEE0008C7056871790DD35D129FDE29EEBF1BDC0 -:10AEF000F4878D7EE8F9F6A5E68594DE9F1744ED8C -:10AF0000C92BC4739E8817C1B27EFB6FD0F872C57F -:10AF10003B0CC79BBBFB220FD2CB46A59919E6770A -:10AF2000F055E84735F5A7F3F84B50B75FF5B6D2C3 -:10AF30004BF35EC0FCF7E0B351C4D31ABBDEA67D71 -:10AF4000D4C62E1E2F60BBF47831DAFBAB5887B520 -:10AF500040196CEF37B01EEACF68DF0FA293F3E819 -:10AF6000F18E3C79DF16CF1760422ED50978C5F3F4 -:10AF70000BCC08E0A9D1FB3B811FE6E54D8AE6D169 -:10AF800066B8C08F51310FC36B8D9527C5F0721510 -:10AF9000B049973B6A484E2C6F1B1497B0123FB5CF -:10AFA0009F7B7DD20EB81F7C377C96E67979DC20BA -:10AFB00071CE3B7EFC5CDA93AF3DFFD164E5E70EDA -:10AFC00059B3FE7CFEDA3C933C3FA50E65FD83E160 -:10AFD000FAFDF2F265FE01C0EF2E2DFCE43E825C2C -:10AFE000CFEF27F53C89F1433579A61DFD5AAF2BEC -:10AFF000D882F5871DEC3DACA03C7378293FE4E492 -:10B00000AEA31FA3FF2ED7C758EF16BCDFB66E97AF -:10B010004AFE60DDAE37C82E8AEFEFB50FDCA32005 -:10B02000F6377E126B5E32AFB9522D4AEDD5D8E9B4 -:10B030004B851F307978E0216C57FA615E0ACED7D4 -:10B0400032A283EEC5EABF83DBC16E95CD44F881A1 -:10B05000DEE37ADF61A67D077752484D413B6E29DA -:10B06000E3F7D0F99A7D482AEAB0228AD366DCA1B8 -:10B0700006D0FEFE74CDF2343CAF9C91BC22AD10E4 -:10B080009ED36DFC5E9A0CC514E0E74E97A5E13D9A -:10B090002037D8F8BE7CC15F27450A81DF5EB7F252 -:10B0A000FB46DD4941BABFA03F4DA5F91C5B074BEC -:10B0B0001B85FB1EDF4CC47B0772CE3826E07CB2BA -:10B0C000C5BD163FCAE3F7DC1C7FF6BB89E8AFAA13 -:10B0D000671D74BE5DD29FBB30B6BFB242C0A3D164 -:10B0E000C3F3DE4F0AFBF190D86F9579F06BC43E45 -:10B0F000E0A1D103F78379302FA431C19FBA10E3C7 -:10B10000110754CA6BFFC6E94F4D23BB99E7B3AF94 -:10B1100011F6C34991F7B966F68C4CF42FE2E54B72 -:10B120001FC8E376EF0F755FA5CC3F8D0B873433D7 -:10B13000335F42F72E05CE55EFD53FAB31E1795A5B -:10B140007C8F9737DF97A7E8F2E21B312F1E5EADA9 -:10B1500079A53C939D235FBA11EF23D7E4D7A09F35 -:10B1600086EB6BC4FBC8E99ED213744F07F683F7D6 -:10B17000869DEFDEC815621E8D984F9EAE7DCFF97D -:10B1800039DABF9BBE3F2DE0F6F43BA6AA6D31E64F -:10B1900099378CCBA7711E7300F7252F8EF07B3F5C -:10B1A000E3D593E7B8E3CDAB6B46EF8D386FCCCFEB -:10B1B0008C355ECA304E2772BE5DAEDE9501BE9FF5 -:10B1C00037BA3A595376F6E7CFD5C8D7D9023F5D9B -:10B1D00057F5E6D37D00B3B9FF1A0FCF65E66605D4 -:10B1E000E190E00A06D11E91F715E37DC63CCF231E -:10B1F000744E7C47E1ACEACE1F0C86B395BECBFE05 -:10B20000A4DC39FA884A72E7E807821F99DFA19423 -:10B21000A1BEE27C7594F1B8EED176FEFB1FCB8225 -:10B22000A02B407E2CDD5E3F070F1FAFDC3171236A -:10B230008A7F7C7F37C89FA5598C4D83E7B20DFA72 -:10B24000FDB16FD903A4E7563C60D467012BCAD97E -:10B25000950FE9EBD7B107BE46FBA0CE60F76608B5 -:10B26000BD6BB47F670C13F66F192BBB90734E8FB9 -:10B2700030FFEC61A4FFF97EDB24B19F6EACFFBC14 -:10B2800097D3C36D3BFE60C59F048AD7EF319017FB -:10B2900023A1DF13EB9CF45C32CC5F330CDA350D69 -:10B2A0000B2EC471FA0E70389F6A38B592E2D2B58F -:10B2B000DC0EB0E1252BF09FB6EBEDE447DF8BF71A -:10B2C0008C019C6D366E5F48BB4A556F57F1275B0A -:10B2D000A6FE6E451AAECFFDCCAC2AF43F3CCF247F -:10B2E000F9111F9BCAFD2528BF37553B689F78ABD6 -:10B2F00089DF4368B7F1FDB9F0D353F7613878645B -:10B30000C7E619E86738BBF746302ED166E2FBAFD7 -:10B310006DD398B8C79A8FD7D45DDD89F3CAAF01D2 -:10B32000790FFD6D2AF0973835FD33612F350A5CB2 -:10B33000F4BD76D14FF1DEAB9FBF43E62AAC730478 -:10B34000C5BFC6314E3732BF847E1B43132F3A012F -:10B35000FA8769CE3F8FEB50229614BA5F8FE2D8FE -:10B360000DEB2319D7A3FEFC25DFAF95F373BF9E2A -:10B370003D03E3FD529F5E8FF96D18071676EF22AD -:10B3800026FFF87E41ADA0EB45C2DEBD3E89C37904 -:10B3900019F3D1F9ABEBEC2C05E3CBD757744CA2E6 -:10B3A000FBAFEB2D6968AFC8B8773CBCC78BCF3417 -:10B3B0003E99CCEFCB51FA476327C73006521ACDDE -:10B3C000B737F6B36398E0E7D1C24E1BC9FCB8CFDC -:10B3D000D2B8E722CAC7B725F27D35906F76C4EBA5 -:10B3E0007ED4E7B0EE5B5E4D88F07DE3B0B81787A2 -:10B3F00085683F664F26ED2BB80BFDB4EF7ED2D2A9 -:10B400009B4FF200E49702BA73CFB04FAE31E3FD29 -:10B410002039604741F9F82F0E5F83BFCFD238A2A1 -:10B420007725DE179EFEF8595E1ED77B18CBC31E0C -:10B430004FBC96CA137A57AA509EF278D6B5D41E3E -:10B440001D2820ACCAC7875F8BE7FC8E89F825F3DF -:10B45000F5D23D418DBB2F3269E38325F95C4E1F48 -:10B460004BE0F58E15B0257311DE637A476B7F379D -:10B47000C1932FED526E97C975CA762C2B76FFEFCC -:10B480000B3D708BB8DF677A126B4BE0FB1521B474 -:10B49000AFDEECBE88E0F2C2309780572FDDDB28AC -:10B4A000FB319EEF97E3AE42BD8D72DDA23F4FF4BC -:10B4B0001BA12F609C0D344E91BF04EFE5699C9B4E -:10B4C000578278037C9905BECCDC0FDC4A78C67EB7 -:10B4D000D38A498F4CC43CB137CF40FD82E8BC8D44 -:10B4E000F471588C734B2BDF67EA4F2B243A9A9EEA -:10B4F000C4ED3F560AF003393645C0AD245F9CE3E6 -:10B5000019C043A642FDB70AF8E5F1FA17BADED32F -:10B510003FD07A3578F263DEF19BBBC6129EA60C53 -:10B52000D0C1665D3FC75A0CEDA6F0BC94465721CA -:10B53000B5BB57DCB32FEF2DC67605D06E7A45FF2D -:10B5400044E407796F1B0B4D2367BD41488B817B1A -:10B55000D83A787E0A1BE9E7F711CD9D532AD6E742 -:10B5600014EB736AEFA51BE0C38FFAF36B34F75249 -:10B57000CBF703701FE8AF6882E84FC7CFB1FA433B -:10B58000BE88878F71F97F617CC8791AE0390067BE -:10B59000C3FC243C918FA95D919E9FE43C87E59B71 -:10B5A00084BF6DE0E782EF399EC8EF5FFD37221F51 -:10B5B000D2ABA7E7D55D0526DC3F95EDDA3A5A0216 -:10B5C00028E765BCDBD6551D42FDD7D45D4E799B7F -:10B5D000AB7FF5ECCB2168BFEAF987533099F6A829 -:10B5E000B93D03EDDC861DF7A4F871BFC41C4A41C8 -:10B5F000F97934AC56C53A0F181278907654A3D026 -:10B6000037C79EBEFF1A84C77FECB038518F363DD6 -:10B61000658BD8280E720BD95150FE9C97EFFD1AFE -:10B62000FDD2A65D7A3B69D53F3C9CE1257A0AE5CF -:10B630009AF08C0B8BE43278366EB7F8226E1E4F80 -:10B6400084615813EBDF88F333B6C7799C06BC37A7 -:10B6500075A84BF13CAFF13B4812B2C39ABAEE2742 -:10B66000BBAB491B67003CD4C5B1BB6ECDD7E75B14 -:10B670004BB8B0B087EC9AD65FFEACF87307DEA784 -:10B68000F94F294A91565FAE27389DEA58FEF7BB1D -:10B69000BDF1F5EA49B40B6CDA761CAFDE5D0AED5C -:10B6A00049B06EFE6CB04452D0CF6FD86AF181E6DB -:10B6B000650DCF3EF124EE87B04F6C74FF41FDB3B2 -:10B6C000FB3FBE14CAF59D16F71C3E7D879211C53F -:10B6D0004F9397DB27121FAB5EDC4FF70CE27BB476 -:10B6E0006B255EEA3BF75AD9F8C1F0ABE8D82B7E60 -:10B6F00077C1809F8ECFAFA4FB3C7FF99D15E9FAFF -:10B70000E81E8565160C6E5FB7757F0AD21FC209E9 -:10B71000FD4B89A701BC0DC257E49ADDA5548FE209 -:10B720001AF1F036379FF178D0AF9E7D0E7F07B0CB -:10B73000EE37361FAEBFEEB9DB53701D5F999B39F4 -:10B740007DFFE29E0C3F8C5B67096538E9C9DFD756 -:10B750003D7E07D1DDCD07EEC8E0BFA7E1CF364D76 -:10B76000A17566E3FA6E7A6C3EAD6F250B12DDD5DE -:10B77000FD82C727BE15BFC760C4E769C11F5F6DE3 -:10B78000B3E18F64B0AF30111DF3083F50459EEF19 -:10B79000AD4C7B8F0558DC54FE56C407DE1FD0032A -:10B7A000CCCE3471D9A6EDF7F6207E8E0DF367E28C -:10B7B000BE1AC02124E0A5E0FDBAEA81CA4C8E1F62 -:10B7C000E635CBB832D8DF15F81EEBF758FC09C5C3 -:10B7D000BA7662BF9E8F2FE31330EF44DCF7FB2A6B -:10B7E00023F6B9ADD1C31521DF580FD3D2573C7E14 -:10B7F000DF7E1FD1D5371F71BE690C5757D1F71E99 -:10B800004B048F163786F7D628240F6CBAFB9F0699 -:10B81000E862BB45F0B3FE3BCCD3AC68E1BB87E745 -:10B82000D5AE7CC8A6BB0F214A37D6E8FB82287F5D -:10B830004A3FEA66C1FFC6F51AE5C11F0CF2803D1A -:10B84000E619D2BD320D96F0938F22FF02BFA29F60 -:10B85000D9F0AC85FCFCE33BDFF8F83AA0F3E31D3C -:10B86000926FF572D5C8B7752F4C62B1F8F6B8C3B0 -:10B87000C762F22DBC8FC9B78EE83E8D97FD7072FE -:10B88000F5E63872356FB8F11C4B512AE6BA1F7BCA -:10B89000BA7E38C5050C7095FEAC515EBE9CEF8D2E -:10B8A000292F195E41A581A3849FA4C755CFACA6BB -:10B8B0007106E856D2A5A4DB01BA1C945FA983A344 -:10B8C000F1FB17288F2645F16E590F7E0ADAB1AFCA -:10B8D000A9F43B287D30978D00F7BE9D05B40F7A03 -:10B8E0008FB0F3FB9CFD2918D7BB47F815FD184F07 -:10B8F0004C8DBEEF4F10790381FE94348D5DF47949 -:10B90000B79A82765C6F38F6EFC9CA7B2A7BE3FC74 -:10B91000DEAC3CBF54A93AF2D7629CB69DEF4FAE65 -:10B9200068599882F18CBEEE42FA3DA19BDE057FFC -:10B9300017E6DB27E39A21BF39BB2C7ABFE9111642 -:10B94000A2FDCAE5DDF5B45F688C83AC74D4A4E2D3 -:10B950007EA0310E7233E641611EF263FAF7AB301E -:10B960003E827832D05310E9297B303DAD1C2EF653 -:10B970005F4B58896EFF55C8B54AB5E8A7689FF474 -:10B9800081DF8EF120A616FD1AF5E9B7E8C723037B -:10B99000843C44A7F5C12332CF8AE85AD29DD17F97 -:10B9A000373E4FBCF469199E076A78F9DF8A7F0E2B -:10B9B000CF132F7F32FA552CFFEA5FF3FF8D0DAEC8 -:10B9C0005FB1E78FE4AFF4EDB1D17CFAF6BC9D7FB7 -:10B9D000179677DB7C38DFBEF536FE7BD07B92E9AD -:10B9E000DEE9BE613CCED6FADA77C5BDA4A7361033 -:10B9F000DEFE6E38BF2FF654F77F7D86F7AB9EEAEA -:10BA0000B67931EED0B42789FCF0A6DD09744F7CFD -:10BA1000DF6BDF9569E345FFDDF5348AF3167DC9F9 -:10BA2000AC16F35BFAD2B8BFD6F4EAD4275A0AD0E0 -:10BA30002EDD4BF71657BCFEA762943F7D2F70BBDF -:10BA400002FCF3C77113F117C3BB7F6A998AE78DB4 -:10BA500018F9D553BD7FBA36E48805170E873E80A6 -:10BA600003AE0BE042F775C78347D7707E0FFFFF29 -:10BA70003E787C4DFE4243F764E2A3285C14FEFB53 -:10BA800023DDC961BB42EBE7EFF77C578C76D2F13F -:10BA90008E16D2FBE75BF787FF6BE9E0FBAE5B89B5 -:10BAA0000C65DDA7FED7AE9BD3FFDAE15C3F19F949 -:10BAB00060309DFFEAAFA9FC5CB28FE66BE0FFFF50 -:10BAC00007ABA359F3008000000000001F8B0800A3 -:10BAD00000000000000BCD3C0B7814D5B9FFECCC76 -:10BAE0003E926CC22604084260F2244A1E0B791072 -:10BAF0001EA99B842008E206A4A2222EF8E015923B -:10BB000008B6C66ACD622202F5B6516CAF6DD16F30 -:10BB10004141DADA6B8A41B1025D10115AAAAB8257 -:10BB2000A246BA52AB50031B41052ABDDEFFFFCF30 -:10BB30004CB233243CFCAEDFD7E423C733E7CC3927 -:10BB4000FFFB75CE18498599ADB9004DDB4EE587F1 -:10BB5000B1056806280648526D00FD004E6CFDFADE -:10BB600090944CAD5D853480BAED710045D8FE31BE -:10BB70002600124064DBA9129F13E01BFAB912A041 -:10BB8000A3119718D6DD37B71D9B3F2CB917A7D443 -:10BB9000BCF041FEAFB1ED78E1BDEC97A9FFE2BB8F -:10BBA000433EC0B6D606BE565C2F120F3337213C3B -:10BBB0009144F000EE5FF7F2E8A796E1FE8BDB3EE2 -:10BBC0009F4DFBD76C1D0532F62BFFF4EFFC30CDFB -:10BBD000DF2479C4F3F88003E1AADC7E463CDF7EF3 -:10BBE0002A1FB0FD6C93149413B0FF807D7E80D625 -:10BBF000ED05EF118477F17F22DE3B6CB7E278C36D -:10BC00005095E1EBC67B870DF208DFBDB3697E641A -:10BC10007BBCCB9E46F0FD7B0844E17F21BCBDFF91 -:10BC2000B1FC3E3FDE007E86DB2A7B1DE908DFC3D8 -:10BC3000100CA9D83E0830B1D5792E3C3FA6C16280 -:10BC40007A0F42D01F4006F123272F9C0209D4AE61 -:10BC5000FA5CCEA7F7A74D4C4338FCAAC5BD5EA53C -:10BC60001916A6C38AC1EEC02A840B14EFFCB5D8FE -:10BC7000B70EAD71AFE215EE042801F881435BAF5A -:10BC8000FF948912AED7B40CE1C2759AFA595C4D93 -:10BC9000B88EA25A82F67C6E3FA2F6A1FE57EFA1A3 -:10BCA0007D15A70D82DABBDFE03F27603F47EBE35E -:10BCB0007EB199517DFC17033B5D0AEE1FE35620D0 -:10BCC0008028D921EA7D9C7F93EA62BAC442C0EF02 -:10BCD000725E3A9D7E4F83FD7AA793993E3ADDCE00 -:10BCE000A1138083DE57E8BF08FFE45521D2430546 -:10BCF000147F58E0237D23113DDD290E5CCFDAE768 -:10BD00000EF72A899FAB4A89F69E85FE2C31D01703 -:10BD1000E9E789C9EFA673D47A8CBF99CE974A5FB9 -:10BD20009D2F31308DF91C33D8E90E20FC0FAA82EB -:10BD3000EE0F22DD25A99BBE3ADDCC7CF093EC14FE -:10BD400077D3BFBB1DE7FA64383312BE41E2FA2B4A -:10BD500020A71ED7A992C785FDB8FE89D238B79D06 -:10BD6000F44582A03412DBF2FE15807874A4DA1454 -:10BD70006ACB3A11A72878AF3CED00250ABF72487C -:10BD800034F43B52B3F9FD4AC740C37B1D034B1D3E -:10BD9000F4BCCA956698FF464C423E14D07B1326ED -:10BDA000D2F85529971BDE9B7AB863CD1C6CAF95F2 -:10BDB000C245241C1D7B675510BD26A9230CF3B674 -:10BDC000A059217DEEAC9203EB901ED552B07F3E80 -:10BDD000D26D72CE68237C128C273C6B2C285A388B -:10BDE000EF1A77B961FCDAD2498675AB3DD5867E0C -:10BDF0004DC357A0F40518DB70169442B4E3C15646 -:10BE0000C3FB857BB618E627EC03391EDB11FBD597 -:10BE1000266A0BDB434924BEB6BE0EBFA50F8A704F -:10BE2000D85B89E840C991FA57A86D70203DF0F9B8 -:10BE3000A918D122BF58CEFD8762024D08EF294BC9 -:10BE4000C04774B85B0EE4501B3BE88E7C48073853 -:10BE50009AF2B0DC87E0075FA78A7230FA8B401352 -:10BE6000F5AF3CDB2AFBC80E6F94FDB602E2FB94F3 -:10BE7000B8BF92DD6D9580F85EE3B47802E4B792C6 -:10BE80005AF39746C9D7673F845BBCB9E7EAEB8BA7 -:10BE900059E596345CBF39C5D3B283EC66C587B328 -:10BEA000E5F473E7814BE90CEB7449A7F7BC4583D4 -:10BEB000511EE5F8F10EB2EBB19532E30557590387 -:10BEC000EB719DE516778CA6FCEC5F5D13AC6B49BE -:10BED000AFD7A409FB10FB175025843FB6AF4FCE58 -:10BEE000A3F77E26C17AE8DEEFD652603CB2D22CB0 -:10BEF000420F1457BF9BF3E8FD787EBFA454D011C6 -:10BF0000A6580259B864C241F76E2BF657E7EC7792 -:10BF10009119689B72D82F235DDA0E86CA24D4A5A6 -:10BF2000010F979FCC14F3210BFB6D39E3E3F2D89B -:10BF30008FE558C8CE2C41B347766647D93339E4EC -:10BF400027965C7EC500E8C1BEE96DC26909D4C20E -:10BF5000EEFE9A3495E14A50C2407A9D705AE171E2 -:10BF600068C8B690FDD1D74F98A5BEBB94E0D86302 -:10BF7000852CDA5EF12C223C565DD1AEAE623C04DB -:10BF8000DE00E1142FA2FA4FF4932A315609A7DC00 -:10BF90001C7F2E1CFFDC589CA8221E7DCBDD896EE9 -:10BFA0006A7F8F441FC374F7131D7E4A7F2EA3DE62 -:10BFB000DAD0781CDF4836518C0701E57A954D1BA5 -:10BFC000279382FDBE9236EE5FEB1D4F7C958DF37D -:10BFD0000BD2BBE67B1C29DDEB7BD7AE0D35F748DA -:10BFE0004F3BFBE55513AC01BB7431748DBB005D59 -:10BFF00013045DCFA2F5C77DEE72887D3E96D421F5 -:10C00000246FAB2D68053200F6BB7CD7935CC7CAA2 -:10C01000C13C7A3E37C133A00CE5AFCDE619720FB3 -:10C02000D9956D31EE75F85EF59D9F3DDE407A3D08 -:10C03000F59F39CD24378A276E24EE53E7FA8AED2F -:10C0400041959CDB87E29D2E3A923CE39E3FB5747E -:10C05000F7C93E2474D3D59389E3ABA2E8EC709082 -:10C06000FD12FD47D3DABC4CA7DB1C4CA7A59A4EAA -:10C070003527428B05F5E1A46BC3F7491E4E6EB41C -:10C0800002C54D6D3448FE32C7C17A05C9E1946AD4 -:10C09000D483BC372D5E8ACBDA513E3C241FF5D9C0 -:10C0A00086F54E8E7B37290FDF3B99AC24117D1628 -:10C0B000866D4CB79B1508DAD15EB625DF5659CE92 -:10C0C000FAA1F278ABB6CE6B599EFBD2D8EF8C7743 -:10C0D0007D8278499E31F237C37BE71779D04F7460 -:10C0E000FB8874AE2334937A9783E6724780E2CC60 -:10C0F000BAD265B9E41F9624660F00C4A36EBCC40F -:10C10000FEB6AEE10BA6BBBEBE725A06B56F777F18 -:10C110007C86CAF640513C2C0FCA691B8FD7349CD1 -:10C12000643B8EE0A491DE742C13F6AEC50AB754BE -:10C13000635BF3BFF22DD538BF06430CF617B0D3BF -:10C14000B624CA1E42EBE75D76BF0079B77ACA5BB8 -:10C15000B16467AB25D70C401C8EA6BBAA95D1D87D -:10C160008F71CD90B0DFB6EE8C97FBA9AE1916ECAF -:10C17000EF4ABB498C0F74FDDCE206F87CDD5DA262 -:10C180009FE63A40FD0FD31EA95606623F5EC8C126 -:10C190006FD26AABFDB9245F4EA6CB891571AC1F77 -:10C1A000BDD1795EC3CB06BA9C332E4BB778C96E2E -:10C1B000CC1476F1D8CA416B391ECA0C65D39E5B8C -:10C1C000D344FCDA1F79538AFF5E45BD77201D9268 -:10C1D00033C063C1F9C92FA23FA2F91F878610FDA2 -:10C1E000E6BD181394901F8B9F78C546FE68AEACD1 -:10C1F00066935EBD3FCCB793E4E3787C88FBF31A8B -:10C20000B6335C29592E61A75D9DB95E94CFF9D0F4 -:10C2100062A3F1F9A01C26BF614161A6B866A173B3 -:10C22000978DE2B2854F5B0F87A3FCEA22081F229D -:10C230003DAD79D67A381CE57F81DE8F92AFC3168B -:10C240000187A2D163AE1C9A6D13701D20B816270A -:10C25000617C2F93BB08F5F7715C5493C379494A0D -:10C260002C90DC2DBFECFD7C5F0F7EB0B511FD3E48 -:10C27000AADCA6C62DDCAEC135C9EE0C50C23637DD -:10C28000AE53ABD9E592D0611B44BD7F42A36B9FF7 -:10C290002D128FEBF6A27B3C5ED025D733C2827085 -:10C2A0002C9EB66F1CF145E7E79571D01A93C47CBC -:10C2B000716B7C71135F74FA233D0B157C6FD7593A -:10C2C0007C2FAD27B9D0E92FE06D8B15F6A27373E3 -:10C2D0000CC74D66F8E3D205BC3A1E43D3CF0FFF1F -:10C2E000D0F4EF06FEA1E9428FCD78E87AAC3FD7D3 -:10C2F000F5D88CB70EF7A5CB59C8763172A6DB9965 -:10C300005AF0E5D0FABA5DD1E9ACC3A9D3AB8DF24E -:10C31000A11EE0541A5E32E0A3842A28898071E9C4 -:10C32000E9C28EB54E02E283D2B095E75D2A3EBAED -:10C33000BDED0D2FDDCE9AF1D3EDAD8EA76E7775E5 -:10C340007CCBD090B03DC4349EF2AC2B4FFB0C7133 -:10C3500070392C30C4C9958E3B0DFD2AD73D86F926 -:10C3600057A52C338C4F52571AC627E73C62E85F1B -:10C37000E3FEA5298E5F6B8AE37F63181F170E719A -:10C38000DCFD7AE344509047DF3BD2C9F177B0D16E -:10C39000C5FD9D8D29DCEE6A5459BF7737E670BB29 -:10C3A000A7D1CDCFFFDC58CAEDBE460FB7A1462FAF -:10C3B000B766BB30F5F9EB15CA574A432D9564CAE9 -:10C3C0007764F87E928EF47BC312688A473A8D6A4E -:10C3D00017F139CC37FBE35387EE25BFEEB2B9C96D -:10C3E0001F36EF182DA93DC47309E8EF3C51F292B6 -:10C3F00030250C1E8A7BD03DF7245F2DE916964729 -:10C4000032FB807A37D301D664D4B79933257713BA -:10C41000F0733F24711BF4E1F85405FCE4FFAB9D7D -:10C420004AD09EC0A0791D08E70C0126D8699CFC63 -:10C4300077725F85E2D6EBE821C22B7B64F81E3E63 -:10C440009F51FA97339437DFE86CB5929CDCB0E7E4 -:10C450008163F7E23834FB8B493FBAE206FFFB9673 -:10C460004B891B5A28AE443A462477C843F14EA262 -:10C47000E28ECE07F4F6B674910F4C6DF2CB0948FC -:10C48000CFCE3781E3385D1F11BF1504BFAE17D57E -:10C490002E25382C81FCFD239534BF66BFCA74D18C -:10C4A000F542D7033D0FD4F5A04A7EB689E69F3802 -:10C4B000089C4F8FEAF01D799EF034C59DA59D2DF7 -:10C4C0009594975D286F1C73BAF5159AB7BDD1C7BF -:10C4D00072B4B57126B7C1C6F99A7CD6737F57631B -:10C4E00003F77737FAB9DDD3B84293CF161EDFD7FB -:10C4F000F838F75F6F0C6872BA919F8FCF10FEF714 -:10C500008B50E50092BF17D3451D071CE59C478063 -:10C5100022DA8B95939A9497453C65920FB35CE829 -:10C52000F200683724A4D78DE867C93FDC04FEBC5D -:10C5300039D8CE9CD7621D2B7D7BB958E86CE6F8C4 -:10C54000C36C0F174090EDDDB9F65DC4FF17B2EF75 -:10C5500032E6ABE4AF74FBB718C2BC9E5DBED34DF0 -:10C56000F594EFCEAFB834BF0273687E57DE1DDBA3 -:10C570003E5BB65C38EF2E1A2CF8AAE7DD183F02B6 -:10C58000F9E54840E6B87A7E5A4B02E7DDA59D09F9 -:10C5900014072CD826333F30CF540622DFE6697CBF -:10C5A000EB80E03BC49779E3E6715D6EFE1A233EB3 -:10C5B0000B9DD7F509AA3DC6693DE2590B0F7F4E89 -:10C5C000F5B95A8D5EFC1CE16968BF61D2AEA879ED -:10C5D0003119F1C99FC49142C128A207C2EF0E923E -:10C5E0009EED9759CF7A938BE3989F909C9F6A9C7E -:10C5F000396917CAFDF1B38D9C7F25653CF2887FB0 -:10C60000DC77C7AFB559DEA1199C0F856DA43F3A01 -:10C61000FF96938D44B8975738029468478A5D0A0D -:10C62000ED1F913C723CF1E323702F43FA956F7D2F -:10C63000ED20E947B9C3C9E708884447343F47EFCD -:10C64000F7353971DEA87D1E99C2F7E25DE1269AC1 -:10C65000A6FB1BDDFF8CEDE8947D5C17C8643D02F2 -:10C66000CC25BEC9B8783D32E79B4D946FA2413AC4 -:10C67000E99CC0F09E0C829B9E77D7B544BD69ECC7 -:10C68000598F9C80F02DD7F2C3D11F7B198E6A87FA -:10C69000CA7268D7F2497B8A053C517474D97C1BF5 -:10C6A000A9FE097F8CE13AAF19BEC919C28EAB4908 -:10C6B000DEC94C5FA79A4D794395DCB1E1D7240FD1 -:10C6C0006D716E3BBE67B6B7BA7DEB2D6EAF739DD5 -:10C6D000EC318ED4DB3A8B38371859A91652FE4705 -:10C6E000F125E5857A9E689EEFCBAA989DD18FEBC8 -:10C6F000AB210FC1E5B29C574EEB1A3E3F6F9EA691 -:10C70000EF5FB7ADD83537AA0EB226433F5F505C16 -:10C710009F38BAF976B1FC2DEB9C69F03FFFE9F147 -:10C72000DA540C7324D4A13C2920E20810F1C42C63 -:10C7300008713B1B3AB9F5A124513B17DCDCDE063E -:10C740005E6EBFCEF4AD26B989583BFB931E1F7BAE -:10C75000E1EB5C928B63DF1BEB4A53BBFDABEE6FEF -:10C760002FD5AFC6D2F9520FF2B041935BDD6EF711 -:10C77000CA1F93DD8E8C40FB807046368B73B148A8 -:10C780007C6C80CE0174FB007E63BCA8DB8BC2593D -:10C79000EE37B85EB84FE6BAA5D97E5429228F0786 -:10C7A000C59D43F5517DFF260BCC2739DB88ED1F56 -:10C7B000108F3EB3C28A1A85CF760D8FF21BC60347 -:10C7C000E52F535D223FAC724032E57370F664EEA4 -:10C7D0000C340453291E45791E95E4F913D1DBFF6F -:10C7E000D0B8443E7F20FB3314F9F79138B7810568 -:10C7F00052200BE9B1A54DF4F36E4F64FC6E82201C -:10C80000F3F166085B09FF5B00D8EECE0195DB5BB8 -:10C81000C1C3FCC495E3F2D10EDDDEA68C5C857845 -:10C82000162475A6937EE68D7E2F4942B8F229FE26 -:10C8300075726D6605C5293A1E964C81C765999E2D -:10C84000B709BE82A4D0AAD514176EB600C5859FBD -:10C850008EBEE70E88F2AB2559150769DE73923854 -:10C860002FF46FB38BBA1A74F6F746C5E35F6756B9 -:10C870001E22BDFF07C1C6F9EF2A3E47AA7609DA94 -:10C88000C3F87E4C037C6F8837AF27FDF4B37D2C53 -:10C89000205A8A3AA11F4A795FEE7FF5D417D5CD89 -:10C8A000021F3FC5632559BE08ED5760435348F04A -:10C8B0003F610FACE3B8A97E08D52FE63D69B7907C -:10C8C0001F7F0FED309D9B7ED0E8E0F643CC6FA834 -:10C8D000FD1BE637D47E84F90DB57FC7FC86DADB15 -:10C8E0004F8F402102F861A6E77F33CE8347EF7672 -:10C8F00046E0119160664FE77DA73244FE91DFF676 -:10C90000F1037124075B6437C969DE6685EB10C7E4 -:10C91000B78E0AC869D174F5C565221CF95BDE7E45 -:10C92000746C11BDA7B8249C7F7CCBC9FE9C379941 -:10C93000E0EBA2C7369BA08706EF7389A155F4FEF2 -:10C94000739BD30942B42320E490F8D9431D0D60B2 -:10C9500019F3F1F50C113F5D6BEF2C8A3EDF040AF1 -:10C9600019A85EA9F9992AF96C423857ABDB8E26D3 -:10C97000B9CE7C83F6F3EF117A887C35D4252A353D -:10C9800039D4DBBC6D362FE9D373DBDE993619E978 -:10C990003075CCA46259ED9E5F98D98FF7CD1B7D81 -:10C9A000E657AB93793E9F5BDC006BAB5C38EF26C0 -:10C9B000C78E57890437BB3EAA4AC4FE2D29D26EC2 -:10C9C0006AE7A8691392C80E4080F7B935A77C378B -:10C9D00089D81477B58DFC7239295594DDAD74C4AE -:10C9E000D1496A57BFCAD5D7D0BF2A659061FE2406 -:10C9F00035C3303E3967B8615CDF778ABBD0308F92 -:10CA0000F495E266C483F90EEB653E97C9DBFCC57D -:10CA1000FB8B18FF1B8A08FF08D2CF8681C591D2F5 -:10CA200095BF584D6663F3CE043EA735C5A735DBE9 -:10CA30009EDAED517B8F4FBF84AD3DC675B5BDC449 -:10CA400075171B9FA2FD7894EC47C10BD7F1B9FB7A -:10CA500073A3CF5CA6225EBE4C8C5BC9EE99E2D676 -:10CA60008816B79AE5A74B4E2555C8CD5E19280EF6 -:10CA7000D2E357B3FC003CA0F97FD15EAA9E4F7D64 -:10CA80004BF8AB7F90BEF78D966BAD35D5230A6C16 -:10CA9000E857A84EF85719D6D183B308874EFF8CB4 -:10CAA0006EB987DBD6BE3AB0889FFBE371CB5AAD37 -:10CAB0003EF1AB4CED9CBF66C7AB0393BBC7E1AE89 -:10CAC0008F0CF3E13E69B7A1DF9C66EC3F5CBE3B97 -:10CAD000FAFDDEECD0BC3577DA7C54977E4CD42955 -:10CAE000CDE33A3C553B633C642F95AD76CE876AE7 -:10CAF0005D1EAE9F28BDD44F74BB70830CF53DD92D -:10CB0000B7F5DABA5376C680FC2DD67D0F6585E081 -:10CB1000F1BF28FCCC7B7D3CE08DDAA73553C47D8A -:10CB2000C7125B7EFC15CE3BF612B889F4C712859E -:10CB3000BDCD6FFBD462213F112BE425DF15B62458 -:10CB4000D17D97F9717E3A4FAE5B10EFA773A38248 -:10CB5000F4CE771CC8FA2D4FFB1E75A0DCBD6FB15B -:10CB600018FC4E846C1DF67764FAA691DF99BC33ED -:10CB70002668F916F8ECC804E1D72A84BECF26B996 -:10CB8000D1CFC5D0D4D43D08867332C29FFA679EF8 -:10CB9000BEF5ADC728EEDD2BF41F879DE67CF4A61D -:10CBA000A87C14D608FD75E02FC5390B77B5D828B9 -:10CBB0004FFAAEF4BE3DD3D9ADDFC3CED5675DDF4E -:10CBC000EB0E087D3FB1F5CBB7C8AE9F407F17ADE8 -:10CBD000EF5D7E51D3F3BAC765D647FDF9F1ADF2EB -:10CBE000C4400FF47D4D930370651BCECD96949D8C -:10CBF0009A467E6DC93685CF037BF3D7752B8CE7BC -:10CC000064CF6DB7CF17E7C8028F88EE4FB77D9915 -:10CC1000549E2BDA657C5EDBA2D91D11C7A01FB51F -:10CC200026931FAD96B8FE7660DB00BE9F714082F2 -:10CC3000A03A9297B8CE817C9B2E96A3E74E8AC7E6 -:10CC4000202547A17DA669FC9CAED585666C9B918D -:10CC500045FC7AA76DEE010FA19795C1F2733DF8DF -:10CC6000391E3C90E84DA57B0A539B847C1F48EC01 -:10CC7000ECA03AD281B23889CEA370FDE6E878EF15 -:10CC800080D59B5ACF78E9E79357C8DFC45D421E31 -:10CC9000ACD943E4A75F12F91CCBBF32F06196AB6D -:10CCA0000510D8EDC17D6BDD418E4B1781C8EBCDF2 -:10CCB000F17CEDB8CF6CE417CCF967F9961D07E964 -:10CCC000DCE39C3A84495E2F547730E7BDBDD50F35 -:10CCD0004625790BB3A2EA7EE6F8BC2B0ED5E3A875 -:10CCE000F5717C2EF44AD97F1F5F84FDBBD6C7B98E -:10CCF00028CF3EFAA4DD4F76F9E83A7B40C2F1A393 -:10CD0000499DED94771CDD94E7C615609E45FDDDD9 -:10CD1000B3E4D77F6B65B90030DE6B58527637DFEE -:10CD2000FF5BB23E5EA27B389022C6F59C4F7E260A -:10CD30009EE38205CF0FE4734EDDBF907ED0B9F441 -:10CD40009127623C14E41FDD33BD0FD5FB3A2C7FE5 -:10CD5000E0F37C90EF3B44E7F58B36C48FA4F801F9 -:10CD60007281F9367FDDE57CBEF973C53783F0AF9C -:10CD70007CE69A0174AF6CC1DBFD80F0896C7D9E0E -:10CD8000CFFFBAE3F49EE3BB135B33FA406E379DEB -:10CD9000F43AE08AA7977989EFC5922ACE69A0DE96 -:10CDA0003388E4624B35D0BA2365716FB473651C68 -:10CDB000C7A566B9ABC91271608D5E6FE80B8E14A2 -:10CDC000D21F1F301D222B87AFA3F3B0E6AC24CDBA -:10CDD0004F77664F8BBA975825B7D7BE4CF2B9C676 -:10CDE000CE75908E989ECFC11AB21279FE3C87F113 -:10CDF000DCBCB6E18CB19F8BF91DBE3FB2492DBCA6 -:10CE000013DBA51AFD57A77AEFCDC2F717B63EF28E -:10CE1000C23EA6CB9A1FBE4FFBEE718AFACB3E41B3 -:10CE20003F73FC3FCF21EA1C006B797FFDF9A74FD0 -:10CE3000BCCBE7AB9F6E1E9E2DCE8D439FFC3A8DE3 -:10CE4000CF8B0FDD8BEDA63D6F315FCCF09E73EE87 -:10CE500027498C6F0DE1D197CE77BD8F109CC80804 -:10CE6000CEDBE6AECA63FAE9E76F91A33DE7273A66 -:10CE70009CFAFA3A7CFAFAFABC27B3441E335BCB2D -:10CE80000F8ED942C7F91CFD85E112D5F7BA9E274E -:10CE900085F213A3E4E5BBAAA7DFA8D5430E5A96F3 -:10CEA000FDC046F7E45A575B7DD176EF12EBE85DA3 -:10CEB00071A00754577FE14AD86F21724A7F3AEF39 -:10CEC000D3FAA40CD81FA78127113C746F506B6153 -:10CED000A12F85EBE4B49E4CD71003DC6F2A77AB0F -:10CEE000D45E29791571EF2BC0F23F01EA07131EBA -:10CEF000164798CFC5F47B2E3312975F9386FB3588 -:10CF0000F783E514C7345B855EF8E7C471FEA6D3EA -:10CF100049F733E0CA35F8976617A80AAE3353814C -:10CF200015D624316F28D2F9C09EB9AF529CF0AE0D -:10CF300052DF8FF67DCFF9589E64A1F82E104F393D -:10CF4000E2FB6FFDB6F8AF38F703F09439517EAECF -:10CF50007BCDC176DF5C8FB81D7CDC9F0761EB1752 -:10CF6000F8DEDF46FF6BFD4EE8C6EB6F63BEDA4CC2 -:10CF7000F9C14D890F14D3FBFA3D4CF37DBFA32EAD -:10CF800027DF0B34DFFBBB167C9F91DD3A65F1D5C3 -:10CF90008AFA47FD28F2BF91441B48383FD24FA37D -:10CFA000C731607A44ACDAFB9FABDC2FAA1CC9F511 -:10CFB0004838A5B23D1E6BF23745C32D220FFB4604 -:10CFC000CC2FEB540CFEA6A840ABDB7CAD725C7A98 -:10CFD000E569E5BCFEE8A16C61CF8AFA5AEA7B8A72 -:10CFE0000FD56CA13F4D1094053E224E18DB2557FE -:10CFF0001E99F857ABF56BC99FA13C45121C7EBA30 -:10D00000E83876AB90AFB14A7007B5685DA181E2B0 -:10D010008A2DE8EF7438E88C306538CBC1185D3E56 -:10D0200071AD59386FB954CF798B83E2196C574978 -:10D030002186E37BD0C9AD47F3E315E0E6763C7883 -:10D04000B945F9E47622B4707B35B4723B0542C22F -:10D05000EF5F116C627F06F7B9F8DC62D23C0BC55A -:10D060001B45D7F79C2F546874EA9D0EA87025972E -:10D070004E8709807A97D1033D06E7B0FD30D3C3D0 -:10D08000AC9F651096593FC93064509D40653DADD9 -:10D09000040FF7AB2E920EA5619FC2751A333D2A7D -:10D0A0007B968BC91A3DFE950D2C1F3A9FEECF56ED -:10D0B000F9B9CE2FD4AB14927F331FF5E745711524 -:10D0C00027E96AFA1DD9C3A7D3BDAAA2C28AA5645B -:10D0D00092EFDE30663ADDAB2A1A5BF13C1D79DE59 -:10D0E000933D4EF40B2A0AAD6ECC5AA4B2E9E3711B -:10D0F000BE4FBB970C33457C7D9716B7F896FDC0A5 -:10D10000ED423DF1A53ADD849F03837BAA7FCA19D6 -:10D11000E27C70C8C4E04E2BCE3BA4F8E664537C9E -:10D12000E00826A848F7BB9655F1BDB5876C62BEEE -:10D13000DD2EEAB03A5EF8DC1F83FD4D9B862F950D -:10D14000D27BDF1FD7ADA5757DCBB2FCA4AFBECD22 -:10D15000925B70B262C04CD4CF8E9015A81EAAEF1D -:10D16000939DEA5B9ACDE7BAD95C271BA4C5331D12 -:10D170009B860F27BEDC9FADDDC34A4E2B24BA2D04 -:10D180004BF5DE4FF323F142BEEED7F8D05BBB2167 -:10D19000DB735F76F1B9CF23FF4000F0FD9F65FBA5 -:10D1A0001EA0F5EAE2CEB27F3F3EE2EDE5E1B46ECD -:10D1B00039959049B310EF260F046CEC07B4FBEAE5 -:10D1C000DA7955E4765C07E950E4F53591491B3589 -:10D1D000ABB384EC27AEFB5FBCAE2D3C6404BEF762 -:10D1E000D8F44336216783859C697668DBF6BDF702 -:10D1F0000E125D2F44E955DDF6335F7D80F4AB3BC5 -:10D20000E174D3F46E7DFAE552CE27C169B01BBA42 -:10D210009E8DD962E7B87AECD6CB6FA779656FB7E8 -:10D2200067105E57B687F91C2CB2EDDD41020E3D4A -:10D23000DF38257D1BBF4BE7B49CC76D16E7B44BA9 -:10D24000A4FA57E2A9FF7BC9ED47F83FD5FC869EBB -:10D2500017CFD7F05ABC77FD72AA8BCC5F73EB1453 -:10D26000BEC7131079838ABFA4FF5FC23E3E1F5F13 -:10D27000B4D19C4F74DA88FF8B5B4DF781281FA6D1 -:10D280007B0FD1F6BD877C787BB6764E9B0AA98C46 -:10D29000873CAB8FAF077B67CE771F07CFAB2C9F49 -:10D2A000E09569FF62A5E77AC273DDDFD3B03ECCBB -:10D2B000D3F6263A3939DFB589FBC24F2C75BBA8A6 -:10D2C000AFE9E75A9495528AA33B7FC9F2AFBFA753 -:10D2D000EBEB8215E25E36ACE9CB3257B0C1EE2102 -:10D2E000BE166C18C0F905E6411CF7ADDD605F4164 -:10D2F000FDA60763FD7201D5933B2FA3BA4A538C59 -:10D30000F8CE89DC23DD132D4817758E33BA5DD72F -:10D31000FCBA7EDFB62BFF89CFE67BCD5DE361C52E -:10D32000906F3469F17311C1477160BD55E44F319D -:10D3300002FE1D6F7E3F8EE2D8CD8A378EEAD2275D -:10D34000F6A7F7811EE8A6B7C5E85EE03CE78CC506 -:10D35000EF4EC9381FBF8A1ED7EEA76BF2F9C7463A -:10D360000FFCDDDACD0F1DAF2AF9D94A1BD5396E76 -:10D370000317D53D96EC7DAA89BEB759B212B8A263 -:10D380007082FE50BE70C4C2E7E063F616A6903C01 -:10D39000B669F68ECE85D528B92AA1A210CE2F1E49 -:10D3A0000C01FAFE28468D05352A2F8ECB4932F422 -:10D3B000E3DD9719DEEF539A6E1807BF27945BD20F -:10D3C0001DBF267AAE30CC7F2861027F8F5316BAFC -:10D3D00083EB4A7D278E348CDB51AEE99E037C21A2 -:10D3E000E29F52FC65BF0AF532C139360CF02B942E -:10D3F000BB311DC6F8A834DCC27960CC7EC590D79D -:10D40000DB2F5067BA7C98A6578361B0B00F667A5D -:10D410001BEF432CD92B731CB7241503CFB4DEE9C3 -:10D42000ADEB9F4EF77E5E23DD07CC34D279A0CFE3 -:10D4300048E741F38D744EAD37D279688391AE6978 -:10D440007E231D33568C31CCCF6AA930F4873D7EC4 -:10D45000B561FEE5816986FEF08D371AE6E7B5CE47 -:10D46000358C176C59785EBE8F082E318C9BF95E17 -:10D47000B8E74726395498CEC5DAF7593AFFFDF890 -:10D480004BFC1F0BDE3E4189CA81FE26D2C7FF2F0F -:10D49000FE2F18A69D23E8FCBF48BB7A95E687CDF2 -:10D4A000DF794D8D13F6E6F53D27F67BB0FF865A02 -:10D4B000684DA1B8498B0FBCFA798429EFD3F39456 -:10D4C0006B4B25D3397D8CE19CFE42F7DA8A4341D0 -:10D4D000437FC47EF17DD4C883EE57A82DFED823A8 -:10D4E000477F0F35FA0B76CBE7E49DFAFD383D6FA9 -:10D4F00082E627390F9DA5C34F4A50726E7D51CFEA -:10D500004FCD79AB9EAF9EFBBD95884BEE967BCB06 -:10D510006345FEAAE7ADDF070F7F5776D560DFDAF8 -:10D520006168FF654B675F1AD7F359222C9D1B4733 -:10D5300088B0FCDDCC3BD33DB9FC3D2AD7BD174AB2 -:10D540006F4FA77BFE08BE2B5C22CA3FF4F3D2309C -:10D55000DFEF68BDC3926B7921BEFBFA98CF86D00E -:10D560007AFF334CC46F76192984FE67C02C0FD024 -:10D57000F351499EE768BEF97EB6B935DF1B6A6B89 -:10D580000C72ABB8DC7C6FC75C1F0C5B548E3BFD30 -:10D590003F92F89ECE6704DCE8EE78E5C40A2BC71C -:10D5A0002BA0E5E3376BF4D7EB16B3347C0EE31214 -:10D5B000F3D1FFDEBCE535E6CBA2940EADDE51CF54 -:10D5C000F1F5AD839D23F91E9AA7D02DEA5C7A1D53 -:10D5D00063D0257D5F7221FC17A51C35D491E0D95D -:10D5E000BE1775BEDD8DB758FFF04A518F3CBC3277 -:10D5F00095EBDFDDEB1FE77AD2CDF56F1AF4E296FB -:10D6000086F70C7A30C7FF91613C9CDC69A5FA6112 -:10D61000F88581136E42FA1DDB6CE7EFA1510E3ADB -:10D6200088AFFAFAE195C3C7F3779517C4F3338649 -:10D63000A3BD31C4FCD5F13CD47890FBE1C630B732 -:10D64000663CF53A85DEDA76420EDDCFEF9462DD98 -:10D65000541736D72FEEB6A89F901E3C9493AEC5B4 -:10D660006BF5055EE69FA857B46BDF97B66BDF9747 -:10D67000B66BDF8BB66BDF87B66BDF8146ACCE1542 -:10D6800054D76897C4BD9F5992E7C939B85FDA602B -:10D690009F3387E2FE859DF90AEE5357109E2D2198 -:10D6A0009FF3FAF9FAD07309D38581FC3D919FEF7E -:10D6B000871DB1F8F3E9FB9BC91BB3AEA33CF0484F -:10D6C000ACFF384522953969D751DE77C426F4700E -:10D6D000FAC6D8EB48EF3EC6C5083FFF4B92A82BD1 -:10D6E00039C336FA7E6A6AB26F504EB1B8F7C5DFF9 -:10D6F000CDE073924BBDCE19B18A3830A2C583E913 -:10D7000039E21C302347C4AD7A5B463CC7E7D3A956 -:10D7100065FD7C389BBF375963078A5F717FFEBE0A -:10D7200046BF6762FEFE66E49FECFC9D845E0F2DA3 -:10D73000C949E375E8BB1CD2CBE49FC4B1DD82705C -:10D7400068087DC7D305EF7EF15DE531AA2347D593 -:10D750009F4B72441D066E03C377408BF71E3E44F9 -:10D7600079D6FBC37C6388AE732D6A09F17571C2EB -:10D770000EAE774DC951795F8497F145FBD34C7C50 -:10D780005AEC08737DEC42F5F0DEF03F767BE8174B -:10D79000B95CFF55F3F93B3C6D5F84630AD15FC709 -:10D7A0005B87A37B9DF3CBBF5ED7D5FB9F3EF1503C -:10D7B000B65697BFC5DB833FBD55A34BBBB5E73A14 -:10D7C000FAFD1A7FCFE1CF3000AADBDB63D14760DF -:10D7D0005BAFD1E9D80D880FD7273C2388BF8BA733 -:10D7E00039F9FB737D7D5CC7F787F3ECB33AD5BBA2 -:10D7F00090F05F582FEAEEFA7844127CF5AF14757A -:10D80000D0C5DBDF3B44FF1F8405CFE415727EAF3C -:10D81000BD6FA633D297BF8B9A2B8B732BA4EFDDF2 -:10D82000C46773BDFDDBD235922ACE57236BCF0C74 -:10D83000A17B648BE9DE1A7D1FA6D5AFA0CD5897DA -:10D84000427AF9A95E71EE7914F0B9965DF3237608 -:10D85000FDFDC18AE1FD634EEF4F893E2F687603DF -:10D86000E7072CB87F9B9E279BEA286D2151EF6C20 -:10D870004BB1719C4CF10EF9273DDEB9EB4D51EFE8 -:10D88000BC2B4DC4D1041FF1573AB89BE3842EFF43 -:10D890002FB955A29FD3EA0BD0FEE05BCAFE4B1E08 -:10D8A0008AFCA5F38B3F5FADD503843F2CD6FC5F8C -:10D8B00031AD43014E6E1FF68B45DABE183F72DD67 -:10D8C0006D34F89A04305ADD6CE56E431DE1FF00BB -:10D8D00090CECABD504500000000000000000000CE -:10D8E0001F8B080000000000000BFB51CFC0F003AD -:10D8F0000917B1A1F26FA0F1B33851F9BF5951F92D -:10D9000097D0F884B02E1303C30A46D2F420E39DC7 -:10D9100040FD0780F838109F6322DF1C103E210C69 -:10D92000F48F1803C34220DD0DA4AF00F11F207E49 -:10D9300004E44B8B30306801F1325106864420BD3F -:10D940000688CB4520FA4E02E96651F2ECD4E3A1F9 -:10D95000CCCDA39832BC411A955FA3C2C0B05695F6 -:10D9600081E1931A84BF02499E5D9D81A15605C243 -:10D9700036956360E807AA59208DDD5C33A0FC046E -:10D98000A0BCB83A840F00134DDDCB680300000043 -:10D9900000000000000000001F8B080000000000D5 -:10D9A000000BCD3D097855D599FF5DDEBEE42679A3 -:10D9B000819705B8090183067C09612DE24D8C1819 -:10D9C0006C8A2F88364E197DA0D56859223235B61B -:10D9D000DABC4012C2A6416D8741A52F5A2D525A7A -:10D9E000A3624B67D4792C1DD1B1355AAA76A49D78 -:10D9F000C8388E5A65E242AB558739FF7FCE4DEE6F -:10DA0000BD7909A89DF98ACBE1DC7B96FFFCE7DFB5 -:10DA1000CF7FEE73CB3E80090027F1CFB900574B83 -:10DA2000009037548237D608118026CDAD6F2A0674 -:10DA3000F886123BAC57B1E763E5D8FD3A3E9F5CF0 -:10DA40000B610005DBE703C4F07FACDFFAE0BA311D -:10DA500089207BA62CCDC2D21CDF2C9B5400AD129A -:10DA6000DF6F999CE9BD5942CA35D0EF05FA73B210 -:10DA700004A0E5E86FA71E32EBECBF0208455E0F7D -:10DA8000B0BFCC8259271580F7828BB3D230F278A1 -:10DA90006FB5769FA54E02F853EBCB530F4D1AFE90 -:10DAA000FE1B0A34F7960F7F3E0BD8A433101F4994 -:10DAB000777CEAD0BA07D71964489AC3FA03A43D21 -:10DAC00039ACDCB5ED2CB56C084EE73A00921CBFC2 -:10DAD0009FB39F2752932E60B50A29318FE052D908 -:10DAE0003F3301A829DB97EB763500C1E580B723EA -:10DAF000F2978177C4FD12EDDE0BAEEB04D66FBD5D -:10DB00008BD34B7B9E1C5B07C3E9C5DC0F138FA730 -:10DB1000BB1F37818FE631E9A8495E3AEABE9F8A8A -:10DB20008EAE443A3AEBFF9E8E927FBD74D441E3B1 -:10DB3000FC95D1114037C717F4AB38FFD0735E4660 -:10DB400096F64A4867ACDA87708FE353C1B896CE31 -:10DB5000EBE5694C4C41ECE93398DC1AD7BFAC1EBD -:10DB6000E11E7B74E19B58762EA9A93B9FAD2FBF88 -:10DB7000B1F7F90B581989A7A404DBAF3B4046A1C4 -:10DB8000C2C65B91AC66EB6BC7C1E6023C905C66BB -:10DB90002471BD60008C01F83BB126005957593DF6 -:10DBA000447FCDB40E37A4393EA4939EE1FD475A7D -:10DBB0007F08FB996D8AF1FF6B00D777AA7EB0963C -:10DBC000CF9764FF20BE0B87E6A771F29B2C7540B0 -:10DBD000FCD8DFF7E15F08BFD7FFBFCC5700953E09 -:10DBE000940FA17A594B617BE8CD56593DB24285DD -:10DBF0003493110555DD924B3FF5BE7402D4F5F216 -:10DC0000FD911A4243F0FD2748443FE3BFF55ACF48 -:10DC100006467227960663441F1A406ECEF0F57CC6 -:10DC2000B71509D9525F52232568BED8D3A5AC7F5A -:10DC30007209D77B77D42FCEB6CA2B8F2409BC3973 -:10DC4000E903747526B215A70FB55E367CD3BE38CE -:10DC50007DA89F933EF2D65AFAC167DFAF88691755 -:10DC60009C267D7CD1F9CC7D1DCE576D625F4B7DAE -:10DC7000C0F8F6F6BAC519ED8C91F7B592F83D5299 -:10DC80000F462A43BFFCC1FD4C0E2FD9FE2883DB73 -:10DC90007B836DBF94B1331B7B46C18712B1AFD775 -:10DCA0001CD7D7A2E8AFE5B2AAAAC9389E1BC763A2 -:10DCB00074B6317A7B12183F9C40DA66F850BA2B62 -:10DCC000D258875288DD2F209059DD1735529B8816 -:10DCD0000E52B42F267C1E5DB6E15F8DF86D75681F -:10DCE0004C4A56F87D2D6E82C38DF3317A57343607 -:10DCF0002043851A84B42F8C2D38FC4806272762D0 -:10DD0000FDDB363AE8D22B21D33E98F48A68E5F45D -:10DD1000FAEDD3932FCEF996D8E13DED7E41557FB4 -:10DD2000DDA28746EEA7C2EBE6FE30245E8503CC7B -:10DD300018DAA70D2ED8279DCDF475D1A590604F88 -:10DD400037E0AB3944A764CF6C28AAD490AE609773 -:10DD5000A4229CA61E85680EB5AB90741A47F636B1 -:10DD600003B653820695E6FB91E112F49734F697D9 -:10DD7000B271BF22F6F72B42AF4195EBB57E136E21 -:10DD8000D2B3EA509DADE39D9BD8FF189D242BA4F0 -:10DD9000D4FDD2F0F7F5A817995CAAC7E716B9B277 -:10DDA0007D900FA2B45FF5E2DDC1C75E9A3C9DD1C4 -:10DDB000475F4C01145BEB1EF318B56CFCE7CF9189 -:10DDC000521E49C0CBE05C24E07CD6C81D8774DAC3 -:10DDD00057EB213A5E74C19F2248C6C7F7FD5ACD62 -:10DDE000442F8BE6B986E060FFADB6AE8FFDF7C37A -:10DDF000C17D29A2794CB856562A0447DF3C2985B3 -:10DE0000F31CFADD7FDDFA2506E7B35552CCA313E8 -:10DE1000BC2160F3F519EF4746F53BCCF975D010FE -:10DE20009FCEF9CDFD081702E115FE9DE195CD9736 -:10DE3000AC19E85F8F783E26C5D6B3F9B2E6B74C89 -:10DE4000C0798A6599E0DD38CF2B2B8C7EE0E531F7 -:10DE500032E23328F83CCBDDED9DC8E0EC9C24C3D6 -:10DE6000BDECD1C6D2D1E559BB439EA95ADC90582E -:10DE70007F3DA9552AA3F045CA90EB32C9BB672460 -:10DE8000AE273B928BB5525CDE21BB1D887A296E92 -:10DE9000D1ABCC5E7C4662EB7745381D67D7C6B9FF -:10DEA0009DD83786E45740EC47D6B4C55990C10E8B -:10DEB0001E711D6CA24C7673B6CCE183A37C7CD51D -:10DEC0001C3F67F4F13788F13F6C92A00FE153E3F8 -:10DED0005EDC7F302A889EFD823E616D0ED54DB995 -:10DEE000EB298B7715B37DF44465D0755C5F92F6B2 -:10DEF0007933DBE322068ABF96BD674D377FAA9050 -:10DF00005D922D9F4826191C9BF75F0B3AB353FD7A -:10DF1000D114507DEAD55EC4CF66A614F8FCBD804E -:10DF2000F30718D9A27C0D30F9AAA37CD57BD33294 -:10DF3000ABAB751033D8AB901693FC8C640E444B8E -:10DF4000DA54F6BC7D2910FD025A1116FCB6475F63 -:10DF5000301406576723905DD319A9A1F5B597D75B -:10DF6000788BD1DEA957E9397CC2F061DA214C1EE9 -:10DF7000FACBC0C0F936E7432A88BC549B47F4E883 -:10DF8000D6F8FAF5EDA5909ECEDE67CFDC8FF327AD -:10DF90006F81D8243E25C935D5A40B359194D0BFC7 -:10DFA0006BD1629B32D0DD764864C9336C744A7A97 -:10DFB000D789B72C375C88F8EDAC60F45F3C7C9C6B -:10DFC00022E41F466FA9D8E28B4A32CC532CEB4493 -:10DFD0001F665DFFD04DF08FD47EA81DB3337371E3 -:10DFE000684342BC406D84D69703837F0CACE78ABC -:10DFF000F58E81666A179DDDBD1FF9ACC0E8AD46A0 -:10E000005C7C3774E9F3B46F70B786F108066DE98C -:10E01000C9DC21396104B99C782F26937C0CC9692D -:10E02000CD6003847C7D5152D63A901F91855D1856 -:10E03000C09B5ABBA7A27F19869884EF43313569EC -:10E04000953F59C0EA36FB0F8E94CE24D2E27C0174 -:10E05000DA7E6419ADACF90C1CEF0E06908FF9C98D -:10E060005B4209D2177FF285A7E1647F92E3596989 -:10E07000DEBF0CEDEE1B157F6C13D2438CEB072F2C -:10E08000FB07E55FD66CD5268FB30D7B3DD7A13757 -:10E090001628415A6FF65740E803A37ED29821F81C -:10E0A00018640D4837DB6A55C0F982410E9709673D -:10E0B000AEF2495A0682E318C2C1D0437084CB80C5 -:10E0C000FC3D06CF31073CC71CF01CB3C2D3E2E5D0 -:10E0D000EB75FAFDCB65E1F733BF17F5E00978DBA7 -:10E0E000A8438231C6915E096BBC6DD0DB47469573 -:10E0F000061AEDBFD3EF67FBF39E4D3FCC16759D1F -:10E10000D9F525049FFD3D14119D505D8141FF759A -:10E11000F96C133FFA575F617C77ED6117205F312F -:10E12000FE55F0BD4BBCBD56F8B1CB51FF33BD7DA4 -:10E1300015C4C308DF3B2093BDFC0EBC109E6E913E -:10E140008B77C86EA1C7D9865AF9176251F4ABD53F -:10E1500060679F1226349874269DA47D8B01F9DD9B -:10E16000414E6F49F0B6917DD1C5F5A3E9F77DBD6C -:10E17000DBAEAFAFD96EAF5F0D8BC7207D5D7DA7E6 -:10E180000B526CDC6BADF607DB9F6FC91AC1770DC4 -:10E1900034776A41B2B31A711DCB3550D14F5BF958 -:10E1A000B37B662E63EBD921F4E85B4CAEEB16BD76 -:10E1B000715D24E536CA87AF6FBD145BF42569E451 -:10E1C000F56D70F52D42FB20B9D5457E1D38FDB5A6 -:10E1D000BD0AF96B967E04EF955DF6F59D6AFDCE5E -:10E1E000F5328F85D67BDDAE65A437475A8F7B9796 -:10E1F00064A432E8B7874D7D28E48B49DF265F278A -:10E200006B80DB7BBFF7A5D6B3F97E83F291F6BFB7 -:10E21000F96C1E47699E85E5A9FAFDDBE7ECF7EF8F -:10E220009FB3DF6B428E3BFBADF4F6BB713F57AB48 -:10E23000C93A491EB2A3BDAE66A390A1C2B5AF3A1A -:10E240008DA698A55DD769B63B2C959C56BB3A79AF -:10E2500094F18E0B3BE3A93DF7B9FB91FF76BFBA72 -:10E2600008F5FB37FE49012F5BD7F13D2148237D9F -:10E27000AA2937DA2BD731BA4A513D3DF3628B5D7B -:10E28000C52896C6FFC64321B20FAE7BC493AA67CA -:10E29000FDAFFBE97F4C038687E3EB06FEA510E9A3 -:10E2A00075B7C4FDBF64FFB48BD9F3EB54B8229E9D -:10E2B000814E6485F3CBDB3F0F34A2DD27EDDA7F9F -:10E2C000398DDBFB5517CA65B3DD47B28BE665EDCB -:10E2D0000C7C9F7C504A4D92387C0D5387FBDD6F40 -:10E2E0003F2871F8F6B9523E846F578F3BC1DAADC3 -:10E2F000DEF52ED1ED790FFD388C7858BD4FB1F990 -:10E30000BBAB772969CF342A5FC51235A3C4F86D3A -:10E3100095E0D7557B57921E58D5BBF95DE4D7D50C -:10E32000FB5C36B9CEF0124B235E5F5262F5587F2C -:10E33000F487619DA1EAADE8EEB0564EE32E73334B -:10E34000BABA68B6BD1F8EFF61CEF0F1000628AEE6 -:10E35000B9BA77239F0FB8BE31F9F42DFC4BFE708C -:10E36000BD3145B19F3B9C806767521C72576E461A -:10E370003FCED41726BF7EE3C7277626D9BC6F3F92 -:10E38000F2879D4906FF8AFF797FE7B7D9BAE0494E -:10E390009F867268F5EEDF84C182F75A85FB61C7FC -:10E3A0001FFCE1033B18BF1CFFAD87ECBAE34FFC39 -:10E3B000D7789DADFBF8C31F8D41BB73ED13E78F7D -:10E3C00045FA5AFBD879636114FF01E935E5B1EEEE -:10E3D0006B8AF655DF27611006E071513AF6E7E0E7 -:10E3E0005E258DA1DB775EF6A43C0C3FABD9B396DE -:10E3F0004ADCAF95A487B07E33C3F3AA3D1BDE553C -:10E40000A665C277B2508E62C9D8268AFB7DF145D7 -:10E41000E75461E98AE9481F3040F2DFD96FF5110E -:10E42000B6AF678FBC8F27E01337E27FF59E8D7CF8 -:10E430005EC73EBE837F999341FF0FDBC715DFDFC9 -:10E44000812FF7E6D2BE8FB48F2B1FBB6454FFCC55 -:10E450009407A7C26F93C4E13A5B31D628C8578F9F -:10E46000FCE8811D11BEBFF50C21C77F7C623C0614 -:10E4700097DF700D5C8E7272E0098F762FEB73DD83 -:10E48000132F119F1D7FEC79B74E72128212D37B2E -:10E49000C761F04F1FEAC15512AFACFE4128ED092C -:10E4A0000FEDD3AA54439D1EA6E7AFD2F314A7FFE6 -:10E4B00055A9FD4BA40CFBB65B29E1723995477851 -:10E4C00059A9F7B9B5A07D3FA5D9B88FAF2E40BAED -:10E4D0001B691FCDF56BB8FE5996FDFC01E7DB917A -:10E4E000F8F3788F4795B286F6F7B8B00F56A7A421 -:10E4F000972003DF02ACE3F08E70FE68964E7AF848 -:10E5000081831ECCFEE6BA4FC5D7A75ECF67C3D7BF -:10E510009D8A6EA31B136F6F7F9259DEA7859C584F -:10E5200005C9BA8289C3F5950AF16461F110BC9DF1 -:10E53000BD0AC9F1B7772964A73BE5C2AA11FCF16E -:10E540005F29DCFE58B56FFF34945F6F1FF8B9A0E8 -:10E55000434EE7ABF6BCEA4E0AF99FB2CA7F1C2FC6 -:10E56000C37EBC2CE05EFD78E6F156EF7937E378A8 -:10E570006FA9C65711FEB7FA5C906443BCD5AB6473 -:10E580008C6F1C505CB6386E6768E6CB5918DF0C90 -:10E59000FB755CF7FA75C64B49B4435E7001D981CF -:10E5A0006AEC0D0F7BBF3EE4A773EFF5E1AB41B71B -:10E5B000E8E976079ED4689CFC603512AFE2B1D7DB -:10E5C00094CD1F7569B20D6E509345184FF955F1F2 -:10E5D0007FA938EE7368FF9D31D4FE39153A72D9A0 -:10E5E00078CF1952AC0D32C4A71CE3C7E729A05B52 -:10E5F000E9CC2893ADF1D5F0819B282ED102CD69CD -:10E600008C134111F4DE6F19F7EE560DD26C7EA813 -:10E610002B93ADF1554F73B3E1617014ADD54AD072 -:10E62000341B69FE71CDB23DAE2DE65F23E209B029 -:10E630006BF7EEDD6CDC3A7C57827E0C8F573177BE -:10E640008AEC98F3841CFC6761071F90E287D0CFA7 -:10E6500032F46D2ACA39A9749B8AF6C4C24FBAD55E -:10E66000E5167A5C58DA5684F472F853A531135DD6 -:10E670002D51395DB5156F28C2FE877D371671277C -:10E68000344AEB2C10EB3C34EE9A603F1B777FF161 -:10E69000355B2633B8EAA20A60BCA52EB26C4B05E6 -:10E6A0005B7FC11125E663F582A6A49A983A7C9E09 -:10E6B0009D28EF19FEEE453C32F87FD01AA5FA03EB -:10E6C000AD3A95BB5ACBA8DCDD1AA3F77B5A67534A -:10E6D000BDB7B58ECA475AE3F43CFC2D7F02E977FB -:10E6E0006F6B233DFF696B82CA1A95F3DB42810F82 -:10E6F000CBBAE91C6C497B781DC6514CFC39F15DE5 -:10E70000CB282E87CE0D241DF13D56E572C589D745 -:10E71000969620D9A53B25B0E173A6CAEDC8B8806E -:10E72000E3903771A1CACAF7EA4ACBC9EE81780CE7 -:10E73000E5F44E297E5B05E397A7C6CD8A5AE56EC0 -:10E74000249888AB7943F5F15D3C3E334BE5F2A963 -:10E750000EDA0E6531F88C4F40473A33D779A05A1C -:10E760002F42B978A08DC1538EEF6528B3D0993967 -:10E77000DE5C011F0433CBE921BAE5FC1F9D5BB6CB -:10E780000DE3C4CCF18C4DD2C9EAB6F5DBA69A7183 -:10E790006F9DE8D8A413C63F4F8D8BD030DC5F6CE3 -:10E7A0002AE6EF7D9CCE5BFADFA5F856740CD8E222 -:10E7B0008D1D4D32F9393B8EF2B8F489A6926D93D6 -:10E7C00059FB6A8637F4DB73169666252C74BD45B3 -:10E7D000D0D30E6F3C4B1B457F758A7666FD155F67 -:10E7E000E23B88E7BF9FF0937CA4E71DAED4652889 -:10E7F0001F5B8E7AF475129E37C493B86FF122F6C0 -:10E800009C8174A26EAD879616E4E70F2D37EBDB83 -:10E81000CEB0F0792866E7EB9D2DA3C7A54DB8775C -:10E8200022DCA3C4654DB8CDFD3851B764E01A1899 -:10E830008E07E7B8390B978C3AFFDDC8771EC2C345 -:10E840004ED5229F8A9A353A6730FB9BEB75F67757 -:10E85000AE77285FE1F4CE677A5D908BFBF9F0C765 -:10E86000E31F7D0E70CBE30ACAB12BD4442FEECB4D -:10E870004C68A63AA803F9C82FBFF373FADFD1F9A1 -:10E88000403EF1919A2A46BD70BAF375403C5E8DC8 -:10E890007A2B26C7ACF2DC2C7FA19A718234C58F0B -:10E8A000E888994D29076E8E66C2F3E0F845EADBE9 -:10E8B000D6F3A42D00DC4F4F7BE99C0303221AAB57 -:10E8C000171F86CA4D6CBCDD429E54ABDC2F9C7E6C -:10E8D00058EF5178FC48690859F028E2A9661CAB4A -:10E8E000036E068D7575AB15FBB1B9C9870DEEC406 -:10E8F0008B882F7754A7F3775724417C0522FE3D60 -:10E900004EC4E9CF1771C6FB5B789CB105E2179E38 -:10E91000817C7D4401F28F13136DFCEB5CE77E413B -:10E9200057FF24F4DFCF85DC2E55F74B596CFCD014 -:10E930001BE9036156FE4CC8F1C7841C3FB0ED5F74 -:10E940008A319FA023E18E214EC355FEB4C4ECD082 -:10E950005B67BEA15FCBDA77744F6E47FC6C58CB18 -:10E96000E3F28FA2DC67FD1E16723FDCDC793D9D71 -:10E97000DB09F95264E60B08795224E4C9C16D2F12 -:10E980002EDB80EB4B78699E16483F8D717D582BAE -:10E99000939D12EEFDDE0D38CE43AD061FB77BF71B -:10E9A000DFA17D7F8F375DF9AF18FF9FE78E25517F -:10E9B0004EA526D9E454B877DF8DD82EDCFBCC4D9C -:10E9C000940F23F0E0799CAD9735C9BAFD703AC435 -:10E9D000DA15F6A7D1EC66FBDAB3700A1BAFB45EAA -:10E9E000A670F51E297E5E08E9A1819F4367552C1C -:10E9F00069C3F6DD2B5E4862FF31CF364BB8ED3987 -:10EA00007F776F35E2EFFEA2D79EAE66E5645731A1 -:10EA1000D141F0A89EFF43C0F1E3D16BF591E9F03D -:10EA2000E08A358072CC73A74CE7F4F7DFB906AE05 -:10EA3000B1E65DAC5033C6C726BB3CFC3CEBCEC553 -:10EA40007D2867CDF3ABC295B55EE2FF67C1763E28 -:10EA50006B9E6399FD2BA4C464571E9D57F0732DC4 -:10EA6000D1BF40411B8F556F90391FC4D33E6BBE41 -:10EA700049F07A399E099E592E95E0698FD5EEFAB4 -:10EA800017369F3AEB52D2CBD06D87C3D98FC131A5 -:10EA90008BC3C1E133E118C74C82209BFFF6852F61 -:10EAA000E6237C1FD60DEA1B3FFAFF1DDF95D3132B -:10EAB000D8FE6C6D97E9FCFE40D5012FE2714B55F5 -:10EAC0008D9FDB3F9CEE72041FFDA04E26BE3D5184 -:10EAD000C5CFFBE19393741EE612EF73F20E78E953 -:10EAE0000C236904AB6762FA81F9C7925FC0705367 -:10EAF00099F4DBE4A7DC9263CB371807058EBC954D -:10EB000092A1F6E87FD71D91502F85C47974A97919 -:10EB1000BEAD1C8DE1FAEF32F562AB97CA9EE603FB -:10EB20003E9DC1F58B664627B42E7B5E8AA7096899 -:10EB30005D05CDFC9C6D8BD6B7DFCDEA45DF65A8C2 -:10EB4000D7D19EEB25F902DD3C5FC03CEF98B4C203 -:10EB50009EB752E4C8B719969FF519FDCCEB5DF648 -:10EB60007CC313B0650AD1435F896D5F7AE630B725 -:10EB7000E6ECE1FEE6E0B8C29F82289773393E3E9C -:10EB8000C7ADDF529AD05E0A5F58996D3D1FED7494 -:10EB9000713BE9D0EF3C80F1F80DB55E8AE398E770 -:10EBA000E8E67E6FC5A42BCC77687FC087F4B223DC -:10EBB0005242E5C1B9CFF8FA890E793E8047AC6977 -:10EBC000DDDC67163631BCDE9327938EE9287A2187 -:10EBD0001FCF176FAFF5D2797F38D0DF7B90D58309 -:10EBE0007FEF8EE1F9F6FDD5E946ABFFFA908BDBBE -:10EBF0005BDB5D425F6DB19F3F333ED88E7CE009A9 -:10EC0000C6E9FC52F68ABC09879F63E2237C205F39 -:10EC10002E9ECACB92A943F6F9DD826E760879BFA3 -:10EC200045C87BE738C54DDA0137DAFD2BB44A25F4 -:10EC3000035F4E68B1DB09E39AED7935854D76BA0D -:10EC40000FC50A1C76459AF498A98F37F88213915C -:10EC5000EE2B99BEE4F681265BCFDB9DFA78B76A8E -:10EC6000EC7391BD7B7A764238106F467C3BEDDCCD -:10EC70004302DF1F2BC601C46F408D1F72511E68F7 -:10EC80009CE48CD36E1806273038A78E0AE72F5DD8 -:10EC90009FC17E3AD5F9C09FE4F8F6E718C8F3B3F0 -:10ECA00040E45D84480E7784B8BFD2E1E27EC27B47 -:10ECB000625DFFE15268DC01415FF303D09C399F44 -:10ECC0008CC78B3E40C304DB8DCD9CBF8B160BBD28 -:10ECD0002FCCFCFE03173F679B3F61F479FE88F35E -:10ECE000B0F257AAF1AECB728EF384CB78DF658990 -:10ECF000537CE8D2383F98FB21F2734DFB699F6A41 -:10ED00007C64ED6F96390B553ACF3D01FE98C2F009 -:10ED1000F3643EEC0526479E94043E7FE7A33C2027 -:10ED200013DF83F635CA0FD4034703298CA798FB5A -:10ED3000609EC30CCA11D1FE4C3797278C6E026EB1 -:10ED40009A3FCECF0B214DF2A140D0CD0EDFD2DBCA -:10ED50006A5979EBDCB75EC67C85771EF3E908D784 -:10ED6000D6AA6361ABDC84263BFD98CF5D1F16D22B -:10ED700039FD37A544BEDBE247BA22036EECFFA49F -:10ED8000A4933F97FC8D42F6C893526A0A192A2A27 -:10ED9000D079C693D746539B2CE71D4E3B3FC7D730 -:10EDA0007FD76A5C7713B39760F8BE9976FAA0DDD7 -:10EDB00011B5F78FBB41D8D96CB98CAF2BC4BA63EE -:10EDC000AAA1201C332041E52CD0A964FE40A59BBC -:10EDD000B59F0E03F9C847EB02E3BFC4ED8CFF33C8 -:10EDE000BC197F8D781BA25BBBDE36CF1DF2041EE3 -:10EDF00042D04CE7EFBF685CBE71129BCF5D14241C -:10EE00007B38AFB1FD7A398CD97E7D1AFA9B79E2D5 -:10EE10003C1C9670FD6C9E4FE7D4DBF5B9537F7BAD -:10EE200084BDE11941AF3BE5E6487A7D85DBAED78D -:10EE300007E3C723C83F67FCF8D4F24FBFADB6184D -:10EE4000F3348C976AD1AE9BA752BC333C11AE8889 -:10EE50005BE8E1F76E223A56F2BC994D8C5F53673E -:10EE6000703E07F413024C01E179C2383985F93656 -:10EE70001B92A93ACC3FDBA04ED2ACFB583D8EDBB7 -:10EE8000B35B6BFC4D56BBF60F7E178DFFCD40F587 -:10EE90003348C7E5C1540DB97B067304C7F0BC4BBA -:10EEA000DCB7B334E8C773580F70BDCD38C2CBF5AB -:10EEB0004AADF63AE56726E0646034BD60CFC7DC52 -:10EEC000ADA6D6F9111F111E7F096D97283947E9A4 -:10EED00035D298CB5515587CB79BEBAF329C67FF6A -:10EEE0004C66EEB2F67FDCEF263BA73754A8A23D76 -:10EEF000F9A4BCFCFB68070EFCD603789ED2FBE9A4 -:10EF00009974AFA137F4A5054807BD1230CF96AD6F -:10EF10009FF10F4FFE8100C6EDC3E7198071CB81D1 -:10EF20005F40EC5E36BF2BFA689CF276C108C8B32E -:10EF3000593F1F7461FE4AECCFFEF7CF6574F74866 -:10EF4000B0F28EB361280E60FAFFB5FEC4A3086765 -:10EF5000C7987F6B423EEB62702A6487195184BB6D -:10EF6000324F26FE83BC606A127B5E7D38528BF97D -:10EF700068D56A054A1A0607DFEF577C892710FF14 -:10EF8000B55A436D366B5F7544277B6541F4FA4390 -:10EF9000589F7994D73BDC40F620F22F58F8AFFA0F -:10EFA000C3F1B4BEC3428EB7478D3E431A653F34AA -:10EFB000D5719FC39EC762A5036DA68D0E122E2B21 -:10EFC0001DCC667430D54A0786F459E8E07B42DEF2 -:10EFD0009E9A5F389FDCA870BE194EF7CDDE9CF27A -:10EFE000E1FC61CEBBA92A2782E7AB261F68B36E7E -:10EFF000D6B0EE59E68E23DF997C61F283E21BE402 -:10F000008B8B7C6C7F9704F5F333F105FA7156FA1C -:10F01000BF78043E5904038730E77E910AC92C2645 -:10F02000427E35E78DD2F116BA77E269D13C098E7E -:10F0300059E4D1C993BC6EC1A3369807AD9C3EBEBE -:10F040005F50F58E8885EF3A99FD8C4661971C8359 -:10F05000BC62E4BBE541CF0CBCDFF07094E2FB9EE8 -:10F060007813E5ADCD7A3B7035A3C33F8E91755CC7 -:10F070007C87BEFC21E2DF97038076DBD699D74DF3 -:10F0800040FFE48FD72626609C7323C3FF31326E86 -:10F09000526365CA85EA1FCBCFCBF4282F1351FEEC -:10F0A0001CC4FB94A81BA25D3FB563FB6C9387DB7C -:10F0B000BD5C0E6EF7723B70A3BBDB8BFC3550EC76 -:10F0C000A5F354E7FACFF5707E38D70355B108CDD4 -:10F0D00046F1960EAF52D7C3E350E973D9F37327C5 -:10F0E00096DD6BD58F66BF3B5A53F1D726E17A7612 -:10F0F00051995B9F023C37F09725758CDB7BD7419C -:10F1000022937DB8C3CBE304DE03FF40E74DB9A5EE -:10F1100031F24F23F56C3CCBBE2E6228CC62728656 -:10F120002DCB407AEFD0FD64AF2D8AD4BCA94E1B05 -:10F130004E07F8E798653FBDFFA3247AB91F477EC5 -:10F14000C85AE1F7D59678897F3A5ADC3D184FBB0B -:10F15000CC934DF8FA2052336A9E2DFA5749460F48 -:10F1600029E65F6189E720C933F83908D6F11C0424 -:10F170004B3C07C112CF41F03D9E8360FD27AD0699 -:10F18000D5F13C04EB781E82753C07C13A9E836042 -:10F19000B9AFB589CA7F6C6DA6F78FB7B6509DED34 -:10F1A00013D9E350968C2E6678EEBAC96DE0F976E5 -:10F1B000B7D88F8346492EEEA32FC2FD53DFB3B7D6 -:10F1C00003AEC717E571A5CEE8ED70252BBB6684AD -:10F1D000BA30E0E57D2848A54FBD0330BEB0534AA4 -:10F1E000366124EFC60DFBCE53991E2F8D5E5F93C3 -:10F1F000C3EAB76C78723DE6F74CD6DB62CBB5A1BB -:10F20000BA1EAABCEE614B7D42798FEA67EDD779D1 -:10F21000F6AF477E4638D0C8DBB2E1E0796DA58C09 -:10F22000984A80EE790C14BB53488F57E17E4D42CB -:10F23000F8B9FDFF65581F457F7A82EEAE443E6205 -:10F24000EDD39C7E4FAF7D371E66CD18DE6FB47652 -:10F2500072D569B5036594F1F0BD34CA381DB05E4E -:10F26000C33B679B91E731EFC817207FAECBC5F951 -:10F27000B7CBC7CBFF167C7BC85B13F7B232EEE58A -:10F28000FBDAE58BD7613C7460AA4C71855E171B75 -:10F290000293775B8A7F5DC2E6FDE6332A607CFAE3 -:10F2A000871ECEFF932684B85EFDB697F4EA051359 -:10F2B0007EDC9EC3EA93EE8BC5504F6E86981FE9A5 -:10F2C00024B985F3FB8FAA26E634B0E667CD782C07 -:10F2D00007E30DAA802385F79258BDADE3EA09182C -:10F2E0000FF9E3F35C7EFD54CCD3E3EA6BA6FD9CFF -:10F2F0001124FB82618CEC87B6A84AE7F7723E2F97 -:10F30000DD2EED6FB09D9B29E82483C7FDE92C2FEE -:10F31000F9E91F7AC47DB63EB22BDCBE8496CD9E41 -:10F32000772765E2F7F59A3F8529FB9B839574BFA4 -:10F330003659AE527EF6E6721EC70B842E4DA13DA5 -:10F3400071DB7E1F970F412FE569A5CAF71EAE89B5 -:10F3500060296BC8EF2963711DE15D9335CAF762BF -:10F360007FA3F74D11CAE7DE0C625F9A64F2173B88 -:10F37000C6FCF95FCFC673F1AF6B3171C788F22558 -:10F38000C90492F1BEEFC08100C2F3B7E6FDA4FE4E -:10F390007501D6BE7DB916C37D98A6D5D4611CB1C2 -:10F3A00043ABF1225F05A6D67A97911C1ACC67A6CB -:10F3B0007B70EDE5DCAEC5F7C897D00E87F0DE4B6D -:10F3C000A1906581EC4A09EDA18E7A0A2F61BEAF4A -:10F3D0002D3FB33DE742CA7F5716E5109C1D60786C -:10F3E000B17DB25E25FD5518F4A6D1DE2B34E38B3A -:10F3F000989A6CF1377257D8F39BF39B54DBFD8FCF -:10F40000B1097B3D4FF80F798E3C68C96B9E23DABA -:10F41000F1E45C6F6EE4DE6C8437172F34EBC3D7F6 -:10F420007347A4B201D759A8F909EEA8B6AE1AE5F8 -:10F43000D758686E43BAFBCCF03AE09C56DEDE87C4 -:10F44000FB3E4D57E9BEC3D930B00EC7DD2CE8BC3A -:10F45000ABD8AE4F7FE851C43970CD1CE4478C87E0 -:10F46000252DF31727FD90B4CC37B12BC7569FD469 -:10F470005D606B7FC6F612DBFB29A9336DEFCFDA37 -:10F480005569AB4FED9D6B6B7FF6BE1A5BBD227D60 -:10F49000A1ADFDF4C38B6DF5197D7F636B3FEBE58B -:10F4A000E5B6F773FAAFB3BDFFD21B6B6CF573060D -:10F4B000BE656B6FDAD74EBD38DDFBF9EC6A0FDE47 -:10F4C00007B3C50FED76BBD3EEF6FECF7A7D1DCA2E -:10F4D000B5B09BE85B453DCEEA6B6EE27E8F777EF2 -:10F4E0004C47B93245D063246818B86FD5612FE90D -:10F4F0000335C8DBA9C10564778CDFCEE4D174B4D1 -:10F500001661F07D00E5726B325EEA1A82DBA77548 -:10F51000D3DD86EA701DC5DFCDFEAA66402284F3E6 -:10F52000E93CFF887995D8CEA7B3FE96753C29CBE8 -:10F5300074157C80F967F75AFCB391FC31A7FF750D -:10F54000BAFED67819FC58F648F1662CCB9B9FAFD3 -:10F55000C1343CE6875DE565FBB3D51D6FEA61E329 -:10F560006E2DF1F3F332E1877515F7125F0C14ABD2 -:10F57000A45F40D5CB175BE260B709BB32E0BD8B1F -:10F58000FC40B564F6611DF1DEA6527C62B3C4E3B3 -:10F590002849B60FA8D776CE7DE3DD5BD8736F8997 -:10F5A000B7D0CBE451ECA0DBC073D23B045E4BB4CC -:10F5B0008A1A667131FBA2E1009693756667B0B254 -:10F5C000AC6CDB012CDBBC2534DF99B1876B50962A -:10F5D00078E773FB4F99E64EADC3FDD3381C23D1BA -:10F5E000999AB39D9F6795AAAF23BDA1557E521EE0 -:10F5F000A2031FD2814425D18F2F1224BDE1C30362 -:10F600001FACAB522AC0DE474A0D09F333AAC3DB55 -:10F61000E97CCE97B6DBABCC2FBD0DF11AA9B7EFC5 -:10F6200077C0BB93E06B97789CB62B5B7FB686C1A7 -:10F63000DF9557928331168C633458E4CD76A14F11 -:10F64000AFF0C9A6FE2779E343DEC81BB27718FDE9 -:10F650006F9727227CDD8072CB77733720BDFB3418 -:10F66000B69B686F7F2749F46FDABB3708DEAA2D97 -:10F6700069A473B1F7239564DFFA5A7E92117FBEB5 -:10F680007E058CE923E3353C7907E97B2871EB683B -:10F6900057B4E86EA327D339A047F81F981F82F00C -:10F6A00088FC902E810FF35CEE7D336F4A9C07DF60 -:10F6B000900DB6F3C11BF22AC78E668FFB987F9818 -:10F6C000B0C0BB91CD8378E9F8A4A12E4EE784C0E9 -:10F6D000EFB37D5ADE43F7863F59AFE339E62C811D -:10F6E000EF733D1CBFE3DD407EC27918E7988E5E64 -:10F6F000E997EB902FCDB8C89BDE1CC27F2C094A3E -:10F7000033D92B2E536FC927CF269875B719CF241D -:10F710009397EB35F6EF7EBC7F31B1CB7EAF69526C -:10F72000B7BD7EC6767B7D4ACA5E6756F311B40BC1 -:10F730001A80E3E7AC5DF6F70D663CB096DFC7F0E4 -:10F74000B2994F72FD6BBBFF0A42FF9B71D771BD2F -:10F75000E96A14AF456BED7AB540E8F90287FEAC73 -:10F760000C29140FA83E1C3984F6A319A779C5A744 -:10F77000DBE29F66BCC529CFFD47B7017B437E75A1 -:10F78000C2C3E31009E6DFB41489F8C6385EBA14C0 -:10F79000FDB9A564A7359F81F2E99037F1B197E2F1 -:10F7A000CEF6FB12EFD5A9BF90743E4FC232CF8D7B -:10F7B00065C90BF8F253947F62C63B4C7F5E091A11 -:10F7C000711C6F73EC85E683186FFAAD07709CF3BC -:10F7D00095670FB7B2FA9A712AE54B6AB3567CDF88 -:10F7E0008FF1427CCFEAD5C5FA58A2FFA75DE4D7D6 -:10F7F0006F10F46CDEE331E323519FD03F3ED32EF4 -:10F800004AFA453EAC1FEDDCB37631D96CD3733C7C -:10F81000EE66C6D7A6F6DADFF78294ABB1FD3BBB46 -:10F82000312573BBCA08565BE2EF678AFD9AB6348E -:10F830007DFB5256DF03A94AFCAE4485A08BD8213C -:10F84000FBBDB13120D1FD82314794588AB59FF676 -:10F85000B8FD7DB9E35ED999CE7B668E787048811C -:10F860007797B1F9B6E8CD12CACF2D4B99CCC2F932 -:10F870007D22CF78324C46FA3B5F09C6D288DFDF63 -:10F8800028A4373CAF9EF1D232D4E7CFF33C166DBB -:10F89000A2BEAD96D5B57F55483F6901A8A8080E10 -:10F8A000C58FBF773206EDAEA178D46EB6AFA59303 -:10F8B000D0BFF602EA959FB0FDC57A2FF3C7B1FE1F -:10F8C00008F3C7B1DCCBFC717CFE53E68F637D1F70 -:10F8D000F3C7B1FC47E68FE3F3C7993F8EF56F0698 -:10F8E000AA1738E359D6F8DE503CAB5F32E359280B -:10F8F0004A3E70EBB4EF8371AD048F6B9D7A1CC3ED -:10F900001C87E286C3C611F1C3776EFAB707F09E73 -:10F91000F5CA19EBBAF0BEACD765C6CF789E84990C -:10F92000FF6CF2DFCABDD7D3B9B13BFF4833EEC796 -:10F93000DEAA207D8BC8ED4A68281F9DFE97E977D7 -:10F9400039ED5FB374EA233FDA01D3D14EEAA6B8AA -:10F95000CF261794D1FD59C91F43BE70C62B4D3E0B -:10F960007ED15792F1BED4601EAD88CF7820E5C518 -:10F97000B89A5B12EB14799E24C2D8109B919F2DEC -:10F9800079C9C1F234C539824183EC2F89D96564C4 -:10F99000A7698928C6A13A47C89BBD4FF0675BBEDF -:10F9A0009BBE37D199CFF3046A8B6251ECBF3E7F87 -:10F9B00066D49A476BE6F91E0ACDF4F65BC65B1374 -:10F9C0002A19554F294CAFEAA3E855C5C3F3DCD734 -:10F9D0001F98E3C5FCE54DC1E57D685F6D8A46E88B -:10F9E0009EFBFEFC99647F0CB68FCEA63C6725C8B3 -:10F9F000ED5625EA25BB55C5F5970FB537DBB5FAAA -:10FA0000385D31F6A3F85C20D84BED3C6A9CE21FD0 -:10FA10009E08D0B996C7CBF30A82CCBFF6DAE2AB28 -:10FA20007CDE1611F7DDA427E2D86F5354D5511CA4 -:10FA30006D2AAB243CAF17785E9F67EAFD18D91B8F -:10FA40003F137836C7592FFCF5F54D6EB2BBE22D4A -:10FA5000D9466D2EE56DEEF1E1F8C17BBD9807EF5B -:10FA6000CEAF1A75DC0338EE8CD1C67DB5A6763ADA -:10FA70008DFB331CD71D5AAEE1B8AE11F2F39F13C4 -:10FA8000707E5EFB92614EA3733130F56D2A6A3D44 -:10FA90004F76967EB413A70FEFB752EF5F80F9C190 -:10FAA0002A24EBFCCAF0FB0DABF6F1EF556D55FBCC -:10FAB000C8DED9FA8994F19EC418BF24CE6B07FD25 -:10FAC000709BBD5228F8A950BCD7D15E2946BFD241 -:10FAD0006E5F4C3F6CAFCFE8B3D767BDECB4578CCB -:10FAE000DFA0BDB244C8BB3E269F7972C5808A7232 -:10FAF000209E4C5523DC0DD0DB86E7992E85E7113F -:10FB00002C11FAEA22A1CF82FE6C82BFB0C96FF33A -:10FB100013CDEF6E1489F1C7D51EBABE1D856BDCFF -:10FB2000B47F74F22FC72D7CA49AC4A4C30E6A308C -:10FB3000ECF7562F72D8394E7BA85AEDA1BCCC02F7 -:10FB400047FCC13CCFC475E2FD5DE7FC9F755E7369 -:10FB5000BC1D4C6FA1BD627ECF80BEF7C5FA8F532E -:10FB6000D3522C48795E940F58B8168C9E0C747C36 -:10FB70008ED8F761784B9E4B783B4F3C2B08F2EFC9 -:10FB8000A514D42A29BD98E789A13C59BC82AD8728 -:10FB9000ECE593745E6DB6CFC9EEA5BCB21DF5124F -:10FBA000F71F93407688B9CF3B82FC9E4DC33952F4 -:10FBB0004AC6FECD25343FC15532B4BF0C4FC738BD -:10FBC0009E781EDAC575F6FB400D0E7BC3A4878BAD -:10FBD0001CCFFB7DDC2F32F9E09D392F4F1ECFE08B -:10FBE000582925EB02CAE9EB490B7FB84E221FE2E8 -:10FBF000DFC7D052883F0E781FD5288F20BBFF2E3D -:10FC00006024D9E08764ED3C807FF60F9C25B17AB3 -:10FC1000E3A6B33BBAC6E1B5C6811FA151E6D950F0 -:10FC2000757EDD394375FF2683EA11310F732D92FE -:10FC30007CBF2DDF3760F0EEC43C02B44B0DD8A67C -:10FC4000600EA6AC6D8B150FF5CBC17ED228FDE200 -:10FC5000B04DCDD02F68F663E8EA34BF0752822555 -:10FC60007F2F0B78ACF3AB88374D0FD27D9F05AA61 -:10FC700086E73F5F148E31A75A7702B6B9260EEF9A -:10FC8000C7C06E33E19733C39FC2F7D6F95DA3C0F7 -:10FC9000FF97C6C7A9C6738BF79F193ED67CDD9820 -:10FCA00091D78B70B9E8BB1A7A50B68C73DBFE8F94 -:10FCB000287EAD5E06749F4775195A8CD179B97646 -:10FCC00027F9E16A76AD8676C04656473B60636F9A -:10FCD00037C5A9CB4B6FEF42A22F4FFB01E5C154B3 -:10FCE000D0B2F7B071A76A2A66EC807ACE2119E308 -:10FCF000DEF015A0FB2459FBFDFCFB17C573EF4399 -:10FD0000FF283BDB4B71A040F6CCFBB8B1CBE3C185 -:10FD100026FC81EA23351827571B2086ACA84A29E0 -:10FD2000A846269B02740EE137F6DE88F73299E288 -:10FD300023FD44DF8440BD2AE2E26339C940975B7A -:10FD40006B403F21F98C4AF1F7B17864C188B2BCAD -:10FD50003C671BC2539E600348083F8F6B4D4DC8E4 -:10FD6000B1341BBFF25DDE0F7EC9EF11305FA2F12F -:10FD7000B1E0105E4DB93256C4CBA34BEDF164181F -:10FD8000606B66FD2B7FB9F87E8C278C1926BFB976 -:10FD90007F6D7E6F27EB5D883F46E79A76BDE11762 -:10FDA000DFB5F03BBE97303968BFBF37CC6FF84E38 -:10FDB0009CF48007625E37D9174BC96E30FD911DE8 -:10FDC000D810E3FFE3807FFFCAD97F26EF0F51EE03 -:10FDD0009F78FCCCCCAB64EFAFF31B9417E4617558 -:10FDE0008647C90DDE7CF6BC40E67191360954ACFD -:10FDF0000FCD97A6F3FC0D52AC2B260DF9BFEBB53A -:10FE000018E519C0DA1C9BBD6CE6ABAEB9B6786CD0 -:10FE10000E2BB386EE0D69488F6BF24AC97E0EE752 -:10FE2000F67F0DE5EB47FE5BCFF7A23CC53C87B9FB -:10FE30004C286FEEEA483279EBF9B010748B5DE62E -:10FE4000519B290EE6F970BCED79BAD57ECFD0086A -:10FE5000CAB5384F514027BC5683D68EFDAAC17E05 -:10FE60009FD0F361BECD4E1F1ABFC8F63CCDEC1932 -:10FE7000EB772C461E3F007A9975FC89238C3FD97D -:10FE800031BE9671FCA171736DE376A83C3E9A8CED -:10FE9000F869DF9DF64055A0A63890374AFC3EC071 -:10FEA000E3F71BA2CD14BFAF01C6F08C4ECEFDE42C -:10FEB00098C2EFBD01D96D50648FDFD708FA95194C -:10FEC0004520FD9EABDABF1F361F9CDF13B3DB431B -:10FED0002F21A3B079E550551FC5F13F0AEAE87F0D -:10FEE0008D642FF7B502C58FE707FA6FC073EAFA82 -:10FEF000C0F75D1DB3459E6C01C0DF04F69E8FF711 -:10FF000003FBC4BDBE8E884C7889D78CA57B3AE6AE -:10FF10003871374C42791897797E02FD61F3F7E525 -:10FF200015D8F21CCCD2790FB4C190E2A516BAE96B -:10FF300093195EADF39D57D8A358D611F7C00C9A0C -:10FF40004FD8B983F38DF97CF33D2FE24EE67C0D5B -:10FF50000BECEB6B706BB4BE06C1BFE67CCFE3FA73 -:10FF600032E0F794F3C99C6E06E7BBC0BEBE068FB5 -:10FF700046EB6B10DF031E9C6FCCE79B6F83AB39A6 -:10FF80008176DB3689F3FF77373FDE81FBFA7EFD32 -:10FF90009A28E90361175F841D58BB8B543EDFA28A -:10FFA000226FAACD32DF0E26070C910F6F78307FBB -:10FFB00043A37AAA354AE5BDCCCE36287FA38CDE92 -:10FFC0003FD01AA3FAAED6D9549AE394CDE6DFA770 -:10FFD00099324FCA686FFF32C0FDC66DF9DA6557B6 -:10FFE000A15EAAF6F37B93B3BF0486C5FE6506F156 -:10FFF000011F9EBF5C0A15A8DB266FE770476AC722 -:020000021000EC -:10000000A470FFFC1587FA5A59DDE372E9A84F196D -:100010002FC433F9A98703DC0FF7B8B9BC87B9FC43 -:100020007B878B845E01A55E72213E2ECAA6F3FEFD -:10003000C54B8C90C6F0B644927E532AF414DE6F02 -:10004000B9446C95D3CE8FA0C660E3460C2585DFFE -:1000500031BAA4E87023EAE578E862F20FE2AC6313 -:100060000E1BE712A127AB5FF500E63BC0F96E82DD -:1000700063C912BB3DBFCD97D6D03ED9561101DC26 -:100080009FC5F5F6F71E37E7C3B8E3FB068B4EF1C5 -:10009000BD03FAE656867C53677CF24040E4AB8AA7 -:1000A00038E40928BFAD165F164546FDDEC14D0197 -:1000B0002E9F4CFD369C8E393C7F10726C47EB3E78 -:1000C0008A8799F015A82909E57561D33E5B5E130F -:1000D000432C19C3661C1E943D15E88738D7B343DB -:1000E000DA933FDAF74D0A407DBDBF4C7CFF531ACF -:1000F000BEEE5703F6F8EB0998F75C2964E21F1E81 -:10010000775D745889B5E9437831F1F0FFCD475BED -:100110001166563E77DE0755DC7F2BB27D67D3FC38 -:100120007EF0C5837515540B3D5F749D9BEC1930B3 -:1001300006CA91EE8E9C13E0DF7B33ED97F46F657A -:10014000B45FBEF8F8C6385B7EA71877A4FD72E6E8 -:100150001B5AEE8B0EE5C3637E89C4CFB10A30CF44 -:100160002DCC9F1FB3DB99B63CB7F5FB1F9430CE67 -:100170007717E6E359CEAD0B993F8FF1AEA215F696 -:10018000BC3A275C665ED5E07DDB794BB43D3A7DB9 -:100190005FB11B3F58D3B53D19074B1EA5798FD0D2 -:1001A000F4A79DF7079520FFCE5E54DCCB70C68385 -:1001B0006F94935AB18479AB296F352BA7E72466E6 -:1001C000E195F61B95641D3E57C6CE6D423C2C6DE5 -:1001D000F9760CE3775A6EE6B8F452A1BF6B829CB5 -:1001E0006E8EBAD2E3308E7D4D4E4D4D302F43FB97 -:1001F00096EFD078F347F86EFDD7823C6E7297D0B9 -:10020000E7CEF74BC4FBAFAE94E93B183E08A5A47C -:10021000623C37EE9E4DF7F656ED8865BA1FF75CE7 -:100220003871B1151E5F29BFA70DD03B07F1B5F19D -:10023000E3BB7B1F62A8CCF93848723447E1E35A2C -:10024000FA7F2D386378FF273F7A91EE373F89F7A1 -:1002500059E6E2F6DDB300E3DF5BCD3A86E4B19E1A -:100260006DD6BFCDDF0FD6672CA866FDB7220D3245 -:1002700022FBFD960B3A51CF6E95407C87BC6E01F8 -:10028000FA875B5DBCFD3F89F7F32F7CFBBEDB503B -:10029000DECF74931FB855D823267CFD417E1FA95D -:1002A000FF14F8BC45EC5B10F119F94CF8BC2513B0 -:1002B0003EFB738CEF209E7C9849C140F07DEC5D45 -:1002C0008BF9C6FFD00AB1ABD81AEE8AED7DF036B5 -:1002D000A0FE1D99F019CF313AF17970E5315A5FDE -:1002E000A83488EE0D6C9C05344E06386E1D6D5F8B -:1002F0009FCAE272EC93102F7384FDA778FAA2785C -:10030000FEAF557DEF068DC991CEE2EEC64CF47D71 -:100310007788DBE5D923C4AB1F15F8FDBD16DF894F -:1003200070B76BB7D37758DD12B71B36CEEE07C95F -:10033000D2EF85106FCFE07E00E176CFE1DF470D91 -:1003400031BC638259A88AC3BF513F0298FF1D8AFE -:100350001EA1BCD050553FF13B5D6928E07485FE7D -:100360009A57D8678F6E59BA00E54C8E62D2E1F188 -:100370004EA41B65A84E74D493C3FBBFBCF578276D -:10038000FA733B99FD82DFEB4816F0BC11E7FA9E49 -:1003900014F0DE13367E8EEB1B864F4FFF7DB7B118 -:1003A000FE5B27F17B39F3E5BEC62B912E2F0C9215 -:1003B000FDC59E375ABF93F307416F7F0872FB69F3 -:1003C000EB475E7AEFDC8F91E8F5D702DF9F835E23 -:1003D0007F9D89DE18BD1E71D0EB0790995E5FC9C5 -:1003E00044678C5E8F66C28BB3AE80B11DCF67D57C -:1003F0003F2FD885E3A95F9EB7FD21562A7FBE39DE -:1004000049BB19936CF750CD792AA4C45B418B7C0E -:1004100037BFE34D391099C69D35733BCAB1D31828 -:10042000F704C2ED1CF7208E3B03E54B3091E9FB4E -:1004300046DF0FF1BCF107C5BA46E29BE74EC13774 -:100440003F0D713A607CE30A9D06DFBC2EDAB37D76 -:1004500008854E8B6FEEA4D257CAF986AE2BCF1DFE -:10046000CE3700AF74A23CEE2CE67C313EF44667FA -:10047000B2C8C247F011BD5786EA24BF4D3E7A3B51 -:10048000F411F191B37F7884EF594D1A5C47BC1495 -:10049000D76D9CA5B5F3FB38FDA4B77B6060BF8723 -:1004A000F26C795EAB3F9934B8D9D007F87DC4A916 -:1004B000821F77A20F867ECE4C116752FB60716857 -:1004C000383F87AAD255D6EF0D1C12F37F1A8A57F0 -:1004D000E1FC3DD03F05EDAF91F6698E98EF7BD9F9 -:1004E000C69C50063A3F951EBA3CC4F3372F17F30B -:1004F000E67CEC6D46FBD3C9EFF357FDE39B0F8C15 -:1005000032CED744FF8B439F9BFF2F0E65E6FF251E -:10051000213BFF57E1773A33F0FFD74299F97F69E2 -:1005200026BC7C017E6F0A65E0CBEAD3C4F78F045A -:10053000BE7FF405F1BD51F46FFBFCF86E1B01DFCB -:10054000EB108FA781EF8D23E07B5388EC95470854 -:10055000FE901EA43876D72CD82B956484E376EBD6 -:10056000385E9D8FC3F0FE81C4E87EFE9FBB62991A -:10057000BE4FC3FAFD83157EB3DF9C90B8270DFAFA -:10058000F5E89FDFF5E520C5FB997EBC27F497953C -:10059000FB0F8632C8FDF93297431F6FD9DB89FA0A -:1005A000FE0B8CFF58263A5B2DE03E955D7058D0CF -:1005B000075BF7E3A1BCE1F2AF47FC9ECA3DE1C493 -:1005C000C110F957FD0B515EEDFC568E84F1A82247 -:1005D000232DA19FF073A1C72A433ABFCF20FAED84 -:1005E00054D312E6B3EC6CD624BC6F6419EF97A118 -:1005F00019238FE78483C1D7172279673C8FFDE6E3 -:100600000CD9819FC94E6ACC367E1B22BB2DFE0AB7 -:10061000C9ED33EC72DB5C871CEFA6BC17DFECCCBA -:10062000BFF7F2F3A02AECBFF86B56F97F34A409A8 -:100630003F948FF759F50F83EF9D10D72BFF8DA5B2 -:10064000133E275E4E056711EA793EDE4799F49422 -:10065000733CD36F35F7C98D3AC912D7718707ED4F -:100660005E5718E549874CF790160979B26876B657 -:10067000B0DB353F8E7F978893DFB5E2F66A3CEFBB -:10068000EEB959AB4014143471BDA7AF184FF14FF8 -:100690002D2CD9CE93CD72B0BFBB770A7E9F9CCD57 -:1006A0001BC179CF9D0769F41BB3D06EA078844637 -:1006B000BFF795E3E98E62FC74A3D4DDB81CF5EABC -:1006C000C220BF57125D728AEFBCF1F893B96E88F1 -:1006D000569DA27D1BB5D702DDF49D8CD36EEFE94C -:1006E0006ECC945F32232C9B788D8D8AD76884E200 -:1006F0005A267E87CFC3F7AF3ADE2C21BE435592F0 -:100700008657AF428C4ED05E924BFB289FE92B550B -:100710009C5E80F925A37F67A3D3B4D7CE0BE77D7A -:1007200071B8CC7623CF27DA39EE2BE0B917C5673D -:10073000835C8E5143567FEF706EC6B8BF596E68AA -:10074000D58A549775FC148F430EE64FC7A2686F85 -:10075000B500A747887AC90EA3EFB95BF6F39A30C4 -:10076000CF73DE99155F1E26F862F4FD42D0B4D334 -:100770005A0FEB772DEE2BA8AC5FE8F4FB8D5C9A5B -:10078000BF7317D3E396EFA599FC3A369104FC1E8C -:100790008DBF1C3489ED7F24649E13723AB8336890 -:1007A000D69374481E2FEDE679F9BA49275CAE68F6 -:1007B000815E43AE00D81EAEBF203A858D579A8821 -:1007C000E2A7F759FD2995E42FAF03D43F7588F4CC -:1007D0008576A614637A4AAD7BEAF038E057A5C85F -:1007E000CFAD7B8AE4DD601DD298CFDCE31FAC1B6C -:1007F000DE28AB970CD69358DF29F4E4F670DD536E -:10080000EDC4FFF13BACFC512DE8F02F4D7F3D7A5C -:10081000BB86F70C925195ECAA8D0E7AF8E7B09B47 -:10082000F05FA525EE477A5874F3808A5757BCC508 -:100830009110F2C384E80749FCCEDE8479224DB5DD -:10084000947FCFA127BA96F8B207F705785A02C667 -:100850002787F62795797FCA52B43F7E9DBF97B10F -:100860004EFE368FBF05CA383F6B1E1EDFDB27E406 -:10087000C9536145945CBE6645DBC99FF2D6C91475 -:100880003FCEAA936D7A837E298FDAAB367AEBCF8F -:10089000491C0C5BE523A4E3656C1DFE29911C3CFF -:1008A0007FA92E53D7A2BFFD7D61FFB17DBA97E42A -:1008B0004545C49FE0FBF64CC67D137839D5BEBDD7 -:1008C000D89A88D5BA46DEB74B2FE3F9F4CEE7BF06 -:1008D000137838DEF89FDF437659E91DA0EF7E7765 -:1008E00095B6511CD68CBB7AF656A70BF5A17CC0E9 -:1008F0007581F03C2C9DF3BEF8C9DF6B744FE42387 -:100900004FC6F324258BE3F9486B23F5631B4CBFDB -:10091000D372052E85E7B1D9EEF199F7112E074E66 -:100920000C4BE2CBBE82726879A342DF77B802EC4F -:10093000F914979B795F2D667E1CCFFB4A40F60227 -:1009400064C36549C7EF4C406C01DEB71FF6FB136B -:10095000E27CEBEB8EBC89AF362E8BD58A76EFD35B -:10096000FF5384BF253A97BF4B62FC3B3F97C42F90 -:100970008BD55ACEA35FFA54C99837191FC4473C88 -:10098000563B69383E96C725B7A69F1A2FA78B8777 -:10099000656AC5823C7D381E9CEB6718DB8A78FE51 -:1009A0003AC333DA9D23E183B5A3FD78E932857E2E -:1009B00077668152EFC273902B1B243A6362F80D65 -:1009C0008BBCB8FAF32DF03AF1E8C4D7954F00DDAF -:1009D0001BB8F2BB218AB7BD60E2277D2E9D5F98D0 -:1009E000E72796751EE3F95B1AAD73F1EC8A5FE0B9 -:1009F000F71512ED4CDAF2F5DACE019733CCE3BD00 -:100A000005B6EE6323ECBBED3CD0099F137E9FD06F -:100A10002BCE733150D3E5A807CFCF12E763D32095 -:100A200026CEC7B2281DB734B3BC757E97CEA4B30B -:100A30002B5A1A06E7C5F125480CD635BCAFF5B4DC -:100A4000B2F512F6F73551FEFB87F1CB723BF0DDC4 -:100A500022307F97C8A0F3A62B04FE1A98C787BF41 -:100A600099762E134E78AEB7C8F0E941CB3ADFEB5A -:100A700096EAC43DAAAC2553B15F72BF326D38BC53 -:100A80006BA2FC770E191D7E60A543DF24FEFD5985 -:100A9000275E4C7C350DE165DA67C1CBEF5171E61D -:100AA000D1790DD9B9039297EEC39BE738ECAF49E2 -:100AB00037139DB764150B3B80AFDBFCCE1740337B -:100AC000D9F74BC57DACA32E687C38C8CF752A2DCD -:100AD00072EB3B39D5B76459FC63F35CC7FCAE9449 -:100AE00049CF977B836985D3A1EDBB5143794C09ED -:100AF000CA6352B256E8888F2E7C3587EC9EAE2CA6 -:100B0000F49F03FCBCCAF7F4A35D97E843FBB7E985 -:100B1000AAC7BA67B0BAFFEBBF4ED2A07A0EE12DDA -:100B200024F6AD5AEC9B099FBF9C3FB7EC1F8F9FEB -:100B30009589F899D8C791F484B98FE6BEA11D852F -:100B4000F4EB2B53FF9CE9F7FAE050D500F2692251 -:100B5000AA520E5D427AAD83BEC705FA4E3C7FBFF6 -:100B6000A2C565FB9DA604DED3C7F61B7DC22F89F7 -:100B700051FFE5F9BC3F9471BB7190EE93ACBF257A -:100B80000F08BCE131B86FFDAC2FE689B1F1C6A00A -:100B9000BE872ECB3C25C3E71D713C473F65F0DC8B -:100BA00024168B59E4F5BE2C6EDFBE17ADEA9533E3 -:100BB000C45FCC72B937B748B5E4871DCBF736664A -:100BC000FA7EA939DEE0F7E506EDC481A70ECD1B5C -:100BD000B2133777BC65B713936F7D213BB1FFB676 -:100BE000B79E6A67FDFFF43B0FE9ABF7EAFCB40F71 -:100BF000B92DE7C17FE07D5B157F0390EC7BFA3E6A -:100C00008EB7A590D623A90C73F83B627A4C427C30 -:100C1000BF891FF3C5B88A0EE910032E578D498886 -:100C2000AFDB853FCAE86C8AF53BAE6F66713BC3AC -:100C30009CC7E38524DE3336C76574D04679A5F5B5 -:100C4000407AC43C8735F9D91CE74496DD0F3E0D48 -:100C5000FE3D91897F9F959BFFFD16B45F9F5128B4 -:100C60001FF46FA337D1F34B5BAEA4F2B2966BF9CE -:100C7000BC62BE6F4A8993384E5FE3AFFFF64646CB -:100C8000AFABF77AE85ED9CA6FBE792BF2A7B7850A -:100C9000ED3B6BFFBFCC8E383800800000000000B9 -:100CA0001F8B080000000000000BE57D0B7C54C585 -:100CB000B9F89C3DFB4AB2BBD9DDBC96BC38E11902 -:100CC00025C44D801010EB86575109049F51026CCA -:100CD0000884008104A4BAAD1436246040ACF155F8 -:100CE000F1AA7451ACB657BD4169E5B6D16E442D39 -:100CF000540AB1BED00A06A516154DE45156ABE50F -:100D0000CEF7CD4C72CEC92E84DAFBFBF7FEFEF196 -:100D1000D77ECC9939F3F8DEF3CD37676F5C587521 -:100D2000FF986442CC430D4E8910D29C45CA5B6D3E -:100D3000B4DC209501DCA898A7EDA4B0CE5132D246 -:100D4000398690B3F0773994276399781C0652441A -:100D5000C84A2BFDB742C89943B77BE6D3FEE26D84 -:100D6000362F7D42FBC9B9CB40CB64AF4C1EA740A8 -:100D70004E20F3CAF228B43038D069242405A001EB -:100D8000611A40DAAF3542679304EDBCDE7A3ABEB1 -:100D9000D518244E8011233E374B747E79BDF31154 -:100DA00050F4678DC8848C82F1F4EF9BF139AC0B61 -:100DB000DE9793D83CC4FBB9F0FE1880621E096C24 -:100DC0001E49FA7E1CECB94CEA014FFA7934254EE3 -:100DD000CA73A6009E7C230112D2692AB31332D7AC -:100DE000F68783523E85565B58A690044CC73B73EA -:100DF00009FE9D1D04FF5FE1FC78042112E994CEF9 -:100E0000D2A1677C23850752FCC595C8A17539140A -:100E10004ACED2D1A369B3129317F0D93124D93E67 -:100E20004835FEE540453AEFD78D4E3BCCB36C8A52 -:100E30005C16CAC3EE53AE857EA654156D62C359C7 -:100E4000492A21F3D8BFC9EBCAF6E641B43E1834AB -:100E50007987523ACEB3064330BF79C418ECB462F6 -:100E600013E9AC84503116F1F7E87CE74D967D71BB -:100E70000E4D3B7296CE9334919787D0FEE74A7C15 -:100E800080202DD3F70EF3E207934F5E07CBE824C3 -:100E90004EF320DA7E6E67E574928F5536E0A785B3 -:100EA000BCDDBC80E9684FBFF47F95416D797E71F0 -:100EB000C1AB940C142FA169A381CF2E32209F5572 -:100EC000356BDB2D7CFF8A4F8803FA351EEDC13769 -:100ED000CC93DCCDF8654AA353A1781AED54B03C0D -:100EE00063F24793092DCF24E43AE877E664D919F1 -:100EF000A6AD37070CC44727BEDF278724BAB6FD47 -:100F0000B99D7B2F07BC159B94C761ADB9E4CE6B2F -:100F100092A17E9413F05C06CF06607B42A09DC731 -:100F20001A1A4A9F75F83EB255A9F86E7FF1471715 -:100F3000F929BDB61A484D347E22A401E9FAF28F90 -:100F4000E2B19F0FEE9342163AFF29F2377F1C4B16 -:100F5000E753F56393D7A2E0B20C40D7E95E268F42 -:100F600084F86C53283EE71256FE88941585E9F8FC -:100F70005505874A2CB49FAAF512CAA9C03FC5F7E8 -:100F8000876ABCF9EBCB12C30AE25DF39C76660676 -:100F90007EA678FE30069E3F54E339F0FEBB235F09 -:100FA00056B5BBDB694F063E2785A4F02C45CD69BD -:100FB00032217114E9BB6E01CFAC3D38F2E5A1845A -:100FC000DC477C5B50EF904E63D9484A2723F145BC -:100FD000D303A50E260753E4E3489F13C5B202F8D6 -:100FE000DA1FF8D446398CECFF469E0678263E4A36 -:100FF000EC71BDEF3DE334E37B5BCDC40778DE9A53 -:101000006E0D35D0AEDA7F74715A27D247796002FF -:10101000D0F10F26F2B8127BBEF6804C8650C62C5B -:101020000D480805FD0606E28871944A5F91E8F3D1 -:10103000FF1DC8319D5ACA6A6250E8B8AE20F185DA -:10104000A2F08568B7CCDA3DD548B07DD845E7B782 -:101050005C318424BADE0289F1B3D554EFCBA04DC4 -:101060008D6DB3821904E621E33C143A3F239D5F62 -:101070004E2001CB8302490807075C08870432B081 -:101080007E686030C261811C7C3E3C3002CBB981FD -:1010900051082F0A1420BC387029C2118149D82E5A -:1010A0002F50827064E02A7C9E1FB806E12581598A -:1010B00008BD81D9585F10A8425818A8C4E7A302F8 -:1010C0004BB13C3A703396C70456202C0ADC86702C -:1010D0006CA0116171A001DB8D0BDC81E5F1817BDE -:1010E000115E1AB81BE184C043580F0A08F010CFF4 -:1010F000E5F10E6581934A0A70B8027C1C4BEEFE46 -:10110000C1ED52B5D3F731F09D68673610BFBABD57 -:1011100068F735B71B2EA06B94FE4E73FDFC85F768 -:10112000C39F0E27BD746BF6349411B9975E969DDC -:1011300025E10CFACFE5BB6611D00B243759C3A7C4 -:101140007DF5035BDF5FB8FEDA6AECF0C9C0BFF57E -:10115000C41BA48F4A47BF2E413FDB14E3B4501495 -:101160007ECB7799705EA39D7E938BC2849CA32FC8 -:10117000833E991974FE7122F04B5EF21F26D2FE57 -:101180000636196004AA4A9CED13A9DE512613D431 -:101190008BDB084179DA16AFB5A7C35C0C1F84B4AA -:1011A000EE1984F234A490D99FCE2B40BECC3F1AC6 -:1011B0004436E580BC852523ED2FB89290C785CDB8 -:1011C00080F61BE6FF1CEA7BFB33337FA199BC64EE -:1011D000A513C9695126C65138788BEFA538FACACC -:1011E000D0907F623C2D0F7F32F812C08B5A431390 -:1011F00013281CB12BFC1235A76464B873A28D961A -:101200002FD94376035A0B3A9449765A1E75D0B7B4 -:101210009BB20119D3E99FE450603EA146079DCFE0 -:10122000D6C3C4DB40CBC5C75BE444A2A2BF99F8D8 -:1012300077A8E8621FDD313989FE337395B34086A4 -:10124000F78D9D71AEBCBEF4D906EB8675523BF2AC -:10125000385D57A62F2C39557C72B54B1274280275 -:101260003ACC58DD6D84756E6B72DB917EF1CE12D7 -:1012700018B27B0A713EAA001F1B114FE6F583507E -:10128000DE05DF51FC5E34CBAEC69B24F45A4D6BB9 -:101290005E6CFC5EFD6F86DF23C06D6362E3D70A80 -:1012A000BC32EEFC725CE5EA91E379AE31B1DB353C -:1012B000BB983ED5E3799B81ECA1B68A8E4BF9941D -:1012C000C91509D2A68D9CBFCF87D71FBB985DF9E2 -:1012D00077C1EB4D2EA62762E19528C9A82729BF23 -:1012E0005E4406C7D637D05F34FB758FAB8F9E3315 -:1012F00083BFD8ECA47A6E706C3D37D7C5E81D5318 -:101300007F713D63E67A5C8CF7334EB7038EB2474C -:1013100080BEB6F58620C85909B1A35C104F32E7EC -:1013200013673CF0C974D95902FA860C27E847279D -:10133000E48582B04F1918540A6568064A19F09876 -:101340009E1BDA44BBCEA17E8691D29F761506689D -:10135000559C86F974DD8942DE9C951EB5BC097BDF -:10136000DF2B8F822FDCDB36E5307E9D45FD97C37A -:101370007CDEBDFD48D86EC30FD3B76D52E9C16D99 -:101380001E0F9645FB58FCFB8DE0DFA675C40FF2DF -:101390003121BADF70D02573BEEDF6019F07BF473C -:1013A0009CE0CFB89A3E44FDE4A2FA4942FDC4C68F -:1013B000CF0CC4FF3C48CBEFB852B17FC0E3F5F689 -:1013C000FF77FCFC948B30799AE06C9769FD406A5A -:1013D000871490D30974EEA3015F66A4BB42181D65 -:1013E000950924047E2FC55BD800FAD7600F819D34 -:1013F000319B5B7C20CFC4ECC2F51F70F83F769D1B -:1014000043DF3813940220EA99BBFF3ECD46F96FC3 -:10141000438E331ECAA76879B3878EEBEE24BCDCFB -:101420006C43F9A17FE948C530DD1B807D14659FC1 -:1014300015DA0FEA2907A1BC157C92F1B47FD7D742 -:101440007B9A2862CA5DBED3301FCAD76700FA866E -:10145000D30DEAE05E7E3E9F3F20E4B3579E9C059D -:10146000429E2AF3501F4AEE94DEFE62F937BFE532 -:10147000FAD3ED6630967F23F8FE82FD1B3E5FE2D5 -:1014800056CEE9BFC4ED7D63CB765A5EE99195A354 -:10149000D4BFB3A7BFDD61A4652BF5373FA2658339 -:1014A000B5C308ED4AA984DA28BE7DD4C983FD8777 -:1014B00075342BC31FEC3F4EB448D398BE5612AFC1 -:1014C0001D792E3C86703D2B3D661C2F6EE89044A6 -:1014D000902B07E72B62944260C71DC54EE37CEC5E -:1014E000AF935C4DFBBBC4CDEC82906BD05BCFE681 -:1014F000815E721B61BF6EB192A0DDDDDB3F941394 -:101500000B7BF513E1FBB89BF99EA9659D3771082C -:10151000C8E97E16476959C3E4B2349384D6819EE4 -:10152000F011C549DBC711F1470597964DBC34FD55 -:101530006B89F8E8FCF77D2D23948690B09DEEF73B -:101540004ABD5218F68166833504B6B424DD4ACC10 -:101550005076184216908F0F255CA7B9302104CA27 -:101560006F727A7162275DC7C97DBB6DFE28F4BFBB -:10157000C15FE99D3C2A361E7BDACD79C509787CAE -:10158000486972821F19F41831EEB0119AAAF4FA60 -:101590005C37F347A83F540E7C3A6341779319E8D0 -:1015A0009D938CFE1019E246BE1DE0D9B9B1044CE2 -:1015B000562DF34FD349A841ED5709FEEA74FBE7D6 -:1015C000BBE93C1EE276848A65C73088575D94EC9F -:1015D00006BFB4A42EBD0DFCDD07D712EF0213EA3F -:1015E00083EB605C5F526B01F0EF43DE9DBFB80B95 -:1015F000F069A1FB62D0E3A30ED9144AAF8A31BBD4 -:1016000053603D7FD4CD5FC08AC01AC48B7E1FBC9F -:10161000D2CDF7C1F9241FF6C127BDD7248691B7D3 -:1016200092A2CA7745E036EC47EC87DF3785B39C5A -:1016300051E5508B6F317E85C4F6B5C42431FDC7AA -:10164000ED28D52F4DA8074204EDA6CF223D0AF67E -:10165000E6A4779417EC762C7D23E643F138B4CCDE -:101660001EA55E2265D1F4C45637F30F2A4C74BF11 -:1016700040EBA51563EA615E15769B047C27DA6D65 -:10168000E2ED043F8B78959CF8CD18A03FC407A3EA -:10169000AD7F1E319E52C7A33681ACA5307C79A3A5 -:1016A000F82BB1F075D0D4520AF33AB850260DB4E5 -:1016B0009F93FEB16924CAFB02BE077C43E9B22AAC -:1016C000898DD743CF21D1F177706D8D77B2A997EE -:1016D0009E7DEA2BE3CAC17E97031E55E31E70333D -:1016E0003B7F8C4362F12B4E5A6F9E7FBF938C04DD -:1016F0003D756A4CD00E71B1EE5F3500BD7F6CC791 -:10170000784579E5E9310D2355F82C266824E7ED75 -:101710007ED0A9D0E7E5439B5282B6D8783C0678C4 -:10172000A478BA031E8CC378CC1FDC17108F2179E4 -:101730006EE437B23BCE1B8678E45BB217FC06182A -:10174000D78FFA93C5935739D9BCE2747E5E79601E -:10175000B946BF244424124A52958DAD189F4D8836 -:1017600018F1B95EDE9ED2C99BC07F2C7A0AFCEBD1 -:101770009FFF9EF3E5C1CAC50AC40DCDF1D1FDE0BE -:10178000EC2449C3576FAFF56BC67BE75B59B35F7A -:1017900016F0EFBCFF93FE716910AF2A370787F68A -:1017A00047CE057EDEFEE60127F41BF79525AAFC51 -:1017B0009DE2F689DAD3E6EB14953DBD516E02BC8D -:1017C0002718B97ED3C99D0FEC2AC5E7E56057E914 -:1017D0001413CE6357E791603BC491F5E30B7BAAEA -:1017E000E72F615FF574137CE049A2F44BE8A59FF5 -:1017F000881BC6922F21579D5CFEF5F8D7C31BCCE2 -:101800005ABF47C0CFB99C9DF4C79120D58F379759 -:10181000C82122217FA07D3C78BF84FE66B8D28299 -:1018200076B9AA320EE3B3550532D657DD29A3FDAA -:101830000C53FD504BE7F347AE27F4F1D912227950 -:1018400027ABD63D63749CA67CE3C27BFFB816E24F -:10185000CBC52605C6DBAFB07873D027A3FF4AFB04 -:10186000F086213E7DDF655EB067821FF6FB6494E3 -:10187000B7E09BB21786EDE0F1E8FDCD052119E850 -:101880002CF97BC6510643FF550AD0E15DCF1627E0 -:10189000E8BBB86F1F282BC3FDA35F2940BB499D40 -:1018A000553AEF382EA793D28BAF073BFEC1661394 -:1018B00081B8D107AB4FA23C77AEADF74E1EDA1B15 -:1018C0005F16F1617D9C591F5FEE1357D6C59305D6 -:1018D0003FE8F9A422067F087D158B3FA81EAB4A7E -:1018E0004AB9703D26F4C77B7C9D93D2B7DCD940C2 -:1018F000F190B040463C08BE7CF79BDB1F013D1CCD -:1019000047F9631DF0F3B74FBC02FB10B2588A1AB7 -:1019100047DEDE63F7285D727BE972A37F714F19A2 -:10192000C47F76CD8A9E32AC5F6F5762EBB573EBA6 -:10193000AD61492C5EA1B73B7A79F857DB9DF2CABD -:10194000FB73E1FDF2CA8521801BD3AD35A07FF585 -:101950007A426F27C47CF4F34C88C824344A3D6F24 -:1019600005DBF5DA0933D607AC8E7C70D6CFC431EF -:1019700018042710FCD2C371A1461CAFFE92329C02 -:101980007FFD588001E2ED0CC2FA3CF1183F68C9B6 -:1019900064EDE52BE2993F3EDA8DEB9485437ECAF8 -:1019A00085E546BE86516EFF734914BF8D3E431CCC -:1019B0009C2B4CB21BF742C8A565A28158482F9EAC -:1019C00084FF4E203240D78B7512EC3B0BACE6C146 -:1019D000E89FFE16FA216BE8BE90F2FBBE7DF2CEC8 -:1019E0006D7489FBBCA312A3F9E702CEF1FC10F5DC -:1019F000C2F5812A84877EF04E36C8EB2D92FF55C2 -:101A000090838EF2AA3BE15CB86E978CE74A736EC6 -:101A1000797718DBA769CF2765873517E2288D52BC -:101A2000BC17F488C063BBDD8CFAA5F110D3838D9D -:101A300047245E66FB889779FDC9F7EDB8CF10782B -:101A4000A7EB790BC6F7DDEBC2F5887DC677584F5B -:101A500027E027F67A329DA82F80AFE4DEF9CB7617 -:101A600023AEAB8BC47B61FE011E0F22EFC7A1DF4B -:101A70002CE85BC7F94FD07739A76F57DBE99F5C3C -:101A80004ADBB7F8DC78CA2067115C6FD7FB09C85E -:101A90001F62BD940F4EC1FC76B7313BD172D8CED8 -:101AA000F0652FCA85F909FFDA99C4FC64FDBA2BE9 -:101AB000C43E9DFB19E0DF429C62917BE2D9A431D8 -:101AC00051DA73BF96E2D9904CEB4B9CE45488F406 -:101AD000E2598C23C615EF3992B57E4C058F2BBC8D -:101AE0006F22E5104F84710B55F35BE32E7124A731 -:101AF000F41DF73BD07140F239F9524BC73AA3AD10 -:101B0000594A243DFB620CA5297DE55C2F67525B99 -:101B1000FB57703EAF97FF33867A22D17E6F95FDDB -:101B200007DD1436FA49A765705F79389F1EA1F466 -:101B30002E484EE9AB4FFA4BE709C952CF3E86D348 -:101B400079427214BD27F03DDC5DF63DA887F5674C -:101B500014E23ECF0774073D611E84E3215F76BB2C -:101B600048E851DA2889C751C47C202E1147DF9BF1 -:101B7000999C83E34A461234D17252AE5702BDDFBC -:101B80000F3E98F92FE6839B92CF29CF61F44B96B5 -:101B9000717A2F1379163BCF9D67D10FBAD5C03A12 -:101BA000CE18BCDDFE9C0BA7DBCDC97DE4F3E6E4DB -:101BB00073C8E770B7FF1618AFD14C4EA11F5E5C1B -:101BC000E981F10E387C9F24D2E72F36707D924355 -:101BD000E946EB5F4996515FDD432E463DFC3D8370 -:101BE00001E7DF45F5EFA339D1F83E6874D3F7CFAD -:101BF0005C4DF03C8EAE6F3DE3CBA004CF6F9D47B4 -:101C00000CF0DCA33410C305E8A196BEFCD9722EFB -:101C1000FEA47AE85EA8A7FCB80AF8D1AA388DE736 -:101C2000D2433F4BD6DAF97EF0DFCFD478FE17F0FF -:101C3000DF2FCFCD7F17CC57CF45D307828FC5BEBF -:101C40002056BE10954792E1EE3B2E215E3C0F2BB5 -:101C5000715899DDDD21A19D6D3C52E0C7B2DD8A4E -:101C60004A41D8E1133B59BD3C31BA3FD896EC66A6 -:101C70007906AD2BBC464D1E48109FDFE53BE11CAD -:101C800042F5E254D986EB4B2A65F143B17EAA674F -:101C9000A74F49E57153BA9EA42C868724EA0FC04A -:101CA000399A83EF0F128B8D1ABF5FE0ED56B94C56 -:101CB00082B8B72B9940DA0DF5EB570F87F37B9776 -:101CC0004FDB3E856CFE52C64108CA839BDA6F88A3 -:101CD00063254DD3B5837D483EB4573DCFE9BB9FC7 -:101CE000F83899EF27CCC4037685C815E7E41BD5EF -:101CF0007EE2F3E47EC4454E261BF8798AD67EB593 -:101D0000C691A871818614BE2F38E542FF57E6764A -:101D10006B72670EE6A7ACB42B182F9065AF757A7F -:101D20004EDFF75D3E035154EB4B9A164F14D5FE30 -:101D300021A5CCAD29A795A76BDA0FF00FD2D467F8 -:101D4000D45CACA9CFAA2FD4940706C66BDAE750AF -:101D500001509707375FA9693FB4E56A4D79F89656 -:101D60009B34ED2F0ACDD7D48F787289A67E64EB91 -:101D70004A4DF9925D3FD2B46FE4715F3D5E2673C8 -:101D8000BC361A99DE69B015623CB2D1A68D4766A1 -:101D9000F37625891372210EDEF861412EE0FB6592 -:101DA000C7788C8BC7E20BBD1E8BA53FF5CF2F4BA1 -:101DB00061FAEE8B97CC069083E5BBA9BC5E42CB63 -:101DC000B6F736C09A9AF3D879AA91B0FC1E71BEC4 -:101DD00022DEEF395F317A597CD561239BA2F04531 -:101DE000768A1235FE29F82816DE1AFA89B7297C78 -:101DF0001DDF156FEF4B2C3F55ADFF774499D79AF8 -:101E00001416DFA2F6655E0AF37746C7A327EE44F1 -:101E100079BC50FD2FE641F5FF9214F443DF98732F -:101E20002BE8FF9D162FECC9BE287FA3FA0105DA27 -:101E300057B3F6066F2ED02556FC7B4D4A9FF87798 -:101E40000D8B7FC76BF0562BE45D17876B747C8D11 -:101E5000F1EF46B337B73FF1EF5AD031294007C60B -:101E60001F3DF4E5F1F358FBA000217B25D8F7D8FE -:101E70008C0A9C739D6F5F4BF7B3B9709EDA02FBBF -:101E800026D53E87EE6FF9FE260EED02B57BF7A64E -:101E9000A0DE237B15FAFC0CDDF76E52A028EC9F28 -:101EA0004FE3975B88D76A96919E0FA6E07E97AC2A -:101EB0008A93215E16DE3721E73BD9F3ED291760BF -:101EC000CFC9F9CFE5D0EE94D2F5AF8BE277E9CF69 -:101ED000E17AFC6FF0D3243C8F433CADA77611CE62 -:101EE000E3DA53987D5E7F88ED93D71F99E541B97A -:101EF00049293AE7395C7FF5CDAB297DFCD25753B0 -:101F0000CEE1978AF5AFE4FBDE29725E2BC41B4F4E -:101F100044CC883799B0FCC8BA3D2612427AB23C0C -:101F200063414753644307D86713D1E7152B89B042 -:101F30006ED31E19F5134966F541626D003F27B156 -:101F4000586BB75C3EADDD4A9AE6D6D931ADDD4A75 -:101F50002BD7DAAD017EADDDCAA829D4D931ADDDEC -:101F60001A1898A8B3635ABB35B8F96A9D1DD3DA1D -:101F7000ADE15BB476EBA290D66E8D7872A5CE8E75 -:101F800069EDD625BBD669EA0BC29B34F5A3F6DC16 -:101F9000A3298FE9F80F4DFB457B9FC3FC9BB1073D -:101FA0001FD5B41BD7F94B4D3B8AF00EC8D35E80CA -:101FB0002421E4D263CF6AEA17703FEDB2EEDF6806 -:101FC000FA212D2CDF3A48FF037AFD95F8CDE09CED -:101FD0001849F7AB1994AECB4392374C9B2DDEB525 -:101FE000A308E6F1D9E12BF6403F8BB668F3B417AE -:101FF00087B4E53A322811F4431DE58B10E593A52B -:1020000090BFADD26B4B49BD03F321FAC9678BF684 -:102010005E4330EF33E8EB80FC74B14EC16F3ECECF -:102020006F627E62BD4BA9DF17567AD7E9A3FFB175 -:102030007D64A719F8B67A9744FE43EABB9E9AB628 -:10204000BB37644459977E1D7ABF734CAA368E3DC8 -:1020500045B6615CFFC49BB297C507B572B8722FD5 -:102060008BE7AF7C5AC2F89A1E1FC22F8D85173995 -:10207000C8F60975C9241452C99FC2F161F168E517 -:10208000EF04FC03E6F3B01C82BCA038255ECF6FE2 -:102090004561D217CF09B95A39D5E3D9EE4D8FCA68 -:1020A000570AFD0FE6514DD8B9949EAFF4785FBE44 -:1020B000EB6E33E8C50BC5FB8254EDF9A0383F2821 -:1020C000A1AB3547C9831378A5FBF225A929B1F740 -:1020D000ADB7A45EF0BEF596D47FEDBEB521F51C7C -:1020E000F1B32E889751BF521F2FEB1B1FDBFD95BD -:1020F000E4C038348B7FF9BD5696AFA2B393B91EB6 -:102100008D9DECD9F77E28851A69E7F50E5F0BAC3B -:102110006F85C37737C0990EDF3DA92AFC3452BCC6 -:10212000E0FD1C6AA77644F10FF7A50ABFA80CE3EF -:1021300022EB4B587B7DBB5FA7B2FB40ED29451ED0 -:10214000F43B8F1430FB692F3AA7DF79173FCFB9E3 -:1021500003CE0B87F6E6F1DCC9CF55A8D8F9806E1F -:10216000EB4D651E759EEF83A92E1CCF31EED90E67 -:10217000C8776E741A9C9202FEB301CF459B7CB661 -:10218000693BF3D87BC99AF7D8BD2319F00DFEBC83 -:10219000CDF8B59A6FF7515C42BFB1D6B92F95F91A -:1021A000BB26E2B382DE15E7B9A60F0BACA06F8D9C -:1021B00092D7192D8FD3C4F3A426F2F35CD9C9CEDC -:1021C000777BE4FC3C7952373BFCAFA9F9549CEB9C -:1021D000CE76F8F6C1F380316801FF32608DBEFF24 -:1021E000FD13A7E35DB03EA4A70DF908C797FB1543 -:1021F0003FF9732AC6E58298AF78ABEC3D06F1B99A -:10220000FEC6AB3E4EED13AFFA58CD877AF9A3FE6A -:10221000E72789908797986EC4ED84D19B0BFCDFEC -:102220000CFF1E87F1D5CF61DD7DF24F1537CFA7AB -:1022300055CE994F2BFA2977F94EA5B2BCBFBFA551 -:10224000B2BCBF2659D58FE33CFD503CE5D6DBFA46 -:10225000853F396D0CC6358FB160C285C5351D69A6 -:102260007DFC4747DA39FCC733878627C279B288B5 -:102270005BE9DB59034999EAFB31CD2EEDF81B0AE6 -:102280005979001F777922E3FB91698C8E220F50D8 -:10229000C4ADADD3890FEE3BDCC3F3B3453F23D3CD -:1022A000ECD83ED53D71645A0A9CA749B8AFDCE032 -:1022B0009234FBCB4F524B46C27A86F3FE47A6318F -:1022C0003EDD3688C567F479902778FB13A9131192 -:1022D00052825D04F834CB72543C16A6B1F97F9259 -:1022E000C8E45BC4CFAAEE67F7BB44DC4CC4010969 -:1022F000F1BE9D40F5CA479B4D04E25A0B65DB06D3 -:10230000E0C39EFB73FC5CDD49FF037B5999578654 -:10231000F947DFF5FE16E033C1DDD75E5E99D6E3FF -:10232000A7782FF01ED7ACB40B386FEF8C677CDB2F -:102330006DB7613C5BDF6E29E787CD3C4E01FA1A31 -:10234000EC865B26F5D1ECC7528EF733872C3EF432 -:1023500063A6C5633E8738FF3052FE4C74631A781B -:1023600010A035909109F7897ACE3F1482EF25D9D4 -:102370006CF89E5121613B5C09357A25C82FEB34FE -:1023800077AE4F83F95E2679E1FE405A85B33D2D45 -:1023900019EE112A28661B7288A318EA0B0C58EF55 -:1023A000BAD6B9C10479D70A81936C62A2E3D8E99D -:1023B00038F7A6E5B07505AF694FA3ED12956E32FB -:1023C000280FF48873AA07E4B89CE5AFEBD7D7C40D -:1023D000F9D5B69EEE1B001F4AF43CF0A63483C824 -:1023E0009B6F047E2D51C84E762F8AE5A1429A3507 -:1023F000E60B7A59BE7402E41B0D667A06EA7FEAA0 -:102400009AB411DE13F225737C03DFABF3E1EFE541 -:10241000E324E9E453E0930ED000F910C6E904F98F -:102420007A6645F4F93EC3E9BCCA51F620F0CFCC38 -:10243000090D98E74EBE397B562E02A797C9097D34 -:102440009F401C222E99E9DF3845417D4C9C12E6C5 -:10245000995A156F0D94E36CE39D32D83D0B3F2FD5 -:102460005C6020462A6F93783FBE72227D9CCBE24F -:10247000AC4CBF1AC9C7422E648E9C22B09FEC8F11 -:10248000FA459B13E87A26D9F6E13962DC90FA1214 -:10249000B857F0CA3CD6C73D31F2F63FE17ACC2DB1 -:1024A000FB3D06F0E9837F79EDE50948E78BE1869E -:1024B000E61DA6CED7F65CC6E3E7982FDEF99A2F85 -:1024C000EF9FCF2F7F2DADF3B5A6BCEFC2FF5E0906 -:1024D000F4F82794B160DE7AFE17FAECA0EC3F78AE -:1024E0001BC5FF7594A90285008DA402E9CDF28772 -:1024F000AEE5780E7E4DF16CEDC5F3756D7B117F09 -:10250000074D74DE747CD344866AD38F12793E46BD -:1025100008C7BDDEDA3205FC9B2E73773E8CDBF5F7 -:10252000C23B5941AA4F0EFDF8A49D50FEFBC0D8F6 -:102530006D87E7C756BF61F751BC1F5A2DE3FD37C2 -:10254000BC97ACCA07FA9CCBCB959EB2A3C057F3FD -:10255000D67E5BA4F6B3492005EDEEE2900C777CC5 -:102560007BF4DFD2271338D3B1F2B2D6244D59D839 -:10257000E36596E8F7C40779985C2C7E6A9B19F2AC -:10258000E1AFF4F8FF06E31FE3F906C776DA717FDF -:1025900025E633FFA90233EC273F68B39030F0BD46 -:1025A000B1C344304EE59B2E51BEF5733ED4CFF3FC -:1025B000D51713B0BF85F7CB1847AAA46305285ECB -:1025C000FD6D8BD9FE56B78E858794A9A0AF166E88 -:1025D00094485061ED5753BAF903B7E3F98A7E9DE9 -:1025E0007AFB729AAC36831ED1DB9705C4DB3C01C3 -:1025F000EC568BF6F9A2B63BB0DF45E7398FF178A0 -:10260000F8FEAC888C3D3B18E2CC83305F3096BD41 -:1026100039B69609E5A76BAD088FAF75223C0ACA9B -:1026200094E279E9AEF6573350AC3B8AC00EC5ED63 -:102630009D64BD89F4FACFC66DD7841F52802FB533 -:10264000F990151CCFC27F5EC4EF199CCF7FAE807E -:10265000759E231FB2A29FF99027F68CB2C2F3F1A8 -:10266000021F63293ED0FEE61D50C8F9ED6F2CBC59 -:10267000C47A6F197CE7200A9E85DC1CE5FA7DC1CF -:10268000F6591BD2E9041A5FF86B7627F2258B43C3 -:1026900088732AD9B3A103D62F135DFC2F48DE24FB -:1026A0002AFED5F3E722E26576C7C6DEB3F2B84468 -:1026B0000F5FB6DD8978157C04370A0C1E80618FA8 -:1026C000A1B8EF7703FA7C1FA0455BFEC2D4990D39 -:1026D0007A63912E5EF085147DFF35DD3388AD5F22 -:1026E000F14D85BC8885A46C038BABB7A09E3A6680 -:1026F0006C79F53690E7ED4C9E963DFFF4AF414F77 -:102700002DF9AFFB1DA0A73E31B6A4C278B58FAF9F -:1027100077805E3F660C3AE0FD4F4272D4FBBA4FC1 -:10272000787ACE056C9017B61C590C042C3803F43B -:10273000E4DF1E3739218E5AF7A4256CA1F858BE64 -:1027400093E191968FB0F2ED88AFBA5D5A395CF2A1 -:10275000C4FDA90AEEE783191C7F19A0AA976F3759 -:1027600061FEE8F237652F0C5347BA717DFAF761C5 -:102770001E114AB7BA56B9D29CD8B79E7A3C669019 -:10278000B3BA9D8C4E753A3FB386EB653DBF3FE0D3 -:10279000E17E26E7738A178C87897C561262FAB924 -:1027A000F1170FE41FA1F33ABEFD358794D7CBEFA5 -:1027B00004B22EC12F6FAD9A077906B1F8FC0B2E2B -:1027C000173D7A9FDB1965179D18F8FE6D0CD69A98 -:1027D000C28E4B293E6AB799BC41FAB8F669D967EF -:1027E000033FE95D0B7EDF61E9D3AFBC3D9ECE6F59 -:1027F000E90E53F274B60C1BE86741A73AE0EFC24A -:102800005EBA2C79EE1533E441C2F3D5EE5EFA2CB4 -:10281000DDD16E86BC4A3D1E27B5B69B997CE9E8A2 -:10282000D47A642AD8E5C65F9C31031F7CF2A244A7 -:10283000C085D4BF5FB3ED1507E80FC013D80F41B3 -:10284000AF1EFAF5A15B78C66F46633B279CD3C4E5 -:10285000A25F00E63206F9FB99DFD0F16BDEB378B8 -:1028600061FD35CFDCEC8075FCD558CFF8FC91F5D7 -:10287000A9608F6B4CC1542742F6BC66EB0F90FFEA -:1028800016BDFE8354827AD33700E497AE7300AC52 -:102890006FE1C3D7E1FAAA891FF9AFE611B90CFCC1 -:1028A000C4D346322D9A9FAF0C60FAE9AF8F5A70AD -:1028B00053F0573361DFE1F893CCF2F8C80AF443E0 -:1028C0007EC0D74A3531964F5B199D4E79C4FD7550 -:1028D000A6C7EA78ABBAEDB7A31EFB34CB9706F2D6 -:1028E0004EF1A08DA7BE3E258DEB3FFC5E0ABE4794 -:1028F000F96E123C87F61D265F5CBEE63D9ED7CA88 -:10290000C65FC5C7A7F38E87B8DC5F53B5FB570119 -:10291000670C107A807410357FC592FBED1B91AF68 -:102920004EBDC9F4CAF2D0AC6958DF610AA7417D37 -:10293000A8FD5A09F502F52FA2C9F57613976B6D1C -:102940003D9DA75152E3F745762FAEFA3EDA4EE5AC -:1029500087F4F28DB9F7794EAF7C8AFC8A453AFF4D -:102960004C40BD5E481FA0B57FE27DF2704AD47B2B -:1029700058BDFA20887C516B0AFDFC3F408EDFB5C4 -:10298000E03DC3DAA74DF8BD9CCF9EDAFDF64D942D -:10299000DF3F6B15F2ABD5B37AF9AD79F63A124D4C -:1029A0007E3F4B2E2351E5973E8F2ABFC92C7FFFD8 -:1029B0007F5BCF2E8AA167270FD0EA59EA4F245EAA -:1029C0004A8B9FFE72E940DC67E9F02AF0A9D79BA9 -:1029D000873C0AE257AF37E9DF9B448547813FC117 -:1029E000974BFE73198ED3C3BF823F05FFF6F0A746 -:1029F0007EBD5A3CEAEBE3E0CE514A2FDD4DEBE8D9 -:102A0000FE1ACE5D5F90F1DCB54BE976B8212ECB96 -:102A1000F36EBA9CBCEC62E5EE14F306D01FE279CB -:102A2000771CCB43E82AEB76B8547EFD9136D9016A -:102A300079F59DA1E8F91298499102B74463D53719 -:102A4000F0EFD6D8B203B02F6B61E73D0B1A6E7072 -:102A5000803FDDD536786639F8F17B65F4A9BAE2B6 -:102A6000797E55D0671C40F15AC5964C8E91E04F47 -:102A7000C1CFAE6A5B3A1D368D0B366BF1516DBB23 -:102A800016CFB3AAEF33F5F205017F2764063FABFB -:102A9000E661EDF325905705F4D1F1911FF828CAAE -:102AA0003D8C3B051F159002B64FE6E7555CAF4DD8 -:102AB00091F3669643FEE21E764FE2449B4C36C08D -:102AC0007A9FE2E757C114E4CFE5948FD571CEE346 -:102AD000C067C363DBEFE3BF3A54741B6D52FBEB7B -:102AE0003FE73F44E1F15FBF3BECB7507EFE9DEC1A -:102AF0003F93BEED27BDF8D55CCCA37CD142605F8F -:102B0000D4F5E2EFB36F83F26F2C5E9867D73AB6D5 -:102B10003F0EBE6847BBDE95C5FCBFC617CEE47747 -:102B2000A27D6A427AED1AC0EEA99E68FBFB61099C -:102B3000F2E9DAE8AAC0EEF27D57DD6FE2707FDDE0 -:102B4000F5C219CDBEF2BBAE6739BFAFD46527E57C -:102B500070BFB8CBC5EE77D6FD76DC63705F71D9F8 -:102B6000CE767315AD9FF4BB6FF341DF743DCBFCA4 -:102B700009EADF6E05977AF780039B4D14CF5F80DB -:102B8000CF974EF71FE989A5700FA32F5E181EBAC5 -:102B9000281E605D142F35A02763E1E3BD01ECFE24 -:102BA000C8BF1F3EBE9C0BE3D7B68D25104FEFC5A7 -:102BB0008BE463CFED987741D7CF9EBF78261FFC7B -:102BC000A3F3AD37F2FFD97A53D3FF5DD7CBF87DAE -:102BD000EB00667FF47CDF97AF9FBF05CBCFD8BDFE -:102BE00038DF7ECA7B51FABFABBCFFEFD0FBDAFF08 -:102BF000B3F4DECBE96D77C2794AD70BDF66930B6E -:102C000058F7CDFF47D7DDE3E718BCD6D1747EEF88 -:102C100091D0752552EC3CCE50BA761F3183FB1112 -:102C20003392ABD17F98E163F1954652B807EEA994 -:102C3000057D329E3B60320DC543C7B50521CCDB17 -:102C4000320687FE14F2B8AE5FE665DFF9D2EEAF6A -:102C500066A44E9B06FEDBFE063A2FDA6EBFDDE071 -:102C60006CA44B98E993D1DFA310FDBCB7265E8519 -:102C70007921338BB5FB8C9B74FB861BCAB5F5D7CA -:102C800093475320FFEEFA1A13E60B5DA76BBF269E -:102C9000DD89EBBC81D4AF67F1990BC353473ADBB5 -:102CA0004FF6C5C3B9F1D6074F7C3F89B93C4A5F9F -:102CB000BC59FC6C7F69A115DCDFE279722BFB85C6 -:102CC0004FC2F79D163EB4C0AFC5C7BED7A9EA171D -:102CD000F122F07EA1F81674D2E35DE057E04D4F8B -:102CE00087C7E04C42E58FF7429147E227EA7CCB69 -:102CF000193D7EA30DF178603BBBAF70A0B86A733D -:102D000001949F92D05F3B3D6114B1D2F5EE3791B3 -:102D10005DECFE974F7116F5E6B348C5BFC7730566 -:102D2000C82754EF4B219F50BD2EC8275497219F91 -:102D300050DD1EF209D5F5904FA8AE877C4275197B -:102D4000F209D5ED219F505D867C42757BC82754E2 -:102D500097219F50DD1EF209D5F5904FA8AE877CD4 -:102D6000427519F209D5ED219F505D0FF984EA7A79 -:102D7000C8275497219F50DD1EF208D5F59047A82B -:102D8000AE87BC417519F205D5ED2F8FBCA42997EC -:102D900090D734ED2759DFD094A738FFAC69FF7D79 -:102DA000CF479AFA2B94CF34F582FE57E59ED43C58 -:102DB00087338B6011EC63D85FA9F7EF9A7E8CA400 -:102DC0000CE3CC66528FD00AF15B0AE3492B421B1D -:102DD000157380570EF35F9C01FCBA35B801986BF0 -:102DE000FFB833D9A0FF0F4CB886C51FF839C14CC6 -:102DF000F8A7429938E19B4CD8D78A734F474426AD -:102E0000E151940F2312426724818493281F46E2E4 -:102E100010BA2349F83C29E242981CC9C0E729911D -:102E2000010853238311A64572107A2223100E88BD -:102E30005C84303D320ADFCB881420CC8C5C8ACF96 -:102E4000B322E310664726E1F3819112844AE42A13 -:102E50008439912B100E8A5C83ED064766211C1283 -:102E6000998DCF87466E44382C52857078A41261B4 -:102E70006E6429C28B228B115E1CB919DF1B11599C -:102E800081302F721B3E1F19F921C2FC4823C24B0F -:102E9000220D08BD913BB05D416423C2C2C8BDF89C -:102EA0007C54E46E84A3230FE1F33191071116459E -:102EB0001E433836B20D6171E43F118E8BFC02E186 -:102EC000F8C873F8DEA5911D0827447E8BCF2F8BA1 -:102ED000FC37C2EF4576E3F3CB23ED087D91D7F0C5 -:102EE0007949642FC2899137F0F9A4C8EB082747C4 -:102EF000FE8CCFA744DE453835F211C2EF478E2055 -:102F00009C16F90CE115914F105E193989EF5D158A -:102F1000F912E1F4C8DFF17969E42B843DFBFD0986 -:102F2000B1EE25FA0D6721AE6573F7EB3B5F846C5C -:102F3000D19C4B3D90E0403D397335CB23D9507245 -:102F40007232FAB52B2C0AFFBEA64EAF7E6303FF8A -:102F5000613DD40C607D401EE01CCEBF078A77A780 -:102F600080BFB4A1B0B316E22177E6745600BC2F3F -:102F700083F90D776430BB784F068B97560E73B28A -:102F80007B062B86E2F91549EEDF3ADEE4F659B40A -:102F9000BF398B976DDDD9782FA09FFDF4B7DDF990 -:102FA000F2A37E98E17F2203FD22FDFDBC7EBFFFE0 -:102FB0005FA827FEF9F79F3FD7FB1F707AA564969D -:102FC000FD16E769F4E543FDC47503E464DA4FE5F3 -:102FD00066C90976B2AAA9602AD0AF90F8309E38A7 -:102FE00027465E5727A7DFFC7A1381B8E27C85600D -:102FF0003C77FE4E96E70B71D052CA17359C2F9640 -:103000006DDC610617B4A67E11CB3F0AB1389395EB -:10301000FE07FCBC64F32CCC3F5AFAA436FE540BDA -:10302000711D19CE91B5CFEB789CA9CFB9822EBE78 -:10303000F46E068F2F7959DE11913371BDA7E97AAD -:10304000219FC37F8BDD0AFA9FE201CF49C4FA4575 -:10305000BC52E081F4BDCF8079A127F60CC53CB508 -:10306000138A9206EDFC549C3A6C90FFE01F0BCF44 -:1030700029FE309FA4BB2101F3918E507DAE40E22A -:1030800093D33F16BE9FD6F95E16E1DF6FD49E1B29 -:10309000583763FE75A5890E4CDB553E9E84F71F9D -:1030A000697FF9BB201EF9B809F3818264A58714F2 -:1030B000F73D57285B6F42FE98BFCBC5F2C382BE77 -:1030C00037215F5FD0E348D3E0A9905734BF39A7D9 -:1030D00000C36EBB4CE8E789F35241A7BE79D165C6 -:1030E00089F07DC425CDAF233D29BD34F5B59BBF07 -:1030F000C4FB03945E4763D0EBE8B9E89598A9A5B3 -:1031000017C4956F80CAD54928A715EBC243EB5564 -:10311000FCA88FD3934C1BDE7714F9C4D3D2193D8E -:1031200088D19B0A743DB9790CD24B4FA769FFA88F -:10313000427A90F7ECF8BDDD3983C9BCABE9F3798D -:103140003C6E39A7F10AF49F7333991E3BB0167297 -:103150002D09797DAD95F8A8F3FCC65A2796DF5A5C -:10316000EBC1F23B6B1584EFAECD4578D4CCF27950 -:10317000843C5106C0BCBAFC4C2647F999625FB545 -:10318000CA0371E969FF78638C0155A367C6942C63 -:10319000F4BB35791AE5D76AF3303A4D3CCF6BA3CF -:1031A000E485EFA8CC2FBB54D39EE48EEA2D83FD9B -:1031B000E07923F39B5DF8FDB61BA72769DA5FDF93 -:1031C0009CA1294FCD5410BFB3A60DD63CBFA96218 -:1031D00084A65CC97F378158E30DEAF329EA19B167 -:1031E0003C6F276B7BAA7E6CDAAD74FC53FB4C58AA -:1031F000AFA7C7517310F7E3C1472D5EB043C7E0D7 -:103200001E192D1F7B4B467D77CC44824EAABA8F68 -:1032100049A409203132793A7D90C9D3B47FC804DA -:10322000F6E1E497163CBFABDA229120DCA1EAA6D6 -:1032300098A7E3AEFA8505D7BD608B4CFC785F4953 -:10324000698573EB558F0FF7C2B9E59CC1E12CB8C6 -:10325000B7D7FDAB38EFA3B4B6AA93BD7F8CEEAF62 -:103260005D90972415E2F9C1E7A52DD506C83790E2 -:10327000F7A5809C7EFEAC8CF194C52BDE2A728271 -:103280005E7BB5F5ED623ACED11619C7FDEC49CBA0 -:103290003619E5DD9706DF75ED5D7708E30CAF794C -:1032A000CAEA32291F7C5A1DCA47BDB39AC5B7FB6B -:1032B000E287AE17E80DFCAAD263BD768B9D9351D1 -:1032C000E53300F44395C98BE7A647379BF03C8F65 -:1032D000EA7F3CFF3FDA926460FAE759E4BBF946C3 -:1032E000C5AC1E77FE66D9C77E174231C37CC9DDE7 -:1032F000B29F8C8532CB5708364B7E765EA3A5EF06 -:10330000CD2BC6E2FD627DFE94805F5099F2ABCE7C -:103310008196BCC0CE67C9E84EA33A7F5CC457888B -:1033200087F52FBEE3533BE8819F4CA0F0848F7D4F -:1033300072F0F4763BEAC7E386978A6EA5F0B3D2C3 -:10334000E0C7464A977AD9FF5026E4EF18366F95C2 -:10335000F05CE4A39FC079FCA74F9BBC28863C5F30 -:103360006BC92F170F3C577E10CC809D2F8753259C -:103370000F7C959760FEC66CD2CAE3032176FE0FE0 -:1033800093A0F871D6B273AC8FC6D837C13DDC2A92 -:10339000DDBDDD8FF8BD856732258D7D3ECECB55F9 -:1033A00006269FE445F6FD45C87B19A2B2A7429FB9 -:1033B000BE90C9F2497AEC2A6945BD52CDBF0F5C77 -:1033C000FBA485DDD3518813E47131230FF90AE49E -:1033D00099CE7789F9E99F023B2F221D68E73E3598 -:1033E00085AA3B72E0FD6D4D6E7CDFE40D81FC72C1 -:1033F0003B60A58A03F4C722C2E6B7AC450A8555EF -:10340000710AF17B1C04EC824ADFF4B5075A3BB029 -:1034100090DBBB854497EFD3A2B54B6509765CD7AB -:1034200092169EF7DC332F999CA538ABF6875E9DEC -:1034300081F396BCA128F35844BAC3F01DE0654F50 -:10344000B1FB40FA79E9D7D1DF79567B674D86EF3A -:1034500009F78CAB9BB7C037810B4A2A3A08BC5797 -:1034600007193EABDB24A4D75FB85F25EED909BAB4 -:103470002F22653340AF2DBA8FEE0B737AF9A0C7B8 -:103480005EEF08A1BFF4196971D828FFD76ED97112 -:10349000FD3878EFE1D7CDC0DF15EEF050838BEE2D -:1034A00017833FFEC9B4AC28F65D67CFFF55F821FE -:1034B0003CCE84EF517C2CDC2E635E83AA1D3FDF63 -:1034C0000F327E0E12CC23AA7953F636D2A735F0EE -:1034D000733E85173E5F819FFFED79EBFD98DC2CF5 -:1034E0009E6F10C38FD1EB973E7E8CCE7EC2BD09FE -:1034F000B097DD292C0FFC94D197E846BDACD3BB27 -:103500002985F8DD51A177ABB9DD13E32C047B47A6 -:10351000CB1F6F79CE01F187BFDCF75C2AE65180C3 -:103520007DC9EBB52FB754B1F16E793E0EF3963EDF -:103530002FEDC807BFAFE291DF3BD4DF35ADF3F825 -:10354000A766C17CB93D5C266FCB76823D0C44CF2B -:10355000ABE8B3FF8AB54EFB79D669D7AE733EAC04 -:1035600053751FA48AAFF3C366B6BE8F36B3F52E6C -:10357000E8B3CE209E83DCF298C51B443F238C76B3 -:10358000FCD80E99C0FDB31E3F4367F74F9396AD2D -:10359000808F652BDF396CA47CB17818C50FE5836B -:1035A0008ABB2D68E717FF8A9D7F7E2A95A4E101DB -:1035B000FCCB61C70FE9F325D43F00FFA2771E3D86 -:1035C000767F7996DAEEF7137FCB791C6A79DBEF99 -:1035D000F1F7A2241FCB875C2EBE03B34BF71D1857 -:1035E000057400BB276F053A651285ED13B5F1D45C -:1035F000BF0DFD72EE4AE4FFEE61EAEFF5D6C58736 -:103600004D90EFDBBD4342BF68D9AA12470981FC48 -:10361000561607BB238BD92FC9E7C3BC170BA56B65 -:103620003C1DEF27590A7BAE38595EF7C304BF3BF8 -:1036300023E6AB7F0EF1712BD83F9B01ED9F7EFD02 -:103640002FF07196C906F4A76BCDCCAFEEE2DF7D0B -:1036500078288BF9D30F6531FF7A1B8F0F74811F88 -:1036600009E7D39759F0F77A08998C71722361FCB6 -:10367000671478731ABFE8916FF497BB33014F73E7 -:10368000498709E839A3789602F7060EA75AF13B55 -:103690004AF4AF0CFA99CDFBD96F62F7040EC31848 -:1036A000745DB3793CF9307C06948E7F788019FD87 -:1036B000D8E00B16F4136E8F67F13E929C68043EBF -:1036C000BF89EBA939132C3E381F983DE1F63280B3 -:1036D000B4BF20A1F8AAB076AF2FA0E33418989D0C -:1036E0006F7013BC2F499A3AC700FE2EA16E31E4C9 -:1036F000C9D3D5EF3C9B742E3ED2DE53A885B8C209 -:1037000078C218AC18F1AB29D79A59FD1B8F1C99B8 -:10371000715F26217F826C26B0338023E08BCA4400 -:10372000DCE7CE843C7E374023F2DBD546123430D2 -:10373000D86CC3EF10B1BC7E710E725D310927D217 -:10374000F585F76AEF51DC10368487C3F98E31DCDA -:103750000EF833581593938E53364D2A04BCD7AECA -:10376000EBDF7C3F7EE4F88CFB26D0327CEF0AE670 -:10377000F94309F3796653A1073E9D6B242FCB854E -:103780008C7EC087756E2588ED56303E17F737045E -:103790005D0A68F76AFCCEE6F3A3FD343BE07D7377 -:1037A000F4B8C9892CB1CF637EDA522EB74B05DF4E -:1037B0003DA595D7E46C2E37E00F52BCCDE6301610 -:1037C000DFBBB2995CB8B2599EF5B71738DE320B41 -:1037D00009E3BA5FB0201DC5B833394CCC1E84FD57 -:1037E000897908FEAD26F5987F53CDE33106AA49C5 -:1037F000304FB7E531CCEFD7E709510709F3CE9643 -:103800006CD73F57C573648D5EC238A764EE5E0007 -:10381000F393BE17E7057E9F6D6EC57880BE9DA9A8 -:103820004542393735537F4AE2E75BB46CD92CE126 -:10383000EF3BCCCEEC1E89DF2BE77E7535A72BD571 -:10384000DE53E11E5035F85378FEC5BF13B585F938 -:103850009146EEFFCEDFACF5336637A9FC4C06345B -:10386000F7EA2DBAFC7013F7373E30778F047DAF3F -:10387000BF67FF8181CD3F984A303F52DCB337723A -:103880007F52F093926DD29C8B89FB9C15A0A7D898 -:10389000F70E74F95436FCEE4A85C4BF57C9E38A63 -:1038A00027A8BF89DF95391487764BC419BB4AEC2A -:1038B0004143227CCE9295E724DE3203FCCC0A877A -:1038C000D908F08CA113C7B955EEB0E7E4F4C6717E -:1038D00037948CDA027943D7678F9869CDC2530E3B -:1038E0007EBFC87B00F2D6AFFD86CE1FCB05337DF1 -:1038F000747FD4F54AF75C2B55D1B55B0B661AA9DA -:103900003DEFBABF7B2B94D76C1D3FD348ED60D7FA -:103910009DDDD9F00DE135D997B3FA06D1DFE53356 -:10392000213FB8EB41569E4DEB83E0E7F27B40151B -:10393000E325D4B36BB8FD11F1A30AC34B0C4E645D -:10394000BFF371BE76B76797AD01FB2CDB8FE2EF5B -:1039500009DCADF8D680DFD394E9AFCEA670C92CD0 -:103960002968867BF16F868671FB15F5772FD66403 -:1039700031B9DC3890F527F045FBA9FB67FA49839C -:103980007E5234FD04FE997E8EF6EDA7E19FE9E7B5 -:10399000FB8AB61FE19F89EFCCFD31C7F708F4BB66 -:1039A000740DDB0F93A336CDFDFF93F5CF0F03BB53 -:1039B0007FF2294B12F0E1D267FE3BBB1AFC3FEECF -:1039C0000F7DD6FEAE19F2BE9747D87771EA22EC8A -:1039D0003B39CB77B69BA7E6411E6BBB79926A7EDB -:1039E000B5BDBF7365BC5AE5C73C9A2DF2B5D9EF9A -:1039F0003A2E7DE613FC9EE05243EBC790E74BC6A0 -:103A0000B3389A7E9D9BF87B87E1DC3F4ABCE0C9D6 -:103A10006CA66FFF31D8F74436851BB309F62FC764 -:103A2000F86ED797BCBF8A78A6C7AB8AEC5685E2FA -:103A30007BCC9BFE46C83BAD7E38A750A6F37822D0 -:103A400073E20EE82F767CB39BC537DB587CB3C29C -:103A5000DDB18A1A29723C7BDE5DD6CB08B9EA015A -:103A6000D273DF0FE286D32CA27CCBCCC91358BC17 -:103A70000CCA07B6D6DD05F2B387FF3EDB9CB12347 -:103A8000E341CE3B73120C4E2AFFBB322A8FC33C5C -:103A9000E68CBD6C2A3C2FB1D88755B2F838F2C7F6 -:103AA000AE8CB2DF037DA13DC43DFCE670CA0D744F -:103AB0001DFE3FC89837EDCF4FF047BBA7F20AB7BE -:103AC00057C7B3999FB6C740E759D83B0F313E75EA -:103AD000CC567540DC6ADD8002F0A353324B3ECBFE -:103AE0001ED33B7E4AA6FF2094C5F874B9F9F0BCFA -:103AF000BFF3788BD3E333A01B85651364F8524280 -:103B00008F5EBF7A7282A67CEDF424E253C74DAF7C -:103B1000CDD094CB2B066BDADFB46084A6BED4D2B2 -:103B200031BAFE02FCFD3AFB9398DF7BA8EDF4DB93 -:103B3000B3C18FDD2E7B25BA9EC52F3CFE36E45FD8 -:103B40009F809F2029647131F6BD467E1E63F41963 -:103B500035E7317B9F3383DFAE8AF3EBEEE5EDC3D0 -:103B600038BEFE3C46E48BFFB3E7310903F5BFE7FF -:103B700079FC55BA323269573BD2A7712FCB636EAD -:103B8000A47E0B7C4FECFB3B2D21F886FBE7FF7DF1 -:103B9000C4ACA8CE65EA220DF8BBBA93761DC173FA -:103BA0009BA7B89FB4BCED4B33DC93FA7EDB0A9441 -:103BB000E7A9547F2552BEE968272377423C39C7DD -:103BC0008E79384B9BAFC03875626436C2DA962B5B -:103BD000B0BF65916BB0BC9CFF9EEF9EF88EA96054 -:103BE00087F7FCDA85FBC1037278D843D08FC58E86 -:103BF000FAA13463CE3AF013F6C407F36EA6E39548 -:103C0000FED7F7310F7DF94E09E3A6A532D923413E -:103C1000FE7D240EFB2B95FF347A057D7ED5246630 -:103C2000574BC1C7A1F572917D137E4F3AC6EFA4E1 -:103C30008D1DC8FC3A53279BF794C82CEC4FD45FDA -:103C4000367090E6BB7CA694EDC6F9B6DEF5983AE0 -:103C5000258457464620ACDB39CB08F9E77FC87D81 -:103C60002C19F044DBE3F7C1FAEAE3B189248ADED8 -:103C700012D0C2F5F06CD0C370FE9EE3BB66600A42 -:103C8000FC1E61A7D10A7AD4667582FF32A3B840C0 -:103C9000A956AD4B7EE946BC076149EE3681FD9ED3 -:103CA0004DA15A6FCF8B61676E1C28F47603426179 -:103CB0008F48E407EC3BA83C3E20E469EA4083E6F9 -:103CC0007B3A1D12938BE0AFD8B940698E7FE940F3 -:103CD000DA4F4709297F16F5684736DC47FF57CD8D -:103CE0009FD2D70AF477183B09C431EAF97C843CA7 -:103CF0009F6FFE7379FB033209005F1CB8FCF20E64 -:103D00001F9D57FB6DA346815D10E3350C6479A6BA -:103D1000C4D9FD0DE61BBE98A0405CBF14CE3C4646 -:103D2000F7FAF3908F08F1C3BA172D8FC20752EB41 -:103D30001C747F6F83BCC0B830F06DFBEFE28C6009 -:103D40003F0A87F81B002F937E377C327CC7C7D78A -:103D5000663112F4837CEBE079ACF99E4F7F0979F0 -:103D6000D4F399BF99C99F9FCB6125E7DBF95C0E1E -:103D70002B8DDE44388F99B74FC67B91F3574B2379 -:103D800077427C40B1E33D7D218742DE4CC097A362 -:103D9000803F195FD6465C5CBE7378BF4C0E4A65A7 -:103DA000966F573AC285FBE7E591246C27E455C826 -:103DB000E91D39FE1DC0D7A58D54BEE938FE750337 -:103DC0004683BCF4F289D909FC44F9C453ADE283BB -:103DD000C6F6AF8CC027A60912F28985C2492A3ED1 -:103DE0002AEBF14F9C5353E93C6634E5E0F79445E8 -:103DF000FDAF7BF8A57FFCFE18978FF9B6F050F069 -:103E00006B4DF5715EF88EFC896405F5D8CA8D128C -:103E1000FE38E14A53D924F02F563E28617C0FFC2E -:103E20000ED03F4507EBCDEA73901B23F9785E7DFA -:103E30004D6408C22732FD2F03FD2B23D7733CE6C8 -:103E4000473DEF3B557F3BC6D54E852C5EF69D31F9 -:103E50006DFC6E8CCF8BE77FA67D26B24D81B89B23 -:103E60005FC6F3BD2CE2BC5762F13B88E789F89B43 -:103E700038A71371380B7C0F5765474F1B5BB26136 -:103E80001FD2271E57C2ECFEF1ED26766FABFD4F19 -:103E900045065AFF698E0FE372AF79FC87613D4B8F -:103EA000AE0E3D63A2E5A5773EE78078B9C067AB6B -:103EB000313C14F64BAD148F101F6CDD2C4F0B31C1 -:103EC0007F2761962ABF22165F2F890C46FC087B4C -:103ED00023F4F7F36B3DB829157AFC7C7648F0F7AC -:103EE000322E07CB400E88DADECC2A83DF3523B9A9 -:103EF00012DE73EDB5374C1E849EA6FC8E72533ACB -:103F0000380BE3EA426FEBEDD16EB9F5DEF1C03765 -:103F10008ADFA950FCFC0F4D62B3890080000000CD -:103F20001F8B080000000000000BB55B0B7854D518 -:103F3000B55E67CE9C994932AF3C0986C43393077E -:103F4000700D383C22E1E1C78140002138C15B455A -:103F50004D65402411131250AE51B8DF9C90808003 -:103F6000D486EA55DA824E28285AB551B0C68A302E -:103F70003CB4A15A1DABADF456E8A014791BB15660 -:103F8000FCA472D7DAFB9CCC9C4982526F874F37D6 -:103F9000EBECB5F75E7BAD7FADBDD63E8789BFFC50 -:103FA0007AFBFF0240ED8B4F4F820C8009570920AE -:103FB0000A00339747CD36A4C16E736FF5205D3A82 -:103FC0004C5E500C70917EE301C4BD5F49F210005D -:103FD000EBF24A50EC00B7625B668FF54B004A3B50 -:103FE000D20051F32C47EC79A66CC2FFD1F32680A6 -:103FF000129C57E73BBF14E01A80DBDCC07F8DC802 -:10400000D41FD7217EE49B6A85397E5C1FCC91BC8E -:10401000F8F92A3C1307CAC85A2C0B6CDEFF2FB9DB -:104020002B44B00969004E7314D28A697E5D6E9587 -:10403000AFF32D725FA1F1BF2342633B8E7F67FC1C -:10404000F8888272ED5936628428C7D61B2F5B1818 -:104050005F453A8E1D09D0F59A35B419E5069C4F97 -:1040600040FE4F5F1B1C5A8B5B3B0C5D17C83EEA42 -:10407000CE1499F655BF2B85F1D727BB4202F6D750 -:104080003BBB8AFC284FD9EEA4300CC57576279926 -:1040900001D7FD26FFF6F1A49FB2DD0327094E14D8 -:1040A0007AA7D50CC8F7409EA2D0F3BEE4D7E54B63 -:1040B0006CF5FD97570AAACB0530BDCCA19AB05D2F -:1040C000783E1F6004C05DABA7B1F6E560362A19E3 -:1040D00060F2F94A00DC5BDDF91BD8F345E75318C1 -:1040E0003DFDC14839ED075E16602BCA5F91F3C3F1 -:1040F0001580F27526C3901DB8AF4E6FAEAF9970A4 -:10410000D93A8DF157FC6ACA54DAD7A21DC84CE3DC -:104110000609A142D2D351BB09B200EEB671F13FFC -:104120006FF860A48CE33F1FE91806C8BA4F6C7F94 -:10413000788CC0ECD949F69CA8E15D3A2F8282F2D6 -:1041400058CF0BACFD400E2C964B181F401AF9436C -:10415000FF9101FB77C1D32B928C78946A3F93082F -:104160004F566CCBE2FAE7683849D4E37F5DA61F6F -:10417000CCFF8E785A43782AF9B7E2690DE9A9177E -:104180003CADFD3E78BA841D7DE089E16CFA9B1C54 -:104190001F90EFF06D0586172677A72537D48C7C06 -:1041A000B7925D095F17A181F43987EC9B1EC3EBC1 -:1041B0000E4FE0F9783B7726ABC58B8BBF8B9D6F9D -:1041C000068A1BB766348082CFE7601B1F37AC645A -:1041D000BFE29EFBDB7E99766EFB8E76DEAFD91951 -:1041E000DC68C791CC7E32D935D1EE6457B27BFD05 -:1041F0002EEBE64BD9757841E09DDEEC0AEE6413B8 -:10420000C919B38BF506C2CDE76133907FF56557C9 -:104210006903D7BB4EAF0C9BA786D87900E99543BD -:10422000185E22DF072F1565ED7FB7A5029C0DDD17 -:10423000ED378F06B8B114BBAEA0EE7B5A95028A5B -:104240002FF8F7316C46056C4C9F9C56974626E13B -:104250007EA73FDCDDAF52FFE4712E3E1EF9715B9D -:10426000DDFC67424B22EB98DCAD5CDF81A8D93FD7 -:10427000248E1E89B4238E2E4DA037727E3A47DCE1 -:104280006C9E10F74F9C5F184EB43E9FE607D055CA -:104290009E8AF69BB94370AF457BDF32EE530BD954 -:1042A000A7A22CFA460EEE57685BEEB70FC6E714CE -:1042B0000751DED4B69656B5401B8FFE53ABA9D13D -:1042C000DA2E2822DAA9B65408793D3DF598EA316C -:1042D0009E67F4331BC78365E4E58D273BB2F15E2F -:1042E000363E6CBD8CF56F1A074AA8973879A587BA -:1042F0009FFF7001697D7ED4DD0DB8BF502FFE3663 -:10430000509B376232D501EAEBEAB60DADB65CB42C -:104310002F707C0C6B7BCCAF721C8292B0DF4BC9D0 -:104320009BA9CB11B75FD9383E7C297DE5F4D097A6 -:10433000868F1A235E5C66FFFECF510E5786E056CD -:10434000D1FE8BFC49EBC045F6D7F1BDD9AF0CC00F -:10435000FD2541375E8DF8FE859FF0BD0874FEADEA -:10436000AD742EF94DDDFC1CEF3B85EEF183D0954D -:104370005DC0C74F6FDBD2AA16337BB07E469B2F42 -:1043800081F7F6047A5C827F68F866FE49711BF556 -:1043900053D84BDCA8D1F47B4680D914F72213798B -:1043A000BE17F1F276B587E7770D1A5FA36EE7E4E3 -:1043B000383D0C88D9197F611864D837D3D3CD190B -:1043C000FABEF7FB67A0DF44D26088803859E10964 -:1043D000B7B6C4E1A4C5B39FE12436DFDE08C5FD4E -:1043E0009B353DADF6EC8B683812C8EFEA1820100B -:1043F000073B0455C47DD6110E7AD9E7AC9E3852DE -:1044000013C62BD225C6CFEE395E49180F52C6E52A -:104410008CD7EC3423C18E5313EC382981AED2E90A -:1044200090219EE9716E5EC7FA955928C75DDB043D -:104430003A26285E5B8461009BDA7EEFB7F727BCE3 -:10444000CA520EC6FCB6B6772236C47225C533866C -:10445000DF48AB8278BB81FC9DD1EFFA1517E1A74D -:10446000616536F23FD5F687561BB2DED2B25EA248 -:104470009CE6976DEFB79A71DE9B47FEEA0D9ACFE7 -:10448000DCF4A7C80CCF25F0DA9AB08F8D09B49A66 -:10449000C0FFC8B7C4F79684F1CB13FAD725D01B59 -:1044A00012E8D5C6F173E70BCC4FE6A2FD4871DFE9 -:1044B000E6377B347B76FB3FEE40B0B33CC980FBF4 -:1044C000E9CD9C7EB3EDA87FB53D8EF61CF393BF7E -:1044D000EB389680FF6ECD0095CE0FA98F78F64A07 -:1044E0005F381A9478DEF1FEBFD25FFB53DE098697 -:1044F00073799F68A4F788BADC7F8FDC63A7873A5B -:10450000FDB99FF2F1E98F19F78575A1467FE69F06 -:1045100084FE3FFDC71AAD76F995B87DEAFCE5FF4C -:10452000BC28D27A473C5DFE2DB8EFAA89E1C206CD -:10453000E4AB4AE32D9E33229D63F536EE4FE5AFA3 -:10454000897E3A67AA92C3854B8AE3F609ED45B4A2 -:10455000CF3DCB44661FB599D723F3C067012C85A7 -:10456000F6B85C8D4F22FFBE6562239D6B871BD31F -:10457000B348FEE15E5EEFED735D997507D27B5245 -:10458000E65864E4DBF3C064D6EE1595555D88E328 -:104590008B6D17D939BF27C5C5F4F3B5E76B7F130A -:1045A000C6AB6F3C325B3F90E6CEEAA07C75AD04B3 -:1045B0005B6592C7F738C3CD8FACC3D6A21C739B83 -:1045C000AECAA2FC6DDEFF5496F747BE792B259F3D -:1045D000C0F86028C91D583BD942FDF35BB4569D15 -:1045E000C2DADDDF6C7F7328F277AD117D9B9179A4 -:1045F000D779AF731ECAF571128FC31F9D2E7092AB -:104600009C8F7A03C95EC2ABD3912CD0E1E1969D19 -:10461000B370DE87F395146F668C7FF737E21CCAA0 -:10462000375F3D3D2F2B8074A697E366D7F9795904 -:10463000F3E2CEFB0567CC4CCFBB2DF23D945FEE91 -:104640004ECE155481E939BD12FD65BE965F235EDD -:104650001AB7F772EE9BBC22D3EB516B237C8C20F4 -:10466000DEF360E63892531F57F27EA0D941781EE0 -:10467000200F8FCFA3B3F2267A48DE18CEB2DE2504 -:10468000DCB03C1AE9E2CD69EB553A0BF761FE4F1D -:10469000726428E5D40FCB9101F34EC86E2F8ABF08 -:1046A0008F88E5A92BB478C0F90EA90E56B71E7AEB -:1046B000362944F5CC21F52F0EB0C7F3733FA97608 -:1046C0003A543A8C3F7138CCA4D7C3E6E0B1FB70C2 -:1046D000DC824D128BA30B36652EEFA27880F62C70 -:1046E000849EEBAEF44A6C9E3EFD44CDAF34F80997 -:1046F000E457D2B9D6979F946FF6566EB1F7ED276F -:10470000D55ADE5EBE49F213CEAB4B1C66B81AEB2F -:10471000EC4DAF6F253C562F4E1A6E45C1AB375945 -:10472000997DA30E87EAC6FE80D3614EC5F6560D6D -:104730000FD1A62456A788591616F7C4552532E975 -:10474000A74C04B30DCF15D1E993FD9C6E7163DDC9 -:10475000B6D2512A937D577865B6DFEE7ED7ECEB63 -:1047600004AC6BCEE13ED271DC89C6871F1D85F299 -:104770009D84D08DA350EFE7C8D0B8CEB91D624854 -:10478000A573C2AC982B30EED500F7F7BA03DB2D3A -:1047900013F0AF350DD533A83EBA33247D14D56A56 -:1047A0009F8BF8DF17F09685F2DBBBB6199FA3C786 -:1047B00058C8AFEADA8DCFEB61DD67E2506ACD1FF2 -:1047C000450769CF71DDC60FFF3C647F1CDFDD5EEE -:1047D00047C6312CC161380C47CDE23AC5AE9B08C3 -:1047E000768D2293575C9114223D8A79FC7C980245 -:1047F00042288900E1C67DE3BA5F060F0ED98F809B -:1048000010EF1FC1F4723488781A88FA70DA18BF72 -:1048100078BF18B2E2BA65E9A0A4923E1FAD047059 -:10482000307DAA6EA4A7643498293E7579B83EE716 -:104830000AE06F677EEFCBA3FA78C1A62466BFEAD1 -:10484000C7EFFCD34F4792BD2A32E2FDE821C25D9B -:10485000099B0F6C69B1793E69FAEF3C92A7EC09AC -:10486000AC2BA9DE14038FDECCE2658A8FC52D77D1 -:10487000F447A308274D29C3D602E1A47F9EB73889 -:1048800036BE7AC5B2223E1EEB5527C5AB24B69F75 -:10489000DA1D568693B96B44859D8FB916763E7E98 -:1048A000D492C4E8DA01A5CCCFE69A2040FBC05CE4 -:1048B000309BC575AE72A8B583B2DD4E717E5D4486 -:1048C0007432FBA89ADD2C649FA7BDE96CFD39A466 -:1048D000633CB70E68389B6BE2F8815D42682B8BB6 -:1048E0004F0D32F97F954960712ED11F7F434918D2 -:1048F000C5C93CDF6D34AEEE21AB6F8587CB20EAB6 -:10490000F2209EEA4C91053FA7797F6D65F71AF575 -:10491000B88F2427AB2F941751FE7A33982D742F1C -:1049200025F378A6CB532F574E219C62FF4133F6D7 -:10493000D739783CAE4BE5F73DE0B085B6C6AF471A -:1049400032E7F371B293FC6C34C30BF9BD09FB3F42 -:1049500005DE5FE62C95A3F8BCD304ABE99E84E4A6 -:10496000193C346E5DA4FB0F253C2E367B1D6487FD -:10497000F41B67D37ACF892C2EA1333D544AF9DF3B -:1049800073E208AA63E7AED957BE81E81786B94932 -:1049900084B9CFBFC7CEA7BB349C4529EFA7F30A84 -:1049A000E917B0FDC8CBF3FB80C8EF713EF2F2FC13 -:1049B0005FD7ABDE5FB74662F6A85BC9F150D7F4AC -:1049C000019BB7CE11C9227BD4BD245D43B83EA55F -:1049D000C93DAF2977DC41C4C73CC9E516F051ADEC -:1049E0005A6121BAB65560B4BE5EDD9A3F66998AB7 -:1049F000F97CD45A351CC5E6CDCCA3F3ECD4B3E98D -:104A00007973E3EC7EAAE565A76C27BF0917BAE9BD -:104A10001E6671926F33F3536E8F532D859BE99E03 -:104A200066BE3BE210B07FFE3DF96974CE1D76870D -:104A30002DD47FB8DD63225A71BBC711AD98AF6624 -:104A4000F4290CE1EDC51A78D14E8B048E9BDA6700 -:104A5000F759BCB89E3B9FEBE7CC73EF15D17D4176 -:104A60005D5EA488CE5FC455510ED9E51981E50974 -:104A70008B9E1595A4A1315C2D225CA1FF2FD470D3 -:104A8000B568C7CBF7929F2E223C0DEF894BAC2B1C -:104A9000F7B3E72FB695031FBF9F70A79FF748B7DF -:104AA0004874AF66D1685C87E8D47C99F901F64F09 -:104AB000E2FD6A313B47206AA17CB85EE47902FAE4 -:104AC0005336E511F51D92DA1D2F695DEA2F8EF53B -:104AD000F7859BE1F926CDCE56761E0DD7F4125DF3 -:104AE000F392937071E6B97D6F8CA1FAEA45C14DDE -:104AF000F1BE871F6A7AAB273D39D93E595E544FC4 -:104B00007A71C6F4D4ED6F1A2EEA81EB41D74BBD12 -:104B100059D393DEAF8D1FA1E9A11634BDEE18C89D -:104B2000FD5DF36FFD1CD1F71748E3E3757CCDD72E -:104B3000F637219F9F9BB5881B5F31C39762B946AB -:104B4000ABFBB1EBCC0B6DECDE48B7A72EF7F27CDC -:104B5000EE0718A795D4B4989DA326A8E9ED9EFA70 -:104B6000264D7F929DC795234D39B735A2FE163E3F -:104B70002BFA98F2A8E68A5BD76A8A3A585E7ABF1F -:104B8000E8A67D95FDB2F23ADAB78E3B699B60EEFE -:104B9000184975462AD3BF2E5F593FFF75A91C7768 -:104BA00061924797F3881066F6525F10DC3CCF8D18 -:104BB0005AE8FE50F7D34479E76BF28A4E618C7065 -:104BC00035C9E393C9BF01CF41268FFDE032B69EC0 -:104BD0007A689967686C9DC3AAC34C7C8781C701BA -:104BE0001D9747B4FB88232B5F6679B0BECEFD3D91 -:104BF000D7093466F45C47E75F92CFCF01DD2F3AE7 -:104C0000D338FECB5A3E607C7A9CA51FDDC3E9FAFF -:104C1000D4F516E79706FDE8FEA5FB936ED77FD582 -:104C2000AF607926CB571FD0F6CD7C242B762E1083 -:104C30003EE9BCB35A109776C3B9C9F29A29033E2C -:104C4000B3047A79AEEB29F179AC9E72E791FEA7B5 -:104C5000D8B34D9407404BF6FE82B8BCEC63BAEF74 -:104C6000A2789A09FC7D06A057C69DE77ABEA69F4A -:104C7000D7F85BD78D4B1C5F9FA19CA0FE9A918BB0 -:104C80008B288FF847BE97E9EF24B45B26E07CB50C -:104C9000C723E54E3956AF5CFBF7B0E8A2FBC01D59 -:104CA0001E43BD507B7A3FF3EF3A88ACA2FA76EE12 -:104CB0009AF72A4691DD9FC67C1CF9E6B77AD8B9E7 -:104CC0007762CBED23A8949DBBB290D1776EBD8364 -:104CD000D36B783E377765C993741FFF7192524E3C -:104CE000F8EE5A2FB8A9DE1ABBB564F92DD83FD615 -:104CF00071652AC97D68CBC71563A86E681499BF12 -:104D0000285B1EBE91FA950ED1475B9D0FEEE5B76D -:104D100010BECD2EE66F87B573A259E2387B578B54 -:104D20001307BA5B8EC3B2E6E62213ADDB86E71348 -:104D3000EEBFCA22B787A9EE7BAD9F6F33E90BCBDD -:104D4000D46CC4D17181E7DF3516B011AE0E489135 -:104D5000A524FF81A58E614D248078E11AF20B45D0 -:104D6000ABB3B06E62EBEAFAD2D78F68FEA2CFA3E4 -:104D70008FEBA47C8ACE0F4DDE132D4FDF4879C216 -:104D8000896D856910A7F713B42FD4F79D18175FA5 -:104D9000ECA5FE3B94AFDF4784585BA3DD1B1E9060 -:104DA0005A07D0FB5BCCE38FC6E7E59FB425D90853 -:104DB0008F98C71B9F4BFC3CC13CDEF01CFDE6A856 -:104DC00031DFD7EA3BB1CA15E8250EE96D629EDFF7 -:104DD000956FCF387615F4C8F375BF4B1CAFE7F568 -:104DE000DDF72C1FDA13DEC78C72C125D63F1D44B8 -:104DF000C360EDB78D7C17E59D94F2CFED11AA2726 -:104E00005BAD6E2BEAF728F915BD077C49E479A262 -:104E10000D7C61C4C5D13F8EF0911F2EF890FBDD53 -:104E200082762144AFD8F7AF7F4024FE3B360AD0CC -:104E30004F88ABB31E597F23B9DD395F60557FE4DE -:104E40003FB74DF0A94C42C59E505FBDD15FEEBB50 -:104E5000BEFABE75957ECF94A8F72B0BB4FACA079D -:104E60003EA3DE797DBE1BE1533ABCA7DE4F0703AC -:104E7000AC8E3A1BAC61EDE8F6B6B21C94FF53E180 -:104E8000C84363C97F1C2E764F723AD8C05E029E1B -:104E9000ED18716126EAE755BBCB4D71E36CB0911B -:104EA0003DEFC68B86CF6B77EC117380F1EF1C8BD7 -:104EB000FCBBEC2E7AADD1CBFB366E5F8064FE7E00 -:104EC00054ABB7EF5E3CAA1F3DD7F77BF23E6E674F -:104ED0005DFE93DB6E77527EBAE7E7E93B47937D51 -:104EE000535C6E8251F506110223008E6DE071E86D -:104EF000B8CDF524DD971EDF784316D58377485D5E -:104F0000161FCEEB7BADD249F7027F33479D6E6A09 -:104F1000913F4C72984322C5BF315381BD071C138A -:104F20003683EC61AFE8194E469F3687C2489FA290 -:104F3000F783746E5F48E6EFE9B5F77E77BCC2EFA2 -:104F4000D3BAEF4FB47B84B1DA7E9715A4E9EF7B37 -:104F5000D8F3B252FEFC938DDB67D27C27B6486E45 -:104F600092F7EC1689CDBF10EB7813E2F038E28DA2 -:104F7000E2D7C2F7451F41FAC4365E272F44DCD280 -:104F80007D71DD6249B1B87AE2B14CE7DB29B0FA54 -:104F90005AC7E5422554CEF4AEE1D3867F2EE29186 -:104FA000910AEDAB481F8938FD57EBFE2584CBDE17 -:104FB000E241020E747DE97888E113182E75BBA7D3 -:104FC000B50F9B90C306A82C5EA8136110E505CD14 -:104FD000161864261C98927DE4E78D36E750BA6770 -:104FE000FA3289B7F79ADCAF53BDFCA54996046C39 -:104FF000FF56E061E3EF157D93899632A2EC7E4087 -:105000002C3329263AEF9AAD2C5E24C69B870A786A -:105010007EEA25B061FB4C819BE78FD0C0F207BDD3 -:10502000C50DE6527E529992F6858C2C3F2F983111 -:105030008BDEE3568E4D5B9A8F99E52F0A66CD3253 -:1050400023AE2B47A4BDE4457AEB163FA7AF4E2B0A -:1050500091906E126E983509F9F716283F2D288920 -:10506000ADA3CF8BCF37D2F3B7FA059EA0B6DE62E1 -:105070005F4DF1FE53A16B91498CF1BF2BC0E157FD -:1050800085181D95208FF2E967E89D6A49DFEDD903 -:1050900002655B412FCFE701AC243DCE537F7B906F -:1050A000F235FCF96D88B7EB35BCCDB3D9C3840BB1 -:1050B000582D9DEEC68597E292CB4CFE3D5333F7BB -:1050C000F5E6F01E1A3F185ADCC76C2C15DC783157 -:1050D000BDEF388F8E09C7F4F9707F9F4AB85FB46F -:1050E000ABA0A0ADD1A504547215C63761E76FBF60 -:1050F000A2799B558826313B54B9097F02044C178D -:10510000B1AD4B413CA09E96BC74663FC1FF4E3D85 -:105110009FCAE6DF672CD5F0787D4479AC0D85FA1F -:105120002408190568EB33B0F7AC19D73D610ABC08 -:105130005D807AAC35BD95B74426BF6D7652FE7260 -:10514000E679D13703C7D56A793B5C10C3E3F179BF -:10515000A767F0E6B57138FA40C3CF694F386F19C9 -:10516000C50F0FAF3BE1C2BEBC65C83FD53BAD84A8 -:10517000CEA54740F97301B3377FDF30D3DCFBF7AF -:10518000177FB882E73BB0859FAF5633A88E34D6E1 -:105190008213F5310D6529455A425A64EFE3438C79 -:1051A0009FF89C94A7C8B767F3F735E0277FD4ED45 -:1051B000A8DBA787DD5064CACF4D3690C85F06C311 -:1051C00046379D3BBAFD268B76166F96BCC4EFE33F -:1051D0009608D19674A29FC3F392F4A5F965CF7394 -:1051E00073AB854C51B3F176169FF4B824E31FC21C -:1051F000CFBFEB5ED252A89D9BC36018E1EADBF201 -:105200001D3D2EA17D1C8571EF7FBFD53EA422DC04 -:105210006FB5B6F664B14A36935E326D3E8ACB4BBB -:1052200036E5F7E3F1F82710CF071BD3193E57797E -:105230004466C78A8E1C90F1D19D1D02C878CECDE0 -:10524000E84867B4F37C7F46573CD56F22E5FFDD25 -:10525000EF2D9F1AC8E8134FBE3932C0EF576C3498 -:10526000BF1F74398ADB291F3A674739D00E7EFB8E -:105270006A765FE887EE3A46B828108D28217F527B -:105280002495DBC5D6C4FC5ADBD71237B7E39203AB -:10529000FCDC5D3281BFDF33AB835D8407A95384BF -:1052A00010D23F3820968491B5598BCBD66C13C859 -:1052B00071F6489293418EABDF4055225427CDD6EC -:1052C00070923228CDD0FF80109048AED9F6050CF0 -:1052D000370EDF1586F92279E59D4C1F019EDFEA26 -:1052E0007802F1B499E4FC629C00E9888B1FCCC67B -:1052F000FEB879A5719F4D12586BCC8B512F472F5B -:105300008527BF8EA7C13098E129413FE81F2CFFB8 -:105310003C87E738A54D985D3C360EE91B3B2508D8 -:10532000C92CDF64FE734E4961F7F72B353DE9B8B0 -:10533000F30F048782F3BA4A8D7A4B558C7A4B9FD0 -:105340006AD453A6DFA8977EB3BD86FEFE81FF30E8 -:10535000F4E7D40C37D0B90D630CFC57364E34D07B -:105360001EF53A037FFEEA5906BAB0F51603FFC0F0 -:105370000DF30CFD83430B0DFD576D5B62A087B4ED -:10538000DF6FE0BFBA6385A17F5878ADA17F44E7A6 -:105390004F0C7449E46706FE5107371BFA47479FD5 -:1053A00031F48F3DFEA281BEB6EB3706FEF1E7F782 -:1053B0001AE809F0A681BFCCF69E819EECFE8B8197 -:1053C0007F4AF6C786FE69F22943FFF4419F1BE836 -:1053D0000ADFD706FEB62B024F1462C89F6D5A77BC -:1053E00048058ACFF28FC7219E6FCA30FBC2C474B2 -:1053F0009975DB53855A9EA6E1F60BB0DF66F27E07 -:105400007B1C5C47794126E17A06D07DEFB9768135 -:10541000E1BAAFF3D985F9AE396E1FA98A0D0BF049 -:10542000189D3ED56DA033FDD906FE7EB365437F42 -:10543000FFC020437F4E8DCF40E736941AF8AF6C03 -:10544000540CB4479D6AE0CF5FED37D085ADB30D06 -:10545000FC0337040CFD83433586FEABB63518E8F4 -:1054600021ED8D06FEAB3B5443FFB0F06A43FF884D -:10547000CE56035D12D960E01F753064E81F1DDD54 -:1054800066E81F7BBCDD405FDBD561E01F7F3E6CC3 -:10549000A027C001037F99ED5D033DD9FD6703FFA0 -:1054A00094EC2386FE69F209437FED29841FE5CF42 -:1054B000AF0AECFDD7F4419F19FAA50CCCD3E97ED5 -:1054C0001A927DF41D7E629EAEE76F15BEAF0CEBA7 -:1054D000DC6B6A60DFC57D69E2799DA3C8CBCE37FE -:1054E000CCDF6D361667F1841AC2AE5A9A283F7522 -:1054F000A902C31DA51A55ECBE3083BD576047A352 -:105500004CDFA1617E83449AC9E3A1FA21259687E5 -:105510000EB838E2BBE7A13945C0F07F5D51C05DF0 -:105520005442F5D80BE5549FDC09EA2A9203CF5781 -:1055300017BD677A3BC9786FA4B7D36CA8BFB8F51D -:105540000E24B50E187E09BF9D663BCDF8BBE7D58E -:10555000EE9504DCDF92B8F91FC2BAC98C25646BE2 -:1055600010FD0BFDF4274137A31F096633FAD1A0C4 -:10557000CCDA0DC141ACFD59D0C7FA37064B19FD45 -:1055800078506174283895B59B837EF67C4B7036D5 -:10559000A39F0C0658BB2D58C3DA67820DACFFD908 -:1055A0006023A39F0FAAAC6D0FAE66CF5F0CB6321F -:1055B0007A477003A37F1D0CB1B623B88DB5BF0920 -:1055C000B6B3FE9DC10E46EF0A86191D0E76327ADD -:1055D0006F30C2E8FDC1838C7E2318656D67F0389B -:1055E0006B7F17EC62FD6F05CF33FAB476DF3FB502 -:1055F00088E75FBA5E741A6012C3839ED7CEA4BADE -:1056000085C0512A9D35D42D09F543A23D4E6AEB44 -:105610004813F1D8A63CE78AA2CDCD71F9FE7F16DA -:10562000F17BC10792414DC2F8D744C53C42B12934 -:105630000D42CDECFD2ACFBBAB355C4206CFB71790 -:105640006872556BFE5042F81CC4F0F9D6E5D44997 -:105650007A9DDC322030BF08DB85B92695DD13D872 -:10566000434594F73F3520504DB83DD770C71B6C6C -:105670003DB7AF8816A9B086336FA2FB9F0322BB4C -:105680002FED6BBD7AEDDF2FF4D9BFEBC4003A8765 -:10569000A67E23B2FBF4B725C76CBA1FB94FD3CB94 -:1056A0007D4526433B34D7DF48727E52D8F0E4DD97 -:1056B000C852B5B8D04579EBF5545AA3DF57822CC0 -:1056C000B1EF6341799D3E99FC01267644DF042ABF -:1056D0006B3B72024D34FE662C20880E8CB1E6F5D1 -:1056E000B69F44791ED470F16091C9D04ECFF5AF0A -:1056F00025FD1C2D540CF2A8B9B2F6BD7BD7E324CE -:10570000D73F5EFBEC98901FD3B77E2FB16A82F62D -:10571000FDD462417F4FCDF3411BE8F920EBAF5A36 -:10572000CAEF677E887519BDAFFC508B87E71A24D6 -:10573000162FAB84641FE5D3E71A960EA4FD24C68A -:10574000CD2A1C67C27155C0BF87A8FA3085E10B0E -:10575000E7037AEF5685993BD57F77E7EAF71E5145 -:105760007B269747A1F7B073765ADBA84E459C3C41 -:10577000CDE2D86851B5609DFCB6295424880C1F31 -:105780001601E5ADCE407CF49217E83858A4FDFB35 -:1057900018FD39E26B3BCD77F6955183D87B935D4D -:1057A000A365D25FB309ED41F735BF13F9771274E2 -:1057B000C54EDF71B88ADBD877FE944490BD463B76 -:1057C000D8FB903D2234BED04BFC7C5FB3DBDBD9F1 -:1057D000D2D4109BD7F89EEFF71AAE7EAFE1AD6240 -:1057E000EF81DC7B71DE459D12AB776064B4D8DF5E -:1057F000CBF74DF58D6FF62F88DB477DC711FE5D2A -:1058000014448BE3BF873AADCDABE349B438026DA6 -:10581000F678F9388E10D7EF911E10D7C728AF9FB2 -:1058200069955D37E1D028AA268C6DE00937FBAE7B -:105830004EFFBE6E3EF8595B8D70201CFBD5F5AC5B -:10584000FE5D08EDECF9A2D2DBF388AE87AE49D954 -:1058500054BFAC6E7A3D1BA5BBA175FD64BA7F9E9B -:10586000159AFB3AB5955B84635477A35F1C25BFFB -:10587000880A0D2BA924BDE5D9092BE99E77A6C876 -:10588000ED006F723B208E1431ADE7FED00F4ED18C -:1058900078F40326BFEE07552B387EF47F8FD1EDC9 -:1058A00017A577FD3587DE7D98BBD87721F5BBAC92 -:1058B0006984AF8554798AF179A17E3EF3BCE02EEC -:1058C000CC0B88EFA4C4ED7FF25012FB772F270595 -:1058D000C4C7F09EB8D7F3CC2F4DFCDEED5E11B7F8 -:1058E0002852BDFC30D3538D2D3494F484E7B33467 -:1058F0009070FD71FBAA6174DF37319447F9AAF407 -:105900008CD5D7EC31C479B89812BBC77B48E2F785 -:105910006A89F2F6C85B4ADFF88AF209AB05547A65 -:105920009F84FECFFDFE3097FF4B5320FB1A91E77B -:105930002BAC8E1EE067F53F64D97C6B859EEBB780 -:1059400068EB76FE93D7D36A2EB0EF7112E510DCC8 -:105950007CDD4479ACC95C0EFDDCE9290FB7832EF0 -:10596000CF90811E7E2EE6296CDF4DA65416BF3ED9 -:105970001503C5A437FD7E4CAF633B3D9FB0B80E09 -:10598000179A07F0EF7BC37D9DA7A7BBEB676FEC72 -:10599000BCD3EF99605CEFF7827E9B5B22BBCD02AC -:1059A0001F8BFB83E1435D3F867BC2FF035073AFD8 -:1059B00086E0390000000000000000000000000048 -:1059C0001F8B080000000000000B7BC4CEC0F0A3BA -:1059D0001E822538106C62711D0B03C30756D2F569 -:1059E000C17025507F0910E703711610A7027102DC -:1059F000104703711810BF069AFD0C881F02F11D95 -:105A000020BE0EC49780F82C109F40B277191B035C -:105A1000C35A36D2EDFF83E4E78940763910CF24AC -:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2 -:105A30005479051E047BB92065766D03EA0700E9F9 -:105A4000CD424A800300000000000000000000007A -:105A50001F8B080000000000000BD57D0B7854D58B -:105A6000B5F03E8F79253393C9839040C493970452 -:105A700009382421F2AA1E0842A4D406F42A5AAEF8 -:105A80000EC823869044B02DB7729B21092F411B6D -:105A9000152D5AB483458B0A36F268D106EEF028EC -:105AA000C65BB4D1A282D536D45B450B4944116F95 -:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370 -:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5 -:105AD000D9C5E42B19FB027FA09CA330C60644CA9B -:105AE00051775EBB687B09FCFE99DDFFB8166967DC -:105AF00094173389B1D1F09E653056CAD8954EF8C7 -:105B000015DA95BD70EA0F97A531B69F29CC018FA4 -:105B1000C26A59EAB7A09FFD9F333FBE975F706787 -:105B200075B8F1BB2063E98C5DC1F877E16C2DCBD2 -:105B300057881526E373DD49BF433FB99BEAE0FB75 -:105B4000B39FBAE97B2B1C46C93E9759587CF34555 -:105B50000EF6AB7EDC5120EAD90C066702DE2C1A69 -:105B6000D780F7D0DBEF11BC075480578B33BE13BF -:105B7000E04F8BC0BF9F5D9BC40A39FC7A6904FE6D -:105B80000B8587E60F786EACD7BE9997CFD8BA7AD7 -:105B900046E5DA7A2795ABEB7DDFCCB331B6B23E82 -:105BA00083CA46153E01381AB7B0501050EF2E8404 -:105BB000F646FFF03F21CF69AA3BB37CA6BA3D0D64 -:105BC000FA2988D455B766AA37BA2739036E1C1F3D -:105BD000E6EEC0F19D5402984733001F978A79BAC8 -:105BE000B4E02C06EB91E7B66B2180E352F782E933 -:105BF0006C24B6CB27BCD9055E9764367420BC1FD5 -:105C0000433B06F31DE69EF23EF332F69FD94FF07A -:105C1000796C606C203C5FFDEF751D12F4B732D3D8 -:105C2000AE35407F4FC0F86B1C5178DCAAFEB9033B -:105C3000FA74C23FC4E3D08DBC1E9937D4A3E631B9 -:105C40008C45BDCF8EF473A1FDE6379BEBD67EF37A -:105C5000347D12D2ABD16F3EAB68F0B9FFF7F67B63 -:105C600029E03C3525D2AF314EBFFD023954C0B7D3 -:105C7000F91B59289C1D3B4E9EE62F0FC2FBBC8D85 -:105C80002A0B65F3E769C01779FC57D6E49B94109B -:105C9000288C8587458F93135997BC34FB1C19E8D2 -:105CA000292FE3FA4512D25573D4FAE63066F0CDC7 -:105CB0008FEA7D4C1FCAD8DDF505546EA9F7E9C8F7 -:105CC0002777FF5D99D55218CB8F7F11F2EA1E1B03 -:105CD00023FA0B3ECE428F4BD85FC5AC39505F3FA5 -:105CE0002ABDE82E8D885C4679E61274BC5ED26EC1 -:105CF000C8C1F6AF280CE5A0951FEEB6E9D3B0BF3A -:105D0000B5A364A901F19CC7F921CF1676E662BF5D -:105D1000CD39A382D88FFF55E287BCFC4B3405C632 -:105D20001D9627F861F4834E94873DF35F96AEE7A6 -:105D300015339664A103DF79D2816F42DF74F07569 -:105D4000F1C3D7475FCD7DD2D77AFF7DEF3BE0FD32 -:105D5000963CBBA664C7C295797138A3C21D4B6F30 -:105D6000797982CEFC7DD399B57CB03EC4DE011A30 -:105D7000BABF3E83E8EEDE7A8DCAB5488730EF07BA -:105D8000B0E958A8231DE2B8D71551BDD77D8BAD1A -:105D900020BA4C9FD5CC50FEDE8FF4390E875BA91C -:105DA000EB1360AE79A20E5BA40C7BC0BDF87E1035 -:105DB000D575DCCAEE928CF6CF0675C0778A683F3F -:105DC00075C5B3C146F8FD7E17AF5FBDA2530F6620 -:105DD000457D1F5CA7EB5991F6500F4F52A3FAC3B4 -:105DE000FE0BA3E13948ED8DFEE6AF38A10701BEF9 -:105DF0007B5DBCBFB52B8EFD53FA5F2B053240B5E2 -:105E000060AB2CFDACEDA9DFAB231E8C7172A45FDF -:105E1000E8C1E8F7C16774DD1D797FB9746F10DFE1 -:105E20006F64157912AC43E6F48A0C06EB6FAF6829 -:105E30000EE296DB039FC077647E0F12BCAE0CFEB1 -:105E40007EC48ADFEB8D51EB3369C5CB4184D7D05B -:105E5000731441AFF20B594B8F00BD2A49763FE9CD -:105E60001BD701D364C278B32A980670C969150C90 -:105E7000E58192A6BE1BCD0706FD019C6309CEC934 -:105E800015B37A8133180DA701477F701B70F44E4C -:105E9000A77C7C2B3D4DBA66CCEF26C0FE6D6FB75C -:105EA000F9515D48453C4157ECF35B8336789E3AA7 -:105EB0001370ADD1BACD62B9B1FDA64D1FC4425128 -:105EC000FBF73F7A5DF3B0CEF116885E5FA8CF9501 -:105ED0000644F03856B4B3D29F313F5BCCFCAE35AC -:105EE000CD8FA9818C0A4FFFF3BBD7E59F55E18E7B -:105EF0006DF75B49A2F1274D19F36DC6C7630E908C -:105F00005FC9385E5164BCE469301E76A636C71D91 -:105F10002F65328CE7FCFAF069E547035E7B0CBC29 -:105F2000B79AE05D6B03BE8DB3FE5F37BCE7CB7FF6 -:105F30002E90BFC47F797DF3DF3FBABF64FC153E6E -:105F4000F94865E12B015F775CE524FDDE9073FF86 -:105F50006C7CA5E2A7B07E77BC547CE24A192B404A -:105F6000D72322E3D74A1AED57BDD1776FF3810DBE -:105F7000D6D4CFFFAFF9F486D7AF5B0E9DAF7C6D63 -:105F8000783D81213FAD2C642107F4B1B2ED2AB2F6 -:105F900037571E291BC8A05FDB9AE14C8749256350 -:105FA000FFD0DF4A43CF985CD24FFF5CCF00FB4E5F -:105FB0006F02A56BB7B782F4A29512A3EFD783DE69 -:105FC00016023DA6E4950DCE3958F7EF70CEC1719B -:105FD0006D8CF4E992570EF9CA80CE5D23524629A2 -:105FE00040022B5DC6F3A3E5A8E7DE55289E7B782B -:105FF0007FF0BC02DB2788F6BDC1959007F044AD69 -:106000007FA2BD395011477FD76599F0F390D0BB7F -:10601000EE46BD0B047262424B00F56A57BA5D7BD7 -:106020004C8AFDEE265912F306BD0DEDEC115332EC -:1060300051CF3A30E389157684AF90915C77E5854E -:106040007419EAEE02CEDB0F59F67D37AE21E95D19 -:106050009952994ADF99EA77F7E831D913516FF3EA -:1060600016F0F7650D574C6C8C7ECFFC1371FF3525 -:10607000DE071A4AE97DA6B3E2D804183F13E468A4 -:1060800023E02B536D96EA685DD3E2EA8F1BE63B73 -:10609000678500860D331ECC9E1F673F81D534F186 -:1060A000E9A079663E7B48E0EF6E81CF4CE4F5D104 -:1060B000820E41BEB978D31EF9E61ACAE55B4241A9 -:1060C000F30AC4F7A079CC8FFAF686194F90DE6AEE -:1060D0008CE32A30CBB94CD53CAFAF6B3E1B99FE5D -:1060E0001D7974EFFD5BF96C230BDC8AED33C57E03 -:1060F0009E5010920285FDCFDF3ADFDEE6FD2DC413 -:10610000271FA74E1E103BCE3F0B2F996E18A7E4FA -:106110001F3F4EC23CB3BC3C5FBCC33E20E88C2951 -:10612000B81F58EDAB84129FC464AAB6A31D4EF2EB -:106130001BE0F6B0E6F24B80DE522B56DD2E83DDFF -:10614000EC79EBEAF7D1CE4EED9843F676536151F8 -:10615000DB246897E4F7CD984274CA08CF6BB1335B -:10616000E2BBAA1513615E8D8CF3DD66F996895C3E -:106170003FD069BDBF2B70062BAEA950477665395D -:10618000F1E66167613E6FE90B47ECF7BDCDDF16C5 -:10619000F94EF8FF9690DFB4BFEFD8743BF9118346 -:1061A000F00FEDD2644B3F49BA3DE2676488A7A87F -:1061B0003ABCFF6D0F5FDFFE4F19CFC7EE736A4029 -:1061C0000AB63CD987F67A12F325AB2867278342B3 -:1061D00000A2D897D61D94B5FED7A589B1F29642F4 -:1061E0004E7733A2F4DC0E99EBC969332767AF848D -:1061F0007ECF9670BF70AA0FFE17C5CE671DEC6BE1 -:10620000E1283FC7BAC2C7887F1B819E72802F8258 -:106210008532F9B7D7E6EDF045F3B5AC18FE6D2B36 -:106220007D304D2D15FA1FE047C99375D7C8AF4E85 -:106230001FCA97A48FC4E951DFB10B5FAF24E5C239 -:10624000E8E3AB8E67AC6B2C5F71FD246DE63C27F9 -:10625000EA3BAB326626C593B3BDAFEB7DB4AEA8C7 -:106260004F84E2F49FA64871FD39567D9EB1A5A6E4 -:10627000F5520696CEDADCD7BAA599F161F4EB5A5D -:10628000A668FF85C24BF5915FDC29FA5BABDD1791 -:10629000C4FDF32CEEED800FA5795418F53D96C79B -:1062A000FC8FF326A487B8343D443A24CADDD208D3 -:1062B0007CF62CD9349E9A9660C2379B05DA761408 -:1062C000FCAE657682C389E3C1388A0F3A94D0FF69 -:1062D000CFC22E2FF548FDE1505FE462FD4E131D45 -:1062E000ACCE2A8ABBDFA9625DD16CE5F47AE7F90E -:1062F000C917EB78D799E13DEFEFDCAAF66E1CFFEA -:1063000071EC772A7BD7C01720F1961E7AE7EBB4A1 -:10631000CAC6F64849200F32AE67010DEAF80A36C0 -:10632000EB35588E453A2CF2915EB05552114E62C3 -:10633000690DFF737DBE10955BE84F7606084F8AA6 -:106340005B67D45E3B3F7DFF9CD0AFD3843E6FBC88 -:10635000FFA162A77E5556C1D06E3EF7F6D40CEA77 -:10636000578747A51138ACFD162A811F2A0390ECE8 -:10637000383CF801FA09584701F9B5F305CECE3D8E -:10638000303389F5C15F0F59F8EB2189C3C92ACE93 -:10639000CFCE380763B6637B359040F1B29305C426 -:1063A00007B962FC27D6CF4DC0F19FD8D8379F1BC5 -:1063B00070FCB4DEC9C2A0A786EA7D541AEF43C2BE -:1063C000DFBF59D831C6F3738A4C70EC137CFF845D -:1063D000B32281FCE7076F9C360CF82BE7A8E24755 -:1063E0001D4F5BCB52FA1A3F3B68E637A6CCEE1343 -:1063F000DE656F4D9C71288A1F7FA178D2DE1D0E4D -:10640000BF5CCE2E47FAEBEFFB73F5FA8C43F95FD6 -:106410001D2F9B85FD79AEF1772B48CF095F49FC95 -:106420009923E448CE3C2E0F72AB594843FEFDFC45 -:106430000B164D1F6099109E32AB558DFC4D4C775D -:10644000CF81F743C5DB4C65BA8C5BF850D4BF50A5 -:106450008E6CE2FE73C3CF0FEB7E17CAB9CDAF29A6 -:10646000640BE7556A0DB8DE39EBCDFEFDC12CCAD1 -:10647000EF8EFE7AA1D7655AFCF85F751D3A701D44 -:1064800012FFF9EB105219D19D51D72456116FFF0D -:10649000FB44D0A9B6E210B743C0F87B272A1E01FF -:1064A000EB99829BC04F83F74D44BB35B886F9F317 -:1064B000E3C84B9B9A48746F637A7828FA0FE65CBE -:1064C000DFB117E5D50466925F71E4864DC5EFD262 -:1064D000B8DC080567F2F27385E265F9EB5908E369 -:1064E0005B9337D4ED47BF5E6635B79B33D7042542 -:1064F0003BD473EA981F87C9AD64BCFD6C16D27992 -:10650000BCE66806D0CD104137430C7A5966A69791 -:10651000C17596B8D01A737D20D2057C37D0422F32 -:10652000D67E723446F1B8BCF5328F17CD32C77DB6 -:10653000F259F7FB3F0778F30FB9FD61161B6FB2F5 -:10654000F6AFB24001E265F70FDDFF590013FCD949 -:10655000FA49A98817902749244F2AE2DB3D31F4F4 -:106560006AE81BBDB48FC84FDEAEB7F7ABF2D39766 -:10657000CE0538D67A7446E307B349AE2B225E794E -:1065800030F37A6707FA6DDC4524DFF7631DFD3CC5 -:1065900019970C8C96F78AF02319F546E147B28ECD -:1065A0003755E57AF07B4C9F8A7818E50864605C83 -:1065B000CF9691BE730E8C67F381BE15E7BBB16AAF -:1065C000029FAFA6FE2D1AFFB071FB481E32BE1F00 -:1065D0003377CA79E1A3440DDCA442199C04660414 -:1065E000D27F0E0B35E2FAD635F3FD2DD2EE16D161 -:1065F0002E8879053DED02D06E84A9DD3C9C0FB458 -:10660000D34DED2A62DADD26FA63A671F598716B37 -:10661000447FA4CFF5B4F3C7F4B754B4233DB0A777 -:106620009D16D3DF3231AE6E6AE78B69F7EF067CD9 -:10663000A6719979DC9EF7A576E33DF9630FE44FE7 -:10664000217A39943FA57C2E8CB3F4451B97115BBE -:10665000793E874157FB45BB26A4AB42CC5B6163C7 -:10666000AA294F85E7AD34BA673A0351CF7BE8CA10 -:106670003DD317FFF95C537B758D8BE9C5F49CDA2C -:1066800037FD5D11F1AA1F4C427FEBEA3459F8DB6C -:10669000AE69D05590630354537D4D86786FBBA689 -:1066A000810262223E02B2F29B8551FCDD33FE3F45 -:1066B0000B7EE13F8EC03FDB02FF6C33FCA2EECCD1 -:1066C000E4EFD595B327E17C0CFFF2D9A6E50D41A7 -:1066D000F7FFE6F95559E65765995F95697EF69596 -:1066E00055938279FF97E6B7CC32BF6596F92D3383 -:1066F000CDCFB972D905AD9FB5DDDDB66692B76B6A -:10670000F35F27FD7FAD88E326ACD41B56E07BE02A -:10671000ED76EA4F23F93E8AE99FA33CE8EFBB47B9 -:10672000548DE482D323935C60F9F6507E36876BF8 -:1067300026C885E7541F97DF02CED72CF50F2D759D -:10674000F8E56FB86FFA9861475AE47C3FFBDACA04 -:106750004CBE9FACF2F8E5E87D4D15B83938A094F1 -:10676000E44FA38FCB9FFD03843C4A837D8DFC4483 -:106770001924AF6C425EDD57CFF3D89A457E506343 -:106780005A11E1A759D80B2C9465DA370F4C9CD2DB -:10679000867EAB334779DEE23A1BD7C756D6339DA8 -:1067A000E8ABDE49F945FBA0DF003468057D0FCB7F -:1067B000E741DFC3724F7D0695BFACD7A8DC01E38C -:1067C00062F94CBD9F0560FC6DF563A8FC31EA8B56 -:1067D000503E20F4C52BD264F2576CAE872D339F08 -:1067E000F4482A1FA9F78D5561BC9FD46750FD233B -:1067F00069E6581BD9AD1D8D4900E7EE57F3285FB8 -:1068000069429A4AFB2F53C34A5249E4B981D78F50 -:10681000A44957E077E33264DECE196AF4C66F57B5 -:1068200086EDC664A8040F7307156F5ADC76E5364B -:10683000C04BA95BF4E70B347AE2F7F72D6C57E411 -:1068400016FDA5698DEEF8FDCDC47147FA381E58C6 -:1068500046474362FC763760BB429F986F56584E5E -:106860008C3FEE6C1C3725A53980F1AD2B6733D2F8 -:10687000476D69DA66292A3E141A50C164A0F39460 -:10688000D4E63A6CF78D809FE5C0F89AD7CF64A024 -:10689000679B1BDE17624E138F478DBF0EDEA33E34 -:1068A0008CEF4744BDC7EFA11C3B4B7C9F647EDF50 -:1068B000A397AF613D793C98BC646B32D79365CEAA -:1068C0009FCB571E98847C9F6CE7EF7F8A75D4B767 -:1068D0009633431EF1F609FCFD8F8CF65EFEFE1723 -:1068E000A27D4A0A9FB76B8A338471B147BE7B4948 -:1068F000E6DCC2C87C2FFA5EC1B0B951F37BE47B01 -:10690000E332E7BA23F3B9E8FB1386CDEDC3EE49D2 -:106910002D977B7264516E25371792FC1CE5A820D9 -:10692000B9336A60A98EFCACACE770FD87EDAE862A -:10693000863C822B88F2C680EB278BCD700DAE3162 -:10694000C3F5931A335C836BFB866B9D8DCBB5DEF1 -:10695000E083F1F5E8F11FFD37F3F8437E601EFF99 -:10696000D11F98C71F72E7571E3F1CBD2E9B6E3765 -:106970008F9FB5C43CFEA625E6F1B3967EB5F1FF28 -:1069800051FA78922D70C426F45D255AEFAC0B981D -:10699000F45368F78A681754A2F5D840C0A49F4200 -:1069A000BBD76D42DF35B5AB8869F707D11F338D93 -:1069B000ABC78CDB21FA0BCBD1FDF963FAFB8B68FB -:1069C0001794A3FBD362FAFBC080CFD4CE17D3AE0B -:1069D0004BB463A67199795CF82950A19FEFB30479 -:1069E0003FFA47964D5E4371AF812C20A1BFCF97F0 -:1069F000CA461D82EF592ECFBF4F9EB2EC62B43B08 -:106A0000D7249BFD5CE9766E9FD9EC0A95BE44566F -:106A100047F900CE60E68CA87C8B6A3BDFCF7ADE3C -:106A2000BB8399D746BD1F28BE5F23E2D469F6D247 -:106A300046942BBEC1D03E8EBF22538C6BBC67697F -:106A4000FE761DE0DDF8AF3347A3BF2832AE8DB729 -:106A5000BB588C9B151FAE35D97CDC45386E213E6A -:106A600037F48B6026E1D7C74BE3F9839EEF49FFEC -:106A70000578593DD9292B49F07E3DF76F1A7EF6EE -:106A8000647B9D13F3761B2F92D963D82EAB6F3F97 -:106A90004E53BDD9DFA9FA2A74B4F70655FA8A1401 -:106AA000D6FB770F97CBE5F1E20DA3C5BC9A2A2759 -:106AB00035E7C1F8EC90D96F0B84CDA2F3610A954C -:106AC000C0687B3CBF6D538129AF3E7950DF7EDBD0 -:106AD00046A15FF4CC033A8AB77E370AF8D8C602DB -:106AE000939E959C3293F4ABE486AB9DBE38DFADAC -:106AF000B5F4EF6233756C9798D6CC64EE5C34E9EC -:106B0000614DBEC7F83E94093209E33F693BC2C8F4 -:106B10003F674BF8790A3523149428CEC1E7896A78 -:106B200025FE24AAE1A00CED076D54593895B1FB60 -:106B3000E5C08D881F575E33F9C7549F2E219ECE26 -:106B4000D94257D379025017E3E57FCCB3733FF0B6 -:106B5000C3DACCDF65C759C7DBEC9A492F1DF4A90E -:106B60009D858B7B6F1F69C7E1EAA1D30CA04FE421 -:106B70006F8DD3E9ED8ABED84EFA5A968FFC8E8679 -:106B80007C35F85FC4B7E78E61E247BBE10F308F19 -:106B9000DBDA6C3CBFEF73681D15F7B94DF8BFE643 -:106BA0008A78F73C56E1C597A7995C8E7C759ABDAB -:106BB000EA2D8E5AAFB5763B1F678D8DFC5B463C48 -:106BC000777EB3CDE4EF5AB8D15C5FC066A6A35C14 -:106BD0005AB0C1C6F07CC76D167FD8BFE17C615E3C -:106BE0000B59DD2AD4D38DFCA0B93EA662FEF7E294 -:106BF0005F3D528A7943CD769EAFF301D08B16C5A7 -:106C00005755EE901DEDF97776155F3F9EE1F7A1A0 -:106C10005583509E26B3B8E78C6E5D6386AF3FF810 -:106C2000ADF032D640F0F60687BA558AEBBF7AD47B -:106C30002E99E244CB9CDE910CE4CC39172F7BFCDF -:106C4000297F74917CDF27E80836C0CBB89CAFBBA6 -:106C50001CCBFEBE3BD8CB778B9D1D76E48F5AB5FF -:106C6000AE5C92237126872DA00F86EF6C7B268663 -:106C7000073353BB35E7D9AE4DCA39AF76E5721F3E -:106C8000FD750A79F9C2B69FD9D1BF78FAA913D791 -:106C9000201F2EFAB5C29CD0AE739B8785715F50C2 -:106CA0004376942755BB94B871598AFCC3FC17FDF1 -:106CB000C24372A26A8723341DBEAFFAE53B231993 -:106CC000E0A1B3A1FBF060DC479F92787C34D8311F -:106CD00012F7AD2A95DD122F4FEC84A0BB53CF25C0 -:106CE000CEC27595B6EEBF99FA6DB9C1E688920F1E -:106CF000C7C4BE04EDB87FED4929941F477E18F143 -:106D0000AC534F4A1CBE3DB6900BE1DBBAD91E0016 -:106D1000386AB77E487454F68BED5EC443ED1EC5E9 -:106D2000E4F7ADDDAA841D23A93C8125C65124E0EA -:106D3000EB1AC6E563CDAEC5E40FAF6959F7A1E222 -:106D4000C5EFCDF40C78F18711AF6F28FEE958DF5D -:106D5000F973AF06A8FAA0FD712FE215FA9D634FF3 -:106D6000C278AED98F8DFD7F9A12DB1F63DD76A4CA -:106D7000AFDA96B57C3C0BBF7C80BF64C6C64F9C27 -:106D80000E4B1C6B6BEA79E9898BB69F7D3408E367 -:106D90009DDAF1D74783B87FFFBF8F1EBD13F59AE9 -:106DA0007D2E1FF27BED53AF7959D43E98E3E07C02 -:106DB000D7F9E4CF9F7818F8A4F3B8838EEE75EE78 -:106DC0007D6F8806F3ED7CF6BFD335687FC7DEABF9 -:106DD000C8EEBF6377D9C0BEF643A4D350F43917C9 -:106DE00091C7A4ED9150D902435E94967539B84B82 -:106DF000612E80F3F4314708F39A6BE1D9B2225C3B -:106E0000A7C5247FB1BE1CF05BB36DF587CAC878F7 -:106E1000780E0E9631C79E01BB64E03A5FFBED6FC2 -:106E2000946069A338492DEB26F969FDAEF628ACCC -:106E3000E765BDAFDF59F6B91D8378B5DBD6F271D2 -:106E40002DEB771A7F191BBB7EBA65FDCEB2EA9F88 -:106E50003E8C2F77A5C68DE71AF1AFC5BBFFA54FB6 -:106E6000BDC99003FDE1B752E270791C7A8503F940 -:106E700069C7D34F3C9CC6D7773A20A473FBD9216E -:106E80000CE8E3A4ADFB66948FDD7B1D3EDCCFAB4D -:106E9000F6BE41FCD5B9FB15BB46F291B925D0131E -:106EA0003A59CF4F3BEA0D3512AFD46EF1841DDE57 -:106EB000C83AD58466946B5E7A7E829E8738DDD729 -:106EC00084F65F27C559B7D58E1C2E8F433C696F5A -:106ED000F1963FD899DBBC9ED2185CC71353F0796A -:106EE0006FEB68CCDF87F3BF3C6A3DB7707EED8DFA -:106EF0002F3B373B54CC4730D6B7D3C6F5FDDA909D -:106F0000F4068BC3AFC6FE76A1F1D00687251E2AF4 -:106F1000E6DB1F3FF73F8F0BC3D3124CAA1C1D8B20 -:106F2000AF539FC797EF8F382401475DF9A0DCD896 -:106F3000FD496515C1C1D911784F8973B3A79E5218 -:106F4000424178BEAAE520C969AB5CA8E9454F7EFD -:106F5000C6186FCFFE9128BF4E1D788EE8B066DB55 -:106F6000093BDA4787B7EEB4771446E81EE57F742D -:106F70005EE4A967F68F24398DFDC7599F5F0B79B1 -:106F800057DB6AEEBF76DB87A6FE17055BECE417DE -:106F9000ED679C0F54FD069CEF07ED368679F71FD1 -:106FA000B428E5F1F49B90C366CA835AE5293D866F -:106FB0007E4525C5AEA1BC6B5AA1BF11A4738F3607 -:106FC0007EEE51D58F39802F1B93ED1ADAAB4D9E93 -:106FD000EB991625B79B2DF8F4A5F926625CCD3701 -:106FE000B9A224DA7E32E04FD66513FC7778CA075F -:106FF000E27909B4C3344C3250FDE45756BC53CA4D -:10700000713E8A4FF6B9E2EECFBC3FF4B721FDDB0B -:107010007C32D3A2E86B54D9F5C3D1D5A632CD9436 -:10702000BF7AEF641EC735E67FEF456C1303B97B6B -:10703000AFD4DD86F9ECC1AB795E201376BA17EDDB -:10704000F4EC587D8EE9BA86F287C40F6FCF7423B3 -:107050007F147EBE0FE0C898BF23FB4999FFBEA2F4 -:10706000533E8F1DC7CD45FB2944CF135998EA8A5B -:1070700093CB1F0FABA3E749ACA319CF30BDEDA84D -:10708000F8D401CFEF2B4F9138DC61CAD74816E313 -:10709000C88959997DF13F9BAC9E8AF6FB38D8266A -:1070A000B24BD0EDF8456A040F463E9CD1EFBDAE21 -:1070B0000912EE3738BFC178AE479C9FF7F5CC5721 -:1070C000A7FA00A36E19075BFA4AC5164BAC1890D5 -:1070D00054056F0D68263FC720D64265166BA73250 -:1070E000C5E9935482EF2DF24BC9ECCFEC8B440BE6 -:1070F0007CE7A18F9F93F5E301281B6DE2F9DB9EEE -:10710000D0E350DF90CC4CE783739D9CBF2F77CAB0 -:10711000865F26106D7735B26A9ABB2B8D1F63315F -:10712000BEBBDE1918EE8CA227C5DDCEF3BE84FDF2 -:107130006BD8EB5729CB29FEBE3A83DBD5BDADCF4B -:10714000CAFA0A935D6D2D9B0738E76C66043FF71A -:1071500053494E7E7E59679A2F9AFE605C67697428 -:107160003EA3AE937D2FDEDB607AF8D28178546245 -:10717000E96F06D2DF68A4BF0ED14937F9296E57EF -:107180000257E37C33F2EA24FE3C2071BF97AEE065 -:107190007CD345FF72627566A08F79B259401F514A -:1071A000792D1B84FDA8AA4C4D284278368975B7E5 -:1071B000D2A5393FD5D0D7DCA2E6107972BF2979A4 -:1071C00095CEA3A8696ECA4F719734DD8EE77C55C2 -:1071D00056E743F9E936F24FFC3C9FD0B08B5D0592 -:1071E000E63C4E87256FD526ECEF983C6EB1EFDE7E -:1071F000830FE2E8C3D67DF77667FC3C2436267E13 -:10720000BEA0A1879D2FDD5BEDC86A67FB611ADC1C -:10721000A7539EA52AFC0D13AFF3911FBC6B9BC413 -:10722000CFAD59E8A86B47D2489487C8BF78CF45FF -:10723000A2782E6DDBBF1FF5A6262FD3935348CE21 -:10724000694A2E9E971AE594A05CBCEBC3977F8D8C -:10725000FEF55685E1D6DCE536E2937A322E5622EB -:107260005B6F5ADF0B9D4F6C5C91F3DB129FC16F1C -:107270006EFAFECC3689CE4F296CF88FF1FC436D47 -:107280009B8D85E0FD19C6FB3FB389EB030B5F8443 -:1072900051F03CA8181FF7A5E8FD23B53C8169D142 -:1072A000793C41BD1DCFFFCF13F8185091627AFF92 -:1072B000D7B9E56DE49F09F07B0006CE1A64EA6F4A -:1072C00091B27C2825E1093F8606FF90FE8CF99F4C -:1072D000930376BE4F542485499F01FB17ED86909A -:1072E00044F94A567F47CD1E89F6A7DB607FC2F37B -:1072F00038B7852CF6A3258FCEC0B7952E0F3985CC -:107300007DE066EE5EF0EA0F97507C94F86AC98BD8 -:107310003C2F6CC976294479CC1D439318E159213F -:10732000BFD17BACEE41D83922F46BC19B23C38C17 -:10733000679766C673628119AF1EBF198F563C27C7 -:107340008DC931B55FA454DB89C8049E0BE01FE2F0 -:1073500019E420CDA306E611D662F159D97AEF2AB5 -:10736000F46FF48B470BFE4E59F07796B5EEE76F4E -:107370005985339D589BE69DA986897FACFC66E0C4 -:1073800029CBD73E919EF93DE42FCE109D48F3F8CE -:1073900077839C2D9C798AFCC46F467E7062CF7E79 -:1073A000F90EFB02CAA5330E9D98CB62F96B1396BA -:1073B000C0D72DF54EDFBC7C8C4F33DF3C1BC6ABFA -:1073C0007D54C6D947A97FA047DA0FEEC1B8641A29 -:1073D000F2B54AF12B5CAAE9504F6CB5F9D06F7940 -:1073E0004F51F735A8B7D7CEE7798E372770FFEB27 -:1073F0009204BEBFDA12785EF35D1532D3D1BE6F50 -:10740000554212FA8B7CFA8B57A2DED56AD3685F9D -:10741000F375BFFC1D7A5FECC3F86EA6DC3C0AE195 -:1074200080F6E46FEF6A7DC77B6B94BED3B9E7FE4D -:1074300061B8EF3C24B3CA787A7CBE8BC3D159F0D3 -:10744000E77424C7C5CE6EB2A35777D455E0BC0C01 -:107450003BC2BE8BFBB76AF6CC207DF2D0027E1E0B -:1074600073F7297E1E738A32FB9B23A03EF6359567 -:10747000CB4DA64F9F93CE5328701D3760BE24F28C -:10748000C17FC9A106C24FF3EF314ED5F81795A1C0 -:10749000FE5852B780F69F5F7BA7B46159AAB71414 -:1074A000235F4F6E4D9E88E7646ADFE27995A3DB28 -:1074B000CDFE1CA6541F443FD8D9637C5BBEFC980C -:1074C0006AB5BB14DC8FC776989F8FEF876ECB5C55 -:1074D000623FF2B2F40BC98BFD91AC4F73917F9474 -:1074E0009FE3F2ABF1EDA74713B87D037891504EBF -:1074F0007575337F03E0A96BDE209A6FD7C7FC6AEE -:10750000A6AECF95F278F6D12D2E4E2F0FD979DC7D -:10751000F6A105EED00A98C781055517A35DF4C9F9 -:10752000BF052E8E17A788D8072C49A63D4F4F625E -:1075300063902F9AF8F932D69C19EFFCBCC10F0664 -:107540007F187C91B9202110CF7FF98E8BCF6FD21D -:107550008202CA83EDDC27518CA7B301E0EA038FD6 -:1075600041D63018E1A9DDF311F9179CADF1FDD03A -:10757000F5784803E9B621B8623CE0EB7BC0D44122 -:10758000E4077B7376BCFE836C03F99B16B834E288 -:10759000B74E27B7A399DA9C39D3837C5276F52A64 -:1075A00080F361E03F24F9876C7E823BB89831F22A -:1075B000AFAA9CFFB3AE619BEF8AB2B7D6BA263EA4 -:1075C000E082FE1E70F178476AC02F21DCFEBF9F6B -:1075D000F362FF5D9F3A68FD06093F8FF15D8BC046 -:1075E0004F5982FE23FC9E55A69130F407BCBE790C -:1075F000B0FF5FB607F01D27BFCBD077520220FB4C -:10760000009E14B74CE756D0DE427BA296193F414C -:10761000523E0DFEC34366783ECB90B752AB14F694 -:1076200080DC2C71BAC3E84F49A98479633C8A395C -:10763000797FED667D14252FCA5D94013C599EDB50 -:107640003B861C36E477533297834DF7AAA146094F -:10765000D3DF3B5CE83FCED6B549985A95A26A94F1 -:10766000E7705125F3075148E63E92DCA3F78C679B -:10767000ECD9BF2B71FD1B275DDC1E294B08FC0AD2 -:10768000F135B2ADFB00AA4F7E174BC5F59E22F433 -:107690009BB1A7B93C32F2FA6B85BD619547CF012A -:1076A0009DA3C018FB0DBEEF8D3DEDF623FDF4C884 -:1076B000A10553681F2D6A2D3E88F939456F717EEB -:1076C0006442FE80F54678296D0B2A880FABDCE911 -:1076D0004FDE18F2C4BACEA05CF7D4B30029C56D52 -:1076E000C06751FBB7554E1D7389FD55C8A9B36CD2 -:1076F000C2C0ABB4083D152DF31F7444D18F21A730 -:1077000022F414223AB48E2331674FDD978BF2E5D1 -:1077100088827E90AE893C3EB942F051F2C7A1AB5F -:1077200071FE1B5AA7BA90EE77B4953991AD966465 -:10773000F0735EEAFEEB824C904F745CD7C69C1AE5 -:107740009E291F0F2B8FF8507C508F9AD79966492E -:107750009C73D492AE8B733F82512EC9E0E7B8760A -:10776000B4E524713B334CEBDE43F7C20F61F08587 -:1077700041EF56FA36F8A19171BF84A13F28528B90 -:10778000B00BCD7E8146C3CF1174519CF80EA10F72 -:1077900036BA2F5937017E6D0A4FF2615CE20E4F07 -:1077A0000EE533DF3180E3CD8A07A3ACFD14F4C3CB -:1077B000A8BCF35AB59BFC5AB59FDA4DCF0DBCF669 -:1077C000860F03AFE310AFD297C7EBA7B8BEA36392 -:1077D000F1FB65E79DB5644CDCF372FF57E63D9E17 -:1077E000057EDD4176173FB761D097212F4A976E0E -:1077F000CC24E26837DFEB65C891317BEA0EA28AC0 -:1078000068951397B5B26B114F63C32AC3A32EFDBE -:10781000C98D8FF1974C3A7F716302F0DFA817662C -:107820002DDA068F466A2C753A0035B25D2539C6C9 -:10783000DACF2F0ED512FE381DFD8B865E1A8357C8 -:10784000A1971AFB8B11075A9710A8C4F1A53DC048 -:10785000375ECC3FE5F6EE5A57605102B44F0498BC -:107860001330D7AE209CCDED53335FF6C687891613 -:107870003E6B01BCD03904D8E7F2A558388CF1F33F -:107880001292399C406DA8BF6495323E580DBFCF0F -:107890002E6B240BE03E8CC736719E6B85FE759770 -:1078A000A55CEBAA68C079D9541674147D79B80D1B -:1078B000BFE0BA043D88F87096EB348FC13EE647CE -:1078C000BD7EB0DA22F9018E946A4DEA71D618FBBA -:1078D000379EFB99AE4D44BA189CC7E83CEC60D487 -:1078E00083E2ACCFA6041EAF5DECEC388C21F3DA5A -:1078F000E975E5DE3EE2D3917B06FCC24F65CEC35F -:10790000E8DAFBC64518977CFBDF3FF260DCE94F05 -:107910006AB707E13CB9FCF71EBCBFE5EDE5DCCE7C -:10792000B8D9A2CFEC14F84B4EAC780AF1774BFDE6 -:10793000DF4BA3F99D2DE37194DB420A1A9D3DF4C0 -:10794000BD686B22F9E68CFAE2965453DDA0D3C5EC -:107950000E9E27659DFFFBC28EBA6DDB66FB600D38 -:10796000C70FB422BE4F0A7DEDE42E0FF9330C7819 -:10797000E66E1B65473CFCA9D521E2F0ED368E7F13 -:107980007D3AC6CF026229AC701EDE9748FDCD7FDE -:107990004021FD620E8CB50CE83BD07A1BD9D9D6BC -:1079A00079CC7F5B9B3210D66FFE5A89F4526CBF44 -:1079B0001CE821B06C35C5D9ACF39C13B4C6339721 -:1079C000939D6ECDF398C7B47513B2E3E47BB4F224 -:1079D00038F9C27EEC9A3F26087DA1945D8EF9E8C5 -:1079E0006759E18F0AB5FEED9A93F58C92B43EA8E3 -:1079F000775279AADE47E553091A8F67EFD97F9846 -:107A0000E84B6D2F457EDFD1F64EE24D5A446E5F56 -:107A1000B1F9A3833F817A31E3FE1BC33F3E5BE0B4 -:107A2000FB4A21BF170A7DA0F8D3BEE5F76C9CEF97 -:107A3000C858780DB93D1BEF958DC28321C7ADF8AD -:107A400038D3969B887421255AE3C05F0D2FBD7DE6 -:107A5000B758899F3768F0CF53C21F306FCB8C5512 -:107A60008360FCC6BDEF0DE1F702B3A3281F0CFA3B -:107A7000B4D21F637576E4E71E3A6BBD9BF063D00A -:107A800005F05186883F66A0DD67A5B7FEF2893A0A -:107A90006D1D43500E58E9AB536271EF154D4DE427 -:107AA000FEF2799A3E05ED50D85E56F1381D973FAB -:107AB00027D5E6C377227F6EE1FCB1F857DB7F89DB -:107AC00072A7EA170F7851EEBCAF36A7E378D58FCF -:107AD000AFF4629CFBA41AF4E2F7EF8794B87985BF -:107AE0000B1325E10F37E72BB035C16B906F3F7952 -:107AF000DCE6433F43ED56078F83EFE278833A8F0E -:107B00007FEF8A9FAF50F5F307D2359EC76ACE5BF1 -:107B1000D862A3FC13F497E130BDC5717BE2C22D9E -:107B20007DC7B76B77AD8B9B7762E40758E9F606A4 -:107B30000BBD025EC88E09023CE4161771EBC62726 -:107B40007F3CF204C0756ACB6FBD5261B4DF9CC745 -:107B5000C7CFB4DCFA530CF1F446AF9D82BE237A52 -:107B600043286E1E43B52DEC453BBC7AB38DECBA71 -:107B7000EAED0A73623ECB7107EDDB8BB6FFE6F5EB -:107B80007100DFA2676D69D3F934285FC158A79EE1 -:107B90003C12B12E553B7FC3E3BD9AC82711EBB30E -:107BA000E8D9FD76CC8BB1E2B1AC65BFBDC3928F95 -:107BB00040EBD472620A9DCB7BF29C1DF7D3F7F7A2 -:107BC0004974BFB2F5FBCACDBFF1A27C403C515C09 -:107BD0005EAC57EFF942E16B9E2FA176E487EB6D27 -:107BE000FDC6E0DE3A9AE8FB99E761FCCA371D94CE -:107BF000AF54F9CC52CAEF794FADE374FEC8CA74E2 -:107C0000DC5F2B6DC1741F95FC79E5A3DF25FA5B62 -:107C1000F8CA77D3F9791E3D93FB6D829938BFF985 -:107C20009BFE85E6B7800588FE2A1F512AD05F7229 -:107C30005665E5CFC6E1933F093E79EF310706511E -:107C4000D97BC26F197C5511F7FE5AE349FCBE95EA -:107C5000B3C28EDE95281BF71439A3EDAADA2DAB3B -:107C6000DB717D3EB8481FE8A3B8BE1A14F89248ED -:107C70001F7FE5AA81428ED13D31869E5386CFB1CA -:107C80007DBB8DEE8B89FACE74DFCB1D627C803B91 -:107C900041BA0CCAF4F8FE4C8F5B32E0E3F92F06D0 -:107CA0007DF5C6F75B783EC9C747B95CC1BC187A99 -:107CB000DF6E0B0F34E5C3384CF78944F23D6C821C -:107CC000AFCDEF014ECA57E9C1EF3E89E2AC0B36AA -:107CD00038CC79703D7463BDE7C69CBFB2D0A26F4B -:107CE00019A5552EBC69910B6CD3F9E5AF54DB4255 -:107CF0009477547DDC41F643F5765B05E2E3AFDB38 -:107D00000EBE7E13D0F95F5B0CBE35CB572BDF5612 -:107D1000EE18CDE2F1ED5FDD7E16976FE1795CBE86 -:107D20007547E2111AFBFAE4EBC25EE4ABE28ED1D6 -:107D30000792302FF783A7165D4C7E060B5E0DB9B8 -:107D40006A95978F246AFCFE8298BC3ABE9F47F2E0 -:107D50001D39FE0C7AAC7A7A318DD343B7065D1AA1 -:107D600074DB4B9E96158FD6F72FA23C1A10EBCFE3 -:107D7000084E620578AF5EA39D15A0FF392827F84D -:107D80001FCF8E93D7C1EA86A29ED1E8CE8E9B9F4D -:107D9000EB77FBD08CC573654ABC78B7BF4C8EAB14 -:107DA000C797B8B95CD98BB40065B59BE3AD49C43E -:107DB00057C012A4BC7FF429123F257B899F6CF029 -:107DC0009CD1B94A3F9DDBF627CA1F69A08255B8EE -:107DD000B5292AFA538BE5A5B9505FE82EE6F5F1EF -:107DE000F2CE1CA8DFE62EE1F5CBE4621B90E61391 -:107DF0006CF494C950AF31E6392FC9E4DF50E51374 -:107E00000F62DC457D9EDF17B70EF8DA591489F74B -:107E1000263A58D05584F7344209F555D9BF5F85C5 -:107E200046E00647E01A37C9A3491AE2F594CF495C -:107E3000F932773C7715E56756BBB9DF78F8CEF1B4 -:107E400074FFEED730FECDEE01BD8FDF64E3FD9C05 -:107E5000DA31BC0CF13AFC62467E0803FF45AA46C3 -:107E6000CF5D2D78F494F83F03CF7F3426DBA99FB4 -:107E7000EA9EF53ABFB251E43528899C0E9424B9A4 -:107E8000EE5928978AF5BF43E0037FD05EEEDA3BD8 -:107E9000F0317EDF53F7105C5F4539F347D41BBBED -:107EA000FF35D18FE757DE4CE0F8BA2169BDED52BE -:107EB000A81739872C45A27E53DAF65D2CBFED0951 -:107EC000FC90E39F85B1BF9B6E56787FEE3A0FDE44 -:107ED0009F26E95C8F96806866031E1A75A6D97383 -:107EE0009145CDF9168A52D41DA6713DA671591639 -:107EF000EC83B04E378CE5EB0438A57DF18D31BCB9 -:107F00003E2B94D3D8A1111CF7201CA31CA18BD00D -:107F1000FEB909D4224ED766FBDB88D3D7FE4526AF -:107F20003BB356D21ADD50DFF91623B9DC99E015C0 -:107F3000F907FCDE19C32F31F6A5B965B864257BB6 -:107F400016F13C0EE18732E2E86759AB829389F182 -:107F5000535BE4E178B69EE4647FF1B19FBB457C5E -:107F60006C101B7481F1B167DCE7111FBBC86DE8B1 -:107F7000F322DE2EF6FF334772285F485531278FF4 -:107F800031BBA6508A88F1DD2E8BFC35E878C451D0 -:107F9000DFAD88971147D92DDC5EEA253FE224A3A7 -:107FA000BCE6511D05941F61B3E6471C9329E1A966 -:107FB000F4C5620DF1D924E2C6171AB737E2FEC53F -:107FC000FC514C1CFF796F39C5418B7DF1E3F8E31F -:107FD00094D914776047F8FA19717CA6142A08E737 -:107FE000D930D86008E751F3DF01B93C2DA8505AC9 -:107FF000CD5BE6E7E32C74605DEFBF58D7FB7CF305 -:1080000020DEE7F7AA8D6223290FC226F2207EC95F -:1080100002F747E7411878EC2FCFC49A5762CD2377 -:10802000C90C98F134B8F252D3FB8BEA8A4CF58B29 -:10803000978D33B5CF868D30BA9EBB669AA97D7E6B -:10804000F34C537DE8C69B4CED8785E69ADE0FDF47 -:108050005AD5E7BA8F6859627AAFC8A162BC0FD20D -:1080600058F7CBF6FC202E5D18EB6EE46961BA116F -:10807000E27734ACFBC3D9E43F2A93B4D8F5F78751 -:1080800083B42F5FE8FAE77B843E7481FC3E0A8963 -:108090000DE3443AD713BB6CEE35A81727036C28C1 -:1080A0006FADFA4572EB0BFF2D79E3E55B682B9022 -:1080B0008EBEAFE86371BF1F20F2239B64719E7474 -:1080C0009293F4817B64F996E87BE4AFF0703972A7 -:1080D0008587FB557E02FB26EE9383135990F64F5E -:1080E00071BE9CA1430AE6EB4D65E2FCF963AB2649 -:1080F0004FC078664781968C2205EADF88C8FD9BD1 -:108100001C5A23C60346295C8E837C9FE6198DFB8F -:10811000CE721BD77F8236C4F360270B7A8B68DF61 -:10812000A3B866324B939614A2E9D5B3BF685F003B -:10813000311CAC1A9E8476D0CB383406699D09B4C4 -:10814000FFDF68C8BDCA6124F7CEB87BEEB5A0F3E7 -:108150008E67E6E5D2F3E33703D701FF1CB79BED4B -:10816000A2FEFC53959BEFF7A0FFFF780133E519C2 -:10817000547BB81D55ED5178BC3CF49774444BD7F3 -:10818000FCCF2E41A06BA5F65528A2576FBCBD822F -:10819000F27677CD08A2FFCFF03B1BFDD4B64E643C -:1081A0003DF707433F37BCC1FD5F377C66F6E7DE2E -:1081B000E9E179D7778AF1AE87C20778BB1EEFF481 -:1081C000C6F2850953901FE0795882FAB7DB40F573 -:1081D00003BA9F11C8B6213CBF67FED7764B98AF54 -:1081E000ADD1F7D7B10A1BC2F5FACD8B3DD8AEA7FA -:1081F0003FA39FC178A613F6E9E4A02D1DE8A7FBD5 -:108200001B12EDEB309E139F57CC1EBC12B70E63B2 -:10821000BCD759E0F46BB0DE33999FFA35FA672C7E -:10822000C1240777542EFA536A0ECA3F99FC1F4B9C -:10823000F63A48FE75559DDBFE20BCBF6570C7450C -:10824000A85FBC59F5D92588971B372A4C83F50FB1 -:108250002504EEF344E1EDF8BC8F3CF81EF484C72E -:108260001FC44DFE69079DF37AB3EAE94BA2F5EA14 -:108270004D9E893FF6E03E39E6FCE23D654F0D2319 -:108280007BDBA0AFDB047D2D797228E9834B3CE6D4 -:108290007B53963C9E4BE7894A2516D78EC47B3F7D -:1082A000302F7D07D0159E23DCF729CF1FDF7924DF -:1082B000A598CEA3B2C07684CF68BFF3E59B865362 -:1082C0005EE7B1B4F3BB1719E00BA27EC5389C2F53 -:1082D00009FE98D59A5A2CF4BBE7106F37FDFAC9FE -:1082E000D37F40FCEC7DFAF13BB14DC9F9E18389C4 -:1082F0007DCC2FF000FB18D93F5D2CC1EF8863FFC8 -:108300003C2BF4AFEFCB3AD925E7E40A91BFCEED91 -:108310001045F667601E774BAB928878F3A2C16276 -:10832000C817D009BD78FFA2B83FDD09F6D9702182 -:108330007FDA3D1F4F69E27108935E5772A8CAA4A5 -:10834000CF55C03F94F7976F0A34E23D8DBDEA7573 -:108350006199ECE12FABDFBDF325E57DA787F37FC6 -:108360004B0197DF2DE18410B71B5831EA7BCFE03A -:108370005CE0FDB464BE2FD8A5CE0227FC7EC6F318 -:10838000C9AA3559B0DC791C1F58C7BFD3C3DA3826 -:108390009DF6E87F872EE57F674E9C032E11E7A2AE -:1083A00063EC49E02BBEC92698F4C7F0E1BFD13990 -:1083B00097ED29DAEFC6A33E0F7A0AF2BD4BEDB076 -:1083C00027C799DF2F517E027D8FF572FBC4B987D5 -:1083D000C7E19C9A4EF79EB97CBE51682F19ED4FAC -:1083E00089FD66F1E13787D8619D4ECB47BC1847C0 -:1083F000A8DEBDC38B66F2658981242FC64B8EBF74 -:108400005AEAA37CABCD43D0AE6D09F3F8C408950E -:1084100005D538F735D76E2CA64BBF6B36A652392B -:108420000CFD09F0A836CCE7D9B9A731259EBD5D72 -:10843000FB1F7B07E1BA3D3D809F971AD15ABC10C4 -:10844000E51FC2620339F7D4A7C3A9BF4BBCD93417 -:108450003F185FC5E7209164BCEFE86961AF757EA6 -:10846000AA503BA3DF117B262A3E58CBC270F301F2 -:10847000B20F5B1D1AAEB36B0BBF0FCED5EA22B99C -:1084800057BB6F2AB7E39279DC737B42F71FC5397C -:1084900036FABB042E5F334B81FEB7DBF9FE380C96 -:1084A0001860873BF2DC18CFD5FA634A6A77E6F1A9 -:1084B0007BF55C6A33FB863B1AEF1EC2FB542FA789 -:1084C000ABED096119F376BA81261F23B822703209 -:1084D0001AD7807318E9F3DBEDDDEFE2F94B3A5F71 -:1084E000A7211C1C4ED63A5443BDC2E5E3F15B976D -:1084F0004FF307A558B86A47829E0BFC764F038B53 -:10850000FC7D04CC634B88D49DC013DB739890072B -:10851000C3564FCE8AAE83401A13F97EF63DC35739 -:10852000374D203B27A8A05D0FA52705E7C9F737E2 -:10853000BCBF604011C703FA89139DFC7D4F7B27A8 -:10854000BFB24475F376FE245FE23489F5DC676AD6 -:10855000F89DEE90C2EF5E89FEADF081911AC05297 -:10856000FDC2F344B78BE4D6074768782E31B000DC -:10857000E9F5576FC90CEF47FAE049179D432E788C -:108580006E33F9ABADFDAD3ED6701FE665773D2786 -:10859000699807DA65EBA6B8514DEB7B745E71EA1A -:1085A0009E13746E4B490AD47947635EC48A32C401 -:1085B000DF58D6DC88FE3D908714A76FC9E0F2E350 -:1085C000CCD14B1E5B1185EF07BDC2BFDB1DB818B8 -:1085D000F9A655F0E73ED46FA0DC2DF4ACDDFB6FBF -:1085E000CC8D3E87156407C81FD6C00E517EA1F101 -:1085F000BC2BA4D239B0E1AF3B6FD1A3E8AD59F0A9 -:108600007BB3182F3F29B08AF876FF9FED5E0DF3FC -:10861000585B86A0DC6D013DACAF7CC65A0BDFF425 -:10862000E4B79CE4F771C3BA3625C13A3DFDFA9E22 -:108630004BF1EF8B00FC8CEEAB3AEE20B9B93B9BD3 -:10864000F3DF8AD73E198972EB93BD8B2E467C2DC2 -:10865000F3DA0C3A9F9480FCF42C233966F0632102 -:10866000F2A384F742713F4A21D239F29FBD7D1AAD -:10867000F1DF6E7E2F04D039D13DD0B90FF58B429A -:108680001FD03D7D3F94F8797BBBCCCF81831CCF3D -:10869000A7FA24CA57D9DE3ED947FC2C036A8B902F -:1086A0002FC307A89F16FADB75ACC4729FEB294C49 -:1086B000D21810918F7FF3703E6D29D092FC309FBD -:1086C000444531F141D43EC9EB621F957F74D3EA32 -:1086D0000DF8F7C3DAC5BE20F4AE7D42CF65C7B84A -:1086E000BC5F2AF6B225BF19F7ED6D30DF252F29C3 -:1086F0005CFE0B3A3920F4E043F51954C7FD428380 -:10870000751A0D25DE0754AAD7E19F2F6163CA9B16 -:108710000F6239AEA2A50C8F4C4D98D57E909F610B -:10872000D38723FDED3A70F570CADF3DEE6098A265 -:10873000B8EB6FDD7F7C0AF351F701FEE3EC4BE809 -:108740009F6514BFA9207AEC8D6EBAA48E6BC6FB10 -:10875000410FBCA77AAA0A1B7D0D1206E0E3F57B48 -:10876000AA56E3BD803725E9C7911E97FB02C79142 -:108770008FBA5EF95B3ACAF4DD47FFEC4579BFCBAF -:10878000AE0F473ADB9503F6401CFA3C2CE8A7A451 -:1087900097BC8ACFBCDC5EBA24C8D621FDD4EC528B -:1087A000E8EF169CDEA5E8780EFB5D3D908E7ACE54 -:1087B0004916BC7E3CEEEFC2AE9DCFD1CEE6A3DE25 -:1087C0003292EECB30D9994C592ED33DEFAD12F900 -:1087D000272A2D7A48356B5E3518F78DD6CD769CD5 -:1087E00047D516F3F7D5A8BF8CC4B26F7BF533AF6E -:1087F000D05F72592EEA2F403FE49FE87E4DF13F53 -:10880000C628BFA70DF37B9E96397E405E121F1AC5 -:108810007ACC569F7E1AF5CAD3824EB70B7BB47BB7 -:10882000BB44F9FDC3B6F2BCEB7127B5CD8CCF9F2D -:10883000F2C22A851C1CA7F2F8C5B8A3B9140F1DF3 -:10884000A333F2872C68954288C74A43AF13E729C0 -:1088500060DB25BD6E2C0B35E2FD720BB74A740E42 -:1088600063D156B3FFBE7AE32B87D13C5CDC62391F -:108870001F2FF0628D6FECC05FE2C4372E4E12FEE8 -:108880009C216C88E9BC55DBF99DB7FAAB387FFDBC -:10889000AAE8DF68372189D34D8D986F754809891B -:1088A000BF4FE9C6FCDB5B057DDC2AE8A39685EDBE -:1088B00098BFBF78039F2F5B6F33DD5BBC60D7ED44 -:1088C000741EC14A4795DB78DC0D1048F19DCA4DF6 -:1088D000E6F755021F55167CD404240B5C5CDF8E32 -:1088E00085ABE57A5CDFC5DB6CF4F739AC709D6570 -:1088F000B3298FE81F0D9F759DAE33D6E95276A937 -:10890000699DCAFBBE9F2062DF98F5DF670F5F4A53 -:10891000F92E67DA72C87F60D087B59F29427F9EA3 -:10892000BA91EB99A7F794258E40BBE888EA97A007 -:108930009FE2973EF6E2798FA2BD0AC3B860576BFB -:10894000F13A3CA7BDB32DEF5ABC8FA2E82595F6AE -:108950008DE2978AE85E90A2978A1273298F424B24 -:10896000457C403FB4EF761DC9FB7D21CACFB6C917 -:108970002588E615478A12513FD8C9B83F427AA9DF -:1089800024B5236A1F599CC4FD03AB32DEB907F539 -:10899000F7A9CFDAE8BCC9545BF7CB987FB0B34DE9 -:1089A000F5AF807AF54B731BF09E8AEA27253FAA24 -:1089B000D987DB97A47D07E9ACD5E67310BCDF3D12 -:1089C00080EF83DB247F3EB4AFDD7BD5F0ED98E70D -:1089D000BDB9D81F7D2EBB2859BB1FF32A5966226B -:1089E000D9DF532FB2D17E7A6A50E2CFE83E167DAE -:1089F000F31494B3A79EDF69A77383DB2596011355 -:108A0000399C71F019BADFE397AF50BE42D9AE5727 -:108A1000283FA137797F3AA4B030D9DDCD742FCC6F -:108A2000E2CD46BD83CE415408BDA966CB09AA5705 -:108A3000A1FE0FE3556D52421AFC7A70EFAF28BFCA -:108A4000A1661BCF6F80F7247FAA307EAA45E87C01 -:108A50002EE3743057C89F458CDF33B4A8999FA389 -:108A600033EE4532E87CFEB639948716936F86F66E -:108A700025C5219A89BE63EF1BE2F46DBD77C84A14 -:108A8000DF2D067D0F63C390BE3F99C8F3C33E79C7 -:108A90002521B110E6F3C98B0AE5DDF741E7B49F64 -:108AA0001E11FBFF99B04CFB93D1AE73CF47B48F2F -:108AB000D41E3963477D754AEB87B40ED35BF74FFD -:108AC000463C7F8B05AA116FDF6A4DF4219F4FEF63 -:108AD000E0726B5AAB23847EEA6FB196265CDFAE00 -:108AE0007D3F6F4A417A7982D38B21CF160A7C2E43 -:108AF00014F85CA8F2FB9EAA0AF73F88F9D0D318B5 -:108B00009737D35A84BCD964C66F97AD4525BA1937 -:108B100021B1E6ECD8FD6E11EBA0738F5D99C3E92E -:108B2000EF4906C15E453DAC7A9B350ECEEDFA1A93 -:108B3000CB7E7A30C9F6A5EEC178C7B22ED3BBF989 -:108B40007E360DE809E3216DE18642947B067EAC1A -:108B5000EBD2A6E526F575DEF965A1B71BF56F8B9F -:108B60007B265A7CCDEE683BBCDCC7F5F0AAB14A47 -:108B700010D7B5C75EC93B38529323F60AD8299F50 -:108B8000250DE076CB28E8FA852C85A5A545EC9542 -:108B9000D519F74F2F4AC3FB23B8BCE81C03FD616E -:108BA000BE80CA484ED56E7384D0CEF81F85B75AA2 -:108BB0003D008000000000001F8B08000000000046 -:108BC000000B8D576D6C53E7153EF7C31F8913FBE0 -:108BD0009A78662C34BB31F9202584DB109A40D773 -:108BE000F626A51D83141C58296AABE2B65BD90A88 -:108BF0004E5085281295B889A9D6956942DA7E54D7 -:108C0000EA56DD226D621BAB4C096A9892C8A1A19D -:108C100025E990A0401BD0D659FC60EB9490C0345D -:108C2000D24D95D873DE7B8D1D12B43A528EDFAFD4 -:108C3000F39EF39CE77DDED75D7DFFF29AF544DF7E -:108C4000EDBFEECDC2C6FBA54709B63A94F069DF89 -:108C500020EA20F2449A60FB242343B0ABAF7B139D -:108C6000254423558B4209CCBBA1EAF335B46FF1FF -:108C7000E7E1BCEDFA52212A23EA84D5CBF2FD9D2F -:108C80006AD6CBF33BFB25D386ED3DF99F8ACA52CA -:108C9000A2C981E98AE760576832FE71FFF796A89A -:108CA000D877EA928F6295D8D8322FD0FD442F9290 -:108CB000F3D9A611ED9987F6F04BEDD4800E697FBC -:108CC00039B5C0AF878C0CD6755E540C4B47FF0985 -:108CD0000F513351F7277F1A9E1721BAF6AE64F869 -:108CE0007467FDAB8D683F6FEF9F87F9377F27195A -:108CF00016A6BFF84DA287D0BFED4DCF95ACDFD9FA -:108D0000EB96F89FBEB217F39247FCFA1B687553B7 -:108D10004F39616E0FED1736493FBBAE04E1AF2FFF -:108D2000E5655CC82E581F23DA7E78A6BF24A9F912 -:108D300036F2DBF397D68EE182F1355A69E46A00A8 -:108D40005FEAA8EE96C2F1171F90B0FFE488A2F97F -:108D50002481DBDBDF2AC4E734C058C0FD4526216F -:108D6000CFC973257611E6FD731FC66A89C6F7C1A0 -:108D7000B90F7E5A148187BCD2B14B06DF8F713D8B -:108D800019FFC452A23F0CBE7F2FF30109883A6C31 -:108D90003F8C798B0BE24E23A88238119791C17ECC -:108DA0005D9F2A06DC735C35DE483EAEE36A3668BA -:108DB00014F0637A9FD9315C8D72492745BD64698F -:108DC00058D8DBBC39A1C4EDFA7C1BF96C35B1FE77 -:108DD000299717A44E45E388F3590D45043FBBFB83 -:108DE0009DFACA038EC5FE9B8971419BF79F35DEB4 -:108DF00066EDE0F19B9501B218B72FAD766EEF8E60 -:108E000029F406DABB3F79A9960AF6278E13F5ED09 -:108E1000F24C4599B75DE764115FD7B91BD12AB40D -:108E2000D7D23BAB35B4D7517A3F8F7F180BFC8834 -:108E3000796DF1BEF3F37EBE0829225EE27CE1CFBC -:108E4000A25F3A7EDD7C7B68A3C0A1C7E5D50B217C -:108E500059CC7F554BBCC2E770F2DC7FA3489B8E98 -:108E60005FB812E47AE5EA7DE7B9BB1D3776E0F535 -:108E7000375BF5F34F83078D23AA15429EC7C68A39 -:108E8000EC76C66560DBDFF672DD2EFB88CFC3EEC5 -:108E9000C16DB5C47E138965719CC39B833F5EC65B -:108EA0003890D423E2B2383EC435D17731AAA33FFB -:108EB000397031CAE3C9E32B7E6161FEF2338DEB79 -:108EC000B8FFD86955F0AFF14C93E0DFB13F37956B -:108ED0002DE2C0C908B0DFE4881A677C92234D1FD9 -:108EE000B7635EF24C5B93C4DB9C692A63FD592E29 -:108EF000513C8D7169A44AB473F9FC5C73F09B1CFE -:108F0000021FD02F51CCE10F55CDE0CF8EDE535E46 -:108F1000CE63479F6216F228B7EE90A60A3FBF6560 -:108F2000FE804FDD69C914FC38EAD81D7DC7447E38 -:108F3000DB3D6951EFEE231E67FC8F8E253A28D664 -:108F40005934CF623C3EE62ED461ADD75E480871FD -:108F5000B492B6A4E7D0C39AB024D68D5E4A7C9B67 -:108F6000F932DA9AA8D5EA67CFB3A84DE443928BD9 -:108F700077AF678D3D87BF2AF6873C8265B4353E63 -:108F8000C77838ECF067AD971273C5F379EE3C11F2 -:108F90001D90C18BF3ED1E8DF94F64962C80CEAEE3 -:108FA000777576D3E31ED3BB0CE3A49D2AC2F8FAEF -:108FB0009CDEB640CFA00B71FCB1BEC5DF8C873202 -:108FC00080B4C39CA9731B29EEA145F0B36666FF6C -:108FD00013AC970D6C55E1E76E3AF829EBE0127C83 -:108FE000A9A11AD641524A021278F3EFD31E4D11AD -:108FF000F1DA55AC0777E697D3990FA17F3AF4EFF2 -:1090000034F48F6D77DD670D59E0313A74E9DDB0E6 -:10901000D0CF228A3101BF8277E49DD4DCBDEFF04E -:10902000D77DFB7C7E7F06DF72F5998064A7EB67B6 -:10903000D7E786E6D421E91FF782ACD4453B5F979A -:109040009147BDE2F0CFE74998E5C8C3D3D79A2945 -:10905000673DAD838A22BF8947259B751E7156F8EF -:109060000A747E628124C6776F966C0B5F87EA3E36 -:1090700013F7763273D6CB7CAAE97DEE35716E2D6F -:10908000BA40D17C1D37F89DFBF276FD72F9F2A053 -:10909000CEF981CF428F23C2F27CBE1FD7BBF7E14E -:1090A000869699F5ABA5B38F95238E274DC9B0E76A -:1090B000AAFB96FB4EB1DC7DDDBA2F09272261E0C9 -:1090C0003179F6C6E6A5F0375AF7F70ABE473BEF07 -:1090D000C2DF0A97DF5D81600385A02EB57A2A0B77 -:1090E0003CDE2B4DDC13669D90BF0ADE4BBC3EFB85 -:1090F000F6CB12D78304DE773B2F55AEBFAAB0E67E -:10910000E874849633AF7EAF69CEB9F5D80B590FAA -:10911000A81E8F9995FF5F77BB4F7CD4C075B93679 -:1091200034D2E02DA8DFF8CB38F77C8F0C7C10D53B -:109130004B0AF925BBFC528595A48DEEFD38936F43 -:10914000E3CC37AEF7D10FD63FCD3CE9DD1491F437 -:1091500082FBF3F8F9607581DF897E45CC27355BAA -:10916000F34469619CAF893827D28E3FA26CCDA6AB -:10917000A585E32997B759C1DB9F2CDE19E7739CBE -:10918000E3AD4A0E6F3BFB3A48DC476EDE692FBE0B -:10919000202E6BD067FF06E3939EA98A70C1B9F8B1 -:1091A000A18B737346127C5C4996C27E9BE1F119D8 -:1091B0006EAB9451611FA08CE8275A48CCE3FB5D4D -:1091C0001E37AB9921A941CCB354F072159D15F30C -:1091D0001EA229614D82C0C3B691216C8B3FB38E14 -:1091E000E5A33E9D56984F99A81ABE0A3EB294CC6C -:1091F00055BF7CFE2A5DCDF11393F1B8D91A9F4378 -:10920000AF0FBAE7DCE0B71AD77982EC43E87A907F -:10921000B20A6FF2804A6B14E4F3A04AFE62C47B88 -:10922000745816E77730ABDBAC5F4699BBEE0BACFE -:1092300043BBD974CE295F35CF34E6F3BD138755D0 -:10924000F017E2792ABDEE113866C47E0F73E0C8CC -:10925000BB957495DBA970A5C3679A7A96F779A434 -:10926000DF27DE39B2DF1278FC34ECD433003C83E4 -:10927000F0B3EAA04463D8D758E4E49BF3BF0AAF45 -:10928000BE5023CF77EE31B4690CFD01BFB38E68B9 -:10929000B5C6784999A87C2BF0F5719D8C92883BD6 -:1092A000F8C2D4B5BDE2DDE6D30E2124A3FFA3317D -:1092B00009EF69C934690FC7E32FC9F0FB1AEC182D -:1092C0002F7C57FF3AFCFC5B7CDE255D13785182D6 -:1092D000747E67CCA75F697C6FC83CAFCC81EF1F01 -:1092E000C0EF4957EF2E173BBA71D8DEA8CBA8C7FD -:1092F0009688DFE07A34FA2B9613FC6E284D08BF6F -:1093000097A523D5C2896AAF60BF399E07C86C6133 -:109310009C25B75E7BFC8EBFE922C7F299643E07AD -:1093200020E77EC47500E7C28FB6D5E6D4DBFABC71 -:10933000C84E61BF69392EC8F88A62F805DF6389B3 -:10934000B16658B5CDD47796F0931D7904F279A41F -:10935000781FDCC7F4033C1041865D9A934FAA4402 -:109360005ECCBF9752546CE07144BB4A1D9EEDFA2F -:109370006B914D95B3E33BE94B9CE4FCA665636CB4 -:1093800054DCA33B9B59EF18A7EFE47092F3386DC0 -:10939000B163A9AC2E7019619DBECF67DF93C1BACE -:1093A000A77C7635C79FC303051224D55C9C73F850 -:1093B000685C3FE6B189FAE5EA1FCBE374A0D8C147 -:1093C000073FDF1C1C74D471E9ECFCFF0753B7A7FF -:1093D000EBB00E00000000000000000000000000E4 -:1093E0001F8B080000000000000BFBC6C7C0F0A3E5 -:1093F0001E81C3D1F8E878022F7E7952B10C038226 -:109400005DC1C5C010CBC1C01007C42780F82410AF -:109410006B70323024027112102F00F21702712586 -:10942000101700D5363333301C6663603805C41717 -:1094300081F8061BE9F66B483030EC9241F0396454 -:109440001918D8E4A9EBC7513C78F15A0354FE5BD4 -:109450004D54FE576D06063D4304FF9D2669E627E1 -:1094600001F526033100FBB288BA68030000000052 -:1094700000000000000000001F8B0800000000003A -:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B -:109490004942184248765E1030E01042048A9E49E4 -:1094A0000A8896D2889E165BAB4340823C035A4C96 -:1094B0008F78B2212104083050AC91224E10305ADE -:1094C00068A3A2D216DB8094A2F5F4466BABB53E3E -:1094D00002521E3E68EAA38EF7D4C359FFBFD6CE10 -:1094E000EC3D9909D89E7BEEFDBE7BD2AF2ED65EB9 -:1094F000EF7FFDEFF5AF358AE824F23F117211FEE0 -:10950000683A4C24840C8AA784C85A8F0352A25FFD -:109510002CB4E4C945E972F27F1B61CDEBBCDF7F5F -:1095200021248B90EFF032FA1782FC149E31E6630F -:10953000A424A890AE92783F5308CB6BA2402E0A89 -:10954000F0D55A6E8C53EFF08D2169847CEA64A9C2 -:109550005E458BCA69FA9633DA984F88430817B28A -:10956000F9D45D593D1AD3AB206D14C8EC4E4F921F -:10957000799035848CA7C9FE2122A988CF3FB19E5E -:1095800091363510D2658FE765998492F55B41E796 -:109590000FFD9E13C215381F0F91011E0A87878D7C -:1095A0000409A1EB3AE29F169843E7DF3A5909DA3A -:1095B000A160FB10684C7C061C67E761DEC1F39577 -:1095C00044E3F0EE6A29A4ED9C41916CA0B9A6FC9D -:1095D0002A07292564F3C4BF06C2743E4E3942549B -:1095E000483DC9E7379388BC9F7BC9E5AC3B713FD9 -:1095F00064D8A3F19815615DC67CB7D8E8BC32E9A0 -:109600007E8C17C95E9ADF543E2B0DE663ACCB917E -:10961000629C6680EB0842363638306D9A302B8D6E -:10962000403BD23B1BF677F3C42C718310AF7F64B1 -:10963000E271470F5D6F236FD7AA1D75407D639F51 -:1096400013E1B699C32744049CF7C6D1AED9D1D251 -:10965000FEF308111F966F76D246B00E2F89EECD1D -:10966000871E7ADAE6D2BC6F825AB641EB8F2F534F -:1096700046CBC12E3A4F8FC713B4D3724F80B57704 -:10968000BC2144356C1FF20CA1F55DC6FE4F10E302 -:10969000F0A4FFF7916A42283DFA727A5F8371EC79 -:1096A0006FD88321FADDFDD947AFCDA5FD92934256 -:1096B000702F8C4B965BF68BEC6170B5A9F4DFB420 -:1096C000DC3579FE0C5882FBF327AB016EEB8B5631 -:1096D000B856C35E95B0FD53E9FF2E16D0FE35C5D2 -:1096E00032BECDBCBFF9809AD6BCBB78D6D70AB5FE -:1096F000D4F8E1EEF191AE0C5A59BA05F73B55BDDD -:10970000FA37C65E73CC346E1BF1669E71D37F5CF4 -:1097100045AE423ABF44FB4F1B82D71CB3E1BA456A -:1097200033BF49557F2DC78F3E3CCBA7F8518AFBED -:1097300019B86174FCFB4B8017400F7A25F231A4F5 -:1097400045BADEE6AB49AF44F7A3A958D1D65038A5 -:10975000D855A54BF0B1317B01BFE01FB4A9BDA81E -:10976000B95B180399EF58F860CBE07F0D760D30A8 -:10977000BFC47DF8A2F0EB02F85D11879F9D54A74E -:1097800075C17E5707103E5E3E8F7557AFD4BAE85D -:109790007AD6657F3F749298E07815A3B3BEF9E45A -:1097A0004489797C83BEAE14422F027C2425F85A6A -:1097B00098C2834C52827B93AC4B16185F89C3D9F5 -:1097C0002113034E80BF87F5C00D5E9C52B5C304C4 -:1097D000677BE0F867003F399374B9C7E0F7263933 -:1097E0009DF2AF4CA2BBD3B01719F29F917CA44F4E -:1097F0005A3E452903BE302D18A6E334DBF878EA3B -:109800006ACBBE7EC6F7355EAE07FED9526EC3FE8A -:109810009ABD9C6FA88D38BF7EEDFDAC7DE27AFFCE -:10982000027C743CD45339FE340640DE3886344F13 -:109830003F02701F51D73917D6A8128483C1FFA9E0 -:109840000024508FCA87CFA09D43AB46B8DB73423C -:10985000248C70B3CAD3947C39418EF6C32795E625 -:109860008D3E0AE0BF392AD21B4994DF3C0D0DBB67 -:109870002C39D8984057B4ABA47266B4C0F82DD137 -:109880003371FDB281075C3FB019E0D8CEE859E5ED -:10989000E32A301FCA0F9D248A9DBB29A643DE4BB5 -:1098A000EA30FF49A8AC4B00BC91C97AE073F6904E -:1098B00048F4FCFEE36FE6F224D53A364F4C2E070F -:1098C00086094C0E489E3ABE1FB7A84067821E26E6 -:1098D0001781DE4884CBBF20EEF7BA867AF20E5DA0 -:1098E0008CEBE87544A3F823E7D48542B49D04B417 -:1098F000485934F194B3540E6A66FCEADB47B21A55 -:10990000FBB351B0C03A6D1EC71C320652F5064C6F -:109910004B46DD0EF4614B9B560FAA1CC59B4A01BA -:10992000C67724C72BE2A1443A11F35A75D2F1F855 -:109930007EF37A29F1AB0F3F8CF56A4AB5B73FDE6B -:10994000B8CA5501488166BB613E83F96C06879BA6 -:10995000978B6360DF22D387D3FD19DC3307E59350 -:10996000F78DEBCEC3BAD696969D00152E2DA8DEA8 -:10997000308DEEA7AB840800EFF5D0D924E8E18460 -:109980005E09721DFE994DC8B7856743BA87A18FDE -:1099900055DF1435D9E027E280FA8B70D1DEBF7D28 -:1099A0004AFE4C4CF483727CC5E5E94BB7B0F174C8 -:1099B000FA3FA03B7F823C4D0B99FA25001FEB3804 -:1099C000EB006F10BECBFF5BC653C93687067A47E4 -:1099D00091A846E9D86944F5535E4C5C536402F2A1 -:1099E00044CDE9D5617B2FB52F6B09998E7C94D23C -:1099F000AD19CF77723E10A869CA6FA6FD7E52EEF0 -:109A000009021F184CD966467AFFF56C4CD0B33763 -:109A100096EE46FED848F1A800F4FD5211F5A1F5E6 -:109A2000454FA86679F57383DFF4C30FA2C915C843 -:109A30003A08A1F0918AC49073CC3F8E1F897AD2E4 -:109A4000E5E287FB16EB7E7CD1FDFA759FFE7D7902 -:109A5000F8F18F8E67EC6B2ABE45F715F5EF166DA2 -:109A6000D680FA4BFF7DDD86FBEA2A22A1647CB812 -:109A70005B10ACF2C99C9AE507B9D3B25FB6C2AF2E -:109A800007760F000F5B49829CE4FD3AEB25ED342D -:109A9000E8B1B28AF2C8B01FD66BDB74D0E73FC919 -:109AA000214CDF8B2CEF12400F2A22A807410722FE -:109AB000CD3BB5507483C0F01FF6C5D06F6C541DFC -:109AC00033C357525D963C99AD0BE6F93BEB159CC1 -:109AD0008703C603BAF4D00E69BF520EE972A2FE24 -:109AE000C9E60F43313BFE9ECBC203035F01AC0CC2 -:109AF0005FADED9A036524D9FEF51BEF26EB7C5391 -:109B0000F2A5C4761E593B63D24752B793C9199345 -:109B10005E33B4CF7FA11BFADC2181EA858D81AF52 -:109B2000EB386FF80F95AF2D905279260DA9226171 -:109B30000DE4A4C6E8444B67F2B743B0D8E1C6F7DA -:109B4000D4F360E3C56EA7B8087C4DD62CFA7262D8 -:109B5000DAD810F8924C91D25DFFF024791C55624E -:109B600057876657D3FAEB1B3A26C177A3DE54D149 -:109B7000B0BFA9D834E9C732A1F51CF8955C1C0721 -:109B80001F55A299E4BB83746239FDCAF78FE03E8A -:109B9000A05E45BBAC1335EC572187B01E7404F5AD -:109BA00028179F2497B0EE20BFD1160AE1BCE488A5 -:109BB0006305A5BB8D4E9ED778DECFF32ACFE7F3A2 -:109BC0003C951390772B344F53A72DA262DEC5F33B -:109BD000F93C9FCEF37E9E2FE079611BE6372AACDD -:109BE000BF0D7294F5EFE2798DE7D3795EE5F90266 -:109BF0009E27BBD9F8769677D9A2AC7F37CFE7F30B -:109C00007C06CFFB79BE90E785DD984FB57FAEA28D -:109C10000E06A73EBED019CFA3F0E070EDCB77259E -:109C2000E419BE64080C0F635F35F02688FC917858 -:109C30007291DE86F0368DF3CAD877EE47317D3FDC -:109C4000A15139F749584439996ABEDFE7FC743BA2 -:109C5000E8B934DDDAA062BAA521807AEFA6068DD4 -:109C6000FB554AF0FBFA8620E6D7354CC0746D43AD -:109C700008BF37364CC7FC630DD598EF68988DE95F -:109C8000BE8630A67B1A1660BABBA10ED328D57744 -:109C900021DDD5A063BAB3A105D31D0D114CDBE6C0 -:109CA000953D5F04F35F40E73F007F183CDBEA0728 -:109CB00019546DE58BE953D22DE5EAE46CABDFA4D2 -:109CC000BCC092F7948EB2E45D456596FE1C399354 -:109CD0002CE54A6695252F7BAEB7E4AFE89865C9B9 -:109CE0008F8C7ED3D2DF88B61A4B797164A1A5BC64 -:109CF000B06585259FAFFF8BA57E5EFD1A4B799BD6 -:109D000033FCAC48F9D5B0BA0D967A43176CB3CA98 -:109D1000AB199997C5B7C8C77A96D99F91C8EFA5CF -:109D20005C120AA1DC62F2A511F016FC5EC3487455 -:109D3000AF00FEAB6B4F80DD612F6272A79F7D99F4 -:109D4000D09FE2D9F79A4EC7A9F49D08F498E88C01 -:109D5000044CED28DF3F2532BB79C3BDCCAE6EBDD0 -:109D600037B97D8D9C9DAEA3F5F3E4FEDB1E51E279 -:109D70007A906EB1535AEF15B0FE3FDABF519ED8BC -:109D80006F7C3C8A7315663D246AF845899E15B739 -:109D9000776D3DFEB960F71876AEE460DF2B4B823D -:109DA000279B28BCD7AA04FD866B3D5504F48A4F37 -:109DB000544637644F2EDAE346FDFEF333E915C807 -:109DC0007F5C563FAD6716FA3DD7660EAC972931DA -:109DD00009FD77524C205D54EE2872F5F47C4ABFA1 -:109DE000CA2B52703541F993D4BE27641BC2414A35 -:109DF000D06F9AE625F0BD29C370DD36BE8EC6CC85 -:109E00002AFCDEA40E3C2F3BCC0BE6C3E7658BB9E6 -:109E10003195624E9CEFC45806E627C4FC985E1547 -:109E20001B8A69456C08A6E363859896C7F2311DC5 -:109E300017BB02DB95C546623A36360EBF07636331 -:109E400031BD32F625FC3E263611D3D1B12FE3F7D2 -:109E5000D25825A657C4BE82DF47C5AEC37464EC92 -:109E600046FC5E12BB01D311B16F613A3C7633A65A -:109E7000C5B1B99816C5E6605A185B84ED0A6277D9 -:109E8000609A1FBB13BF6BB1E598E6C5EEC13437CE -:109E9000F65D4C87C51A31CD89ADC674686C23B6A2 -:109EA000CB8EADC77448EC7BF83D10DB8A6956EC6D -:109EB000014CFDB187B15C8DB5639A16FB217EF72D -:109EC000C51EC5D41B7B12BF7B628F63EA8EFD0C5F -:109ED000BFBB623FC1D4197B0EBF3B624730BDD4CC -:109EE0003E2939563E2E65BA2CF909A7D32DF851D3 -:109EF000F186958F97BF5260292F7BD1CAC783C740 -:109F0000CA2CF931872759EA971EACB2E447EDB75E -:109F1000F2F1923D563E3E7CA7958F176DB7F2F158 -:109F200082562B1FD79AAC7C3C7795958FE7DC65E2 -:109F3000E5E3D98BADFC3B30CFCABFB3C80EABFD58 -:109F40003D65B755AE4D7ECCD29FA7FC09ABBDC0D9 -:109F5000F98CABF4A796768EA2A349ED9A447F398B -:109F60008044A6F47D377105CDE72A469ACEF941A3 -:109F700006D01D4D3339DD0D02BAA369FA5716E339 -:109F800039D3A75F6DF95513ED2C7D28617E017DD6 -:109F90005B15F8BD9A87F03CFD22D07ACDC308FA54 -:109FA0000988FE6E2596E7B3FC0FA433953AF3DFDC -:109FB000B2727281953B59FEB1C67F5B0DE5E969CE -:109FC000A1EC20ED678F2D391F7F4262E76D17C42A -:109FD00050BB44D7FBE7CA9E95E047B33BC27B2505 -:109FE000FA7DB1239C07AEE90F6CE14764E08B2456 -:109FF000B40FBEA791D02312F26BAB5FB415146EF1 -:10A00000DACFC762F57E28CF98D9817691B1EE6616 -:10A01000EFC0F3894A4C2E35FB09DA8DFAA30ACA40 -:10A0200053FC33E4059583F7BB7D2128DFF5A8B207 -:10A03000DBCECB2D72A33E0BE586ADA37939B824D8 -:10A04000EDB09F5232BF680FE6D340E32F04FBBE52 -:10A050003757A6E9527B5733C8F5BFFABBDF122446 -:10A0600084C7AF003E2BAF0F63FD35EE9913603D03 -:10A07000141E27E03B85C7F3D2A0D4F02070B24075 -:10A08000E71F30B068BF60F13F9E13C2BF954C7EA2 -:10A09000CC403888703B20A9080F037EF4EFAE74E3 -:10A0A000C31FC3DAFD11C74DE84FE6E762BF95F85D -:10A0B000F85C1E1A789C21927032F81BE73EA423AC -:10A0C000F70BF9B39D8A98741C9B5C8DE7A9FDF88A -:10A0D0005E66825D9F1986B35E2A3FA9BC4C32AF93 -:10A0E000690AF74FC97997757E15E5FA3DD99FFB47 -:10A0F00085CEBBC0D083FA438D7D3A968BF951BC97 -:10A10000FD50D0EB283E3DF7A6FDE812CA07765178 -:10A110009E614FE20FD8D521E2F9FA503F45385AF7 -:10A120005ECFF5006A13A13E688C2B2FB6FA8F2202 -:10A13000360EC7C356380EA588FD536A72134F1EDC -:10A140009B1F3FB734FA69EF9BBF751EBBF52031EB -:10A15000DBDDF9ABA322E83572079DC798FEE31358 -:10A160007EBE60D091ECE17E13350FFB35C64D1CF1 -:10A17000874833F03C29157CFB8DF305CFEB2AE4AF -:10A18000E4E79D747F104E4529F43CE3BCCEC83F04 -:10A19000F7662D9E7F37476A50BF6B0EF073F6BF90 -:10A1A000D15EA11F921C4FF6727C7A889F8BECDDEA -:10A1B0005EE5C0769979967D2ABEEF265798E967C5 -:10A1C000E990EE6B63F5863F308F7FAFC1EF0FAD47 -:10A1D00062DFF3EEFDD8C9BE7FE88734AAB3EFDAB9 -:10A1E0006A99D717B13EA9A77FA673A0E16AB508FF -:10A1F000FAEEF0ED2404DFF2D45E01FCC89A4A4482 -:10A20000DD04D7ECED472BAFA3E5D991EA59D7C1CF -:10A21000797898048B35F8FEF2EA91B88FC401FB87 -:10A22000BD83AF3B2712DE3012EACDA6F548BCBC99 -:10A230008D8F3B2C12DE761DF8EF4A583F46F9F71A -:10A24000797B97511EB2B68FF0F2DC55A7BA46D093 -:10A2500076B991DE97AE857A1DD67A9B79BD51503D -:10A260000EF3085AC769E5F390F4DD04D0438A90F1 -:10A27000F4E9D08F6AED678381BF505E8EFFC6F22E -:10A28000870DBE90C0478C762D29F6DFE0273BC1B5 -:10A290004F3002FD5598E6B426F7BF96717E65E013 -:10A2A000572A3C270B448B7D47C22E6B7EB649FF55 -:10A2B000837C28DB5A3EA1C05A1E1C65CD97945959 -:10A2C000F3DA244BFED33E3F4BD409F460F8590C2B -:10A2D000DFCC0E95D149DC8FD7ED34DB2539BCDEE0 -:10A2E0008375CC1FD3E8E1F4C4FD322E4E97CD2503 -:10A2F000CC6E31D6FD24E75711EEF7D8D5D0C6FC89 -:10A300003063438E7CBA9F2DBF938203F9A11FE770 -:10A31000FBF1634E8F07B8FFE6877C5F1EE5FE9B6F -:10A3200047C07F03F40AFE1B3BEC3FF3DFB473FF2F -:10A33000CD43E0BFC17DADE67E98D958DE06FE9BD9 -:10A3400011E0275A80E916EEBFD9C4FD371BC17F43 -:10A350003302FC422D980EB231BB7CEBD45036F860 -:10A36000CBF64C4D6E170FB231BCC8074586A6B967 -:10A3700024F46517E02F456C3897293F167ACE4DA7 -:10A38000F323A20CAEE50743CF4179711BCB17F243 -:10A3900071409E807CA1FF60713639541B32E1EF21 -:10A3A000B817A3640EDDB7B7657E0EA051D5232B79 -:10A3B000EE2F8572D8A73785508F3C1EFA25CC8F9B -:10A3C0001F0E0B401E83EFEAD5155A4F5DDC1D8230 -:10A3D00036BE96CE2EB0B335BD0BDB6DAD0CA29F55 -:10A3E000CDD8273ABA051FE8DC902F0EE3FB4F26A5 -:10A3F0005BF12137B60BF5E1E6BA596988771A198E -:10A40000D05E2FD969D517866FB7DA49CD77CD1AC7 -:10A41000D0BF9CE82F53275BFD65CD2503B7F7958B -:10A420005BC7F79426B4F70CDCDE199B39A03D78A6 -:10A43000855893611B14CF17C6AEC1FA89FA9F0CD9 -:10A44000F16F54AF93A72821380796A7A8187A254B -:10A450004FD1781AE4DF433C5FCDF22A8B93A0FA08 -:10A46000623E8C43F727E1FC3B44E07C7AEB48C238 -:10A47000ED91DA35A11C9AFF6782F6C449F9CE2A1C -:10A480009DE677CC7088D295806F2CDE41E1FB95FC -:10A49000A144D723DD6E15C96E9ADF131998EFF525 -:10A4A0008B83F084D07F3374B15A260D40F7DB17CD -:10A4B0008BD3A349FABD86D315394612F5EA6B6CE6 -:10A4C000F4FBDAC5B354E0FFF24D41B41F88C6E691 -:10A4D0006FF0B98CF481F76F57C27C7353F87556DF -:10A4E000DB38BD9530FE68E07FC64A86E7A9FA5F93 -:10A4F000C7F959AC53B0F87F06DD545D69CB447B96 -:10A5000028E8013EFAB9C4FC688759FC9A414F8D8E -:10A51000252F23FF36C6CFCEE902B38D341F99C84D -:10A52000E22A287CD15E3C42F97829F27B02F55D73 -:10A530000B7A2A991F3D8AF10FAEBAA00E79C9C3D2 -:10A54000F005EC515E1FE7B3E1AE5921D8A7C61C58 -:10A5500012E420C6751A78D018103134E29312A68E -:10A56000F7CA2AE51330FF9132CE9FEA59172F1A06 -:10A57000F68B04E789BACEEC37167765C4E30D6D28 -:10A580001B83F8DFEC5D89E785FA58A60748A49B92 -:10A5900088F9381F5D2C077FBF1A04596FCBD4058B -:10A5A00033BE7D4D08DF0BFB1EC7AF4E8C4731E03D -:10A5B0009708FF6F71BE9A4792DB1F83B97D93A105 -:10A5C000745E077CB7E5518AE749E266FCBCDE0FA2 -:10A5D0003A66A5012919746B941F90341CC7C80FE3 -:10A5E0008D292CFEAFCB6AA7FCFFAEEF1FB459E359 -:10A5F000F3FE47DFFF1F7DFFFF117D9FCBC7A96BD8 -:10A6000060236C1E962F6F9EBA46C7F559ED7649AA -:10A610000E5AFC1FBD40FF26392F7BAC7AC9E5F3EB -:10A620000D19F527121C66E1BF19D903CB19C3CF49 -:10A63000F1E930439F0F215D90A21262D6D79A8034 -:10A64000CF5338EEA470E47187384E365F97ABA7CE -:10A650005A17317EC2CAB7772E38EA1C81FC5FC612 -:10A66000769E406708E4AD43EB46FE6BF069CA9FF7 -:10A67000C72A8380CF5720FF739544307E6D2DD736 -:10A680004313E10AFC305006E325F021A2A53BA0CC -:10A69000FCBB0C0764F0E3819FB27E603FCBE5C654 -:10A6A0007D187118B9F40FF8D04699CD8F1CB2C639 -:10A6B000B1537C7458E275CF3D8CF2D4E8C7D077A3 -:10A6C00012DB35A9556A32BEF8A610FEBA32009EDA -:10A6D00024FAB548021FA71C54007D6EE88CE9E8F7 -:10A6E000AFEAF36FC956BE2E078CB898FF5EFE5EC8 -:10A6F000A7FC9DF1EB5FD0FFB78B9FEF27D2716274 -:10A700003FA24EC49E24E3E7EB62C2B9B355EF17F4 -:10A71000648DDD13AAB39ED3C89EECE4E7093CCE5A -:10A72000B366421FFE7EE38F147FEF3861633C8C7B -:10A73000CB25C3BF7B07C47BD2FDA981F84F2ABFBD -:10A74000E7916A1F147E40448C2BFB80BCEC1B6796 -:10A75000DAA77D0AF3E79316DB29B86F64C435DE08 -:10A760001E6179633EB56DD6FC7C322B0BCE35E68F -:10A770006FB7118863BC83C8A77A8CF9533DE7FB98 -:10A780000A8BD3AE2575CDC0CFD672FF7D8D4A64BE -:10A7900088435CF2CC8315606F1E50981EF52E85A1 -:10A7A000BF668A575BE8892A703EF1CEC1715FFFB0 -:10A7B0001281F6D1E66C8847A47A2DD8BD89709FA6 -:10A7C000DB629DDFA5E69F385FE37E52AA79C81D54 -:10A7D0004228991DF133C51A3777A97B536F8391AE -:10A7E0008CE720D67B53976A775AD148B2FB5697AD -:10A7F0006A77FEEF1CEF428AF196387A14E003CBB9 -:10A80000E4F074A1201EF7A5D8AA43432928E44305 -:10A8100063BBC0176EAAD77299F54E80017219F505 -:10A82000A68B03F47781D3F1AFF63FAC007D7EF0C9 -:10A83000D8C99970EEB3E8671271C0BAF67B4917B0 -:10A84000B34F1490630B0F4AE88F237257C58DA640 -:10A85000385A8CB8A5EB5FF4632FC6692C7CC21EF6 -:10A860009D41DB2F7CFA9D3184C2E1C29ADEE34335 -:10A87000C1CE784C6071897ACF981BE9F78532B9DF -:10A88000AD3A091FF4D8199EBFFF13F76CC023A17E -:10A89000E3C8ADD86FE7376C76D3B9A064B7E1B839 -:10A8A000B45E889D6709D16281CDCF7CDFC2880705 -:10A8B0007DFF5181CDEF902DEA84F975B42B615A5B -:10A8C0006F59C75F106FBFFCE3033E80C3B2439272 -:10A8D00085BF2CEB90BAEC63303D69C7FB34218F08 -:10A8E00040F9C8526431343DB804E3C797766EFC32 -:10A8F0008BE483F656FAA1700976015C5F9582338A -:10A9000020FFE4233EB01BDFEDDEEB03B8D27EE791 -:10A910002814AFAEF9D8446784F51F4BEFDF1FD57D -:10A920007414C0AF659DEBD97809F4F92EFC634827 -:10A930007FB930CE6E950B9F90172BD05EEFC84835 -:10A940001A6FDF271738BD2E3AF0C92E9D8EFBFEF9 -:10A9500013EFEDD2E9FC17FFC747BBEE01BDECE7F3 -:10A960004E15F8CCB2C77EE72326B8CFB433BFC1AB -:10A9700085471FD9B783D2CB853FD8D1AEBDF0EC88 -:10A98000D95C8DAEFBC2E39F6569B4FE5DCF4E1D01 -:10A990000C70B8EBA92F0F1EC84F00F81AB59BF723 -:10A9A000358AFD6B870416DC7F98A709FBF3DCC1B1 -:10A9B000E772619E1FBC66C7FB8CCBE8B7FA32D842 -:10A9C000AF25C8F721BF8AC279E9FE757F91C624F9 -:10A9D00083B73E54C4C3454A3601D8EF1BBF7675D2 -:10A9E00039A4B6A006FD915EE4DB89ED96BD42F781 -:10A9F000F5CAD4FBF809F99B02F05FB67F3D1B371F -:10AA0000611F3F807F4CECBF8F8BFBEDE3E287D073 -:10AA1000E638989134FECAD8C7254FFDF3807A8076 -:10AA2000C10F2E05DF053C8E70A23DB4CA0E74F531 -:10AA3000845B0FB0FD8DCEA065170E7C924B287EF7 -:10AA40009CB3F5DE0A7CB2F759BBBA9B7E5FF8EC8B -:10AA5000AB4867179E7A49D1904F128F40F5840B0F -:10AA6000A4EFAF1BF486A5FCCC79D91E6F97DD1738 -:10AA7000DFA7A5D11BA66B3EFC7E12BF4719FE2F98 -:10AA80008D1EB94948B26F4FDB0B183F8F0E42B88D -:10AA90002C21DD8A5A6ADD4F6102ECE3C9698077B7 -:10AAA000A9F6D158BF0AEBBFCAB49F7B18DD26D6E2 -:10AAB0005F4AE913FC887DFB1A155E2549E8F442DC -:10AAC000BB5D8678E10BB64BDC03FE82FA5FA73DE7 -:10AAD000857DCFE170293ABFD4FABE28FC76817318 -:10AAE0007B507F38BEFFB7E4FCFF45CE379692F02F -:10AAF000F46CA9BFFC9248481F9A1F9F6F73A784EC -:10AB00007CFDFD0E290A4D13F9C4D2147EA7D7EDA2 -:10AB10004C1F597AE8C818E067EF1FFD09C74B863C -:10AB2000F74BF79F54742E0FA2667990C23F799A23 -:10AB3000CF7BD9E1E4FD2DDBFF97A4FDBD2B87BEC4 -:10AB400001F37FB7DB4674DAC5BB9D52523FEC6F11 -:10AB5000EC364B5C61B3B7E2B534DA4EF2B9341877 -:10AB6000BA714DE8551DF492976D78DE41E4E039F5 -:10AB70003BF813BD2E6D038557A36F3EFA2B8DFE58 -:10AB80009A12E02407AA75B04BE5CCEA72A62347D7 -:10AB90002D76B14D152DF3A6723607E4D05B63CF49 -:10ABA000DA609D6F27E8836FCBA47930EDEF6D5DA0 -:10ABB00008AED692E1B7B5FFF02A896866F967EF6B -:10ABC0007D0BE6437EE12410A722FDDCA9033F595B -:10ABD000B6CB1985B880E79EFA741FC0EDC24376E4 -:10ABE0001E27C0E2CE6B55D6C7D9A73EDDF5EFB420 -:10ABF000FC2C34A6E3D7EEA2F5410FDFEFC6E0FF51 -:10AC00003F3F91368650FE5CFB8B7B66027FA90539 -:10AC10009E4AEBD7FE7830EA756706B1FC9903C30C -:10AC2000A2B02F8B9F7C7629C891453F7213701973 -:10AC30003CF7D4ABB742FEC22FBC182779E11767A7 -:10AC4000AF013AA0FAB36696E37798DF2BA0FD2E0A -:10AC5000823C2B172E9AE26F16414AF9C6A243692D -:10AC6000780FC8540FDB2DB3F7AE0CA23F59CF16A7 -:10AC7000D1C6E9CA063A5CD4611D6FA483F949972D -:10AC800029BDF359FD4836A3D76E6C57E1E078CA69 -:10AC9000CB13DB1BF5CB1D05967A46FBA5765297A9 -:10ACA0000CFF2B79BF8B3A3E1F61ED8FE16BFF717B -:10ACB000D8F7EF08EC9E0A79DC89E76D8B95AEE159 -:10ACC000E9945E9F56C802A0DBC5BEAEE17E3ADEC7 -:10ACD000CF389F5CECA279FA3D9BCF03EA439E38C4 -:10ACE0007A7E04FBBBE41927017C5FF20B2F9ECF19 -:10ACF0002C79FAD3333FA0DFDF7FCA8D7E9325BF47 -:10AD0000B81BF77B89BDEB56F0FBF53E6E477FF332 -:10AD1000FB8F3F9F0B7AC8FBB6AEDCF401ECF3254A -:10AD20009D76EE8CB0AE83DA052575743EFA561624 -:10AD3000C7564F5CC1D5109F028E03C0E3379C2CD1 -:10AD4000DE8A9FEFAEE0FEA00FE7696938FF52E6AA -:10AD5000DF5AC1FD072BBEAA0DF69BE60171A66462 -:10AD60001C21772B752380CF4AB1AF108DE6E558B3 -:10AD700021A6463D490DE2F98394C9CECF6D994194 -:10AD8000525B0AED585C12F15CDF4767FF8B6EF196 -:10AD90008A07B4C1D0DF4207D3A7DB9CA1BB1D68E3 -:10ADA000CF78F07E29AE933204FD29B6AE4F05B6BA -:10ADB000AEC4F97E6AD3EDC0CFE3E7DEEC9CA55EBE -:10ADC000D65E85F34C7282F3A57EEB6774F6A19A8A -:10ADD0008E7466AC6363838AFC647D4300D3750D17 -:10ADE0002544C3FB0141CC4B1C1EF6529D4870DF2D -:10ADF000566373B57BAA43707E017DE2B986278CCA -:10AE0000F8650FD4A1EDEFF010B44F258F4E6A3DD9 -:10AE1000E80F4338C1B90CC049E179B96D06C29554 -:10AE2000B6C7EF2B9DE15D001747CE280B9F52322E -:10AE3000CB2CF97E7033F0E2C07F37FC08C26B7D0B -:10AE4000830353B85F017083FB1590FFBF00BFE31E -:10AE50008EF1ECBE8366A21FB8EFA059E82905FC6D -:10AE60001EA0F0CB8CD355221CEA797C9B414FA9C4 -:10AE7000E817EEA7C0E5836D0D6D981ADFD353C8B0 -:10AE8000F5E14E81C7058457DBB87F1CF7215327B6 -:10AE900039267F1209E8782F0AEF5743B987F9114D -:10AEA0008DFD9554F98C95FF69AFC27AEE7EC1266F -:10AEB00002BF92EA1F26EF6498E87846B5534338FC -:10AEC00007D17FDBC8E5EBDABEFDB4D2C7C6060DFD -:10AED000D34D9C4EB6703AD90AFB0EFEB9A0887BC2 -:10AEE000DA3A9DA0FCBC8FE6997DDF45CC7E6D7F74 -:10AEF000B0B3CB46F71F7992866917F2AFD7ECD182 -:10AF000062DACE5D4A42802FFED7BE1BC5B592CE17 -:10AF100000F843FD1C7EE47081FF66F69E828DC9B9 -:10AF20002922B1346203FB2911BE8DC1A30EB0BB2F -:10AF300053CD272BA8DB73E978596FD8917F67DE53 -:10AF4000D2F95A0D5D87A7D58DF6645690E1A327F7 -:10AF500018166A4DFB979542EFDBE7BC2ED349E903 -:10AF60007810C4F3D2745B5BA113E0BBD1D6190097 -:10AF70003EB8D1CFE48C369B8E7695A93DE78FBE47 -:10AF8000722BFD1BFC589D5C66C16383DFA64FB12D -:10AF9000E2BBC16FCF3B983ED7E6AC1EEE8478DEB5 -:10AFA000D84EA4C744FC6FB429BA40F59446D025C6 -:10AFB00041BF3B29B0B894FE7C00E3563EECC9DFAC -:10AFC0000DEF0EACE1F1D43AA517943BDCFF699C80 -:10AFD000CB1F20D52DF00E4C0BC52302EFD550FC16 -:10AFE000017AD84CF107D208C51F4627133035F037 -:10AFF0007326384FCCE7BF45C745769F4304994336 -:10B00000646A077AC0CF7464A203F442D9C6E259D5 -:10B010007ABD6227C4B3ACF5CC7284C0AFE32FC74E -:10B020007DFFABB7266FA07315785104F046F50489 -:10B03000C9A9D2F8BD5F492D23604F1EF074E3F912 -:10B04000DED54ED132AF3667F846A7C9CF3F1A4694 -:10B05000E7FBF64FB8FEE4F7876F73723F658E4EDD -:10B060008A4CF46DC499124D2725263A5F533C8DC6 -:10B07000C039687FFA4EC1C7F6FED7F0B1C6BC280A -:10B08000EE9B2D916F6452FEEEC154175538DF3B95 -:10B09000D4F42D3FE2D95D000FE2D9DDA7BFFC5308 -:10B0A00041FF7926F2ADB83CD2D05F45E5D1FD1322 -:10B0B000800FA6904747DE1CF1358596BFF3BC2470 -:10B0C00098FD750B62EB511ED4C626128DCEB7A625 -:10B0D000ED7B98CE6F6B47BC3F175DEBC3389A167C -:10B0E00066CF9D8BDAA2523EE2ED4509FCFA84F56B -:10B0F0007F6E6723D623E07D318D7B6E276B4FCA31 -:10B1000035D4A73FE46BACD9620FC139CDB936DA7B -:10B110006E0078D6803194443FC5F704E0EE00A974 -:10B120001B017CCEA0F7BB15CA97000E6FD993FA0E -:10B13000D9573AA7EE00BA5EE90CB533B8A75FD687 -:10B14000BB16EF8854EF4578877D3758FCACCC8F21 -:10B15000F90ED78B892345B98FB75793972F697D00 -:10B16000EFF8BD34D75C1AAE2626FB5A22CCBE5E61 -:10B170007AA892BF2FC2E693043F993EDB6A473E0E -:10B18000348FFB830C7C8DE34BD8C7EF975AF0E9E3 -:10B190008ED856DC6F61E3E8FB2752F87D44F10856 -:10B1A000FC72C2C6AB07031DADDEF0A52DB7D0FE05 -:10B1B0003F7E51C2EF0B624EAC7FFEDEE0FDB780FA -:10B1C000BEFE6F36027CE4E31353F13CF6BCCDEADD -:10B1D0004758E462F2FA1CA7E3F9B18D16FD787EB8 -:10B1E000CB5C05FC8FF3639BF1FB7C3894C17B2027 -:10B1F0007F3E5629C3790DC1F3D173CEF7A7AC01B9 -:10B20000381C2E433F56ED267BD27B29E79C9AE5DE -:10B21000DCB9B6A715FB25543FCACCE2FD99F84727 -:10B220006D0C2EB1C0FEE804EE2DCCE77CA46F7E41 -:10B230003B6D163E72DE99DC4F12E37AC9FCD8975B -:10B24000908EFAAFEF1A465FC6B83D8CEEE2EBB9CE -:10B250007F62B2F5C4D73119EB9FF7271F3F8FC329 -:10B26000F94CC30212A27CA8C64EEB7960FC3B9B52 -:10B2700027809DBDD39F2E98D655DBB688844CEB96 -:10B28000AADD3947A931F51BDF07E72FCDFB90B7C2 -:10B29000419EBAC60372BBDAEDA270AED978F598BA -:10B2A00030DAD98C9FBC630BE6025F3DDB766752D8 -:10B2B000FACE736916B950DBC6F787EABDE5A6FD7D -:10B2C00031F625B1FD99376BFF7A2FF8011E604AE0 -:10B2D0004D2A78F5DBB7FCE4709BE862787986CA82 -:10B2E000D930C24D7BFA35C0EB4D6E8CF74C0DBF9B -:10B2F0002B487820F8A5D05FA9BE53E61A0FE312B9 -:10B3000084436D1BC3834BC12D3E2EC783CAE4EB20 -:10B31000A9EDC3837AA253823DA55C0A0FEE21BA40 -:10B32000638075F4E1C1680B1ED4BA8AA7023D9E02 -:10B33000033D6544FFFD3FA5E8BE49700EB441C220 -:10B3400073A6532E3DEB9B2C3F16F8F3295F64E662 -:10B35000A4F278FE8EBDC5BE39A671CFB6DCE94B2E -:10B36000E667AD4D853F453A29ADF83F873FEFA4ED -:10B37000B8C7B5D259B908F6934492FB738DD4E09F -:10B38000DF529AA7CFEE04797ACA53F0D7282D3D21 -:10B39000E40CAF047ABA5BD4C6CC11E2F6673FFD89 -:10B3A000B361FAD5A78BC15F587DF5691BEA43D815 -:10B3B0001F01BD329FC745A07F6308CA83C4F3D273 -:10B3C0001FB8F2939E8FAE6DA81B07FD12874E54D7 -:10B3D000739C1C617AD4FF86F1F3E3EB516C613509 -:10B3E00008F6A540AA01CF6D72B805EE03DB0299FD -:10B3F0006375135C1F7031FF97F3D8B1967CDADE6A -:10B40000F9A7175582F7CC74F4AF3972E40FCDFE6B -:10B41000695B268B5F2445A6EF0510874CF3163B2E -:10B420009FCE77003BF567028383EEB5F37B75BA59 -:10B430000472EF662731FE50FFFE8311072237B1F9 -:10B4400072BF51DCC4CAB9FF72590DF34F26EEEB3F -:10B45000CD87D775833E73F3E12173C18F75B367D1 -:10B46000C49FE07CE167E0C3077CF733B99CD8EE6A -:10B4700030A7D36FB58BBA8DEECB315BEF5137CCA4 -:10B48000F73BEC1DC76FFEEE98CD4DD3D75F396506 -:10B4900083773B6E83001DBAAE39445398121CC5A6 -:10B4A000F67349A797E53B07CDF29AFBA3A62AF4CA -:10B4B000B79C9DF37EF377AF4C05F14FFB5B0BE937 -:10B4C0006D2F1205FA9F73506B66D7F8787F8769E6 -:10B4D0007F62BCBF381C1566E7C80E844B1C4E0E3D -:10B4E000849B012778E606CBE370467DC380731FFB -:10B4F000DCD2665F4FC6A4A6979B3DC3FF44C6C47B -:10B50000E79508E78FA188D2DB7157E88F403707AE -:10B510005CA137205DECE8CD950BF01E630FE4973E -:10B520004AE1BC2C8A671F0C0B8F1804715CDDC9C3 -:10B53000CF5713E9F42DA01788FFE67198B7F2F5FD -:10B540003DF7DDB35E8CB37CEAD55C4897483D9B04 -:10B55000BE01F4F66B09F5EF0F0F8E18302EED2DAE -:10B56000EEEFF8D425F2F303B6BEDBB81E77DB416D -:10B570007714DEE3BCAD5EB2E8BFB7D5B3380E22B8 -:10B58000778FB9C9A24736A5EC07ECCEC47E8CF5FF -:10B590001DCDCDBE02ECC387C62B1AF81F8EBCF89A -:10B5A000E11F6A69DE35CC81E7B29BFC1C7F2B452D -:10B5B000DCF787FC21F768F03B6D480FEA749D1BB0 -:10B5C0007E493A450A9FA3235746ABE8789BAF16BE -:10B5D000D167B525F670A40ADA95B2778F54AE8F8D -:10B5E0006EE93ED506F878F6353BFAFBD3BD12CEB0 -:10B5F0006383AD3A17F4F73FB52B49DFD97378650C -:10B60000ACD72EF460BCDB5C127100DF38D83D6B28 -:10B6100030CCC717242AA0FFD99D92C8F464C3CFA9 -:10B62000D125333FBB2EB37C88A7AAD3FCDEDDFA3D -:10B63000E953309E625EEB4B184FEC2B4F7ECF6987 -:10B64000829BDDD7F576A7635CB4778A886F24790F -:10B6500083BD02B4CBEBAE52B07D4418B07DDE2A80 -:10B66000F53A802BB407FE9F7799ED836E05E1B024 -:10B6700095DBC9EDB660F314DA4FFB26BF00FB6122 -:10B68000D4BBCECDF499B3530CFF4D04FD37B9456F -:10B69000AA13DE5BC90D2171136F79C401F0DA0DB5 -:10B6A000F5987F13E1D03EF2E92E383FDE00B2017B -:10B6B000F6D9C6F069C32601FD99147ED9202FFE64 -:10B6C000749FFD2BB08EBC164105DB9BA649E7BDE0 -:10B6D000DAE360F2A6F57EB403C13D0AFDE6EEFCB6 -:10B6E0002DCECB9B62BD3FF430FCF8D325F023C7B1 -:10B6F000CDFC36B9F5DDDC4EEAC2F716230027C8CB -:10B7000087CAD93B87724833C7A1C4E987D9617416 -:10B710009D18075A334189821F406C69C77785E7B6 -:10B7200046ECE45ABABE56A13B04F4A28F17F97B4B -:10B730005EA1B7004E9BB70EC678B675622817FD9E -:10B740003BFFAAE0F9D8D1D0870FC0BBBCBB2628ED -:10B7500048174743EC9EEC43AB0ADAC10EF7D657C5 -:10B76000E17BC1515541CED2584E5E8078D2C6554C -:10B77000A22AD0FA916AE33E82EA02BC182B7D74B9 -:10B780005D099C9F0D11C19744CE0AEC9D91B5AB0C -:10B79000AA54D8D7B56AA660B65B748E077FF457F3 -:10B7A000EB6EBABEC0BDDB548801DF12CBB802FC21 -:10B7B000857A8BA2B1778BD9FB24197C5F32BAC50D -:10B7C000AEF93ECC7B16501379CB64E6A7FCDEF5D0 -:10B7D00061E65F8433C90AF42FF2BF00EE6B26CF17 -:10B7E0006D18E5C2CCF635F3B13EF49345FBC9289C -:10B7F00017BB2A68BFBBFDA15D284FA63A104E4477 -:10B80000EE69033845A76607E1DDE46D1387BF04E1 -:10B810004F54659CE89D0572343ACCF57A3BF0A90B -:10B82000B58A06749EB1EACC2DF0DD1FFCFE9D901A -:10B830006634FDFE1E9007FE9EBF34E0F7E98AC520 -:10B84000BF97F1C6F9CFA13CA35AB1F8093FF3570E -:10B850003FECA6F0D9551A89D468EC7B282BBE8E14 -:10B8600003ABBBA7C3FBD9676F1083BB7939AE6B42 -:10B87000BB1ADDC0E0560E72CD80DB3A51EB84F787 -:10B880009DF5990EC48F22D28DFC6A089C2217C6A2 -:10B89000F725E38DF5CB214E22713ECFB885BE77DB -:10B8A00061E09D4A8CD7A7724C1932C50578FD78A6 -:10B8B000597700F4F84DFEE4F1099F7A587B7B8AB2 -:10B8C000FBEE1F79183E004B6C2BC334341A520F19 -:10B8D000D1D320CD7184203EF67151FB23E2F9369D -:10B8E0004983FD81FA36BA7F475E7817FD83472288 -:10B8F000BFC5F4654F097BD78F125C16BCB35B7E66 -:10B900000ACF4736AB0C476A5B18BFA80DF438E086 -:10B91000BCA2B694A8BB39BEE9069CC1DFC5E555FB -:10B92000CD4D0CAE99A504CF5BC12706EF9E6541B6 -:10B930003D0ABFCC96D5CB711F49B75E48EB6D86EB -:10B940007E617F9AD8FD14427A1C48BF1109CF1B33 -:10B9500029BDFF06CE136B5A07E3793B5C7787FE60 -:10B96000D2F9B8E9BCBF76DA0FF8FFCEB648643733 -:10B97000F2B76E78639868AB282E237EF65696D081 -:10B980007EB57255DD60E081C1C72869CCA3F202A3 -:10B99000E0364FD79703FE9D72A82FC03CDCDBED4D -:10B9A0001AAC7FDEF667EE06BDC51DE86901FE50E4 -:10B9B0003B81CD37BD957E47FD46FB0DD4AF6DB5C0 -:10B9C0006B6C3C0EBF728E671C0EB7F379DFBE93B3 -:10B9D000CDDB352C1A01FCAC5D45E10A656186F7CB -:10B9E000E0D2BC28225D9D80F57BF52CEC77D0EC75 -:10B9F00004BA48C03F635D357C5D35ABD8BA08A753 -:10BA0000273AAD2EE8B7A69CAD731E61ED45F84E02 -:10BA1000FBBF9DAFA7467F1AD3DB5BEC96FE779505 -:10BA2000ECE986F9E4972A9A807066EF6DE6F27584 -:10BA3000E536B1F1724B9F4678917AD37CD12F6A6B -:10BA4000CA53BA3AFB3C252C78CC22D781C874EA79 -:10BA5000BB0A9EA3146DB7AEEBECFA110FB782FFD1 -:10BA6000F33E05CF2B1E17836FE5A11DAA688CFF3F -:10BA7000047F3B03F8F4ED4D78BFEA402583FFD9FE -:10BA8000AF9228E043F189EA748077F189304FEB77 -:10BA9000F01C9B0244E8E37B747ED4746A11805FDF -:10BAA000C60A7FB800F800DD67D0078799E74DE741 -:10BAB00097D192550571489913D2AB147C4238A1A5 -:10BAC000FCC48E59F01E6EE6B11D77C238438869FA -:10BAD0003DB4FC4A6F21BB9F758C9642BDFA33F78B -:10BAE000C27EB4F277ED8B6166E9981E833483D20F -:10BAF000F7C67498A74CA694C5F9C1DEFB2AC60206 -:10BB00005FC1BB2565987691B2FE7CC3547F24AF9C -:10BB1000AF0B49EA5578358B5DBEF7BE6923C17E10 -:10BB2000DF0C7A621ABC0BA87E04F1317A5044B85B -:10BB30006FB675394A33E1DD719180FEB2A5E4F745 -:10BB400022D0DDE6832408F89151FD1F76F33ED61E -:10BB500079FCB86E59211B81FE8F8E3C331DF6296E -:10BB60007A84EA9DB47ED5AF3C3BE03E71FB1F5822 -:10BB7000FC49FBF37528BF57E62A49DF7D2697D09D -:10BB80001313EBA717CF423F5EDEF6ADF8BE6CEDA8 -:10BB90007439782DAD9DB9BDB212F418AD9A62D743 -:10BBA000603AEF9D635703116A33D87995369D7DCE -:10BBB000D7A6B07463C3827160B7473A6467119DBA -:10BBC000EFA8F5ECFDBE8DA51F3AC2542F2DAF7C1A -:10BBD000C2F155FAFD74399582F4FBE9C91F3AE1C7 -:10BBE0007CE6A1F2AA0C80E7C116AB5E47E0713695 -:10BBF0006A078DB647425E3AAFD6DF1184A764EF7D -:10BC00006AABA179E9190F6838FDEC9BF5ADEDB38E -:10BC1000014FE795607872FF7DE7F2626E7DEFF489 -:10BC200002A05B9DB073D4C8FDC8946FE72C235F5E -:10BC3000EF46A6E3DDCEEC93881C3A0E7C39521A0F -:10BC400056A089C1CF5A8B6BF6013F53B8DE4FEA3D -:10BC500016E0FD48A47F09F4A1DECA6476D3B7DDFF -:10BC60002EC4ABB33B6F7C15FCD3F3EA99BE9FB7F0 -:10BC7000F32301F783EA7D4368FF79E5F8E425992A -:10BC8000B72AE2180DFB5324124D83F97412B01336 -:10BC90002254FE98E160F4FBF7B6DFE1B1E33ABE6F -:10BCA0000DC6F3F8F87A3C7C3DB9C1DECA64F1B345 -:10BCB000DFE2E37EE7C18F8E4C04F8AF6226525E6E -:10BCC000E4A4E030CD234FBFBC79DC02FDD1793C48 -:10BCD000E961F7A7BDE53D78EF2891BF833A0F747E -:10BCE000BBCB7D612CB3EFADFCB45F9EE355E2F7B7 -:10BCF000DC047E35DADE793DEEEF01F6BE3A2194C2 -:10BD00006E1DF8ACA8C6DE9D8D1AEFA0D741BD51BF -:10BD10005E8F0A78D03AF2F765009F4D5C5FB8BD40 -:10BD200094A0BD7A7B4E37EA0B739BB8BE20079B6D -:10BD300081C9BA77FAC90693FE802E2C702D357111 -:10BD40007DC190FF5C6ED706BA5B50AE827E60927A -:10BD5000AB353A93AB790126D76B5BE8381A47E6E7 -:10BD60000AB35EC2E4B8B69DEB0F5C0E67F07133A8 -:10BD70005B98BCCA003DC207E1073ACA653CCBCB21 -:10BD80008AEB2D834A99BCCC687D1CE5DA1FC0E99B -:10BD90003208F8069397C35E7A45073005E8E73620 -:10BDA000CAA78FF1F2804AF5B3F4B87EB64EE4E745 -:10BDB0004C84E987185B4FE77998D737BEEFE1F3FA -:10BDC0007BFC58FA5780BFEE8D148C954C748B5EBB -:10BDD0004F9ACF2D67E7F4B9F5EC9CDA1B9CBF4F67 -:10BDE000329D3F6CF5707BD3C0ABFAAE00F48BF79D -:10BDF0001D918FB3F7AAD6537D09FD4FDCBE9AEB98 -:10BE0000E67E0D8E3FA9E489C187BC24E42BA5F012 -:10BE10003D1DDD87FC5AA7F612ACED74A4317B21E1 -:10BE2000D07BE4867298FFE6897FC5B88BBC14F698 -:10BE3000A2C3EB30E0F085F8BA77FA2BCC0EED1602 -:10BE400093DE9399CAFD0F9D3271033C9D11F6DE7E -:10BE5000A1738292B4FE042FE39B195E768F68F380 -:10BE6000C47D78BF31A57C96892E2591A786BC6DAF -:10BE7000857D9E44C8CCD65B9B75B4D3A3D512F206 -:10BE800057760F30C27F77462F51D06FD86A8B38E4 -:10BE9000603FB694F37D551DED703FFD0BEF0B85B4 -:10BEA00007ECF3FA901815F2619FA3EA68E6D7C190 -:10BEB000DFED394BED77F339C52CAFC8E1A489101C -:10BEC0009F98D7C2F06BF34405E7B1616C56BB9401 -:10BED0006FE6BF02E79F0C4E1B261E47FCBADCF93B -:10BEE000CDAFBF67D269D339E299071E290038C7A1 -:10BEF000DF6F090D787F617EFD4B93F624391FE8D3 -:10BF00002B073BCA037660F49BE67396855E6667F3 -:10BF10002DF11AEF3333FE06FCD586C645341BFCE3 -:10BF20004B07AE8EFAD07FBF989DD7DEC1CF6BDFB7 -:10BF3000DD7323BEBF301AEED426D9F7F30DD6F742 -:10BF400017CEEF7D249BF935A216FDEA8E7D3F19B1 -:10BF5000C5DE9FD1F9EF72102DB382BDA38D72FAA9 -:10BF60007850B74BF1F7D114F85D0CF0B703051713 -:10BF7000C22BA09D987A807E0BE1F7857A315541DE -:10BF80001C15829D14C4349354639A45EA300D9075 -:10BF900008A6D9A413D31CB0730B412EF462AA11C6 -:10BFA000552426BE5F4082982F22D598CAB06F19BB -:10BFB000F17309B9C381F117707E01746F9C531836 -:10BFC000E7FB377B6B1EF02639AFB8C71BDAC1BE63 -:10BFD0007721DF9ECB59F8891F8DEA84FB3D2B36F4 -:10BFE000B1FB25065F47BB86F6FFC3742607F46DD9 -:10BFF00002F2AF35EE99D7201C5B6DEF9BCF1B880B -:10C00000C35104BF3F63F43B97FB17E672F907EE99 -:10C010006D76FF2E88F77FE6829FC1544EFACAD90B -:10C02000FD6BA31FD13D79F840E77BA6F6188F5C26 -:10C0300093A0FF5F526E27E4E725B6FF1B9D505685 -:10C04000DC0FF7C36BB45C76CEC4E43645240DDB5D -:10C05000B5D84FA21D16991A32C3E5258EFF863C2E -:10C060009997E0D74F4CE7C99C2E12FAA192CF0FB7 -:10C07000F766F00D14135D1BEFE81ABFD375472860 -:10C08000AC0C61CD02B08F2A9F7784ECAC1A42D3FE -:10C09000739037F9F37FE70BBFED35D1891AAA13F7 -:10C0A000CDEF34CDE77438556AAD04FE76364C8258 -:10C0B000603FDC41EA36833E465E9190BFC13D6CF5 -:10C0C000F8FDA06170A0918E795DA1E9070DEC5E8D -:10C0D000CE1978476904BC7FCDDE517A0FDE4DA2C0 -:10C0E000E9E8B6BB67021EBC0BEF27C1FD5B4EFF44 -:10C0F000C6B8A33BDD7340EE8FEEBCBA16EA8DEEF8 -:10C10000B0E3EF45951C5C5F0D7E2178CFC545C738 -:10C11000C9A1E339D2818F1094B7EFB5BAA26BE809 -:10C120003CDF6B93902F7F522AE2BB23F06CA6C4B6 -:10C13000E797960EFDFCFBADA087BCCBF988F17E9E -:10C14000E47B951ADAC7BF3CB04E807B09EFCDD1B6 -:10C1500070DDEF0DE9CC4D07B9E463F1E545FBED8A -:10C160005D05741E0B1FFB43410DF0BF82C8C26406 -:10C17000E7CCB93E264FDE7B8A603CDC7B4EFEFB83 -:10C18000488E4E9FD9CF1AF00916BEF59E97FFCE66 -:10C1900052CE25EAF1F872E2E9F431BAEFF4C1794E -:10C1A000D4FDEE1FE1FDB5334FB1738A5F3E509B66 -:10C1B0000BFEA8229FC6CEBD0F3C8971E3B00EB026 -:10C1C000A3E9FC3498DFFDEEB7DE05FF036D87F7CA -:10C1D000338C76670ED4B2FA6DB4BE0FE14E7C6537 -:10C1E000800F0CEE643FE31386FEB8289A85BFDF0C -:10C1F000102F17B11CA6E8A4F01FBDFF063CD7AA5C -:10C20000F0A5337C563B47CDC2F94772611D07AE9E -:10C210000EE7821FEF8CF17B52722417E070B33768 -:10C220005CE133ADFFFCC96790BF9788756FDF0B8A -:10C2300078F904FB3D93BBDFD82A9AF9C7541FD382 -:10C240007BEE772FF5C179D499BE7775222CDEE786 -:10C25000307BD77511A7BD33EDD47EA2F038BFFF78 -:10C260007B587EA6EFDD9B4E8C273BBFFFB9744801 -:10C270006B783C3F89DE88F445E1D2E24822AFFA90 -:10C28000EE4545D97DB70B027FCFF441036E75CAE9 -:10C290002CCB7915A3EF9C9DF9C7505F8E26BF2745 -:10C2A0009728EF13DFA7BDD43DE0539C4E4FF377A3 -:10C2B0004DEEF1866B7C49E448CDC625B900E71AFE -:10C2C000B85387710E95D782BD8DF74DD8FBB45DFD -:10C2D0000827E3FD59FDAA6B21CEF18C9FE5BFBB7A -:10C2E000B97A9DCEE1C8EA4F63EDF359F97D504E1E -:10C2F000EBFFDE5BBD9C8D4F04F6FB48363FFCCE6A -:10C3000085C1FF52AFDFFA3B171DC093C7637FF7AC -:10C31000607F32ED6FF43FDE9FC16FFEE17E1CFF58 -:10C32000B5FD187C18E81242F6483038EABF027EA4 -:10C330007F6F7B323BCFC2CF3F7DA0B019CE813E15 -:10C3400009B077A2ECADAB09C8A5DBB76F4DFA3BDE -:10C35000797D791E4FA214523A33D1F3F39CAF3E4C -:10C36000EF8B9F07C0F9CC7042F87B175455C9C2B8 -:10C37000901BB4FF46F077E34B4804F5AB51A41390 -:10C38000D352D28DE918D28B291E931682AB2F88F7 -:10C39000E99F2B7B2A60F18B1DE1872054D7EE08A3 -:10C3A0001F077CFA6058F8117807788D7BE924988C -:10C3B000FFAF7DAAF17BA224E1F7D9E2BF2BA281D6 -:10C3C0005E332330905E4354F9FDBEF88D027C4706 -:10C3D000F8651FAE2FD5EFCD25FC8E25BF476CC06D -:10C3E0006109E9C438885FEE5CF102BCEBB370BF51 -:10C3F00017E5C1F09D4DF87B620B497716DC2F1DC8 -:10C40000CEDF93206DEC1D0FE39D88916D76CB3BC5 -:10C41000164B127ECF6811FFFDB14589BFEFC5EF06 -:10C420006F6E840F49E20812EF7FF6FA52BCE75AAA -:10C430009AFC776512EF7FEEEF1431BE6705C40BEF -:10C440000971BE37724F9DDD8A5F9DD71499DE83D7 -:10C450006A1482CC9EF6BA427B85FEE38C53197E29 -:10C460001D1084A47164DF4C33EC9B26723DEDA754 -:10C4700071B1AC82BDD91875E13968A3CAECC2A10B -:10C48000DE2A07D8E9C42FAA703F659A3419E3CB96 -:10C490009525F23838F73CB67B6137DC5F680CC80D -:10C4A000E8A71DEA67E7A0648888EF0334A94FF87E -:10C4B000E7C23E79D839E33095E0EFA11E695F29E4 -:10C4C00042BE919A2D83611C21DC8DF76E86C88453 -:10C4D0009FBFCE189B85EF98F138A556BC7F3C6571 -:10C4E000C96927C8F53CBEEF5569F9B84E99EFE721 -:10C4F000AEFA537EC0D3E7DB9B5F9E46FBB3456538 -:10C500008C6B2DF9BCF1F56974BCDE768598DFE3A0 -:10C51000CC5D255BEECFE6DC65CD2B09F788656247 -:10C520002AA7F972181FE148F544735C55668839EB -:10C530000B550FDE0F0EA5094C2FE6F90AC85390D4 -:10C5400074D822552E3ACF8E3705F43B1C6D9F9F31 -:10C550008771FA3F09E7017E1BF890B87F4A9A6617 -:10C56000BCEFE1E4F7839D705897883F4D0DA41808 -:10C57000FCD18EE831D715B08F276CF89ED45AAE17 -:10C580007FCB1E16FF6EE04B62BA3601EFD67E7E81 -:10C5900023E25D2FC5BBDD03E09DAC6AA827D872FE -:10C5A0004810C8C396D99DADD276573CA3043D141C -:10C5B00064D37E5C9A06FACC15CFDDCCDEF5A3F011 -:10C5C000C27721EB9562B0FBEDF599C57206D4F305 -:10C5D000203E7EE861E73F72BD3B08E58DED150129 -:10C5E000CD84D7CD0D6AB15C0CEFE3388AE1779644 -:10C5F0009A53FCDEF330BF580DFE2585DBFF77A68E -:10C60000B1F9DE99E6C674451AF35B3C28EBB360DA -:10C61000FE0F52FC817881237731FC5D31C481F7B4 -:10C620009E573C5F3878A038A07D0D816280DBCEBC -:10C63000BB6AD0EF51B9FC9813DE055BE175A880A9 -:10C640008F926FF8FD9301DF5FB0E1BDAF466F855C -:10C6500036D7D49FE49B807E2549D4B3C1286AD9BC -:10C66000F2D6B5F244C0177D0748A248DAF16B65EF -:10C67000CA5F3ABC7AB640CBDBD25E60E583F41D7C -:10C68000022D8FA6FD86E587E9D9F04B221D692F83 -:10C69000B37CB1BE03F29D69BF67ED41B7A07ACC10 -:10C6A000A1B4D7AF053DA7D1169C0DFE9D1FD1F9B2 -:10C6B00097D2F977F2F4A71C4E46F913F09DC2FB0E -:10C6C000204F13CB9FE6ED0EA528FF292F3F9CA2FC -:10C6D000FF9FF3765D29DA1FE5ED8EA5687F9CB795 -:10C6E0003B91A2FC055EFE628AFE7FC3DB75A768F4 -:10C6F000FF326FF74A8AF6BFE7ED5E4B51FE3A2FE5 -:10C700007F23A1FFB778FD1EFE3DC7DBF23ABC1BBD -:10C7100096D3CE5E022DF1B6A0FEBEB3AE1CF1BF25 -:10C72000713CD3330C7CCF81784D9ABF52657ECD5E -:10C730002B55C6E75FE1785DB9BC680BE0DD8A7F09 -:10C7400093509E523982BFE7AB2F67712F2B9E67A4 -:10C75000F741562C97F1F7800C7C34DA1BF3DFC5D8 -:10C76000E7D764C031AD809FB7048A6798E33D5531 -:10C770006BDE41E90942769A32997C29595EE518C7 -:10C7800001F283CA17E09B6B3D4A17DCA35FABCA7B -:10C7900058DE9459A542B9AECA287FD6665639E606 -:10C7A000A23F271DFD13793C6EAF4995F11EBFECEA -:10C7B0009F82E5D37E3C43053EDA447AFD95B0BEC8 -:10C7C00055329ED71EA9ABC2EF79FE8FFDC09F7F69 -:10C7D000E367703FE63DEE84775FE5EF88282F86BC -:10C7E00003FCE8B805ABC4A846AB1C535788907F40 -:10C7F000B889C92BFAE71D6B7A77B16365C50B1051 -:10C80000BFD3B8490EC2790EFCC9267950C47FF750 -:10C810005453D32DF2EA41EEC7D5030E8CC32B92AD -:10C8200049C0FC7B989A2AF17729D83B668511ABE1 -:10C830007CCA6FB1BE63F39FD7EF7F0B008000000F -:10C84000000000001F8B080000000000000BDD7DD1 -:10C850000D7854C5B9F09CB3677FB309BBC96EB2FC -:10C860009BDF4D801024C006420C88BA090122A229 -:10C870002E880ADAE286DF00493670A962C5B22145 -:10C880001103450DB71181825DA85AB462438B1222 -:10C8900031E88A88F8157B43AFF6A2F67A17A48AA6 -:10C8A00080B06A45FB63F9E67D6766B3E7245168AB -:10C8B000FBDC7ECF870F1EE69C397366DEFFBF99D7 -:10C8C000CD23CA89A889E09F8BF984289A764EA344 -:10C8D00069B052C4DBF4AFD16553B52DB664C787D8 -:10C8E00049F41F5EE2BDA82364D9EE65932DB439E7 -:10C8F000E917C503A2C584AC30A58C2003685FF896 -:10C90000732D21CDAB3AAE19A42764EB2A3A2EBD84 -:10C91000367F3D7A26292524966CF1ED900859B38F -:10C920008A8E3FB8A7FF681BBD3986906D4A683A6A -:10C9300071D06B58214D745EAF2C9709B497B94DE7 -:10C940006123EDB2EC8DFFBC6E08B497CA5EE2E9DC -:10C95000795F7B7D72956B307CFF2D3A2718571FCE -:10C9600090069F1C4DFFAD045CFE644206B625ACEC -:10C970009FFECD6FA5ED84F5EAF57E9BCD4A48DE9E -:10C98000B7C04DEF7CCB1E2886F1151C5F3B8F6F27 -:10C9900083EB1AA9B1880CA4573A57804FC829874E -:10C9A0009FA0EBCC5E71EFB8936984641DB2B400B4 -:10C9B0005C49DBA384A413A2836FD3752B92CF436E -:10C9C000281E5AF24BBC12BD1E7ED6C2E0946345AF -:10C9D0003819246FC6F5F46A94FD36189FFEF1C12C -:10C9E000F80FE458B6AFCB8766C00470C8DE4907BD -:10C9F000CC84F6C0B53E85E289829B8CA37F43BF81 -:10CA00006BF5D175ED94E2ED6A6877840DBC3F89D2 -:10CA1000C0FF76CB127B4EC7575C84EC9224F63C69 -:10CA2000E4ADAECAA6FD15DB30C54B48D056DAAA38 -:10CA3000CF81E7B278DF47CAE9FAE07BBC0D70F935 -:10CA4000F941F1BCB2B56A101DDF40C4F821E8BF5E -:10CA50005B9679FBAA56187F57A5787FF05A5F3608 -:10CA6000CEE77A9D9D90FBDA26B65ADD3DF37D68D0 -:10CA7000C3F5AD4D747D9F78A2297419A47EFBC9BE -:10CA80007442875A3333E007380261FB8713724AD6 -:10CA9000F220BD08FCE9F75484B2E8ADF387FE9CB0 -:10CAA000524CAF415DF45012855F7D67C0A42FA04A -:10CAB00070D6FB4259F93DEFD5EF994602946E824C -:10CAC0005D2578EDE3BDC38AFC77BD67325CC2F7B4 -:10CAD0003E89FCB6E119FAA85E1768B50EC4FE845B -:10CAE000E1BFEFF589F73F79E6B7B7C2F7CE79A294 -:10CAF000E953802E23142E7DBC27FA37745610A0DC -:10CB00007B29C9B7DEE624641E853971027F357A38 -:10CB1000A17F87A9CDE6A5CFCDFA36BF97F6A7A806 -:10CB20000CCBE53DD7876D83703CED7D2DFF749870 -:10CB300048DA544AD7A13AC5FB0481762869046DC6 -:10CB4000AFAF574637D129AD2EF9DDA862683F67F0 -:10CB50002546DA6EAE3BE82A063EF21A08152F6427 -:10CB6000FDD80E37F0714BBD61E6E340BF9165AE75 -:10CB7000F9C53DE33F64D7E33CD6BE46F96C24BD1E -:10CB8000EA3BEC12BC3F5821C087663BC5336D9B26 -:10CB9000DDA924940FFDACEB811FD7EA03D595D016 -:10CBA000CF2D9327E877CD83675457D279B89CB2BD -:10CBB000A4C379541D5B409F37DB0C20D9C87BF69A -:10CBC00039CF019C7EAE781B810F7F6EB5DA42F4BF -:10CBD00001958D3EE05B65B0230C6DA38E3476D05D -:10CBE000F96595107F87B5679EEF71F9F89ECD8046 -:10CBF000705E6FEE985641C7B12C936D21FABDB5AA -:10CC0000F51BBB27D1EFFCB8FEF9A34DF4FEBA74B7 -:10CC100085C03CAC0E256248A1747C039D239DF722 -:10CC2000AE26BF0DE467CCA9901DF4B9659081785C -:10CC300012E4A0B598B613E4539A43F199E9FB7F47 -:10CC4000B2078EC0FC47BFF99609DE778D9165600B -:10CC50009B0E85E139A5543D8E6DBC7A9CD42AF596 -:10CC600073C754F5F3F419EAE7AEEFA8DB99F3D4F0 -:10CC7000ED5B80DEC640473AE732BA0EF68858A22E -:10CC80009FAE2229089F7700FE9642D90BF031D73C -:10CC90003F7E6A017D9E05F284CE9F8C20E127288D -:10CCA0003E0FE47EDF13A57036A6367AECC5BDE1F3 -:10CCB000919563BA1EF0651DA4D808ED6FFDFDC700 -:10CCC0005FC3F85692D02F1FE0E3FBC43686B55DF4 -:10CCD000743EC9F00F0FC0BBF17FEE03BD7754E780 -:10CCE000057867D52BF8FD076778C2BA7CD69DD04A -:10CCF000FE29BC7F8A697DB76E04BDFE7EED525D64 -:10CD00004A6FB8A6934609F892D207EA0B524350ED -:10CD10005F3C20935AA01BCAAE04C6B3C10B54CECD -:10CD2000F8530D0827C5CEE887FE4B86E7E936366F -:10CD3000A6C13DCF0CFC7CFF2146FFF71BD838F184 -:10CD4000F13CF851544120276D765935CE461BEF02 -:10CD5000C3DB4E3B6BEF3E987A3DF0E5C619A9A3C5 -:10CD6000804E8C3209C07803B24DBEA1747DE63787 -:10CD70000C21890E3A402107F5A9B4BF85DCE9A74B -:10CD8000F3D87CD812D2D1FBE6F9FF6EA34026255A -:10CD90007CDEBB577BFF13E440AC4641389A9D6D67 -:10CDA000B651C56C0D213ABF54F807958F1583DB3A -:10CDB0006D804F73451BEA6F73495B1BC069F35469 -:10CDC00019ED89D47932D2B339A7E3E8207A5F3FED -:10CDD0005FB6C178A954B11BE8203FCA6EF3FB616E -:10CDE0005C0A73B98C910A8C8B2BA4DF49E37075B4 -:10CDF00038F6DC2DD171D260BC11AC3FC0C9CEE198 -:10CE000034D6EE413E75F071D306D1FE23D8382DCD -:10CE1000653DE3083C6EAE2661989FF8AE18273E4C -:10CE20003EF1492057F5BFA670A37892724D38B9EC -:10CE3000FB1793B0311FE0E36FDC8E7C6D253B80E8 -:10CE40005F1CD99540479987B74C9747C07B16FC24 -:10CE50008E7E3E09031D672AC4744D2AD82F7E8416 -:10CE6000A3965FDD07DB6EA63C12C78B967FDD0ABB -:10CE700069D5A5F6E663B7C3515938A20F7ED6F03F -:10CE80008BFB70EC7B40F45ABE7E2CE95C09C085BC -:10CE900024F6D77D7B5BA7EB383A09909541F504E2 -:10CEA000057DAEE67B84FCCD086D89C89E8B034171 -:10CEB000EEDB391D537D459975F728DB042BF0E92E -:10CEC0005282F455B977FDEDBFA6E35D186CB081D1 -:10CED0005EC939DCD60DFA91740686001EB62A8129 -:10CEE0009F24D1E75B8F651090DB6BCD6426D0B7B4 -:10CEF000C2E95CAB5F1E02BE71226B8465D7DF7F27 -:10CF000015F660C7A0F461361B8CFBFA6193F37FC2 -:10CF1000D1CE0A0D433B2BFB60779315BE6F9BDC94 -:10CF20006AA2F035BFC9FA3F48DBA14100BFBA3C55 -:10CF3000E0C303390B104ECABB4602743A5CE70BE0 -:10CF4000439BBC6726207F773EF79D5A0FC89FF40E -:10CF5000291E90433F017EA7EBD9C6F95EBB7EC573 -:10CF6000E00B803DA1BDFF685C2EF94FD5503C0E13 -:10CF7000FFA981ACA30F8BE439ADF9C0176BA9FCF5 -:10CF8000A54FE7E83C0D3F947AF0D369AED86587AA -:10CF9000EFAD32918091AEEB2B89042873E6387E99 -:10CFA0005B01F227974424D0B3B98DD4E005BA5A77 -:10CFB0006E2181047ACFFE4AC1FE9D66DF2E3B972B -:10CFC000FF262A07F4EC9FE4E7A97E52E360320AC9 -:10CFD000EC17FD3396E3203788A3CA17F7370A808A -:10CFE0007EA9DEA7DFDBC7D7ADA76A423F8AFEB5C1 -:10CFF000CA11E388DEFD5FE6FD14933502F252B1FB -:10D000001E3986F2C5A69C4DEC670A337D43EA487B -:10D0100078B0C4E082ED7FB3613B8BCA5FE328B494 -:10D02000FB434698670AF33F88CFE771A403BF101C -:10D030000472B689B49A683FA476CA6F6ED26D4600 -:10D04000BBF920F1003F5088D9C13F845B00D7ADC8 -:10D05000845427F281B88EB4313E5056E8D05F1A1E -:10D06000F6AA19E7A36F246133D84330370A6F65F6 -:10D0700039092BE06FAD3060BF91360FBE67208D50 -:10D0800068CFEEFAFAFD4C90D39643D41E1B097874 -:10D0900096514E592C6AFE23A409E1F409E7BF6DAD -:10D0A000AB6C88E7B87F16788BE339DA04FA22771D -:10D0B00079AA0ABFA25FF6575924303A71DC308E44 -:10D0C0009B3DE8A0448AE1792E3EDFB6CAF32DE30A -:10D0D00017F433BE1BE9A8FFF1B3F1F9B6C85BF64C -:10D0E0001B2928B6C60EDAFD9E1EFB5A0BE7ECE59F -:10D0F0006AB93CB253DD167031EB7D8E6914E6E6F9 -:10D10000EFC9DEED74BC2B8FA9FB55E7BF8DFE6D1B -:10D110004FFF88E366E84FFDEFED201D4EA9FBFBB6 -:10D120002B5EB3031FF7F467F3BBF62B753F2D7E21 -:10D13000B4F3A5F372DE9230AF0926A3EAF9CC9AD4 -:10D140005EF372DE9630AFC92E75FF4053DFF3BA3F -:10D15000BEC8F88DF312FD6E2ABFB47EDA75DC5CB2 -:10D160006DEC07EEACFF6D332F6DDC3B6ABFB9DFB2 -:10D170009D2BB4DF0921BD5F2FF97CA9F43A076E1E -:10D1800081BD68B5A0DDABA5975D5C7E4E067B8E4C -:10D19000F69F95EC9B9C4ADB1305DF3DF5BBDB411D -:10D1A000BE1C7EF68A0C90EB59A0E7109E2CAEB008 -:10D1B000BBCE857185EFF2FE549FB480BCD8BD9381 -:10D1C000BE97C2E695683FA5D531BFC24662C8CFBB -:10D1D000C25E4A253689F9E3CCDEE9EF3BDAF1D7C6 -:10D1E00071FF73EE8A09E403CA87CF1B6C150AF836 -:10D1F000678F49680FCCADF2E992297D8C6B953031 -:10D200006E34F79E7F1B0D7265EC494F6794DE9F6D -:10D210001BB67BE1B30DDDC417A67495A15B5A72F2 -:10D220001FBD3E7280DA3FBCBD14E8CDEAF380BF7B -:10D23000510333A2E39CD53796D8406E7ED7EA03DC -:10D24000B95933C3F70EAEF7AFD42AA1FDE6B3A5A3 -:10D2500093BDEDD30C1E6A67D47CC7530E764F4D39 -:10D2600087D9875713512C741D35D41E836B868143 -:10D270002866B85A8809AE65AB99FD9552EE37D449 -:10D28000D0EFD774FDEC0B786FA1127985D993613B -:10D29000C45B4DD71B7F027B6DBECF6F0079316CB5 -:10D2A000A781D9A49C1E8677A8DB200F12DB25114D -:10D2B000757BF46175FBC35406DF7D527818E06717 -:10D2C0001F5570E017877619515F1CD86F44FC2CEE -:10D2D0003963D90EF1A7094BAC28D7CF3C6DC6787E -:10D2E000D43EB9E35968879E4D42BFFA9577F795CA -:10D2F00049B4BDF817C9323C7FF16B1DC21996A322 -:10D30000A7F7973C3B74FB3A7A7FC9E88E321BBD86 -:10D31000FFFC158474C373253C02D6F7FCDF743818 -:10D320007EEC29637807A587332FFCECD97BE9F7DE -:10D33000CF3C95952A51BC5C05FA80F61BF75393B8 -:10D3400005FC8C71679E1908F262C94EA36A5D4F95 -:10D35000A7327B83223305E8ADBF78E289B53FC3AE -:10D36000F78B4E1D437ADBA70FC91658FF5A465F4D -:10D37000DAFEBB5399BE11F380F7F2297ECE7F6CA3 -:10D38000B913E2684336A9E13B34AC6EBF90CAF4EE -:10D39000FB1C92703F1FC62B58E3023B753B417B41 -:10D3A000A6E8D4EF6FCF073BDAC8EC07ED3C0EA43C -:10D3B00032BE7EFA693A0E930F3A663FD315537E1A -:10D3C0005CC2E9F84589D9AFF4CFF22C4AB74B409B -:10D3D000F117F4DC5FA2998718FF077C9D0EEE57CA -:10D3E000C7DED4213E4EAFAA1D7D7270EFF97CB826 -:10D3F000AA716895BEA7BD60D3D2436EFA5EDD6E9A -:10D4000027FA89E27EDD53AFA6DF41EF9FDDA978E1 -:10D41000C174AD9BF5E443E3A0DF53BA0E982F3CF3 -:10D42000F7D1F59EED782D05FA2DD86A1FA54BC0D2 -:10D43000C3C24DDF1B5A95200F2F971F04FFD671D3 -:10D44000FF766F79F7A42CA0EF4D9217BA2DE9B8AB -:10D45000E5E61BC056D9AAF30EA6CFCB14E2D78DB2 -:10D4600042D77B065CEB763F7728933E0FEE1F5347 -:10D4700006EB5A27FBAF1F0EF4FF981EE3585AB86D -:10D48000FC85E39BBE1F91E9FBEB6EB5D686AD38FC -:10D49000EE41681F28DAA183387BCA292A9FD8FD6C -:10D4A0006332E5C9535DF78F8078E23EBDB515E87C -:10D4B0007C5F32C34368970EE53C89B0758CE3719D -:10D4C000E325FFDD6E50E8F5D4A9D529158C8F50E2 -:10D4D000BE805076D0F5D5FE7438F2DDC24D6A3E7E -:10D4E00011FDC47C1785D5CFB5F4919526E20DA426 -:10D4F0002891CEB4FDD2A6860CC057752BA83C4E01 -:10D50000B07FEA4EB619C06ED27E072C4022F0AA38 -:10D5100043FA241E5CAF99AD979AAC26BADED3F0DD -:10D520002F16F796C02F5F2CE112C9922B489587D2 -:10D53000C273C974520DD77D52E4211D9767187FBD -:10D54000DF9584F2ECAC2DFAE48F81FE9EC9F18662 -:10D55000E8A34C1E973BEB89A4A4D2EB79E00BA087 -:10D560003F1B6B2FEEA2F29CF2F7994F0C28D79B32 -:10D570003A5E4D017C9D7DD62CCB142F6776A75546 -:10D58000423CE76CC7AF53605DA73BD22A212ED740 -:10D590009FBCD1CA29A1CF8FC33FC7526598E6BBB4 -:10D5A0002A0DE4564B1A18E32423ADB1A4B10FFEA3 -:10D5B00017EF390C8D251E901BDFB57A77303811A7 -:10D5C0001F6D7F76386D07E05BC8A91A898D2FDE45 -:10D5D000BF318EC76F968FD5EB86621EE833E21996 -:10D5E00000F27A1A287AFADEE1570A0780BD20EEA7 -:10D5F000373AFD33D2E87D5765B74F0771C429C468 -:10D60000DB4CBB7EA0F3DE65A3F89A47A8FE826BD5 -:10D6100069C08071971627AE6FAE42220AA5F7B98E -:10D62000A05F47601BF13577AB146EA6EB99B75E30 -:10D630000DAF05EDC61E3AA17F17112A608111B703 -:10D6400026F4A3E32F023D4AF1B0D844224974DC0A -:10D65000C58FABDF5B4222389FBA672E1AFBC2C769 -:10D66000171C1F8D4E5F7D9A4A0EEA510E2E21FE29 -:10D670006BE0BB4B84BE7E8BE12B78CF3D43E75103 -:10D68000FBE3FC8A7B87CE4B837822F1811D41DA54 -:10D6900093918E975491480E9DD7922E29323CA596 -:10D6A000675CF24B89F96744C1F57FF116C3DFED82 -:10D6B000DCEE994F6F831D7115F8EF80EFCD12CE20 -:10D6C00063DC33522899FA49F34DD4C503F9C4D722 -:10D6D0000BFD07D0F6421242F83C9C968F785B44D3 -:10D6E000BA0D8C7FC2CDE9F4BB0DA7A84C2297429E -:10D6F000076311DF9F132FE2FBDFE3745086F421F1 -:10D70000EE53FB8698537BBF0F78F325C0B976ABF9 -:10D71000BA4D1E4F6817005E683B015F0D7B2E1AE5 -:10D720007D7DE0E991B87E0B0F9D363C913F98FDE1 -:10D73000FC3EC7E323B72C70833C7A18ECC94C3EFF -:10D740004039C86F22E22311131DDF329AA8E22567 -:10D75000D44EC3F62FD2FEEBBA4DD9846CD4073029 -:10D76000EF3057E73F0429B281E9815F01DDCF95B2 -:10D770007DB90AC2D557887EF30A460F8F8E6A1C80 -:10D78000DAD887BF2CE6BF51EA88C8209F5E60F6D2 -:10D790004672694C1F48E0F737D3981D33E040F4D8 -:10D7A0005016D0DF7312C6F7374BA445A2707651DE -:10D7B0003C835EDA2C1D3F047A6CF3751ED24C9FBD -:10D7C00097EE99B6F435F4B92D5EC897D4EFA9D089 -:10D7D000D55B71FDCCEE4D6ADC2ED3E71977168D43 -:10D7E000023EA3EBBE733ABDFFDB340FC2CD6D65C5 -:10D7F000F4E35A1DCA5F06F1DD03FEA5AF01DD0D9E -:10D80000B7601C2D83C22A3915AFAD60CFBA4893DB -:10D8100004FDD63825C4C79A1A32F397C548CDCA35 -:10D820008054763D46AF92425A202E9CA150FB98E0 -:10D83000DD6F81EF3C92C2E6E59475774E03FB7C89 -:10D84000146BA7AE947C3B508F6D403864184935FB -:10D85000AC1BEE833D4FA7E1DB8DCFC338EF8C09C6 -:10D860008D25308F8C81ECEA3044B2619C23824E4E -:10D87000BADC32E88DE55CFF2FDF5D91914ADF3F36 -:10D8800072D6A4803C3FE212F668C40AF628195406 -:10D89000C4FA733DBBBC64420630B52357DDEFBC10 -:10D8A000DE376034E8ABA33ACC1BFDD1EA1B60A79E -:10D8B000FDAE32B07568F1AF7330BC06BF92483828 -:10D8C00021FE109C7901EDFCE0578AEAFED955262D -:10D8D000124E883FD4D51E9804FDEA49F71AA0C716 -:10D8E000FA8E24124EE08FAB2C7D7F57F045F02B43 -:10D8F0001D098D46B2CF8638E9117D6CCD7CA0C361 -:10D90000FD12C6B382D4AF0F25CEEBAB34124AEB77 -:10D910006B9EE9EAFB743DAA76E797D88F9447534C -:10D92000E03BE76CD1143B5F1FF413FAF77C580E11 -:10D93000E947629E92E96188335999FE9A06F85543 -:10D940006229D3937BC615CF61BCD484759E9B6935 -:10D950002011C44B0CBF0B700B0D21644BD7A706D5 -:10D960000FD8235DAF20DC04BD24C22F9498B76A82 -:10D97000EE8EC854565CDD9EB3AED84C517580CB4C -:10D980008550DE3ADF78FA5C27ABE44452695C6E7E -:10D99000A0987A04B2681857F5AC83386BBCCDFBFD -:10D9A000C7DF0FE54FA9A2E39516B3F727B717FC1A -:10D9B0009FD5A003491BD3CF4A2CD79F9CD0366953 -:10D9C000DA56DA1E9ED0B6699E3B34CF5D9A763623 -:10D9D000EB7F363992ABF31232BDBD708A42E5D689 -:10D9E00059776436F5A8C97ADDD02955B45D5FCA88 -:10D9F000F47A4397E44535C5E1D7E06576ABD51BAE -:10DA000035CC2D0638741F02B952D729D924CA073C -:10DA1000D68EDD116CC37B9E84F73A247CAFAEE3D7 -:10DA200038BED7EFF84532F2F9BAA213AC5FC74758 -:10DA3000683FAC69A9C1FCBEC85FEB88DF9725F5DC -:10DA4000E4AF857C3DE7F6BD2A33BAB625FA7341CB -:10DA50001837216E24FABF37BCEB6D304F92967F9A -:10DA6000DA04F6F47FD77F3406ECCBF7B81ED9285A -:10DA70008587C277B790C050D0A3DFAD1FFC8A4C1A -:10DA8000FBBDAF8F6E831CDD86F66B107EEF2747E4 -:10DA900073242A637EE4B88EB59DD16D00CF8F1DAF -:10DAA00053A628749CF773A239326D3FDABE9CB539 -:10DAB0000747B741FB654780F51F1ECDD1D9C0553B -:10DAC000AB9952459F3F61EB9B9F5BB91C11F333B0 -:10DAD0000FF4353BC07EAC63FA671BB57F4D545ED7 -:10DAE000CE5E7C7AD713140EB3BF9F8472EC89B3D9 -:10DAF000374F61FE41C8AF9441FC97FD41FD8872EC -:10DB00005E41FBC20D3A31B5071FC9B9DD1ED41FF6 -:10DB10005734EE06BB25637631EA8FB169BED3F088 -:10DB20005D71FD4526BB9E76D8985CD6C9980FCF0F -:10DB3000B83719EDBA87CD6C3D946F10BF568E8FF4 -:10DB40006D0E66976E7330FF7649DAC4D30E7A7D18 -:10DB500057F26D3651B8BFAB272133C8D94516B43B -:10DB600097EED84EE50695DBED7CDEED1BDC61C85B -:10DB7000E7DF21113FC815213FDAED3E776A825F6A -:10DB8000D45E42DBD61E3FB87D9ACF6D71C0355D45 -:10DB900086BC8F904BEDF9EC3DA18F329AD977324C -:10DBA0001E1EBA03D691A4B0F8D5FC99853B9AD035 -:10DBB0001E988EF3253E9F1BE220271715C810D70D -:10DBC00012F8B962A06F2FC0E5769E17107812F890 -:10DBD0003CCDD73D5747ED09BADEBF380308476A49 -:10DBE0005F8CE0F133B42F4E836E4F802F51A263D0 -:10DBF000E0FEFF4770FA3D3CFF47E154BF82CA0B8D -:10DC0000F912E40587DF4629A2CF60F202FD79B858 -:10DC10000F7AA7332D1083F1C5F767DF5B8FF6A46A -:10DC20009857D2DD7BAB6F23BDF94C6BEFFD19F03C -:10DC3000E5ECB14BBD220ECABFF3FEBB26CC7BBCCC -:10DC40006FE840B9F93EF5A39A40BEF0BC7DD9F724 -:10DC5000971C017F548C1B70EA70BCB592CF0DEB02 -:10DC60005B4BF16E82F94F33A0BF21F46ABB3DBC20 -:10DC700019EA26DA6FC9C6BA89F384D5A78456246F -:10DC800061BFABE41304E2AAB1B136CC9B533AC1F5 -:10DC9000E7EDB30AB17E85D243C80CCF293D419D43 -:10DCA0005F7B095D108C37EB0A7C0EFE3AFAD9B324 -:10DCB0004C385E1F74C2E2D443587D467B3EA7C3F6 -:10DCC00045054887E9CD2C1E4A14DF8869097A7E0C -:10DCD000BC93E139A934FADC7F01CDAF37A33D0B0A -:10DCE0003A16734A6D19381EC5FF60278B4B209D6D -:10DCF000CD7B2899D7C379CB00AE0F2433BADC6A29 -:10DD000066F9AEADD47E46B9C8E957D4E105B89DF1 -:10DD100017AD9553C05E18ED8CC73B7C107FC07863 -:10DD20003B7D3E272A1D07BF6F4E481731425CB826 -:10DD300075A22F9AE0BFC01FC817DEC9E52AD944D3 -:10DD4000D0BFBA13DE4B81F12D29901FBD13DE0722 -:10DD5000FF71E544551E7022C8F0313DF3D3CAFD72 -:10DD6000894E1EDF6C7BD497F81D31BE763CEAC726 -:10DD70004E723A11CE9101E04734E9108FDA7946BC -:10DD800037B1B87974531ED29D18AFBF79FE8F2E6C -:10DD9000F63D89EAC10513987F2FFC9EF9DCFF262A -:10DDA0002BD57E1DC479E26D5DEFB6D64F84FCBEE7 -:10DDB000BA3FB35B928A6306CCFB7824D5FC05BCE2 -:10DDC000FA83439DC0E725C24DE8BD47CD549E521E -:10DDD0007AD904759094BE36DD93847ACC61080FAD -:10DDE00005BADA02F535A84F99FFFEF91175FC4521 -:10DDF0008BBF1FC4E9EAF2FCEE26C0B9B3B7DF1D42 -:10DE0000B4C41E03F8072D8C2FCFED4F46BE2283DE -:10DE1000A2B3A1EEEDFC3E23017E6890A2852027EF -:10DE2000CE49BE1AECD794E401FEFC406671812015 -:10DE30006084AE3318FA0BD65B053BD57EF839FA11 -:10DE4000B796F2CF39395A06E308F902F204EDAC7D -:10DE50005A96876A904908FCB4ABE4398BD09E98F7 -:10DE6000954976E0FDE385E09709BD41FB1D94529D -:10DE7000191902FFD5717C34C827B05F1DD44D013C -:10DE80005EC05F83781F3C4C885337AC3F83755B23 -:10DE90000D7BD47453D74357D24509DE4BA033943E -:10DEA0000B218423DAED2047AA581E3D99B793AA87 -:10DEB000BBB18E2BC8E32FCE03D149209F924B3BA1 -:10DEC000C81C7A0D9E6276CBB8AEEDAF825F6EAFA6 -:10DED000EECE01760AF278A7A01B31CFB15D1B749C -:10DEE000E0370A7B27C16F1D3A5D15B7588DEF816A -:10DEF0001F0CDF8BC22D379015D3931BB99E4C029C -:10DF0000871AF469DB10D4A7A0EF40CE093F1AE4CA -:10DF10001ED0D5C0F4CA23C0F72FA657BEEE74B2E8 -:10DF2000EFA17F00CED7D8FEE94EC047F4037FFAB9 -:10DF30009BE3905C7E13167F5CF686F31BE9FFFD86 -:10DF40004BA6FFA11940E7CB244F06D0F9F138FDCD -:10DF50001762BE52DCFF5017C038A388772D82F8B5 -:10DF60001EBDD67139B480C7C71688B8D826755E6D -:10DF700015E2D189EDC5224EB6D3D8536F04F2A372 -:10DF80008A4492E978F51067836B87FABD061263BD -:10DF90007CD479D1A8CADBB63338DEC9E9C95E15AD -:10DFA000D681FCDA6C66F13221D7C6ADDC8E7432D4 -:10DFB00060942FFF7EE09B37F4186FF903A70301ED -:10DFC000974667E551C0A745C7E381F71B519E9F60 -:10DFD000A476C26E1EE7990EFEF1AAC050A897273C -:10DFE0008A2D37D17F16D775FBCCB5687FA7CB2A92 -:10DFF0007A7DDEC9EA9B30FE85FA2209FD012ADE20 -:10E000004600BD9615087D4D4640DCEDB89EC5CD59 -:10E010001B6EB50660BCA8CCE4A13B9DE929773A0C -:10E02000AB5714EDB8FFC9E951E443210E95988F21 -:10E03000F0C4FB6FE075C804D7BB7111AF778FF3E5 -:10E04000858CF22DA9D88F7AE12AB912E55BEC63B1 -:10E05000AB07E0527DA66E11ACE3B399160279C905 -:10E06000793C1EEE4DB7E3B8228E7DB9F1F0D1E9CF -:10E07000717A54C5C3F771B9B88FB0F9865A8C2C30 -:10E080008FC1E7BFEFD41561CE1F21909BB1DD6634 -:10E09000A68FA99D0CF27ADF9E216158CF713DB306 -:10E0A0006742FB93F9FB81CD10A7D9F74BA717EA7D -:10E0B000A0828B4F8F00FB76DFA9A77FF51BB8BF2F -:10E0C000DFE8057F741FCF63D419228568CFF3FA88 -:10E0D000CFBA944821C4A55EE4F8AAB3D036BD7F78 -:10E0E00083293035DDD9936F84F7E0FE8930F31B47 -:10E0F0004E104607A1F52C2F4CE1EB8679C4D6666D -:10E1000060BE12D60578F860FF709CF7463DEFFFC1 -:10E1100020B32F4FF0F689174AB01EF2BCDF80F50E -:10E12000CBC187993D3B57F63CB60264EF4B49188B -:10E13000079DDF7E14F347C187164E85E7C1C52BC7 -:10E140006F24DF9057013D9518C73F4762B9E8A794 -:10E15000D7167444E877CF750DF5B2F4A80B937118 -:10E160000DBC4EF624852FCC3BB65F8FF0BFD4F1AB -:10E1700031A059C6F4257C279898BF42FDA2CE67EE -:10E180007D5BFB9C3E5A780FFDFEDAD4C00FD213A4 -:10E19000ECD8E04B6E94A31F3CF8652EDA3B6D2C57 -:10E1A0006F7252EF9B0D7C62AF8A18E624C8D78D40 -:10E1B0009C8FE71AB95D4BE56022DF8BE765956AB6 -:10E1C0003E13D747D2995C4EE6F512BD9F8B7ABCC1 -:10E1D0009B8DA08F59C80BC6F5E0FD3C9EC71C77F0 -:10E1E0002AF60AD49DD57594609E346F6504F99221 -:10E1F000C23B02FEC9C9CDC94C9ED065C2380BCA0C -:10E2000009DAD50B74ACFE638191DAE9CC2EC0FE3D -:10E210001F6ECE403894AD66F669EC3909E5A2C8A8 -:10E22000E7D610F6FEDE96E3211DED5FB3532AA17B -:10E23000A295D4B454607DC8E2ADF988FF715CFE4C -:10E24000CE35FA0A3703BDED4D467AA3DF437FA0F2 -:10E250000E6AE046A15C32807EADDD29617E44AC71 -:10E260005F9B3F256175DE695C0793DFA03748A29D -:10E27000DDC9F510E80BA2B16FD57411BA247DAADF -:10E28000D50787E372F2F2F4E9AF417E8DE9AD4F35 -:10E29000A9BF70249DD10993FFBB59BEA99E34B27A -:10E2A0007C1BD767F175717DF8A18EE9DF05C60D7E -:10E2B000783D9E9E8FF35A4CA23CEF1433C0FCFA7B -:10E2C000A3AFE3FDD097A0AB139CCEEA4E91C8D587 -:10E2D000F47B752B49A47E04BB268F40FDCEF4BC95 -:10E2E00089E979B85A2E41DF6BF5BC56AF6BF579E9 -:10E2F0008681E96D414F89F907B093C6AD0CEB58A3 -:10E300009C39DB86FBEB387E97A4F92E668EE9B14B -:10E310000383C74C26CF4868FB498115E26715EB9C -:10E32000B2212F40F500F06F1285D376888B71FFF4 -:10E33000E3EE6CB67E17AF93D22B7E5262053C752E -:10E3400063BC20E624E8BF0BF86E4BA6EF8D82F786 -:10E35000185FC7DF3791164BC2FB95FBCCA8972EF1 -:10E36000BC908C753D54CFE4D9E978E9EF51BF8179 -:10E37000B6CFED4B463BE11CD71B0E1197216B101E -:10E38000BFCE0C86E710A9CC82F83691A66481A88E -:10E3900015F66CBDBDBF7C047F9EDF7D2BA33323B0 -:10E3A000EAEB0BF6E85DD0A6F3C13AECE40C36EFED -:10E3B000E09E0925F742FD85DFEA65500D9480FD5A -:10E3C00061D42DBF15E25E93742B63F7D075D4E74B -:10E3D00058B1BEBB2AEFF7BF9B45DB1FEFD113231C -:10E3E000E0FD899B0744E035C5E7EA8B4F1685F5CC -:10E3F000AAFD834B76AADBF51DEA769024EC2FA4C8 -:10E400002058F1FB926B0E26D0495946B2E3C36106 -:10E41000C096C40BF5E944F79D01813EE4AEB87E99 -:10E42000B9CA7BCD413DD6F75D9DC1F8D900F6D183 -:10E430001CA0873EDEFB23E77BA3B1F114EC133075 -:10E44000BE68F436D1B7CC198149F07E831C3B04F9 -:10E45000F834E69D1D01FAB432EFAF9827BC701F67 -:10E46000F1027C2E982BD04EBAB0D9EC017FB13D91 -:10E47000D7CAE2322F496189F91553C750F95A8B2F -:10E4800053A1EBDD74DDC76C530B31C9885FEA55CE -:10E49000B9405EF9D0CFFB709AC5B69ABE57BB891A -:10E4A000E9ED3AD29D0272E087803FA06BDD330632 -:10E4B00013FD677E8B6F68139DEF12BF05F733293D -:10E4C0005F2B7EA0AF0760C804BF644E069307F5BC -:10E4D000A6A8A102BEFFD779D5CE829E389E41CF95 -:10E4E000E2784A6749248BBEBA70C55CF4BFE2F992 -:10E4F000FACDAC8E6CE13D3578FFD5CD465CDF873B -:10E50000FB25A4F30FB7B1F52FDC64F640BDFBB5D6 -:10E5100076E6BF2FA4EFF5BDFEC91FC3BA3EDA7A77 -:10E52000B717F2101F11F69D908DC5DB3EB2B1BA40 -:10E5300002E80BE37CB46720DA43B59B164DC5FABD -:10E54000BE6D3A2FD823647F32C6B1166EFBDE6FE4 -:10E55000C6429C6CFAEDA500876BEDCBD3212E440F -:10E56000FBF9C3CCBE6675D3A9E54F021F5EFBF570 -:10E5700084EE6BC1EEDA46F9249FED4B007BFFE0A1 -:10E58000B6C968DF2E9C66B1C3BA3C5B9F98047A1B -:10E59000E8A3699932AE6797446C0007FB8A74B8A8 -:10E5A000BF5052FC7DD1537E860EE15A9167F546ED -:10E5B000E0BDB775482794AF6E053D5CBF4D8FF643 -:10E5C000F3C1E9EFFE6E96A387AF16EADA6E1D97E8 -:10E5D000603F05B7DE20E88444CAC02F6330D1F223 -:10E5E00097316F6521CC47CB670B573716B2BCDC30 -:10E5F000E5F11BD9CAF8EDF10C89C56F2E9DDF7EC0 -:10E600007E39FC46B25355FAB7B75C0B613F91D7E0 -:10E61000307989EF092BE6AF7D1295BB6F6528F83D -:10E62000FCAD0CBE8FEB4FCB76BE49E1332B23B054 -:10E630003F03EC28E22B013AF2C46C95B047CBCAF9 -:10E64000ED41B295D9DFE02700BE373AC993EB120E -:10E65000E221DD196C1F21E5FF4330CEB977FE7A48 -:10E6600008F0D3907B7604CBEBFE11F3A0D62E9668 -:10E670003FB77A635857A077F891FE845C0F7A9978 -:10E68000DED1AE2BC3C5FCC2A02386E37CE6627C50 -:10E6900028F20A5B5658301EBCC51136B37847883D -:10E6A000805E9A5AAE63F93F6EAFDDC0E3ACA6D28E -:10E6B0005709E4FDC878566FF766E9AB4A1A6DFF53 -:10E6C000A67CA217F73996FEB4B500D63D5ECF9F63 -:10E6D0000F0CC1BAFFC35781CF97B9741EE0EBA9E5 -:10E6E000A5AC6E94D4A6601CE7CDD20F1CF312E645 -:10E6F000EF27268F95D2C974EA2C25D639DE38DE6D -:10E70000ECB126D0D7676D5235B39B3D03660C67DD -:10E71000711AD4C3A56A782C7319F0BB2FA6577C45 -:10E720000A70BEF61A868FD3BB8C61907FA7F9BEA4 -:10E73000A15E74E1E2F4F39D22551D82C3D0910BDA -:10E74000FAF18CA47E6F71AB0EEB0016B54A244C27 -:10E75000BF77FAA9BDB920C73F7E626FEE9C84F9EE -:10E7600068DF13578BF81E8F776AE3D7FDC5AD4579 -:10E77000BFF39B48C034B0A7FFF9DA3F63DC7A4EA1 -:10E78000178F7BFB7C831CE04FF1FEDAF146BB194F -:10E790007D489D12C64D44DCF6C4E19F4286288E1A -:10E7A0003F7357BE9C58272AAEE338DE6E06BCD1B5 -:10E7B000A5985B59BB3F7CF5C78FFFC1F58FC0DBC8 -:10E7C00089D68103008E8606AB42D8FEBD22B0F703 -:10E7D000B7118B17F8C990E9B282FC12E71F7C6968 -:10E7E000665787855EA9BD96935984EFDD2DFBB1F1 -:10E7F0001EF14BB90DF76FDEAD6BC43AF73217FB64 -:10E800005EB6CDBF7B01FA391D58F74E5AD5F04D93 -:10E810000728809EAA31A09E1270BE6ACE5DE8EFE6 -:10E82000F6819F4D403799E5EC5ED095CFEDE52818 -:10E83000E643CCE5C4067181E6B1219C8FC04F90C0 -:10E8400075275297847632D4EF24A562DE37C4AFA1 -:10E85000C49A4AE2799024EE1F134DDE838AAD10EC -:10E86000F413F304310675400FDB3BDA0A59DE1866 -:10E87000ED4F1817EECF2956306F00FD0CA3BE9D4B -:10E88000DEE274C9EB3BA78AFBB5963EF32C5361DD -:10E890009F14ED9F43F520D87FC4AB57ED93DA4A20 -:10E8A000ED66F0EB441E5B277794B8D00FE98E42FB -:10E8B0009CC55066F2805E4DD2751401DEB4796D50 -:10E8C000DA2F9FD55364DB41AF887D500D2B26F89E -:10E8D000619F41DCCED8CFFCA3867B2AF0FE842E3C -:10E8E000962708B61A711F67B053C2BC5C83DF104D -:10E8F00036613CC4D304F80A513B0CFCCF763BABE9 -:10E90000036BBFCEE60D91C4B87AF4B17B31AE6E25 -:10E91000C57CE4DF9BA73D9F4C013032210F37C0FF -:10E92000C4EB0D59DC3D9DD393C0BFE06791D74D3B -:10E930002EF6E783C5FDE5C6D0AF2DCECBA87F214F -:10E94000B73DF88DF52FE4A31BA0FEC504D63C7F90 -:10E950000ED3A27A33BEAFD1ECC1FC5DFC399C472B -:10E9600061EA94F8FBED374C1C8475BBBC9E66D6FF -:10E970007AA8C37FD84C54DF4B9C9FA2195F4FC726 -:10E98000B77A44FF7BAF9FA8601E9BB7DFFD21D401 -:10E99000FB3CAC578F872428F6619A7ABEB72E6B62 -:10E9A000C883EBC7F7E86FAACFF7BAC6F4E8F10758 -:10E9B000DE9DDA36D203FCF539D6410B7D1C74B0EE -:10E9C0007A18ADDC3AE09284FD3B0954EC9A993513 -:10E9D000787E433C8FDD35CD07E758883C7670A5BF -:10E9E0001FEBA141FFBB50FF9FFDF01580D2F4D378 -:10E9F00068FF07BF52585C89DA1112A543535705C7 -:10EA0000C64FA13C17F4A6C0FF62AE97C05607FAE6 -:10EA10000E6EBDED091D7D9EEBF6FD078ECBFD4014 -:10EA2000ED7C4FB9D8BE816051E5669007E47189ED -:10EA300080DE5E57F419DA190D2F4C1C9358CFBFA6 -:10EA4000A8F311560FBE53DFE7FA4FB9983DDAF03D -:10EA5000C27318173D1D66DB886A95F0DA71109F46 -:10EA6000A995C1D222A5E19A59A8FF67D275D075A0 -:10EA7000FD86DB25C19D3787607F4190FE05906D47 -:10EA8000F12F407B7FCB4C9315F248C1A2394B91BB -:10EA90001F6C161FAC5F3BCF781EFC1E0BC62DD71C -:10EAA00075EAABC16E2AA376D2AFE87C7352A75445 -:10EAB0007BA95CCAD2ED2EF9372BD40FF4AD87D7E2 -:10EAC00067323DDC22F943379562BD2749AC47CA1E -:10EAD000EB64F6D84597411587BFE86276E2F850B7 -:10EAE000F704A0B997946812D8C541E2FB14FC5C06 -:10EAF000E2B77A601C380103EC2CC72A0FC6854D9B -:10EB00008EE80F47A2DDA4A09F21FC88732FB038A8 -:10EB1000DA5277C0EA86F88E2EFAA39B006E3F6425 -:10EB2000FBAB89C2E44DEECDD65110F7323BA23F8C -:10EB3000AAF6601D11C61F065CDD827878C9416C9B -:10EB4000009F09A11A454AD033426E4C88EF637288 -:10EB500060BCB5928B97C1145B1F9A90445B2EA644 -:10EB6000F5D80587FF3A43819BC25E904D01F4675B -:10EB7000AA6652FF10E8724DEC900CF17D4737DA2F -:10EB80008BF51D127EA7BEE89758E7B784D793C5CB -:10EB9000EBBA9428D6B915BA93785CAC85D103E961 -:10EBA00046FF973CC3E04FF526D6BFF5D8ED4DACF8 -:10EBB000EE888F67E079897A1EAFA180C2E7256E63 -:10EBC000116F5BCDF5AFA8D763DF258AA72C31BEC7 -:10EBD000B0711AD524382F4F0ACCB7D3EC1FE7A653 -:10EBE000EF9FA895595CBC35290C9B72374ADD3ED6 -:10EBF000885F864AFADE7F7413FFEE8003B149987E -:10EC00003778A1BF7A6056FFBB79CC1558875FDA99 -:10EC1000F9E924A00F524D901FA9BCB8A47AE019BD -:10EC2000800FE7FF43F5C05EC9B7835EE7BBEDEA3F -:10EC30007A602FC397C8AB6AEB80CFB9230AABDBEE -:10EC40008B3EF604E8DD4E23D6034EED7CFD18C462 -:10EC50002FA79A4807E69935F6C3C9B49B1B004F06 -:10EC6000E73FF9F0B1FB09D4913FEF65F5856A7B89 -:10EC7000A03FFB1F7323097E6248D0CD3FC9FE171A -:10EC8000F23AC8FDA93352ECA14258DF7E9DADAFE8 -:10EC9000FD480FBA45DEB59F7A96AEBEEB5944DC0F -:10ECA000B93A9AAFCA733D1AE783CBCB9B6D819C6F -:10ECB000761F793385D7A92912131D24C7A0CA9BB3 -:10ECC00029F6C2FEF266117CFEDC107CFE40AFBC71 -:10ECD00019AB7768D99FE101FBBECE197BF2490FD2 -:10ECE0008C67C0715A5E480A433D7F0B877FDDA564 -:10ECF000E7CD7EE5EE236FB69DDB6F1F14C91103D0 -:10ED000085EB76C2E61FEA12F93319FDD8D88339AC -:10ED100062FEF8FCFC83C3305E3457E4C55E62716A -:10ED2000B4B93CFFF5C1F442AC67EB0FCE735BD5D1 -:10ED3000F985D7389C2F982B301E7FD7BF4FC3F84B -:10ED4000D40288E30F84B8561B8FCBB3789EA79567 -:10ED50009D2BE0D929853D2C3F6392D136B4C970F3 -:10ED60007F0915A35B40F48628D55C496F4B146A74 -:10ED7000F4B9A785B6A9D1AFAC55422EDA6FFBB175 -:10ED8000248C9F3DE0F0E07C1F686179EAD07A290D -:10ED90003C988D8BE7B5855A641F8CF30737D3F306 -:10EDA0005FBB0D7D9E0FD1A2E7F910FEBD26224765 -:10EDB000E02A4BECFA804DA9EECB7E10E3B5E81BC0 -:10EDC0004D1500EF1C762ECC05836F26C697530B8E -:10EDD000F1FCA796E4C6D66AF61C79F68239E6C736 -:10EDE000E7572BCC20259E5498EF7B6E9E5FD3C0B7 -:10EDF000797E9BBAADCD1369F7BBCD258121EE811C -:10EE0000BDF783BDC7F5DF8575F91C2F5ECC97B4C0 -:10EE1000E83DBFCD077A5FCBCE776ACA6670937341 -:10EE2000D8B5C05E85E7F0113BB7E3089B7FC1D53D -:10EE30000E09F8A1C5CEE8F61F9DB776BEFACC4202 -:10EE4000065F3BE3D796B55298C18BCDFB52E322C8 -:10EE50000333FFB972F103C9FB64241FDF43B91008 -:10EE60007A508F7C778284B3587DA80DE5E61CEE3E -:10EE7000E716677AF0FB5B6A0B52209F3AF7D41AC9 -:10EE80003CA769C2CD569C7FC34B66F4E3EA574664 -:10EE900073819EB57084D92A429ED2E7731C849DEB -:10EEA000EFD3AACE0F6AF3BE6B53FDE3201FD450FD -:10EEB000192D84BCD123F207BB5F67720DF56AC3BD -:10EEC000CAD8931067FE6E6AA002FA9DBDE7DD49BD -:10EED00092075F47F9767EFF10DCD739A745BDBFA3 -:10EEE0008DAC57E71F496B2AC6D549BBFA3EECC328 -:10EEF00052BDD72B1FC9EC9A8D86C050B03BAFBD19 -:10EF000086D55B7CB2482680CF4FCC84E7F9859CC0 -:10EF1000F51626EA81D9FDE295F60338F3FA57D1C2 -:10EF2000BF1EF04AF159C7F1FAC9735716025ECFF6 -:10EF3000EEBEB210F0BA51DFE603BE18981E980379 -:10EF4000F03839D18F76A1A8F7BD547A5B9AC9F50C -:10EF5000E0BF480FFF407CFF32F530FC498C97BC86 -:10EF6000F45756971BEA62FB827BE274A7F17CB3ED -:10EF7000F35FC912C8E1FEC6B371FBCE652221B0B2 -:10EF8000BFCA2AA3F85ED99F650276A0B07FB5F309 -:10EF9000DFC0F1BA23D377C105F8E571DD5A3EB67B -:10EFA00029FC39B3B31F97306E6BF28452C6A15F50 -:10EFB000357FB40EE5CAAF70BF07E9926CE09F2CB5 -:10EFC0007ABC099F9FEB9C8BCF655324027E583DF2 -:10EFD0007D0EED35E3D5F5DBFA3D259144BF97CEA7 -:10EFE000E333F04B931C3103D06703D8D5748A0DFB -:10EFF0000A8B6F373808C6554A3BD57EA2C8DB6EF0 -:10F00000F1B3F373B67449788E56BA21909F0D7898 -:10F01000D5E46F7F91E93B96E9ECC9BF373A7DBBF8 -:10F02000810E1D06928BF57A7AB11F51BD8FB3BF49 -:10F030003AB897057F7CABFD340BEDA42F881FED0C -:10F04000A403107BC0BCFDAD685789FBBDEBE0C2DB -:10F05000AA7CFD02BEDF7601DF6F0BF23EA291F7C4 -:10F0600089EDBA843AB8485FF50C09757089EF25C7 -:10F07000D6C1455472B28DEF07598679F220E59BCF -:10F0800015A37AE8BA8EF03F9B621FE07EA09D46F2 -:10F090008CCFD5F1FADC60ED09F47B82B0BF88F14A -:10F0A00037AB63E7E755D4517F12EB943BD475BC83 -:10F0B000E7FFC9FA45F4EB2FEEFE670D7F8B7589EC -:10F0C00075D475498C1F35F3D4FAD1DAF8B9F083C9 -:10F0D0002F55CEA564FD6BE55C5696A0EF7F4CCE18 -:10F0E000F5CA430C8AA578FF0979888F3D6DE91030 -:10F0F0009A6C9518BD4ED2597D2CCFA9637510DA44 -:10F10000FCAF6712E63545DCD7F4BC2EBC3A1FFBDA -:10F11000635EB77E7F32D625D47A6AD16ED7E63B5E -:10F120001793DD9300055F9023B88FED1FAD2FA8D7 -:10F13000CC8AD717E45F667DC175599791EF7CD56E -:10F14000FA795A20814E2A8BA90350DC7F1DD96D94 -:10F150009CEE92781D8A4909117BC2FBFDBD776741 -:10F16000168B1FBECAEB9F1E4E4EC2F3175C06B62F -:10F170006FC325B33AAD5CB7BF266B0CE81586C7E5 -:10F180009FBC701B81BAC79FE83BF03C8450BDD543 -:10F190000BFA50C4ADC4F8BFE2F1D44BE59FBBFEFF -:10F1A000C9FCF36D722324BE77A9F9BA4D14060980 -:10F1B0007CA5E583FEDEEB4FAE6CC8F2AFCF42B963 -:10F1C000E51B81798F4B944749A5545E83BEDF636D -:10F1D000F480FF61E2FB8BC87AB7CA7F9FFB700E99 -:10F1E000EAC34FCCCC1F11FBA0C4FA1FEF17DE7F80 -:10F1F0009FBDF817A7FF4958CFC90A1FEE7B78209B -:10F2000099E995D853ACCE48BB1F48AB4FC47E1686 -:10F21000F1BD4E21CFFE45F2F4B57F923CA5FA1523 -:10F22000ED8D7EF3BABDDE0FE177CB2ABB7D3CDFEF -:10F2300085FB39C4BC82DDAC3EEF6D8E3F71FF595A -:10F24000AE7733B37DBF033C9C7DC764823C6A6963 -:10F2500029939F0D7E2BE6211A3A585D4EC34A82B0 -:10F260007103B1EF775646200A72EA8177AD787E56 -:10F270006C43E7F6D602AC5708A09D78EE1D76DF0A -:10F280009C113809E307574655F98EB28B9FAFA9F9 -:10F290002EC5F9A2DFEF30AAF75319B2993F2FAE6E -:10F2A000BA6CA1B7A99F43DF3B5BCBEACA830E9F31 -:10F2B000AD02EB14583C3DC9D38D71F0863DA824B6 -:10F2C0000816B9C2F37BB3916E1AF65494E0F90BA9 -:10F2D0001DE6123C47E83D2BFA6B67EFC90C433C37 -:10F2E0007BA93BF017986F7269F83AB057F3E8774B -:10F2F000209E7E76F77525185FD4F09DE0B7F83E26 -:10F30000DA3B4CE166A9871F37EA997E147AED0C47 -:10F3100018C74ECC7BB03AC3AE6964BEB5A76D7555 -:10F32000A8EB2F77644E3C03703E93A5F03C39CB9D -:10F33000CBE79BA8375BD09B0EF3795E7E1AAFA715 -:10F340002021534F1D45C1B7E7E5C5FC445BE4E50B -:10F3500093BE62767381CD807491DCCAE406A17499 -:10F3600001F6FAF858F704D8BF36A83D321EE0354A -:10F3700000C00F312E12FDE148C87FA429E321FF10 -:10F38000F1D88A51074C0E8847755F0DA8F1B4D9A2 -:10F390002AC1559D95E12F82FA4AA2341601FD57E4 -:10F3A000BEAD67758F6B9350DFB7E7D661DDE3B90C -:10F3B000778DAA7D46BDE43459ED82B85341EB7F89 -:10F3C00062FE21798FD4673DEB427022C6B0FE10F9 -:10F3D000C74A6EED0E95435CE641899DC149672F92 -:10F3E000B9209EA0C86077CCED64FBDFE7B6D92BCF -:10F3F0004D284F2596BF19EF4039A9ACBD5E067F59 -:10F400004F692278DEDDEC6C76DEEDE0769B0C78E1 -:10F410007FF96B5D9F79B91BB27BEAE8005CF5C6AA -:10F42000D821281D10F944513F27FCABB87CE5E7F3 -:10F43000C20B7DA4B5637BD9AF5C1FC5ED780D1DF4 -:10F44000F7F79EA06F41CF2FEB09DA612F4B26DC37 -:10F45000C726E8BA45EC2BF89AC585F3787DCE89A6 -:10F46000757F19C1CE8114F99830ABABD247D76400 -:10F4700021BCA2D78460DD7BEC724331C6D31A7005 -:10F480009CB5ECDCBABCD681ABCB4BE16A230082E5 -:10F4900013FB96E4015F86281D0CEE830E8AB35998 -:10F4A0001D94B23609F1A66CC013BA89624F47BCED -:10F4B000298F30FC1466333A17F96011F7CCCC0E63 -:10F4C000ACCC1E93B0FF6C8585ED3FE3FBA4935756 -:10F4D000BCBB0BF6753DC6E3CF075E1A86BF9F71B6 -:10F4E00061AD22411CEA82BD260FFCBD07385E9348 -:10F4F000956E62B326D2E701ACBF2DD8CFEA0815CE -:10F500007E0E96B2D6B11DE039362D8075C657B73E -:10F5100044F0A7275EB29DC43C1FB58B70DFF8E9AD -:10F5200017246117A9F4A1F0D7B47ED88FB3FF7761 -:10F53000FDAB27E372FA32FD2BA2F633E3FD85DF44 -:10F54000A8F52334EFF767FF105F485567F302C74C -:10F55000BBD0EF995C368AFA9BF8BE6F1236C3FEB9 -:10F560008CC9504BCBD68375489B248B17EC246DEC -:10F57000FD51BC2E88340E6175298D23D9791E8DDD -:10F5800057C255D42799A13E25B10E3699D5179962 -:10F59000A13E85DE6FEE779FB8A709BEDF7E9F4D47 -:10F5A000EC136771FB6AC2F3163B701F79EC966C23 -:10F5B000DCF733A19AC50353FD0619E8F2F9BFE958 -:10F5C0007C207763946FC1BE4A1DE47383BD65A63A -:10F5D000CFA1EE25BE4FBC86F4B94F5CD447897CE1 -:10F5E00071E6908D12E89F78DD4AB067FF387CB7EE -:10F5F0007DA907E3CDF13AAAEF125C67A590332607 -:10F6000035FE527CAC5FCA4C03DA19E972E029CCB2 -:10F610000B6EE936037FEECE2E40BC359787F11C8A -:10F62000E4D4E2368CE786D37CE7B29D3DF423E652 -:10F630004736B1F59F87FD6752CF77CF2FFA732EEC -:10F64000D853955D4646879A796C899F5343BF434B -:10F65000AFBA1C867FAFC6BE15575D8EA4AAE31352 -:10F66000DFEF6F9D821EBFCD6ED7D257A892E3E722 -:10F670007D7398D53FA9E9EBC0AAEAD127A92C3917 -:10F68000B8CA8FD7F366A94307754AE6D86C90804D -:10F690006FE6B4DD08E7999C4F8EE5C2F9276FE766 -:10F6A000DE7513B69DB1F7A17D2AE769D61E1C7BD6 -:10F6B0000CCE43F95BCE889BE0BC93F3F0AD4C429B -:10F6C000B2B615DC142A867D26D135DDA09F4A35D9 -:10F6D000F52E9A731BA02E13CF99B0327C66F0BA28 -:10F6E0005852C5ED77C854D176B3BBC40BF50C5650 -:10F6F000E2D9D30DCFB38DEC7C07C2EAB09A07E70D -:10F70000B3BA094EEF249BC7B3493404F4DB9C6FB2 -:10F71000C7F7E3F27A8F91E7B1D8F78F3EC7F6BD0E -:10F72000897A5F426C3960F7583D44D516E79E10E0 -:10F73000C59603E71C348B78216FFFC112B83A27B6 -:10F7400041FF1E9D787731FE8ECBF3F70E82F54E8A -:10F7500036A8CFC116D79772197D9CE7E7456EB3DF -:10F760000426C138C792664F82237867A65518ECE5 -:10F7700068A73DA50379E4E474619FC1E667AFF231 -:10F780004BF0FB29E2BC466740C1780009B4EB406E -:10F790007F3A4FFAB1AEB0CE14CB55287D194D81CA -:10F7A000E9399057AC397E17E615338FBE0F7520B7 -:10F7B00047F56D1352405FE4F3F333A8E317A2ED6E -:10F7C000435979E8F7C5CF771D2CA17C983A83ED92 -:10F7D000A79D423A148CBFD8D8FEAE49A5F9DE6683 -:10F7E000FABDA9BC8E64D2317F0AC40126DD16554C -:10F7F00058FE26A624D66D882B71E93D897C709D24 -:10F8000027A14DE05C6875FB06AFBA7D53F9D7437D -:10F8100012DB0388AF1EE0F8A214C5FDD6A1B1C467 -:10F82000C6D6C5EA139FE67EDB301731E541FDA45D -:10F83000430A815F306C6F26E665F696136CA7EF7E -:10F8400034ED3025AE7F83CCF2BE3C6E2E7EFF09B8 -:10F850009E815E7DFE9D748457BA5546790A117566 -:10F86000A0B7B22C9305E4BB8ECB79B13F7D628A01 -:10F8700009CFED6D5ECA7E37427B6E69B3DEF60A54 -:10F88000E0B1F96338928AFAD9C986889C02F8A255 -:10F89000BE8FA3471E0BFA81F1AE01BA1FC37E9F34 -:10F8A0008B52F9A0C473E39B9D6CAECDF7293CDF6E -:10F8B000C77E27A428FEBB2194ED687FB02909F2FA -:10F8C00009CBB7E5887512C507FDDD44B4D97EAF15 -:10F8D00074DE16E7A51252A1E0F94492E8D784ED50 -:10F8E00047793FA9EBF53F017D0C4AA1EBA1D7D7A2 -:10F8F000723C48DC3F958F6E423AB1063C4027DEB1 -:10F90000A4BEF71F75E4303B62624AB90BE2EBCD4F -:10F910006EAF0BEC2A011F715F8C2B9E8BEF79D39E -:10F92000FA1EF7352EAF3BF83E68EDF3977364F59A -:10F9300077F5745CEB377CD7A9FE6EFCBD9CBEDF0F -:10F9400013F7457FFC59AF32E03306B729BC6E96FA -:10F9500014A9EB5D48B9D7C4E4BDBABE65B2B4D250 -:10F960000DFC799DA9BE2B4ADF7F9DD3C96439F078 -:10F9700047C837BC3EBBF020F06735FC30011DE7BF -:10F980007A125903C472BE22F013FB409417C78049 -:10F990008F1A748121A9B4FD89BE6DD0D27CE4AFE9 -:10F9A0007772C6F49E9FA0C3F83C29FD01DE05FDD9 -:10F9B00069E72DE880DCD8810582DB4804AF2EC2E0 -:10F9C000EAB2A9FE62F5D79E9C9E7551E29C646ADC -:10F9D0001C04FAFDF5A610CA9FC9F61F611DDAF9CD -:10F9E000BCC03998D7CC919FE2F942C45583F61632 -:10F9F0009DEFF97FE57CA18208EE0B3B50D87BBDE3 -:10FA0000EA913F36A8EA91C5FCB47C2CE61124ECBF -:10FA1000DCA8095DDBD1BE0BCEB07A61DF4810EA0D -:10FA20006C4B319F8675CBFBB85F169258FD702FDB -:10FA30007BB1FFBA65764E41BD8D9D1F24CEA1FAE4 -:10FA40005E81385F88CD9BCA2F7EBE10B6DB6B3CD3 -:10FA5000E8FFC5EDC6F9CC0EBDB6D0D202E735F64B -:10FA60003E6788C5F7C85EA387DB89A8BFDB93D94B -:10FA7000773E31B33AF904394EA4F49EF3CF36EA17 -:10FA8000993DE8CDCD677941D95B06F8D802792B4D -:10FA90005DEF38E4C0F4C0E85CDA6F7EB12F177E0A -:10FAA0009A65AE81C519295D6DED26506ED7F8387F -:10FAB0009C0B7A1D697C4B1E88743516FACF1CF698 -:10FAC000293B2FB487AEC6E53A99DC0421F86D7C5A -:10FAD0007A322D3001C669B777BCD7500A794B23EB -:10FAE000C25FD4336AF937613E27F56C3E0E381F8A -:10FAF00099CEE7FABEE67329F49D48471984D1717F -:10FB00007F740EFB069247F5D0F90012B81DBE1B9C -:10FB1000A7F735DE56DDC03EE6ADB322DE6F9DC5EC -:10FB2000F231C12466A7425EC69D0EF127F6FD5B49 -:10FB3000D732FAB8D56C447A99D6558FF91752C591 -:10FB4000F2295EFA1FCC6726F14D849F58B9D93649 -:10FB50000DF781CE98AACEB7CC344DC6FCCE2D84FD -:10FB6000C5D36E9DA157FD7EA480C34CB2FE53A8A1 -:10FB70000F99A9F9DD482D5CB4F91A018FE6F26FEF -:10FB8000E6FBFB72E3799D219799D769C945F97422 -:10FB900069799D83FA189E23F09A73E1D6A5942F74 -:10FBA00086FCB818CF5B9F98BEE8F10DB4FDB32D6D -:10FBB0005760FBB5F43B961F85E78F1562BB4AFE85 -:10FBC0007436F04151D9AC29704EFD41331BC765E5 -:10FBD00009B4C3EF8EB846148C0297ACCA10C37E2A -:10FBE000D78FAC1F0D75355516D63E52F25FA3B0B8 -:10FBF0005DC0DBA35EBC02DA07A54F67F795171A55 -:10FC0000562445E0F7C5AA5259FFA9A39ECA8438D5 -:10FC10004155256B0FF356AC1D08CFE5CF66F7A510 -:10FC20008F7FC9ED63616FF939BFEFF51D6F81FDFE -:10FC3000667EABE4857D06FEF2E3EC5C3113AB4BF4 -:10FC4000F0FB4A143877B2D2C7E27B13AC4D6E900A -:10FC50007F37060CA510C7B559F35BE07CE701E5DB -:10FC6000156300DF13A81906FA8FF2D5F3C0CF335E -:10FC7000AFFC343705ED10355F09BA9D26F8A94A67 -:10FC8000CD37541E74313CAAF9818EFB0A8E7B95C8 -:10FC90005A2FC5E5BB866FB5F4D8AFDE276A391891 -:10FCA000D74F6B3A902EB309DB4FB40DE894F1EFC8 -:10FCB0006F617E06B9DB03F7F324EF1558A8D18FE7 -:10FCC000FD20E607660F19D57B5EF04711F6229BF3 -:10FCD00081CD960EDF65CFE97B3EF83138312FFAC2 -:10FCE000FD13089F356C3EDBA446FEFB22CC2E178D -:10FCF0007E6F83586FA77ABD6516B62FDE45A8DCE8 -:10FD0000C1D87DC915DF34EF20D7B3334CFE078D42 -:10FD100032FC4EE15CC4F36D24F41CD837EF58027A -:10FD20007F84F9E8E4D0FEA804BF0FE2C37C32C5AB -:10FD3000E3174CAE33BC887969E1D1D08F5CD5CE66 -:10FD40005B0B871EFC74A37DE6E6BF23185F9766F6 -:10FD50003DCDFC770462254655DDE9911A56572BB7 -:10FD6000E675442245A827250BE651E37127AD7CB3 -:10FD7000EB677F9CD0CF629E77F3FD595FCA4CEE54 -:10FD8000DDAD8BE03CF3AABBCD00C7F2BC02763EF2 -:10FD9000109F7F737908FB1964A9CF3C71799E2C61 -:10FDA000F260A4CF73DC3CF956E08B3B4DFCDC3AAF -:10FDB0000D5D104DFEAC3F3A11F1BB4AEEB7C4F3F6 -:10FDC000A99A73E2E698FACE9B4914BE59A9BDF1EF -:10FDD00020F2693768E374D7B1F8D50D3C4E37A1EE -:10FDE0009AE127754532FA75A9A5471532BCE73C5B -:10FDF0006B81AF0B8E40551EE635A263208EF0E678 -:10FE0000989F611E499C1BA9859F3F4F16F1C64BC9 -:10FE1000E297FEE6FF078B7F3A7CF713A91BCF839F -:10FE20001BEDE6E79192403EF093DD965F01F1070E -:10FE30002A772F5E0467141E51FCEE74066E87F756 -:10FE40006E23FE8950EB9D5A1DD0B3F83DC1F8F1E9 -:10FE500032EE474EE4FAFFB367D87EFD2ADFD04783 -:10FE6000C7837D7A584FC21EA81B67F0F96CAB0E92 -:10FE7000F5FEC23746BBC07EFF80D3E3904DB2EAA9 -:10FE8000770887862DAA733D86ED4C55B587776434 -:10FE9000AAFA8FEC2C503D2F895CA17A3EFAF0280B -:10FEA000557B4CF73855FF2B8F55AADA63A3535473 -:10FEB000FDAF3A355DD5BE3A76BBFA5C9290AFBBEA -:10FEC000281D7E3F81C1E3DAAFE6A8FA9F49997405 -:10FED00018F872DE7A56275E4196A8DE5FA2ABC3A1 -:10FEE000FA6BD2C6EC9C46FA1FDF17AF607D1AB5DD -:10FEF000EFE1A701166E52DB41B55D1BD6802CEEFB -:10FF0000751E86C6DED1DA37431C35706C3679240F -:10FF10008FFFAEF895E44AFEBB345ABCE2F9029F6B -:10FF2000BDA5433F63D91BCCFE5FB68BD5DF1592D1 -:10FF3000C10370DFD9611D094B70CE42E3C6F15297 -:10FF40008F9DA3858BD1A5C6B3D9A3C67352911A31 -:10FF5000CFC95E359E0794ABF16CF7A9F19C56AD05 -:10FF6000C6B3D3AFC673C64C359EDD01359EB36AAA -:10FF7000D578CE6954E3396F851AAFF9A1C5AAE7E0 -:10FF800042AE0E6C5DA6BADF2C759451494AE6F973 -:10FF90006BF17C89C16DDFEF933E04FE43F43FC6F5 -:10FFA000CF8D58CFBF80E21FEAF9BF20EB0F414A47 -:10FFB000564B070D9D1B30EF76B974F0761EB75F78 -:10FFC00005FE2FD17EA5FAF2BDBC3168E7BC0FF269 -:10FFD00061E610EE97F8FBB67384DC4AB42B12FD91 -:10FFE000EEFEE4592F3DCAFDF07EF5A8C60F7F074F -:10FFF000AA9FD05E5F8F71AF599CAE3F875B632134 -:020000022000DC -:10000000EEFA2CDA07EFD08994D379BD03F31E0101 -:1000100076C2308C93DC41227A3C3F1C2A4675A87C -:10002000BFB04EB386DAED709DCBED87F93C8E62A2 -:10003000340588C789F193BC74F86E7637EE33FBCC -:10004000BF17F44F2B008000000000001F8B08003A -:1000500000000000000BE57D097C94D5B5F8FDE6B5 -:100060009B2DC92499241012026126210B908449EA -:100070005804451C9660D4806193C58833498090AC -:100080008504D0D7B4A5CD40C2A28536B4A8A8A80F -:100090000302050B345804D4688745A44F5B636B97 -:1000A000AD4BCB4B0045F618B4D23EDFF37FCEB953 -:1000B000F766E6FB480AF6BDF7FBF5F7FBE3EBBB9B -:1000C000B9DFDDCF76CF3DE7DC3BECED38C612196A -:1000D000FB06FFDD717DCA988FB1DE8CFD01FF84C8 -:1000E0007A231C455607E4275A1D0F3D069F8E189C -:1000F0005879B30DFE28847E46436A2CCA9E96DD4D -:100100005D3F2BA13163AF2A1E0F1B0EBD265A5D2A -:10011000DB15C68624316B622C1427F853A64532B2 -:10012000D6C761A07AF04F61F18C0DB6D2DF6C4F6B -:10013000DFE6A531A9F8973FB628FBDB8F9BEA7075 -:10014000273B4604EBDF68BD6673F3129C6747B537 -:10015000CDB5D5C9D87B5804ED9EBFCF1250A3189A -:10016000BB62B2AD55A219FB2062DEF1DE0EC69E67 -:1001700009F764215C66CFBA6B35E69523718EA5CD -:1001800030BF2BDEB6910CE66DB17A5C585E65F53A -:100190000C8887255EEAEFC98856A1CF220E7FF82A -:1001A00023BBA8DBF9F3F94C50F8F89F847B46E3B6 -:1001B0003A8E185A935D080F63EB486CC76CBDA963 -:1001C0009F4B660E979EE0303EA27F31AEABCC6275 -:1001D00071A9D0E77885E3F54CDC83F36AE0CFF9C9 -:1001E00086A2F880AA99F79D346FBB7740620AF423 -:1001F0006F12F3B6F6167077641545F63CEF06EC11 -:10020000BF17E47EA0F8B73B392E317FD017E37FCC -:1002100014F216C3D5F7A643BE23DBE0DA0A459BEA -:10022000C3A1EB3CC6DE11F07EC604F958FABE1637 -:10023000BF2784F3F6098F1BFC0DD0BE68FCCB846E -:10024000A7E717DB683D5EE63033985F29739B7143 -:10025000FE9F8CFBCFD7DA001FF31D1E0FC2EDC12E -:100260003843F27B340FCF90A9306F36E6E6E89F33 -:10027000B175063692B16976BE84F9026ED399DB08 -:1002800084E3CC641E138EFBFBCB663703FAF83D88 -:10029000E098C17C67311F7D9FC3FC94DECF025480 -:1002A000FF01D646F9772372FAD7C1FCA63E919199 -:1002B000C60C1AB8FF1BCE17E8E5C15E9C5ECEF6F1 -:1002C00041B86FEC7D53F43B55D00BF0EB0FB11FF1 -:1002D000E0D7E1B929217C3391D30B33DAD3FE1176 -:1002E000DFB47646E5B0A19877DB1261FD770A149A -:1002F000DEE9AE2CC475E6AB36D60BE0DFEA50FD86 -:100300001618B3609CB72FAE0BFE45FA004F53DCB6 -:100310002A433CBFB902BE40BD3773553FD2C49497 -:100320004D93CE61FBC271D31BA361FD93BE6E1BC7 -:100330001E80B4A09FE9545B261FE31BF8DF976C77 -:10034000F3C41848EF4ED8676430FFBB076ACB0B85 -:10035000B3206F0DE6A73063B01CC63D8C7000FA69 -:10036000A9FB73EED86321ED186B52916FB63A2258 -:100370007B7D3A04B283D9E06F70DE6A71B4A71B4B -:10038000FE91E957F5AEB1C78026EF51DCBB1C44A6 -:10039000170E33D27F8991B9BBE3BB8B698AA01F4B -:1003A000C02EC8B37BC55C3B0BAF9AAFC07ADB1CD9 -:1003B0009EFDD8CFD2C99FCCC3F53123FBED308051 -:1003C000DBE2DF01DCA0FC543D403E03F8B3DECAB3 -:1003D000DC16C63EADB753FEB3FA044ACFD73B286E -:1003E000BD589F49E597EB5D9467CEA2D7B0DF92E9 -:1003F000B59F1B3D598CAD099378E4F35826E878F6 -:100400004DFF917F72C1786BDE3651BEBCB9695227 -:1004100004A4CBFA9F5A1901DF97ED525CF8BDB2E4 -:10042000C56DB6211F1DF3AC46F259F876DB1414E6 -:100430003BD5D714E601169A3DB0E82D1C6FC41FBA -:10044000CFC423FCCED68FA2F99CAB77D37CDC2D16 -:10045000EDC7E3A0FD85FA02CA273A8BDE45BA74E0 -:10046000B3CFCD587FF2EE76631294E7BB1537F227 -:10047000F75837F3FB017F9B4C7CBFD804FB05F298 -:10048000FBB8EC69CF3CC4509E7B3EC6F166C69675 -:10049000E6C7C1F729A3BC46AC37EB6BC6302FE9E2 -:1004A000FBC67CCDE1512DF072E97585E074E9C0A1 -:1004B000907B6F83FE5E3FA13215E6D579CD40F388 -:1004C000EAFC20DC0F3B5357BDA52FA5F661364C47 -:1004D00087F46159B83EE804D69DA9180D75C0FF90 -:1004E00017F67C2701E12FC7BD10DBFCD78F50DE4C -:1004F000FD85CB3BC69A3F7D0AE561BF04D7A3903B -:10050000BB6C62B3893F596D04EE878BCDCCC3F3CE -:100510009E2198BF10CE1E2C82FCC8BD49E3917F5E -:10052000703C4746509EA5EF7D22E5FB8EE0783B70 -:10053000F63CD9F98A03CBFDC4CFBBF63ED3F769AD -:10054000C855ED5B158EF37A15D6320AF8E3D50D52 -:100550001124B75E35B94ED6A1BC7EC6E6DA0EF5DB -:100560007EFEE3EF9E3A84E9FAEABCEF421AE38C9E -:10057000A57ECA7EBA6830B687FD9B25C23A7F71D8 -:10058000500984E53096BDF1F0CA44186FE8E6766C -:10059000435F4873B7290D980EE95F7002F7CD3EAF -:1005A0004E07C17DD86EA79A846CD7D7FFD11DB4F2 -:1005B000AF6BF7FBAC8D9F8FEFCB82FBFE60A5F995 -:1005C000FC0A27D2EBFB791E824713CDE3A596E9FF -:1005D0007FB89FE13A40A3C0797BCD2EDA6760B93E -:1005E00026C85FDA9FBAE55158E301836F0BED43EC -:1005F000255CEFB854E47B12E9A51AEAFB205F9D65 -:10060000EB8BBA15CAABFF32D00594C1FA3F7B67BA -:1006100001C263F1FEC726F5857A97C6309702536B -:100620002F7FE9EA246CC7FA3386AC7D697F43FCEF -:100630005C68F7A3ACF123904E8AD4661A87D5F094 -:10064000719E10FB176B03E0C40B92837A3F82CF3D -:10065000F83DB625E670120BE2A7A66585D308ED36 -:10066000877BAC2E15E9DFE94BACB505F743D8C75E -:10067000463B91B4CDA25FFBF4E4A26FB18F99C564 -:10068000BE24FB7BC2CC7C61D04F7FF8AEE03E6BDA -:10069000E6FBEF76900F48BF72FF8571EF728EA078 -:1006A000F66E94A749B0D9E6C23C939EB0903CBF89 -:1006B000D9F1A5DE5413CEE591D43F66C735BCD63B -:1006C00006EB3D1EEE9989E3CC17FB3733BA1C28A5 -:1006D000A7F784BBEF73D27ED8918C6B80FD712E0F -:1006E000E617ABA04FA586E853D69BDB1F3F0C77E0 -:1006F0007BB0FDCDD6D7CBCD655F1A582ED0C1B219 -:10070000C72C7E06F36E40F90AEB6A881C694539EE -:10071000C08E19AA8EC37E793B6FD9D5DFB2C83C93 -:1007200092130D8C750BAFD7819F3D203F0220EFB8 -:100730003DC0D763AF75A89CDE5B8F460F4779C974 -:10074000DC91403F775C33304FC87EA6EF07F05511 -:100750008FEB1BC7229827647F74B31833F22DB335 -:10076000C5FE73EB16F31F23F037A6F38308947FBF -:10077000CBBECC2339D8D3BA5E13EBFA35AE0BD24D -:100780004FD28A36201DDFFE85DD88EBBBDD383594 -:1007900019F51398F71338EFB15F18B4F3FE3A5C0C -:1007A00093BFD9F93FAC309F01F9F173B31FF9B191 -:1007B00005B7398063CBA22C3FF2FD0133CFFBA2FA -:1007C000CCA49FB644321FCA9196A9F17E9F13E52F -:1007D00021E3FA6B6FC6CBC344FB39F1D4BEAF053E -:1007E000408AF2E0FE70D17FED5BD958BE2289E4E9 -:1007F0004883C9BF3605FBFF81EADA0E78FBC06F7C -:10080000F099804E36C604EE57A1DF8D9FC7331C8A -:10081000E7031648AAC171CAC349EEDE66303C3808 -:10082000D586F5DC89B100EF03FFAD92DCDF980BD4 -:10083000791BC9EDD9CDF07DE354776238F63335B5 -:10084000DE40F351592D7D77F2761F9978BDB902BC -:100850005F1F0AFC005F13DF7BA64418916E4F3ABE -:100860004BDE7512BEDD890ACCF7A9B234867273ED -:100870006EC55D4EA297A627487ECD163890FD61C5 -:1008800003EB48D47FF9BF39F3B787213E679687DA -:10089000B5C30EC93E285F19E980F6333D6AC00230 -:1008A000F294CDC87777E9672938AE9BC6AD6E1E46 -:1008B000947A26849E4B2C2027A0FF43619E0F88AC -:1008C0004F0FE552F921504EBE017E3A5596B617AC -:1008D000F98A95C9F35FA014F1F07A8795F4CD9E5B -:1008E000E8A101E13F54D029E26539C73BE85D94B6 -:1008F0006F983D98CE25CF9938DDF8F685115E0BBF -:10090000A65909CF9DB3C3B758A0FC4121B71A66B9 -:1009100087BB15A8D7F092C56F70D27987EAF95EC8 -:100920008BA47EABCC3C5FF5621AD1D301B37FD7E9 -:100930000E2C7F3D8CE8A12A8A8F5BF54A92A03766 -:10094000B773158EFB9A85E8A02ADC114DE5FF1ED2 -:10095000477432D9EAF91BC20BE8AE16F5822A7346 -:10096000203D06E07B52D0D5496883F8F3D546D2C6 -:10097000BC89E521EF69E8BF15F1E931F372F63D75 -:1009800095CA4FDAF9F827D7F1F18B7F52F9360380 -:10099000BC9D2C9A94381FE671B23682F4BF3FD7C3 -:1009A000A90173149E5F3A1E4F877A97979F1EB9CD -:1009B00009E6DFB6F2E364A48FE295D585D8AEB838 -:1009C00062F914DC377BE2CBE22A60FE103E4E492E -:1009D00071C7A4C07AC6A6787A615A93D5B600F5D5 -:1009E000E0CBE6D667F11C9114E7E983DFAFBC7C6E -:1009F0007607D78F3BD2713F586CE4F421F7D51AB4 -:100A0000417FC7533CFD53709F080FCCC3FD232289 -:100A1000AB95CBBBE53727E7CFB76C3FA0C0389588 -:100A2000E12D8B2955FD39D8CF052510A5A412FC41 -:100A30003CC84F17ED812884BBC7C0F5B3CA9DDA07 -:100A400075E13F23CCAB12FF807695CDAA3B0C71AC -:100A5000CDFC669C7F253307EB3B8378827E084F75 -:100A6000CCF6E779DF07F857EC1A9487E780CA9845 -:100A7000433FBE8DEA413BC927EAF579B99EEBE7D2 -:100A8000C3D77751D0FF4549FFB3CDF25C4EE35F4A -:100A90007EB90F8D7F61AA3F1DE17F5911F576590F -:100AA000783DA00623CEF3979C9E1E37F90CE17487 -:100AB000BE6744CF9571CD23112E520EC11C7C060A -:100AC000A87F616F12D597728B153186ED2AF726B4 -:100AD0006EE5FA993897E244A17EC52F78FF9847D2 -:100AE0003E3CFF4292188FEBC77AFCE9D75B9C62D1 -:100AF000A0F53E2EE577A4E47357C254807FC62646 -:100B0000B3A6FEE548F3836EE877905FFB5DF65F82 -:100B10009EA2907E364087B7BE6AC7610BF2D3F3C0 -:100B20008CF8553FAF9A147EFE7BE1852E3CA91CC4 -:100B30006FA0064AFA70703DDC8470FEB00B1F0F88 -:100B400025815CAD4418A404E17320D79384F2FF9F -:100B500032E6715F88817C16EA411CDE322FE1ACFF -:100B6000A7B3951F2E486A83F64F09F80042FB2071 -:100B70003D76E92F26385F64E1B9B27CD899343CE0 -:100B80006FD60E82ADA06B3D0B36E55A919F166E67 -:100B9000CEB59684E0A161E7B0130E80F3C59D4603 -:100BA000178AE506A3FFC7A84F37EC549B7D8CCA74 -:100BB000AD08DF8BB623BFC37A0B36C7E4A1BE2CCA -:100BC000DB2FDCF4F0A0B210B80FD9A9C54376B37F -:100BD000363FF49036BF0D6543EF6FDF2E37A0CD63 -:100BE0000F3BA1CDB30EC016E041B5723C1D1CE514 -:100BF0003AE1003C0DF0AB2EFC34C0366DFA64D403 -:100C00002F36ABAE34281FB0BCE89E6CC87FB679D7 -:100C1000BE0BD15CAEFA167F1F7058FEF1A413B85C -:100C20001F5E60CDEF4F063C2C68D960363A70DD10 -:100C30005ABA3D6010F4FA02B7972DF26BCBAFE7CA -:100C4000EB15D25E9A194A4F7ABCC3B8F7B9614224 -:100C50005575CB869D812DB3BC10081D6036BA79C1 -:100C60008319F5B61B8FE3E3F462733B101EDE516C -:100C7000BCECD6BA09ECF430F863DDBB9370DEDE71 -:100C80001F29A437787F95710CF781F67D73EEA646 -:100C9000F4BE025ABFB4CB2D6C51029190B78F7243 -:100CA0001C6A8376F3FD8A0BE75DD26809CA33F8C4 -:100CB0005FD93ADD3C368694C3FC171E3AFC3705F3 -:100CC000FA2FDFAC6DB708E42CCAAF8A6DDF58424B -:100CD000BFCB73E3AD2D5B545CF77C397FDF588667 -:100CE000EBBA955765BD847E730633B06FD4F62E8C -:100CF0003A8BFBCAAD1B793B10975E5C6FB5CDECB0 -:100D0000C0F5565B592002E67122D2ECB6C3F7ABB0 -:100D10009B22C91EB6C002FA641EA52C2C0FDBB99B -:100D2000A2B1DDA7EF70BB58751CC777F5730A9D9C -:100D3000A3AAD18889F9E7797E110BD03A904EDCCD -:100D4000A1EBF36BF3AC899FBFAA8C81C3088F0A18 -:100D5000D6C6CF4F8047B7841FC0AB0AD6F9412C07 -:100D6000EA5BBAF6CCE5C1716B6C5C7FAA39F48D95 -:100D700025B45C9E03E53955DA699F4B2F0AC7718C -:100D80005629EE27AD30CF5542BFF66D0823FA9DA8 -:100D9000BB85EF37A0C7A6235C366E4874A19E3191 -:100DA00017F4F230E49B45E1540FF45DB2AF748068 -:100DB0005E8DF6F68D31CD01DC37363EE6243D1AE8 -:100DC000F45F824BC7FA30FF5605F560AEC76CDCA6 -:100DD00090417AF8AB729F5ACFF5AE6EF4622A67F3 -:100DE0007DB81EFF112E25440F4E8DF7A4A586ACAD -:100DF000AB6CA53B11F79DB2696603DA9D58F9CD3E -:100E0000F90DB60B3DB203D68FEB38A3141D378412 -:100E1000E8A32353F93E3272BC7B87A847FE853294 -:100E2000C3D447EFC0F11E373870BC2E78BBDDE964 -:100E3000388F331BC2F290CE468EE7F69F93B95C93 -:100E4000BE470C676E3FA477887EEF483568D28432 -:100E500070A03FE8E74C3EB73B470E2F227B1BECD0 -:100E6000D524E7F5EBB847F453662EFAF7DBBB99C8 -:100E70008F840F9BC8F585334B94AD7C5E805FC833 -:100E80008FFC6918D9E9CE88FD47C219E86604D9F4 -:100E9000DB85BCDA20E8658389D3816F113F3F058C -:100EA000E985113D6C14E7ACB902BF6C3DD76B818D -:100EB0005E389CD7270A7A61ECEF480FF90EAE67CF -:100EC000DFE47909F05E9ADAFBFA7393C43733FAF8 -:100ED00047FC23FF46F5C13D077CB07F56FCF2B1CD -:100EE0002806F5CE199BE25DD0BE6AFBAA2837A47E -:100EF0009F197D517618FF9C5F2DF077036FBF809F -:100F000037DAD715903F8BF14F07EA3B3F9A82EBD8 -:100F1000FBEB76931D4542CD4E0B9D9F16EF5F4434 -:100F20007A36E4DB797ECDE72AE60F69EDE0153FFE -:100F30007F2CDE41F0F6251912300D243148176F51 -:100F400033B902685F7E4F75C130A03777ACC6F900 -:100F5000E9DBE33CAE01BE6B9A55AF39FAFAF21AFF -:100F6000215F6AF6FFE873B4EBD5E8ECEEE5C2FF6B -:100F7000A0B7BB37A546F6FA140DCCB7B05B500F3F -:100F800002B8B802C8B7309F3422136EB76DD8F5D7 -:100F9000444E3BEA0BDBDE8A52B2827677E997E871 -:100FA0006C2E7D0EED9A3DF1E36561870DE28BCBF2 -:100FB0002DC7210565001CD0795A650A44DD06F06D -:100FC000A8DA62223953B5E7F91D4F219D7D68A14A -:100FD000FDBC72CF1BEFDF8AFAEE3E53AF42BE0C70 -:100FE0009B121FC4538D83DBC9245E2A7EF586D9EC -:100FF00091CDBF2F8F0DE2A772DF6133CBBE1E8E66 -:10100000139A0F9BDB6CDDE0A9B97D12D989767D3F -:1010100065463E38F7BAC2FA38AF6F5FBEE58D2835 -:10102000D4C7104EB82F497C75E14F571FFA9FF275 -:10103000CA70AA67C773454FF85B827B07D17724D4 -:101040008B81F1CB3FB2F80B11AF7B9745E13ACEE4 -:101050001A6B399D3FB32A1EF5BA72932FDE4E29C3 -:10106000FF5EFEECC3447F0B95DA787B16D177A246 -:101070008174065F22AE6FFEE699B4BE05CC43F4E0 -:1010800057FE8C5AE487F44B232BD8D70D9FF41DC1 -:10109000C8F9E4EC56402AACEF2CDA6D506EFC5ED9 -:1010A00015E7DC25B47F3F2CD6CAD852CA7F29F475 -:1010B000B64BA95D7E656BE879B166DB9A56C4CF05 -:1010C000F9FEEE3E384F80834FC04BF906FA55DFEC -:1010D000CDEFC3F1C31CC691A21DECA313F03BD608 -:1010E0006F35B9D1EE1DD24E9CE7F8F80F89F1614A -:1010F000DEE1785E3D1BCFF576FDFA0A062AD2DEE8 -:10110000D6CA42E9AB27BEDFF608D1D517EF71B9D1 -:10111000B2D83FB580CA5B4D813E58EE3F3C43217B -:10112000B9606181EEF87A9B49F0B5B61CE6695466 -:1011300042E1FB3AD7431780DE1508E1E320DD9852 -:1011400083DF69DD3F15EB6823BF98F4A72D14F208 -:1011500040BF6EBD7CE83550F8E3847C90EDD9E665 -:10116000EEFD3941B9E0A371AB603F413DA3EA43D5 -:101170000BED1B557B4C45089F0BBB8FBE3F17CF1C -:10118000A1CD928FB5F256CFC7E52F8EE8968F2F5F -:10119000ACCBED9E8FE17BB77CBC4E21F9F63F9541 -:1011A000B7B0D391DDA0277E5DD883BC1D3B502B0B -:1011B0006FBF6459D1B761A1DD3B80F0A383AB84DD -:1011C000A75E7EBE9FEA20F8EAE527C3D0881038E4 -:1011D0004AF849FA64CC43E374D1B1A45349C75DDA -:1011E00074AA5FAF168EFA72C34046F3297AD9C447 -:1011F000ED672D0AE9DBD0EE78D270E253376D7FD0 -:10120000ACE97852AFD0BC5F976FD6D577EBF2459B -:10121000BAFA1E5DBE5653BFEAD051333F1F0434A5 -:10122000F52C75F7D039E37A3DC2CFFD3EFB3F3751 -:10123000FB902EFA7598512E9A56325F24EABBAF76 -:10124000A9A4EF5E717444A15EB22A8CEB6D57ECD9 -:10125000221FC3F31DBDCDAB512ECAEF1D61DC4E65 -:1012600072A5A8232A26E49CDEDEA246A13DB6CDC7 -:10127000CF0ABA8F136920B8B6B19ECAB9FE96AF2D -:10128000DA92EBD01EDAA4BA804C58D98A5951149C -:10129000BFD0927AEF6CF83EFF372A85015C09E7F0 -:1012A0007605E6731B317EA094A3907DC67C8F8F5C -:1012B000817595B6F03882B2755AFC2EB0CD880E85 -:1012C0003850EE68FDFD0BF15C978AE73DEDF70ABB -:1012D000B68EE8AD42C7171E61A7D5F3C516C9176C -:1012E000B92C57D863C8CFB154C8EB7C35EBDED9E5 -:1012F00000FF2B275466817C678BCA56E37A772BD5 -:10130000E4EF418700F2DB62E04B9C8F84CF45E441 -:101310009B8C9EF5928B2FFD65E4F7914E0E7C9C85 -:10132000837ED88B073E4C7F15F307FF94FC31BBBF -:10133000BEFE84D7FF360FE5F095D72D0CE9FBCA2A -:10134000EB6F26A35DF0CA2B163A2F5F5969E1F6C1 -:10135000E6D723FDE88FBCD29FEBB90DAF7D95D3C7 -:1013600046FB6E23E1EBED8166AE37B5FCE749B491 -:101370005777B6C0AA509F783D82F8A7E69530F21D -:101380006B5F79EDAB91A1F10FFFD3F548FFF595B8 -:101390004836FB45A45BA1D7D7BC3AFA79F4E756A7 -:1013A000EF3F6C2E85F209BFFEAF1C949F575EE4A1 -:1013B0007AD26553DBB3686BFCD3C0393F3525A2C5 -:1013C0007D0E3AEB0BDC96F6E434E493EBE1C2E1FC -:1013D0007005E080EB02B894A3DCEF091E97FF656F -:1013E000E1F1F93C2ECF6E61E8FF0DC245E17E844C -:1013F0009648BF55A1F5F3EFAF7F9583F2E646EB34 -:10140000B5A59989AFFF7F59EFE0B47F55FC727A9B -:101410007F71A083C7F5E9E8FE7ABA3EF86F94DFE2 -:101420001BE9A2F9DE24BFDFFD2FBBFEFF1B7C976B -:10143000FFCBAEF746F8FE8DC077A41DFD8A575E40 -:10144000FBAF64F62DD6BDE65F96AFFFF1BAA5BE41 -:101450003E5E759DC885FA6FB1E6F75C4ED23EBA26 -:10146000D53BF6A7493B093F1F4D607C9F9E60AD71 -:10147000247D7342BFF5A41737B03CF243F8FAA9B4 -:10148000E48FA1E00B80C39B09B97EF2271903FD0D -:1014900096417E7C5235C55BE9CF8D13C22717A0DC -:1014A0003E7A7405CC0BFA391A69B0A3AF78623F63 -:1014B0003560C9A1B41DD3E3C9F79C40BD65A24DF9 -:1014C0007B7EBA47771EBACBA12D2F602FF642FF45 -:1014D00059419689F9613E93B07EC8B9F1A7697602 -:1014E00082CB5DACA9D16EFBF6703A23E0743D1C53 -:1014F000FE31DCAE839338271B457D3DDC8CB6473F -:101500005BB19D91C1B997AF97CECBF2DC7B2378CD -:1015100032719E368AA1257C8DFDB89F34A45F82EE -:101520008B84FBB785B7C4931EEE12BE126E7A3C55 -:101530001C446354EF20FCFB19738DC877B70B3D37 -:101540007EA23186E7FBB5AA45C48F7E82FB842F3D -:101550005C46D44FC6D96228EE9239FAC7E07916B4 -:1015600055CC6F92182B1915335281F5261999CF46 -:1015700002E74DF4A1911DF511A37FA513C7E1F674 -:10158000DAFE466E9706EEF685E7517DB719F2DE74 -:101590009F2D646EA8EF4D622E85D767D1B1148E52 -:1015A000C6548CCB8214DB79A379BFDE3ECCBF92CC -:1015B000E393F082C726B45F40BF6E432C6F1F9544 -:1015C00047ED7D06DEDE6D8474402AB7AF77ACB29E -:1015D000D0F9C3BBA67F3ACA8FC2F15ABB71713A28 -:1015E000B7ABC8F4CD74CEEFAAC195807A7149E348 -:1015F000203A0FA9E145D52FA1BD7F6F04D1A37774 -:10160000F5039347E0FCF6C6B9707AE7A7EC1BC96F -:10161000EBCF79F88FF0DDB3338CBE5F48F7F44938 -:10162000877ECF2B8E792FC187929947CD09308441 -:10163000A779EA25B4FF4DF1EDFB1DFA19A7CC50AF -:10164000A9FE14C6E32B596304F9A327FB3E3726F2 -:10165000407F93E1B081E5ED61F6E425307FAFB0E6 -:10166000F7A6A673BB8B1ACE3C2FDA705EFDD35360 -:10167000E0FB64D67D3CAF57D61FAF6C46FFD080F1 -:1016800009DC1E2FEB633FD8EFC274EE5FCD117003 -:101690009179802BD52F5B6B694FC573CF5A53203F -:1016A00003D26732C7E7A54379610A9BB409E1FE1B -:1016B0005D956DA5F97678C9CE1D99E9403C788095 -:1016C000A429BEB0C9E940BB57FBB8E600FA07DA67 -:1016D0009F74BA1A1C84658AC791E7ACF671818140 -:1016E0006897EFC8E57E8693F6B6483C1F96DAAC5D -:1016F000149F23E37AE6DB399F0F68685B7F0B9EBC -:101700003B1F535D5B213FFF31EE77F9C466F52B3C -:10171000785EDBC8F994ADD3C6F130BB8BEC3DA548 -:101720004DE3CC78BE2CB3B9CDB8CE8A0C4F11AEF8 -:101730008B7D0DF01B89719C8C98C1DBE4A538135F -:10174000350AF80EF9C4E888C273AF3E0EA846C445 -:10175000FDC8FCA130CF1CECAF24DAB117E9E55489 -:101760005D2AD93D3709BA2BC43846F44F18DB122D -:10177000713EE1F81DE05F186B4FB7113D87318472 -:1017800043BBC99E8EF4DDBE2ACC807EB6C2959C3A -:10179000AE81CFAC4668FF889185A3DF2043B42F8C -:1017A0005E612CDA02F97E56668C8C45BACA25BA7F -:1017B0006ECBF4E4207D7EF603360AE9A174DD06E3 -:1017C000F2AF48BA60C6D6897130CE67DB9D792802 -:1017D00037251DB5658EAF4D0FA587190AD101A418 -:1017E0008753891EA63D8CFD168E0F0C5C9A85E7EB -:1017F000D12AE6C6FD3D81B9504FE8641DE47FEC77 -:10180000B4991D68E792F244CA0DC0ABDB1A1FA45D -:10181000831DB0DF1B4D8CEDACB752FA42BD9D1954 -:1018200041C6EDAE4FA0FCDE7A07A5CDF599F4FDDB -:10183000C57A17E5F7D78FA2FC817A37E50FD51760 -:1018400050FA4A7D117D977209E0427248CA152903 -:101850008F4A6DE676F4474AB9A4A79B7900DEB1BA -:1018600079D49EE49E9477B80E435E501E49FCA640 -:101870002845BE0427CAB1B63988FF7CF5E29E83AD -:10188000782E2FB7B9E89CCEB8DCEB047A45B824A3 -:101890009BD921B4BB362C71B7AF7106E17F7FB9FC -:1018A000C28C2174F5406D183386EC1B0FD6C568C9 -:1018B000F2C5757F78A30FF45FD1CBB30BF176F24D -:1018C000879F3EF327F8FEDC0FCFA721BE611EDB0A -:1018D0009FC071978777CD2316F38D26F2470D9021 -:1018E0007610F8877829619CDF9EFBE1DF89BFDBFA -:1018F000EB2C0ED4873F423C015CFF2CF054526726 -:1019000021F879579DDE7310F97CB999E45C49A3FD -:10191000E0C3B500CF10FFEEA94446F608D0A659A3 -:101920001DC0EDD40FCC8108E8FF94C2F95701A582 -:10193000A018E3FED6BEF901F2BF527782FCE71E83 -:10194000AB8DEE35319FE962687F4ADD71AAC7DA57 -:10195000FAC5A0BD84F6B13BD0EFE8363B60DD4868 -:10196000D388B792CC232C11FD264D8A1DFD266508 -:10197000E27BD95A85FC9318773303F4BE77D355AD -:10198000C26364BA91D2CA7426F4BA26DA9F24BD1F -:1019900096AD8376C8174DB9E6052172B8447C2F01 -:1019A000CD34502ABFB78B7EFBAECD9D8DFA445F00 -:1019B0002CCFC2346F36C2B7AF6D925109C1FFC789 -:1019C00038FE089C071FBF12910AFFF768668A79E4 -:1019D0007E16E287EF5F729C92CCBCD518C759B2D5 -:1019E0006E1C4A5FD6607225F4827A67BAFAE17A91 -:1019F0001BB3F278E5AA1EF60F693FFB0CFF1C4DE6 -:101A0000EB26BB6EC5DE5FEC7D057AAEF8D842F8FA -:101A1000AD182AE2A7B2FC23A793A1516BAF9EF8A1 -:101A20008BBF4491FF613F8FAB8494DB53979773D7 -:101A3000FBAB0BF8AA1BFFCFB1BD1F47756BA7DE31 -:101A4000AFDE949DBA46F93A0AF507B99EFCD7BEB7 -:101A50008CA77928D7C8FF53F3DAAAF8EEEECFE8BF -:101A6000EDD55DF66C61B7D397EBED757D32747E85 -:101A70000123A3FB58D25EC7D4AC68B4EF7F29EE34 -:101A80006BF474AE91F6ED9A4DD0491CF0A7D111CC -:101A90008DFEAA2B3DE8D30F66F0FDFE92B0875F66 -:101AA000D9ADD239E7CAEE48E2A7C5BB7F761CFDA7 -:101AB000878BB729348D6AD64A700378326BE83E3B -:101AC00086F16671D7CFBBD39F168DFB48E52F22D9 -:101AD0006B91CE16352BEEED309F4EAB23BA77C807 -:101AE0007C6ECBE0745669691E497016F3CFCD70D9 -:101AF000D077596F51CBCFC87E0CF52E931EF4CB07 -:101B000008F4F523BC7F87F3BCB079980BFD7E8B7E -:101B10009AF72D263D6277841D8F0CE7459CB0EC2B -:101B2000E7CE0CCE9F776670BDE582F0075DD8AB3F -:101B3000923CC379227F9D57B4F1789345BBC9028B -:101B40006E9F0BFE92F51735B7470D84FA670FFDB0 -:101B500081D259625D8B6CAD39B8FF9EDD1F41FEAD -:101B6000ACB3FB9F9EF42A8C77A9795C2FE407D94C -:101B7000FFFC0C13D5BFB4592D4078313F8F7BA9A2 -:101B800046F80E0B9D67DC169F3394EF78DCCF850B -:101B9000FDBF8A326405F1596DF558F15E63CD7E63 -:101BA0006F11CA8DCF140E4FD3FE713EBC8F54D32C -:101BB00092CB909E89EF12A9FE5A43483DB3C94586 -:101BC00042D17868AA3B89E02CEE13897879BC1F52 -:101BD00087F267E9542BF927E60D75CCBA1FE5E4C7 -:101BE0005B268E977E8E27507F9BF74E1CC54D2D12 -:101BF000753A66E1FC97BDAB52BCEFBC61420E2466 -:101C0000B48DC0B8C5AAB50A73C33ADB9D5C6FA892 -:101C1000F2ABCC03F9BE400F3E00C5FA8C14214F45 -:101C200003E978AFEFA97283DB0CFBDF4933F3A93B -:101C300068377A91C73357A5F0B8E1A790EE21AD88 -:101C40008A0DA4C7417F17053EABA605D2314EA22F -:101C5000EAC5448A93B868E67E4BFC8E7ED2AA3CE5 -:101C6000680FF57A8978586C1F13423F55252E0767 -:101C7000D653635D8E5C1BCED77E99F4D89722191C -:101C8000EAB18683913CCEE9E7615B2D2178DA9257 -:101C9000C1F5E55E028F6C2E8F877C5CC4633FBE0E -:101CA0003DD18FE73759FF7193670EC201D781FA93 -:101CB000FB2273533AEAB772BE8BA29A689E17054D -:101CC0007D2F0A6FE2F1D2E29E2CD6C77CBB8951F0 -:101CD0001C77C72E0BC5939C4F6C3D80E39FDF356F -:101CE00088E1FADB9DFE0587A81CF447C05BC50BA5 -:101CF0009600AEE7DC2E6E6F3E67E2FAD8B9A9090E -:101D00000EC45BC1B44DF3C81EB3CDA220DECF29F3 -:101D1000CC9C80E5DB7BBB7CD8BEBE8EE2A42B4096 -:101D20004CE07D1C480BF05ECDB9ED83283EECDC29 -:101D30006F54BC1185DFD7E2770F6B9AF73D84C7EC -:101D40004E7E7E3AFFC27F0E0ABD5726D38A6DDAD9 -:101D500038384927B2FC4806B70F1C11703E9EC1A7 -:101D6000F7ADEA88E6C753689D1CEE80273AF7C1B5 -:101D7000C61FF9F4708C834853506E3C0574F534DB -:101D8000DA1576F2F3D5F9DD268A0BAF3818E9A615 -:101D9000B8B335B718280E42E57A788501C047A94F -:101DA00042FD564CCBA47BBB006F3AC7766C57C53F -:101DB000388CD970DD3B789C6F21EA8A549E4DE5C2 -:101DC000E744FEDC816CD2EBA07F37DE57AAF8DE59 -:101DD000F7391CA797BFCDC88E6125F95AD5E5C73D -:101DE00019138DFB5DF59ADBA2F13E1F7B4765A8B9 -:101DF0009FE8E174D5E8EA8372B577A690B3079EB1 -:101E000031A33CA814F7432A5F50B83F19F80CEFF0 -:101E10003B56AEBEED09A2CFDF99581AACE762F38C -:101E2000CFA234F81072B0ABBED945F52BA13EF667 -:101E300053B9FAAD289ACF0E13C5995CB75FDD6C24 -:101E4000FB17D49B6ADF451FCDDC8E72DDFA59EBA0 -:101E5000BF7D0CFD7FB13BCCE5A3AFCD74AFEC8271 -:101E6000A97901AEFFC29E3092471762B87C380B49 -:101E7000F2D39781F3B8E7271497F5FBE9741F6E47 -:101E8000A15FDBAF1CD79869E27416E78AC6B8BEBB -:101E9000EA77B87C03BCDC4BEDDF31517BFD3A4E79 -:101EA00067F0765DFCB92782E8E1425F8E970B7B95 -:101EB00033683F6A8FE1740EF34DC6FB7317F66407 -:101EC000E4D2BD34546E801E2AC4F9F6424C73B27B -:101ED0003DA4BCDD24CE6901A88974836D40EFABBD -:101EE000A8E37A55A5751DC587605CEDC83C4A031B -:101EF00096D8EBE363815EE9FC787FA6B053E27885 -:101F0000F1227E9BF49D6633CA6F8FD00BAB76EBCC -:101F1000E36B79F9AD998A8C0371F492F1BC48872F -:101F20003E85E24C2A1B972C423AAFACDD703FF263 -:101F3000999C7FA59115E039AC5D51691EED61EC6E -:101F4000C169B86F848E13AAB7C979E254E3495FB7 -:101F5000A57DECAE4CBEAF61BE09FAAB6A54D6D1DA -:101F6000384E799EE5EB927002709831AEAF7D9C51 -:101F700028EF61DD729EFA75CBF93C90C9E551BB43 -:101F8000D3F1933188E7DFAA743FF6EAD7C3A2639F -:101F9000BBD1CB82FBBA3918DF8AF1BE487BD04F68 -:101FA0004E26976B95183F0BF34CDFAC8DEBCEDCD8 -:101FB000A6CD0FDEADCD67EDD7E6735AB479D73134 -:101FC0006D7E1A8EDB9B9FB3F13E2E9EB331C5739F -:101FD000B6C3C2CFD998C77336A678CEC6EF78CE2F -:101FE000C63C9EB3318FE76CCC4B78E3791BF3781A -:101FF000DEC6F2A7059CAA449C24E201E99DBD1C13 -:10200000A6B9EF73E5357E8F03E880F3CD1C33F17D -:10201000CD535883CE1DDCAED477BAD581F1BE8FB7 -:10202000C47A5665A25F54695D9D887833B651DCE9 -:1020300069CD2B3CEEB42A2FCC86F68DB65567576A -:102040006338E703B19E47B1FE1553C70E846F7521 -:10205000DD51BABFDEB6C2F1CE1D1C7F646761E5FB -:10206000B1A43779719F8BED198FFAB86FB64E1BFB -:10207000E7AD8FFBD6C77BEBE940EA7BCF993A12FD -:1020800051AE9FDE655D87F33F1D26EE9FCCB6EA1D -:10209000FCFD424F5BAF6CC5FDFA1799B1DCAF7226 -:1020A00002F4F36EF65999965E1B467A78577E9D38 -:1020B00062A07B7109F1B40F2D13734A563ADAD737 -:1020C000A09C5B64A07DF32AE86538DED5F754D286 -:1020D0001F32361934EB19E40FD7D0D7909DB1BA1F -:1020E0007B0D7D35F5871E4AD1DD6B18AC8DA39F26 -:1020F000B1E2309EEFA7AF1BA6A95756749B0E8E78 -:1021000062DE427F2D83FDC30DEB7B6AF9A664C4BA -:10211000EFB2459DED6B503F7D298CEE8595E3FF39 -:1021200003B9580E7DE27DC6F2FDE23E709D761F3A -:102130002E15FB50B991F9ECB1413A2CB733770C1D -:10214000B45F34B8352780E78ADFFC61A43D05CF52 -:1021500015E3FAA03C4A36B9290EB66A5F5ACC0A92 -:10216000E8F758AAE7A34CC0CB99A6A33F2EC6FD1B -:10217000701F3FEF9D5EF7AB288A1313F4966CB285 -:102180008723DEB734F1F838B48FA9B141BAD8D279 -:1021900014173ED0165C6F900EBE263C017EB81D13 -:1021A000A7FC08F93D3A9BC57AC7293ED4A7E5FAB2 -:1021B000968A7D850DE4FD3C24F267C4F942AEF3B6 -:1021C000E2A0C3390EBC7F517F285945796ED8BD36 -:1021D0002311D2D116CF97B89EF22D697F1A03E34F -:1021E00054FC91AFE7938D13A246A3FEB9C7E42A2E -:1021F00084FC9AA6E7CD78CEAE30FACD145FB96BE9 -:102200008B19E38BEFDCB985BE2FD8E9A578CA8599 -:10221000AC96CE9F9FC97704043CCAC72B9BED3078 -:10222000EFB983B8FC280FE7FE3BD08FDEC0F73B49 -:10223000AEEE5472318E6746D13EB317BE470D12D3 -:10224000F783747CD2F9F6F4FCDE040F7E5FE38F33 -:102250000C4EF1A9D7F3C5F46B4EE28B19D786D09B -:10226000B96C6660103FFF66E9CEBF6FABDC5ED72E -:10227000C2F9A0DC1CE8351DF9E47513E9B9D5B045 -:10228000DF8CCAC37335EC8D90168D5135F45A33FB -:10229000314243CFB359ACE6DECB7D183412929F66 -:1022A0005198AAA93F6BC6101DFDE705CB498EDCEE -:1022B000AAB95F57BDDCE75048CF1CAFFDCE789C74 -:1022C0002063776BDA57B369C17A48DFDBB81E5CED -:1022D000BD3F662BDAFBCA0DFCFC34DBC3BF2F3ECF -:1022E000C4BFB3D94CC38703525D7FE2FBA289FC14 -:1022F00002D29E3E1BFFEE06FE8C8577DD0FC77B6C -:10230000F1688FD0DC9F16FE409C37E2A15AD88D31 -:10231000AA33B9DDA8DAD76AC6770700FEC6B8586F -:10232000AA678DC3F8C82685EC8A982EA778496DD0 -:102330001C16F687718C8B4FA85EE4137D7939BE2D -:10234000DF83F87D85C7952EDCA48F835C47FEC8AC -:10235000C5680F0AC1DB53831C425FF1AFEE8BF0FF -:102360002B5472E95EE4EEC3668CB39B31232617CF -:10237000F9464F5F52AE033FD3F9BBF3EDA3445F81 -:102380009DE546A2DF1BC161B19BDB51F574B780AF -:10239000B59AF19EF882FD8A0BCFA3580FE1D117B1 -:1023A000E951078FB8D8EBE120E1D305AFFDFA384A -:1023B000370EA78587147FA01B38E9E7DD13DCE41F -:1023C0007A16783C93502EC8752DC4F963FF307F80 -:1023D000EC5FFA21D8283D7FA6927D6A71118F8F1C -:1023E000D5D3C3B46BDCEE72DF3523A5330AB5FC5D -:1023F00088ED902F665E8BA7F26F4B2F8B619EFC52 -:10240000FED3CDD1895C8794BB417EE0F7066EF4A4 -:10241000BE8FDEEEB8639088131CC14668E29185DA -:102420005CD5B7D7C7234B3D40BFBF78230D1437CA -:10243000D9694B21FD42CA598FD83F3CABBEA47A23 -:102440001EA8C76713AFD96F3CC2FEB7343285DE12 -:1024500063485E11178F78F286D929FEDEBB42A54C -:10246000B8672FD47384E827AB1B539371BF38F53B -:1024700048C6B33ED0DB4F7DB757FC2818E7F42A97 -:10248000532FAB2358EFD4AAFC648CD338BDC13290 -:10249000DBDF0DBC5AC5FE50FDC30F683FBB64783F -:1024A0003B6A36B4AF5AF5521486F957AEE2FB7860 -:1024B00079AAE79D41BD713FDFB2C38EF0B36FC90A -:1024C00041BBEF49D80EB0BDD41F2A56E5F741FDF8 -:1024D000A2EABF8F3E6BC77BD62B4CF1A87F9E7BB9 -:1024E0000FF64385F633D21B3E0B832EC89F164949 -:1024F0007684CF14E646BFD245C3E1BFAEC1736157 -:102500006E737A00D2EF593C2771DCCA55CF93DE47 -:1025100052F1E88A7455C57ED3A2BBB39BC87487B9 -:10252000D8B7517FC714F5778C9341FD1DF3A8BF31 -:10253000638AFA3B7EAFD9A4D5FF2EA7713925ED6A -:10254000C9031A3A72D17FE71BCF326B69BFB565F9 -:10255000A2BEBE4C0977A13C5A86BA12E6FF1246CB -:10256000E758B62D91EFB702CF7556EE37FA4ADC31 -:10257000CFBDBD0374B210FABCE39A9585DE9B1DF6 -:10258000C76234F909D6444DFD7CBB53537E67C204 -:10259000204DF95D8E5C4DFE9ECCD19AFA935DE3A1 -:1025A00034F97B47DDA5A93FD53D55939F5E304764 -:1025B000537F669157533E6BF6224DF91CCF124D57 -:1025C000FEFEF2EF6AEA3F50BB4253FE95014EA475 -:1025D000402F2D78EEB2E0FB29564ABFA3DA8D28B2 -:1025E0003796FD36CD86F81E33C150DB9D7D3F63A7 -:1025F00030D787CA86B85306F7E6EFE0203DF617D6 -:10260000EFDC8C18CCF199C480AAE8BCDB9A88F482 -:10261000ABAFA72F1F1371E4AA0370F893C14367F0 -:102620001A410E8DB9E5C8B054C89F18BC60A611F8 -:10263000E4C698DB8EFC2A05F2AD837FC1CB871EF2 -:10264000B98AE5B38654F2F2E98C548F3FBFD07754 -:10265000A60FE77F47CA3A17B793747BCF5CA608EB -:1026600007BCAF8D70C03400F48BE911A05F4C8FB4 -:1026700001FD96817C3A0EF48BE909387FE2F77F01 -:1026800087F327A66FC3F913D3DFC1B913D3563825 -:102690007762FAFBFAD994BE57EFA176EFD797533A -:1026A000FA417D2D7DFFA8BE8ED23FD7FBE8FBD43B -:1026B000C1D28E11609AFB01E867447FE221D3C545 -:1026C000503FB0F4574AFF64432D6B8B4079D1667D -:1026D0008CF9D41AF43BF66C0730B24F43F4B1686E -:1026E000E62E1E4CFA423F3BC96FF1DDE4F0781153 -:1026F000CF7F744E4F1BA6E2BE55FB06BA65FF683E -:10270000E8FEDDC411823E460D712F20FA10FE75E1 -:10271000E9DFEE8A9B09F1BF1B42E275E85F48DC06 -:102720008DF483CB389FDBADFC9EB1F473CB781E68 -:10273000D95FFE178CE4C3D8B546D25F228D2C80BA -:10274000FDCBB89DB1D6E65C8C63185B65A37BB509 -:102750007DE0BB398FEAB95548B7FD0DEAE704FDC6 -:10276000EA7DC4FCA19CE69FFF8587ECB063455CD5 -:1027700001B6B7F2721FB61F8BB685E194927C7AD0 -:1027800006EFEDE605FDFC583F82D70F607F03FFA3 -:102790000EE34505F9A67F6C732ECAEBFE8B6D74B4 -:1027A0002F74F3B800BD6745462780CB74797EB29D -:1027B0008ABCF4E7EDEC4376A40982D7BFEFF06C56 -:1027C00042F81759EC7F89203E4BED8FF6C9A9429C -:1027D0007FFE07787B06E940C253E245E251E223DF -:1027E000247E8AF0D0135EF5F8D4E351E22FFF8BFC -:1027F000205E10AED7E32D8857B4E7FEABE06DB88E -:1028000091BF5F66A9B2D2BB6837C2E3831D6C5229 -:102810003456717A46207EBCD71CC7315FCAC64D7C -:1028200042D4CAF2B1583EE2FA72CF171DA6E810A0 -:102830007CDF2EF03DBF87FE643DF91E83ECBFB107 -:1028400087FA6F85C9B80BB72D776430FE71593E92 -:10285000877F815325F84FC85A487A32B3713DD3E8 -:1028600001FFA15C9AF47511BD4FF925DB8D9E5BCC -:1028700036A997563F2DD0F9ADEF167AE9DD3ABD6E -:1028800054AF577E3E58F8B39DCCF92DDF9DBCC6A2 -:10289000E5DACDBE3BC9DF2D9D28F82C49D059AAD9 -:1028A000436563908E9887F6C963F86E690EBEEF34 -:1028B000E9A3FC5DCC4FE93D2C40FBEB6410C498D0 -:1028C000BF174428E68F464C29C6BB7113864D18A6 -:1028D00088DF43DE658B1CD29BDE65FB0F7BC8BBAC -:1028E0006C47263AE87EE5116B2AE95FC887A61097 -:1028F0007BE06F607F1A08FBC751D8BF307D03F6BD -:10290000AF81B0DE3761FFC2FCDD992B18B69BE4C6 -:10291000D0C6EDC8F6F7D827C0C1A467F8DD93F399 -:10292000723F84EF5B311913D17EFE56CC2D1371AB -:10293000BD6FC5F431F0D462A634FBE0C0EEF443C1 -:10294000C907C1F126D1787AF84A78EAE128E1FB93 -:102950004FC0F396EEE0396230E3F649EB1FA21266 -:1029600052D07F1725DEA3FC6D8E0AF97338B5446B -:102970008C57BD8DE639B66E34330E23BF4D16C26B -:10298000B5CACAE1A5B75BB16D7D0CA1F1BB57CD4E -:102990009E8221B0EEB39B55BA377EE9C530B2476F -:1029A0007DE6E7F6B67B14CF649C5F95EA5887EF27 -:1029B00088B2B7F83B67ECEBA3C9D322BF059D6E85 -:1029C000E3F7EDABAC93BAC5A33C4F4D71BA47707A -:1029D000FAE7EF454ABDA29F85BF4B20DF2FEC49A8 -:1029E000CF1819CEE5603F0B97DB12AFD08EF249BE -:1029F000D0CF489073493F09A7F3C5CEDEEEF9B8B2 -:102A00003E6947E8EC17E147793B363084DEE52A3A -:102A100038A1523CF11111DF75E7905A5B0AE0A929 -:102A200029CD5383ED98FAB58A72E66D58671CDAA2 -:102A30001F4E0CB3D1F9F15B9E43BF3344C88B1CCE -:102A400096A3B9AF26E94EB551FC4EE77BFC3EDEBE -:102A5000D2DFF0B8CDA5BD558AFFD7C7C58D65E9D2 -:102A60003F417BE3845E2697DF11942FF21D204BBC -:102A700082813942F4EC3047387384CC27223356B4 -:102A8000938F74F5D5D48F1E95A2298F710FD6948C -:102A9000C715E469F2BD8B6ED5D4EF337BBC269F9E -:102AA000E8B95B533FA97C9A368F7C0770EF5F3B98 -:102AB00057D36E405D89A69ED357A129673E776B99 -:102AC000663CCA71FE2F75ED524DF9D351053C7E1F -:102AD000DCB680EE29A6357D4FD39FC46F521CC74C -:102AE0002F73F0FDC107FF91DF42E0393F41BB6F1B -:102AF0004CB08F3B66A7546BD748BA411CD4A17F1A -:102B0000960EAA99960E7AF1389EFCDF0C73A01EE1 -:102B1000A3C73FFA2342D789FE8850B8A03F22348A -:102B20008FFE88D0FAE88F082D477F4468F9B013EC -:102B30005AFC8F68D5E2FF960FC6FF433C8D6ED3DB -:102B4000D2831E4FB77DA6A58FB19E7082CB04D0D5 -:102B5000C790DE259E66C37FB4CFB3A268B41BDCEA -:102B6000C1DC742FE07F0B5F9775F8FA92AD1B8183 -:102B7000EF5C5EF17239DED33E7F6580FB0B94BB68 -:102B80002942CEEBED00329ED4379EE3D377328CD0 -:102B9000E4D55786B648DC3FBEA3B6915D3E91753D -:102BA000BC81EFCF0CE9E56159BDF1CA36703F94A5 -:102BB0003FB5E8BE5CDCE7E6FDDA928C7ACDBC017D -:102BC000FC3D4196D546EFB4C8F9CC4BE2F147D66F -:102BD0002C21A75D3C0E29228BDB7F225D768A8328 -:102BE000F6663111E7C992E765231DBE1D96817413 -:102BF000B691DBB9DA4C0E8A6BF1013DA29F12F55A -:102C00006DD487FB0B7DB4E143AB95D31DD3ECEFC3 -:102C100083FC564D1CEE909D764D3EBB3941537F53 -:102C2000E82187A63C3790A9291F76C2A5C98F68DD -:102C30001DA5A97FCB076E4D7E745B81A6FE6D9F9F -:102C40001569F249ACE34984E7F8AC141EDFAF081C -:102C50003B8083E365DE77E2E93E8D3C47C8B86C94 -:102C60008FA063FD796480D94371DE0D89CC45F76F -:102C700041ACE23CC8B4E7148F88AB96FA3CF369E8 -:102C8000E3AA653C75D779469C5FE47922249EDAF5 -:102C90008DF397F1D45D7817EF4BEAE9F35E817716 -:102CA000FD3A0698F9FDAF86EF9AE91E8B9C9F7E50 -:102CB0005E9B443CE0766BF7EF0F3D20E8AC2DA522 -:102CC000686616D47B16B62782E775E3B9DA7C000E -:102CD000DF861F985D2B1D371E6FDE50BE9E627C07 -:102CE00057358BDEE9A47B6B72DC6A31EEF41CA5F0 -:102CF000DBF5CD8BE6F15D2CDA4CF72E7A1E8FC317 -:102D000035C1CC1AE99D24710FE18175CDEB3154A9 -:102D1000B3D8DC64E2EFE3FB4D68272A1C0F7A602E -:102D20002EDA0DDFDF68037DEDD93A23D97D1EDA77 -:102D30003DE63ED020BBEE950C80731AD24921E2CD -:102D40001FFA3D97CDE39D1FCBE2F2215FFDBAEB69 -:102D50003E804523E7F9F9AF1BBA237A94EBF8BF1D -:102D6000BA1F20E9570F2779BE6662FF1A28E625A9 -:102D7000E1D7653F11F093F7331C4B4C455B6D7405 -:102D8000CFA300E3CA24FEBECEE674F96616C737A9 -:102D9000D64379D453BD7C352B1AEDE09DCC116D13 -:102DA000BF813DF8FFE8DE04C1BFA7FB5E3DC989D6 -:102DB000EBE4430FF7BF7AA24FFAF72DEE8185C8F7 -:102DC000091EEF23F0E11F6820BFFA9A482D1FFF6C -:102DD000358BDB5D9E96FB850FCEDD5A39C1D0AEBB -:102DE000DFB04A15726241D7EF48E0F7F9AB4CA467 -:102DF0005F3356F438C6197CB2D14471B163DD8CAF -:102E0000F49892CD8A7F8B82FBE898049CBFD7A769 -:102E1000DD8FEF60AED5E8FF285DABFDBED0C67F8D -:102E20006F62BEFEDD14715E5F7883F3FAD92CE128 -:102E300007723117E95DC2FF5F2EDAE8F5AE4E3F4B -:102E4000F79BE1795BE576278A1B93FBBB03FD3794 -:102E500021EF81003CC333711F6F34761BCFD70540 -:102E6000CF1EE2152EDA44BC828DC76774EE0FE3E5 -:102E7000FE4DE95712F52FFAAE5239D6C7DE2EE5D0 -:102E8000F2B80BE94FD2FBAB3A6D06F2B774EE8F96 -:102E900024FF3CFA71A2810ECE1BF6C58F7206E7A5 -:102EA000E76953357E107DEA59F1129D17CB533DEA -:102EB00031D918876D74595D907FC47684DE8F2A6E -:102EC00014762FFD7CBBCE5D63F8FB2E9D3EAECF0E -:102ED0007616F07738402E32E42319873095C129D1 -:102EE00015526F6034CDE7DBFA73A65FCBE57ECC7D -:102EF0006BB7517BCFDAD1941FD0B87E09DE8399AE -:102F0000D9B0D0842EECB62797E78743D3B6FEFE20 -:102F100095E188B7714AB776F9BC6C85F8A14D1771 -:102F20005F2FD3ADD99C5F7E9D2DE5B888435AA114 -:102F3000101F2C55988C4B22392EF3579B443E9FE3 -:102F4000E797ADE2F936F1BEFE0E6147C175638ABF -:102F5000EBC673FF6E6167C175638AEBC6EF28B776 -:102F6000308F720BF328B7308F720B53945BF8BD20 -:102F7000841525E7AADC0F353194EFAE59D9C4107A -:102F80007E413F54681EFD50A1F5D10F155A8E7E2B -:102F9000A8D072F44385E6D10F155A1FFD50A179D0 -:102FA00036EAAE601EE59C7BAA263F1DF4FC892113 -:102FB000FC8D7EA8D0FED10FA5E9CFB344D3FE7E11 -:102FC00056A7698F7EA8D0FA0FD6291A3FD583E27B -:102FD0009DD3D24D71443FF31D4535D980DFFF8825 -:102FE000F8EF874D2988E79645FC5C16EEE2786E8F -:102FF0002AE07837308EE78E3984E7E5669ECFE7A2 -:10300000F1C97AFA417FCF4413F7F7608AFE1E4C6C -:10301000D1DF8329FA7B26A6717F0FA6E8EFC1EFE7 -:10302000E8EFC114FD3D98A2BF0753F4F7608AFE94 -:103030001E4CD1DF83EDD0DF8329FA7BF03BFA7B96 -:1030400030457F0F7E3F897E2753705EA8C70FD41F -:103050009C1F810E35E747BB268F7A7C687DD4E3C1 -:1030600043CB518F0F2D473D3E348F7A7C687DD402 -:10307000E343F3BFCC72109FA13E1FDA0EF5F9D0E7 -:103080007C7693EF0DB49D4DDE7CF918A66D91CA48 -:10309000B30A888CE6ECF7EE433F5D5B98921C0325 -:1030A00092D3B4E2C3FB2682BEE611F17F39ACC3F2 -:1030B00080F8F688F7D43D0146F196D97F4BA4F20B -:1030C000CB78AF5FC4DB22DE73F733FA5D12E92FF2 -:1030D00096ED5DCCAE622AEB07F3DDD7D38F2FEBF5 -:1030E00091FC0C9907DE00C67895DCE5B63C8CF7C0 -:1030F000DC6150284E62C74A1E27ACA7AB33424F53 -:10310000DA61D87704EF81747815BA0F9C6E642762 -:103110004C7908A7DA3CDC7FDFCE8E11EBAABD1517 -:10312000EF9BC8794BFB26C809BA3F37A6A3754267 -:1031300034F4E3F18DA3DF49293473BD01DBE17978 -:1031400072884F716F0DA1EFF785DCF4F8F8F83F46 -:103150007F6E0A6F17CEDBFDFCB92882E3944685AB -:10316000E2A5C6EC666EBC9FFB1F429E0ED91D50A9 -:10317000713C6F231F4FF6EBDD9C4CF716BDAC6D19 -:103180006202F9481486725BC20DD6770CD707C766 -:103190008613689FBED97B3FB70F8FC9C7383AD611 -:1031A000C2E81DCBC9C3DFD5AC97D03E92FAA57D4E -:1031B0002DC3A7D07BC1537C2B56E2B63ED9B7E4D2 -:1031C0008DDE587F1B73391DB415D1BD58399FC191 -:1031D000EE7D06D81659166B358429886F76342E05 -:1031E000847E80F36720BE735D267ABF77AAD16E96 -:1031F000A2F7237A883FB96A93F1273A7D4117678E -:10320000D2B0FC8364B4272F8D3490FD77E94BFC5A -:10321000F7003C9B14926B520FF28A38B5AB8D6F5E -:10322000F49E8570DF67A2FE64FC4975AA3FD980D1 -:1032300071F57DB7E4C4AAA407C4E6A01EE0FBD5DF -:103240007DA3B0DE2AFE8EE5D5C699D101EA89FBC1 -:103250006BCA04BCCA441C93171FF45683BF8B254A -:10326000EF77B026AEEF497B8EF7B7C38E237EBDD6 -:10327000CF8877A5D77AE95EB63E8E6851A389E2FA -:103280008E16E9F4C24AA11756DE402F1C9CA3D328 -:103290000BE5EFA588364CEDF73EC6EDC97B89C539 -:1032A00026CEFFC5FB18D9618B574C30D03BC82FB9 -:1032B00071BA295EC1F59BE297DD74BF50EA8BEFCE -:1032C000083D66DAB52482FB1F84DE3213E32B014E -:1032D000BE856D61220E2B91D259D778BCE5341B87 -:1032E00097036DAFF177203A7D16AE4F1D63FC1D3D -:1032F000331D5D4E35FA0D78E1CE3506E812F293B6 -:10330000510F82FE66A35E148774EECCA7F8BD024F -:1033100085EEBDE8E9BCD054FB06C687166E672E65 -:103320001F0BA573A05FECCFA7D0FB001E71AE955D -:10333000F4ABA7F77911C21E65E3F6A62EBB04EA2B -:10334000A8F44877CE2CD41BE7A16FAF2F27188C99 -:103350003B8BCCE2E5653939B31AF190D3839D42BA -:10336000FD9E99E0E191EF20F46037407B01CAC9EE -:10337000071ECA359784C8C9E1AEF18D434704F1F1 -:103380005DD275DF2F8BDE055DFA481AFD1E4E4FAC -:10339000FA7029C015F9625E74DBC3F80B6B0D3946 -:1033A000CC3D31017F2750AE8F05308E70AEC837CF -:1033B000EFBDEF4F6B6D0417CAD7E78C998571216C -:1033C000D5D6B649487635599E02BCC718944F45A4 -:1033D000EE2405E5536E00CF849BE4FD649D3DA281 -:1033E0003987D7D7DB254AB3B8DC96BF8B72EA9111 -:1033F000837B71BF92F33FD5C3EF30ECCCE1F2F7A2 -:103400007FEB1E84FEFEC32FFB7A9ECC81753C6E43 -:10341000E0F7F9FBAA4D4CD887C82F2CE50513EF30 -:103420006004F1EEA677741B1E51ECA1F629CF5A69 -:1034300085DFA3EFC18EC3323B9EDC0EEDE6D59B4C -:10344000E9F7F89E4BE7F4F31CD00FFD5E8AB9F55F -:103450000DAB3308C78FEB7E6AA2DFA56181347C98 -:103460007F676E6D980BE5F17057D12F71DE1159A2 -:103470002E92438D18430EF9BB7A15BD88DFABD76A -:103480001D7E16DF13A86971D2EF95780FE5AEC6E1 -:10349000774E86BB3C07B1DC6BB3D37B1A8B1B63C7 -:1034A00068FF9AD747DC0B651DE46793F07F47D828 -:1034B000AFD6BA38FD5E11E70E14905335F5BAB7A2 -:1034C000E3493BA1DECEA07F5FA227FB82B427A009 -:1034D000FDC01C626794F60953E6A939A837149B0E -:1034E000B5F71265CA86F27D5F9E03E777ED5B59FB -:1034F00093FAA07EBC41B1D37B9336C7ACD1902F59 -:103500003B61C2C84E5618EB30E3FB031D805F8C55 -:103510008F2E017E4539532CE2B4CA368D267E2B80 -:10352000F343DACD3B9C32BD7FC3D1FE2F23FD0494 -:10353000DCE4B72CB3BBCDB1217C5FDAA468DE1D1F -:1035400090F98E1C95F311A8E308BF071E729AF13B -:103550006D9F62502330FE8F0D7568FCC7508FE25F -:10356000410A53D871FE0E3CCCDBC9C7CB0BE9BF77 -:10357000A489DF9B9679A84FFACFDF732209AE5E4C -:103580003BACDB89A99DE60970203875AC87FE1C31 -:10359000340EE1A334E037E179BB18E350203FD784 -:1035A000EE37E138258DFC1D13CF3A3E8E676D8CCA -:1035B000391BF523A3DDDC1FE1277E6F15E6477A73 -:1035C0006419C005EF63E17D37DC5BF4F0F18AF943 -:1035D0009635C5D03B0AC1EF1B4C888F393DBC8B5B -:1035E000903594D36D49E338BABF5E6674D33D0716 -:1035F0008F80EF274BC21E45FFC09C8D4F989C903B -:10360000EF3794D36FD6504E5F852981347AAF68F7 -:1036100049980BE739C7DE44EBEB82EF63000F05F7 -:10362000DFB92922F8025DF8306EAF6CA3169FC196 -:10363000F970F8966DF412BF2D307ACCF6D0796C13 -:103640003A9C86F7AAE6007FE3BB12CCEEA1FB9280 -:103650009F3E362B99D609F344B846BA1C93F0FD29 -:1036600021A0137E0F46AC47DEEB96E34D1CCAEF5C -:103670009D4E1CCAE567CF7CE926BDA601F08B767E -:10368000EF9EF8D28C821BC63597F1DF91D0F3A95B -:10369000E44FC997924F25FF3E6B2A0A24284139EF -:1036A00003FB6CED8BDDC0A951CC77AEC02BC0F510 -:1036B00058E83DAF6A81D7E2142DBF637FD8EF1C75 -:1036C000C1EFC5E30369F82E93AC2FC72D8EE5ED4E -:1036D00090EE91DEE688F1B0FE52AAAFBDA752DAB5 -:1036E000252F76AF8A4779B14FE17ED0F547FB7F32 -:1036F00007F5D73D5C7FBD50B57D31EE97CCE84FE7 -:103700000E7DDF7F3EE83928271688FDB92CD0BD15 -:10371000BCB890EEA9181AC2CF653FDB93EEE1F278 -:103720002680F2E6CF7B5EFDE3AD8EE07E2AD753A6 -:10373000B2F65D93D7160A3FBEFE47333BE93E5EC5 -:10374000A9CDECC078E7D2462FC95F96007AA112C6 -:10375000127FA6A30B6FA342F7C84AEB46FAD5FF28 -:1037600045395DBA6E2ABD7B20F126DF6791FBAB40 -:103770009CFF7A31FF2621DFE60AFA9E5B3ECE9C53 -:10378000D88BF46E0CB36473C4F73965DAEF5D78E7 -:10379000EBF25F67AD467EC1FB45743E5967E2F6CA -:1037A000BEDDDCFE7861E9C1DFDD07F5CE3FBE2579 -:1037B00099A95ABCA19EBA40E8AB0B85FDAF1BBCD2 -:1037C0006D19DA3B985FF81CC75BE9DEDFFE05DFA9 -:1037D000132B4E11F26E3D7F07A0A4791FE171CE2D -:1037E000DA0D2627D4DB37D44970EA92FFB5B976D3 -:1037F000B42BCF5DBBC58472629F84838E1F8A45C4 -:103800009CB08433EE4B4A887F43D647F988EFDF7C -:103810003FB4242C0AE379E4381F093A2FAD8D898F -:10382000C5F14A6BBD3FC6F390DC0FF4EB3C1DC6FF -:10383000F9A504FA43BE3D3DCE95BC342BA8CFEA92 -:10384000EBBF2BF0F8B489FF4E4D5244F32E8A6B38 -:10385000A80977A1FC1838B0CD8FE3227DE3BCCD59 -:1038600006FEBB3603ABDA3EC77980AA4D713598A8 -:10387000E2FB58A87AC7437EAB81DFDF4A5179FA71 -:103880009590D7501EC072D6AB8D7E5F23246E56A6 -:1038900043BF66B68D7E3FD1DC8BD1FB66925E6501 -:1038A0003F925E253DF7B4BE2B42AEDC687DA79DFE -:1038B0001C9E66F1BB2937BD3E0BFF1D5DB92E393D -:1038C0003FD0E1DDF4BEC7F7B3C9DE737A852B19AB -:1038D000E3267B5EEFC6FCF86ED6AB5FA7E41B1950 -:1038E0000BDFE5CF6AE27E87D30AEC6FD0EEF4926D -:1038F000308A6F93EBD2DBC3FF1FB640B5F6008072 -:10390000000000001F8B080000000000000BCD56D7 -:103910007D6C5355143FF7BE7EAFDDDEBAB1751B2B -:10392000DBBA8D8F46BAF1CA80F891681D8CF0C75A -:10393000A2DD14DD0C6C25B031C68A9360A8C6B830 -:10394000B2229211E24C3618044C876C7F18205D2D -:10395000208AB19A8689468311E11F1292A60B38FC -:10396000D16856310A44649E73DF2B9D08897FFA23 -:1039700092E6F4DE7B3E7FE7E3DE0F7A658085002A -:10398000C77B1D00468093BD4E41A3BD2EB19FA7AE -:10399000D801E6007E495B930D60AD05DA7C565C8C -:1039A000C6F1970F9008568DF4B3CC7E831DDA9A3A -:1039B0009026E4A4CDEEC67DBBBA7FADC7DC0F393F -:1039C000002D90DCE7588AB2C12A1845538981AB93 -:1039D000368E7C579F463E77466EBB3EB51E88CFDF -:1039E00066708E5600646DFFAEBE10EDB50F567852 -:1039F00018CAAD0BD6268278BE6E57A102B86EB734 -:103A00003A773BE83C54A1F4E13A6BD033358CE78C -:103A1000EDBB1629C4BF9D812F4A7E0F1C002800D4 -:103A2000E8807B9FD7B41C6013FD43BE4D56C32472 -:103A3000ABC1F3E0C43C19E53B14B387A1FD4DC312 -:103A40002C6EC4FD060E7BD81280F2B06F5511DAD1 -:103A50004B1D64CA51923D5CEF4D9A5485339500DD -:103A60005D0B7D35CA325CDC99999941FD8F20460A -:103A700020515C512FC501434C1E05F2DB67207CB1 -:103A80004E2C760A9C13839336A75BC5BB11F106B7 -:103A900047010794DF6652FD2B37A426DF46BF524D -:103AA00036AE1CC575BDE4FED649717E2581D1496F -:103AB000721ABFACF1BFF9A8C98FFAB6D92A0B01A7 -:103AC000E9C66174A216CF9A4D9C70E8D47C6E1F33 -:103AD00079AE00D08F763C77E2F921DA7C0C60F782 -:103AE000E08A8224C9BD5BBF3F540D50A6E1784DEA -:103AF000976CA4FC5C1F29B4EFC4D83606C20B0037 -:103B0000CF378EBC5D46F4FA88B939827C2BE5C686 -:103B100095B9186FC7E15C8F84FECCD0F714E64DE1 -:103B20004121C4A72BB0A21010AFEEBB13EFC955B3 -:103B3000681FB126DC7F8F664542C8D2DD7BA64C6C -:103B4000E2E88AD1DF4C786EE1B1171E433D3FB108 -:103B5000C85891E07716CAD68CDEFBE9542FC28094 -:103B6000F51C78F3B2D0F30B3FFF4C0BCA77074E2E -:103B700065939E2D439796CBB8DF59E5DFA8CC21FE -:103B8000BD2363324204C323353E8CA35D01E1674C -:103B900083DDF7420BE1FE9524707F98BDCE334C58 -:103BA000E07B2FCE488E8170F7C7C1201395C140AE -:103BB000F57D5D8260146943A5DA2FE9FD20E1827D -:103BC0007E5CCF1928A3BAD83C76A0CC89F4479B59 -:103BD000BA5E3BF6E2D7908DFCC78C06CA975F07AA -:103BE0000605E5368498374275D389FD5A94B1DFCE -:103BF000A764097D9B87D1A9BCCC3E4044C4F5A3F2 -:103C00000E56931FE5E194E715A45774F176CAEBBD -:103C1000951EB312AAA03C3905DF95016915ED8701 -:103C2000B091E6335A9FB2CD43FBAD39D043F2B6E3 -:103C3000A5D138C73C074EE72E91D49212F5B55561 -:103C40005617F5927555099E6F1B6732D5E9B68FE9 -:103C5000CFAD02750DC01E8E67D7AD27C039CBEF33 -:103C6000AED3E306EA8FEEE3182FDAEF8E8E7F51A4 -:103C70008C7AB69E595FABDA1D00AAFF80D6CF5B67 -:103C80004FABB8044E4F1A36B8337AD6BBECBB4BA9 -:103C900030B7A34AEB8B43C8BA9EF2F63840EC64C7 -:103CA00063F3CE79486B641137E852653EECC37E0E -:103CB000D74503F5516097A6CF757177A588B731C1 -:103CC0000F66D5C398A217726979C443C8C5039615 -:103CD0003DB01887CD56AB8E683860CD267AB88750 -:103CE000BB7488AB97591409F10E9AB26B684EDE1B -:103CF00034AB346651E90EEE1BEF40176FF20B66E2 -:103D0000C0BADF210D30A24FB97B18220D8BF2FD16 -:103D100031AA5F0744190820E28CFC9EFEF4875A02 -:103D2000B2FF6479F2374097F43BDB9A57627D7CAF -:103D3000AE68F1B993B554E773CEAA73FA881EF64C -:103D4000989750DC3E68AA262DF89FF27E9B476824 -:103D50000EC758FC7DD29F8EF796D6C73EA3750F2F -:103D6000433F1B9CFE6FC88F6799BEDAC32907D2F9 -:103D70007CD23FAD57CF71FE7A4D581775DAF02DD2 -:103D8000E510022C5943B1C34A75CDBC5E08A2FDB3 -:103D90003EF7D90D541F7B532630A2DDB086475D18 -:103DA000CA32C990AFB47835079CC7CC994F770C0D -:103DB0009C75F39011FDDC0BA608F18309E7B12B8C -:103DC000338F0DDCEC15FCB12F6FD37C2F917E9DD2 -:103DD000C841FE921D4C09234FEB8DA923DF225DC4 -:103DE0000B110FE1DA95EF9FA2381237564FFA31D7 -:103DF000BF7BE5A84971ABFA66FB1F7BED76B69DEC -:103E000067FC9A4E4D9DF868295193B877EA629203 -:103E1000B837EEF767DAE1D4911DE48B73E2B7F2BD -:103E20000863C43F7199FCAB3359E35236C9E97F4B -:103E30009E7DAFC085D2DCA945E22A8199129CF60D -:103E400061356F4F6A7D98CE8B85C05F4654CD4FEC -:103E50001A3FE1FCACFBE433EBD83AAA9F74BFBE37 -:103E6000ACEDDFB8559943F3E546AC2A07DC0FEF1C -:103E7000CF4B385FE99D70B8C26BF72CCBDCA76BDA -:103E8000D2B7AB76DF4A9ADE351A4E6BAC5CC5E52D -:103E9000F9FB70D1EA245D0769BFD3794EE70F5E65 -:103EA000BF702EA742E4ADFA1D10F99A4BF613B776 -:103EB000CFBF856D05C59277D25FF17FCC57DCBC53 -:103EC00090DE0D435CBC1B4A09F825827A39C6078F -:103ED0002E10F3A055B228FD0F98077E9A078B6924 -:103EE0001E0C883EBFC953E738A379D023D60E48AD -:103EF000EDD4E13AC19336F23769C6AA47EAF754DE -:103F00008A7BA0843ABA4ACD13F5F591D76C47E97C -:103F1000FD1666DE8326940FEBB57EDF6C8D8CE29A -:103F2000FE748487F4686F303772B003F707D7CC1C -:103F3000554288D334687C9D1631179EE05CAC53A3 -:103F40002D0591A315C48F7D8D710EB63C22EEF127 -:103F50000FEF4AE2BD989A0FEAB907160CD379A37E -:103F60004BE8FB243D67F6D984BEC1466F91459C62 -:103F70001770928FE4F95FA2FC164B2A1F3E0404CF -:103F8000DFA143DE22CAC7A12683E0DBCF7C2DED73 -:103F9000A4A7DAAAD0FB32D9623939A6A623CE96D5 -:103FA000D27B558D375DBFC30B64814B7968F2209E -:103FB000BD434275E0EAA1F72BD5E1E24C7E9817AC -:103FC0007361CFE4295D8F213DE62B5FCD571FFB49 -:103FD00077BEF2B57CB120D66D36E52D2AF0BFC98B -:103FE000D53CEC9020998531495C711891FE91EF98 -:103FF0007F558DF342119DB71A93CB06E85DCCA196 -:1040000033FA803E0C519F8BF739DEA258E76D5A88 -:104010009DB7A5EBF18DFBEA313937772A4BAB47DA -:1040200094FFDEE2EB237BBFB04BCB69F3FC5F5226 -:10403000F383ECECD5E6C89F467FBFE8F36385FFCA -:1040400078679EF7FC504AF70CDC99984BF7CE99AD -:104050003CDF3EE233CF4B19FC8467514A4FF124D9 -:104060005A7E2AA5F74C5BF04BD137FFD5CFB41F52 -:104070007F03DC4DE081B00C000000000000000078 -:1040800000000018000000000000000000000040D8 -:1040900000000000000000000000002800000000F8 -:1040A0000000000000000010000000000000000000 -:1040B00000000020000000000000000000000010D0 -:1040C00000000000000000000000000800000000E8 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E0000000000000000000000033280010000064 -:1041F0000000000800003330001000000000000242 -:1042000000003328001000000000001000003A7881 -:104210000000000000000008800000000000000016 -:10422000000000008000000000000000000000000E -:1042300080000000000000000000000000003120AD -:1042400000000000000000080000336000010004CE -:1042500000000001000033680000000000000002C0 -:1042600000003370000000000000000800003374FC -:10427000000000000000000200003A700000000092 -:104280000000000800003A4000080000000000089C -:1042900000003D88004000000000004000003A504F -:1042A000000800000000000800003A60000800005C -:1042B0000000000800003A8800C8000000000098D4 -:1042C00000003C18009800000000002800003C5846 -:1042D00000980000000000280000337803600030E0 -:1042E0000000036000003EB0000800000000000174 -:1042F00000003EB10008000000000001000020089E -:10430000001000000000001000002000000000006D -:104310000000000880000000000000000000000015 -:10432000800000000000000000000000000000000D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000800000000000000000000000800000005D -:1043600000000000000000008000000000000000CD -:1043700000000000800000000000000000000000BD -:10438000800000000000000000000000800000002D -:10439000000000000000000080000000000000009D -:1043A000000000008000000000000000000000008D -:1043B00080000000000000000000000080000000FD -:1043C000000000000000000080000000000000006D -:1043D000000000008000000000000000000000005D -:1043E000800000000000000000000000000000004D -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000080000000000000000C -:1044300000000000800000000000000000000000FC -:1044400080000000000000000000000000000000EC -:1044500000000000000000008000000000000000DC -:1044600000000000800000000000000000000000CC -:1044700080000000000000000000000000000000BC -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000012C8008000000000008012 -:1044D000000000010000000000000000000040009B -:1044E0000490000000000490000019C800000000C3 -:1044F0000000000800004948000800000000000813 -:1045000000004928000800000000000800004938A9 -:104510000008000000000008000020080010000053 -:104520000000001000002000000000000000000853 -:104530000000401004900040000000400000499836 -:104540000008000000000001000049990008000078 -:1045500000000001800000000000000000000000DA -:10456000800000000000000000000000800000004B -:1045700000000000000000008000000000000000BB -:1045800000000000800000000000000000000000AB -:10459000800000000000000000000000800000001B -:1045A000000000000000000080000000000000008B -:1045B000000000008000000000000000000000007B -:1045C00080000000000000000000000080000000EB -:1045D000000000000000000080000000000000005B -:1045E000000000008000000000000000000000004B -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000800000000A -:1046300000000000000000008000000000000000FA -:10464000000000000000000000000000000000006A -:10465000800000000000000000000000800000005A -:1046600000000000000000008000000000000000CA -:1046700000000000800000000000000000000000BA -:104680000000400000180000000000180000430077 -:104690000040000000000040000043000040000215 -:1046A0000000000100004301004000020000000083 -:1046B00000003000004000000000004080000000CA -:1046C0000000000000000000000030000008004072 -:1046D0000000000400003004000800400000000456 -:1046E00000004B00002800000000002800004B5094 -:1046F00000100000000000100000380000800000E2 -:104700000000008000003800000800800000000267 -:1047100000003900002000000000002000002008F8 -:104720000010000000000010000020000000000049 -:104730000000000800005108000800000000000808 -:104740000000512000080000000000080000513067 -:104750000008000000000008000051C00008000030 -:1047600000000001000051C100080000000000012D -:10477000000039400010000400000004000051D087 -:104780000030001800000010000051D80030001860 -:104790000000000280000000000000000000000097 -:1047A0008000000000000000000000008000000009 -:1047B0000000000000000000800000000000000079 -:1047C0000000000080000000000000000000000069 -:1047D00080000000000000000000000080000000D9 -:1047E0000000000000000000800000000000000049 -:1047F0000000000080000000000000000000000039 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830008000000000000000000000008000000078 -:104840000000000000000000000000000000000068 -:1048500000000000000023E800800000000000804D -:10486000000000010000000000000000000020081F -:1048700000100000000000100000200000000000F8 -:104880000000000800002DA0000800000000000843 -:1048900000002DB80008000000000008000024E817 -:1048A00002D00028000002D000002E5800080000AE -:1048B0000000000100002E59000800000000000167 -:1048C00000002D900008000000000008800000009B -:1048D0000000000000000000800000000000000058 -:1048E0000000000080000000000000000000000048 -:1048F00080000000000000000000000080000000B8 -:104900000000000000000000800000000000000027 -:104910000000000080000000000000000000000017 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950008000000000000000000000008000000057 -:104960000000000000000000000000000000000047 -:1049700000000000800000000000000000000000B7 -:104980008000000000000000000000008000000027 -:104990000000000000000000800000000000000097 -:1049A000000000000000250000400000000000089A -:1049B000000025080040000000000028000009C099 -:1049C000012000100000000880000000000000002E -:1049D0000000000080000000000000000000000057 -:1049E0000000402002D00028000000080000300035 -:1049F00000000000000010000000509900000000BE -:104A000000000001000050B00000000000000002A3 -:104A1000000045A000900008000000088000000091 -:104A200000000000000000000000296000080000F5 -:104A300000000001000029610008000000000001E2 -:104A4000000029700008000400000002000029781E -:104A5000000800040000000400002FB0000800005F -:104A60000000000400002FB4000800000000000453 -:104A700000002FC0000000000000000800002FC848 -:104A800000000000000000080000300000000000EE -:104A90000000001000005040000100010000000173 -:104AA0000000500000000000000000200000080886 -:104AB00000100000000000040000080C00100000BE -:104AC00000000001000008B7000000000000000125 -:104AD000000008B600000000000000010000100007 -:104AE000003000180000000400001004003000181E -:104AF0000000000400001008003000180000000250 -:104B00000000100A00300018000000020000100C25 -:104B100000300018000000010000100D00300018E7 -:104B2000000000010000100E00300018000000011D -:104B300000001010003000180000000400001014E5 -:104B40000030001800000004000030000100008068 -:104B50000008000400003004010000800008000488 -:104B60000000000A000000000000000000003068A3 -:104B70000100008000000001000030690100008099 -:104B8000000000010000306C010000800000000205 -:104B90000000306E01000080000000020000307054 -:104BA000010000800000000400003074010000805B -:104BB00000000004000030660100008000000002D8 -:104BC000000030640100008000000001000030603F -:104BD000010000800000000200003062010000803F -:104BE00000000002000030500100008000000004BE -:104BF0000000305401000080000000040000305824 -:104C000001000080000000040000305C0100008012 -:104C1000000000040000307C010000800000000162 -:104C20000000307D010000800000000100001C1821 -:104C3000001000000000000400001C300010000004 -:104C40000000000400001C380010000000000004F8 -:104C50008000000000000000000000008000000054 -:104C600000000000000000008000000000000000C4 -:104C700000000000800000000000000000000000B4 -:104C800000004C10000800000000000200004C1260 -:104C9000000800000000000200004C1400080000A2 -:104CA0000000000400004C20000800000000000884 -:104CB00000004C30004000080000000800004C00DC -:104CC000000800000000000200004C020008000084 -:104CD0000000000100004C04000800000000000279 -:104CE00000004CD0000800000000000800004CE06C -:104CF000000800000000000400004CE40008000070 -:104D00000000000100004CF000080000000000025C -:104D100000004CF4000800000000000200004D00FC -:104D20000008000000000004000050000010000017 -:104D30000000000400005004001000000000000407 -:104D400000005008001000000000000400001400E3 -:104D5000000800000000000200001402000800002B -:104D60000000000100001404000800000000000220 -:104D700000001410000800000000000200001414DD -:104D800000080000000000020000141600080000E7 -:104D900000000002000019B8000800000000000830 -:104DA000000014200008000000000002000014248D -:104DB0000008000000000002000019C80008000000 -:104DC0000000000800002C10000800000000000196 -:104DD00000002C11000800000000000100002C124F -:104DE000000800000000000100002C130008000073 -:104DF0000000000100002C0000080000000000027C -:104E000000002C02000800000000000100002C043B -:104E1000000800000000000200002C300008000024 -:104E20000000000200002C32000800000000000218 -:104E300000002C34000800000000000200002C20BC -:104E4000000800000000000100002C210008000004 -:104E50000000000100002C220008000000000001FA -:104E600000002C23000800000000000100002C249A -:104E7000000800000000000100002C2500080000D0 -:104E80000000000100002C260008000000000001C6 -:104E900000001400000800000000000200001402DE -:104EA00000080000000000010000140400080000D9 -:104EB000000000020000141200C0001800000002F0 -:104EC0000000141000C00018000000020000141CB4 -:104ED00000C00018000000080000141400C00018F2 -:104EE000000000080000142700C0001800000001A6 -:104EF0000000142400C00018000000020000142666 -:104F000000C000180000000100001590000800001B -:104F100000000008000015A00008000000000008C4 -:104F2000000015B00008000000000008800000002C -:104F300000000000000000008000000000000000F1 -:104F400000000000800000000000000000000000E1 -:104F50008000000000000000000000008000000051 -:104F600000000000000000008000000000000000C1 -:104F700000000000800000000000000000000000B1 -:104F80008000000000000000000000008000000021 -:104F90000000000000000000800000000000000091 -:104FA0000000000080000000000000000000000081 -:104FB00080000000000000000000000080000000F1 -:104FC0000000000000000000800000000000000061 -:104FD0000000000080000000000000000000000051 -:104FE00080000000000000000000000080000000C1 -:104FF0000000000000000000800000000000000031 -:105000000000000080000000000000000000000020 -:105010008000000000000000000000008000000090 -:105020000000000000000000800000000000000000 -:1050300000000000800000000000000000000000F0 -:105040008000000000000000000000008000000060 -:1050500000000000000000008000000000000000D0 -:105060000000000000000000000000000000000040 -:1050700080000000000000000000000000000000B0 -:08508000060209000000000017 -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex deleted file mode 100644 index ba1ce53df1d87493599873c05571869b39b6645b..0000000000000000000000000000000000000000 --- a/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex +++ /dev/null @@ -1,13192 +0,0 @@ -:1000000000004F48000000680000070C00004FB8D7 -:1000100000001ED4000056C800000094000075A027 -:1000200000009F4C00007638000000CC00011588CD -:100030000000DC5800011658000000940001F2B8DE -:100040000000400C0001F350000000A400023360E7 -:100050000000F4240002340800000FFC00032830E4 -:100060000000000400033830020400480000000FC4 -:1000700002040054000000450204005C0000000679 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040004000000FF02040008000000FF79 -:100170000204000C000000FF02040010000000FF59 -:10018000020400140000007F02040018000000FFB9 -:100190000204001C000000FF02040020000000FF19 -:1001A000020400240000003E0204002800000000B9 -:1001B0000204002C0000003F020400300000003F59 -:1001C000020400340000003F020400380000003F39 -:1001D0000204003C0000003F020400400000003F19 -:1001E000020400440000003F020404CC00000001AF -:1001F00002042008000002110204200C000002008A -:10020000020420100000020402042014000002195D -:100210000204201C0000FFFF020420200000FFFF5A -:10022000020420240000FFFF020420280000FFFF3A -:1002300002042038000000200604203C0000001FBB -:10024000020420B800000001060420BC0000005F8A -:100250000204223807FFFFFF0204223C0000003F97 -:100260000204224007FFFFFF020422440000000FA7 -:1002700001042248000000000104224C000000009C -:10028000010422500000000001042254000000007C -:1002900001042258000000000104225C000000005C -:1002A000010422600000000001042264000000003C -:1002B00001042268000000000104226C000000001C -:1002C00001042270000000000104227400000000FC -:1002D00001042278000000000104227C00000000DC -:1002E0000C042000000003E80A04200000000001C4 -:1002F0000B0420000000000A0605400000000D006D -:100300000205004400000020020500480000003201 -:10031000020500900215002002050094021500203D -:1003200002050098000000300205009C0810000043 -:10033000020500A000000033020500A40000003008 -:10034000020500A800000031020500AC0000000218 -:10035000020500B000000005020500B40000000620 -:10036000020500B800000002020500BC0000000207 -:10037000020500C000000000020500C400000005E6 -:10038000020500C800000002020500CC00000002C7 -:10039000020500D000000002020500D400000001A8 -:1003A00002050114000000010205011C000000010B -:1003B0000205012000000002020502040000000105 -:1003C0000205020C0000004002050210000000407F -:1003D0000205021C0000002002050220000000139C -:1003E0000205022400000020060502400000000A69 -:1003F00004050280002000000205005000000007F4 -:10040000020500540000000702050058000000002B -:100410000205005C00000008020500600000000109 -:100420000605006400000003020500D80000000675 -:1004300002050004000000010205000800000001A0 -:100440000205000C00000001020500100000000180 -:100450000205001400000001020500180000000160 -:100460000205001C00000001020500200000000140 -:100470000205002400000001020500280000000120 -:100480000205002C00000001020500300000000100 -:1004900002050034000000010205003800000001E0 -:1004A0000205003C000000010205004000000001C0 -:1004B000020500E00000000D020500E80000000059 -:1004C000020500F000000000020500F80000000036 -:1004D000020500E40000002D020500EC00000020F1 -:1004E000020500F400000020020500FC00000020CE -:1004F000020500E00000001D020500E800000010F9 -:10050000020500F000000010020500F800000010D5 -:10051000020500E40000003D020500EC0000003090 -:10052000020500F400000030020500FC000000306D -:10053000020500E00000004D020500E80000004058 -:10054000020500F000000040020500F80000004035 -:10055000020500E40000006D020500EC00000060F0 -:10056000020500F400000060020500FC00000060CD -:10057000020500E00000005D020500E800000050F8 -:10058000020500F000000050020500F800000050D5 -:10059000020500E40000007D020500EC0000007090 -:1005A000020500F400000070020500FC000000706D -:1005B0000406100002000020020600DC000000011A -:1005C000010600D80000000004060200000302201B -:1005D000020600DC00000000010600B80000000078 -:1005E000010600C8000000000206016C00000000C7 -:1005F000010600BC00000000010600CC0000000065 -:1006000002060170000000000718040000910000BD -:10061000081807D800050223071C00002BF700006C -:10062000071C80002DD10AFE071D00002F461673FF -:10063000071D800016342245081DB13049DA022515 -:100640000118000000000000011800040000000074 -:1006500001180008000000000118000C0000000054 -:100660000118001000000000011800140000000034 -:1006700002180020000000010218002400000002FF -:1006800002180028000000030218002C00000000DF -:1006900002180030000000040218003400000001BD -:1006A00002180038000000000218003C00000001A1 -:1006B000021800400000000402180044000000007E -:1006C00002180048000000010218004C000000035E -:1006D0000218005000000000021800540000000141 -:1006E00002180058000000040218005C000000001E -:1006F00002180060000000010218006400000003FE -:1007000002180068000000000218006C00000001E0 -:1007100002180070000000040218007400000000BD -:1007200002180078000000040218007C000000039A -:100730000618008000000002021800A400003FFF1D -:10074000021800A8000003FF0218022400000000A5 -:1007500002180234000000000218024C00000000E1 -:10076000021802E4000000FF061810000000040058 -:10077000021B8BC000000001021B8000000000343F -:10078000021B804000000018021B80800000000C4B -:10079000021B80C0000000200C1B83000007A1206A -:1007A0000A1B8300000001380B1B83000000138824 -:1007B0000A1B8340000000000C1B8340000001F472 -:1007C0000B1B834000000005021B83800007A12053 -:1007D000021B83C0000001F4021B14800000000112 -:1007E0000A1B148000000000061A1000000003B36A -:1007F000041A1ECC00010227061A1ED000000008B1 -:10080000061A2008000000C8061A20000000000296 -:10081000041AAF4000100228061A3718000000041E -:10082000061A371000000002061A500000000002ED -:10083000061A500800000004061A501800000004B0 -:10084000061A502800000004061A50380000000460 -:10085000061A504800000004061A50580000000410 -:10086000061A506800000004061A507800000002C2 -:10087000041A52C000020238061A40500000000656 -:10088000041A40680002023A041A40400004023C84 -:10089000041A800000010240061A800400000003D0 -:1008A000041A801000010241061A8014000000039F -:1008B000041A802000010242061A8024000000036E -:1008C000041A803000010243061A8034000000033D -:1008D000041A804000010244061A8044000000030C -:1008E000041A805000010245061A805400000003DB -:1008F000041A806000010246061A806400000003AA -:10090000041A807000010247061A80740000000378 -:10091000041A808000010248061A80840000000347 -:10092000041A809000010249061A80940000000316 -:10093000041A80A00001024A061A80A400000003E5 -:10094000041A80B00001024B061A80B400000003B4 -:10095000041A80C00001024C061A80C40000000383 -:10096000041A80D00001024D061A80D40000000352 -:10097000041A80E00001024E061A80E40000000321 -:10098000041A80F00001024F061A80F400000003F0 -:10099000041A810000010250061A810400000003BD -:1009A000041A811000010251061A8114000000038C -:1009B000041A812000010252061A8124000000035B -:1009C000041A813000010253061A8134000000032A -:1009D000041A814000010254061A814400000003F9 -:1009E000041A815000010255061A815400000003C8 -:1009F000041A816000010256061A81640000000397 -:100A0000041A817000010257061A81740000000365 -:100A1000041A818000010258061A81840000000334 -:100A2000041A819000010259061A81940000000303 -:100A3000041A81A00001025A061A81A400000003D2 -:100A4000041A81B00001025B061A81B400000003A1 -:100A5000041A81C00001025C061A81C40000000370 -:100A6000041A81D00001025D061A81D4000000033F -:100A7000041A81E00001025E061A81E4000000030E -:100A8000041A81F00001025F061A81F400000003DD -:100A9000041A820000010260061A820400000003AA -:100AA000041A821000010261061A82140000000379 -:100AB000041A822000010262061A82240000000348 -:100AC000041A823000010263061A82340000000317 -:100AD000041A824000010264061A824400000003E6 -:100AE000041A825000010265061A825400000003B5 -:100AF000041A826000010266061A82640000000384 -:100B0000041A827000010267061A82740000000352 -:100B1000041A828000010268061A82840000000321 -:100B2000041A829000010269061A829400000003F0 -:100B3000041A82A00001026A061A82A400000003BF -:100B4000041A82B00001026B061A82B4000000038E -:100B5000041A82C00001026C061A82C4000000035D -:100B6000041A82D00001026D061A82D4000000032C -:100B7000041A82E00001026E061A82E400000003FB -:100B8000041A82F00001026F061A82F400000003CA -:100B9000041A830000010270061A83040000000397 -:100BA000041A831000010271061A83140000000366 -:100BB000041A832000010272061A83240000000335 -:100BC000041A833000010273061A83340000000304 -:100BD000041A834000010274061A834400000003D3 -:100BE000041A835000010275061A835400000003A2 -:100BF000041A836000010276061A83640000000371 -:100C0000041A837000010277061A8374000000033F -:100C1000041A838000010278061A8384000000030E -:100C2000041A839000010279061A839400000003DD -:100C3000041A83A00001027A061A83A400000003AC -:100C4000041A83B00001027B061A83B4000000037B -:100C5000041A83C00001027C061A83C4000000034A -:100C6000041A83D00001027D061A83D40000000319 -:100C7000041A83E00001027E061A83E400000003E8 -:100C8000041A83F00001027F061A83F400000003B7 -:100C9000041A840000010280061A84040000000384 -:100CA000041A841000010281061A84140000000353 -:100CB000041A842000010282061A84240000000322 -:100CC000041A843000010283061A843400000003F1 -:100CD000041A844000010284061A844400000003C0 -:100CE000041A845000010285061A8454000000038F -:100CF000041A846000010286061A8464000000035E -:100D0000041A847000010287061A8474000000032C -:100D1000041A848000010288061A848400000003FB -:100D2000041A849000010289061A849400000003CA -:100D3000041A84A00001028A061A84A40000000399 -:100D4000041A84B00001028B061A84B40000000368 -:100D5000041A84C00001028C061A84C40000000337 -:100D6000041A84D00001028D061A84D40000000306 -:100D7000041A84E00001028E061A84E400000003D5 -:100D8000041A84F00001028F061A84F400000003A4 -:100D9000041A850000010290061A85040000000371 -:100DA000041A851000010291061A85140000000340 -:100DB000041A852000010292061A8524000000030F -:100DC000041A853000010293061A853400000003DE -:100DD000041A854000010294061A854400000003AD -:100DE000041A855000010295061A8554000000037C -:100DF000041A856000010296061A8564000000034B -:100E0000041A857000010297061A85740000000319 -:100E1000041A858000010298061A858400000003E8 -:100E2000041A859000010299061A859400000003B7 -:100E3000041A85A00001029A061A85A40000000386 -:100E4000041A85B00001029B061A85B40000000355 -:100E5000041A85C00001029C061A85C40000000324 -:100E6000041A85D00001029D061A85D400000003F3 -:100E7000041A85E00001029E061A85E400000003C2 -:100E8000041A85F00001029F061A85F40000000391 -:100E9000041A8600000102A0061A8604000000035E -:100EA000041A8610000102A1061A8614000000032D -:100EB000041A8620000102A2061A862400000003FC -:100EC000041A8630000102A3061A863400000003CB -:100ED000041A8640000102A4061A8644000000039A -:100EE000041A8650000102A5061A86540000000369 -:100EF000041A8660000102A6061A86640000000338 -:100F0000041A8670000102A7061A86740000000306 -:100F1000041A8680000102A8061A868400000003D5 -:100F2000041A8690000102A9061A869400000003A4 -:100F3000041A86A0000102AA061A86A40000000373 -:100F4000041A86B0000102AB061A86B40000000342 -:100F5000041A86C0000102AC061A86C40000000311 -:100F6000041A86D0000102AD061A86D400000003E0 -:100F7000041A86E0000102AE061A86E400000003AF -:100F8000041A86F0000102AF061A86F4000000037E -:100F9000041A8700000102B0061A8704000000034B -:100FA000041A8710000102B1061A8714000000031A -:100FB000041A8720000102B2061A872400000003E9 -:100FC000041A8730000102B3061A873400000003B8 -:100FD000041A8740000102B4061A87440000000387 -:100FE000041A8750000102B5061A87540000000356 -:100FF000041A8760000102B6061A87640000000325 -:10100000041A8770000102B7061A877400000003F3 -:10101000041A8780000102B8061A878400000003C2 -:10102000041A8790000102B9061A87940000000391 -:10103000041A87A0000102BA061A87A40000000360 -:10104000041A87B0000102BB061A87B4000000032F -:10105000041A87C0000102BC061A87C400000003FE -:10106000041A87D0000102BD061A87D400000003CD -:10107000041A87E0000102BE061A87E4000000039C -:10108000041A87F0000102BF061A87F4000000036B -:10109000041A8800000102C0061A88040000000338 -:1010A000041A8810000102C1061A88140000000307 -:1010B000041A8820000102C2061A882400000003D6 -:1010C000041A8830000102C3061A883400000003A5 -:1010D000041A8840000102C4061A88440000000374 -:1010E000041A8850000102C5061A88540000000343 -:1010F000041A8860000102C6061A88640000000312 -:10110000041A8870000102C7061A887400000003E0 -:10111000041A8880000102C8061A888400000003AF -:10112000041A8890000102C9061A8894000000037E -:10113000041A88A0000102CA061A88A4000000034D -:10114000041A88B0000102CB061A88B4000000031C -:10115000041A88C0000102CC061A88C400000003EB -:10116000041A88D0000102CD061A88D400000003BA -:10117000041A88E0000102CE061A88E40000000389 -:10118000041A88F0000102CF061A88F40000000358 -:10119000041A8900000102D0061A89040000000325 -:1011A000041A8910000102D1061A891400000003F4 -:1011B000041A8920000102D2061A892400000003C3 -:1011C000041A8930000102D3061A89340000000392 -:1011D000041A8940000102D4061A89440000000361 -:1011E000041A8950000102D5061A89540000000330 -:1011F000041A8960000102D6061A896400000003FF -:10120000041A8970000102D7061A897400000003CD -:10121000041A8980000102D8061A8984000000039C -:10122000041A8990000102D9061A8994000000036B -:10123000041A89A0000102DA061A89A4000000033A -:10124000041A89B0000102DB061A89B40000000309 -:10125000041A89C0000102DC061A89C400000003D8 -:10126000041A89D0000102DD061A89D400000003A7 -:10127000041A89E0000102DE061A89E40000000376 -:10128000041A89F0000102DF061A89F40000000345 -:10129000041A8A00000102E0061A8A040000000312 -:1012A000041A8A10000102E1061A8A1400000003E1 -:1012B000041A8A20000102E2061A8A2400000003B0 -:1012C000041A8A30000102E3061A8A34000000037F -:1012D000041A8A40000102E4061A8A44000000034E -:1012E000041A8A50000102E5061A8A54000000031D -:1012F000041A8A60000102E6061A8A6400000003EC -:10130000041A8A70000102E7061A8A7400000003BA -:10131000041A8A80000102E8061A8A840000000389 -:10132000041A8A90000102E9061A8A940000000358 -:10133000041A8AA0000102EA061A8AA40000000327 -:10134000041A8AB0000102EB061A8AB400000003F6 -:10135000041A8AC0000102EC061A8AC400000003C5 -:10136000041A8AD0000102ED061A8AD40000000394 -:10137000041A8AE0000102EE061A8AE40000000363 -:10138000041A8AF0000102EF061A8AF40000000332 -:10139000041A8B00000102F0061A8B0400000003FF -:1013A000041A8B10000102F1061A8B1400000003CE -:1013B000041A8B20000102F2061A8B24000000039D -:1013C000041A8B30000102F3061A8B34000000036C -:1013D000041A8B40000102F4061A8B44000000033B -:1013E000041A8B50000102F5061A8B54000000030A -:1013F000041A8B60000102F6061A8B6400000003D9 -:10140000041A8B70000102F7061A8B7400000003A7 -:10141000041A8B80000102F8061A8B840000000376 -:10142000041A8B90000102F9061A8B940000000345 -:10143000041A8BA0000102FA061A8BA40000000314 -:10144000041A8BB0000102FB061A8BB400000003E3 -:10145000041A8BC0000102FC061A8BC400000003B2 -:10146000041A8BD0000102FD061A8BD40000000381 -:10147000041A8BE0000102FE061A8BE40000000350 -:10148000041A8BF0000102FF061A8BF4000000031F -:10149000041A8C0000010300061A8C0400000003EB -:1014A000041A8C1000010301061A8C1400000003BA -:1014B000041A8C2000010302061A8C240000000389 -:1014C000041A8C3000010303061A8C340000000358 -:1014D000041A8C4000010304061A8C440000000327 -:1014E000041A8C5000010305061A8C5400000003F6 -:1014F000041A8C6000010306061A8C6400000003C5 -:10150000041A8C7000010307061A8C740000000393 -:10151000041A8C8000010308061A8C840000000362 -:10152000041A8C9000010309061A8C940000000331 -:10153000041A8CA00001030A061A8CA40000000300 -:10154000041A8CB00001030B061A8CB400000003CF -:10155000041A8CC00001030C061A8CC4000000039E -:10156000041A8CD00001030D061A8CD4000000036D -:10157000041A8CE00001030E061A8CE4000000033C -:10158000041A8CF00001030F061A8CF4000000030B -:10159000041A8D0000010310061A8D0400000003D8 -:1015A000041A8D1000010311061A8D1400000003A7 -:1015B000041A8D2000010312061A8D240000000376 -:1015C000041A8D3000010313061A8D340000000345 -:1015D000041A8D4000010314061A8D440000000314 -:1015E000041A8D5000010315061A8D5400000003E3 -:1015F000041A8D6000010316061A8D6400000003B2 -:10160000041A8D7000010317061A8D740000000380 -:10161000041A8D8000010318061A8D84000000034F -:10162000041A8D9000010319061A8D94000000031E -:10163000041A8DA00001031A061A8DA400000003ED -:10164000041A8DB00001031B061A8DB400000003BC -:10165000041A8DC00001031C061A8DC4000000038B -:10166000041A8DD00001031D061A8DD4000000035A -:10167000041A8DE00001031E061A8DE40000000329 -:10168000041A8DF00001031F061A8DF400000003F8 -:10169000041A8E0000010320061A8E0400000003C5 -:1016A000041A8E1000010321061A8E140000000394 -:1016B000041A8E2000010322061A8E240000000363 -:1016C000041A8E3000010323061A8E340000000332 -:1016D000041A8E4000010324061A8E440000000301 -:1016E000041A8E5000010325061A8E5400000003D0 -:1016F000041A8E6000010326061A8E64000000039F -:10170000041A8E7000010327061A8E74000000036D -:10171000041A8E8000010328061A8E84000000033C -:10172000041A8E9000010329061A8E94000000030B -:10173000041A8EA00001032A061A8EA400000003DA -:10174000041A8EB00001032B061A8EB400000003A9 -:10175000041A8EC00001032C061A8EC40000000378 -:10176000041A8ED00001032D061A8ED40000000347 -:10177000041A8EE00001032E061A8EE40000000316 -:10178000041A8EF00001032F061A8EF400000003E5 -:10179000041A8F0000010330061A8F0400000003B2 -:1017A000041A8F1000010331061A8F140000000381 -:1017B000041A8F2000010332061A8F240000000350 -:1017C000041A8F3000010333061A8F34000000031F -:1017D000041A8F4000010334061A8F4400000003EE -:1017E000041A8F5000010335061A8F5400000003BD -:1017F000041A8F6000010336061A8F64000000038C -:10180000041A8F7000010337061A8F74000000035A -:10181000041A8F8000010338061A8F840000000329 -:10182000041A8F9000010339061A8F9400000003F8 -:10183000041A8FA00001033A061A8FA400000003C7 -:10184000041A8FB00001033B061A8FB40000000396 -:10185000041A8FC00001033C061A8FC40000000365 -:10186000041A8FD00001033D061A8FD40000000334 -:10187000041A8FE00001033E061A8FE400000007FF -:10188000041A62C00020033F061AD0000000007254 -:10189000061AD24800000010061AD6B00000002038 -:1018A000061AD47000000090061AD46800000002E6 -:1018B000061AA000000001C4061A30000000001043 -:1018C000061A308000000010061A310000000010D7 -:1018D000061A318000000010061A330000000012C2 -:1018E000061A339000000070061AD4580000000257 -:1018F000061AD34800000002061AD3580000002040 -:10190000061AA710000001C4061A3040000000109B -:10191000061A30C000000010061A31400000001006 -:10192000061A31C000000010061A334800000012E9 -:10193000061A355000000070061AD460000000023C -:10194000061AD35000000002061AD3D80000002067 -:10195000021AAE2000000000061A5000000000022B -:10196000061A508000000012041A40000002035FB3 -:10197000041A63C000020361061A7000000000042C -:10198000061A320000000008021AAE24000000000F -:10199000061A501000000002061A50C8000000127B -:1019A000041A400800020363041A63C800020365B6 -:1019B000061A701000000004061A32200000000809 -:1019C000021AAE2800000000061A50200000000293 -:1019D000061A511000000012041A4010000203679A -:1019E000041A63D000020369061A70200000000484 -:1019F000061A324000000008021AAE2C0000000057 -:101A0000061A503000000002061A51580000001259 -:101A1000041A40180002036B041A63D80002036D15 -:101A2000061A703000000004061A32600000000838 -:101A3000021AAE3000000000061A504000000002FA -:101A4000061A51A000000012041A40200002036F81 -:101A5000041A63E000020371061A704000000004DB -:101A6000061A328000000008021AAE34000000009E -:101A7000061A505000000002061A51E80000001239 -:101A8000041A402800020373041A63E80002037575 -:101A9000061A705000000004061A32A00000000868 -:101AA000021AAE3800000000061A50600000000262 -:101AB000061A523000000012041A40300002037768 -:101AC000041A63F000020379061A70600000000433 -:101AD000061A32C000000008021AAE3C00000000E6 -:101AE000061A507000000002061A52780000001218 -:101AF000041A40380002037B041A63F80002037DD5 -:101B0000061A707000000004061A32E00000000897 -:101B10000200A468000B01C80200A294071D29114D -:101B20000200A298000000000200A29C009C042475 -:101B30000200A2A0000000000200A2A4000002090E -:101B40000200A270000000000200A2740000000069 -:101B50000200A270000000000200A2740000000059 -:101B60000200A270000000000200A2740000000049 -:101B70000200A270000000000200A2740000000039 -:101B8000020160A000000001020160A400000262E6 -:101B9000020160A800000002020160AC0000001811 -:101BA0000201620400000001020100B40000000113 -:101BB000020100B800000001020100DC0000000189 -:101BC0000201010000000001020101040000000107 -:101BD0000201007C003000000201008400000028A7 -:101BE0000201008C0000000002010130000000042E -:101BF0000201025C00000001020103280000000055 -:101C0000020160580000FFFF020160700000000741 -:101C10000201608000000001020105540000003054 -:101C2000020100C400000001020100CC000000011C -:101C3000020100F800000001020100F000000001B4 -:101C4000020100800030000002010088000000282E -:101C500002010090000000000201013400000004B5 -:101C6000020102DC000000010201032C0000000060 -:101C70000201605C0000FFFF0201607400000007C9 -:101C800002016084000000010201056400000030D0 -:101C9000020100C800000001020100D000000001A4 -:101CA000020100FC00000001020100F4000000013C -:101CB000020C100000000028020C20080000021195 -:101CC000020C200C00000200020C20100000020494 -:101CD000020C201C0000FFFF020C20200000FFFF70 -:101CE000020C20240000FFFF020C20280000FFFF50 -:101CF000020C203800000020020C203C00000021D3 -:101D0000020C204000000022020C204400000023AE -:101D1000020C204800000024020C204C000000258A -:101D2000020C205000000026020C20540000002766 -:101D3000020C205800000028020C205C0000002942 -:101D4000020C20600000002A020C20640000002B1E -:101D5000020C20680000002C020C206C0000002DFA -:101D6000020C20700000002E020C20740000002FD6 -:101D7000020C207800000010060C207C00000007F8 -:101D8000020C209800000011020C209C00000012A0 -:101D9000020C20A000000013060C20A40000001D6F -:101DA000020C211800000001020C211C000000019F -:101DB000020C212000000001060C21240000001D5F -:101DC000020C219800000001060C219C0000000775 -:101DD000020C21B800000001020C21BC000000012F -:101DE000020C21C000000001020C21C4000000010F -:101DF000020C21C800000001020C21CC00000001EF -:101E0000020C21D000000001020C21D400000001CE -:101E1000020C21D800000001020C21DC00000001AE -:101E2000020C21E000000001020C21E4000000018E -:101E3000020C21E800000001020C21EC000000016E -:101E4000020C21F000000001020C21F4000000014E -:101E5000020C21F800000001060C21FC0000000724 -:101E6000020C221800000001060C221C00000007D2 -:101E7000020C223807FFFFFF020C223C0000003F4B -:101E8000020C224007FFFFFF020C22440000000F5B -:101E9000010C224800000000010C224C0000000050 -:101EA000010C225000000000010C22540000000030 -:101EB000010C225800000000010C225C0000000010 -:101EC000010C226000000000010C226400000000F0 -:101ED000010C226800000000010C226C00000000D0 -:101EE000010C227000000000010C227400000000B0 -:101EF000010C227800000000010C227C0000000090 -:101F00000C0C2000000003E80A0C20000000000177 -:101F10000B0C20000000000A020C40080000101109 -:101F2000020C400C00001000020C401000001004D5 -:101F3000020C401400001021020C401C0000FFFFA6 -:101F4000020C40200000FFFF020C40240000FFFFB5 -:101F5000020C40280000FFFF020C40380000004641 -:101F6000020C403C00000010060C40400000000243 -:101F7000020C404800000018020C404C000000F029 -:101F8000060C40500000001F020C40CC0000000175 -:101F9000060C40D00000003A020C41B800000001DD -:101FA000060C41BC00000003020C41C80000000107 -:101FB000020C41CC00000001060C41D00000001AC8 -:101FC000020C423807FFFFFF020C423C0000003FBA -:101FD000020C424007FFFFFF020C42440000000FCA -:101FE000010C424800000000010C424C00000000BF -:101FF000010C425000000000010C4254000000009F -:10200000010C425800000000010C425C000000007E -:10201000010C426000000000010C4264000000005E -:10202000010C426800000000010C426C000000003E -:10203000010C427000000000010C4274000000001E -:10204000010C427800000000010C427C00000000FE -:10205000010C4280000000000C0C4000000003E86E -:102060000A0C4000000000010B0C40000000000AB8 -:10207000060D400000000A00020D0044000000327E -:10208000020D008C02150020020D009002150020A8 -:10209000020D009408100000020D009800000033AB -:1020A000020D009C00000002020D00A000000000D4 -:1020B000020D00A400000005020D00A800000005AC -:1020C000060D00AC00000002020D00B4000000028A -:1020D000020D00B800000003020D00BC0000000269 -:1020E000020D00C000000001020D00C80000000247 -:1020F000020D00CC00000002020D015C0000000196 -:10210000020D016400000001020D016800000002E0 -:10211000020D020400000001020D020C000000206C -:10212000020D021000000040020D021400000040E9 -:10213000020D022000000003020D0224000000181E -:10214000060D028000000012040D03000018037F3A -:10215000060D03600000000C020D004C00000001A1 -:10216000020D005000000002020D005400000000AB -:10217000020D005800000008060D005C000000047D -:10218000020D00C400000004020D00040000000164 -:10219000020D000800000001020D000C000000010B -:1021A000020D001000000001020D001400000001EB -:1021B000020D001800000001020D001C00000001CB -:1021C000020D002000000001020D002400000001AB -:1021D000020D002800000001020D002C000000018B -:1021E000020D003000000001020D0034000000016B -:1021F000020D003800000001020D003C000000014B -:10220000020D011400000009020D011C0000000A6B -:10221000020D012400000000020D012C000000004E -:10222000020D013400000000020D013C0000000B13 -:10223000020D014400000000020D011800000029F9 -:10224000020D01200000002A020D012800000020DC -:10225000020D013000000020020D013800000020B6 -:10226000020D01400000002B020D0148000000207B -:10227000020D011400000019020D011C0000001ADB -:10228000020D012400000010020D012C00000010BE -:10229000020D013400000010020D013C0000001B83 -:1022A000020D014400000010020D01180000003969 -:1022B000020D01200000003A020D0128000000304C -:1022C000020D013000000030020D01380000003026 -:1022D000020D01400000003B020D014800000030EB -:1022E000020D011400000049020D011C0000004A0B -:1022F000020D012400000040020D012C00000040EE -:10230000020D013400000040020D013C0000004BB2 -:10231000020D014400000040020D01180000006998 -:10232000020D01200000006A020D0128000000607B -:10233000020D013000000060020D01380000006055 -:10234000020D01400000006B020D0148000000601A -:10235000020D011400000059020D011C0000005A7A -:10236000020D012400000050020D012C000000505D -:10237000020D013400000050020D013C0000005B22 -:10238000020D014400000050020D01180000007908 -:10239000020D01200000007A020D012800000070EB -:1023A000020D013000000070020D013800000070C5 -:1023B000020D01400000007B020D0148000000708A -:1023C000060E200000000800020E004C0000003243 -:1023D000020E009402150020020E00980215002043 -:1023E000020E009C00000030020E00A00810000049 -:1023F000020E00A400000033020E00A8000000300E -:10240000020E00AC00000031020E00B0000000021D -:10241000020E00B400000004020E00B8000000002C -:10242000020E00BC00000002020E00C0000000020C -:10243000020E00C400000000020E00C800000002EE -:10244000020E00CC00000007020E00D000000002C7 -:10245000020E00D400000002020E00D800000001AD -:10246000020E014400000001020E014C00000001B8 -:10247000020E015000000002020E020400000001E2 -:10248000020E020C00000040020E0210000000408C -:10249000020E021C00000004020E022000000020B8 -:1024A000020E02240000000E020E02280000001B93 -:1024B000060E030000000012040E0280001B0397AA -:1024C000060E02EC00000005020E00540000000C95 -:1024D000020E00580000000C020E005C000000001C -:1024E000020E006000000010020E006400000010E8 -:1024F000060E006800000003020E00DC000000036E -:10250000020E000400000001020E0008000000019D -:10251000020E000C00000001020E0010000000017D -:10252000020E001400000001020E0018000000015D -:10253000020E001C00000001020E0020000000013D -:10254000020E002400000001020E0028000000011D -:10255000020E002C00000001020E003000000001FD -:10256000020E003400000001020E003800000001DD -:10257000020E003C00000001020E004000000001BD -:10258000020E004400000001020E01100000000FC6 -:10259000020E011800000000020E012000000000E1 -:1025A000020E012800000000020E01140000002F9E -:1025B000020E011C00000020020E01240000000099 -:1025C000020E012C00000000020E01100000001F8E -:1025D000020E011800000010020E01200000000091 -:1025E000020E012800000000020E01140000003F4E -:1025F000020E011C00000030020E01240000000049 -:10260000020E012C00000000020E01100000004F1D -:10261000020E011800000040020E01200000000020 -:10262000020E012800000000020E01140000006FDD -:10263000020E011C00000060020E012400000000D8 -:10264000020E012C00000000020E01100000005FCD -:10265000020E011800000050020E012000000000D0 -:10266000020E012800000000020E01140000007F8D -:10267000020E011C00000070020E01240000000088 -:10268000020E012C000000000730040000C9000009 -:10269000083007D8000503B207340000332B0000D0 -:1026A0000734800030A40CCB07350000351A18F52C -:1026B000073580002A8A263C0736000018D830DF0C -:1026C00008364630373A03B40130000000000000FD -:1026D000013000040000000001300008000000008C -:1026E0000130000C0000000001300010000000006C -:1026F0000130001400000000023000200000000142 -:102700000230002400000002023000280000000314 -:102710000230002C000000000230003000000004F5 -:1027200002300034000000010230003800000000D8 -:102730000230003C000000010230004000000004B4 -:102740000230004400000000023000480000000198 -:102750000230004C00000003023000500000000076 -:102760000230005400000001023000580000000454 -:102770000230005C00000000023000600000000138 -:102780000230006400000003023000680000000016 -:102790000230006C000000010230007000000004F4 -:1027A00002300074000000000230007800000004D5 -:1027B0000230007C000000030630008000000002B0 -:1027C000023000A400003FFF023000A8000003FF19 -:1027D0000230022400000000023002340000000039 -:1027E0000230024C00000000023002E40000FFFF53 -:1027F000063020000000080002338BC000000001FA -:10280000023380000000001A023380400000004EB6 -:102810000233808000000010023380C000000020DE -:102820000C3383000007A1200A3383000000013825 -:102830000B338300000013880A338340000000003C -:102840000C338340000001F40B338340000000058B -:10285000023383800007A120023383C0000001F40B -:1028600002331480000000010A33148000000000CD -:10287000063280000000010206322008000000C875 -:10288000063220000000000204328EA0001003B6C1 -:1028900006323EB00000000606323ED800000002BC -:1028A00006323E800000000A04323EA8000203C641 -:1028B00006323E00000000200632500000000400F6 -:1028C0000632400000000004043274C0000203C855 -:1028D00006324110000000020632D0000000003035 -:1028E0000632DD40000000440632DA00000000D06D -:1028F0000632DEA0000000020632E0000000080000 -:1029000006328450000001180632100000000188D1 -:102910000632500000000020063251000000002066 -:102920000632520000000020063253000000002052 -:10293000063254000000002006325500000000203E -:10294000063256000000002006325700000000202A -:102950000632580000000020063259000000002016 -:1029600006325A000000002006325B000000002002 -:1029700006325C000000002006325D0000000020EE -:1029800006325E000000002006325F0000000020DA -:1029900006328DF00000000204328E00000203CAED -:1029A00006328E08000000020632DE9000000002AF -:1029B00006321C4000000038063288B000000118C2 -:1029C00006321620000001880632508000000020E8 -:1029D00006325180000000200632528000000020A4 -:1029E0000632538000000020063254800000002090 -:1029F000063255800000002006325680000000207C -:102A00000632578000000020063258800000002067 -:102A1000063259800000002006325A800000002053 -:102A200006325B800000002006325C80000000203F -:102A300006325D800000002006325E80000000202B -:102A400006325F800000002006328DF80000000290 -:102A500004328E10000203CC06328E1800000002F1 -:102A60000632DE980000000206321D200000003809 -:102A700002328D50000000000632401000000002BB -:102A800002328D5400000000063240200000000297 -:102A900002328D5800000000063240300000000273 -:102AA00002328D5C0000000006324040000000024F -:102AB00002328D600000000006324050000000022B -:102AC00002328D6400000000063240600000000207 -:102AD00002328D68000000000632407000000002E3 -:102AE00002328D6C000000000632408000000002BF -:102AF000072004000091000008200780001003CE8A -:102B0000072400002AFF00000724800015090AC0DE -:102B10000824A9F0692803D001200000000000006B -:102B20000120000400000000012000080000000057 -:102B30000120000C00000000012000100000000037 -:102B4000012000140000000002200020000000010D -:102B500002200024000000020220002800000003E0 -:102B60000220002C000000000220003000000004C1 -:102B700002200034000000010220003800000000A4 -:102B80000220003C00000001022000400000000480 -:102B90000220004400000000022000480000000164 -:102BA0000220004C00000003022000500000000042 -:102BB0000220005400000001022000580000000420 -:102BC0000220005C00000000022000600000000104 -:102BD00002200064000000030220006800000000E2 -:102BE0000220006C000000010220007000000004C0 -:102BF00002200074000000000220007800000004A1 -:102C00000220007C0000000306200080000000027B -:102C1000022000A400003FFF022000A8000003FFE4 -:102C20000220022400000000022002340000000004 -:102C30000220024C00000000022002E40000FFFF1E -:102C4000062020000000080002238BC000000001C5 -:102C500002238000000000100223804000000012C8 -:102C60000223808000000030022380C00000000E9C -:102C70000C2383000007A1200A23830000000138F1 -:102C80000B238300000013880A2383400000000008 -:102C90000C238340000001F40B2383400000000557 -:102CA000022383800007A120022383C0000001F4D7 -:102CB00002231480000000010A2314800000000099 -:102CC000062210000000004206222008000000C872 -:102CD00006222000000000020622B000000000C60C -:102CE0000422B318000503D20622B32C0000000B07 -:102CF0000422B358000503D70622B36C0000000B72 -:102D00000422B398000503DC0622B3AC0000000BDC -:102D10000422B3D8000503E10622B3EC0000000B47 -:102D20000422B418000503E60622B42C0000000BB0 -:102D30000422B458000503EB0622B46C0000000B1B -:102D40000422B498000503F00622B4AC0000000B86 -:102D50000422B4D8000503F50622B4EC0000000BF1 -:102D60000422B518000503FA0622B52C0000000B5A -:102D70000422B558000503FF0622B56C0000000BC5 -:102D80000422B598000504040622B5AC0000000B2F -:102D90000422B5D8000504090622B5EC0000000B9A -:102DA0000422B6180005040E0622B62C0000000B03 -:102DB0000422B658000504130622B66C0000000B6E -:102DC0000422B698000504180622B6AC0000000BD9 -:102DD0000422B6D80005041D0622B6EC0000000B44 -:102DE0000422B718000504220622B72C0000000BAD -:102DF0000422B758000504270622B76C0000000B18 -:102E00000422B7980005042C0622B7AC0000000B82 -:102E10000422B7D8000504310622B7EC0000000BED -:102E20000422B818000504360622B82C0000000B56 -:102E30000422B8580005043B0622B86C0000000BC1 -:102E40000422B898000504400622B8AC0000000B2C -:102E50000422B8D8000504450622B8EC0000000B97 -:102E60000422B9180005044A0622B92C0000000B00 -:102E70000422B9580005044F0622B96C0000000B6B -:102E80000422B998000504540622B9AC0000000BD6 -:102E90000422B9D8000504590622B9EC0000000B41 -:102EA0000422BA180005045E0622BA2C0000000BAA -:102EB0000422BA58000504630622BA6C0000000B15 -:102EC0000422BA98000504680622BAAC0000000B80 -:102ED0000422BAD80005046D0622BAEC00000005F1 -:102EE0000622BB00000000530422BC4C0001047207 -:102EF0000622BC50000000030422BC5C00010473E5 -:102F00000622BC60000000030422BC6C00010474B3 -:102F10000622BC70000000030422BC7C0001047582 -:102F20000622BC80000000030422BC8C0001047651 -:102F30000622BC90000000030422BC9C0001047720 -:102F40000622BCA0000000030422BCAC00010478EF -:102F50000622BCB0000000030422BCBC00010479BE -:102F60000622880000000100062280000000020006 -:102F7000042212700010047A06223000000000C003 -:102F800006226700000001000622900000000400F5 -:102F900004226B080020048A022212C0FFFFFFFFF8 -:102FA000062211E800000002062212C800000009F3 -:102FB000062212EC0000000906228C000000000826 -:102FC0000222114800000000062213200000000623 -:102FD000062233000000000206226040000000309C -:102FE00006228C20000000080222114C0000000084 -:102FF00006221338000000060622330800000002F3 -:10300000062261000000003006228C40000000080B -:10301000022211500000000006221350000000069A -:103020000622331000000002062261C000000030BA -:1030300006228C60000000080222115400000000EB -:103040000622136800000006062233180000000262 -:10305000062262800000003006228C8000000008FA -:103060000222115800000000062213800000000612 -:1030700006223320000000020622634000000030D8 -:1030800006228CA0000000080222115C0000000053 -:1030900006221398000000060622332800000002D2 -:1030A000062264000000003006228CC000000008E8 -:1030B0000222116000000000062213B0000000068A -:1030C0000622333000000002062264C000000030F7 -:1030D00006228CE0000000080222116400000000BB -:1030E000062213C800000006062233380000000242 -:1030F0000622658000000030021610000000002843 -:1031000002170008000000020217002C0000000354 -:103110000217003C000000040217004800000002F3 -:103120000217004C000000900217005000000090B1 -:103130000217005400800090021700580810000089 -:10314000021700600000008A02170064000000807F -:1031500002170068000000810217006C0000008068 -:10316000021700700000000602170078000007D068 -:103170000217007C0000076C02170038007C100466 -:10318000021700040000000F061640240000000291 -:10319000021640700000001C0216420800000001E8 -:1031A0000216421000000001021642200000000139 -:1031B0000216422800000001021642300000000101 -:1031C00002164238000000010216426000000002B0 -:1031D0000C16401C0003D0900A16401C0000009CF6 -:1031E0000B16401C000009C4021640300000000805 -:1031F000021640340000000C021640380000001097 -:1032000002164044000000200216400000000001A9 -:10321000021640D80000000102164008000000011C -:103220000216400C000000010216401000000001D0 -:103230000216424000000000021642480000000052 -:103240000616427000000002021642500000000004 -:1032500002164258000000000616428000000002DC -:1032600002166008000012240216600C0000121002 -:1032700002166010000012140216601C0000FFFF0E -:10328000021660200000FFFF021660240000FFFF0E -:10329000021660280000FFFF0216603800000020C0 -:1032A0000216603C0000002006166040000000028C -:1032B00002166048000000230216604C0000002443 -:1032C000021660500000002502166054000000261F -:1032D00002166058000000270216605C00000029FA -:1032E000021660600000002A021660640000002BD5 -:1032F000021660680000002C0216606C0000002DB1 -:1033000002166070000000EC0216607400000011EC -:1033100002166078000000120616607C0000000FA4 -:10332000021660B800000001021660BC0000000137 -:10333000061660C00000000C021660F000000001DC -:10334000061660F400000031021661B800000001AA -:10335000061661BC0000000D021661F000000001BD -:10336000061661F4000000110216623807FFFFFF25 -:103370000216623C0000003F0216624007FFFFFF9A -:10338000021662440000000F0116624800000000AF -:103390000116624C0000000001166250000000009F -:1033A000011662540000000001166258000000007F -:1033B0000116625C0000000001166260000000005F -:1033C000011662640000000001166268000000003F -:1033D0000116626C0000000001166270000000001F -:1033E00001166274000000000116627800000000FF -:1033F0000116627C000000000C166000000003E86B -:103400000A166000000000010B1660000000000AB0 -:1034100002168040000000060216804400000005ED -:10342000021680480000000A0216804C00000005C9 -:103430000216805400000002021680CC0000000436 -:10344000021680D000000004021680D400000004A0 -:10345000021680D800000004021680DC0000000480 -:10346000021680E000000004021680E40000000460 -:10347000021680E800000004021688040000000420 -:10348000021680300000007C021680340000003DEF -:10349000021680380000003F0216803C0000009CAD -:1034A000021680F000000007061680F400000005F8 -:1034B0000216880C010101010216810800000000BB -:1034C0000216810C000000040216811000000004A6 -:1034D0000216811400000002021688100801200460 -:1034E00002168118000000050216811C000000056C -:1034F000021681200000000502168124000000054C -:103500000216882C200810010216812800000008ED -:103510000216812C00000006021681300000000710 -:1035200002168134000000000216883001010120DB -:1035300006168138000000040216883401010101DA -:1035400002168148000000000216814C00000004B1 -:10355000021681500000000402168154000000028F -:103560000216883808012004021681580000000560 -:103570000216815C00000005021681600000000553 -:1035800002168164000000050216883C2008100124 -:1035900002168168000000080216816C0000000617 -:1035A00002168170000000070216817400000001FD -:1035B00002168840010101200216817800000001F6 -:1035C0000216817C000000010216818000000001CB -:1035D00002168184000000010216884401010101E5 -:1035E00002168188000000010216818C0000000490 -:1035F000021681900000000402168194000000026F -:10360000021688480801200402168198000000056F -:103610000216819C00000005021681A00000000532 -:10362000021681A40000000502168814200810016B -:10363000021681A800000008021681AC00000006F6 -:10364000021681B000000007021681B400000001DC -:103650000216881801010120021681B8000000013D -:10366000021681BC00000001021681C000000001AA -:10367000021681C4000000010216881C010101012C -:10368000021681C800000001021681CC000000046F -:10369000021681D000000004021681D4000000024E -:1036A0000216882008012004021681D800000005B7 -:1036B000021681DC00000005021681E00000000512 -:1036C000021681E40000000502168824200810017B -:1036D000021681E800000008021681EC00000006D6 -:1036E000021681F0000000070216E40C0000000042 -:1036F00002168828010101200616E41000000004CB -:103700000216E000010101010216E42000000000A1 -:103710000216E424000000040216E428000000045D -:103720000216E42C000000020216E0040801200446 -:103730000216E430000000050216E4340000000523 -:103740000216E438000000050216E43C0000000503 -:103750000216E008200810010216E44000000008EC -:103760000216E444000000060216E44800000007C8 -:103770000216E44C000000000216E00C01010120DA -:103780000616E450000000040216E01001010101D9 -:103790000216E460000000000216E4640000000469 -:1037A0000216E468000000040216E46C0000000247 -:1037B0000216E014080120040216E470000000055F -:1037C0000216E474000000050216E478000000050B -:1037D0000216E47C000000050216E0182008100123 -:1037E0000216E480000000080216E48400000006CF -:1037F0000216E488000000070216E48C00000001B5 -:103800000216E01C010101200216E49000000001F4 -:103810000216E494000000010216E4980000000182 -:103820000216E49C000000010216E02001010101E3 -:103830000216E4A0000000010216E4A40000000447 -:103840000216E4A8000000040216E4AC0000000226 -:103850000216E024080120040216E4B0000000056E -:103860000216E4B4000000050216E4B800000005EA -:103870000216E4BC000000050216E0282008100132 -:103880000216E4C0000000080216E4C400000006AE -:103890000216E4C8000000070216E4CC0000000194 -:1038A0000216E02C010101200216E4D00000000104 -:1038B0000216E4D4000000010216E4D80000000162 -:1038C0000216E4DC000000010216E03001010101F3 -:1038D0000216E4E0000000010216E4E40000000427 -:1038E0000216E4E8000000040216E4EC0000000206 -:1038F0000216E034080120040216E4F0000000057E -:103900000216E4F4000000050216E4F800000005C9 -:103910000216E4FC000000050216E0382008100141 -:103920000216E500000000080216E504000000068B -:103930000216E508000000070216E03C0101012024 -:1039400002168240003F003F021682440000000041 -:103950000216E524003F003F0216E52800000000A3 -:1039600002168248000000000216824C003F003F11 -:103970000216E52C000000000216E530003F003F73 -:10398000021682500100010002168254010001005B -:103990000216E534010001000216E53801000100BD -:1039A00006168258000000020216E53C00000000E6 -:1039B0000216E540000000000216826000C000C050 -:1039C0000216826400C000C00216E54400C000C0B8 -:1039D0000216E54800C000C0021682681E001E00E4 -:1039E0000216826C1E001E000216E54C1E001E0010 -:1039F0000216E5501E001E000216827040004000B4 -:103A000002168274400040000216E5544000400057 -:103A10000216E558400040000216827880008000BF -:103A20000216827C800080000216E55C8000800027 -:103A30000216E560800080000216828020002000CF -:103A400002168284200020000216E5642000200077 -:103A50000216E56820002000061682880000000299 -:103A60000216E56C000000000216E5700000000080 -:103A700002168290000000000216829400000000EE -:103A80000216E574000000000216E5780000000050 -:103A900002168298000000000216829C00000000BE -:103AA0000216E57C000000000216E5800000000020 -:103AB000021682A000000000021682A4000000018D -:103AC000061682A80000000A021681F400000C0805 -:103AD000021681F800000040021681FC000001007F -:103AE0000216820000000020021682040000001767 -:103AF00002168208000000800216820C00000200FC -:103B000002168210000000000216821801FF01FF59 -:103B10000216821401FF01FF0216E51001FF01FFEA -:103B20000216E50C01FF01FF0216823C00000013A3 -:103B3000021680900000013F0216806000000140E4 -:103B40000216806400000140061680680000000232 -:103B500002168070000000C0061680740000000786 -:103B60000216809C00000048021680A00000004859 -:103B7000061680A400000002021680AC0000004877 -:103B8000061680B000000007021682380000800090 -:103B900002168234000025E40216809400007FFFA4 -:103BA00002168220000F000F0216821C000F000F69 -:103BB0000216E518000F000F0216E514000F000FA3 -:103BC000021682280000000002168224FFFFFFFF79 -:103BD0000216E520000000000216E51CFFFFFFFFB3 -:103BE0000216E6BC000000000216E6C0000000025B -:103BF0000216E6C4000000010216E6C80000000339 -:103C00000216E6CC000000040216E6D00000000612 -:103C10000216E6D4000000050216E6D800000007F0 -:103C2000021680EC000000FF0214000000000001FA -:103C30000214000C0000000102140040000000010A -:103C40000214004400007FFF0214000C000000007A -:103C500002140000000000000214006C00000000CC -:103C600002140004000000010214003000000001F2 -:103C700002140004000000000214005C00000000B8 -:103C800002140008000000010214003400000001CA -:103C90000214000800000000021400600000000090 -:103CA00006028000000020000202005800000032DE -:103CB000020200A003150020020200A40315002048 -:103CC000020200A801000030020200AC081000004F -:103CD000020200B000000033020200B40000003015 -:103CE000020200B800000031020200BC0000000324 -:103CF000020200C000000006020200C4000000032F -:103D0000020200C800000003020200CC0000000212 -:103D1000020200D000000000020200D400000002F5 -:103D2000020200DC00000000020200E000000006C9 -:103D3000020200E400000004020200E800000002A9 -:103D4000020200EC00000002020200F0000000018C -:103D5000020200FC00000006020201200000000038 -:103D60000202013400000002020201B00000000162 -:103D70000202020C00000001020202140000000115 -:103D80000202021800000002020204040000000106 -:103D90000202040C00000040020204100000004077 -:103DA0000202041C000000040202042000000020A3 -:103DB0000202042400000002020204280000002085 -:103DC000060205000000001204020480002004AA7C -:103DD000020200600000000F020200640000000701 -:103DE00002020068000000000202006C0000000EE9 -:103DF000020200700000000E0602007400000003C2 -:103E0000020200F4000000040202000400000001AD -:103E100002020008000000010202000C0000000184 -:103E20000202001000000001020200140000000164 -:103E300002020018000000010202001C0000000144 -:103E40000202002000000001020200240000000124 -:103E500002020028000000010202002C0000000104 -:103E600002020030000000010202003400000001E4 -:103E700002020038000000010202003C00000001C4 -:103E800002020040000000010202004400000001A4 -:103E900002020048000000010202004C0000000184 -:103EA000020200500000000102020108000000C8E8 -:103EB0000202011800000002020201C4000000001A -:103EC000020201CC00000000020201D40000000246 -:103ED000020201DC00000002020201E4000000FF17 -:103EE000020201EC000000FF0202010000000000DD -:103EF0000202010C000000C80202011C00000002C6 -:103F0000020201C800000000020201D0000000000F -:103F1000020201D800000002020201E000000002DB -:103F2000020201E8000000FF020201F0000000FFB1 -:103F3000020201040000000002020108000000C8A3 -:103F40000202011800000002020201C40000000089 -:103F5000020201CC00000000020201D400000002B5 -:103F6000020201DC00000002020201E4000000FF86 -:103F7000020201EC000000FF02020100000000004C -:103F80000202010C000000C80202011C0000000235 -:103F9000020201C800000000020201D0000000007F -:103FA000020201D800000002020201E0000000024B -:103FB000020201E8000000FF020201F0000000FF21 -:103FC000020201040000000002020108000000C813 -:103FD0000202011800000002020201C400000000F9 -:103FE000020201CC00000000020201D40000000225 -:103FF000020201DC00000002020201E4000000FFF6 -:10400000020201EC000000FF0202010000000000BB -:104010000202010C000000C80202011C00000002A4 -:10402000020201C800000000020201D000000000EE -:10403000020201D800000002020201E000000002BA -:10404000020201E8000000FF020201F0000000FF90 -:10405000020201040000000002020108000000C882 -:104060000202011800000002020201C40000000068 -:10407000020201CC00000000020201D40000000294 -:10408000020201DC00000002020201E4000000FF65 -:10409000020201EC000000FF02020100000000002B -:1040A0000202010C000000C80202011C0000000214 -:1040B000020201C800000000020201D0000000005E -:1040C000020201D800000002020201E0000000022A -:1040D000020201E8000000FF020201F0000000FF00 -:1040E00002020104000000000728040000A30000F1 -:1040F000082807B8000904CA072C000034F10000A2 -:10410000072C800038A60D3D072D000037B61B6731 -:10411000072D800032632955072E00001C6835EEFC -:10412000082E48B036EA04CC012800000000000048 -:104130000128000400000000012800080000000021 -:104140000128000C00000000012800100000000001 -:1041500001280014000000000228002000000001D7 -:1041600002280024000000020228002800000003AA -:104170000228002C0000000002280030000000048B -:10418000022800340000000102280038000000006E -:104190000228003C0000000102280040000000044A -:1041A000022800440000000002280048000000012E -:1041B0000228004C0000000302280050000000000C -:1041C00002280054000000010228005800000004EA -:1041D0000228005C000000000228006000000001CE -:1041E00002280064000000030228006800000000AC -:1041F0000228006C0000000102280070000000048A -:10420000022800740000000002280078000000046A -:104210000228007C00000003062800800000000245 -:10422000022800A400003FFF022800A8000003FFAE -:1042300002280224000000000228023400000000CE -:104240000228024C00000000022802E40000FFFFE8 -:104250000628200000000800022B8BC0000000018F -:10426000022B800000000000022B8040000000189C -:10427000022B80800000000C022B80C00000006632 -:104280000C2B83000007A1200A2B830000000138BB -:104290000B2B8300000013880A2B834000000000D2 -:1042A0000C2B8340000001F40B2B83400000000521 -:1042B000022B83800007A120022B83C0000001F4A1 -:1042C000022B1480000000010A2B14800000000063 -:1042D000062A9AF800000004042A9B08000204CE73 -:1042E000062A9B1000000006062A90800000004865 -:1042F000062A2008000000C8062A2000000000024C -:10430000062A91A800000086062A900000000020DE -:10431000062A93C800000003042A93D4000104D0A5 -:10432000062A9DA800000002042A9498000404D1E3 -:10433000042A9D58000104D5062A9D5C0000001146 -:10434000042ACB20001004D6042A3000000204E620 -:10435000062A300800000100062A40400000001034 -:10436000042A4000001004E8042A8408000204F82B -:10437000062A9DA000000002062AB000000000509E -:10438000062ABB7000000070062AB150000000022F -:10439000062ABB6000000004062AD00000000800C6 -:1043A000062AC00000000150062A94A8000000322E -:1043B000062A502000000002062A503000000002A9 -:1043C000062A500000000002062A501000000002D9 -:1043D000022A520800000001042A9B28000204FA65 -:1043E000062A963800000022042A96C0000104FC28 -:1043F000062A96C400000003062A976800000022DF -:10440000042A97F0000104FD062A97F40000000337 -:10441000062A989800000022042A9920000104FE30 -:10442000062A992400000003062A99C800000022E9 -:10443000042A9A50000104FF062A9A54000000033F -:10444000062AB14000000002062AC54000000150C3 -:10445000062A957000000032062A5028000000024B -:10446000062A503800000002062A50080000000208 -:10447000062A501800000002022A520C0000000117 -:10448000042A9B3000020500062A96D00000002274 -:10449000042A975800010502062A975C00000003D1 -:1044A000062A980000000022042A988800010503CB -:1044B000062A988C00000003062A9930000000228A -:1044C000042A99B800010504062A99BC00000003DB -:1044D000062A9A6000000022042A9AE800010505D5 -:1044E000062A9AEC00000003062AB14800000002E8 -:1044F000022ACA8000000000042A9B38001005062A -:10450000062A50480000000E022ACA84000000005B -:10451000042A9B7800100516062A50800000000E21 -:10452000022ACA8800000000042A9BB80010052651 -:10453000062A50B80000000E022ACA8C00000000B3 -:10454000042A9BF800100536062A50F00000000EE1 -:10455000022ACA9000000000042A9C380010054678 -:10456000062A51280000000E022ACA94000000000A -:10457000042A9C7800100556062A51600000000E9F -:10458000022ACA9800000000042A9CB800100566A0 -:10459000062A51980000000E022ACA9C0000000062 -:1045A000042A9CF800100576062A51D00000000E5F -:1045B000021010080000000102101050000000015D -:1045C000021010000003D000021010040000003D93 -:1045D0000910180002000586091011000010078656 -:1045E0000610114000000008091011600010079625 -:1045F000061011A00000001806102400000000E0C2 -:104600000210201C00000000021020200000000109 -:10461000021020C00000000202102004000000016F -:10462000021020080000000109103C00000507A648 -:1046300009103800000507AB09103820000507B045 -:1046400006104C000000010002104028000000107D -:104650000210404400003FFF0210405800280000B4 -:10466000021040840084924A02104058000000006A -:104670000210800000001080021080AC00000000DA -:1046800002108038000000100210810000000000BD -:10469000061081200000000202108008000002B510 -:1046A0000210801000000000061082000000004A86 -:1046B000021081080001FFFF061081400000000287 -:1046C0000210800000001A800610900000000024F4 -:1046D000061091200000004A061093700000004A66 -:1046E000061095C00000004A0210800400001080EF -:1046F000021080B0000000010210803C0000001099 -:104700000210810400000000061081280000000251 -:104710000210800C000002B502108014000000009E -:10472000061084000000004A0210810C0001FFFF07 -:1047300006108148000000020210800400001A8068 -:104740000610909000000024061092480000004AD5 -:10475000061094980000004A061096E80000004AEF -:104760000210800000001080021080AC00000002E7 -:1047700002108038000000100210810000000000CC -:10478000061081200000000202108008000002B51F -:104790000210801000000000061082000000004A95 -:1047A000021081080001FFFF061081400000000296 -:1047B0000210800000001A80061090000000002403 -:1047C000061091200000004A061093700000004A75 -:1047D000061095C00000004A0210800400001080FE -:1047E000021080B0000000030210803C00000010A6 -:1047F0000210810400000000061081280000000261 -:104800000210800C000002B50210801400000000AD -:10481000061084000000004A0210810C0001FFFF16 -:1048200006108148000000020210800400001A8077 -:104830000610909000000024061092480000004AE4 -:10484000061094980000004A061096E80000004AFE -:104850000210800000001080021080AC00000004F4 -:1048600002108038000000100210810000000000DB -:10487000061081200000000202108008000002B52E -:104880000210801000000000061082000000004AA4 -:10489000021081080001FFFF0610814000000002A5 -:1048A0000210800000001A80061090000000002412 -:1048B000061091200000004A061093700000004A84 -:1048C000061095C00000004A02108004000010800D -:1048D000021080B0000000050210803C00000010B3 -:1048E0000210810400000000061081280000000270 -:1048F0000210800C000002B50210801400000000BD -:10490000061084000000004A0210810C0001FFFF25 -:1049100006108148000000020210800400001A8086 -:104920000610909000000024061092480000004AF3 -:10493000061094980000004A061096E80000004A0D -:104940000210800000001080021080AC0000000601 -:1049500002108038000000100210810000000000EA -:10496000061081200000000202108008000002B53D -:104970000210801000000000061082000000004AB3 -:10498000021081080001FFFF0610814000000002B4 -:104990000210800000001A80061090000000002421 -:1049A000061091200000004A061093700000004A93 -:1049B000061095C00000004A02108004000010801C -:1049C000021080B0000000070210803C00000010C0 -:1049D000021081040000000006108128000000027F -:1049E0000210800C000002B50210801400000000CC -:1049F000061084000000004A0210810C0001FFFF35 -:104A000006108148000000020210800400001A8095 -:104A10000610909000000024061092480000004A02 -:104A2000061094980000004A061096E80000004A1C -:104A3000021205B0000000010212049000E383405E -:104A40000212051400003C100212066C0000000166 -:104A5000021206700000000002120494FFFFFFFF24 -:104A600002120498FFFFFFFF0212049CFFFFFFFFEA -:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA -:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA -:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82 -:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A -:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A -:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 -:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 -:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 -:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 -:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 -:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 -:104B200002120504FFFFFFFF02120508FFFFFFFF4F -:104B30000212050CFFFFFFFF02120510FFFFFFFF2F -:104B4000021204D4FF809000021204B4F00050005E -:104B5000021204B8F00010000212039000000008D6 -:104B60000212039C00000008021203A000000008CB -:104B7000021203A400000002021203BC00000004A1 -:104B8000021203C000000005021203C4000000046A -:104B9000021203D0000000000212036C00000001AA -:104BA000021203680000003F021201BC0000004036 -:104BB000021201C000001808021201C4000008031C -:104BC000021201C800000803021201CC00000040DC -:104BD000021201D000000003021201D400000803F9 -:104BE000021201D800000803021201DC00000803D1 -:104BF000021201E000010003021201E400000803B8 -:104C0000021201E800000803021201EC0000000398 -:104C1000021201F000000003021201F40000000380 -:104C2000021201F800000003021201FC0000000360 -:104C3000021202000000000302120204000000033E -:104C400002120208000000030212020C000000031E -:104C500002120210000000030212021400000003FE -:104C600002120218000000030212021C00000003DE -:104C700002120220000000030212022400000003BE -:104C800002120228000024030212022C0000002F4E -:104C90000212023000000009021202340000001962 -:104CA00002120238000001840212023C000001835B -:104CB0000212024000000306021202440000001922 -:104CC00002120248000000060212024C0000030615 -:104CD00002120250000003060212025400000306F2 -:104CE0000212025800000C860212025C0000030649 -:104CF00002120260000003060212026400000006B5 -:104D000002120268000000060212026C0000000697 -:104D10000212027000000006021202740000000677 -:104D200002120278000000060212027C0000000657 -:104D30000212028000000006021202840000000637 -:104D400002120288000000060212028C0000000617 -:104D500002120290000000060212029400000006F7 -:104D600002120298000000060212029C00000006D7 -:104D7000021202A000000306021202A400000013A7 -:104D8000021202A800000006021202B00000100485 -:104D9000021202B400001004021203240010644046 -:104DA0000212032800106440021205B40000000142 -:104DB000021201B0000000010600A0000000000C7B -:104DC0000200A050000000000200A05400000000FB -:104DD0000200A0EC555400000200A0F055555555B6 -:104DE0000200A0F4000055550200A0F8F0000000F9 -:104DF0000200A0FC555400000200A1005555555575 -:104E00000200A104000055550200A108F0000000B6 -:104E10000200A18C555400000200A1905555555533 -:104E20000200A194000055550200A198F000000076 -:104E30000200A19C000000000200A1A000010000EF -:104E40000200A1A4000050140200A1A8000000006C -:104E50000200A45C00000C000200A61C000000037D -:104E60000200A06CFF5C00000200A070FFF55FFF75 -:104E70000200A0740000FFFF0200A078F00003E031 -:104E80000200A07C000000000200A0800000A00042 -:104E90000600A084000000050200A0980FE00000BA -:104EA0000600A09C000000070200A0B8000004005B -:104EB0000600A0BC000000030200A0C80000100013 -:104EC0000600A0CC000000030200A0D800004000B3 -:104ED0000600A0DC000000030200A0E800010000C2 -:104EE0000600A22C000000040200A10CFF5C0000E0 -:104EF0000200A110FFF55FFF0200A1140000FFFFF8 -:104F00000200A118F00003E00200A11C0000000054 -:104F10000200A1200000A0000600A124000000055E -:104F20000200A1380FE000000600A13C00000007CD -:104F30000200A158000008000600A15C0000000368 -:104F40000200A168000020000600A16C0000000320 -:104F50000200A178000080000600A17C0000000390 -:104F60000200A188000200000600A23C000000042C -:104F70000200A030000000000200A0340000000089 -:104F80000200A038000000000200A03C0000000069 -:104F90000200A040000000000200A0440000000049 -:104FA0000200A048000000000200A04C0000000029 -:104FB00000000000000000000000003000000000C1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE0000000000000300031000000000000000060 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:10501000003100520000000000000000000000000D -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000052008995 -:1050400000000000000000000089008D008D00912C -:1050500000910095009500990099009D009D00A188 -:1050600000A100A500A500A900A900AE00AE00B1F6 -:1050700000B100B4000000000000000000000000CB -:105080000000000000000000000000000000000020 -:105090000000000000B40309030903130313031DF8 -:1050A000031D03240324032B032B03320332033990 -:1050B00003390340034003470347034E034E0355A0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:105170000355035B0000000000000000035B035CBC -:10518000035C035D035D035E035E035F035F036017 -:1051900003600361036103620362036300000000B4 -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000363036D036D037B1B -:1051D000037B0389000000000000000000000000C5 -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:105220000389038A00000000000000000000000065 -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000038A03D6F8 -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000003D604010000000050 -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000040104330000000000000000C2 -:1052B0000433043A043A0441044104480448044FC6 -:1052C000044F04560456045D045D04640464046BD6 -:1052D000046B04A4000000000000000004A404A863 -:1052E00004A804AC04AC04B004B004B404B404B81E -:1052F00004B804BC04BC04C004C004C404C4051342 -:105300000513052A052A05410541054305430545C1 -:1053100005450547054705490549054B054B054D1D -:10532000054D054F054F0551055105E805E805E90F -:1053300005E905EA05EA05EF05EF05F405F405F9C9 -:1053400005F905FE05FE0603060306080608060D18 -:10535000060D0612061206130000000000000000F1 -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:1053800006130624000000000000000000000000DA -:10539000000000000000000000000000000000000D -:1053A0000000000000000000000000000624063994 -:1053B0000639063C063C063F0000000000000000E5 -:1053C00000000000000000000000000000000000DD -:1053D0000000000000000000063F0675000000000D -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:1054000000000000067507780000000000000000A2 -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:105430000778077F077F078307830787000000003F -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000078707C8EF -:10546000000000000000000007C807D107D107DADC -:1054700007DA07E307E307EC07EC07F507F507FE94 -:1054800007FE080708070810081008670867087C67 -:10549000087C089108910894089408970897089A3E -:1054A000089A089D089D08A008A008A308A308A6BC -:1054B00008A608A908A908B2000000000000000022 -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00008B208B800000000000000000000000042 -:1054F00000000000000000000000000000000000AC -:1055000000000000000000000000000008B808BB18 -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000008BB08C100000000DF -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:1055700008C108D008D008DF08DF08EE08EE08FDF3 -:1055800008FD090C090C091B091B092A092A0939FC -:10559000093909AA00000000000000000000000016 -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000009AA09BF70 -:1055C00009BF09D009D009E109E109E209E209E3CB -:1055D00009E309E409E409E509E509E609E609E75B -:1055E00009E709E809E809E90000000000000000F7 -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C000000000000000000000010000000204C013 -:1056D0000003098000040E4000051300000617C0F7 -:1056E00000071C800008214000092600000A2AC08B -:1056F000000B2F80000C3440000D3900000E3DC01F -:10570000000F42800010474000114C00001250C0B2 -:105710000013558000145A4000155F00001663C046 -:105720000017688000186D4000197200001A76C0DA -:10573000001B7B80001C8040001D8500001E89C06E -:10574000001F8E80000093400000200000004000F9 -:1057500000006000000080000000A0000000C00009 -:105760000000E000000100000001200000014000F6 -:1057700000016000000180000001A0000001C000E5 -:105780000001E000000200000002200000024000D2 -:1057900000026000000280000002A0000002C000C1 -:1057A0000002E000000300000003200000034000AE -:1057B00000036000000380000003A0000003C0009D -:1057C0000003E0000004000000042000000440008A -:1057D00000046000000480000004A0000004C00079 -:1057E0000004E00000050000000520000005400066 -:1057F00000056000000580000005A0000005C00055 -:105800000005E00000060000000620000006400041 -:1058100000066000000680000006A0000006C00030 -:105820000006E0000007000000072000000740001D -:1058300000076000000780000007A0000007C0000C -:105840000007E000000800000008200000084000F9 -:1058500000086000000880000008A0000008C000E8 -:105860000008E000000900000009200000094000D5 -:1058700000096000000980000009A0000009C000C4 -:105880000009E000000A0000000A2000000A4000B1 -:10589000000A6000000A8000000AA000000AC000A0 -:1058A000000AE000000B0000000B2000000B40008D -:1058B000000B6000000B8000000BA000000BC0007C -:1058C000000BE000000C0000000C2000000C400069 -:1058D000000C6000000C8000000CA000000CC00058 -:1058E000000CE000000D0000000D2000000D400045 -:1058F000000D6000000D8000000DA000000DC00034 -:10590000000DE000000E0000000E2000000E400020 -:10591000000E6000000E8000000EA000000EC0000F -:10592000000EE000000F0000000F2000000F4000FC -:10593000000F6000000F8000000FA000000FC000EB -:10594000000FE000001000000010200000104000D8 -:1059500000106000001080000010A0000010C000C7 -:105960000010E000001100000011200000114000B4 -:1059700000116000001180000011A0000011C000A3 -:105980000011E00000120000001220000012400090 -:1059900000126000001280000012A0000012C0007F -:1059A0000012E0000013000000132000001340006C -:1059B00000136000001380000013A0000013C0005B -:1059C0000013E00000140000001420000014400048 -:1059D00000146000001480000014A0000014C00037 -:1059E0000014E00000150000001520000015400024 -:1059F00000156000001580000015A0000015C00013 -:105A00000015E000001600000016200000164000FF -:105A100000166000001680000016A0000016C000EE -:105A20000016E000001700000017200000174000DB -:105A300000176000001780000017A0000017C000CA -:105A40000017E000001800000018200000184000B7 -:105A500000186000001880000018A0000018C000A6 -:105A60000018E00000190000001920000019400093 -:105A700000196000001980000019A0000019C00082 -:105A80000019E000001A0000001A2000001A40006F -:105A9000001A6000001A8000001AA000001AC0005E -:105AA000001AE000001B0000001B2000001B40004B -:105AB000001B6000001B8000001BA000001BC0003A -:105AC000001BE000001C0000001C2000001C400027 -:105AD000001C6000001C8000001CA000001CC00016 -:105AE000001CE000001D0000001D2000001D400003 -:105AF000001D6000001D8000001DA000001DC000F2 -:105B0000001DE000001E0000001E2000001E4000DE -:105B1000001E6000001E8000001EA000001EC000CD -:105B2000001EE000001F0000001F2000001F4000BA -:105B3000001F6000001F8000001FA000001FC000A9 -:105B4000001FE00000200000002020000020400096 -:105B500000206000002080000020A0000020C00085 -:105B60000020E00000210000002120000021400072 -:105B700000216000002180000021A0000021C00061 -:105B80000021E0000022000000222000002240004E -:105B900000226000002280000022A0000022C0003D -:105BA0000022E0000023000000232000002340002A -:105BB00000236000002380000023A0000023C00019 -:105BC0000023E00000240000002420000024400006 -:105BD00000246000002480000024A0000024C000F5 -:105BE0000024E000002500000025200000254000E2 -:105BF00000256000002580000025A0000025C000D1 -:105C00000025E000002600000026200000264000BD -:105C100000266000002680000026A0000026C000AC -:105C20000026E00000270000002720000027400099 -:105C300000276000002780000027A0000027C00088 -:105C40000027E00000280000002820000028400075 -:105C500000286000002880000028A0000028C00064 -:105C60000028E00000290000002920000029400051 -:105C700000296000002980000029A0000029C00040 -:105C80000029E000002A0000002A2000002A40002D -:105C9000002A6000002A8000002AA000002AC0001C -:105CA000002AE000002B0000002B2000002B400009 -:105CB000002B6000002B8000002BA000002BC000F8 -:105CC000002BE000002C0000002C2000002C4000E5 -:105CD000002C6000002C8000002CA000002CC000D4 -:105CE000002CE000002D0000002D2000002D4000C1 -:105CF000002D6000002D8000002DA000002DC000B0 -:105D0000002DE000002E0000002E2000002E40009C -:105D1000002E6000002E8000002EA000002EC0008B -:105D2000002EE000002F0000002F2000002F400078 -:105D3000002F6000002F8000002FA000002FC00067 -:105D4000002FE00000300000003020000030400054 -:105D500000306000003080000030A0000030C00043 -:105D60000030E00000310000003120000031400030 -:105D700000316000003180000031A0000031C0001F -:105D80000031E0000032000000322000003240000C -:105D900000326000003280000032A0000032C000FB -:105DA0000032E000003300000033200000334000E8 -:105DB00000336000003380000033A0000033C000D7 -:105DC0000033E000003400000034200000344000C4 -:105DD00000346000003480000034A0000034C000B3 -:105DE0000034E000003500000035200000354000A0 -:105DF00000356000003580000035A0000035C0008F -:105E00000035E0000036000000362000003640007B -:105E100000366000003680000036A0000036C0006A -:105E20000036E00000370000003720000037400057 -:105E300000376000003780000037A0000037C00046 -:105E40000037E00000380000003820000038400033 -:105E500000386000003880000038A0000038C00022 -:105E60000038E0000039000000392000003940000F -:105E700000396000003980000039A0000039C000FE -:105E80000039E000003A0000003A2000003A4000EB -:105E9000003A6000003A8000003AA000003AC000DA -:105EA000003AE000003B0000003B2000003B4000C7 -:105EB000003B6000003B8000003BA000003BC000B6 -:105EC000003BE000003C0000003C2000003C4000A3 -:105ED000003C6000003C8000003CA000003CC00092 -:105EE000003CE000003D0000003D2000003D40007F -:105EF000003D6000003D8000003DA000003DC0006E -:105F0000003DE000003E0000003E2000003E40005A -:105F1000003E6000003E8000003EA000003EC00049 -:105F2000003EE000003F0000003F2000003F400036 -:105F3000003F6000003F8000003FA000003FC00025 -:105F4000003FE000003FE00100000000000001FF12 -:105F50000000020000007FF800007FF80000014010 -:105F600000003500000000010000FF0000000000FC -:105F70000000FF00000000000000FF000000000023 -:105F80000000FF00000000000000FF000000000013 -:105F90000000FF00000000000000FF000000000003 -:105FA0000000FF000000000000000000140AFF00D5 -:105FB00000000001000000000020100100000000AF -:105FC0000100900000000100000090020000900419 -:105FD00000009006000090080000900A0000900C5D -:105FE0000000900E0000901000009012000090142D -:105FF00000009016000090180000901A0000901CFD -:106000000000901E000090200000902200009024CC -:1060100000009026000090280000902A0000902C9C -:106020000000902E0000903000009032000090346C -:1060300000009036000090380000903A0000903C3C -:106040000000903E0000904000009042000090440C -:1060500000009046000090480000904A0000904CDC -:106060000000904E000090500000905200009054AC -:1060700000009056000090580000905A0000905C7C -:106080000000905E0000906000009062000090644C -:1060900000009066000090680000906A0000906C1C -:1060A0000000906E000090700000907200009074EC -:1060B00000009076000090780000907A0000907CBC -:1060C0000000907E0000908000009082000090848C -:1060D00000009086000090880000908A0000908C5C -:1060E0000000908E0000909000009092000090942C -:1060F00000009096000090980000909A0000909CFC -:106100000000909E000090A0000090A2000090A4CB -:10611000000090A6000090A8000090AA000090AC9B -:10612000000090AE000090B0000090B2000090B46B -:10613000000090B6000090B8000090BA000090BC3B -:10614000000090BE000090C0000090C2000090C40B -:10615000000090C6000090C8000090CA000090CCDB -:10616000000090CE000090D0000090D2000090D4AB -:10617000000090D6000090D8000090DA000090DC7B -:10618000000090DE000090E0000090E2000090E44B -:10619000000090E6000090E8000090EA000090EC1B -:1061A000000090EE000090F0000090F2000090F4EB -:1061B000000090F6000090F8000090FA000090FCBB -:1061C000000090FE00009100000091020000910488 -:1061D00000009106000091080000910A0000910C57 -:1061E0000000910E00009110000091120000911427 -:1061F00000009116000091180000911A0000911CF7 -:106200000000911E000091200000912200009124C6 -:1062100000009126000091280000912A0000912C96 -:106220000000912E00009130000091320000913466 -:1062300000009136000091380000913A0000913C36 -:106240000000913E00009140000091420000914406 -:1062500000009146000091480000914A0000914CD6 -:106260000000914E000091500000915200009154A6 -:1062700000009156000091580000915A0000915C76 -:106280000000915E00009160000091620000916446 -:1062900000009166000091680000916A0000916C16 -:1062A0000000916E000091700000917200009174E6 -:1062B00000009176000091780000917A0000917CB6 -:1062C0000000917E00009180000091820000918486 -:1062D00000009186000091880000918A0000918C56 -:1062E0000000918E00009190000091920000919426 -:1062F00000009196000091980000919A0000919CF6 -:106300000000919E000091A0000091A2000091A4C5 -:10631000000091A6000091A8000091AA000091AC95 -:10632000000091AE000091B0000091B2000091B465 -:10633000000091B6000091B8000091BA000091BC35 -:10634000000091BE000091C0000091C2000091C405 -:10635000000091C6000091C8000091CA000091CCD5 -:10636000000091CE000091D0000091D2000091D4A5 -:10637000000091D6000091D8000091DA000091DC75 -:10638000000091DE000091E0000091E2000091E445 -:10639000000091E6000091E8000091EA000091EC15 -:1063A000000091EE000091F0000091F2000091F4E5 -:1063B000000091F6000091F8000091FA000091FCB5 -:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A -:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD -:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C -:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C -:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C -:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C -:10644000FFFFFFFF0000000300BEBC2000000000B3 -:10645000000000050000000300BEBC20000000009A -:10646000000000050000000300BEBC20000000008A -:10647000000000050000000300BEBC20000000007A -:10648000000000050000000300BEBC20000000006A -:10649000000000050000000300BEBC20000000005A -:1064A000000000050000000300BEBC20000000004A -:1064B000000000050000000300BEBC20000000003A -:1064C0000000000500002000000040C000006180C6 -:1064D000000082400000A3000000C3C00000E48070 -:1064E0000001054000012600000146C00001678050 -:1064F000000188400001A9000001C9C00001EA8034 -:1065000000020B4000022C0000024CC000026D8013 -:1065100000028E400002AF000002CFC00002F080F7 -:10652000000011400000800000010380000187008E -:1065300000020A8000028E00000311800003950013 -:106540000004188000049C0000051F800005A300C3 -:10655000000626800006AA0000072D800007B10073 -:10656000000834800008B80000093B800009BF0023 -:10657000000A4280000AC600000B4980000BCD00D3 -:10658000000C5080000CD400000D578000005B0010 -:1065900000007FF800007FF8000000D50000150023 -:1065A0000000FF00000000000000FF0000000000ED -:1065B0000000FF00000000000000FF0000000000DD -:1065C0000000FF00000000000000FF0000000000CD -:1065D0000000FF00000000000000FF0000000000BD -:1065E000000019000000000000000000FFFFFFFF96 -:1065F0000000000003938700000000000393870061 -:1066000000007FF800007FF80000068E00003500D3 -:106610000000FF000FFFFFFF0000FF000FFFFFFF64 -:10662000000000FF0000FF000FFFFFFF0000FF0061 -:106630000FFFFFFF000000FF0000FF000FFFFFFF44 -:106640000000FF000FFFFFFF000000FF0000FF0041 -:106650000FFFFFFF0000FF000FFFFFFF000000FF24 -:106660000000FF000FFFFFFF0000FF000FFFFFFF14 -:10667000000000FF0000FF000FFFFFFF0000FF0011 -:106680000FFFFFFF000000FF0000FF000FFFFFFFF4 -:106690000000FF000FFFFFFF000000FF0000FF00F1 -:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4 -:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4 -:1066C000000000FF0000FF000FFFFFFF0000FF00C1 -:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4 -:1066E0000000FF000FFFFFFF000000FF0000FF00A1 -:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84 -:106700000000FF000FFFFFFF0000FF000FFFFFFF73 -:10671000000000FF0000FF000FFFFFFF0000FF0070 -:106720000FFFFFFF000000FF0000FF000FFFFFFF53 -:106730000000FF000FFFFFFF000000FF0000FF0050 -:106740000FFFFFFF0000FF000FFFFFFF000000FF33 -:106750000000FF000FFFFFFF0000FF000FFFFFFF23 -:10676000000000FF0000FF000FFFFFFF0000FF0020 -:106770000FFFFFFF000000FF0000FF000FFFFFFF03 -:106780000000FF000FFFFFFF000000FF0000FF0000 -:106790000FFFFFFF0000FF000FFFFFFF000000FFE3 -:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3 -:1067B000000000FF0000FF000FFFFFFF0000FF00D0 -:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3 -:1067D0000000FF000FFFFFFF000000FF0000FF00B0 -:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93 -:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83 -:10680000000000FF0000FF000FFFFFFF0000FF007F -:106810000FFFFFFF000000FF0000FF000FFFFFFF62 -:106820000000FF000FFFFFFF000000FF0000FF005F -:106830000FFFFFFF0000FF000FFFFFFF000000FF42 -:106840000000FF000FFFFFFF0000FF000FFFFFFF32 -:10685000000000FF0000FF000FFFFFFF0000FF002F -:106860000FFFFFFF000000FF0000FF000FFFFFFF12 -:106870000000FF000FFFFFFF000000FF0000FF000F -:106880000FFFFFFF0000FF000FFFFFFF000000FFF2 -:10689000000000FF000000FF000000FF000000FFFC -:1068A000000000FF000000FF000000FF000000FFEC -:1068B0000000FF00000000000000FF0000000000DA -:1068C0000000FF00000000000000FF0000000000CA -:1068D0000000FF00000000000000FF0000000000BA -:1068E0000000FF00000000000000FF0000000000AA -:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 -:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 -:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 -:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 -:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 -:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 -:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 -:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 -:106970000000100000002080000031000000418075 -:10698000000052000000628000007300000083805D -:10699000000094000000A4800000B5000000C58045 -:1069A0000000D6000000E6800000F700000107802C -:1069B0000001180000012880000139000001498011 -:1069C00000015A0000016A8000017B0000018B80F9 -:1069D00000019C000001AC800001BD000001CD80E1 -:1069E0000001DE000001EE800001FF0000000F80CA -:1069F00000007FF800007FF800000344000035002D -:106A000010000000000028AD00010001000902068E -:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41 -:106A20000000FF00000000000000FF000000000068 -:106A30000000FF00000000000000FF000000000058 -:106A40000000FF00000000000000FF000000000048 -:106A50000000FF00000000000000FF000000000038 -:106A60000000000000000001CCCC0201CCCCCCCC5A -:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80 -:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70 -:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60 -:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F -:106AB000000E0000011600D6002625A0002625A005 -:106AC000002625A0002625A000720000012300F367 -:106AD000002625A0002625A0002625A0002625A00A -:106AE0000000FFFF000000000000FFFF00000000AA -:106AF0000000FFFF000000000000FFFF000000009A -:106B00000000FFFF000000000000FFFF0000000089 -:106B10000000FFFF000000000000FFFF0000000079 -:106B20000000FFFF000000000000FFFF0000000069 -:106B30000000FFFF000000000000FFFF0000000059 -:106B40000000FFFF000000000000FFFF0000000049 -:106B50000000FFFF000000000000FFFF0000000039 -:106B60000000FFFF000000000000FFFF0000000029 -:106B70000000FFFF000000000000FFFF0000000019 -:106B80000000FFFF000000000000FFFF0000000009 -:106B90000000FFFF000000000000FFFF00000000F9 -:106BA0000000FFFF000000000000FFFF00000000E9 -:106BB0000000FFFF000000000000FFFF00000000D9 -:106BC0000000FFFF000000000000FFFF00000000C9 -:106BD0000000FFFF000000000000FFFF00000000B9 -:106BE0000000FFFF000000000000FFFF00000000A9 -:106BF0000000FFFF000000000000FFFF0000000099 -:106C00000000FFFF000000000000FFFF0000000088 -:106C10000000FFFF000000000000FFFF0000000078 -:106C20000000FFFF000000000000FFFF0000000068 -:106C30000000FFFF000000000000FFFF0000000058 -:106C40000000FFFF000000000000FFFF0000000048 -:106C50000000FFFF000000000000FFFF0000000038 -:106C60000000FFFF000000000000FFFF0000000028 -:106C70000000FFFF000000000000FFFF0000000018 -:106C80000000FFFF000000000000FFFF0000000008 -:106C90000000FFFF000000000000FFFF00000000F8 -:106CA0000000FFFF000000000000FFFF00000000E8 -:106CB0000000FFFF000000000000FFFF00000000D8 -:106CC0000000FFFF000000000000FFFF00000000C8 -:106CD0000000FFFF000000000000FFFF00000000B8 -:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329 -:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66 -:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB -:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44 -:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316 -:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23 -:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC -:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC -:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA -:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD -:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2 -:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5 -:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304 -:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85 -:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7 -:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45 -:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328 -:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65 -:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389 -:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43 -:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315 -:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22 -:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB -:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB -:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9 -:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC -:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1 -:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4 -:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304 -:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84 -:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386 -:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44 -:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC -:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98 -:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB -:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76 -:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B -:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55 -:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B -:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33 -:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B -:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F -:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B -:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7 -:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B -:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7 -:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB -:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77 -:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5 -:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63 -:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387 -:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41 -:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313 -:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20 -:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9 -:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9 -:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7 -:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA -:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B -:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5 -:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD -:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5 -:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3 -:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42 -:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4 -:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62 -:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367 -:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40 -:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312 -:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F -:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396 -:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C -:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6 -:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9 -:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE -:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1 -:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320 -:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81 -:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9 -:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75 -:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9 -:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95 -:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8 -:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73 -:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398 -:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52 -:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378 -:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30 -:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358 -:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C -:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338 -:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4 -:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318 -:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4 -:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8 -:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74 -:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8 -:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94 -:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7 -:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72 -:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397 -:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51 -:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377 -:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F -:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357 -:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B -:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337 -:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3 -:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317 -:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3 -:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7 -:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73 -:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7 -:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93 -:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6 -:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71 -:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396 -:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50 -:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376 -:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E -:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356 -:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A -:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336 -:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2 -:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316 -:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2 -:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6 -:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72 -:1074E000000C0000000700C000028130000B815832 -:1074F0000002021000010230000F024000010330C0 -:10750000000C0000000800C000028140000B8168F0 -:10751000000202200001024000070250000202C0E7 -:10752000001000000008010000028180000B81A80B -:107530000002026000018280000E82980008038031 -:107540000010000000010100000281100009013854 -:10755000000201C8000101E8000E01F8000002D895 -:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B -:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B -:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B -:10759000CCCCCCCCCCCCCCCC040020000000000067 -:1075A0001F8B080000000000000BFB51CFC0F00350 -:1075B0008AB7B13130ECE644F0E98159181818F86F -:1075C00099C8D7BF1168C04E20BE01C4075948D71B -:1075D0007F551AC15E26C9C0700A8827883330B427 -:1075E0004A21C4ED651818EE01F92BA16272403DE5 -:1075F00073A4C977F3281E3CB8D014951F620CA160 -:107600005F9840E82234F950A8BCB81E842E36C5D5 -:107610006EAE841E71F6A7A9A0F2BD55F0ABCFD512 -:1076200040E5C7A2A90F81F2017EE9B234D8030078 -:1076300000000000000000001F8B08000000000098 -:10764000000BED7D0B7455D5B5E8DA9FB3CFFF6421 -:10765000278470123EEEC400C1063C4280A0A83BC5 -:10766000FC1A7DD41E1025E5A11C446B004922A6FE -:10767000D78C96D76CC8870450E3E751BD457BA0F3 -:10768000D88B0E5BA3A68ABDB43D887AA9C3DB2242 -:107690005AA52D7A83FA2C58A0B1572ABD4FCB5B3F -:1076A00073AEB592BD77CEC9C74F47EF788D43769D -:1076B000D6DEEB3BFF6BCEB95634D94FF22E27E422 -:1076C0001CFCD0A7291142A6F73DC92D5932C92368 -:1076D000E41B3E823F1FF923534816210D3EF6BCA2 -:1076E0003D10D905CF2D8D84A426C2F771491221F2 -:1076F000244848899A0B2D02B1870BE15977617CA8 -:10770000323E67C23387C8848C84F218FDBD20EBFB -:10771000FB9C42FF399AA880F114F68AA8A43C96F3 -:10772000C2F6DF226446DF3C48DD57F578B86FDEED -:10773000EEA7A26B24C5EB9E837F94E5598950E6A2 -:10774000FA0D47A5C79FB7D51F4FC2B9382F95A8C7 -:10775000382FDE9E108BD8E7E7EEE7A346F2F8F36A -:10776000E3FBC32DD3B8026E6D8D3E7CB636EA24A2 -:10777000E5258436333B4BE93344CC5DA5FDDBCDB9 -:107780002312871F9F0F8C63D0FAF47F42E1DE9CA7 -:107790004B9241C0214938E0D61C5AEC33D3F42730 -:1077A0009E2497C2AD84CFB9A8FF7AFD302F0A0777 -:1077B0003FCC2B0D3C97C2BCA6F79F97BFD83DAFDF -:1077C0006A6287CF70E7159844C821C0876A128221 -:1077D00078B9CDD19FAC9B56779AFE08A70BD5E020 -:1077E000EB1B229E822572DFF8000723E0A02F6F9B -:1077F00034C7496F6EBA067820BE3A387CE20AE395 -:1078000007AB0F8FF4199A1D93803568F110E02DA6 -:107810009F30F8E557B7DE2A4F2194D53A0F4EA096 -:10782000F0CBEF5EB99040F9E8152780DF9ACBA640 -:1078300056CEA5F5B2CB63AF2CA04D423143027AB0 -:10784000DD0A9D15407F5FB32A68B909FAA365CBAD -:10785000BACAB4106EA6036E1472864ACB1EF8B56F -:10786000280DFC482F1EA473DEFEED33C1CF436C00 -:10787000F8437E5EEFA0CB8C78BF91E1CBA2FF01F5 -:10788000BE46101B5FD37EB22B35075EB25CE33C75 -:107890000ABF20BC6FFD9B8C97439EF41994CE3D8C -:1078A000A5B29EA478CA26B16CB58CE263A14A4009 -:1078B0008EE5E4EA1290C360786926A412F89F4A24 -:1078C00007B2C826E77ECEF9AB60CDEE9DAD749CC5 -:1078D00033B34331A895AFD3B94EEDBF9E3B40BE05 -:1078E000786DE5B2E74802C7EB3C5844E76595C9B7 -:1078F000B18729DD6C2D3DACDBE5E3B15EF9E2A695 -:107900000F62A833B83CA0F0514A65D31FF9ECF4DC -:10791000A17C4AFA08DFE8C4C770F1757A98F4F1DF -:1079200059C71378EDCF571B055E7D847EDF52B2B9 -:1079300078407DD51FAF4F92046D172A2566324DD2 -:10794000BBFFB4EB0BF7D326DFDD72541935A36A06 -:10795000E74078CB75AE57F4EB6F508C7747D0A2E9 -:10796000AAA37CD5B81E688FDE63114A776740F6FC -:107970005078281D17A5A04C8A49EC61D64D4AA223 -:10798000657FD44C6E413A48225EC4FCBC86EC90C4 -:10799000B36AAE530E932A4BB2CFDFDFA0E13C3483 -:1079A000182F17EC02DA2105851A2229A05B41AFB6 -:1079B000A092CE9D0F65A79DD1664C25E9F0A072DF -:1079C000BC4B92A0D76F0D4DBEB8C75BE29CEF9049 -:1079D000DB8554E33DD1268D9CEE6BA792F7047EA8 -:1079E00028102F13761DC7D3660FD92B5D48E5C12C -:1079F000986BC152209BE1D32C6A87C0932A9FCDFC -:107A000063A6EA4057648FA4C23C71488A4742F596 -:107A10001DD40B4A06F623FBEA90FE9490894FF1A1 -:107A20003DF3BCD8F8BD655FA206F0531DD58C2D83 -:107A3000748E6B15D3D80874318DC9A7EAE88479A0 -:107A4000A0EF3C129BD7B7A57C5C879AD39687762C -:107A50005906FBAE5AA52A7F2A7CDF3661207E229A -:107A6000494F4FB70D9E6E7BF06689DA835FA2BFE8 -:107A7000CC2433018E7F8A2DCE4A0D80AFF71B0FA9 -:107A8000EAEAF83E7BD0FD7DAD42EAD2C98156C913 -:107A9000C7F8D26769601F8875AF0576A720DD1625 -:107AA000DBC4D69B9B8BF05DBBE717BA6AE3BFB51F -:107AB00054CD78A7F65F8F80B7E8A7B77DF2A0A373 -:107AC000BDBB5D6F7F425E507B18E85CD041504A81 -:107AD0006C95E87B6F6CB105EA6CED63150CFF19D2 -:107AE000E6DF8BAF4F397FD16E30BAFAD3EEA656B0 -:107AF000D04FEF691D575D4CE9E8F74F28B14DF4C1 -:107B00006BF58E89F3C05E7A8FD3B7C0D389DD4D14 -:107B100079E9E823139E7E21F9711C415FD5F2F2C9 -:107B200001E96130FA7ACA4D5F9D577F21F475C82B -:107B30004D5F1C1E273BD9FAC9FD23185E38BEDCF9 -:107B4000F8C988974FDBAE3F3DFD5AA27CEDEDBCF6 -:107B50003A3D3DF1F90A7C7DD6F90E4647798669B2 -:107B6000EA74FC51D48E91407F9491588ACE53A7E9 -:107B70000FD45B31A6B7845C12ED4F4BCC4E53C98A -:107B80006BD85E21294B477BDB6967CC57E84BDA22 -:107B90004F7309497A715F64FA504F95A884E93FA1 -:107BA00033943F03EC08FEA3CC8EC1BAB3C0FE07EA -:107BB000FD359BEB5F89DA5B747DA132E7BE37E070 -:107BC000B23F14BE5FE8676F0D737FEC97F9FE3824 -:107BD0004842A88FC4FE38037FF6EE8B395C476AB3 -:107BE000C494E9BAB5839EE42609B41B41FD4C8ECA -:107BF0004A49E62F20256037AF970A62A00FE83E7A -:107C0000AF278B7E7FEF070AEA878668DD8A1658E2 -:107C1000F6B50D13BBE9B8F7349269C59EBEF1EE17 -:107C2000513B7C00EFF6E2F50EBBF6BB52A250B61C -:107C3000E91D7F549B563C0D8653DFEEA6F090293C -:107C40002081FF02A1FBA22F18003FF6BE174EF6BF -:107C5000B2D2BF9C0B364F011653B02F6DA7B63B67 -:107C6000B9188AA3A50A4A07ED1EFEDDFA4D05ECF8 -:107C700077DBFDACBC63D3AC8D169447F2FA561596 -:107C8000FB9ECFCAB76DFA4105EC0BDAB2E99AA9AF -:107C9000BE6EF324ABE269F8FB365976D85F4DC669 -:107CA00082F2FF43D7E1F79917BD40E1498112B352 -:107CB0000CD26B97150ABF41C7DD952500FFD7147D -:107CC00002F4EC3762F19B0CA43FA47B7FAE19DB7E -:107CD000424B0DF4850CF528DE1E96605FC7EC3133 -:107CE000F0E79C43FAA57C41BFAFCFD6B13ED16D42 -:107CF000F659519F3DD68B2717DEEE557BFC80B79A -:107D0000EF8DF9F01713693FD642390664F3BD0DC4 -:107D100045D92B6D787CCC37A70AF0489A73D12EC1 -:107D20008992DE1F13CA62DF5C403A2BC0781C4385 -:107D3000251FA1743A2EDE53012830AAF4E7708F74 -:107D40004BE6E9EFA15DA548E7BE34743BCA0D07D9 -:107D5000DAE3A845543E8D90483C9DDC5DA9E6A041 -:107D60003C185149D73B809FE09B549F30FB2CE14E -:107D700003FF56A67132CDF333C073934CC71D4D2C -:107D80009208A7C1E09A099EADD127B3515E7FCE7C -:107D900070CDD4DE0DCF1112E397956A39F2CB5036 -:107DA000FD3B6D7C3FD5027E38FA6CE27E38777BF6 -:107DB000BFDA416269F0EB379CFE210DF625B67201 -:107DC000BD6C307D1072FB89189EDD7A6101D70B86 -:107DD0002D51AA17983C5C087A20C8E1DF02BB7ECF -:107DE000909F6192B4E8F720F707915226FF7DF447 -:107DF0003FE0B751554E7DA00D511FBC2BC55F9084 -:107E0000910E8904F3BB5FEAB86202D04F3EB3C75C -:107E1000A337B445133638D4CB4CDF097D962C16E6 -:107E2000FA8C20FCCEE37348920E3FE8C307362C51 -:107E3000CE42BFDD8D41871C8AB62EC6FDAF8D9E1A -:107E4000D12FDAC1FDA399F0A76BC9443A7958A89C -:107E5000307918317B52E0F34342CEE32E434ED6C5 -:107E60000CFEC4B10F8B4CED39783E5DEFCE8BE448 -:107E7000D826DA4E9DADA63C14BE6AF98B55127D0C -:107E8000EE2C64F0B76611A4D390B1E08402FA58E6 -:107E9000ED467F4DA8D2BD2FB69515E8A7E77AD459 -:107EA000DF763FF500FBB8A13E9B28BCDEB6F13F74 -:107EB000855C4AA1EB50371003EC09D5A4223102AE -:107EC0004F3D0FE8453563217C765754C2F3BCD94A -:107ED000F14AD9A6075433BE05EA8FF8CA7DEDB042 -:107EE0005EF526595624C6073936789B4AA1633F6A -:107EF00097ADBBFCA589D62AD4EF8646C617F69F58 -:107F000077BDAC72B9E7A417412703C8BBCF441FA4 -:107F10006FCAC25FEDC4BF834E8AFAF02BDA85FACE -:107F2000F9AB9CF875973F6FBCFA014F141FE751EE -:107F30003C017D9E379BD123B547D17E7AC0D76166 -:107F400002BC1F2836644BEA6B175672989FF92CB7 -:107F5000DD6851BBE7FE95DB4D68975F4C6580841B -:107F6000CFB4FEA37A59C376542E542ACC6E97C050 -:107F70001E9FAF6CAB82F63B295E81DF77027F43A9 -:107F80007C20A1A11CAE97DB2B36D2BE5B8F4AB200 -:107F90000246ACBE14F1EBE7FCFE912751097EC806 -:107FA0002DFF4B26BB0CD04B03FBBD9A38BE4519A9 -:107FB000FC0D609F8CA9D3A702D833B5DB5E275791 -:107FC000A65B57B5C2F07F47DDE10E344F9F77EED9 -:107FD000473CCB4DA048D897542B36FA0E97317FAB -:107FE0000749D0F5407D4E371F150E4CAF0FBAE64E -:107FF0003F96C753DCF55E56B8BFCE60F03244FF03 -:108000001B07EE5FC0E76C9BC2E323D40043221E34 -:1080100049ECFA5BB9F15005BCA75CB709F0B55D56 -:1080200026D5CCDF1C473D14E1E3ED2CCFC1F60B88 -:10803000552647C79AFA16C0F7D866192C05F2B824 -:1080400062E0FB51CBEBF67B281EDA0B492C64E097 -:1080500010D8EF8BE335A4CBFC5CA6C7F2EB290963 -:10806000D07AF9A52469D0F6EDFB1FA8D068394273 -:108070003754600AFBCA193E7D252406A690C72204 -:1080800029997D4F424C5229EFB140951E183F036C -:10809000F75F77E69298D7E8931B82AEEE6CBEC787 -:1080A0000F7AE481E27BAE9800FEC65215FDE4E44F -:1080B000630A27E14F54205E163761BCF6596CDE27 -:1080C000F40DE253D5D9FAC7DC3F1BF9A43DFC34CB -:1080D000CEC35A4762E3B15E8C60FC860A54F05707 -:1080E0003655337BD78D8FF524F1B832DD4EAF870F -:1080F000906EDA3F51F8BEE0C58D60E78F835F690F -:10810000F9974D7FDC381CBB45C40F85DDB245EDCA -:1081100044BEB728CF815E12768CBFB813C7FDBFAF -:108120009CDE87DABFBFC4E96F75DB356E7BA65E68 -:10813000D61DF6AB7B5D1F795257C0FCB6E4537E6B -:108140004FA3077E03FA9AB6DF115DFCAB89465F49 -:108150003F7D72C8C0EFA23CE6AC86F8197A7D2A52 -:10816000F7608F6632BE1A2BE4D037285F0D107F80 -:10817000147CF511151287804FD40EA42F6296201F -:108180005F097E51BA3BDACFA7F460D4CBE0B906E1 -:10819000FE2239B45C48E93D65B38784BC504B3B53 -:1081A000E313A5FE74F7A021231ECF94317F7596AB -:1081B000D56D4293606927C6F5285DFD17D095AA55 -:1081C0002725C0EB98FB17E0BA7EA93056F7AB2CF9 -:1081D0007EEC5EC7CF397C89BE1BED793F1B8EB22A -:1081E000F87D31363F579CBDFE5703C6D9FD319708 -:1081F0009D334C3F428ECAFD08DCEF3558FBE1C68B -:10820000D795B323903E7ACB19E4ED4D2AE78BA3A3 -:10821000BB1C70E9070F65476CA0F9F9859FFE53F9 -:10822000C60550870D010E6E385EA23AFD879F3756 -:108230001CDDF1EF97B8DC1F4C1E044D33252BE0FD -:108240003F23CCBF1322DCBFE3A4F79DCD32DA215C -:10825000C1B0BC134CC9ACFA6ED4C1627C4AEF55B4 -:10826000AA8DDE47971E4A413BB73ECAA4870693B4 -:10827000B7AB7CE60D2ACAADF4FBF1BE7C03CA2580 -:1082800069F20D32E2B5EEF3C937182ABC7BFD9BCB -:108290003C7FE0867241C7C6D2DF51B8AC3EE821D0 -:1082A000E897F998AECE16575BCDF78137F07DE4AD -:1082B0008D241E818FA7885C09FC728A1C8E4CB3AA -:1082C000C993FB548DF14B9BE76DF0AF8A78F94D64 -:1082D0001DAC2CE673F3FDCEF2D7C9E23CF0EB7D8A -:1082E000FD3E0FE26BB5CBBFD6AC32FD7133A96B4F -:1082F00005BCB5784815C8B11B74A28EA0A6EBBA10 -:10830000671E9CB19296BFCBED91F7A95C366C715C -:10831000D035A1A406F87DA76BDAB59710689F6CDD -:108320002D807D5A36C17DAB1BCEABDA9CF31B6C26 -:10833000FEEEF952F2C2F9669A87BA474A6B4F3F8E -:1083400022E40DC757A6BC2A914FF50B20205ADF17 -:108350009A43D8BEF3AD60B209E535CBA71AACFDA0 -:108360002F55463F9FB6FDAB83B45FE7EB5900CC7A -:10837000D6966BC5C12F24E28235A4CE1C4D7F5505 -:10838000F72DB246135BBDE810EB150F5C2FD3BC85 -:108390004FE83E4BBEB06FFEDF9512C7D434F3BF3B -:1083A0005D49D440FF5EC083024F15F18D7E608A27 -:1083B000DF5A35D4266541BE5317EE03FD86EAA089 -:1083C000875AF805E45A09936BC112E777B77FF82B -:1083D0004355C4E153C87F188236C07E08A514F007 -:1083E000DF94AB277BEBD3F16A605D1742298E7275 -:1083F000A35E67F56B8871D7EC32E43F8C3FD4B74E -:108400009F8F71F5FA9106FA77551233B10F17DD88 -:10841000D59E9548D2A60F6BD51E0DF8AC96DA45C1 -:10842000F6F7EBA38AC34FEB7E7AA8E51C2A817D81 -:1084300092CCFC483A2DDBD6FDA70E89E7AF185940 -:108440004B06F0DFAD8F327FF00DEDE3B398DFD058 -:10845000297F4F3732BFDCBF3DF67D0DFCFCA71EE8 -:108460003D7615C07BEDBF2AC407F91B8F85490AED -:10847000EDB1A406F6D89A2EC54CA6CDAF6862F130 -:10848000CFC7C388AF354F7A930B69FB354FBF33E6 -:1084900085D0F99DDED4F3E268B09B1F95581E820B -:1084A000D53DE56AFA7E8D4A56A4F31B4CF630F9A9 -:1084B00073F2D96015F0B7B467FFF5D86FE7528F44 -:1084C000D7B6DF2EF678906F693D66973F2225C7B5 -:1084D0004BE9E6C7F23F4E3E22B1F9EDF524FD30FF -:1084E000BF3D3BB5049D47ED9E0F509ECC7DFC8764 -:1084F000118043ED5EC5A1076AF72829EF147C1EA1 -:108500008327C48DA41940279C5EBAD661BCA8A657 -:1085100073EB07E0C7A8DDEB946B142EB114C0F524 -:108520000D25B610CA4FFD4BC4A0A07AFFD0C311D1 -:10853000802BED77A59605FAC649DFD0FFD99CFEC2 -:10854000FD11D283F1BADACE76365ED7577E0F7A36 -:10855000A5D6253FDF875FF2FBDB33D7785CF6CC0F -:108560009EA1C5EBD6FEF0CC43161DF7E4937F78B1 -:10857000C8A2F3BFE5AFFFF9D0B7803F7FE6D74190 -:10858000FED73EFAEB08B1D163AD87F1E3E9B1C4A0 -:10859000A27B5472FA37DE24F84B4EFFF4F7E30C5B -:1085A000BAEED34FFC25CFA0F5EB7F3A7F14C0A1E4 -:1085B000FEC773470DB4FF067A4D7AEDF34A225E8B -:1085C0008DBD123382F6F1A70B3F07BA0E8C83796B -:1085D0009E3AE28D81DBB996BE6B980AF85A87FA0B -:1085E00018CA1B289C6B1EDBFC01C889FEF0B6462E -:1085F000CBE8AC4F8D06A77D4DD73B0B106FA40782 -:10860000F5A8BB7EED6B149F1766C6DF19F2B106A5 -:10861000F2AEF6B176365E27C55FA43FFE4EC12F9F -:10862000B3FAE3EF0E17FECE905BBE970F798D5D28 -:10863000231C7152F1EC8B0FC6B3E203C80B210F60 -:1086400006836FB5C4E6B5CC633EE801BE7A32D886 -:108650008BDF8580DF1F9E1947287D1CF7F45C0F98 -:1086600072B3E7A75E7D177DBFE6A76F209F9DFED3 -:10867000F12B9A81F9992424E5F13C31F67308E451 -:10868000700DDBCB91DADDE19437D287A79AE4A2B3 -:108690004A2382EF8FE1FB24A3FF9AE4FE25521ABE -:1086A000BCBDE1296276407224C265DDEEDF69CC93 -:1086B000BEECC3A7540EF83CB600DE67C2A758BF95 -:1086C0000EEB9F69C3EB6EC6B7EEFA35943F41EFF0 -:1086D000F5C36F527A039EA7777A55D07BA7C1FE68 -:1086E0000AF5C77B1FFC99FD33DCFDCA2B6EFE1615 -:1086F000F1630E87CCF461713B60E0F50D177E3FAE -:10870000F7180E3A12703CF9717AF97F8ACB8D1AFC -:10871000625516D8EC139F87DA27905F46E2D6E8B9 -:10872000C2BEF99E847D04A5BF938F2A18AF69ED60 -:108730003C8072DC2D2F6A48FA7DFB5F3DCC5EAC3D -:10874000D9BB7F0AC8B593CF3D8BF459F3D8310D0F -:10875000F62F2FEE794AEB2EEDE307D00F499B7EE3 -:1087600038F9A3FD53983C48BFFF0D6AACFFDA7D92 -:10877000CEFE6B1FFBC0D1FF5AAB5363790C038F46 -:10878000F3BE6A2E85F5BE7FC843409EBEDFA9A416 -:10879000F5BFF670FD28E0D4FACA82DF419CBFEC39 -:1087A00070C0003DDAB5C91C7507D86B873D04E47D -:1087B0003751CD3F7869B9EB9500C633BA0E5FAB40 -:1087C0001836FFC4332E78CE7CCD9A1BA6FDCDEC97 -:1087D0008E97C116CA2D37CA8FD27DA3DD7FF54A89 -:1087E000E52890FBCD60CF4F84F16251F07F289156 -:1087F00005952C7F50D6FD69F537EBCF138A63BE04 -:10880000A047977B7DB6488F62BFC5FD4DADA1F4F3 -:10881000FEE8059AD817D0716D7290DAAA55E9F082 -:10882000364B637648A6EF976ACCDF93E97BC52089 -:10883000ED7BF99BE3470BCBF174F39EC6FB71FB19 -:108840005733C9030FEFA74C331CEB05782FB2E564 -:10885000C58F26C98D90274A4221773C3AEEB3C78F -:10886000A3AB0EED87F873EED5FBF201FE11D2AC8F -:10887000BF87763C899D1BC08E75C79FDD7989991E -:10888000E2D1BE50CD9114E9DF5FFFF8BB897928B2 -:10889000CD63E6F90A6DF1F766BD5FFC7DBD46C7A5 -:1088A0006DC9808725DA9C7FD280BE649248F77DAF -:1088B0000BA79BCB49F7532B619E3116BF9FED82CF -:1088C000D7A51C5E3F3B9F2E9CAA9E0A62A81E0A4B -:1088D000DFB94BCC661081F397F7ACDD0F7C26E255 -:1088E000F7D644F95C70E8F01B6E5EC42ADFE27BC9 -:1088F000B521E445103D27AD5EE89B87C5F755518E -:10890000DC2779389F1D78F3661FC82D95242A0B24 -:1089100061BFC4E39A986F4FFBCB4BF98949E7AB32 -:10892000E906DADB79A9D50FDC0471757D0CC62365 -:1089300094B397A0FFD0DDAF128D59980F16322A4D -:1089400014DB38ADB92C3EA3EAF1B479C3ABB4C49F -:1089500013B05EE5EC65D8AFEC8B613D121A5ABEE0 -:10896000EC77AE8E207C7D14BE201F1164B02E9E4D -:108970003775F7D511D433FE839E9DF0DD1F6279E4 -:1089800054B7CB8118E459B9F3A82ADE6A27D05F1F -:10899000EB3109E328827E5B0BEBCE03393E401EB0 -:1089A000D54B9ACDAF9E298FCA1FBA11F3A8FC9F51 -:1089B000368FCA2A9807F6586B361179559644E7D0 -:1089C000D1CAF3A2FEA3F5A5B9A09F5AFDE2FBCB45 -:1089D000734D7BD95A7F00CB3CEF6AB4B7BD09EA2F -:1089E000E78E26759DE8CF33C93536391BF1AA08C5 -:1089F000E77FD6CC7735479E7CD4115F3AF0E666A8 -:108A00001FE86FFAAC2C02F851BA02BB3D2FD54ECD -:108A1000ECFA483C051DB5160F1CBF53CF5E847E93 -:108A20007C51F6E949D34C537FBE8FD91F827E7D9E -:108A3000B924097AC967241EB809E83937140B32FA -:108A4000BAC438595B08DD53FDD6D1567C03C6DB6A -:108A5000CEE804B95ED071FFF95FC6E75F64615C80 -:108A60002244309E96791D65B88E559A19F6DAE043 -:108A7000987B5EFABCD4BBBD6C3D2DF1E52CEFAC10 -:108A8000DA198715791AA27E504A1478411EE6B287 -:108A900038ACEC63FCD6872FAA2A6CFECD26B2DC5C -:108AA0000212509777E2D146554F62FD127FE27C69 -:108AB000AF233ED7CDE2BAAE78E27CE516C6DF83BF -:108AC000E04F9CCBD80A71B789109F8BF2F37D06DB -:108AD0008FD3992CAF28033DB5150F1C87EA688CFE -:108AE00061FBBB1ACB59BE9244B85F3BD9047402F8 -:108AF0006E0946F73F6802BE092B822F7E88E53B50 -:108B00002556BEC9FBCC5CC8373CF0E61B55AB28EC -:108B10007DB49A01E4FFC1D6A72767205E873B4E4C -:108B2000FFF5B271DBCC10EE77075BB79E62E30E08 -:108B3000751C115FEB5B9F0FC769350619A7838D05 -:108B400033F8FC199FDCB17F35E62FF828FFFBE9ED -:108B50007BDFEC1E9248D37F16E79F036F7A515E4E -:108B6000B7E5B2FC284F49C8644E4067FF9ED2BCAF -:108B70003978DEA1EC02CC9FBF637F3BCA190DC6DA -:108B8000A1553CB1D04AD62E61C239DBC83C82F136 -:108B9000674F49DE2A78DF403AE273400F97CB2CCB -:108BA0003FB9A4E426E8271BF892CEA3DCC7F69DC4 -:108BB0009E928B6F86FAFBA7BF9E68023895333A68 -:108BC0002007F31D706C358AC4B99D01F9DE53EEA0 -:108BD0008C5B109F33FF93A84B306E4EE54287D7D6 -:108BE000665752BD781FF23329B3C0DEDBFEB56B8A -:108BF00063767EFE672DFE1D565FE46B093E4F9F38 -:108C000037D79A2BF2E6123EA50CCE29F5E6532F64 -:108C1000CCB7E77FF17CEA90C8A7E6F1CC0EFA5F0B -:108C2000BAFC39F739C6CF2B9FFA292FDF0F07C9B6 -:108C300058C8A7FE8987C4529017F36B250679316F -:108C40006EFA70F7E73E07D06B8F64E0E7F7013804 -:108C500036B9979F70E1ED463FC6E7C478CF837C75 -:108C60002A1D9C4F47573BFB195BE73C9F755E8372 -:108C7000335E55681538EA9FDF56E4F83EBEE302DE -:108C8000C7F789F74F759427252F76D4FFD29E39E1 -:108C90008EF2E4CE2B1DF52FDCBBD851BE28B5CC0F -:108CA000517FDAC11B1CDFA71F5AE3F83EF3C87AD5 -:108CB000477956F7371DF51BA87902F92C7040004B -:108CC000F7ABDB46CB76FA6CCFA67A250BF3B8353B -:108CD0009ED48FF166968BDC9767E06EA7146BA627 -:108CE0004EF9573126CCD331CFF046E423A5386F67 -:108CF0008E81EF672C00BF132963E7B444FCDA537D -:108D00004C527EC8EF0BB9F0EB8A4B7B946D29C0B7 -:108D1000B376F4CB07A5487FBC7AA2EE7CC6A1C58A -:108D2000B555E3B3E507E4F9385F8CA57C817EC4D3 -:108D30008F15D8B7907961B40F6CFB1B84A3D8DF73 -:108D40005CE623CD0053C11715CB7B46BF80D5C44D -:108D5000BEC62B0F272FB9BF5EF1A2DD25E4CC6084 -:108D60007A45494E73E421B89F54FE95F9609F1EE1 -:108D70005986F2A8775FD02B1FE333E1BB478DA163 -:108D80007CEC957F7B0A1C7261A8F6995B4EDF052F -:108D9000421FCF05A597D711C80BA372E9CEABAF81 -:108DA000C23818A9278EF3807955711FE83D6A975C -:108DB0007DC567DB3F47CA997DF6F766A78660BD2C -:108DC00036F927EC5501D7118575718CEB85650255 -:108DD000FBAAA6D9B128F801DBA08A6D9FF65DDF5A -:108DE000F958BF39A4C9E02F6D3E381FE3035E7FF9 -:108DF000DC0779CE4D9E7825ACAB295BD6D3E53B1D -:108E00006DF631FF8CD6109CB67B00FAD034BAEFE9 -:108E10004FB3DE7FF131BF4BB3BEF820E8B99CB051 -:108E20006640FE44EBFE598B305F77A1AAC3BE9625 -:108E3000D04DDC3BB6B8222171F46769B932EA45FE -:108E4000AD2182E30F36DF5B7DCCCFE06DF00F38D4 -:108E50005FAF96DE4F9169BE9B61BEB983CFD70BE2 -:108E6000F39560FC108EBFC9C7F0E886BF87986D88 -:108E7000F368BD96635FEE28468A61F97AF72E9C07 -:108E80008A744A05B5837EC53E82D2EFC340BF6275 -:108E9000FF2ECEB3DEE263790902AFC460FE881113 -:108EA0000915F7BD3909B6FFED931F8C8E723C3161 -:108EB00082E7BFC6A8189704378DDD8FA1F8D9BE09 -:108EC000C77B690CF1D5FE15956C027A2BA6EB8158 -:108ED00073B90759DCA9DD13AB8A87FAC613EDDF36 -:108EE000E1FB40952CC9C27B529485D174F6672F63 -:108EF0009D73B8B9E5EC011FCFC3CA27F94CCE96D4 -:108F00002E85A34499FA71DB1B0DDCAF3CFCF329E1 -:108F10001D08CFF631F7A11D2DFC63245A3688BFFA -:108F200087C54BFBF0BCD448513CAA574C45A75FC2 -:108F30007B31C7739D2B9F97E359E057F8ED493478 -:108F400017F95AE05B017802AE94D9D181F495C249 -:108F5000F9C60DCF53FF4DE17904D600743B96AEB0 -:108F60001FF8E6C01504E3602E7E14ED04DDBBD7C8 -:108F70001FF6FFF75EBFA087CCF5ADB4FB0F11D78E -:108F80000D737AF371BDF942F9DB6D709E44CD65C6 -:108F9000FBDD7079F3AD329CC320960EFEB5B03880 -:108FA000BF53E6BC7F2450EADC7FF85CF74D78F8CD -:108FB000FEA3DFFD2ADCCE12E7F9DDF377E36BAE2B -:108FC0003F7D1E261993DEEFEA8EC789F886C88397 -:108FD00015710084035DBF67961C47F95746CC9D09 -:108FE00069E4D3323FD30B5DCFF9314F225CA5A1A9 -:108FF0003FB6A02C5501E5823A12033D71F1F143D1 -:1090000024413BBD20C0E47E41595202BF47C149C3 -:109010009617B89DC72B0BEA93D24ADB38969FE987 -:10902000AD8FDEBC1DE5E37363595EFA6D15CC7E32 -:109030003B14BDA1A302C62D67F9E461BA5F84BCED -:10904000B1F0116F12EDADB26E027E54AA05AC30D4 -:10905000FD7EBC914CBD713CE47DF9F079B251C705 -:10906000E781B1DAFECB69BDF5850103FA6D290A06 -:10907000B0F3BD611FEEF7FF9CFD75F4AB9E6E8CE7 -:1090800062FDB66F9B685734EF3F817EC3A0392DD8 -:10909000C6FCA8A642CA613E874CF0731035662C08 -:1090A00086EF077E83F5142DF11B0BEC93651AEE0A -:1090B000EF010E104F68F2B37CB9CDFEBA68363CB2 -:1090C0000BC98A4569E0BD82EB1D4A518A96D79744 -:1090D00087A495A7942CF02797914EC873F7B424D2 -:1090E0002B404F93D5BA01E38CF1252BC07F3CA6D2 -:1090F0005A8F810F5D2B67E745043E3C7E127F222D -:1091000004F552D2AD74DC89011DC7293892C4BC64 -:10911000E58FDE9C99D6FEBFFD68057EDFD65879C7 -:10912000789E8D9F4319E2951B8BE73CE0A7E3BD3A -:10913000EA67FC9AA95FF11C6ABFAF723A39F0E6A0 -:10914000C451605F3664C8A356748AA7114C3E812F -:109150003F62FD78635476C8DE0F8387F2DCB30C80 -:10916000AFA58C3E9B7E3C310BFA7DFECDA53AF837 -:10917000FBFE945B8CFB86534F7B4DB05F4EE590BE -:109180006ACCB77C7AE68BB03FFC43E3C11CD526A2 -:10919000174FFDE895191EDADFA9275F99A1227301 -:1091A000251D76ECBA73AFCE003BC19A434AEAE87C -:1091B000B356D708F45BEB63EB107972DBF3B4566C -:1091C000785E19CCC6F679A3E43BA1ACF85E1DF736 -:1091D000EE345C378B2BF0380E5D5F5308E95AA7ED -:1091E0001B1088175ADE7110CF7AD38BF4F75121F8 -:1091F0002929BC10FC820AB6EB594D92904FA1A5CB -:10920000EA803D89FFE52401BE09BEA6EF475AE387 -:10921000F7C1DDE9E7F90F3C8F70E39BB74F04F826 -:1092200008B9AECE2518CFE8F99A2F09F6E83DAA7D -:10923000F19DE560075EA7E23C6819CF1BB9F1B369 -:109240003C58E488E3E5F0F884C06B263AD9DA4864 -:1092500062C514DE3F6BF4C560FC7D8D3A967FD20B -:1092600018C5F2DE46039F4F3796E0B3AB3186DF79 -:10927000F73496E353E4F5E1D65E417B3A5E017A3A -:10928000E81AE687D30DD9847C852C95F8E0BE26B4 -:10929000FDE8BF55C17E1BE44A560EF2BD04ED73D6 -:1092A000799EDFC8FC39ED15469F7C15F2B4C943A1 -:1092B000249047D62CE66708437FB47DEE1242DE49 -:1092C000B6C9F573F49FB74BF8FAE87CB24CE77770 -:1092D00077FD884A1790D3BF1D958B58EEEB373D2D -:1092E000FC86FB047FF9DB36FADE3E9DAE9AD2D1D6 -:1092F0007689C9B13BF9F73BA6CFC8BA01CAB366B4 -:1093000064815CDF3E8B183A85E35D866C79B2FA46 -:10931000EAEF683C98376F3CD74120A7EAF59D5BA0 -:109320006CFB9831165911B7D1CB5D756AE52EB437 -:109330003312F98B2763BE31F76BEF9E678EC17EC8 -:10934000B13C21F0E23C8BEB159033979D657AA8F8 -:1093500057FF7CCCDE0BBDA771FC6F9BBD4989001C -:109360009F803C057959962073E83C4397B2F8F703 -:10937000AC775304F2FBB4187D0FF6A8C6F24D0A81 -:10938000A24909CA3FF2C7670620EF3DE7FED42E87 -:109390008AEF0FBBBC06C41BBB9EFB0BE6672853C2 -:1093A000341FF077C1BE6398B7A4C8DD1AEC789774 -:1093B0000526CF57C19E8589607C802A6A8A6725E9 -:1093C0008FAF8F3CD5322F04E7BE1227ECF5B707DD -:1093D00012B7B21D33317D51CA0F7ED1FE82168085 -:1093E000C7560F2B2F0B4C6AB1B04CEB67B37233DF -:1093F0006DBF35BB332A6743D2D4C4968397425995 -:10940000D49FD862CD26E41AAE0F48285108FCDE5E -:109410005BD669396C2BABAC4C7CEC29D6BBEEC06F -:109420005F5E1C4DE150B34FEAC410DFBE9D12AC2D -:10943000BB60EF4E94AF054982FBFE82A49484A3E7 -:109440009D7B1A0FEACDC2B926F04245C3A428BBC2 -:109450005F484B7A62B0BD9CC4EF0F1174F17490F9 -:10946000E9C74949DADE1E9776DD273289DF57835F -:10947000200579B98D9D0776D37929EFAF81585BA7 -:10948000E03C2E79CCA3637C9CFBD94F0ABB89FBC3 -:10949000736EE10E3CCF262B7001C8BF952AFA816E -:1094A000D7162637521B8AAC7DB630462D56D2E2EF -:1094B00067F4B236BB336F2AC5674BB6B3DCC4F36F -:1094C000E7A3D956369CD7ADD97BF738C8EFA92189 -:1094D0001DD77F13E6FB328B879FD83F2BEB125AA9 -:1094E0005EF7328B63ACEB7A4503FABE27C0F38E8E -:1094F000BA2EBA12D657B34D267221E34B73229D72 -:10950000AED971019CAC7B7EEB5BF3FD630979A462 -:10951000C8D4E58B08E90E9E68F151FC3FA2E9939F -:10952000803EBA833D2D405F6B67C99C9E7A5E305A -:10953000559EFF5800E35CDE027196DDCB2AAF0436 -:10954000732B4F66FC4B0912E3DA4A76B30FECF942 -:109550003FB6C8683F838B7403857BB14A0EAAF47B -:10956000B95DA3F8043E6B55511ED2F76D1EC44B76 -:1095700007DE3342DAD83D2DE3F77957829D5D5CF3 -:1095800067AE467B5B2F453FC038D2FB837912E73D -:1095900011267F27EAA442A5F566050B117FC55564 -:1095A000D7AE85764A784900F83D4F495AD8FF77BB -:1095B000991CDE2E273B7D2097234588DFED114641 -:1095C00017D63DA54817BBE53917805DD422ADDC21 -:1095D000F20BC06B76119E7B85F7EB61FD1C9F4DF6 -:1095E0007ACC07F8DBCDF1A9EC942DC8D714EFB7EE -:1095F0004A37AC06B89ED8523FDF47E19AE735DBE1 -:1096000046503C1CDF52DF129D857828F2D1EFC70F -:1096100003F52D3E8A97DD1BCD02DD569EF8099598 -:10962000EA48B4F52DE66CF09FDCB7069410FDFE19 -:1096300002F83F1EC9117CCFBE1717F5CA1113ECF3 -:10964000D226AB4FAEF8A85E28B6D59F47E5C20F2D -:109650001E5210AFFF4EC7033941D76101DDF74CF1 -:1096600052D12E08D0B904683930B908F36DE9BA7F -:109670004900EC86C92AEA7911C7D126C96837435F -:109680007DA087407E11E6CF51791D87733E4A94B5 -:10969000C5751465874979980479FEBEA42FC2FB6D -:1096A00048FC25B6BC0290BFAE3C04C5551EEFED8C -:1096B000CE97A97ECD3DBA481A47F1F25E80EF8B76 -:1096C00072E93E96BE7F3FC0FC40B7C7AD2F43BE98 -:1096D0000C31BAF3593C2A3E159EA3AE2B1E359091 -:1096E000FFA5FF7E3586F6CBBD63D4B4F960FF1AC3 -:1096F00064FE41EFD862BC57A38150FE07BE08F15B -:10970000FBF2B8FCF0707BC17D4E40C8134F365B56 -:10971000637DFBDC5139A1BE73704AC8F4813CD82B -:10972000AF4FCD027B743C9753CDA9595F05BB4524 -:10973000E5F260879F9DCBEDC9269DBB08D8BF3160 -:1097400062CF4B10F2605BA30F9F0F5F3601E39770 -:109750000F5F963707E215072E7E1FF7BF6776303B -:10976000FE3D73E805B84B899CB1A8B6311859A1E4 -:109770005F3E752FDE17F27D357E17E6CB43BE0EBA -:109780009DD25DD9CE3CCC47395CCE0578DE808752 -:109790007D17F778A867BF847EE06D7C3DBEC43C32 -:1097A000DC57821B0FCE1DFB4907DEC724E0E0BE5D -:1097B000BF433D3B85F9EB036C5F2AF297DC794AA6 -:1097C000623EFB8219EE3376E143F835041E44FB1A -:1097D0007AC91CA50F4037B5671592B4E585F49D8D -:1097E000DBD0F0FD6938EF9205F7AF243A2E29045B -:1097F0003E48A29DE80F353BEE712551B5C77EBEB0 -:1098000024E83AEFE2E617B83F18F4B4660C7CAEF1 -:10981000E57DBACD1579B998A7AE9207C0AE3D15D2 -:109820007C6B06F8E36AA998005739512D3C4F7AB2 -:109830009AEF4BD47DB7E2791E313FE18F13E59A61 -:10984000BD8BD04F57BB3B84E7796A924C0EAEF389 -:109850005907BDB23DEFD64C41BEAD672FEB6F3C13 -:10986000E080D2C7877A753EAC3FD870FE4C38672F -:109870009227D79D370EE0A3323CC07EF9C9109ED7 -:10988000D355BDB6FB53DFE2FBE365DC1E09124B8B -:1098900006782A8158376167164D95DA474AAFDC5A -:1098A0009BDC02FCB0DD656F6D0FB0726B70724BAC -:1098B0007329EA67948BCB023F437BA8C52FCACF9D -:1098C000A29CDCAEB1FB3AACA7BD06E83DDA1ECFE8 -:1098D000A75BCB4A507F2845A400E0360F1C2D2003 -:1098E000FF9EF6EE023FC38FFC896B0236B89D0ADD -:1098F0001F1907FBCA34FD598EFEC60DAF3F3A7ED5 -:1099000017E0417C9F17B91FFBA7EDD0DF41C61CB4 -:109910007A8BDABA24EF692F9E33DCE171DADBE26D -:10992000F920E7CB36D7BD1DBE44B3099B73C19F59 -:10993000EE7B9605BFAA672739F2A4C607593C5BA0 -:10994000554D7055D2EFA5EC7B80D1411BCFC7C9D7 -:109950003C4E4E86719C71BBFEE3CCE07282F07D82 -:10996000ACAAF7DECB3940FEAB3BBEE8966FBD4FED -:109970002EDFF2393DC7A5C4B3415A5E93EC5C10AB -:1099800060FC3905F87335A7D3923D773F076AFD30 -:10999000319FF967D837ACF2991704A70F9F7FBAA8 -:1099A00083623DFDE417B3CBAA999D5BDF3EED4A90 -:1099B00028D7DF51A45B69E245E2597D36E8905F24 -:1099C000F7707F51B56AA11CAB3E1BC1EF9FDF78DA -:1099D0007EC779B6FEE385F0BB18EF16977C3E7024 -:1099E000F14BDBCB291DD73FE191BDB671EA9FE07A -:1099F000E780FC545E3BF9DD047E570B496F9E22E5 -:109A0000C887BB3451565AC12E7AC42E1FCAC16EA4 -:109A1000EB6B0FF716DE15E0F5AD60FAFA4157FD76 -:109A200022D17F2ED677CF47C81F28839DA67EE2FE -:109A300015F343F975B7ECEA2F478C3F06FB13F695 -:109A4000FAB703E35F843B25EECA4E568C66FE1DD3 -:109A500003EC80EFABB180FD3EAC6F737AAD3E7B23 -:109A6000BE03DF7D709FE078FFFBC6A8235FFFE6A3 -:109A7000443D9ED3F87680D16535B5E8B1DD8ED111 -:109A80008E3CFD7FCCE3D3CEE3920CF3B8EC6F3C7D -:109A90008F42077FF6CDA3D8F1FED3CE631FF70B1D -:109AA0003FC79FF375762FC07C4342BFF57C5AD7E2 -:109AB0004F69FDCBF4E9A3CFF92AB14278CF6D927B -:109AC000DD6346CBE00FF8EA27B7BD7B39DE0B6DCF -:109AD000623E8E57E4E3F0731E9BC70C7C5F91FBE4 -:109AE000EF3BB8BF0733DCD3DA1862FBEEBB2FBC09 -:109AF0008A60FE7A28817182FDF90BA260A77FE758 -:109B0000C21A7C36E7CF88823C6A0A7FDD916F4EAD -:109B1000F70869CFC1FE91F74BCE7E59B69F47D962 -:109B20000CE751D2D41771B1CDBE3ACC03FFA2D607 -:109B3000FBE017B4DE4BC38CDE36FB1218176C8DBE -:109B40007E31F37F26C4C6B9FBC2CB089BEF6529E3 -:109B500016F7D10CFB7960F1DC1F9E118575366517 -:109B60002F88023D3767CF70AC47C9B09E5561065C -:109B7000A7CDFA17BB9EC39F793D0BD2E6C1AAB908 -:109B8000E9EF176B17788A2690CEBEA8759DFA1B51 -:109B9000AF6B14C7577588F90D361B8C8F824AFC42 -:109BA0005785D2E07C38D8DF1D21C5863C943CBC6B -:109BB000DF727865E2DF659EE44898D79146B67F0C -:109BC0007E9DDF27F5DBEAA630FAB55DE36C1EB3B8 -:109BD0002B3C909FE37F563BCFA70F26375A422C52 -:109BE0005EF3B584B3DDD2AA60DAFB4D28FCEE2A21 -:109BF0002CEC83673FFC7FCE70CB448FC3855B6BBF -:109C00007478701B8C0FAAE1929BE983C34DD05BE3 -:109C1000A67EFE7FA1B307870E2FA4AFBF15BCFEA3 -:109C20005EE9EB1980D710F8F21FF03AC7F5E6D0DD -:109C3000E025E4D81E8DDDBBE8EEE74498DDAF34C7 -:109C400051AA3B7C05C417BEA2A0BFF7F08E79EBEA -:109C5000886CAFC7F4D9E1CAB9EB30DF351EC47BDD -:109C60003C5F9363FF5E067187C5AC5DBF7972F898 -:109C7000BC14CEE67E4B6324F8115E8B5F3DE0FAA8 -:109C800048A56D5D989769BB8F4AE90FDFC3C4B8DB -:109C9000A30CFC4D0BD3CF43E033D3B8C3C5E76B64 -:109CA000F1EF0F0B9F83ADF7D970D190E485D837D2 -:109CB000E492DEBF977101C0738FCCF2398EC2ABD4 -:109CC0007CB89F8C60A5A555A376029ECA223CEF66 -:109CD0004933D6819FCC7BF5C2AD618AB7D7AEC977 -:109CE00096BC367879230CCF3396A7B70B73233CF9 -:109CF0002FB7B7BD44E03E44773D85D7BB6639BB3F -:109D0000978AA8E6D8C5B67375535CDFDDEDC74604 -:109D100022F8FD351E6F777FCFE2ED972E19B83D03 -:109D2000A963F7B950BA1B9BEE7E41C11F9DE14468 -:109D300034429FAF4B8907BF01743429C4E21E2A05 -:109D4000298478BDE8275725298DC2FD5D8F3116FE -:109D5000FCB469FA291CA89F4C7015EB11E3002B89 -:109D6000C2BD2C74FF88FBC5329390D9B04FF4C6A6 -:109D70006E65870D191DE4F0FC999975C1E446B034 -:109D8000F354BA4EDB7CBBFE6BEEFF80EF5D876564 -:109D90007D53617F380C261F1670BAC955129BFC83 -:109DA000E01F5B21A5BDDFECF208FB3B251F847B98 -:109DB000E3EA38CE84FB121EB8E7E05A9EDF44483F -:109DC00062ACFDEF8C7DC0E58ABB5DAEC2E2D1E442 -:109DD0000DC6CF7B76AD199B8E7F5EE57CFA41B8D0 -:109DE000C4919FB4247EAB07F873C9C2451E2304F7 -:109DF000DF99BCBC86CF638F96187B51A80F4E1994 -:109E0000E510874FD7914413DCEFB0A241C238521E -:109E1000E90646772B36EC97D7D1E74ECE7F8B00FD -:109E200007B6FE6EE578DDB32B300EE6BFA7D74F41 -:109E3000473BA6F3B8FE7E827EAFD591AB3683DF7B -:109E4000AB5B22FCEF32FCA412F20DBA799E480BF8 -:109E5000FDBE11E63B6F24F2F7840D1FD4837CEE28 -:109E6000D2089E97FB8F762FFE7D0B412FBD72622D -:109E7000C3478D907477AF969A0C7433B2A9EE1BDA -:109E8000E9FCE416E7FB0F43F1AC7476AE780A798F -:109E90002EEA2D560D4FBAFA57573AE59898F7081B -:109EA0006FEA54BAFB1A7AE93039B0DEFB3597E332 -:109EB00002EFBDF83E927E5FB423C2E2777B9273DD -:109EC000D6A2DEB2BC06C843311F01AF5C8BC1E92C -:109ED000DA258A43DEAE5818749D476270FDAAD712 -:109EE0007808D671EFAE9726E3DF5174E987809248 -:109EF000D0E0FBCD24E50139715C31F0F97AA3F3B0 -:109F00005EE6D749E28EE9A03F1B94B47CF50CA72E -:109F10009FD7AB565D83F36F567498FFB1E523AEC0 -:109F20002A07F952E5C17B828F35DF16BEC9B67E9E -:109F3000A1EFDCF3FA6DF5AA01F5D6D22A27DEF6F9 -:109F400068CC2EB0AE647CB89ACA9BD9485FDD77E6 -:109F5000CCA4E31F4EE65CB4855527F0F71CAFE6B2 -:109F6000BF1F971377CEA4F2E684CCFC61D63F31B5 -:109F7000B9B1E4BE780BC4794F344CFB6937ADF707 -:109F8000325FDF5B0D03EB47373D4DB8CF793FE5DF -:109F90008C234483F689FAF4FAE0FAEC2093AF6A52 -:109FA0006C1CC897EB36A4AFB709922B69BD137F21 -:109FB00055AAD3E56D7EA2333E59114FDFFE133D06 -:109FC000CCBE835E4A03E7BD59412EE7F47120A75A -:109FD0005764986F575604EBBDD372FB7510EF3B77 -:109FE0002E3BE5F30FB278FC3C8BC9E713BB9679A7 -:109FF00046029E5A251DE8E1EDECD824A0B795CD88 -:10A00000C7D08FF02D5EFFBA50FC43D04F4B8E2C43 -:10A010009E3F92E2A56B3989494666F9FF31E79F79 -:10A020005C85DD6340F5DFBBA0FF68D377D1FE50D0 -:10A03000CD715F9BCCAE6C84BCC213B2B506F3503D -:10A04000760558DE11894DB7DF2F13E0F338B17B69 -:10A0500078F8BE261E1CD08E3F4C3A6A70DCDD417B -:10A060001DE28F872B95D4E57492EFED0EE23DAFA4 -:10A070006EBEC834FE70EDC013BB8767070EB6EE28 -:10A080005856E190ECC03395F7DE59067CA4754C28 -:10A0900049277F859C7E8DFBADDCF4239EB3393E42 -:10A0A0008E27079ED7CDF73BE7735D9D733E825F9A -:10A0B0008E279B02901F4E479F6CB74BC9BCE9830C -:10A0C000E859E6FFCD34CF389FA790134079104F61 -:10A0D0005BCDE5CD5B0DF746EC7870AFFF84CCF738 -:10A0E000070FB1BCADF1F19573461A7DF4795D1699 -:10A0F00093439F375D0A3DE3EEE7EF9D0E859E1B80 -:10A100008C0E855C70B7FF00E2FC23E1EFE3E81AF8 -:10A11000C4653E8818AC4CF40570448694F373CB48 -:10A12000C41807E76E4EEC0AE0FDF6D6166F12FE75 -:10A130006EC7F15D974CB2AF6707C7FF8A25D97824 -:10A140005DCA713976C528CC2F50F0BEAED78FE4EA -:10A150002C80F2BD876490D0E4BAFA950AACEF8106 -:10A160002C9677BE62C32B680F0E97CE57D439F565 -:10A17000FF277C1DBD7696DA5306F493090EED5940 -:10A180003EB6CF892F9A0FF279D50609E5ED962CC8 -:10A1900003DFAF524D94DBA499E947E2A3F0A02A74 -:10A1A000E4182C02E0F1BFF9DF2953E39AFD7CD2D9 -:10A1B0004DDB6E9F0FF6A19B5F46EB8C8EE15E3010 -:10A1C000785E174A3C9935B24F3EBF2DD5ED1F45FD -:10A1D000AB5C9EC5ED6DCEA7623D9767B1F5513B77 -:10A1E000ED87F8F799F8FA48CC456F7247CD4F00E4 -:10A1F000FE737C681704BC54EE43DEDCF7033ACBF5 -:10A200009B637C25EC1D77FB6BD584C36E3C94551A -:10A21000E8C8C771DB21FFD017E9EBFFF96FAC2F5E -:10A2200064FDD3E98BFF0778BAC08E008000000080 -:10A230001F8B080000000000000BDD3D0B7854D59B -:10A2400099E7CE9DB9994966924932933738930080 -:10A250000625780321449E370991A0A803040C1A0F -:10A260007044D4282144C54ABFD2CD0D893120DAAB -:10A27000505DB4D67587885DB6D235586AD1D2762E -:10A28000B0828FEA365A45DA8D1A1FA5800FA2AD2B -:10A29000ABDB8FAD7BFEFF9C93B9F76626046DFBAD -:10A2A000F12D7C7ED733E7FDBFFFFFFCE7B0A22591 -:10A2B00085449D04FF7C49FF3B9C1A20C44FC8F194 -:10A2C000BFCA8DBD6E428E45DA93AF81AF4D5D90B2 -:10A2D000ED2344EF94C9A3B4DD3B473EAD81F2BD0D -:10A2E0007D36AF44CB2BD65F238769BB4C28F9A1C1 -:10A2F000DF9234287F097FE60EFFDEF0804CA2C596 -:10A30000B179AF867518CAC77A923502F3CDF14498 -:10A31000C60709D9AB109D9411F2F6E6ECC8265A8F -:10A32000AE7112DD3D8590B9696CBDBE8D9FB77A67 -:10A3300027D3F5F4FCBA8414D2F5DD7DFB8AF0A4B2 -:10A3400038F37B6D844CA3130402369245C86D7CB0 -:10A35000EFAB528906E3133ADFA386F145BFC3ADE5 -:10A360008444CFA5F5E368BFF2583FEBF8CBAEBC11 -:10A37000702CECFBF09533C75E3329D62F111C9659 -:10A3800049E17F5E0AF3B6C92AC075D73D498D3DC4 -:10A3900071E0A673B85AE7873F76BA8F25FCFF971E -:10A3A0006EACBCC34341B22965CEEC709CF90F93EF -:10A3B000F0DDD3E87CFA46369F759EC57C9EC3F5DA -:10A3C000D72E05F87FA6CB5E99C263A0414EAD8023 -:10A3D0007EF50E753C1D7F40BFD5739D619DBF4FBF -:10A3E000009FDF375EEB898B07FEBDA2DE4C076F57 -:10A3F00093C197A7C33C3BE3AFEF16581FC5DF31AE -:10A40000257CCF85747DC72F96559DAEE7B88DF618 -:10A41000037A7990F60B0CEF773DEFF7F6C691E9EA -:10A420007249AD793D4B8F249BE9D2461A7BE3EC10 -:10A4300067685D6748F72B2CFCB74B191CE3A5FD3B -:10A44000DFDE71EACDDB613F3B9211DED67132D3A4 -:10A4500065C6A7C02700AF2D499C4FBA9B9FA6FD9C -:10A46000DEBE344FDD4486F30721DD97CDA0F5FD38 -:10A470003DB6D22DB46A574F4A6324CE7A27A7330C -:10A480003AF0C97AF279B43D7983E103C80DF866F0 -:10A4900029A7376FCF0F5B882DD6EF0DA0832442FD -:10A4A0007EDBEAC4EF36AF13C7A95BB84809D079A1 -:10A4B000AEB3130DE0877FE8B8DEF30A766CA153E4 -:10A4C000BD6E63657D15E53F69F87A1EE674B92BAC -:10A4D000B27844F8D637C82678D62D34C3D74A9FE9 -:10A4E0004723B6DA78FB17F49C68BE2B1D113FE0BA -:10A4F000E908DFEF61BEDFDF37B67BA0BD759E5D8B -:10A50000919E11F9E0AA46335D9C6E9F6F7A830895 -:10A510008FE56173BF2BEACDFB5D4A5A66134A2A69 -:10A52000CB88EA806F1D6929799A82F2E8034B7023 -:10A530003DAF13520B729E9CBAB56451496CFC1727 -:10A54000393D7F5677EBA5202EDF505A4ABC71D695 -:10A55000F33A8793C0F7EB09E019E572F70DC033C2 -:10A56000D0EB32392E9EFF8BCFFB46C3C87CB4ACF8 -:10A570006E643C9FF07A113E6F34B427C33E8F89DE -:10A58000791F64F3825E33E2E3C457D45B56FE1D49 -:10A5900020FA4D48C791642FE8111F9087418F74AE -:10A5A000A4DB981C2F1E598F88EF6F855CB5B4AF64 -:10A5B000B36B0E233ECABD01849B28D72D34AFF365 -:10A5C000BD54060FCA7163431E83DCE0FA55E8BB35 -:10A5D0007B7F70FE5BA03FC7A7333CD4853E7100F4 -:10A5E0003CA87CBDC303FB7AD5E605F95A7E4473CB -:10A5F00018E137278DB53FBE7364F8CD4963EB3C56 -:10A600009D9CB5EEF7ED6FDF3905C67DFBDB9F3B0B -:10A610008CE32FFB229F443363E5ABEB252D1287A0 -:10A62000CF36789551C17D83058E577F3116C7F798 -:10A63000C9A4A537CEBEECE94E6CBF3454E9F05343 -:10A64000785EBB5152253A84239DC9DD6B85BCB32E -:10A6500007C62EA270F7B7B7DC168A33CE6C0EEFA2 -:10A660003FBB4369F1F84C7C853E17ED96D9C38E0C -:10A6700078EDAD7A7580F3B9B55DE80CE971C80E77 -:10A68000B2B41FED3AE6A6313ACC4C8A7E04F28889 -:10A690004C32DB61A79DD7D2DE3AEF651CEE89E62E -:10A6A0001776AD757C9DC33F1CA2F413B7DE83F50E -:10A6B000AF12A65FF5480AEAC3633BAFBD07CCB74C -:10A6C000EB17DC7608D4E4CBA9416CD7107AA50649 -:10A6D000D9EDD4BD9301EF9FD5DE7B4F195DDA71C3 -:10A6E00025DCEEA11D8E6F92D06EB1CEF32AD72756 -:10A6F000AF813C3D17C623CC5E9D4747CBA56097F5 -:10A70000B5352054C8B79202463BD5B7E1F356326F -:10A7100019EC87D0260FFD7DC2C64FD6835E262456 -:10A7200082FDDF75A83722BC09B373FB7BDC3BB627 -:10A73000D076AF825C80F1893A3654629013762FDE -:10A7400096478B9FDF26C0CF99CA29B1CF44F350DB -:10A75000C8E3FA1657B9BBA434B07702D7C17E0656 -:10A7600017B8BC3D14858B15ED1280CFABAFD86CFC -:10A770006D411C16ED15611F072F0BDE755E19C8A4 -:10A780001F87E6A24B5904CECB85948EAADC3A8C67 -:10A7900057F6DB858F017EEEAD4F0AC830DE9CC0D8 -:10A7A0009B322D2FBE3829007E47795FE1011F1DA6 -:10A7B0007FE942C94B68FF790BC6FB07E8FE5236BA -:10A7C000D071F26079C76AABC711F243986C066129 -:10A7D0000BA6B0582CF1B2EEDB3C8FB63FCFBFD703 -:10A7E000E6A6A09EF85DDF66271DF78EB6508E3771 -:10A7F0009DDA13E91F743967139295A5F5CD5509B4 -:10A8000071677C540BE5BD0F8AF13EEED20A08F960 -:10A81000992D1C9468FDD48CA405760A2F5F91981D -:10A820003F6FB3368BEEE7E21B1F5D4FC75FFEDD68 -:10A83000490BECB0EE06317FE90258DFD259A25C39 -:10A84000EE82B22F85F787F55650F955185BBF3D5C -:10A8500087CE9F21DACF58308FF63D5CD9526DA755 -:10A86000F3FFE8BBDAE649130999BEB0D2ABD1F2E7 -:10A870001319F50B52287EF6124AA7B4FC64C6954C -:10A880000B60FD3ED9C6C7BF6A33ACBFBC413F0FAA -:10A89000EA257DE5E65ABAEFB5CE814340AEEB3608 -:10A8A000E8CE2CFA3F2912E363A7A345CBA7B073E8 -:10A8B000ECAB8CE6E372BA19BD16444B408F0D9594 -:10A8C0008B69B9C450CE61E5BD9BC8D5F1E4ED6D8F -:10A8D000994CEEED4D8E5FAF64307B80C20DF54933 -:10A8E000DA11A2ED8EA3573E4A77E37C079389EEF7 -:10A8F000CC88F1DBE594872B285F12275BA71867CC -:10A9000098FEC8607287E89767803C5D0843D0ADC9 -:10A9100017A912FABBA42525321E688744ED4B40C7 -:10A920007FC8365CAF5F96AE5E44C7CB4A26E13D3A -:10A93000F4EBCF2458A6FDB53DEED8782F71BAAF11 -:10A94000290AED84F16AB2734BDB83B171E8BA3B3B -:10A950009C534CEBB6576440FDE2D29B2719E0397B -:10A9600089ED83D201F6A3D33C3697F2C1DEBEF364 -:10A970000AC17EFFA945EE96F72D7610DAEECA4C95 -:10A980002E5F02ACBFBF9AC99FC19B53223DC09F9F -:10A990004EB53464B03B031C1ED5772EBC1FDA3590 -:10A9A000F53948126DB77E4F653619412F367D3126 -:10A9B0009344A61ACAF6A80272A7E98B39F87BF568 -:10A9C0009D2F29C0A7304E80EE6BBD4BCB56016E3C -:10A9D000EDF1F14F1D725C47D317E9449F6AFC9D6E -:10A9E000C12936BE0FEB4FB7AFD8783289648E34A9 -:10A9F0009E82F54370B773B82BF1D7395FD02985A4 -:10AA0000B7CD405F4B39BD51E9877194FECB26F538 -:10AA100080BC8FCDBB09C7DF6BA778043BB02F3953 -:10AA2000007671B99DC9CFF2BE0CAF2EC5E843D0F8 -:10AA300085C0EBDE8C964ADCEF22C9DB131CBEAE70 -:10AA4000CBC4BAB83ECD6E08CBD718D627F8818EC6 -:10AA5000BF978F5F5681FCF32F4CFF50BE5901FC0E -:10AA60000B760BEC438D962CF60C5FFFCFA8EC8099 -:10AA70002FC52383FFA5EE08E80101B7E1F0CF3F22 -:10AA80000D3EC7627D79DF330AECB32901DF8632E0 -:10AA900053B15FF691682AF8B5BF4C677A6D6FEFD6 -:10AAA00054D74CE08B853602220CF60DF66AB9902D -:10AAB000B764D70B5576FAFB5099CADB00E06148C2 -:10AAC000FE469DCE58FBAACC5D0B3A689D2F89E2CD -:10AAD0007F12DAA14E62F027BE9DC1E4584598C4AA -:10AAE000B55B966532BB45C0FB7B1BAAC97B747FF7 -:10AAF000CFA533BEAC18D025C08BE06BAB9C7A8859 -:10AB0000E3F17BFCFB8F9753D269E4D4222EA7D8C4 -:10AB1000EF07A9990FEDB2B2A22512D589AB5E98C5 -:10AB20003A1EFC995B72E4C0FB94AF9648EA981F0A -:10AB3000D171EB9C018C93093AA923CE801BE04E86 -:10AB40008DA62F41EF2F746119FE805DF269B7C4A5 -:10AB5000E89004D2EA4A12CB21B18E5B72149C6F4A -:10AB6000D5E6F16961E3FAB89EB83C29FA2352347C -:10AB70009CCF4599AE7FAD4D36D4BB993EFBD0A35B -:10AB8000FD3483E2E15589D4E37A2CF6D26F78DC88 -:10AB9000C66A2FD5733BD20FE625F2B10D9DD3ECDB -:10ABA000AEA408615D74F053B37B09E7D7A8ADC9C3 -:10ABB0004007BFCE286076ED15B4F202CA94CE6A83 -:10ABC000ED7D831C7B1ED6837A213A0DF8F4A50C0B -:10ABD00062B2F31AE4508104766B76920A7286E2CE -:10ABE00009E170D045EC2E3AEF73F40B78AB916F1E -:10ABF0003EE0F0011D486A3B427F07F75B4914F4D1 -:10AC0000CDE57353D06E25A76E1D07F10A7F0AA309 -:10AC10005B3A8E938FE3443AE172EF376327F68015 -:10AC20007E12F253E0819C92713C517F505A54E065 -:10AC3000A5E583FE734BDB25B3FD03F650CC7E5AAE -:10AC4000BF793EB597A6D7F6466D5E902AB72FB866 -:10AC50009DB6AFA1F6938BEEE78F194C0F1E0CEA51 -:10AC6000722A8C379EEE83FE7428393CA9C51DC319 -:10AC700007B571C280BF2C857EDD8C3FE0DB99C9B2 -:10AC80009091E163DF06FECD4A65ED87E93D5EAF59 -:10AC9000490CDE5B2A999CB0B6B3F171D73AF5DA6C -:10ACA000AC42A37D1522408776C2EC2C19748F1F0D -:10ACB000F519C2ABFACE8634D09B9FF52D4D239368 -:10ACC0006272D4E1FCEDD8F7A91C899225DF017EE0 -:10ACD000555E9709D8CB7738185D2AE9616F06FD74 -:10ACE00066A6C4F79B27F2F564825F4DDBDDC3FDEA -:10ACF0001EC717E7A3BF9D9FC9E245A9397528D78D -:10AD00000196018AF73432A87B0D784CABB099FCE0 -:10AD100007C71793B1FF99DB0FA509EC873293FDA5 -:10AD200020E6B5DA116FB6E6E0FA45FF1539AFD582 -:10AD30001043FB9564E00E186FE5FA7C53BC289134 -:10AD4000FD3137531AB217F4B8EB524CBFBF49FD6F -:10AD500045DD38FF31367F6CDE14CA70B179E54CC1 -:10AD60004DCB44BF6F96F7E8F9F4E3A2BFCBA877C9 -:10AD700050FE53FDA4ED70A35EAA05B92DFC24E09E -:10AD80007F6F1AF077656DA6DFA027793FAB3C3A5D -:10AD9000C0FDEA035CDFA41D117663724092627A03 -:10ADA00067B8DEE276B1453E9ECECEA674AB1BED13 -:10ADB000806178CEFCAAF6655102FA98F00FB12FA7 -:10ADC000CB6785E512909FB512194F3FD3E799F5F0 -:10ADD000BD9EC9FC109D329CD16F59DC606ED701BD -:10ADE000EDFCF04D1995DF62D447920C728F8DD730 -:10ADF000CCE92178E2552540E57094DB43BB7CDA51 -:10AE00005D40171DC9A993414F74248F8D405C622A -:10AE1000C7FF5617EFA0EB1F7CD9A1F6C0B0FB18F7 -:10AE20009D542E5FDF6EA7BF3B7A256F1289ADD38D -:10AE3000BD41D256533EBE9FCB89261FDB4F932F79 -:10AE4000AA8CA3F3E735B17514F41E90EC0679577C -:10AE5000D0C8DAEDC87498F4CFA350A6E33C22FC26 -:10AE6000111269AB2983F69A1DCE41F27A258C0F17 -:10AE7000E7B55040507AC853D9F86E35225D3B296A -:10AE8000B6DF2EDBA249A027BAB25254D013277DD9 -:10AE9000E1C760BF4DFDD128806B7A7F9F1DEC3DDF -:10AEA000975FDB0DBF8B7D06646F1EC8D9947EB69D -:10AEB000BE6E0BDD1372175F570F93BF32799E0082 -:10AEC0005E4086D0F9B23615A39E12EDB332B8DEDD -:10AED000C822E127D0CE225D04F146701F599B267F -:10AEE000A0BD2FF01AB3AB264E01BBAA686BD4BE2F -:10AEF0008AF67BFAA1F8F1FA17399FD07D1C34EE5F -:10AF000023117F08BD26DA3912F8D582EE536AE3A1 -:10AF1000DBAB5413607DE572DF95B0EFA60E8524A0 -:10AF20004931F8BBFCA12320B7F27A7748001B2BEC -:10AF30009D7564FC50CAA7FBBCF546E29549E275D5 -:10AF4000376D90B5D5467EEE5018DD28E6F33DE12D -:10AF5000677CC2E305B3FDA163008FE67DDB14C00F -:10AF6000F38D3BDF51463AD7192DDCA446E6BF34BA -:10AF7000D53B23B0DFCAE576C4E39A0E2502F2A9D9 -:10AF800069F79EA80DECEC8D4405FE6FEADD732891 -:10AF90008FC227BF499B260762E3E5374524584FF8 -:10AFA0001625C63EF4FFA20AE86D2B7D839D0CF6A4 -:10AFB000CA2117E3FF0F2BDDBA44E1F8A123DC041B -:10AFC000ED3ECC4D51F5600CEECFED99FFBC4459F0 -:10AFD000DCF3445214BE5DB69E1C276DD7759EA24D -:10AFE000023DB9FC618F8FC229C31EDA0BFDD37DF0 -:10AFF0001EB58DF60D249129A8AF470987E916BA29 -:10B0000098BE91F1CB5C5FAAB003A7805C3AD7E70A -:10B01000117614CAAB430EB68F0EC2D6DB99A915B2 -:10B02000C07A883703E7CD6B8A4AE00758E78DD1AD -:10B03000955688ED47BDCE5E05E4FC1A2E6F2A9723 -:10B04000EF94DE33D041A98F9DCFE6EDDE21817FE5 -:10B0500048EBDB6A7CD89E2481BCD9CDCE29D6D0E2 -:10B06000FAEB0CF245EC238E9CA980F5B9FBFB9E14 -:10B070006572268AF427D66BC5E73C1FB3EF2EA274 -:10B080006602FEAEE8C5013ADEA1C2641C4FF0BD07 -:10B09000954FE7F9189DE7D5EF94209EE04B61F6B8 -:10B0A000A4589F68B7CB5755EB4338F4211CD6D62C -:10B0B000DB116F623D354A681CF865CBF878CF5CD0 -:10B0C000F1963240CBF7FDF415A4C7B5DD9286FEAC -:10B0D00042F72BCA5288DBE9FF2E439CF61266A288 -:10B0E00090ED3F7905F5CA257B59FC60EDDE3DF614 -:10B0F0006BDD313A0D9E786625D0D9DADE24E292F6 -:10B10000007F01E4532B9D523983744F7405CFB9EE -:10B11000A89CD451AE927010FC1421873B397F1348 -:10B1200037FBFD46BE6E316E4C7EBA90DE8327A69D -:10B130003CE3A4F05CAB4AAA0BF891C39B8E1F457D -:10B14000394C4821F86B627C2BFCFE99DBED71F0E9 -:10B150007C1BE0D9AA4F849E0D3E5C45E02BF06736 -:10B16000E7701FD2EF3E05D7DBE1B3333D5FC9E2A5 -:10B17000DA1D0EA6473ADA9C11E0EBE7D22F7A5E91 -:10B18000A2F2D293A144E17BD0B6AA09EA0FE6B1BC -:10B190007574D93615B7303D76870FF1974A987C8C -:10B1A00062F2E8BE1F3379D2A4BBD17F6C0AD7AD5F -:10B1B000C673099F4B857309127E5659EA89D1835C -:10B1C00015BF81270E28015A7F492FE38318DC9889 -:10B1D000BE12744BE51CE2BD33539C5F868300575F -:10B1E000EAD7B741FC41F8F5A90D21DD1318CEAF20 -:10B1F00099DCAF9FC6FD7A4785F36FEAD7AFD9F0E8 -:10B200006BF4836ECA7901BF825FA8FF68E2AB2747 -:10B2100038BEEFF731BDFA948FD1D59AB25EE4878C -:10B2200035EFB7201FB96B993C71F79BE52021776B -:10B2300073FB602B8E5393D27B910C7EF2BF4ADE60 -:10B24000769278DD37482DFF097932640FCFDF38E9 -:10B2500045ADFC720A571787016FF76B1FF3B73EB6 -:10B26000DC4511017C696F5146B2874F372E89BE8C -:10B270002601BED770587FB8BBFAC23F409C7157B9 -:10B280001AE6B37CB07BC937FF40FB7FB873AE0AC8 -:10B290007ADAD71E42FA19F4BB54882752F1592B97 -:10B2A000517A68EBFD55EA4C382F7BEC8229203728 -:10B2B000DFE57C79E2C7F20680CFA67F7B7C0ED4E7 -:10B2C000AF894899603F7EB8EB5FFF0A7AB171E7BA -:10B2D0003ACC4B6B7FEC976897DB223BD8EFBBD225 -:10B2E000D0CE3CFEC8B63900F7F6DE76AC3FF1C8EA -:10B2F0000E2C3FF36F8FFFE22F60778452556877F3 -:10B30000E2C7DBFEE92F40E775A92AECA3296C67A9 -:10B31000E7B982BEAD726BCF01E453412F9780DE57 -:10B320000538D533F923E8F95D7EDEB4AADADD0508 -:10B33000F2ECDD2D9EC6787146C5CFF002B11894AF -:10B3400063F512C6D9BA28D540BCA32B9954C0378F -:10B35000655254C9A7F35CD1B0670EDA3DFA3BD70A -:10B3600043FB25FB5C640BC6E520A84BFD0124755F -:10B37000424AA8183C4AFD663AFACE2F29DD1EA69D -:10B38000F201F58EC51F58D2F5C2FF801CAD730EB9 -:10B390001C0051287EEFE2F11BDA1EF54EF9FAF897 -:10B3A00071D254BF9BD32DD39B797B171504504E7C -:10B3B00024A9E30DF6E998232D5B203D29AFB1EFD9 -:10B3C00022D8C7C5C5D74C45BA80F81FE81FDD8D08 -:10B3D000E3AF85F825E5BF73FC3C2EE225BE19746A -:10B3E000FE1A3BF1B9E14BC86B0E94238FE2B8D43F -:10B3F000FE40BB2AF0CB2B1E057B64BB239C3B0D80 -:10B40000C6E9E27A6B275B37EDEF8573543A9E7796 -:10B41000C6141CA7CF9181FD75D67FFECE3629B606 -:10B420005E4AA963416FC178656ED0337A3DE227E9 -:10B43000A0E0BE4E40935CDCF7E4152531FEB5C6B6 -:10B440007D409EC1F9F06C7F65857F5AEC2BE2410F -:10B4500056786EE4F53FF36BF825BB324D7A2591B3 -:10B46000BDF2CC151F33FDFBB37750DE34031DC393 -:10B47000FCE1F74DFAF75A41C74FBD83747CED3EAE -:10B48000A67F9BF7952A40B71FB46AE43D6A8036D1 -:10B49000F3F3D7EDD2C0F598EFF294CB0B71BD8FDB -:10B4A000B9BE59B3F59DA3706E5AB82F17FDFC8F26 -:10B4B0009F72D5C338076D3684E7C19EF377B44BCE -:10B4C000C67532BF80DAC148AACDD44E6576F0EA9F -:10B4D0006DE0A7AD6D242AF07FB3857E9AF7BD821B -:10B4E000F422ECE0E0C38B5733FBD3A5BAC08F9BAB -:10B4F000C7EC5142ED51689F3E2FD2A6207D959614 -:10B50000037D3D73C52F3A418F37CF235E187FFBF4 -:10B5100018EDA97CDC8F4420CF65BBA3BBCA4EFBD2 -:10B520006FAF0978292429DC76A2DD4B8A15AEE7B6 -:10B5300056A3BDDC9C73958A7C6695074FB5A1DD4B -:10B54000D51C48C6F55CB24FBA85D9236EC2D62F3A -:10B55000217D5E12991981F8D9471C7E028E1F3B0E -:10B56000FA56023C3EFE0925445A7FC93C46AFE9E3 -:10B57000F37A518E3CF7D47CD4E3822E3D4F26A142 -:10B580003ECFB07B2515F5DA9224235EBB1D4C2FF0 -:10B59000A5733D53B495E1B793F353A7DFC6BF8AB4 -:10B5A00039FEE2D52783DEFD88E31FC508C8772E64 -:10B5B0004FD6AE8E223F35ED66E3F992B4D25B0DE5 -:10B5C000F4EBAB667A519C07C0F9C0A238F2E231C5 -:10B5D000BE8EE0C3ABB681BD7C31C53BA894BC62D6 -:10B5E0002E47295D00DCF21A43480717FB6E5021F5 -:10B5F0003FD59F49D05F1C6C5348BCB8CFE35C8EED -:10B60000FA3343651087F6677BD0CEF1CB953617BA -:10B61000F42B95D49E009E7BA29D37E8CF557B4CA2 -:10B62000FC1E2AB3D176C7B23C0CCF91DFD8179756 -:10B63000001F06D8B816BB6FB8DFCDECC685DDFAA3 -:10B6400064F043C4B9868043A42DB9DE283F7FC28D -:10B65000E11099C8E2A9D4BE77635CDB4BE701FF38 -:10B66000BE67E623CCBF6FC7760FFB997D5443F7C7 -:10B6700007769BBF28B49EE9538F1A0F1EB3FDC2F5 -:10B680002E5F590A7E65739D5B057EBBEF67D22AEC -:10B69000A467081682DF1D5E8D7820140FC00F246A -:10B6A000CCFCD2E69650243EBD2F42FE6B06FE93A4 -:10B6B00090DE310E4FE93DC2E89DE93FE1FF837C1A -:10B6C00034E61D0A3920E44BB3323001E858F04328 -:10B6D000F39C810900B7D1CA938F1D94FF817F2805 -:10B6E0001C807F04BF789E667CB2A52D5009F55B57 -:10B6F0006A88B7DDA08FACFE12AC13FC4E21D74F89 -:10B70000FA42C7FD1007B0453B21BF42C8E1E6A79A -:10B71000374F8897FF26E4B0D3CEE49B339212696B -:10B7200037D0179CF979A6E017F3795236C48F8F7A -:10B730009CF2BB791C7F74F91259A0CB41DEF4A4B2 -:10B74000605EBB881759C7FDD82F99E232C26F815E -:10B750007307689F93C5F827258BF3679688CF46B4 -:10B760004CF41FB085DF813CA344FA4BF4FB5BC56E -:10B77000AFC43C428F5AF12FCE4D603F8B26256ED1 -:10B78000D77D80C9272B3D4EE47C72147C0FDAEE06 -:10B790003FF839D770FCB2714878A2292FAECBB6EA -:10B7A000A7315E1C4C9C779087268E2AEFEE402BAB -:10B7B000CBAFFA0F9E674B564F34E559B9D5401BB6 -:10B7C000C451AB9CC15219E765712CCF1CF209E83A -:10B7D000E1C9FBBA8B217FC91F329F9764D7279B92 -:10B7E000CE2372C319A6727E639EA9FD989642531A -:10B7F000FD391BCE33D507F529A67251D70C53FB63 -:10B80000F1DD55A6F2B90F5C6C6A3F31B2D854DE57 -:10B81000D2D65B0F78397FD795A67E5576AFBD948B -:10B82000C2B5A47795397FCC02CFB4BFCA71E9B055 -:10B83000292B8878ADB29BF3882FD8678607A4CBD5 -:10B84000019C27133EDE9C635346CA6F9D4CEC7FE0 -:10B850001E10FD83C3E9813807D4501C3F53D0B973 -:10B86000285BCFB584FC3853FA4BB44E417F89EA4C -:10B8700013C1ED3B9CFF055C1C4370A95747828BAD -:10B88000E3747021142E9EAF0E17EB789B529A3101 -:10B890004FF8352818ECE38156F37D98657A1AD372 -:10B8A00043A125A7B1A3591C389CC4CE2BADF5FFED -:10B8B000C9E1F2218509E261947CFD16C7437F222C -:10B8C000BEDEF0C9C16C90DFB504FD666F4BDB27AF -:10B8D000A0B7AEB64709D0FF7D7C3FDB79BEE80359 -:10B8E000AD5E1CE7417E1EF9506B007F7FB8B51836 -:10B8F000BF9156157FEF69ADC0EF4E6ACFC1F70714 -:10B90000ADB5F8DDD51AC2763F6CADC7EFEED630D7 -:10B910005BD7307C9172B473429971E3A5D7E8F29A -:10B92000A8F044E482B8FA32E13872C388F9E51B22 -:10B93000FAA5C79F35F0EF5B591EDF51C86D9C4ECD -:10B94000A6C3F9E6E9FA7FDE4A1E7F76FCE8F948ED -:10B95000D013399539211E5F87795EE563DB57DDAA -:10B96000A54F4A0CAF189DC587539DF3E33C70D695 -:10B970002783CD60E82FEE9F88725D382DAEDD9075 -:10B9800097CDF46E7D123B8F5F6EE1EF6F6533FAFA -:10B99000FD5636D377BF4B2067D2793D5DA703CFE5 -:10B9A0000787F1DD3DB3E3C1F7AEEC80292FC57AFF -:10B9B0006FC53ACEEF1CDD63D4387C76BA71C4FE15 -:10B9C000ACFDAEE2FBFF663661EBFF7FC69FBFBBFF -:10B9D000CE83FE03C0CD6FD8FFEFAE4BA98F179774 -:10B9E00069CF66E7A1D43A27C10C34F575056CC55B -:10B9F000621260E7BEE3BC101F12790189E9D58E9F -:10BA0000712484A13C1CAE141F01A5888E6F1F9A5F -:10BA1000276A8779545B4CCF42AE0D31DCFF9087AB -:10BA2000D303EDAF2B98D7339007EB3B537A22F239 -:10BA300043E3473AA71BD6FF0CE5CC9AECBFAF9C7B -:10BA4000117C4E4EDD3B3E9E9EAC87B967507BEC31 -:10BA5000FE87989C39CDB8670ABF7A7900CFAF4787 -:10BA60000DBF7DBE51C5A53E77A54E26D4AFDBE008 -:10BA700064DFDB93537BE0FBB96B6C84A4527E8163 -:10BA80007552BED5AB08BBBFF596F09B5AA683BCDA -:10BA9000DD9E1B7A309B8EB34A61FEE29FB2B4EF0B -:10BAA0004339999F0B27F37361255BE98432D18A6F -:10BAB000715F17F07D75DA0263615FEF4BEA44F066 -:10BAC0005BBCB6880ADF54122D61F9799130F86BAE -:10BAD00099E72707C0DF4D9E40481FC6C75517C4CA -:10BAE000D19494C117C701FFFFD286F7A21FF7B206 -:10BAF000753EFE403E9EB350818FF26232FC4EB7DF -:10BB0000B205EC72DAFFFB52F8896CBAAFE35EA7BC -:10BB10006EA3EB9ABCF9BD8C0CFAFBE3FBABF05CBB -:10BB200021BA4BD615B8DFD0F7E1772FA1E35DD06E -:10BB3000E7C0F8F3054446F9BEC64EB6021F25829B -:10BB4000EF07DF889F07E6C8914CF95DD6FAF7B991 -:10BB50001EF82041BEF16BBC5EE4CF3844FE8C5F22 -:10BB60001B317FC661C99F71D84304CE851D43F93F -:10BB7000330D04F367E838C6FC990FAAE2AFA39F20 -:10BB8000CB73C7172909C64DC5DF3F281C799F8E87 -:10BB90002F5CA67CEC587F37FE9E287FE73301A7F9 -:10BBA00004F94B9F0CAD2F97E899C67E8CEF62F39A -:10BBB0001460BDC3920714AB67F93F1DE98C4E0EAC -:10BBC000E4787DD7D0A1AF2103789FF36AB7CF0186 -:10BBD000F1A41051F7E0FD1EBB637040F06121B489 -:10BBE000B3BF0B76B78D4A5EB0BBAFDEE07877C0EF -:10BBF00020B71669E63281F60639BC1862D8741F80 -:10BC0000C9E71563FEDFA72490E61D418E3638E5AF -:10BC100090DDB08FFE0476C4859C0EFB73E3C3AF4A -:10BC200030C766CA631ADE9FE703F07B68B77A47BE -:10BC3000969F00DF70A6717C2B1E7C587F3A38FBE4 -:10BC4000E1B00DE26A9512CBF3FF9BC33B9DE7BBCE -:10BC5000B1FB030E4BBEFAE25CEBBA59BEFAFDE94A -:10BC6000A19939D82F30C1785F60AF5D4B9942BF41 -:10BC7000FD5CEE58E1B289C3D9BAEFBD3CEF3E5945 -:10BC8000262D7B0CF0B7EEF71B398CCE45FB0E074B -:10BC90003BCF02C1E7A4726F0561726F454E21CFA1 -:10BCA0001F4FB703BE1AD8106485F7109E2F0938AE -:10BCB0000F831F87BB158E21125809F9DDA783E773 -:10BCC000865C6D450E9DF79A57921590FF2B9D83CC -:10BCD00007C1671DE8B31D1E47BFEFB8C71DDD498B -:10BCE000E03CAEF8C967E837B542657915641EDAFD -:10BCF0003F929E2F7F79FEE8ED9FCED47031F0C742 -:10BD0000FB3C3F5BE8A5CEBC131320CFFEBD8CCA25 -:10BD100029B97E8CC36B9940473F4F6274F4001D74 -:10BD20008996D7FD6222DE87BF2A37AC423B91E776 -:10BD300047B4C109909770A670A27F1C4047A783A3 -:10BD4000D39A1CC2F831353E9DF4E4B0F8DFE9F82F -:10BD500003EFA195FDFDF843C0539C6388F5A9B995 -:10BD60008C0EC557C0CD9A4FA4E6DA783B96AF78D3 -:10BD7000556E08E17C72CC27475D74EDFD4AFCF7F7 -:10BD80001D9E1CE5FE05BCFF5E72B83F39FEFA5EE3 -:10BD90004CC0C7FFA8F54DCDE5F43339FEFADE1EE1 -:10BDA00025FC4264F0ADF4BF831EA3789E0A78267A -:10BDB0001D83281FFB33E2AFF3AFA35E67D8F1F713 -:10BDC000D0B782BE897E4D239EDFE724C73DBF5F8B -:10BDD00046FD29F087ACE7F8E2BC9ECA0FDC6F9DF8 -:10BDE00073706526E07D1EDF771689A6C3F9E62FFE -:10BDF00092F03C60989EE4FC41E195920BFA64E17C -:10BE000020C635FA27C4970B29B98CEE86DA77B1AC -:10BE10007912DD43C8CC9546750F819485311E5843 -:10BE2000E97447658A875B383E94FC9B54B00F2BBE -:10BE3000735E3A02FBA4F0FF70089E86FCBE13AD51 -:10BE4000CF7BC73912CBED35F213E52D71F63321D7 -:10BE50002B3C21D7106F5CB3EB05EF3803BE4AC80B -:10BE6000808DDDA31EB499FCE46C72467EF27E17D1 -:10BE7000E397F73242A80F403F80DEE97CFAC252D6 -:10BE80004026D81990DF33E8494639DA9E37A3387F -:10BE90006080676DAEB02FE50476E3D7BB1F10B3AB -:10BEA0009B2493FD1A1BDF8EBF0BFC54BA5F8C8B57 -:10BEB0008F0959DAA500CFBF646897C1D70A3FFD43 -:10BEC000CE59E978FF00E0373736DE10FE13E0F98F -:10BED0001B595A3DC04DCD0CB0BC0191D73714BF92 -:10BEE000B07B8F3A63F01E2D5E92797C8DDA0DABBC -:10BEF00061BD4A12E747E2C67BE4C26E2116FB86AB -:10BF000014337F7745CE4BFF03F19FCE54C6B29DCD -:10BF1000FFE4423FF06AC9ABC0BEA9FDF1E6F76994 -:10BF2000FB3089BEF92DF40F859D91227F9932FA5D -:10BF3000750AFFF97479D6CF803D46D7536573E310 -:10BF400079E733747FB9546E5429EC5B399F5215ED -:10BF50001DAF4A2ED83F40D7F51939953C9B7EBF7F -:10BF600043181CD6BFF2870CF047ABEC8E1346B9D2 -:10BF7000658D7FDC956B8E7F7C4616FEE67C80CBE4 -:10BF8000AC0C84CBE4A7E6651BE32F43F10FBE8F17 -:10BF900025FA354C9E5AE49C906736277B6F84685F -:10BFA00024E0CDC2381283BB2EE1FB57B345199C68 -:10BFB000145A9EC59124417FBAEFD9FC4B56857324 -:10BFC00040CE405A0FCC47BDBF1CF8B65FA806E074 -:10BFD0003B570AD9D93A222C0F91B414407B9B735A -:10BFE0004086F945BC02579205E3887959D9C3CBFD -:10BFF0001D759FAEBC2E303CAE41DC1EB47F15BE1D -:10C00000BEE35EB76E33C43B92DCD1E398BFCABFD8 -:10C01000D6B8C7EDB2AE43FE7632E94579E9767F10 -:10C02000A40330BCC42B41F9FB52F8E7C017479575 -:10C030006E12A4BF9FFCF9E704DF65831B6245F025 -:10C0400035EB27BF7B3DE645FB43768B5E0A4BC055 -:10C0500047D9F5D6DFCDFACA49FAF1FE90140DE5BD -:10C060007C9979FA784EA2388EA38AA17EF0466632 -:10C070000F1F4E66FD0F27B37E6F71BDD49CA110BC -:10C08000CC8BC9723AC19EFFD8730CAE6C823EE96C -:10C09000027DE274688857A157D6EEBD9900DE9AFA -:10C0A000F72D4238FC5E62E7A4FA0A09F319C4BB13 -:10C0B0000FF593C8CBB4279991C7FC94A5CF8757A8 -:10C0C00034D172DD4BA4244ADB95CE0DD5C0FB2EB6 -:10C0D000ED2544DD44CBEDAEF08F7E02FB7885BDCF -:10C0E00037B68EDFABA59858B39B8EBFE3CA31EA53 -:10C0F00016D852F56027E40B0D6E265EC82F194640 -:10C10000BFA7283F507A7804CA74DDEB5687FFE555 -:10C1100036DA3EF725A2621B5E0F3E0AE04FE2745C -:10C1200001BFCFA5BFAFE37454B45F62E7FC3EF636 -:10C130000E180E0EEF7439D9FFAEDB5F79F934BA01 -:10C14000AEA2BEA948DEE3687BC883824C04D69EBB -:10C15000D8E2B51F07ED0370AECFF043F2147C3F79 -:10C160008970F937DDC2873363FC80F5A5BCBC8ECE -:10C17000EB2913DFC038D46FD7CAD9B13FF6F331FA -:10C18000FE5089F8C3F8790689FD8171AB63F3A08D -:10C190005C9EC7EB0E2E5F80F9DFD3EDD103C0EFBD -:10C1A00033F9B7947F81DF9D148E57D85B0EFAE97F -:10C1B0007ED23710B50D666908B4C37865242403B0 -:10C1C0009CCBBD9BDB617D1736BC9209F475735E19 -:10C1D00011D2DF2CA75AE4A224D25EA1AADE2278D3 -:10C1E0006F4C42B82CAD774620CF6DE9D07B3FE154 -:10C1F000E032CA3F5784257E0F3F1C6C30C46D452A -:10C20000FEDFB224EA5FC791DF37E731FD2EFAAFD8 -:10C21000E3F75344FDDA3C37CBCFCCBB68461E9ED8 -:10C22000C7B0BC68CAFFB3F3A6C5E40A9D17F356AE -:10C230009610CD01FB5AC2F957F0FF52ED56B46784 -:10C240009786CC76E9EF25866F7DB98476E215F581 -:10C2500023DBAD0BF3C4B9708117F500117A8AD1D5 -:10C260009590E78B41BF831CAEA5FADC603737DCC5 -:10C270007E2A1DFB65FF60ED97E7C4EEC3ACB3DC1F -:10C280008769E6F761D6ED6B736401BDF3FB30EBB4 -:10C29000F6BFD369CC0314701A7E1F6610F31F9784 -:10C2A000299103704F68D94D748FB4FDAFF8FD89A3 -:10C2B00067E1FEC494181D79AE7445597E9D867958 -:10C2C0007E05DE1415F252BA6C5330AFA82BD5A3FD -:10C2D0001AF378B6B4B5D4403B914F24EEBF2C4B43 -:10C2E000706EFCCD3C663F6F97585E97BEDC89F060 -:10C2F000F6CBE488F19EBFBF2884F97433F202388C -:10C30000CF761E5F80FCD3A9F41BA1661AC317EB7E -:10C310006F950F74BC0E18AFBA48C53C9AEA3496B4 -:10C320008FE6CF0C95DE3229366EDD7E96BF57172D -:10C33000FAE410CBC35D5406F04C24D7ADFA8BD28F -:10C34000DF3D408FC3F556B819E8CF51155A7E1D11 -:10C350001DF7E4CB0AE6DB918D9AE4A0ED7EFC822A -:10C3600057857B781D95A14535586FC77B8259F558 -:10C37000249A44EBCB5E527A20CFAF91742B304E8F -:10C38000A3458FDDE47E56013EBD69A72346970491 -:10C39000F213D52210784DBB87C545500E09F964BC -:10C3A000A56732CE2C874A85DCA5F281E5F73530CA -:10C3B000BD477E20417CE8A4E798CCFD6B947BD3FD -:10C3C00084B0B2C8FB69FB9F437B46C0730E9517D0 -:10C3D000E0C749F0FB64EC87652A4F8B21EF742698 -:10C3E00049467A1B6647F0F5950DAD9FD94D424EF3 -:10C3F00056561002EF2358F143E7433A17E77D7092 -:10C40000B402E70833F9FC9FDBB449D120E08B4448 -:10C410006C14CE9D520BEA1D27E481D2EF16298CB5 -:10C4200072F1A7BA2E035C2F242D4B160611EF2FA5 -:10C4300001DE6739FB52000F4715D509F5359030FD -:10C44000885F33BEE6BBEFB303BCE6E758F1A2DB7F -:10C4500001BE0B02C3F085F70BB404F8D2845C2153 -:10C4600066B91224A7D8FDE6CD876E03FFF874F6EF -:10C47000C9F7B2C247E3D1AFB05312E5E59DE4F28C -:10C4800078B47979271DCCAF984106AEDF2D0DA782 -:10C49000938F0F6E90730CF424E8F4699EA72FFD20 -:10C4A00092E7FD967950FFC5F425A383725E9A0149 -:10C4B000F465A083D9FB5C5199EEB394F79F01F426 -:10C4C0003025A62FA33677402904BCAB5DB23CDCF7 -:10C4D0004ECECA0820FEA7DA34C4FF34EA8171BB0D -:10C4E000D39D4FF75FE1EC6DB70710FFDF07FFA6A5 -:10C4F000920410FF9516BD53EDAEB3039D543BADB2 -:10C5000078D610FF35DE61BFDBBE0AFECF01FC0B23 -:10C51000BD320AFB94E27F42FE08E78D89F07F413D -:10C52000BEFB8CF23205FEAD781772608FCB5BEDEF -:10C5300086787023CB4B9EFAF2B8762867AD0DE271 -:10C540007D993DE9EAAFB0BE85D597F56932BCCF9C -:10C5500058B49ED6D3F29E60A81ACAEB3648284734 -:10C56000A7BD166E87F2B88DACBE7453CBAFE09DFD -:10C57000B3753AEBFFF4F14E7CAF22D2C9FB57768C -:10C580005743795D17EBFF478F5307BFBCFC48A4A7 -:10C590001D7E9FB895AD43D87D7339BDED919EF852 -:10C5A00015F6EB66FD6E38E44C66FE12B3E3E6F07A -:10C5B0007DCE7D88EDD3F7DEC5B5010AF7EB0675B4 -:10C5C00007CA0D5B5339CAD1047E5AA5D45D00DF7A -:10C5D000F9544E10C43BA5D34296B7DA43A75893FB -:10C5E000CFEC2691EF0979E78B0CF85A93CFFC0832 -:10C5F000D12E2B83B0FCE407D9BBB3221F357A3F81 -:10C6000091207E007B44FD9B203F757E510BEAD339 -:10C61000F9E788BCD401FB2A3A6FE9977FBA289ED4 -:10C620005F7E4B3EB3938EF13C7AF17B63246803CB -:10C63000FF640F100FBE03147D19EC963DF0BE9100 -:10C64000E11D923D4156D6F3F7DFDD459DDC1B6CC5 -:10C650002D761D94C05809DF55B9AC8F44D352874D -:10C66000AF7FBE9D4459FE045BFFF5ED4ACF1683B4 -:10C670001DBF54888F59E351AFD4713C09B9B194AF -:10C68000E38BF2F9E67CBAFE65CE16B41B9713A6CF -:10C69000D76F24118C6FDC68E1F335EE3FBF65B3D3 -:10C6A000411CCDCCCF6BE972D8F9FAE0C3BFA3F03F -:10C6B0006F7CC0E305FDBFB6D7DCAEF181978F304C -:10C6C000FBCBCCEF8D82DF23667EA70605E3F7FB6D -:10C6D000CFC3731B713FD0E51C7C4B27B1FD0EE926 -:10C6E0007D0BFFB9E0BE6031F8353696A7C8CB6246 -:10C6F000DE4FBB995ED6A95EE67E108ADC4FFB2F2B -:10C70000C17CF852A147B99C11FC5CCAF5FC303DD4 -:10C710005E6BF577EE433E99CA4B56FD2DF4B6B8E5 -:10C720008748C745FD4DF5F5CB1A5D6F9FCD1D01BF -:10C7300078C7F47604F9688A93CA6B1BE2EF00E0CD -:10C740006F1AC75B3BD7EB09FD03F7FAB8FE01F59B -:10C7500037F01C61B85F1035D9FBC3CE3112D8FF5A -:10C76000437873517B2A05FC7DC2ECE23C32AA3C43 -:10C77000112AB7DFCC1F416F2BCFB0DF0777B8305E -:10C78000BE20E2EC82FF5E2F6076F8B65CED3D9055 -:10C79000FFFD7CBE7E3E7EFFCDF3F1FCFBCF44C3AC -:10C7A000F36FC867CA8F937F01E7DF1D8678697FC3 -:10C7B0007AFC38F8275CFE941610FCFEC9AF7D0A9F -:10C7C000EB3FA6B038FBB164FE4D65E714FF3BD4E8 -:10C7D0009EC98F4CFE15EF911FCB30C7E7453B3FFD -:10C7E000FFBEDFEA0C7518E2E181FB935A408FF936 -:10C7F0008B785EFC7A46C7279F4ADF617C272E50E4 -:10C8000050595A300DDA694A2EC4679E62FAA2D98D -:10C810003EA0C0FB3E3E7F38A5C00FF79B88F604C4 -:10C820008C1318509650789FE4E7FE27F97B402739 -:10C830005DEC2BD6152858540AFD4EDE3C80726301 -:10C84000A8BC6800E542A02084F39E5C2AEA79F93E -:10C850006E5626DCAFACE47C8271E33871E2E171A4 -:10C8600061F37B37EB94F8E7D5A4C0638AF7AED8C1 -:10C87000CFE2902B9DA4339FD65FBD3F1BFD8DC69D -:10C88000547D02D0C3D78DE39E1CD387FBDA523987 -:10C8900038F6C1323C17C678D1DAFDCFA1FC5B2B4C -:10C8A000F866AF996F66178CEE3CC51A671F053F97 -:10C8B000CD2F18C10E7A12F4972386875B787E53AA -:10C8C0008DDC540D71A54F5713BC677BCB0B32D257 -:10C8D000D52D3F92F0DD0961C7ADE5704EB42FB89C -:10C8E000A71030C815B8A71030F875704FC158861A -:10C8F0007B0AC6F6704FC1580FF7148CF5704FC104 -:10C90000582E25D7B6439C6E5D17F14602ECDE82A9 -:10C91000B13FDC5B3096E1DE82B13FDC5B30963FBD -:10C92000250C6E9F3E2463FC1FEE2F18FBDFF0C228 -:10C930008FCBA3B06D17CB536B7751F8031DEA5A19 -:10C94000DF240A9FD51C3E70BFC138EE07A9173DF2 -:10C950000FF859DD77FD42F85EB0EF26D3B8A49BFF -:10C96000C9E316FA17E0783D09A5813F37850C1E0B -:10C9700082784773445261DE1B1E30CBEDA1F74C29 -:10C9800022E6DFD71043FC37383CEEBFA5C0E343B7 -:10C99000BACA2379C6784F8C1EDC6A14E0F09AACD0 -:10C9A000C6A38752726E1AC6799E97218641FE48A9 -:10C9B0005AB6CF920CE703167824E598E9C21530F1 -:10C9C000D3454AB1992E3CAA992ED22ACC7491AE65 -:10C9D0009D37227C336BCD74B2466E42BE1770AE6B -:10C9E000A07F01CE53E0854A802FDD27C48BADF0B8 -:10C9F0006DDCBFAD13ECFE3385EF9316F87E466613 -:10CA000055BB03585DE72C8FD93165CFB7E021B016 -:10CA1000357E2AE028EC081107A5FA1FEDE9985F9A -:10CA2000CFFC3D6A1F1C2CC0F303E6E7012581DC27 -:10CA3000BC8E84513E5D67B10F6E70DFA7807D3084 -:10CA40006CBFD43283F70BADFB057B8B18E25256DB -:10CA5000FB40DA2F453D9361BBFB859C0E7F89C669 -:10CA600090268D466EF47AB4FF02B9058EA2B3DC2F -:10CA700014378E6BF7897508B888F993488B9C0337 -:10CA8000F45C6CB5CFCCFEB5F0C745BC5DC4B585D4 -:10CA90003F2DFC182B9CE57382ED40FF53BDC28FE8 -:10CAA000EEBB0A7E17FEB3D56F1DBA170090857BCB -:10CAB000373C4E7FA77F9593BDCBC7F84EFCDEE990 -:10CAC0005B9C36523EE61DADE67B30741BDA88F780 -:10CAD0008A00645970EE4420A842B65E7A6800DE8F -:10CAE000DAD97AD98B83CFD2EF96921F0C6C82BAA7 -:10CAF000535FCA00D7A1783E61F78415DE4F29E85D -:10CB0000BC19F468B26A27EF1AE8C24935D5BBC52B -:10CB10007C5ED0133943F5BF319EEBFFA3BE775146 -:10CB2000F8BC3B7E847A456D8C67D759E1259EC35E -:10CB3000704DBAE838D8272E62D837EA4343598E69 -:10CB4000C10B55AB8CF7A644BD06EF977CDD7D018C -:10CB5000DEDF7518CBD157DE7718D71F617905F660 -:10CB60001081FC5BC547EB8DFA65880E2943951B48 -:10CB7000F6378A7D01D380FBC9EC1286EFBFD5BEA4 -:10CB80003A2CF88271435967F5FAF4B37C7DD1B33E -:10CB90001CBF64D1D90D3F6DD1D90D3FFD2C5F5F16 -:10CBA000F42CC72F597C76AF4F5B7C76E3573FCB95 -:10CBB000D7173DCBF14B969CDDF0D3969CDDF0D39F -:10CBC000CFF2F545CF6EFCEA6807BA2BA204DE97D8 -:10CBD0000874103518A0262BFD19FCF92295609ECB -:10CBE00006E17E4921F74BB66D6DA90717EA115D85 -:10CBF00009603C88FAF739B47E2261F58F742DC63E -:10CC0000386BDB980979F05E95BBEBA2E3707F6F20 -:10CC1000A2CEFC71EBBF1BB64833FFFB6B9757648A -:10CC20009ACAD3FACCEF575CD55864AA5F1E3EDF90 -:10CC3000F2EFE74D35FFBB64A19996F7206E26C64B -:10CC40007B918524AA427CA5F06E5B159C9BD9C183 -:10CC500067BE90FEB753C17E1AFD6BF45F0AA92729 -:10CC600034347E10E0A698C6775BEACFF41EEAFE65 -:10CC7000B1F1EFA112786432CEBD736B1E26B1DF25 -:10CC800088F13981AF3B37DBD0E5FD6C2BC1771ED6 -:10CC9000AB23011BBE83CEF1763E273DB1EF48ABFF -:10CCA000F93E7AA14EAA009F451DC406F1B5E04E9B -:10CCB000A26A04E34248278FE8F1E9E411E2AD8279 -:10CCC00077B91E8910FC77B2045DDCE908E4C1B9CC -:10CCD000DAF95D8C1E049D04804E52212FC8FAEEB5 -:10CCE00080155F644A94AEF591AD8519C67C54B247 -:10CCF0009BC1DD49FF8E84AFE29D667C0588A1FC67 -:10CD000015F0F5E9D7C497E20B45D37C10CF240189 -:10CD1000C8933A3866820DE011EC52D1FFAFA5CD31 -:10CD200000CEC12EF69E9AC093186F6B2B89CE331E -:10CD3000F87F4135AA019C6BE44955907FBEA30C56 -:10CD400043C6C3F0B383789321EEBDA3CB968C6F1B -:10CD500054EFA3782921E4BF372F4B2BA6F53D4193 -:10CD6000920CEF6CF5B4D9F0DDB29EA7A47AF3BBB8 -:10CD7000CAD1245B0EEE23C956815F3BFB6AFC4B94 -:10CD8000ECAC3E2A4379ECC661EF7EC8509F5E6BE7 -:10CD9000F97703892641FBE473581E679A667ECFB4 -:10CDA000C651619607148C7D39E5106FE1F4CEDF32 -:10CDB000498DD490C826BAEE73B8DCB1D251FA1DB1 -:10CDC0008B9198DAC67C03E5594F9B82F077707996 -:10CDD000453632BAD0E95FA0A7740B1D7954331DD4 -:10CDE00039E402CCC3157C25D623E66F1B93956CE2 -:10CDF000C775D9F13D6C87554E58D6E7866020C57A -:10CE00009DDB4722115AEFD0197F10B91F7F774C55 -:10CE1000272433F815D6F935E553E89CBF8D7CF20D -:10CE2000F031EF9CC6F6F999CADEB5AEEE60F4EECD -:10CE3000D9CAE81D6E74B37C2D6D61AEE15C752FAF -:10CE4000975356B879FAB46AA0E78BE49734C88F41 -:10CE5000B8FB3546FF6D630E3F0FE5AD7733F8073E -:10CE60005586674A2F6A942EFDEE3BDC98173CB539 -:10CE70008CE20BF0FF92599E4CEB33C3B1C82237C2 -:10CE80008209E06AE5D74470FD96806B39856BD1E5 -:10CE900099C355D1997C4E9FC5DE593C384661FFF8 -:10CEA0003EAFCEE098AEA9287F2F924F45D368BB06 -:10CEB0006D1A9537749DB51A83B7779690E36678A7 -:10CEC0000AF922E05FC8E1EF55BD2FC0BFF3E2D6FB -:10CED000ED2420017CFF5B033BA27B9A9037830407 -:10CEE000F096A631BA1570EE9ECDE05CA871387749 -:10CEF00071B8494402385BE9D52A9FD3BE269C7796 -:10CF00009DC3E3F159A4FCABC0795B0A7B47D931DF -:10CF10008EC1D5E11E8C829CED0ADA715F07820A10 -:10CF2000D67795B0FAFB5356E680BEEDF277E60071 -:10CF30005DB605AFCF01F9EECAE1728668EEDCF2AC -:10CF4000D8BD831A792BBE43DA1950103F9E407C1E -:10CF5000F995362BECC47926D9898C7078488D07E1 -:10CF6000076799629297F98D66F8A658E0EBFA9AEE -:10CF7000F2E1B5AF291FEE216CFD778E17EF347407 -:10CF80003B513F55DC8471F34C3ED7E685DF65BFEE -:10CF900073BD66F8BDB610E489DBAE023C13ADBBD1 -:10CFA000A795F0F75A9CFCFD16F6AECB3678D785E0 -:10CFB00096BF03EFBA2401FDB3775DB6C0BB2EF474 -:10CFC000DB05EFBA9C0BF6B4865FF9D2427C7FF0AA -:10CFD000B35A82F1F14D297F25F1E055D465D67F12 -:10CFE000413DD9F20E9B59CF65CCCB3395BDB3CC27 -:10CFF000EFB67954F66EDBFF0164680340008000F1 -:10D00000000000001F8B080000000000000BDD7D09 -:10D010000B7854C5D9F09C3D6737BBC966B3B9924C -:10D0200040124E42081B0861810483829E84406343 -:10D030004D71435151A88D40314248285E1A7FF509 -:10D04000C94282841834A0585A2F2C378BB56AB441 -:10D0500051A922DD2052FAD5964551F152BFF55221 -:10D060002F40258A177C3E5BFF79DF99D93DE76425 -:10D0700013C0E2FFF8FDF1C1C99C993367E6BDBF5B -:10D08000EFBC332184906FE8BF04CF0412F410FC8E -:10D0900081BA433D9704EDD1FA23C3EB1C6A3A21D0 -:10D0A0005677A5E139F1F7115F22562D248390546C -:10D0B000DE365DBED71E2E26644DCDAC24520CFD4F -:10D0C000B450266D4F80469590D5566F968F3E4F43 -:10D0D000A85954435C84AC6A2124388A90F6163BE4 -:10D0E000962B726CDE601A2177BE2C7BE3E82B3620 -:10D0F000CDA7B969FFDE9C5B09A1CFD7B80919920A -:10D10000479FBB9711924F88423F20D1BA5233E3D9 -:10D110002352425F98B3849049D1F9ACA9B1788386 -:10D12000A584C4253BBDF07D52ACBC13A66D6EFA40 -:10D13000DF37F4FD6FE0E782681947583BAE13BE56 -:10D14000A3EAEA04BE676C6F7E537A74AFAE7DAC1F -:10D150009A98F63E2CF61C72CE37322DE579497539 -:10D160004E5A96A71092D5FF7B5FB69047F78E4434 -:10D170008012920E653D01782A7CCCD5C9B3ECC4EF -:10D180001985B378BECACDE01B27D1CAE4FEE3B649 -:10D19000015CE3A2758510AD1BF0915D1AB3BF2849 -:10D1A0002906082923A4B32578F03D6BF4B9730A46 -:10D1B0007DDFD9BFFF4C55C679CF55552C9D4A9080 -:10D1C000B869BF442F7D5F0717A77666DFA73FA525 -:10D1D0006974BD2E4E37E477920278B5F37A8254A3 -:10D1E00037572D037CF9081941FB956BA4AE987D48 -:10D1F0004F13EF49502AE41D41DF79AC74D3760612 -:10D20000522869BBDDD8AE6620BC705C25FABEF63C -:10D210008D34F0BCBFAB12F0F8CEC841DA6DDE7AC7 -:10D22000E0A77ECF558B80635F1A859BCCD71B030D -:10D230008E6DC0DF028EB293C1B14DCADB19A6FC60 -:10D2400066D55C5E8A115291A676035FB6694EE49C -:10D25000CBB6B4EE5025AD9F28B57861A8C49195A2 -:10D26000C88F6D43F71D5E08709DB9FFC36D08350B -:10D270002D5425E04BDB133DD5A12A9DBC11F88A26 -:10D28000E7BF778C7D20BC9296A917CF236E4A2AE0 -:10D29000CE21362253BC384656D9EB9C51FCD8E0FF -:10D2A00017FA3C3E6DC64732E5FB78AF0E8FF0EFC4 -:10D2B0001B564778D0C5DBB26FFDB904449119E91C -:10D2C0007700E6A3A8BEE8FCC8D9C717C94E43BE7D -:10D2D000278A3713E4657F7AF733BEE7FD06E60B4E -:10D2E000D66FBA5C93791585CB9A17987C241E2645 -:10D2F000176C7686CF354463EDD98A97BE41D664E4 -:10D30000AE44F9D1AECE6F07F9F979A685C8123CC3 -:10D310005F6F07F9A198E447BACF62D00743E6C42C -:10D320001BE4FE9A825928CF069A67569DF1FD614B -:10D33000F5C6F77396A518EAE23D6BE6452F55A5AD -:10D3400046EBAB943A3BC8915B33D74B753AFA1E28 -:10D350005254F73AD0ABA8DB3267E27B7139A53182 -:10D36000E7B5CFA3BD0572A25D65F326EED870BE0A -:10D370008BEBA1BBB91E3AD53A37F2FEBFE6FDEF03 -:10D380006D716319C167C13506BCACCEA2F29A8E2D -:10D3900007B0D77FFF29B5EE73985F14CF96287C2E -:10D3A00080698B175B805FC5386D59F90EC0DBFA59 -:10D3B000EAC1E727F4AAE867557CC44BDFB312A3A0 -:10D3C0001CB7A5590CF89890C7E5C6B66B0CDFDD05 -:10D3D0009B3C63631EA5ABF587648274F73BE3FA5D -:10D3E000FAD3AB711DEB33D9FA07A66FD3BAA944B0 -:10D3F00088D011D6534CF5A1A6FEF9A6F6D1A6F613 -:10D4000009A6FAB9A6FE95A6FA0F4DFD6799EA5747 -:10D4100098FACF37B52F36B52F37D5FF8FB17F2983 -:10D42000C3F3F5E2D920F205F4BAB9BFA268885F68 -:10D43000A1E7237CE536F2E30F722AB43C66671855 -:10D44000F02BE8F374F1B39ACAB810F093A23A50F3 -:10D4500099962F267A7A589F998FFAA38D4E0BF5BD -:10D4600037B75F52041D5773FB70CE12031DF5E6EC -:10D47000143AC07E24CE34944BA7A20B89A418DBA7 -:10D48000B5A1D1F67CF8FFD9A58B53D37180EBDD24 -:10D49000C1E72DE4C023C37DD7223E02D49E1E1BCC -:10D4A00085931AB1A7E9C728DF6D49238138AAEF10 -:10D4B000B6F82D58FF3C937E08EC952AC687237852 -:10D4C0007F42C2128C23E6D3CEE9651DC8295ADEFD -:10D4D00001728A96B7B56462B97AAD256B218C5713 -:10D4E00063433CA58EBBD5AF4059595E04FAFBB6E9 -:10D4F000B13B340BAD279E94497022B5174AAE2834 -:10D5000087E5244C9F9FB9173EF735FDCE24E04EAA -:10D510008246C6E62A12B08E2364ED9EAC1F7AE8DE -:10D52000B86A81E275405BB177859286FDFCE03692 -:10D53000A84ADFFE11B43EBCC082F685B5BCAF057B -:10D54000EC7731EFB53FA4844B3BE6557B2D7E0A4B -:10D550008215C3EB7E05701ADE492C1AADAB7E55E1 -:10D5600002B9F6469E8AF276EB1F28438E800FF5AD -:10D5700065819EFD62AD6D25CC73603C11D952FE74 -:10D58000ED4B310EDA9943F1B906F4AC2A484274F6 -:10D59000951F76C13C9D32AB3F9777CCB7B2385AD6 -:10D5A0007F2CEF987B256DEF9C986B8175E4A5B976 -:10D5B000B4400CBA3A0CF218D6B776D170BD1E340E -:10D5C000976A0D1D77082D8B7909B4760EC09F9749 -:10D5D0002A7F9EC9EA0738DCD466DE9EC6CAB3FD40 -:10D5E0001DF3F8AFE5B9855D3A94FB8FC5CE8C414C -:10D5F000EDD3C37965FDED532AE886029D6FB27ABB -:10D60000875AE8D89BD6DA889FF2D4A61C827EA2DD -:10D610007F8D2DB01DF84351875EAAB3BB026B32DC -:10D62000AED0E8FB0189CCD1CBC97B399CEFCA973E -:10D63000707ED3E5637E99D2EF263F413B6B137139 -:10D640003BC01E89E0DBFFB90FE990E3BB2ABF6A4C -:10D650001DD02959C8F4667E549EAD50E8389B61B0 -:10D660001C5ADFDC6EC1F96DDA45F9977EEAF39B4F -:10D67000DFB180DD3C96042DB0BE312480A5872C1F -:10D68000B30050BAB91EDFC6F9B790F237FA3B20A3 -:10D69000FA68FBA5C3EBBE06BE48222AD655BF1BBF -:10D6A000E9A9715772652CFBC0966FE17E26A957D8 -:10D6B00026713F87C1D9965FD61FFE56B20CE17E18 -:10D6C00093C767CF07FF6EE7C1E030DAF4C4AB461B -:10D6D000BA05A8CCD2C99D1CFE9D24AF4F93E93852 -:10D6E0007B72EB92E1FDC6FA4FF665C0D07E3FBE7D -:10D6F0003F39DF8DFDAE08764F8761C679C395400F -:10D700000B63AB7BF700C98CD136839B413CE53F73 -:10D71000DF93AAC23CEA86C23885A17005908FB318 -:10D72000FE603003E773BE05E86204CC87D3472D63 -:10D73000D2978A7422F00DF4504BEB573430F850E6 -:10D740008310DB89E236CC7FCB2A4A27CEFE749247 -:10D750009ACFEC236F148EC43AB87FE5CD8F41BFCA -:10D76000022EB37ABC560817F87EE75E053ED0CC91 -:10D7700040DF5E077DDE9E5B770EACB374A3AF1512 -:10D78000E8CFB92BE4877E024ECE29214DC27EDA46 -:10D79000B9D06FD3CD9595A817BA08FA4B427F9AA6 -:10D7A000F16F9D62B4F708E9C2F58CEC32DAE994C6 -:10D7B0008E519FF7A3E39B23741CAF8F4B08FD137F -:10D7C000E8B4C47BC0CFA0FE078E35801C7980EB07 -:10D7D0002541D7E27901891D67B8323FE2CF66CA99 -:10D7E00083C3FBCAFC18FEAC0BF86304F2CB7CC00D -:10D7F000879BF461FBF09B8DFCD2B8F3937DC3E86B -:10D80000FC9DA5EA04C08FF87E03C737A5E3C54891 -:10D81000C71BFBF6815E1B7E33A3E36BC1D6488F2B -:10D82000D2E34D1E6D297C47D099793D4BF87ADAC9 -:10D83000737DD7C278576CEC7EDE81EFF9AE473E40 -:10D84000DB180A3A4814BEC3397CE36E89E0D90D6F -:10D85000F263568DF779D0CF3E8F7B3A9433D5BEA5 -:10D8600036302DE6D6CB06BBCF8C5F4A5FAD485F26 -:10D87000C4374D92C09AEDB6A2FE1C806EA27AD338 -:10D880002FE8FEE653C8ED3B62E1E174C73F99EB38 -:10D89000BB1BDE4FA9F611E4D3D39DD769F61371F4 -:10D8A000B3A81D1BB0EBED5841F71DEDB3D04F16DB -:10D8B0007810CF57B5CFAACE033A772ADE58FE4F5D -:10D8C00044DF703ABF9FD3F97A6E7F7571FBEBF638 -:10D8D0001615E57B678B07CB8E162F8F879663B95E -:10D8E000AA45C37EF29A4F2BD07FBF99605C6B65CF -:10D8F0004289148BAEF2FC467B7F78B311EFA9D539 -:10D9000046FF3B596F2FD37F49E5F986F644EF6810 -:10D9100043FB69C48B0F00DDDBD22A0DFD48F813F1 -:10D92000837D2BE0385D9E87F1620A4FB4AB853D65 -:10D930002BDA09A9C378AED5E467769AECD80E80C5 -:10D9400023C297C1B10BE088F02DE7F0AC667E13DF -:10D95000F77BE285DF53B47ECE7C8C8B1094572B03 -:10D96000726CA89F3BF298BDDD8F7E3275F293F208 -:10D97000FCEA354C9F0B7BFCF99C57AAC1AEDD92AB -:10D98000694139B9256D8F672BD6E3BD4C9FFABB32 -:10D990003C147F560F8F57538ACDA2EB4DE47CB3D6 -:10D9A000DA4A30FEDD91EEF4421C2CD1B3A806FB1E -:10D9B00099BE4BC8CF89DEFF23EFD51BEC0EA25CCE -:10D9C00063586764FEA536368E44241827A5D866AA -:10D9D000C09F9DE8EA79305F5B148F79B05E8E2737 -:10D9E000939D23E214663CB96B8CFA6675117BBF7C -:10D9F00037E701C4BB19BEAE2A23FD7670BA684B67 -:10DA0000DF827C68EE6F1E9F4C8937F87F1D9EC1B8 -:10DA1000E324C29F16FDC08F76C7E86FF6A3CF86BA -:10DA2000BFEEC6EF19F55D0C7F7DD2085D3C49C0A5 -:10DA30003B8207115FE47E98885B8BF114C2C6C3FA -:10DA40003AC6B7FD28FF7E99E0423FB2C0690B801D -:10DA50002C2CA0F3003A6EFB55426025ADAF4B98DD -:10DA6000D99744EB05DB6415DB9DBEA11067EEDDA5 -:10DA7000306368987EF71EA9EEA211BA38DCB6E4CE -:10DA80001B32993DA0BC13F600934BE8E7FAD74D43 -:10DA90000C69608F1711EF76025E306B17F444F457 -:10DAA00075B97FFDB3114CEF66CE25CBBA63E07F2D -:10DAB0000D6F8FCA715F3CCA6B2EC70B38BCB6772F -:10DAC000CD8AD7CB71DDF3A4587475B6E4771BC843 -:10DAD000EF51F09D1735D4DBA584CBEF47C8F75144 -:10DAE0007E2FCBAB5B3DA22CC67E9F1246F93D51EB -:10DAF000D5DA01EFE9E0EF015E7E4AF112631DCF56 -:10DB00008E60F6CDF7152F42AF6EEF7A9CE1A558E7 -:10DB1000E0E57612CBFFFD1EE0E569807B3FBD4A64 -:10DB2000C2B80FFB45B6F60CB43FA56ABB007F1127 -:10DB3000FC5C169B6FFEF91DE3E77EEEB7AEE7F8DF -:10DB4000E9E2F1F1DB397E3AB9BEEEE0F869E7FAD5 -:10DB5000FA56C04FDC99F3CDF066237E52ABE34D0D -:10DB6000F830E227A9DC889F44AF113F099ED126F7 -:10DB70007C18F1935EA022FCE2328D78EAC737A7C9 -:10DB8000F057D2609C187672765DA802F6B886CE01 -:10DB9000E9EEB5C220BEAE0A28C57AEF35F9A5A2D6 -:10DBA0004C2F6078CD9C161BEF16DE1EC8D7A40242 -:10DBB0003D9DFC20361FDB79FF63AA1667E87F5185 -:10DBC000ECFE2EDEFFF5E15AA2BE3FFDB94B1EC4AE -:10DBD0005F30AF3F41D2D20B701DEACE30C5FDB6EB -:10DBE000156C1F729B43ED86FD7CFF0AA777BB8AED -:10DBF00023F9ECE01FF171883F09C7CDE59F19EECD -:10DC0000DCFF15ECFBE52DC81E7A356DCF5B9E79E8 -:10DC1000A48E96A30B46E03CF3EBBD7B00CEB26B2B -:10DC2000CE50B67F3CCFFDFE184A6AC154E91B7046 -:10DC3000B8DDB1F7ED4529F42995836807D2890449 -:10DC4000B6533A8D5388929802EBD5705D56B06307 -:10DC500065586F17D6E34937964E1262FBD7DC1F23 -:10DC60003DAF200FC7731337FAAB29C48BA5E06310 -:10DC70007B1A51D227E0F86D7113082AFCF3C05FBC -:10DC800075666FEE009F46A3509884AC82F090EECC -:10DC9000DA87EB271EA2B278DBCD6ECC4FF8335D6E -:10DCA000DF98D35FDFE9F6FBD2E12A21498434DB38 -:10DCB00059F98B78D71628BF74E4062068A58DA87B -:10DCC000FB31E0D55F49D0FEF0BF951068C5C92E85 -:10DCD0003B87F907A73DCEBCB334CECFCED2388D2B -:10DCE00005E9A71EE736F87532EC63FA9643FFB6EE -:10DCF000E44968778AD20CD77D1EED06989F627F33 -:10DD000029F7BDD4A8DDE67C5342BBAD4D0A12888D -:10DD100053FADF96D0BE22C50C4F4E9578F2C64519 -:10DD2000C7717A970D67F12E16EF59F1F75F8C02E4 -:10DD3000FBFB970933C349F4FDAD07A99D0779346F -:10DD4000D3BCAFD7537A4A4FB579B750FA49E57E7D -:10DD500072DCDA4907EAE9AF9F8C62FCBDA365BFBC -:10DD6000BB8D0AA444C57BE104FA9E93EFDF12B990 -:10DD7000260C7663E22445853D8E2239580DF32525 -:10DD80004D16027C714F83713FB7B3B008E122EAB0 -:10DD9000C3F87E2E2955FA227936D48EDF58C0F387 -:10DDA0006A5CC40576A1F26F2D2956DE8328C5FC76 -:10DDB0004AD3A8DE4A82B820E5145A96760631F98D -:10DDC000A3D21BB4831DBB2140FC360AA707E7FB87 -:10DDD000AE81F13ACB7D0960976F3834EBA2B17414 -:10DDE000DEA1B0E205100447A5E0BA439ABC368133 -:10DDF0003EDFF9A6C50DEBDBCADFEFF449C8FFF73C -:10DE0000CC23013F85C7D6863D7619ECDE90858C04 -:10DE1000443B973A5C93B82854215ECBF8FE965168 -:10DE2000E9F8B027B43C19E0B22EE1FC9046C7AF48 -:10DE3000AD6671E71972F6F3306EA8D386F849E73C -:10DE4000F94712A945FB39659ECE5EA6FF123B99A4 -:10DE50005F19BA8E60DE535299D3EBA7DF7B22CCD9 -:10DE6000F68DEEA96671671709E2F767C8BB1C1645 -:10DE7000FABCA75A71033D2599EC73278C4749AE2C -:10DE800067231BCF359E8D9768CA83B28B79B9E91A -:10DE9000BC28FEE44405F1ECAE36E64FB94CEF3950 -:10DEA0004DDF7B59E0399B14029E4FF86E98F812B3 -:10DEB000B67AD558F9139D2D2454A5CBB7700E1002 -:10DEC0003FFCB290F909B6ACBD7698D709DF2B6953 -:10DED00010EE7AE15FFBDEBB03CA7FFF574F135D95 -:10DEE000D75FBF3ABCED518063F36D2F221D72BF27 -:10DEF0006A084C81CEE7F95A1BC2B14C63F101525A -:10DF0000DABBD75A8AEDB8AFB5768F03DB87959326 -:10DF10008083C27398A265FD0CF835247B57A83026 -:10DF200088E6CC9A44D85615ADAFBD92120E950F27 -:10DF3000E9F334D95F0CF190174822C5F7064D522A -:10DF400059FE9BF43CF0534E95847E58CE219F039E -:10DF5000E8E1C46C0BE6BFACA8BDF4C29174FCFB55 -:10DF60002A148C375457555C0EEDC30E317A715D0F -:10DF7000C7F047E114ACA2FC30E2108B279492B0BA -:10DF80003748DB877989350DF4C73C0A60985F27ED -:10DF9000C70F8F0F949686FC00D444AF118F6E1379 -:10DFA0001ECD78758DA47804FD52448A985FC7EC25 -:10DFB000C75ADE6743D544F45FEF5189DF3AAE3F7D -:10DFC000BE5EA4F6A346EDBF10B51FA1FC1BB51F96 -:10DFD000A1ECA1F62394895AC545A574BEA1743A53 -:10DFE0002EF05F4DD94AD81FB86FEAD537FD93960A -:10DFF000657C9F8D726A4A25FDCE2CE062565FAF2C -:10E00000519BE4A552D9505F9BA6887D3C3FE8D444 -:10E01000C42C0BDFE79971A746EB9D990ADFD76304 -:10E02000F511C5C450EFA9B118EAE7EDD18D3F0550 -:10E03000F01387F5092377AEF71744DBEF28A475B3 -:10E04000DA7E80DB73B54B2DBE2D31E877D948469B -:10E05000BFCABF895FA2F8FAAC80A09F2E5B349440 -:10E06000DFA4505141BEF6D7CB540EEAFDEB022A95 -:10E070005775F191C3853CAEEEAB60713612FDF978 -:10E080007A12CFB322F0BC330476C4ADAF5EE90D93 -:10E090009281E5AE355339A2A7938B051D8C2423BD -:10E0A000D19F27530E54009D754D54801E4A391F31 -:10E0B000106EC761889FD2CF539FDEFD174D053F7D -:10E0C000ADDDDD3612F37E2E1FA9CB935995BE68C8 -:10E0D00022E83391F7434895FB7DBA2EC97FA90505 -:10E0E000ECB681ED1485BCAF83476FED8C24D00373 -:10E0F0004E2EC7CDFD57B5EC7C05BEBFBAA51B4B58 -:10E10000679A0F858C5DF163FC669FA7AE11E6658B -:10E11000CFA6ED3A396C4BA3EF19FC806C667709FA -:10E120003CB809C683C4BEC986CE09F17114189DD6 -:10E13000545F807CDE109A8579159DDE0983C6AF19 -:10E140004EC5275BAB5E2269148E4FBE3AF32FB3E8 -:10E15000697910F88DEAC12738DFE4943FF6DAB523 -:10E16000067E396AE297A3267E397A0A7EB9E04EA6 -:10E1700068EFC9540CF51CE0175D7D6B845F583D5A -:10E18000CA2F47915FEE79D986F58D238F1AF865EE -:10E190004521AD67EBF865BAECDB12C30E78E53BC1 -:10E1A000E2975F9F29BFBC7166FCF2C4D9E3973F39 -:10E1B0008E4CFFEEF8C5779AFCE2EBCF2F87605EBE -:10E1C00067CA2F9DEE20E60376CEB6540762E0FBC9 -:10E1D0007A8E6F11F72EE3718A69F3B4CBC7823D53 -:10E1E000CBF3D6443E4DE73CA6BF57D4CE407DB9D5 -:10E1F000F520D397423F97713CFE8DC731CA424C00 -:10E200006FA6974BF8FE4C4D0AA8F4D74E6A12A49D -:10E2100082BE9E22912E1596BAAC76A414B59BE8C8 -:10E22000F7D06EBACFCBF266C92166EFD8E97F404E -:10E230004F17975B0D7A7588D9FE32D5C53EA6D8A3 -:10E24000BFBC0FF212283CBE1EC9ED2693BE15704E -:10E25000D870A812ED90CFB36D83EE5775F2F546E6 -:10E26000ECA9525F45AC78587DA184F0BEC9A3C526 -:10E270001796813EBE0AF5AED0E766BDDC53F59237 -:10E2800051CEF8C7A75616EBE48C7F3CEACD889CAC -:10E29000E1F501E50C3907E546442FF37A442FF305 -:10E2A0007A442FF37A44CEC0F8D951BD3CF281F1C3 -:10E2B00077FA757A7B19D4B34FAD9717707970B62A -:10E2C000E5CC1FB8BDFA5DE9E5CA424E2FFFB99C07 -:10E2D000A929FC0EE54C2DC899A453CB995A90332B -:10E2E000C506397355E1B7D0CB890DBD7ED8BFBF08 -:10E2F0006200BA77707C371568D7C0F8A4E6F4F2EC -:10E30000B6CD74D55BFBC0AA0CA0172FF3F3067A29 -:10E310003FB1F9F7AFB4E9F2A21395103B5FD1FC1E -:10E32000243E9FDB7010E365A79A6F7D21C1D2ACBC -:10E33000477B6BF7D9916EBD16DC13FFB6F3E89CF3 -:10E34000CDF8F28DED4FAF073EBA8FC7FDCC76AE5C -:10E35000C0EBE9DA3FE6EF5E3F52C571CDDF3F1516 -:10E36000DD523ADD0C747A22FBBA31E0E7C98977D5 -:10E370002500BCBE07FAF0C96F43A7AF8C64F83C18 -:10E380008D750761FCEF6ADDFF017FBEFC6DD6BDB8 -:10E39000A090D1D569ACFBBFBF4B7CFF07FEC26725 -:10E3A000DF66DDCB04BE093B2FE3865F289FACFF11 -:10E3B00057E1DB10BF58FFEFD18FC13ABBBEB26F40 -:10E3C00086F805F9FA1BD9AD3F3F45D8B99944FE07 -:10E3D0005EA28F9D877157EBCE4791E879295C0F3C -:10E3E000C63722ED07629D97FBAE4BB047DEB10EFC -:10E3F000D26E63713BF3F3FF2E90D83936A9D60164 -:10E4000079F1BDB3F760BE41E7EC09B86F65B6536B -:10E41000C47B3D2D1AC6933A5B7C58DEDE521D82CA -:10E42000B8C9932FBD25413E58E94B0DA8DFD64E04 -:10E43000FAE130CCE39B5A1A0FF5DB4D768A8BDB81 -:10E4400029DE51AFDFA9F75F9EFC4D13CA4111874A -:10E45000BA2362BFD0F7549D9F44EB400E113F0991 -:10E46000EA063F69D97AB05F7AC07EA1FDA78E5ACD -:10E47000B63ED677D65A483DD82F6B1B2CD5B1EC7B -:10E480009770416CFB85D671DFCD91680FACCC03E2 -:10E490007B86D4E9E36AA7B25F1E1EF5DDFA495711 -:10E4A0008C3A3B7E52846FB9DD32A4485B0821D997 -:10E4B000B32527869DA69C18D65F4EDC38EA5BF80C -:10E4C00049E102965F2DE86BABEAC578726735C10A -:10E4D000F8636768656A09AD3FD1602112AD5FFFDF -:10E4E000328B0B6F2827013847BB219B603DE465C9 -:10E4F00074304376FE08E2E03D55D47F52216EF73A -:10E50000E35A80EDBA8499B73928BDD4962B04FC20 -:10E51000A619F214FC4E4863F9A1B54EF2A338F0E7 -:10E52000ABA62A64E519C4AD13E562897224E54FF0 -:10E530003519F876A078B439FE4CE417BC802F73F7 -:10E540001CFA4CE3CFDB055D7DFBF833F2DF970F60 -:10E5500034CD8278EEA9E871C12815F599594F9903 -:10E56000F958D0D340F4E7043B69A2AECECFE186A0 -:10E57000F93EB513ECA48951BAE8AD9D94142BFF74 -:10E580004A9409CD7F78457F1E2F41E9C6F1129A42 -:10E5900077E1F3BB206F00D6A778519E3E5849E53E -:10E5A000708CF9ED6E597608E4E7AE96662C2F5024 -:10E5B000FAE414DAFFE916FF2180DBCE96762C9F71 -:10E5C0006CE9C2F69E968D58DED112C0726DCB0EEC -:10E5D0002C6F6BE9C6F2C17CF69D294A10C7B9E0E1 -:10E5E000241D5F474753FBE87774F83EEF43BFA114 -:10E5F0007D72B8DDD07ECEE12E43BD2CB4D1D0DF0C -:10E600003D2560686F2AA83B067CE92ADD6178EE2B -:10E610002CEE36BC77BA7EC1D9EE976B7F04B6C9B3 -:10E6200049329CBBA0AFC8706E88F2F190662A5E3A -:10E6300069FDFE441EE7E866FBE49924F283740951 -:10E64000A964601FF426B23CC8D62CF67EEB8DACD4 -:10E650007E7F0EDB3F12799AB23D42D744CA88EEE4 -:10E66000E7DF9FC8CF2915B0BCC8DCE200442448CE -:10E670002E24A8C17E4829DB2713FBDEAD3CEE70BB -:10E68000BF95EC94A83DD9AAB0F9B76A24B082F638 -:10E690006B2D66F57BAA48C002F3D7A814CFD0ED46 -:10E6A0007337EFFB4A2A89EE9793D11AEED7C87CCD -:10E6B0009F3DB2EFED7897E0BE3E87D7CA848F3199 -:10E6C0008F36B9B94F02FE1AD2DCD70BF3BBFF1657 -:10E6D0009B1ACB1FEABDE58B2CE09B4D377E910545 -:10E6E000CCBE29923FD3E7D0E7CFE472B86C6ACEB4 -:10E6F000C7FC854DF52E2F87B3C5D48EF90C9FD757 -:10E70000F3FB0988827ED1307714AE01913F22431A -:10E71000DE1D5DFF88E8F9D3FF34BF6653F37296C0 -:10E720005F934D787ECD4CF427051E364139AEFF00 -:10E73000B9DEEF3ABFE6947935A63C0703FD42DD2A -:10E740006FA66F15F112C7E95BBA99E5456499E8C0 -:10E7500046E45D08BA14F919225F43E46FD8785E85 -:10E7600007FD2CCF6B8E4D5FB63DC403E7DE644BD7 -:10E77000BC774BDEA9F3089A3DF95C392C1BC7C660 -:10E7800065F903FF334AFB85A72C3A6E9E47BB51C0 -:10E790005F17E556F875321DC21BAE027BB5A85C4B -:10E7A0006B85F37C29A504CFE994964B58161D621E -:10E7B000F5DB3C327EAFCDC3E24DA27EB1A63D0774 -:10E7C000EF2799DEBB38F29E15FBFDDE63E1A5C2A3 -:10E7D000E6CDF3906772FA5E3D5966F9D155129312 -:10E7E0001BB0A13A89EB430ABF8B89FB92025DDC27 -:10E7F000F5C71C5BB7B7B0FC3E910FFDB79765CC72 -:10E80000877696FBA6C1D9B3B2502808FBEBA5DBEF -:10E81000883B4585F98535E0C7153977EF817C88D8 -:10E82000272E647BB6171F62F6C28FCBAFC6FB469E -:10E830005C5FCB188F754F49F406E0433556A6FF51 -:10E84000453E74B9D15EA835D90B179FE2FE8F14EF -:10E85000D2E7073DF988C7148FE5F7800C24BFA3E2 -:10E86000F78030F950CAC77496BB1D10BF2E3A64AA -:10E87000C1E39EF2364DC6F3B19D2CCFE389906F74 -:10E88000D0F3A82F723886B89CF81BCF93ECE172B6 -:10E89000E2752E270E839CA0E52B3C4FF210CF9300 -:10E8A000349F97D8D152FD92DEDE319745927F1684 -:10E8B000E6416D56089EBF1BE0BE8FA2001DC790AB -:10E8C000C7B802E9676FF2DD15401CEB350BDA952E -:10E8D0005D5348562CFFAEEBC2CA41F30F3B5BE6DB -:10E8E000BCD43688DFE8B4517F26D6FB1E71AEABB0 -:10E8F0000BCF5BA4955B08E45565D9FBD8FE43AF0D -:10E9000003E97988D78EFBFB649E93BCABCB53B9EC -:10E91000DDD7350BE6FFE03605CFE7887113BD7410 -:10E920003E3A3A499BB22713E6DF39359809F64C4F -:10E93000D7F87D1B0B205FE4A04C800CCCF3B21603 -:10E94000717F96AF2B4DD1A45879EA03ADEB038FBD -:10E9500064B867C20CFF01ED0EC80818FCBC95B383 -:10E960002846FEE269CC13EDDB6F765C3B1BCF4D96 -:10E970009EE6FD17099C0EB3161207FADD408F8341 -:10E98000E0D9650D21DED62EB454C73A5F5B54C47E -:10E99000F0BDB6F453B48B4971EC7924959BE9959D -:10E9A000CDE70E858E4FDFEB2A8D3DFEE51C6F9483 -:10E9B000AE5F0379D5556D41BB22092E62C0FC1CA8 -:10E9C0006A074948EF28973E2BB5313BC1242FFAFF -:10E9D0007DBF54474FF9FDE5D0F9454E437CFF44D8 -:10E9E000F6ECA4600C3C8B52C051C8A1FE70247898 -:10E9F000FEB58BC39114C7E6EB28BE56887855DD6B -:10EA000029CEEBCD2E2A8B714E6C003C98E9E18E1D -:10EA1000853E5C1779EE35A282BE2CA5FCA88B43FF -:10EA20000C043F33BC167EC7F032B7FFA888C74737 -:10EA30004E739DA7DD8FDA456E9D5D0C87A2155A3A -:10EA40009FCAEB3FF64BE17BA85C9576FD09ED9EF6 -:10EA5000A9BCFC3194543FEE9282EFBE415F9E22EE -:10EA6000A93980B4594F8F820819B9555A66B07FB9 -:10EA70003A24EFE167302ED4970AFDA6933A852118 -:10EA80003980EBFA93146E05857529D15641D94822 -:10EA9000BA6CF05E63CF9F0EC3771A7B1C4119825C -:10EAA000933BADC7F471A36BF4E747F2E0168D6EAC -:10EAB0005B1E9DCF921DC67DD20612C2F196761BBB -:10EAC0009F9BCF8F4832050C5C4E10C97F9D82F909 -:10EAD000BDC4C1DAE3478BF3E87D85FAFBCCEA39A4 -:10EAE000BCEAEDCE20DC2F4402C6798A7B739EA758 -:10EAF00072CC3E01CFC33C0C74FC91DBEEB7507B73 -:10EB00003923A5AE11E07115516DAC647683589729 -:10EB1000B887668173B60DE0BBA0DDBC0ECD06F3F1 -:10EB2000F959D7E0EB1378FF4711C175DC5EA46299 -:10EB3000B934BE66BF06CDA5A15CFD7D104D5C3F1E -:10EB40009065A906FE7D51D023D1E4D3597F7FB8CB -:10EB500016609C4CC075603A35C6C976C121D77421 -:10EB600084DFCB7AF811A5AE04C615EBF96759E836 -:10EB70008120ECAB26B27BA0DE4DA97B03FAE71C1B -:10EB80000EBF2FD1A913A75A08EBFC78E747AFC8EF -:10EB9000F9D1F51112BE1BF2A3EB77CAEE0E58CFD6 -:10EBA000CEE70E03BD0FB42E911F4BE901E146E7FE -:10EBB000F521E837F3BC8EDE407E0A76C974B9D8F9 -:10EBC00010477986C3F19E62DFC7F05EE94BD92E0C -:10EBD000BC7F27BF7BDF503A8FBEEB25CCAB4D937C -:10EBE0004915C04FE4237CEA54D0CF4E4BF0CB2ED6 -:10EBF0005AEFBB8A78B7C034BCCBBC402A724EB146 -:10EC0000B783D24DC6F5B20FE4C9DFAF5B90BC80CD -:10EC10009619890B9347D0F28238E277D0F13224EB -:10EC20008BAF1B8350F3932FA1F3FC491C9D27ADA1 -:10EC3000E7DD90101C41F9ED8F3662077A4D4BA845 -:10EC40005B371DBE932CE37C8E503B51A172ACE22E -:10EC5000F2CF26DAE9F7867EED9C00F3C96A9E467C -:10EC6000DEA5A03C5CC4F8E4E8C35F4E8473E0F228 -:10EC7000374E2F9E33E7F4973682C1C38CEFDD1CED -:10EC80001E6FC6337FA731DD762BC4DB3FE6FE0F58 -:10EC9000D13CE82F5CC7FD8537E3991FF466A18856 -:10ECA0002F05D3F5F66DA3434BBA0C9C076A274199 -:10ECB000BEF3676E2D2919FA111FF2ED75DC6FFE98 -:10ECC00098906AA0F3EBD64C1B9242DF4F6F6570B1 -:10ECD00030CF6FEC68A69F1B4E5282D6C5CF1A94D8 -:10ECE000A00DE477C3499BE1F9DFA91DEDD79D573E -:10ECF000FFC98787A6C3FCAE24E155D0FFCAEB123B -:10ED000058E09EF36B0F9FC74070694C568842E1F4 -:10ED1000D12811DF60FD9EF9B71C13BEB34733FB4A -:10ED2000257D5AECF55DC4D7376D75CD2F81CE1A90 -:10ED30004356B4E5AFFB43C590C1ECE7C693E791FA -:10ED4000802EFED7A884111E8D27CFC7E7D3561F6C -:10ED5000B301DDC3382A7D7E9D431B02F1DA81E0D9 -:10ED6000BC9BDB418D2793893F55FF9CF17774FC59 -:10ED7000346CFF2D87DB6FF75BAA63E577358F6611 -:10ED800070199DAEF8201F684C90689B637C57F407 -:10ED9000CB4831EE5F98E7D55319BE12E67D4E158C -:10EDA000D1627D6F3187A3986F4F4A78910FE9B395 -:10EDB000AF10EE9988D4DD7DB9FA7B24B672FCF5EC -:10EDC000FC309C0BE37F7C61EC733B02CF9394653A -:10EDD000682FBF9052F734C8B77997D10AA58F2111 -:10EDE000F38216763EC53F28BEA370964960E26066 -:10EDF00070B661BB18EFA317393F523F1CF2D4AF76 -:10EE0000E2F2FFAA6D4B30EF49C8A98F36CA28A796 -:10EE10003E42DD42CB8084F6EBFC3A0A6B2A571661 -:10EE20006D9FB60FD4C15599D4064D61CF6F86B290 -:10EE3000CD6A88F78BEF2D38CCECB7859D463D57D2 -:10EE40004F3A3F01FBE0A317993CA0FC6D0379BC4E -:10EE5000E82EE338F5DB2EFA00E6576FF2CB33B835 -:10EE60007E36DB799B47F3F8FE2432E94CFCF24610 -:10EE7000A2ED188D7AC127C33CCA14E33D5BA24CB6 -:10EE80002F61F05FBEFD84CDA50E3CEE112A470A2E -:10EE9000E8B8C7A83F0EE51F476BBF1F4DF170FCD8 -:10EEA0002083CB81D1754FC1F78E1F64EBFFB4E196 -:10EEB000D345704F0C99C3EC8638387C407F8D9BCE -:10EEC0006B0FB4D2F5AEA662CA01E782E2983D228A -:10EED000EC3059BE5676D1F6C9FF58980CEB4C7BF6 -:10EEE000E807D5305EFA43091AC0ADA3421B0FF202 -:10EEF000BEA3D6E985F32A9B291996D3F7ED741C96 -:10EF0000D02781DF4EDE03DB9105DDEB2AE1DE1742 -:10EF1000F7AEDEE030BAAE760BBB27A3FD7CE26D28 -:10EF200025D1EF35EDAA7D0CE6953B9BEA0709CE8E -:10EF3000D16BE3DDBAF109B7AF1A394E8E3F3BEA28 -:10EF40008EF3E05CC27E19CDC74F1BF2D1AF1F4DCF -:10EF5000183D89FC7BF836D891027EC7A8BE22BA3C -:10EF60003CB5D1DD52D04AD7B5B4E731BC8FA361EF -:10EF70006530632EE8DB0715A647F9FCD2FE9855ED -:10EF8000A9BAA2FA77AEE4463B52D8C99713F15317 -:10EF90008CF1C2399C0F2EE7F6F1DC0406E7F9C4C8 -:10EFA0009B0BEF5D61272E0B85D9DC69DD65CB40BE -:10EFB000EF2EB126837D036B898577519AED20C1B1 -:10EFC000878D0F24FA21EEFAB1D45708831CB13291 -:10EFD0003EEB7B362EB025AFFF38D631CCAF6F2C51 -:10EFE000E4765D01D1E0FC40E3EE51781E2C2E9ECC -:10EFF000E27102CA3F3BE0F579D0FF74DDD73CE314 -:10F0000008E2B930715F999BF813E9779A760FD9C6 -:10F01000027646DA086DFC723ADEC7D6702ECA0B4D -:10F020002ADF24AA5B73C7ACB944A17CD53894DA33 -:10F030005DB47ED14377B37A7E789185D6AF7DE893 -:10F04000D14B144A9F8DA3C3EF43FD96879E66F56F -:10F0500009E14532AD6F7C683FEB0F7BD894B0B6C9 -:10F060003F74E012F0FF8F2433FB8178C35702FD19 -:10F07000343E3DCAD2A15BEFBA314C3E1E71B07E28 -:10F0800047F2C84F6701BC3DE1C259BA7DB9EBC731 -:10F09000083B96D971629DE23D92197BFCB1639861 -:10F0A0001EBD661AEB7741026977B0F3757EB0C773 -:10F0B000F6EE1A8570491993C2E145C7298D8E2352 -:10F0C000E028C613DF5D0C7A1DE4BE95CA7D9D9CC9 -:10F0D0003997E38D7EA70DBF53AC8D877BAC1A6744 -:10F0E000658F07BC517C291C5F8A1D2F57DBCCE63E -:10F0F00047C74D2E413D3311E2CA7BBFA6FDF3A2A7 -:10F10000F336D3C78C314C1E5DD3CACEF7F7258FAB -:10F11000403ABA2081D98BA494C28FCAB38D1C6E99 -:10F12000EBC624333F32828721128EDFCAE197CDAE -:10F13000FA9FE97AE7F0799CEDF5EAF0A4417C6565 -:10F14000EFCE22C4D3C6081DAC338C736485E9BDF1 -:10F1500072CA78308F9411F8DE6A07B1E373B22572 -:10F16000F25E1E7DEF82697D13811F96727B98F897 -:10F17000CFC7BC86062E2D96B6876C10975EDACD6B -:10F18000E2E4A480AE0FE863564D295F9F9BAFCFAA -:10F19000CDD61730D02739D4973B3BB13FDD46E081 -:10F1A0001E19AF78021FCFC0CFB1C603BE18081F0B -:10F1B0001D671B1F629E267846E06C9A9F8027F091 -:10F1C00031BE576CE42731CF5BC644E2B1467ECEF8 -:10F1D000FB96DFAB60EF2DBD91E211EC1FD548CF60 -:10F1E0004B7BF22CF38BA3EFB577AFF0819C4F9064 -:10F1F000541607EFA9F583FE6BDA558171AAA54F66 -:10F200003DFCA49FBEBFF8D10D2E48AEFA48E9CA16 -:10F21000003BB861FB2A17DC33F7A1E27781FCFCE5 -:10F220002820C7CC5B7F9BCB01617735727D73E46F -:10F23000B7B7CD04787CB1DD8AE70C9B76C405E3D3 -:10F24000306E720DDA63B4FE36ABAFFE04FCD8A6A6 -:10F250009D46FB69F16F3664A8484FFE6116DC04D9 -:10F260000B0E83CDB0C66D56DC4F693C247BE9673D -:10F270004813E9BB15E6677E1FE67192E2BDA95B04 -:10F28000BE0AF2FBCCED5492A03DD6D4731BDA69D2 -:10F290004D3D177E00764593299FA27E003BECC52D -:10F2A00031DC0EE3F7A40BF890403ADA37AD0FFEED -:10F2B000B2E46D3AAF63DBFEE2928AF57A7325E23F -:10F2C000E9D3EE059B9E5607D6AF1F837D10A77F1F -:10F2D0008FE157DD29B18DA15DAC6CB0065D101FCB -:10F2E00068D86CF5520D4C1A1EDEFAC0AFC1BF7C57 -:10F2F0002DCE0BA9A64B1E7EFE9573697DC963D6E4 -:10F30000B41A367D27EC730B3C41CE06D829022F68 -:10F310008B7FFFBC0DE290F01CEC5E819F258FF58A -:10F32000DAE09C9F198ED3BA7B6D980F6BC653F7AA -:10F33000DB33C004697DF04B1BD0F747BB25BCF71E -:10F34000DEFC7EFDE6E75D40870027F04305BE2238 -:10F35000F8EB87B7E0CCA74BB11FC6434E85BFC7BC -:10F3600001476548E78F3C0D7194D7E3BC0087FAED -:10F3700047AE75C17A3E5096317ABF6F5506DC971D -:10F38000576FF567B8B164CFEBEFBF1EE9F0EA83C2 -:10F39000D767B07B24B42C768FA63F0BD6F9B37B0E -:10F3A0002FC1752E22754887F5F7B1F8C6E70AA96F -:10F3B0007E2C06BFCC2D66FCF2C19638480E221F6B -:10F3C000C03E02EC9BBC28E3B9FB7EF72291E558D6 -:10F3D000FF9CC717C61547EEEDB3837DD7C47B35B9 -:10F3E0006D5B1D023C1DC9D186403C9FC2C1CFE16F -:10F3F00026C1BDEFF2C1E943189E880AFB21F81E21 -:10F40000B5C7A7C173E81FB26A8E12C37BFC7E1B0F -:10F41000F67D11DFA0F38E87FDF40F32585E9E79E2 -:10F420007D1DC5421E9010D1D3D940FCBF6D0DD2B9 -:10F43000D7678718FF34066AABB13D640D0E81F6BD -:10F4400040EF6C09E5439C61FF3C421FDBAC9CBF75 -:10F450008DED749E8AA487EF6E09EFD314F4B2E8A1 -:10F46000AE38C37E7D947E8CF745097E157ED6D559 -:10F470005C1E98D76D960F97169BFE8EC2BDE9A7AE -:10F4800015FF6EB0061EF835F033E55FBF0AFC6C61 -:10F49000C5F8C0D1DF3DF7CA1594EE8F760B3E3626 -:10F4A000CA5B331FD73F5E4662F1F151A797C4E4B0 -:10F4B00063FA3C261F3BD9B9E9FF57F2F6EA01E4AB -:10F4C000ADBFD8286F3F27C549E711D0334BF0BEF9 -:10F4D00057337C85DF6B96A399C56A4C394A7F0EFA -:10F4E000111D3C051C057D2E7E68297E2742C782A2 -:10F4F0004E051D47E8D4BC6E233CCDED5530775DFD -:10F50000FE837525F563C0CE7D560E6CA1533B4E30 -:10F51000E7722B85FFF1DFE561BED12AEE071C778C -:10F52000F7B9207F6C15F73BFA202E99147DDEE7A2 -:10F5300060F6D2715F9F2B596737BDBD4B76819DB9 -:10F54000170E90EA58F1242AB1711E6132503BDB4C -:10F55000173BCEE3A1C779BC73BAECCC6D8638708B -:10F5600017BBD77FE18ACB5CB02F707CD7883B80FC -:10F57000FF7EF66799DDEBE9D714C89358C0404089 -:10F580003E24FEBBA7D0752ED8B504F31BCC7194D6 -:10F5900045CE6DB8BFF039B9194B73FC6431C4590D -:10F5A00080DEEF353DDF7511D2D762137DD5017D49 -:10F5B00065F5A7AF1704BF8E27E3F5E7CF9673B9BC -:10F5C000375D2EBE03EC99E3D4CFC75C02B9F800D7 -:10F5D000E8DDCFC1EF07C6F0A723DD2EA9FBD0C61B -:10F5E000EF71467A177468F6F7CDE5B127FE3EE96C -:10F5F00026DAA5E1C9374AEEA1E5B1275F2B7C06E3 -:10F60000EA4FBD9AFB06E9DF7FDAEEAFD0BF39BE25 -:10F610003B0EE7737CF79F726F82FAD37198877500 -:10F620007C651CE645F9772706E03CDFF11C16B740 -:10F630006B7DF6CB12CCBF206D88C793C536668F25 -:10F64000ECFA9FB7207FFAD35D712AC4299A7627F6 -:10F65000A0DFDEF4B403F35E8E3FFBE5247D9CE97E -:10F660003F5D4FA38DC5338F2792398F033D2733DD -:10F67000FFAEE999C95B215F6E694FAF0DF607A632 -:10F68000FDF15F2520978E3FCEEC0FEACFDF0F37DD -:10F690001DCA639BEEB652787F0C3622F5C3378DB8 -:10F6A000EDBE14FCF0FE706170384EE100EBA2700C -:10F6B000A907793A103C868EB521FD7FFFE0F1095C -:10F6C000FA170DBBCE413E8AC245D2D8F3C4805D45 -:10F6D000C2F5B3E7BBBF2C017BEA68F70AB40B4E57 -:10F6E000B5EEC963BFAF74F06DD72D054F67DD73FD -:10F6F000BEB7F866F4FF16D757663EE84FE74FDD12 -:10F7000080F54712BD38DFD3E4FFE6FFDFF0FEB837 -:10F7100084FBF2A7C2FB2FFFD7E2FDCF1CEF896E5F -:10F72000C82F3BFEECBF72896EFDA75AF793FF4BC3 -:10F73000D71DB18F649F1DAEB8EF24C1109C5F5FD1 -:10F7400035809DF2EE5849E4EFA01F22F277E4B431 -:10F75000C56867C8691D6837AC22EC1E64BF6AE1E2 -:10F76000F7B1B1BCEFF66C6F00E3A28AAF7E33ADA8 -:10F770005B8737783B7004A37F2667D454439CA5EE -:10F7800075059D171DA735DDE26E55E19A764B3064 -:10F79000AE04CBB7A15C9DF1C3FDF05DC569BCAF04 -:10F7A000D669F237E20B6CC6BC62B2C70DFBD50E50 -:10F7B000AF0277B95353D678BF6DEF58B6AF1D4F30 -:10F7C0000298B779A6704A2D191C4E66F808B8F54C -:10F7D0008313F747C57DFC4A5A4708F85021D49F48 -:10F7E00064EB413F14FE8E14ECD7589316793BD846 -:10F7F0007E8A1AB9C71FF220B8BF19B96756B5A0DB -:10F800005F2AE0AC1B0FD76F86F399C257E0C54162 -:10F8100066219E1DD94E6F80CE7F95CAE0BE8AC2FA -:10F820001DEE1717F0157033E3E17DA0519D1D1FEC -:10F830002D8DF93AFE4AE2817D96E9F294B01FECF3 -:10F84000E5F204B4978F49242851FFED5845462529 -:10F85000F815C7726C0A9453FBE89A74F3BDE0A4E0 -:10F860003DF237F4A05E41920DF5633985F8FE3420 -:10F870007B96E1BD0390B74DFDF66359E576DC0F4D -:10F8800075E719DE9B99E0DA02ED07208F1BBF3F79 -:10F8900003FD9B1F641619C699F9CEB17BAFA2E593 -:10F8A0004EEE57F74DB5623CFED89FE755021C2F30 -:10F8B00054C71BFA1F24EE74202ABABE2A58DF450B -:10F8C0009EC986EF36BCBDA710E2103FF256189EC7 -:10F8D0005F5C7EA1611C9F3D1C04F2AED56A0DCF1A -:10F8E0001B9ABF204A2A21E7357F4D9489D47C0F8B -:10F8F000761BC699B87FA7A1BF37E49E0626E3848E -:10F90000C3DEE7A014F9ECB654BBDF42CBB16F57AE -:10F91000CAB0EF59F65E5D2B84A1CF3B463C400751 -:10F92000E79078DC0F1C28EFFD4B4BA00ED6F90BAF -:10F9300039E081327ED8A21258D747999D326C4B5C -:10F94000DF23D55D5E0276D6678156A85FF075B776 -:10F950000CFE64EB0E19CFD74D976B12FE0AF2B86E -:10F960005BC21CFF06A705E3F04753BA4BAED5D1E7 -:10F970009DC8DB31F371D1C48A25307E5BA6D6D514 -:10F980000BF2B4F2EF57CA31CEBB12B7F15EBAA296 -:10F9900089BEDB619F5EE425C54F935972FB0FACB6 -:10F9A000182FB9D5E27570A1807AD73DC3BA19F87E -:10F9B000DD3A8EC98DF8BF1015E241F1A975329C70 -:10F9C000B323774898D722BEB7A09CE5DBDF5E2241 -:10F9D000EE3771A7FF642CBC9FC8F205209606EF96 -:10F9E000D558D04E711DF6EE83FBC8EEF41C728321 -:10F9F00078E8A979C70FFB223D874353258A9721D1 -:10FA00009D15270A587F02F1CD1E4F55C258D46F5D -:10FA1000E59887B39CE7CFF44EFD8D07F4C7F2A2BB -:10FA2000D14306CB2F779D9488AACB33B08E5371E8 -:10FA30005E2E258CE7C55C27156C27E1F1CC1FE411 -:10FA4000E3BBE6A9AF5E0BF3D86FC57C67A2684B3A -:10FA5000601D1DA3DF543B701D84FF5D9130FEDDF2 -:10FA60003CC84FC20BD19470E64F629CC33BB2A31B -:10FA70002C19FCF2D40A2F9E1B4C7D588E9C9B05A2 -:10FA800038DC0EFFC373B597BE5A45C7DD01B2928D -:10FA9000B50709A5EF0E9B68A7A2C6C3EF3DC4F644 -:10FAA0004B2F831843BC6CEC3F2E3FD25FB36746AD -:10FAB000C7FF43C9A5AFB6C584671CEAEB8E1956CC -:10FAC000CC9F38355C134E01571783EBD7542B640A -:10FAD00044E38BEF496A2ED0DB9D705C80FAD1BF86 -:10FAE0004CAE0B96A4C3FC8363E1F97C9736642A81 -:10FAF000A5BF1E9B967B23C6491C98FF55FBF3A30D -:10FB00001BE1C8986BE6114F1BD08DA2254C8038A5 -:10FB100095FB0B940B22CF2D0A474ACFF49BB75B82 -:10FB2000A2759013AE285C35B82BB84307673BAD80 -:10FB3000D772B8FECF23F597B5017E17DA912EAEB6 -:10FB4000E53CD5964CBA20CFEE84FB814B811E4E0E -:10FB5000ECB062326B0F34821EF5D8D9DFF5490B59 -:10FB600067C2DF71197BD082F1BD37297D68401FE4 -:10FB7000C1F1087731DE8929AFA6C0F98913694A36 -:10FB80000AC06771D88670FB894282707F6A4FDA3B -:10FB9000C26915C81F2AB677F371264FD4FE518269 -:10FBA0007A9D9FFFD5CE95E1BED481F065DECF87EB -:10FBB000F8F0B92903D3415B851DEF1F6A2A5F5115 -:10FBC0000C7A62797221E663355549A8879B9A3F82 -:10FBD00043B88BF1959332517579533D104D4CD705 -:10FBE000DD237FD286ED0DCD27509ED3E9E401DFE2 -:10FBF0001CE3FB9D5D56F2D35A5A36FC5BFE69ADA1 -:10FC000013F72DDB419F34903DB6E53A7948BA3F72 -:10FC100089C8FF71147777D6BC180F72B656725F19 -:10FC200002970ECCEADE7B19ECE7D73ADC97C0FEF0 -:10FC30007F8EF71156CF715F02FBFD631F4D9A0354 -:10FC4000FBFBB559EE0DF09741AFF016CDC1F63C78 -:10FC5000F7CB509F316E06AB27323A4879347F8E0E -:10FC60001FF5B913E1F2697B4260B07B48AE6E7E4E -:10FC7000C600977EEDB284795198B841E9E79F6B51 -:10FC800086B17B710B4298A735721C8BAF67A4B00D -:10FC90003FC92BF277D346100DF657D39E72B07B37 -:10FCA0005BDF0BE502FCAE7ECA1184B8E4D2FB9E9A -:10FCB000B3813E9A2FAB85C057B3CBEAC68C2B835A -:10FCC000F84908EB5737EFC679754C70F3FB72FBB8 -:10FCD0008A217E55CFF39EEB4DF9BF8B9D7B311E64 -:10FCE000B7789B31EEB68484DF023E6DF8DDE079B3 -:10FCF000BFEF58D83C140E8FF972E84A1B9BD7F916 -:10FD0000E3E8F797A6F462DEB1E20E65D4217C1B2E -:10FD10003CE8AF64C6E3B99A5B87BE5E12EBBE985F -:10FD2000EE16AAFF29CB3DDEB2134BE77882EB1922 -:10FD3000A2846D5E3A4E2397CB9342EFD8F4F983B9 -:10FD400073395C9376B2FD6F735EEC5CD05700172D -:10FD5000BECFBC74D60B53002F029F1724906ECCDD -:10FD60005F4D215E8E172FE045C03FBADF4CDFCBE1 -:10FD70008B451702FE84E5DBC53379D1F78403EDAB -:10FD80002BF3FCAFE3FA57ACA39DD7079A7F3BD781 -:10FD9000B7677BFEED5CAE9BD721F8583C177C6CB7 -:10FDA0005EB798F799D359C8763A7426E44C23A9DC -:10FDB000F3605C96CB150167314F01AF9E01F25D98 -:10FDC00095E63F18D6A3842AF1B0FC7650A420C74C -:10FDD000BA2FC4942BA57917F63BD3F508793BD0FD -:10FDE000BA849C35AF4FC85BB14E2177C57AA75214 -:10FDF0004182F210EE7E90C07FA833D8C3157062A6 -:10FE000041BF0F64FFB9A13EDD7DA3A1FF0F3257B3 -:10FE100018DA2F54D718DA2FF2AC33D47FE4FD95DB -:10FE2000C9AEDF6C68AFD51E34B44F0987A681DD3B -:10FE3000FDB7966ACCE73EFFC3BEE7A01E6C7163B8 -:10FE40007D4F4B26967B5B54E4EF7D2D1E2CF7B740 -:10FE500078F1F97FB59463F9428B8665A8C587A5CB -:10FE6000592ECCFCFD650AD8EDE5A12EF407C68F0E -:10FE7000AFFB0CE4E1014BA03591C2E99C37997DC1 -:10FE80004E02667DFCE55B37815E77B37BE8DA7A0C -:10FE9000274B6A0C7BCE45F59DA6A317574D98C0FE -:10FEA000FEB28BC4CEBBFC6A1CCBF7C17C3D4A9B27 -:10FEB00073ECEC5EDB397324CC4F9C43D879055A44 -:10FEC00006EB68FB4C85F841FFD73A15DC8F22FC26 -:10FED000FCF0256C9A70BFBA3F0EF4775A2A9E57F1 -:10FEE0009A0D0FE97C654DC6BCD64BCAFF82F980DE -:10FEF0005738D9DFCDBA7CFFCA7FDE44DB499BBFD0 -:10FF00008C9D8710F786BC6E3913BBE12B386300DC -:10FF100079A09297FDDD9464C5ABF70744F9D771DA -:10FF2000CC1F98D9CACF0B1C2468C7097EA4EB6BE1 -:10FF300087F90BBEA8752BC1512ED0F7EBA641FF58 -:10FF4000FF0B270420E00080000000001F8B08004A -:10FF500000000000000BB55A0B74146596BED5D591 -:10FF6000AF904EE88400411E76886020AF4E271D7A -:10FF7000C26B28124054C446650714A540313C9317 -:10FF800018981547F774633308AC6737337A5C5DAC -:10FF9000C1D3E0A0ECACE7102171339A300D2A8F69 -:10FFA0005947A3828266B141E4B126742428E270E5 -:10FFB0008E7BEFFDABE8AE4E02E859939373F35797 -:10FFC000FDF5FFFF7DDFFB552D3FE4720701A0BA71 -:10FFD0006C4D1E14209D221DB7215DBEFA3B30F7EB -:10FFE000C3F1EA0B602E06982ABF164C2D01387F0C -:10FFF00004DC369C3FA65D3DB3CB85FF5CFE5182A1 -:020000021000EC -:100000000100ABECF83F8ECB3AEB2AFAE2BF45E1B8 -:100010007A30D335FCF911FF8A0F34813927361E27 -:10002000F77DFDDB346FB75F05B305A0D93F876966 -:10003000D8BF18CC2300F6FA6B78FC8E7F358FF78B -:10004000F9034C0FF8D733FDABBF8EEFBFE77F9EB0 -:10005000C7EFFB434C5BFDDBF97A83DB09D01FE084 -:10006000426BC540350F8F46632F6E689F9CE94BEE -:10007000416A16740E1DC883D40E968C0CA473248A -:1000800096075E0F403AD3B08AF79767BEC5F2C0B5 -:100090001F9F1DF99D0DDA4F463F339402DC03820A -:1000A000FFD965FF7D494AA5819A23A1BCEECDEC1D -:1000B000031B2580FB2090BF00E99CCA3ACB7889BE -:1000C000EE4F719E42794881CF4C3FE6A24CE867E3 -:1000D00052778A078553BADC6480A58EB556180E10 -:1000E00080523A1141F99A40821FB3009640D80AD3 -:1000F00074FF8F96139138392F03C8826C3CFF6BC5 -:10010000169EAF5F077A3E6E5DB94286B274929BCF -:100110008BE5B60222BC9E4D7EC45DE3A0FDEAAC39 -:10012000B44EE2BE4B1DEF5871D0C3BEADFCFCB562 -:10013000F6D5F55405B080E6AFCD54EAF6E0BA2B1B -:10014000FAB43D209B7A9087D3DC79653D94C3BF98 -:100150008C127A9553A6D85507D9A9034CA8C7681D -:10016000480ED9709DC55975A9B42E1A662AE0F5B6 -:10017000252D32EB03CC8A7910EAAD52D35B3B8458 -:100180003F21BD544EA89C01A8BFC59B8CFC2C757B -:100190009C64B97F0BCD3DF25B054F7F23A776E7CB -:1001A000B76AC22DA769BD2A4D6E7C1DCFB5BA4D69 -:1001B000DAF14EDCBC95EE948C53C9E4583086E4F9 -:1001C000827CB8C3E46F8764F6B7DEECE39C1FD88B -:1001D000DE2FFA61C73B68FFE72EE3851B009E70A8 -:1001E0004F7B3E30E197D35BBF62DF0637F913DA0E -:1001F00009F991AEC775684380E75E576E0F0550E9 -:100200009E51AFD34CFB47A5503095F47209DC6B7F -:1002100050DE939BF71F213F996C7784496EC84449 -:100220007BBC5E27B58BCB134F868229387F7C5BE6 -:100230004026B71D7B480D3A703CE63D05358D7173 -:10024000E61D9F4C7ADFE96F6239D4FBEB99C6FC5F -:10025000E726F6331884D7B2AFDFCFE021BB89E2BF -:10026000DA4AED4CC134A83361C0EA724C93539022 -:100270008FAE30B8E97AD1215790CE55DCA6C8A907 -:10028000782EEF493548E75E876A506C1427037271 -:100290005FBC6E3343D88671C4966902254EAE6347 -:1002A0002F84821407F5B8D69C24EC79D2E57A998C -:1002B000E296D3AA6EDF82F2843793DCDB5CDDCF7B -:1002C000FD96DBC472FF32DDF7961B29385C237D77 -:1002D000F9643FEDAFBC48F6D390ECB6E173897199 -:1002E0005A8F8BFA3ABADC7439563BBB38EE2F5F23 -:1002F000DDC5712F71DF6A13A8F528774F85ABB87C -:1003000016D7695F03F367E1B8CE8234AFFBFC8F89 -:100310003CE5EF93BD4C9527B42A742EA7E9AA7645 -:100320005DBDFA1BDEBFD7FBDAFED52D5EE7424787 -:10033000ECBAA34812711ECCCE53F6983EAF57EFDD -:10034000133BE718F2D6A4EF5543DE9A8C9136FEA4 -:100350007E85FD11C378AAF331C3FC5B32D718EE5A -:10036000DFEADA60B87F7BCEEF0DE33BDC2F18E6E7 -:10037000DF59B6C5707F96F21F86FB33655024F4B3 -:10038000B97C2964213F9B0BF54CE7412BD307A097 -:1003900093A98A96447421B8993E043EA62B3CAAA0 -:1003A0005C847613B5740E20BFEF78E3EF796417A1 -:1003B0001DBF1AEFCC72C5F2B29EA77F6A3EEE63F4 -:1003C000453DF5600F038A84DDEAF1BE57FD24C484 -:1003D000FB6811C6133C67B43199E34C34A54F4810 -:1003E0009262F1042DD244F958F75B3DBE14CF73ED -:1003F0007FB092FCE83D1946B8BAC79BA9662C0DA0 -:100400003C74DD9D737F7E6CFFA00916939D6D4744 -:10041000FA3AF2D1775EC4EC8AE3A780F8407B9B7E -:100420003C770A44F0FA4C272821CA4376C848A2F0 -:100430005878B92B6F36068899DFA3A2D09E7F48E3 -:10044000570A49DE81A726A49DCAD5E2D28DA8BF4E -:10045000E326E6079648A111288FA60631CE5F94C1 -:10046000C6FCDD0761D6E3FD10B110FFF301384E85 -:100470002F0017D30741617DE2CAC905189F1635C1 -:10048000983D1B91CFC2F4CEE1E49FF9638FA64B58 -:10049000782E2CED14E2A7D004EBA9BED1F9A8D593 -:1004A000F8D858A454D0F90AD35B373E83FB77368B -:1004B0009A602BAE737AEC630F435C3EDEEE299FAD -:1004C0004EF37648A0505E0DB4D842DBB268FFCE42 -:1004D00001940FF4792B3C15338B70DDD945C0FAAC -:1004E00086D6BF00E9679653C81EA6F46719E07365 -:1004F000C37CF93DF967809F2B2459DE00E2421945 -:10050000EFCBE3875F7F6DCEDA3CE6274075DC7684 -:100510008F3A9FCF6FC55840E7DF6C0B6DE57AAB24 -:10052000669884E7AC7CC966A2FC7F14E333DC0CDC -:10053000F0B9DFCEF47FFC4EA65FF833991EF7BB0F -:10054000987EE9CF61BAE87B6400F577BA48A922C2 -:100550007E7AE3A3F73823F8884A30A7DED1FD7E00 -:10056000A5E60F050D279F4C263B6892DD64A7F991 -:100570008D689878EE73CD63427256BC5CD5C7899E -:10058000CF82A68FFF30BE849E333B259C7FAEA9D1 -:100590006B00F96FE2F9AEC8A3C52AE4A19D7747C5 -:1005A0005AEB467A7E47E3703A21C611107648FA34 -:1005B000947AE2630DDBC9AF8A44BEBFD3D659E259 -:1005C00074C4F8032A3130CFD46A7966AA7C39958D -:1005D000FC6216AD3B96ECFAA60F68BFC001E1873E -:1005E000A8D7F9BE387FDAA5C941A7F92D561FF95A -:1005F000D38E964FEEBA1DE53073DCAD5ED9159BF8 -:10060000FF3209C14BF67DE9DF9FC9E0F94EDA6A96 -:100610002E6C99EAC479F7D9F7BC4B22B8DF797C04 -:100620006A1A8EE7674AFB882E70654D4BA7380023 -:10063000217EFEC19CC9FBC8C466B86759A99E98B3 -:100640004C4E1517772BEC186F0C71BE9F617C4BCD -:10065000E660C3FC5B5DD986FBB7E7E41AEEEBFB13 -:10066000CE70171BE691BF52BD8D7CB0DE619B1C26 -:100670001A21911D5CF86C19F33FB784F88FA2FC26 -:10068000AC58389C29DBF0DC3314361AF7A6927F7D -:1006900026D6B5CB5B5EDEA7B87AAF6BABC0D737DB -:1006A0002CF55ECFF6560F5E6F5D8B71E40F14472D -:1006B0000ADFB8C719C473EC187BE90617F2F761B3 -:1006C00051CFF56E54AB7713EDE88ABD4A2E613FEA -:1006D0000765A07A48AF7B13ED08E049AD0E10F432 -:1006E000A7FAFBCC8F44DEFA8AFCBE5FBC7D6B347C -:1006F0005464C8338556CC2FA89FCEBFC9B0952E61 -:100700005CC673E87AC88ED93F3CB4E5DD41257CF0 -:100710003D40756D15E5055C3FD923897597EF79E7 -:10072000775046EC3EAC3A6E980F4F48FB0CE3B561 -:1007300059C6F1D393F7C53FDF5B3CAADCF488557B -:10074000C5385DF9ACC4F92AF1BE7E9EA97B93142D -:100750008A9BE6661BF753554E051407554D98477F -:100760007AC8EB7A7C982B434D4F716E80B6EE8C35 -:10077000BD4920FF8C758FA2ADD07902FF25F2CD47 -:10078000D1BE0AF8E2F6C9F288FAAF23ADEE9FBEF9 -:10079000C3791D7F063789BE234DC4DD8286D326EB -:1007A00013E5BF3EC25E0A9C11533AD2E8E2E40070 -:1007B000A03F552F4909980AF1FEF0CE4FECA8FA58 -:1007C000519E412FD8516F9F994C86FC13A5988755 -:1007D00063CFCECCB9947F6EDF9B1436FD0C7E3C8C -:1007E0005473202D2C177EFF00D98DD84701F48F2C -:1007F000EADF81BEAF427182F8A7F132CF90A3CF7A -:10080000E2BAD507451CC0DB8EC47EF6BEB87E16A4 -:100810003609FFB5E32FD53B55109AE620DC208C36 -:10082000FE0FBF9CFFCFF43832B8CE213FBFB9BB1B -:100830005FEB7E5F7D58F8FDF9E66F3FA2387F1EC3 -:10084000F35FBCDFEB72D3FDBDFA7999FD52BF7E39 -:10085000AE599E1EEA41CE65BA5F296EF6D75AA7F9 -:10086000D8B776E2C5BB28CFD5B6A086A4EEFBE804 -:10087000B47ABD0CAEB87D76ECB62D0E39627C44F0 -:10088000F5FCDAF26DFAE43C41D750FE853A2DFED4 -:1008900088BA06F3AA2583F2EA2CC9BD0DC9E196F0 -:1008A00081E524BFC312845D1E5EE21E3B9EEF6E97 -:1008B000B11C5D77507D06993966DAE72E4DAF772A -:1008C0006BF8D2EC96D92328DE7FD2B0F0B042513B -:1008D000CE93CDFBFD1A025C1F1E4EF30D5D89E722 -:1008E0009C1914767E38ADB39DF0A8C31393A5A0D0 -:1008F000C4EBAF8DAFFF0E5B7C436B982F0D97520F -:1009000046CB3F26FF847E598B8BA8CF8024FA3BB1 -:10091000F603F3A0A719675802A17D0AEE5BE50E66 -:10092000739DBA0C042E9058DF574DF8DA4AF9211E -:10093000B11F9DDCB4E78854D0038E9160B7D7C255 -:100940002D12FBE0DEF0871FD27DDB3C71F8616287 -:10095000BD7EA52ED5EBAA6DC9A1AD789EB727FEA9 -:10096000DBB965385EB52DD9497DF7D9976C018A19 -:10097000CF67B7DA4212DE3F9BDED9467DC8D99DEC -:10098000F96E5C012A4DAEFF7C8DF2FC9F2C6C173A -:10099000006EE11F57ECF4D16314EF6AB7A548402D -:1009A000F5B52AEEEB3DA0FC6A0AD7094B760D0A95 -:1009B000D9A4589E21FF706169716673924245FF08 -:1009C000D90377F725FCAADDF4FA30C6C3E4278EF5 -:1009D0003D86CF2D7B25C543F504E401EB6DF1D6B3 -:1009E000515BA83E7ED1A2EE27FE2B5EBD63601652 -:1009F000ADFF717F207EA2CDBB06507D14ABDB7BAB -:100A0000AEF7CE3767F785BC989C743C71FD1FD755 -:100A1000F848EFC9928BAF9BA146194C76D1340BA5 -:100A2000685D8F2C29E4979D1B92B94E4DB4BB6332 -:100A30001ED1A72CD7F1877E60CF24FF5181E5100E -:100A4000DD90BB7523CAE93B4FBA96AF3B47DE95B5 -:100A50001F6F9F6D556F917D6EB2312ED29E64AC2B -:100A60001B74FABF9E34DEA7D27EC1804354ADBE54 -:100A7000641CE761BF87CF7B82AEE24790AED4E4CF -:100A8000DF35DAD7E1C1E797D6FFFE8DF7582E9B09 -:100A9000FEF133DAF78043E031EF09F925F60395EB -:100AA00076817B006CE1F3EAD74F6FFEB480ECF007 -:100AB0007463EE48D2E342B9F5D48BC8E7B994D653 -:100AC000638F23DD79E023D64BE27913F19B7649DE -:100AD000627E97131F78FD1EAF4F2EEECFEECC7DBA -:100AE000DCC28DF92CBFA9725E5FD263F46C2FFD5E -:100AF0008A764E7D7DFD7CFAFAFA3C67B1D0D7FB51 -:100B00001AFEDE616D3D47FAED782357227CF0CA6C -:100B1000F5F4D682B4387BF9A570F97B357CE4888E -:100B200069CD6FAC688FEDF5CF58D4F8B8F713F1F5 -:100B3000F82BF5A0022EE700914A386F2173661C4E -:100B40004FD4C7E40C389EA01D4FA2F3A05F4ED433 -:100B5000282C5533196FA7F590264188C7C1C96E57 -:100B600017D149928F710FBD6F98063543880F9347 -:100B70003DC238E15AC227B16E999DB6EE8E2CDC8B -:100B80006F6D7F5847F5CC5A8BF08BC08264EEE7CF -:100B90007439E979069C7986FCB2D6092E33AE33D6 -:100BA000C70CEB2DE962DE8D28E7C30716BE4BB8F4 -:100BB000EBA7E69AFEB4EF51C7B3F99289EABC50AD -:100BC0000AF58C9F7DF427EFDF70EEE7A04CA4BA06 -:100BD000E29EFD768EFB89F8C42250795C0911CB28 -:100BE000057CEE8BB13F6CDB0B31BEBE18F75D238D -:100BF000F509F7A53DE9A5E703E5904379E96252D8 -:100C00006A01F1B3DA2EE8A37D52B7123DEB74040A -:100C10000897BD98342C44F9F445497D80EC199F20 -:100C2000E33E36702C3944F9EE5159AD621C3ACD91 -:100C30000A12CE8FF6D7E4D2012C97A8459BFF8DE0 -:100C40008BC725151EC629E1A28BE3F2F884BC539D -:100C5000926B12FDD98F62FEC44EB321EF94146AD9 -:100C600078CEDF5D5CA74EFADE7CD5BC74B958F453 -:100C7000BB25FD4C353DD58BCF68F783109605CE4F -:100C800023EA85F157EC4B91498F55DAB88AF21A6D -:100C9000DA5534D51E9091DFF1CDC2CEC69BC37B11 -:100CA00088629485D5545F3461DED3CF817105327B -:100CB00073D91EC6E9768A6BCDC379EBA41AEE63AD -:100CC000EC54D720DD28B5F2397E059D4C152D9FBB -:100CD00097839BE914F031453B653A1DEA98DE069F -:100CE000F54C6740ABC8FFA3C341CE6BF08493FBC8 -:100CF000C15B2B4D547794FCBAE7FEA1518B27BD05 -:100D0000CB011DAFF4A7CB611AA0FF65F7208F219F -:100D1000391C4712E591E8A7132122B39F5280C8DE -:100D200026FCC0C5FE5A010A8FA75EA71CCA22AACC -:100D300099F19B447954F46C17BB35BBA8255BEB48 -:100D40001FD35357B18BC7BABED0BF32A90E4DD4F3 -:100D5000A37EBD24B9BCCB85A1F8B35D27E79A314A -:100D60002F951497AFCCC6717BF1B773CD98CF4A4E -:100D7000C697EF1A8EE373BBBE13E3C2F2628B1BFE -:100D8000BB983517E74EC1F92AF9672151F4438A18 -:100D900067AAE88F5769758CBAE6376E27FA8B3ADF -:100DA000D4E1263EED58EC133E2A678BF78EC3A69E -:100DB00087F75A70DE498B7A98FC77853D9CEA422A -:100DC000F9AF5A33752085CEA7AC62BECD26705AD6 -:100DD0009D3FBC1E48C2F1CE9DB92BA5E1D73E0771 -:100DE000AEFF25ADAFAE191120FF551B25B7D06C56 -:100DF000F9C03928C3F6560B106EAAEFF7E468F570 -:100E00000CE747979BE3F760ADCE69DF999B4B7A80 -:100E1000EA2A163818646415931C8F8FF675D1FC76 -:100E2000688AB0B72ECAE5DEDEE9E012E51B9A9FBC -:100E3000783DFA151E009F3797A817E97E75F26571 -:100E4000CEFBE78A3E5E17C98AD9AD844A9B87FCF0 -:100E500007150859393F4C705EA95329DE2DC2751C -:100E6000501E253E3548216ECCBCCE528AABB8AE62 -:100E7000A904F7A9B6468615E173CFDE7DCC2AEC2E -:100E80006E88B03B2D2EB5EC3EF8F86031F4419CF5 -:100E90009F55EFBEF4DDE728BFEAF30E374D8FF91B -:100EA000D70B2BB9DF0487218EE87E37AEC9C6F594 -:100EB000F6F8E6518B68DEC48FDBB289AF496D115D -:100EC0007E8F166DF974B03887DE875C947E4E3E57 -:100ED0003EADE589D3769117E8BD30F77B8DE2BD55 -:100EE00070AD8673D6B648A100C71FD13F2FD6F884 -:100EF0005B71B0711FE1278B373D3883ED2824FAF1 -:100F00000A17FE525C587A44F4CDCBB61BFB8D6AAF -:100F1000EA9B693E84AD640F2BEA13EE6FAAE0BE34 -:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B -:100F3000E4797DD51EE261625F5C05CA8412AE7BF6 -:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A -:100F500052DB9BE4E460B958B99FA8DDBCD2EDA494 -:100F6000B1E6B75B4CD453E3C4773E80F8E7743FF7 -:100F70005EB25EE2BE0336F5631B2C7CC5A610BFD5 -:100F800085AF0CE43E04FB25AE0FB7BC625B4FE3BC -:100F9000E0EFFA04E442C2A13B6F201C269884F5DE -:100FA000A6C0F341F2300EC3B8C823255ADCD7EAF5 -:100FB00000081719FAF9A096FF6B53460EC4CE39F4 -:100FC00036EFC020437F12D4EAED123A27D58DDBED -:100FD0006F10F793041F7B3EFC8764AA7B1BCDBE7A -:100FE00064C2B5CF1F1ACE7D4C6F72F7621A82AB06 -:100FF000BCA7F47E3A23FB6A7A2B79DE2CE4A5D9D0 -:10100000ED9B7E05BEB4C4F4A2F337557EADC24A53 -:10101000B8C843E0249CA4F6E0CB413BF5851B8097 -:101020001188F320ECF9FC1913BF772F859C7F9D65 -:101030008063EF19B33B84CF37687191DE3FBBE229 -:10104000ECCCA6E1BF49AE3EE08AEBA39373D20D90 -:10105000E314F70D86E7FA960D37DC47796FA5F5AF -:1010600021A0B4E695C6EADE3465B4E1B9A752A77B -:101070001D60BF6F7D9871A97ED33DC6F3C8CD3288 -:10108000C503B820EAA532FC257F1B038120E96354 -:101090005CBBB18E2A8BD471DF9874C86CC0016CB4 -:1010A000D7C0A5B6907F519C1C024344DC4894B73E -:1010B000F1FB8BDA8332D77BB543B150CDEA49DE01 -:1010C0003719E4ADFBA32EF7FE3EA3DC07CE31CAF1 -:1010D0007B906A94F7E0C546790FAD31CAFBC6D55F -:1010E00046B966058C72CC5E3FCE307F445DB961F7 -:1010F0007CF3F3B719E68F0ADD6518E76EBFD730CA -:101100003FBF7EA1E17E61D3D2EBD27F51B8D63012 -:101110002F51FFC5077E7B55FD07F057E81F581F6D -:1011200065A88FB0EBFFCF0E4EE87156B783EB8CFE -:10113000B36F92CF329E302112203B284B663B99F1 -:10114000992CE2CEFB07CE1F5270FC81ABD892499E -:101150007596563FF8B438A4F733897DE39D655200 -:10116000C2FBFE24C3FBFE6B7D57E76D0D1BC6451E -:101170008780BF9BF11C71BF4DD47B5261B8ABF42B -:101180004CCDDB44C75EE0B4DDAD5FD5BFCF4BECEB -:10119000B760F9217EAF384F7F2F434E51DA1D9F44 -:1011A000D4FB31BDCF4DEC7FF5BEB77B9F26EA98CF -:1011B000EEFD863BD3CC75B4CA75F57E49659C734C -:1011C000CB2875B0D74B4D00F6C926EA93234121B1 -:1011D0004C05E83D7494FEA72224F0CCBD84C7479B -:1011E000D380F17345AABB3790C7C777464A057CC1 -:1011F000443FC55E758417F57A4272AE2B267C6239 -:10120000DCD7C3A81EC9F18A3ACF26A3A4302F0D7C -:101210009CA7005DFF215D19E5F5C6F092DEEC2686 -:10122000F1FBA4067F98A9D9E9E6EF9712F1C588EA -:10123000C9C5F569E0B7127FF7F3351D6E6CAC8E4A -:1012400039BFDEC2750C68FDFCFD9AFC75DC639E3F -:10125000C6CF095C6231E6E5FB9BF6B35E9665B6E8 -:101260006B78490DD7E30F0E7178F87B38A5D82D30 -:1012700070321D07192CFF94BAEB5AFC2FCB3C6B34 -:10128000C0A1E0B57ED7F5BE3CC6B758FFC4068105 -:10129000679ED83094F1F3D8FAE7188FBABFE643C7 -:1012A000837FCC5F7DD4E00F0B02C70DF723199D20 -:1012B00016C21F236F0C9A761FCAAFA3D1564AFAE3 -:1012C000403B7898F4AAAF1FD9903B85F6BD369F76 -:1012D0005FF339DAFCADAC5F9DCF63FE233C8EF843 -:1012E0002309DFA7093E759C43A7D6BD9063A6F7E7 -:1012F00089521F37E1CABDE11FBA9F994A87F33A65 -:10130000174DAE530227AA1943F55FDBE401E574DC -:10131000EEB6A156B3A023C57850995D8CA74D2792 -:101320001AB538D6132ED22689EF89E649CA4B0B57 -:1013300070DFC747A94F913F542FED2C20FFAB2EF4 -:101340008C3C20E1FA5DFDD58D241F09DB8B41E942 -:10135000CC077F7776C6142890D055F679BFBC9716 -:10136000FAC4337D02E7A842D9DD784C8CADC21FA8 -:10137000DFF71E60FF3B898B119F813F4B029F72FD -:1013800044ACB3709D8CFEEA73B42F7D4F46EFF7EB -:10139000E83AD9A78E97462DA24E8C6AF5E266AF41 -:1013A000A8675F4AA04D54E312FE4894E3F5D323A7 -:1013B000094F3FBFC90654DFE2FE8AA924F6FDCAE1 -:1013C00000E485EAD877ADA2CFF4FCC516A638A50F -:1013D000E3AAAF7BB378BD8C6C819766FC33C62DD6 -:1013E000F2C348EBB0592971E73D048C6377101EB6 -:1013F0001D8763BFEE15FD3A3C24E25EC786C18CB3 -:10140000B7AF3878E218C5AF7BBC6A23C975A1C9EC -:1014100055CADF67A5EE61DC6CBFD7C5FBE27999E1 -:101420005F8C436B494F2BEC11C6D9AE85ABF7C629 -:101430007FC7A2D6E7F21847761590DDE8FBE239C0 -:10144000F67BE3F06FFD1CB175AEEE073A3EAC8F54 -:101450004F6F7E6AA486EFCFF7F5905F8F69726950 -:10146000B3F48CC75FF28AF778DDF4733300E1FFE1 -:10147000B63E98FB917EED15FC77CC457E18DF508B -:101480008A48BF2BEE72B849CEFAFAB88EFAFA55EE -:10149000F6E91AEDFB8AF85F5A23F07BFD7E5412C1 -:1014A0007A0D6C1078EA8ADD478F3D8EBB2C79353A -:1014B000BF98F281FE7CA29C51BE23F9FB3B59BC34 -:1014C000FF42F99EA7F51371FB9F2BD7E850F19EC1 -:1014D00036BAE5D230FA3E6D057D0F5740F621F061 -:1014E0002F6830E25A28AF00E11BDDDF6B01BF1F20 -:1014F000B369F9C4A63F3FC46C78BE3EC597548A11 -:10150000E77F438B1B383F64A2EFB9B5F8D4A0F551 -:10151000DD89F84B43ABC04D1B32AD5C4753FD43F7 -:10152000F7F5FA67D58702375D9525EA6C3A27E922 -:10153000593AB28FEB852BB8B884F91EE5986E55F1 -:101540008794923FA92B399FC937A29EE97DC85F36 -:101550006FD37004911FBD5A3EF4D23A74AEBCBE34 -:101560009C274BB47DB1BF60FC6E2CA85AFDA0E156 -:101570006F1BF619F087FF037A5FA88030310000F7 -:1015800000000000000000001F8B080000000000A9 -:10159000000BFB51CFC0F0030947B0A3F20FA0F13D -:1015A00067B2A1F2B3B950F9875950F9FE68FAD180 -:1015B000713B13030323137E35F8B0083303830C08 -:1015C00010AB00B10E33F9E680B089280343A904BB -:1015D00003030F906604D23E405C06C4FE407E27A3 -:1015E00010CF0262197106864B405A5E8C81E1A5CC -:1015F00028449F2D90FD438C3C3BAD792973F32803 -:10160000A60C5BCAA2F285D41818BCD51918266B93 -:1016100040F80648F2AB8062C26A10F611790606FD -:101620003D205F5D16BBB94781F2FA40F9DD1AF83B -:10163000EDDFA183CA773543E5E7A1C937BAA0F248 -:1016400035DC50F9AAEE101A00B1C92A3BD80300C4 -:1016500000000000000000001F8B080000000000D8 -:10166000000BCD7D0B7C54D599F8B98FB9736732D7 -:1016700033B949263079C14D081030E02484808A7E -:10168000701322449BC204698BBB6C77C4D646148A -:1016900008EA6A7C6C33790701096A77295A3AB1FA -:1016A000A2A0B44D5DDC3FB5D69D40DCD2D6D6A01D -:1016B00058E9AE6D23F5DF5A57D9A052A9D2B2E747 -:1016C000FBCEB9997B6F2609E8EEFE363E6ECEBDA5 -:1016D000E7F19DEF7CEFF39D1345F4106D0921E7D1 -:1016E000E1873E5F25F4273BF924A48790F9F01C9D -:1016F000922373E019E3EFD933B8B64F2045581C55 -:101700002495841410F653D0D4B9599C4BC8641254 -:10171000FEF1CC425A1EBABE8E0468F9F5ABFF004A -:10172000CFCED5D5B557E984E4ACE93BB69C3E8332 -:1017300091B8102D25E4412212920BFD15C7AA7C09 -:1017400084B44367971332299663C44AA160D002D8 -:10175000217FA7F28188A8CBB4ECC75F93F3309FB9 -:1017600084282451821585F3EED1ED9DF5CDA71F78 -:10177000DA99750AE1FFB71298DF44EDC8ED6CBC49 -:1017800018FDE73CC54B5E727CEC27A7C152268052 -:101790001FFB776304EF9BFF57C6CB25E51EBD8279 -:1017A000CEB74ED4E2509FF465C8B41CBC452609A0 -:1017B000817EAFE8115CFAC4EBD249486D9F0FF10E -:1017C0002BD4FB93F07D8E08389F2977BFD9DB158A -:1017D00024E4CC5A5F18E94323242B73F47CBED64F -:1017E0004C48C26D29AFAE16A2385EF8C7C5B47DAD -:1017F0006CB518DE0BF0D4ADCA80F766BD3BF93886 -:10180000A3E983E832C5A3CCE943AE130DCFDC4F87 -:101810004F1FF227A48FECDB2DEDC8C5AF17E27D7B -:10182000FE85D3C7A71DCF5CD7D17CD582704CB9BC -:10183000BBD843E8FA3F50BB2A3D9AA2DED8EB5A08 -:101840008EFC1EAC23463C45BB2DB09E38CF984D38 -:10185000DEE093AE8F34B2BCB7D9D64B9A5CB9A652 -:10186000771C7C4841FB7CCD7E9526497F338B16C7 -:10187000654D84FE64DE5FA7B62E46806E81B62974 -:101880003EA49EB204A1FC414224BC974320D2B2A4 -:10189000A219F1FB0428C5715D4CF8D462D1369EC3 -:1018A0002BDF6B5B0FB2262658E1579A1484430650 -:1018B00036E1F22E82C28DC10D439C9F06E57B6C02 -:1018C000EB2FFB48C243E5EA96E272625D07934E56 -:1018D00005C1A4D37B2E4CAE38C75B6D87F382DB8A -:1018E000F964FD77669BA2F1DAC9E477269E28F2B7 -:1018F0005E815F2CEBDEE52287844B0969CBEF8CA0 -:10190000C1DB2EF8DF65489F20B448577EB906F446 -:1019100044F60932C0E931C9239489F57A898EF4F5 -:101920001413EE20504FF245104FE6F7B1E1E27488 -:101930001733FA8B69BF9FE5DD7E96EB3352E17A70 -:1019400073C884BB08E7912CD379BC7B17FD1FA516 -:101950008F589910DF2B8CFE5E07FA90CAA33A7855 -:101960006F91276EC12ECFEAF8B723CFBC36631E26 -:10197000A5C7C1B044405CB53EE3366A68FFC7AE58 -:1019800014E26E81C34BEBAFE070BE686415007D5E -:101990000ED6B8917E572CFF3008E47BEAD02B722C -:1019A0002A7E5DB1C8958483FEB7C93A3FFADF2429 -:1019B0001803F9B206E9C8846B43B984700C2E127F -:1019C000E230CEC0AF7E7FFF1514CE172B84B05B04 -:1019D0004778FD848E3768BC1F1C4F4E10737C9D6A -:1019E00068804FE7F823EBA186D7005F36688A7ED0 -:1019F0001F1DEF66297C14F41899CCF4438336A399 -:101A000006D64712187D2C1572B05D9BAF7512AECD -:101A1000BBB436A5BC6AA08A422B87EFDB668C0B71 -:101A200067DC353C64A1EBA6D70BEF1FB0C039478C -:101A3000F0077F97467F594016C03ABFE75B959EF7 -:101A40002063F7F776B3DA22BB08F9B059BF7FC03D -:101A500035FAFBCD1269EC2B1DFDFE1A41E5F88825 -:101A600029609F99F31E99A72F88F47D33885F4AD8 -:101A7000EA37EFF3B4C856F9E398C7087E3F613BF5 -:101A800035786B2C57077E8BAE14A01F99FE5399A7 -:101A9000E4C79B0FD433BE73C0DB11FCEF81772208 -:101AA0003E7ECFD7DA09F66A9B8BD14B7BB6186E98 -:101AB00025A3E9C55C0F138F17BA1EDB040FF2874D -:101AC00049470DE2DA71D77D223ABA03E8E892FF7E -:101AD000793A7A10E868FEFF493ADAF57F918E92FA -:101AE000E5E5682FACE47DF50FFDF62190CFBF3022 -:101AF00024947BBF58C4E4FF2FA24C2E0E92E8F62C -:101B0000F9A00F8E4B28A7068D363FC24B4D629829 -:101B100007FA5D94FE5E017B692695EBCD2A3EE9CE -:101B2000EC0B56D1EFC7AEFA301FF4D731BAB6601E -:101B30007F13326C18B4FD4B23656A8043D9C3CA46 -:101B4000C32D6763609F0F0AACFC2F2D678D188E25 -:101B5000B7AD7339C5E74AF895C2B17A9160C453FD -:101B6000D0C54F0485E1A586D8F42A5D979F0894D7 -:101B70005ED4C866B4AB098910F40F8BA99D60B11F -:101B80002F9A4081815CAE71A3FE73F6FF12B70BF2 -:101B90009D76DCEA45652ED017EEC86979883E57F8 -:101BA00046042C03FE350BDCA22118A007228BDC97 -:101BB0008F82FE8BC8C4A5A5E0D79586DB66779D8E -:101BC000E67A8CE2650DF35BB482FA39C9FAA74D67 -:101BD000FDEB98CF587461CEC32C5FBBE8F4401680 -:101BE000CCBB56084F8786AA56F045BFB5FF34D305 -:101BF000BEF103DE7EB1E6DA74460751D4AB263D72 -:101C0000FDF88DAFB860FE647516D2E5EA3AC96694 -:101C10004FAEAA49B3953FBFE8DA71ED7012B5E057 -:101C2000C142F7813C82744A7E43ED144AA7B1EA6F -:101C3000E128DA2D2705BD8D96D317374D857EEF28 -:101C40001133B1BEB0B869E610DA5BCB90FED37841 -:101C50009FE94AE3EF8B40AE4E17C9A33AD8A3E3FE -:101C6000FB051D9CCECDB22B188D09743DF5985601 -:101C70002E8D83EFB821D6A6F21BA6896CDD3A62C1 -:101C8000ABB4620068C02E37326A1AD1FE33EB5310 -:101C90003A9E2666C3B8317C3F42C7DD745EB49D70 -:101CA00097D922247DF6AA7432CE3CDA1DEB4FC5BB -:101CB000BF914ACEDECCE1238758FFA64C4ACFA481 -:101CC000FDA7A86F3EBB78FF67C322190438E588DB -:101CD0008AFC50524DACFD10A30CCB0A2FBA431115 -:101CE000B590E2D35D2AC2344847E9A386AC031E0F -:101CF00062B8DE5BE9DAE65BF872EB9F25F4F36F1E -:101D0000168B5A406E6CEDBF89E8141FDE509C6044 -:101D100079CE8D2AE0692B75B206617CB98F001CE3 -:101D200069F9F4773A4E9A46E23AED4FD6FB122221 -:101D30002DCBB5246CD04F7E2D2C78A99C381C2A35 -:101D40006A91E9FBF6B504E52301E961A19FF6D0AC -:101D5000CB8604F4B3868401E0F6E03A9C6767E939 -:101D6000BAEE42FAFE4C9D8CF103728EC26BFAF50C -:101D7000D4CFF0961003C6DB9A43E23EB4830DC481 -:101D8000AFA2B1F5D3771593C43CFA3DA3B21FC6F9 -:101D90008FFD3D617C49985C93B93C2132A53F1889 -:101DA000BF490BDF9782FE5412BD499C6F59672DC6 -:101DB000827EAC136FE90AB906F0DB5E46F9208536 -:101DC000DCBB4314910EE2E1552B8B528C738FA830 -:101DD000A37C32CBFA5905E11FAB7EB29E4C12595F -:101DE000D0B521005E482488F3CB24233F0694B36A -:101DF000F87C279146AC175AD8D30FFC966BF45554 -:101E0000012EBEE6FFFC315C37F28806762C85B6E3 -:101E1000F87C56525E80CE81F9BD1716D1EFF08B5B -:101E200009CDA01DF83D8321747E758271B9746857 -:101E30004201BEAF596D07BB2440C2027CF787E563 -:101E400098D5AE4F27B46C8BA790E3C59584897C59 -:101E5000FCAEF503EB68258D9702300F068C7F05ED -:101E6000BF699B3F8A7ED8879EC05C18EC4E6FE0AE -:101E700051787EE8991247FF2CCCFC2D95FE03F299 -:101E80002E7DA16CF36F320C7B39CBE1872D937CD7 -:101E900038CF8CCF12EE5F1975D32725E1A210D56C -:101EA00003BDECAC9109F8FF3E1F83C7842F4BBAEA -:101EB0007701EAC7B07C12E0A0684138CE90730980 -:101EC00058E24009C1F82985EBA403AE930EB84E41 -:101ED0005AE16A52D97C9DF662AC9A943452E07E03 -:101EE0002872FF83DA4D60379E21EF18B540389194 -:101EF0006B50CF0634D6C6A70E62B042231AD281E9 -:101F0000D36EA4EBF49ECDFF5AC8CB3A11601E14D9 -:101F10004EFB77928FF48265898CC485D72D34F17E -:101F2000A57FE1DF29FFDD74D44580BF281F4BF07A -:101F3000DDC5BFDEC4E3C3EBC0BFA6F8FB12890456 -:101F400000BE77898871A877C9CB81791639794A1B -:101F5000E4F6092CB1958F493804725CF6750E4A87 -:101F6000014483496FC2795CC73093F33E467731B1 -:101F7000A2B6A03EEC66FEA7194FFD728FDD1FFED4 -:101F8000CA2E7BF946B26A12C44B6F7CC845E2B4D4 -:101F9000DF9BACFE3D5DA757450DE1FB0A69EC04F4 -:101FA000BBA4CBC5EC8D751A9121FEB9E1FF7DA3D1 -:101FB000F27A3A9F33200FE683FD4EC1B7E891F5E0 -:101FC000C1B862948E9E5F9B105E718530F6FCBA3C -:101FD0005C832BC0FF8E6D77A19D499C71D08312CD -:101FE000C6412DED10DE1BBAEDF39B68FECEF91253 -:101FF000F200CE77FDBEEBD13E1F6B3ECABED4F6DB -:10200000A64F126C711F93AF4D7A77F27785A4B308 -:10201000B80E558368AFFC3A2DDE86EBDBB800D6F0 -:1020200077A2F69741FBEC4FDE7EF1A71C7FE90417 -:10203000ED37A8C3CB60BDB7047B22C09F661C6B85 -:1020400023891979F457D7739B6360BA8DD40B5DDC -:1020500060BD7C5A4FBA807AC5E3F7778ADB253FAB -:102060003AF02D05ECD4779F7C6305D80137FF400B -:10207000222AA5875307FC2481F64A5C01FB663DB2 -:10208000A5BB38961395D75AEC614AD1B80E377F65 -:10209000D78F76C4FAA7DDF13ADA7EFD3FFF762EC0 -:1020A000A17838D53AFCAF7940CF4F0A2CEE1A1BF5 -:1020B0009A7B2D7DBF5E267F1B494147D74B8C9F66 -:1020C000DEF97EDA1AB013857DFD5FC47EFBBEE0CB -:1020D000725BF4F11AC985E3D27AE847C4F60BF1D2 -:1020E000E90283CFEA0F98F1EE77F60B0CBE43AE10 -:1020F000B807E0DBD7AB4469BD4DFB4E235D2FFD38 -:10210000EEB70380874D87EC76FAA67D52C23D1765 -:102110009F6FC01334A85009F864FCBCF1E006D4EA -:102120001B1BFBB69E067EDE74C86593FF142FE171 -:1021300004E0F535295C07E57F7A22A05354BD3DC4 -:10214000B8370078A5FD5EAF50BA5AB9D0DE0EFAA6 -:102150003F9B39BA3FEA19A2DFBCA96F0B1BEFE026 -:10216000677F0FF27613617ACAE4E7B7E1979CD1F3 -:102170007A668B648F6F9D212F56E23EE0BEAC9451 -:10218000FEB3A9574CBEBEF9DB67F6C4E8F8EF3CD6 -:10219000FD1F7B62741EB7FCE5FD3DF7D0F991E7AA -:1021A0003D1AC8AB4D4FBE1A2016FC3F26B1FD802C -:1021B00053FB9F787C37E59353BF74A31D78EA8760 -:1021C000BF9FA2D3F99FFADE9F26819D7AFB0FAFB6 -:1021D0009A0CF8B8FD99A593C7B3D7816EE36EEB5F -:1021E000FAC6B17FFD90009B20843CC79F8E753A54 -:1021F00072504A4088E0DD13EEB89BE267137DD74A -:10220000540EEBB601F51594EFA5F8DE78A0EBB40B -:10221000343715DE637962089E893C128275BF7679 -:10222000E59515F0748575A013328C7AC2D96ED3FA -:1022300071BABE978EBD9ED49E5000FF9B0E6C61FE -:10224000E3F6D1F50C8C5ECF77E197CB46AFE71183 -:10225000C91E673A436EF9E66EF878300BD77FAC4B -:10226000F5DCF0CCE7C6F5EF4CF930119E1B040607 -:10227000D70EC97845027E7CFAA9C77707D93AD725 -:1022800051C49CFAF69929B0C9FB966BF88B2027AC -:10229000877FE8D6C0AE5EFFC3D790EF4E3D734C4C -:1022A000D1717F9AF804AA274F91919F41D09B1B2F -:1022B0000556D8F4983FE10E24D76B63BCBE560F89 -:1022C000E0FB37F07D9CF1C3C678FF6A21C5FAF9BF -:1022D000E422A69FE2D988970DFAA0A2F9ECEB2A96 -:1022E0002C84F57C6319D0DF58EB69CE5F83F92F1E -:1022F000B0ACEB638C8FC7E2D753BD6E59481FBD9E -:10230000CEA7B85DB1292EBC966ADD096965F1BD1D -:1023100031E2DEE6D349178A6CE773B3BD39FF8932 -:10232000F87CE2795D1CDECE707DEDC4DF3BE752C8 -:10233000EB812259E07AABA736D7A2EF3C2EAAC791 -:102340000AC1EE6C8CE51526E1EDEC9350BEBFB3EF -:102350004F427BDF2927368EE1D787CD710EF5CF2F -:102360000579F6CEE1EF737A64F4BEF1C01B4A8CB6 -:10237000EB85B8552F407F29D6E372DEDFA6E75202 -:10238000F7B7E9C0E994FDBD2D1B5F00F8DF1E74AF -:102390009118EDE2ED3E29659CA45876D9ECAC4E3F -:1023A0007FE58974DA4E0A787598775BABF15A0C41 -:1023B000EC91975D04ED4739FC969B7E6FF37B7142 -:1023C000BFA52D7023D12DFABBDD81273914413FE4 -:1023D0005A0E462AD85E68DCE6CFBA34D106379169 -:1023E00063F9B0CFF9F3C2DFCBD02FC4D3744B5C09 -:1023F000E8259974403CED254308B79014712D47AA -:10240000FF914512D1AD74664C15ADF1C5C0E1BB6D -:1024100030AED1441A13106F22F9A46FAFA5DF4775 -:102420009A7516778D4C15ADF13F7763A3E1A670D1 -:10243000E4DFAE1581FF36D6F8058DF67D5F73FCBF -:102440005B793C82EC7BF2C92769792A7C13810E87 -:102450002306C2718EED2B2FE5F2F047DC7E3E2C79 -:102460009001B0C36AEF8DCA20EF84D0F518175DD4 -:10247000967FBDBCCE428FCB42A77340AF7EF3CFD9 -:10248000D29A54747A88D355CBDF3F9E03ED777B85 -:10249000BE90CF9CD908C297C7E35D03D9CB7D100E -:1024A000DFEBBF69D98B33E87C73358940BC269755 -:1024B00054F9CA289C79C7A5B027C53A98CF3D3CA6 -:1024C000AEF768B386F2FFB1E610961FE778DDD766 -:1024D0005C82CF279BC3F8FD40F3422CF735D7E24F -:1024E000F3E9E608BE0FDCFD6CBF0278F92AE98348 -:1024F00078CDC1E635F8FD9F9BA3F8DCCBE7B30CA4 -:10250000F0E2B3CD1FE33187DA97B4423CC6C4A3EF -:1025100013EF4B486CC08DFBF9820E78BF4B66F20F -:10252000C589DF29EE3E01E44BD32D04EDD73D3CB8 -:102530006E6CCEF7EB32B3370F72787EE0897E4750 -:10254000A6CFF76A8B4BD12E229130C8EF3D4224A3 -:10255000BD8C5679217B41C82A87A7FAA30765CB92 -:10256000BEC2946E16EFD92D337935553FDD9F41AC -:10257000F1509B2FE8104E30E77BB84ACF073979EE -:10258000581070BD6BF3255262A17BB3BF6FC82298 -:10259000DFDF482DB79374CCE441E6D57209F8B576 -:1025A0006788372C517E7F3E871C24D4FE781EE836 -:1025B00012E4C2AFD2304E6CFA37DBF87A670251C0 -:1025C00040BEC4EBFE38C89FB1FC9E4E5EFF3D0E80 -:1025D000D70639F28A8CFBCA3CFE4A1218C784948B -:1025E00023A0C7DD9EB53B6AE8F3FECBDF3E01F1D9 -:1025F000C1779FF1E800D7F68A93012B1E4983FC2F -:102600008E753F7E44DE9CCDC3B8D8FF27D137649A -:10261000AB1C0A0E2BD0FE7941DF09FBD7B1572541 -:10262000E4BFE785F82C8C63C904FD82E76F0A617B -:102630007E87D9CE1FB6F377A667E8E14D30EF0667 -:10264000251C4BC117BF49D36DFB46EE90BD7D08DD -:1026500074E67C56D6297D96F1798765430238E683 -:1026600093283E17101D9F39AEE847308F79A42F6D -:1026700007CAAD6953AE60FB07FF6378535DFF0780 -:10268000F166D26BE8F2128483DC2D86A7EBE84D6D -:10269000DAE87CA54BE0F855519EE78EEC4F35FE0D -:1026A000A82088DDB0388996867230D7C3F0D73439 -:1026B000741AE3BBA129C41677EF6810910F76BF97 -:1026C000CEF6F5CE3414ED9C41EB57117D474DE12C -:1026D000E87998FCB15B8DA4A7DA9F329F265F98BA -:1026E000E59D53BF48400EFDE3D42F62DE51EEEB73 -:1026F0001E1DFC8EAA5FEF6F01B9D8F106CBAFF8B3 -:102700009537BAC8353F29673A6E6A9C0A7E50C031 -:102710001F59ECA2F889E4C7AF037977A6F676379C -:102720004EDDC7F25E9AEED577CED4C75E9F3D4DA3 -:10273000E3EFDF98F3DA03F31A67FFC29C97B95E01 -:10274000676A570FDFA8839C294E8FA66837224FF0 -:10275000AE5E3DEEF87BB85EA1F35F6BA5CF294D71 -:102760001AE6B798EDCDF93ADB3BE79BDC07BEB044 -:10277000BCA03E17C9027AFFDEC753FEE925148DBF -:102780001109F434E5CF8D004F2569C43291FB72F5 -:10279000C0BE31E97977E7E339A817E47821E67715 -:1027A0005DE0781D2412A9027E0B8B61ABBD623EF9 -:1027B000DB46E83C81715537970362DABDA1547856 -:1027C0001EE93FDFCEFFDB0861723EA1A29C87407D -:1027D000A146CB854749F97DB4BF06480AA5E35415 -:1027E000C92C1E32EFA8DE2BB1B8AA54EFB7E09186 -:1027F000EF3798F1DD0E722FD174F02BCAFAA1BA1F -:10280000C9A74794E84340A74A48C77C4F57302A96 -:10281000B0FD38B63F54C2ED92ABA4B52AD8254DD1 -:1028200024A2CE06BE3D2E119687C7F8DA6DEE8340 -:10283000713E76733EA61C8CE519FCFB739CBE0EA4 -:10284000817D82F604A3A383DC3EA9191E3EE2A784 -:10285000ED4A067BAA613A4F83BDE206FB248CDF7A -:10286000BF03F60A2D1FC9F8C76B6653BCEC33C40F -:1028700030E0FA40B3C1F8A1B901BF37919877337E -:10288000C8A547440DE0EC7AA4550AD0F27E55C0A5 -:10289000F8C523CD8D583F70CE9B007F73BF9A1033 -:1028A000C01E391326E118C04DDD2398D70C3E8F8A -:1028B000AA370771BBFCF1F87BBFDD41EB3DB8D017 -:1028C0008BFB64267FCD681AD6AE01BEDA7B52DF61 -:1028D0000CF0CFBFD580FADBC245B84FF104C51765 -:1028E000ACD3BE5DEFED1AA4DF0372D766F0836749 -:1028F00016AC427B28A0FEE36D500E684FFD1D3ED6 -:10290000D5EFDF09FA7A665CB4ED9F07D49FDE0548 -:10291000DFAB87C235E9B49F59C707BBAFA6CF8EDF -:10292000F0ED2290787AE61F705FE3B0A07DA907F2 -:10293000E26AD72B48AFC609A305D8D15561CF832A -:10294000CC7E310A690B64F200C53B01BC1B32F43A -:10295000FB96AB10E92C14C8A909D0F2E38F9DFCBB -:10296000F1D5F4FB915DB7A25C743F22A33D36F331 -:102970001BB793AF58E484FB3139655EE95B2E37B2 -:10298000E3A34756F7CCD2197902FFCDDA5BA3A2B5 -:102990009C78D19EE760EE0BF792E85B2EA4676609 -:1029A0009FC81ADB47863D2FD84F240F8B8C4F22B0 -:1029B00051AF35FFB9E4EB6224559CFBAC4BC679B3 -:1029C000B5C76B4A601DE4F377E03E19E9B18F6F3C -:1029D0008E47C73F6B956FB2C6E02A00D54FD7B37D -:1029E0005FF9F71C80FF6CA3A9A712A8A706CAC4A9 -:1029F000C4540ADF030F897148CA3C52CBF4D6761F -:102A000099E50B6EE7E5C7CE91B85098E4A3999C81 -:102A1000DF1E7B4464F65C9CA09E23E7CEA37DE191 -:102A2000E3DF33CB5E56717F2266F8AA2A312B9002 -:102A3000FF58E885E2E8D298D72667C5A64CDBFAAE -:102A400017508BC59E4F5D94AC2F811C3FAE02FD8D -:102A50009EA17E2BD0EF12BE4F5463E6614AE7E69B -:102A6000C1FC1F36F5AC9937E3C893DEDBB8CE0B5B -:102A7000F1C2174CFA696834D0FFD1DC389EB94FE7 -:102A800058724B2406FAD3956FCF9FAE72E4472F4E -:102A900071942F36BE52AE38E3A8DB66211DE801E3 -:102AA0009457C51CCF7B2FA3EE7CFAE838CB48BFE8 -:102AB0003C8E407A02B87EC59C80EEBF5B6A00BF48 -:102AC00020F040798635BF60B9C2ECEE815FB9096C -:102AD000D8F9FB6B548C679A799D2E3EEE0A45C758 -:102AE0007AFB1FBA4385F65DC1220FE0EBC8E5EB28 -:102AF000BD98FFC1F3534DB9DB7AF9FA6B6E0279D9 -:102B0000982DA2EEE9C86FCD857DF9076A54CC3FB8 -:102B10000DA40DF51DA165DF134AF851FA7D7F550F -:102B2000628D356E7387C2F4D7750ADF07DA66CF18 -:102B3000DFA07C709D02F961BE46DCB714559EC7CC -:102B4000EBF0EF4D7C040E5F2716FAD9B3C80FFEE9 -:102B500028A38F38A78F3DDC3F7D04E4BF1BE886A8 -:102B6000C9FF6DDC3F75F63BBD217258013BEC1689 -:102B7000AD1C4251CEF59DD66DB7270A6376393725 -:102B8000D549F78DB9B6FA790D45B6EFFEF06C87E9 -:102B90007D92607A8DB0F5E9F2F8A681DC2EA77AF5 -:102BA00097D9199A18B1EEAB38F47A83CB68562EC0 -:102BB000C2BE09A4451A617D9CF6F456BE3E7F2331 -:102BC0001B5B94F9E8BF6D8527B58F79BEBADDFE32 -:102BD000180527A170CE1917CE872E06CE89F6D9F3 -:102BE0009CFB6B774A915D2FD1E7E274960FD9E198 -:102BF00067FE7C07C45169F9594E874F2912F67F49 -:102C000088CF77711AAD9F82BFCDF8EA73907803B1 -:102C1000F526A7CEB3040B08BFE7A5FEFE9CC2F6BF -:102C2000B3174F1D7F9CE7611CFADCE632BEAF583C -:102C3000E278ED8AF1036B39A1B0FDE79175E17996 -:102C400094A63D7687CBE8B7D64F3EED72D3DC072E -:102C5000C9E6EBE9278CFF5E58B36ECB74CACF4A46 -:102C6000BE0FED9FEC35ED9BC500E41F0D6AE00F34 -:102C700064F37D7CB29AC951735F3DB3CE2E579DEC -:102C8000E7ADDC3C2FDEED3C67C3E5AB931EC7929E -:102C9000AFBF56ECFB1A23F1EB31E8CA19BF6E82C5 -:102CA0005F999DC9EDE048FAAA3963D3E3CF9B87CA -:102CB000B70F4C4F965F82F33329E980ED27060E5C -:102CC000FFA16E7505ECDBB178DA607362F19BD31E -:102CD00093F22BB228E305887B466A3250DEAC08BB -:102CE000FD71FB00F5C7EB8DFEC56F5AE639A851A3 -:102CF00068A78DC32786EB232B7F3D2130FAE9E0BF -:102D0000E3EDE0F874DAD15D62CC0DFD7E40860C17 -:102D100021855F6B9D773BE26DC8077436D6BCC3D7 -:102D20006EC65781858D6188D3B9CF4BC807EEA990 -:102D3000A6DD1246BB659E3B839DFBF015E13E1E62 -:102D4000F5D387FB611D7C2CBFDFD48FEF9BF15443 -:102D5000AEF76ECB60E5ADCD2C7EEC3E72D96B3A12 -:102D60006DE77FD1453CF4FD162AD7210ED84DEDF5 -:102D700078F81EA8182210476FA3F5A316BFBB2D25 -:102D80005CAD819DD05E5AAEEAF4BB34A702CB7233 -:102D900061B9564DC79CEDFEDAD26C8883178B98CB -:102DA000575B4ACB2DD4A44B776B38BF9F97BCE9B8 -:102DB00003FB2C1D9CF3F9C9F57455440D89C2E33E -:102DC0000A69D5908B31A2B7399DD1F78F42BCE407 -:102DD00009215AE9A6F3FF393F7FD5A53496DC0ACD -:102DE0007E8F1C7343FCA04965FB10400FEDF392EE -:102DF000702FE1F855F8B8237E105FCF0FE4A118CB -:102E0000A4B67689A421D5FA5CED6672AE5D33B4C2 -:102E100071E949933FB2E54F2F62FCA404293DA517 -:102E2000883F3AE5357147EADDD9C97C25BAB01A41 -:102E3000F22961F69E79BEE74DC5F89C9BCEA3D5DD -:102E4000C7E5587E26D2297DBFDCFB89E43E8BCFC7 -:102E50001C5E5471AC06FC924117C68B02D3C8DFCE -:102E6000462CF2F6A81B836EF4C9ECA4FB287DC4A3 -:102E700067B2B80401BA49A38A18F6210BC4F8A3B3 -:102E800085006F6FED34DA5F973C9D5AE6C97EAAE4 -:102E90000A98FDBFBDDADB60F503DE4D63FB2F77DB -:102EA000F9AA9E86F995FAE2D5E83E4376E62476BD -:102EB0007E0AE8F8128D0C0922C8C108617A33AC89 -:102EC00032FD5AA3C179298144C9F9B4F1F4A3FDB3 -:102ED0005CD59372BCD50BF808B278977F9780C900 -:102EE00080529F91F08298F4AD6A77337D5102E36E -:102EF000F4577A898FD6FF63BF82F6619F3F4F06F2 -:102F0000BC3E2FAEFB26C49F867FE9C6FCC6BE3FF3 -:102F1000CFC6FCFB3EFF15CB406EF709E42855F603 -:102F2000A4EA6C1E4F362469B0CF17586A10D8E750 -:102F3000187E8184213FD815FAE9E237E7E1C4D34E -:102F4000C485B49D87747B68BBF047DEF79750BAA1 -:102F50007ADA57FEE0A524195731E329CBD2A20F24 -:102F600003DE3A26FD5B03F04D37855342FBD5085F -:102F700001DCE5D922C61F49B62F3E1DE265478315 -:102F800035903F5A2597616A6C60295BEF5F79A3A2 -:102F90007B61BE355A7D0DC4D72B8EEB2867978594 -:102FA000360F40B9F27556EE5018BF40BC8858E451 -:102FB0006ED5D92938BF3E4E27ED2163D010C6E526 -:102FC0001BC7B9037BBE9C950E20CFDD42075197EE -:102FD000950E16523A9863A50343B8183AF82A2A70 -:102FE000EB4FC23FC66B3542326E379A0F36AB9904 -:102FF000A5A3F9C584E3BE8ACC20C851932FB4059C -:10300000F7A25C755FAF44C05F37F9C4E48F8F3DB2 -:10301000237C12017E5FEDD3AF4AC527E08758F9C4 -:10302000E1DA31F86605191E08D2462B64124BA767 -:10303000A2E4E797BD553CC5C2074EBCAD582490ED -:10304000933679C6CA16BC6A23E71BA50BC7FFCB0C -:10305000B2DE11B4F06127F543C058EE16C304F494 -:10306000CA02DFBA3F025DCA75DF0B813FE87247D3 -:103070001A306F76C13B693752BAFCE3245187C9D5 -:1030800077E8EBBE8BFC7C228D807DB2BD723DC6A5 -:103090007DFF7853742AE8892D14FF27512FC72705 -:1030A0008B9883393499EDB7EB21F68C86D87BC2A7 -:1030B000BFC779D9E0F586B01E5D679B7CDCE16116 -:1030C000FB5D3B3C4CDF6C517A54E0B7E142554B21 -:1030D00095EF5CA9B2FA4BDCA4221CC4D1705FB995 -:1030E00043956A7B599C2FB184BE5F32ADE451EBAE -:1030F0007E81D9EEC1E63EB453B6341FC267565D39 -:103100009C40DE95B724A6C3FEB8FA97A5820BFAB9 -:103110009DCDF671E17D8BC54ED355C69FEA5FA468 -:1031200028F0B1DA1AD3332DF2581585682A7B7B43 -:10313000A787C569D45682DFD5C35FC77DEFACE2F0 -:10314000B0F06528B7F69030EDC79360EF83C58681 -:10315000F0254BBFC1BA3E9B3E5C41972ABD1CADDA -:103160002C3C17D3A17B719F6C45B0FA0FF2DCD1D8 -:10317000F4063F272D7463C26FEED7DECEFDF49ABE -:103180002215F9B4A349E9C573302AB39F3E085606 -:103190008F7BAE00F669A98587FE303C61BF36366D -:1031A00093EDD74219F66BE109FBB5F084FD5AF8AF -:1031B0000EFBB550FE4EB38165D8B78532ECDBC649 -:1031C00066B27D5A28C33E2D3C0F3537E0F3D9E671 -:1031D00046FCFE5C731396293DA0FD474A6221B070 -:1031E000ABBBEF520CC8C7E9E2EB7EC428CA027A37 -:1031F000F104593CC1F3E203782EDA131231BED741 -:10320000197A80DC409FDDF3FDDD101F51BFEBC359 -:10321000A7477E9080DDB64788359030211BD58A40 -:103220001A99DA13C5A1CDD59961C0DBE5ED909F60 -:1032300038436F09AFD39265DD5FBEFE7B96F2D453 -:10324000D25ED94BEBDFD5BDA81DE406C0019B6B58 -:103250006DEA929A96624AB445D4A001F957A8C47F -:1032600081EEBF04EB351DE06776E067485B08E25E -:103270001F5375A51CF895D64F303EB9B0FA5DAA1C -:103280008EEF9DEDC6AB27565C503D228DD31F7C43 -:1032900017C6E9A783B4698314F6AD205BC08EF22C -:1032A000B0FDE06E179313DD1EF6FC9DC7DC0FAF7B -:1032B0005EEEA1CFE51EC687DD9E482D9C4B199E74 -:1032C00023621CA8CF45BB80430A4D85AFC0F9A13E -:1032D0003B7E2213D867D8C3F976FA543FD3E7F779 -:1032E000A8A8CF974FFD767B262D4FFF56380CFAB6 -:1032F000792B097B814E62DB985C79AA625A663D24 -:10330000AD7EC9FC6732414F7DAC32BB36CEFD92FB -:10331000968E1BA742FCEA8FC7989CFC361FA7D746 -:1033200035D888EB39DF87760D752CD06E6909C9E1 -:10333000986724E6B0A7E2D2FE0AEA29D430885181 -:1033400078943F2F50314E72D6CDEFC118447B4652 -:10335000F144B50CFABE272622BFB769DE38D8DFA4 -:103360005B7DE578FE34562AE33994ADA52CCE9AE0 -:10337000E6FF7C1CEC981DFD1E261F7C2AE699C6E4 -:103380004B0F1EAD0EC253D480DFE3C6AA5AC4BB96 -:10339000266A98AF4A7FC3EF0D413CB7B295F075EE -:1033A0006910F1DC5DC7A48F7E7A29E4EF7C590BAC -:1033B000F3BB09301F1C4D3311F68D860FA7013C5E -:1033C0007F63DE6B30D49A46EBB7AFD3C2B00E73D7 -:1033D000B5EA5AC837E8D0AAD11F4A9B53A35E8FDB -:1033E0007268E4DC06DE9FD15E2A63BE117C07BEF4 -:1033F00024ED6400CECDE771599696512E801DD6EE -:103400005187E14038D760CB3F6FCFBC06CF2B4907 -:103410002B3211CE0E62A8503F5627A39ECCF3A9A3 -:1034200009B04BF2CCB82F1CC5B0C425B26EB19F09 -:10343000E7C869906DE7C72747EDE56C1E67C8765A -:103440009CFB38CBE9C58927E77CB3828F6600BC3B -:103450005970E0571F3D9F0783E5F530CF3CCD8B7A -:103460007087B4D62A905F9349630BD0DD45C3EBD8 -:1034700080736E69FB20ACFB5C5D263A1DFF523207 -:10348000DC0AFD6EE574DE5D68D7DB7B54C9E4C7FA -:1034900030F0E3D42691C42CE343BC3266196F5A52 -:1034A00077A6AD3CBD27D7567FE6AE22DBF759F1B4 -:1034B000D9B6EF97EC2BB795E7F45D6EAB7FE9A13A -:1034C0006A5BB92C718DADFEBCA3AB6CE5F9837F53 -:1034D00065ABBFE0C43ADBF7CB86D6DBBE5FF1D687 -:1034E000ADB6F295C377DBEA9B76BD532FCEE6F6F9 -:1034F000CDC5DAF36EB84FC216BFB5FB0B4E7B5F7E -:10350000FD4B9BDE0A722DA0207DCBA0C769F9D6AA -:10351000BB98BFA52E0EEB2057742E47A9185C0050 -:10352000EB561550511FC83E564FF62D43FB63CA4C -:103530002E2A8FE681554A46BEA7815C6E8E2D2EBF -:10354000B6C4A53C5A0F9EE1AA0AD4E23E88D95ED1 -:10355000D60C12F5C3783AB37BA8370BF53C3A6D1D -:103560006F99D7F3A28847A587A95FF8A8C52F1C34 -:10357000CB0F74FA7D17EAE74D118917CF1F089119 -:10358000467896361EAB86B461EAFFFDB587F2E752 -:103590007625D2D04BFBDD5EE465FBA5DCFFEB2E90 -:1035A000EC43BE182E9451BF10592FB5C6ED3AF911 -:1035B000FAA6A94FA1FF49F18EF2D6C4FB566128A5 -:1035C000DE0672E72E2FCAC329BF71BF0CFCA516F9 -:1035D000A9792A7D1F3EA218B00FF520C76B91561E -:1035E000560DA1A7E250FD6178CED0A99D419F253F -:1035F000253B0FA35AF314E178B3C3DFAB0659A2FE -:103600002E66F69F3C5789B7D27E248DC291C2FFA9 -:10361000309F526017DBE728967F07F406D6FF79C4 -:103620003A85AA4C15F3423C4007023E917E3C414C -:103630001FEA0D0F1C8285B22CC4619F10EC53D879 -:10364000AFABCADC85EB6EDAAD60CF46993FDC09E3 -:10365000780DD6D9D73B4DFD0EE2A95D60F1F1EEB4 -:103660000CFDC56A3A6E77765126C462217E526F90 -:1036700091373BB83E8D7AD9D39437B891333F69AF -:10368000EF50FADF254E03F87A08C82DCFBD3D0470 -:10369000E8DDA3D1D544BB3EA647509F327BF73629 -:1036A0000E534DD11ACC03783F588EF6ADA7E9F9E9 -:1036B00094F8F30C49C49837365E033376A3BE27DB -:1036C000458A0E764593AE18BD29E4C15C95FB3959 -:1036D00053CC73AF2C0FA89BE3C38C9B8EC4237970 -:1036E000DCCD8C479AFDDC965D3E793C7BDC43FD6E -:1036F000D0A805DE2D741CC04BC7B9FA5AC4834C40 -:10370000D8B9DD3F97F6DE87FBB16D3AEC37CFE5F0 -:10371000F67225E087E27B8A42D04F580AF1952C59 -:10372000F07E3F530B7C69C663863CEC1C773846C1 -:1037300024167F73997A4B3C7F29C2AC2B661E19E5 -:103740009ABC4CAFD17FFBE17CD9B46EFBF9CDE9DB -:103750003DF6F2CC5DF6F2ACB8BD4CADE6E36017D9 -:10376000808D86F18D7DF6EFF5E6BE410D3B6FA6AF -:10377000D291CF33FD6BBB3F8770FD6FE6BB15F475 -:1037800025AA40BCE6DF6ED7ABB95CCFE73AF46759 -:10379000B95FC2B843D5D1E000D88F667CE8575EE8 -:1037A000DD967766C6799CF2DCFBFA4E42BFA0FF3D -:1037B0001E75B37807C4913F2CE071957C1E579914 -:1037C000C2E32A052CAEE292F497D60A9827FA3E75 -:1037D000F20569BC94C573D8B9AFF76AE517049DC3 -:1037E0008D17B58C7767496C3943433C07EA99F1EB -:1037F00015337E10F01BCB817FB7865F6E3C42E9AC -:10380000A4FA976E02FD5C25BD78B419E45B818C47 -:10381000F9DDDA825BBEE98578257CA7E5EA427DA1 -:1038200032F2C18F5D1847E8E2746D9E5734E33180 -:103830009A97F181CF6BDA47312FCFDFF782BD7BCB -:10384000C93E2AA36DFA8EC5FDCCF8DE9C3EFBF77F -:103850003E226469901FB0262E32FBCAF05559F201 -:103860001F67F3759BBB36F1C05A5A3E40E2E570C4 -:103870002F5D19A78FF080FD9CEC2422E039A94927 -:10388000C7A5709CD69FFB9CFD7BA9E31CED6CE754 -:10389000B95AC7FE915F22A7AFA7E36DD31B05906E -:1038A000A3DBD6525B9E966779F9BEFD0C3203E826 -:1038B000F02AC9174E007E5F95701FCCFDC6CCD78D -:1038C000AE07BD7E8CE52769D3F49D106FD67E2AA6 -:1038D000A19ED2D24859992FB9DFF40FE7C304F65D -:1038E0004FCCF8D793745D41AF1CA07E79B10BFC2F -:1038F0006C0DCB7DD42F87F2D3D42F87E741EA9785 -:10390000C3FB7FA67E39940F51BF1C9ECF52BF1CB4 -:10391000DE3F47FD7228DFE5ABC278F920AD0FF43A -:10392000E22D3BA84EAB0039ECD2803E9C72A8AA97 -:10393000EA36753525A92F743D85FB1CD557B17C1A -:10394000EAE5F73D85FB1CD6389C354E998CC30DB6 -:1039500009661C0E42A3BFE6FB1123F1B8288BC7F2 -:103960004DDC8F61F683F1CF51FDF038E8BB77FD78 -:10397000DBE36DF4D386F90F747B8BE07C47238FF8 -:10398000FB99F933BA2D3F7FC3C116CC9F51728E7C -:1039900037C2BA1EACF0615E89E28A6A206F9DFE72 -:1039A0009CE9C739ED69F3E9D46F7E6E5798F1D57C -:1039B000ED2E82F9D43181DA13605F34C717BFE985 -:1039C0001A3BEE7AC25BC4F3F8EC7261E41C018F1F -:1039D000FBB8C19AA5F354048E0F9EDF8EA2B18866 -:1039E000C5FFACF1576F711C0FAF7B7D06DA750216 -:1039F000B5F7D0FED3A22188A375C2B98114F3DB39 -:103A0000CBF9BD2547417BA33387E58BD4E48743BE -:103A1000D0BE2DA732643D47609E7318F057AA436D -:103A200096FE6EF5178DABFF24AAAFF571F4B5E4E1 -:103A300066E77CDA0E5FA6C2F98D6EDFBA41F0A3AD -:103A4000BB43418CD3F7E75492214BFF5268219E30 -:103A5000F3907CCC1E96422ADAC332CCBF3459DFB5 -:103A6000ACD7C2E53E65678C2F7A7C3D58CF2D4799 -:103A7000F07E09771054267D6A6CDFCE5B2C12D560 -:103A8000222FCC71EFF63279D95D1AD520CED21D16 -:103A90009275382FD2AD97239EDB389EDB0A4C7B84 -:103AA000228C76CCF7B97C35FB69E37180B60605CC -:103AB000EDB948538656938579BDDF017EEEF6B5A4 -:103AC000AAB07FA9E4548CDBEFC084FD964DAA997F -:103AD00087FD7E1FFA55FCEB34E8D735C6F9A463A1 -:103AE0009C1E3EA9DDEADCEFA3D086AC792BCEA7E5 -:103AF0009FDB9FCE761B4A871458F72D8FD9CF3383 -:103B0000BB083BDFB5F1D066E4F3EDF220DA51DB20 -:103B1000CF0929CF8985D204CE6F23FEBDCD0ECA31 -:103B2000E3FC94C7BF03A981BE284BD8ED96794723 -:103B3000EDE5F983F6F282134E3BC87815ECA0D57B -:103B40005CEE0D5279CF92668665C0472416AF02AF -:103B5000B8EB495F0BE453B8249617B29AEBBF95C4 -:103B60005C3F06D23210FEBC06AFCDFF24FC3EC047 -:103B70007CDE7F41CDC0E67610B211D3AED2D16FDC -:103B80002DB8FAE92A14970EFBAADEB09FF75FE979 -:103B9000B09F9C765695DC8B79BBB98EB886B9EF11 -:103BA0000BF3847B0F9CE35FECB8667F90AF05F26C -:103BB000CDBC0F06EF1FA6ED0BE48410A678CA6DEE -:103BC00064E775F26E27466F0A3A5EC2D77D14DE4F -:103BD000624B106F4BF9BB5C1FBBC72BB7468AEB20 -:103BE00074FCDC863EB40756DD42E78376F879CC78 -:103BF0009731EB6766F4E1B9A5DD7502CFE325687F -:103C0000D798EBBCDBC7CE19D65F29C44568DF580F -:103C100084E3235C45C9F5A5783AC9F0C4F212AF34 -:103C2000ADB59F87AC77D82F263DAC74BC3FE96516 -:103C3000FBE7261FBC7BD9891953281C1B849EDAFD -:103C4000B46917AE2F2DFCE13A0F7C08BF4F6229F3 -:103C50003298EFABFE9386E74232861E269424AF5D -:103C60004D23B19A4584FC8B77F8128196FF6A6BDD -:103C70005F4777011CF31E7E0A8C3C77D73357D5FC -:103C80005E992C7BEFEBC772908F035B906CBD2D20 -:103C9000F7C350D4C5D3187C5B0DB253821C5C5162 -:103CA000DB192E4CB6CB8476C238ED2264A79CA2D9 -:103CB0009DCF6C47D1D509F73FF17979F97791C359 -:103CC000631D5F06BC69BA0FCF3B2E9335D8BFFA90 -:103CD000B4704C9A68DE51B2D3356D743B0A768B62 -:103CE00009BF981AFE387CB78EEF1A07FEFF6E7C6C -:103CF0004CD49FC2BF5F347CB47AEBA4B1E70B70A5 -:103D0000B9F05E22DD275AFAD9D1FF278C8BCBD7A9 -:103D1000913084BC6497A1C17E5EA9F610FAF77257 -:103D2000468D0676C0165A063B604B5F0FC6BF4BEA -:103D30008B1FE806A22F4D7809C8833944CB384041 -:103D4000FB9DA3C970028BC8570E88104F279F2573 -:103D5000985F92DEEF65F708155EFE2DF0B7323200 -:103D600054DCCF48CBA8FC16337A599CD9843FAD9C -:103D7000EA7835C4DFE57A1216002E214EAA80C9F2 -:103D80006611DCDFF01A07EF84F3024466FA09EFEC -:103D9000D201BDCAE3ED9319C9906E45ABC73C97FC -:103DA0009FC818C79A0C578551A22C2DCDDC09F05D -:103DB0009446690702C0CFE26573A2623841FB2FC7 -:103DC0003FCDDA919FB17326D43759F38C2F8957A1 -:103DD00053AE4CE671F8D05A7B9C9A0CD339D3F68B -:103DE000E53F5BB517E2149346C96FE6B77B399C94 -:103DF000E9A74904FA0FD6D9F58697E7797B1DF72D -:103E0000CC54F85DF6FBA19DFEC35723A807DC2424 -:103E1000AC2A685FAC45BBC1F44B764345B0C70BD9 -:103E200008BB97D7D9BE92B52721E6A7B8BD4455A0 -:103E3000CBE9F7F55E03F312DDB44CF1282844CD4D -:103E4000A1EF7345166F6911880CE5E47809CC473A -:103E500070AB9F6907FBE5B03A0FEF4F33FDEA36D1 -:103E60002D8CF912A4A4DA66379B7961B796154DAB -:103E700086EFE99346E24E1AD0E5ADD9C56847070B -:103E8000B286FE1AE4ECB9ADE9CB5490AB90AF71B9 -:103E900039E4477B3B6354E9BBCFE611DD629FB950 -:103EA000E5468CB3B9CF4EB1BD4F34DBCF5B1B3E83 -:103EB000B106C699EA637C5845B476685745ECE785 -:103EC000AADD67736CF67AB2FF7CDBFB04B56BACE2 -:103ED000F7008DDD7F1AD14BACFD4F1BA3FF198E70 -:103EE000FEB594FD27FBCDB2F5DB21B3F86B2CE8D2 -:103EF0004D792FE5025F75311C951D6B7FA0D2C7F0 -:103F0000E29A5DA146DC1FA82694F129BD2C3977E1 -:103F10005262E77D09DA6F24DFBE3F50CDE958A435 -:103F20009481E70764FBFDC68B89F3BE63BB5DF438 -:103F30004B8839507C89FE8A41DC27F8930FCF03E8 -:103F40008E65370F36138C4F2F4E1BBA0DF6C157A7 -:103F50006ED3958E10E63DA33FFF37DBE62F033B84 -:103F6000DFBC07B32328225E22D593F13C97D94FBB -:103F70004421D3412E46449607813F74FCC1EC5C3A -:103F80005BBE86F9749E87AF3784C5C596790D42AE -:103F9000FEA175BCA579BD92651E1137998FE3719D -:103FA0007B7764BC499F6CBC633C9E658E57BFCCDD -:103FB0003EBF7A45C3F9D5733E36C73B06F34B8106 -:103FC000DF09C7E3F99523E32DB7CFAFDEADE1FC01 -:103FD000EAF97DBC23E34DFA64E399719D2EA5B106 -:103FE00011E870ACF88E19D7B9B66BBF2DAE43622D -:103FF000FB97561513B25360F223EEABEE04BA787A -:10400000BFEED612D42BDCBEC67B57A93E5E293349 -:104010007857E4FBE22D163CEEA672C49809E72916 -:10402000540207CFE07C8581E72D42F87C94DAEBDF -:1040300006E69794E0F7C79BC358DED7BC109F668F -:104040003F250BD9FD60B3160929EDF6133EE67F37 -:10405000EECCD1AEFB12E8B72A2FCB0B5E78053140 -:104060002C763435AC0F7B607FE8F3A40C74E48CC1 -:104070005D0CEE60CDA438ACBFB76C60B019E2A0A7 -:10408000B24BC7BC583DF5DF3B78C5C7FC79B79B41 -:10409000B52757B07B525770FD44A43ACC3F5AB174 -:1040A0003203F31156AD36FC1AC5DB6A4178B59878 -:1040B000EB3B381FF539BED44E7F21089A87AE57A7 -:1040C000D090E2708FDCE7F25F5C23D07E23FE6B42 -:1040D000D1CF88D08699B49FCF717D5BF5869B4008 -:1040E0003C825CA5A0FC5ABDDAEE17ECF42434B097 -:1040F00073769605490B6DB7AACEFEDDED667C158D -:1041000071DC13B362827B63CCBC5C277E9C71D371 -:104110009FF9ECF1D133A474079E0DE3F9BBCEF601 -:10412000661CB4DDC7E45B97C2E4C3683E60F0BCC4 -:104130000B7DA3FF7702E368267CB9725C00799F50 -:10414000D770C2961F4F118B46B5B94F40A4036577 -:10415000A8871DF3D92D1CC819EFDEA85C22FF6EBD -:10416000A884FF7D0361F4BCDF1935EF452F15935B -:1041700054FCC3E2C12B8E4AE1163D8917130FFF91 -:10418000DB7CB4CBC7F0F9D2D20F2A981F986FFB13 -:104190003B02E639AF6B47CA32912DF4BC72BD6267 -:1041A000307F75B814E8F2F8956961F6F730B81DFC -:1041B00094F8A50876D0A7EFDF28B0E53FF37EC7D7 -:1041C0005A2F67DEA5E55C72F29E04C87F690987F5 -:1041D000D01EC81609F0532EE4E305D8F79376BB3A -:1041E000D5968FD7D6BF5F80B8E1C3909F68398FCF -:1041F00097D7D02774807DD71267718804AD47E1C7 -:10420000CE6F4808EDA5C9BC2FA75CCFBFC59E2FB8 -:10421000D8B168B5764087BC9AEA1EB8206CCB2E20 -:1042200016E732EB8FC4BBF83955176924704E433B -:10423000F2B1787388DFDF31519EEF87624C2B2C0F -:1042400084FCDEB85A45E7BF272BBACC4FFBED0EF6 -:104250009637F6027DCA61CC075FDB744F04E284B7 -:104260005A56EA38F85A6E1FD4FB195DBDEE4A144F -:1042700040DCFCE5ACEA7A7F768AFA4D5FC5FE1633 -:104280008F712FFD7A3F8BCF3C2CA6960737F0EF2E -:104290005FD820E27D431EE2C773AC9EE29E85801C -:1042A0008F8737EE0EA73A8FB9508BAEF35BF0EEE7 -:1042B0002966F70510D27719CC73CBC78FF47D9799 -:1042C000CE3BF3631FCAD94C89F56B69BFDE3A1F39 -:1042D000B3FDF37FFA059EB37F9EDFBF4EC8F4E5C2 -:1042E0001067DF3E52263138E8BC3D839763E272A7 -:1042F000F02B93E5E796554119689412DFBBFE97C2 -:104300003AE1FE9AED02E1C43AB80CEBF3FBDE7F32 -:10431000C2BF2FBEE69D6FED007D50A9A0BFB99D25 -:10432000DB3B267CFFE967793FFFC9D7652C7C6EB4 -:10433000E3DF7D80CFE045E1735B2A7C7E26686CFD -:1043400087F71EC804A120783E566F87BCECAF37B4 -:1043500093C897E81C1E0E1FDC0F678F68FB8752FF -:10436000B5FF4196F1353FC27312E7E72FF685019D -:10437000155B1610EC27051CDF186F5DCB33989C7E -:104380004B4B67CF4C6E5F4AEEC110E42F6815FFB0 -:10439000709B46E54C67E1E09A5471E2A702CCEECF -:1043A000CF18232E7E98E3EFEACCC8B701EE76ED66 -:1043B00001F4F7148144A0FE96854344B0B47B23F6 -:1043C000C0E897C2FD0CC0AD5CC6EEB1F653BC436D -:1043D000829CBF82C1BF453F4E204FDE1F3A8E797F -:1043E000ADFE8A21E4771485B98CAEC01F54B9FDA7 -:1043F00076D8FF26DAF5999249777774011D4AC974 -:1044000032D2656F266BFFFBC01D5DE02FEE516859 -:104410001B9083B90ADA37CEF9FD2CC0E6A768C62F -:10442000518077143EDD43DF827B09B64F67F7B9D1 -:104430002C1607D7DC0074798D0FED33FA7E8DF5DD -:104440005CFE479C7F3FF233FB6AFB9F54FCEE5CB3 -:104450008FB1E8F5246FFF09E8F5642AFEA5F4FAA8 -:104460005B786FA1D70F486A7A7D7B0C7AFD0F6865 -:10447000EFC48BB32C116317EC2BCB1F2DDB07FD87 -:10448000C99F59B4EBBBF4297DB42D86AB19166CCA -:10449000E79E93F23EFA2718D7BC7FC0FC3B46CD7F -:1044A0004008F353F4BBA07217C8B10BE8570E6471 -:1044B0008FEEF7653F8377F135BE68AAFB14BE1314 -:1044C00090D9F9D800AB3716DFFC3AC0F253C6E2F8 -:1044D0009B17381F50BE0906E64FCC3767927C9376 -:1044E0001FB820BE79089F9E62C63738FFCB47F3BE -:1044F0000D89ADEB02F9DA59C8F862CEFD9B902F19 -:1045000046F82816C3EF52B28CF2DBE4A38FEF8F8C -:10451000617D67FBC018F70656707E5AA845E60114 -:10452000FE8D4BB476768E6908CFEBF692E17E373E -:10453000E609B3BC5C6F2C6630F36090C0FDB48BB1 -:10454000381EF6808F067E50258F67C98364957F5D -:10455000343FFB2B1215D67B605EE1E3FBD2234B8D -:10456000018FBD646816D86763AD532D1F4FC832E5 -:104570006A0329F87F223DB421C0F4D0063E6EE6DE -:10458000C76A23D8A74E7E5FBCF1D93F3C3E4E3F61 -:10459000EB391CEB029F585FAD0BA4D6573704ECE8 -:1045A000FAAA42284AC9FFEB0329E407E5FF9B5317 -:1045B000E1E553F0FB9D8114FC1E095C18BE9FE5EC -:1045C000F87EF653E27B176FDF13F8C4F2B62715B7 -:1045D000BE28BE7706B22F08DFBB52AD17C5F7D78E -:1045E00003B8FE4F23FC7EDD87F1F2EE05E420F4F4 -:1045F00093028E5E6B3FAACEFAA13CF58140E97E24 -:10460000F147DDE154F724D176FB52B5AB0D683CA0 -:104610000EAD6F06FFE1E1CFF8705F81EAC703815D -:10462000FF5EB97F28151D2C16991CF206167581A0 -:10463000BEFF14FD0FA492FF5FE57436915DF01A82 -:10464000A70B3AEF9F029C4EF9D7CBCF312B5AF4F0 -:10465000E500E26BE86A90577BEECE1420DE956FA2 -:104660002404F0138E723D560597FDCC4FB6DB2324 -:104670002704B867674FA326C079294B7FAF07B2DD -:10468000C7EECF090785EF3730BE2FDD188276B52C -:104690007C7E176B271DC934DE0AA0FE89BC0D4F36 -:1046A00063A65D6E9BF310233D2CCF7661EABF734A -:1046B00079D42F9BF2FF7DABFCFF8F11BA62FD5DB9 -:1046C000ACFEA1F09DE3F0FD25157C4EBC4C04E74B -:1046D000250199EBDB889A9E424F39FB33FDEC9123 -:1046E00075029D6489FB64A78FE8EF603AAC478749 -:1046F00088E7A8567079B2626106B7DB352FF4FF00 -:10470000308FC33F7CCB0355B0AFDE7BAF5606285E -:10471000C86D607A4FBF650AC657A7F27E9DF08FBD -:10472000B457FA66C1DF8FA0E34E83792C59441247 -:10473000E037A683DD80F10A0DFFCE71A6BB27040A -:10474000F1D92D42CF9A75A057AFF6B17331A1D5EB -:1047500013DC9FD96AA35B12AA98A07E0BD6D7D28E -:104760007AF09E950BAEEFEE496967D5A48B9C9EBF -:10477000A24BC6C56B2888712F13BFA3C761EB5727 -:1047800015691400DFFE0A4183D43B3FA513B0979F -:10479000C4E241CC9BFA6C05A31742FD92F1EF698C -:1047A000E934E15A0578FFB47099F5C61E8FD773C6 -:1047B0009CB718F97B643E26C7B0222DBF77342BF7 -:1047C000E5BE82F9EC6AD60CB832F93D4DC7FB1B49 -:1047D000BB46F2BEC3A155FEFFF97AC979C5597C23 -:1047E000D4517FE49E92908AF61FFE9D0FEB7D3D93 -:1047F0009C2ED48C482C1DE54A18EF89A4E5565808 -:104800000FA2D2B21FCBED58D646CA9D583FC4EA7C -:10481000134DBB20BCD376DBB11F79A49F1DD88F6D -:104820006F64DC9D580E8E941FC4FAF9ACFE858E21 -:1048300033EA9E964109E7FF816CA4C3BEE9E79B7A -:104840006EC0F8D2754D37E1B3BB59AB82389D7954 -:104850005FC9E7AFBB41037FFABA2F3F88FBFA6617 -:10486000FF2BC1EF00FED7E55AB097944231F29882 -:104870002FC97F4938DAB1BC4266F7FEAF5C787A5F -:104880007BBB257EA7C2DF4F87FC1ADD725F06491E -:10489000CAC32704E37BE91741CFA3E749C800A5B2 -:1048A000DF0F7CC5F118D273B5968A6FCCF98ED51F -:1048B000BF39DFB1E48D8937F3FD9662FEF7761DCF -:1048C000F14BCFF41ACCFF59297038FDFCFE485E3D -:1048D0006F051DE7E952A40B1DE87605F7EF9CFA7A -:1048E000C11CF709217A02E804E2C4F7968FC6EFEB -:1048F00085E2CDEC7F723446E0FE2E6F29C17DB19A -:10490000A0DFDC576772ED219F598E617249A4B810 -:1049100007E59C4737E51ED3935A5A9F2196513F8E -:10492000A887D48666411E6834047FEA87968FCABA -:10493000684FB0321DFEE800DA3FDA6CB8F1516D15 -:104940003FF7A3A35712767411F7DDCEFD08F5B734 -:1049500059860B7C4B68D93B5236D4102D178D9459 -:104960006350DEC3ED3EA1E7DC8F60CF84EAE573E0 -:1049700056795FC5E5EA44F2F4BF00B9E905CA001B -:10498000800000001F8B080000000000000BE57D88 -:104990000B7854D5B5F03E73E695642699BC270490 -:1049A000C8090F098A38090482623BE1D558790C9D -:1049B00015359628938447782620D5B1D2322180A8 -:1049C000A0D886AA156BC509C57B69AFB6A0B4E5AA -:1049D0007AD17F10B4D0521A2B55B4A25150F15154 -:1049E000938294A9D572D75A7BEFCC39273321B45F -:1049F000DEFFEFFF5DF874B3CFD967EFBD1E7BAD6F -:104A0000B5D75A7B0F6361C6721963DE1CC6C63107 -:104A1000761EFF7CB967C944BB366DAD67C268A816 -:104A200079ADBEA11A631BF15541BC5D89C74EED3E -:104A30001ECD0CA67BCA199BBEAACBEA8476CEE219 -:104A40001C77D0C55891F79370257C5F349E310D4B -:104A5000BF1D9245E3B679572A769842DB08E651A6 -:104A600018BD5BE381F6396EC6DAA164D60863230C -:104A700018BBDF25EB301F28032511D601CF533596 -:104A8000FEDE827578AE3A58D34EA8A795307F04E3 -:104A9000EA1E079B1380B2D863610CE6E5F3A834E5 -:104AA0004F1F8E06F50CEF5AA6417B6795C51F81F7 -:104AB00032034B971EFEB5E23B2B95121FD7E6043F -:104AC00047209C6D8C55EDC479B168A004E0481D69 -:104AD0009E937537D42A4BAC2B190CF9E86A1698BB -:104AE0006B63ACC21348C3F6AED29CD4E008AA8F65 -:104AF000F2403FAE75963003BC54327744298EE3C2 -:104B000005669E1A7027A7C7CBAB838149B6E474AC -:104B1000BBE12635A087439653100FF0FDC7D5EFB4 -:104B20007C1FC159EAECB2B34140CF219B034C45F5 -:104B3000783482D3B97B66B410DE2FDBB39CE17C82 -:104B4000D7A4A58F473A9AC77DF9B3073D01789F4F -:104B5000F25747606782F196083C1F5D5D4DDF416B -:104B6000F79A358FB13908CA204604ED7062C994AE -:104B7000F30E02EFE810787F0BE3CC302B503B8D27 -:104B8000015EEBAA55A616E377DDEDD979A8DFD251 -:104B9000513B958D844AC876129F3BE1EF79E83707 -:104BA000C832A778E0716D983FA7F6F0DF3CE69B2E -:104BB000920BDFD56F303D7FFD9AF7593ABEB79E15 -:104BC000EC2889F77F63756D6092687786FE1F21F8 -:104BD000786669CC8F749BE54B8B8401C4EB0337FB -:104BE000052695C4FB7BE573750EE2C58C8FFF44EB -:104BF0007CE4223E028149437BE2A32EA0D83DDA29 -:104C000085F1D2573CD45A4BA7E46A3DF160861F28 -:104C100030762FE2791EE0F9EEE2E4F88076448FF8 -:104C2000576E827600CA1475AACD0278A89FA93063 -:104C30008742F84D6783B19D7FEA64DD7CCD78348F -:104C4000E3ABFE19E68B42BFF50FB87DC0E1ECF790 -:104C5000123F5140DA189027BCA91ECEB771FE1E34 -:104C6000F88B707EADA2F4F91C984770ADE2631C1E -:104C7000DEB7F5F0D5B140465421B8DF4E42F7B764 -:104C8000F5709AE7679E7F0A0A2B907FA1D78BBFAA -:104C90007340D78E59A323029733F6538F3BE7DD3A -:104CA000CBA03E92F9CEC3BA3ACBC6678CC2F743CB -:104CB00012CBDB73ABB5EF1CB0E9D739E7B339A141 -:104CC00099DDE362FF0A0B76D73D80E7C04DEABD70 -:104CD000D7C3BF5F3E98BD0E9FADF0AADAC96CC4C2 -:104CE00017C04BF4F23326F98B6119DEA702FE667A -:104CF00032A7E6827EBE0C42EA3CC032DD9FA2B9FA -:104D000074709C6E55AA508E02F132665D1E87D774 -:104D10003CEF155E3B8D07FCF8899E1FCD7879B975 -:104D20007A7006CA9117112F69849791178397AFEC -:104D3000E0628675E3C9665105E8DCA53823DB60CF -:104D40004E35A13B039346215E58D80EA2F35D4F2A -:104D5000B190D31C6E1B937F9A18CAD31A3B0B22B7 -:104D60005CAFDB58F52E1796D101653AB9F57E7622 -:104D7000E5BB28A765BD26F46DEA1F1891F850F22F -:104D8000F32D4E5754E57CF85137DF903CABF120C2 -:104D9000DD814EEC3CC0A9662CD1106E352D7D24F2 -:104DA000CB606C033601389D9981D328FFD5B4813F -:104DB00011E4BFD49B7EB481D3F1BEAA1B74744CA2 -:104DC00099F754983AD7B20CF84F13F4AB14F44B4C -:104DD00029719AE9C7709D864B58E43145A000EAD5 -:104DE000A787F823B86E93E90D49CF9412EBA71D5E -:104DF0007ABE66AD8457494776607417AED7A0D7A0 -:104E0000CAEEA6F725849FA047E2A7CB86FA644E98 -:104E1000C8765ADF4FB0606EA419BFDBE8F0E1B38B -:104E20003A8B9687ED004F1ED4E3ACC4E7C3F5C3BD -:104E3000C2F09DE427C42B1A13BAFE3B00868232CF -:104E4000EC0FA4277EB74137CEA09EE376AF2B733D -:104E5000BFA6EF5415EC07B2237C3E9F4E7E0FCECB -:104E6000E4F6C369EFE89D9641C9F157E7CCF65BDC -:104E7000B3E3F5B70B9CD591047A40F627F5799604 -:104E80001AF45A10B6F063070FF4473DECB9142436 -:104E900019BBC71639787000431661AC1FFE2F721C -:104EA000D0EF22BB43D4813161FE6DA9DD75BFD344 -:104EB0000BF541DDF530D6B7C270EC4AB05B32235A -:104EC00007D7C27CCE1D7790FE3A5D951AC1C59377 -:104ED0001D9AC84EC0BCAD60E66400AB4111C6D29D -:104EE000192A2478142B600EF09DADF914C4F7AC88 -:104EF0004C8DE66FD558D40D93CBB6FA14C4D7F7C2 -:104F0000ECAC41C88DE13375F6CB2C01AF1CC7E189 -:104F100064E194B278BF606135A31EB14E65A457B9 -:104F2000609D93DD26D7B7EC2798C9F567F7FABCE3 -:104F3000F07A0E662658CF872D4D6F7E0BEDD95F28 -:104F4000ABEC3100E566EF1DF4FC86503D953785EE -:104F50001652B9488CF70E0B2ECA84B2BDFAA59B27 -:104F60006F07FE6DDCEDF0A15A5E7ADBFBDF29D71F -:104F7000104F4077FC6E5EFD03E5F0DE3ED442F656 -:104F8000EC8601AC1AF9C9DEAC907DB451B357ED93 -:104F900086F2A18CCA2D993A381ECA98447556A536 -:104FA0005990CF5738399F9F3B7E97B70EED4A9760 -:104FB0008BD68BBDB9F8BB16A8B343306F86F2838E -:104FC000919DA13A78797726B753EF16F85E93C989 -:104FD000ED3D670C89CCF9BA09C6775AC30CED6C64 -:104FE00067CC4ACFED0ACC2F019FCAFE9C3158A452 -:104FF000A3703CF3F7767A8E70E1F76A3633D83DCA -:10500000F7E1F7B958CA79A4F179649BFB49E7CF76 -:10501000C5FA33CFE34F9E890F227E1ECAF06FC9B7 -:10502000A475D36143797E8BEBD7C794917D91C7EB -:105030001D0ACAE3E99F29D122C05F4AA51A595324 -:105040008C7ACD336D34F001ABB4F9109FED43721F -:10505000DC8374E3FF44D0FF45ABC78DF30C4C06F3 -:10506000BB9AF89BE5CEC27E26D78FE1F20F0C2EBD -:105070009D9E7D51DBBE6110CADFB08DF64B739CE7 -:10508000E108CE4F67B729E7B95CD6AC63E2F6DF3B -:105090009C49AA3F25BDA77D07DB900364FF4959C2 -:1050A0001E863A7CF786A8BE39E9CCF5084607F398 -:1050B000D807E9ED41DC2D8D41FB86FF991332DAEB -:1050C0007D66BBB0AEA2F4052003E02552351AF987 -:1050D0006CB885F8ACAFF632639B399D27B7787012 -:1050E0005FF528CA09A84F9F746212CA8D19605AC9 -:1050F00061BF3326A99E28B4DE14B2303F4CFC8831 -:105100005F8D2800DB91928E435F46BC55D834D228 -:105110005B25ECDEEB72F0FD280FE23920EC106825 -:10512000CFF59BD719190ACFDAFD275CF53ABE3BBC -:1051300052716238EE5740EE3524E227C69A89AFA5 -:105140000F7C3395FA79F37E25E280F94F563FFBC9 -:10515000ED58B467BF65F3393402CB82749DEA63BE -:1051600062E3EA774DD6D9012758600CD995A5C7D7 -:105170002B1D68BFAE53689D4AFCCF0919EDCD6069 -:1051800013D8655A4FFB143AB3233FF7D53E35DBAE -:10519000579F650A7BB38C95E9EDAA647A4ADA5584 -:1051A00056E657B3F87AB2A2DE9D0E0F12C9819A65 -:1051B0000CBE0E26AB1F117D4E57A81AE2EB48E835 -:1051C0000317EEC78F7CA6F27DB03FD760C715648A -:1051D00071BFC0563B1864F0DDD67ECE483374B53F -:1051E000EF9B97E677107DB407C7231D7F6D2339AA -:1051F0009C6CBEEE90CA8600634E0B29544AFA1589 -:1052000085529855A71F8A58E2F95F9AC5F7A1B948 -:10521000AB9845837133C3CC9F687F2CDBC1BE78CC -:105220008A9551FB6826CC6FD9100BF1A7DC1FA71C -:10523000D8C2FE4280DFB6777918F7C945303F9C67 -:105240008706F3437D591C4AA3FAA0503695834341 -:1052500099540E0915D2FBA1A1C1545E122AA6E7EA -:10526000C3429751BD24348ACAE1A1522A2F0D5D51 -:1052700045E565A037B1DD885025959787AEA5E750 -:105280002343D7517945682695BED06C7A5F1AAA18 -:10529000A7B22C544BCF478516537D74E856AA9776 -:1052A000879653392674279563432D5456849AA9BB -:1052B000DDB8D03D54BF32741F9557853653393E03 -:1052C000F430BD97764BAA588FF768733DE8EF002E -:1052D0000ED7908F93ADBB85595C0FBC98E99F8921 -:1052E0007C27DBD92DA0C75D3DDBCD136526D235EC -:1052F000417FC12CCE971FFBDEFEFE3016A7DB469A -:105300006FEFFE0C56D237BF57208BCBAFADD676A2 -:10531000BF8AFCDBC47C6178346DF48B0ACA973693 -:10532000CD5A95C8BE7B28CB46E33E9A196CCA82FB -:10533000EFD38A4F1E40793223ECF9ED04E4971144 -:1053400039BF9E00FD15ADB5D0765F639E7DE85FE9 -:10535000D32631928BD2AF04769D419F6ECE92764A -:10536000E3CE8383683D0D29E3FAA7E31A5C5FF679 -:105370006F0EA2FDFB567B54B1A27DB38231BDFD01 -:10538000BF757DDDBFE1FB787F7C7D166D60CFA1B1 -:10539000895DDCAA4D488172F016FF7329F0C9D0EF -:1053A0004870422AD487ED083F87E5F09D9109694E -:1053B000505EB627FA1C6EE32E8F764C7041FD8A44 -:1053C000836C3F2EFFD2766DA21BEAA38EF9F70302 -:1053D0001BB0F28EE0C4740DE713694987F96C7D48 -:1053E000030C3DA8577CD4AAC276284E7FB0E3D0E8 -:1053F0007E9374718F6E9F940DFFECBFD253AAE21F -:10540000F7D68E94CC113DE9D38670239CA0471E1D -:1054100003B8FAFBA38A47C727CF08FE003AB42196 -:105420001DA45FB26D6D16F925DB523D953864D72A -:1054300064E6D9A6211F5B094FF67583C81F27F9BB -:105440000EF06BB067370B39B1B5DBDE4D8CDF6723 -:1054500010BFE5FF3AF89D9AC5D74332FC3A915701 -:10546000C65D781D1F117C08EBF8D788D764EDCE98 -:1054700008FC9BF1DC6661074157C1B8C0A77C5DA1 -:1054800031F4A37D2CD6FB85F07AEA5F0CAFCF0B0D -:1054900039910CAF4CCB213909FC3A1CFD63C9E4AE -:1054A0008D5DEC67CCEF3F17FCA69373DC6FEB01CF -:1054B000393738B99C3B7421F925E48CDDE4DF49A8 -:1054C000CDE6E3557802CEECF2047E6A1137907E89 -:1054D000EAA9AAA712E50D1BC6C88E4E1B1109E347 -:1054E0003EA528AC95A9D80C8532E2B15F09F91F19 -:1054F0008AC1CEB002FDA1AB28964ECD63A943FF71 -:10550000BB5C6F9E5AAF7EBD497D1F5F8F922FB2ED -:10551000DAEEE67E496D26D82FD764737E8BF7C30B -:10552000FD20EBEFE8D776B74E0EB679BD5497ED78 -:1055300093F1EF02F1BE6DED1AC2A7737C62BB61FD -:1055400062B62AE441971FF93CFC25E6417B2673AD -:10555000EDDB249F32413E29249FF8F8FD43A9FF4B -:105560001686FA84EC3C21CF3DA937B8FFDFF173F2 -:105570003EDA54A807C67BF6A918A7013DA4E13A74 -:105580001D0F731F8DF8B213DD35C6E9A88D6711A5 -:10559000B47B016F51DCB7872D6EF233D9EDAD7E50 -:1055A0005CCFCC9E49F057788233B37B91379E34E1 -:1055B000AD14895A97BDEB1A17F0DFFA624F2AD65D -:1055C000E7407D53058C9BD5C1447DA36BDC3FEE4A -:1055D000F7A8BBEF6787D0EFB13FCB1FCCE67C5D70 -:1055E00087A57F98C74AFEEA3EC6C1E4FA8CAF277A -:1055F0004FA95C4FB523481E2EC17E657FC9EC9B29 -:105600004BB2B99CFB56B6C5C0D73DC76D36AFFB94 -:10561000BED93762BE8BB37B5FFF2F1FBC6FCB76CB -:10562000A6F337F6FB7EBB55437F06F7D3589CEDB8 -:10563000D49F5BF81BFDE86F043E700EE175FC9390 -:10564000C85F9C1C8F119AAFF4334A7F62BAE02B7B -:10565000665522A8C7D32B3CD63AEAAF837D0DFA14 -:10566000FB81C0935CD728B79E1C817229CB8AFB33 -:1056700075F427B9B3E2FD633DA32C2E9F98D8C7DC -:10568000DD2AE6DCBAC697812EE7F011EE4769FD08 -:10569000365F97D3FAB3C81A94137EA679A07D0A11 -:1056A000937FFC067FF2D44F15E687F91FFE54A5C1 -:1056B0005219C2A26ED8EF4DF32951DC07DA2DCE74 -:1056C00008EAD2CA7E4E86F14D7BBA2582F111FBE3 -:1056D000DB0AC1692F4B8BA0F09BD4AF2203E39868 -:1056E000670EEF770513D0FFC660ADC1FF65C663D7 -:1056F00077BB9B9FF7201E1FBE409CF65076779C81 -:10570000767F36DA4373BBD6DAB5789C56C61F0B64 -:10571000BCBB3756A2CA5AC2EDD37E2CD2ACB7ABB3 -:105720007471D0DF22BF3F1C8F83B65FA28F833698 -:10573000F6DB8BF6EE43DD71D06014C7F567EF2C16 -:1057400045FE7DD8B7FBC7DF457C3A44BC62D471C7 -:1057500097867EFAF2FDB908CF6F4DF397A5F4E373 -:1057600099F7C1C7B38DF18533BEEB32A2C45BD9C3 -:1057700009D7B7F42FCAFD30FA0F3D09D7A111DFC1 -:1057800072FC1A85EF6B994DE1F24FE851902F9D15 -:105790002407228CF4A6DFA16C437D73C637CA4769 -:1057A00071CF24F246CE07F0383451FC17C64B189F -:1057B000674DC9E17AAAC6C6FDA6CAF2F2269C5771 -:1057C0008DDBA53874FEFEB342AF9BE3426AC66729 -:1057D000E541E1F74E04BF39BE7356E80BC497DECE -:1057E0004F7E217C1DB3B552FCF0D83C9535433F2C -:1057F000678263F35982EF65F91AF2CD50C6DECCA9 -:10580000E1E375D33349BCE8D8EA068A339BE36900 -:10581000DDEF6B53AA517F57231E75E35E29F077A6 -:105820009D289923A879E0BDBDEE010FC3F8D7D01C -:105830004FCAC36EF48B75FD1CE317EC5B6EF25719 -:1058400054D79E2D6FBE5C87CF0AC6E3B3FB1FF211 -:1058500068F0BC7AE8DADCB02B391ED1B78578BAAB -:10586000071F8C237F4C79CE45F863D8081E17623A -:10587000FB53287E9AF207D58776038ECBF500F787 -:1058800027AF147113731CAF3AB4CC205FD2620AF5 -:105890008BE8E21769D69DE49F4D8B59E9B979BD34 -:1058A000E5E774C73969BD49FC27A3A7C4BFF979E7 -:1058B000590EE7CB63B50B35F41BDA5313DBC11B71 -:1058C000453B5937E723248BBBCF17743D131C97F7 -:1058D0008FFEAA6A7B78685FD6B9C4CF85F21CE6D2 -:1058E000E4707DEEBEE92511C753D7626F52AFA6B3 -:1058F000597B8FC7FA4DF1D8B4D13DE279FF23F13E -:10590000D8969C7F2C1E7BADE0DB0BE5A1DC6837D5 -:10591000DA3DDD7815743C134C6161908FB756AA5F -:10592000148702FE20FD78EC0185ECCD68AD83F490 -:10593000727D6D0AF967EB4B557A5F7FAF4AFA3398 -:105940000AF26109C887DF0A3961F6CF5632C510FD -:105950003F9F3E3AC550BF69DE7DBF5D8DFEE50AC3 -:105960009B86E31DD1B8BF39EC57C97E853E7C517B -:10597000F44FDF7FB50FF599E487237E95D65BF86A -:10598000A8EAC361DB853FFAC886D208E6A93025BC -:105990001EA7D70663FFF514077ED5BB85E29C29B9 -:1059A0009F3F1808D0FE31A89592DEE4F1D314B1E0 -:1059B0004E27F6ABB801F5F89B9B6C0CFD466FAE1D -:1059C0003A43EBB9637513E54548FFB2F40F9BFD0D -:1059D000CC66FF720FBFB2C99F9C2C9FE15749F85C -:1059E00043CAAB64FC0162EB484EEEC5CB31293FA4 -:1059F0005E13704EECB7E5DE66C043DA5C95F020CE -:105A0000F9F2D5CFEE7A04E5700AF0C71A86F8FCF1 -:105A1000F7E7711FC2162A09FDC81952AE63FE448A -:105A2000499C2E37051776D771F9CF6E586EC8FB93 -:105A300030EB95E472AD77B9B53987DB5D66BD6350 -:105A40005E0F5FB4DEA9AE7DA004BFAFAE9D17C1EF -:105A500072633F6703CA5FB37C30EB896A939C8DA6 -:105A6000EB07954546E9E7AD51BBB89EB0D3FB7354 -:105A7000293CDF21E4E4E5EDA9E9DBB03C97C2F382 -:105A80001DC26814A29DFA465AA485F6E54D63919D -:105A90004F42CCD7114638BDA9E44768EDCFDBA90A -:105AA000D7A472BBFC4025C1AB4AC37C6D25AD9B1E -:105AB0001601CBD6EC60512ECCA7C56F49C1F8C2F8 -:105AC00044B7F510BA5E5A27589883C5F115CF0B25 -:105AD000611E05BEA7770AEE3F4B9DF6C164A70E77 -:105AE000CB457EF936EC0F81EF0F1F5677B701A833 -:105AF000877DA33212D9E9B234C7918F7FE39581B4 -:105B0000B86EDF61C1B25C8A1FD7DF8BF1E1C63DA1 -:105B10002AC5976EBEEDD54BC8EE36C529D574673C -:105B200009FA535A94541FCA1389C77D6E3BC99909 -:105B300096E369B49F68794B117537C94389F703B8 -:105B4000D0AE6034E62AB9496E4AFC035C13701E7D -:105B5000920E952C7A787CF13F05D734C47772B8D1 -:105B6000FA7B487E209FA9713854B795E0EB64A971 -:105B70003E9C5F48F887D8EB69B4FF93746E14FCC1 -:105B800028E9BC4CD0B973EFD9EF5C05ED5BFD594A -:105B90001475500730C243E7EB6EE21389070937EB -:105BA000F0451DCE53C2BD7FEFA86341FC3E3D953D -:105BB000E2F8D2EE9679073DE494D8BF2FCD55BADE -:105BC000ED5EF45FFC3E7BC2D2DCDC04ED85BD0BF8 -:105BD000F86EC2712B3DEC93088BEFF392E537AC76 -:105BE00012FD77F773E1FC8655B989F21BFE717AD5 -:105BF000DE7531F46CB4BA362819717CCB7D332D47 -:105C000069ADE7FA37AF3F490F65EFBEBF621CDFF2 -:105C10002C176E579B9802E3ACBF9CAF4BB68A69BA -:105C2000941F645A2F17923740FF6D085732B9D32B -:105C300057FA3FD193FE4FF446FFEF65077E86EF9C -:105C400071A8C232DA17EEC23ACA13FB201A8FF8D3 -:105C5000B62B93513E9BCC8F91F3917932514C5A94 -:105C6000CDD5E5E194F814D4137DE08FA87E7E5F56 -:105C7000007FFCA6773916A575BA54D07FA9CCCB86 -:105C8000D8DD7B5E461FE8F75A22FADDAEFABA820B -:105C9000C57DA7DF3B3DE9F74EEFF40B9EC2F72D24 -:105CA00076F609D9EF15B55EE4970A8F7F16E6A15F -:105CB0003CDB2CE44E31D00FDE3F9FA3925CFB1EF9 -:105CC000BB94E4F6972C169A6F27C8EB6D4A9FE0B9 -:105CD0008CE5D2FE2F6CCD827E6FBF8E517CCFAB18 -:105CE000352B58CFD7404F6B7D8757CDE37A5C0774 -:105CF000AF9A9740AFEBE4953D8FF3E74AE44FA7A7 -:105D0000E6B1F626AFB2F28C76421FF8312BEF8B5C -:105D1000E5C70179BDCAAB8BE6B36138BF6472A237 -:105D2000AF79A0B04E596156CFF119F3515CAD3245 -:105D3000DDC9F5F62E45E8F1D220D5DD4E12160765 -:105D4000849E3FBD9BBF572724B62B7D7959C4CF76 -:105D50004B772E0F580DF924617AFE5DFF69CF1045 -:105D600015F3B45D044FF634EE8794F0CB3CED743C -:105D7000014FF6000E77F6719ED72EF1952EF61B89 -:105D8000191556C33E42E2ED7635A0A01F3D33877C -:105D9000619A04EC134628E8E7CAF41BDB4B7CE766 -:105DA000B24D7F5631E5ABCAF83E17F73323F1BD4C -:105DB000EE7982FD2BD0A704F3C766E709FF839D28 -:105DC00079511F31B5A6573ED2ED4FEAF2FAE0679E -:105DD00069C8B3887D8351EFED4C6109FD0C7F11DB -:105DE000EB01EC15F237AB42CF4DEA28A67C9715B4 -:105DF0006E8DFC0FAAEA734E2DEEF97DA61F96B7A5 -:105E00000E1FD955A94CD3C19D1BC832D4F3ABFB8F -:105E100019DA17040719DE17365C6A783FA0A9CC97 -:105E2000502F0A5D69685F0C88D5D7076FF8AAA163 -:105E3000FDD0D6AF19EAC3B67CDDD07E78A4CEF013 -:105E4000FEB21D8B0CEF2FDFB9C250BF62CF370DF2 -:105E5000ED5B841FD98C97FFCCE372BBC5CAE550BC -:105E6000B3AB8CFC9B2D2EA37FF33E81FFCA8CF13C -:105E700025E8576F79BBB404F17D20FD4AF2B327C2 -:105E8000E30BB35C4B264FCDCF9F14E37DFC9CDD31 -:105E9000827CBD6C3FACDB2BA0EE7A6D3DC2B47151 -:105EA000048FCFDA18CF1792F11AF97D77BCC6EAC2 -:105EB000E3FEDA7417BB3B015FDC97A725F4A74A22 -:105EC0003E4A8637C98F17C2DBD302BFFF2CDE5E86 -:105ED0005778BEAB5E1FEC4A30AF337916115F0EB8 -:105EE0001E15FA66742A59F21E5A8F17AB0FE43C3E -:105EF000401FBC9997DB334FF7E3EA97E63FA86171 -:105F0000FBF9BCBDC557827449E64F3F23F0A6F3A9 -:105F1000A737707F7AAA016F6FC9F56EF2EBB5A44F -:105F20007F4AFEF416BBAFA42FFEF4B7F218E1FFD0 -:105F300069A473AE8EBEC21F9F6C1F1562EC109ECB -:105F400087602EABA6DF3725DB1F4B790EFBE312F4 -:105F50008CD3B6E2FE4B49A80753F2CB69FF4CFA4B -:105F6000A015F4A083FC04EC9006F5DB275AD8DDDD -:105F70005A1C6E69CF3B98CF695789AE19F83DFB23 -:105F8000365B99A27E21FBCC7EF917A1E7D985E388 -:105F90007D64A74D03F8D7E8F6D7123FE6F89EC414 -:105FA000CF341F8FDFAD03FD88F1BD7DB95C4FAFEE -:105FB00083FD37E2D1931DF00E447B1E9E6F43722A -:105FC000E48EA1F523F16A8EF3F555EE8CCFEF61E7 -:105FD000B78ECFEFC56E95F0AF10FBE7C9EA889D8D -:105FE000E8C73C1DB313DE54C6F32E1B0FDA5884EA -:105FF000E8C8F397251D6DB1F5EDA89F6DCC9CAF5A -:10600000AC6520FCB683FC9C18CBE1EFC3CCD98CEB -:10601000764F4685517F65FA8DFA2BBB2ACBA4CFEC -:106020008CFA2BBFDAA8BF0A8246FD55D85066D23B -:106030006746FD55149A60D26746FD3578C3D74C44 -:10604000FACCA8BF866D31EAAFE111A3FEBA6CC7E6 -:106050000A933E33EAAF2BF6AC31BC2F8DDE6D7860 -:106060003FEAE0F70CF5F2F61F18DA2F38F414E5E2 -:10607000F58C3DB6CDD06E5CC74F0CED00E1ED98D0 -:10608000FF3D9748C2D855A79E34BC9F2BECB5ABBB -:10609000BB9E36F4C35A791E7718FE22BDDE6341DB -:1060A0003B1A2956D6F54221D0755944F145A1D95C -:1060B000C23DBBC6E03C3E7CE39A83D8CF822DC66E -:1060C000FCEF851163BD910DCA40B9D0087C110168 -:1060D0003E598C79E13AF9B698358973817DE3B3FD -:1060E0000587AE63944F1AF6B763DEBB8453F29B09 -:1060F0005FF09B9C9F847731D87F512D0EA71FFEA8 -:10610000F2FD66871DF976FE1E85FD40E9094FC345 -:10611000DECDEB0B13C06586C36C87FE47BED13F57 -:106120003E597551BCE0F451D5C7FD8DC675B8E236 -:10613000108F13AC7842217F9D191FD23E4D8617D8 -:1061400035CCF70D8D392C12D1AD3F4DE0C3E13583 -:10615000AEBFD3F80F9CCF0FD508E61BA568A96684 -:106160007E1B13653DF19C56625CA7663CBB7DFDC2 -:1061700012F295067F711EF3C5F943335F99F1BEA4 -:106180006CCF663BCAC38BC5FB6BF989E312A0EDEC -:1061900046DB13E4D749BCC2BEBD03F548B2FDECF3 -:1061A00047F917BD9FFD28FF8BDDCF9EEB4DCF75C7 -:1061B000A2BF0DEC4BB39FCDAC8795BDFBFFAAA44E -:1061C000935FBBC381EB2EE873F23C18939E2C299E -:1061D00031E8C9EE7DEFDB0AED7B7F91E1B77B61B2 -:1061E0003EBFC9F03BBC00E72D197EA757076F0BD8 -:1061F000E085CEFD809EDA95C04E9CE495719700B7 -:10620000F94DD655F2F6E67623BCFC9CD1BEDC31C6 -:106210005EB23FDF2AF592FDE91ED3ABFDF95D11B9 -:1062200027BA07E39043E3F941F78A780D2C3B3F07 -:10623000D26D9D2DE0D5E70F67783369BCF4714FBF -:10624000B6631E758BC7E251342C793EF75A97B569 -:106250006ABBF82EC7F01D3FCFA422BE01AF5697F0 -:10626000F5533DDF4EF232EA37199C93BC7C3F690F -:1062700063C17BD11E92F161DBDB954E94772DCC0F -:10628000EFE172D2E7D1E77FD8188F074F10F161A5 -:10629000F95CF5FC637958ED19C189DE047958770A -:1062A00064F827E1F39035EC40BB33E44CBC2FFE9F -:1062B000AA97AF139B80170C50E22B9A877AF1F1C3 -:1062C0001FB037AFC7716F57C39427D9E21E53125F -:1062D00074F5DDCF15F4F6B08F82DE5EEC23B04F9F -:1062E00067E179327F463F2B6D3BACBE12C4F706A7 -:1062F000FCF738F2D32EC0EF7BE4BD8A73B8B08FC1 -:10630000EB358F57F6B33FCBBFCCCBF30D9BB03FF4 -:10631000FF30CF5A55D74FFA05FA917E8E3EF8AD31 -:10632000BEED4DEC1F3D85FABDAF78DCE8EDE12F09 -:10633000DCE8EDC55F78EEF8B00C8C674B7F97B961 -:106340009D3C1729EB1B328DE3AF2FE3F5FBC5B85E -:10635000AF887B3A7688BAD3745ED43995D13D1D27 -:10636000F29CA9EC6787D74DED9BB327ECC0F9AE43 -:106370002F56681FBA3E5331EC47EBBD953B900E4C -:10638000DB44FF3B907F73296F94FC39E63CCC25BE -:10639000A2FD12EF042AF15C2BCA31BBAA26C4E38A -:1063A000135E3EFF5999BC5FE977AB7F4011FB2735 -:1063B000E3BD08B0CE5F4E03F97362938DCEBDCEC0 -:1063C000535DEB911F93DD73503B2240F94FFFEC7F -:1063D000F931C4675A564FBDFABC37F1BD05C9E45F -:1063E00088CE9F76D87B11794B1DA99C4FBBDC2EA4 -:1063F000F29B9BDBBD2BE8B349F83550AEA37EC9B9 -:10640000525953223DF3AEC0FB3F7EAE99DFE79178 -:10641000ED72D177E673CD1DF68E75F938DFAB15C9 -:106420001F9E5FC8AFF1ECCBCFC1738C1AF9F8D6C1 -:1064300017B3F40A7C5F6AA1F799B33CEB6D98F748 -:10644000AD31CCDC673618C70DE3A4171473B8C29E -:10645000D7EDCB8776195A171B3482CE7B4FF1E2EA -:10646000BAADE6F9F33DF02DE49B6B1DEC2F101F48 -:106470005AE23CF4F342BF80BCF93BF26BA5C6760E -:10648000F373593C0F16D992F2157D3C5F3B0DF327 -:106490009D06737983EF95EC89D682DCF8FA520574 -:1064A000BECDE7B9D30BF8387D3DCF3DA326F17CB7 -:1064B000871770B88E67047270DC19E39BB93FECE4 -:1064C000B3F3E7D531681CF37502DF33F457A4E466 -:1064D00070399CA26924979947A13C57A7E66BC0E5 -:1064E0007A8AEB4A8F8A76B283C725D95C0BC3FBC5 -:1064F00055268A7EFCD54C79B784FB65B99CB5B22C -:106500007725FFAB02396350CFF23F603F6D4A03FE -:106510007826BA0E537C32654853259E6B787E0EE2 -:10652000EFE37B49CE0DC8F3EEDDE7FAD98F0E1B02 -:10653000CEF5AF7BE4F0C1AB75E7FAC38F1CF68FE5 -:10654000F8C7F3DBA73CF4C8E1B5AEFFB973FD5261 -:106550009E1D5383C7EE04FC5F0F4C152AC3D2CA9D -:106560006A88DE5EC2DB2C81E7F0A78067671CCFFC -:10657000D7EF3D44F83B668379C3F8B6091CD5B61E -:106580006F66445A482E4668DC1B9CAD9371DFD978 -:1065900069EF1A89E3763EF3CA8030C893E3DF3AA5 -:1065A000E366C07F6F5ABBDCF8FCD4AA97DC780F97 -:1065B000C2F1552AD96B742E5A978FD420F8EA5716 -:1065C000058139C85773567F3E466F8FB3502EE909 -:1065D000DF85119552AFA4FC5BBC234D301DAF2F5E -:1065E000DD996DA84BBDBCD491F89CFAA3059CEE37 -:1065F0000B1F6FB3176A387E70398E7F4AE4379C61 -:10660000DAEDA67D989C4FDDE3A576DC77BEB9D7A1 -:10661000C1A2E4076EB731F267F9A72A79788F1122 -:10662000FF639EE70BCFA6517FF31E50C9EF540BBB -:10663000638500AFC1BD0BF93ED804C7BCE3DA14D3 -:106640009457F3362A2CACF1F6ABF0FE8CD05D14E7 -:106650008731C369D62F0B92DC9FB360EF3DF4FD09 -:106660005CE6BF07EDD979ADE6F7D7BC874CBEE055 -:1066700002F19CFB0B84DE19C3C69E1F4CF1A38C58 -:10668000CBB50BEB9D53ABF922FD60B593CA8F568A -:106690007BA89C53C0F978F19E7D2F14D2326F1FD6 -:1066A000837AE9E583F5695FD7E276F798B65BF719 -:1066B0003F4C4D8DF9993502EF63455EE60271EE70 -:1066C000A1FC58EF799935888F913DE72BEDEC1AB5 -:1066D00093DF57DADD667C9C3E38310DF9E3970590 -:1066E000629F3B16F0A2FEF37849F6DD5295DF9BE0 -:1066F000667E2ED7D11CC1D773B7CF5CDF0FC66FB4 -:1067000079E6BD811DC4A7DC7F512EF055EE5ADF1E -:106710008EF0973393DF30CC8E321D3F033FA9A814 -:1067200077CC7C2BF9891DE5DF3B855FA39B5FF769 -:10673000DE4BF8957C85271D2C68C3B1A8D7527114 -:10674000E17BAEE6B51AEB1FDB3A06A23C5960F2DC -:10675000377CAC24DEBF1D2A1844F898ABF9A7603B -:10676000FEC53C1658CFFDF3FC7E9C53D6D617EEE3 -:10677000C475BE9DAFB3A5BF7CE21728BF16FDEC64 -:106780008174945FEF5B5BF370BC258FAD4B4779F1 -:106790007FCA1A4EC7EFDF8FA809CF115FD24FEE25 -:1067A0009FFD2ECC535B46AC06FFCD0D4F47F9F94C -:1067B00097C76C1EF4C336EE70441D808F65BB39DD -:1067C0001EA1FE16AFDF45F86ADC635C978BFEFD09 -:1067D000813C8DFC01E14281BF4214E1CBB6DB2854 -:1067E000AF75D951D587C334B22E82CFFC3DCE23AD -:1067F00006746BDCA9D6DA337ABE074BC88EEBADD4 -:106800007137A767E36E4EAF46931DDA20E4B69961 -:10681000FFF3FA097920F81EF0437E35996FCB22F9 -:106820005C7EB7FCF8C1916FC1FC3EDAFE9B7465DB -:10683000449CFF196685023D4EEFAC9F63EFE5BEB9 -:106840009E8FC53AE9D60B420F697B6062F950DD35 -:10685000CBCB25B668FA558097256D365F181E2F6D -:106860007942F5BBD08E7AD541F74F2C7EE2F9976D -:10687000AF84F92DDE65CB99CAC170A1FC96F46A8C -:10688000443E2F8BD367D153CFDB314F139FAFCA19 -:106890008AD369F1AE7D76CCFB34E373E2CE7D76AC -:1068A000BEDE4CF4DAF9D614D4DB2D3F3E67477ECA -:1068B00078FF5985E517F7FCBEA1EDF9749433888C -:1068C00027D42F926EDD74EC41BFE8F4A747533B09 -:1068D0000FC6792E44C7BFE019845CE2F79F3E0DD6 -:1068E000F36878CDE1433C34FCF4D67484E73D6B27 -:1068F00013E7FB47D6E5A1DE6EB085F33C54F2E723 -:106900000D5BBF41FCB8E0C56FF0FB9C98BF00D7A2 -:1069100033C05B8070CEFBE1F504E77C16247E6C0F -:106920007884DF6F78D6CAAA12ED07DAC4BA796F15 -:106930009B83360FEFD919BF2FE4F7AAB80F6B3935 -:10694000D92BDF10308384A6FA5927A7D7CA7EF245 -:106950009C3D976F8DA255E3F6BB48BE7D30C09F2E -:106960008FEB1FF060F4CFBE38395FC845BAD785CA -:10697000BE03FE9B88CFB17DBBCD9F32D2F09DC8B8 -:10698000BFE5E3AF14E3C3BC53D1CFF75E9E719F65 -:106990002BCBF66EB9C0DA999ECF92C981ED1B89D7 -:1069A000BF3E39CAE5CCB2C8CC2A7ADF6E8BE6E3AB -:1069B000FBC8BE590AC909B04312ADF3ED36B1CEDA -:1069C0008DEF619E56458FDF67F9F93DC92FF3EFD3 -:1069D00087F6BA751DE71F7BFC79717CBDCAFC8DFB -:1069E00005267B4E966639F1B0494EC8EFD90F7334 -:1069F000139E8F88CB8730E16F892DF26F3FC07572 -:106A0000FDAA83CE452E79C246F7FB7CF8F8FE97A7 -:106A1000BF0EFCFFE14EB99E8DF2D7BC9E1B9EBC03 -:106A20009E255ACF1FE60458C2F50CCF13AEE71CC3 -:106A30007EDEE0FF96FC5D9044FEBED0AFA7DD7128 -:106A400015543FF8C9E222DA9F99F02BF16A96A714 -:106A500037A3B190DB539EC29FA34C874F8947C990 -:106A6000A78BFE63298DD3CDCF925F253F77F3AB04 -:106A7000196E233ECDEF37E2DEA93C4E7FDB1AD8FC -:106A80009763BCF61995F2F33AB5AEF42C18779DDE -:106A9000C8EFE9F4887A26AF77E5DAD7A33C91CF3F -:106AA000BB5278BE4367A02B3D53B71F786BAF9A9C -:106AB0008EE7013A2289F332286303FD2049F2363A -:106AC000E4B9DFCE54EEEFEB4CE57EBEC9AA6B60B5 -:106AD00008F777AD3CBE34B7F9C674DCDF77EE1D3E -:106AE0003CA31AF70387549E7314F65B0B00BFF5A3 -:106AF0001C74768A85BF3F1EEDF7BD8BA7623F737E -:106B00003719F132DFB5DD8EFD9C65ABA89C7FBFE8 -:106B10002DCE27F0DF22CCD7423EFFA1E9F9DE6B74 -:106B200089AF1699F82A887C95E03C4966A158AF50 -:106B3000A5AC94EFB7457C4CC8BDC9EA8819D59877 -:106B40004F79909FF738BD5765EB11DEC745BC2CD8 -:106B50009C4BFCBA0CF85BEF37FD08F96E58723DA0 -:106B6000FFD1CF8F8FB9139A2CF9C51F473E0CE583 -:106B700047BF78F592FFC2FA2F5F19F847D6B3FDE9 -:106B8000C467FF7A0BE5753EEBA07B4D3B9FFDD5BF -:106B9000C03BB1FEB483EE17ED5CC3F7D9E167DD0E -:106BA000A4FF3B07707BB1E59973233B487FF17BE2 -:106BB00083C717F27B2A4EEFFDDB1B0AE6F3ED05D8 -:106BC000A8503E8AFD5BE3D329B44FEF7CE69C617D -:106BD0007FFACFC2B34C9CBBEA74B36A3C27DD9901 -:106BE000C9CFA936FED7B81FE1B9CBA5BBF7D9EB02 -:106BF000E1FDC4FFF3F94894439D4F72BB03ECE100 -:106C0000ADCCC7D8570A37DF6B03FA7D8C3622AC80 -:106C1000998EC217A7E179929E78E178E8043C202A -:106C20005C809706949FC9F0714B213F07F3AF87B3 -:106C30008F3FDF82E32FD93B96EE198EE345F1F3C8 -:106C4000E76ECAF700F8F9F367CF8D443BEA42F0EC -:106C5000AEFA5F06EF0FFEC5F97D5021D74766BE3D -:106C6000EFC9D7BFBC8DEA3F75FB68BE7D5CEF4FB7 -:106C7000FF2FA3F7B1FF6FE97D48D0DBEDC1B84C22 -:106C8000E7339F0F641701F7B97F593AF70E77B7CB -:106C9000DD63F13947C3FC5E6391EB2B95E4F9A307 -:106CA00043FA2B721F44FB0C790FF7F49CF96447ED -:106CB0004CF7737F4C0B2B3B88E7ECC27E95E217B9 -:106CC00094BC0378689F551AA13C316B78E8F73182 -:106CD0006FEC86A53E7E5F9971FF353DAFAA0AED48 -:106CE000B923CD302F6877C46DF1B4000833FC2A86 -:106CF000D97F5092DDF78709D7521ECA8C0AE33E2E -:106D0000E4EBA6FDC48DD5C6F737B06DB998EF7723 -:106D100043838DF293AE37B5B7F4F7105E6E644DD2 -:106D2000EBB83FE7E2F034AB3FDF8FF5C443EF78D9 -:106D3000EB8127B1DFA4DC21AD27DE1C41BEFF744F -:106D4000C00B616F89BCBC157DC22713FB5287182D -:106D50005AE2D7E1E7F78EEAFA25BC48BC5F2CBEC1 -:106D6000259DCC7897F8957833D361189EF7CC8D14 -:106D7000E33F5E1AEFD566C26E9CDE6D37BA088FB0 -:106D8000BFDBCECF4BFCAEA27E5329D61FE7F7C1A7 -:106D90009F1D3F8A3901DE2336B687E2427EBFE679 -:106DA0001913CF9F512A7E45F109CC5FD4EF57319B -:106DB0007F510F17E62FEAEB98BFA86F8FF98BFA78 -:106DC000F798BFA87F8FF98BFA3AE62FEADB63FECC -:106DD000A2BE8EF98BFAF698BFA8AF63FEA2BE3DA5 -:106DE000E62FEADF63FEA2FE3DE62FEAEB98BFA89E -:106DF0006F8FF98BFAF798BFA87F8FF98BFA3AE675 -:106E00002FEADB63DEA2FE3DE62DEADF639EA2BE33 -:106E10008EF989FAF65F8E3D67A857B2DF18DA4F10 -:106E200074BE64A84FF6FCD1D0FE2BDE1386F7D7D4 -:106E3000681F1ADE4BFA5F5B72C6F01C631FE131FC -:106E4000B88FE17FA6F9FE66E8C7CA021427B5B37A -:106E5000262A9DE8EF853295EDA4D205CB1CCBF711 -:106E600087057FDA1FF9756B783D32D79171E70698 -:106E7000A2FCFFDDF8EBB85F42C41766E03F356067 -:106E8000E2B4CFFAE33E57C64FD3632A8B8E023E5D -:106E90008C29547A62692C9A0D7C184BA1322B965E -:106EA0004DCFB3639954E6C40AE9796EAC80CABC8D -:106EB000D8602AF363C5547A63975159101B4E6505 -:106EC000BFD828FAAE30564A65FFD855F47C406CDE -:106ED0001C95036313E97951AC924A2D762D95C523 -:106EE000B16BA81C14BB8EDA0D8ECDA472486C3623 -:106EF0003D1F1ABB89CA4B62F5540E8BD5525912ED -:106F00005B4CE5F0D8422A2F8DDD4ADF5D165B4EE3 -:106F1000E588D89DF4FCF2D81D548E8CB550794587 -:106F2000AC994A5FEC1E6A571ADB486559EC3E7A09 -:106F30003E2AB699CAD1B187E97979EC212AC7C42A -:106F40007E44E5D8581B9515B1FFA0725CECC75480 -:106F50005E197B8ABEBB2AB68BCAF1B1FFA2E75786 -:106F6000C7FE93CA2FC5F6D3F32FC7F651E98FFD9D -:106F7000869E57C60E513921F6123D9F187B91CA45 -:106F800049B13FD2F3C9B157A99C123B41E55762C1 -:106F90006F515915FB90CA6B62EF53F9D5D819FAA6 -:106FA000EEDAD89FA99C1AFB1B3D9F16FB2B95DDA3 -:106FB000FBFFF1497F57C0721EF7CFAEAC3EDD57E5 -:106FC000B6392D9DE4E2F4555C2E3E98F6F101921F -:106FD00093E31C9A8384DF1643BC8B7E4402F67DC8 -:106FE000FBC6BDD71FED9DF595275EBF15F5D97280 -:106FF0000713FACC24773F73097F27C37CC49B0512 -:107000005FFFAE627F2EDA51EBCB3A96A0DFE4DE73 -:10701000E28E1A2C0B07703D9925CA8201C2CF5A05 -:10702000C2F56FCDF2A1FCF70572FA065FB5D0DBB1 -:10703000B2BD5224EAAEAE81745EAF8FFDF4B5DD11 -:1070400085F2B03EEF1FBC62406E6FE707FBDC4F7E -:10705000C517D44FE580047961E67EDE14746F1B9A -:1070600010988CED99D53F12DF4F5853A0E2EFAA4C -:10707000D46E523CC82FF56B4BA7205DCB989FFC7C -:10708000923727C9275B2CE85AD76463E89FACD3B3 -:1070900018F987EB76F33C64F4A74E037E6910FC85 -:1070A000B274E39FC9EFD4D0B480E73D45B87F4ABE -:1070B000FE8ECDE2D6B617D0AD77961DA6FCF8C5EC -:1070C0003B8CFEAB46E19F5ABAD3F4BCE92B09FDD9 -:1070D0009E66BFD4DC01C2DFE9E3794F4CED4F700F -:1070E0009F05B8319F24789BDB897A03F0417118A2 -:1070F0008907E9F794F8603DCF5D50FEEAE98343E4 -:10710000294FEEB4A6E563BB603AFF3D2BC51A1CC0 -:107110008BCF018F94CFD2D59C46F9506F811ED072 -:1071200030F1CA131C8BF7C775BC368089FB2B8DD9 -:10713000F108E726CA13AF8539605E4AED63D9745A -:107140006E13FA1BB907FD9A8FD9281F29CC5678E0 -:107150005945CF7845609D8DF8A26E4F26CF4F0BD5 -:10716000FB8FE2B9024997B7D60E9E82794D751B07 -:107170008A4BC95DB7C746F6A18CCB4A7AF5CCDFFE -:10718000E6F9028D2CB21E5397805E2713D2AB75A1 -:107190001FD115E8763209DD4EF646B7874D7443A8 -:1071A0003FF58DF8725536ADE79A35D1A14D3AFECF -:1071B00034FBFFD9DC2BE9DE1399FF5CD54FFECE03 -:1071C000982F0FE97B665339D1CD4CAFAABFD713A7 -:1071D0005DD86B6EBA77F8E6C16CCED7E0F91CE1EA -:1071E000F7BCB9E51AB2BF770B39F7BBD598FBC925 -:1071F000D88BAB9DCC0FC6F74BAB3D54FFC36A2F6A -:10720000D55F59AD51F9EAEA122A4FDA795E915CFD -:107210005FC00894DFF7B458574F0F90FBB2955EEC -:10722000F47357FDFDA5720B89BE37A64F1E40763D -:10723000BB215FA47A96311FA4C326F2CD362A3E25 -:10724000BC4FA62E7095A13D2B1915AFA3FE11F9C9 -:107250002B751B32E91EBB9BA6661BDADFB0A1D0E3 -:1072600050FFFD008DE09E5935D8F0FCEB359719A5 -:10727000EAB5E2F723985641EB46C6BF407373BAAE -:107280007878DB4F9AC6E6DF0EE37F72D846EFCD03 -:10729000F438690FD37E3EBCCDE1C3F8DE293CFF54 -:1072A00006F5537F5029BFE8948D853D20E24F2994 -:1072B0006C2D96CCCAD7D5D9637C5D55FD5D65B87C -:1072C0008F673F71507CB07E8BC2C27837431760A6 -:1072D0001EC65DF96307C13D778BCA8274BE4ADB67 -:1072E0008971F2958F0DF3617CF4E6C1D10178DEEE -:1072F000B0EBE7293E3CF755DFC1BF3F05FBF34C40 -:10730000CC8F52CA281EF1A769ADF32D986FA71E26 -:10731000CEC5F5FAA727F9EF9A2D5CFE87311EC07E -:10732000F3A21776BE5C01E39C6C5569DC0F7738DD -:10733000DA545AF7FE7CBCDF360E7784FC14D7F69D -:107340000BFC0DE5F507F3232349FEACE2FEF19EAD -:10735000F8017891DEC8AF3A7916D76F3CFE064245 -:10736000A800E544BDCD4771D9939B6C142F047DD3 -:1073700040F906275BB32D5C0E3D497C5767D5EC81 -:10738000FA71EB36A97EFEFB189A1DE7CB36AB41AE -:107390003616EB3C3F22BC4109F2F88F91BEB72E66 -:1073A0001F4BE7A2CD795CB2FC18D6545017575A40 -:1073B000F40C8FFFB2D11D567D9EBBF4CFB060851B -:1073C000E13EA325831EFCCE78284FFBF9D58B67C1 -:1073D000B7BB494E7E64796ECCED507E382DFCAE45 -:1073E00015E8F2A21A1C3610F3862C9BB62A145705 -:1073F00039F11D8CFB7FF084CD47CB50E48D2DFA05 -:10740000C9428A4F25B7179897C7AFA3798A176FD4 -:107410002766942F329BED14FE8508CF33C04900B8 -:107420007E3C4B785CEC44B9FB6E3C3F5C6F3A6F42 -:107430007C429CB3B872A062D0D7770CE472A0DE15 -:10744000C2D7277B96DF43297F2F4ECA71296FA5AC -:10745000BCFEEA409EC722E52C633B49BECC17F731 -:10746000252FD9E1E0E78B34E6413C2EE4646277D6 -:107470000DE4EB7A91FD89EF235B2F60EDA4F73EDD -:10748000B045E6B717E3F76D6BB3E87B9B2F82EB54 -:1074900038227F8FCE4A726401E3F35CDAAA44A2F9 -:1074A0003A7F87FC7D12867A4227777AE805933EF9 -:1074B0009827F4DF3C66CA376A35EAA9409A9BE010 -:1074C0005AD42AF2B0BBE7A5B2F318EF0A465E9889 -:1074D0004EF3567C9104F358C0BAA2782FF2D2C76B -:1074E000F93926F3BCCC70F4759EF37D3327E1FDAA -:1074F000CADDE39AE62DF1CDF060958E0E12EFF322 -:10750000C31C9FF3F72A44AF7784BD25CF079AE9C0 -:10751000BF8005A6A39C5B703FEC338BE3FC20F996 -:1075200060E1AE089D07FC90B5A6BB603D2CD9B2CA -:10753000EB8671F0FD821FBE68477EAFC98A0EB52B -:1075400064C2FE333CE9BB555727D0FB263DFF45BF -:10755000E18909BF157D077899B75DA53C0A5D3BB8 -:10756000914710267C3584F9EF09361C557D2DF0A6 -:10757000B4017FE6A8ECE2E72BF1F63F3D6FB35D87 -:10758000F38B81BDDB356679D3C3AE31E9533CCF94 -:1075900081FAB32B97E7A77F62F56764919C36C9A0 -:1075A000E1DC32BA8F55CAE1F9420FCA71E6A1FE99 -:1075B00083FABB5B9E4A477FC63BF73F9547F91A64 -:1075C000A86F46C4F5CD6DF57CBCDB7E9942F952BF -:1075D0007F9AD63E12EDC19A477E95AEBFEFF54F2A -:1075E00005C1A30371BE423F2E55DB06E2EF1A4AE6 -:1075F000397BC17D5B3238DD1780D36D84B30EE1FA -:10760000D49D53A91770BEBD81C377621387776E6F -:107610000F38C31457B9ED470E5F98EC8E28E9F583 -:1076200053BB5486FBAC6EBBC364079C65AD5B115A -:107630001F4B57BCF28615F862E125801FE0839A44 -:10764000CD0ED2FB0B7FCEE3A91F2895F914D03FB6 -:10765000104DBF039E2F027B01ED8DF83CBAED80EB -:10766000CF108FDD76401FF1B74CF8B596EDFD15C4 -:10767000FD8E96E2E7F998CBE4BD367B4CF7DA68ED -:107680002803F8397F27D2A9BFF93E2EEE9FFDCB04 -:10769000D03FDFB282F8BFEB12FD39B6C6D4A80DD9 -:1076A000F390BB762964272D5D59995EC9F07C1B48 -:1076B000F7AB151471FDA6F8FD945FE300BAA6C2FE -:1076C00078FD8B34FE5CF3F07CF31F32BA4747CE73 -:1076D000D7FC1CFDED4ED4872E0BE94333FCD716A7 -:1076E00071BDB954B5907DBDC4CEEDEC4E717FC572 -:1076F00070318FE145FC9CC315C2AFD0897625C699 -:10770000BBAF76D0EF18313689FCEE56C6F9CF2ADA -:10771000F1E6B17EDCBDBEC97EEEEA8F78BA85B5F2 -:10772000D3EF224EAF98A9E1798637F29C744F14BB -:10773000FC09603FB3453F476CFCFCC21B3806C0E8 -:10774000355BF8A7DFC0EB5161FC370AEC64D786E4 -:107750009F7190DD70572AF71FB29C0C2BAE87AF3C -:107760000B3975F378871FE5FAECF17705B084FEE5 -:10777000C20CF055E3EC5A570AE3345BB8BE6FCE47 -:1077800062DC2FB0B6A31CF1770598C998BF0FD063 -:10779000EF3E9FDD1B1F19CF4F2C413FC3958C330C -:1077A0005805E1D7505F62E7EF6B1FDD31E3FEF173 -:1077B000B04FC0AC29D4338823E48BDA0CDAFFCE87 -:1077C000C0F30559585A89DFBE6665610B2F37B87B -:1077D000E85E25AFE17761AFAF60D10C802F7AC84A -:1077E00078BEE3C6A8253A0CE345D6E83EC49FC55B -:1077F000A9D93C304EA04A2943BC2F59D3B7F9AE82 -:107800007CF4A919F7F7873ADEE785F3BC43A17C3E -:10781000A1D9B0E8914F6FB1B2036A19A71FF26105 -:10782000639616A676CB399FCB7325922EA5D0BD35 -:107830001EBFB3C5FCA09F0DE9F8BD3DB15F252C6F -:10784000F852DA6B8BC5BA5D2CF9EE71E37ADD265E -:10785000D70DDA8780B7D9A24CC6F78F8A75F16841 -:1078600011DF67DE5324F7997D1B6FA9834509EE6D -:10787000671C444739EE0C513E523488FA93F3901A -:10788000FC3B9F35513ECF7CE1A7B18024A1FCE0B9 -:10789000D61F71BF9029EF080C25CA6F5BB4DDFCC1 -:1078A0005CE7E7510D7289FCA68ABD6B2ECE4FF9BD -:1078B000528A0FF97DB67D27F907CCED6CF8FBA94C -:1078C0001877DB00769522E26550776C52E8772FC7 -:1078D00066F7EFBA1CF53948EB29742E54D8DBF360 -:1078E000057D1DE27EABF9685F615C0DED2BC4D7B1 -:1078F000166E575A853D5CB7C9686FCC5EABB33B1B -:107900007961B81FC061CA53B709BBE34D7BD7E5A6 -:1079100028F7CDF705BC69E17084F318BF573387AA -:10792000BFB70AFB52F2D5CF8A6C86789B3C775A58 -:1079300083F28ADFDB60CAD372D1FD31350ABFBF63 -:1079400053FA215F17E569B043E9BE9CE369140768 -:1079500037FB273B2BDD618BCE4F7973C66DD3117F -:107960003F35E9762B96AF77DF2BD641E31FF70C37 -:1079700022FB677DE5A82D989FF4DEA36766380794 -:107980005034459C9F8AFD0EF3E9677D06F050FD5B -:10799000AF33FCB08FEA7CBEEB162788EECF8B3E70 -:1079A0009D61053DDFF940D756AC67686A80EAF70C -:1079B000760DC43B9733220E5E6F96FD3902D85F79 -:1079C000E743BCFED1A38E4018ED5F716EA9E64A75 -:1079D00085E4AF0BD75779DCCF5463798E9713F8D2 -:1079E000EFA25CA89D570BB88ACAF13ED493F4FB72 -:1079F0000B8307F95D45807FCFC0E0392C17CD544C -:107A0000C2763CEF7F347289D06B097F27C425D6BC -:107A10006B617180BE977E74E88769E53DFBF96F05 -:107A20008E8B3EA000800000000000001F8B08002D -:107A300000000000000BE57D0978545596F07DF5B7 -:107A40006A4B52498A244042162A090901031490BC -:107A50004080A04512202C810A28A2A0168B10106D -:107A60004840EDA65B7AAAC226E216D4B1691B9DF6 -:107A700012D1C66EB5A3B204D92A6C823A5228DA62 -:107A8000A8A041504163774418E30CB6FF39E7DE04 -:107A900097AAFBA8B0F4F4CC37DFF7878FEFE6BCEA -:107AA0007BDF5DCE7ECEBDF7651C63AE7A1B633F88 -:107AB000E3CF0DA1D2D6D5C05821632F3ADCB6AEA4 -:107AC000504E5D9813EFC967CC9EE18972003CB7B8 -:107AD00052F199FB30C68EFA73DDB18C8DBB423FFB -:107AE000BFC8BCA49F847FA49F8F74FDDCAEC0BBC5 -:107AF00083E03F733AF0FD3BB25DBD1D1D19BBEB4A -:107B00005F9807FB6165430C6C0063775B19FD7C34 -:107B10005FB335D75A00E54B96449609ED5ED9968A -:107B2000310BFA618BE1A514C6BE69FCC8EC807EFE -:107B300016B4AACC95C85875AB42E5824D8DE611B6 -:107B4000D0AE1ACAD2B0F9CD13F365ACC93821361C -:107B5000F4BCBF83CF97B1358CE17C5E396BF440C8 -:107B6000BBBB0CF55F3E95048F072BCEE71D97AE90 -:107B70003355BCF72963E5F5F997D60F722854FF02 -:107B8000588EAB08D7D905FA405835F0F5EADB2F07 -:107B900015FD4D8D6677B8A17EC68058AB03F05DAC -:107BA00078D4B32C16E6316B5D663F15FAE89F5129 -:107BB0005282FDB19983257C9577612C88EB33B691 -:107BC0007462507EBFA3309EC1BCA62604EF617DC7 -:107BD00019FB8DBF7B9D752863637E0B6DBAD02B1F -:107BE0002E06EF965B04ECBBDE5D560CF0DF558293 -:107BF0003D8EA23A1FBC7F10E703E56D037B45B3C2 -:107C0000DE80BDCC18833D9EB192F469BF41BEB801 -:107C10006DE0D011F87C982536771AE197117F94A2 -:107C2000A4BB27633DB667B00E8F39D0F166588785 -:107C3000E72DD5E98375787AC778FC11F03649E0ED -:107C4000E1370E3B95070D30CF7EA17968E30367DE -:107C5000DE1384FE4E2F4DE9BB1AFA7B367DD81217 -:107C6000C28B18FFD974CF9CF0F161B9BDF1F9D581 -:107C7000CE639698C71241377731F099C0F5CFF0AF -:107C80007F42598C04DF383691B9F242F0A41B537D -:107C90002578F2D46CA9FDAD33AF93EA2B2CC182C9 -:107CA0001A5B88BFF5F3D14A2014F16975ECC63828 -:107CB00006533CB1E3C28753404EFEB641752A30AD -:107CC000D7393B9FFF7008B43A070B4E04BC9D7335 -:107CD0000100EB3DB749F5FB32913F5CC68A4E8C03 -:107CE000556157D07EFEA1D7CDC3E0D7AA9AD963FC -:107CF000918E73FCA6CF9BC2E679815D34B32C9044 -:107D0000878DF2F36AF6D0776A6F840266772FE880 -:107D1000A75E575F33F22B1687ED8C9F3769EB8494 -:107D2000F1171FCF7C645FD8BA9F76C4267D791D7A -:107D3000FCD28FF5FB59C5F19A0FC00A596943234C -:107D4000D169D921D5892CBA2C5D610AAC73E4269E -:107D50008B3F0A44EBDB6D27CD0EC0D70F5EC723E8 -:107D6000FB4C28FFB58C25E27B27CD4DF07CA8C3CA -:107D700041785AB0E33B3303BA8FDCB190E47A0424 -:107D8000E8B178E09F6023EBB509FAF765C63A9F42 -:107D900087FEEF5A350A848BB1F8D62954CEAB1B37 -:107DA00045FDCD6F9D48F082D618820F46074730BB -:107DB00098C7C12D1DD83298C7613590FB7BECC7A1 -:107DC000124B7AA222F5B6A5B8EE83D1BEFCBB61F8 -:107DD000BC8A3F8F2C47BC2ED8A4B890CF2A5476AB -:107DE0005049C0F946517F15EA7B050BE1F998D25D -:107DF000589F219EEA19837A7540EC6A06B06A069C -:107E00007D11813F0F09FD626AE2F31EDE5A49FDD2 -:107E100069F5871D59B47E0D3675DC609C6E0BAD1F -:107E2000C7D4A45039BAF53A2AAB37551A1D30CE0B -:107E30005B79CF25219EA0BDCD13512F0F8C6711EB -:107E4000F497565A843E9E82FA18FA3D90E5FA025B -:107E5000E572DC9226A315F5A9CD6A7F1EF8605C59 -:107E6000515FC7ACB075A97B6E610EE0234B528B9E -:107E7000C905FD4F81325C7FDFD18EBDF9A64D7FF4 -:107E8000D752A9D925E65CC218F0F9ED763E6F4DC0 -:107E9000AE8E89F6DAFB4185CB876FB3C5FF3CFC1C -:107EA000FE5996E7279C6F70189BFC1AE9D3604631 -:107EB00065EC3F6FFE405F2BD23FCED8C412E07D11 -:107EC00043A6367F2ED7579A7F8B98FF61952D4614 -:107ED000BE387CC30D4117CCABF1BEFEFDD13E6870 -:107EE000E325669AA93F666FB988FC5ABD2BC6B1D7 -:107EF0001AD65701B441B865A7C5BF3E939E332536 -:107F0000094BCB7A05EAABE35A72D1FE94EE8E0AA6 -:107F100020DF36EE8E32A21D7933C79398D9119F98 -:107F2000772F5380BF5D3B2C46E48364872B29B3B6 -:107F3000B0FDF95E498F69F2A8E733CF2A2E7F1E84 -:107F40002187D304DF4E177238CDE88CFF25CCFB98 -:107F50008E7754867A7CFA12A5D7A602D469B1CE60 -:107F60009C3039D4E4CD847CD91FF993F3E5BCD699 -:107F70000E42BE3345BF5C0E2AC040237E2AAEEBC4 -:107F8000E047F95ED09A48ED3479D5E4343DDB53CF -:107F90008AEBAE5806F20DE37896A614A0BC84F8DE -:107FA000C46C477E023E499E15C607CB1A7F342219 -:107FB0009F988A15E2130B94A5617CE46EF353EC51 -:107FC000233AC13CC62DCF34AC66A1FA72E4978E39 -:107FD00057CFEF85A2FD745B20C700FD996AA29C74 -:107FE0004B615EE7921CA4C7163D0000A06091C9DA -:107FF0005D8A7EC6A2DF294ED4BFE87FA0FE19703D -:10800000ACC6EC099BDF2DADBD9903F034B1B51BB7 -:1080100095FD333C93100FD35A27093CF6A69239AD -:108020008A0C389F7BACDCCE9CAFB9FF761CEFBCD2 -:10803000DFE2C4F1182BE2F416F32D74393BFF1282 -:10804000E7F78E893D0BEDCF44795494CB33E9CCDF -:10805000FE384C71C65AA033F47BC6C47C76A0E7C8 -:108060004C803D087760AE0EFD50EE609D6176E578 -:1080700082B12E8365037D17FDE55323A8C239B96C -:10808000C1DE011877EA306EFF9B3798C8FECF6BD0 -:108090007C6F8001EABFCE747566A07BC774F1D493 -:1080A000E07AE64EF0BF6202F8AE875F8F1BE4080D -:1080B000E1B3DE18C831C2FBF580471FCCABFE210F -:1080C000B5DCCFFD9E98CA5E57E6EBB9ADD9841FEB -:1080D000CDDE68FA7BAB37191611D2E357B2431ADB -:1080E0007FCF1772301FE58085DB9B4AF730E4C3F2 -:1080F0003CC599C3C2ED0D97074D4F03BF93DC54A8 -:1081000064A73B97B190DED6DBA3BD6AFDE3836134 -:10811000BDCBB33CEB510F94FCE9BF5EFF18AAE660 -:10812000BDF66219D269D8750A5395ABD1933F9ABF -:10813000484F2EA964A427A10CD793A676FCF43F40 -:10814000645E9B9EFF57C1F7E0DF92DF887A3CBCFC -:10815000BFCFB24AB6219D77652A5CEFFE93E6ADAC -:10816000D7EFBBDAE4F5EAF4FB4BA2FD95F4FB1183 -:10817000D4EF8597EA7306FDA13EFFDBCE1E7ED4C9 -:10818000F79F32D0FF68DF76C4389E17FA9EEC4125 -:1081900074BCFF72FAFEB19C1947103F11F4FD7BCD -:1081A000FF0C7DAFF1975E1EF472A0E7FB310F82EA -:1081B000FF8574DAAA30D4AF217F8B111F1FCCE268 -:1081C0007CACC94D98FF45761EE4C19F9379A95CAC -:1081D0007E5FF3970207C69B05B17D9912E2774D4A -:1081E0005E347ED7DB9139591E35AB302427F35EE0 -:1081F000D3DB81F6F8699B09E357D3BCEFB81D8048 -:1082000032DC0EB4E7EF58B3AE4D0EFEE32AF92987 -:1082100035EB7F9C9F52B322F3535A56C77F9C9FE6 -:108220002E4347B2331A9F8D799BF307CBE6FE3E70 -:10823000F00BCDFBA039DDBF2C13F51ED787637E75 -:10824000663588CF3B443E41E3D711D91E17CE5344 -:10825000A333FAF7E8B75FAD5F3825A986B9E0F92F -:108260001D5086EB0D0BD22F827F3FFC1AE9DC3FBD -:10827000EBEAE83C49D0F99FE8174ECB8AE0173289 -:1082800017B7FF21BA582622DF7C1F303294AFF691 -:10829000E86A5ACBF1AEC12B0246CDBE26A27D05BF -:1082A0007E99FEDFE1978AD2FAF35670FD7CEB8B64 -:1082B0002B8D83001F454CE43F86AE717543FD0254 -:1082C000BF0FA61E293F725815B0EFFA2365308FF5 -:1082D000318FB7D5FBB07E78717C5B3E054309AD2D -:1082E000BD77FD90230FD1BCEB38BE3D4D4677AF37 -:1082F00030B800E0D830B84807AFE3EDD18ED8A948 -:108300001F3F974FE85FE987B0D69F9003D632A210 -:1083100003FA8B9B143BE6436E2DFE9B19E95351E8 -:10832000DA742015D6FBF8FAE195B61EF01CF5209C -:10833000CCF7B9F5156B7C46F17E27CA8FD18FA596 -:108340005E71A940A779458A3F2BF3523C3E9725A1 -:10835000DB33FC31CAEF3373C1B5BD8FF24BEF672E -:10836000D1FB01CB358C7F733173F923E8C957B545 -:10837000761701D6FA07DC4DACE771B8BEFD3621A1 -:108380006F4183613E037C35AE9FB606F365C3192A -:10839000E78FBDEB3D95980F2342EBD67BB9F9FEF5 -:1083A000214B8EEFF0C721BF1FB81CBE5EBEE47D1F -:1083B000C11F5532BFC41BDDFBBE8779C427297698 -:1083C000F46B17B8A31E42FFBDA254E3EFBB2A5DB6 -:1083D000C5B0BE2826E5FF42FC3DAF12F97B01D3B4 -:1083E000DA2F588376C96D686BCFF97D87D2F67E18 -:1083F0001EF00FA5E2E0FD13EBE7AFF1D9881E54A4 -:108400004F70B7CBF07BBD0E2ED6C987E06F924F71 -:10841000D4DB809F9C087AE33F059DBF55D864D488 -:108420007BC112EEEF05B378D9259BFB77866CDE16 -:108430002E3A5BD0393A0C0F69213AC34F00E388DA -:10844000B075139E6E49D2D6FD70E55858573081ED -:10845000F552804F92B21F58B33C8C4F3A653F5C47 -:10846000897808F5F7E011D4FBB7083C75C97EE8B8 -:10847000888FEB3305E56E3E3104F0C126C5A7C2F7 -:108480003AE7231F4458E7E94BE5C6A77BDF65BA07 -:10849000CCFB5F5FCA872EDDFBCC94742DEF0B3ACB -:1084A0008DD5D1B15C47C7321D3C5583FD923ED37B -:1084B000F4DCF486352B3A2561BE51413381FADA7A -:1084C000ACF465ACCF734F56DA0621BF3A4CA9A085 -:1084D000F3FB3FB7F6881578B912F519F1EFEFD62F -:1084E000B8801F27A2BC13FC54A5AB0FF24FCD8A56 -:1084F00064683FE8B9DFAFB142D35B97AF31A14FBA -:1085000033F4B9A7D718817EB714FCF900F667AC2D -:10851000FDB72363332FC3AF75BA75ACD3C13E5DCE -:10852000FB27AEA0DF97EBDE5FA2AB7F4807AFD59E -:10853000C1ABE4F7A7CD54484EA601FD1071579288 -:108540009B89D96D79A4367BA6D8C84F92F87ECC8A -:10855000320EDFF6DCCB95ABF2C3E0EC3F5786F38F -:10856000B189F19F2949CC87F6C3D48E3E1B93DD98 -:108570000E1FE5E9ED1DAFFF0C7F4DA17D16C92E45 -:10858000EF5565B851D5E6BDF3C83D367CA8C13B73 -:108590002AD11F6F77DF83BD5189FB1E631E15B083 -:1085A0006F5B25EA3D6D9D5AFB113FFDACE278778C -:1085B000676FABDC80FB2A25811CCCD74F4DE025B3 -:1085C000D81915ED58B5C8778CD8A9BAD1CE4C8D2D -:1085D0000EE42CCA0F5B27ABCFC57536DEA7127D24 -:1085E0007CCB783C329D39CD98AF688C8F5FFC0294 -:1085F000B4DF7B9FBA18EDDAA78B133BE1FCF7657C -:1086000073BF6D6F7CD74E7702DC18738719F3B593 -:108610008DF70FA7728FEA5AD9027CBCE6B9836442 -:10862000E71B63E2093F0F67EFABAC05B9A8CB7658 -:10863000D0FB9E047BA706F457579B18E6ABC1916D -:108640007A86F8E6614BDFD5308F69B5D7D1FED198 -:10865000F47FAD1C9102EDA6AF30D1BE02FCF4C692 -:10866000797B560F3763FDCCE5A2F48DA472F7DF5A -:108670005F7FBB37B46F794075AE87C6BB5AB3E234 -:10868000A6C3BC4E45713DFC7973B7389C678F6EAD -:108690009E75D9C8AF71B1D10A1A0FBB236E02F40F -:1086A0009B9BE37A3ABB63A8FDEEBFABB40FB6BDAC -:1086B000797A27CC3FFD41E8EF5DADD33B4D0FB359 -:1086C000F7B3BE35129E779B1DF7A07FB93B3A5D8D -:1086D000C1BC0CE03911F3B633857F0DFCB2F8F55F -:1086E0000876FF896C95F072DAB2989D02266E7C4E -:1086F000B06331CE537B4FDB7F33A539FA85FBD195 -:108700001BBA96BC8EEB08F1D96747906FC88F06ED -:1087100078D7739FACF1A12DDC0BFE3FCE23C9357A -:1087200002EBD99244BE0F9A5C9F1B9E8F08F9A959 -:108730004B853EE0ED4EF862296E3DF152941FE309 -:108740009913BE4F62C3F3EF9A9CCC8E8BF5A13187 -:10875000FE2A36D68878FDD4E8FDF257B86FF8B413 -:1087600089F4E8ACA73B2E69417D00F4C47C907E7F -:10877000DCE46E261AB7FDFDC1E6CAB2B430396139 -:10878000CD95AEFCF6E5E4D873DF546EB0B52F2777 -:10879000B385DF3EE269931BF97C7661AC11F7E9A2 -:1087A0004A9EDEFF3CF2E3EC8551FD2C30F1D94FBF -:1087B0005B88BE4DB1B13E3BEE23C6C51A3B40F9C6 -:1087C000ADD0234DB55114A7A89DCCA4F7D4958561 -:1087D0000EC44FA9CA8C56B02B6A9CD3E1E6F07246 -:1087E000CC1BAE882D72207D3B76E3F2D0561F3F26 -:1087F00079B4D23BB46F7676F1E34F0E84F97DCD38 -:10880000FC930666FEF7F7D1AA993B1EF38FFF5340 -:10881000FB68E66EFA7DB4FCF89B91FD16AB346FF5 -:108820007569941FF1A966703B319229B48FC6EC2B -:10883000B0FE5EA17D34F5D7FD093FA7BDC057DD71 -:10884000012F71566AAFFE5AF55B60DCD2449E6F11 -:10885000559FAC64B8AF0678F5D9011E995443FB17 -:108860006B4B859E99A630773DC9BF3303E3E4592E -:108870004F47111D673F33E7C3DF1520DD2A92C242 -:10888000E52953F01FF4C7AC09A17EBEAAFD4D0631 -:10889000CEA7F4DF20BEC4B853F53C790BE9CD1860 -:1088A000DA6F63F6A6870722BFD4C6F4C53CF9EC9D -:1088B000A75332B2F243EFCF5E7A5F2E7F1FE2D62C -:1088C00038D45B51B49E799B2CC42FD31E505D6469 -:1088D00027D3CD64273F5F1E45F0BCB42292B76911 -:1088E00006BEFF063E6132E9778E7236CFC65CAFB8 -:1088F000DB50DF3F1454397D7C826E66A44F71B724 -:108900004492CB3B10C760BFA622BF75A4FE781E61 -:108910006A9742FB4D8CD538500F4C3528A4EFF4A4 -:108920007259D18DFBAFD3329CB7E37BF31FB138C3 -:108930009766F239A8DA7C206E9A6F08CEC27D481D -:10894000B6C542F98D6A5847541C3FF7F01ACCBFA0 -:10895000DAC88C66CC4F39B85ED3E653EDA81C89D3 -:10896000FC0AF5C78C503F3F96EBE5F91D78DE8792 -:10897000C55AFDCF878F8773CEE6EF39E250DE060A -:1089800011BFA0FC1BA0FE6F8CD797C615399AF2B9 -:1089900069FF7E15E64B703E3D7A878D0B704A6FFE -:1089A000E4C785C6AC58A443E2A4C938DECB2AE9A3 -:1089B0002710AA478AD00F7C59ED8FF1ECB407F647 -:1089C0008E588BF0AB7DED388569AFBC4F76EA2EC3 -:1089D000C1674DE8FFA3DD02F85528EFEDC6F5832A -:1089E00047E5F99C7BBB29D2BE9F563FFF0113D1BF -:1089F00063FE0ACE0FF36BFF42FDCE8F0D76427AF7 -:108A0000CCDF6C1A807CFD2F62DED36BD38B8F01A1 -:108A10007F4C37C5DB157834CF576146785E9D4271 -:108A2000B036DEFC073EE864C8E7FD6169117C14DE -:108A3000EAB76306DAB56F5E4ACC981646F76F96CA -:108A40006F8DC37DED5351811C3BE663164639D7CC -:108A5000939C727A7CB33C673DE66B66DA83B1B86F -:108A60001F3EF39EEC04B4779FDA0366ACFFB43E7E -:108A7000D380B0CB6E2F46D865EC43F037E29C0A2A -:108A8000FD009D16289C6FE6BDB4D79C05E33D27ED -:108A9000F8ECDB97DFCFC5BCC1FC8C602EDA61E05F -:108AA000ABDC54A4CB1F15F21716BCA4BAA27A876C -:108AB000F86A01F215C8FF5CC1570B366DFD25CA77 -:108AC000E902E4A77E97F225C497FBE8F96BCF8E05 -:108AD00060FCFD7DC8779ADD0778B909F36B660104 -:108AE000C338086F10FA1AEACB78BD2F9FEC096BD8 -:108AF00032A35F5CAD727F01E42919FD89EA069318 -:108B0000AF294C3F2EC0FAFC507D7B7CB3BF9BD875 -:108B10002FABB5905DDA2FF0D2F4C0E638E48B6F5E -:108B20005FDE7B6030C659AF2976D4FB97C8A1C001 -:108B30005B35E2298ED649FE5135E2252E84A736D3 -:108B400079137C51CD381E34BC541B059EB47AF188 -:108B5000FE01C187F398C0EBA6EE5CDE857C03C7FF -:108B6000901DD1D6E74990CF0FFC20F8FEA858E71A -:108B70003CE01B673EF197CB3C40C4FF50F5EDABAA -:108B8000CF52FE48A3A736EFF81C87A6A75D1D129B -:108B900042746E32B0AA48F9EAAF85DC996C5CAFDA -:108BA0009CAC4DBD7D31E06FEE4BAA939087B157E1 -:108BB000D8B81643532CF9A7BF56EDB8AED23F55DF -:108BC0008EC6756B7C67DAA8181B709F907520FCA9 -:108BD0006BF32BEDEC1EDD81F35D00E7A3CDF3A479 -:108BE00012207AF95E55ECDCDF6D32631E5193532F -:108BF000FD7C7F10F355E394C14A1F9C8FD381F213 -:108C0000CDC00ED27C6CC7EEA3F17C27EECBEC1D61 -:108C10001AE7535FAC11DB7DCAB81ED0F8F2A4C8C6 -:108C20004B9C5CB195FC616D9CD81CCE5761E37880 -:108C300016275D3A8ED6DE94C3E7A5C9C5C104CE1A -:108C4000FFA5CBFF42ED343D8B3F988FD3F0A9E1D8 -:108C50002D4C2E25FC68F2A5C99346D77F54AED87B -:108C6000928EE4B7DE2FD64D32D2296417903FD1D1 -:108C7000DE59CCFC1C5C98DD24BF6664DA77664F55 -:108C800084E71A9EF4CF4371953D03F13FD2964C91 -:108C9000FBE56C79F2BE6E61FED929CC7BA13E7DED -:108CA00051F5933E65209561F65CF3DB6A178EB44F -:108CB0000F43FE7A49A173479AFD869F87DAF8141D -:108CC000FAAB2A58988BFEC4EA9C2C1ABF3AC97595 -:108CD00016DF9F77263822CE118A5F869E0FA8F175 -:108CE000981FDC9429C50FF39AF7919CCF67C19523 -:108CF00018EF4E7BE0FD8A8148FF174D747E616658 -:108D00005D26D9BFB31B66F4C7D076DA8A1C82E72A -:108D10003C7F27871FE07EDDB415852F607EFE54E3 -:108D2000946B04F279CB1AC58EF1D790E70B97DCE0 -:108D30000AF54362BB76C0F99ED870AA6230C611AC -:108D40008B55921BD786C72761BDAB4175E2126771 -:108D500032FB925B91CF8DF12477DAB9C66526CECE -:108D60006F77E670BD715B0ED71BB709FE2D5DB640 -:108D70002C17CF15B43C0B760AF7D7CD8EFA00C668 -:108D8000813B3B3BD7C338D510B626033F9D51B836 -:108D90003F5E656656E4AF43A6E0BD38FF43F7C6C5 -:108DA000F6ADC509A81707A07CB844DC0571148D81 -:108DB000ABE14B1B7FA61857EB477BEF20FA5568BA -:108DC00047C47CCF2E7F7112FA0B6737E624B03090 -:108DD000BC9FC57501BEE7807E7C2D423CB8304704 -:108DE000CB4FF8A9AC1279C443A6BA34DCCF05BF87 -:108DF000FE74B87FFED5B35156E44BF0EBE5E726A1 -:108E00006E57C09F979E83FC48705BBCA74E8DF742 -:108E100044D0475AA9F7F797E7D822FAFB9AFC5DA6 -:108E2000A2D7847FDF9677E9766DE7BA9ABD4018BE -:108E300010886274CEE0FDB2989F5EC7F397B3EAE4 -:108E40002C760BE0F734CA17EE0B6E56B9BF68E507 -:108E5000F2767A675F3FE615661D67CE00C0B38E77 -:108E6000AA4E07B4DFB7E67E3ADF71E73A8575565A -:108E7000C2E2AE27D64C42713BE7F4AC4C81F6E738 -:108E800036F2F328506DD3C55B07521CEDC75BFF6C -:108E9000AC384BCB3FE9F1BF2907E2AD18F8C5C9A3 -:108EA0009C32FE79DCBE1BD8A8A8DFA5F86FF67A45 -:108EB00028AEFAABB78ACA41F5CF96A6C23AFEA64B -:108EC0009C7C6408CA516C3CE54F9ABD35B439F8B6 -:108ED000D786FE17C7019EB6DBE2EDA83FFEEA5D2E -:108EE0004CCFDBF846F0E9D04D8D6A2AA3F63B86DD -:108EF00040FB5DB678DCEE88B00FC7E9AC3F7F730E -:108F0000F7C2819DF1B9B6DEAF7FC5E9DD66C7372F -:108F1000CE88437FB5F1F7893B06219D63E2EDC81A -:108F20000AB3C5399C2FD7727D74C61AFF02E65169 -:108F3000CFAC9BD809E3C33B4D2D6627F4EBDC593E -:108F40001987F9822F8C4D71762CA17D00E761F491 -:108F5000ABA807079733DA1F1C1C303247266DDD9C -:108F600013FF0C6A36FA316EFE06F70DD18E5F8C58 -:108F7000E6FBF7623FF0CE6D3CCFD6965711F985F0 -:108F80002162BD1D7213B47D207A5E5AC49F7FB5E5 -:108F9000EEF571D8DFD90D263BCEF7AF1B4CD4FFD1 -:108FA0005C88EF0DC08F6736F2F3027377409C9CAC -:108FB000897A4421FE9D0BFC6B45FE5B687299E348 -:108FC0002FE5CBD28D3CBE9E5BAF50BCADF1E75CD4 -:108FD000977F04E15DF0A915FEFD0CA6A303AB5F2E -:108FE00089F8688F5FFFD17C803537723E40CF0FA4 -:108FF0001ADE34BE08F12923FED4E89F50DF7758EB -:109000002ABDE0237CFA4A581EFA0BCBCC2C0FCF9A -:1090100043F90CD14E94FB1FA2E27A631E6AB1950C -:1090200097BF8C8E5B8FE50F51197E9CF70F06FB67 -:109030007E8CB3BCB999C4B7BF541D26057E9D98DC -:10904000D4544666A0D4E032A01D5C66213DA2D770 -:109050004339B9220F98CBA81C96CBCF899B580DCA -:10906000F9175A09FE403AFA2F95310917F0287975 -:10907000BF173A4FC4FDDECA2109F76683E739F806 -:1090800085F48946E0F3CAFE099BB3002ECE4DE37A -:10909000709F844213C0B5B51913CBA0FD2DB92E16 -:1090A000676ED8385ABFF0BC3F3E1F99E219908BCB -:1090B000F6DF6C5B8576E06F4ACB02831A6A7F44E9 -:1090C000619F6E574270938965A0BF3DAC6DFE9164 -:1090D000CB55B9AE1B72233C9FCED80ACC4B4CF774 -:1090E000BD794C217DC6DC56A0E778C17FD3ADB6F3 -:1090F00000E9B955A6E636FEC8423D156F44BA8F61 -:1091000013641F6F0C34E2FB3DD872FB9756721547 -:10911000D7FD9CD8BEFE0741655F6AFDC1FAFE66B9 -:1091200082F5025D1517D01A444C01244F057DA726 -:10913000EC78F347EC77998F3545111DA6DA910F3E -:1091400015E631FC0CE5FC18E08B3E58023F40BBB5 -:10915000459BBFDD87623147F3B33C45E42FDE63B7 -:10916000E7EB619EC1C4AFF70A7EFDCACB6A3055FA -:10917000343E188CC3A3B0CDE302B9A81FCA554F23 -:1091800015D2E1AB75CBD21601FF7CFB9AC539161F -:10919000DA9FF1BF1E8776759EF0F7D945357003CB -:1091A000D41FCCECB17E75187F2DCCE576BF39335A -:1091B00090711FEA994C1EAFB28B7B33EE83F6E5BC -:1091C00059A30A5713165C77E786ED4F8E33463E58 -:1091D000BF31298DFBEB6C03B7C71623F3C52650AF -:1091E000C9E2004FA3602E45782E156095F6F3FD79 -:1091F000D41EDBC5A15FE39891CCF77B981BF59655 -:10920000465F8D6E97D013A68C7EBDC1CA4CB8DE6A -:109210001E6C9D1DED9346D7AF843C7E65E572388C -:109220005CB5919E5AB499E7F516295CDF2EDAA950 -:10923000F0FCE625F676F34AD4C955EB66903ED3AA -:10924000F49803FE217FCDB5BBE3038E7FC0EEAE65 -:109250002BBD2A7DB65ED3677D595FE4BF2BF94BEA -:109260009A1E03F2BC98DBF11AE885288375CF16A5 -:10927000731CAE4E7518112F1DAD4ED4E78B9ECECC -:10928000263BC92EAE65E1EDD8BA44E2DF95992AB6 -:10929000D1B5A2219539E0D19C0685CEC98E6D4805 -:1092A0002438AE3585E08A3F742EC175B7ED83FE54 -:1092B000A13BC1675F78BBC0C3F33456ECDFCDB4CC -:1092C00079E4D7A3FD39678379009EDDB65594779D -:1092D00074B3B67848F9594118B806E5CE65F2710D -:1092E000FA586B49FEC5BA1609B95A7488DBEB45C2 -:1092F000C3F87EA1D1D7231EE96F3AA8323FC03709 -:109300001D520B03D07499D0E79664037384D12D5A -:10931000CA11CD1C61F4613E5710E3ADC9825FEE06 -:109320008FE27A3F262F416A37D9368BF82798315A -:10933000E220AE37D6D945EA9779B87FACF1D5248B -:1093400091371FC75A96A39DBC6932D487F5672A07 -:10935000FE8EEC86A958F6AB012FA72FC74FCD1A6A -:109360003FF5603D889F74F801F9207B7FEE28BFB0 -:109370007F025EC96F8B019E74D0C4FC50BF42E077 -:1093800005FD568C7FCEB962496E34BE0BA2DD035B -:109390003D175F24E3AD834BC65B62B98C9F8E6E35 -:1093A000191F9D276749F5299E9E527D6A553F09E1 -:1093B0004EAF192CB5EFBAB84482337DA3A5F6D9C8 -:1093C000AB2648704EDDAD52FBEE6BA74BF53DFC76 -:1093D00073A5FAEB362E92E05EF5BF96DAF7695880 -:1093E0002AD5F70DAC96EAFB1F7C4C820B834F49C4 -:1093F000ED071E5B2FD50F6AFAA3543FE4CC6B1226 -:109400003CB4E50DA9FD0DAD7B2478187B5B6A5F4C -:109410006A7D5F8287DB3F91DA8F4C3E25D58F7264 -:109420007C23D58FC9FB5E8257083FA7C2F95FD264 -:109430007B4188D8908F73D23C43BB53DEE78C11BD -:10944000E5EFD86D0A4BC4F8E7E0443BC9FD35C6EB -:1094500081C3BB8B3844F0F10566BB1DCFB35F49B8 -:109460002F66A33F51887C3E96EE559DABE7F90EE3 -:10947000BD5DD7FCB97830CBC6B0713BB8AC10D06D -:1094800087E0C472BB047774274BED3B4F7648F5F9 -:10949000299E3CA93EB5CA29C1E9354552FBAE8B90 -:1094A0005D129CE92B97DA67AF724B704EDD64A9B1 -:1094B0007DF7B51EA9BE87BF4AAABF6E638D04F7AC -:1094C000AA5F2CB5EFD3E093EAFB065649F5FD0FF2 -:1094D000D649706170ADD47EE031BF543FA869A316 -:1094E000543FE44CBD040F6D6990DADFD01A90E070 -:1094F00061EC90D4BED47A448287DB3F92DA8F4C01 -:109500003E29D58F729C95EAE77DE30CD0BED476D8 -:109510007EDF55F3E7C6E47D27B5332581BF8FF99C -:109520006F16EDC4F3FEEDF9F99A1F58E1FC511ADC -:10953000F70703F7CF5FEA9E25FC7FEE272EF3B9EE -:10954000E97C5E021E78053989F729C47F18624DCF -:10955000A57C6412ED5B90C974E07937F083004814 -:10956000306466621C1213F263D37EEE7FF57EECEC -:109570001B10E3A05F7DB6BBE7CF289773EB5F1DA1 -:109580008171CE1CE65B89F300BB1B8FFB58EF4655 -:10959000C9F928AD1C65053C868D7728AA2EADDF5C -:1095A00065E47794B599DAB7F52BF2550AAC6F51AB -:1095B00058FF8F40FC650439ADF3829C41A0FD98B3 -:1095C000D74EF013DE64829FF43AA85CEBCDA3F291 -:1095D00029AF93EAD7798B087EC6EB22D8EF2DA767 -:1095E00072BDD74DCF37782713FC82D743E5466F3E -:1095F00015957FF4D650FD4BDEC504BFE2F55159F9 -:10960000EF5D45CF5FF3D611BCC9BB96E02D5E3F41 -:10961000950DDE8D54BEE1ADA7FA1DDE0682777989 -:10962000030407BC0709DEE30D12BCCF7B8CE0030B -:10963000DE262A0F7ACF50F996B785EADFF1B61207 -:10964000DC2CF613BEEAAE48F7183598B132E207C3 -:10965000CDFF1D87710F324791E9AF52DCA38B3FDD -:10966000F4F4F85A8C632A01F717FD9F2EB9EB9793 -:1096700085C505DF8BF1EE8F66BE2890875A03CF34 -:109680000BD42630BA1FC6847F3E5BF0254BE27EAA -:10969000F92C31AFD9420E0A913FF3883FDFB996DA -:1096A000384B8BB7ED191E350FF933DDE0A3BC83C2 -:1096B0008DDFC3EF9FE131E7811C9DABB9F3008DD6 -:1096C0006777E6E220159640C79B319F7448A53C1A -:1096D0006C7BE3558B7B12EDD6EF3A9B86F6A8FCAC -:1096E000EF2AE5EBDF35C54EC67C4B721EC74B72C9 -:1096F0009E412A7764B83BE33CBFCAA979E16E2555 -:1097000074FF7F3C86E620E795CC61A273B8CCB5A8 -:109710001FAFDEDC040E1FC237331F9525E91E077D -:10972000BE7F0B0418087B065B3222AD473F9F9E2D -:1097300079DC7FEF996790CA8F32DC3D103FA773C9 -:109740005CD27CE2BA3AC47D9C9667705EFFB1F34E -:10975000BB2F95EC10BEB5FCC6CA61E29CD6424553 -:10976000DB07E77EA295697E22D54FBD97E77B3464 -:109770007B79BCADE4FAF05C8D89F4E65425DA8996 -:10978000FEF6B99A7BFBE07EE16D10EFE1FEA9A643 -:1097900047A7026C00782AE3E72EA61E8F253ED34A -:1097A000EB57788FE17EDF54F03F317E54BAF27C84 -:1097B000CABBEEEF4CD82F4B6AA17BABC037A3716D -:1097C000FD7307A9F4FD86770DFE5C45257E312BE0 -:1097D00030FFD949C02F11FC058D2F16887B39DA4F -:1097E00073E0B71B913E7FDD36308FF669760D72E0 -:1097F000203E9719F8BD3ADF5B2A3F9781A97C3C50 -:1098000037129FFF2CDD2F40E702E9372896EE172D -:1098100034AA6CF1AB11F4E9BD828EEF269BCAFD30 -:10982000D4AFBCAFB840D075816857B1E7503ADECD -:109830001B5C70D04471112B68CA7747385755BDEF -:10984000F8C15F740BE3F3EA8693FC3C166BCA0F16 -:109850003F87F5B0E06B8DBF5473ACE7595BF8FC04 -:10986000F8F8C0E7F7083EFF12FDFE711647FCCD81 -:10987000F06A13A02600A5E7DFEC749E4F3BD737B4 -:1098800093B9A99C0DE446BE76FBD6D0BDFAB9AC1F -:109890009E9E2F289A918170356B294B86FE6E5AB9 -:1098A00055BB3F196637B16ECD70CC734FF04FDBAF -:1098B0008F65E506E54B9F83E464058EDFA4D4AC99 -:1098C000E802E3DDFAD2B01598471EA7723AB0B7A6 -:1098D000391D809F5C6AC2A5EB03B97848C805CDE5 -:1098E0005F938BA94B994B490ADD03699393A2BB04 -:1098F0003E4BC53D16630B9D43A9DE6549C0FCC9BF -:109900005CC6ED76280FC4EDB526075F9B38DDBF3A -:109910007E59A17B365F2B8CBEE7D09EDFA0F99FDE -:10992000207F5CEE3E8DE1FCAF8ABC5E8627B95F8E -:1099300076C83E7F6DF00F88CB26FBBD11D7632A1A -:10994000F13CD417CFEBBDA23897C15CBEEEE0CF9F -:10995000E0E704DAEC00FB392694277CC4C4F376F4 -:109960007A7F575B477BF3B498990FF7B394A203C0 -:109970003FA21F72E97C3DC903002FCB904498970A -:109980002C713B22CD63B918FFE04F3C1EF7A53385 -:109990003A17A4C7A762E7E3B4975FB544F3F96841 -:1099A000764A9BE7A5F3E2F47A3F2F93E8AACD0F1E -:1099B00034459E1DC6371AA39D28AF9546CF7B8898 -:1099C0004F2DFFA6C5C50733BF227BC02E2E4BE30C -:1099D000E78F03EDD9E1E6B6783C2B6427B53C165A -:1099E0002B8E9C8F745BEDA4BF263027D98B1EEC89 -:1099F000B8862FCA63A9B84348795E0FADC382FA0F -:109A00001ACA28CCA390BDF4937CC6E0BC685D4123 -:109A1000CC88B03531718487C1C718E9E9C1B8066F -:109A200058EFCE93CC8FE7A91A2F4C2A8D85FA9D3B -:109A3000DF1A290EFA6DCC2BA9F81D899D673F4CC2 -:109A4000C57C4FED852D040F681E7196E7CF8E4FB4 -:109A5000C1FEB69F373B2CE4072C243C6879CAED45 -:109A60008C39711FB4E8231BDD332E3C5A1F437819 -:109A70001379B562B1EEE2F33C1FB20B81411007DE -:109A8000B4985920CC5F36D965B88885C1993824F7 -:109A9000C061798E6B8D1F637B883CC84036303C3B -:109AA000AFC65A1322DEA7D2EF2316287CDE67F258 -:109AB000DC9D7A50FE6C82CAF1FD7715F17583CD7D -:109AC0009F82FE6DE39C1752D0DFFD6DCCDF098FC6 -:109AD0004FFD644E41BCD60DFB0FB22375F06E10E6 -:109AE000E35FA33F8A51FE6B3EE5D76E1076F6A981 -:109AF0008B9FB364C0675D1123FBC9841DD6EAEB5D -:109B00002E9EAB427A5E28B63A502FE48A7C68EDEE -:109B1000F5FF99DC14868F9DE0570780C0DBC1AF4D -:109B20000E80EFBF0DFC6A84F1DE29969BC1AFC6A3 -:109B3000D20F7E3596CF805F8DEDD0AFC6F229F083 -:109B4000ABB15C0B7E35964F825F8DED9E00BF1AE8 -:109B5000CBC7C0AFC6E77517A797D27C8E31BA5F67 -:109B6000BF3426CE80FA15E61F8D79A1C3AE7ED113 -:109B7000888FEBCF1B24FA1637474BF0E0D309212F -:109B8000FA22FD8F7791EA071CCD92EA337D3D25BD -:109B9000B8EBE27E128CF9A1F0F753AB4A2438C53A -:109BA000335A6ADF79F20409EEE8BE556A9F583EDF -:109BB0005DAA7F344E4747FF3C834C47FE7D850BB3 -:109BC000C5363A5FD91E9F3E26E8A2C18FFF4A9D47 -:109BD0001C296F7B570F83140F741173BBBB8783D2 -:109BE0009EEF3B31F0C5DC02A487816F9BBA5A62BD -:109BF000BA015D721F37303C5748270E607E76F100 -:109C0000DEE325E762902FF75698A3903EBB5D25D3 -:109C1000D1082FAD30A784F3515DA6A71FDD53F007 -:109C2000F0F569EF3F5A32E1B2FBE88F21FF75BFD3 -:109C30004CFDE8B959280F97E09155D17E6D088FFA -:109C400013E8FB4ECC5325CD5F2F170C37E953702B -:109C50005CAB8C4F57D6038887A79E30D239ACB601 -:109C6000FEC4FB5A7FC3D58B314DF997CE7FB78B9E -:109C7000B707FF370AF1026349F34B703A86217E3A -:109C80007E27E4ED5F85BCFD56D015E35884999D91 -:109C9000BFA7D1ADAEEAB151B92837457C5EEB6FB5 -:109CA0007C4C417593C89CB5F630BC3E21E6F18CE6 -:109CB00058D73AEC17E08E37BA14C45FC662B78241 -:109CC000F2D6754913C14F09F94EAB69A1E7E9F71F -:109CD00004A8EC5215A4FAE1EA4BB48E363C386580 -:109CE0003CEAE9E417EBD1FA0DBDFFDA21E4B70B4A -:109CF0002E3EFF389FCD85F622CE6777F2D2214ADD -:109D0000A713F57E9CCF25E09A7C84B78975C5F9A9 -:109D10007C04FBC5BAEAAA920EBDE0088DC71CD52B -:109D200086707BD31E3F6D15F8DF2CF0A47F6F9BF0 -:109D3000A9A6BF3D825C69A5664F8B8E1B747A27EE -:109D40005A92FB43F80BB7037FE981F2E873AB62E9 -:109D5000FF8AF038B12D5E9A4AFCB426E6F6B73198 -:109D6000DEBEF1A8CAB8BD1DB71FF5E5FBA32C6484 -:109D70004F1B478D4C0FE7BB06B18EAD02EF837CC6 -:109D8000AE13F740FB316E0BE5E3073257FABDD057 -:109D9000DFE8B1AA3300FD1D6DB327EE187EDE812A -:109DA000DB9309620D7BC64E7C10C77FFF28E80558 -:109DB00047689E5AFDE6F289637A211D839C8EEDE9 -:109DC000E1E74D41AFFD625E7B05BD1A057FEF16F1 -:109DD000F664A7B027DBD19E5890CE45623DDC9E4D -:109DE0006C16F62488F604CA77853D7907ED099448 -:109DF00005A3B2CB486FE22536B22710A0D07982F6 -:109E000005D2BAB47995A7A912BD4624C548F42A4B -:109E1000B3254AF525C65409765DCC92E0EBCFF721 -:109E2000D4D929D9AE0C3E3D5867A74A2478C0D171 -:109E3000D1D2FB95AE8952FDF8A229527D85738659 -:109E400054CFC47E18DFA283327A9D4A71AED87790 -:109E5000D2FCA9F7CB55DAB719F481EA0C97DB42AB -:109E6000D6B64F66C07D32705F1C46ADBF2CA99E32 -:109E7000FCA8A326772A9EDFABAD043E84B2F82867 -:109E8000F869947C04BE06BFB7D03D92FC40F097C1 -:109E9000FA131D5AF87E93B66F3548B7FF343A5F10 -:109EA000DE9F2ABCC2FE94AB673B7E59B7C4ABF2BF -:109EB000CB40BEC8FFFA6DCCED7B916FB67D047EC2 -:109EC0002AFAB91FFD82FC2FCD6FDBFAC52FC8BF60 -:109ED000DDDA262F1E495E0A85DC6E399AD5D0045C -:109EE000F2B63959710A5493BC1469F2D224F4665B -:109EF00079353D1F20DEDB6A72C7A0FFB7F9D85263 -:109F0000D16F981E217F3D4C8F601CC912E4FAE48A -:109F1000D4507D162756787BC67AEAFAEBA78307DA -:109F2000EBDA97E8E0D1BAF61374F0ADBAF6D3A540 -:109F3000FA0658F7E5FCEDCD423F68ED0A8D6ED587 -:109F40001941DF0E382AEB57E6AE96CE3D349E9887 -:109F5000457A73CBF195028F55127DF668E31C05A7 -:109F60003CE75FFA7E89D117D31BF8A0E498D1595A -:109F7000EB08D14FA313C37838ACBF52AB2AC95FEB -:109F8000C3314EDFF6D6B94BE8E71DC2CEBCA1F314 -:109F9000DFD49FCEBF3F1EF8674B9381E2AB2D47C6 -:109FA0002724627FBB2FCEA4F9361C33D03DB217D5 -:109FB0007B8EBFA9B65B687EDA7C0A3F581A83FBAA -:109FC000AC179A0CA4FF0A4DEE447B04BCEBF9AB32 -:109FD000BD7E35BE05072A11F1B21BEC109D1B1684 -:109FE000FA54C3CB9E134F12DEB71D5B948878BF23 -:109FF000A1D520E165688BECAF0F399320C1034FE9 -:10A00000727F10ECAE84DF2BCD5B2F17B83322C3E9 -:10A010005DE4F657E90F6C1774DA26E8B43DCA39E7 -:10A0200039D2BEC6B64FCD55E1DF5538D393E7DB05 -:10A03000CEF4E4F9AFCD4047D4B3174E1B48CF0E52 -:10A04000B1D7AB3511E851DC6CD0D909D96FB8D68E -:10A0500078F5543B7AB1BDF735BD58A27D3F2578E0 -:10A0600063C4F3B1213A8873953A7C6A7EF495E92A -:10A07000A69D47D7D1AF9DF743FDF8F4F134BB0E51 -:10A08000FB69AA247BB326E65DA1CFDF257DFEDE3A -:10A090008F429FFFD889FCA423A33AA7A31C1D6964 -:10A0A000D3E32C365C8F6BE72183CDEFC584FBF9BE -:10A0B0006EC18F3B5DEF8FE983F4ECA6FEAFFA3BF8 -:10A0C000EF0A7FE71DF477BAE33E10F7770EB96623 -:10A0D000707F2759A1EFC52C8DB9DEE889C0A7FF95 -:10A0E000D7FD9CF145B29F53E194FD1C6DFF60B715 -:10A0F0005DA1735863F264BF6737FE827926ABE2D5 -:10A10000C77B5CDB5D132FAB870342BE0F09FABC34 -:10A1100029F4F07E1137EC40FC135DCA055D78BE72 -:10A12000A2F8BCD3E674207DAA785C96574DF1F472 -:10A1300050CDBE7B6BA8FD910BD3CFE3FDFEDDF6CA -:10A1400018CAB3ECC6F9C0128E983CE7F1FB15BBF8 -:10A150005D8A636984B87E488BAC07343F41E3CBAA -:10A16000DDCD9F135FEE6ABDBC3DD5F497D6EE4DB5 -:10A17000F67A29E2E7FA66C6306EB892FED1DBC500 -:10A180002B8DA36F3FC458AF46B23BFA71DCAD01D3 -:10A1900015CF3FEF6C0926E2769D3B7048C57BE00A -:10A1A000C52D019AEF3E97625733A95D299E8B7E9C -:10A1B000F3E27B63F0F9AEF3468385F699EC24B7BE -:10A1C000C5423EDFB968B03909BF2AED73045A3E73 -:10A1D0007F10E5D56755E9BEC8EE8BFD92C2F1F65A -:10A1E000E8752AE993ED651603E697B79F378AF37A -:10A1F000D601F21F76B466D9B0DCEE02F9217D11EA -:10A2000024FCFFFE3A7E4E7527F4C7F58483E6A151 -:10A21000F141E0BCA13CD2F7767E2FC61B72F1B3B0 -:10A2200018C4CF81F37B62505FED6AE1E30C59D231 -:10A23000148371E6DBAD86589E57E99F84CF1B8758 -:10A24000DF6FEB87EB6A31F0FD1BE1D768E3ED2EA2 -:10A250009B4DF9FCDD2D3C0EDB7D9EE78FB6FBF9B7 -:10A26000B93526F498D67EFBF909637A61FEC06F92 -:10A27000A2F643987F651CB4DBDF71EB7574BEC634 -:10A28000378F85EBBD52BBECE794B4E8EC93671EC7 -:10A29000C981468723DF4DB8B192CED7733D39CA05 -:10A2A00028EB975DE797264DC0F16D7C7CE6E7EFE4 -:10A2B0006BF119FE18C3BEBB523BFCE68915D8DF13 -:10A2C000667ECE6C884DD6674786CDF8FD7C3CFF18 -:10A2D000BF2986ECEC765C3FF67F9451FE6C77F9F3 -:10A2E000E3A57198B76E664EEEC7C97ABDF4C2A6F3 -:10A2F000BD71D0FEBD0D0AE177649EBCDE9DAEEC63 -:10A3000087310EBED0CCF1ABE59334B9DCD39C7071 -:10A310001BE9A732781BF0F85EF9EB94C79EE39730 -:10A32000FB19B831469AF7FCA6045DFC26E7C7C1C5 -:10A33000DFD4F203B68A01A1F8ADB095E7D707FEE6 -:10A3400034A17F00E65B5CC6CFCFEBF3E2A38C16B3 -:10A35000D9CFD2E5C50BF57971BD3D17FED800B157 -:10A36000AF7189FF23EC9C966FD8660A4C715F83AE -:10A37000FF30C808A10B9DEBF5241600FEDF10FE90 -:10A38000E52073DDDD29202A5B55DF1016E6173046 -:10A39000BB8F250D08C5B7834FCBF140D171992FE5 -:10A3A000217EFC12E3C955B8A74972E0E379D0AB2E -:10A3B000F433D6C4F46E6802BA0E3CCAC47EC7BF7A -:10A3C000EC45BE6AF842DBCF00D7A313EECF33F2E1 -:10A3D000B71BBF3013DF6D19CEED94E6A768FB34D1 -:10A3E00037B2A6E5A50A9ECBB6AE68027C6E3A32BD -:10A3F0002B7501F4FFC1C7B4DDC9B6146ADFA7AF7E -:10A4000093E2CB815A1EEAB8C1975880FEBA4592B2 -:10A410006BADBEE1F8D218FCBEC885A081F8B4F1DE -:10A420002333C3BF0FD0B0C342FB390DC7CCB4DF59 -:10A43000B26D0797132DEFACF9F96F097D7E50F8D7 -:10A44000BD0784DFB24FF82D7B84DF12107ECB2E48 -:10A45000E1B7EC107ECB1BC26E6E3A2EE46F498CD6 -:10A460009F7FC796E765B579DED1BDE98411165C9B -:10A47000FDF180B50186F65C9693510E594E462645 -:10A48000CBFA63B83D556A5F6ACD96EA87B1EBA413 -:10A49000FA1B5AFBE9E291C1BA78A444E78F8C9188 -:10A4A000E5F26858BC4BF1B51CEFDE141EEF6622D6 -:10A4B0009D781CB8ADE931A2E3B6D359F1E17ED95C -:10A4C0001B426EB69DE6F6F98D33E76223F96D67A0 -:10A4D000043DBE16F468167ECA4D29AEDBF30B317F -:10A4E000AE3867C6731FEDF1B3F6BEF6DE19FFA9ED -:10A4F000B870FBF705058D21F8DB2D9FE452FEE4D3 -:10A500002AE563592C3FE7B65989A6FBF757BAD716 -:10A51000F29BFC2CB10F51D387EF8BD60CC4F20504 -:10A52000933B15EF3F6D56DC53508FFB7E678EF8E3 -:10A53000F72496E72B9AF037A07DE04792E1E725D4 -:10A54000C588FC1525C067996739E2C78AF13A3496 -:10A55000526D6E86EBDA64620D68E7998B39EC9D7B -:10A5600018172118E7875E9ED5F9302F25C8F78F79 -:10A57000C1BCD2F73EF068167E770B4BDC27B35890 -:10A58000F9BD83E87C4F5D7E21FF9E6D7C3FECB77B -:10A59000249BEFA306487F4F11FD1A6276A4933DDA -:10A5A0006D4FAFEAE25C364FBE8FA2E79706A16718 -:10A5B000DFC8744F89F41D8C3F0AFC6CFB6A9C8ACF -:10A5C000E31658E35CFCBB902E15EF81BDF1F5E876 -:10A5D000986911F86C7FEF697FCC0FE38382608DFF -:10A5E0002AFE4E8541CE6F190248EF0B3633C9F56E -:10A5F000605C70C2A5FD0D3923FB79839AE4F83FB6 -:10A60000B4BF5FA7E079B3367E428220FD8FF0EFC2 -:10A61000695C899FF4FBF6C7F3B5F3929E4FF01C7B -:10A62000B11A6FA3F3359B8E58D7A31FA9CFF71D7F -:10A63000FE80EB71FDFC1B3F98948AFED7E6A137A4 -:10A64000A7A21C6F41054FDFEF5938C925C1B07E65 -:10A650001BEA7B26BEB355CDEB476970CD243C3F4A -:10A66000B365186FFF49FE9127F17B605B6E13F5B0 -:10A67000BE4778BD06B3459386216C32103CA917BE -:10A68000B487FE7EEAE93A8EFC199DEF3A81E59F98 -:10A690005076A01CD1D3F519C2C791C760DD477BA6 -:10A6A000B84E86C3893D5CA7C2E1CD6DF6A5C5163F -:10A6B000BE7FACF1E1E1631384DDE1741FAFC5350A -:10A6C000C55797E7FF77C1A76F0B7D7548D88F37C0 -:10A6D00085FDD88FF683E2616E3F1AC5BEF16E61CB -:10A6E0003F768AB8371477B9857F3159C4C33C0E99 -:10A6F0002B185ACAE35EBB96E7CF30468A87C61549 -:10A70000C87EE2D87CD9AE8CEE9628F169795AAA37 -:10A710002E4ECED6C5C9B25D2931F6D7C5C98375CF -:10A7200071B21CF716378FD6C5C913A4F6C7F31D2F -:10A7300044D7A2E3B7EAE2E5E952BB101DE57D9BF1 -:10A7400010BD6644A4E396E2190FFEDFA263E4FDA8 -:10A750009AFFFFE8F80FCAA3CD20EDDFE8CB77849E -:10A76000FD7F4BD88D83C20F3820F21CFB843FB78E -:10A7700007E9D81DFD3AA7F0EBF8390E2D0FF28648 -:10A78000C8433588731C5BC4BEDB2691875A56FCD0 -:10A790003D3FC77191093ABE1B918E154ED9CF1B13 -:10A7A0009327D371942351E7F7C97EDE70BBECE7A2 -:10A7B000955A653A0E63FD757E9F4CC7A12D253ACB -:10A7C000BF6FB4CE4EC9E738C02F78B45721DE4BE7 -:10A7D00090CF731406E5F31C7AFBAEDD57D4FC86EC -:10A7E000363FC12BEF336F421B8AFB452966FEBD06 -:10A7F0000DA3A70BFA1D1ABEFCBDF839C42D9FDCB2 -:10A800004EF82C447B1EC17EFFA917B7FB7FEA657B -:10A810006FBB1F19DD0FD39B3EEEFFC48FB5F373E3 -:10A82000552C88DF9FBA8CDFF4275CAFE62F19ED3B -:10A83000350CFD08D562F0E1F777996AA573778743 -:10A84000DBF1A34EF5CAD4BEBFAA60BF9F887E9538 -:10A85000E237F9B9BC5EAECDBDF05E4FA9B305F3EA -:10A86000E29B3F323B6B919FA3F87750F4FED6E119 -:10A870005EB9D49F863F3CFFFF0BB48FF8A158FA16 -:10A88000DEDEE73AFB090B867E5E88E6F091974FA5 -:10A890004DF2A585ECF527BD2E903DCDB57599817E -:10A8A000F1B2B2D697C0F72B03245F7ABFAD5DFF3C -:10A8B00057E7A79DCC7305116FDFA35D2EA47355D9 -:10A8C0002E63BFF6DF7F21DA7D17FF1E8C4BC5712B -:10A8D000353C69F58704DD0F8BFEDAF0A2F1157EB9 -:10A8E0009F2621EC1EAC6EFE1ABE561ED91BC42339 -:10A8F0008CD7BA1E6D1D11F8C77D05BFFB7BA2AFBB -:10A900008E7FD858A7B8A71BD9EF33093F329CFEDA -:10A9100083695D7E6DFD6C783FBCFFA2DD5BE7FA6D -:10A9200050BB339360AFB367821CDD7E54A5730EBA -:10A930004CEC831BDBE859ACA09D318E505862581B -:10A94000DE55BF9FA8CF1FE8CF9515377791E0EB75 -:10A95000CFCBE7CA5C177B5ED6AE94D986E8EC52C3 -:10A96000A9CE6E8DD1D9B5893ABB27E7C58DCCA8C4 -:10A970007D6748ECD72B0EFCFE8E916328BC5E7C75 -:10A980000788E37B793BF2DB767EB69783F0DE26A1 -:10A990001FEB9883D3CF27DD33516D1EA2F3A303A2 -:10A9A000343BE6A4B8D71C1844DFF3343BE5BFCFF3 -:10A9B000E0F75A3F2ECBC17B368CCA67BCF68FCBF3 -:10A9C000E83E4E32954F791DF47CAD378FCA27BDD6 -:10A9D0004E7AFE84B788CAC7BC2E2AEBBCE5543E2B -:10A9E000E47553BBD5DEC904AFF27AA8CC02F706F2 -:10A9F000FFDE40968F3961C62C7B158C1786E74C9D -:10AA00001FCC230C8F5D17DB2538BD26596A9F5A52 -:10AA1000E590EA533C79527DE7C94E09EEE82E9263 -:10AA2000DA2796BB24B883AB5C6A1FEB744B704C7F -:10AA3000DE64A97D94C323D5EFB97E707CD365E431 -:10AA4000B9CEEB3A817858ED759FE0782A3FC1F195 -:10AA50003399CAB9BD3B107DEDC67A17DA6D7BBE5E -:10AA60009DE1F976B395DFFBEE60B42B1DC2FAEFE2 -:10AA7000E082FEA4F9427F523CE7E7E789F3DC2756 -:10AA8000E4794F96DE0319243BA9F931C3D5B458B4 -:10AA90008CC71E34D9FFBD3FCCE381E12AC37B2B99 -:10AAA00047CA26525E04AF6CB2087AF40BE19FC627 -:10AAB000F4B652BC38FE0985E23B584905E61167F9 -:10AAC0001DCD7686FF3D28AD3CFC1BFEBDA1983D0B -:10AAD000DB1C98171B5F3C2D312A2CFE1B1FF8B185 -:10AAE0002C85FAEB3B200AE6317EED34F38CFCD06A -:10AAF000FAB476B39E90FDD110FFFBADC21FA775CF -:10AB00006AFA69B57D3D3D5F9D77F97D9BB3625DD6 -:10AB10005F097FED0BE1AF9D127EF749E1777F2A58 -:10AB2000FCEEE3C2EFFE58F8DDC784DFFDA1F0D7ED -:10AB30008E0A7FED3DE177AF147EF7EABCF5F4773E -:10AB4000AD2E6C54987A99F3A57337C8EBAC5A279D -:10AB5000EF1BCE7A42F6BB673E24FB6BD397CB7ECE -:10AB6000F71D8B657FEDB61AD95F9B5225EBC75B4E -:10AB70003CA5127CF364392F77935BDE37D4E8343D -:10AB8000B15CD6939664D95F6B6FBD5B03A354FC35 -:10AB90003B2448CC5361F630EC7BF0D279C702BB42 -:10ABA000AB14F76B0A997B19EEE70C3504DFC7FD90 -:10ABB00026F6A14ADF816CC0370681BC5E1830766C -:10ABC000BC23CCEEF864BC4E3D2EE7476EBD47F685 -:10ABD000832BE7C9F18CB95CF6835D69F27EEC44A6 -:10ABE0009DDD61C21E9AF9EFACCC7D793B648899FA -:10ABF00047F795AED51E9999FEFC18B747346E9667 -:10AC0000544FF628AA0F3F273140DC53A88D1AF87D -:10AC10000EEEDFEDF988DF2F00B407BBC1FBD733A1 -:10AC20008E6FB375247D3F6EA789DF1BD89D62733D -:10AC30002E85AAEB2FF2FB01ACD548E7C73C786F15 -:10AC4000240BFB95CF8F15068DD2F932B3AE3E0D96 -:10AC50006DE265E7C3CFD1FDEFCD479CE3E8C3FAD2 -:10AC6000D0F988A6C8F70DDAFC381D9F6AFAA7202C -:10AC7000C0FDA38276FDA3A9F49D31E3878CEED9B4 -:10AC80005B0C2D679EC3FB515FF23CEC3026C76D19 -:10AC9000378E95E3B6E1F6CBC76DA31C32BF8EC9E4 -:10ACA00093F5408553D60397F8354DFC1C627B7EA7 -:10ACB000CD4D7DB2B47B3A849FA89C7D317C1F939F -:10ACC000F3CF10B1CE47CD6EBABFB23C9D119D8679 -:10ACD000D8F979C55ADCB7C1F37F1FF07B2F46E660 -:10ACE0004EEC83E5E911E2FCE25827F5D7CCE955B3 -:10ACF00004FF7ECEBAF47CA2256894BEBB61646179 -:10AD0000F485FA39C85F1D437CF47F675EE2FB0877 -:10AD10001A9FD912AEB07FE793FC40AD1C1674A900 -:10AD2000B88EFD76BE8FBA3F5813C4EF447E9FCCD9 -:10AD3000F314F7A74D30F2EFB6B86CC3812E23C4DD -:10AD4000FA8BC43ED9162F0BA23FB7C96BA552DBB5 -:10AD5000FF5C99BC2811EDE6960C4F2A9E0BDCD2C5 -:10AD6000B1C372067A7AB3A9435AA47B048DA68133 -:10AD70006467B734A618D10F1D66B41BE97B52690E -:10AD8000D355CCCF8EC4FB26490833DAA7DBE40DBC -:10AD900004CBE85CA887CE11C13A4AD18F2DB34FBE -:10ADA000A3BFF7D8F801C88503FDE30E53F1BD7DBD -:10ADB0001DF9F96B8B9D9F6F1D91349BE855E0E465 -:10ADC000DFEF2B48B339FDD85D32FF8E4F15FCE322 -:10ADD00074E17602E45EFABECF40160623BD74F03D -:10ADE000D37A3DA03B97B8F298383FD71479DFE685 -:10ADF00033E1576C117987E3C2AFF858F8154784EF -:10AE00005FB15297077A5FF815FB441EE880C8E7E8 -:10AE10001D14F9BCB7845FA19DBFD6F822791573C4 -:10AE200058E2197B771AC773CA2AC55F0EEB289DB3 -:10AE3000C9E1E4C57C7FB4ABA7CE5D5280F526E7BF -:10AE4000485847F2E4BAE1B88E94A92D744F69B21C -:10AE5000C7EC7029783FE929BA17A5DD0BBB93A38E -:10AE600086DD3E7304E9DF3B3DE2DCB1DA5C48FCA1 -:10AE7000F58489BE93A47D3F6EF24CF97B4AD3756D -:10AE8000F8BD5D079B15AE47DED1E4A23FEB1F8EF8 -:10AE9000F714D136EA4E719E172F5D459097B50293 -:10AEA000EF1A5E1AAF1F1DCBD7C1F7432DA29FA388 -:10AEB000C5B7C6623F1FA4F1FE260879D0F7B75A7E -:10AEC000EB4FDCA78916F47FB4E7E5CF9D1EF63281 -:10AED000E99CE961419FB67E4B1E34E1F7B4270738 -:10AEE0001E48477909DDAB71C5F2FB2B63FF3D13AB -:10AEF000E8B45ADC43D0F4EACD427EF5E37DE0BD10 -:10AF0000FCFD9D0F4AA698F07BE837057EC5FF1E25 -:10AF1000B0B12639FCBCEF07383FD095F7DF743766 -:10AF2000FD1DC96006E707CB8D16077E67B06B9ADB -:10AF30006B05E23139CD395CE447C99EFD3FEE81B6 -:10AF4000191B0080000000001F8B0800000000009B -:10AF5000000BED7D0B7854D5B9E8DAF34E32810958 -:10AF6000049C604227E161AC04262FF260083B108C -:10AF7000344524131221981026099068D11BAA3D4C -:10AF8000D27B68B321218418799C6B3D50090EF85F -:10AF900068CFB99E1AACD7D27EEA8D8AD6DEA312CC -:10AFA0007A430B6DC5F092F66B7B2F5ED49ED3A3D4 -:10AFB0001FF7FFFFB5D6CCDE3B93800AADF634F920 -:10AFC00074B3F65E7BAD7FFD8FF53FD78E93C18F57 -:10AFD0008F314BC25E65423263CE62858D87F6A6A5 -:10AFE0009245694333185B5EDDBC98CD64EC12FE7C -:10AFF000CC83E7CCA60D65E24BCC724981FF8799E3 -:10B00000CF361BEFE31DC37376291DFFDFCA82898C -:10B01000703F78CB6F719C6AD6EAEF87FBDD79EAE7 -:10B02000040F8CCFEAEC67875C8C65C2EFA58CE8D7 -:10B030003CF25ACD6CF45C8EB76431F497E3339AEA -:10B04000CFF07C6B17F339C742E323806E22BC2F0D -:10B050009E6DB5855D385F77F05E97EA662C23D5E7 -:10B06000D2E004782AD236AF64B06E56E9F44CC30D -:10B07000F7030BDFCECD836BE65A1F2E0FFB354354 -:10B08000BFE33776A6F96644E1DABA8D9584609E0F -:10B09000AD697FE75D9B88FD3E6C0B613F3BABE993 -:10B0A00083F1BBE7FF2E35DD1DED7F7056E94CFFC8 -:10B0B0000418B01CFE97C2D8744728C33F63F87ABF -:10B0C00019D3189B80F88F670CE038D3A0849D00BB -:10B0D000574D0FE06F0C3EBFD082F71B7A9CBE6EBF -:10B0E0000490A9EEDB609D6BF93259C3B48EFC7EEF -:10B0F000B8AEED01BA61FFDDF6D3882F17FC227ED2 -:10B10000D35A6DA723F8C2FE4CD7C6794C6D07CE33 -:10B1100001F0DEE24F4C7EF726F8772ECBBD64E5DA -:10B12000F447FCD688BE710D556319D2D30BC82CD9 -:10B130001ABEAE15FF6665FDE319310CCB8FDE3FFD -:10B14000B17A4A7C08DF43BE7109BE9A453CE97377 -:10B15000CC46FA73BEAA167C05ACF912F19566D7F7 -:10B160002270C2BAD87DF628DF6518C66308EF32B0 -:10B170007D9BDE578F4D05F8570AFE5F1968E1F891 -:10B18000BA8FF3A30B6E8A71A2FC06E3044DFC4751 -:10B19000F49A28E084716E2F2BFB1F3F059C3DBE67 -:10B1A00033E336A4D3EDDFB4322BCC5705DDB05DED -:10B1B00055A384C3D05E16B899E461997E7CB85FCC -:10B1C0005D6D3FABA7CF3B1BA7D038ABCAF9386C3E -:10B1D000A36E7E826F27E133C8D8168F8EDFDE4DD7 -:10B1E000675319E0F1A53DCDFBF0FD73BB9C0CF955 -:10B1F00088E1BBB391EE1CAFC7807791FFCF6F534F -:10B20000C20700EEB37B9C04E7BB6B943043FA3378 -:10B21000CF93FD70FF017F12CD732E2EB4EF1BF084 -:10B22000BC716B825F83F5768D6BBD2708F39E4BF7 -:10B230000AD5E3388D5B6FB268D0BF2B5E7365E0D3 -:10B24000B88D56FF019862850D703A0EAEF0EFEBA7 -:10B25000E1DAD0A5A31FFC37E85788EF975858A824 -:10B26000CF3D9C7FDCD90ACD8F0877EAE05F926101 -:10B2700021788F3FE42478C764FB689C86C2383508 -:10B280006E0CD291A9B61C8027559D8C709E55409E -:10B290003E81DFCEDCAE68881F66E374715C3F6977 -:10B2A0003FCAD33F89759E7DB06032F2F39924FE88 -:10B2B000FCB4373E8CEB3AEDE36DCDEB0E3F81B243 -:10B2C000610B652E4BE4EB50800F1A055C8D3E8BB5 -:10B2D0001A07F46D7C68F95791CE8DDE9EF5783DA6 -:10B2E00096A8252AF0FEF93D5686F8467CB872F0FD -:10B2F0007971333E37E3E5037F06C183F81B0F788E -:10B300007B77777B6208D6C13C2CE49818C543C391 -:10B31000CE1FDEAFCC2479D6B8BC733951986E3FBE -:10B3200006FE5DE17368E5300E3B3C95F876858757 -:10B33000F3ADA368CB840CDECD1DE10F1FB57B7090 -:10B340007F6F14ED06E45BC0EB0A949799888F71C8 -:10B35000B3FBE17ECD6A23DF6E49DEFC6015AC7382 -:10B360004DA19D59E1F91AAFCD2037951B8C720480 -:10B37000EB36B4C767335A77D738C19F9D9C3F815E -:10B38000D32707B3A27CD1EBB748BEF0D947C1BFE2 -:10B3900019AF5F343C9C467E057D7326CDB7AF88E0 -:10B3A000F402F00F878B5975F2D0D0E524BE67C048 -:10B3B0001E8827E04F476556945F247E1A766F22D9 -:10B3C0007E6C107CD7D803FC3346C747267CE19AB5 -:10B3D0006D729E29513EA3E731F8EC453F875BCA69 -:10B3E0005F030BD633EB70B99657A27331D0B36FAE -:10B3F0005D8D16C0513492E31D25C56389DF053D7F -:10B40000B8EAA11F17D22D51D2476383B89FBBC59D -:10B4100043CF06E54419E81BABD8671DEA40B81FC7 -:10B42000EE276DB0D27DD42F36E88FD33224F8F3D7 -:10B43000054F4F87769C68BB055DAD56770AE22BBA -:10B440009119ED9E71CCA44FFC9CAE52CFEEB4B3DB -:10B4500014DC8FE3C4FEDEBC708A82FD762A0AD932 -:10B46000078E32231F584D7A605AB685D62FF1C009 -:10B4700084BE75B8F87AE3522C24171FA482425573 -:10B48000A2F87088F58FEBF7F5F5C3F37AAFCB1F11 -:10B49000463E621ED20FA53053BF6EDEEAC509AC30 -:10B4A0005F47E7859EF186F62DDEEB0DFDBFE29B43 -:10B4B00062787E6BE64D86E7B7F9730D6D07D3E9C9 -:10B4C00075847388E3DD21F0AC7B2EF5F200D2B1F8 -:10B4D0004AAC638723E40DC23E5CE55D4BFA7953C9 -:10B4E000C95DDE215887D3CBE5CF81F6248C1B378D -:10B4F0006DB587EC08A19F0BE117E9D08E83A444BA -:10B50000F9CC61C2B359FECCF6E4DA6CB07B12A080 -:10B51000F165F665B27BDCE362DA3766FB0D7484B5 -:10B5200005F9355ED06BA1D54D7A636B35D8730ABA -:10B53000DA974BB9BD94F95F88AE41D18F6916B2E5 -:10B540005B9789F54BFBEBAD36C6FA6F007CCCE719 -:10B5500076D6B2C20BD57ABB5C5EBB453FD98E2F87 -:10B56000DCAFAA31F4694736DF371302FCF9321732 -:10B57000B3A11E92CFB764737DBC4CE8ED2520C704 -:10B58000C8B71578D5D9ADBB049FEE8AF02B1BC880 -:10B59000D1CBE9538A0DF110279AFB596857F6046D -:10B5A000C4B3469DACEE2023F9FE08B03B9BEC18DB -:10B5B000FA29CD5EDDFB75F447AA13FDE85B38D5AB -:10B5C0008627BE0DF88BAF4EF05B7C517E27BF0304 -:10B5D000DAC9999CDF6B525D7E7AACA983536747C9 -:10B5E000EDB26A61DF4D60AD2407C3FC1817E7CBED -:10B5F00091FD18BEFFC8F99C62FF67D68D7EE2BB45 -:10B6000020DFF72DF08B7C777B8D91AF968746E717 -:10B61000B31F640BFBBA8015109F85D6115F3845A8 -:10B620009F1D93815F389E883FE2257E85BD6DB763 -:10B63000B17E1BD0E908D21F8074DB5922AE734063 -:10B640007D85E4622093D9F57C100C58D5B08E8EA0 -:10B6500003452CDE03FA65C0CED27641BF31EAF253 -:10B66000451E58DF40A933B18136D5B0C16E3F02C7 -:10B67000E39E72B311ED7DB33C4C877FA01ED89A38 -:10B68000F6AE17E1D96A67B4DF3376B106E1DA2E98 -:10B69000DBDAEF6A4AB11D27DB1FEE56A1FF93F1FB -:10B6A000BCFD61F6A5DD5A2AD18BF82A41D0234191 -:10B6B000DAEF337478053AB89273689F7199F06D38 -:10B6C000B6EBA59E30EFC3E6797F27F70341A7913C -:10B6D000D63D0C5E60CD2F8F2E17EFA35CB8C05FF8 -:10B6E000D6CBC5F071FAC97EAF15EBB6243C9F16D8 -:10B6F0008AE14746F0BFCEFE7BBDBF00783EA4A0E6 -:10B70000DDABC2DBB319571D308E52F8DABFA3FE92 -:10B7100057766BE3108F56E8807ADECE42048F9422 -:10B72000D738E4032BE2BD9F9E83FE1D52A6E02086 -:10B73000751EE45F05FA5F42FC5CE93E59CEF5DA1E -:10B740000AB1FF55E094305E45172B45FF3C6E4D26 -:10B75000D3816DA8E754275A1470FF4229C207CF3E -:10B7600055275D2FA84837E06783DE79A9E44FBFEE -:10B77000790CDEEB1CB0FA9D306E67E0C70CEDEE85 -:10B780008B33981F17DD811D01BEFA9067A1C38717 -:10B7900072D37FBC631A63A7DAD840997D38BC03A3 -:10B7A0002FC7397CB0D8909634F35918A7ABD0E99D -:10B7B000417BEE9D8D5607D26960738386C83891B0 -:10B7C000A2F52970BFCB1662E8DF3B36B62F44FEE8 -:10B7D0003E61D7FCE3E0DAB559BB1BFD10D5B7B825 -:10B7E0003C1DE03FD0652B0FC7D89FD7E7707FE7A0 -:10B7F000AD97EEA4F51F4971F8E360DC218C6F0072 -:10B80000FD8ED877A6F971DC4DFF2D0DC73FB266CE -:10B81000ABFF6580EBC826277A52ECC81E570D8E09 -:10B820007B646EB377AD6E7CD7F58E56BC3F30C966 -:10B83000E19842EB792FD18BEBD9983B1E79B3334A -:10B84000C531B9099FAF6D66B85E8777A71DD7E789 -:10B85000B2B1DDB8BF7CC97BE1CD02F4977C96D94B -:10B86000B740FFFFEA0FDD9A83FEC986530B512FC5 -:10B8700039CA92B6E0B553C029F72B49DFA19446E7 -:10B8800017EE639DAB9B781CC66B69203AA6588265 -:10B89000B81F7506D6B8A6CFE0F79BC70CC74B27D5 -:10B8A000C65D66219C6BBD6BB3B0DF876D21E83749 -:10B8B00034D759130B8FCD395C8FB9DA9B333600EF -:10B8C000DC9D7B5C1EC44FA712DADD0078D5D2DD8B -:10B8D000FE277CC3DFFB81784FF207D089E4707DBF -:10B8E000CEA43D9A0DED554E47C08BCBAED39B07F2 -:10B8F0006795AECBD1ED93C3E64DE9247DD1A97018 -:10B90000B9FE414ECE1E0DC6C9F587EECB81F98E2C -:10B910007481ACCDA2754E467B7F24F91912CF3BC2 -:10B9200037C1BA63C8FFD06A2BBB612CBF5E07D793 -:10B93000E99BAD939518F8199ADB948171AA23F0CD -:10B94000DC02E30CED71F12BDCCF40FE1A813FF3FA -:10B9500072B8BECF9A19ECC6F5B2197E8AF3BD99BA -:10B960001DECA1366BF562FB0BC0BF8F7D4EF897C7 -:10B97000B149C0AFCFCCDCA3814BCA3CE30C76EB22 -:10B9800048FB67900DD9703FDE54F2A716F407BA52 -:10B99000B31C3EA72E2E28EDE825995CBF05A79D78 -:10B9A000CD839D9B55CD584BFE0DD8CB141FF4C0B5 -:10B9B0006FACF86010E3813A7DB8C4D496F6E9BF65 -:10B9C000E608FB45D8C9A9BE9DC1F9E87FBC61F571 -:10B9D00087016F69F802B42B172B61B4D73795FC38 -:10B9E00033D9F14CD8714B049CBF6C73B1B2692C44 -:10B9F000E2CFAD10F7135A4E3D8EFE7502C63F31B1 -:10BA00005EDBE2F451FC05890FF35789F549BF8EDF -:10BA1000EC4858CF8A16110765BBB8BEB106F29143 -:10BA20001F601D06BF24C84C7EC86ABBC19FAB35D2 -:10BA3000D90F66BFA1CA6437EC40DB09ED425B9FBA -:10BA40000BF9E9FD193947327CF458EB97F63DF4D0 -:10BA50000B150E6E19D2ED3F8342FFFCAC4D3D81BC -:10BA6000FA684BF03117C6E1BB6D6117EA93EEF24D -:10BA70007B1391EFBAEBACE5C86F036DE5D4EFAD86 -:10BA8000B6205D6DB95C6F54FAD58F703F91F65951 -:10BA90005579E9890E1D5D2BD5AF9CE8D0C15F516A -:10BAA0005869684BFEAAB0B2D6BE18FB4B5EAE8C8E -:10BAB000BBA8CC608F5A9FF28762EC17F21ACF6C4A -:10BAC000EFEBF1382ED768F73E3063FED8D1EC1992 -:10BAD000B94E891FB97EF97C2478FF2347FA279F46 -:10BAE0000DDECC4F08AF194E09FF48FD2B70139B9C -:10BAF00084F076ACD066201D4385B980E7AA326514 -:10BB00000BE6657E26E2953F0B24863580E7D54C13 -:10BB10001EFF8C6FE17E657C59E542DC9F3E29BDAE -:10BB2000EF2854483EAB034A58857FDE2CFCD55F96 -:10BB30006632CA3F80BCBE9908ED5FCCB5F338329F -:10BB40005317DF363BEAA7C6D7F1FCC40E07F3F75D -:10BB5000E37B37BAFD9BE1FE32297F35C63C447555 -:10BB6000B5DDB0CF5498F20EF1A67D6679AEB0BBCC -:10BB70006703DEA744F13E92FF31129F30DB853C24 -:10BB80008C8B99F1738F093F667FA7E279937C5C78 -:10BB9000A1DF73A02BEFD564B433CA14FF34A41F04 -:10BBA0003E82F7E2D583940ED921E548F87B325FD7 -:10BBB000B5636915F97B6FA13D3096F24D93315E07 -:10BBC0002DC7977E5EAE5FFD466EFEC8700C8AF78D -:10BBD000B656C6B61306D14E98C5AFD7C175FAD2C0 -:10BBE0000569B1EC84C1226127C073B40F06F794D4 -:10BBF000F36B91D14E60E5B997C1CB265A6FDCB497 -:10BC0000BCB1B1E46E7056E8E1DC09D17642662B36 -:10BC10002BD3E1FDABD9EA3FE27A2B451C42CE079C -:10BC2000FAFDB0DE0E33CF7728C7C3F15C3E9EF439 -:10BC300085BC5E8E7E364F2B433E7BC0AED6A0BD0C -:10BC4000678E27FD3097DB895D196A0B3E67EE9C96 -:10BC5000CB8CBB49C6AB33B327F2F403C57D4CFE96 -:10BC6000A0F49FF6E3C3FCA85F68F370BF303EF515 -:10BC7000C2610F3C5A971B7A1EF135F74258B380C8 -:10BC8000DC39172B643F395319D93D57EC875D6177 -:10BC9000BF2E146AE0E7AD8D3C1E5F9A6DA3767CE3 -:10BCA000C87A80F605531C275E7D8FFCB02560079F -:10BCB00088B80DD953C7853D1564ADE4EFB9ED6182 -:10BCC00017C62BCC719B9A544BFF74D0EB3585175C -:10BCD000AA7D33E97D43DCA7C69771788278EE812F -:10BCE000EB92208F032DC338108E5F1DEECAC03C2F -:10BCF0009CDFE65719F7F3D0BE58DE747FD6C3BE7B -:10BD0000AB170792F125692F4A7B06F44BD778A42D -:10BD1000CB02C547BEBF294E648E0BC9B88C397E95 -:10BD2000648E177D9C9B4EF490F6978CFF7C946BF1 -:10BD3000B4C3AC3037F6EB2E822D15E4BBDBCED28C -:10BD400076CEE0F11DB4978E94FEC483F68535CF90 -:10BD500014E7BCC2FDAD13F6A133B8AFBE126747FE -:10BD60007B3BE80D513C7189629493C9797C9FF3C8 -:10BD7000E4B9F93C228FDCD9B641BEAFA1BE09A619 -:10BD80003AC2714A741C56987F45F2949CAD4ECAD3 -:10BD9000CB277F2415AFCC0FFE4816FA231ECEDF2B -:10BDA0008513683D4C9DC0CEE8F3C602EE081C2EFC -:10BDB000F05BB23EF9FC2988E7FCE83C97C3DB8ED8 -:10BDC00092629703E31140632BE72B4F247E9F8100 -:10BDD000719D753EBD5D518F798B5CB43B795E433F -:10BDE000DED7C5CF6DC8BFF1A9213518635F5D955A -:10BDF0006731E44F23F1F74C46F922398E8D7937BC -:10BE0000911CA0AC4A78AC31E2F402DED5420E00BF -:10BE1000E12E27B04CD34E2BE375095C4E643EC235 -:10BE200056142C4F87F5366D53286FCCB49AC368DF -:10BE3000DFAF11CF1D22FE66CE23AD117918665DEE -:10BE40004776DAEA878CF9B5C61E63DB6C97CB7848 -:10BE5000BF0D8044B8DB249D40C15B47C7C37E5AF9 -:10BE6000E75F291E241F2ECEFDAA17EB5A3AE342A4 -:10BE7000BB1B30AFDDEBA27808F990282FFDF00B4B -:10BE8000EBD9B6B7F0315CCFF63C2B977B85D7B9B1 -:10BE90001C4E79D835A4E3B7ED82CF66E5F978DC9E -:10BEA00005F72550892C3599E448D6B51C49E1762B -:10BEB000A523C0EDC6A7A6BEBC94E75D797D4B6601 -:10BEC000205ADF520AF8C912F8C99CB6DADF0FD738 -:10BED000AC00AF4B9AF1ACD15FBD35D36857669AD1 -:10BEE000FD5553FB405EECBA96689E4DC4DD05FCE3 -:10BEF00066B9FA5E1BCFB7FC33F8AD787DAACD43A7 -:10BF0000D7EFB779E9DAD7E6233BED99B64CBA4AD1 -:10BF1000BC3F600FD6635E4BC621657CBC3F8FFB88 -:10BF20006F2CC0E1A8106B59684D4D443C1F0D703B -:10BF3000BB70A4FDA5AADC1807BD3D68CCEF2DAFF2 -:10BF400031E6F7EE9BA9BE9407F024CCF4DA43BAAD -:10BF50007CD41AB1FE1D0FF37C931CFFE83739DD4A -:10BF600065FB9C58FFCF045F24BC9C62F701B12A9B -:10BF70001FAABC19E3F6CC937345F6E02F855C2627 -:10BF80006CF6D8312E54D9BFC281E3ACD90DE3B8D9 -:10BF9000AF7C9CAD6913D38CF985AFDD81701C8DAE -:10BFA000E4175AEFC0FCC251915FF843DEBDDF4198 -:10BFB0003F6B569E7A1AF5862B4F3D83F8F883D057 -:10BFC0009BD03EA76FC3CFEB4913478DE3FF212FD3 -:10BFD0007F781CDFBA40698D55D7F2A19017D05BEE -:10BFE00017711EE68AC4D13EE06DAE8FE2F2397E53 -:10BFF000DA7FC95A709CF61FB3966762D8F32C5F3C -:10C000009171B98F490F7AA51E0C5E8A359ED5595C -:10C010003919F17DCECEEB62CCE3C5E53B247CCE75 -:10C020007C7C3F35025F5C7E7E74BC1D808301A4F6 -:10C0300093CD9348794D7637E53F251F25D47B6E08 -:10C04000C3BA05702C19EE2F09CF796ECBC338CE49 -:10C05000CFA7F89F6023D3F5B782BFCE0BF93A87FD -:10C06000F205727446C8D729942FB89E14F2F5EBE6 -:10C07000363FB57FD95648EDE36D2AB57FDE564E83 -:10C08000D7C1B620DDFF595B0DB53BDB42743D5A8D -:10C09000F6D8CDB8EF7CF03D85F4F148F0DCF5B88A -:10C0A000D5203F2D7B130CF2B6F6A1F186F6EA1EE1 -:10C0B00063FEBCB1638AA1BD6A83317FBEB2D598ED -:10C0C0003FAF6D9963986F456881499E6F35C97B15 -:10C0D00095A1BD309FDB8955E5B586F79CDE4643CB -:10C0E000BF84A52C148BFEB7E5F3B8C9CB25C56377 -:10C0F000874689733836DCFA36DA2791B62DC4D0F4 -:10C100009E776C5842F71F88E3FB9DF9BD26C1AFAF -:10C110009D65AB83F319DA458BAC7ABBE79E59A1D9 -:10C12000E5F93A7FD0E1E5FED8C5A9D5562FF0D183 -:10C13000D2B2F75EBD0EF82834C0C8EF51C1DCF3AF -:10C14000821D5CD8BA6BC175D0AED6D61BFCC7E2D7 -:10C150009683AF80F8B240D9D1F664783F3F3BD4A4 -:10C1600084E397782FBC82EFCF5F9C6D43367F20AE -:10C1700089913D7A2ECD113E10831FEE1770CBFCB6 -:10C18000D527DDA7CD79FA8C4C568A71E48CCC0B7F -:10C19000A5A8D7A0AD62FEEBE0ACD0FD081FDC5730 -:10C1A000514F3E90B53603F79391F2468FE41BE36F -:10C1B0000912AE1D251C9EA322BF3064CA2FE8E2DF -:10C1C00009EDF9A3C413CE89F786BE1D3B9E704EC0 -:10C1D000E41DCEC9BCC3C35531F30EE7168A7802FD -:10C1E0003CC738C2B93D35FCBA70F4BC835C1FEC67 -:10C1F000477BF20D790761E78BB8F9E02C752F3E8C -:10C20000FF6AB6DA8BD73F66A9FB108F4775F94FE7 -:10C21000CF445DFEB3EC2786FCE7A19CD093F93CAC -:10C220006FCDD0AF6AD7D850DC14CCC706EF89C524 -:10C23000C7CFE4CBF862FF67CACFEAF2A8964B37C4 -:10C24000B12BCE035C71BF425E9762B66F121023B2 -:10C25000E3A276DFD379A19F20DE3A929EF3F1FA32 -:10C260002B4B74FF40E537823D649E4F8E87FA0A60 -:10C27000F5D620480CEE33DB932ED4A19F724CD020 -:10C28000D37C3D9E2FE8C93CC948DFA7F382BF207D -:10C29000FDF36C9F8FEADAC4FD2B85E34947F06D0F -:10C2A000B4633B1BADBE03DC6EA7B8C50D81A470A3 -:10C2B000B72E1F7C11F7CB7C8C3F0E4D7500BDDB7C -:10C2C00043AFB8B11EFC9DBD36AC8861DF4DD4ECE8 -:10C2D00048FF9A4CBEBFCDF786BE34348A9C033FDC -:10C2E0008CB778090E8BA590CFCAAF9A825773FF8F -:10C2F00081BDEF4FF0C178DFEDE5F9AF1B7A57BB99 -:10C300001A75E3DF305BEC97C83379989F54C258B5 -:10C31000A85E1378EFCD02CCAFF82C14E77867E372 -:10C3200007C79663DC51B552DCF19D8D17A97DDC02 -:10C3300067C945F2BDE3FD7FC7B0FF0DDF5C3391F8 -:10C34000FB2D1C1FAB36E63ED99D4E7931C76C984C -:10C35000E7B87A3171CA8C68FE6C95C282B1EC98EC -:10C36000C9B339FF2F525BEF40B816859C0CEB9C8C -:10C370008F376C7D1BDBDF2D557C56F4EB33F93C9E -:10C38000357B6D544F0BF85987ED37FC090CE79D51 -:10C390001F3A68C3FE1F6629EC3AE52AE255BD380C -:10C3A00001E5F01DE4BF18F05F94F22BE468BA0DCC -:10C3B000E43E07F17FD8AD8F534A7ED2F2D4CCD978 -:10C3C00014F70BB504C9CE5D7A19FB7433AFD3FEF5 -:10C3D000DE051BE61EE21F6F9D84F1A561708E00D5 -:10C3E0005F91A0FB1FF3791CF3865EDB9B5F417EB0 -:10C3F000DE68A73A845979C139B3F5FED655DE37E0 -:10C4000064FDDA40213F8F00E634CD03F066DA00A8 -:10C410008E3825DEAF71B9A2F89C4BEC7FD04F1D52 -:10C420000BFD56B1BE7E8CF3319BBAD38AF1C32289 -:10C430003BF9C7CB57DA13912ED17C99DFE06F9887 -:10C44000AF67303F46751A2EBA0E809F8DF912FCE9 -:10C45000014B1C1EDA84DDEF7F449D0A722FEA4AED -:10C46000EF3F74EB2358577ACCC2DB771DBAF5FA4D -:10C47000CDB0A433935B8FDD0EEBEADEA5F837F980 -:10C48000F0BA7F77239EAFD8A0F8CBA16B7DFF8D4C -:10C49000F598626CEE72928D7F7ADBFD3723BF5E7A -:10C4A000F4320FF2F3F214CECF4D832C6C81F62DC3 -:10C4B0003DBB28EF191CB451DD9ACCCB9E4CE179E1 -:10C4C000D97F68EB27B8D1AF5D389BBBD8F833CEA6 -:10C4D0000F70601CB5CC46F9D2F1CCD389FB4BBCB4 -:10C4E0009A5ECAED698F83F23C8B19FB0EC67936D2 -:10C4F00070BFB948D445CA3C163BCBFDDB16F845A6 -:10C500007D32BEDCE81FE79BFC5FA9DFCCF916E0BB -:10C510007F0DEF77CE4E34C4EB468ADBCBEBB360B6 -:10C5200047E0FA9E1379DC4360AF633EF3C760AF28 -:10C53000E3F579B0D7F1FE8B60AFE3B51FEC75BCC6 -:10C54000BE0CF63A5E0F83BD8ED7D7C05EC7EBEB4D -:10C5500060AFE37BFF0BEC75BCBE01F63ADE7F7685 -:10C560002EDFFF3AA739C29B01DE4E3BFB35F29529 -:10C57000562AF2C2224FB62D693AEDEFAE8F80CB2C -:10C58000C19E1A504277213DB43417F51B48BCF0C8 -:10C590001FFF17DBDBD2C90F6136DFA12178AFE3C4 -:10C5A0001BE9FE6E68763918E9FB53479947017B12 -:10C5B000E6FCEDCA4C8CA39EB94DE9C3F6C06D0AEA -:10C5C000D913D351F472A2FB68F1FBBE03B89FB537 -:10C5D0002732C18F4FF6AAC07FE71136E4572DA945 -:10C5E0001EFDD2794ED91E538FCF1B3728C24F1D47 -:10C5F000B74F85356C53E4FBA9BDD8BF43BE2FDAD6 -:10C600008316F9FEBABDE8271F8BCCB7BA564D8505 -:10C6100076867CBEB60EC73F15A9AB9BB712DF1F4F -:10C62000888C3FBB17DF3F9326C7BFB396DA76D916 -:10C63000FEA795D49EC0FBCF7AE1BA47B16EE56AFA -:10C640008FD71EE2FB1FEC63AA3E9FB3A9D84AFB1B -:10C650009EAE1E9CE26E32CF6F49704FBB9278A99E -:10C660002ECF4FF15298CF8E72F6F5D2A4C9A8778B -:10C670004FA5F963FA29E5C591FA5663FC5455783C -:10C68000BDBD8785B03E3E5EDC8FEFE175F48E4C1C -:10C69000DBB03AFA2B8927CABA07194FAC593D7A51 -:10C6A0003CB1A6D4184F5C259E8F144F5C658A2739 -:10C6B000AED868CA43843E593CB18EF5DBD10F63D6 -:10C6C000AA427254E7E97B7522FAFB677D144F6436 -:10C6D000BED729DE2ACF4FE0FF2DB3F1BC196F9FE3 -:10C6E000BF5BF1A25FD17DB73211AF27EF5626A114 -:10C6F0007C9DBD5BF1A0BC7D589041F8CFFF8DFFC4 -:10C70000751FEEB75E8B9FA323F802A62A82AB9318 -:10C710007CDD30CEA9BB9571F8FECAFBD21DC80FD7 -:10C7200060770A7EB4EE45FEB426288676DE64C9BC -:10C730008FE147503EE68D176D6DF95E949F5287ED -:10C740007C7F33B5578414D1FFEB7B51BF1C9B2FEB -:10C75000FB4FACC3E7B74F91E31D20799C9720DBDB -:10C76000BB49FEBA22E37DFF11ECFF0BD490D4DE6F -:10C77000B917E5BDB452E8336D268DDF5927C7FFE1 -:10C780005A2FC6AD6A2DF2FDC524FF4D4CB6C17EB1 -:10C7900087F6AFC4FE70D70F3FAEC5B8D61DF2B94D -:10C7A000F6F123084F9D68AF2BF897BDF8FCAF7EDC -:10C7B0007D7FE6F9CCED956C60E1757951B930EF8C -:10C7C0002B0D45DCDF296C3988EA8BD5B5EEB7A295 -:10C7D0003C46F36A29D541E46F9795EAE7825E7695 -:10C7E00073AC7AFE4B057C9C8D05579A5F8B3DCED2 -:10C7F000DA22BECF75CD6731FDDC83B3E66F2DC87D -:10C800008FDA0D68223AE05A02570B5C3FCE0A3DA0 -:10C8100088CF91D618879171ED25A29E7853C9775C -:10C8200082F3F1FC5291DD2FC2E103FA7CAF4D9C03 -:10C8300073AD9DCFEBBC42DD4EF2D7AABB441D8940 -:10C84000D54DF908DBF58EFD943713F9D410D61DBC -:10C8500067505DD7A8E73B6CA63C6A97586F69F6AE -:10C86000FB94A76E7A83D70BCB3C76BD80AB09F5E2 -:10C8700032C0DDB85A095BE0BD46543C98D7CD6460 -:10C88000615F7A34AFBCA2CCD6EFC07361E27C06A4 -:10C8900013F670241F5EEDEBC3FA189B1AE757716D -:10C8A0001ED61FA4BA38CC17A5B348FE59EA91CAC0 -:10C8B000E6EBEEC63CB54E6F519E3A9E0DD31BA4DF -:10C8C0001722754D228F1EA9CF117A40E6A71BC4EF -:10C8D000BA9645F4C0E22568E7C63F20F2D422FFAD -:10C8E0002CF3D495A6736D8D810563289EEBB7F963 -:10C8F000A9AC26D5789E29DE44879B8AF9B94A9946 -:10C90000A73E5A60CC373F6067A477BB328C7CB7B8 -:10C91000A098E743FCC5320E19DF1F87F6377391E5 -:10C920001FD28DF19CB1DC1FA1C35CA6B88E6D43F4 -:10C930002DC51FF1B9027CA864BEF6EFA897B15DC2 -:10C940000CFD6D78BE05E9E1B6903F2AE33F68A68D -:10C950002CCCA138D079E467DB867A1A479E677FB2 -:10C96000323EB67C5C2C9079D63E3BF6ABF5BE767B -:10C970001CE7FBCC7120E18745EC181FAF7F995471 -:10C98000E09376899D9FF763F6A559142FF9B800B7 -:10C99000EFCFE8F3211C725FBAA3E839DAC7AE3CE7 -:10C9A0000FCEDF5BFBA3976AB5E491F3183705223E -:10C9B000790737A6C059B2CC3BA889D88EEA595816 -:10C9C00048A141CFD6B5FC27D0B351BB3FA30E9FA2 -:10C9D0007FD1E0077EBAA590EAA778FCED8B06FF31 -:10C9E0001BF96A3DF2E1B59EE7C5FCE03A9C67ABF6 -:10C9F000A2D6B8E95C0CF32BA3E70BEFC5FEE67CEF -:10CA0000E1E5E2187F8B5B8C1EB7E82D34E6F53F3D -:10CA10002F718B7F04DCE13E09F27490E429C0E5BC -:10CA2000E9AF7DFF83F51EC1F56E55FAC2F1D6ABB5 -:10CA30001F37783A2FF46B94A3E9A9AE06B4676068 -:10CA40001E1FCA5F341E0270171AE2217B5BAE41C3 -:10CA50003C04D6F97BD27F659CAE7F05747314E1EC -:10CA60007A546E47FC15F26506ADAF8FAFEF2F30ED -:10CA70007F4E11EE034F717E89E287DB493AFCD489 -:10CA8000B5FC65F07333C17788C3F705A0671DD186 -:10CA9000D3CFE1BD9CFFBDBE80FB17F05E13BD97F9 -:10CAA000C7F9E05E6157835FBEE03A5FD42F4FCE97 -:10CAB000569B8BB89D7B6791A1CE54BDAB6874BF6C -:10CAC000F99EA2D1FDE6FBF0FD2F8ADFBCBF80DB23 -:10CAD000FBD1BC4DD8C53FBED142F9E57AD1B77B79 -:10CAE00043D5A21BB1AE06F08F6D27AEC7AA5B4F30 -:10CAF0009A8DFBDBA6F36AF27B07725D366BDDD89D -:10CB00007E5F149F6F8D6975E079A86635A913CF94 -:10CB1000DD2EE8788FEA061DAAD3877EE197BCBE9A -:10CB20004ECCCB56A97CFD8E160F9DEF93E7DDE42E -:10CB30003994E6FE1B5F73E0B939F05F5260FC8AFE -:10CB400032FB69FDBA9DA6732936537BC3AFD3B7B9 -:10CB50001FD6F57FAAC8544F687DAA9CBED3D1A129 -:10CB600078449D2FD565348B313695DCB108E39739 -:10CB700060C7F9100F0B76EE1AC07C9AA3C34AB9AE -:10CB8000F33FB6F9B61F06918AEBB552BCE1830DAF -:10CB90000AFFDEC7629EC76F12797C668A33C87847 -:10CBA000B8C463DC83BCFEC35178AA8CCE37D6AD43 -:10CBB00019C8E7BC43F1061B878CC9EF6F540ABE46 -:10CBC000AA0FBCD781EF2DF35A0CF543E678848D7C -:10CBD00099EBE4791DA74DE5759CB64C5E271FCFF8 -:10CBE00054FA5E47FC962AA267A5CAEB38C14812E0 -:10CBF000DFDDE274A908ACA73A1F731CC159688C29 -:10CC00004398F9D24C8F93267A3C61E3E7933A0735 -:10CC1000AD7E0D6E773EB4BA0BE3E7DA43168A6356 -:10CC20009C95F5210024C6F397B3087EC95EEE6C8F -:10CC3000E5F502922ECB77F2BA11EA6588DBA732CE -:10CC4000FD773C968BB8C21DAC8FCE3BAC6443766F -:10CC5000948355184AB7623CC647D726A66D6184AF -:10CC6000BF50573ACCF744EB783FC6B5FB27D99372 -:10CC7000DECDE47E442CFB359AAFB5B1777571FEFD -:10CC8000BFC5B53E695CCBAAD1F952AF233C4DB9C3 -:10CC90007C5CEB88C84BC8B8D6D99DE27B1BE2BC54 -:10CCA000C580BD75F24E37F6F3919E19B377F92220 -:10CCB000E48323BD3FF188F3AF1B278EFE5D88829E -:10CCC000E218F5A43F2F60345E67FA109DA33E6919 -:10CCD00037D6E5CAEBED0159BF19528B75F631F322 -:10CCE00044EA38E717D346C0CF6BCB38D3BADCD091 -:10CCF0002D787FEE05C10F8B95B002EBAD702BAF99 -:10CD00002ABEE8FCCC5C47FFB77C18C11D87F80140 -:10CD10003C0EC4F1BADA817456F34C0CFADC389745 -:10CD2000EBD181ECD8F493CFC13EB9BF7802F79F25 -:10CD3000C6F0B8C2EF1DA3C715BE551C23AE20E92F -:10CD40007B709EAA71BAF3B62727D489FDDB4341D5 -:10CD5000AAD739DF63F56D42FCF7B7BE5508ED255C -:10CD6000DFB27A301F7EADF37C930AD289AF2E9763 -:10CD7000E7FB50E0F764A4AEFB5B944FEF8EF867DF -:10CD8000DC7EAC1DA76BC3965C3CC8FBBF585CBC8B -:10CD90000FCFD98F646FDE1758D58BFE9CB437A1A7 -:10CDA000BD12DBF27D9084C9A5A0349B5A643EB1CC -:10CDB00082F2F5D1F956EC43FBF8ACDD38BEB4573E -:10CDC000078ACBF7A1BD1A8CCC5FBE0FEDD953A655 -:10CDD000FEF47D4A18EFD7C565D4BF91C9F1CBEAFF -:10CDE000B17F24AEC8D6933F7ACC21DBF7D4A33DE4 -:10CDF000BE3D9D8F371858DFAB7D0EE1B9D6E37F7E -:10CE0000D2FE23D9FD27EDBC7E50033BED89742C67 -:10CE1000A3ECB372E1531D78C6AE5855683FFA9340 -:10CE2000888307DD16E1E76CEC45BFA7B644F2E95D -:10CE3000E354073212DFAD7FFE478F68FA756A3F11 -:10CE4000AA35C0ADB5529D8884FB04F68775D4DE43 -:10CE500073A717E1AC95F10DD6D98BEBEB4C92EFA4 -:10CE6000DDB40FDB23CDBBE6F99DBD88EFDAC83C0E -:10CE7000DFA6F76BE3E578BDD48EE2F300C54BA2E5 -:10CE800070B518E07A2D70A017E10A7AC25B707F46 -:10CE9000087A19EDC777B46CA2FAEE881C693BD208 -:10CEA0004A510EBD9136C757448EEE2739BADA7013 -:10CEB000C17E9A3E07F7BF4CEE275EFD75C33E89E3 -:10CEC000EBEEE17A48F2519D478E03F8077DD2E4FC -:10CED00093EDAFD5B7B8AFC6BCDCDF0DFE9E917D3C -:10CEE0002BE58969AB4DF27365E3B5BBBF4675149D -:10CEF000CDA0D763D563DF5B10D14FB7123E0BA532 -:10CF0000FFCCA4DD5181F72376872F627754CE8939 -:10CF1000617774629DD52CAAE722BDA9C213AFAE7A -:10CF20000E68C65C9E076C177592799BD95ABDBF77 -:10CF3000FDFD79DC9F7F6A1E874B7EDFF6CC3A854C -:10CF4000EAC4DA7BA68CC1F36EA7537DDB51AF0D2B -:10CF5000A45BE83B0527C5F73507BEE14CBB0FEEE8 -:10CF60001F4F73F9515F1D4FDA49DF513BEDB70A8F -:10CF7000FE3CF40EEEF3BAB8A2867A45C60DEF9EDB -:10CF8000B3F55194A3133EDE2E9CF7E377509E59E0 -:10CF9000A6F97C6780EC18C7CDB08DE0BBE2FB9CA6 -:10CFA000C5E279E5B61F7CBB0AC710F68BD49FE6B5 -:10CFB000F39EF863D7DB5F5D566E7F79793F2F1B59 -:10CFC000DA74C982E3F2B66B84EFC2D6C8F3CB261B -:10CFD0007BAAD2743E9989EFA04A7BBC38B9D18F25 -:10CFE0007E5CF13AA37D74BAEB959E42F46BFD56DC -:10CFF0000F6E93B7661A9F4B3B6C51D763E48F82D9 -:10D000005D689847D6DFDECAFA3AE85CB8EFF5C348 -:10D01000D68951BFA5DD5349764A7326B4603DC712 -:10D02000FEBE34311FED831E2B7E1196D7DEEBD66C -:10D0300001FDEC9664DAA7FD8AA2AF0BDAF228CAEA -:10D0400045B42E88B7A3F1F8BF7FD45047C7BEB60A -:10D05000CA10E7D46A1FA53A3E1917D3AAE9F919ED -:10D060009B8883694D8FE27E16899369BFEA35C438 -:10D07000C9B4203D0F46F6BF5DFBB0BDCC23E0D167 -:10D080004EF622BFB5AB5C9FBC34C77D52B37DF278 -:10D09000FE209FFF730EC6B7827CBF333F2F1E0C4E -:10D0A000B78F11761DD68B9BE57C5C80D7DF95A969 -:10D0B000D91D137C3C7EE504FAA82BAD2B316E10F4 -:10D0C000AD5729A2EFA4358D505FB224C0E5F7E833 -:10D0D0001CB7C12F37D7A934893A9591C6B9B38403 -:10D0E000E7D907144F35D7CB56867AB974D714379A -:10D0F000E6A664BF9B4BF83EF071967A12D76F8E0E -:10D10000A79DC5781AC9198F7B2C15BC63DBC9BFD5 -:10D11000572FBF677226C9EDDF0CF797F688784561 -:10D12000F9678B9FBD37C7784E7FA4FA87D212BEAE -:10D130009F1589F57ED6FA8727E35515F135047DCD -:10D14000313E38AC1E42D439C83A88B1810C5EB742 -:10D15000C1783D44BBD64AF8BBEAE75CC4FE0F7C0D -:10D160009A1C403EADE17A44F2D94FE7F838FFFD12 -:10D17000C64FFC27F90EFA4F0AA01EA9E6FD8B7FC9 -:10D18000C3BF7B21ED8B718133BD9BA6921EF2053F -:10D19000F4FEAF3B722E322310430F1D5DA04E0DE7 -:10D1A000E8FC23783F33901FF3FD2F13BCA6F7B3A1 -:10D1B0006606B3E8FDC8794E7566E06F7510A03D50 -:10D1C000CC75277CBF30D79D487BF0CE92DFAFC4B3 -:10D1D000BA934BF3D5651CCF1CBF11BB7288DB39EA -:10D1E000517B3287F6C36B602F36133D453DCD35FD -:10D1F00018FF5EFDF8D27E82FB7FA7BFFF79F3DFC9 -:10D2000000BE6E824FE44D3EC5FBFF40EF8B7CCDF0 -:10D210009F01DE30F191B0FB3F87F87CF6730EDFA3 -:10D22000EB44AFC59CDE657398DCB7FF35361F5CF9 -:10D2300031FFFF6F7A5FE4CD75E3FE5C3FDF48FEB0 -:10D2400039F4FB15E16DF130F93919D0E5E347798F -:10D25000FF8C7E7EDDFBEFEAF9F32AC8F9053D7D00 -:10D26000AFC13EF2118D3F958FFFBBE2C83A2EE968 -:10D27000EFFF2D4E76593E9F3617F1D5CAF9E90AD0 -:10D28000ECEB9BE6F2FA96108FCF6A927F678AFBEF -:10D2900043789E74F91C26BE8F12CCC6FB2AE3FE8F -:10D2A0006DC41FD17AF719FD1118688641CFEFD3ED -:10D2B000FB1BE5739FD88774B72EE0FDE7BE306E89 -:10D2C00015E2DFDC067B64DE5C635DA68AEDCB8D58 -:10D2D0008BF97F7ACF94FFD73D5F44CFA3F50B64E2 -:10D2E000BF82DDE672028D7F51674D6E8476B5F0A8 -:10D2F000DBC1FE8879AEBB3A1AE7AE9EABABC7186E -:10D300000C5AE97C60C44E61EE4711FF113B4AFBA9 -:10D31000FE3EE3B98D8314E72A11F46D7EE1D97ADC -:10D3200001E72AC4374B16EBB87CFF35D4DFCBFBC3 -:10D33000C7787E273D4FE57032F7EB67ADBA7C18B2 -:10D340004A9A05F3BCF82F1FC06FBF7D6E32D82BF1 -:10D350002F77293E2BB41BF74A7E7A81E44157F799 -:10D3600041F2B742F0FBD6170ED7233FAF785FC22A -:10D37000EBE4EB8FD4311DA6F59F10F188092F4205 -:10D380007FCEBFDF24F87C1CBE6B30FE36A213E3D9 -:10D39000F8A9619A7DE2287516BB04FDE1BD9D04E4 -:10D3A000978BC3551352C85E0FAE06890638EA073D -:10D3B00059CC38D3EEB90EB98FEDA679DDC28FF511 -:10D3C000C73E2FBB2FCA4FFBA8BF87CFE702FD8FF9 -:10D3D000ED40E8E802FC0E448DF8DE784D998DBEF4 -:10D3E000B750537861A98883507E53E6C14B1F9C88 -:10D3F0004AF9CDF8B238EE2FBA8C7FC722D8E4A410 -:10D40000EFC9C9EFD6CABA8C4A66FCBE5C8CFC96E2 -:10D4100021DE22E32291EFC95953C9BF753C2AFE90 -:10D42000FE93E9FB71F11B18C5B79C1DFC1CB839B4 -:10D430004FD5B0B1F5AD22ACFBB0D9292F6BCE677B -:10D440009AFF1EC63C1753C7E4503DCA6B73F3A343 -:10D450007528E7F74E71A31C9AFDE7F323F9CF7BFC -:10D460008DFEF380F49FD5ABE33F9F986BF49F1F35 -:10D47000CF0DFE8AF8CAA6D2FEF67249F1528C236D -:10D480005C147514A71E4A5E82F128AD879F573839 -:10D490002DF2FC32DF7FAA88B93D78DDE2247C9E44 -:10D4A0005A9314C62D784C47F362FCAEA0F4A31136 -:10D4B000F318FFAA10EB34FBDBF18540CF5924664B -:10D4C000E4679FF278282F50D125BE2F21EA05A4CA -:10D4D0009F5D21CEF13795F173D518B1437E90DF72 -:10D4E0000FAC107EB8F4C7FB7FCA147D1DC052E696 -:10D4F00027FEAD06C6C0EB32F13DC51A0FDB8240F8 -:10D50000FD312BC44A102F7B399FB0ED36FA3B57C3 -:10D51000A77A76D1BE3AD2390677893CC7A0517E28 -:10D52000F61AF8F9490497D83FAE60BFB98EFADB16 -:10D53000B81C6FC3F3BFF9D1EF4AC873F3DB93781C -:10D540001C654609DF6FCC57F9DD884FAA3F407F45 -:10D55000DE5082EF47FDF94C84E70AF4E74C825B2A -:10D560007CB76232E681F8FAB34B783ED73786272C -:10D5700071BB1CA3D70114968C92CF6597AF235033 -:10D5800063BDFFA1B0B3D7E5861696F07C3FF1AD41 -:10D5900039DF2FFB1DC3F8548CFD76838853950229 -:10D5A0008B5A72869FE7FF459B7A126DBC636DE5CF -:10D5B000743D6ED312B17EEB2D719E1F0C2DAA67A8 -:10D5C00092755172DC9ABAD2936775FB59C5C2C77E -:10D5D000A9CEAC3DF3C0EB0AC0795AD47B0D24FA36 -:10D5E000689FD38EF2EF4B2DABFECAC9B3BAFDC311 -:10D5F0000C2FD6456920EAEB4BF877CB5E2975F600 -:10D60000CFCBC3EF3571395CDD738ACEC3D46F687D -:10D6100060A12CAA9BB2217DDF9EC3BFBF50516881 -:10D62000659A0EAEE46CF5AE121EF759477C12AD4A -:10D630000BBC1BDBA576750CFEFD49199F94F98286 -:10D640009B5FFC3F94771B4862347FD0CBC29877B6 -:10D650005FA0AE770C61DEC5EBA3F8C8DA121FCD70 -:10D66000DBD8B59FE0890FBC47F0806DDD8FF58377 -:10D67000667C4BB9E814F8D6AD9BF03D92FC562C75 -:10D68000B425227EDF427A41BF07C53E70C476C111 -:10D69000ED8941F7C87B85A5067C3BBDE506BAB59B -:10D6A000ABF78EC1F5483A378A67E7BBAC6F221DEE -:10D6B000DF073A32A263EC3A88A348AF1B806F4C75 -:10D6C000F4AAEFE0DFBDAEEF28A5EFC5D5177EC504 -:10D6D00091427900A50FCF4B36953530B4A71D6A1E -:10D6E000127DDF4ED26F6919D04F072FC8E3632434 -:10D6F000A7C2EEFC14F1F5FF5EA2B383AF75FC1F69 -:10D70000E6FB51490CBBFCCF957F18FE3D1FBEEFD9 -:10D710009E12FC62BECA7D77C4FA662DB8AAE55394 -:10D72000C021E506E5769382F5938A1DF92C88F2EF -:10D730008BE7D70A7FBB05F3A1CD5ED6877BE13EA1 -:10D740009423C09BA33CDD81F2D3B8379DF802FD42 -:10D750007FC2A7D8A7DFC47D5AF8FF74BF85F3C581 -:10D760005F3AEF03F0FC1BC15327CE177CCEF25279 -:10D77000C9E541F73CC05B50DD4FFAE5A742DEE06A -:10D78000278D7FB7E993E5418B555E3726F3A131AD -:10D79000F29F3EE553E43FCD79D591F2A131F29F5E -:10D7A000067B7DA4FC2733E549CDF9CF455D5328A1 -:10D7B000FFBC28D342DFA99676BFCC7BBED1F50350 -:10D7C0001B7D176986C292D287E747BF2DF431438C -:10D7D000AB4EB7FEE369FCFBD7DD292EFABBABF8F5 -:10D7E00083F558129FA01F5C4E98B76321AFCBAC56 -:10D7F0004C7FC68C5787F04BAE08AF32BFEEE85275 -:10D80000C29B9135BC2C52FFE7D0D1D991F91CD1E4 -:10D8100091D9FADDF83DEE46FF78AA2733D3A1B8B7 -:10D820008BFF5DCA62CF6CFABB9492FEC5DEE175D8 -:10D830008336095F8CBAC13F3B3D7D9B5D19A3D008 -:10D8400053E6B147A2E3ACBCE0BDF32644BFDF24FE -:10D85000EF1F4FE3F83D7323137FFFD4484FC0BF42 -:10D860004AE7FA33D9FECDCA707E2816F598C599D5 -:10D87000DA7AAA838F5FECC5BC5904BFA98708BFB9 -:10D88000EDADBEEDE81F1D2DB353BD4A0C7EA0BF0C -:10D890006F7B397E1846F79E4F47BFDAA22716A442 -:10D8A000C7E08F4F4DD7CBD0D3617DAAABD0174BFC -:10D8B0004E5FE92139F55B3D4857494F49DFE1F4B7 -:10D8C000E4FB9DA4F7DBF9EABFE07E18A5B3FA34C8 -:10D8D000D2392ABF9AA19EC5FCDD9B1F8A3A161831 -:10D8E000E7391CE710FA58143F540FE138555F8AA6 -:10D8F000FDF74E9E29E5FE4E1DEB7B7522FA7D67F6 -:10D9000099A8D7F4BFEEC338CD862931EB358F3DCA -:10D91000A0F0BFD3E365FB2D627FB5E8FCDD535873 -:10D92000B709FEED09ACDB84EB5BF3D2F9F7E5B1A7 -:10D930007E732CD8E3A2BEB30EC7C679C09EC5BC09 -:10D940003CB385189E4B1FC0EFB3CCC2EFB36C2223 -:10D95000BD1BADC3F890F45534EEC9DB9501D97603 -:10D9600087A9EE46E63F993764CC7FCE0C1BF41DA9 -:10D970002B0C19F39FBC4E47EAB7CDEAFC10C6B595 -:10D98000A371C5721AFF649DECBF235C3A4397FFF5 -:10D99000D4AAC2AA5B9FDFBC2DACCF6F82BEA4B657 -:10D9A0008C433FD1FF6008EDFAAC99A10B48377961 -:10D9B0006E1E14908A7F87CEEAF61C403F1CFC0343 -:10D9C000A6E68F6C575FEBEBFF07133449A100808D -:10D9D000000000001F8B080000000000000BE53C69 -:10D9E0000D705467B5DFDD7BF727C9866C42A04B0D -:10D9F00009ED4DF879692561F909044AE06E76135D -:10DA0000B62D9405429B0AC50B64101D5E0DB5280A -:10DA10003EEBCB42421A420BC1E1F937AFBE2D05B6 -:10DA2000677CD631386AA1485DA0459496A63699A0 -:10DA3000521FD280790CD5AAB496577554DE39E7B7 -:10DA4000FBBEDD7B6F3685023A75DC4EE7E6BBF741 -:10DA50007CE73BE77CE7FF7E9745B315C66631F868 -:10DA6000F99386C6585F2DFC79338E83A651C2D8B0 -:10DA7000D2B1725C9934263236374F8EAB4D633655 -:10DA8000631D1E26E6B30403F8D7989BC69B8D5AE8 -:10DA900033318EB1F02255C0C708FF99E5127E4799 -:10DAA000320CF896B9C438B12469F819FB2893E30D -:10DAB00005345E9E1EC769FC00E3EBEF4D3D6E260C -:10DAC00060FE77A6C56F3646C0BD68B71EAFF8C703 -:10DAD000A3FF9C22E9196BE2F30F3BBD20EF9851A5 -:10DAE00085E8B9BCFF01E85D41FAB19FD3FB21A4F1 -:10DAF000EF2192E7D39CBE0F013D6D444F37D09389 -:10DB0000FFB75FEFC52A6327EECFDF808F2768DF7F -:10DB100027723EAE02FE29E23BC4F7C1F9FCE67073 -:10DB200080317C3E8DE37BDD2DF428D164A2DE9F25 -:10DB3000755BF60DC6B37AE57A1BF4B066A57F0374 -:10DB4000D9C9B2223EFFD7A9CF9A8992CC187E06B6 -:10DB5000EEBB9CFF1B7C6E9BFF199ADFE94EC3D383 -:10DB60007A1EF15C39BC89E8CDF09B20F81E077C59 -:10DB7000A3E0AFE07047326191074B3C4AF249FBAA -:10DB8000A5C4E3E497FA3C72BC8DEC667B29C73FE1 -:10DB9000EAF0E349A41FE47782E43D8ECBEF9F5D7A -:10DBA0001EBF3584BE947379483DFCCE34E377A81C -:10DBB000671F367A61FFD4F0888CFEFF1DD62BA438 -:10DBC000F5843D7DD0F9697B14719FCD4FCB77747F -:10DBD00018EE8FAAD5E979F5DA7D919BE0CFE5CDF6 -:10DBE0004FAA26E2051856CC58BC9F2537C39A7712 -:10DBF000B0A4CA2086C543260B4CB4D835FB32D11D -:10DC0000E1F1BBC4F8BFC8FF2D9B23F5FA5412F312 -:10DC10008B0CDDFE95B84F69BAD91336BA671FF67B -:10DC20003F29F80E852D7672A3F1076B412E967C65 -:10DC3000283D16F259F6E057C7A01C969549BCDF5F -:10DC400048229ED70B25DE7DB4EEB2F43ACFF171B7 -:10DC5000AE84FF29C167E8EA336D74255EA5BC4B2D -:10DC6000D2F5CDC37DB45F9E4072CBC869706D5252 -:10DC70004209D88F8FAEDDA49A56BFC0BAF530C422 -:10DC8000B7FB597A4C7A95F103DDB4EE8DA66B7D26 -:10DC900058C847D8699ACE7E164A302B7DFBF9FECC -:10DCA000DCE0F52D7EE121D4DB1B2FF794FB268BE6 -:10DCB000DCA51D2C0FA4EDDB603E90BB2EF1BC60FB -:10DCC000AEF55FFFBAA0E78F5BFDC9F5F3D153470F -:10DCD0007CBCC5F725E37F5E36EDFEE7AAE97B3223 -:10DCE0006C89E71F74FE7F87ED7666F13FDF42BEE9 -:10DCF0005BFD451ED4EF9541662481BECBF89B9B0E -:10DD0000B98EAA55C83FA5EDB39ACF5FB2833577D8 -:10DD10004F1C0C7F53AD8BE05A9F656BBB015FD8E6 -:10DD200073B1296E814B85F9F3436185AEC0DF2164 -:10DD300092FF464EDF89B04EEB8599C60CB0A9869E -:10DD400025634A500F5A7FCEF1B160882DCECFE0C7 -:10DD5000BB20F0C9750E2FCA6FB4F2F113B1CE8992 -:10DD600030E703E33FC9F311CE875AB02E88F8D5C8 -:10DD70003C595FFE9AE4DAEE16E3C43B14D7FAD2BC -:10DD80007EE877A4EF4BBD522FDF23FB97F9FA3BD8 -:10DD9000E13F2513B3917EC65C53ACF37E4B7EF01E -:10DDA0004AF3FA65BC6813FB9548EFD759A4FB4AC0 -:10DDB000F3D588D24C72F2B19402F143F50776772D -:10DDC000022B1595C69B38FFA5C9C6AFAE060FC876 -:10DDD000E922EDCBC3F67AC4F2FCDDB0AD1EB8B8D3 -:10DDE0002E8E7860652FECDB6BCBD5E25520B7BF6C -:10DDF000E2FE54517D10CBA65F7FCDECCB5FC3B666 -:10DE00007C3E925F0576C446B942E3F5C1F3FCB5AA -:10DE10008AD433B14FDA93C8477BDADEF8787B21B6 -:10DE20007F9E73C4BD52D8535E2DAEF33D215F1665 -:10DE300028C6F5D8C4E329753AC45796FE192E189A -:10DE4000AFC2BF60FDBEC85937EAC18A0EC5486679 -:10DE5000D1FB4176D221F03F96DEBF51B52308AF0A -:10DE6000C9A68BF801BFBE8F6F22BC8D4D0AD99F0A -:10DE7000D35EC6D672F98DAD4DCB692CD16F70BC17 -:10DE8000BE69F1F188174099774A06FF0A4177D8B1 -:10DE90001D3F7413E8417B9BA2A33F5AB9716547AC -:10DEA000298C99E60E8D87CB049414CC6B0F96F9D0 -:10DEB000D10FBC24D6437C1ED8478C25C122826357 -:10DEC0001A5CA7C7D61FC5E97FA930AB70DDEAF899 -:10DED000CE08B235AB71DF51BCDE036E1AF3944D40 -:10DEE00073BE16AF85FDEB99E90EA1AA4176D63334 -:10DEF0000EE86A107469C6BC37D930A8A23C2C94CD -:10DF00009A8671DD1FDA0CF71B9A3E3E9F55024C34 -:10DF1000DC3DD0EF43664C76B90CF16A03FDE55C5D -:10DF20006697C1C72DDAE8CE8C91367CEECB3C5F8C -:10DF3000722BF74FCB6A419E16BDFB91E0EF474233 -:10DF40009E3B80869E8984209FA1DDB0B52E94DF04 -:10DF50004A81ABA76DC95DB7017D97CA5908C75EF5 -:10DF6000E44FCDF077768CC6F963867FC148585769 -:10DF7000ECEBC916F075FF0268DB804FE047539762 -:10DF800017A42C7A7C7298C94298B79527B630D0DE -:10DF90009388B9D3DD0F74DCDAF4F65ACCFB5698CB -:10DFA0005E7D1E9078FFDA401DE6B54B4C2197F957 -:10DFB000EE73C8B70FFE43B978526FBEE04139CF58 -:10DFC00056D828C0BF30CA9F4BB9789976CE2A1749 -:10DFD000CD31DE78BA74FBF316F84FD5E6179FFF04 -:10DFE00008FC31954DBD0C7C82035980F45CEA50ED -:10DFF000026A2981B918F0E9F1F17DDCDBB1FE2577 -:10E00000B4D315412DE4D2913E46F26B146BBCD7CC -:10E01000A26F7F1E72D5C8C69D5DA877F7F7AACC00 -:10E020000B70EDCBF72226FCF9109F26F4C295F772 -:10E030009F3D1AC069FFA6325C4FCA11E41D980EBD -:10E04000F7CFF5C17C00BDBF1AE404EBDE63787541 -:10E050001DE07267BFDD8672CA65CDA9E130BE37AB -:10E06000E862295F862FE03B21E4E2BAACD05ABADD -:10E0700026D775D99E935C723F17610C7D77C2E8F5 -:10E080001907708BA4DE76F0FD5C64F0FD90FBCA8E -:10E09000A25C5FE5BEE43AF4D55BEDCEE867167DA1 -:10E0A00075EE43D2B10F7B356E27677B55CA8FCE95 -:10E0B000EE2ABEA71AE491D8E5223B863A6DBF52FC -:10E0C000007FA414A681FCEF13F4D20FE0F63617FC -:10E0D000263B4B33FB715FF9B13F2A958C438DCCC6 -:10E0E000F82386452C8CEF15A3FBBE9228423BFDFE -:10E0F00028EB76A35D3FC0FADDA8FF1FC352504551 -:10E10000FF18F2E0FD465FC08372DCBBEB483EFACD -:10E1100091D4CDEEC2F3E5642ACCEA279D5794C48E -:10E1200079C93700A7A4FFF49941F2CB7EB8929F3A -:10E1300036188E0BEBA23E334B1C3936D5FC31FA28 -:10E140002339D602CD0CE9D83335FE13EE77F9FC2E -:10E15000F195C64FD17FEE9F629CC0FBDFC07C0F64 -:10E16000E2C3C5DA47A82EF94B857112EF3BFDD803 -:10E1700039F4637A461F163BF441FAB153E8C7E01D -:10E18000D162B457901B8B5D9F1F3B2BF5E07676D9 -:10E190003BCA07F8F925F97F0DF801B99CC17D9FAD -:10E1A000C4B0FB966245C4A61E00FA14411FDE5798 -:10E1B000C0BF2B1B7FFC4765181FCF023845EC2BD7 -:10E1C0009691751837BE1EF2F9C6A2BF304F21DFF7 -:10E1D0004EB9406076535D163C760AF5C695F7C396 -:10E1E0003166963898DED775EEB7D27CA11D4126F0 -:10E1F0008F7C28CC745D467E0240C4A8F7D38B0484 -:10E20000E941FB0285F86B2F658DE8CFDBF0D14C3F -:10E21000D0F7054A37EAFBB722453C5F1AC7F3C27D -:10E22000CEC26430C4FB2C04CFCA436C494506EF10 -:10E23000B7222AC14F9A66E461E082BC8FF2259929 -:10E24000AF4AB84084E795C3233CCFA8A88C1751A8 -:10E25000A02B0E91DC218F1A4E637F2AE91A29FA2E -:10E2600022FCA7BB2C7944DFE824C33C24D7C89EFA -:10E2700037DC1249C7F55B22C8C72E19D78D5B1151 -:10E28000FFDCE18106F4731EA07B7769265EFF60E8 -:10E29000C1175458967D24524AF45537ED6C1D0928 -:10E2A000FB1D0E8FF563DA94AA4906318FE81C0531 -:10E2B00072C8622F1B233C0E4EBB45C00979C9B8FA -:10E2C000EF83F4DB0DEB6099EFC23CA084E7010F14 -:10E2D00044CA689ECC07003EE101B8F00493F0B454 -:10E2E0008FCFBEDE03429E99781B2A407FCD5833E4 -:10E2F000C58BB88827AFB51867064029FB5A6274EA -:10E3000005FFDF130507774A4BE487B2C86F61DD6D -:10E310001E1FC6EDD6F255BE7ECCFF8C08E16D5CAB -:10E320001E3E3360F1B79D256C0CE601F736DC79B3 -:10E3300066C0626F3DF99C5E8C33096F06EF52D464 -:10E3400013A0F768D89B9A0B02CD0DB2A457A1ABCE -:10E350005B473B88E8F43C6EAC6426D6E3D5673572 -:10E36000EA7F15B234FC26D89A483973235DF160F0 -:10E3700092E1BC5C18237C7CF6DB04BFB05A6509D3 -:10E380000B9DE07F56901E38F2A51DA86080B77DDA -:10E39000A692DC0C781B826B28FE6C9A934BF7617B -:10E3A000DDA417EEDF33BE89E296CCAFDAA3D1103D -:10E3B000C5A7EBCCA78E4D8D3F84FAE809A6FDEAF0 -:10E3C000C34467C6AF6E8870BFFA19BC4AFFB1FB81 -:10E3D000E86BE43FA00621397782BCBF9B651F37FD -:10E3E000093BE82CE47AE87CFE55A1AF7FA988B709 -:10E3F000221D06C4B4E0946BCF37DB65BE29E478F8 -:10E40000BDF201797C2962F1CB208F2F679303FC49 -:10E41000DAD05FA8D25B3CAD68A8FF3962F824333C -:10E420009338CFC79A0948F5C719C6BBC178520CB3 -:10E43000E72D13FC7D507FFC1D486FB85F339E8E27 -:10E44000505DC8F559FA65B04B1E7FAFD16FF7BA72 -:10E45000C09F023D1D786B66E6F921B1CFCF55997B -:10E4600087701F2794F856A2FC1F558CA05FC5BE6D -:10E47000A7D9887E84E9536CF306AFB389F0F4958D -:10E48000996BD1AE99BEF80AF09BC5BA824F9DF345 -:10E4900001EB7E25776C667C25BE7E10317E86F290 -:10E4A0006A35E3BF40BB7BB9DCA52714BA921D7661 -:10E4B00056E724151807A698AFF37D043F0AA83B3A -:10E4C000CBDFA1BC68E17C85F2B4853EA8E0B2F860 -:10E4D000C9F322DE2CD4F97376DA085AFB1D855174 -:10E4E00097BDEE059530ACFD8BA86B15F6E5653C48 -:10E4F000C3BE49367BBB28EC49F5BE5D827EF5651F -:10E500007776BFFD4EC443704A54F42544FC5BEA61 -:10E51000E5F5157B11E8B3C4D7E7AA6AFF8FE2627D -:10E520008225144B5CEC1B7D91FC1D3DB1DC5F280A -:10E53000FA4EACD78E47F2591465B675415F5D51FE -:10E54000DEC750A396E74B55C6FB1E3D7679013DCD -:10E55000BE28AFBB9B94E959E919C7A667A1E79408 -:10E560009D9EA228DF97E7AA8C22C407F17938D2B2 -:10E57000D1510BFA9745BEFB26D5DE84701A4B7439 -:10E580009495BE6FDE7A0BE291634BDEAA47EDFEF7 -:10E59000B534CAFD6B5994FC4AF6752B85DCAED7B1 -:10E5A0003F5CABDD6F73D8BBBC76F67F2FAF12E854 -:10E5B000F07A139F267B9D7875F6FDB15B7A462332 -:10E5C0009F87847EA26FC77CC3D0793EF26094EBB4 -:10E5D00071784292E09E1D22FF48C38160B02F37C0 -:10E5E000541E32F31AF390CED97D7988A7F5DDDD7C -:10E5F0007958C73F3B509B350F3954D245743AF395 -:10E60000900343E4216BA23C5F3DFABF1ECA2B6A14 -:10E610002EF0385F73A14BD5413FD745B93F9B39A9 -:10E62000D0A39AA027359887009E03220F41F84D6A -:10E63000A0BA9177BB54A46BE6851E9A570363CCAE -:10E6400043660E918700152AEADDFE9ACE5771DFE8 -:10E650009CFCBE58696E885AEAADEAFE1E7A4F22CB -:10E66000E775966FCE33699FED7A736C2AA73733BF -:10E670008FEBBB136E28FDAA53FDE5D81FD8CA72D5 -:10E68000432887F7728655B2025ED7605EBC15419B -:10E6900081EFADA7F39209ACAB7DFCF9677387ED11 -:10E6A000C6ABF43F3E6117EFE5DC92147590510064 -:10E6B000F33FAB1AA9B9100FB68EFB6280F3B39E7D -:10E6C000EC6883904DED4E8DEAE93B827C1F64FE41 -:10E6D000F5D25285F24340337F01C0CF10F83DD3CD -:10E6E000787D58AFFA096E5B39CF23EF485CA4FE02 -:10E6F000C5CC7E8FAEC37846FF1A5E2FAA3F3C9EE4 -:10E7000087F9FE4734A6C2FDA56DF156D2CFD31EC0 -:10E71000EA67C8FE42556F37C92D6FC063EB73E4DB -:10E7200082274B59F2168F63CCD4E505D9FC90BCF7 -:10E730003AFB10FBA2A2FEAC64932E835C2EB14781 -:10E740003A9037EFF8DAA34FB1C1F3657FE1C149E1 -:10E75000C633A81FE3DCFDDF7E06E475E02D0FF570 -:10E760002D0EECDA757725F097E8D2A8AF2BEB19D0 -:10E77000905BD122AC675106D4973EB90AF5F2609E -:10E78000BE1C834303BA0FA6DFD77F629561199F32 -:10E79000886E398771EFE00809FF269F2FC789FE31 -:10E7A00055785EE3E0283EBE14559F4AD0FEF66BD6 -:10E7B00054476FFCA53F9B7F3C5967D7D77BAAD7AF -:10E7C000737DBDC23CF0EBAF47B3CCCB59606EABB1 -:10E7D00000791C1C70D1FB21A8B352981F3C38C98A -:10E7E0007C03E11F3DC5E57AF0AD8702B84FDEE15D -:10E7F000FD0F67F3F3BF11F1285DE74DE6FE83B12E -:10E80000010DE3D68E39CF9EA884754ECE1C3F45B0 -:10E81000051640163ECC97E57C6F1DAFE332F4BD84 -:10E82000A2AE42FFF3D6B9866CF65E15357F1FB5F2 -:10E83000C1F3F7A2AD5D1AC9BFE8D8BCDD78EE27F9 -:10E8400055D3D5A3C1FE1EF88D8B619D72A042D415 -:10E85000E143D11502BA8AAE8AAE5D33B2E81BD06D -:10E86000E5A91B3198AE97EB18C9E7C54AC387CF16 -:10E870009D7432D1C79C25FC7DCE9B5FA4BEE381F5 -:10E880007E17354F2E0DEC5651F564FFBBF354192E -:10E8900066406CEEFCB32AAA94F9886AB3BB19A748 -:10E8A000726DE3079A87DBC6CBD68ECED821FCBF2C -:10E8B000383AD636F6066FB78DC36CAA6DDC30FFDA -:10E8C0000E1BBEBA40C4369E17BCDB067FA7BEC473 -:10E8D00036BEBB7C990D7E4168B5ED794D60E7167B -:10E8E0006C1FC5274ED68633D2C7C975B00F79BD08 -:10E8F00006E9E3A3A71E0AA05EA46AE26350DFFA5A -:10E90000F27B4AB07FFD923B7BBDF6489D2AE377C0 -:10E9100009C67B83F17A4DC287CBFA6D7DF9D57537 -:10E920003C3EAFA853B2F6099CF158C66119979DB9 -:10E93000EB3BE3AE33DE2EBC6DB78FF7FB79DC5FCC -:10E940002AF4A0B5FC677EACD75F6AE07D84CE92E6 -:10E9500038F50DFA447C3EBAF4BE31F85E2DB7DCD2 -:10E960001CEE2DCDC4EB487992FD12FB3C81241B9B -:10E970005B81CF936C7505F5A5B5C8447E7F82B8E1 -:10E98000BF06AF10A7EB2D7273C6DFB06FF20B0599 -:10E990002C93AF34FCC18816007D7735EDD38AE126 -:10E9A0001AF11FD6AC7EE864CDAF8A8788D39FB4B6 -:10E9B000DBC72B641F070616BF6F1C78A385F7DD26 -:10E9C0007FD0E26329E0EF744B80AE3F6F09D2FD48 -:10E9D000575A74BAB6B794D335D512A2E7AFB65426 -:10E9E000D3F5F91683AEC75A62743DDE1227B89F7D -:10E9F000B634D2F5C51693EE6F1776FA61A1C72823 -:10EA0000977D85F8519742726DC0A3BAB32E18AAAC -:10EA1000D5CF835CFF239B5CAF359EA46ABA47A326 -:10EA20009E41BCCA6A4FDD7532AF4FEF37D125F337 -:10EA300061AC5F504F649F0EE8FB26D2E7C5FE5CD9 -:10EA4000D1F5D37750E1741D2CE4FD1BC4B3281F0E -:10EA5000FDF9D7E2B5E4CF474C267F1E649ADD9FCF -:10EA6000970EF2E72BC9EED871EC93627F91DE53DB -:10EA700038FA2005F53ACD937D90397FE07D902BD3 -:10EA8000F10F7C1F47BF25FDF6D5F2EDE4F7D85412 -:10EA9000E365C423E3F3A0F861AEA3F8512D6C96AF -:10EAA00069EF529E9827F8D9716E7101FA172F12EB -:10EAB000C8EB748355E33E33791E60F7DA92C17870 -:10EAC000DFA8E9A678BE2D9DE7BC4D79CCE0F865BE -:10EAD0009703E642D6F80E7278B3AE6AB07ED6A936 -:10EAE0003FECDF0CF1F9603FE37DB269FC7D9D8C6A -:10EAF00083072FF03EC6254D4932D8BA5AD6DC35A9 -:10EB000003AEFBBFC08AE3F8BE698C2BB41740F399 -:10EB10008E1CD07D0017EE3787E7C0F3EA540ECD88 -:10EB2000AB9D3F3989E386F8DBE49F6A357B9CC463 -:10EB30000C351D77A80956E418DF9C8157717FCBEF -:10EB40003263C0BB6EAAA9D5035F8B2F36331DF08D -:10EB50007B4B989BCE870C8EEFEB144B9F4D63A1A4 -:10EB60000EE443FBDC36FE5ECFA16F524EB2DF26D1 -:10EB7000EBF0279911C0F59CF8DBC47B17E7FB96F7 -:10EB8000F72ACC20C22B8163F4BE85AD65FC7C8462 -:10EB90000BEA1394DF304F726FE960BDDB3FE5CEC7 -:10EBA00031F564DF09E5C6D4ED5D0AD5EDA26E62EC -:10EBB000FAA75CD63A46D64DCEFAE831E167655DF4 -:10EBC000F4989B51BDD5AEE486761393CD93F8FBB4 -:10EBD000B8E61978ADA9977EE90BB63AC91FA83FE8 -:10EBE0003330355B1DC7EB11777ABF4B02E7F33249 -:10EBF000FBEDF798413CDFD83E79DD5756A2BC4685 -:10EC0000F8E8FD26D3E23AFA9BC7F1443FDA7320D5 -:10EC1000C18AA767F65765DA79ECC77640F282EFCA -:10EC200077E3F53C9F70D2E5BE46BA7023E93DB567 -:10EC3000B4771617EF25791EE913F7DB746EF70C1E -:10EC4000FD96E53D799BDFF0052CFBF828CAD93B02 -:10EC5000F4BEAAA56D01EC6777F95D64A71DBAB68D -:10EC6000B514C61D7E8DE729BA2B96ED7D5247BDA2 -:10EC700022F8E67405045D6A7831E53343ADD7299F -:10EC8000F65D8E73279A06D9951E8A63BDDBEA2F3F -:10EC900056B0CF299FAFAA57C4BE77911CB68AFC45 -:10ECA00028B7BC3BE5427D19B5662A8ACD07F9CE67 -:10ECB00079B8EF9BD84DF951FB089FED7C96BC3E8F -:10ECC00026F06D75876254BFE7BB18D6EF5B4BB378 -:10ECD000C7C387C5FEB6EA53E2089F00B98C570642 -:10ECE000C3AD11705BDC5DC100ACBB75FCBD74DEF7 -:10ECF0006BEB1872356CF48F6F7B6A937FB07DC0BD -:10ED000098F6CF1D60F23DBAEDDC43ABDED0B81211 -:10ED1000D6D55E6121340B6937DB313F81AB7BD4C3 -:10ED2000E246D4DF4BD5B92184AF535F4CA01CDB46 -:10ED3000438CFA165A61930FE97EB444A3730E9282 -:10ED40005EC8BB77A3FFC80FB96CF9794175AEC334 -:10ED50008FDAE981F548EF86DA5F277D94924F7963 -:10ED60001FF842B3319E05DFAB697BB7EB97FB0A17 -:10ED7000FA75257E6C71B22413278F1CFBD7D5F84A -:10ED8000BEE371C69F3F7F6C0ED5EDCEF18DB2F321 -:10ED900056ADAB11F7A5759C87F4CF397F6B29A7CA -:10EDA000ABB57E965837A0A0FE6FAF2ECA413FED9F -:10EDB00047876B91EB0B95E6CFEB2D71B830DA4CB2 -:10EDC00071F8BBF58CE4E8D7E38171A017FE5E15FE -:10EDD000740AE4EEFAF31FCEEAD72E47D66590DE2A -:10EDE000FA59E6F76790CB30C6F5C4CF1EEBA1B851 -:10EDF000C436109C94D7F65B4F86526CE875FDD5EF -:10EE0000F63ED307ED23FDA93EBF98E49CC37250A4 -:10EE1000CE97D8230AC5E1A841761748FB557EFE58 -:10EE2000A4580E811D1C93CA2999FE12C3F71768B6 -:10EE30005F26A33C8520478A57573AED0BCD1B2D03 -:10EE4000D0DC8C076354D47FEE772FB1B7F8FA305B -:10EE50000DCF9F280917C5CB5B51AF01AE94997FA9 -:10EE60003C9BE55CCE9840D3BED5702D9E27FA62C0 -:10EE7000829F2BC943D2FDB7D25B19E79DFD50D9C4 -:10EE80002F7D06FBA5CA95FBA14CBB48729379ACBC -:10EE9000B33F0A712D0FE5FEDE048D7592DC791EFD -:10EEA00090A9D74D9FF51C9D8C97ED81C5B63EFB73 -:10EEB0000CA94B0E3EBF7785B8D8D90B7E13F3E172 -:10EEC000E066EAB3EF3FBDEA38D6E397821E9D596C -:10EED000FC7F7BBEFD3D80C4FBF979A29F3EAA9ECC -:10EEE000E17CADC76478FECE130C515C6855B2BFAF -:10EEF0003F689D27F209679C70BC67F99F1C7FD211 -:10EF000053C6D2F14315FE59C657A641141D699D3B -:10EF1000CFFDA894C77E9157761EF9049D176041D6 -:10EF20004BFFB62CCBFACEFCCF30F4C0F44C3EAA4B -:10EF3000F4F33C54AEDF2EEAE7D6D37C3F72C5B97A -:10EF4000A141FA5A617E7A1EF67FCA5D8E3E95DD3A -:10EF5000DF38F35AAF8F25722DFE0FF2DA8DF328CA -:10EF60001FB1E7A5C3638C9FEF293419F6712241C5 -:10EF700053C5BECBF4DE669501DF334EBFFF7E2C5A -:10EF80009AC7F39CF6F25571AC7F641F79C79CBB9E -:10EF9000C8BF421CDD3ACF52C7CA730B1FB4AF249F -:10EFA000F575BAD847896FD0F992D91BF8FB9FD372 -:10EFB0000F9D407DDC0FFA8871BE3D3FB1AD02F37D -:10EFC000935754B6571FDC8772F225FB49FE18D7BA -:10EFD000534FB0FDE85C97453EFDCDAA4EF2311887 -:10EFE000BEEFD1C4FB1E67FFC8EB359A317EA76A1E -:10EFF0008C466BFF58CA6D91D0E7376A9AE97DD489 -:10F000003343BCFF9570F89918D6D3B21F553AC94F -:10F01000FC3EEEEBF4D87A15DD48757C3D9DA3CC23 -:10F02000FB77467520CB55927B61A923739EA53A49 -:10F03000F1F74146FD320FD689C55817F23A51D63D -:10F040009FD24FD4A94F7794E1F98C5E8DCEDBE54A -:10F050001DF9840FF3DE70EF6AAAD50C65691EEE08 -:10F06000A33C7F24E9BCDE3AB30AEB4CCB7B928C09 -:10F07000DF88FD02F5A0B325FE8B28E8C781168343 -:10F08000C6ED2D8D74ADD29206F253554E951B9B55 -:10F090003500CF2D7454F5C46CE31D95E619D4CB1F -:10F0A000BCF2B8EDBE3708F82C7A0175EE3992EF54 -:10F0B000692E4FCF7C85CE152CEC675BB86DFFD3E6 -:10F0C000F8212D7663FC504EEC7DFD107F5FEAE960 -:10F0D00017EF4B1DF6B6679E4E7690B63B7C6F4A97 -:10F0E000712E41F3E9DDDF4CE067D827B9DFCA9C18 -:10F0F000CFA0EF12C3E27B693D366B0FE6B3EDAFF5 -:10F1000033F99DF01EC3F21CFE6AC2EF440E63B1D8 -:10F110000B79E6E65861137D4F2DBE87893416962C -:10F12000F4B1CCB945A7BCB6C45CB6733161C6FBBB -:10F1300062F2F92763A26E03765C96730FB978EEDC -:10F14000214BFEDE24F0350B397578F8B983B98E82 -:10F15000EF3C66C6785D30D4771E9F1378AEF45DC1 -:10F16000C76201773FAE5745E722C331A4372EBEB1 -:10F17000CF1274CCEA4DB60EC32431C8B2E2B93313 -:10F18000C6CFEFA562FC3CB1276868B82F80EF6E50 -:10F19000C2D7C8CF59CAE7B32EA49F2F243D69E038 -:10F1A000CF675D30A91F24BFAFBBF3F8D83D9BC626 -:10F1B00065CED7B4633FC28FDF99F0734BBB04FDBC -:10F1C000CEABFCCEE4DE8038A793B8758F81780C87 -:10F1D000FE5D65EDF10903098DD6FF18D127BEABA1 -:10F1E000992CF885FBAB882EC7BF0FF0C0F1E01E4D -:10F1F000F13DCE1A9AD7CCE9CEFC7B07A13DD6EFE4 -:10F200007B261FAF6C12F0EB087E2D87CFA20F423A -:10F210001FA7ECC15EEA55E0FB0CD1B79CD3571693 -:10F22000D3F977590EBD05B8CFD3BAE23B9FDEF8CC -:10F230006A1FFAF3CCF7FBB7D17A5721A736C2631E -:10F24000CAF59838CFC4ED42EABFD4876F08FDBC39 -:10F250003DA648BD7A8CE86DBA61FC7F89E8717C77 -:10F260005774253E2A2AE34FD0BC60FA5CF1D78957 -:10F27000AEEBA4477E07E6B48BEF0BFE61DDA7691A -:10F280009D92109D2F8275BF7D23D605BCCF101E89 -:10F290005F1AEFFE58767FF381F0B292E2AB3A1F2D -:10F2A00022C7FF0F94B0BE363046000000000000B9 -:10F2B00000000000000000001F8B0800000000009C -:10F2C000000B93E46660F8510FC181486C62F11A3B -:10F2D0007606866816068699AC0C0C15402CC74934 -:10F2E0009AFEE540FD8B80782E10CF00E2C940DC0D -:10F2F00007C49D40DC02C49240F34480981F88B943 -:10F30000809815881980F8370703C3370E8439377A -:10F3100080620F48B41B84AD7810EC3340FF6F045B -:10F32000E2AB6484C3281E1E389D9F81A15A00C190 -:10F3300017104495CFE047B0B94429B34B1AA81F22 -:10F3400000656D40B4800300000000000000000074 -:10F350001F8B080000000000000BE57D0B7854D5E2 -:10F36000B5F03A8F79666672F2204C4280134830CD -:10F370006A8A03840882F52420C696DA9152C5FE73 -:10F38000D60E34224A2051B1722BFD726002040164 -:10F390003BBC1414E9E00D8A8A362256ACE83F20C3 -:10F3A000B5B4B56D6CB9D55AED0DB5AD2F0C88520D -:10F3B000FCFBEBE5EEB51F99734E661250F1B7F703 -:10F3C0000F9FEEECB35F6BAFD75E7BEDB577DCB232 -:10F3D0000FF287029CC49F8B00EE7003C0D8743A72 -:10F3E000EAB66FCC7DA49AFCFE7FDD916D7ABA9E61 -:10F3F00048878244EB01180045001779C9AFA4DEA5 -:10F40000A49F1FFED37985007B41010FF9945227F9 -:10F41000157C8DF4B3F7238860B9FCF3406957007D -:10F42000DB99B4DD9781B54B95E9A55A156640C6C1 -:10F43000EF8697FE4EFA19BEB999B43FFE6180B6C9 -:10F4400077C22152F84886146F737218F6AB7ED0DB -:10F4500055C9F3654006070EEF64809A34BCFB5F24 -:10F460007B83C2BB4F25F0EA19C6F712F80BD3F025 -:10F47000EF856FE4421583DFA849C37FBAF0D0F966 -:10F480000F0058DEA23F5DEE0258DD024F97570095 -:10F49000AC6CF1D2FCD2168DE6E32D619A5FAE9290 -:10F4A00026040FCBDB216992F6A16A525FF447FE76 -:10F4B0000B54796D79772169EF4DE7D540D896F7F0 -:10F4C00096EAB63C01E76098CCFB1C3E9FA52D0454 -:10F4D000071E1CDF0BC65958FE6D8A171FC75B3C01 -:10F4E00038E2CA61042F6D2F2A84D2002EDD988164 -:10F4F000F09507DC7A92B0C63981D9536124193767 -:10F50000140320F5E21B00D612B8CF0E4C790B4243 -:10F5100000F793FEDB48FF4AA8ED650F295F51E62F -:10F52000D615C4CB76F52F5D640C2FF987783B6B2D -:10F5300023CBA7E745F296799E0D9672D2FE977976 -:10F5400077BE2C1138E2E56EDD23A5C7E9A14B3F5C -:10F55000FD5724EC7967FFE5BA51877C2AFAAD8024 -:10F56000E8122DF0C5EDF71C82DB82FC74BF629CB3 -:10F570007EFB25E48F92B6151B21992AEB3D4EB9EF -:10F580001EA9374979F946159265EC7B219187725E -:10F59000F62B2C2FADF3C7AA7AC303D67186A5E943 -:10F5A00052AEBB67CA842FCACBAF982B11BE8184E1 -:10F5B00085CEC31883A2BCFCB045A3FCB8BAA59203 -:10F5C000A6ED2D5A07959F8F95191D55BDE5F0AFF6 -:10F5D000A8A748BB3B5C40F9D0DC06C96D12F61702 -:10F5E0009D3193E4578D2A1A7DBB8EF91932EA05B5 -:10F5F000C1DFAB249DF2B749F81BF59F533E56BBC4 -:10F600008CAF607F2B46C9D212C47339E3F77257AF -:10F61000CA3B1CFB4D0C1B65623F91DF7561BDF25F -:10F620008A11BA42C63DBB9CF1FF2FC7DEE9453DBA -:10F63000D833FF85451DE56300721D7CA09D221F08 -:10F640006813FBE60331CE672D0F678EBF127DF284 -:10F65000D7AAC8DAB7506FB49733BDE184AB7868E6 -:10F660002A1C0DF4E6B7F272C26748A748DF7CE6B1 -:10F670004C37B424E175C243EB5AC294EFD6B4E8D8 -:10F68000345DC9F9D0853C554CF29C0FA1B09AE687 -:10F69000B3AE57B098AE4703A6272146E05C87FC7F -:10F6A00079017E5F6A18A5A479A5C8434A26BA7F66 -:10F6B0000D9697D0BC01A5C89FA2FC31D320EDF3D5 -:10F6C00079FD29D263669C20699D8FE5EBA56EC309 -:10F6D0002CB5B65F691813D3F5493E55576EED8FBB -:10F6E000F45F6585E7395A5FF4D7201D324C925F8D -:10F6F000E363FDB5492F7F2EFDDF2E25C2B8D0ACC8 -:10F7000070F473BBC89B09C3A84A8F53B6F851C3A2 -:10F71000B496C3A3B6F29AC509D32478BB0BA2C38F -:10F720002542DFE2A9D13010FAFBA2491397DA345F -:10F730007C0CDFE9F9DD49E1F597B3F22AE9F746F8 -:10F74000DC429F5AE93726C22FEC1B85F3ABFCF352 -:10F75000D29B5F20FCAAE4BA23D4CE282499F1647A -:10F76000BCE931D0091C723806A80F94B0FA77AB07 -:10F770001C08FE23708EA3704E8ECEC802A769852A -:10F7800053C0D11FDC028EEC7CCAC677F253DD6514 -:10F79000E37E3B91B0B8AFD315413BAF00F144F4E9 -:10F7A000007CB4CE7091EF05D308EE754AB71930DE -:10F7B000BC77BF85534B206959C73F6BBA0EC7FC56 -:10F7C000588AB7EF4863D3F425F999563C8EE3F590 -:10F7D0009CFC27E6E7EE35BFEFDAE6076A221C0D50 -:10F7E000F63FBF35BEC88C68A077BD5F4ACC8EAEF1 -:10F7F0009B32EEEBC0C6030FD15F7938DEE8F478B8 -:10F80000795F21E361676A32E378F993C978DE337F -:10F81000874FA73C0A787DBDE05D6783F776179137 -:10F82000DB0CF43FD3F09EAAFCF989FEA5F257D970 -:10F83000B7FC7DD6FDE5E1AF849FDE57217511C190 -:10F84000D7828BBD49534AEBB9CF1B5F055844E8BB -:10F85000B7E0D7630E5D246386F0F597D2E3CF97C8 -:10F86000740A7736FECE361F80A4AD9FFF57F3C9CA -:10F8700086D733AD874E55BF2EF9839FEEEF969610 -:10F880004312E569E9818BE93E73E90B930602E9CE -:10F89000C7D5762E18645279DCCE588A7606F63FA4 -:10F8A000F9D4EC8CDB5BA0A395185D4F84A2D42E19 -:10F8B0005A2A016DBF8AD86D4962BF54BFD8EE9DE8 -:10F8C00019A076154D97BA80DA31D52FEED726914B -:10F8D00029F82BF24721EF2FF589EF07EBD1CE5D09 -:10F8E000594EBE13D6581A64FD91EF51AC9F53C1C7 -:10F8F000BE67832BA792C063C1BBCF9D8C65D28F9F -:10F900005F96658A9F4DDCEE5A8D761751C83E7F13 -:10F91000228676B5BFC8ADDF27F56E37436676FF22 -:10F92000FA8A9F98E8D25881F61B99FFBECBEF87E1 -:10F93000AE2A5C0713868CED23CC35B0C9B1DE0747 -:10F94000D086A3EB66589A44D64CBF23BF5AD4370F -:10F95000F55AB4D74295ACBC76C985B5716B399C64 -:10F96000578BEBAE28BF66C9585A5EEC8DBE3C91F2 -:10F970008C5F4CF4679CE0A9584D48CD949E99F952 -:10F9800065FDB5DE194902C3FACBEF2CBB36039EE9 -:10F990000815299D45BEA4C12E5F9B38DE56733CD9 -:10F9A0008651C62D7ACDC7AAF6E835DF594CAFF996 -:10F9B0002B138B11CF250D10413B7B3DC15FCC320A -:10F9C000BEAFD2AEDF8A55FBBCCED47CEE02E32ABA -:10F9D0007940F6FE9DF27517C46662FD62BE8EFB2D -:10F9E0002B9352ACAAFFF93BE79B6DDE5FE5F82451 -:10F9F000E3CCCF34CEE78597E20019A7FAB31FC74F -:10FA0000DF60D793A78A77686C37705F8DA626EE84 -:10FA10009B7D303992A2FBB9DBA81FEE160E3BC4CA -:10FA2000366968D7C40132EA33B5DC9DF6A7E1FF39 -:10FA300094AB7333D145A40B5F7D2F6FBFA57E526E -:10FA40000E16FE3D87FC723E9C7F5249B707EEEFD3 -:10FA500053051C817CDBBC4EB41CCDDB4FF4C61AB5 -:10FA60006D1AD5C7D9C67B90E8D11491AF075ABC9F -:10FA700034DDD6A2418AC8D9BF1379C3FC56227F90 -:10FA800098FE88EC1731BDB72542CBEF691947F3D3 -:10FA90009B5A0C9ABFABA59EA61B5AA2F4FBBA9622 -:10FAA0001934DF83CF8FC87835946501EDAAB36729 -:10FAB000244DD463B003221504BFCBF1BB05FED5A2 -:10FAC00072EDB332FA3D67F8A87F23C8E7E987A44F -:10FAD00081FA1B0E2AB00DB2CFEB0E3EAFAF28322B -:10FAE000F39FAA957470414FB91DA85FA5A89AAC61 -:10FAF0005B44E5E65ED89A8FFC5E54CDBE07038476 -:10FB000091C877A51A52BE101D5AC5F61A6FDF3676 -:10FB10004EA6F5566B2A6DEFE48B73A193AE33605E -:10FB2000782308A777BCCAEA57B1753278FE3EA49D -:10FB300020B44D94E9FAB9BA9CC1A168767E09D681 -:10FB4000DC0768EF879561741EAB2F50370D473681 -:10FB500080CE9787937E3690AD0DAE6B0F6CDEA98D -:10FB6000CDB4D0D9AB30FBFCDCE93BA315088F4A00 -:10FB7000E49A8C5FB8D99FC47587D0434178737C71 -:10FB80006C3EE7E298048EC24590BCAF2C5D1EC867 -:10FB9000E3F3D18C5AEA9710DFB9E23957EF48C93D -:10FBA000D86E2344EE8374B94FB433ECED7CA29D40 -:10FBB0009942DC42E12A7B3BBF6807B5B6767ED12D -:10FBC0000ED61A74BC0469A7A7CB15DEAE47EE2B80 -:10FBD00035D92A674A409799DCD8E9948D7F34E07B -:10FBE00074D8674A27115FD52C2F49DEB69332AE01 -:10FBF000B3763AF951CEAD7A2660C913D245517623 -:10FC000071BFC6E9953433D36B9D1AF94539CEAF30 -:10FC10004AB5CD4FD0699D97D3D1F467A4D33A8D1F -:10FC2000D33106363A0B7AAD13F46AB4E34FD06B96 -:10FC30005D167AAD13F46ACE4CAF7559E8B54ED067 -:10FC4000ABC1DE4ED0CB490FB1EEA4E9D62C21DDFD -:10FC5000CE143D9C7AE10559A7DFE5F6A39D680F18 -:10FC6000162D50D93EA9B21350CF43697E3F76ABD3 -:10FC7000C9ED93665A7F2DFE2AFC5F28A76E96BFBA -:10FC8000267EA816EDF07C4994EFAB457F5812CB49 -:10FC900089FD7573FC382D7F528EC614DA5F1270A1 -:10FCA0003FE2C497279A848D04A40A357A6905FA3D -:10FCB0002537CB11F4DF0A783C20F004FCFCE6D4B5 -:10FCC000F81F80E10BC13B39FC94E0BC45A1F84C26 -:10FCD000323C39E124FBCB8D645F3384F3F710F3BE -:10FCE000CCC0090D6CBDE8599FB99DE482CCFD5490 -:10FCF0006E966D7C3362BDDFC637E5ABF26DE5C352 -:10FD00005A4B6C797DD1305BFD210BCEB195973686 -:10FD10008EB69597345C60CB87AFAEB3E57BF10BC5 -:10FD2000CFB72BAF2CB6F18B39A20EF76D496074AB -:10FD3000D81E1F5187FBB6FECABF7E8B6A7809FEAC -:10FD4000D542375D870805297E04BE723530DDE86F -:10FD50001F280C242F21E57ECD30A93F403300F72A -:10FD600073B216A37957D82E5F5F4301227CFAF550 -:10FD7000AD2A780BFBECDFF824FDF7372F27BF887F -:10FD8000F55D2964EBEA06B25DC2F33593E8C76D11 -:10FD9000645C97C6D67597E01FC2CFA8573455E26A -:10FDA000F27B7A72367CA31DDEB2843D3FB4CD6116 -:10FDB000079E227F7F5EF2DB1FFED641C4544E01B8 -:10FDC0007F1155E2E7D5A727FFA58D76FC9434B8BF -:10FDD0001D72E2D0E79F33FE5AC57A01D13AC44B77 -:10FDE000CE7AE64341BB2B935D21F865C3F49BFCBF -:10FDF000D6F50CACEBD4B0F43834AF64CA7FD1F88C -:10FE0000A4AB16ED8B9C8564FE65CC8EC9387F4E05 -:10FE1000EF755365BFD50EFBA2CF3F4DE71F9C5634 -:10FE2000FB700FBCA51ADDAF89BC635FD6BBBDC933 -:10FE3000F44DCC275BF524F9A954ABD135E98F20DB -:10FE40009F9DF08546422ED91F7A597AA6F76D0FED -:10FE50004C67FB12F3D59C6405E293C771AC7DF54A -:10FE60004B4984273955863BF19C79B29CAC20F9EB -:10FE70005BFDA1FB10AE6F2AB15BD50108EF9024AA -:10FE80009E1783AAE74D0B5AE6C9ED2231FF6CF6A7 -:10FE9000D192D69BEDEB194CAFB3F2E35DADCB69DC -:10FEA00039B13B5A554AAF2F8A7D9415CE4DEA178A -:10FEB000D83E12E703CEF6FF2AF6D101B57189DDEF -:10FEC0003EDACDE8008C0E2FB4EEAE3B9572611F8A -:10FED000F9036EBEAF77D82F95C43EC2F3A300B727 -:10FEE0005F2A93D45EF1552699FD5229EC19FB7ACD -:10FEF00076231AA063D3F6511FFD1B9FA4FFFEE6D5 -:10FF0000956D7DF705847D9460F611C135C69928FD -:10FF1000446DF846225FD8D7F76A5796F5FD7F8C77 -:10FF20007D94597EFBC3DF3A4830FBA81FFC4DCFC0 -:10FF300086BF7F71FB68BB0AFF9FD947D9F8E47F72 -:10FF4000B67D94A6F36763E738ED1A61479C69FBB9 -:10FF500046D827C48EA1769649EC2CB4734EC89A25 -:10FF6000EF4E32CF5B15DD877EEAB55C5E17AAD116 -:10FF7000352EBA7EEB7968676C447D3E80EB59B4D0 -:10FF800083023C3E4F8DC0B42F61FDD84697E51CDF -:10FF90004209E8793DE7365F203C103BAF522DB473 -:10FFA000CC9FE345E061972B8FD3BBF9FC289BD70F -:10FFB000E3140FA04BD4DE52751FA64FF3F58DAEA0 -:10FFC000C7D5567CB0BC52AF27511E48FBA75D0376 -:10FFD0006C78F1D9F042D621361E28CC9E336DF1D3 -:10FFE0006CFE6A4D42BF39C97622FFD2F3721D20E2 -:10FFF0000889FA11A4FF82D8B21B311E33F8EAA592 -:020000022000DC -:100000006F615C6341D74C1ADFD85A35FA401DA99D -:10001000971BD12E9FA2E3BA0AD4CFB8023BA3E725 -:10002000A110AF0DF0731C22DFBF597A9CAF9B0665 -:10003000D8ED725957853F69587679213FD2494F9B -:10004000EFF6D9E4C365956B2A9F379D9A7C4E6580 -:10005000726D927FA82FF21CFDE41A8EF304B0E4B7 -:1000600049F9879C8F8985F2B98CA7C15AAF4EF8A0 -:10007000CD552E6B181F990B5A1EF29F7FB20A297D -:10008000F4BF141E35D105DB1F5D5AB91F1D25F0C5 -:1000900072CB7E22E866F21A9ED55AB68CF47BBCEF -:1000A0009AC5DF1768E4BFD1BDE7B392CB574FBE07 -:1000B000EA3E7A6E1A27FC340CF9B84AA6F70856BD -:1000C00094333D2EEA9DE7966CF7082CFB365DAD28 -:1000D000E1F634C18F522E1B68077C5AFE503E2138 -:1000E0007FE44CB5DB05A74BAF89FC5EC5A9F2C721 -:1000F000A71D4FD0B5B75C2DE6746DF0A2DDBF2C07 -:100100003CADCF73D4DE745D4BE9EA2F072399A190 -:10011000FF5AB794317ED6B93F72DAEBCAC09A194A -:100120005BFBA25BA1D32E63FDFA162AFA5F51791D -:10013000A91A5D07BCBCBF15FA5A13D793E36833FD -:10014000107C28895129D49F500EF41C111906CF18 -:100150004D7DBA41F7E17405AA49C3E72E956DE3D9 -:10016000A9857EBB5D3DC394ACF0FB16BA291C5E2D -:100170001C0FF5B4C6CE3DD58038F774EC1F1D7644 -:10018000C3F2D2D119E30CD4CF6ABF3ADD0EEF2906 -:10019000B70BA8FADF2D7654F6762AFCDD624FAD58 -:1001A000427EB7D07F990B764B641D8E87AF8098C7 -:1001B0004EF258540CD086E978E4C3D11A5DBFB62C -:1001C0004BF47C988AB48EFFB173A2ABDC3AED4756 -:1001D000F6C6289E948001B4BE7E6AE7482706B31F -:1001E000B8A56112D8EA3FEC76D37215A2F43CFDB3 -:1001F000C46B978469BF06F9549386C3D9EF55EE53 -:10020000D8C36E6CA73178B001F5478C637E81B09E -:1002100097B53B31B3EFB8818D285F6759F23C2E1B -:100220000BDA4E2DAEEB0419B3B38AF2BF1FF7B54C -:100230009060F6D0504EB3AD8BF2E9F7ADAD7DCB0B -:10024000F9DD5CCEB770FBA81DED238BDCB7F3782E -:10025000B36D12D8EE595478587CD63B5CEEB77A21 -:100260004D1FBDAFF0DC0ADF088C7739A8447C0451 -:100270000FE5D71AF9B13EF05091B0CBDBE9C67764 -:10028000BCEACE1CDF91ADBD88EBF8B478D9C6F7D7 -:1002900031159ED971BA6F495D44E5B398F34DF1BC -:1002A0001CA076ED5013923AD6FDE82458F983FC51 -:1002B000EC433F454903190BE915930DD41F251B4A -:1002C000DC4999CABB763BB60F1F5458AC21188144 -:1002D0009935945569FBB0F2422D8ADA706E9FC150 -:1002E0002AFBBD8BD245F6FB52258E7B1261B4EF03 -:1002F00042E877B5D42BFBF4F40879083DCEFDFC39 -:10030000E9D1AE1A7ECDD2BE5C82684786FECA3D78 -:10031000CCEE285FB39EC5813504E07531DF6148BE -:1003200057231F17832D89FB16E3399BD9C0E26B36 -:100330000635826CE5E3319E1CDA8F0B0CF32C82C0 -:10034000B7A5DFBEA2EB19A4EB44B0E9B10CFA6388 -:100350008C87C88BAB90E98FF6C434967EA4D0F519 -:1003600023BC08924B08889363B1C52EA4FF1CA040 -:1003700071E8E186E6BD185F5DDC08111C86F015AA -:10038000E5AFF00C481A945FE06098F0C76036154E -:10039000188C7C81EBCF02465FC117258DF6FB36AA -:1003A000E1067BBE88DBFD45CEFB5B8E7E8A7576E3 -:1003B0000F4A5F2403DEFB83E9F6FB3661E87AF03F -:1003C00001846F7F2092427E351DE338FA572176F3 -:1003D0008587E0F389EF4FFDE559A4FE8F16D5150B -:1003E000205EB67AA3B9F45E515BE6B8B35EFC2A30 -:1003F000EC8E2CF5D37AD4B4C5353BD3651545378F -:10040000CF2270AC081A40F59A7915D5EF0A97DF1C -:10041000E78AAFF0623CE9D2C0E85CD4B37B314FED -:10042000D2A5E111346E57F4A3F0F85D918F737D7E -:10043000EA1CEF160FD3A37F07E316C4C3284F2C83 -:100440008CF376858B1E9FA9D3F3422399A1DD758A -:100450001E3FB32F75F59F56FC93055CA372087081 -:100460005AFE85599E581BF2A75947B613C8FFC3B9 -:10047000201947FA3727B8DFBDA7DE6A5ECFA47E12 -:100480004F512F9600EBBE93D45B8BF321F50C5BA1 -:10049000BD68AF7A77F17A601BD7E835EE66011F49 -:1004A00058FB8BF4EA6F2BEF8FDA833DF5F45EFD9A -:1004B000DDCFFB336CF5B45EF51E16F0D9C605FB37 -:1004C000B83DE5E7B89371AAB7593CFDBE8A2994B7 -:1004D0005FF6574CA99F45C6B9F9172EAE23AEA1BA -:1004E000EBB6E0ABBDBC5E2BF25515DEC385B64660 -:1004F000BC07CCEF09C703D3BC31CBF71EBE0A4CF7 -:10050000D3327F9F65ABAFB6F9C01843BFD3FAAD06 -:100510001F2BDCEF9D3719FD71CB0B65EE9FFB5B4D -:10052000DC50891E1BA0DAF26D61563ED2FBB7B8D3 -:1005300089778AF83D18A22B9FAEB2C877CFF89F73 -:1005400017FCFC3C230DFFFB71A3DC0A3FCB0BF82F -:1005500045DE5BCCCA47B7BD3F092F56897B00C338 -:10056000DB0A5AA9FFE20B3B3FA9D53E3F964FCF8E -:100570008FE5C5FCAADBA4C9FF5AF3CB6DB5F31F09 -:10058000CBA7E7C7F2627E356DB9A7353F673DBCA3 -:10059000AF847A7E45C5FD615C7756E0424AFA1D1C -:1005A000D7F6527C31C9DF3E40D8DB3AD5EFA3C045 -:1005B00038C73BB6FF76BFC2E037D2D61B64E7C16F -:1005C00050E1E6E7C18930FA39DFF0683C8E8EC130 -:1005D000A978EDF9A1981F90CE935FFE89EB308644 -:1005E00029B2FDA443CFF7B3AE2D2D66EBC9B2609F -:1005F00044B6AE6B220EFAB9013554FFC435A67F5E -:10060000F60EE0FAA890AC6BCC9F47EBBBB8BE5A95 -:10061000DBC2DE0B48F0FBB0F1C2D1143F09711F01 -:10062000D69C62D36FFB6AA71C40FFD5B183EC9DBB -:1006300088A7BC6CDD5BDA021DECDD032FBDD7FDA6 -:100640002CE937462AEC21F61EA63F25F61EA6BB4E -:100650005BC234FD498B4ED39D645C4C1F6D894059 -:100660008C8CBFA3651C4DEFE2FBAB0D682F92F4A1 -:10067000CB8532F55B6C6D2196B20BFDBD5E9ADECB -:10068000DBA2AD522BD0DF1BA6F963D2B4EBBC7456 -:10069000FFDA15CF25703EF1BB727A4F7C62A14A1A -:1006A000D75F50534A6E75FABBC0EB31A9AE11DB70 -:1006B0005D1096593D6F321ECA5CEF46AC372EACCA -:1006C000527820602AA1C28CF5BE87FC5513E0FD4C -:1006D00069B17830737FB7617FA303BCBF423D1E11 -:1006E000C8DC9F89FD8DD4181E20DCB5242773BD7E -:1006F000A558AF4AE3F32D4DC93999C7BD1DEBE5A8 -:10070000E727E8FD9D8BAE066A8FBA0AF5ADD46780 -:10071000C1EB25074441267C9E5F9068C67A17C6C8 -:1007200022308C8CAF872220137E7605487915DE27 -:100730002527FD9074C274528EE74258FE254B392E -:10074000B627E9F819BC7DAEBD5C8CE76A839EFBD9 -:10075000D37869DCD56ACFE7C94C3E1F6ABB6A32E1 -:10076000CA7D1E3F7FFA35E6C9B8AE4520F411AB0D -:10077000EF67E5CF88FA2156FE1ACFE7E7B379FB9A -:10078000A67869BCF0BDB78C289E55959EEFE0EF2A -:10079000559E3DCB32BF7BBF7741F1AC407A3E8363 -:1007A0006F9D78F6AC3EF63D05F572CF9B24A8B759 -:1007B000F21255547F8EF244A97D386A608D81F221 -:1007C000ACAC6270BDEB2D6B5DA252B84C7A4F930E -:1007D000C375CF3C3B5C83E6DBE1BA67BE1DAE412F -:1007E0004D7DC3F59497E9B56CF091F10DEBF85B95 -:1007F000FECD3EFE90EFDBC7DFF27DFBF8436EFBE4 -:10080000D4E3A7AC74D97CA37DFCD29BECE36FBE90 -:10081000C93E7EE9CD9F6EFCCFCA1EBFD01BFBA791 -:1008200097DBBB8AD5EE6C8ED9EC5352EF24AF67C1 -:100830002A563B3616B3D9A7A49EEAE3F6AEAD5EC0 -:10084000B4573D9F8FDBBBB6718D5EE386787F2901 -:10085000D9DA5FA4577F05BC9E295BFBD37BF517D4 -:10086000E6E31AB67A5AAF7A83057CB671C13E2E9A -:10087000F038B05B791C189577527FE1D5649F5DA5 -:1008800086FBD0A884FB7DAD0046EDC7FB26C3D90F -:10089000BB477953160EC5F55C9AB2F02C5CFFDAB3 -:1008A000F2C0B66F9BE2637E84B13E85A65A0E34D9 -:1008B00053FF9DB7B9F872CBBDD72DBC5E4F79A061 -:1008C000B9F81B96F24B78FB367E6F70B2EFB7D457 -:1008D0001ED10691FA19FC66978AFE783914463AB9 -:1008E0000D02F75D574D1B6BD5CF5B7C2E3A7F6DAC -:1008F000281FB734335C6D656CDC7B71DC007E17C0 -:10090000F6477331C5B7C652F17D4370B6F457C48C -:100910006ABB97AEEB6EBEAEE7B99B1F282370C4CF -:1009200007CB80F7229697F6EDCF696DB19F2FA880 -:100930005AD4C07D5FC91C6D348A47B67677D7CB51 -:10094000F599CE1F1AF87C5AE7D425CAC9F8B0DF4A -:10095000EEC7250C0ED6FBC857B9630DBE4C7EDC26 -:1009600056AFCDBEC92B9A960B7DCC23DE62F7E342 -:1009700012D56B64A2DB4A1F3F1F39E8B5D95B79FA -:10098000F932DD771EAF62E7066016533F610F5EF6 -:100990004BEABCD6F15738C6F3C13403D7015CA685 -:1009A000505EDCE5EC5D157F61422BD3D17FD049F1 -:1009B000CF0381DF7713FDB686A7D1FDF8717E0FD7 -:1009C000560D276A99DF91C3A7715DC5C729D9A8BC -:1009D00042AA808CED8AADF48DB5D2CDA4F74B4EF2 -:1009E000B89297D2F79ECA08FDA5DEF3BFD3C7FC25 -:1009F000C577EBD37E5B9681BEF7A0B3D8D26FC923 -:100A0000876E488DC95E3F5D8FC1D5C3B761C2AFE8 -:100A100028FF3AE75BB7F1235FA6780BA11FF839EF -:100A2000F8AC71C07FF42BFF44E671FD01177B77B2 -:100A300041DCB7E1A5D773BFE92CEE776D8068087C -:100A40000BDF05B91EE5EC5DF85D688C85FE4FFB9C -:100A5000DC0CAE3617F5778973DF6B132E9B3FECFA -:100A6000BA8DF6FC6C9856847A6BF67A17F5AF5D02 -:100A7000EFF0D33ECCE77B1D342F433B5EDCDB9EA7 -:100A8000A5818AEFF2CC7BF2DE1ABC1FB5CFC7EE90 -:100A9000EFBD4DF846B7C8DB0D81A41BEF01BCBE0E -:100AA0006BCC151300DB279795A0BECD838CEFBED2 -:100AB0007DB7CD0E5F7FF03BE10558D2271CEA766B -:100AC00029A37FABD327CE8919BDB2C57988B88B4E -:100AD000639C8F7AFC307FCEE17E18167FD15FFB5E -:100AE00013FDB49FE7ED72A3FC34A9CDF5929C3EB3 -:100AF0009FF2B862C620324FD7EEDAD420B0D56B61 -:100B0000EBBBDED12940F5657314F948D49B0FA4E3 -:100B10001ECAE59ECB4D5BBD72526F78F67ADD5CE6 -:100B2000AFFE7CC7BFBBD11FF9EE43872E43B99CF4 -:100B3000FBB4025E326EF78E20A4E83E36E9C6FDB5 -:100B4000DC0DBB948CE7B9346280F43FF7C741BA3F -:100B50005EDEB0D3939C4ADADFF093D74702C143FD -:100B6000F792A3CF0FC275F721899DAB9A5D2371D0 -:100B70005DBB4185EF4433F437C0CFF8F0F0533913 -:100B80003390CED2F6BDD7D07E3BAE74792CFA220C -:100B9000E077897ACC1FF7A044E3A37BC3C7CEC11B -:100BA0000E3F2831F876BB923E846FFB56778CC09F -:100BB000D1B4FD3DCA57937EFC4808F1D0B45BB177 -:100BC000F9899BB62B29CF489A1EC214CF57A41A75 -:100BD000C427D38FF377CDA3FEF3F91D2BDF534248 -:100BE000D8DECEDF042F9114E2F525253215F38FE0 -:100BF0003F10D209AADEEEDC1642BC927E67BA73C1 -:100C0000F11CD8EEF7C6FE3FCCEFDD1FC05137F226 -:100C10005753C70A36DEAEAFBD81FAA5C921476F6B -:100C2000E32FC5BDCF5D2EF43BCEC1B6179C927DA0 -:100C300039F791E35B4C32EEE19DEF6C3109FC8DAD -:100C4000FFF5FE96DBD00E7AD6A7A11E687AE83FA4 -:100C500042605937AFF43379EC7EF081FBEF26F236 -:100C6000D1FD470F5D3FBA9F7963884EE6DDFDD821 -:100C7000FF29D249FD05CF5C4CFD050B9E9834B091 -:100C8000AFF513F935697D978CDF3FD77793710600 -:100C900092EC1E9E3AE8F3DC2E057C04CE775FF6DC -:100CA000D07B524DE4DBC2D148AF79542F637E1123 -:100CB000C1F3FC1DCBDF534666C2B73948C64B07AC -:100CC00040C4308CF4FEC6D72FACC6D445CF579A5B -:100CD000E028D5ABCE764D07095DCFCB4EC7E3F00C -:100CE000911BE3569A76AC60E376103A867AD3F19C -:100CF0005DFC657C6F3A7ECF41C7E3D0F8233C1F93 -:100D0000845D0519CF85C5F9D9BC27BED9A7BD25F6 -:100D1000F4427F789E2331B8EAFCC6323FCAD7CE70 -:100D200087EFBFBB90D1792A414CF723C78700E1F9 -:100D300093375D47AF41FD78F4198F86EBFD0DCFFA -:100D4000BC44E5ADFB8917DD3AB5BF2120117BA37B -:100D50001B7A7E3AD1FE982FB14C537B30E509A522 -:100D6000E9353F7979BD1EA2DF0FD1EF492607F3A0 -:100D7000937BA74B19E8F7AC9FDDE786E4008A97E1 -:100D800079ED7F72D373700B5DA57148CF4353F03B -:100D90007B367A8AF96B38FFF32D746D67F29B4DC1 -:100DA0004EBBB77A548C6B70D2B9DBC5F6094D498E -:100DB000E9A54C7417EBE0E99EAB3EE5946F3EEF7E -:100DC000FEE4BBFFF99C1EBEB6FB751BDF08BC1D15 -:100DD000FE28B3DE3FE897381CCDF525C37BAF83F3 -:100DE0002A44CD416569780FD3B7C948FA9042DFEC -:100DF0003B5DD6F11CD5DF4E3D313F8B9DFD37AEBF -:100E00009FE6EFDE3B12F5D9E17D4F517E9CBFE3BB -:100E1000901BF737CF6F7FDCDD5595E67F5C17AC15 -:100E2000EF5B1C7E74EF48AABFB1FF0CF439C6FB20 -:100E30006FDA63EFBF69C77BB6FEE79A1D6EEA5FA4 -:100E4000ED679CB755E34A9CEFDB9D2EC07793DEA0 -:100E5000EE50EA33D9412FF175B127AE2658F3325F -:100E6000FA27957CB78EFAAF75B1F112BE9B68BEBA -:100E7000E862EF56AAC6CB1E229FF13CB78EFBDE7E -:100E8000D6E015A05BF478C2814FAD50ABC5FD80B4 -:100E900036395A6DDD7F09F8F30CD906FF8260FD03 -:100EA000407CEF0AF7713ABE53A14698FF3A34A549 -:100EB0009EDE7BD464CD9771DD66FDA1DF0EF9DF88 -:100EC000A5C9A05BF86BD4A42BCE45979D0ABA6D3B -:100ED0003FB066323B0F16F35F33183603D1C36B56 -:100EE000A4A307F09D08F352166728EC3BE0FBFE35 -:100EF00010EEFBCB7ADB7B60183AEA23AA8E7436BD -:100F0000BE61B9E79C8EE3055D56309E39423701DC -:100F10002AC468108617E36C87E3BEAB83A601A2E0 -:100F2000DE309D98338CF1371CA5F9B5F57FA171A2 -:100F30008F8539D1513903309F2FB179A4E83E4FC5 -:100F40005CE397734A8BFBD20730593D6CF52779E8 -:100F50006033DDCFA03BF364411A2F22DE4EF4BB99 -:100F6000C63751C2F508E73908DF69C3478E2CEF51 -:100F70007088F8C90122EF18076B6A357C09A6A2B0 -:100F800019935CC3F17C3F21E1FC4AA083A6A5D064 -:100F900049D37CAF26A914BE57A9BF4B86BFC0C991 -:100FA0001C077CA760C73BEDEF5B15FD9518A1639F -:100FB0009CEF73EECBB3C7237D3B87E9991B73642A -:100FC00011FF1CB3EEDBE2D04871E02B64CF93F548 -:100FD000C8414EECDA1C0B9F29814E165FE6D82FD4 -:100FE0005FAC2CA2E7FBCBC37DC7752DC5F8F0B372 -:100FF000B297270678676E050A3FF383495E16E7C6 -:101000006D80AE59F91163796AAC719386ED3D1D1F -:1010100017F2A182783669EA43B922690EF215A166 -:10102000C34ACE8741E8E29D1CA5FE8F2DEE581CD9 -:10103000F97060794C62C1445189F9D50CC5CA0771 -:1010400072CED5C57DC56DC174C22796B899FB38DF -:101050005D541554FF68846733A7BF933FED71B0AB -:10106000C2AE0BF09C87C7E3FDACFA77F4FD17B571 -:101070003040E35F02D5AD37E2FBAD2A346BA857B1 -:101080000322BE25C2E216C5BEDA57698F17F538AE -:10109000E2635D7CFFDE2B5E9CAFC777E0870C765A -:1010A000B3733D7E3827739C138CCB1C9728ECB40C -:1010B0004FCAFF62FFD9E8ED7C9E02A11934AE53FE -:1010C000E57E8BDAE91AF5B71FD921B1F7361CFC9A -:1010D000746467EE48D49728CFF87E790EFF2EED22 -:1010E000D8BB17EDABD6101879F954FFE90AC1FF48 -:1010F0003269945722E9BC5DEFFDE669F4E3EF51F4 -:1011000000DF753B42E6D889F3548D3C245A0EAC7F -:10111000B2D1F993CEABF7392693BF9B34217F012F -:10112000DAEED80E89BDF303E7DE85EF5D351D707D -:101130004192941F03D6EFB1CDCC6EB8EE178FD786 -:101140001049808D1C1E5CBFACEB4C41BD1F740B65 -:101150009F84C5BA601A9DF8DE7303C7CF8068BE4E -:10116000AD9E98DF3BB3EA0F50FF4F8CBDFF3C7044 -:101170004689AD7FE0FE119DFC43BEECE5679063C0 -:101180006EA0EB4A343745ED20B29FC6FD47528A28 -:1011900020DC4E7FCAFCDD125DCFAE27EB19BEC747 -:1011A000767DD2B11F75C45309FC3BF9560E703BD6 -:1011B0003200812C788EA4AAE9F92C95BB9B7EA1E4 -:1011C000507BECA647A4248DA7EE3A2B1728DE15FA -:1011D000EA977A039AEF242B4C9ABF1DF8F384ED1B -:1011E00078F7E976BCE754DAF11B8CD8F1E8C473E0 -:1011F000EEB861B6FA73954637653E8EEF4AF20F48 -:10120000F14DF4249DC77C328F94DE1B9F73F6ACA6 -:101210005986FE927EF1E8C0DF390EFC1D873D7BCA -:10122000592944BD4596F84F3545E5CA2987024FEF -:10123000A55A672DFD1609523F7598772235B0766D -:1012400025DE0E2654A323540E459C724ECFBAFAC7 -:101250003A9C24E9CD97EF3F340BB2CB5D478B37F7 -:10126000D2E0C2F371883454E079B946D3CD58FF47 -:10127000BCBED65B838EE7828886E91DFCDCE44831 -:10128000157B17A923F54111DA7F778C3E7A19DA9D -:10129000FD4DD74294BECB1464EBEF2E9E4E0EB2A2 -:1012A00038EBDBA33218E82FD8A32425F44369C612 -:1012B0002F2E42BB6D8F4BA7EB9F76F437FF8B969B -:1012C0008FD1F01CA3584E8CC271497DEAEF3FB21A -:1012D000E7F5D0772DF651F7EE7567E3FAB4498656 -:1012E0003999F6010D01367E77E55F8A902DE77911 -:1012F0008FD27DF9F22EBB9FCDBD8BF9E1E6EFBE1B -:101300009CDAA3FB67B3F7389F38CCEEA54E51AEFD -:10131000FEEA97487EFC7FF0778CC0983AB38885C8 -:1013200072203DE33E826782C7F53C7EB3E9AF326F -:101330008DDF1C7F214828AFE3FF08111351DB3CF0 -:101340009BAE574F87A61CC074F21E89FA8F9A0E67 -:10135000B3F56D6CA7DD4F74FE64A21748FF357BB3 -:10136000987FABA68B9D0F9CFFB2BDDEF82E7B7ED7 -:10137000423FFCBB24C0D7AD10149D4E7CEE1E979F -:10138000B122C0CED3E8BDB2889A79FFD515647674 -:1013900018C1079DFF91A3105942E671A4A1A4169C -:1013A000EF291DF9809D371CF948A9CFB4BFDA1287 -:1013B00060FCB2C9CDCE8F37CD0E24179379EC9B4C -:1013C0007DC350DC57FDE3DF6243B5BEEC12A222C1 -:1013D00064BA261AB9300EE5A395DD77834471A669 -:1013E000F793855C083911F2513CDB1FCBE4171DE4 -:1013F0001664FBBFBAD99512C66F773F2BD133A6BF -:10140000EE2504AE3EF068C29241084FD3EEF7A934 -:101410009FC2BB27B3BFFBD94088CEBF7B89B978B9 -:1014200002C1D7F788709B280FEE4459A6FE4D588D -:101430004FFD57DB028C9FBBBD6C1F0E6AA218DFED -:101440008DE8DE3DE9D26504CEBB89FCE1FABDC979 -:1014500015A1709BF380BEFF07FC7E61E965B0F5C6 -:1014600076CB7EED40A0F620D2FB6080C51F15C470 -:101470002212C21DF9F84408FB3FF2A187D2AF84C3 -:10148000FB8B44BB23017E0E17347E43F9654E214E -:10149000558A915828D23006E0BCDD04DF16FD9D48 -:1014A000A69B49C7C98F01BD479F1F90D97918D9FD -:1014B000A7E1FEA309C48F49F72B42FEF0D29B6A35 -:1014C00089BB97F648A920D19FD5DE400AFD32F9A5 -:1014D00073647C8387D8A35ED65FA7DD6E450D8CD1 -:1014E000FA177500D03CDB1F097D2CF4786B1ED3F6 -:1014F0007FAD6B54AA1F37AB5D3EF44B97197A9DB5 -:101500004AC6CD57751A6F31780E93F79CE1F7E60E -:10151000F5D84513001EFB58C9E81F392B28F015D4 -:10152000FB07E26BE481A3FBD0BC8AF8A000E93D95 -:1015300085DB3DE3DF65FA48DC3368EAB94760D70D -:10154000479B7CDC8E81C4EFF1DCFEA9BFAAF4FED0 -:10155000408FFE993D85AEA7A0543D87FC35E157ED -:101560007C7BC0F50FD9ED51BC9CFF422C8E7038AE -:10157000F5CD38207A49EA5FEF38E94C8CF09E7C53 -:101580002941CA980344CE2CED9D7A6A6090AFB38E -:101590005C4F1D8789032FD6D3FC347A61E4398FE1 -:1015A000857F849E4AF35392E2D5398E04DE9EBC39 -:1015B000361CF5CB0B0AFA518ED4B2BFF393E2720C -:1015C00094F741F252E487F57B2EF121DFEF3C30B6 -:1015D000C98B62755398DD3B53F74E3781B38FF556 -:1015E0005CD9055E3D5089F890291E148DE42DE3E9 -:1015F0001F4B48FCDEA59E3B3DC3FBD822BD29CC3A -:10160000EE95ED3C302C97ED475394EE3D7CCFFDAD -:1016100017422E04BF3BF95BC8439CB4922D7684DD -:101620002275F0FDA3DD8F10E776445CBC3F6316A6 -:1016300053FB7001B70FE381112BF1CF1CB4A6EA65 -:10164000343CF758101C46E3AB170C60F873E243C8 -:10165000A44D1F127BD11207DFA41EA5FEB1A60F59 -:10166000DDB6EF02BFD9F022F07B01E257FAE4F8D1 -:101670003D3FC8E8ECC4F3A79D7FE94DE332DEE7C8 -:10168000FB5799FF04883DDD45FDB1EC3E89E0370D -:10169000A13F6A6E6E8BE7E8697D21EE8308BD236A -:1016A000F4CBF98D89E77232E80FA7DE88B8B4EF82 -:1016B000AE22F88BFC2C40DFEB70EA910FF09762C2 -:1016C000EA77BB2748E07DECF9B765F49B3CF15322 -:1016D0003277521ED93B99F9053B4FEDBC4BD8AD43 -:1016E000C25E75D613F6AA5877C479D3AF83B18793 -:1016F000707C693791A710C6C7B27DF28140EC11AA -:10170000FC9E4360F6632C6065AA8CED67EDF29A4F -:101710004D3E731CF2D79152D93B3201F62E9413F1 -:101720000E317E4390BF2B40B80EED9AD21A6083E3 -:10173000CD67EF06948E8418AECF78BD14E7F92BF1 -:101740006E97BDC0D71B911E0844F723FC2E154C85 -:10175000CFE84F0EB7F02FFE3A68ECC3FEBCF5069B -:101760009DC7200D2268EF0F523BA4088123BF5173 -:10177000977A9C3D625D27FD0D9AAAD7A21C0DC2E7 -:101780003B05581FEDA30CF4F97390C535CDF376E6 -:101790003D8F267CD3D4E6FA501FE7EBE9F7102201 -:1017A000DCCF658F0339F2CC4B83F1FCF3B51FBC62 -:1017B0001FC473ADFF548F0611CE3717FD3E88F757 -:1017C000215E5BC4F61FD738EC9CE31C7FD343D16A -:1017D000C341927EA7E5E31ADB3B240BD9F9CCF594 -:1017E000490537A53DFC3E777B0EF5ED89FCBC8EA7 -:1017F000025B5EF0E93C0F8BDB72CEBF2AC4E2686D -:10180000AEDFB1D53D48C7F163FF85E3BFC9EDB891 -:10181000377705A9FF43C0336BC72837E2E13FF7AD -:1018200078F8B97FA78BE1DF988AE773314E0A27F2 -:101830009CCF3F9B43FBBB768342ED8E9964AC8586 -:1018400084BF637BAEA7FB70E73CAE7D4D9F3290BB -:10185000D0EFDA1512B557B1FE22C20FB185CBE930 -:10186000399E739E334D47FC08B72B9C7126D7EDEC -:1018700061E7EF0DA0AF9C589621EE64CFA5F4DC94 -:10188000EDBA7EF63D65216E4FD4C0F918377F1C46 -:10189000AA7E58A5F7BFEF79B3056810D9DB2D5E96 -:1018A0009A1E6ED158CAF5E7DCDD7B9FA77CA67631 -:1018B000D6A0DCEF3CF07ACEB7F4B41EFFF2D6F738 -:1018C0009FBB87E4C700F3F3087FFBD51CEF1771BC -:1018D0007D7E1DB717C67CD8B73EBF1AF131B2372F -:1018E000BC428F5F8D7F6FD08207A1D79DF838767D -:1018F00060780EF2C7E490F3BCF9D3E1255BBB79C5 -:101900004AE67846214787838CAF1BDA2F5F564221 -:10191000C68F3FF3C6902EA6270EA29E107C0AD03B -:10192000EC463976F2A3E0931EBEDBB39AE249F0AF -:101930000791AB303FE70CE3FED0C97FFDC537759B -:10194000BBBA86A05E70F259B7E35EB448AF083107 -:10195000FF7B836E4CC1FD2A596E96B1F340A68F72 -:10196000DE5413CFDF86F2DACEE465DE938FFC041B -:10197000F5D00D3FDE10423DF4969A28C2F11AB719 -:101980002D0DE1B9FA9BAA19C2F66F25958CF18F3E -:101990003B4292784FC31627016DE66528C7FFD8F2 -:1019A000E6D2F01CAC69BB879DBBEF6278237976E9 -:1019B000DEBE2B739CC40D0F6C28D259DCAD3D5E8E -:1019C000A2DD45FD17E85FC361B29D17F79C3F7725 -:1019D000F47D9EDEB48BC7D9ECBA3463BC84884BEB -:1019E00070F2F16607FF12FC50BF9F49E0A2EE764D -:1019F0007E4E1E7FF0AE9187087C87DB7F1592AA12 -:101A0000ACFE78761E7FACE3BB3FF2CAD9F9B79B38 -:101A1000F37BDA9E48668C9F6874A542B8AF6ADC97 -:101A2000EAA2FBC0C64714FA5E1DFCD143D7F3B946 -:101A30008FFCEC0F1710F8E63EE62A9CCAA641E39D -:101A40002404BD7AE258387D6E78FC67EC7C59E757 -:101A5000F12C9C4E731FDBEBC6B81C273E2775ECA0 -:101A6000757739E22028BD3A0E4DA1F7091F3CE1F8 -:101A7000C675F6AD67251858D6BBFD9CAD3F0BA1CA -:101A8000BE403CD138004EB7EC714BA9CB7E5A4DCD -:101A9000EB51BF5D7F745C84B23896F2FBA33F25A7 -:101AA00070CC79C543E3A7E63C7A338D337A436D36 -:101AB000667C7FEFD2225C7FE7B8CC228DA6ECFB60 -:101AC0009C2DB7507EBCEEC55B8AF87DA462E6EF24 -:101AD000318B719ED76EFE269DE76C88517E9C737C -:101AE000AF12453FCB7115EA1FCB2037237299DC2B -:101AF000BC719F071FD38137B89FD3FC9DC2FF5E87 -:101B0000A4F3BC8ABD1B739CEFBFFF19EA396FF4C5 -:101B10005AF7634DEDCB3B914E6F0F36066A349EFC -:101B2000403539DEE8FBEBCA8B170FE4FA8DBE7740 -:101B300023ECA049F81DEB77BAE8BB379676B67769 -:101B40006B16F0F109DC7EE93C921665F6837E3374 -:101B5000571271F02CFE46F059363DD0CEE2593E78 -:101B600038C8F40CC6E5D0F24E576AA02D1EC763E4 -:101B70007B17251D67E2E2726E2F2770D278991EBF -:101B8000FC3E2B25F11D64C12FB3D77BECF1793DD1 -:101B9000FCE37CB7C71E3F739DC32E1369AFF53FAF -:101BA000D7715EB7F9D4E2671A5D491AFFD4F847D6 -:101BB0000FDD9F343EE28A225EDED9F1DC1FBE4596 -:101BC000F8FE9D0E21C776BDEB94E3393BC7422654 -:101BD000397E2710818C724CBE6794E340FA5C43D7 -:101BE0008733AF77AFCBA277BFEAC027B11B723183 -:101BF0008EF8ED87E60EA5FE0A077E85BE75EAD152 -:101C0000D7433AC573EF783FB6EEA7E331191E0507 -:101C10007FDEF0F03C3A4E0F1F0B3E157C9C256E8C -:101C2000CC894F67792EFACEC6F6F68B9875508917 -:101C30007FA729EE06F6DE9BEC8F20FFF677DEF914 -:101C4000DBDC32F1FEDB796C5FC8CE3B23010DFF9C -:101C50006205DE9753329DB34726C919EDFF1FE495 -:101C6000323B09DDB2983E99CBF0D7AA44B923AFF5 -:101C700083DE63A067AB08675E88CA998BC7A990AB -:101C80009EE97DF4488EFCBE4EFAB8FB87FB2F51CF -:101C9000D13F3B46BE7938C9EFFCE1CB97A884DE43 -:101CA0009109F2E3C3487ED70FFFC8CACF93C7B8E4 -:101CB00008AB6E375FB96432C9CFE7F39E2FFC24BF -:101CC000AD636D7E12553E74279EE7A83F657F8FFA -:101CD0006825917BEFE8F439738E074C1FC9E7B88C -:101CE000494AF2CBCA7EBF0C3791BFF2C736E652E3 -:101CF0007CD5E988E7C39A97C6EF2C78EA621A4741 -:101D0000FA642EF3479FFBF804FA771DCF201C0FCF -:101D1000E60EC80E47AB8BF57378E7B99310CFE7A3 -:101D20000E459F5A9A1EA3559D7EF711B49BCCEE8B -:101D30000FE3FD96789E9BF6F324E7B3534D45DC05 -:101D40008B92C3F842C9959B1F23E9B39C1FFE7772 -:101D5000AE26D621BAEF3EF2CCC0FBD8BB314787C6 -:101D600020BD15E5D89FD1DE3CFAED1CFA774B5E1D -:101D7000F133BCBDE26778BB327795EB1CF27DB4E2 -:101D800077C8CDC8F4AF483B6EC174AB16FB25A332 -:101D900007A4B0DF6F5DA3B07E03CD417C374E3228 -:101DA000981D2E1166BA9AE0236E80EE1E8E226C6C -:101DB0008FFF5094D1475374FCA06D7C2825EB26EF -:101DC00091F32BC7337A11DCD275F4A5712C2FE077 -:101DD0009B911C16EFD2293C7F4278467992837101 -:101DE0003FF52D625631BEB7EFEBBBFDEC7CB31B6C -:101DF000DB8F4CC70F34FD4DA6FBD9269C03C93F92 -:101E00007E18F8DF2B64EFEB08BFC7F85FDF44FDF7 -:101E1000DFD5BBE7B23813EEEF12E7F935FBD9F99E -:101E20009CD3BF350156517D3ADEA14727ECFE2AEF -:101E3000D5AFFD9DCFFD43E8D5122839CDF3B98F3D -:101E4000734FE17CEEBF013359118B00800000001D -:101E50001F8B080000000000000BB55A0974545590 -:101E60009AFE5FBDDA92AA54AA2A450804E34B02FF -:101E700024210B45122004D42220D0314A8016811F -:101E8000F64881B298AD98B4DB699D438520D2DADB -:101E9000A319756CCE69BAE785D61125E92924D135 -:101EA000E05432C52204254E9045A01D3BED74231D -:101EB000DA64313D824BF761FEFFDEFBA82541E984 -:101EC0003E67C8E1DCBAEFDD77DF7FBFFFFBB77BA2 -:101ED000DFBA4409600CD03F1D2403D49BF1970264 -:101EE000307C3C2311F200F47A00D9096054642854 -:101EF000C1F62AFDBB0DA06D338E3385FB6F252AFD -:101F00006C9EFC53F6FBC1462DAC86828879ED7C35 -:101F1000DEDB652B4031CE7F1154533AC0B4BEECAA -:101F20009FCFC1BEA1DB002ABD979EA0FB6775AA0B -:101F30001F459B71ECD74521BCB435CE560053F1FB -:101F400095293A50CC6C5EB88AFFE3947850B2C3BE -:101F50007D4BB633AA2FC7DB764122FEF07B7A5346 -:101F6000508E227E0B12DCE3A3E679DBB6A89BE45D -:101F70002EB2AFAF20B9134B32A2E681E3FA4FFA8B -:101F8000B09F8D7F573300A643656208E52F844AD2 -:101F90008F84F2BA3F027708E59F718A8FD39E73D0 -:101FA00087FCB217712CF928FA7A2944F4719EC77C -:101FB0003EFAC27138429EE9F604D7050BFE180FAF -:101FC000E3AFCAA3E2E80E114EA76437AA01EA8F75 -:101FD000E12017B69F810A88DB3428480486AB0CC1 -:101FE0002AF6DF04EF0B73B0BDB279C871785218CE -:101FF0004F87271ACFA445D1788EA98CC673EC8A57 -:1020000068DCC679A3714ADD3825EAFE4D9B0AA338 -:10201000FA373F561A353EDD5F16D5CFDC5E1E35EA -:102020007E52D3D2A87ED68E5551E373D4B551F7E4 -:10203000737757DD90FEF303F551E362F53FB5E3A7 -:102040002751F396CAF7CA9011E6811FFF880785CA -:10205000A462D23FEA210423F53FD3E527C6FFCD92 -:10206000FA7F98F49F1BA17FF9DE44AF356C6FB106 -:10207000ADA6D79FD05AC7905E714E14EE0AE919EB -:10208000AF0D1AACDB256C1DC89D7BF1FA63667E33 -:10209000FD5181CF95B83495D6EF081EFD5AC21672 -:1020A000D5C2ECD0FFB1456D44DE3C2A2B0DC4AB4C -:1020B00017E54A09509E54549D2E1379A4838D012F -:1020C000E4F7B33ADDEACA08F99EB373BFF29C5D48 -:1020D000C7DA5F18D156F1BDA916F09B0BD973B4BE -:1020E00036FAE7015CB72D8981822F2CDF3E7F0E07 -:1020F000DE77F4652B0E0033F56F01381FCFE53D19 -:102100001FCFE55C65521AFBC87FC8EA2492A7D9A5 -:10211000EEDD69C7F79C979E30E09BC1E0F21BC8DB -:10212000EE52CDE0B7E1FB1A0DB0BA12FB0E7049CA -:10213000F5D826C24E3BE18B622857911487AA72CC -:1021400013FBF0FAFB24D138B231B70E6600ACD4E1 -:10215000FCE1C61CE60F87718DBDA450BD9208D866 -:102160000E3F90C9AE9FBB0FAD10EDE99C91E3A16E -:10217000E17051F8C9CF379B597B69B33DCA6F6E87 -:102180006C7E2141C179CE65C3A240047E5D84DFAF -:10219000746A6586DF80FAC764826770DDB7934929 -:1021A000689FD4BBCD8A439EDAF10F95807A30B612 -:1021B0002DF1A34E60A55161E3B5797CC1B94038DA -:1021C0001063E9FA3D1FC22692EF9E6FB18D785FD2 -:1021D0008FDDC0DED743EFC376393676C46D39EA7A -:1021E000C541EDD1390BC82EF07A48C2FEE26E30FF -:1021F000903D2CF1A61B489E93E03EDD8EF29CB5EF -:102200002BECF91F42A581E43A735F6D028DBB365A -:102210009F360F0AEBC078F2A1C36F4846BF3574F2 -:102220008BE4DEA5B0F799E97AE5BDA94F5A95F0A0 -:10223000FBCE80B7FF34EA7B29B8D9BCDAFC6879D9 -:10224000517EF18D8DD5BF4BCA207FA80333F9C3D2 -:102250004E13F3878355575A5FC2FBAB53FB6E3265 -:10226000E273E7ABBE9D4CB8ACDC218382FAFF245D -:10227000C1FB07FBF4301EE71EF87302DD5F6552F9 -:102280005F7909ED00F698DCAF003DB7873DA78D7B -:102290001BB0CFFD8C78072508D4ACEBDBA786FFFD -:1022A000BCD773C612CF347E3D28F855FF5AD65896 -:1022B000E2537DC2357EF1FE2B9963895F3324CED4 -:1022C000CBD879BB905F4A16AE1B79A520AFBABEBA -:1022D0002A4B223FB1EFB8B388E4D483F76AE4BA5B -:1022E000F6BDBF2A97EEC359D70DC94BB6E947399A -:1022F000EF012E678FB08F15C1A422D23BDA9DC5A6 -:1023000081E356FDC76BFDBF257C3AF7BCF2388DE3 -:1023100029BE313C34FFB4379EC7231071CE2D70D7 -:10232000C13897AD47510721DE4DF9C2F5FCD65EA5 -:10233000F20BC8AB2B3A747C99E4AF2A81FC82057E -:10234000DC0AB5E865DE9B8D7A6C3CA083A7B16B97 -:1023500023A7A6F99F12ECCB3AEE7FB06F4EC1389F -:1023600022FCD324C7BF2EDACAECC7635D3383B91E -:10237000442657F1E1AA0A7A2FF4A21F47592BF1FC -:102380008FE2C16CD874280EE59CB103F3031C37AF -:10239000F32CBFAFF9F55921DD1A63228DFBD91754 -:1023A000B28D208A8E03B30F977F4AF3CE8688E7DB -:1023B00046890FB31C7F5F7C98EFE0FE2190CDFD36 -:1023C0007B2014AFFAD3D9B44595F9C817278F1FCE -:1023D0002D8839D9B1511AC836A31F5EE468DEBE14 -:1023E0007D02D26122C785FA8DF45B29623CBE96DC -:1023F000371E9EC2FC21FC05A522BCEC42E61879E2 -:102400008AD1EE78307647E59DA123DFD8FA701D9A -:10241000AD4EE5BF485F4398D7905F88D3F7191D4D -:10242000A3ACEF4DF2AFC8FFE71C3A26AFB943F2B9 -:10243000A8F87EB3E20109D71067B74F93A5F0F86B -:1024400032078F4BB547CEA719515FFDBAE3B63CB3 -:102450009CBFA6FD0D1B2E1F7E6CF3AE73E03CD51A -:10246000E73E9841A10B199E569940386524923D4C -:10247000E5EBC1AF2F1C29876F072E06295FB72315 -:1024800089B5391D125B9F2FC4D739D0D1E88CF4A0 -:102490001BD79EFBCFCEF1A4B73D636005F9E3FCEB -:1024A00060D106E231C962405DBCFE552E9BEF094A -:1024B000473ACFAFF5A0A7EB00AA6E290EDA63C0AA -:1024C000E770DE81AF64364E9B37BF63AE6C471E4C -:1024D000E5859A0E525E18173429A4E7B89781E370 -:1024E000128C637ED1D7B510287F1D74805BC2FB30 -:1024F000ADF1431F132F863A4DCA2E89F06B022788 -:10250000CEDF6AE4F133070DE10D6BF8BAF6BEB821 -:10251000E0CF81FC15F2C3A3D27D7D13DC628DC4B4 -:102520003D81C9FF4B07E7576B7C486725BF8F9CF0 -:10253000DCC5E40ACB09ECBD9A9C39AC0E68350EBB -:102540005D78DCC5E4B2131F7280CB09C12CE515A0 -:102550007ADEEE61EB88B32B6EBF34522E5F01E65C -:10256000C56877CF6E816B764E76EF8B0FF7CD68AF -:1025700013AD1920FCC229968784FBE8B04AC2CF6C -:10258000BFF1CF67B66F9DC3EA23BF8C7CB0609B61 -:10259000E0A47572FBC2B2C933A690E3E0469C2C5E -:1025A000667EFFDA78E4BB95FA563ECE9D68B79416 -:1025B0004BCC6E80ECA64EF89987A4D085DB50B545 -:1025C0005F860E1628284BCDD1B7196FAB75C19712 -:1025D000F2F17E59BC3748FEF7AD8F7460C3F57FCA -:1025E000FE5A9C5A817864EF6F4EF65847CEF7D466 -:1025F000D92DCFA792BEF74B0A228D79E1501AC987 -:102600005717FCD4E8C17661C7EF8D149F5639BDCA -:1026100047C80E4A3A1AE6117EB3A0A9D16E657E6C -:10262000D14B3C0DA470FF317C6AF2AE8608BC2F02 -:102630003978DE0243DE9BC96E82C23EBB28FFC1F1 -:10264000B65DE461ED0756662AF9E1E7FC703015E6 -:1026500070CE2D70389570D6AE0FAAFA45C4A7DC9F -:1026600033E6D59E08BE5D10F67E41BCEF1F9DDEB1 -:102670008F0887EA039F186DB82EDF1F0269149F29 -:102680000298A7D9BFC32FFA62ECC6A71F32D2782F -:10269000DF45607E04F5BA3511F5B4E74CC79435D3 -:1026A00056263F24E2BADBCF9998DF6C4FE7F6D786 -:1026B00070FA7201F9ADCB9DD537135EEF3B0C1A62 -:1026C000CFCBE2C99EF602F3639A3DE6913DA2E8C4 -:1026D00079C4F362EAE7B0F95A8DBDE5CCFEDA754C -:1026E00040F6873C67BC479EDB29FFC8B323EFD980 -:1026F000F359CC9E5B7B31E061DF8F7E7C12EB97E0 -:102700002DA37E6BEF7C3BB3671D425B4876193A85 -:10271000C8E609604C23D549501999A796396C4CE5 -:102720005ECD3F563AB8FF0F642B896E5C8F45969D -:10273000A3EC20225EF2BE88A72B9F37FCF4C509CC -:10274000644D222E88BCAC4BE4C1E02D62FEFEC776 -:102750002296D5BF53BAB805D75BDF2373FF2F7816 -:102760007250E4C98737A7B03EC50B05F5341D5B31 -:102770000FFAD3199E4DF3D0C6A06451D3216A4BF2 -:102780002B03F3107198B3A2F790819B732EF1AFD6 -:10279000EDE00F72F5C4F77326884311DBBE19FA1A -:1027A000F875C4E1912EC47F94B884CB61FC4304D6 -:1027B000181FAFC79B41A9EFAED96E4CF99F1FFB05 -:1027C000037D1CDA0F1103F1C87B7ECC4FFD28502E -:1027D000BBD333D58938FE36C93BD589380E9EF830 -:1027E00026997C7AFBA94F6CE4EFDB8C9E5CE25966 -:1027F0005B06D60BA3F0738293F3A7D8149DA76B47 -:10280000ED5227E7FF643F3C43FCA96B93ED2AEAB6 -:10281000BBBF4DF618318FBAE0F126EB11D28BE039 -:102820005F3E9BE2BBA87FD771D8611DE52F18677B -:10283000D6BF6888AA4B6BC4BE4616F46D4B459C48 -:102840007C2F4BACAEDD18938FD450FE5240F54533 -:10285000B391D653F572CC3C94C714D0B8EFAE7395 -:10286000973AC53E472664521E833C62F5F4D06910 -:10287000D9BD8B62A01EBA4DC8DF3D3A8E13FA4D0A -:10288000668F5A3E637279E691DDCFD3E28AA85B08 -:10289000875A2595D9CF6EF4F3D82FBDA83403C736 -:1028A000E154CA0C5A0FE765A99E8F2F0DA633FB82 -:1028B0002BF1603D8FEB5E8FF5BC4AEBD6F23CD539 -:1028C000C0D68FE197E579B3406DB4E1B80DBB2573 -:1028D000B6EF53BDDB1095E7F9043E353B4E1CA126 -:1028E00072B23610735FE0E38BC1E70DFA316B24EF -:1028F0004E8F3A45BE97066991F91E743B47AD0B62 -:10290000347CB43CFB4F069E5F7C20E6D7C6FD8B33 -:1029100093D7E7751E60FB4735AAACAA3C1FB4AE3F -:1029200041BEDC2FF872BFE08B0FF8B8DADD921AE7 -:10293000A278F533AE7733FE112EEB026B16A42A84 -:1029400023795525F0D8D86260F92FC02623D9E71E -:10295000C69D31E3042E5531B8D479A518F9783ED7 -:10296000FEB7CA576DE0FB35D5C82FBFF2FF276F02 -:10297000ACFEFE5DD3DF149812A5BF454937A4BF56 -:10298000D83C79EF9129167A7EB83B83ED4368BC39 -:10299000899D6781C8B317EEE0F9687FC73C4B3E5D -:1029A000D553C7F56E09E729EAF95F5B3EE251D8D6 -:1029B0002943054E31182C7AC68FEBDCD73D71992F -:1029C00082F1A1B047CFE24B514FA14A754D614F03 -:1029D000A1253381194F12D50B380F8BCF83C72711 -:1029E0009ECC233FDB3DBF98606F385E68A13C62A0 -:1029F0001FF07D0DA9A738A92F22DE743BF9BEC6B2 -:102A0000B694FF7996F2FC857B0D6ECA47161A863E -:102A1000DE9FEDA2F7EBDD0DD8AFE959BB258EF4B3 -:102A2000FE9AE4A674FC486FBDEB47A4DFA0C16E1C -:102A300062F23E7C90EEFB5B24F7241CEFEBBC3D86 -:102A4000B715FB85CD456E82597B5FA14379A18285 -:102A5000F2C5711656C72FBCC9C0E2EEA5F1965F4C -:102A600053BE54E5695E40FEF8D2DBFB8CE40F06F2 -:102A70005B2548C1851C4939F41B3FAEF3D29B2727 -:102A80008C9494CF6B3B61ECFB8E7CA25F9521C450 -:102A9000EAF72623D541B5CD5ABFCF487AAA14F913 -:102AA00055DDCBBF67FD2AAA13F07D553B6555C1A7 -:102AB0009F873ADF3212DE752D128C4D8FB8FFB230 -:102AC000C4EE6BBC5F0B9C076B857FAA16FB90D591 -:102AD000B40F89D7613BF7371AEF1FD8BDE40885DB -:102AE000EF754DD17EE841C1F30D5497B2FADB6B1F -:102AF00024BD6ED811334EF0FCC1EFE1B93549F871 -:102B0000F31CC8219E5F9ECBE3C9E513F1963C5CA4 -:102B1000D7E563B21BE03BF9CEE2EF71912F0C8752 -:102B2000742C9E69E3063AFECCE28DEFF8B091F288 -:102B3000DB05C12F983E2A8207E613DE7782B7862F -:102B4000F0BB3368B193FD57F4717F501E34A9B4C4 -:102B50000F7E2704B6929E07BB5EDDEA24DEFC1BD7 -:102B6000E70D087FB741E0BA41E0BA011D7E12BA15 -:102B7000D8AABC032F61BA0FE5C0FD507940F8A177 -:102B80009DD13863E4B98FF4551734C1D378FF0E63 -:102B9000E18FEE68E1FE28364ED6897D80C171B99D -:102BA0008BD97E2BD6BB94C7D5B444E35F27F605FB -:102BB000EA62E2F0CD497CDFEEFBEAFF583DCD8DC5 -:102BC000D153C510E74F39C53D5C7F77684B1EED8B -:102BD000DB6978C5EAA95BC94C1CAD9ED5DAF7451F -:102BE000DEAFF517237129DF0CD89BAC9175FCABD8 -:102BF000493CFE54CD92FDA4E76BF5CEC443058A53 -:102C00002E5CEF609DB332690CAF7BA6E1D4472701 -:102C1000C8E07285EB9DA7525EA828A47CA585FB21 -:102C20009181129C2F91F27960FECBD76252A94E0E -:102C3000F1217F589D43BCC1B63228DD4EBCC1FA9C -:102C4000611DCDBF84B68E1187251D3CEF5932FF23 -:102C50000BC6B76313F97A87F5CAD8D1EA09AD8EE6 -:102C6000A8FB8AE7A9DAF53AB47B1A5F1794585D96 -:102C7000DC76F0EBB474F49F839D57D2D660FBA250 -:102C800058BF96A70E619E9A21F214CA9FD77395DA -:102C9000C1064C871F431EAE17710EA4ADCC4EEA81 -:102CA00028D925BEB54B7C1F673F5E9889FEF78308 -:102CB0007896C70C9CE1E743F4FC1398470DAC0DE4 -:102CC0001C76E2F8CBAD128B7FEB31C7BDB570A49B -:102CD000BDD70A5E36C01651976D656D79F6DE4F29 -:102CE0001E277FD46256C8BF0E74341AD9FEB21A9A -:102CF000F17CC6C87CA856F0B7F67BF6B55E4D12DF -:102D00007152F012D7C1F2DBC163B2DD2431FC7E17 -:102D1000353E122791FFB41D8C637A1E3C61552904 -:102D2000CFFF5CF0EF92D8776F2891192EBA59BC7B -:102D3000CDED7A2B83F44A7AF0D23E4AD75B533CEE -:102D40006C9F4F65F654BD5BA6C3BEB0FC010BDBA8 -:102D50000BD5FA1ABE3E812FCA35D9E80ACBD5AEBB -:102D6000EFB3B947B11B493AC8F4A693A2EB5CDFB5 -:102D70007EB9528DB0275CCF6AF26FFB053F403FB2 -:102D8000944C7EB9334961F23504B99E759DBCC53A -:102D9000F72FE7FB3606F6FE11F7CBFC3574FF7212 -:102DA000BA05184FBEF25750FF910C99F9A9473E4A -:102DB000A8CA8288F783C4EB719F612899D5C3277D -:102DC000744C3EDF89E1E48956F283CDF3ED79E47A -:102DD000DFB87F389261D948FCF6D37BC786E759C4 -:102DE00098C4E33CD07A53289B7991CF2BD6BB056E -:102DF00096321CB6089E75897C14EBA633648FB19D -:102E000075D3F5F2DD88FA8D3D7F79AE72F247C851 -:102E100083C2637A3FD5EBFBCE723FD1D0B9E17765 -:102E20005407FBCE9B80FCC4235D1BB2280E83D7C6 -:102E30003B95F2BBCB5D0F4E65FB97D21626979F55 -:102E4000E44BA1BCE97432E543B59DA793595C6F8F -:102E50009FFE02E5499817DD41D7315F61FC2BECFD -:102E60002966FCDB77BC3829930407B785E6AD3DBE -:102E7000A6AF247C6A8F15BF5741F94B4F19CB93EE -:102E8000B4BCA888EA71CA938E4D8CCA93FA057EA9 -:102E90008307E2D8FE8704199C3F30318A3F356DA5 -:102EA000EFB07CA2A643F644F2E8DA732E3DE38D40 -:102EB000C1A5B0F91A029287F1632F6F6B3AF6B190 -:102EC000F5551B024CDF0D2D067EBF95B7004DEC6E -:102ED000793F38FD84C77B7409F5506E5427D0FEC6 -:102EE000FABBE9BCBE88D5C77617DF4F78F79CF7E9 -:102EF00066E2CBBB73BD59F651E2861FCA78DD2D61 -:102F000009BCDB0C2CAF8C1DB7CDC5F77B6C491011 -:102F100075DEA8B5F52ECE9F7223DFA78ABD7FABE5 -:102F20008BD7CDF8EF191DF2E26485C1FEB4A82756 -:102F3000C6A1BFBD4BF8DB65771A58DE71529C33D2 -:102F4000DDA5F9DD121EBFB5FDFE253BE1492CFFD5 -:102F5000E14BC863E7604B3CD17EEF6E915F2D5B28 -:102F600014735DE453777F4F3E35C325FCE16498CD -:102F7000CCEB06AB85F645BFEC36D86526B73AB143 -:102F8000327FE43A357F73449C0F75A31FA4B621AA -:102F9000E743B64FF5EE8173BF71303F1A07197CD6 -:102FA000DF91EDD7D75E67BFBEE19A9DFE308A778D -:102FB0009A9EFA29CFCF1BA9A7A502EF5AF3252382 -:102FC0003BB7844DDB7572F89CD264F07A52711D68 -:102FD000868EB9213ABF6CC831B17CA9FF764925EC -:102FE0007F8F72A69922FC7DFF389E7F3DB25C6286 -:102FF000FBC207723E6471BC36D46B245E4D6E5BBF -:10300000F324B35F3F9CA27A49D3E762338F9FD703 -:10301000F4A8AD976E2AB43EA79FFB65176B693C79 -:10302000C5CBBB447C5C5C12ADBF2CE85D40FB2390 -:10303000F77824962F5D4FEF4B574C7B87DCDF8D65 -:10304000EAFF9F5CDE875D64EFBDC3CB697FF7DD80 -:103050009C4FD328BED65D87CF7E81AFCFC2CFC570 -:103060007C167E1EE6CE521AFB101FBDC3BBD9458F -:10307000FB4FBABFD8A600CDD3F7AB7A89F4030CC7 -:10308000FFEBD9D13631EF36979DDB8B8B9F0FC588 -:10309000519FECD9A04E203F01793776CED7B0FFB3 -:1030A0006801E969E0C0B10263843E2FD5A33FA067 -:1030B000F8D2792859B146F24D27F8A667AD242DEC -:1030C0001571339A7F97887FA4FFBD87EEA2BAB0AF -:1030D000BF6D994B5222E26AFB49DBA48879FB83DE -:1030E000321B8FF5D8E4BB1322E57C92C9D91FE0CF -:1030F000F301F44D5E961F79BF919F1B99FB188FCA -:103100009FCADEC4CEDD351EEB81F3B8AE6309B0D5 -:103110003825D61D30E20FAA33BA4C2A9D53D07EF3 -:10312000BB23C24E8E0A9C67627140FC9C057E994F -:10313000E69D8933DE4B7D3D84E84C6E3684647EAB -:10314000DE3D0188D73304AF67EA4307A402368E19 -:103150009D4B95422F1B772B0CB1D603763DB56561 -:10316000E0666D89397407B993BC40807D97144A35 -:10317000D63B2E98D951298CA6BFF0FAF57041E3C1 -:10318000290EC6A487EDE3C78E1B1676EFA6DA825A -:10319000F4DC0F6C1FEE16E893E925B3F5B088BE9A -:1031A00027BB450FE6789477EF611DB3E7AE3E4548 -:1031B000257FE64E12CF7D86CF617FA687DB2D85EA -:1031C00020FA6E455B6F2C0EA5381FED0BCED46335 -:1031D000E5CB700CB1F7DD4682E3BAE782A2A7FE29 -:1031E0001F5DE9623F85D769F3449DA633FB191E35 -:1031F0007F12F191CE736C384F69930467E97C2696 -:1032000093AF579BBF14B3C1C4421ACFE31B6D8564 -:103210009F75F2731E1B3B9F9B6F27BCA450B2EEA1 -:10322000AAE5C6711D4C0626B7EDFEA181C78BC36A -:10323000E75DEEE0D1B3F45D8EE4F1B0EF7ADC66E9 -:103240006B88F27364C7A5C8BCFBAA6BED5FC9DECF -:1032500025C5CEF0022F28947F8C0D7FEF02579367 -:10326000C2DFD3108C1793C3E7FBDAF735BBD5A5C4 -:103270008A0EF5B2C26576935E0ACD6945540F3663 -:10328000DBBD7F75B1EF6C5A26B1C9F4EAF4CA848C -:1032900030DF2DE02921BCB5737D49E8EF7AE7F6F0 -:1032A00064ABC4730BBA7DFA2EE819B417B373B4C8 -:1032B000EF8FF8793E5AA142DF1DC113F314FA2EA5 -:1032C000609BC3EC7E5AA2141FD76709AFAFD1CC65 -:1032D000BF276834F3EF0260EB74B67FF690388F47 -:1032E00068B4EAB2A9DE6A84783795F49ABC0F25EF -:1032F000703E3EF4DF16763E1A2BF7D7F1DE9C3196 -:10330000D3C3F23F2ABBCF62EE1385E71C0D4F5D9E -:1033100018CF156A46639FC2F09B46CF4F33A9373B -:10332000D1BEC82A13FF7E49C30D15CA486D17FACE -:10333000D0F0B393BE691D1ED4B7C6978C307ECF34 -:10334000C473DC0CF4E544267B56217F1D8BCBFF38 -:1033500001AF6B7F8EF0290000000000000000002C -:103360001F8B080000000000000BFBCACFC0F0A3B9 -:103370001E8143D1F8E8389D0F534C941182D7B386 -:10338000E0D78B0D5B3122D8FEDC0C0CCA9C0C0CF8 -:103390002A40DC07C4FD40FC1E880DB818180C81BB -:1033A000380DC84E07627B2076E386E86966676061 -:1033B000E806E2C9403C9B9D74FBCD251918CECA96 -:1033C00022F8B2720C0C510AA49B338A87267633FA -:1033D00042E5C76BA3F2BB7419184E23A949D02646 -:1033E000CD7C466306062663DCF271E6A8FC504BF2 -:1033F00054FE5D3354FE4577080D00AEA32483B818 -:1034000003000000000000001F8B08000000000007 -:10341000000BC57D0D7C54C5B5F8DCBB77EF6EF6AF -:103420002B9B0FC20642721302040CB8C480C14A1F -:10343000BB89A0A0C85B502B585F5D02242004828A -:103440005A492BFE73212104126041D4A0881B3EEF -:10345000142BD8A0A0B6B576F9D0529FCF4645A57B -:10346000ADA50115D4024DB5C8F63D7DFCE79C998C -:103470009BBDF76637E0EBFBBF7FFAABC3DC993B44 -:1034800077E67C9F33676665318564E6117211FECD -:10349000BE47C8040B21644CBC244155206309F984 -:1034A000919DE09FD6CF5C36D61312B511129B4B7F -:1034B00048A78B76946AEDA49896B7DE28922C42A2 -:1034C00052E17D859026A1F6C8E05242D44122D92E -:1034D000491FADCA999E1A72251F77371FF7B97A0F -:1034E0003B961DF55E2C9FAFF761B9AF5E21D161B0 -:1034F00084BC585F84E5CBF57E7CFE8BFA322C5F72 -:10350000A90F60F96AFD242CA3F5412C0FD6CFC07A -:10351000F2707D08DF7BBD7E1E9647EA6BF1F91BDA -:10352000F57558BE59AFE2F3B7EA9BB1ECAC0F6347 -:10353000F94E7D1B9647EB23D8EFFDFA5D581EAB85 -:10354000EFC0E77FA87F19CB0FEBA358DE4ED20860 -:10355000E947C86DB79DB7CFA2EB1DF6C47DEF4C10 -:10356000CE2464FD18D10FE01AF6C4C7BE50717C9A -:10357000DDEBBFB1CCE8480097EF1301C759EF2648 -:10358000D8BEFEC0EF893292907563BA7C2AAD4FE7 -:10359000E6DF19BEF3A87D5671BC9F799C4F8885E4 -:1035A0008D63A5EDB4DFD0CDACBFD63E19BE3326BA -:1035B000DEFE54DB3BF6D92E7D3B7BFFE92DEFD8B9 -:1035C000017F6B63128922DE554268E950BADBFA4B -:1035D000513CA71CB3115B3EC5BFD241BAE838EBE2 -:1035E000C63D12154B61DDB49B02EB7C9708140EAF -:1035F000AA9B203D2830C6D5F1EF5C4D449CC7B056 -:10360000278EB2EFDC7A1ECB57FF211342DF5B77A8 -:103610009B1071D2F1D78DFFC217007A539FB10072 -:10362000BD21B92AF09F2E5F908EBD7EFCFB3E959A -:10363000C269ED37EFCE980DF4379AF8E17B6B0F46 -:10364000FC9C28D03EB21BE1D7C0D7BD76E6AC3C8F -:103650006F7172BAA49444C432BA5C17094412C0A0 -:10366000F75F0108143E166F04D7E4A0FD12E1E1F4 -:103670005F898CFDD6BA83EF015CD4DBACFE9D7410 -:10368000DED7F9A3E4942B3E6FA87F44EBAEBF478F -:1036900089C50DF3FECC67A1EB7796C957A5D0D9A4 -:1036A000B8BABB8FC1FBAE6BAB02B0F675A3BB7CE7 -:1036B00055B4BFBDA813D74BFCC43F848EEB285232 -:1036C000C9EC62808305F16A9ECF6C80773FC0D3DE -:1036D000573EC0894687EFDDFAAEBD52D7FF698DF0 -:1036E0003E04465FA4356A9FE68EB73FA1B5A7307A -:1036F000FA217663FB66131D939C24ED560A68C479 -:103700009718D92920DCEDD347F69E776BF4B7C81C -:10371000072E7FD41E4AB02ECA2776903BA9A5A2B9 -:103720001FE0B56E3CE597E2F83A2FC577CD1C2E29 -:103730006B4BA7BB61FC4BC9AD911D2289167199DA -:1037400049FF7FE5CB0E3AF3787D7434DD50BFEA54 -:10375000C80043FF319D0586F6AB8F8D30B48FEBEB -:103760002A31D4BFF3E93586FEE3BB2B0CF5EFC558 -:103770006E34F42F27B718EAD7D97F60E83FD13BE2 -:10378000DBD07E836F81A17DB272AFA17E53D10366 -:1037900086FE37FB1B0CEDFF52D662689F1678C879 -:1037A00050BF65D2E386FEB705B71BDA6F9FF1AC59 -:1037B000A17D66E80543BDC6113A0EF8F9C1BC5FAC -:1037C0001ADEFBD7DA4386FA7B844C4A845F2230C8 -:1037D000394329C87BEA0ADE9F8A382FD01CD07172 -:1037E0003F46A745ED49E4246F7F66C73BF6B9061F -:1037F000396965749CCDDA7745DE49FCFE20CE2719 -:10380000A4D33EDDAD6F67F3BAE21F54BE42BBA442 -:103810007E2BF9EAF6FAB1BF2657297D13720D8582 -:10382000AF3A5055F17B743C2A2F2D6CC9A48E30D1 -:103830003945C8BDF85CD3FB2487442D74DC06777A -:103840004EFB1A80091D5BCA847AF136A88B4A8028 -:10385000742580ABC52B1BF064862F71A55362EED7 -:103860004BCEAA083F75222992E0FB82C3BF9CAED3 -:103870005722A101027D7E410CF960F24B2DEA6FC7 -:1038800042F9F1FECBC7D37F42FF13426405F657DE -:10389000108E0D234900F4869A2D4776E6233C6D61 -:1038A000204FB4F7E803A58BCD57BD38D85067F348 -:1038B000BD64FDEB61C6BA36EE4F8CF0A47086FA9B -:1038C0005DBCD26BDD7E394EB716E8C7EA8A289018 -:1038D0008B28078DEDDA772EA4784691548A473BE2 -:1038E0002B973A3CDBA0BC90921B211E428AC5500C -:1038F00005C04DAD60F0518F3B230D385EEDD5C155 -:103900009100DFC4F602212B187F7C3859D4AF23F5 -:1039100019DE1AC06E1BA6A3831C3FCA71BA6AD4F3 -:103920006FE6FEB70B321BDF455145C7B711466343 -:10393000A996D0EDC218586D9048384F3F0922BE65 -:103940002611B04BED1A3CC373B1EEE276E601F7F7 -:10395000D863218AE7B501D90F63550A0AC783DF07 -:10396000077AC056269235B4B65679C70EFCD19C5C -:103970002F67835CB749B5C44BEBB642CA0709F45D -:10398000C8E21E39F120B91CBBD88CA722FA3A9B99 -:103990000741386AF30F0FEAB417005D8EA776313E -:1039A0009DEAFA6BFBD62F2B397C5BC02EA6E53A3D -:1039B000657A2A41BE253381BE9BF3B344E4530E9E -:1039C000A71EB8E4BF6F073E5DCDDF5FEB7F07ED5D -:1039D000F4D59A1E37C1B179F44984CF2C81E9E33B -:1039E00096918E19910470992578B0BD19782A1393 -:1039F000ED2BC65F267AA12DBE4ADA6E57BC256B29 -:103A0000E8F813464A33812EDC6544B121FF065C99 -:103A1000D9F4FB0EDE5B524483FC706732BAB57F8B -:103A2000284414DADFE563DFB3B9482480EF2F318F -:103A3000E0C551169A4246513BE91F167C8FCE9144 -:103A4000D9114727233F5ABD6C9DA488E1C94BFF7C -:103A500077B1808EA7C806BDB1BC5CF647E9779602 -:103A60007A5C484F563D5EE9779DDFBC1084F15784 -:103A7000E5DCE3584EC7BF50DEB40AD8D2F2E1E429 -:103A8000CF80EF2CE6FE83A6FF6E70023ED04A6721 -:103A90009787443360803BFBA403CF87ED6F1CD630 -:103AA000CDF315C19D89F2F56A7235CA854BBC7F8D -:103AB000A13EF2C6E121080FF172E879A589AF9B1A -:103AC000F235BDA5FAA6E9ECB2F302D36B442D475B -:103AD000384B9C9F9BC6936EB05BD7E5CBCA0ADA86 -:103AE000452A93A3403AF0D74DBF0FB6190179ADDF -:103AF0003475B2E73F32C8CDD5FDA7FAA37DC04DDE -:103B00002A34E99B4BACBF0EE0A7EBFF31C0CF19C5 -:103B1000879F8D0453A3402FE149063F7655F9FD59 -:103B20004A94FE73D580470227880E8EDFA37CA8B7 -:103B3000E30F5B4E84E8BFAFC9C55BC44037C861C3 -:103B40008BEC4739450A64F447CCF32B1299BC89B6 -:103B5000C3D92E111D7F902911843BFD0BDAB33898 -:103B6000FCE85F8AEFF57F00FCA88E8E3A47E1F310 -:103B700046A984CE2793A8CE2BE9FB1291A03E48FC -:103B8000CC47BEA5ED13E474E0DFEBFD20079BB846 -:103B9000DF47BCED3EBD5D3E4864788DB7477CB7DE -:103BA00019DA99BDD3A4D9F5DEED06BAE8793F8DCF -:103BB00024F43FFA89CCCE1E247A39FD6C47FF6D80 -:103BC00075E69418A02125FB7A7F25F0AB97201C81 -:103BD000343DA1E905AA2F0689FDE2E3C98541220A -:103BE00060BB51FF2695D726BD9B52649403446F5A -:103BF000CF14C07F73BC482FC4ACEF7919BCF1B2AD -:103C0000F8AA97BE2489FDC5692293C344CDC4F5A3 -:103C10006B7C45B83D61D5E882307AF5F0EFCA306B -:103C20009FC180E7080EEEA46E15D4DDA416EBE765 -:103C3000CB4AA200279BD4D54CB87E54F313F8513D -:103C40003C0E936C1DEBC727D60FE5A207F16971F7 -:103C5000D59210D2F19D68070A6A885C447B30CC0B -:103C6000F5AADF07785C555F473EA28B711C9C8CE0 -:103C7000FEB9941308807F6F0122C8A6FF7795B222 -:103C800052F22B7AFAECC123598EE3592958609DE0 -:103C900056977D16E801ABCB3B0DCBA211730528DF -:103CA00053AFAF1391AD12D393361EA5AB79228CCF -:103CB0009719427E96BC412C892B13ED57DA5F0988 -:103CC000269C07A703DE2F29DDF5D08D0607458644 -:103CD000F1CCF4E428A51E8988D54E986F7F8EED2F -:103CE000FE739A960088DD24DC3C94E2AD7FD7AC6D -:103CF00029A077DCA07FE83A5716971C01932FD5AF -:103D0000EFDD70BD02710022001E56C360D7C0787F -:103D10003F585E8EF10FFA37800A8B15C172E61F8D -:103D2000044C76ABA8489A7D26F669EF08176DBD5E -:103D3000DF4FB67E1BD1F115EAF17B2ECFBEBA93D1 -:103D40007D4FA5FF037E4C33E9D9D480511FB84D78 -:103D5000DF790E6089F05EF2BFF23D2FD96857C05F -:103D60005E2914BD114ACBA9C49B067E946302F55B -:103D7000EF68DD9BD3ADC2942E859795DC8F25949B -:103D80009FF5F47F88CBD7ECAA4DB39AE8B8E74B00 -:103D90005D7EA0E7FE549C66A4F75E4F4B3D31F07C -:103DA000734BF136A4EB06AAF00AC03F2816D15E89 -:103DB0005F5DF8BC57AFC73ED1E4502FFA208A347C -:103DC00096FB93143E9642319032EA9FA70FB3FDC3 -:103DD00074B9F4E1BCD3888F6F8BAF2FBE257DFC07 -:103DE000B3DF5B992C3EC1E559765523F35794BE5A -:103DF000FD83DE78DD88787550BF26917CBED08348 -:103E00004FB57769D02BC6B880F586EFCFD8D107EC -:103E10003CAC33CCFE3F1B37A5CEA27C0CF6ADE408 -:103E200035F841AB958D2AD8F3E7C12E07FB305CFE -:103E30008EF16152C8E2B5308048EB294A20C2FCBD -:103E40009B08D1EB4139C71877B3643A8CFA7B866B -:103E50002AE8E79F5227E33CECF0BD4C8CE746E0B4 -:103E6000BB162F89A6A0FDC9F0079F62F180072E1F -:103E70008B0E347A053398D1ABF1BD553925241119 -:103E8000FE7A7DEF56E37C93CA25F37B2E4939A554 -:103E9000B35392BF2791533A7BA742DBF7E178A255 -:103EA00076DECB422A9507BEEF9310856F133465FB -:103EB000433C94A03E6BF29578519FEF124C7EBB31 -:103EC000C2E84749C7FEA29DE94DAD9E7C3EECBBD2 -:103ED000F17D2405FDDA64FD1BEACB1E9628713ABC -:103EE000EB0E6D92281E1B97076604D1BF3DB249A9 -:103EF0001A12EF5763D1FC76AA3EC7C6F7072442D1 -:103F0000FB21DC4472F12A78E825CA588026FBB3ED -:103F1000934E6CA74F391E89D0E3CFD021DB609D33 -:103F2000189F3886FD60A08B186FEA6275FA22D45C -:103F30005BAC8100CE4B0ADBEFA1F06A49E17585ED -:103F4000D7D378DDCBEBF9BC4EF505D49D32ADD39C -:103F500032C51AF662DDC1EBF9BC9ECEEB69BC5EE0 -:103F6000C0EBC246ACB7C86CBC3552848DEFE0756F -:103F700085D7D379DDCBEB05BC4EB6B1EFDB58DD91 -:103F8000618DB0F19DBC9ECFEB19BC9EC6EB8379D1 -:103F90005DD886F564F8731452F81BE44367BC8E51 -:103FA0004A84C3B5A7DE656A67F49221106E87A9BB -:103FB000D960B71D98757F36C4431F3D71B50FE8B2 -:103FC000A7E1668D9EFC283F49CE4D28C7FA737F36 -:103FD000AEE1CE1518876808C98C89787C26DE5E2C -:103FE0007204F4F6F919A21F1ADB92F82FCF723B74 -:103FF000FE191E97799AEF57EEE4FB95DBF97E6583 -:104000003BDFAF7C92EF573EC1F72B1FE7FB959B41 -:10401000F97EE526D8AFA4FD36F0FDCAF57CBF7267 -:104020002DDFAF6C81FDCA6140EF7558AEE2FB95A4 -:104030002BF97E6503DFAF7CE4CE92DF16D2F59DCF -:104040007789680F24C347F16EA3FC1CB1C3283FD6 -:104050008BB6A41BEA43370D30C8F7C256E3BE4502 -:1040600041E308435D595662A8E7DE778D61BC9C49 -:1040700085C67D8B01736E34D4FB05A71BFAA74F51 -:10408000B8C350F75E5B69A87B4AEF36D45DC5F7CD -:1040900018C67314FEC450B7E7AC30F47FDC52800E -:1040A000F42567AE31F4935C1B0DFD6A1C81CF2DA6 -:1040B00020EFA6645E967C237F57B3F4F2D2AC1F48 -:1040C0002CB92410403DC7F411C66821AE3688C50E -:1040D000AFEC1FDE7004FC175B21D353E6789579B3 -:1040E0003CD9F5D431957EA7DC73C4D7A5A35BE298 -:1040F000D3BD47979A2A3139B9E64146DFAD0F263D -:10410000A673D404741DADDF248E17BB258B418F9D -:10411000687E4DEB8302F6FF67C7D7DACDE3C6BFF3 -:1041200047713D566FB744F87CA88ED0D90BD6AEF8 -:10413000B4D904F53CF3972D9CDFCB27F84F3452CC -:1041400078AFF412BF8DD657BA2A02CC2E1115942F -:104150000FCB6E46BF5EEBAFCDABD1359DC917A27D -:104160008B5BA29C7218E20A2B33FBB6DFE4980546 -:10417000E37F969840A2542FC95270523EE55FF9F2 -:10418000A8C5BF9CA07E4A181F206423DB77F619C0 -:10419000E3A68D734CF28FE7655835F9965981CFB8 -:1041A0001BBD7DCFCB06F382F9F07959634E2C2DE0 -:1041B000B1149CEFB85806D6CB6269585E1D1B88B7 -:1041C000E5D8583696636283B12C8DE5637955EC5A -:1041D0000A7CAF24361CCBD1B1ABF0B93F361ACB39 -:1041E0002B63DFC1E7A362E3B01C19BB0E9F17C7A7 -:1041F000CAB1BC2276133E1F119B8CE5F0D82DF876 -:10420000BC28360DCB61B11F6039343613CB21B1D8 -:10421000D95816C666613938B600DF2B88CDC7324B -:104220003F762F3E57624BB0CC8B3D80656EECC71E -:10423000580E8A356099135B8EE5C0580BBE372047 -:10424000B61ACBECD843F8DC17DB8065566C339696 -:1042500069B1EDD8EE8DB563991A7B169F7B62CF5D -:1042600060E98EBD80CF5DB1BD583A63BFC4E78EB3 -:10427000D8CFB14C891DC2E7F6D8012C2F85A74BAA -:10428000D9C1651F1BF79FC77E68DC7F2E3D6A94EE -:10429000E3256F1AF79FFD878DFBCFA35E31EE3FBD -:1042A00017EF33CAF111BB8DFBCF453B8C727CE815 -:1042B000963B8C7A6493518E17B4DE6DD4238D4671 -:1042C000399EBBEC27463D72DF0AA31E59B8C6D003 -:1042D000EE9B6394DF59E431A39F3E619B518F5C59 -:1042E000FB53C378AED2E74D7E4D04E58BA3F817A0 -:1042F00086F7EC85074D725965F2C9146F0790C0B7 -:10430000FEE652E2F0835F63C6673A970719C0770B -:10431000B4CCE47CD70FF88E96E9372DF4013D64D8 -:104320004C2D9B0576CC85138202B132616ADD305B -:10433000D8EF491F48583C818CB80EE2684DD95AD5 -:104340009DA8026D6F1A4430BE40D4E5150117C612 -:104350009BB1FE5BE9C10AC88B69B2F276B292B535 -:10436000A7B0FAB1C6392BA03D3DB5231B12991E4B -:10437000B72696E75D12DBDF1B28057E27D1F5FF08 -:10438000B5BCEB7E88CBFDBB3DF4AE449F2FB4871C -:10439000F2606BEDAC35F434A88E02217014FA8D06 -:1043A0001402EF4928B78D71D629A038E9F37C298A -:1043B000F807E89731D527C0FA353834B9FB9ECFD6 -:1043C0005B5C3F35A511F437D5D57C3F18FE34BD75 -:1043D00041F5E1A34E0FCAFDC86A799B8DD9854688 -:1043E000FDA166CDC6786273D312D4C7805F4BA29D -:1043F000386B17D653C1BA1C0C7181EE5C89968B51 -:104400006CD126D0275FA5751E172C088FF3B09EA0 -:10441000FB6F0C61FF15CEA965B01E0A8FAF383C4B -:104420002EF4050FFA17F4D1F9F934AADA2D18E2AF -:104430009AA9969060EDC7F653617C5FC88F7ED9CC -:104440001F25166FD7E047FFEE4BD7E23804DF4B4E -:10445000B18EE93D9E368E000003BAE67A51A3EB99 -:10446000BA247A4A8B7713F5E66FB5EF7444E67E8B -:104470009CE93B16C98FFBB6E6F72497510E5A5DAF -:1044800021CC8790A5C4FBBBB28DEF5B6D997A59A7 -:10449000FBDC3BB47534DE7C59FDDBB5FED43184E6 -:1044A000FE391C8E64CBCD4877055C1FE770FBEEB0 -:1044B000D09F6E58D14AF939429FD912C41122CDEA -:1044C00022EE6BE6D45082CB8FC37BA0C2EC42EDD0 -:1044D000BB036B8D7198031A1C375D1EFCB5FCCEB7 -:1044E0001C4AF8BF28E93D0FB2632A5B8F9755A598 -:1044F0000D417B0A9D5701A3253290BA23FA38A0BB -:10450000793E84EF5F0CE4C30D74B1FE649771DCF7 -:104510005EDFB5BC32BA2F3DD8EB3BDF723FB0CA8D -:104520009A783F95E20BF13DD064FF69A5B61FA8CC -:10453000D50FFDA9DA0E7677D3C24ADC6F6FF23160 -:10454000FD4DBEA6A38E8DAFDB3CCE4E0EF7EDDC4F -:104550009FDCB9A902F31FC96E237D0E79F8564777 -:1045600088D96FE9503ED5C6FA0DDD3C873FAFC410 -:10457000E7DB5BD9F3C16B4BF9F3127CBE23CC9E16 -:10458000176E98E080784EA3B7221DE33A75F44F7A -:1045900027EF86784322C4E386B491003C1BECF5F8 -:1045A0008B20FF0BBD012CB5790FDAB4AD7C38ED53 -:1045B0003F6861703AE4B952C2C4FC430221153A23 -:1045C000EFC7F87A73B5F690B1BD8D7F2FAFAD729E -:1045D000F970FACFBC85A18D934BF1997F0889F7CB -:1045E0007B848F63D7DA03C6F6306F575A4FA21811 -:1045F0005016FADF9904FD9A8DDF5BC7FBB928B32B -:10460000C1BC0B16061CC3615E45ACDF131ADF9AF2 -:10461000E482146E249375DF6BE5F3B62C64715657 -:104620004D3E6CE37180AD10071816EFBF46EB6F7F -:10463000DFFEC4C7548F4B0B593EA9D6DECCE7A58D -:10464000E5E514DC678CDFFEC2CAF8B85B66F15B97 -:104650008DAE92D13799271AFC3D127218EB337444 -:104660007621D403038CED6505C676FF0863BDA8EB -:10467000C45857AE31D42FF4C4613A53F471182D95 -:10468000A6F384B712FD9078FCAF3B459F479ECBC5 -:10469000F9EDC9BA12ECD7E0E27C64CAA769522AE4 -:1046A000ECFA7DF8BD9C8FF6413C84962F40FE3697 -:1046B0002DF78F0ED8F341BFBF67F16F23C9E1B665 -:1046C00095E3710BE7C3C7009FB46CE3F87C84C724 -:1046D00075D6F3B8CE5A1ED76981B80EC667585C36 -:1046E00067158FEBFC8CE7A1EFE1719D67795CE7C3 -:1046F000191ED7799AE7A1EFE479E8DB795CA79DE9 -:10470000C7752672F9BD7F624736C4D91E9F98D8F7 -:104710004F9E28337D168480262DAF224A8315E8CC -:104720009AC206F6754AEA148B0DF262030CAE25A6 -:10473000F3148BCCF271F06F3AFF0EE815CC9F7931 -:1047400093E7F5E450AB4847EFA30F4709E47564DE -:104750004DF08E8690682AA747DAE6837E5C0D903E -:10476000ACC35E307388640978E57E303EC17EF963 -:10477000BBC307C19C1911ADAD70D2F78B5E0E564D -:10478000504F9B0C2DF21F1414C8170A8880E7FDA8 -:10479000E5FE234A691C5F741606BAA073447D9631 -:1047A000A7E9876B8D7471556C2BDACB4D753C5F27 -:1047B0004A2109FD78ADF45E2B9AE249463FAA6989 -:1047C0009931DFC35C8ED861F4C38BB698DE57FA9B -:1047D0007E7FE826D1145F33E61137B9A6F7191F9B -:1047E000CF8F4DEDD35FBCC552799D3C265E77C619 -:1047F000BE8BFDCDF6A004761EB557A5A37200ECC6 -:104800005DE9A837007113E9A8C24B3F7F1EE0F5B0 -:1048100020D6A9DD1884F1295E0C76A3850A7CD800 -:104820001BD90FC21DFD908B2B02D418DA7F1B41C0 -:10483000BF224D765EA7827114988BF891397E3233 -:10484000E4DAA7210E12A911C9365A7F7C61DFF282 -:10485000AE575E852B80FB4939B5DE124B1FFCBE7F -:10486000A9569C94689F6C31A7EB95B5D3BDA83F22 -:104870000E5F326F60B1ACCB1BE8772BCF1B38C318 -:10488000F2E20669EBBABF6F3A78D4B48EFE49EC17 -:10489000EAE735BE73B1BC138DEE330AFAA6935521 -:1048A0005C3EC62222E904792B05507EF6BB358496 -:1048B000F9F1A0A0F57CD2F4CD75C887EA83EC1C91 -:1048C0004FBF5B03449F77AFCD63504E17B875A4BD -:1048D000E9C03896C741E10FFBD74D0708FF8E8A24 -:1048E000C2C17E1FA980EFD9492DB1437CB3CEAFA1 -:1048F000C2738B8BC10BFC55DE1FE7D5BC4CC49437 -:104900008A86092C3EAAC97F8D4E1A7C3C5E3F41A7 -:10491000C278B7E4AD8D02DE9B46133C6F43EDAE2B -:104920008B1735FF06F2BC323BF1DFD6A26814E8E4 -:1049300092042621FCB4FCC026775639ECD3ABF3A5 -:1049400035FB82E7A14A7E3CB790D3368AC5C33295 -:10495000C3985771BF187A4EEEA7A7BB0E844F536A -:1049600092F3056B6596F7E44B82D7F7B91CCE90AE -:10497000A393993F4AE93F419CA093F7DBD23CFDCA -:104980007743499C7FB5F63F4A0AB66BF59C988CF5 -:10499000F3266DDFCE0FB85EF3F74CFE9B550A1A77 -:1049A000FCB05CAB82FDB4BA9C699467973F4F89B9 -:1049B000E54316DF68C073C680BEF9A689F3CD85CE -:1049C0004126BBA3B088ED1BF7D81D22F150B86E6D -:1049D00035D193A647AC45DE0DC3F27BD3C5D66572 -:1049E00095AA00FB2A7E82FB426E7F4700F6055D9A -:1049F000399172B08F291DFC15E840A38B9CB6B18C -:104A000008EF1735BD57472A0209E6AFD975E06FA1 -:104A1000F9D2616493DF43825EF0AF7296331B720A -:104A2000208F2B0C54FBF6FB2E77FF5ADB4FCEA5C5 -:104A30007FE0F7FC42C3F7A7A6B89597B2EC589D64 -:104A40007EFF3443B0E8E8B2C7CF37BD47FD0B6FF8 -:104A500022B92D594259361DBD98FD77B39F4D7A25 -:104A6000E5BD9512C89BB24C997404F21F7BFCED16 -:104A70002D5399FCE278B3727FB4B73F79A7BF2F6B -:104A80007D627599F659BEA53FE9B719F34B2F3BE7 -:104A90003FF75BC6231A789E5E2FBFC3348E180E75 -:104AA0008889CE6D0C091BE12EB98C76C79556C648 -:104AB0009F839B8D71E4BCBA0189E39D3C5FADB2DD -:104AC0004CC39372FB1F29BFCD3F62653E10F78335 -:104AD000B578D37C9E375D09796C144F7348D00349 -:104AE0008D678988F93167C93B9EAB747C536563D8 -:104AF000E7E848B3F5249CBFD0F2B3E686595D9B46 -:104B00004F759BB15E45A66741DCB56A9395403E03 -:104B1000D67C229DECD2E64FF9FDFB366607559315 -:104B2000DA26906B2B793CB1D24B24C8A7AA79E93D -:104B300089B1709EA7C6C6E4F7E714FE8A2EEFE699 -:104B40006E574406FEFE68DF55DFFF0E81F7234DEA -:104B500003406FA6253E0731BBD938BF4BCDDF3CA4 -:104B60005FED9C46B27948BB8484E7151FD0E25EB6 -:104B700097798E64BB8DE13FD939924BBDBF0BDE77 -:104B8000EFE31CCAA5DEDFF34FBEFFFC25E65F6343 -:104B9000EFBE1EE4C4AACCDA20C8552D9F651109CA -:104BA0000520566379659A3A50D1F5F35D66BF1CCE -:104BB000DACF7219FD0AFB1EEF1CD7C3BFD9BD5D4A -:104BC00006FE3DFBD31353C12E58F04B0BB1533AA5 -:104BD00038B7DBCDCF8B4564D08F77EFB360DC8007 -:104BE00048D1B1B7E8F20531B3908EBFE0676EDC13 -:104BF0005FBEFB795B640A7DFFEE173F1A45281CF8 -:104C0000CEADE87E7D20D83D3F1558FE95DA35EAD9 -:104C100016FAFC6E89DC154CA0B73A391F9CF9B91D -:104C20007306D099B0EBC00F71DC8EDBAD369D5EA4 -:104C3000F88DCD8AF0A7FDD879AC6784C81081CDF6 -:104C40004F9F2FAEE5BD9D794660F37BD91A498110 -:104C5000F9ED6A9743B4DFE25D7F43BABEEE677B4E -:104C60003C0087C52F5B0CF267F12E4BD4360ACB84 -:104C7000133694F701973016E049500F2CDA57831A -:104C800079B28B3A5AFE66F1C0FB46FEA270C17340 -:104C90001F0B3EB0F8A740FD85A73D60C77EDEB97B -:104CA000D30370A5E3CE92295D7DF7EF3A3E246CE5 -:104CB000FC587AEFF1205203F4B5B86335FBDEBE41 -:104CC0009B4F837C5B6CE2E3CFE11FD9BDF547CC02 -:104CD000668C479E276F8E857D0AB22B23617E717D -:104CE0008FFEE07CBD60CFF9AD709EF8CCF37FD92C -:104CF0000A76FDC2FFFA72EB03100F7835C50BF28E -:104D000068F14FDFF3101DFC33ECCC8E3FF7CCD3B2 -:104D10004F3D46F9E4DCEF6D68E79CFBD5E95C8527 -:104D2000AEFFDCDE7F64C1B9DBFB7E35B13FC0E3A3 -:104D3000BEFDD7F5EFCBCF00BA8DD8F4F88D207E2D -:104D400095970596CCFC0A2F4D783AB4EF502ECCAF -:104D5000F3EC311B9EBF594C9FD59500DE6A503F46 -:104D6000407D1985F7A2DDABFE66199508EEEA4095 -:104D7000113745A203C1C85EB4EF967F195F0AA53B -:104D8000D5AFC078A41BE5BBF9BDC547297EAF4CA4 -:104D90008ECFF3E46B19E0BF78F76AF6DD0E8A4F29 -:104DA0004F6F7C9E857F8CEB8DCF12BB199F0B9F25 -:104DB000C4D8E8BE8C8479241A3E6BF6DFD6A7DD12 -:104DC000A0C9874BC1791ECF9BFA2F5BA0C20E7C76 -:104DD000F6BC53F5313C47A6D0B6737BCEE7124AFA -:104DE000279F5ABB7F0872B2FB57362FF81D77FFFB -:104DF000EA03E4BB73FBDF961576FEC42550BBE2E5 -:104E00001CE9F9EB043B6311DF335BBCC31DB579CF -:104E1000E2F85A14993649F1E0F313F83CC2F8610C -:104E200051E4C0AD4202FC2DB31730FD14E9877088 -:104E3000A9A19E0E9CCFD7E35528037C9EB81EE8FF -:104E40002F193EB5F57B61FD57EBF0BA83F1B1B98F -:104E5000FF22CAAF20877BE137227C00E5B9769B31 -:104E600004F991E7AC2CFE66C67B1CFEFCFCE4B7A3 -:104E7000B417EFB727D97FE070B814BF5F6A7DDF42 -:104E8000167E73EC0A8E6B86E399AF13EB838D5C11 -:104E90007E2C22B59306E8F499CD4AF5593ED87B8D -:104EA0004175A0109F6F538705E5FC995D9608E852 -:104EB0000BB3BC584412EFDB45ECCC7E59F4F281C5 -:104EC0005120D7CE1CFC39A74B46F78B769F9055C7 -:104ED000AE1F227AFD90C4DFFE291F6FF12B89C718 -:104EE0005BBCFB6F09C7FB5C0ADC0EF3FFBCD34A5B -:104EF000543AC4E71D964989ECAD4D76AB31CFD617 -:104F00003DF6582A7DCFE27128B0EE8615810F5408 -:104F1000B04BDEB1629C9648FE4F6D78DEDAA1ACF4 -:104F2000A1706BF054613C451BAFD10427C91744F5 -:104F3000BF54CA0C96329B3A62F0A7ADD4DFD5CFEE -:104F40009BEADD1CD04BC7479FB6C23AFF6CB21F2D -:104F5000FF2C91A6FE74BC3FAB827FB992C85F3430 -:104F60008E1F5A66218A5E1FDABA8FC37CC8AF5380 -:104F700008E4AF595E4D51419E2CDE9A12817DCDE1 -:104F800043FB2F3C05703BF7A48DEF73B23CDB6A0B -:104F9000BEEF777AFF85ADFF49DB4FC3CBF4FBD57E -:104FA0005B697FB0DB773B315FF3AFCFA78E2254D5 -:104FB0004E57FFFA81A9205FAAC1C7A2FDAB7FD6D9 -:104FC0003FD240C73BD58FD54FED191401BC2C7C87 -:104FD000E1578B409F2C78CE4980240FEDFFE0876E -:104FE000503FF76B37E67B9DFBF5E9EF021F507BE7 -:104FF0005BD1EBF5F9FAF3DE74DC055067EDC245E1 -:105000002EEBC08F590025A5F7052FA7E2F9075D04 -:105010003F7C6FB1ADFB7E1688520788E8134507C9 -:10502000001F2ED865FCDE5FEDCC9E5A2C7757B161 -:10503000FEE1018C5F3BF1BDAF353AE5EDE6F7B53A -:10504000FEFF612F308DC3DE5F6423B589E8DF96F4 -:10505000C2C65DB0EB9B61C6F118BDF6FE0E7BFECD -:105060002381E5E793BD29B84FB0508E0E4D2FC672 -:1050700078C73CE0DB859EE8D034FABD5F7279B931 -:10508000D041EBF4F9003E0FE80F7562EF7A0EF0B5 -:105090005BF3520A017AAFF9B51BE3C9352F5E38CD -:1050A000F5387D7E66BF13E37A35BF5E8AF8AEB110 -:1050B000457F08F1BDEEBD36B28DF63FB3F7B7B907 -:1050C000608F9CB14673D3FB880FD574D87832B803 -:1050D000711DD42F28AAA5F35137B0BC9C3AC2EE5B -:1050E0001DA883A00ED0F18729EC1C31DF97BA8769 -:1050F000C7A3BE98A3A4E2FCAFBD893DE7F1867BC0 -:105100006E56FAA7E9E6017973E42AEA97C8B5C3AF -:1051100040CE5A62371105F6FF6283B1D4FA59E0E6 -:10512000FE8662C8DF62FB7ED64C3FA9A6E5D2743C -:1051300012C2F397AE1B7BF8EC7714C5F76C56FAE6 -:10514000C378FE14265F6A1C81F129980F69BC7729 -:1051500041DDCFD67581DFA7609EEF05AB6A03798D -:105160001EDFAF6379837592F201C47DC9112E975A -:105170007AAD9FF1D917DE74E4336D1D2DF55E9481 -:1051800027ABEB7D58AEAA2F220AE629FBB16EE1D0 -:10519000F0B015AB04EE99001E843F9B2B1880FBEA -:1051A0002C604C88B75B5C21A42F9BAF16630576FF -:1051B0007EFF8EC5A5926A17C467189C206E0C707E -:1051C00092795D6A9B8270A5EFE3F3898ED09C94FF -:1051D0003190EF3BC220A7E4CC1243BD17DC34BAB8 -:1051E000D8F3BF0D3F82F05A5D6FC772557D19C26B -:1051F0006D657D00EBFF1FE0D7CAE0770D5174FCB1 -:1052000023675618EA49E1B799C22F33CE5766385B -:10521000D4F1FC1C8D9F92F1EF23F504375F36D655 -:10522000B761A93D4F4FA2D7CFA6307BA48E8496FD -:10523000E33EA897C56148A64A7274F127E253F18C -:105240001C089E3785F69C9B307EA9E1D7E2954EDF -:1052500019E59FF201AC67E91B5611E495A56E3B79 -:10526000F92843C7C75382290AC2D98F71E006AE15 -:105270005F57F6E0D3C81F2DF50A966B399FACE750 -:105280007CB201F00EF13DBF88386D9D44507F3EE9 -:105290004CEBCCDF8F127D3C3CCDDF11B552FCA333 -:1052A0004C52B064F7701CB34586D0F79CC52400FF -:1052B000F49276ECC7115C2BE9C0F3D669DA3D3085 -:1052C000AF14A4CDC4FD1F62657A8A585819B682FE -:1052D0001F65866F83FF20DE2F916C3EE5C7E70BCD -:1052E000F0BD0B33D99E59E69D1DC7E03E0857AB74 -:1052F00013FDCA2C7F6D5E2ECA571BD2ABCB1F127B -:10530000AA7578CC4A62FF2D734CFE23D0E38790B8 -:105310009748F1BBB16D700AC0B9C5DAE10379D81D -:1053200092C6F48D3283424177BFD86B5C4E7A4A85 -:105330008D724093CBDE6B4B0CF4ACC9DDF40946A7 -:10534000BAD7E4EECF7AE46EF02CC8DD8CD816E440 -:105350004B331F34586555B812EFA361F1A7130200 -:10536000DB57EF2D0F70DFFD8BAEFC6D701E5BE326 -:105370001FF3FAA5E6C9F89D1E7BD09A381F60205E -:10538000BF97A199D21BA174D44AE90C10B18ED257 -:105390001994614A678C9FCAB0D4E8780561324499 -:1053A000DD27B279F278ADB67FB2C25E12003CAEB4 -:1053B000EC603C34C8C1F7493345CC0B90A83FE9B9 -:1053C000A28FA403E3EC605F4A56B68FDFED163B75 -:1053D000601F7FA56BBA1DF24A85B452A49FAFDC53 -:1053E00095797DEDEBC0FD6B407F5E979F9C2C8E89 -:1053F0009F9BB4784B08F8A57B5C9D98DFE472888E -:1054000086FDA71A47A8C0A1AB8F84AF73BCC3B0F9 -:105410007B929CBF1CC5D743725452A893133DF78F -:1054200025292A29D2C98B1543AEC7FB987ACB8987 -:1054300024F270E7FF8C3C6CC88B205EAD66F9935C -:1054400019C03BA068A9C2D50AD43A5FF983D148F4 -:10545000A7D739C00F716DEBB183BE57D07B9E6665 -:10546000F917D76B0AC6C1A85E7BB40CE46952BDBC -:10547000567B17D271EB4005E8F8C0BA079E84FA54 -:1054800047EB6C78EF4B556C3551E87CAB63E3B080 -:105490009CD7F61096956DED94890859BEB67ADDC5 -:1054A0004CE8BFD982F19F5391ABCED5D1FAA95622 -:1054B0001BDAEFA7B6DC9B07F6DFA956A762017BD4 -:1054C0007FCB18637B33BBFFE5549B356261F47B74 -:1054D000D102FB1184CB778802E9E64B4A15B4E38D -:1054E000BF30EDB754AEB705044F72F857B625B6C6 -:1054F00027F1FC36E45C93DA61205FCB8FFF380F35 -:10550000E84393334BD3A9DC03F81DB79144FB0266 -:10551000131D1317039E263A024B19BE2EEFDEAC65 -:105520008F446A77239E429E6986B82F8BAB7EC4D8 -:10553000ED72624FD2EEE1EF7B13B7D7B4FEE5F523 -:1055400007696D55B131AE6D8178B500FEF83496BE -:10555000EFA0ED03F5A66B664FB7DA50AECCE1F1E4 -:10556000288DCEE37416F2F07C31031DCE8F6D4092 -:10557000B927B48C7C741C85DF9794FE803E84969A -:10558000F1FD01BECBD77C67FD9D74FCBFBF69C137 -:10559000E7F36229D8FFB307FD8FDE09FEC2BF5BC8 -:1055A00009C89FBF1F9988FBC89F598D718C7227AE -:1055B0009397AF72FEAF8AB518ECF3AAE6D932C45E -:1055C00041AB62EBF079156C22611EFD1DAFC10687 -:1055D00070152CFD1A78FFF6892B509F96601CAD34 -:1055E0007AAD2D619EFFAB0EC520AFAABB5A715C90 -:1055F00042EDB3CC2C3E9E4EEE54C732903F8857BE -:105600002590F75DC5E54FCFFCB6580DF2E7B39492 -:10561000C4719AB71C6C9D55B1EF20DFF55EDF7742 -:10562000F17995F6DD2EC6A7F1F53C3A2ED17AE256 -:10563000EBB816FB7F9696F8FBE7397C4FD5CF2366 -:10564000012ABF2A6DB49F0BBE7F6F5319F8F95B17 -:10565000D2D205DDBAAADB1690806E5DD55B66C935 -:10566000FAFB29E378B8CF8087F36B16231E9639AF -:105670008227400F54B68C1F15423F7F35C2F92355 -:10568000AB3F17E4F1E9B67B3D89EE913C6FC64F25 -:105690001BC70FB5BB4B75F8D1F0627EFFD49FAA34 -:1056A000BF7A10E4D466B741AE98CB5E78CB4F0C8E -:1056B000B7544E9FA7A8FE0E21DC94178F015DAF53 -:1056C00075627E5C72F85D41427DC12F89FD4CEDB3 -:1056D0002CBB730C7C97201CAADB181D5C0A6EF196 -:1056E000EF723A284FBC9EF14E8D0EEA884A19F6A9 -:1056F000A47C293A7880A8F63ED6D143076DAF95B1 -:1057000017C6E960BC333C7105EDF729D83FC37A71 -:10571000E3FFA4AC7AAE017B678D05F7BD4E3AD4AA -:10572000AC3B587D34C8E7939EF0D46B4AE3F5F95F -:105730003B8778F4F73A9E6EA6704800BFF1CE24FE -:10574000F453A892E2B1FFEFE8E7A324E760263A1A -:10575000CACB019F249C389EAC959AFCB6A4BA7A19 -:10576000FC5ED0A3275D055F4568EB3A47E86627F6 -:105770006D6F4CBB1FF5FCC99302EAE1E57F5A3A15 -:105780000CE4702FFBB73EF6D8C743306EF9F8C76C -:1057900056B4A7705C42ED1FD003986F8E7EC04058 -:1057A0008CB324DBCFBD172EFF1D13DFD7D5F66FCB -:1057B00057D6773E04E313BB4ABCDA797D054A66C7 -:1057C0008FFD07CC43179F97AD21AF1FFC5D810470 -:1057D00081EEAD52A819F20CADBECCD1AA0ECE4BC3 -:1057E0009C2C2F27E5F0E1E67CFA7ECADCDF7921EC -:1057F000CE67A3DF81D29E237DA18F975B3359DED5 -:105800001729D43D2F8073C8B46E883BD0F9F6E1D8 -:1058100037FF52E8B9670DEF379EA95DF405A0A3E5 -:1058200074F37B2D7F456A64ED695A73236BE771CE -:10583000D4C5952C4E7A68562AC24F5BD7CC5756A2 -:10584000E17D6B335FC9C6F34C335DC33E0178FE27 -:1058500012126B80EED3987E36D3C5435CFEFCA05B -:105860005D54AD74BCC3D6EE834EE08B1F09E85780 -:10587000DFF1DE612B90FC1F8E9EB4425ED45D9002 -:105880005844D7338B283233A223F8FE6CD2E1661A -:10589000F58E7E70FF697C3CEA32C3784BD8FEF30C -:1058A0001DEF1D9D086A948EB712CABBDE24328C90 -:1058B0003F6B9FD2C48E43F1F15EA1E389F1F17A8F -:1058C000E027D9111E71F8D8115EBFEF395FA2A28F -:1058D0007DA1832FDA2B1A7C1B006E147E33536755 -:1058E000DC484625E79799AEA19F9051F1F998E1E0 -:1058F000FB7768A2FCF68433B017F8AFD119781E95 -:10590000F867A1BD3B572AC073602FC2F34596507C -:105910005E16A5ABB38342C3FAC1BD1E9D89F7795C -:10592000CD7C7A1CF8E54A28295FC03CF879951FA0 -:10593000F2751EFAF169379E47D9FF412E943596CC -:10594000AEB5B703BFFD9B05EDCF2FF60DEB33AF23 -:10595000EE388FBBBCE514F9796BB6CEBBB83D779A -:10596000D73E6704EE41BCABCED2E35F015DDF55AD -:10597000C7F24F88D439EA56833DD9C8F7437A8FA6 -:1059800003FE82791C6D9D0773075C01FEE593633E -:1059900064F4230EBCF9C5EFAB69DD31C88E7EC25D -:1059A000DA344EBFE5CC6F7D322DE01C09F1AF3506 -:1059B000E97E95AE73CD6BA443A4703A38FCFE48E3 -:1059C0004529DC0B2D62EC6C7D6C7BB802DE2B660E -:1059D000F7CE78B95DBABEF3641BD0E3E96336DC79 -:1059E00077F8CCCDCE11AEB10673C18EFFA45D4E5B -:1059F00078FFD99FDD12CEB75DE81280CE6793B0F5 -:105A00001DE4C5BECEE9FD613E1E3FF102F99FDEF9 -:105A10006211D9FD685ABC252AB178BF2AB17A80B3 -:105A200097DE14FD7D63AB274DC03C8F39AD6F63AE -:105A3000329EA734F13D3FA92E365F7767FA64BCEA -:105A40007773828879D86E7FB700EFE57556C8F80E -:105A50007E58E8F3FDBC655ECC4385F741CEE75D3B -:105A6000E6FB3617CBD3DAC0FDEC76ABBF69021D7F -:105A7000A77D6D9A00F8D0FA292E26574E4FD0E216 -:105A800048618C23E5167A53E01E8BDC00323771B7 -:105A90009786F1BEEF6DD08FC559110EEDC35F8CA7 -:105AA000C23EF61A88AF009EAD8C9ED6AC1530AEC5 -:105AB0004AE13700F4C4270FDB6E8275E4350B5ED4 -:105AC000F0DD699970DE33DC7646E7AD8FA25F08C2 -:105AD000615A183777CBBB382F7792F5AE70B37B0E -:105AE000F23FB9047D7CE964F726E6D675F2FBF156 -:105AF000A2780F5E18E004F54029BBDF440A28FABB -:105B0000FC9838FF2CE7744802B0CF56592647203E -:105B10008E2036B7CF8075CF0EDBC80D747DAD42B9 -:105B20006700F8451D23F2FB9402C7014EEB36F4E3 -:105B3000C73CBC55622017F4B0FA7F64DCA73B1861 -:105B4000F86233DC1FBFB54C46BE381860E70D9FC6 -:105B50005C56D00EFB94EEBA8AB6D974BC88574610 -:105B6000C9D2504ADE1806FB94CB44AF40FB878372 -:105B70005ADEB6D7017431DAF2E5E422D8C7CB1683 -:105B800031A6745A60F736AC5C56E105BCAEF466DB -:105B90000A7AFFE5764E07C7D383B7BB287C7C0F14 -:105BA0006EF452338EF267C6151047549B65453B21 -:105BB000B70BF73D6470BC64748AD12A0FD65DF3CD -:105BC000D2E13E5D162F7DE8C6108B73C2DEE85829 -:105BD0008C73F23F1FE23593D7D68C706065D38A01 -:105BE0002AEC0FE364D171324AC5E8583AEEB6B4F4 -:105BF000C0568CDB4DB4239C88D4D506708A4C1CCF -:105C0000E0877B6D378E1BFA369C5FC938D23D1D0D -:105C1000F4686490E30FED20A756CA0AF079C6B283 -:105C20005377C2F334FF23F74299D1F8FE0320A73C -:105C3000D3BAFE568FCF27C986F862C6879F7D03E9 -:105C4000ED1941D910A7FC3A3DF81380CBD6E2708C -:105C500018EFC5048C66C5D7B16779E724B8EFF8AB -:105C6000F434D1BF8DB7E3BA3679236B18DC4A41DF -:105C70002F68705B252A1D5158D7543BD24721E924 -:105C80004479950DBBD983E378C9F870F512C8D76C -:105C900030CF679D4BE8B97F03EE09045C417E8CF1 -:105CA0009CCDCE15EE2DE9F4813DBF362D717CF2F1 -:105CB0002D377BDF26B238ABB9FD0D37A30710892E -:105CC0006D252C5F7E24942EA2A64299630F40FE80 -:105CD000F35E51F923D2F9468B02F881FE568ABF52 -:105CE000036F7C8EF1C503E177B17CC65DA4E5DD71 -:105CF00047B3E8FBEB4AD97DC7EBBC8C46AA9B991E -:105D0000BCA8F675D961DFA4BA9878B7717A533513 -:105D10003843BC8CEBABCA5B195C338B09EEFB429E -:105D20002C08EE9BCA827E147E99CDCB97201E490B -:105D3000A73A98F65B07E3027E1A45C2C6EDB22386 -:105D4000FF862DB8EF49F9FD2D886B55B6F6C77D56 -:105D50007F38360CE3A5F3EFA6F3F1DAE938103F0C -:105D60003CDD6CC17301907E03756519A565A4CFF8 -:105D7000EEF2223AAE52EAF5AED1E84093639435A2 -:105D8000E6507D01709BA3AA4B80FE4EDABD6FC02A -:105D90003C9C9B6C0AAC7FCEA6979682FDE2F47584 -:105DA00035837CA82E63F34D6FA5CFD1CE51DE8213 -:105DB000FED5AD36857D8FC3AF94D31987C35C3EC6 -:105DC000EFB95BD8BC1D832261A0CFEA6514AED0C9 -:105DD0001662740F21D18B22F2D51158BF5BCDC250 -:105DE00071FBCD30F18589FEB47555F275552E6382 -:105DF000EB229C9FE8B4A2306E65295BE71CC2DEF3 -:105E000017E1391D7F2E5F4FA5FA2296739B6D8691 -:105E1000F1B716EDE884F9E417CB0A9E1321ECBE26 -:105E2000C35CBEAEDC46F6BDDCE217115EA44E37A5 -:105E30005F8CABEAEA94AF4EFF9632165C0A00071D -:105E4000D8E8B8277F2CE37E4EE126E3BA4EAF1E9A -:105E5000B6BD95B67FF4B08CFBDE7B45FFF13CF41C -:105E6000476585C91FFFBB53404ECF6DF4831CDFD0 -:105E700053CEE07FFA6612017A187224980EF01E53 -:105E80007224C4CB5ADC4FA700117AE41E9D1F7503 -:105E9000999A059097B1C1CFCE033950C6EE231F12 -:105EA000A49F379D5F46735605E4436596A557C882 -:105EB00078B5ABA9FDC863D345683FFCD8BDF09D5C -:105EC0006CA25B0F6D973D83D97996C3B415FAD553 -:105ED0009D7A10F0D1CACFB90E8199A5637918CAFD -:105EE0000CCADF2DE9304F894C2889CB839D0F8F59 -:105EF0001D0D7205539E4AB08C9292DE7243D77F7D -:105F000038EFAF0A09FAB93D8AC13FDFF9F0F5C3AE -:105F1000C18F5F0776622ADCC7E6FD12F27454BFB8 -:105F200088705F678DDA8B697D15B51BC17E595FFF -:105F3000F4BE087CB76E1FF1037D6404FFCBA6C7D7 -:105F4000E30D6EF6FB3C924C5A80FF0F0E3F350975 -:105F5000F0143940ED4EDABFE237AEC79C600FFD5A -:105F60009EE5C1B4FFB616F5F7FDB972C2FB78C95C -:105F700025EC4473FFF421D3319E97B76903DEEF1C -:105F8000593D49F2DF407B676E2A2F073B46095295 -:105F9000EAEA4FE7BD65F4726042650ADB2F5326DB -:105FA000B1E7CA0456B6D41F7908FCF6F02E29A52D -:105FB00090CE77C46A76AF584BF117F610B54B4BBD -:105FC000CB9FB7DF4C9F7F5C4AB5207DFEF1B55F6C -:105FD000A4C0FECE93A5151900CF7DCD46BB8EC0C3 -:105FE0006557D41F1A690B07DC745EADEF1184A7E7 -:105FF000C5166DABA475CB4B2EB0707AF939AB5B7F -:10600000DB67009DCE2992316C6F5EEFFB5C9FCC0D -:10601000AEEB9E04F7EBE7AB84C5F7C38FA2509EAF -:10602000CB4546BEDA8942C7BD89F9276129F03AD6 -:10603000C8E570714886573479D63AA4F22990673A -:106040007FE2761DA99D87E7C890FF2D600F7597A9 -:1060500027F29B4A5D0EEC7F7ACB2D1F409C7A4E37 -:106060001DB3F7F3B67C29203EA8DD974DC7CF2B93 -:10607000C5AB06C99C6561FB48C04FA1481405E645 -:10608000D341C04F0853FDA3878336EE7FF7FD252C -:106090006E1BF26129D8CEBAF5B8F87A72FD743D5C -:1060A00009F47409FFEE8F9EF8F2C03880FF32E6E3 -:1060B00022E5854F0876DD3CF2D4CB9BC755301ED8 -:1060C000D8AF6E2F8EEB2EEDC2FB5CCCF21DCC79DF -:1060D000E0DBADCE73A3997F6F94A7BDEA9CAECCF5 -:1060E000CF734DF26AA4ADE346C4EF1E76EF35647C -:1060F000C442BB404485DDFB19D1EEA7AE857E23AB -:10610000DC2E2FD041EBF0F74B003E6BB9BD30B722 -:1061100098A0BF3A37A713ED85D98DDC5E90FC4D72 -:1061200020649D5BD2C81A9DFD80A612B8D08DDC7C -:106130005ED0F43FD7DBD5BECE66D4AB8DECBC5F72 -:106140008F9DA132BD9AE7637ABDBA997E47E1C4BB -:106150003C566F97303DAE6CE2F603D7C319FCBBDB -:1061600099CD4C5F65801DE181340815F532EE61F3 -:1061700065C5ED967EC54C5F66B4EE45BDD6013F64 -:106180002E3306E406D39783DE3EAA02987CF47190 -:106190001B95D38FF3769F97DA67E971FB6C95C8EF -:1061A000F79B08B30F31E79FCEF321E8AFB31B771E -:1061B000F0F9ED3D9C7E13C8D79DE1023C57AEF14E -:1061C0002D463F693DB794E5AFE4D6B17D72B7BFC8 -:1061D000EA29FDF9B3796E76EFD03C8DAEEAA23EA6 -:1061E0001817EF8540392E637C7135B59730FEC4A2 -:1061F000FDAB6B5C3CAEC1E927993ED1E4909B04BA -:106200003CC514BE1F479E4279AD527F09D6F67138 -:10621000B861C0DDC0EFE169A530FF75E3BEC2FC27 -:106220008FBC24FEE29F353FF35BCA75F7A4A3CC75 -:106230000FED14139EEFC9F1B0F84387449C00CFD3 -:106240009430BB472EA54C4ED83FD5C3ECECCF398C -:10625000DCD68D7B0ACF6726D5CF12512D09F4A944 -:10626000A66F5B01CFD7D0FEEE379A54F4D323410B -:106270000BCA57767E314CBAD08F548B648C1BB6C8 -:106280005AC376C0C7FA528E57AFBD1DEEB7F9D6C6 -:1062900078A1F0003CAF0E8811211FF01CF18E6434 -:1062A000711D3CB77C9AFAEFFAFD8AE11E91C34951 -:1062B000C11FE6CB6B66F4B56E9C8CF358333AABDA -:1062C000DD92AF97BF02979FEC9CD89A71AF237D68 -:1062D0005DEEFCAAEA9EC57B3FB4E7A7363F5D00B2 -:1062E000708EDF7F11E8F33C4555DDDF36ED48B0B9 -:1062F0004FD0D30E7E940BFCC0C81D867D4D8EDF23 -:10630000091ED1107703F96A45E7223200E24B7B80 -:10631000C6473CF01E59C6F66DE7F37DDBCF77DC50 -:1063200082E7C94752B2B226C0FB67F5C6F3EA9FBF -:10633000ED7C7A008B6B440C79C2F39FFAF908C3A9 -:10634000FE7080289963F915ACC0EFAFFB559B2513 -:106350007EFF800CBF57007176E0E0C170AB620732 -:10636000962EE05F5A7A4837965E504783C14FF2C7 -:10637000639949825866915A2C7D248CE500D2811C -:10638000650EF8B983412F7463A910AF487472BFCA -:1063900080F8B15E4882584A80B78CF8BE84B4CB8E -:1063A0008EF91BB07F017C9FECDC99DF53B9C4836D -:1063B000FC5D7B25FB1D23B65F31DD13B8C78378F9 -:1063C00088A2FC9ECD45F991E74674C0F9A37BD61F -:1063D000B2732F9A7C47FF867EE7D974A60FD48DBF -:1063E00002CAB115CEA9DF4578B65ACFE8F71B88A7 -:1063F000DD5E08BF0FA28D3B9BC71966733D08E1A8 -:106400006E767ED08FE7936643BC41D74E7ADAD959 -:10641000BD34DA38A2F3DAA17DEDF7E9DEC7FCE896 -:106420004A931F7049FD6DAACF31BFFF359D50566D -:106430003C1EF7EC77955CA457AEBF294129F85E66 -:10644000B3ED04FA63E189013D5C9EE17CA0E9952E -:1064500039A67C0F733947E2FC611A876AC0343869 -:10646000D78B774AE8F85BBB9F54BBBF677E20247D -:1064700067B3D77C80472F9F77986CA9C8A6E5A7FC -:1064800050D7C5F78FA6865EF2E8FC116FA056D4F0 -:10649000DF77B390F3E3444B6B39C8B9D321E207FC -:1064A0003F623EA9F57C07E2F9472D28E706D2793D -:1064B000CBF07B2FB0C1918E75157EEFE56C3D3B27 -:1064C00027748ADF33FC14DC4743CBBFF07B85475E -:1064D000B62D9D0A74F039BF5FB868DFEA20C47D2D -:1064E0004676386781DE1FD931BE1ADA47EEB2B17F -:1064F000DFF1E172429B171C7377A4E33976D59ED6 -:106500000EF284A0DE3DDBEA88C0EFFF9CEDB0B068 -:106510007B558B45BCBF0CAE21B4F0F9A5A6C3F7E3 -:10652000FEF387608F7CCEE5C9194F1AC397A40A82 -:106530006A26A4A5103FD8351B9C8BF01C64952BB4 -:10654000F2D46399901F6EF7AFA0DF3FB0F7A55C60 -:1065500078FEA87311967FD9FC412EC8ADB3FB3FDE -:106560009013D16D8D1495213EB5609F20C2FE49D8 -:1065700079C72C19F647AA761FC0B8728D3784EDFB -:106580000BDBF6627DC2EEB771FF6470AA82F33A4C -:106590009B1DC2386F619B2D0ABFC7B1A7207C77B6 -:1065A000C27DFB54A66736385FC5F11F75BEFA3A47 -:1065B000C265B30DCF7F1CD8FC1B1CF7CCFE97F82F -:1065C0007C09E60B9E4DE938FE13D05F7BF9794CD0 -:1065D0007BA7471F0F965205837C3DEBE6FB5E3998 -:1065E00097E8C7F30589ABD3C3E452A707F6CDAA52 -:1065F0003A181CFE628DCA60472EE81014F83DBDA3 -:10660000F2DDED781E70C13E3B9E975800F000B859 -:106610005178215CDA0EE0FC0B002EFD601DEF626C -:106620003E7EE13E0A9751F1752F7085905FB5F57A -:106630005238B075EFB9149E42463CB5BD2D435C4F -:1066400066E13E01E1B770379B47D53E36AF09BBE7 -:106650006721FECFEC270AC45B4EEDFDE07358CFF7 -:10666000D9FD76BCCF579B17DCB7E02901FE6174DA -:106670004AF631B9AAD9DD35912CFCDD819EF6DDD3 -:10668000EC7749016429945E47EE9B86FB82A54026 -:10669000BCC0FFDE8E11ECF705C3B900D73DE3A304 -:1066A000B930EF33DAEF2349E15CC08BDF132A4DB9 -:1066B000D5E1E3B3132FA15E2C126BFFFC20F0F1A8 -:1066C000F3EC7738967EB841D4C3E33AF841AA3167 -:1066D00000B7B73C08B79EFB5BC22C5F8A84901F53 -:1066E000AB383F9E6DA77E275DFF676D2F60FBD99E -:1066F0006C637ED55FDA0EA503DC2AF9790C12B93A -:1067000005E511854BB33D819EEF39D71661E7153D -:10671000CF09FC3ECD2734B8D5CAD30DFB7C4C1E27 -:10672000E66CC93F8C7E4624F13947B39D64BE2F89 -:1067300035593EC0492ECF3EE6F774697A77BA27BD -:10674000342BB55FF2F3DE952D35B900EF4A381BD7 -:1067500089F79C1EB801E215786E88DD931A05F85A -:106760009CEAB907F5A51B20CFF4541AABD7A57640 -:10677000AE02BBF69476AFAAFA1A7B3F9FB56F8242 -:1067800076DAFF394FB03695D9F702FB7D1F6B1AC9 -:10679000FC4E83A63792C3C1F83B0D4FD3B5025CC4 -:1067A000E8783FC1F1243ADEC87F7E3C4D4EFFD3EE -:1067B000E3D8FF67C7D1F417F027A43E12BF7FC408 -:1067C000FF04FCFEBBEF93F05C035F5DD83CB809AF -:1067D000F6D1CEFBD83D30B6D6E504F4F9DC4D1B3E -:1067E00012FEFE5B4F9DE7E5C88329BFE9F8FA4832 -:1067F0002AB3CB8F70390D7FB0BF0577E5A05D4C14 -:10680000FF5AB3307509FDE761FC1EF3221246FB07 -:106810007404E9C0B2987462398A746389DBCC83EA -:106820002154EAC7F2AFE55D6361F10BEDA1275397 -:1068300044CC3B780DE4D0D941A1A7E1A2B615CE56 -:1068400045D7C0FCDF48F57278450DBFB742F4BFAD -:1068500087A1803D38C5D7973D48BCD2999EBC974B -:1068600002BCCFF6ED545C5FB2DF515B62BAF786D3 -:106870009D0BD7E050433A308FE4B52DF7BC319CE7 -:10688000C2FFEEDD6EB493876E695C02F2FC6ED2DD -:106890009905E78487F27B44481BBB0F47BB1F6405 -:1068A000789BCDF83BC2A6DFE359C07F3F6B81F9EF -:1068B000F7A9F839DC167890201FC37C8EF7AFA9B2 -:1068C00089EF7D21C5897F0FC57C8E77778788F911 -:1068D00051F740DE95CEBF18BEA3D666A42FE5DFE4 -:1068E0000AADBABAE067F108B723B053E8FD9DFFDF -:1068F0000B82D8B2B4008000000000001F8B08009B -:1069000000000000000BDD7D0B7854D5B5F03E3360 -:10691000679E99849964924CDE131E21C86B0221F4 -:1069200045A47A122246A43A3C6AC15A9C8040800F -:10693000BCA068B1C59F8144081425D488400107D4 -:1069400044C5FAE8A417E561B00344448BBDA15ADD -:106950002F522F1D901F1111466DD1F66AFDD75A87 -:106960007BEF6466480AF4FADDFFFFFEF4B3877D2F -:10697000F63EFBB1F67AAFB5F70C77288CA532F668 -:1069800082A2DCE31DC4D837F87753D773AA5DC75A -:10699000D808067F8D6C5C31630DD5AA7D15941ADD -:1069A00002564DEF84A75D1750F219CB4A2C33CF16 -:1069B000853273E8ECFDDC8C8DD58F3EEC86F6C617 -:1069C0001A75B809CAEDDBE67618F07B97CA4C3029 -:1069D000649603FA8532CBD005FA41B9D1FE1BC7C4 -:1069E0000C18BFC006EFA19F1C3B0BB8A1DFFD5BDD -:1069F000EFD761B9A19EB1741C47F175B8E93B9519 -:106A00003D85D362DAF8A234C6F2F09F308ECA56C2 -:106A10007FAA4F62ACBCE6B4256C83F7E1CAF16C87 -:106A20000863A5F67C5AA7FAFEAD1F6179CBA25385 -:106A30000E1F8CF7C6D6E57F180BFD1902302FE824 -:106A4000A2F0EB86E36361BCC85623DBC6BAE090D4 -:106A5000BB583D1536D380EC1BF82F7B616CD9C831 -:106A6000A05C28CAF9388FA87A280F17E333368537 -:106A700085D2B05ECCD7A93106F364769BF3CC40C7 -:106A8000C66EB22BEC9BDE5DE511A2BCC3D05C668A -:106A90008579EEF84FC5B314AA0F6C9D9587EBBBB3 -:106AA000B4C7976787752C32270D61BD2EDF3F83F2 -:106AB000DD2DF6CF6FD1B9F019B2305757FB01DB9E -:106AC000EB4D3EE8A77109F39CEEC79839D06E1DD7 -:106AD00088FB78D8E081227B4861538250AFDA98F6 -:106AE000168471860B7C897F3EB4C4FDBBBE86AE26 -:106AF000711FFA7AD214DCDF48A255DBA65C3E2F68 -:106B0000F99D6A77FB717F0DD9CC9300E3199C1D29 -:106B10009976F86EE02EA3C706201BFBEB41BDC2A1 -:106B200030EEC08353993B91C30BE7AB2E327A4EC4 -:106B3000A730665AE4F4A8C3B19D8DF0F1339B31C0 -:106B40006042F82FFA7933D6376C2D71B9A3F07AF9 -:106B5000F912BB4785796E5A62F6A8B0C0E5627D2E -:106B6000F1F3CB71E8BC01F8CEA8633EAC5F00FB4B -:106B700080705C604FA0E77C51DEACFA27E2FC3706 -:106B800003FE2C457C5DC8F1774186398078BEE0F4 -:106B90008D3EE9AC1BBA92CFA797B83C7D611E9B96 -:106BA000164E7731F8B4747EBBE51658FF8244B3B5 -:106BB0001DF1519F54F0F868C4F7370D0CE9AA2174 -:106BC000B1C43D23AA3F7DD24817C243AFF3673219 -:106BD0003B632BECD32AD40CC417FF46E6616C4D03 -:106BE000F3CDBC9CE8CF54A0FEF1E65B7939D5BF6C -:106BF0005181FA279ABFC7CB39FE4C1D949F699EDD -:106C0000C0CBFDFC1BB1FCEBE6EFF3F26098432632 -:106C100063BB9AA756F861FC0683678A07C67D1195 -:106C2000E63F08E61F14CF3D76BEAFB2FE37F81E32 -:106C3000E0BD533CE3EB5F16DFEDEEA17EAFA86F46 -:106C4000EBA1FF57C577A11EBE3F20BE6BEFE1FB56 -:106C500043E2BBC33DD4BF29EA8FF4D0FFEFC57731 -:106C60001D3D7CFF07F1DD3B3D7CFFAEF8EE580F8C -:106C7000F5C745FDFB71FD9F10EDC3E27D7662D344 -:106C8000713FE05D36F02DFC2B4C6C4A46BCDB546A -:106C90005F4CF8DF3002F07C5017BE672BCC8BE5E1 -:106CA000210E95FA1B82FC189E6F8BFE4BE7F75D59 -:106CB0008378B7E02DBD07F1B041F11CF341FFFE31 -:106CC000F93A0FF2DD056FE8399ECF57032C8ABEE3 -:106CD000DF8E9BFF1631BF4631DFDFD97B13DDE44A -:106CE0002D7279C64B7E89746F8F2D9B819E3418CF -:106CF000BFD1C9E54BE1FC32737F941F205F906FD9 -:106D00003E6433864C30FE437695EA1B9D6576AC37 -:106D1000F7DB55923F0F39CBCC3390AFDA80D99562 -:106D2000C07876DE77A35DAD0820FF709453FDD860 -:106D30005F8FB7231F6D64114729AE6F31C815F8F7 -:106D40007E7F7D19BDCF73FCC581FCF968325F572A -:106D50007BE2214B3EB453EFD391BC28B0AB24C7A8 -:106D60007A2FD605DCD0A4DDBE4087E5271BB9BC51 -:106D700082BFC42218BF2F1F9EEDB8BFE4CD42943E -:106D8000670FAB1EB79BBF53A3E4415F94574938CD -:106D90006E728CBCDA5CCC34ECD7EF32079E827E0C -:106DA000FBAACC9592DC05F73C879ECB17FD780FAC -:106DB000CAB53ECDB1F229BF294A3E319497B1F20E -:106DC000295E5EE5D4037F8CFADEE4B2C7942D8E93 -:106DD00044924FC0633CDFC0D00B5A17DC62655D44 -:106DE000FC3A5E1E3508F920F96EC3D7C363E4830D -:106DF000E4CBF1F2E1CAFCF5ED5BFB131E02B772C6 -:106E00005F99CFBE8D7800F867F029243F98EA7328 -:106E10007913AF0C2F83C16BB7DBAE0C3743EA3B62 -:106E2000A457187C2AF57F995CB9025C653BA3F9ED -:106E3000C9CDA741AEFDE5FD9F14322099E5001BA9 -:106E4000DAFF545DE0295877F6A2E73663FF5987E9 -:106E5000AC8D0867A36BC6E6465C4FF3E38C013E3E -:106E6000E9CD1C9F8C196576FC5ED569AEE43E5079 -:106E70007EF6DDBB14C0277D4ABD87C1BE1D7EF1F5 -:106E8000CDE4DB107E6F1988CE4D3AAF9DF5A1E9B8 -:106E900010BEADC8B16E5D4578EC33239CB27798D7 -:106EA000490E30FFF6951A2075036C071B85F553C4 -:106EB000566AB0EE1D4A67F9562C070346DE1E5887 -:106EC00034FE5FAB4E11F54C535DA4778AFADF5464 -:106ED000948F86F6AA7DA00A7267C1DA979A0C3958 -:106EE00058AF93DF6B6C24AC17C7136515F6E7B981 -:106EF0007651EF3FD8540E44D46A94E3333FB66FD3 -:106F0000D5E978D9DFD684FDBF5026BEF73FBD5204 -:106F1000CBA6F9DCA67740D1F17A93EDFAAEF9AEC3 -:106F20004D7EAB6929ACEF1377380996C16AB69EDE -:106F30004E43F9BC624ABD17E18688EF0599D84BEC -:106F4000EF263CEDDCB79D13FC59507BF1D0DF936D -:106F50000641559D3E7C2801E057B3BBDE6C80EFB7 -:106F60004D06AF3F2BBFEBBB9A9D95A4CFD4B51573 -:106F7000D1B39BEF0EABBDFFA5EFCCC6AB18EF9323 -:106F8000D01F6A9F87AA1A7D7D934D4FED19DFFFB1 -:106F9000EED727BFFFE4F93FDC89E35D7087D3C6F6 -:106FA00041EB1521804B37DFC9F6B5BB27D0F3582D -:106FB00082B6C601EF6703EF227EA5D67BB07DD0F7 -:106FC000DC6CF700A02D86662FCA0D007D4037B21D -:106FD000EBF90B475F6A1FFF3E9EBE826696321E2C -:106FE000F978B54A722A68F6270C81F26AB043969E -:106FF000C2949615BD3B6C10965FB231B44B1AAA81 -:10700000DB5D8390AE3C4686FAEEEAEB831948E7F7 -:107010008D35C629DB117F430B5C33A3F4ADB5C9B5 -:10702000069AC7CAD780EE86C2D3107428F87D3F6F -:10703000901B0AF2459F19ED1C4B4632F3E7633B68 -:10704000DB6AA4CF95065F4519B6CBD0917CB1F42D -:107050009B5C5106F370A5EA143DCDA3FCD82C949B -:107060006F76234A50762279FA6E84D373AAA71ECC -:10707000E9F0399BCDEE870AE0911AF23FB59F33D4 -:107080008065939ED5A31CCF2A02791EA5C79E10AA -:10709000FCF384C348FC6EB52538A114FAB12ED098 -:1070A000D9FD30DECA9A751D63619C5FD6BC7C74C5 -:1070B00029BC5F95A6329C87CDA9868C207F0CDFEA -:1070C0008339C2BC5F58EAB5237F8DA4AA6C1BD458 -:1070D0005BFB1A993B8A5FD90641398A4FA638551E -:1070E000CD02DF7F95ECFB77078C3BFCAD77CCF8CE -:1070F000BD6B844E87641354F93E2715C7F6631F92 -:107100001DDB4F72796CBD737C6C7DDAE4D87AD765 -:10711000DDB1E5CC7B63CB5324BE01CFB1813CB65E -:10712000F22A660D7FBA04E52DC0E73D84BFB54065 -:10713000E741F8586AB69F9D05F559C84FD01E1A09 -:10714000C248EE1EC8FDA91BF5025372BDDB31E833 -:10715000727864E5986FC3FDB2F555ED0CDADBDEAD -:10716000FFE86BECDFC6A2DAE5237CB488239597B1 -:107170005D309F44FC871BE15DFFE707512E1ED564 -:107180007B10DE59352A8DFFF0647740CFF5091763 -:10719000EA3349A27D927975871EF879D2FB2BE7F5 -:1071A000A3DD1B0FD73456AF205D027E707BBB92F0 -:1071B00091FC58A1635588376823607FA41E01BFE6 -:1071C00098946224389992156137AA3AAC4F13FA11 -:1071D0009331E35E0BD2F1438738FE3F64E4FD74E4 -:1071E000F6E7A64111E519F2C994645D4C3FEBEC5A -:1071F000A28D28A73A78B9B53DF936A4CB759393FB -:1072000087219E98D0EE82FE7A659BB501B03ECB79 -:107210001B46BF029DF65259BB01F6B2D5CAEEF12C -:10722000C23C361CB6FAF5F0DE32F31776D4D38AB8 -:10723000C5BC5B9779DE463E10A954098E96D4668C -:10724000FBB0417C0D7E981FA203CAC5D27E2DA43F -:10725000E7594A9B49BE5B8A9A9B114E1BC6EB4875 -:10726000DF48BE5747F86CC9091EED8B7E82993AFC -:107270003BF6970C82DF089D3C9ADDEC45BF090385 -:1072800098EB4A38AA60BFB442182745C0D5E9DC5C -:10729000F91305FA49C1FE86F0F608278780D3E87E -:1072A0006437C1DD29FA4DE90BED87F07E1A4BBA40 -:1072B000FA91FBB8A18205707E725CD94F67FF4CD2 -:1072C0005390AF1A7E0770837D5272CD34B987E632 -:1072D00032B28F5B9779EBB7125DDBC8CF91E9CC07 -:1072E0002E433CCA3CBC71A26E087E67A5710C336C -:1072F0005900F1385365E61B9351BFF1121CE3E9C5 -:1073000035A3BD7912EAA9725FE2E93743654DFA08 -:10731000E4CBE938C3E92C2B18D20D3DC7D14BC6BD -:10732000E1C87D88F4F174BD25E14211C28545B7FD -:10733000D75FB9ACD7078FA29F87A5839C00D0E702 -:10734000C68DC7D83F4C585698CEFD4D1FE4FB0E56 -:10735000E1BF017905C4DA3ACC3EC686743A9F1182 -:107360007E95ED5A7DD7EFA0BF4BFD8C76942B39DF -:10737000879B3B503EB2DDBEFEB80F9B54DF130926 -:1073800050BFE9583A43BEBDD2C2ED3155E079BC99 -:107390007C592BE8C68D72CEF5AF3FA57E18EC9BCD -:1073A00036D00EB4B7F617156F9853FF07F52CF6C5 -:1073B00002E959D9ED1D4B6D38FEDAC34D6680AF39 -:1073C000E52DDEBE19CA7E15E1574DFEAC0339B37B -:1073D000084EEA7113433C1DACD70258667FB230A9 -:1073E000E4BF3B5EBABBCA8DFC276D9C1BF9D0364F -:1073F00041EF01619FC5AF5F356A3ED427E2DF6F81 -:107400004CD689FDF49EAD847D1CFCA491AD82CA4E -:1074100042DDF426B4EF222B81FF42ED74BDBBF6B2 -:10742000E751F6ED23D6D26032DA254BCCCC070AF1 -:1074300073F6970AF30171E638FF508AFC279785A7 -:107440001494B3B9F5A0F0225E2DB4325F14BE6778 -:107450007FA952FB47AC5A3079047F6F063E60E04B -:10746000FF64CF257B59A593F328D45F0CCF5B4FE6 -:1074700022DF60CE72ADD31EE98DF80B721FC6DB22 -:1074800027D66D00181A86C17F365DC834E4F2F63F -:1074900007049C54B32D84FC52B51D3946FCC5AE7F -:1074A0009E8F6E87763731B16A467E59840B957F01 -:1074B0006CA77216F05FD330D2FBFD687FFB93B8E8 -:1074C0003DC234CDED4C437A6104E46C336B3243FE -:1074D0003BC276A0B70CD66121BDB99DB9911ED033 -:1074E000C3762681581643B86E62AC229A0EE453D6 -:1074F000FA25D4457AB2A7061EB4D07C0CF52C60D0 -:10750000417D08E706F05617B2809ADFE5171CE2C6 -:1075100070D37746564FFAEC0B5F9FC8443E6D3DE3 -:1075200004FAD850DC671DF129AB3596FE185B4A8A -:10753000708A08FCD8BCC44EFBDC69BFF9DE11FBC5 -:107540001C5E8AF222776172CCFECA76D95F663100 -:10755000DFF0E87E03D46F76DF7605FD32D95FE693 -:1075600052FDE625EE2BF4DFBB87FE33088F7AEE63 -:107570003F9BEA3787DE71DC0EA0D814697778DD8F -:107580005DFA753C9CB317C6F2E5A1BB63CB122E26 -:107590001683E69C0030B7DCA7F36C85FEBE732C27 -:1075A000B65D45FE1FC9FEED6A1F724EC2F6609FB2 -:1075B0006F85B7379C8D6DEF2D7DCD8174DCD59EA9 -:1075C000CFEFA62F63DBC5EF4FFC7C615EA9DF8F99 -:1075D0009AD718B329A67E4AE565F34AFD41D4BC83 -:1075E0006E71C5B6F72DED7E5EB7159AFEE9BC64E7 -:1075F000BB3B465E5DBBF8754CAA30F50077DEFEFE -:107600000753AEAEDF1F56FDF376F72C8A1FC74F28 -:10761000F8BE40A78D4981FAE9F80AF5459B95F433 -:10762000DECBEC2C219FC6A1E201DF7992B471F888 -:107630005D85A43BE16738FCE275E9C8D7B3841FD8 -:107640009D09BF426BB58BFC0A3ED11EE44923F273 -:107650008BD61DF05D129F57B4FE9452CDED0A3BC0 -:107660008B103D4B7D2999D9156E8F737DA7A7711E -:10767000E2FB7F18154098EF8C4563D80740872FB1 -:107680001BEDA52ADA675B14D20766946BFA44C037 -:107690008F514D0AF995663CF0F6A3E88FB9FEB418 -:1076A0007B7718DECF08383C386C6D07D3304E90AE -:1076B000AE9F5FF4203C1F3BC0288E86E5F9886FA3 -:1076C00036CD8DF64625CE08FA396FA82FB223DFC6 -:1076D000FC914D43BE5939597B8FD6FB156825D097 -:1076E0006E265F3ADBD532C188F18ECABBDD2351ED -:1076F000EFA90C5A347A9A996A857554823E86CFDE -:107700007423532DF8B432333E4B9671FD2B69A48C -:10771000D75809E357B63DF357FC6EB61ADACFF5E2 -:10772000C900ADBBB2ED8DBFA1BE3653F31A915F58 -:107730000CDC61E43AA9C087C1C1D832F283E87297 -:107740005128B63CFC706CF9D3140EDF51C28F7512 -:10775000609F89F8F6BC8FADA47FEE05818776B275 -:10776000FF0513C98F31F36CB45F1F9FB36E45BF24 -:10777000DEFEE3566A3FF7390B6FAF0BBE8865FF3D -:107780008B096467CF4B099624C3BC5FF95A4FF04D -:10779000C66519B0FF17076C5D85F5C383251817FB -:1077A0007BF93AC63AB05E0D0CC175BEFC0FEEB760 -:1077B0008E3C6B0A6C837E3FDEF3CC8B3FC3719FA4 -:1077C000CD4A56607F6E40B900ED463D69B6A2BD18 -:1077D00031EAE3E7FB20DF98B7C314B3BE175314B5 -:1077E000A13FB89310EF7AF23B9E5AF90C7D5F7877 -:1077F000F618E1DD5E835F87713CFF4A8E677B2D63 -:10780000DC4FBAD7921BC07DDA97C2E9EA06DDB633 -:107810005FD6A27EF916D7437AEABFD03563737973 -:10782000377EC6CE7A18371FF6F9E247D67BD01FCF -:10783000D77F7DEC3E0D08C4965F4BE17AC274168B -:10784000F53E1FE7D37BB90BE7B395D17C0ACFBEDA -:107850007F573EEAE326AE87C48FFBFB142E3F7FA3 -:10786000F52BE887F3193DD7C3016240D7F3043DF8 -:10787000BCA2703D18FE166601FECF4305A277D765 -:10788000FB7971F390FD2F1570FADC9CB40DE5B90E -:10789000D3C8F1FEDC92C38F621C53B63BB344D312 -:1078A000CAA3FCCAB3D6CF3F9401FB5FDD9A4A76E8 -:1078B000A67C5FFDECC1B41FC2FBF33B540FAABE14 -:1078C000D5539F7E6414B67B561FC47962BD06FDF6 -:1078D0009F0FBE9684ED666D720C437F89FC7EF629 -:1078E000FA9BB5F2287E7AADF424E9BF5AD8C7BB1B -:1078F00046768CCD0278CF5BAF78B0D9BCE0F72765 -:107900007D0F759D4D7A0FC6374A54E6D50F23D3A8 -:107910007D323EAB5B5F3A9409F575FB4694E0BA65 -:1079200056E9BCB70D467AD962203F58FCFE189D37 -:107930001C7FE1FB900EBE5F75A7AD0AE322D06FFE -:107940003B960F146ED3A31F3FE92CF037FEFE9831 -:107950000E78E6D9B6878680CD02786C6B42FAD86D -:107960008B8E0B1CE7053DC90916E2EB1825FCCFF1 -:10797000F3FEB3C5A8C2F3ECD96549A59CFE689F88 -:1079800090A93B617D554F0E267A9DBD3E96BE6403 -:107990003B39DF3981D8FA78BC28704A7F052B8CB7 -:1079A000C6AFF87629E3FD46A4C7EA45C0CFA3E8F1 -:1079B000A6FA74B311F5AEF871508364725FF58462 -:1079C00097CC4DEBB5F0F582CA6B86F59EC37F71FF -:1079D000BFB98276FD5C8596C8E65DC7CADD00CF7B -:1079E000791359053E253F3C3F323804DBEF35849F -:1079F0009FFE25F1C144E207E7EDA124F42B650ABF -:107A0000BFDE79772809F9DC4511B7C37A2CCF6D31 -:107A100003790074FDF12746920B4B83079370BFE7 -:107A2000CEBF68D1E9605F3E6E4D29437FD0F9E05B -:107A3000EF92705DE7822965E8D7EB894FC4F33791 -:107A4000A90F9CC47F5E0F7A8F531BEB44F86290A2 -:107A50002103E44D4A7D517D37742FBF731AEB8BA0 -:107A6000304F23F2239B671B8713C5F33E3B9CB229 -:107A70000DF75BF2D94A85F72FBF9FEABC3ABE5A91 -:107A8000B16A00C5993E63EE5EC8E7EF46DA80F959 -:107A90001DDE5FD00BF50DF9FEC134EF3D4EE8CF92 -:107AA00055D641F901AE71CCD3004D3FD07BEEB736 -:107AB00003FCEF6520FFF059EC3392DFA63195D639 -:107AC0003743652115F07D06CAE72154267D68C637 -:107AD0002625D000EBB977752CBC66B598BAF004B2 -:107AE000FE9BC380B122216E8A6A07FDCF41390C0B -:107AF000FB30D7CC4209D0EFDCEDB1DFCD63219A6A -:107B00004FF5F3DF98BADB8FBF8AFD78304D5B8489 -:107B1000FBA14C34D3BC7EFC824272D229FC9591ED -:107B2000C77A0530AE364FCAFD77F8BED53D50A9AD -:107B3000DD0BF87771D10CEDDE144A3DD1501F6199 -:107B40002D8984CFF3CA592807E637AF4D090D4E6A -:107B5000EAEA8FFD46E1761EE3F1CEBFBEC3F7F140 -:107B60002EA13FCD84D7A88FDCA0E3793D910D0AEB -:107B7000C9D751CF2BFE44E0CF33CD602A229F12CC -:107B8000EBC6F6BDA03C9BF9094EBF74E6D3FAE6FE -:107B9000B00E23A7A340431A8C5B7B167813BB1A45 -:107BA0007CB89EF6FD73E6A17DDF82734E457C288E -:107BB000213C91EF414F6296E4CBBFC7FDD3A2E0D9 -:107BC0005DB529B6CCB647957BE3FE40396ADF6ADE -:107BD000777E63D2BAD9AFC73AE55B60C084C1D1C2 -:107BE00074C2F5F013623F1FFBFEAC0CE44B6B500C -:107BF0009FCE141D8C443ECEA49F256486FEADC34B -:107C0000598CDF05F43D2ABFE2FCD1B8F5D98CAD23 -:107C100033F8287E3143EF3D84A1B6A274DF6F11A3 -:107C20004F66E8B45C95E0AA1590FDBD88E3C3E318 -:107C3000C3EA07D4776377CBF9AF5382211DF2A74C -:107C40003D5C5F492C8E187C5174FF9EE0BBBD0EDD -:107C5000840F6521DEBDA4509C6083C21A1580B3D9 -:107C60000BF619E5D306E5E42194671B6E75B306A0 -:107C7000A82FDE3961FE6B64BB5B29CFA86667A9BC -:107C8000BEC646EBE7FA7342FD561DD4A7DF533854 -:107C90000CE90DD67DCF44787FC2E9A67965D83846 -:107CA000FEB896F9F317A09FF88077FE6B8877836C -:107CB000ADE48F4B07582526D3B309F562175BAAAD -:107CC00060BBE5A90ACF83A864537E3388B059ED21 -:107CD00095CC9FC7E0A9A8AC11FDCBE92AE8D9FC57 -:107CE0007D238EF358129F57AA4E7FCF04D4F3877B -:107CF000F172F26245DB46F26C2DCD2BDDC42A70A9 -:107D0000DDF81EED029886D64AF5018253FA98FAFC -:107D1000229C477A1FFE741A43D9D8CF914E3CF16A -:107D2000E9507E2C147AC0C2AD65E9C8EF8F9C374C -:107D3000ABC8D78FB8A43E1BB2A13ECBFA16F2F661 -:107D400042DE2E2C1A938E44EDCC8D6D77D1A0F5AA -:107D50001A8E72EBA89EE24F7FB169BD1CD0EE0671 -:107D600023EB36EFAF572ADFD7BA2F151688F26309 -:107D7000D44DB944F642DD976ACCFBF34BCC2C10C2 -:107D8000E5C7A8AE3A3016DBD5B08EE5888F35C191 -:107D9000041688A28F1BACDD8F2BE9A2EE4B3DF3BE -:107DA000773BAE31F6FD9729CC9FD25DBBB4D8F7B7 -:107DB000B08E98F2EE2F3AD781EFD9C87012FA75CB -:107DC000C7A37C86F2C580CE6F00BE75C4C0E5EE49 -:107DD000057B38462E5F7087B95C46BF958DCBB367 -:107DE00009B8CF6A24696262D738B21EBF4F8E5A73 -:107DF000EF85294616A2FD89D03C107EFEFE8C6DD3 -:107E00006CFBD488F93AD56DFB097E126FA2E1E8CC -:107E10008F8E8335748474C033C6A56E5F35680059 -:107E2000A0E001C91F9E5EA58D867ABD2E865F24C7 -:107E30001477F20F62578F61548EF8CD33ABD06F49 -:107E4000DB55E6EDBBBEDF310EEB8B07F1EF27A76D -:107E50003EFBE6324A6A69E67A971AC9F5264695E4 -:107E6000CD71651B94074795ED71F5CEB87A575CD7 -:107E7000399BB73F9F18CAD57B18BB27F585712A58 -:107E8000F0CDF319A16998C7B6BAE1D7E3CA819FCB -:107E9000D51473395FDBA678485C09F8D57AB81E2B -:107EA0006BF3848D983F9750DC7108F94BF56EC5E4 -:107EB000AE003DD882AD212AE377EEA8EF820A7D9D -:107EC000571D3C49DFF5D87FA18EE87D55E129DEBD -:107ED0002EF821E9132B1AE753BE808C87EB994FBC -:107EE000CB52BAE2E192CF5EC8D00E129FDDA7D886 -:107EF000913E3BF114FB8DF243C9F67F1ADCF64745 -:107F0000545712167EBA14F5EBFFACF97004EA9BD5 -:107F10007F12F2649D121880E36E64BE01284F7FC9 -:107F200054D36FBF0EDA9D30843763CC6F4BEA6B4E -:107F300004BF1389E11CCC0B0C3CF6EFBC9C1ADE91 -:107F40008CF0BCF458C738CCFB3B9113CEC13CC07D -:107F5000EDA9FFC5CBFDC29BB17CE4B133BC3C387D -:107F60009CA387EF7BFB3F1C570EDF3F65EF9EAE68 -:107F70001F13FC44CEAFB6AFD69C8A7A5E359743CA -:107F80009BC1463303DF9C36F7DC0B4F011CA6FD7B -:107F90003481F8D953E7278DE3F682DFAB96A03F13 -:107FA00099FF919C247EAF929E9181B231B96B3F33 -:107FB00012733BDC2447AEAB6F45FD257DDA209282 -:107FC00023E54EED0B1C573EF767C113DA7F916A2C -:107FD000E7FC5BAFA3F87AFACF1249CF5B63E1EB22 -:107FE00001BAA1FDB589FDF89558CFAF52B91D7AF8 -:107FF000BFF366EAE72EA1DFB7AC0C3C6B01F81FBC -:1080000097793B6BB9BDF0C3ADC057808FB738B41B -:108010000CE4273F147978927FE0FBE4283BA9A584 -:1080200008CAB62E7BB86582966175E2334D8771BA -:1080300024C98F5AF2F977522EA537F071D3D70C95 -:10804000D886EB4850B93F6CE694826D4B492F9827 -:1080500048F3659A96A1407FA7E7F4D6A19F4CEE1E -:10806000CF9ABE5A3BAD47C419E43EC9FDFC2295E8 -:10807000DBF733F4A057C03A2DE93EEA0FF48C2128 -:10808000C21F477AC617B8C751F0656A7804BEFFA9 -:10809000FF084E1F7D1B70AA5904FC427715FC4255 -:1080A000C06F9D1232A4737E41F63DBE47B9D3EE38 -:1080B000F47D9D1A95AF33ED6735A457CA7925FC39 -:1080C0006457C50FD8E57416AFF799D2F87E49FD0D -:1080D000D423FDAA629C13C7CD144739610C12DF6B -:1080E0003C0176D552E42F220FA0E4A7F38EA07DA9 -:1080F0002AFBAD49D373FFB4DC77C5DB3A2B1FF302 -:108100006298DF8CEB9860A47D9772B7C5C1F35C71 -:108110005A1EC8A23C978B2CCCC83F3B92117F04BF -:108120003CA0FAC8D434A27F68EFB760FB39D751BE -:108130007BC00B3FF187A956B2835A306E8EF55340 -:108140000B03989783763CE1DB1C1D8DDB0DBE7025 -:10815000FF777F9EF721F126AD81FB9998AA0D99B3 -:108160001025E76F4DE3FB9C501C7EE93F50AF5D4F -:108170006D21BD16652CC5A89AD3A91FD8FF6169CA -:10818000DC4F417876EF238922BFCE5382705D9118 -:10819000C8F1729385C7CF36811E4D7C51E0AFCCBC -:1081A000EFF3097D2F5CA54B427D414B937633C89D -:1081B000F512E1BF87FAE961E524DA7FD3FDFA9091 -:1081C00009FDCC4D376BE1283B06FF30FE788FE090 -:1081D000AB6C3D233BEB1EFC2E09FBB72661BCF5C7 -:1081E0001EFC1EEDC8C537C7C41527A671FA96F345 -:1081F0008BE7FB13E5BC9A1FD7A2C791FDC7F70712 -:1082000076EDA4B4548273A817EEEF523DED5FFCF7 -:108210003CC3EBB91F3EBC3E8FF04EF6D7D33CFFBC -:10822000AC8FDCA7801C9C3586DBFBD2FE9929EC49 -:1082300071B638D6BE43BF4F67597F7939DE5EC409 -:108240007C81D8F65C6F4918143112DDBA9598F923 -:108250004B78F5048707AE116E52EE3D6E013A0081 -:108260007C598F7995805FEB1F482039E6340606EC -:10827000205E6DC47C1D92A7DC8EFFFC48AC3F26BF -:108280007EFF7E9E26FD6AD7667F3F8278D18DFD78 -:108290005D678D6C41F8D75919D1E7857D89448F89 -:1082A000AC6F781AE6D15DDC6B62480FB54AB80056 -:1082B000F9E00545ABA4764B13DC4897D2DFF1C15A -:1082C000CBDCDF51873B03EBADF3FF17E571D5ED59 -:1082D0008EB5CB2FC07F5540471774E112EC4FF29B -:1082E00017D0CB35D2B7AA787CAB56C7FC68B7DDC0 -:1082F000A09B3E87F38D4CB68DDE9F2C5810A5F7C2 -:1083000043BB762599A323D261B5D8975ADD296A54 -:10831000578DF958B83F68BFA11F102BA3FCD6B5E5 -:10832000AB3FA67CB0DA9DB1F853DD855FCA370A52 -:108330007E17856FC41FFC82BF30EE8F29E7F1F9ED -:1083400044514EA8E8A0FCB03AE18F493D101E8B85 -:108350007C2AB138C8A6C3B3EE2CD75F46B56D3DB5 -:108360008876BAA3A22307C9AA4EF84125FEC87988 -:108370005EDFB6568F76A4D47BA2ECD8011363FCE3 -:1083800018CBE83BB48B71BC30BECA40F4E2F27249 -:108390009D9097096860A35C6DEE4F7215E51EF223 -:1083A0003B695723FF43FC2A4A2F3B8EF4FF467A52 -:1083B000D91F399F04BC453B018DB4EB7BC63F09F7 -:1083C0001FD90EEDEB7FEE9F147C9C71BFE48237CA -:1083D00052FF291D9CEFE4AF57F44BA623BE2F504C -:1083E000DCE988EF17057F3CBCBF80E2A0F2FD19F5 -:1083F000BD8FFC8FD2FF3507FD7EF0AC16FC689672 -:10840000F097CD927EB2F5B1F15AF4534797E74A0F -:10841000BFD90E53571E13FAA9CA592811FAAB41F6 -:10842000BF1B3E83B1DFD5B2087D57B7FB1B534C52 -:108430003CB885C3F11E814F8EF2801EF9D8060B21 -:10844000F79F49FE366AF156C2935EC3B4FC87902B -:108450006EDE3090FFE57F0B3C90707930ADECCF55 -:10846000B8AF56BDF00F3E6422BE7E1AF48556E1C9 -:10847000F7998876F212A6E13901A6DA73A3ED68BE -:10848000F95CB5D75285F89899AE8BC1D7F634030D -:1084900095C91F46722381F402607343105F4B7AC3 -:1084A0004BB9CD86A01FEEA4B0EB6BEFB4F9B0BF13 -:1084B000B08EF3C5FEE97C9FFBA7F3BC5959EEB41F -:1084C00043053ECA382BFAA5A2E314433ADBAF15A5 -:1084D000FA2EA3F5AE9B23F2E83BE942477C2E61DE -:1084E0009097E4C30DBA32E273918F6C6E844BC5E2 -:1084F000C7D573701D9F4DB1D279C97B859FFCC6CE -:10850000749E8726FDDBD7EA272F4DEFC4C7183F9F -:10851000F95EC117F7323E5FFF592BF7F7AACC8FF0 -:108520007C726F704000E75B29FC23A87F21BF8E1F -:10853000BCC4F791A95C5FDBDB3638807474D2E091 -:10854000DB3013FD4DAD06F21B3235F0ECD3D8CF46 -:10855000AB191ECCB3BAA08B6CF93DB4DB7BF657DC -:10856000591857DB2BE21BD5C65001E9F522AFB4F1 -:108570003A2954807EAA57C47E555BA10CEF532C38 -:10858000BEBBD253BBE28FF81DBE3F15E076C329B8 -:10859000C6F1C0BF9AC79701BE193371BE2BD3294C -:1085A0007E89FB82FBF0C1BEC1B4AE7506D17E0FE1 -:1085B000F7732B130BA7919C59654A41F85FF41A86 -:1085C000292FBA6E0DD76B67E8DC5B1621EF7D357E -:1085D00081D637B3E528C595EA1E994DE74DEBE600 -:1085E0002EBE9DFD93780BCAA968FFFE0516C9250E -:1085F0007BBDAA773004F3B8D036C0C3C3A5FCFC5A -:1086000052ADC8BF3D6D601ACE3BB2CF10E8EE5CF4 -:10861000654FFD9383B384CB4B1CA72E3AAE45F236 -:108620002536CE75A5F20543B8E001187F758A6F2F -:1086300075BAD03B115E75AF66101FFDE0E12F7279 -:1086400049EF69E6F194D3066D1AD289A33C649C84 -:108650001EC55FB70B3A9E6112FA2DF0C168BA973A -:10866000F52565B174269F4F0A7A4B14791897D770 -:10867000CB3CBF492694C7DCF585FDBAF9393411E6 -:10868000DF1C7536B21FF3D9AA8345143FCD5B1C9E -:1086900022BA047887D03E39BD2191F3135826F6CB -:1086A000336B2423FD7A969EE795CC3281BECEF5BE -:1086B000026A7F66433AC1A16419D753232F29C4A4 -:1086C00017659CB792F1EF77359EF4EBA17DE50E2F -:1086D000A508582BAB6C2CA5BC93B99BF269FF473E -:1086E00009FE3BC3A4156C407CDBC5E384301ED976 -:1086F00005D5985B378CF89211E56BD50E85E22590 -:1087000072FDF1715516888D478D0A72FE8D728348 -:1087100045E993520EA1BC60717A6E2C5EF8AF4AA7 -:108720009EC6CB8377D3AF56AF8C95A7EF21FF4A78 -:10873000BD5C9E82DD701CF1B0A48CD371A495C782 -:108740009F6A583D8FC30979D6B92E210FCFE8B95A -:10875000FC9D655A4BCF8BE93C0E359785451C2A0D -:1087600062C4F9F5845F17D3657E7B2C7E49BC8A91 -:10877000209E417FD56759E8BB305EF56216AA1985 -:10878000C29F894348BE73396FE6721E9FD6AB9075 -:10879000F7F1723E5EAEC7CB73146728B7253E452E -:1087A000C723504F1AB538A0E7FEE66C3BE665CA12 -:1087B000FDBDDFA939B253BBF4C0BA6366B37B28F1 -:1087C00096BDACB70DFD68A59B73A0BE4EE5E7C393 -:1087D00013004E5BE1FD666187ACCAE174E612F9F5 -:1087E0005706D5CB8A6CB84F1DE43788A432CAA788 -:1087F00097F0DD9C08DF613E420EC78FCEEFCDAC17 -:10880000D11AF57DD95E0BC9A94B7B12E91C205307 -:108810007D790EE82FED4F603F40F9C2DE44D21360 -:108820002E08B9E194FE19B69CF6A38F8BEFB39F87 -:108830009565A19F9B29E3B2189D8FE7FA6C8DA3E4 -:10884000A7F884A8CFEFB893E39989E4F52547F812 -:108850007E2CC37C28BF3BCBC5F7BD6EE798A29F9B -:10886000615E86D7E6E150F515A1FE61D22FBCD33B -:10887000ACC77B1216471E8075D4E4D8286FBC3C69 -:10888000EFFD77A742F9A39D063A5F3AE7A949BDF4 -:1088900042F899AAB9BAA393390143CCB9C5793B37 -:1088A00062CB35C1D8725DDC3D058BDEDFFA667BBD -:1088B000547DB94B9CEB74330FE6BD33FDDDBD7CBD -:1088C000DDF05DF9FC6249E0CDF67E9437789B8B54 -:1088D000D3B311F5A3E9880FDD7CA773F17D35993A -:1088E000EACFE2F903D32B26BACF20DDE59BEC4A91 -:1088F000453B2A7208F7D394777E08CAD3B2BCAF3F -:10890000286E78E941E641F85CB294929E746983DE -:10891000C58D76634BAE8DF0A0E55525A070BB628A -:10892000FC08E0AF55341558EFFA5B3FE2876598D5 -:1089300099DF7F0056950BF9954676DE990956FB2F -:1089400032F8AE6A3D97DBD5AC2309F9C006B97F92 -:10895000FAE78D66F8677EA3366029CC779ED74A02 -:10896000E7A4D4AF55BA1F600576196597D4BB3814 -:108970003FA831878DA538FE570B2BD00528FD79F0 -:1089800026834FC3F37886DD45A12C78357BD14112 -:10899000B2BF3AE3F6FB38DF9AFDC07E7AAF4CAC4B -:1089A000A0F59E81F5225C0E6E30D17ACFE4D8C856 -:1089B000FE3DB399DBF9B3EDC68099F4962F53F0E1 -:1089C0001CF399CD06BA3FE07278DC42E7893FDCC0 -:1089D000F43AF91B3F647C5CFF4E3DE93D1FDA230E -:1089E000252184A3BB3E09F5E6AAF573E83CF2EC29 -:1089F000CD7A2FF2B3D99BEFFBFDF5E8279B785793 -:108A0000312EE926C7C234B7ADAB5EEABB6AF2C805 -:108A1000A7910E6FFA7A4CC74DA8776D063AC9E751 -:108A2000E71D50DF6FDF7C0BE9B7B327581DB82E69 -:108A3000F7A6A7C6A21CFA7042269D9F9EFD82C281 -:108A4000F0CA8CD98E4569F87EB6A27ABBC3A7A1BD -:108A50002E7EEEB934CFE609E1777FD4139E005D18 -:108A6000DD8972B866B381F4E7F689C7DF9DEAEC69 -:108A7000A22B65E2FADB4761FB670CD4BE536FDAC9 -:108A8000F43D892F2C5482F619875B3C9D99F21690 -:108A900017E0BCE2E96DF6B2FA021EA7BB36BA6374 -:108AA0009B38DDFD9B4BDCFF71F574B7D7957AF5EC -:108AB00074C7B29363E4F0E5FCCD4FF094710EB34C -:108AC00087694FD928AEAD29C07F3FC080FE087CA2 -:108AD000F27362EADF16EC780BF1D8E53B82F3C85B -:108AE000635A11CA4D77C45E8667C06C422F649B7F -:108AF0004CD29E203B615D2A7B7A55945FE4CFA2E5 -:108B00003FE0037FC47E2EBCF7D521DCA7DADCF37F -:108B100043D0BF5DF7E55F282E6A6BE371759B2735 -:108B200042F90606A797F050F2F73A0F973FF1EB9C -:108B30002AC8E0F6619D3342FDE833DD546E1171C1 -:108B4000A48D8BACE437DEE80C58B8DFC3CF503EC1 -:108B50008D1FA9E7F140A1B77D4FF85DCDC507197D -:108B6000C601D9689E8FF756F1413505CABF1F79F6 -:108B7000B387CE51163FD9D41BD73DDA20EAFBD0BC -:108B80003D27FFAE9552FD0297DE8DF43DBE98E77E -:108B9000A3B2AA24F2E7BC55FC81F3DEA8F97B99C5 -:108BA000D96D03BC9908C41A9DFF78FB688BDB164E -:108BB000853F9F352B155C7F76F79A3C98FB6B4879 -:108BC0001E17C7C26381CB48E3BE915ECA3200CE96 -:108BD00037DDC8F7E3DC0BA600F2C173E25C523C60 -:108BE000FC7A6508FC5107C4E427388DC15C949376 -:108BF0001F2BB1DFCD6DD2537EC09C26850560BC96 -:108C000073CFEECA457EFED153BB72A747CD27FE78 -:108C10003BF9CCC888F57FC6FBB37BF263CB7617F4 -:108C2000D7339FB94F57FB8B557F273FF6F436E17B -:108C300007D7B4BE4EB4AB44FBF8FECA057E28BBD2 -:108C400015F29F483FEEA9C34F62C4A873FF2C6D75 -:108C5000F9BAE83C52F91C25F66D12EE1B2CC5D270 -:108C6000C4CB3DED574FF47842C821B96FA79AFAAB -:108C7000F442381A6B6D2AE3E7030B51EFDFCCACFB -:108C80001EA4A72F443EB1D30A4FD0D38C992E1BDC -:108C9000F233791FC34FAC49DBF0F985C837765AF8 -:108CA000E109FDE46416527F5FE8BC641FFE44DF07 -:108CB0004CE7466FC9E0704867214541563BEF6578 -:108CC00085F2E49A62E19DD6C0E548A4D248F24B11 -:108CD000C2FD86E9F7931DDCCD7EAD473CCA1CC9B9 -:108CE000DFF933F2851E1DA678896524B3A39FA002 -:108CF000E17A3FCD43EE571D6FCE943685F467CCB5 -:108D0000F34948A6B8B05F3C992D9975C6491284BD -:108D1000DDCCE2E222E9A077633B394F2853BED095 -:108D20001A47B0B980C795492FC57EF1FDF4412A95 -:108D3000C515B09D71D895F1AF134F453EE878F950 -:108D4000BECADA6D1C663C9ECBC27D00F9887A21D2 -:108D5000F31862CE656D027D1AED3D19E7D6EB8200 -:108D6000452EB24F3AC2E887319698DD286F13F44A -:108D7000C142DCBFF8B837B4CBE7F916D90E94334B -:108D8000F2DC55EDA2315E8CC781FEE137E3FE4D8A -:108D9000E0FB57FB4029BD5726162E45FCAA5BCCAD -:108DA000E87E88316DAD940F5657C1F5B1BADD2715 -:108DB0008D0CF077BAF00B31E1174F13FB7A4AE8CC -:108DC000DF5D71BDF016CCB76F99934DE7ACE3F35F -:108DD00067AE35AE7B31110032342A5ED7CBCCE59D -:108DE0008CD87F49DF327E9738C89B8F9AB861BD97 -:108DF000E98875C4B5E4C7841F2ECFFE27F931FE7C -:108E0000FADB313FC68C5ABEA8C769801CED3C47CF -:108E10006971537CAFB31EEFBF30EF56C47839B7DA -:108E2000DFAC529EAF289F5A8D7EB1351616335E49 -:108E3000F4FCD4B8FE0DD0BFCD2DDBEBC6637F8F25 -:108E40000D13657FE56ACC075A6388ED8F50509EFD -:108E5000FB34778DB7393BF8F0EAD15DF21CE4FBC7 -:108E600061941752AEAF383EBE79A81BE9EB73CAC6 -:108E70009B96F2B9CEC9F365E2F9D8DB829F835E97 -:108E80003C1645EE8A29F3E9BE88CE38775BA58685 -:108E9000FAB08C73D72DF652FE34E803FF9141FAF5 -:108EA000C0F933FB19EA9DE7C82EA8FB52E5FE2660 -:108EB000D02BF0FE1F735B29F955319DB75FD4FEAF -:108EC000CF15720A7578A487BA4D3F784A0FF543DB -:108ED00033B530F56BE8FEFEAFBF65703DBEAEB09A -:108EE0006C03F203B65DA1FBB756157E467A47EDDB -:108EF0009E9B4744E7FFCFD9FD18CF1FDF61E8767F -:108F0000FD7FCBE07A6AED9E97C86F7A2EC08F2DD9 -:108F100055A98195A8875655E950F362C581CAA91C -:108F2000A40F4C8175C0BAFE9CC1E153B763921F78 -:108F3000CF23D4C17F0ABCDAE89D4576C1C6296635 -:108F40001BC697EA0AA7CF27FCB75B355C7FFC3CC2 -:108F5000BBE2E9563A37BE6AB7A102F5A812D09B28 -:108F6000FE0DE69B933CAEC2037C294BDF5AF463B3 -:108F70001BE617742F97B764713DA051F1FAEF28E3 -:108F8000267F298BCE57CADBCDF5337BA631C63F72 -:108F90006FCFE4F74C8DF6778C419C7B550D27A065 -:108FA0009E5CC7B44FD1FE655E9B9BFCC48CE713EF -:108FB0003897B8C94F6C76867F3E94F42895E2E9DD -:108FC000D2BEB8B087FBD79665FA7232D13FA80FF0 -:108FD0003F7A07C2EDE7AAF037733E933BC9360CE0 -:108FE000FD611667F8D10A37E519915FA2D7771BA3 -:108FF000691F5E75323BC2678CBF5255A2E48CE498 -:109000001B633ACF4D39C90F5BC6D91AEB07BB7545 -:10901000C64C28DAF84D4A979E70F8ABC92ABE9420 -:10902000FA83CEEC233BA77C0AD88D8897CB238785 -:1090300074E8F7777690FE581354689C9AC2DF5014 -:109040001EE03C916FD699F7A586290FEE3B990952 -:10905000C28FD9C8F19275905DCC9EE7F007FE44AF -:10906000F9715D7AFC526A27FB338A78458DF0E30B -:1090700000A0A8BE2C53FAE19689A7CCE7E3E3321F -:10908000D55D12ED775837012409CDCB9D84F37D52 -:10909000C4EABD2D13E6750AF017D779AA2981EE27 -:1090A000035BA77468E8D7F417F1BCE1783CF28958 -:1090B000717B1D888C457912D9D353DE30CF13DEF6 -:1090C00030E23ACADB2FDEFDE958C40F56C1881ED4 -:1090D0006B775F5DDEF04CB11FFFCFE40D7B146D4D -:1090E0001B3CEFCF7470FD4AE60D7BF87EC9786BB0 -:1090F0007CBEF0858C90CAF3FAC25B9E42BB7DB702 -:1091000089F261C6EF7EFD18FA35C79B5990E2CF10 -:1091100071FA43C4396909D2C9C54FCE6C798861E7 -:10912000BEF9CB1E7E1E36561FE8C91EA098499474 -:10913000DDB83653E8E7DF923D20F9759DB0AF3ECC -:1091400056228F14E0FAF6E9EDDD9D5FDA22C7EFD3 -:1091500029DFA5ADFB7C17E98FAE08E7C7C4BF7652 -:1091600074F6776DF1B4E7507676134F5345FE9A57 -:10917000AA70D6C11C3CBF49C6D3D4D6011427332C -:1091800075C5D342AC9B789A2AE2532B0C5A25F929 -:1091900069F699DCDC8EF612FF6A6C4DF5207FAB28 -:1091A0009B7BEE453C7AA13AC6BAF09C5FA3807FD8 -:1091B000F5D5C7D3DA33BB89A76D157ADB0785BA36 -:1091C0009011E0BA9571FEEB6F9371351DD9B59191 -:1091D000877368DECA4433CDFB83574DDBD03F3500 -:1091E00043C6CB5EE5FEB519222EF6C1C402F23F9E -:1091F000F504E7194DB1718777059C2F594AC94F7E -:109200007FFF2F26907F7E16FAF7FBA07FAB59F8E1 -:10921000EBB99FCFDDC4EF3170EF50E81E59441316 -:109220001DE9A476BA4F761EB0D18DC87AFD80357F -:10923000DF81D78A4E417DC8DD086550FAD595AAF1 -:10924000DF05EDB61E4B20BFE20AA75BE4E7F1F8AD -:10925000B57FB512E8C7FBA5FBE3FC8D3A0DFBB962 -:1092600094C9E57C5296B1DBFB281A0D224E22C62A -:109270005BCA60DFE1A953F87385B89F301E1EB248 -:10928000BF4643BD19FD7B911C7E0FCD25A33685BE -:10929000FCCEC90574DF5463627D5305AF279ABDC8 -:1092A000648978A9FEBB2A5748993B99F2A83345AF -:1092B0005E621C9C6736C796E3E347F1E7E36630DE -:1092C0005FFF8C3E979F1F3B8FFC16FABFB42A5F4F -:1092D000EC8B87E2288D06F71FF2290ECBEF935A0D -:1092E0009ACDE1A6CBE1CFDE8E72BA1710E885EBFE -:1092F000718CCFBFF7779D0AD24BA383E3ED7F77C5 -:10930000DEF1F34DCB2AE07A8D83D36BE34A25C09F -:10931000E1C5E77DB57E92E2AC6FD74FF281E2798D -:109320003A944FDF117FF03F6C20BADB6BE1E75ED0 -:1093300025BFA28423B43F85BD7B232AD318573D84 -:10934000BB9CEE85DA58D53B09E3AE6326D9681D90 -:10935000B5AFF273D5358BC3B988D7B565E182FA5D -:109360006EE08A03A892BF42BBE94EC6EF176A8A35 -:109370008D23C6C78757A768E3B346A0BDF441EB6A -:10938000EBB8DFAD1692AFB58B234FA3FFC097E2CA -:109390009B9405F871FE81E36315377D46FAFCC5A1 -:1093A0007DFDE93CE8F4C6D873716C756C7C923530 -:1093B0002593DF9DB5C4BEC7735B31DF5D16AFE497 -:1093C000FACD3AA36F00EA9F37DDC8F3313E99A387 -:1093D00063B8AF9F58F8FEFB1F4E14FCDA53102DF4 -:1093E0000FEA7BDC5F683708F302789EAC6C5F8322 -:1093F000FB0BFB5A2DF6F79397BE5380FB7BBEF514 -:109400003B05B8BFEB0CCD1AD24751BA6F21C2E36E -:10941000F4CD5ED20F655EF0D5E25DC3B78C77D731 -:109420002A8F9BB3FE35798C7FD17E9357BFD2FBB9 -:109430002D245FF879E22EFFDD39BA57EDE2973A35 -:1094400005F9714FFDE50B3DCF65667ED4C34ACA71 -:10945000C2F45DC9DF750CF541A907C7CFFF4931DB -:10946000FF9D599A09E5A0F4F75689BECD81CFB981 -:10947000BEBD5D217FAED9ED4F1A45F6D5CCE17A60 -:10948000E22FFF46E742589B62473B65CEF6A55464 -:109490007F61F70CAAD7994321B4C76AA01ECB2BD2 -:1094A00046C7E6791B77F27890B47F611E7AD4D7ED -:1094B000129C1123E2672DEAD730C55A95FBBD6B8C -:1094C0009DCCE367A80FC7DA8B32AEBBD1CBEFEDF3 -:1094D000D9D8A6D0FD5D69465F7E36EE6B5C7C77A1 -:1094E0007F96760EF14EC6E71F4CD30E22DD3A8DE5 -:1094F0002C97F2F90CF25C5AECB9CF9EF2E48E761E -:10950000E2C195F4A8A9A42FFD9579495F7A072FA8 -:10951000CD243DEA4ED2AFE4FBCBF3E40231F1FCC3 -:1095200059E29CEE2C714E17F97E288EEF4797ABCF -:10953000A3F2E442DDE53B44E5C9457F179D2717CB -:109540008AE18F9C9FA4EB17501CBD0EE866D1B03A -:109550002EBCAE66E26F7DE4033A37B4C3447EBAF4 -:109560006A91C75B57758AEC9F3A3C87C4E95BE315 -:10957000E7E9B97E550D7625E5330763F37D95EC74 -:109580006F57FF96ED7AF2C7DBB2A59DC8E95BAED7 -:109590004BAEA3BA4DE1F41837CF787B3ADEAF2E4D -:1095A000EDE1ABE573EE6F79DDD7CAE706C7C1E140 -:1095B0005FE57397C527FA46923CDF427CE223774A -:1095C000731ABA28659E74D33E9E273D566FD37892 -:1095D0003C54CFF325E2E3C2EEB114F7947168F383 -:1095E000CBFAC0B27C6AEFC17CB49A7D8994BF503B -:1095F000E5AE223D3E3E1E3A97B58EC5ADF82B3BFB -:1096000042E7DEFEBB7908DFCF4E74129F72B3FCD7 -:109610006BCC43B83BFB1AE2A1076D9FA7F8A2F001 -:10962000A56C101804837ACE379B2BF63F41E4AB30 -:1096300098553F73447DDFD3770BB2B93FF1A0C893 -:10964000935A939840F737B88CFC9C874BC7F3B973 -:1096500086667A17E2FCCD6EBE9F4FECF901C373AC -:109660007B4F1882749F82BFC6E641B928FD58B26D -:10967000FF76E15FBD5A3A5AF93FCC3F1E957473AD -:10968000B5F1BCF5008328FA8AA7879EBEEB89BF97 -:109690006CCFF63EC1F1421B427190ABE44B09C561 -:1096A000C0B751EEEF34B9D11E41BF0CC9DBD5199B -:1096B000D29EE7F742ACC921B9F88985DB27F2DCF5 -:1096C000945CFF2EB9FE6F496FB4A47BF764437FAF -:1096D000A74B353A27B12291CB97C8B33C1F29FE3F -:1096E000FC50BC5C91E75FE478BFFBBFCC578F7D3B -:1096F0004B7C15E42CE91D3DC67D2FFBDECFEFC171 -:1097000029EBD044FE0D9DFB90F3AAEBE0797C673A -:10971000C5FCE4FB90D07306E7681F215E9D7FCFF8 -:109720006CC6B86A7131E79FB55E1BC5256A833C7C -:109730005FA77631233F823C273CDBE5FB1CF76FBC -:10974000C5711BDD5F5BBB7B6B536FCA67F091BE5E -:1097500078E13DFE3EDDE5FB02DBD52D0EC7C43FC3 -:109760004ABEF97C794531CD97FC004E53ECF9ABFC -:109770008C1CCE6FE4332D47C217EC1DF8EE7C1520 -:10978000CF3FAF736AF652CA63E0FEF5047707F97C -:10979000956A77929060940C8BF53FCB26BCA9DD3F -:1097A000595A44F736042D45740FD19FF8BD5DE733 -:1097B0001FC80CE8B93F3E2967049E3B09DC8A7A42 -:1097C0006B1E8C832AEEF9D65B8BC8DF1847779225 -:1097D000DE3ACFDDFED01C6850BAE8719D81CB49DE -:1097E00029DFFE91EDE6F110A7C8476C9BC066DA51 -:1097F000BACA36676C9EE6CEAC9BFF81FBF38F6CDA -:1098000055C4D179DC3EDF0CD66CEFCBF1305FC4B0 -:10981000ED27887C0BE63777E559F4BE72DC5ECE27 -:10982000AF93EF8BB87DC297E27722EC46C28BC430 -:1098300026CE3718E005EAEDA3231D63F0BC5BDFFD -:1098400096D06884572F043F9EA361E19F0FC5788F -:10985000488A3A1AE3215B160D3B80715A7565C739 -:1098600077716BDCCDF632345967BBBC37E4107FBF -:10987000A92F44FC2FFBA381E747AE4C2079DF9250 -:109880005B4DF991178E9B62CE23C53FFD6C990B02 -:10989000FD50BD9BDEA67844E24EA5DBBCD79FE61B -:1098A000D844FEE43217FAB5129B3AFC23D14FF3A9 -:1098B000B0C2EF0085D92B2EF427A83AD43B66EC32 -:1098C000E6E7E567343BCACCC44F151ECF19ED243B -:1098D0003EA9AEBC4D87769FBA94D17D7BF373B819 -:1098E0005FBC5F8B5D87FBFEDBAFF5DDC6E97C39D6 -:1098F0003A19573422B86A4C914398DA29E38B32EB -:10990000CFAEA77BECA53C8AD7672FD363853CEA13 -:10991000D4E7E3F0B8A7EF247E4B7CFEAD81911E27 -:10992000F65BC54CE7DE245E37CAF3075F733F7111 -:109930009EC8DF39B5EABF86F07B02647C26C0EFA3 -:10994000713584976711BCC237FA71DD3B1DBADAF5 -:1099500041E45FABA57E56F27BF2F29AFA2C1B59DA -:109960008C4F3B53600AA7F6CECB43BAF4031EF4E8 -:10997000EB060F6ECAE17952EACA04DA37752DDDBB -:1099800010CE54471AED9BFA18DF9FEB73383C65F5 -:109990007C58FA4107E7F8D6603E70E739B545567E -:1099A0007E4E4D9CAB4E5C74FC053CFFB545F8A368 -:1099B0000FBC3A907EDFE3D24A55413DF592A39227 -:1099C0007ECF6AA3D8D744B583D96DD1F87980F218 -:1099D000747BEFE3F986AA3837AEAE746E4578969D -:1099E0003B7D948FFCDDC610FD04C6ABF6D314F7A7 -:1099F00003BD88CE079FDBA348BD28461E4ABB2D6A -:109A0000DE1E7B51F2CDFF213D694F279FBE463BB5 -:109A10008BC5DA9B9DEDA5FD186F4FC47DDF93FECE -:109A2000C3347F4CDECD11B1EF52BE670ADE28F39E -:109A3000713ACF89B38005CF714C41A21CD1959763 -:109A4000C444BED27AC5EA417DA9A7BCA4CEBC213C -:109A5000563F94FB37EBBF834F99D724F3962C984E -:109A6000BF927279FE8A05F35752F07750F87973F6 -:109A7000997FD26070533E8BFF4146714965620504 -:109A8000F9FF92BD46C2BF8B2CB0017F07C03FD902 -:109A900046E7EAF19C13E27D447151BF632A34D951 -:109AA0005E87ED3BEF93AC64549FDC57CB403DCCDD -:109AB00002F578CF75E739F399FCDEFDF8FC1599CE -:109AC0004725E3CA99FD5F56D0CF8A6104CA67F87B -:109AD000B1F82E9FF7D3F22337F18DB4069E2715E8 -:109AE000B99ED9D1CF5F26F98F39765FD729BE7C51 -:109AF000A4CF75567ECFC266E669D243B93DA7377B -:109B0000EDE346E6DEAF2386DD4CBFDBF1BC53D38D -:109B1000E7A676E1939C175BCFD77D11CFAD295D8A -:109B2000E35D9CF3F75CD4AFCADA4C1C2FE3C6DFCD -:109B3000D879CF4DC082F2C495CBF1C113A7EFCA3B -:109B4000A72B5789C9FB93E3F7B43E899F57D2E30C -:109B500025FEF5846FFE32B14F271248FF90F8764C -:109B600060C90EBA4FB27D49909E172D4A508FE7BB -:109B7000872D9169C81973F2B2EEC07B502E26462C -:109B800072F11E95016EB717EF51B9981A3981E538 -:109B9000EB9FF8BE97EAFB45B6E0BD2A77E41DBB14 -:109BA00083EA713F33192BDA72E40EBF0DCFA9841B -:109BB0009777A0DC2A8ECB8B89BBFF2141FC0E540A -:109BC000BACD48FA64BA8813B272A1D763440BCAFB -:109BD0000D19451417B431F7CE0EACCF36F17B22F8 -:109BE00018E03FD6F7CBE7F9158CAF9B650B7F37B5 -:109BF0000BFBE9771DF31DF47D271FDF6912F12EA2 -:109C00003EFED197785C52E6093366CF417DC8E6C7 -:109C1000663165797F0A53ED39785F4283F4278A8C -:109C2000F22B09BE49B95172F9E8CD3F1944BF2F53 -:109C3000F3F2CFFA22DFBCC5187B3FB77C26BB39D5 -:109C40009FBC28EEA1BC2FC17777EE08FC7D9969F7 -:109C500063F14AE12929A54607E96FCFEA914FA5AB -:109C60000AFC704CE6F373947B15FC5D17790F6466 -:109C7000AA4F253F01F3B5E851AEA69EF652FE610C -:109C8000B539928BBFBFF396D95785F3BC5479F29F -:109C90007E8A3F661E3D81F922470DCD6392508E2C -:109CA000E48B7B3830C00BE5435979640F76F2873B -:109CB0007E0AC547C74FE6E771C7B1A08AFB3CD60D -:109CC000CECF878D2DCEF734C078E345BEC9D8639B -:109CD000DE24E46F637F1056F93D2111353ABF430E -:109CE0003E99CBE08EA6875BDD516586F755C7961A -:109CF000BFE7892DDF31F2EBFED1E5C18AD680EBDB -:109D00007C4511F76D007FE1EBE2798CBF12F6DC48 -:109D1000401733E7619EA553F1A3BD30705726C5A8 -:109D20006D768D64544EDB61DE668E5EFF5A1D8F4C -:109D30006B0BBFBAFC7D2AAC4379FBF27B6904AFA5 -:109D4000341BF05B27711FC2B703826E0F083A2DD8 -:109D5000C9325B91FF1F30B837119E279ADDE8A703 -:109D6000DA9F68A4FB7F1BE6F3DFB75092CCCC08E8 -:109D7000FDEAA7F332B4633742BDBEC44CF92907EC -:109D800044DE77C3832AF9B9B01EEF41D43F622580 -:109D90007F797952E1DD58AF4F32D2B98BFD8925F9 -:109DA0003E311EFD2EC1F64473087F2723FE1ED6CA -:109DB000A3382F841BCCEB293E0FA2477D8991F459 -:109DC00070793E1FFAA1789E3ED34CE31D70D8F700 -:109DD00023DE357C449A1ED48F74633E99C4EFF21F -:109DE000A491F4BB33407D7DA3EFD9D7A779DCFCE8 -:109DF0001C30FF3D95C2CEDF578161A11DBAD51938 -:109E0000D12D8F0FE648B83355C3F6194C96F9F9A2 -:109E1000B5B4CE72A94AF72D29B2BC94CA8F8B7AF9 -:109E2000796F6C6A1EE7534ADBEB7F43BCED9B0402 -:109E300070817DF224747F7EEAB4E0EF97EF5F8952 -:109E40000BFDFE0AAE7350D7FA0F383C2E6F54B993 -:109E50009B7D0920BEC5EFCB018BC78D7EB62BF74E -:109E6000C7E12AD7A1CFE4F0EC5C474AF7EB48CD35 -:109E7000E3EB088A73E3F1F54A9EEEDB5E67B7F821 -:109E8000F72FAF332D769DDFE23CC3CAB7304F7D4D -:109E90002ECCCFD6353FFAF9B812E49B1CFFC68909 -:109EA0007C6956189BE7C4467ACC5C5F8CCD6BBA54 -:109EB00045D9D488F2F57111377F5DD0D5A184FFE3 -:109EC000D517F5ADD7A715B413BFEDB5B411894BB0 -:109ED000F267C9FF2F659C2CC132C88101792067C8 -:109EE000EEEF7D741A76DEEE78BC2FCA2BE09BD79E -:109EF000E58DB87C9E927E3BE70BF48B7424E937AA -:109F00007EFE928ED8ED414A10DDCC42F474319E33 -:109F10008F0F7A09DD73CFDC395DEB03221F6BAE47 -:109F2000E7EB58EAA779DFE27894F2106FC9F7DD22 -:109F30009407FB3D65E8A774FF147355F6273B4D66 -:109F4000D1B4FF9BF3C58C7F7C2FF5FC78BDFE4A16 -:109F500079E9729EF1FC50CE4799B883F4F83AD073 -:109F6000E379DEBA42FCBEAE4AC7F9F06E85F4FA78 -:109F70005A903328A7E4BDCC3715581BF19ECDBDB0 -:109F800006EE4FF5BF6472C7DE4B159FBF2EEC89FE -:109F9000C54CDA0BFC7E8B1A3BBF774AC89996FBFF -:109FA0007ACB7BA9B83C043915732F55A53BF65ED7 -:109FB000AA1EEC05B00B483F63BD74C22EE072BA16 -:109FC000E57AB7DDCFC8FFCC7F2774AA51E88300BC -:109FD0008BB4AE7BF3C00EA0FB001BF3F2C5BD64D7 -:109FE00001FEBB2C42FF8FF74717A5FB56209ECCE6 -:109FF0001CA4E5E24F04CD30727F33E0DBA60E8671 -:10A000006998F5DBF15ED95B59FD3BBA3E846F0F71 -:10A0100013BE0DFC94DF37DB856F8FE4A572B98426 -:10A0200042E64A741C71FA1EC7715B1CC13FE13DD8 -:10A03000F81BDB4C046F99E71A4FDF51F3396DE0E1 -:10A04000F371EAF5349F27BA9BCFD5E07D345EA546 -:10A05000338EDF3DE13F9E27491CD685FF8315DF08 -:10A060008B386E271D2CE776D765F3D6DB68BFEFFC -:10A070009CCAE3727509D24ED6C667A4A11F928FFF -:10A080007FE74A8E177756F2BCA4096D35148763B3 -:10A09000E53CAEE681FFD1EFFC08FE36D9596440BD -:10A0A000D4FB2BBBDB807ECEC9E363E36F53CCB71D -:10A0B00050BCEFCEC98698DF39957098227E477DD7 -:10A0C0004ADCEF9BC6C3253E6ED7C90FC47AB3F0F6 -:10A0D000777FE099CDF8399E0CF17B7447F33AE332 -:10A0E0007BFDAF31BE772CEF1AE27BED8608DD3BBE -:10A0F000F15AEAEC4DF3816EFAFF7210DDDB7F73EB -:10A10000DA9CED6BA1FCCCC6EBA8FC5ADA0F171E4B -:10A11000C5FA2D05542ED77D3A0DE9A0B064EA3872 -:10A12000FC9D83760BEFC765F5B5E0EFDFB886F4ED -:10A130001E86F9C8E5C608B5BB6D68CD70CCAF2AE0 -:10A14000B7F2F291A2FF1846E5DEA23CEC95EBB027 -:10A15000DCAE7C3AADBBF8E0C0422584BF73579EAD -:10A16000CCDB8F1FF66C26FA8BCACB7879A0A7744C -:10A17000651FACD77D36AD3B7DC428EC21A95F7B44 -:10A1800005BDEFD24E36E2B944AF4DF1E0F913EF21 -:10A19000C893FC3E3A33CF53F93F722300BD008091 -:10A1A000000000001F8B080000000000000BE57D90 -:10A1B00009789445D270BFF3CE9564924C0E20215D -:10A1C000102609840492300987288703048C0A38F2 -:10A1D0005C028AF08633E42011748DBBEC6620802B -:10A1E000E8A28615151574404070118302A206BEC0 -:10A1F000E1505151E3B1AEE82E7FA2ACDC1283AE48 -:10A20000B8EBAE7F55757766DE37C902FBFDDFF32D -:10A21000ECF7FCF8EC76FAEDABBAAABAAABABABA7D -:10A22000C7EBC935CFCA626CB847F1F8211DE158B8 -:10A230009268EFC7D858CDDA4F5518733A5296390D -:10A24000E3198B1E38AC3F7341B99D59582A6337C7 -:10A25000A468E1AE0E8C4DB9E6DBE4289531E62822 -:10A26000ECE98D849405181BC0D838FC13EA8FB331 -:10A270003B026A0EFC9D6F39D790C1E8DFCFD03E1C -:10A280005BF1385DFD31D725E6EBDE8C61173F5F72 -:10A290004FFD76C0EF53067D9B6CC68F09BCDF0B6C -:10A2A00016C74A253AD8FF4DA27FE661DDE33B326F -:10A2B000A688FC4D72BC0CFD78F84F817A9D98F809 -:10A2C000BBEEAD1F15ACB7A25661690005F351BADC -:10A2D0009ED528084CB6A2A5E3FCACA67A177EEF63 -:10A2E000A6B87B39119E816EBB37BB35DC12BEAE82 -:10A2F00026F890D71A2EFC67867C1293FF14A7B31A -:10A30000238ECBCBA19D87C506E182F107107E5637 -:10A310007078D62B1594624306ED1688760BE47C94 -:10A32000F7EAE73B209CF9C2008E04E65EA962BB17 -:10A33000F8DC5EFF0AEEF2F0A81CD687B18976EF52 -:10A34000833698C3A4985944E7C9CCB73B06E6FFC7 -:10A3500062845680F0A826DFBE0698D41CE6B1229F -:10A360005E808E37723A72BA48B88CF86881D388AA -:10A370001703DC463C04E9539F886922ABA07CCBE1 -:10A38000BC0CF3A9461E047E6DCAB5F937E22066FF -:10A39000F81FF0F3D1C274FF034A10AEA30ACB300A -:10A3A000433D9F12EEDE9CC2D80F61307FF81E2F16 -:10A3B000F03068E62FC6B2A8D6F056DA79BD7BC277 -:10A3C000A336627A7D7AF8325334B64FF663FDF8DD -:10A3D00070487382F0FF60629A1DE0BD47AD25FAB8 -:10A3E00075614D4BCC29413E7BD80593EE8F7C297E -:10A3F000E7E353904E569332C3EB8039E1BFEB83D2 -:10A40000E9C32E4068078E2F3BC0354370D38C06BE -:10A41000A55141785D290E5C2F33EC6AC096D39A22 -:10A420005F704676A0D3CCCBF00FAB799C61BBE1DB -:10A43000765E6F26F68FF5168FF484D69B89E3E05F -:10A44000B82BE1BB3DF85D01BC27C5B6A60FCC8F8C -:10A45000E01F5339C27B220EF06515F4BA3792E83B -:10A4600035E6DE61F45D199FA134C0FC4714B828BD -:10A470008DEDF7A1996513DDA6D46605E9A876D41C -:10A480009EC275CACC0DFDC7C1BCDFEBFF5CAE063A -:10A49000E5C74DAC08EB19F1F75C107F57B48EDAC5 -:10A4A00083FFF508EF36E4FBF34AFD002CCCEFEC1C -:10A4B000243A32A6A520FD629C29C36210DF3FC169 -:10A4C000B880EF8958047CB0A7A3B613E19DCCBC3B -:10A4D00023CD30DFD802CDA239683813C2B3D0C93A -:10A4E000E119A93A886F9BB72B7E1BD4CBF7643E4A -:10A4F0003E18F2E5472CCC0FE5CD8CF375F33AD539 -:10A50000EF037E9AF7F6CB036005B2AF041FF75C4A -:10A510006B622E490FF85FA63F9CB93282F9DE5B71 -:10A520006375F9ECDACEBAFA7DF6A6EACA7303BD12 -:10A5300074E57D8FE4E9F2FDEBAFD3D5BFE6B3E17F -:10A54000BAFCB50D37E9EA0F3A355E971FD2749B16 -:10A55000AE7E7518ACAF3E886E4F7D06E065B6A046 -:10A56000D3F59766EADA9D8D1A7504D7DDEC55F3BD -:10A5700046E3BA1BC64A74FDB01ACB97C89715F0CC -:10A580001FD2732EF34607005F2359D39B4980BF28 -:10A59000057EC58D789BB796D793EDE6EFBD7378B2 -:10A5A0000CA67EFDF712660EE6A19FCA3F6D78E706 -:10A5B000704879BEB3D084FC77DE1519FF7504228C -:10A5C000825DF3B3DA267DDD01A4DF27AADB069FD7 -:10A5D00016BEADD23A58F882E267D06F3AEB118DD1 -:10A5E000F9F2232AF303FD4FB28AC70643FA4395D3 -:10A5F000FF9DC33D82F8B125E8E91CE6D2D339229C -:10A60000434FE748B79ECED103F5748EF1E8E91CBD -:10A6100057A0A77307AF9ECE9DA6E8E99CA8E9E9DD -:10A620009C54A4A773D70A3D9DBB55EAE999E22B38 -:10A63000D6D3CF407F299FD3562ED4D56BE1036F5D -:10A64000D1684C7BD4FC52D76F895A6A65A6203FEB -:10A65000F8E03FE4879E8CB90380E705408780AB34 -:10A66000351F14D5AD5E91F46FF041760AD0BF77F7 -:10A6700008FDD569D15A1BF25CA692AEA04FFBA68D -:10A68000F4273B6800A6537A821D04728379DBB6F7 -:10A6900083A4FC0AB53BCC0382FAAA3DB9D64ACFC3 -:10A6A0008E95FAA91D3DEBEA1A94838090638CDBAA -:10A6B000018CAD32211C53055F1F0CE77C79118B97 -:10A6C000AE857A506720C0750CE186718E85F73EA5 -:10A6D0008CEBF436566BC1FEA7B17A4AA7B3264A73 -:10A6E00035E624BB622673533A9B79297DCFAE4D64 -:10A6F0004901B9596A6F188076C95F0B3F3CAE209B -:10A700003047E310D876F12AE5F5C7F827D47B3037 -:10A71000C5AB215EF3EDAEBB1E854F07514FA0FCCC -:10A720001D1D47F032B3377B7C765BFD2C25F9FE8F -:10A73000BAA26928777D8976F766985BEF24664F21 -:10A74000443D97E04F1D0FF4294FD1EB975E8227D0 -:10A750005EE85CBB10ED28C6FCB1A81FAE76DC5FDE -:10A76000A5787E8170CBFA979BAFD55A7B27C2D94B -:10A7700054E6706F04FEFC44D0E3D95B6D01352ACA -:10A78000C8479F454C7FB303D0EDEE086D19F1DB50 -:10A79000E41B57605E3918E75A08F05D28047C73A3 -:10A7A000FCAFC4F252BBD6AD234CF17C57AD67343D -:10A7B000E2DFCBF10F7F647BDB849FC33342E1E3B5 -:10A7C000BF1EA1ADC67E0E9AEA93DD880F73FD0011 -:10A7D000B24B1D1DA89FF3568E97F6F0303CA2EBAE -:10A7E000349CD76C9BCD8DFB93E10AA7EB89B819FC -:10A7F000D3CBE1CF39266FC780AA83FB1982DB59FF -:10A80000D82D11F8E6BC45C06DEF20F0EECAC27538 -:10A81000D51EDCD5D83FDA89BF56FC6827D23FC8A1 -:10A82000BFE28BF13F00799BE9E22713D07EC93666 -:10A83000B93742D1BA70E81AF8FD0381EFF516C8AE -:10A84000C7D2F795F83D219CB74F78CCE4AF86F698 -:10A85000DEE1AF129D9E5DE0A0F91432971517D985 -:10A860002C615FFF65D8DFF735003DF6A5687B7189 -:10A870001E33E24CC99F101C5A6FB477D8E02BE30B -:10A880007FB94EC73BF914E608BC4D601E5A77935A -:10A890009866C1713FFAC6EA41F9F991902760FFC5 -:10A8A000D3F7A9CC4FE9ED2C40F5EF600D94FF30C4 -:10A8B00022A76B25C037EEF19E3D50BE86E0FD7DA0 -:10A8C000BE5EB519F19C5F4E7642BCAFE97045FCA7 -:10A8D0003B4EF00BACD74FB11F58AFFD725343D670 -:10A8E0004D3EE7176676F6F857EBA6BE99EB0B10D0 -:10A8F0008C8E4498FF0D828437784A484FA09D156E -:10A900000FF8AF77A96467150C6B3423FC5BBEE5C9 -:10A9100072ECAD252CD207E56F0D5319D26BECDA32 -:10A9200051A7B1DD511688EF07F5475ED20E47C338 -:10A93000FCC7827C0789CC0ABA809E08D14B372598 -:10A94000ACCE473BE2A6EEFAEF37B31A15F1373A31 -:10A950004BAF57C6A25E91F560BC038887D8D6FA84 -:10A96000E547A95F7AB15E57A35F169A3C2C95EC38 -:10A97000549715F97EA69979DA5A6F937B2AC29E6D -:10A98000E576CB2D62ECE6D117AD1760BE0353B56B -:10A9900008EC67E198BF4C47790CFBACF7FAA21EB4 -:10A9A0007D5F650F40F99755807150AE27AAECCCBA -:10A9B0000306CED7554ECA9FAA4AA0F44C958BD217 -:10A9C00073551954FE4D959BF25353BDF1D8EFCCFE -:10A9D00095DF9AD18EBA2F4CD28FC3B148F0EF7D5C -:10A9E000617C9FB52872D1678530EE225280A0AF7E -:10A9F0006B6B46A1D955BCB7F64D4CE1BBEAC0F232 -:10AA0000D58A1BF5D39CC3DA0A649F79471BC6A27B -:10AA1000D8E9FF87131D116F659714A6C1523AD06C -:10AA2000C39386E39FAC1A48709DAEF2105C9EBA49 -:10AA3000C637E3A0FDD9AA02CA2F4CF566A6764018 -:10AA400075FBAD15DB8FD9DE684E82F2911EC58392 -:10AA5000EB7BA887F9FD40BFB516AE2FD682BE406E -:10AA6000FE19963D7EFD5D0CE5B9D617C799143BDE -:10AA70006B641CF2D5C04233D69BFC13D85C2941D1 -:10AA8000FEBEDC3A39BF5F21FC9CDF1F43F89078A3 -:10AA90002A13F43ABFA7F72D83A0DFFD6047AA0071 -:10AAA0005FF32513C1D7FC59B81F8D0463FB85BB29 -:10AAB000D33A3107CE131ADB30DFBB13033A9C7D48 -:10AAC000E19E04A44786623655825C381B5BFBD747 -:10AAD000CF51EEFD99CB3DC66ABF7E12E562970469 -:10AAE000F70390FBC602FB34DAD75444A05E5C60E7 -:10AAF000651ACF6BBD317F369CD1FE76C08EA4E146 -:10AB0000B89E703C57CFA05C4BDFF178EAAF5CC1D8 -:10AB1000F96E79E189E6D75C58EE27BEDCB6637D35 -:10AB2000E7A72057BA737938C2F53ADA19B04E5E02 -:10AB30005F1D41F2EB758BFB7825CAEDF50EF766CC -:10AB4000A8F7DC43F77EB917D307CBF2EE45FE48F2 -:10AB50008DA57E66FF6E7E2F6C0F7A9C25C2BC7E13 -:10AB6000FF8A120843FFCB9A034B1361BC3EEB1ADA -:10AB70004D9D21CDDDA45463DABB6BC111D49F156B -:10AB8000A92E6ADF777B8A8AF661AFCEFECFAF2728 -:10AB9000FDAED7FB596BBE1DDE9905F57F2FA5F6DF -:10ABA000CC12A0EF7D5D3FCDE3FBBE1AEA6777DDF7 -:10ABB000848F6F67380FB02C10EE422BF92570BAD6 -:10ABC00016C89FDF95B601FD177B4CBE0DA48F669E -:10ABD00072FBE3BCD7F704F24D19D4F741BE2CD772 -:10ABE00017751D9497FDB9BB1B3884757DFA8602D5 -:10ABF000C4C7825D8F8EEA0CF5CE0F666E05402FBE -:10AC0000DA7D7114B6635DC156C67E765577BC0D8C -:10AC1000DAFD366B787FE413AF5A4BE3B0723ECE69 -:10AC2000E3428FB1861CF20B904A817ABF85CFF840 -:10AC30003DB62EE600F76D71FA94D72D4941FF4AD3 -:10AC40003FCDEE56711DA4F8122B1C41BD08FAEC45 -:10AC500077B87E12ADA25FE78464EF55E833ABD0DE -:10AC60004FB2BFC7ADCC1716CBED6005F5AD95EB78 -:10AC7000E1CD202F905FA51E867137A6F2F664FF06 -:10AC80002681D2CD0538931EB7F949D75FE1F84642 -:10AC9000BF99B443A6C455EF6B40FF4E84B603C7BB -:10ACA000917E326676BBD0CE5916E1793195ECA80B -:10ACB000A6649C03E8C997B1DE0215ECAAB410BBE8 -:10ACC000CA7E657AF2C508CFABD8FE4AEB1BE5E831 -:10ACD000A2EF4D2C17F860D1A336DA77560BFF415F -:10ACE000B5F06755470EB0E3FA67874DA56F82FE52 -:10ACF0001CC27B68E97751641EC9876AC6DAC4DB67 -:10AD00007E58D71AC89100E8010DD6F7D04B4D2ACE -:10AD1000E7FBFA43D1FD507E324FA40BF7F526A690 -:10AD200085E847633F40B76338CF612C8269217A59 -:10AD3000D0C362ACB87E9923F6DF9AFF60413F39F9 -:10AD40008FC1C27F37B8F9B30894838BBECF237904 -:10AD5000D8DEFCF689F9FD17CE0F526F4FEF39841C -:10AD600073C8774E33CE7388795C32DA2D007F3327 -:10AD70007E1FFA9D490FFF4FE1BAFC95CEE36E8529 -:10AD8000F94CB83EBFB5FA717DD6017FE37AAE9B30 -:10AD90009FE54739B007D603FAF17DE3AD64B7D636 -:10ADA00009BF685D0727F98B5EB7F0BC6FAA681F03 -:10ADB000C6482FD44DED4CED3BDB2ADECDC6FEABB5 -:10ADC00023487ED659FC2B53B1FF5FC7B97D402F76 -:10ADD000D5FEECFA137D61FFE037F92CC82F96C041 -:10ADE000ED2AF6F7AD95E1786B620249E5507FCD2B -:10ADF000FCCE54FF33308DD01F37C8649A31CE81DA -:10AE0000E59EC458C8EFF9A74A7A604D2EE41D2488 -:10AE1000C7C9BFB7669C27313C1ED38E26824765C3 -:10AE200015F43D85B7FBDCC2EBDD26E8774CD00797 -:10AE3000D639C9016D6C8419F9F8DAB49959696485 -:10AE4000C778121580E7C9D93D18CAD1DB8A6F4C83 -:10AE500021BE117ECE298206B23F26FCA493F8675C -:10AE60003675CEE630A4E7A4A230F2837E56B43421 -:10AE7000D205ED2769C2FF3951EF17BD36CD43E347 -:10AE800096D566A69D08E1EB9936901BD0FF43E16D -:10AE90005ADF34E4C7BDB954BE178C959F615D7D00 -:10AEA00039BBC70EF253CC96FBC2C02CA4EBFE26D6 -:10AEB0003BC3FD467BFC508D74807EBB215DE2046C -:10AEC000BF22FDA784F37D8B19F805F2D5B599B49F -:10AED0006F79C6C23C0AD26BB78DE85F30DEEE21D7 -:10AEE0007FE294F00D36289F21E459F59470FA5EC4 -:10AEF000BD2FD26F52683F4479DF4E0BB52BB5FAA8 -:10AF0000B76D817E4AF76792BED96315E3BE16C15D -:10AF1000CBA33C29CBFB617927E283D72DAE682AEE -:10AF20007F5B65541E1E488F013CC6856913111F47 -:10AF30009D6D406707F6CBBF1F17FC751CBA45FA1D -:10AF4000F92A22A95F5AFA90D7AABB6E447A6A56A8 -:10AF50005ECE7EA952F971A727710EE48F57241196 -:10AF60005CD26F74DC6B25BE3F5EAA90FDF3A74AEE -:10AF700035600DF5DB8FDF7A7F3AB4FB6ABF85FC65 -:10AF800072D31E2E398ADFA72D2D23FFE2B4E2C52E -:10AF9000742EF0CDE2AF06AC85F9342CFD22590BAE -:10AFA000F1334F2B855621EBF937699E32E4832725 -:10AFB000D3B40A9C5F7956C35CB497BFB1D63F8DBA -:10AFC000F67F7ABCB608BF5F78F5E4166E4737A502 -:10AFD000A39E5860E67C22F56DB9E0C35EDDB57BCB -:10AFE000B13EE06D3AEA9588AC7A2EFF165F99FC87 -:10AFF0003F53B7798F02E39484D72DA054F5E760CF -:10B000003F67954094924678D4705D9D7306A21078 -:10B01000FF9A89DB6D255BF5F3C27F789E55827FB1 -:10B0200040BB925AD51386EB80F9AD087F09B30671 -:10B03000EBA704E905FD10BD98E34FD37F05742805 -:10B04000DE969987FB859298BD0F0DA27AD04EAE01 -:10B0500017B5755ECEA7353C7C7EE7C43A38075FEE -:10B060002CC82FDB6D72DF4EE37FF36A271ABFA374 -:10B070005827DF28825FB78571BE72C3BC10CE1718 -:10B08000395F3D26E5E436DE4F499CCF8472A9A4A2 -:10B09000CA497C25E512C042EBEBEC8E246A27E519 -:10B0A00018F33246F577246EE4F69BD8BF22C050E1 -:10B0B000BFF8F77C1CCCA33C3FF37C921C97EC6759 -:10B0C000A33E36CE7B7F9A89EC2DD0D39DFED5FE54 -:10B0D0002F2361D6FAD97D43E613691572C19D30DD -:10B0E0002E1BCF0BACBA7EBF89B4CEF038F0DC405B -:10B0F000FF5DF6F74E1ADF1F7633D0B9B3DA74C0AE -:10B1000086EBF059467AC308C787A2DDF3CFB7D0E4 -:10B110005515FE71E692FCE4E2F63CD1EF9855D26B -:10B12000EFAE2490C72588ABD4201EF7E46A49A867 -:10B1300037BE11E73D7B62209F85F614A78BCC4B71 -:10B140007A18F972E9B1B94978BEF4CF34EEB73361 -:10B15000E27B09E015CBAB2DB05FC9C27DEB914717 -:10B160004EF408CEE7EB2A8F6776487EEEDA5C3B3A -:10B17000AEC779EB72ED3343E851BDB5EF1117E07F -:10B18000FDDC56B31BC57BB5D9FF10DAE9D55BD51D -:10B190005AE42328B723BECF390EBE8FF5E6AE8B17 -:10B1A000C9433B5CB69FB776A46776081D7A6FD516 -:10B1B000D325BB569FEFB3579FB7776734BFAB6DAF -:10B1C000971BD0E7FB1ED1E75913506F00DA039CA1 -:10B1D0006EAF0C741F7101DDBAF955377EEAE618BF -:10B1E0003F610CDA11EB54770F28EFB6D87B33DAD6 -:10B1F00015A7D6CD7123D98B54DF825F014D8BBE4D -:10B20000187504F5EA5956FBE918A0CBDCBAD556F7 -:10B21000B30BE7ADE7F73D26C1BFCF737FDC7CBF43 -:10B22000BEBCB55C5822FD1819A1FC65E40318F7F3 -:10B23000560F00545AF9F12328178A4603E3A31E38 -:10B24000AF5D6D45FBEFF2E3F8B87DE9F0B8101F94 -:10B25000850379D9759523D857B0EED8AA0F472121 -:10B26000DC85BF55C8FE287CB9E761E4AFC69D53B5 -:10B270006FA2F4D6029ABFF4FBCDAB530291907744 -:10B280000E74ED6D807673FCDC7F3173992D280F81 -:10B29000199E7B19E05813520EF0CFDB7BE0473C40 -:10B2A000172E5AA76F371FE434EA9FE24D3FDB4267 -:10B2B000BFCBFDE875751B549CF71C01BFD49FCC18 -:10B2C0003794CE1DAEE34DD809FC3FD03BBFEEA86E -:10B2D0008DEEDE3FA847AF5BC3DB83D82DC47997E3 -:10B2E00039AC2E9C77999D0522009E2391560FC65E -:10B2F000955C5C1B497EB7B936B057F3286518B723 -:10B30000008298CEBFBEFE4025BBA72C8ED3BDECDD -:10B310001985F66965E82CC5FCB33C3F9F05683E7E -:10B32000C82F9ED079FAF57956C3F777A5E6C00104 -:10B33000C44B316BE0FB33A0A727E4FCBA14E6F959 -:10B34000592CDA6F86F6CCADD1B99C83DB63E57BF3 -:10B350007FB68596CB7DA6DC074B7FF033E9DE70A8 -:10B360001CC722ECE635F77BD211DEE5164F3AE238 -:10B37000C1B73A8CF6FBB76DE0FA6B4D0CD8B1F162 -:10B38000643F933D7E9BC2ED733695CBC341A69738 -:10B3900002A86F9A1E8D716F74517DD2636B1ECCA3 -:10B3A000E4F6FF3F55B2879A56F3388835B91C7FCB -:10B3B0006B1ECCE6F6BFD47B1D18F5D7DADEF6A4FB -:10B3C000A31F823DC2E1FA1CA714625FE776D21E7A -:10B3D000E81E323F6997B3A22B3B9FD82CE2329AEA -:10B3E0005687F9F17CE284E27DD31462DF3ED59D7D -:10B3F000EB8901C33D5B443D3AC7986D1AF7C0F530 -:10B4000000D7ECC74C2EF4A7B5E0DBE34947FD7944 -:10B410006275581EF2D980E1DCBF743C97CBFD8881 -:10B420007E8CE29B36897E377537E9D28470E03FA7 -:10B43000E8E7C448EEDF8EECE725BFDE661797FB32 -:10B44000C679D48A7E665BBDEF0C69031E891796A8 -:10B45000CFED8E13772A1B395C406FC80FF85D184B -:10B46000F9034F08BD24F10B7C43710C526EC5B437 -:10B47000F08B7F5B18F0CB6A0BE703B96F0BE1171A -:10B4800041FFAE44DFDB047DD98361825F4CEC6F0A -:10B4900088C7914ECE0F57B9FF027A1F417A1BF72A -:10B4A0006192DECCECEFFFAFCE51CA5E79618F0FB7 -:10B4B000EC8CE2171F8D6250EFB4B9A6A31BDA978C -:10B4C0006E5E1EE581F494D917E584F14FFBD50239 -:10B4D0007F1BF8B6F690FE688F430939F73CF3FC02 -:10B4E0006FC7E23CFFBAD9E2449150BED546FBB1EA -:10B4F00005BBE693BD0EF9469EBFEF5B3C072DDF13 -:10B50000ABF7B7173FF7684717E1DB97644AC034DA -:10B5100090C4205DB0C9D2722E0CC380FDDDB40290 -:10B52000E133B647382E01BDCB6BD5426B74EBF2DD -:10B5300072215FCA77FDF65BF41B96EFBAF124CA5D -:10B54000FB72839FBF489C7718FDFC7FEDAE3F47A1 -:10B5500006FC50DC800FE0EA41ECC2FDC4D5DB1EE6 -:10B56000CF6944FB61D3BB514A56D0DF2FCF419AFC -:10B570006B673D83FED3F6D6E537C2DF1BA41B976E -:10B580005FAEBD0A0F9AABE369A925103508F77BBA -:10B590001B2C64FF96BEF0EC962791CF8ED948BF46 -:10B5A00097BCF0C6A7D7A1FDBCD3123F9A4FC3A149 -:10B5B00084C4D994BBB83F4ED2A7F8E537ACAE6C83 -:10B5C000FE7D716C904E253B0F5831DEC788CF1140 -:10B5D000B507AC0D8E36E855DB388AFC50DB7EB003 -:10B5E000E2FA38BD5F619D525AB72FDAF04614DA9D -:10B5F000678827D44F926E2D7434D487FEC7BED689 -:10B600008FEA39719F72393A7E2AECACB2572259CF -:10B610000CC051F4B9CD3F1AE9BB635114CEE7A475 -:10B62000B982F3FDFAE51DD1DE2BB2F83A3A29E5ED -:10B63000DF8B9EBE9BF8719E52D1D19945FC9E68CE -:10B64000225BC29788F39CB36E12CD732ED3881FF2 -:10B650008BD6AB5E3FA4DF9B59C1CE36D6CD52B15F -:10B660006E4E6E04E2C23C4F8A782BDF47AAD84761 -:10B67000DF49FAFC6E3167C61652FE7B61CF4DEC96 -:10B68000D1729E6D0FDD87966FBAAF1EE974A6ABBF -:10B69000A713C20978F009BC293F43BFEA87233BBF -:10B6A000713A3117C623503BD0AB23F03BD6AFB72E -:10B6B00078D0CF1ED24EEC13F9F87789F101EE70F5 -:10B6C000DC079FECD8763CD7CE16B9C0EA43E3B985 -:10B6D000DA95039BEE27FEFAEE132E6716F8C715D0 -:10B6E0005079BD25D009CBFD07262A24276C2CD004 -:10B6F000D63ADF6411EB5C5F0E709A9550FCEEE772 -:10B70000F6A9E497B960970542EC8420FF5883DFDF -:10B7100069FEBF13F86EA0F33979AE374FC807E35F -:10B72000FC8DF262718FB6E34ED8BAB6CF938272B7 -:10B73000C247E396827E477BA4F4988DEC88D217AB -:10B740002C5EC4D3D9ED873EBD0DF7B7B5725DEB66 -:10B75000E5B0715D17BDD4BFCD757D76556EDBEB61 -:10B760001ABEB7B9AE572924EFFEBB7218341FF9C1 -:10B77000252EB77EE7B523879F33E0F57B96153DF1 -:10B78000080B9D85DD884E06FC4ABC1AE5EA1014BC -:10B79000921D5ACB5586211A21F8947894FCCA98A8 -:10B7A00046E3B4F0B5E45BC9D72D7C6B9CB71E9F14 -:10B7B000C6F2F9487B80C7FBAA85EC85D23A1E6F9A -:10B7C00008ED283EAE1CFDF354BBE6CDA4F8D0BC7A -:10B7D000DF90AF35D4F718F25E437DCD90AFD0D572 -:10B7E0002FDD7BC8CAF70F015D3D5BE5CDB41F6956 -:10B7F0006D67F8F9B9D3AE6FAD3EE48F2E4D569418 -:10B800009396A5CC1709ED9BF6A964F75C703545B6 -:10B81000A1DDB23C8CDB75179C221FC3F34D1DAC20 -:10B820002B504ECAEF4D61DC0F73C1DB141513B200 -:10B830009F6FAC53A3D0FFDBE067056DC7AB54131C -:10B840005E1B587BE5DCBEBB10CEFD0D17C2B9BF39 -:10B8500061A4EA48AE443F6C0D8F0B9CBD6472142A -:10B86000C555D4A5DD3205BECF795BE561E03E8FDD -:10B8700019E319667152B253CC47F181B3EA785C8F -:10B88000C3EC557A3ACF756CA2F8B7EFD9624AE7A4 -:10B89000AED1C72314B355C46745EB0CDFEB6EA6DE -:10B8A00075526C58279AF00F1BD789235DC43DE66B -:10B8B000B25C5DDCA390E723D5AC5BA6003D2E1CFB -:10B8C00051990DF2CD752A5BD18FC7B9E2F9136E8C -:10B8D0004870FD2D80F58A7693C4D7395C473DDBEF -:10B8E000B75FCEEDFEF3805F21DFECF92207CF8555 -:10B8F000CFED3996FE3AE65FF963F217AC75FD11AC -:10B90000FB7F9C8E72FAC27E1B437EBFB0FFAD648C -:10B91000F4475E78CD46FBEC0B4B6DDCCFBD3FD2E0 -:10B920008F2AE642576E1757EFFB21A781F4F232B8 -:10B93000A2DF35E9566E5FD5FDFD38FAD39BEB608B -:10B940005628F7F747D07A2A7F2D8CFCCC17F6FDC6 -:10B950003020D43FF7DF9D8F3C4FBF10C9A6BC8479 -:10B960007C1CC3F705E5AF5FFB2C9E2F97ED3A607B -:10B970009D05E523FEEB1F3928572FBCC4EDA96FA9 -:10B980002C0D4FA38F73F896A8472C89E8E783CE38 -:10B990003A33F6C596B1137C596DE185E3E102E0D7 -:10B9A00001E7057829427DD01E3EA6223E3AFC27BB -:10B9B000E2E3DBE95CBE5DC3F03C3A8817C5C3BF78 -:10B9C00047FAED0ACD9F7FDFFF430ECA9FCBCDF72D -:10B9D0009EFFCFE6FBE87FEC7C39BF774D77119C6B -:10B9E00046BE6FCDD7AFFC82F23B22DD04EF15AE31 -:10B9F000F7DDFFB1EBFD7F86DE1FFFC7CEF772F4E8 -:10BA00007E5BD03BD289E79917F6FD23995DC5BCD3 -:10BA10009BFF97CE5BDAF1C355F7915CA8FF2EAB85 -:10BA2000FDC49D42D6489B7648B7609C1FED9F465B -:10BA300030AEA747D84BC8FE1CD1E541B297AB59F1 -:10BA40001E9D5FF8BAA874AE4341208087B712727A -:10BA5000E95E153307BA2C82FCF0A4328AFF32EE7D -:10BA60002B47848F2940FBF4D012800BFA391469DC -:10BA700072E219757E177E4F09D2464CDF4CBE9993 -:10BA8000E2F8F31DFAFDD5CD867DD28D2E7D7901AC -:10BA90007B291ECFED0AB22C745F6214D60FD957E2 -:10BAA000FE23DD4978B991D52C733AAE1E4FB70805 -:10BAB0003CB5C6C3BFC65B2B3C897DB459D437E2C5 -:10BAC000CDEC78A01EDB9919EC8BF97C693F2DF742 -:10BAD000C597C32713FB6DB3185AE2D7DC859FCFF8 -:10BAE00086F44B789178BF5A7C4B3A19F12EF12BA2 -:10BAF000F166A4432AC6F8F50FE2BF8B39D78CEB69 -:10BB00006E88B0EBF3CD313CDFA55EF5D27AF473ED -:10BB10003EFFCE6D46BB7E982386E2428DF71166CE -:10BB20000E8C19A0C07C93CCCC67837D289EBD91E0 -:10BB3000DFF57EB37F690A8EC3FDBB5DCDDC7F0D73 -:10BB4000ABDB179E47F53D56C8173E328F79A07E76 -:10BB50006112732BBC3E8B8EA5F038A6C6F27B9B80 -:10BB6000D8AE309AF75BD889F997727A125DD0ED2A -:10BB700083FE0DE8D7638AE5EDA3F2A8BDCFC4DB51 -:10BB80007BCC90764BE3710A4DCBB95FBEF0BEAE75 -:10BB9000E9283F460FD7FB99DFEAC9FDD232ED9B7A -:10BBA000E1227CA9267702DD8F589649FB2335DCFC -:10BBB0005BB61BFDF43B789C4EE18A3BC6F447F82C -:10BBC00076C4B911BC3363770EE0F5A7DEFD07F844 -:10BBD000AE6D0DA3EF9333B4A53D311E40714DDF23 -:10BBE0000D1F664E3A644D8021B4DA71E7D14F38AB -:10BBF000D6B7F37D3C9F1C3B51A5FA63198FF764C0 -:10BC0000CB601C281FE3FBD69C00FD8D814D079661 -:10BC100037863993EF04F80B857FF8215C2F086F86 -:10BC200038D35E72205C5DD353E1FB18D676BCF14D -:10BC300051597FB8B20ECF99BA8DE0FE7B591FFBE8 -:10BC4000C17E3FEAC9FD514F8854E601AF547FF6EB -:10BC50004A5B631AEE7F565A023D2175F41ABEBE46 -:10BC600027E06F742A1BB516F17EAFCA3612BC4DA1 -:10BC70008574AE1099E1423A68C0D274BE5293E224 -:10BC800042BF58E3B0DA009E27343E91E2AE76110F -:10BC900095291E48EEB71A8705BAA31FBF29979F9B -:10BCA0004B1C773644E27E7196C3CEEF498AB8A228 -:10BCB00039E25E4CB7EA8607AFC17DE8A32A9DD77B -:10BCC000CC7994DFF7FA8BC3EE5770DFB646DCD73A -:10BCD0005CA58F23624E37F98166D50CB3E27E7383 -:10BCE000B6C363C579FE31437B1DE725EF17F642E6 -:10BCF00022409785358514AFA246C1BAC3756276D6 -:10BD000045E13ED81887542EE28E64FEA170ED30D6 -:10BD1000F2C3CC68D70EE4972F2BD3C83FAA0ABE34 -:10BD20001B8D7195789E616E484478EEEEE922BED7 -:10BD30001C1DEB4C77103F8731C443A3C5998EFC83 -:10BD4000DDB83CCC84E772A39772BE867566374334 -:10BD5000FBFBCD2C1CCF197E27DA4F5B62F66E8081 -:10BD60007C173B3347C6225FE5125FDFD24B7B0275 -:10BD7000E777EAD76C20F2C3AC55ABE93C46F20555 -:10BD800033D7E7C7C138A736A7E4A1DC6C91D3BD90 -:10BD9000867F81ED5AF861A2427C00E98134E28716 -:10BDA000F10D38CFD1C303DD1766E17EB49479502D -:10BDB000BF273037DA09CDAC89CE2B9B1D5617FA39 -:10BDC000BFA43C917203E8EAC17BB7920FB680BE74 -:10BDD000375B18DB5A65A7F4F92A2733F7606C7BC9 -:10BDE0005502E57754B928ADADCAA0EF2F55B92952 -:10BDF000BFAB6A20E5F7547928BFB7AA80D2D7AA8B -:10BE0000BCF45DCA25C00BC9212957A43C9AE5B0F2 -:10BE1000D27D5F29978C7C331DD03B348FDA93DC45 -:10BE200093F20EE761CA0BCA2349DF54C5EB4B48B6 -:10BE30004139D63015E93F523DF7C22BB82F2F724A -:10BE4000B8699FCEB8DC6B067E45BC245BD95EF436 -:10BE5000CB56DFE969BC2F2588FFDB8B14660EE12A -:10BE6000AB3B2AC29839446FCCA88CD1E5A7557E4C -:10BE7000FC4627E8FF9E0E5A7C06C071FC375FAF78 -:10BE8000FF237C7FE637677A20BD018ECD8FE3B834 -:10BE90008BC35BE088C5FC320B9D737513FE936EFC -:10BEA000C27F82FF903EF27EF333BFF91BADF3C633 -:10BEB0004A9B0BEDE2CF915E80DF3F097ACDACB4B7 -:10BEC000111E0B977FF5C22BB8DE175B49DECD5CE8 -:10BED00026D6A3E15EF397898CFC126055B34AC065 -:10BEE000DF97BFB60622A0FF2F15BE8E15300EA617 -:10BEF00061FCE1CAB73E4339A0541EA1F3770DEFB0 -:10BF0000E1217C3ECB39DD3DE9CA37A91E6BE81241 -:10BF1000837E1379CF38A29FC7EA82F9236F23FD6E -:10BF200066661C648978CE52A338D185385B7C9FC5 -:10BF3000BD92BFDB80713C13C1FE1B92A1123D2B51 -:10BF40007B9A29FD14F52DF9936B484F49BE9DBD91 -:10BF50000ADAE1FAA8C9B5CE0D91C733C5F7591968 -:10BF6000264AE5F731D82F9EFFADCC9D82764567F6 -:10BF70002CCFC2346F0AE2B7B363945909E1831B33 -:10BF800032CC020E46ED3EC54507E90319A9D63964 -:10BF90005974BF8FF4981C676646DE0A8C2F9DB9D2 -:10BFA0006A184A61566D7127C4433D6F4B3FDC7E72 -:10BFB00063761E475DDA8E1E917EB553F8E7B53481 -:10BFC0006FF2FB16EFF8FD8ED7A0E7E22F6C44DF8F -:10BFD000E23E226E2BCB3F60023920F5FEECFCDF07 -:10BFE000FF398ACE2976F1F84E48B99F757111F75D -:10BFF000CBBA617DB5715E7478C717516DFAB177B0 -:10C00000A957E4C72E577E8A423B42CE67E4BEEF73 -:10C010003B121CCA253A272ADFB7BC635B715E4618 -:10C020003F768BBF5BF8F5CA1717B4E9EF36FAEF26 -:10C03000966518CE0FCC8CEE8D49FF1D53B3A2F13F -:10C040001CE07B719FA4BD7D8EF47F97AF854EE28F -:10C0500060BD9A5DD178BE75A11DFBFA6806D7FF59 -:10C06000E785BFFCC27695F63D17B647D2BA5AB0FF -:10C07000FD9137F1DC71C12685C02863F5843FC08E -:10C080002BB387EA358C638B6B0D77B3BF4734EAEC -:10C090009592DF475620BFCDAF553C9B019E66BBB6 -:10C0A0002BBA43083C5B91DF807F4A6CB50308DF05 -:10C0B00002FEA7514EF60FD69B5FF708F997A1DE57 -:10C0C000376417BD1881B10288F7F711CEB3EBFAC8 -:10C0D000BAF1BC707EEDCE0564576C8F70A25FE143 -:10C0E0008C885B96FDEC12FCBD2B83DB3167C5F9B8 -:10C0F000D1D91DFC5E3FC289EBEC8CC2FDD0B2DD14 -:10C100006B02CED732F8BEE48E0CBECE65FDF9B51B -:10C110008D51DDA1FEC9BD1F537A58D49FEFA8CF22 -:10C12000417D7C7257049D7F9DDCF5D4A8D761BC0E -:10C13000F3B5C3E2715DC8FE3FCAB050FDF3EBD466 -:10C1400002C417F3F3B89932C46FDF5038E336F8FE -:10C150005242D71F8F1F3ABBEBE5285356909E657E -:10C16000F60A7BA209D7D19D5EE4EF68641E80D7F2 -:10C17000BA6B9C0F7558795D2E43BEA6F59748F5AE -:10C18000579A42EAD92C6E8A33B5EC2DF48837548D -:10C19000F83D2711C73F52CDA273C5E97D5C936F6F -:10C1A0004739F9AE85E8B130D33519E5D3C57A956D -:10C1B000219C0B535800ED9345F7466E403D26E118 -:10C1C0009EDE97CB83D2950AF3C0FC4AFD2AD3208A -:10C1D000ED0CF4F7213F2534F4C738C9C6146E5767 -:10C1E000C8F8D1278B4C1E2BE8C19F3262E5FB0FAC -:10C1F0004FCCC1F3B3F119B49F3B6E653E15FD4AB8 -:10C200002FF1F8D2D2541ED7FCA488872F8D0DA40D -:10C21000C7417FE7047D4BC707D231EEA2F4A544A6 -:10C220008ABB3867E5E79EF81DCF594BF3A0BD8365 -:10C23000DECDD064FB98107E2A9DE976613D35D62F -:10C24000EDCA7520BCCE6FC8CEDD1DC9D0CE35BDC0 -:10C2500012C9E3A69E0BDB680BA19B3393F39F7C73 -:10C260008F83DDC6E38C1EB3F0B8D4C73627FAFD42 -:10C2700021F87ACCA24D453CE03CD0BE9F6FAD4941 -:10C2800047FB57C23B3FAA86E03C27F87D7E780DEE -:10C290008FE716F77BB13EE61B451C7AD3361BC5EC -:10C2A000019D49ACDF83E39FD996892FF200FCFE04 -:10C2B000B97BA91CEC4BA067F1F3B600CEE7F436CE -:10C2C000EE8F3E6DE1F6DAE971092EA46FC1F8B583 -:10C2D000D3C95FB3C9A6A09FEFB4C2AC0958BEB919 -:10C2E00003C59F17575552FC7631880DBC3F046932 -:10C2F00001DE033ABD3993E2CD4EE33B0C0A7D5F8C -:10C3000089DF355633FD97888FAD7C7F75E6F9BFA1 -:10C310006786C67BCBB478933EBE4EF2892CCFCDD8 -:10C32000E4F22D57E0B97F267F2FA42CA2F6B1545A -:10C330009A27C73BD089BF5BC31A229FEA87F114B3 -:10C340003D1494234FB240FA53E877D8CAF75F6799 -:10C35000B65B286EBDF895480FC5B1DD778D89E2D3 -:10C3600029546EA7179B007D902ABFD94AF165F129 -:10C37000CF87E5D9C83E67B4CF6DDAAC8A71C026E5 -:10C38000C6796FE171C7A3D196A4F26C2A3F2DF252 -:10C39000A7F76493DD07FD7BF07E55F12F7FC5F194 -:10C3A00038A1E828B7BBEC246F4B5BCE790647A3D6 -:10C3B0001E2CBB6F5034DE3F641FA80CED16239E6D -:10C3C0002E9ADD9D50CE2ECB147277CF7A3A9F2ACB -:10C3D00011F7084A9E57F83934AC43BC9F59B262F2 -:10C3E000D0E3C49FEF5B580F98CFB9DA47A242E978 -:10C3F000B12093CBD396FA5637D52F81FAD84FC9AF -:10C400008A77A3089E2D168A5731D2F18ADB3FAF77 -:10C410005E51FB16FEA8E57E9656F367F5BFF8025F -:10C42000FAFF6E7B98DB475F6BE91EDC594BED5CD6 -:10C430009CFFD917C2486E9D8DE1F2E124C8535F7D -:10C440004F84E3E68729BEEBA309747F6F9E5FDF0D -:10C45000AF1C77512697E36571EE688C172CFB8033 -:10C46000CB41A0CB2DD4FE030BB537CE63BC68D730 -:10C47000B23E5F88207E38DB99D3E5EC8E9EA49F88 -:10C480001A63389F03BCC978DFEFEC0B3D73E91EDC -:10C490001D1A3DC00FC562FF7B36A636D91952DE84 -:10C4A0006811FBB800D444BEC13620DF8B2BB9BD68 -:10C4B00055625F45F12518AF3B208FD2802DB675B0 -:10C4C000DC2DF02BED2FDFC9147E4C1CAFA388139D -:10C4D000273BA8D68A725B13F662E97663DC2E2FBF -:10C4E000DF26DB03B4F1324E18F9D0A7509C4AC9BD -:10C4F000B23BE753FC7DC5EADB719D49F84BCCAC00 -:10C5000000F7698D8A4A703486B119E3D1AE0C1DEB -:10C5100027C49EDB151C87E1FB5FA5F807ACD9BDDE -:10C52000992EFA8EF91AE8AF7499B28AC64991FB2E -:10C530005D3E2F8927408715E3041B8789F276E645 -:10C540002DE134CEBBC5EECAE4FEA5C614D7C38325 -:10C5500091CEEFA9749FF7E24F7DA363DBB0D38246 -:10C560007ADE1A8C9705F88F6532EA677D26B7D395 -:10C570004B301E17E04C5FA78F17CFD8A4CFF7DA48 -:10C58000AECF67EDD2E773EAF479F7617DFE8018EC -:10C5900017F7E1787F18F7E198E23EDC65E3FB707E -:10C5A000CCE33E1C53DC87E377DC87631EF7E1981E -:10C5B000C77D38E625BE713F8E79DC8F6379782F91 -:10C5C0008EA752116F8974407E67AF86E9EE235DB6 -:10C5D000D8C7EF97001FF07533D54AEBE649AC4159 -:10C5E000FB11EE77EA3CC1EEC2F8E15571DA7799BA -:10C5F000FDF11E4AFD8A44A49BB981E258CB5FE35A -:10C6000071ACA579610EF47F342C3FB902C343B5F8 -:10C6100038ED47AC7FC1D2B405F15B567988EEDFC7 -:10C62000372C717D703DA71FF96158512CD9518568 -:10C63000A8E762DBA7A3319E9CADD2C78F1BE3C9DD -:10C640008D71E4463E90F6DF3396A64494EB5F6D21 -:10C65000B3AF42F8BF0A13F761A6D80DF1000E92EE -:10C66000270B1F5436A2BEEEDC8BDB51CD47C05EDC -:10C670006F43CFCA74D6A5BE6497B7E45729268AFC -:10C680004FD73CA4871609989295A6C6FB50CECDED -:10C690003791DEBC08F61AD9839FA8643FE03B5966 -:10C6A000A1F3C177B242F90BDFC9D2DF97E8ACAB97 -:10C6B0008FEF64E9EF4BF4D2C7E74F5C7200F7FDF0 -:10C6C0001356F5D5D59BED1D64C0A3805BD8B3B3DD -:10C6D000417F78D0BE5CBC3619E9BB687E73E37DD0 -:10C6E00040DF45BBC3DC585E84FF0772B108FAC463 -:10C6F0007B9745BBC4FDE54ABD1E9E25F45091992C -:10C70000F99CB1413E2C72324F0CB49FDFAB3E0717 -:10C71000DFC39AFFF6C7039CA9B8CF18D609E55125 -:10C72000B2C54371B5A53B7BC42C817E7BF7D06E2F -:10C73000EC05EBFA44CDA187A6A13EDCC9F77F5FEB -:10C74000AD7A398AE2CB04BF255B9CE148F70D3511 -:10C750003CBE0EFD676A6C902F36D4C48577770493 -:10C76000E71BE4839F884E401FEEE7293A48E72203 -:10C77000CDB562BEC3141FDAD9727EF21D2DB68C00 -:10C78000F77397C89F10FB0D39CF739907725C78C8 -:10C79000AFA36A6FB28AF2DCB47D0BEE43FE69D3BD -:10C7A00066F7EA8FF1A03DFE88EFAA15FF81CFE77B -:10C7B0002F6B46445D8BF6E70B16F768C8DF57F31F -:10C7C000AC15F715C566BF95E233B76DB062BCF224 -:10C7D0000D5B37D0F7B95B0B291E731EABA0FDE8CC -:10C7E00029F9EE81C047D170659D13E07E47C88F5F -:10C7F000A2707EBE07F6D11BF8EEC8C5AD4A2EC6A4 -:10C80000F94CF4EEB416C2F75F8B7AC675D27C741D -:10C81000C2C80E840F7E0FE40F0C76F769ADD7C542 -:10C82000844B29B42E265EEA4DFBB449814CBE1FD1 -:10C83000CE32EC878FAADC9F57C7D7419135103F86 -:10C8400001D7C97E0BD9B96566FE6E5319FC7D1DF3 -:10C85000A4DEC1AA8E5FCBF32374FC3C85C5EAEE4F -:10C86000D3DC8A412521F989A3D374F5274FEC6DD8 -:10C87000E0FFBC6039C991EB74F7FECA16FB5CF4AB -:10C88000BE211BAEFFCE787C21BD086A0FFD3E3E67 -:10C89000580FF97B93C2F73DBB6236A21FB0C8C4E4 -:10C8A000F74F5334FE7DC15EFE9D4D61BA75D82DA4 -:10C8B000CDFD47AE172D746E20FDED53F0EF36F031 -:10C8C0000F9AA2E51E3BDEE347FF84EE7EB7382FCA -:10C8D00044B8910E65C29F5496C1FD4965BE7A2B3E -:10C8E000BE9300F837C7C5523D7B1CC655D628E419 -:10C8F0006FC47431C559EAE3B4B03F8C7F5C7044B7 -:10C900002DC475622C2FC2778790BEAFF1B8D405C5 -:10C91000E8178A6AFDDED902F413A17FCBF0BE9935 -:10C92000A3B74BF811FD2B3A231E472BB9746F7335 -:10C93000FB012BC6E74D9C18938BEBC7C86752BE13 -:10C94000C3BAA6B8C2E6A38788CF9A8BCCC4C797D0 -:10C95000C3C7020FF7B31AF96F2EABB7E2FD94B954 -:10C96000BB1437EE4BB11EE2A533F2A5012F71B116 -:10C97000ADF121F1D4823743F93CC6F1356FAFE216 -:10C9800047F9D80A4F027F46F8DBC39F9CD75C4D1E -:10C990001B857242CE6F1ECE03C78179E038F2DC70 -:10C9A000820D34AED734F25F2DF0F2385B237F8CEA -:10C9B000BFC4FD32B75E32533A71B47E7D623B5CD8 -:10C9C00027932E75A4F2ABE59F050027EA85ABE51A -:10C9D0001B391F298F83EB84DF4BB8DCBB4546FF37 -:10C9E00064426FE19FECCFFAEBE29B85BC35B63732 -:10C9F000C6374BFBC0A8770A234D146FD9EC4825E6 -:10CA0000BB43CA5F4DE8156DF9F7544F837A1C1A82 -:10CA10008F4E0F69C24FB8303295DE91485E12D703 -:10CA200011E95518E6A4B8FEC2252AC55117423DA2 -:10CA30005788DDB262595A32EA912FEFEFF9B40FFD -:10CA4000ECF92FEF8DEF3810C6F96AB925DEEE0A42 -:10CA5000D6FB72F9C8648CEFF86AB56D8ABF0D7C9D -:10CA60000DEFCDFD0A65BFF98CF4DC79D3D1A8298F -:10CA7000D0BE74F9EE28BC3E50B29CEBF7F7BA6B0F -:10CA8000C37AD3B9EF862DF49EB173430EFA89BDF4 -:10CA90001CA72D7645F1F2919DD0EE28FDE7A1A7C8 -:10CAA0009D782F7C89A523DAA5A73F013DA9909EFB -:10CAB000237BE254187441E77091F49ED92985795B -:10CAC000F03CEA9CE9C05FEFC3FD626E6D7A40C145 -:10CAD000C353CDDB1BF7F7CB9F257BA6F88125E958 -:10CAE000F8AEA0B6A447745BFE14996E11FA1CED63 -:10CAF0007A4CD1AEC7F81AB4EB318F763DA668D721 -:10CB0000E3F7F2B57ABB706A4F2EB7A4DFB95B7555 -:10CB1000532E9EFBF986B38C0AD2C30E7A07789106 -:10CB200012EE46F9B4086D28CCFF3982FC0EEC9366 -:10CB30001B757496EF04CB7780873481AD16B24EA7 -:10CB4000AEBF6467A1F77487B1185D7E843D51570D -:10CB50007FA43345577E4342A6AEFC4657AE2E7F98 -:10CB600073C6B5BAFA63DCC374F95B06DEA8AB3FE3 -:10CB7000CE334E979F503055577F92B750573E79DE -:10CB8000CA7C5DF954ED4E5DFEF6A27B75F5EFA80B -:10CB900058A22B97EF22D7E17ECC86EFBFD82995FC -:10CBA000EF23DFA3327A5F6DF00813F733DAB83E74 -:10CBB0005AF45E0F47281F3C29F8F95296E751E4D2 -:10CBC00057F9BEA57CB7722BEAA3FE788E1950F8F0 -:10CBD0007EB83E11F9D858CF583E38E2E04517D01C -:10CBE0003266FBA94966901783AF39D8370DF253E7 -:10CBF000B7E7DC4AF941075F4E857C61D6DDB79A1D -:10CC0000415E0DEE73F022969FDDDE97974F6064D4 -:10CC10009A94657D3209E365075F9FBACACDFD2806 -:10CC20006DDE779729E203EF89233E300D001F6305 -:10CC30007A10F818D3C3C0C7B32D8CBD097C8CE91A -:10CC400011D89FE2F777607F8AE951D89F62FA3E58 -:10CC5000EC4B31AD877D29A61F554DA1F4932A8D4C -:10CC6000DA7D5A5544E9675515F4FDF3AA4A4AFF9F -:10CC700054E5A3EF877B4BFF4340F77E687BEF844F -:10CC8000CA734E79AE595DC11A22506E349863BE94 -:10CC9000B607CF2BDBF71398D9D721F65AB6E2F9AE -:10CCA000A0378DDFC54971E2E2FB1D29DA2748E78D -:10CCB0003FA44CE8D157453D56F10686DAFCC1D475 -:10CCC000F67B905B7B733BF9DD2CCF31EC6F889D5D -:10CCD000DF4F1E62E7F78F8798EBAB91BFAA7F64A7 -:10CCE0002E8CFF3910C9DFFDA8BEDFEC473FA872CC -:10CCF00089AFF3A1F18CF2D53F36D07DE5214E7797 -:10CD000002EA2B996F39F7C77F21713EF21C5EC68C -:10CD1000F7E45FAA1F81F6C25087D5857224346E6E -:10CD200000CFDB0F447E2DE161389E3CDFDFF42332 -:10CD30000B987282E7F843ECF529E837187A97DD0B -:10CD40001D1AB724CFEB954B0D2AFA55657C921C22 -:10CD500047C21B6986FEF282F147439CB5B978DE73 -:10CD6000515DE6A0FE3AC1776B1ED5F3A8D4AE366E -:10CD700017FD72434B1D14072BE3043A8979433D99 -:10CD80009A67FE258DE224868A3809ECC7CECB7DD2 -:10CD9000D8CFD0F84022C6810DADE0EF90AD57F866 -:10CDA000FBF3326E01EB4784AC5B8413FBEDFE3783 -:10CDB0008017ED288F87F03B41EEEB5C222FCF1DD3 -:10CDC000EDC3C9BF3542C89A8F53B4CE59786FC5E9 -:10CDD000E6FC7304ADEFB4AEE8371D27ECFA7FC173 -:10CDE0002FDDB0DD7F9F5F3C9CDEF8807F4A6BBE0D -:10CDF000917491746E8F8F24DD43E2CC88CE2D71B7 -:10CE000063A21F237FB5C757929F86D839DD91AEA5 -:10CE100018A726F948B9C4DF751B5A6A277D27F978 -:10CE2000C8C807ADF988F365F5DD76EAAF351F05AB -:10CE3000E98FF8F8F7F9A841C5F3ABABE59F194DB9 -:10CE40006C5434143D94AA6D45395278C9F526E6E0 -:10CE500067B161A390A564F9E358DEBF75B9F65DCB -:10CE600093253A84CF86083EDBDF4E7FB29E7CF767 -:10CE700042F67FBC9DFAEF0ABBE1DD3019A7E271F3 -:10CE8000E40E08C68D2E1AC9F9AB204525BB6344B4 -:10CE9000167FCF9C39B89DED82FF501EDFC4B4C30E -:10CEA000D129F8EEA897DE1B1D156F786F54D8E7CF -:10CEB000058673FE9BB26E20FBFCA6CBBC5BBD2C33 -:10CEC0004BDCDF49612957F9AEE86FB3687F78A57D -:10CED000EF8AF2F768F3C57A4F12FC94E652D9E074 -:10CEE000587C9F5D33A372398CEFD1E6E0BBAD3E39 -:10CEF000CADFC8FC94DECC0264478C014584F95B30 -:10CF000018A37BFB8722C64EC33B8723FA8EE88E8D -:10CF1000DF43DED9F3237C0B54EDFF3843DED93BEE -:10CF200098EFA2FBAB07ED696487E27AB584F84B12 -:10CF3000DF06FDDC1DE67708F437A66F80FEEE0EF7 -:10CF40007AF42DD0DF98BF296309C376A35CFAB8C1 -:10CF500027D9FE66E708D8A8B58FBF9B735EED8220 -:10CF6000F87D37A6673EF2C5BB31D7E4E37CDF8DA1 -:10CF7000E964E2A9CD4A69F62BDDDBB293E57A08D4 -:10CF80008E378AC633E257E2D3884789DF7F039F13 -:10CF9000EFB485CFADB88FC0FB21F68FA31252F14D -:10CFA0007C93CBD9B28864F1BEE87B396A2AC6FB90 -:10CFB0000E223887565ECBCC78DE6EE7783A59C5BC -:10CFC0007C88DFD3380574781BFC7BCC3CDC141ADE -:10CFD00007FD8A4DFB13C271729D4AF7F5CFBF144E -:10CFE000467EBB537EEE975C68D21AB3D06FAFBA61 -:10CFF00056B9D1DE7C57253F30FBE950F2F8C8AB7B -:10D00000E0D74DFC9D8352FBA836E929F797CFA5C1 -:10D010007A68FD33C3EF4B74B1F1F720E4BB94970A -:10D02000FBDD962E362EAF257DD759851D00FD0CD4 -:10D0300000399BF47038EDB7F674F4FC88F3837D07 -:10D040000CBD3FD5DC2592F4D34111173734D09B6A -:10D05000DE5B2B10BF23F096789FFDA08897FB7BAB -:10D06000BA66CE0678DF721DEC82FE87EB193F07A9 -:10D07000BAD1C1DFC3BFDAFDB9235BECCF7358CEA1 -:10D0800055FDEE410795EE530C65E9740E3F02E144 -:10D090004539F7F62C33EAC990DF3DA079FD6FFBE7 -:10D0A000DD03C69A549C579253614FA65CFDEF2056 -:10D0B000A8625F257F0FA18017B5FA1D84A7A20A79 -:10D0C000785CBE636E9BBF839024DEA9662EAE376C -:10D0D000E4EF208C4CD0EB9111CE61879D94EAFD5A -:10D0E0003C4997891F1B9D2DF4C7D5D2BF8C11FDDC -:10D0F0005BE24CE379FCD350ADD7C3E89F1F116FBF -:10D1000071FB5DADF9E03FED774EDAA393F1F74F98 -:10D110008C7432FE1E4A925A6AA67720059DA6C0DC -:10D120007F48A7EBC5EF55E4E3EF55B0FF7774AB4D -:10D1300036D0ED7BB6AA3FBE5B7AA190CBF5F6F474 -:10D14000FE0D299EFBB341FE3C2AFC47D23F22E361 -:10D15000728DBF9724FD00325ED7379CD3DB773CBE -:10D1600082CEAFEE511B2251CF1C37F1DF471AD8C8 -:10D17000417B1CE5D38CAC0A05F191C0BC3BE702B6 -:10D18000FCD3FFCB968CF9E9DDF87B912C8BFFFE6D -:10D190008F846F7A128FE77A265BE17E3F378FDFCD -:10D1A000DA98CDF701916E27C599176631113FCBFB -:10D1B00092A767237F1E0DEB89FCB786FB031BF04C -:10D1C000BDCAF8E07B9568A7A35DDC55D8A5D5C797 -:10D1D000EC76CE874CA7FF33FD765D9C73EFAD4EAA -:10D1E0005D3EBB364157BFCF5E97AE3C3790A12B1B -:10D1F000EF7BC4ADCBF7AF1FA8AB7FCD671E5DFE45 -:10D20000DA86025DFD41A7BCBA7C126B7A02F17B23 -:10D210002C3B95DF9F50849FC4C5E931FD9E8E74E1 -:10D220005F49EE3F64DCBB26F8D9B8AFE966E57626 -:10D230007D7522E3FB56BBD89F32FDFE461371EB92 -:10D24000D2AE673E7DDCBA8C576FD907897D8EDC04 -:10D250004F84C4AB7B107E19AFDE4277F17EA8917C -:10D260005FBF167437CEA39B95DFAFABBED74AF72F -:10D2700084247C46B8D40CCEDF9BED6DBF07F55DF2 -:10D2800036B713F2BB7BCF21BF3E0DE28AF0D96ADD -:10D290003C7703FE9E40F5AFADEEA5AECB8F37BD1C -:10D2A0000F9FCF347C37378BDE5FA57B81725C7339 -:10D2B0000E1FF75C1FC1E786F1A647F3F838166D1D -:10D2C000A57B2DED8FC7F19A6065CBE8DD2A71CF84 -:10D2D000E38E55B50FA20B759AB5C6C21F1EF05B43 -:10D2E000D08F367A38D889B9E85F7DF85107D86988 -:10D2F0004F579AC92F1691639FECEB1EBCB7D30D05 -:10D30000F669C827A391FED0EF923E3C3E3D0B6DDF -:10D310009F0EE47F6FB96F61D3C97F46F2BF0DBE28 -:10D32000237E94F3F89FBA7F21F9D78827B92F6716 -:10D3300042AF75177049FCC97521F127EFBFB8EEF0 -:10D34000B478373AE81E4D01C6E549FAADE9C3FDA8 -:10D350009CD3053EB01ECAA3F6EA8D54B3A2F1BC1D -:10D36000A099B9A29D97F19BFF0FDD4B21FCB777E8 -:10D370009FAE3D39D14A3EB473BFAE3DFEA47F5748 -:10D3800071CF2E444EF07829410F7F7713C525DCED -:10D3900017A95FC70FE570FCE689F504FADB91ABCE -:10D3A00097130CCF3FAA97AB424ECC6DF9FD10FC02 -:10D3B0003E67B985EC6EC6BC8F619CC65FD658E8E7 -:10D3C0009DC7A11E46F6CDCC758A7F8312FCDDAECB -:10D3D000429FE19D16F527B20FBF5FA538F1F71FF9 -:10D3E00066ADD497CF73F0DF1D99637CAF469EC7BF -:10D3F0005D665F5F9523F4BB9BB9C92E137114451D -:10D40000A28ED12E6BF6F3F346DC97ABDC8F45F1A1 -:10D410007752EFBBF0BC2BE41D16C06B7806EAF127 -:10D4200065E636E3225BF0DA4EDCC7398788FB70AD -:10D43000F03897E65D61FC7C589EC389FAE77C175B -:10D44000A91CEB636FE77379FC8A3C7F339EEF3551 -:10D450003B4C743ED5BC2B92E21CF0DC2B1AF8E15D -:10D460008C6967C7812941F8B40655776E644CB55D -:10D4700025BB693FF95E776D5B0EC6E99BDD7637AC -:10D48000E4EF771CA477BC460B3F9811DE96DFF1E2 -:10D490001BCCDFD569F6717BB7B980BF7702F291FB -:10D4A000E17A92F11CE3185877901606AE2578AE13 -:10D4B000F6FC6BC2A55C7EFE7B6910B5D7565E4B51 -:10D4C000F96ECB1EBC13EF194DAA9E67C150808622 -:10D4D00027168F0C87A60D5DFD4BC3916EC3943646 -:10D4E000CF2FDEC9E17AA5C1706F41A6D7F5E17AE9 -:10D4F0007532C6E6F40F89E75AA2D07A58A83019D7 -:10D50000DF45F25CE62FD688FC489E5FB49CE71BA3 -:10D51000C4EF2A6C11FE169C37A6386FF40B6C17FB -:10D52000FE189C37A6386FFC8EF20BF328BF308FA5 -:10D53000F20BF328BF3045F985DF67326F72AECA50 -:10D54000CFEDF243D6079EDBE587D847786E179A72 -:10D55000C773BBD0FA786E175A8EE776A1E5786E5E -:10D56000179AC773BBD0FA786E179A67036F0CE6E9 -:10D5700051DE79C6E9F213C0FECF0F59DF786E177E -:10D58000DA3F9EDBE9FAD3EED4B5BF9D55EADAE384 -:10D59000B95D68FD19958AEE5C6F86788776D6DA74 -:10D5A00038E29F7D295E5B1FA0EFFF89F8E7DD165B -:10D5B000DC2FAA75F3F9BE2DDCCDE95C53C0E96E12 -:10D5C000E2F72C94A6A944E7C5569E1FC9E3BC8D7B -:10D5D000FC83E762F9167E2E86299E8B618AE762BC -:10D5E00098E2B9587E0F7E2E86299E8BE1773C17F4 -:10D5F000C314CFC530C573314CF15C0C533C17C319 -:10D6000014CFC5B01D9E8B618AE762F81DCFC5306F -:10D61000C57331FC7E1CCFE72C41B8D09EEFAEDB4A -:10D6200057021FEAF6954E5D1EEDF9D0FA68CF87D6 -:10D6300096A33D1F5A8EF67C681EEDF9D0FA68CF8E -:10D6400087E647E5B8687DA15D1FDA0EEDFAD07C6C -:10D65000768DEF0DF49D8D59F7CD614C1B2295A76A -:10D66000151019057DFC93F1FCB2214C498E01C9BE -:10D670006959B279723EE435114799C39A4CF4FB6B -:10D680007BB879C4388700A3B8D5EC1F13A97CAA4E -:10D69000BC7F87FF80EEB9BB18FD1E8D3C5F97ED08 -:10D6A000DDCCA9622AEB07F36DD7338E2FEB91FC0B -:10D6B0000C81036F5A63BC4FEE62471EC6CD6E11DC -:10D6C000BF8FBB65298FB736F2D562612F6D31ED03 -:10D6D0003C88F7699A0A15BA779D6E66472C798857 -:10D6E000A78A3CB42366F789117AA9E23AFC1D3176 -:10D6F00009B7F483829CA0FB89839BEA4744433F9C -:10D700009A6F18FD3ECE682BB71FB01DEE2B7BFB2A -:10D7100014CFC610FE5E20EC71CDC7C77FEE99B165 -:10D72000BC5D386FF7DC335184C7B1CB148A3B1B27 -:10D73000BC9D79F01EF43D429EF6DE1E5071BCC2C7 -:10D74000657C3CD96FE1BA64BA175AC81AF2F15E27 -:10D750000BEBA73094DB126F30BFC338BF74582A6D -:10D76000E8C7BED2FB5443FAC58CC4784456C7E818 -:10D770005DD131FD3ED4CD97C83E80FA25BDD6D3CC -:10D78000A7D03BCE637D4B96225B8CF1DDF946073B -:10D79000ACBF89B9535CA48AE8FEB184A79767A798 -:10D7A00009D422CB62F5A63005E9CD0EC585F00F70 -:10D7B000ACFC8948EF5CB785DE551E67765AE89D5C -:10D7C0008E76E2752E3A64BC8EC15E30C4E5542F6D -:10D7D000FE2C19FDCD0B234DE43759B83B82EC06E6 -:10D7E0006DAD42724DDA418522DEEFE2B2373A4C3E -:10D7F00046BCEFB4507F325EA72CCD9F6CC2FB09B4 -:10D800009D37E4C4AA64073C8FF2F0ACEFE55B07F8 -:10D8100062BDE5FC5DD18BCB76F3DF1915E73BF2FA -:10D82000774B678BF8AFC26C6F34C6C3C8DF4793C2 -:10D83000F764E4EF924A3F4FE17B7DDF44FA16AE96 -:10D8400017EF7EAF2CA4FBEFC6B8AB1261FFCD5F24 -:10D8500066A1B8ADF906FBB044C4655DEEF74A0FAA -:10D86000F531D887F27772441DA676F914FDC2F21D -:10D87000DEE7340B9703D376323AAF9AB664840965 -:10D88000DFAB66BB39FF4C5BC2ED9C69AF7AE8FE4B -:10D89000A6B41B3F10F6CCF84B4984FF8F85FD32B0 -:10D8A00009E35501CFA31BC2441C5B22A5932FF1B2 -:10D8B000F8D5F10E2E0F1AF6F177379A7D366E579E -:10D8C0001D66FCDD38037F8E33FB4D78A1D13D18FA -:10D8D000F813F263D01E82FEA6A07D1487FC9E3250 -:10D8E00092E2210B14BA4764E4F7D1968A3730DE0E -:10D8F00076F466E6F6B1507E073EC6FE7C0ABDC7EA -:10D90000A0897DAEE46323DF4F8F10FE2907F73F28 -:10D91000B5F829D056C547D47D7F9B8CF1C4D3D1AF -:10D9200067D899A6E1C1B8BDC82C5EFE8F17FF3637 -:10D9300079196E7ADAF15BA8BFB4123E34F9EE447D -:10D940003B7E04F41FA0BCBCE3AE5CEBCC1079F9C9 -:10D950007F018165E5A90080000000001F8B0800A1 -:10D9600000000000000BED7D0B7854D5B5F03E7340 -:10D9700066269364122621901048980422A906383E -:10D980007941401E87C82358B40349143009C33B6A -:10D99000A878236A0DBDB499908001C11B340AA2F6 -:10D9A000E880CAA5966AB4DE0A4ABD838855EB03AF -:10D9B0008354EF6F1B86A7A0B546B8D6F67E5EFDF2 -:10D9C000D75A7BEFCC9C9399006AFFFF7EF76BF8E8 -:10D9D00074679FB39F6BAFF75AFBE4ADFCD28CFC2E -:10D9E0007E0C7F2CAC3F630B5CF43B9BA2E6A50650 -:10D9F000F3185BB12E27953919FB067F26F62C17F5 -:10DA0000FEF54AE6EECB584D9FE01D8AC6D8208D24 -:10DA1000E993D3189B83838CA5A1022C97B1B9A25B -:10DA20003E5D1BF2410B8C5713CFEB69ED8ED93E57 -:10DA3000A82F7704A7AAF0E89FF2EACA065818EBC5 -:10DA4000A3BA198375C5D8BCFAC02CC66C7BF20387 -:10DA500003E1919AEBA2E7CC1A1CE04960AC7A434F -:10DA6000FBC6616E1C17FE57CC5895BDD5C67020FD -:10DA7000E6B77986C3FAF298EE77627BF8AF88B1A1 -:10DA8000E3EB9E7F6ABD125AFF711B9BDD1E617F17 -:10DA900093340BCDB3B38131F730C6763538A87CDB -:10DAA000B2C1C5DC318CED6E48A3FA530D6E2ADB92 -:10DAB0001B72E9F9B30D1AD59F6B28A1FAAF1B743D -:10DAC000AAEF6928A3F285060F3DDF3FD05BA0C116 -:10DAD0007A1FB0E8C7EE82FDA5ABAD8C0D8135B6DF -:10DAE0006E66780E8B700B6E829FEE18C598971F2E -:10DAF0000B1B6CD7ED2C85B1A6758A6B35F4F33A08 -:10DB0000EDC79444285B9440CC0868E09BA207735F -:10DB100079DB6FB2115E1C8E2CB7EBC127A05F4D75 -:10DB2000839DAD87478F5EC6741CE7D19FD8FDBE2D -:10DB30002C84DBA1838EAC101C3FACBFD7061881B0 -:10DB4000C797E3867673EB62B5F5F0FEAD7C4F19AF -:10DB5000AE3B3E4FB37B016E19F98CC6BFAE9FE75B -:10DB6000871A94CB37EC7FE47D3CC77D59762FE054 -:10DB7000CFFC3DF96BD3DCD8CFEBC17EF39D2EBB40 -:10DB800007FADDD29C6477231EA4B2BAF63C9CA7A8 -:10DB90002B73564208FEB59A42EBC82AE0E37F8613 -:10DBA000E744ED5A6D330DED2CD40EE0A63BFA8719 -:10DBB000E09461653E4B01C2CBCB7484D700A621B3 -:10DBC000BC06C2F39802FE3E3639043F33DCEC005B -:10DBD000770BBC1F08A5BD2004C70C78AFC2735BD0 -:10DBE000EEF1392C1BE1C6E67922E0CF83B87E84C2 -:10DBF000FB6C07D1D562073F4FA0ABA9A980872B4B -:10DC000036292E4003B6C8E9BE7E0CD417BD666324 -:10DC1000ABA13E23D96D1F00F52E38DF1D505F707C -:10DC20007BBEDD0DFBAEC2B380752CDA3286E86DAB -:10DC3000911FCAC2E87479C3A603197B117F02BA87 -:10DC40001DE964914BB727E785D16DAB427461AE96 -:10DC5000AFD3545A77156393117ED5B767D9173868 -:10DC6000B1FE9A6D451EEE8BC341F68376016C378B -:10DC7000239BBD8AF4D505FBDA91C5E72B081B7FF2 -:10DC8000018E1F363FB49FE781FA7D5A028D37DF40 -:10DC900005FBCEC2D245EB0438109CBA36C2786E72 -:10DCA0009A87CE6361C06FD3703D569817EA735D53 -:10DCB0007E1BCEB3A039DF8E7CCABB81CFE36D491A -:10DCC000B20F87FA7CABCB9E81F08B0358A4D0FABD -:10DCD000FC3BE06816015C929D380F9B37CBD91353 -:10DCE0003EF3C57A17B526D9171B9E6FB2E17900AE -:10DCF0007FD323F18D83E2DC17344FB233EC6FD541 -:10DD0000ED1AAE47C0F7D4ADB1EB591FE8DFB6D975 -:10DD10009605F57F13F87B50C07546762047C17D88 -:10DD2000DF1AABE13AE7B85A697FDDF0BD1FE001C9 -:10DD3000CF17BB3C045FC00B1F03382C6A339E67B0 -:10DD4000683D1CBE8BDAE613BD2DB17AEDAEF075E1 -:10DD50006CD99FA3005CE6007D2B007FE6F2662273 -:10DD6000BE9CBEFFFA4CDA27AC13E19AA0B9A7A675 -:10DD700015119E101E4B7CA929E4F42BE7FBA3662A -:10DD8000A5F9FE28F86774BAD45F4D43BA84F35DF1 -:10DD9000ED8E4E977664DC30AF7D91E26F527AD291 -:10DDA000A9A44F4997924E25FD3E62F304D29410E8 -:10DDB0009FA9E9C3EA9E8D00A78C7C7E0E73C5B92E -:10DDC000025C5F41B8CAF7F67CCE8FAAB28DF48EA2 -:10DDD000E3E1B8E704BFAA2A0DE4DC9A176A2FE74B -:10DDE000AD4AE6FD10EF11DFCE8973C7F62BA8BD53 -:10DDF000E063825F2CECE617BBD7F4477EF18CA280 -:10DE000021BF58B1F140C69D00B715BF8CD7100691 -:10DE10009FDCFCC42D03B251BEF9E9DCE4BA16FF65 -:10DE2000359FF8C412219F170522F38BEB73BD6A4F -:10DE30007E71A8BEE8BE5F5EE6E5FC2680FCE60FCC -:10DE4000BF7CF1C85877489ECAFD2C6879D736DF69 -:10DE5000190E3FBEDFF5B9E7E6E3792D74DADD2A66 -:10DE60003C5AD83C9FF82F4B635A8E123A7F335E50 -:10DE7000CC6F5674EA573FCAAF7E8F7C7AE18699A1 -:10DE80000CE5943C379898B15121F92AD77F593E37 -:10DE9000A7DB1FE4F3FE73057ECFAD9D641F908268 -:10DEA000FB9D5F886AC51CF17CCE22E3F3EE7373A1 -:10DEB00075F3F9B5482FE7DAF9B99DDB6023FE73F6 -:10DEC0006E77829FC1FE3E59F1FCDBD741BB8F1FAD -:10DED000D89E89FA4AF8B9B1427E6E582E8573638E -:10DEE0007D239EDBD8F0735BFA283FB7854FBDF5E5 -:10DEF000C717DCB45FCEEF36C6F8911F2F687F8658 -:10DF0000CE714ECB265B16B4BB3A3F8BCEAB9BFF9C -:10DF1000D7E5BB18C0776ECB761BF289AB251C4CBE -:10DF2000F400A5CEC2E80CE592921CD2C7647BE453 -:10DF30008FCFC03CB7DF1A9BC84686E6B92D9FF34A -:10DF400085857549C938DFC2BAF9F7B01121796002 -:10DF5000DEE789584E2F0B603CA4DB1393B4CC153D -:10DF6000849F968872F74681870F01B863011F0668 -:10DF7000C6B7FF1CE130F09FE234E41F438706FD83 -:10DF8000382FE237AEDB0EFCD301ED86DE1CFC1C25 -:10DF9000D73114300CFB6199904C25EB0FF51DB077 -:10DFA000EC1228B3555EB6E6733D09DE07F03D4B33 -:10DFB0000916E3FE257E9BF1D7CE1E6FC9463E961D -:10DFC000C2B42677085FE538125F253E47DB5FCB9A -:10DFD00045EEEF441687A73D0EF6977C09FB0364D8 -:10DFE0002D490EED4BAE0F7478DD82FAE33F0FDF63 -:10DFF0008EFAF389462DB3CED9DB7EDBA6F48FB043 -:10E000005FF33E25DD2C72709A06BAE98376C7B9B4 -:10E01000D6217D50EE9C5040BE41BF13B7C65A700A -:10E02000FD725FA897B318AE9763897A391BC6F55E -:10E0300072ACA35E8E25EAE5F43C3F99CB23164CE7 -:10E04000403D13F401CE0F029C4E3AEB87D0BEE464 -:10E0500073A91774BA8209C961FCFB649D909B2C5B -:10E06000B811E99BD50F614FC0549DAD27122C7993 -:10E07000889F7C7DB2DFEDB62EE2872CC1EE7E025A -:10E08000482EFEF677A7A4C27C8BDBB2F215E857C8 -:10E090005D5FD8590FEFAB9B5335E41B8B9DEEB5FD -:10E0A000281717FBB234948BF16DF9A7B7C0FBC5E5 -:10E0B000CD5768D8FE76857990BEA49DB08475FF53 -:10E0C000909DB054F0B5A5C82F015E4BEA0F0C75BA -:10E0D00041FF255A6C3ECAF7A55BB89D30C3C25AB2 -:10E0E0001494C34D9EA9C8C7BA1E5434D437D9C39B -:10E0F000C05F1D21FEFA7EAEE7B7C867D857807FA4 -:10E1000030FEE5288355DC57BB8EFB60A08F3CC1F9 -:10E1100070DD1ED2EBA70ABED1D9762CC19DC7E116 -:10E120008DFA3AF3EA16E4BB2B845C1B6CEF3A766B -:10E1300017EA3309166D07E797EFB8719FAFAB2C5D -:10E1400086E48D682FF8E9E09F953890BFAD48C808 -:10E150004E25BD6A8B4AFC51E24FAD58F3E2EDE526 -:10E16000FD116F16C37B94775BF121B0D0B56D576D -:10E17000F547BC5AB469CA033E906399028E27AD35 -:10E18000C199783E67B6A72637A25EB8BCE93206C9 -:10E19000EF176DBF2B13CB33DB636723BF9FEC9A65 -:10E1A000393909F6BBE4E1A47C354C6EFC45D0E37B -:10E1B0008DCBAF4A457BE0E6AF0F3CE2023B6E31D0 -:10E1C000C01AE1FE457BBCDF074D6E6ED893A902F5 -:10E1D0008D7D1DE3FD1CE1799365DF756390FF2B59 -:10E1E000FE9D03A8BD3BD5D58B9D7D1AED50C0E7A4 -:10E1F000E53FFB80C6F9D4F2E6B573A0FFCDCB7F37 -:10E200009588E3DC74FFE1512E78FED650EF7FA3B2 -:10E210003DFFB1B27DA70B05D396ED23506E7F8DE8 -:10E22000765A31E2B5E7BA3908F7D755827BB4F9A7 -:10E230006AF728045F59AFF6F7217DD61B60761781 -:10E24000962E46FAF21995D5A33E20F51AF93CA967 -:10E2500080C3E54C9FD64CC48B653B3767A25C39C5 -:10E260009BC0EB553BAF7F03F994F7F118AEB75B5A -:10E2700019E9C90B7D5CEF66B540AF0342F30F2C83 -:10E2800088A7F1966D2934C843D04BE8F9592B2B58 -:10E29000C3750C6EEACA47FDEB436B60319EEB879A -:10E2A000A0D7A27DFB17C1C73E6C55A7E2731F1014 -:10E2B00012EA231FB6FE2A61A833A4C72514B507A6 -:10E2C00090CF2D7F2EA940E52845F8754BB75FC448 -:10E2D0003975600AE9632EC4D3157B0F4E65BC0EF9 -:10E2E00082303A3C6F147A5877FDB967C8AEBB7973 -:10E2F00037D7276E6E7FE6D57418E7963D429F109C -:10E300007ACA7241CFB73CC7E1B2FCB963F685E186 -:10E31000F6486EF2DA81A0094E78F6F2D9F7BBD151 -:10E32000DE56C8AF52A965CE691C8AA5F4977491D0 -:10E330007EB83EB783ECF2E5CD62BCDC8EB5D9B4D5 -:10E34000DF997DC3F5A1890536EA27FB033CA8DFE9 -:10E3500097B1892390FF0596C7B5A05CD76F715A16 -:10E36000B16C5AEE2439FF709D25D70AF0D5953847 -:10E370000DF5B87A076F7F675CE20E2CF7C5F1FAEE -:10E3800097B19924A7BEB4789E5902EDEE540FC5FB -:10E39000A2FF6300EB3A60817A493FEF7505306F69 -:10E3A0002A03EA51517E04147CFFD96F3E2AC475BA -:10E3B0004C181C3CCF6069B6C6BC3993014F6A0A41 -:10E3C000C43EF3828588EFFD5EE6FC7A9B8DB5A0A6 -:10E3D000BC63560F9B05CF03C8BFF0FCFF66F1235B -:10E3E0003FDEA7041E0BD7BFEE1378EB8971B6286A -:10E3F000B0CEC7B3BC4B711D3F526CC35175616E3B -:10E400003507C7FFCCC6DF4B3DB65430E10C618FFA -:10E41000D9D3D39CB8BF26012F45D7593DAC6375DE -:10E42000DECB0B115FEEEE72B01898BFB42B8EF4FA -:10E43000DA8CF432926F4D022E8A3B05650E7B39E1 -:10E44000CFE28B81F5DECD1C7E6CCF1C26FDD71272 -:10E45000AB633F65DF6FFF86FC7EA0FAF9813ED09B -:10E460007EE09D8AD6046D6ACE9DDEF60E43FBD912 -:10E470009F8FF0BBB39FB7B100F6D779AEEC98177A -:10E48000CEFB6E57BB43CBE3E385EF63DFCABF250B -:10E49000265B42EBFBACEBF42F9F2FC2D24172A85C -:10E4A000749FCAFD4DA6F57C96E6B6D23975390241 -:10E4B000166CEFB4F81505DB1FF800D757EA7006A5 -:10E4C00054D4E31DB63F85CB19762823E9F41524EF -:10E4D0005AD837A02CF46FE2E737A18FD1BEDC59B0 -:10E4E000C0EDA49DE29C247C25DC985B67E172E68C -:10E4F00025E7CE6AEEC7E274FC4FE2F9B9BF669336 -:10E500007E716E1FE81911F44E591E463D03F487C3 -:10E510002FB3F5A7106E52CE564AA92BE4B02AC6E7 -:10E52000AD14F0AA745A387C2A4CF0117863C60BEB -:10E53000F3B9CBF3643F3974B04F169DE3F07F61BC -:10E54000747E7B111F3BFFF6E61A203796AEEAC7B2 -:10E55000BC59FF13CF2F103B0CF58AFB2DA457A0FD -:10E56000DE877AA2E41F5EE40323E939D703731937 -:10E57000F18D1A358EFC8C66BE21F985370ECA11D5 -:10E58000C8375A891FDCA9761DB428213E31B82C22 -:10E59000381CE5702798FEF83E6869A7E7DF146429 -:10E5A000137F18C40E0D203FAB35588C7AA0EA7843 -:10E5B0006CDB4910296DEB387D34D9FC0F2E41FE00 -:10E5C00050E9D450AFFBCC6FF1D9609D6D499C6F81 -:10E5D000B42D4B2779FE19137C64B69DF8C89516A7 -:10E5E0008B8FECAD39E9646F75B7CF71937FF5D739 -:10E5F0005FAB976DC1F7331D2477DB501E43BD6DB4 -:10E60000E3707AFFA2E44BCB385F6A9BA90F88C303 -:10E61000F733FB5B70BEDD29DEBFE1B9A7ABFE9F20 -:10E62000C7A23E79531C7B029EB765E90350DE3ECC -:10E63000A078E62CC6FEC3F9BA8373E29EDAC98FCE -:10E640002780FEA4CEFA841DE17E6FE9471FEC3BD4 -:10E65000F620C2CB57CA72519FEF44FC1C193A2FC7 -:10E66000B0CA597D72E8DC524CE726F1D56783F3D6 -:10E670004BE1E7B75A897E7E29E2FC947AC06FE2CB -:10E68000FFFC7CEE54397F672F696E2CD5FEDED4FB -:10E6900042585FD3AD702E2410837720BCB6AD4CAA -:10E6A000D0711F9D1656DB1E816EB30B85DF09A549 -:10E6B00031D0C33C410FF324DEAE32E16D7050D255 -:10E6C000E97881B7D0FFC578CF509CF753E5F028A3 -:10E6D0007CF8E67FABB323CD33BC90FB0BF68356BF -:10E6E0005A48F2B5D4A0AFBE99FF5106CA29F6D553 -:10E6F000814128775F49F18C2C04FE113BB48BFCDF -:10E70000E69D03BA6CB8CFCE391F67A05E34AFFE6A -:10E71000B7445F17BBCED5F135361C27A922CB16DF -:10E720008432B522EB20E2CF91E931EE98087AC825 -:10E73000FEE9C33250FFEDA81C96817CAF030EF0BA -:10E7400010AECFEA4E40FEC7F654131FAB147CAC9C -:10E75000A362087F2EF866D8F38D45A8D73A2D5AC4 -:10E76000B8BE602ECF02DF0C00DFFC08EC332C4F6C -:10E77000817D1600FDF504D867583F06F6199647C7 -:10E78000C13EC3B2A341A3F74D1543F604E19CBFBC -:10E790006851687CF4DF46D28B6F7C5C6501091F91 -:10E7A000F8AFF6E17816C80DD597B4F535D4176DE6 -:10E7B0001868A82F681E62A84B3DD2BBEA0AC3B8EE -:10E7C000E565858676ABE347D8F05C93CAF239DC21 -:10E7D000CBF209EE1DD74481FB35A309EE87A78F45 -:10E7E000CE40781E46B8A3FD66D512F01C24DC6727 -:10E7F00089390F9715F2E702EEA1E7E5BDCAA94FE7 -:10E8000010DE31087707951F21BC09EE1CDE2710AA -:10E81000DE3108F75C2A8F22BC87E1B800EFA20B3B -:10E82000C3FBE6DDAA010E373E6E8477EDC37D4D56 -:10E83000F01F6880E3A20D430C7509EF05CD467803 -:10E840007B57159ADA31B601E0508EBF001D1C2EA1 -:10E850009E467129AB83F9E281AF2421BDC1FAAD97 -:10E86000150AD78FE0A715E87016FE02F46575F259 -:10E87000F7CD73143FF225D489D0AE00B806E281FB -:10E88000CECA5D979D42BE743D723015ED7A3F95BC -:10E8900037B000D167350B527D1EEBCAB443798B7C -:10E8A0001A588BFEBBB71CDE27919EFF32FDDD4E52 -:10E8B0000589529B3F0CE99C3993C9DE8C764EC08A -:10E8C00029257F62CE51625FF05381FC1FFA75C427 -:10E8D0008FB8E30E3887CFE60747E1FC373BBC8FA4 -:10E8E000A65868BE3D38DFA736EFB0BEF0FCADE2FB -:10E8F000D11948FFCCD3CF6027459B6F136E16E02C -:10E9000030BF0CE0A4601C8EC3E5642587CBFE4DB0 -:10E910003176F4679C5C67237FE5E6F8CC4CC4DB7A -:10E92000936BA66522DE356E1A9689F83EAB65DAE2 -:10E9300059E4DF53D41935144F6DE578CFD8ADA421 -:10E9400077DD21CEEEB89B6901785F393D41F3C197 -:10E950007EBCBEAC445A2FD39DF9D06EA1D8F7C26D -:10E96000D6A533703CB9FF051B620CE7FFA3126309 -:10E97000BD92D943789685E76C0FBDC7F357ABFAC4 -:10E98000787BB1A3EBFFB0FD8D57C2C63B5E98907C -:10E99000827A0B1BCD467FA386FA4783EB970DFE49 -:10E9A000375EC909C155E2D36F0A3D9FE0F9C063E4 -:10E9B0008AB7012D913CB8A5DBAFB52F11E1B7297E -:10E9C000FEA57BAE44B8BCC7FD1C9BE36B887F7C77 -:10E9D000827C3B0BF9F4F519C130BE20FB07053FE3 -:10E9E0003DF2CBEB898F1CA84CA5784CC773DCBFDC -:10E9F0007C54D07D47C5F5D57700FFECD8AD929E0D -:10EA0000D7B1E7FC41F4D374B42B9A00B9257CDC70 -:10EA10008E3DC0CF91DF7A6CF47EFFEE5FD13ABFBE -:10EA20002F7E5EB157F0F32D7CFEC5560FF117E631 -:10EA30009D6DD8DFDF8BAF5F889F1FB1713CED38D4 -:10EA4000A292BF8DF9F443B9FDC3F0B38CE36763C1 -:10EA5000650CE3F295F39959154007A8E733773130 -:10EA6000DA949FEC29EF47F27283ED38EAD32EF85F -:10EA70008772DB0CC74A663D1E0CC3DF9B9F83F683 -:10EA800061EB9B85EFC3F0D98CAF2545467CFD82B9 -:10EA90007D9569CFE6EF0FF50FF13DFC09E72F9269 -:10EAA0006F49FC05BE55837C0DF8CA554580B73FBC -:10EAB0002EC8FA4D5009E32B17C9C736C57F4D72D2 -:10EAC0007073FCD784C7872B051E839E81CF3BAE16 -:10EAD000E1FA06F3CF267A9827F5089B2701FDA4D3 -:10EAE0004756F54DC4F7C79ACB89EE243D99E73BCD -:10EAF0002AF04FB69B67EDB26911E4A17795117FBB -:10EB0000D8AED984EF7798F02CDAF8E6F6729E79D1 -:10EB1000A678AF799EDB8A84DED95E7D51F3211918 -:10EB200076F727FD362E84972AF2812F1382A47F51 -:10EB3000CD36E86547CB46935E76B8E27C44FDEC83 -:10EB400068C5F9B74623BD95D904BDD752FF72F108 -:10EB5000DEBC8E8F84DE704AF08F1382AEE57B754B -:10EB6000FB9AFE7311EF57A91AF2AB23330A09CFB0 -:10EB7000CFF82B69FEA3152AF99BEE2F9A3217FDC9 -:10EB80004D723D72BEF26BCE27A03FED0B8017FA9F -:10EB9000C7CA6D5ABF48FA85191ED1C695F803FA3F -:10EBA000EC11DCE761E4A3F8D66B84D361EC0FEFE2 -:10EBB000676D5729DE6686D381E9C3882F1DDD2561 -:10EBC000F827C015F5F0DA878DE7BAA42DDEC46FFB -:10EBD000FA1ADECFAAE47A99E4D7727D87570DE955 -:10EBE000179E3775A1F396E35C2CBEDC28FAA3D8F8 -:10EBF000FC86E46FB2613CB0144DF3659BDE5F6E42 -:10EC00007A5F60AC5F241E1F13F823E5CFB158ADC7 -:10EC10003A521CEFE8D531B5E1F9099D45DC7FD3C7 -:10EC20005924E2DE9728B7FFA328B2DC8ED65FF224 -:10EC3000BDA70B3D41E4772C504EF1EC8BE57361A1 -:10EC400072FE4C11D27950B1637FA957DD58C6E5E9 -:10EC5000C2E6F8A7284FE3D346AE17ED6F8C213CF0 -:10EC6000FCF335FCFD9FFFED23D2A70EECDD9C18D5 -:10EC70002EE7255E9EDD332D11FDC2272B1E4B0C8A -:10EC8000B703E4FB8F2B1EBB672CD1B7AAF5762EFA -:10EC9000DFD61EE8A810F680D0176EB2B6FF3FB1DF -:10ECA00007CC76C014F5E144E47F667BE0AC5B4FB3 -:10ECB00074117C04DD09B972A380CF9F6D7A22C5DF -:10ECC000E9761572B962C24F0987D3120E1BCA7B4F -:10ECD000C59B53422EC8FA622B2378781D8CF465AD -:10ECE000D6A66818FFC234951238974315F98FA13C -:10ECF000FF4AB67FA65825FC96F31CD9A6B4A37F7D -:10ED0000E5B7CDE5D57760BEC38C78E2ABB2FD1236 -:10ED10005FEFF2EBC8C6A46B711EEF1655C3475EDA -:10ED2000DFB17EE1EB977A9AB9DF326BEB45D9D14F -:10ED30005EDFF644B46F83629DC1FDB1767742CF4A -:10ED40007E18AFC1FD2F9BA16A8DB0FE651BF8BA7E -:10ED50002A7DAA960DF5DFB63E762DD2C1897A9B23 -:10ED600085DB072E039EBFD95AF836B63F59C6E554 -:10ED7000CAB18AAB12310FCEB7C5A6E5B87BCE5764 -:10ED800053CCF3D2CEEE89B1A0FFF46CBD8D05C893 -:10ED90007FE1217BF9C88621549E45F871FB9ACE0C -:10EDA000FFC662EEE73AD1BAB03FA72737AD43E2DC -:10EDB000CBB15D6A993F02BFBA519CDBA9AF9E26D9 -:10EDC0007C7B755739C9E313157C9E53ABB44484DF -:10EDD000E7EF36A844C7277D7CFCFD7BEF4A1C0B80 -:10EDE000FB385BC1F77576CF9D6F8F817D062BA4B5 -:10EDF0003CE6724AE6F704370CA178EFA7CDDCFEBB -:10EE000096F42EE3E157AD3C9248FDA59CDB3DDB3B -:10EE1000B0FE8E5D27C80E3BBB0166E372CE998FB4 -:10EE2000F986BC3B5B32C378BEB32AE20DF5792D7F -:10EE30004679D6B897F32BB39EBB7803E8C1E89721 -:10EE400032D9790B1B0B134B907E510FC63C932785 -:10EE5000CA0FA6E23EDAABA95D85889B2D6C8B318B -:10EE6000F083CA66A35DB7C064C7F5B0EB4CF24847 -:10EE7000C2697914F924F5B90E61AF1CB579AA23DA -:10EE8000E553B41773F9330FE8370DE3444CAFBCC7 -:10EE900052C07B3DC2C7DEF5450EE8D31DAA361E23 -:10EEA000F5EA1E7460D203CBCB8CF0659A8F95483F -:10EEB0007F849BF4FBD3A8FFB7F41572DB0772289D -:10EEC00001E592FE6C31CA958BF51F5CB47E5E2322 -:10EED000F4F31A837EDE814DC2FAEFAFBC9EFC5480 -:10EEE00047AEB99EF4F523DD7E2A8FC14F25F5BAD2 -:10EEF0002333CA0DFA67D8F33EBDE58B47D3378F6E -:10EF0000213F263ECDE5D25A6147360B3BF2C80C75 -:10EF10006147A630A223AB556791F8D9A5EA6F0BDC -:10EF20009A8D72C9BBCA683F3E3FC97B16CF252662 -:10EF3000ED72C3739BABC0E83F34E1E740C6FDE729 -:10EF400077A12F00E0DE54C9F34EF139E6BF48B98E -:10EF5000C4A03DF28BCA0D97FBD7F3F73EB500D3A3 -:10EF6000E518AA74D4DECAEBBAC2EB3EA778AF8A22 -:10EF7000BC371BD48F6569B351EFC2BC9EF864FEE9 -:10EF80001E516420E075627248FEA15F3F9687D6ED -:10EF90007D89D06F5045D62B48D798EF735901DA49 -:10EFA0008C3C2F2C0D5DFA05347E00F37A824D13D4 -:10EFB000C9DF5CEE48E4F179B0A37BC7BF46AED7AA -:10EFC00095F5A5C90659F97AA2E2B36877217C0EB6 -:10EFD000D3C3068C223F9A85FC2D9BE247D8107F35 -:10EFE00067393D190807C07792AF1DBFB1131FDE07 -:10EFF0005FC9FDB01DD3476FBB1D9E8F78DA49BE38 -:10F00000F48EC5D20FDE95108EB747579DB0205FA6 -:10F01000FEFD1EA6611EE3D1DD5507DF80710EAC3B -:10F020005AB8B118E9E84D95EC06B3FF76D2D3E3B0 -:10F03000C8FEBAEE1A95F2BB0F97A90CE5DAE10DFE -:10F0400071063B24E4D755093FBED867A5F768EAA7 -:10F05000E462FE15FA37314FAB8C9FCB0B829FB524 -:10F060008B73FCB9D063760ABA69137473AFA09B33 -:10F070007566FFEEC39C6E0EEF01C301E4FA3B33ED -:10F08000169692DF7A0BA33874D674757D11ECEF67 -:10F090008A18CD86F09B34239FC3B342B160FCA68F -:10F0A000BC2CDF86F47E455FB70DF96879D94CAA90 -:10F0B0004FAEC8223B7FFF2A908F68EF2768194820 -:10F0C000974367C4042C89683716129FB8F28CC521 -:10F0D000402FF9813803DD5DFE78B2E1FDB02DE906 -:10F0E000867A3F4FB6A17DDF32233DC60D2D30F22B -:10F0F0005DC6F54209E729EA38F2731D0DC9517A58 -:10F100002FF511E9AF93ED015A06BED622E4C808E7 -:10F11000A8633EDDBA8A2607E64D7CD16ED5F8F8A5 -:10F1200055A41F38B29E73209D606815F3AB5AA496 -:10F13000FE29FCF74C67A6756D6018673D5AC60836 -:10F140009F62873205F5AF3671DEF7897981AF4E60 -:10F15000B2919F8E9F63DF191E6AC73C46FB200D4C -:10F16000E9AC00F184F7FFB9E8BF53E0CBD1B2C7F7 -:10F1700056C7213ECC66A46F4C516F5E8DF1C4A37F -:10F180003318D1497BE0E5385C3F8E83F9812F4409 -:10F190001BA7E2571FDE82EBD965A771CA1F671351 -:10F1A000104F2EFFD1B18FDF46F06D711D88653D88 -:10F1B000E5F088C7750D81937B86056C540674E471 -:10F1C0003FB9670EE9180FBCFCCFBB3E7E8AE1BC9D -:10F1D0005C2EB408FC36F3D75F3CF1EB05289F7F2B -:10F1E000B1736BC10750FE60F583E9F550FE7CF505 -:10F1F0004D5B6F7787FCA53BAF5DBAA30DEAC37E7D -:10F20000F8D3279F43BCBAF6A7FFE7395CEFB57F79 -:10F21000FBA313D67F59530243FA96EB33CF93C621 -:10F220005A148C8B221F25BE6CF5517DBECF68FF12 -:10F2300098E53EB6B702FCCAEB7F41F1E534D1FF59 -:10F24000F03577292ACCFBC17CCE573A1ABADA2698 -:10F25000DBA87D00DB039FA47CCD818380AD607F34 -:10F26000BB4FC1B83828481AC67B07C07BE4E7CC3F -:10F27000ED26FD2A53E2AFE02B78CD81913FD04AB5 -:10F2800078962BE291C87F91DFBF312A9BF8F2403C -:10F2900027D3F17CCB5EDCA0609EDAFB5EB7467ABA -:10F2A0004103BB7F32D8C997AB3CEF22B7ECFDB925 -:10F2B000782EB055ABB72034EE2EA1D795BDE8A47B -:10F2C000BCEDF77739B7939E7FE85A4BB87E58FA72 -:10F2D0008B3F3DFB3BC4AFF9B1845F66BDA543D016 -:10F2E0004777DDE6DE763BC0C7F71B07B7AB747721 -:10F2F00006D9E99A3B03F377BADBFD54C6D3B43F92 -:10F30000223F9F55154F7106195752CB3E5F83F42C -:10F3100038AFA4AE18F5F7743C87BEA138F607CB1A -:10F32000EC946FE053E2282F3D5ABCFABF843C6452 -:10F33000AC6E24AD83D58DC6F2FCECA66D767774E9 -:10F3400079D52CCE35DA7B9B9D7923C595FF6B143F -:10F35000F72336E139D8C2CEC1F9FBB9181F8E7632 -:10F360000ECCEA2FA03C4B876328E681A48AC79B7A -:10F37000E37FF616CAABCE235C5EA5D67FD980F4B8 -:10F3800027FD163569AC3B6EA6433F9BE8972AE202 -:10F390002C48C3A87FD78878516735A378516AFD78 -:10F3A00047FF8DF0D924C6AF798F8F6FB706F6234C -:10F3B000BED438DD24773AFB256A78AF897DC5F362 -:10F3C00053D219C747393E13E3E3CA59D8BA53E3B6 -:10F3D000AADEA1EB101358201EF14771D0BCE9AB97 -:10F3E0006228AF55EA57A9F577DDAA8E308CA7A021 -:10F3F0005EFD7E15B7B7D1ECEC1E37CBA057919EC2 -:10F40000655E87ECD769637BD0FE0DD3B3480F638D -:10F41000E1F30C31D4851FCD58B7A5D90D7CE2FDA1 -:10F42000AFCAFBD47139E04E19C5FD77080FA98F1B -:10F4300049BDADC7B882DEC3F44B1FF20B9947D16B -:10F44000AD27D586D94DD93DFBC97C35790E129EA5 -:10F45000D1FA3F3F499F329AF4AC008DE315C3586F -:10F46000E29D99045F13BF04B6C5F3E9851E0A5AED -:10F47000A4218F41EA95923F770ABE1BCC0A92DF06 -:10F4800050E6890F823E99D0FF86D149DD79F6A8F2 -:10F49000071D6DF88CE2EF35A887C2FCC1D59F1817 -:10F4A000EEA114954EBA81D66BCA97088BBBD27A5F -:10F4B000BD826F4E519D94B7D2C9E234E45F9D3E48 -:10F4C000A18FFD219EF431C92FCCFCE11ACDC8FFDC -:10F4D0007F5462E4FF33F5BE26BBD018A7AAF49888 -:10F4E000E2E1EF4D37F04DC97FEE44379F8AEE25BC -:10F4F0000FC575DE14FCF26DA107DA591D3D77309A -:10F500007E7F348EB553E96487A84C645D54BA9805 -:10F510008BF26B929946650AF350D99FD55199C6E3 -:10F52000783E553A6BA772103B446526EBA2D2CDCC -:10F530005C162CB39946E550E6A1D2C35C14277F34 -:10F540002F21987118E037E37A26EEFD1EBA418725 -:10F5500073EAAC64A17BC04857539840BEB7F9FB2F -:10F56000E9B2FECE0D3ABE9FC4DB6F7DFEBD87F0D3 -:10F570005E30F01BF1BE83BFEFAEBF7BC324EC6FE8 -:10F58000B3507DA7687FAA487F08CFFFE9D18CCE12 -:10F59000BBAC48DF36BA38543F53A83F1A5EEF3F42 -:10F5A0004ADF1E5E1F5DA83F16DE7F49A1FE44F8BC -:10F5B000FB7DC5FABFF2BA8BF0F23D9B4EFA2EFCF2 -:10F5C000EC5246717CC39F3EAAF769C2C3DD8A151F -:10F5D000CF3546D09B1DCF51453AD21C31587A7851 -:10F5E000DE4F30D6198CB7F462FF98E82888FC0902 -:10F5F000F070B8E2DD47F398F889E213F98329C681 -:10F60000B809E03BF95583ABB89DCE58E4F772DEFC -:10F610000BE139D3C3FCBCD9A171A3EDC38CBF8767 -:10F62000849ED721F4BCF7441CB97BDF416BD269BF -:10F6300047888EA3DB8756763A9C5FF6D8F79FAA59 -:10F640006D40D7C1FA1817CABBCE58F636DA69BE74 -:10F65000232A433DE352D7DB5638F50CE78B835C16 -:10F66000C867BAE7157CA6137F053DE78A3ED2BE80 -:10F67000D41C1CDEDCEE4812EB6A9A9C7C752EF9D9 -:10F68000F3B95E9F673B34731AAC337503F7AB264F -:10F69000227D63E8ECE93FB8308ED63AC5C2904F80 -:10F6A000AD917E5E933F6ED3E415AE707FF09A44C9 -:10F6B000BF82F1CBF4402CF743A4307F2CCAD13267 -:10F6C000AD8CF2667CAAAB0CEB55ECDA5CA82F682B -:10F6D00053DD6530EF81B65FAD403FE0A22A3BC508 -:10F6E000316CFAD4B3DCFFC7F33792059E37AF8B8A -:10F6F000D10208C77E4EF2DBE6AD2928437BB7C9AD -:10F70000999C8CB8985CB584FC864D4EED35BCDF79 -:10F71000E17359283F91B9744739E82BDB6FB796ED -:10F72000211FCF78A628510D5BF789E673B1180722 -:10F7300079D465A1F78FAE2A752C71E23D46B017DA -:10F74000A03CE03AAEA3FEBE15DAA0BFF19EDAE31C -:10F75000AD97F5728E89657603DEC66BC67A8CC965 -:10F76000DF6833E905C34A1252E89C47B15178CEAD -:10F77000239FFC8AECDF794E37F9D54B5B14CA8F97 -:10F7800009EED73251DF3CB17118E5BB34B718FD33 -:10F79000D1C10C9689F77DE6B72AA4AFAACD9F37D1 -:10F7A00062BFC1B9EE0138CE60AD6B802B8CFE1EFE -:10F7B000FDE98F6351DE35E38535C223C6E342C2DE -:10F7C0005E95F7CAE7BBCE55A3DEBFA8F55D0FC2B5 -:10F7D0003F49B710CD1CB5F9D3F0FCD74F9A45740B -:10F7E00089F7B4508FE9A18FFE15D619763F614D88 -:10F7F0004A761CCE1BC25F3D11F77BB2B590F4A3D5 -:10F800001D2DA5741FC03CCEDD0DAC1DF5D6350DEC -:10F810008EF648FAEFDD999E4CBCBF7D6AD3A4B545 -:10F820000CCEFFD4FE656978DF7D716B0C8B75F7AC -:10F830006C7F72D3689A6F31DEA3C6795B67DA5149 -:10F840006E4C6B9B6447B8DDDD30FB99F0791E2A66 -:10F85000F5569700FDC5B73E4378E264011FC2F537 -:10F86000DFC7EB99A85F9CCC6111F33997962844C8 -:10F87000B7BF1BEFA1FB29A73222B7BBA984EBE7D7 -:10F88000C11237BFB76E656F2F4D217BD085F47ADB -:10F89000A2A590E277368CBB0FC1EF567CD580F8DD -:10F8A0007FBE6AE1074BE1FD9AE9D79DC172A4BD15 -:10F8B0008EF466F67B95E801F442BA27F69F150EA2 -:10F8C0005753581E21EA8FBAC1AFE161687FD85AF9 -:10F8D000D4801DF8BB6DDF69D2C3115FF530FCA584 -:10F8E0009F51429F17F92169A3E8DE1DFDACB9FACB -:10F8F0003A7F00CAE32D0B1D91CE31FAFC61E3A2E1 -:10F900007E3B99E9B161F383540C905FDBCBE7EB6D -:10F910006E27DE8319AAD3FA845E6E7EDF4D6F5B9D -:10F920008CF4B94D9C8FD4CFA3ADF7077E63BF177E -:10F930003038818644FBB5067AB95C6D5F817115FC -:10F94000F63EE7FF60D7314F84385788CFC2DAFBE5 -:10F950000BF8013CD7A6CC22FB24DA3AECFE437A22 -:10F96000D68890FDF68334E3BA64BB17C4BE62FC4C -:10F970002C604BC43240F73962A03FCAEF2FAA6E09 -:10F98000735D1D812E6469E65BF8E30E8BFF98F9C9 -:10F9900004A2C150A98F58787F3D8CCF25DCCFF5CC -:10F9A000DF935B14D27FD76FE279145FF8A14ECA60 -:10F9B000053F27542DBE11CA8E33ECDEE192175B52 -:10F9C000EEB9DC6D80DBA2F0EF999C79F2276FE352 -:10F9D000FB8F9EFA8907977B57CAA244CEB78E2D1C -:10F9E000C0794E5D61277F0CFE38247E40C3A5FEA2 -:10F9F00018031EAEDFFBE496052877F63A344CC7B1 -:10FA00005BBCC5F83E262D6C5F8CE397CF00A760EA -:10FA1000F64CA0A3A33FFD57BA1F1E87FC13E97144 -:10FA2000550CDD0B33C3795C49F77746086F1784B3 -:10FA3000E250741F44D2D5F10D4DA7541867ED2A3A -:10FA4000BB9BBEA760B2BF8EBA67EA6961F161FB7A -:10FA50002A7E4F9385DB89D9A1FDCB718FFA163AA7 -:10FA6000DCCE9EE3F5C0BB28E3F529D5BF46BE98A2 -:10FA700056EA6163281EBD90F65DBF67D5D137A0F9 -:10FA8000CD3D715EEB987EB8FE21A314BC2F63754B -:10FA9000D3BDC1E6664B2CF2FDD6766BEC50847775 -:10FAA000B385E47C6B7B4ADC50944B4E0BC54F51C5 -:10FAB000AEA861FEFDD16338BC42F2C39318AEFF1D -:10FAC000C4097C3C952BF49FC95CFF519EDE477AAC -:10FAD00047F31A1EA792FA864BE08FAB99C721A372 -:10FAE000E93FC87870DD09C58B5CC8D7D624F2EF32 -:10FAF0006F2C9AACF9F03EE7554E467263305EAA21 -:10FB0000403DCBC9FCD3601ED5C5F51B6F2B237DB3 -:10FB100026D9E9D410D4A96D7E1FAD5BE774E680C9 -:10FB20007F08CFB85C9DE1F856935E6137E90DAA76 -:10FB3000A9AE8D11792B428F6042FF96F1E0848D42 -:10FB4000BDE70149BF6EABF04F80FEE4A37B2325E8 -:10FB5000CC8F78CB74DD9DD23F6407A489EF1EA5BE -:10FB600095B0ED4D61F127457F95FC06D22F29FD1B -:10FB70000FD2CF31A204ECB5C4307FC44B605AAA77 -:10FB8000140F9B8E789205EC80ECC93CA6F0EB1923 -:10FB9000DF524FAFBFB8B8CF432FF3FB41CD9638FC -:10FBA0006D4756CF76378DE3F8167700F6867AEDF7 -:10FBB000F50EBA873345DD4DF7EE371759785E33CA -:10FBC0003BE4427D60E118CE77B34A3D0BC6503C22 -:10FBD000D593857803F0F0D9F0FE9EF0DB66DC91DA -:10FBE0001D87FAF007034E6F42BDDCB7C642FC46E4 -:10FBF000C231ABD1722FA261587C2E602D08C5D9BD -:10FC0000D67BCEF9F0BEF0B5E3B8DF356EE6C9FDC0 -:10FC1000E8075D37D4427EF6BB12748ADB01FD38FB -:10FC2000541EAF7B0DE36D2DEEE464FCEECE534924 -:10FC3000FCBDFC7ED50309FDB787E797948EE3FAF8 -:10FC4000C8034A647DA5EF3885E759ED0540F621E4 -:10FC5000BF16B7C77D5F54E9CEB03AD21EF4FF1786 -:10FC60001FB7A75BF67E51E51B4A7692789F534DEE -:10FC7000F63AFA18E1FD89BD2F55F9A0FE4856E481 -:10FC8000797F2BE67DE475EF60D467837B017FFA93 -:10FC9000443ADF00B394D0B89918970AAE8C991DF6 -:10FCA000E93B3683C6F37D6E8677317D427AECE69A -:10FCB0002AB39EEA277E75BEF6F8414AD306FE5166 -:10FCC0000CF490C422F3CB0BEBAB5A1AEA9D4D2BEC -:10FCD00095B5C83F9A405FC5B860AACB4EFA6A7323 -:10FCE000D28F27E1B99CAF652EBCEFBA03D43EE4B6 -:10FCF0005FE857C57BACD3EA399FF1BAB89F15ECE2 -:10FD000038CF55888F03AC848F527FB55671FE7300 -:10FD1000450CCF47EE4C7292DF34A99EE71FC7FB1C -:10FD2000409FC5FD4DE6F9C33AFC433E24F55B67B1 -:10FD30009ED590476C37E5195B4D79C5FBC718ED2B -:10FD40009984E2A25EF5AA97C0FEC575EE03FE8314 -:10FD50006500EC602C5F06BB1DCB57C06EC7B8C1F9 -:10FD6000AB0DB954BED6A0D1F3371A4AA89C981946 -:10FD7000A4B822F991C97FC3020AF9F1247E7D3A21 -:10FD8000A814EA4F4DE2EFFFF3853B1FF50D82F714 -:10FD900029A2BDEFEA6AC4D7EE3AABAFC6F6356921 -:10FDA000BC5E3DF6C7D5E8FFE99AA27F88F2AD9F19 -:10FDB000C5337F0DB6FD498C16C9BEAF1D2BE47946 -:10FDC00014FB9DE127128CFE9CB3637AF1E73CA003 -:10FDD000F075F4DDF7D2C348177D665A3D88C799A0 -:10FDE000D9463FFFD563395D3C3896F39FCC3780C9 -:10FDF0003E7A81BBA48F68EF9BF6020A44A02B5980 -:10FE00006E4E6013E87E76B57D76A43CA7F3827FC4 -:10FE1000441DDFC9DC312343F4D6E434D35B90E2E4 -:10FE2000BBE7EB6FDB8FF2F2BBD31B23FB3058AD8C -:10FE300093BC0E02BD213F576B39BDA9567E3FB31F -:10FE4000E64DEE1FD981F485F970486FF0EB341F51 -:10FE5000AFA79AE8ADC94C6F4E23BD0591DE60BCDB -:10FE6000241FD72FE2ABDABF577A1B39F6BBD1DBA1 -:10FE7000BF8F0F525E436756DD0084CF66F13DBCF5 -:10FE80004BA5C337C7DAB93C18AE935FA0597CFFC6 -:10FE90001058CC06FCCECAB4418DD66480DF8C9459 -:10FEA0007CFA0EC16D63FB0B3A39E4447F4DE224CA -:10FEB0007DDA58A4AFEBCED0FDC67E164EBFB5633B -:10FEC000BBAA90FE32D674CC9C8674B75225396991 -:10FED000DED78B1338DD35297C5E38B901E171BD81 -:10FEE000B963393EBA5736290ED4C7E7332D278B6D -:10FEF000BE2B43DFBBF997E6FF74E1B82F4EE0DF7E -:10FF0000737137BE97E4E5FEB534B4DFE84A734158 -:10FF10004F7A849F765B7F033D2FC47D44A3E70B1C -:10FF2000F18FE01845C085511EB057DCDF94719108 -:10FF3000A8F46CF2E346F51F0E8FFC5DCAC9E3F925 -:10FF4000BC4DC2FF6BD6F7E4FE0F4FF2FE6C2C8C5B -:10FF5000A3385FE57EE07DCC8DEB9471B3EE3C235E -:10FF6000A91FFA98BF09F56D2BA832FDB9BA81E334 -:10FF700075E71F093D7159A9771D8EBB9DB9F7A380 -:10FF80007C736A3C5FE1F949FA7A82E7B7D4034BA4 -:10FF90004AF57B71DC6878B56C9AFE406FEFD957F3 -:10FFA00030CAA8505C6BD24C2BE70BF58AE003CE2D -:10FFB000B576A86F4E027EE646BD9DEFDB057CC39D -:10FFC0004D7686D18E988ACE48E41BC84708B8FA89 -:10FFD0000CCCAB4C14E387E475F020EAA54180ED2E -:10FFE000BDF02AD1C7E575D39B9CAFD881AF505CDB -:10FFF000BA84DB09F25E507C9E46F697AAF76E3F04 -:020000023000CC -:10000000584DF6FD9EB1C27E28604508B74C8BFB6B -:10001000BE31F0BCF0C12987C7C0E3E26D8BFBA203 -:10002000381DBD7D4D397EEF6BD913A7B6A39F74E4 -:10003000CC7FC430F15D35CA33F83BCA193A97F327 -:10004000FB58B5CF8AFC2A321EAF19CFE59F8CB37F -:10005000F682C7EF131E8B38E725E0B1F302787CF8 -:100060001CF135021E9FF88E78FC09F6BF170F01B0 -:10007000D61D3B4DFFB437BC9D3A55FFBC377E1AA9 -:10008000163FE0F943AC96EC6719BFEC015794AF0B -:1000900039BDF8A5D6ED88457BB6A976C7EBF8DD66 -:1000A000C7A67A6E677726688E12B46FDE55E97B35 -:1000B00056D1FAA3DDED0366B96A3CCF8F3EB0326C -:1000C000263011C6497772799BEED419E68B5B5DB9 -:1000D000419B3701F5350F43BDCD9E6261BE307F38 -:1000E000CC48DB2192CB9D20C7913E803E39BD2577 -:1000F000F171A47C9EB8F23E8CE4B0F15DC0FBC20D -:10010000E8E4F5BD25E4874B287E6E05F653ABED9C -:100110006EC4EF897F05B91936CF24D044C2EB579E -:10012000390618C699E2CA32BC9F96F603C3FBABE8 -:10013000015FEC14C7E6F702A55E33DD9D6F68979B -:1001400024E21C3FCC1D6318CFAA7E75EF68A47F04 -:10015000A1478C837FF45D5E93BE60D627CCFAC343 -:10016000E82B8DF75D4658451E9A95E7476C660E5D -:10017000FA2E05F041FAEE414D284F80E864843DA7 -:10018000B8E36EF4ABCC71683E78D6BCF7EAB4F94C -:100190004521FFD9E67AEEF76BDAE3D88EF4B05555 -:1001A000D0A5A4AFBC84E37318C9753B43796CA692 -:1001B0005799EF24FD05D29FA0D4723FC3D90959A6 -:1001C0003CEF48F09FCD55DCFE7D4809C42A4338FA -:1001D0005DBA9343DFA74B638A6F3AA76F3D59948B -:1001E000AAC8479579AF380EDAD9697C3EF61ACF9E -:1001F0009B6CFC67ECEF62BE41C29F91911CF25375 -:10020000607EC2CDBC9F6FBAE83758E45BF6E1EB85 -:100210000F4C11F38D8052ADD3857FDA4B650CC640 -:10022000C3A1CC56B438F47F0C513D14684914F185 -:10023000F574114F8F57029C797C4B3E3212D828AF -:10024000E625B064FE7D91D25F38994AF461DF8182 -:10025000F2E8AE63DA3BC5F0BC39E1C76F4D84E725 -:100260002DEFAA1AFA49EFCAF07D80746D0564F08B -:10027000915FCB331FCF4DAD70B8A6413FD5B7BD11 -:1002800011E3BB23EDFEFD749EAB6388DE83D00FCC -:10029000F1616B02D029E22B7ABA4685F281641CA7 -:1002A00023384673A01C0D623BEE6F36F83F23E403 -:1002B0009B90BFD42AEACDCE1DA4BFAF4DB1E317AA -:1002C0005331BF27B31EF1B25F1CBF7FCB78DC6018 -:1002D00030FE12966F6F7745F66B82BE4670083619 -:1002E0002E4DEB4DEF8A1A47715A02F6C48B8FA33D -:1002F000ACB9F13A7F206C9D72DF6B9D3B9405ECAD -:1003000052E667C6384A2DD363474488A304FD0AE2 -:10031000AE73702D8FB30C16FEFA6F1B47A99CC0ED -:10032000F5C74B8DA3C8FD5E237E9F01882DEE1976 -:10033000533C81CECB125A5F18FC1E277E44B82155 -:100340005004EA3F12F5B77677FCE949F8F5CD5D40 -:100350002FEFC652EA7133C5FB6B877DB90F73B7B8 -:1003600066AE5B21E258C6F8C33560D585FBF9F16E -:100370007B01E1F599A6F5945A8D7182C94E63FB14 -:10038000A929C6F76583627A9C1BFAE569BF4ACF43 -:10039000FDDE157F0FE3DF9B0A3B07F5C27507E61D -:1003A000CD61DCC7DD134FC2E3009EDF58597211E7 -:1003B000E28B85F4D2ADBEA5F75702FDAC0539CA74 -:1003C00079B1DB407FA1B847998EF824FDFDD1E8D3 -:1003D000E9B8339BFCFF83EBF7B74FEECBBAE300F2 -:1003E000F7C4791DE3F07B41CE730AEA2183EB5F0A -:1003F000A1F7D7CD29EE158F72EA0FB44F0EFB8E01 -:10040000608ED56341FB39A7FE557A1E559FEFC913 -:1004100047286F2D47E085CC0BDC8A798100F79C5B -:100420005AF17DE0B6DEF3DFA43C6C0ECBEFA364A3 -:1004300006B7C2C2C79772AF873F9D71BFAF9CAF6F -:100440003B2FD0346FB7FC7371F9F7FC24AF36AE95 -:1004500038EC5E86B8C701FB8E98073A5AF8B37B32 -:10046000C963E37667C56B1FE0F8976C7746197729 -:10047000626630E23DA9A9C26FD5191BCC40BF41CD -:100480006794BF9BF0D094A93F1CD78BBE8B79B3E8 -:1004900008CB68EBFCB679B37522DE24E3AD327F7E -:1004A00056E6C55E287FF6BBFAE1570A7F40E93879 -:1004B00016310E615EEF6DC23F9E55EA598178118B -:1004C0002DFE20DB7F30C01ED12F7E6442E4EF0E74 -:1004D000C8FC50586F4AB81D24FBC9BC7CF3786037 -:1004E00017AD1917E60FF436E690BF2FCCDE92F960 -:1004F000B0441F9B851FA29B0ECC7AA1888798F5DC -:1005000042191F51AAB87F02E8A30DE745BD0BF3BE -:10051000D2A59D27F34965DE28E685523CEA5BEAD1 -:1005200055DFBB3DD53885F2BA9A5CA5AF7D177B08 -:10053000EADF2718ED29AF93FB1DBC684F0DEF696B -:100540004F15957A5F447899EDAAA33FFB84F26337 -:10055000C10EDD37EEFBE01326FFD4DC311CBFA556 -:100560009C96FEB4FD432D06BFEB5475D57ECA178D -:10057000AFE5FE9674BD9DEC34BBD3EE467F8B7524 -:1005800032A7235B1EF3EB3CCE4BFE15995796EC3E -:100590005C12F1BEA9B41383D24EF4F1FBA99D6F96 -:1005A000F2B86D3CFA5BB06119976BD2DF624B1108 -:1005B000FE16533E76BCC9BF62F6B79C1E27FCB63A -:1005C000C2DFF288E2BE1B49FD575BA6FC0E41F17B -:1005D0006F0F2F8E4753FF79FF9A1F0A7FCB834EF1 -:1005E00058DFDE0F8CFE1673FC2B42DC8B9C57838E -:1005F000C6FF8EE26E12BE926EA53F2BBD9E7FBFE0 -:1006000069AABA5B41FEB2D9C9E1ABA23F2B25E48E -:10061000CF529EFE53B75F8AEEE3F68893D7BD8E26 -:10062000EBB402C3591FC9BF25E06A8E4725D68B9C -:100630007BC0DF933F2B79BC11BE050F16DE87DF31 -:10064000352EDA567E18CB51DB6FEB3B17CA92275B -:10065000EE2BC7F22FAF07B350EF34FBB114047E7B -:10066000714FF89AE128F1D45B2BF1D46927BAAD28 -:10067000E27034C32955E7789A03780A2A4237FE94 -:10068000752671FA4C9FACBD86FEB5C17956160928 -:100690008FADF5FC7B59128E5B051C936B97909F79 -:1006A000D08CA783DB2E0D3FC79AE0F7EC96C2BB38 -:1006B000116ECF3D5CFE3B2C7FEDBF2D1EE1B6E7FA -:1006C000F1FB7E28E03780BEA76B82DF03F811E9DB -:1006D0007E3DE13751E3F6F5E7A5DEB2F100DFAB91 -:1006E0008143A03F64474B81C3180732F2D3D4EF54 -:1006F000C93F15ECE6A7ECED9C4BE0A71F9BFC5314 -:10070000A93E4E37A9BE63449FE9409FB1E8AFAA16 -:10071000E57A24887D7FBC823637E7AF52AE21CBA5 -:10072000B180F0D9EAE271E7087ECA007DEFD7C454 -:1007300087D181138E772057EB107E52DE6DADE5A9 -:1007400071B4DBA678568CEF178AAB3D3F49BF6D7D -:100750003CDD5FF8D6FEC77FC6FED2FF08784AFBB5 -:100760005701DFF1FBE657813C41FBDF5A1BB4A187 -:100770005CA9A9BF55F142D9E74A4E3FA9695E86F7 -:1007800071FE9EFEBA6002EAED138776E3C37A9C9F -:1007900047E2C3C895E7EF433F57347C488F92AF99 -:1007A00074617C2835C8D7CDDDF850B7EEB2948B94 -:1007B000C787B809FCFB11DDF820E83FB536F82003 -:1007C000D2AF55E083D5057C0CE0A1221EE485E282 -:1007D0009E921E8222FFC00C9FA06F48943C8415FD -:1007E0004A492FEBBBE8FC03110F6D12F1506F3D2E -:1007F000CF97ED5C1933D5987FA0D1BAA739EB9488 -:10080000F03CFE0879B22FE3F9C938A78C6B7E5E05 -:10081000EA79059F4FCCE5E71C8C1E670AE0FD5680 -:10082000403F9709CFDF223C97F70F841E77DB14F8 -:10083000FD6D1C7784DD4F79CEA0EF1DC6765BF78A -:100840003EC9BFB72BFC90322FEF3BFBCD12ED7EA4 -:10085000BC2F29FD669B13EC3BF0BCE7B3E014FA18 -:10086000CE2FC629D0EFB43186F21A172A6078232A -:100870005FBCCAFBD1788AEB79281FD75BE170A1F6 -:100880009EDF9C34350DF946CD5A95E47A34FB460B -:10089000D25B0DF01BA2B77ACE6F5201BF08DF7C8E -:1008A0000AF19B74E0379CFFE80CF53A2BD29DB31C -:1008B00027BFD9DC0BFC2F92EF7C83708FC077941D -:1008C00009C506BE6399F01DF8CE4FC6336E1F8A68 -:1008D000FD633C80F68FF415BE7FB33EDBBD6F2316 -:1008E0007D49BAFB5F4067232744A6B3FC09DF8D2F -:1008F000CEC662FF087476E504239DE913FE67D235 -:100900005905E1DB05E8ECA3F14CD8B7D71AF48A16 -:10091000CBD5F6733938FFFFE7FCED8357723BFE0A -:1009200042F9DBF87331FE53733EF73FFCA9FF6BCE -:10093000FDA9CF4EF81EFCA9AE716EC23FB35FF5A4 -:1009400093D1FABE09BDC495259FB64A3E0DFC1849 -:10095000796F0DF033E4CFA9555D9F3ECFED4D2D5E -:10096000DE4DFE86D771BC74C1AFCD7C19F4CE3795 -:1009700026FC1DFD0D7F2FBFE14AE167BDD07DFB49 -:100980009502CED1EEDD3709FBBE09C6C07B7A5B8E -:1009900057DAFDCDB0608FD0AB47D45E773512D932 -:1009A0003BCBEC71C15EEC26F977245A1BBC2F9E21 -:1009B000CC09DF1F8B28B7BAF767D293C3ED26F7B0 -:1009C00025D84D33261AF5646B2DB773AD20EF286B -:1009D000AEAF9704905FA7FB94764C0DF6A6D42992 -:1009E0002807536B3D940F7FA9717D331E458BF310 -:1009F0007FDF717D73DEC0FF94387FD14461CF9B70 -:100A0000E2FCD2FF6A8ECB8FB0B796917CADB6E098 -:100A10005FC060CD7B3FDE71379EF71C07DDD330B2 -:100A2000E703448BDB8F48B607E3B3A3C7EFA5BF4B -:100A3000E0115BDDEB68873FD268A1F335E70DE499 -:100A400025F0FCF1B313766DA3FC1FA90F57093EE7 -:100A500053AFD8E9BB8E557EE2335E7D5723C693F4 -:100A6000539DAC1DF5ACB8896EC23F354D273E6332 -:100A7000ADF2125EC9F8444D26BF37172BF04B1D5F -:100A80005AF7168E9F7448D530BEBD119B02CF48D1 -:100A90004059897AC4180BE545B42975E4F76855BF -:100AA000DCF4F73F92F25CA41F3D95A4FD7E36AEC8 -:100AB000BF1FFF3B2507A62F49433EB8B6B1310DF6 -:100AC000EF27DE3491F3877BA79FAEA6387A2EE816 -:100AD0007F0A9586BF672BCB1DBA22FEDE929FF25E -:100AE0001161DD5BA8DF503BF9D954FD81DB900F2C -:100AF000A8974D25BC6E555C7316E079E5D8498FF3 -:100B000069CE19357B11EC6B5D3F4F59169E6BD248 -:100B100050DA677352FF44D447D70DC8A6F95B1467 -:100B20006F5916F61B6021BA56457C7E5DCE92D772 -:100B3000F0EF8034A55B18DE3B68CB39DD82EDDA5F -:100B4000C6F03F82635EAFEA32DE93C20F1F21FF21 -:100B500056D3785C5C157171D514572ED51599FF55 -:100B600048718758C1B76A7256CFA6EF2738ED2E65 -:100B700044B2A6846025E1C74A1BC3381DB3B61A28 -:100B8000F4B4BB1B8CDF7F71E619D7D3D27D3F2134 -:100B9000CB8B7C86FE062CDD5F48F2227E20BFE5F3 -:100BA000497FF1BC1E2BEA019BD717E17CFE51FE69 -:100BB000A3FC47192AFF2F0D22483C0080000000AB -:100BC0001F8B080000000000000BC55B0D701CF5BA -:100BD000757F7BBBB777279D4E7BD2C93E816C5614 -:100BE000B6446410F25AB68494D8684FDF322EBDF2 -:100BF000387C88C476CED8B8CE34932A4E49EC845B -:100C00005667EB64C95FB2A414E44C3AD3B34932DB -:100C10006DF08042661AF33967700821D028811080 -:100C200032930461885B529A310127A2434BDF7BE8 -:100C3000FF5DDDEDEAE4AFB81331CCDFFFDDFFFE91 -:100C40003FDEE7EFBDF73F00F0C00200D90F003AEA -:100C5000C0A6224F122200E7AA200D95D8F74E9782 -:100C60006941800FE9AF25DB1EE807C8F8B2FD60D7 -:100C7000AD0A660DF0DF87A271CD3B6E5AF3C29FBD -:100C800073DEE16AB5371D9C3BAF3DAED594001ACB -:100C9000F2AE03D225AD73E6673A8E4FFE4C866AFC -:100CA0007DEE7AEEEFEDEF3615AD2F86DAFFBFF170 -:100CB000F3D175A9E90128137D68C47353BB44744B -:100CC00075A48302820E039D8DE90CFE73424A0CCB -:100CD00057D2F9C21EE39B30970E762B6B73F897B1 -:100CE0009D5F16D347ECF9710BF2CE801908D12B1A -:100CF000FC0E69AFE1B63F449628110F3F076BBE6B -:100D000028C0B31FE2FE8E67F905DA82ECBCF2065A -:100D100095C72F57FB5E6C5885CF5E918D6FEAD9D2 -:100D200079793F95C00B80FD5D65F6BD62ADFB91A5 -:100D3000232A64ECF1F8FF0933CC749AD8783F2465 -:100D400090BE3FDFF089E2441E39B0DB6569E7F70A -:100D50006FE09CC07483F437F1DFA95F8C4ABCF864 -:100D600009F13CB5424BEFC7E7FBA5F4FEEB68DCAD -:100D7000DD82BE361F0A2D3EE05FB40AE9E8B5F811 -:100D8000E4759F0BFF94054C278B38397C58C27350 -:100D900054D1B907ECF974230348A703CBEB56EC05 -:100DA000D7E9FCA3FFF26DDCC791E37BDEFA36BE28 -:100DB0000ED4D68D34E17E0A0C8F21933C7FEAC499 -:100DC0000964170CD5DE334AD36E1D954C0DDFFB3D -:100DD000B5E03199CEE8974C9A4F39BC90CF13DDEE -:100DE000EA948309C958504EE71B9380F85268383B -:100DF000DFFBF49CF3E0FF4788CF2C9F39CF916E47 -:100E000048BDDEC9DAB9747FC5926705C727ED7999 -:100E1000912EE35EFD16A2F3F83E199238E5F82E06 -:100E2000548AAB007E6B4E7E7A3732FD9E412FF3A3 -:100E30006122A6A6251C3F51A4DDDE4BFD328F7139 -:100E40008C898AFFE3B946975DCBE7B2D7FB6C8B01 -:100E5000CEEB8DC51694933EE2B8F2F80D73E5CF54 -:100E6000BDFF4B95BFED668925EFA340F3C3E42D8D -:100E70001ED227BF35E63A79B27E09ADF7731984E1 -:100E8000DCF441BC682E7D06C91E7C242B27AA25D4 -:100E9000477B23EB7F4CD3CF27CF6A7ACAACACA376 -:100EA00075A08FE8BE2CEADC9F3DEE7316BF7C690F -:100EB000C87843D4664CA8A376CA94B03DB7E10B7A -:100EC000DA5A7DFE757C90336F25CD077C6E2F241A -:100ED0009858C4573387AF7B0AEBEE24BE0CDEACC8 -:100EE00002CB9F9BCE17E8AB4AE6A4142279F80800 -:100EF000CB4712E5A31AE7F1469D72187F72154C95 -:100F000007059F92FCBCDB243E255ABCB376C89FE4 -:100F1000632F41DFFD1B19E7FB6AB7AAEFC77D7E90 -:100F200035BEEDBEDB48CF5F900D89DFEB6C0FEF78 -:100F3000B1D680D109968762CBEFEC3C71EF6BCFD5 -:100F4000138FBAD5D7896EA4C7B37411F6D9F43705 -:100F500066D73BDC747A7829D221359C7FFEBB4A68 -:100F6000F5CF11FD6C3ACF37EFACFDDE7972B27D73 -:100F700065B63F529008C4F09C2341038D00BD3FED -:100F8000C5EF6115CA65F9FCFC448AB23CBC46FF5A -:100F9000C4713DEDA616C3BE7C02B7BE1CED6291C6 -:100FA0007ECB7A7CD511797D23D17F6BD0A3C939D3 -:100FB000FA3570D00B99201102D745B95B07D31BC6 -:100FC000D7E338A8F2B29CCB9115FC7C4B515CF175 -:100FD000607B6D6C09AF677FDF03FFA0ECC0E7CBE0 -:100FE000BDDA2B2427A988443BC2E74840DCFA5AE3 -:100FF00005CC10B65D7ACC4F7EADFB095A08A02512 -:101000003C1E21BF54F7D8918A04E975D29CAA41AD -:10101000FE842D765DEF9B8AB7E17C032FCAC61E46 -:10102000EC8783DBD601CA91F47090EDC400DA79C5 -:101030001FF25D0976BE45CFD79C0568CF91A79674 -:10104000193FB4E7D8BD18CE9CDB6FF3973BC6774A -:1010500068958EF732984606E9D4155DE61857D4A0 -:10106000B04AA3FDF6E82B1CCF6FAE69767C0FED7E -:10107000CAE969ECAFC6FF88EF32883EBFAF249C57 -:1010800080FD9CEF15C8E9E3FBB5B1A2C819724A0F -:1010900037C28DA447C8976307C8FEF4FAD96F0D0D -:1010A00078E184540CA4FA49A827629BECEF254B05 -:1010B0005E93B14AE693147CF67D96C327A63D84E1 -:1010C000B3E031A827FBFA8F9A7ED28343AEA629DC -:1010D000F1FB280ABA8E7C4218960CD4F37373691C -:1010E00009F93929D983FD45382E2A44119EA37167 -:1010F0007ED8FD15310E16D1380D9215D8D70C2893 -:1011000020BE56E03C9F2DE1EF923DD677D788EF89 -:1011100092C52562FEBA7AF6A3990E6C8F82013EC3 -:10112000B63F71044D6445FAB8BD867685CF1F0081 -:10113000A39EFAD530CD760AD92F517F214C6AC2B1 -:10114000C86784DD9E56C267FCC2EEE7D397ACDE6B -:101150002870C6E6070EBEBDC5FC12E9CDED773698 -:101160009C1777283B9F71E8ED23315DF8C39D5DA7 -:10117000AC27CACE67F9FD4BB1F81E9A8F48EFAF86 -:101180009F4BEF3A350364BF523130923845EAD174 -:10119000B5D1CDC8DFE4A37EA31AAE1C3F2E950FB8 -:1011A00069D00A88AE72DFE5F201D8CF074FF88F19 -:1011B000EE676134D94FFE097CF9F6E5F0C5CD0F35 -:1011C000B8B714A0F9C276F4EB5226202D657A98B0 -:1011D000D1FA2CFDB19F5C66D1ABC4E2872CDA8CCE -:1011E0006C3D574AE6E70BCD575A92E5CF85F8128A -:1011F0008DE3FBFA2C7FE43E938967FB691F9C65B6 -:101200007CBB4432985F4BE5B887FA8552C6023DF5 -:1012100069F69B21D0983F57411FB711EFF466C67E -:10122000C33B7121C2B31FA097CD89C752C1567F5E -:1012300025D9D71AC5F060BFB6C8134F231DAF56C6 -:101240002043E72B572049F61C9101CF9F7A14BD0C -:1012500015FA9914BA690F7DB7CB9F4E49D9F5EBB2 -:101260002CBBFDE3A26F69D3B5593A9F26FBB55C51 -:10127000D0C3C3F6673243DF47BBC118D0E7DA33C8 -:101280001C97942D3B45ED267AD1CC744B86B02F1C -:101290000DFFE07DC219349F82FDEFC512EF923F32 -:1012A000259C1E2C61BB345D48C07A2E2E30095718 -:1012B0006CB6D6E9BD495F1CC77D6E1EF6BD4EF308 -:1012C00041CAE7C405EEEF750972BFB7BF9B952B06 -:1012D000F7F797A907B0B3ECA27040ECE1D5C5D3FE -:1012E0007970FB2CCE243D29CDFD4EF0498D24187C -:1012F00077A8A42FA5179EC7EBC22FF63C5E145CFF -:101300009AC76BE117DB4F6D83B35E65A9B54FA438 -:10131000D716B0FF224CCF4D16FD3E4DFE2A44F4A9 -:10132000C44005CFBD15E22AC9ED5F2184261CBF4C -:1013300064DFD610E30568D7883E52E663F287D7AC -:101340005F021D2D3A6DCABCE5D5C92EED2C823742 -:1013500072E337EBFDBB1B3E21E274BFBFCA9F1394 -:101360001F169EF8A09F8CFA9EC2BF7FB105B73EA4 -:10137000F8926CC895F45EE0E60008FF5D487A8A52 -:10138000FB2E7CE2CCFFD0F84217AEA69921675E17 -:101390004FE141C6B3852155679CED92331B47C38E -:1013A000070207072DEAE5CC2B115EB6E31E9E5718 -:1013B0009ABBEE0D163EC757B10F2F02CFBB713A45 -:1013C000CCE273F13E1854859E609C9971C4C17A39 -:1013D0005E3DB3F76D7F57A6C62B8DDA3CDF5B7C95 -:1013E000A8A5401CEDC2C20A48EFC6FD0E0FEF884B -:1013F00015627FAC0C748C3061A8F38B12E18DD632 -:101400008810A57093C085B404D8713CFE85FF4355 -:10141000DF5F83EFB755040DDC192C7C1B7132CED6 -:10142000737785DF30F1410AC4FB649347C4934965 -:101430007899F0E8568B3FDE2704CE64DEA01E1EAE -:101440006C15F86AEB89CFAE23FE8E94DC6A64706B -:10145000DC56B44FA584C746BD8CE710D73970BFA2 -:10146000AF290707E2FF771FF13AFA5E174E3CD02B -:101470008A3810E5DBC681F7B702EB19ED8BFCC9A2 -:10148000955A078211B6A73728539E7CF9379B1FC0 -:1014900036FE7EB24CD0D9FB9EA00B06CC3BE8B901 -:1014A000EF3D118FA1010F362C20EF2FE8E76B40A5 -:1014B000FAD0D3F7843FC02F79DF26FE47FB76E3CF -:1014C000619F0B0FBBF76BF3E1619B3E8DD048F43E -:1014D000417CCE38C13E8FFB1C4F607CDE8E42F1DA -:1014E00054BF9FDB4CBFC6EDD3FD516E4FF5EBD023 -:1014F0008E00ECD9FE1A6E9FEB37F8F9F3FD4DDC48 -:10150000DA74984B1F91D7BCC6DAB3523B15273F0C -:101510007A55BB875561EC5E0FD3ED1CCA27295F56 -:10152000C8A0DC1B8EEFF6A429A4B7E39F8596BC68 -:101530005EEF3B7BD287E347CAC1D883DF2F6CDAEB -:10154000C672B6E6AC27AB2740714E81234F10839D -:101550005247BFCD7FB5637C87B6D4F1BE2436CD6C -:1015600076AA2B7ABD639CCDE77FA2380BF737D6DE -:101570007E5A23BAF6E82B1DE3947B91FF7514FF86 -:101580007CCC312FC8EB0CB2D3251B9C721872F1A6 -:1015900055DD7EFE38C8E6F3DBADCE78683EFEBA98 -:1015A000E5D5A66BC92C5D455C99A2B812E95AA293 -:1015B00009BADAE71DB1CE6BAFAB3489F35DE9F858 -:1015C0003244F16565BEF8F24D8BCE17882FBB9D76 -:1015D000F1A59BAE178A2F17B439EDCAC5D273D3C4 -:1015E0006291772B7941E6B845EEEE633F583A2594 -:1015F0001B5D64122D5C56443600C76D6A50D3845F -:1016000033C7603A4AFEFCB0845445792BAD35CAE5 -:10161000C9CE3C14365EE925DCD823F280CFC46EF7 -:101620008F12EE18DC7D348ACE0A9ADB3C6CEF46D2 -:101630006367387FA1E8C0F90B6CCD741E7C628FA4 -:10164000B7F38D8737AA6909C71FB6F28D877B6606 -:10165000F38D5CDF986810F9C68FB6E9569E29199C -:10166000A578E5AB1B1BCBD95929D8BF81861BAC0C -:1016700027FB035A88E2E8D4468F46E79257DDFFFE -:1016800005928F4352DFBE2A8ADFCA3C9C774D8584 -:101690001BCB37E3387913C218EA6F6C7C956CF674 -:1016A0004499BEAF8ABE0F5731FD0657DFEEA775CE -:1016B00046C20B7A283F32D2E1611EC98433423CD4 -:1016C0004FCDF9E21E771D40268B4BF15BC4935141 -:1016D000C95F11FEC8C9FBDBFCDF1F56393FBBA544 -:1016E000EDC1A3C92A7ECCF66BA15D97D9D8CA7982 -:1016F000E6738427A4F9EB327BAD7CE7ACDF893A53 -:10170000F793671DC605765D82FE743B4F8B7FA9FC -:101710005B3AD3E447C721DE4DF633193C7F1D44C5 -:10172000099EBF0E325FDD63579BC8A37E99F82EDA -:10173000EA338E7A89D26DD545ACF8F530E5C349E8 -:101740001E5C75127B1F03D67CA9593972D54D5684 -:10175000ABD67C06E4CB5FFFA9F593FBDB44BDE68B -:1017600052EB26DF6D03B15F2BDFEDB5F87F9D3CBB -:10177000B983E4F1CF9DEFFE6EDB95CD77CFAD134E -:10178000A5595FE0C4D93758AF972DB0F0CBF9EB2E -:1017900040FB09E823FFC657202EA5FA87D54FDE68 -:1017A00020E675D78502561EE5876D4B45BC45F68C -:1017B0008498AB188B89AE41E53B490DCF51101C85 -:1017C0008330B6BEC8E624B52D8B75AE0F8D2FF3D2 -:1017D000B0BF1A2F4A1C1DA4FD2F0BE6D58B572D29 -:1017E000FB376CD56F48803DA46F92AD1C90F02004 -:1017F0009F2640F0F9EDB6308F57B4D1A6BB506E9E -:10180000DE247928E3F3E4ADFF9C6913F59F9CF98E -:10181000BF41729AB226A77936E33CFF65C923908F -:10182000E35840C18E58CFAF8F36112EF85D9B26FE -:10183000DE2B2B0CD287F170FEF57E679D072815F5 -:10184000D398C5470B378879C02FBE3F2C9DED3DFF -:10185000BD8AF9CAFA44FBA0F7EEFA977BFE408DE9 -:1018600033BE512B9CE33F983D87332E3A344F7D56 -:101870006C51BB90D796C542CE483EF6E4910FB767 -:10188000BEAB94F7A478AA3D6CAD27EC4E50996A94 -:10189000A57827580B06D71495937CDEF893552727 -:1018A000A657919D0F191407297E3495F5D938D183 -:1018B0007DEE0BC5798A02496FFDDC780FE7358B29 -:1018C000EB859F49E6CC774DBB901339371EACA40E -:1018D0007044BF85EB785407A4FE2E5F6F3E3F5DDA -:1018E000DD76FEBACE9138C61114A43E7C70DF16A8 -:1018F000ECBFAB79341F8FD1F3D67534AB3F5BD7D8 -:10190000895F5C5D67B4BDA4A7EA52EA3AF3CC3BB9 -:10191000EB8FE7D675DADBF19C6341515F99ADEB54 -:10192000DC1AB9A87C0E587EB9C4B2CB453D561C12 -:10193000B153E238E2E9867F3FB09CE4ACC1CB72A0 -:1019400000072720574FD66DD0BF564A7EE6551F59 -:10195000540BBB66D27C765C6CD34FB5E66F7DF0E2 -:101960000585C68F977B1A793EC8F83C5CEC4EAA79 -:10197000562B53BB5CCDC8C5346F095875F48C44E5 -:10198000CF6348ACDCF86064E6A76DC59427098294 -:1019900041266824A6ED2EA67F501588F04EA59E00 -:1019A000267BDBE62F74D8FF911E55D8D76A715F6E -:1019B00066FCA4FEB5AD387E68678071D3A10A8F3E -:1019C000D0AFA4C4F5E40ECD19F78C4F2E1178ECEE -:1019D000A0D7A07B22C727C5F82DB1C6B4CCB8DBF1 -:1019E0001917F5E8CEB8684B79FD2B841761D0CB79 -:1019F000F978CDC2B537D738E3A4A2CABEE708A7A5 -:101A00006C1A1478786FB464C116B47FBF6AD71D9E -:101A100071E2E6C1BBB96E34A802D7534736AAAC0F -:101A20001F23DED78F6C61DC58C0749CD8A8962722 -:101A300072F4A5B4C367DD8B10F803E1656232CFA1 -:101A4000FBD20E617750B0D98FDBF2F2179F117481 -:101A50000E55405A271CD7B3234371E578059E09DC -:101A6000DF0F46AB7A4ED2FA2FCB40E774CB6165DD -:101A70004735EBE9AC3F6DF238E8E4F5C5FB687E2D -:101A8000B81974B26BEDDDD8A73CC00615283FE04D -:101A90008BFE2D9FB704FB01ECFBBB47930AF6FDC1 -:101AA000558995848B9FD975C7702C42FE4EE8B737 -:101AB0006FC3B6F82768FC2A2F04687FA04B51DA61 -:101AC0005F52DC6770EBC3DED4F7DB894F7B0D8997 -:101AD00059B4A967FD76BEB7142960DC34EA8D6F6E -:101AE000667B749B5F4BB20F9CE638C2FB151F9060 -:101AF000DC4DECFA4D19E1EF1FB58BBA664077C6A5 -:101B0000D77E1865BFBDDA9CDA40DFAD6E52A9E220 -:101B1000014F379F61BE4D34F80C1FEE63A259622E -:101B20003AFFA1C19BA6759E52A7645AF7A93FE050 -:101B3000DA95F9F43BBF5ED97AE41E3FD2B4DE4FAA -:101B400072B117A66E25FA2467449ECA3D2EDE2187 -:101B5000FCD5DED46D350AE7B354AEB72B670DB3B1 -:101B600018670FCFC4FF9972AFC97645C449E59E87 -:101B7000A484F30DF5887B194345896192E721948C -:101B80007B8E9322E23ED27879C4D89FB3DE78F37D -:101B9000ED3564CF5E6C0830BE1F38F5377711BE67 -:101BA0006F95DFFEEEC3145755A8CCCF216FDFAB86 -:101BB0001407251B02BCDF538B54F0933D88DCF5E2 -:101BC00000C5D9707C03E4CAEB44B7D0D3890AA11D -:101BD000F7D2C31B380E189764A6B359764C223C33 -:101BE000E6EBB6F34E22CF14B3CCD9C48647380FF8 -:101BF00075558FC8A3C6BAAD7C931C4CB25CDE1879 -:101C00007880F4DF54BC8EF878CD5967BC7C952B76 -:101C10005E76E7A3FEB7DDCA475879275B2E43D629 -:101C2000988926CB4EAFF2A5851CF6956BB573F55A -:101C3000FBDF2CFC3CD5EFE77B643FEDD7B81F32D0 -:101C4000DFD95D8AF3BCDC1FE5E77FB9FAA894FB16 -:101C5000DDC8AADBFC3ADB93E928CDEBB6236EB9ED -:101C6000D8DF5EE0F027F63E8B9A5BC5FDBBB36C18 -:101C700091614D70BA8D7D234C0573F17EA65FDCBA -:101C8000737BDADAE729DAA78FF264627FCFF5EBAC -:101C9000DC3EDF5FC3EDC60E10F500DB3E5C83F675 -:101CA00001E9D05E21FA640F88FF2591BB384FE629 -:101CB0008B2A1AE9BBBF623423E5D88789A2BE5FAD -:101CC000DC4D76BF2CC8F2E83ED79A0E4FDE736D1E -:101CD0006ADEC176E71CAE43F4473BB39DED10DAF4 -:101CE000055E77837A27EFC344BBC476A1EF6B7799 -:101CF000B05DF002C9B9DB0E9424857E277491BFD4 -:101D0000B3EF09CDDA055C278DEB3C8D769DFA4368 -:101D10006807689DA1E6D7FF9AD6FDC3FB057C2F17 -:101D20006A62E32B6C175E3C8736FB0ADA055B0FB1 -:101D30005F3B153B961BCF67F9BCFE8E13821E1AC4 -:101D400008BAF6C6F3C48997CA67302F0EC7A495A0 -:101D5000E93B45DD51653ACC5B774C7A0C4A0B0C7C -:101D60004C2ADD56DD11A8EE68D71F73EA8E05CE2A -:101D7000BAA39A4E31BE495B75C7DBD78ABAA35A5C -:101D8000301DCCEEC3AE370ED2A3F26C7DFEAE8E0C -:101D9000C4AE8E866C9D5197441DFCA598F9657A5A -:101DA0000E9112F6FFEE3AA55D8F4478272572EA70 -:101DB0009B75F8DC5F92AD7FB9EB99F6BD8C3A75F7 -:101DC000FAD801A4CBC09D7EC60FF6FE061EFDE824 -:101DD000AB8948F63E805DEFB4EB9976DD13F73DB5 -:101DE00096BB6F7802D8EEC063FEA3E4DFDCFBFD98 -:101DF0005E2C717F47599E7D5F647D711D58F32372 -:101E0000EE227D7ECDA2A33DEE414B1F97AB22BFBC -:101E10000D2195E39DD607832013CE2E528F915E20 -:101E20006C86E90EA2EF4058E0BCD4212FDBC9E359 -:101E30001D3AF3AF4C35F93E44D99703C66E9C2644 -:101E400075520B51FEA9A7DD3CDEC1FB18BD753DE7 -:101E5000ED03713BD9BB5F57DF17E17A3FDD7B2A8A -:101E6000A6F8CF584C7990173AF2DF576A597C762A -:101E70003DAF5BE4018ACF5201E339BE57FCA4C2F7 -:101E8000F3F5E014663DDF5F6A574B681E713F75DE -:101E900020789AF9D552ED5BC179BDA2FC71E0B30F -:101EA0001D226E5D8B73A938CF675A13DFA77D5350 -:101EB000AE34CA722CE2BB17C84E0AFB75AFA7310D -:101EC0009B072B96132FD078382E29E41F7D96DCA4 -:101ED000D871E23BADE68BC477E48749EBDBF78052 -:101EE000ECF55FB2F890EC307F4AE35EB7D6A9D349 -:101EF0009231D2C3BA04CA83C4FAE3AAC30BB9703D -:101F0000CBAB2D6FB375784B0E254DD46B51AE5EB8 -:101F1000E7FD3EA59FF448546F4F1C3D40DF5E66D1 -:101F2000BDFBEA36F32DDA77716BFC3F69DE5FEFBC -:101F3000BA83EF055FEC3D8E96C57D51AAE30F0590 -:101F4000046E7E286638ECDDA24EC19F459D022FAF -:101F50005D8F3233C5F74B0DBEF70DB09D71B46D7B -:101F60009F46FB138FBF599DFD3ED50F93540F9A8B -:101F70006F1FDE7D3B38AF3B50D1EA27FB83F6ADC8 -:101F800098FA43156634771FA92221E7C945226FC5 -:101F900041F9B464CE7DF2924E99CFD35601199295 -:101FA0001D5F50D4DD7CA8B83AFA1F9FD9C4F78BC7 -:101FB000F1F924A518AEEAD4455C1E31C0A478B36B -:101FC000220EA4DF3E2DFB3DD551DB2AFAF8BEE5FB -:101FD0007CF3C851FBFB047F7F53A7C6F3AA118F84 -:101FE000230F7021BAB9E9324874AB9E9F6EEA455F -:101FF000D34DE89D9B5E8D16BD9E097F91CF071F37 -:10200000B4B19EF9343C27B6AB3B857D9183262441 -:102010008AC846C51141529EBD0FA80E6DD359D630 -:10202000049D65AD8FBFF3551890B881E89260BAF2 -:10203000B8E9807602C84EFCF0D12311C2A72DD892 -:102040008F0AFB013E6CBFDE21F862EBE93AF849EA -:1020500050E4BF9DFEC26D4FEDF6212BFFEC7E2EAE -:10206000750584FDD0C141F722EBF70BC786EB194C -:102070001FA0FF4CD2BD98CEF2EA02EA5FE93AA275 -:10208000BB7EE8AE13BAEB8359B931FDB4CF77B557 -:10209000D3C98FE79117BB3D60E9DB60BF3FAFDE7F -:1020A0001D407D27FE0D359B49AA1BED0D4F47595D -:1020B0006E4EBEC5B858794136085F2A8AE073E78C -:1020C000A269E663579309546F3AD0DFFB9DDC7930 -:1020D000BFDE9AF84A27CA49A13669D23C41C824D2 -:1020E000C9FFAC2D35FBF2E1A621CB8EBCD31ADFA4 -:1020F0004DDFD1B575E2FF9B31730FF52FD66ECD55 -:10210000A74F8A4DBB4BD6A7D3429F9A76B03E8D40 -:1021100054F431CE1AF9894C482A8B232D7D1A6943 -:102120003EC3FA6EEB55DAB63F4D422F288F40FE84 -:102130003B5461B2DDF896A54F0AEA09E993CFD284 -:10214000A790961D4FF9F136A2333E572AA6F9BB48 -:102150005093A57FA44F41BA3F0C8C038650EF28C3 -:102160002FE2D6AF962AE1379F684D3CD449F862FA -:10217000D17ACECB0F55FCBE94F18B25FF59BC5BB9 -:10218000CFFEFCDCB0C7207DA823005D9FD503FBFC -:10219000DCAB6764C8206BD6CC48DCDE3453C86D3A -:1021A000CB4C805B73A694DBD84C98DBD699ABB94B -:1021B0006D9B29E7B67D06F56025EAC34C25B79DE2 -:1021C00033D773DB35B38CDBEE99953CAE67660590 -:1021D000B76B673EC6EDCD33CD629D1A71AE3CFA4A -:1021E0004065B02BA00F46128A480F3EF32ADB77DA -:1021F0004DE53B4AA97023D7897CCA34EBC3B1268D -:1022000061EFBB82824F6E7D78A735F1AB7CFA30EF -:102210008B6F15D088FE2A587F2EFC80F8E737F4A4 -:10222000BD8D7BD5A8C97286F8E40CF1F37271C23A -:102230002CCE5CAC321EB571E6C822C49995599C6F -:1022400039D42CE2B2D4211FC76F5B2471BFECEAF2 -:10225000B6C47FB37E82C813256EF56B849B53E1B1 -:10226000CE6890F27A7B65A07C01E2900F789F4A5D -:102270005CDC67BD487D7E3326ECBE3DBE0E4E7BEA -:10228000FA2E01C7FC9AFED93CBF5D28B95C3FEB32 -:102290006D13764113762155D137CC7569975DB0B2 -:1022A000FD2CD2C3611796765976C1D2F3920AE11A -:1022B0002F4BC82E207D9675D976C1E967151B87EF -:1022C00074DB38C4B20BDDE23BC4ED0E3F8BECF6A1 -:1022D000430E2E46395ADE950787B03FCFF1730380 -:1022E00055D531FA2D41F82CC4483C4333FA5A23D2 -:1022F0008FDF4969F5AC07279536C8CDAF5CB29E34 -:10230000856DBF63B2DF718FB3F56DE8648F38A759 -:10231000E5874EE2F9CD1C7DEBD2843F42FF73335B -:102320009DD3AD6F2D8BCD443CCF3E3FD925F0FEE4 -:102330008FD658B81771A511647C9F17377C92F817 -:10234000D7207EA7F118DA9F8EEE644AD159CF3F8D -:1023500049EBAE6E9F92290F7453D3E8CB541241D0 -:102360003DFD5457C3E5EB6953AB55EFDB592A2EBE -:102370003B5BED85E4DFC645B61EB8C73D5469F644 -:10238000E6A3C7B3163D06863D3D74E1CF968B9319 -:10239000CA52C63F79ECAD695C117B7B71F8E324CE -:1023A000FA41E2FB79F0C7817CFC9F0F7F8C77CDEF -:1023B000E28F31E2534BADC01FCF76C179E39BCBA7 -:1023C000C615B1D34CB7CBC5150F769D1F577CA74B -:1023D0004BD84D459B66FB11BA4C5CE1B613881F88 -:1023E000FE95E96308BF6BFFDE842F50E6F82FB43B -:1023F000338FD338C20D7479EC58B03529B11EC46F -:102400009FA4E7A3E61296A32BA50F88137FD09570 -:10241000D3BF905E5CF4B8C98D9C07B4EB997F0C78 -:1024200084EA283FB2D32FDA2F15848E513BD62F62 -:10243000F2D07F0C2C4E53DE6CCC0B5C3F18940A10 -:102440008C63223FBA9C7F5F037D37527BA6CBAE65 -:10245000CBFF9DA35E1AD6B63DFE6669BEFD88FB26 -:10246000BD948AFF90EF8157689C3FB7E84169208F -:10247000F6CFD5058CFF00614B538EDD4F75AC1345 -:102480007172A59FEB79322867281F3F4C6BF1FED4 -:102490007AB98E19B0FC212849FDE3BC5F9107B5DC -:1024A0007FF7B76FF5FA627109793B8FB7E57F5F08 -:1024B00070D4AFD53AF4DDF1BB6E772BAF38A5B54C -:1024C000E17EC77485EBAE078D4880EB2615227B35 -:1024D000EE5FE489A7F3E8E9B5DDB3F722785F6141 -:1024E0006B5FBE0E11AFCDB7DEFE7EE73DAB82DA8D -:1024F000B849FEC45FD91727BAF9174524CAABCE2D -:10250000D2BB5BB2EE69189916A4F7B0A587053562 -:1025100093190FD139BC6D25D1D65F938633344FD3 -:10252000ED24BC41FEA2D2DF9B6FDFD759FB1EF624 -:1025300026E38493862B15AE5F0E57E6F72F25DD35 -:10254000C2FEFA17EDE0F1B048E1FAB37B9CD22D60 -:10255000E4689FDAC7758CA145F7F37DB721FA21AE -:10256000CD47D1EEFD70E681DDF8FC50FFF6C7DF08 -:10257000F4929C26B8DD77ED7E8DEE711EAAF76889 -:1025800094870BFB337EFA7D6678B5C87396B4E307 -:10259000B8DC7855AE08909D0DADC27972E2D031AD -:1025A000D002B4EEBE906D1FA7FDC23E0A792AB2DA -:1025B000C68EAC1275A9917576FE5FF02FFB7E7CFE -:1025C000BBB82FA7EAC079685197E2D49E4EF7674F -:1025D000EBC374AE324DD4A30E59F23568E5D9DDA4 -:1025E0007439B4788AFDC9A13553BDE43F429ADFFE -:1025F000E826B93EEEDCD7DEE66907DE1869386DFD -:10260000EDDFBD3F21F7CAD36F093B69E1FE90F1D1 -:102610007BC659F63DAEAED5420F8BAD7BF4C5916E -:10262000B849F3EDBEF6B749AA131D2EB7EF167CD5 -:10263000DE790F03A6191787565B7539F96DBEFF52 -:102640000BB78A7B12F63D6F35A23AF202A5AEFBBC -:102650005921571FE40DE7BDCFB6F397479F3F952C -:10266000C3CFCF773BEF835FE8FB3FF6A79F3F8564 -:102670007E6E6CD5F9F5CFE6D3E1FE266E6D39B4EA -:10268000E5324C47AC9FFFFBB1703C6FBDE5114B91 -:102690004FDCF2EA96D3625F9CFDFEE81AE73CF756 -:1026A000597A7E9F358FBA18CA090F8D86855E8E3E -:1026B00006A0F7913CE77AAC5BE5F159B977E28285 -:1026C000A2CBC5052B5AADB8A284F56D6C55EB7342 -:1026D0002437EF915EE4D82777DEDCC6054A8FC049 -:1026E000A5CF845589FCBA169C66BC3CEBD72D1C43 -:1026F000E0F6EB7E6FB297F4CF5FA9DA7689ED470B -:102700006577E01BC920FB0329D70F1ECADCC9F37C -:10271000865D797388387F87B2B71B984E61DDB2CA -:102720002FDD8AB887356A42EE3D9A31CFDB336FB1 -:10273000E8E2DF1FD838A292DE1F9CE2DFC7C03D6F -:1027400090BBFEDE964DFC7B880BF1DDDE17DDCB0A -:10275000CAD59B4BD58B976DBD084080F4E21CDC3D -:10276000CB757418ED76F821AE282C601320FEF09E -:10277000984AA365C7A4ACBE409755DF4E883A3D42 -:102780005198BE33ACCFCAE99604C5D790E1DF1D9E -:10279000DAF6E51CFC92D74D3E2D49B3B8E96A0C38 -:1027A000DFE9F78C4B690B9A875AF7FE9780C1CF08 -:1027B000AB20CEEDB5D0C76D0D8C727B1D4C725B1E -:1027C0000B53DCD6C1596E57802ED3222BC1948176 -:1027D000AF5E26B87F2324B96D86C4FB742774B01E -:1027E0006CDB0AB257EFBBE864D3398FBE332EB42B -:1027F000E961D3FD2132D20D17E66B2A2CEC6F5B19 -:10280000D314E3D7A2A01DFF0A39B7E7990FC7BABF -:1028100071979F70D7CAB9727021DC65E3C4FF035A -:1028200008E97101B048000000000000000000004D -:102830000000001800000000000000000000004040 -:102840000000000000000000000000280000000060 -:102850000000000000000010000000000000000068 -:102860000000002000000000000000000000001038 -:102870000000000000000000000000080000000050 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000090000010000097 -:1029A0000000000800009008001000000000000275 -:1029B00000009000001000000000001000009DA822 -:1029C000000000000000000880000000000000007F -:1029D0000000000080000000000000000000000077 -:1029E000800000000000000000000000000091A036 -:1029F0000000000000000008000093C00001000477 -:102A000000000001000093C8000000000000000268 -:102A1000000093D00000000000000008000093D4E4 -:102A20000000000000000002000094980000000078 -:102A300000000008000093D8000800000000000813 -:102A400000009B3800400000000000400000941887 -:102A50000008000000000008000094580008000072 -:102A600000000008000094A800C8000000000098C2 -:102A700000009638009800000000002800009678BA -:102A800000980000000000280000C0000540003051 -:102A9000000005400000CB200008000000000001FD -:102AA0000000CB2100080000000000010000200809 -:102AB00000100000000000100000200000000000D6 -:102AC0000000000800009D600008000000000002F7 -:102AD00000009DA0000000000000000100000000B8 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000080000000000000000000000080000000C5 -:102B10000000000000000000800000000000000035 -:102B20000000000080000000000000000000000025 -:102B30008000000000000000000000008000000095 -:102B40000000000000000000800000000000000005 -:102B500000000000800000000000000000000000F5 -:102B60008000000000000000000000008000000065 -:102B700000000000000000008000000000000000D5 -:102B800000000000800000000000000000000000C5 -:102B900080000000000000000000000000000000B5 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD0000000000000000000800000000000000075 -:102BE0000000000080000000000000000000000065 -:102BF0008000000000000000000000000000000055 -:102C00000000000000000000800000000000000044 -:102C10000000000080000000000000000000000034 -:102C20008000000000000000000000000000000024 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C700000000000000012C800800000000000807A -:102C80000000000100000000000000000000A000A3 -:102C9000071000000000071000001EC80000000020 -:102CA000000000080000AEC000080000000000089E -:102CB0000000AE4000080000000000080000AE80E8 -:102CC00000080000000000080000200800100000BC -:102CD00000000010000020000000000000000008BC -:102CE0000000A01007100040000000400000AF40AE -:102CF00000080000000000010000AF4100080000D3 -:102D00000000000100001ED00000000000000001D3 -:102D100000001ED8000000000000000200001EDAC3 -:102D20000000000000000002000012B000080000D7 -:102D3000000000088000000000000000000000000B -:102D40008000000000000000000000008000000083 -:102D500000000000000000008000000000000000F3 -:102D600000000000800000000000000000000000E3 -:102D70008000000000000000000000008000000053 -:102D800000000000000000008000000000000000C3 -:102D900000000000800000000000000000000000B3 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD0000000000000000000000000008000000073 -:102DE0000000000000000000800000000000000063 -:102DF00000000000000000000000000000000000D3 -:102E000080000000000000000000000080000000C2 -:102E10000000000000000000800000000000000032 -:102E20000000000080000000000000000000000022 -:102E30000000B00000180000000000180000B300FF -:102E400000400000000000400000B300004000020D -:102E5000000000010000B30100400002000000007B -:102E600000008000004000000000004080000000E2 -:102E7000000000000000000000008000000800408A -:102E8000000000040000800400080040000000046E -:102E90000000BB0000280000000000280000BC402B -:102EA00000100000000000100000880000800000FA -:102EB0000000008000008800000800800000000280 -:102EC00000008C000020000000000020000020080E -:102ED00000100000000000100000200000000000B2 -:102EE00000000008000011080008000000000008B1 -:102EF000000011680008000000000008000011A890 -:102F00000008000000000008000012700008000027 -:102F10000000000100001271000800000000000124 -:102F200000008D00001000040000000400001320C9 -:102F300000300018000000100000132800300018B6 -:102F400000000002800000000000000000000000FF -:102F5000800000000000000000000000000011E8F8 -:102F600000000000000000018000000000000000E0 -:102F700000000000800000000000000000000000D1 -:102F80008000000000000000000000008000000041 -:102F900000000000000000008000000000000000B1 -:102FA00000000000800000000000000000000000A1 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00080000000000000000000000080000000E1 -:102FF00000000000000000000000000000000000D1 -:103000000000000000008308008000000000008035 -:103010000000000100000000000000000000200887 -:103020000010000000000010000020000000000060 -:103030000000000800008D100008000000000008DB -:1030400000008D700008000000000008000084509F -:10305000046000280000046000008EA0000800004A -:103060000000000100008EA1000800000000000127 -:1030700000008408000800000000000800008448E8 -:10308000000000000000000100008DF400080000B6 -:103090000000000200008DF60008000000000002A1 -:1030A00000008E04001000000000000480000000FA -:1030B0000000000000000000800000000000000090 -:1030C0000000000080000000000000000000000080 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000080000000000000000000000080000000BF -:1031100000000000000000000000000000000000AF -:10312000000000008000000000000000000000001F -:10313000800000000000000000000000800000008F -:1031400000000000000000008000000000000000FF -:1031500000000000000030000040000000000008F7 -:1031600000003008004000000000002800003390FC -:1031700001C0001000000008000032000020000024 -:1031800000000020000037200000000000000008C0 -:103190000000102006200038000000080000A000F9 -:1031A000000000000000200000003EA90000000018 -:1031B0000000000100003EC8000000000000000206 -:1031C00000001C4000E00008000000088000000033 -:1031D00000000000000000000000400000080000A7 -:1031E0000000000100004001000800000000000194 -:1031F00000004040000800040000000200004060A1 -:103200000008000400000004000040000008000066 -:10321000000000040000400400080000000000045A -:10322000000040400000000000000008000040488E -:103230000000000000000008000080000000000006 -:1032400000000010000050400001000400000001D8 -:1032500000005000000000000000002000005008A6 -:1032600000100000000000040000500C00100000DE -:1032700000000001000052C7000000000000000133 -:10328000000052C6000000000000000100003000F5 -:103290000030001800000004000030040030001866 -:1032A0000000000400003008003000180000000298 -:1032B0000000300A00300018000000020000300C4E -:1032C00000300018000000010000300D0030001830 -:1032D000000000010000300E003000180000000166 -:1032E000000030100030001800000004000030140E -:1032F00000300018000000040000500001000080B1 -:1033000000080004000050040100008000080004D0 -:103310000000000A000000000000000000005068EB -:1033200001000080000000010000506901000080E1 -:10333000000000010000506C01000080000000024D -:103340000000506E0100008000000002000050707C -:1033500001000080000000040000507401000080A3 -:103360000000000400005066010000800000000220 -:103370000000506401000080000000010000506067 -:103380000100008000000002000050620100008087 -:103390000000000200005050010000800000000406 -:1033A000000050540100008000000004000050584C -:1033B00001000080000000040000505C010000805B -:1033C000000000040000507C0100008000000001AB -:1033D0000000507D01000080000000010000401846 -:1033E00000100000000000040000409000100000E9 -:1033F00000000004000040980010000000000004DD -:103400000000411000000000000000020000411216 -:103410000000000000000002000041140000000055 -:103420000000000200004116000000000000000241 -:103430000000604000080000000000020000604240 -:1034400000080000000000020000604400080000C6 -:103450000000000400006080000800000000000878 -:10346000000060C00040000800000008000060008C -:1034700000080000000000020000600200080000D8 -:1034800000000001000060040008000000000002CD -:103490000000634000080000000000080000638096 -:1034A0000008000000000004000063840008000021 -:1034B00000000001000063C00008000000000002DE -:1034C000000063C400080000000000020000640067 -:1034D0000008000000000004000070000010000060 -:1034E0000000000400007004001000000000000450 -:1034F00000007008001000000000000400007000D0 -:103500000008000000000002000070020008000037 -:10351000000000010000700400080000000000022C -:10352000000070400008000000000002000070442D -:1035300000080000000000020000704600080000C3 -:1035400000000002000076480008000000000008AB -:10355000000070800008000000000002000070847D -:10356000000800000000000200007688000800004B -:10357000000000080000804000080000000000017A -:1035800000008041000800000000000100008042AF -:103590000008000000000001000080430008000057 -:1035A0000000000100008000000800000000000290 -:1035B00000008002000800000000000100008004FC -:1035C0000008000000000002000080C000080000A9 -:1035D00000000002000080C200080000000000029D -:1035E000000080C40008000000000002000080808D -:1035F00000080000000000010000808100080000B9 -:1036000000000001000080820008000000000001AE -:10361000000080830008000000000001000080849A -:103620000008000000000001000080850008000084 -:10363000000000010000808600080000000000017A -:1036400000006000000800000000000200006002AE -:1036500000080000000000010000600400080000F5 -:10366000000000020000604200C0001800000002DC -:103670000000604000C00018000000020000604C24 -:1036800000C00018000000080000604400C00018DE -:10369000000000080000605700C000180000000192 -:1036A0000000605400C000180000000200006056D6 -:1036B00000C0001800000001000066400008000083 -:1036C00000000008000066800008000000000008FC -:1036D000000066C000080000000000080000D94299 -:1036E00000180000000000020000DE4000000000A2 -:1036F000000000000000E0000000000000000004E6 -:103700000000DD4000000000000000040000DD4477 -:1037100000000000000000040000DD480000000080 -:10372000000000040000DD4C000000000000000468 -:103730000000DD5000000000000000040000DD5427 -:1037400000000000000000040000DD580000000040 -:10375000000000040000DD40000000000000002028 -:103760000000DA0000000000000000040000DA00A1 -:1037700000000000000000680000BB6000000000C6 -:10378000000000000000D000000000000000000465 -:103790000000B0C000000000000000040000B0C441 -:1037A00000000000000000040000B0C8000000009D -:1037B000000000040000B0C0000000000000001085 -:1037C0000000D6B000000000000000040000D6B4E5 -:1037D00000000000000000040000D6B80000000057 -:1037E000000000040000D6BC00000000000000043F -:1037F0000000D6B000000000000000100000D34818 -:1038000000000000000000080000D3580000000085 -:103810000000008000000010000000000000000018 -:103820000000D35800000000000000080000000065 -:0838300006020900000000007F -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex deleted file mode 100644 index 8405e719e7fb08c5f9cd17f7faa7f588b58a0e30..0000000000000000000000000000000000000000 --- a/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex +++ /dev/null @@ -1,15473 +0,0 @@ -:1000000000005310000000680000070C000053803F -:100010000000318000005A90000000B000008C18F1 -:100020000000C13400008CD0000000D800014E0850 -:100030000000F26400014EE800000074000241502C -:1000400000005250000241C8000000B40002942099 -:10005000000121EC000294D800000FFC0003B6C898 -:10006000000000040003C6C8020400480000000F9E -:1000700002040054000000450204005C0000000679 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040258000000360204025C000000365F -:10017000020402600810000002040264081000007B -:1001800002040004000000FF02040008000000FF59 -:100190000204000C000000FF02040010000000FF39 -:1001A000020400140000007F02040018000000FF99 -:1001B0000204001C000000FF02040020000000FFF9 -:1001C000020400240000003E020400280000000099 -:1001D0000204002C0000003F020400300000003F39 -:1001E000020400340000003F020400380000003F19 -:1001F0000204003C0000003F020400400000003FF9 -:10020000020400440000003F020404CC000000018E -:1002100002042008000002110204200C0000020069 -:10022000020420100000020402042014000002193D -:100230000204201C0000FFFF020420200000FFFF3A -:10024000020420240000FFFF020420280000FFFF1A -:1002500002042038000000200604203C0000000FAB -:1002600002042078000000210604207C0000000F1A -:10027000020420B800000001060420BC0000000FAA -:10028000020420F800000001060420FC0000003FEA -:10029000020421F800000001060421FC0000000F08 -:1002A0000204223807FFFFFF0204223C0000007F07 -:1002B0000204224007FFFFFF020422440000003F27 -:1002C00001042248000000000104224C000000004C -:1002D000010422500000000001042254000000002C -:1002E00001042258000000000104225C000000000C -:1002F00001042260000000000104226400000000EC -:1003000001042268000000000104226C00000000CB -:1003100001042270000000000104227400000000AB -:1003200001042278000000000104227C000000008B -:10033000020422C00000FFFF020422C40000FFFFED -:10034000020422C80000FFFF020422CC0000FFFFCD -:100350000C042000000003E80A0420000000000153 -:100360000B042000000000030605400000000D0003 -:100370000205004400000020020500480000003291 -:1003800002050090021500200205009402150020CD -:1003900002050098000000300205009C08100000D3 -:1003A000020500A000000036020500A40000003095 -:1003B000020500A800000031020500B000000004A2 -:1003C000020500B400000005020500C000000000A6 -:1003D000020500C400000004020500D40000000172 -:1003E00002050114000000010205011C00000001CB -:1003F00002050120000000020205020400000001C5 -:100400000205020C0000004002050210000000403E -:100410000205021C00000020020502200000001C52 -:100420000205022400000020060502400000000A28 -:1004300004050280002000000205005000000007B3 -:1004400002050054000000070205005800000000EB -:100450000205005C000000080205006000000001C9 -:100460000605006400000003020500D80000000635 -:100470000205000400000001020500080000000160 -:100480000205000C00000001020500100000000140 -:100490000205001400000001020500180000000120 -:1004A0000205001C00000001020500200000000100 -:1004B00002050024000000010205002800000001E0 -:1004C0000205002C000000010205003000000001C0 -:1004D00002050034000000010205003800000001A0 -:1004E0000205003C00000001020500400000000180 -:1004F000020500E00000000D020500E80000000019 -:10050000020500F000000000020500F800000000F5 -:10051000020500E40000002D020500EC00000020B0 -:10052000020500F400000020020500FC000000208D -:10053000020500E00000001D020500E800000010B8 -:10054000020500F000000010020500F80000001095 -:10055000020500E40000003D020500EC0000003050 -:10056000020500F400000030020500FC000000302D -:10057000020500E00000004D020500E80000004018 -:10058000020500F000000040020500F800000040F5 -:10059000020500E40000006D020500EC00000060B0 -:1005A000020500F400000060020500FC000000608D -:1005B000020500E00000005D020500E800000050B8 -:1005C000020500F000000050020500F80000005095 -:1005D000020500E40000007D020500EC0000007050 -:1005E000020500F400000070020500FC000000702D -:1005F0000406100002000020020600DC00000001DA -:100600000406020000030220020600DC00000000D5 -:100610000718040000AD0000081807D800050223E1 -:10062000071C000029920000071C8000312A0A657F -:10063000071D000034A216B0071D80002E7A23D9B2 -:10064000071E000003502F78081E07F03F02022506 -:10065000021800BC0000003001180000000000007B -:10066000011800040000000001180008000000004C -:100670000118000C0000000001180010000000002C -:100680000118001400000000021800200000000102 -:1006900002180024000000020218002800000003D5 -:1006A0000218002C000000000218003000000004B6 -:1006B0000218003400000001021800380000000099 -:1006C0000218003C00000001021800400000000475 -:1006D0000218004400000000021800480000000159 -:1006E0000218004C00000003021800500000000037 -:1006F0000218005400000001021800580000000415 -:100700000218005C000000000218006000000001F8 -:1007100002180064000000030218006800000000D6 -:100720000218006C000000010218007000000004B4 -:100730000218007400000000021800780000000495 -:100740000218007C00000003061800800000000270 -:10075000021800A400007FFF021800A8000003FF99 -:1007600002180224000000000218023400000000F9 -:100770000218024C00000000021802E4000000FF12 -:100780000618100000000400021B8BC000000001CE -:10079000021B800000000034021B80400000001893 -:1007A000021B80800000000C021B80C000000020A3 -:1007B0000C1B8300000864700A1B830000000157B3 -:1007C0000B1B83000000055F0A1B83400000000034 -:1007D0000C1B8340000002260B1B8340000000011D -:1007E000021B838000086470021B83C00000022685 -:1007F000021B1480000000010A1B1480000000008E -:10080000021B944000000001061B944800000002F7 -:10081000061A1000000002B3041A1ACC00010227C5 -:10082000061A1AD000000008061A2008000000C8A6 -:10083000061A200000000002041A1BF8009002288B -:10084000061A371800000004061A371000000002CC -:10085000061A500000000002061A500800000004AA -:10086000061A501800000004061A50280000000460 -:10087000061A503800000004061A50480000000410 -:10088000061A505800000004061A506800000004C0 -:10089000061A507800000002041A52C0000202B882 -:1008A000061A405000000006041A4068000202BA0E -:1008B000041A4040000402BC041A8000000102C077 -:1008C000061A800400000003041A8010000102C10F -:1008D000061A801400000003041A8020000102C2DE -:1008E000061A802400000003041A8030000102C3AD -:1008F000061A803400000003041A8040000102C47C -:10090000061A804400000003041A8050000102C54A -:10091000061A805400000003041A8060000102C619 -:10092000061A806400000003041A8070000102C7E8 -:10093000061A807400000003041A8080000102C8B7 -:10094000061A808400000003041A8090000102C986 -:10095000061A809400000003041A80A0000102CA55 -:10096000061A80A400000003041A80B0000102CB24 -:10097000061A80B400000003041A80C0000102CCF3 -:10098000061A80C400000003041A80D0000102CDC2 -:10099000061A80D400000003041A80E0000102CE91 -:1009A000061A80E400000003041A80F0000102CF60 -:1009B000061A80F400000003041A8100000102D02E -:1009C000061A810400000003041A8110000102D1FC -:1009D000061A811400000003041A8120000102D2CB -:1009E000061A812400000003041A8130000102D39A -:1009F000061A813400000003041A8140000102D469 -:100A0000061A814400000003041A8150000102D537 -:100A1000061A815400000003041A8160000102D606 -:100A2000061A816400000003041A8170000102D7D5 -:100A3000061A817400000003041A8180000102D8A4 -:100A4000061A818400000003041A8190000102D973 -:100A5000061A819400000003041A81A0000102DA42 -:100A6000061A81A400000003041A81B0000102DB11 -:100A7000061A81B400000003041A81C0000102DCE0 -:100A8000061A81C400000003041A81D0000102DDAF -:100A9000061A81D400000003041A81E0000102DE7E -:100AA000061A81E400000003041A81F0000102DF4D -:100AB000061A81F400000003041A8200000102E01B -:100AC000061A820400000003041A8210000102E1E9 -:100AD000061A821400000003041A8220000102E2B8 -:100AE000061A822400000003041A8230000102E387 -:100AF000061A823400000003041A8240000102E456 -:100B0000061A824400000003041A8250000102E524 -:100B1000061A825400000003041A8260000102E6F3 -:100B2000061A826400000003041A8270000102E7C2 -:100B3000061A827400000003041A8280000102E891 -:100B4000061A828400000003041A8290000102E960 -:100B5000061A829400000003041A82A0000102EA2F -:100B6000061A82A400000003041A82B0000102EBFE -:100B7000061A82B400000003041A82C0000102ECCD -:100B8000061A82C400000003041A82D0000102ED9C -:100B9000061A82D400000003041A82E0000102EE6B -:100BA000061A82E400000003041A82F0000102EF3A -:100BB000061A82F400000003041A8300000102F008 -:100BC000061A830400000003041A8310000102F1D6 -:100BD000061A831400000003041A8320000102F2A5 -:100BE000061A832400000003041A8330000102F374 -:100BF000061A833400000003041A8340000102F443 -:100C0000061A834400000003041A8350000102F511 -:100C1000061A835400000003041A8360000102F6E0 -:100C2000061A836400000003041A8370000102F7AF -:100C3000061A837400000003041A8380000102F87E -:100C4000061A838400000003041A8390000102F94D -:100C5000061A839400000003041A83A0000102FA1C -:100C6000061A83A400000003041A83B0000102FBEB -:100C7000061A83B400000003041A83C0000102FCBA -:100C8000061A83C400000003041A83D0000102FD89 -:100C9000061A83D400000003041A83E0000102FE58 -:100CA000061A83E400000003041A83F0000102FF27 -:100CB000061A83F400000003041A840000010300F4 -:100CC000061A840400000003041A841000010301C2 -:100CD000061A841400000003041A84200001030291 -:100CE000061A842400000003041A84300001030360 -:100CF000061A843400000003041A8440000103042F -:100D0000061A844400000003041A845000010305FD -:100D1000061A845400000003041A846000010306CC -:100D2000061A846400000003041A8470000103079B -:100D3000061A847400000003041A8480000103086A -:100D4000061A848400000003041A84900001030939 -:100D5000061A849400000003041A84A00001030A08 -:100D6000061A84A400000003041A84B00001030BD7 -:100D7000061A84B400000003041A84C00001030CA6 -:100D8000061A84C400000003041A84D00001030D75 -:100D9000061A84D400000003041A84E00001030E44 -:100DA000061A84E400000003041A84F00001030F13 -:100DB000061A84F400000003041A850000010310E1 -:100DC000061A850400000003041A851000010311AF -:100DD000061A851400000003041A8520000103127E -:100DE000061A852400000003041A8530000103134D -:100DF000061A853400000003041A8540000103141C -:100E0000061A854400000003041A855000010315EA -:100E1000061A855400000003041A856000010316B9 -:100E2000061A856400000003041A85700001031788 -:100E3000061A857400000003041A85800001031857 -:100E4000061A858400000003041A85900001031926 -:100E5000061A859400000003041A85A00001031AF5 -:100E6000061A85A400000003041A85B00001031BC4 -:100E7000061A85B400000003041A85C00001031C93 -:100E8000061A85C400000003041A85D00001031D62 -:100E9000061A85D400000003041A85E00001031E31 -:100EA000061A85E400000003041A85F00001031F00 -:100EB000061A85F400000003041A860000010320CE -:100EC000061A860400000003041A8610000103219C -:100ED000061A861400000003041A8620000103226B -:100EE000061A862400000003041A8630000103233A -:100EF000061A863400000003041A86400001032409 -:100F0000061A864400000003041A865000010325D7 -:100F1000061A865400000003041A866000010326A6 -:100F2000061A866400000003041A86700001032775 -:100F3000061A867400000003041A86800001032844 -:100F4000061A868400000003041A86900001032913 -:100F5000061A869400000003041A86A00001032AE2 -:100F6000061A86A400000003041A86B00001032BB1 -:100F7000061A86B400000003041A86C00001032C80 -:100F8000061A86C400000003041A86D00001032D4F -:100F9000061A86D400000003041A86E00001032E1E -:100FA000061A86E400000003041A86F00001032FED -:100FB000061A86F400000003041A870000010330BB -:100FC000061A870400000003041A87100001033189 -:100FD000061A871400000003041A87200001033258 -:100FE000061A872400000003041A87300001033327 -:100FF000061A873400000003041A874000010334F6 -:10100000061A874400000003041A875000010335C4 -:10101000061A875400000003041A87600001033693 -:10102000061A876400000003041A87700001033762 -:10103000061A877400000003041A87800001033831 -:10104000061A878400000003041A87900001033900 -:10105000061A879400000003041A87A00001033ACF -:10106000061A87A400000003041A87B00001033B9E -:10107000061A87B400000003041A87C00001033C6D -:10108000061A87C400000003041A87D00001033D3C -:10109000061A87D400000003041A87E00001033E0B -:1010A000061A87E400000003041A87F00001033FDA -:1010B000061A87F400000003041A880000010340A8 -:1010C000061A880400000003041A88100001034176 -:1010D000061A881400000003041A88200001034245 -:1010E000061A882400000003041A88300001034314 -:1010F000061A883400000003041A884000010344E3 -:10110000061A884400000003041A885000010345B1 -:10111000061A885400000003041A88600001034680 -:10112000061A886400000003041A8870000103474F -:10113000061A887400000003041A8880000103481E -:10114000061A888400000003041A889000010349ED -:10115000061A889400000003041A88A00001034ABC -:10116000061A88A400000003041A88B00001034B8B -:10117000061A88B400000003041A88C00001034C5A -:10118000061A88C400000003041A88D00001034D29 -:10119000061A88D400000003041A88E00001034EF8 -:1011A000061A88E400000003041A88F00001034FC7 -:1011B000061A88F400000003041A89000001035095 -:1011C000061A890400000003041A89100001035163 -:1011D000061A891400000003041A89200001035232 -:1011E000061A892400000003041A89300001035301 -:1011F000061A893400000003041A894000010354D0 -:10120000061A894400000003041A8950000103559E -:10121000061A895400000003041A8960000103566D -:10122000061A896400000003041A8970000103573C -:10123000061A897400000003041A8980000103580B -:10124000061A898400000003041A899000010359DA -:10125000061A899400000003041A89A00001035AA9 -:10126000061A89A400000003041A89B00001035B78 -:10127000061A89B400000003041A89C00001035C47 -:10128000061A89C400000003041A89D00001035D16 -:10129000061A89D400000003041A89E00001035EE5 -:1012A000061A89E400000003041A89F00001035FB4 -:1012B000061A89F400000003041A8A000001036082 -:1012C000061A8A0400000003041A8A100001036150 -:1012D000061A8A1400000003041A8A20000103621F -:1012E000061A8A2400000003041A8A3000010363EE -:1012F000061A8A3400000003041A8A4000010364BD -:10130000061A8A4400000003041A8A50000103658B -:10131000061A8A5400000003041A8A60000103665A -:10132000061A8A6400000003041A8A700001036729 -:10133000061A8A7400000003041A8A8000010368F8 -:10134000061A8A8400000003041A8A9000010369C7 -:10135000061A8A9400000003041A8AA00001036A96 -:10136000061A8AA400000003041A8AB00001036B65 -:10137000061A8AB400000003041A8AC00001036C34 -:10138000061A8AC400000003041A8AD00001036D03 -:10139000061A8AD400000003041A8AE00001036ED2 -:1013A000061A8AE400000003041A8AF00001036FA1 -:1013B000061A8AF400000003041A8B00000103706F -:1013C000061A8B0400000003041A8B10000103713D -:1013D000061A8B1400000003041A8B20000103720C -:1013E000061A8B2400000003041A8B3000010373DB -:1013F000061A8B3400000003041A8B4000010374AA -:10140000061A8B4400000003041A8B500001037578 -:10141000061A8B5400000003041A8B600001037647 -:10142000061A8B6400000003041A8B700001037716 -:10143000061A8B7400000003041A8B8000010378E5 -:10144000061A8B8400000003041A8B9000010379B4 -:10145000061A8B9400000003041A8BA00001037A83 -:10146000061A8BA400000003041A8BB00001037B52 -:10147000061A8BB400000003041A8BC00001037C21 -:10148000061A8BC400000003041A8BD00001037DF0 -:10149000061A8BD400000003041A8BE00001037EBF -:1014A000061A8BE400000003041A8BF00001037F8E -:1014B000061A8BF400000003041A8C00000103805C -:1014C000061A8C0400000003041A8C10000103812A -:1014D000061A8C1400000003041A8C2000010382F9 -:1014E000061A8C2400000003041A8C3000010383C8 -:1014F000061A8C3400000003041A8C400001038497 -:10150000061A8C4400000003041A8C500001038565 -:10151000061A8C5400000003041A8C600001038634 -:10152000061A8C6400000003041A8C700001038703 -:10153000061A8C7400000003041A8C8000010388D2 -:10154000061A8C8400000003041A8C9000010389A1 -:10155000061A8C9400000003041A8CA00001038A70 -:10156000061A8CA400000003041A8CB00001038B3F -:10157000061A8CB400000003041A8CC00001038C0E -:10158000061A8CC400000003041A8CD00001038DDD -:10159000061A8CD400000003041A8CE00001038EAC -:1015A000061A8CE400000003041A8CF00001038F7B -:1015B000061A8CF400000003041A8D000001039049 -:1015C000061A8D0400000003041A8D100001039117 -:1015D000061A8D1400000003041A8D2000010392E6 -:1015E000061A8D2400000003041A8D3000010393B5 -:1015F000061A8D3400000003041A8D400001039484 -:10160000061A8D4400000003041A8D500001039552 -:10161000061A8D5400000003041A8D600001039621 -:10162000061A8D6400000003041A8D7000010397F0 -:10163000061A8D7400000003041A8D8000010398BF -:10164000061A8D8400000003041A8D90000103998E -:10165000061A8D9400000003041A8DA00001039A5D -:10166000061A8DA400000003041A8DB00001039B2C -:10167000061A8DB400000003041A8DC00001039CFB -:10168000061A8DC400000003041A8DD00001039DCA -:10169000061A8DD400000003041A8DE00001039E99 -:1016A000061A8DE400000003041A8DF00001039F68 -:1016B000061A8DF400000003041A8E00000103A036 -:1016C000061A8E0400000003041A8E10000103A104 -:1016D000061A8E1400000003041A8E20000103A2D3 -:1016E000061A8E2400000003041A8E30000103A3A2 -:1016F000061A8E3400000003041A8E40000103A471 -:10170000061A8E4400000003041A8E50000103A53F -:10171000061A8E5400000003041A8E60000103A60E -:10172000061A8E6400000003041A8E70000103A7DD -:10173000061A8E7400000003041A8E80000103A8AC -:10174000061A8E8400000003041A8E90000103A97B -:10175000061A8E9400000003041A8EA0000103AA4A -:10176000061A8EA400000003041A8EB0000103AB19 -:10177000061A8EB400000003041A8EC0000103ACE8 -:10178000061A8EC400000003041A8ED0000103ADB7 -:10179000061A8ED400000003041A8EE0000103AE86 -:1017A000061A8EE400000003041A8EF0000103AF55 -:1017B000061A8EF400000003041A8F00000103B023 -:1017C000061A8F0400000003041A8F10000103B1F1 -:1017D000061A8F1400000003041A8F20000103B2C0 -:1017E000061A8F2400000003041A8F30000103B38F -:1017F000061A8F3400000003041A8F40000103B45E -:10180000061A8F4400000003041A8F50000103B52C -:10181000061A8F5400000003041A8F60000103B6FB -:10182000061A8F6400000003041A8F70000103B7CA -:10183000061A8F7400000003041A8F80000103B899 -:10184000061A8F8400000003041A8F90000103B968 -:10185000061A8F9400000003041A8FA0000103BA37 -:10186000061A8FA400000003041A8FB0000103BB06 -:10187000061A8FB400000003041A8FC0000103BCD5 -:10188000061A8FC400000003041A8FD0000103BDA4 -:10189000061A8FD400000003041A8FE0000103BE73 -:1018A000061A8FE400000007041A62C0002003BF7C -:1018B000061A1AF000000042061AAF0000000008E5 -:1018C000061AE00000000540061AD0000000007271 -:1018D000061AD24800000010061AD6B000000020F8 -:1018E000061AD47000000090061AD46800000002A6 -:1018F000061AA000000001C4061A30000000001003 -:10190000061A308000000010061A31000000001096 -:10191000061A318000000010061A33000000001281 -:10192000061A339000000070061AD4580000000216 -:10193000061AD34800000002061AD35800000020FF -:10194000061AA710000001C4061A3040000000105B -:10195000061A30C000000010061A314000000010C6 -:10196000061A31C000000010061A334800000012A9 -:10197000061A355000000070061AD46000000002FC -:10198000061AD35000000002061AD3D80000002027 -:10199000021AAE2000000000061A500000000002EB -:1019A000061A508000000012041A4000000203DFF3 -:1019B000041A63C0000203E1061A7000000000046C -:1019C000061A320000000008021AAE2400000000CF -:1019D000061A501000000002061A50C8000000123B -:1019E000041A4008000203E3041A63C8000203E576 -:1019F000061A701000000004061A322000000008C9 -:101A0000021AAE2800000000061A50200000000252 -:101A1000061A511000000012041A4010000203E7D9 -:101A2000041A63D0000203E9061A702000000004C3 -:101A3000061A324000000008021AAE2C0000000016 -:101A4000061A503000000002061A51580000001219 -:101A5000041A4018000203EB041A63D8000203EDD5 -:101A6000061A703000000004061A326000000008F8 -:101A7000021AAE3000000000061A504000000002BA -:101A8000061A51A000000012041A4020000203EFC1 -:101A9000041A63E0000203F1061A7040000000041B -:101AA000061A328000000008021AAE34000000005E -:101AB000061A505000000002061A51E800000012F9 -:101AC000041A4028000203F3041A63E8000203F535 -:101AD000061A705000000004061A32A00000000828 -:101AE000021AAE3800000000061A50600000000222 -:101AF000061A523000000012041A4030000203F7A8 -:101B0000041A63F0000203F9061A70600000000472 -:101B1000061A32C000000008021AAE3C00000000A5 -:101B2000061A507000000002061A527800000012D7 -:101B3000041A4038000203FB041A63F8000203FD94 -:101B4000061A707000000004061A32E00000000857 -:101B50000200A2A4000002090200A270000000001E -:101B60000200A274000000000200A2700000000049 -:101B70000200A274000000000200A2700000000039 -:101B80000200A274000000000200A2700000000029 -:101B90000200A27400000000020100B40000000175 -:101BA000020100B800000001020100CC00000001A9 -:101BB000020100D000000001020100DC0000000171 -:101BC0000201010000000001020101040000000107 -:101BD0000201007C003000000201008400000028A7 -:101BE0000201008C0000000002010130000000042E -:101BF0000201025C00000001020103280000000055 -:101C0000020160580000FFFF020160700000000741 -:101C10000201055400000030020100C40000000170 -:101C2000020100F800000001020100F000000001C4 -:101C3000020100800030000002010088000000283E -:101C400002010090000000000201013400000004C5 -:101C5000020102DC000000010201032C0000000070 -:101C60000201605C0000FFFF0201607400000007D9 -:101C70000201056400000030020100C800000001FC -:101C8000020100FC00000001020100F4000000015C -:101C9000020C100000000028020C200800000211B5 -:101CA000020C200C00000200020C201000000204B4 -:101CB000020C201C0000FFFF020C20200000FFFF90 -:101CC000020C20240000FFFF020C20280000FFFF70 -:101CD000020C203800000000020C203C00000037FD -:101CE000020C204000000021020C204400000020D3 -:101CF000060C20480000001D020C20BC0000000162 -:101D0000060C20C00000003F020C21BC00000001B6 -:101D1000020C21C000000001020C21C400000001DF -:101D2000060C21C80000001C020C223807FFFFFF30 -:101D3000020C223C0000007F020C224007FFFFFF44 -:101D4000020C22440000003F010C22480000000069 -:101D5000010C224C00000000010C22500000000089 -:101D6000010C225400000000010C22580000000069 -:101D7000010C225C00000000010C22600000000049 -:101D8000010C226400000000010C22680000000029 -:101D9000010C226C00000000010C22700000000009 -:101DA000010C227400000000010C227800000000E9 -:101DB000010C227C00000000020C22D80000FFFF72 -:101DC000020C22DC0000FFFF020C22E00000FFFFFB -:101DD000020C22E40000FFFF0C0C2000000003E8CE -:101DE0000A0C2000000000010B0C20000000000382 -:101DF000020C400800001011020C400C0000100002 -:101E0000020C401000001004020C401400001021CD -:101E1000020C401C0000FFFF020C40200000FFFFEE -:101E2000020C40240000FFFF020C40280000FFFFCE -:101E3000020C403800000046020C403C0000000C40 -:101E4000060C404000000002020C40480000001850 -:101E5000020C404C000000F0060C40500000001F37 -:101E6000020C40CC00000001060C40D00000003AFB -:101E7000020C41B800000001060C41BC0000000348 -:101E8000020C41C800000001020C41CC000000011E -:101E9000060C41D00000001A020C423807FFFFFF79 -:101EA000020C423C0000007F020C424007FFFFFF93 -:101EB000020C42440000003F010C424800000000B8 -:101EC000010C424C00000000010C425000000000D8 -:101ED000010C425400000000010C425800000000B8 -:101EE000010C425C00000000010C42600000000098 -:101EF000010C426400000000010C42680000000078 -:101F0000010C426C00000000010C42700000000057 -:101F1000010C427400000000010C42780000000037 -:101F2000010C427C00000000010C42800000000017 -:101F3000020C42D80000FFFF020C42DC0000FFFF51 -:101F4000020C42E00000FFFF020C42E40000FFFF31 -:101F50000C0C4000000003E80A0C400000000001E7 -:101F60000B0C400000000003060D400000000A00BA -:101F7000020D004400000032020D008C021500200A -:101F8000020D009002150020020D009408100000C0 -:101F9000020D009800000036020D00A000000000B5 -:101FA000020D00A400000004020D00A800000004BF -:101FB000060D00AC00000002020D00B80000000297 -:101FC000020D00C000000001020D00C80000000268 -:101FD000020D00CC00000002020D015C00000001B7 -:101FE000020D016400000001020D01680000000202 -:101FF000020D020400000001020D020C000000208E -:10200000020D021000000040020D0214000000400A -:10201000020D022000000003020D0224000000183F -:10202000060D028000000012040D0300001803FFDB -:10203000060D03600000000C020D004C00000001C2 -:10204000020D005000000002020D005400000000CC -:10205000020D005800000008060D005C000000049E -:10206000020D00C400000004020D00040000000185 -:10207000020D000800000001020D000C000000012C -:10208000020D001000000001020D0014000000010C -:10209000020D001800000001020D001C00000001EC -:1020A000020D002000000001020D002400000001CC -:1020B000020D002800000001020D002C00000001AC -:1020C000020D003000000001020D0034000000018C -:1020D000020D003800000001020D003C000000016C -:1020E000020D011400000009020D011C0000000A8D -:1020F000020D012400000000020D012C0000000070 -:10210000020D013400000000020D013C0000000B34 -:10211000020D014400000000020D0118000000291A -:10212000020D01200000002A020D012800000020FD -:10213000020D013000000020020D013800000020D7 -:10214000020D01400000002B020D0148000000209C -:10215000020D011400000019020D011C0000001AFC -:10216000020D012400000010020D012C00000010DF -:10217000020D013400000010020D013C0000001BA4 -:10218000020D014400000010020D0118000000398A -:10219000020D01200000003A020D0128000000306D -:1021A000020D013000000030020D01380000003047 -:1021B000020D01400000003B020D0148000000300C -:1021C000020D011400000049020D011C0000004A2C -:1021D000020D012400000040020D012C000000400F -:1021E000020D013400000040020D013C0000004BD4 -:1021F000020D014400000040020D011800000069BA -:10220000020D01200000006A020D0128000000609C -:10221000020D013000000060020D01380000006076 -:10222000020D01400000006B020D0148000000603B -:10223000020D011400000059020D011C0000005A9B -:10224000020D012400000050020D012C000000507E -:10225000020D013400000050020D013C0000005B43 -:10226000020D014400000050020D01180000007929 -:10227000020D01200000007A020D0128000000700C -:10228000020D013000000070020D013800000070E6 -:10229000020D01400000007B020D014800000070AB -:1022A000060E200000000800020E004C0000003264 -:1022B000020E009402150020020E00980215002064 -:1022C000020E009C00000030020E00A0081000006A -:1022D000020E00A400000036020E00A8000000302C -:1022E000020E00AC00000031020E00B4000000033A -:1022F000020E00B800000000020E00C40000000042 -:10230000020E00CC00000006020E00D80000000102 -:10231000020E014400000001020E014C0000000109 -:10232000020E015000000002020E02040000000133 -:10233000020E020C00000040020E021000000040DD -:10234000020E021C00000004020E02200000002009 -:10235000020E02240000000E020E02280000001BE4 -:10236000060E030000000012040E0280001B04177A -:10237000060E02EC00000005020E00540000000CE6 -:10238000020E00580000000C020E005C000000006D -:10239000020E006000000010020E00640000001039 -:1023A000060E006800000003020E00DC00000003BF -:1023B000020E000400000001020E000800000001EF -:1023C000020E000C00000001020E001000000001CF -:1023D000020E001400000001020E001800000001AF -:1023E000020E001C00000001020E0020000000018F -:1023F000020E002400000001020E0028000000016F -:10240000020E002C00000001020E0030000000014E -:10241000020E003400000001020E0038000000012E -:10242000020E003C00000001020E0040000000010E -:10243000020E004400000001020E01100000000F17 -:10244000020E011800000000020E01200000000032 -:10245000020E012800000000020E01140000002FEF -:10246000020E011C00000020020E012400000020CA -:10247000020E012C00000020020E01100000001FBF -:10248000020E011800000010020E012000000010D2 -:10249000020E012800000010020E01140000003F8F -:1024A000020E011C00000030020E0124000000306A -:1024B000020E012C00000030020E01100000004F3F -:1024C000020E011800000040020E01200000004032 -:1024D000020E012800000040020E01140000006FEF -:1024E000020E011C00000060020E012400000060CA -:1024F000020E012C00000060020E01100000005FBF -:10250000020E011800000050020E012000000050D1 -:10251000020E012800000050020E01140000007F8E -:10252000020E011C00000070020E01240000007069 -:10253000020E012C000000700730040000D60000DD -:10254000083007D80005043207340000322B0000A1 -:1025500007348000314B0C8B0735000038C518DE7E -:10256000073580002F90271007360000268F32F5A0 -:102570000836716031D40434023000BC00000030F1 -:1025800001300000000000000130000400000000E5 -:1025900001300008000000000130000C00000000C5 -:1025A00001300010000000000130001400000000A5 -:1025B0000230002000000001023000240000000270 -:1025C00002300028000000030230002C0000000050 -:1025D000023000300000000402300034000000012E -:1025E00002300038000000000230003C0000000112 -:1025F00002300040000000040230004400000000EF -:1026000002300048000000010230004C00000003CE -:1026100002300050000000000230005400000001B1 -:1026200002300058000000040230005C000000008E -:10263000023000600000000102300064000000036E -:1026400002300068000000000230006C0000000151 -:10265000023000700000000402300074000000002E -:1026600002300078000000040230007C000000030B -:102670000630008000000002023000A400007FFF4E -:10268000023000A8000003FF023002240000000016 -:1026900002300234000000000230024C0000000052 -:1026A000023002E40000FFFF0630200000000800B6 -:1026B00002338BC000000001023380000000001ACA -:1026C000023380400000004E023380800000001082 -:1026D000023380C0000000200C33830000086470C7 -:1026E0000A338300000001570B3383000000055FAD -:1026F0000A338340000000000C33834000000226B0 -:102700000B338340000000010233838000086470B3 -:10271000023383C00000022602331480000000014F -:102720000A3314800000000006328000000001021D -:1027300006322008000000C8063220000000000217 -:1027400004328520008F04360632875C00000009C1 -:1027500006323EB00000000606323ED00000000205 -:1027600006323E800000000A04323EA8000204C582 -:1027700006323E00000000200632500000000940F2 -:102780000632400000000004043294C0000204C776 -:1027900006324110000000020632D0000000007036 -:1027A0000632DB00000000D40632DEA0000000028A -:1027B0000632E00000000800063324000000011883 -:1027C0000632100000000188063250000000002090 -:1027D00006325100000000200632520000000020A6 -:1027E0000632530000000020063254000000002092 -:1027F000063255000000002006325600000000207E -:102800000632570000000020063258000000002069 -:10281000063259000000002006325A000000002055 -:1028200006325B000000002006325C000000002041 -:1028300006325D000000002006325E00000000202D -:1028400006325F0000000020063284F00000000223 -:1028500004328500000204C9063285080000000227 -:102860000632DE90000000020633286000000118E6 -:102870000632162000000188063250800000002039 -:1028800006325180000000200632528000000020F5 -:1028900006325380000000200632548000000020E1 -:1028A00006325580000000200632568000000020CD -:1028B00006325780000000200632588000000020B9 -:1028C000063259800000002006325A8000000020A5 -:1028D00006325B800000002006325C800000002091 -:1028E00006325D800000002006325E80000000207D -:1028F00006325F8000000020063284F800000002EB -:1029000004328510000204CB063285180000000254 -:102910000632DE98000000020232845000000000FF -:102920000632401000000002023284540000000011 -:1029300006324020000000020232845800000000ED -:1029400006324030000000020232845C00000000C9 -:1029500006324040000000020232846000000000A5 -:102960000632405000000002023284640000000081 -:10297000063240600000000202328468000000005D -:1029800006324070000000020232846C0000000039 -:10299000063240800000000207200400007300009F -:1029A00008200780001004CD072400002AE400005E -:1029B0000724800027670ABA0824D35063FC04CF99 -:1029C000022000BC000000300120000000000000D8 -:1029D00001200004000000000120000800000000A9 -:1029E0000120000C00000000012000100000000089 -:1029F000012000140000000002200020000000015F -:102A00000220002400000002022000280000000331 -:102A10000220002C00000000022000300000000412 -:102A200002200034000000010220003800000000F5 -:102A30000220003C000000010220004000000004D1 -:102A400002200044000000000220004800000001B5 -:102A50000220004C00000003022000500000000093 -:102A60000220005400000001022000580000000471 -:102A70000220005C00000000022000600000000155 -:102A80000220006400000003022000680000000033 -:102A90000220006C00000001022000700000000411 -:102AA00002200074000000000220007800000004F2 -:102AB0000220007C000000030620008000000002CD -:102AC000022000A400007FFF022000A8000003FFF6 -:102AD0000220022400000000022002340000000056 -:102AE0000220024C00000000022002E40000FFFF70 -:102AF000062020000000080002238BC00000000117 -:102B00000223800000000010022380400000001219 -:102B10000223808000000030022380C00000000EED -:102B20000C238300000864700A238300000001570F -:102B30000B2383000000055F0A2383400000000090 -:102B40000C238340000002260B2383400000000179 -:102B50000223838000086470022383C000000226E1 -:102B600002231480000000010A23148000000000EA -:102B7000062210000000004206222008000000C8C3 -:102B800006222000000000020622B00000000330F0 -:102B90000622F400000000530422F54C000104D189 -:102BA0000622F550000000030422F55C000104D267 -:102BB0000622F560000000030422F56C000104D336 -:102BC0000622F570000000030422F57C000104D405 -:102BD0000622F580000000030422F58C000104D5D4 -:102BE0000622F590000000030422F59C000104D6A3 -:102BF0000622F5A0000000030422F5AC000104D772 -:102C00000622F5B0000000030422F5BC000104D840 -:102C10000622F5C0000000460622E2000000044043 -:102C200004221240009004D906223000000000C0A7 -:102C30000622670000000100062290000000040048 -:102C400004226B0800200569062211F0000000062E -:102C50000422120800060589062212200000000244 -:102C600006224000000005C00622C0000000000649 -:102C70000422C0180006058F0622C0300000000A9A -:102C80000422C058000605950622C0700000000A04 -:102C90000422C0980006059B0622C0B00000000A6E -:102CA0000422C0D8000605A10622C0F00000000AD8 -:102CB0000422C118000605A70622C1300000000A40 -:102CC0000422C158000605AD0622C1700000000AAA -:102CD0000422C198000605B30622C1B00000000A14 -:102CE0000422C1D8000605B90622C1F00000000A7E -:102CF0000422C218000605BF0622C2300000000AE6 -:102D00000422C258000605C50622C2700000000A4F -:102D10000422C298000605CB0622C2B00000000AB9 -:102D20000422C2D8000605D10622C2F00000000A23 -:102D30000422C318000605D70622C3300000000A8B -:102D40000422C358000605DD0622C3700000000AF5 -:102D50000422C398000605E30622C3B00000000A5F -:102D60000422C3D8000605E90622C3F00000000AC9 -:102D70000422C418000605EF0622C4300000000A31 -:102D80000422C458000605F50622C4700000000A9B -:102D90000422C498000605FB0622C4B00000000A05 -:102DA0000422C4D8000606010622C4F00000000A6E -:102DB0000422C518000606070622C5300000000AD6 -:102DC0000422C5580006060D0622C5700000000A40 -:102DD0000422C598000606130622C5B00000000AAA -:102DE0000422C5D8000606190622C5F00000000A14 -:102DF0000422C6180006061F0622C6300000000A7C -:102E00000422C658000606250622C6700000000AE5 -:102E10000422C6980006062B0622C6B00000000A4F -:102E20000422C6D8000606310622C6F00000000AB9 -:102E30000422C718000606370622C7300000000A21 -:102E40000422C7580006063D0622C7700000000A8B -:102E50000422C798000606430622C7B00000000AF5 -:102E60000422C7D8000606490622C7F00000000A5F -:102E70000422C8180006064F0622C8300000000AC7 -:102E80000422C858000606550622C8700000000A31 -:102E90000422C8980006065B0622C8B00000000A9B -:102EA0000422C8D8000606610622C8F00000000A05 -:102EB0000422C918000606670622C9300000000A6D -:102EC0000422C9580006066D0622C9700000000AD7 -:102ED0000422C998000606730622C9B00000000A41 -:102EE0000422C9D8000606790622C9F00000000AAB -:102EF0000422CA180006067F0622CA300000000A13 -:102F00000422CA58000606850622CA700000000A7C -:102F10000422CA980006068B0622CAB00000000AE6 -:102F20000422CAD8000606910622CAF00000000A50 -:102F30000422CB18000606970622CB300000000AB8 -:102F40000422CB580006069D0622CB700000000A22 -:102F50000422CB98000606A30622CBB00000000A8C -:102F60000422CBD8000606A90622CBF00000000AF6 -:102F70000422CC18000606AF0622CC300000000A5E -:102F80000422CC58000606B50622CC700000000AC8 -:102F90000422CC98000606BB0622CCB00000000A32 -:102FA0000422CCD8000606C10622CCF00000000A9C -:102FB0000422CD18000606C70622CD300000000A04 -:102FC0000422CD58000606CD0622CD700000000A6E -:102FD0000422CD98000606D30622CDB00000000AD8 -:102FE0000422CDD8000606D90622CDF00000000A42 -:102FF0000422CE18000606DF0622CE300000000AAA -:103000000422CE58000606E50622CE700000000A13 -:103010000422CE98000606EB0622CEB00000000A7D -:103020000422CED8000606F10622CEF00000000AE7 -:103030000422CF18000606F70622CF300000000A4F -:103040000422CF58000606FD0622CF700000000AB9 -:103050000422CF98000607030622CFB00000000A22 -:103060000422CFD8000607090622CFF00000000A8C -:103070000422D0180006070F0622D0300000000AF4 -:103080000422D058000607150622D0700000000A5E -:103090000422D0980006071B0622D0B00000000AC8 -:1030A0000422D0D8000607210622D0F00000000A32 -:1030B0000422D118000607270622D1300000000A9A -:1030C0000422D1580006072D0622D1700000000A04 -:1030D0000422D198000607330622D1B00000000A6E -:1030E0000422D1D8000607390622D1F00000000AD8 -:1030F0000422D2180006073F0622D2300000000A40 -:103100000422D258000607450622D2700000000AA9 -:103110000422D2980006074B0622D2B00000000A13 -:103120000422D2D8000607510622D2F00000000A7D -:103130000422D318000607570622D3300000000AE5 -:103140000422D3580006075D0622D3700000000A4F -:103150000422D398000607630622D3B00000000AB9 -:103160000422D3D8000607690622D3F00000000A23 -:103170000422D4180006076F0622D4300000000A8B -:103180000422D458000607750622D4700000000AF5 -:103190000422D4980006077B0622D4B00000000A5F -:1031A0000422D4D8000607810622D4F00000000AC9 -:1031B0000422D518000607870622D5300000000A31 -:1031C0000422D5580006078D0622D5700000000A9B -:1031D0000422D598000607930622D5B00000000A05 -:1031E0000422D5D8000607990622D5F00000000A6F -:1031F0000422D6180006079F0622D6300000000AD7 -:103200000422D658000607A50622D6700000000A40 -:103210000422D698000607AB0622D6B00000000AAA -:103220000422D6D8000607B10622D6F00000000A14 -:103230000422D718000607B70622D7300000000A7C -:103240000422D758000607BD0622D7700000000AE6 -:103250000422D798000607C30622D7B00000000A50 -:103260000422D7D8000607C90622D7F00000000ABA -:103270000422D818000607CF0622D8300000000A22 -:103280000422D858000607D50622D8700000000A8C -:103290000422D898000607DB0622D8B00000000AF6 -:1032A0000422D8D8000607E10622D8F00000000A60 -:1032B0000422D918000607E70622D9300000000AC8 -:1032C0000422D958000607ED0622D9700000000A32 -:1032D0000422D998000607F30622D9B00000000A9C -:1032E0000422D9D8000607F90622D9F00000000A06 -:1032F0000422DA18000607FF0622DA300000000A6E -:103300000422DA58000608050622DA700000000AD6 -:103310000422DA980006080B0622DAB00000000A40 -:103320000422DAD8000608110622DAF00000000AAA -:103330000422DB18000608170622DB300000000A12 -:103340000422DB580006081D0622DB700000000A7C -:103350000422DB98000608230622DBB00000000AE6 -:103360000422DBD8000608290622DBF00000000A50 -:103370000422DC180006082F0622DC300000000AB8 -:103380000422DC58000608350622DC700000000A22 -:103390000422DC980006083B0622DCB00000000A8C -:1033A0000422DCD8000608410622DCF00000000AF6 -:1033B0000422DD18000608470622DD300000000A5E -:1033C0000422DD580006084D0622DD700000000AC8 -:1033D0000422DD98000608530622DDB00000000A32 -:1033E0000422DDD8000608590622DDF00000000A9C -:1033F0000422DE180006085F0622DE300000000A04 -:103400000422DE58000608650622DE700000000A6D -:103410000422DE980006086B0622DEB00000000AD7 -:103420000422DED8000608710622DEF00000000A41 -:103430000422DF18000608770622DF300000000AA9 -:103440000422DF580006087D0622DF700000000A13 -:103450000422DF98000608830622DFB00000000A7D -:103460000422DFD8000608890622DFF00000000AE7 -:103470000422E0180006088F0622E0300000000A4F -:103480000422E058000608950622E0700000000AB9 -:103490000422E0980006089B0622E0B00000000A23 -:1034A0000422E0D8000608A10622E0F00000000A8D -:1034B0000422E118000608A70622E1300000000AF5 -:1034C0000422E158000608AD0622E1700000000A5F -:1034D0000422E198000608B30622E1B00000000AC9 -:1034E0000422E1D8000608B90622E1F00000000439 -:1034F0000622153800000002062211E80000000232 -:103500000622F3000000000802221148000000001B -:1035100006225900000000060622330000000002C7 -:1035200006226040000000300622F3200000000860 -:103530000222114C0000000006225918000000066B -:10354000062233080000000206226100000000305D -:103550000622F34000000008022211500000000083 -:103560000622593000000006062233100000000237 -:10357000062261C0000000300622F360000000084F -:1035800002221154000000000622594800000006E3 -:10359000062233180000000206226280000000307C -:1035A0000622F380000000080222115800000000EB -:1035B00006225960000000060622332000000002A7 -:1035C00006226340000000300622F3A0000000083D -:1035D0000222115C0000000006225978000000065B -:1035E000062233280000000206226400000000309A -:1035F0000622F3C000000008022211600000000053 -:103600000622599000000006062233300000000216 -:10361000062264C0000000300622F3E0000000082B -:103620000222116400000000062259A800000006D2 -:1036300006223338000000020622658000000030B8 -:103640000216100000000028021700080000000207 -:103650000217002C000000030217003C00000004C9 -:10366000021700440000000002170048000000029A -:103670000217004C0000009002170050000000905C -:103680000217005400800090021700580810000034 -:10369000021700700000000602170078000009FF02 -:1036A0000217007C0000076C021701C4081000001C -:1036B0000217034400000001021704000000008A02 -:1036C00002170404000000800217040800000081B3 -:1036D0000217040C00000080021704100000008A8A -:1036E0000217041400000080021704180000008173 -:1036F0000217041C00000080021704300000008A3A -:103700000217043400000080021704380000008112 -:103710000217043C00000080021704400000008AE9 -:1037200002170444000000800217044800000081D2 -:103730000217044C00000080021704800000008A79 -:103740000217048400000080021704880000008132 -:103750000217048C0000008002170038007C10045F -:10376000021700040000000F021701EC0000000225 -:10377000021701F400000002021701EC0000000231 -:10378000021701F400000002021701EC0000000221 -:10379000021701F400000002021701EC0000000211 -:1037A000021701F400000002021701EC0000000201 -:1037B000021701F400000002021701EC00000002F1 -:1037C000021701F400000002021701EC00000002E1 -:1037D000021701F400000002021701EC00000002D1 -:1037E000021701F400000002061640240000000247 -:1037F000021640700000001C021642080000000182 -:1038000002164210000000010216422000000001D2 -:10381000021642280000000102164230000000019A -:103820000216423800000001021642600000000249 -:103830000C16401C0003D0900A16401C0000009C8F -:103840000B16401C000002710216403000000028D8 -:10385000021640340000002C0216403800000030F0 -:103860000216404400000020021640000000000143 -:10387000021640D8000000010216400800000001B6 -:103880000216400C0000000102164010000000016A -:1038900002164240000000000216424800000000EC -:1038A000061642700000000202164250000000009E -:1038B0000216425800000000061642800000000276 -:1038C00002166008000012140216600C00001200BC -:1038D00002166010000012040216601C0000FFFFB8 -:1038E000021660200000FFFF021660240000FFFFA8 -:1038F000021660280000FFFF02166038000000205A -:103900000216603C00000010061660400000000235 -:1039100002166048000000230216604C00000024DC -:1039200002166050000000250216605400000026B8 -:1039300002166058000000270216605C00000011AB -:103940000216606000000000021660640000002B98 -:10395000021660680000002C0216606C0000002D4A -:1039600002166070000000EC021660740000000097 -:1039700002166078000000290216607C0000002A10 -:10398000021660800000002F061660840000000D03 -:10399000021660B800000001061660BC00000008B6 -:1039A000021660DC00000001061660E00000000462 -:1039B000021660F000000001061660F4000000032B -:1039C0000216610000000001061661040000002DCF -:1039D000021661B800000001061661BC0000000874 -:1039E000021661DC00000001061661E00000000420 -:1039F000021661F000000001061661F400000003E9 -:103A00000216620000000001061662040000000DAC -:103A10000216623807FFFFFF0216623C0000007FBB -:103A20000216624007FFFFFF021662440000003FDB -:103A300001166248000000000116624C0000000000 -:103A400001166250000000000116625400000000E0 -:103A500001166258000000000116625C00000000C0 -:103A600001166260000000000116626400000000A0 -:103A700001166268000000000116626C0000000080 -:103A80000116627000000000011662740000000060 -:103A900001166278000000000116627C0000000040 -:103AA000011662D400000000021662D80000FFFF79 -:103AB000021662DC0000FFFF021662E00000FFFF5A -:103AC000021662E40000FFFF0C166000000003E82D -:103AD0000A166000000000010B16600000000003E1 -:103AE0000216804000000006021680440000000517 -:103AF000021680480000000A0216804C00000005F3 -:103B00000216805400000002021680CC000000045F -:103B1000021680D000000004021680D400000004C9 -:103B2000021680D800000004021680DC00000004A9 -:103B3000021680E000000004021680E40000000489 -:103B4000021680E800000004021688040000000647 -:103B5000021680300000007C021680340000003D18 -:103B6000021680380000003F0216803C0000009CD6 -:103B70000216E6E8000060000216E6EC00006000B5 -:103B80000216E6F0000060000216E6F40000600095 -:103B900002168234000025E40216823800008000FC -:103BA00002168094000025E3021681F400000C0840 -:103BB000021681F800000040021681FC000001009E -:103BC0000216820000000020021682040000001786 -:103BD00002168208000000800216820C000002001B -:103BE00002168210000000000216823C0000001342 -:103BF00002168220008F008F0216821C008F008F19 -:103C0000021680F0000000070216821801FF01FF73 -:103C10000216821401FF01FF061680F40000000264 -:103C20000216811C0000000502168120000000051C -:103C300002168124000000050216812800000008F9 -:103C40000216812C000000060216813000000007D9 -:103C50000616813400000004021680FC00000000FB -:103C600006168144000000020216814C0000000488 -:103C7000021681500000000102168154000000026B -:103C800002168158000000050216815C0000000544 -:103C90000216816000000005021681640000000524 -:103CA0000216816800000008021681000000000072 -:103CB0000216816C000000060216817000000007E9 -:103CC00006168174000000060216818C00000004B4 -:103CD000021681900000000102168104000000001D -:103CE000021681940000000202168198000000056F -:103CF0000216819C00000005021681A0000000054C -:103D0000021681A400000005021681A80000000828 -:103D1000021681AC00000006021681B00000000708 -:103D2000061681B40000000202168108000000009F -:103D3000061681BC00000004021681CC00000004BD -:103D4000021681D000000001021681D4000000029A -:103D5000021681D800000005021681DC0000000573 -:103D6000021681E0000000050216810C000000042C -:103D7000021681E400000005021681E80000000838 -:103D8000021681EC00000006021681F00000000718 -:103D900002168110000000010216811400000002CA -:103DA00002168118000000050216809C0000004CDD -:103DB000021680A00000004C061680C4000000021D -:103DC000021680A400000000021680A80000000077 -:103DD000021680AC0000004C061680B00000000502 -:103DE0000216E6F80000020402168240003F003F7F -:103DF00002168244003F003F061682900000000435 -:103E000002168248008000800216824C00800080EA -:103E100002168250010001000216825401000100C6 -:103E20000616825800000002021682600040004020 -:103E30000216826400400040021682681E001E00C6 -:103E40000216826C1E001E000216827040004000A6 -:103E500002168274400040000216827880008000C2 -:103E60000216827C800080000216828020002000E2 -:103E700002168284200020000616828800000002BC -:103E8000021680900000004B021680600000014086 -:103E900002168064000001400616808800000002BF -:103EA00002168068000000000216806C000000000E -:103EB00002168070000000C0061680740000000525 -:103EC0000216880C0101010102168810010120046C -:103ED000021688142008100102168818010101201A -:103EE0000216881C0101010102168820010120042C -:103EF00002168824200810010216882801010120DA -:103F00000216882C200810010216883001010120B9 -:103F100002168834010101010216883801012004CB -:103F20000216883C20081001021688400101012079 -:103F3000021688440101010102168848010120048B -:103F40000216E6BC000000000216E6C000000002F7 -:103F50000216E6C4000000040216E6C800000006CF -:103F60000216E79400000001021680EC000000FF3A -:103F700002140000000000010215C024000000002F -:103F80000215C0EC000000010215C0F000000001A5 -:103F90000615C10000000002021400040000000128 -:103FA00002140008000000010214000C00000001CF -:103FB000021400300000000102140034000000016F -:103FC0000214004000000001021400440000FFFF42 -:103FD00006140004000000030214000000000000AA -:103FE000060280000000200002020058000000329B -:103FF000020200A003150020020200A40315002005 -:10400000020200A801000030020200AC081000000B -:10401000020200B000000036020200B400000030CE -:10402000020200B800000031020200BC00000002E1 -:10403000020200C000000005020200C400000002ED -:10404000020200C800000002020200D000000007C7 -:10405000020200DC00000000020200E00000000597 -:10406000020200E400000003020200F00000000170 -:10407000020200FC00000006020201200000000015 -:104080000202013400000002020201B0000000013F -:104090000202020C000000010202021400000001F2 -:1040A00002020218000000020202040400000001E3 -:1040B0000202040C00000040020204100000004054 -:1040C0000202041C00000004020204200000002080 -:1040D0000202042400000002020204280000002062 -:1040E000060205000000001204020480002008BF40 -:1040F000020200600000000F0202006400000007DE -:1041000002020068000000000202006C0000000EC5 -:10411000020200700000000E06020074000000039E -:10412000020200F40000000402020004000000018A -:1041300002020008000000010202000C0000000161 -:104140000202001000000001020200140000000141 -:1041500002020018000000010202001C0000000121 -:104160000202002000000001020200240000000101 -:1041700002020028000000010202002C00000001E1 -:1041800002020030000000010202003400000001C1 -:1041900002020038000000010202003C00000001A1 -:1041A0000202004000000001020200440000000181 -:1041B00002020048000000010202004C0000000161 -:1041C000020200500000000102020108000000C8C5 -:1041D0000202011800000002020201C400000000F7 -:1041E000020201CC00000000020201D40000000223 -:1041F000020201DC00000002020201E4000000FFF4 -:10420000020201EC000000FF0202010000000000B9 -:104210000202010C000000C80202011C00000002A2 -:10422000020201C800000000020201D000000000EC -:10423000020201D800000002020201E000000002B8 -:10424000020201E8000000FF020201F0000000FF8E -:10425000020201040000002002020108000000C860 -:104260000202011800000002020201C40000000066 -:10427000020201CC00000000020201D40000000292 -:10428000020201DC00000002020201E4000000FF63 -:10429000020201EC000000FF020201000000001019 -:1042A0000202010C000000C80202011C0000000212 -:1042B000020201C800000000020201D0000000005C -:1042C000020201D800000002020201E00000000228 -:1042D000020201E8000000FF020201F0000000FFFE -:1042E000020201040000003002020108000000C8C0 -:1042F0000202011800000002020201C400000000D6 -:10430000020201CC00000000020201D40000000201 -:10431000020201DC00000002020201E4000000FFD2 -:10432000020201EC000000FF020201000000004058 -:104330000202010C000000C80202011C0000000281 -:10434000020201C800000000020201D000000000CB -:10435000020201D800000002020201E00000000297 -:10436000020201E8000000FF020201F0000000FF6D -:10437000020201040000006002020108000000C8FF -:104380000202011800000002020201C40000000045 -:10439000020201CC00000000020201D40000000271 -:1043A000020201DC00000002020201E4000000FF42 -:1043B000020201EC000000FF0202010000000050B8 -:1043C0000202010C000000C80202011C00000002F1 -:1043D000020201C800000000020201D0000000003B -:1043E000020201D800000002020201E00000000207 -:1043F000020201E8000000FF020201F0000000FFDD -:1044000002020104000000700728040000B300004D -:10441000082807B8000908DF072C000028CB000097 -:10442000072C8000365D0A33072D0000347017CB4F -:10443000072D80003A9424E8072E000036C7338EFB -:10444000072E80001CE94140082EC5D0274608E110 -:10445000022800BC0000003001280000000000001D -:1044600001280004000000000128000800000000EE -:104470000128000C000000000128001000000000CE -:1044800001280014000000000228002000000001A4 -:104490000228002400000002022800280000000377 -:1044A0000228002C00000000022800300000000458 -:1044B000022800340000000102280038000000003B -:1044C0000228003C00000001022800400000000417 -:1044D00002280044000000000228004800000001FB -:1044E0000228004C000000030228005000000000D9 -:1044F00002280054000000010228005800000004B7 -:104500000228005C0000000002280060000000019A -:104510000228006400000003022800680000000078 -:104520000228006C00000001022800700000000456 -:104530000228007400000000022800780000000437 -:104540000228007C00000003062800800000000212 -:10455000022800A400007FFF022800A8000003FF3B -:10456000022802240000000002280234000000009B -:104570000228024C00000000022802E40000FFFFB5 -:104580000628200000000800022B8BC0000000015C -:10459000022B800000000000022B80400000001869 -:1045A000022B80800000000C022B80C000000066FF -:1045B0000C2B8300000864700A2B83000000015755 -:1045C0000B2B83000000055F0A2B834000000000D6 -:1045D0000C2B8340000002260B2B834000000001BF -:1045E000022B838000086470022B83C00000022627 -:1045F000022B1480000000010A2B14800000000030 -:10460000022B944000000001062B94480000000299 -:10461000062A9A7000000004042A9A80000408E325 -:10462000062A9A9000000002042A9A98000208E7DD -:10463000062A900000000048062A2008000000C852 -:10464000062A200000000002062A912800000086A9 -:10465000062AC00000000120062A9348000000033B -:10466000042A9354000108E9062A9FB000000002C2 -:10467000042A9418000208EA042A9CD0000108ECDD -:10468000062A9CD400000011042A9D20008F08ED0A -:10469000062A9F5C00000005042A30000002097C05 -:1046A000062A300800000100062A404000000010E1 -:1046B000042A40000010097E042A84080002098EA2 -:1046C000042ACF4000040990042ACF600002099414 -:1046D000062A9FA000000004062A60000000054092 -:1046E000062A9D1800000002062AB00000000050B3 -:1046F000062ABB7000000070062ABB68000000029A -:10470000062AB94800000004062AD000000008006C -:10471000062AC48000000150062A942000000032BE -:10472000062A502000000002062A50300000000235 -:10473000062A500000000002062A50100000000265 -:10474000022A520800000001042A9AA000020996D9 -:10475000062A95B000000022042A96380001099824 -:10476000062A963C00000003062A96E0000000227C -:10477000042A976800010999062A976C0000000333 -:10478000062A981000000022042A98980001099A2D -:10479000062A989C00000003062A99400000002287 -:1047A000042A99C80001099B062A99CC000000033D -:1047B000062ABB5800000002062AC9C000000150AA -:1047C000062A94E800000032062A50280000000261 -:1047D000062A503800000002062A50080000000295 -:1047E000062A501800000002022A520C00000001A4 -:1047F000042A9AA80002099C062A96480000002272 -:10480000042A96D00001099E062A96D400000003CF -:10481000062A977800000022042A98000001099FC8 -:10482000062A980400000003062A98A80000002227 -:10483000042A9930000109A0062A993400000003D7 -:10484000062A99D800000022042A9A60000109A1D2 -:10485000062A9A6400000003062ABB6000000002DA -:10486000022ACF0000000000042A9AB0001009A21A -:10487000062A50480000000E022ACF040000000063 -:10488000042A9AF0001009B2062A50800000000E97 -:10489000022ACF0800000000042A9B30001009C241 -:1048A000062A50B80000000E022ACF0C00000000BB -:1048B000042A9B70001009D2062A50F00000000E56 -:1048C000022ACF1000000000042A9BB0001009E269 -:1048D000062A51280000000E022ACF140000000012 -:1048E000042A9BF0001009F2062A51600000000E15 -:1048F000022ACF1800000000042A9C3000100A028F -:10490000062A51980000000E022ACF1C0000000069 -:10491000042A9C7000100A12062A51D00000000ED2 -:1049200002101008000000010210105000000001E9 -:10493000021010000003D000021010040000003D1F -:104940000910180002000A220910110000100C22A0 -:1049500006101140000000080910116000100C3210 -:10496000061011A00000001806102400000000E04E -:104970000210201C00000000021020200000000196 -:10498000021020C0000000020210200400000001FC -:104990000210200800000001021030D800000001C1 -:1049A00009103C0000050C420910380000050C47B6 -:1049B0000910392000050C4C09103B0000050C5172 -:1049C000021040D400000030021040D80000003037 -:1049D00006104C00000001000210402800000010EA -:1049E0000210404400003FFF021040580028000021 -:1049F000021040840084924A0210405800000000D7 -:104A0000021041380000000102104138000000018E -:104A1000021041380000000102104138000000017E -:104A2000021041380000000102104138000000016E -:104A3000021041380000000102104138000000015E -:104A40000212049001F680400212051400003C108E -:104A500002120494FFFFFFFF02120498FFFFFFFF02 -:104A60000212049CFFFFFFFF021204A0FFFFFFFFE2 -:104A7000021204A4FFFFFFFF021204A8FFFFFFFFC2 -:104A8000021204ACFFFFFFFF021204B0FFFFFFFFA2 -:104A9000021204B8FFFFFFFF021204BCFFFFFFFF7A -:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A -:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A -:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 -:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 -:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 -:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 -:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 -:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 -:104B200002120504FFFFFFFF02120508FFFFFFFF4F -:104B30000212050CFFFFFFFF02120510FFFFFFFF2F -:104B4000021204D4F800C000021204B4F0005000B5 -:104B500002120390000000080212039C00000008EB -:104B6000021203A000000008021203A400000002C9 -:104B7000021203BC00000004021203C00000000582 -:104B8000021203C400000004021203D0000000005F -:104B90000212036C00000001021201BC0000004080 -:104BA000021201C000001808021201C4000008032C -:104BB000021201C800000803021201CC00000040EC -:104BC000021201D000000003021201D40000080309 -:104BD000021201D800000803021201DC00000803E1 -:104BE000021201E000010003021201E400000803C8 -:104BF000021201E800000803021201EC00000003A9 -:104C0000021201F000000003021201F40000000390 -:104C1000021201F800000003021201FC0000000370 -:104C2000021202000000000302120204000000034E -:104C300002120208000000030212020C000000032E -:104C4000021202100000000302120214000000030E -:104C500002120218000000030212021C00000003EE -:104C600002120220000000030212022400000003CE -:104C700002120228000024030212022C0000002F5E -:104C80000212023000000009021202340000001972 -:104C900002120238000001840212023C000001836B -:104CA0000212024000000306021202440000001932 -:104CB00002120248000000060212024C0000030625 -:104CC0000212025000000306021202540000030602 -:104CD0000212025800000C860212025C0000030659 -:104CE00002120260000003060212026400000006C5 -:104CF00002120268000000060212026C00000006A8 -:104D00000212027000000006021202740000000687 -:104D100002120278000000060212027C0000000667 -:104D20000212028000000006021202840000000647 -:104D300002120288000000060212028C0000000627 -:104D40000212029000000006021202940000000607 -:104D500002120298000000060212029C00000006E7 -:104D6000021202A000000306021202A400000013B7 -:104D7000021202A800000006021202B00000100495 -:104D8000021202B400001004021203240010644056 -:104D90000212032800106440021205B40000000152 -:104DA000021205F800000040021205FC0000001984 -:104DB00002120600000000010212066C0000000151 -:104DC000021201B000000001021207D80000000327 -:104DD000021207D800000003021207D800000003E7 -:104DE000021207D800000003021207D800000003D7 -:104DF000021207D800000003021207D800000003C7 -:104E0000021207D8000000030600A0000000000CFA -:104E10000200A050000000000200A05400000000AA -:104E20000200A0EC555400000200A0F05555555565 -:104E30000200A0F4000055550200A0F8F0000000A8 -:104E40000200A0FC555400000200A1005555555524 -:104E50000200A104000055550200A108F000000066 -:104E60000200A19C000000000200A1A000010000BF -:104E70000200A1A4000050140200A1A8000000003C -:104E80000200A6A8000000000200A6AC000000007E -:104E90000200A6D0000000000200A45C00000C008C -:104EA0000200A61C000000030200A070FFF55FFFD7 -:104EB0000200A0740000FFFF0200A078F00003E0F1 -:104EC0000200A07C000000000200A0800000A00002 -:104ED0000600A084000000050200A0980FE000007A -:104EE0000600A09C000000070200A0B8000004001B -:104EF0000600A0BC000000030200A0C800001000D3 -:104F00000600A0CC000000030200A0D80000400072 -:104F10000600A0DC000000030200A0E80001000081 -:104F20000600A22C000000040200A688000000FC7D -:104F30000600A68C000000070200A6F40000000096 -:104F40000200A10CFF5C00000200A110FFF55FFF52 -:104F50000200A1140000FFFF0200A118F00003E00E -:104F60000200A11C000000000200A1200000A0001F -:104F70000600A124000000050200A1380FE0000097 -:104F80000600A13C000000070200A1580000080034 -:104F90000600A15C000000030200A16800002000E0 -:104FA0000600A16C000000030200A1780000800050 -:104FB0000600A17C000000030200A188000200009E -:104FC0000600A23C000000040200A6B0000000FCA5 -:104FD0000600A6B4000000070200A6F800000000CA -:104FE0000200A030000000000200A0340000000019 -:104FF0000200A038000000000200A03C00000000F9 -:105000000200A040000000000200A04400000000D8 -:105010000200A048000000000200A04C00000000B8 -:10502000020090C40000E000020090CC0000F300F9 -:10503000020090D400000003020091A000000001D3 -:105040000600917000000003020090EC0000600078 -:10505000020090F400007300020090FC00000003C6 -:10506000020091A8000000010600918800000003E2 -:10507000020091000000400002009108000053006F -:105080000200911000000004020091AC0000000139 -:1050900006009194000000020200919C00000001B3 -:1050A000020090D800006000020090E00000730051 -:1050B000020090E800000003020091A4000000013B -:1050C0000200917C000000010200918000000001BC -:1050D00002009184000000000200912800000300FB -:1050E0000200916C0003F0080200912C0000030004 -:1050F0000200913000000300020091340000030020 -:1051000002009138000003000200913C00000300FF -:1051100002009140000003000200942C00000001F6 -:1051200002009430000000010200943400000001ED -:105130000200942C000000010200943000000001E5 -:1051400002009434000000010200942C00000001D1 -:1051500002009430000000010200943400000001BD -:105160000200942C000000010200943000000001B5 -:1051700002009434000000010200942C00000001A1 -:10518000020094300000000102009434000000018D -:105190000200942C00000001020094300000000185 -:1051A00002009434000000010200942C0000000171 -:1051B000020094300000000102009434000000015D -:1051C0000200942C00000001020094300000000155 -:1051D0000200943400000001021300780000003047 -:1051E0000213003C000061A8061301080000000340 -:1051F000021301040000000002130134000000004B -:10520000061301080000000302130104000000005F -:10521000021301340000000006130108000000031F -:10522000021301040000000002130134000000001A -:10523000061301080000000302130104000000002F -:1052400002130134000000000613010800000003EF -:1052500002130104000000000213013400000000EA -:1052600006130108000000030213010400000000FF -:1052700002130134000000000613010800000003BF -:1052800002130104000000000213013400000000BA -:1052900006130108000000030213010400000000CF -:1052A0000213013400000000021100B800000001E8 -:1052B0000216E6E8000020000216E6EC00002000DE -:1052C0000216E6F0000065550216E6F4000065558A -:1052D00002168150000000000216817400000001D7 -:1052E00002168178000000010216817C0000000196 -:1052F0000216818000000001021681840000000176 -:105300000216818800000001021681B4000000012D -:10531000021681B800000001021681BC00000001E5 -:10532000021681C000000001021681C400000001C5 -:10533000021681C800000001021681100000000062 -:105340000216824000BF00BF061682440000000221 -:105350000216824C00BF00BF0216E6C40000000126 -:105360000216E6C8000000030216E79400000000E1 -:10537000042ACF40000A0C56000000000000000084 -:1053800000000034000000000000000000000000E9 -:10539000000000000000000000000000000000000D -:1053A0000000000000000000000000000034003594 -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D0000000000000000000003500600000000038 -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:1054000000000000006000910000000000000000AB -:1054100000910095009500990099009D009D00A1C4 -:1054200000A100A500A500A900A900AD00AD00B134 -:1054300000B100B500000000000000000000000006 -:10544000000000000000000000000000000000005C -:1054500000000000000000000000000000B5031183 -:105460000311031B031B03250325032C032C033308 -:105470000333033A033A0341034103480348034F0C -:10548000034F03560356035D0000000000000000B8 -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:105530000000000000000000035D035E00000000AA -:1055400000000000035E035F035F0360036003610C -:10555000036103620362036303630364036403651B -:10556000036503660000000000000000000000006A -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:105590000366036D036D0379037903850000000042 -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000385038600000000AA -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:1056100000000000038603B100000000000000004D -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:1056400003B103E0000000000000000000000000C3 -:10565000000000000000000000000000000000004A -:1056600000000000000000000000000003E0040F44 -:105670000000000000000000040F04160416041DC2 -:10568000041D04240424042B042B043204320439A2 -:1056900004390440044004470447047A0000000031 -:1056A00000000000047A047E047E048204820486E2 -:1056B0000486048A048A048E048E0492049204965A -:1056C0000496049A049A04EA04EA05000500051603 -:1056D000051605180518051A051A051C051C051ED2 -:1056E000051E052005200522052205240524052682 -:1056F00005260693000000000000000006930698AF -:105700000698069D069D06A206A206A706A706AC59 -:1057100006AC06B106B106B606B606BB06BB06BCAD -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:10574000000000000000000006BC06E000000000B1 -:105750000000000006E006E206E206E406E406E6D3 -:1057600006E606E806E806EA06EA06EC06EC06EEB9 -:1057700006EE06F006F00705070507080708070B01 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A000070B074F00000000000000000000000091 -:1057B00000000000000000000000000000000000E9 -:1057C000000000000000000000000000074F07E19B -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F000000000000000000007E107EF00000000CB -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000007EF082C00000000000000004E -:10583000082C08350835083E083E08470847085038 -:1058400008500859085908620862086B086B087408 -:10585000087408D508D508EA08EA08FF08FF090215 -:1058600009020905090509080908090B090B090EB0 -:10587000090E09110911091409140917091709203A -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000920092600000000A0 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D000000000000926092B000000000000000065 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:10590000092B0933000000000000000009330934AE -:10591000093409350935093609360937093709388F -:10592000093809390939093A093A093B00000000E8 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000093B09AC000000004E -:105960000000000009AC09AD09AD09AE09AE09AFF0 -:1059700009AF09B009B009B109B109B209B209B357 -:1059800009B309B409B409C809C809DB09DB09EF7F -:1059900009EF09F009F009F109F109F209F209F337 -:1059A00009F309F409F409F509F509F609F609F707 -:1059B00009F70A1600000000000000000A160A1984 -:1059C0000A190A1C0A1C0A1F0A1F0A220A220A258F -:1059D0000A250A280A280A2B0A2B0A2E0A2E0A3020 -:1059E00000000000000000000A300A330A330A36C3 -:1059F0000A360A390A390A3C0A3C0A3F0A3F0A4277 -:105A00000A420A450A450A480A480A4900000000B5 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A3000000000000A490A610000000000000000A8 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000A610A620000000000000000000000005F -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A9000000100000002070000030E0000041500D2 -:105AA00000051C000006230000072A000008310042 -:105AB00000093800000A3F00000B4600000C4D00B2 -:105AC000000D5400000E5B00000F62000010690022 -:105AD000001170000012770000137E000014850092 -:105AE00000158C000016930000179A000018A10002 -:105AF0000019A800001AAF00001BB600001CBD0072 -:105B0000001DC400001ECB00001FD2000000D90001 -:105B10000000200000004000000060000000800045 -:105B20000000A0000000C0000000E0000001000034 -:105B30000001200000014000000160000001800021 -:105B40000001A0000001C0000001E0000002000010 -:105B500000022000000240000002600000028000FD -:105B60000002A0000002C0000002E00000030000EC -:105B700000032000000340000003600000038000D9 -:105B80000003A0000003C0000003E00000040000C8 -:105B900000042000000440000004600000048000B5 -:105BA0000004A0000004C0000004E00000050000A4 -:105BB0000005200000054000000560000005800091 -:105BC0000005A0000005C0000005E0000006000080 -:105BD000000620000006400000066000000680006D -:105BE0000006A0000006C0000006E000000700005C -:105BF0000007200000074000000760000007800049 -:105C00000007A0000007C0000007E0000008000037 -:105C10000008200000084000000860000008800024 -:105C20000008A0000008C0000008E0000009000013 -:105C30000009200000094000000960000009800000 -:105C40000009A0000009C0000009E000000A0000EF -:105C5000000A2000000A4000000A6000000A8000DC -:105C6000000AA000000AC000000AE000000B0000CB -:105C7000000B2000000B4000000B6000000B8000B8 -:105C8000000BA000000BC000000BE000000C0000A7 -:105C9000000C2000000C4000000C6000000C800094 -:105CA000000CA000000CC000000CE000000D000083 -:105CB000000D2000000D4000000D6000000D800070 -:105CC000000DA000000DC000000DE000000E00005F -:105CD000000E2000000E4000000E6000000E80004C -:105CE000000EA000000EC000000EE000000F00003B -:105CF000000F2000000F4000000F6000000F800028 -:105D0000000FA000000FC000000FE0000010000016 -:105D10000010200000104000001060000010800003 -:105D20000010A0000010C0000010E00000110000F2 -:105D300000112000001140000011600000118000DF -:105D40000011A0000011C0000011E00000120000CE -:105D500000122000001240000012600000128000BB -:105D60000012A0000012C0000012E00000130000AA -:105D70000013200000134000001360000013800097 -:105D80000013A0000013C0000013E0000014000086 -:105D90000014200000144000001460000014800073 -:105DA0000014A0000014C0000014E0000015000062 -:105DB000001520000015400000156000001580004F -:105DC0000015A0000015C0000015E000001600003E -:105DD000001620000016400000166000001680002B -:105DE0000016A0000016C0000016E000001700001A -:105DF0000017200000174000001760000017800007 -:105E00000017A0000017C0000017E00000180000F5 -:105E100000182000001840000018600000188000E2 -:105E20000018A0000018C0000018E00000190000D1 -:105E300000192000001940000019600000198000BE -:105E40000019A0000019C0000019E000001A0000AD -:105E5000001A2000001A4000001A6000001A80009A -:105E6000001AA000001AC000001AE000001B000089 -:105E7000001B2000001B4000001B6000001B800076 -:105E8000001BA000001BC000001BE000001C000065 -:105E9000001C2000001C4000001C6000001C800052 -:105EA000001CA000001CC000001CE000001D000041 -:105EB000001D2000001D4000001D6000001D80002E -:105EC000001DA000001DC000001DE000001E00001D -:105ED000001E2000001E4000001E6000001E80000A -:105EE000001EA000001EC000001EE000001F0000F9 -:105EF000001F2000001F4000001F6000001F8000E6 -:105F0000001FA000001FC000001FE00000200000D4 -:105F100000202000002040000020600000208000C1 -:105F20000020A0000020C0000020E00000210000B0 -:105F3000002120000021400000216000002180009D -:105F40000021A0000021C0000021E000002200008C -:105F50000022200000224000002260000022800079 -:105F60000022A0000022C0000022E0000023000068 -:105F70000023200000234000002360000023800055 -:105F80000023A0000023C0000023E0000024000044 -:105F90000024200000244000002460000024800031 -:105FA0000024A0000024C0000024E0000025000020 -:105FB000002520000025400000256000002580000D -:105FC0000025A0000025C0000025E00000260000FC -:105FD00000262000002640000026600000268000E9 -:105FE0000026A0000026C0000026E00000270000D8 -:105FF00000272000002740000027600000278000C5 -:106000000027A0000027C0000027E00000280000B3 -:1060100000282000002840000028600000288000A0 -:106020000028A0000028C0000028E000002900008F -:10603000002920000029400000296000002980007C -:106040000029A0000029C0000029E000002A00006B -:10605000002A2000002A4000002A6000002A800058 -:10606000002AA000002AC000002AE000002B000047 -:10607000002B2000002B4000002B6000002B800034 -:10608000002BA000002BC000002BE000002C000023 -:10609000002C2000002C4000002C6000002C800010 -:1060A000002CA000002CC000002CE000002D0000FF -:1060B000002D2000002D4000002D6000002D8000EC -:1060C000002DA000002DC000002DE000002E0000DB -:1060D000002E2000002E4000002E6000002E8000C8 -:1060E000002EA000002EC000002EE000002F0000B7 -:1060F000002F2000002F4000002F6000002F8000A4 -:10610000002FA000002FC000002FE0000030000092 -:10611000003020000030400000306000003080007F -:106120000030A0000030C0000030E000003100006E -:10613000003120000031400000316000003180005B -:106140000031A0000031C0000031E000003200004A -:106150000032200000324000003260000032800037 -:106160000032A0000032C0000032E0000033000026 -:106170000033200000334000003360000033800013 -:106180000033A0000033C0000033E0000034000002 -:1061900000342000003440000034600000348000EF -:1061A0000034A0000034C0000034E00000350000DE -:1061B00000352000003540000035600000358000CB -:1061C0000035A0000035C0000035E00000360000BA -:1061D00000362000003640000036600000368000A7 -:1061E0000036A0000036C0000036E0000037000096 -:1061F0000037200000374000003760000037800083 -:106200000037A0000037C0000037E0000038000071 -:10621000003820000038400000386000003880005E -:106220000038A0000038C0000038E000003900004D -:10623000003920000039400000396000003980003A -:106240000039A0000039C0000039E000003A000029 -:10625000003A2000003A4000003A6000003A800016 -:10626000003AA000003AC000003AE000003B000005 -:10627000003B2000003B4000003B6000003B8000F2 -:10628000003BA000003BC000003BE000003C0000E1 -:10629000003C2000003C4000003C6000003C8000CE -:1062A000003CA000003CC000003CE000003D0000BD -:1062B000003D2000003D4000003D6000003D8000AA -:1062C000003DA000003DC000003DE000003E000099 -:1062D000003E2000003E4000003E6000003E800086 -:1062E000003EA000003EC000003EE000003F000075 -:1062F000003F2000003F4000003F6000003F800062 -:10630000003FA000003FC000003FE000003FE00170 -:1063100000000000000001FF0000020000007FF804 -:1063200000007FF800000A90000035000000000126 -:106330000000FF00000000000000FF00000000005F -:106340000000FF00000000000000FF00000000004F -:106350000000FF00000000000000FF00000000003F -:106360000000FF00000000000000FF00000000002F -:106370000000FF00000000000000FF00000000001F -:106380000000FF00000000000000FF00000000000F -:106390000000FF00000000000000FF0000000000FF -:1063A0000000FF00000000000000FF0000000000EF -:1063B0000000FF00000000000000FF0000000000DF -:1063C0000000FF00000000000000FF0000000000CF -:1063D0000000FF00000000000000FF0000000000BF -:1063E0000000FF00000000000000FF0000000000AF -:1063F0000000FF00000000000000FF00000000009F -:106400000000FF00000000000000FF00000000008E -:106410000000FF00000000000000FF00000000007E -:106420000000FF00000000000000FF00000000006E -:106430000000FF00000000000000FF00000000005E -:106440000000FF00000000000000FF00000000004E -:106450000000FF00000000000000FF00000000003E -:106460000000FF00000000000000FF00000000002E -:106470000000FF00000000000000FF00000000001E -:106480000000FF00000000000000FF00000000000E -:106490000000FF00000000000000FF0000000000FE -:1064A0000000FF00000000000000FF0000000000EE -:1064B0000000FF00000000000000FF0000000000DE -:1064C0000000FF00000000000000FF0000000000CE -:1064D0000000FF00000000000000FF0000000000BE -:1064E0000000FF00000000000000FF0000000000AE -:1064F0000000FF00000000000000FF00000000009E -:106500000000FF00000000000000FF00000000008D -:106510000000FF00000000000000FF00000000007D -:106520000000FF00000000000000FF00000000006D -:106530000000FF00000000000000FF00000000005D -:106540000000FF00000000000000FF00000000004D -:106550000000FF00000000000000FF00000000003D -:106560000000FF00000000000000FF00000000002D -:1065700000000000140AFF000000000100000000FD -:106580000020100100000000010090000000010048 -:1065900000009002000090040000900600009008A7 -:1065A0000000900A0000900C0000900E0000901077 -:1065B0000000901200009014000090160000901847 -:1065C0000000901A0000901C0000901E0000902017 -:1065D00000009022000090240000902600009028E7 -:1065E0000000902A0000902C0000902E00009030B7 -:1065F0000000903200009034000090360000903887 -:106600000000903A0000903C0000903E0000904056 -:106610000000904200009044000090460000904826 -:106620000000904A0000904C0000904E00009050F6 -:1066300000009052000090540000905600009058C6 -:106640000000905A0000905C0000905E0000906096 -:106650000000906200009064000090660000906866 -:106660000000906A0000906C0000906E0000907036 -:106670000000907200009074000090760000907806 -:106680000000907A0000907C0000907E00009080D6 -:1066900000009082000090840000908600009088A6 -:1066A0000000908A0000908C0000908E0000909076 -:1066B0000000909200009094000090960000909846 -:1066C0000000909A0000909C0000909E000090A016 -:1066D000000090A2000090A4000090A6000090A8E6 -:1066E000000090AA000090AC000090AE000090B0B6 -:1066F000000090B2000090B4000090B6000090B886 -:10670000000090BA000090BC000090BE000090C055 -:10671000000090C2000090C4000090C6000090C825 -:10672000000090CA000090CC000090CE000090D0F5 -:10673000000090D2000090D4000090D6000090D8C5 -:10674000000090DA000090DC000090DE000090E095 -:10675000000090E2000090E4000090E6000090E865 -:10676000000090EA000090EC000090EE000090F035 -:10677000000090F2000090F4000090F6000090F805 -:10678000000090FA000090FC000090FE00009100D4 -:1067900000009102000091040000910600009108A1 -:1067A0000000910A0000910C0000910E0000911071 -:1067B0000000911200009114000091160000911841 -:1067C0000000911A0000911C0000911E0000912011 -:1067D00000009122000091240000912600009128E1 -:1067E0000000912A0000912C0000912E00009130B1 -:1067F0000000913200009134000091360000913881 -:106800000000913A0000913C0000913E0000914050 -:106810000000914200009144000091460000914820 -:106820000000914A0000914C0000914E00009150F0 -:1068300000009152000091540000915600009158C0 -:106840000000915A0000915C0000915E0000916090 -:106850000000916200009164000091660000916860 -:106860000000916A0000916C0000916E0000917030 -:106870000000917200009174000091760000917800 -:106880000000917A0000917C0000917E00009180D0 -:1068900000009182000091840000918600009188A0 -:1068A0000000918A0000918C0000918E0000919070 -:1068B0000000919200009194000091960000919840 -:1068C0000000919A0000919C0000919E000091A010 -:1068D000000091A2000091A4000091A6000091A8E0 -:1068E000000091AA000091AC000091AE000091B0B0 -:1068F000000091B2000091B4000091B6000091B880 -:10690000000091BA000091BC000091BE000091C04F -:10691000000091C2000091C4000091C6000091C81F -:10692000000091CA000091CC000091CE000091D0EF -:10693000000091D2000091D4000091D6000091D8BF -:10694000000091DA000091DC000091DE000091E08F -:10695000000091E2000091E4000091E6000091E85F -:10696000000091EA000091EC000091EE000091F02F -:10697000000091F2000091F4000091F6000091F8FF -:10698000000091FA000091FC000091FEFFFFFFFF64 -:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 -:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 -:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 -:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 -:1069D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 -:1069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 -:1069F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 -:106A0000FFFFFFFFFFFFFFFFFFFFFFFF000000038F -:106A100000BEBC20000000000000000500000003D4 -:106A200000BEBC20000000000000000500000003C4 -:106A300000BEBC20000000000000000500000003B4 -:106A400000BEBC20000000000000000500000003A4 -:106A500000BEBC2000000000000000050000000394 -:106A600000BEBC2000000000000000050000000384 -:106A700000BEBC2000000000000000050000000374 -:106A800000BEBC2000000000000000050000200047 -:106A9000000040C000006180000082400000A300B0 -:106AA0000000C3C00000E480000105400001260092 -:106AB000000146C000016780000188400001A90074 -:106AC0000001C9C00001EA8000020B4000022C0056 -:106AD00000024CC000026D8000028E400002AF0038 -:106AE0000002CFC00002F0800000114000008000D2 -:106AF000000103800001870000020A8000028E006E -:106B000000031180000395000004188000049C001D -:106B100000051F800005A300000626800006AA00CD -:106B200000072D800007B100000834800008B8007D -:106B300000093B800009BF00000A4280000AC6002D -:106B4000000B4980000BCD00000C5080000CD400DD -:106B5000000D578000005B0000007FF800007FF808 -:106B60000000022A000035000000FF0000000000C5 -:106B70000000FF00000000000000FF000000000017 -:106B80000000FF00000000000000FF000000000007 -:106B90000000FF00000000000000FF0000000000F7 -:106BA0000000FF00000000000000FF0000000000E7 -:106BB0000000FF00000000000000FF0000000000D7 -:106BC0000000FF00000000000000FF0000000000C7 -:106BD0000000FF00000000000000FF0000000000B7 -:106BE0000000FF00000000000000FF0000000000A7 -:106BF0000000FF00000000000000FF000000000097 -:106C00000000FF00000000000000FF000000000086 -:106C10000000FF00000000000000FF000000000076 -:106C20000000FF00000000000000FF000000000066 -:106C30000000FF00000000000000FF000000000056 -:106C40000000FF00000000000000FF000000000046 -:106C50000000FF00000000000000FF000000000036 -:106C60000000FF00000000000000FF000000000026 -:106C70000000FF00000000000000FF000000000016 -:106C80000000FF00000000000000FF000000000006 -:106C90000000FF00000000000000FF0000000000F6 -:106CA0000000FF00000000000000FF0000000000E6 -:106CB0000000FF00000000000000FF0000000000D6 -:106CC0000000FF00000000000000FF0000000000C6 -:106CD0000000FF00000000000000FF0000000000B6 -:106CE0000000FF00000000000000FF0000000000A6 -:106CF0000000FF00000000000000FF000000000096 -:106D00000000FF00000000000000FF000000000085 -:106D10000000FF00000000000000FF000000000075 -:106D20000000FF00000000000000FF000000000065 -:106D30000000FF00000000000000FF000000000055 -:106D40000000FF00000000000000FF000000000045 -:106D50000000FF00000000000000FF000000000035 -:106D60000000FF00000000000000FF000000000025 -:106D70000000FF00000000000000FF000000000015 -:106D80000000FF00000000000000FF000000000005 -:106D90000000FF00000000000000FF0000000000F5 -:106DA0000000FF00000019000000000000000000CB -:106DB000FFFFFFFF000000000393870000000000BA -:106DC0000393870000007FF800007FF800000BA30A -:106DD00000001500000000FF000000FF000000FFA1 -:106DE000000000FF000000FF000000FF000000FFA7 -:106DF000000000FF0000FF00000000000000FF0096 -:106E0000000000000000FF00000000000000FF0084 -:106E1000000000000000FF00000000000000FF0074 -:106E2000000000000000FF00000000000000FF0064 -:106E3000000000000000FF00000000000000FF0054 -:106E4000000000000000FF00000000000000FF0044 -:106E5000000000000000FF00000000000000FF0034 -:106E6000000000000000FF00000000000000FF0024 -:106E7000000000000000FF00000000000000FF0014 -:106E8000000000000000FF00000000000000FF0004 -:106E9000000000000000FF00000000000000FF00F4 -:106EA000000000000000FF00000000000000FF00E4 -:106EB000000000000000FF00000000000000FF00D4 -:106EC000000000000000FF00000000000000FF00C4 -:106ED000000000000000FF00000000000000FF00B4 -:106EE000000000000000FF00000000000000FF00A4 -:106EF000000000000000FF00000000000000FF0094 -:106F0000000000000000FF00000000000000FF0083 -:106F1000000000000000FF00000000000000FF0073 -:106F2000000000000000FF00000000000000FF0063 -:106F3000000000000000FF00000000000000FF0053 -:106F4000000000000000FF00000000000000FF0043 -:106F5000000000000000FF00000000000000FF0033 -:106F6000000000000000FF00000000000000FF0023 -:106F7000000000000000FF00000000000000FF0013 -:106F8000000000000000FF00000000000000FF0003 -:106F9000000000000000FF00000000000000FF00F3 -:106FA000000000000000FF00000000000000FF00E3 -:106FB000000000000000FF00000000000000FF00D3 -:106FC000000000000000FF00000000000000FF00C3 -:106FD000000000000000FF00000000000000FF00B3 -:106FE000000000000000FF00000000000000FF00A3 -:106FF000000000000000FF00000000000000FF0093 -:10700000000000000000FF00000000000000FF0082 -:10701000000000000000FF00000000000000FF0072 -:10702000000000000000FF00000000000000FF0062 -:1070300000000000FFFFFFFFFFFFFFFFFFFFFFFF5C -:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 -:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 -:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 -:10707000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 -:10708000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 -:10709000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -:1070A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -:1070B000FFFFFFFF00000000000028AD00002918BE -:1070C0000000291900000005000000070000FF0073 -:1070D0000FFFFFFF0000FF000FFFFFFF000000FF9A -:1070E0000000FF000000FF000FFFFFFF0000FF0097 -:1070F0000FFFFFFF000000FF0000FF000000FF0087 -:107100000FFFFFFF0000FF000FFFFFFF000000FF69 -:107110000000FF000000FF000FFFFFFF0000FF0066 -:107120000FFFFFFF000000FF0000FF000000FF0056 -:107130000FFFFFFF0000FF000FFFFFFF000000FF39 -:107140000000FF000000FF000FFFFFFF0000FF0036 -:107150000FFFFFFF000000FF0000FF000000FF0026 -:107160000FFFFFFF0000FF000FFFFFFF000000FF09 -:107170000000FF000000FF000FFFFFFF0000FF0006 -:107180000FFFFFFF000000FF0000FF000000FF00F6 -:107190000FFFFFFF0000FF000FFFFFFF000000FFD9 -:1071A0000000FF000000FF000FFFFFFF0000FF00D6 -:1071B0000FFFFFFF000000FF0000FF000000FF00C6 -:1071C0000FFFFFFF0000FF000FFFFFFF000000FFA9 -:1071D0000000FF000000FF000FFFFFFF0000FF00A6 -:1071E0000FFFFFFF000000FF0000FF000000FF0096 -:1071F0000FFFFFFF0000FF000FFFFFFF000000FF79 -:107200000000FF000000FF000FFFFFFF0000FF0075 -:107210000FFFFFFF000000FF0000FF000000FF0065 -:107220000FFFFFFF0000FF000FFFFFFF000000FF48 -:107230000000FF000000FF000FFFFFFF0000FF0045 -:107240000FFFFFFF000000FF0000FF000000FF0035 -:107250000FFFFFFF0000FF000FFFFFFF000000FF18 -:107260000000FF000000FF000FFFFFFF0000FF0015 -:107270000FFFFFFF000000FF0000FF000000FF0005 -:107280000FFFFFFF0000FF000FFFFFFF000000FFE8 -:107290000000FF000000FF000FFFFFFF0000FF00E5 -:1072A0000FFFFFFF000000FF0000FF000000FF00D5 -:1072B0000FFFFFFF0000FF000FFFFFFF000000FFB8 -:1072C0000000FF000000FF000FFFFFFF0000FF00B5 -:1072D0000FFFFFFF000000FF0000FF000000FF00A5 -:1072E0000FFFFFFF0000FF000FFFFFFF000000FF88 -:1072F0000000FF000000FF000FFFFFFF0000FF0085 -:107300000FFFFFFF000000FF0000FF000000FF0074 -:107310000FFFFFFF0000FF000FFFFFFF000000FF57 -:107320000000FF000000FF000FFFFFFF0000FF0054 -:107330000FFFFFFF000000FF0000FF000000FF0044 -:107340000FFFFFFF0000FF000FFFFFFF000000FF27 -:107350000000FF000000FF000FFFFFFF0000FF0024 -:107360000FFFFFFF000000FF0000FF000000FF0014 -:107370000FFFFFFF0000FF000FFFFFFF000000FFF7 -:107380000000FF000000FF000FFFFFFF0000FF00F4 -:107390000FFFFFFF000000FF0000FF000000FF00E4 -:1073A0000FFFFFFF0000FF000FFFFFFF000000FFC7 -:1073B0000000FF000000FF000FFFFFFF0000FF00C4 -:1073C0000FFFFFFF000000FF0000FF000000FF00B4 -:1073D0000FFFFFFF0000FF000FFFFFFF000000FF97 -:1073E0000000FF000000FF000FFFFFFF0000FF0094 -:1073F0000FFFFFFF000000FF0000FF000000FF0084 -:107400000FFFFFFF0000FF000FFFFFFF000000FF66 -:107410000000FF000000FF000FFFFFFF0000FF0063 -:107420000FFFFFFF000000FF0000FF000000FF0053 -:107430000FFFFFFF0000FF000FFFFFFF000000FF36 -:107440000000FF000000FF000FFFFFFF0000FF0033 -:107450000FFFFFFF000000FF0000FF000000FF0023 -:107460000FFFFFFF0000FF000FFFFFFF000000FF06 -:107470000000FF000000FF000FFFFFFF0000FF0003 -:107480000FFFFFFF000000FF0000FF000000FF00F3 -:107490000FFFFFFF0000FF000FFFFFFF000000FFD6 -:1074A0000000FF000000FF000FFFFFFF0000FF00D3 -:1074B0000FFFFFFF000000FF0000FF000000FF00C3 -:1074C0000FFFFFFF0000FF000FFFFFFF000000FFA6 -:1074D0000000FF000000FF000FFFFFFF0000FF00A3 -:1074E0000FFFFFFF000000FF0000FF000000FF0093 -:1074F0000FFFFFFF0000FF000FFFFFFF000000FF76 -:107500000000FF000000FF000FFFFFFF0000FF0072 -:107510000FFFFFFF000000FF0000FF000000FF0062 -:107520000FFFFFFF0000FF000FFFFFFF000000FF45 -:107530000000FF000000FF000FFFFFFF0000FF0042 -:107540000FFFFFFF000000FF0000FF000000FF0032 -:107550000FFFFFFF0000FF000FFFFFFF000000FF15 -:107560000000FF000000FF000FFFFFFF0000FF0012 -:107570000FFFFFFF000000FF0000FF000000FF0002 -:107580000FFFFFFF0000FF000FFFFFFF000000FFE5 -:107590000000FF000000FF000FFFFFFF0000FF00E2 -:1075A0000FFFFFFF000000FF0000FF000000FF00D2 -:1075B0000FFFFFFF0000FF000FFFFFFF000000FFB5 -:1075C0000000FF000000FF000FFFFFFF0000FF00B2 -:1075D0000FFFFFFF000000FF0000FF000000FF00A2 -:1075E0000FFFFFFF0000FF000FFFFFFF000000FF85 -:1075F0000000FF000000FF000FFFFFFF0000FF0082 -:107600000FFFFFFF000000FF0000FF000000FF0071 -:107610000FFFFFFF0000FF000FFFFFFF000000FF54 -:107620000000FF000000FF000FFFFFFF0000FF0051 -:107630000FFFFFFF000000FF0000FF000000FF0041 -:107640000FFFFFFF0000FF000FFFFFFF000000FF24 -:107650000000FF000000FF000FFFFFFF0000FF0021 -:107660000FFFFFFF000000FF0000FF000000FF0011 -:107670000FFFFFFF0000FF000FFFFFFF000000FFF4 -:107680000000FF000000FF000FFFFFFF0000FF00F1 -:107690000FFFFFFF000000FF0000FF000000FF00E1 -:1076A0000FFFFFFF0000FF000FFFFFFF000000FFC4 -:1076B0000000FF000000FF000FFFFFFF0000FF00C1 -:1076C0000FFFFFFF000000FF0000FF000000FF00B1 -:1076D0000FFFFFFF0000FF000FFFFFFF000000FF94 -:1076E0000000FF000000FF000FFFFFFF0000FF0091 -:1076F0000FFFFFFF000000FF0000FF000000FF0081 -:107700000FFFFFFF0000FF000FFFFFFF000000FF63 -:107710000000FF000000FF000FFFFFFF0000FF0060 -:107720000FFFFFFF000000FF0000FF000000FF0050 -:107730000FFFFFFF0000FF000FFFFFFF000000FF33 -:107740000000FF000000FF000FFFFFFF0000FF0030 -:107750000FFFFFFF000000FF0000FF000000FF0020 -:107760000FFFFFFF0000FF000FFFFFFF000000FF03 -:107770000000FF000000FF000FFFFFFF0000FF0000 -:107780000FFFFFFF000000FF0000FF000000FF00F0 -:107790000FFFFFFF0000FF000FFFFFFF000000FFD3 -:1077A0000000FF000000FF000FFFFFFF0000FF00D0 -:1077B0000FFFFFFF000000FF0000FF000000FF00C0 -:1077C0000FFFFFFF0000FF000FFFFFFF000000FFA3 -:1077D0000000FF000000FF000FFFFFFF0000FF00A0 -:1077E0000FFFFFFF000000FF0000FF000000FF0090 -:1077F0000FFFFFFF0000FF000FFFFFFF000000FF73 -:107800000000FF000000FF000FFFFFFF0000FF006F -:107810000FFFFFFF000000FF0000FF000000FF005F -:107820000FFFFFFF0000FF000FFFFFFF000000FF42 -:107830000000FF000000FF000FFFFFFF0000FF003F -:107840000FFFFFFF000000FF0000FF000000FF002F -:107850000FFFFFFF0000FF000FFFFFFF000000FF12 -:107860000000FF000000FF000FFFFFFF0000FF000F -:107870000FFFFFFF000000FF0000FF000000FF00FF -:107880000FFFFFFF0000FF000FFFFFFF000000FFE2 -:107890000000FF000000FF000FFFFFFF0000FF00DF -:1078A0000FFFFFFF000000FF0000FF000000FF00CF -:1078B0000FFFFFFF0000FF000FFFFFFF000000FFB2 -:1078C0000000FF000000FF000FFFFFFF0000FF00AF -:1078D0000FFFFFFF000000FF0000FF000000FF009F -:1078E0000FFFFFFF0000FF000FFFFFFF000000FF82 -:1078F0000000FF000000FF000FFFFFFF0000FF007F -:107900000FFFFFFF000000FF0000FF000000FF006E -:107910000FFFFFFF0000FF000FFFFFFF000000FF51 -:107920000000FF000000FF000FFFFFFF0000FF004E -:107930000FFFFFFF000000FF0000FF000000FF003E -:107940000FFFFFFF0000FF000FFFFFFF000000FF21 -:107950000000FF000000FF000FFFFFFF0000FF001E -:107960000FFFFFFF000000FF0000FF000000FF000E -:107970000FFFFFFF0000FF000FFFFFFF000000FFF1 -:107980000000FF000000FF000FFFFFFF0000FF00EE -:107990000FFFFFFF000000FF0000FF000000FF00DE -:1079A0000FFFFFFF0000FF000FFFFFFF000000FFC1 -:1079B0000000FF000000FF000FFFFFFF0000FF00BE -:1079C0000FFFFFFF000000FF0000FF000000FF00AE -:1079D0000FFFFFFF0000FF000FFFFFFF000000FF91 -:1079E0000000FF000000FF000FFFFFFF0000FF008E -:1079F0000FFFFFFF000000FF0000FF000000FF007E -:107A00000FFFFFFF0000FF000FFFFFFF000000FF60 -:107A10000000FF000000FF000FFFFFFF0000FF005D -:107A20000FFFFFFF000000FF0000FF000000FF004D -:107A30000FFFFFFF0000FF000FFFFFFF000000FF30 -:107A40000000FF000000FF000FFFFFFF0000FF002D -:107A50000FFFFFFF000000FF0000FF000000FF001D -:107A60000FFFFFFF0000FF000FFFFFFF000000FF00 -:107A70000000FF000000FF000FFFFFFF0000FF00FD -:107A80000FFFFFFF000000FF0000FF000000FF00ED -:107A90000FFFFFFF0000FF000FFFFFFF000000FFD0 -:107AA0000000FF000000FF000FFFFFFF0000FF00CD -:107AB0000FFFFFFF000000FF0000FF000000FF00BD -:107AC0000FFFFFFF0000FF000FFFFFFF000000FFA0 -:107AD0000000FF000000FF000FFFFFFF0000FF009D -:107AE0000FFFFFFF000000FF0000FF000000FF008D -:107AF0000FFFFFFF0000FF000FFFFFFF000000FF70 -:107B00000000FF000000FF000FFFFFFF0000FF006C -:107B10000FFFFFFF000000FF0000FF000000FF005C -:107B20000FFFFFFF0000FF000FFFFFFF000000FF3F -:107B30000000FF000000FF000FFFFFFF0000FF003C -:107B40000FFFFFFF000000FF0000FF000000FF002C -:107B50000FFFFFFF0000FF000FFFFFFF000000FF0F -:107B60000000FF000000FF000FFFFFFF0000FF000C -:107B70000FFFFFFF000000FF0000FF000000FF00FC -:107B80000FFFFFFF0000FF000FFFFFFF000000FFDF -:107B90000000FF000000FF000FFFFFFF0000FF00DC -:107BA0000FFFFFFF000000FF0000FF000000FF00CC -:107BB0000FFFFFFF0000FF000FFFFFFF000000FFAF -:107BC0000000FF000000FF000FFFFFFF0000FF00AC -:107BD0000FFFFFFF000000FF0000FF000000FF009C -:107BE0000FFFFFFF0000FF000FFFFFFF000000FF7F -:107BF0000000FF000000FF000FFFFFFF0000FF007C -:107C00000FFFFFFF000000FF0000FF000000FF006B -:107C10000FFFFFFF0000FF000FFFFFFF000000FF4E -:107C20000000FF000000FF000FFFFFFF0000FF004B -:107C30000FFFFFFF000000FF0000FF000000FF003B -:107C40000FFFFFFF0000FF000FFFFFFF000000FF1E -:107C50000000FF000000FF000FFFFFFF0000FF001B -:107C60000FFFFFFF000000FF0000FF000000FF000B -:107C70000FFFFFFF0000FF000FFFFFFF000000FFEE -:107C80000000FF000000FF000FFFFFFF0000FF00EB -:107C90000FFFFFFF000000FF0000FF000000FF00DB -:107CA0000FFFFFFF0000FF000FFFFFFF000000FFBE -:107CB0000000FF000000FF000FFFFFFF0000FF00BB -:107CC0000FFFFFFF000000FF0000FF000000FF00AB -:107CD0000FFFFFFF0000FF000FFFFFFF000000FF8E -:107CE0000000FF000000FF000FFFFFFF0000FF008B -:107CF0000FFFFFFF000000FF0000FF000000FF007B -:107D00000FFFFFFF0000FF000FFFFFFF000000FF5D -:107D10000000FF000000FF000FFFFFFF0000FF005A -:107D20000FFFFFFF000000FF0000FF000000FF004A -:107D30000FFFFFFF0000FF000FFFFFFF000000FF2D -:107D40000000FF000000FF000FFFFFFF0000FF002A -:107D50000FFFFFFF000000FF0000FF000000FF001A -:107D60000FFFFFFF0000FF000FFFFFFF000000FFFD -:107D70000000FF000000FF000FFFFFFF0000FF00FA -:107D80000FFFFFFF000000FF0000FF0000001000D9 -:107D900000002080000031000000418000005200FF -:107DA00000006280000073000000838000009400E7 -:107DB0000000A4800000B5000000C5800000D600CF -:107DC0000000E6800000F7000001078000011800B5 -:107DD00000012880000139000001498000015A009B -:107DE00000016A8000017B0000018B8000019C0083 -:107DF0000001AC800001BD000001CD800001DE006B -:107E00000001EE800001FF0000000F8000007FF8FD -:107E100000007FF8000005F60000350010000000AB -:107E2000000028AD000029180000291900000005F5 -:107E3000000000060001000100090206CCCCCCC9FC -:107E40007058103C0000FF00000000000000FF0020 -:107E5000000000000000FF00000000000000FF0024 -:107E6000000000000000FF00000000000000FF0014 -:107E7000000000000000FF00000000000000FF0004 -:107E8000000000000000FF00000000000000FF00F4 -:107E9000000000000000FF00000000000000FF00E4 -:107EA000000000000000FF00000000000000FF00D4 -:107EB000000000000000FF00000000000000FF00C4 -:107EC000000000000000FF00000000000000FF00B4 -:107ED000000000000000FF00000000000000FF00A4 -:107EE000000000000000FF00000000000000FF0094 -:107EF000000000000000FF00000000000000FF0084 -:107F0000000000000000FF00000000000000FF0073 -:107F1000000000000000FF00000000000000FF0063 -:107F2000000000000000FF00000000000000FF0053 -:107F3000000000000000FF00000000000000FF0043 -:107F4000000000000000FF00000000000000FF0033 -:107F5000000000000000FF00000000000000FF0023 -:107F6000000000000000FF00000000000000FF0013 -:107F7000000000000000FF00000000000000FF0003 -:107F8000000000000000FF00000000000000FF00F3 -:107F9000000000000000FF00000000000000FF00E3 -:107FA000000000000000FF00000000000000FF00D3 -:107FB000000000000000FF00000000000000FF00C3 -:107FC000000000000000FF00000000000000FF00B3 -:107FD000000000000000FF00000000000000FF00A3 -:107FE000000000000000FF00000000000000FF0093 -:107FF000000000000000FF00000000000000FF0083 -:10800000000000000000FF00000000000000FF0072 -:10801000000000000000FF00000000000000FF0062 -:10802000000000000000FF00000000000000FF0052 -:10803000000000000000FF00000000000000FF0042 -:10804000000000000000FF00000000000000FF0032 -:10805000000000000000FF00000000000000FF0022 -:10806000000000000000FF00000000000000FF0012 -:10807000000000000000FF00000000000000FF0002 -:108080000000000000000001CCCC0201CCCCCCCC24 -:10809000CCCC0201CCCCCCCCCCCC0201CCCCCCCC4A -:1080A000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3A -:1080B000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2A -:1080C000CCCC0201CCCCCCCC00000000FFFFFFFFE9 -:1080D000030303031342020250505020706080508B -:1080E0000200020006040604000E0000011600D67D -:1080F000002625A0002625A0002625A0002625A0D4 -:1081000000720000012300F3002625A0002625A010 -:10811000002625A0002625A00000FFFF000000008B -:108120000000FFFF000000000000FFFF0000000053 -:108130000000FFFF000000000000FFFF0000000043 -:108140000000FFFF000000000000FFFF0000000033 -:108150000000FFFF000000000000FFFF0000000023 -:108160000000FFFF000000000000FFFF0000000013 -:108170000000FFFF000000000000FFFF0000000003 -:108180000000FFFF000000000000FFFF00000000F3 -:108190000000FFFF000000000000FFFF00000000E3 -:1081A0000000FFFF000000000000FFFF00000000D3 -:1081B0000000FFFF000000000000FFFF00000000C3 -:1081C0000000FFFF000000000000FFFF00000000B3 -:1081D0000000FFFF000000000000FFFF00000000A3 -:1081E0000000FFFF000000000000FFFF0000000093 -:1081F0000000FFFF000000000000FFFF0000000083 -:108200000000FFFF000000000000FFFF0000000072 -:108210000000FFFF000000000000FFFF0000000062 -:108220000000FFFF000000000000FFFF0000000052 -:108230000000FFFF000000000000FFFF0000000042 -:108240000000FFFF000000000000FFFF0000000032 -:108250000000FFFF000000000000FFFF0000000022 -:108260000000FFFF000000000000FFFF0000000012 -:108270000000FFFF000000000000FFFF0000000002 -:108280000000FFFF000000000000FFFF00000000F2 -:108290000000FFFF000000000000FFFF00000000E2 -:1082A0000000FFFF000000000000FFFF00000000D2 -:1082B0000000FFFF000000000000FFFF00000000C2 -:1082C0000000FFFF000000000000FFFF00000000B2 -:1082D0000000FFFF000000000000FFFF00000000A2 -:1082E0000000FFFF000000000000FFFF0000000092 -:1082F0000000FFFF000000000000FFFF0000000082 -:108300000000FFFF000000000000FFFF0000000071 -:108310000000FFFF00000000FFFFFFF3318FFFFFB1 -:108320000C30C30CC30C30C3CF3CF300F3CF3CF391 -:108330000000CF3CCDCDCDCDFFFFFFF130EFFFFFF3 -:108340000C30C30CC30C30C3CF3CF300F3CF3CF371 -:108350000001CF3CCDCDCDCDFFFFFFF6305FFFFF5D -:108360000C30C30CC30C30C3CF3CF300F3CF3CF351 -:108370000002CF3CCDCDCDCDFFFFF4061CBFFFFFEB -:108380000C30C305C30C30C3CF300014F3CF3CF323 -:108390000004CF3CCDCDCDCDFFFFFFF2304FFFFF2E -:1083A0000C30C30CC30C30C3CF3CF300F3CF3CF311 -:1083B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF22 -:1083C0000C30C30CC30C30C3CF3CF300F3CF3CF3F1 -:1083D0000010CF3CCDCDCDCDFFFFFFF731EFFFFF3C -:1083E0000C30C30CC30C30C3CF3CF300F3CF3CF3D1 -:1083F0000020CF3CCDCDCDCDFFFFFFF5302FFFFFCF -:108400000C30C30CC30C30C3CF3CF300F3CF3CF3B0 -:108410000040CF3CCDCDCDCDFFFFFFF3318FFFFF2F -:108420000C30C30CC30C30C3CF3CF300F3CF3CF390 -:108430000000CF3CCDCDCDCDFFFFFFF1310FFFFFD1 -:108440000C30C30CC30C30C3CF3CF300F3CF3CF370 -:108450000001CF3CCDCDCDCDFFFFFFF6305FFFFF5C -:108460000C30C30CC30C30C3CF3CF300F3CF3CF350 -:108470000002CF3CCDCDCDCDFFFFF4061CBFFFFFEA -:108480000C30C305C30C30C3CF300014F3CF3CF322 -:108490000004CF3CCDCDCDCDFFFFFFF2304FFFFF2D -:1084A0000C30C30CC30C30C3CF3CF300F3CF3CF310 -:1084B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF21 -:1084C0000C30C30CC30C30C3CF3CF300F3CF3CF3F0 -:1084D0000010CF3CCDCDCDCDFFFFFFF730EFFFFF3C -:1084E0000C30C30CC30C30C3CF3CF300F3CF3CF3D0 -:1084F0000020CF3CCDCDCDCDFFFFFFF5304FFFFFAE -:108500000C30C30CC30C30C3CF3CF300F3CF3CF3AF -:108510000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE3 -:108520000C30C30CC30C30C3CF3CF3CCF3CF3CF3C3 -:108530000000CF3CCDCDCDCDFFFFFFFF30CFFFFF03 -:108540000C30C30CC30C30C3CF3CF3CCF3CF3CF3A3 -:108550000001CF3CCDCDCDCDFFFFFFFF30CFFFFFE2 -:108560000C30C30CC30C30C3CF3CF3CCF3CF3CF383 -:108570000002CF3CCDCDCDCDFFFFFFFF30CFFFFFC1 -:108580000C30C30CC30C30C3CF3CF3CCF3CF3CF363 -:108590000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9F -:1085A0000C30C30CC30C30C3CF3CF3CCF3CF3CF343 -:1085B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF7B -:1085C0000C30C30CC30C30C3CF3CF3CCF3CF3CF323 -:1085D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF53 -:1085E0000C30C30CC30C30C3CF3CF3CCF3CF3CF303 -:1085F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF23 -:108600000C30C30CC30C30C3CF3CF3CCF3CF3CF3E2 -:108610000040CF3CCDCDCDCDFFFFFFF3320FFFFFAC -:108620000C30C30CC30C30C3CF3CF300F3CF3CF38E -:108630000000CF3CCDCDCDCDFFFFFFF1310FFFFFCF -:108640000C30C30CC30C30C3CF3CF300F3CF3CF36E -:108650000001CF3CCDCDCDCDFFFFFFF6305FFFFF5A -:108660000C30C30CC30C30C3CF3CF300F3CF3CF34E -:108670000002CF3CCDCDCDCDFFFFF4061CBFFFFFE8 -:108680000C30C305C30C30C3CF300014F3CF3CF320 -:108690000004CF3CCDCDCDCDFFFFFFF2304FFFFF2B -:1086A0000C30C30CC30C30C3CF3CF300F3CF3CF30E -:1086B0000008CF3CCDCDCDCDFFFFFF8A042FFFFFBB -:1086C0000C30C30CC30C30C3CF3CC000F3CF3CF321 -:1086D0000010CF3CCDCDCDCDFFFFFF9705CFFFFFE5 -:1086E0000C30C30CC30C30C3CF3CC000F3CF3CF301 -:1086F0000020CF3CCDCDCDCDFFFFFFF5310FFFFFEB -:108700000C30C30CC30C30C3CF3CF300F3CF3CF3AD -:108710000040CF3CCDCDCDCDFFFFFFF3320FFFFFAB -:108720000C30C30CC30C30C3CF3CF300F3CF3CF38D -:108730000000CF3CCDCDCDCDFFFFFFF1302FFFFFAF -:108740000C30C30CC30C30C3CF3CF300F3CF3CF36D -:108750000001CF3CCDCDCDCDFFFFFFF6305FFFFF59 -:108760000C30C30CC30C30C3CF3CF300F3CF3CF34D -:108770000002CF3CCDCDCDCDFFFFFF061CBFFFFFDC -:108780000C30C30CC30C30C3CF3CC014F3CF3CF34C -:108790000004CF3CCDCDCDCDFFFFFFF2304FFFFF2A -:1087A0000C30C30CC30C30C3CF3CF300F3CF3CF30D -:1087B0000008CF3CCDCDCDCDFFFFFFFA302FFFFF1E -:1087C0000C30C30CC30C30C3CF3CF300F3CF3CF3ED -:1087D0000010CF3CCDCDCDCDFFFFFFF731CFFFFF58 -:1087E0000C30C30CC30C30C3CF3CF300F3CF3CF3CD -:1087F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF21 -:108800000C30C30CC30C30C3CF3CF3CCF3CF3CF3E0 -:108810000040CF3CCDCDCDCDFFFFFFFF30CFFFFFE0 -:108820000C30C30CC30C30C3CF3CF3CCF3CF3CF3C0 -:108830000000CF3CCDCDCDCDFFFFFFFF30CFFFFF00 -:108840000C30C30CC30C30C3CF3CF3CCF3CF3CF3A0 -:108850000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDF -:108860000C30C30CC30C30C3CF3CF3CCF3CF3CF380 -:108870000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBE -:108880000C30C30CC30C30C3CF3CF3CCF3CF3CF360 -:108890000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9C -:1088A0000C30C30CC30C30C3CF3CF3CCF3CF3CF340 -:1088B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF78 -:1088C0000C30C30CC30C30C3CF3CF3CCF3CF3CF320 -:1088D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF50 -:1088E0000C30C30CC30C30C3CF3CF3CCF3CF3CF300 -:1088F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF20 -:108900000C30C30CC30C30C3CF3CF3CCF3CF3CF3DF -:108910000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDF -:108920000C30C30CC30C30C3CF3CF3CCF3CF3CF3BF -:108930000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFF -:108940000C30C30CC30C30C3CF3CF3CCF3CF3CF39F -:108950000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDE -:108960000C30C30CC30C30C3CF3CF3CCF3CF3CF37F -:108970000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBD -:108980000C30C30CC30C30C3CF3CF3CCF3CF3CF35F -:108990000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9B -:1089A0000C30C30CC30C30C3CF3CF3CCF3CF3CF33F -:1089B0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF77 -:1089C0000C30C30CC30C30C3CF3CF3CCF3CF3CF31F -:1089D0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4F -:1089E0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FF -:1089F0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1F -:108A00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DE -:108A10000040CF3CCDCDCDCDFFFFFFFF30CFFFFFDE -:108A20000C30C30CC30C30C3CF3CF3CCF3CF3CF3BE -:108A30000000CF3CCDCDCDCDFFFFFFFF30CFFFFFFE -:108A40000C30C30CC30C30C3CF3CF3CCF3CF3CF39E -:108A50000001CF3CCDCDCDCDFFFFFFFF30CFFFFFDD -:108A60000C30C30CC30C30C3CF3CF3CCF3CF3CF37E -:108A70000002CF3CCDCDCDCDFFFFFFFF30CFFFFFBC -:108A80000C30C30CC30C30C3CF3CF3CCF3CF3CF35E -:108A90000004CF3CCDCDCDCDFFFFFFFF30CFFFFF9A -:108AA0000C30C30CC30C30C3CF3CF3CCF3CF3CF33E -:108AB0000008CF3CCDCDCDCDFFFFFFFF30CFFFFF76 -:108AC0000C30C30CC30C30C3CF3CF3CCF3CF3CF31E -:108AD0000010CF3CCDCDCDCDFFFFFFFF30CFFFFF4E -:108AE0000C30C30CC30C30C3CF3CF3CCF3CF3CF3FE -:108AF0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF1E -:108B00000C30C30CC30C30C3CF3CF3CCF3CF3CF3DD -:108B10000040CF3CCDCDCDCD000C0000000700C003 -:108B200000028130000B8158000202100001023067 -:108B3000000F024000010330000C0000000800C0DC -:108B400000028140000B8168000202200001024007 -:108B500000070250000202C00010000000080100DF -:108B600000028180000B81A8000202600001828067 -:108B7000000E829800080380001000000001010030 -:108B80000002811000090138000201C8000101E85B -:108B9000000E01F8000002D8CCCCCCCCCCCCCCCC94 -:108BA000CCCCCCCCCCCCCCCC00002000CCCCCCCC15 -:108BB000CCCCCCCCCCCCCCCCCCCCCCCC0000200005 -:108BC000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCE5 -:108BD00004002000CCCCCCCCCCCCCCCCCCCCCCCCE1 -:108BE000CCCCCCCC4100200003030303034202029F -:108BF0005050502070608050131313131342121200 -:108C000050505020706080500301020000000000AE -:108C100000000000000000001F8B080000000000A2 -:108C2000000BFB51CFC0F0038A0F093230688A2055 -:108C3000F8C4E05C760686751C0C0C5BB849D3075B -:108C4000C32C0C0C0CDA4CE4E905E1FBBC0C0CAFBA -:108C50008098850F559C871342FF015AC0C7CAC030 -:108C6000A0C1865DFF3A35043B408581A11C88D9AF -:108C7000941818CC5411E2D2EA0C0C3380FC04A8EE -:108C8000D81D201DAB46BE9B47F1E0C1378D51F981 -:108C90005B0DA169012A7E0B4D7E1B54BE4A074223 -:108CA000DF36C66E6EB50E71F69FB546E5AFB4C63B -:108CB000AFFEAE3D2AFF209AFAAD503E00C5D55B0F -:108CC000A7D8030000000000000000000000000022 -:108CD0001F8B080000000000000BED7D7F7C14D589 -:108CE000B5F8999DD9D9D9CDEE6608096C20E02454 -:108CF000861AFB82DFE577A841878034B63CDF8A9D -:108D00005AD3D6F6BB506C551456BF3EE1F56933C5 -:108D1000F941122262049FDAD61F2B554BFB6C8956 -:108D2000942AAD3FDE024AF1F5C743AAD5D7A22F58 -:108D3000FE80AA455FC4D2D87E51DE3DE7DEC9CEB3 -:108D40004C76930DD01F7FBCF081E1CEDC1FE79EF7 -:108D500073EE39E79E73EE8DEA0BC2C7CE05388EEF -:108D60003FECD913028059D9A771F5BCAEBE99006A -:108D70004721D2D35D0AD0A68009AC6C1D88A41F00 -:108D800094007F6A14565E2D7F3CDE5D097067D1CA -:108D9000D7EEC3FA6B2C0502ECD9DD0C9039837D3C -:108DA0000F453743314011A4B6E277F6937890F53A -:108DB00037109C9C866876FC32F0D1B80015FAA179 -:108DC00022AA07C765F6CF81E47C18072083FDB38C -:108DD000067A593FCAF3721AC795E5C5FA8B55D979 -:108DE0007EBC4F595721A389FEF01FF9B2E26438C7 -:108DF0007FFD35072AB73E5D93AD7F06444A0FFDE0 -:108E00001DFB8F020AC123AF07C4C3D130A4E5CA3A -:108E1000FCFD0C341B5B9FF6231EBF509C989ABF31 -:108E20009E8DA7AE668D9E1DCD3A6402000C64B384 -:108E3000B7963DC3606EAE1DDA6E0148842FCDB08B -:108E4000089EF6B02F5D5489502701187EFD881FBB -:108E500009DF2FD1CC1CEDED279432FCD8F36578D7 -:108E60000C02EF0FD8FC1E64FD0571FC1CF8BA085B -:108E7000C72F63DFAB878E6FCD3CF1F1436702EC08 -:108E80000B23BE4D84017C7A0AE282DE9F9486E940 -:108E900047D05931783F23E1BDA8C6971D97FD0DF6 -:108EA0001A21179F0462256EBEF1F225E2A90CE992 -:108EB0006548AF4FC9F6AB22DD72E0EB4A81AFFEE9 -:108EC000F989A604C3C7DA66B05E73B4936360A67B -:108ED00073E069B568678FA794B27A39FA076811A9 -:108EE000EBC772D52F14BE9B4E10BE9BFF42F0DD28 -:108EF00026F89D49287AF6CF4F129CDEFE72AD2FE0 -:108F0000B68807CB21256DF990BF4B21FE207BF859 -:108F100035BECEECEFDF073FF5B303250E1BA74DA3 -:108F2000C0D73F9FCBBFB5D3D4F46689E4910BCEB5 -:108F300087517EB1769224F0A1F502F25FD1070A43 -:108F4000C05884CF844404605D7583369CFC015D09 -:108F5000F9539FCD775543F9EEE36C18842B14CE6B -:108F60008DA7EF0FCAD1CBACD7583F5A90BD3F1D4C -:108F7000FB2D8D55CC069C1DFDF8C577907CF271BC -:108F80005CB7C758BDD942CECAD43FC911A8009218 -:108F9000F7B2A84FE3B0FA01362D733A7BE2FB1A21 -:108FA000318E34B45F6FBB0128E1F811F0D8725DE7 -:108FB0008627A89F41789404E1CBFBDECFDEEBE16E -:108FC000937F7FB265BF9167BC1E89F869A4F6AF35 -:108FD000087E19C29F79E8BA5FAC33057A4D383DF7 -:108FE000CB47367F9D281F9D349FB0E1495FE4E168 -:108FF000130B52B46E5835AB7BDAE8F925079F6442 -:109000009CF5174B63F83C9438F10B834721BED590 -:10901000393C65D34BA93F09D7F819D88328231EBB -:10902000D87C97D9ED214EEB3584768EA33D9B1CE1 -:10903000C12BC99290FBBCDE0D629DCF6BA8E0F006 -:1090400083E8DF032FEB4F73F627438587CF39DCA7 -:109050001B242EDF58FD0CE1D33BBE2211BC322471 -:109060002C1F6BB7598CEF955FF673BBE86FBD048F -:109070004DBD61BE9E9638F4618324E484C6D799C1 -:10908000573EF991AF669C385F152AD7174BB9F553 -:109090000EB38A621746F2EB9D629FAD0F323141EB -:1090A000B751D1FD74A9C445F742E15D7682F04E17 -:1090B0001C0A6F417C76A6E41B959EBCE104E10B83 -:1090C0007AE03B557C3D43F059A1F0DBEB60B4F016 -:1090D000CB43F15BD03A9A3B4AF8369F207ECB7C5B -:1090E000B69D24E0CBB36EE7097A5BC0F9436176A5 -:1090F00038EE730A85EFD191E103F804FB6BBD6A8A -:10910000990AD96B0013009E6E79D5B2942C7C26F7 -:1091100070B93EDAF1F78C4C3F31FE5B96599D1DDC -:10912000FFF996B75CE32B8C7F90D90A1DF7854237 -:10913000E70DEFB9E6FDBAF49E6BDC13C5FBC18207 -:10914000C7FFA36BDEEF4B7F74CF3BCCE67D7AE1AC -:10915000E3FEFE04F9B152AC97064977E9817CF64B -:10916000FB0C41D7BBEDFA36BC79EA9F29E06A2FA8 -:10917000B0FE44D1FFE70AACDF2BFAEFC5FA652356 -:10918000D73F5DD44F15585FF2F175984F7FCE975A -:109190006CFC816BFFD1A6713F88D9A640F09CA1E1 -:1091A0007E13AB21F5ED3E467BAB35A0B79592DF44 -:1091B00084FC226B0012E837F92624EB7CAC1F6399 -:1091C000C74DF761BD238AA677EBC01724FB1E3C71 -:1091D00010D9DC5D991D6FB59C6C929097DAA2FA5C -:1091E00083E45F493549EC59668575F4DB0C5425F9 -:1091F0005A9696E23C0CDD62FDFCFA8A8B76627927 -:109200009326E9322BFFCB39736FFB0C6B35F0E102 -:10921000CE974EC37AD3C655B592BC3425C44F6998 -:109220005C35E5287B5E7C71561FE03F8B1D6566D3 -:10923000077CB6E9122EFFC5F7CF27DDE54B1A2FC5 -:1092400071B5BF34E1FE9E9D0FF07DC7B9DCFF30E4 -:109250005095FA2F0ED7C72A2DEE5FA0F9EA565483 -:10926000EF66F35CFFE1B5545EDF52ABB7B2F2E7F5 -:10927000AEF4B72C65CFB004BACC9652715CA5F9A8 -:10928000029BAF5AC7768FE73CDB35DBC8BFFF2AAE -:10929000363DF38C5F9C8593CDB3E9EADC70ABFA85 -:1092A000FB13DE60F6D2C0CEA089F084F7CAE9A035 -:1092B0004474DD3909E9621527397D40AA66CF2358 -:1092C0008D3AA07FA4A13169C8ACBC31A6C5030604 -:1092D000DAC9190DF11E411ACC65EFE3BE20DA633D -:1092E000AAFE07EA5F17DF7BE255E3D13FF2E3E630 -:1092F000351315B6DE77345BF47CB4B98B9EDB9BFB -:109300007B262ACC88DFD27C173DEDF9A12431ECF5 -:10931000F9C9B8AF365B91DF06FCCC34423CCEF7DE -:10932000D1FE7603CA113FCAE1745B14DFD7C1B422 -:109330006E40B9C4E5CBC6F8B6DDF87E633D4C435C -:10934000926D3437B745D93CAE2B87E9D8F7CE9725 -:109350001FE3DF2B607A8095773536905CED89FBD3 -:10936000D2814A82FF7CE4E79E461F3093078AEB56 -:10937000185C0EBC0662EEF2AE4626B066123ED215 -:1093800001293B7F852D33C4C746B32AE8DC57CF7C -:10939000DAE76E7F66DA5DDE88ED87F14BCDED733F -:1093A000D79FF392BBCC24DB2B837CC0F1F8AF3E7C -:1093B000260F76BF3CDE67E1BC4D3E4FF6E4FEC2B1 -:1093C000982F8DC6E716813F1BBF03112E5F3636DF -:1093D000733F603E78367EEAAAD8707E03B5B1232B -:1093E00081FE54B5B1270167E1332D9EBD09A79FCA -:1093F000D57EBE88C68FC35FD211DB58B2B4360BA0 -:109400008FB7FE785925793750C6BF77C45ED3979A -:10941000D63AFB93BCDFB5CBC3CEEFDCAF32506E98 -:109420007F3FA22D0DE7683F897DCF4197A532FF91 -:10943000FEF4CB81863B901F057E77BFFC13AD1AEF -:10944000F1FDBC0CC8671BF73590BC453E4379B1B4 -:109450008BF1455F2DD27FFD2BCE755B5CE72E3304 -:10946000BEE2FCC5FAC5A17E86F4601DFEBBF0CB52 -:10947000EE157ED93DCD317A3EDD6CD07357730D3C -:109480007DCF34C7A9FC54731D959F6836A9FCE3B2 -:10949000E6462AEF684E50F9D1E6267A6E6F4ED234 -:1094A000734BF315F464FC4BFCBCA13925FCC06B79 -:1094B0005CFCF0F7F1808BFF3E5DE32E9F6F9C918B -:1094C0005DD7ECEF2763EEF279FA275DE5059ABBED -:1094D0003C1FBEE2EAEFDC0FBEEC2ACFEBEF70D50B -:1094E0003FFB4D77796EDF439EF5E22ECFDAB7C7AB -:1094F000B31EDDE5E2BA43AEFE023177F97E1432E7 -:109500005C4E117F74C45A4B72F2CFE0F78DA12FDD -:10951000B9BECBD47E64FE59D65589FC93F6C52DD1 -:10952000943B26E7275BEE78F9C4A6DB48FC65C3CD -:10953000F197E6ABFFE5A7E1F9A9607EA85772F2C3 -:109540008397EE5EFE18226704BFFC2F1FFC6DF0B0 -:1095500001CC64C42ECFAF5773D877649F061240F6 -:10956000F69D1FED34477B75722A69E6D09F57F947 -:10957000E66F95593F8152E8C0786840C9E3E795A6 -:10958000F93E25A0F1EFC16A93ECB26230A6CB633D -:1095900000AE796C5EF932F6FEE7421F765C089603 -:1095A000C4FA1B37414DE23EA6B8DABDDF7B46E682 -:1095B000FB18FBB9E9879126FC0EA5334798378F36 -:1095C000D7C8136737FDC660CF0B666F59CBDE86F1 -:1095D000AA9319F2019596927D9A0C19D4AF5997D6 -:1095E000B67CA518478338DA8972D884241B67AE05 -:1095F000CFFC05CE9BD947FF21CFCADA3D9BC4F3F0 -:1096000047621D5EE4337F29EA3D3F5C3D7BDC1110 -:10961000E905494BE2FEA9F8830C447F69DC653F0C -:10962000D9F353948499C8616FFC4EE04BD2E34D5B -:10963000DC0FA202CA877CF50FCAB6FFC972ED071C -:109640008BA13F23231C311E6F82631719174E1DF8 -:109650000A87AA2492380EC6AB37B371DAC77CC624 -:10966000483AC6F948E67E2A2966123CAACEE1515C -:1096700095B899C8C14703021EBB1F3B6E26C5FAA9 -:10968000A12F9C856F6D30D184FB256B8C4A786A45 -:109690008FB8EDAF190AEFA75A3CDBFDB9ED438057 -:1096A00056BE1F1E57A761FF6D750D1ADAD78C1DA8 -:1096B00068BFD21E5E523C9CBDBD5ED8BFDD280F88 -:1096C00003180FD785BC8AD1B33DBCAD11D7C1D12A -:1096D0005A8687CAFCFD44E2EEB86E514DC813C7E6 -:1096E0004D139C41A3C413EF9DE06AE71FA7F8EC5C -:1096F000B8364823C3DF21E0B7EB752A294DCF895F -:10970000273EBE5D0EC4DCF0FEF9F0C7DB17F97B27 -:10971000F55C709D2ABCE58BC3DA4F75AC9A4A7331 -:109720007F4ACCB90E3E2BF84B1DABA5483E69F9DC -:10973000BE8778FB7082FC5B5A38614055361EABA1 -:10974000E17A70E0E95AD1EED78A4FACCB540CFDE8 -:109750005C92916A427ED22AD83A9286B6B39F49E9 -:10976000D1BEF3C3FFF712AD93328DD68964B075C5 -:1097700094631C4931AF56D8F31DD9BC46C1F8CC0F -:10978000477232D77A5921E0D116270CAD8A427838 -:109790003CDFC303C73A85EB834336FC568AFC564D -:1097A00085C2BFA640F8ED7118FCED02FEB5C3C13D -:1097B000DF26E02901A3857C990697B300171ACE0E -:1097C000BC8B37C4F825424E314C11DDECEFFF2540 -:1097D000FA29743E1B059C23CDE78D2C3DEEC579FF -:1097E000B0F9DC87F3CA379F7B041C6F285CCF6815 -:1097F000898411AB22559F93AF9E1070F42B228E5B -:10980000665D3B2ABEFAD702E7F144962E8F09BA6D -:10981000EC186E1E8F8A79F4C830F70DF4339E2E43 -:10982000F40E2C71D1E5A8C04F4FC0A6CB752EBA4F -:10983000FC4ECCABD0F93C53209F1DCDD2E5393145 -:109840009FFDC3CDC751FF4551FF25519FFCE74701 -:10985000952B5AAD5AFC9E38A0CCCA8EC7EABDECF7 -:10986000AC776DFB2CBBDEABC80F5223D783ACDECD -:109870006BCE7A605DD08AF6DB5A8C897E02E081FD -:10988000F6AF3688766F52BBC583FDBF25D607B5C8 -:109890005BD73EBFD50A53BD77F07DCB828FEC7A84 -:1098A000EFBAE15D61C37184E04D0CC2F1BEB3DE7D -:1098B00013CAE7A9BF217947B19282EC1F7F699251 -:1098C000F2F74A20D283FEC50E2545FE640C36A071 -:1098D0001F7275204EA92A23F9A3CB2EE6ED7445FD -:1098E000237F6A005270177BBFA154A1F8C862257C -:1098F00019F1A31D21252D0AAE827E590BF63FD604 -:10990000A0FC2F1B9EDB8ABED845FD3078B0DF3B24 -:109910008BA23B91AF364E520DE4AB9D936E20BFB0 -:10992000F96D2D3C7FF0B6F355DA676D7A3942FA5E -:1099300077AD12FF2CD6B74CD5403FFAEAD0472F6F -:109940002D67E5BE96625D3A87E641705B3E48B49E -:10995000CD74E42332B80371CAA7233FDC6D8D3C7C -:10996000AEC37ECAB1FDEA0546BCDB40F1C5E418D2 -:10997000FBDE59A792FD7A5B45D57C1C6F539D4653 -:10998000F6C6A6C5552DE4C7AB0B91BFB2246C48F3 -:10999000E8678FCE519901CECAA5460BDA9B91D9C3 -:1099A0002140BF5349051F2F7206901FCA0F3D89E2 -:1099B0006AF68C76A990198BFD2DC97C09ED99BAB0 -:1099C00000F9E1D9C4F6D78EA39437FE23FF0C101B -:1099D0001EFF441910EF367DA33D83ED87CD638CC8 -:1099E000A60BAC9729AC5EA44B81CC8C02EAF51493 -:1099F000582F5D60BD0CAF17800B87CDE78338CF44 -:109A000023D4D81F9EC7E8C82BACE4F6BBD36EF1B5 -:109A10007BBE8F362FF42ABFC80B9D0373785EE898 -:109A2000F0EDED7CD091E60BE0CBC2298F5C7F6D31 -:109A3000F3F07E63FFB81B62987FD959F655F1BCED -:109A4000913FCBC5FBF2353194779DE5E27BF98DF3 -:109A50004DB9F6AF77FAB91CAE81C4B0742811F0D5 -:109A60001F62B0637E4F8DC2EA47F2D7574B7DC36A -:109A7000E6596A8AD540EB76B18FD66D008501AE86 -:109A80009B0ABE8EFD904A54F37855B4DCB17EFC3F -:109A9000F57B68FDFCA25C06A98EE813473C7AF9C9 -:109AA000C4CB170170942B4F9E4FB6FE99F8C4DFBC -:109AB0002517B47EFC3D05D64B17582F53583DB59E -:109AC0004B2A48AEA83D05D64B17582FC3EBAD9D8A -:109AD000AB727D0E7F68C578BFFF139AABBCF613DF -:109AE00021F7F7B3C3AE72C72C777B75B6BB7DC7C2 -:109AF0006C777B750E6F1FEC800518CF2F749D1C43 -:109B00003CC17552A30D5F3F5237C2BAD2F420B6A2 -:109B10002F510CC89492BE4A0BBD95331E7E9ACA33 -:109B2000D77F959FC7CF6F53F420EE23FFD6E72949 -:109B3000A93C9FC09EEF48F0DAF2F7B7B2B0B7F297 -:109B4000E47D438C9F7FF043288E768EB1506B78F6 -:109B500085E1D1FF2CCF7BF7F6FB8A9A9CA63AF6DB -:109B6000C5CC3E83A4C30F737E99C2F36D181DD07C -:109B70001E5221D158C9FA6BABF0913DA28447D057 -:109B80001B150EB995232F2FEB970213CF53D02718 -:109B90000360FE9B7CDC501C08EE08F4D166BA180A -:109BA00053E54E07180386C493BEE212CF13ACD719 -:109BB000519E95064F75BF9751BF92791B1C2F1A66 -:109BC00045BF4A1FE5CB9CF27E478037087753BFDD -:109BD0006C97547A7C6CB65F7F2C452F314F56764C -:109BE000E4CBE1B908CA37F1C53394DF30214AFB31 -:109BF000B2B5A5D7B9F2C1FF59AD72F98754BDE32B -:109C00005A09E3BA15579B7DC3F079331357E4F72C -:109C1000AC586EF6D5E4AF3798A78FF99E39D64188 -:109C2000879A4CA3FD6E4D0EF3FDBC92227F63A775 -:109C300054321DF32DEC7A4A0593B40CAEC84CD3C4 -:109C4000C2FD5EE7585F1CED5405D6EF93CE62ED82 -:109C5000E4C571A7FFD2FB542A94B79DF3B95D65A3 -:109C60007A12E1147AB26D047E1FD1EE51E3C95C21 -:109C70007ED16FAB7C5FEB0FE5FEDE176A78409D0F -:109C800035146F8F217E717F3B06BAA4FFC3D9873D -:109C9000F2A52AF6BC8478585BB62836DC7CD90657 -:109CA000EAF0205D18897F16321F4179300C1C3F85 -:109CB000CC0507840BF37FEB0BE3C48783F65229B3 -:109CC00088FD98199518DF870457DE32737306CF25 -:109CD00043F897864DA49F6C6E01F457DB76936C26 -:109CE000865EF5113DEBB9FD54C3ED2193FDC179BD -:109CF00044EB87B7AB654FF939D56D0FB535EF003C -:109D0000679E9BF75C85FD4C871A5ECC8D8FC2F6F3 -:109D1000C3B7337EC13CFB8DCD1A22057A9A752AD2 -:109D20006F688E51797DB341CFF6E61A7ADE8C4D9D -:109D3000E7E2F9A7545725C35B57EC81D8E5ACCAD5 -:109D4000ED283B288FEFDE05682F770F96D93690E8 -:109D5000C1DD3D09785E9F7AEB02DCE7770741F8C9 -:109D600015DA16A05D9D2DDFD1361FCBC2CF10EACC -:109D7000BC6F01EEF76F17F90FA098DA250EBD77CB -:109D80005AC04FFC477B576A6FB5617F414594E1EC -:109D90009105EE3298084F50E3E505816DD43F8977 -:109DA0000036DEA7033FE0E34D11F96DB54B46C029 -:109DB00023F7EF5BAAC1FD5DB525143F52E3717433 -:109DC000BFC2ED6304DC05F6034A92EB3B718E2FB4 -:109DD000FFBA1941AF093846A23F4307F9D1EDF365 -:109DE00069CA0BB9F5F4A91EF776FFE8F0A2D6F51B -:109DF0005B7886ED09353927C0DA47CCDE4C252B58 -:109E00004717672C5ABE058E3B3660E7392669FD39 -:109E1000DB7856746E77ACF0D0D15FCAE3754171D0 -:109E2000FEA4507893AA1847F4030F37940F67AF36 -:109E300095257C68840DCA8BB18D21E19CE1E531CB -:109E40006689AB5C5C37C1553F12AF727DF7EB1F83 -:109E5000777D3F513A5DE299C7A784DD6897CFF5DA -:109E6000CEB3C07E0F1627560570DD34404D8AE113 -:109E7000F5CE2F3C44F80F0DAED385ED6605E58396 -:109E80008B753D8F9775FB7B5DBB59CFCA86FD7D7A -:109E9000062F9BF6F738AF6FD9DFA7F2EF28F759F7 -:109EA000F96B9D67B45BF81D5AC96F0B152958E211 -:109EB000A0CFD8F10DAD08DFF8CBD2318BBDEFFECE -:109EC00050E6F2007A62CE7A776ADC0FFDCC943BE2 -:109ED00062E8AF5C77E64331207927E58C07FE3CEA -:109EE000C0F3C5CA42899E00AD77B3BF98F1E1A126 -:109EF000876483EB21E535D4873E8BE7E3AB10DF46 -:109F000067A25D54C3FDD521F19DE85899AD3F4846 -:109F1000574FF9EF34AED77F87491B0CCEEF159B17 -:109F2000F7D0B890961AD97AAFB0A01FCF1F81B0E2 -:109F3000FB26F2A6509A48939F6F12C3A7CCBE4F40 -:109F4000BEB8BFC5CF706D5CA6FB7089542D8FFB6A -:109F500048C00DDA9163A5E3ECF93DA417CAE39B71 -:109F60005280FA7BED990F35215E02997F0283E1E1 -:109F7000ED1F27A5C040FF6F80C315B8AC07483E52 -:109F800057F7109EBDF85A3788F7B40BEF3F0970AA -:109F90007F7E2CC9DB0DD65358BDA943EB75077BDB -:109FA000E6AB68BF4DE178F48EF35E4012E776DDF4 -:109FB00070D8FD7AEBDF1210716D2D4DF18D67CEEB -:109FC000BC21867EEDCE298CFEB5F9E97F4B80E77A -:109FD0005B19C76E22B9DB3D6923C533D7556F26A0 -:109FE0007BF228B323F0FC747765EEF69DCD3C3F01 -:109FF000E65CB8BBB18AD1A7F37999FCB4DE7ADF0D -:10A000000954B9E28D5A857B3FC8F8AF0FE5E8489F -:10A01000FC27471EE0EB72947C8766213FCF50D629 -:10A020008EF6805F94EF0E1C6F13FA9FE47FF9F2B7 -:10A030001E70E64BBE2FF82213E0722658C1F9A31A -:10A04000DB6F494EFAC5D8FBF98E76F9E8968F1F7B -:10A050001E17EBE17D25DE44CA5F49E9B9E4B3127E -:10A06000FBF42F173ACE7BB52B694D47F86B364A78 -:10A070004EBBF61B6632A439F627A1D805BF5C8813 -:10A08000FB1F259E739FFE29D38C6A6CFC9B9B61F2 -:10A0900046359E4B50AC00D6BB59C934D2BEA2DA6D -:10A0A00047FEF27515D7EDC53C2BABD617C76A6DC9 -:10A0B00015BB1AAB0CE4976D9467FAA6BE2486FD17 -:10A0C0000462EA8CEAB194DF9DC079876B59BF0EB8 -:10A0D0007ADBE3DE2DF8F65BBA3959E3F2E034EDD2 -:10A0E0002F200FDE87788C1B590CCF39F65743F1A0 -:10A0F000CCF3043A2B86E0798EE6E0EB00E27906B9 -:10A10000C9FB9CFE0B86E7B35D780686E7A9593C40 -:10A110007757703C77D66CEEAA72E2B966D7DE4A02 -:10A1200003C7E7787E48E3E773438867079C5E3C94 -:10A1300087255BFF7CAC1DF9D6CBF70CEF7F8FF04A -:10A14000D8EF3F0AFC82ECE1B1E313176AE43F4920 -:10A15000D1FEE94E29AF5EBA442B402F758A757443 -:10A16000A7C03FEBFF0BD47FA9E8DFD6B7421FFEA5 -:10A1700083F66F0B501FB27ACBA89E9EA27DF06033 -:10A180003D0B86D5A3ACDD95C447614FFF268C4AB5 -:10A190001FB37EAEA37E34CFF8069C949E67FDDE8F -:10A1A00044FD2A9E7E4FB13DC1C6E926FC81070FC2 -:10A1B0007F663B2696F4F083D2E3927B363F942F62 -:10A1C00077D7CBAFD77AB85E1B6AD710DFFEBC73E8 -:10A1D000CF6EDC27BDA99BDF46BC8E761DD876608E -:10A1E0005928B94DE376209D83B0BE51946E636DBE -:10A1F00095E33D511E7F77EBA3F1B63D54CDF5407D -:10A2000070947A699FB0D73AC6301955CC9EFE44F7 -:10A21000532E3FC3339A9DB7E6B69B7F8373243F8B -:10A220005182FC6BEDB1CFECE863B4331B7B20971C -:10A230009C4F86923FC7F9A9BA65927A15FE917C28 -:10A24000FD9626AC9D7B6792DCEDC7BC461072186C -:10A250004D6BF4C74519DE0E69E4C288A37FADECEF -:10A26000626B3ECAB10AC62F587F5CD33E29992B38 -:10A270003E6EEF7F10881CFB97719F9B9DA47CB85E -:10A28000C53347D8DFB4D8F6EB6F715E87D49E0B29 -:10A29000A638F06ED3E90E2971E179284FE7713ABB -:10A2A000158F924E03824EB098E7A19E7BEC5C8D99 -:10A2B000FC8B115F02FDF0417F8F5EE2E0A3713EF7 -:10A2C00048F68E02FE7AE8DF7D1CF77F611FED778E -:10A2D000BBC3CBBE83F7EF58BA1A9F6264C7ED6663 -:10A2E000FABEC4A17FBCFEAAC17DF4E2C2F265A79A -:10A2F000587328DE9FBD3FC89D7FC018AB06F3860C -:10A3000056CBDC7F7E67D1D7280F618D15D003A592 -:10A31000A4C7C8FE5B27F2D93A453EDB5A91CFE687 -:10A32000B7566FC5FA9B0012E8976C9997A2787F91 -:10A3300054D1F4D638C2919A837A225A6AAFCF1F89 -:10A340002FC4F53958B6BED1DEC0E61B8DD9E58DD8 -:10A3500064BFB5B77079F3D9E00B0BAD7A64C53E35 -:10A36000A2C7A6BA25C5308C3F325CEBCE9F0B55F9 -:10A37000875C65ADA2C455564B270C1BB7F819FA7C -:10A380008966E17CFA208E70E6C9179E12E476B6E3 -:10A390002C4FEBCF60BEC1D96A7CB381E7A8DD79D1 -:10A3A0009CED416E0F3E8A0E218AE30ABEA8E3713E -:10A3B000D5A2B955BD180782319C2F304FD0C90F97 -:10A3C000F9F8E2AF8D1F5FD1E118E65DDCD21A0526 -:10A3D000CC73B965EEAFE21903E56A5F0CF333DACB -:10A3E00098246965DF37CCFD9591CB9F7C404B2E3F -:10A3F0000F22FEC209B2BF223393F4FC6BCF6B2451 -:10A400007ADE19E47A6E8AA0A782F49C99A5E7BA4D -:10A410003A46CF99D975BE4EE9D10AA1E7F9387EFF -:10A4200019CAA1FFA67DDBCD75BE46944306F45242 -:10A43000FEED865A9F0FFBFF6BE1C5862B3C97C94B -:10A4400047A25326817A61435CF1A11CF99BE3C3C7 -:10A450008FFAE87D017CF8C35C7CB85CD0432EDACF -:10A46000D7942BEF6E4A5072E1653DD28BE3A591F4 -:10A47000E3C5F757C1CBA0BED0922B916FAE88A990 -:10A48000B4EF564ABA3A285EC4F41EC61B56C8A694 -:10A4900081F126F8969FDFC7847ADBA15FFE180C56 -:10A4A00072FB445EBF88E2186C6AB82F63E58F0DBB -:10A4B0001B0F4DFBFB9DF79478F3325E0BBAE31054 -:10A4C000472A961423BDF2F5F776F35E1DCFD5DA51 -:10A4D000F919DEEF2B6448E53AB72885346167F651 -:10A4E000AA84871B99AE9D86F8F8D8423C9FD9591B -:10A4F000D13A8EEC1871AE61C5966775C501E70A51 -:10A5000085A9BFE943E763E37705AAC91247FBF4CE -:10A510005E577B6FBBC1FE447B66B7F9430C3E536D -:10A5200049EDC578B37D7E43DD323F436A330FDCAE -:10A530008C8E270577A1E7388E3CD0D681FB6DB491 -:10A54000BF3EC1F8E4B78FC8F156F6F58ABBCF58C5 -:10A5500088E75A0F01E7179B3E6F3DD0362E175FF5 -:10A56000E4A3CF79A12087E714F3D759210F7FF512 -:10A570005E549C8153CF5F8BF3F197C0CFE15E8E29 -:10A580000FB86B6C4E3AE59BCF209DEC7682CFBC2A -:10A59000EDF3B5637C95E07C95899E5D085F097855 -:10A5A0006DFA9D2CBC23F155608D6CE079AE4A2587 -:10A5B0004172B3B3F43A4BDCEB48F99E72CFB48CE2 -:10A5C000B8D74AE4B54306ED8940A949767448DC1A -:10A5D000CFA355BBE5A612739F9B8835253276BF66 -:10A5E000E8BF0CAC5169DCC1F8711832C12896790A -:10A5F0009C14C51FEE2B02F04DF27BB27639FD9E06 -:10A60000F65311F96A98CB4BF7B2C1E747C86F719F -:10A610008F13BB78F8FC1A6F7D082BC62107DEF379 -:10A62000B753E090639FB341DC2B6AE3DFDCB29465 -:10A63000F2CA83E08BD3FE20D661E1BEAF43ACE724 -:10A640004E7CCEC573BCD375DAAF55F0788B257DC3 -:10A6500099FC0CF6B9337B3CFBBC995D6F24FAAFD7 -:10A66000C6F594637DEF0A717D3AF0B5D47FE33E81 -:10A67000C4FA1318780FC5E3CD1F509CFA9CCC5B2D -:10A6800032FAF79F098DA37ECEE9EF931738D6E50E -:10A6900039E21C0740AF9CEB9C97DF0AEC427E78C6 -:10A6A000EA30DF8F3D75F808D9E14FFDDE9746BEF1 -:10A6B0007BEA83E1F31E1E17FB22BBDEE3BFE7F656 -:10A6C000D9E34A6F512EFB2E3B7E9AEF070FBBF961 -:10A6D00015945E19F965E0A67D32FA071E6FD6A4BF -:10A6E000D799FC9927E679CEE13E19F74D23CD6B3A -:10A6F000AB87BEF63CB7D6737B746BFD9110FAFF47 -:10A70000B73EC1E77BB49E9F8FCD07EFAE669EDF5D -:10A71000B1F589DCF86898C7F7C70D7EA334A75D4B -:10A72000EB3967B54093DDE7BB4E317CBBEBB9DD60 -:10A73000B55B89874F049EBCEBBBAEA711DD08510A -:10A740004836CE9708BDFB5D7E92035F6FF932E617 -:10A750006B2C0D9B12EE65A12FF3249B5789A92525 -:10A76000F0DE98E2FA1E6932E677C4781EF937AF58 -:10A770007E2DF3322BDFDC5444655D379E5B84F81D -:10A7800028D5C99F72337A5C48407F732DE627D065 -:10A790007A64E5C0CD3DE7A13F4B012E2F98C56BF4 -:10A7A00028E3E85E3F72D2E4931BEC473A1EC8B63A -:10A7B000CB3B4F4FDE6D00960C2FC796F3FA16FB7E -:10A7C0008372A8C49367A22F74E7A5443DFD4F454B -:10A7D0005BB5AC80BCF2931C670C6CD30CDC67D708 -:10A7E000FAF434D607630CE60D861B9981C4E83968 -:10A7F000460709CDE591F0BE0EA091FBBF33E03CCA -:10A80000A7D350C4E5D584AB6E97709F7134CEB892 -:10A81000621A96DFCC997FD52EE4C76059DF45F2E6 -:10A82000B4037AF7525C20E9233BFCE6DAD631CE5A -:10A83000F64B8B24DB1F28E80F86323B4B7F363FDD -:10A840003378D65F8EFEB1E56EBC8F962ED714712D -:10A85000793512FD4F761C9B6E43D7478BA0DB03E7 -:10A860001417EDAE195EEE0FA5DB36D277E1DADC18 -:10A87000F9BAD715492E796C3F3548419CF1892C9E -:10A88000EE6796C7CF6EBA7F18F9233BEF67866CE9 -:10A890003FE38C1E13E356E3A1C7C473DF8CA7E329 -:10A8A0001940FE3601ED24661E111FC99EFDDC46CF -:10A8B000C14741789EDAB35560E9A45752A03BF2F4 -:10A8C00054CE93C371F45FACD3C3742F12CA4F9E9E -:10A8D000BFC3F3FC8B39480CBFFD80F22D542E838F -:10A8E000857EBF7A01AFC4F80EF3FB0FBC7500F78D -:10A8F0002BE1996E3A29078A28AF2DE43D2772E0B3 -:10A900009A6B687FE3A1E368F3FEBF5F24ECFF224C -:10A910000893DD24DAE7CBDFB3ED7E1BBFC6B108B9 -:10A92000E5ED741C90081F659313F7E3FE0C7E257C -:10A9300003CFCB0413F3F656FF74167D1F1A574846 -:10A9400054225DDE3A50A4B75616922F9948B6B0FD -:10A95000FAC68140BCD520D5E2D3908E7D12D1516C -:10A960001AA751BED6EA7FF7DF1F18265FCB8E3FAE -:10A970000E96158BE29B5DC674CD294FCA42C95F06 -:10A980001639E3F622AEEBF5AF07C3EDB16760F41D -:10A99000F18FD2F120E2F29F5F84F64B17AE019E59 -:10A9A0001747797A5DE5BCFC46D1944518DFE98A02 -:10A9B000F07271F8C8792D246713E4FF5BC3180E99 -:10A9C000F1087BFDE21E4963FC85C3C80BEFFCD791 -:10A9D0002BFB284FFE9EF0FEF3CF40FAC47DE48FA0 -:10A9E000BBE7FA6DAEFB93DED41BDE2FA2F5AAB750 -:10A9F000637C7A62D2CED774C74526A0D660F39B1B -:10AA0000C408E3677838ED626845B6A9BCACB71CEA -:10AA1000F7C96B4BB78DE1E7FD17EA87C86E972939 -:10AA20003E9D0F5EAF9D9E6FBE76BCDDDBFEAE0829 -:10AA3000BF47D51B17F3FA831E44FC9651FE2C60CA -:10AA4000FE6CA7BF2F673CEA8D22EED76CAF5894FF -:10AA5000B81CE7A598730F327CDC5B1AA57D90FFCC -:10AA6000A2DA4B7D0E7BC3CE6753C47ECE5F9A22A3 -:10AA7000B9A86866D719182F7A5EC61505153D3B2B -:10AA800025B4E7EDFB2010AD174FE5F3C579058040 -:10AA9000DBC5785EE1B863DE1073F8C1509E88FDB7 -:10AAA000DB29A0F7B4F0ACA1F49DDFC5F3D0635768 -:10AAB000F0F34D1395DCF41E7F99EEE3F1AF534BA9 -:10AAC000E77CEDF3C53DEF8AA8B47EA6E8ABF7E2DC -:10AAD0003D771D567112E33103FE5417CAAB0DFFCB -:10AAE000E883CD34FFD1E937454FD03D7A15297D34 -:10AAF0003A2EEF7CEDEE48ED0A129E2D9ECFE0FD42 -:10AB00007E7998EB9B9E94EF36FC6E3E9DDAE9C70A -:10AB10007D678CEFABED7D783294BC3CECB0CF75AB -:10AB2000D3223E9A92BC94E4C0405961F72F0CE2C4 -:10AB30002B4F1EF31D11AE97A718AB79BF9386F765 -:10AB4000CBDA78F9A04B16BF1721134438FC8C914F -:10AB500013B82E6EE472E2EE35BBE8BD7263DF7CA3 -:10AB6000FEBDBF05F5EA1D3EB82297DFA82DC2E362 -:10AB70004193CDCC3AD41B93533E40FBF4F688412D -:10AB8000EFC75FC6F1D43509E238EC69D81FFBCFB7 -:10AB90009E4A95F4D2D852A0FB92C6AE01D2DB6396 -:10ABA0006B206DB072D7CEB93BD1BE55AB218EAE06 -:10ABB000EBDD953758680F6CAA0013F5B8FF46B661 -:10ABC000C0587DD5F0A53150BC29B58CEE6959CB64 -:10ABD000D6255263ADD140F6C3D1182F072AF839D4 -:10ABE00098AE331582C3BE7F9CEC4EA61FFCB5FD0C -:10ABF000265EFD65C015D48F7F2EA7AB71573D9D96 -:10AC000053EB1AF310DD4B635D033CDE69C7A515FA -:10AC1000C65F6C9CF62BF49CFE9523A1E4B79DFCCB -:10AC2000C0F891E44C17E613E4C0676798E3F30EAD -:10AC300021E706FCF0298A97B4F8E83E176FFD6516 -:10AC400002FF775B4BFEE10C23AB6FECEF078B0C45 -:10AC5000977FA3E20395E6B348BE1174A43BB39378 -:10AC6000E8FE17BC18F4745A9617943BCEB3DC1B5D -:10AC7000EF85C98867DB2EAAE5F68C7DEE91E12190 -:10AC8000730FFBAED705E87ED1F14DB9ED23B5408A -:10AC9000FBA8ABC8FC6918F30D443EFFD7972F21E2 -:10ACA0007D9FEFDEDABB235CCEDF2559951D489FE3 -:10ACB00049FCFE196FBD83C25E64F620F1CD268B80 -:10ACC000DFBBB5896D7D1E45BEBA9EDFF3C7DEF3DF -:10ACD000730E06D079F1D80DCBB45CEBD51B57CEF3 -:10ACE000B7EE826A5F3257BCA556D0AD24AECFF71F -:10ACF000F1E983E9B0478B6A81EEFFD2197DD0F686 -:10AD0000AD805E4ABADFD858528971A15B6F540D8D -:10AD10007C7F5F65AFB510E72D41EF839823A3F4E7 -:10AD20009A781EBD223ECEE8769CF72EAE7894CE61 -:10AD3000C3DFFE54000275783FA9E7F7D938E9234D -:10AD400067E96CEBAB7CF32BF4790BC397F3F780DB -:10AD5000308833388F220B0CBA1FD9E8253BF4A872 -:10AD60001544DD0A467D2FD72BED2178308EF7CCA8 -:10AD7000F2F2A6F054C0FB6735A597EC754DAFA273 -:10AD8000725175A29BECF369DBF55CFAE153914AD1 -:10AD900097DF24E4895369C91B9AB89F56852939DE -:10ADA000D6D9C12285DBD3AC29C573ADE1E5EDC9A8 -:10ADB000F2C79B42DFE8D97D32F107C92E468F707A -:10ADC000C5A2B764C77D9C61EFF9622F3D3DE59355 -:10ADD000A5E73AA4A723BEA0D52735A49FC1EC249C -:10ADE000B2FBEB019CF7A66FD22C7E0F8361F82C8F -:10ADF000077ECB85DDA77CA0D079DBBB9676D0FE25 -:10AE0000632CEB03F37AD933E7BDD3078B785E78F5 -:10AE10005751624984F27281EE195E27E4C679F2D5 -:10AE2000CF8298871504A6E7908F16FBE0C11C74AB -:10AE30002D8F703CA743E6E722B3F2CFF77129F7D5 -:10AE40007DA276FB83C20F50B81CE6F39D620ED044 -:10AE500079D2819B0AD3DF036C6EFBD02E57E25C64 -:10AE60004FF719D03E93EE7F4AA3DEDD145B4278A4 -:10AE7000BF0FF529DA56B55C4FFA53DC4F0C864408 -:10AE8000F7CA86C4BD1BF7A58E3C8B76CFD11A05B9 -:10AE90003D3E10AC485AA85F8BABFB2C09F56C69A2 -:10AEA0009AE2C74C8F598867E3AE4504B75FE96DF6 -:10AEB000417D99562084FA7C008D4966C73D127EFB -:10AEC000A403F35DFCB5695064DCD70338EFF737B2 -:10AED000602FD9597EA687C96E52FA5A502EB5D71F -:10AEE000EB14D739EDC63E70EEEFD8B8B7E2B81321 -:10AEF0004AD97846567F7AED8D7C7606D3B3222FD9 -:10AF0000674107EEDF6829B1F2C3E1ED1D686F7E8E -:10AF10004B37BF4EFC93679FC1F8E29E48D9E8F9D2 -:10AF2000E2B9B09B2F06FD27C2EFBAAC4E087A30CB -:10AF30002EFD0D83FBCABD7EC0F99F7BECBE3DF7A5 -:10AF4000307CC8A84FC972E9D9F324FBBE1CFDB000 -:10AF5000AC7CE581A92ACABD5F4D90F1EC30F25975 -:10AF600014F9E71DF0917FE81DD81F9DE180676708 -:10AF700084AF13E8F2BFD6E7F03F5EDEC3CBB6FC8A -:10AF8000FBCA5DEEF29761C938B4BFBE7CBB1FD26D -:10AF900012FEDE29F7BEF99108CF37FF0AA43A1056 -:10AFA000CF6BC5F9A46B1E9BAAA2FD74E50CBD1264 -:10AFB000E39F361CCF0A3DFD36E363C3210FAF0A82 -:10AFC000A755CC977A7DFB8CCF9C0DD84FBA6302E6 -:10AFD000FA0FC7404E3DFEA52E379C23CDC30BB7BD -:10AFE0007DDE281F1CCA1629A71FECC588DB0F763B -:10AFF000B2F7B31F45FB7856F6F7D7D9796627DB4A -:10B00000EF9FF2F47B8D86175103AC527A1AA5AAF2 -:10B010006CDC2BE8B7CC8968FFED989FC1DC7547E5 -:10B02000BDAE02EB35FA86A937D27C5687EE8DA2EB -:10B03000BFA84F8244AEFB77CA42C931D15943EF12 -:10B04000E101F1FB820EBD62DF63DFBF08FD7C0121 -:10B0500060FB7B7A2AC407E4FF91D05EEDC9989526 -:10B06000183F565CFC5184F11466F7AE12F6655138 -:10B070008DFBBBD71F747A94AFEB7AE823FB3FAA12 -:10B080008533329E6BAD73E73FDD59F44592BB2BA0 -:10B09000F7F9C9CE5C09C6ADF533691D921FECFA0C -:10B0A00075A7539CF8FA32236EA15C83B8496D3DB5 -:10B0B0007CB7EA0309D20E3FC12AA55FC5F5B68A5F -:10B0C000E90FE7FBEB62B2F1468EDFDF643FFDA0E4 -:10B0D00019E11AC4838F9FA7D559D931CF233D5287 -:10B0E000238FCB19C5170FB37FBF2EA6D238CBD66F -:10B0F0004D29E6FE21B7DC7C57E8A99F3CFC2D9545 -:10B10000EEA3FAEEAB17201E563C2E83C6C67DF783 -:10B11000E10864487FA555D45F576D9773EA77CCF3 -:10B1200074A2BC94ADDC7F79D5B6407A316B7FD503 -:10B13000A3AF9F050CBE775BFBF74CC475F05DEECB -:10B140005704ABEFAC8BD8FBAB14F8BFB9ECA9CF6D -:10B1500047B9BD7DF847454DB8BEA52D3BBF48FD5D -:10B16000F65EEA0F38E2734BA2FC7C2CABC7FDA065 -:10B17000DF91D25372C4EF6CBFFBE1EF481CBE1DE0 -:10B18000FE7410E1DB72BF9A6470ACDAF21EC993F0 -:10B19000055BBF17453CACDAE18ED3ADD8FA610749 -:10B1A000E6A1AC90A17F31F2B37C8CCA474DAD5F74 -:10B1B00026B9CFCF57AF2492B07A3FF8EDA2DFB0D7 -:10B1C000EF6FC7640832D1FBF6BE83EAE3584E86C0 -:10B1D00053B8C35DB5C32DF7566D799DF222741F28 -:10B1E000F4579C8DF9016EBEF6D667EB4745FB69B7 -:10B1F00055EFBAF7D0AE5CB5FD9D5FA3FC58E59165 -:10B200009F6FE37FCA87FAA9DBA29EFB69B61496FB -:10B210003FB1E27B47EFB5D8B887B7FDEE5ECCB360 -:10B22000BFFAA3F7EFFD67B4179E0AEA28FF577D20 -:10B23000F7852838F8F11EB1FEDE9D045639ABF7CC -:10B24000EE7F06D278A0F5DD277F3B19CFC9BDFB85 -:10B25000C81FC719ACFEF54F9E47F7F25FFFC30545 -:10B26000E387B3AB905FD301275C69A2ABB143E244 -:10B27000C6CB13E2E9A1C7E1470654B477FF2041EA -:10B280003FEAB995BD1FAAB83FD963423FE267F7CD -:10B29000F6D7F77C9595DF61F409E4A00F9BFF4496 -:10B2A0001FE96F2626D973E5F6D71721BCABA09FFF -:10B2B000F4E9107A3ECFE839334B4FEFF7A3704CE7 -:10B2C000C57DC1AA8719FDCE423A32FA9D35947EDA -:10B2D000EFE07FE60EA5DFE351F7BD0947E1EAFBAA -:10B2E000CA7163BA7D6CCE3C886C9C61F87B506CF3 -:10B2F0007930127EAF90385C5D51F3A728EF0F6F65 -:10B300002B1AA4EF62A4EFF78E4E46E3ED4D7FFFBC -:10B3100017110FFD4F0674FCFD12573DF922ADB316 -:10B32000777FF89C6A505C07A2D26C5686C19FFD5D -:10B33000C0CA2BB90F1CAE79E0FF2FFA356B7F0D19 -:10B34000EB02F7998C6E54DEC3D61DD1217D61A32B -:10B35000817A335D46F35E99E6EB61657AE7C578FD -:10B360001F8517EFFE62FB3ED02C3DF1BE8395DBBF -:10B370005F5D847C978F9EF6FC759CFF1CF6FD013B -:10B38000F77AF5D65FC9D627E9292F7DD33B7F8190 -:10B39000CF77EF0F28783EE35D71AFAE97EE59FCA3 -:10B3A0008B73F3A38C431DF7F0C7601C4AE0293F61 -:10B3B0007FF0753ED2FC468BBF77A2868B8F6C3CAC -:10B3C0001E3E965BFE4F2CE6726325F434A2E9EC38 -:10B3D000B55714485A132BB3F01E46FB82C17BF8B5 -:10B3E000BB32F9853A7A77931CF7CA8B9590FBF7B5 -:10B3F0006FD516737B71E58E9D67A15C3BBCEB47F7 -:10B40000C49F2B1F7E55C57DC79E2D3F50FB6AB341 -:10B41000EB01F543DA81EFC3DFDF79169707B9FD5A -:10B420005E73C57C563DE1EE7FD5C3EFB9FA5F612F -:10B43000F592BD30D2386F2BE6A538DFB7F7F9E9C2 -:10B440001EC2B77BE5C65C76F0E462BFCB0EEE7839 -:10B450006ED16FF03CECCCFD21BA7F717BAB39FE35 -:10B4600016B4DFF6FB457CD1FC1DDAA5DB9F0B9102 -:10B470009F67FBFECF503E90DDDF631E7CCE79DE02 -:10B480005A1061FDCDE94BCC948DA172A3EE00DB87 -:10B49000EF39F8E0FAE71AC7A3DCC7FDB181BF5F57 -:10B4A0004E89D3392C39BA88F2CC65DDA70773EA07 -:10B4B0006FDE9F3FCCF7937EC698CEFBDCCF3DF688 -:10B4C0001FB47FEF88FB72E2E13E817FFBF73FD93B -:10B4D000EFD74B9C6FAC67793C24DFFADAD81C8B32 -:10B4E000573354DEDA5C17C7B8CFB5C5FCBE9EB182 -:10B4F0006F18129E2D99DB674CC7F917432FE0791F -:10B50000FFDB9BF5B8333E5476D86CC17A67BF0930 -:10B5100071AC87E3E27E6DB4E35AC5FCDCF3907155 -:10B520006B7B092F858CAB9DC0B8B79E8271C327FA -:10B53000806780CD058DEBCDB3F28EAF4EE379639E -:10B54000DEF192B63E10F1055A7AC3F8DBFCA29FF9 -:10B55000A5C586EBF7958192A17BABB3791769A955 -:10B560007326C6EF06CF1B2734C77963F69DCE1B23 -:10B57000B7993C0F96B5A375D025FC1318CF5CE6A0 -:10B5800080F705219F0215A918DA5F9D79E211AFB6 -:10B59000083EEF8C346838999DFAF4E2BE61F48677 -:10B5A000B2E69B339CE792153D23B9E2C8E6EB7403 -:10B5B0007F56BEF6DEF8A20D7FE7CE7F82AAA9985D -:10B5C000379B80D61C706E17EB07EB5562BD581287 -:10B5D0005A1CF5D4189FA75DEE147EA1576E7DA569 -:10B5E00093E2F679F0B443D0F30574CC97D1F64DDD -:10B5F000C3F86F57C44772B22B98FB1EFBFF2CF6A3 -:10B60000B9E4A48AE71FC90FBB8FF68DC6B1974D69 -:10B61000BC1FE9D65A95FC6091FAFD543E6AFAC8FF -:10B62000FACF871FFB3E83C1721EFF53BDCEE9BB1D -:10B63000DBDC46F9B1D74D558DE1F22D426BA6C545 -:10B64000316F425B73761CCF6B876AF8EF61D8303D -:10B650000FE26106DF863CFCF13F58523CAB0080B4 -:10B66000000000001F8B080000000000000BED7DB3 -:10B670000B5C54D79DF0B93377EE3C813B30C0F082 -:10B68000BE8310D1623A28A2363E2E0F0D3E62468E -:10B69000C4A809D6D13C4A2218B436A11B1B2E02DD -:10B6A00082F8C2266BCDAE4D47A22D6DD31653DA6C -:10B6B000358FF61B4C74ED635B626CE2F6D30613B8 -:10B6C00037AB59D365B7CDD6ED9736DFF9FFCFBD90 -:10B6D000CCBDC30C68DAF4B7FB7D4B7EC9C9B9E7B2 -:10B6E000F53FFFF37F9FC77C4AE4089949C8EE2DD8 -:10B6F000840C151342F8B08DB808D95762B2433A9A -:10B70000284F4F1AA6E987F0B7606C6A6DFEDB1907 -:10B71000553322F9CEBC442E48FBD999F73819A6E7 -:10B72000A9F5831612A0EDAD3C91FB69EA96C960BC -:10B730009287E6E55B7C561F4D5D24C3544ADB953A -:10B74000DFC2EDF08DED7F30E711EF5BB45DBA4CF9 -:10B750003220ED2C17324C3A787ABED04402749CD9 -:10B760008E72612DC0690D7F9E480991F2274513A5 -:10B7700021A9F47B5D8F2CC3FC08C90824C03C4977 -:10B78000468DAE5E0F47D6F4178F1DFF10E087B6CB -:10B79000DFAD96EF9BF3CEA17B29FCA22C95986997 -:10B7A00037FB06AF92FC69341FBE2A73302F0F9906 -:10B7B0006E2763FB817A3E5A2FD11B241B00CEECEF -:10B7C0006112A4E327160D1398BF43229249C27E4B -:10B7D00010FEA4D92344A1F592E60E7B9569BA7EAA -:10B7E000FE608E09A719E649D7D1D15CEA2F48211E -:10B7F000C4D63CDF5F40D725811F2222ED2741625E -:10B80000F88F6EF7CF490C3F1A5E7ACA6F490AC6A5 -:10B81000E87F747D5BCEA4F1165DBEBC670DE0DFF2 -:10B82000E2092A30FFC4D90C2F5A79A2344C643A69 -:10B830006E2261F324A5443E4693845285C0387439 -:10B8400048593F9F07547A7C409D0FFCC969588F27 -:10B8500010FA29415E74D57C2BE479F256112BFF46 -:10B86000D0477041DFB2A979F3D87CBCF94C94EE93 -:10B870006A21E42DDD7C6DD974FE5ABFF4DF1E0B06 -:10B88000C900FC7E54BC09DE61A407EDFB3675FEE1 -:10B8900016CF30E2670CFE8A19FE9CC50C7FCE28BD -:10B8A000FCED55DBEFFD2F86BF513C71A63540877F -:10B8B000D178D4EA578CC2AD205DD276847C0AF26E -:10B8C000816AE0DF1E3BCB1F12EFAC06FE00BE9A82 -:10B8D000805F08C9A44D7AB82E28CF1545ECDF7AD1 -:10B8E0001F9507FA7C50930F6C5C97CF5F4D283DF6 -:10B8F000139F891CA328ED9AAB7861BDBA9153229E -:10B90000FDFFA33809EB774A8289FB244DCF2C4CED -:10B9100007B9D966EBB1C17CBB2C3DD84F5B8E49D2 -:10B92000EC8D21DF4EABF335373B671C9D111F8F2C -:10B9300066810463F1FDDBAA7C6B1B7CEA8C99D2E7 -:10B94000072F09929DC20B4CFFB6B6BEF9B43DE974 -:10B950001FF2F9609C441CC7A5C2E52A349156DF4A -:10B96000C4701E57E98A6FB68F0B270F70C69033CD -:10B970001A9CED00A7273E9CCE9C0AA453BED985F5 -:10B98000E30C8A125B0F4B936D239D9FAB35496A85 -:10B99000A5E92EBEA9AB0ED2210B5168150B91CF94 -:10B9A0005450B8F969D309A1FD745C9A659B04B43D -:10B9B000DFDC43023A391F74042F89B43F5E0C92D6 -:10B9C00020859377293280F1AC4A07DABA91A264D4 -:10B9D00042E6D0F182FC0C90A7CEA080A9D68F467B -:10B9E000274E8B4CC462E8C7248740DF416773222F -:10B9F000F5E6BB19DEDAE6860354F691EE129EEC0C -:10BA0000A09FDA8B28BD24D1BC45EEAAA3F8E87E1E -:10BA1000D5427A757CA08D9BEB66FAC74E6A93C2BD -:10BA2000D0B7F9B037388E3EB603DE68BBE60BBE42 -:10BA3000EFBCA2E115FE15133CEF38917633809FE1 -:10BA4000DF27C5AB4DA6F8FDFCAE45FACE2B3A7903 -:10BA5000D54C98FE20444A5F312D7EBBDD2D6446D7 -:10BA6000416124BF870F213EBB5DBD5DF9749E8A95 -:10BA7000DFE42FA4EB45B24B0D788A4E096965725D -:10BA800070CCBAAE96C2B47D779189B702BD1690DC -:10BA90009019F092ED41BED4D635E8607463F13070 -:10BAA000396976C998DA008F20EFCC7BBCE3C96B8B -:10BAB0001BF0490C3C16B9291E3FF1DF0F8F1E37D2 -:10BAC000C1D499509304F8232FEF22D23400C3C875 -:10BAD0007F5A3B8DDEA3E75FFDDF7CFE1A9DC4AF7E -:10BAE000AF68F6103F48AB660549A89BC37CC0967B -:10BAF000864D29E854A5D8C2ADA09A72EAFA334E11 -:10BB000011D0CFEDE23B36145DFE0F53C6EB9F27FD -:10BB1000EF68F83447C6D3E3C7047AE78C25748C02 -:10BB20008BE02941FCB47790DC089E9A6C208F3A18 -:10BB30005D5BCFF84A2378EACC7E4EDCA0A3F72BDE -:10BB40006285E2A6F8D809766D0C7972AFBBA21DAA -:10BB5000CA05536C797E48956B5480F30BE9380B1A -:10BB6000468C789AA7E2697EFA3B8FC134A994E4A7 -:10BB70000915C815017F15E0AD6A4D00C882085946 -:10BB80001F7C2288F45025025E3865B2E943E78DB8 -:10BB9000E32F1EBE5C1C09C482FB19B1E6881BF4AE -:10BBA0004931C59BCEFEA08421A27CD4D6C5E5999F -:10BBB00080AED8BABD7C31DDA4D0AA9D5E5308FC0E -:10BBC000190B69EA02BC93736602765A5A3803CBA2 -:10BBD000ADDEFC10E8BBB4B09DC8E82788213BADC2 -:10BBE0007F70ED5D7ED443D76F23614A3728CB4009 -:10BBF0008E65CB61B0A779512A374B30CEA336F092 -:10BC00006F3ABD354984D9DB24961ED8E20EFE007A -:10BC1000D68DBF3E1FFB33D998DCBBD1F97C69655B -:10BC200022013BC07E810B812E3BB0727ED77029F2 -:10BC3000C8CD841E2B4DDB78250C7A4CB96097005B -:10BC4000DF5B0B95DB4D342DFF95BD88A7DFBB383F -:10BC5000871FF0D05548979CF6F3BBA79C2142F371 -:10BC60003B572E1F49827E8E9A25287FF2C3A64F0E -:10BC7000823D65FB603FFA8736D53F247CD32C5844 -:10BC80003FFB479413BBF91EA4FF5D05D36D7AF902 -:10BC90009EEA080E035EB4BCDD4BE5DB0CA4A7B73F -:10BCA00086293D99148E7C48E9D3E6DAE63D25C124 -:10BCB0007CE9778D3E7C917A11BE35E63D14D760E4 -:10BCC0006712726431D8919D206FD06E250A07EB00 -:10BCD00096C1CADF3FB06231D8A19D76AD7CE562E6 -:10BCE000599F57FE7006F3AADDEB4FF6EC82FA9EE1 -:10BCF0002CD2C4F01320AB74F64C41328FEBD6E754 -:10BD0000967FEFD6D9CD1A5D761530BA7CF9626789 -:10BD100035C8CD4E4A975609E87097C14FD6528D17 -:10BD20000E3B0B189DC5C3BBE57A0909EBEC408BB4 -:10BD3000A707E9D1E609A01D1D5D7F450AB363345D -:10BD4000FAB77909F2834D0A3E753FF287CB0FECC3 -:10BD5000672D68221CA5138BC8FCE189E6110F3EF4 -:10BD60008DFE3B0BF215A0D7F745E227E3D4B75C75 -:10BD70002FC5F96C71CB93927578F4E451BCC798D8 -:10BD8000CF5792D97C3A027581FB69BF72BDA4205E -:10BD9000DF7889BF1BF412257FB03BA9BDF9C9E448 -:10BDA000543D9E983DA2F5AF704D8316E0730F6D24 -:10BDB00047BFB6939714587A8B2764E0EF2FA604F9 -:10BDC00067EBFBE145E61F2E34BB4CE423E0673F05 -:10BDD000F5CBC293A99FD82262BAA7C58B69578BAE -:10BDE0008469778B4CC256EAFE90EBE7EF053BDBAC -:10BDF000E540F826A28B8E163FB66F6F99CDFAE11B -:10BE0000343A9FBA0BE8C261D2F8C4BF0BE83CC910 -:10BE1000AC959761BE8763E58F242F58AC14E37C03 -:10BE200050EE754D30AE395486EB77F3FDABF25BD7 -:10BE3000C5DFFE798F54E703FDBD6126FA38C618C9 -:10BE40007A09B3F16EB4FFAE6C13CAD3FDF3769EDC -:10BE5000F1D1BCE575DAFF78F4D8C3FA8FDB9F0621 -:10BE6000EFE02E84D74AD7DB4EFBB38A4CDEC7E324 -:10BE700087E8F9D294207F7808CAE9FD836BC9CBA3 -:10BE8000C09F7458BB087C1A9021DE25B4531CFB5C -:10BE900041DF06C2CF80BEB571E418CD0B2ADF505A -:10BEA000B5AFBC4CFB11641BE9A6ED06E7DD45A070 -:10BEB0005DE72B360A13A5D3947CB417EC85B5A4A3 -:10BEC0008DD6DB596D2766FA3D69FE1A02FDEDFC41 -:10BED000991DFBF79D9982FCBA4B647C34A11CF23E -:10BEE0009A4858AFC76D8E483E1FE4E57D24300D5B -:10BEF000F9FA693D5F533DD90BFC24902A8570A067 -:10BF0000871FF0333B4451E569E05832DA81016C18 -:10BF10001FB10B9B8808FC7ACE1CEA06BFC4DC80EC -:10BF200046DF22F361DB30F2B5BC3CA38C10170373 -:10BF300081ECF287492EE025C34C6D31204B818482 -:10BF4000A9DEE8A1FF007CFC85AB17C8AD84A4AFD7 -:10BF5000110CF3E02F382F996E05F8587D4D0FF135 -:10BF6000171A1BA13E4F74F5D19FA94B1ACF2F8CE6 -:10BF7000B6E30793557FD0497240EFB5B79C206F69 -:10BF80005B22FDF05171252DD5ECF9875358DC6209 -:10BF9000949E2446DF2F503F1DE8B1E31766D21B65 -:10BFA00083BEAF27FB0CF66E46D014991FFDF795A4 -:10BFB0008BD68A8306FA1C7FFDB3EA8DED739A1C3B -:10BFC000063CE635271BF23E25D3507F5257BEA1D3 -:10BFD000BCB067AAA17CF2A1E986FC94D0A70CF5BD -:10BFE0003FD15761C84FEB5F62A8FFC91335867C0C -:10BFF00049F86E43FD1967361ACA670E3D64289FDB -:10C00000757EAB213F67F8AF0CF5BD41F1E409E067 -:10C010004F4A8F668AAF5D19CA21D09FC36DD48EF7 -:10C020009BCFEC63D0B7249BA8F631554C694057A1 -:10C03000ECAF1DF400C8F93D8F85BF807AD2E407CC -:10C04000FEE50B16C91BA15DBB68225E9D1C911607 -:10C0500011F85EB1C78DDFE5D256E40F81AA0D7BE2 -:10C0600022E86DE37A10F376D20FF0BDC1E0E3452C -:10C0700025A67C12B28DF46F25F72405C6B1FB2CE2 -:10C0800092B1FECDD2BF2F45A5FF1C4AFFE689DB4A -:10C090006B74FF90499E9CC2FCC3AA731E83DF830E -:10C0A000781DF57B6CA41DD8A9BC6E24EB14ABAE37 -:10C0B000FA3756D3879FB871FF269ABF684A714EE8 -:10C0C000D7C9CBE4B566DF8FD587330CF65974DA60 -:10C0D00096F810CA3B2A17CB530C72315005F31354 -:10C0E0007819E5A2F6DDD73715E57297C8EC944EBE -:10C0F00089F2E538F88A96CB5F4E9698BF18473E8E -:10C100000B54CE82C2DDB9F2D35D8037791B41BDBD -:10C11000447510CAD9E8FEA95D7537C2E965F4A473 -:10C12000F9439ABF65A3F203FC2B9B44105F568A28 -:10C130002F27DA478FA27D49E721817D64F550FBE7 -:10C1400013F43DB53F99BDF9E7B52FF361DE7AFBF6 -:10C150004FD5972187DC94921ABFFF17E3EC479DD8 -:10C1600049D6FCEEFF9EF427A718F1A1D1A146679E -:10C1700056203A3ADEFB125B77DA2291D3F62F246F -:10C18000F84F10E9E5D4ECB34A25AC5BD0255BA9A8 -:10C190005EDD37BB06DB0993780272266178C33215 -:10C1A000D093A494C90985FE03F4E62836CA0D5B32 -:10C1B000941E15401F278ED5BB9A7CD0FCF389E4D2 -:10C1C000CBB752D438D92C324B2F5FE2F9E19A7CAD -:10C1D000D1F0B0E0831611ED8E0F68B9664FD07EB6 -:10C1E0002C397C00E2CC829FC84762F0DFCBAA5E8C -:10C1F000EE3B6997812E5D6B04F4B332FDE172C8AA -:10C200006736113FE067F670980469FF3FF4B0F5B8 -:10C21000C8F48738B0CF332F873880F3A085C58521 -:10C2200032B785387DDCE89AEAC7FDEEE2A37E5896 -:10C23000F78A3C17F2E9671713A48F21EFC69E72A5 -:10C24000D857984BFCC03F2E0F4F32217FDE1A4249 -:10C2500079E21F51A8AF4392E944614DAFB490E930 -:10C26000F751FFFDDD161BA6D75A444C2BF38A0766 -:10C2700017D07A5B7D0E8C1774E43B709CCE5C010A -:10C28000C7F98F9C87F2C02EF8758B17EB773DDED0 -:10C290005404F184CE93FF8971CD083D53AC7901EC -:10C2A0009E30EEF710BEC90BFBBE49F20CDC27ED49 -:10C2B000B404FF7103C413D70AFE6331F837E9E50C -:10C2C0001FA19F0CF8013CB4DB195EACCE26BF1B4E -:10C2D000E2FD93C8FA15B1F854C513A530B340E98F -:10C2E0003789910611E686DA1241AFFA493F059B7C -:10C2F000583A421CEC8790074509E245D9B6D02050 -:10C300009467D78BFE36AC4F705F415B278B9D04E3 -:10C310008EBBA05E98DB42BFBFE811D9FA0D8570D5 -:10C32000DFFD37176E1FCC21F1F97B4F4BF5D92A72 -:10C330005D3CD64562EF0BFFCB6D15160FEDF77622 -:10C34000806D26ACF7AC71F5E38DF67BBB8753E3CC -:10C350001393D3C15E6EE663DB996691AD0FC47F24 -:10C36000C08FDE5A28A5BB5DFA7E183ECC279FC73A -:10C37000F57116B3F9B77DEF8DCD8F513AF977DAB4 -:10C3800010E255AF5CFC0CFA8FEF254BFBC1EF526E -:10C390007E6C26B0CEEF7D7FD669589431F36E392E -:10C3A00093CCEBE249EF7DFBD5320BEDFFBDE75EB1 -:10C3B0002DE3510885101F5A79E387AF9541FC4A58 -:10C3C00068FE4DE6650AAF52418A9A204F0D68E635 -:10C3D000876E591A1E076F07D31ED802F1C2509BF1 -:10C3E0004BE4A8BDF625E71F05A0C766809FA60FF2 -:10C3F000DB4676727489B9F4779754D1FEB6728AA7 -:10C40000E2E2006F8A15FC0A72C1EA07BAD95AC87B -:10C41000F4E5D607C59002722CDCC4C8DDF65AE6F6 -:10C42000652A87ED3F0DC11900D2CE052A13207E63 -:10C43000378D20BDDF76AD290FF695DD44C8073A6C -:10C44000B498CCD8CFC84567A817E56FD32C9043D4 -:10C45000AD171F9D0CEBF57B55BE6871B73453D3F8 -:10C46000813A1FC4DDFC1877DBCDF7639C3EDE7C90 -:10C470009D5EB6AFC0571235DEF5DBEE7076841EDA -:10C4800034FE8A6EB7B785F861BC975A6C98BED0F7 -:10C4900022627AA2C58BE9F75B244C075A8A30EDF9 -:10C4A0006BF1FB0B2C00E76C4C3B2C647D40476729 -:10C4B0005FF0B0FDC87B92CABF0074FE24EDF73276 -:10C4C0006DF745DAFE32AD3FAF366C86B8CCBC11A5 -:10C4D0002A2F2528EFC2EFFB697F506F6CB9AD049E -:10C4E000CA4BABFBC380C7D262FA9D407F7D587FA9 -:10C4F0007FCB093F2B1FAAB450FC96FE96953BE7D5 -:10C50000D27E68DEA9F643C72F61F567637F745C4E -:10C51000CCC7E8B784C173A224163CD1F5A9956FA6 -:10C5200026548F88F0BFE0EF59240EF75138123EA1 -:10C5300006F2F882B51CF4E79E12926FA2FACD9231 -:10C540005AC041FEA966229A4BA8CACBA8D9554E1B -:10C55000A09D8CDF95557CE8980FF513F6ABE9A705 -:10C56000E4EA30EA9D243FC937BB69CAD381A753A7 -:10C5700054DF4722E70D503EB13CAE076D2756937E -:10C58000C8790332717DAA5FA2CA63D3DB474D210C -:10C590003EA63FF771701EB1835F4B7DFD7E924BCF -:10C5A000F3AA7DF645B5DEFE7965491B21BFF8810A -:10C5B000A7200EFE1BE2E5603F7EB47D943D77B878 -:10C5C000E54C5A55A1AA1440DE6F138FE8EDDC6CE0 -:10C5D00085D2AB8E0F7A9AF8EA5E8C2F04336A7498 -:10C5E000FAADC312CCA0CC4BAE3FF18F8B413E8055 -:10C5F000BE06393D7784E9F751BDFE5B261F357BCA -:10C600004250D76B9FBCB12D01F7D3A83E92C0AE6C -:10C6100008920ADA3EB17CEBCBF09D9418BF270854 -:10C620008C8F32BD210EF2999EC04F3CB0DF907CC2 -:10C63000487E86CEF7B7035609E8AFEFE4DA7A888A -:10C640001B3E4C12253BED27F3A54B02C0D1611ACE -:10C65000168008473CCD4B786A0775089A9CA486DB -:10C660000F5DFF8E34552E90DF7757D1FA074DC1FD -:10C67000AB54578ED63FE8086E813CFD936D54AFA6 -:10C68000EF1D8DA36FEB96294DEC55E3E6239ECF6E -:10C69000762BD990A7F5DD2CDF4EDBEF750F794DAA -:10C6A000349FC86DE93E930379ADFE966E85B6BFA3 -:10C6B000EA61E700882BE803B9379A17693E41978A -:10C6C000E7599ED858DA77F23F05D0431D6923A772 -:10C6D000B3009F3FE4FA41BE36BEFCF541C86FAEE1 -:10C6E0002712C4E7324F1CC175F8AAB97C04F0D6F2 -:10C6F000D7724644431DFEB475A176EA142FC17863 -:10C70000B210E242F960BF15F798D07EDB4E49B017 -:10C7100004F0DD9506EB5C91C6FC812921DA8F8E51 -:10C720007FA650BEB34E0775651919D6FB5BC46F63 -:10C73000027811E5F01FE57F2F01FDD4375B714CC6 -:10C74000A5E36DDAC0FB5B25D03FA15601D6FF04FF -:10C75000877AC2772663C73768FE5A7F4A2FF81B4D -:10C76000961D8C3E37F9FAD3A6D3B4C3CEE86293B4 -:10C770005BCDBB8DF976D59EF4BA157732FDBEF947 -:10C78000C4815C3000AF1E9B857EE4660D1E720086 -:10C79000E1B93A3827E9363ADFC69FB2B866E340D6 -:10C7A000C912987FE31E13013F6EF300A5271D7F7A -:10C7B000ECA37C284FA6F3907BA6F2943E02070BD5 -:10C7C00096DAE9FA7E3D5F16015FF569B7EEB6517C -:10C7D000E7E8EB823805E8A13EAD7437D0D3A6393F -:10C7E0006F213D26A596FEA49AE2EBE8DDD54B40ED -:10C7F000ACA599185F5282433967766F43FCFF6B93 -:10C800003919B1BA119DB8CF9907FF47E19B2CCADE -:10C8100015505F5C465D22A053217012EC10A5C23A -:10C820008671D20A711996E7AE21A66E0ACF112938 -:10C8300039B99536B517C826B053F2030E8C7F9AD6 -:10C8400013AA76803F7AEC1CCB47D6E912E2C55199 -:10C8500014EAB7D17E6E71F122F8226966D906EB2F -:10C86000467979E85829F00BB303942F1663BCE797 -:10C870006022A97F8EB63B6ADAD8FD235AEF68B2F0 -:10C8800087805DD9C171EB6BF07BC5D4AD743D8EF3 -:10C89000AAEB6776FB4558AFA36E637E2FB7F141D5 -:10C8A000C0DB23A92F2E81F9A559E59E140ADFE7E5 -:10C8B000525FECF666209EF36DB4FC737FFD42B7C9 -:10C8C0008DE2FD68AB9C29EAF293FF40A536CEE3EA -:10C8D00005E453DEFDC587808F69F98F6D54FF7EB7 -:10C8E0003D59B307587941BEC6D7D4AF9D4DE168D5 -:10C8F0001DCD2BB622D8F78AD4AFA27CFED5A7CD0A -:10C9000044EB1FEC09C79C7E9BC38CF3200EB067E1 -:10C91000A6F168CF38DC6C5D1D53F2D14E3A6A67E0 -:10C92000F81AC93161F922F3B322C407AC53781362 -:10C930009EE5214D01D0CF7C364F58BCF7B03C4529 -:10C9400082B029DB1FE47A56A07F682FD2ED071250 -:10C95000F0638DFB877C54BED03A9C61A27AD87379 -:10C960006105974BFBFB6CAAEA2F7A4806C4631F4C -:10C970004D6572E6D18072BB45021A1B66E75649C7 -:10C98000603AA4E9EB0AD2C73BBF32F65C4018ED2F -:10C99000B23D2E938AB749BBC305D45E763D27824C -:10C9A0001CA16A7EC761D06F1E1EE9A610F89FE623 -:10C9B000B7B9591CDED7B7E44BB3C13E7CB5D00440 -:10C9C000FCCF8B7E11CED99527942681DDC68FD2E0 -:10C9D000E9EB4BC240378373EE043F5000FEA59F46 -:10C9E0000FDBD9F9D0910CD20F7161DE2B13FD3E14 -:10C9F000A1C6BF3B5B6C98527FFE5DD01F5FEB22F0 -:10CA0000B84F2078039897DA09077CF1F2A7EEC6B1 -:10CA1000719FE10349EB40DE9E63763D900BC63982 -:10CA2000C24F7010E778DF16488279EF771BEDBFB1 -:10CA3000B23466C776A632F9D9D9C2E2A0C2F54FA0 -:10CA4000605CA7C3A2C923D7D2F05CB0E783788E1D -:10CA5000D61ADC2683BCB21145117571725BB631F2 -:10CA6000DE255CBF95C58752D938D1E70D5C9CD6D1 -:10CA70007FC1EEF1FC032D8D3E9FD04C02288FC864 -:10CA8000103BF7B06D57657AB2AE9F6D9C9C2E8EB1 -:10CA9000431F0F5F379390EE9CCAC3FC8800F37965 -:10CAA000F8BA80DF897738B115F66528C175C33AC1 -:10CAB0003EFF5DD44B0ED213860373568853E8CEE7 -:10CAC00085122F3F324AFFF911FEC07D752E067F79 -:10CAD00048C67CF47EFAA3E03BD37F77387F2DC035 -:10CAE0003CDFAB242360871232BC08F8B7B1D28197 -:10CAF00071EA87498FCD06062EDF23EAE3C58D0351 -:10CB000097123794E23E960476F0C32F951BE254B9 -:10CB1000DAF9302DBFF9C4068C1F3E7CF49A30B58B -:10CB200014C118B2507FACD1D673C69A1FA96FB783 -:10CB300004952CA0FF975AE52CFAE95B00279CABE3 -:10CB40006A9E340BFCBFDF8AF519802727AFEA8F76 -:10CB50003536D41FED76EAAF019D5E9C8CFA9416B3 -:10CB6000F3A09FB5F15778181D8EA8FE7C023533CF -:10CB700001BF1D8EC01566B41399A7F64E47B24685 -:10CB800037CDDDA0FF0E0A11B908933DE860F9E446 -:10CB9000B4E6EE76A687B1FEC893FC6EB0873AEC99 -:10CBA0006ADE43307F50E8413F41F9BE5502380FFD -:10CBB0003A027EF007951D5324D02755E92E9C8715 -:10CBC000E5EFACBD200F333DC1AB60B7100FB38FA5 -:10CBD000DE4BBD904B5C31FB19E16EA41FAFB11F62 -:10CBE000FB5C36FE7B9C39B0A334528FB60FE3B9A1 -:10CBF000807B6C18FFD1EA1FB618ED642D9D92C69C -:10CC0000E20C204F80AFB5EF42F03EE45F2B69426B -:10CC1000FEB57A8DFB451A3F0BD7A718E297DF4A7E -:10CC2000F5E1FA687240B85E8CE59D2A9DEE847D40 -:10CC3000F471C7498E33CE0C9413F1C72953E5081C -:10CC400051E3493C9E33D3F824BEBC30C671A3E502 -:10CC50009F966AF2EF884AC7FF600F2E4CA3FFFF32 -:10CC600050A87F91035B076F85F5F9A36AF716F566 -:10CC70001D3809E47745945B5353E13C957C1CD205 -:10CC80009BE59BFA3436DE5839C6E20FDB1E945022 -:10CC90003F3FC3FB1DFE1870D75F771AE4577EAA8B -:10CCA00084FDD5F30ACAB1FAEB8958FED1FBB793DC -:10CCB000D08CF1FA7761F968FFFDACFF973FF5E39F -:10CCC00083B3A1FFE3169355E7CF6D3BBE301DE262 -:10CCD00095DBEC542E1BF95606BEE57D64D40F029D -:10CCE0003EDFAFF945CAA2DD5573C16ED5F1F96CCF -:10CCF000B0BF22ED79BACEFB1D5AFB3B77833D34A2 -:10CD0000A6BE33AA7EBED6FF6AEC3F1A1E4D8E40E9 -:10CD10001EEC2DFE0F560D3E9443074C51FD8DCA5F -:10CD2000A520F6B7690EB33392FEBAFE270A0FF4B8 -:10CD3000172ACF023BEB4122C139E768BC27A9740F -:10CD4000587F7D92615D23F8BEC5F0FD9F5BBC24DA -:10CD5000A4E3B7CF04B72D027E4BD2D689283BB1CE -:10CD6000DDE12C12D2F1DDFFC0F151E1B82D0E1C36 -:10CD7000F3FFC270F80C7C1981A3C0F0FDA3C2615F -:10CD8000B65DCFBCACCB5B4492A5CF97846D599771 -:10CD90007576CB8C33A2213F73C86BA83FEBBC6484 -:10CDA000289F335C6428BFED8ADF909F3732DB50C9 -:10CDB0007FC175D9902F278B0DF52B6D2B0CF98525 -:10CDC000E25A43FD696A9CFC76EF0643BDC5D283F7 -:10CDD000867A4273CA77C07E59F0C1021BF8173BAE -:10CDE0005DA6EA10C5CF4E3E684B8E211FCBD47E88 -:10CDF00047F59D370DDB2F149BDA411E2EA4AE7034 -:10CE00001BB5D7D2EB02EDA0F7AB45229AD16F0E3E -:10CE1000B1F8C9072BABE0FB9D8B89D8ED8EE46F91 -:10CE2000FF2B42206FCD96F15C9BBDD884E7067640 -:10CE300017D78CBBFFB04FB5DFF744E9FB51FA3190 -:10CE4000B3F393D1DF8BD3195D1D58B08FC03E81F2 -:10CE5000CD15C27B3E8353767A21FFA505DFF6828E -:10CE60009FD135E5112FD04F67CE570DE7F21C0546 -:10CE70006C7F26BADFBF55FB2DB8FEA80DF4E7EE98 -:10CE80006C86CFE87ADAF9F4DD361637FFB8E6B902 -:10CE9000F8639AE7E5746667EDB68530FEDF5DF40A -:10CEA000F1C07FAF3ACE81058F1306EFE3780EB95C -:10CEB0002B4790F47A564BE1DE28CCA7D3B7D30B9F -:10CEC0007AB7CBF788C1FEB7C27C628C63F3323C81 -:10CED000ED163FDEF93CFE27CF6767CC7D775B9C84 -:10CEE00079156BF3F2AAF7283EA6793DF5179E5700 -:10CEF000581D2F359DD9A7BB25C64749E6C0CFF39E -:10CF00007DF1F92F69B6F19C5282DFE807E417043E -:10CF1000C63D7F745EC54F3C7E5D635152018ED726 -:10CF20005BD839DB7380479A9E0F4EAA80FB0AAF0D -:10CF3000C3792D0EDAEF48186F1DD606CD063827B7 -:10CF4000920F25E9F9888FD56B8CED56059CC6F3B9 -:10CF500052EA39038AA7FD105FD6F036669DFF4C72 -:10CF6000788A476F378AA7EEA29BC3D344F49D9A71 -:10CF70002E21BD4C84278D8EE2F5F3FF2A1D2DBE98 -:10CF800071FC20FD7CDCF8F9AF463FF7A64B37C4B7 -:10CF900067FFBFE2E7F11BC4CFE8796B81D4C73AE2 -:10CFA00007D2E915900E27734D6717839FBDD88C64 -:10CFB000F1B3D70E1734927C7D3DA6075E5B36A990 -:10CFC00011CF8F553BF1ACD65953EC7E5F53F1F145 -:10CFD00090D7AD9EA7F3A782DD7BB67AE5B8F322A2 -:10CFE000CBCCC6F38BC411999F99F64BA40A8C9FA6 -:10CFF00051BC1E1B67DDB5758B37DE8DAEDBD9EA04 -:10D00000B69B5A376D3C8AA798EDEEF6E6DF10DF47 -:10D01000C309768637761EA0EF7166B7F701BE6941 -:10D02000BFBF84A20CB0FF09C6FD56AF493F02F056 -:10D03000BEE665F1F001416AC47741562EDB0DE78B -:10D0400051CEAD727310D2D0E038A6AE67595D6C88 -:10D05000BBF339B53CD29E2393A5B1F58EA876CF0C -:10D06000AA3A0EED07C2CB39FA773FFE21AA3CBAA5 -:10D07000FD4BDE442C3F17E73CE6B7D4F6AB6BC75D -:10D080006F4FEA53F0DC1F21528EFE3EFA285DA955 -:10D090007CB0C21BFCBE97D67F9D0B7EF973104FF0 -:10D0A0009DE2C2F33D84273ED8F71FED8797F1BC80 -:10D0B000C6E54686F7E87E75FD85BDA9F1FB8B8741 -:10D0C0005F6D5EDA78A524807E1DA926E27E36BEDD -:10D0D00019CE39DC59499A707C5E427852DEA4FE42 -:10D0E0009C2F421F174CD23ABC48A3F633F0FBCA20 -:10D0F000A5D0CFC05993B8C3171FEE78F2E09F5464 -:10D10000FAF198833BE05C0159CFC53CB7F72BAFF0 -:10D110001DEBEDF78EEED7E338B73C19B448B4DF1A -:10D12000BBD4736784047356E8C6DFAFCE3BBA9DA9 -:10D13000C7CCF6C7C91B66C45F5FEF4339B1F8E7D8 -:10D1400035D55EDEEF2D32F8C7B5812D16B06B6B8D -:10D1500097ADB0482E289718DDA970F409C19C122C -:10D1600057044F71E58F8A9F81F3413CB7B1BE9957 -:10D17000C373C7C5DB19FDADDF3E686AA4E911952D -:10D180000F57C03E93AE3F77069B5F5FAF2317E01C -:10D19000EFD39FBFA0707CFA10C1B89D2DE3E93D8D -:10D1A00010B71BE6881AE7332D87FD8661755FACE3 -:10D1B0009096B702BC55A9C8E7EBB7AF403FFF96C2 -:10D1C0006AE6E70F0804CF01BD392F2104EF1D10D7 -:10D1D0009B3CF828CDBFF58724D2ED8FD0C71342F2 -:10D1E000781AD0476A5BE073B1E2D35206E3F3DF0B -:10D1F000BAD83E5E3CBC9C55E5A956AF86972CB18B -:10D20000EAAFAC36CA350DFE146BF83D12239E3ED4 -:10D210004A8FA1F1F5DD2F5439FD5A94BF547B3E5E -:10D22000B6DF3237433DA71BAAD884FA4AB14A7801 -:10D23000B65885C7A3AC467C7EB8948890BFD32AE5 -:10D240003D0DF0DD556B8E92C321EC67FD32A76179 -:10D250005E4FF4FE781ADC4BCA2F60F2F7FD2217FE -:10D260009E137F80340970FEAB8E28F3912F896462 -:10D2700001FA3EA7E24F83EF1C91136682BC683629 -:10D28000C7E4AFBB543A3A17A85C85E7DFDBCD783B -:10D290001EE1526DCA72887F2B018B1F8E375D6A2B -:10D2A0005F9970BF6E5D35BDA7D935E78395E3EA19 -:10D2B000AF5501E37AF5093DB8FFA75490A66394F2 -:10D2C000CE267FF9F2DE59347F36642A61E7DCD856 -:10D2D0007CCF86B2B473F1844FA3EBAE165D350DEF -:10D2E000637DE56FD8BCD6D58516C296D83D877AC2 -:10D2F000F6CDA2F9860CB7BAEF387F1EF0EBAF9AE5 -:10D30000C7B707A2E9E996271D867CD97922E07B79 -:10D3100014DB62EB87F7B29C6C5F87F7E7C23AAC2D -:10D32000DB1EBB9E3BDB85F5AEFED15C1FCBEF3E2B -:10D3300090C5D6637D3D17539E1FC84A60E50DB169 -:10D34000FB5F95E954E59D980BEBB23E0EBC2B328A -:10D3500013118EB73B56AF83FDFB2B51F655452677 -:10D360008343CA64E72BAFF6BED09106F4B09313A3 -:10D37000E11CD95B6EFF14A0BF0DED97D0CF4F57C6 -:10D38000EB3BD2034F66D0F4EEF3CF9D82FA0375E8 -:10D39000C4CF49F1F5C0E10C4D0F68F7A2357DD837 -:10D3A00063077D04FF0BFBAB1404252919D65D79B7 -:10D3B00008CFC5F43A44760FCA3F536F577F43A551 -:10D3C000E7AB476F6EBDEFA937DA4567C1FEF3449F -:10D3D000ECBFAB82B4B7948E7B95D25B2B9D0FF9DB -:10D3E000E0895BF5FA46E38778E3DEA81D78F5E887 -:10D3F000CDD98113CDF36719BE1BB203DFAF7E62B7 -:10D400005FA904F3ECB93596BCD5E4F22F55B918F1 -:10D410004D2F5AFA4B55CE5F098D0FD7670E19E184 -:10D4200059D7648447E38F2BA13607BCAB45479F90 -:10D4300006EBACD9A5A46AE60DBD17120FCE5FAB03 -:10D4400074F2AB66338F72EF2887F1E95F353F9155 -:10D45000182B6E153DFFAB264A0F401F4FF3287F58 -:10D460000AEB379C4C9322F4F87F543CFCA974A837 -:10D47000C9574D9F44B7FFAF4A779A3E9B88EE3C11 -:10D4800071E28F07326C88BF0DBC28C0FED1810CC1 -:10D4900089E589B8C80BF6EB6C76EE9D4AA85C78F6 -:10D4A00057E26AAF03EF8329DDD650215DC72BBD5C -:10D4B000B74DD1AFE3EC4CB61EEB1BDC3B61CBFAB6 -:10D4C0008AC9BF381DD6AF86BDEF71EE7CF2A2745B -:10D4D000DAFE892113BC9045D66DDB6086F9CDCC90 -:10D4E000647A64FDF657D1EEBB59BA5EDF64D4E7C7 -:10D4F0005FCE10553DC1ECF03BA95D00E708E3E1CC -:10D50000A13093E1E19EFAE3284FEFDDCEA13CBDCF -:10D510002593E1E35E3E847299B433FB99D8283EAB -:10D52000A85CBA0493007CFC35C7CE77F30141FFB9 -:10D53000FEC6FD7B562F043B309A3FBEA7E2E92B87 -:10D5400099EA3B84E9C13B33D13F0C70D0DF5B9F4C -:10D5500067F0AEDFBE05CF275FCC50ED6B953F2F58 -:10D56000C23ACD8CCC2F459DDF05C7C836D0179465 -:10D570006F4C78BEE47533C275F5ABDF6C827AE22E -:10D580005417DEF7423B96E6FB9627845A75F13A2C -:10D59000CDAEC9F7337EA8E565835DD890E933D871 -:10D5A000E9D1F6C6FFE80396F6A878FA4BE983C3FB -:10D5B000AA5DF0A7EA834754FE8FD60BA37CBC93E9 -:10D5C000F1F1A5F3FFBE10F2D17CFCADCC8FA69794 -:10D5D000A2F9F74AEFDD48D7CA1222161AFCA39C1B -:10D5E00010F8C1A3F41FF1933838DFF644EF4FA6CB -:10D5F000419CEBD2DED5EB628DFF4416B3B33626E9 -:10D600004A267C1FF2754667D17222BADD285FC4B4 -:10D61000892FD6D6CC41FFF05CCD6DB970EF2DDAF5 -:10D620003F18539F935357817FDCAAFAC7FBACF591 -:10D63000BD31E0F566317CE6178C9C027CBFDFC013 -:10D64000E17D62F8D3DBE9779FF7FF60581A0BEFB3 -:10D65000685EF34FB6B3F1A2C779575DB751FF4487 -:10D66000A1FE09C5F370AD3911CEB16AFEC9B0F2A1 -:10D67000E7F54FDE2423FF300BD6F9686CB81CEABF -:10D68000FCAF08C17D73281C579798FD0AF08B8961 -:10D69000B6D3F925D1EDFEA8CEE7CDED37298FCE53 -:10D6A0001BE3C9F1F86D14AE3F91DFFA84911CE0E1 -:10D6B000FB378F7C70F15198CF1107BE3F16DDCF3D -:10D6C000D7B2CCAA7FE0403ED0F4EF80D0B3F905CA -:10D6D000DAEECD3B32FD3B888E2F08E50BFAFDC21A -:10D6E0001F295FF851BE211FF7F53AEB63F9298333 -:10D6F000AA3F141DB7117BBFD1047EB14CFC167D2F -:10D70000DCE90D75DD7FA1CAA5A22CA63FEFAA5DBD -:10D710002140BCE8FED1781141E7429C9A7D04FC8F -:10D72000CBD7D47B02CAC68498F1DE992A5E278AB9 -:10D730001FACA933FAF577D51AE5C73BA1FC513DDB -:10D740005238CE7E9446BFF1C6BB51FDD117BAB94F -:10D75000FD8089E6F7D9AC1BD31FAB48D33C8C7353 -:10D76000D0F581B496344D7B81C2F3CEA19509608A -:10D7700047FD82906AB4E33FF8EC34BD5D1254F18A -:10D78000FC7EED67EF00727943689A164BFF44C741 -:10D79000697E118A7D2EE32E55AEBEA1DDA7B82B82 -:10D7A000763C7F8B3AEE1B75E3F34D74DCA67699DD -:10D7B00071DE4A16B387DEA86B7304995FCDC6FD90 -:10D7C0001B362EE82DBD5DAA64FD79F4E330C4EF6D -:10D7D000619CED84403CA54F50A6EACF5DA5643323 -:10D7E0003CE4178DBF0FA5EDA768F5A2EDAC9F67D0 -:10D7F0004A867BB3B5CB8C70B569F62D11310E72AC -:10D8000015F4A527A22FEFB4FA1F043A202E09CB56 -:10D810004FA878BFBBFEDF2C307F2A3F3BF01EDBDA -:10D82000599308F2B3EC7CC8A2C7CB851BF4AB2E8E -:10D83000A8F6C2447234BF6804E5DBFB2117DE8F13 -:10D8400078F30BBFB3C4EAB7F67A96E11CF1FA405D -:10D85000ECB88A98258C8B6731CB88BFF5D773F1EC -:10D860005C703CFBFF10C8AF99608F1EE9D0DBFFF6 -:10D870004F6549AAFDAFCA339ED9FDF1E2AF432AF5 -:10D880009D4D147FD5F4B3562F7AFDB5345A5F0EF3 -:10D89000ABFC1C5DEF52D68DD1DDA81D1387EEE2E7 -:10D8A0008DABF91F5ADC37BF98B68FB12F33661C8A -:10D8B000B55EF4386F46ADCF183F224EDC2E299B63 -:10D8C000E13718276E9794CDE2766709D38B4AC863 -:10D8D000897AECCAD17BF781B9F7C0E2CF9D06F512 -:10D8E000D6A8C66BEAEA5F3D057EAAE65744ECF18E -:10D8F000601BEC935DDDC1A1BD113D4EB45DDE0842 -:10D90000EF15822055E307456619E3D4E43176BE6E -:10D91000DFD3BC1AED4B2D3EDD27047624D0EFB7C4 -:10D920006CFFB76DA05F353FFE2D8BFF411667661C -:10D93000F6EE855E17DE73DD3AEAFFF931DE38CAAE -:10D94000FF6AFC71A2F518953771D6632279132FFF -:10D950002EA2A5A3FB2C8254F80A9C4BE512FDBD18 -:10D9600034AD11080F78A859CEA19F5923C84B3167 -:10D97000DEFCAAC90479DF72DF6E3807BFB2DA2293 -:10D98000DBA5C8FE4BE96B0D85AF807F41270C7E80 -:10D99000ECC02FA57F82FBC1AF2FB64BB03F727694 -:10D9A0009E34E8A1F9B3777022D83D558BEF374FFD -:10D9B00083F15671F80E8DB399A8E7B56F5D5E5986 -:10D9C00040C8370044DDBD8F1A6D9F4659BB0FEE2E -:10D9D000CD4E4D1D30B9284ABF7B78ED3E1B85AB3F -:10D9E000A335E085FB78F76597EC83FB786969F2EE -:10D9F000D0026A471DCC9EB11CF2037FA3F557BA33 -:10DA00000FEEDFBD680AFA385AFE83EC65CB79D891 -:10DA10008F98A48DBF1ECBEF5AF2E0B16DB4FFB763 -:10DA20000F6F590E67D7CBEAB4F11F595EC953FA8D -:10DA30009FABE51F4B84BCC74922FB4CB309B144E3 -:10DA4000EEF7E179F781D1FB7C2DCBE1FCF8EBE53A -:10DA50004D95708FB3ECCB1DFB8AA710326B59B973 -:10DA600028D3FCDC9C2F2F77C2FE31A1F448F3723F -:10DA7000CE57107E8FD9A4F61FDA2767033CCA540D -:10DA800028E79467F655BBE13EC2F06920CB879B3F -:10DA90007B6C69867B098A0CA68970A23C9C85E018 -:10DAA000A8FBDAD9E169ECBE9D9A2F62718AD1BCDC -:10DAB00097E50776C4BE7FF2610E935F038ED8E5CB -:10DAC0003D2ADF6BFBAF49E789FC6C0CFEFF3CC4D1 -:10DAD000FD6746F8E914C4433CF8E45C532BECC3FF -:10DAE000DA189CF1F671F7A9E314B426E13B45CBB3 -:10DAF0009A9CF8AECE243F9337948BF89520FFCDB7 -:10DB0000268433D5CCE17B26690E123C4ED3D41447 -:10DB1000F6BEC9328A6A787764E1A4C0513CDF9BC3 -:10DB20009E51D206E7EB5A7FCE831DA6B51F0BA7E9 -:10DB3000B805E04C35D7946C29D6E1AF98C14DD7E4 -:10DB40005D6D277F13DE7B19189A9A0F767565B67F -:10DB50006488CB940DD558E05CEAE51C554E48AC82 -:10DB60007D6A25932B235BD4F72A6CFE12435C5FFE -:10DB70009D7F65E7B22F41BD86210B817388DB8EC7 -:10DB800097E33BFDF1F8BF01CEBBEBF476031FC674 -:10DB900073E60D70DE7D06F4F75301CE37423FE0A9 -:10DBA0001FC0BD0EB09B52DB62AFB716576EB8EE0A -:10DBB00026CA0CFD7786AF48FF1E2C9F685E91FE3B -:10DBC0008CF7F8C6F6A7DEE7D3F0CEAB781762C3C2 -:10DBD000F9AA469714DF261D3DAD52E98B4A3F7CDA -:10DBE000D7F7C2F2E25EFD7B0584EC60E73A78BAD3 -:10DBF0008E604F0E39F07DE0329EC9C7B2A16451EC -:10DC0000E1C6D285B6AE03C94DF83ED1C80A2EE6AC -:10DC1000EF0F9CD7E052EDA7F4BAA079830E3E8DAA -:10DC2000FE23FD0F7D41E38F75C8B77B197C606FC4 -:10DC3000C03CFCE169FA73201AFCB753D981E7496B -:10DC4000DB54FCDFE10AF57211BC8DC57FD604EB15 -:10DC5000998BE5654327059867431C3EFD650E3BA0 -:10DC600027927E3E9C08E703966633FD35D03FC37E -:10DC70007E1BF0C53213E124366FB033CB34F94A42 -:10DC8000DEFB590595AFE9A3792A5F2558875179BD -:10DC90001BB6D922F57F9AF3DEF276AA3F3C567680 -:10DCA0001F8CDA8F36A2BB8768CD61F1DBD9C1D872 -:10DCB000FBD6C3390906B9F5547325799BCE6F6538 -:10DCC00036D3E7B387157C2749E3EB68B95498C38B -:10DCD000D6D197C3ECF18F5F2E7113C8A515AA5C3E -:10DCE00062E5C4136880F234937A2F4164EBBEF18D -:10DCF00047330A210EB7D56B96E09EC34ACE9FF3F9 -:10DD00002D3A4EAD4DEA489022F4514B6C920BF0F7 -:10DD10004D47807BAF35CBEC98873FB03BFEBD874E -:10DD200063F447A4A4DA71EC5A0D9EAD5E01C7DB23 -:10DD3000B8AB3029A887930F3C8BF13DA70AA72DDC -:10DD40004A5FF1C67C5A5AB8D164D695BB98FEEAB0 -:10DD5000F6CAE539605FAAE79BA2EDA27BB23983E0 -:10DD60001CD6ECA2DF79199F50FE45FF319DFA8F3A -:10DD700004EE7BF407F03C183C605488F775D9FB3F -:10DD8000C66F1D2773C14FD2FAB92BA7D8D06FDD4C -:10DD90006ABA489FA4CC69AB942FEBE4D919F57DFE -:10DDA0007A4A0F33815F57E710633B73201BEE9570 -:10DDB0009374AB1FE4CD29217018D757246E58DF18 -:10DDC00085E62D87912ECCC4DD86E7A48E60FBEA24 -:10DDD000BA9152B4533F308741EFFC3C3703E339EB -:10DDE000A94E46B7A7EC4DD88E275232CA1155EE30 -:10DDF000FD3C770ABE7FA1C9CFC87D16AD1F567EF8 -:10DE00008A5B910DEFC49E4A9D5CD2C619ED1DB090 -:10DE10007F22F6D2F3FB6EA7FC38ABBA3F4C61A66B -:10DE200052E5A5E58FD2FA5B7298FE3BE50B0CC07C -:10DE3000B8A7DC4404F8670F079F85FC62AF13DFC7 -:10DE400071D3D623CDC47E1F264DFDFD15E01348AA -:10DE5000C55CC66F8773D93ABEA3E6D31263FF9E33 -:10DE6000CC7FA8F57AE0FE1FADD75D1EFBDEE81E75 -:10DE7000958F1B6D3DD570955E77CF13EF2DF38495 -:10DE8000DA55B4CADE1CD60FD56788AFCACE3AFCC5 -:10DE90003DB1F78756E1BBAEA3BFF301EF54D17597 -:10DEA0000F9395FB01EFC22FCC787EB3C3C2E8522B -:10DEB000700745B88794E28CEDEF7E578527C5CC77 -:10DEC000DEEBD6EE2F58D4FBFCC7547B2CD15B8BFA -:10DED000721DDE58937CF02EDB08DECFD5D631FAEA -:10DEE0003CAE45BDC77FF3F643491CFBA1D4603F60 -:10DEF00068E346DB1117E13D6E5DBC7B9DF7DC42BC -:10DF0000A2ABFF6932DC01FD7D7A5B96212E11CF39 -:10DF1000FEF8912A6FC15E5062C22518BE5FA47ED2 -:10DF2000A0A21FFF0A1B3F32AE9328BA71F7E6C8C2 -:10DF30003FCEC1F8CD5C11DFB1B0133C0F5BA6BE84 -:10DF40005F47F513BE5748F55235C86FCD2F02BE57 -:10DF5000179380AFCBCFE6A4EAF4A4DA2E5A1EDDE5 -:10DF6000A1DA0177A8FA26E9BC66373A248E8BE855 -:10DF70009DB17A8B53EDE868F918AD178C7635A50D -:10DF80005B456F078CE11715AF374F1F93E2D0C782 -:10DF90002D7F11FBB26C6ED03C0DE4663547601FDF -:10DFA00064569551DF3B7299DFE1C8751ACEE1D610 -:10DFB000D419EB25423DE0AB5CE70DF9297A7DC42D -:10DFC0009941EEB1FE36ABF4E07BF7AC00EF372EB3 -:10DFD000C965F650499E9C9A4BD3237FA8EC83DFFA -:10DFE000A11869E549AF07DAC97DC31E98974D04AA -:10DFF0003FB57C6D55D1115A6EF9A905DF9D2427D7 -:10E0000062FBF7AE664EBE8FF273BE2AE71A3C6C17 -:10E010005E0D9EB05040E1C86C60F064F70F72BCBA -:10E020004EEE65D7B37AC5B91683FEF1439EC2772B -:10E030006BAE16BF0CB5C2EFA164D7CB3CE8BBCC2E -:10E040007E8EA8EF6EE27BA9997ED6BFCB1FE2EE53 -:10E050002D8ECCBBCBB4A218F445579AD30FFAE25D -:10E060007379C1329877C3857018D036EBC2100F20 -:10E0700076DFFE3C79167CD7E62799C54CD81F770A -:10E080005E60F0F544D13F21BBD575E965F0B9027A -:10E0900025004F5AA284EF10D1BF7CD0AB69C9AA2A -:10E0A000DE482341782F88D8683DB0831CB49EFE9B -:10E0B000DE260994C23E412875DA74D0730B1DFE2A -:10E0C0009336D0AFD37DD3E15DA1170EC78EA7D70E -:10E0D000AA7A87C27FA71EFE78FC31FADEBA5ACF31 -:10E0E00012C78FD6E8DE591DDB5EA59A00CBCBD7D1 -:10E0F0007AEE86F934B40BF81B5D1ADEF7E70536C5 -:10E10000E6A6C23A1DE1805F33FBCB91AE32159E8D -:10E11000805DD1EEC80DC13BB2EDC99F4A07FCC777 -:10E1200083BBA1D92CDFA7E7E77601D7E348D4F971 -:10E1300035CDCF782C97E9A3D37981AD30FEE613A6 -:10E1400007F09CE083472F09E3BDEB73A378E3EA74 -:10E1500099FFD2B086BD9751BE96473ADCD42EE0E7 -:10E16000BBEA0DCF1E0FE37EF17682FBA00DFDC74B -:10E170004FC33BAD590DF24CFDEF126435B077E360 -:10E18000D212467F1F5400BD9DD9BFA201E95A2477 -:10E1900022413A0AA2DD956D63F6A886DFD34238A4 -:10E1A00017E267A74DC4DF46CBAF59942289E6AF8B -:10E1B000F91C7E787FE1EF8FBF213D067886B81885 -:10E1C000BC7B9017FC12E0A3BB959D27EF5E48ED4A -:10E1D0001E5A6FA1936C85FCC2361701FEB8513CE4 -:10E1E000CC8AA28B59DB199FFC283751E55782EF67 -:10E1F000291DCF4D50EDA8601DDAAF741E9D731020 -:10E200002E9C87982B7F15E9564CC671331BC29CF8 -:10E21000FEFE899646E84A7E3637F566E0ECC77D15 -:10E22000C64DAA9C295F7B947B5B47072FE69A919A -:10E230006E329F3DC2817F48CB5B177AB03EC607E6 -:10E24000339F657ED3265A7EBF41AE6CC0F97439C8 -:10E2500098FD48E5CA4980EB94690BBEEF776A3AAE -:10E26000C17766EFB8103E8DE25985F794C0D6931A -:10E27000A77868A5F99FE54A38FE6921781FACFBAD -:10E28000E94C76BFBBCBB403DF3BD5F83E9A4F7F5A -:10E2900096CBFCC9CC3547398827789CCC9ED4E0F6 -:10E2A000D3EA95E4559C05FCCEAA1E423C34AEE16F -:10E2B000D97D0D159E8542A000FCB461B5BF93AB1E -:10E2C000BF6D3E44E16B2CE6909E9FFCBB57912EA8 -:10E2D0001B7B38F6BB413DAF0AAB74FED5C1EFBD29 -:10E2E0008A7A65E9008B1F340E1CE7EF7581BE3911 -:10E2F00089F4D948E9CF5E0AEBC6ECD86B96702E4C -:10E30000E8CB68FA745633B90831D742F60E1CEEE2 -:10E31000FF86D6DAD0EED7E4AFA8C209EF08827C38 -:10E32000FD8DCAEF5AFF117FD5EE07FAF6BD3BFD12 -:10E3300024BCEBD6E8E7FC701EF93F46F50993D7FD -:10E340005222FC7660A4FF68FCE5E631F91A438F9F -:10E350007C184B8F687AD6F77405BE97ACAD1FAFAB -:10E36000E27D54BFE7B1FB578979BC0A8FEC853851 -:10E37000B644F9B9BB14DEF50B144B809F54A71FAC -:10E38000E23B7FEF7E5DDAA0C3D76981F23BCD9F90 -:10E39000CE77203C942F92F274EBD750CC7E67EA74 -:10E3A000C9EFAE40BC36C0DA51BC3604EFBB0FF14A -:10E3B000EC25E231902F4126BF1AD6DCC5DE05D709 -:10E3C000F4DF731CE2BF4171E13BD74BFB57207D6B -:10E3D000128FDD5FC8A15CC375D6F84CCCD5F61D95 -:10E3E000D8BB43D4AF6F857889E6D727D605940488 -:10E3F000692C9FA6A87EFD4CD5AFB7CCB6FD59FDC4 -:10E40000FA4DCD3F41FFE721EF8F30D5F884FA8DEB -:10E41000067EBA2D8FD92D929A56E431BEDC54DA9D -:10E420008FF4BFE97213F28FAB9AC911D705A3FC21 -:10E43000D3E260D4836374E8EC5F04FB110BBFC2CA -:10E44000892007E2C1FD19AEE967705E851C67E7A8 -:10E4500028167CF0F344FD3BA435798CBEAFF599CA -:10E460004918F0CD3709E3D9BFF1FACB0957CDF9F7 -:10E4700027BA7EFFD29784E782AE3DBBF2F3905776 -:10E480008E26E139929C702DD2C535CF1C3FD081AC -:10E49000A78DE1E95A7F25D2CFBBE99209DE096B4E -:10E4A000ED7F623EFC5E74BD0AD7BBDF3537031ECD -:10E4B000767CED3BF3E15DC94D212E05EE9B5DEBD6 -:10E4C000FBCA1F41EFD51F7D18CF7DB57DF37FA11E -:10E4D000DD6D0A1D61DFFB9244A877F59903F30116 -:10E4E000BF6DFD6D58FEEE3347307FF26BDF311F9D -:10E4F0002A8DD0F1BBDF3DF2C3DF433E9088F77237 -:10E500001A824F3E0E79529BC8EE5D055F11F4BF33 -:10E51000DF75F0F820F2A146174BFB39F5DD30012D -:10E52000CF7968F4FB56457119F01DA550BF793EAF -:10E53000CD7727D4C78A23EE51E7DB00B408E3AEDA -:10E54000E142C0075D82D287F25CECCF0579EE2C08 -:10E550000E0BF02EE9EABAE3F3D9CF10B662F94A0E -:10E560001B3B2F368DF20BBC1F457B3BFA21C4F7BA -:10E57000BA1E5C07FD1D3613D19C118177B320A113 -:10E580007FB4B986F3530E231CD9762A15F6C79AA1 -:10E59000897AAE8BD5EBA2EEA52D19F510B1D3B4C7 -:10E5A0006C5BEC38E893792E953E19BF660EACC8CB -:10E5B00006F9413C567FA12FD25FCEF9A66E78DED8 -:10E5C0003FB37E6811CC6349D18619300F0FC4FB6D -:10E5D00040BF282EECBF11E293949FBEAACAC73455 -:10E5E0003180EF8CD8E4402AFC269B640DE0396E24 -:10E5F000697DC0D20A72861FC95D858AF09861FF65 -:10E60000F0A025983113FAEB52F5D351063F6D8FE8 -:10E61000FD4995B207DAD3FEB13F5B9DCCE36FBEF7 -:10E62000D9D83AFCEB0F6E3F668C9787C6F45FEA49 -:10E6300002FDA2ACC17593049CEFBB5015F1ADDC9B -:10E64000AA8F6347C77B409EC17EEFE9BCF2C1BC85 -:10E65000D448AAC581A2F1CC4BB49CF65321C998E9 -:10E6600092BE1BBB77A6C9EDCD7B54BDFBE22594C2 -:10E670003B9B833CD3BBC1CBA877FFA545266F53FB -:10E68000C3F2E0F39790BEEF3DC1F4EEE61325022E -:10E69000D0B3F61EF2E68A6BA87F153341BADE2CA2 -:10E6A000F49FF642FFDDC44D2D7BB279FEF02D20A4 -:10E6B000FF7EFDBC7D0DB43F653221BD9DEAFDC4EA -:10E6C00091364E0F1FF303B8FA10F2E366D52E28E9 -:10E6D0005F7BDF01F0C71AEBD9EF116C1E50F98B8D -:10E6E000FA6380DFCD275E45FAD1EC5EDFD3354893 -:10E6F0006F6E4A6FF8BB095543081FFDF317D2D45C -:10E700005DC5DEC55D52545206F47672F50F778210 -:10E71000DEDE5C4544E8FF608EFC3CBEFFFB3C87D0 -:10E72000EF511EB4F454C03DC9830B2511F8637337 -:10E73000B076543FE1F9EA60ED00F28F679D1FEC7F -:10E7400087EED620DAD5DD194EB40B0E3EDF8AFAFD -:10E7500073B3E4F0C3EF992C3DC16DC5F68A8B30DD -:10E76000F839B4F397866EC3735B1A3E96560DE77D -:10E770003279C1E0FEB565E8D330EF5F7FCF0A6F35 -:10E780007E8FD2DFFF05D640AE560080000000002D -:10E790001F8B080000000000000BDD7D0B7854D5B6 -:10E7A000B5F03A73CE3C1226939327E1E9C90308EA -:10E7B00098841308EF872704102BB583F2B2220E3A -:10E7C000C823424846C48AD77E37830331526F6FCD -:10E7D000AC2FEAA576A06AD12B106DAC51030DA821 -:10E7E00014ABB5D1528A16BDA3222F918CE083DEE3 -:10E7F000D2F2AFB5F639C9CC640262EDFFF9FFE998 -:10E800005737FBECF7DAEBBDD7DE9336D9BFF18E85 -:10E8100032802BD561BAAC03A42B6DBE3B3201D242 -:10E8200000F435986FB07B9D3A9647FE430A6DCE53 -:10E83000C5EFD3C0081501E4DF23192137408A262C -:10E840000164516A335307C008C0BF0691AA811200 -:10E850006F31C027B5067C3800F84FCB0658CEFF85 -:10E860000058B1A8D5A1617F554F89FE329D46E978 -:10E870002D989EA3BFCB305F013778B13C4B966E8D -:10E8800098C1A98D53ABDC4A8799F3C87D64E1BD7B -:10E890005370FEDFA9043D0987E85D88DF310F7EF4 -:10E8A000080DC0F9F7AEF4F6D5A83C73A92E633E67 -:10E8B0002B03BE4FE591350ED82C75ED7724AD6B4B -:10E8C00004D5F39649582FAB678A1EA4A1E4725B66 -:10E8D00012B52B95F4CD1AE5AF7E14084E59BD74D0 -:10E8E000EA072064C2C15B66C37A47B353F4F5F408 -:10E8F0003DF407E56A84C7244DB5CA4BA99DE601DE -:10E90000585FDAD96E4ABE97FB9BD233490FE23C7F -:10E91000A737044A204FC0C1EBEE8443684DF2DCB8 -:10E9200050143CC6131CB07D6830CC6D2C22F87B93 -:10E93000ABA89F6C9B9EB11E3715DC81926B526811 -:10E940009C20C36B00CD03D329B83E3FF59BEF5D00 -:10E95000C5F0C84AD113C163CF25021EBBE76C9333 -:10E960003760BDEA2229E4C4F9DDFFE28C525A6720 -:10E97000F54CB70E98AFF6290B695C08B8E031CCBE -:10E98000836FD1BD53305F5DE9D5D76BBCEE455485 -:10E99000DE3733495F8FE50F3E2F1994AF0EB84332 -:10E9A0004998BFB259E04375F3D3CA8D98F620BC9D -:10E9B0007353BB40C98CE2CEF900ACE1F9544F3A35 -:10E9C000D1FF656C1F9041972762DE111EA8E3FA04 -:10E9D000AB27860712BC4E3E9F3497DABF62B30561 -:10E9E000689C57365FBA292875EDE7A4DDDB44EB58 -:10E9F0003F89EB0F60F96F9FFF7388E8612DD28329 -:10EA00009C837BB4462BA7F2F55340A57DB1F66BF2 -:10EA10008F23504878B5272F99F183E6E945381FB1 -:10EA2000A77FF602B8F5126F8D8670AEB6B5D629FF -:10EA3000D46E4B06C018CCBF70F7409FBB2B9CB167 -:10EA40003DEF8B4B01C65F57A847281885572E17F7 -:10EA5000D2DA304E036E4C7BAC16F089EFE74ECD28 -:10EA6000CDFDAC7085F7E0CE41CDEA065736E29198 -:10EA70002F59E3EF49F680D107E7E3682E6FED8366 -:10EA8000E5D9E9F81FDAB7CD3D42B46FD9D9E07BBB -:10EA90002641BFAB4C3CB3F6A5211D182FB33DA2B8 -:10EAA000FECF4DBAF98949975BCC348A2E62F1DEEC -:10EAB000EDCB253E919D0CBEC604E359ED717E5C05 -:10EAC0006ECD0B5CD84F26B5D36C8CDF717417CA32 -:10EAD0002A1E4674372559DFED227A1A963B2C08F8 -:10EAE0009DE320247267A474C5035A07D10FAD8B30 -:10EAF000E8ACBB7A0DBB047F8AC7CB674C3AA9222E -:10EB00005CC7796F93901E13EEB3E8A7DE966B7B1C -:10EB100010E7FBA3FD32F3D9F87A56BAAB16A0750D -:10EB20001040DEC66B53BDC5DDD7DB66D6FB71ADCD -:10EB30008B53B7AEAD51B0FFA12D5AA90C349E3600 -:10EB400089C60BE078B4CF2913E15319E1E319DD4D -:10EB50005078672EE179E35C5AD750256C2B25BE9F -:10EB6000EBB5416BA1E0DFE7F0FF3DE72643ABAB40 -:10EB700033DFCB971E93EF53D93BA67E3F7F5E4C8E -:10EB8000F925AB87C494E70686C5E4F3EBC7C6D482 -:10EB90001FD03029263F68C37762EA0F0E5D1D93B0 -:10EBA000BF74CBF763EA17372E8C299FF48FFCDDF7 -:10EBB0003F253CA7F527E073561AD17279FF8636B8 -:10EBC000C7AE3F7574ECFA158800D1FBA4E4BFEA28 -:10EBD00089E8D94A5341F92C6CB5233EE0D26C0F39 -:10EBE000E23CCAFF2C87D627988785CF567E922293 -:10EBF000C78C6BF1890BE1579EEFFCF8F263C217EB -:10EC0000E779E6FD0F39215DAAB9820F28E0E5F525 -:10EC1000A74E9C7BDEF5DBE3D70F1AE3BD87D69FBB -:10EC200000EFE3D79F3A3A761FACF5E7F90637874E -:10EC3000B19FCFE74A2C5FF651D198AEFDBD1BB70F -:10EC4000CED9AB52599F01EF3509EB77CEE34E9EFB -:10EC5000C7F54EF02782C374130E95B982DE2F4498 -:10EC60009FEF9BF3F81FA24F4CDD6B73991E619FC2 -:10EC70001C1A805D2DAC9776F544BC48F7B9592F26 -:10EC80005BA8B44269949CBFDFA4EF074DFADE5045 -:10EC9000AB723F0FD7E670BAB156E3EF8FD416725E -:10ECA0001AAAD5F9FBE6DAD19C3E8AFA18A58FD7C5 -:10ECB0004EE3744BAD97EB3D593B97D3A76A7DFC70 -:10ECC000DDDA9FEBCDFD016F06CBB3F8F5CC5F9598 -:10ECD000182F412EE2F6F391CEE4F3F0B52EEDE5D8 -:10ECE00079A9E7C3A3D50773B7BF1C8507D7E5A6E6 -:10ECF000641EEE81FF1805A3CEC9176EFF65ADB681 -:10ED0000FD65FB85E9C2C21738FBE18044F5AEA77B -:10ED100031C722BFC9DDDC1070770F9F4E3C8AC31C -:10ED2000572FE22B7E2D21D9DE8BCAC3BDA3C7F995 -:10ED300093B9CF567EE64C81AFF1FDDE6FE2DF2C5A -:10ED4000C24F2C9F1D47AFA77385FC3C9D2BF4F44D -:10ED5000FDDDF08B7B726DA6FC14FB3E6B9FE04BE0 -:10ED600077F6983FC197605C294F8BA1CFD9336369 -:10ED7000F771BF5DF0B7FD7F92436B12ECFF85DA50 -:10ED80005BEB896FF72773BD9FFE7F466FFBAF4D2F -:10ED9000617D7EBFDDD72F2B6A7FF65FDB636EA2BE -:10EDA0007DFFDF5CBBD8AF421548BE433A18A407CD -:10EDB000E192020ED2E5A0403D4C7482C610D145CE -:10EDC000F778A9C0618B9E64826712EBE39FCF4CFA -:10EDD000E1FD079F6A4054FFA0A8AC976EFB2EEAA6 -:10EDE0000A349E82E3A11E0ABAAD73FFF2E8BFC9DE -:10EDF0009DFC5AEE9EDE2E8407161F994D7CE43C46 -:10EE0000F2BA6BBB8BE32387888F5CFACDF3118B4F -:10EE10008EE1EC8D03BC295DCB67111FE90DF0D3AA -:10EE2000DCB7998F7C6D3859746BEA13F1FCA4DB65 -:10EE300076CD9917907F263F57FCF561C48BDBE4B4 -:10EE40009486F5D8E42EC5FF73CA07020A3C86A94A -:10EE500073F5E9DE878673B7850AD71BC2F69D5323 -:10EE6000F1FF32CCF6A053A57A0FF5F8F7ED945FD9 -:10EE70008D1CD389E99749FD4380B640699EE03FE8 -:10EE8000B2EB4CEF4351F3B3ABD0273A5FDAEAEA87 -:10EE900073286ADF86EF5563F223DA7262EA8F3AEB -:10EEA000A0C5948F0917C6948F3BAAC7E427444690 -:10EEB000C7D4BFEC8C11932F872B62EA57B866C476 -:10EEC000E4A7A8D7C6D4BF3C67414CF915DA4DB1C9 -:10EED000FD157887E7E1BA173ADCF5522ADA69B905 -:10EEE0004619E59393ABFD0BC84E5AE3516122D509 -:10EEF0000E85086E750E97BA1EF9D40792D11F10B1 -:10EF00004FEFB3A1D59D8FF5E530507AD0A697523B -:10EF10009A676CF1119D6E2F4CD6681F920702B450 -:10EF2000919C52F424407EE2E811F95D01EDCB6F33 -:10EF30006CF01826DB5554F4A97E736688ECDFACC0 -:10EF400064DF15348FF5B606CF1ADA671B781FCB4E -:10EF500064BCFAC968CC1F7E41B1119E6D6FB1DDF2 -:10EF60003316F39F61F7329637B59DF8C995981F10 -:10EF7000DA66D7A9F65090D94E5CAEC03D4A7AF712 -:10EF800078F6F10F843D15FFFD677982DF6755083C -:10EF90003B33BEFC8E3C21DF3E76242E5F6EB6AF47 -:10EFA000B86BFA43C4D7EC6D7620BFC5AA2CA32753 -:10EFB0009C4F5F3D930FA1E15179C50BAA9BBE0FFA -:10EFC000E4EF1577CD83B05BF4437EAC5549464FF3 -:10EFD000F23B7C3C29F13C6E31E7613FD3A39B7E41 -:10EFE0003DFCFDE3BCF3AFD37E2609421989DABBB1 -:10EFF000F97B563071FB7BCCF13F4E4F5C5EDFD12D -:10F000007F2F086444B7137CA7739CBE5C6E3F934C -:10F01000068184EBC8E4EF9063E410DEEC423A270B -:10F020007E519E96ED0024F1F91079C540F8CF206D -:10F030009300F1145C7A29F12950EC91B04517281E -:10F040003F1680F201D90B3644C67338B51B56DB28 -:10F050003F0847D1D10C23360F543F4ADE7C427D16 -:10F06000E37A928714A612BE9F022D554D805F56FB -:10F070003ACF257B95A8F51CEC464F6A33E178B072 -:10F080005762383E6FF2B191F320A1BED696E711D8 -:10F090007659A1DEF37C7283E0EBCB88EE377E1FDE -:10F0A00032B9FCABC219F182E57AE4BBEE10FB2960 -:10F0B000BF71785BF8DD27062F3EC98F9F777F2EC3 -:10F0C0002FE8EB7D2B8FE58A3690E4629349BF4DA4 -:10F0D0008AD163989BF8185426827F9F7C534F8D6A -:10F0E0005B771318390BC8AFA1D875E267C932F83E -:10F0F0009F4E00FFF875A79AF3C6F6735BA93D789B -:10F1000074C1E7C0EBCA463D9FFE854B280FBC6922 -:10F11000A7FEE7F93DFA7A54813ECF13FAF40208CC -:10F12000DB890F77819F3BD34E7EDB78387A419B1A -:10F130002FE55F189EE905C6E7041F9B4BCDDE8ACD -:10F14000EB9C1FF000F9696E98079E629C8FEFBBE5 -:10F15000E96F185877E155434AD6527AE9F83A9957 -:10F160005B4F66BD4F0AF491CF5DFAD5F5BE3A8F7D -:10F17000AF90E8E390A42D61384808079237BD8F1F -:10F180000F5C1005C715FDCA7F9F9F45E7036064AC -:10F1900090BF788793FD56B001580FADD9397813D9 -:10F1A000C9852FF27DAF51BD51934DFFAD11197837 -:10F1B00075CAC5C30BFFEC44271782976CD2FB417D -:10F1C0004F62BC19972FF6EBABD24B66BE8043045F -:10F1D000E1B0B9EC9BA717845F0CFF782D5FF05F5F -:10F1E0002BB5E0366A5AAC7FF735731DAFE57B3837 -:10F1F000FD22DFCB706EEFF7E9E12492FF0E5C7F1A -:10F2000002BCF7764337DDADBF3B7AF9A6F8F2C111 -:10F21000E4C4F35CFC2D99E71B344FE2F32589E746 -:10F22000F96F17894FB83F4B5CF9DFFC3CBFC8371B -:10F23000DEC8A779A6279EE74F2F129EC8EC96B48A -:10F2400062BDD9C807A9DE373D5F082C984272E835 -:10F250001A9FF0FF1723C7253E845379F4DC70D240 -:10F260006FF5751B88EFACF4E80195F9C81BF982BE -:10F270000F8281F399394D627F52FB884F97288422 -:10F28000EFD9D09A46FC6AA793FDD9F1EB0F99EB21 -:10F29000473A799CE004D32303899F1C1C98984F1C -:10F2A0003C1E5FBF3EC2F2697D7962FD749B49AF2F -:10F2B0002B5C0DD3B26DD1E72BB84099B86CC0E888 -:10F2C00043F2B64C5D4BFCC4817289E0EAE833A49A -:10F2D00027ED07E6BD12F981735E3F207918DE271E -:10F2E0003AE097D739CEF1DABD6A81BD7B7EBE5C4C -:10F2F0007E66A43FC17AB66ABE5DF95176E3F22D0F -:10F30000AFAA05D1FE7108DB800547C4E6E5F341ED -:10F31000D36FD0132ECA6F509C29E865453F2FCB81 -:10F3200007921B643FD7BD30A6943617F50F20FB1C -:10F33000209292CCF222D87B6CA11605CF0FF32D30 -:10F34000FD53EE46AF74C47C7FB7D685266567FE55 -:10F35000FAA3FBA6903E3F1FC2EBA8FEFC553DE87A -:10F3600008B2639D1DFD9D9162F4DBCEFE15FE5E2D -:10F37000EE72B7CA433175FF2EE17E6CD58CA304C3 -:10F38000CFB5FD8C63B4CE78F805EE1A9FC67E0427 -:10F3900082DF655DF7BDBB7DFEAB669CA6FE5EE8C9 -:10F3A000A75A7E1D9DCFE392ADF361453DECEA8403 -:10F3B000F757DD9764D3BF88FAC4399AB701557EF1 -:10F3C0009ACF3C8BBEE3F41C2814FE803A4FDBBA84 -:10F3D0005D517478832D9225E476781D3999FE6706 -:10F3E0004712F38FF61DBFEDE7E3F3344BEFE8214F -:10F3F0009FEBF1D5E767F917ECC989F569EB1C6359 -:10F40000B7BDA880F5123AE71D8D79495B44F6AA8D -:10F41000A2821EC4F5955F8ED884FD4D92FBB68402 -:10F42000711D9FC3D9E40998FE2788F5AF7AF3A32D -:10F4300074F2634E52ECC7A3F953BC1F684041AC51 -:10F440003FF914CC4B6D25B88C4F67B86C6F99940D -:10F450004AFD943C3FB927A5BB6AEB55C5DEE90FD1 -:10F460008A9F7F793776E9B002A177BE9E6C0C2B1C -:10F47000C0B4BC9BF58F32EB85938D5105599DFD32 -:10F4800051FD44F1106D832C3FAE80EB358105AC0E -:10F490006FD95CC857897FA2FE2AABE4272CB03312 -:10F4A000BD1BA0A9D9EC3714FB8F7C5DC1FC0433D4 -:10F4B0002FD5BF1DA4761B6FF1F03938F83420F931 -:10F4C0008080E173813AC9CF7E0717C57D60BA5E3F -:10F4D000D237902E26DB2219822E4222AE017C0AE0 -:10F4E000E57F2B85831427B0D6F5EF3F273FB81172 -:10F4F00054206922E615603F63E0600A9FCBF1CC9F -:10F50000701E4E6B5E663EC5CCB7CF9A3A6D00A6B4 -:10F51000B7253FE2213C0D4BC847B19F2F93FFBD5C -:10F5200095E9C69FACDB7B937FE93DCE4B2B937572 -:10F530002987FC4F9E42D2535743B2EEC4710C77D9 -:10F540007180C67568C0FEF86468E475B8DD9F0414 -:10F5500008282AA812DB4FC9BE65056CAF009F932F -:10F560001F7E2F6533AD3F493DD57A077ECA0083A4 -:10F57000EB65C4C9C72CF72A89E337BC4A9C5CF405 -:10F580004904FF9E73E3BFC7CA4B171C54899F48A9 -:10F59000ADDE9C73C89FDA086E659D706B53845D09 -:10F5A00067C12D30C9FF4B826BE04EA71ACCECDE51 -:10F5B000DF86001A45FA789BBA642BD547C3096CDD -:10F5C000D45F8E585FA0D229F641F16DA5F6EFD831 -:10F5D0007354B27B2C3C7B68A0C9AFBBF1773C5025 -:10F5E00020F4A3EAF4C3D524E70007B5F50738995A -:10F5F000727424F10D9497F5242F93EC06C3DB92DB -:10F600009B2B9AD600D15575F30220BEF28EE41BD7 -:10F61000F032DB23C076D99C6981576C1AF9B26647 -:10F62000AE7363FA49411EE3D7FE57A6BEC26C48CB -:10F63000761753BBD2CBBC53B270DC6031E8776233 -:10F64000BD60926FEBB3B4AE3765FD318DE2212A18 -:10F65000E0C3E12632E1F74DB333D86F9A5911A9CF -:10F66000A37881C8DDA0527C4F17FA388BEB1B09B9 -:10F67000F00B1E0BFB59A4B612FEF4427C93D4CEC1 -:10F68000F247A93C5FE42FC37C8DD852C86F29FF95 -:10F69000DE0882479B0C141655D322D968FCFC99CE -:10F6A000C359AF29A0F2CCE8F2B4E54F61BE60EED9 -:10F6B000049DC849B3F97E762B95BF01BC0E30F985 -:10F6C000F7A838FA1DD749375C5EDA91F757D07C36 -:10F6D0005FB919D88EAD31E56D0CBDD162B1CC18D2 -:10F6E00049F8D7D10F503F15667E9CA2723F7DFD31 -:10F6F00060F205EFC607F89CC0A6937FB24E6A6021 -:10F70000F840C0CFFA1EC5CD10BDF49FB76BB79DB2 -:10F7100006CB1474A7EF157457065E99E03552BDF9 -:10F720003B48E3CF9997CB7C66CC5160B830E5611C -:10F730007E429AC4FB943F209FF165BC4BAF97116A -:10F740008F64B9343F09C79B3B4FE2F38959735D1E -:10F750002109FF390BE983E3A1145FEE6CC4F7398B -:10F760003E499CFB627E5E943F1EB5613E379BED39 -:10F7700004FFD309F0397F80C077AB7DCD5A478C29 -:10F780007FE792016EE1E71830F59302E6BF22AE03 -:10F79000252BD91B117CA381F9D4611BEADFA4FFBF -:10F7A00082C1FAF63526BD5BFC6296710BDBC1B3F4 -:10F7B000BCB17AF43BB4274407D74AACE7CE997B77 -:10F7C0007E3DFB5C8164C6DDF455599E99DF35D0E2 -:10F7D000D89EBE9AF49C12FC380DF59028FD7EDE72 -:10F7E0006D67D3B87ECFC7579CBB0451A152F09729 -:10F7F0001A8427F1CBF26B15A697EAB50E8EFFAAF5 -:10F80000695E63CF267CFE21E8025FDFAFEB83F306 -:10F81000EC53658C90B528BF4D554822BACE269E34 -:10F82000C3F08F38C82F37DBA157D1BA66A7831A28 -:10F830004843BCBCF68A8DD4FF5A17A832CADBDE17 -:10F840002D6F8608AF9095EB849388391CD7D657D7 -:10F85000EDC1E70BF5B6611CB755EF49D1A3E3A4A1 -:10F86000D6AFE9C43B8AD7D29C304C35F737919D4F -:10F87000346480E0570F4AC0F22270AD8BE19C9552 -:10F880002FE295B2527547308DF88D66D5E338BBBF -:10F8900007EDBE5EC3310DA15A29F647B48BA7FB15 -:10F8A000AC0CB39F1E9A1444629CD9525A6623B87A -:10F8B000B953748A4FB4FAAD4836ECC4B72A8648B7 -:10F8C00023820CCF4DCA22D24F9362F9BEDD2EF6B1 -:10F8D00005DE157C3F5E0EA21C60BE4F7EFB6019EC -:10F8E000CBAF8A01592C0FB89FD58A4B75EAD0450A -:10F8F0009E657A2185FC5CC31064A4AFB7E5786788 -:10F9000050FC5EE07585FD6A6573F5EB1647EDEB1F -:10F91000E60E391099CFF1503FD4FB503CD4DAF2C7 -:10F92000CE3CC53D56428383F0BD324E3E2E73BF62 -:10F93000CC7AE4B247ED9DF80B1427AAE713FFA891 -:10F940007AAA8B3F88F954273F8BB32F417D89D604 -:10F950003302F931F121A3204566FF32CC13721432 -:10F960001E97C82F267B56D793DC6B97521AE4B2AA -:10F970004E3E39C2DCAFBB14EF4B141F1B407DE978 -:10F980003115BACA01F0B3FE3211E526E9D152CBE6 -:10F990001C99C6DDB814FBA6F37C255C41F9DB9607 -:10F9A0008A735208DCCCE760E3024E95E8FFCBE4B3 -:10F9B000FE6BCD71FD7664D6C7D41F727F80FB428B -:10F9C0007A8B44FC10CB7B4FC3A64807E35A8E705A -:10F9D0007F1B33045DC4EB312FDBDC219B8DF86E84 -:10F9E00080E54E128472087E4681E0B36507049F6D -:10F9F0007D2E801AB44CAAACFF9AE9B9AC0772F913 -:10FA0000D80870FCCC0EF0559BFACE5D034650B47E -:10FA1000A85FF071535FB0F4B82971FB78B9FB7E31 -:10FA200085F8D6E5395DF64BA6FEA781C4FAE21546 -:10FA3000DAF9F99661F12588E54BB97096F70FEE82 -:10FA4000DE732BF90982717A50F022F5A05EB9BEFF -:10FA50005FD0FAE2F5A1EEE2299F1A7071F194A845 -:10FA600041CC27F935D6B2B3E2F0A77ACFF1F9F756 -:10FA70004027DE75E07360D375B40E94E72AD97D14 -:10FA8000D26F1E62BA5E8BF5E4F104CD83C1FFC272 -:10FA90007CAB0DFC14AF003EF534E1A92577911342 -:10FAA000319ED42D1678374A11F9BEA8C8125E06C9 -:10FAB00047C7EBEBBE5CF2471B65C51C1F6BC9E378 -:10FAC000E13683F16404E81954CFC2939161518EF9 -:10FAD000F8F11AF19371D3105FF228CE76541FD249 -:10FAE000BBCA4163FC288F936B15EE990AD17985C7 -:10FAF0002B7EFF0D3E779C6CE2C714F5EBE1C7252A -:10FB0000841F96DC423DF9AE38FBE2AE38FBE22BB7 -:10FB1000E0C7918BC18FC845E247BBFD87EF05CA9F -:10FB2000D89EF5CBFDBBE287D472DB927B88DE8367 -:10FB30002940FBFE74925AE1C679D6548AB8F3E1A3 -:10FB4000BF2F08523E7B452EEB854FA7E92F71B999 -:10FB50005F9497B519720AE6F3576139E69FCEF5BF -:10FB60005650BE66359663FD11FB7C41CA17FC50AA -:10FB70009497DEE97F2985E47C40B47FE1589DECD1 -:10FB8000C1F2509DD9BEBCA182F235F5A2FDC803D9 -:10FB9000A120E507DF23C6B7F4CECB4CFEF9B47441 -:10FBA000EAA5DBA93FE49F9B917F8E3B61946EC3E6 -:10FBB000FC22D56623BC5D1C09D8091F0EDBAA46B2 -:10FBC00012FEC0425F0EE19993EC56B9937FD9C8FB -:10FBD000A983ED262A76D6FB5E95FC0AD59B4624A2 -:10FBE000417276B4EE22FE4EF1C89B51DE1499F2BA -:10FBF000C88ADFA57B0433A2F6AB68A090F356BD9C -:10FC0000EC748117F0B0C00B2BBEB8F52190C8DFA3 -:10FC1000426B633F449778633FCBEF50BFE2618410 -:10FC2000B797539C31965F3E56C419979E3B3D351E -:10FC3000915D347CA0B0E78F9AF722ACEF95A15C80 -:10FC40001BD1CFD3843CBD099EDA1F495F7A9AC687 -:10FC50001ACB200DC068DA47912F7FBCEF7DF57D70 -:10FC60000196DAFC0AE111F497749AFF556DFEC90A -:10FC7000BC9E2A80EFF54AB00E53DE2F093A368B30 -:10FC80003811C17F6699FB764C9DF7CAED6C3F7BBE -:10FC9000743B8E3369FC00A6FB9973258BEEBF3352 -:10FCA00090F4603AC1607FB68FE3DD6F8290830687 -:10FCB000B9298EEE97BB3F7B8FE4D2F22DB174BD94 -:10FCC000025A1DC2DF1C79E46DECBF72438A4AF20E -:10FCD0006745636CBDCA0DBF3F209574E50395165B -:10FCE0001F08C5F2015438041F7868089F7FADCC07 -:10FCF00091B54319E4FFF0B3BC4F0221EFEF52F48A -:10FD000030D35F8B53D851A67E7E9B2CF4F32470A6 -:10FD100069EE42E2C336335E55E4ADF1212ECEE505 -:10FD200054C3CDCC6FAC78180420CBFB5381CBD51A -:10FD3000683F5B079F8FA3F7D2969EAD74DFC0F23A -:10FD4000B3A07EC0F6152C424E378EF910EF9BB44F -:10FD50000CFF3F86D6E5E0753DD4A33FF3F7D548C9 -:10FD600010CE52B28B95E256EA7388A02717D111B4 -:10FD7000F1F769B1F65612083D7E789BF0E38CE806 -:10FD800094FB75B4BF4ED05D42EE3700D157B7F645 -:10FD90008A7B55427B852514F63F7B9AE0EB17B2B0 -:10FDA00057BAB3473AF63309F5364C67FA92B6D3E9 -:10FDB000BA2F3B9B9A92289E6A66B9EC25BB6CA62B -:10FDC000DDC84A4FA0E73F60EAD91DF57D6EEE4FD2 -:10FDD000F1656CA7F825ECB795F87FDBEB8E8471A5 -:10FDE000C98AD9BF6237D444FD5F454EA9287FBB7D -:10FDF000E2CBE67EBF017DE579DA977879E4D81D1C -:10FE0000774E098181D171054F0F12FC6E4281F14D -:10FE10009B81744E94D49FF99D568AF6541FCE73DD -:10FE20007F076FBE9CE3243E03E38271126BA3FC49 -:10FE3000E707D3129F8BBC61F2D7148A7DC3F47697 -:10FE4000CDF8038D7FD421CE5D8E269BA9479C5B88 -:10FE5000BDD3515FF0C788C5276DA2FC687AEC79E5 -:10FE60008D55EF94D9EE50ADCBBB36CAFFAA3DE419 -:10FE7000F4939CCECA37EF71AC02B69FDB9F4FDB89 -:10FE800014BDAF670796A70CA2F8A27CC3D18BE084 -:10FE9000F8BC907FD54AD841FBFBF025BEA334EFD8 -:10FEA0006A0D8C67A81F2DECB8A698EC06111FD21E -:10FEB0006E1776607B9248AD799D1D382365109D45 -:10FEC000CBDE1C66BED8919F1166BE7776A097C721 -:10FED0006D9F65959BF9FF10790D549DE65BEE32A1 -:10FEE000ED8742752DFB5D51EF23BF4DFCF901C03D -:10FEF00078A11F9BF19E46DFBFF3395E777E7E9B24 -:10FF0000ABED95FFC2EFF34D7FB0AFF9D357EED015 -:10FF1000187F0ED3B80B4249C071DFFFA45FBFBD8D -:10FF20005F1BAF677D79A4FFC3651C2FC07EB5152D -:10FF30002DBF65BEBEC2A2FBA658BAEF65C2F14294 -:10FF4000E76AF1E72DDF009D0D1C9440EFFB35C9FA -:10FF50006BC4AF29F274E66BA79A24F68768D05673 -:10FF600047705E29897D59F9EA8D150ECA2F0695CD -:10FF7000F97C533C3FF305494F585E0F2CEF4A2163 -:10FF80003F95E05DB357261F02DFB7D1A2F824DD0D -:10FF9000B7D1A2EC62BA6F139DA7FB36D1F5E9BECB -:10FFA0004D7439DDB7892EA7FB36D179BA6F135D51 -:10FFB0009FEEDB44E7E9BE4D747DBA6F139DA7FB4E -:10FFC00036D1F58F80FFC1F112C175E206826BD385 -:10FFD0001AA74A70C5ED7AAB289BC519E31FDDCB84 -:10FFE00089EE67B967AA6305C2614F8E0CD268BA01 -:10FFF00077B32CA6DFE57215FB0950ED6039E2C737 -:020000021000EC -:10000000FF313CE522B6933F6F962003F175E986F8 -:1000100038FDA1E5DE3AD2B76F0AC57E5F0E517E8C -:10002000F7DCAEE7404B0699F1C0BDA137E1F31410 -:10003000D9ADD33E9FDA27EB4E305D00B4CF5B8560 -:100040003FB214063D349EF7D10E218D8E4744F900 -:10005000A98D722890DB793E746AEFAF0EFBB0DE9B -:10006000D25EB24A74E7CC89DDEF242D76BF7B14D3 -:10007000C6EE778A1EBBDFA9A363F73B1ECE694697 -:10008000ECFE833C9DE1BCBC0F9A77387EC6B45829 -:100090007CB0E03B1AFF27F05563F82E41F83E2C68 -:1000A000D1B9DA3D7BFA685DE15CDD7CAF83F4D7E2 -:1000B0008B85F37D7170FE1CC657B819B830D335E7 -:1000C000B2535F2ADBEBE72081636ADF0AF35EAF9E -:1000D00038DF31E18AFA0BDB0B51E750F5B2CCFA8D -:1000E000CC26A267233385F980BEA107EFD73097CE -:1000F000E86F31F8983F2D8ED36B96BAEF77905E0C -:1001000013BF4E9A0DF95D2A5B845E13BFDE2EFE8F -:10011000A842B5B58FE0DB8D0FEBB4CC168B4FFB4F -:10012000C88F91096D0ED263BAE38333728C5F93EB -:10013000DC402E06040F610AF05F427DB2A6A35890 -:10014000F8E79D7EE1E787401ACF6314887970A3B2 -:10015000287FFF2825C47E073429D8BF64D963F1DE -:10016000F084BED2DAB7B05FF92530E1A8CB92AD0A -:10017000D37F8F56A041FAF5C8CF84FE34DAD51864 -:1001800054B4AEF6F927F9E639B762C67F5EE01CD3 -:1001900092E64F7E8E6BCCF8BB092DA35EA17CC787 -:1001A000B9E4CE57FBD07E8DDFF9FB0C4ADF92B469 -:1001B000C7EEC0F1AF96045EC4DB95C11DE334DA2F -:1001C000FFCB242FFB2BA682BFAFB047423CAF89A9 -:1001D0002E1FEBB5369761E7F328D37F09109E4AAF -:1001E0007AFA32DDC1F358AB7E3095FC31CBC1F4E5 -:1001F000C734C7EE5F177B28CE0EAAC2FDA77EE3E9 -:10020000ED9E047814170F102BEF17145AF7CA45F8 -:10021000BC8A06E2FE77A5E947AA746DF4887338B4 -:1002200094737DA18BDDA410E0C7F07985BD90EDBE -:1002300062B407F8BC5F73248AD7033593CFD56FB8 -:1002400074CF64BE7C637D17BF0EE3F5E2860BAC12 -:10025000CBD413C6D3379CFFE1419A90FBC9D3F7A7 -:100260001A545CD6D63F5A9FAD7188FBB9E0CF884F -:10027000B9B730B8509C7B97997A53A5CB8453611A -:10028000A08EF4E30EBDA98BBDF8F5EEC958F12E92 -:1002900008AFA242C6E306CF9ACCCEF31D6B1D9FDA -:1002A0008C687BBC15E125A74C76117F5CD1CF37DC -:1002B0008CEAF73B103E4C74036E8DF5F593CDC779 -:1002C000F6CB799DEB423C7B701CADA35956C5BD66 -:1002D000F940DD38ECB7BD54E05DF7F6AF8027CECE -:1002E000EBB2C2ACAEF3B2E2ECA7C845A9E128BDBF -:1002F0003DC3845FFB10EF146A57F6C7BE1E9AAF6A -:100300003DAF714F6FD28B6F157A31EE2BFB41648D -:100310003B48A4974E91CFDE42F95339A092FD9904 -:10032000D923207B48CF5B00EC2702DDAF13AAC89E -:10033000FD8AD84ECEBE15ED27ECF7DD5537A6D198 -:10034000FDFEEC944569F96E8A6FC2A90EC0BC64CB -:10035000F38AFBD9CFBCF76F65543E8FFDD2D73BF4 -:10036000C53973EE0FFEB69CE900B474E7181ACFD6 -:10037000C7EF0B44D2649E5FF9B59F0D27FDAAF726 -:1003800059F730D2CF7AD1392F8274A8491F9755A7 -:100390004486FBDD9D70CACC4F6CBF649BF03898DF -:1003A0007C72369D8758F7301EEAF1069F879F348E -:1003B000CF4FF28C69A984E707075AE75AAD59E491 -:1003C000B2AA4E3252E7D03CDF94F97EC567AA91BB -:1003D0009A86E527C1CBFA63A0CDCEE744ABEEAE5B -:1003E000E899EEEE3E6E7F4DA1B06FAAE2E2A2AABE -:1003F0009456079D6755FD9371514D6871273A0FCB -:10040000B3D65F9DA68032145309BCE7ABF7E23F39 -:10041000E48470DC629677777FE3E7E6FAACFB1959 -:10042000D5743F033FAD7ABEBC279CC70EAD3E33AB -:100430002EE61E04D96BB4BEEA3313F97BC55D27E3 -:100440001C84DFD40F3D8560DDCFE80ECED985C298 -:10045000DEA8A67B0D19D1DF051D77F69FC9E54FF4 -:100460009A707B72AF6DDAE604F37CBD50D8DD4341 -:10047000B214F6175CDA0AC6A604E35AF5ACF70D17 -:10048000BA9B57D3A4F07C9A37C505271A6FA709E2 -:10049000476BBE4DE9E1255E71CE3A90DE2FE8C88C -:1004A000AB91FE5747F1D3B3A67FA0E93BE1FEFC39 -:1004B0005EC615C28EED6E9FE7F4F3A5137F18A9F3 -:1004C000B4DEFA4A269B5D407EB49EF35A6D242723 -:1004D0003BF84F37FBDD096739E61E4C57383BB810 -:1004E000BCE3FE19181E299BE410B03EF0D01F4B50 -:1004F0001C0E1CFF980D22C477A6C87DA7BE4079AC -:10050000B41F882E8FB1ECC07483CCF7998E3D9ABE -:10051000EF20BB6C49394464E45BC7DEEA5F477196 -:1005200097DA02D424C7A1BAB336F6FCB1128C3DD7 -:1005300029D8EEC603DED456CC2FBA27568E1D7BA3 -:10054000EBC70EB207A4856E3FC515E13CA7BE8080 -:10055000F9C5CD0EBE9FB5E4FEF8FE62F5E06C5322 -:10056000DEC6EBC39F179AFAF048184972E685DA9F -:1005700066F17E8E791F11F53F23119E587A7028FF -:1005800079D2DF99EF43A34C7C699C92B8FE92220A -:10059000B10F2B1F3BEDF068DDD3D971E42705388F -:1005A000FE895A95D3ACC1866B30F63F60B02F659B -:1005B00030B697B548FF4FD8CF29CE4111DF385F0D -:1005C00043F7D448DECE157A8253BEB992F5D13EB8 -:1005D000A006597FF1FBD99F6E43FD248DE2376E53 -:1005E000913DEC6F10EF078DF968511AAD37F3BFED -:1005F000E73C4D70A53B0E40EFB0941BA5C4DFD780 -:10060000CF70F379FF265B80FBA140ADBB109EA1AC -:1006100027C7EC26F77941E3BD93C8EE535B76B567 -:1006200092BD526FFB740FC525D44F043DC8D00E48 -:10063000F138352D339EA6F6FD67BA75BA5FBA3E1E -:10064000D72855A3FAD720F21EE99927AB6CEC37CF -:100650003DD5FC0B3EAF42FB2E42CAF7A9AA3CF6A1 -:100660009B59713F7CF697C06F7802E51B44DDE72C -:100670005ED1B4C946FAF8A5B451517155D6BCAA99 -:10068000EE6CCDBE8EE4EE130ACBD1CCDF5CC1F1B3 -:1006900003B98A26113CAF9354A18F9A7AF2B560C0 -:1006A000FD35BC42FAE942D293110F3F94421CAF90 -:1006B00069839667A9FDDC1CA10F82D63882FCD71E -:1006C000E12AF37DA2E5F634D26FAC7382EEF0A19D -:1006D0003B3F0FF6B4E41D1CF7A404EC6FAAB14530 -:1006E000FAD3FC8EDB13CBD779834D3E30D01F621B -:1006F000799E0EEA6334AF025F2ED165B54D5BC9BA -:100700007EAF7D5E8E0F6997D4F498775ED4865F56 -:1007100093DE5D6353857D73C028A5F398F6194574 -:10072000FCEECB497BB83FF311E47B149775EB13D8 -:100730004D3315845B756FD4BB30BFF9895D3315BC -:100740007A87272FBCC486F95707FF45940F091FE6 -:10075000A6FC1F9FF848940F0B2FA1FD39F9C4691F -:100760009127030C11EC6F4FFCEFCC00AEEBB8E916 -:10077000FF043D3C9FE659FDC2205BB47FF1C86099 -:10078000C1378F27897AC773E186AB49FF280CF3FD -:100790007D18ABDE6B83CDFB0426FEDFF462522BAB -:1007A000C5095BED202771FF41B3DD4DE67B59485C -:1007B0007FBFA27A2FE768E9BCCF479147115C9EC3 -:1007C0001FCCE73D370D4EE7FA049FF4A2AEE32DB0 -:1007D00023394F72C01E7BFFADC1DC2F2812FD579D -:1007E000F756D3683FB2D3859D811B927617BF63BE -:1007F000B0C9D4ABC4FE64CA6A695065B9339CEC15 -:10080000E697CFF62D65BBB9A29BFB9E83851CBBEB -:100810002928C689F4D2D4CD7CEF1C0C8A4779B93B -:10082000396973F47B29274DF81E199C26E0D7B14E -:100830000F3D251E2768C2A52FC2BBB8137FACF69B -:10084000175AF7F67FD1BABBEC5399989FB51E8023 -:100850007B051C707E69A8E71F5F63B61B6DCD43E7 -:10086000637AB8E9C5DB3708FEA7A5B3DD0E3F11F3 -:10087000707059E316F1F9E40A530F96036F38C804 -:10088000DE5851DFC6EFAFAD6814EF6D75D29DB184 -:100890002A9ACE32F3C53A33652333C8F488EB6322 -:1008A0007A34CC788358FCE980773C1D77E94F4B4C -:1008B0008FED4FE3FEBADB87B08917DFD83E041314 -:1008C000C3B383BFC4C1AF831E73CD76458867654C -:1008D0005DE9F18FDDD171EED71CCFBC77B2E27646 -:1008E000335E558BC5E3154DB9B685459DF5EF6E65 -:1008F000BCD71B1D4FEB6A5A1020F957D352CE714B -:10090000B52B9EDBFAEB00B65FB6FD010F05531F5A -:10091000531AB2492FAE7A6C9DC7A0731625E021F9 -:10092000BE792C244F4B747F75D41029461FABA67B -:100930007F62FFC79FFC5BDDBFE1FCBF9050BF4201 -:10094000785737FDB58EECB73D862B4272FBA81267 -:100950009E4A72F4A6056E3FBD2F58D31CAB4F2D97 -:10096000FBE503D91A077707FAD8589F6AED43EDDC -:10097000AA1FB5EB64BF57EF93751C066A20524758 -:10098000F38B6F5FD3F8A183E0AAA23ED8775CD740 -:1009900072E4248CF7354D3FFA54F6507AEC1D285A -:1009A000A1FEA2FC1108F7CA6EF4B2C221B1F7028F -:1009B0002CF840288BF59BE0130F95BC8FF33AF190 -:1009C000E86B1EA9285A5EDE29CEA91A6FFCF90B26 -:1009D0005AF772F524E907CEAE7A80D62C0925BBEA -:1009E00045A455F6560FF905AA36D9F5007EAEDABC -:1009F000FA8BC7E95C05DE76EA74F458B5F5B48382 -:100A0000DE3FAB928C88C47A1678A4919DFBB47CAF -:100A1000EB47C25FD54B86E9B84FCB7EF5B9A86FDF -:100A2000402409EB2F7FFA7DF66F55F9DC7E578263 -:100A30007DAA68DCE508BB13EC53E3FB53490F0ABE -:100A40003EF125EFC3B19D12F4CCEDDABE72D3476F -:100A50000EA29B13B8211969025E649FD634CA0B9B -:100A60001CA989F6ADF52AD2FFB09CFD2017DA3F0C -:100A7000D7101074F1DCD66D640F54BEE3D4A7D345 -:100A8000B8DB6EF100EEFF11C52FF0FD67EBB20D84 -:100A90001CB7D21EC8563915DF2B1FB995F170E966 -:100AA0009BB766B35E07462FDB685E6F2F5AE7E29F -:100AB0008DB3789D4BC0C77858F933E1CFF85C818E -:100AC0006989EE1B6F1F22E487136E2E21FAF81C32 -:100AD0007B223FCC11078878DEB7C43B644EB83A1E -:100AE00035FA9DB93B8708391080D07BF4FE640D40 -:100AF000DAC5C417E4373F9F4AFDACCA55FC4E9592 -:100B0000D71F30E1259D13F11C9A62C59DE6E17E59 -:100B1000BD39A527D9C14E38E5B8BE8CDF69D0C82C -:100B2000FF1BD58EE17664B33359423BFF4876E232 -:100B30007B84EF99EBC0BFB7200A9F6AB61C617C2B -:100B400002B4BB527344FE61A243B48B52116E9F38 -:100B5000EDFBD0D19BFC1D99361840F36DFB88F35B -:100B6000A0676954DFEABFA6D919F32E49CDA31FA8 -:100B7000C5D1B333EEBD133FC3B3065235D2378F61 -:100B80003822535FA471705C8AD75C72BF33E6BDB4 -:100B9000B04E7C71747ECFEDA44FCBBE5A6AD27F2B -:100BA000FCFAE3F9C19371FC0036667DA5F79FAAB4 -:100BB000ECA1C7093E5548AF01A657417FA8A347FE -:100BC00006203D7CFCD44BFBBF4F7EBA467BE674CF -:100BD0001E2D96CF563E83F44BFE348477924E7C86 -:100BE000F64B07E9BD39156807E3BC3F76EB74297E -:100BF000AD2BDDE2F78474EB063ED7FABFC55F97F5 -:100C000076C35FF7C5C1F373284AA53B0CC79F5C49 -:100C10007E09FB15E2E06BD9BBF17CB37A88C67024 -:100C20008EE79BF8B71FA2E0B8ECBF3F61BCFDA206 -:100C3000973807AB7EF4AF2CBF10AC1127E26D756F -:100C4000E853CEAF23F9C5F95D33E9BCBAEBBA631B -:100C5000E1195FBEC1E4471DF7DCEE8400C5DD4548 -:100C600076C8FC0E433BCEA58EF4F3A772F99C70B8 -:100C70009DA9EFB7AB110FE9E7EBD2AC3CDC40EF3D -:100C8000C1B4074AD400B54F32E30FBC114F5A9498 -:100C90009EF47E8BEC21BD2E1C826989DF050CF24F -:100CA0003CC2D05DF91A715F4B3EBB2D6CDAF54E3C -:100CB0001C2FBCE6CB6D746E7E4871F1B9E5A23590 -:100CC000733C7CFFAF25FF3F092F16BF8A70247A43 -:100CD0000A188E5E08E71B0508D0FC08F079B09C66 -:100CE00052B6E745ACB704014CE724F1FE9465E049 -:100CF0004D6DCDEDEA374139E820F9BF14E511FB20 -:100D0000BD37C6962F6BF998F16C591C9EF908CF28 -:100D10007A75C5B3DC4B4DFF4A29949AE7BA6CCF7C -:100D2000B7EF95F93CFF940B58DFA0735EDC3138C8 -:100D3000D522F3FE9C7A4A0A71BC61204BBCDF8A43 -:100D4000F84E7A968587F1F67D7C7AE2D97747D29C -:100D50003DB1AA5FFFA5E4BF303DF1EBB707BE4848 -:100D6000F9E7FEDCFF2FD0B57EC5CEBFB21DD3BEE6 -:100D7000D3C9FED0F69DBFED4F72B9FD05A74EF861 -:100D8000DB7EA753C435EC4CE177CCDAFB09BF5DC1 -:100D900070C7972561965B6B791FA75FEAE0FD3E00 -:100DA000D5F2379623A75A9C1AADA366670FF68F24 -:100DB000D5BC901422FF40FB8E2F4746BF77F5CF5E -:100DC000AEA7DABC4FD39E0273296EA63D4DC4591F -:100DD000D6BC38E6176BC81E69DAE520FF7FC56F01 -:100DE000FE5E427CA9FD995D0EE25B68973E02883B -:100DF0001F732EFDE903F65E745F0CD8DE3E7DE9BD -:100E00003BB3E87DACAE701170684738D0BA102E95 -:100E100095A49775078FEA6F2D3C3E657BA2AA6566 -:100E200014D351275C24437C4F09B9245AFFF31E85 -:100E3000F21BB5E7A1FCD769DD5F9690FE74A17542 -:100E4000FFC7A5E27DEEFFE7D76D838B5AF753DF2F -:100E5000DA750BFC1F76A926DEA78AA383AE78FE7F -:100E6000DC0F38BF2D45E7F97E45FA7FFD5BBBFE01 -:100E7000AFBCEF25E4B7BDD87DFFF85BBBEE0BED53 -:100E8000FBABE6BEA7A874BFAE7DC7DFFBF37ABF9E -:100E9000E2BA938BBEADFCEDFCEBEED08F64AF8B72 -:100EA0009ED8BA075ADB344CD775A3A78C2AB2FC5C -:100EB00010C21E914D7D631D0C3336915D857A06FF -:100EC000D901EB3245BE1EF50799EF0F72B00AD477 -:100ED000F7D5C5BBB68A1F54CCDBFF7C23C7B3ACA8 -:100EE000CBFE0EE495D17985F06304D7E8BE5DD8DA -:100EF0003E9866D3823A3D57B5D2B709CBD5DEB21C -:100F00004AF6CD3AED6A57F43B168ADB1163A7B86F -:100F1000E3EC8DE402478C5D9204BB55F2C327E9F4 -:100F20000AC7FF3921AA3DD6CF2A12EFF42743285A -:100F3000A0BA2F1E4E8BBE3E9C5C7CAF5235E104A6 -:100F40008641EB766A0AEB610AA0FD28D621EC4EB9 -:100F500084A316054730ED50C504B9A20D6338A22D -:100F600001A14D1A4D70F5331C83BD6495E1DAD9AA -:100F70001FAF3B7E1FD6699320CFD4C725FD9B872B -:100F8000F3D822111F100F672BCDF795AF21FD77F6 -:100F9000D51A71CEF5CCEFBEC3F9263BEAC374CFA8 -:100FA00030D5B7A288FC8E5E43223A5D3543BC2F14 -:100FB0005846F7C032C9D41771B899AEBEA0B0BFB9 -:100FC00012ED0CF657AA40F69F3C091AD91FE855B6 -:100FD000E2E27A558E7B0ADE2CE29EA01034F14EBE -:100FE0004B6CFC4F601214525CC314B9AA81E675B5 -:100FF0000A521A28EED2616FEDCFFEE17E008F918A -:10100000BFA5FC8B8D549E8B7A3DD07D32A5F53DDE -:101010008A6FB84D4E058EAB8AE0A728B85D76C6BC -:10102000054A149CCB212D267FA2DFE126B213F2C4 -:10103000024E9582C72A5CBD62DA9FE87586C70BAF -:101040003A5D2AD94753D4DC98F6B267EF7B64D770 -:10105000BC916E63BBE0F29CC131EDAFFAE0C4C657 -:101060000526CED23ABEF7AEB8A78AF6D623AF632E -:10107000BB37EF0720BFF1155A694CBB66D3BF12CF -:101080009962E7F766AE2C1C13336E737837C3A5ED -:101090002A0B243A0FAEB2214960BDEFEAE531F5E3 -:1010A000BE37FA8A987E67183362F255ABBF0025C7 -:1010B0000360DCEAB340EF0796B636C6B41FBEB78E -:1010C00039A6BEE7753485302DDDA705291D75507D -:1010D000DC231D8EFB41E71BCDE1853AC5EB14D324 -:1010E00005D0323A16F0565018F2C8A3FE9728BD24 -:1010F00050FC3298EFB2269BE7AFEB6DA1C605B965 -:1011000014FFD3F0E35D12C743EE263C1D1D69A812 -:1011100048C5EA63CF34BE446953DBF87A7AC7B373 -:101120000AA08DE5AFDBC6E70253E4961289ED9F76 -:101130001EC39D51E72EDDBDD7F9A3D2F27D4548F0 -:10114000476B738C865DC4F727BD3B5FCEEB5A0FB0 -:101150005425128DE73F2AF51EA6384D2B4E2AB98D -:101160004216BF4771B98893A9B3E94926F362FDD6 -:10117000409D6AE738FE65C582BF8D6CDBDCE82EDA -:1011800023BBD3A5D1BE2667C4DEF3BE71B4B8B706 -:10119000F7459179BEA2A859D7931FBC3845B4270B -:1011A0001F1F8D37DDC6FA94E780BEC78EF9FB0A94 -:1011B000F7A9C4CE9AA67F10E0F74D0FB44D903436 -:1011C000809EF794DAC80E87BD76FE7D99A6C2C9C7 -:1011D000A70BA87CFA5B1CC3B86BC22F0B49BEAD32 -:1011E0001C3CE4BCEF8C7ACE48A045C5412C2BD6E4 -:1011F000783E1E25CCEF1279CE285CEE99A7DBFA5B -:10120000478DB77282D0FF560E4EDE4A78EB3960BA -:1012100088B8A842B73680E9239CC37C4209E75CC2 -:101220009F22E2ABB4F3BCF37F7CCB88349263198A -:10123000E57A1AF94133B6CA1DF7CE683D3FA6FFDD -:10124000D0C13AACDF3F19E7B58562D744792BF2BC -:101250002458EFB0CA9125613E43B2CAD7CF9E5CF5 -:10126000C4EF31C6D41F9AD751DF70E574F6AF15BD -:10127000AFDFBFB688E037CA467125EB7F67E777F7 -:1012800006709DAC4FAC447A06E97CF0EC710178B5 -:101290007AB8FC90A4C5BD9FDB5A4CF982BEBE4112 -:1012A000C558FF92B3A9FC0EC067F5492CFF2E3933 -:1012B000FB3D7EAFB3C961F4BF9DFD37491C6F365E -:1012C000E3E68F37AC26BABEEA7821C52858EF5737 -:1012D000D6A85F303FB0E2EC3AE187F88B78FF6345 -:1012E0005B679EF883A7139E06BDCFB53E0ABEF48A -:1012F0009B2F334C78FA8A37CE5E8BFD6B8BA6E53D -:10130000105D9E0637C7F59D561F9F4DF33DBDC529 -:10131000CE41B44D26BF0C149AEF11648673E85E7B -:101320007EF19B368E473A88F860203EE4B7BE993E -:101330005E4CED3295748A6F383DFECFFC6EC2E98B -:101340001F0207172F0B3B185E4D998B2ACA19FFF6 -:10135000B574F23F58F06D34FB79B8D4B8B298FD4B -:101360005CE67D1163EC45BD3FB96BC2977C2EB046 -:101370003617F5FC340A393E5347EF4BAECCB5B3C4 -:101380005C5A99F6C5D44CC2F7725784DE81A859CD -:10139000FD19C317BBC98DBE07A69C91418B8ADF7F -:1013A000D2868AFD571483F75F39E3E0F2AAD5A706 -:1013B000996F5BED4F98E7ABF42E23DD17AAFA8700 -:1013C000CCF746911FD64BC328DDED5819C54FA069 -:1013D000F1D30E3E3F14F7EABEE96F25939F728664 -:1013E000A4CEA2F9B56C3B339BE2056624A9B328D1 -:1013F000DEA06EDBFBB329BE60463F7516C517DC69 -:10140000573C790E97F7521FB0A1FC7AB964BEC859 -:10141000E7AA7FA2FC535BEF98C3F553C4BEDFB6C7 -:1014200075CE9C00F36337D3C1A9FA1E21E779E892 -:1014300060E9EA1721FA3DDB2EE5E6EF49C15CC120 -:10144000F73EB9BB0FBFDB09056D1C2FB6BE58F8C0 -:10145000FB3BCF5741A5F3D5CC7C30C8DF9CF95C72 -:1014600092F85DA2436DFD097E4736DEF203F2A7D6 -:10147000AE9080DFD1AF026D24D1D5425BF83D4AFA -:101480005F1CEEBBB798F5A9368E775DBA7A27CF89 -:10149000EF53DD8C5B562345DEAFF54E04F69FF02F -:1014A0009D88D838E30F6CDA40EA5731E1B2506ECC -:1014B0009BEF10F37A94E6B5227D17C7392B6A5B50 -:1014C000B64FE851856C3FE524F37BD175BDDF292C -:1014D00049F43B088DB528EF91E49EA96DE674F5BB -:1014E00050607CEBA9841D3AF6537D40C89D916DF8 -:1014F0001F38A2E319779BF04D357FEF2A3E1E7708 -:1015000037C9A5A8B88315BD5BFB927E68ED6BE774 -:10151000BEB4F635F70568BE99192F3D45EF9D50CD -:101520009CEB0FE93CE3B9A456F25B778F27D63EDC -:10153000887937250BBE11793689F5A6F8751C34E4 -:10154000E76DAD2762CADFEED61131E5EBBF6A1D4C -:101550001193BFC7AFC7A26FEBBB45DF5DDB8BF954 -:101560005F3CDE897B6D17C23B8BFF5483AF50DC41 -:101570009716FCC682B7354F0B6E4DDDC4E32AAB20 -:101580009F8F598FD236898C1E482D11EF5F298D80 -:101590005700ED87B2BA85EB75B71E39E5333EC704 -:1015A00059A6819FF4DEF875554123B7EBBAAE0812 -:1015B000F3E3159AE0C75DE3F823CC9FABD13E235C -:1015C0007DDC5A77079FC6F5137D4F4086C37C9319 -:1015D000EE124A645FF862F4E372BA31117D6EE58F -:1015E000BA39263F45BD3DA6FEE5396B62CAAFD08C -:1015F000EE8E29BFB2F0DE98FC77F59FC6E9F79B27 -:10160000E2F4FB2762CAC787DB58FF7EA3761AC7BE -:10161000A74F3C1A613DBCB556E5FCEEDA1C4E5FA7 -:10162000AED598FEF7D41672BAB756E7EFBFAB1D2A -:10163000CDE9EBB506A76DB55E4EE3F946595BB84B -:101640008CFCFBA33353F93C6AE350DFF525140708 -:10165000B92F5244F837F640E34B240AF2439FBEB9 -:1016600047F54EAB0E8E475CBB6BCC1F6EC17CC684 -:10167000EB322469E7D38B6430A2F0C7333D0C749E -:10168000FEED01F13E567CFD8525424F9E0B61F13A -:101690009EC06A3E0187B92EF5152393C54684EC9A -:1016A000F6B9E0673DD4B65ABC5333177428237B90 -:1016B000D607FE7B381E29F67D01AF3163DDAFB062 -:1016C0007C36DD3BC5F6DF7737F2BDF267F6A64F15 -:1016D0002EC5EFD77A25FE9D8F033BEFBAD5C5F611 -:1016E000AF75FFF41DDBC5E8130B4B047DB54B7ADA -:1016F0001BCD379026DE2F8A6F37CA5CE755C108AD -:10170000EB1F11D43F28DECCA2CB19EA2173FD9A3E -:101710002D750CD1C71ABEDF50D5A6E94184F798C4 -:1017200043822E46205DD0BE8D3D2AE86024D20142 -:10173000CB41D33EB4E800EDA997A8FDA983A03B17 -:10174000B17DDDC41FC9647F8DF92C14A4F4B2B33C -:10175000915DE7B07C5C9BF8DDA40BD993965EDAD3 -:10176000523B97F16867AD8FD3D6DA4A133FFD9CA1 -:101770007FB97635E7F7D40638DD5B5B6FE2670348 -:1017800097BF5EBB81F36FD4864C3CDDC2DF3592E0 -:1017900067089FBB4B4C39ED2A37ED0A917A8D359E -:1017A00076BEE78F9F889FCCA5B9127E544A21E26E -:1017B000DF75E9013BE5EB92690F68D601AE7F9DCD -:1017C0001B5A490E54E5BC28F4B0383C29CFBC86DE -:1017D000F164A619C77A20BDEE5607E2C389C6FB9D -:1017E000ECB1EF8D5E1C5E2C73AFE57B7DF17CF17F -:1017F000267A8F42EECA0F0174BDAC4CDCEFA238E2 -:10180000BDAFCAEF555B9B795F4CDC7FA9EEEBE681 -:1018100038DB7F9D9C514D39030BA87E87FD9D7C55 -:10182000703EBD8FD7052E71F6F7E141627F2DFB2B -:101830001BF54CF64BB58764B6BF2A731B3C6C7F17 -:101840008F8E78683F6FDA2103EB8B8A38EF5D4A21 -:101850001D6914D7D3BA7F1CCB99557B882F2D33A4 -:10186000CF7BE3CF6DABE9BC574A04EF30C7D52F30 -:1018700037CF7BE3D75D3DFE089FF7565FE05EE91B -:101880007B25B1BFE7137F7FB73B7CA17882E8F768 -:101890005C4F9EAD653BEDC8B63B1E0AF4FDD7ED2F -:1018A000DFADA5DECF4A441C35DF9BB3F6B3CEFCDB -:1018B0005DCEBA492EBEC7D03E42E5F76FDA25F1BC -:1018C000FE4EFB5F415FA3D1FB3AEACB24172ED338 -:1018D0001DCC574787C57B01E3E95E6282F702268C -:1018E0001C0A0553A8DDC100FBA3C6ECF305E9DE25 -:1018F000EDA8D70D99C8ABF465AF4C7860C9274BFC -:101900005E75D295796F8E6232F2BF3AFD698B4671 -:10191000E7907ED761B7BAA7F23B45A75B81A349A1 -:101920002DBFD8F083864CF712461CF20549DED64F -:101930009976E6A813013915BF4FF8CCCF76D018A9 -:10194000B453E552718FDA8882AFE5D7B2F89CC5FF -:10195000D7AC7B7BAAC3B785FCCFF04212BFFF1286 -:101960003FEF41436DD67BD6838612DF33EFE94DDF -:1019700091CFEE3A4776419B8817B8E46CFBE3645D -:10198000F7AC7AB607DF53BB907D50A39E4EA89F5D -:101990005A698D4D9CA30CABD08693BD497A2BD947 -:1019A000A1965D1A5FBFAC74D2D8A15934AFF16D66 -:1019B00006E1B76A3B2F7ED7ACFEF4BC76A1357E3C -:1019C000CD8E11EAC228BFD5EAA19219C7F2F5DE81 -:1019D000A19E10991B23C7BEED7A1FD26119E11792 -:1019E000D98624A7BE4F3B80EBB80E5A595FB9DEAB -:1019F000FC1D8B1B001CD1F7646F0483F9C39F741B -:101A00005F0DE1CD6288CCA77C8D14A97A1141F8D5 -:101A1000C9C4716AAED6555E5FAC7C4E36EFC1C6A6 -:101A2000C3FD4E136F2DFEDFEDFEC4F1FFF65295A0 -:101A3000EF41B73F3BCE46E738EDBF97F9FD54ACD9 -:101A4000C87C25384CDC3B1D3ECF7C8704F9CA009E -:101A5000BD2B5F393D7ECE64F61FD1C106C59F2ADE -:101A60007AE1F551F7CD82E6EFBA6CC194E22553E5 -:101A7000E78595E8F3B39F9AF32FBF7632903D74D4 -:101A8000952AECCE292EC84C225E78F674D12C64AF -:101A90001057913E3B9CDF617F98E0DCF10E08F12E -:101AA000A34B70DFDE17E77C7093C4FED2E626916D -:101AB0002F5E9CC6EBFAAAFB883DF728C1F52F6E76 -:101AC0005286117D0F4D8FE4115D168F793B5DC2FB -:101AD000799598F7B170DAF510F5FB56EF9AEBF8B7 -:101AE0007CA8B18DE63734BD6DFD7DA45F3E6B03F0 -:101AF000F21B1E1973FB128892CB9ED249BFA27AA9 -:101B0000DB25F39DBA1DE2F70CB04576B47FEB4FB1 -:101B10007AC5F354AFD5F433C0AAE7F91EFF0C55CC -:101B2000EC014CCE327F4F32D23FD1EF0B59E75907 -:101B3000430996C2FFC8EF8A6D37FD936F0EFD60B3 -:101B40000EF917A1359247F3389224EE517B4A7D66 -:101B5000BF233E3394FCBCB48E9F09FFC091343F39 -:101B6000DF23791BF9339D1FFFA5D6C5E9BB681F8D -:101B700051FA3F681F51FA3EDA47947E88F611A564 -:101B80008BCF60A7B87F3374E36DE6AFDDACA37B8A -:101B9000FE1230F5FBC4BFD3F49609FF92A643773B -:101BA000F6203C6896393EBAF85985F5D3932DA3B3 -:101BB000627E9714E9F530ADAFA4F98F3FA17BD6D3 -:101BC000254D8A2A69742FFB7436C71FC6CD8FE056 -:101BD00040E70D911D0EF17B4AE67CB7A7B5ADA796 -:101BE000F6DB9FCDA319D2398EC0C31DCE84BF377B -:101BF0006CC5DB3D3154E85FDF7346CAA2CF1FE3FB -:101C0000E3D3D80F3C86F0B9E00F344E60AF0C033D -:101C1000182F63FD1BFD74710FC14A8B7738384E46 -:101C200079FB8EFD575F89FDFD1F8FB61B3100804C -:101C3000000000001F8B080000000000000BCD7D9D -:101C40000B7854D5B5F09A39F34A32934CC2000957 -:101C5000123809AF00018664121212E024048A8A45 -:101C60007482D482A28EB462541E23D29ADED23FF2 -:101C700027244012830605CA558401C1C7FDFCAE66 -:101C8000D102175BF44E50A9F6B73422E2A354C731 -:101C900047552C4A8A62EBAD2DFF5A6B9F939933BF -:101CA0004C0222FC97F0E9CE3E7B9FFD58EFC73EE9 -:101CB0003BB3265E5E24C900A7E9670A80CBDB1729 -:101CC000A008604CE9D70FDCEFC1F2599BDB0400A0 -:101CD000F360DB3437F6BBCED1F1A21BEBD7BBDF11 -:101CE0009B968EF51B334D07A8BC49CE999E812546 -:101CF0004088DFFF515EC5810CACCDF456DB024E4F -:101D0000800A9000F2807F4EE37F531D29008E6889 -:101D10007D9ABB8FA1FEBDCCCB0CFD2F978718DA27 -:101D2000AFCC1B6D68D7E79DE92D34F41B97D19597 -:101D30001B74D23EBEBAA71CF70326080FA37DED85 -:101D4000FEF2EDDBB19C35719E8FF67F0CDAAE1999 -:101D50008D1BFDA4A479E3FDF4B245B165F503B88C -:101D6000857EC7F6E3103E5286ED926BF9813BF11A -:101D7000BDDB322590BC00359BADEF4762D6B10488 -:101D8000FC6961EC77DB0EE37380882DEC03B83DD2 -:101D9000E00CB62000173D81ED0E433B8FBB78AFC2 -:101DA000CD4DED4BC0126DCF01A83D9AF3E40B3140 -:101DB000E38DCBE8BCEF7E1C6FDC9E39EE065CDF6A -:101DC00093A55F0F90719FE55E97E723040D4C800C -:101DD00009A711E42039CD80FD4EBD2485245CD7B0 -:101DE00034E99BD4483E3EAF423C67E17B26F90F85 -:101DF00065D8AEBE2CC14E1CE76F75F2932F5869A3 -:101E00007CB8D19F1FA50B80950C5FBD7CAB0E7F6E -:101E10001D01F0C73A07977FAA7373F96E5D269785 -:101E2000EFD5C95C7E5097C7E5AC431068C7F1FE9B -:101E3000FCF7F1007D681C15A06FB41C67F39A07CE -:101E4000E03ABA7E2F85B6E37EBF289F9006B4CED7 -:101E50006F70FE620D0F4802D5448CA5F8DF8FB776 -:101E6000BD98E5E3E7AA0BA75AF27709141C77B9E6 -:101E7000D724C65DD4F1629627DA0ECBDF33F48720 -:101E800015A603867A638EB1DE5A7120F67D1D0E8B -:101E9000F1E52D9BEFB0055C58AE372921E799EDB0 -:101EA000FA7AA6ED4F524C389E659F3D64C7FD2DD2 -:101EB000712BA0607F0B80D29E7FE67B00F50CE744 -:101EC000791204DB138C5B47E312BDEF4F02E93C50 -:101ED000C67D0B6983D6A3FE973DB413DF7B2B4DE4 -:101EE000017FCC3C2DDAF89FA5B7FDE22BECF7D9AA -:101EF00033404FB00E73693D63777D6C3663392E86 -:101F000059D0C95877C49C81E5899A7F6C3CE261BD -:101F100032F59B26637B6ED71107A2FCBEF6AB366B -:101F200039106F6F9BCD00034020BE04FBE31854B3 -:101F30007FD07BD5DC46FCFDCAFD4961F379ECE737 -:101F400041E445A6A34AC1EF3710DD88791440511A -:101F5000B37415E8F32A241F68FF547FADDDFFE654 -:101F60007AA233E8DA48F2E13840B885D7AFA4C6A0 -:101F7000F2FFD2677FC2FCB9280BF99E04E066C16C -:101F8000BF0EFC773A97F83534DD89EBBD358CFC14 -:101F90000F179FFF9FF13AA37C3E22219F1FBA1289 -:101FA000EB4B9F91BC766C3EB96F98E0278DEF7537 -:101FB0003ED7E1B87493C47CA9D73FDF27CD08256D -:101FC00080F7368D2E86285DB369BE65CF5AA00591 -:101FD000D7B76CD288FEB1E3C7BFB7B44902396640 -:101FE000FC279FB3D710BFC8D0D5AF1AF967DCB3B1 -:101FF000A7322AF24559CFF868D3E44DD720FF180D -:1020000094D726FF9F7E8EF301E27127C2A7327319 -:102010006E36CD3FDB094ACB7806CB1C07CA89ABAD -:102020000588E0EA92EBB201E1B919D12521DDCDB5 -:1020300051AA5FBF0EF1F80373E02A92F3C7BC43C5 -:1020400078FC6B5CCBAD606672CD36E17873E7D817 -:102050000B693FB31A045DBF9EDE759C9EBF3E298F -:10206000C5D480EFBD6E8246C888EEE375AB3F9B5A -:10207000E80D37EEFE08F163524649A7537A9617EA -:1020800044C91FE97894A2F26F9AE454699E936E52 -:1020900033D3BD25ABD546EBBA154207149C7789DF -:1020A000376C23F9773BB82D5462D1D54D1F447F4F -:1020B000E5FFE8388DEF2FE9944226ECDF5ED70E7E -:1020C00016C4EFD3757BB91CFCCDE0C6CB101ECB7C -:1020D000C7DBBC2DA4B734FA32AB26389D405F9DD8 -:1020E000499F96683BAEBBC2E10C4BA9F4D87A3C41 -:1020F000761D8DD94ACA78DC8FBAA63C9DE99368D3 -:102100006170749FE36C004E92F33B5358CE1F7B7B -:10211000AED84C783AF63B6BC844F52D23DEB8D3E5 -:10212000C7752079732CC36BB6517B466E48C5F6D4 -:102130005BCCA0925C86ED426E3D3FE9AE77488E67 -:102140002DDFE932D94D828E653401A447D7BEF325 -:10215000EF38CEADC8AC766F546F2C9AF2E8C62734 -:10216000900E1699DBEE29C767A7203CD68DF0FCB0 -:102170008BA97D38E9ED8F1FB287CDF4DEC323B77D -:102180004B38FECBA98191B41FC854FAE7E0F39A0B -:10219000437DA105DF9FFAE83F0F92DEBCF5C9BE83 -:1021A000CC5F3ADD4F233EC4F59C403EA4F59CDC59 -:1021B0003784F92E8A7F0187C5280FC8246ADEB1CB -:1021C000CE4FF80C24CBFCDC02AA7219E17BEF4D58 -:1021D00040765381645288CEBB9A115EA633E9499A -:1021E000196FE6F7169951BF121D06E44282C7091E -:1021F000935CA0F105D07ADE7F6EE4F6167C7FAEAC -:10220000D63F4A774797FC86E86EB3DD6BC7251C3F -:102210004F32EA7DBD9C393E9DF9E516C79760298E -:102220008C3E5F52FBB5B19E0F0AC98D8206B9F094 -:102230000E2CEFD4E07EC548FFF7C7E3FBB7B5AF80 -:10224000DBF38A4CF36EFEE9DB34EF4B4E9E175EF8 -:1022500011F03B6112FAA55BBF3AFECAE3A3E4E1C9 -:10226000F5EACF3F7EE88DB1011CFFE3DDA38703D4 -:10227000D2DD02A9F3A307115F9FBB3ADFF93996BC -:102280004FBF74A81FC12F7EBD8B6ABF004B8C1C33 -:102290003A6E32F17E17D13EF0F96F0AFD3733BE48 -:1022A0002DA827106E0B5AC66C2779304DCA4F23C4 -:1022B000BBE9C431E3FAE2D7A98FAFAF4F1F5FEF9D -:1022C000B78CE08F709838CE2DF4ABADF373C2EFBE -:1022D000677B469B9015A3CF333AC7A6E747F1E447 -:1022E00057EAADD4EF1A12F5888AB90E81D7B935FD -:1022F000A650430EF7E3F6EBF039E1BDC2D3C0F5CB -:10230000394ED467D87F51E66F785D24E81CA8D792 -:102310007E00FA4FF5AA5F61BF3797A5B25C987B44 -:102320004B9B95ECDC6E79A6BE6D3E3DFADBCB3364 -:10233000849EECEE07CCC3A43F013767C1FA24ADFD -:102340006E2AF963C3AF483EDF99EA95D064841AD8 -:1023500019C2C4D7272144F05E6D0AB2BDE7203D03 -:1023600080658BC99B69C1523277F5019E27C47085 -:102370009A06010BD57F6B8A3400BEB7CA539949C0 -:10238000F4FF2638FD6417FD207DF51892A395EE25 -:102390009973E9F96C35D5DD82FB6DB4CA77E793A3 -:1023A000FDF303C94B76AF0E175D7FCCB578AD0456 -:1023B000DF7E41D9AB22FD16BEA2384C0C7F874A86 -:1023C000E3BE6109F6A575BDE55C3FC664263B2DFD -:1023D000E41A839B7DFBD07F14FD1EDFFF2328932F -:1023E000C81E98F35B07CBF19B40667EFF11282C3B -:1023F000C76F8600D76F8188F54B7CEFDDD2FFD9A0 -:10240000B91FA2FB7A77E257BBC9AE9F2BB5F7CDB8 -:10241000C176B512F248CFFCDAF17FB646701D4A9C -:10242000830592D0BEFA35D129D9EF475DA19DD859 -:10243000EFAEE42DA91D588F9884FDA556069FA4E4 -:10244000FEAA19FC0D58F64D0E3C4F7CF8CB14310A -:102450004EADC5E126F94806168DF3D13B2EA67781 -:10246000D2BB3761BD0CB145F03AD157D09BFA577A -:1024700060B97BC2EAED5468DC53B27727BD3AD528 -:10248000CCEFC36999D75116A75F7CA3CDFC3EFC66 -:1024900043E6F72775590CFAC537CE1C7C1AF73777 -:1024A000E5EF965EF5CECD05827F7C7DCCC144F60E -:1024B000E0FF68FC851092683D0D7B4DA116264219 -:1024C000611F94E9F40891D5446FE50041A27BD8DF -:1024D0008B7A4C9F2797F7FFB9EA233AC476B60761 -:1024E000DB9F2739690F0A3EC1FA54DA8F23085E51 -:1024F000B2D750218305EB49F8A290BB6E203BB6C2 -:10250000A502DAA93E092212E17B0A417A08F9C341 -:1025100032D3ED5450B8AED3F1F740E5F272087102 -:1025200079258485BE07B9F1299CFFAA4F40EC6745 -:102530005498E91D1D19F747686FC0E5B798C9EEB3 -:10254000F0FD30B1BF30A840870B22C473EE709904 -:102550000E814C31BF80879D9EFBA2F070C4C123C9 -:1025600089E0E18DC203E710F03803BE023E931408 -:10257000840FCAA7C9D025D13C8A66DF548297CB85 -:102580002AF073D90B5C5EA8F79C09979248C01299 -:10259000C84F009FA989E96684069F3F1600CB2F8C -:1025A0005DFE5C5B20F3735D0E217F66923D1A2F0A -:1025B0009FF4E7BE94CA2F64A487AA82AC7916D48C -:1025C00067BEC2CA3B8760FDEAA7F344BDACF257C1 -:1025D000B958FF41C128511F5759684578D59B46C6 -:1025E000CFABC2FA90806923F1E5F27AB4AB715FA8 -:1025F00081A47B8244C7A60C709BB03D505FE42D44 -:10260000C07A00E912106E7629A79EE06CFF397837 -:102610001B7015196981C905B8DEFCF99DAB053E33 -:102620002BFBCFC5FEC73BAD6CB7ACB10583842790 -:102630006477777D69747FC79FFE790D3D7F7A004F -:10264000B849BF80472EF4BBCE5C8FD9015C5F8C4C -:102650007283E21F38DF4C9A2F80EA49A6753D2528 -:102660008508FECBEBA7B13F7024CFFFFD82BE31C2 -:10267000E3E33EA4F134AFD073E0C92924B8958CCC -:10268000F45F4BFD4EB850BEA651BBC0434F6563CF -:10269000813297E68D7F6E4EF9E6862538CF52A4BB -:1026A0001192D38B0B0237D2B84BCD914185F86C88 -:1026B00065CA3B36A60B05E993E403F12BEDB7069B -:1026C000E991E87ABFE057E40077B7FD8AF8F5F8BA -:1026D000BB6E58E813224EC2FF15CF0D3E8F6635F4 -:1026E0008D7F3BAD63A9D4B590E8F2F3F4D76C7F4E -:1026F00066BE1C28E84E935B4B9FFB9AF9E7593363 -:102700000425CD3F8618BE5BFA5C9285FCC3A59F6D -:10271000422805DF2FDBF77803F93BA5E8FF939FFD -:10272000BC78D753CC6FFB485F22E896FEF7B3CF57 -:102730003F487C7A6512C7A126BD767408D94153FB -:102740008E461A106D70E2D9372E13F4AFFB257F39 -:10275000339D8F1E9F26ADB887F0BD0CF16FC7F972 -:10276000969982A26E75B855967BC24FAED1F6F19E -:1027700019746E9CCF72453D504AFBC99480E56345 -:1027800048F81332FE23FEBFFD686835AD13A46F11 -:102790006C246F4EA15F4CFBBAFDB178BFA3EB4038 -:1027A00029F9DDE417E33E17B71BDB97C6EA870478 -:1027B0007EF296022D1E960DD9B4AF5FA33FF4C1F1 -:1027C000309A777E1AD9871329AE90405EEAFE715F -:1027D00028B9F29102B697DB25E287324BE2FE0B75 -:1027E000F3855FACDBFFCB1E92D88F5BF6509F5119 -:1027F000EC276BFC0A612FF3EF93A45788CE022FCE -:1028000003D1C12DDA9E60731FA6B95B9B4CECC748 -:10281000D8A53BBCA4F7C73DD2FFB67F63BA4975C4 -:102820004326D527CC7DCCC3F655908435FA556C1C -:10283000673E99DE954BF33F992E838AF3352475D5 -:10284000E5929C559F757849EFC6AFFBED02E10F0D -:102850000C098FDF14F1083C139FE7BC54BA89F0D0 -:102860007C12F99CF0B7CC35BC3F38C96E989C19E6 -:10287000C1B241B3D3731E1B95361BE1E2A3F5C66B -:10288000D8D51DAF5E9342F6F26E8B3FC58DFD4EDF -:102890001ECE35F841F16551189153D84BFB1B33CF -:1028A000870412C05D2F7D9B2C0C2F9D6E7F5DA732 -:1028B000C00756C247B9D8876A77DB7D447FA1A994 -:1028C000E44F2EBB19DC2DD87BD9CB0F3738A8DECF -:1028D0000C4CCD27E97FD4FF137388ECF15FA68CF5 -:1028E000BDB71CEBBB8E59849FA22A87F263EC58BC -:1028F0007BA6196403BD764A8B491E13DD23BD26D2 -:10290000C9C920C7D0634A5E86A1EEF20E30BC9FD3 -:1029100056926B684F574619DA8BA13612C0F514E0 -:10292000654AEE10AEB8CF8C0243BB1DE93A4CEBC2 -:10293000FC52D85125F84FE8DB20DB4365118007B6 -:10294000900E261E37DA59259136F637930E5B0C1A -:102950007100FB59E250C9851A7F0D8481C45F481C -:10296000FF5E9263270F8BB893ACC17359B6D0CF7B -:10297000CB5E96D80E5C76CCCC7AE22478BBF14361 -:10298000F251E7BB78B8F7F51BE1DC7FAE11AE5929 -:1029900001235C2FAB31C2353B6884EBE05A235CEA -:1029A0007354231C87344D34F41FD65669A88FD82E -:1029B0007485A1FFC8D06C437DF463D71AFA8F6980 -:1029C0005F60681FB7F736437B3C5D8D0F2F33B4D4 -:1029D000DB538F305D1D40BA32A13E287CE9DFE237 -:1029E000E8C2C2702F1AE8F48662F0AFE23FC27FFD -:1029F00099969798006A03F1E385C2FF1584FF94C6 -:102A000028FE75B9DA139FEAF81D42FA9AE565794E -:102A100084F07EB22485E9E5E04B270F2B40F84F88 -:102A20008502DCEFAC29228E22C9C126A2934E700A -:102A3000B591FDB9C61264FF4545B3702729E53845 -:102A40007FF3FB25E86FC6ACB35A49024BCC7EC777 -:102A500087DB0DF5C297F61AFA1775860DF5F18723 -:102A600041227D55F0A6F7792A8B3E5438FC55FC5F -:102A700049F0792A4BBF0CDE45FA37DECFBD5AAD9F -:102A800097D2C8AFFF7BFBF368D6A07F364825BF3F -:102A9000377247AAD73400E191FC4E03F9DF807604 -:102AA000B4159511B80FB23E98EF10EFFF2D69F2F3 -:102AB0002AEA6F42FF9CF08E70C9237BAF1692BD4D -:102AC0000417B25BC80F832B843DBFDAA4B23D9AD2 -:102AD00084F628D9230D157EB697A74370203DBFF5 -:102AE000069455C4779219ED577CFE3F23028D85DD -:102AF0004562B1443F777D21B3FF3D85FC6906A661 -:102B000002A4F74ED0EFB43E78691EC5E34F902E75 -:102B1000C3F5B7B5BC304F253BC303EE08AE3B2031 -:102B200040069B0B03F7D0B8EF9BDCAB0BF1DD83CA -:102B300013FF3288EC917585C2EEB34B0829A4814E -:102B4000FEF315A0E78DD9CA7D8545D1384B4FF4EA -:102B5000A3C733F5F8E6AEBA309716B75722BA8B4B -:102B60008F3B46CCEEAAF1A4FF9699D8EFFC0B2D33 -:102B7000AE94E7496539EF804E7B3A2F99FDFFEB24 -:102B800035BC991D9DAB7E8EEFDD1014F6D60293F9 -:102B900097FDF5DB338F731CC52E99C047FE505A45 -:102BA000FE76117FD1E3259749DFC6CE3ADB7E6FF3 -:102BB000CF3C668857C1137D12C6D7A3E3ABACFFE9 -:102BC00062F6B9659347E835F2F3DF6FCEAE84D491 -:102BD00044F37CCEF1ABEB83AF1AF8E2C6DAB70C64 -:102BE0007C7093FA9EA13DE2E9B252BC32B2276BEF -:102BF0003AC5D73FDB6D2F263C20FE0F16C6C4EB2F -:102C000022CDA3AB60ECB9ECF72FBC8EA3759D8CE5 -:102C1000577DBFEFD4BDC9F5485D84CBF8FDEAF11F -:102C200011BD4471D844F6CC5D12CA0BF277495EEF -:102C30007862E405401ED9FF7749A3BC44EFB6FD96 -:102C4000C147A9BDABDEEEDEEEE3F808C74D6A91E1 -:102C50002EC86E00A7787F81CDC176E81D3EE12F9A -:102C60001EADF8EA06B25F7320D58B32107FC27FAB -:102C7000A2B8C97C531AEBFFD55907B8FE61338857 -:102C8000BC514DF821F25797A6A60ABB58C1FE5871 -:102C90003F9161E6FAA11181AF981FF3C39CDF5801 -:102CA000DA5FC4F3C01319447CF833D9FFB5E05799 -:102CB0007780DA6B32D0DF46FAFDC4AC8E35116B0B -:102CC000ED1A70AD05F1FE49B2FA395934637CFD55 -:102CD000AE253FF3139BE0DF49BB4ECF53113E1FA0 -:102CE0009A24F6CFD5674C1CAF0167C4568D7ED8A9 -:102CF000038303561F8EDF66457BD2299ECF1E13AA -:102D00008DCB9EB0624971D024513A7DC2EE75F9E7 -:102D1000449E532F4710CCB09CE4D3E57CEB708AE3 -:102D2000BF9DDC6C07925B38BF42FE96FAAC88E32D -:102D3000F7CBF02F028117F71A5CAF6788FC05F11B -:102D40009F4742BF16F721FB720CF167726053B1C7 -:102D5000FDFD3DF66D84BFEEF51E16F1B0CF9A472E -:102D600073BC5BA713D9A7C5BD7F0C20DA2FDB4648 -:102D7000ED8B5F7EFF1D8ACFFDA63030D487ED0B33 -:102D8000CC7231C9C9C5A91D1CA72BF6C93C2FAEF1 -:102D900097F78B72AB117D7158EC88705CEF6CF11A -:102DA000FB9EF6FFD9CD9D1BF3395E2D8F25B9A271 -:102DB000CF8BEB28A675E8FBD4D7111DA777FED1E2 -:102DC000E3D07AFDE387D60CD7F20837FA13E8E5AB -:102DD000AB743AB6268EFBD768F88CC74FC18860B3 -:102DE00088E3796E703760FD5A0D4E9FCDC3FD703C -:102DF0003C44194FF85D3CDBE92538EBE3F7CB8029 -:102E0000C053BDCC73C548FF1CA2BFDB82224FA0BC -:102E1000B723FD893867730AD3EBE2E7DE7AE7E789 -:102E200038CBAD8F8E2924FDA1BF1F0F6784EF70B3 -:102E30005ACF0249E4CF10BE37D1F8F1F981F385BA -:102E4000EB89EC4ED60B27B6FD2C44EB3B91056E7F -:102E500013F2E3E27DBF7DD33496E8C41996B084C3 -:102E60005DC6F857BC9E7243E03A92237694236481 -:102E7000DFD8F5F7065A0CEF55672A77F9D81F55B2 -:102E8000EE2679645785BF362450C1F5E556E1AF8B -:102E9000EDEA34CBC4DFBB2C10223DBEFCD50C9533 -:102EA000ECC7E56877B0A79317E4F54232FA41E939 -:102EB00009EC069357E6785C5A600DC14BFAD1D401 -:102EC000079FC889FAA3BABE2CD2F4BD927F6303D0 -:102ED0008DEFD3E281686772BCB314029A1DA1C55D -:102EE000E19A0F701C4297DB3698EBA0F8CF9ABEA0 -:102EF0000B1CE41FCA382CC7D73CB3D3A0173B72B6 -:102F0000551D4ADA11D1BAB5073F5E3F1FC06BECC1 -:102F100047DB0512D6D07AD5814823FEDA3AEB7723 -:102F20005D2F60D932E691C84A6AFBE6B44476A4C4 -:102F300043B303B8E847EB14EFD906AEBEC384FA37 -:102F400033D96B81F763F4A00339FFFD3C6D5EB2AA -:102F50000732BBDBFF4078EB691F17AB24F8BC6F6F -:102F6000EDA5DDE6AD49240F12C28BC8C433FD18B0 -:102F7000D16332C4EC9BED9E98BA14072F89CAEE38 -:102F800076E57482FCE577DDD7AABAF0AB1F1AECC0 -:102F90008110AFDF6AF18317E9C9E6C176C3390C46 -:102FA00055CB7F220117C7ECEF1CF64576B955DBF0 -:102FB00097F522EF8BC6F5F7BBA4D7A75EE2EB0B24 -:102FC0005FE2F885EA4B1B7E4AF5A50D3FF5125FDF -:102FD0005FF812C72FCCBEB4D7A7CCBEB4F1AB5E9E -:102FE000E2EB0B5FE2F885AB2F6DF829575FDAF063 -:102FF000532FF1F5852F6DFCAA6C073ACB81CFCD0D -:10300000A6379A4374CE46AA0A73DE3857058E4710 -:10301000A73603E72BB67B851FA5C7E947D2103239 -:10302000FA2D567716D9D1DB1BEFABFC318E732A04 -:1030300013174FF9FCEC230A8DB36D1A70FEC2D939 -:10304000F8D1518A7FE540D81BCEA1B89A04E11887 -:10305000BBF4FA600A8463FC896AA58FA15ED43947 -:10306000C0D0FF964D430CED37B78D36B4FFA8A9FD -:10307000D050BF492D33F4B7434E4B1EE55D1B2D99 -:103080005ECA8359686FA567C20D76D8F83D05FF03 -:10309000911F9383167DF7B8B88F74D56618D7192A -:1030A000D77EB67C407C3E614EB1964FE8FE7E41B5 -:1030B000BC0F6E4FC2B8A79E4FD0F139DC92C4F856 -:1030C0005AA78A7CD39A69C28F9C1A729B286FA9CF -:1030D000E36FB44672FABEB7D519FDC9F446772539 -:1030E000FBA34DC0F9DCDC2A7348C9A138C1C04A32 -:1030F00007E239B443D04708047D841A81F385A1DF -:10310000AADC95D47E2A047C0A46A78FD1550B678A -:1031100052DCB53EBB5F16C51972AA043D2CDD6BAF -:10312000A4034AE7D256D30F4BBCFEF4FA8C02CA72 -:10313000E79D819727049CF5F3E7E97170CFDB6188 -:10314000C44B3CDEBE2D5ED614C77F57F2EDF06255 -:103150009B2177A4519C540599E2322F660F373397 -:103160001C9ABC8C9F19D88DF830A70938DF134FF3 -:103170008FAD7510AE8AE1DF1C6F5821FC4C93F2C5 -:103180002B99CFF0DDFEC0A744195FDB9A44FE16F1 -:10319000CB641A1FF6CA0328AE105267F3BAB737CA -:1031A000DB92E93CDF57F566A0F3F2DB73E40194B0 -:1031B00017DBFE8C696EECF920A40ABB3993F7612A -:1031C0003797706911A5A2956011ED6189EA835660 -:1031D00098E3F0A94AD49E3E2339EEB962A2FE5B81 -:1031E0008A73193E694A86015FD61223BF23180FDE -:1031F000E5A37C1C4CBFCB4457824E42AF4BA195FC -:103200001C5FE932D510DD68E72DD257CD06CA47DD -:10321000D567FF742ECBAF7A1BC31D5608BAD0F307 -:1032200082D6264187F1F4E3F21AE9C72A0D3489E0 -:10323000FC96E01F7D1DDB146DDE2C0954967BB6D9 -:1032400001C467D6B8F1EC243C49DE78045F3A61EA -:1032500036D07BCE123BE7B1413ACAF8B74E00E810 -:1032600013734E217EBD675DE777A4F30FBF239DE7 -:10327000EBF267AD57933F45E25CE429A46B8A1FEC -:103280004DADEA04FEFE0ADC26A247A4835959C5C7 -:103290007CF4817F76911CB213BCAAD3A8DDD5A99A -:1032A0004C25FA9D2EBDA2B8709CB587059DA37EC6 -:1032B0007989EAADCD16A0732628674C3FA2794BD9 -:1032C000EDEE952479A481E369DD853E943B1447B6 -:1032D0007CC5282F8A3A8D70CB8D97EB3DC0B127E6 -:1032E0003D110F47D7040D8EC508C721DF1E8E364E -:1032F000AFD0C3E92542CEBE98FD537ED57D589C04 -:10330000AB495780E1FA852AF4F274E97898E4CB66 -:103310003A05E50BB6CFD0DADD25429EE870CED572 -:10332000E0ACCB9375F32183F8DE4DF2C44970FD18 -:1033300088F5765B9180334084F39FA98AE09335CA -:1033400056F0529CB6ADD4E9A57861AEA2C1B7499A -:103350008397094C04DF78BA9421A68EEB4B8DAB92 -:103360007F5BF8964ED0F4643F283E1FF8AE4B4981 -:1033700015FC3654C0C7EA8CF0B9E6A61C8B77253D -:10338000F275470EC21BDB9B5E17F0FEA5D67FD5FC -:1033900018E07A53DFD5990CAF9C859944CF4DD670 -:1033A0003695F2584D3AFD69E7C25C9A9C9886FCC6 -:1033B000BD00DF5F8DF289F290A92501078DD794BA -:1033C0006F0189F7BFD99B68FF0E9FCD20072FABF8 -:1033D00031C235250E8E49DF91FF7F3CE1BBF1FF05 -:1033E00076FA15FBAD1906D0C979C89083E0642B35 -:1033F00099984C74D4D2BA9DEB32849A7271FF0FB3 -:103400003B85FDD5D23ABBD7F351214D2E6CA97324 -:1034100070795F9D9BCBB6BA4C2EEFA993D97E698C -:10342000ADCBE3B2A5CECB65535D0997ABEA14EE05 -:1034300027ADCDA860395C051CCF5E99F239E7DF76 -:10344000E3E7CB518D7A6C706DB201EE7D6618F5B5 -:1034500055BA62D457748E29B6DDE51D65684FC92B -:103460002B30D493E48986FE5326047E3981E48090 -:10347000A7324E0F223F8E899EB36B6915DF4BE951 -:10348000F0D3F59353E3F33556EF00CA3B395B05B0 -:103490009F366B765E13C111CB6405F8DC8CEDB002 -:1034A000E40D01F1FF6AA6F38771EEFE488B1DD98A -:1034B000D7286427B4C8C28EB78238F76BCBF4879D -:1034C0006BF07912EA2FCAEBDAE6A6B05C78D8E3A3 -:1034D000F4D239DB96D6656E5E8F579CA771E3BF39 -:1034E000447980F8F3358EA1C67339D6B39C6FFC4E -:1034F000754FF4DA9491508E9C2167BBF32FEF6BDC -:103500007429F22FF778043CED3DC8A3D6387BD957 -:10351000A9E55F60A02F61FFA83D25F20BAD717199 -:103520007BF4C312E66FDE9A2071FF3F4F9085BF98 -:10353000660903C96B9717DF8FF53B14F17DE8B976 -:10354000CE8F3F3E4F8C7C0A2407FE3C019F2B4FC1 -:10355000083B254916DFA1D84051583E81C887D085 -:10356000591FD237A95ABEA75BCE908888A13BE7E6 -:1035700019FEAEC88BD06716443F96E8FB17C4BF50 -:10358000FDB66523F9C3C37A69A7FC5002B9E02AE6 -:10359000D1BF1F832E4F3180EEBA23FC5C2589E119 -:1035A000172678359AD6CDC8C5E7A95E8B173100A6 -:1035B0001525F25E3A5FB14A4965FDBEAA446E2701 -:1035C000FEF942717A091FADF955ACAC93867DC8FE -:1035D000A2B7B1C4C676BA8E87246D5E444F679594 -:1035E0000E67ECEFCC9B11ADE37FCD6336725EAF1F -:1035F000E5AA4738DFD732EB3F38DFB73A6B7A1EA0 -:10360000C9BDA492E9C7F82097861F660DD2237919 -:10361000C6FCDEE9D3A2CE70A0F8849607048F31F1 -:10362000CF6791FD86F92F349E60A0D0436051F89A -:103630007B8333E95BF0B5DEAF673E50F5EF4E5765 -:10364000D2F9E0268F90A34DE07D3340F55724AFAB -:103650002AD3F38237E9BCE9EA8116C6CBEACCD992 -:103660004DC28E177E53936725E76DE3F5369DD7E0 -:103670008C95DB745E3356BE37C9B37BD5CB59010D -:10368000739CDE37BE9F1D34EA1FFDBDA4CC2B5FAB -:10369000AB8A392FD56CF13B485EACF2DC678AD53A -:1036A000730F2881052531E793AC99B3F83D7BB6BC -:1036B0002FE1BAAE50948544DFB8FF5EED81F59AF4 -:1036C0005CDCA8E997B3ED7393D6FF01ADFF66D23A -:1036D000EB23A2F8193EF4F26496CFEB441C8379F5 -:1036E00020665EA524B082D615C5AB390A17A4D3CF -:1036F000E1F957B0DDD1B06E7632E169E7FADED795 -:10370000A3E7D5F57E7A1E353EBF6EF3980DF0DF48 -:10371000A3C985175C0B2B1F40D0EC6C13F4D4B0FD -:103720004EE891E14F887D9C4987C6F5EE6CEBDD54 -:103730000E8AEF4F91C56E3AE17A465C7D405CFFA0 -:10374000DCB8F65171ED0571F58971FD2BE3EA578F -:10375000C4F59F1D57BF36AEFF82B8F6DBE2DA979D -:10376000C5D5FFCD884FDFB56989E0188F3FBDDF34 -:10377000B9E2EF5D5FC57EA2A3E13083E945A7B75B -:1037800073C543D4DEF5339DD94A46B17CDF81F65B -:1037900015D9433BDB2ADDE27C4760E56E8D3E4870 -:1037A0003F58368879D0CE4AE6F89CD36390236799 -:1037B000C3B709328CEDB17668EE85C7F7D9E93326 -:1037C000A4D917BDAF5BE7E32913FC27490E414895 -:1037D000F899BA5DBB4D15FCB34D5D50B99EE46DD3 -:1037E0009359C49FB5FB50E86E1D11270F684A38E6 -:1037F000C2F18426CD4F68D3E4C95A4D9EDCADF9A1 -:10380000094943839B28EE9B7C988FE740B3AFE048 -:10381000AF0B103FF797166FA3EFC7EE1E53F2F8EA -:10382000C35877FD5D827021DAE9635B14B259DA1F -:10383000948C243A4F946272B4939FB8AAB0CD3F4F -:1038400014FBADDD7FACFD79C4B39C69F3A2CE0758 -:10385000D9D265227A837C2F7F9786EB54C9C6B272 -:103860009677D5253A77BAF60AB7898CB0F419B2AB -:1038700099CE11F79910E85B8AF018DC046605EB25 -:10388000196A98CFE25C532A0BFFEA196428DE6FAD -:103890005716C1EBAB66DB7EAAF68C0F90B438DD11 -:1038A0007995FA38698234E887E38EB245ABAB8FFD -:1038B0006CA6F3D04E49D4A73CF3F8FC95F9D1FAA5 -:1038C00098671E1FB812DB5B0B0799489EA67B52B8 -:1038D00013DE137375A9909FDB9B170E4EE48FE9DF -:1038E000A53C13383021E76B25D1D4042C876AA579 -:1038F000AC3DCF14F52B35B8C9B55ABB4794177AF0 -:103900009EF8F1E794BA753B7B809F8D6CC877F683 -:1039100033D88B5797F6622FA279CCF1DAAD56796E -:10392000009D23DCDA6C03BAFF616B3688EF905799 -:10393000D9F8DC2858DC03AE7145D71D5AD56F1E67 -:10394000D14DC80486386EA6065FFB4493768EF28E -:103950009B307DC7B755CBF36C8588DB9D1F8BE70C -:103960005FCD27BCEA78DE57FAAFCD449F1DD90B57 -:103970002B37E27BEB1ACD1C3759D798CB744EE32B -:10398000907D746AC52133D9ADF9D06E263B7F1482 -:103990007D793D84AE400A70D9AEC9E7FFD4FCF80A -:1039A00061A0F0F341D0C5C0F9B438F01382CB1058 -:1039B000126D12F18FDBE4C07996EC4BAF48A4B7DF -:1039C000EB4AF5EF7AA1C652ACF91732C3B78EF8BD -:1039D000281EBE74429FE38E8ABF9EDA9D7B5F0DD8 -:1039E0005F86D5DD6F18E993F0363B46CF6CD4E0A7 -:1039F000E7F6FA15C2E1B5C581167A7FC9A6BF1EE2 -:103A0000207354565533BDFF14E11D9F2F0C07A79B -:103A1000D33063BCE14AEA3FBA76DB7E8AA7E5058C -:103A2000EFA8EC8FEB1BAE54577A888694C0FD3418 -:103A3000CED0CE48850BEBCE4DAF86B3783D6379C3 -:103A4000BC5C7D3D480FD54C476E11C7D7F04BF895 -:103A5000A773CB0B370BF8607B16EFCFE2CE8A5DF6 -:103A6000FFB669FDF8BB8578BA68D5E0F758148EC3 -:103A70006035FA358F2582A34EA73A3C6E78A26B4B -:103A800015E53AE7873A5F2439E8DFE49EC6F2B0ED -:103A900038F024BDEF6BF337701E7057275D47D4A5 -:103AA0000D1FA7D249D7BB603FE569C2FBD615EF12 -:103AB0005772BC782F88B8589C3ED44BAB129F6786 -:103AC00010F7E58CDB6BB493915E958D9E587A353B -:103AD00073BE33A4E9935013D22FCDB742D06F48B1 -:103AE0005DE64E44678F687A658746B7FAF3A13D75 -:103AF0009CBB3C54DAED27664A46781EEA8DEFD32C -:103B0000C0CBFC807C7084FA65101F607DF00A37A2 -:103B1000D3A7CE074BF6FEF500DD67E3F4C905B188 -:103B2000F7D745343C227DBE43EF2FD9D475807C36 -:103B3000C5C12B047D7E4C77871545E90CFDC7F781 -:103B4000A89F4E3FF1FB78571B4F2EF67F4C785CB9 -:103B5000B829C8E321FF1C2BE5713AC349CC724A4E -:103B600025ED676B1BB8693FF65F1474905C3855A0 -:103B70006B62B8DE981F5E65C6F2FAA160A5EB869F -:103B8000AA33916C72298F6BCCFF0D6B33E20FE976 -:103B9000E76F344F91276013C1EBA08DE5690F7477 -:103BA00011D57BAA0EFF157172D73CB1177A3ED79B -:103BB00071D7162B8E8945DF621DE7D84F8F379D51 -:103BC000193F1DC5FE434BD36CFD9CF00CBA8F67AB -:103BD0003BC54F11AEAB9A7AB7572F58FCB4F9A436 -:103BE000889FAE008E03AD4C196B4A44379740FC5A -:103BF00074CAC444F1D3C87B063B735593900B3A07 -:103C0000FC86578D4C16792948A57C891E1FD3F751 -:103C100075B7664F3669706B21B8313C05DCDA0840 -:103C20006E0C4F1D6E33843F425F8853BCD66316C3 -:103C300079B1910B3651BEE054A6C893D767DB44E7 -:103C40007B8EC82F9C411F9931F634F2C19A667160 -:103C50009F08BECF79B517B30F3886509E33D3CCAB -:103C600071DAED9EFB6AB6733D99F9CF0A6A5B1E65 -:103C7000CE3BFCC3B9EA027A5E62E773F27A3EA7F2 -:103C8000A5AFC8E7B8F2B47C4EDC7C76B8A9B28D9B -:103C9000E6CB137E4B8F74ECD3F2115A1E2823DF30 -:103CA00098AF70C4E52BE2F3956B9A17ECDF2EE228 -:103CB0002B2C9F87FF7824FB63F1F3B8671AFDB7BD -:103CC0003523753FEA1147A2EF1852AB8CF4D8A206 -:103CD000E1BBA1AFC8479C6D7C284F36F8552D79C4 -:103CE000E71647D0FB911FEA4ED03FDE0F3D1FFF86 -:103CF000D6CDE31BEF074CE0DF6E99C8F11441DF2E -:103D00006B9AC5FEBBE3699A5FA59F3FD2C7B16AB4 -:103D10007E1CD773A2724ACF870D75DB985E876AC7 -:103D2000F74535FC7B4A68650EE5D76675513E72EE -:103D3000E80E89F3EE439D7ECE43746C98CEF9F184 -:103D4000BEC981A727C6C49F76B87E9AC9F9022D3D -:103D5000DECFF7E6A0DE53D715762A64EF8E04BED9 -:103D60006727392E1F107F3F4E7C7D4E99D0C39917 -:103D7000D741C27B4F3E9F28DACFF4DFAF6038A136 -:103D8000BF9B2CE4ADA2D7FFBFE4A976B61DE2EF3E -:103D90007D4EF94093B3FF0997A29C3D5112389E86 -:103DA00050CE5ABA58CE8627289F919E5C4E177DDA -:103DB000101E6E4C7C3F8F5C76A9E2E16981877CA6 -:103DC0001D0FF75C92F942C4437659223CA05F452F -:103DD000F06AF32983A85D29510653D98D8F1F26D8 -:103DE000E68B5965C2EEBB58F858A7E1E35EC207FF -:103DF000C769642D4E93C7CF9B357CAC39031FEF49 -:103E00000B7C94E8F878EEBCF09151956168779757 -:103E10001BF191EACB35D49DF9467C240F2D308CD3 -:103E2000B7BC4C16F7240D9C68E877263E8CFEC084 -:103E30009DF45E2FF6E8C04067057D4B34606E7BD5 -:103E400007C9E64C7F5B0595FA3E37C7F9737AB927 -:103E50005CC35FE6D4C4F85DA0F15BC644E526030D -:103E60003D7C2F317FD668FD979728B794C5F2F334 -:103E70009589FB2FD1FADF3641591CDB1F7FD64BCA -:103E800031F6784FFB0E242BCBCB78FD224FB6A317 -:103E90003E95F3663B92E476CA57ABF54EC3BD75CB -:103EA00083E937AC67FEE89B0E95CED9D13D4168DA -:103EB000596DBBA35FEE1A6CDA96317C25C1B1A9AE -:103EC0006C88B8BF7591FF6DCAEF28EA09ED1CD266 -:103ED0007CBEEFC814EE63A27BB2C09D714EF92385 -:103EE0009467E25EB7C120BE238620EB41C90FE98B -:103EF000F4DDB205FC225F4EFDC5F785BCF9140860 -:103F000073DD0511AEA7697EDE0365393C6E3AC8E4 -:103F1000260124AF89E4A8CEA70E4F90E9DF53EB2A -:103F200036AD245FCE0250467EA073207FCF0B9526 -:103F3000A0523ECB040EB6334DEB0F7CCD793AFD4B -:103F4000FBC397FB88EF0FCF717FE7DAAF91EEE508 -:103F5000F344EFE56BD4EC01FD5E3EB532C8DF976C -:103F6000AB2BEDEE06CF99DF973F3A31B08BF0FDEA -:103F7000B7A4412191640E4E98EDBAA0E3872FF2C9 -:103F8000F8AF5CE4F1DFEC6DFCBBE9D752CAEBF9AA -:103F90008F123F37B88AD9EED4CB78BC5DA12811F7 -:103FA000EA27395E1BF0619FA83DE73C6A627FA863 -:103FB000C124CE9FA9EF99D8EE827C41074E19F219 -:103FC00072C645C7717A838345DC49C45FEAFF74D2 -:103FD000D708B2BF7F99322B9286E31D7C55D87FDC -:103FE00096A991CD74BF73FF349B773BF2DD3DDA28 -:103FF0007AEDA513EEBD137FBD798A90172E8BF74E -:10400000F2023EB7343342F6A3ABD82253AEC01906 -:1040100097D76CB5B42553BCB275C77D15A3B0FB5B -:1040200063752FB91B137CEFE9D4F29A23A5C472F0 -:10403000F09F939244DCCB67BC4FD85AAE9D2B497E -:104040008554B2232DFF52D2129D07D04B7DFE2204 -:104050004FA48ABEBF8ED0256E88E7A292EAA464E0 -:104060000F9F8BE824F8567AC30EB27F1F5F10BCF7 -:1040700035F6FBD3D61270911DEF9B22CEC36E5046 -:104080002417DDAFF160C4C2F78E3FB8E8E9E6144B -:10409000ACEF3D6A76133C5AFDEF3993B1FE388E92 -:1040A0004BF2EEE00E71CE529D0FA16108BF56F2A9 -:1040B0002AB1BE5B11E7B2D9212BD6AEEA43F8FF95 -:1040C00075725F016F0856D3BD9DEB5226F37D9646 -:1040D000D973443C78BA74B483DE7FB0C4CEF81B85 -:1040E000A29DD331A9D57C9F65DFF9C6733A0F2E07 -:1040F000EF5409BFEE52BB5BE5F3974ED7587CDF18 -:10410000F5A8192456715D3CF974C929D6E5157EC8 -:10411000EEE37258A5FB8EFBE27BF56EBE35D170E7 -:104120001E68F726E19FA68D777A91D271BD71E75F -:1041300085F475B5E1BAE8DE63D7508E4764CC31BB -:10414000AE2F2DCE6F70C6D5A79677DFE3339CF0E8 -:10415000FD85FFA785AF71AB574EE47FB6D64167AB -:1041600055CCB904670F71C09AC982AE6D592F380A -:10417000C84EF9C27FC4433878E59F073EBC97CA52 -:104180007FFD6ED75284CFEFBF7E73C793B4BFDA83 -:10419000BB0F11BDEAFE189FC1C4F5BC586D63B8D2 -:1041A000F96768E7397D1D2F587DDCCEF9A5B5FB91 -:1041B00093B87D64398492B07DA445C9BA99E8AEBC -:1041C00053F2D6CB3488388FA8E37FED0D7E138C65 -:1041D000213CFA25BA0F639A76BE76C3229009FF76 -:1041E000B645ED7C5EDDB75C9C57F729D5497CDE92 -:1041F000748E99CF87D4575F73F930ACEFBA5CDC1B -:104200004F3563B9328FE75704BDA475169B9713DA -:104210005D6689FB9AF4F3A645D0C5DF7F8CF4B6C2 -:1042200077D848DECC4700D3FA5A357C69718322AF -:104230005FA74AF6A4CB6BC463461CDEE2F1BA4228 -:10424000C7E34818497894A12D99F4E14300ED742F -:10425000AFC086E54FCFA3F36C5FA8690CAF9EF8A3 -:10426000F91DB4579511740F8B83CB4EB457A9DC4D -:1042700085F62A95AE60C575CB71DD7BDE38F8D248 -:104280000F71BA594AF5957444AB48CB7B81BA7427 -:104290005025AEFF06E25E51DF4289C4777D92A1D0 -:1042A000BED66389FE3D00FCD595A5FF7D80D35B1E -:1042B00094A108964C8B968F11F559E487C4B4EFFE -:1042C0009E69EC5FB63F66FC81B8DEC5366E0FEDC9 -:1042D0005BBA45B5C4B43F87F572805735FBF1FA38 -:1042E0009D66FFF604F2EDDD7261475AFE052AC9AC -:1042F000B52FD14E23FF5E322B2CDF21D72227BAD8 -:10430000570F00E561AC5F2E1BE5EBE51A5F58FC2B -:1043100015A0E5C7E01B3DFE803F7BFE388BEF63B9 -:104320005A35C4C2F70FA13EF0F696AFB3782C9F72 -:10433000C6DEDBF5AC2EBF87C1309AFF4B28FF43AA -:1043400005F341CCBD0DC4F76DCF5FB614E7F11D89 -:104350004DE638AAE45A9FC2F731D535B13C7F40CB -:1043600009FCB63CE67C4963FAC242922FFA3999BD -:10437000E8BD47D798BFCDBDF71DD50780F4C297DC -:10438000485AF65EE8B0B16EEF115AC7EABA762E17 -:104390009D6E85858DDD12E4B8CF154AE04FB43EA1 -:1043A0007B26B6C7F089D58DEF19FC0EE37D9CB254 -:1043B0003BE224B86F28F9C049F3B71E167CBDE173 -:1043C000F0EC24E2BB56EFA124E29B2FE8E2C7EF1A -:1043D000C0273EE5559661BBDF48BD9EE8674F4369 -:1043E0001ADB150797DF7F2DF1CF8DBFF801C3BB17 -:1043F0009B6FE0E14195CE18BE818799AEBBF9462F -:10440000ABF7CC377F67BEDADDCD37A2EECB074303 -:10441000FDE04C63FF6EBEA0F1912F1EAFB073BBE9 -:104420007DD2C35BD418BE3A49F558BEF909F24DA6 -:1044300002B93F7D9246DF17986F522E32DF0C9DF6 -:10444000A4C9CFEFCE3763275D14BED9633A1FBE30 -:10445000B9EC4CBEA99AD4F7DBF34DAB3BCCE7E902 -:104460005AE79813FE7D900F347939757EA0B28D8E -:10447000EC1A45DCDF374D9A99E5F3109F497487B4 -:1044800034EA4FA1CF0F5EDFFD7D06EB67FDFEF541 -:10449000F58450B293160BBAE9AC1371DF6952F987 -:1044A000B4C5A477E93B024A3553F694EC02D4FB39 -:1044B00032D985D05EE1C179365499A04DA62D0739 -:1044C000AB87F1F861B6CF8668717FA7942FBE677E -:1044D0009A29FEEE85FE5D4CB562BC5FB6FF59ECD5 -:1044E000265C770AF931EE12F17750164D8AD7BF64 -:1044F0006887E0FA3A07DA984E362857F71A273ACB -:10450000E35CB52F98302FF9D6249376CFBEF233E3 -:10451000A2B3DD6F6C49A673127B24E0F339F383F9 -:104520004FCD23BE73A942DEB4AEF833A52361D7C5 -:10453000B41F1AF5347C6AD4D3F0A9514F6BF51E21 -:10454000E58D7AC2A8A7B57AB79ED6EADD7A5AABCE -:1045500047E5CDA7063DBD61D2A70679F31ED5CFAD -:10456000414F1F9E7471F4F4A88B2C6F9EBE70F2A5 -:1045700066DFA4BE1743DE1C392F79937DA6BC39B4 -:10458000743EF2C6B5B943A5F4CCC21EF8A056C31A -:10459000FB5B65CADB343E949C5BBC269EBE3AAA9C -:1045A00017AEA6BF2BF3A557F87F3DBDEFAAFDD5EB -:1045B00091C6183FDC65E914DF23D4EEE1E7B76C60 -:1045C0007E95E3B1675D2F5D105A74A65E45BBC84A -:1045D000C1F4EB35732EFC7CD7D13A47F0DB95CF95 -:1045E000DEC1FC945C6E9C4FB77F3BAA6D669EAFAC -:1045F00044C8E99EECA19EE6FDA05C16F7FFC5CD80 -:104600001F4FBF489FE9938B981E2D742FF8179D5D -:10461000C07FA7EABF4E6EFCBF8A7C49E9C51193F3 -:10462000CF834EA76BF84CB06FEFC5DDF705E3CF36 -:10463000E993CFC38E3E4CFBEE9B70DFDF67385EA5 -:10464000B47D5F30FFE1E6F3C1F7BBE5DDFBE6EFEC -:104650005132B47D6FF8E735EF515C63C3BFAE7D77 -:104660008AE21AF77D9DB78DE21AFABD726910FDD4 -:1046700091F5EF8F102E2EBFF89E24634ECC774518 -:10468000C0FE7DF4BB13B2377CDDEDFF2BF7CA9182 -:104690007DD2DBBD72AD36635C4F2FAF2A17F64A71 -:1046A000AB691DC72336A05F558F78EB9823E211C5 -:1046B000AD68A7B0DC9953D0AB7DB4AB4EE1B85335 -:1046C0006B9D9FCB7BEB6670B9EBB5256524777D41 -:1046D000AF2D62BDE7F3FAAF7B1881E4AEF8D049A5 -:1046E000CFEFF5E8FE90B05FD2C87EC1FAC393D792 -:1046F0006F8D8D0B8CFAEFE15BD481D178555B66C1 -:104700008CDD23C7FA51A012B944FD28AC1BEC9AEA -:1047100011EC47ED26BB06EBED934718EC1A7D9E96 -:10472000B566A821BB66ED0EF38C4476CDACF2C421 -:104730007E14D6390FE27039F8FB7F49FBFB5F51DD -:104740007EE9DDAEC99D7271ED9ADF4FBE30F18713 -:104750006E3ED6EC990714E50D4DAE7C47F9B1D10C -:104760004CF1E36F2B3F4692FCC837C88FCFCE4742 -:104770007ECC2A771BE2A20765B5CF58B2D37798D3 -:10478000A15ED6F42FD63BD1AF31219C7E5221B110 -:104790009FB3C10BFCF7FDA64BF35F267AD8BDC8CB -:1047A000CCDFBB3FA88873220FCD11E7A91E5E5E48 -:1047B000309B3E235A9772C3DD4914D72E17F70456 -:1047C0004C97CA39CEFDE00C61E7643BDB2FA7FDB7 -:1047D0001FACB000D1D5D9E2DC146EE778B5E6475E -:1047E00081B499FD0ED70F2D6E3AAF1A1FBF769682 -:1047F0007CCCDFCD83F40A7FDF7DB6F8F5B78D5B27 -:104800000F98F29DE3D6CC8F35CF0DBF41759E49F1 -:104810009F4726CBE25C620F7A2C9E9F3BAAA7A7FC -:10482000457A3917E524FB29E61E59FD7BD659E563 -:10483000621E27D94F8551BAE8A82EEEF55EDA94AC -:10484000DA678EC4E685522CED3C5E4AED3E7EBEB4 -:104850009ECE2F90CCB27859AE3E5E89F239C178A7 -:10486000FBEA8287092EBFAEAB3D4C71EA49964EFA -:1048700089FE9EEBDE3A95EB7BEA9AB8DC55D7C60B -:10488000FDD6D76DE2F2BEBA103FBFB7EE31AEDF54 -:104890005DD7CEF5C773C53C132D211E6752178E09 -:1048A0001FC30F659FE03C31782E8DA886F6096FF7 -:1048B0003619DA8B3ADB0CF5BEFE4D86FE7D66843A -:1048C0000CED6F950502538AE85CC363867ECEFCCF -:1048D0007643FD5CFD850BDD6F654AAAE51FC8AF19 -:1048E0008302484F4867E9B5B2CA79F31AC197FD08 -:1048F0006BBD61AA6F71D998BF75BAE433CB26B18D -:104900007E53CC3DB51D2E717EB2A1AF88A734FC7D -:104910004CD4B76489F391C3AB447EA461A0B8972B -:1049200044CFC36F7169F793F8C43D1A83F223FC37 -:10493000DDED20EDEFC139CB45FECC0D6ECECF378E -:10494000D481F67D6284F31D1960F68AFBD5159932 -:10495000FF9E920542F5385F43BE5BBD85E44C3057 -:10496000D56BF6F29F960D99298F48E2899330ED29 -:104970009ADED1F2F2491F009F3BE886CFE7E27B47 -:1049800084DA2EBEB7A97F6D17E7E3B6FC42DC637D -:10499000130FD78E5F7CC5F72A6DFDD95759C4D444 -:1049A0005BBBCFED7425C57E8FB6A52695EF5BD892 -:1049B0005A9BCBE728B6D688EF8D6510FBDDB2C8D1 -:1049C000C6E730B6D69ACD24274F2DB2305CF4F529 -:1049D000C7CFAB7FBFB94E3BD773AF76AE67AD766F -:1049E000CEEA6EED5C4FB376CE6A8D763E76159D3F -:1049F000EBB1133CC5B99EADB50B14ED3CAB7E2FAE -:104A000003C35742F8F2772A56D86B1A07F4870C7B -:104A1000196EF1DFC7665425C79DE7319EB74AF589 -:104A20000D30D49DF9C6F356C9434719CFA90E34AA -:104A30009EEFB1798CE77A2CCE4AE3F9D058FA444C -:104A4000609A566CAC27FC77FF7D477AD88FFF7E43 -:104A50005C37FD86F47340129D4349637ACDAC12F6 -:104A6000F499A17D0FE3864E2E53915EA874529E59 -:104A70005DA273902AD351F4FB37A5577A3ADFBF72 -:104A80000720AD4CFCF700F473087FD1ECA8A553C8 -:104A9000944FA71445E7BB7F8A723CB6AE973DC9D9 -:104AA00085FFADF2FF01C18CE32B00800000000008 -:104AB0001F8B080000000000000BB555CF4B1B41B9 -:104AC00014FEB2BBD144A35934B6865A481A520DCB -:104AD000A4B06D37A225D2D5869283C8163C78E85B -:104AE00021879CFAE358E86D635B904A24A9422F22 -:104AF00052C8C11E0A821EFC03621B7A8E680B52CA -:104B000029C18AE7405B7A11D23793AC899BC47A7A -:104B1000E940F2F266E6FDF8BEF7E6E50D68798158 -:104B200090A2DD137D40245A2A3848065468B930D3 -:104B3000305324E9A2FDB5AA94359114C0A9095CAB -:104B40009ABA1E2F4912D9C9163BFDD4CECEEF8D8D -:104B500031BB0126252EAF1F39000FB015B3E51666 -:104B6000FDC0C20E9DABC0EF315B0E7E96DC49A549 -:104B700032CA4D01917D69BDDE4BC02CFB49F17AF3 -:104B8000C73D0309F29F3180FC30BBF3D0CD745791 -:104B9000343BE5A33C427B4548E42F5284DC078646 -:104BA000AFAC81F6E7AFDE17258AFB6109B84CFB95 -:104BB0000BF652EC11DDDB1AEF945F28CCCFB4FD7D -:104BC000299DCF5C1121325DB71F962855D860AB67 -:104BD0005C237EA25255A755A1CF0334E894F70C6D -:104BE000D347EABAFB243029535ECF0FFC1B8591D3 -:104BF000BA5D805261FBB7B51ECF71376D8410AAC4 -:104C000088751C15B6EE36CB3F866FA360673821DA -:104C100030BED43D21E7A738BD5F96BB183EB1A892 -:104C20008B25B2478C508F13CE3DDD8D73FC7D6795 -:104C3000FC7502078683CBA22173B9650C72796C6F -:104C4000F8B83C3246B83C34142E4BC61897408A0C -:104C5000D7B3D3061E2F63C47763C1F6F1645B59E3 -:104C60006775C78484F7ACCE432AB76BBA17253F64 -:104C70000D7C115DBC190A3D6F2799FDBB27028F82 -:104C8000B91ADDF4EAE166FBD56753E7E24E1B7320 -:104C9000BBAFECEDCF5D1D486CB6F0FBB2D6C740A4 -:104CA00096E711880B58A43CBC0EC529D3FDF4B679 -:104CB00093F7754871E49C0CDF9A0B3F4C1CD43F72 -:104CC000CB696A19829CD524997AEAD46F8F42F90C -:104CD00034F45560FAE320AB677A223FA8138ED5EF -:104CE0009B9FE786C92EB5232288E6BC5E6B369E65 -:104CF00097892B202982DC027F3B5C8F6BF618F2B0 -:104D0000F0B960E5DF7ADFAC3BADB4345A7BA2B4D6 -:104D1000125D898C4675D2D66D9C07A70FFC7D77F6 -:104D200040CB33BC17C80FB8433CE7238994AB9EF4 -:104D30004FBB3A997974D7FACF9B2C3B12846FF909 -:104D40001F7DD8672F3A58BD9692423CD7228FF5E7 -:104D5000DA9C5B526F39D97B44B8751EFD716B9F2D -:104D600056F35991C83F9B4F2AF96FC1F737C67761 -:104D7000B59FF745AA6B46137CAC9FFB891B8D4200 -:104D8000F547904B116FD9A8A0E4E9FC97DAA17020 -:104D9000F796F9D0145F6DE8A36BCD73675B73551D -:104DA000E74D1041366F7E0ECDBAF32DEA6B4A9374 -:104DB0004773EE34F358AEE24C567122DCFA3DD71D -:104DC000EB355F1BEA488867FBE6EB797DD38E7F86 -:104DD0006B1FAC2475779EFE1FF0691FBE1B8C8F66 -:104DE000B3EFAF1D6F569E8EFF334FD6F3A23957E8 -:104DF0002E88F3A2F74CFD2FDBA790A6F00700004A -:104E000000000000000000001F8B080000000000F0 -:104E1000000BFB51CFC0F0030977F3A0F2BFA3F161 -:104E2000D7F3A3F2CBB851F99E68FC2634FDE7D145 -:104E3000E4591820B4233BAA38B158988381410E15 -:104E400088353950C5F3A1E6D6002DE807E215AC48 -:104E500084CDFA2C05748F1C03C32920DD00C4D730 -:104E6000651918D8817C216906065F204E00E2CFC3 -:104E7000320C0CB380F43B20DE2A0DD1C707143B63 -:104E800027439EFBBB85C8D3378AA9831F28A1F27D -:104E900067683330DCD66160D0D683F0AF20C9BB01 -:104EA00003C5666A43D831AA0C0C877419184E28BA -:104EB00061373716287F18281FAB87DF7E572354AA -:104EC000FE2E6B54FE4F4354FE134F547E9F372AE1 -:104ED000BFD107420300BDE0D98DD8030000000018 -:104EE00000000000000000001F8B08000000000010 -:104EF000000BCD7D0D7C15D595F8998F376FDE674A -:104F000026C90B3C20C02404891AE8000182224EE5 -:104F100042B0C14DF181546997EA93B53622C81366 -:104F2000B1A6AE6D26DFE1AB8DE85656AD3E586DAD -:104F3000A9D51A2D6D6957DB04D0C52D8548A9B5B3 -:104F40002DFB6F50575B16D9E816755D5AFEF79C1E -:104F50003B93CC3C5E3EECC7CFC6ED0E77E67E9C25 -:104F60007BEE39E79EAF7B9F220640BF1CE01CFE14 -:104F7000B1E7452200CC197C462BA0542E07D8243B -:104F8000048D70117BFE415AD91566DFC08A2F9FB0 -:104F90003ED8EE5A10A8FEF3456DF13EF6BD63EA29 -:104FA00057E350C6EA4F14A8BE53CF79DE0812402B -:104FB000014049E76A35C1FAD934AE49C5FA1DFA4C -:104FC000F695C0C63B53A28084E315656FDFD6001B -:104FD000D03D0DE072D8AA16C758F998646C866C5B -:104FE000E314D1384ED91F17A1BB14E8EF1CFBDF27 -:104FF000A62F2621C1C66D9DFAD59508B7D27D335F -:10500000E811803BC6254167EF678248F3522A2C9E -:10501000305959D5ADB835FDFC713A102F65D86BB4 -:10502000677C7964F0FD32072F0C1F197801B804F2 -:10503000408359DD16960340ED33FB35EDF1B5F8AD -:10504000E8C63F7FFE7CFC19A0131E40ED8C272292 -:1050500083F06CF2F5774B0CDF5611188FB12A39BB -:105060006C9C4A573F99E30DCC53EEF4ACFF74842B -:10507000B380E621C8AEFE32E1996BD79BCB668E3A -:105080004F675E390BF83823F57F25A2B800EB7720 -:10509000C6AD888B1E65CB83F7A05D5F33BDF586FB -:1050A000C24F08F13307F163C5911E1D3A96C27ACB -:1050B000630D9B4F8105FD522E918D096300F2F126 -:1050C0005FAC89ACE99548AF634C56977D1F1BB325 -:1050D0001A25F67EDC82B420B367041ED2DE0801F6 -:1050E0004253728E1A599CEEBB6677F431BA3D0377 -:1050F00091CECDECD92CB37E116FC723E9C71848E8 -:105100008D97A51EE963E588254353398D4B7C783F -:10511000A77491B19991F4669BFE3B1A547AB63507 -:1051200068D0ED07686988D3F3FED097BE81FDD7BC -:105130005B7ECDCF9E72D7ED4F61B9192081E345DB -:1051400062BC7F9055ED310DCB6022DE2325FCF94A -:1051500012E285C1F9558649C4CB0F6D3CE9D04DAB -:10516000FCDA6C2CCF812CF8749EA1522F9F05F491 -:10517000206B3958F6C7F33C659F36DE531FA0906D -:10518000F04665262AEA042E8F22722F180827C3BC -:105190005756B960CB15499AD9DFCDE6179EA718A7 -:1051A000BB58D36D8297BFC6099C3ECA04959E31F9 -:1051B000E8DF7F0EF16288E9CD6CACE0CCE2AEEEC8 -:1051C000188EA91853D93A067D692D2F0B7F41B946 -:1051D0007CAACF81BBF8A3C78F24F5A41259C6FDC2 -:1051E000BDBD7E979F3DA222FFAB33C544BA0CE103 -:1051F000B5126CF2B05597459CF74707F7F0EB7581 -:10520000C2E6E73650A9BE8CEB553EB85E1D065B84 -:105210002FE49F72BE5E1DB2A58E66BD1E07F0E034 -:10522000253480972E8E97B28F182FCDFB5626B23D -:10523000CCA3CD5E4F190CA394F0A0E808E7D646A6 -:105240004EB716A3DB6CF277283C4839C7E3C9B2E6 -:10525000F3F17E8DC0C75964F38983A74D865893B7 -:105260000E239E3A6B506E6D2D1145944B1F159E6B -:105270001CB8360FC095E670957EB47049A1EE95C6 -:10528000D9F8B12D831FB720DC9CEE6A38DD891F69 -:1052900029DD397005901FF83A27F83ACB7F13EBD8 -:1052A000DC36B0CE49BECEF18F669D9DFD1C5463A9 -:1052B00025AE5B9DC6F890C1718B642937E0FE1A5C -:1052C00012E03183D101C23F8EE999E1A697751DA5 -:1052D000E03E21C0F50D69554ED2056F9DCC749608 -:1052E00059F87EEB05C961E601695F7F9F0327E3FB -:1052F000DFFAE38DED075C707E5188C408CE79300B -:105300000FE17C27BC3CA71B86EEEF6483DA28FB09 -:1053100000DE6BB0DA0FF8CEFF7E8B04A96CFAE5E5 -:1053200083B65C00B54BA1F9DFCD787026E2E1824F -:105330006A88B2F508378DC17940987D9CCFFAD93B -:105340001D68945DF81D6A3E037875DA3175C79F54 -:10535000777EFBA1DA7D20241F11187E5B63623506 -:10536000C2A596401AD7C0BF7B59F778181ADED667 -:10537000D85F06DE21D7CDAEF74EB8A90D58BB6673 -:105380009F71506774D252201A4D300887432FCE38 -:10539000BA38781CEDBAFC6680BEB65E01A467829E -:1053A0002ECDFCF3E9EA20D2D5C57F7DBA7AE36F32 -:1053B00097AE4E0A057FBB74A5D44BFAEBCCCE2832 -:1053C000924D2E27B5D516AD3F8ECDE492D439B38C -:1053D0001BE525C4997DC68701919515CDE47A2FEB -:1053E0001880FAAB5AE29593BE42AF9C8CAF34BBA7 -:1053F0009D7E37EB38AE42E3A27984E3CA61E80EC2 -:1054000044B1AC503F48CEE7A6303CC18335C5BC63 -:105410009D81ED869A8F8CEDD878A87E9C2BC276E4 -:105420007F9F93C862F70ECEDF3B4E7C452227114B -:10543000197D7D08CBFA1B2EBC0FDD4E86371CBCB8 -:1054400030FA2F453F49C120FECDDDB791FF220044 -:10545000A241765D619B855FDBF1FFCDC77D9FF348 -:10546000757BE12C0DF52D60FB0DBEB784CF039647 -:105470003F1074E25B673C299C00A21BBBDE48EB3B -:105480007F27F25316FE5E25727DE3BD2FA5FE1B1E -:10549000ED416BB3A03FC6F07AB8E17D788DF1E5C0 -:1054A000EAEE0B15F47B5C2F8EA17AAB1714298BD7 -:1054B0005CFDAC066E1702F4C9CB22EE711BB91E5F -:1054C000DA25EDC379BF5A21A571FF7BB5E27F488C -:1054D0003F7FD594D288E4573BAECE194EEE1C6E7A -:1054E000E0F6AC53EFB029D1FE7E58EE0B67D3E364 -:1054F00007C74FD3F8575548DE7D5AEE9371FDDF4D -:10550000FB22F8507F3EDCA00AAF4D65C62FCE933C -:10551000D1D1EA8A2205FD0E23CD6B89ED0773F008 -:10552000EBCCB3252CD23C5BC255E4B76AD1DE216B -:10553000FBF10C7B8FF26028781DBF558BB63C2B9E -:105540003E9408D7B7145F32BBBD69CFD72967FA3D -:10555000B31CF8DAC2DC2E6A0B73B8DA62621AF98D -:10556000BF2D9E7D5CE7D96CC3E7D46B8971BDB458 -:1055700085C993D1C02387BDF030B41D457FC94490 -:105580005BD6E4D7F6367E0EEDEC64D8940C7CD373 -:105590002B4C62E5097109366B6CDC9AAA8E6AC6DF -:1055A0000279AB122F3230602C7456A21F70F217A2 -:1055B00037F67C8DCD6BC27CBF86EDF26A523DCF53 -:1055C000B176E399989358BBB1C7D7AD4339FB4F38 -:1055D0006827A220B66E6A443F560B0E7109C0C3FD -:1055E000E2AA4AF4B3C9C0E502937ABA3C06FD3395 -:1055F00040CE99A1E403FB13CEF907DB0D85B788F4 -:105600002DAF68DE24AF960F2FAF36F2FE2DF61FBA -:10561000CA9B0983E351FB71758A078F6333BE1FF1 -:10562000B0E9D20FCBFEAAE38C87E501D44F222B41 -:10563000442D8DF5A12B17FD5063D6CAD08DDFCB3D -:105640003B1B99F81811EF4CEED570BF715258E61C -:1056500082F79722F7334DBAEB9820A0DFD7602A64 -:10566000FD4C2CD7CFCC46A7DB6DFA1C28D7AC1647 -:1056700092345E62C954946BB522D9BDFFB46256B0 -:10568000AEBBFDFBF63883EB0FBA3C17CB7CFDE5D8 -:1056900015A21998F1A7AFBFFC21D73F7FA3E2D98C -:1056A0004F3FECBAC8687B148CBCFE7FEE38CEBA94 -:1056B0009DCF1F5C3E4EBAAB3A80F2EFBEC4F07293 -:1056C000E5FC755B4EEB36660598E92C72252009E2 -:1056D0009E7DD579AA900283ADB3744C22F9268DB4 -:1056E0009DBB72270C3DAE145332EC37BB3FCBDC75 -:1056F0005FC2D6FF13E0FCF5CA28876A510EA15C91 -:105700002AF7BDEEF68F308C0F9619EEDFFAC2FE47 -:1057100003288F2C268FD07F9AF9BD16CB2E7AB80E -:1057200042E2FBEFBEEFFEE202818D73C4F0EB7E3E -:10573000F6EA90D0FB06F97D2B25DA8F113E752E07 -:10574000B607524E8E989259CDEAF7960BB48FFA5F -:10575000E1A5EBFE91DA8728DED1BBE0B52F5FCA69 -:10576000DA7FE2321F720EC704B68FB37FA25E7378 -:10577000B6EFCB97B2FA872ECB1F56DFAAC5F9BA80 -:10578000E8E4AA67BDE555486F08FF7FBC59FB20D8 -:105790001BEF08E424FCF8ACE0F01D41F890EEFBB0 -:1057A0007EF506EA85874D81FC51472A7E16437BAC -:1057B000BCD214485F5CBA4048FBB3CC73E982DBCF -:1057C000264F62FD258C901660DF0F55BEBDF55249 -:1057D00006EF553F90B6E1F3F45EA920593634BC8C -:1057E000CEFBAB4CEFFB01BD189216E21D341E97A9 -:1057F000F0C58CB89B5E07F418396166F3B7AD95B8 -:10580000B8FF51D00CD2EFE4B002388FA1EADF34F8 -:1058100004FDE6407FB7847038FAF7D9AB75B73C22 -:1058200074E050E44412C791340576A19E917B8DBB -:10583000EE9E7F83C4E34242DC2478148DC3A3C868 -:105840008699CDDF546FC3E3F403D069B7EF87BE09 -:10585000F0207CAD81C44AF45B58B9DC7FD812F1EA -:10586000FA03F7D8FD3CE6F4E783AC71158026EA2D -:10587000BF6A4C858AFD3757703D490783FCE32D8D -:10588000CC6E8461F4BAADB6BCD88CF10D3FC6398C -:10589000343BCE11E7FA53F819F2939D2913C9AEA0 -:1058A00019AA9F88E1D54742A55E3BC6D15F027A1F -:1058B0005E861FC8EBF7F18D914547EF437A1D09CE -:1058C000FE013DCFAED72EA7542D2B9ED2C3EA7337 -:1058D0007F3DFCF1F6215F97960DAEBF14DE1CBA3A -:1058E000CAEC5FC95752698ADB25E21E7DC09693D8 -:1058F0004ABE9AC27D01D4A1BE0779FB30FB8EF16E -:105900008C7042477F8A043C2EA4221FB8F0F3B665 -:10591000DDEED3B268EBF3298A830A7A8AFC766AD1 -:1059200021E31FE1FC76CEB3CF6EDFFE87DB5F2184 -:10593000FE2850893F049DF14F96719A24F394C438 -:105940009EB74AE65BF8F4FD514A66E393FFB2E581 -:105950008A5A9BD0D5628A2B923D92094740E6FD38 -:10596000DEE4C06FA5284E395AF8DF1F25FCCE387B -:105970000C7E592E20F87DF81C0A7EC986270FF46C -:105980004619E59ACEE52BC032DDAD97DC28737958 -:105990009167CB2780DBE26E7BEB7ABB9FD1CE2772 -:1059A0004F1EDD7C9C71D97C26C97C3D26CBC3ACC7 -:1059B000C7441B8E1B65BEDFA9D5093DCED6257712 -:1059C00008BA5A60C39192455BAFB8ED43D1D5C5D3 -:1059D000A39CC782C1759967AF4BC570F3986BCF15 -:1059E000A35382F9AFA35E3CC5F1F72CF7ACCB1DF6 -:1059F000367E3AFDCEBA6CF0ACCB2DF6BC463B9F62 -:105A0000C5767F23CDE78EC1755966CF67F970F3F0 -:105A100071D5BFD6AEBFD2AE4F76C71D726913DA4D -:105A2000194D5262955C30381EABF71977BDB79BA4 -:105A3000CF34DAF56EC0F7420DDFFF58BDD5EE7AF0 -:105A400060459BD03FD08AB602B3634A5A2EA9B2B2 -:105A5000DBD551BBDA81FE6FB6F983DA055A8426AD -:105A60002B4CF5D661BDC6457F74EADDEA85F76249 -:105A700007DE0D046FF5001CB7BBEB2D9027507FA0 -:105A8000E7C51D46E90FF2C5921D18E7CF834827E9 -:105A9000E679B4C9A947300FC0B264780CF309FCA9 -:105AA00086803EB66845EA1B582FD762F635AE5B56 -:105AB00055EA292C5B22249ACB299F80F205EA65BE -:105AC00055F31B987F61C00E56D662721AEDF356DD -:105AD0002169E1BEF85329F96599E4ABB6AA11FB37 -:105AE000CFD7B99E0E7DB46F3970DD13BA8EF21F19 -:105AF00072195CE88F6ACD80EBFED0A41EDC6FEFDC -:105B00002D50484F66065629CA973BA5A081FDF542 -:105B1000147C9EE0DDDEC8F31BB67FE2F304EF7D6C -:105B20000250DCF63E1FCF6FB8C7A76A4D1AF617B2 -:105B30001DF759CA87C8D1FCE5361C08DFDF1513ED -:105B40007CF9A055DE2890F8EA41FBB6B542217DEC -:105B5000797B6C5625F557A1929E7A5F625623E9B0 -:105B60001D1541F2D1E7870DB25BA3F314B0B01C51 -:105B7000331A51CF8CCC0D620E0CE417022617405D -:105B8000641AA4B1EC83CECE12F68C7630BB249F7F -:105B9000EC26B811EDDE0A8677B4232CF328DA253B -:105BA00061B0FFA44326CEDB374102F47B38EB1B08 -:105BB000ED1C683FACDD154D8FB25EF7E8EA453A63 -:105BC00098DD3F7B14F53A47592F3DCA7ADDBCDE9C -:105BD00088FE0E83DB7B2AFB0FEDB640A6DD1CF6AC -:105BE000DAC3BE8CEF99F1B8CC67663CE4A4EC8DC7 -:105BF000878CD4DE89838C345F744A0CC0298D5C19 -:105C0000DFD13787FAAE8CBF266EB2F6ADE33E1D0C -:105C100027B9366E157F4EB4DF4F5C69973F6D979D -:105C200057AD34B3C8F7B13E2E874BD11F329CDF3E -:105C300001B8FEF80683FD9C80C94BC3FB4F32F5CB -:105C4000DE4C79A7CA5615F2EBF604F76BFA9119F8 -:105C5000910F0B81FCB03E487596A09C0033BA783A -:105C6000CC20FFF8CC174CE4E7C3E324102A687D6E -:105C70000CF2A767D049265DF833FC397F2E9D7C56 -:105C8000CCE78DC7FEA5E844E99046C53F4AE72822 -:105C9000EBA54759AF7B74F5FC1DC2E8EA758EB2DF -:105CA0005E7A94F5BA79BDB6F90ADFCFE17B4D662D -:105CB0000983FB12D5536EBB24E8FD7E69D8536E71 -:105CC0009FA3D0FEEF94FD73554FB99DC979CFF7CF -:105CD00079612A6F6AEDAE625BD9A8F9E43FFF44AF -:105CE0003E295547F04B578819765B065FA97A0025 -:105CF000DBE7CB3A60FE547E8CEF53EC69A6B3E051 -:105D0000F7119BFF77C93C7F73BBAC07D07EFC5B70 -:105D10009F67A38FC3EBCC7724781DF9FBA664EBB8 -:105D20005B43E57D54F3BC4C1982949759526D56F0 -:105D3000994C2EC92FF2385866BFD729C9A77D2E96 -:105D40007B58D6923CBE67F7B7A44026BD44667226 -:105D50000DF51E05123545144714C9DF278747D8AE -:105D6000370A5D72AB7818B8ED3C56FAA40354FEBE -:105D7000968F1B3480E46B04FAC898CE41AD670A55 -:105D8000EA69BA00D4DE10B8FF7C8186FB5E2CF095 -:105D900097EE7715F52B98F7C0B9D087E857EE2323 -:105DA0007FE75FBCDF11E00D607EEFC5144288B96C -:105DB000F37B7DF114BD84B3E7CE49738137A1BF76 -:105DC00024C5D765D1207F288C8F925DD61ADBA0A1 -:105DD000BAD7F5FF7CC51EBF89A2B5DD2644D9B36D -:105DE00070ADD9370C9D9FC3600CFA470A6F34FB26 -:105DF00086D94F07E29918AFCFC2076D4A328DFAA4 -:105E0000BB3529CCED7939457EC676216FD6E67251 -:105E100017FD162ADD0857A4DCB4D0DE6BCF170DB2 -:105E2000D45365D8DA2BCC60EDA45A2399458F184A -:105E30006C2F9F74CF27A678F5A9E611E8BD7504ED -:105E4000BDC7A718C96CFED0690AB76B7DC1ECDF6E -:105E5000EF12AB4A9439E7E38DA9F9DCBECD850E8C -:105E6000E1639C7C28DFA1F08557100FAD0557C476 -:105E7000879B2F68DEBCCB9B4473A6323C1C73B25D -:105E8000C131DA7C10ADDA203A1CD097629CAE5159 -:105E90004F12C660BE07FFDB56BEAB1BF3407C371C -:105EA000F0B8AC64EE06F4533B7A9364064F88B4C2 -:105EB0009E0BB8FE54CAF52193FD87F3882E185E19 -:105EC000AF9632CACB14AF3ED4DCB017303EEFC031 -:105ED000EFF8F132E7758958756D767C8CCE1EBE71 -:105EE0008FD10B4CC378948A4881CE068DCA5F6EE1 -:105EF0008853796B834ECF9686527A6EC1A6F39102 -:105F0000CF531D450C6F1DF147E39F6555EE43D9F7 -:105F100041FBFE758B504FDE3C50666620837B3321 -:105F200006BC991E71BB72D522B4DF3707C0F62BB1 -:105F30002C5A647ACAD7345762D9F6336C6EBB9E3A -:105F4000EADF3711EC7310A6FA49D7BEF788E223CF -:105F5000FEC6BD85B7379BB1BF806C97E1B645DE05 -:105F60003298084F40E5E5FDCA06EA9F44001BEF62 -:105F700027CAED7CBCA9DC8F0F65CB47C023F7EBAC -:105F800083A273F9599647F92C8A61A0FB15EECBD1 -:105F9000B5E11E6D3F7292EF77C7B2EF97837C3306 -:105FA000C2BE66C331D2FA3374D87E88245838EE24 -:105FB000CF791CF1AF3DEE7DBE0F8717A5A2DFC2E2 -:105FC000F3230B94E4F791DE23665777112B476B8D -:105FD000BB2D62DF518E7BAFA2D9F34E12FF3B780F -:105FE00076F48EFFF279D7D11733290F2910E6FC0A -:105FF000375A78FB50BF9A33D80F3C51356E387DF5 -:10600000AD2021A21236202FF26B82688C0D947382 -:10601000CD3C4F39A762BCA77EC428F67CF7691730 -:1060200079BEFFA9EBF4F38C79FCBBAD373AE51FE1 -:1060300067CE7394FD3AE59EBE4562295B87976BF8 -:1060400025D2EF5EAE7DEDBED9584E4814BF3DB3AC -:10605000B2D9878C740CCCC81CF4872525DB9F6EC5 -:106060004E447CFE1CFFC9C67B09F73D269F8ED897 -:10607000E77F989C9888E79F8E5C366F22AEEB1185 -:106080001FE76FB03A493EFDCC071E79F0335BFE47 -:1060900018ED3B9AD10F794CE065A97DC7228BE2C0 -:1060A000835BDB3ECEF496AB390A6179AD90D51EA9 -:1060B00088F815C2C7074232E267F334ABF5D61849 -:1060C000E6BFE940FAAA1F12A497D5835529A2BEBC -:1060D000C3E88FE2DC727F6136BDE367F67EEE8750 -:1060E000AB49DF5F5E9BEB4363DE5F33D3877ED4D8 -:1060F000AB6B2A7D60EBCB9A0B3E3121D0F9A91511 -:10610000B5FE5D88D715B2E9CB16D7BA3AE1F7EC00 -:106110005333190E11FE63F6B90780FE4277BC694E -:10612000A69FDB3BF192E1ED05076EA7BCAC76E6DE -:10613000F38807866D3A8F026A7FE1751177BF2178 -:10614000272E1CC17E5F5EF90F7C7F6674817EC541 -:10615000174F7CCE4771D915F91EFE5B5E2D79E095 -:106160004F2C0879CAD7D45E9D33ACFE91F467C832 -:1061700033CB3E8729921CDE7C5C20F99033A93F0B -:106180008D799AF0B2045CFF73FCAF9790FF353ABB -:10619000A15F477D017E13D21E73C9CF169B2E8748 -:1061A0001AFF393FD76BE5BC1A8A6FBF7742D071AF -:1061B000BE425EFD349CAFAC984D386E4B9198C694 -:1061C000B8F79DC5DB555CEF4D251F4E0FF4C57824 -:1061D000BC5FB7B459C8FE43B54B9BFC1C41E6FB02 -:1061E000B57E1E6F69B5966B25B88C07B44A9C7F47 -:1061F000A010B29E3365F4BFD68F7EFB98053CBEDF -:106200009E20BDBA445D4D79B8F2F8E1E3B59978C6 -:1062100093ED386066BD276D7A2CA9D845FDBE7711 -:10622000E1F0FD3A7879DF10A1D7D627B0BE0A6C2D -:106230003E0CFF5B4A791E6E4BD9338467C9AC2490 -:106240007DD6A7A54CACB7A56C35D1652BAB93CF4C -:1062500086CEADEEA2739A5BFEC0E3134FB61F6805 -:1062600046FD614BCFCD807995C1781A507E6C99EF -:106270007E938A78D8B213A017E958EE22A75CC89B -:10628000F687873448334B0A426526A05CC8D3F8AA -:1062900099CA7DF12AC075DB520E06B2667E3AD5E8 -:1062A00088A19F2D711EFF0E969A354508F73891EB -:1062B000C4800EC90E2CB7D4CA348F368DE303EDDB -:1062C000AE734E7E17E6C19470BBAB04FDFBAC7F92 -:1062D000E58B7CDEFA8E12F2136DC97DD9447DD731 -:1062E000FA04185381EBB5A427C88C8EB0FF7A2D21 -:1062F000EBBA6F1593DFF2BBE2F7B2A60B48A79992 -:10630000F879CF0757E2BC5B668AB02B8BBEB1D75A -:10631000CFE3756963F955C559C679CEAF7BF204F1 -:10632000F4F715827BA8FA83F564F2EBA3E1B1845C -:10633000CDA3A086FB4B21E31C6B0C9264DF8E0582 -:10634000AB11F9D139BF3AA13AF1CB247B4A91156F -:10635000944F37D4795627CF7375852D9041BFF66A -:10636000D76CBE371FF401E2EDF2B38FBC80F95257 -:10637000BE0ABF46F955D0F902E66FDEC8D4312C0B -:10638000DF7C7CBA82F93F2F8F97303706F9278A56 -:1063900074F81688947FF6161C8DCE76D1F9297B79 -:1063A000DF41C98A72A43997CF4B0EB7F54A515CC9 -:1063B00077D9EA73F2F74861E279ED1066EF55CAD2 -:1063C0003E6A24F9D7C1F3859CFCC8CF767AF3875F -:1063D0003EB7C35BBE09968F41BEB989297469D6A1 -:1063E000EFCDEEBC2F36FE313FD70F3E07A936DC8E -:1063F0007FDAEDFC9875DF9FAE205DDF3C5B2BC242 -:106400007318CE3C7EEFE776E849C6A7BA8BFFD774 -:10641000C4D2949F9C39BFB7F62CEA4EB2F26BBA45 -:106420009CE276B6779EEDBEDEA598EF656DF3D95A -:106430007A8337CF71CDEE4A13F3C518F6F47C6F2B -:106440007B82FF1F3ABCF31D091F99F377F4C1A1AA -:10645000E6A3EC16B2E6FB85546FBE54B3CAE38DD7 -:1064600066B30C8185E79F8FB6AA5274BED96AF2D3 -:106470006BCD318A4F52FCAF9E110EC6F7CA559DA7 -:10648000FA792F30290D740E21350FF5A33FB7DFB0 -:10649000F92AE7C3BF74BF0B8780779DDAA7207FF7 -:1064A000AE973B6B84E2C1F301019F654E60F8F645 -:1064B000EF5DD63D013CF53A4659EF201E811E4561 -:1064C000BD1A7198FE4EDBFBD6BF3DF12F0AEEDF01 -:1064D0006F3D7E6229CAB95BFE550295D53BFD44EE -:1064E00004BA69DF492B2897D7EC9168FD41EE9EED -:1064F0007BB527DFBE99E67FCB5311DA1FD63CE38D -:106500004FD7B2F66BBEF7DA0C607C7BBAA9FF8579 -:106510000988BFC7059EC760F5CDB89ABD5F23C384 -:10652000F5D9F2106E50395F9DFA416825EEEFC241 -:10653000EE9EEBA8DFAE6B7D7E97FC5DA9727B9A29 -:10654000D533F1BBF54D213D55E0F065CBCB3BF5A7 -:106550004DEE4759B3D797C63CC535BB772A495648 -:106560006FFDEEB789BE173DF56414F1B07EAFF74D -:106570003CC22D4FFDA1ED92723AEFD45F8BF24FEA -:106580003A4BE533A6DACFF3E0B93FE656E2585688 -:10659000EF3B6F5EF16BF6FD645C82001329277B95 -:1065A000FF53F9572C27C32926CA58FFBE57DD7C55 -:1065B000B87EF76B74EE481399027B299E87C8F862 -:1065C0009E519FE9B90ACAC3F55D9BDE4679B97E43 -:1065D000CF5BBF42BA5B0FF2AB6E7E3E89FF18778E -:1065E0007E3C6B93EAF5D39D814373C901B03B3F79 -:1065F000ABBDE8C4B31CFEBEE5C9330FA31E71EAF0 -:1066000099FF7A18EF6758FBC7FF7918F35AE147EB -:10661000010DE5D6FAC77F1E0517FE1FB5E5C3E9D4 -:106620006F7EE3EB0F303C9CFEA59FB076FAB93746 -:1066300027E13D1DA79FFEDF31A87F6C7C6EF158DE -:10664000A4B38DDF5D3476B873A048B769BF7B7D96 -:10665000D3FC7E83BD026E8200CFDACF8C7581437E -:10666000FD0AEABDEF0AD0BF3997BDEFFA8382FA7F -:10667000CB0B26F4239EF6EF79ED85BB58F92DB6AA -:106680004EFE2CEBC4E63F41A4FD8DB10F7BDEBA7C -:10669000E7EAAB2E2BC7A7CFC0EED7433FED1BE7F2 -:1066A000ADEF31B6BEE583EB9BF9FD0C9C5510FFB9 -:1066B000EB9F60EB3903D795ADE78CF3D7F32DFC57 -:1066C000C7FCF3D773BFEAF5C79D81B58F3C801F28 -:1066D000F7E467B56F9DF55CF7DD4F0EAB973BF2C6 -:1066E00061243CD3F95E06D75754F3672AF2ED33A1 -:1066F000DFFAFA0331BECEB50C31A79F3C33090F48 -:106700006BFCD6D77F1DE2A1FF39BF867AD49AE70A -:106710007E417C77FABB2FD1B91EF61715D87E774C -:106720001A06FE8E022BDF2AF0C23ABDFF8A5FB145 -:106730007ED7B12E2C83D6EF8A5F95E3FAA9FDB4FC -:106740001EE965353ACADF7401CDFBD634E78F5BAD -:10675000D33D2BD09F9D89F748C0C9271C5C57F4B7 -:1067600097DEBAE7C415487F43ADA7337F0DE73FF7 -:106770008F7D7FD4CBBF43F2ABBDBEA777BEA7A0B2 -:106780007ED5FDAF8A26323BFFB4AF5F198FFBCDBC -:10679000D39286E78D33D77D10FF4D59CF1D673ECD -:1067A00033E9C31FC81EBF76F03412BF8F3CBF0F42 -:1067B00087BF33F63E9C89C75367B3EF075302DCAC -:1067C0009EBB153A6B50C5CCDCCF7C90B226140D25 -:1067D000C2DBD625919C3FB59BFB6932E5C5AD4335 -:1067E000D867339D71F6F6CC40B9766ADF0F6CBA84 -:1067F000E4747FEB132714CBDE1FD22EFCAE1FC236 -:10680000DF7DA9DDDFFA67B3F7B7FE89B7B3F677A7 -:106810005236AF45F84FF6FA282FE9649794D5CE53 -:106820009D1AF079F4AEB6C8DC5772583B291AA409 -:10683000BCABE626F317E827B58EFA6C3F80F15B18 -:10684000CCB76A8E04E99C7B73F426BA2FC9E9AFF2 -:1068500025034F723C41F6931C4B94F31858DA63AE -:10686000C7F81841B8E106D92A44BDFF70D19B3260 -:10687000F67B04F548975D7F4486D6FC723C172171 -:10688000188D90C5BF91D17F628104BADB4FD83D8E -:106890004EFC3D6BEF3F26A511B5F590EAA67301BE -:1068A00085D0F55896FE1E6AD0C97E2E4A5C4FFEF2 -:1068B0001F7F2A65A2BE56B8512B16F5A1C79D9819 -:1068C000F2C6AFC733CAFF3D8E73D047FA20EC7EC5 -:1068D000FCF1C7C7F02D05F5F217F0C9E4DFE57547 -:1068E0007A21961FB2E7CD7880CE314EB41232CAEB -:1068F0003921B64C46FD62712A21AF76ADE7E298A8 -:10690000301EF7D3F410F7407D3FC0F7CFC6C66BFB -:10691000288FFDC12F8A44D70F063E5E887C7620E3 -:10692000775E18FD6B3DEBE61E9AC6E09C10960064 -:106930004DCEFDE1E1CF6D3E6CFB1776D9F70F3DF3 -:106940006AE7977FDDC6DBEE86527A3EDE60D0F7DF -:10695000271A2AA8DCD55043CF671A12F43E7A577B -:106960003089F4B9A76125BD9F006F0BB8FEDF6BBE -:106970004852F9D1402EC13FF96E1093ECFD62C42C -:10698000477870DE0E3C69DBEEFE7EE0C72DC8174F -:106990000378CCC0F7E5D02BA8E8BF8A093AAE7BD4 -:1069A0007D40E779AE19F89DE4EF17302E577F3719 -:1069B000CF877858F09E77B8DF96FFDFB1F9F4DD26 -:1069C00068F2C9007BBE53B3A294F421D0CA906E82 -:1069D0001E1612478C22C2B3E7DCC9FABCE4770268 -:1069E0002EFFF0A40E6ED7EF08D8F26D2388486F03 -:1069F0001353A023BD39F3DE57A917A25CDC270887 -:106A0000B4DE486FA52E7A1BA0DF809D971CCFBEF9 -:106A10008F0FD22FE7FFF825A5F754235E3688E4C1 -:106A20000769C64FAE761FD874C4EC16D1427AAE51 -:106A300013C99F3BF9F8096112834FD7BE15C07B7C -:106A4000BBE293C0F637750590BE1EACE3FEC5AF42 -:106A50001DE7E798CE6C2C5E368DD55FCAF083C1FA -:106A6000A8BC25251EBFA5737EE16B6A22471BC605 -:106A7000BF9599F776FFE42FBD9FC3C699703CA4DC -:106A8000E379987B26FFA84761E5F17D02F993C67B -:106A90008753D3703D2BFFDF37C7F5B9D6E181753A -:106AA000A9C9A837B64DFEB6807C30FEEC8F05DC58 -:106AB000474AB4E49BB83E1364FB9CB09C9A87762B -:106AC000C1F57989DFE1FB4461FA53484F676A36C3 -:106AD000FE1BF6EFC421EBEBF5DC692EF990799EF5 -:106AE000E2A1D4F0FE4C67FE0FE1FC87A9E7CCDF02 -:106AF00059BF3335B1B5281733F199D96FDE9215E7 -:106B0000C38EFF907D8F189BBF3FE8926B85A93E97 -:106B100019DB39ED878ABB66CE77C04F34CA386D32 -:106B2000970FF2912E9EFEBF49DF3902483A0909BC -:106B3000FD53FB02C97108CF5C4851994947CA67A8 -:106B4000377239FF3E30E6EBE388EFE47411E57D00 -:106B50008C72BC5648242A719F334423DB3E303D5F -:106B6000C8E97E01A4C83F2A86EE1E3ECE5FE88DAE -:106B7000F36F059A0458DDAA1DFF0059437FD841E1 -:106B800098857EC8FC20E7F74A99DB97B30FEA3B6C -:106B900025EEB79296455CF8B3FD763EDE3583FB75 -:106BA0006ED0743CF735B34770F1EB7BA1E4C220A3 -:106BB000ABAFC4B93FD2174BD279CBC55258247F63 -:106BC0006E2797FFF590502FE47119C079EB1017DD -:106BD00071BF7F68233FDFAE6B2182FBA1984EE53A -:106BE0007A5B4FF9B14D473FB0E5FEF76D7AF92E6C -:106BF000CA7DA49B3EF3400E83EB3BB6FC7FDA9646 -:106C0000FF4FD9F27FCEB13EF86639C96303F39ED8 -:106C1000BFBC3DDE84D37CB2C1A47ABB1AEAE8B91A -:106C20003F77ACB897D57B74A3B80BF9F9516DECED -:106C30009578DF55DA140D81357EC8DABE28CAE0B2 -:106C4000DFA90A143F7BB82145ED76AA7A938AF131 -:106C500014662D5B4806F5BD14F6A8FC6DBF56C33F -:106C6000EA7DAD33EF4A8CC3DD5B23533B878FF462 -:106C7000391BB03944F3FC4164ABBC826E750ADA4F -:106C8000E91B45EAE72B81CFA88BD873E2C4A3EABE -:106C9000C7755C8C13668A7D5FC4908CF3A8E8EBA3 -:106CA000B3B05CF27A98F2B5E7BED2074FB3725137 -:106CB0005D84CA132D2F5F4CDFD367753238269E53 -:106CC000E2DFABF37E6775B1FA391BA2D45FD5EB77 -:106CD0007D02D2B3AFDC7BFE6A87EF97FB236CFCAF -:106CE000D8A1848078DB27688B3025C4FA143F7FD5 -:106CF00033F62054E1FB787409ADC3F66011D1CFAF -:106D0000D75A8EC66F463C6D8CB5A099B37FE3060B -:106D10003A9FE0DFB891EB4129EEFF9E78C701E191 -:106D2000732EF950D82267F5DB6D0FFA799C64E376 -:106D30008AC4340EDE8130EA7B25DC5F59D45AEDFB -:106D4000C96B72E2231F08C9ED41B29B789C44D6FF -:106D500052F4FE32097545F6FA4E91EB4989DE8010 -:106D6000DB0FA3DFC1EF67CB8463575026385AACE3 -:106D7000EA3A9417DBE6287200E19866DFCF62C733 -:106D80002107F63121B9CB2DD7648DC33591A132BE -:106D9000847077F77EAA8BF5F37ECAD9C7CC20E939 -:106DA00049F788C41F5BCBF939C0FDC63BDD78CFFE -:106DB00085C34FAD8648FCBB5D16D202EB677B797D -:106DC00071EE85483F31DCBD69BE2AE2B944F6F177 -:106DD0001C0E30F7A15FDC8F7E71B6DE25C743271E -:106DE00044F2FF79F3BF8B2CEFFA8BF5DE73771348 -:106DF00099D2E3CE57064634037446FB6BF5BEFFCB -:106E0000407E5819223A03CB8C568EC1F445FB4F75 -:106E1000AAA5F3CF2519E70C1EB0EDF787ED738413 -:106E200070F63640B9F5807DFEFA81B5625067781C -:106E300079DE3A4AFBE6C4FAEE4A0ACC687E4F7E17 -:106E4000B5FF6EAD09F7D7A294374FA832232FA80C -:106E5000E4CFCCB33E1EF4DAA9FB4E060DBC0F2FD7 -:106E60007D4C32509FFDF25DB349FE596BB8DE9206 -:106E7000AECB7B00CFBBE40B60E07BA75FC77E7D22 -:106E80002798477C939ECFBEE730B912E95A5287C4 -:106E9000EB05395A530CCF43DF09DFC6FEEBF8FA96 -:106EA000571602DDAF5318033AE7CC9E9B2F40FEE6 -:106EB000DF28624C1CCEA19C4739AEF6BE88EF732A -:106EC000AF14E9FE9CA216EB429CE7BE4BC68F476F -:106ED000FAD81AE6E75E9A851468086F01E7879D7D -:106EE000916ECA07DD562342135214C3A581FDAC2F -:106EF0000EEEA23C1684770ED11DE95D18A3407EEC -:106F0000B46E08F27DE7AC7521FA95A3A1BEAEFD83 -:106F1000AC9F70BB62EC62FDECACF4DE533735C461 -:106F2000F7BB404870E2FB81107B9A5B81F216D977 -:106F30005C88BF195F5940FB8246769513DF8FEE60 -:106F40005B22164DE7CF6217FFEEB2E56CDACE5B3F -:106F500078D8DE3F1C7DE301DB6ED86AEF1B45E687 -:106F6000554D0AD26D1DCC443C95ACED125667B31D -:106F7000EF3BBC7235935F2667F24BCA7B4E75427E -:106F80005DB1E77BC4B8C8F39D4231B8EE6CFF46F3 -:106F90003CB707CA24D4FB6643C274CB95A1F6FF65 -:106FA000FCA03923F421F49F68289142FD3353FF5C -:106FB000BED45E97EB0289F9B81ED14B56521ECF54 -:106FC000BA40E252EA5F4E0B284F1760BB58567822 -:106FD00029F96B14F0567F18784136E83CD79D921A -:106FE000739FADF73C1764DC5F9B793FEDC2FFBB3D -:106FF0009BEEA76D1598A287E51CFB7E5A3FBF9FAD -:10700000B635C2EDAE563B8FEA561B0FD787F87DDB -:10701000AF6B6D3A5D18CA7EFF91E3F74AA16CC071 -:107020007A63B3DF3B861A15F6B77042F6EFA91004 -:107030008F3B2E9C3CFC381B701CD6CFDCA0B92E9D -:10704000E4F2AFCC0E99EBDDE5DB43767E919C203C -:10705000BDD294F97E5814343786E6B8F06B3FF30E -:107060009694D379BE33F6793ED66E87407895B440 -:10707000D1E0DDD1FF5B05FD1E92833F677A5F960D -:10708000F5782F18B5C49CC17894A31FED0E717BC1 -:1070900092D1DB263E8F34E5418741BF07EF8198CF -:1070A00080F770EBE85738FEF0BFA0BCBDACB70668 -:1070B000F5A7753F94E87EBBF3F0B596D19D2B1FE5 -:1070C000C5793FFEFD0964074F9692F7875CF6F19C -:1070D000F8BA7E05E91DE1AFE6F0F3FC69217D21F8 -:1070E000B70780E238AD37C73DF98499F6481EDE10 -:1070F0007340724521BD2E132EC79E70CA99E711A9 -:107100000EDB74847FFA18BC271CB8322B9B12F25A -:10711000D71C48D2731EE8F464764B17CE83F19FD8 -:107120008E703685265D8AF3F82BE2ED47A1397F14 -:107130007B7873E8B82879F9001D67BBFFFAFE5029 -:1071400094E46DFDF108E9FDD17D5F20BA96185DEC -:10715000076283F932F560E7D187A10BF5DEA264FF -:10716000039D0B3DC3E818FB95347E8E55062D819B -:10717000711B29C6F9C327976AA2867159CB8F79EB -:1071800007563118286BD11FE986B73C9C7CD38DFC -:10719000C73B8FDF43F2F6BA40F224AEE79D259657 -:1071A0001F353B971C3EE596C3028475E4BF856797 -:1071B000F97E5999D465A487458CD311EF8B214969 -:1071C000E58F8345CF2590A6E7DFE19546A4C7D993 -:1071D000E716BAAF15DDE71606F2B9CB9D7C0E1E99 -:1071E000A72AB0E9106C3BF5F995CB1B17B3F1D981 -:1071F000E29B188FFAEA4A9ECFE39F27D3F9D58204 -:10720000BE1B6A314E042BB85EE6E441E4D57AF544 -:10721000B4F3EEB73AFEBBE3D82EF39C9CA3AF6564 -:10722000EE5BCE33535FCB0B673F3F39D4BE931930 -:1072300057A8C77F72FBD5B6AB1339EE7BE3339FFC -:10724000871BFA5B0EB8F2CC8FE0FD4659F7011EA2 -:10725000EF8DEEFB5DED8A72BA5FCEC094C9DE861B -:10726000EE85AF4F1DB483130B729F477F74A23A14 -:107270007796C4F0BE34FE6ECB817C806566CFC24B -:10728000D75DF3ECD518B459F48481F14CDF07EEE7 -:10729000FDF72D85CB97567BBC881D1F6B172D3FA7 -:1072A000F1ABED7FFB7D21B7D31DFB3EDB7C5B08A3 -:1072B0005F7D61A487A1E6FB0F61BE9F8E5969D0F7 -:1072C0007DF9CDF67DF9CD139DFC2D43437DF2A6CE -:1072D000702EBFAF205C42F1D5E69EF9E44F2E3808 -:1072E000E4237FFA981549C172ED8BF73670FFEBF6 -:1072F00057987E87F9205B985E87E57D957355B436 -:10730000176E8FCCA278EDE606C3932FE23CF13ED8 -:10731000BAA4CBBFD79CA8D230DEDB523B4B45BBD7 -:1073200043FA443995E50B677556317EFECCD61984 -:107330005714605CA28CDF47763D2B3796303B3A82 -:10734000CCF7D9C3C6EB61C453555877E887D6D17B -:10735000B72269FA502EC4B52ACC9571DE834D5FF1 -:10736000EC3DE9D76F29C99BC36CFE87ED7BB1DA91 -:107370009554E986323C17CF040EFA8955EE27441E -:107380003A68993D08F7061BBF97D8E33281243E3F -:10739000ED5A3F25CED7AF5D84BA6CEB737798EB8F -:1073A000372D9AA90D4B479AFC81E7FED0F218CFF2 -:1073B000CF8F313A72F1F3F9F4CEF9A93C9C680908 -:1073C00017A05C84D214CD3F4CF287DA4983F7587A -:1073D000C6C36607D63B9A6BEB2F853C0F9ABDDF81 -:1073E0009243F34B917C77F4C17699EB73A3D50765 -:1073F000F3966C247DF01DC65A649F7D6223C9ED0F -:107400008D3E95EEFFDBB740A67856740A5CEFB66A -:107410005BA4887DFF7F84FBE5F17712D2D3B8DED1 -:1074200083E73CA221A0732EFD13797E693BECAC6F -:107430009942F04DD5DCFB59E544EE67D85615ACC2 -:1074400073FB1B16E6F278D98BB995BFC3F9978504 -:10745000D355C89A176BD087F93450C5CF8F09859B -:10746000FC9C8D0F0C95F36BB586F7860A90A4F300 -:107470006743AE1F78EF177D5C4E3705116F31EE15 -:10748000D789EC1028694FEA32BBF1EC4E7BEEF263 -:107490001F223D32B967207FF7CC0D92BDF76E8F6A -:1074A00042F6E7BB37C3AFD19FF4AE2F072CB654DB -:1074B0003F12C55F3FC5E6DBCF987517E67F69FCD5 -:1074C000FBCCAD02F99B7EF4417002D2BB110511D9 -:1074D0007FCF6229D32778922084303E1B5D04DD64 -:1074E0009763FB9E30E1CF17FFC9C2D767D3FE1366 -:1074F000122BF0BC96F820CEFF9938E461FBD9FF3F -:107500005B25A1FFCAD187BEAA258F22DEE6815561 -:10751000D7C3DA6F53387F6DCB53D218A79C552051 -:10752000921E02BE507A2AFBBEF4E0EBD598DFB97A -:10753000B46226D6C4F169BD4BB4E4719C77B5B68C -:10754000AC3A97D52F3FA693FCBD227EDB012CCF12 -:107550003DCECB3E3FD7E3518F719F0F58FAFE24AB -:107560009AD79B61AECFB6C4CD5E531896AF32EEBC -:10757000E5F59E2F70E8806DEB3AE6A5D3BF75A2C6 -:107580008BA44F1CF43F4185619F3F71E8C1143EBD -:107590000C3DEC09F37DA11DF3CD6283F966EDB6D8 -:1075A000FE36DA7CB34C7ECA5B22D33ABCC3F42DE0 -:1075B000BCCFE37C3EB98DEEFFCCE42707CECDE512 -:1075C000793194C30EDF68F3EE26B9ECBF41A1FB1D -:1075D0004C1D3E72F8E7D29C013EBA0FE5C58AB059 -:1075E000BE98A76898E0E693AB47E0ABA5D07F20B4 -:1075F000C6CA4B65B07298083A3CFFB725935C7CCD -:107600009289CFA50B0478D5230779D9856F6DE0D2 -:107610001EE02C76F250EB7254E6E71E1C3EC5DFEE -:1076200063C1F3631DA201B81FB5E7AE36226CDD5E -:10763000E4DADCB5C80F5B84440AF92132EF54E880 -:107640002686F777C7302D12FD87FAEAA788DF5F15 -:1076500009915DB66DEE1A8A4BBD7B737232EE2FC7 -:107660009B18DE5FA5FD3C3D56A45CDBBEB13C6FC4 -:10767000428FF36732CEDF83FD3D6D974DBB5E1FBA -:10768000D563EBEB919B3F8D723EF86994EF539B72 -:10769000944E15E9A1BF48D5B2E52BA722BCFEE563 -:1076A0007E28C7FB18D968941FD0AA4A353BC95910 -:1076B000C2E5C4E5534A77B9CF5739EDEE6DE822FC -:1076C000BD6653C35E7AE6D7A601F3E882A5968E1F -:1076D000FA87FAC74502EEC770118FCBE3FB4697D6 -:1076E0005EF7695BBEAB785F101B4F6DB274F7FD40 -:1076F000B4AA2864BD47E84894FB89D526A0EFEAE0 -:10770000BE7FA6FC85FC1243F82C969B3AE9F765F0 -:1077100002DDFC7DACC4146E74F51BABEDF2ECA382 -:10772000AAD82793DD540F9A8546A0DC578DFEB961 -:107730008EE5C14ECC6BCEA437FC7BD54537EA1F16 -:10774000AF26FD098E72FDB5BA58253A6FAD577652 -:10775000A2FFEFF7B12ACA67EF88089EFC02E7890B -:10776000F177A611923FCDF2F338BC358DC7E1B168 -:107770008C71787C621C1E9F1887C7EF1887C7F230 -:10778000B71B4C2A633C1ECB188FC732C6E1B18CA5 -:10779000F1777CEE6DA8A3E70F1B52F4FDD9867A32 -:1077A0002A5F6ECB5728E5BF07D6F105C5C4FCA9F3 -:1077B0006E7B7DF69BCBEB7E86FE42881AB8AF07C8 -:1077C0000E35BDF2EF7699EEC98E17E7A3FF126270 -:1077D0002260DCA12DBE9DE9A283F30BC8F7824E87 -:1077E0007177AB0EF31EBFB1ADF70A99E91F25F112 -:1077F000DBAAF258F9C96D2FB7619EE9057AE3CA91 -:107800009DAEB21E99B5E6696DB03CB96CA71C641B -:10781000DF9F89FCB20DE54520C6F5C367B7FD9A29 -:10782000F4C3EE62A600A1BC2B52D248EF37E23A75 -:107830004DC579F07CEEBF83E638E6F94DD6955913 -:10784000C8A7AC7E37E78F51D6C760CD9CF3DB0D60 -:10785000574F2C1F553D3AA73B643DF65D18A69F38 -:107860005668D67A19EC5B7C7C1FB60AB89FB8C301 -:10787000C7E54347803FA7E438F90D55CDD102CC89 -:10788000FBE17CDC11E0F713F44F17E9777BA05E96 -:10789000F87BECE7F3E341C3FCC859D38BF3D14E3B -:1078A000F8854D0F532747F8FEFE8F2AEDEF1F9FF7 -:1078B000FC644B1E2B4FFD17C3C0FD7A0B1841947F -:1078C00027D6562E4FBE553E256F19AB7EF19CEF45 -:1078D000E6A17E3CCF964F69DB8E696CBD6932DADA -:1078E00011EFBEC4E5E31BB67CD9E9EB4DD17ACEEE -:1078F00009D3790B804ED25F1AE332E58989E3F828 -:1079000053F1699FA6FB335B15BAAF49F9C33C95A8 -:10791000FCAEEFFBEDFB8A7B49AF5102492D97BDD1 -:10792000EFB444F253346BC134DE9BB5253C8B7EFF -:10793000BFC12A93296EB6A58CC77F42916BE85EC2 -:10794000ACAFF404A87E6B58A57CE174D99E835536 -:10795000317C8A1AEA07697339DD636969A246795D -:10796000C7EC5FF47D6D8CFC4174FE18BFAFE5F190 -:107970000ADFD843546EFEA446FD839DDF4F2A9A4A -:1079800088BF2791E8F1DE4BDBFF938FA1BF640D29 -:107990003FBF32435BDEF31CFBDE62AA8962C60F87 -:1079A000ADDA3BFB42585E05144F0D4D7FBD298477 -:1079B000F56FD40C9EAFC5CF4B807D0F724BD98A2B -:1079C0009EFFC0FE578660AA81F5AB55E4576881DB -:1079D00017F0DEAA428288BDCF9D25A0DED65A4B85 -:1079E000D77332F8BCE70C5AF2AE54916EA4A57965 -:1079F000344E2B982AD6B76A65DA3F0BC36A37FA3A -:107A0000170A6DFF84230FF253AEF306EC7FE3D722 -:107A1000CA9EF308636FF4960B32EEE12DB7E927A7 -:107A2000136F99F3CC8F3D938BF0E4AFA59313E7DD -:107A3000C17F6F6CD6329CD7386D9FB0B39C4C1F02 -:107A40004DC77BC821D5E8CED7F873E19D51D6D27A -:107A50008BF4304397416778F918F43761FF5B6C1A -:107A6000FAEF28F2EEE3BFB0ED1FC6A76BA37330A9 -:107A7000EE2182E5EA1FE322960B9E291D799EF2F4 -:107A8000D4CEF19EFAD376147BBE5F98BEC8F3FDC8 -:107A9000E2DDB33CE5E95D9778EA7F6C6F95A73C42 -:107AA000B3FB4A4FFDD907977BCA737A3FEDA93FD5 -:107AB000EF95D59EEFF3FBD678BE5FFADB0D9EF215 -:107AC00065FD7779EA3BFA7FE6BE795394CBA30F45 -:107AD000ABF7E3EF03B9CF1D67DA15E7DDAFF3C707 -:107AE000661DE38410E5F7E9CAB8BFB3F2862F70CC -:107AF000FB4C5D68E8286F5645B97C5D9F67DE8E5C -:107B0000F2B532AAD23E2187793D397C05E923932B -:107B1000763039359BECB681EF18AFEE68B016962B -:107B2000B8FC5A01AD13304FAC325A43F70A3AED64 -:107B300065CD04CC9F5B15D5B91EC4AC5EBA2F4091 -:107B400067ED5DF36276225D31D1CFEC48D4FF075B -:107B5000EC443987E2C3CC4E243BD20872BB11CE31 -:107B60004AF4DDF88A40F7F8333B90ECC867C2CCA2 -:107B70008E9C89765BDF169443FD3F9529DEC8FE17 -:107B8000C84E2C6776E2E65CB7BFBCAF089F69D0F1 -:107B9000C6E3B347E916C71691DDF8CF48CF9FD9A2 -:107BA000F8521DF63BBD9CDFBFD731A6368EFA7466 -:107BB000475117F1497F91CCF7213951EAF6031E5D -:107BC000B0F7AB90FA2DB257D93A905C76D6618B6C -:107BD000D097C67B0EAD2F04C92F3EE937FEA3C850 -:107BE0006F6AB13A01F3048DFD8A89E3DD6BE3B975 -:107BF000589B59853F0759125FB60F9F17E84C1FD6 -:107C000061CFD2D27BF6E1F37B51327AE122E3E914 -:107C10002A9431EA42EEDF966728E92601FDD20C6C -:107C20008E2CF689F394A23BF8BD4025F21B487FC9 -:107C3000681D9C6353A8CC5329BE1C40BA10E84968 -:107C4000F4149043B4BF04F0B02A962B843486C455 -:107C5000507FC5BCD1CABC1D44078E5E8BFA6E92A4 -:107C6000DBD10790DE62B5DEF50FA9DF263CB5D883 -:107C7000E7A23B72F543556CDC8E82E23CF4EDA248 -:107C8000DF65994BFE1CB4F7DD477344474F20F97D -:107C9000B30073190A06F522C60F3BC429086F8288 -:107CA000E2F0814312D9FD81BB3BE97758039AA5E5 -:107CB00003E9FF968EFD5617AF243FE1FFC466919E -:107CC0001E1CA8FF5156BC05FA2430670F8DCFE863 -:107CD000050F903E0063823AEEB3F5B1A0B9338B45 -:107CE0007D5017B1ED9F498EDF3341E7625BD12FA5 -:107CF00017C6AD4D15319FE7F69F1678EC9ADB0B52 -:107D0000B81F73A8F103CC1E4DBAE0DBC4FA4539A5 -:107D1000DE7A76590DDDBB8ADB4C399E1B2DDB49A3 -:107D2000FEFCB3CD3AE67DD5D9784D61320FC3DF85 -:107D3000240516ED447992C7F42386D24ADBFFE28C -:107D4000F86926E6F0F8BF6181C4FD773E67DF126F -:107D5000CFE17D353AE8CA5CFB2A005281F9BEC604 -:107D6000FEAF07CF0F4EE970ED7380FB81B73C6D1E -:107D700087B77C61DA5B665AF4CBA807AC00E0FEFB -:107D80008FDDDEEF61307D186F19EFDCB39FE0E728 -:107D900009550601D2775957BAE76B6C7E09E73E61 -:107DA000CC8C7BF5A7EF4993FE7295FDBB1F99F72D -:107DB000BD8FC7DF019941F3F2ECA3B37C12F92523 -:107DC000D09F64B8FC49259AEEB1AB1CBF50A65CAD -:107DD0000F1EBF07D817B2EB937EBC37552B43FF5E -:107DE000435BE1977E73A27CD00FD326A7DE3C4194 -:107DF0007E4EA67FC5B89F04FDD7B7FFF48EFF3E29 -:107E0000E1F267BE1B4DCE46BFC7FD93797BE75EAF -:107E100055E7DCDF3B35F2F382CEE148BAE0B8B398 -:107E2000D4FA385757D2E3D08FE4F8611C7FC3F5FA -:107E30007926E9E75B8CA3A9FDACDFAA5FFA01FB19 -:107E4000592C1D3AD880F26EA24C7925DABCB58F38 -:107E500004D1EF89DF59B9AA481F4BFCF1A28FFC6E -:107E60000EED36DF3BE7571DBF4D2287F347AD6D63 -:107E70000FB09906ED731B41D4932FDECDD6D0B34E -:107E80001F72BFA1E31F9CDEE5FD7E111E0527FFCB -:107E9000E84ECA8332E6F33CA8312BD3FB709D3FFA -:107EA00066AF33C6B72AE70EC659C7AE4AEF433DA1 -:107EB00074869DCF54F6E2F3F493BF20154A485FD1 -:107EC00017611E136B671C903DE746C68040F94062 -:107ED000638E49469AF533E359EFF73270958B106C -:107EE0003E6F39337EC5D4ADB76F10F0F7535302F0 -:107EF000CAB3ADAB988DC0CAEB72EC3CA40BE002E8 -:107F0000A4DBC552D8C0FBF536FC5CA23C64FF89FB -:107F100069BFC0382ABCC4F32EB5293C2EABFD4442 -:107F2000329804042D0433678607E35D5F3D67E004 -:107F30005DFB037EB4C7D9BAE33EF404B3FB4B7CCC -:107F400068C76B54EE62763F969F61763F3EF7308E -:107F5000BB1FDF7F8FD9FD58DECBEC7E7CFE90D936 -:107F6000FDF8FE5966F763F9C5DCCA2D397330BEDA -:107F7000554AF4149CB987F21EDB559F86F4932969 -:107F8000CF2A2B6F575730FC6E0E2FA6784BD56239 -:107F90009E77BF256731D9D303FEBC0C7FE8A07F55 -:107FA000AF4F70FC7B78043A6EDBB3037ED2A44102 -:107FB000F71B8CDC8FE9F4437ED6F3FAB1FDAD6F8D -:107FC0007DE1575F6F669FD6CDD9DE112CC6733F1A -:107FD00029FEDDCE3FCCFCDDAD757B1A291F501983 -:107FE000772C85EBBAA73C4CFA06FE2E13CAED4C53 -:107FF0003BD1B10F33F571E799B91F66E6CB446CFD -:10800000BD64A4FC8D6DBE14C5B7AD46265F70BFC0 -:1080100068482F7CDD77BE7F77B29697714E99E7DF -:1080200067F90FF2BCBD0E486AEEF93BE723C8E6DC -:108030002BE67E46B77F375892A6FB1B826193F4EE -:108040004581E991A4576A498A17B60DF1FBDAA771 -:108050006C39D138EE1ADAEFDB5EF491BE556DE77C -:10806000C9358F53A9DC3C6E6E9CF22B2373D5BEB1 -:108070002CFD6C88140FBBBF4A6CFFD787D9FF2536 -:108080003F3F17D6BC6FBE8AE7A73AC2AB7BD16E23 -:10809000EF88C7284ED0336EAEE77E72295E41F777 -:1080A000594861AE674B7195F46C19E75F3658DF3C -:1080B000A9773087D30F6373F26306C29D54CF2F25 -:1080C000274CF4B7F8633C0FD9AFF1B862B0440461 -:1080D00035CB798D1EDB2FDE5196D4D0AFD31197DF -:1080E000E9DC47873E6BA8B82CBFEF42F3FA079B49 -:1080F0006DBF43739D427A61A23E57ABCEA7730B0F -:108100006790CF3BC24D2AC669FF3F82909C4F00CB -:10811000800000001F8B080000000000000BCD7DD8 -:108120000B7C14D5B9F8999DD9577637996437C91E -:10813000E6C90402060DB8818487C6380991A222D7 -:108140002E0235B4B42C0414E415D1B6ABD5B2214B -:10815000098F2025581F282DDD50B02FBD8D96DEAC -:1081600052ABFD6F04B9A8A8A97A15FDA146B43E8B -:10817000EECF6A04BDC547FFFCBFEF3B33C9CE64F9 -:108180003604B5F77FB1653833E7F19DEF7CEFF347 -:108190009DB38EBCCA60CCC758CB3FC5862E2F3C42 -:1081A0008B18EB8127934219AC9C318F2C3096CDE4 -:1081B000D869FC73317CEF76ABAC129ECB1C717727 -:1081C0000963E168454EFD44C6166685990CF51CA9 -:1081D000BEC5720CDADB1953B13FBD9DFE0C627F48 -:1081E000558C89F26F6BDEF20FFEAE3FC5F41D2C8D -:1081F0008270944A6FF7BA18B3294C386D8332F302 -:10820000CA6F9FC7E8CF6911FFEE09867DA9FBF110 -:10821000B9FEADE6AD8983DBAD2AEF75880A639BB5 -:10822000F7748419943F131482CBCE626A01CC6B2D -:10823000F5FEEB5904E6BF55EA71C900C7D62F8495 -:1082400085E1F2C1FD2FD3F003088B219CF0C776A6 -:10825000FA7CF85B618A63126305F866243EF9775D -:1082600018A5FB34F45F91807299060FFC7FE261E0 -:1082700063B9AAC7589E7CD458662C640F8F63ECF0 -:108280008575D0E9398CCD39F6DE3196CED8DC58FB -:10829000E8F147038CE5ABAE705C666C1E0B3DFEEF -:1082A0002A940B1A3C2C1182C16D6C19AE0B4CF345 -:1082B000A55280AF8111ACAC60591A63AE81FEBF8C -:1082C0002B67123E1A7A17CD64E319FBF1CD2D8C82 -:1082D000413FB13A21BE17E09F5DBF67F62878DEC7 -:1082E0005B692BBA0F1B45EC6FE1FC5CD0D9699838 -:1082F0006FA6EDFA1123A17E789A4768817A3FBE76 -:10830000E0DCCDA550EE993E3A8478077CBDD53FA0 -:108310001FC0FFBC306FAF8FFF6CE589B9A3E0B918 -:10832000B3F2A1D9F89C935C1FFA9B35A5B3D90190 -:10833000FD5DB9529980FD85EB8DED0BAA8D6580B1 -:108340009CD609E7EBCF1A0CEF99E0318FAFF777A6 -:10835000EF3A85F0CFBE007A007C86F113B40F4B64 -:108360007D5208F09C5F2DA871A09B0255503B2DBB -:10837000F8619B463F66FC8BB10C867C56374F8C70 -:10838000B743957C979DF09F3F53882B307EFEB27C -:10839000BEC469287FD3658F8BF03D2BB34BC0EFF4 -:1083A000F7AE64ACA384C04BAF4D5ADF7B5D6DF676 -:1083B00062F83E2F4F6436A003563D8AC6233846E6 -:1083C000123E8E737CB8081F052B438FFF0CC6BF6F -:1083D0007A8A5316A1FED50DFCBB0EDF5609E80CB8 -:1083E000BE6F053A8B119D49C793F133E7D8AA5563 -:1083F000488F734CEFC7CA8CE8EAEF538F8E29067B -:10840000B856091D333C008ADBDEC4182E346010D8 -:10841000E95AE7471D4FABF635133F26F199FD3476 -:10842000F233FE3B8750437CF698EBF732CA8DBFA0 -:1084300064F6EE6440C2BF9059ACBE9AB1FF93D6C9 -:10844000779E00E5DF74346CDA74117C77F7FD9663 -:108450005530E6DCF89D19338A06CA69EDCB67CC46 -:10846000B808FBE3E3C014627CBDFBC725FAE893C0 -:10847000397C5B54B65D84B26493B7874A06DA658B -:10848000613B61887661B65DB268E7D5DB019E36F7 -:10849000C0FAA569F34AD3BEDB347892C797106F50 -:1084A000B2E215603DA4E9928CF4F255E1C839D3EB -:1084B000BC236CBB7DD4E0760076B30EBFCD1AFE34 -:1084C000387E4F1EDF3E04FC5F373ECED49F43FB19 -:1084D0007ED6F041F5F539A9E78B70D9515F298A2D -:1084E000D796D4CFB6EE4F9F3A1F88579ACF426E99 -:1084F000E843B2AB7208E8BC5CBEC3859D4B99F5FE -:108500007204F86133945578BFB9ABC3A5C0FBF2D0 -:10851000D2DB3721D19727D218CA83714CCEBC1F2A -:10852000FA1D274B2C81AB76D1419B07CAEC0A166A -:108530001A0DFD6674A7913CC92CB9E017028C9BFB -:1085400099E952B1BD2773D22F18D10753A4247CC7 -:10855000786A5FA8F3205CB35908595112E2AC164F -:10856000996C2C637BA19C79C91E560FE5097FF796 -:108570002922F2B4C4F55D3BB6473DDDCA0EA17EAB -:10858000C9D3E4CF2687BC9DF4C7751243FDE1191A -:10859000778780F0DC0B5D89C097E5E559B3EBA1E7 -:1085A0005C7EC41652149C4F87508CF3098AA4B782 -:1085B000747CEA7264C24709CEF463597C2FC0DF31 -:1085C0006A8F27505EC5A65E2DEF0578F29724C905 -:1085D0006BFCAB0F7080F03E7DD5DEF612A46FE928 -:1085E000ADE4FE323E8A27509EB1DA8630B60FCC1B -:1085F000940CF23F4D936769263DD09A65273AD196 -:10860000F50153254586790BDABCD98FC2A40F9C9E -:108610002CE47290BDB280EC1081F50AA73D307F4A -:10862000AC887017F1790C6A3F89B767C1900BED80 -:108630001C675A5313D6878F59CD805CE1BA341525 -:10864000F5B3E060AEBC09306F1B8B74019D340B39 -:108650004CC2F2C0780986E3395D9E56B4BB1E73E6 -:10866000B5D8107F2D87417FC03C36DA19B7FFE4BB -:10867000902B0BDA4735FB6D6DC5C85C2C67E4E8C1 -:1086800076615846BA5C9B5D9A8BF661BABFF7DBA0 -:108690002867676EFFE30C17CAD53AA87301E89DF7 -:1086A000CC8736C540EE3A4F153025C9CE734A4DBA -:1086B0000CED29E7A962C3FBC43A98D1390365D50B -:1086C0006BABC771D6642A84D75A26B762BB5A40AF -:1086D0008692B42ECE53794C9968D57FA1E17D0264 -:1086E000EC24C5399CFE3D4C294BEE7F548AFEC7D5 -:1086F00098FA972DFB1FE8D76FE8B74D626447C71C -:10870000025E5A77B35DB031B3EEC64CB4479DAC50 -:10871000A9CBC2EEDC906923BADB186CEA51A17DCB -:108720001D03C6073AB9F88BE322237B06560AE8F5 -:1087300085154A7DFD743C12EB71FAB5C50486724D -:10874000E962C96EE0931A662C9BEDA27361AD11CC -:108750005F365F650FD2CFDAEC34C56901BFFEEC3E -:1087600059C76A4A47C37CD3C2CB18F0F1CFB71FB1 -:1087700076B505A19CCEE9E481EDAFCE88C1FC7A47 -:10878000044E7F6D011BE1255C97DB2926F51B76E6 -:10879000B0D12817C348DF5E0E0F8EDF935DB8BBE4 -:1087A000DD627C10BB06FB61B62AD49426CDAB47B4 -:1087B000B383FBC79B56D0897CD03F9E9355D1781D -:1087C00022E03F79BC9C2F37DE5F717EE503E3CD6D -:1087D0009E6E9CDF6C874CF39BADF1AF3EDE5F710C -:1087E0007E255F623C9C5FF278DF30CE6FB653A689 -:1087F000F9CD16397DF58F97F3E5C6EB59574676D7 -:10880000F04607C827A093B48A7DAE5130EE469754 -:108810005D16948176B5B537B8E6A2EEF54E9B9E0F -:108820000DE3D45D0295F3B19769D36B4B19DB2E41 -:1088300070BAE8CBFCAF4DE8479E9CB9B68CF48982 -:10884000665F5F8955411F5F29717867157AE3CDAF -:108850004978BC17E4880A70FC14F85D057EDC05D5 -:108860007C89E5F8BA203D7783BD8ECF3D002F7E11 -:10887000BF6F5D88CABF5A37859E7A3F6553B8DDA2 -:108880003EB6DADA6E3F2F8BDBEDDBF3E4F94B50CB -:10889000AFD5A685502FB229173235D9AE664D8F88 -:1088A000B9E1FBD66FB20AD48D637670B803F5399F -:1088B00064B7A7551CEC5907E58D925D41BDBC51CD -:1088C0006133ACFCE631A867603CA793B7671772C9 -:1088D0003F2C10EE3D887A6F0EDAE980D7ECB9BDF7 -:1088E00007D1FFBB0AEC72D2CBEC8D83AFC2F71776 -:1088F000C0FF6BC7B2E865329467CDC9A6F1E14FFE -:108900007A6D0EDAEFFCCF4F669E20BF22ECE67A3E -:1089100021C0663FDE8DF0861C4A9CFA6377869103 -:108920000F54BBD24EA2206C473D9D8D7A1ABED704 -:10893000BEE1643684EF1207C9B5B9738D7EC37684 -:10894000774246FB677B45803543FF57CD347E77C2 -:108950003A39BF854D7EC32C5319AC2DAE77C50572 -:108960001968EF6FC4575307E32D7AAC79E3C1243C -:108970003A55B27C81B73DB8106C0CCAB34F58F968 -:10898000B67AFC589845C68AB9FD3FD6C5361E044E -:10899000D4BF80720FE5AD83CB8DC1FCC1E1A9D1FD -:1089A000E4E3BDEB7A6ADE1A3D005FBE1417500F98 -:1089B000142C83F749F395027101FD1D26DE5F81BA -:1089C000FE8D791EF70AF7E7318BF1F4673E93DEEF -:1089D00046BCE052A23C37CFB766D07CAB9F2D653A -:1089E00056FCA46C477B6ED66131D4AC0CE0439F3F -:1089F000FFFF345FBDABE19BA90196007A7916E8D1 -:108A0000BD9DFB310CED549D5EA102D94F575E090F -:108A1000DF912E54B508F1F9ECC8BE3DD7603B900C -:108A20001D2DE8EFEA7650E2651BDA415FB6DF2BD9 -:108A3000AF7390BDC558BDFC76D9407FA9D607FB62 -:108A40007D3B497FF6DB89F8679226FA10C6E6502F -:108A500090EC819BC03E467F3F5AFF9E94CEBF1F45 -:108A60004FB253F1CFF1A4FE5ABA7F2D280057E739 -:108A7000BAAE9AB7EC03E3962C936D6D68CF35C709 -:108A8000058A4324A01ED803239729B656C0FF1297 -:108A9000EC07E9D324D747B6423FC9764AF55CF9DB -:108AA0007EA087D6F2BA8E103C37EFE0F132BD7E61 -:108AB0007FDC2C1023FFDCCE9A9800703ADC3FFA62 -:108AC000792FCC476D9198BB06CA766EEFB0577D73 -:108AD0002417446FD32FF17B3006720BE75DD7F478 -:108AE0003B2CC76C2CDC02CFBB3DBC7D5472C94E05 -:108AF00058BF76B975064E3F272F726F168CD796E2 -:108B0000934672D0F19A6F37CA2947E6846568F7B1 -:108B10002C88FE308CF148D9CF16862DE86B816603 -:108B20003FECD5E8EC983D519409704FCFABDB9BFF -:108B30005565513FFA23EAAF46B4B6C31ED5FAD9FC -:108B400069B3960BFF9EC5E39D57AF7AE8BDFB6006 -:108B50003E9E526F08C96DF3F96C9F601B5CBF3B72 -:108B60003BF287ACA478ABBB5496280ECABAA6A237 -:108B70003DB7F9F39F76FD0E509EF5B997E46C96DC -:108B8000E88B0B2586F68F26CF436FFF974F5F0C40 -:108B9000E2FAFCC5CD48BFB2D8D397AA18D7D4CB38 -:108BA000F046C072A65EFEEDA5E86F0E94AFB9B4B4 -:108BB00016CB48BB409435FEE866D4CF5B05A611C2 -:108BC000F14DBCBE9DD72FD4BED75CF6FE2FB6A10B -:108BD0003E98E4203F74AB6607E9F0A97E91F0A3CC -:108BE000FA87C6E36B1A9E5DC3C7E36B567838906D -:108BF000A7BE8EF875B32E01E9D8FDB9EB466C7FA0 -:108C0000CF3A165E02B0EF54F6FD7A9B42EDDFB626 -:108C10005A87F3F3D477B2088EE3BFD80670F8749E -:108C20003826B31B53C0F1E150EBF9A71C2EE7BE69 -:108C300015E0CF2CCDDE74387A82B3E12957DE758A -:108C4000830CF2664349578355FCF9333FF70332EF -:108C500053C4DB037E4E7FDDB9E1D30847ABFC9004 -:108C60000BC74F135818EB6F99D2CB84A47E4301E6 -:108C70008E6780DBE987766953998A74E663BE382C -:108C8000033AF35572F8B7045F600AB4F395C1D3A1 -:108C90008BEF7B89FFD1E5E0F400820ECA0E8D3E9A -:108CA00002FEAD97A29D9F25EAF457D48EF4E2B060 -:108CB00069F563459761B9338B9727DD51D41E2B36 -:108CC000043DE380362817F21D64EF98E75718E05B -:108CD000F3DB96ADE6FBB32DF0E9ECA575DA3ACE01 -:108CE000118AC1BAD6D87A1A1AF1DB655EB2D7E01A -:108CF0007D433C69FE976BF8BADCCFEDADAD9FBA12 -:108D00001AE216EB918A4E276AEDCF824E27FA2D92 -:108D1000E803E8B412F19F44A71F336B3ABDD06F4C -:108D200041E740A7D5F8DE8C0F735964EA8E450001 -:108D3000A0F4D9F45F6D436D7579F58EDFC1B3E6AC -:108D400073AFE4873AE2184676A2CDC5E5FB80DC36 -:108D50008F5C86704B7213BD17BD61DAAF792E2B15 -:108D600045BF9327ED40B9358C7EE721DCE67E4B8D -:108D7000FD8CD6A3E6326F246E81F77FFA256E1F35 -:108D80000778BD54FC322E60A3EF29F945A7FFDC1C -:108D9000F05284E34CFC523FC02FAB86C72FFB88B8 -:108DA0005F3CE59C5F3C29F80523D1289F3794F070 -:108DB000F28FFCB9C40FFDFCC3CAE87B3FFFB0B221 -:108DC000CBB0ACF3CF658132AA6F6E9F8EF3B6C085 -:108DD0004B9B5F9F47B815D7553D4F6E15C9DEE8D1 -:108DE0006528A73A595FB713F9B05A08ED85B7B3AC -:108DF000623DF52E05BFF7B0D9607F6CD5E87E17D0 -:108E0000C283FED0242D9E25F5B0AB7C83F9D857C4 -:108E100099288B24E17FA486C76F07C277E0F89D6D -:108E2000AC772CDAA5A9D6E91E6DBC9B82EA3D562B -:108E30007C7F26BDF328EA9D6C7CF27EB23E7735BE -:108E4000A11C30F379CDEA87DFBB6F887E1ED6F098 -:108E5000F6D0D9F3FD4329F8FEF726BEAF14465AE3 -:108E6000F2FDC329F8FECF567CFF15F8FC3FACF8A5 -:108E7000BCD33F3C3CBB035CBFBBB5F5FDB2787EC9 -:108E800047C3EFEBFEB3B6035EB7C213E0B9779802 -:108E9000787EC76A9D00CFEFFA69BD6D31DC17405F -:108EA0007E47FF7DD3E4581FEE875AC0D197DC8FF1 -:108EB0004BE1FD8069FFB100745EF3D9A650C48216 -:108EC0002FA1DD3F92E1D7DBDDE397B5B8B3723D6B -:108ED000DAD53B2FF7F2FD846CF5732B7EF80AEBA5 -:108EE000EF0C58C8E31A1B9743DFF6BF4576DE57F1 -:108EF000E8DF6FD5FF331A7D9D49FF8F49D2FFD838 -:108F00008F59DE75321E4FD9961D290910BE7A2F52 -:108F100045F9B4EBE62C01FDBA423521A0FD9FAF27 -:108F20008D77BB5F21FAD2DBED92128284F59B64D0 -:108F3000212618FA3B6FA8FECC70007CE30324DFE7 -:108F4000D4F3F1798FA6CFCED61EBA30A84E0E70CC -:108F5000393D15C757CF31CA697D1EB67017EB452D -:108F6000FD02EE77DC82AEF2357D09FDD4513F9AE9 -:108F7000BCBF20206BFE29EFEF6CF50DC07739F6F2 -:108F800007FD5E61059F192F6782F3960138AF0ECA -:108F900058E825737FBA7FADAF13E9D3A4B8CE12DA -:108FA0008D5E80AF1A113E579B2DC60203FCABEBC2 -:108FB0006B904C69D8FF4E078FA3EE5C797B2DE652 -:108FC0001B74DE2257204AF297713DA7AC2CA6B83D -:108FD000EA6AAD5F33FCFDED1D5D632796D3B86B88 -:108FE00071DC8BAB5902E54606DA09147F90258CBB -:108FF0002F64393B821897DD2C74342C463D7AA9B6 -:1090000097F42D0BCEB58C4FE94F3DFEA4CF9B05B9 -:109010002BCF50BF99EACB9E8E26B493865DDFD9C5 -:10902000616957FD44B3AB607E3F1E12AFC100C5FE -:10903000B774FC0E1E87AF5F6DB849407CA795C31F -:1090400090C09269E10EDA6CB595C6592FDA4F657A -:10905000402FD4DF0B9671BF81FE36E8707522FD7C -:109060007C55B8F47AA9C7E3F570FF8CE21D5E2E3B -:10907000B7E803944F1CF65BEE1FE8CF8DEB645509 -:1090800002FD73425632305EB851D383E09905AF8A -:10909000F2FDEBEB0DCC23CEE39DA6FA51C6E99E83 -:1090A000055D64DF61183E996E8E6A74B02D27FCF1 -:1090B0007480E4482884740DE567495EBAA0ECA387 -:1090C000F25FA92CF7979FA7FA415E9FC9F2B0F013 -:1090D0000CED5EA176527F3FC7A8ECED1FF7351A65 -:1090E00027D05FEEA5EF85BCFE70C7495A573EFFFB -:1090F0001E91E6FFB1A466E0FEE837A38D14279A1F -:109100001F5D4ECF4DEBE45A8CC73DB3AEAFB515E6 -:109110009EDF9CDF28A3DD3F7FE94F68FF5EEFFF06 -:109120004AF42B90DF156906D94525B6F01EEF00ED -:10913000BF0DC0D1AAE9FBDE7AA42397CAFADA2BC5 -:10914000A0FD948F5A5B0D794E1D943FE356A4CF3A -:1091500092E3EABA1CFCBB433D1D383B3A36CD973F -:10916000B18330FEC7DED2788CE8BA4EB6E2177D06 -:10917000DEA9FAD7E79D4ACEE8F8D3DF6F2E9D200F -:10918000F3FC9FB8012FEED1F594EF73A5A0C1E9D0 -:109190007369FCC6EBCD82711E2A27FA50907E6758 -:1091A000697E9C592FE8E3FEDD1119938DEDE0CD2A -:1091B0002D132CF03B4CBC1D5DB72C5C6F4779DC4C -:1091C000E5A6FD7B26539C5FAFD79062FE75D95C08 -:1091D0008F30A74AF3D9726B461CED8E2D8BFE2083 -:1091E0006370C533EEE32ACCD7F4087D9F2C46F993 -:1091F00072AB8FF2311A167D52D59CD4FFC2037F19 -:109200007261BCB761DCFA6C8CBB2C64D2C7C9F943 -:109210000EE6711BA2AB896E63CD428395BF752CA0 -:1092200087F3F5424C9111A9BFE3C9FBC88B9409A0 -:109230000E8C4F2C8A19F77340433A903E1A379997 -:10924000DF27EDE788D83FA379C770330FF55E9B22 -:109250008DE86D27E00DFDC0625097F83C9693A510 -:10926000F1410FE1F35F0DCFB11C6E0F395D2CE6BC -:10927000C91AA09BDC480743FDE4AB14687F33E0C8 -:10928000D3F323BA484FDDE1D5CBA0B700FFE1729D -:10929000CDCE29E5DF6D5846FFC7D373D0067CDC01 -:1092A0009EFDF865C1B1D05F79246893A9FCA44400 -:1092B000F6212F33F6F89307C99E95CF1542C0FFCC -:1092C00052F793878BC89FD7ECB1EE27C91EEB2FBF -:1092D000B30483F974A6F597555710CA23FBCB3115 -:1092E0002CEFD2ECF8F6ECEE275BC93E09B7652708 -:1092F000E9EF5AC6E3CB5FB77EEC0C2EE9C07CA247 -:1093000058A98DFCBD34133F3E98EDA07A637223BB -:109310007767C373D62D7D12C61B1C792F04500EA0 -:109320008C283DA18E04FA1F51CDD36458191FB764 -:10933000B3742DD90D9DDABAC0FFD6A3DE1B589F9A -:109340001ED3FAF0F50857F6D0FAF8CA7B68BD6C60 -:1093500058A6B81FDF8FBFA292DB1BB293EF2BFC86 -:10936000269BC75DFF942D6A4FEE976694DE4EF103 -:109370001DF70C1BD5CFD09E6639FEA76CC9A05730 -:109380000EE445FE909D64B7C2FB705925CAB740F4 -:1093900016EEB3D6964A37223DFF5CF34F619DEE41 -:1093A000A0752A09A445F8BA3D62B96E65C35BB7DA -:1093B00017D745485EA55AB76FCE17C35671B76722 -:1093C000353C7CD0F0B7BB902D57B9FA1CB80FB321 -:1093D000B974BB21AFDAB56F760273A1F5BCEAF5BB -:1093E0009EF46A94DBE6715FFCE23F0288DF999F9E -:1093F0003A2DE5E37F6BF2F185750DD40E16589189 -:1094000072480E309EF7D29F27269C76D2F45EC417 -:109410003CB4EF12EB333637FC06ED572F0E8A0CB7 -:10942000F7C71732635E198BEA79C13C0FF645091D -:109430005C5340E18B31210498628BA4D9BA5C3132 -:10944000E487CD9B3BFB10EEC3376AFBF0205F0C3B -:10945000DF979AF2C6AE6E5814AED7BE9FA4BFE394 -:1094600034AFB90AB71BE77ABDA45FE785E787EB9E -:1094700093F6E35EFAA76899875E97A3E3251CAE8F -:109480001F3D182F8BC3824356CE8C1F333E6A2557 -:109490008EAF451ABECCF831E3A171EE6C5A7FF362 -:1094A000FC5F7485093F2F027E305FD88C0FC62287 -:1094B0005720DDBE345F64681F4F1767DA314FA055 -:1094C00071B6C030BF68290BA5F3FC6075D625497D -:1094D000F09AF168C657E3A32C94807E1BEFF4D179 -:1094E000FA3DA7E1474C7C48F30AC3BCDAF9BC8ECD -:1094F000F3FC5599E675955AF17800BE475A41DA62 -:109500002A567A84CF6731CCA75D1EAC4F3E61D519 -:109510004D48274B4D790B66F8CCF0CF4439387560 -:10952000F03EFEE41C5F80CE2F8C67216D1F3F83D1 -:109530008E3584B287CC5B18E0734E5F0BA3B3FB10 -:10954000C7C37E0516E92FCB80DF994FF8B7CE83CE -:109550007FAF0D8A0AE609CE9E3FAA0DE71F66E19E -:109560008C4409DAFB7D76942357313063A1DDC545 -:109570003049D4B7E17A3795F57E4F747C64273D46 -:109580001E614D7B69FF5DC9983B2EB57C591B74EC -:10959000D078663B6566C5E80C9417667CE878FA77 -:1095A000568E96DF309E8D3F1BBCF4A0EC457F1697 -:1095B000E368B08E7DCB19DB5D31B07FCC0A556E90 -:1095C0004FE630DAFF5F9D93A9D91D4D147758A05F -:1095D000E9856376D6F0A097EF234F48928F0BF37F -:1095E0006A57E724C5FBF47D642FEB25FC7DD7E5A6 -:1095F0004D88E389EEDEEFA70F925F7ABE6684F2B4 -:1096000035C58C950AC5C53CE9E35906D8C58CCF4C -:109610001BFC989B7230AEE7298EA31130F3895F53 -:109620006C9AA70CACDBE6257B3B105CF7D2DFC75E -:10963000A87385E77378B475ABD5D6ADDF8E2E836E -:10964000F749F83DD1A1D961655A1C1FFF40F94483 -:10965000A91A1FCA7FD5D7D15D06FE87218FB08397 -:10966000F0A7AF2738117DC89791A04439C336E6DB -:1096700022FF387213CFC758C8945D981FB4306A60 -:109680003F91DC4F244F2238229BDD5ADC2444FDDD -:109690002CCEE3FDB032EEE7F5D37D0CDA27E53FC3 -:1096A000DA5C604A62FB4C1642FF09FACB417DCF7F -:1096B00036258D3372F0B8A9FA33B713B5FD5BD1F7 -:1096C000190A8592E4F46F72B89E3C11ACECB28D2D -:1096D0004C8DBFC52EBF2A25E5C51ECF733558C595 -:1096E000C5F4FE74FDDD6F27C6963F956C277A376B -:1096F000343E75F8A2243B31D6F814C515F5F2595D -:10970000DA89CFDFD5F8542BCCEF1FAF7E83F2C7B9 -:109710004F3481C0043CFAA3D3D89B7E940F32E926 -:10972000AFE206F0A830F95B52C622BDBBA305AA82 -:1097300094942F7B2C4721B8FDA52AED9741D32E79 -:1097400074C5FD524840BCDDAEC5CD8070C7CEF6B5 -:1097500025B7E37E883E9ED325131C0E7D3C166AFA -:10976000A6FCFA998CF4889E07A2F3B5DECFBB392C -:10977000C678DD30F8F9DD9CAAC1FC2C8A4DAFDF3C -:109780008A72E22991FCB0EF046FA2F7E678C089F3 -:109790001C6E1F8E102327502EF4343CFF9D1F405B -:1097A000BB35FB9C2154C3ABBEFFDE8FAB14C4138F -:1097B0005FFFF94B1BEFACC2798D9664DADF28E2CC -:1097C000711847B340FEABBBC411DE07CFB703B57A -:1097D000237293E07A3B504FE59133385C27A0CF5A -:1097E0007605DB6D6F207FD1C7F7BD4F280A9DEF4F -:1097F000133D8CEC09D1C99F99B9DC2ECDCCE5780D -:10980000766B4FD729811609E9BA09F72DA418E517 -:1098100041BB4E49F4DE210896F69ADE9FEB140810 -:1098200067C497C7DCDE41EF713ED85EF433837DB9 -:10983000938FEDABF0C9E9DD75CAC3E1F09BFB493D -:10984000E7EF35FE33C37163CEB462C4CBDB017581 -:10985000442E8F6F7339EC7DF2A8307E38F298E792 -:10986000EB5F9127B928AE77AB101F0DF2A9BDECC5 -:10987000441BC9AD1257139E934AB29F047EEE86D5 -:109880009FAB18B04FFB2E995389D16BA6DC1B1AE6 -:109890006C6FBD5EF9C9BC3958D0CE4F7C5797BDAF -:1098A0003128833DF79A565CA48CDC80A1FE2BAB5B -:1098B000B97DD688F65988E496C1EE32DB675ED072 -:1098C000F773802E96062519E9C26CA7B557CE23EB -:1098D000BBA61DEC1ACCD71E6CA77179735BD4C6DE -:1098E00054A8F74CB5487EC63365BD4F5C8CFA6210 -:1098F0008A5D217D51D677DB1CFA3E91C6F16AFE66 -:109900001DD4E7E71D429EF86878F76CF59BDEC62C -:10991000A4F57E66CA9B63D12FD89522BF428FD310 -:109920001CBC99E77FBD7E87107722DE6E116DD853 -:10993000EFC20A1FE5AD5E227A699CC6AD62DC49C2 -:109940003854D32FC919B01B99589DF33CE2619B41 -:109950009DE1F9C1A21B7B0D76EEC2A8D19E8B348E -:1099600081FDA39CBD1D68B6FFCC76CCDA5CCDAE84 -:109970009BC026A0FDF2CCBAFDECCDD10376CCACD9 -:1099800014FBDFBA1D7381ADEEE65C1E17A4FD83E8 -:109990005992F5FEFE559A7FCA42DC1FBC447C9F5B -:1099A000D6EB444852107FDE9B9EA4731DDE7F8A57 -:1099B00061ABF1B6E7727F7C978391BCDD35C14323 -:1099C00079D7DD379F9BDB4BEBA5DC5D8DEBFFA4EF -:1099D0009DE4602AFDE68E8AAC1426E68B0AF4D458 -:1099E000D77344D4CD92F5C38814790ABB73B9DC1C -:1099F000CEBE85D9D0CFCE8C31D5CA2FD5EB813F05 -:109A00003A1D63D4503F9109F0AD2EB551DC5FF79C -:109A10004BDD767EDED7FEC8F531F44F47007C087B -:109A20008702F0A11C2E897AA83C32EAA7E7A86831 -:109A3000263D4BA305F47D7474143DC7444BE8FDEB -:109A400039D1F3A85C169D48CFB1D10A7A9E1BBDCF -:109A5000909EE781DEC27AE5D15A7A8E8B5E4EEF18 -:109A6000C747E7D0F3FCE86C7A86A2DFA6EF15D1F2 -:109A7000467A4E882EA2F713A32BA85C19BD81CA83 -:109A800055D1EBE93929FA437A4E8EB6D0734AB4F0 -:109A900099EA4D8D6EA1F205D19FD0F3C2E8767A96 -:109AA000564777D2779D9F3D9A3DFD74708F4CF954 -:109AB000F62C518EF231151FBEA1E9856FE4AA4F35 -:109AC000A03CD5EB1DD1CE1D98EBBD9A3B74DECDED -:109AD000D15C4E9F1F848EDF85C769F575DB1C1C2A -:109AE0003A8EC0CA0367D8B7E2F33B9CCBDBEF9258 -:109AF0003AC8DED8D5C4281FCC57D923503E43508E -:109B00009A61454799417EBE6B4C6EE45D9CA737D8 -:109B1000EFAD83B81F7565AC27300DE92514489B60 -:109B200006FD8D68B5917BAD3059C0B252CFE404CB -:109B30001B88E7807D65D06BEEA04D8BFFF4CC9C3D -:109B400088F09C5B3A81EC576D3FF9C8CD2319FA38 -:109B50001DBB1C09414279B996B1643B7CD786C5CF -:109B6000F7259FD370071D9C8F36B1C7304E56D254 -:109B7000A1D4E179C2513BD4C730C573743C52972C -:109B800006E5737E157B0C9F63BBE2751E789EB75E -:109B90003FF118BA4FE312BD755E289F7F981DC034 -:109BA000F053458F32CD07E58947D503B84D52D5DF -:109BB0001B9996AE203CF196748067D76B60684124 -:109BC00079CAFB1D22B82503EB0F76DB8349EBE254 -:109BD0002EED5145F867E18D7205CAD95D52AF3B54 -:109BE000B37CF0FA74E2BC719EA057F66AFBE8728F -:109BF000D27A5405053D1E9817AC1A880776B63EF2 -:109C000047F1C0CE34B916435D7D973079B7827481 -:109C1000CCFD84B4B691A49F74BA03FC1AEC49B786 -:109C2000D6EFAE7E7BD31ABF55FFCBF07B50A3E7B8 -:109C300054F87D1AE79177663E9E1EE47615F07122 -:109C40005D303B75BD15412E4FCD78DE25C9E7123D -:109C5000BEBCCC16AB1858B76B34FA3E135E23FF6C -:109C6000CBF07A517068BCB24A3F8F336BF969A967 -:109C7000E4CD9114E744BEA7E13149CEF178A90CB7 -:109C8000726E546A39578B70650F21BF52E43BAC3A -:109C9000D7E8BB3B3B1C0B669F39AE7F9B4DAEC5E7 -:109CA0007C97D878467E02D897AD98BF3322A64CD1 -:109CB000A06D2C14CA88C709E7919F5E02F686340E -:109CC0008161AA63029F575466DA1697635E83C662 -:109CD0006FF2A26032BFE9FA7E801F75BAC8EAA4AB -:109CE000731640AF984FD8ADE169A01F1E8FD87092 -:109CF000537E677B921CEC0C155059AF9F8A7E5F98 -:109D0000D7E9B7F539DAEFBFA2DA3ADFE4CF41514C -:109D1000CB3BEA5391CE63354CA6F3CEADC7493E5B -:109D200065827C124A787808C72F8CA6DD8771DAA5 -:109D30008783399A3F2EA77DD3F7FF8F9EB781AFD8 -:109D40004E7E66B5DC8DE72A46801E52504E560385 -:109D5000EC95A8E71CB4EE0AE3EBA854B3784220D4 -:109D6000BC25D06F8ED9F8F98C238E2E95F48E23D6 -:109D700053C6FC93EEECC813C121F842F62815B87F -:109D8000A8AF0457CDF4E6615E8E9C86E597A07C73 -:109D9000DB14CC13EA655AF936EFD42F1F7F7865B0 -:109DA000C78A23B84F7561503D8AF0005DBF827449 -:109DB000AD9E234B141F1EE6FE93CE9F03FC24573B -:109DC000E8FCB4A89CE4E15BC1A4FDAC54F6CD2E44 -:109DD0004D7E7E121CDABED1E9FEACED1B0DDE37E6 -:109DE00035B9948AFF673EF1FC8E3D6C20FEE7CBCF -:109DF0007FB14752D0DE9EC6DE9C8871AF1E4EF703 -:109E00008CC7F9548CFF011DB82B5DA6B8AD30434B -:109E10008BBB0C19AFD5E3C97ABC4F8FEBA56B7424 -:109E2000851706A01E4F9F224B8BA9BF5E7615E6B5 -:109E300037E5D90C7C8D720BF7E75D6D59D2C8F20E -:109E4000817E196B2239D5D9C0E4F64CBEFF9A0148 -:109E5000F2A5633D233F2FF68C48FD9F546DEF61C3 -:109E6000CEF7C94A4020CA059529728E760E8188A0 -:109E70005C267A7532D685FE36FB51C8E5C038F7C8 -:109E800067025301EE239F89F49430C20D8DAE0812 -:109E90005584B0716D467508F703C537A10C70D6AF -:109EA00067546760F9C89189216611BFBB3AB2C88F -:109EB000105F32E3A9BFDE77DA285F61E719F63F6A -:109EC0002FCA73E876E7E43CDCFF5CD2D7EA5006A1 -:109ED000F63FF57DBDBCD2872EC57B76F25672FB70 -:109EE000339FC59B93EDA6A4FDC5DABC2ADC4FEFDA -:109EF000DF5FEC1993BCBFB826FF163CBA7F4FFF5B -:109F0000FE62A412EBABFEAE0AA44F3D1FF688839F -:109F1000EF03B0894F05140BFA5850F17836D1A3EE -:109F2000E64F0CFAAEC5CDCC7EF09C3C631CFF64C2 -:109F3000684E46023FA688E3EBF13CDD0FC6789DF4 -:109F40006CC97746FCEBE32F10B81FCBEC02C93B82 -:109F50005D6F823C598AF88666148F569D02E56BC8 -:109F60009D0C352AE417A5902FFDFB062C31DA6AEB -:109F70009F75819677627EFFA33CAE9716D8799C39 -:109F800052B87E6904C75D90E7129C4976D28A3C3C -:109F9000AEC7F5FD1747FEA92AC4B3C31151ACE6FD -:109FA0006DDE475981B66015C753C842EFA5C2D3CD -:109FB000517B07EDCB1D5D2AD279DD9391C974EFFA -:109FC000432AB9F00AD2CF68C6E6E5733D34B08EB5 -:109FD000D678D3F364CCFB55FDDF17B9E9FC8D3996 -:109FE0005FE6210D6F4F6978F957E7CB3CA5E1EFAC -:109FF000692D3EA3C7B3AE4821EF2FB0D53D90C722 -:10A00000E38C43C665CED3F37D34FCB00363E95ED5 -:10A010008E2D3DF6B85B40786CB47FD9F09F620816 -:10A02000ED2FBD9DD7242FF4FC1DBDEC3925B07854 -:10A03000D23E8247EAA238A9E79444EFCDFC775B91 -:10A040005EFFFE22F19FBE2EA9D6595F17F3FBFBE0 -:10A05000B47539BAE84F413CEFB2C5CD2CF38958FD -:10A06000BE31FE6ECE0348B5CFFD9AD6FFC9C8D427 -:10A070005C94CB0D8ED8E8E1F0BD8E9F17BFF8A39E -:10A080000BF96CCB29E70CABF57849D34FA04F37D0 -:10A0900025EF83FAE63FDF8ABD7A24E33EA8AE4F80 -:10A0A000F57D504FA5791FCD7A1F740BB3968FA9FC -:10A0B000F64107ED7F6AFAF6B3BC14FB9FE5439FB8 -:10A0C000673F90C78695F771B5839F9735BFEFD1EE -:10A0D000F8EE646473D15DC057372C7252965262A9 -:10A0E0009193F8B071919BE2B28D153CDEDB78A7BD -:10A0F000A0EDD719E3B04F83BC5809E33FABE99D0E -:10A1000037597812DAA3B32A05C33E79B8DA6D2835 -:10A11000CF5FFA93A7F1DE8467A6D8158A3F435F25 -:10A1200031B40BAA799E2253FA6EC338B71E7FD67C -:10A13000D7FF99EA37E91EB418D8F9A343187F1658 -:10A1400089BF9E796122BF974E18D80F57C04ED84D -:10A1500072C128CAF778B9FC5B14E7DD8271719887 -:10A16000E9962FFE3883E80894720CF9757C561C2A -:10A17000E563E3B80939489707C67FE6C3B8E8EB5B -:10A18000B79CCCC675EA5DD7447907E67537C799A1 -:10A19000CDF1E5B38D2757E71BE9E169533C5997AA -:10A1A0005766F991144FAECF1F463C59975BBA9C46 -:10A1B000D0E5D7CBE5EDAFEE867FBE1C71124CAF7C -:10A1C00068F3EEE74B8D2E5FD6F9F00B27D9230706 -:10A1D000C63F4CF9567ABDD6BC4CA2AF6F95C7EDC1 -:10A1E000B43F8B790A6503EB323FB2BCBF8CDD7E96 -:10A1F0007BD9F506FAE8975367946343CB29573E1A -:10A20000B7C352E56BF6A4D43FA3C94EF5FCD51EE7 -:10A2100077957C793DD4B0E80F0AB683E70E6A3FA4 -:10A22000DE11895BE827333C9E53228B4F4C7EAF77 -:10A23000F0F7FD7AC041DF6375CAFAF5016E4FB7DA -:10A24000107FC69CB8EE52B6DA8A749097ADB6E528 -:10A2500043BBDF06D40DF949F2B4C5CEF723451B45 -:10A260008B3C688197C7F235BCB07010FB6BAB3587 -:10A270009EE7D29FBFC997B4F3189382685FB7BCBB -:10A28000511144FE39E89B44F676AA75DBA6F31318 -:10A29000CAAFD103FEC4566DBD814555DCC76DB351 -:10A2A0008783C9F1C6ADF99CAED2A73ED48376733D -:10A2B0008B6CA33CC11699E75FB77AA5197BB4767E -:10A2C00001433B493F4745F765485E637EF5636858 -:10A2D000EF54A59EE763F9DC3FB4B3C41DD5C2803B -:10A2E0005EB11FAF75D1FD0F4C95797E53C8904F6D -:10A2F0006DD7F44B9D295F4394BF9CDF569C1DE9AD -:10A30000C6F534FB6D8702EA63F83E2AC59C481FF8 -:10A31000519735DF1FD6D6B5459BAFF95E55D17441 -:10A32000EF8368BAF72156D7F4CB5EA4B7F54EB9E0 -:10A330002540F73CD0BD0F51BC72099EFF70F37CE5 -:10A3400016F0FF26F3F306A15E94AF2CE8A2785432 -:10A3500047A1AA164259F4D976AF87FE5AD43A15C6 -:10A360008FAE74786D9DB8CF979317790DE731CD87 -:10A370002791DEE9B82C8DF4107C777339C26461C3 -:10A3800012F98374690AFAE078BECC1E74503CABB3 -:10A3900025C27A9DA3F8F97FA4F75A9638525D82B8 -:10A3A000F6B6AB12F17424343123622127F4A77975 -:10A3B000FFFFD5EFBD544CF9AA62E4A37CDAF76F36 -:10A3C000DC8AFBFA6BF68B21DC47F8CEF75F1EC305 -:10A3D000CF1B19F799EFF6D4F4A23E8B7A1D54AF38 -:10A3E000DB37A903F1D422F83AD0DF6D79E3FA9F85 -:10A3F000231E5B9A799CDB8CE783BEEFD3FD1A2783 -:10A400006139B1BEF97E0DD6713D5F27A78BF62D60 -:10A4100061BEF6822ABE8E141F3CE6A37BA04E1EB0 -:10A4200039E045F8BEC2BC65EC37F5BC0B65D257C8 -:10A430001AFD3029BC09E7F503D1D7D11EC07BD264 -:10A4400060BD11EE47ECE4EFDFED49A7758D027CAE -:10A45000B8AEA2AF5E4597ECC3FD22AD73546AA2BD -:10A4600079B198C4F6E2FB473EF9F18548076A16D0 -:10A47000ED6A89454D84970F012FEB2DF002F433DF -:10A48000A600FDE5476EA07E3A1C2E192D9B16DF17 -:10A49000243AAF3CDCFB452A0A847E7F4BBB5FA499 -:10A4A00002FB1D545FF3B3D0DFC6EFB532FB38CEED -:10A4B00006F09E2A7F452D30DACFC3C85F510B2CA2 -:10A4C000FCBBAFB0AE97170C49CFC6756D71FDDF01 -:10A4D000E96867A9627AC85D0C655C27C43FAE1362 -:10A4E000AE9716B72115A4201DC88902A4831BD2DC -:10A4F00043489F67921B12E3EB6E97809EC1AE7339 -:10A50000CA91A37476518BF7E8F2C4CC672D2EA3C1 -:10A51000BC6AD1EFE53B363C7905F4B202F16096B6 -:10A520005BC3A593EF0FA693EF0F45276979E12849 -:10A530007E473C154CA078C5CD583E7244DCE718E8 -:10A5400089E3F1B8595F1E937727E565E9F06CC69A -:10A55000CD6ED2CB3C6F4A6A600CF3E0FC652141C2 -:10A560002E1F161D6DFE9AE9E88EA1E48397F5D0A3 -:10A57000798D557A7ECEBEA1F373BEAAFE81F5BC5D -:10A580000FE169F17D9FE87383DD25F37BD4CE6E07 -:10A590005D1F2C10CCF70B3D988CB7C1EB1AD987F7 -:10A5A000EBA8164CA27B8CD8944564377567ABC773 -:10A5B000305F8C4921835C1CC43F9ADCFEC1390AA0 -:10A5C000E5ABFEA5599373CD4E19EDF1C70337FCEA -:10A5D0000EEBDFCE9430C6436B6C6B094F1FC2FC91 -:10A5E000768748AE96E1BE4F94A585343DFA1F08A4 -:10A5F000CF0CA559C882F781058A8DAE2155B63397 -:10A600005BF9F0F1F0DC603C3C37141E400EFEA715 -:10A6100046CF37223DEBE7ED53C9C137B4FECF42F9 -:10A620000EBE91CC5F5F03FDBE3FB47EFBDAE5CD8D -:10A63000A7389E59DE78357EFE6E8885305E3EDC1A -:10A640007C36B03715E4AFDA7417D14FCB8302E50F -:10A650004B811D1EA1B2CF45C2E6A0CFC1F37FF74B -:10A66000F1EF621DC7B3194F42213F9FB5AAEBFA24 -:10A67000B064C8938AF1F39AEA09B954C4FCFE6A3B -:10A68000A267BF66CFE879FDE99AFCEFD7F3336D97 -:10A69000349EBF88CB773FD83B681731A997A11F5D -:10A6A000FF83029EBF0FFC40F40DA384911F32A6CE -:10A6B00048A63C2DCE2FD912B77732034C205D83AC -:10A6C0007962F0FE13B027F07E824CD5D8EE076990 -:10A6D000DF15506FF52EF23609740E3EDCFD33287F -:10A6E0006761BE17F08D7F86B17E364B2A5BF8E737 -:10A6F000B13A5686798B15855ABCCDC182A41F35D7 -:10A700003F5DBF2F503C73DED7D4C261F8E9171705 -:10A71000EA79C2467DDCE56696F1B523855C1FD5F6 -:10A72000F7D6D6A15DBDD6C7C8AE5A8BBA13CB99A2 -:10A730000EBAD726D45DE9B2BAAF2253B519EEE707 -:10A74000F5CF4833DC7B9B1DCE3294731BF20DF5A5 -:10A75000F322230DDF0B969D6BF85ED434C1501E9F -:10A7600011BDC050BF04109C5C1EB5E93243FDD141 -:10A770001D5719CAE7ECF896A1FED8F862C3F7F3A3 -:10A780007E759DE1FBB8AEB586F2F9FB6F36D46FEE -:10A7900061D6F777766878057E2739D6ECAD6BA061 -:10A7A000DFD1901D8638FF755ABDEECC4965180F74 -:10A7B00069395E5146FE70FA0543FAC366B9984A94 -:10A7C0001E9BDF6F2EE4F2F383C7DE9EB412E91CFA -:10A7D000853CC8A50FBCAF6CC0396D2EE77909FA6E -:10A7E000EF6298EFE5EFDFA794549ACF822C07B37E -:10A7F0003A1F705DA162B9BFD02A845CB857940A31 -:10A800006F478689B7EDDA3CBE2ADE8E09C638105E -:10A81000EA93072DE07A42E32BD057BF453E047DF3 -:10A820005599461E06BFC7E16CF5890E07E8937F70 -:10A830002FCC1E9C1FFE41C3F3D7DCAD60FD6B78AF -:10A840007D5BA80CD725D5BED21385E67DA5AA656C -:10A8500028E716F8D284E4FB9AF76BF5F478764B88 -:10A86000FA67B4AFD4E208950D675F697F21E3F71B -:10A87000E0E2FA6627ADAB5D0DCA96FE9DD98E610A -:10A880004FE03D1831AF4479C366FF2EAAC96DDD94 -:10A890009F930ED692BFDFE21D49791F2DEA5AD24F -:10A8A000971D29FC5CD097BDB83ED37C371AFCB904 -:10A8B0008178804AE3415BB29B5A92FC7F6CA7DEB1 -:10A8C000CDEFD5FE1AFCE08F0ACFC2FF5718F783F1 -:10A8D0004F328EA793AA8DEC84936027A0FC6D93D2 -:10A8E00018ED7BC72A05C5CA2FEE58AFD987EB39BB -:10A8F000DECCFBDD663BE38AD0F584B736A0275774 -:10A9000025CE9FDBBF6D767EFFA6EC0F0751DFF6ED -:10A91000653BD86E80F660368FCFE978F9B2F228C1 -:10A92000A76890FF93533484FF738958DE85F7B688 -:10A930009E38C5E3220A1E450CE03DE47CFDD63E70 -:10A940003127B606F55489D484F9EB225332102FFF -:10A950006B0E8B2C2EA01C33E6E7DB59D35D188FD2 -:10A960006301FE3EC65CCD6827654C31EAB14CD52B -:10A97000A8C7FC33B24C7ACDA8C7721B8C7A2C2F97 -:10A9800062D46305CB2698F49A518F8D88D699F4BA -:10A990009A518F8DDA749549AF19F5D8393B8C7A75 -:10A9A0006C6CDCA8C7CEFBD55A935E33EAB1F3F7E3 -:10A9B000AF377CAF48B41BBE4F3C7CBBA15CD573AA -:10A9C000AFA1FEE4A3BB0DDFA7F6FEC6F01D10FD90 -:10A9D0001C9E67C07B6871112F7CF721E377A63A34 -:10A9E000301F7F059ECF8475BCA8EF61437FAC8389 -:10A9F0009F5B88C17FB85EEFB008DD030072EC504A -:10AA000001B45B1D17420986FAE9C1B771DF6679A7 -:10AA100050243F6E0D065B911EEEF7C5911EAEDD14 -:10AA2000613CFFB03C6E2CC7807E148C2B00FD2057 -:10AA30007DAD30FD6E04D883446F2B14A909ED4A17 -:10AA4000337DBDA3D3574C7D0ECF73E8F3D5E767B5 -:10AA5000D7CF9F6AF4A76AF4C7C44708EE1505224A -:10AA6000FDFE8E3E5F15FEE3DFDF77E03C3ED92F33 -:10AA7000303FC0710D8B1D2AB098CFEAFDDB1DC899 -:10AA80009FE67999E761B653DB8A8CFB489788DEAD -:10AA900010F1DD0B22E9239A02F2D903FCBCDEDAC5 -:10AAA00027443A17837C88FE82186B20BCAC01BC1B -:10AAB000E0BDE1BADD7A426B77E2A7229D6F3E13DB -:10AAC0003F2A1A3E9C41233FBA9534133D19F1EBBE -:10AAD0002933F2E78AD72E75A0FC3A04F816A6307F -:10AAE000E60B19F97585B892F6F9743C2BF01F8EB8 -:10AAF0002B81A98BF35E0DF34E2883F1BBEC91ED16 -:10AB00001B0A2CE8E64CF87DB0C8B8DFAEEFCFD515 -:10AB100002761C1679A53AFEBAB3D53FA27C4CE565 -:10AB20000F1F283A6B7FF840D1D7EB0F3F5334A467 -:10AB30003FDC370BFD29274B0FB55BC4FD242627CF -:10AB4000305E6B6FE271BF81F8DDD71EE7790BE1F4 -:10AB50009464AE27DD921EE7091D8DA07D92716E73 -:10AB600008F3A2861BE7F870B01EFB70283D06F6BE -:10AB7000C5313C4FA866E4D7DB9099A45019DDEFAE -:10AB80008C20F03CA4FF46F806E5EB966669F9C711 -:10AB9000CA90F9C75768FBBB1706D57F221CD0DFC8 -:10ABA00069ECAFFF3EB6CA6CEA27FD0CFDC4EAB8FB -:10ABB000BD16B3F93A5AB8BD46FB4C5F431CC35FA0 -:10ABC0008C712D2FC77F8B83C76DCF36CE565C3CE3 -:10ABD00028BE545C3C447CE91FAFE6F273AB21B065 -:10ABE0000E2A52D3B77E0E532F6FCE34FACB1B26CC -:10ABF00070B8CE2DE6EB1ED1CEE3D668653DEF12E0 -:10AC0000F316DD13A03C939F53D2CFB5EAFDD414C5 -:10AC1000FBA8FEA7C1BA1AC4C786127EFFCE864C17 -:10AC2000E33D3C278A6A6B705E53B4FE6B8A193F22 -:10AC30003731523BB7698A177CAED5FFBCA88E9ED0 -:10AC4000788E16FD1287285AE2735AB14DBBEF86F3 -:10AC5000D173BA7E7EEE4E7EBECE7CEF02F0C98B03 -:10AC6000F8FB506FDE66277F0FF4119D9F5B5AC083 -:10AC7000CF219AEF538894C98750BC7EC2CA2DEF6A -:10AC8000E51994E770EC26CABF7B662A9385BC332E -:10AC9000E73D7CBBB85F5F85BEE439BAC6E261E4DC -:10ACA0006B2DD1CED1F5A6713DD697E78AEFB6F0E0 -:10ACB000776FD5E8F236CDAFC5FD69DC27C7FBBDA0 -:10ACC000ADF6CB6F2DE6FBC3C33D577DBB231241D1 -:10ACD000BE359FAB4E759EBAD7D1DB968BF08E6595 -:10ACE00021B4DF7317C8DDB9502FAD5EA1F38F1B00 -:10ACF0004A58FA14FC5E610BE1B98ECCB9F2063BFE -:10AD000094334B599600E5DED81C1AFFB606268B05 -:10AD100000D77DC5FC3E8485B77C44E36557C3D42A -:10AD2000143A773E1DFDB35803A37B0BCDF3BC5BF8 -:10AD3000A35F571BBF2727A3D43A0FFFEE62DDBFE7 -:10AD40000EDF85F45B5BCAF6F1F3B3FC9C025E4B4D -:10AD50004FF99BA134DA17BC12D68DEF9FF7D0FACA -:10AD6000DD149CF6536CA7F39B43CB53309F27BF56 -:10AD7000AFF8ECCE93A72DB08637A1ADF735D9E16A -:10AD8000FB918ED2CA3AF8EF977E71FAB43849FB3C -:10AD9000694705DB4722A8FFDCA0FF047C2A329D1F -:10ADA000A3652E81CEC3BA9426A22BF794901F7F61 -:10ADB000178D2DB131BCC7659AD65E6D6002FE9EBF -:10ADC00004E502929C36FDBE841A6A6D86F697E011 -:10ADD000BE5908F3BE43CBB0BF7A6F9A8CF14D7762 -:10ADE00069532DAED7E30B791FB7A7382FA19FB3B7 -:10ADF0001FB87F6ACDB3867B051CCB9F35DC2BC08B -:10AE0000963FFB55EE1578AD78F9B3FF13F70AE8D6 -:10AE1000F20DD4901DEDFAA322BF47EFC347AFB6A2 -:10AE2000E33A6CA8655D88F7D8678067D7009EED28 -:10AE300075E1C777A25DB2363DC47F4F24F61D840D -:10AE4000F3350F93B1BD9E6F28B032D2D7731B0478 -:10AE5000B21F98D4B71ACBF31FF1C8E83F7CF8E8CB -:10AE60004B4531A0CF576F3DE9C3FCD4D7A53E1F5A -:10AE7000C2F5EE2DCFFBF0FEAE576F11290F85CE38 -:10AE80007D27E5890923387D2D1A113E85F4B5709B -:10AE9000DD3F2725DB672C9A4DFA7E791C204EB6C4 -:10AEA0007B7FE531FCAEE8AA2EBFA1ACEBF9554E95 -:10AEB000EB73F35347703E5C7E7FA7A340C1F12341 -:10AEC0006923A0FEBBDA39A077F7F9C88ED7E1591C -:10AED0007C7F8503EDE1D71F71B204C5057BECCC07 -:10AEE000CBF507E65D44F8D083E03CF4970207F227 -:10AEF000D95281F53989B9D921C4F7DF34FFCF3C64 -:10AF00008FA5AFCA0E5CDFA5B5AC0FCF9D2DBE518E -:10AF1000D8F003A8BF38E225BFDF3C4FB3BEB91657 -:10AF2000EFB311ACEE816B3AF467E86709F483F68E -:10AF3000E7D20EE3F713876F38B413C6DDB7DF41EE -:10AF4000F6E2B56788F78F1FA1E9A5496CF2E951D0 -:10AF5000A4FF32C629A9ED0E5D1FBDBB8E5192CA5A -:10AF60007FE1EFFBC2F3FD75323D4F152BB41E2B75 -:10AF7000F6771FA2DF16967A26A1BC9BF944A3E7B9 -:10AF80005B6C20AF685267CB819D5455CF574D50B5 -:10AF90007C6F8A76FFCBB5DAF98FAAA3E67CD5EE73 -:10AFA000C7FF8C761BCCFF6CEEED5930CC7B7B4E13 -:10AFB0001C9EE6413A993D42F37F26035EC4AF8E64 -:10AFC0009754ED56A5F8DD169D9F4E697A66C99E89 -:10AFD000D91BF261FC9647DF29C6F8718C71FAAE75 -:10AFE000FA29FFFD9F2A6F0ED19B0BE9330F9B9827 -:10AFF000EE7988B11759127D5FFB8887E82408F63F -:10B0000090730ABEE1F45A85F776227DBFC0DBBBA0 -:10B0100034FF36F2C8ADBCFE9F1DB233487C19B474 -:10B02000D13311B44DB1B867CB7CBF5887B1FC8127 -:10B03000BDB718E5CAB5263FF403C13A3FAD71C4A8 -:10B0400048C2C712459D8E79004B5978038FDFF2B5 -:10B050007B7BDE953A0EFD10F97D8FC06280A7558F -:10B060007F7CE0DF518E5DF7BB3BD3518EBD2775F2 -:10B07000E4E0782BF7B6A5A31E78578AA563FBF703 -:10B08000E25C9E0DD29723044D0EABE902C8E4D5D5 -:10B09000446AF0FF257D1B6E8671FE1BF08C7CBF21 -:10B0A0007ADFA7543EA4BAFA5810FBED9D8E702C9F -:10B0B0005FE46D6A0EA17F69E4CFEB7E79678E4213 -:10B0C000791EB1020D7F05D86EF51E3BE5F9A21F72 -:10B0D0008FC3AC617D343F73FB355D6F3A505ECBFF -:10B0E00036D65778E1E0EF60213990DFD6ECDBF21D -:10B0F00091988ECFF75EC1DF835A63B24F9769F2A2 -:10B10000DB4CFF5D26BA07FC507C210670F19F6383 -:10B11000E272BCE5D7778F7F03E07B7FCF53E9F8FE -:10B120007B133AFDEBF73C9FE86A5CE818E21EA14E -:10B130000F343EE9D70F9A7E52F60360B9507C84F3 -:10B140003F57DA13E917C27C5776DA4348F32B1FCF -:10B1500010552FDA552F3BC91E59F9C049A2DB956E -:10B1600082DA27909E63E928C7F5F55AF1C0DFA679 -:10B17000A39C5E9127B299C08AD7FDFE135E1FE89B -:10B18000DC0DF5573CF8C6F41F6219E489CB62BDAB -:10B19000A675753B7ABD16EBD5F5C6748CCFB7FC9A -:10B1A000FA1FB41EEFFD4560B92583DB2FEBFC1BB6 -:10B1B000C5C1DE8785F167727CA1BE59D3252E7289 -:10B1C0006458AD5F62D6C395F49DF2C2CFB48E1DB4 -:10B1D0002318D78F7F7CE0DF1E063896BDE20CCDAA -:10B1E000C471FFED86740674F08ED4C4E9FE676DF9 -:10B1F00039A8BF97D96339323DF9FB65BBBE47F427 -:10B2000078ED5FBF97A3ED37E4D9481EC4F2709E76 -:10B210004B7F3A8FE6790D8B103D2EFB19BF67F1FE -:10B2200013F0B3ADFC84A90AE71B27BB7EFCCD015C -:10B23000949B78670BC0E160FCBEAEE778FEBB93E1 -:10B240005D95916CE77A146ECFC558FC35B43BD749 -:10B25000805A46B9F6FF003503B31E008000000097 -:10B260001F8B080000000000000BE5BD0B7C54C5DF -:10B27000F5383E77EFBE425E4B5E8457B8791224B4 -:10B28000C485249040D485400C0AB8404494884B2F -:10B29000C010202101AD60A5CD860002C53628551D -:10B2A00014B40B8245451B31086AC08D2886EA1705 -:10B2B000438D165BA18B2008045810EAFA2DCAEFC3 -:10B2C0009C33F766EFDD243C5ABF9F4FFF9F7FFA08 -:10B2D000A9C3B93377EECC79CF9999B3E2814BF911 -:10B2E000BF8C62ECE1787DA5C9C25805D33B3D66B1 -:10B2F000867FC215814A493F189FC35F0263790761 -:10B300004675F3A4316662178CF767327611EA9FAF -:10B31000B36ADE6357E2193BB1D1D445B819CA18F4 -:10B32000565A07EDAFE0DF6DFEB25482CEA3A9F905 -:10B330005F18F43F97BE04FD6C3991BF0EFA65B1FA -:10B34000220B8FE5F073303E4B71486578367CAF49 -:10B35000E5A8B107D43BA3742C19C7DBFC0DC1CC05 -:10B360001A2D617BA5FF8A9D26E656C603FFAFD83E -:10B37000F48D91613F3AE6ED35AC7D3D6395E9880A -:10B38000870A162EAD84F284D19BFF2E7E07BEBBAA -:10B3900019BE53B206DAA7AAFAAB3FF937968EED7B -:10B3A0008DFEE7F1F8DFC58C65412116853B42181B -:10B3B0009B8938CC693FFF855F553FFE81AABF0C52 -:10B3C0002934EA7830FC63081B7245F4BFCFD603FA -:10B3D00092BAB77FFFFB2AE7E31F18F06D27E1B1B0 -:10B3E000CCE07A09F154F6A5C9EA043C96BD76C9C9 -:10B3F000A88B422A326F7257C64E6FDDF3C57D307F -:10B400009FD37586A831F4555B9810E3C77BE9B6E6 -:10B410006FF2D7417B03E03D08E839B7FE7BA30E0E -:10B42000DAC7E631AF09C67F3ACACED800C49BE17D -:10B430006B8F0A6F79F0DC1342E3E8A98BC5D2DD8C -:10B44000934139378A59DDF0FEDC16D12A21BE98A6 -:10B45000779925A4FDFB15754703E8A2AD67CC6B72 -:10B46000B4E377EB7F735E0C53E35DFFB5478577FD -:10B4700005CF81789D8A78EDEFC7EB2596160E9F54 -:10B4800061A75E99D3C791D61EBF0A5ECF563164BD -:10B4900072FFF33E12E159DA091FEA06750D72C90F -:10B4A000D8174C85C7D9AF9E21FEFD67779189C01B -:10B4B000377337FDB00CF90AD0EA3501FFCE759D20 -:10B4C0002778A9CDEC650437160AE91DCD5B8BCF33 -:10B4D000C0FA78446AB49FFE86C5CC190AFD7A7713 -:10B4E00089AE8D30B47392372C02E6B734883D6054 -:10B4F00087F29C4586BB2A307B601A8CF39C33DD37 -:10B50000E2C4F782D8E43AA0CF39BB37AC6B887F6E -:10B51000DE471AC43009DA7B5CACA02EA43D1F3292 -:10B520005643DFF7B0CEEAAB491E4689975FF7C0B6 -:10B53000F72E38F5CC04DFF3547FFFBA07CA637ADD -:10B54000B305F134A3FA9E30A683EF3724DE351914 -:10B55000DA3DB80FF047D3B319BB037EA7F3A9B305 -:10B560006F99F3E95C989F189AB9F75D78BF04105A -:10B570002B02BFCE58A5C5CF6C660F77C7A3DC1AC8 -:10B58000FC7C42FF7519DDF0DE4C4748E54AF86E59 -:10B59000E97A6DFDEC86D3C45FB303F8CB81FCD5AB -:10B5A000BD3D7FBDA2C8ED403610F96B9418A24393 -:10B5B0007E3ED724BA4CF0CE852506B60CE00B5B58 -:10B5C0000517837E2E3440238477729839A3896FC0 -:10B5D000153E57F0D68AFCD7B73D3EDBEAB71F1AB7 -:10B5E000FC1834297BEBEFE9EBA06C7DEBCB947777 -:10B5F00011DEF1D7B8BFB3F6EDF376FF3095C6B5DF -:10B60000DBC4705CE7767F14F718C2EF98ACC8B75C -:10B61000E7169B6C0CF5DDEE505732D6F7067E0030 -:10B62000BAD7ECFA3E1DF53D634B888E9F4B462AF8 -:10B630002F34FCEBB080F3683049388F8ADD80040A -:10B6400078BFE29D2017C3F7777D3FD811F2F3CD85 -:10B6500067AE9139883F43D9E46DC8BF5D990DE766 -:10B6600053F16ECE8BD5F0FDF2FA46E374A8CF7B92 -:10B67000EFC774D447E7B6351A515F9D35785E60E1 -:10B6800056E4DFFB6B0D80E7B3A1D0590FC61EDD7A -:10B69000F0BCDD19D2115E381ECE011E705E80979F -:10B6A00052575AE7F8F8FEBF161FE7A7E2F7CB1A82 -:10B6B0008630315E8D17C1C69F87BACC02CD9F3FC1 -:10B6C000DFFD7D3A0BB9F67CA3E38D24EFFF7F9974 -:10B6D0006F46FC7F2B7D39BFBF2B4934BE40BE6F08 -:10B6E000CFD73B1E21F8F5502B8DF73AE57DE27F51 -:10B6F000EDFCFF6FE83DEFBF76BED7A2F73E99DEC7 -:10B70000A11613EAAD5D3FC6B11B9877EDFF47E781 -:10B71000DDE6FFE8ACE64C18DFDF98EBEEE10279FE -:10B72000251DFA23BBE2B5EB8E71B25F51C3BE1E7D -:10B73000390DBEEB047F02FDFD9A90AFF52D003769 -:10B74000839F80FE0543E704F0D05C38D0B512ED4E -:10B75000B6BE925900367C319DE0C9C53FE833A1A1 -:10B76000FDDDE0E761FBFDD59E19D550BFBFAB4EB7 -:10B77000AA01F82EDBC4E47A802D3D440BAE636A47 -:10B780006C19664935BEBBB2B5EB91FB02D615F715 -:10B790004CD6D64F621BA3F5D0DFA4520373C194DD -:10B7A000EE0E68BF2EDE42F8BA87552EB584DC381F -:10B7B0009E4ECB78AA61839A24C48B4DB46E66EDFD -:10B7C000F1C6106F8897D80CB6D28A5FF1E85B009B -:10B7D00036C9FE15FC913CDE1D657E09F16462F3FD -:10B7E000D923D0DF25495F89ED4D0CD68D7CDCB4A3 -:10B7F000DE0CC41B93D79F26990477D91E628867F5 -:10B800007CDE2756F33ECD3B10CF378ED7C5C94FD0 -:10B81000235E0B43AD2EE40BDB8BD17AF85E0DE09B -:10B820005910FCF854F0148877F43969FD27E35B6C -:10B8300029D398772AFA9D612CCCBA12FA0F33F7E4 -:10B84000627A3E0FAFA93B161686EB357104AB5BEF -:10B8500009EB3596AD6F6D9B5702D5BB1F83F76A19 -:10B86000E6C1FB88D75E4CB213FF1759707D2330B9 -:10B8700007BB12ECF73F3FCD06FF339E4AE2DB4F9A -:10B8800037717FF352EE9BCB0682283198B3733029 -:10B89000FAB9F29FD35384EF894C67C5F52FB3D91A -:10B8A00024CB60EC97D1BA263C5BA759FF76B575DF -:10B8B000D1E02DB220420347DB7B68DA779B9CA066 -:10B8C000A9EFEEB84953DFB3749006EE5D3954D357 -:10B8D000BECFC2111A38DE7987A67DE2F2091A3886 -:10B8E000B9F63E4DFBBE6B8B35F5FD5CB335F5FD12 -:10B8F000B7CCD7C003EA7EA9697FF3CEC59AFA8197 -:10B90000EE959AFA8CA627357056F3739AF6430E85 -:10B910006ED4D4E7785ED1D40FFB769B06BEC5FB10 -:10B920008EA6FD6DBEF735F070F6B1A67D9EF9339B -:10B930000D3CCAF2774DFBDB638F06C43B2CCE87F0 -:10B9400032518D013F819C8D964E6BDA83C75C84AA -:10B950007C6390F9E1CED4EF34F563ADFFD2F467A8 -:10B960006495400464AB5A2ABBB03A2A43583395D5 -:10B97000BF1EE0B027A05CBCE05C864CB53FE7FB97 -:10B9800038B4239FE63EE444BEBB14CB2CE24018FF -:10B990000FF3EA91AF75C1977B395471A3309FC8FB -:10B9A000DC19C0873E814A8B2F98B923810F7D41D6 -:10B9B0005446F822E979A4AF2B9551BE9EF43CDAA7 -:10B9C000D79DCA185F2295DD7CF154C6FAFA53D987 -:10B9D000DDD78FCA1EBE0C7AAFA76F2095BD7CC382 -:10B9E000E8796F5F0E9571BE3C7ADEC7379C4AC915 -:10B9F000772795F1BED15426F82652BB44DF782A2A -:10BA0000937C53E879B2EF5E2A537CD3A9ECEB9B8D -:10BA10004665AA6F0E95FD7CB3A8BCC9F710BDD7CB -:10BA2000DF378FCA34DF63F47C80EF512AD37D3552 -:10BA300054DEECABA6D2EAFB0DB51BE85B41E5207A -:10BA4000DF53F43CC3B79ACA4CDF3A7A9EE57B9643 -:10BA5000CAC1BE17A91CE2DB4065B6EF552A737C4C -:10BA60002F5339D4F726BD37CCF70695B9BE77E901 -:10BA7000F92DBEB7A9BCD5B7879EDFE66BA4D2E689 -:10BA8000FB989E0FF7EDA37284EF337A9EE73B405D -:10BA9000E548DFDFE9F928DF9754E6FB8E5279BBF2 -:10BAA000EF089505BED3548EF69DA4F20EDF77F411 -:10BAB000DE9DBEF3548EF1FD8B9E8FF5FD40655BE0 -:10BAC0003C21D710A017DBF49FEE0AC67942223A38 -:10BAD0008CB7B5BD2FEBE3D5C12F308C7B8CAB146D -:10BAE000689DFE4CF0D90F484FE69824849762D3A6 -:10BAF000EEFC3B9618C6EEC77F488C35E69868FD8D -:10BB0000BEFF57FCBD65C38F7EF510DAC779268668 -:10BB1000F63150FF2ADFFD347B4F34FA61CB0679D2 -:10BB2000CA30FEF244BCA708CB860481ECC59B72E8 -:10BB3000F94E828ECA3503B8FD2E9A971C4E71AA13 -:10BB4000A8EB9BD7FFA2DD8FF6B77F2189F7C34211 -:10BB5000BC71642FAEB39FEB6DB7D4FCEB3F605C60 -:10BB6000C756A36741B702ACE7F6DEF955A86B33B9 -:10BB70004CC939A2F28F18E7712E36596AA210CF3C -:10BB8000BFFE13B65FC898DD04E51F121C9F254059 -:10BB90003FDF07C5B9C038C25FE59009A13F6BFF21 -:10BBA000FFF83FEEFF34EAB5CEFAFF87CC476312C9 -:10BBB000EDE7701C4C6F4B473A8C58DC5D8C82F77C -:10BBC000A7AD122CC847D3970CCC47FE18C46C14F1 -:10BBD00027BD3F923D60EFC02FEB96A893FD0BC9A8 -:10BBE000780F8CE70CB81CE84F144B8CF8B2B841B6 -:10BBF0007039290E6D0B1B0BF6BB54E6DBE2E5D565 -:10BC0000C605D0AEBC3B8F9731178F9799E17F283F -:10BC100047736A37ECA570A37899E26397D0EF0574 -:10BC2000D699B3A57D3C7601C699771A2D6837CA97 -:10BC3000EB02E2B90171B3C0789925518EC75A99C8 -:10BC400095C7B9434AFE8ADF63619218756DBC28B7 -:10BC5000F1598949DD108FA3C4B4705CC75C684A90 -:10BC60000E67584A52376CE7005A344329E81D439F -:10BC7000F039E0D38974F55607BB36C2B88E803DE3 -:10BC8000913270408E21468C47FEAD375B2910D52E -:10BC9000C80FABD824925FEF59FCAF6518C79E154B -:10BCA000AFA775C0348CB9E3F8DEEEEA720AD42F80 -:10BCB000E1DDFB9A407157279B1F8B71DDC07D141E -:10BCC000FBD2E871D948A7E55D079990564EDB177E -:10BCD00049312AFA2CA921BC16C74672FAEC3490D5 -:10BCE0005F0BF4A946FACC72198EA9F17C895D36F6 -:10BCF000E27E4CF1F2F344AFD97E7A69DA95D73619 -:10BD0000125D814E9AE71595279438FAB1ABD12B85 -:10BD10003F805E183FBF072B1745927E285AEC4E96 -:10BD2000AE54F169E0BE44D28CA1E1769087821EC8 -:10BD30009C1E4C6F8D417A7EB72A8BE81548A782EE -:10BD40009FA6133DD8DF42D96618CFFD89EC810943 -:10BD5000F0FC0139FE7A7FCDE8028C974F4DE4EB81 -:10BD6000934F61FD6983F5E7812A33B3816AFEACA5 -:10BD7000CA42F0E755B104FFB54AA2F2CBAA542A51 -:10BD80008F1959699D4ABE80018C38BE192857D138 -:10BD9000582AEBC3876331EE5EF0D367593A52A954 -:10BDA0006F8E1FD51BD7178004157E261706932F7D -:10BDB000ADC01E83253F16F5C70AC1BA19E96A1F2F -:10BDC000A669CF5233FC30DA2F3DE727E08B8DC8D0 -:10BDD0007FF78E89D4B49FB4BCA7065E9428D1F8AF -:10BDE000C617246A9EDF57D45F034FF3C17A1E3E05 -:10BDF000952415E89CD0FFC54F0CC4CF172B877432 -:10BE00005BC061E2BB40FC1F333A298EE0DC68B2C4 -:10BE1000A2FEFB3688F3F7B79F8BAE1A5AF73A2982 -:10BE2000EE72C96C91709DF2C874671CD63F120CFB -:10BE30002EF940C497C8307EC05E3191FE9CBE563C -:10BE4000604E94112FA3F5F2C32F9B689E33D68AC0 -:10BE5000CC91417C1287ED1F8E96A8BFFB13A53AAB -:10BE6000E467EF66937523D44EF7C8EF0B83681F22 -:10BE7000A47CFE5F0FEB511E529AD371AD5514EFA7 -:10BE80008E463DD8BAC940FB5EE5E286921020D1CD -:10BE90009C27DE0CCB9148FC08BFA70E446FC0F96D -:10BEA000FBE7EBA2B8C8377DEC1B13419F9E2A71BC -:10BEB000A5D33A79118FC7B7C70B233DE5D4854980 -:10BEC0009B71BED31D432C696A7BC8F7FDA61BACD2 -:10BED00031D634E4FECCEEA8078EAD321460DC051A -:10BEE000F4FE38C4D3B1DA48DD4A5A546D23FE2A31 -:10BEF000D64B46F5778B5789366A0FFA7D3CDAEBDD -:10BF0000D5A2830D41B896FA772E171CB8EF94C4CA -:10BF1000B2BB21DF3E346F48379CC7D44EF619CFF1 -:10BF200082CC3854FB58B3778976177E2FD3A32F52 -:10BF30001CA01E3F8F03253996F79A8F747A23C869 -:10BF4000BA5242BD9A188EEBD4932D6037E01BB3E2 -:10BF50006A1AD32560BDB28776101D4AC7D5A5B829 -:10BF6000E1F901B3E313C4E3B7DDEB9E1E8671A2D2 -:10BF70008617E39C680717F2FDB5D9AFCCEAA3F6A4 -:10BF8000E7DBFB132C56978D853B4600BC38249687 -:10BF90008FF89DC2EAE4F8858BC627A1D2057C58AC -:10BFA000CAF8FEDB749D75EA679988FE500BD2458E -:10BFB000E9EFA881C7B9FE21CBB362877B24713F2B -:10BFC0006BBA8ECB1DDB2D109F02C1BE4852D9CB60 -:10BFD0000AB68AEC656C4F91E1BEDDD9C408592FD1 -:10BFE00070FB3707ED1FEE0B5B04928FB22D269787 -:10BFF0000BF82B3589CBE76CE36B4F0FC2E6F1955D -:10C0000046FCCEAC7A813D074D4F195C25CDB82F4B -:10C0100065D9B02482DE33585DC8A7B27E3783422B -:10C0200040BD3013FF09F5E56B04979BF8C54E76CC -:10C030006806C64D70FD8F7A5EA547DAE9F700BD48 -:10C04000FE200BD8D7AFD5DA177B70A819C7397B7C -:10C050000DF76BFDE311D915C05589C3B5771C8D5C -:10C0600057A0B848E0F767E2F870BC303EB7F5C6B5 -:10C07000C75362E5725A562BB85C1D8C4FC16B7862 -:10C080002E93D03ECFD924B8901F4745CD23FCCE68 -:10C0900006FC46225E9DF6B07B002E014672517C66 -:10C0A00085E3BF623DC73FD0F92F6ABBFB4D94D7F4 -:10C0B0008878FD06ECA713F7032BBF27BAEF05FA24 -:10C0C000A2FCCE7AC365C48DC8D3AC362C04F97EED -:10C0D000ED81BDB82CF866CD9B31B87E2D8A7027D6 -:10C0E000EB406F45B2E8270B6EF1F35FA0BD6E67C2 -:10C0F0009703F0E36476B243EDF0645ED58CFBDE2B -:10C10000EDE827C7C51EC47F017E1EDC24DA82D27B -:10C1100035EDE4F3084EC25BA9D34B7E4229CCB384 -:10C12000C6824F9DF9889707AD8CF4EE8D8E3770DF -:10C130009C4C2C22FEC4B81EFA21FFEE7803FD8F22 -:10C14000494957F73F02F548A0FFF195C1A65B8C1E -:10C150007EDF01BE2F7E51EFEE8DF27B312AC10AC8 -:10C160002DFC7A347A5037D4F38A1E2D91ED96D275 -:10C17000EF8368AF003EBEF6CD30A4BB42FF9968A6 -:10C1800027D2FC76E291E9D03F7CEF911D41D4FFAC -:10C1900099B160A7A0CFA2E73F0A632AFDF7781FF5 -:10C1A000C7FC24D4278A5D1337C45980BF147D7916 -:10C1B000AD7557A7F30A099857A8765EC538AF0C36 -:10C1C0007F7FD3E5797DBD9CCFE7E82A3EBF19ED9F -:10C1D000E6C5EDFE232F9AAC4EF20BDCD12887DFAB -:10C1E000BE21B21AA22FF71B2E99819F0662FC6610 -:10C1F00015D9F593D14CC2B84EA7F67BB589FC8210 -:10C2000059DBF97EEB29617837DAF8FFC01DF62893 -:10C21000CAF53691A11DF28FA7CD6E3F9BA4B6DB68 -:10C22000D789378CB3A23D9B0BA843BE9FDBD08D33 -:10C23000E1399755C3599D48FBF01ED263C04214A3 -:10C240009F063F5C136F3031ABD98C74EA24FEFA41 -:10C25000CFE4F353E7133EBC29887FE5FB155DDC93 -:10C26000866EE8D7BC21905F53FEF0F0B0E10CBFC2 -:10C27000C3E3663B92B89D7A07F51CCC4BB0555290 -:10C280005C0C7C1ACBEF705CEB797C98BDCFEA102C -:10C29000BF0853FC58C7E7214816563488C7E5CD78 -:10C2A00068D7427464D702F17042FE4EB9A823FFEA -:10C2B000B7CCC8FDE073023FFFF1916C1F3F4AE22B -:10C2C000EBCC4F92783CE11CFA81D0EFB95B4CAEDD -:10C2D0006A01DD563DAD93F5B92617FA337A7388B6 -:10C2E0005B4C47F4EACFB6C933E06B2A6B36203D8E -:10C2F000C765CFDB82F339DC8359C4AE546DC77D8B -:10C300008429A41918DB6FF8EA438C473AA1AD08D9 -:10C310006B8529D9277A63FBF508C3FC0F07D57D08 -:10C32000887196C3F17A86FB02CE5D26B2FF861134 -:10C330009EDE14A7ECC258CD408CC7EC598A7CB461 -:10C34000373632D502ED1FD077B18A5CFF8C3C8F37 -:10C35000E32D15F8FECD124F16D2E766B6C472DC97 -:10C360004C5B0BF55722AFC63F7A765CE10318535E -:10C37000D908F8C750C6192B9BF0A98101AF045FFB -:10C38000DEF4C88435B9B869220D403A972578F5AE -:10C39000B89FE215987723E0E1EE6CAFDE86F4B249 -:10C3A000B1BABB807FDDFB9880DF4111C0EFDEE3D7 -:10C3B0004E18857860A9120B87FABBF412C1BD0A2A -:10C3C000588428EF1B601CEBE03081E8A0334B065B -:10C3D0009CB7BD401884FBA2658BAF6F9C61C9D52B -:10C3E00034CE329D8EAF671FE5EBD929CE23A3C88B -:10C3F0004FCA6502F26145449D81D6D1202F38FE97 -:10C4000081D08D1A7F53F41E3EBE52185F0ECA456E -:10C4100012F1F17D9502F99315C68EE31A3D9295BE -:10C42000759745C2F673E05FC8D7731A7624E3F7B1 -:10C4300056099C0FE6287CB6552B97B9C9ECAA7C07 -:10C440009D93CCF93A2799F37572DBF7EAC8EECEE3 -:10C4500069F8E820AE2B3BEBBFDCC4DC84975D269B -:10C460008A1F083A6F12D1051109749882FE24B808 -:10C4700088439223B89F2EF36709FA1F8958F2B8B0 -:10C48000880E9427DAC3D2DA178D88B4C0F347E058 -:10C49000F8D039A0D99B029FABE22AA246EF50DC2C -:10C4A00053307A67E078845B83ACA88FA718EB6879 -:10C4B0005D1ED8CE50CBFD2CC372EE67D1BE1AC024 -:10C4C000A655DCCF9CD2CB3B80919EB3E40BF1AC64 -:10C4D000CD2F2EE19F86E7651ABFD88471048C7B2F -:10C4E000ADE5FEA05EF65F8B5769FD85294B54FED6 -:10C4F0002275EB2DC7F11A160553DCC584FE84CADC -:10C500000FF8876EBC13F5B033414FE72F0D2CD0D9 -:10C510009FB0331ECFE4CFF5B29F383AD9A0D97F70 -:10C52000738E60A9888722D44389A86AECCB319E98 -:10C53000778185D662DC6C94B888E27F45D5FC5C57 -:10C540005A60FCEF42E587CF637BACC7E70BBAFCD0 -:10C550001487FB9BB02CB50BB782BFD1E5F0250744 -:10C56000CA07282AC3508C03EEFF06614117CE8408 -:10C570006CFCBEFB79ECDF69345B506F3D131C46ED -:10C58000FD2C5C28507C788985CBDBA1AF4237A29B -:10C590009E52E2BDCB8667ACC5734B359B1B27987B -:10C5A0007BA37A60746E8939F7FEC506F329BC0C4B -:10C5B0007243F047136CE1C0E71F7AA79A014FCF8F -:10C5C00026374DD0839C9CFBBDF705845F4D3EC054 -:10C5D000E127BC7141086FFE9CC3D54A7F9F4FC0C5 -:10C5E000FECE3DCBE1E550EF84EF17A17EC3790F7E -:10C5F0001568DDFF8AEC7F2BF19E22DDFBBC1CC1A0 -:10C60000DC683FAFD5AE3ED9FE0AFA3B62E8B150D6 -:10C61000F42FDEEE6B7B05EDF78E44FB53C948AF7C -:10C6200016574C34C6B174AC19E90276CCD6D1BEDB -:10C63000F42B493C4EF3568A9DDE57F005FDACFFC6 -:10C6400077FA1999C2C7A5EA67F3BFD34F78DF76A7 -:10C65000E3793D39FAC6FB9917D08FE2B781032CF5 -:10C66000A19EF2A6DAF6E1F8E6FCDA36A21EF5CFD4 -:10C670007E91F8F4BBCA1D2968F7BFDB6A8A44FBC8 -:10C6800037E7F5B7E34A308E20FB45A71BBF344A96 -:10C69000F0FE5C9FC86CA0A72B7C029573EB1B8DF2 -:10C6A000F96978AEB6D198A71A57993C4EE074FD57 -:10C6B00004951FB33F5927EBCDD554CE79FDA41E69 -:10C6C000E9394757771CCF1FB3A13CEE1538BF1D82 -:10C6D000B2DE3D8CE70D3A8803B4C8FAB9777FDB48 -:10C6E0006788B7B7509F030CE6CAD111BE7AA5F090 -:10C6F000711475E17A3EABC55AF219ADFBD27522C1 -:10C7000094830F561A8BE1F9C1C41187105FEDE3D2 -:10C71000905E1E876CE071C8A288E687C198B16EF2 -:10C720002F5D7CD20CEBB83B9F91E503450FF44B9A -:10C7300081499197E0892373799C0BE1FF4D363C49 -:10C7400085E7089BBA34FFE233B40F2B42D94690F9 -:10C75000B3FB8784C66D83714C77860B603BD970C1 -:10C760005368CA3468D79A30BC5B0AE92746FE6131 -:10C770006B82FD02CED7131FAC036784398C3C9EBD -:10C78000E5F8B348F12C477AB0C3D501BEBC323EC0 -:10C79000BBA5F0FD9D261D8C73108E839FEF85BF7A -:10C7A000B86D186F5ADC4740BE53BE3F2671788C77 -:10C7B000FAFB6312ED624AB4BA7D38C3F6D73B0E7A -:10C7C00096C2C71193C2E965CF05FE52E9FD092360 -:10C7D000833570E198486653AFEF0A7B6AE0C9453C -:10C7E000899AF6F7CDE8AFA91F6B6ACEACBC017F82 -:10C7F0005F0C4B0DA7F57F165F871C6AB8F4C51454 -:10C80000F46337895601E6356BD7E62F8651EF1270 -:10C81000C5B94E3589648FC0BD35AAF74FCEB06615 -:10C820003A77ACEFBA84ECDF9C587EBE7B964BBB6C -:10C83000FFA1C4E53BDA37417B5686E7623ADA3737 -:10C84000F1C7E3AFBA7F929D22AF8707B1417C3D2C -:10C85000DCBA1766CAF2763612BD6AF6895664D516 -:10C860009ADE0213609CB7D79B5C4130EE336F1F9A -:10C87000314AAAFD930A5F35062DE0BD23463C4FA1 -:10C8800075305922FACD6D386F64C017B737CC2395 -:10C89000B96E6E744445A3FD027F757B26F2575D29 -:10C8A00026DABF269DC58EFB6173968FA63873B8B6 -:10C8B0006F0A9565B5A3A9DF72DF4482E7FA8209A2 -:10C8C000FE546CAE3F80FD3C136E417B5EAE776ED6 -:10C8D00045BA944BC119B85F35B7FEC0C55FA21DFC -:10C8E000B5F07B1D63C5BF6462FDD83E165D4D5734 -:10C8F0001C6F10F5D33CE2EF9968970A705D00CF8A -:10C90000CBB6E53850EE87D7845A50EE453C4FD62B -:10C91000019FCE48E1FE9EC1C3C73BCA379EFA5372 -:10C92000EA67A72450BD021BA237E9517F28F330E4 -:10C9300080C1C7F20E5F7F2A2BEAC7EBF15CFC9F38 -:10C94000535F8C423C41FB102C93460E233DF35D1C -:10C95000E59070D681DE524A93AC87A7A01E86FE72 -:10C96000EE4DB555A11C8E5BE4D19B518F86982D61 -:10C97000B8FF312E7BA054A29A8FF8FEBDB892006A -:10C980005FC56B40BB3D054AB5DE7EA013FBB234EC -:10C9900045D1DBD54467C50EB12D4F325C874DE5DF -:10C9A00067B5DAE46ABE2CD7CAFBCD02F7079CDB79 -:10C9B000795C7F7EAA632DEA91E6E16CF236D2A71C -:10C9C000CD71E3437FBEF187E99B89CE611649872C -:10C9D000FB0A4AFDF36DF3E0F27DAD79AC94DB7FA9 -:10C9E0002AB285C8179FDE765BB30DFA6D7C2C23C7 -:10C9F0004354D9A9D753F8F94766F15E267DB13B78 -:10CA000058423D3016F71E32FD7E3F9E87C4B84621 -:10CA1000C56ED3463C0F561106EB7CF8FEF8FE8E31 -:10CA2000D7917E8DEFE55CC47B34365C98819CDBCE -:10CA30001A865CC473F63633681B2BFA41B63F91F5 -:10CA4000BEED64BCD7D2674923E744A13FF11D0C7A -:10CA500009ED2DD8FDCC160EDB115F8EE55CFE1CBA -:10CA6000B21C4E93F9B75896C3697A2E870FAC095A -:10CA7000B760BCB378913000CFCB3129D48A2AC0BB -:10CA8000807C9981FCC9F9B2CCD75596E778B91F5B -:10CA9000CEFF81F239D71749ED1439FD53AAE310BF -:10CAA000B72BCD990B615C77805CA3DE732CEE9E77 -:10CAB0008972E2E713A305F909F824B644C50735DE -:10CAC0008D3FE8914F0CB902F18909CA3C151FD975 -:10CAD000DBFC134B7E0CFA554BE2752B99BFFEEB3A -:10CAE00014659FFCFAF8FD53B97D7108F81114FF25 -:10CAF0000963185FBB1025519C74FE0A1824A060BE -:10CB0000BEC19D8C7198F9F382280E56D252B92C71 -:10CB1000546A4FAF7B7DE9B4BF3CD19744E5C14433 -:10CB20008717E5659A6F928CC7F4EBDA9FCBB2F169 -:10CB3000B89BC165B26E88C7B89B43A4FDB8DECC74 -:10CB4000F214D929653F8EC7DD309E87F1BDC0FD47 -:10CB5000358CC3E17ADA14A5D3EC13B68BC70DD7A5 -:10CB6000EEA79535FE65B00EEA4FC5DB282EF74DD2 -:10CB70001F47505F98C7EC09AED70DEA7D36198F75 -:10CB8000757A7732DAD1BA4A8E9FBA556201ED379B -:10CB900031163C5E755EF75A7C3CDB9748F851ECE9 -:10CBA0008BA2B77754D1A1CF36FD7D2DBB532EF389 -:10CBB0007B39F2BBB5BD9D51F835909F15FD6C8852 -:10CBC0006E213D7407BC82FE83A2AF0BF286E5A204 -:10CBD0009D1FF67262FD3B30FFD854470EE2E5B66A -:10CBE000577B67AE03F80EBD4B6F09B91E7DF88306 -:10CBF00081F4E1A2F18CF421946A7D68E8C40FBF4E -:10CC0000B5EF8DF1779ADC1EFC58EE1F82BE56F709 -:10CC1000373F75C4F8BED074525F6E277FAE717710 -:10CC2000A6C727F5BD313D9E278FFF5A7A7C565FF8 -:10CC3000AEC703F5366863D2DBE776F5A338D96172 -:10CC4000067A1EED5943B0B4395E75CEBD4BB84B74 -:10CC5000ADD77BF79F3E0BE97A1D7A7D36B6FB7721 -:10CC6000F57AFEF837C8AF823FFB5DB7C2FAE3370B -:10CC7000B0BE43F85358DFC5B79787403908E47B07 -:10CC8000588FD41F80F1353DDD87E20E2007C4F7B1 -:10CC9000E5C0F728078ABCCCAD1F188EFB06EC1345 -:10CCA00091A1FE0F948382BC57F518A7423D8EF8E0 -:10CCB000DA03328F7A26D04EFCD8D7F12CF28F22AD -:10CCC0000F8A1C5C9B8FDE36E0BAD450769EEB79DF -:10CCD00028D57ABE337FE6851BE4FF55D7C93F6F61 -:10CCE000FCFCFCF3C675F2CFB6FF847F9246BE4BC8 -:10CCF000FC83FA13D76F777E6C0D5FC0F987CE2562 -:10CD0000023F6462DCB969706F2BC669EEBCC2FD7C -:10CD10007AD0E9E4D707FAD55364FDF7801C2738A9 -:10CD2000986AFFBC2F9757F2DB8727060F447B7565 -:10CD3000BDFEDE94A84A6683E70F40A9D61326A459 -:10CD40005B07FEFADF6E90BE4DD749DFD37DFF63F0 -:10CD50003FEF52DFEBF0F3926CE68988CFEFDC7A9D -:10CD60008678BAD67AC0B096E3B9CD5F77EB15BBBB -:10CD700019897613F8E39FFF097F8CCDABBB68065A -:10CD8000BA466D3116EAA1FD243C6B41F10CD31A71 -:10CD90005B12EA1BA6EC0B50BCE35351869DE69652 -:10CDA00091308E3B9F62FE7D03A81F951BDE161FF0 -:10CDB0001198BF7DE41643CB2A8A3FF0F32ACCE1D9 -:10CDC000D1F37D3219CE043854056707C0EB79FBE7 -:10CDD00030BD87F1731FF27359FF8CB3F07D01FFF3 -:10CDE0007E9E37BF2BFA7FF58205F717EECB3D67A6 -:10CDF000C478CED83CCFDE9ED02E654B7861483FBC -:10CE0000785E2FD07807A7765BE34CA2235B363C95 -:10CE10006F5896CDF74D4C758DF9B60EF87070AA17 -:10CE2000D64EE19F3E86E263F467AA13983193F7EA -:10CE300093107F7DEF23FDE8FD047ADF6D8ABAFE53 -:10CE4000F7EFC9653657077C345269877161A57F52 -:10CE5000A0C9C43AC1D651DC664C2A9797669DAEEC -:10CE60009C019E0A53FBAFC1B8D728C6F96252EAAB -:10CE70004D854E1E4762B680F95E6DBC433B98AF50 -:10CE8000A47DDF7D357CD95215B957DE97E95FAABD -:10CE9000E59370BDFD83EF601CE1518205FDD4B9BF -:10CEA000F6A0552C1CE92EF335CB2AB4E5C2FC8242 -:10CEB00098268ED7C6D76C70E1C834F9DE3ED567A8 -:10CEC000AF41FADB756DED399F37086DEFA7EA19B1 -:10CED0007E82DEAF4C1DB206E37E400FAA2738E902 -:10CEE0002A7C5E1700E706C805E330C925EA65C05D -:10CEF0004F7207FBB74FC8F83D23F0F34DCD23B871 -:10CF00003FD79CC0CBADA9DC7F5B23E371BDDCBE0A -:10CF1000B98B0A0FBDFC74863F37AE0754F3263C2D -:10CF2000DD1BA5CC7B52E118985773041B20009F92 -:10CF3000BC943A61CD92DEFEF7B7A44E223EF1F7E3 -:10CF400057D88276FC5E194F5B53EF6EC17A3C7204 -:10CF500082F2569ECDF75F4DF5073A94B705EDF98D -:10CF6000C789F915CA8991F03DC166C8E4FD2474EA -:10CF7000809F5FB57FDF16F03E3344DDC8FB327D16 -:10CF8000C604D0AF20807E2303E0222DECF783A1DE -:10CF900067F09F8A77AE5E1A83F1B32D02DDB1028E -:10CFA000FD6C14E079E396070A43703D2A4A869E99 -:10CFB000D0F6C32DD35ACCA0BFC6A3FE227D5C4CB5 -:10CFC000FA7A22CA39C1D30B6D3723DF542E8D85EF -:10CFD000F61F6F99B106EFBDDEB764B50191FEE9AA -:10CFE0009692357AE8F7DECC3FEDC5FEF4D5A52D57 -:10CFF0006384ABF0696DC03CD607C0CE80F66BAEE3 -:10D00000A1CF9704BCBF28A07E5500BC36005EAE01 -:10D010007D7FDA0CBE7F390DE88788BB96BC7C9398 -:10D02000DAE617B4D92F01EDD9C75A7EBFB386C34C -:10D0300067531F295C1EA282B72C2854F3AF41B658 -:10D040001753A2ECB68EF8F75067FC931A68D79C7A -:10D050009A73898719D3D8DF3DA2166E1495F12EE5 -:10D060006D79384DB51FC89614E23E51E7FB158B1C -:10D070000B71BFE2CEDF29F58B0B6DAAF929EDF319 -:10D080007FBC22E2F7F42F57176EA2FD3F79FF2EE7 -:10D090008297B75DBE128674C9C7F3A358DFC59DDA -:10D0A0003C5F6DE7595D0ACEAFF1317EDFD05903A9 -:10D0B000F400392F6656DAFF6E0C0F5FF812B4DFFA -:10D0C000F398B810EDD7E1859174DEA8B01FF7C7CB -:10D0D000F684F7897910E0C6E0078C18576D7C7CE0 -:10D0E0001495EF8BB6655E407EFCCBB564C71B83A1 -:10D0F000C3092FBDFBAD2AC42D59A99F44787444A0 -:10D10000586276A21FBAD2C070FF8931EB0BC427D8 -:10D110004F98C84F9D56DD9FF67B8A7F3F3EBF3BB1 -:10D12000B42B5E6AA0F83FFCD17D0CC7CA5146AC57 -:10D130009FB1442E9DB753F9DE4F6F7E9C4EFB3A54 -:10D14000229DDBD9ED8B380E92CCBE760EA0FB0A69 -:10D1500047E5FC2A6FF773A4F583797CDD9A44F9DF -:10D160005298450A9B807EDB4DB601FDA2FDEDDEA7 -:10D17000FB49A4FDAA775B8B63906E43FA717ED95D -:10D18000ED2B8E2956D9F592337AC2F37B46E961AD -:10D19000D41BEF75E92D38496EEB2231CE3A43F6B8 -:10D1A0009B814F16BED9011F26F513A9DF63A68503 -:10D1B00078169635FE263A17C7A5BC97D5E2A8C1C2 -:10D1C0007C31865ED220B57F7C6BF2883C9C879F49 -:10D1D000BFFE48FA9CFC6380C7BDFCE21A27DABC9C -:10D1E0003DE0D7E338A26CF958AF9CC763B175290D -:10D1F000EAB882DF0F5D2CCB3F6F77080F07C3F7CC -:10D200000F6D0DA2735F879C7F0F55FBC78A7CCC87 -:10D210000CFBD5E1665A17874B421CF08DBEEAF82D -:10D22000A3F05EC9F306D29B25CF472FF2623DD013 -:10D2300013B70C03BFBBA51F3F0FD0B97CD407C8E1 -:10D2400047FD55E5A3F4E5370B378574241F5531A9 -:10D25000C847F9CF1BE87C755197CA4918472CD2AB -:10D26000DDCC6A607C239EFF450CEEB3CC7CDE44B3 -:10D2700074F584861EE7F3EA138FF36AB33FFDB8B3 -:10D28000BEF254E790BD1075E09D81FE16971968B7 -:10D290003D22C61849EF8961565EDF85C52F06BB62 -:10D2A000BC34345B42FA6E4679C8A27A09F92C2F55 -:10D2B0007CF21D78AEE5F0C244DA073B99C9F7C1AC -:10D2C000663DFA6218FA9F871EE6E7BB6763BE1DDC -:10D2D0005CE7FE9BFB5E1572BE9DFFAB7DAF67FA00 -:10D2E00005EE7BF173A07B16666472BC30C984784E -:10D2F0008A1B4878B9DDCCA420C08B18C15250FFDE -:10D3000028FB5EE22FB97E127502ADD38F55392905 -:10D310007F415E98993FFF25BFB7273E3D9ED13E96 -:10D32000585425ED8345C8789D26303BCACFD1207F -:10D330006BDCBC34E4BF20A2E7CC17667DF16C2621 -:10D34000D26D6C94269E80FC17ED7FFF44F52D3442 -:10D35000BE1302B3A0BDCFFB43DF91489F46D1F17E -:10D36000F4BDA4378369FF9C593C4F0C01786635A6 -:10D37000ACB319F24DF7B884347F3F33173F968230 -:10D38000F4CEFB43901BCFDFCC5812B416CF619480 -:10D3900035F07BDED3567C47E77159BCBE12E39C67 -:10D3A0005F2F09E2E7D4EB8710FF4CD3F1732E2CEB -:10D3B000CE48F1A5B21019EE954DB0EAFE9211E9F2 -:10D3C000A1DCBFF918F50A7CFFB4820FF41B51EF02 -:10D3D0002AE7E859A584F25FA4133A3CE7F5553FE4 -:10D3E000EE9F4E8BB3D279D1F2DF9AAC8BE3399DAD -:10D3F00045559EB9729D377F2DF6AB63D2760BAE45 -:10D400001F9A4B70BDCDEAFB521E820A3DD31B23EF -:10D41000E0B9C4F599329E0A69FCEDC44F7A7650A2 -:10D420001F81786CFEA219F96371A8847191F2AE24 -:10D430005607F51B6AB6703B217F17C79E887CE0B4 -:10D440003346201F7C21E84C3CFF804D07F5E71850 -:10D45000AF6FFBCE921569346FB34537A23BF2DD57 -:10D46000F9FCB5F0DEED4C4AE88EF7C456444E9A0E -:10D470008CF5AF89A49740987E9B8DFEDE6B62068B -:10D48000AE53A7ADD843F39BF3C640BC41C0A6BD85 -:10D49000FE19D9A739327F79E4736BC500BF01A5A6 -:10D4A000FE266E271C22ABAC2358D0EC572AF5E59C -:10D4B0002B0C448FF2A526A27379F55FA9DFF2D079 -:10D4C000E618A447F97603E5EF08BD49A2F6C5D5ED -:10D4D000BD730FC2B88B0DE116011E9539C71A1125 -:10D4E0002EAB150856BE57BEE2F3185D1AEF0F4B70 -:10D4F000938EEFB3FAFB8D8E437B767A6B64DC34CC -:10D5000015DD4F2FD91186FBCE4783DCC978CED7E6 -:10D510003B2FC88AE70A9578DAE925C9FC3E90A531 -:10D520003914F7AB673C9C188176EEB0C56DC4FA30 -:10D53000C375F178648ED92C965C846DFA9B093E94 -:10D540002D9F23A13FCC1F2870BE29DBBAC79800AE -:10D55000DF1B24E3E7CC6B47F70E457C001F5950D7 -:10D56000FFC435A7A01D2ED735A7F444FABC2290DE -:10D57000BF00EB531BE61F998B7C3508F4A1CC57F9 -:10D5800073EB772C40F92C7FEB643EE2F5CC5866C8 -:10D59000C4F858B93C7F583F7EA087F6E5DB36E4F7 -:10D5A00033FEFE07C8778ABD07788901E026238706 -:10D5B000336EE2FCD364F450DEBBA6498CD1FE99F5 -:10D5C0009E8DC47640797E0F4014E5FB6995B113BA -:10D5D00078DE3DA7FAFCDC5CAC4FF3D777C6378525 -:10D5E000325F14579BC82E15CA78F1ACD81E867CC2 -:10D5F00071E6B53D7B87A25C6C132C4C2D0F8A1C09 -:10D60000C679793DE0EF49C4DFB6F3F998876276D1 -:10D610006BA8843454F0A4C89B82970AC6F1A0E09A -:10D62000A5422FE349AEBF5BC64319F3527FAC75E9 -:10D6300080B419FB7FEB07DA6F3B338D09FC9C301C -:10D64000CF8BA6CCCF11A1DDDF5F26CF6FFA4DDCEB -:10D650006E9659B85D2C8B6252F540E2339B51C9EE -:10D660002F094DCEBC714433FEE7653968A337CE30 -:10D6700003C6E9D1F17B8281FAEB51197F47AAA752 -:10D68000B851AFCC76423F99280F96A9B8CFC95E62 -:10D690001765FD0D32A9FA6EDEAB47880F41774959 -:10D6A00011B066316C8171A0FFD5DA9BE28579DD1E -:10D6B0003C34EFCD632C4C07FAE488E009DD89F6B1 -:10D6C000E05191F494324E9BF363A287AD8ECB2749 -:10D6D000F20BC60715390D1CEF3279BC269DD58398 -:10D6E000E782D96281EEAF898BCF841EE4F68E2269 -:10D6F00089FEFE6FF900F7236D17C324816AAC7AA7 -:10D700006C37F7625802DAEF2372DCE1C8D21D6190 -:10D71000C52A3AACEBEC3BCB864848FFBC90838FE4 -:10D72000A11C3D759320F3BF75E442D40797C22432 -:10D730003C2FD514E14C433FAA49C796B308CE8786 -:10D74000FA183FFE405E087F502F3D65F1CBA532B1 -:10D750006EA09B1BE906ED6D5C8EACB48F31378AF1 -:10D76000EF8B5E5B9E323CA49FAA056963A6BF9DBA -:10D77000722FEF7179DE2423317E7B80FC89F6CE17 -:10D7800024E7310ACC837A7BAFAE7188BF8A10B3AD -:10D790000E977081F581B07F3D55A9473F9F2D8938 -:10D7A000DDABBE977634C849F7CFBCDD45B611E88E -:10D7B000513DEF237E9EB781DFDB52EC34FCAD6A36 -:10D7C000E33F78AF34F37C3EEAD73FE698E85E5318 -:10D7D0004C7F7EDEE514AB330E47FBFF6D737E9806 -:10D7E000E45F9FDC72D12D8693BF10AF591F94B5B3 -:10D7F0007E40F25CCE9AE93EF6B4159F8D1D82F410 -:10D800007ED940E70766D4C6939D3BB9697A06CEB8 -:10D8100077DAD26482676D7E90C32B78FEC3694B42 -:10D82000B35E42FFEB68902D1FF9D9BB5AB0E0FA06 -:10D830006AD8E6AC45F741FDB0D03E5D71DC873675 -:10D840001D1D8B743FB45024FD64DBF4D424ACB7AD -:10D85000ED14F1C618AC672C8B30AF29D3875BD0A1 -:10D860002F50CE17D618B8BE3D2FEB87936D25E706 -:10D87000D3BC9A9A14F497BC1BC01EE1BEB7D15B0F -:10D8800042E7BB058B7523F0CBB782936066B1246A -:10D8900054E7E07D96F5941FE75CB2C9827EF2FD05 -:10D8A000266645BFF6FEF77A0FC2A5824D5E578DFC -:10D8B0008DE4DF55F0A57CDF2BF33D135795D0BEEB -:10D8C00043A49480FAAD493E377E541EEFC9252FFC -:10D8D0004F42BFE0E496E408A6C2FB49394FD32C7F -:10D8E000D083DB3A58EFFD7893127770D1774AE511 -:10D8F00078E03E436D2FCCFB1978BFEBC486203314 -:10D90000E6E70DBCE775C2C0ED47BBFB5E3BB570FB -:10D91000609EDBC0F12865BBFBFFFD433AF4E315D5 -:10D92000390B7CBFDD7DF2A4EB3B5F8579C9F0BE8E -:10D9300077D34D8CC63932F8C737515F97D49A2CBC -:10D9400078FFFE589044EB2167169336A39D314B28 -:10D95000E1B89E3FB62F83CEFF957CC548AE4AEA1C -:10D960004517A62AFE6075DFDFE502FC60BDC18AAF -:10D97000EF9F5CB37A1217336D9E856CC6E57326F4 -:10D98000AC93DC16FFBA2870BD347BED1B748FF0AE -:10D99000E75A2F2971A4407CDFDA5FCE4FDAC9FD48 -:10D9A000B9F7806DB207B5C7776B9583D64567AB7E -:10D9B0004AA9CCA9DB90D753C2FB14477E3B0CE5A8 -:10D9C00026349CE221AD5595B489777667C665BC4F -:10D9D0001FFA6E48B805F5C5D9AA85F2E502994F38 -:10D9E00064BEBCA5BE51ECC9A87DC33068BF3B2452 -:10D9F0009CEEBA24D9B2C3D1CE2B740DBCDFACCC13 -:10DA0000EFD4A39CAECA784F6D991E867E67E3BAA9 -:10DA1000C8869C283C9E1B6E417F7BA67CFEE5F859 -:10DA20005AAE6FBE3587BF3406CFCFAC9F1883EB9D -:10DA3000BA070D5EA315FAB5EE1A1F8671BC6FF416 -:10DA40009E30BC6FFC0DB477A39DD0BB44D4734310 -:10DA50000B18EDE30D75EB99144F5BE6C41739AD68 -:10DA60007A17D2F5B4FBE29E2BC847AD3A8A77010C -:10DA700066F65C81F6D6D03E14277CF06DBEDE647F -:10DA80003F76E1F501F7169FE9CFFD9613EBDF1C1A -:10DA900047EBF34D060B8EF3ECA6CF63F01CCE6C78 -:10DAA000C6CFD77FBB45A079CC067E0C8A47FDC088 -:10DAB000E3A0B341EF9B85F67C98B7A59AF8703642 -:10DAC000F021E6F59E6DE3F99867633E6689B5CB74 -:10DAD000FFD155E6BB39C077787FF7E7CEFBF13B46 -:10DAE000850F03E45EA1BB821785FE7E3E649AFC2F -:10DAF0008211750387F7647E7DA0DCEF607ACF2A00 -:10DB0000BCA7B1400CADC57C55FBF5957FA0BC2DE5 -:10DB10004E3DDB4CF69CA562BEBC05E24D568C0723 -:10DB2000D6182BDBF2BA607D605E173184BF3F1ED2 -:10DB3000F313C37CBBA6C5D3F72658ACA310DD8670 -:10DB4000280FC505C43C9D8DEEE5D59868DD1CA861 -:10DB500087EA64FADE95C6F5D0FFF4E7E7B5957B72 -:10DB60007F4A099AB137F2FBF8E0884B1234D9D5D5 -:10DB7000FFD0DDB84F3B7E58C42F12E1FB7B5F3DE9 -:10DB8000CAE18C88ED090037F5FFFA6EBCC731FE9B -:10DB9000E6882C03FA01D5C7EE1E09F0F1FEB67730 -:10DBA000FBABBEA3F40BCF77E3F37FC439DEEF4FBB -:10DBB000CFBD2548EF734218CFF796E4A538A8F2F9 -:10DBC000DE01811D7E57F0C31E038BC3BC06FF839D -:10DBD000BA3BBAF3B27B9AED63FE7DED73A4D077C6 -:10DBE000B8CE94F77F7466C988FE9FDD6AB4F2FCF4 -:10DBF0008ACC6E06BFEA2E997F8BCD974792FDADFA -:10DC0000645613263059AEBD8FD5CF7F6F6FFD8D13 -:10DC1000DCDB634E9E87AF46CEC3D7D93D4AA1E138 -:10DC2000A31FD0BF0CBC3F95F149F35BC827E3802D -:10DC3000AFD05E643673F82E994FCA778CA57CCF2F -:10DC4000F30F185CE827CC92FDB12447172641BB9F -:10DC50004B20BFA8175AC7B953507F9CA862B5493B -:10DC6000A0B00ACC8E4BFD014F4DF11F515EB41395 -:10DC7000EB6BC2D0EF3903EB8931D04599ECDFB3C0 -:10DC8000CBA2FB36F483E3FB6D5CA9E2B79F643E55 -:10DC90006B8D77C7E1FAC6196FE2F91A2FEFA13C35 -:10DCA000CF0509A3B3308EB4BF6A273B9AEC7FAF90 -:10DCB000B3FB284375230C69AA7DC971FA8ECF691D -:10DCC0009C51F2696EE2F6DBA4AFA53C5A40CACA89 -:10DCD0006A82ED14578A451EC5F8B0F410C1CB66B0 -:10DCE000310BDD63F5EFD3D17D5085FE36EB959199 -:10DCF000D86E1CD01FF58DCEECD5236C2FE0E753EA -:10DD0000FA01E1509F28F41F252EFA2DD261BE7C26 -:10DD10008F6BBE50C9618399CEB906EA478C6B16EA -:10DD200091DE74EECD417F0CF424E55590F5A2040C -:10DD3000FFA3BC48D91B8CD4ECDA7991F6E6FC073A -:10DD4000FA31234D9B475CA193E25F754627454F0F -:10DD500002BD86A5455F3FBD943C65F39FE7F1CECC -:10DD6000F9CF4F8F1D44780389437F28ED4F44C47A -:10DD700099F21CD8FA48E263C308BB84FA76ECCE69 -:10DD80009E4C8247B3760A74BE75CCCE4882C37C63 -:10DD9000DD795E25D9DE8FFD63B711189F3CF9D27E -:10DDA000DF1FC6BCF7637EC3287EAC0B0EA17C13BD -:10DDB000E208398F8318F221DE63BD20F1DFA1B0C4 -:10DDC000B376F9037444FF267E4E1656794E4E27DD -:10DDD0007EEF6FFE3E6EE7E70FE7FB8217F00D6800 -:10DDE0007FA150A43C4DCF04A793FF5673B781EE9B -:10DDF0004730A7ED2FB8AE9A2CF383291616962A32 -:10DE00007A054920AF2AFA3C1EF4DB0F1DD0BF076C -:10DE1000D65D420FC682532334F57A67D037983FD8 -:10DE2000D6102B5A5C30FE506B0F4D7F76B1CC80F4 -:10DE3000F114E6E07EB4C25F4C6CD5D3BDF95C9EB4 -:10DE4000BFE2EEC9DA7B9286DCF323C9DEE46AFD29 -:10DE50006FFB35F236FD4AE1A77EAC9F9C979EECA6 -:10DE6000FF85167E3F4462F6B58ABCA0FE07EFE64A -:10DE700019C4CFA42603734984BFD7B0FE82D364EC -:10DE8000C178409B1F9E04EF45A19134139F635EB0 -:10DE900050F53C312FA81A2F9817540D635E50751A -:10DEA0007BCC0BAAAEC7BCA0EA7ACC0BAA86312FDA -:10DEB000A8BA3DE60555C3981754DD1EF382AA6142 -:10DEC000CC0BAA6E8F7941D5F59817545D8F7941A7 -:10DED000D530E60555B7C7BCA0EA7ACC0BAAAEC7C9 -:10DEE000BCA06A18F382AADB635E50753DE6055557 -:10DEF000D7635E50358C7941D5ED312FA81AC6BC59 -:10DF0000A0EAF69817540D635E50757BCC0BAAAE51 -:10DF1000C73CA0EA7ACCFBA98631EFA7BA7D335B78 -:10DF2000928C766C77BCE37FD268DFE95BE2E783B3 -:10DF3000F7033FA31C364DB450FEC21B5C277E9EE8 -:10DF400026EFF7C8FC7B89854CC573E89DBDAFF013 -:10DF5000E7EBB2BF01F66039F12F0BAD457FEE71F3 -:10DF6000BD8DEE4339EBF8FD44A6E77EC00251F6C5 -:10DF70007FE4BC100B4489FC00CC1DAC578DA7ABD3 -:10DF8000CDCCF42A3C4416583470B43D56D3BEDB95 -:10DF9000644953DFDD91AAA9EF596AD5C0BD2BB3FF -:10DFA00035EDFB2CB469E0786781A67DE272BB0693 -:10DFB0004EAE9DAC69DF77AD4353DFCF55AAA9EFD5 -:10DFC000BFA552030FA85BA8697FF34EA7A67EA04A -:10DFD0007BB9A63EA3A956036735AFD5B41F72D04F -:10DFE000A5A9CFF16CD1D40FFBB64E03DFE2DDA9BA -:10DFF000697F9BCFAD8187B37D9AF679E6031A7866 -:10E0000094E54B4DFBDB638F68EA474B2735F5659D -:10E01000A7B97FCF6A607D8071CA109E5F63AE9B97 -:10E02000D5A17F7167EA794D7B4314AC17807FCA15 -:10E03000411FA2DFF77D9738CAC7CC2AC3AC78EF5F -:10E04000DB39A2F20FEA7BDE63AD3F68BEFF4C70A6 -:10E05000983B88D61766B2B7230624907D6CCB27F1 -:10E06000A2DC67675E161B4521212FFA4702FEC21C -:10E0700012C061369E171AFC20F29F2CE017A1BF38 -:10E08000D9B62ED2C5C7A35D0EF6FBC5BDAEA8F2AC -:10E09000BC5CCB2FA66F67519EDE5103301E5EF72E -:10E0A000463EAEB36631E732DC4F54F22CEE0FD26F -:10E0B000C6B79472B419F0ABFADEBEA0DA5E83AED6 -:10E0C00022EFA3CDADD4BEAD5F39FE25C064E7AB72 -:10E0D000FAFF2DACFFF420D7B555207FE00F3D5956 -:10E0E0006521784D552CC14F574954AEAD4AA5F224 -:10E0F000B92A2BD5AFAFCA26F8852A1BC1AEAA0212 -:10E100002A3756D9E9F9A6AAC904BF54E5A0724B2B -:10E11000552995AF545552FDD6AA8504BF5EE5A496 -:10E12000B2AE6A393DDF56554B707DD55A82DFAAB3 -:10E130007251B9B36A0B95EF54D5517D03F86F084E -:10E14000EFAE7213ECAE6A22F8FDAA66823FA83ADF -:10E1500048F0DE2A0F954D55DF52F9E72A2FD57F7B -:10E1600052E523B855DE87583440D0DCC753603DB4 -:10E170003BC6FD3DCC5B817918B20D67AF961F376A -:10E18000900EA7E4FE0D23C05DC238728F948D35CA -:10E19000AA75C5F201DC5FACD6F1FC2DD53D98A582 -:10E1A00086FC761BE3E7B4B8DF3E13FF25C1D3A896 -:10E1B000AABDB8DE28A9E479CAB3901F53891F3FCE -:10E1C000B9A1759ABC2ED891687F6600AE43425CB7 -:10E1D0005FC467FAEFD11F4C743C877C7AA1F2C10F -:10E1E000BDD87AA6C59A821F196B724763FE2FEFBE -:10E1F0003ED1BA51EAFC7B15F2FD874EEB779FECDE -:10E2000085F6AAE02791E2FAFB0DA193719F7FABFF -:10E210008C8FAD03749AB228C9FE2A8EE74472E54A -:10E220004B0F09FEFBFB77E1121FE47B3C93280FA9 -:10E23000CE4466FB105DF0BBC11144F81EE6A4B2EB -:10E2400035C1518FEFDF0B0B10841D434D711DCD78 -:10E2500027703CBBE5F1EC96C7A1940B92ECBB1088 -:10E260006FC7926D9AF16C95F3338C63DE17705C17 -:10E27000FFDC75FEB890E8C7775B3C8555529E8CF5 -:10E2800022C6E3298F635E8C287F5E0C65FD50B447 -:10E290008FFFCE11FDA1FD5C104FEBDBC0BC19CB95 -:10E2A00086EFE17930603D86F77F8BE6FD82F42FC3 -:10E2B000FE1E14DEDB5DD0E530E599F1CC025EEDAB -:10E2C00049793578DE1B0720B027E5D5A07AE1260D -:10E2D000F87F771C9739554FE3EB42F94E9E09DEE4 -:10E2E0004F796930A660EA8A798F79BC66BFFD3CB8 -:10E2F000F7BBA3BC743F7547A2E3EB013C4EFE7431 -:10E3000006C689909FF03B16179D5F037E320A80F8 -:10E31000A29951C04F1DF81B0ADFCC95EFE128CF21 -:10E32000811F5B11DF67DF1E928A7C53B13B47423E -:10E330007CD7E8F87D3AE79FE57D41F9F710C4F016 -:10E34000B40D74EF009D71A46F4E28DD3B6814D9A5 -:10E35000C2373AD0AFA1E95CDEF7C7F27C92350153 -:10E36000FB93C6744E77633AE787B1EFEFA33C6443 -:10E37000739B78BC9A657AD2EC1D9CCBAA58F89B0B -:10E38000A79354F3A8D879849FE7629E34F539AEF9 -:10E3900064F9FB0AFF89C650C78610F5F878FC01BE -:10E3A000E420243D8BE4E038DEEB1E6792C2EF11DF -:10E3B000E8F7C1CE627E19C71F2C741E503917387A -:10E3C00083D9A99C099613F9DEEE5C4DF7E767B394 -:10E3D0003A7A3E377B7A1CC215CC3B3216D747CBF4 -:10E3E000AB3FC470D0C4DAD5A3BAC3BC26B8A67DEF -:10E3F00088E5F84DC271A74472D43B1DF7B785CAB2 -:10E40000A53DE07BF76D1DBE14E3D6E3444E07F651 -:10E4100031A74311F0B318D17E7E203749E95C6EF5 -:10E4200068FC8ADC142D66363C7FA0DC0F6993A360 -:10E43000EC39FFE8897B38E04F22BF56EC3645D0F7 -:10E44000FA14F3CCA0BE92E567A99EFB974E4C6DE3 -:10E450004AFA93FB1B069B9CCF8B717F648E93AF14 -:10E46000C74E19B8BC9D3A14EA42FE5ED0E5F538B5 -:10E47000920F83221F3F4DA5F33D0CFC8F5BDBFB0E -:10E480001F6D79667A31F237589C237650A2DF9E51 -:10E490009FD2B90687F1BCFCA3105F7B63F9FA79C0 -:10E4A0000EE6A1C1FAAE7609E3A5A7A2CD745F2856 -:10E4B00030CF1963569A9F419E1F8C6C32FAD32637 -:10E4C00039AE561330DFEF83E268BED27056C7D044 -:10E4D000B1D05B9CD351EE1FE2766241975F3BF077 -:10E4E000FB9E20661186D17C281EEBD4317B0D8FDC -:10E4F000CFD2FC16EACD163C97B36C9AE811C84E01 -:10E50000C038319E1765B6F2BCAA4AFEEDC0F1DAFA -:10E51000B4E333C7319C9F4D64DEA0617CBC383EC0 -:10E5200027D083E803F034D5F8A05F17E5FF0996FC -:10E530002CE88735FDF8108F2F5773FF11C6BF8564 -:10E54000E8D31DC6DFF3DAE337208BC2F817A4C780 -:10E5500013DFD5E00EA28876B62BE9DF0941F64736 -:10E56000900F931C2B7BCDC7B8468EC98AF13B76A2 -:10E57000B9A617EAA91026515EAD71369E570BBA9F -:10E580005B82FC301EF3D659C80F6855E761630102 -:10E59000F135200BC55727607C8DDF25FA00E3B3EA -:10E5A00013E5F3CDFDD8570AFE28BE26E2F8285E13 -:10E5B000EDA0719A90B25006619C87E8E0A27904C0 -:10E5C00033B71CCF6E26FF60B5CC87430F32B21332 -:10E5D0004343B89DD87D84B9F0DC57E30F93F242F2 -:10E5E000A17EF7793DE929C013E5037CE7736E57F7 -:10E5F000769F3CDE13F703AA7FD8DB13FDC4DD064C -:10E60000875881EFE7982C8BADFEB846C3C1101E2A -:10E61000D791E37CB7C8F36C60CD3515509FDD5DB5 -:10E62000641807CC6A7107A33C638EDA8EF61B73FD -:10E630002F1A35BF6B61B068E16CA682E3F1E85137 -:10E64000C0EF7FDEE03A775BBAF6F729DB7EF7B3FF -:10E6500035EABA7EF733539EC7AA74FBBBE964D789 -:10E66000268832DE05C417E88146C4F773E546FA0A -:10E670005D83C67263778F6A7CB5B3FE49F87DEF20 -:10E68000C77F92DD7A2F4BC98F531784CF8DCE5021 -:10E690008ABB3D77594771B775A55FD3FAA4369BFE -:10E6A000D1EF88D55E2E263FE05201C34D24567D22 -:10E6B000EBFF9622FCBB5BCCF4BDC0F1EF027FDE2A -:10E6C0000D847A17FC79775FC6DE067F1E61BCCFAA -:10E6D0008AE576F0E7B174813F8FE50BE0CF633BCD -:10E6E000F4E7B17C0EFC792CD7823F8FE5D3E0CFE5 -:10E6F00063BB35E0CF63F924F8F3F81CC69547E314 -:10E700003AC8E8DEFEE2E0B015E86748CE50F237DE -:10E710003EB50DEAE251D9D95B2FEA3474CE6DD5FE -:10E72000FEBECDD063119ADF3FC9FEAA87A67E70D8 -:10E730004B82A63EDEA9FD7D9B3E0BAFFEFB363D28 -:10E740004B4704FC3ECE1D01BF9FA3FD7D9B68FB94 -:10E750007D01BFBFA3FD7D9BDFC9F932153AA648F5 -:10E76000AF05215FAC2B9D10CE3AF02F94F2499962 -:10E770001E0AFCD4A3E2E48EE2C85137737BFFFE8D -:10E7800021D3BE4D80CFF758B81DE3EEEFD974A466 -:10E79000979E5B1B4271589367E849E49FF76C4C66 -:10E7A00042FE79EEF2882E389EE140467CDEB3943C -:10E7B000DBA73E374BC4CF3D4BBD22DE17BDEDB2CC -:10E7C000D78AFCF85418FF9D2DE8D7B518FA7B7F3F -:10E7D000ECE07E18C7792E04F819E5CDED0D4E0258 -:10E7E00038FC8A8EA17E045B4979FE9DCF86C8E7FE -:10E7F00051AFD07DB870D4E9A097DE2BE5DF4FF1A3 -:10E800005C0E56FB43BFFBE95A7861C4579DD6DFC7 -:10E81000313B01C7EBC73BA84628535829FB2DE2E3 -:10E82000A38CCB4F6DA98EE4E912C813E207664DA5 -:10E830007461CD5A797F12E5434D87B2841538CF84 -:10E84000E7D6E869B76C94B875DFCDF0CABA16910F -:10E85000B6D9258B37B823FF4E19F73A1B9F5F8433 -:10E8600095E9D0CE45003E5DB49F6DAD56FF9ED577 -:10E87000B3B27CFE5E96CF67647EC0F536C2A3C499 -:10E88000F5A353701CD95C5F033D05BC8F75690609 -:10E89000A3DF11FD7D6142978EF27CAF91C7F182BB -:10E8A0003CAFF5D82FC93397FB5162D170EC679D0F -:10E8B0009D911E5F67FBBA1AE376970A79BF7D16B2 -:10E8C0007904C46FAF4AAF80FDF77ED84DA54B1ECB -:10E8D000678FD266AA57FA93AC2ECEEF655FB32648 -:10E8E000982F1EB215C95EB4527ED4757A3D433B53 -:10E8F0008CFA0CE14B663D9E91603D661D63789FEE -:10E90000B936444FFB14EBE69E2278B585C361CE41 -:10E91000CA343C7FF1B63C9F30A7936057C07C520D -:10E92000A407C2D5BFE71A58EE90F1BC5DC6C7DB9D -:10E930000687EE028C63C85F45FAFD8ECEDE53EC8F -:10E940006CF657BA00FDD34523FFF81B7BB25DF888 -:10E95000F5CDB87E76DAC92E28EBB6ED63B87D5DCD -:10E960001D3CF5635CF717CA7CF44CF0B80FB1FEA0 -:10E97000B3D1FC77701A47DFDE5BAD2777CAE3DEE1 -:10E9800021E33DC7693BF430B41F6F37E1C8C08C49 -:10E99000D97AFF02FAB38F11AD6EA05B4B96220FAE -:10E9A000F66094BBF7C74C6707B1FF02BEEFB4BD7A -:10E9B00060223D9798FDCE01F0DE5F9AF5E4CFC06E -:10E9C000F3ABCAE37E19FF9FC8E3F8B38CFF269927 -:10E9D0004FF7A21DE98B7196542ADF97ED885BB63D -:10E9E00023BB653BD220DB91B7D18EF4C5794DA610 -:10E9F00072BB6C4732473F457ED225CC8B2BA01D86 -:10EA000099CB96C138F361FC6207F6EDAE6C31E04C -:10EA100077B2823574BA333552038F967A06FC4E3C -:10EA20005762C0EF78F5D7D4E79933027E076C9828 -:10EA3000A6FD6DBE1101BF23A6B523438F4DD0FAAD -:10EA4000335FDDA7A91FDC52ACA977E23F60BE5956 -:10EA5000C718CF2F1B9CFB04F24BD671BDF2FBCC29 -:10EA6000B48FA6F85B81FE4F166BDBC7D3D13E9EF9 -:10EA7000934978AE93B6961334F5E43FB518EC3D60 -:10EA8000F1FC61F578E03B3C87D8523286D13E3CC0 -:10EA9000F02FC85396FDC457946F542CCA203FE9F9 -:10EAA000A25EB39F9613B02F661FA9DD37CBBAC6FF -:10EAB000BED9B19B3BF91DF6D688EBF2C7409E4408 -:10EAC0001CF733C153F720DEDEFE92DBA9C62F1FF1 -:10EAD000E989CF3FC0A6D0CF8E6F1E21BF6B479B69 -:10EAE0007C3882D5FED6760FB7176FB524ECC47587 -:10EAF0004666B4407A30F3C8FC29C48F2D3AFA7DBB -:10EB0000CE94828A60C4CBF6838B83B5F7A754FA80 -:10EB10008108A5D20F22B232FFBDBEFF07E9D10F97 -:10EB200034008000000000001F8B0800000000007F -:10EB3000000BED7D0B7C14D5B9F8999D7D25BB812B -:10EB40000D09B08104260960AA3C36EF4D48C22465 -:10EB5000048C1AC8427804C1304978A48A9AAAB5AC -:10EB6000D86233211062A4121F55B08A2BADDAF699 -:10EB7000F6B65425A0A22CCFAA5058306844D4052C -:10EB800014ADA5F7A284D6F6CFFFE73DDF77CE24FC -:10EB90003BC32640DB7B5B7B6FF8E9E4CC3973E653 -:10EBA0009CEFFD3A134208F94AA4FF8B1F4E0269FD -:10EBB000047FBE4A81FFA7F4B6A19F5C4D02F6F028 -:10EBC0007686A19D6F185F62685F6F183FD3D0BED5 -:10EBD000D130BE56D7BF2D3473A0E2A4BFC3CFA49B -:10EBE0008BAF5B1A09095CD53B2EDBEC133D632F21 -:10EBF0001E97D369EA9D97FEB7F3FD25A6F3F1842E -:10EC000074748A7E5B32BD1E5F42D42C3A4FA7C912 -:10EC10004F04BC9A08EDDFD6C5DA36A23AC6D3FE59 -:10EC20002D9D664F9B44C80EFEDE31BE85037D31AF -:10EC3000844C329F8DF85EF982A9777F04E69B3978 -:10EC4000904418A75D77F179038D76BC6E6F74914F -:10EC500080ADB75F8CC9EEF4D17574844C1E7A9B7D -:10EC6000AEBF248ED07DEF762E76C0BC74BD840CF2 -:10EC700023E4DACD23AA9A461122D1759BE83EB649 -:10EC8000844CA48DEE33EB287B7F96458E734580B4 -:10EC90002B21263DFC2F9A8FFE009C9CA2BF8DC28B -:10ECA00065D7FB73E2C6D3F95FEA1409ACC7AAD4EF -:10ECB0003B7CE368BB8BAD4B9B77B25DD4C1A19825 -:10ECC0003874F8283C3B48D7CE3A41D7499FB74AD9 -:10ECD000157100DF4BAD939068031D0D32B487E9C9 -:10ECE000C68F9128DEC6F58D8797381EB6001EE8C0 -:10ECF000C65E8AF254F922C06BCB07D67A7FD8FD64 -:10ED0000660F054A365C4D78CD3A61F204287CCE18 -:10ED1000779A3C00BC3C57BBD810619EFC8FF4F442 -:10ED200099D319AD83171117F4CB07CB8F37ADD912 -:10ED30001336FEFB9E98F8D3D7D05F72492EEEFFB4 -:10ED400012CFFFA9515DB3C742E99892EC663A8EA3 -:10ED5000B82A0949E87B3C212B717F1A1C892B8E2C -:10ED60006EEE72F0D48ECF5D84AF3E9EEF9D472550 -:10ED700064308527052F8C5B3BDEF7B887B6496882 -:10ED80008608EF7FD0719B18A2EB7ECC71DB6EA062 -:10ED9000CF037FB64AC0D73BFFDC9108F7F7A76FD8 -:10EDA0004D04BADF4FDF1D84FD9929D668DBAADE4A -:10EDB000E400FA7AB3F308F28F4482374CC882B683 -:10EDC000C9D34687BD9A563990F403B7D7399DEC1D -:10EDD000E3FCBA87F3EBAE4637E76309AFAF35A67E -:10EDE000E1FDED8D1E6CBFDCE8C5F6B64619DB1DF6 -:10EDF0008D65783DDCE8C3FB871AABB0FDDB46854B -:10EE0000D161DA9DA5208FCE275200D07DAD744C04 -:10EE10003747C2E775929ECFAE75EBF96C0A8573E2 -:10EE2000787BB27DB8812F5375FD93BEBC5AD75FF6 -:10EE3000783643D79EF869BE6E7C5EA844D7CEED87 -:10EE4000BA5E377E6669A5AEDF57305FBF3ED189B7 -:10EE5000F265874B40B93C3DAB4ED7BF037E0139CD -:10EE60006C17FC6A32C0A5B25F791A00FCD8008E1C -:10EE70008C8F7FC3F1B317F06303BC30F8BF0AF087 -:10EE8000A7ED5700DEF49ADDADEC1E28811CA8C763 -:10EE9000B6356DA0D343E1FFAA5344F9BFB5B10124 -:10EEA0009FDB7FBEB65BC4F53A24C0CB0EBE9EFD91 -:10EEB00016A55B8C87B620AD142E5E5776979EDF25 -:10EEC000C7942D44B9B9A3F3A403E8EDB52F2F4F90 -:10EED000EF69E37E432A27037D1475525D957C69B3 -:10EEE000FDA7E9AD4BCDAF8D03BD1A495F18E7BD56 -:10EEF000FE4B4524741FAF76A90FC7403BF04D5120 -:10EF0000A2ED9C2E6532E06D4F9AE012051C375938 -:10EF100086755F387203DC7F2D6436C1BA0F5C18CA -:10EF200044601F3BA8DEB5D1716F92D4B51328BCE5 -:10EF3000035D5FEC07BE549D16CF6872F13A52D361 -:10EF400045942B5BC6DA4CC204D0776612180B7C52 -:10EF5000AE203C3BBE4C71C2754B9AC8EF0791DFA7 -:10EF6000C7A7BBF0B9572F64C443DB4482280F0204 -:10EF7000DDA6327F84FD8E87F750B9937DE143870C -:10EF80008B8EDFD75DEB00F9F25A179B3F7B45C8AC -:10EF90000170DAFFE52627DCDF919689F3EE1CB7D6 -:10EFA00014ED8B1DDD26A4EB1D63D73833B2709FA3 -:10EFB0001E80DD8EEEDAB5E940D75D666C4B4421EC -:10EFC00041A0B734A667B774D79223B4FFBC47F407 -:10EFD000039D6593F67D03E0FE90355692C2E06F87 -:10EFE0001E42C8ADEC6132D9A59703255D7A7D62DA -:10EFF0000D2D983503EC08A067DA9E668ED3F5EFE9 -:10F000007F7765FC4CC00B8537DC7BADFB8EFDE369 -:10F0100040FEF859FB0FC77F621D48AF4DE3D60C89 -:10F02000BF0DC66D71786C12F428E40BDACEED36A4 -:10F03000FBC1DEC876EAD7B1FF1B9508F72DDDCC02 -:10F04000BE3A9FC6F6B3C353471EA0CFBDCAEDAFAD -:10F05000C9274695C3FB0E50FB09EC8A573C2FC4C9 -:10F0600065823CF38A3A7AA3F0417A39DF49701E0F -:10F07000FA33601A8543011B42F9D0D77C3BEDDFA0 -:10F080009F6773ADA4A8DE7161D7EE3B683B374143 -:10F090002422DDC937FDFAF5E5FDD4A16BDFFAA91D -:10F0A000DE2EB11181EB7327CA81BEF867E259AB3E -:10F0B000EEB969669B6EDE5C12D68FF8B4F6F62761 -:10F0C0005FDA3ED9CAE59A669F6CB528F37D40D7D2 -:10F0D000C15997D0A32BB9FE6D4079B18D104F5B0C -:10F0E0003A95EBDF1065E0C3F3C7ED08C7DCC766F0 -:10F0F0004C24A8AF9589C00F488C61F680F7F8259D -:10F10000EC15974AE273F8AB085CCDA743747C2BEF -:10F1100055F35F810EE7FADC386F5F7AFF41C70075 -:10F1200094FB05A54C2F3CE638887ABEE37DAAE720 -:10F1300005F68E10C5FB6CF805F4FEFB561CFFCAE5 -:10F140007502CA11CD6EA824B285AA3832DDDB6DF6 -:10F15000FE01C59FCF5E3DEE567A7DE5DD8EE1C0B6 -:10F16000BFAF807D80F2A1C1C1EC8318358E2E71B6 -:10F170007B970DF970EB5913B183DFB0DD86744ACC -:10F18000F9F4FE71F43DDB83CC5EE838CBEDBDEDE8 -:10F190000EE4939D7F60EBE858E1607EC619AB0CEE -:10F1A000F6F8D6153108E731524CC00CF32D67F351 -:10F1B0007771BCBECDF1BA9FEBAB37B8BEFA0DD8B4 -:10F1C00013A8BF983DB11BEC097ADDC9ED891DA0DC -:10F1D000CFE8F5C5B3CFBF077C797E7B14DA9D639A -:10F1E00048DA6658D776A715D76984F33C45CF0728 -:10F1F00073ABF47643F958BDDD70FDA8E1BA7659DA -:10F2000062AAEEF9A9F1D7E8FA4B9D997A79649E42 -:10F21000A86BCB17F4764385F7063D3DC9617603AD -:10F22000CA3BBDDF383BDC6F4C063C313F676BD7D8 -:10F230001D88C7ADC753062A6176C2360EE7ADC733 -:10F2400099FEDC16FA22468960477CCAC77DC6F162 -:10F250007186E3E33F46C8BF4B1F0CFCF20593BF2A -:10F260007DD0B1F6BCF6DCA7FE5303C2F5FA4851D7 -:10F270004226D1DA7FE8786F0CF45F2E5F503A6D4A -:10F280000D513C7F478C696FA38FAC31373C056DC6 -:10F2900055359367B2101C6966ECBFDA03F2B839D2 -:10F2A000A6E139E8DFD264736D8A073EFAFEAFA0AB -:10F2B000BD9CB2828D5EFF1435C24F28AB39324CF3 -:10F2C00038FFB316DF700FE84DC137FF563A5EDDE9 -:10F2D00060F53C235DBC9ED80C4163F66DA087446D -:10F2E000CEF77F1194D80C7A5FFE8580723A4A225D -:10F2F000A8176CC41700FE21F5F27CE00F62A2FC97 -:10F3000043AF8D99CA50184F6422B9E83CC8DAF46B -:10F310007D4270DF9F05BA2E0B6950611E5B3D95E3 -:10F3200030949F1F4D5746E078F34C9CFFC569848D -:10F33000803CA3DBC176D6DDC4D5164B286B2BA64B -:10F340002F687B3EF5F7E1FD26C732D453EFFDCEA3 -:10F35000E41723D84B3D705E6639130A8B8F18E98A -:10F36000A783D3C5B6641FCA5FE3F3B900170AC702 -:10F37000AD1F4E1781BEB2EC0364B02BE806C51971 -:10F3800054BE6F3B79BDA326C273D767D5E4660C24 -:10F39000EE6D6705378B354EF4E745D8D716FA3B47 -:10F3A000ECEBE54E5300F07BDE694579D2D73EF2B7 -:10F3B00042FA38442ED80361FC46C80217F88B0283 -:10F3C0006917BEBA269CBEE4FBC3E9EBC58BE90B0B -:10F3D000E1FC9DB7D210AECD02A32F95D217F4ABAE -:10F3E000250D485FAA89F89AB390DEF0F9E566BB6F -:10F3F000CB4625E4B28C147C4F474CF97B0109DFE6 -:10F40000973A13FDB96AEECF55A39C7FE32893F397 -:10F41000C67DED3C3A677808EC89D17387039F7706 -:10F42000800218068BCA9B27EBDA248076E0140250 -:10F43000212B80C03CB03F3BAED3DA5ED62E66E3D4 -:10F440006F79FED10D2AB46FE2FDEA6CD6AFB549F3 -:10F45000FEBC62685B4CD83E09E3E9FB1EF3C8CBF7 -:10F46000006F8FA6CBB7025DE680D142AF9F4D9073 -:10F470006F87F6B20C82FBFDDE04F95B304E6B6FDA -:10F480001B2FDF19DEDED2E3A7B6733FF556B44B70 -:10F49000DFE89A89F6AC447C3780DE7923C8E251F4 -:10F4A0005B46F5EF071DE4F6FC01EEA7BE09F2E8A6 -:10F4B0002AD027CC4FDDCBFDD4DD5CAFECE47EEA77 -:10F4C0000EAE575EE57ED22BDC4F7A09FCD4ABC082 -:10F4D0000EA9E27112E6A7668D9E5C8A76844BF3D4 -:10F4E000534744F4532BBC7A7D33CDA3D73737A48D -:10F4F000C519F48B5EDF4C8DD7EB9B52E73506FDCB -:10F5000092A91B2F5FD0FBA945DD25BAF10567F451 -:10F510007E6AFE473375E39765488847EFF11B75B0 -:10F52000E3723A6B75E37AF1E6433C59D5279D6067 -:10F53000C76D1955C7F1C6EC050D6F1D97C0DB6F80 -:10F5400038DEF672BCEDE678DBC9F1B683DB03AFDB -:10F5500072BCBDC2ED819738DEB672BC6DE1F1853B -:10F56000831C6F0738DEDEE4FE6ED6E8DDE89F9D83 -:10F570003F4B38DE368A91F05696281AF0E030E09C -:10F58000418FB712F370031E520C78B85AD72E3839 -:10F590009361C043BEAEED3D5E6280FFF506BBA148 -:10F5A00052D7AFE16D9A67BE81BEEA74E32E9BDF4E -:10F5B0009CCCCEFB6BF96D1FB7E3F670BCED02BCC3 -:10F5C000619CC8C3E3115E1EF76576DCCB1C6FDB64 -:10F5D000785CA803F006F61DC75BF3A87368C79FA5 -:10F5E000BFA0E1ED6044BC5D29BF5DEBD6C785A639 -:10F5F000B8F471A1C9763DBF1513BD7D37E94B3D08 -:10F60000BF159ED5DB77133FD5F35B5E68A6AE4D85 -:10F61000ED8084CC6CD05337EA9ECB0ED6EAC6512F -:10F620003F89F92D1EAEF7FD95A88F5AA631FD48EA -:10F63000F910EDEF67BF4DED80F45E78BC68F09F88 -:10F640005EEC437F5F93C9F477C77BD508D76CD056 -:10F65000DF91F20B7C5C4EA60BAF363351A33370B7 -:10F66000997B86D1F5984731BBC71CB316820CF045 -:10F670001334E5F4DA49A2D347607E6A2FE5648645 -:10F68000E97DB3AB8180DD20DA1E5A00FB22A2C9DE -:10F69000837AD7601F917A977C07DCBF6380A78D40 -:10F6A000C2E296CC585C879B6CB6809DD198294F5E -:10F6B00002788A93193CB62451DF9DC2634B146BC8 -:10F6C000AB145ECFD0B6387001C2AF83C24B4C874B -:10F6D000F9E3C9DD745D55995606877984E953F5D8 -:10F6E00039A65F7BF421351868FBD968D6BEF18551 -:10F6F0009FCE53137BF56F5DE64BA84FC73887D578 -:10F7000091F174DEF5EA20B033C7D2F5817C34394B -:10F71000B62745B2BFFBB2C3568F97E7C17EBEC7BF -:10F72000F5EB180A117346DFCF3F1BEDBB05F09BCD -:10F7300005F0088B7BCDCC64766B15CC3318ED4B84 -:10F7400039DCBE24C14A6CB7A433FAFAF1DA99481D -:10F750006F4E0A2F3116D6CFE037FF2E465F57BACD -:10F760000F6DFDFDD0892FDC9E0EA393EF45A213F4 -:10F7700052EE71A3BFDE973DA7B2F53673FB51B3CE -:10F78000936D899ADDECC7F558287BE40FC22B995D -:10F7900042E13AC845305E53ED32F9FD14645160E0 -:10F7A000F083DC2915882B19669709C363B9142ED9 -:10F7B0007F8CF141EFF168837C1F64D0C3C374ED8B -:10F7C000A2EE14839F7875BF7ABED439D1A09F264C -:10F7D000EBC69725DE60F0632B0D7EAE5E4F9889F9 -:10F7E00059E5F83261DC421524730EDC27889FB09E -:10F7F0007EF43B7BE0FC845C85FCCAFD1A23BF36AB -:10F80000664A0867C1C5FC1A8D1FB4E735F859DD93 -:10F810000CAFEB7234FDE441BD630B7C93405C950F -:10F82000DAD0F2E6307ADBD4687FAF7434213F69F6 -:10F8300024EF9552E4F91B5D78DDD8E8C6EB138D13 -:10F84000125E1F6F4CC371EB1B3DD87EB4D18BD7BA -:10F85000471A65BCFF506319B6DB1B7DD85EDB58C9 -:10F8600085D7B64605EF8F322BAA9DEE6B542BF150 -:10F87000A8742BA3DBE9FBC2E096DA4AD71106F79E -:10F8800064D5A56B8F5CEED68D4F6A9074FDC3EB8B -:10F89000D374FD098A47D71E5AE5D58D1FEC9375A1 -:10F8A000EDB8B232DDF858D9A76BC778AA74E31D5A -:10F8B000698AAE7F5751FEC0503F7CFC506320C820 -:10F8C000E0120C3238BD1E64F0E9C2EBE75CFE0EBC -:10F8D0003207515E0CCA7251D2A1F8B2B3FC5A9CE5 -:10F8E000D923C486CD1F5746E74B0B5F2F9D4FE7AB -:10F8F0009FF9915E623C41DD7D475A97EEB929A29E -:10F90000B304F211870B448C7B1D2E888B01FBE521 -:10F910007E8B6B5A16A5C7434745CF26780E1E88A7 -:10F92000202F4F70BDE8186F47B950B14AD8242234 -:10F93000D1B2E76B3B5323C63D0FDD4BAA605F8E10 -:10F940005D2F494017150535715161FE5A45E0CFCD -:10F95000A56EB8BF2A3D278ACE56D19A6CAD1BDB67 -:10F96000BB2F6D5CED2ABD7DD94BF77E3BEC638CE4 -:10F970007AAF1DE45B5BE2266CB7A5F59F27F98C97 -:10F98000DB619F723BEC348FC37CC4EDB093DCEF42 -:10F9900009713BEC036E871DE7F6F3316E877571D5 -:10F9A000BFE76D6E3F7772FBF908B7C3DAD29E9F4F -:10F9B0008AF2F017021123F8A9DAF5969FEAEDB062 -:10F9C0006FFAF576D8D2F57A3B6C71BBDE0EAB6B75 -:10F9D000D5DB6135AADE0E5BB85C6F87DDD4A097FE -:10F9E00087F3EB27EBDAF3147D9C6D6E95DE7ED604 -:10F9F000F033DBA7978B95657AFBB9AFFDBE12B8E4 -:10FA00000EF33F80C453617AAF279F0B7A85D245AE -:10FA1000D605AA57300EEE6B86FCC9361842F56F34 -:10FA2000A129F816E47DC8DB2281B8D3AEF339E50D -:10FA30001511E82F47D5D3CD82E3FAF8C68D77E9C3 -:10FA4000E13A6399DE2FB196E9E12A27EAFD924A6D -:10FA5000A39EF1E9E1AA1285005D1AF58DC9B14CAA -:10FA600002F97DA57AC74AA85E616D9DDEB1C29D8F -:10FA7000145D3FEA9D1F64B17A831CBA0E30169A5A -:10FA8000A2720F7828DC76BD6BC63A11BAC023A3E8 -:10FA9000A8FE2982DF29FC5EB5286A03E4D9785ED6 -:10FAA00084886776DF4EC75B87B3BC08F9D2FC1148 -:10FAB000CCAFD07F80AF1C42DB617A2E3BC8FAC34B -:10FAC000D6ABEBF703CE06F7B71EF9C8A89CFFC963 -:10FAD000F5C4C49F06A137814CC07A83D0A0CB8ADD -:10FAE000AF1AEF6705981D9495C8EC206FD24C9122 -:10FAF000E79F08843CBC2662C778E608E27F06E2FE -:10FB00009CD1071CD369B319A64C003F49CFFFB362 -:10FB1000CAFBCFCF1BFDB0EBA45483DF768DC1AF02 -:10FB2000D3F3BF8D18EC971091C09E441C9874FDC0 -:10FB300008A777381D359D68990FFB7A2989E75703 -:10FB400038FD4CE4F82264F3EE1ADAEF758B04FC0E -:10FB50000D1B51E326407D51B04186BC43AED7E634 -:10FB600042BC892B3C68979E61F8F1D27F803F2F81 -:10FB700009C317E0EFB81E7F3643FFEF393D5DBC88 -:10FB80002E4647FFB87519E8CA39E8B2EA588CF72B -:10FB90008B83B21843D7B7D725601E756FB0215835 -:10FBA0004CDBE7DCAC6E684DE24C33AE97C803A685 -:10FBB000503C4CE5FBF5F2BC56472341BBE3C54640 -:10FBC0003B5E096910411EB5B8EF8803FDD831428C -:10FBD000190EF5691D836357417E7E8B25363152A0 -:10FBE0005DCB4E4B2EEAD38E9D0966893E5F6C76C7 -:10FBF00099E1B9E2C45A11FCBD6BBB08DA05C589AD -:10FC000004F3592F36060EB3F729588743F73119F5 -:10FC1000ECD35257CDE4987888CF52DB46023B377D -:10FC200016FDD73D836D88379B6B69E9B7E8FE0EFB -:10FC3000268844F052FC788827007A20D1E9F1C365 -:10FC4000746ECB4980733DFD0778D1F402E5F393E0 -:10FC5000E1F8C825616DCC2BE8DB23B3F5F891887A -:10FC60008275162D5DACBE8C8422E7593EE4768306 -:10FC700016DF3FCEED86633CEE7698DB0D2D86F8E1 -:10FC8000CD5BDC6ED8C3ED867DDC6E789DDB0D6FC1 -:10FC900072BBE100B71B7AFC05A236415E711EB152 -:10FCA00087C05F3858C3E0EC5E25F8CB201FAEB4A8 -:10FCB000FB4AE87DDB2A0BCACF91896A13C4C76D62 -:10FCC00055EA14D8877B417B135C9B8ADA12E0FEED -:10FCD0003CE5F471F0B3815EA6E5707EA7785867C5 -:10FCE00065705EBF38C6B312E85959528EE31219D7 -:10FCF000DCECF41FC03B61912A001DB8158B0EDEB1 -:10FD00003506F8CE837698FC88067AA4F09C9ECDC2 -:10FD1000EBCF32492683BB1A05708FAAE1704F8B57 -:10FD20008FC827EB39DC35B8EC2CBAD9A4D2A16F37 -:10FD300025B2BA89B70A6E361DA4EBEF9445CCBF45 -:10FD40007626F23A41FE5EE37CEF707B765D49FFFA -:10FD5000F1BA437C5C4FBB9548B68161F394DC6F8C -:10FD600091E8F35581FB92802FD60DD0F2C41EB4DA -:10FD7000AFA78805BF4DA6EB0CF23A484D5ECE21E9 -:10FD80001C3686F7BDC5F7D9D77ADE2AB9C122D18C -:10FD9000796705EE21F03E9BB9C11D5E5FDAC9D7D8 -:10FDA000B766C69D04F83238E26C3DFAF13E9B041A -:10FDB00076F7C844CF6AA00377A262F936BD3F9DAB -:10FDC000CA43C905CB6ADF190FE3E8338F13A09745 -:10FDD000AB37033DBC956447B9D3D77A2ED2237E87 -:10FDE00082F6485F7A84CA1FB4876CE59F1C07BF00 -:10FDF000B692347802F4B960966730F031A9B2A0B7 -:10FE00007E4EA3FFC2F36ADAB5D2A0BF1D5E4BBF20 -:10FE10007278E485C656F03BDE02FEC13C2889813B -:10FE2000FA9C60F99D76804F4552CA2EC00F29B6C4 -:10FE300087465338AC29587D13C06B4DF952970053 -:10FE40007455988AFDC162FB69A8C8E92A5E9324AB -:10FE500085C17BCD7DA448017827DDED5E42F79515 -:10FE600092F8C74685F24D9785F93DEF94FC3E31F7 -:10FE7000396C7C4676F1BF67435CC7CDE87C8C5516 -:10FE80004989541FACD179535134C6654ED6B07AE6 -:10FE9000057A7FF572FAA842F5559BA7978F1773DD -:10FEA0007A8A1ADD5D0FE395FB6C12FA67E282969F -:10FEB000E5B45D05F612D84F8F58902F357E4E6A07 -:10FEC000D0CB4DC5C0B75506BED6F8E9379AFCEC85 -:10FED000E5E318C06B540DE3276D7FC67DCDFB9223 -:10FEE000DA39718418FDBB7717A546333D1666DFF6 -:10FEF0004E40D92459E9FE66717A9AC5E98992E49F -:10FF00004E58CFA17B52A701BED426EA07C0DA56CD -:10FF1000587AEDDF14D82719E0A5FB9FB55C4C0794 -:10FF2000FF94DC65E9A5C714DDFBB05E604E781B6D -:10FF3000E85595DF013B02C299F0D23F9D38BCB72E -:10FF400099BEAF73581C69F2E07C1F31F928E17C3F -:10FF5000870AC4015EE8FFEEE87448E193707AA571 -:10FF6000F38754D65F7D4F6A069A9BBCFDE18AC138 -:10FF70005041467CE596DEF1F0BF5233E27FF60A4F -:10FF80006113C4FFC6889F9FDD4DC7CFAAB4799A7D -:10FF9000E9FCB31FACB580DD5FA92A7BEBE8B84A6A -:10FFA0004A177E17EE43C72747CCC402F31C9105BE -:10FFB000D24EDBB366E9F9A67A85BE6DB4478EC62C -:10FFC00028234CF4F94F041BD944AF3B372CDD08F0 -:10FFD000F37DFCA00DEB0A09BC2B07F400E1F1490D -:10FFE00079E33DB4BF76BD8D405E641EB7F7E37222 -:10FFF00092715E9363013E5FD316837EF1E90D43F8 -:020000022000DC -:10000000C703FE5B0735DC06F5D41FC72AD580D7AA -:10001000DA35D798203ED21ADD3E05C67F6222AE81 -:100020004DE9B42D3D6481F57451FB00E2ADDA3A3F -:100030006B5AC3F00FFBCA6171DCE926A26C8E60BB -:10004000D73C9A23703D4B545BD8FA37E448787F0D -:100050007ACAA09687E13D14FB2E0F870BEC7B0A32 -:100060008B8BB6267AAA07D3F6470271AD8C87AB85 -:10007000FC01F0A7FA031B7906D14F70BC75F8B0EC -:10008000A7DBC2FCFF4CFEDE53B1ACFFA43BDA0F92 -:10009000FB3C29B1B6EA76FA919ECD4ADA9C18B6B5 -:1000A0001F61089C8260EB3B1A235953101F447A4E -:1000B0009EAEABF691C710BF5B287C803FBB5C5205 -:1000C000CB4EBA8ED35459ABD0EF7E7C0AC0F3CE60 -:1000D0000C4AA80917C3A9316710AEE7F4FAE6186D -:1000E000AC337111C53AA4171E35ED5BBF238C47A5 -:1000F0003DAF32F9C1F84F2061F29DE2777ADE0F11 -:100100002DB5B0DF28D20E7831ED59658775CEABAD -:10011000B1607ECC497C65204F6B1E11B04D7FD6FF -:1001200082BEA8E5FCD52A0DDA07747C12EC71F4C6 -:10013000F79ED80BF501355C7E552DD2D3E962B719 -:1001400059C72F3396EBF987EE53D7DE98C3EA3AB7 -:10015000BBBC1FC7837E6EA5DB06B87CD222F837F6 -:10016000A17CF58D08AFAF1B9363D2E2F092250C12 -:10017000FEB594FE6A416FD8497B09D83579A3A7AB -:1001800002BD5B8F46E33A8DF0FD6787C3A924A9C2 -:100190007A305DCF294AC750FF73724333DA2FF0AC -:1001A00023EAF8DAD502F4BD84AEF27117D2A7754E -:1001B000C6B85E7AD1E053B33E791F8C73FF678C6B -:1001C000449D2752E3CE5F0AF6640F1D19E0037BBE -:1001D000366BEF49EDA533EC8F406765742CC38B0C -:1001E0008AFC5253DA93D71BD15FFD32E23B9FE288 -:1001F000B5237D3EE4A13439B7AEE84DA483732E18 -:10020000E217995FFB36C8FD18BE3695C881BA78EB -:10021000502654EFBAF01EFACB717CBFB1CB856388 -:10022000A599840C5A2E1E2BA537634B8301D0133E -:100230003637D7BBDB737F3566089C6E2018A7194D -:10024000105DEE09E06E5C09784EC1E24A00FBE702 -:100250004141A882B8FD00A2B7ABE20CF02059E6FC -:100260008FC2EDF2682EEF974E4915D0DF29D3FBF0 -:10027000A766835DF4AB1C93E65FE055825F291CA3 -:100280005BA8FF06726A50A0BD1DE8B39ADAAD7E86 -:10029000DCBF07F33AD652813C2EF4C6AFFE51F1D3 -:1002A0008B8BE2603C7ED1571C4C8B0754B25BD4E5 -:1002B000DF51DC90F7AB74533F6700D85937BBD19F -:1002C0006F729F46BBD4CAEDD2A8D18B5C2C7FC67F -:1002D000F8478B0718E9CA185732F29FD12EFDCF85 -:1002E0001C6E3F5D4DAEBE92F88016C75F93C6FC94 -:1002F0009E3569B52BA17EED3CF77B5CAA09F138F0 -:1003000067968078D4ECB539DEB3B380FFB4FA8356 -:100310004BF93D6D063F24DAFBB42C47D09F8E5C31 -:1003200046478E02D63FC74ECCF6B0FC813397E9E4 -:10033000DF39540FDAE916A7F3734415449F9F1A67 -:100340009ACBE4AC76A53FC18C1C5DBDE0D0DCB09F -:100350007CA88DE743EDBC5EB038BD7BF757705F7E -:100360006675C036B9E6C96F533844CF8AF19890A4 -:100370007E95677E087EF22C07CADBF83409EB5EB7 -:10038000AB12ED1EA47D557E1BFC32B43325D892F2 -:100390008CF2762EE5DF80AB1F7FC7DE7FDCCCA939 -:1003A000F93B058CAE7AE24B3E26BF4DF41FD0D30D -:1003B000EC2A3DBDCC55FAA79FDC5CFD39AE31A1DE -:1003C0000B3BBF42BA60FCBB6E04CB479F2FA763B9 -:1003D000207FDB873DAEF9B74E0BF58B285E82F2AE -:1003E0006EA4F7601AB184E3DB5720EAEA1B827936 -:1003F00024DA45FD9EA085243D48C70D90E75EEFB9 -:1004000002DFB7D81653837AC3AFB3EF0FD1794F5A -:1004100038FB5E8791CEEF1BBD04E3FF0F5C4741C5 -:1004200046D77F1F249CB15E6FCB7CF0DB1E8036ED -:10043000D6DFFDFBFC62684769ED6D3F92C3EA0DB4 -:10044000EEC90DFC482DA07E8D9DEA5B3A9F4322AC -:1004500098A7226433CA6711E281209FC786C1171B -:10046000FD063DBC8D76BC58C0E228A281EF8DEF21 -:10047000BD3D97F339C7535FFB363E477FAAAED6E3 -:10048000D3FF7772FBA997353EEF84FA89982BAF9B -:100490003BA08214F3D3223179C05F262504DF27E5 -:1004A000B8185D8184013D686918E041B8D17614BF -:1004B000E805BF438BABE2A2A300FF22E41303A82D -:1004C000CFE95242422A8CD7EA0F14F295E3F2E5C3 -:1004D0001E95C7388F54C6F2CBEFCA2404EF1BF326 -:1004E000F87A5F0EF8EB47A99E95408FDFAC42BCCF -:1004F000AC7B05C1FC80C3A5609BBE2AD4EC82B84E -:10050000156B575318815EB6B9F5F5AF3B8B1E2FAF -:10051000B6D2FE9652166F3DD418787715A5B596CB -:10052000827C9497AB6060D87A83BBA2AC10875171 -:10053000D46FD9C16EFE708568856B70658D0A9B1E -:100540007E3741DD2C4810775008F8F9D615CD5389 -:1005500080AFDEB5A89E414ECCAB629EB875A57A41 -:100560002BF83DB2545E964CF96853AB19CF199DE8 -:1005700028F97DA214C6879FE732BFE1E0CEA80725 -:10058000000E6B047B280AAE1665D37DF1F03EABFE -:10059000A7892EF1DDA68793E03D6B16AFF1EC82C3 -:1005A000FE261B9C40256B36D8AB60DE35494BDC04 -:1005B0004BC2E6B50FB736C0FDE0B016AC6B51CA02 -:1005C0003CD6A858D8D7E731909F6D5D911907B4F4 -:1005D000D892601D5107E396FCE9B7B98077C984CA -:1005E000795BABBBDD02FB1EE95654C88F9B72944E -:1005F0000340AFF3969F98827573A5B1ABE13AF2D1 -:10060000C2EDAD00FF77793C2694508BF9DA964520 -:100610007576586F4542CACAF0784C4BC162FB18D8 -:10062000FA5C8ADB54B374C0C5F4D102F19709B007 -:100630002EBA9F7130EE8F8D0A1D174AB256453A79 -:10064000A7F509D747F6E6A529101769D96087F4F9 -:100650000C691194F5901F50939D11EBD833BC0C8D -:10066000EED58A6B8A5542FC20BF7DBEF5D88FD46B -:1006700051605732FCD9CDC46E09D37F19D9C567F3 -:1006800072C3FCE88BDE9BD082FAA04560FC9BE144 -:10069000FDE247502FFC7CB6AF1BE0B7A655590FC3 -:1006A000F022AA9D0C28EA9B4F42F7911184CAE3DD -:1006B00096265B55A43AB4D022713AF009E5A0130E -:1006C000034684C9E5957529101F09355D85DCDD74 -:1006D000337E83FD03C04368435A2CE8C350526DF8 -:1006E0004A0AD02DA74BE3FC5BB81DF062A62FDAB7 -:1006F0000B76E55896F79C91EB73629BB4BBC1CE29 -:10070000FD1AD06D2AACF71F48B7A8E73ED9FA1FEB -:100710004857C47579F9481F0999319F5AF4178CC5 -:10072000F7B68DD3CE3FB1F8A066F7468DFE6815BB -:10073000F8ADBE3C2DDF55B017FCF5E95A3EB59C2F -:10074000C5075DF45FA4F8A0CF101F9C6E686BF620 -:10075000E60D5EBD7D9B28B5FB4A40EE1E103DE0D8 -:100760004F2411A65766940B7EB0B39B8AA2EDB8B6 -:10077000EE3C1EE7E4FED73CBEEE638D7602F92424 -:1007800093A36035AC7F7A3E5BBFA33E3D3B2081A7 -:100790007C67716E526F93306E02C84F203D7E9A17 -:1007A0000F26A1FB9957BF14EDFD5EF835B1F81087 -:1007B000D1FB133E62F01F16317B4CF3B7E61BEC06 -:1007C00003A3BD6F8C53F7E60536DB819EBAC7667F -:1007D0001C4A91B05B0D68F9003A6EA1B773752899 -:1007E0004CFE7472FD70A4513EB68AEE7FB5EFC721 -:1007F00076A0D336B3DF0EFAA4ADECCE18A0BFB608 -:10080000056219F07DB0B10CC71D6CF4E1759597C8 -:10081000C9BB60B6BCC21B1677AE2C2B3EB62ABC39 -:10082000EE41BEEED8AAB0F5577867E8DA1A9D55C2 -:1008300088A4617304F9F2BC97D9ED66AAF7B1CE2A -:1008400050FC85A7BFFA1BEAAF7687C3EF41AFDE46 -:100850009EBD7F6CC9C0FEEC166D7F1A5CB47D6BCB -:10086000FD7DADF37B7FE33A9FF5EAEDB94BADD368 -:10087000B83E6DDD7D8DAF0061350CD659BA00EA0A -:100880006283D94A07C8A3CA526135E44B8FF07816 -:10089000E29182183CE7BE378DF97BD1F58C6FA2CF -:1008A0004B6760DEEF4AF17BA397D995B30A04BF8B -:1008B0004C7F9DCACFDB1F4B63F9DCA6A29FFF16BE -:1008C000F2D0EF145A58BC97C8D3A785E5B1D659D2 -:1008D000FD01C8271DEBA9D358B6FA6EDA8ED6E40F -:1008E0004A953EEF306B963E7F5861C833441BE417 -:1008F000CA518D3E7228DC537BE1DE973FD1177DD4 -:1009000010F3D92CD04346F8DC66808FD17FA9D86C -:100910006EE087CBF46336B566ED85BC9A4AEDC9C7 -:10092000D1803FE8A2CF45CBBFC634C8803C468FBC -:10093000634267D6825EECA42A00F4CBBA9977AE04 -:1009400087F679AAF7012F7DBD47F3DF9ECF96BFCB -:10095000F446A81FE89123601F4C80BC6064FBA094 -:1009600073D1E46911ED83997529D9B0AE197AFB79 -:10097000A07343D99399701FEC03FAD39957A7B387 -:100980000F4859E625E0C3E46ED4E8AC88757AB325 -:10099000B395C17961FB71A43590F07AC6EE1C79EC -:1009A00008F4CFE07104ED7DD4FEDA638950BFA86E -:1009B000BD2FD7CBEAF049591CD30FFC7A293C6AEA -:1009C00075D4F75B64FCDE8B16F7D2C665E731FBA6 -:1009D000B03545AE877EE2CCB8C4BC4D5A9C232DC1 -:1009E0007D08AF1B96488F3FF41741C2FE08FE1EDC -:1009F00081BC6474E2D93D2E3AE433AF929F970DE7 -:100A0000E728FC2AE4436CE502DA4BB6448276CD53 -:100A1000E5FA57973BAE158A03C0DFAA65F1F2E20B -:100A20007433B6A3157113C8854917060A20377C9D -:100A30008AF834AC375AFEFCD31F83BEA67A1FE275 -:100A4000303ED280E7AC9D161FC627DACAE9CCE952 -:100A50001087596949C1787AF2AF63DCF0367F2B91 -:100A6000C4CB6D1E761EAACAABAE86EF6654148E3A -:100A70001608ED9FEE63F19B3910BF8179679DDD0C -:100A800009F19FD95E26BFC06F03BD39B7EE3BE3C6 -:100A90001E95FE9AB88DBF352E0BE34912C60B0C7E -:100AA000F1215BC1548C0F69752ABE0211CF779377 -:100AB00044277E87C218DF31C6738CF11E637CE742 -:100AC000EE3C5627ACD953DFCED3DB532BE00CC220 -:100AD00060B097A8A8A47CDD662149ED943E0F156F -:100AE0007F42EEA2EB70FED00435E0749C21CE78FC -:100AF00099722B48E5CA29D8C8EE372CE0DF2E9032 -:100B00006B30BE67A4FBC7B8FCBA2FCFA9ABEB080C -:100B1000362EE7CF47A980E705A3ACFEA8E4DE792F -:100B20002E973F9ECA911FCE637EC50F81CE894707 -:100B3000C1F30433725D3ABA250D83C9A9B0F88DAB -:100B4000F1BDDA7AB4F9AF741D0F71785F2E9FACE6 -:100B50002BCAB75BE9FBCF511C8BA82FA9411D16EF -:100B60009FD6E2E7DA73D59037C8043B52C0FC81C8 -:100B7000763F2C8E6D06BA8D4E54E448DF9B7A3B4F -:100B8000AF276E8A794CED3D4450502ED4F17C8DC8 -:100B9000369F99B89B900F80B6B5758911E2E6C46F -:100BA00063B75192A95D2B1288FF3889DC0EF1677B -:100BB0006BAB05DB44ADDA0776FA22CE17D682A9F5 -:100BC000FB20AEA6F185316F631513A7C2B475ED96 -:100BD000FAFC95313F65B4A7B5F8BA99BE04D6754D -:100BE0000EF0C1F6EB172F6FBF4FE37EBEA6FBD50D -:100BF000E8AA3CF31637D49FB44429EB6BE8BAD487 -:100C000027ED18AF70C0DA002601FA0FE4E493DE96 -:100C10001FE379F67CF65D9A1681D5A3EC49F8635B -:100C20007CF8F905533EA39B9FE549388EEACF0037 -:100C30009C972263E3912FB4FA934309CC0EAC281E -:100C40005C1CB893B6FF8DD74B5E53F88C96EF1FA4 -:100C5000509C43B0F403E0B2CECAEAD20E7DC38CFE -:100C6000F564443CB0EBCEF8DEBADD6B36EBFDCA82 -:100C70001BD2F4F6A0D1FEB31ADA43F38D75648A61 -:100C80001DEBC812781D195FBF914F7EDAC8F21AAA -:100C90003FE775FFBFE0E72F7FC9EBF736F3F39728 -:100CA000CFF373B31ADCEFB728188F3E711DB5E987 -:100CB000627BE380EB8ABEEBC6F3FBF9CCCF9A22D2 -:100CC0003A77819EEA3D67D1FF77C22ACBF479B3A8 -:100CD000D93E7DDE6C6E953E6FF6FF32E5ECFC6C26 -:100CE000388751BF12BE5330639588F9CA752DE716 -:100CF00050CF9E2F406BFBA2F71CE6E730B4731C6D -:100D0000DAFD6BF3D9F7911CBB122C508F3F635562 -:100D1000EC54889F1357C665D96F15107387FCCFA5 -:100D20004A9705BE0731239080F1D09AD62B9BE7D6 -:100D3000BED143304EDD13E757C7DE04F2F9B016DB -:100D4000E727D7DC0471FEC33CCE5FF3F2B827C1BE -:100D50003FFA599E3C17E0D1942757C1B586AF871B -:100D6000B66FCC1FDCDBA63FAFC7EABF3F5193DFB6 -:100D70004F3C5D9C2C3444AA17B939BF27CEB5141B -:100D8000E627F69E38D737613E626FC77376F7E67F -:100D900033F9D47C8CD4C33CCD2F93FAE723D8DD30 -:100DA00077E50BDA7CDFC2E7DD9A7EF3DDC9E6D7B3 -:100DB000CF27DA624780DF7F82D79719E7BB37DF1B -:100DC0008AE3E87CDFC3F9127BD6776FF8FA7ACF33 -:100DD000CFB86280691DD58AA98BD2136911B1EE93 -:100DE000C4D1E19A067549646A2AD6B11C2EADFCBD -:100DF000A7384F73B8F4857FC9F334DBF2932FEB38 -:100E00003C8D63265122C535029C2E7715640E0C4D -:100E1000F58327EBF2FD41B0337ADA668540DECF09 -:100E2000BAFC20DEBF3FCA551DD1BEE0F2ADA574AD -:100E3000910F52426B92A68AE1F6CBD92CE5CDFCFC -:100E400008E713CF8DEADE0DAA6966A96016E2D124 -:100E5000DEF608547E66AD9821BA2542BC0D0F4ED1 -:100E60001E4AFB672552FF2E6CDFF9F5BFDE4DD918 -:100E70009514941E6E8EA7E376E4286F03FD16B9D1 -:100E8000A53DD09EE54BC7BAF7FB6309DA79274643 -:100E90005BFD9B922F5EF7EF7AE5F24AF315C8E50A -:100EA00096467DFE7B4DD29895B0FE3125240412E6 -:100EB00036C57DB618F27F19D9CAEF605D296E225A -:100EC000DBC6E37D9984E56F8CF30E98C8F0342679 -:100ED00094F80388271FD2FCFDA22BF6F7FF180E0B -:100EE0006FE3F584E6EFAF8EECEF9F581417391FD0 -:100EF000D052570BF98013ABF5FEFE890DEE6A3820 -:100F0000E77782FBFB27A6507F7F6CDFF9006D9FA0 -:100F1000540E3927EAF201DC6EE771EDD9D9F2C03F -:100F200089D9E8CFBBE0DA9829C7E278D575139E56 -:100F3000472691CFC992275C32F839DAB9F65CAF0F -:100F4000320C9ED7CECB8E01D13608F2A2AEDB2278 -:100F5000D1F368BEBEBF3E4FDA93C734E139EACB66 -:100F60008CD35FEE38C9BB99D5E398599D61544243 -:100F7000891BF253E7C7DA51BFB7C2FFC2F46A6AEE -:100F8000BE3271E2E0F0790CDF57952EEFBD5A9D2D -:100F90003EE82BD02F9D849481BC7920B601E31EBE -:100FA000D771B819AFE513395E892B1EE0999AEF16 -:100FB000BB01F0415EDC2CE17760F9FDBEEAFB8D00 -:100FC000EB78D6EA7B1FCFD7978812ABCB23C81715 -:100FD00057A5B9504F6BF6D7D2894C6EDA48689452 -:100FE00095EEB359DEEDCCA4E33E7CC29C0E8F3D62 -:100FF00017432CB06E5F1A9573741F256E65647F5E -:10100000F211BE4864F2C2352098DC788D635755E2 -:1010100080FB17F1E313DD83C11E7FEE49969FBA73 -:10102000EAC945F6DAB0F99F98C8E566225B7FB554 -:101030002CF8A56458CF59CC43CD904C1E9940DE76 -:10104000F8FCD1B91027A4F6DB686C9FC376503248 -:1010500065425EFB43F7174761FC55F72E1E82F48D -:10106000CFE1B17045E6B368E7E728DF05FC070B81 -:10107000CEC5A48E453B7E3DD0FF4281F822D909E2 -:101080000F71BC5D2F37DC087476BD6C23706E2D3C -:10109000586C43B83F572848E0B75600CD433CE76B -:1010A0000933C69B293C9641FF018F03BF1B5D227C -:1010B000FFDA0CED3F8E13C8D07EF4F115C3B5E016 -:1010C000DC60E0C70F81FE22AC7F295FBFC64F14F2 -:1010D000EE25B82E99D58BF44557DD79F2934097DC -:1010E000AD294A3D7E17D135F3B2BE8B58F1533F3F -:1010F000D6EED97ED2308C44A8FF3AC4F9C478FF2A -:101100009713997D770BE78FAB9EEC3E701DF0F542 -:101110000A8B0BF0FAB33CDF66584F8FDFF57796FA -:101120002353C40588BF60395D3B7EC781C4407BC3 -:10113000FA2833E24F2DE1DFF9B89BB89A63F12921 -:101140006CDB5708C8670E677B1518CDE6BC86A315 -:10115000B3E1B96211CFF5879D73E9B78E2CC4CF87 -:101160009FB5C0F9336ACB075789DA77B7884065EE -:101170005BB0D4CCEDFBCF9E94E9AFCFF2FACC9329 -:10118000AF5A36421DCB51136BBFFDAA65C44AFA54 -:101190009ED008B68EB607054F9304D7A7D743FE57 -:1011A000B26EB9E029A3EDEAC03D5D10E25AF288C3 -:1011B0008D80ABF0F10F974E85FD9C7313FCBEEC58 -:1011C000DC04C6374A90F84DC9BDFEED0749C4AFEF -:1011D000E54BE11C9D97EB9987E01C1B5DF7B5EA99 -:1011E000B7D4EF40DE94FABD10571BE461F9CCE8A8 -:1011F000A0D9E327E0EFB2FAC8961F08E421984788 -:101200005CDB0CFEB98DD7EB46CB35E83F0EA2F484 -:101210002981060D9975E7D8EA8882F41B5746396B -:10122000231DAE7AFF38EB12E7D9E6DE343816F824 -:10123000E52F13F5E732FA8AAF6B57F8DE0DE0A71A -:1012400083E757B751BB1DF6FB32B5DBE1BA9DDA38 -:10125000ED701FBE530D5738CF06D75DD46E872B68 -:101260009C67832B9C67832B9C6783E7E03C1B5C1C -:10127000E13C1B9E3F2C540303013EC5D104F243C5 -:101280002D1646676A9215FD8D4021C1FC7D30C93F -:10129000BA6925C4EB0486273596F50763949BB19C -:1012A0009D3C96E577CD9E11708E7095305602FB71 -:1012B000A9D5AA60FDF289956602F5CBA169C2FBAA -:1012C00090772182C92352FB66C757B721FC17CB01 -:1012D000C40475E92BE1BBA1208F3F259B587C2ED0 -:1012E00028C2F7E59A6308A7C73ABF4C65F669417B -:1012F0006B1F52C09F9D043101A4DF030AF42F5ECF -:101300002EF076D02F8F82BA06DEAF1E7A0AFCD777 -:10131000558676A7497B3EE52998EF68CFFB465472 -:10132000CB40EF295A7FE242689F8AD29EFF7C2100 -:101330009EE7D2D6A37E8AF38592B4F1A9D5D01FB9 -:10134000EAA9935B82EB0D0D66E3FF6D57E7D3E0EF -:101350002FFFBDE76B56548CE3ABB3087926F662DA -:10136000FAFA7892A88F87CA822E1EAAC5DF4D8E00 -:101370000543F1FCD90336948BA79208FA217DC569 -:1013800045C3E2F51817FDD524AD9ED910FF240AF8 -:101390008179AB201EE8C1B72AE1E7D388D040A00D -:1013A0004EDD772646023BD29A1816BFE332A0BF25 -:1013B000786173038B0F06150B51937BEBFAAD0528 -:1013C000BCAE9FC70BB53A066BC1A3BABC81315EF8 -:1013D00048C465988FF62DD2C7032B942B8B172EFC -:1013E0002001CB50A07F59F080FFBEC0A57C300407 -:1013F000EDFDABD9F719A5D7316EAA9D1B833BF044 -:10140000DDA92ABEE7B65B4FBC3F848EF3AF8C925A -:10141000E030FEFC65C5F87C1EDD21C4B76A0AF128 -:10142000F02DC9FED4F3BA04F2D46DF23033CD7787 -:101430006F02D80B8B62316F72D35DE91FC03C8B9A -:1014400055073E47ED4A4EEF2F6D047A1221701971 -:10145000D6CE1AA1D15BD546E0AF49715A3BE629F9 -:10146000E08762ABF6BC17DBF3148DFFAE790AF4AC -:10147000C7D1128DBE0F54C3F3B3537BE643FA9E1C -:10148000E4D0DAD317427F6BCF7C4B36C27CEFC0FF -:10149000978DB03DF529E0E7E2195C5FA91F6D84E7 -:1014A000F95B1668F34FF0C3771EE79BB4E7A3FC24 -:1014B000B07E85686D2ACF68FB3DCEFFC70A5EA867 -:1014C000067EB9B1A7FF05DCEF02DE3E5E50F714E1 -:1014D000F4FFCBEFEF7FF87DC6F64D2438656856F4 -:1014E0002F5F18E5D56F8B981CF1D6FF1AC8952C85 -:1014F00068781ABFEF06F10096CF4A98E503796144 -:10150000173D943388CFEDC238A7719E9B0B595C71 -:10151000FD4C813E2FD662C88BF9787EAAAF798EBA -:1015200014B1795A4B22FBB119D9257F2A80FA01CF -:10153000725684F95C1460F07DB2964CE5FFC37D71 -:10154000CABAF8DD4D2AB23C709FFAC52AD899D3A1 -:101550002938210FDB54F438C6E9437916DDF7400A -:10156000B43CE73AAB8CF2F1635ED731BF449E7274 -:101570000FF0FF30916CC23A0F27E61BCCC3AD4F82 -:10158000A35CE7794FED7B1CD32F712EC2782EA57B -:101590009BC3FF5C419B05E4B34AD429A55928AFFE -:1015A00083506F6C72ACC53CB0ADC88279042DFF1E -:1015B000ACF0EF7F6B79DF49170632FD9EA6C5754B -:1015C000FBCFFF2ACB77FAD03E68178949B8381F7E -:1015D000BCD8A726413DCBF4D2183C2F5055FB0672 -:1015E000CE7F7804C1EF0447CF6AC0F341666A1F1B -:1015F000CA00179E2FD6EA63465EB81DCF8DD66906 -:10160000F5E662F941B0536D8F513F0BD997C14553 -:10161000CB17CF30C8FBC50595A86709B5E347C709 -:10162000C27BFA3FF7FCF0A458A49B8FDA593D7FA8 -:101630006121CF97F03CF0FD1616E76B4DD1D3D565 -:10164000CF27317F65FD244677BB8A7E5E85F633E2 -:101650003179202F469E60DF8583180B9EB7327E3E -:101660008F396D0EDA754F8CA45BA4B6B679F97B11 -:10167000185714D6B3E73E1D4F1AC06F319B599BC4 -:101680005E54C8FFE77A9599855097B5FC031CDF37 -:10169000ACB27AEFBEE237D5859ABE67F19BF9EE20 -:1016A0007D5D70AEEC6F8EE318CEBDFA24565FD22E -:1016B000562069F946FC2E21255C0BD88BA9F9BE72 -:1016C000FA428C6F6D96601D9ABCD957741BCA275D -:1016D0002247CE4B6B7CDF62C84BFBDCECF923AFBF -:1016E000DD530D7F17A2AF3CC4B3C53D7983E5F848 -:1016F000FE782D6F20DF03ED5E3D4A37E4D5E9D15A -:1017000085F5FF0BF4688FDDAE76A11DFB755B3FA1 -:10171000A5AB1710AF652C7EF6755BBF3C517E13F1 -:10172000F8F9BFFB3DE9137D5D00A7FB04B9CAC909 -:10173000927B1E419FE7FBA0B09F3CDFA5E20FFF1D -:10174000176FE83FDE602FD2E7E1FF59E20D0E3858 -:10175000433518F928B108F8A880F1D1BFBADCA345 -:10176000FBCD2F827CBAB0D91F9DFAF7F7F753F360 -:1017700095B222D4838A6917A59FFB8AEDCC9E0976 -:1017800030F8F6C633E8FABDBA78C653F5FF0DF166 -:101790000CBADF2AC46F297FFFD71F7F77207C65B3 -:1017A000664FFC0BD2E703B8BFCD6C7FFF80F76FAD -:1017B000447AF905A3975EF8303B290C3E0BEBFF0A -:1017C00031F0791EE1B38DADEF6B80CFD7119E1E46 -:1017D000B6DE4BF9D7270A044D2E1FC27D66313A7B -:1017E00038C5ED6BEA774F1E2AF5FADD4FE5C86F75 -:1017F00015313BF76891AEFE537E1BEEF7E3171FE2 -:1018000083FE087E7108EE7FDDFCE2D8429647EC4D -:10181000CDBBF8D9776F49D5F5DFA0EFF980C21BB2 -:10182000E26D6DCB45B42FCE2712FC1E80666F840F -:101830006259FDDEC5E7C14A099C47B4E5B1EF8CAA -:1018400068DF07308B0B0606A48BE17A7080628517 -:101850003AAF25727A0B9C6F9DBCF6733C77659509 -:101860006DF8773547BA3D96BBC08FA67EEEB510B2 -:101870004FAD77E1393AED5C9976FE634960DE3E23 -:101880003867DB46E92181BEA7A2D472327CFF46CD -:101890007BC36C681BFFAE69C2247DDE83C21FED73 -:1018A0009FF3EB597D5C9B99EC82FA8F3A55F437A4 -:1018B000D1F6336B05FC1EE7220A27F0F727B7277E -:1018C000633DB935917DEF4CFBBBA7940EDAF3C0B5 -:1018D000FE3B2A12FC3B76FC3C99F69DEFA869671B -:1018E000F17B5BA7E8FEE1FB3DDA772666703AD133 -:1018F000E019D5148770394FE142002EFCBCCDF4BD -:10190000E52C1FDCB2607110C8BBBAE0F35591EA58 -:1019100052E6B8F5DF4B37C6338CDF1B3713DF4099 -:101920003857575150AC82BD6AE3F59AD144C6EF9F -:101930005A9C5AFB63F65D8B528BEE3B22C6F746F0 -:101940001BE8D466883B18E9D4889772035E9E3101 -:10195000B3EF0CB6748A1E95DE6E7964512B9CCB66 -:10196000571F31B1BA7922E3779F5AA8C58BE7CFC9 -:10197000E962215E3F97C353C30B210D16E0B70503 -:10198000DA397453C36A384F3A8F9F43BF916CC69C -:10199000730637810541DFBB1042E4227C5746B213 -:1019A00032E7C045601D7555EC3B1926D803E409A4 -:1019B0001E3121BFB6B877E1DFFD0A0CB3C49E4EDD -:1019C00063FE44247BB627AE4021713A2C8EFF7F04 -:1019D000F1ABBF2D7E35B17010AB9B880AB8F29287 -:1019E000D9F726A09E6962A1C4CE2758941178DE4B -:1019F00061C3272AD08176DE81FEAC18A2FF6EC2B9 -:101A0000C649FDF87F258584D54727879240AE7D5E -:101A1000D0475DE5E1E29EBACAE72661FE9DDABFE6 -:101A20005920F798FD3B23D7F7B3496817B373CE16 -:101A30005A1CE933AFF24B185F087F3F270BCFE703 -:101A4000F8E1FC4E8553D82B48BDEF27C63AF6FF88 -:101A5000A579AB7BB8DF168C22F81DA46032A97A79 -:101A60003E023E9E29617644303D32BEB47E6A67B6 -:101A70001C9FC4FDA1018C28CE58F5F18193809F55 -:101A80003EFF0E1DC7E3E829F2478877DE7E385710 -:101A90002132D4F72ABEF701AFA7555102BD420249 -:101AA0000A7ECF6FFAF74557A4BFA7F8CF7EFD2F68 -:101AB000E87FAE8400800000000000001F8B08005B -:101AC00000000000000BED7D0D7854D5B5E83E73A5 -:101AD000CEFC24998409061C24E849001B6DC0E152 -:101AE000279000813393842490C0F0A741221E08E0 -:101AF000D0DC5EB44111634B9B0381102222BE8B6C -:101B0000AFBCFEE824185AEFB37DD4CB6745D48E22 -:101B1000012D5AD4E0851A2BA54110B1CF7E8F5EDE -:101B2000E5B5CFE7FB7C6BAD7DF6CC39930920C6DC -:101B30005EFADD3B7E7E877DF6DFDA6BAFFFBDF6BA -:101B4000492D8B3AAFCD628C6952A0131EB53EFD74 -:101B5000E4502CB39B59E74478A88723F224C65657 -:101B6000B2D84F7540B986FEC558DB5DA77E3F14DD -:101B7000DA4536A6A86C3A634B5607A97F11F332B3 -:101B8000199E6DD372181BC258C1B9C06115CABA6B -:101B9000DF11906898F0778741BFF08A4CB50DC689 -:101BA00059560CAF0A183BE984E714F8DF98B64C95 -:101BB000CB87FE58BE8E3A680CCA4B065BCAD9D09A -:101BC000F4186F5FA8FD35628C82F199D9DF6CFF44 -:101BD000AEC4DB9F0F66470C2F63B79BF550D6B1A1 -:101BE0002CFA33969E1354A07FBD24CAED9A629DB1 -:101BF000EFDA766D1A63679CF6F16BCDF16669AE2C -:101C0000761C2F1C9BDFD5AE41F97402FC77305E49 -:101C1000BE557350FB95B1F60E5AEF594994C7EA79 -:101C2000583EEE12FDF39769B0DEED39BC3E1C1A4A -:101C30001B31B2AF3E78BEEAF1BF303CD354A2AB09 -:101C4000C2FA5F945C0BFFAC6D6897752FD259F8A0 -:101C5000F70CE8D17844523BA14F21DB2B3399C0DC -:101C600076C94097533489B5C15CEB4212F50F7BBE -:101C70001D7C1EA328A2019D2D992EE8745904E70E -:101C8000ED8FEEFEF4D29AC70CEB3A8D354B6D70AA -:101C90001B636D702FEA82F6505E72F73FF811CE2B -:101CA00025B9627D2511A4BF964CD1EFC38BCE7BA5 -:101CB000EAA56AA2F725B179E653FB25A962BCDB48 -:101CC000A91CC7E79D767C1A372EC3F9045CA1D006 -:101CD0009D84CFB02FB219F93DEC670103F0797BF9 -:101CE000FD0659CFB7F09151A5121FF963E5889D04 -:101CF0008F0A888F061AAE9153C23FD440CEB0BC33 -:101D0000BD6A78CC57B16E9093B86E43A2750B3A0A -:101D1000AAF559E8DD03EB564539B0ACDE3B10F3CC -:101D20007697D1BC1F01BE599C9F98919BC03F974D -:101D3000375EB377B90BE15EA5495A04DA7F8EBFEF -:101D400019F1E7E9699CDE019F2F6BF0648580CF74 -:101D5000747CCF488EEF9B107E95F0ACEA8E2E807F -:101D6000CBA579581BE060DEE4F06FA83DDBE147CE -:101D7000FC0300D4BEE5285390CF80B7028EA95053 -:101D800076B29ABD49E6FD69C841F3363356B117BC -:101D9000E09BB8D1B72AEC8DD7E79671B8547CC2D6 -:101DA000B8C7D37BEF1802F3F732E6DB08E3371B43 -:101DB000C0BCF07CBF5E8A48B0E6F7B3C3738AA0AC -:101DC000DC9DE3086C84E9BB1F708F580BED7B72C0 -:101DD000BC0184AE277347BA0FC67F3F209BF8BA79 -:101DE000E73DE4EBE3E9317E3250BF749BF83DA759 -:101DF000853A908FDF5179F967A56BDF43FE6279F1 -:101E0000CCC786021EB007F0AA236D9AC70DF3BA9D -:101E1000668238C1BE3EA6BBA0DE8DF5B0C4798F08 -:101E2000EE7E74018E61D4BC32CAA2475D4C317A19 -:101E30003D34AFF2395790CC39293EAE6B67F3CBC6 -:101E4000CDA88FFD320B216FF9797B3FEBDDF0B927 -:101E500003C787721E43127CE97358BF6496F1F77B -:101E6000392CD1CBC2153908571E0BA0BE9DA73BFC -:101E7000CFC4EAF9639B32C98413E191D75714C1E7 -:101E800033B5DEDE6E761E943DF1F2AC9D7521C455 -:101E9000FB2C0DBA8D63ECC8CEBA681DC079A4D0F6 -:101EA000ED9300D3AE6CC5D67E36DBBB09F10E7662 -:101EB000C52119F0B2D49CAFD937EFF70CFAADCAEF -:101EC0008312ACFFF87782E90559C86F72C061B61A -:101ED00071087C306AE77470391D90A07DF37362DD -:101EE000DFB40EE403394DB295832E513FA903F9B7 -:101EF000E2784CAE8E598EE5452305DF0CED403D72 -:101F000039234D94072D47BEED559CA63CBBBE031F -:101F1000E559AB18CFD8457CFD3613F5691D484708 -:101F2000E198FC9BDB8EE55B7D263CC60F491E36A7 -:101F30006B5C9F4C7DE9D55EE30ADA037F16059161 -:101F40000FC35CDE25D64F391669CE30EDBAD16AA3 -:101F50005F7EDB1694898FC2DA9F65DCBFD206C034 -:101F600019EC5F498D74AC00E953612390EF5B9AE3 -:101F700080F74743F9608A4B4D47B9EE9BA925E1AD -:101F8000DF57830E1AAF2AE8CD3AFB75683F814DC3 -:101F900040BA6B696A14FD0DDC5F7D942B9292D37D -:101FA000FF38A74AB81CE8967C0BB97E9619EAE779 -:101FB000E02323BD452CDEEEC5122E0F5A26688B7A -:101FC00083F09C03E297C11E6E98FE837008E63989 -:101FD00053E40CB889CFB4B790CFE69B34F4B04B40 -:101FE000630FA0DC2872FB36A2EC96F39D8D505651 -:101FF0008603BF62B982D3B70EFF7D9E8BE32A7141 -:10200000FA0738E635DAF9416116FA86FAD5C1746D -:10201000BEFE9BD9CDB8FE079DBEA528C75A737DCD -:10202000775BE5D9FE122EC79E36D7DB35FD9F6B59 -:10203000103F1F334700E5C79ED430C9B353198CF6 -:1020400075A0CED798EA1B8A7CCDD721E5DDCAB032 -:10205000FD8F6E80250C03381ADFED2E9D00EF7783 -:10206000F17EE7C6B20686EF155E8687618CC37681 -:1020700027A9DDD6602ECDCF1E0B783C48FBD01CA7 -:10208000F7DBCBF63AF1E9487B7E849E647FC4930C -:10209000AD767E14C303F21268425CB7C474C7E71E -:1020A000B87E53FE039D6E273AADE17A64CAB9F358 -:1020B000367A2B0DAAD42E91EEA0DFA3D46FA1E81F -:1020C000C79CBAC55EDF168C443628A48F7E48EDC7 -:1020D000BCA08FB26CFAE8C7F43E411F4DAAD41ED3 -:1020E0000F16C4CBD07F3795FBF6EF0C26D167D007 -:1020F000FEA734AE47277CCD9BAC3D89E589D70B45 -:1021000079020D0B417E5C23CAE977D64FB3CA9F93 -:10211000C2C751DE2CD625B3FEEB8F237F1F0F09DC -:1021200079736429CA93983C62358FDBE4119B7301 -:1021300027D6C7E40F5BF5188E17933F6CE6E328AC -:102140003F82F3845E3BF3188EDF522BC6BF25120D -:1021500044BBC421FAA744900F7526CA763BF27798 -:10216000D3FE65A9D56F62EC5F1ED32C7EC689694C -:10217000758F931E3486B0D3820F72FBF2BB90032F -:10218000827E847D78EAE093BA01ED5654686F59F7 -:10219000F7256667F672BB276E5F9EE7F6F7C0DB32 -:1021A0008FA769FE7C4E6F5FC1F8FFCB3ABEB0A728 -:1021B000E0FDBF59DF5F6DFE1CC0E70A21BD4FE4A3 -:1021C000F05D41FF8C10AE2FC0F5D4DF00DE6C9ABD -:1021D000CFF403AE427C064243AE6AF84A09BE2AF7 -:1021E000BEDF2F6A313A2D4F4E07974DFF73695F5F -:1021F0004AF9BA2DE3CEA7F755822FD4A4FE3AB4FC -:10220000BBCDDE2ED6FF7682CB1CF722FDEFB4B716 -:102210008BF55F6EA5CF01E0F3D5D6FDFD0AE4484E -:10222000238D3F8A8FBF328EC7EF58DFFF67DCEC0C -:102230009274DE4EFBDEC0E9E932ECED9F60FBAD4F -:10224000D25E3D83E24486C0FB3F23DEE17DAF0BDF -:10225000DEBF65EEC79345E19FE17B2CFAC75BFCCF -:10226000136309AD2FEE9FC040F9567DAFB75BF504 -:10227000FDA1505D3BC22B97F0F6FBBBDE5C86EB0D -:102280004F2C835D7280D6930576C918B24B9EC7DA -:10229000F2A5C605F8BBA8DFB39C6E92D4BF42740A -:1022A000F514AF6F75713BF6EDDA8FC98ED3D6A8F2 -:1022B0000EB4E3845E3F1AE27E00D82315116F5FEF -:1022C000BBF1684812783B4AE3EEE5F83F1696D337 -:1022D000D1DE8CD92DEC55F283E276D55DEDB88F49 -:1022E00071BBAA81CAD3CD7D3E13BA779909EF0994 -:1022F0008E07733D976EFF1EC1E1E7ED93D49FA556 -:10230000F1B2399CCC7BF80CFAAD44AFFC37CA0172 -:10231000E5556621E85C549C05764BD74E4945321D -:1023200059B94BECF3FA769BDF68F2E162938E9534 -:1023300092E665185F58FC89E0FF437CFD313FB5AC -:1023400099E07FC78C4F3C8CED397C9F12FC2A872B -:10235000EF2B18DF55427619C74F0D339C689789CC -:10236000F382C4FDCD287188FD4D2F213B99C355C3 -:10237000A34B64BF87579C7222BD2F3DC6B464F443 -:1023800031A4C425E24F43A8BFD7F46F033C2E9479 -:10239000D87E78492C5E359CE0F4F1F936148547F7 -:1023A00060FF69FAD192A17C6B3C688F864BA5488F -:1023B0005B0EFA37DEB25228CF73B05EF2FB18DB49 -:1023C0008C715FF7F30A6B0B506B55B1C475804B82 -:1023D0007F8B7EE422739FE7B1587CC581F11A4B55 -:1023E000FC86FC4077C9FD793B558ABB50DCC6E5CD -:1023F00097C9AF083EB482E223A9856E9F1BE7917F -:10240000B3C9CF75FDD08C172DE4FEA503FE433B69 -:102410003AB59191FF36679B1451A1DEADD9E32FF8 -:1024200075EBCF37937FB782F934F01395427BBDBC -:102430002BC17F6D99A087104F6777D539101FC1C9 -:102440004AEE879DDD35D28BFC97E8479F453F9A42 -:10245000A4541F3FDA7800E36B163F7AED00FAD1FF -:102460008B4AC08F465964FAD1238BC2B7113D28DD -:102470001AC9B7AEE953E693BFBC4D666E687F7A62 -:10248000E7C4370AA16C6C5302186E78DFA92DC51A -:102490007A03FC69F97ADA2686F1ADB926FCA78BB6 -:1024A000CE9722FCDABDD70790DE4F3FE4263C9F53 -:1024B0005E99194983F132B6FD65530AF47F2532DE -:1024C0001C836C31FF3AD10F672C6220DD9C6623A0 -:1024D000581BEE83E26338AED290113002717F7BDD -:1024E0006E9ECFC0F1F4481AC37D8FBECAA4B379E3 -:1024F0008C8E1C908EE731D58985054C7322FE1792 -:10250000319DCAB701BF492371BE3C83E800F80E74 -:10251000E3774D13F4EF10BDFF88D307DBAEB4E3D0 -:1025200079C569E39174E4B33DA9F6788378B698E8 -:10253000FCE9413F7FCC80FAF90F5AE5C465C895A4 -:1025400047F87E727E7595301A07F4643DF279B7CC -:102550001907DE9EC9E3277BCC3849E213183E0BEE -:10256000FB7F513D01FAB29DE08DFBF11D08CF6567 -:10257000E8CB9F12DCFBF83A7721DC5CFEFCF7121B -:102580006E07A819144F01513C89EF2FFE3E95F4B8 -:102590005FE07CDA5312ED578ACA480EB95938CA3F -:1025A0008989E3117EEB87DAFB3D7BB17E6B827C10 -:1025B000FE3F16EA2FE0FCC5E78142A19DBB8AC71A -:1025C000C1E77AA5972535DEEE38C6A192ECF779FA -:1025D000538E42B3A803EC958733600FF2717F02EC -:1025E00083505EBFDDA49D441BEE7853053D7B9474 -:1025F00006921F3DBBE4C806E8FA4613EB2E1DDD2C -:1026000077DC9ADAE0C933167934B7EC090F08455C -:10261000D69CD77158C278BDE656DDD0BF3B3DBCD5 -:102620001DE3F5C651997502BCB72EAC3C79C622A4 -:102630001F12C785F998012CFB61894C701F0CBAD9 -:10264000A333308E60481194072B8C534E8C572E39 -:102650006D5CC674D82757E12905EDC29AA08FDAC0 -:10266000CF2D94996181EBF149DA7B8867A08B3398 -:10267000B4BF81981DF53E96834E2DC3971F8F439F -:102680008A7381174B9E22FBB83B93D1FC613F8B31 -:102690006C80F94BB465AE5E3C67F187296E7AB207 -:1026A00044A57957EE6C277852A7FD99E001DB39F4 -:1026B000EA18DC17DF820F8E9A786F31F1DE1F9EE9 -:1026C00095521ECF13E5B9654A3AE2F92D45A57337 -:1026D0008EFEF87B7EA97D7FDCFE0A5BB959BBD7F5 -:1026E00081F47476A71CC17D82E7EBB86F9FC0BEF2 -:1026F000B19CF838DDE9ACC6AA9FC5FECC29B5EF80 -:10270000CFD26D7C7F966E0B125E969656BA86F18E -:1027100073B5BD40DB4C2F5CC6102F2EED9482723A -:10272000ACBFFD027E1B568AFC6BDA8F57103FCF81 -:1027300029B5D8B55F757C1FE6BBA534899DFDB76B -:102740003A5F10F4740CE56A7E5CAEDE56CAE5684A -:10275000E253C8558B3D49714D0B1CCBEBAF000EBE -:10276000C127C8A728374A7648CEDE7CDC7FE0D771 -:1027700031689F7DB819F35156F919D14356A94ACA -:1027800074ED9A36CF85F278E5AE3F2BA8AF009F67 -:102790008B4B2D72B8A494093D544BEFEB395DFC83 -:1027A0007B9FEB003C77D3BED77238AFB673A7756B -:1027B000D5E18DA5740E0472C98BF1789FD04323A7 -:1027C00078DCFB8B9D6FBEBFF35E8676E0BC3FA5D9 -:1027D000AB6807DE5ED4A9E5A849CF3755C976BEF8 -:1027E000591762E45730161AC62E79BE99787EDAE8 -:1027F000F7BCD378B9392B6E77279E77269E6BB2BC -:102800007ECE3FFB9E771EAC2A02386705649FAAE6 -:10281000C6CF335DD3CE9E6063FB9E770E32F52E1E -:1028200043ED6D596FCF08756F14F3A38679021DC0 -:10283000BC399327C5F1087AC0E38679369501FC47 -:10284000682FE7743CBA80D9F0E8223C7C413CD246 -:10285000F936E265A714D988FD950603E5F94AE63D -:10286000537F1088EF676CBCBC751ACAE7EFD47948 -:102870009903F87F73D63D6C19B44F3D92C26468DA -:102880007F44BD87F6FBC847E92A9EF7BAFD967DCF -:102890003071A908F8E4BE7ED2DF601F3DC8727DAA -:1028A000F651ED28453D7BB9FBF76451F803E4632D -:1028B0000FE86B657CFC7DCF088ECFDE9B58A44370 -:1028C000EABB8F806F8DFCCE3CD6BE91EA1B18C64A -:1028D0000736498CE33B812E1C69EB0D3CD7762DE6 -:1028E000F7921FD5DCD040F83E0AF8367C9CBFF04A -:1028F0009CEA22FC25E88249432F9F2E12F7FDC84F -:10290000CE3AD67875EF6B3FFCB9BB14ED9ECBDDAC -:10291000D77953B59CB202EB3E6B23CB8658F9D6E0 -:10292000E07E0938C0E44F2E64AC33B3AF1D956F21 -:10293000E6A5C0785FC7F1C69431330EA88DC1F209 -:10294000821B5843B2BC976BCBB93F560B2622C5AE -:10295000558C54CABBACF5EDF83DE5611A37A9D6E4 -:102960003CCC3ABE0476FCE1F61EAC9F0B8B756442 -:10297000D12BCACB14F80995E5D0B845AB4FBDAE05 -:10298000527580C67781F0473FB5165F523E098B7E -:1029900074921CD0D97C90F777AC95289FB3C64829 -:1029A00063E8D7C6F32AF626E455F0F2DC6CB3DE12 -:1029B00078B1C37E8EF9DA72DB39A6D19BA0DFFE37 -:1029C00048FACF665F58F4D9072F7FB2DC50ACE7E6 -:1029D000989FD2F8276BC57CC1DDC17CEB39A66B13 -:1029E00037C223E2D4F0DB6D3DA704C8A92CE2C8AE -:1029F000A933B53A8C87ED9BA0AFC0FD914BA406DF -:102A0000B48F40C16812C56B7C1DE84F83FDBF12B7 -:102A1000EBFFDED70976485399E5FCE3EF0DFED3D3 -:102A200022BE6F1C5F8EF05DEDF002BE7F46F8AEF9 -:102A3000E0F8FE3B80F7605952FFE4AA81EF6D8217 -:102A40002F760EF1EF0ECF876596F38BAF7A3E6D42 -:102A5000AAF6BF71FD5FC13A1C33711D66FEC165E8 -:102A6000B4F7507BF3BC34B1BE69A6E93F98E7C424 -:102A7000EFC4CEF1AEADC3F17AE3E77A74EE153F61 -:102A800047CC1B89E78871F8F3687E718E189E79B0 -:102A9000731DE545F7738E391FEB4759FBDFB41BF8 -:102AA000F9AC2D613E9759BF6AE6448237BEDE0914 -:102AB000345F7742FB1A737D6B674EDD6D58F00112 -:102AC0009DA87D4C2E31AD0EE78B9F3B4EAFB39E44 -:102AD000DF7E6FA6B65B9CFFCF443A36CF69FFA37B -:102AE000E363C14C1EDF11E7E5820E474ED116228B -:102AF0009EAE367861FFEAADF4FF37986FDD4C0B80 -:102B00003F7DD1FE317E34F5BEC89F00FC1A88DFC0 -:102B1000A6723569BE84F013C3BD2C827ECB5416D9 -:102B200091F15C221CD019C641637C6D54125FBBCD -:102B300062F723E6ED46F917BF1FD1B61BED8BB840 -:102B4000FEFE559D3DCF616E9DF57CBEFD955F8976 -:102B5000753F6AE593811EFF7BE576BCC4CA267E7D -:102B600096DCFDDF46D8EF5F2CA679DE89DDBFA8B5 -:102B7000DB6DBFC7D0B0DB9EDFF15D3B5CACD50E3B -:102B8000176BB1ED574679EB6E03CA2E33EFCDB517 -:102B900042EAE77EC572920BE25C17CA36B940E59D -:102BA000EC8187EBB7828E4C3E8DC1D9273FEF9BDE -:102BB000BBEDF9790333BF452EBC8DFC30F078E7CF -:102BC000F73B04DEFBBBDFB15815E5C6BAFAFC2FB4 -:102BD0003F2FE6FF59E5C9975F07BF2FE24ABC2F99 -:102BE000C236D6D9E5CF65C3E72A4F2A7F2EAFFF7D -:102BF000A0F27EE58F0FC76DF63AE83E8AEE674990 -:102C0000EFA33495F373A9187F9AF751163C9CDC17 -:102C10009FFEAEE94F8B7877D0757E85F5BC6B74DF -:102C2000398F6FE796C7F25072697D8D1CBE00CA5E -:102C3000433CEF610AD380A7162E18918DF035FF23 -:102C40008E8FC7FCE027A7C7C7AB36E713F3BC34AA -:102C50002FBDC69AD730D69C27109F2F40F3ADE7E3 -:102C6000EB9007ADA67B5E31BFDAF831E1B5C5293F -:102C7000FCEC4EE2EF78DCB883E4CE22B7A0FF276D -:102C8000775BFD89DB7EFD14C9370C5FE0395EBCE4 -:102C90005F7BDDE5F42B2B37F5F12673BF8CD87EF7 -:102CA000CD44B82FD5DFE24747A5ACB81FBD6F8232 -:102CB0003607FB833F3DB7BCE0D2E3009E16119E72 -:102CC000D6DAFD114BFDE2725B5ED2F9D517CB4B24 -:102CD0005A61EE7B7F79492BCA6379242BCA2DE791 -:102CE0004AC17925E905182719E6487A8FE21E734B -:102CF0005FE3F95DBFA4F5B408BE33CBDB3379FDE8 -:102D0000B77EFD6C9DC9576BCA2DE717E2BC85E500 -:102D10001F8E629CC7925FA439AC719F92534EA4E0 -:102D200087A5DBA4A4F9337DF8A5D51C7F5B6C1FB8 -:102D30009BCA797C5FC7B8E36231EE3736D0B835CD -:102D40002BF8B8897CB3D5C4DFD6389EB6129EB4B2 -:102D500058BECD8358C69401F7F8F8F8E27E4FD0FC -:102D6000197E01CF755A0C4945F9AA372EA3734530 -:102D700056013C09FB141C96BB0D4587986F5C05FA -:102D80009F0FFE598AEDFCC042C630B06B2B96D126 -:102D9000B9F3248DE7AD4CAEDA200F5129AFE547EA -:102DA000B8AEA285EDCDB8BCDB6A7F2127CB67E941 -:102DB0008EE5B3B0B7460D05FE36E1C37B216B61EE -:102DC0009E7762F92C5565EBACF92CE12F97CF2259 -:102DD000E27F4B428057CBBE8D34D739B282E33588 -:102DE0007E0ECCE8FCF6465633EB268C2FE3BD2D49 -:102DF00078DD6DDE73BB90CD2278FEBF617A2AC587 -:102E0000F17A33199DABC28664544FC23C12FE4B1B -:102E1000195D4A715C37AC0BD781E7B2D1AFC1F015 -:102E200072EDA068127A7E234367012FC6FD8DCD17 -:102E30000CCFD5F447E87CEE86157FAEC77997EACC -:102E40006E15496071BDAF8CF2B856079CEB300E21 -:102E5000E9979986F1EC2AE77BFC9CC643789A5B5C -:102E6000CACB022F6EA6BC67C58B92506E3CB16177 -:102E7000CB214B7B5734251DCF05DF2E4FB7DD2BE4 -:102E800062B297E8E082DF11C173A86E85752900F0 -:102E9000479D2ED3F97BE7B635AFE3FDB1A57E257F -:102EA000E0807596344A94FFB5D8C7F1F49726634D -:102EB000CB21B0615386E5D239CC059F87A2F12D95 -:102EC000B59D14B7077AE95630AFE70199E1B9B774 -:102ED000C87F9A67D28BC063CAB28F092F17F03CA4 -:102EE0001CF1529849795073001FAA8FCEF93721EF -:102EF0009E525943F41A98F756BF83452D7168586E -:102F0000BF2D8F0CC6A6BC3385DED8EA093FA90FBA -:102F100094F07C34B92A8AFB7AA190EF2B94034871 -:102F2000EFAC94D3A9C07F6A029DBA13F2C312E931 -:102F3000B40FFE2BEC78EF5458208AF4764C26FB25 -:102F4000A277A7924179573B1D9477C55884EE31FB -:102F500075B2C18136949B5189CE096E33F126F04A -:102F6000CE58C3E6E518E76EC80860FC9F391A36EC -:102F7000637ED4E2481AE5DFDDCEF6521ED41DE8AA -:102F800021C3BC77329F0BCBCB59809E12CBA7FBC2 -:102F900025B7EA12F185CEA2D53701FEA2D7393383 -:102FA000AD7955FDE635C1CACF5ACE23465598F2C4 -:102FB000D2A3FB799EA76EDEFBD1283F28B3ACD409 -:102FC000A32791B7A545FAD72B0A2C7918BE064638 -:102FD000E7D345E1311543E2FD9F9AA08DC5F2E4A8 -:102FE00042ED166CBF07ED3CD0078B0E8F7D02F5CE -:102FF00059CB046D3CD627CAABD3FDE7DF451B8117 -:10300000EE7A505E511E613EF1E140E5DF9555F4E8 -:10301000C9BF2BA7F598F977279DFC5E19E5224FCC -:10302000657DEFA735DE46F5E27E5AE2BD34F62334 -:103030005E8605196DE3F0FE6E03AD5BE03D113F6A -:10304000CCBC97B6C4FF4A8F347600F2D67C60DCE5 -:103050000DBB187D18FCFE72F59A9E2CCA235428CD -:103060008FB02587DF5FDE844D30116814B7070706 -:10307000557239BE25B3C11F80FA2D4E9E0FC3F283 -:1030800074B6604C7CDC4195B238176A403A00BB9C -:103090008FEC2561AF8A76F7997AA1B14212F7CE0B -:1030A000EEC7F696FCEE46DA0F6F34E210E776FCD8 -:1030B00047E740C27E383EBC81F269DC5A727BA190 -:1030C000B922A6CF9B69FC9D429F6B9B70FC19D7D0 -:1030D000F816229FB94A64D6817A6CEE5D24779FF8 -:1030E000C1BC51B06926EB1B4A86C27E3F52619E2D -:1030F00037D56722BA58B7C6F349A3C50D7ED47732 -:103100005B8625BFF77DB282DBCF13AF3F2FE3B8DD -:103110005B9681A7320EF167501E9BB1086409943B -:10312000C1DD3F84E7321EB4038A502FF2F6BE7A27 -:103130006803FBD865E22B7823D00FDACFA3EDF933 -:1031400048E229DA25E65B81284FC77527E6B98969 -:103150007CAB1EC5480F24817F6ED95A0FE56B6585 -:103160002FF7A09E6CD14A68BCC4BCB72DD96C04A3 -:10317000C29598D726F2A644BE9418F7B90A4E27EE -:10318000226FCAEDE77A0B9E942713AD50CDFBBB9F -:10319000F6FC36915F83ED29BF269BF1FC1A7F0375 -:1031A000C37E6E2863FBB0997F9698570572E8201E -:1031B000D1411FFB88919DD15264E60D306DF332F1 -:1031C000B48FF0FC3690C4BE0281807AD005FA0933 -:1031D000EB15797505A6F27C593BAAB428DC83F07F -:1031E000B9FC3139FB3B82372E67DF35E5EC09ABA3 -:1031F0009C75BFBAF509B4BBB7489C0EB700DE9FFB -:103200004E421F1F98FCB6253339FD7C6ED26BCB26 -:1032100084F08738BE96C5EF777C513BB3256E6747 -:10322000723C0E909D09F8F8CC2AA7011FFF2F19B8 -:103230001EE0B709E58625CFD45959D07F9E696233 -:10324000FF2BBD277C0DC80DE43FF0077D95E40FF3 -:10325000723A16F2387EDFF6CAE4F53107C85180BB -:10326000076D026BFBDC4A2EE7C64DD5732B492F49 -:10327000F3FBBE5B83FCBE2F8B6AA4F78FA7EB35F5 -:10328000C8A72C6FFC25E6DB60E6D3EAF56192F374 -:10329000F32FD17EA339BFB9DEBCC1A43FB64ADA51 -:1032A000AE54395EBED4FAAEABD42623FCCD7A98A8 -:1032B000BE97B025CFA11AB0B47F9AAC17E3FB2D0F -:1032C000791B69FFDA80E024909B731CE71FCA9585 -:1032D000281FF85969103C3DE0B125A1EB59959C98 -:1032E000EEC18AA57A7642F35BE31C6B4DFD16CFE7 -:1032F0000778FA09EB3DA61595FB5618163D86F1A1 -:1033000092A793D0C5C24ACE3FB27B8D4D4F26B611 -:10331000BBB5D245ED56569AF10853EF2D72733F67 -:103320008A1D01F82C7A75DCD4D0EDB4AF063324B5 -:103330008B3E14FA8F6A2CEFDD7E7EFF841DB38FE7 -:1033400023D6799F49A7625EA0D755C81FA077BF33 -:1033500081F388FA4532E3F18E6E3BBE009ED59C28 -:10336000CED88A587E96051ECDC1C78DC1D1638740 -:10337000E33E733FC64DD5EEC371401FAFC3676BCD -:1033800008E82D095EC71784BE8DF50A335A73739A -:103390002E6AAF6EC076A26CB1579B2BEDF6EA2673 -:1033A0005C2FC8D1CDF87E4F6AF2797798F81AB0C1 -:1033B000EF065C269F3F88FF4CC22F6DBDFBD2C637 -:1033C000028BB9DDC6BDC497F9E32FC1579C8FEFBF -:1033D000BCBE81F4DB0BA6FDF1829329985703BC98 -:1033E000154896EF73B452D81B91E18897E7FAB16C -:1033F0003762EDFAC9ABFF1ADB9176257647DBB46D -:10340000E36964777CD29186FAFDB933A1A476C7CB -:103410000BD93B8627B33BF6F76377BC6ADAA7077D -:10342000DF77911D517C8EDB1DC5E776C8683FBCF8 -:1034300059A9D27A8ACE74CB3AC05D8C76078CB308 -:10344000DFB43BB03DD91D9FEC9011AEA273DDD42B -:10345000AF18CA687714F56377001432E2E1D9E255 -:10346000B67FC5FD4B5CEFBC897A8F956E0B7BBB3D -:1034700029BE23FAB5E56D4CD369BFEDF4535AA4C8 -:10348000DAF2E20B7B39BD27B6EB8FCECAE4AAD6BF -:103490005E58D75696BE83F2319586C7B16C180A2E -:1034A000FF3E1E7E5F039EF7CF051832B15DC34F0E -:1034B0007A51AF186E1F7ED7E02FA94BB99FB396F4 -:1034C000F99C53E37288960EA01921733C97C7D7D5 -:1034D0000C76D2F7D332088F8D3E11CFD951910B94 -:1034E000FDEFFFDA28BAF7137A040682F2D46332CA -:1034F000D58BF8CFEBC318E5E703FFCEA986F127FC -:103500009BE3839ED3EE85F68B4C3B6CA6ECA5F635 -:103510000FE6F1F6538DF3F5582EEA75A978BF8CB6 -:10352000C9EBE5BB316E8BF608B47FF0F9709907F3 -:10353000EA538F032438DE0917C52F447CA1E0D855 -:103540005EC267DA19972DAE910A122F6AB15B5CE1 -:10355000096526D70E4A269FC433310E71ED2CD350 -:103560001F1DCB6EF91CECAC0B6C7D2BAED13D3A24 -:10357000747037EBDB5FC419CE4FD446CC827D1C10 -:10358000E5D4C96FD95F01B8867DDABF73E7ECB1C6 -:1035900088F71D0AC5754F7E3B8DF6E9C0234A3B6F -:1035A000C6934E029FF2F8ADB112E9F5403A13E727 -:1035B00040518CCB1D88DD67CE5EA959CAE35E2BD6 -:1035C0007C1FF5E08121A2FD8F79BD281BFFB4127D -:1035D000F3360E0CE3E525AF3DD369101DF72AE461 -:1035E00057379EF626939F9366DBE9784EE11A4E95 -:1035F000C797E807F27EC6AC24FD52AAB97F75A032 -:1036000016401A8778D24B67015FEFEFB9A7750CA8 -:103610004C3571DAB7BB498E5ED3BB3699DC5F306F -:103620008BDB53D1E208F95BE0C3737F97298730C6 -:103630007F750E53C7A35FFFF0F4E77E3316E6797C -:10364000A368F47839095FDF3D2B97C689C37754A7 -:103650005E8E72E9A3F716269303DFAFD417DBD78C -:10366000C3CF479B772884FF0766FFDF2730EF2112 -:103670005ABC83E277FBFFE460E8AFEC1FC3ED7E4A -:10368000BCA187DFA51C00F8764E4E427700DF5DB7 -:10369000B30AFAC2377936E3F9A113B56F617D2217 -:1036A000BC2AC6B9015E30AF022847523EFC2FDD6E -:1036B00018CFDCDFEBA0A0CA85331D3292605B4FD0 -:1036C0006E299AAB33AA4EC94852C5BE4736E3D1DC -:1036D000AFBE5EB6F1DFE49E545BF98E866B6CE59F -:1036E00025F5C3E3FCC8F01ED0485BD9EDBFD95621 -:1036F0000EB209B6F2C2AAA9B6F1CA7C25B672B951 -:103700007FB6AD7DA5BAC0569E9DB7C4D6BE3A5011 -:1037100067AB0FE78F53F00A1FD0E5F771BFD38E69 -:1037200069C4E75B7AEEF1215D448BC3E44F1F4F20 -:10373000EFCEC678F5EBFD7C57EED42CAECFEEBCC9 -:103740001E4C239493A0CF3766C6DB07737B6DF1C5 -:10375000F8C3B3B87D7A7056623CBEBF7B705C3FE5 -:103760005FEEFDB7443D3CF7A67B482EB52D942374 -:10377000789FAA39EF2D2FDE1B7B7D218F23B46527 -:10378000C33ABD948F41FC7570D16D23F05C2D352B -:103790004FBF06E5BFD0DF257911761AEA537D11B8 -:1037A0003612EF9741B9CEBC675692CFDFDF68BEC5 -:1037B0005F854FD0DB332DF84AD4C741CFB897C1CE -:1037C0005D60D3FFEAA3EFF72DCCE7F19ED24F2245 -:1037D000A5789F7AB6F6D2217E6D9ACB9F378AFF65 -:1037E00098D58FDE7ED3CEAF47891FF69F997F5144 -:1037F000F9FF87261E5F7FA6C9C3A2B0BE134D3E48 -:103800007AFEAEC94FEF8F36A9F46C69CAA367B4CC -:103810002940F5FFDA5448CF434D1A3D5F69AAA00D -:10382000E7E1A630B57BADA9869E479A747AFFF191 -:103830002CCE97570B3C5A9E8827840F3A24C2EB14 -:10384000424CD59D724E93ADF21DF0FA6932BC5ECA -:10385000A91E8916EF1D1EE67A2A291F0D9D2DEE41 -:1038600085713B798E4E323F069F0BE37359F1F819 -:103870009C1B4D9AC104E7A0D9050307E701337EDD -:10388000732093D53CCDFDBA4D12E91BDF382ECF06 -:103890007F100E913C1F322EB93CCFE923CF979178 -:1038A000DE6287316E8A6945288CD7E1FCC9E32145 -:1038B000C6A09C8BE281CE2B051E2CFB15B8123CBA -:1038C00024AEBFB4489B8CE3E03D14E7E0BE7AE44D -:1038D000C6DECF348C493D9BCFE17DF8BDF983D066 -:1038E0005E7163308AEC1570F00A71BF99698FB40C -:1038F00077D667F71DE70FC57B49AF3F18B3739EB7 -:10390000203B26B11DFC0E111E506F59F090440E45 -:103910008493ADBF4C7EBE7723F43FD0CB285EA608 -:10392000A24D0DF03FA7F0EF341C38E7203C5FF0CC -:1039300048241FDD0FDCEBC1D8F6B3DFE5ED8C6A60 -:1039400089EE2FA475ED57D14E0DF6EAD7E0F7C6F4 -:103950000AA3954EFC3E6868DAB8408A850E428A12 -:103960005D4FA2A51AD33B140C1B9C50BE2EDE5EED -:10397000C6FDCF8D9773E8DEF53FCE063A9D7FBE3C -:1039800081A9F9667C35399E564B96789BC202AD6B -:103990009373C8EE3C741D9EDB8C661199E8CA20B7 -:1039A000FF5BC02B7BC3742F4FF8E99F4ADAFDB34E -:1039B00093D80FAC5EA37337E670D0B95BD304BD68 -:1039C00069369DCF279CCBF85EF93F12E8B45607C5 -:1039D0008BA27D6164B8087F89FB35B9B07213AEE4 -:1039E000CBFFA5FDFA1D92F53B0137AA33C89FBA5C -:1039F00000FE14DE436956F8FD28E3447AA4938060 -:103A0000647968B7DD2FDF1CC0FDFF7EDAF7C83FA1 -:103A10006A047F0BFDAF6DA61CBE3F35A383818278 -:103A2000DAE66CF81F58DF22B17007FA5B29D74736 -:103A300058461CAECED95C9FBBD91D8390CFBCBE6F -:103A40009927CF4C48E6EF71FFC419DBF76C1FF9DB -:103A50001B66D9EBD2FD98F7D8326EF52EBC8F6578 -:103A60000CF1F0F34E25ACCE03FC3C64DEAB653EBE -:103A7000836559EEEFCB4C398BF1D9563066F07C2B -:103A8000F79709F038AF101E174A18F447B35C11C6 -:103A9000CCAF51511E015CAD7E07F1CD2695F3FDF3 -:103AA00026AFE6F125D9B72D884777FFFB29E76CCC -:103AB000F2611C7B87D7417CD9AA2A5B73A0DCEA20 -:103AC00055F8F75A554745B27CAD8F6673BB099AD6 -:103AD000A4507E53703ED931FDCDD366EEA728A702 -:103AE000E6EB1AF18F1A08E37A9ABD5912C63745E8 -:103AF000FDAFCDF1459C78AB6917A5E6ED8D62BCB5 -:103B0000A665D8AA09882E0FD83967E1BD277F2F6F -:103B1000D9452D433C35C9CEBFCECFE671B6ADCE2B -:103B20004005E2736BBA831980BFAD39C9F5608F68 -:103B3000B97FCDEAF830D12DE063B4D4B7DD6F4C56 -:103B40007DB9D9B9C38FF7D0B68EBE95F2BCB68E0B -:103B5000E072B7F1C889CE0DF9C80FDF62FF86FCAD -:103B600090A5D0BEA92CE041FDD5E2537CE8EF4FF3 -:103B7000CC5AE7095AE497A0FFED6887C0D3396CA7 -:103B80007E0DD2E385C2D40022BD4C3E42DF0969DE -:103B900009803CCDC13CA4069FF5FE3FD8D37215E9 -:103BA000C0951E70D8ECED4185767F4165BA87E8F7 -:103BB0007318A7A3FEF62F111E2F4A9CF117699FB9 -:103BC000A9D724FB2EC9B82A8E574137CE4BD0CD6A -:103BD000A5E0B7E9BBECB8BECBA91AB10ACF2F1E3E -:103BE00062BC7EE491F39DE8AF2796BF2C7F362B15 -:103BF0003B481E378F72113D25F6DF9AC3E1F9600D -:103C0000F647341F861570DF323D3C8EB4BD7070B0 -:103C10004A32793B6BA25E5465B18B324BF7921EF0 -:103C20001D5CC5087F5E35EC1B05E3788FC940A39A -:103C3000806FC7677F3DA55E391E951D0D2CCCC7D3 -:103C4000233983BFCF40BE6598FA64CB0D6F30CC6B -:103C50009FD93E5209C89487702470313BDA5B6863 -:103C60008F137DD138504D95998F92C252781E5046 -:103C70005548A1FC1B07D79F1AFC3FD4BCC22E9904 -:103C8000FB3FD43C5A52F1158F7F65D5325A4F2CE9 -:103C90001F05BF2783E3E88CEC0CBC108BEDAE5BFB -:103CA000CDEDA86CD62BE1F9DE0D98952323BD73DD -:103CB000F97981653B281F07A6C17C12C97090BEA7 -:103CC000FBAF379C9482F0767BD1AA71B83F89EB29 -:103CD000585365C6B362EBB8381E049C034DA74227 -:103CE0002F377BB89ED54021A7A0119C10D72C93CD -:103CF000D7535CB3C570FB500F372BA077B3A877B1 -:103D000098E2A00971CDBFA4F0B8A7B48EF9A4229F -:103D10008A6BE6E13E35B2D400C61D0729BA07EB2F -:103D2000D346298CD355C3643C3F89FBDBAA97E774 -:103D3000BF35529EE0AF50AF41BBAECF2E2E8FF6B7 -:103D40005D42AFB51D1BE5A5B8B9A72E0DFDEC670B -:103D5000FCB947D06FB9E0E1F95BA25D57C2F74CFF -:103D60005A4C39D75365C6C753FE2263FF197E5597 -:103D7000C13CB990671CC9F76629F93940AF29DF02 -:103D80006E54DFE474B65A7C876C35C9FF77D34D27 -:103D9000FAADD79750BCD8B4E398A6A9BE4971FB39 -:103DA0004DE84BBFE233EEC271CCFCA93EEBECFA1E -:103DB0000786DF57617E4BDC3517E71F14CB9BC3AB -:103DC000F913EDB6FEF0D966FABDCDFE10E55D5CE7 -:103DD000409995E45C443CC1FEEC463955D06D9762 -:103DE0002F697976F9D2EA68A03C2EE366E6C33CF7 -:103DF0000F5615F05BED5FB0438F571133DBEDC904 -:103E0000FBAAB9BCEBCA54158CBF9478820CCF1BAB -:103E1000946C9DE17EB8FC818BEEC7CFABB8DE6FB2 -:103E2000C95B1E467FE5E1E9DF24BC4CACE079A527 -:103E3000A21DE8CB0FAA2C7E8BC83BB8ECEF23F970 -:103E40001C948F78B9F1A1B6692BF9F791FCCBE9F5 -:103E5000FB48CF78F8F791BAD2F534B4BFBEE8F793 -:103E600091EEAEE6F41AF27CE3E08C5C0B9E7A7481 -:103E7000CA0771F9CFD3B9CC0C337F24310EE47665 -:103E800037D0395AB4B86189350E2CF0F77393AE38 -:103E9000FF50AC539E4F7F7FDF41B4438CE1BADCCF -:103EA000669C734BF1B709FFF32B3229CEA49871AE -:103EB00026D7799DF27A3B27EAD7565BF49D3BDB08 -:103EC000207D97F63DC6EFAF7FCAEFAFA76D6421A7 -:103ED000BCAF1EFA6C3C9D3F85A229C467D33F0945 -:103EE000D0F7A7CBE4A75A73A1BEEB9842DF85EFCA -:103EF0009A9E9A857AEDE363DCBE4DEBBAE9C82D54 -:103F0000502E3E5687BE3EC81D806570DF754CFF43 -:103F1000C4F1A5FCC702F41F2DE72062DC5F361D4B -:103F200026FAD8D7D44DCFFD4D517AB635F5D0B35A -:103F300050D14A703D85DD7426C9A69C817A0B1C40 -:103F40008527A0BF851E864CD4B56AE2BF6E5BBBD9 -:103F5000B4BC1E5B3BF05F4BAB0B308F87E3D3856C -:103F6000DF0D83F1E7F6B0CD92FA1F4A5EADAA1ECF -:103F70001879F58FD505179357FC9C34D4637E27A9 -:103F80002C811F1DD52AF90D31BE34CF4B859E6E75 -:103F9000C57F823E6DCEF826976FB17C0C7EFF50B8 -:103FA0007C677EE3EB1FEDA1BCD277CC7A83FD4426 -:103FB000B3D433F6C92ABC0FF2123AAF60879E7BA6 -:103FC000BD6B15DE9BBEB52653D100BE123C58CD4D -:103FD0008CDF7F11798A8978FB9FD59CAF8FE7FAB8 -:103FE00028BEDE92CBFF5E4162BB37ABB9BC409AC4 -:103FF000B0FE1D8FD47EEEFDBC2AC635F1D6EAE2B6 -:10400000F907FDDDEF78ACFAE2F73BFE60D65FEA38 -:104010003EC72FCD795FC4790B282F720FD285F858 -:104020003B1B51F37DECEF6BF859D2717E6ECADD0C -:104030001BE7F8CCFDD414F33BD47B893ECCBF877F -:1040400020EAA79C8BD5EFA3F9627FF740A7F88FF2 -:10405000B85FF7F3EADFEED960F99E574BEC3B8986 -:104060003C6FE95313FEC4A7B85F12FB1E147B6BB1 -:104070008F66F91ED44FAADF396B7EAFEA10C16795 -:10408000DEAB79348E875FD3FB84EF0374BDFEDA39 -:104090001EF33ECE6FA8BE21F1BB5BEFEDB1DEEFAC -:1040A00079B4FAD42AB3FD515AA7F99DAE247461AC -:1040B000D2ED993D789FF032C67B97C633BFB3B53A -:1040C000D9E4A3FEE819DA9FA2F6B1EF0FD7795031 -:1040D000AFC4EFF1BFBBC7F6FDACFEF1F5475AB771 -:1040E0002EE665667E13E717911F26E8C23B87EF31 -:1040F000C776931FF0FE1FF55F316078F88CD69578 -:1041000070AFE852EBD837212CCF4138FCB1FC62BC -:1041100085CA5F121E711F2C913F86CF91445EF3BA -:10412000609A273BF61DCE6B06625E1877048D13EE -:10413000FFBEE7F57392CB9F2F342E532F2F6F4482 -:1041400094FF3F19A999BA607100000000000000B7 -:104150001F8B080000000000000BF3176060F8518F -:104160008FC09C687C5AE3BF4C0C0CFACC0C0C97AB -:10417000D818189C39191884F8C833E7229ABE7BDE -:1041800040B366F030302C636560D809C47A5CD8DF -:10419000F5D90822D847817E5F01C417E91C06A320 -:1041A00078F0E01A11068649A208BE9E18AA7CADD6 -:1041B0000882AD2345995D4E40FD008850BECB80FE -:1041C00003000000000000001F8B0800000000003A -:1041D000000BD57D0F7C54C5B5F0DCDDBB77FF2728 -:1041E00037C9029B10E24DF863D04037103058D4E5 -:1041F0004D041A90D7AE69ABB1A576A14A151156F8 -:104200006B9567D5DCFCDF841002A202455954107F -:10421000ADB6A9A2B59FE5BD0D508A7D7E9FE8533E -:10422000AB56FB62A5B45AA5F1594AFA7D086FCE88 -:1042300099B9D97B6FEE6E962A6DBFF86B87B9F38B -:10424000EFCCF93767CE9C99956C6E52760E21A70C -:10425000E1EF12421EF21242C6A4D2CAEF7DF986E5 -:1042600027AAE8BFBDCED04E9A54FE626E71B4222A -:10427000557F1611B05EED2F96FC91D07AFF4EEC73 -:104280008A937EDAE71FF486685E15EC04DA394912 -:104290004DC1BF0468F9902DD445F3C993361FA1D1 -:1042A000FD4C2776E8842844F645A6D1EFE29773C3 -:1042B00089AE7F737AF16691240B08D97F27112389 -:1042C000B45E9BFF8225033E425E6C4CFEE5C864F3 -:1042D00042C2C9A9A242FB39D07808F3FFD678F8C8 -:1042E0002F471C8444491E8E533BF72371296DB719 -:1042F000DF411AFA68BBDAB0E058AA1B2FCAE7B34D -:10430000DFCDCBE51AD1B2DC4FCBE9F7DAC0E596C9 -:10431000E5513A23AC97C7FB191AB0433D850C7A97 -:10432000719E27EB2DE7398EB7D3F255036CBEFB98 -:10433000DE3E7119D0214972234E484F96BD05F8D3 -:10434000EE77090A29A5F81D5884F84D027E6917F1 -:1043500027DE61F8DEFF892DD444F15DEB927D21EB -:104360009A2722A5072DAFF59130C225D294C271AC -:104370001987FB2A9ED6438A7451902EFD2E4A1728 -:10438000DFE8F05EB2594278B579F6C33CB368A76E -:10439000D1957EF545FCB41DB1E68391F8A1E3CD3E -:1043A0003C733835BC46E6F6FFE5888BE0DF69FAFA -:1043B000BFF9F2F37F39529ECA5F3274D890A71CBE -:1043C0004D5CB329BCF04F0552F1CF035A79292B2C -:1043D0008771E28DCA9F2751FEEB6D247F9E44F9C1 -:1043E000AFA7D185F9EE4619F35D8D41CCC745DA0B -:1043F00084D231DE4D122A6D9F17A6F575E3E5567E -:10440000D3763AF8FC21D990F796070DF5DD8A624C -:10441000288F2B37DB1294EE9D15B6845D0038A8EB -:104420008C9C0B70B830A5E0BE16A4F399C49A908A -:10443000750EE5576500CF4B76D24CF3394AD8B6A6 -:104440008CE64B82769208D1F1730609A1FDC5EF87 -:10445000246423EDAFBB72B66D19CD77CD71CA76EA -:10446000999004ED3FEEA4FD9C4A2A2DD0CF34292B -:1044700004FD905EF1B7802717FDEF741921131525 -:10448000E91D5B0E21A52AFDAE9F9F530D825CE7BF -:10449000561BBF4F5496DF4868FD8944F7BD34452D -:1044A0004F6D5C2D6F1ECF3CCE396B4CFD9BFA2DB2 -:1044B00051066AE48A54BFE790C126D9F7CFDC6F72 -:1044C000B856003A858892A83C7B70FBD67C9C77D6 -:1044D00064660ACFDD0EA607CDF236406CA83F8891 -:1044E000388684295C8A624B74D17EBA4A6DC83F93 -:1044F0004A1B4980DE5A37E1700CF25DA592D24C1E -:10450000F3A5E5071B84E984AC9D2023DF75ED75D9 -:1045100092E610832340F9B444E3D353033565C0D6 -:104520008702096DA4E5A5CAD126A82FBFE6511CB4 -:10453000D523E747D6B0F9639ECE7F10FE316B647A -:10454000BFBF9C258523C0B72A4938293C9D939A33 -:10455000EB543ACE03AA48407EBAEEEC7B1DF01C29 -:104560009FCCE035CFBB449196025F13FDF874BC3D -:10457000924957DC00F332C3A1E98BEF37CA288F89 -:104580005B1ACB317DA051EE033DB1E513BB257E17 -:104590002F13987EDEEA88D8003E758E2DB113F574 -:1045A0004F74EBF5347FFF77C7CE8075E0E6393680 -:1045B000D42F7FEE66F8BE5FE8BD8A607D49C1FA00 -:1045C00026F97F400C377F8BD6BF3F5840542ACF07 -:1045D000258EC30BCF85FED69455AAB4BFFB6FD9E9 -:1045E000F80EB42F993345B1D3F613AB8FBE4517F0 -:1045F00071B2E5D44030E2833C93EB923563FB2605 -:10460000513E19AFF4DE04E397544B4AA234C597E8 -:10461000C52484E39CD3E025497974FE2C5E9999E6 -:104620003FCF9E1EF8FBC85511C855410AEEADDCC0 -:104630003E31D37DB160437E1996AB6A26574F5EFB -:10464000C8E8ACC9D59609BDEFE5D27CCF37189F35 -:104650009AF9BCB4FA680DD0B59BCA4F7E909042CF -:10466000A7F2B140F33D4BB91C561F1596D3F67F08 -:104670007AD5A31090A725D6FA3A1D3FA752E3B8E2 -:104680000FDC62AB8DD07ABFBC76CA1F9D30DE12C4 -:10469000490139EB11CB717CE5BB92A2EAE859B232 -:1046A00084CA13E5AF925BB8FC98E46AB4F1E38D79 -:1046B00009F22E95A30D8D4112A6745BDFA8A07C94 -:1046C000ADE37206B62829A4792E67A47C06E6D34A -:1046D000D99F8434A1DCB994248952FA6CA07D93CB -:1046E00022F89E0C87E712920FBAEA42042769A3C8 -:1046F0006BFBFAE17212A64C4F7A049E57FFA88614 -:10470000E9787288E59F6BFAA3DA428570839BE5AE -:10471000F70AE535EA5C7DFB83D8BF569FE693B583 -:104720009374FD41FF157A786C35505FEBEF8DA6E1 -:10473000A21A958EBF9EE7A5E63C963FCBFD770B70 -:104740007D41CAF464ADA99F6E81E349FD8F70D8A5 -:10475000971AE73EE1BDB06A28FF4318F0A495FF21 -:10476000A0E93F5495D6FF8844B608940E33E64539 -:104770008B08A5BBB72E49C094DA60C2776A7E2F3A -:10478000E1FC7C152CFF60D32761C0B756FE8CE09E -:104790006F027C03DFF8C6121244212164F3CFBB01 -:1047A000AF7F01FE5D9E4FC81C3A8ED24B14DA8754 -:1047B0006D524C807D47708978D4200F9CEF287C07 -:1047C0004F08349D3137FA35580A2DE053F5F0691A -:1047D000E38F06AF06477AFE64E39BF9A87641F5BE -:1047E0008B73A97C790F3B424E05E6210BA0C7F3E2 -:1047F0000128AAD7F24EED473A11B12F0876B4B985 -:10480000DFFC794524A19BE7674DCF2D9067787B2E -:10481000454F579A7F4D8FC727A0DEAC917CA7CD1F -:10482000CF0DF3236007D3F955E9E7F75403CC2FF5 -:104830001DDECCF35BEFEE6D8858E8DF8B6D7CBF3F -:104840007B71F597A07F3A1E01FDE5560651FFCA20 -:10485000301EDD6AE69EDADF005BDB74E3C973E9D4 -:1048600078E5670F9FA3F1B18FEA2F85D6B3853224 -:10487000F3B1599EB5797B61DE02F011DB0F98E749 -:104880004D08E523FFFFBFF3FE5864F4BC85F6AF87 -:10489000B27931F9F807CDEBE3170A505E011E3B00 -:1048A000E3E7A0157FBD2B28867DAE99AFD3CDEB76 -:1048B0001FC5A723E79519CF675B0F65AB5F9B5FAC -:1048C000F3201E7BAE61FB849E43F3D1EFD0F3C295 -:1048D000A5E3008E9CF8F9244CEDDF29D03FEDAF25 -:1048E00047B32F36578DD23FB32FEE6B247DAD9358 -:1048F00009793A6700F7C3144E6CBF95DA9F09AA8D -:10490000E0AA5EBAC5BD948EB7F5BA8D6EF02BF5F0 -:10491000707BB1EAA587372CA0F81C776D7EA59D2A -:10492000B2428F5BFBBEE7F929F4FBE66BF877EE4A -:10493000BFA2DF5F82FA415E3F1D5C85D2403482B8 -:10494000F242E1D2E15F2B7FCAC6ECD227C1CE3A58 -:1049500017F633CCCE2AF4F42E05FAE66C959407BC -:104960008591FDFE6FAE4FEF033B8DCE77CBB5ED5E -:10497000456057EDDB317BBF0FE0BA86A03E3F3785 -:10498000B1ABDFA1C0F8AA00787ED241343B0BD78F -:10499000F9A26B34BAD60B974EC276DCCE62F9EF31 -:1049A0000FAFAB5F47BBA538CAF2CF347FB7A64580 -:1049B000D495ABDFAE0917A7CA5F6CBEB106D6DDD2 -:1049C00019AEE89B7329E96650BDD742E198212AC8 -:1049D000F618F0CBE680A5BDB8FB79574382E277A5 -:1049E000F78E2913AFB55847281591CE5A7EE62188 -:1049F000A39C3D09F873021E99DDDA4DD10BF583B6 -:104A000051A505F039F31009C17E349DBE4B47C74F -:104A1000E036A3BE9B211AE775B6E6F31191D97E65 -:104A20009BF74FD7F5976D6C3E7690A3992293FF35 -:104A30004F3B9F24E089D911BFB1EAFFEF35DF1961 -:104A40003E3A4EE0B31F27681A275DBF667DA5D6A4 -:104A50001241047F7C1109013C79F36204FCF87671 -:104A6000DFE1A04AED3D511EC0D411180CAA54EF4D -:104A70004A41A510526771A810BED3FD11978F8EC1 -:104A800026D4ABC3F9CE26D0A3EB218FF2B716CB39 -:104A9000370EE7D761FEEE094C3ECFB1DFD30F7A78 -:104AA000B80C940D856B5DFF1B0DE0072838E00BFB -:104AB00081A951E00B11D0C35A794FFF7B4117D820 -:104AC00071077CC44DF93D5F0E137DFBF5FD7F0D35 -:104AD000CAB4DCC7CB7D8188A17C63FFD4C22045EA -:104AE0009187977B82512CBFBB7F4EA10276CC0170 -:104AF0009F0CDFBDC5311CF7D25FACB4A13F76B1CE -:104B00002DE1D4E9ABF8E219A8DF9708D1A9764ADC -:104B10008F9A5F74BBC07E881FA81807DFD1E6415B -:104B20007F92F87F613F0AD9D36807F9E4A3E7735E -:104B30007AD953F4E886F30AF403B3738A383FA7AB -:104B4000506B9349185FCD6174A21C9DF23F63FBCB -:104B500043297F35E60F1BF27E3911867DB418A0FC -:104B6000FA81B6F786D530D05D2A6679BB2F9404DA -:104B7000FDB1F91B2404608B149F507FFD1C9A57D4 -:104B800080FE116CDF398BE5A56054857CBC92E515 -:104B90009DC5B124E4D74E65F9CD1A9DC9A3463E03 -:104BA000207F42BA770EE7DDCD501ED7F886789B7E -:104BB000A17CED454CCF168935FB00FF9BFB3B0BE1 -:104BC00097D3FE73811F68FFB94B42482F8D2EF794 -:104BD00029365C6F35BADCA7CCC07382CA5C8A09FF -:104BE0009C9082F4A83CE7669B0CE71DE7DB123B38 -:104BF00005389FEA760FD07A9BCB6760798968E7A2 -:104C0000FE01E60FDFC9FD0165D4BA00BB63275F73 -:104C1000AFF7DD332517DAEDDBFABF90DE17DBF3F4 -:104C2000B0DDDA72767EF32C5DA7C14FF74CA30B93 -:104C3000D31FD1FEA2545F3FD1E8C2F4078D32A644 -:104C40008F523D0E69372D4F82DF81962769BE6FE7 -:104C5000C05607F27F4F2335CD68FBBB1B5D1F8B12 -:104C600093C15F21637E7D6310F3DFB6D5AFB133AF -:104C70007F8AB782CEEBE99727A17F2FF4862D920A -:104C80008079CBA4607155EABB869F6FDB6AEF0425 -:104C90007EFDE18088E31071A0EB7CEB7ACD506F54 -:104CA000FA1B22EB2F30B0F1B28065BD0EA8F7F8E9 -:104CB00011063771253D69FAEB06782BDEE6F00523 -:104CC00093F969FADB00F51E3BC2E1F325BACEB3D6 -:104CD000AE772F8C7BDEDB1CBEE2C4C645D6E37EFE -:104CE0001FFA73E5337BE573E0CFA8C2756087A038 -:104CF00093E74D4B55C146E9EC2A188841BD6955EB -:104D000031A18C8E1FB83A26D8A6313BC346F36E2C -:104D1000E887A6E797D3725A6F1394FB75E5D09E88 -:104D2000A6532B5879E09BC6F261BDDD40343B357C -:104D300009CED6E0578CF92936A61F9FB3FFB606D9 -:104D4000F87D8AC4CAFF1BF260772D36D5F7B0FC18 -:104D50006FB5FA39ACBD4D6479573E9B77CE565747 -:104D600002ECAE0DF3DB83CB7CA9F9E62D889743EB -:104D70005E9BDF86055B83CB74F3C9FBC2B6F2652D -:104D800015E9D715B7622361DDBA3BA5B782840B5D -:104D9000FEF9F5CB5775EB06AC2BE3F8BA30AE9ABB -:104DA000AD2B146F2AB35719DED65F64C45BEEC512 -:104DB00046BCADBFD888B7DC4B32E3ED977CFC74C2 -:104DC000F8A3E387F5E36F5C681C3F7F9171FC8D6E -:104DD0008B8CE3E75FF6A9C74FEAF9A6B7C638BEE2 -:104DE0005C6B1CBFB7D638BE7CE9A71B5FA34F67BF -:104DF000FF16E3BA5E15217AFAC5FB3B8386753D43 -:104E0000C4D675AD7C6DFF4F83B0BEBB617D07FF1F -:104E10004C395BDF2BDFFD28087EFBF5171D0CC22C -:104E20003E633DAD7BB822B56EECBBE856DB63B4A8 -:104E3000DFEF4C65EB4CFF45CFB840FFAF2D67EB84 -:104E40004C9C9FE77635268FAF74A4E6E58FBB7147 -:104E5000BFA7E587ED25F2BB1AE0C378B98DDB4B20 -:104E600085CD616A8BBAA68A867C67052BBFBDB5E6 -:104E7000B059055F8AA816C23AE42D277FAEB0D894 -:104E80006F69E36BF0A41F9FED8B53E34F348D3FAD -:104E9000D130BE96774F63E5AA38A916E0D9CCF792 -:104EA000CDB788BF43FD72F6E09BD61C9EA4878FCA -:104EB000E553F0B1BC06DF5DE2F45A75D2DF13BEF4 -:104EC0000B4CF8BBC084BF0B0CF85B23569F11FE44 -:104ED000CCF5BA4DFC790309DF268E013922686FC3 -:104EE000C644999F07B1FEAA442E5F303EC4ED2C04 -:104EF0009512934B59793D5DD796887C1FC6EBD7A9 -:104F000099F29AFD0ACBD169F4C358DBAF12617AEA -:104F10009BDA1DA19DA8D743284FA97D07F363887D -:104F200062241CB1D007F78AEC7C5890430D00A78F -:104F3000E893D08F9AAE7EAF2870FB5A359CEFE491 -:104F400092C1A41DE008128C4F2227BFAC5C3E6DBD -:104F5000241C921889C2387659220FD2715AF3AEA6 -:104F600050F4714C8F6AF004C3088F2433782431D5 -:104F700014B6F2033F2832BF85D60F8590B71F24A1 -:104F800060276AF0B5B9230D4BC19ECF93104FAD8A -:104F90007EE379F96FF8BC5EE4696B9A733F02D1E6 -:104FA0001810BF34B61AEDD096EA5A17F0A542424F -:104FB0002EF0D7B7FAACE389B4D46C77C6A95D0AF2 -:104FC000F9766A9742DAEA7BB20ED69DE3C0C7163D -:104FD000E7DAC37A2E642349DDFED35BEE214983F1 -:104FE000FF348170BA957CC37767B0C8D0CE315694 -:104FF000447BBED5674B40A8D168F0B773F8B57A4B -:105000001D62CC2567B15F76068DF09E3DFCB1F642 -:105010005E479F6C05D76785378DAFCCFD4B05523A -:105020000CED623112D4F3BFDDC1F8542A70C5987B -:10503000BD9EAEDCC3DAFB6839D8C5BE8802E72F57 -:1050400054E4314ECC0572A0C3CF78DEAED5C1CFCB -:10505000A3490CFDB582126B003E72154B783E6081 -:105060006EA7A51EDEBEE393EFBC8EF231C685F2BD -:105070002128547E2CC6795C0C8F75D074B3181E11 -:1050800007A9E3943D6A2527631C4C8E5D9188E255 -:1050900062A12696F0CFE4FDF66AF0AB313CF7CA88 -:1050A00016FEB22CE19F99827FBA6316C2FF39487F -:1050B000D3C13F8DC3534042FDB06F0706857E09C3 -:1050C000B95CD19FCBF5F07E0B387C84DC8474D343 -:1050D000CA3B391EB29DCFDC2CE7D3939A4F1D9F5C -:1050E000CFC24CF3F9029F4F8F83AD57AEBA8812EF -:1050F000A47C959F862ECB79FF5B87E972D319F14B -:10510000D557B39CC7F2D43C9672BE5A96691E51CD -:105110000E4FAF9DCC3902F13313F97A43EA0D7487 -:10512000D9AEF19593AD1B84DC6CA0CB3DBC9F6CDC -:10513000E7B33ACBF96C4FCDE77B9C2E77649A8F1F -:10514000AE7E13AFDFCCE50AED96ED8EBDCD607F70 -:105150003C2E46DA1DB352E3D17A1DFA7AE3DBBA6C -:10516000B47A6BE1BBB078B85E371F9FDB450FE1C7 -:105170007EAC0D6C0C6ADF7CB1EDC55AB0C769BB63 -:105180008DD87F84AD9BB4DDDDFAFE67B6DDDBCC68 -:10519000EBDD07F59A2E3DA5F5BF59DFFF764752A7 -:1051A00083631BC25137DCDFFDFA7ACB1D7DCDEC6A -:1051B0009CB0583EEAD5D935C1ECCE7D1C81687CC7 -:1051C00000FC95C4DF0B7647BB18DB3E00FC408D2E -:1051D000BC9DF4FB6DCEB020D0F5530EC71E817A76 -:1051E000F9AA53B603DD6A633F82BC6A2311888B38 -:1051F000BCCF7BD776C8AF115DB23304F696824739 -:10520000433D0111E379DA84A80AEBE20931FAACF3 -:1052100003ED1EDA251DE7B60225D12580FF96088D -:10522000CCEE60706DF05E1D07389C142E880F6EFA -:1052300033C145C7C37D79E718166F4344522E42E8 -:105240007F764F08FAEB1F732BC21B6F72CAD03EDA -:105250003EF95684979645303ECF1143783B1C2E3D -:1052600019E2F1EEF3AEDA0CF1766BD45CAC8F7030 -:10527000C0FC279621FC6E124B2E2D05F5D51BB6D2 -:10528000013C8B258C4B8E0736E2FEB66B315DE41C -:10529000E8B85DE51B5568777CB107E3EBDCBE5EE3 -:1052A00002F15605974904E280DC815EB433F317BE -:1052B0007958BE98E038F99F67F1B20E322097D145 -:1052C000B420CEE28EBBCAEBD5A560C754B37854E8 -:1052D000A2865F86F8B63CC2FFECC5FDD0BF63BCBA -:1052E0009DD84329FA16F40EB7CF8D5AC8CB70BD9E -:1052F0004496F592D9D5CB8F8BD9D5EBCDB25E2222 -:10530000CB7A4956CF492ECFB58AF718E6FB7912EA -:10531000DA1F5A7C5B0EB5FC87ED935266B7EBED56 -:1053200015079152F60AF0997D494638D6BCD51436 -:1053300038A0B36F02923F80FB8D0BC8052897A35E -:10534000B43FD1A8060E38469F2F485852E7271F72 -:10535000ADFE5AB0F79CE9CBBDD3AF08A23E9BF699 -:10536000359E2E616925FD5E016903CF7F8DE7972C -:1053700034842DC6AB91981E2E27918C747073F8CF -:105380008FC2993F6D522ED2FA16E7E35AEAABB0BC -:1053900099EC46A3BE73896A2D9E7394B3F8412796 -:1053A0000823C84D88A07E7190A45C86E78BE19CA1 -:1053B000A56353F2E3088E45F9F93F85762254231D -:1053C0007D428047339F98F9C267E28B4FCB2757C6 -:1053D0009D253EF1C6ED59C98FB737CB7A892CEBA5 -:1053E00025B3ABE78B0BD9D5EBCDB25E22CB7A4997 -:1053F000566FEDBF48DCDF7A590BF861BC5F74195A -:10540000F26BBFE831967FC967C8772F34B6F72DA6 -:1054100032B6EF5E646CEFBB8CB57FAAFDAB9782B2 -:105420009F275B39F9DDDF2827E5AECCF5F3178F31 -:1054300022572E15F7936E5121C900AC5F749D124F -:10544000300D272CECBBE7B9FCBFE0607E9CB8A810 -:10545000E2BEF69F7D9E3F9098DF489BEF68F06A22 -:10546000FAF7F7766E6F99EDAF61BFCEC9D3A76734 -:10547000831E21102C4D64854E8DEA1B0FF1842074 -:1054800054C4539EC0F36973FF5D705EC7FC2EC1A8 -:105490007A1D1CCF3B995FE5E7A5ED413CAF9DBA76 -:1054A0002B08FBF4AE0982A59FE594C4CE05CBA2E0 -:1054B0005EB4333A1417EAC3AE09EC1E5397238146 -:1054C000FEE3AE52637B17B71F4E496CBCAE3B6325 -:1054D00004ECFFB6A9BB1A605C67F25F8942E1FE8B -:1054E000EE8418C68FB63BD93EC0195609AC0B2EB8 -:1054F00045C5F377333C712D6E882482F5BA79D790 -:105500003B19DFFC9CCE279B79BD2B49585F0E339E -:10551000FCA5C3D7DE33C4D7B54ED6AF127423BEB5 -:105520008E57135C4F8090F6D9048FC6D9DF20D1F7 -:10553000F387793D060A337E3B8D7945BC2A233FAC -:1055400099FD30CAB6AF65E4E70EBE9E3BC9D7B140 -:105550005FA7120B83BEF35624C832C42F0993B140 -:105560009CEF14F8BF56D546E5977241682B6575D8 -:10557000EF98CE50D2227E6998FE1592515ECE7081 -:105580003D9BE9A4EB9937B59E1D27DDE884EDB678 -:1055900091EBACF0AEAD674AE0AA8CF3EE6A647EA4 -:1055A0002B42EE207D309F57EC481F5B395137501E -:1055B0007A392B443CE7704E4A10A0B3AB9C24DDF3 -:1055C00039E9E7F51AE73B259879DC1E8EEF6E4E38 -:1055D000A774F5BAF9B9E76B1D0FB5C0FE2D6F1EA4 -:1055E000938361BE171306FE1C92985FA3CBAD3464 -:1055F000613C4B29F38F8C983787D32C57F134F7C4 -:105600006934B9FDABA4303DE44AA0DF41932F4596 -:10561000F957D4735D139A5DC0D471E541F4131F3B -:105620002F9708DC8331EB032DD5ECC84B48B70B23 -:10563000EE2BAD7DC51EEAB280D70D44D0F9F5CC76 -:10564000FA7A347D72DFA7D4273FD1E47EA43E41AD -:10565000FA5CDBD1BA1FE8D3E566FEEBFC3A952C89 -:10566000D5CDB79B8FBFC4C9D7856206479743AED8 -:10567000D1D3298F7EAFD1EBCD34F44947F72B211D -:105680001870560A0EF3FC763959BD7C18BF627447 -:105690003C8CA403C3438BD39A0F3EABF9343BB38A -:1056A000E3E36DBCDE368E576D5EA3C989D67F1FDE -:1056B000C757DE3C93DE175503FDED1ADEEA4CF5C5 -:1056C0005CC67A1A7E4427B357B47562B4FEDF967F -:1056D000187F98FB4F2787BF19964315FDB2DA381C -:1056E0004EF21CFA0F8E53BDDC5549F7A3BE418C18 -:1056F0002FA07B7D8C6F82F82FBDDE35EB2F4DFF09 -:10570000A7D347E67DCB68F5A58094D14ED2EC9A1D -:105710007C7E6FD2C5E381370AD6E73C435C8EA816 -:1057200062CF2AAE0FC244001F2442F8FDBF707F33 -:1057300013CD8F0D494A17F83FC4F9FD3B687ECC65 -:10574000CF9CA42B042E9779FDFD94DFD6865D11A6 -:10575000281FE72A1DBEA7D53B1BFC5ACCEE22F61C -:105760003B5E877BC063AF1409E0D549E6609CF6D9 -:10577000F13594769523E1192B12323E9FA6DC3F3A -:1057800080E787B0A5FC8A119F64B12E0F7E6097D9 -:1057900071DDCB76DE6678D2B51B159ED43EF4085B -:1057A0008CEF2499D7B5339DDFB05D9BE5BCB4FB8E -:1057B00068DAF7D2213B51E07EFB9080E939435E05 -:1057C0004C4B86DC984E182A200A255AF1501EA60A -:1057D000E387C6E3F7A2A1424C0B8726621A1C2A74 -:1057E000C5346FE87C4CE5A1A9986EE072983B3413 -:1057F00013F3DAFDB79CA14ACCFB873E8FA96F68F3 -:105800000E2BE7E7A91BEE8C12F0574BB00E51F9A7 -:10581000689BBF1CD725F3BC36B8D83ADCCEEF095D -:10582000B79BF4761F2F7FCCC5E47E03970B22C66F -:1058300088DE6F7E3FAFB7A12C8AF677BBB61E1607 -:105840002E37AC87E6FAED69EE273FA395737848CB -:1058500079FD28F461E7AFCE4014EF0D101245BD7D -:1058600044C4A841EFB66BF067798F70C3FC6790B2 -:105870008FDD549021B4D0FD856D0D0F83DE5970FE -:10588000EB7507A8DC7DE88CDEE68271BFB002997B -:10589000EEFBAB6E0F82DF77C3FC7BF17E1398DFEC -:1058A00010D7DCB1E08ED8C3C87551B4B369BBBBA7 -:1058B0005CBA73D0CEE5B737ECA2FD29AD36A2E8CD -:1058C000F8B5E40E0F51F4FAEB644121B42FBE2574 -:1058D000DFF0BD686591A19D764F22784D99A19E1C -:1058E0003CEF3C43BD9CB9338CEDF839B9AFEA428B -:1058F000433BA74FC32B3B47A4F437AC1F1D823556 -:105900001D632EA62FD3F1CD152EB6AEA5FACF4C22 -:10591000B774FD677B2F24C51F69E781E710B1F8D5 -:10592000E279604F39E528DE5339F3FA67771ED9FB -:10593000D633EBAB1CD05705A04F044C7DA0AF0A6B -:10594000408FB831D5EA9DE97DDB75A06F7C3A7D4B -:10595000338BCABD053FF8DC99F5CDF9BC7CB29B11 -:10596000E99B759CAFCC7C13E4F5D681BEA9185D8C -:10597000DF04DD99F54D251FEF1FAD6F3A67DC1B86 -:10598000FD16CDB92FD8D6F0104D3B2A6FC53CD5AA -:1059900017A29B9677CCBE23F6904E8F9093FFC9AB -:1059A000F892F3436EB5517F68FDFB43263DA2C9D3 -:1059B000C3DF28D7A738BFA6A3CF914F29D7A7CE3B -:1059C000925C9F7275CD83F3C56CE57A64FDB33B41 -:1059D0008F6CEBA9B5247909EC4BA678122DE0BFAA -:1059E000B4F586D8BDBC28C6ED743EEFE07E1EE659 -:1059F000FF9BE10A2F02FE99E18A2C76D3F63797B6 -:105A00002AE3609DA6F92FC2775D3E62CAD79BEA62 -:105A10007FC594BFC254BF415F1E57947170BE18BA -:105A20003FE4C0F3C1B862ABB3E2A7856EC62F876F -:105A30005C9128F4776EE2BC7140179A5F86FDB9DD -:105A4000597F347F8D29BF1CC74FE5AF3395AF30E9 -:105A500095AF34E557E9EB779E9A781FBEBFF14BBF -:105A600007D969E14F7A95EB898EC9B7479B995C55 -:105A7000DE06ED3BA6DC115B46902F08C06DF79962 -:105A8000F67F94CFF4FC7288F7F3F309B7E2BEA96E -:105A900083EE9F308E11FC7816F8F9B59BBFC3A535 -:105AA0005C8FF71FE28537A39FA3A3B819E3148E79 -:105AB0002B129ECFC64BADDB7736323F5347B1F545 -:105AC00039C2AF210857678F9049CCFF076270DA5F -:105AD00006EF0931FDDE56DA8EFA554A5ECFFC1B21 -:105AE0008551F46F3CC8E927F962E8577016C72C56 -:105AF000F7F51DC3F830FA35F769F8E0FB481D3EAD -:105B0000500E9B3B3F3C00EB6BDC6D2D673F7633CB -:105B1000397304B31B7FE4FCD9FAB01D2EB558ECE1 -:105B20006BE30E1627AF4E607E00918EA3F72B9885 -:105B3000C71B9EA7699FFD00C753DCCDE2ECB5FEF5 -:105B4000CCF03CC2EB3DE2667E056D5EA2CCC61990 -:105B5000ADFFE7E0B216F80164B31FC2A8E7EEE0BC -:105B6000F51D0163BD74F8B973183F2C1E4BE3DFBC -:105B7000D1F85D1BE710C085FB59EB7DB872B21AF6 -:105B8000E3378E137F6F17EC9B45F97588E3B88D6B -:105B90006E93C0CFDF22AAE85F501522EFC4F34F07 -:105BA00076FE709BFDBC10E83B178FAB20105711A1 -:105BB000D0C525829FF35C8CB37804CAD7A84E1950 -:105BC000DE3719724F6471AB27D7603C4527DDA9DA -:105BD000C3B827DC250978CFCA9EDB8DF6BCDD5E15 -:105BE00019B38A33153D8C6F2F39B91EF56CBBC2C2 -:105BF000EEDDB48B51577E05B8AA5594D74E257368 -:105C0000FCA2390ED2219BE30F8DF89AE661F48D48 -:105C1000F3F537EE0E35E8E393821E37960FB98D14 -:105C2000F075007C3E802B86F1A4F1629B0DF0762E -:105C3000B6E0D3C6954A6D11C04B8044315EC515A0 -:105C400014715C9B97E137DDB844113FD0BF1F73DF -:105C5000B6F039BCFE46193F89C483FCA4CC73D589 -:105C6000EE86FCF3CC2F6F1EE788277A8147E71773 -:105C700016E528FAB7B4FE168E6171DE6231C1FBFB -:105C80008A1289D495D2F9B714B3771645DF2871F3 -:105C900011C5667F45BA7339763E824554446BFE22 -:105CA000C0C6F5F078013F19C060D15C50E91321FE -:105CB0005E4011D83B102181C595CFC538F280FBDD -:105CC000B3EE7709F62B843790D3DE33E8571C40C8 -:105CD0003FD767DEEF28F0BAC936EC1742534F17AB -:105CE000A4FA05FD8B4EA593A74FC3B9999D687F74 -:105CF000CC0E176DEC5E1529CAC1B8C3B6C0CD2E47 -:105D00003D5D9B3C6586F55592DB6F1272E0DEE7E8 -:105D1000CAF04006BE6C0339023F62F135E181F200 -:105D2000F4F53438453A7D2B7F68BB144D3481BD82 -:105D300058E263F1AA620CCF473A84FC195D553AE8 -:105D4000FE2D96920097BF2AAC423C6347812D04FA -:105D5000715822E93E8CEF3BD9178732C9AB582CDA -:105D6000BEAF9FCF568F310EA465147E6FE3FA3A13 -:105D70005DB9430A45ADF4F0131EBE8E79ACCB3F3E -:105D8000F6D63EE6B15877F6723DD5914755E9E72C -:105D900018FB001F88C5075F073CB48D5990593F19 -:105DA000C946FDF45FDEF04F609C0C703C67050750 -:105DB00081C714B2B0FBE579188C988A070A30BE07 -:105DC000863820612C9CD2B2BF75550F26C1EE7665 -:105DD0002CF585817EF6F06E02EBA81617640F7B1A -:105DE000DEB1213DE7B2F8A072E6670DD3FF308E39 -:105DF0006C6EE6B831BB29FF2B339D1B9FC5F72284 -:105E000034F8B53875F3BC9EF2D6BEED9965858F32 -:105E1000ECF6419B28BF10CA2F1BE9FA4E91427A3B -:105E20001B65CCF7340631DFDDA860DADA588EE97D -:105E30005A683A07E23F62F152D88F041F0E5E4B58 -:105E4000AB6C029A605CCB8EF9B08FEC1ACE135516 -:105E5000807325B81F4FEDD0BF7A36CEE7E76C3C94 -:105E60006EB67D3E9EA30DE7B7B4815DD8C5E368ED -:105E7000E5B50FCE87FDE3A609DA3E39ECFAAACEE6 -:105E8000FE9AEC75B073A652AD7D4B1BF4E7167904 -:105E90009EEC996FCC9330C0E376B1FC42EFD3080F -:105EA0000FAA003ADEE5DE6730BF6932F73B54D413 -:105EB0008F8247E6C768F728CC0EAAC8473F8514EB -:105EC0000AC1F502B2298FC39D653FB0FFC1F5EE4F -:105ED00015EBF5322537A3AC6B1C8ED1E84FD18181 -:105EE000F605E86115C67DD58EF270B6C7DDE438DB -:105EF00033BC48D5832A5CFDDAE7895EE4A5EDFD75 -:105F0000E1BE6429CDE72C4EAA28BE598E5BE8E598 -:105F1000F7C9E87C41FE353C6B76C74D40C731A9D7 -:105F2000FE1C8130BE23E1E6EF09670BEF728F6C38 -:105F3000E8873C5E5B98E9DC654CC4064146C3FAE1 -:105F4000A2A0CEC38335583E2F9C6FC8E7561719C1 -:105F5000EAFB43658672877C9EA1FC6FA5D3D73D83 -:105F6000B281AF23A679CD379567DBAF7B8D5D819D -:105F7000F7204B45CD1EDD88F7928F038E413FF60B -:105F800056E23D5D3249BB8740C210AFE256C2C8FF -:105F90009F1E12C2755A2A36DAA962C068A7061B6C -:105FA000D4A4D62FC425B8D74838EEF03AE563F12B -:105FB00020DA3919EED72782AAFBDEA152D6CE32DB -:105FC0009E414B457E5E8677EF4B473F4F358F13A3 -:105FD000FC4AE63835737DE21395A33AF94BDF4E60 -:105FE000244775EF6AEC00DACF4AE13FBC7B29FA1F -:105FF0003D9C84DAD114CF2DC12B4894CEB31DAA79 -:1060000050FAC521A57CDE1E9C21631CBEC2E86A35 -:10601000733139F98E5731C473D87D4C4EB47AA39D -:10602000D1FF363B8959AD67AF7AD93EF9C45DB12E -:106030003FC1FE527D99E03BAE7D8D43F8CE655564 -:1060400072A11DFC26AF7BC7E27CAA0E84ED97EA05 -:10605000FAA922ECBD6FFA67D7FB5335FF3039E957 -:10606000C2B8E03D491617BC27F9DFFB4F43FE904D -:106070000DDF15DD7338B37DD5C7ED2BAD5EDF21A8 -:10608000B65FED1389373F939DC3EFBF55264D7122 -:106090008722B103FD4FDCA9D8C1DEE96B7409B0DA -:1060A000EECFE0F3AC4A86EDB09E8E36AF7D26FA99 -:1060B0006AF384FB8730CF561FBB0FD82AD3F9224F -:1060C0005FB3F7B2D3C13BBCEF97ADF121F9D9BBB8 -:1060D0001792232A5BCD7BB47B8A1A7CED009F004C -:1060E0002983AB3DC0E8D01ECC4C87160E9F56AF1F -:1060F00035C0E8D04AED836CE0117D4678A88D2745 -:10610000805DE823893A7CD34C252FC33E08558512 -:106110000278D897BC1FE0857B1760CFE75509D779 -:10612000C2BD8F28B30FFD55C9E4DE009A2711B810 -:10613000975130D09F7C9B961F6CF0E2634FF2B575 -:106140004792D08F280FA2FC74C160681F4D6C0766 -:106150007BA70DFE4955FAB8EEE002B03F44C2F409 -:10616000029538451CCBED130B79D79DEF0BA79DFE -:10617000A976E9F066B63B9DA43EB3BEE2E7FD2AF0 -:10618000FD0FF48D6CBA1F61B673CD71F017813EAF -:106190001F93C53D8C4F394E2E79D005EF21D8CBBA -:1061A0006D32BCC34C557A1EDCFFF1864502718D01 -:1061B000B9BE017C3A6B34BC53FD57C7E246FB883D -:1061C000FE1E69BD8FF98102F55582C0EE1128F0DF -:1061D000EE66A0FE50C88A4F35FE1CCEFB9E44FDE5 -:1061E000D8461271883B51EB6CB8AE759597E5E9CE -:1061F000F74737F904BE0FD5E84F1471768AFE745D -:106200007E61F7F4BF1FFDF3171BF17EA674B9D3AF -:10621000C7F4D268F4FFB4E368741B291F4D9C6E69 -:106220009B50FF754ECA4EAFA4E8F620CAABB79C90 -:10623000841316ED9A39BDCCF7F65D2446E0F728B5 -:10624000ECAF307BDA3E6E76C30E92812E23E2AC49 -:10625000583F761FF3A7AD133C21186A5D1AFFF271 -:1062600024BFC0F5FF008BE79B733008E7C7DDB3A1 -:106270008E06E19CA3E713EB73C8857E7E2E127E0B -:1062800003F7013DB3985F10FE40EFDCC6FE49CA3C -:10629000D4F736C33B66EBDEF21AECA1F6C6CCFEB1 -:1062A00006A9E8BA28D81927DE1114586F84A23538 -:1062B000E7025CFD7396E3BB23ED55FBF01CA63BA8 -:1062C00094992E5A9C6FBB29DE36DDB9E1092EAFB9 -:1062D00065EA0D685FF614BE8CE3ACABCA3C0EBC3D -:1062E0009795299ED7652351F4179BCE75DFE4E37C -:1062F000BDE9E3E7138EC8972696C2EF72A8E81FA0 -:106300001B5B1EE9B751BCD5FBA3AFF9285D7BE64B -:10631000DC5A0870C03B317ABA07A07F0BF8C6FA86 -:106320006D06BBE94459ECBFEEAC82DFA79882EF63 -:10633000D66BF5BAD3C4B19FA7D15971E3BEA71DDF -:10634000E2FE297CDD85D9E15FA3F325E405D7448E -:10635000680F71BE19F8D9BCDE8F8677331E7A1CA0 -:10636000031807D52358CF67A19FC95DCF9D4976F4 -:10637000AE36E7289EABF9926F60FCC477671DC606 -:1063800073B5123FA387DF378071A539D5EC3DC0C7 -:106390007472F400A79F281BEB1171C070EEB3DD7F -:1063A000C7CFCB0299FBD3E024AE0176DE33522E69 -:1063B00071FDD9D9FDF0417C378524F15CA1FD55F3 -:1063C0003BDC4D1DC6C308B98AB3DF85E9818DC7A3 -:1063D0008530CE5DEDE027E9D1CED92AD9BE49ACD2 -:1063E0004AE2399BCBAF18E3AF43DABB88D9CDD3B0 -:1063F000076B11F30F8BB0AE823F1EE06BADBC029A -:10640000FD69E9E8FA1D6F74A67F8CDEAFCFF65DFB -:10641000FF6C7C78C2A718EC43333F3AC937CE688B -:106420005F97CEBF7C82CB67002AEAF649DFF44B48 -:10643000D6F87DFBCAD1F0FB4D6BFC5EE501784FD1 -:10644000DC63FDFB445ABAC5A4EFB668F128F0231B -:106450002185D85FE9E516F3D6D6D5137EEDFD9EEE -:10646000A807D68D3275AE07C6DFD5BDCC03E3EEE7 -:10647000DA9C999EDAF8DBF9F96282DF77D1CA13E8 -:106480009C2F7798F4FC2B5CAEEFE7F2B5CB15F1BF -:10649000E0EF55ECBF6AD1548ABF32CA17E05254BC -:1064A0003A497EA6F14B55D3BEE40CEFB5F4F84D56 -:1064B000F1BD59DED3FCB478D901FC7321E0E1DFF2 -:1064C00051EEEDC95C94A7B2958C6FCAAE194CC25F -:1064D000BE76E2265B42C1389628E2A570A5A86088 -:1064E0004C1BBFF77A2E5FDF89FD0E5B0994C3BD9D -:1064F0007119DC2EF2D7301E669BF1F73F76B9C2D8 -:10650000CD12D8BF718C742465DDC6DFCB184F74F3 -:10651000BF5741C72D7CEB3DFCFD9442D3EF827CFD -:106520005ABCEFFD07E13D21128F5E1F2B028958F7 -:10653000E9FDFFE47CA9341D60EF18C47CE45DDD57 -:106540003907A55F3ED805DBD58D35804F354E42E6 -:10655000932DF4D86FFD5EED777C0EC03B0B8E6201 -:1065600076FFAC6DE915037BA9CADA7E472DB13AF7 -:106570005FA17AE1B77E5C9F985E48A8F52C3D69E3 -:10658000473E99DC4D12F03B28F336C5FA1D20EA50 -:106590002BD93BD48571559068BE8C9AAFB47B32B1 -:1065A000F13AC2EA2F218930F211792D3836F57B84 -:1065B00027250337F5C3BEF820DD17C3EFA868BF52 -:1065C00057A2F1CBF898913F26C78DF971267E31FD -:1065D000B72F53C822187F52B78DC0BE6E4C83AE02 -:1065E0003EF44706DF7B848E3FF9003CCC48D3DE87 -:1065F000CCFD8B24EAC8A1F87CFA2EDF2FCBE9046E -:106600001FEAAE2D00BCEC721176EF22E2C27717C2 -:1066100048C4FA3C6904DF6A767F9AFA297DC9EAA0 -:1066200069EB5EC75B027BE7A2447EA714FC9CAFCC -:10663000B1DFAD4BBD5B7121BE5B112431663F9272 -:1066400008A6AD9C3FE54B8B4BC11F1A7FDB2BC3CC -:10665000FD2CB9C0E84F13F3EBF03DB061BB3B9F9D -:10666000DADDB43C9E67D4A33539CC6E0DE5B07B42 -:10667000A1B297F5435C6AA15EEF6FCA118CE53E4B -:10668000B5F0CBBAF25ADE3ECEDF2DBF24675107FC -:10669000D833F2785ADF823FE7F171B57212081DE4 -:1066A00086F73F367FA37E967E3DDF94C3CE77E4A8 -:1066B00073F8B8C5D670C54BD9B877F37137E518FC -:1066C000DF8D23324BB5EFF7FA6F158E507C9F703C -:1066D000905A88576919634BC0BB69B78DD5E2C220 -:1066E00032EB098D0EC3F896593C52D175F20CBBB2 -:1066F000851C6BE9D63AE6A7327FBF9ACFA3F5BADD -:10670000DADE4914AEF0012677CE00B13C07A2F2E2 -:106710007D75CE2C8B75BFB50EF77127F232AFFBAE -:10672000E67DAEC8FD8BE67A4D9C4ECA2B417C8A35 -:10673000BB35C8FC895AFF270A995FD1DCAED3D498 -:10674000BF9BD48721CE18CE57E15C559A4412499D -:10675000DA8F27D02B972A101F705885FD91422879 -:106760001EC1CF162268D7B506D97E540CF6D6D8EE -:10677000209E84D4C97A3BAC88FFAEA29677F8A25B -:106780004D39680F8505C48BC8CEF34F38120B0105 -:106790009F2DA53662F54E7F770EB373B72AF52F7E -:1067A000965AD06F438E62B09F8B8698FD9DAE7EC9 -:1067B000AA1E836F981F832ADE3F200AE3C77A7FD1 -:1067C000F89E1CABF35B4DAF703FE4B26AAE7089CC -:1067D00072E5AFE93CAE3FE4C0D8F44B4E6E3F08E3 -:1067E000FAD74EF56F17FE8E5CEF41F0435E03F76C -:1067F0009F68FEFAB7A64925B4FCB5223B7F743EDC -:106800009203E37E486CE82FF990BC9C335347BF5A -:10681000A77224B6DEC41DA847357FDCB5BD0E8344 -:106820005EFDF666637E39A91F0B7E8AE59B1C24FC -:1068300041F17BBD49EF3E94C3CE89BE4D62EDB0C0 -:106840007EB6F1F3BF1B7F324D02B9B97EA65C6AFA -:10685000D7DDBB7A2E87D977EF533E527472B6C21A -:106860009790601FF7EE9E99577C9E403F89F622D5 -:10687000F0A7E559C7017E2B6E8473B47998E1D6F1 -:10688000CEF3D2C121EE162CFD42CFE708067F7C65 -:106890008B8BBD87146E1189FB6288C3A3020B70BA -:1068A000BFE5C7F7BBD5DA18C6D5A9CD4EB9258047 -:1068B0007176184FB786120CDE1F3ACAF94F8BABB0 -:1068C000A306C505B04FBBD13520815F79B518ABA4 -:1068D000839F4ED3CE659C8E68783C85DFF16C4DEE -:1068E000723C31D48B6759EF90509655BD3A5B8618 -:1068F000FE8E713DF98BC71F9260FDF9F0B177BE36 -:10690000087278C373760257F38E3DEE2749DC3F59 -:10691000242490F3157BEC96EF48508C61FF37FCF4 -:10692000C88F7A71C593CEC462DA7EC533EF4E2725 -:10693000549E8E350F1E1C0FF87B4C60E785EAC015 -:1069400074589F5688E49B56EF8EB97399BC7FF0BC -:10695000536F03D04FD8DD7F35F6DB77A543FF2E8D -:106960003EC965EB0FADC7E2261F1512932DF487C4 -:10697000B61FFAE0511657B2E2594702428257EC6D -:10698000DE2145291CAB777F84FC72E98F9EC8010C -:106990003CAC7ED66EB0236EF8D127ED17523ADFAD -:1069A0006027838B418EED27317F3CEC1AB4A35CCA -:1069B000B3F89455A80268BDA77EBFE0D7B4FCFD2C -:1069C000A09D4088EBFB877F273D07F9A88F5A6E73 -:1069D000D0BF91AF57EF7E57C2DF31B291C1E2CF46 -:1069E000C3F987D14E32D7276450023DB5BAAFF311 -:1069F000233BE5B7D57B3E7C13F86EB5493EDE8779 -:106A00007F148EB4CF2B734DF6F9EE82ACECA31B42 -:106A10009E38FE00F8233E78F28F0FC03DDA95A72E -:106A20003E7EE07B1017F66F6E19E47BF563AFE6F0 -:106A3000109DFEBF2C97AD9BC71E7D64D7563AFFB5 -:106A4000636F38115BC7F6FEBE04FC3FC77EFCD700 -:106A5000B1E00FBA65EF7CFCDD9A5B9EBE745CA66C -:106A60007511F835A1FF7D457E6EA43C2B80314920 -:106A7000C8CF786AA207E91D94605DFB8B4006BB16 -:106A8000F2E8F7BE4F24B0CF0E86C920E067FF9E24 -:106A9000770FDE4EF31F52FA382DE843E73FDE86CC -:106AA000FA998A0D4D57EDF9F2972EAA82D4817684 -:106AB000F86A32887A73045D5FA174AD4AD1D55CFF -:106AC0007E9C9C94E0DC60F5E3948ED3819E948E52 -:106AD000D347D2F143F8C79C91745C916B8C4B3ACD -:106AE0004E566EDF0A857B0A2CCF79B57DD68D4F49 -:106AF0007F35A3FDA4E985D1F07C9DC0E09A9D1B64 -:106B0000BE3D17E4EBC91FECDA1A60745E4C1173DA -:106B1000EC89E32584F2C91F1C8357031E06F73A4C -:106B20006558DF57ECFD15CADBB1A75F92148C6F77 -:106B30002139C26C9A27C37F2F139A5F25B0CC8D61 -:106B40000FFFBF056FD2F637C2431E32D20FF307D5 -:106B5000A9FC213D1297D729A077136370DEAB12F1 -:106B60004C2E5625FABF02717D66BC3F956BD3F45F -:106B7000FF305D216E6CD59E771600FFA5A3A7366A -:106B80007F19E67F012D7FD828B769E594D3F7D820 -:106B90008E1312D807C9E724D946EDE1638E410967 -:106BA000D7C71FDBE59DA191744FE19FC71F9DE1F2 -:106BB0003EFC876639E7F8194DCE479FD799E16DBE -:106BC0005BAEC2F65726FC7D70D25AFF3FCFF5C6AA -:106BD0002A12AB2B9A3872FD1249441D5F9A82F734 -:106BE00003881FA3F07EF0981DF787ED7DFB518F82 -:106BF0009BF5C5AA3476F49BB9CC1E58F56CFF748E -:106C0000D06B1FECFB29F2E5AAC7DF91C07F737040 -:106C1000F753D240454A0E607DD0FF0ECE073FECC1 -:106C20009F0EFA6B759A38C0DFF3F9ACFE99B1FF8D -:106C3000D58F7F64E8FF06B54F423FD928E3BC2FCC -:106C400086AF84F9BE7FD8012718E4FD3E7B9D9571 -:106C50009DF3025F1F353CB5FB67BF9E0BE75EF9F6 -:106C6000EC1DC6D6A6F0AFF0F77B5F72F0FD6DF8B5 -:106C700075B0675AF224BC8FD0EABF02FDF55A7F87 -:106C8000BD267CCA01B906F603F2BC48957E5FA515 -:106C9000C19F17B619E0BFC55F374EF1B1FD9942EC -:106CA000F71FFF03B64D466E008000000000000095 -:106CB0001F8B080000000000000BD57C0B7C54D516 -:106CC000B5F73A73CE3CC24C2627AFC9D37892F0C1 -:106CD00094804312DEB40E0491226A505AA9F5AB97 -:106CE00003F28821C9A4F8E25ABFCB8444F4029F7E -:106CF0008D95166A693B70A152217690A0B10DDC8A -:106D0000012C06056F105F78B18D5A152B24631482 -:106D1000B4575BEF5A6B9FC3CC9C4C84DEFBFBBE2D -:106D2000DFEF0BBF76BBCFD9679FB5D7FAAFD7DE02 -:106D3000EB0C28DEDCEA5400D93D6B366461AB5ABB -:106D4000D41409E02BFABB2AD6028400C603585D8E -:106D5000D5E07761AB5A407300FF7D45FFA7785BB4 -:106D60007BF0F97BE5D4D6B5348FB5F157D48726BF -:106D700005B657F2B0914A25DDBFC2BBB61860A375 -:106D8000F39F1FA7FB2B8376D58E6D73EA3DBFA5BE -:106D9000FE0609AA65EAD3F3383E6875A8DB55BC40 -:106DA0009E0E0BC265317AF25424321BA00CE9A06E -:106DB00016FFFC3001DF2B488266A8031C0129590D -:106DC000A120B5C6730FAAFE62757CAC2FBBBAC1F9 -:106DD0008FF35E2DBB2CB4FE07732D217B31B537AD -:106DE000A641D9403E18ED03ABAA213262F0FBADBB -:106DF000D98E855B80E90E5A681D9223B49D08F1F7 -:106E000081A67A8069030DFF873C74C4D18D037C11 -:106E1000B40E45BF6FC565D14D3B04B94D213960F6 -:106E2000EB84084029D2AD96B05C52A1479F240A5A -:106E3000D563006E4CF57F93D6993BB451A2EB1EFF -:106E4000A8E6B612FC12DDB738EBF2FC5FB33E5891 -:106E5000A09CE919A9CB175FB1C12AF8AF28A00CF3 -:106E600029273A36ABEF8FC679E87E268D0AB21C09 -:106E7000C6557D67740BC181888FE3F32333676444 -:106E8000126E8C71CD8EA29312F2DB27A7A8294532 -:106E9000D8579033C4A753A9CCA71F4DC399F1FE6F -:106EA0008F4FA56E95511E8F48024F41C213E10AC4 -:106EB0001A1F277CB8113F6BE9B9198DBF65BC5803 -:106EC000A0BAB952E7A487F827FE106F8CA7958A5D -:106ED00043B57B89B73E4DA1796C105A2B11BD7E0D -:106EE000E6A7035AB91D02616E5DD0CDED5DC4E722 -:106EF0006C928397FB69D0D33A149F9BA356D7AA71 -:106F000078FDC7B333245A9F0B549DBF8579D41F96 -:106F100094BF3391BF8E187FEDC44FE7407E3A4057 -:106F2000653EA47BC1BB761CCF0B115CC723D3216C -:106F30002433885450112F39FA3A33C127117D84F4 -:106F40001F5A5FF602B13EF3FB72A195C7E5439865 -:106F5000DB42E8E636C3A14A0AD3734A97EF3BF017 -:106F60009533468FD1DA09C138FFB9429CBF98B931 -:106F7000ED963CB47EE3AF9A71F887CA83BE2A1CB3 -:106F8000A7F85D3E3B2EE5FF54CE201082F572053A -:106F900048AEAE9E8573C18DC3BD36888CA4D9839F -:106FA0004C5FCA48D137EC8B1D051531E8C7E7ACFB -:106FB000A73E3C45CF59216E1CD121DF9A467C7FEC -:106FC000982E4C1EC8F795A79AB29E8B9B77AB9ACA -:106FD0009A45EB848930F12B39F63C4CCA40233377 -:106FE000F0F9CF5605B39EB3C6F8D0E2F867C6A550 -:106FF0000F019CF24DEC138EB36238465CB29D0BD0 -:10700000AEB6ABCD598C43C6E94A64901DDBCF5276 -:107010008A42BC7E689C7823DA618BC3274978BD9D -:107020004E7587883FF5AEF02CB61326BB317DBE7A -:107030001AC9C7717D8DE025BE6EDC73C369E26B32 -:107040009F07347BBAC0856F02D909C38E8026A3FF -:107050007CD748E31C12B6F5ED1FBFF47B1C9FD212 -:1070600029838CF7FB70CDDDB46EC5974E4274C298 -:10707000FA04FD6E7608FD31D669D6D77F749D2857 -:10708000799E9FE52093FD5DFF2FF47C3FA4B6D24F -:10709000F84D0ABE9AE6EFB286B6231F561C911928 -:1070A0006F2BDAA410909C152D8DFAF7BE2883C0A3 -:1070B0001FF0FD7B7F55CA789461F48FA6E1F381C0 -:1070C000CD562F5A4C48F725FAABCCD943408BC349 -:1070D00001047D2FE722BF16EBFCDAE87C780BD1A8 -:1070E000B3A949F8A7ECEA8C84F19FA55C6F5B8A91 -:1070F000F36B7948D714C24DE7F035D85F5E20AB0B -:10710000329A889C05F989FEB1D5FA0EE99F86FF6F -:1071100008DF86FD5A4AF68BEC907C3FFBBF73205C -:10712000FC9F02C2FF35A0BD8AE07CCB3689E78D8B -:10713000F96A3A1F595380ED1DA1C4EBCB4189F583 -:10714000D9CFBA47921D580943BC766920FE2DE974 -:10715000887F02890B5C420E2E2FD997FE5764AFB1 -:107160005DB082F595F84E7644EE19B1711ACE17DE -:10717000E8B24248237989FBFD9BE550B038A61F51 -:10718000FD5D7B981FCBF2901F884F7B6E22FF53D3 -:10719000B444FE3B47667CAD3C52BD267ECA739923 -:1071A000FFC86FA0F9D32695243EAFF37B24FE13CE -:1071B000FCF6319D4B3B24784C223EAF3F5CA00D4A -:1071C000E46B43C72336D2FF8BF1D5CCC7D1E9BAE4 -:1071D0001DD1F9780E3A0FE8A8AC7678D894F03A39 -:1071E00014B5753AE1B410F5967062D66B837FD60C -:1071F0002CD567C37197D1385C5FBE232C94D10B1B -:10720000CA09C2CB2261779B551FFB23C3DE3A2FED -:10721000D8ED77E12B6CB3E6553E4438BA534A6D4E -:10722000952B07EAEDBA31F7B0FD2A5C8DF698FD93 -:107230006A629C165EE5F02E467A9E5C05DEC5C34A -:10724000009E5AA5726B8EDF0C7DDF8CF19B5DF882 -:10725000679E5741FCAE55C9FE7855A2F3611BB03D -:107260009EF69541682BBE3F1CF9D4A391BD2E8F8D -:107270005E5F8DF145600954539CF1AF1922AE7BDE -:10728000466F6765D8B85D5B6D011FBEA7B7530E2B -:1072900049485FAFEA3B7215D99D4EABC6F1951ACE -:1072A0007DE97B7CBF425D8BFCCCB3B48EA3F7E25F -:1072B000F8D9219CB7AFF35DF7ED717EB9B7E3D193 -:1072C000511407FDCC0235E124F1D0F2740BC73123 -:1072D000BD23DFF1E0B2A1DE11B501E2E9C19EC636 -:1072E0006A8AA7EE746A4C97AD7D7AA480F1338FD9 -:1072F000E3E3E7960E61BCED3D0321D2BB59F2AD4D -:10730000D78EC1FEE45715AF9D95CA77FDC2093CE3 -:1073100084E5BEE1CB8A4DC4BF00F273355F6C3D9E -:1073200041F27AF6CF0A90DE55363EFDAE1FD77990 -:107330003817D1300960822F5C11C151333BD3A77C -:10734000937E074E01EBEBF86E2501B720D71D2A7F -:1073500020BBF286080F27BE61BA0F4199E2FFC930 -:107360003D89D7A75E04EFFF62D80D377808EF8F0D -:10737000ADEA8077C92FEAFE331F17988C9F06BEAF -:10738000F738673C922EE2769970EB55928F7F2703 -:1073900043C4F91BBE9425C2655F14BCAB915F7DED -:1073A0008BF379DD7D9F524086ED97F2EC709278F9 -:1073B000EBD7E93696DFCF6C02F73F5BEA0A35E19F -:1073C0007A0E2EADBDBC07DF77FE9FFC97AB5F1733 -:1073D00007A369B14C6279A511DFEF9CD722B11EDA -:1073E000426B1EF1CD3CDED013436F0C7DC95B3A7E -:1073F000C41F4AF29EE1B43EA46FC6D291928D7032 -:10740000BB5F029263EF6AA4EB6BE2C720AC2E2055 -:107410007A021D9FD8C85F3B3A255F28C9F8C3E9A7 -:107420006EE65FEFEA60D354E4D73D8BF059D20BA0 -:107430005B6B71B2F983B0A1008343684BD704EE54 -:107440001D701BE92528AD79E4B77B3BAABE4576C4 -:10745000FD31D4438A1B7E66F532DDC17A80EDC4EE -:10746000160A3CB15F783D6C591B974776A74F3F92 -:10747000958EF39D4A5779DE4CBF5722BABD7FFBEC -:10748000CC4DF3F77D6E67F9E5930EC7C56D9FA6EA -:107490000BFEACC9F0BDC678A9C96263EAF5BBBDF5 -:1074A0008B2B00AEEC407EC7E13226B720AF3BC34A -:1074B0001F647A32BA3171E2FCCBA751BC1CD08D6B -:1074C0003344245026C4EC73A5A3305220F28770B5 -:1074D0000EF237A3E6C76CAF53D00E53280EDD89EA -:1074E00079115B647C9E749FEC42B32AE2AC967483 -:1074F00061E75A1E5142CDF8DECD4A4FCA306C8B3F -:107500007DDA0C45237B5FC6F3E6DE05ACDF16476C -:1075100048223BE42CFD45FA85B86B2AC0EEBFC972 -:10752000CC7FB39C46EB7AB126C3FF05F1756C574F -:10753000F420856FDE14C824B9CE925DBCEEC96715 -:1075400085FD31DB1B39F2AB9F91BDE9D3F3A72455 -:10755000F6E676F2AF86BD01B9EC10E167EA8B7A08 -:107560009AA9DB19CC3E980F138FFA9B5D49ECCB9F -:1075700024A84E43165FD4BE98E588C1FE857E21BF -:1075800032A3A20BF528EE79B33D2AC8D0FDAF6E29 -:107590008FCEC1B49CABB5185ECA577A0FD9E3F051 -:1075A00061D8A1185E428C33F37B24705CE8ABA5F4 -:1075B000643F8ECA696477A6A3DC71FE2E5D4FD24C -:1075C0003F0D7D8BE4BFA1F39A14C2F5535D550EB8 -:1075D000529B15B9B2F6678C9F9503F383A0C385C0 -:1075E000EC9DF15E2B3834D748E28785F920ABD883 -:1075F0008F7B7F7FAB349BEC220A2D6DFE98C1ED13 -:10760000C18A5C1BBFE7A9AE9234C2910B30BF4563 -:10761000F955764A1C2798716DC67133BEC0C27980 -:107620006335C713B214D6F71D12F3D2E2E064F645 -:107630005377611E4E716B7F17FA2D6C9F423F4F3F -:10764000714AB36B16AFDB58AF41DF5DA93372A04F -:107650006CE0FA8D36F0B90CA1CCB8BE12B5118E23 -:10766000039FDB12AE1BFC1C8C0F063FA7103FA52F -:10767000FF3E3FA76608B99AF9FA3F5D7FE18A4964 -:10768000906C5FE0FF97F54F05FFEF7B44BEF55A26 -:10769000AE27664F0A57CC9697211F26503CEE8D99 -:1076A000D90707FE237C8DED68657B3309ED0DC599 -:1076B00099057561B62F137345BE64B61B5776C224 -:1076C0004D641F2747302EBD04FBF129FD471EEFF7 -:1076D000E3FC3203E91EF7FC82E5BBF0D2580D3221 -:1076E000E7E27BC6762B5EF27BD09D99745FC0EC9F -:1076F000378CB8D48847CDE38C78D4F0270D3A1F67 -:10770000FE3DC3FF64065D57D520E91BEA55F831FD -:107710002FC35EA378A13BBD7A37DF1F190E721EFF -:1077200050022AEDEBA0BE721C56E97045E4B1038D -:10773000F5D369D2C330F285F609822E4B689834AE -:10774000900E0CB78314F7E103FCFEA5BABF28C462 -:10775000312CB406E0F8BF702CF8C9EF1696638B95 -:10776000EB3CA6C7232F995AA4FB79E2AB5581A025 -:10777000BDFC1FA797482C2827FEF8FE40EB77CCCE -:10778000F631FD052A78298E2F50C29217DF9F51BE -:10779000A7491736910C3F8DF315CCD5D85F160C41 -:1077A000C53E8DA77827895C7A32ACBCCE7A47CFAC -:1077B000611BF22130B771B6DB128BD3ED56BFAF30 -:1077C00080F68F3A44BC0EB4DF379EED9244EB5105 -:1077D0006608FE0454915FB94065BB59A9CBB1D28C -:1077E0003197F777C827DA270F5CB7A4F97870FECE -:1077F0007CD082936376D5C87F701AA0F798ED6A23 -:10780000DFBED72F0BA23EBEF5BF3F4905BCFF2709 -:10781000259A4AFC387DFF89541FF2E3ADFB45FEF3 -:10782000F27D537CA4640AB92ECEACFE82F87ADBDA -:10783000AABF4D88B72FB0329BF5E28E904CC9F0AD -:1078400005FD59BEC3C97BCF46BF3E9C99D037F4D6 -:10785000A0DE0E8DC9E2EA6999222FBA63D7161B02 -:10786000E5D18B33FDA999D83FADC77FA7DB53790D -:107870003FC0A067D1AE7136E2F79F3AED106103C9 -:10788000D96D1572F65D2F4DA0CD7BF167A6F3F093 -:10789000FE021BED9F2F91202AF6B5E0F0CFB1FF3D -:1078A0005EAE0C6BBD03D7B1E42DD56641F92C99C2 -:1078B0000ED120EAD5A2BBA435F7E2F8457E1745E4 -:1078C0007003D6B9309898E72FD3E395DB1FB29AAF -:1078D000F2A4C6C3B45FB618E7A17C76496BE2FD9B -:1078E000FEAE3B0FFF9CFC40878DFDC0B28BE44F8A -:1078F000E332F57865024CFCAA94E295B21F9569D3 -:1079000083DB25235E39BD0A083CF097550E6ECF08 -:10791000AC52B9FD42B7D7CB3B0E1C665C2BDD13D6 -:10792000C8CF3ED5F5AEF3162DE637BEB9E5934385 -:107930003FC77E05ADB398EC65C44A78BC4AF71BD7 -:10794000CBF438A4E273B3DF38F087DF539E8DEBBE -:10795000DFCE19D7A5C523B782F2693C1F0C3F6261 -:10796000E6477F57A99370323F33713FF67FCA973E -:10797000C19EAB9711D749EC87A14F5F64087C2F5C -:10798000DE366F4D3EBEBF79DF07453DC22EBD06D8 -:107990009E185ED1D033DE960144D7223EFD9DFF76 -:1079A0007498F87498F03689FA97F1FDDC2AC42FA0 -:1079B000EAEDB2CE0FDF84B1AC5FB9965C6A23B951 -:1079C000945F9A7168C69F196FBDD69E22B20F66EA -:1079D0009CF54A89E76446BB34539C5F2CD67CB344 -:1079E00028DF45B7B646E5F508FB775A693DFC4305 -:1079F000D2DB6D12E787F5CFB43D4DF6A8F6B73F61 -:107A000071933DFA5069F5D0FBEAB63FE0F6915D1F -:107A100052826E7AFEC390B04BE6F775EA7C34CEA4 -:107A2000052EF8A587A26BEE437E9C477D26FD6D53 -:107A300068FFEB9AFB28CFF039A294779E567A66BE -:107A4000111D772C7435367929BF4D5C77EDE33FF6 -:107A5000F168BC7F1C2CD0F9C7F96AC336AB3782FA -:107A6000F336BC227BE9350188F2FACCCF07C2EFAE -:107A7000DAC87EAB1688164E1D781FC56823BD096F -:107A8000B4AFFB5876532BE415203EC79D33D4E8A2 -:107A900076D88CE35D99FABE888E5FE40FEFA70677 -:107AA000912EDA3F8290B0C7CDBFD938F66DA4EFE2 -:107AB000CCB617DD5259FCB9C26A96477FF8F65F1B -:107AC000392C83E3B757C77B2C6E09F1735A87248F -:107AD0000E833A455B678DB8296FABDB62F506F123 -:107AE000725D9B0C0EF25F27ED1C37D4B57DC2F89A -:107AF000AC937C51691C2FC32DC5C511CBDBDE9B1C -:107B000045F676799E0C7351A56AF79C13E37D10B8 -:107B10004DC1F1CB77BF3DEB87D447BC3B92C8AB9F -:107B20002A7CC026F4C624AFF0DBB3281E6EFECD3F -:107B3000672C8F0FF74B90533CF0F99A2DEFD9C873 -:107B40009F9C41C164A60B7E91DF0884E585B6B495 -:107B500064F28B5CFFBB4ABECFFB7F1793E37A3A9C -:107B60006B1BCF787FF2774847CD9B76EF5C7AEF3F -:107B70009377BA0171F081D22870FF8B073CE487BC -:107B80006BAC418FCAADB85EF3CBBB198FCB8EDF28 -:107B9000ED11F98D2F4FEC1705F3689D4B367F9B48 -:107BA000D7B914FC8CC79A5FC8D5B44F734E81D92E -:107BB000BB93E84D659688B7ECF083B1F789F30085 -:107BC000A0FCFC037DDF34F8B2CC719B1D6E4C9B96 -:107BD00017B7FF64CF12F62A08A13FD2B96A00DDB9 -:107BE0002B9F831C3F378BE6B9AB5869A473225C8B -:107BF0007F50E797F415EF0B80A6C4C55955C7AF62 -:107C0000CEA17D313BF4DBFE5725C7D51AC53D71AA -:107C1000CF31DF3ED86A1F225D89AD27F9BEE9ED7D -:107C20005986FEC3CB1087A7C08E0F184F80FE3B2E -:107C30002D57F41F237D5CE46A4C43BE7DFACABB1A -:107C4000363AD70AE27A8611BDDDEF711FBCD91A28 -:107C50008D37E60F74D863E781A4D7DBDE33E9758F -:107C6000E27DF4DFCCCF00A46994B77D608BCE2297 -:107C70007F1EC4F7527DC1D20DF684F3C6185E4C48 -:107C8000E78BBA7E1AFB9CCB4CF198D19AEDC2954A -:107C9000598976013667273D5F34E72175D6D0AF25 -:107CA000893F7527ED9CBFD4B509FDC3803A3A0CD6 -:107CB000F5E1A35D875EBB05D7F151D89A3597DF13 -:107CC00096686F6B9E42FDC5F132F23B85EDED6724 -:107CD0001C4F19FEE823175E1C93446FF17A52BDC6 -:107CE0007501DBB3FF577676D92076F6BB5903E2F0 -:107CF00084347C0DFCE589E597537C61E6AF615FD8 -:107D0000CD76F3934C2DA9DD04DDCF1B7CACDD7962 -:107D100096717B3E4F9C37356CFB2BFB31646BD4EB -:107D20008EB86D087DCCFD07C88F71FFC07C696C73 -:107D3000B27527F2D37CFF32922DE723D1EF139F48 -:107D4000658BDB2BF6E7543ECF6F26BF49765A533F -:107D500081E40833204C7187D4F9FC5FE97DE6BCEF -:107D60002238034636F2B92EAC8BAFCF092B7A3DC1 -:107D70004530797D4EB32D769E4BF7073BCF7D5F27 -:107D8000B7575E97CAE508D62C4D4E5657E2ADB2AE -:107D900024CD237E9225CE774AB3C5BA8F65097963 -:107DA000B4C8D5FA46A3C897680F95ED5FBA9BCFC4 -:107DB00083AD7A7D06CE9CCBE7074ECB27C812D881 -:107DC000BDA17A8E42FBC315963B4BB1DFB5E1F600 -:107DD000390AE2C73BD5B2A704FB2F6C582CFA57DF -:107DE0005A2AAC08FDC7834BE6CCA47D03CBDB3F0E -:107DF000A5F529AB15A0FA91D296F7B87F97559CB7 -:107E00005F353CBBB786DEDF20A12090FF2DEE70F2 -:107E100023D731E482BA9A368FB53D7EBABF260F9A -:107E2000F379944724CDFFDB2CF22B8E885B2BA1BA -:107E3000BCD2B7F17B785F79D94A3921AE53EC8354 -:107E40008FDE333597ECEEFF85F7FF5B56F6E0EFFC -:107E50003FF3D4B50B68FC68195419E72B57B42AC3 -:107E6000EADB31BFA6BCCD9043B922F85EE6B27121 -:107E70003ED792EECB253C1D239C665F7ADBACD7C8 -:107E80000FC94E810339CDD2B81BDB5774F9BFAA95 -:107E9000F383FE685FA06F5FCE56AE5B816811C949 -:107EA0005796B7B6113FA24D0A6CA5FDD77D8FB787 -:107EB000113E5FB73978FFE8E6B4F5D62B90E4724F -:107EC00047D19D04FE37A55D7753BB2FDBDF93259C -:107ED000E68DD0BCB77C5F16F3BA1A53C97F820F08 -:107EE000F54AECD370FC0E7ED42BA2F920EAD538EB -:107EF000320589754E663AE4B45D4CC7CD7641C70C -:107F0000825049730FD231CE1EBA8CF22B7C7F94F3 -:107F1000E4700B865B84E760217491DC5EBFEDCA80 -:107F20002D627D85ACAFACFF7CFE7EE6499A2F804A -:107F3000F3D3396A40EAE1FE1EC5A1065561DF1799 -:107F4000C6EDBB3D0BAD27CAC4FE7E33E51D53F520 -:107F5000BCD8D87F33EA0D2676F9AB5C64B0E54E29 -:107F600099ECCA398CD7C88E99F7DD269BECEFD4F3 -:107F70008E8FD82E5FEC3CD099ADDBE37CC8A77523 -:107F800084E93C90025EDD4F7AE93C3089FEC79D72 -:107F90000766660B397DED79E09DBABDD1A84E0E1E -:107FA000D7D18F1393DCFA8F2E82F24AAE476884C2 -:107FB000F4C1FD6ABBC9FE1B381FF38A7A3BD9B3F3 -:107FC00031AFC06DB4DEABF5F393FED3C0F580E303 -:107FD0007A1C5C1F68EDB28642525C3DCA490BD7E1 -:107FE000A3F48337C4F52B41BB1A647B3996EB4F5E -:107FF0005A4EEAE7BD7A3D438560D93F5C0F61AEDA -:108000007F98E29E242FACE4F31990260DAC7F9864 -:1080100022DF2A935D81A3429E17EA20E43299D69B -:10802000752E024029DA8457E2E48DFF9B9815945F -:10803000B9FCE954E2F529265C98E57F6DB61EDFB0 -:10804000E8F21FB48EE443B1AF360EC6721D89D577 -:108050005C47F286850B366375241521D2B7094D2E -:1080600062DFF862753CE63A1D731D4E9E3F914FEC -:1080700005355724DCBFACB13CA17FF9CA2909E31F -:108080008BD1A1C6F74B1F9A93307E58EB8D09FD1B -:10809000119B6E49183F2AB428E1FEE81DB549EB53 -:1080A0005E0C9C8C09AF48B8BFD1F9E4BB84AF9695 -:1080B0003C59A578FECA8EFB4C7531D31817538CEA -:1080C0007D785DFE465D1D9581119FC7A3FC1F2B2A -:1080D000A6B8E9FE2A491B88036F24C87EFC1FC589 -:1080E000C17A931D30F4FF62FB373FD6FD849C526A -:1080F00024519CE3C3B82A652AD5118B737B784B36 -:10810000D4AB7C96F2778E8B34C9ED856FD25B55FC -:1081100089E2A07BAB348E83EE1D527480F60F7A19 -:108120007EE0F64AF903EB42CD75A0190EDF64E05C -:10813000AD115107D982869EEC7F708683E38C87D0 -:108140002D96DBAAE3E87F225BD89F27B245BEF5D8 -:10815000735B7837D901C5016A539E789E8A1F8068 -:108160002A7B502EEE4C10F561F0C6DA9985E43F7B -:108170007B466AE9543F8BFD6FE06525C4FEE496BB -:108180006685F3BCD5CE27D99F942BC29F8C93854F -:10819000DF403FD241F6F14DE97EAB88B382569283 -:1081A0004F810382EE72F6AF7C4E9C0E59D28A321A -:1081B000AA4FBDE0B7B4AF104C876AA75A884FFDED -:1081C0008B653E0F7E8948427AFB6B46719D73FF3B -:1081D00085FA3F2D8DF2EBFEC58F9EBDBB32A69773 -:1081E000276DC9F3BC8BEDBBD56C793495CE514E60 -:1081F0008E8484FA8C37B3457EF866B62CEA0C423E -:10820000EF79884D7D4BBE184E4407A4EE352E1CE9 -:10821000F2E0A61F54935C6CEDF382B4AF69ECE31B -:108220005FC8033BA773FDB6912FDDFCBAD8D7BB5F -:10823000F98BC47DEB8FB2C5B9C047F43E6CCBBBA4 -:10824000FCE3496E379042F0BEB27F3CC507D52AA9 -:1082500068E4F717F817DE7D14FBF3D64B1CEFD359 -:108260007D1A7F23CA90EE9F00EFAB7B91BECFB308 -:10827000053DF3A1DA4A74BEF6FDFA54C2D3EBE928 -:10828000627C54026D6BDC7C37E8F3BDFEFDE57B60 -:10829000294FA7F7D1FB891E7AFF3C154AA8FF1A80 -:1082A000F8CFBE5A3CF0BD3781CFAAD77B59C94F12 -:1082B0009642A8ED69B2AB472CDEB5C06D2493FDA4 -:1082C000929DFD525F53F4C97B90CE3FD5FE75AFB2 -:1082D000847CFDE3C2E8AF9FC6EBDFDD248386B874 -:1082E000F838C32F7BE2EAB44F2EFE2495F889F1CB -:1082F000CAF69F92DEEDB47BA9AEE3CDDA9DC3E36F -:10830000E3FA54CF74073D07932EED3CADEA89C9DB -:108310008CBF15DB05FE56FC66440EE16C45EA0594 -:10832000DC89FEF6523E279D2041D2FC783FE24D8B -:108330001BC17535A021CEF67F2EEACAF71CCDA849 -:1083400020FA14F05F16BF9E3D2FDD329AEB79DFE5 -:10835000C8BA243A496783687F6F665389F181AE52 -:10836000270B3A332BF478729487E2B9DFFFE6ECFF -:108370007F105FF6EDDCFE43D6914BE3C3C03A5A63 -:108380007527DB27230FA3BA57CAD30E59D84F5EE0 -:108390002DDFCF7918D56970DE35A488C7A3C15108 -:1083A000ADC2BE89EF24300E6EF672BD27EBEB4AEC -:1083B00055C42D469E245BBCB98AF8C8E0C5A93CCB -:1083C0007F09D0FE989B122BC35E611CE1962DBAEB -:1083D000BD029F03F3D3D1BA3D9BE5F15EDB22CE14 -:1083E0006B12E24FEC57ED4A127756E33F8E3B3764 -:1083F000FB9B53D82F6D96CB28EEF03922E4C7CDE6 -:1084000071E75458CFFB0003E2CFE7FE7249F1E772 -:10841000F73CFF3DBFB3D4A3B1FD098F14762E1CEA -:1084200019C2790EFE55907E0DA5BD003A07CD13F9 -:10843000AD4DEA1DE940FDACF594AF7B681AC2650D -:10844000A8E00FF551A450AA7D72E82B8A03BB1552 -:10845000965FFF73577CED772495A887E4EC23871C -:10846000A770BD735F97D08FB60CEDDFA7529E81CA -:1084700071E656243145E9B1A52759CFD3647F5120 -:108480001FC21E9147393AC4B9A843F301D99714C2 -:10849000551D4789B9317EB147D8DDFAC36F16D96A -:1084A000503E672D47DD74BE52B7F729372E179A15 -:1084B00033FD0F90FE2C3FF9F20495EBDCB614511E -:1084C000FE1D8EBC3C83E3B3D9C8DA7183AF27B0FD -:1084D000A9823E4280864D99DC8EA27D15BC14880F -:1084E0008875F676346724DB1F08FCDB5B0769BD03 -:1084F0003B8FA570DCB233BB9BF520380F603BF29D -:10850000FB89CF47F37C0830A6E38A6A4D227FFFC0 -:108510000B7D3D3BF5FCB2F77399C719F38EE998D3 -:108520002EAB88ABB248EB41AEE3EAB46B24DF94E8 -:108530006D20F8D399C2756181FDD788BC335D9CED -:1085400047B70D89FE91DE13DD67D7A84E35456D1F -:10855000850C9CBFCD26FCEC2804FE53AED875E3F9 -:108560007D299D1BF92308C405D7E3A528ADF00D8F -:10857000573CFF5399DEFD1E11EFB40D89585CE4A2 -:10858000273057DACA74C5E8047EAF41E7288E8BDE -:10859000DB6CD1F769BF1DE9520917A340D0099DD3 -:1085A00023348A57525471AE9EA26ADEA03490AE34 -:1085B000C058086170000FAF860B7ACE7584436295 -:1085C0007D07EA425B891EC70417AF9B392DAE4F6A -:1085D000866C52ECF9139E65EB5A0A695DC20F2A4C -:1085E0004A98CFC7DD0B40A5F3EF14C5C77952CA2F -:1085F0007CD09A505E4E878FEF7B708EA6C9DC8F41 -:1086000010FD2ADDA77D9B34D53907E94EFB328D5D -:108610009F6BE8B672DD79DDDF6F4A2BC3F59DB144 -:108620001CBC6717B61F2D0C0FA773DA0969FEB7BC -:10863000C81E3F736AD1BA3138FE2F6D56EF5CB257 -:108640004B3DC11FD3B97DED13568DFCE2836FF412 -:1086500047BE22F93E2BB15DECB38AFBD8D79AF026 -:108660007E43E707363AD7BAA6E36D1BED7FAFCC62 -:10867000F1BF4F7A30A9A3A98AF836195A9B699F8E -:1086800013ED21D74B847385BDE87F65F8D6A638F6 -:108690003EBB72F47DEFA8FF72D29B4E5D3FF75355 -:1086A0007C84ED5E3D4EDB7BE0BBA55ADCF96910B6 -:1086B0000EF27EE06A788EEB3A8DEB7D216536E135 -:1086C00068F46B8EDB7C7138B3E5087DB7E9EFFBAE -:1086D000798EFF4BD6DB03EFD8DCB8FEC09FC345D5 -:1086E000E4AFC218CF7D5D1D69C0A42F17EA8E4E7E -:1086F00003DB919DAF7570FCBDF33E359DF41EE923 -:108700008734ECEFC5F882F4686FB1D0BBA657CFC1 -:108710008FA5FDE2F3FB965F4EFCEAF5580D7CCF8A -:1087200018427AB41BD88E197A58467A28D1F77B2A -:1087300062BFA78CF04D7A67EB9EC37AB7D702A4CD -:1087400077886FC63BE25BA538A44C45BCF3F323A6 -:10875000588FDBBA5FBE82EBD991BDC3C651DFC271 -:10876000F86A8BCC0949F87CA53572909EAFC4F7A6 -:10877000376931BDAC9412EB7A167B449DAC611F16 -:108780007FA0EB6778A496E6C5F14E594EC07F9C5A -:108790009F147DDD8FDEBBF127EB36A0BE94FA2A55 -:1087A0002C1328DE3926B31FD8AFC7C92BFE30E5FE -:1087B000865DE23AFBCF888E8B837ADCFCDCAA5C98 -:1087C000EE935FD0502EE3B1F55550BD7763156D34 -:1087D000C54D9ADD7A88DA29D5E12A3A2E9CB6A0D1 -:1087E000FB90F8C6CD379AF0D67EF05BA3B94EFA6F -:1087F000A41DE83BCEF6FF8CFEF1095CFF3DFB912A -:10880000DF90342E61BCA1C766FC0D86933EA9E7BC -:10881000FAA96897AFDBF8EB6B1574E80D04045CFC -:10882000FF9C8DDBD605D1079EC8F15D9783F8FBD1 -:1088300022D77F5D0EF2ADEFF87F7AC89FEC7DE521 -:108840001D37F9E1769B6F34E1AABD04F3882478E3 -:108850009C926365FF5A3948BD49638EC8B7860745 -:10886000611DE1A5A15D5643E4A77DDDD793DF78C7 -:108870001F5949FBDA4BA707DD942FD5EC3DC47592 -:10888000FA463EBD04F43FF9D659C4FF73B9223FFE -:108890005EBAC19A90DF8E80888DCE91037E576339 -:1088A000044552638A3BEEE8D8C2DF8DD46E4B7C20 -:1088B000AE8EE2148450DD45F2E3C61C7D9FA41405 -:1088C0004A294E41DCF03E49F455D9BB15B8BEAA41 -:1088D0008BEAAB765A049F9C0E6849CB88C52B2344 -:1088E000F27C4BC8DE2D31FC875EAF146D93F87BB4 -:1088F0008A513B44BE3CE5B4B685BF930AFAB84EF4 -:10890000AF860840BAA728415EFF94DC5208E2FA1D -:1089100027A179267D59DA2985989FFA772F0AFEB3 -:1089200013FB459B65FECE6FB30499C5346F94F974 -:1089300053ABEF1F2EDF91787E51B7E9F8610A95AE -:10894000EAC3A6F3209D3FE6F39DA7E83F929CEF84 -:10895000FC24478FE78AA028E1BBBCAE4BFB2EEF7F -:10896000238A075C74F8080971F91E1D470DFABACD -:10897000EB42B258378A82EAA36FD76112002FF315 -:10898000A91E71423880F542DE463D632D54DBA8B6 -:108990008EACBEBDE9309DBF2DD5E35A339E90A16C -:1089A000CCAF657ADD50CDE6C4FBB53A5F6A4D7C4D -:1089B00069F04B26FA44DC7DA9F4A1E5FA0EE1A0AA -:1089C000769795EBB9CFC1AD5C7F55DFBE85E95990 -:1089D000AACB6F20BD415ECF325C0FE9D3A5D26B2D -:1089E00096DF3103E757C01509F29B9D7949F22BB9 -:1089F000057539ADAFBF4BE4B5FD5D25BC2F61E01A -:108A0000C5FCFC2C3D8EBE66938837CF7654392941 -:108A10001EE83BAA7825C47DC5B14FDDF4FD4DF9B4 -:108A20003E19E89CB4AFB3625D10EDE59EAEA13790 -:108A300069E807CA8F29EC372A8E9587528AA95F81 -:108A4000EE2CE53A132D93F2009C87FD70DFD1A147 -:108A500027CA384E9F5949296AD3D17227C50B7B43 -:108A600040EC6F48C72A337BE2FCCA7B3962BF61A6 -:108A70004DEEBB0F939DBA66B795F783AFB1465FD6 -:108A8000A23C6C4F97E26DC27EDDB145AB5348DE30 -:108A9000BF91BC14761FEE5E9145E735F59D56D526 -:108AA000CEF4DE7D90EE077749DE61383EB0EFEA26 -:108AB000D16DB44FB4A5C24BEC35DE579EAE3D4AE6 -:108AC000F5AE90E7E4BCFD9ACBACEC5FCFE43BFFA6 -:108AD000752EAEABD6B76516D9E133BFDBC37515BE -:108AE0007D6D12E44AB48F7CE849AAF739F3F4713A -:108AF0001B9D0757B51FE7BA8DC1FCC1D910E28E87 -:108B0000F3F6561BE537F55B8C7E0F7F8F52ADC7B2 -:108B1000510DDBDEE67E2DE50184C7CD7248C3FF33 -:108B20003CB4EF193E1F6ED825EA3E2EDCDF26F15D -:108B30007D03EF8B74BBB51C34C6FB7203EF7A7DEB -:108B40009481F7733097EBB496EF7A84F1BD44C704 -:108B5000B7B96E0A2DB0AD2C4BE82BEDB799BFFF1E -:108B6000BB43C7F71D17C1F7A85C1DDFA36014E165 -:108B7000FBFC74514F77FEF81027CD7FFE08EFBE47 -:108B80007E1DCED9EF1ED5E382FE88C567BB323687 -:108B9000AEB7E313FE0E3170B4DF467527B33A3F2C -:108BA0006679CCED3C3093F87D1DF8EB887FD77566 -:108BB0003A558A83E7F6087B36A7D3CEE713D74129 -:108BC000B885E4DCB7FFF1960CC2CDAF056E0C3B67 -:108BD000B74CE7EBB5653F9845F97BADEE0FFBBBB6 -:108BE000EE9CC576671C1453BC3747FFCE7B4E58AE -:108BF000B7439B13F94EE7D424B7864E3BD79B5C13 -:108C00000B3D36F267D7EAFED3EC27FBF29C2CE74C -:108C100020FAAB6138BE6E97A98E52E9617AFA3BB1 -:108C20006C7CDED560F2BFD372AD09F51783E1D35A -:108C30002CAFDB72757FA2CB6B6E54D431CC7945EF -:108C4000F6D2F94357647519C50B06DFCCF2EAD2A8 -:108C50004AD3BEEEF7125ED2E37CA37F83FEFD5BB8 -:108C6000586D75C5E7EDCFE75AF473CED04F2B7032 -:108C70009D7749D04D38C4FCE6867229697EB332AF -:108C800017C73F5F78FBFA71F1F98D6FCB708AF7E8 -:108C90001E44BB5251C9F53BDD7C5EA8B4CEA57322 -:108CA000B0C02EAB97F29A4087CCF14060973D64FC -:108CB000C179AF211C215DD59DD2D58423CC1B5A0F -:108CC00072D13ECDA32D651C37AF03E3117C6EDE60 -:108CD000CC8F197F47868A75F72B5A4EB23CC2C893 -:108CE0001F1A3E17F1AA71BD01ED008D6FD0BF4B69 -:108CF0006B3FF8D7A2E2543AB7FDAC6821C5A9B9D9 -:108D0000227F31E2D528C6AB257ABC4275174B8548 -:108D1000E860E973F7D9C87E1DA61FB6A0FA49D549 -:108D2000BF86F261D50F8D3FA240436A613D6A2044 -:108D30009D221CEE95C4FECDB356AA0D81A6978741 -:108D4000705D60EF6BE21CCAACEFBD8BBAD95E9C64 -:108D50005FE86A24BC2D2FDBB206230C18BDFF751B -:108D6000B637A37F67532D6A6C5D4DF4DD1DE7694F -:108D70002D09F1726F47B38DF7A1E3BF1B2E1918B0 -:108D80001FD55F641FEB79935D41FA39DEED3B221D -:108D9000ABB42F847CFC657E3CBFF478A8FD600AF0 -:108DA000FBAFBEE3AE10C5FD7FD1F17846DF976F14 -:108DB0009A24333F2C93453B7AFF3325245F9287D7 -:108DC0001FEDFDCEFDCF5CE1E37DF490A823DE91A5 -:108DD00058875D1F4EACB336F81AD0F98A740DA7C8 -:108DE000EF950DBAF62A3D6E6F123D92A4832C2F9B -:108DF0008B9498E7069E95ABE3EB48713DB791DD08 -:108E00003B69E88B12F5901F7E2B5763DC34750AA3 -:108E1000F95AF68916DFFF1DB15F63E5F70FB83F1A -:108E2000235847F7CF173BB9BE013E0FCEA5FE3DF5 -:108E300025E2F703EE79B97644FC3E1D48221F0F68 -:108E400058A35CEF17386E61FA02C7FB3D435D64BF -:108E500017B7CCA43ADA6B757B71B8C45943380F95 -:108E6000D27B7362F32CC915E71B40EBCD8D7D5F80 -:108E700069AC7735DCC87C58ADE3EA3FF4BC1EF33F -:108E8000A8F3B949F2A8C1E2DF0B74EBF1D3F9E919 -:108E9000DA89EF210ECA8F2841CAD7F7BC91122276 -:108EA000FFDFB46FD99F281F0EBC69078A43EED934 -:108EB000BF6C04D7E1FBFD57923D39BFFF8E2BB944 -:108EC0008E5112DF970689BE5C8AA75EF5509C54CE -:108ED000BFEF55AE73ACDF3BFE518A9F305EBA9652 -:108EE000AE631CC3F82B3F56C9F8DB73B432B3949E -:108EF0000807AF93E6AD3FA270DD63FD91CA17E7A7 -:108F0000525C736C06C74F46BC5441F938C54F4795 -:108F10008626C44FA979827F7D075278FF4382124B -:108F2000811F189A809FBAF63F709C5187F62E1EBB -:108F300047C673C5790ACF332C4FC74F58F2313E1D -:108F4000768BB6AE630FAF6FB935CCF26EDA6515BE -:108F5000F7DB446BD44907212348FC78912EA11CF0 -:108F6000E6D84285946FBE502CF20DB33C9EC813D8 -:108F7000E7852F9C14DF19BF30DD3F22D9F7C641AA -:108F80009821F27049E777BB7576B2EF7977E4897B -:108F9000FD097726249C4B1AEDA379425FE6D8C4DD -:108FA0003E95F9BE3FCFF03FB08ECE634ECCB5AA12 -:108FB000C6EFB7E4A1DDBD1E8C3FEFABF3B3E89C79 -:108FC0004BE4D5003D33C91E7E9BF6F929FE9A2459 -:108FD000FCBAB1CF3F6F333C20F6F96FB5925D30EC -:108FE000EA4BE6F9CCF157F5D534CF8DE8DF699E31 -:108FF0009B6627DEFFF645E2AE0579BA1F1F0EC35A -:10900000455EE172923F38D76555655E476868B244 -:10901000EF0B0DFB737895383FEA42BB486DD3A840 -:10902000D779DFEA8503279F4C67BB9A0225C8E200 -:10903000ABBEFC9327D93C4D17F4757E02FE0C792C -:109040009DA53CA06CA0BCEECCB3E8DF259DB1F1A2 -:10905000F926343E649107FF2EA969D4672DA44FE9 -:1090600067F5EF5E90BE227B9CDD3F9BF731DFBF53 -:109070006706448378FFC0283BFBBFFA99129F1F05 -:10908000D447843FAC9F2FFCE1F0F6792C97EFA0FA -:109090005C7C5E3613AF515DAE21EFABBEEC9B69DD -:1090A000E493748ED34438673B9DC56D7DFBDB2D07 -:1090B0007C5E897E97E2C21B2625CA6D04F81FC814 -:1090C000C6FB37CF96BCE84106C8FDE65BE7B1DCDE -:1090D0006FD2BF8FB998DC7F9BE7FF691EE97D7770 -:1090E000FF77C6208B5E18F54111F9D7864170BD18 -:1090F00055E72F0C8D3E4DE765DE0BE7E97F7F3AA4 -:10910000FE3CBDC4E3DF924776D5F2A5FB0AA0F989 -:109110007A7EB942223901EBC5607AB5439F7F4719 -:109120009E2ADE9325CE8746E9FD17ACA142FE9E1E -:10913000A2ECD2CE019B9E7D7E2CD9B9DE0347C620 -:10914000DAE2E47A6605DA07F237FB0EF1F78731E7 -:10915000DC5974DC29DC4AD28DBA1F4DC4E119C236 -:1091600021D9E7DD87AEA7FCF16CFB4D599216E7DC -:1091700067F79E700F8B9BF7ACFEBB1898B70DFF7F -:10918000766A3C9D0F309D67C3623ED4FFE1378D08 -:1091900089BFDF6C7C67C7787E7064239FD31B78A0 -:1091A0005640E0D9F83D8C0BDF55DA80BF7B0CEEE2 -:1091B000B7737D459F355A941EA72F1F1A72449886 -:1091C0001566312BB9DE75226CA8E273024CDED72E -:1091D0004DA6CFEFC2B2A80F6DE4BAC5698DE025E8 -:1091E000DC4AB099FB13668BF3F229D02D135DDFB7 -:1091F0008428B73E50156A67508519B6931C61994B -:10920000C2ADB6F6834EC257C4A3A4BFEF10A5A744 -:10921000C9E4175BBF02EF1B78C5C1180425FD4EDA -:109220003F2B5FD87FAF53E863F4ACF8DD936F401A -:109230000FD33F55E9667A53352D83CE4B763FB732 -:1092400042A6FA97FDA04549CFBC998DBCFF169D5B -:109250000EE1ADE9B1F54EA2F5AAB1FE940560A10B -:10926000F54AB04BACBF1132E87C6C3244F83D5744 -:1092700011C1B8DEE9A029D4B7E517EB7C16F95B7C -:10928000959EBF591C41AEFB49CD17B8762A2139AE -:10929000AF92B7B6C38FD0F94CA958E744BCCEE71C -:1092A000388D82EE0BFE3A5FD8BB29106639430D2C -:1092B000A82FF28F2BCC54895F52C463A1DF13BB5C -:1092C00054BEF67980E977DF1EEDFD6165ECDCCBFD -:1092D000DB99C3F5D0EB254B5426BA1C85A21E3A68 -:1092E0000261FE2E3392F87B67C5F9375E9E4F7E92 -:1092F000CF2FBEC335D775EE086DE5BA9B05416427 -:109300000FCD530870DA13AB03B09684F8BE95CE38 -:10931000D955AE33ADA07C715FB6FFF2FC6CAE37B1 -:109320001DC69329A1F1D5A931BC2365FCFB3B4E99 -:10933000486D257BD4ACD7D30655B75ECF54C4EB6C -:10934000D0D0CEF38F4828A2AEFBDE2A517F7AEF31 -:1093500090FD5CE7DB23812A15D0F9FF7EAE03A6E2 -:109360001F86B3167CCDF97F96FEBB0F25FE3726F0 -:1093700096EA461E9F6B3E95CAF5AFCA0C9F46758E -:10938000BCE67AF1D296F10FF5705E6AD06BAA1343 -:1093900057BC7CFF5EDDBE363BC4EF0049ABEDAA97 -:1093A000348DBE7F5FC1BF63D54CA141257DF7BE23 -:1093B000829FA73A662A02ED4DF3DF44FC32FF2E6E -:1093C00015C2ABFF059A376D38EFF72593C73443C5 -:1093D0001E9681755228875B49BE46DDAD516F4BA5 -:1093E00080A0753B7DE277F054C409FFEE1F42C9AF -:1093F0004EB8F4997FCF43D4FFB6E8FC47BA7670F5 -:10940000DDA7437CA76D7CCF6BE69B81DFFF02B9B4 -:10941000D77EA250530000000000000000000000B2 -:109420001F8B080000000000000B9B25C3C0F0A3A9 -:109430001E8145A551F9E8F81C9A3C0B0303C34F64 -:10944000205ECC835F1F2E1CCB82607B893330185B -:109450008B32309800F12C209E0DC43F81D8508C67 -:1094600081C108888B81EC1220F6056247A0DA2FB3 -:109470001C0C0C13851918E600F1726154735F30EF -:109480004268252E060653206664C66E3FA73AD072 -:109490005E5D04FF23906D6F409E5F46F1D0C35523 -:1094A0004EA8FC7C6B54FE2C5B0606666704BFC0AE -:1094B0009A34F3ED817A1D9C71CB77BAA3F21B3DF0 -:1094C00051F97FDC50F935E1101A008D579524B819 -:1094D00003000000000000001F8B080000000000D7 -:1094E000000BED7D7D9C14D595E8A9AEEAEAEACFA4 -:1094F000A9197AA04706A8611A19E3A0050C30281B -:1095000048CDA0384693349890D1D5BC168821090F -:10951000CFD7F1ED2A1AC9F47CCFC0800DB2067DF9 -:10952000515B0C89262621899B3559B3698DC92346 -:10953000D96C168D9B47B2B86F243C379F9B79EE50 -:1095400043FABD90B0F79C7B6BA6ABA6BF00DDE4F1 -:109550008F37FCCCCDA9BA1FE79C7BEEB9E79C7B8B -:10956000EAB6EAF1437C1EC059FC5B03F0A6170083 -:10957000964D95E94E33076DACFC1C98FDECD1A5DA -:109580007AAE5362E5A2D0B84732002E8F66003C17 -:1095900000F1C38F8287D51B695461671380DFD8C0 -:1095A0005003A1A97EDD657F0F406E61E9F7F20BE4 -:1095B000A33123CCFA7B6A79B7C5FA19F9727BB764 -:1095C000D53AF5BE010765F8CD07864D3DC0E09C54 -:1095D00007C113051866632F64FF69F72521C1DAF7 -:1095E000A9B951301661BD5AAAAF3D73D4731B7B24 -:1095F0003EEC85EEC3ACD49E4DE7820CEFCB9ED300 -:1096000097C88C1EBF62797EC5607FCC934D231DA9 -:10961000B17DD4EF2946170EF576D1B314E9617404 -:10962000ACAA929E55A5E8792E9D467A2E7FD658F3 -:109630005C488FD6C8E9D11AFB689E4EC5183D4DCF -:109640001742CF3D44CFB0A067D845CFBB043D1BE8 -:109650006D7A1A86889EA1398C1EF6C8775F1A1219 -:10966000ACBE86F484B19E939E21A4A7B5083DDAD2 -:109670001F879E0F09794B213DCB2AD393427AEA6B -:10968000ABA02794019D3DF783641D6E9D8E975F6F -:10969000F071D13399589AF53BFA7B99E699ADC8A8 -:1096A000D8864553F5C6055EDF691A8A8DA37C2DE1 -:1096B000783006ACBFD13912D577F7FB10A8547FAC -:1096C00066A3D58BFDBFE34967FFA37338BE76FD64 -:1096D000DF8879FC0DC8D46E5628318AF0E882AF55 -:1096E0004112C7F166623AB66BE2ED06172CEF1E27 -:1096F0000F156BCFE919DD912679D672F710BFFEF1 -:10970000624E060C06FB9F4C02F25F8D717CECF6FC -:109710000C2F802B90ECBB2C8BE30770119BA7F4D4 -:109720005DB9341B2F9EB9434B307E8C36F46948AB -:10973000F788B1AF1BF5D6A9B80A7213E2559C0F92 -:10974000B65CAC81316D3E9BCFFE576473274CAF46 -:109750009746E1AA9F82959007722D407F6701E9A5 -:1097600049D2FC0F2E7890E85691AE4548570A0C26 -:10977000F6FC1B427E7CCFA401E54A33D2B1F4A2B1 -:10978000E9E38C20FF5BB1D74C6C4301FD3FB5E7AB -:1097900097CDAB6B7E892F0F81954B235FFCCE79E4 -:1097A000B3CBEF09BE5FDE9826FE561A7F3AFD7CEA -:1097B000FCBF0683FA012D134B84A7F019F58EF731 -:1097C000A15CB335691E62552E63E37414F0DB3D72 -:1097D000DE249D4AC621C75F137C1AF54FBC50D8C2 -:1097E0009F1B9F6F897ADF029D4A9BAECB9EE5E36C -:1097F00054EAFF47C8E27AACEF5A574ADAC1F77B1E -:1098000045FDCB9F73D62BC59F8F4FF2271D437904 -:10981000B4D723FE59330184C8D05F6839C025F816 -:109820007F5893DFDE367E172EADE3D1E4296CBF7F -:109830000D92F302CD6CBD78939FC5729D62BD49B8 -:10984000FD42487FFD52217732E9013E1EEB1E5852 -:10985000FF61D19F2275013079F6B543762743ED3C -:109860001AF9784E62FCDC0760CED20BF6F5137C59 -:109870005F5FA967D7E27E7EA5C20861E3D580EE6F -:10988000C712EBE758BDC8B290C946021FFC594D3C -:10989000A288DCF8DB20EDAF61E3B7AB8E75E1B7F2 -:1098A00092807A211C839C3F02A04BE128E1BF02F9 -:1098B0005670FC0D09FBAB538C5E858D23C73DE6CE -:1098C00041F6B46615ACDC54208786C4E5B737EEA4 -:1098D000F1205D434CFFFBD8928CCC61EB1DD7434C -:1098E0008CD91B45E47652BFE765C8CD60FDE625FF -:1098F000C82D657008562659BB8C0F569EA471C1A1 -:109900003C5844CE364A7C5EA5F8C4D9B3641740AF -:10991000F65AB20B32B48ED578C6C27D40B322A6B9 -:109920000FA7FDCCFD5CAF2960A19CD4C633B91A4A -:109930007C6F5CDC84F8CE8AA7E0B5565E9E28C0BA -:10994000570BA563643F355D2CF515EC63CF33F9F8 -:109950003951206F233BB81D30D83424F4CC8749CB -:109960007FDAEF3F20F8A48E3364902E43CDCE975C -:10997000A6CBF588545C4F6C16F4E2DFD5CB9DF294 -:10998000AACC14F2CA86F02940F235FC1464115FA7 -:10999000C6C9176E63F0A52F6AB093C9572B1CF583 -:1099A000A0FC5C0613549AA0CB582E0193CA3648EB -:1099B00050F9DB0E26F7ACDC6631799F4FF2FF3EA3 -:1099C000898DFF9B39C98511F6DC1F4F5F81FB0B29 -:1099D00093FF8DF89CC98984F2546741D1FDB2563A -:1099E000E2EB75AFA2FBB1DE5E0B483FEE97FAD318 -:1099F000B84F8C083B69C40F8E75BC47D03D22CA56 -:109A0000DA7812C6717ED9BCA05E7FBEE9765AC7ED -:109A10003E85C3436C5E48EE56F37DCC8D8786F35E -:109A2000B2E8FCE761E31F7F1E86A4FAA2F3308C44 -:109A3000F3B051E2FA53FD391FBF0C7DB44F6FEE06 -:109A40007D9CF8AF9E3CB7FA36FDCB5D7A7385D02E -:109A50007357C2C45C85E9913B7C39559108EF4747 -:109A600010EF377F72F403480F8C2717E23EC5F0E2 -:109A70007E54223D9982A36C7CE515398B7E8A2722 -:109A80007883962CE3A780CEF49926F4D97CFCDF6A -:109A900046FDF5E074FD7BF1E10F1D237B03B4E48B -:109AA0004ED44FAB531ACA457FE3060DE568B89113 -:109AB000C128373155932E676508BA50FE6CFB6399 -:109AC00028B669A4298A768FB91CBBB5C75F1B4B22 -:109AD0008244CF93337C4DCEE73FC3F5AF2763324B -:109AE000A34FCD5EAB219D83FA06ADD0EF5243C9A3 -:109AF00098CAE47018C7C3F1BDA9234D6DA83F6192 -:109B0000691FEA733D054B51BE639D84E7DAC68445 -:109B100086EF7DB125E03390C509B2AB86A24E7FBA -:109B20006EB8F14EB89DEAA7E0F5D074FBDA174A9B -:109B3000815AB04FE03872C13CFB94540EE99263F5 -:109B4000C5F5EE3F09F9F71809DA6F20F3494B63C1 -:109B500072EF1532E08DC14FA4CB0AE6295AB0EF5F -:109B6000B0791AF29BDDC5D625DB419CFD9A1268BF -:109B7000CBABEF776ABF15F39E5931324EF31ECE51 -:109B8000E0BCF733BD4FFBEAF170F61023A1777507 -:109B9000EA317CEF4D2BD017A56E5A709FBB5B7ED0 -:109BA0008789F2B707F9C6368EB11E8DCA9D3D3A38 -:109BB00095233D312A3F19FCC467C759BBED699F06 -:109BC000EE4339C8DCFD25EC8F79DD899DD86F9493 -:109BD000F58FFD2A9A7E484798EF3BDE382F6FF1CC -:109BE000703ED67802846F9B87DBE10658242F19DC -:109BF000BDBC9F5ED3EEB473C366606A3DB0FF82A6 -:109C00002D750ED86F5CE4A8EF5E2F2F79B8DEF0CB -:109C10002A09305BB12CAEC7CF4A32D593E5C513C4 -:109C2000687F28B354B20B0625A7DE7ED4C3F7BBEA -:109C3000273C1AD11983896F9F65FCF0EA1EB27B1D -:109C400022B5F30FE7903FF5AAB9801511EFB85E82 -:109C500057643C882ABF1E2F58E74F4956DCF3272C -:109C6000C0A769F4F7763AE47A9787EF7767C57A01 -:109C7000917D5637EA9918134320F9301E473E78F4 -:109C800082ABCC16C687C15AD5407F68A0D7537423 -:109C9000DF71F341AEB92586FAD1CDF76F09397A74 -:109CA0005AF07DCD99F7909ED8AD7BBAB221E4DB16 -:109CB000D12ED4F3036D1E0FCAF99F0CFF5C746C98 -:109CC0009FE4DF241DC4B78128B79BC774263FB823 -:109CD0009EA35C7E0CC875D17B93D1254DA7CBCDBF -:109CE000BFB79B3E9BEF35B59E44B615F19B481020 -:109CF0007EAB94A2F8FD47F1DDC62B3489578EE385 -:109D000065FE69E0F594943C88EB7B8F90D73DCA63 -:109D1000B8867A216ECB4D90AFA3E97A4972C83BE1 -:109D2000EBE7F3D8CFFDD80FAB7FBF32E1E8C7AE8A -:109D300017463EF07591E0EB42F9A3AE0B1BAF9DC9 -:109D4000026F03B25CAE5B8ACBF5DB8D97BD9FF6ED -:109D500005AF02D437B5A104D9DFB342891CF2ABF9 -:109D6000BF5E35D0FE618E12EDD7D4D428F093EAD1 -:109D700037C6B0FE607823D9E583DE04D9E947EA27 -:109D8000BF66DDC6E8EA3F53033E93F903C1AB8EDD -:109D900018A8178FC8E4AFF59F699E952A32CF4166 -:109DA0008C8F31FC03881FD9D5EAA4118EF8F68771 -:109DB00098E263FDBCD10A59D4A7DE901543BBBB22 -:109DC0007F9166F651AD04207FFB821F684FB64E2F -:109DD0006F1F0C0D7D4CBE6C6A1CF6279D45DB97F2 -:109DE000EDE1E8C7137D92E37D513C2AC1DE29589D -:109DF000A7FE196C68D8B5649D6D9EE23BA3A5458E -:109E0000C17D130226CE7F3CD1D5F73BE4D3F76466 -:109E1000D2836EFEFCB59C0CC8CBA6606F3449F3B0 -:109E200066F7775DBD427A546984AC4FC251135DC9 -:109E300068DFF6377A28BEA68436D494B5BB1BAB50 -:109E4000B3BB41C43D6C79E8F8391F376072FD1D22 -:109E50008671C0B84A0DF0B8462D1812507B534A8F -:109E600050B06415C553A2FEB7BADF5BA85FC9DA6C -:109E70000B6783E7D0AFC2FA6D7E1BFAAD80AF1FD0 -:109E80003E45FD32F5103D3B63AA5F6F2C450FE167 -:109E9000CCD9B3F272E04DE82F49F2AD784C5A9F1D -:109EA0007051C43CC48AC1E89D0E7FEABDF27C4774 -:109EB000DC54D5873E264558D9B8CD1A2FD00FEEA1 -:109EC000F9EDC681D0BF6CDC628D57A137D0EC2E86 -:109ED00016971A5293D95EDCBFE786288E084A8A05 -:109EE000E2C2C352DD12B49FED7A4AA39A43BCC2C8 -:109EF0006D561AF5C5F00C8F299BD8EFD851F40791 -:109F000040BEC14C96892F298DCA2F0BE9F9CF721B -:109F1000384A788A38577F05791FEA297F3EA1AAF7 -:109F200066B2983F9396B9FDA2068ABFBF5AEDDC90 -:109F3000212F9BCEB70CF28E3D1FAE652EF7E55C50 -:109F40007C500E94C6EF1E433E0C35AC8B95A31788 -:109F50007466E714F845A66AED94CBE3B1A7181E22 -:109F60001062C2B3B2CC38627EF5AB4D1EEF40A595 -:109F700088E771C23E637847A4995C4FE3DFEEB691 -:109F800083398CA3796F0B59387FB2F524C8ACFEA6 -:109F90000F1B6490DA110EBCE6A1F95C6592BE6AF3 -:109FA000E1FE9DC5FE211D9155AA63DF42FD39B931 -:109FB0006F35A1FC3BE1CFC9CE78667FCFB3F0B35C -:109FC0000553F8B34756B178B1A2761E2ECE8FBA9C -:109FD000AAF8B19FC90B3079D9C7FC46C614C8305E -:109FE000BF11E13DCC6F04F2270D2A077A5AA8DC95 -:109FF000854D57E2F9596AA4A909E3A59F8E7D9082 -:10A0000055D98FBA83CE55029D183FDF69C3EC89BD -:10A0100084B03867F941FFEF3A301EB3D3CF618087 -:10A02000890ECB01CB7D18EFDF19E6ED7F26873A4D -:10A03000F13C62BF384702C5D2DE57E0FFE7652F2B -:10A04000D18136106FFF9B5EECCFAF08383D87F0B3 -:10A050009984191F111FBFC6E1C681B9D43FA90059 -:10A06000365E7C601E1F6F01B7EFA17543053EF69B -:10A0700091FCDF84877048736B1D1E2A836A9A8067 -:10A08000DBCDFE5A817795FD8092E4FB9D882B9570 -:10A090005E3715F6358147A5F907F44B317EC1F4DB -:10A0A000701AC7FDC7E2FBF45B3DEE7EEFB9F145E8 -:10A0B0006D9F482B8CC57F29277585C161EB70AEDC -:10A0C00089C1911B72695ABE558EFB6B5917F1D02D -:10A0D00024AD7F9BCF8ACEED8EAB5DF3E88D5A74B5 -:10A0E0002EE90FF1F5572DBE2B719C827EE0E9CE53 -:10A0F0008644B874BBFA8467CADE62FFCDE80A4CB6 -:10A10000D96BECBF5AABCE01D7B45FE4A81F36E7DA -:10A110003BDE7BF57738DE9FEF3C5DE6A2A3D9E618 -:10A120009F80636E3AAB963BC510FB5C9ADB8F93C6 -:10A13000B0D88F2BC167163A61DEAF0F6EAEE1F675 -:10A140000DB763FE13883A6E3CCC02FD2B633D0EC7 -:10A150001B1E096CFB36D732BDFF7EED131487B38F -:10A16000FA15F05F353D4E97EE4C519C2DDDE7D34F -:10A17000FBA31477A338DB7666C8FB58B9CD9BDC0C -:10A180008AF27BDA3F370B11EC37B502E3D6FDAE2E -:10A1900078825B9EE29FBAA9E879995D8EF4F0F827 -:10A1A0009F0D6B8DC5F300EE55F879FD77BDC97B2A -:10A1B000110FD48D40715AA075E035F8FEF87CD3AC -:10A1C0003AF805F9FFFC7C4C85F4B166464F86F9F8 -:10A1D0006B3B0DA49BAF9391A6755A9C3DDF5BEB47 -:10A1E0001136DD04D94F998E990DB89E6A94093ABB -:10A1F000B7AB8917C7E77EC523E6EDD6B2F4B9E75A -:10A20000E3560CB4B2767BE7481EE2FF1C4FF61013 -:10A21000C6A31A3DB4AE775BEAE378D4BEBBADEE1D -:10A22000268AA75BAA47263A725AB1753828ECA647 -:10A230007E113FDDD3C8FDD6E73B5ED7F0BC668F0D -:10A24000D949F9004AE687D47E58F03BB3F804C5F3 -:10A25000C9874B9CBFF429DCCFEF0F07BAB345DFAA -:10A2600047E87DA6A9E38587900EA67F0F917F061C -:10A270000D5B181DBAA52F417EEF9D63797E81721B -:10A28000B5DA437216C1B89C8CE7A24EFF79EF6A2B -:10A290000F9DB366F49089F6FB29EB0DA08D48D194 -:10A2A0001BF07CB1E6F8953AED95CCDE6928B0F369 -:10A2B0006B56A556E07CD974F9607DD1F990E66EB5 -:10A2C0004F223FEF5E0206FA63BEB95DB94758BF41 -:10A2D000A757FA7454055787AFCE7D13E5896D2BC8 -:10A2E000E827FBA2560EED267F77100CF63E123BB8 -:10A2F0004C76941693C142BBEAFFCA345F4C671098 -:10A300005DCAFE9547D7B0F6EA6ACF2CB2CB5AF9B0 -:10A310007EA3B37FB8DF6871A75D257B73D4DFFDB3 -:10A32000E38FD3B9B2EAB2AB1428A88F76D7EA0D7F -:10A33000EF692EA20FEC521E8FD0B92EC8B794B57C -:10A34000B343C73FFC0F2F16F0FD84E2B2D385FD67 -:10A3500066F753CA7E3BDDB3F51F5E64B29CF4F230 -:10A3600038A8A25ABFC47579429C2FEE75E5DD244A -:10A37000BD7CBD9C16EB186716FD6DF48F915F03D5 -:10A38000D76CE47E16980E3F86ADF7D34A819F6D59 -:10A39000EF7719ABBC3F3195D712F2C7CBE4B5AC20 -:10A3A00057928AB74C5E8BBD5E47575B1063F33B99 -:10A3B000560BD93E9CDF35166C467995C0ECD379A7 -:10A3C000FD09FB1CA509E5F01AD882EBD7504C3CDF -:10A3D000871C6C7E3773144BE3AB449DF251691EAE -:10A3E000B7BBE671B6D769877B2151936BC23846FC -:10A3F000EC26C463775435713D7A3DB76CDD644C0F -:10A400009F4758C1F586379A8362E3DAFCBCC36B79 -:10A410002DF4629C5D358F2551FE3B55F27BDDF5B9 -:10A420006FF58A3C962650D03E4BE33AC1F5DB658A -:10A43000F1BC31494F3D6C12FA09C7B956FC4DCAFF -:10A4400067FB940CA919AB006EF436713DD3B19142 -:10A45000DB3DD78324D762FD24ED5F0D962EB1BE80 -:10A4600061D4B6CBF4DB62EB0BF4E48D423EA7DEA5 -:10A470002763EF73BCF7723CC3C26ED637C7D62FC3 -:10A480002AD2BEB6B89EBC5EC8F58D5E614FA437B9 -:10A49000535ED0A0714B02F93CB0C632B7A0D64291 -:10A4A00019C17C941038EC6326DF37223FEDF89118 -:10A4B000A227A8B4ED8152F3EFB603BC3167DE49A1 -:10A4C000B5E7B6F1FD37951DC7BD3FDBF96DA8F9BE -:10A4D0000AF9E4157C6815EB65CA5ECA88F56E5208 -:10A4E0003E90AC5A498C4BCA1238ECADBD425EE48A -:10A4F000007FEFC683F9CF77E13A952316F9D7109D -:10A500006AE3769B621AEB8BE06F9F733E21F278D1 -:10A51000E39977D3FE3756DB49FBDE805E5E7FD85A -:10A52000FBEA1AB841C3B8DD6069FD3156A83FD4D3 -:10A53000A8C7B98E857FCFE8378AF1D9E6534CC4D6 -:10A540004BFBC31B6365E382AEF31553B51E22BEFE -:10A5500094E6DB23E7C3B7319157B763F0E51744BF -:10A560001E82535F2F2EA9AFBFE0D0A7425FBF8DE1 -:10A57000FC7FEEADE07FB57118FF76D9383983A93D -:10A5800078254DF48C1AFBD2148FC1F58D7640A638 -:10A5900083F215200EA417B121EA3BBF6111DF023F -:10A5A00022CEA4363AF719391A70C0B1EE3460BE23 -:10A5B0001AF68B74FBB7AB34AECD6F66B3503E99D1 -:10A5C0006D5FE272427FA4547E9A5DDAF11B3CC655 -:10A5D000394BFBD4C78F207F4F8580F687D2F43B61 -:10A5E000C789BD37515E3FB9EA4348315E2F722EAD -:10A5F00038BD9D02AF17E8B5FFE3D227D693B775F4 -:10A60000931E058F89F1CBFED8464832BC8780EB7C -:10A6100093112C57623EC9121DFDDFEF7A0DDEDE6D -:10A62000E0FE9D4713717AA33A7FEF6EB60F15B324 -:10A630007F2E56B97D7CFA13A9DF625E427AA76449 -:10A64000E0FE76B2274FF6D3A6DC252AE6A55DA26A -:10A65000CEA47A9BF637A96B0BD6E726E0E7FE0C73 -:10A6600011B5508FDAEB4FCDF85E403A4F64785C0D -:10A67000E344E6DFE85CFFC401398B4C3D31726393 -:10A68000D9F57352E86DBBDEC903B285FDA547A4B9 -:10A69000EC02D6FEA462458AE60140969F070BF8BD -:10A6A0008319D92197A7772455D433277B34E967B9 -:10A6B0006C6E6E473A19FE9B324D2AFA6495E89A01 -:10A6C000A13AE7D3A67310F3159AA6F27706A36F03 -:10A6D00010BDA7D873B94C3C69A7D01383D1E2FA57 -:10A6E0002420CE5F03DE6CF1BC0717BDC116E7BAAC -:10A6F000B4F11B16F914C33AC76B38E6A179186E8A -:10A700002CAFC706C43CD8F50663FCBC755049683D -:10A71000D5E0E3D59DF8941A475B75B80BB7F91AE5 -:10A7200048767536117B5FC63802850E0DF49F9E04 -:10A73000923EC4D6CB0F6F0B59520C1F4EE4BEC9CC -:10A74000E898C5FC1DB44F752B2BCD6DC3BC4E19BD -:10A75000306EFCC89FBF917B15FD51E6FF205C6BFE -:10A76000A4D65F6B601E5C52C275B51B953F75FE2B -:10A77000AEFE8E56B1FE18FCD1A1CEB5188754207E -:10A7800021E2191E03F3F568E97B4AEB09D49E67C1 -:10A790007D53ED4AD2E9F28B7CB0A1BCFFBD95D7C9 -:10A7A0004FB37FA87766B9FCACDA6EA7DD5DE37ABC -:10A7B000BF57C86B29BFF2AD1A6726BCACE1B9AC74 -:10A7C000D6E6D1B3581F52B5B8DF466E5100EDF84A -:10A7D0009986DE8B21BE4A7CDF053CCF0DBF8828E1 -:10A7E0005C7F9F51B91DDB78E7A725DC9F4EA197C1 -:10A7F000BD18E1BC594C7EDD76DF887182E2894369 -:10A8000070B4AB19EDF92D1E3A4FDADDB6AFB6B024 -:10A81000FD77C43853F30F86B29C4E65C99F57DB52 -:10A820003C16EE5BE73BFF6E3FB9D2FC376C75DA46 -:10A83000C5E73A2F2F21E2CB2ACFFF858E63CFDBEE -:10A84000F4F5C1F566E39D2F521C67CC2CAF6FA6C3 -:10A85000CFDBCB346F9136B08AC5717E2CF6317761 -:10A860005E9F062930313FF115BEFFC8CDCB63078F -:10A87000CBE81F39EEF23F443FF90F021CC5FD56ED -:10A88000312A7C0F7778BFC2F6CDE0F62BF72B4B41 -:10A89000313FCBA23CAFD11E8B9E4FCEBFCF23F01A -:10A8A00095C0B35CE81583CE3FF72B646F78E02C3E -:10A8B000C6414007C3963BC07A5DFB158AC7182284 -:10A8C0008F80559D89ED80F4D2624CF6ACA7737AE7 -:10A8D000EA073BE271986E0EB386344F5ECB22BC22 -:10A8E000948C7627E3E72EBF800D01D70A581770A6 -:10A8F0009380611FC14195C11897F7667482030266 -:10A900006E12709D806B053C5FC0D23E8277A9BC01 -:10A91000BF9D4A96F71F10B021E03A01EB029E2F2F -:10A920006038C8C7F77118F7438283026E12F00CC3 -:10A9300001D70AB859C0D241824BCD5F206E117F3A -:10A94000A7E6BF8BF30D40F89B0917DC3D55BFC050 -:10A950001F1DEC31A4C2F3436F89F8D3121FD73304 -:10A96000131D09CA5362FE42FA44E1B963ACB8BC94 -:10A970005BA2DDE4B97994D52B1ABFEE2DBA2EAACD -:10A98000C56FDD79E2F7DEFF20FC6EF6D9EB9EFBAA -:10A99000E7131D26E1E9EECFDD0EED2D2838A70FD8 -:10A9A00028D934C66B988D44FE8E5773E6B3DEED1E -:10A9B000E3E79CBD3E9ECFDA2FF09BE8E0E70F83F4 -:10A9C0000B02D983D2F438E35FF8783CE1FB369E82 -:10A9D000DA61F27B8279B662C90FE27ED468BCB3D9 -:10A9E00042FEBAF2FF0AFD65771CE4DFF01D1B276B -:10A9F000102ACEA7BB27F5CD2DE913ACAEE667CF65 -:10AA0000D19FD1A3B1C6C2BC69F11E248F4CFAE517 -:10AA10000CAB67E78BC8D43F8F1737F278B12CEABD -:10AA2000D3384DFC3B066B09EE33EC798B18479A13 -:10AA3000DEAFBB5DCE57C7E74BE063E7A7C8F01CAE -:10AA4000F533898F92207EB99F631EB21EBAF0E75C -:10AA5000170A7B8D12E365F8F94BA5F69F15F232C4 -:10AA60004D3E4BCCEB7FF3D976CA610BF3816C3949 -:10AA7000B2E5EB7CE5E882E50437A4B6D2729286B3 -:10AA800014AD1B055DCEC5E72E2F45E4245758BFF6 -:10AA90005EAB15E7F926C90BC34721B9D5393EF599 -:10AAA0004BA2D49F846B7C21F62060E403A3F75271 -:10AAB000AD56F081C7290278CE58D09E1147F84A8A -:10AAC000B224F43EAFB746E3EB7C756723C71F445F -:10AAD000FF2E7C597F5A617F3234BAE49CE3FD7EBD -:10AAE0008DCF2FAB4FDFF94D1B5F91085F191269B6 -:10AAF0000F6BF75151DFADBFEC7287C06FD4035BB2 -:10AB0000F977920928FCAE32A879C4778F7C9DB979 -:10AB1000F59317E56AE9F9CB55B57ABD5E2BBEEF23 -:10AB2000303DDF82F1BE52FBCE316D723F6811F3D2 -:10AB3000764EF3FE6BD443CBA6E6B35A7C2F15E3D7 -:10AB40009E2BBE27A7E35B959CBD21F444B5F8ADD1 -:10AB5000394FFC5E76E1F756C9F519B11F558BFFE9 -:10AB6000FBCF531E7E309DBF55AD238F766EFCFD0F -:10AB7000E879E2F7CF6EFC4AAC5B55E3FC4A0397F9 -:10AB80000F459CBF548B5F4F65FC44BED8BA012B68 -:10AB90004EF61AF9E3BBB5750369650A3F0BB85E5B -:10ABA0003FD7F1EFAF7AFC770F58CAD4F88F68EF30 -:10ABB000768CAF2826095BB5E33E5AEDB8E9F73944 -:10ABC000E87E7AE47D8E71CF97EF5FAC7AFC5B1DF7 -:10ABD000743F3772AB93EE9049F9C4D58EFBCDF339 -:10ABE0005CEFBF14F80635DDB10F94B2DFCF08BBC0 -:10ABF000F6839AEE90E352F5DF10F6CABBAAAC7F5B -:10AC000052F4DF6CE353A1FE3D02FF7BAAACFF6B65 -:10AC100081CFCA2AF1F9BE5887A5F6CF80E07B1014 -:10AC20007564815F73A1794B5B7C49C98FE79CCFC9 -:10AC3000F4D077826F289A8EF14EE802B2C7FDC732 -:10AC4000C307795E495AF8FFC9B4C4F530C5B7BC2B -:10AC500051D3711E67FB5D8A92B08A9DB7D5FAB950 -:10AC6000FE9374B39BAF7715300FA954FDA0BF7846 -:10AC7000FCA5062628FF0462E21CE9CC8D46D173B0 -:10AC8000022541792DB2AEC24136CE40ED46A33009 -:10AC90006F396EE313B3081F55E7F8A88A6915CB1F -:10ACA000539EE3E7F36AF763FB87526C02F83D0EAD -:10ACB0001CBF417FA21BF3C4D3B52AF16920EC3C31 -:10ACC0001FBF49F4F34E41DF80B77C9E58E7CC7636 -:10ACD000CA57EA6FE7F94A069894DF39102A7FAF1E -:10ACE000C1580F8FFFEF14F94F23F8FD287E4F8CCA -:10ACF000DF8F2EC4F65FA1EFF04EB57ACADE8F1358 -:10AD0000369D71F6608BF37B1E3B2EEF379CDFF593 -:10AD1000F862CEEF7ABC3315CAEB1A08F1F3814A18 -:10AD2000F8DB79EF76BD6125A5E945F994759C0BB3 -:10AD3000F8624E7CDF3EFEF1F641EF61BD185E6FBA -:10AD400015DF4AC51B26E9AD515359AE371CF91919 -:10AD50003D42BE7C355A0AF532D3BB25DE0778FB6F -:10AD60005082F243B458C2A078B4D807345C0F05BF -:10AD70007CFAA4BD2E031E3BDF98F23A24C3A2F353 -:10AD8000470DD79134BDDDE4BCDA72FFFBB5315A13 -:10AD900027F51AAD13C998A0EFBADCE32CF45BFBDE -:10ADA000FC783EE6B71EC0D2FB0739596CBDECF506 -:10ADB000733DAADD9030B4F9E4AA92DDE3C6E34B1B -:10ADC00062FD856CFCD316E55F548BFFA355E26FE3 -:10ADD0008FC3F0FF1CEA5986FFE7B12C85FF534271 -:10ADE0001FD581D14B7BB6C1F52CC07AA330BE1ED6 -:10ADF00008F07EEB849E02E870E4F578055DD5D21C -:10AE0000F3ACADD72AD0638FCBE87951CCC777CAE2 -:10AE1000CDC7B7053D8100DFB7B40309832D4DB819 -:10AE2000B8C4BC9C1078CC0C88B852BAE39CE4EA55 -:10AE3000A52AE93831352FAF8A79F9E772741C17E2 -:10AE400072959161E549DC4F9BEDFC850D8E7999FA -:10AE50002DF893F1D9F3D2E99897DA739C975F555F -:10AE600049CFECA979392DE6255F4ECE0AEAFF5E7F -:10AE7000D4FF83A84F76E2ECC0EF06F0BC6CA13F94 -:10AE8000E109D44FED6FAC9E1C583655EF93A347A4 -:10AE9000EC7A3EAAD735594F0B14F407E9D706F0E0 -:10AEA000FC7B507CFFF1FDD1F035A25D84DADDC082 -:10AEB000E961ED6A0AFBFFD2E82B76FF33B05EEF63 -:10AEC000DA3FD8F5A285F56607FE60D78BE173E916 -:10AED000C0647F0D85789CF0FFEB00CFD771E57BD8 -:10AEE000E9D5E53B78A349BACFA10EC2199995439C -:10AEF0000ABF5F21CD8CEA43983FEB4BE6A00ABB2B -:10AF0000CBA3F1763E666FE1F9F10C1D9EF71BE8CD -:10AF100082987080BDDF1355C81FB8D39F6C0BD4C7 -:10AF2000733C290FE0556E8FF586DA441C85E3B536 -:10AF300037F88111EC4F677861FF9F0C469EC7FA86 -:10AF4000FBE6A894CFFBFC9CBBC84EDCDBAB00BE91 -:10AF5000DF7B9D4A76E203AF86691F1E54CC9B2897 -:10AF6000FFC1520DB41BEF0EFCE118E6298FF7D696 -:10AF7000E8D255440FE19FF640A29FFAE776E776C4 -:10AF8000863FE603D3D685FD76713F06449EF3DD0A -:10AF90006B0DCA9B3180DFDF34DCAE529ED2DEC641 -:10AFA000F91D38DE03ED1AD91D0FDC30BF97F2B959 -:10AFB000DB0394FB56173224CCEF89AC50013F04DD -:10AFC000A98B1ABD6877869707F0CE2FA86BE4E3AC -:10AFD000851702DDF3E7854C22CECAC8884AF738C8 -:10AFE0003D70C386DC66B46BDA79FE3223ECE5F89B -:10AFF0007280906025C83F00C4C73B9B9FE7DBF38E -:10B000001CC94CB62F7B8E18C956592F575DBDF001 -:10B010008842F9C915EB65AAAC97ADB25E8ED7AB85 -:10B02000787E2FF22935F60FE3707E773E76A8FC06 -:10B030007771E79AAFBB37E0CCBBAED4DECED3ADF1 -:10B04000442F1E664EE22957AE6FE7D9957AEF9DE1 -:10B0500079570CBF4B1BAEBF5794F7F1B2413C6F11 -:10B06000D81EA3FB221BC4FB86FBE8FE48773F7F6C -:10B070002BF4710B24CACE439DC0FF75863BC6B32B -:10B080005B940AF900EE7C3F97DED3947427ADDB26 -:10B090001B787ED1E4F7938DE2BB114825E214CFF3 -:10B0A000B2228B674EAD1FEFAAEFD2FAB1BF9B64FD -:10B0B000F3C3BF9774C9895B2E7CAEFC940B959348 -:10B0C0001FBF4D72E21D91AB5A3FDE4C95F5B25554 -:10B0D000D6CB55574F1D91AAD22B6AA6CA7AD92A28 -:10B0E000EBE578BDC195AAD8D7470731BEE5BD428B -:10B0F00073C08357049CEFAF0C39E0A165CEF6EA2C -:10B100007267FBA1E5CEF6EA0ADEDE0CEEBF261D75 -:10B11000AF7E9DFCAFF35C272D5AF9FAE1F60AEBFE -:10B120004AD3FDD8BE4E3100EF1762FB5556EC5B9B -:10B1300045E33FEB827CFD5F17D01DF7D3FDA9D31C -:10B14000D912E4F8DAF456C2D7D6BFFF220BBBAB54 -:10B1500044DE3D7E564079D830DE80FD3D7FCFCC49 -:10B1600006B4E7F6BEB682EEEFE87F979D376352EE -:10B170003EA472EC9764BFECDDCEEF977EB4D6ECC4 -:10B180008AA3BD12F600DACBCC8DA27B3DF6C63C7D -:10B19000648FF45F5DFEFE924FF5F03CA187D1EF26 -:10B1A00067FAFF80B877EB4171EFD6FD3D0695BB9E -:10B1B0007B5AA8DCD5635239DAD3CEF3197B2CF154 -:10B1C000DD5917955FEA49D0F32FF47453F9F99ECE -:10B1D000243D7FAA672B959FED49D1F3433DDBA921 -:10B1E0007CA2274DCF1FEF19A1F2B19E0C3D1FBAD3 -:10B1F0007A03DD9371EA3E0F7D1D520AFF392967FC -:10B20000DC61F65667DCA121E98C37CCEA76C61BF7 -:10B21000F455F31DEF236DEF70C0A1D6258EFA8192 -:10B22000F8150E586BEC74C04AE89D0ED87C6E83FE -:10B2300003BEEC999B1D70EBD39B1CF03B3EFD11B4 -:10B2400007DCF2A93B1DF0C5FBEF75E0171FEB73A0 -:10B25000C0EB83F3F97DE0033B1DCF8DFBF639E0B6 -:10B260008FCCB41E0B623C3413E1F6EC7189F6C14D -:10B270001973CDDBF03B29F8B14CF204519E0F3F1E -:10B28000637EEA72BCA70C94D48A1BC395EF91B677 -:10B29000E33D72A43D89F27AFA35C9407B578A6C46 -:10B2A0005F58E8CFD9E5D65329388C71499167A604 -:10B2B0005F0496C5DA05983EA1C34548E57650DCA3 -:10B2C000D243DF5165A424E59B309BD9FC2B1DF3B1 -:10B2D000E8DDFB6F90ECF253519ECFDED1A9350D26 -:10B2E000B0FABB17A926A6784DC3D775BFDDAF82CC -:10B2F000DC0FDEB583C72BF517FC4D1A6B1F32939D -:10B3000033D055B5DB8572DFA3EF944286B91CFDBF -:10B310009A503C039B43588F7FD7C7EA7F3558200C -:10B32000BFA164CE5259FDD89664B387D5DF2DFAFC -:10B33000DFBDECC7748F6038F713B898FC9DCFD091 -:10B34000F8E1B6A3707B18F5D338AC2BB28E77FF3B -:10B35000BEF8F748E34199DAEFEECD82C9DA05721B -:10B360005FA77B38ED7909B61E8524F6BB6A82BEDD -:10B37000A1DDBD43A27E764B2FC56282CE5E179DB6 -:10B380008817D2753BEB27D49D94D6B5F2E7CDE173 -:10B39000A97EF1FD667C7F4B4AC23CF76AF8A72282 -:10B3A0009F928C7FB8DEB664A4B2FC337216F25B57 -:10B3B0008B57E2DF839C7F8C6FB7B74EE7D764FD76 -:10B3C000F45158DE5AC06FD11EF9727B11BE4EF295 -:10B3D00089B54F52FB97606988B7433E8419DD9B5E -:10B3E0008BB5935E12E3649DE3303EDE4ECFD322F5 -:10B3F000BEC8EFF5B4F344ECFAF8D7B55CE42932F3 -:10B40000BABDE3B59BF1FBEB8ED624DD033C18F20D -:10B41000D0FD4283A1AFE4E89E7E1DE8FB5945B113 -:10B42000FA7E14E571E83EA9D83A75FA09F8654A3A -:10B43000E1F76403213B0FBF82BD24EE1596C5BD25 -:10B44000C2AA92E86AE2EBD9EC85A9F8EAF4F1F72E -:10B4500011DD72CCB9FF0E6C71EE7B71FD668A63F3 -:10B46000F747ABFB6EC897E7F6A52AF0F1E683FC39 -:10B47000BEE3BC9FF0B4F233A85C93AFA5F2AAFC84 -:10B480006C7ABF3ADF40F0AA7C33C157E69BA8BC78 -:10B49000227F293D5F99BF84E0F6FC522A57E417CA -:10B4A000D3F3E5F92B095E965F49705B7E2D954BD2 -:10B4B000F31D542EC95F4FEF17E7AF23D8CCDF48F9 -:10B4C000E525F9F554B6E4FF8CDE2FCCDF44F0C55A -:10B4D000F9CD042FC8DF46703CFF51829BF31FA6B5 -:10B4E000727EFEBF52D994FF18BD37F21F27785ED7 -:10B4F000FE1E82E7E6FB099E93EF25B831BF8BE085 -:10B50000D9F9512A2FCA3F4065437E2FBD9F957FB1 -:10B5100088CA99F927E8796DFE712AF5FCE7C57D9F -:10B52000D14F5119C97F95CA70FECBF43E94FF1BD1 -:10B530008283F9AF5319C87F9B4A2DFF3C9595E64E -:10B54000A9D2F74F6B6086432E56E72F72C0574E35 -:10B5500038F7EF953F77EEDF2BC69738E065C79C4D -:10B56000FBF7D2A39D8EF78B8FBCD3015F9273EE56 -:10B57000DF0BB3CEFD7BC1814D8EFACD998F38E0C4 -:10B58000A611E7FE3D2FEDDCBFE76CEF73DA2FA9C4 -:10B590009D0EB861AB73DF9E050FBBF2C90F3AEA8F -:10B5A000D7589F73D40FB77FC575BE92E5FADFFCFD -:10B5B00086D38E6979A1E8394C7CFF75F4DDFEA94C -:10B5C000468FB86748DCDB2AEE4773CF679DD00310 -:10B5D00033F2DC7F8A8A75578FEBAE20EF89D91959 -:10B5E000AFA17EB0ED8C19F38D2FBFC8E0D373559A -:10B5F000B397C1B69D61D7AFF8BB15AA399E6678DF -:10B600007A8FFBE8DE3929D26D615CEDEE1312DD35 -:10B610006F57371B449EC0755D3C3E01F67D3A7402 -:10B62000BFCFF01CFBFDE66B298ED1C4E123A11D29 -:10B63000EB308E3AECB5DF7FFE5A6AEFE7F0FF0899 -:10B640006D19C2F775358763681FED2A71BEF93F22 -:10B65000432AF1B33664FD30B46CEA9EE9E3D1E4E9 -:10B66000CB21F67C9B969C875776E33DF7788FF34A -:10B670003AC5FA11D65BAF58AF84685F70FA0FEF26 -:10B68000C7DCD765742FE04FF0BD1C7996F6A3BADE -:10B69000EBEFA3FBAA86C30C9F50697CFE3E244FB0 -:10B6A000EE3760EF37F3299E4AF6E05013D0BD190C -:10B6B000C3B58934DEE797FE8E06874CA43BC3935F -:10B6C00095447EE2F025862D178EFD092091C33822 -:10B6D0007E301932D05E0BC151CABF88C004953A82 -:10B6E000E892E3BE6D9BFE399C7EBCFF3F44E7F0D1 -:10B6F000D6B3E314674D81B8BFFA4D7CCEF8723AE9 -:10B70000B4AC345FAE91EF039D8DFF28B327918ECB -:10B710004781E33B86FEA98478A6F466EAD7798F51 -:10B720008472FCEB243776BC47915769CD488FB8BB -:10B73000C7A18BFD43FBB03E513EDEE3BEB7E15CEB -:10B74000E33DD1B03BDE13A2F3E453ADE5BF83B3D9 -:10B75000E33E63ADE5CF7B9F157EDFD7C479EF3342 -:10B76000E2BCF72BC2EF3B2CFCBE2FA2DFC79E3FF3 -:10B770002DFCBECFA1DFC7E027D1EF2BF8BEE4C977 -:10B7800012F7BF2CAC95849C6D27FB3E28EE2B62F4 -:10B7900023903D1F10F6FC98D93713FD8E602D6461 -:10B7A000D14FD87ADD41FA7E969162E2FD0077FCB6 -:10B7B000E2F599FF85C1F11838EE770AB4BAEE4B7D -:10B7C000A8348E92B5B0DF20F31B326669FE9C73FD -:10B7D000BF5A16FCE7D52FBFE7C7BEB78D71328DB4 -:10B7E000F21744BA7594ABBFA1714E897140FEC186 -:10B7F00011BACFF07205CAC9C1B471CE51FEB68478 -:10B800005DBF4FE1923FC0840D46EF3CF1BDA611F4 -:10B810004A37EF61EF9FB84F757C9FED96C7DED733 -:10B820007C14871D5CCCEFE579B17EDD45E80F7EA9 -:10B830007AEF9B4D889FFDDD52BFE98C5BCCBB0F3F -:10B84000A4C27C9603623FE8D7CBCBB97DAF78FF2B -:10B8500058F97A0F8A7A5F0C5A7D61D22B13741FC4 -:10B8600064FB89AE9B11DFC77668745EE36EF7C533 -:10B8700060726778D9743C0BDBA3BC9569BFAF5C81 -:10B88000FBE53FEDFA29946FFF70B8BE74FBB697E5 -:10B89000BB1EAE80FFC1E2E3A71FC376F3623CCEBE -:10B8A000D4DB3044F3BB6B07F79F5F5CB48EEE993B -:10B8B0001DA8E5F356A4DF2F54E04B7705BAFEAA86 -:10B8C000527BA93C5DDF2CC717C6D76315F8F29DE4 -:10B8D0000A7C3D5001FFBF2FC1D77988F73CFC7D22 -:10B8E00038D6AE770EE32BFA6FC85798BE1E8AF48F -:10B8F0007BAC1C5E55C8EBF805CAEBCF2BF0B592BC -:10B90000BC4E5CA0BCE64BC92BE27D01F22A47CAC3 -:10B91000F3B592BC06231726AF33CAB5AF425E67B4 -:10B9200097C3BF0A796D2E36BE0F8216DAD5A75A95 -:10B93000F939D9D60E7E3F99B785EFC3C1E39F256C -:10B940007B6980ED5733DA71DF3EF1E01D6D53FB0B -:10B95000B47B1F72F7E7DE47EFF8DF9FA17D342449 -:10B96000F67D1B1FBFE1EEA7FCFD16E73A6E007FD8 -:10B9700097A9E0F72E1A926FF578CE7D3E60F2F12E -:10B98000818DBF96CE159FA673C59AF60B1DB77C09 -:10B99000FD59DD1766177C28E2B40B666FFFEA637A -:10B9A000741F89E867B662D1EFF8297035BFFF646C -:10B9B0001BCF1F92B77FF9B1934B0BEE9982C35205 -:10B9C00061BE90BCEDF063270BF0CA63FC87C79B98 -:10B9D000298F31AE5F11A07BEBC6CA9F67FC40EC9C -:10B9E000E3DF17E71947C479C677855DFBA2B06B23 -:10B9F0005F10766D4ED8B57F2BECDAE7845DFB0DDA -:10BA0000719EF1A0388FC8F41C20784F4F56FC4E21 -:10BA1000C993E2774A0E8B7CC967F9B9454F8EDB33 -:10BA2000C78F7FAD19F93145873B8EC5E9B0EF4728 -:10BA300077D3F12ED379DFC6F52D41C7BC5D6738CA -:10BA4000E322D7C6663BEA5FA3373BDEAFD52E7550 -:10BA5000BCEF80A5CE384BFE0A679C65C21917B9AA -:10BA6000F2E7CE738D95E3CEB8C88A63373BE32CFB -:10BA7000479DE71A4B8F38E3228B73773AE0CB9FD1 -:10BA8000BDD7517FD161E7B9C6A54F3AE322B3BA1A -:10BA9000F739E05AEB61E777F5EDCEB848D874C6D0 -:10BAA00045822D5F71C0EF61FB3DEA4FBFE18C8B9A -:10BAB000F862CEB8C84F43FC1CD0F6B359BBBF8B5D -:10BAC00090BF19CA5DC9E4FD8928BFE7FD09485246 -:10BAD0009E2CC09F93DFA04CFA0D16AD7B59E81D3C -:10BAE000B5E1E48FD1AF517673BFE70E69454E2BB8 -:10BAF000F47BBCFF2215CA87ACBBFD870AFD7B4DDA -:10BB0000F277940A7EC9F47EB9BE9ABAE7BC2D8D4D -:10BB1000F954CAA45F72BDCB2FD996A1DFB39A5155 -:10BB2000DE2F9936CE39EA9FD391127E49CC43FC61 -:10BB30003314EE97EC32855F02FC7B29BB3F5BFF41 -:10BB4000A80DE5F5887D5F8BBA88FB0D4AA8F879CA -:10BB5000B67DDFA4BAB87C7FB65FF37711714F5C16 -:10BB60000D88B8FEFF978FB7523EAEAC29113779DA -:10BB70009BE5A354BD73950F057506E5837C70188E -:10BB8000F3417C2E581370CDFDDBD6E1F74DDB8100 -:10BB90009FEFC02BFCDED552FDDBF95DF155B7966A -:10BBA000CD83B0E3AC522D3FFF8CB7DF4AF993A7AA -:10BBB000D818E5EED576E75BC8D114FEE81E7ECF37 -:10BBC0005EF4DCE79FEA785C28DEFD81B2F68AFB52 -:10BBD00077C1E256F97B764705FEDF7E7516D9A957 -:10BBE000BBB6717DAC747FF37994C74FA33C9A14B4 -:10BBF00057D12E41BAB62974AF5AC8008A0FCE0D5C -:10BC000041B6B709F96AA6F13E2FF647E7CB93F2A2 -:10BC1000B9CD79BFC9EF74BE9EE389F27CADF8BBA4 -:10BC2000062B0F77D0774206A4F45A5A3FF07A9445 -:10BC3000F023391D6E37F9EFDF317C747D7A7B3765 -:10BC40005EEEF5A96CB98AE24AB3257B7D064DCC40 -:10BC5000D739150A95BDEF6D5ABFE7B81EBF306DD5 -:10BC60003DDED0F78F38EE9888236D677F05E79D1E -:10BC7000EEFEECF568C3DF7EF56EFABE6578EC4E3D -:10BC80007E6F71A3B81F6C8CEBC752781D1272B413 -:10BC90005BD88587F677F6217F07D8BA29D4470B7A -:10BCA000FEF2BD81243F5FACC3F23307F877DB17A8 -:10BCB0003FB4453CDF44CF1744F9FD470B983C6146 -:10BCC000CC3BBCEC158DBF7F59A7FAD1F1117C7F1D -:10BCD000B178BFA7BDCDC2DFAA8CD4CEEFC4521EAF -:10BCE0003B4A7A97CDB9B5C0C07115FA1D9DB923ED -:10BCF000F038D231772CB1E13AF40FD2C07FAF2DBA -:10BD00009ADC89F21AC900F597060E1BDB759ABFFB -:10BD1000F858721FD56FE5F5D97B82E7A6F8FBE0EE -:10BD200018C317C733D97B03DF73FC1BB7E814AF05 -:10BD30000B8D1D4DAC257FC46ECFE1865B787B6596 -:10BD40008CD183ED6376FBF10CBE9F15E5EDD5310B -:10BD5000BE3FEE69DF44F7EAB1F1E9DE29AF78FED4 -:10BD600084E07FBCFB5F336BA35379196966FFAE38 -:10BD70002FB29EED756FFF0E60BFF80E49D3663F80 -:10BD800072B2E05E06FB77430363CEFDF94C0D5FB4 -:10BD900097FF1DF5CCB2CAF7B3FD3B5950D3F30062 -:10BDA000800000001F8B080000000000000BC57D14 -:10BDB0000B7854D5B5F03E67CEBC3293E4E43D79C0 -:10BDC0004D4E2040944007081810DB495444458DDF -:10BDD00068DBE0B53A04E419202296A0D89C9004D0 -:10BDE000F20206EB2F111126281A2BE86041B15AF6 -:10BDF000EF80B9147B6D9B5A2FA2A28DA05114B86D -:10BE00002915C9DF5FAFFF5A6B9F43E64C2609EA4D -:10BE1000EDBDF93ED8D967BFD77BAFBDF60E6B102D -:10BE200059C8C6E8E79B61F09F1A63CC5725B2500A -:10BE30007E58BE32C3989F3BCC58FFF64B8D79D7C6 -:10BE400078633E798AA1FDF91B18EB744246F2D85B -:10BE500018A4D2D1DB6CA56318AB4D5E4EF9DEBBE6 -:10BE6000F4726F0CE6F3E418912533B6AD400C3450 -:10BE7000E532F644D5F2C3C320BF3659A43ED7BA43 -:10BE800066C6FBA0DE37F8F3A3FE69433563212BBA -:10BE900063DBABFD946EAB6EA5B43E79F0767BB5FB -:10BEA00076CF57DB58681463C16A99F2CF56BB2826 -:10BEB000BFAB5AA1F457D5F9F4BDBDDA43F927ABAE -:10BEC0008B287DA2DA4BDFDBAAA7537E6B7529E5B1 -:10BED000B7549751BEB5DA47E9C3D50B28F5575784 -:10BEE00052BAA1BA8AEAB554AB94365537D0F7C0E6 -:10BEF000B860596941FF79D6CA00871428BFDA9320 -:10BF0000510AEB79FC6A56168C5A4FA07A1B6500D1 -:10BF1000DA44C6DCCCCF1C85F07B2B633B15C6EC2A -:10BF20009D7ED50970BD74177CC37CC8AF3A209F35 -:10BF3000FF04CF6FD2C6A962CCCBB05D150BEC0469 -:10BF40007CD8143F9B0DE379B35576732C63376926 -:10BF5000E3E07784AF9AAB32C4EF098BB7544EC19C -:10BF60007EF8F8313E9F00CB63692B588D05D28453 -:10BF70008A2E668771E21F0A796D900E6BE864BEA7 -:10BF800002C4AF586282799CF38B011374AD4C6587 -:10BF9000A208E337BB383D44AED3DDBB8D852640D8 -:10BFA000BDE42E3B8EBBAE6A663C8B020F3D1DDDB1 -:10BFB0002EF6D127FCBB2410C60FF06F9D7FF0F644 -:10BFC0006965C6F609DE88F605D01EE0102806FC75 -:10BFD00045A1B7F82263FB584F447BD7E0E3C7F491 -:10BFE000DEC8424903D3F3294B790DC25DCF8FECF4 -:10BFF000FD21D57FD729131E12AF5FED4238C3CF85 -:10C00000550867298B059A04CC7AD902C89BE1B7F9 -:10C010002699E76D90374990F7403D55F1B2B198B8 -:10C020007ABC2C0E532FE50F997D1BE589982FE5DF -:10C03000DF651FD141E012E82203E58DD2E0CD8219 -:10C04000FC8FE1F7298CDD2C8F9EAE42FEBCD927F8 -:10C050005641FFCDD9626007E075A57B7C0CAEFB35 -:10C06000F196C1F9B416F974545FDEE4F43201FAC2 -:10C07000C9AC90C79BD8C0ED1EAA10A707A2F4BBFD -:10C080005BA3DFFA8A99F2085C7507CA30C6AC4E2A -:10C090001695DE60BDBB71BDE664BECE945B4B29D8 -:10C0A000CDDB35D9560AFC703E7670FC3546CCDFC8 -:10C0B0000E4306A3E1519B57DE1B2F91BC3C3F86EC -:10C0C000D3D540FD366BF2AB3720B24EC4AF544AE5 -:10C0D000F235E5561FCB83F5AC4B17034E58CFBA5C -:10C0E000AF6F69C8057E5237892407F4F9478E6B14 -:10C0F0002AE8124C50BEEEC042A6C0F8665729533B -:10C100000B30AFCBEB20C3FE1DCE90175390980C95 -:10C11000D7EFA8F2A998B7B854E2E775E917EADBB8 -:10C12000102ECD7E91E4FBDA2C31C0044A9913E63F -:10C13000736E35A37C4EFA838C24FD57309F49D013 -:10C140000FFE6E42783355C475E4325A471E3BCC1D -:10C150004CD0CE3686799AA04A7C1E3B80EDD6A57F -:10C160007F79C08AEBBB97794628D8D847F2080870 -:10C1700094A11C595B2953FDCCD6B1C417FABA7FE0 -:10C1800062F17D1ACE3716179767EBBE364595AF2D -:10C190008735F9183300FEE21378F97973F05A9471 -:10C1A0009FCD90DF11859EEC5ABD47E5997FCA5718 -:10C1B000FAF8532F7FD7A910DFEAF9CC5E0BCD3BFD -:10C1C000EFD69FC5E3BA06A287B51A9DF9E3B9FC7D -:10C1D000CD9B7A8517E17E0EE68AFC1E597F51BC05 -:10C1E00042F3D0F392D328A72E7E7E12C9E3BC532C -:10C1F000AB383F640F4EB7FA3CCF671BED04316F8D -:10C20000818A7C5DAF007E15B417D63091EC02E6D2 -:10C21000615C45B138C83FB15A935FF95DF64B2078 -:10C220006F7BCBC410BFDBAA4A4415E09E932B055D -:10C230004C00F7F82CBF97813DE2286002CE1FF03A -:10C240003D322105E96012C1337B754810A1D31E30 -:10C25000947D29B4EC3AD7243E0EFE077C3F26019C -:10C26000D6E9DD2570F9E0E2F2C10CD3B191FCAC66 -:10C27000624118CFF19689BE033F841E807C8C2CCE -:10C280007A509EB678D6A4221F3A1218E9B505D77F -:10C29000EE20B905F2D6B30556B4F46477EA32C895 -:10C2A000E7B9F87A74F8C414580CFA61C871A4801C -:10C2B00017FB7508CCE3F70CA247BE6DBFB600B301 -:10C2C0007FA77E4191A4129F683FEDAA80E3E0BA68 -:10C2D000A15F2B7B99C639A78DC34C6F1C467E8905 -:10C2E000F981C44C51F865C0714CB70FAA37AA8EBA -:10C2F0002DFC5347183DDF95109BDC3D1A7EB98C11 -:10C300005DF60D2A0E13103CCE03EC4E13AD9FAD1F -:10C31000413CE7C8DCEE509CEAF00D50FEF86A0B99 -:10C32000C90FBDDFF3D50BFED401486C29E072BF05 -:10C33000E6436B09F6533F4E0C58A15D47CAB48CD7 -:10C340002EF8FEC4A62F73717EBA7D5AEB31F245EA -:10C35000CE6A4E977ABE55E38B5A79707DB241EF23 -:10C36000AF65F07A0F6BF59E75786B918E81D20573 -:10C37000E4CFA2E3D36FC3F96E7FC0C64C51E4C2D1 -:10C38000B30E5F73C2C4FEF30C6F8FF43648FB5FCD -:10C390000ED67ED2BBD3DF6583B77F342165E0F64E -:10C3A000856F4EDF32C4FC1F8F3EBEBA1DDBE5B881 -:10C3B0002C0CF15B93BE96F0DBFC80C563057EEF31 -:10C3C0001833CD8578AB4BE0788BD2EFB383CD0BB0 -:10C3D000E05236C4BA5E18AABD30F8BA5E1D02AE8D -:10C3E000478780CBA1C1DA035C5B8798FF1FA3CF8F -:10C3F0005FCDC179E7645948CFD464035C518E2383 -:10C400005C597F7E88D2EF3B43C065287AFDF07B84 -:10C41000D2EBC9C1C6BF087AFDDBF7A4D7FF3B103A -:10C42000BDE2BCBF07BD4A89DF8F5E9D8983C375AE -:10C43000287A4D1EACFD45D06BD660F3BF087ACD8F -:10C440008B36BE9539BC2ADA45055C9F2F281649E4 -:10C45000BF9BF3B91E761C7BCA8BEBAA037D955458 -:10C46000847AFBF8C34B0BFBF474A41E8AEC2F52A6 -:10C470008F2EFDDB93A4479D9ADED7E7635722FBFF -:10C48000F99741EDBB6F3B6E8C8B85EC63FBDAA7B4 -:10C49000FBFEBBC733EAF9180F1F9FC1F85716A15F -:10C4A0007EDDE541BA8C2FFABEE30E5E3FADECFBBC -:10C4B000D9050B12C12E70F4D9059955BFDEFE5176 -:10C4C000525F3F999297C9403712BB8AEC3756C1E9 -:10C4D0003C3BB1B86ACFF68F26F4D903007F01FD4B -:10C4E00023FA38A68AE0F68FC2E6D53B9769FBB4FB -:10C4F0004ADA17E5C95362908ED7B50C6E2FBFA1EB -:10C50000E9F1DF6B7EAAC39A9FEA10FAA920ED40F9 -:10C510003F15A407D14F05E521F45341FE55CD4FFA -:10C52000F58AE6A7FA8DE6A77A58F393F9D14F4634 -:10C53000FEA880E68F6AD7FC51414A1BAAF753BA7E -:10C54000B63A44F5DADB5E188EF0E85B07B7DBF34A -:10C5500064DDBFC7D7C158298B86AF1B3C26C3FEFD -:10C56000E2FA7C87016FD72A4986FC35AE4C43FD41 -:10C57000ABE5E186F22B6DA30DE5C56C8221FFA32F -:10C58000DE2986FA57F49418F2977F7A9DA1FEE48B -:10C59000AE9986FC65476F33D49FD8596E289F703B -:10C5A0007891A17C5C68B921FF83FDF719EA8F09B6 -:10C5B000AE31948F6E6F3294A7953D18E167DA62C1 -:10C5C000A81F5FB423C28FF42B43B923FF7943FE26 -:10C5D00026D0F728FFECCA6F0CEDACAE8386FCBF0B -:10C5E000C531DAFFD89D41AF378A3DF9553CDFAF01 -:10C5F00082DD5E4CF632C8B1A671D8BAD28FFBF19B -:10C600004CF81DED63C0AEC08643EA31CA1D5385A8 -:10C61000C538FE10FC8C1E00ACEF861FE4C7AFF4DB -:10C62000FD6CBB5DFD218E9FC7E5B02AABE47F8822 -:10C630006CAFFB8BF2DA67C563799D5C2247930789 -:10C64000272CBE93E1FA2172FF9BE78D655E1CAF3C -:10C6500042F797717967E25558E6B16B0E0BE8FF28 -:10C660002A7B3501D7A3FB79D6697C5AAFF991AD06 -:10C67000EC72F2639CD3E43F334DF50C269F22E12C -:10C68000F56DE5999814B9CF9911FA18C7AF9002D2 -:10C69000D1F4A49EEA722CEFAD3B07C58F0E5F1D4F -:10C6A0008F2639E845BD6A532A59B9B33F9C4C5986 -:10C6B000400F71FFFC75E72619E5F839F64AB177A6 -:10C6C000D845ACB7EC0E5A878ECFC87AFA7EAB0548 -:10C6D000F14AF291CBDF5A0DBF6291770DC2370E4E -:10C6E000F6D1B8FF133D21D6F51DFCC08EFC4443A6 -:10C6F0005E726618EA9B3D952C88FE5B1887113D9B -:10C70000FA18FA73F11FFA4B4C3287F3C07C773971 -:10C71000F909CE45D82103F11F0EF1CDF0A1F9F5AD -:10C72000BBF277C7DC54EAFFBE78A6F95F549EAA35 -:10C73000EC4DA49FF2228D8098F2D3F760DE0B0FB0 -:10C740009B49CEFCE8ABED871E03BE341559E526A8 -:10C75000F20CF90FFD16CAE77A6DA5985F786C8C1C -:10C76000C50DE5473280085C585E1A8772E03413C5 -:10C77000A7A3DFEE347B336E42989CBB27C942F2FD -:10C780008535988F77D9707895CEB1EEF2F3BCBE2F -:10C79000AEF9ADC6FC3C3633558271E63D646601A8 -:10C7A00000D642261DEFD2E10074302789FBDFE777 -:10C7B000B3CAB5328C5B6FE6E7364B5E1C63413C17 -:10C7C0002C9C20E79AC6F5CDE3FE2491EA7F06F47F -:10C7D000A658FBBE2F72062C28974FEC9DF093CBEA -:10C7E00019F613589B81FECE04B04394FEF09DD3FE -:10C7F000609CE750EB889C37BA41069B87D42E7823 -:10C80000A3F9D51B9304031E6B6DBFD8DE05F3F4AB -:10C81000D64ACCFE43C84BFC5C493D161BD889F276 -:10C82000BBA4F2A92E8083BAC62AD742BAD9F18B0B -:10C83000E7B07E15200CFDB9CF2729348FF376772A -:10C8400000CF1940DF5C3633F6FBF7FBE23FA9DF90 -:10C8500057B0DF94FEFD2EB17559D09FB84CAA9CFD -:10C860002E88E857E4F5AC669F3713FD89FBC78532 -:10C87000321543BD868BAC7758187651F5A68B835D -:10C88000F47746936FBFDBF5B805E5D6E95F7D78B1 -:10C8900023EE8716BF6C6236A87766572C0B91BDC6 -:10C8A00017B0A0DDBA68AFC91BA07C68D22DB1E17A -:10C8B0007C5D4BFD2F7E2E96F6538B9EB706664011 -:10C8C000FB452F9C18CB401E9C59D3732813E1F7CE -:10C8D0002B81EC67A6768DBD05BE2F92D89DD1CE5B -:10C8E0003DFF9AC4ED8E532F39CA90DE84F603774C -:10C8F00050BFC19F9AAD617AEC489299F009F5C892 -:10C90000DFAD3E2D0446087C7E378F099F5F0DAF5B -:10C91000F734F7E72EDA6F0ED8717EED6D161FD45F -:10C920005BD6FE37A2EF2B9FDB1D877058B6DF6802 -:10C93000AF2E7EEEEBB55300CF8B4DAC6706E9F121 -:10C94000AF287FCE6BEB31911CF2C60920B79692CF -:10C95000C8827ABFFE64DA7B50FE99CBC4EC200A11 -:10C960003EEBFCD8F232E67DCE4AF4682FDB6FE472 -:10C97000C365ED272C382F59643D59C0E83FFC2290 -:10C980008C2F59FFFAB00FB6A09C5D166CFC9B096A -:10C99000E86DD9DED3EF22DD2D8BE0E7CFF097F401 -:10C9A000FEFAD29A1CA92FDF9884FE72D60E9B9FA6 -:10C9B000C903EB4B9DBF17EF3EB74D85F14F3DFFD0 -:10C9C000F93615505EF15F7FDF763FEE8F5EB5CBB7 -:10C9D000289796FDEA3FE25818FC872573F970E620 -:10C9E000E9A79EDC027038F38E95A076E6B79FB873 -:10C9F0001580FB993DFF3715CF9D56FCF6EA34A410 -:10CA0000B315FBAE4C1B6C5F84741BB086E33740E0 -:10CA1000F855F6C33869907D454B23F0726ACF799B -:10CA20000B9E0B7D29B01E94BF4B835F5BD03E3BBA -:10CA3000E4653D08A7D7F69E38741FE44F039EAC0B -:10CA400051F004EBCF1449AF843251BF2CDD7BCBC6 -:10CA50004D5714626AF6288827D643F2BE1F7EDF40 -:10CA600002FC16F6E137B2FC1CFBCA82F05FB60B83 -:10CA7000F03916F10AF81CDB1F9FA7F197C9FDF1E9 -:10CA8000599C6CB4FBCEB18AED5BB0706F12E17F44 -:10CA9000207C2ED9F7E341ED2C5D3E0C05E7050225 -:10CAA0009F576CB2F7E664E4DBE71DAA8BE33930ED -:10CAB00003CACEEC3EE76640279F9A7BEE4038F4EF -:10CAC000FCD62AEF80EF8B7EFB36F1DD997D7FB6B9 -:10CAD00020FEE1274E98047976E1E74D06F9A5DCC2 -:10CAE00006674B58CFB4770B31653DAA87F047F9FD -:10CAF00043C087848FC0CDD31594BF81145AF7D219 -:10CB000000E78FA58103B70A63FBC3BD3959D4F58C -:10CB1000D605BC0A4588CF0FA721FD0D844F7DFDAA -:10CB200032AEFF32287FC2C8BF91F59702BFE2FE46 -:10CB3000A81F7E0307FE88E99936AB24802D740672 -:10CB4000ED04677FBCF7C19FEBE76F6B1FD747F022 -:10CB5000BBDE5E87D350FC3ED4FABE2DFCEE4956B8 -:10CB60000C74A4C3F1D457D1F5411BCA8F8908C7EF -:10CB7000CAE919C3FBEB33132B553385BEF9AE0D50 -:10CB80009A48CE9F6A07BB5CE82F2F96E2396E94D5 -:10CB9000719ED3E4D4D2FD07C6A25C3B75F0258D0F -:10CBA0002E39DD2FDDF5A145D5F443205C3E0F7015 -:10CBB0002EFC9236EF65AF44EF6FD9AEBF45EDEF77 -:10CBC00033C9FB539CFF679D66A642179F054D51D5 -:10CBD000E3191E4FE6FAEFC2BA63271D8DC77D41E8 -:10CBE0005C8C82EBAE5DE37D1BCF45D537CD74FE0B -:10CBF000CF24CFA75628AF8D8D51D08F571B378F9D -:10CC000029617ABC2E024E92AB94CEEFA4E4D242BC -:10CC1000BEA70B18CE7FCD4010E1F306BD9B857AF1 -:10CC2000E983719F98719D7F8DB023FF2AB1B5690B -:10CC3000D0DF5F55C153A344DB1F18FBF7AD36317E -:10CC400025ACFFA5D69E0F703EEC5FED0CED32D308 -:10CC5000AB7601E5C9B26D66DA7F2D836D15C2ED45 -:10CC600093C7EC0115F29B7F5D7D07EAA5FFDC66AB -:10CC700065781EF1DABE95DDAB502E3D2A30F4A367 -:10CC8000FFE74BD55FA25E5EB8155607F264BEA300 -:10CC9000E7496C3FFFB94C560BED3F178293703359 -:10CCA000DB9D129A84FB90EEDDE91E95FA797129DD -:10CCB000F67BE63907F57BE65FDFA671CEFC6B2CD1 -:10CCC000E9357DFE606F2BE17A1CEC6DE5021F906B -:10CCD000BD1D96877116639ED717BED1641ECABF4D -:10CCE000C59802DD2FDE1FEF45FF4A583DEA6799E0 -:10CCF000B5E7E71EDA7FAB1922ED9D4219C88F8B8D -:10CD0000DB8DE37FA3C9BB65969E79BCBE3F83F3F1 -:10CD10006D27B573A668F4AA9547B6D7EBC7A40CE0 -:10CD20008BE887B75F6A6595D1F8204DEB7771FB8B -:10CD3000D7A38CFD71BAED3F0EFF7EAFC0E340D8A4 -:10CD40001E3BC5A35558422313816F5FB0B005C881 -:10CD5000BF1571A1910930DECB9ADCAC88813C7C97 -:10CD6000CFD0E681F531CF6C5D6710AF4B5EB4D3A9 -:10CD700079CA9217DEFE12F1790A610C183B95D23E -:10CD8000F9E5FD4007A71E333115ECB525D690FB1C -:10CD900051D4537BAC6C07F2F7ABAF93DE3AFDBCDA -:10CDA000551CEC9C7A4910A8C1D67F1D6A09CBAFEF -:10CDB00074621C8E576CC37DC36153A006C6AE92CD -:10CDC000BC6B9EC3F51D36D33EE3EC5C968FFBCA6D -:10CDD000B32CC3A312FE95B725285FF97BB3102DA2 -:10CDE0003EC9DC0B427D02F041EFF54C8154EA1D57 -:10CDF0004EE94A4BE52894BB26191657407E02B2ED -:10CE0000DBCDC91E361FD29589CC87F063CEEB2EC1 -:10CE1000F0D79F00A5CB1F51D2B0DD8F52CC34EF9D -:10CE200045A9DEEB53483F3A65B22F343A55F7F146 -:10CE3000799E17623C35189FD37BDF9D08DFE51F85 -:10CE40000A4A783C43643C6895A4BCAD14D27A4944 -:10CE50001EE5C9310CE17A563B773F3B57894F08B5 -:10CE600093CBCDD532C98FC66A17A5EBAAF39942E9 -:10CE7000FE350FE54DDAFAAD052AC507214FE38FE0 -:10CE8000D559EA453B0FE784714126A78FE8C8EAE8 -:10CE9000AA24DF94CDC9681F6B72AA6C3EA46627D2 -:10CEA000878FC9594AF0B16879A97506C113DAD3D9 -:10CEB000F7AB537D77233C6C59971AE4922579BCE4 -:10CEC00021DF0F5E3AFE77FF4FC18D119C1AAB6DCB -:10CED00094AEAB2E2278D5577B29FFBF00B7D694EE -:10CEE0008908B7294CB185C3ADC4901F106E8F005F -:10CEF000DF2487F30DC011F986C5787646597F6423 -:10CF00008AF11028A81FAC6EA554FF9E3880DE3E23 -:10CF10009F2268F1B0BE1A338E23737F0B4B565994 -:10CF2000D6A43EFF2673A94CC13CF22AE2E5680C68 -:10CF3000C16EF9FB76F21B9B64A93B5CAE2DBF4131 -:10CF40004943F965AA7A9C9D088B4733CD28B52BB8 -:10CF500004570F9D53D66A7AB3FE02FE8C7CD05CD8 -:10CF6000AD50BA5EE3878D1A3F6C423C631C8987E3 -:10CF70009F6BB64C67A417FF0FE4F93E3EC4C2E3B3 -:10CF800046123CC19019F04D3252A13444F1BF47D2 -:10CF9000AD8111B9143FE545FA4838BA8AFCC78C0F -:10CFA000055DE84F4BD0E0C65E1996302B9696672C -:10CFB000E67A879978EA37A33D1E09D75ACF411BF5 -:10CFC000EEAF079A4FF1070B051CEFFC2C42134BF9 -:10CFD000BE3D78B41CCF4F5B1CA457533D9539E838 -:10CFE000DF63C7AC449F4E8F4F981F86BFD401ECC0 -:10CFF000BA55A9D77E8C7CDB8DB20CE8F0C1D6E1A6 -:10D00000768473B339E84279D79CC0F587520650CD -:10D01000B8ACAFDD9F3439185768E4775DBECA53AA -:10D02000C71BE85797AB895719E95C97AB2FA570D9 -:10D030007B6D516AE9799C4F52EF56E2C348BACFF3 -:10D0400093A794F992510F304F13DA6B6833A21DF6 -:10D05000F7A110E0F4CEFD5367BB7277A09D03BB30 -:10D0600002922B2AF203E1A9E7B56F9231DE95CB4C -:10D070008735B699365C6F03D0111B85FE6C850031 -:10D08000BC01E887D179A047E38F224A75FA74A7DB -:10D09000E61AE2044D798744C4573DD811144F0C69 -:10D0A000FB3B278C271D986C437B4F327B0EA39C48 -:10D0B000EA891583A837EB9D336D5EF4DF241412E3 -:10D0C000DEBF8C2DCF192C6E09EC16F2DBCA4E0F89 -:10D0D0003B8EE330467E5B933C9EE13E71B7B333BB -:10D0E00006F72DB1A9A2615E8B527DC353C3F263D3 -:10D0F00070740D5FD8ED6EAD9FC8F17E90AAF92DCA -:10D10000B354E60D3BB7A8D2E95B51D95561FCBDDC -:10D1100066C434867117917C3DA0DCDAF9FDE456D3 -:10D120006D4E80F0658E9417C920C79D94AAA28C7D -:10D13000F3569AFF2581E8EA4A840373EEB86087C4 -:10D14000FC685814FA3A7A691AC56B5ED033B06B32 -:10D150002E203DB3B988DB239A9EE1FAE96C8B83DC -:10D16000F4D3D9B995144775B6254D41BA3BB0E112 -:10D17000F2B1088F79BD8D4C81F9CDEF9D4CE982DC -:10D18000D65F525ADEDA0644CE58CDFAF91B664114 -:10D19000BB138F98282EA83B30E14C15E4BB5BAC49 -:10D1A0000CE38EBBB7DE93837EF16E1807EDABEE1A -:10D1B000AD2388BEBA016E946F30D6C7786113E094 -:10D1C000A59C313D68D38BF5E7BD6E6A8B662795CC -:10D1D0006FB47AA39DEF5C286F8D6EB7D5E2AFE98F -:10D1E000F85FE5288457F107AB7270BD3AFFAF4C8A -:10D1F000047984F0FAC0CAA2F9E3AF4EBDBA227531 -:10D2000022A6DE159832676254FF5A1FFDF3714F54 -:10D210008860DF125E7C71371BFCACDC8F7942B317 -:10D220007F996D80F238ADBD1CBD7C49CBE7871E70 -:10D2300060787FA1B214895EDF4F9B18ECA705DCF4 -:10D24000FFDE4CF1D0FA7CC04E253A66800F942F59 -:10D2500073357F0FC0FD260B7C3FF1BA4940FAE8D9 -:10D26000A3275F1CDA2D42F30D6B7643F9DF0FF332 -:10D27000FDD9C2DE4D24EF84E6319B27C3F77B5EE8 -:10D2800037939CAF69BA7CE3ED80DF2FDE30517EAF -:10D2900041AF9DEA9D7CC0B3F976A8D7F30733D997 -:10D2A000E15F1CBE9AE21E4F9A8D7E82A9699C8F17 -:10D2B0005FD2F8795E6F33D91F7AF9BC863916854B -:10D2C000E874037D9F878736785F8195FD7B711EAB -:10D2D0009EE730BAAFF0D2C3B75EBF86F4DA78B259 -:10D2E000F7E7AFB77AA2C54FBF94AA18E4CFFCAE58 -:10D2F00016EA97815D949CAAF5172647E6F7261152 -:10D300001F30596518673C4F932717E6B7D56C90C7 -:10D310002727EDD1FD20AFA7F27DD4BCDECB89BF9E -:10D32000FAAFEF87F47D9E3E6E17E7C7BEF56C9EA1 -:10D330001C6D3D7DEB984AF54F26441FBF471BBF30 -:10D34000BB7A01F3825C2AB7423D278E7FCFDAA2F7 -:10D35000425C4742A210B6AEF9AD8B99376C5DF3D3 -:10D36000B7CEB69487F5DB8787E5FF5E2CF5E1A1A4 -:10D37000277509E161556AE931E49BF2E62BC62283 -:10D380003DCE6F6D24389F307BDC285F3F69BD2721 -:10D39000CE17759E8AC18F30BF55C30FD8BB85612C -:10D3A000F8D1F112D9BEFBFDF95F3E80F2E7116EB4 -:10D3B000DC0C04AF7E78CB8D0EB7188D3EBB41DF01 -:10D3C000FA086ECA0B4791AED73B3C48D703C36FF0 -:10D3D00034F30D06BF01EC57B0774C69785F017DDF -:10D3E000B4780ED9CAE96028B8F58DABD14171F493 -:10D3F000F514A5E97450C55460D8E396A1E8E07E21 -:10D40000A6DA0659C7053A78D84007459BD7131DB9 -:10D410007C8AF6CAA8FEF83F6E51E3A6E0B94F93A6 -:10D4200089CE958EC7A8A9B7F1FC3894C7C7E3FC8D -:10D4300037E2398D9E5FB87344DCECB0713F690010 -:10D440003844815F51DA00F493A7B28249FF3CFA75 -:10D4500039618E7EBFEFEAD4E2A969A83FFCD1FD15 -:10D46000B57AAACB6B53BCF3C23E13F5E771E7B0B4 -:10D470002F0350DA9CEA9B8E745197F0F33B511EB8 -:10D480001C3F2E90BEAD797FE528D46B917602ECDF -:10D490003F1BF0DC73A529D64F76A854B99DCE4129 -:10D4A0005589ED2CC47D4AE5968F46A0DFB08A529F -:10D4B000A6D9A12B4D977A9AC82F5BF9149E930297 -:10D4C00091C8585F6295746E0A82B014F39B1DFC7C -:10D4D000DCB54AB2C9D6B0B884E51ABFD45797FEB6 -:10D4E000F223F443DB5426A7627B2E3725C6EDAF2B -:10D4F0007FE03CC3F4BDC5EC933DB80F155829F24D -:10D500008559F2D1FD27B32B799C1A8687CA347EC0 -:10D51000DE6EEFE868C885F6F6BBFE20A31EB4C237 -:10D5200038E867B3654967C3FDD5E6E420DD6F627F -:10D530007961DFC1AE721640DEE00780F90E621736 -:10D54000BE2C785C5F223DD67078142188207D67E0 -:10D55000EEF03694CB45529D09E38E66DD3582F2BE -:10D560009BE77C33B22B0A3DCC7A655D27DA33B377 -:10D570005E499F83E707B39C233FC614B60BB618DA -:10D5800068FF9AC0824D905E657B9CE2195FD3FC78 -:10D59000631D980FD38B1D1ABD819D337D0FA4B3DE -:10D5A0006C7EF3DD057DFEB4C871376B7CDF610EE8 -:10D5B000A65C8A7400E3E03A7EF64AE0C7A0FAD996 -:10D5C000EDC1C00D63003F77B01E33C2D1C7643ACE -:10D5D000F7D0FDBAE5CCA3E519ED4FDFAB30EF4056 -:10D5E0003A89ECEFF610EFEF671DD01FA4771CEE21 -:10D5F000F93754CBBEA03CCDC1C2FADBEF39E460B1 -:10D60000FDFB8B84B347B299D430B8028AC470B89A -:10D61000F7836F7CD9756CECC07CD6076F3E8F4862 -:10D620007C7C8145C0A76D69DE5F23BFA969DEBD33 -:10D63000C8BF15B61EB70474732CD9B71FBF2F35DA -:10D64000F97252011EA7B37DA352102E9DD1CF5F58 -:10D6500023F93BAFECF463C83777D4480CF1BC76C0 -:10D66000DF278F215F9E36031FC17EE0B5559FC423 -:10D6700022DD2C01060C97271F548D20FBE9ECDEE0 -:10D680005183DE1FF940F397746A7CA2AFF34E64B6 -:10D690004018EFCEBD0EDACFDC5965BAB0CF427A72 -:10D6A000BFB38AC78730A973ECAD06BBB36EC07E2B -:10D6B000701F11D94F77B56F3BF1BDE49B8476F7AE -:10D6C00089EA05DB51BE44CE73A4CB77228DF4DB0F -:10D6D0006C43BCEDDC9685DBC3F950AF5F3B807CCF -:10D6E000F58CD2CE016D7C3CA6FCA0D83989EE6BBE -:10D6F000D28F3D64FB5008A387A1C6637957792F69 -:10D70000C805DC7FF944E64CEDDF5F643DBD7F5723 -:10D71000D595ECC4045C9FF7FFA5A50C3D7F8B8BD2 -:10D72000CFDFAEB5D3BFDB7D7E8676A1FDAB78B211 -:10D73000133CA3B8FFE11F9A5DC09CB05E6430FF4C -:10D7400066EFFFC67A61608A17B66FB5468D2BCA41 -:10D7500074491C2FC143C5B628F3EBD75F48621745 -:10D7600053CF338AAF1FDD64E4EF1A1943FB9AF2FB -:10D77000AA5ADA673782FC407D10399FE34D8F2A21 -:10D78000A807EC16BF827ED1C691A9B96BA01D482F -:10D7900035F2FBD863FC8A14FE5DF307D9D7F81580 -:10D7A000DCDF368EC8A0EF7A7F8D0297B33A5F3404 -:10D7B000C2BEEF79F28B795C3331AEF4ADC0F45870 -:10D7C00068B7632D0B99DC8C1D74678CC67DAEBF6A -:10D7D000DE42E77B8DF962FA5CC8C765DBC83FD6DD -:10D7E00096109A85F76B554122FDEA4F50AE8D4554 -:10D7F000FFEE9AB44E947F07EFB6D07A9B27F3FBE7 -:10D800006AD6291FF9AFC4FE57300FEAD51DBDBF38 -:10D810006EC57702D4A3B09F45BF21760AF268C7D0 -:10D82000F4B376DCCFB930AE0EF0B1D51CA4796D6F -:10D83000A9B152BF5BDA2C65D1F0F779BA44EB0A93 -:10D84000085D141F9CC4827684EB83D3676ECE83FD -:10D8500076B9794CC6FD7C73C1596DBFE935F1F3DA -:10D8600028DD8FC8ECDA79964D3BA7B285C7173E05 -:10D87000EADF4BFE43C78C204FA78BE47F8E9CC70B -:10D880000A17A77BC7D4CEE9A8271C852213D0BFCF -:10D8900099C7045C973C7D075DD2C8CD6703B43758 -:10D8A000517BD90BED0B797BF409C917D9BEC2C5E1 -:10D8B000E30CD7A31F0ACA03668F702DCC23708395 -:10D8C0002CA84A5FBD7A17D7AFDBA1FF10C9D100E2 -:10D8D000ADCB9D1F0C21BDB92B44C2D3FAA2E3747A -:10D8E0002EF060A1EE47F5D03CB6D61C3980F6D7B5 -:10D8F000D67B19D9495B518642BBAD37B0003F4F4B -:10D90000621928DFB62CB45C4FE7F905007F81D29D -:10D91000A8F39E9D6E237CBB573F18C2FBFB311EB4 -:10D9200020D45C4AA3D66F4CE770DA620EA4A37FC2 -:10D930006420BA287371BFAABB4AB3AB98DF85785D -:10D94000DDA0C187DD3A9EFB1724AF121EC7D5A705 -:10D950004FB81F03D64771AD497516D247E28CD038 -:10D960002C5C5762BE855D938BFCC5E1A68E117958 -:10D97000DC190BB4227FB65D924AF1A4EBC4800B94 -:10D98000FDCD6A8985CE930F1689B3F05D848D75C0 -:10D9900016F243409EF8C5EF1DD686FCE6985A5213 -:10D9A000B6A010DFB9B0C808DFDA02D98E745CEB1C -:10D9B000156501F21B4AF5FB118CDE37186732D969 -:10D9C000F3A17C7BBA883E5AB65D1088DFEBBD259B -:10D9D000FEE1F0BD5E4E16C2FD002FBBB8DD7B77C9 -:10D9E0004EE9CB2E4803DE07FDC3158E4B6912E3CB -:10D9F000572CE02796851660CC4D5BFD934771BD93 -:10DA0000EBC7D9E8FE6CF60A7F19CE37F6128B8287 -:10DA100078DDD19B349AD6576751909F3709816B37 -:10DA200091EFB7DE7D4845BFBAFD6327C60E336769 -:10DA3000D7DFAA317ECC59688938C76222CA717D86 -:10DA40005CE75B21A2A72EC1F79758F2FF1434E5DB -:10DA500027533CF32484E78629EFE6CF8B4217D087 -:10DA6000DE993A1EED653134692CCA29AEC7982477 -:10DA7000A787E3775376C63BE867DA560CF3C7F11E -:10DA8000AABA6FA779798FDC8F7695F3D8C9AFA33F -:10DA9000CFF34DD223B1C71C21712CA64B66907DCC -:10DAA000165E0FE4FEC61CEFC72EA09BDD355CEEB4 -:10DAB000B7DCC5E83D0AFCC90F836F4B014869FE1E -:10DAC000048D42F50A64F2A3AF13956008E139D6DC -:10DAD00046F494C67C24D722D7EB38D67837C61DB7 -:10DAE000393CC679F66AFC8D3F522A9D57A025CA5B -:10DAF0002CE973ED28FFF68C57D271BFFD6042749C -:10DB00003DFF5E3A6FBF5B886E9F9F4BB7737D0989 -:10DB1000B232348950C528AE0FF2622A9DDB909351 -:10DB2000DB2A72B9C0AE63A4F7E2C675D93D61E3E2 -:10DB3000ED49EF9B27C61FC46BED98DC13AA81F556 -:10DB4000B701D5E27DEEB86C0E47A7DA0747AC2FD8 -:10DB50006BEB023EA81955884094A93E2BB5D0B96D -:10DB6000084843F51BB10F0EB15AFD2D459280EFC9 -:10DB7000900C036008503F61BAC5708E22D71D51CA -:10DB8000B1FC7E1353128BFAC67F6C1C0BAC81F177 -:10DB9000E3BD4678C7AE786125DAE591748033B885 -:10DBA000D02F868ACF35B64BBDBD1F1F103C699E56 -:10DBB000009A96B7D80E0B00A5A55DD2E36349FE87 -:10DBC0004E3475AAE80FC580A47D30FF4B9F7ECBF5 -:10DBD000BB0BF22D3ECE67B1F92FAC44BA4CC8E076 -:10DBE000787A077DCB00E74799FC778CDB51AB4413 -:10DBF00005F1B12D348CF47823934A114F8D95475C -:10DC00004494EBCD7B99471090FEFFCB1A3EBFDBCF -:10DC1000D2F9390D9314927F929BDF1B6D2E101D4C -:10DC2000285F0FDEFD02E9BDC70E880CF9BFE4775F -:10DC3000C71EC1F7815ADEB152BEE5F54A921B3FBD -:10DC400087766A14FFF9507A39B27EDE921D029E01 -:10DC50004FE42C08BE3E12E5B35FF25C83F858D067 -:10DC600049EF872885FC9CCD392344EF8728A8D528 -:10DC7000C02655FC5ADAC2CBD9AD89B48F1A63EDF0 -:10DC80006AB80EE6F7E8D312437D69B206D3E743DC -:10DC9000BFA6179DA809FAED8F1E9D114A47391E90 -:10DCA000534961D0FDE677229DCB59F70CE5F72368 -:10DCB000A1DF84A91C96767FDA0194976833E3BDCF -:10DCC0000A87CAF5DC0629E0C538EF0D2B7C161C47 -:10DCD0009F69FB97C625E54F229C4F6A7A8F552E88 -:10DCE000A0774CDC1ABF38AA5871B47D56AB2B868E -:10DCF000C7B73C201E40FE707B19E90FB92A181ADD -:10DD0000A5E9659CB8BCFAF946D42FCE0A91D6B1E4 -:10DD100041EAACC1772536AC60728DD2BFBFEFDA75 -:10DD2000BE2ADD4AF36F451CA7F4AD835C7220DF89 -:10DD3000DC0BA2AFE3611C7762DF3A62F475E47733 -:10DD4000515E9FC7766FF0A2E6B1595BC7A6749982 -:10DD5000524701681A677F79BFC6F101BD2B1300D6 -:10DD60005BDD44F7D182D7615E794E64FCBE96914B -:10DD7000BFFBE535BA8AFCAEB0B0717291EE389E49 -:10DD800081EE34FB09F8CE86224054BE213F869FA7 -:10DD9000D61F498FFF74B9183E6FE83FB68109144A -:10DDA0001757C19492F4FE72916972D1C6D410CA09 -:10DDB000BFFF69B9087290E4620BAC3409762AB1EE -:10DDC0001D4D77A31ED7E5E144C4C914645FDB0D84 -:10DDD000254EDA1751FEB247FED082F191EB44EDA9 -:10DDE000BC4B830BBAA1102E5FBB14833E7D187F02 -:10DDF0008175ECE948BCBE00C6DB5C366C1CEE2FBE -:10DE0000ECFE17C93E7017F0F81577153F3F77E421 -:10DE1000CD7B32FC5E5C653AB7D32B75FAABF2BBB7 -:10DE2000709C0DD82FCAE73C0BE9CB475990EB43C8 -:10DE3000CD3EDDE6D2FC241A5D45F249A47C9AF081 -:10DE400087E41294EFE98255C6FD1CEAE783A946F0 -:10DE50007D8DF4A2EBEBD6CE3509E80FCBD5FCFDDA -:10DE6000B936639CC365195C9E99D3F93CD68995F4 -:10DE7000B4DF544B44DAC7E9F477418F47C031121D -:10DE80007E48A86B27517C0CE5E38A7B18F2EF36BD -:10DE900020597CE32D2E5DD1E2A6658273DBCFC4D1 -:10DEA000F1282FF77494DBD1BF2EB86DD7E2FE7046 -:10DEB000A3C04228373716BF4971254D55D0332CA2 -:10DEC000CA992FCEB68CED8F67E063DAAF3A546B08 -:10DED00027FAB582A11D14B7D01438348B713B9644 -:10DEE000615C4A53FE9A8C4528DFF34B0B11BF6DE2 -:10DEF000F5168A9B91F359543FC2E7B88F213AF93E -:10DF0000767ACCA1EF2F2BA2EF2B4B33F8FE3628DD -:10DF100081A882F964E58B1EE4FFAC3A4BD4795CAE -:10DF2000A9E1293383DF0F6BAB3F944EEF668995F0 -:10DF3000013618BE60FA6B52C3F03179007CB874B8 -:10DF40007C483A3E1266131F76758A5CDE925EDB71 -:10DF5000C0E4DB503FAA9516B2631BCD7C5FBEA325 -:10DF600040E30BD9D686C4F66DE93A6E8948F7705E -:10DF7000B28B44DA273A2A9EA7B8A64759CFEB2896 -:10DF8000EFD4027E7F3EB2FD1D19DC7F159414C1D3 -:10DF900043FB698E47C02BCD67EB88D4B6703E6DCE -:10DFA000D5ECE8561787E3D6FA87894F2F769EBAC5 -:10DFB000DCAED5ECE8855E9F05D5812A944E4B47B3 -:10DFC000FDF9047F878A999C64977F8A4DC2FCB2D1 -:10DFD000ABB27C951961E743B2B752C47A57E3BB41 -:10DFE00042D0FE9320BF0FFA49F0D7C5F40E978FA9 -:10DFF00011332F649D023139C8D09D907749412A51 -:10E00000772D80B924D0ED48CADB6CA0176142A7F8 -:10E01000ABF9FD8B6E7C5F92DE9FE4EF4B7EAEBD75 -:10E020002739A6755DC9A3389E22F950667C86EF14 -:10E030004BE2FDE7A277292EFA14C8DAA6048C87F2 -:10E04000E1F7B7E5FB982C4EC6FCFA128C7BBEE7D5 -:10E0500055AB764FB2730DDE7B795C8475439B665E -:10E0600009F4FD702C6A102AC3E878F7159D7178C1 -:10E07000CE773A78CBA0FE63BC3F48F3CDE078DAA8 -:10E08000E4584AF7CBE639436E6C7F60CF534F6E4E -:10E0900081F13EDF67A3F74C363B96BAB1FCF347FC -:10E0A000DE76A3BE38BDEF6D4BB4F3C92552701AAE -:10E0B000DE23AB50E3D91A987F7170B685E24F76B4 -:10E0C0001DA0FB694B649F05FBAF68DD43F9AB7690 -:10E0D000FDD98DE5EF67703D713ADDE746BF445EDF -:10E0E000AB352482FED93DCCBF28EA397B86A8CD4A -:10E0F000FB55EA7FB3E3D5438897D38F58C9EF76B2 -:10E10000E091DF51BFA7F6BD48F3FD7CF7DB77A0B8 -:10E110003D5DC19807E5F969BBE6D7B375C685EFE4 -:10E120006F5FD5E0A1E74FC76AFBE0AC21EA69E782 -:10E1300031CC09F0A7FB039D7178BFF073B3CF8298 -:10E14000F0588CF080B418E080727F7150A0792E66 -:10E150006E6DA3FB568BF772FFE0628017C1A5F5C9 -:10E1600000CDFF5806971BA7F6FDC54DEF52ECB545 -:10E17000D2FE595FF762A7CF8DF0D1D70B70E0EBDD -:10E18000DE7D71789AA7E3A9F5CF34AF8ABD7C5EB6 -:10E1900015BBF83CE6ED053C39114FB309FFA7F676 -:10E1A0003105EFC174EF79FB33B4674EEFB32968E3 -:10E1B00057E8F3CA02711B371EF988EB63B6572084 -:10E1C0007DCCA44E3ACF5922CB32BE4F70A13C60D9 -:10E1D000097079DA599209E5CF3C24D2FB964C0EAE -:10E1E0005E8AFED53319FAF946A71BFD62BBAFF074 -:10E1F000137D9E8CD5E02D75BA317E6673A6EF4CEB -:10E2000038BF9FFEF0C54B71DD2B4D95BFCBC6715E -:10E210009EE2F1A1E78755FEF5019AF770C3796395 -:10E22000640A708BC3F3EF7C91F9E85EF2DED7628B -:10E23000C2CFA14D99DCEFB6D9F101DD473C8DEF9E -:10E240003CD27C8214A735D25BEEC673BE93CCE978 -:10E25000C373D9CF9F788DE26DBAD375FF5327D59D -:10E260003BB5F7B5444CCBB5787816B885E418C003 -:10E27000B1C1363E9A7CD4EE1705F8BDB133020821 -:10E280004CD4138FE970AEB4CC349CEB70399AB592 -:10E2900035B783FC2D81E8F7CD22E56FDE4393E9A6 -:10E2A0005CF91C8B7EAECCB438B995A6188ABFD960 -:10E2B000ECF805DDBFAD52AD32DE5F39AEC9C58FBA -:10E2C000B4F716CEC7C4A922D0CD4B99BEE199139D -:10E2D000FBDFC32D6F5EE246F896E3B9076D6A7601 -:10E2E000DC807189140F3A85B46D88E067D6CB5B0A -:10E2F000797902CF4FC9DCB31EDFC344F8723BF516 -:10E30000495E9ECBCB7FA295CFCF281D9F49FA8532 -:10E31000D13B4560912574DBB80A8F068F3EB84823 -:10E32000AC5BB7ABA1F2C24CC6E336324AA7E27A85 -:10E33000A058E07CFFFDFA03BCABB6C4FF867E6C40 -:10E34000FF5DFD04492F893E7CE30ABE79B8FE7B60 -:10E35000BC84C94D09DFBFFFEFDA7EA5C92B9E44FF -:10E360003A8C1789EE75BEEE7E64D438DCFF5B1AFA -:10E37000EE0EA1DAEC8E2DB1A4C3F7730A3F3FB9BC -:10E38000EBA14D86F755F534F21D5BFD1CCF32DC59 -:10E39000783EDB92C9E5514B669FFF0DCFE546E223 -:10E3A0002F0ACFB7A452280CB7D359A588F187F903 -:10E3B0001D367AC7F712068202E63F9A8544D4DFFB -:10E3C000635817E57F802080FC38A698303F81F5A0 -:10E3D000B8A5E178FE1C5A8B76DAB1645F13D2D906 -:10E3E000978F747E2040F9CF337CBFE982EFEB3307 -:10E3F000F93EC8096621D2B38C29D0A1E898E18AF8 -:10E4000026F72FC053964E859FB7DD2C791F223AF1 -:10E41000665972B7A30FCEBA3C58A4BDBBA4B7FFD0 -:10E42000ECE9A786D17B437DEF850F7A1F785ED517 -:10E43000C2879E983048B9266777D7046E0BD7F706 -:10E44000ED1A9C9FC9D4F5805FD70764C7FDEA66C3 -:10E450006E3FEDBEC2BBE67194B7AD26DA4F9F6C3E -:10E46000FD0BBDFB78AE94915D37D0B82723F07ECD -:10E4700072E75319FCBC2360D0EF0B9F7CE9D2F00C -:10E48000784B00B3923C89BFC341783FE451AD263D -:10E49000A4D252F2C75858258F53C1F90EC777B886 -:10E4A00082943A5927A571AC875299C9E49F4E646A -:10E4B0001E4A935929A5A9AC52E0F69D9FD20C168D -:10E4C000A4340BED53F4F7B01E4A15BCF11916BF76 -:10E4D000310C4F4C87E37BBCA5FC7B447C9084785B -:10E4E0009C10459E47C40549ED5524CF312E684404 -:10E4F00072FFF71474F9BD39B3E43D94A72F657A20 -:10E500008F617AF8D9DFF3FB15EB05B2AF4FD8670F -:10E51000581440DD33895E7A07441559E94ED0EF2F -:10E520007375FF3FFEE871C208CC16F3A9F0F81D21 -:10E530006673E6E379F11CADEA1CED1C648EE60718 -:10E54000C1F7CDF83D3D0FDDB79FA39D3FCC89F0CE -:10E55000BF30BFD5E04751F11758C71CBF40E70691 -:10E56000736266BCDAC506A693B0FEE8DE5F798406 -:10E570001F6A487F56447E6E647B9BC06CA9F89DE1 -:10E58000D3D3333F54C8AED3FD5940700AB56BB0F6 -:10E590007E487E21FFD5DE70382565F17DABDD7FBD -:10E5A0004D5CB47797F4742ED867E6C4FEED6147EE -:10E5B00098807CAFCB619DCE7371638B7C946F0927 -:10E5C0000C1697AABF77DDF4809FE1BCEDA155F44E -:10E5D0004EF5BDD92AF96A6D0501BA1F10931F7057 -:10E5E000A951E6D784EF3A037F35C51ACF4D966718 -:10E5F00071FE5F9EC5CFB50F5D925A82E7D9EB14CD -:10E6000091EE0DAF53F8DF2D589735D43BE536C367 -:10E610003DF9B549DBE81D20FB57DB19DA93762974 -:10E62000FABD94DBB4F13769F537276D233F49C351 -:10E63000087EBE1F59FFC08887E9DDC7C65CD8EFDA -:10E6400062FA804AFDD78F78B80CDBDB428D86FBFF -:10E65000BCB3B3F8BEDAB697D3A329CF121886F4A9 -:10E6600020F929BE40AFD738C079D28D595C2E36FB -:10E670009903744FA649B3879667C56D407B675D64 -:10E68000D68EA3C8AFE7F2189D37DA434FD339824D -:10E690002DDFC2EC82F6770230BEA32048F8416736 -:10E6A00053C840B7317DEF6C98FAF75FF78DDF857F -:10E6B000EB6BCCF5D3F843ADF74A8D4E1B35FDDA45 -:10E6C00068379EA35568F0BE5E5B97ED1546F26411 -:10E6D00010B890BD77E3D61137A27FCAB67F48380D -:10E6E0001AEAE7B2B2F868FC1229FF9D0562C43B42 -:10E6F0004A02CDEBDC5E417B6F91BF63D1670704BB -:10E700002DD8EFBF6D2D3F782DCC6791CFE9C5F89F -:10E71000C9A7B6EEA07BFA8B5F34537CC2C8AED9D2 -:10E720005C0EB6F27712F5F78D2E69B51ADE9B5A9C -:10E73000C2C2DE5184F1161F3B798CD13D63E37771 -:10E74000FDDD8066FC10254E2DF2DD8187B222DFD3 -:10E7500023D3DE1D2888EEA7897C7760575024BD1F -:10E76000B11CE358691FB0AD04F73D55C704F21B57 -:10E77000F4E743E5B13C73585EF0103DAAB131DED9 -:10E780009D51F8E9BD6C4E2FBBF1508DECFEEA0DAA -:10E79000A12C4CEB189E37D5AE90643CD7AE0DC47F -:10E7A000D0FD925A590C60DC48766C890DFD8F2C97 -:10E7B0004194F11EDA34D354BAF764B9579A40EF52 -:10E7C000B3EE58D489F7EA6A5D12433ECE4EE0714B -:10E7D000042C5DA4F769EAE43713E6E03ECEC9EF06 -:10E7E000E9E5C82CA00868D779199E2FC366A53221 -:10E7F00004A657B6E00DE17B576CB255DEC9DF9930 -:10E80000B971DC24F203D3CF81B669A1DFE2385EAF -:10E810005B29E2FFAA7B93C91E0CB84C0CE3003FB6 -:10E82000CDE2E78296D892D0FB38BF590EF2ED06C2 -:10E83000543111F1F07ADBDA99D7C0777340A278BE -:10E8400087FCAF6B6FBB06DAF7B459E8BE850E27BD -:10E85000A54E32BCDFE05E6DCC5B22DEAB9058583B -:10E8600039E4DFC179905D55C642E171BCC95E7E75 -:10E87000E82E3B894EBA813FE9FC43CBBF8779A0A4 -:10E88000D776B39FF0DEFEBE40FED5836DF37248AF -:10E890005E3A966EC7BF635275949F630E249F9F26 -:10E8A000CE52F47712ECDA3B1576F47B45D2535D09 -:10E8B00035F3609CA12DD011331AF17BD8ECC1B097 -:10E8C000E67A4D3E4A4E2EC775BA894CEB23E8AF27 -:10E8D000DEECC9F743FDFAAF4DDABEF1F48D485FC7 -:10E8E00092ACD0BEDA9CC53C680E9B933B336498D7 -:10E8F000C7E8172D1EFC7B07D39E2B8847393FFAAC -:10E90000B55924DF104E882FA9CAE2413BD95A9548 -:10E91000EC9126603D27D1E559A785EC21A9CAE1F4 -:10E9200027FBAB6D924B09937B6BAB658F64C6BFC6 -:10E930008F63A374ED00F23E27412C45BFAB45B376 -:10E9400097D3B475A5653B284DCDE6F273BBA4CE35 -:10E95000A4F77B816E30EEE6C06A4EDFCBD36DA4A8 -:10E960003797BF3E3C6D30FFE093D52E4F1E0076AB -:10E97000DBEA72F2DB16AFFAA811E96E79AC4D460C -:10E980003A34C58DDC3C15E9FEF766BAE7591B3B06 -:10E99000499913D69F29AEC885F030896A06D2738B -:10E9A000C163C11BA5C94827EA16BCCF5F98DD7AB1 -:10E9B000A304F2A53D56CDC0F3B2A9D95B793E457B -:10E9C000DD22209F6407783E5BCD10213F23FB09A9 -:10E9D0009E1FA16EC1FCADD9ED3C3F86EBA3DBB31E -:10E9E00077DD88FAA8D6EC2943FFF4B330FF821113 -:10E9F000F87783787A870617BDFC79FC6EC6BF333B -:10EA0000C4D3C8F217B476FB0728FF8D56FECA00A0 -:10EA1000FDBFAAB50B0DD0FEA0D6AE6380F687B4BD -:10EA200076870728FFBD56FEC600FDFF516BD7391C -:10EA300040FB37B5766F0DD0FE88D6EEE800E5EFE7 -:10EA40006AE5C722FAFF40ABDFA57D77C736BC8BEE -:10EA5000F69A1BE415CA93FCD806F2776DAB2A240C -:10EA6000FAAF9DC8F5BF4EEF6EED5EC0916C7E6E45 -:10EA700073249BDB01551A9D17AFCADB3815E9F0EB -:10EA80000FFC9E22E88FA3780F575D25927F6FF9C8 -:10EA9000EBFC5D99E5AB243ADFB8A0F7B4F6FAFCDD -:10EAA00003DA3CEBB4B4329BBF9791ABBA3C33C2B0 -:10EAB000F4A35936E66DC04F18FF5F97CCF54CFEB6 -:10EAC000AA92063C37A9053D83EBAB775A42E8FF93 -:10EAD000AA97252AAF4B2EF1E379BF2A4BA487EAE8 -:10EAE000931343F84E735D5DA1E1BDCF3A59A2F790 -:10EAF00063A484AB6C739C283766C8283FEB989C52 -:10EB0000584CE76AB04F437D525522A3DCC94D48AB -:10EB10004E44B93C3787AFAB23B6DB8EF728A4074A -:10EB2000447A2B60A42C11BFE7D5890105E6D121D9 -:10EB30002F27FFEBCE16ED4C91F1F3445DCEB7FFDE -:10EB4000621AE9B15AD0630AE931163F2EB5EFFED9 -:10EB5000A6746CB405F5969C61626690CBBFCB4EF3 -:10EB6000A471773EC4F5D608D05BF8CEDAF642C67B -:10EB7000DF7973D9C8AF5B2E315752981FF377D91D -:10EB8000DC8E67A6191EDC678FC0F710C3E03BDC84 -:10EB90006FD45BB943E8AD9C2A909761F5AD2ED94F -:10EBA000900F666BEF2A799807ED9B69CF6D257DF5 -:10EBB0007216F50943FDF2C798D1A85F408F5859E6 -:10EBC0007F39A8CB63DD6ED1E574ADA6376A23F437 -:10EBD000C6D072F7EFAF8F22FA140DEFD00C247F5E -:10EBE000AB304E00E8DFEC1348AF30C947F7FB8786 -:10EBF000829BD95C2ACBCEA1E1674EF92201E5B414 -:10EC0000D927793E8A724F6A28F8EAF52CB6CCC724 -:10EC100050AF7D716C653EFABDD69A3B67EF42BA44 -:10EC200015E2E97E87A2F91DB655EF672746603CDD -:10EC3000FC7B5BEB26E0FD71AF4CFE92F41205DB32 -:10EC4000D9619F9E44761CDF6F32D9E75F84F6FC62 -:10EC50008B1605CF050E3FABBDDF90ED2478DEB3FC -:10EC60006705B5330B952E7EDECF08DEEB3212F949 -:10EC7000DF0969B76976E3998DDE3CE857EC1250FD -:10EC8000FFFC474EDB461BEA0F6D3FC058DB4DB81B -:10EC9000FF09062C5A7DBCE8CED81E51D0FDCF5EB0 -:10ECA000C9156E875A6EBA2A0BCF43E5D112F49775 -:10ECB000B1CDBED17C05968B7A7B2F5E1E42F1A52D -:10ECC000E725C0C3331D5AB99AB6F12A98CF1E8BD7 -:10ECD0003E3E18D445389EA8D193BC11FBDF5DA2FF -:10ECE000B7EFD9E89D4AF3B9DE047BB07C77E646FE -:10ECF000677ADF7C87E7E46EAC81B59F56BAE27035 -:10ED00001BB7A4EDA354D4DBEBCAF8FD616400F497 -:10ED10008FE8F7882FE06DEFCD2ABA62FFF3D03F7E -:10ED2000E20AA06899A9EB9003E0B6647FA5CD2C18 -:10ED3000E2FB5DA52ABEDFA5B75BB27736D939CB3A -:10ED40005E194769947687F1FECC776867B35CC437 -:10ED500078A7436F2EDDA5E0BD99CA06A789EA33DF -:10ED6000EEFF8ABE3EBDFDE95D6FFE04C73BA374A6 -:10ED7000A55E07B5D785002E51DAE9F5F5FBD55329 -:10ED80005CDECBDCC07FFF70733E6452A507EB07EF -:10ED90006D7EBAC76637FB4B519F002A0318A7A0A8 -:10EDA000A753DC79FC5DEC88EF91FC15B4B1A41994 -:10EDB000282F574874EE1EB4A98EB1906F817D4AFA -:10EDC0000D4C69CDB823E3315EA0659F93E47AEDE5 -:10EDD0008A0E5701F295C7C2D0EE6DB9A2331DDF7E -:10EDE000BFAFBBD752F604D26F68B9EBAE303B6C05 -:10EDF000780E8FABCF4EF097213FDA811F511F372E -:10EE00009A7D367C37454D1729AEDA0EE56F50797D -:10EE1000B656EE997E0DEDCB4419E7559F37777ABC -:10EE200009EA355722FFFB8423AE2A9B0FE501D95F -:10EE3000222379DD9D53EE43383D23792A91FF9EAD -:10EE4000713A658CC7025949FA401A914CF15956EA -:10EE5000EDBE53F638AEE7F57936B9B9FDD0E4B674 -:10EE6000101E5A623B6F2E867631F789B20AFD3743 -:10EE7000DEFB7029C6273E76EF913F637C6B53AA79 -:10EE800044EF0CECAE0979B15E8FC03A77801DB9C2 -:10EE9000BE6A6627EE47D73345417B7DB730D38FB7 -:10EEA000FAB92745623BA07E4C9E315ED559608CF5 -:10EEB00097CAAA30E637E6F8EEC7754DF8436131D8 -:10EEC0008E9322280A3E1D5CD8C9283E3F352F4F1D -:10EED000C6B8EEB8C28838D8A9C67E12AF32962717 -:10EEE000CF8888DBBAD558EEBADD98CF986BCC7F47 -:10EEF000AED3A38B9F3FE87FE7E1B17B9F64A8A7D8 -:10EF00001BBF8AA778568423DAED3123250F9E8B09 -:10EF1000645B3A67611C1CBB3486ECA583EE18A6C3 -:10EF200040DEBA94913CB526060FE07ED52ACAA5EC -:10EF30002A69A8E081F7A1DC01FB5594BF91F0CBD1 -:10EF4000CEE6FE416725FF7B7141294476847D55DD -:10EF5000BC5CE3C1AD63841FB6222CCFE3BD1F7739 -:10EF6000F3F338BA774F477284575819E26D320B72 -:10EF7000E03B94D9F77EA486601EEB95BC4AB4337F -:10EF8000D6895D348E5AEEF4E1BE3B05E3BC4D18E4 -:10EF9000EFAD521A898FE7DDDC4E52D85C3FE2D1EB -:10EFA000355BA4F891FA43317578F852AFBDD7A01C -:10EFB000C7B1E974F9B29BFBE7F67488A217FDE0CC -:10EFC000B7E7ED407CEBF9565F721BC5F58FABECF4 -:10EFD00042BA6437703B14F400DDCBD6E3C4F4B816 -:10EFE000C2EE1C1EBF763A47BC80BF901E47141667 -:10EFF000074E4777263CBAF0CB78DE933DAE5446B9 -:10F0000039F34BFDFE05E3FDE2F385746E3043F406 -:10F010005EA2F9D3D1AE4BD2C64B4A96BCF4BE3BEE -:10F02000CC4984FA0F315E3F296FEF4ABC77B507B0 -:10F030000907F9E72E0EE748BA4DEFF0978E4178B1 -:10F0400009A00FB3FAD3B1E06EA5F3C0FAFB58A242 -:10F05000755C7FBA9E68E2F64FCF4285E22C87A2AC -:10F06000F393EE04EEC74ED922A37D9B91F7500D8A -:10F07000DD83B98FC9A8EF323A3A6F46BF57243FB4 -:10F08000041C71E3799CDCB7F3C39B4C9C3F589AFA -:10F0900044788B8C2F8D8C271D9E93A0F929400FCF -:10F0A000C4E27D00F94A8C13EC59C5E89D809217A3 -:10F0B0005B6EFB77E8EFCB111619E575CE5BBEA74B -:10F0C0001C30AF2F5FF2E5A09CDE2675D913C2FC81 -:10F0D0009E92C8EF9F45CAEBE139A246AFA0375CCC -:10F0E000DF3DCD46FA06E20AE6A58E968108876FD7 -:10F0F000DFF4275BCAFFA0DDA2DAFCF8F746DD1DCE -:10F100007A3E8BECB09CB778BE685BD6465542B869 -:10F110005590BFE860F63CF21749EF727FD1189323 -:10F12000378079F69E9DE2EEDAF7DDBE00E3D5EAA0 -:10F1300053AF53503F176AFB9FF139425478491639 -:10F14000AF0FF926F27B81065FC64A3F9D0DF81B83 -:10F15000F3B885E2EEF2C5F2865CE4874613E1B3CC -:10F16000DCA42C6D0EDBA735A71697E44CA47D011B -:10F17000F3C18641E915980FDF614A3E5E8CF49A2F -:10F18000036C86F22547E506644E550CF385D1A93C -:10F19000D22B51FDE6546F498E26F7F0DCC7ACB197 -:10F1A000F43389A56C36EA65F8867AD7BC2B869F3E -:10F1B000F7241BEF479A4C3C5EE4266DDD663CD796 -:10F1C000198FEFBD8921EBD8FEF56FD5EA49366777 -:10F1D000C8148F7EB2378ED2BDCB887360DCDF520D -:10F1E0005C4E05233F28C285F2F7C8FCDDEE2A1EDF -:10F1F0000F50BB9A09781650ABDD5351EFE07F8F6B -:10F200009879BD0ABEAF425B4C05FF0B11FFBA6C8B -:10F210002C11EBA7B34E8A63641D4CE1F112C67347 -:10F22000A76D03BC03A5FB01A42A13ED5346BF66DB -:10F23000E77F17AA8AD13BE1F46613EE7F57B380CC -:10F2400024F4F9E18E642BD44E3F8FDDFDF50719D0 -:10F250002897F3C51DBE37C86E889577A07E8C3180 -:10F26000F2A17E7FAD56A3936DD532E15B2F77ABD4 -:10F27000C729DE3E87F5D4E03E2BA72AD180E70BD5 -:10F280007ED9DE4CE69B10DE6F80BFAB9B27D13B67 -:10F290005D4AAF9BCAB7552B43F43F6C80FED389C0 -:10F2A0009E06EE3F8BCAB787BE48B81140B1ADE7A6 -:10F2B000A38452A5CF6E8D84B37BB5517EFF607F52 -:10F2C000643C39878BDDEC4DBE19E0667F40F4B4B9 -:10F2D00031FC7B3CC67AD373CF25F0F372BD7E2818 -:10F2E000F916AC0FFBDE3605FFBE8FB17E69F1C7A4 -:10F2F00009FCDC5DAFCFE7F7A35E63BD48FC44CEFD -:10F3000017E695F2E3B0795D69B31ACACB66F79B4D -:10F3100057CA4FC3E6758DCB58DF57137D5ED7E7CD -:10F320005B079D975EEFA6A28BAB17B98E5BA65BC2 -:10F3300007803BAFFFD3B28BEBF75F160C5EEFCECF -:10F34000AAC871542E272CDE2328E7CA99B216DFEB -:10F350000967CE98A871C1259A1D7316FD14180F60 -:10F3600097E97D1FE55A4F368F4B39FCEC223F9EC3 -:10F37000C32CDF6751F0BC235BF35B83E0598CFC4B -:10F38000BBC72627603CA0CDAD68FBABCE5C8CE74D -:10F39000DBD37EE436927BCC68CFC07EAD18F535EA -:10F3A0008830BA97F126B64B098FA3F092FD572FFC -:10F3B0007AFE42FBAA9FF07D951EBF1F6E67B14982 -:10F3C0007D76961EBFBD491BE7BF7286D17CC0CE3D -:10F3D000A7BF7B9B9A27517CF32F6D9D9BF0FED19D -:10F3E0002F939313703F73589BB76E37EAF71AD277 -:10F3F00066E78D334581D7FF0791B1925A008000AF -:10F40000000000001F8B080000000000000BDD7DE5 -:10F410000B7C54D599F8B973EFBC9299C99D64F2ED -:10F42000E211EEE4C5044298608801AD4C12A0A838 -:10F430002C3BC147412D0E893C227921A8A1B2F570 -:10F44000864484F8206840A0A043148A56ED6011D9 -:10F4500001C11DA2A6764B6DECF661A94B47602950 -:10F4600002C2A8BB487F7F2D7BBEEFDC9B99B99978 -:10F470005150B6DDDF9FFEECCDB9E79ED777BEF7E2 -:10F48000F79D33172FD27F93087928892C0C1413FA -:10F49000FCC7951162CFCFEFE9741232BCD42B8E2A -:10F4A000A3EFDFC9D111329E9087E983D07AB9509A -:10F4B000F06FE3E8DF22212BCBE9F7D030979027DC -:10F4C000C57EBB40EB9F7408A2CC413B09DBED7CC1 -:10F4D0004BA7F3380879EA8EFC1EDE19296FF03944 -:10F4E000B64279B88EF80216E8445C44E8FB9D26E3 -:10F4F000D1DE594A8B42BFB3C64ACB3B7E7F1B67E6 -:10F500002364C40882FDD5B55693635711B2DB104E -:10F510007EF322CC673DE7DF46FB79ADBB74AA40A2 -:10F52000DBCF3B4988997E5AB7ECA6278FA71132CB -:10F53000E1B85809EFEB36DBDD3C7DDFD4DF321577 -:10F54000C6212DC45DE0262493AFE4ADB49FCC4723 -:10F55000DE73B7D329AFEB95F6846839BC9573F7A2 -:10F560004850BFB87431C0C7E2912C74BD7361AA12 -:10F57000F8DE3E550FED6E32B83B683F67F4641617 -:10F58000C0F1A20257F539F70EA982D0F9CF0D2CA0 -:10F590009B8BE38A1464D9B46C12711E26494C6D9E -:10F5A000A3E5CC2462328F23A47C85D8F7008C5F3E -:10F5B0006F157B288C6D1562DF8F605D2D3922EF12 -:10F5C00086C1FD0807B5FF791EAF81D07147EF30C6 -:10F5D000D0CED83E5EA4FF8D09C496C7EE892D9784 -:10F5E0000663CB57BD135B7E5562F09E681ABAE581 -:10F5F000388577EF012381F92E3A9DE4375278EF71 -:10F60000D31302EB975F32223E542FB278003F4E65 -:10F610009F4ADA6AA4E5838793F0FBBB7F6266DFCB -:10F62000EB022F43597E3999C0F78BD202E5A974BA -:10F63000DEAF7FC9DFE92D66CBD243FF2F176DED1B -:10F6400084FAAB02E5227DBF7B1421FD502FF84BDD -:10F65000609DBBFFC663BFE1E78DFE1EDAEFE9BD2B -:10F660003F7E19E075FAF9A1A91C9DF335BA9EAB4E -:10F670003AA1BECD2AF5D0F7134FBF98E78BDA97A2 -:10F68000453B8C31EB5C2C71B8CE56C1B3E259D8F6 -:10F690009F437AC4A725F3FC7541DA7E0997E39668 -:10F6A000A11F03C5D36228BB33ED145F27DA18DE30 -:10F6B0002E31D3729C7D579FB51B78E2BB2A523EF8 -:10F6C000BAFAC7381FD7C9F711AFF7E9655D12C09D -:10F6D0007135E7DE46E7BFCF6C2B2129F0CCF10373 -:10F6E000DEC81225BC745CD78F9A002F7EC5BB7B09 -:10F6F00048E2F15C597FDA3CF9AAAFA8A7E33A4B9C -:10F700000839F751D29D1E3A8F911B62F7BDC81F71 -:10F710005B5EA5C0A79644BD77C27C725766219DEB -:10F72000109C8FEBE407B739E97C8718490BC0457B -:10F730003BEE5A651D2FBC40FB716137FC459EF5C1 -:10F740002765D07D51E8EA758ED111FDB77428A5E3 -:10F75000B7451CE32FEAFB459A79A8FD4F94189F03 -:10F760007218DC6B42B8FF4611F6FFD483D39E3C7F -:10F77000AE1F3C9F130F7A3C93A3DECFDFB0B82FB0 -:10F780009BB66BD8993E8E8F826FC3F36F66DC4E4B -:10F79000DF9FD921B8810536CCDEFEF844F8EE793A -:10F7A0003E00F3857A0F5DEF99C0DB36F86EFE669A -:10F7B000FB385E8AB45FB0618A67B22B02CFCBA5FB -:10F7C000D3D72A189F5B14D0FB4D401781DF4D1D06 -:10F7D0000A78BA817317D071CA051F0F74672DF3A9 -:10F7E000E8E509844CFAE25FFB86D0FAE603E3CB56 -:10F7F0003B697DA7CE7BD33F01DD3DCDBBB7015D2E -:10F80000FFF69E0C5FD4FEBC03FB4BF7A5F3D606B8 -:10F81000EC47A6B85140997AAFABB61ACA138B0918 -:10F8200067A4FCD8769278FC16188FBCAF4B25E401 -:10F83000E4FE874A041DF2A3DB814E4E139B1BE8B6 -:10F840006E9FB5E5DF71BC97F438DEA4600A07FC53 -:10F8500077DF739CBB93003C62E9EFE4C915B64ABD -:10F8600046D7777A510EE88883F6B7F0D931C807C2 -:10F87000D4F7DAFDABF7C7F6A3C58B8F9475016A91 -:10F8800046E397F6BBB4E9B201E8B1A195CA8B286B -:10F89000BA6938DE652096C1E3103280BF04F09764 -:10F8A000E2259170BD66E41BF41F67A2787B0AFE17 -:10F8B000CA636542C7BF9BC3A59145A30285C0E744 -:10F8C0003841ACEAC88EF05752E1473E7F86FED9F8 -:10F8D000E906BE103802F40EB2741BC817317876F0 -:10F8E00013D4CB233CC08F860092D227F96932F221 -:10F8F000DF3352683BB67F718C5BA6AFCF01BD583A -:10F90000B09D2D358A3FB505DEB48568F9F4CEB4D7 -:10F910002ADE0678FB4B1BACF35420ADCA604BCCFF -:10F9200037B47C93CE0CE1FB21FC49F14E747A9202 -:10F930009D00EF0E2A74419EA5B594B6C4D937B583 -:10F940009DC3D0522A01FFF8BEC5DDC3E0463CB4DA -:10F95000FCE93B693DB0EFD7E8742817E672AC7F4D -:10F96000B57D913311BF9666071D117EFD84228FF0 -:10F97000557EFD8495C1E372F9B5F639ADB328051E -:10F98000E0F7299152403EA59AEA9E013D43AD7FA2 -:10F9900022811E50EA64FCE99D838529214BA4FD48 -:10F9A0009FF3BC6500B7ACAA7E0F4FE79F7503714C -:10F9B000B7D3651DE3DDF789147FEE2254BEC3B3D0 -:10F9C000CC67003E483AD211BE84B8A7C2FE2F9839 -:10F9D0004EF1A59495411ED77B0DEE4EAA37D40962 -:10F9E0000C3FEA7670FE760AB2BB1E8DDDBFF9DDF4 -:10F9F000C6081EC3FF6D8EAAA7E3D40BFE95206731 -:10FA000087514D29AD82E2EF73B1DF2F22419C5720 -:10FA1000C38B178DF1F0E2BF15BCF8739E6706AC7F -:10FA20008F9B69C2F92C7989437DC06108A0FE13C0 -:10FA30005E4CE5079D2FF92DC39BFFE4BDB8EEE6B4 -:10FA400065733D77D17D38D75AE7B98B56216B80E6 -:10FA5000FD0E307D6FD1E4401FF24122BE727B1655 -:10FA6000F4E74578501889DB101E028EF7DFBF657A -:10FA7000F8749BA2375EA39B89EB0AD713B187F278 -:10FA8000B9892F1EC432FDD772FB4478B07EE6B729 -:10FA90001011E0BA80C8064269ED01A713F7AF9EC6 -:10FAA000F41B185DFBDB3368BB26AA6F025F8BA3D8 -:10FAB0003F7C3F1A1F0F6BF0F1F015C3C709884F49 -:10FAC0009F1137E2D36D1A7C3C9C001FDB07F0B11D -:10FAD0001CF1596D4FF550624E1DFC3DE08B276ABD -:10FAE0009F176E8E2D93E7A2CAB98017B41C852F7D -:10FAF0004DBB2E1A3D71F064DD80BCF717D58C89A3 -:10FB0000E6136D38BF230A1EADBB657E36F0E935BE -:10FB100060700C513AA800F946FFC27D234113EDF5 -:10FB20003FE9AA8132D697AF6065FFD65F7B375C2D -:10FB30004BC87ABD2F5BA4F0AAE3BD7D3A902FF9A4 -:10FB4000BEE79C6057E83C3902EEABA7D03B0636D7 -:10FB500094E1E353E35A8A5AE2C04F9DFF7A2E1094 -:10FB6000D4019FDECBF4376B59581F2D5FDF703205 -:10FB70003994D21B427C0DBFCA11B02B36726BB3C5 -:10FB800001CF36664B5C3B5D53D9AEB64AC45FCA03 -:10FB9000EB0B28DE35EEFAB06F282D974DEB07F40E -:10FBA000A3EBF62E7E1BF8E5F824669724B76CD5F8 -:10FBB000D1FE32EF748D6BA7F8F6A653C27192AEE8 -:10FBC000EA3A08FD84174B620FED276B85ECBCA762 -:10FBD00018C66F6943BCAF21F83EFD7BCBDBE0BBB1 -:10FBE000478690541EBE236D1C7CB7329DC3FD58C2 -:10FBF0003997CC7AA518A84844BD7ED82C916B9B28 -:10FC000000E5964AA41749B4FF321BA9AC2385DA54 -:10FC10002DEB6C04F975BA8EBFB3863ED78D63E5C4 -:10FC2000D4E59CA70789772DCE2FD348A671A9ECE0 -:10FC3000BDBF18598E6727D6FB71BF33AB5B4A61D6 -:10FC40001E9979ECE930F874F974FC43EFE9FD2B67 -:10FC5000E83A0F29F8B2746B5566B45C3B74C6245D -:10FC6000E8A8DE7C284BB5178216B0179696566723 -:10FC700002F3C8CD9F9602FBEAC889AD3FA7F7A45F -:10FC80005C05F2FB3D9EC0FEFD97C59302F4798DA5 -:10FC900081CD5FBBEF9F29FBD97C8123FE28BA6C05 -:10FCA0009E751EEDB0E60B42CCFB330F9A08A810F0 -:10FCB000037AC5C2DEA9F05D23E95F0978D8184848 -:10FCC00026FE28BAB82629FEB82A3D345FE0891CF2 -:10FCD000775C43ECFB0B69444E8BF75D46EC7BBADB -:10FCE0008E98F29ECF07D601EF4945C8E6A576F873 -:10FCF00074D05368F99C5F27EBC7029B63FCEBACA5 -:10FD000018B201FFA2FA480BECCB592984FAC63984 -:10FD1000CA9AA01EE4780DECAF10B6CDB446C65119 -:10FD2000EBA17DF43E9E9D652041DC9F30CE03E03B -:10FD3000278F2464D3FE4F0C12E869FB0F22FC547A -:10FD40007C8986A31CC56F32DAFB833A4A5725B9F2 -:10FD5000196B8B8BE896F5AA7C216BAD87F2810C31 -:10FD60005E17C32792CB06F806B2A9753A5EE13357 -:10FD7000D96B275F1B5D66DF47DA0FA981FAB26294 -:10FD8000D6BE2277E87B2B40F6922E9C1F5D470E55 -:10FD9000C06FA06CD2942DB43C26AA2C6AEA1D9A9E -:10FDA000FA2C4D7918FBFE8C359803FE81EADC11A4 -:10FDB0003502A5D333D9C1391C2D3FDAEEAC994CAD -:10FDC000E9B4B18CE9174DFB39374722F06B723338 -:10FDD000BDDEE20E19EA8A010EFD7DC0571AF670EB -:10FDE0002247E9C112D819C432B493A2DA05386C9B -:10FDF000D710F810DB25ECDFA5433AEF741D65DF63 -:10FE000005FE827ACCC31D8BBDC0D8FAF48C6F512D -:10FE100029E7194A1B36EDA9213E4B84BF9ECDF63A -:10FE2000BC89FCF50027027D0EE029F46B89D085A2 -:10FE3000FAFD9FC6ECFF1DA849C94B3F6913E8F7BF -:10FE4000FFD1F897F1A077FF499123EB397F118C0F -:10FE5000BB89F88A408E7FBFB1E0A08E7E77441FB9 -:10FE6000DA02BCB73DF76A84DF116B683847F59258 -:10FE70008772AB6A040ABF23E9A12D00CFFFC8AD8A -:10FE800066E5E1A1E13A5A5EDDD3C4CA05A12D5071 -:10FE90007EA567362B8F090DE769FB3CF93684FF99 -:10FEA00036313E5D2FCB65FAAC3ABF87CA3C4B7307 -:10FEB000418F6E60F267CEDD876703BF9DA323226B -:10FEC000A17C7ADB99632F6DA3F0D8D69A4C7A186F -:10FED0003A7A056A6F6432D4A772A20BF97AD8C94C -:10FEE000F41BCAED42E0D74B1E6F923A9D917D51B3 -:10FEF000C7CF1CD5B213FACF9C538C72C4ECF41C40 -:10FF000081F1D5E7F451EC79245764FC9BD779F063 -:10FF1000FB07AC7EF87E8D99AD8BD20FEEB345D941 -:10FF20009735CABAD6E4323D63BA73CA91DCF1A000 -:10FF30009F28F6CEAA40FA283AAF6E8E04C06EA46F -:10FF40007A8A6C063E5C9F84F64C37CC1DEAD766F5 -:10FF5000FB653ACEED1CF1027F51F949B7DD939D67 -:10FF60001A65377697D2B225E227E8AEF1642739D1 -:10FF7000E099A1031B4AE54FDD4ED64E954F99ED12 -:10FF80006C9CCC35453DB09E6481A0BC9B37ABB02A -:10FF9000A70DF58399386FE2F16473B4BFE3F5B947 -:10FFA0003A80A3BA5FDBCB3C2FE0BA78E6F750F794 -:10FFB0004D85EF915CE6F7A8E3A97E41F1EEF17C77 -:10FFC0001FF647F58D1214EC8ABE710490767C04FE -:10FFD000CE44088D87F7FF1FC2AB1FF0E9DBC2AB31 -:10FFE000B195F211DD25F011058EEBB9A03E93F12C -:10FFF00011F44BC07B9047CF3B7DC773A3E861CE24 -:020000023000CC -:10000000038DA867AAF34ABEFFB569DF234087A71F -:1000100090EEE6FC2019FD085A3D50B503557D359C -:10002000911DF8A9420F6ED5EFADCC23B938F4D2AB -:1000300063145EA9C42A021F3D62088D71D3F6477E -:1000400074BE675F83790FE145CA4306F5F7421E28 -:100050008FE39B553C2161DB2847044F56533C31CD -:1000600041FB1A03DA25DD76FFC6F98027B70C734A -:10007000CB12CA61A467B93519EBAFD11D25E0C712 -:100080000F4F1045D033295E617DF7EC42BFCCFCA9 -:1000900031B219FDD349FE1EC0BB520A00E86FF60B -:1000A00028AC077F08FA91669BD87883F18AF92DEE -:1000B000461256EF54F0B63E17F136A39D303F90EE -:1000C000E029A989D217BE9FC7F022B92CF4EA1FF4 -:1000D00040FF7CD4EC2E20CC6405FF12E9CAC4FE9C -:1000E00028BE8CC81BCFE438F47BD7E3D6AD8CEFA9 -:1000F000B9CB01CE0F5BBBC832F40FEA71FE9BCDCA -:1001000041D4C37526C90E7EF8393C595F08FDB548 -:10011000EB45C0132DBC2BF312F91F42F746FB8BA6 -:10012000E71865630ED43F6846BB40B5FBE6A430D4 -:10013000BA52ED3ED5CFA11D47B5FBEED4D873031F -:10014000F59D7F2DA8A5FDFD59C13377EF8582B9B7 -:1001500016B66EF03FD5C25F74DCDAE5E60FC1CFAC -:100160005C2BEB83461BF091299E50949D4636B044 -:1001700075F87EA5F7039C5A05B27E3BEC8FCCD672 -:100180004FEDD8FAE8756D32B075C93FB0C6AC6BAB -:10019000938DC591BEFDBA3E1A1FBBAE93E3957514 -:1001A0001153066DA7C8B93B5BAD1F7225F409EB6F -:1001B000A24FB29CAECB1559D7B23CC64FE7287CB4 -:1001C0006C90DCCD637A7C1CBBFDFFC67ABB9EF2D3 -:1001D000C45BAF769D7FCEF3FC202F1DE9262896C9 -:1001E00045F0DAB791AEAB0CF635DDDF86FBCAF031 -:1001F00093109B1BF8D89279745DF06CCB447FE12F -:100200001CA3B407FCE6E44729CA3A09F281251B7E -:1002100087235D52BC6574FB14F3BF2C317BD17F07 -:10022000B364B1E8964558FF2B680787297F45BD21 -:10023000A43596AF7F3D1CCC39B5C5D17030E5CC27 -:100240002D8EB3EFB211F139D1BEFF990FDFCBE59F -:1002500025F69790E5B17E0AF0E70E94F9C165ADF9 -:10026000DF8390BF1963BF9713E051E8FBD1787427 -:1002700044AFE0D13233CA1F158F8E5815BF900698 -:100280008F08D5A2818ED5756BE13807E018C72F8E -:1002900044F1A900E07844B1CF283E15001C553A3E -:1002A000B8B395F1032DDCFE9498AF7DBB7568F073 -:1002B000F8DBAE43AD4FB40E55BFDDC02DDE08F800 -:1002C000B9219B88EDA80787C6809DE430F88B6034 -:1002D0005E9B0C947E91AF303FE1678762FDCEDA82 -:1002E000F95CB8647EC1FA4DC42712E1E5E5FAF97C -:1002F0006A35703BAAC06910BEE733B9A9F5F3357A -:10030000DBC24F83DED49CC4E4F7D90356A47392B6 -:100310001F9A03F6C2B97D4602F2A0890B15C27777 -:100320006739CF5CFCAE2D590239AEFA738FED669A -:10033000FE5C99507B9D961B7CCC1FDD2CFF7225AB -:10034000C0E5629ED002F672F39E587F20DD0F1B3F -:10035000ECCF591DE987EF9B787F3D98D8EB0D4C8A -:100360007F59AF23018067C48F70B410ED9A6C91F0 -:1003700080FFAA49F761E13D517E8726A5BE298706 -:10038000F9D3203F01E32E309473305C9A1E3DFD7B -:1003900025C4579B7669E93B96FE1B2265EE220732 -:1003A000FD45D53B23F48FFE03C08BC9C45FC081DC -:1003B0001F909593A7F5FB21CFA159F13FA7F78691 -:1003C000A6827E632D0B10E0FBCD2799DD3471FFF3 -:1003D000D637C13F689FD63F1C54A866251EA5B5D9 -:1003E000D726EC5FCB833F4BB5B7A2FC67453363A1 -:1003F000FCA72BB01DF8E360BC10BC82B881C0F430 -:10040000F2F58A5E4EF577E4F3F3BA46A2FE0EFAF1 -:1004100035E849AA3F0FF426D09F77E757CDC8A704 -:10042000EB9C5D50757DFE78361EFA29C04934215B -:1004300031DEAAF051BF03BFDE57C78514FD8FB070 -:1004400078D03DBF48FF4ABA5C949F307E7F7BB432 -:10045000FF7D9FC6FFBEEFCAC5833281AEEEE1A429 -:100460004CA0AB891AF9B62F811DB0247F201E94B1 -:100470000974ADB63FC1FB30FEA1C61DEA21CE8294 -:100480007226887189BB5B88BB13F3407C2BA1DC8F -:10049000B890889D14DF1B26FB58FCA38588374E37 -:1004A000607156298ADE208E195D263B6839460E1A -:1004B000F6631CA489F6B0C90D7E9AD8EF9B89BF5C -:1004C0005A003CDE73D118D34F37DBD73B15FCDE27 -:1004D0006866F18389CBB7F224CA8F9332CEE37C6E -:1004E00008E8F7177AF45FFFA7828F2A3CFE9C5733 -:1004F0007513E05512F8D5E0BB878CA8C71CD791BF -:100500008580DF6BECE4CE99F479F641E2C9D7033C -:100510001E8B39D1FE44F5D9B9CFBC10E8E219855C -:10052000EFA9EF2BA051BA120F40FD3F19F3472856 -:10053000FB2F01BA29CF55ED0E520271880F157E9F -:10054000DA74ABC507FD85748CAFBF98CFE4C08B60 -:10055000F906DC3FB53CE08F53E8828E83FD255DD4 -:100560004562E2D73F53F055F58713254EB7BE3E9F -:1005700089D92903F4A943FE9B5CEC35F890FF551B -:1005800021FF0D7F6491002ED34E37D4C33A3E9D98 -:10059000954420DFE62E254EFA6EBE1DFB55E38BFB -:1005A000FF40BA8889935E2A5DFC3E421731715242 -:1005B0000AD764900BFB74CCAEDD47110BFD8201B2 -:1005C00025EE2E100FC8AD7DBB46A21D3357F15747 -:1005D00053BE81F66B98CA37B6DFBE8DF3E0BB40E1 -:1005E00001E6237CA8F73FBF1DF49903CC4E53F7D7 -:1005F00063DFBEA17EE03B134F7F9103F0DF77F214 -:1006000085A190E7B14F89AB37188285E84F31302B -:10061000F9DE600B1602FC5E57F0A6218996E9FB15 -:10062000BC745F18F05ACD8B8176765C8F64037F43 -:10063000CE31C54E3F4AED769817A5967E88F7D302 -:10064000FDCE8672787526D3A7E9BC002F8E1D18C3 -:1006500083EB5BAF67782CEFE5D0FF73541F3ED17F -:100660004ABF3F9A7D156913413E5FD8DE07FD3FC3 -:10067000CD13A30879479F9FDF43BF3F378417C13E -:100680002F59A7F34ECD067EB19BF943B4FB00F280 -:100690003A3AAE7B968473D06FBA303700F87376EF -:1006A0007F11E6D3118748645A6EDECBEC476D7E2E -:1006B000C4717D2CFE6BFB857581FFB219FE067D32 -:1006C00024BA7D9CFEBEAE7C561F2A5C46E13145B5 -:1006D000F24905517E80E637B2518E1C7BEC73DC0B -:1006E0004FD2C5E2E8C7F59E39303FFBE4A0A13602 -:1006F0000A1FAF2E50FC5046A65F50FE6B88E637AF -:100700006A7D7915899B9F525EC0E8DCDACFE4F4FC -:10071000E07A86E7F7926779E0175743320FED6F7B -:10072000849267732FF9ECA011F4A94029E6F18CAB -:10073000581E443E40E78BF8797C630AF247F22862 -:10074000C3D7F93F3222FF984FE507F367B0BC42A9 -:10075000F228CB1F3AF19013F1B97C45B01CE9C1E6 -:100760004EDCA047BDD6F1A1CCD3FAB93BB852C8F4 -:100770009B9CDBE1443BF0EE5D4EDCDF890A5FAF22 -:10078000337A304F923CC3E29C773D518FE334265D -:10079000133B8FFAB5DF007AC4C21D1CC6C32706FF -:1007A00018FF6F108207414FD7E6FD107F6CBE0126 -:1007B000C82312A5C783FC211ABB2B76DFE54BD2D9 -:1007C00017B472667141427DE1EFA4C77F337D614A -:1007D0005981AAC7C7EA0B60FF17303C64726D27C6 -:1007E000C7F89CA22F3482BE00BAB022A75539BFE9 -:1007F0004091F32778A667CC37AEC5E79A0296E713 -:1008000070370929790E6103E87F89F0788D322FDE -:10081000158FBB008FC747F0B8E164B0CF887E0763 -:10082000F76EC8D368584E82566AB7CF175A509E93 -:100830000D118988F9AFD53E9C57E6126AAF51BCBD -:100840009C0FB1FC7197AFC70CD25B34FA8A3A6F38 -:1008500015AFB5FAF5C4E57E1EE28BBE9104DFABA1 -:100860004F91044A61BE352666DFD4982C411EFCA8 -:100870000F93F567A2EDCF1AC1F322E33BC3EC2738 -:1008800046234B23D0EF74A7E737A3D2237A7B729A -:100890005978E563B43F3D29D1015F57C7373B2BFA -:1008A0003F298638AFD08FF62BC962F92C478A19B9 -:1008B0005C93E93E6CA570D50B32C24F6F12ED6DA3 -:1008C00076D8FF7E8CD385D309FA6DD5FDDA622503 -:1008D00032E4151F2966787FA458C4276D8FF9006C -:1008E0007A176D4FFBAFDA67463E727EAFD50FFACF -:1008F00004959323ECB43EE34FD40EA4E5B3FBACD4 -:10090000A8579D55E49B43F5DF9395B8FFEF2A78F0 -:100910002393AAA160EF11EE86A174EE44B5431AA9 -:10092000ED89E2DA4ABDB3FF5686BF46D46FCEDB0F -:1009300043F74199CE0773E0FA14BC6ADE555DFABD -:1009400000C81BAFC5CDA0EE2B057DCDC82FBDD5F2 -:1009500044813D955F1E5E06783FDC221A6993C98B -:10096000233EF8FD6C5AFE68979E18017FB6DD9411 -:100970001284668227CB3B66F07CEAFDFAA3A128AD -:10098000BEB368476CB931105B6E26C2D15094BCBF -:100990006AFDA0FED76F45E1DBB902AB03F08048EA -:1009A000C47D91D2D3F107F7906320BBF93B52800D -:1009B0009FDF45D9563C7AFFFCC185BF7E8B7E27E1 -:1009C00018AA3E2F40FD5232007DD5523D279E9DF4 -:1009D000BF4DE16B4663CBC9AD143EC6D78DEE3635 -:1009E000DAAAB7C0470AD3C13E0EF7C1BE1A479C68 -:1009F0002981F846D5882F30BFE4FCBF1037C0E905 -:100A0000BCB912F1E9FC46B3047E80EE1C0BF3CBBB -:100A1000BFC1F9396617CE184FEDE9853815E0BB2F -:100A2000E1951B41AE4C308A2B445CAE4987FB4DAF -:100A3000AD63FAEC36C82BC1CFDE4D0DF43637D896 -:100A4000D1FD362086A98512CB9FE05F3498E89FC0 -:100A5000CE0E4F511BFD6E91378940DEACF0A5E004 -:100A6000053C7B18BA8AB22B8715323ED3680A1927 -:100A70002AE977CD5F2C9D96AE8BC47D8C7A9F67DB -:100A8000289DB77E4F6970287DB5A0B51AED672AFD -:100A90001F185F3CC0F8E2826595F89E9B390DD720 -:100AA0007B82AE17E0F2E64623AEF7C4700BFA3352 -:100AB0004E6CE1B0BC403460DE2DD5A7D22A1DF0CB -:100AC0005E2F1AC96078346F7878E5465AFF6E3623 -:100AD0004F388AFF7FD9FC738C4FFD85B0F1E55DFF -:100AE0003CEA697F11C3E54180A7D4628BB6D71772 -:100AF0006CE1BDC02F176CB9F7DD0900B799B79548 -:100B0000013C26D99766489648BDAA9F0AA915DBDD -:100B1000812E277D59DD3F09F4C42D946EE8BC0574 -:100B20001DF181BDF4D696EFA27DB0A026C90EEBD3 -:100B300093366F9B0AF2F82F354374B8AE9738227C -:100B4000023CECAD19F07E012778E3E1D5E1021E0D -:100B5000F1AA7284C50DF271C1EF78C4174A67B764 -:100B6000425CA9718B1EED8FB7661EFEFD6C47843B -:100B7000CEB8991B664C84EF7FACC7EF07F4BFCDAE -:100B80001F7F007E17F84735119043083F2DDD1970 -:100B9000472C2F847969E96FC18A964296EF717963 -:100BA000744836333AF41572C8A7BF011D2E2CBC09 -:100BB0000C3A24C35263F48EC17C4F46BC55E3E526 -:100BC0002637F16CB3607E9487A3FC7A6DA180F523 -:100BD0006B0B999D29FCF59E1DBFA2704A2BF4FD5D -:100BE000A010E42BF194827C96C26215B8E62D8A9F -:100BF0009E4B36B3F318600FC1FEAF4F27DB3BA30C -:100C0000FC5F8F417FE9C817DAA19FB37FFCA20F79 -:100C1000F6AB29E74C09D801CD17FE0BF36C2CFB82 -:100C2000597E96C51DC6BC35BDC38BF8A8F2FD66BE -:100C3000379343DA755D28D4333EED08633F635C38 -:100C40008C3ED5F8F4A6D6248C136E72F8CDCC8FDA -:100C500045F553DAFFF4321EF98CA9AC9D801C23B4 -:100C6000153CC6F7267DF16B02F1D077AFAD7683E8 -:100C70001E6C297B5348837556E895FA9FAECAA52A -:100C8000F5BFBE760ADA73F764F112E853D3CBF2FC -:100C900064949F1E96273FE98B14A4C319F5335023 -:100CA0000F56E7EB2526C942F1642625D6E8F30462 -:100CB00033AE354B9628FCFAB48B9BC6EC0029E585 -:100CC000E631CCEF162866F23C1A0EF7641970FC78 -:100CD000D905952F01BE4CBA8EEDC3A9978CFE1590 -:100CE00074DC53E6F8FADDFE42E647C815AE47BEAF -:100CF000B4F42523E66B9CE6E27F7FF72A1EF3CC53 -:100D0000EA5771C44FC73BF5FC6B39C0D73FDAF6E1 -:100D10005A4E6DD47C12B5FF6361227F76F0AE68C7 -:100D2000FFC074038B139171C6187FFF749B721EF2 -:100D3000E612E35FFF9430EEF38B6130DF5F0DC4AA -:100D40007DDE19161DFF1A8863BA59DC471BBFCC1C -:100D5000AFF83765BEECFC41ABA0CCD76D6471AC8D -:100D6000792C4F62C98134C4BBE986F0E318DF7C7B -:100D70008317953897C784EDB3587D8275118F27F7 -:100D8000DF518EFE319C0FB7870B5A6DDF627D8479 -:100D9000C5B5B4EBABDDCFC78DD336BB585E48725B -:100DA0007118EDC0A3EF3C0B991803F86EDEEFD479 -:100DB000459F5B19D06715FCBE09F09BAECFBC8A7E -:100DC0009513E175227EF5A822B755FC3EBA2A2F6D -:100DD00005F0ED215353A88FC2CFC3A710F3105ACB -:100DE00056F241E40FACC88778052E4491835B3EF0 -:100DF000B0A27DD6AE6F7906CED9C96D02D946DFD5 -:100E00003B929AFC6DB42CE9AD9847777FD28CADBC -:100E1000608786A882CBD1F2E74947B6829E404CD4 -:100E200029444FC791AB94F60693D84EF58BA79201 -:100E30006DC85F5AEF2228BF334990E32840DC2376 -:100E400073991F7CD16E0EF3E729C583DEE7CE8B45 -:100E5000AF8F168C64FCFB8F905045D7EBAE8EFFA6 -:100E60009D7BA4EAF7137CA128BBF461CE2D29F960 -:100E7000E404F265F5A47F36F265AAC7FF9ACA8337 -:100E8000A1FC2BE8FF3EF6A0EF9978E792D4E75D4E -:100E9000D5F1FD0A1394715D5D9C5F6F43FAD56DCA -:100EA0008DA15F25AE6BCD70530903F17C16B7CDD4 -:100EB00027EAF9940D10171952C1E668F38408E87F -:100EC00017595DD7135F1AD0D3C44C906F4BE6C54A -:100ED000DAB959B5ABB2D10F597BDF0C90DF1BF4F7 -:100EE00096555C0A3C63FD871B34FEC3AFE30B5988 -:100EF00009E9664216F8633644E2C1883FED73455E -:100F00003FCFE12A48749E4346BBD4E7033DA8D2B5 -:100F1000E4EE710FA61F52E1CE8275BDA8EE9B4292 -:100F2000CFCD0A6A72FB39B44B07F343059E8DC3DC -:100F3000109EE6AEFBD16E4A2E657EF7E4FA5A1F8C -:100F4000F09F64CA7FC08E33185A38DCFF89CC6E9C -:100F50005BC2B1F2924A5194E9F7069B923F7D033E -:100F6000ADB7039C7CBE68BFC335BA7B2AA3F3B47C -:100F70004542DB031F9EC5C69B6E5ACEF2C47D540C -:100F800047CA8EC0B14A81637E45123B6771AF0983 -:100F9000FD719BCD5D385F9DC4ECECDA4E33F2BB46 -:100FA000A1BC0BE352BD7A861FB2D584F4EAEE7D74 -:100FB0001FF305875E9D25F1CE28FC59CAEA55BC72 -:100FC000209A3C138341EA037F239D881BF2949669 -:100FD00070525F15AE4B0CCB6E58B7C2974B9298C0 -:100FE0001CA1E66616832B8B3B6AF68BE20D8B0306 -:100FF0008CB1303F17F149A87769D63B186FF6BA24 -:1010000080DFF60EE0CD1E573C7EBBC62EF5F544C4 -:10101000E30B9156821FF8111D0977C6C31F77ACE9 -:101020009DAFCD9BD4DAFB4DADD55EC5FE904DB8DE -:101030009F06B43F9A96557A99FDE16A037F59F36A -:10104000722AA9689BEAFD9C09FA6B9E6543FBBB6B -:1010500079CF4ECCA7689A46DC308D5AC59FADAE8D -:10106000F3A89EC549A9CC0A403E47B73DF4349C3D -:1010700083EDAE57F3BA589E93BC8753F2BAD43C73 -:10108000C0F011F0D7767312FA6D07CED3D2FD6798 -:10109000F95C979717682DF63AC112FF69C17FFC7A -:1010A0002629FD32F2AAE582755F9D579D742BD4E7 -:1010B0009B602F947A4003AA2FAB658F59827CAE38 -:1010C00048BD40ED4ED31E8EB597D7DC3245C07378 -:1010D000704AF9F327E1BCEB1A3389192F7A7E8223 -:1010E000A67F302D2D92FAFD1F664EC9C73C48657C -:1010F000FE154F7A86D1FEF4B1FD21CA28EDA1A0DC -:101100008EF7C2E863DD8F0E8BE8ED548FFF6CE441 -:10111000F888FEFEF0E1E95D63E958C9E26778EE20 -:1011200050D5C39B1D2CCF5A8BE77F53E414B58752 -:10113000A7826AFDF0ACC55EE877200F72FF5C0FF6 -:10114000D8C16A1E64F3722F9E3FA47ABFCE057980 -:10115000D57F3C73E220013BF314FA039A2F08CCAD -:101160004F4EED078EE28B69FF5AC41FB243EF0763 -:10117000D74EB75D26808FDD07B8F1805F84B4E479 -:10118000DC42617F9BCB9384FD25C83FC873313F10 -:1011900077B3AB6A6321C0FA398E803EDEE9FA1478 -:1011A000ED8AA6BD53C6479F97ADDFB38E9DBBDCCE -:1011B000A18FBBEE3C17CB776CDAFB2AC67B4EF9CE -:1011C00039A4B985827F35D89B0B17EAC0B2226556 -:1011D000FEB998374D661908CCDFACD821CD3B6EEF -:1011E00092E1FC6E33FD8F9200D9E49D8FFAF6A652 -:1011F00059260BE40934BB6A1723BF13933C60CA1A -:1012000069E739900FB92C09F3AA3AF7E8A7819D4D -:10121000544EE9E26716E0ABEF39B702FF4C1BC74B -:10122000B78B90771A5FFF2E1AC5E45007E795FF3A -:10123000B90CE338243ABF7DC41E667F4D74196231 -:10124000FD932E66175E2BF75703AEBD218492C126 -:101250001E6E269E4FC0EF45BC1609E3582480FE43 -:1012600040C78312DA4D2647E891B1507FAD8076B2 -:1012700093EA4738BB3713F5B1975DBEEFC23E9690 -:10128000F3A127FF19E0F688A0C4C3185FC9B9C944 -:10129000320EEC2BBD83E93366AACFC0B9A1EB5661 -:1012A0001FFF6535F0568717F50842851CDCEF50A7 -:1012B0006DE2583C48A33713D13D19DA4F55FCD2A3 -:1012C0000574B74E9810353B2EA6813FC32103BC51 -:1012D000DFA10B48A3F55388A783ED0BDBBFF50611 -:1012E000A6AFAFD799505F57F5E164473FDA898DD4 -:1012F000010EC76974BD82E7471629E71406CE0BB5 -:1013000008213C3F51EB4A56E2B01D0C3F493FFAE1 -:10131000C3C88B6C1FA8E689E72A54B8ABE70CD486 -:10132000FE0C4A7CB751F1E75280317A74A9F1DDA5 -:1013300015CA533D07C2C62582541EED775C5F4334 -:10134000483FCE4BB2C17C1FC9F0DEE7A2DF1FA52C -:10135000780C78767455B29F708047FD1E88D3C88C -:10136000A52CFEA2C5A7475C9C72CE2C3C15F3F0C1 -:10137000F6263867B627F69C19E50F8BDFA6E394AF -:10138000951D76037EAFB12BEDAF2778BE407BCEA7 -:10139000AC4BD987FF73E7CCDC9CA7873EB7BAEC90 -:1013A000B1E7CCDC6CBFD43C19EDF9B2B3D94181C3 -:1013B0009D07093DBD0DE5A511EDC2D73FEEEB0040 -:1013C0003FF3B952831BCED564DCF64E07E62B7192 -:1013D000420BC44FB5FAC0EF9CD53F01FA5977CB09 -:1013E0006E37E68F6BF481447E008CED46F9890EF2 -:1013F000B8AEAC1FC0DCF5B90DF0ED34177E1CF2B1 -:101400009AE5037CDCBCE60F5C89E2629E59D1FA66 -:1014100069879AFF674F8AC987ED4890FF9748EF21 -:101420001712E6FD5D8FFA5BC740DEDF34557F8B18 -:10143000CD6B1693BED25E56C79F1672C6E4117C62 -:1014400072C9EB54EC9804EB4B64B75D6E5E841686 -:101450000E1D09E4E85F5D03F13F4D5E8447843C67 -:10146000820EC823A04F812332FACF760EE44504C2 -:10147000D15FFCEA48F47B1913E645B0FC3EE1C0BD -:101480004809BE7B58EFF5803D23EFD42B72C0FF97 -:101490003CF84D3A0E64A39F8DB84225C01F05FB52 -:1014A000D42CD0AB3A14FC6CB8F4BC88B4A2387914 -:1014B000115BFDE31ECF65F6737F32D5CBB61226E6 -:1014C000A7E4FDCCAF49E78D7EBDF063C3515FE576 -:1014D000669A701DC7DE30F618510F77639E436D14 -:1014E000162F827CE9AE293F01F2EB18555C818E04 -:1014F000EBEE5E8EF66BA2FDA95B151B7756DF5FE8 -:10150000EA3E8D2B62FB7414EC7B14B432FA8B1719 -:10151000AEE20E62FEB626EE5D56441439119BC74C -:1015200070DE5C89F1D8FB9EA8C138EC7CD282CFFA -:1015300085A44B89CBB2788BB44A403921EDE0FCCD -:10154000929391890E6D7B5187F7F550F1B609445E -:10155000A24CA9E66AFA9AD371A0A74A1DB49C4985 -:10156000D7B55A90B3E8775BDF4F46FFEBC30E4920 -:101570003957C3EC2FF9510EF53FDA2FDACF720746 -:10158000C51BDACFCD452C2ED050C4FCC91445FC68 -:10159000381FE5D9A1E47DA8E3B5115D109E3A8E10 -:1015A0003D1F168569F1F43BB5BF0E7D8B09E22D19 -:1015B000E1E13A8C679E377866613C30B59080BD3A -:1015C000D8616D59358DD5230F3D6F0E7BB1FE3B34 -:1015D00002331488940AF3BD41D90FEDBECEEB8AD5 -:1015E0002D6BF313B4F77ED411DFC8ECBCC1F760E8 -:1015F000DC50C4E4E1F94EA7B22F6E8C9777E8A5D2 -:10160000DF38413EAE16500EB70D6370D30D67CF75 -:101610005CFBE4592887ED543FC5F9B2F9E77EC772 -:10162000C101FD75D8197E7DDB796BE7BBB4A810CD -:10163000F7AD038C063A5EC76ACECFE0C5E67DA95A -:10164000FEEA278AAEAC9C3AC6B9B70701CF2CFE9A -:101650001F81DFAFAECD28023F3BCD29F4BF9A47B3 -:101660007EB669612A968FAE2A403FD000DD9E5C2F -:10167000B918EE33B9D47C8AE714BC7857E387AB4A -:10168000ADE0DE837EB47007841254F9439B56DFCD -:10169000543C15F863938E4899A00FACD2E4B3681C -:1016A000E8798AE47BA508EC0F437F1FE353A1424E -:1016B00001F56FB31BE0B64E776CE7CF015F769A0A -:1016C000313FB26979783BF82B3325DF5E68776666 -:1016D000D9E1A99C84DDA19E74EEC048BC1FA7B6C9 -:1016E00043738FC7A3B1793464552ACBFBE88E7D51 -:1016F0000FF737C4B41B945FC3F4D6F5065F11D857 -:101700001793AE6379891FD7EB08E0C5C766863F9C -:10171000F2635645CEB80BA3F5DADF6BF1E3313354 -:10172000E2479D72EE4DBB1F8D801F74DF1A14FCC3 -:10173000F8F8D5AB0B013FCEECBCBA10F063BDBEE0 -:10174000CB03F4B53BDF7718E0717C8AB74FC7F85D -:1017500052E1E5E0ED4757186F2F55BF328D4A141F -:101760006F91EE888EB7F4EA999F4C36C79E1BEBBB -:10177000BD4CBF6A62FF58517EAC7FCC951F57BFEE -:101780003299BF52BFBAFC75103C37A8C6617AAD1A -:10179000E1C7B747C16B8999E5A32C291245B91454 -:1017A000D6579B87E710FF6872F77057749D317E9C -:1017B000C037BEC85BD905F3F030BFE51B82D477D4 -:1017C0000D1DF70DC2FC96DA75DFA8C46154BB5B32 -:1017D000B503B5E3978C627AE6A4519E52B00B260E -:1017E0007D7111FD0827E11E2C3AAEC9FF33B4E725 -:1017F000C87E4EC4738C128B8336ED9DF72CF85D3A -:10180000EBFD4AFC721787F67AFD739F60FDD93DA8 -:1018100075586FD9CF05210EDA3C4C87725BCD7FAE -:1018200050FD3FCDFB4BD1EFA3FA7FE83CC6805D76 -:1018300099EC081B906F817D49DB35092CBEDBE4F8 -:10184000206E1958ED9E58BF899A1FB5C96B407A12 -:10185000DFB49FF3833D9E61F03987213C87892760 -:1018600092237C63FA28CF4AC87352F3EEE0FE9FBE -:1018700051E3D10F9A83E710F4EA7D2FB1F7F324F7 -:10188000C2E70509E986CC89C6B790260E11BA626F -:1018900079CCB351DFFE6FE2457DDBA7C1B75002C3 -:1018A000F9D23C4ACD63BE15F57DB5FDE0FC7E3F27 -:1018B000CBEF1FC8CF6379FC0DD309E9B4B332DC99 -:1018C000EBD408F73AB999BC0F6AE47D7419F2E1D8 -:1018D00082517CBE41E8C77302EA3D4E901F17FD5E -:1018E0007D139CDBC963797231FD28FC3F93BF07F0 -:1018F000E35571E2C47744DB4B8754BBB0543D17CA -:101900001636803F6A499B230C718F4356E5BCBA5B -:1019100092AFBCC41C3E06FE9A25CF67E279A201B5 -:101920007BE425A3E2EF6774DAC0FE24CD0B8FA21F -:101930005FA219EEA5E022FB363DA11DF98B7C8844 -:101940001F1D1AB023DFC987F363AA5C687033FEDA -:10195000D6B08763E70803B1E7C85E1E7565E58406 -:10196000FA5DA2F6874625B24BBF0ECE0CDF0F25DF -:101970003A7FA7F075158E5ABCBF5CF8A9F503F045 -:10198000A37C08E583067E5ABF9FEABF231D22FA87 -:10199000F7A80E1580FC53D57F77A9F2FB43054EBF -:1019A0007F6FF94D4627E243DF6E7F12F1A3CBDD57 -:1019B0009741F21BF6A724B1FCCEAFF83765DEDA0B -:1019C000BC0965DE9ABC8943FAF00C760F0B858F53 -:1019D0007370DE4442FCFB9ABC896FB04E4DDEC48E -:1019E00057AF539B37F1CC81A76C105A84F38BE02F -:1019F00027E9DDA6C77C81A9BCC5C3F2D97896FFCB -:101A00004A3C785F6FB3C98CFE106DBE1FE5542B46 -:101A10005B401FAEA0760A9C97DAD28E7A4463367A -:101A20008FBE55C86F14A538F9A4424D4A501A9C70 -:101A3000D706E70BF05E8BCBCC6BBB66B4D581F2DF -:101A40005722CE6F985F5A3D1AFD0F5F9DD7F65C07 -:101A500001C3FF372D9FA545DFA75B552C13885386 -:101A6000253A0751339A1BC85BC6F38A824CA2E51C -:101A700071A276B34733FBEC4D43F8FD00E881B427 -:101A80001B88D36619A8F55F16B9AFE13697F7F64C -:101A9000D1E9A83FE1FE9EDDFB078C4F3C934D440E -:101AA0003897F08C5EC67D96D309E2B59A7FA18EF9 -:101AB000734E89A35D2AFF593CFAEF2B171EFFBF17 -:101AC000CE7706E569317AFC06FC06E96F809FE86F -:101AD00059FC4ABDAFE56BE5DC95E6339AFC9244D0 -:101AE000EB6A065AA4F8F3CA68EF8B8C8E3CE817B1 -:101AF000BD5CF9975C46F52180C72EA304A466520D -:101B0000EE65218F66AB7E5C769FE79AE1A82F7F1A -:101B10006C66F355EF9B51D7F3B6163FBFA5DDFDBD -:101B200078BEF7E7405FC72B3D780EFC612BD3DB17 -:101B3000C2CFB33C7DEDFD29946ED87D32CABDE0A5 -:101B4000DA7B20FE38FA1F23BF2F8CFEDFD1AFFED9 -:101B500051F2FBF2D7116B7F1FB2B23CC888FDFD7A -:101B6000BFB6AECB92D76A5E747955BF129FE008BC -:101B7000C427D4719AFBD9B9A2A1CA7916F5FD8DF3 -:101B80008A5E7867B167189C9F292B0B3E0DE76B27 -:101B90009A880D7FD7A02970FF8E5F39D8F9662CFF -:101BA000BB587C95782D785E3FADD057588CF41B90 -:101BB0005A09F439C241CA21CED1E99A49EA2C988E -:101BC00037310AEA472C0F3DFDAB32CC1B6B017A53 -:101BD00055F3A6CB2F7EB6725A19CE17FDD50E63DC -:101BE000ECBD333716337B507D4E53E64FB73D1B6C -:101BF000E67366213BEFDBECF088E0F756E3F4C9CF -:101C0000523FE63934ED62465139D88A50FFC03030 -:101C1000A4AFA65D95A510BF25017329DE07FE2799 -:101C2000760FFF996543D03FFAB2CB5709F3B696CA -:101C3000F9AF07BB7F041D07E2BC67765E5FEA8BE6 -:101C4000C33733F95419E2E0993C093C2946F816A8 -:101C5000B5F767A37F7B6518FD6EA5C5EC7DB383E3 -:101C6000C9F5E6FD35649E2552B63862CF8B4D1A14 -:101C700035A514E6515A2C2879A42C6FD549D530B6 -:101C8000F0736AF1C9A9E4ADD62879D9443645F292 -:101C9000B173BF3E6F559D9F5A56F356932F30BF79 -:101CA00043AE68C03C17EB2AC657C97282718E6B6F -:101CB000C3FDD529144EF9DDC16B014E290076BC58 -:101CC0006F39F4C858FADE91265C0BFE9BA75BC700 -:101CD000F582FE2BACEEFF0E6C89D42556814B3479 -:101CE000ADD0DB887824B4B8802F55FD4ECFCE55CB -:101CF000AD4E46BDB23BA701CF559D3D6C8C7B2FB1 -:101D000085FA94C98A2C8893E4AEFA77CC63B0EE56 -:101D1000E2E29EBF7BB7D8A29CBB5A91057117EB3C -:101D2000AA7EB982F69FFB184714333A9BCB027FF9 -:101D3000B6A003F95AB787DDCF58D765AF32A1BC3B -:101D400061FE2572AD03E588B0FA461DF009A18D4C -:101D50006AB1749D6F17B3787A41B7A80339F5AFAC -:101D60005FF271E35E4F1447CEE700B81A8DE1BE13 -:101D70002C67242F493D97A3FAA706E4CFAEB9E814 -:101D80009FBAFC3CF4F0ED98E7F86506C683A6DB45 -:101D9000983D420591723F516CFB41F713297A8BB4 -:101DA0006A176BE9409BD79D5F3104E982F2D1C08D -:101DB000263186EFC5CDEF6E1598DE4DD7615802FE -:101DC000F3A8CC72833FF152F3E9B5F6F4809EA3F9 -:101DD000E825EABCBF69FEB95ADF0079E771FC1F4C -:101DE000AA5ED3A19E33FF92DD1F3742B1278E76C4 -:101DF000FEBF12764FA79AE7E267E754F4947F227A -:101E0000FE84AE93010F76D9754DC5180F6BC27E57 -:101E100056B3DFFF18B12A6F4545193C45C25178CA -:101E20001FDDB76804C69B295D14C4A18BC5C5EC32 -:101E3000FE06617532E2B1B09660D6A660CF403C36 -:101E400016D6317C5DA4D0BD9A67A7C62DEF2CF6BF -:101E50001D2B4E8FBAA7A53589DDD3A2E4AB5B5B02 -:101E60000FBF04F79F3CADC4AD7BDF183D13E38982 -:101E7000AB050EECC3F3F6B923C07F7756E1DF560E -:101E8000A19F8896687AEDC5F38EB907D8392D41A0 -:101E9000C9AB15563BB6027E9A9D3E3CD7F99D8E46 -:101EA000208F795BE2F127A7496077840D906777EF -:101EB000AA4D08AFB0A3FE14E327D3FABD8810C023 -:101EC0003C22DD982BAB47A9DF256A2F8D49A83F1F -:101ED0007DABF322E46BFC53DF16AF13F9A72E7F23 -:101EE0001DDA7322CC3E216FB07CAC38EB8AF15FF7 -:101EF0005EF175A97E4B6D7EDD203A66FE0FD51E24 -:101F000052E325C423C7E4BFF7EAC520E83D904F5C -:101F1000FCAA1BF4EA1F9BA3F3DFAE1FA38BBDB784 -:101F200092F8CD701F429D723E9A08EE5510B7BDD3 -:101F30009FB776817DD70EE71240BF04F87251E754 -:101F4000333EB0629E46ABC0CE6F10999DFF5832B3 -:101F5000AFE5C7D07E495BA608F097AB5A7E8AE70B -:101F60003B74C4DB4E9F9F2BBF87A3CE473DAF90F2 -:101F7000487E0E3AAFF035E72DB2139CB758A0E07B -:101F8000BDEB2E82E72DC82ACF569857779B40206D -:101F90003E9D3A8D95470826FC7D2633E47DA7E1DA -:101FA000F958CCCF0E5378429EB919F2BED3E03C1B -:101FB0000CBBA7939B390DF12F95C207F482763D98 -:101FC000BB9753BEC582F8543D8DC55B53BD06E437 -:101FD0003FE7881BCF09C8707F9F03F06C05E2675D -:101FE000D89A81F1E2D47CA6479ABD069DC9897929 -:101FF000DD88AF614ECDEB667CAF7BAE84F9F60336 -:10200000F774CE23B83FAB0BA666C3EF920CB9C9E9 -:10201000C0417C499533550A7E746F55DA37B2F664 -:10202000708F27CC8F2C61ED07EEF1FC3EAB6F1566 -:102030004278AF14D561947B2459FD92D919483F59 -:10204000BC722E97DCA69C2BE0D83D644B660F61DA -:10205000F536C607C9DD498A3C57DADF9BEA57E205 -:1020600005EC7C40BD4EB9EFA08B44C79F553AD3D9 -:10207000FE3E4784CED8F9922722E704909EDBAF3C -:1020800017310F52BD87B4CA6260E7CE4CB17435C8 -:10209000694C2AC3FB0AB709C65DEBF4FC644C5CCF -:1020A0003F8D7F6E345F19A2F295BB0D1ABB2C9346 -:1020B000C1D5167E9A9D4F335E965D96380EFA7C9A -:1020C000766C1C744776741C54DDDFAA8506E42BFD -:1020D000DD76E92DC897DA44410BF73A6AD7BD6936 -:1020E000E07E76BF19F452AD3D7828415ED4E931E7 -:1020F0004C3F7427F0439C1E93C8CF9520AE5C6A7A -:10210000FC5F8A8F33FEDB9BE03CE200BC54BDC920 -:10211000A48D7BC897E5F7E935FD10F9A0A75D20F0 -:10212000E6EB6859737E8EF241E48BF20AA3D8EE97 -:10213000003EFA43E48BADD4723546F1456A8E5EBB -:102140000DFCB8F74117FEDED55B0FBAF179CECCA6 -:1021500005F8B1F00CCF018DE993970DDF83FBCD2E -:10216000CF59C33970BF794A207516DC577E2E3D92 -:102170007C04CAB69FDEC1CA05E1A7E1BEF3FC9F9D -:10218000FEF27B58061A1B42975B12FC9E5C0CF712 -:10219000EE8756F6837E5FA63977A0B97F19CEC742 -:1021A000C27A322D068C53672AE792C964C53F0470 -:1021B00099694077D9A598576821D2AE7EA81FC6E5 -:1021C000E42EAD6F83FB7DDB0B9C2C6E4E181F2025 -:1021D000C394BC131292C11FD5EEB463FB01FD6E14 -:1021E0009751C95B63E3BFF72ABB37493D6F4D8801 -:1021F000381CEC468B4462CAEA7DE6441087C3FD76 -:10220000C3ED6ABC5A291FC8F48D2A89B25FDE9BD0 -:10221000727F31ACF3E3DD0FE4833EF55DE577E2F9 -:10222000B478F5D7B14C8EAC48FEDB1CE0E3EFF39D -:102230003637F80F9666FACAA0BF798EB6F1768A5D -:102240003F93C54AFC3DAA89F26C0EF88AFD6636BA -:102250003FFB642F37AF38F23B55E93E01FDF4C434 -:10226000D7CD83BE9D7EDC2B027C1A4CE11C81F60F -:10227000F381C33709FA3D3FF7C3FB308F70C87B4A -:1022800047E05ED4F7F45DD536C027A7720F36114C -:10229000F01C50DFD0113DCAEF6DB1F340059C1228 -:1022A000870D4E06B9700361780B65A8BF51B987D9 -:1022B0006EAAC8EE8D9D5AE6C4DF4F9C41C202E073 -:1022C000C3D4F7BD3602F471B3AF2CDE3D1BEA93E5 -:1022D00064E9A568FAB95E8A2A13C8B7882DFF9306 -:1022E0003BB6FCCF155F8E8C2ED7089E3B60DDAFD2 -:1022F000734CFEC81398FC11496005C8C7175AC42F -:102300007118577770329447BF3604F3A84816CB3C -:10231000BF1865CBF53338E46D867585A99CEF71E0 -:10232000C0EFB0B1FBC532DE376C85FB2088246D71 -:10233000063ADCAD77619E6986A5F6676DA8CF5831 -:102340004901F2296933E2B5D524C1EF961CB4B234 -:10235000FC89F6B53A8C37713693CE43BFE37B04E4 -:1023600026FFAD0BABA19E2FA71B426575AF9DFD50 -:10237000AE5BFB78A25F510AFBE67E1FF522AB093C -:10238000CF274CB6B9EE807ADE66C0FB2B0E5ACB57 -:102390007DCA7804FA7FCEBA10DB038FD653FAEDEC -:1023A0003533FF3A4FEDE3156C7CFCFD46FE1EA273 -:1023B0008C6F220628D7123C6FD06B17D97CEFD5D3 -:1023C000613C04EAAFC3F999B05EBDCF3272BEB7CB -:1023D00052C0DF21E088121F6BC3F2530A1F6CD773 -:1023E0008B07014FE58F0881FD986CBB8074C0EBB3 -:1023F0006C6EBC1FC843F21D1984F92CE8F77C866B -:102400001884FC7BFE1E1BDACDA0F940FD50F813AA -:10241000E95AF09072C53583E3798E021E8FE08809 -:1024200017F6E354492EF2A36775EF6DC0FC0A8BD3 -:10243000D7E8A6E3186E23B8BFEEE4F8E77AF7967C -:10244000303A1DBC7FE55990C7C1D92A2478B65BC4 -:102450002B2438A7D46B776779A3CA71F6C50F7898 -:1024600013D91753505702FBE19640BFF8FAFE68A4 -:10247000BD05D623E1BCF8216E09ECD07C1BED87AD -:10248000F27D775AFC759C52D61150EE2DD4D6FFB2 -:10249000BE4477A5D7A9C1BF6FB9CE8CD8755EC130 -:1024A0007986B82B304F3E87CECF12991FFD13EFA0 -:1024B00051BBC1A243FCBA41BD1FCA157B4E447B30 -:1024C0002E8490E51B81CF7C57C977AD4AFE17F467 -:1024D000E35F4FF57C906B7DC93FCC877CD3A92906 -:1024E0006D1D8C385ACECC037E6CE290EFDC4882B6 -:1024F0002BE1FDB94ADF33F63CE4FB7F2B190FF7E4 -:10250000E9FA46A6D2F2C7FAAEFCC54EE48B1781B3 -:102510002F5A4818E9EE06F8BD46A0BBE9FE0E2882 -:10252000D3315AF09E304A8740B72A1D0E9E3FA5F0 -:102530004BFAFDD0161B9EDFDA428278002F8B7497 -:1025400071CCDFD282728B48C323EBA4443BD5D439 -:1025500082EBF8799B8CF2E1BBF6270528DF5CEA79 -:10256000738CA5F39A35F613FCBD0792357724D802 -:102570009D74BEE963FF81F31D7CAEFEABF3C8FE24 -:102580005EF6E884B1B1F6A823E96F9807277136A3 -:1025900037A1FAE3807DAA37615E42E41C72B80E6F -:1025A000CF3B73295E9067EA39642DDF9D741DE38C -:1025B000BB1F2FB6B957E03D923BD02E6DBED9A2BE -:1025C0009E5346FDAB79A14E39A7CCA15C6922266A -:1025D000BC2769E0F72CE93F2E23F2BB34FBE0BCBB -:1025E00072D9579D5796F03CB4BC9CC5E907ECBB2B -:1025F0004691D9AFEAEF9BDC9BABFE0E05D3531699 -:10260000934BB26FE39C6346BD91A4E814FB95E93C -:102610000BDD13245126185F657AF86C03D6AF4F93 -:10262000F2E3EF05D5F15D88240D63EDCAFD0F7E61 -:1026300033FEAE98C15D087C428DB3EECEF7358F88 -:10264000A5FB34AFD893C3D1A5D41958FC94D2C1FB -:10265000E67EDA6A1A69790E7E6FEE7AD2F25B5DF7 -:102660001ED2C1BDF0FDACD19FB0DFA18BD0C17D2A -:10267000400726C2FC01372871A2D73FDEDE01FBEE -:102680007E8E23EC3C9A4B7B1ECDFBC3B12C9EA5CA -:10269000FC9E542CDF899AC7713D9B8783E7711E8E -:1026A0002BE3CD63101D123F8E4FF7B705CFCB6BD9 -:1026B000F0483B1F6EFFFD789E6FF3ED44E42780EA -:1026C0001CEF37033C870146E4C13A7DEB609DD99E -:1026D0009062099354ECEA41F3E62DB8AFB7CE1EF1 -:1026E000C8D399915D0E712236EE53C94DEBC0EF00 -:1026F000D17CBB1EF97BCDFE31A8A7F5C94611924E -:1027000020C964965FE3A6FF8379CD229E2976DAFD -:10271000CF4D620DDE0B77F3746D5E8EFC500B6D4A -:102720007F8B92E773EBCDFAA3D1FAE639FDA37A5A -:1027300080835C6769E127427F42A4BD73305C06F9 -:10274000DD4BD5C1F813A17A0EF4DF5E1140FE9483 -:10275000884FED1D3B709FDCC86F98EF73702CE2C3 -:10276000ED57E7FB6C57EEB17A4B1FC6FB51DF4EBE -:102770005FB079315DE7C81F15E3EF1B4FC9A87F34 -:102780006E2D2DFF78D3282CBF9D71FBD2F7A0FEB4 -:10279000E9422C4FD67D3207E8C1553EFB06F85D75 -:1027A000E8B7CCAC9FAC245F770DFD2EAB24771C33 -:1027B0005C6033D910C6EF6E1CDB7815F8632627F2 -:1027C000B1F2A1D23F8CC372AE521EF7FA2828BFD5 -:1027D000C57D32271E5F1CEDE2824554DE4E4E65FC -:1027E000DF4F1FF7FC10B0E32757B1F26877E5EA37 -:1027F0003CA8D77D3A279EBE7456E1AB93BE38D72E -:1028000091E680B030FBBDE2D73C1FE2EFCB78A968 -:10281000BC85FB06BC152C0EE7F5940AF07B6655CB -:102820001E56AEB6B465031F9CE1339441DC55B42B -:10283000383B44DA2EA5A2723CEC7B3555B721CE4D -:1028400049E9EB53A4AFAB3FC9B1A15EAAD297A8A7 -:10285000477A4F7CAFE4E76CDF62E981F6F705CA9F -:10286000CF6B62E5E7207AD5E0E1FF008B7F42C5C0 -:1028700000800000000000001F8B08000000000026 -:10288000000BED7D0B785445D2769F3973CB7D429A -:102890004248088409F74BC01912205C1D02645994 -:1028A000050C171514E1041002B98DE0EEA2EB9AA5 -:1028B0000901441777E38ACA2AE88080A0C80E0A73 -:1028C000C86A644764237EBA1AAFEBED631345E52B -:1028D0004E0CA2B89FFFFAD75B7D0E99338405BFDB -:1028E000CBF3ECF7FC3F3E3E9D3ADDE77475557542 -:1028F00055757575CF55CE4EE15FE60921FC891EF1 -:10290000473E95BD6D271A7B0BFEF74357592A6941 -:10291000427410FABF9521457413A2930870B95EF2 -:10292000D42A421562B2558BF70C12C26E6970E35D -:102930007917C5D3D745CF45BEC759D41F2F764A7F -:10294000FEA29F4053F1C395429CB67D922D5285C5 -:1029500008D00375383DF489EEA9D48F82A66ED9CC -:102960009595E04CA35FA1B85C69E857D62B757FBD -:10297000E5F7D739E8FD0CEEBF93A73DF093F8AC2F -:1029800057FC5CBA84F6B8A0F155A40BD73D5EBCE9 -:10299000DCB8324CEFA5D388EFF110B8D73CDE9A03 -:1029A0007CCFA264F5427C2DCEE65961FACE3491FB -:1029B000E851E9FDF79616B5F712B2D709BF0DE356 -:1029C0007D282E31904CCF2BE724041DF47C670723 -:1029D0006D00E8A15A022F36127CB3F0D9D16EB245 -:1029E000D577059EC70BF9BD0AFADE3D289D448FB9 -:1029F0003C898723A30D7A44E1193DFE56BE346419 -:102A0000A0CC107E86D3856795DAC67884D57F778B -:102A100023BDFF0B35A1F61E2A1FB2FA2C1BA8FFFF -:102A2000C0EBB6E06685C72380CFD24F12363AB2EC -:102A3000A9B40A8685C7C1F54B6E26FCE9BD254AB7 -:102A4000962740CF6B12FC8FE17BCDD556B1311567 -:102A5000DFF76D00FC7A757781F1458F27BDF6A70A -:102A6000424BA17AC5FF04DA05AA1DAECDD4EEDB38 -:102A7000D87FCCDDC874482AB265111C3369432362 -:102A8000C18ADDE9528869E973D2595ED7DE427C9A -:102A900020FE050A42DDE603EF475551E38AA40311 -:102AA0006192DD2A9FEB3D44B4F69063831E0105DD -:102AB0007269B728B38BE28926F877656BB9DE6354 -:102AC0001182F8D43DBFA30FE35EE2151EC80FD1FB -:102AD0004101DDC55E45A703C913EA15973FE0BA7A -:102AE000904F4B1BB36F45FD7E0BE14B6501F12B06 -:102AF00005EFC7A9F27DC5D32199FA2F4812FE1020 -:102B0000954B62DCB746D275B8C532BB28477ECF3D -:102B100049F49BADCF0603CF396B55A1E50A31C609 -:102B200039F7B1C3B9C0775887A28488FA7BFAE431 -:102B3000CCA1F75FB689E9F8BE677FEF9CE21C1E67 -:102B4000872F94C37C5C1102FEA3D33D010FF06B71 -:102B50005EE1017EAA68DEEC011E014716F089C91C -:102B6000F40404F0AC15B7E545E01F43F803BF3BA0 -:102B7000C6F922C76DE07D313CA3E97D313C2139A6 -:102B8000CEC154AFCBCD1C675C933200A51A7690B2 -:102B9000888A55D4AF33525F45C9B90830DF272E34 -:102BA0001D537498E42DD54E8F20A7B725043712F6 -:102BB000FE136F1BCDCF9529E7589EDBD17C745057 -:102BC0003966BC5B69243CDAE5BD6515FD21A78447 -:102BD00017F0B1360E9A4CF43DD6557B12FAC6C0AA -:102BE000FF2F839EF06A547FC8224A4239178E6FA6 -:102BF000B72E4F2ED16887DC5538E3C3EA800BE54A -:102C0000E562F8BFD8A1E839E88D934AC36054560D -:102C1000F676F17321B46C7C2FD9953D3A197AE29E -:102C20007BEA6F30F414FDA379D0B7BBF627BC77ED -:102C3000BD281A67A5F1B61BAFD9341AD738359E0F -:102C4000E773CB7685F5D5585F8C0574A93C680B86 -:102C500006095EFCAACA745ABC5E0D62D2B608CFE1 -:102C60005ACCC39680C305B97C286EC06F4750F913 -:102C7000D97A9BC7817E03BEB77B53BFF3743EF501 -:102C80005A6B116E832FF47F9F60AC70F76E85FBDB -:102C90006D6D6782FB873A9ADA5FB1B7ABA9DE1B2D -:102CA000EE6BAACF3D38D0040F6A18666A3FE48302 -:102CB00002133CB4F12A53FBE147A698E091CD37CB -:102CC00098DA5F796E8EA9BE34B1B07E298DB73E99 -:102CD0005D150AD9C9D1A2D4D4BE542DB30B62B1AB -:102CE000A8B57D0A79F4D37FCC4F75A615743EBB89 -:102CF000571129A48F16AC95F5C67B2575F7AD84C1 -:102D00008D5B18343F2F15D65618FAF793856F1E32 -:102D100088E8AF576AB12599CABF7B1252212F624A -:102D20008818F283CA7CF540DFB4BCAB7A1C42370A -:102D3000A5042F7E5A09DE437CEC297A3C04BE119F -:102D40009F45D00DBECAFA96756A3040FD7C5B5532 -:102D5000F2E6011BC10773D7422F2F20BD0CBDE542 -:102D60004837F333C66DE6675C6F333F133C667ECE -:102D700026E59BF999EC33F33365BC999FED8BCC39 -:102D8000FCEC30DDCCCF0CCDCCCFCC12333F3BFBB9 -:102D9000CDFCECB2D4CCCFECC022537DB4FC765B3E -:102DA000B5D854FF50DCBE2F34A2436A47D5E5A006 -:102DB000A9D7A3F676D3F7843AC1BE82E8559AA97B -:102DC0000AD5D52A0701FA4FCE6B3FCFAFF92407BA -:102DD0000F131FCE8AD5F599EE0BE5A162EF7D7634 -:102DE000CCCF1F2B0FC3BD663920B94BD2DAB06BE5 -:102DF0004669F099FC91D15ED20FD3BCDA582FE925 -:102E000093E9BDBECAB292DE1045C5BD60472EC76C -:102E10004FB10EFE117ECAA410DBE38BFA29EECE71 -:102E2000ADFA8F9DBF80057AF9C3793696DF65715B -:102E300003B6432E3FA8917279064D860A71830826 -:102E4000B11FF661EC239DD15F01115C198ACADACA -:102E50009B80FF4CE04FF6EC26D168C3C7C98EDAE1 -:102E600051160B37977375FFEC66115E89C17C9222 -:102E7000AACD075D2A54AD4B1AE8D1A9218BFDD804 -:102E8000D75380F445E96AE8EB77F027B57BC45B5C -:102E90005481EF8C71BA6F7DC00D3F80EC03F1451A -:102EA0004C4861BC85B5A8FF94FE6D7D6719DB8B2E -:102EB00017144D03BD03194E0FECAD480F3DA3D0C1 -:102EC000F8FAB6730FBC27B9B5FDAFBC867D21C734 -:102ED00086DA3FB92B96E9D5AFC3867618D78FED42 -:102EE000F76EAF6F39F036DA5F6ABC76BB67D1CF69 -:102EF000A8DF6645F8371212EFEA7CC974483F3103 -:102F0000534DF4D4806F71B3EADB131D6EEDA0FD59 -:102F10000EDF9F7EFD4F570256F6A7B817137EA708 -:102F20008B1B07035FA2FF83A82F7312FD6968271D -:102F30003B6BBD9220144592FEF447FFA236F197F9 -:102F4000F81CD0E9FF6207ED31C8F57E4B439607C8 -:102F50007CB4360C663EBAE4B84EDA255D2E468760 -:102F600082B8CE3341FF790E8747257A1628F2BB07 -:102F7000879366CFAA24BC6FB614A5855513DE4F80 -:102F8000A3BFB2F8E22E19C0DBA6E3ED6CAFD3DD30 -:102F90009D13E99F45E35D83EFC31FFE15F997D9A4 -:102FA000781EDE06F839E1E2F58BC322ED7273B5C7 -:102FB00012DC48F56FEA745E6FA37698974ED1AE37 -:102FC0009AF0BB66E48A0D68F76BCDC9786F169EE0 -:102FD000BE6BB2C10FC1FA3EF32E2558930DBFCA86 -:102FE000C3723F4F1465EDA276AF79B57AE0FFB7B3 -:102FF000B87F0CCAB6F0341EF42E7D67CFB20E9E99 -:103000007B008DB83CF9EF4D9A03FD4F9928EDCE2A -:10301000CD3ADDA689229EA7C6BA8926FCC90A6ACE -:10302000379DFEE2F59870F7077E33007B5BE7F58E -:103030004CD1C0E52CE1E2F5D4DBD51D7E761BB585 -:10304000996269CEB2AB98A7346FB399FEFF0EB9FF -:10305000F966DC5B8714D0FD0ED263E0F79AF69731 -:1030600025C79315494F9AB79FEBF3360F53EBFCE7 -:10307000FC19DB5ECA9FD5D5E39FCD1F528C891901 -:10308000E4AFFF44AA42F1D09944914AE36CE8AA24 -:1030900006B19E1AA7DE61DD45E36C207FC2817117 -:1030A000FB8A3B9EA6FAF1646FEF91FA352140F05E -:1030B000249F2AEE6139685CBE909EBF9E4FF5D476 -:1030C000FE956A919047F02B5E9BA786E470DC39F1 -:1030D000ED4012959348EF87A9F555E9F78D857F67 -:1030E00030BE13D991083B715577334C13A113F8B7 -:1030F00074B54EEF093966BB330976C768DF86DDE4 -:1031000021FDAA82BE710375FBD357F485FD79B901 -:103110006AAFF88CEC8B6187C608B9DEB8981DB22F -:10312000DA0B5206B23FEBB6637ECCC1FA04F476FA -:10313000691D2747CC97D2210AF3C94D86C742E3C0 -:103140007FF3A01A047DACBEF070D06FF18B0ACB78 -:10315000E9D503B5AC81C48753B6C6F9909B8611F7 -:10316000B94982FAFFB48A10E945F3B7CA297C3419 -:1031700017BEA872317CA42A9DCB63556E2E4F5486 -:10318000F5E6FA53551E86CB0716F5027E73567D7B -:1031900065859FEF167EF68F96D07A17FC5A92B00F -:1031A00058C236A70B4AF8AECEF5963882EF0A2AF7 -:1031B0001ED8C585BB822BE308AFD23A9F3D9EE067 -:1031C000259DDB8D8947FB071496FAF907FDF51855 -:1031D000EEA9773FBD6EA2681D6FF93985D7C9EF9B -:1031E0000FF20D46FF5F56E5335E47AB7C8C97AF21 -:1031F000AEA93E85BE77BC6A3CC3770D2C1A81719F -:10320000FBC457EC474CDCDE64859F31CEA7F8C089 -:10321000E7513E110C12BDD6DAA45D594B76057A02 -:103220006074FF29EB6F15D0FB5A21DEBFB6DDDCE1 -:1032300071F05727E517B3FF7AFDF782FD5743FE7C -:103240002F358FDCA2E15426F5773220E9D3B2EB9B -:103250001D865BAC441F1AF1BE5DA5A582FC83965A -:10326000736FCBE7D48EFDD4DDB2DD629B6CB77893 -:10327000F7AFDBF9002BA25944ACB78E131F85239F -:10328000027EFA17E95A847C1D6F17FAE623E8C913 -:103290007FB77836B29C6A9F3D0F3DBADCC57AE6AF -:1032A000942DF4C5C3D0B39DC9AE72BD3F6E0AC99B -:1032B00059855D682C7742EB07F878ACE0F800FAA6 -:1032C00073F792CF218F3D773CD4F597EED6FEB6BB -:1032D0003CFDFB96E7DDA80FF2FCDFB6637DC74738 -:1032E000082ADBB92216787D76EF7399185F2F557F -:1032F000F8559A67737FF3C7CC3F52FF4F906E41EA -:103300001CE3059BE7D45EE0B39EF0A1EF3C716F38 -:10331000F940E8B779BF5BD817EF07065A98AE4F68 -:103320003DB793ED3FC998670CE9A9FE6B5E5A96CD -:1033300041EDAF58D764E948A577935283B274FB47 -:10334000CEB7ABA9BF5C97C50F7F74C54037BF3FF1 -:1033500030B461A302BDFEFDE31D31CF72D67C55B2 -:10336000D0515CDC6F782AEB8396621E572D8F6BF1 -:1033700077DDD4776E14F04BC82301BEC5760FDB22 -:10338000291AB60DFCDED56D03DEDF6309B0FD0939 -:10339000CC917ECBC9A2C0EF31FE726A1F20B8DC8F -:1033A000DBD0741BD597277715883B1C092E998194 -:1033B0007A9ADE2ED0A762D703851D093E3942785E -:1033C00014EABF64F79942B66F9DC9F7C6F776D580 -:1033D000A4DD00FB96533048A5FA2235C4FD894A86 -:1033E000D95F65DD4EA7E0F5BC68A792224CAE1B05 -:1033F000FD7266047F2C8DBFC9B6D2F7DA937D04C7 -:10340000BE6BB30319FEF8567BFA9AB7680BEB2331 -:10341000D7FDC5F8CEE78417FCADCBB57F768B7FA3 -:1034200021E3932E5C81A1ADDFED6C092FC43848F8 -:10343000DA5D01FACE6657C30C6E47F06FB95F6D67 -:103440000FE65FA64A544F95F6BA06FDBAA6668106 -:103450005F97DBFF4371FF60BFABD292E871E4B5C9 -:10346000FA2DD3536A5E6C247E6DE8A0EDC7F88C0C -:10347000B8A4B07ADCD0E3810EBE97F1BCCC49761B -:10348000D5C2F6F415C0861F7CDE0F735E9E3DDD4F -:10349000D9C1F717A6E365B677EB7186F37AF5EC39 -:1034A00040935EAD49B00B2F3DAF59E3E0B884388F -:1034B0006029ABA7F5C7487CC2D2FABD2509033BFA -:1034C00040DFD708D126BDF6D17CD688B661B203DD -:1034D0001ACDEB51E79A558DE77DC3CB4979D09F43 -:1034E000C297E0461CC022B4087B17FD1DE2D70935 -:1034F000F06BB488135A84DDF489643BE6AD886FC1 -:103500007799E30E3F6EB627FB1F8F1CF788960F47 -:10351000E2E052113D3AA0BCD8B85ED4C7F5278C82 -:103520008BCA79438AFE01FC467EEDB2627C23ADF4 -:1035300093B3BC5D196F6B2EF53BEA6B8B19EFEF04 -:10354000634DF0E5E2FF3385166A90E3AFEC1C179C -:10355000AC83EDA771D42DCC0962BEEFB18B801383 -:10356000EB982976F66BEB1202097D51AFB84288D1 -:1035700027BD606B9821D739C2B5D90BF97DE3110E -:10358000C8FF0D2D7605F1A98E0EF105FC25A126AB -:1035900089CDA911DF6FEFE2B885EACC5C8FB86204 -:1035A000DD50FDF90C3B3FAFB109B67B8119B18C01 -:1035B000D79A64FF6BFDA97E4DB58C677E2082ABE8 -:1035C000BAA2FE0E95EDC070CBC6CD0F621D333989 -:1035D0009DEDC69AE4706625DA2FECEB09903CEC81 -:1035E000F987CAF6608DD797D12E1E7A50C605D7B7 -:1035F0004CF665C4A6A24CB360BC1D49CFF3F36C76 -:103600006A47E54736D9EE439D6F44E90CE8DB870E -:10361000E7F510D03F57E7168CCC65FF47C63BAFA8 -:10362000952C10336E7E80E3AD0F6B6A50CD065D36 -:103630007E736F4F826F98A3BA1077BBB62486E370 -:10364000A1D76A7A3C749A390E7B75AE6F642EF1FD -:10365000BF3CD4A7DBE108399E71738F9F433F7C49 -:103660002A645CFAD769DA38B4137BBDDC6E2F3973 -:103670002B3FC04E38DD03D87F9E67AC1BC3734120 -:10368000DF7DCD4EF64B2F260F42789C7DE9FB0F58 -:103690005A4408F2DC05FC4961B90DC06F0B846225 -:1036A000580EC64F71727CBD25DEC2FB0C8F11BF58 -:1036B00060DF02BBE53E03294AE6DF83FB3AB35DE8 -:1036C0009AADEBB19AE9B1FC5ECD4E5BD0023E2BD8 -:1036D000C16D5BF0DE8B316C3FCBF4386FD9F3FDFD -:1036E000580EF6D87DD92BD0EF3E07F3B92CD19DDB -:1036F000C4F5FF962250FF821E772E8B0DF7443CB7 -:10370000BB5B7B6D3EE84172C771F932BB7C7E28A2 -:1037100058C0FB1A82FC95B851040B1FEF4F04C828 -:10372000AFD9EC91FC035E5A4DE78DC057233CC0E6 -:103730006771BB8C971FA2B98CF11DF27766BC94A0 -:1037400029E3336EA6FACF16C7711CF55051FD5907 -:10375000F80187D2559EF7A4A1EE1D42F564731BB4 -:10376000EE21B872E1A76F0CA1A715351F66ED75A4 -:10377000B7D27DE6B2F20982E460E6A23B2689C4B4 -:103780008BCFD799650EAC115BE7B7B063B12661FB -:10379000D2EB6B727D3590C350AEB612E3AFCC2145 -:1037A000FF99E4E894BDE151C4498EBAB5BB517F9D -:1037B000FA8F5F6EC173616DEEC9F2E16C2C449CAF -:1037C000A5CC22E344A3F3B4DFE6B29D4D64FE55DD -:1037D000861CCCBFB89C06A917EFB83C7B70AC6EBA -:1037E000F31E85FA298DADABE0520D0E80BD3AAEC9 -:1037F0008413956E4C5F0DF3EA842B9C08FE6816CB -:10380000E9BF956E8D1EA7DC4F2CC51FBCEE0CD9F1 -:1038100087135E8B48F53EECC2737B6BFBEC563E28 -:10382000D277988F22FE9359BF44FB6D7D06DE430D -:10383000742F4DDEFB9BE1D917D22F1A36C67321A8 -:103840003EFA3C290A27629E1C57E43C3921A4FE1B -:103850000A6C8DD1D7FF128F537FECC078A4E9F3A7 -:10386000E894A2B7DBE690ED48F6E0CF94FE41CABB -:10387000DD8336CF5AB9AF66657D599A22E152474A -:10388000BA0BFE5647356089855C56099E2F841B0E -:10389000CFCBE33B32F97D43AF892221A0D74A77D2 -:1038A000646C947E9DBE0EC600A8FDA2A7647F80B6 -:1038B000A1FF8F3D99A9F72FE753345FA3E9F07E6D -:1038C000AE8C5BD5240CEEF0CFE295BDD33F5E0706 -:1038D00015F4A04DCEEB4082B423E4B7A44FEE8F95 -:1038E000FD06BBE9BBA712ECB37DF1D877303F37BB -:1038F000BEF769AE5C477689E27B47B5F925F84BA0 -:10390000E271C17A221A8FA3788FF07DF2C9F37C1D -:103910005625DF49900CF97233FD840DFCF9D06E09 -:10392000F0F1D64CD2EBA5A055D7563AEEF16A99F4 -:10393000B023A7F47DA33DC904E7C0DF92F6C3809E -:103940000D7E44CBE9B20FE767629F2A2D4FAE0F81 -:103950006A6212078824945941E8816AA22BEAC955 -:103960000EF27EDCB1AAF1F71FB6B58EE78B2A9F67 -:103970008F4CD07978FE5AAF13F373C13AAF734EC0 -:10398000043F6AB6E61E7413DD4F6CB562274BD454 -:103990005883BF19968AE76A2820B8DE097A9F887B -:1039A000DFFF06DACD5F973C508DD04F0BD68EF3FC -:1039B000CD8BE043BFAD66BEF40F99E12BF69A6163 -:1039C000377832E8C7BFE70D9BE1DC8366F8B9FCC6 -:1039D00066F507D8A7784BD0A9A06C517F807E0FE1 -:1039E000AA41AC33BADC51347522C147D6CDF5803B -:1039F000CD0BDE5B3618FC3BB9FBAE3DE5F4DE914A -:103A000076160FD657C745E8FD89C48FF975F7D9E3 -:103A1000AD6E8CD72CE77B2CBADC3E29E37A0B8386 -:103A2000E6FA0BF543B51E4712BD23E52A9AFFD4EB -:103A3000EF753E42AC6CE9D4FBE1FF944C2081274A -:103A4000FC8686EEB38BF8CBE927C072634D14E198 -:103A500074C2AFE9AE048EA70C5B3A467C46DF2BFE -:103A6000B7BA0663BF7D8E5371617FDB889337EDF4 -:103A7000CCA8803DDDECB278904CE1CAF7D767E680 -:103A8000613D21422E0FE2F477AEC43ABEC49FC816 -:103A9000F45928821C679FB3DCD1AA1FE9FF79ABD8 -:103AA000A3F05913514FE32859676EBF68D30F8EA7 -:103AB00048D858970EABDBA062BC37EB78AB0199C6 -:103AC00037304C8F3F1C4653B2377FEB56549C87A0 -:103AD000F66B46CB7AAB53B7B33E5EE795C7DBDDFB -:103AE000ACCFAC6FADE4FD1A9A87B00F0713E6FFB9 -:103AF0001CFAEE8C53B81C9C47A231FC458A5C171B -:103B0000F23E04B53FB34E61BB5E9E22E1F2C79523 -:103B10002062BAE508C2027E42C65DCB747A404E8E -:103B20007C11E301BF2261516BC4BBC3BCFEADF08D -:103B30000B0FFC00417CF499F6BDC3F623B0B30132 -:103B400025F4B017FE9EF93B957B7F7044C2E7E3F6 -:103B5000C5C4BA6AFE7E90E9A8DA850F7A5CBD33E7 -:103B600096FD763200B1B0EF36DDBF16AB82ED6167 -:103B7000AFD6C05E51B942F7C303F7497BB526D92A -:103B8000D7D385FAFB323CA0C30D8ABEBE855F9FAA -:103B90000CFF7A3FF7DBACB85C1B93D15E0462523A -:103BA000D9BF96EB847FA86CEF9AC97FC7FEFC1A39 -:103BB0006F280C7CD63C90CDFEFA0B86DDBB3746D9 -:103BC000FAF317FADDEC5F89FBA5FFF891E0BEC5BB -:103BD0009EEEDA863C92F3B96A116F2ECD5BE6CB8E -:103BE000C077E74DB15BC00F517279FB1C9BF53C70 -:103BF00098661A2FE2EF8795A27A4B841FFC4C9EA1 -:103C0000B40F830B7C5BF4761EB49B67798BE93031 -:103C1000CF225C58CF6F3EA70A2BC19B6B1DC1659D -:103C2000F4CABCAEBE9E8B73F09E8C371DF24A7DEB -:103C30001F97277C41E87FFDBB2FE4594CA5182B2B -:103C4000E32C8763A41CCE1445851CEF770B53FE31 -:103C50008551BE9227EDDE3C7B83199F4F5E66BE89 -:103C600090CD732D837C8F957EC7E15B14B6E734CE -:103C70009E9E2E8207FF2E86E38587757B64D097F4 -:103C8000E487F3220CBD95ACCBCB9ABB83DB628877 -:103C9000DEF7D9486EC037921BE4F910DFD92F5CEC -:103CA00033238DF97E83CE57716F02F36DB8C52231 -:103CB000E97C6F06D399DA8BBFE3BD716EE9CF5F04 -:103CC000E63A8CF8FE37F03D7A3D66F05B58838328 -:103CD000FED97E4CF9734FEF0990FC2FFAC303898C -:103CE00082DA1DB5D6A679E8FDB2CD2B127D541E21 -:103CF000B106125DD4FFD1A03A3ED806BD3B0F52AB -:103D0000F4F5902F11797415BA1E3FF6E47FACBC20 -:103D10009DF0FC4611CDD08F15BBBE5B793B8DAFBE -:103D2000DEE76C863E3D626D2C84DE5D581CEFAF95 -:103D3000F660FE9AE3F28B9E7820CDCDF40E645AA5 -:103D4000D279FE67E2BD8A4D360FD67515EFAA1EF1 -:103D500037E6BD685E09FCA2DFAF0C7D6607FD5D3E -:103D600016D1DC69781BF5A291F57CE5AE5F7FA5E5 -:103D700026A23CFA11D6179551FB0125FA7E49F48B -:103D8000BE40C2A084D42F10F0D6F7A3893E9C97E2 -:103D90001020BC7AB0B8C83872CDB6870634C16F6F -:103DA000D8F45AA292D3BA1F60ECA3B484E63E863C -:103DB000B8EAC5E6E5A9A838B0A1C7DC7B1599B477 -:103DC0005827CB325B3811FE7ED9061BEB91B2A788 -:103DD0001FDFF230E4ED4387A7871BF0193BF44166 -:103DE00099E26B5658BF8B4465702BBF4A9FFEBC4F -:103DF000F011F8D719AA9840FC5AF4EC59D9DE27EB -:103E00009A63A87DE9CEA642AC0FCAB478BFB30DC1 -:103E10007E8D09BD646F8C6F835FA1A6428E536D4A -:103E2000FB96F971749F223A645FF87EC986CFEDE4 -:103E300042AE0F9A539225BD60EF2A436AB13DE925 -:103E4000C2F6F4FD49CFE771BD0BEB954BF1F124C0 -:103E500068C1F29E2090C758F291233801FCDDB171 -:103E60002411F94F5F5AFD52EED7AF48839F576236 -:103E70000BA4B9B894CF4B1EFD19CBE302C59FE646 -:103E8000E2BC2DD2AFF93CDE0C8CF3E675D7F238EC -:103E9000E70B8DE5B164BD5A14A4F2AC558CDFD9A3 -:103EA000C6BC796890D4770E71CB00CC93B3F4255F -:103EB000D8F12FF5757DE06DB99E7688294991FB83 -:103EC000432583A45E0C88E021D881CA061BC7293C -:103ED000D4B7CE16E23BB7665BFDC8DFA0F107742E -:103EE0007A293FC8F58B1B790C95F88BECE998B7CC -:103EF000C67568CCC1F75BEC3751BF5F639DE83195 -:103F0000BDC774FB72A32356B982CAB4B6F3BEEA26 -:103F1000CFCF7FF1B68890A7CAAD5FB23C89745508 -:103F200024A54B18FB11AE39F1FE24A2DBD7EF7E9E -:103F30006647FC3B906A113D806FC3E70C0B4F7BDB -:103F400037DA1BDFAFDCEB10E1C879BBE9F3A87906 -:103F50006DAE17C2CFF4AC14496ED8EF2FEDCD85FE -:103F60002FA01FEA7733F5339FFCAFB0C9BF6A2E8D -:103F70007C04FA64AFDDC5F107F23FC31172737EB2 -:103F8000BF53DFE75BA0EB83683A44EB87FBA2F407 -:103F900083F1BE58D7F6FE52AB5E08303DCB6C22A3 -:103FA000003FA3EC4307DB8FB2A7E57C14A44F7B53 -:103FB000D0FC38BEFDE5F76FC07A36644B9DC0BDBE -:103FC0009AF56FC9339FF3B8E612FD633CD0BFDFAB -:103FD000DAB1FE4D1F239A1D84FFF1D55E3BE4FE4E -:103FE00082794CCFDB9CC7AB15D66FFF55BD4BF428 -:103FF000E6FCC04BCDD70517D1BB7551743D2B7274 -:1040000092905E2D5CC55D78FF208ABE065DA3F5AB -:10401000E8B441EE36F528FD7B5F44D051884696E2 -:10402000E36F482F625FAD62D3776CD788ACCDC8A1 -:1040300027AF087EC5F00AD835865F9A8678E58571 -:10404000E336D333BAFE4EC818FD5FF4471BFB05B9 -:104050006575326F91DEE3754725E2F5DCBAB63E51 -:104060003335120E46C1A1A8F6BE28B828AABD163F -:1040700005FB4DEDCBF6BECCEB2CC2DBD4CEB1F4C0 -:104080006A5E875CE85704791C95BBBEB207201FA7 -:104090009D9AEDD08BB665229040EF37BFA8B2DF76 -:1040A0007BDADD9C083F65458CF4E34EBB7438D960 -:1040B00080C5EC62C2E37460800B7902CD3132DEE0 -:1040C00072BAA839313962DDDE54A726BAA97D63F8 -:1040D000508C6F3BCFA586E753A3B858BDF4E7C615 -:1040E000A9DFEF90F99F5681FCD8C6EA6F77209E32 -:1040F0007498D64FF05FE6555F9F88FD97D375DDC6 -:10410000AE998E75E0ABAA9069D63E3BF220E64AA6 -:10411000568A2322F0E0081A9F9A9057FF02D6573A -:104120002428D8FF9CB73ACABF11454961ACA7D72C -:1041300044E72B04EDF06F16909D853E2A5967AE3B -:104140005F54779CE7CBA2A8F9A2E971E3E8F9D222 -:1041500075B09EB7E0155E3D7F92F3F44E1F545943 -:10416000BE5A96DBC4CA5499278BFC92963A997F23 -:10417000D3B257C222A0E7F5E8F3D6A0DB09CCA75B -:104180005E17F75B4EECFEF7C1BF84FCECF97800DC -:10419000F6894FECF9B0E70B809FFB6BD6C7E2C204 -:1041A000F663F67D378BF1DAE710C0EBF4BE57B259 -:1041B000E06F9C7EDEC1F905A79739D85F0FEC4B05 -:1041C000E0B8C5E9CED21FAE79F1DB018D6C8F97D7 -:1041D000331F270EB64BBFAAEE3FD83EB6D439DC0C -:1041E0001847E5BE389E5795CFC7F0BEDAE917BF2E -:1041F0001D1C198FFBAF8EC7D8573F9D20A63F03CC -:10420000F9D5FDFFCA17863E5E8DF5F2AE97EC73C9 -:104210009127F2A7FF3300FAF5F4332FB1FE3D6585 -:104220006B7C14B1CDE97B321EB10D455C8F3ED65F -:104230005188AFF6CCB811F3E742BA483A9C263A17 -:10424000605C449712F8E517A347E5BF2C3DBE9A82 -:1042500025F5DC10817D9F56BA283EF93C81E35557 -:10426000347EF97CDFB703A0872E35DE7BFF1F1B72 -:10427000EF53186FFB7FC5F14A79CF1DEC66FCA2A6 -:10428000E5FE42B97EEEE70CEF48F030BE9739DF2D -:104290005FFB971DFFFF0CBF8FFECB8EF752FC7E9E -:1042A00055E777820BFBA0A75FFC3F59E2478CDB09 -:1042B00039E45F755EFFF3711BFE7C81EA39E8A586 -:1042C000F6AF89D0BB9E6CF64ADAF447060D518CE6 -:1042D000B838AFA7C6E02F37DA0F5C8E734C01F207 -:1042E00027B08EA9891F78E02D825F213F41E57DAF -:1042F00059194F7A25DD1B94F15DBF403CABE0AF0F -:1043000073197EDDFB9303C82B2954653CE6E56AEF -:10431000CFA6061AC7CBC91637CE958DED34F7F068 -:104320004EAA7775545D589FD574CA75BA23F01B91 -:104330001B6F5E675D1DB54EFAA9DB5C3F5E3C936B -:104340008AFDBAF1393681F33685681FB1AE4C1952 -:1043500022CFF7FC54D42E77C5FF783ACDD5E94467 -:1043600074E17D9B402755CF7333D34D806EA9A058 -:104370004B2EFBEF01E139F016C156DDBF12FAFEFC -:1043800063A133610BD6D10E51100E127CD66DE5B0 -:10439000F3935641EB61394E5E4747D34DE8EB6AE4 -:1043A000ABCE82B19DC68441673CEF926E7A9FC7C7 -:1043B0001D4DE71F4FD7FD9D9680AEE9099E20E475 -:1043C000A2D3B3A988B3D6109D15A5959E069DA22C -:1043D000E99E8FCDF541ADF4EE64F55A31CF46EA52 -:1043E000FEFC586BB2843B35A8F25C5E90DB8FF923 -:1043F000DA63853F323A3E99F343857E6E42D5F7C4 -:10440000C39161C778D0FA1479B693ADDA92219C42 -:104410005FEF120558B7168810E2B74ADD2BDF614F -:104420007D84F32245BCAF59FF01E05E382F86FC46 -:104430008E75D613A6F36E51E72526E5EF1C0D7E8B -:10444000CD594ACF10C772B9EB311F8BEF77B8C186 -:10445000BF4ED606AEA7B596AB7A2876AB430CC74F -:10446000CE234F3F03ED5E19CDED970897928C74E4 -:10447000BB109F778C77C97C355ABC7E03D8BE3C75 -:10448000C15D23E32602F2D41D65577C5FB64F1F42 -:104490004BDF43BE9BD0D85F8EEDCE9120D1552906 -:1044A000E2FDF72EDD645E44F30A07AF778AEFEA98 -:1044B000DC137A694281396EFDC510B9AF69945336 -:1044C000F3DD729FC2E249C777E62CEFC3EB2F35CD -:1044D000B6A87C37E8B8238EE5BC78E54D1307D144 -:1044E000F78B77A47880E6B1493B07CBF6337EF6AD -:1044F0001E3DD7B6C6F0F39FE76B8F0F419E81E25A -:104500009EB59B1ECCB9F6657B3A75A185269F4466 -:10451000DC715260E71BD8E79C344DE5F69384CC00 -:104520002B15CBE378DF7C62E02B6B3A7D6F222D7D -:104530006A50DF14E3CABA85F02FD6E3CD7FD0E707 -:10454000A11A2BB467E28157E79E5DE9F94421F394 -:104550009BA3E7ED71BD7D97311E772AE8A3C4B810 -:10456000701ED6688FEFE0BB5FE9F4785E2F0D9880 -:10457000E8CA71F179AB1C4DDD1251DAC2BDA8EC6D -:1045800033AC601FE46D425751B816DFBD4D151BAB -:1045900019DFE6628EB327F476830F9AD0CF77AE19 -:1045A000E9C1FB394DA305CB4FD37DD906BF393FB8 -:1045B000C958CF358DF6D4237FAB79B4D3B3D1832B -:1045C000FC9650187194436BE57E4D979A7077E88E -:1045D000D966AFDC07F97C69AE1B7272F303531323 -:1045E000A13FE7AE51C30EC8FB6A73DE9270793803 -:1045F0000F7C6EED683BD6AFF3E27D768CEB4CBE64 -:10460000F611F8659C73EC0B9C708EA7B6F875AC30 -:10461000FBD4449ACF987F567722D6D5D1794F953F -:104620007A7E9301FF3A4DFB0CDF9B93E4DE01F9A8 -:10463000F87469378EAB76CBD7CF575AC3DD419F1D -:1046400047692E607E3E3844CADF8476AE9EF12CE8 -:10465000BF3102E36AB2B97A429E9B56C45840A762 -:1046600009CBA41CDF6D95F32BE8735B02F4FEB35A -:10467000789FBE3BB3DA5AB481FAE9E414D6847663 -:10468000B4CE1DA63D0FFE4C0C541FC2FA7AAE6E7E -:10469000AFE6AE96E7C1BA8C917C15D686B129F407 -:1046A000FCC8E6EC81C87337E466FEB082BF0F89B0 -:1046B000E0FF84025F617BFACE048BBB057A78DE73 -:1046C00034E5A56E520E7E18C2EBF93A9EE72DA492 -:1046D000271CC93807D82061E4AB426FD43EE4738D -:1046E00046ACDBED6217D7DBE7C97CD42EF670351C -:1046F000E75FDD225CCB08DE427E84D526C4D62A65 -:1047000027974F5691BEEB21C4F6AA74867754B909 -:10471000B90C55F5E6E7CF547918DE5595CFF09EE4 -:104720002A1FC37BABC673F97C55113F8FD63F73ED -:10473000E3E7B33E71F5245E0FBD506E66B9092FF5 -:10474000E81FA770DD85F34742EABBE4DE52FF08AD -:104750005D1F75ED23EF03E8962FF9615B35DAC233 -:10476000E737AD8D1990BB71EA89A79F43BCA3249D -:104770009EF3B25A4423CF931661E173D9D03F0E12 -:1047800092BB2E778ECF8ECC3BBFB14411D608F9A9 -:10479000BAC91F23AC11F669F6D264133C73E93B26 -:1047A0007FEE40DFBFB1AB96974F781CBAF38BF525 -:1047B0007FA5E78FDD79AC873CA7FBFD86C8B84BAA -:1047C0008B6896B0D5C9FBF18FDD9E9196A2DFD3A1 -:1047D000007E19E7A4BBD89B8F3E8179B842F52CA7 -:1047E00023F823F087E8F989CE9FE215DD56FE0213 -:1047F000F3DAE7F428F49D43B7F72BCCA7F68FE95B -:10480000FB51179CAB4E97F6EB53D8AF6469CF0AB8 -:10481000A047C3D26E7DFAABB4C05DA8BF25D183DB -:10482000130DDAAA0E810504AFF6DA3D2AE27A7595 -:1048300082EF5D201A4BBF226033DBB1C64EC988C0 -:104840005B1AE79EE3F2824E3E77451D613F664E5E -:10485000EFFD22037AA9567161BF06E7349DEDA0F2 -:10486000DF14DE1F451ED034B29737E5AB3C3F7FE7 -:104870003FC4CAE559D873A26B8CF0707C66DE6ABF -:104880006A0FFD58EBB5CF8FD0BF73F4E7737B5B36 -:10489000B8349E97E17BD83F5CE59D0EF9E888FA35 -:1048A0001C9403A703BF8EF185562562FF777EBE59 -:1048B00055EF5FF67B169392E07B7A77B5DF9CC36A -:1048C000E7ADD86E19FDCCE93D706557D8EBD5A39F -:1048D000411D5163F3A4A752BBCAF3DF71497FC4E2 -:1048E00029F3B3CB2E62378C38DD11FC29CF3DF292 -:1048F0007817ED786A07CE3D2CFAD8C1F66BD11542 -:10490000D22E899CE0E0A91CD034C7C5C73E75B241 -:10491000FE2EC2E724CE2521DEBFEB333BF24369F6 -:10492000DAF8933200AB4DC8338D8ECF1ED8F171BB -:10493000629B71F15DEAE5C5C595EF1361178CF1D6 -:104940008C7BF16C1AFCAC4AE51CEF3355BEB822E7 -:10495000ADADFCB0E8B8F8F9F8B958FD15CED757A9 -:10496000DE71A4CDF879741CF0F1FCE8FD88F80242 -:10497000E889B307D520F6D35B823D92441BFD1B2B -:10498000F1F3CAB5F4520AE6A53B09FB61A72FE291 -:10499000971FC997F6FDA41E6F3FBD5DE5F5D2E9EF -:1049A000ED0941F8A715DBEFAFC73E65C52685DDEC -:1049B000F372D1C0F4223A0A67A41D43BE5B0A9C7D -:1049C0006B7712F495815FE953097EC8D5C290E2F6 -:1049D000DB4C78B438DD49ED23F03800B96A8F3C00 -:1049E000C0D060A6AB8EF7F3BA1E34DA2DACBB9FF5 -:1049F000E3D2D4EE14FB3B7F88139C27289ADF0078 -:104A00007EC7D7E57AB0AFB830B4B382F33BB6C750 -:104A1000B9108738A6E7391BDF69D0FB6BC897FE52 -:104A2000C9717DFFEEF80E79DE1C78623E1D53CC15 -:104A3000F982EFEBEFBD9F2FF7CFEEC05EE2A0D67D -:104A4000F60B434D89DDA9FD977BDFE1B2516FBFC6 -:104A500030BE6100ECEE97BBE2783FFECB5D8F1479 -:104A600022CE7C32343A15F26F7CFF54BE8DDB9F30 -:104A70005CA78E07BD4450E6D99483AEB99178A661 -:104A80006C086447CE33996F747CD7B389969C5673 -:104A90003E963BFD4E9CF7ACDC754B11E4B8DE2630 -:104AA000E969DF35398063CC95755E01F9E5799662 -:104AB000C1ED575922DA396C1EF68B6D7B8B7D6800 -:104AC0006FC4A117EFB6F179C15957B8AFBF11F351 -:104AD000F0351BF361711FF7F59C8FD4A072FEF2C5 -:104AE000E26C1186FFB1E4B6840DD80F33F09D95CA -:104AF0002BE77BD92A45F8685C6541790F4747E287 -:104B00007B00394AE98D83903FD9941DBCBB672A4D -:104B10009FDF0DE3FE1623CF94E6714F9C73EC30BC -:104B2000B41D8FFBC119856CEF0ED945007A21F0B9 -:104B30008CCCC329EB2AF3A31F86DCA3BF76E19EAE -:104B40002934DE133A5FCBA6847B222FA3EC990C89 -:104B5000CECB386197FBA5788EFDE2B281F47E3C26 -:104B6000DFCFA119EF2747C851D91C8F1BEDD47691 -:104B70001EB7371EF8BA4EB1DFBA3B41C06FB53C25 -:104B800097A0E757C5701EB9F15EBFA152EE8C7BAE -:104B90003FC40D321FF3419BCC577D707306DF7706 -:104BA00061B47FD0A6CD80FF8471C05F5F68AFED38 -:104BB000897D1703DF8589B58CE7095DCE17C6D6D9 -:104BC000CABC70FD1C31DA036ED2F3D89BB73938FA -:104BD0007FE55846C337C0F7D8B63EC88101BDE768 -:104BE000EFE57AF21F899F8B9E7484517F749B8CB2 -:104BF0005B1FB505BF811E3EBA3E85CF471D6D1FA9 -:104C00001CCCF9018ACB02FFECA8A2C33617FB9596 -:104C10005DEC0453FBD4586141FECEF8296B67214B -:104C2000BFA1659303E2298E6D79288DD735C29D8A -:104C3000C47936075501BE1D7BF23FFA44FA2F4670 -:104C4000B9689339EFAE295B98EEC9B97AA89C97F9 -:104C500057EBF4BD66A8B453E571A107BBF2F82485 -:104C6000BD893FBCBEA3199AC0F9134FF750A037B6 -:104C70001E16C19F7F9CC7AB6C37F2E6CB9ED9F660 -:104C800006F66B8F594403FC0FE5CEAD3FC77D1B85 -:104C9000A9BF49623B24C4261EDF51973CA74A1393 -:104CA00096C7BFB08384174DDDDA13703DD91C85DC -:104CB000E6D7228BC2FD2FDAD39FF3ED881F16DED5 -:104CC00027DBA9EAF8904F09FA6D91F9CA13DA05C2 -:104CD000B7C0DF6B5EDF4DE0FCFA3875DD00F0EF4A -:104CE000CCA6380BE4A9FCAEE149C341B737550166 -:104CF000FFE38CD5D321328E104DAFE83CF0E0506D -:104D0000A99FCA700F0ECDABD23DEBF9BE9052C831 -:104D100025E8F2A4C2FBD8A52B873FC472FA864DC2 -:104D2000F4A07E4F84EE4F8CE4CF3D43A55F70FE30 -:104D30003B760FB72FA5F6F2FDD71219CF2D36CE41 -:104D40006B89E6EB65BFFFA47A59EF9F1F7F88FC54 -:104D5000820117D2E18C68F8F9C7F4FDAFB7C7F04C -:104D60007A9056007C8EEDB82D341FE33EFE740C15 -:104D7000EBAFE3C9524F7C49FA34D00B785CFD5B52 -:104D800096D3B7A7F279BF0541F3778D7E7F3B5469 -:104D9000EAF1F2144F12D69DE56F4A7D48FCBA86BF -:104DA000DF7FD3C6EF478FA3427FEFFC3C7D3A8E77 -:104DB000E5E27847C98FE33B7AB17D6A4A76099686 -:104DC0009B6D36596F0B65C10F3EFE742F6F4DC43E -:104DD000778F2787B25C11CF9B6CC19543A43E6D42 -:104DE000C6BA588449D50E467E91603D6FBC57EADD -:104DF0005CDD003F05F9BD8307721976B4BB304F07 -:104E000077423BB99EFC529F779CB39AA6E793B337 -:104E1000DF13B2438F6BBA7F58B63D3ACF57D6D720 -:104E20001BEFD3BC4B35F28A2DC037644FE7788334 -:104E3000703F43F8962EBF6521F2C74BFDF7DD08A2 -:104E4000FFA9D42AC6DB09AF2645653C9A62C4ECAB -:104E500029F02323FB89F0DFDE6AED47E0DEB6327E -:104E6000FC41F3E0BDA16E293FB0A4F4BDB2E5CA98 -:104E70006A7CDFD02F1C284C6BA513F25A91DFD32C -:104E8000345AAFBFC8B89B6CB23E7ADC063E478747 -:104E9000CABCA0A66CF76F47802F7F51F97CD799C9 -:104EA000EF7393DAB5E1A7B5DA7B7B6B9E2DE1FF5B -:104EB0000D7C6BFACEF3BABE2B25FC8067CF75E66E -:104EC000BCF2DE9BCC70DFED66386797191E506729 -:104ED000863D07CCF021BD5FACB3710E19EB6C942D -:104EE0005867BB1D729D0D18EB6C945867E339D65B -:104EF000D980B1CE068C75366083DE586F03C67AD2 -:104F00001BF5BD86497D2E7CE134E46B5658649ECA -:104F10002FF1C3C7E79866D84DE7524EBF28CFA5FB -:104F2000903C487DBF309EE7C9C36831147649CEB6 -:104F3000A7D4E71DC165F4DE38B7963C0C7662ED68 -:104F400057F32177155D1B39EFB569C52B3DEFA7E9 -:104F5000768D4A82805F51B1F6AB59F0A33AB8B56D -:104F60000EC3089FCAD8869543386E1F66FDD15878 -:104F7000ED7EF34AC9478EBF14ABB8F982EA4BDA2B -:104F8000B5993F149D772E569BF3CC2F95771E2D08 -:104F900007861FF898AD39C3C5EBF4118F22CEBB3D -:104FA000584970619DFE598C5886FB8002AFCA3CFF -:104FB000B59683369937B05AD92822FC93413ABD29 -:104FC0000D78EEB95CF6C7CFC3AB158BB84288EE4F -:104FD0005A7313D6D7674A2CEC779F2929286C0F70 -:104FE000FF8FD6659813B86F2B125FDCB715293F7A -:104FF000B86FCB7C6EA2A3A93DEEDB329F9BE86B22 -:10500000AA9FBA3AD7543FAF68B8A9BEBB90F82D53 -:105010005928F19B47F6C197027819E72D2E01EF29 -:10502000C84FC952022B592F6F50F8DCB87BE9AA40 -:1050300042D0E5048933E20886DCCCD5ED8BB0069E -:10504000EC90BBB3A9B2FEA8D2F0C55DF4DE496F07 -:10505000ED165C8572D2B2EEC1116EE4D76FC872E4 -:10506000D13CBC5509A541F5140CD234C8D9616BAB -:10507000E364DE4FDCD9BE5D35FCCE8383DEC847FA -:105080007FDB55CE9B30E425CB26E3741B689D0166 -:10509000FF6A43ADCCE7DD509B12DB3D62FFC518D4 -:1050A000670BF820502E4B4BE5B89068C038C86F9E -:1050B0005F06BFEDCC41E9B71BE3E9BE3CDC690903 -:1050C000D5DFBA3386E973585F379CE8F3D20037EF -:1050D000CE6F54EDCD52E10F58B66FC13A22215533 -:1050E0005B0AB92FD9D0E3AFB8AF6BD17BAAC07937 -:1050F0009ACFD78C491C4ADF39F6B4CD3381E0BB57 -:105100006A1FB7639DBCC81AB4731EE6B60D76E479 -:1051100025FF64EB067E3E7F6B31E75D2E107E5EE1 -:10512000471ED1CF6519E32E2950D6B948BE3E1A85 -:1051300026F56349ACDCCF2379FE33C67566ABE256 -:1051400085FF38AD68A7BD989EDFA7B7734F9F3E18 -:105150000EF2D71292F76DB4BCAECA7BC4A6A932C8 -:105160002FE622F7F34C3D97CDF23DED5C3F5E67B5 -:105170005D1BEE23D7B139527FB4D4A9BC1FD7F23F -:10518000FACBA953F1BD3A1BEFDE95D81BE4F97FAA -:105190008BF0E31C817B7A8394AB6CE187FFB7E4EF -:1051A0002FEFD463DE2DC976BA311F8A46A826F9BF -:1051B000AC1C1B6792DFE9A29DE91CCD75482A89CA -:1051C00080A74DE8666A7FFDB47E51FA60606B3D52 -:1051D000EB836151E7000B4C70399577403F89AB09 -:1051E0004CEF958B29ADEDB01EDE24FDD6F25DC9E6 -:1051F0001BB12F5E6291EBA1E99A7C5EB1573E171D -:1052000022F6FCB9749CC7477CC0746E5BDFE74331 -:10521000BF1C0FECD6C0719DE60CD29744D1F2DED4 -:105220008D76C4D3C85D6E469CB43C4030FAF58997 -:10523000E61A9C1FB14AFAC67B5C5D9765B4CA4505 -:10524000C52E73BE55C5C177B89D91CF185D4F9ED1 -:10525000EFCA8EC07B82E2E57393DB9BEC88074D3F -:10526000D33AF1BD14D1F79F95859A18CF6BF7A665 -:10527000B9B06F5B1175EF59A7E16E699FF4F83F04 -:10528000EE0D927E42835DC66DE3F75B78FEC97BCF -:1052900076CECB658945DE1710459709DEF7B8BF96 -:1052A0008E19320F0D74B146D0255A8E40276B04EB -:1052B0009DE60B49A7F9A44D820477849C45D2E76B -:1052C00047D26B01FEA0FA057B9520F2DFA2E933FD -:1052D0005F6B64FACDD7E2FD41D785E3A9B8E383DC -:1052E0007AE8A71D19F29EC268FA2D100D2BB1EEB7 -:1052F0005D4076239CCC726177F23A4DF1C06EBB73 -:10530000F31BED36A9CF38CEDBF2FA3B3CEF5A3C2B -:1053100034AB211782EAA97DBCCFDDBCAC8D3CDF6C -:1053200029E764FCE4BA73562EA74D30CFBB6BCF90 -:10533000A5F1F31F4B970AD019728EB85E621BF766 -:10534000E621CE9778E1788DFD10430FB7FA75E628 -:10535000BCE58BF97FD171C2DEC3F538E12031C8DD -:1053600094B77C11BF233A6FD9B0E32DF1D24E8EA2 -:105370005373DEC4D9C6E257555EA7BBA78FB7F0FB -:10538000F9F157E57D77DA8AB34D904F2DC1C27A96 -:1053900070714257BED742D3E376463F59D529694B -:1053A00088FF15C7B8381FBFB85A2D82FD2AA676C8 -:1053B000EE88762B9777CB825DF8F4EE5E8F0668E9 -:1053C000BE7C7A5B6A1AE2FE9FADB0A592E63CDF36 -:1053D000EED315E3B2909FF1D97D8EE9C136E85343 -:1053E000345CDA81F23B3F60BB75D2F27AE2747AC8 -:1053F000BF6CC5EE4484EA4A57BC33D8452EC5E19C -:105400003CED9AE1BCBFBA610BDF07EDDAC0F709EA -:1054100068484A6E8F7D8815CCF7458ADCAFBE554B -:10542000097F7125B53B11735FE2F46CDC6E2A389D -:105430004FE3ECA604FD3C5A35E70D9D88257F809F -:10544000DA1F8991F43CB233C1C37762780259BC48 -:105450007E6B2FF7774A2D75D7019F6B52356DF80C -:1054600020E011DC92AE723B3EB7AE55F7486A2B96 -:10547000FE61945B743B0D7F1B25FC6DE4CBC0DFAC -:10548000060C7F1B25FC6D3CAF5C6BF6DF6ED7F71F -:10549000FB8C7870979A662FFCDD4081E8ED673BC6 -:1054A0003BA1E0F7B05BAF4A7F6189E259D5C8FE06 -:1054B00052422DD69D3556E967073E91E7A22082DC -:1054C000D04FBF50FB7AB09FFF50DC9D8FA1FD52A3 -:1054D000EC0FE5E11E53F2BD22E4F5CA734E1179DB -:1054E000EE7634396191F0186786A9FD3857B6A970 -:1054F000FE27E97D4CF53F757B4DF0D5BD879ADAE7 -:105500004FF48C36C1D7E4FFD4D47EB26FB2099E7B -:105510003A7E86A9FDB545C5A6FAEBA72F34D5CFAF -:10552000D06E31C13796DC666A7F93BFDA542F8420 -:10553000FF09D0C71790F7AAD561FDE4C0FD2F4E33 -:105540002EA9FE0FC8631E4D22CDF7AEFCE5677C89 -:105550008FF57EE435D38C1B31C6E26F2B8EFF07AF -:105560005DFE6347FAB60DE7756E03DF8B89D82DB4 -:10557000E46E1FECD4A0D6E79DAC46DCAA2143DE46 -:10558000876E6E7FB17623E2F69F7193C8F5AC3BD0 -:10559000739395F4D78821FB73BB21EF79C4E0594D -:1055A00056D2372386EF7FB62BC1FEBA3B6771FD1B -:1055B00015FBCFA0FE1F75C3243C55B06B72FB8852 -:1055C000BFDD84FC941157765DED91719136CFB7B4 -:1055D0001B25E88473E1A013CA30C93DCAFD24F736 -:1055E000280F90DCCF23BD564F728FF220AD33F1E0 -:1055F000FCDF689D89F2755A67A27C83D697281BC9 -:10560000687D89F2EDAAE95CBE5BA5F17BEF579559 -:1056100070F941959F9F7F54B594CB4FAA02FCFC33 -:10562000C3E1328E108F7B9313FEC9BDC97E17DF95 -:105630007F50A3DB2D51A7E7D5ECA7F52BE8D96860 -:105640004DFEC2D9BABF78F1F5BE557C11E1B74D18 -:10565000B6FA3E97FCEDE462BDAF3F2FF56AC7A0F6 -:105660004FDECB9EDA235785BDF3FF3989EADEB3DF -:10567000B47D9FE43E5D5E3E1EE13B8DEF8D741E6A -:10568000E2FD74770679ABC31956C07F65A08C5FC5 -:105690008EB436D4A0BEE63BE1C6BAF9A584F7794C -:1056A0001FBC86DC659C3F56CEC9F5CA287DFFBE6F -:1056B000E63BB97F3F0AB853FD4897ACAFB9992C88 -:1056C0009D17F521FEFE289C7696E7DB4C793B631F -:1056D000CF358CE1FA78BB1BF9A6A39C61F93DA7F5 -:1056E0007021BEFC52C21ED9FF38D9FFA6EFC2FC02 -:1056F0007DAC3E91973DD2D98ACF32C6AF41DE37DD -:105700009723DBD7E8ED4769D47F32F0F34BFC8A6F -:10571000A9BDC49FF5DC287C3319AB6D591F9B2EA6 -:10572000CF278F3DA7D77BE4783B58258C3325A81E -:10573000CF4CD1848FFACBCC141EC4DF46A536647F -:10574000707B3D9F21C12ABF97E491F77175FFBB24 -:1057500026F7038800C0DFC84B32E66DE776E10C20 -:10576000F8799D17DBF97B99EA4E2FF4F5A75EAD2A -:10577000EF08AAB73A2D3CBE1A9F3C2FFFD68BEEFE -:10578000CEB85F74B2EEAFFF13FE5F81F7473AF712 -:1057900049FEE392B7CC5658994FFF0F6D93FF9295 -:1057A0005E242F183FF19FF9017EEAFC570CFAE8BE -:1057B000FC3FCFAF6591F5BA7C5CC8FF90E4B72E93 -:1057C0004FA39C326F02EDC1FF9156290F35313244 -:1057D000DFE3A584C287714F16D1A608F1F991863F -:1057E000BCF8E5F9E1FFADFCCFB3CA7BE41C654E24 -:1057F000BEA7EE52F230BB5914E2DECD8D03B57D6B -:1058000098D7C5E7DCF580E78AD18570CF8DFAA7F8 -:105810002E52AF7DDD6C036C3C7F1BED06B5D65B75 -:105820009D6FC741EF19DF31DA7DA57FAFB5DD4050 -:10583000FE9D8D25E342EB60BFC6575B396E4D9EE2 -:1058400009C307C99EC97C4E5FA2372D32FFD373AF -:1058500060711EEE0B95E7B744BCF4ABDDF41FF4AA -:105860006AE1F745CBD19F50B75BB1EE388B7C5ADC -:10587000FA4E61AAD93F1F1FB5BF7E55CE97EC8F58 -:105880005F75897BAB7F3742F7A7B345F67FF2DEC2 -:10589000D08747B07EBEBC7B437B8B3A9683B1C535 -:1058A000329F8BC66F1988B88D4FF801170ABF1544 -:1058B00072305ED45AE5BAD277A2228F57ED4C9F50 -:1058C000AB45989F4F24830263720D890FE097E3E5 -:1058D00026CDC47DC06372C774C7F388FBF3FE0096 -:1058E000FC2A54ED6FAE88FBF3F68F95F36DF1B59E -:1058F00032DEB4DFD9AD4D3FF455B2B7DD7B802E3B -:1059000082CB3F933DEE4EE37E85EC31E0AB7A57A0 -:105910000BBC57E836E71D19EF5FED1A23AC2917CA -:10592000B777570FF86327D0F9B5E45E63C1AFD7F7 -:1059300092878C453CFEB5E40E16593AEC5CF67F36 -:10594000AE7B5BF819F3A3B5BF42EECFB8FF776C1F -:105950007B79FF6F345DAF1221137D27E8F4FD11D1 -:1059600074FD087A349AAEFBF475C57EE73B7B8CF8 -:10597000BC29C493BB2F6F60F8569B9C07E5CF4DA5 -:105980002C405EF4E2F7647EC751A002BBBB7438C2 -:10599000E33F6AE95061CDE5FDA800E85DE6947457 -:1059A0003C19786900EE29AF4FD18E83AF5FAE53BB -:1059B000F9BCFDC96762381E7724F86C22E869C813 -:1059C0007199EA5ECDBFA7F19A2AEF59FAFEE52C4C -:1059D000DC2B7A31B92679FE7AC4A036E4399EE40C -:1059E000B9FF85F22C36C97B0CCA9C856DF2D9585B -:1059F00077BE30D0C7FAC225C2B740FE2B845C1FE9 -:105A000055385F97F754128C73AFD17ED5E0586A42 -:105A10004FF576A7CC1736F89DE990F75866C6097A -:105A200017E22042CBED0B7CFB76F7C58DE4FCC280 -:105A30009CED91796BA3C2FD78DF79FC4195F3DD94 -:105A40005F8995F7B837123F14F24F7FD2CF1FDF2F -:105A500095F8983C444B1B8971A9DFABE8F7F51E1C -:105A60008A48E1F8796E3CAFB37FE47A3D6BA4AE2F -:105A70005F068801FFF4F711DACB7B8417BF9A1B0E -:105A800004DE8BABC9AAA5F2EF5CF03D7135589FDF -:105A900067B7EA9D51A227FFFEC598541BE799FFFF -:105AA0006FFB7D844CA1F1FCFBCFFE4EC278F9E880 -:105AB00082DF49C84C5C75404B6DFD9D8CE8DF4929 -:105AC000C8D4EFA7166E693F8CDF47B852F8382F5D -:105AD0007F5CBAD9AE8C718D3EE0E2D21CEFC9BCBE -:105AE000443ED74D23F5739D97E27BB9D0F92ECF75 -:105AF00075420EF4DF3B09423E8DDF3B31F86EFC10 -:105B0000EE494D7BF9BB27FF6ABF7312CD9FE8DFDB -:105B10003D89E64FF4EFA08CD262994E63CAE259F8 -:105B2000AE0D3E4DA7FFD81FC0B95CE5BF9F5FF724 -:105B300047CDD3B362F520DC537ABA58EAF58BD956 -:105B4000FF695EDFEFA16FB6E97ABFC629E321BE28 -:105B50001AAB881925703F21E7CBFEA246DE03551C -:105B60006395F18000F115F7E27D1BFB0F799F2310 -:105B7000F947B68E88CBF8F9FD80DDE9AAF144FC3F -:105B80000ED652791EF89045FE9ED4EC1CBF82FDC5 -:105B9000CB4E5DB5A7A0AFD245D1CEF91C97F70F7C -:105BA000817E9FF5274716EA677591F7478A1CF9AA -:105BB000BB4106FEB332655ED6B323753DEE9179E7 -:105BC000587B46CAFDC0048F8BCF3514E7083DBF14 -:105BD0005564CDEA0F39FE84FDF816B7F4AB1B6DA2 -:105BE000F21ECBC0AB329F679DFF6DF6FB37935F14 -:105BF000AB4AFF66EDBD1C674814D8C77D2CA6399B -:105C000019F8F75A2B4CFE429FA0D39497DC6FAB48 -:105C1000CB04F70FA59BDA5FB1D76DAAF7867B9B04 -:105C2000EA730F7A4CF0A0867C53FB211FF84CF0EE -:105C3000D0C6F1A6F6C38F1499E05323BB4A3A416C -:105C400026693CB396B882F25E7C1927E96297FE1A -:105C500054CD6D723D61E4AF6BFA3C88CE5FEF6C62 -:105C600095F9EB76BFB46B5ABC5CDFBADA0997CA18 -:105C7000E7621A18C6DD109C371E30E7997772CAA2 -:105C8000F59565AC5C7FD8F53CF3D8DEF2DC8B9102 -:105C9000574EEB0A1FE8DD5D34CEE0DF2FD0EF1367 -:105CA0008D96E7BF8FD4EF738AC2BB8B5D9EA7AB87 -:105CB000B9CDCEFBE75ABCBD4949BC109F6E7A7E78 -:105CC000E46667DBF73E39474939BB21AF488CA210 -:105CD000768F92D962FFEB82FE3C8DD07735BFB2D2 -:105CE00073DEF8A5FA9B75851CCF4C8B65F6E41C1A -:105CF0005E0FF23940A3DF74F44BEDFAF874398F7C -:105D0000EA6F565233DFBB2692EC6EC8AF16BF92D5 -:105D10006157AC4856DBA07BEBB90C99A77FD3EA5F -:105D2000D0BDBD08CF99F65A9BBC702068833C4C0F -:105D300028203FD28BF8EB43EBE3891F8FE207EC7F -:105D4000C8CFE8B2AFDDEC4077F899CD2C0F4844CE -:105D5000C17E22FC4F75602BDE6BAE9479DFBE51A5 -:105D6000C2B8FF80F16AD1E3232D2274FEFC44A067 -:105D70000D79D3E2EBF91C826BB194A7CE11E7AC9D -:105D8000B0FEFC9F3A2F21B0434AFDD86A853CE71C -:105D90007809FA19E754DCB7D88A36C6E3BC881804 -:105DA000AF44D0E1892BA55C2E061DDACB76D04717 -:105DB000176B477E5F12F6175A843BC97589B8FA8C -:105DC000FFC4F833AD32CE90E594E7453A5B35D663 -:105DD00017F6DEFA3D7717C8BBAE37F4385927AB54 -:105DE0009CF79D3C725E5FA8170EF0F7ED9ABC37EA -:105DF0002D9ABEFC2F22AE629C5F891D2BF588A1D7 -:105E000017CE9F43E921D7A1365D3F04BB5B38EF36 -:105E1000E0AE04F33C7E7C94A46FA13E8FC9CE27F4 -:105E20007A079BF484C0BE5ECD0A95F504E9C97A71 -:105E30008DF02CC6BD2CAED6DF7BBBF90169C74601 -:105E4000F98A1EC4BEC99C3536B181F715E4FDB090 -:105E50000BF438797120EA7E16DD1F3FBB5A71E1E1 -:105E60007720E6AE32D72F88FFE213AC1F6F8EBECD -:105E7000A7C6D8AFBB441CE0FE51BAFDF7088F9E01 -:105E80007FBF0CF89D0DCA7BAFCF9F57D2E33F2D4C -:105E9000C167257C87E07851B45F60C06EEC9345A4 -:105EA000DCC342F48DED0DFBBEDCDA667EA341DF80 -:105EB000F3791EFA3E1D95CB56F07A46E637903EB2 -:105EC000E07DB913540F3FF044E00CB73FB12B868F -:105ED000F34A4E7A1B0660FFD6D8A7EBAEC97DAC5D -:105EE000965D0932BF21DE22E1ADF21EFB457F0F38 -:105EF0000EC03AB631F0ACE99C83D668DEE78B2E53 -:105F0000B5EADDBCDE3C9CA7D58D427EBDD5E3F471 -:105F1000107C77FC7EBEA76B02AD1FA1D79097B215 -:105F20002255E2CFFA2B7046D2CF2FE9770D397A7E -:105F30009C9F27487B228E2968554B65717828F7EE -:105F4000FF63F7C1A69EF3CAFDDF73C3F97D6DD56C -:105F500050867B079B477F40FD5EA7C5BB1147BAB4 -:105F6000B6E617E362E9D38DBF8F5FC16567F3F9CA -:105F700001A3FC58B7238DB6B6EB27E8FA67E19585 -:105F800086BE96F2BEB85AE17DB5C59071C0F7CA1B -:105F9000FB390DF84CAD0E8F93F092151286698285 -:105FA0001F3C47FFDDB32D7AFC05E34789F1232E23 -:105FB000B05D8FCF60FC28317E3C87BE020C7D0532 -:105FC00018FA0A30F4154AE82B3CFF3C790CEF6BC9 -:105FD00063DF6E6CC47CC2BEDDD888F9817DBB48AE -:105FE00018FB7691EDB16F17598F7DBBC87AECDB4A -:105FF00045C2D8B78B6C8F7DBB4858E4FFB415867B -:106000005EF34D36C153693D3036623E63DF2EF29A -:10601000FBD8B7337D4FBBC5F4FE8D62A9E97DEC9B -:10602000DB45B69FBD5431EDEB09D1CC767DEEDA80 -:106030001496A3D7BC451957B6E7DFA9FA99AD2B3B -:10604000EB078E632C2E8FF5487ED78E97FCB7C852 -:10605000F3114A33FFBEC0993BEC121E67CEDF3608 -:106060004AEC7B8DB5C97D2F94D8F742897D2F945A -:10607000D8F71ADB43EE7BA1C4BE179E63DF0B2566 -:10608000F6BD5062DF0B25F6BD5062DF0B25F6BD75 -:10609000F01EF6BD5062DF0BCFB1EF8512FB5E78CC -:1060A0007E88F09817A1C7E0AF7737AD33490E4D22 -:1060B000EB4C970986BF1ED91EFE7A643DFCF5C8DD -:1060C0007AF8EB9130FCF5C8F6F0D723E11B46B91E -:1060D000799EC16F8F7C0F7E7B24DCBF36F067C456 -:1060E000D626AE3B7500656382F228CE1BDE70E5D6 -:1060F000B6D9D8BF6C8C51B29249A7DBAA77CC1E17 -:106100000B7BABE73F0E10CD16E81F0D8BC93C3E55 -:1061100067C879A5FDBFCBE0FADBF5FB11F81FF1ED -:10612000DDBB4BF0EFCE18FBEDC6FB1E32DB288D3E -:10613000F6AD70DBEDA2FB37DA716E55041E38D177 -:106140008CBC19EF1DF103B10ED9A2FF8EF096653C -:10615000322F3A5AAE7EABEBA72D969DFB710EA661 -:10616000B958F1E0DC47F75A8DCF99F59F292CAA51 -:10617000B7753CBD1E4BE4BCDA5F5C29ED9181BF75 -:10618000111F257DC1E7074734378C49A2F65A60B5 -:1061900034FF0ECE04BBD07F2FD83F0CEBC97E015D -:1061A000C5B73142CEABF5EF690189C7138F4D9268 -:1061B000EFC5CAF79E782C91FB9FB45CE13CB3110C -:1061C000DB850FE794EFD1F1EFB73DACA2BFE2E57D -:1061D000B23FE3BBC5EBB2EC38CF6DD0AB58348ED9 -:1061E000C57DD2224FC19DB2A2A75563BFB4C34C97 -:1061F00097057ED0E59E831A99973C0E7988A24E2A -:10620000F0BDA113F3DE328D97C93518BF6B2A7824 -:106210006DA8056EB1A0DF49448014C49309C67807 -:10622000344DF8B389BED74D2F667AF79E2914D026 -:10623000BBCFCC0D96547AAF9FF69205FE5AFFDA8B -:10624000462E8D71784624AB8027D85CE380FF848E -:10625000710AEB8FE83C1EF8070C2FB7B13D37FCF5 -:1062600087C509E7F37CFE8A3C9F33076D9CE77383 -:1062700066F959AE2FDE1DC3793DDA5A85F59AE1EC -:106280003718793B65B7BC3718F439961DDC92DCBA -:106290008DEDFC1FAF441E4BD79D89381A7762F9EC -:1062A000EEEBE0529E59BE5BFEFEACBEBF63FC8EC1 -:1062B000A9C8F1713E98E1070AB5CE1EB98F63FCFB -:1062C0001E1AE94F6E7766AFDDC5BF47A7FF7EA9EF -:1062D00011F729FE4B6E3DE85ABC5EFE9ED99C55D7 -:1062E000F7154E2778BECF19C6EFA147E7632D8C6F -:1062F000F2032FF5FBA5C267F6FF2EE6EFFCFFF2D7 -:10630000BFB7FCBF73A5703700800000000000001D -:106310001F8B080000000000000BED7D0B58556539 -:10632000BAF0B7F6DA37606F5C080AA8E002454DAC -:10633000C936225EBA2EB9282AE206C4B441DC204E -:106340002676AC21B3911ACA8D7B4348D6C04469E6 -:106350008ED5D6D433534DD1654A27EB6CB59A2EE2 -:106360009A263975A682ED25B53BE9F1D49CC799EB -:10637000CEFBBEDF5AB2D776836633E73FFFFFFC22 -:106380007B9E66F1ADEFFE7EEFFD7DBF25136D06B2 -:10639000369EB1337B459F98C258C5BE3DA52C8E15 -:1063A000B1533526C6A05C562F322CB367992F4DBA -:1063B000C0728E2102CA657F501C82CCD877ABAAEE -:1063C000F7BF064DF7AF823616C68ABF1FCC5826D8 -:1063D000631DAB642A977E3F86B158C60A0211F44A -:1063E0007EEEF789F4BCFEFBCBE87DB10DFAC1FC73 -:1063F000811DCCB71AE63BE5B650F9D44EE6C3F999 -:10640000F1173781B111F8070C99C1A43C368CB152 -:10641000D18AB007BAB359DF5F45E3CDFB3E83C6EF -:10642000BB667C45C300E80FBD1D69D07ED6F8F77A -:1064300072FAC17A5DEE295922948B8DFE39387E2D -:10644000B1C3C4DC29F8FE564302D417325613EB0D -:1064500080F650C6FDBA5CAC468861ECCE89D06946 -:10646000009459CDEB03100E5B98632BBC9AE7AAFE -:10647000C8C67663CA9820C2D4E551ACA61DF7629F -:106480000B64155DCED80FF8BB0EDEE322AFC4C59A -:1064900027BA14A82FEF077F0EA26D29CCCA983D0A -:1064A0009DD75FA924BABCC3E1EF96758A7520CE4B -:1064B000C77F43CDD00EE611EF34FB5603FC5D36AB -:1064C000EB61612C54B8F394C028DEE68754C6868D -:1064D0004D823FB2E05C0C86854E9867C18A0C7392 -:1064E000657ACF3ACCD9D9F3A6C03EF2F0BC61BCF4 -:1064F000E56B4C3E4B0A3ED3E299ADA75DE87311C4 -:10650000C0578EC575076E17003EF314A6E4C25C33 -:10651000F399B62FE667B08E1BD4B2D7AF049A6C4E -:10652000040F2ACFF18F70B9611D375B03530193BC -:10653000D8CFD36BF2130D8CBD61E270B5985CCAF5 -:10654000605887697B867FB08CFB90E83D330612EC -:106550009D76D8C7DAF6FB46C27BAF22F3FD995B86 -:106560004C0C07623E9313E0BC289D293E84BB91EE -:10657000E3D191352F3DDD2CF4ACFF8889CD6B0F35 -:10658000B3BF3AC540F36C03BC954732F6DB5556B2 -:106590007A3EB14A6232A0E053AB12A8FC34E0313B -:1065A0003EDB578DA2F7CFAD7250F9855593A8FC0D -:1065B000E22A85CADB57E5D3F38FAB9CF4BE60B407 -:1065C000EB1605D6FB9041397C0FEC6F90D8C210CA -:1065D0006FF1DCAD137ACE37A2E5BB0A3C8F2A9B64 -:1065E00059C6755701685CB08F4AC5EAA8075000C4 -:1065F0006C1B13A05C2EB2EE6647B873E7707C6C20 -:10660000FE7F2D3540BBC7EE8A24BAD5E057663EE3 -:10661000F0BA35A5077E1FD5FEDAC40C746C69325A -:10662000CC7B434D84A33905F1C3E9C1F546A53BB5 -:10663000CC2E80D7BC298CC6BD32D5D988EF6F5EF1 -:10664000BBEBD10FF0FC76A6985D709E15DB331A7C -:106650001364ECE7BA5781761536C98C78778B3797 -:10666000C62CE3F9C7033D206EB3EEE4627B0FDC7A -:10667000B728028D7B7D361FFF1B3C1F6AD7622A1D -:10668000D2B5E3E7733E3D1C9882F0F200FB581D43 -:1066900083F4F0E2143C77E94EA091C9B01EF63EB7 -:1066A000D59B1398E489391F5E83D90101EB13014F -:1066B00096EEC93DF06B1E55497CCE043428C604C5 -:1066C000C38F113D85E2CFFBB80F804BE50A6175A2 -:1066D00003CC5FD526FA0401E9ABE00DA2AF564129 -:1066E00026FA7A70983991E84D90907F15F497A723 -:1066F000C643FBEEFB0469B38CF40A738DEB19B748 -:106700006AFD64A2B72A1F3C337BA7CB9FB5EE4935 -:10671000DA21E3312A665C6795A498FB07D1FBA2D6 -:106720001681E822B4FC9A22723A626F9A106E6562 -:10673000C365C19381FBE1F8B160458AB9D286F5A2 -:10674000CC6F807515A4B237B05D772BAC3785CF91 -:10675000332E68DC4A1C37685E68BFD009E57715C0 -:106760003BC1B54292CD8928572489D657B9629743 -:1067700009E1B308E02C64203C1C661B8EBF14C6E4 -:1067800007F8DD20F9F3B0FE867499D5C339547A41 -:1067900033CCC89F5C6BF93CAEA618F3E550AE3025 -:1067A0004AE624289745323A37589F0FFB57013C59 -:1067B000FADB705CB610654B285C2AD4F556B5C47C -:1067C0009817EBDEB79AE474E26B4A387E214EE10B -:1067D000785BE92D4A5E87E7EDB64B44B746C5ECDA -:1067E000C075A9F09DDFB6CE9412D4FF5B158FC59E -:1067F000291CCF0A52FD6902EEF7D60807AE77BE14 -:10680000D46242789E83F3831C0E8B257F1A8EBF41 -:10681000D8CAE1700E3FDAF4E7DAB33E0EEFAAB65B -:106820000AA2BF1B8DCEE475D0FF4658A71B9EF36E -:10683000D7EF4A13F009F42E207F905CC9CE207A5E -:106840003BFEE0F5C9B47F583FC2DBEE90A722DFE4 -:1068500001BC21B9ABE14F7926A76BADDFE029463A -:106860009A77F0944BA3D7AAB5EF51FD22A0579485 -:10687000B766F68280F5666084E1E837094786F6F8 -:1068800036C01F77620FFDCE6781F9C85F17AD2D47 -:1068900062AE20FE03F2B6E6B930F09A87EBCD2265 -:1068A000B945E70D74F81AEBDF539FAD9E7759AAEF -:1068B0009EFE713C1CD7A1D567FBD36E4DEF69AF2F -:1068C000CD5BD69FF7437A403C74A8F0C1F6CBA9C4 -:1068D0003D2F833C5EDD80FCE13ED16711F0F9780D -:1068E000C3402C3F0BD216B6F6C5F297DE9D0BCFF8 -:1068F000CF1FDA548EFBD3D6B118F41DE41337AA98 -:10690000F2B9CA1F9E5FFC6292EBBA295941F8F3B3 -:10691000C0EF4720FFFEE2E977D210CE1FDB39BF80 -:10692000FBD9EF1F37B1D49EF55736BD67AAB00526 -:10693000C38BF3BBE65107E9FC168DE2FD1679BF68 -:1069400025F9C5407EA5A59C7FFE15DE6779FB5A1B -:1069500007B577D9FECCCF7F1093C4C40B9FB77611 -:10696000BEA1E7FEA8C9E94F407D34B54547FFA168 -:10697000FBAF50D75D3585F3B71B543CBEA1BA952C -:10698000FA5536553C8E7AEF7C8D7EABF4EFB5F33D -:1069900039B5D644E7736A6D5A23EA8BA7DAF9F959 -:1069A000FC8BD83E7625B4FB62D9D65B1253492FB7 -:1069B0004946BD04CF07F5D21B55FD74099C0FEA6B -:1069C000A761CEE736D4CBB4F292C7F8F92C7A7A25 -:1069D000DF277F9409FFF8FEEEB3F890FF56B63F2D -:1069E0007BE84A783FBFA9D59402ED3C5352083E5C -:1069F000E7F87C4D86C4A2617F4D9B4CC8073CDA0A -:106A0000BE43F05C832B33723EF328E8F0CD315C5B -:106A10001E09FD7BDACF674A3CF211E61EC2B6C6FC -:106A20009DBFFEA7553A2A48759849AE3544B1CD69 -:106A300012AEA3E27E36B677F9753482D305485D8F -:106A400005E9F3E8144732D285A6BF86B6DFAAD29D -:106A5000D7E0A8F6F9B8DEC1B120DF01C4BF895480 -:106A6000B251EFF9CD9556C9E3C0FE2E19EB2D5664 -:106A700026A17CDF6C90C7117E827E7F4F22C232BE -:106A800090857C6FF8B2C0B7B83E44A78871FC69A6 -:106A9000877DBFA3C20B55F181FCBD1F9F49C67600 -:106AA000E25391B51CFF42F50CAD5FA87E11AA57C9 -:106AB000F4B6BF3D17B9BFA3292E1FC98908266D9B -:106AC0008EA1FD2DC7F2B9FD8D628A01FA97FFF202 -:106AD000F24DA84F1EAD57769BA1FEE81D36EAFF8A -:106AE0008FDA6FE83EE75755E8F6798E6E5A44B272 -:106AF000334EB56426935D07360F83FAA3B7461865 -:106B000010FE4753B8BE0016A01DF5C46DAA1D891E -:106B1000FA383E511F6723B93E8EE5A755BB12F5E3 -:106B2000717C7F5CC5BFB248251AE57277BD5DDA1E -:106B30008CF0F073BAE9AC1D4670003D81F36355EB -:106B40002FE89402F6FE417C1AE4C77D28EF58ED49 -:106B50003086F65D67CB51BB211DF192AF4F6BBF05 -:106B6000C2D4C2EEC0760F0BBEAD306ED48AF7F23F -:106B7000E2514EB7A56408D06F41ED69E2870B6C16 -:106B800003658672DCE66A9C88F5EB53A4D5D02DAC -:106B9000AA2DA3B316FA2FF68E24FB798520937EB7 -:106BA000CFEA05B22B996A1F2CC1BFA0BCC4F6C6A0 -:106BB00070955F1A905F2EBAFF8EC644281F36B0BC -:106BC0006E11405360289A8AE5820D310E0FCA5B20 -:106BD0000FDF0FDB087CD4DAC3474F4F72B26CA4CF -:106BE000F7B3806F30FE68581BDA512B4CED0AAEBC -:106BF0009F81DEB195E17A9DA4C7AF52F1A2B3EDBA -:106C0000B05D56CF07F5F3E1AEEEC3F7E0B9DA0CAD -:106C10008E6619E5BBBC5F46B8BF2532D4678733A3 -:106C20005EBFDCCEEBE149FAF1F24DA28F917E5CC2 -:106C3000363080FAD77A91F8E2E24D250351DF58D9 -:106C40000C65945F1B702AC0A7C6B61CDEAE35EF7C -:106C50002137F0D3648139911F1D33068A101E2716 -:106C600037C5F7AF477DEF66CF0806F5559BEE4970 -:106C7000C6E7C94D11F3908FE74A45B931A8FF6CBB -:106C80008CC940BB5FA3B3F46C2E0F6EBA39271EBC -:106C9000E5DDB2BFEF795402B9BA187054423F48EB -:106CA0007B94CF0D4D96ADDA9E2C026AD9E35C231E -:106CB000116EFF62D8397732CA61C1B72D91DACB34 -:106CC000F1521F76F371B42B014F6FBEFB431AE7ED -:106CD0002BC3DEC2F9D07FD9CDCF47E338FFF260B6 -:106CE000C70409DE1F1BEFCAC4F13F17366D93D0EE -:106CF000AE5DBF692CCA8FF1AA7D54D0DF39773ED3 -:106D000087AF63B3DCFB7CD5DB0582A7565EE0EB87 -:106D10006766A897FA9959C2A7C4480F3E29B25A84 -:106D200094EF9A5EA2BD9F96CDF9CFC97E2DC9780A -:106D3000FE4BB7AD4B46F9F1999D975D5BFEB4F8FC -:106D40004E5887ABCD2031C03B979191DEBBC8CD6B -:106D5000F569560DCC24B167FEA2EC2882F3D2F57A -:106D6000993AB9878E197CFF9991E5E33A867ABA08 -:106D700033507FFAC8E85F8CE7FA11E8A7E8974933 -:106D8000CFE6F8F7518B3815DFBB57080CFD4F1FC6 -:106D9000B53C6F1FCEFD28E4C7602F9B7C5BA1BD77 -:106DA0007D7CBB1FF9DECD2FC48C4330E689E9F131 -:106DB000883FCB7798A60EE6FA145AD36C99D16F18 -:106DC0000E776E37A97AD4B9F20BCF9A11EF973DAF -:106DD000D54A7E0550537CA8DF2C6B7FF68D413061 -:106DE000DE2DDB2B32711EADFD2D2F703844B080AF -:106DF000B92448AFAE18D5BF7130F0C8E5D9F9AEA7 -:106E000007511FC273BA12D424655245BD119F1297 -:106E1000ED9319BB491F07FD8AECEB9BBD7CBC9B26 -:106E2000471D6C4CA57D15C5B2A0F3BF2DDB44E713 -:106E3000A5F5877D533F8FF5EEC702B05EC563644D -:106E400011D742D9C83EDE86F063D1D256DC879195 -:106E50001D7B039E2BC57EAC199E1B6B96FF2BB52D -:106E6000AFB748223C3D37D73D1380F964913919BB -:106E7000F47767D7D0786E33973FEBA29E7EF846C3 -:106E800028D7CEB13900BDA11C4DF0D9F90B03F1C3 -:106E9000F944D6BDC700CF78065404001A92EA6AB6 -:106EA00021BEC3383F5E799BEC437E0C1C5C403CAA -:106EB000FFE6951399B8EE6B87064E235E99EAA715 -:106EC00057E402FDAFCF56E1921EC8C4760376ABFD -:106ED0007CCD7880E4A32941EE8FFA8A1FC7C2F5E2 -:106EE000FDD54078B053F03F8EF36A70DAA7D2FB3D -:106EF0007319AE4DD9F05404D3ED7E683F5B8876AC -:106F0000E07E0FF417D3C60D433FC4C72938AE1B2C -:106F1000D0561CDCA3C766AB4B370F9AB41EE132C8 -:106F20000500CAAE065B26BD3F3342F95E66E8B691 -:106F3000C03AB2BBFFB2A91ECAD2AFFB3111449511 -:106F400027229965C3F8C26ED828EC6777FAEE4518 -:106F5000B8CE7BBBAD0CE1C4AC7A3DD76C48F4FF36 -:106F600012F1B926DAC112500EB567203F62B7D8C8 -:106F7000C83FB3E06C20EDE72897FEBA97F4F49F82 -:106F8000A5BA5E46B80E1295C32EA8BF57F20FFBE6 -:106F9000158E5F1BE5A8E7728405AF7FE71D7F8D27 -:106FA0008E857EDF748F303E03EDBE51AC0EF4E76C -:106FB00075DE39E6B5ABA07CB52A4F42D7F54D82D8 -:106FC0006C44BBE39B6EAB1FF5906F6C06F2736471 -:106FD000EFDCF321FA21B3AD36BF188DFD4C5F060F -:106FE000CB1B762029E6F8181231EC0780E74055D4 -:106FF0002E5DDB4F6F3F7666733BA853E53F46D966 -:1070000041703EE536B266C44306659CD768959AE2 -:10701000617DAFDAB62D40FFD5A9EF53FBA1DC3877 -:10702000B573583F96DE3B5FEC407D02F484884C9C -:10703000E5533C7F4DBE96AA708968B9DE84F0F0B6 -:10704000003CD0BF566A33F82DE85F9DA38703ABA1 -:10705000ED2E47BC61866807D20D9E2F9EBF2C186F -:10706000BAD955E79FF7756725FF2FA1BC00CE134E -:10707000E15A7EEAF8E5BF62746EDFE23AE01C1B7B -:10708000AE603DE7F7BFEDBC98D1D184E7B052B414 -:10709000B7E039788C5CDF73036E6D8DA16EDBF029 -:1070A0005C567A86D3390DF4009F403B0598DAE6AA -:1070B00038E42B07A9FD56CD9F36AA86F84CB9C7F0 -:1070C0002221FCBE8B8CA6FE0CCED534281C9FE161 -:1070D0007CA5B68A115F59985E23E0B927E00CB011 -:1070E0009F4E43C08EFB0C44801609CF6B725255E5 -:1070F000FD1B3882EA67C5FE8FDC61DF8CFC46B47D -:107100000E7EE4188822D6D41D3D1AD6D526B07638 -:10711000DA9749E51F4B6DA4CFB5C5F888BFB59583 -:107120000E71E05EBF616A7D7524F197AB0C062A93 -:1071300077CF1F48F6585B0CB0561C6FFE68D21B09 -:107140005EFC3B8F9774A7315E9FC146ACC7FAA225 -:107150005134DECB1ABFBACF4EE3B515298991540D -:107160003FD080FD5B535C137388AE793B503CA8E5 -:10717000DD860D4A229EE7866233B57B4870CE5F7E -:107180008CE35C6E23BD31303FF2E96DFC38FDE8E5 -:107190005FEAACE5FBD6E840F3AB0F751F7E18F94C -:1071A000873B1B4E04ED43EBD70B10AF1531DA01D3 -:1071B000287CDE397F770ECF59370097C545769208 -:1071C000BD2EA73104369C9FC4B2114FF6003CA1DE -:1071D000BDDB04E71CC7CF79751C9E73E1A6E07385 -:1071E00086F1DC2BE1BDB03CDA214CA2731E85E3B5 -:1071F000D7B24807DAD7E7CEEF555F063E4583237F -:10720000C102B0F83CD5353F27AB478E3CF209ECC4 -:107210000FE0526E0964B5A07E6E60D5ED61F8C0D6 -:10722000A21C6E1F48ACDB84F275A186FF7521F8A5 -:107230001F1812733C4AC57FE8F74ABC73319EC3DE -:107240005742C7047CB9F76FE2BC70E3DF9CC3F917 -:10725000D68138E7325CDF70E3EE21B7A1BE7187DB -:1072600085F45F7676CF109CF77729CE9FE378116F -:10727000C3BBC9BFDE99D86DC2FD75CEFF3C09F511 -:10728000AC85B57F22FABCD8F5AD8E1A6B42B91920 -:10729000939F610A40FFF8FC8CD7F15C0ECEB2C818 -:1072A00096307E905DB32626A13ED4317D6212F2E7 -:1072B000CB8E245833C953871DF9A869FBE5765C4A -:1072C00067477E26956526ABE5923EF9EB17C05FD2 -:1072D000FDA0087C06F61A3E4F80BDE6077EFB291E -:1072E000D86BF83C0AF61ABE3F0CF61A3EBB56396C -:1072F000E87D47FEB0ED8817675AB81F6591D11138 -:10730000562F5BF694C8FC1A7F83FF6EDA12A52B0A -:10731000576F8CD5956F6C030CB2F694ABD60ED329 -:107320009535FDB3D23B46F7DE5597A92BFF3F03BA -:10733000DF260E5FF497FF6F822FFED682BC2BC133 -:107340003F00BFF7654D233EDA21B09A5878C64812 -:107350009CFF199D02F9DDF0D70272BB18FF00BA3D -:1073600031DAE406ACF742FB5F435BB47DD1FE60EB -:10737000CC61AA80F7A5F91112CAF3B9AC86E86C02 -:107380001E6BA1E70DAC9D9E65EC003DCB19A7C31C -:107390006F2A0213F0F9719CEB53A4D36556D7639F -:1073A0007168B725B946C6223FB2F527BBB4B7739B -:1073B000420D9BA97AAE6D82BA2FF8CDC1B543BFFD -:1073C0008351636FBF5DEE99471B1FE63B8D7CE3E6 -:1073D0002B139F675FD6C424E40FCC3940674FF569 -:1073E000365FAB2A272BF2399CD0678BE563A50269 -:1073F000C58B77B55ACCE85F38B6C6A4EAEB77936D -:107400009D7BF810F7CB1C6B98968CF857DF3A32BF -:1074100019F1FC98496EA805F81F9B0CFCDB417E16 -:107420001C07CA8723F976EA0F92223A03CE6D91A0 -:10743000BABF23B2C37C07B42F4D1499DB81F1F49A -:1074400094685CBFB6EFD07557AEB5E8F060F6242F -:107450007DB994997BF02D05CFDBDC538F7A925860 -:10746000D6CFD587DD5DFBF1D2FDAF05E16B72AE06 -:107470003D0EF51A36914DFC41ECE9DF1B7CB57CE5 -:10748000060DBE1A5E7D9FE31C999B45AF29DE86E3 -:10749000717494C71DDB391C5BA3AEBDEF2A80431A -:1074A000F1FB22E3702E777F84F8BC83FBF543E782 -:1074B00009205D8F447AE5745DE17D8FECB78575B9 -:1074C00045265C5FB1AD3B09FD4EBBEE1A9984E7E2 -:1074D0007270D6C824E41B7BA68F7C64058CDB55B8 -:1074E000203A2C804FBB0A4EDF87E58E3A51C27995 -:1074F000BBB69F56F94BF7BE89B0BEAFF34D24879C -:10750000BAB6FF73F84CF10EE03330FF191FE733C2 -:107510004B8C4ED608F32E01B8A01DFFCFE63717CF -:10752000E233074DCE3CCCDBE8AA171CE87FAB9FCB -:107530006E21FDE120D08785E353C30AE49393C015 -:10754000FE9510DF9C596853766C1F3600E1C5DC50 -:10755000CAC151137AF07D51DD9202F4AFB3B5A6E2 -:1075600023A877A33304E57331331E0904E1A9EBA3 -:1075700005534F99F0DA78241084D7A1787A1BE26A -:1075800069540F9E9E616793CDA9BCFEC0C01EBE0C -:1075900087BF60FE728BE86FC478BF86B7FF39FD86 -:1075A000BD72541280AFDC9D0BF8FB8B7129AF04C8 -:1075B0008420BE72917CAC35EAEF24F7D645FD9D60 -:1075C000E4DEA1E95CEEED9A7EFDEEBF20DEDFC5D4 -:1075D000F1BEA37422E1658709E419C0EB605D6622 -:1075E00034968FAE2D213AD3E827749E2E15FFB521 -:1075F000760B8DDD264718FC74D589BAF34C7B6178 -:10760000413FE7E5BDAF5F1B576BA78DBB3024AE95 -:107610001B3AEE13B9DC0E4DDB52D6E7F86000F6EC -:10762000F4A33C94C81E7C15510FB89EB9013E5D71 -:10763000F91C3E5D05D7133D1ECAD7E8D2C5301EE2 -:107640007B708EE843FDB52BFF34D1E919A0531AA6 -:10765000A397794FAAF4795CA5CF632A7D6AF5E2F6 -:10766000D607E7DE80E3D689C4A70FCEC91C80F316 -:107670007DB6258DE685F550DED15BAF2DACAC1F18 -:107680004EFCC18EFCEB10C001ED8492D212B2A769 -:107690004B4C8E01E1F484D07D878EB76B9685F2DA -:1076A000C8603CE277C57795B046E40B0007C4CFCD -:1076B00043D81EEA8BB7723FF01E6C1F170CA791C0 -:1076C000A4AF1CFAADE040D161DAFE373B9EC35255 -:1076D0009F9E5F2C591FA53BB7C52DB1BA72F1749F -:1076E000BE8F4375C30684CB6BBAD0F969FD2FF604 -:1076F000FC6F52FBE39A7F203DA5BF6E3C04927E57 -:10770000BED490FAD121F5E374E50BE1E361152FC6 -:1077100034397238425E102EBED45568A90ECED3CD -:1077200088CEE3764B749E1AB7FF917235224FCF05 -:10773000AF2ED45FE34F9FE738A53C94A3FE12CA57 -:10774000DFBA587E14248713F270BD01C18CFD5B33 -:1077500055395BDDCEF16E5DD4FD947FF395AAA71C -:10776000035E12BFFF5AE5F75FFF412DFF5E20BCAD -:10777000DCB3636534EAED27B68F8C463BEC48BB3F -:10778000271AF9BECCDCD157023E7EE904F909D3B1 -:107790009D6CEF5B7E7EA6F29D13780E2437253A12 -:1077A0008FA3AAFC3C8CF293E4FD287A1E44F909CD -:1077B000F5739E55F5F4DF0A44FF4B8D2DE1FDD3A3 -:1077C0005BF4FCAA7A6354889CD4CBCDAAB58375AC -:1077D000E54AEF305DD955A7979B796219F1F5130A -:1077E0003E0EC792FC4C5DFB13B21C2D117C381C65 -:1077F000BE36C9D18867477CB1D1C1F4A2F1DF831D -:10780000217038867040FCF496F4892747D5FE5ADB -:1078100019EC4213CE5B6275BC1E877E84B5820371 -:10782000E35498EF3709CEF1C09C8CC79B83F48C4E -:10783000F7F344C297C3DE3DE5987775060C30F444 -:10784000F3FEA96E4F32FA572B9E8A22BD2974DEB1 -:10785000AA023D9FF9B2A128FB23E857F2BEE8B384 -:10786000223C0A62887FCD7956F48950EEAACB89F2 -:107870000EDEC709950E35B9B3C45813F61CAB37E5 -:10788000EACFB1A4A09EC6E978506817FAC173D7B1 -:107890006490A4E7F72B31F2FD2F794A24FFEE1212 -:1078A000EFB7FB30AEB804F4405413FED4E42944DF -:1078B000BC3EEC3419889FB6C716227CDC7344CAE0 -:1078C00083DDDB348CF0FC4853CE409CAF4985D33C -:1078D00089ED168370053C9D26E6277BD54FE7F999 -:1078E000A5B784E4C609840BEA414689E8E2813CF5 -:1078F000EE973F0CE360BD01E804F5E12E9F98EFA1 -:107900000B431F0FA8F31C3DFB2BC29F377C7BA2B0 -:1079100051AF38DCCEC73F5A2745637CEA1D6FA6BE -:107920009DD65700E3A2DEBBE37A929327BC1C1FCF -:10793000719D641F3671F9D1E15D74FF6480C75792 -:107940006B45D23BBF6A2A299C8CE7BDD644E59C97 -:10795000A2528A6F74F8B87C39E43B5A8EE777C23A -:107960000BA70FE5FA1D13F78D8FC37336113E5425 -:107970003DA53F97D2B57AFA825F74C604CACFA4F8 -:10798000B82CA81353D14EAA4C00F909947BB8A087 -:1079900084F22A8BDD7A7964614526C43BD42FB109 -:1079A0005DE52325597EA43FB740F272E10B3CEF21 -:1079B000DAB4E56A9277152D16DDBCC5757AFBA899 -:1079C00032C41E0AB5977EB4BC30D5948793171D78 -:1079D0009A5C60D25484FB1130AC9B33E0FD0B22E7 -:1079E000E5239FF14610FFAC5878EA1A552FBD16D3 -:1079F000F18039DC6C9266A707D159A5570CD1D319 -:107A0000F5F005FDF938EAC74DB1AA1C759790BF8E -:107A1000EEF31CE510F1FB8BB5BF2F5ABF2D57F5C8 -:107A2000DB72D26F3B4A2D94AF79109B04F5DF5582 -:107A30007A3DF9750ECDBA9EF4DC43E7FC3A4ED59B -:107A4000AF730D9DDBA102C067921B0EADDCA71EBC -:107A5000A1F18B4FD57338AAF2C9C32A9FEC52ED1E -:107A6000AD46555E78557971A840B5B7E218C90B97 -:107A7000A3516117C3676E6C8B0A910FB12176D445 -:107A8000E090F3D1CB8B6545AEC8A940F79684D181 -:107A9000BAF726699CAE9CB66527F98FCFC83C9F84 -:107AA000E81EC4098C9794F2FC2C666D27FF71A91F -:107AB00043A6FAC1182784F66852611E89869FDAA8 -:107AC0007B298EBFD7CAFD61D7F5D82EA59DCA9E4A -:107AD00052C6300F66B8360E80A31EF484C1E8C7C4 -:107AE000867912C040C3F61ABE0F99D34AEDB2ABE5 -:107AF000992440BBF4A929C4CF129842FC65E03216 -:107B0000A660BE0BF33D4FED1EBF1BF601781FF0C4 -:107B10005C47767989359AC7BB413EF68D67F53C5F -:107B20007E991F4B7ACB102347CD5EF1566D77219E -:107B3000BC0DD283264F25FA34903FA2356AAC099A -:107B4000F1B4D8E624BF01E0F582DBD15FF98A9970 -:107B5000FB094AB97FF2E0F4898FA0BD3BF6191BFF -:107B6000F9920F2E067C26FEDECDED84BA1237CABE -:107B7000BD3FE7733937E6992FE97E44D776E6C0F3 -:107B8000F29EBAE74FBD8DF43247203BA3A32E8768 -:107B9000F365C69C98BFD9919FB39ACA93C030CE63 -:107BA000407A50561B711D00D766AA5F745FD67865 -:107BB000BA6F42F89BA0E6194978AE893DE5384591 -:107BC0002DB3ED544E28E0F9817F54F58376F53CD2 -:107BD0007FA7DA41DB54BA6953E9E6D72ADDAC095D -:107BE000F5876EE47433C2E8B82F0ACA23DC7692B4 -:107BF00033FB0B8ED2BA81FE258CE7A64C179BC7B0 -:107C000003DCC65802C4A74B40ECAD86FD4C29A846 -:107C1000A7FCC51217A37845F19C7A5A5F00634B05 -:107C200057A1DE542F886A3DF2C731B17E6A5F6C7E -:107C30006512F62FC97F7617E6E196BA003450CE6A -:107C40009D532F107C2A603C68BFABEE011AEF50A9 -:107C5000355FC7413BEFDF51C1243794D358FEEE67 -:107C6000157C9D4E8C871EAA7B7E17C17B0E87F7E5 -:107C700055270D3A7ACCF047EAE87AF496FEBAFA3C -:107C800091EB07E9CA039CA9BAF6B1F97A7A8F1C7D -:107C90003E4E57DF915F6240397B668E96DFC3FDB3 -:107CA000629A5D37E5199B01E1317796A8F9710D6C -:107CB0006C205A5D8CFCBE4DAA9EC85A8631CCDF22 -:107CC00078FC4E03E507AC99E3B162DEC3997623F5 -:107CD0009D178C4B7CE4D04E238D6B4DF10AE8C789 -:107CE000BC17E02C06E97F4D9A7C53FDEAB81E6371 -:107CF000D07AFACB0C33C6CEB56F53F1E901751DBE -:107D0000C0B7A798705E27C793D802663041FF01BD -:107D100073B89C0EA5CB76B5FFEFD4FEDB547CEC9C -:107D2000CA7F7C7524C2651E237D244F5CB63A024F -:107D3000D751C0881EDBFDBB2383F5C73FF636CE87 -:107D40009CCC3C1AC7CDF9E8E8D9822702CF7563ED -:107D5000E0F377E1F9F2578DABA361BD4F08AC1D9D -:107D6000294AE39F9AFE7DD5D74D543F7A1C9868E7 -:107D700050FFF2D7CDBCFD0426A3BFEB8FAADC6970 -:107D800052E9276D4B3AF917CFAC3793DDB3AD709D -:107D9000C9E63658EFC899773DF102E24BE15D7FC5 -:107DA0007941EED1F34B0A133B317F7FC42A3B4329 -:107DB000FEA0CD9BB6E5CB6C5AB7646488A74F6E26 -:107DC0007DB112C7FBDDB6488302E33FB9D948FC59 -:107DD000E5B27B1FD9BC9E9DEF8F29C9D7DBF9BFC8 -:107DE0005BB3EE89EDF8BEF6F9C78E05E5E974CC14 -:107DF000BA2709FDA6075755B7E5A6F5CE3F4BCCE8 -:107E0000CC85F1BBFC97BF7CEE1D98FF03D765E3E3 -:107E100082ED80CFA7727DE7E0AADAB65CB0534767 -:107E20008BEAFD15A37B35C263F44B0365D4DF8079 -:107E3000148C2E8065FE8C088302FBFBC067DC443B -:107E40007C60C69A343CCFEC270B769FC4733EA46B -:107E5000E27B2FFAC841F59CCE954D32C1DDFD8AFB -:107E600095DB378A9C44F6B1434E2A0ED2E70EDEEC -:107E7000A5C5971C9F201F2F2E8BA2B8B216771175 -:107E8000F3BF6D403EBF70524D9644EBD7C7F1072C -:107E900021FC3231CECBE3F56EB791515E106C0D03 -:107EA000E964A5389AF24D3E5CFA0B8AD7BBEB2DFC -:107EB000525A1CC50D9EC1722DF01DCB788AE3FA73 -:107EC0005068274DE37E84D3F33C8F98E5DEE1EFE5 -:107ED000BDC0F998D4F3097D9F348D9F8B07CF25C2 -:107EE0004D772EBBF19ED479E7126D25FCD2CE459D -:107EF0008C6EA2736156DB28CCFB88E72885FBD902 -:107F00008772A8F310F7977D50765BFD4A289F3A59 -:107F1000DB8F215D687195F2049E7F4047027CCB28 -:107F2000A4F68F57F56EE463A87797AB7197CE05EB -:107F30008CE22EDA78676AFB497CBC5B486F2EAF17 -:107F400001FA475912F52AE9170DC3787E44B9ADF5 -:107F50007B01E5AB0A0607C6CDE343F47A37ABA154 -:107F6000F5C6BF2F923FDF10B596FAC70378F0FE33 -:107F70002166E8B260BF1218AD984F42570DE52058 -:107F80003D4BCDD78DAF7D89EB4739D03351379FEE -:107F9000F003ADDFF3A9887CA0D62223DFC3DC2C5D -:107FA000E4DB04BF14C4A375D45FBA8949788F8316 -:107FB000294CC67B9A823A5FE8FA613CAE17827E12 -:107FC00086FB15EAF8FC1B67F27B206C279383ED98 -:107FD0001616BC9E61BAB2EA27D3974D09669D9CDE -:107FE000FAE06C49BF9A3EFC35A1FD0DB2B36FBFFC -:107FF0006F7590DD95DAD35ECB13D3E03CA8D672D3 -:108000005888EEBDDFB222E5E7D3804E6DCC99FDF6 -:1080100036C0C3F5BE48F2CE10B597E01188E0F047 -:1080200039A7CFCEE3FA2E68E7F5946F0DF20ECFA5 -:108030000FF3B44700BE33B73E4F409B578B2F75AD -:10804000AAFC38901258E00C038F46A4DF2CE4E71A -:10805000DF50BCBB1CF55BC0E5C0EA2F74F73F4E98 -:10806000164D69C47587E621687AA976AFB4D3CD79 -:10807000E56CA73B93F8CE19666F21FD3F94DF189E -:1080800019E57DAC14231DCDE4B7BB9BF2466ADD38 -:1080900016C902CF590EBD3F66F624BD3C28526278 -:1080A00043E485DEDF55EAD4C78986B7DD41FCEBC2 -:1080B0000CEA4DC4EFF87A8C6A5E9909EF978868EC -:1080C000AFBBE9B957E5CFEFAA7A6604F257781F3C -:1080D0008589E5808F7616A0723F44F96198D22E8B -:1080E00053BE632C53A83C80B9A8ACE54126321F8F -:1080F0003DB5FC962416A0F250D487442429999EBD -:10810000C3D00E19867A9EE35CBC87F22673522890 -:108110005E50C4944FB05D41E65724F70AAE67EA5B -:108120003DDC138B14287796B29E7BB9986792C773 -:1081300054E4FC7411DE3FEE9CAE958FF3F214DE36 -:10814000FECD3F7DF138DED305FEA5D67FC6EBCF51 -:10815000954F2E9A82659381CAEF637B280FC8538F -:10816000DE9A06E7FFC9344678E4C955DE092E0FCA -:10817000CF55F621DE68E5095395FDC1E59539CA6D -:108180007BC1E5C773948EE0FE5D79CA215ECFF3B3 -:1081900097DE37294968EFC2EFB7C2048E87F87BB4 -:1081A000C3E4FA04DB294F09042F0BF0ED66E2DB90 -:1081B0004E86740A6463C53C22E033E6DBA19E8DE3 -:1081C0003353BE9F21CA96DC973F3294BE0226B637 -:1081D0001DFD744546D717440F217C4F70FFE9AF52 -:1081E00098C703F4908D7A7E408D8704EAB83F40AB -:1081F000A313ED7DE87C17C27BA604F979537BC6F7 -:10820000ED6DFDA1787C40D5F70EAAFADEFBAA5FE2 -:10821000FADC7E03C698E3D61EFAEE9D7F1AD9F1EA -:1082200020FE79FE7E8F2E3071F921A1BCE88C08EA -:108230007F0FBBB7F5EDCF991A974FF95E43248AAC -:1082400033308DEF737ED3897F021F1CD34FB35F12 -:108250001D5684431A4B98310AE66DCD67A4BF7A48 -:10826000727717D3F70DCA4082C1BA8EAE38861422 -:10827000C78467B83DD192C468BDF6142902F5A53C -:1082800006956F5A58CCF4E1B8FE214692B7A1EB9F -:108290006E88F60918571CE48FE0FE8D38E68B8057 -:1082A0007106E53BF2296FC52D4AF9582E6385A367 -:1082B000A05CD926CAF930CE9EB6125605E3564DBB -:1082C000023E4719E93C9FA2BF8AC7632C8CF22D5E -:1082D000D60DB051BCDABB66E4AEC5C837134596BF -:1082E00006EDD31BC6E5A3DFD363EBDF9F624EEA47 -:1082F0007A3C36C79B780FC32D19F83D1249B162FD -:108300001EFAA615C67CE4E749CF8E8F1683E07F60 -:10831000D47B2A02F3DB1F930C54FF585DB6F5465D -:108320001BDE23F42B9467201D516C30EF0668137D -:108330000FE3DD5F7DA46504EB1D1FA2F3CD3A3C86 -:108340008D729843FCA07ABFA529443F28C957F3F2 -:108350003426B00978CE573C71D6847AEE429B4CD5 -:108360007EF4EC2681F25302BB1CC9784E47EF1B0A -:10837000497E736F93A8FAAD1DE4B70E24B164BCB7 -:108380005F53D122905E2C7ABFADC77E4347C98927 -:1083900038CED0F1DD89C1FEB2C7EEFA4504F25104 -:1083A0006F9941F573331A4796156B0AECFF53AF7B -:1083B000C0F3274C9280F798ED0F8A11B8AE2E13B8 -:1083C000F75334033FC5FBB9CD538AFBA443D3F71E -:1083D000B0CE20BBA5212E3512E7EDC15F85FCEBA9 -:1083E000C75A32293EB2B9299BF24142C7B9771523 -:1083F0006B47FBA46195959EE7D5273B931DD0FF66 -:10840000D3D6298D20A4D8A7BB9626E0FDA0C52DE4 -:10841000161611068F8FB54EA4F916E33D669CB76C -:10842000A5C88C72645ADB1433C2EDDE55CAB3C1E1 -:10843000F31416BBD6205D46B53C4B7862637E379D -:10844000C2F3DFAE519251BF3896C6C2E6493E90A4 -:10845000CFED8477AE71D27D924F93C2B75B97CF49 -:10846000F335A3A7CBFCFEB891BDBB04E05C01F4DF -:10847000540FAF8E36654623DE9AD83262521F946F -:1084800095B8D19E3B8D7A3BF0F3C6BBE6AEAF828A -:10849000760D778FD88FECE30A33D79BD99F45A20F -:1084A0000BD00B2B903EFF638E55F204F15FD41F6F -:1084B000155D7E1A971BA626D16F067E6EDA79FCB3 -:1084C0006F68EF20DE2A41784CBF09AA5DA0E66BF9 -:1084D000244C206D9C7E0D33E6FAFC0CE32E8BAC15 -:1084E000789EA17AFA797872DE3A82C6473D37974C -:1084F000291141EB0096E0277FB98BCF7BAE9D5AC7 -:108500006F0406F34390FE1E5AAFED63E47A3DBD5F -:10851000BE93CFF542806F9FF1BACB7CFA7E9FE588 -:10852000333AB7D1A2B2FB38CAD97522E5558F5973 -:10853000C7E3FF678630F213F5369EC67FF1671CEE -:10854000A8C211E0DA18574CE7D95B3FB3EF80922D -:1085500032B6C73EBC2C41BF2EADDD67E7F6751BBA -:108560008BE4FA603BDA67161FF0BDB1F83CA0A0BF -:10857000FC1EB56985D4D7BE43F919FE6458EF6275 -:10858000F5C864C035E40F9FAE17543D84250C9F99 -:1085900040571749FE607F2588FF015FE1797B3EE8 -:1085A00081E0D3DC7A74F3BDE487B13B782B7E5E47 -:1085B00063992607791E90764F9061686A604F7CB8 -:1085C0004A83E3C9DFAE7EFA097875E2A9E55FE385 -:1085D000D332A0321AE1794FDC9C6B13A1DD58B382 -:1085E0002F01F9E9129FE53CBCB36AF89282F7F3D8 -:1085F000F4F59684A0F5C37FCD3B9E585F89726ADF -:1086000087D581A9E1885F6E1D7C02A9F85D9CAECB -:10861000BBFE95EEE7474AA716507E7B9D85EE751B -:1086200085C27789CA07987A5F43A3A78896910C79 -:10863000FD8B4754BBE9C85AB053A1DC586796F18B -:10864000BB065D8E222521CC78E63A33FF6E4EB014 -:108650009D98DAB34F6DFC2E37F74336C2F84218B7 -:108660007FDF85C6DB53A48C990EF8BFB7C879F9B4 -:10867000F42CCC6F5A44FBADDD5ED7F536B4B97738 -:10868000A02B03EB8FAC1D36414047A451A6FB7EC7 -:108690005EEF73244F5AF03B3E60CFB7B41B2350BC -:1086A000FF707B0D14BF6D698F8B1C8E72CA6608BC -:1086B0001B675D349DC3AB479E38A383F5A1E65C81 -:1086C000AE0F09CF94DD9F0AF0F21EE2798A9AFE7E -:1086D00021A97833C622117F96BC3CCFAD471FE25B -:1086E0007AF519D4AB515FCAAA9282E5534334FF9D -:1086F0000E4655AEC38DF730736C8CE4C750BCACDE -:10870000807E0B1BF34D4BC1EF643818E6E7F6078C -:10871000FD4706CC8E6FE3FA4EA4CDE650108F15C0 -:108720004E5756F81FC2337294C2701E63887E6122 -:108730000ED11FC490F282E97A7D42668E6884B3BE -:10874000FDBEBEF338347F2EE84D74CFCCCD00FE95 -:1087500088A756379D4F34181244CF8A22C70DEC94 -:10876000D1FBF13E1BF7AF48142F129446F2DB6F9A -:10877000CCE4FE8D44C6E35E83146ECF8F9DE4A6E9 -:1087800032D80F148762AFB248E4CBCB8A5CB723F0 -:108790007EA4001B40FBAF7F3A1388DC2F512F676C -:1087A000B5171757FACD6EEEFFF31A221D9BC3E0E3 -:1087B000FDAF0BB81F2E720FEC0DF5DBEBAD74BFE8 -:1087C000254F7CAA89F069BC81FCDA5E7640427E46 -:1087D000F2ABE95CDE1F2A72DE3F9DE2B2CE14846A -:1087E0007F82112C2A5076CDAA1F37E9F6D448D4BF -:1087F0008B3F4C7C91E0E106D8A5C17F9B6AE3FAF0 -:108800008F82F78FD6AE26B8CA03B89F4CBB771EAF -:108810002BF1FBFDCDCE536EBCDFBBA22095AFAFDD -:10882000C8382315CA43EB0202D2DD3D76651EEA45 -:10883000254DF273741E2919B201FD65838DEC4D2F -:10884000CB38C69E8EE1F5DAF7A31EB20FDC149C7E -:108850004F52ADEEFB2121BCBE725501DF67E70E22 -:1088600000643FB48F996A7FDB16933D7EAE0C7037 -:1088700043B8B8B9FDFCC274DB62F770B28B78BD47 -:10888000FB2ADE1EE3A5502FBDFD7E15DAE38FA681 -:10889000849FF74B75DE47DFEA7E04E358FF59CF2C -:1088A000E358BD9FB39F1980B76CB0B3647605F0F1 -:1088B000B9A5E679E1BE2373CD2CCE473A6DED0420 -:1088C0002F06F23CFA2ABA471FAAAF5A918E4E4B96 -:1088D0009BEB27CA9C8F644DA0ABFD1CF742C6BD25 -:1088E000B0DEEA4840FDD3B3B4BB01F98767D7D205 -:1088F0000FF15E7A799999F4D67263CDBFA31D64A6 -:10890000DCCBF35FF01B13880783801FE17DD36905 -:10891000D5FCFC164ADC5F2B3CF3B13307FDB18973 -:1089200046C24B4D8F1D6351DCE897DDA0E6B7339F -:1089300071483DDEF7320E16C9EF1B55077A2DEE52 -:108940002F97E7EB2AF03FE4439A9E6B4B37EAF20E -:108950007ACD2179BDC6903CE0AFA7AB79722A1FD2 -:10896000B2678DEF539F7A15EC605CE74EE043F8F9 -:10897000F4833D8CCFDD60AFE3F335B0D7D10FFE8C -:10898000C6AA51F47C739583DEBFBD6A123DAF4B1E -:108990000E98109FC91FCDBF33E717C8AFA7E19945 -:1089A00098966DC3EF76F0FA21331BFFD57D35D451 -:1089B000C7A9EDDDAEC5F49D3AADCCD62ECE4E277F -:1089C0003F38959B67342F46BFCFE652C53A03F038 -:1089D0006480C15981DF7960775A286E11BA9F0788 -:1089E0006768723CBC1DCFF013067A3FCEC0197D7C -:1089F000F8711E12F83AAEDAFBFE16A48F7E4546D9 -:108A000027E27172AA3E7EB07206D7F35E579FC905 -:108A10006FBB86F6755F5FA38FDEEA3D3B0005FA0C -:108A2000F55EEFB5B36BB1DE13139EAE06AA74D537 -:108A3000EBF8366E4FB219406F83B11C6A1F0628DF -:108A4000BFE4746D8E9FC8ED27D35B7712D25B575E -:108A50008CAF1EEDC4AE5D4BD7E3774244A4372400 -:108A60000BA4378C7F68F456CBCF6321D21BFC3923 -:108A7000ADEE3D670ED26302A72FE1999DCB291F72 -:108A8000E32E9E47A3D15B8C9A2F1F25B593BD483B -:108A90001FE6C07E407B1B04BCC773FC634AFE100C -:108AA0000B1CAE7074F723E9AD6CC64FA3B77FBB48 -:108AB0002640F9139D294A02EA335EF5FB813F9671 -:108AC0000ECFCC3073B970B92F11C7D9A08E336DCA -:108AD000C861F2FF15581D22CAB37C99C3356F7C5B -:108AE000267D6FC8A7F6DBED5456CC80E780B9270A -:108AF000C9CF3BC0C0E9F7C1B7CD8B11EF931A0EB8 -:108B0000164D437CB943247D3B745F1F14AA713317 -:108B100081CF0B9A5762701CF11E952EE53B3A38B7 -:108B20009F8F61521AAC27C12D15E7635CE86A0379 -:108B30007D4FA45FD1C11894CFDA78707009986F17 -:108B400082AAAF75DCF9F408BF76D3401D3DB7E0CB -:108B50003E7AA3E70BF10FFB0C41E31394EFEB52CA -:108B6000EF49FE58BF6DAF7EC4CBC3FB25AB66712A -:108B7000BEE131F1FC0F682DE177019A8A5C4FE28A -:108B80007ECED3FF764A7E17EE637934F995138C47 -:108B90005CDFC36F24F2EFE5B809CE5AFC4DD31762 -:108BA0006585E7172517BBFE80E36E62F22E94679A -:108BB00036079B47F13590678817CB8A9417675023 -:108BC000FCE5D2F4C02F8B9457895FF7824F03AE38 -:108BD0005776F7856F538AFE63CF0F48FF65DC5FDA -:108BE000BAB0AC8672B306819D84EB9DAAE6677825 -:108BF00086F07ACDBFEA1DA0C54F9542CC9F8C561A -:108C0000E135C6E26415D0BF0BE530DEDFDB1BF0DB -:108C1000E3BD600BDE2393D08FCAA87F4CADE093F9 -:108C2000B1BFF8E5EB182F32E5D0E744189BC4ED4F -:108C300001EDFE8D94FBE3FC8D87353E318E8D4733 -:108C4000F8241BE40726C3FBCC87F33AF078B21E66 -:108C5000591C8BE272E2A68612FCDED6D2AD9F6E64 -:108C6000427FE8E47FB7303C0FD01FFDC6B0F95C0F -:108C7000FF303942743570563CD71353C2E3E9E3F1 -:108C8000B354FD13F1344E87A76C66783C25FDE79D -:108C900027E069E44C3D9E1684E06914CD7BE978B9 -:108CA0001A3B13F0F4559083B8AF17E72A0366F622 -:108CB0008197DF952A897DD507C507C8EE1BC12698 -:108CC0005983BF7BA83D5B515EF6919FD07FCD114C -:108CD000CA8FF3D49EA63CE52EDB917D6807FD4745 -:108CE000AD450EF66781FEAED3D75B40AEB8C19EF0 -:108CF000DC304B247EB2E70E8BFF3AD46BEBF87D71 -:108D000084F2BA4D02E67B0FAAAE115CC0DFE21519 -:108D1000301DA17F8C62E8F19FC07F57980E903E76 -:108D2000BB0EE4B19BD817BF97A6C9FF31969AB77F -:108D3000D04EF5FCCDE8588DE7CCA45DC88FA603D6 -:108D40003D617CF39A6E906F41E3BDB56312F9D536 -:108D5000AEFB1EE45F901F670A8C185CCEB126EA5A -:108D6000FAE54929BAFA690997E9EA35BAEF8C5167 -:108D7000E32A595B72117FC40A9EA7305DCED0B53D -:108D80005F57964DDF03B86232BF7F3773D464DD1F -:108D9000F8A17AC1D5F03FA47731440F08D513422A -:108DA000F5828533F5F740D71803D9C49F18CFABA8 -:108DB0001B7AF6DF880ED6C91CCFBD65A7281FC356 -:108DC00003F63FFA9B0607E597225D8C3507C83FFF -:108DD000B761BE95CE63C38E27E8BB119AFF0BE83F -:108DE00086E8686CB64479AEE9F65F537FB694CBFB -:108DF000D950BA14EA5E22FD6FE36CD81B7E6F6D0A -:108E0000760A977B3B03E48760779A19CA4DAF6473 -:108E1000A0BCB1DF08FE086118D2AF42F28925304C -:108E2000C94BF992EFF1EF2932E6589388A6BF4279 -:108E3000798D80F6DD6FA979B488B711F9CCB17A54 -:108E4000327EEF97D377FFF1FC7C6C0E5E96AEE638 -:108E500065CDDE8E49602D98173B18C783B671B576 -:108E60004CF2905FC34FF543F2D9010FCDCFFBC752 -:108E70005731671394C51A45F537BBD4F87A37C50F -:108E8000BD53054724FA3786894E8A7B473389E2EA -:108E9000E283580D3DA3043F671E97C847AE00000C -:108EA000A0BC603799E9FB19D94FDA187DDF68A9B2 -:108EB0007933E5650564F223DE7388DFC3DB60FF89 -:108EC00005C5099AF6F1FB04F724B93FC478E6A07A -:108ED0003A81BE132E56F33882F8A6E89806F5625A -:108EE0005D2B7D072EBEDA407EAD2BCC35BBE81C5A -:108EF000EEB6D0F7E3BAA03FFAB9D6D90D8CE81593 -:108F000098C7397F2AFCBAAE7152DCA2EB6FFD48DC -:108F1000DEB1103FA7C7C5F56F4F9C99E397EDD41D -:108F200027C8B71BE322E97EDCBC6B6BF6211FD997 -:108F3000F09EE858ADFA9FD1FF3F14FFC0FC03B389 -:108F40003305F54E7375783FA59939F767A1BFF4DE -:108F5000AE25097DE951BDC6456C06BF39FAE2E38D -:108F6000220DE53C0EA2AD53DB67A36DB95029E39A -:108F70005F3F312E52D64B5C24502320BF1F8AF511 -:108F800063113EDC6F7DA971919AC24B8B8B68FB9C -:108F90009EA5FE5D0088ADE677505C80CECDD0B357 -:108FA000BE20386EC1F595E35F327F8F7186D96A36 -:108FB00079DF5307BF44BFFEDEDFEE7E0A9FD79DF9 -:108FC0007DAC6C39E045D1243BF97BF7FF32E641BB -:108FD0003E9C3E7E30CB61D1F9EFF187F849EB1032 -:108FE000F8BDFCE0FAA29075651BF5F1805C9BBEB4 -:108FF000FDD4387D7DFE107DD9CC6A084F43F7BB88 -:109000003AEA6ECA936BBC8D39788678D079881726 -:109010002E9B8798C3EE4BC337E64821BA5FF73ED5 -:10902000A77BE72B2BDE5A4976AC81EECF9F9ED7EC -:1090300070CF3B32E28799B9699C7C05F1E8BBDFD0 -:10904000A7BF4B311DC9E5BE11DA57E6F0EF459DCC -:10905000174F50FDF9436B77B5E706C57BEF1DE869 -:10906000721400DE0CB59D12500F195AFB1AD5CFA1 -:109070009D9FD5271EA5D5EE69CF0DFAAE5F9AD17B -:1090800069403F465AED1BF4BE37BDC720BB79FE91 -:109090005E9959267B4BCD534B53F126AD8CFB5B30 -:1090A000A5542E6F3698B87C7343B57815FC5F5B7A -:1090B00068BE1BE7EB6726F17B1D0CB810F22B6D29 -:1090C000BC5079A6C9019BC2F5C8B4B287B85CD1BF -:1090D000F205DB42F3E25C73113E427523B5DB9887 -:1090E000A3B6DBC9F5533683492897619F61F344E2 -:1090F00017A87EDADEF2D398663FCE79F343CCCF61 -:10910000FBD1F6632FE35E971C087BDFF636D56E46 -:10911000ED8C082439B81F38ACFE3EA374EAAD05C7 -:109120007DE8AF98578B30EDD55EB8C4BCDA8D6A58 -:10913000BC488B976AF9B5CCE81B87DFF91C65FB47 -:10914000F30D1407ED25AFF61EBB2380F7DCBD152C -:10915000118ECDECD2FDEB5BA7737E5A5DC0E81992 -:109160001A5F085DF78602DEFE5091F3E1823EE26F -:109170000A5AFB0F13C3FBE3BE2DE4FB3F775F29C5 -:109180009FEB7D8A4961E1F240B57CF7D0F7600F33 -:109190003D89EBD0CAAEFA34F2DB794C1C6FDD327C -:1091A000FF9EA0A63FDA507F243DAA85EAA3ABB973 -:1091B0003EA9E959921AD708A527A08F3FE23C8221 -:1091C0008DD3ADA6279EA38FB9401F409743188F1C -:1091D0002B19D4BCD121569E827EA97AD4F9F6D31C -:1091E000F7F64BB29FEAB74690FD54BDF92DD4ABCC -:1091F000D6D5723F61A7BDE62DFCFE81FB3D91F403 -:10920000A6DEFA6B76D447857A3B0AE38A888FF12B -:10921000369F205F8E7654C0E482F595A31D65C30A -:10922000BC555700E1166A4F75DDFD05E5BB82BDF3 -:1092300079B820EB1FC01F42FC4B8DD3393EEF1A8B -:109240007E8AFC26622DB7F7C45A1E0F3596F1B8F8 -:109250008551E17E1433C82374056A7E940D0EBDDA -:109260001FA52B89FB51E2736BFCA8079A26592492 -:1092700085E423F7AB6879ED632CBEB7F03E862713 -:10928000C3C8300F1D1455B2032D6A7C03FF410B78 -:1092900094579ADF24346FDA16E22709F5A358674A -:1092A000E9FD268F0AF2BD93619EE7D7E7BD83688B -:1092B000FB878D8BA3D06FF292AF61A6EA37791846 -:1092C000D7B3E343EE37E9DAC1ED22172A305785E9 -:1092D000C3BFF3E254E407B966DFE12AF483687E92 -:1092E000A8F86A151E6ADC07E18BF014F3393C63B9 -:1092F00042E0E91DA2C58554780EE0F02D2F709252 -:10930000DF4942784A3DF0D4FC54DEBDEDF47D6D7A -:10931000CB1D16D94DF0FC92EC5513C213E1FF138F -:10932000FD50E342E039EEE1CC07F03BC1E31F29F9 -:10933000E9C0E7844DB7C5DE00CF495B1F28C127D0 -:109340007B93C709FE7316E75798D91D4C8F636747 -:10935000C8BA3883064F0D0F7BFC778CFCB1E51241 -:10936000F7E797AB789886700BF6E739F470DBA0D7 -:10937000E64B1A736BDC68EF0E0D819B86871E84AB -:109380001BF2BB18B3EC26FF5D9D80F6506F78385A -:10939000B4EDC7E1E1FC59AA3DAFC2EDB9F599F7CB -:1093A00022BC5ED858F20E3E5FF4DD1685F0DABEC0 -:1093B000E58199BDC02D3198CFEF991E1E6E5B8B54 -:1093C0005DD5B3E0FD750E9F91F82CE01BDABD9BD7 -:1093D0009BC659F5F1198D3FE65BC3C98F0BFB970F -:1093E00096535EA1A76C39F1C7AE73FCB1DB8E79E1 -:1093F0008817CB1F2D85FCBE7D79ED77AF5F077099 -:10940000CDA93D4CF46704FAA373AB3B6C50F33128 -:109410005804C88BF832E6C7F8F12066F545099480 -:109420009F407CD38B79CEF881D2503F85F4C65FC4 -:1094300005220E261812808F63EED4152407EF9FA5 -:109440001586CFAE2B3390FF67B3EA1F944B9D2D4B -:10945000D84E8B6F2D2B525A67FD347FE1C3D85FF6 -:10946000F31776C6B073FE35FC3E784EED2601F359 -:109470005006D5DD4AF221BE4C61281FB266CAFCF7 -:109480007BB3B912EDF77C7F5B770EDA099D78A389 -:109490003D83F0E077384F67EDE38407572CE5FE16 -:1094A00091CEDAD3B1E1F1A036E2D2FC8C9B757299 -:1094B000D25BCBBF63D26957DE4CFB11783042C51B -:1094C000034D4EA2BC417C3296051E463FF620C09D -:1094D00087881494979C1F8BA0FF44C17EC45EFCB8 -:1094E0008F1A3D74C1DA2CFDF09E70683E400DADC0 -:1094F000FB7459B67F621FEBBBE83C00352EE95187 -:10950000E3920B6B79FE6AE71DDFE5E17A4F978105 -:109510007D0070D95CE660787ED340B10AD882E7DE -:10952000392F6F358074ACC521B578FED662E7114E -:109530003CD7EB00A712FA635EAF1AEF19A27E07C1 -:109540003A04FF01CF3FC77130DE837240F3A3338B -:10955000D41BED88DFCA17583FD65C9328117EBB19 -:10956000BA71FC753BEEA4FC851EFF20CF87FBC9BA -:10957000FEAD6833E5576AFE2DAF9DFBB72A5880D4 -:10958000FE9D3C8A2320DF6EB5D0F71AAA04D98C41 -:10959000EFF717BB8C85A4F738291FD635C72A915A -:1095A0001F6CE9B644E417E58D22C9EBDEEC92F3BB -:1095B000E9EC47F21995EE2E81CF0C2EBC383E9384 -:1095C00054A8E733C9853F217EB67E969EBFA0DEB4 -:1095D000590FF3E4A8F4746EDF6A1C1FE3571119E6 -:1095E00041FAA8BADF503A3A4F2FFDBF8FAE66223C -:1095F0009CC3D0D5ACC21F4757A58503FAA4ABB90D -:10960000857ABAFA1996FF17D2D5CF691F17A02B02 -:109610006321D3E749C7F2EF3C8F8935F03CCBFF9C -:10962000C379D25FCDE4FE8BD03C69C66AA85C00EA -:109630006743E7A3960BC73319E34C964DAFAD1DB7 -:109640002DF3F182FD9D2CC4CFC942FC9AA1FA5D95 -:10965000183FA8CEEFB9F789BFEC1D0D7F3EF9F496 -:109660007F915EBB6FAA40F7C90B477EB71375D0D9 -:10967000A23595EA3C7DFB3DFFD97E4EFC05FB55AE -:1096800043F7D51875B77A6FE0C7F93999E356FAF9 -:10969000BEF9BA1AE640B85FC8EFB9AE8EE74D6BB7 -:1096A00079CDCE57AA1E2C1DCFF3E9D0EF19EAEFE2 -:1096B000D4F2953DB64AD2F38F2856EE8F0DF1774E -:1096C00056C6CAB7D03DC6F3FD9DEF16FE03FC9DFE -:1096D000930A64FE5DC610BF677CBEF261611F7EA7 -:1096E000B3CE1807437E9763F30918AF656733C994 -:1096F000AF33C816A0EF6B95D74E213DF06491EBC8 -:10970000535CA731B7FBAB97C653BE8103870AE50D -:10971000CBA0671E2FFC27FA09FE597E3E5F01F79A -:10972000735DECFD791FC23BAB8F7BF472E0912837 -:1097300078FF68BD9DBEAFB552D5A33B4DDD492D29 -:1097400050BFFFAE13BBD13FE16B3330BCDF76B10E -:10975000FEA3860BE8C5E610FB68C339BDD8F7D673 -:10976000C420BDB86155FE8E6361C6D1F4E29B662C -:10977000EBF5E2721BD78BCB6DDD26B40FCAE3BECF -:109780007F1DF34E8DD5AC1DE5E220A586F4E17872 -:1097900089513EF1FF8FCBB37F685CBE78B63E2E19 -:1097A0003F56CD47411E8FDFFFE9D2FCA893B8DEBC -:1097B000B0C6C8ED15AF02EFC2C4D143E3F243CF48 -:1097C0003E4371F975DBAD748F6FC38E663EDE1458 -:1097D00026619E792253F5B502EE2F0DD53F1E3539 -:1097E00029D694F188EF06BA4F88F704C92FB2DD65 -:1097F000BA09FD4DE9769ECF6DDEFFF256B73148CE -:109800003F043D94F4E2B2007D97A95C7230E23BE4 -:109810007193FC141FAF1308BF46CCE6F4B330D7E6 -:1098200047FAE1A03249E0F7C4DCDC8E4FE671E78D -:1098300048C42F682A8EE2715FE980E8C0B8F37DE2 -:10984000D87432DE5F65FC7B15930DF4EF50AC13DA -:10985000BA13902FB70A4A223E4167A27B8F4FC7A7 -:109860002803F1DF93F22419E8DF93DA93D7988085 -:10987000EB6BAA6F4D40BD70CD6C1E4769CD3B4E62 -:10988000F90FA674D00753E819F6DF1D9DEB14D429 -:10989000BCC0F604FA1E026BF990F06A9499F17F4D -:1098A000E7C7E15F84F474CC46FAC2AF041FBF2758 -:1098B00064B7D27DBC96CBCC8955B09E66BB99B4BB -:1098C00009EF65530FA4C0FBE6015234C601BC2961 -:1098D000A912FA8FBC318D6FA21FA439259561BEE4 -:1098E0007F53D9048A9F379D0506033D3DA347EC6E -:1098F000CF82F76B84007D37C83DD9C0309FB0ED73 -:10990000B2A989C1F7324529544E3A482E88B2810E -:10991000EEF9896A3C5B3C2F9EAD8F4F7F3F9BEFFA -:109920005B662DF3E81E689C59C2FD965F56FC21CC -:10993000DD738B33535E50B989F1EF7E5CC6E85C12 -:1099400042E1E759A58F2B186DFAF5ADC1C034E59A -:10995000619F5D82F8D18030A53CEEAF96205F6AB2 -:1099600038577F92D747F0F2CED94797A01C941969 -:10997000FFF7491A46F1BCCBF201C5C487CB4D8134 -:10998000B0DFF9BDD07A64E653D4F1D8FFE4786B48 -:109990002E33CFF3A55F78BC9E7301F5F912C6D5BF -:1099A000DA858E1BDAEF7FAA7D6FFBFC68F6B9FBC8 -:1099B000719407412AA27A9F0DF564A3CA0F3DD97D -:1099C000137C7E19F9819BD3458C419767FBDFA6F9 -:1099D000F2D6B800800000001F8B080000000000D5 -:1099E000000BCD3B0D545CD599DF9BF7E6CD10669F -:1099F000E00D0CC910093E082831045F1288A04907 -:109A000079046240A94EF809B825E944A346DBB3BE -:109A10009DBAD6923DD932094320989009A9256E66 -:109A20006D8BA9D9B5B547A9DBEDAA47BB9398F5CE -:109A3000F81FDA5AAB7B3C16539BDDF6B83DF42792 -:109A4000969ED336FB7DDF7D0F6626432069F69C0C -:109A50009D1C72E7BE77EF77EFFDFE7FEE9C3B87A4 -:109A60009F5A8073562B6B2A9865C09F73607DD672 -:109A7000E0736AF93FD0FD0B0114FAE6C047DD4DF3 -:109A8000F1A24AF1BC25404370BE1B4003889F935E -:109A9000F0A9050F5FBD74AE182014C4877902AC1D -:109AA000B67006EE4FBB56C7EFF4039C4538B9C6F7 -:109AB0000C1CDE47113040B0C763FF5A35FCEE9DE9 -:109AC000B4EE35601CD367C62BD6BA571F51216E32 -:109AD000CFC7BFCF5AEBFEB4AB353BE499396F6AC1 -:109AE000BB6C3479DE8774065C27E283D163F83D72 -:109AF000FA6E4CE24D3C837FB8DFE84A6D74109FEC -:109B00003F688FF3E2B822315FC7FD66C0CC47598A -:109B1000C878B05E428903E7EFBBBAE2519AFFF022 -:109B2000E3C3DFFA363E3EF29D3DBFA4764149C510 -:109B30005035C2CB341C86403B044A900E4EFA8608 -:109B400078F47CEAC814A21FFBC978DA5B7E678CC4 -:109B5000C99748471C7FC77EC9D4703D97C77354C7 -:109B6000A6FDB92593F62B1F5EC4FB0F6C4FA6FB19 -:109B70008864BE1DC0F19103121CC37E8691B00E95 -:109B8000FEA905C9E39B09BF55D44B18871B3F2885 -:109B900041E7581A7C3F1874303D886E9184FD1F50 -:109BA00072EAB7105E0FED932182200FED74012C45 -:109BB00006F846F0DFEFDE5D02F0853E27E37D64C8 -:109BC0009D3A2AE1FB11AFB6B993FA4B1CC6511D61 -:109BD0000463E2B90EAEB88ACF65AF3778ABCEEB8F -:109BE000C5D6A9F9E0A1719381A097F9E88D2AE281 -:109BF000A3B765E6A3D4FDA7F2DD5C7C5618CCB113 -:109C0000F0300AC115C89EB279E20CEE0FAE763084 -:109C1000FF2CBFDAC1FB3B5B8003A4D9F9B0AF07CF -:109C200017B87A866F548BEE7BFD2DA708FC6CF37A -:109C3000D4D171B3A882D685F05839F27320797FD8 -:109C4000F6B8926979F83B5850C9723726E3595DE6 -:109C5000A371132AA81D37256CCB1EBD5FBB90BC1A -:109C6000B820017E11C1053E7FAAFC3A21C448DC20 -:109C70009359781B9DBF6FA30AB29406DF73F40F4C -:109C8000EDBCDB24FA473E0F4629EA096720992FED -:109C9000832F9430FFC80332B8A444FE6A34895E2F -:109CA0005FBAD539AD7FDCB61E23BA1B45E0C07D57 -:109CB0001D7E4B66BE391CDCFB0B99E4BB51D525E0 -:109CC000DC7F46ECEE87DAF1FDA1D765631087777C -:109CD0003FB3EB67AF627BBABA788D544C44322302 -:109CE000DB71FCE9F56E63D010F2378D97626E4C34 -:109CF000F79A99F50E5517F37A515C4FBA001F2861 -:109D00008DEA0744875478D3FABAFBF858C3EA04BB -:109D1000B95A187A2188E71BF2E0263CF4FE24BFEA -:109D2000874AE4CBFCD9D7418C325E7E465F71DC3A -:109D30005F5ACD9304A7A9B42A9249E7826C207C8C -:109D40007CE8356EF4E190F79D86DB289F99DF1B58 -:109D50007342BC9CF080EB62DB0C135B5A88EF4BC8 -:109D60009CAC3F64FF4A7EBEDD1B541CB8AFFF0CA9 -:109D700016F37AF6FC26F8B2721FBEBFD639DA4067 -:109D8000FC11DD0E5A04A76CF3C614EA6FA00DE2B5 -:109D9000C21BF53A7711C26D7C9E1602A8F50DFB29 -:109DA000C90E553C77A42044EB47CC1F95219E7DDE -:109DB0000255B0DC351EACC7F9BD6FC8C61E7EA209 -:109DC0001D0FE17C252003D1497A6A6D6002F7A35B -:109DD00078CEBC075900EB26011A12F8A976CA0DF5 -:109DE0000D097AAE0E2127F6EBDDF949E337684518 -:109DF00049EF65308D38D277636059D2386F55A5F9 -:109E000046FB6DD257263DBFB9AC26693E3428A724 -:109E100027B0BF16FF11DD65107D5BAE3CE5D84F66 -:109E200098AF40421FDFFF25E8F59FC9C4CE75708B -:109E30001DC94F33189D241F68BC8D63889785CF3B -:109E4000B92732C9909826DB75C9E2CFAA4D454C97 -:109E50001FC973C641F87F0461C8C81715DA848327 -:109E6000E804DA98C4CF516F0C22B2038AC9E3D058 -:109E7000C069511C77056A6F0DFBDE00C4A8BF04E2 -:109E8000623C1E3FB1C335C8166E313FAB058C83B3 -:109E9000F83EB33C2249D8CF69044346781E635C40 -:109EA000A27D6A385F5E492C19E77E41238CF73228 -:109EB0007C730FCDCFEF06AD2F9FF997DF8F7641E3 -:109EC00084F6F32818E092091FA890969216097359 -:109ED0007B25E839A487BE09C62AEA97C204EB2588 -:109EE00034EF12F517C19826947D9CF5374C28BEA7 -:109EF000336EA1FFD3C9CD8CFC2870C6A60B0EBE55 -:109F0000FF56B37C13EAC1CDB7555DD0DF50BA5FC1 -:109F10004C92DFBB37E98C77A57B23CB8BD2FD122C -:109F2000BF1FD814BC6E133E2755E05E75F1F8AF25 -:109F300050053EA31218E8CB40F4D99B02DBC85F62 -:109F400079D66D94B2C8233E892FAADD93AFD48809 -:109F5000F9440F3FD283F09D530E12E16009D10105 -:109F60009FAB48877D4CC718C32D0C83B1DB5A9734 -:109F7000FAF94807A2CB28680B08AF72F8E2E8C0EC -:109F80001F84B3E81937FB470AD165E965A1CBA760 -:109F9000098F174B97547AC0AE5C809AB9F5E95790 -:109FA000A57886B494C882F4C1F348481FC26700FC -:109FB000043DD0AE1B84A774F8A77E4625E87BB885 -:109FC0002FC6133D233533FC9F8DFC2FFA42BE7CF8 -:109FD0004807D11774F293BC603F101CE3F939DBDA -:109FE0002178209FE86132F26CBBEC8249F66B8BE2 -:109FF0002583E9B55446070DFB9952DC727E46D99C -:10A00000AE6781C6F4590C616EFDCEC9E3E7485FC7 -:10A010007B1CA391226A9FAEA3757A9B51C390CA01 -:10A02000F70ED7315FDE035A29F25DA16AB2FE2E28 -:10A03000BC4631227A22BEF608BF49378F90BD292F -:10A04000747861B07266DDA8D308C4905EA7BC675F -:10A050004E84F0F9827CB4EFC60C9E4F3BC5F908E4 -:10A06000A67C05C983908F4035EEC577BE7E0B2850 -:10A07000826F3D3B107F888FADF402F1240DFC1BF5 -:10A080003F7FA45EE8BBCF6E0A3D4EFC42FA89F1E9 -:10A09000678246FA493380F5A6438FB09F7076C039 -:10A0A000A5139F426CC424BF629BB5CEB601D707EF -:10A0B0005256C239A3AE243BEED083D9CCCF86040E -:10A0C000E41FCC77DEA5F23F74E7CDCB0FA87B6A07 -:10A0D0006DF644F9ECE354928FDCC479824EAA3FCA -:10A0E000C47E874A72923B371C678AFF62C371063F -:10A0F000820CC769FB2F64B7909E77A1DD1A447C60 -:10A100007FDA448788F972F23FC89EDF1ECE62BFB5 -:10A110008B5184E3EE8849A383C88F774258253E4C -:10A1200095A02442F4DB1A91D87F2BDEB73D8BFD3E -:10A130000568D0083F52FC06F9DCF28BC0A385A766 -:10A14000ADF15F3A752FE1D50B3F4F88B7ECF7BF04 -:10A15000EB5A7AAA4A27A5ED2923FA665AF445B59F -:10A160001D790DF7E9FC53360C6AE4177FE98D5A27 -:10A17000DC5FDF8F6583E2B34C10F1D50210763CD3 -:10A1800093E47429F1CB58FC33C46FDDD91A9DD701 -:10A190001E07D6B80884D83FCE443D40701D99FBB9 -:10A1A000993F33B354DDF6B721F11C6E89FD608F02 -:10A1B000A572F3D4789CE42B0FFDD8DDC9F02511EE -:10A1C000CF03C7437C0EE9FCF55758FE3ABEAA3BC5 -:10A1D000370FFF3ED57F87C47890C663DC194FC028 -:10A1E000EBB4BC587266EFDBE35193E525659E4DF9 -:10A1F0008F72A7E08FC5187FEDC6FD0E0C1CAD2336 -:10A200007D3392073A469AD0BFF59F248AB3D693FE -:10A210002E26FBD300A3144778401F2CC3BEB3C027 -:10A22000C3FCB3E8BF83F1CF209CBBAB5D9A8E38F3 -:10A2300059FC91A9D5E1FBBB0ADC8689F48D5AE370 -:10A24000230DE86789E5DF26BFF44E6BBF4C0B9406 -:10A2500043B3A588F95DF1B5ED7D8DE2DEC532C869 -:10A26000A4D7E42E83ECD39D1830E4A2EB0E5F76E6 -:10A27000B2DF87FE1D9FC7D590ECF7DDF58833A9C7 -:10A28000EF4CF1136B5B92FDC0A616E075693FB908 -:10A29000ABFE7AF8E0F1B3FE5CA18C3BB43476D52A -:10A2A000C6BFF49487F1FF421EE295F32441F37395 -:10A2B000D877211E895F11235955882793BEEAE478 -:10A2C000277FEF3E1AEF3A8BFC4BE3654FC3E788DD -:10A2D0000E57587802B12F13FFD1BE53FD61578A34 -:10A2E0003F9CBA6F9B0E77D8F859036B083FE89FE5 -:10A2F000B37F609F2BF53CCF637CDE80BCF4831E74 -:10A3000037B7F11E8DDB133D016E4FF6E8D0808E1E -:10A31000D54B3D65DCBEDC63F0F3577BAAB9B5F1E4 -:10A32000319BBEF1E639D85F38B4CBC17902A55C68 -:10A330007BE56AE2DBB764561F1AE819CA52B643D6 -:10A34000A0E0B82B1B955193CE62C53F8B2C3E5B92 -:10A35000EE9A3CEEC279B17C30F6D044B4DBDB2B14 -:10A3600067E29F75938E1939018A771624E50BEA07 -:10A370002037A95FEFBE2269FC066D69D27B9BBEC8 -:10A38000DFA81372B331B03C69FCA186F5F1BBC9FB -:10A39000AFAF7169946F68D25727BDBFB9EC8624FF -:10A3A0007820371BA4A773BA12E8C6E74FA6ABBA4A -:10A3B000E3C271904DE7D11439988DBEA97C6BE34F -:10A3C00035671AAF22AE8C525CA9D3B9CBA56D0804 -:10A3D0006A68DA2F3181F24BF6BA4A35C69715977B -:10A3E0003FBECCA2F8B2285D7CF921E76DE68C2F48 -:10A3F0001B93E3CBAC14BCCD155FBE7A89F8DC5A55 -:10A4000028F26E39AFCBEC07CA8D61B67FB9E3B2E3 -:10A41000B191424FCB1FF392CCE3B8AD552AFB97D5 -:10A420008760220022AF984FF630B7DCC8277DF353 -:10A43000A4CF5C781BC5F94D0EE3284E79B1EE2B05 -:10A4400001F23BF6ED7E34804609FEA7C5C1FA2E27 -:10A450005677660BC995A2A31F27716B8EA6F14F85 -:10A46000ECF176BEF1E016916F3C68E51B0F5AEBFC -:10A470002042D8DE8E54897CE3AF5B742BFF17E15A -:10A48000FCE2E12D6BAC7C23F657D07083EDF8A095 -:10A49000D730EF20FEF9850722F8E880A4654964EB -:10A4A0002FB63834CA1F8F34AE7A97F249FB3CAAD4 -:10A4B00041021FF5ADC927FE92B7A2DB83FDE1C6BD -:10A4C000E19769BE52EAE07E74CB559C171CC9D354 -:10A4D0009A8A29CEDB504C9806F9993FF5505E23B5 -:10A4E000EA3B13A0F9BDD78BF9B3D12735FF2F93E2 -:10A4F00026A6F8ADC41157118EFCFC993F13BCF38E -:10A50000F2F3297EC5A04FE5BC6DFE8FF77E2B527E -:10A5100042AADCE47CF308CA3CE169EB96966C8ABB -:10A52000A7B63A27F2D2D90B3BFF39ED6FFA93FD6C -:10A530008454F8FCB1F36B0ED1D5EDBC2D7EA2B7DF -:10A54000DC381A27BC41ACB198E25E8FB0CBB3E1E6 -:10A5500041F15CB80E22776798190978B0EB1DD7E6 -:10A56000B68A3CB8D1AADB79C6A47A89D2E8E07968 -:10A57000B67EB0F3E3A975127B1F35AD224F7BFD8C -:10A580000CBCA4BA89BC56B5E0191C17A7E6B3E702 -:10A59000AAA3CC95CF6EB6CE73B175937B5B81E7E2 -:10A5A000FD7FCD7FDFDBFA7F93FF3EBF5E34CAF2D3 -:10A5B00003CF4CFE9CE43BBA6CA13E28EA4349F52C -:10A5C0009CD43ACE60868033BC52F8A9C3563FB2C1 -:10A5D00042C04DADEF6458799548EB521187812107 -:10A5E00088AC9885C4171EE5BB110DF96181E71091 -:10A5F000F8B075F9B745A8AD2DD487AA715FC3CB64 -:10A600001C6CC786BDA147FB480F2DF3A4958F8313 -:10A61000AD422F0E10DF72FC04A683E44EB2850417 -:10A62000420EA4D708733EC0D1569FC86769B1EAED -:10A63000DB118F5F25BEC8E3F3F0FC54F85F3B1FCE -:10A64000FE63C4AF510B38C1D98670BED93A5D479D -:10A650008CD07BB7B59E5B8F5593BFF058AB26F47B -:10A66000B0B2D2A0F30FFBD2AFF798B59EE9084B7A -:10A67000346E5197980F6E31EFA034D9795AD09338 -:10A68000E589D6A7F79946B27E48859B5176E17A4F -:10A69000D9D3D3FB4F8E870E48E9F7F9634B0E6B86 -:10A6A0000B81ED11F1C59E347C912AEF2AE53F1113 -:10A6B000EE098B0EB6DEF128E3EB332BC9BE83D156 -:10A6C000CB883DCEE7DD93790BC7C97D378B3C87BF -:10A6D000AA08BD5DD089606AA8BED210E1BAE1FDCA -:10A6E000A0B97CE7E3E162E33DB2379184F93FB181 -:10A6F000F823B52E18A3BA20F9B15417A4FE4E576B -:10A70000673ABBFD6E8BD3B2BFE9EB3B47A8BE8374 -:10A71000F38F545BF59DA0A8EFD43DF508ECC4F78A -:10A72000BF331DECB74ED7771A8AD7480E9623A0B1 -:10A73000FAF47CEB3BB18679D67782175DDFF9635B -:10A740002BE2E79047D459A6EB3B6DFE79E5757493 -:10A7500088C5BB49AF7401E3C1DB340C3B299F10B2 -:10A760001071C6892A97E0AF9D92159F4103D87A50 -:10A770000A3FCD5DFAC3B9645FDE714129BE5FFF58 -:10A78000C4EB0AF587F31D6B287EBE569D78F05A00 -:10A790007ABFC6C9FAA30E29194FE28FB8CBC145BB -:10A7A000F0886AB5B268E312B5F5EECC247DBD4100 -:10A7B0004B8E3F86A64EC8D9C49F1A1812E279A8BC -:10A7C000CE30B349F71813BDF47C68836E0CEAE40D -:10A7D0000F27C729434DAAD0A745C2EE0C1FD71F8C -:10A7E00026FFAABF3B83FDCF03050E71EE1218258D -:10A7F0007E68D293E39AE1B1E27D2524673127E7B1 -:10A80000CBBF3326C66FDFBD7294E252CDF257B78D -:10A81000E7AF673F14FAC4B89BCB96A79C7F5C2335 -:10A82000BE88ED7402E1BFBFE0F601CA877E1075F5 -:10A83000AE2671196AD3997F6DBA6DEBBB93EB4469 -:10A840007D2A70DD74688BCAFC3F94F7C1913B4848 -:10A850004FE72D603C8F6C51F34309F270A2CDC5D8 -:10A86000F41ED922FC8B3C0784C6D2BC3FD126F40F -:10A87000D027EF013E4F16DA651D1FE94A38EE2258 -:10A880007C1400FC231D27F0E1437CFE460794E284 -:10A890001687FD5DECBFA5F2D9785B69525CEBAA27 -:10A8A0007624E1D1E90A8639CF7D33E8A4AF1A1ABC -:10A8B000B14FF17D970AC46FAEC0FD7CCE1CEC6732 -:10A8C00060DFDD188B28D87797845693DFFAE2CEC5 -:10A8D0008E01CAB3B8FC0E8DF8CDD57557B095C6AC -:10A8E000573A2103DFF7812E05689F1109485FEB76 -:10A8F000106A247F7D38E0D0286FD31C6DDF41EBD8 -:10A9000037FB1700D1796B9383D73B6BAA9CB4CAF2 -:10A91000234783F25F0B3D6C77DF77861FEEC0F134 -:10A92000EF23BD223073AE5D6DC54CA70C3D397E63 -:10A9300076438CEDF05A73BC8BD6595BAD52450310 -:10A940004ED49C3942FEFA4895CB70E1BE466A244B -:10A95000C6F7C755CE51BAE7F003755CA6757FF010 -:10A9600031F246513AF9BDB0DCA48E1FAA6E7113C4 -:10A970003FEC458A107E22530EB65FA9E3FE6CD1F0 -:10A980007F2FE285F01CC1FD96525C34897285D020 -:10A990007D53C1C7EFC076559BC2E3BE90EF885090 -:10A9A0005DA8BF496539E9F78606E8FE4F3FF23BEF -:10A9B000C743FE10F3F370BE9FE5D05E67B86673C1 -:10A9C00019F1CB1B5519ECB757B535DE4B7EFB7A29 -:10A9D000F9A37F798AE2A70295E9D9EF0CC65F2532 -:10A9E000BE6E12FEE2C9250FB0DCF575DD0E8437B0 -:10A9F0008884DFA1BA555F650DC3B7F30DC34B441F -:10AA00003EA9CF7F5F84F21BF16A915F30F38E72B3 -:10AA10003ECFCE2BD5597A6CB92BFC4A29CDBB47FA -:10AA2000117561B9204AFAC04579259AA724E7BB78 -:10AA3000D64D26C7C18B53E2E0D43C13B8C74B5A5E -:10AA4000D19E3ED986F1F17298CE2BD111588E2B22 -:10AA50005D1C2F8E548B3828E60CE76BE5E7CBF1B5 -:10AA60009B961F3CDEE3460E00F8518FC6FD2CF38B -:10AA700037BB7311D45B3D017E7EEBDA47A5C47909 -:10AA80004395ED6E9DF5C64480E0A6EA8B543E5892 -:10AA9000DBB6C0B20F26107D872681F1EBAD5915CC -:10AAA000273E3DFB7BE038F4130DE31E283E7F7EFE -:10AAB0009CF6E9A2FC97D8E749DAA78BF25F627FA0 -:10AAC0002FF7E8DCBEDA53C6ED827610797E5B1F85 -:10AAD0005C89FA00F1D65020FA24FF648773FCB732 -:10AAE0000789BF5C014523F97617C4E252823E18FC -:10AAF000F186DF25BBDC9FE761FE4BDDD7AFDA1CBB -:10AB0000D6B9C2B711DC21844B787F71E77F3DB4A1 -:10AB100094D6794B66BECAE9DABC83F50EEA850C99 -:10AB2000F637843E8CE57938EF30B2B354A2FB504F -:10AB30005B770B47774EB9C7754671DE09D4D7D41A -:10AB4000EF4739A7F3F4D77CF0195AE7E33F2EE03B -:10AB5000FB4D235BDE66B97F030390DCCB28F7B6A1 -:10AB60009CC5DE5AFC6D117F073B9E11E7673D389F -:10AB7000E21D8FD1F9FB7F22433ABC5D2A5DC19C67 -:10AB80009F1F32AA4C1E3FE74F53373445DDB07745 -:10AB9000EC7BDC8F34039462FFEB4ED34D7CF0F5FD -:10ABA000DD8E0BD60DBFBEFBC275C3D12F3BC0A53A -:10ABB000CDECE30A98E03C2B85F05407ECA357D882 -:10ABC00066B787AE6E673F52D415F51ACA39505F23 -:10ABD0005B40FEF3C026B38CDFFB73D8EE0794B165 -:10ABE00038D9F500D5CB75BABF10E1BA27E567E9CA -:10ABF000FE42EAF97B9D13EBF97C3884EA95A9F5CE -:10AC000049C9F37D51DF5F2AEA90767DB2429D38D3 -:10AC1000FA20E1E93637E3A1F7D9EBDFA1FA975D36 -:10AC2000C70F5875606D0768BBC539CC76F2FB9FBE -:10AC300017F550B81ECFB192169928DEB482EB9B5F -:10AC40001BE81C73ED7FBE75C3664BBF2173F33DDC -:10AC5000C89F59F8B4C7FD4DBB90C76B5591B786D7 -:10AC60002C95F5FCFA273C2093BFEC558F929C6CF9 -:10AC700083890D244FBD3EE1B7450F39D96FFB5491 -:10AC8000BBCE74CD534DBEBF90F7F719C66E0413FB -:10AC90003DAE65511EE92FADE6A7DA791FB1B616B4 -:10ACA000DAC780CCFAEEFDD20D7C8FA949CA66794D -:10ACB0005434B330515FEE6A4F7F1FA9B670B2852E -:10ACC000D7F73A80E2AD6886F1B24EF87E4161B8BE -:10ACD0004D20EE2BC1764D1AC073F67A4E337D6A45 -:10ACE0004B5D2B493FED6A17715BD49B3EAE7BA059 -:10ACF0005DC49F852DA12F101D6E82C97AD26F2849 -:10AD0000DA4684EFB588786D17E94B11EFEE72AC37 -:10AD100099C96BBDE40CEDA2F39ADF11FE842B20E0 -:10AD2000FC7A8CD4381F74ACC5FC0782DB4C7C5E8B -:10AD3000C98A0A8EAD3C7F1F519B2EED662FC13B09 -:10AD40006CE9E70ACDE4BA6B05388C5E7F425D5D45 -:10AD50009F5F5D5DD2BE2FEAE937083E86E723821A -:10AD60000FD78346F284FC7798D6B3EF97543CB75D -:10AD7000A388EB2E9758DF3ED5627E95E0BDB829BB -:10AD8000F8353AF7FB3B3B80E1CDF3BE466D6138C9 -:10AD900010443AF56708BFF9C93AA3339890FF7990 -:10ADA000D3A2D79B165D97233B8D8B7B6F6CC7AF70 -:10ADB000826A37D12B157E5F0F8C511D68B6F5D591 -:10ADC0007DF7B9294FDC5BB0DE4DF7D1A29EF5D9F6 -:10ADD000D4EF2F3003B47E5F4FE3B31F96121F09E9 -:10ADE000BE8F2C11F98818EAE748429EF4C576997F -:10ADF000F7555F0071CAA7BB3CC22F7261BCA8AFF8 -:10AE000020BFB99AED393E1FA3D4C16B963CC9A6A9 -:10AE10000126DD172C0089F0853A727A3E99BCFA3A -:10AE20008230D0BE66832337E07C8A470B34F643FA -:10AE30007EDDAE313E7DA663268E87F9E3EBD01C26 -:10AE4000F8CA99035FD37C6DC95D2A9ECE109E8897 -:10AE50004F7C0FF0B9E04FF52C672E547854CFFF9C -:10AE6000C8C68BC7849097C37F89F013A50B36E5BE -:10AE700033F8455F91F12B6B619EE72A3020B48255 -:10AE8000F0A149848FD4F3573CF77803E1ED956D39 -:10AE900042AFD62A96FE08E359903F6FB2D605CB53 -:10AEA0002E356508BBD30C3FF488BCB6E0D30A74DA -:10AEB000C7DD39E7EB57BB7D72967BD74F6ECE105F -:10AEC000FE903EC6FABDB751C0F77A851F7A74600E -:10AED00015FB0F37E6972E48D48F97BB4E985A171D -:10AEE0009CAB0E38C337A69BF6F93BEDBE085D95CB -:10AEF0009B8D3F1E24FE7192DCB8B93DEF7D613021 -:10AF000060905C2D31238074DBEB0B07887FFA8E19 -:10AF1000EF7C87EA24CAEBB241FEA6A20481C6DD1B -:10AF2000981766F9D8586002D5951EEC31BF9B087A -:10AF3000F7969650F966A45BA63666121C0FC423DA -:10AF4000648F6ECA35C3C13474A8DE2CF4C7B196C1 -:10AF5000E02A9A574BBA7315C0C39BCCD5D49FAF88 -:10AF6000BE3A5F9E1ADDA4F72F5D9E5ADC74BEFECA -:10AF70008220DFD3EAFFA14C1ED6F4B87E4B9EFAA6 -:10AF8000973C00A104B90A6E4ED13B7E4BEFF84DC1 -:10AF9000968BCD9B752B0F1C64F970923C9527E81E -:10AFA00019BFAD674C9647C56FCB93257F244F1EC5 -:10AFB000BA1F3C594F7E4A1F887B8CA9F2156E0937 -:10AFC0006DD94C762CEFB7AD45FACCFD4F5D17F23D -:10AFD000D45F60F1FB92A799FFCF22FFD365E15EBA -:10AFE0004F7112BFDBEDDA2919E2488A755312B7A7 -:10AFF0009F98CAE4B6762A835B732A97DBBA291F27 -:10B00000B7EBA7AEE0B67E2A9FDB8629E4FBD5C866 -:10B01000FF5345DCDE38B59CDB8D53CBB86D9C5AB5 -:10B02000CDE39AA656727BD3D40DDCDE3C5523D6F5 -:10B03000A19A504E5AFEA772D665E07F2342F5D101 -:10B04000BEE3F7BC43F8716A2AE751A2BE355CEF54 -:10B05000712A61E6FFA30542BF6FF408FAA4F2FF6C -:10B06000B196D0FE74FC0F4E716F4BA17B5B95ECDB -:10B07000E70C337F9FE7EFBEF447CA83A2FF7198C6 -:10B08000DF5FA2FD9FF62B1726FB95FD79C97E6534 -:10B09000DF12DBAF748D521D6CBBA4F33DB1532D99 -:10B0A000A17FE6F521B88DDE87DADC1AF95351DF8E -:10B0B0008D010FF6B7EE9581F27DE85F7C8BF80C81 -:10B0C000503F90DD98AFBC3EBCC9D2EFD6F80A38ED -:10B0D000ED085F847FF23E7DAD395FEE679B67CB05 -:10B0E000FD55509691CECEE638EB85DC6B42EEA353 -:10B0F00005C101CAB74453E4DEB6A3888724B93F2B -:10B1000065CBBD25C7397E71EF2387E41EF9EA2799 -:10B110009BC579D1DF4EB2A38A35DED928EA5BF52B -:10B120007EA1579546A12F142DD98E22DFBC4B74DA -:10B130004995F78822FCE3A6D27F9DB667645773D2 -:10B14000FC3E291B97D67E3F11A13CD6716529CBC9 -:10B1500077AA1C45B555CCE7C7957A4827FFF396E3 -:10B16000239F6D474CB623A9E36C79EA3BDEC47894 -:10B17000B1EDCA713CB799604F366A020F684F3E15 -:10B1800026FE4A95A7DA4233144CB34FB543F8A5CF -:10B19000AFAD0B0A7F11FD44F253A2CEF47E80DAEC -:10B1A00021FC9F9C46EBF7153A8473510F3636C647 -:10B1B000EBA98681F2AC7620BC75E6442FC960AF5E -:10B1C00067D84FFB47F97475FC15F2F9D126E117E2 -:10B1D00042772EFB2D763B17DFDBFE8ECDFFA9E3FA -:10B1E0009E2C323BD3E1E5F3165E8E0E3C9DC41FD0 -:10B1F00043CAD29B0C3DAD5E358DCBA257E7E757D6 -:10B200001C473BC77A7576BFE2BA8E347C309B5FB1 -:10B21000F1890E91CF45BF621DCDAB2D177EC5E7DD -:10B220003BE0F2FA0B35F731BE2ED55FD86CF1DF7B -:10B230006CFE425787AD37C2AC375C96DEB8587F9C -:10B24000218D7F703BF32F4CCA54FF43541B221FA8 -:10B2500022F408EA99BBE83DC6F1EC2F1CF5087E04 -:10B26000312D3D736D7B7007E175A85AF80B974B34 -:10B270000ED0EFBBAF236FFEF230DF71A58FAD1D97 -:10B2800098203F07BC31BA37DD4BF795287E7CCF3D -:10B290002BEE11009451DEFF8BF23506D9B991CC1B -:10B2A0002F7D83C6774714A07B83433D22FFF7C5DC -:10B2B000055947017967C8197E6AC2CFBF770D1E4D -:10B2C000C5F60F1985A39070EFF6B0256F2ED8C282 -:10B2D000F774B3B45B9EFD3037DDFEC4FD5CBABAD3 -:10B2E000728E7FD751A0F13D320B3F596A10227EFA -:10B2F000922307D747D0DB83EA84BC475F4D5727AB -:10B30000C7C1F922EF25837286F2EF03B49638178E -:10B310009FB37FB1FB513A970E218677D0EFE0BC07 -:10B320007BFF5A11EFF47BC26E2D8DDED8D7937C54 -:10B33000FF28B595973D16A33BC287038A4169CF85 -:10B34000C1B2CA26CA4F4635AE0083EA7304D3D5CC -:10B35000A7C72DF9D4C1607BAC7CB2253B9DBDB0A5 -:10B36000DB010BFF76DF5D326612DFA94566907F59 -:10B3700087E3F34B9184BCF11316FCBD9211AF45EA -:10B3800064EDF50AFDEFD66326FDDEB82FEF2EAE95 -:10B3900033BAF5089CA1E72531F839E9A77C77E7AE -:10B3A000689A7DBCD521E294BDCE10AFB7375FE17E -:10B3B000FAE3DEA2F4F9ACE73B441E49F5AD0F72A7 -:10B3C0005EDFA7709D3875DC53169FF4AB6640E3D3 -:10B3D000B8FA81323A577409708E72EC9D379FD853 -:10B3E0008DFDFD3D41CE7B0C51FE0385B5BFF05E6A -:10B3F000C6FBFE6B1C1A9D6383FC11DF47385C0D96 -:10B4000006E98FEC6A1C9710471E86D101BA0F77A8 -:10B41000782D70BED46B0493DEF723038E93FFA5C3 -:10B420004CB03E734237D7010EF855BEA73354795E -:10B430009AFD231DC6394F315429E865D793FC1670 -:10B440003FFAFD773527CAC1018B6E0F52DE9CEFA4 -:10B45000318D41A2FF75A0709CEDF38175E39D5481 -:10B4600017CCF2BB0D0A45F6D70481E474A8CA9143 -:10B47000F67ED450D569DE67EA7E9C277EC9FA2F16 -:10B480004B99E0FC4456D96FD9AE3C64ED63E35A66 -:10B49000E0CD66570B3D9BDD1606FA7D58DE5BF26C -:10B4A000A88EFDDD85BF8A38493E6E0358A4D37E41 -:10B4B0002778BF879B9F8EF3FEACFBBA203FCFF768 -:10B4C000712128E4D7BE77BDB04D4D8ADFB352EE6F -:10B4D0004565A6F441EEBAE07DB2EEF7EE3975327D -:10B4E00001DEA2CEE4FBD973CDFF43CF8E5327916B -:10B4F0005F0E575E58BE0E59758D584F35D3C9E64D -:10B50000339BEFB2E88839B3CF1FF28D75A6B3C372 -:10B510001D9D420E52F93195FF34D718DBF143EBF4 -:10B5200092E1DCD029E4F8060B4E4EA19E4FEFEDE0 -:10B530007B4C747FEAE934EB7EBA53E5F1337C6DE2 -:10B54000DBF9772ECDCE2F6B1176DEBF2A83EC3C54 -:10B55000E2F365BAC7F67B940F4890EB3E6FB29F5B -:10B5600069DBF9C73B457CF062DE5512D9E91CCF97 -:10B5700004FBBF59D5C97980543BAD3A431C37AA67 -:10B58000F9AAAD6FB89EF55AC7FB4F4410CEFEF82E -:10B590003EAE0F6522FF66484CA7483A3A4179F221 -:10B5A000BD9AF24E10BF63D3855EC85AAB70BD63BF -:10B5B000C8F15EF587D82AB130042DB883CCB7FB2B -:10B5C000C7F97E8EC5F773D1933E7F5A63FD2E85F2 -:10B5D000EA88F56F56A78B2BEC96EE4F25DF77BFE9 -:10B5E00038B9F8FB4EABBE9C0119422E9A1D7D6402 -:10B5F000EF9B1D7C2F85AEEF2A6BACD201D5F56990 -:10B6000067F8DE4FF77F24AB5EB474465EE0567198 -:10B61000AFE5EC0E714F867F47B8947EF739C1BF16 -:10B620000FBC926EB1CAEC07B3DC9C850207D583D0 -:10B6300023272469DA0FBA82AE341A0E9A570241D0 -:10B640006E53F77D1584F97919C4B8BD06C6B82DB7 -:10B6500087716E2B60925B9326E07E8D93A2AEB1D4 -:10B660000A0C999E574290DB3510E6B61A62DC7ED2 -:10B67000A5FE6F7F733B4EF9DA797811784D23DFA1 -:10B6800071043A7D7E1BCFAD9D3AF3C95CF4EEF3B5 -:10B690004DB01F5F5F3DCE7EA8D71364FE76FA05DE -:10B6A0007FDB709CB3E4836D3F49253F69751AFECB -:10B6B0009DC34F4AFD1DC9FF0229F7D0B3D04500F5 -:10B6C0000000000000000000000000180000000062 -:10B6D000000000000000004000000000000000002A -:10B6E0000000002800000000000000000000001022 -:10B6F000000000000000000000000020000000002A -:10B700000000000000000010000000000000000029 -:10B710000000000800000000000000000000000021 -:10B7200000000000000000000000003900000000E0 -:10B7300000000000000000380000000000000000D1 -:10B7400000000000000000000000000000000008F1 -:10B7500000000000000000000000000000000000E9 -:10B76000000000000000000C0000000000000000CD -:10B770000000000E000000000000000000000004B7 -:10B7800000000000000000000000001800000000A1 -:10B79000000000000000001C00000000000000008D -:10B7A0000000001C0000000000000000000000136A -:10B7B00000000000000000000000003A000000004F -:10B7C0000000000000000001000000000000000078 -:10B7D0000000000200000000000000000000000166 -:10B7E0000000000000000000000000100000000049 -:10B7F00000000000000000500000000000000000F9 -:10B800000000000000000000000000000000000335 -:10B810000000000000000000000000AB000000007D -:10B820000000000000000008000000000000000010 -:10B830000000C00000100000000000080000C00868 -:10B8400000100000000000020000C0000010000016 -:10B850000000001000009FB0000000000000000881 -:10B860000000C08000100000000000040000C0883C -:10B8700000100000000000020000C0800010000066 -:10B8800000000010000091200000000000000008EF -:10B8900000009340000100040000000100009348F4 -:10B8A00000000000000000020000935000000000B3 -:10B8B0000000000800009354000000000000000297 -:10B8C00000009418000000000000000800009358D9 -:10B8D000000800000000000800009AB000400000CE -:10B8E00000000040000093980008000000000008DD -:10B8F000000093D800080000000000080000942019 -:10B9000000C8000000000098000095B000980000FA -:10B9100000000028000095F00098000000000028BA -:10B920000000C480054000300000054000009D205C -:10B93000000800000000000100009D210008000038 -:10B9400000000001000020080010000000000010AE -:10B9500000002000000000000000000800009CD84B -:10B96000000800000000000200009D180000000018 -:10B9700000000001000000010000000000000000C5 -:10B9800000000009000000000000000000000002AC -:10B9900000000000000000000000CF2000000000B8 -:10B9A000000000200000CF46000000000000000161 -:10B9B0000000600000200000000000200000730074 -:10B9C000000800000000000800009FA00000000028 -:10B9D0000000000100009FA800000000000000011E -:10B9E00000009F60000000000000001000009F6346 -:10B9F000000000000000000100009F610000000046 -:10BA00000000000100009F6600000000000000012F -:10BA100000009F67000000000000000000009F6819 -:10BA2000000000000000000400009F6C0000000007 -:10BA300000000004000000520000000000000000B0 -:10BA400000000003000000000000000000000003F0 -:10BA500000000000000000000000000500000000E1 -:10BA600000000000000000020000000000000000D4 -:10BA700000060000000000000000002000009F7091 -:10BA8000000000000000000100009F900000000086 -:10BA9000000000080000005300000000000000004B -:10BAA00000009F98000000000000000200009F9C22 -:10BAB000000000000000000100009F9D0000000049 -:10BAC000000000010000000900000000000000006C -:10BAD0000000000100000000000000000000004421 -:10BAE0000000000000000000000000010000000055 -:10BAF00000000000000000500000000000000000F6 -:10BB0000000000890000000000000000000012C8D2 -:10BB10000080000000000080000000010000000024 -:10BB2000000000000000A000071000000000071047 -:10BB300000001AC800000000000000080000AEC0AD -:10BB400000080000000000080000AE4000080000EF -:10BB5000000000080000AE8000080000000000089F -:10BB6000000020080010000000000010000020006D -:10BB700000000000000000080000A01007100040B6 -:10BB80000000004000001BF8000800000000000159 -:10BB900000001BF9000800000000000100001AD09E -:10BBA000000000000000000100001AD800000000A2 -:10BBB0000000000200001ADA00000000000000028D -:10BBC0008000000000000000000000000000AF0046 -:10BBD000000000000000002000001B78002800008A -:10BBE000000000040000E000002000000000002031 -:10BBF0000000F300000800000000000800001AF038 -:10BC0000000000000000010800001B3700000000D9 -:10BC10000000000100001B0F0000000000000001F8 -:10BC200000001B70000000000000000400001B74F6 -:10BC300000000000000000040000005000000000B0 -:10BC400000000000000000030000000000000000F1 -:10BC500000000005000000000000000000000006D9 -:10BC600000000000000000000000000700000000CD -:10BC70000000000000001BC80000000000000001E0 -:10BC800000001BE800000000000000080000005158 -:10BC9000000000000000000000001BD000000000B9 -:10BCA0000000000400001BD400000000000000049D -:10BCB00000001BD8000000000000000400001BDC96 -:10BCC00000000000000000080000B00000180000A4 -:10BCD000000000180000C00000400000000000400C -:10BCE0000000C00000400002000000010000C00190 -:10BCF00000400002000000000000E2000020000000 -:10BD0000000000200000E204000200080020000201 -:10BD10008000000000000000000000000000E200C1 -:10BD200000080020000000040000F40000280000CB -:10BD3000000000280000F540001000000000001086 -:10BD40000000F5C000200000000000200000F5C049 -:10BD500000020020000000020000F30000200000AC -:10BD6000000000200000200800100000000000106B -:10BD70000000200000000000000000080000110882 -:10BD80000008000000000008000011680008000022 -:10BD900000000008000011A80008000000000008D2 -:10BDA00000001240000800000000000100001241E5 -:10BDB0000008000000000001000040000020000416 -:10BDC00000000010000059000030001800000010B2 -:10BDD0000000590800300018000000020000570061 -:10BDE00000080000000000010000570100080000EA -:10BDF00000000001000011E8000000000000000148 -:10BE0000000011F00000000000000001000011F827 -:10BE100000000000000000100000124400080000B4 -:10BE2000000000040000400000200000000000208E -:10BE30000000530000100000000000100000153842 -:10BE400000000000000000010000000300000000EE -:10BE500000000000000000000000000000000000E2 -:10BE600000000001000000000000000000000004CD -:10BE700000000000000000000000150800000000A5 -:10BE8000000000010000152800000000000000086C -:10BE900000000050000000000000000000008308C7 -:10BEA0000080000000000080000000010000000091 -:10BEB000000000000000200800100000000000103A -:10BEC00000002000000000000000000800008410B6 -:10BED0000008000000000008000084700008000056 -:10BEE0000000000800060000046000280000046054 -:10BEF00000008520000800000000000100008521EE -:10BF000000080000000000018000000000000000A8 -:10BF10000000000000008408000000000000000194 -:10BF2000000084F40008000000000002000084F615 -:10BF3000000800000000000200008504001000005E -:10BF400000000004000087600000000000000020E6 -:10BF500000006000002000000000002000007300CE -:10BF600000080000000000080000000300000000BE -:10BF700000000000000000050000000000000000BC -:10BF800000000006000000000000000000000007A4 -:10BF90000000000000000000000088080000000011 -:10BFA00000000001000088280000000000000008D8 -:10BFB0000000005000000000000000000000881099 -:10BFC00000000000000000040000881400000000D1 -:10BFD00000000004000088180000000000000004B9 -:10BFE0000000881C00000000000000080000300075 -:10BFF0000040000000000008000030080040000081 -:10C00000000000280000339001C00010000000086C -:10C010000000320000200000000000200000372057 -:10C02000000000000000000800001020062000387A -:10C03000000000080000A000000000000000200038 -:10C0400000003EA9000000000000000100003EC802 -:10C05000000000000000000280000000000000005E -:10C060000000000000006000002000000000000848 -:10C070000000400000080000000000010000400136 -:10C08000000800000000000100004040000800041B -:10C0900000000002000040600008000400000004EE -:10C0A0000000400000080000000000040000400400 -:10C0B00000080000000000040000404000000000F4 -:10C0C00000000008000040480000000000000008D8 -:10C0D0000000800000000000000000100000504040 -:10C0E00000010004000000010000500000000000FA -:10C0F00000000020000050080010000000000004B4 -:10C100000000500C0010000000000001000052C7A9 -:10C110000000000000000001000052C60000000006 -:10C120000000000100003000003000180000000492 -:10C130000000300400300018000000040000300847 -:10C1400000300018000000020000300A0030001823 -:10C15000000000020000300C003000180000000158 -:10C160000000300D00300018000000010000300E0B -:10C1700000300018000000010000301000300018EE -:10C18000000000040000301400300018000000041B -:10C19000000050000100008000080004000050046E -:10C1A00001000080000800040000000A00000000F8 -:10C1B0000000000000005068010000800000000145 -:10C1C0000000506901000080000000010000506C78 -:10C1D00001000080000000020000506E010000809D -:10C1E0000000000200005070010000800000000408 -:10C1F0000000507401000080000000040000506640 -:10C200000100008000000002000050640100008076 -:10C2100000000001000050600100008000000002EA -:10C220000000506201000080000000020000505039 -:10C230000100008000000004000050540100008054 -:10C2400000000004000050580100008000000004BD -:10C250000000505C01000080000000040000507CE1 -:10C2600001000080000000010000507D01000080FE -:10C270000000000100004018001000000000000451 -:10C2800000004090001000000000000400004098F2 -:10C290000010000000000004000041100000000039 -:10C2A0000000000200004112000000000000000237 -:10C2B00000004114000000000000000200004116D0 -:10C2C00000000000000000020000604000080000C4 -:10C2D00000000002000060420008000000000002B0 -:10C2E00000006044000800000000000400006080BE -:10C2F0000008000000000008000060C000400008C6 -:10C3000000000008000060000008000000000002BB -:10C31000000060020008000000000001000060044E -:10C320000008000000000002000063400008000058 -:10C330000000000800006380000800000000000406 -:10C34000000063840008000000000001000063C0DA -:10C350000008000000000002000063C400080000A4 -:10C36000000000020000640000080000000000045B -:10C3700000007000001000000000000400007004C5 -:10C380000010000000000004000070080010000011 -:10C3900000000004000090000008000000000002FF -:10C3A000000090020008000000000001000090045E -:10C3B000000800000000000200009040000800009B -:10C3C000000000020000904400080000000000028D -:10C3D000000090460008000000000002000096489F -:10C3E0000008000000000008000090800008000025 -:10C3F000000000020000908400080000000000021D -:10C40000000096880008000000000008000080403E -:10C41000000800000000000100008041000800004A -:10C420000000000100008042000800000000000140 -:10C4300000008043000800000000000100008000B0 -:10C440000008000000000002000080020008000058 -:10C45000000000010000800400080000000000024D -:10C46000000080C00008000000000002000080C240 -:10C470000008000000000002000080C40008000066 -:10C4800000000002000080800008000000000001A1 -:10C490000000808100080000000000010000808290 -:10C4A0000008000000000001000080830008000078 -:10C4B000000000010000808400080000000000016E -:10C4C0000000808500080000000000010000808658 -:10C4D00000080000000000010000600000080000EB -:10C4E00000000002000060020008000000000001DF -:10C4F000000060040008000000000002000060422C -:10C5000000C00018000000020000604000C00018D9 -:10C51000000000020000604C00C00018000000088D -:10C520000000604400C000180000000800006057D0 -:10C5300000C00018000000010000605400C0001896 -:10C54000000000020000605600C00018000000015A -:10C55000000066400008000000000008000066803F -:10C560000008000000000008000066C0000800008D -:10C57000000000080000DA4200180000000000027D -:10C580000000DE4000000000000000000000E000AD -:10C5900000000000000000040000D0C00000000007 -:10C5A000000000040000D0C40000000000000004EF -:10C5B0000000D0C800000000000000040000D0CC43 -:10C5C00000000000000000040000D0D000000000C7 -:10C5D000000000040000D0D40000000000000004AF -:10C5E0000000D0D800000000000000040000D0C00F -:10C5F00000000000000000200000DB000000000040 -:10C60000000000040000DB000000000000000068E3 -:10C610000000B94800000000000000000000D00049 -:10C6200000000000000000040000B0C00000000096 -:10C63000000000040000B0C400000000000000047E -:10C640000000B0C800000000000000040000B0C0FE -:10C6500000000000000000100000D6B00000000044 -:10C66000000000040000D6B4000000000000000438 -:10C670000000D6B800000000000000040000D6BC96 -:10C6800000000000000000040000D6B00000000020 -:10C69000000000100000D348000000000000000867 -:10C6A0000000D358000000000000008000000010CF -:10C6B00000000000000000000000D358000000004F -:10C6C0000000000800000000060209000000000051 -:00000001FF diff --git a/firmware/cis/.gitignore b/firmware/cis/.gitignore deleted file mode 100644 index 1de39847f261da6faeaa9d7e8b8e803061b6e003..0000000000000000000000000000000000000000 --- a/firmware/cis/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.cis diff --git a/firmware/cis/3CCFEM556.cis.ihex b/firmware/cis/3CCFEM556.cis.ihex deleted file mode 100644 index e4d92b173e1766420b79a44781e699f7cbc4440c..0000000000000000000000000000000000000000 --- a/firmware/cis/3CCFEM556.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:1000000001030000FF152D050033436F6D004D65A2 -:100010006761686572747A2033434346454D3535D0 -:1000200036004C414E202B2035366B204D6F6465D9 -:100030006D0000FF20040101560521020000060B9F -:1000400002004D000000006B000000FF001303439E -:100050004953210206001A060507001067021B0912 -:1000600087011901556430FFFFFF00130343495313 -:10007000210202001A060527001177021B09A701B9 -:090080001901552330FFFFFF00B8 -:00000001FF -# -# This card is MFC-compliant, but identifies itself as single function -# diff --git a/firmware/cis/3CXEM556.cis.ihex b/firmware/cis/3CXEM556.cis.ihex deleted file mode 100644 index 895010b230ffff125bb495a04f38f52997e99cff..0000000000000000000000000000000000000000 --- a/firmware/cis/3CXEM556.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:1000000001030000FF152C050033436F6D004D65A3 -:100010006761686572747A20334358454D353536CB -:10002000004C414E202B2035366B204D6F64656DA2 -:100030000000FF20040101350021020000060B0230 -:10004000004C0000000069000000FF00130343495A -:1000500053210206001A0501070008631B098701E6 -:100060001901556430FFFFFF001303434953210278 -:1000700002001A0501270009631B09A70119015590 -:060080002330FFFFFF002A -:00000001FF -# -# This card is MFC-compliant, but identifies itself as single function -# diff --git a/firmware/cis/COMpad2.cis.ihex b/firmware/cis/COMpad2.cis.ihex deleted file mode 100644 index 1671c5e48caafde64d1cd74acd3d3d81c2293377..0000000000000000000000000000000000000000 --- a/firmware/cis/COMpad2.cis.ihex +++ /dev/null @@ -1,11 +0,0 @@ -:1000000001030000FF151F0401414456414E5445B1 -:10001000434800434F4D7061642D33322F38350013 -:10002000312E300000FF210202011A0501050001F6 -:10003000031B0EC18118AA61E80207E8030730B864 -:100040009E1B08820108AA6030030F1B0883010869 -:10005000AA6040030F1B08840108AA6050030F1B0D -:0D00600008850108AA6060030F1400FF006E -:00000001FF -# -# Replacement CIS for Advantech COMpad-32/85 -# diff --git a/firmware/cis/COMpad4.cis.ihex b/firmware/cis/COMpad4.cis.ihex deleted file mode 100644 index 27bbec1921b3373d95ad9ef5d546d903c89db168..0000000000000000000000000000000000000000 --- a/firmware/cis/COMpad4.cis.ihex +++ /dev/null @@ -1,9 +0,0 @@ -:1000000001030000FF151F0401414456414E5445B1 -:10001000434800434F4D7061642D33322F383542D1 -:100020002D34000000FF210202011A050102000127 -:10003000011B0BC18118AA6040021F30B89E1B082B -:0C004000820108AA6040031F1400FF00AA -:00000001FF -# -# Replacement CIS for Advantech COMpad-32/85B-4 -# diff --git a/firmware/cis/DP83903.cis.ihex b/firmware/cis/DP83903.cis.ihex deleted file mode 100644 index 6d73ea3cf1b892fa80dc57f25c36cfcae43d7dde..0000000000000000000000000000000000000000 --- a/firmware/cis/DP83903.cis.ihex +++ /dev/null @@ -1,14 +0,0 @@ -:1000000001030000FF152904014D756C74696675C4 -:100010006E6374696F6E20436172640000004E531A -:1000200043204D46204C414E2F4D6F64656D00FFBF -:1000300020047501000021020000060B02004900A7 -:100040000000006A000000FF00130343495321022F -:1000500006001A060517201077021B0C970179017C -:10006000556530FFFF284000FF001303434953212B -:100070000202001A060507401077021B09870119C2 -:0800800001552330FFFFFF00D2 -:00000001FF -# -# This CIS is for cards based on the National Semiconductor -# DP83903 Multiple Function Interface Chip -# diff --git a/firmware/cis/LA-PCM.cis.ihex b/firmware/cis/LA-PCM.cis.ihex deleted file mode 100644 index a0ff0c7b393d24797f455a59fab0cadd885802e8..0000000000000000000000000000000000000000 --- a/firmware/cis/LA-PCM.cis.ihex +++ /dev/null @@ -1,20 +0,0 @@ -:100000000105D4F953E9FF17035338FF20040FC04B -:1000100002002102060315390401416C6C69656414 -:100020002054656C657369732C4B2E4B00457468C6 -:1000300065726E6574204C414E20436172640043CA -:10004000656E747265434F4D004C412D50434D0019 -:10005000FF1A0602100000020B1B08810108E06075 -:1000600000021F1B08820108E06020021F1B08839A -:100070000108E06040021F1B08840108E060600284 -:100080001F1B08850108E06080021F1B088601080D -:10009000E060A0021F1B08870108E060C0021F1B70 -:1000A00008880108E060E0021F1B08890108E06081 -:1000B00000031F1B088A0108E06020031F1B088B38 -:1000C0000108E06040031F1B088C0108E06060032A -:1000D0001F1B088D0108E06080031F1B088E0108AC -:1000E000E060A0031F1B088F0108E060C0031F1B16 -:0D00F00008900108E060E0031F1400FF000D -:00000001FF -# -# Replacement CIS for Allied Telesis LA-PCM -# diff --git a/firmware/cis/MT5634ZLX.cis.ihex b/firmware/cis/MT5634ZLX.cis.ihex deleted file mode 100644 index 72500b9d95d8720526ed16547b9d721e5bb3c4f6..0000000000000000000000000000000000000000 --- a/firmware/cis/MT5634ZLX.cis.ihex +++ /dev/null @@ -1,11 +0,0 @@ -:100000000101FF152204014D756C74695465636824 -:100010000050434D4349412035364B2044617461C3 -:10002000466178000000FF20040002010021020266 -:10003000001A05012780FF671B0FCF418B01550177 -:10004000550155AA60F80307281B08970108AA6004 -:10005000F802071B089F0108AA60E803071B08A70E -:0B0060000108AA60E802071400FF007E -:00000001FF -# -# Replacement CIS for Multitech MT5634ZLX modems -# diff --git a/firmware/cis/NE2K.cis.ihex b/firmware/cis/NE2K.cis.ihex deleted file mode 100644 index 1bb40fc4759f9d7e375ea3668788640953fcefe9..0000000000000000000000000000000000000000 --- a/firmware/cis/NE2K.cis.ihex +++ /dev/null @@ -1,8 +0,0 @@ -:1000000001030000FF1515040150434D4349410011 -:1000100045746865726E6574000000FF2102060079 -:100020001A050120F803031B09E001190155653089 -:06003000FFFF1400FF00B9 -:00000001FF -# -# Replacement CIS for various busted NE2000-compatible cards -# diff --git a/firmware/cis/PCMLM28.cis.ihex b/firmware/cis/PCMLM28.cis.ihex deleted file mode 100644 index ffdfe8522ef5a7830c20e269febfc33f84b882c1..0000000000000000000000000000000000000000 --- a/firmware/cis/PCMLM28.cis.ihex +++ /dev/null @@ -1,18 +0,0 @@ -:1000000001030000FF151504014C494E4B53595391 -:100010000050434D4C4D3238000000FF2004430196 -:10002000ABC0210200001A05012FF803031B10E4E6 -:1000300001190155E06100031FF8020730FFFF1BA3 -:100040000BA50108E06120031FF802071B0BA601A6 -:1000500008E06140031FF802071B0BA70108E061DD -:1000600060031FF802071B0BA80108E06100031FD3 -:10007000E803071B0BA90108E06120031FE8030741 -:100080001B0BAA0108E06140031FE803071B0BAB31 -:100090000108E06160031FE803071B0BAC0108E0E7 -:1000A0006100031FE802071B0BAD0108E06120039C -:1000B0001FE802071B0BAE0108E06140031FE802C6 -:1000C000071B0BAF0108E06160031FE80207140083 -:0200D000FF002F -:00000001FF -# -# The on-card CIS says it is MFC-compliant, but it is not -# diff --git a/firmware/cis/PE-200.cis.ihex b/firmware/cis/PE-200.cis.ihex deleted file mode 100644 index e6dbdab6eb796ca70c3ac177e8f78d32d30459a5..0000000000000000000000000000000000000000 --- a/firmware/cis/PE-200.cis.ihex +++ /dev/null @@ -1,9 +0,0 @@ -:1000000001030000FF151E0401504D582020200060 -:1000100050452D3230300045544845524E4554002D -:1000200052303100FF210206031A050101000101CF -:100030001B0EC181190155E051000F100F30FFFF59 -:040040001400FF00A9 -:00000001FF -# -# Replacement CIS for PE-200 ethernet card -# diff --git a/firmware/cis/PE520.cis.ihex b/firmware/cis/PE520.cis.ihex deleted file mode 100644 index 97a745b5496e96a04f015a13747bf6cd37603a96..0000000000000000000000000000000000000000 --- a/firmware/cis/PE520.cis.ihex +++ /dev/null @@ -1,9 +0,0 @@ -:1000000001030000FF152304014B544900504535FE -:10001000323020504C55530050434D434941204508 -:10002000746865726E65740000FF20046101100041 -:10003000210206001A050101D00F0B1B09C101198D -:0A00400001556530FFFF1400FF00BA -:00000001FF -# -# Replacement CIS for PE520 ethernet card -# diff --git a/firmware/cis/RS-COM-2P.cis.ihex b/firmware/cis/RS-COM-2P.cis.ihex deleted file mode 100644 index 0801ca5da80a48e14e2b2c59eb37b6776bb92301..0000000000000000000000000000000000000000 --- a/firmware/cis/RS-COM-2P.cis.ihex +++ /dev/null @@ -1,10 +0,0 @@ -:1000000001030000FF1516040150434D4349410010 -:1000100052532D434F4D203250000000FF21020269 -:10002000011A0501030001011B0EC18118AA61E834 -:100030000307E8020730B89E1B0B820108AA615033 -:1000400002075802071B0B830108AA6160020768B8 -:0600500002071400FF008E -:00000001FF -# -# Replacement CIS for dual-serial-port IO card -# diff --git a/firmware/cis/SW_555_SER.cis.ihex b/firmware/cis/SW_555_SER.cis.ihex deleted file mode 100644 index 9b9348acee7b6ec6a41844fbc99cb392b00b426d..0000000000000000000000000000000000000000 --- a/firmware/cis/SW_555_SER.cis.ihex +++ /dev/null @@ -1,12 +0,0 @@ -:100000000101FF17034100FF20043F0110072102F7 -:100010000200152A070053696572726120576972E0 -:10002000656C657373004169724361726420353594 -:1000300035004135353500526576203100FF1A050F -:1000400001030007731B0BE00118A360F8030730DE -:10005000BC3F1B08A10108A360F802071B08A2010E -:1000600008A360E803071B08A30108A360E80207D0 -:0A0070001B04A40108231400FF0084 -:00000001FF -# -# Replacement CIS for AC555 provided by Sierra Wireless -# diff --git a/firmware/cis/SW_7xx_SER.cis.ihex b/firmware/cis/SW_7xx_SER.cis.ihex deleted file mode 100644 index 11e44ad86437f128c07da42b8fc18c9a6a384c83..0000000000000000000000000000000000000000 --- a/firmware/cis/SW_7xx_SER.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:100000000101FF17034100FF2004920110072102A4 -:1000100002001537070053696572726120576972D3 -:10002000656C6573730041433731302F4143373579 -:10003000300047505253204E6574776F726B2041E9 -:1000400064617074657200523100FF1A050103008B -:1000500007731B10E00119784D555D25A360F80367 -:100060000730BC861B08A10108A360F802071B0823 -:10007000A20108A360E803071B08A30108A360E826 -:0C00800002071B04A40108231400FF0069 -:00000001FF -# -# Replacement CIS for AC7xx provided by Sierra Wireless -# diff --git a/firmware/cis/SW_8xx_SER.cis.ihex b/firmware/cis/SW_8xx_SER.cis.ihex deleted file mode 100644 index bbcfe6348328f7fb8baaa80395d237cad41dc43a..0000000000000000000000000000000000000000 --- a/firmware/cis/SW_8xx_SER.cis.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:100000000101FF17034100FF2004920110072102A4 -:100010000200152F070053696572726120576972DB -:10002000656C657373004143383530003347204EAB -:100030006574776F726B20416461707465720052F1 -:100040003100FF1A0501030007731B10E001197846 -:100050004D555D25A360F8480730BC861B08A101FB -:1000600008A360F847071B08A20108A360E8480737 -:100070001B08A30108A360E847071B04A401082389 -:040080001400FF0069 -:00000001FF -# -# Replacement CIS for AC8xx provided by Sierra Wireless -# diff --git a/firmware/cis/tamarack.cis.ihex b/firmware/cis/tamarack.cis.ihex deleted file mode 100644 index 1e86547fb361d6e03d3460d61715f68b5bd14829..0000000000000000000000000000000000000000 --- a/firmware/cis/tamarack.cis.ihex +++ /dev/null @@ -1,10 +0,0 @@ -:100000000103D400FF17034100FF152404015441EC -:100010004D415241434B0045746865726E657400F2 -:10002000410030303437343331313830303100FF33 -:10003000210206001A050120F803031B14E08119B0 -:100040003F554D5D06864626E551000F100F30FFE7 -:05005000FF1400FF0099 -:00000001FF -# -# Replacement CIS for Surecom, Tamarack NE2000 cards -# diff --git a/firmware/cpia2/stv0672_vp4.bin.ihex b/firmware/cpia2/stv0672_vp4.bin.ihex deleted file mode 100644 index bd0b9cf65640a24e4f55d24ba92750a3f0402809..0000000000000000000000000000000000000000 --- a/firmware/cpia2/stv0672_vp4.bin.ihex +++ /dev/null @@ -1,73 +0,0 @@ -:1000000001BCE302E303E304E305E306E3079344EF -:1000100056D4934E5651934E51D6934E4F54934EC1 -:10002000924F92A4930592F4931B929291E692368A -:100030009274924A928C928EC8D00B4202A0CA92BD -:100040000902C9100A0A0A81E3B8E3B0E3A8E3A0F1 -:10005000E398E390E100CFD70A12CC9508B20A18D2 -:10006000E10001EE0C084A12C818F09AC022F31CF5 -:100070004A13F314C8A0F214F21CEB13D3A26316B4 -:10008000489EF018A403F393C058F713519CE9203D -:10009000CFEF63F9922ED35F63FA922ED36763FB9F -:1000A000922ED36FE91A631648A7F020A406F394A2 -:1000B000C027F714F513519DF6136318C420CBEF36 -:1000C00063FC922ED37763FD922ED37F63FE922E34 -:1000D000D38763FF922ED38F6438922ED3976439DF -:1000E000922ED39FE100F53AF43BF7BFF2BCF23D0C -:1000F000E1008087908051D5022202324BD3F71164 -:100100000BDAE1000E0202400DB5E3024855E5129C -:10011000A401E81BE390F018A401E8BF8DB84BD10F -:100120004BD80BCB0BC2E100E302E30352D360597F -:10013000E6930D2252D4E6930D2AE398E390E10072 -:10014000025D0263E302C81202CAC85202C2826898 -:10015000E302C81402CAC89002C20AD0C9930ADADC -:10016000CCD20AE2631202DA0A980AA00AA8E39043 -:10017000E100E3020AD0C9930ADACCD20AE26312A0 -:1001800002DA0A980AA00AA84991E56AA404C812EA -:1001900002CAC8528289C81402CAC89002C2E39037 -:1001A000E1000860E1004853E897085AE100E302E3 -:1001B000E30354D36059E6930D52E398E390E100D2 -:1001C000029CE3025513931755139317E390E10034 -:1001D0007530E302E30355556059E6930DB2E39899 -:1001E000E390E10002AEE792E918EA9AE898E81095 -:1001F000E811E851D2DAD2F3E813D2FAE850D2EAA1 -:10020000E8D0E8D1D30A03094823E52CA003482409 -:10021000EA1C0308D2E3D303D313E10002CB059316 -:100220005793F09AAC0BE30792EAE29FE506E3B03E -:10023000A002EB1E82D7EA1EE23B859BE91EC89016 -:10024000859402DE05805793F0BAAC0692EAE2BFCD -:10025000E506A001EBBF8588E93EC8908581E93EAF -:10026000F0BAF339F03A6017F03AC090F0BAE10012 -:10027000003FE302E30358106059E6930DA25812C1 -:10028000E6930DAAE398E390E1000301E100030384 -:100290009B7D8B8BE302E30358566059E6930DBABE -:1002A000E398E390E100030F9311E100E3024A11A8 -:1002B0000B4291AFE390E100F291F091A3FEE100D7 -:1002C0006092C05FF013F013595BE213F0115A19FA -:1002D000E213E10000000327686176616E610006A9 -:1002E000032CE302E303E9385915595AF29ABC0B7F -:1002F000A40A591EF311F01AE2BB5915F011192A7C -:10030000E502A401EBBFE398E390E1000342192862 -:10031000E100E9306079E100E303E3076079934E9F -:10032000E3B8E398E100E91AF01FE233F091E292BA -:08033000E032F031E1000000B1 -:00000001FF - - Copyright 2001, STMicrolectronics, Inc. - Contact: steve.miller@st.com - - Description: - This file contains patch data for the CPiA2 (stv0672) VP4. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/firmware/cxgb3/ael2005_opt_edc.bin.ihex b/firmware/cxgb3/ael2005_opt_edc.bin.ihex deleted file mode 100644 index c1d6e5d3bea74548a96298c555c22f061d8ee0d1..0000000000000000000000000000000000000000 --- a/firmware/cxgb3/ael2005_opt_edc.bin.ihex +++ /dev/null @@ -1,69 +0,0 @@ -:10000000CC002FF4CC013CD4CC022015CC0331051C -:10001000CC046524CC0527FFCC06300FCC072C8BF5 -:10002000CC08300BCC094009CC0A400ECC0B2F7207 -:10003000CC0C3002CC0D1002CC0E2172CC0F301241 -:10004000CC101002CC1125D2CC123012CC131002DD -:10005000CC14D01ECC1527D2CC163012CC171002DF -:10006000CC182004CC193C84CC1A6436CC1B200755 -:10007000CC1C3F87CC1D8676CC1E40B7CC1FA74634 -:10008000CC204047CC215673CC222982CC2330028D -:10009000CC2413D2CC258BBDCC262862CC273012A1 -:1000A000CC281002CC292092CC2A3012CC2B100262 -:1000B000CC2C5CC3CC2D0314CC2E2942CC2F300287 -:1000C000CC301002CC31D019CC322032CC333012AB -:1000D000CC341002CC352A04CC363C74CC37643591 -:1000E000CC382FA4CC393CD4CC3A6624CC3B5563D5 -:1000F000CC3C2D42CC3D3002CC3E13D2CC3F464DC1 -:10010000CC402862CC413012CC421002CC43203289 -:10011000CC443012CC451002CC462FB4CC473CD452 -:10012000CC486624CC495563CC4A2D42CC4B300296 -:10013000CC4C13D2CC4D2ED2CC4E3002CC4F100230 -:10014000CC502FD2CC513002CC521002CC530004F0 -:10015000CC542942CC553002CC561002CC572092B8 -:10016000CC583012CC591002CC5A5CC3CC5B03176C -:10017000CC5C2F72CC5D3002CC5E1002CC5F294289 -:10018000CC603002CC611002CC6222CDCC63301D39 -:10019000CC642862CC653012CC661002CC672ED2BB -:1001A000CC683002CC691002CC6A2D72CC6B300264 -:1001B000CC6C1002CC6D628FCC6E2112CC6F3012E1 -:1001C000CC701002CC715AA3CC722DC2CC73300209 -:1001D000CC741312CC756F72CC761002CC772807D2 -:1001E000CC7831A7CC7920C4CC7A3C24CC7B672452 -:1001F000CC7C1002CC7D2807CC7E3187CC7F20C4FC -:10020000CC803C24CC816724CC821002CC83251482 -:10021000CC843C64CC856436CC86DFF4CC876436F1 -:10022000CC881002CC8940A4CC8A643CCC8B40168C -:10023000CC8C8C6CCC8D2B24CC8E3C24CC8F643518 -:10024000CC901002CC912B24CC923C24CC93643AD9 -:10025000CC944025CC958A5ACC961002CC97273165 -:10026000CC983011CC991001CC9AC7A0CC9B01003E -:10027000CC9CC502CC9D53ACCC9EC503CC9FD5D5A0 -:10028000CCA0C600CCA12A6DCCA2C601CCA32A4C1E -:10029000CCA4C602CCA50111CCA6C60CCCA7590093 -:1002A000CCA8C710CCA90700CCAAC718CCAB0700B4 -:1002B000CCACC720CCAD4700CCAEC801CCAF7F5092 -:1002C000CCB0C802CCB17760CCB2C803CCB37FCE7F -:1002D000CCB4C804CCB55700CCB6C805CCB75F11B8 -:1002E000CCB8C806CCB94751CCBAC807CCBB57E18B -:1002F000CCBCC808CCBD2700CCBEC809CCBF000010 -:10030000CCC0C821CCC10002CCC2C822CCC30014CE -:10031000CCC4C832CCC51186CCC6C847CCC71E02D7 -:10032000CCC8C013CCC9F341CCCAC01ACCCB04464C -:10033000CCCCC024CCCD1000CCCEC025CCCF0A0074 -:10034000CCD0C026CCD10C0CCCD2C027CCD30C0C3A -:10035000CCD4C029CCD500A0CCD6C030CCD70A0094 -:10036000CCD8C03CCCD9001CCCDAC005CCDB7A069A -:10037000CCDC0000CCDD2731CCDE3011CCDF10012D -:10038000CCE0C620CCE10000CCE2C621CCE3003FAB -:10039000CCE4C622CCE50000CCE6C623CCE70000C6 -:1003A000CCE8C624CCE90000CCEAC625CCEB0000A2 -:1003B000CCECC627CCED0000CCEEC628CCEF00007C -:1003C000CCF0C62CCCF10000CCF20000CCF3280617 -:1003D000CCF43CB6CCF5C161CCF66134CCF76135D8 -:1003E000CCF85443CCF90303CCFA6524CCFB000BC6 -:1003F000CCFC1002CCFD2104CCFE3C24CCFF21051A -:10040000CD003805CD016524CD02DFF4CD034005D4 -:10041000CD046524CD051002CD065DD3CD070306BE -:10042000CD082FF7CD0938F7CD0A60B7CD0BDFFD2A -:10043000CD0C000ACD0D1002CD0E00007CC7AE59C8 -:00000001FF diff --git a/firmware/cxgb3/ael2005_twx_edc.bin.ihex b/firmware/cxgb3/ael2005_twx_edc.bin.ihex deleted file mode 100644 index 9b5e9e51fcb755aaa125072d3220c4d597c83de4..0000000000000000000000000000000000000000 --- a/firmware/cxgb3/ael2005_twx_edc.bin.ihex +++ /dev/null @@ -1,93 +0,0 @@ -:10000000CC004009CC0127FFCC02300FCC0340AA22 -:10001000CC04401CCC05401ECC062FF4CC073CD4AD -:10002000CC082035CC093145CC0A6524CC0B26A25E -:10003000CC0C3012CC0D1002CC0E29C2CC0F3002E9 -:10004000CC101002CC112072CC123012CC13100242 -:10005000CC1422CDCC15301DCC162E52CC1730121C -:10006000CC181002CC1928E2CC1A3002CC1B10029A -:10007000CC1C628FCC1D2AC2CC1E3012CC1F1002A9 -:10008000CC205553CC212AE2CC223002CC231302BF -:10009000CC24401ECC252BE2CC263012CC271002DB -:1000A000CC282DA2CC293012CC2A1002CC2B2BA28A -:1000B000CC2C3002CC2D1002CC2E5EE3CC2F0305CD -:1000C000CC30400ECC312BC2CC323002CC331002BB -:1000D000CC342B82CC353012CC361002CC37566360 -:1000E000CC380302CC39401ECC3A6F72CC3B1002A4 -:1000F000CC3C628FCC3D2BE2CC3E3012CC3F100288 -:10010000CC4022CDCC41301DCC422E52CC433012BB -:10011000CC441002CC452522CC463012CC471002EC -:10012000CC482DA2CC493012CC4A1002CC4B2CA288 -:10013000CC4C3012CC4D1002CC4E2FA4CC4F3CD422 -:10014000CC506624CC51410BCC5256B3CC5303C493 -:10015000CC542FB2CC553002CC561002CC57220BC7 -:10016000CC58303BCC5956B3CC5A03C3CC5B866BCE -:10017000CC5C400CCC5D23A2CC5E3012CC5F100274 -:10018000CC602DA2CC613012CC621002CC632CA2C8 -:10019000CC643012CC651002CC662FB4CC673CD452 -:1001A000CC686624CC6956B3CC6A03C3CC6B866B2F -:1001B000CC6C401CCC6D2205CC6E3035CC6F5B53C3 -:1001C000CC702C52CC713002CC7213C2CC735CC395 -:1001D000CC740317CC752522CC763012CC77100264 -:1001E000CC782DA2CC793012CC7A1002CC7B2B8229 -:1001F000CC7C3012CC7D1002CC7E5663CC7F0303C6 -:10020000CC80401ECC810004CC822C42CC833012A6 -:10021000CC841002CC856F72CC861002CC87628FA2 -:10022000CC882304CC893C84CC8A6436CC8BDFF424 -:10023000CC8C6436CC8D2FF5CC8E3005CC8F865689 -:10024000CC90DFBACC9156A3CC92D05ACC9321C299 -:10025000CC943012CC951392CC96D05ACC9756A30E -:10026000CC98DFBACC990383CC9A6F72CC9B1002E6 -:10027000CC9C28C5CC9D3005CC9E4178CC9F565354 -:10028000CCA00384CCA122B2CCA23012CCA3100209 -:10029000CCA42BE5CCA53005CCA641E8CCA7565381 -:1002A000CCA80382CCA90002CCAA4258CCAB2474BF -:1002B000CCAC3C84CCAD6437CCAEDFF4CCAF64378F -:1002C000CCB02FF5CCB13C05CCB28757CCB3B888B5 -:1002D000CCB49787CCB5DFF4CCB66724CCB7866AAC -:1002E000CCB86F72CCB91002CCBA2D01CCBB301196 -:1002F000CCBC1001CCBDC620CCBE14E5CCBFC62101 -:10030000CCC0C53DCCC1C622CCC23CBECCC3C623EA -:10031000CCC44452CCC5C624CCC6C5C5CCC7C625A2 -:10032000CCC8E01ECCC9C627CCCA0000CCCBC6289E -:10033000CCCC0000CCCDC62BCCCE0000CCCFC62C74 -:10034000CCD00000CCD10000CCD22D01CCD33011C8 -:10035000CCD41001CCD5C620CCD60000CCD7C62139 -:10036000CCD80000CCD9C622CCDA00CECCDBC62358 -:10037000CCDC007FCCDDC624CCDE0032CCDFC62551 -:10038000CCE00000CCE1C627CCE20000CCE3C628DC -:10039000CCE40000CCE5C62BCCE60000CCE7C62CB4 -:1003A000CCE80000CCE90000CCEA2D01CCEB301108 -:1003B000CCEC1001CCEDC502CCEE609FCCEFC600BA -:1003C000CCF02A6ECCF1C601CCF22A2CCCF3C60CB0 -:1003D000CCF45400CCF5C710CCF60700CCF7C71806 -:1003E000CCF80700CCF9C720CCFA4700CCFBC728D3 -:1003F000CCFC0700CCFDC729CCFE1207CCFFC801FE -:10040000CD007F50CD01C802CD027760CD03C80377 -:10041000CD047FCECD05C804CD06520ECD07C8054C -:10042000CD085C11CD09C806CD0A3C51CD0BC807DB -:10043000CD0C4061CD0DC808CD0E49C1CD0FC80906 -:10044000CD103840CD11C80ACD120000CD13C821FF -:10045000CD140002CD15C822CD160046CD17C844D4 -:10046000CD18182FCD19C013CD1AF341CD1BC01ACA -:10047000CD1C0446CD1DC024CD1E1000CD1FC025AF -:10048000CD200A00CD21C026CD220C0CCD23C027C3 -:10049000CD240C0CCD25C029CD2600A0CD27C03001 -:1004A000CD280A00CD29C03CCD2A001CCD2B000050 -:1004B000CD2C2B84CD2D3C74CD2E6435CD2FDFF487 -:1004C000CD306435CD312806CD323006CD3385654B -:1004D000CD342B24CD353C24CD366436CD371002B7 -:1004E000CD382B24CD393C24CD3A6436CD3B404524 -:1004F000CD3C8656CD3D1002CD3E2807CD3F31A7DD -:10050000CD4020C4CD413C24CD426724CD431002D0 -:10051000CD442807CD453187CD4620C4CD473C2466 -:10052000CD486724CD491002CD4A2514CD4B3C64FB -:10053000CD4C6436CD4DDFF4CD4E6436CD4F100238 -:10054000CD502806CD513CB6CD52C161CD5361345A -:10055000CD546135CD555443CD560303CD57652455 -:10056000CD58000BCD591002CD5AD019CD5B2104C6 -:10057000CD5C3C24CD5D2105CD5E3805CD5F652485 -:10058000CD60DFF4CD614005CD626524CD632E8D55 -:10059000CD64303DCD655DD3CD660306CD672FF7C5 -:1005A000CD6838F7CD6960B7CD6ADFFDCD6B000A45 -:0C05B000CD6C1002CD6D000052A76B0E48 -:00000001FF diff --git a/firmware/cxgb3/ael2020_twx_edc.bin.ihex b/firmware/cxgb3/ael2020_twx_edc.bin.ihex deleted file mode 100644 index 8b1337f4c329466ce932ad3eb92e3e09a6fd08e5..0000000000000000000000000000000000000000 --- a/firmware/cxgb3/ael2020_twx_edc.bin.ihex +++ /dev/null @@ -1,100 +0,0 @@ -:10000000D8004009D8012FFFD802300FD80340AAEA -:10001000D804401CD805401ED8062FF4D8073DC48C -:10002000D8082035D8093035D80A6524D80B2CB229 -:10003000D80C3012D80D1002D80E26E2D80F30227C -:10004000D8101002D81127D2D8123022D81310029B -:10005000D8142822D8153012D8161002D817249296 -:10006000D8183022D8191002D81A2772D81B30128B -:10007000D81C1002D81D23D2D81E3022D81F10023F -:10008000D82022CDD821301DD82227F2D8233022E3 -:10009000D8241002D8255553D8260307D82725225F -:1000A000D8283022D8291002D82A2142D82B301241 -:1000B000D82C1002D82D4016D82E5E63D82F0344BA -:1000C000D8302142D8313012D8321002D833400E05 -:1000D000D8342522D8353022D8361002D8372B52C2 -:1000E000D8383012D8391002D83A2742D83B3022BB -:1000F000D83C1002D83D25E2D83E3022D83F10022D -:10010000D8402FA4D8413DC4D8426624D843414B9F -:10011000D84456B3D84503C6D846866BD847400C5A -:10012000D8482712D8493012D84A1002D84B2C4B45 -:10013000D84C309BD84D56B3D84E03C3D84F866B9E -:10014000D850400CD8512272D8523022D8531002C5 -:10015000D8542742D8553022D8561002D85725E215 -:10016000D8583022D8591002D85A2FB4D85B3DC481 -:10017000D85C6624D85D56B3D85E03C3D85F866B5F -:10018000D860401CD8612C45D8623095D8635B5349 -:10019000D8642372D8653012D86613C2D8675CC39E -:1001A000D8682712D8693012D86A1312D86B2B522C -:1001B000D86C3012D86D1002D86E2742D86F30221A -:1001C000D8701002D8712582D8723022D8731002EC -:1001D000D8742142D8753012D8761002D877628F41 -:1001E000D8782985D87933A5D87A25E2D87B3022EA -:1001F000D87C1002D87D5653D87E03D2D87F401EBB -:10020000D8806F72D8811002D882628FD88323047D -:10021000D8843C84D8856436D886DFF4D8876436A1 -:10022000D8882FF5D8893005D88A8656D88BDFBA7A -:10023000D88C56A3D88DD05AD88E2972D88F301228 -:10024000D8901392D891D05AD89256A3D893DFBAA7 -:10025000D8940383D8956F72D8961002D8972B45FF -:10026000D8983005D8994178D89A5653D89B0384AA -:10027000D89C2A62D89D3012D89E1002D89F2F0594 -:10028000D8A03005D8A141C8D8A25653D8A303821C -:10029000D8A40002D8A54218D8A62474D8A73C84B4 -:1002A000D8A86437D8A9DFF4D8AA6437D8AB2FF51B -:1002B000D8AC3C05D8AD8757D8AEB888D8AF9787AB -:1002C000D8B0DFF4D8B16724D8B2866AD8B36F72D9 -:1002D000D8B41002D8B52641D8B63021D8B710010D -:1002E000D8B8C620D8B90000D8BAC621D8BB0000FB -:1002F000D8BCC622D8BD00CED8BEC623D8BF007F8A -:10030000D8C0C624D8C10032D8C2C625D8C3000080 -:10031000D8C4C627D8C50000D8C6C628D8C700008C -:10032000D8C8C62CD8C90000D8CA0000D8CB2641EE -:10033000D8CC3021D8CD1001D8CEC502D8CF53ACFF -:10034000D8D0C503D8D12CD3D8D2C600D8D32A6EE2 -:10035000D8D4C601D8D52A2CD8D6C605D8D7555753 -:10036000D8D8C60CD8D95400D8DAC710D8DB0700C3 -:10037000D8DCC711D8DD0F06D8DEC718D8DF0700D4 -:10038000D8E0C719D8E10F06D8E2C720D8E3470064 -:10039000D8E4C721D8E50F06D8E6C728D8E7070074 -:1003A000D8E8C729D8E91207D8EAC801D8EB7F50A6 -:1003B000D8ECC802D8ED7760D8EEC803D8EF7FCE6E -:1003C000D8F0C804D8F1520ED8F2C805D8F35C11A1 -:1003D000D8F4C806D8F53C51D8F6C807D8F740611C -:1003E000D8F8C808D8F949C1D8FAC809D8FB3840A4 -:1003F000D8FCC80AD8FD0000D8FEC821D8FF0002EA -:10040000D900C822D9010046D902C844D903182FFF -:10041000D904C013D905F341D906C084D9070030E7 -:10042000D908C904D9091401D90ACB0CD90B000485 -:10043000D90CCB0ED90DA00AD90ECB0FD90FC0C045 -:10044000D910CB10D911C0C0D912CB11D91300A02B -:10045000D914CB12D9150007D916C241D917A0005B -:10046000D918C243D9197FE0D91AC604D91B000E86 -:10047000D91CC609D91D00F5D91EC611D91F000EF9 -:10048000D920C660D9219600D922C687D923000475 -:10049000D924C60AD92504F5D9260000D927264132 -:1004A000D9283021D9291001D92AC620D92B14E501 -:1004B000D92CC621D92DC53DD92EC622D92F3CBE57 -:1004C000D930C623D9314452D932C624D933C5C50F -:1004D000D934C625D935E01ED936C627D93700000C -:1004E000D938C628D9390000D93AC62CD93B0000E2 -:1004F000D93C0000D93D2B84D93E3C74D93F6435AA -:10050000D940DFF4D9416435D9422806D9433006B1 -:10051000D9448565D9452B24D9463C24D94764362E -:10052000D9481002D9492B24D94A3C24D94B6436E6 -:10053000D94C4045D94D8656D94E5663D94F030202 -:10054000D950401ED9511002D9522807D95331A78A -:10055000D95420C4D9553C24D9566724D957100200 -:10056000D9582807D9593187D95A20C4D95B3C2496 -:10057000D95C6724D95D1002D95E24F4D95F3C644C -:10058000D9606436D961DFF4D9626436D963100268 -:10059000D9642006D9653D76D966C161D9676134D1 -:1005A000D9686135D9695443D96A0303D96B652485 -:1005B000D96C00FBD96D1002D96E20D4D96F3C24C0 -:1005C000D9702025D9713005D9726524D9731002EC -:1005D000D974D019D9752104D9763C24D97721054D -:1005E000D9783805D9796524D97ADFF4D97B4005E3 -:1005F000D97C6524D97D2E8DD97E303DD97F2408C4 -:10060000D98035D8D9815DD3D9820307D98388872A -:10061000D98463A7D9858887D98663A7D987DFFD61 -:10062000D98800F9D9891002D98A0000878C30D97D -:00000001FF diff --git a/firmware/cxgb3/t3b_psram-1.1.0.bin.ihex b/firmware/cxgb3/t3b_psram-1.1.0.bin.ihex deleted file mode 100644 index 140893005171120eb7a59c30882b54121993a021..0000000000000000000000000000000000000000 --- a/firmware/cxgb3/t3b_psram-1.1.0.bin.ihex +++ /dev/null @@ -1,162 +0,0 @@ -:10000000FFFFFFFC000000000000000300000000F4 -:1000100000010100FFFFFFFC0000000000000003E2 -:100020000000000000000000FFFFFFFC00000000D7 -:10003000000000030000000000000000FFFFFFFCC4 -:1000400000000000000000030000000000000000AD -:10005000FFFFFFFC000000000000000300000000A4 -:1000600000000000FFFFFFFC000000000000000394 -:100070000000000000000000FFFFFFFC0000000087 -:10008000000000030000000000000000FFFFFFFC74 -:10009000000000000000000300000000000000005D -:1000A000FFFFFFFC00000000000000030000000054 -:1000B00000000000FFFFFFFC000000000000000344 -:1000C0000000000000000000FFFFFFFC0000000037 -:1000D000000000030000000000000000FFFFFFFC24 -:1000E000000000000000000300000000000000000D -:1000F000FFFFFFFC00000000000000030000000004 -:1001000000000000FFFFFFFC0000000000000003F3 -:100110000000000000000000FFFFFFFBD03403E6FA -:1001200080262A430000000000000000FFFFFFF8C7 -:10013000007000000000000200000081C604000002 -:10014000FFFFFFFC000000000000000300000000B3 -:1001500000000000FFFFFFFC0000000000000003A3 -:100160000000000000000000FFFFFFFC0000000096 -:10017000000000030000000000000000FFFFFFFC83 -:10018000000000000000000300000000000000006C -:10019000FFFFFFFC00000000000000030000000063 -:1001A00000000000FFFFFFFC000000000000000353 -:1001B0000000000000000000FFFFFFFBD03403E25E -:1001C000802829230000000000000000FFFFFFF846 -:1001D0000600023701C5C00013940481C6057000F3 -:1001E000FFFFFFF88200020637030803000000004B -:1001F00000000000FFFFFFFC000000000000000204 -:10020000208000818DF40000FFFFFFFC0000000053 -:10021000000000030000000000000000FFFFFFFCE2 -:1002200000000000000000030000000000000000CB -:10023000FFFFFFFC000000000000000300000000C2 -:1002400000000000FFFFFFFC0000000000000003B2 -:100250000000000000000000FFFFFFF9C4310000B3 -:1002600000282C830000000000000000FFFFFFF0CA -:100270004E70021D00C5C00000000001C118000042 -:10028000FFFFFFFC00000000000000030000000072 -:1002900000000000FFFFFFFC000000000000000362 -:1002A0000000000000000000FFFFFFFC0000000055 -:1002B000000000030000000000000000FFFFFFFC42 -:1002C000000000000000000300000000000000002B -:1002D000FFFFFFFC00000000000000030000000022 -:1002E00000000000FFFFFFFC000000000000000312 -:1002F0000000000000000000FFFFFFF1C00003E667 -:10030000802828230000000000000000FFFFFFFC01 -:1003100000000000000000021394040000017000BF -:10032000FFFFFFFC000000000000000300000000D1 -:1003300000000000FFFFFFFC0000000000000003C1 -:100340000000000000000000FFFFFFFC00000000B4 -:10035000000000030000000000000000FFFFFFFCA1 -:10036000000000000000000300000000000000008A -:10037000FFFFFFFC00000000000000030000000081 -:1003800000000000FFFFFFFC000000000000000371 -:100390000000000000000000FFFFFFFA103400041E -:1003A000000001030000000000000000FFFFFFF05C -:1003B0006000000620030802700000F080259A907B -:1003C000FFFFFFFC00000000000000030000000031 -:1003D00000000000FFFFFFFC000000000000000321 -:1003E0000000000000000000FFFFFFFC0000000014 -:1003F000000000030000000000000000FFFFFFFC01 -:1004000000000000000000030000000000000000E9 -:10041000FFFFFFF1C83102060A000242000000811E -:1004200080000000FFFFFFF9C83103C60A962A4288 -:100430000000008180000000FFFFFFF00431000495 -:10044000000004030000000000000000FFFFFFF0B8 -:1004500020B000000000000213940401C1197000D4 -:10046000FFFFFFFC00000000000000000000000192 -:1004700000001000FFFFFFFC000000000000000370 -:100480000000000000000000FFFFFFFC0000000073 -:10049000000000030000000000000000FFFFFFFC60 -:1004A0000000000000000003000000000000000049 -:1004B000FFFFFFF00000000400004000680C200176 -:1004C00000001090FFFFFFF9C031C3E600266A402C -:1004D0000000000100001000FFFFFFFA10F4000010 -:1004E000000002430000000000000000FFFFFFF8D2 -:1004F0006050080000000000700C20F080259A90E9 -:10050000FFFFFFF0060000000100400000000001B6 -:1005100000001000FFFFFFFC0000000000000002D0 -:10052000288C108085C01000FFFFFFFC0000000039 -:10053000000000030000000000000000FFFFFFFCBF -:1005400000000000000000030000000000000000A8 -:10055000FFFFFFFC0000000000000003000000009F -:1005600000000000FFFFFFFC00000000000000038F -:100570000000000000000000FFFFFFF04E00000040 -:10058000000000030000000000000000FFFFFFF17A -:10059000C00002DE00061A40000000829035C00054 -:1005A000FFFFFFFC0000000000000003000000004F -:1005B00000000000FFFFFFFC00000000000000033F -:1005C0000000000000000000FFFFFFFC0000000032 -:1005D000000000030000000000000000FFFFFFFC1F -:1005E0000000000000000003000000000000000008 -:1005F000FFFFFFFC000000000000000300000000FF -:1006000000000000FFFFFFF1CA31C3C20A966A432F -:100610000000000000000000FFFFFFF84E501439FA -:100620001CC5C0030000000000000000FFFFFFF039 -:100630000000000000000002288C108085C010001F -:10064000FFFFFFFC000000000000000300000000AE -:1006500000000000FFFFFFFC00000000000000039E -:100660000000000000000000FFFFFFFC0000000091 -:10067000000000030000000000000000FFFFFFFC7E -:100680000000000000000003000000000000000067 -:10069000FFFFFFFC0000000000000003000000005E -:1006A00000000000FFFFFFF3CA3323D60E966A4313 -:1006B0000000000000000000FFFFFFF8000004063B -:1006C00020D002430000000000000000FFFFFFF800 -:1006D00000D0000000000000000000839031C00046 -:1006E000FFFFFFFC0000000000000003000000000E -:1006F00000000000FFFFFFFC0000000000000003FE -:100700000000000000000000FFFFFFFC00000000F0 -:10071000000000030000000000000000FFFFFFFCDD -:1007200000000000000000030000000000000000C6 -:10073000FFFFFFFC000000000000000300000000BD -:1007400000000000FFFFFFF3CA33E3D60E966A43B2 -:100750000000000000000000FFFFFFF000501A1032 -:10076000003002430000000000000000FFFFFFF81F -:100770000000020620030800700000F990118A9022 -:10078000FFFFFFFC0000000000000003000000006D -:1007900000000000FFFFFFFC00000000000000035D -:1007A0000000000000000000FFFFFFFC0000000050 -:1007B000000000030000000000000000FFFFFFFC3D -:1007C0000000000000000003000000000000000026 -:1007D000FFFFFFFC0000000000000003000000001D -:1007E00000000000FFFFFFFC00000000000000030D -:1007F0000000000000000000FFFFFFF9C0501BA632 -:1008000000D202430000000000000000FFFFFFF0E4 -:100810004000020700100002700000E890344A9087 -:10082000FFFFFFFC000000000000000300000000CC -:1008300000000000FFFFFFFC0000000000000003BC -:100840000000000000000000FFFFFFFC00000000AF -:10085000000000030000000000000000FFFFFFFC9C -:100860000000000000000003000000000000000085 -:10087000FFFFFFFC0000000000000003000000007C -:1008800000000000FFFFFFFC00000000000000036C -:100890000000000000000000FFFFFFFA10F4020853 -:1008A00000C002430000000000000000FFFFFFF056 -:1008B0000000000000000000728CC8D893891090DE -:1008C000FFFFFFF082900000030000030000000023 -:1008D00000000000FFFFFFFC00000000000000031C -:1008E0000000000000000000FFFFFFFC000000000F -:1008F000000000030000000000000000FFFFFFFCFC -:1009000000000000000000030000000000000000E4 -:10091000FFFFFFFC000000000000000300000000DB -:1009200000000000FFFFFFFC0000000000000003CB -:100930000000000000000000FFFFFFF000000000CA -:10094000000000030000000000000000FFFFFFF2B5 -:1009500000000320002612430000000000000000F9 -:10096000FFFFFFF040000203101000030000000032 -:1009700000000000FFFFFFFC00000000000000037B -:100980000000000000000000FFFFFFFC000000006E -:10099000000000030000000000000000FFFFFFFC5B -:1009A0000000000000000003000000000000000044 -:1009B000FFFFFFFC0000000000000003000000003B -:1009C00000000000FFFFFFFC00000000000000032B -:1009D0000000000000000000FFFFFFF1D03403E63C -:1009E00080262A430000000000000000FFFFFFF205 -:1009F0000834023000C005030000000000000000C1 -:040A000070EAA57F74 -:00000001FF diff --git a/firmware/cxgb3/t3c_psram-1.1.0.bin.ihex b/firmware/cxgb3/t3c_psram-1.1.0.bin.ihex deleted file mode 100644 index c6504803852ff824429ee21632e1733f6e8b27f7..0000000000000000000000000000000000000000 --- a/firmware/cxgb3/t3c_psram-1.1.0.bin.ihex +++ /dev/null @@ -1,162 +0,0 @@ -:10000000FFFFFFF4000000040000000100000001F9 -:1000100000010100FFFFFFF40000000400000001E8 -:100020000000000100000000FFFFFFF400000004DA -:10003000000000010000000100000000FFFFFFF4CD -:1000400000000004000000010000000100000000AA -:10005000FFFFFFF4000000040000000100000001A9 -:1000600000000000FFFFFFF400000004000000019A -:100070000000000100000000FFFFFFF4000000048A -:10008000000000010000000100000000FFFFFFF47D -:10009000000000040000000100000001000000005A -:1000A000FFFFFFF400000004000000010000000159 -:1000B00000000000FFFFFFF400000004000000014A -:1000C0000000000100000000FFFFFFF4000000043A -:1000D000000000010000000100000000FFFFFFF42D -:1000E000000000040000000100000001000000000A -:1000F000FFFFFFF400000004000000010000000109 -:1001000000000000FFFFFFF40000000400000001F9 -:100110000000000100000000FFFFFFF3D03403E205 -:1001200080262A410000000100000000FFFFFFF8C8 -:10013000007000000000000000000080C604000005 -:10014000FFFFFFF4000000040000000100000001B8 -:1001500000000000FFFFFFF40000000400000001A9 -:100160000000000100000000FFFFFFF40000000499 -:10017000000000010000000100000000FFFFFFF48C -:100180000000000400000001000000010000000069 -:10019000FFFFFFF400000004000000010000000168 -:1001A00000000000FFFFFFF4000000040000000159 -:1001B0000000000100000000FFFFFFFBD03403E25D -:1001C000802829210000000100000000FFFFFFF847 -:1001D0000600023701C5C00213940480C6057000F2 -:1001E000FFFFFFF88200020637030801000000014C -:1001F00000000000FFFFFFF400000004000000000A -:10020000208000808DF40000FFFFFFF40000000458 -:10021000000000010000000100000000FFFFFFF4EB -:1002200000000004000000010000000100000000C8 -:10023000FFFFFFF4000000040000000100000001C7 -:1002400000000000FFFFFFF40000000400000001B8 -:100250000000000100000000FFFFFFF9C4310000B2 -:1002600000282C810000000100000000FFFFFFF0CB -:100270004E70021D00C5C00200000000C118000041 -:10028000FFFFFFF400000004000000010000000177 -:1002900000000000FFFFFFF4000000040000000168 -:1002A0000000000100000000FFFFFFF40000000458 -:1002B000000000010000000100000000FFFFFFF44B -:1002C0000000000400000001000000010000000028 -:1002D000FFFFFFF400000004000000010000000127 -:1002E00000000000FFFFFFF4000000040000000118 -:1002F0000000000100000000FFFFFFF1C00003E666 -:10030000802828210000000100000000FFFFFFF40A -:1003100000000004000000021394040000017000BB -:10032000FFFFFFF4000000040000000100000001D6 -:1003300000000000FFFFFFF40000000400000001C7 -:100340000000000100000000FFFFFFF400000004B7 -:10035000000000010000000100000000FFFFFFF4AA -:100360000000000400000001000000010000000087 -:10037000FFFFFFF400000004000000010000000186 -:1003800000000000FFFFFFF4000000040000000177 -:100390000000000100000000FFFFFFFA103400041D -:1003A000000001010000000100000000FFFFFFF05D -:1003B0006000000620030802700000F080259A907B -:1003C000FFFFFFF400000004000000010000000136 -:1003D00000000000FFFFFFF4000000040000000127 -:1003E0000000000100000000FFFFFFF40000000417 -:1003F000000000010000000100000000FFFFFFF40A -:1004000000000004000000010000000100000000E6 -:10041000FFFFFFF9C83102020A000242000000811A -:1004200080000000FFFFFFF1C83103C20A962A4294 -:100430000000008180000000FFFFFFF00431000495 -:10044000000004010000000100000000FFFFFFF8B1 -:1004500020B000040000000013940400C1197000D3 -:10046000FFFFFFF400000004000000020000000095 -:1004700000001000FFFFFFF4000000040000000176 -:100480000000000100000000FFFFFFF40000000476 -:10049000000000010000000100000000FFFFFFF469 -:1004A0000000000400000001000000010000000046 -:1004B000FFFFFFF80000000000004000680C200172 -:1004C00000001090FFFFFFF9C031C3E600266A422A -:1004D0000000000000001000FFFFFFF210F4000415 -:1004E000000002410000000100000000FFFFFFF0DB -:1004F0006050080400000002700C20F180259A90E2 -:10050000FFFFFFF8060000040100400200000000A9 -:1005100000001000FFFFFFF40000000400000002D4 -:10052000288C108085C01000FFFFFFF4000000043D -:10053000000000010000000100000000FFFFFFF4C8 -:1005400000000004000000010000000100000000A5 -:10055000FFFFFFF4000000040000000100000001A4 -:1005600000000000FFFFFFF4000000040000000195 -:100570000000000100000000FFFFFFF04E0000003F -:10058000000000010000000100000000FFFFFFF973 -:10059000C00002DA00061A42000000839035C00055 -:1005A000FFFFFFF400000004000000010000000154 -:1005B00000000000FFFFFFF4000000040000000145 -:1005C0000000000100000000FFFFFFF40000000435 -:1005D000000000010000000100000000FFFFFFF428 -:1005E0000000000400000001000000010000000005 -:1005F000FFFFFFF400000004000000010000000104 -:1006000000000000FFFFFFF9CA31C3C60A966A4125 -:100610000000000100000000FFFFFFF84E501439F9 -:100620001CC5C0010000000100000000FFFFFFF03A -:100630000000000000000002288C108085C010001F -:10064000FFFFFFF4000000040000000100000001B3 -:1006500000000000FFFFFFF40000000400000001A4 -:100660000000000100000000FFFFFFF40000000494 -:10067000000000010000000100000000FFFFFFF487 -:100680000000000400000001000000010000000064 -:10069000FFFFFFF400000004000000010000000163 -:1006A00000000000FFFFFFF3CA3323D60E966A4115 -:1006B0000000000100000000FFFFFFF8000004063A -:1006C00020D002410000000100000000FFFFFFF801 -:1006D00000D0000000000000000000839031C00046 -:1006E000FFFFFFF400000004000000010000000113 -:1006F00000000000FFFFFFF4000000040000000104 -:100700000000000100000000FFFFFFF400000004F3 -:10071000000000010000000100000000FFFFFFF4E6 -:1007200000000004000000010000000100000000C3 -:10073000FFFFFFF4000000040000000100000001C2 -:1007400000000000FFFFFFFBCA33E3D20E966A41B0 -:100750000000000100000000FFFFFFF000501A1031 -:10076000003002410000000100000000FFFFFFF028 -:100770000000020220030800700000F990118A9026 -:10078000FFFFFFF400000004000000010000000172 -:1007900000000000FFFFFFF4000000040000000163 -:1007A0000000000100000000FFFFFFF40000000453 -:1007B000000000010000000100000000FFFFFFF446 -:1007C0000000000400000001000000010000000023 -:1007D000FFFFFFF400000004000000010000000122 -:1007E00000000000FFFFFFF4000000040000000113 -:1007F0000000000100000000FFFFFFF1C0501BA23D -:1008000000D202410000000100000000FFFFFFF8DD -:100810004000020300100002700000E890344A908B -:10082000FFFFFFF4000000040000000100000001D1 -:1008300000000000FFFFFFF40000000400000001C2 -:100840000000000100000000FFFFFFF400000004B2 -:10085000000000010000000100000000FFFFFFF4A5 -:100860000000000400000001000000010000000082 -:10087000FFFFFFF400000004000000010000000181 -:1008800000000000FFFFFFF4000000040000000172 -:100890000000000100000000FFFFFFFA10F4020852 -:1008A00000C002410000000100000000FFFFFFF057 -:1008B0000000000000000002728CC8D993891090DB -:1008C000FFFFFFF082900000030000010000000124 -:1008D00000000000FFFFFFF4000000040000000122 -:1008E0000000000100000000FFFFFFF40000000412 -:1008F000000000010000000100000000FFFFFFF405 -:1009000000000004000000010000000100000000E1 -:10091000FFFFFFF4000000040000000100000001E0 -:1009200000000000FFFFFFF40000000400000001D1 -:100930000000000100000000FFFFFFF000000000C9 -:10094000000000010000000100000000FFFFFFF2B6 -:1009500000000320002612410000000100000000FA -:10096000FFFFFFF040000203101000010000000133 -:1009700000000000FFFFFFF4000000040000000181 -:100980000000000100000000FFFFFFF40000000471 -:10099000000000010000000100000000FFFFFFF464 -:1009A0000000000400000001000000010000000041 -:1009B000FFFFFFF400000004000000010000000140 -:1009C00000000000FFFFFFF4000000040000000131 -:1009D0000000000100000000FFFFFFF9D03403E237 -:1009E00080262A410000000100000000FFFFFFF206 -:1009F0000834023000C005010000000100000000C2 -:040A000070EAA741B0 -:00000001FF diff --git a/firmware/dsp56k/bootstrap.asm b/firmware/dsp56k/bootstrap.asm deleted file mode 100644 index a411047e6db35b4b91727f23ce180bc6053ca112..0000000000000000000000000000000000000000 --- a/firmware/dsp56k/bootstrap.asm +++ /dev/null @@ -1,98 +0,0 @@ -; Author: Frederik Noring -; -; This file is subject to the terms and conditions of the GNU General Public -; License. See the file COPYING in the main directory of this archive -; for more details. - -; DSP56k loader - -; Host Interface -M_BCR EQU $FFFE ; Port A Bus Control Register -M_PBC EQU $FFE0 ; Port B Control Register -M_PBDDR EQU $FFE2 ; Port B Data Direction Register -M_PBD EQU $FFE4 ; Port B Data Register -M_PCC EQU $FFE1 ; Port C Control Register -M_PCDDR EQU $FFE3 ; Port C Data Direction Register -M_PCD EQU $FFE5 ; Port C Data Register - -M_HCR EQU $FFE8 ; Host Control Register -M_HSR EQU $FFE9 ; Host Status Register -M_HRX EQU $FFEB ; Host Receive Data Register -M_HTX EQU $FFEB ; Host Transmit Data Register - -; SSI, Synchronous Serial Interface -M_RX EQU $FFEF ; Serial Receive Data Register -M_TX EQU $FFEF ; Serial Transmit Data Register -M_CRA EQU $FFEC ; SSI Control Register A -M_CRB EQU $FFED ; SSI Control Register B -M_SR EQU $FFEE ; SSI Status Register -M_TSR EQU $FFEE ; SSI Time Slot Register - -; Exception Processing -M_IPR EQU $FFFF ; Interrupt Priority Register - - org P:$0 -start jmp <$40 - - org P:$40 -; ; Zero 16384 DSP X and Y words -; clr A #0,r0 -; clr B #0,r4 -; do #64,<_block1 -; rep #256 -; move A,X:(r0)+ B,Y:(r4)+ -;_block1 ; Zero (32768-512) Program words -; clr A #512,r0 -; do #126,<_block2 -; rep #256 -; move A,P:(r0)+ -;_block2 - - ; Copy DSP program control - move #real,r0 - move #upload,r1 - do #upload_end-upload,_copy - movem P:(r0)+,x0 - movem x0,P:(r1)+ -_copy movep #4,X:<3,x0 - cmp x0,A #>1,x0 - jeq <$0 -_get_address - jclr #0,X:<2,x0 - jeq load_X - cmp x0,A - jeq load_Y - -load_P do y0,_load_P - jclr #0,X:< - * Copyright © 2005 Jan Harkes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define _GNU_SOURCE -#include - - -struct ihex_binrec { - struct ihex_binrec *next; /* not part of the real data structure */ - uint32_t addr; - uint16_t len; - uint8_t data[]; -}; - -/** - * nybble/hex are little helpers to parse hexadecimal numbers to a byte value - **/ -static uint8_t nybble(const uint8_t n) -{ - if (n >= '0' && n <= '9') return n - '0'; - else if (n >= 'A' && n <= 'F') return n - ('A' - 10); - else if (n >= 'a' && n <= 'f') return n - ('a' - 10); - return 0; -} - -static uint8_t hex(const uint8_t *data, uint8_t *crc) -{ - uint8_t val = (nybble(data[0]) << 4) | nybble(data[1]); - *crc += val; - return val; -} - -static int process_ihex(uint8_t *data, ssize_t size); -static void file_record(struct ihex_binrec *record); -static int output_records(int outfd); - -static int sort_records = 0; -static int wide_records = 0; -static int include_jump = 0; - -static int usage(void) -{ - fprintf(stderr, "ihex2fw: Convert ihex files into binary " - "representation for use by Linux kernel\n"); - fprintf(stderr, "usage: ihex2fw [] \n"); - fprintf(stderr, " -w: wide records (16-bit length)\n"); - fprintf(stderr, " -s: sort records by address\n"); - fprintf(stderr, " -j: include records for CS:IP/EIP address\n"); - return 1; -} - -int main(int argc, char **argv) -{ - int infd, outfd; - struct stat st; - uint8_t *data; - int opt; - - while ((opt = getopt(argc, argv, "wsj")) != -1) { - switch (opt) { - case 'w': - wide_records = 1; - break; - case 's': - sort_records = 1; - break; - case 'j': - include_jump = 1; - break; - default: - return usage(); - } - } - - if (optind + 2 != argc) - return usage(); - - if (!strcmp(argv[optind], "-")) - infd = 0; - else - infd = open(argv[optind], O_RDONLY); - if (infd == -1) { - fprintf(stderr, "Failed to open source file: %s", - strerror(errno)); - return usage(); - } - if (fstat(infd, &st)) { - perror("stat"); - return 1; - } - data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, infd, 0); - if (data == MAP_FAILED) { - perror("mmap"); - return 1; - } - - if (!strcmp(argv[optind+1], "-")) - outfd = 1; - else - outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644); - if (outfd == -1) { - fprintf(stderr, "Failed to open destination file: %s", - strerror(errno)); - return usage(); - } - if (process_ihex(data, st.st_size)) - return 1; - - return output_records(outfd); -} - -static int process_ihex(uint8_t *data, ssize_t size) -{ - struct ihex_binrec *record; - uint32_t offset = 0; - uint32_t data32; - uint8_t type, crc = 0, crcbyte = 0; - int i, j; - int line = 1; - int len; - - i = 0; -next_record: - /* search for the start of record character */ - while (i < size) { - if (data[i] == '\n') line++; - if (data[i++] == ':') break; - } - - /* Minimum record length would be about 10 characters */ - if (i + 10 > size) { - fprintf(stderr, "Can't find valid record at line %d\n", line); - return -EINVAL; - } - - len = hex(data + i, &crc); i += 2; - if (wide_records) { - len <<= 8; - len += hex(data + i, &crc); i += 2; - } - record = malloc((sizeof (*record) + len + 3) & ~3); - if (!record) { - fprintf(stderr, "out of memory for records\n"); - return -ENOMEM; - } - memset(record, 0, (sizeof(*record) + len + 3) & ~3); - record->len = len; - - /* now check if we have enough data to read everything */ - if (i + 8 + (record->len * 2) > size) { - fprintf(stderr, "Not enough data to read complete record at line %d\n", - line); - return -EINVAL; - } - - record->addr = hex(data + i, &crc) << 8; i += 2; - record->addr |= hex(data + i, &crc); i += 2; - type = hex(data + i, &crc); i += 2; - - for (j = 0; j < record->len; j++, i += 2) - record->data[j] = hex(data + i, &crc); - - /* check CRC */ - crcbyte = hex(data + i, &crc); i += 2; - if (crc != 0) { - fprintf(stderr, "CRC failure at line %d: got 0x%X, expected 0x%X\n", - line, crcbyte, (unsigned char)(crcbyte-crc)); - return -EINVAL; - } - - /* Done reading the record */ - switch (type) { - case 0: - /* old style EOF record? */ - if (!record->len) - break; - - record->addr += offset; - file_record(record); - goto next_record; - - case 1: /* End-Of-File Record */ - if (record->addr || record->len) { - fprintf(stderr, "Bad EOF record (type 01) format at line %d", - line); - return -EINVAL; - } - break; - - case 2: /* Extended Segment Address Record (HEX86) */ - case 4: /* Extended Linear Address Record (HEX386) */ - if (record->addr || record->len != 2) { - fprintf(stderr, "Bad HEX86/HEX386 record (type %02X) at line %d\n", - type, line); - return -EINVAL; - } - - /* We shouldn't really be using the offset for HEX86 because - * the wraparound case is specified quite differently. */ - offset = record->data[0] << 8 | record->data[1]; - offset <<= (type == 2 ? 4 : 16); - goto next_record; - - case 3: /* Start Segment Address Record */ - case 5: /* Start Linear Address Record */ - if (record->addr || record->len != 4) { - fprintf(stderr, "Bad Start Address record (type %02X) at line %d\n", - type, line); - return -EINVAL; - } - - memcpy(&data32, &record->data[0], sizeof(data32)); - data32 = htonl(data32); - memcpy(&record->data[0], &data32, sizeof(data32)); - - /* These records contain the CS/IP or EIP where execution - * starts. If requested output this as a record. */ - if (include_jump) - file_record(record); - goto next_record; - - default: - fprintf(stderr, "Unknown record (type %02X)\n", type); - return -EINVAL; - } - - return 0; -} - -static struct ihex_binrec *records; - -static void file_record(struct ihex_binrec *record) -{ - struct ihex_binrec **p = &records; - - while ((*p) && (!sort_records || (*p)->addr < record->addr)) - p = &((*p)->next); - - record->next = *p; - *p = record; -} - -static int output_records(int outfd) -{ - unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0}; - struct ihex_binrec *p = records; - - while (p) { - uint16_t writelen = (p->len + 9) & ~3; - - p->addr = htonl(p->addr); - p->len = htons(p->len); - if (write(outfd, &p->addr, writelen) != writelen) - return 1; - p = p->next; - } - /* EOF record is zero length, since we don't bother to represent - the type field in the binary version */ - if (write(outfd, zeroes, 6) != 6) - return 1; - return 0; -} diff --git a/firmware/kaweth/new_code.bin.ihex b/firmware/kaweth/new_code.bin.ihex deleted file mode 100644 index 292d40f4f3343806fbb031866760a696d7510615..0000000000000000000000000000000000000000 --- a/firmware/kaweth/new_code.bin.ihex +++ /dev/null @@ -1,206 +0,0 @@ -:10000000B6C3AABBCCDD9FCFDE06E7570000C4060F -:1000100097C1E767FF1F28C0E787000424C0E76790 -:10002000FFF922C097CFD70900C0E709A2C0BE06DA -:100030009FAF3600E70500C0A7CFBC0697CFE757B4 -:100040000000B806A7A1B80697CFE757000014082C -:100050000AC0E7570000A4C0A7C07A069FAF920766 -:10006000E70700001408E757FFFFBA069FA0380013 -:10007000E759BA06BE069FA03800C809CA0608623A -:100080009FA13608C00976060060A7C07A069FAF18 -:10009000CC02E7570000B806A7C17A069FAF04005C -:1000A000E75700008E060AC1E70920C01008E7D014 -:1000B0001008E767400010089FAF920CC009D006F7 -:1000C000006005C4C059BE0602C09FAFEC009FAFE0 -:1000D0003402E7570000A6069FA07A02A7CF7A064F -:1000E0004802E709BE06D006C83704009FAF0803E0 -:1000F00097CFE7570000CE0697C0D70900C0C1DFF1 -:10010000C809C606086214C02704C6061094F00782 -:1001100010080200C107010070000400F007300160 -:10012000060050AFE707FFFFD006E7070000CE0646 -:10013000E70500C097CFD70900C0C1DF4802D0094A -:10014000C6062702C606E70500C097CF4802C83793 -:100150000400000C0C00006021C0C0373E0023C921 -:10016000C057B4051BC8C0173F00C067C0FF3000B0 -:100170000800F007000004000002C0174C00300027 -:100180000600F007A0010A004802C1070200D709D3 -:1001900000C0C1DF51AFE70500C097CF9FAF080394 -:1001A0009FAF7A0297CF9FAF7A02C9370400C1DFB1 -:1001B000C809A20650026702A206D107000027D88C -:1001C000AA06C0DF9FAFC40197CFE7570000D20651 -:1001D00097C1E7570100A80697C0C809A0060862A2 -:1001E00097C00002C0170E0027003401270C0C0036 -:1001F0003601E70750C312C0E707CC0B0200E70740 -:100200000100A806E707050090C097CFC809A4061B -:10021000086202C0106407C1E70700009E06E707F6 -:100220007204240097CF2704A406C8170E002702E3 -:100230009E06E7078004240097CFD70900C0C1DFDE -:10024000E7570000900613C19FAF0602E757000072 -:100250009E0613C0E7099E063001E707F20532014A -:10026000E707100096C0E7099E06900604CFE757FF -:1002700000009E0602C19FAF0602E70500C097CFAF -:10028000D70900C0C1DF0892E7570200AA0602C3DF -:10029000C809A4062702A606086203C1E70500C034 -:1002A00097CF2704A406E70500C0F0074000080028 -:1002B000F007000004000002C0170C003000060028 -:1002C000F00746010A00C8170400C107020051AF39 -:1002D00097CFE7570000960697C0C1DFC80996067A -:1002E000270496062752980603C1E7079606980644 -:1002F000C0DF1702C8170E009FAFBA03C805006021 -:1003000003C09FAF240397CF9FAF080397CF570237 -:10031000C907A406D70900C0C1DF08621BC050048A -:100320001102E70500C0C90597CF9702CA09D60692 -:10033000F21701000400F22700000600CA172C0083 -:10034000F87701000E0006C0CAD9F857FF000E006A -:1003500001C1CAD9221C0C00E2270000E2170100EB -:10036000E2270000CA05000C0C00C0174100C0675E -:10037000C0FF300008000002C0170C00300006006B -:10038000F007DA000A00F00700000400000C080083 -:1003900040D10100C019CE06C059C20604C949AFF8 -:1003A0009FAFEC004AAF6710CE06C8170400C10724 -:1003B0000100D70900C0C1DF50AFE70500C097CFEB -:1003C000C0070100C109AC06C177010097C1D87709 -:1003D000010012C0C9076A069FAF080404C1C177B3 -:1003E000080013C097CFC177020097C1C1771000F2 -:1003F0000CC09FAF2C0497CFC177040006C0C9077B -:1004000070069FAF080497C000CF009097CF50545C -:1004100097C1705C0200020097C1705C0400040088 -:1004200097CF8001C0006000300018000C0006006B -:100430000000CB09B206CC09B4060B5311C0C902A7 -:10044000CA071C049FAF080497C00AC882080ACFD5 -:1004500082089FAF080497C005C28930826078C1C6 -:10046000009097CF8910095379C2893082087ACFDA -:10047000C0DF97CFC0DF97CFE70996C09206E709A4 -:1004800098C094060FCFE70996C09206E70998C076 -:100490009406E7099E063001E707F2053201E707F7 -:1004A000100096C0D70900C01702C8099006C837C7 -:1004B0000E00E7772A00920630C09702CA09D606D6 -:1004C000E777200092060EC0F21701001000F22715 -:1004D00000001200E7770A009206CA051EC09702C4 -:1004E000CA09D606F21701000C00F22700000E0020 -:1004F000E7770200920607C0F21701004400F227D6 -:100500000000460006CFF21701006000F22700004D -:100510006200CA059FAF08030FCF57020902F10915 -:1005200094060C00F1DA0C00C80998065002670224 -:100530009806D1070000C905E7099E069006E7570F -:100540000000900602C09FAF0602C805E70500C084 -:10055000C0DF97CFD70900C0170017029702C00964 -:1005600092C0E707040090C0CA09D606E70700005A -:10057000A806E7076A040200C077020008C0F21765 -:1005800001005000F227000052009FCF2406C077E0 -:10059000100006C0F21701005800F22700005A00B0 -:1005A000C077800006C0F21701007000F22700003B -:1005B0007200C07708001DC1F21701000800F22781 -:1005C00000000A00C077000206C0F21701006400B4 -:1005D000F22700006600C077400006C0F217010055 -:1005E0005C00F22700005E00C077010001C01BCF55 -:1005F0001ACFF21701000000F22700000200C8091C -:100600003401CA171400D877010005C0CAD9D857D9 -:10061000FF0001C0CAD9E21994C0E2270000E21726 -:100620000100E22700009FAF40069FAFC401E757DB -:100630000000D2069FA10E0ACA05C805C005E7053D -:1006400000C0C0DF97CFC809A006086297C0270482 -:10065000A0062752A20603C1E707A006A2069FAF85 -:100660000803E7570000AA0602C027DAAA0697CFB8 -:10067000FFFFFFFFFFFF0000000000000000000080 -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C00000000000000000003F00000000000000EB -:1006D000000000000000FFFF01000000000000001B -:1006E000FFFFFB13E7570080B20006C2E707EE0BDF -:1006F0001200E707340CB200E707C607F202C80988 -:10070000B400F80702000D00D7090EC0E70700008B -:100710000EC0C809DE00C8170900C907DA06C007FD -:100720000400680A00DA7DC1E709C0007C06E70919 -:10073000BE007806E7091000BC06C807D6079FAFC1 -:10074000AE079FAF000AC809DE00000E0F004190FF -:100750009FDE060044AF2700B2062700B40627003C -:10076000B606C007740044AF2700D6060800009004 -:10077000C1073A00200001DA7DC19FAFBA09C00766 -:10078000440048AF27007A069FAF960AE7070100AA -:10079000C006E7050EC097CF49AFE78743000EC0FC -:1007A000E707FFFFBE069FAFAE0AC007010060AFBC -:1007B0004AAF97CF00080908110800DA7CC197CF2B -:1007C0006704CC02C0DF5194B1AF0600C1DFC90994 -:1007D000CC02496275C1C0DFA7CFD6020E0024004B -:1007E000800422004E05D0000E0AAA003008BE0088 -:1007F0004A0A1000200004006E0402006A04060089 -:10080000000024C0040428C0FEFB1EC0000422C057 -:10081000FFF4C000900900000000FFFF56086008C8 -:10082000D008DA0800090409080932094209500908 -:1008300052095A095A092702CA0697CFE70700004A -:10084000CA060A0E0100CA570E009FC35A09CA37CA -:1008500000009FC25A090AD2B2CF1608C809DE00AA -:1008600007069FCF6C091702C809DE00000E0F00B3 -:1008700041909FDE0600C805305006009FC85A0907 -:10088000270C0200B006C009B2062700B406E7072D -:100890000000AE0627008006001C06002700B606F2 -:1008A00041906750B0060DC067007E06270C060019 -:1008B0008206E707BC088406C8077E06419051AF50 -:1008C00097CF9FAF480CE709B606B406E709B00614 -:1008D000AE0659AF97CF270C0200AC0659AF97CFA1 -:1008E000090C020009DA49D2C919D606C8077E06E2 -:1008F000E00700006002E0070400D007CC0848DBF6 -:10090000419050AF97CF59AF97CF59AF97CFF0578E -:100910000600060025C1E7077006800641906700C3 -:100920007E06270C06008206E7078C098406C807A6 -:100930007E06419051AF97CF070C0600C7570600BF -:100940000FC1C807700615CF000C020000DA40D1B5 -:100950002700C2061ECF1DCF270C0200CC0619CFE0 -:1009600027022001E70708002201E7071300B0C0B3 -:1009700097CF419067007E06E70182062702800636 -:10098000E7078C098406C8077E06C107008050AFC0 -:1009900097CF59AF97CF006005C0E7070000C406A6 -:1009A000A7CF7C069FAF000AE7070100C40649AF46 -:1009B000D70900C007AFE70500C04AAFA7CF7C0644 -:1009C000C007FE7F44AF4000C03700014190C037F0 -:1009D0000800DFDE5006C057100002C2C00710003A -:1009E00027009A0641909FDE400644AF27009C06F0 -:1009F000C0099A06419000D200D89FDE080044AF9B -:100A00002700C80697CFE787008428C0E767FFFB69 -:100A100024C097CFE7870100D206E7570000A80659 -:100A200097C19FAF000AE787000622C0E7070000D2 -:100A300090C0E767FEFF3EC0E70726000AC0E787D1 -:100A400001003EC0E707FFFFBE069FAF100B97CF28 -:100A50001700A7AF7806C00527007606E7870100D4 -:100A6000D2069FAF000AE7070C0040C09FAF100BF3 -:100A700000902700A6062700AA06E709B206B406DA -:100A80002700AE062700AC069FAFAE0AC0070000E5 -:100A90002700B2022700B40227008E06C007060016 -:100AA000C809DE00C8170300C9077006290A00DA62 -:100AB0007DC197CFD70900C0C1DF009027009606FF -:100AC000E707960698062700A006E707A006A206F5 -:100AD0002700A6062700900627009E06C8099C0648 -:100AE000C1099A06C907A40611020902C8174006DF -:100AF00001DA7AC15194C809C806C907C606C109F6 -:100B00009A0611020902C817080001DA7AC1519445 -:100B1000E70500C097CFE7570000760697C09FAF64 -:100B20000400E709BE06BA06E757FFFFBA0604C18C -:100B3000E707100BB80697CFE7173200BA06E7674A -:100B4000FF07BA06E707460BB80697CFE75700003E -:100B5000C00623C0E707040090C0E707008080C0FC -:100B6000E707000080C0E707008080C0C0070000E2 -:100B7000C0070000C0070000E707000080C0E707CB -:100B8000008080C0E707008040C0C0070000E70782 -:100B9000000040C0E707000080C0E707040090C0E5 -:100BA000E707000240C0E7070C0240C0E70700006B -:100BB000C006E7070000B806E7070000D206D7091D -:100BC00000C0C1DF9FAF3402E70500C09FAFC40182 -:100BD00097CFD70900C0170017029702E757000008 -:100BE000A80606C0C00992C0C07709029FC15C0573 -:100BF0009FCF3206D7090EC0E70700000EC09FAF97 -:100C0000020CE7050EC097CFD70900C01702C8092C -:100C1000B0C0E767FE7FB0C0C87700209FC164EB1B -:100C2000E7570000C8029FC180EBC899CA02C86795 -:100C300004009FC196EB9FCF4CEBE7070000A6C0D6 -:100C4000E709B0C0C802E7070300B0C097CFC009EA -:100C5000B006C037010097C9C909B2060200419029 -:100C60004802C91706009FAF08049FA2720C02DA5F -:100C700077C1416071C197CF170257024304210425 -:100C8000E00043042104E00043042104E000C10724 -:100C90000100C905C80597CFE70701008E06C80700 -:100CA0008606E70700008606E70710088806E707BC -:100CB00004008A06E707BC0C8C06C107038050AF0E -:0C0CC00097CFE70700008E0697CF0000DA -:00000001FF diff --git a/firmware/kaweth/new_code_fix.bin.ihex b/firmware/kaweth/new_code_fix.bin.ihex deleted file mode 100644 index fb35d3d0c924d91d0be12fe5fefd36e1926140ca..0000000000000000000000000000000000000000 --- a/firmware/kaweth/new_code_fix.bin.ihex +++ /dev/null @@ -1,40 +0,0 @@ -:10000000B6C3AABBCCDD0200080028002C003400D7 -:100010003C0040004800540058005E006400680046 -:100020006E006C00720076007C00800086008A0002 -:100030009000940098009E00A600AA00B000B400B2 -:10004000B800C000C600CA00D000D400D800E0004C -:10005000DE00E800F000FC0004010A0118012201A2 -:1000600028013A013E017E0198019C01A201AC01E8 -:10007000B201BA01C001C801D001D601F401FC01EE -:10008000080216021A0222022A022E023E0244022C -:100090004A025002640262026C02720286028C0200 -:1000A00090029E02BC02D002D802DC02E002E8020A -:1000B000E602F402FE0204030C0328037C0390030F -:1000C00094039C03A203C003D003D403EE03FA03FA -:1000D000FE032E0432043C0440044E0476047C04E7 -:1000E00084048A048E04A604B004B804BE04D204B6 -:1000F000DC04EE0410051A0524052A05360534052E -:100100003C05420564056A056E058605220626063D -:100110002C06300642064A064E06560654065A0675 -:1001200060066606E806EE06F406160726072C07A4 -:10013000320736073A073E07520756075A07640741 -:1001400076077A07800784078A079E07A207DA07DF -:10015000DE07E207E607EA07EE07F207F6070E08F2 -:10016000160818081A081C081E0820082208240867 -:10017000260828082A082C082E0832083A084608BB -:100180004E0854085E0878087E08820886088C08A5 -:10019000900898089E08A408AA08B008AE08B408F9 -:1001A000BE08C408C208CA08C808D408E408E80899 -:1001B000F608140912091A092009260924092A092E -:1001C0003E094C0956097009740978097E097C09B1 -:1001D000820998099C09A009A609B809DC09E8095F -:1001E000EC09FC09120A180A1E0A420A460A4E0ABB -:1001F000540A5A0A5E0A680A6E0A720A780A760A6D -:100200007C0A800A840A940AA40AB80ABE0ABC0AB4 -:10021000C20AC80AC60ACC0AD00AD40AD80ADC0A1A -:10022000E00AF20AF60AFA0A140B1A0B200B1E0B4C -:10023000260B2E0B2C0B360B3C0B420B400B4A0BA8 -:10024000AA0BB00BB60BC00BC80BDA0BE80BEC0B10 -:10025000FA0B4A0C540C620C660C960C9A0CA00C0F -:0E026000A60CA40CAC0CB20CB00CC00C000030 -:00000001FF diff --git a/firmware/kaweth/trigger_code.bin.ihex b/firmware/kaweth/trigger_code.bin.ihex deleted file mode 100644 index c3e1658c2803df329bed8fa22f6820960d7018b9..0000000000000000000000000000000000000000 --- a/firmware/kaweth/trigger_code.bin.ihex +++ /dev/null @@ -1,13 +0,0 @@ -:10000000B6C3AABBCCDDC807A000F0075E0006009F -:10001000F0070A000800F00900000200E7073600B8 -:100020000000F00700000400E70750C310C0F0090B -:100030000EC00000E78701000EC097CFD70900C0AF -:100040001702C807A000E71750C310C030D804003B -:10005000305C08000400B0C00600C805E70500C019 -:10006000C0DF97CF49AFC007000060AF4AAF000CB8 -:100070000C0040D2001C0C0040D230000800F007F9 -:1000800000000400F0078600060067CF270C02007E -:100090000000270C00000EC049AF64AFC00700008D -:1000A0004BAF4AAF5ACF0000000000000000000034 -:0600B000940005000000B1 -:00000001FF diff --git a/firmware/kaweth/trigger_code_fix.bin.ihex b/firmware/kaweth/trigger_code_fix.bin.ihex deleted file mode 100644 index 7712f73faeda90ea5dd279bc3db6944ac23ee088..0000000000000000000000000000000000000000 --- a/firmware/kaweth/trigger_code_fix.bin.ihex +++ /dev/null @@ -1,3 +0,0 @@ -:10000000B6C3AABBCCDD0200060018003E0080008B -:060010009800AA000000A8 -:00000001FF diff --git a/firmware/keyspan/mpr.HEX b/firmware/keyspan/mpr.HEX deleted file mode 100644 index a53ba10b2358a4728e5100800bbbfb67a3f1d4dc..0000000000000000000000000000000000000000 --- a/firmware/keyspan/mpr.HEX +++ /dev/null @@ -1,104 +0,0 @@ -:0300330002001AAE -:04001A0053D8EF3296 -:100003008E568F57E5571557AE56700215564E60EC -:0700130005120FA280EE228E -:0300230002004692 -:10004600C0E0C083C082C086758600C0D075D00867 -:1000560030990E300B07A20E929B853699C299D223 -:10006600122012030202F9C2123003197E7E7F406B -:10007600751A7E751B407517007E7D7FC075187DCD -:100086007519C080177E7D7FC0751A7D751BC0757A -:1000960017017E7E7F4075187E751940200B03027E -:1000A6000184E53AC39553503C200C342009319025 -:1000B6007F9BE055387029301012AF3A053AE51BA0 -:1000C6002FF582E4351AF583E013920EAF3A053A1E -:1000D600E51B2FF582E4351AF583E0F5360202F7C3 -:1000E600C20B0202F7300311907FC7E4F0A3E0547D -:1000F60002F51DA3E0F51C8011907FC9E4F0907F06 -:03004300020F00A9 -:03000000020026D5 -:0C002600787FE4F6D8FD75815A020A3399 -:40010600C6E05402F51DA3E0F51CE51724FF9203300D0DC20D907FBB7401F0C20B0202F7E51D6005C20B0202F7851C53851982851883E013920D7512FF200C3A2009379082 -:400146007F9BE05538702F30101C851982851883A3E013920E851982851883A3A3E0F536753A030202F7753A02851982851883A3E0F5360202F7753A01C20B0202F73003FE -:400186000E907FC6E05402F51DA3E0F51C800C907FC8E05402F51DA3E0F51CE53AC395535003020268E51D6007C214C2050202F7851C53851B82851A83E013920D7512FF61 -:4001C600300C03020260300903020260907F9BE05538600302026030101B851B82851A83A3E013929B851B82851A83A3A3E0F599753A03800D851B82851A83A3E0F5997575 -:400206003A02E53AC395534026300307907FC7E4F08005907FC9E4F0E51724FF9203200D030202F7C20D907FBB7401F00202F7301012AF3A053AE51B2FF582E4351AF58394 -:40024600E013920EAF3A053AE51B2FF582E4351AF583E0F536D20B0202F7753A01C2140202F7300C030202F53009030202F5907F9BE055387079301012AF3A053AE51B2FF2 -:40028600F582E4351AF583E013929BAF3A053AE51B2FF582E4351AF583E0F599E53AC395534022300307907FC7E4F08005907FC9E4F0E51724FF9203300D36C20D907FBB0E -:4002C6007401F0802C301012AF3A053AE51B2FF582E4351AF583E013920EAF3A053AE51B2FF582E4351AF583E0F536D20B8002C214D201209803020435C298200203020383 -:40030600A2201527AF39053974802FF582E4347EF583E599F030104DAF39053974802FF582E4347EF583E598F0803A859955E555B54704D209802EE555B54604C20980251C -:40034600AF39053974802FF582E4347EF583E555F0301011AF39053974802FF582E4347EF583E598F0D20FE539C395435003020433907FB8E030E116E539C39440500302F5 -:40038600043315391539052B433401020433907FB7E539F0753900C202020433201527AF39053974002FF582E4347EF583E599F030104DAF39053974002FF582E4347EF594 -:4003C60083E598F0803A859955E555B54704D209802EE555B54604C2098025AF39053974002FF582E4347EF583E555F0301011AF39053974002FF582E4347EF583E598F0EA -:40040600D20FE539C395434024907FB6E030E112E539C39440401615391539052B433401800B907FB9E539F0753900D202D201300105C201020056D0D0D086D082D083D02F -:40044600E032907FBCE020E154E5346050E531704CE53430E10BE4F52F753401753102800EA208E433F52FC208E4F534753110E4F5567E007B0074242556F9EE3400FA12D8 -:400486000C79FF74002556F582E4347DF583EFF00556E556B40CDB907FBD740CF0907FCAE030E1030205D1E4F55674402556F582E4347DF583E0FFE5567C007B00243BF903 -:4004C600EC3400FAEF120C920556E556B418DBE53B601175C92075C836853CCA853DCBE4907F9FF0E53E139210929F853F38E540139215E5416009907F98E054FBF0800744 -:40050600907F98E04404F0E5426009907F98E0547FF08007907F98E04480F0E548600BC20CC209907F95E04402F0E549600CD209433401907F95E04402F0E54A600DC2AFBB -:40054600C20BD200E4F553F53AD2AFE54B6005301502D209E54C6015907F95E054FDF0907F9EE04402F0907F98E054FDF0E54D600AD29CC298752C0175311EE54E6007C227 -:400586009CE4F539F52CE54F6003E4F539E5506002D207E551600AE54D7002F531E5514234E552601F907FD77411F07431F07412F07432F07413F07433F07414F07434F067 -:4005C600D203D202D208E4907FCBF0A20CE433FF652960058F29433401A209E433FF652A60058F2A433401907F9BE0FF54086408F55765256006855725433401EF5410643A -:4006060010F55765266006855726433401EF54406440F55765276006855727433401EF54206420F55765286006855728433401907F9AE054406440F557652E600685572E5B -:40064600433401300735C2AF300218907FB8E020E127E5396009907FB7F0E4F539C202C2078016907FB6E020E10FE5396009907FB9F0E4F539D202C207D2AF20053D3003DB -:400686001E907FC6E020E133907E40E013920D753A01907FC7E0F553D2057512FF801C907FC8E020E115907DC0E013920D753A01907FC9E0F553D2057512FF2014332000E6 -:4006C60006E53A6553702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F553F53A300D0AC20DC200907FBB7401F03014030207BF2005030207BF300C0314 -:400706000207BF3009030207BF907F9BE0553860030207BF30030C7E7E7F4075587E755940800A7E7D7FC075587D7559C0301012AF3A053AE5592FF582E43558F583E0137C -:40074600921AAF3A053AE5592FF582E43558F583E0F557E53AC39553502A301012AF3A053AE5592FF582E43558F583E013920EAF3A053AE5592FF582E43558F583E0F53688 -:40078600D20B8015C20B300309E4907FC7F0C2038007E4907FC9F0D203301004A21A929BD214C2AF855799200B0D300D0AC20DC200907FBB7401F0D2AF22907FE9E0120C70 -:4007C600A4091C0009890109E60307E306090D0809010908E90A08F80B00000A24907FEBE024FE601C14700302087924026003020A24740D907FD4F07487907FD5F0020AE6 -:400806002B907FEAE0B401047F0280027F037582D875830DEFF07582D175830DF07582CA75830DF07582C375830DF0907FEAE00475829E75830DF0907FEFE0FE907FEEE07B -:400846007C002400F55AEC3EF55975150D75169975829B75830DE0751300F514D3E514955AE51395594006855913855A14120BBA020A2B907FEAE0700B7556FF75570D7503 -:4008860058DC802D907FEAE0B4010B7556FF75570D7558E0801B907FEAE0B4020B7556FF75570D7558F080097556FF75570E75581E907FEEE0755900F55AAE57AF588E1512 -:4008C6008F168F828E83E0FEA3E08E13F514D3955AE51395594006855913855A14120BBA020A2B907F00E511F0907FB57401F0020A2B907FEAE0F511020A2B120C24907F84 -:40090600EAE0F510020A2B907F00E510F0907FB57401F0020A2B907FE8E0247F602714603424026003020A24A216E433FF25E0FFA218E4334F907F00F0E4A3F0907FB57455 -:4009460002F0020A2BE4907F00F0A3F0907FB57402F0020A2B907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00B -:40098600020A2B907FE8E024FE601724026003020A2B907FEAE064016003020A24C216020A2B907FEAE07076907FECE0F45480FFC4540FFFE054072F25E024B4F582E4348D -:4009C6007FF583E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F08045907FE8E024FE601024027039907FEAE06401702AD216802D907FEAE07020907F77 -:400A0600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08007907FB4E04401F0907FB4E04402F022C210E4F510F534C209C20CC20BC214C20DC215A5 -:400A4600C211C207C212C20FC208F535F539F553F53AF533F530F52FF52EF52DF52CF52BF52AF529F528F527F526F525F524C205C217C219C216C218C204D213C206C20178 -:400A8600907F92E054FDF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440FF0907FAC740EF0D2AFD2BCD247 -:400AC6001A120F7DC21730040312044830042A300627C206E51260161512907FD8E030E6047F0080027F20907F96EFF08006907F967420F0120B1480CD301707C217120741 -:400B0600C080C33019C0C219120EDC80B922E53160021531E53960556535704BE533F460020533E533C395444043C2AF30021B907FB8E020E12D907FB7E539F0C202E4F5AA -:400B460039F533F5357512FF8019907FB6E020E112907FB9E539F0D202E4F539F533F5357512FFD2AF8006853935E4F533E52C6030200F07907F9BE030E00FE52D6006E497 -:400B8600F52D433401E4F5308014E530D39545500DE530B54506752D014334010530C20F22907FD9E030E2047F0080027F20907F96EFF022E51445136057AE13AF14D3EF0F -:400BC6009440EE940040047E007F40C3E5149FF514E5139EF513E4FDEDC39FE49E501F851682851583E0FC74002DF582E4347FF583ECF00D0516E5167002051580DA907FC4 -:400C0600A97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022E4907F93F0907F9C7430F0907F967420F0907F947401F0907F9D74FFF0907F977486DF -:400C4600F0907F957403F0907F9E7484F0907F98F0E4907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D20422BB010689828A83E0225002E722C3 -:400C8600BBFE02E32289828A83E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA367 -:400CC600A3A380DFE4907F95F0907F94F0907F93F0907F9DE04402F0907F97E04442F0907F9C7410F0E4907F96F0907F9D74BEF03016047F8080027F00907F97EFF0E49045 -:400D06007F95F0907F9EF0907F98F022C0E0C0F0C083C082C085C084C086758600C0D075D0085391EF907FA97401F0120BBAD0D0D086D084D085D082D083D0F0D0E032C06A -:400D4600E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E03200000000000000000000000000000000000000000000001C -:400D86000012011001FFFFFF40CD061C010100010200020902430001010080320904000007FF00000007050102400000070502024000000705030240000007058102400002 -:400DC600010705820240000107058302400001070584024000010403090410034B00650079007300700061006E002E034B00650079007300700061006E00200055005000A3 -:400E0600530048003100310032002D00530065007200690061006C0022035500530041002D003500330020003200300030003200610070007200320036000000C0E0C083DB -:400E4600C082C085C084C0867586005391EF907FAB7402F0D206D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2175391EF907FAB7401F0D086D01F -:400E860084D085D082D083D0E032C0E0C083C082C085C084C086758600D2195391EF907FAB7408F0D086D084D085D082D083D0E032C0E0C083C082C085C084C08675860084 -:400EC6005391EF907FA97402F0D086D084D085D082D083D0E032120CCA120FB3907FD6E030E712E04401F07F0D7E00120003907FD6E054FEF0120C242200020E6900020EA3 -:400F06004200020D4500020E9000020F1000020F1400020D1200020F1C00020EB700020F2400020F3300020F2C00020F58C0E0C083C082C085C084C0867586005391EF90A9 -:400F46007FA97404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA97408F0D086D084D085D082D083D0E032907FD6E054FBF0E044C1 -:3D0F860008F0301A04E04402F07FF47E01120003907FD6E054F7F0E04404F0227400F58690FDA57C05A3E582458370F922907FD6E04480F04387010000000000222C -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -static char theFirmwareDate53[] = - "04/26/2002 02:47p 11,570 USA53"; - diff --git a/firmware/keyspan/usa18x.HEX b/firmware/keyspan/usa18x.HEX deleted file mode 100644 index a9ff70eadfe7446cd18f3d55752d76fd022110a2..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa18x.HEX +++ /dev/null @@ -1,141 +0,0 @@ -:030033000212F7BF -:10000300E4907F93F0907F9C7430F0E4907F96F0BF -:10001300907F94F0907F9D74FFF0E4907F97F09031 -:0F0023007F95F0907F9E7407F0E4907F98F02215 -:1000460030091812131BEFC3953C40030200D890E9 -:100056007FBF7401F0C209C200807730033B907FF6 -:10006600C6E020E16D12131BEFC394405064907EEE -:1000760040E0139209907FC7E014F5192000116043 -:100086000FF5087E7E7F41750C7E750D41120CBA08 -:10009600C203E4907FC7F08039907FC8E020E13248 -:1000A60012131BEFC394405029907DC0E0139209B0 -:1000B600907FC9E014F519200011600FF5087E7DC8 -:1000C6007FC1750C7D750DC1120CBAD203E4907F09 -:1000D600C9F0907FB6E030E1030201601211D68FBD -:1000E600191213278F36E519C3953A500F1212EBE2 -:1000F600EF30E008E53620E703300B5EC20BE5196A -:0C003600907F987410F090C000E0FF2252 -:03004300021300A5 -:03000000020E00ED -:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F4BE51925E0907FB7F08027E519D3943F400375193F851908D4 -:40014600907E80E536F07E7E7F81750C7E750D81120CDFE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AF1 -:400186007E79002400F9EC347EFAEF120ED20518E518B420D7907E00E06068907E03E060247F01E4FD1211B17F037DCD1211B1434680907F987414F090C000E546F0E490E0 -:4001C6007E13F08030907E01E0FF121035907E02E0FF12105B7F01907E11E0FD1211B17F037D071211B1434680907F987414F090C000E546F0907F987412F0E5404406903E -:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA -:400246007F5342FC907E09E06011434202A3E0FF1210A7907E0BE0FF1210CDAF42121081907E03E0600853427FAF42121081907E0CE06018A3E0600543460280035346FDB4 -:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B -:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212DFEF54FE90C000F0533EFDE4FFAD3E120F -:4003060011B1E4F52AF529D207907E17E0600F433E02E4FFAD3E1211B1752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98F2 -:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211B1752B01D207907E1BE0600F433E01E4FFAD3E1211B1E4F52BD207907E1CE0600E907F98741284 -:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892 -:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212DFEF5401F519652A600585192AD207121333EF5480F51965266005851926D207300D11127F -:400406001333EF5410F51965256005851925D207201B030207EC300A1812136FEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12136FEFC35A -:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D04C204E4907FCBF08039907FCCE020E13212136FEFC39440502990BC -:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D04D204E4907FCDF0907FBAE030E1030205361212208F1912137B8F37E519C3952B -:4004C6003B500F121357EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F84E503 -:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D29E51904907FBBF0907FD0E030E106200603020797C206E4F8 -:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120ED20518E518B420D7907E20E06068907E23E060247F01E4FD1211FB7F0329 -:400586007DCD1211FB434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121119907E22E0FF12113F7F01907E31E0FD1211FB7F037D071211FB4347809048 -:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB -:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121165907E2BE0FF12118BAF431210F3907E23E0600853437FAFFE -:40064600431210F3907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0D4 -:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 -:4006C600987409F012134BEF54FE90C000F0533FFDE4FFAD3F1211FBE4F533F532D208907E37E0600F433F02E4FFAD3F1211FB753201D208907E38E06010907F98740AF043 -:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F1211FB753401D208907E3BE0600F433F01E4E9 -:40074600FFAD3F1211FBE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741389 -:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C21312134BEF5401F51965336005851933D279 -:4007C60008121387EF5480F519652F600585192FD208300E11121387EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F5169035 -:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E8CFF748025BD -:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297 -:400886000E8CFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340083 -:4008C600FA120E8CFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E8CFF748025F2 -:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EE40A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F3D -:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2 -:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F0AEA49600DEA907FD4F0E9907FD5F085 -:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205 -:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04 -:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F -:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6 -:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049 -:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4 -:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B -:400B8600E4120ED20518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211B17F108F42121081907F02 -:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211B1E4FF7EA3AD068D3E1211B1907F987411F090C000E4F07F057D7F12118E -:400C0600B17F0112126A7F037D071211B1201B03020CB7752D017518017B00742D2518F9E43400FAE4120ED20518E518B409EA753B01E4F539F513F537C208C20CC206C2CD -:400C460000C20AC213907F98740BF075450390C0007403F07F0CE4FD1211FB7F108F431210F3907F98740AF07F018F41EF440690C000F0907F98740CF075478090C000744E -:400C860080F00FE4FD1211FBE4FF7EA3AD068D3F1211FB907F987409F090C000E4F07F057D7F1211FB7F0112128B7F037D071211FBD21222907F987410F0AF08E50DF582A5 -:400CC600E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF22907F20 -:400D0600987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C000E00586F0A3055C -:400D460086DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F0907FAEE0FFD39210E433FEEF4EF089 -:400D8600D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A121245C211E4F50BF513C217C212D4 -:400DC600907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D3C21812139380CC22787FE4F6D8FDC7 -:400E0600758147020E47020D6FE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B01020408102040F5 -:400E4600809012ACE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CA1E -:400E8600DFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E5B8 -:400EC6008229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3C1 -:400F0600A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EA5B4031DAF190519EFB5180122120E8C7E0029FFEE3AA907751AFFF51B891C80D47B00A5 -:400F46007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213278F1AEF423680CA228F1AFC -:400F8600050DE50DAE0C7002050C14F5828E83E51AF012133F050DE50DAC0C7002050C14F5828C83EFF01508E508600A12137B8F1AEF423780CA22C0E0C083C082C085C088 -:400FC60084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D0C6 -:4010060085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F9874108A -:40104600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E544547F90C000F022907F98741349 -:40108600F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544D9 -:4010C600547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF0902A -:40110600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090AF -:40114600C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547FEC -:4011860090C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F09075 -:4011C600C000EFF0907F987415F090C000EDF02212130F8F1A12130F8F1BE51A651B601212130F8F1AE51A651B600712130F8F1B80E8AF1A22907F98740BF0E545547F9098 -:40120600C000F0907F98740FF090C000EFF0907F98740DF090C000EDF0221213638F1A1213638F1BE51A651B60121213638F1AE51A651B60071213638F1B80E8AF1A2290C8 -:401246007FD6E054FBF0E04408F0301A04E04402F07FF47E011212C8907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211B1907F987411F090C000EEF0E4E53E4480E8 -:40128600FD1211B122AE07E4FFE53F547FFD1211FB907F987409F090C000EEF0E4E53F4480FD1211FB22050E02000000000314030000C111C118C195C110C116010A00C19C -:4012C6001B008E188F19E5191519AE18700215184E6005120D4E80EE22907F987411F090C000E0FF22907F987412F090C000E0FF2253D8EF320000000000020FE70002130A -:401306000400020FBD0002100E907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22907F987408F09050 -:40134600C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FF22907F98740DF090C000E0FFC5 -:4013860022907F98740EF090C000E0FF22120003120D5F120B4622000000000000000000000000000000000000000000000000000000000000000000000000000000000083 -:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 -:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 -:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 -:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 -:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 -:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 -:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 -:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 -:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 -:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 -:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 -:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 -:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 -:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 -:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 -:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 -:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 -:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 -:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 -:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF -:401906000040CD06120100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400074 -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:141A06007200100330003000300030003000300030000000F7 -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19.HEX b/firmware/keyspan/usa19.HEX deleted file mode 100644 index c5d1496e8714636d23b9ff85ab35e24d45376359..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa19.HEX +++ /dev/null @@ -1,101 +0,0 @@ -:0A002600120DBF120F47120D6B22DE -:0300330002001AAE -:04001A0053D8EF3296 -:100003008E138F14E5141514AE13700215134E607E -:0700130005120F3680EE22FA -:0300230002004692 -:10004600C0E0C083C082C086758600C0D075D00867 -:1000560030990E300807A20B929B853599C299D22A -:100066000F200F03020431C20F20020302025620A2 -:100076000803020127E537C39550503E2009362074 -:100086000633907F9BE030E303200E29300D12AF3C -:1000960037053774402FF582E4347EF583E01392FA -:1000A6000BAF37053774402FF582E4347EF583E0D5 -:1000B600F53502042FC20802042F907FC7E4F0C270 -:1000C60002300A0CC20A907FBB04F0C20802042F59 -:1000D600907FC8E030E105C20802042F907FC9E096 -:1000E600F550907DC0E013920A20092D20062A9033 -:1000F6007F9BE030E303200E20300D11907DC1E0A0 -:03004300020F00A9 -:03000000020C618E -:4001060013920BA3E0F53575370302042F753702907DC1E0F53502042F753701C20802042FE537C3955050030201CF907FC6E030E107C210C20302042F907FC7E0F5509004 -:400146007E40E013920A3009030201C720067220006F907F9BE030E303200E65300D10907E41E013929BA3E0F5997537038009907E41E0F599753702E537C39550401790B1 -:400186007FC7E4F0C202200A0302042FC20A907FBB04F002042F300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E4347EF583E0F535D20802045D -:4001C6002F753701C21002042F300903020251200679907F9BE030E303200E6F300D12AF37053774402FF582E4347EF583E013929BAF37053774402FF582E4347EF583E046 -:40020600F599E537C395504017907FC7E4F0C202200A0302042FC20A907FBB04F002042F300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E43483 -:400246007EF583E0F535D20802042FC21002042F200803020308E537C39550503E200936200633907F9BE030E303200E29300D12AF37053774C02FF582E4347DF583E013DE -:40028600920BAF37053774C02FF582E4347DF583E0F53502042FC20802042F907FC9E4F0D202300A0CC20A907FBB04F0C20802042F907FC6E030E105C20802042F907FC765 -:4002C600E0F550907E40E013920A20092D20062A907F9BE030E303200E20300D11907E41E013920BA3E0F53575370302042F753702907E41E0F53502042F753701C20802EF -:40030600042FE537C3955050030203B0907FC8E030E107C210C20302042F907FC9E0F550907DC0E013920A3009030203A820067220006F907F9BE030E303200E65300D1034 -:40034600907DC1E013929BA3E0F5997537038009907DC1E0F599753702E537C395504017907FC9E4F0D202200A0302042FC20A907FBB04F002042F300D12AF37053774C0F5 -:400386002FF582E4347DF583E013920BAF37053774C02FF582E4347DF583E0F535D20802042F753701C21002042F30090302042D200674907F9BE030E303200E6A300D128E -:4003C600AF37053774C02FF582E4347DF583E013929BAF37053774C02FF582E4347DF583E0F599E537C395504013907FC9E4F0D202300A35C20A907FBB04F0802C300D12CC -:40040600AF37053774C02FF582E4347DF583E013920BAF37053774C02FF582E4347DF583E0F535D2088002C210D21220980302056DC2982001030204DA201127AF360536F3 -:4004460074802FF582E4347EF583E599F0300D4DAF36053674802FF582E4347EF583E598F0803A859910E510B54404D206802EE510B54304C2068025AF36053674802FF5AB -:4004860082E4347EF583E510F0300D11AF36053674802FF582E4347EF583E598F0D20CE536C39540500302056B907FB8E030E116E536C39440500302056B15361536052BDD -:4004C60043330102056B907FB7E536F0753600C20102056B201127AF36053674002FF582E4347EF583E599F0300D4DAF36053674002FF582E4347EF583E598F0803A859937 -:4005060010E510B54404D206802EE510B54304C2068025AF36053674002FF582E4347EF583E510F0300D11AF36053674002FF582E4347EF583E598F0D20CE536C3954040CE -:4005460024907FB6E030E112E536C39440401615361536052B433301800B907FB9E536F0753600D201D212301205C212020056D0D0D086D082D083D0E032907FCAE030E1CA -:40058600030206ABE4F51374402513F582E4347DF583E0FFE5137C007B002438F9EC3400FAEF120D330513E513B418DBE538600C75C92075C8348539CA853ACBE53B1392BF -:4005C6000D929FE53C13920EE53D139211E53E6009907F98E054FBF08007907F98E04404F0E53F6009907F98E0547FF08007907F98E04480F0E545600BC209C206907F950E -:40060600E04402F0E546600CD206433301907F95E04402F0E547600DC2AFC208D200E4F550F537D2AFE5486005301102D206E5496015907F95E054FDF0907F9EE04402F0AA -:40064600907F98E054FDF0E54A600AD29CC298752C0175311EE54B6007C29CE4F536F52CE54C6003E4F536E54D6002D204E54E600AE54A7002F531E54E4233E54F601F9064 -:400686007FD77411F07431F07412F07432F07413F07433F07414F07434F0D202D201D205E4907FCBF0A209E433FF652960058F29433301A206E433FF652A60058F2A4333BA -:4006C60001907F9BE05408B5250AE054086408F525433301907F9BE05410B5260AE054106410F526433301907F9BE05440B5270AE054406440F527433301907F9BE0542026 -:40070600B5280AE054206420F528433301300435C2AF300118907FB8E020E127E5366009907FB7F0E4F536C201C2048016907FB6E020E10FE5366009907FB9F0E4F536D234 -:4007460001C204D2AF20033730021B907FC6E020E12D907E40E013920A753701907FC7E0F550D2038019907FC8E020E112907DC0E013920A753701907FC9E0F550D20320E9 -:400786001033200006E5376550702A30031A300209E4907FC7F0C2028007E4907FC9F0D202C203E4F550F537300A0AC20AC200907FBB7401F03010030208C5200303020805 -:4007C600C5300E0A907F9BE030E3030208C53006030208C53009030208C5300262300D12AF37053774402FF582E4347EF583E0139219AF37053774402FF582E4347EF583CF -:40080600E0F514E537C39550502A300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E4347EF583E0F535D208806BC208E4907FC7F0C20280603081 -:400846000D12AF37053774C02FF582E4347DF583E0139219AF37053774C02FF582E4347DF583E0F514E537C39550502A300D12AF37053774C02FF582E4347DF583E013929F -:400886000BAF37053774C02FF582E4347DF583E0F535D2088009C208E4907FC9F0D202300D04A219929BD210C2AF85149920080D300A0AC20AC200907FBB7401F0D2AF9072 -:4008C6007FBCE020E151E533604DE5317049E53330E108E4F52F753301800BA205E433F52FC205E4F533E4F5137E007B0074242513F9EE3400FA120CEDFF74002513F582D8 -:40090600E4347DF583EFF00513E513B40CDB907FBD740CF075311022907FE9E0120D450A03000A77010AE30309410609F40809E80909D00A09DF0B00000B32907FEBE024EB -:40094600FE601614605724027076740F907FD4F07464907FD5F0020B39907FEAE070047F0280027F037582B575830FEFF07582AE75830FF07582A775830FF07582A07583BA -:400986000FF0907FEAE00475827B75830FF0740F907FD4F07476907FD5F0020B39907FEAE0FF120E48EA49600DEA907FD4F0E9907FD5F0020B39907FB4E04401F0020B39D4 -:4009C600907FB4E04401F0020B39907F00E519F0907FB57401F0020B39907FEAE0F519020B39907FEAE0F518120D6B020B39907F00E518F0907FB57401F0020B39907FE822 -:400A0600E0247F60241460312402705BA213E433FF25E0FFA217E4334F907F00F0E4A3F0907FB57402F0020B39E4907F00F0A3F0907FB57402F0020B39907FECE0F45480B6 -:400A4600FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B39907FB4E04401F0020B39907FE8E024FE601D24026003020B3904 -:400A8600907FEAE0B40105C213020B39907FB4E04401F0020B39907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FFCC -:400AC600131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D213803F907FB4E04401F08036907FEA36 -:400B0600E07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022201503020B3E -:400B4600D3E53160021531E536604F65347045E532F460020532E532C39541403DC2AF300118907FB8E020E127907FB7E536F0C201E4F536F532F5348016907FB6E020E13D -:400B86000F907FB9E536F0D201E4F536F532F534D2AF8006853634E4F532E52C602F200C07907F9BE030E00FE52D6006E4F52D433301E4F5308014E530D39542500DE530DB -:400BC600B54206752D014333010530C20C22751201C214C218C213C217C215C212D216E4F518907F92E054FDF0907FAEE0FFD39213E433FEEF4EF0D2E843D820907FDE74DB -:400C060001F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD2BCD219120EDAC214301503120580907FD8E065116008E0F5CA -:400C460011120B4180EA301407C21412091E80E03018DDC21812002680D622787FE4F6D8FD758150020CA8020BD4E493A3F8E493A34003F68001F208DFF48029E493A3F83B -:400C86005407240CC8C333C4540F4420C8834004F456800146F6DFE4800B0102040810204080900E04E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E08E -:400CC60060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E4932242 -:400D0600BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D0E1 -:400D460083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DFE4907F93F0907F9C7430F0907F967410F0907F947401F0907F9D04E2 -:400D8600F0907F977420F0907F957403F0907F9E7484F0E4907F98F0907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D21522E4907F95F0907FF7 -:400DC60094F0907F93F0907F9DE04402F0907F97E04402F0907F9DE054FDF0907F9C7420F0E4907F96F0907F9DE044FDF0E4907F97F0907F9E74FFF0E4907F98F0220C24D0 -:400E0600000000000000000000000000013000013301013200013700015000013600013400C105C10CC103C10FC104C10EC111C10AC110C108C109C106C100C10DC181C109 -:400E460082008F13E4F5147515FF75160F7517B9AB15AA16A917900001120D06B4031DAF140514EFB5130122120CED7E0029FFEE3AA9077515FFF516891780D47B007A006D -:400E8600790022C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2145391C7 -:400EC600EF907FAB7401F0D086D084D085D082D083D0E032907FD6E054FBF0E04408F0301904E04402F07FF47E01120003907FD6E054F7F0E04404F02200020EB300020FC0 -:400F06000400020E8900020F0FC0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E0327400F58690FDA57C05A3E582458370F9B9 -:400F460022907FD6E04480F04387010000000000220000000000000000000000000012011001FF000040CD0607010100010200020902430001010080320904000007FF008A -:400F86000000070501024000000705020240000007050302400000070581024000010705820240000107058302400001070584024000010403090410034B00650079007332 -:170FC60000700061006E000E03530065007200690061006C00000064 -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19qi.HEX b/firmware/keyspan/usa19qi.HEX deleted file mode 100644 index 353bfcfefb9c92eb5995f51f3d03c999db35c554..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa19qi.HEX +++ /dev/null @@ -1,101 +0,0 @@ -:0300330002001AAE -:04001A0053D8EF3296 -:100003008E118F12E5121512AE11700215114E608A -:0700130005120F8480EE22AC -:0300230002004692 -:10004600C0E0C083C082C086758600C0D075D00867 -:1000560030990E300B07A20E929B853699C299D223 -:100066001220120302041EC21220030302024E20B3 -:100076000B03020126E53AC39553503C200C34206D -:100086000931907F9BE055387029301012AF3A0540 -:100096003A74402FF582E4347EF583E013920EAF76 -:1000A6003A053A74402FF582E4347EF583E0F5365E -:1000B60002041CC20B02041C907FC7E4F0C203308A -:1000C6000D0CC20D907FBB04F0C20B02041C907F86 -:1000D600C8E030E105C20B02041C907FC9E0F5536D -:1000E600907DC0E013920D7516FF200C2B20092879 -:1000F600907F9BE055387020301011907DC1E01341 -:03004300020E00AA -:03000000020026D5 -:0C002600787FE4F6D8FD758154020B28A9 -:40010600920EA3E0F536753A0302041C753A02907DC1E0F53602041C753A01C20B02041CE53AC3955350030201C9907FC6E030E107C214C20502041C907FC7E0F553907ECB -:4001460040E013920D7516FF200C7020096D907F9BE055387065301010907E41E013929BA3E0F599753A038009907E41E0F599753A02E53AC395534017907FC7E4F0C203F6 -:40018600200D0302041CC20D907FBB04F002041C301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F536D20B02041C753A01C214A3 -:4001C60002041C300C03020249200977907F9BE05538706F301012AF3A053A74402FF582E4347EF583E013929BAF3A053A74402FF582E4347EF583E0F599E53AC3955340AB -:4002060017907FC7E4F0C203200D0302041CC20D907FBB04F002041C301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F536D20B44 -:4002460002041CC21402041C200B030202FFE53AC39553503C200C34200931907F9BE055387029301012AF3A053A74C02FF582E4347DF583E013920EAF3A053A74C02FF5F9 -:4002860082E4347DF583E0F53602041CC20B02041C907FC9E4F0D203300D0CC20D907FBB04F0C20B02041C907FC6E030E105C20B02041C907FC7E0F553907E40E013920DAF -:4002C6007516FF200C2B200928907F9BE055387020301011907E41E013920EA3E0F536753A0302041C753A02907E41E0F53602041C753A01C20B02041CE53AC39553500381 -:400306000203A2907FC8E030E107C214C20502041C907FC9E0F553907DC0E013920D7516FF200C7020096D907F9BE055387065301010907DC1E013929BA3E0F599753A037A -:400346008009907DC1E0F599753A02E53AC395534017907FC9E4F0D203200D0302041CC20D907FBB04F002041C301012AF3A053A74C02FF582E4347DF583E013920EAF3A81 -:40038600053A74C02FF582E4347DF583E0F536D20B02041C753A01C21402041C200C75200972907F9BE05538706A301012AF3A053A74C02FF582E4347DF583E013929BAF02 -:4003C6003A053A74C02FF582E4347DF583E0F599E53AC395534013907FC9E4F0D203300D35C20D907FBB04F0802C301012AF3A053A74C02FF582E4347DF583E013920EAF3D -:400406003A053A74C02FF582E4347DF583E0F536D20B8002C214D20120980302055AC2982002030204C7201627AF39053974802FF582E4347EF583E599F030104DAF3905C8 -:400446003974802FF582E4347EF583E598F0803A859910E510B54704D209802EE510B54604C2098025AF39053974802FF582E4347EF583E510F0301011AF39053974802F11 -:40048600F582E4347EF583E598F0D20FE539C395435003020558907FB8E030E116E539C39440500302055815391539052B433401020558907FB7E539F0753900C2020205D3 -:4004C60058201627AF39053974002FF582E4347EF583E599F030104DAF39053974002FF582E4347EF583E598F0803A859910E510B54704D209802EE510B54604C209802573 -:40050600AF39053974002FF582E4347EF583E510F0301011AF39053974002FF582E4347EF583E598F0D20FE539C395434024907FB6E030E112E539C3944040161539153909 -:40054600052B433401800B907FB9E539F0753900D202D201300105C201020056D0D0D086D082D083D0E032907FBCE020E151E534604DE5317049E53430E108E4F52F7534D4 -:4005860001800BA208E433F52FC208E4F534E4F5117E007B0074242511F9EE3400FA120D06FF74002511F582E4347DF583EFF00511E511B40CDB907FBD740CF075311090CD -:4005C6007FCAE030E1030206F3E4F51174402511F582E4347DF583E0FFE5117C007B00243BF9EC3400FAEF120D1F0511E511B418DBE53B601175C92075C836853CCA853D98 -:40060600CBE4907F9FF0E53E139210929F853F38E540139216E5416009907F98E054FBF08007907F98E04404F0E5426009907F98E0547FF08007907F98E04480F0E54860BE -:400646000BC20CC209907F95E04402F0E549600CD209433401907F95E04402F0E54A600DC2AFC20BD200E4F553F53AD2AFE54B6005301602D209E54C6015907F95E054FDB4 -:40068600F0907F9EE04402F0907F98E054FDF0E54D600AD29CC298752C0175311EE54E6007C29CE4F539F52CE54F6003E4F539E5506002D207E551600AE54D7002F531E55C -:4006C600514234E552601F907FD77411F07431F07412F07432F07413F07433F07414F07434F0D203D202D208E4907FCBF0A20CE433FF652960058F29433401A209E433FF84 -:40070600652A60058F2A433401907F9BE0FF54086408FE652560058E25433401EF54106410FE652660058E26433401EF54406440FE652760058E27433401EF54206420FE1C -:40074600652860058E28433401907F9AE054406440FE652E60058E2E433401300735C2AF300218907FB8E020E127E5396009907FB7F0E4F539C202C2078016907FB6E0203B -:40078600E10FE5396009907FB9F0E4F539D202C207D2AF20053D30031E907FC6E020E133907E40E013920D753A01907FC7E0F553D2057516FF801C907FC8E020E115907DD3 -:4007C600C0E013920D753A01907FC9E0F553D2057516FF201433200006E53A6553702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F553F53A300D0AC265 -:400806000DC200907FBB7401F0301403020914200503020914300C03020914300903020914907F9BE055386003020914300361301012AF3A053A74402FF582E4347EF5833F -:40084600E013921BAF3A053A74402FF582E4347EF583E0FEE53AC39553502A301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F546 -:4008860036D20B806AC20BE4907FC7F0C203805F301012AF3A053A74C02FF582E4347DF583E013921BAF3A053A74C02FF582E4347DF583E0FEE53AC39553502A301012AFE7 -:4008C6003A053A74C02FF582E4347DF583E013920EAF3A053A74C02FF582E4347DF583E0F536D20B8009C20BE4907FC9F0D203301004A21B929BD214C2AF8E99200B0D301D -:400906000D0AC20DC200907FBB7401F0D2AF22907FE9E0120D310A11000A7E010ADB030938060A020809F60909DE0A09ED0B00000B19907FEBE024FE601914605A24026041 -:4009460003020B19740D907FD4F07487907FD5F0020B20907FEAE070047F0280027F037582D875830DEFF07582D175830DF07582CA75830DF07582C375830DF0907FEAE078 -:400986000475829E75830DF0740D907FD4F07499907FD5F0020B20907FEAE0700B7511FF75120D7513DC801B907FEAE0B4010B7511FF75120D7513E080097511FF75120D19 -:4009C6007513F0AA12A913AE02EE907FD4F0AF01EF907FD5F0020B20907F00E515F0907FB57401F0020B20907FEAE0F515020B20120CB1907FEAE0F514020B20907F00E5BF -:400A060014F0907FB57401F0020B20907FE8E0247F602714603424026003020B19A217E433FF25E0FFA219E4334F907F00F0E4A3F0907FB57402F0020B20E4907F00F0A3B7 -:400A4600F0907FB57402F0020B20907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B20907FE8E024FE601726 -:400A860024026003020B20907FEAE064016003020B19C217020B20907FEAE07076907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480D6 -:400AC600FF131313541FFFE054072F907FD7F0E04420F08045907FE8E024FE601024027039907FEAE06401702AD217802D907FEAE07020907FECE0F45480FFC4540FFFE056 -:400B060054072F25E024B4F582E4347FF5837401F08007907FB4E04401F0907FB4E04402F022C210E4F514F534C209C20CC20BC214C20DC216C211C207C212C20FC208F538 -:400B460035F539F553F53AF533F530F52FF52EF52DF52CF52BF52AF529F528F527F526F525F524C205C218C21AC217C219C215C204D213C206C201907F92E054FDF0D2E820 -:400B860043D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440FF0907FAC740EF0D2AFD2BCD21B120F5FC21830040316 -:400BC60012056D30042A300627C206E51660161516907FD8E030E6047F0080027F20907F96EFF08006907F967420F0120C0B80CD301807C21812091580C3301AC0C21A128E -:400C06000FBB80B922E53160021531E53960556535704BE533F460020533E533C395444043C2AF30021B907FB8E020E12D907FB7E539F0C202E4F539F533F5357516FF802D -:400C460019907FB6E020E112907FB9E539F0D202E4F539F533F5357516FFD2AF8006853935E4F533E52C6030200F07907F9BE030E00FE52D6006E4F52D433401E4F5308000 -:400C860014E530D39545500DE530B54506752D014334010530C20F22907FD9E030E2047F0080027F20907F96EFF022E4907F93F0907F9C7430F0907F967420F0907F94748A -:400CC60001F0907F9D74BFF0907F977486F0907F957403F0907F9E7484F0907F98F0E4907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D204221A -:400D0600BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193EB -:400D4600F5828883E4737402936860EFA3A3A380DFC0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E03200000000007B -:400D86000012011001FF000040CD060C010100010200020902430001010080320904000007FF00000007050102400000070502024000000705030240000007058102400010 -:400DC600010705820240000107058302400001070584024000010403090410034B00650079007300700061006E000E03530065007200690061006C000000020EA200020E41 -:400E06007B00020D5700020EC900020E1000020E1400020E1800020E1C00020EF000020E2400020F1500020E2C00020F3AE4907F95F0907F94F0907F93F0907F9DE044020A -:400E4600F0907F97E04402F0907F9C7410F0E4907F96F0907F9D74FEF03017047F8080027F00907F97EFF0E4907F95F0907F9EF0907F98F022C0E0C083C082C085C084C00E -:400E8600867586005391EF907FAB7402F0D206D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7401F0D086D084D085D082D083EB -:400EC600D0E032C0E0C083C082C085C084C086758600D21A5391EF907FAB7408F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA974C2 -:400F060002F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA97404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086D7 -:400F46007586005391EF907FA97408F0D086D084D085D082D083D0E032907FD6E054FBF0E04408F0301B04E04402F07FF47E01120003907FD6E054F7F0E04404F0227400B9 -:400F8600F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022907FD6E04401F07F0D7E00120003907FD6E054FEF022120E33120F95907FD6E030FA -:090FC600E703120FA5120CB12281 -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19qw.HEX b/firmware/keyspan/usa19qw.HEX deleted file mode 100644 index 8a891023bf517393b6ddf00075084230ba830feb..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa19qw.HEX +++ /dev/null @@ -1,142 +0,0 @@ -:0300330002002D9B -:04002D0053D8EF3283 -:10004600301019120E0FEFC3951440030200DF9013 -:100056007FBF7401F0C210C20B0200DF300D3E906C -:100066007FC6E020E173120E0FEFC39440506A90F2 -:100076007E40E0139210907FC7E014F536200B11F6 -:10008600600FF5247E7E7F4175297E752A4112090F -:1000960010C20DE4907FC7F07526FF803C907FC8A4 -:1000A600E020E135120E0FEFC39440502C907DC036 -:1000B600E0139210907FC9E014F536200B11600F03 -:1000C600F5247E7D7FC175297D752AC1120910D25E -:1000D6000DE4907FC9F07526FF907FB6E030E1030E -:1000E600020168120CFF8F36120E1B8F11E536C304 -:1000F6009513500F120DDEEF30E008E51120E703EF -:0C003600907F987410F090C000E0FF2252 -:03004300020E00AA -:10000300C0E0C083C082C085C084C086758600906E -:100013007FC4E4F05391EF907FAB7404F0D086D0AB -:0A00230084D085D082D083D0E03273 -:030000000209C52D -:4001060030135FC213E5366059B48003431102E51130E724E536D3942040037536208536247E7E7F8075297E752A80120B9AE53625E0907FB7F0802AE536D3943F4003753B -:40014600363F853624907E80E511F07E7E7F8175297E752A81120935E53604907FB7F07526FF907FCEE030E106200E030203C4E4F53574402535F582E4347CF583E0FFE589 -:40018600357C007B017A7E79002400F9EC347EFAEF120A970535E535B420D7907E00E0606E7F01907E11E0FD120CDA907E01E0FF120C1C907E02E0FF120C42D211D2127562 -:4001C6003604907E03E06005C2124336C0907E04E0B40107C21243360B8010907E04E06007C21143360980034336027F03AD36120CDA431A80907F987414F090C000E51A72 -:40020600F0907F987412F0E517440690C000F0907E05E06012A3E0543FF519907F987413F090C000E519F0907E07E06042907E13E0600543160480035316FBE4FFAD161247 -:400246000CDA907E08E06005431880800353187F5318FC907E09E06011431802A3E0FF120C8E907E0BE0FF120CB4AF18120C68907E0EE06018A3E06005431A018003531AD4 -:40028600FE907F987414F090C000E51AF0907E0CE06018A3E06005431A028003531AFD907F987414F090C000E51AF0907E12E0F513A3E0139214A3E0F514A3E06005431AC3 -:4002C600108003531AEF907F987414F090C000E51AF0907E16E060325319BF907F987413F0E519547F90C000F0907F987411F0120DD2EF54FE90C000F05316FDE4FFAD1621 -:40030600120CDAE4F50EF50DD20F907E17E0600F431602E4FFAD16120CDA750D01D20F907E18E06010907F987412F0E517440490C000F0D20B907E19E06011431940907F0D -:40034600987413F0E519547F90C000F0907E1AE0600F5316FEE4FFAD16120CDA750F01D20F907E1BE0600F431601E4FFAD16120CDAE4F50FD20F907E1CE0600E907F9874A9 -:4003860012F0E517440290C000F0907E1DE06002D213907E1EE06008751001E4F512D20F907E1FE06011907FD77411F07431F07415F07435F0D20DC20EE4907FCFF0301674 -:4003C60071E51260021512E530D3940040041530806075300A120DD2EF5401F536650E600785360ED20F8011120E27EF5410F53665096005853609D20F120E27EF5480F5C1 -:4004060036650A600585360AD20F120E27EF5420F536650B600885360B301102D20F120E27EF5440F536650C600885360C301202D20F30162A907FD2E020E123907B40E035 -:400446006009E0F532907B42E0F533907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020529E5277040300F39E5127035C20FF5357E007B0074082535DB -:40048600F9EE3400FA120A51FF74802535F582E4347BF583EFF00535E535B409DB907FC37409F0751210E4F51075270222E5276402703630052FC205F5357E007B00742B96 -:4004C6002535F9EE3400FA120A51FF74802535F582E4347BF583EFF00535E535B405DB907FC37405F075270322E53260337531031532E4F5357E007B0074312535F9EE34CD -:4005060000FA120A51FF74802535F582E4347BF583EFF00535E535B403DB907FC37403F0E4F52722907FE9E0120AA9060800067C0106E903054D0605F90805ED0905D50A02 -:4005460005E40B00000739907FEBE024FE60161460502402706F7419907FD4F07400907FD5F0020740907FEAE070047F0280027F03758282758319EFF0758274758319F06E -:40058600758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020740907FEAE0FF120B1CEA49600DEA907FD4F0E9907FD5F0020740907FB4E0449B -:4005C60001F0020740907FB4E04401F0020740907F00E525F0907FB57401F0020740907FEAE0F525020740120748907FEAE0F523020740907F00E523F0907FB57401F00216 -:400606000740907FE8E0247F60241460312402705BA201E433FF25E0FFA207E4334F907F00F0E4A3F0907FB57402F0020740E4907F00F0A3F0907FB57402F0020740907F2C -:40064600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020740907FB4E04401F0020740907FE8E024FE601E240216 -:400686006003020740907FEAE0B40106120DF9020740907FB4E04401F0020740907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F090F8 -:4006C6007FECE05480FF131313541FFFE054072F907FD7F0E04420F08060907FB4E04401F08057907FE8E024FE60192402704B907FEAE0B40105120DF6803F907FB4E04487 -:4007060001F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F9 -:40074600F022E4907F93F0907F9C7430F0907F967420F0907F9574C0F0907F9E743FF0907F987410F0E4F58E907FDF74FFF0907FDEF0E4F5087F017B0074082FF9E4340023 -:40078600FAE4120A970FBF09EE751301E4F512F530F511C20FC213C20EC20BC210C204907F987413F075190390C0007403F07F0CE4FD120CDA7F108F18120C68907F9874C2 -:4007C60012F07F018F17EF440690C000F00FE4FD120CDAE4FF7EA3AD068D16120CDA907F987411F090C000E4F07F057D7F120CDA7F01120D6A7F037D07120CDAE4FFE5167B -:40080600547FFD120CDA120E0F8F15E4FFE5164480FD120CDAE51530E704C2088002D208907F987414F0751A8090C0007480F0D20322D215907F92E04402F0120DF9D2E87C -:4008460043D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAE740DF0D2AFD216120D24C202E4F528F530C209F523C20390F7 -:400886007FA104F0907FD8E065346048300305D216120046E50F6022E52660161526907FD8E030E6047F2080027F30907F96EFF0801A907F967430F08012907FD9E030E2F8 -:4008C600047F3080027F20907F96EFF0907FD8E0F5348020300307C2161200468016E50F7012907FD9E030E2047F3080027F20907F96EFF0300207C20212052A8086300AE4 -:4009060083C20A120B5D02088A22907F987410F0AF24E52AF582E529F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF24E52AF582E529F583C2A3 -:40094600AF058690C000E00586F0A30586DFF70586D2AF22907F987408F0AF24E52AF582E529F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AFCD -:4009860024E52AF582E529F583C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022784B -:4009C6007FE4F6D8FD758139020A0C020838E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B010211 -:400A0600040810204080900D8BE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582B0 -:400A4600C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E925BB -:400A860082F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E47374028F -:400AC600936860EFA3A3A380DFE4907F93F0907F9C7420F0300103FF80027F00907F96EFF0E4907F94F0907F9D74FFF0E4907F97F0300811907F95F0907F9E74FFF0907F05 -:400B0600987420F022E4907F95F0907F9E74DFF0E4907F98F0228F35E4F5367537FF753819753986AB37AA38A939900001120A6AB4031DAF360536EFB5350122120A517E5C -:400B46000029FFEE3AA9077537FFF538893980D47B007A00790022907FD8E0F535120ACF200807907F92E054FDF0907FD6E04480F01209B5907FD6E030E70E300105120D9C -:400B8600BC8006120D49EF60E1907F92E04402F012074822052AE52AAE297002052914F5828E83E511F0120036052AE52AAC297002052914F5828C83EFF01524E5246007C7 -:400BC600120E1B8F1180CD22C0E0C083C082C085C084C086758600D2025391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D20A9F -:400C06005391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E519547F90C000F022907F9874E8 -:400C460013F090C00074BFF0907F987411F090C000EFF0907F987413F0E519547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E57C -:400C860019547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E519547F90C000F022907F987413F090C00074BFF0907F987416F0FE -:400CC60090C000EFF0907F987413F0E519547F90C000F022907F987413F0E519547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF022120DEA8F37120D91 -:400D0600EA8F38E53765386012120DEA8F37E53765386007120DEA8F3880E8AF3722907FD6E054FBF0E04408F0301604E04402F07FF47E01120DA5907FD6E054F7F0E04448 -:400D460004F022907FD8E0F536120748120E27EF30E60B907FD8E0653660F17F0122120ACF7F0022AE07E4FFE516547FFD120CDA907F987411F090C000EEF0E4E516448084 -:400D8600FD120CDA22052B02000000000331030000C186C102C10AC101C107012700008E368F37E5371537AE36700215364E60051209A480EE22907FD6E04401F07F0D7E8D -:400DC60000120DA5907FD6E054FEF022907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22D20122C2012200000000020BCE00020EF1 -:400E0600040002000300020BF5907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22000000000000000000000000000000000000004E -:400E4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C -:400E8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C -:400EC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC -:400F060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB -:400F4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B -:400F8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B -:400FC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB -:4010060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA -:40104600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A -:40108600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A -:4010C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA -:4011060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9 -:401146000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069 -:401186000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029 -:4011C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9 -:4012060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8 -:401246000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068 -:401286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028 -:4012C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8 -:4013060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7 -:401346000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067 -:401386000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027 -:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 -:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 -:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 -:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 -:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 -:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 -:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 -:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 -:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 -:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 -:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 -:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 -:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 -:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 -:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 -:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 -:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 -:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 -:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 -:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF -:401906000040CD06190100000102000209027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240006D -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:041A0600720000006A -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19w.HEX b/firmware/keyspan/usa19w.HEX deleted file mode 100644 index a3b84313f2ca832db2b74a0bc56c2cd1c9da25cf..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa19w.HEX +++ /dev/null @@ -1,141 +0,0 @@ -:03003300020D5C5F -:10000300E4907F93F0907F9C7430F0E4907F96F0BF -:10001300907F94F0907F9D74FFF0E4907F97F09031 -:0F0023007F95F0907F9E7417F0E4907F98F02205 -:10004600300F18120D38EFC3951440030200D890F4 -:100056007FBF7401F0C20FC20A8077300C3B907FDD -:10006600C6E020E16D120D38EFC394405064907ED7 -:1000760040E013920F907FC7E014F51C200A116030 -:100086000FF5237E7E7F4175277E75284112080174 -:10009600C20CE4907FC7F08039907FC8E020E1323F -:1000A600120D38EFC394405029907DC0E013920F93 -:1000B600907FC9E014F51C200A11600FF5237E7DA0 -:1000C6007FC175277D7528C1120801D20CE4907F87 -:1000D600C9F0907FB6E030E10302015E120C418F59 -:1000E6001C120D448F11E51CC39513500F120D20E1 -:1000F600EF30E008E51120E70330125CC212E51C80 -:0C003600907F987410F090C000E0FF2252 -:03004300020E00AA -:030000000208B63D -:400106006056B48003431102E51130E724E51CD394204003751C20851C237E7E7F8075277E752880120A86E51C251C907FB7F08027E51CD3943F4003751C3F851C23907E06 -:4001460080E511F07E7E7F8175277E752881120826E51C04907FB7F0907FCEE030E106200D030203BAE4F51B7440251BF582E4347CF583E0FFE51B7C007B017A7E7900244A -:4001860000F9EC347EFAEF120A0D051BE51BB420D7907E00E0606E7F01907E11E0FD120C1C907E01E0FF120B5E907E02E0FF120B84D210D211751C04907E03E06005C211D7 -:4001C600431CC0907E04E0B40107C211431C0B8010907E04E06007C210431C098003431C027F03AD1C120C1C431980907F987414F090C000E519F0907F987412F0E51644CE -:400206000690C000F0907E05E06012A3E0543FF518907F987413F090C000E518F0907E07E06042907E13E0600543150480035315FBE4FFAD15120C1C907E08E060054317BC -:4002460080800353177F5317FC907E09E06011431702A3E0FF120BD0907E0BE0FF120BF6AF17120BAA907E0EE06018A3E0600543190180035319FE907F987414F090C00046 -:40028600E519F0907E0CE06018A3E0600543190280035319FD907F987414F090C000E519F0907E12E0F513A3E0139213A3E0F514A3E0600543191080035319EF907F98742D -:4002C60014F090C000E519F0907E16E060325318BF907F987413F0E518547F90C000F0907F987411F0120D14EF54FE90C000F05315FDE4FFAD15120C1CE4F50EF50DD20EEB -:40030600907E17E0600F431502E4FFAD15120C1C750D01D20E907E18E06010907F987412F0E516440490C000F0D20A907E19E06011431840907F987413F0E518547F90C064 -:4003460000F0907E1AE0600F5315FEE4FFAD15120C1C750F01D20E907E1BE0600F431501E4FFAD15120C1CE4F50FD20E907E1CE0600E907F987412F0E516440290C000F0D8 -:40038600907E1DE06002D212907E1EE06008751001E4F512D20E907E1FE06011907FD77411F07431F07415F07435F0D20CC20DE4907FCFF0301571E51260021512E52ED326 -:4003C60094004004152E8060752E0A120D14EF5401F51C650E6007851C0ED20E8011120D50EF5410F51C65096005851C09D20E120D50EF5480F51C650A6005851C0AD20EFB -:40040600120D50EF5420F51C650B6008851C0B301002D20E120D50EF5440F51C650C6008851C0C301102D20E30152A907FD2E020E123907B40E06009E0F530907B42E0F572 -:4004460031907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E10302051FE5257040300E39E5127035C20EF51B7E007B007408251BF9EE3400FA1209C7FF7447 -:4004860080251BF582E4347BF583EFF0051BE51BB409DB907FC37409F0751210E4F51075250222E5256402703630052FC205F51B7E007B007429251BF9EE3400FA1209C7C2 -:4004C600FF7480251BF582E4347BF583EFF0051BE51BB405DB907FC37405F075250322E5306033752F031530E4F51B7E007B00742F251BF9EE3400FA1209C7FF7480251B26 -:40050600F582E4347BF583EFF0051BE51BB403DB907FC37403F0E4F52522907FE9E0120A1F05F600066A0106D70305430605E90805E30905CB0A05DA0B00000727907FEBC9 -:40054600E024FE60161460502402706F7419907FD4F07400907FD5F002072E907FEAE070047F0280027F03758282758319EFF0758274758319F0758258758319F0907FEA65 -:40058600E004758217758319F07419907FD4F07412907FD5F002072E907FEAE0FF120A45EA49600DEA907FD4F0E9907FD5F002072E907FB4E04401F002072E907FB4E044D1 -:4005C60001F002072E907F00E524F0907FB57401F002072E907FEAE0F52402072E12073602072E907F007401F0907FB5F002072E907FE8E0247F60241460312402705BA221 -:4006060001E433FF25E0FFA207E4334F907F00F0E4A3F0907FB57402F002072EE4907F00F0A3F0907FB57402F002072E907FECE0F45480FFC4540FFFE054072F25E024B4CD -:40064600F582E4347FF583E054FD907F00F0E4A3F0907FB57402F002072E907FB4E04401F002072E907FE8E024FE601E2402600302072E907FEAE0B40106120D6302072E53 -:40068600907FB4E04401F002072E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF131313541FFFE054072F907F69 -:4006C600D7F0E04420F08060907FB4E04401F08057907FE8E024FE60192402704B907FEAE0B40105120D60803F907FB4E04401F08036907FEAE07020907FECE0F45480FFAD -:40070600C4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022E4907F93F0907F9C7430F0E4907F96F06B -:40074600907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5087F017B0074082FF9E43400FAE4120A0D0FBF09EE751301E4F512F52EF511A2 -:40078600C20EC212C20DC20AC20FC204907F987413F075180390C0007403F07F0CE4FD120C1C7F108F17120BAA907F987412F07F018F16EF440690C000F00FE4FD120C1C71 -:4007C600E4FF7EA3AD068D15120C1C907F987411F090C000E4F07F057D7F120C1C7F01120CAC7F037D07120C1C907F987414F075198090C0007480F0D20322907F98741059 -:40080600F0AF23E528F582E527F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF23E528F582E527F583C2AF058690C000E00586F0A30586DFF76F -:400846000586D2AF22907F987408F0AF23E528F582E527F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF23E528F582E527F583C2AF058690C045 -:4008860000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022787FE4F6D8FD7581310208FD020942E43B -:4008C60093A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B0102040810204080900CCDE47E019360BC36 -:40090600A3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BED214907F83 -:4009460092E04402F0120D63D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAE740DF0D2AFD215120C66C202E4F557 -:4009860026F52EC208C203907FA104F0907FD8E0651A6010300305D215120046907FD8E0F51A8008300305C215120046300207C20212052080D63009D3C209120ABA80CC40 -:4009C60022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E51F -:400A0600833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF8F58 -:400A46001BE4F51C751DFF751E19751F86AB1DAA1EA91F9000011209E0B4031DAF1C051CEFB51B01221209C77E0029FFEE3AA907751DFFF51E891F80D47B007A00790022F3 -:400A86000528E528AE277002052714F5828E83E511F01200360528E528AC277002052714F5828C83EFF01523E5236007120D448F1180CD22907FD8E0F51B120003907FD6AB -:400AC600E04480F01208A6907FD6E030E70E300105120CFE8006120C8BEF60E112073622C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D0DF -:400B060084D085D082D083D0E032C0E0C083C082C085C084C086758600D2025391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C08675860025 -:400B4600D2095391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E518547F90C000F022907FDB -:400B8600987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E518547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F98741307 -:400BC600F0E518547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E518547F90C000F022907F987413F090C00074BFF0907F9874F2 -:400C060016F090C000EFF0907F987413F0E518547F90C000F022907F987413F0E518547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF022120D2C8F1D44 -:400C4600120D2C8F1EE51D651E6012120D2C8F1DE51D651E6007120D2C8F1E80E8AF1D22907FD6E054FBF0E04408F0301504E04402F07FF47E01120CE7907FD6E054F7F0D8 -:400C8600E04404F022907FD8E0F51C120736120D50EF30E60B907FD8E0651C60F17F01221200037F0022AE07E4FFE515547FFD120C1C907F987411F090C000EEF0E4E51599 -:400CC6004480FD120C1C2205290200000000032F030000C186C102C109C101C107012500008E1C8F1DE51D151DAE1C7002151C4E600512089580EE22907FD6E04401F07F86 -:400D06000D7E00120CE7907FD6E054FEF022907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F2B -:400D4600987415F090C000E0FF22907F987416F090C000E0FF2253D8EF32D20122C20122000000000000000000000000000000000000000000000000000000000000000073 -:400D8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D -:400DC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020B1000020EC0 -:400E06000400020AE600020B370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072 -:400E4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C -:400E8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C -:400EC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC -:400F060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB -:400F4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B -:400F8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B -:400FC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB -:4010060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA -:40104600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A -:40108600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A -:4010C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA -:4011060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9 -:401146000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069 -:401186000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029 -:4011C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9 -:4012060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8 -:401246000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068 -:401286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028 -:4012C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8 -:4013060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7 -:401346000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067 -:401386000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027 -:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 -:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 -:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 -:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 -:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 -:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 -:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 -:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 -:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 -:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 -:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 -:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 -:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 -:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 -:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 -:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 -:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 -:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 -:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 -:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF -:401906000040CD06080100000102000209027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240007E -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:041A0600720000006A -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28.HEX b/firmware/keyspan/usa28.HEX deleted file mode 100644 index 000c97863c011e2c643079fbd5c56ce2608f97fa..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa28.HEX +++ /dev/null @@ -1,148 +0,0 @@ -:0A0026001217DB1218B51214C322E2 -:0300330002001DAB -:04001D0053D8EF3293 -:100006008E128F13E5131513AE12700215124E6081 -:07001600051218A480EE2280 -:03000300020046B2 -:10004600C0E0C083C082C086758600C0D075D00867 -:1000560030990E301107A217929B854699C299D204 -:100066001F30C10E301207A21892C38547C1C2C104 -:10007600D220201F03020442C21F2003030202678C -:10008600201103020138E54AC3957C503E20133601 -:10009600200B33907F9BE020E303201C29301B12AA -:1000A600AE4A054A74402EF582E4347EF583E013A9 -:1000B6009217AE4A054A74402EF582E4347EF583E3 -:1000C600E0F546020440C211020440907FC7E4F006 -:1000D600C20330150CC215907FBF04F0C211020492 -:1000E60040907FC8E030E105C211020440907FC90C -:1000F600E0F57C907DC0E013921520132D200B2A8D -:03004300021B009D -:0300230002004692 -:03003B000200467A -:0300000002163DA8 -:40010600907F9BE020E303201C20301B11907DC1E0139217A3E0F546754A03020440754A02907DC1E0F546020440754A01C211020440E54AC3957C50030201E0907FC6E08A -:4001460030E107C221C205020440907FC7E0F57C907E40E01392153013030201D8200B7220006F907F9BE020E303201C65301B10907E41E013929BA3E0F599754A038009BE -:40018600907E41E0F599754A02E54AC3957C4017907FC7E4F0C203201503020440C215907FBF04F0020440301B12AE4A054A74402EF582E4347EF583E0139217AE4A054AA7 -:4001C60074402EF582E4347EF583E0F546D211020440754A01C221020440301303020262200B79907F9BE020E303201C6F301B12AE4A054A74402EF582E4347EF583E013DC -:40020600929BAE4A054A74402EF582E4347EF583E0F599E54AC3957C4017907FC7E4F0C203201503020440C215907FBF04F0020440301B12AE4A054A74402EF582E4347EB6 -:40024600F583E0139217AE4A054A74402EF582E4347EF583E0F546D211020440C221020440201103020319E54AC3957C503E201336200B33907F9BE020E303201C29301B5F -:4002860012AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546020440C211020440907FC9E4F0D20330150CC215907FBF04F0C2110276 -:4002C6000440907FC6E030E105C211020440907FC7E0F57C907E40E013921520132D200B2A907F9BE020E303201C20301B11907E41E0139217A3E0F546754A03020440759E -:400306004A02907E41E0F546020440754A01C211020440E54AC3957C50030203C1907FC8E030E107C221C205020440907FC9E0F57C907DC0E01392153013030203B9200B48 -:400346007220006F907F9BE020E303201C65301B10907DC1E013929BA3E0F599754A038009907DC1E0F599754A02E54AC3957C4017907FC9E4F0D203201503020440C21573 -:40038600907FBF04F0020440301B12AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546D211020440754A01C221020440301303020463 -:4003C6003E200B74907F9BE020E303201C6A301B12AE4A054A74C02EF582E4347DF583E013929BAE4A054A74C02EF582E4347DF583E0F599E54AC3957C4013907FC9E4F09D -:40040600D203301535C215907FBF04F0802C301B12AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546D2118002C221D2252020030230 -:40044600080CC220200403020631201203020502E54BC3957D503E201436200D33907F9AE020E503201E29301D12AE4B054B74402EF582E4347DF583E0139218AE4B054B99 -:4004860074402EF582E4347DF583E0F54702080AC21202080A907FCBE4F0C20430160CC216907FC104F0C21202080A907FCCE030E105C21202080A907FCDE0F57D907CC0BB -:4004C600E013921620142D200D2A907F9AE020E503201E20301D11907CC1E0139218A3E0F547754B0302080A754B02907CC1E0F54702080A754B01C21202080AE54BC39566 -:400506007D50030205AA907FCAE030E107C222C20602080A907FCBE0F57D907D40E01392163014030205A2200D7220006F907F9AE020E503201E65301D10907D41E013920D -:40054600C3A3E0F5C1754B038009907D41E0F5C1754B02E54BC3957D4017907FCBE4F0C20420160302080AC216907FC104F002080A301D12AE4B054B74402EF582E4347D24 -:40058600F583E0139218AE4B054B74402EF582E4347DF583E0F547D21202080A754B01C22202080A30140302062C200D79907F9AE020E503201E6F301D12AE4B054B7440E9 -:4005C6002EF582E4347DF583E01392C3AE4B054B74402EF582E4347DF583E0F5C1E54BC3957D4017907FCBE4F0C20420160302080AC216907FC104F002080A301D12AE4B91 -:40060600054B74402EF582E4347DF583E0139218AE4B054B74402EF582E4347DF583E0F547D21202080AC22202080A2012030206E3E54BC3957D503E201436200D33907F1A -:400646009AE020E503201E29301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F54702080AC21202080A907FCDE4F0D20430160C43 -:40068600C216907FC104F0C21202080A907FCAE030E105C21202080A907FCBE0F57D907D40E013921620142D200D2A907F9AE020E503201E20301D11907D41E0139218A352 -:4006C600E0F547754B0302080A754B02907D41E0F54702080A754B01C21202080AE54BC3957D500302078B907FCCE030E107C222C20602080A907FCDE0F57D907CC0E013AC -:400706009216301403020783200D7220006F907F9AE020E503201E65301D10907CC1E01392C3A3E0F5C1754B038009907CC1E0F5C1754B02E54BC3957D4017907FCDE4F0AE -:40074600D20420160302080AC216907FC104F002080A301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F547D21202080A754B0173 -:40078600C22202080A301403020808200D74907F9AE020E503201E6A301D12AE4B054B74C02EF582E4347CF583E01392C3AE4B054B74C02EF582E4347CF583E0F5C1E54B3F -:4007C600C3957D4013907FCDE4F0D204301635C216907FC104F0802C301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F547D2122A -:400806008002C222D22520980302093EC2982001030208B0202327AE48054874802EF582E4347EF583E599F0301B49AE48054874802EF582E4347EF583E598F08036AF996E -:40084600EFB55804D20B802CEFB55704C20B8024AE48054874802EF582E4347EF583EFF0301B11AE48054874802EF582E4347EF583E598F0D219E548C39554500302093C9F -:40088600907FB8E030E115E548C39440500302093C15481548052DD20C02093C907FB7E548F0754800C20102093C202327AE48054874002EF582E4347EF583E599F0301BBF -:4008C60049AE48054874002EF582E4347EF583E598F08036AF99EFB55804D20B802CEFB55704C20B8024AE48054874002EF582E4347EF583EFF0301B11AE48054874002E51 -:40090600F582E4347EF583E598F0D219E548C395544023907FB6E030E111E548C39440401515481548052DD20C800B907FB9E548F0754800D201D22520C003020A70C2C016 -:400946002002030209E2202427AE49054974802EF582E4347DF583E5C1F0301D49AE49054974802EF582E4347DF583E5C0F08036AFC1EFB57004D20D802CEFB56F04C20DAE -:400986008024AE49054974802EF582E4347DF583EFF0301D11AE49054974802EF582E4347DF583E5C0F0D21AE549C3956C5003020A6E907FBCE030E115E549C39440500351 -:4009C600020A6E154915490539D20E020A6E907FBBE549F0754900C202020A6E202427AE49054974002EF582E4347DF583E5C1F0301D49AE49054974002EF582E4347DF555 -:400A060083E5C0F08036AFC1EFB57004D20D802CEFB56F04C20D8024AE49054974002EF582E4347DF583EFF0301D11AE49054974002EF582E4347DF583E5C0F0D21AE54983 -:400A4600C3956C4023907FBAE030E111E549C394404015154915490539D20E800B907FBDE549F0754900D202D225302505C225020056D0D0D086D082D083D0E032907FCE99 -:400A8600E030E103020BA5E4F51274402512F582E4347CF583E0FFE5127C007B00244CF9EC3400FAEF1215CD0512E512B418DBE54C600C75C92075C836854DCA854ECBE5BC -:400AC6004F13921B929FE55013921CE551139223E5526009907F98E054FBF08007907F98E04404F0E5536009907F98E0547FF08007907F98E04480F0E559600BC213C20B18 -:400B0600907F95E04402F0E55A600BD20BD20C907F95E04402F0E55B600DC2AFC211D200E4F57CF54AD2AFE55C6005302302D20BE55D6015907F95E054FDF0907F9EE044D9 -:400B460002F0907F98E054FDF0E55E600AD29CC298752E01754028E55F6007C29CE4F548F52EE5606003E4F548E5616002D207E5626008E55E7002F540D20CE56360199060 -:400B86007FD77411F07431F07412F07432F07415F07435F0D203D201D209E4907FCFF0A213E433FF652B60048F2BD20CA20BE433FF652C60048F2CD20C907F9BE054086589 -:400BC600276007E05408F527D20C907F9BE05440B52909E054406440F529D20C300735C2AF300118907FB8E020E127E5486009907FB7F0E4F548C201C2078016907FB6E0E9 -:400C060020E10FE5486009907FB9F0E4F548D201C207D2AF20053730031B907FC6E020E12D907E40E0139215754A01907FC7E0F57CD2058019907FC8E020E112907DC0E0CF -:400C4600139215754A01907FC9E0F57CD205202133200006E54A657C702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F57CF54A30150AC215C200907F5C -:400C8600BF7401F0302103020D94200503020D94301C0A907F9BE020E303020D94300B03020D94301303020D94300362301B12AF4A054A74402FF582E4347EF583E01392CE -:400CC6002DAF4A054A74402FF582E4347EF583E0F513E54AC3957C502A301B12AF4A054A74402FF582E4347EF583E0139217AF4A054A74402FF582E4347EF583E0F546D266 -:400D060011806BC211E4907FC7F0C2038060301B12AF4A054A74C02FF582E4347DF583E013922DAF4A054A74C02FF582E4347DF583E0F513E54AC3957C502A301B12AF4A67 -:400D4600054A74C02FF582E4347DF583E0139217AF4A054A74C02FF582E4347DF583E0F546D2118009C211E4907FC9F0D203301B04A22D929BD221C2AF85139920110D3043 -:400D8600150AC215C200907FBF7401F0D2AF907FD0E030E103020EB5E4F51274C02512F582E4347BF583E0FFE5127C007B002464F9EC3400FAEF1215CD0512E512B418DB51 -:400DC600E564600B758960758840D2DF85658DE56713921D92C7E56813921EE569139224E56A6009907F97E054EFF08007907F97E04410F0E56B6009907F97E0547FF080A4 -:400E060007907F97E04480F0E571600BC214C20D907F94E04408F0E572600BD20DD20E907F94E04408F0E573600DC2AFC212D200E4F57DF54BD2AFE5746005302402D20D20 -:400E4600E5756015907F94E054F7F0907F9DE04408F0907F97E054F7F0E576600AD2C4C2C0753A01754128E5776007C2C4E4F549F53AE5786003E4F549E5796002D208E5F0 -:400E86007A6008E5767002F541D20EE57B6019907FD77413F07433F07414F07434F07416F07436F0D204D202D20AE4907FD1F0A214E433FF653760048F37D20EA20DE43304 -:400EC600FF653860048F38D20E907F9AE0542065336007E05420F533D20E907F9AE05440B53509E054406440F535D20E300835C2AF300218907FBCE020E127E54960099099 -:400F06007FBBF0E4F549C202C2088016907FBAE020E10FE5496009907FBDF0E4F549D202C208D2AF20063730041B907FCAE020E12D907D40E0139216754B01907FCBE0F503 -:400F46007DD2068019907FCCE020E112907CC0E0139216754B01907FCDE0F57DD206202233200006E54B657D702A30061A300409E4907FCBF0C2048007E4907FCDF0D2042C -:400F8600C206E4F57DF54B30160AC216C200907FC17401F03022030210A42006030210A4301E0A907F9AE020E5030210A4300D030210A43014030210A4300462301D12AF8E -:400FC6004B054B74402FF582E4347DF583E013922DAF4B054B74402FF582E4347DF583E0F513E54BC3957D502A301D12AF4B054B74402FF582E4347DF583E0139218AF4B78 -:40100600054B74402FF582E4347DF583E0F547D212806BC212E4907FCBF0C2048060301D12AF4B054B74C02FF582E4347CF583E013922DAF4B054B74C02FF582E4347CF5F2 -:4010460083E0F513E54BC3957D502A301D12AF4B054B74C02FF582E4347CF583E0139218AF4B054B74C02FF582E4347CF583E0F547D2128009C212E4907FCDF0D204301DF4 -:4010860004A22D92C3D222C2AF8513C120120D30160AC216C200907FC17401F0D2AF907FC2E030E10302117AE51A7046300C3FE540703BA20933F531C209C20CE4F5127E0D -:4010C600007B0074262512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B40CDB907FC3740CF075401022751A0122E51A64017045300E3EE541703AA2C5 -:401106000A33F53DC20AC20EE4F5127E007B0074322512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B40CDB907FC3740CF0754110751A0222E51C60CA -:4011460030151CE4F5127E007B00741B2512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B403DB907FC37403F0E4F51A22907FE9E012161712400012A7 -:40118600B401132003119E06123308122D0912200A13760B0000136F907FEBE024FE6016146040240270697419907FD4F07400907FD5F0021376907FEAE0FF12174B8B1261 -:4011C6008A138914EA496011AE02EE907FD4F0AF01EF907FD5F0021376907FB4E04401F0021376907FEAE0FF12179A8B128A138914EA496011AE02EE907FD4F0AF01EF9083 -:401206007FD5F0021376907FB4E04401F0021376907FB4E04401F0021376907F007401F0907FB5F00213761214C3021376907F007401F0907FB5F0021376907FE8E0247FBF -:4012460060241460312402705BA226E433FF25E0FFA22BE4334F907F00F0E4A3F0907FB57402F0021376E4907F00F0A3F0907FB57402F0021376907FECE0F45480FFC45429 -:401286000FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0021376907FB4E04401F0021376907FE8E024FE601D24026003021376907FEA0B -:4012C600E0B40105C226021376907FB4E04401F0021376907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF131313A7 -:40130600541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D226803F907FB4E04401F08036907FEAE07020A3 -:40134600907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F0222028030214C2E54063 -:4013860060021540E548604F65447045E542F460020542E542C39555403DC2AF300118907FB8E020E127907FB7E548F0C201E4F548F542F5448016907FB6E020E10F907F07 -:4013C600B9E548F0D201E4F548F542F544D2AF8006854844E4F542E52E602D201907907F9BE030E00EE52F6005E4F52FD20CE4F53E8013E53ED39556500CE53EB556057504 -:401406002F01D20C053EC219E54160021541E549604F65457045E543F460020543E543C3956D403DC2AF300218907FBCE020E127907FBBE549F0C202E4F549F543F54580E2 -:4014460016907FBAE020E10F907FBDE549F0D202E4F549F543F545D2AF8006854945E4F543E53A602D201A07907F9AE030E20EE53B6005E4F53BD20EE4F53F8013E53FD35E -:40148600956E500CE53FB56E05753B01D20E053FC21A907FD2E020E123907B40E06009E0F51C907B42E0F51D907B41E06009907FD77417F07437F0E4907FD3F022E4907FC5 -:4014C60093F0907F9C7430F0907F96E04410F0907F94740DF0907F9D749AF0907F97E054FDF0907F957423F0907F9E7484F0E4907FC7F0907FC9F0907FCFF075984043A89E -:4015060010C21BC205C221C20BC213F57CF54AC211C215F542C219F544F548C223C21CF52DF52FC207C200C21FF53EC209D20CF526907FCBF0907FCDF0907FD1F075C04043 -:4015460043A840C21DC206C222C20DC214F57DF54BC212C216F543C21AF545F549C224C21EF539F53BC208C200C220F53FC20AD20E753201907FDF74FFF0907FDEF0D228DE -:4015860022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E553 -:4015C600833AF583E49322BB010689828A83F0225002F722BBFE01F322BB0110E58229F582E5833AF583E0F5F0A3E0225009E92582F886F008E622BBFE0AE92582F8E2F511 -:40160600F008E222E5832AF583E993F5F0A3E99322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF787FE4F6D8FD75817D0E -:401646000216840216C9E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B010204081020408090181A -:40168600C5E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DE39 -:4016C600E780BE751101907F92E054FDF0907FAEE0FFD39226E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE044C5 -:4017060001F0907FAEE0440DF0D2AFD2BCD2BED22D12187FC227C225C228302803120A83907FD8E065106008E0F51012137E80EA302707C22712117B80E0302CDDC22C12C5 -:40174600002680D622E4FE7517FF751819751912AB17AA18A9199000011215A06402702DAD060EEDB50701229000021215DF85F015F5166215E5156216E516621529FDE551 -:40178600153AA9057517FFF518891980C37B007A007900228F15E4F5167517FF751819751986AB17AA18A9199000011215A0B4031DAF160516EFB51501221215877E0029BE -:4017C600FFEE3AA9077517FFF518891980D47B007A00790022E4907F93F0907F9CF0907F94F0907F9D7402F0907F97F0E4907F95F0907F9E74FFF0E4907F98F0907F9DF003 -:4018060022C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2275391EF9024 -:401846007FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D22C5391EF907FAB7408F0D086D084D085D082D083D0E032907FD6E054FBF0DD -:40188600E04408F0302D04E04402F07FF47E01120006907FD6E054F7F0E04404F0227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022C125 -:4018C600AA011A00031B030000C127C12CC126C12B000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF0031 -:401906000040CD060F0100000102000109027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400078 -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:401A0600720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E -:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060 -:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020 -:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002183100021B78 -:091B06000400021807000218583F -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28x.HEX b/firmware/keyspan/usa28x.HEX deleted file mode 100644 index 9f0f7fac7609ccd9aefa72b39fcbbc3207837c0d..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa28x.HEX +++ /dev/null @@ -1,141 +0,0 @@ -:030033000212F7BF -:10000300E4907F93F0907F9C7430F0E4907F96F0BF -:10001300907F94F0907F9D74FFF0E4907F97F09031 -:0F0023007F95F0907F9E7407F0E4907F98F02215 -:1000460030091812131BEFC3953C40030200D890E9 -:100056007FBF7401F0C209C200807730033B907FF6 -:10006600C6E020E16D12131BEFC394405064907EEE -:1000760040E0139209907FC7E014F5192000116043 -:100086000FF5087E7E7F41750C7E750D41120CBA08 -:10009600C203E4907FC7F08039907FC8E020E13248 -:1000A60012131BEFC394405029907DC0E0139209B0 -:1000B600907FC9E014F519200011600FF5087E7DC8 -:1000C6007FC1750C7D750DC1120CBAD203E4907F09 -:1000D600C9F0907FB6E030E1030201601211D68FBD -:1000E600191213278F36E519C3953A500F1212EBE2 -:1000F600EF30E008E53620E703300B5EC20BE5196A -:0C003600907F987410F090C000E0FF2252 -:03004300021300A5 -:03000000020E00ED -:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F4BE51925E0907FB7F08027E519D3943F400375193F851908D4 -:40014600907E80E536F07E7E7F81750C7E750D81120CDFE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AF1 -:400186007E79002400F9EC347EFAEF120ED20518E518B420D7907E00E06068907E03E060247F01E4FD1211B17F037DCD1211B1434680907F987414F090C000E546F0E490E0 -:4001C6007E13F08030907E01E0FF121035907E02E0FF12105B7F01907E11E0FD1211B17F037D071211B1434680907F987414F090C000E546F0907F987412F0E5404406903E -:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA -:400246007F5342FC907E09E06011434202A3E0FF1210A7907E0BE0FF1210CDAF42121081907E03E0600853427FAF42121081907E0CE06018A3E0600543460280035346FDB4 -:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B -:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212DFEF54FE90C000F0533EFDE4FFAD3E120F -:4003060011B1E4F52AF529D207907E17E0600F433E02E4FFAD3E1211B1752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98F2 -:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211B1752B01D207907E1BE0600F433E01E4FFAD3E1211B1E4F52BD207907E1CE0600E907F98741284 -:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892 -:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212DFEF5401F519652A600585192AD207121333EF5480F51965266005851926D207300D11127F -:400406001333EF5410F51965256005851925D207201B030207EC300A1812136FEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12136FEFC35A -:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D04C204E4907FCBF08039907FCCE020E13212136FEFC39440502990BC -:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D04D204E4907FCDF0907FBAE030E1030205361212208F1912137B8F37E519C3952B -:4004C6003B500F121357EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F84E503 -:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D29E51904907FBBF0907FD0E030E106200603020797C206E4F8 -:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120ED20518E518B420D7907E20E06068907E23E060247F01E4FD1211FB7F0329 -:400586007DCD1211FB434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121119907E22E0FF12113F7F01907E31E0FD1211FB7F037D071211FB4347809048 -:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB -:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121165907E2BE0FF12118BAF431210F3907E23E0600853437FAFFE -:40064600431210F3907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0D4 -:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 -:4006C600987409F012134BEF54FE90C000F0533FFDE4FFAD3F1211FBE4F533F532D208907E37E0600F433F02E4FFAD3F1211FB753201D208907E38E06010907F98740AF043 -:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F1211FB753401D208907E3BE0600F433F01E4E9 -:40074600FFAD3F1211FBE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741389 -:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C21312134BEF5401F51965336005851933D279 -:4007C60008121387EF5480F519652F600585192FD208300E11121387EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F5169035 -:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E8CFF748025BD -:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297 -:400886000E8CFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340083 -:4008C600FA120E8CFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E8CFF748025F2 -:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EE40A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F3D -:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2 -:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F0AEA49600DEA907FD4F0E9907FD5F085 -:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205 -:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04 -:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F -:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6 -:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049 -:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4 -:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B -:400B8600E4120ED20518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211B17F108F42121081907F02 -:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211B1E4FF7EA3AD068D3E1211B1907F987411F090C000E4F07F057D7F12118E -:400C0600B17F0112126A7F037D071211B1201B03020CB7752D017518017B00742D2518F9E43400FAE4120ED20518E518B409EA753B01E4F539F513F537C208C20CC206C2CD -:400C460000C20AC213907F98740BF075450390C0007403F07F0CE4FD1211FB7F108F431210F3907F98740AF07F018F41EF440690C000F0907F98740CF075478090C000744E -:400C860080F00FE4FD1211FBE4FF7EA3AD068D3F1211FB907F987409F090C000E4F07F057D7F1211FB7F0112128B7F037D071211FBD21222907F987410F0AF08E50DF582A5 -:400CC600E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF22907F20 -:400D0600987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C000E00586F0A3055C -:400D460086DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F0907FAEE0FFD39210E433FEEF4EF089 -:400D8600D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A121245C211E4F50BF513C217C212D4 -:400DC600907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D3C21812139380CC22787FE4F6D8FDC7 -:400E0600758147020E47020D6FE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B01020408102040F5 -:400E4600809012ACE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CA1E -:400E8600DFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E5B8 -:400EC6008229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3C1 -:400F0600A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EA5B4031DAF190519EFB5180122120E8C7E0029FFEE3AA907751AFFF51B891C80D47B00A5 -:400F46007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213278F1AEF423680CA228F1AFC -:400F8600050DE50DAE0C7002050C14F5828E83E51AF012133F050DE50DAC0C7002050C14F5828C83EFF01508E508600A12137B8F1AEF423780CA22C0E0C083C082C085C088 -:400FC60084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D0C6 -:4010060085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F9874108A -:40104600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E544547F90C000F022907F98741349 -:40108600F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544D9 -:4010C600547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF0902A -:40110600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090AF -:40114600C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547FEC -:4011860090C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F09075 -:4011C600C000EFF0907F987415F090C000EDF02212130F8F1A12130F8F1BE51A651B601212130F8F1AE51A651B600712130F8F1B80E8AF1A22907F98740BF0E545547F9098 -:40120600C000F0907F98740FF090C000EFF0907F98740DF090C000EDF0221213638F1A1213638F1BE51A651B60121213638F1AE51A651B60071213638F1B80E8AF1A2290C8 -:401246007FD6E054FBF0E04408F0301A04E04402F07FF47E011212C8907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211B1907F987411F090C000EEF0E4E53E4480E8 -:40128600FD1211B122AE07E4FFE53F547FFD1211FB907F987409F090C000EEF0E4E53F4480FD1211FB22050E02000000000314030000C111C118C195C110C116010A00C19C -:4012C6009B008E188F19E5191519AE18700215184E6005120D4E80EE22907F987411F090C000E0FF22907F987412F090C000E0FF2253D8EF320000000000020FE70002138A -:401306000400020FBD0002100E907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22907F987408F09050 -:40134600C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FF22907F98740DF090C000E0FFC5 -:4013860022907F98740EF090C000E0FF22120003120D5F120B4622000000000000000000000000000000000000000000000000000000000000000000000000000000000083 -:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 -:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 -:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 -:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 -:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 -:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 -:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 -:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 -:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 -:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 -:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 -:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 -:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 -:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 -:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 -:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 -:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 -:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 -:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 -:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF -:401906000040CD06100100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400076 -:4019460000070506024000000705070240000007058102400001070582024000000705830240000107058402400001070585024000010705860240000107058702400001F4 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:041A0600720000006A -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28xa.HEX b/firmware/keyspan/usa28xa.HEX deleted file mode 100644 index f14932efbafb070ca5ead356322f5a89f0d3f23c..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa28xa.HEX +++ /dev/null @@ -1,141 +0,0 @@ -:030033000212F9BD -:10000300E4907F93F0907F9C7430F0E4907F96F0BF -:10001300907F94F0907F9D74FFF0E4907F97F09031 -:0F0023007F95F0907F9E7407F0E4907F98F02215 -:10004600300918121327EFC3953C40030200D890DD -:100056007FBF7401F0C209C200807730033B907FF6 -:10006600C6E020E16D121327EFC394405064907EE2 -:1000760040E0139209907FC7E014F5192000116043 -:100086000FF5087E7E7F41750C7E750D41120CC8FA -:10009600C203E4907FC7F08039907FC8E020E13248 -:1000A600121327EFC394405029907DC0E0139209A4 -:1000B600907FC9E014F519200011600FF5087E7DC8 -:1000C6007FC1750C7D750DC1120CC8D203E4907FFB -:1000D600C9F0907FB6E030E1030201601211E48FAF -:1000E600191213338F36E519C3953A500F12130FB1 -:1000F600EF30E008E53620E703300B5EC20BE5196A -:0C003600907F987410F090C000E0FF2252 -:03004300021300A5 -:03000000020E0EDF -:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F59E51925E0907FB7F08027E519D3943F400375193F851908C6 -:40014600907E80E536F07E7E7F81750C7E750D81120CEDE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AE3 -:400186007E79002400F9EC347EFAEF120EE00518E518B420D7907E00E06068907E03E060247F01E4FD1211BF7F037DCD1211BF434680907F987414F090C000E546F0E490B6 -:4001C6007E13F08030907E01E0FF121043907E02E0FF1210697F01907E11E0FD1211BF7F037D071211BF434680907F987414F090C000E546F0907F987412F0E54044069006 -:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA -:400246007F5342FC907E09E06011434202A3E0FF1210B5907E0BE0FF1210DBAF4212108F907E03E0600853427FAF4212108F907E0CE06018A3E0600543460280035346FD7C -:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B -:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212EDEF54FE90C000F0533EFDE4FFAD3E1201 -:4003060011BFE4F52AF529D207907E17E0600F433E02E4FFAD3E1211BF752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98D6 -:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211BF752B01D207907E1BE0600F433E01E4FFAD3E1211BFE4F52BD207907E1CE0600E907F98741268 -:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892 -:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212EDEF5401F519652A600585192AD20712133FEF5480F51965266005851926D207300D111265 -:40040600133FEF5410F51965256005851925D207201B030207EC300A1812137BEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12137BEFC336 -:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D12C204E4907FCBF08039907FCCE020E13212137BEFC39440502990A2 -:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D12D204E4907FCDF0907FBAE030E10302053612122E8F191213878F37E519C39503 -:4004C6003B500F121363EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F92E5E9 -:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D37E51904907FBBF0907FD0E030E106200603020797C206E4EA -:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120EE00518E518B420D7907E20E06068907E23E060247F01E4FD1212097F030C -:400586007DCD121209434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121127907E22E0FF12114D7F01907E31E0FD1212097F037D0712120943478090FF -:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB -:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121173907E2BE0FF121199AF43121101907E23E0600853437FAFD3 -:4006460043121101907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0C5 -:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 -:4006C600987409F0121357EF54FE90C000F0533FFDE4FFAD3F121209E4F533F532D208907E37E0600F433F02E4FFAD3F121209753201D208907E38E06010907F98740AF019 -:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F121209753401D208907E3BE0600F433F01E4DA -:40074600FFAD3F121209E4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD774137A -:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C213121357EF5401F51965336005851933D26D -:4007C60008121393EF5480F519652F600585192FD208300E11121393EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F516901D -:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E9AFF748025AF -:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297 -:400886000E9AFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340075 -:4008C600FA120E9AFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E9AFF748025D6 -:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EF20A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F2F -:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2 -:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F18EA49600DEA907FD4F0E9907FD5F077 -:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205 -:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04 -:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F -:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6 -:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049 -:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4 -:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B -:400B8600E4120EE00518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211BF7F108F4212108F907FD8 -:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211BFE4FF7EA3AD068D3E1211BF907F987411F090C000E4F07F057D7F121172 -:400C0600BF7F011212787F037D071211BF7F137D011211BF201B03020CC5752D017518017B00742D2518F9E43400FAE4120EE00518E518B409EA753B01E4F539F513F537B7 -:400C4600C208C20CC206C200C20AC213907F98740BF075450390C0007403F07F0CE4FD1212097F108F43121101907F98740AF07F018F41EF440690C000F0907F98740CF00E -:400C860075478090C0007480F00FE4FD121209E4FF7EA3AD068D3F121209907F987409F090C000E4F07F057D7F1212097F011212997F037D071212097F137D01121209D28D -:400CC6001222907F987410F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00568 -:400D060086F0A30586DFF70586D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF577 -:400D460083C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F00A -:400D8600907FAEE0FFD39210E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A56 -:400DC600121253C211E4F50BF513C217C212907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D38A -:400E0600C21812139F80CC22787FE4F6D8FD758147020E55020D7DE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F4568031 -:400E46000146F6DFE4800B01020408102040809012BAE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C828 -:400E8600CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92548 -:400EC60082F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F87401DE -:400F060093F5828883E4737402936860EFA3A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EB3B4031DAF190519EFB5180122120E9A7E0029FFEEB6 -:400F46003AA907751AFFF51B891C80D47B007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508607B -:400F86000A1213338F1AEF423680CA228F1A050DE50DAE0C7002050C14F5828E83E51AF012134B050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213878F1AEFF8 -:400FC600423780CA22C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D21123 -:401006005391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F9833 -:401046007413F090C00074BFF0907F987410F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0C0 -:40108600E544547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414B3 -:4010C600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BCC -:40110600F090C00074BFF0907F98740AF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E54582 -:40114600547F90C000F022907F98740BF090C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C3 -:40118600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E5CC -:4011C60044547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF02212131B8F1A12131B8F1BE51A651B601212131B8F1AE51A651B600712131B8F1B80E8ED -:40120600AF1A22907F98740BF0E545547F90C000F0907F98740FF090C000EFF0907F98740DF090C000EDF02212136F8F1A12136F8F1BE51A651B601212136F8F1AE51A65AD -:401246001B600712136F8F1B80E8AF1A22907FD6E054FBF0E04408F0301A04E04402F07FF47E011212D6907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211BF907F2F -:40128600987411F090C000EEF0E4E53E4480FD1211BF22AE07E4FFE53F547FFD121209907F987409F090C000EEF0E4E53F4480FD12120922050E02000000000314030000DF -:4012C600C111C118C195C110C116010A00C19B008E188F19E5191519AE18700215184E6005120D5C80EE22907F987411F090C000E0FF2253D8EF32000000020FF500021367 -:401306000400020FCB0002101C907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F0902A -:40134600C000E0FF22907F987408F090C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FFCA -:4013860022907F98740DF090C000E0FF22907F98740EF090C000E0FF22120003120D6D120B462200000000000000000000000000000000000000000000000000000000000C -:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 -:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 -:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 -:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 -:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 -:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 -:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 -:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 -:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 -:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 -:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 -:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 -:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 -:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 -:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 -:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 -:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 -:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 -:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 -:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF -:401906000040CD06150100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400071 -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:041A0600720000006A -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28xb.HEX b/firmware/keyspan/usa28xb.HEX deleted file mode 100644 index 07cb708f1956ab4f24594f265ea1a38487111136..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa28xb.HEX +++ /dev/null @@ -1,142 +0,0 @@ -:0300330002002D9B -:04002D0053D8EF3283 -:10004600300918121333EFC3953C40030200D890D1 -:100056007FBF7401F0C209C200807730033B907FF6 -:10006600C6E020E16D121333EFC394405064907ED6 -:1000760040E0139209907FC7E014F5192000116043 -:100086000FF5087E7E7F41750C7E750D41120CCCF6 -:10009600C203E4907FC7F08039907FC8E020E13248 -:1000A600121333EFC394405029907DC0E013920998 -:1000B600907FC9E014F519200011600FF5087E7DC8 -:1000C6007FC1750C7D750DC1120CCCD203E4907FF7 -:1000D600C9F0907FB6E030E1030201601211F58F9E -:1000E6001912133F8F36E519C3953A500F12131B99 -:1000F600EF30E008E53620E703300B5EC20BE5196A -:0C003600907F987410F090C000E0FF2252 -:03004300021300A5 -:10000300C0E0C083C082C085C084C086758600906E -:100013007FC4E4F05391EF907FAB7404F0D086D0AB -:0A00230084D085D082D083D0E03273 -:03000000020E12DB -:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F5DE51925E0907FB7F08027E519D3943F400375193F851908C2 -:40014600907E80E536F07E7E7F81750C7E750D81120CF1E51904907FB7F0907FCEE030E1062005030203C1E4F51874402518F582E4347CF583E0FFE5187C007B017A7E79AF -:40018600002400F9EC347EFAEF120EE40518E518B420D7907E00E06068907E03E060247F01E4FD1211D07F037DCD1211D0434680907F987414F090C000E546F0E4907E13F6 -:4001C600F08030907E01E0FF121054907E02E0FF12107A7F01907E11E0FD1211D07F037D071211D0434680907F987414F090C000E546F0907F987412F0E540440690C00093 -:40020600F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E06005434280800353427F53C8 -:4002460042FC907E09E06011434202A3E0FF1210C6907E0BE0FF1210ECAF421210A0907E03E0600853427FAF421210A0907E0CE06018A3E0600543460280035346FD907FFB -:40028600987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E06005434610800317 -:4002C6005346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F012130FEF54FE90C000F0533EFDE4FFAD3E1211D080 -:40030600E4F52AF529D207907E17E0600F433E02E4FFAD3E1211D0752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F9874130E -:40034600F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211D0752B01D207907E1BE0600F433E01E4FFAD3E1211D0E4F52BD207907E1CE0600E907F987412F0E5F8 -:4003860040440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203C205E4907FCFF0301A54E5389E -:4003C6006002153820134BE513D3940040041513804075130A301B02D21312130FEF5401F519652A600585192AD20712134BEF54806480F51965266005851926D207300D71 -:400406001112134BEF5410F51965256005851925D207201B030207F0300A18121387EFC3953D40030204B0907FC17401F0C20AC200807730043B907FCAE020E16D1213879B -:40044600EFC394405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D16C204E4907FCBF08039907FCCE020E132121387EFC394405099 -:4004860029907CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D16D204E4907FCDF0907FBAE030E10302053812123F8F191213938F37E5197F -:4004C600C3953B500F12136FEF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120FFC -:4005060096E51925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D3BE51904907FBBF0907FD0E030E106200603020799E431 -:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120EE40518E518B420D7907E20E06068907E23E060247F01E4FD12121A7F03F7 -:400586007DCD12121A434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121138907E22E0FF12115E7F01907E31E0FD12121A7F037D0712121A43478090AA -:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB -:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121184907E2BE0FF1211AAAF43121112907E23E0600853437FAFA0 -:4006460043121112907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0B4 -:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 -:4006C600987409F0121363EF54FE90C000F0533FFDE4FFAD3F12121AE4F533F532D208907E37E0600F433F02E4FFAD3F12121A753201D208907E38E06010907F98740AF0EB -:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F12121A753401D208907E3BE0600F433F01E4C9 -:40074600FFAD3F12121AE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741369 -:40078600F07433F07416F07436F0D204C206E4907FD1F0301A54E5396002153930134BE513D3940040041513804075130A301B02C213121363EF5401F51965336005851998 -:4007C60033D20812139FEF54806480F519652F600585192FD208300E1112139FEF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B4297 -:40080600E0F516907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020924E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E9E44 -:40084600FF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EEBF -:400886003400FA120E9EFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E25184C -:4008C600F9EE3400FA120E9EFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E9ECB -:40090600FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EF60A0C000A80010AEC0309480609FF0809F90909E10A09F00B000044 -:400946000B3B907FEBE024FE6019146061240260030209D77419907FD4F07400907FD5F0020B42907FEAE070047F0280027F03758282758319EFF075827B758319F07582DA -:4009860074758319F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B42907FEAE0FF120F1CEA49600DEA907FD4F0E9BE -:4009C600907FD5F0020B42907FB4E04401F0020B42907FB4E04401F0020B42907F00E509F0907FB57401F0020B42907FEAE0F509020B42120B4A020B42907F007401F0903B -:400A06007FB5F0020B42907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B42E4907F00F0A3F0907FB57402F0022E -:400A46000B42907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B42907FB4E04401F0020B42907FE8E024FE4E -:400A8600601D24026003020B42907FEAE0B40105C210020B42907FB4E04401F0020B42907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583EA -:400AC600E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB47B -:400B0600E04401F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E017 -:400B46004402F022E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F945 -:400B8600E43400FAE4120EE40518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211D07F108F42125F -:400BC60010A0907F987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211D0E4FF7EA3AD068D3E1211D0907F987411F090C000E4F07F05B0 -:400C06007D7F1211D07F011212897F037D071211D07F137D091211D0201B03020CC9752D017518017B00742D2518F9E43400FAE4120EE40518E518B409EA753B01E4F53978 -:400C4600F513F537C208C20CC206C200C20AC213907F98740BF075450390C0007403F07F0CE4FD12121A7F108F43121112907F98740AF07F018F41EF440690C000F0907FC0 -:400C860098740CF075478090C0007480F00FE4FD12121AE4FF7EA3AD068D3F12121A907F987409F090C000E4F07F057D7F12121A7F011212AA7F037D0712121A7F137D0927 -:400CC60012121AD21222907F987410F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690FD -:400D0600C000E00586F0A30586DFF70586D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF53A -:400D460082E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92B8 -:400D8600E04402F0907FAEE0FFD39210E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0AD -:400DC600D2AFD21A121264C211E4F50BF513C217C212907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092580F9 -:400E0600D63018D3C2181213AB80CC22787FE4F6D8FD758147020E59020D81E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C88340FA -:400E460004F456800146F6DFE4800B01020408102040809012CBE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A320 -:400E8600C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E022D5 -:400EC6005006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A37A -:400F060093F8740193F5828883E4737402936860EFA3A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EB7B4031DAF190519EFB5180122120E9E7EC4 -:400F46000029FFEE3AA907751AFFF51B891C80D47B007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF015BA -:400F860008E508600A12133F8F1AEF423680CA228F1A050DE50DAE0C7002050C14F5828E83E51AF0121357050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213AA -:400FC600938F1AEF423780CA22E4907F93F0907F9C7430F0E4907F96F0907F95F0907F9E7427F0907F987420F0907F9E7407F0E4907F94F0907F9D74FFF0E4907F97F0227C -:40100600C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB74087E -:40104600F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF00C -:40108600907F987411F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F0220A -:4010C600907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F9807 -:401106007413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907FFA -:40114600987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F71 -:4011860098740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BFD -:4011C600F0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF0221213278F1A1213278F1BE51A651B60121292 -:4012060013278F1AE51A651B60071213278F1B80E8AF1A22907F98740BF0E545547F90C000F0907F98740FF090C000EFF0907F98740DF090C000EDF02212137B8F1A121325 -:401246007B8F1BE51A651B601212137B8F1AE51A651B600712137B8F1B80E8AF1A22907FD6E054FBF0E04408F0301A04E04402F07FF47E011212E7907FD6E054F7F0E044E1 -:4012860004F022AE07E4FFE53E547FFD1211D0907F987411F090C000EEF0E4E53E4480FD1211D022AE07E4FFE53F547FFD12121A907F987409F090C000EEF0E4E53F448095 -:4012C600FD12121A22050E02000000000314030000C111C118C195C110C116010A00C19B008E188F19E5191519AE18700215184E6005120D6080EE2200000210060002137E -:4013060004000200030002102D907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090F5 -:40134600C000E0FF22907F987416F090C000E0FF22907F987408F090C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FFC0 -:4013860022907F98740CF090C000E0FF22907F98740DF090C000E0FF22907F98740EF090C000E0FF22120FCF120D71120B4A220000000000000000000000000000000000C1 -:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 -:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 -:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 -:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 -:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 -:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 -:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 -:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 -:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 -:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 -:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 -:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 -:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 -:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 -:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 -:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 -:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 -:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 -:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 -:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 -:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF -:401906000040CD06100100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400076 -:4019460000070506024000000705070240000007058102400001070582024000000705830240000107058402400001070585024000010705860240000107058702400001F4 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 -:041A0600720000006A -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa49w.HEX b/firmware/keyspan/usa49w.HEX deleted file mode 100644 index 5e5b3d13dd5f9936bc6bb2fd4b405c97bc075291..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa49w.HEX +++ /dev/null @@ -1,145 +0,0 @@ -:030033000218FBB5 -:0C0036009078417401F090C000E0FF22BF -:10004600E4FF74402FF582E4347BF583E0FEE5158A -:100056002404FDE43514FAA9057B01EF7C0029F997 -:10006600EC3AFAEE1211F10FBF22D7E5152405F589 -:1000760082E43514F583E07003020134E5152409A2 -:10008600F582E43514F583E0700EE515240AF58251 -:10009600E43514F583E060187F01E4FD121647E5A8 -:1000A600152431F582E43514F583E054CFF0804110 -:1000B600E5152406F582E43514F583E0FF1216767D -:1000C600E5152407F582E43514F583E0FF120003F5 -:1000D6007F01E5152408F582E43514F583E0FD1269 -:1000E6001647E5152431F582E43514F583E04430EE -:1000F600F0E5152439F582E43514F583E04480F003 -:100003009078417403F090C00074BFF0907841740D -:1000130001F090C000EFF09078417403F0E51524EF -:1000230037F582E43514F583E0547F90C000F02265 -:03004300021B009D -:0300000002109556 -:400106009078417404F0E5152439F582E43514F583E090C000F09078417402F0E5152436F582E43514F583E0440690C000F0E515240BF582E43514F583E06032E515240C0B -:40014600F582E43514F583E0543FFFE5152437F582E43514F583EFF09078417403F0E5152437F582E43514F583E090C000F0E515240DF582E43514F583E0700302024FE588 -:40018600152417F582E43514F583E06011E5152432F582E43514F583E04404F0800FE5152432F582E43514F583E054FBF0E4FFE5152432F582E43514F583E0FD121647E55E -:4001C60015240EF582E43514F583E06011E5152433F582E43514F583E04480F0800FE5152433F582E43514F583E0547FF0E5152433F582E43514F583E054FCF0E515240FEB -:40020600F582E43514F583E0602FE5152433F582E43514F583E04402F0E5152410F582E43514F583E0FF1215E7E5152411F582E43514F583E0FF121617E5152433F582E45E -:400246003514F583E0FF1215B7E5152414F582E43514F583E06044E5152415F582E43514F583E06011E5152439F582E43514F583E04401F0800FE5152439F582E43514F581 -:4002860083E054FEF09078417404F0E5152439F582E43514F583E090C000F0E5152412F582E43514F583E06044E5152413F582E43514F583E06011E5152439F582E43514E6 -:4002C600F583E04402F0800FE5152439F582E43514F583E054FDF09078417404F0E5152439F582E43514F583E090C000F0E5152416F582E43514F583E0FFE5152435F5820A -:40030600E43514F583EFF0E5152417F582E43514F583E030E011E5152431F582E43514F583E04440F0800FE5152431F582E43514F583E054BFF0E5152418F582E43514F576 -:4003460083E0FFE515243BF582E43514F583EFF0E5152419F582E43514F583E06011E5152439F582E43514F583E04410F0800FE5152439F582E43514F583E054EFF0907869 -:40038600417404F0E5152439F582E43514F583E090C000F0E515241AF582E43514F583E0606BE5152437F582E43514F583E054BFF09078417403F0E5152437F582E43514FF -:4003C600F583E0547F90C000F09078417401F0120036EF54FE90C000F0E5152432F582E43514F583E054FDFFF0FDE4FF121647E515242CF582E43514F583E4F0E515242BB7 -:40040600F582E43514F583E4F0E5164213E515241BF582E43514F583E0700EE5152425F582E43514F583E06028E5152432F582E43514F583E04402FFF0FDE4FF121647E547 -:4004460015242BF582E43514F5837401F0E5164213E515241CF582E43514F583E0FF700EE5152425F582E43514F583E0602A9078417402F0E5152436F582E43514F583E0C6 -:40048600440490C000F0EF600FE5152431F582E43514F583E04404F0E515241DF582E43514F583E06027E5152437F582E43514F583E04440F09078417403F0E5152437F550 -:4004C60082E43514F583E0547F90C000F0E515241EF582E43514F583E06028E5152432F582E43514F583E054FEFFF0FDE4FF121647E515242DF582E43514F5837401F0E58F -:40050600164213E515241FF582E43514F583E0700EE5152425F582E43514F583E06027E5152432F582E43514F583E04401FFF0FDE4FF121647E515242DF582E43514F58397 -:40054600E4F0E5164213E5152420F582E43514F583E0700EE5152425F582E43514F583E060189078417402F0E5152436F582E43514F583E0440290C000F0E5152421F582A7 -:40058600E43514F583E0600FE5152431F582E43514F583E04402F0E5152422F582E43514F583E0601FE515242EF582E43514F5837401F0E515243AF582E43514F583E4F0F0 -:4005C600E5164213E5152423F582E43514F583E06003121885E5152424F582E43514F583E0601BE5152431F582E43514F583E04408F0907F98E0FFE516F4FEEF5EF0E5156C -:400606002425F582E43514F583E06016E5152431F582E43514F583E054F7F0907F98E04516F022907FE9E012120307830007F701086303064C0607740807680907500A07CE -:400646005F0B000008B2907FEBE024FE601C1470030206FE240260030207467419907FD4F07400907FD5F00208B9907FEAE004758217758319F0907FEAE030E0047F03802D -:40068600027F02758282758319EFF075826D758319F0758266758319F075825F758319F0758258758319F0907FEAE030E1047F6480027F3275821A758319EFF0907FEFE0FB -:4006C600FE907FEEE07C002400F519EC3EF518753319753412758214758319E0752700F528D3E5289519E527951840068518278519281213120208B9907FEAE0FF12142BC9 -:40070600EA496032907FEEE0751800F519AE02AF018E338F348F828E83E0FEA3E08E27F528D39519E527951840068518278519281213120208B9907FB4E04401F00208B99E -:40074600907FB4E04401F00208B9907F00E525F0907FB57401F00208B9907FEAE0F5250208B9907FEAE0F522120AB80208B9907F00E522F0907FB57401F00208B9907FE8BD -:40078600E0247F60241460312402705BA200E433FF25E0FFA206E4334F907F00F0E4A3F0907FB57402F00208B9E4907F00F0A3F0907FB57402F00208B9907FECE0F4548063 -:4007C600FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00208B9907FB4E04401F00208B9907FE8E024FE601D240260030208B910 -:40080600907FEAE0B40105C2000208B9907FB4E04401F00208B9907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF67 -:40084600131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D200803F907FB4E04401F08036907FEACB -:40088600E07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022E511540F703D -:4008C600030209B21216A5EF20E175121703EF14F5191218CCEF2519FFE433FEC3EF9480EE648094805059851582851483E0FEA3E0FFF5828E83E030E011E5152431F58250 -:40090600E43514F583E04480F0800FE5152431F582E43514F583E0547FF0E5152431F582E43514F583E020E212E519600EF523EF2401F52DE43EF52C1214ADE4FF1214E3C0 -:40094600E5152431F582E43514F583E030E75D1218CCE515243BF582E43514F583E0FEEFC39E5048E515242FF582E43514F5837401F0E5152431F582E43514F583E0547B99 -:40098600F0E515243AF582E43514F583E4F0E5164213907FC2E030E110E5152426F582E43514F583E0F52480031212A11216D4EF30E103020AB71217D28F191218D8E515D5 -:4009C6002438F582E43514F583EFF0E5152435F582E43514F583E0FFE519C39F50281218B4EF30E021E5152438F582E43514F583E020E712E5152431F582E43514F583E0C0 -:400A060020E103020AB7E5152431F582E43514F583E054FDF0E5197003020AB7B4800FE5152438F582E43514F583E04402F0E5152438F582E43514F583E0FF30E729E519CF -:400A4600D394204003751920851923851582851483A3A3E0FCA3E08C2CF52D1213DDE51925E0FF12151922E519D3943F400375193F851923E5152438F582E43514F583E053 -:400A8600FF851582851483A3A3E0FCA3E0F5828C83EFF0851582851483A3A3E0FEA3E02401F52DE43EF52C12146CE51904FF12151922E4907F93F0907F9C74F0F0907F9677 -:400AC600F0E4907F94F090784A04F0F58E907F9574C0F0907F9E743FF0907F98741FF090784374FFF0E4907841F0907FDF749FF0907FDEF0907F92E04402F07E7B7FC07581 -:400B0600147B7515C0907F9674EFF0751601120F127E7B7FC075147B7515C0907F9674EFF0751601E5152426F582E43514F583E4F07E7E7F40851582851483747EF0A374F5 -:400B460040F07E7E7F80851582851483A3A3747EF0A37480F07E7C7F0075147C751500907F9674DFF0751602120F127E7C7F0075147C751500907F9674DFF0751602E51536 -:400B86002426F582E43514F5837401F07E7D7FC0851582851483747DF0A374C0F07E7E7F00851582851483A3A3747EF0A37400F07E7C7F4075147C751540907F9674BFF018 -:400BC600751604120F127E7C7F4075147C751540907F9674BFF0751604E5152426F582E43514F5837402F07E7D7F40851582851483747DF0A37440F07E7D7F8085158285D3 -:400C06001483A3A3747DF0A37480F07E7C7F8075147C751580907F96747FF0751608120F127E7C7F8075147C751580907F96747FF0751608E5152426F582E43514F583741C -:400C460003F07E7C7FC0851582851483747CF0A374C0F07E7D7F00851582851483A3A3747DF0A37400F0C20AC209D20222E510045403F51014601F1460311460432403701B -:400C8600527E7B7FC075147B7515C0907F9674EFF0751601803D7E7C7F0075147C751500907F9674DFF075160280287E7C7F4075147C751540907F9674BFF075160480137E -:400CC6007E7C7F8075147C751580907F96747FF0751608E53255167003020E11E516F4FF5232E526547FFE700FE52A55166024907F98E04516F0801BBE2018E5152431F543 -:400D060082E43514F583E030E309E4F52A907F98E05FF0E515243AF582E43514F583E06003E014F0E5152434F582E43514F583E06003E014F0E06003020E11740AF012009D -:400D460036EF5401FFF519E515242CF582E43514F583E06F6007E519F0E51642131218E48F19E5152427F582E43514F583E0FFE5195410FE6F6006EEF0E5164213E5152415 -:400D860028F582E43514F583E0FFE5195480FE6F6006EEF0E5164213E5152429F582E43514F583E0FFE5195420FE6F6015EEF0E5152431F582E43514F583E030E404E51665 -:400DC6004213E5125516FFF519E515242AF582E43514F583E06F6016E519F0E5152431F582E43514F583E030E504E5164213E5175516FFF519E5152430F582E43514F58380 -:400E0600E06F6007E519F0E516421322300903020F11E52414602A14604114605814606F24046003020ECF7E7B7FC075147B7515C0907F9674EFF07516011212A17524015A -:400E4600227E7C7F0075147C751500907F9674DFF07516021212A1752402227E7C7F4075147C751540907F9674BFF07516041212A1752403227E7C7F8075147C7515809051 -:400E86007F96747FF07516081212A175240422300433C2045313DFE4F5197E007B00742E2519F9EE3400FA1211ABFF74802519F582E4347BF583EFF00519E519B403DB902D -:400EC6007FC37403F075240522E536603BD5360A5313EF300A04D209C20AE4F5197E007B0074352519F9EE3400FA1211ABFF74802519F582E4347BF583EFF00519E519B467 -:400F060003DB907FC37403F0E4F52422E4F51A7E007B01E515251AF9EE3514FAE41211F1051AE51AB43CE8E5152435F582E43514F5837401F09078417403F0E5152437F569 -:400F460082E43514F5837403F090C000F07F0CE4FD1216477F10E5152433F582E43514F583EFF01215B79078417402F07F01E5152436F582E43514F583EFF0440690C000F1 -:400F8600F09078417404F0E5152439F582E43514F5837480F090C000F00FE4FD121647E4FF7EA3E5152432F582E43514F583EEF0FD1216479078417401F090C000E4F07F89 -:400FC600057D7F1216477F0112154F7F037D071216472253133F907BF1E030E3167E7B7FC075147B7515C0907F9674EFF07516011208C1907C31E030E3167E7C7F00751417 -:401006007C751500907F9674DFF07516021208C1907C71E030E3167E7C7F4075147C751540907F9674BFF07516041208C1907CB1E030E3167E7C7F8075147C751580907F37 -:4010460096747FF07516081208C10511E511540FF518701F907841E054F7F0907F99E0F517907841E04408F0907F99E0F4F51212112122E518B40104120C7322907FC2E018 -:4010860020E108E5136004120E1222120C7322787FE4F6D8FD7581370210DC021229E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F44207E -:4010C600C8834004F456800146F6DFE4800B0102040810204080901850E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8A2 -:40110600E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BE907FD2E030E1030211AAC209907B40E014602614603B14605024836064248070637E7B7FC01C -:4011460075147B7515C0907F9674EFF0751601120046804B7E7C7F0075147C751500907F9674DFF075160212004680337E7C7F4075147C751540907F9674BFF075160412FB -:401186000046801B7E7C7F8075147C751580907F96747FF0751608120046800312175CE4907FD3F022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB0189 -:4011C6000CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D086 -:4012060082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF907FAEE0FFD39200E433FEEF4EF0D2E843D820907FDE7401F0907FDFF08E -:40124600907FAB74FFF0907FA9F0907FAAF05391EF907FAF7401F0907FAE740DF0D2AFD20B121814C201E4F52BF531C207C2027529F0907FD8E06526600675320FE0F526C9 -:40128600300203120FD9300107C20112062980E23008DFC20812183580D822E5135516606AE515243AF582E43514F583E0705CE516F45213E5152426FFE43514FEE4FD0FA2 -:4012C600EFAA0670010E14F5828A83E0FC74802DF582E4347BF583ECF00DBD0BE2907FC3740BF0E515243AF582E43514F5837410F0E515242EF582E43514F583E4F0E515C1 -:40130600242FF582E43514F583E4F022E52845276057AE27AF28D3EF9440EE940040047E007F40C3E5289FF528E5279EF527E4FDEDC39FE49E501F853482853383E0FC7494 -:40134600002DF582E4347FF583ECF00D0534E5347002053380DA907FA97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022E4907F93F0907F9C74F0A7 -:40138600F0907F96F0E490784AF0907F94F0907F9D74FFF0E4907F97F0300007E52954F0FF80027F00EF4408907841F0E4907F98F0907F95F0907F9E74FFF0E4907F98F0C9 -:4013C600907F93F0907F9C74F0F0E4907F96F0907F92E054FDF0228F1A052DE52DAE2C7002052C14F5828E83E51AF01218F0052DE52DAC2C7002052C14F5828C83EFF0159D -:4014060023E523601FE5152438F582E43514F583C083C082E0FE1218D88F1AEE4FD082D083F080B5228F1AE4F51B751CFF751D19751E86AB1CAA1DA91E9000011211C4B4E1 -:40144600031DAF1B051BEFB51A01221211AB7E0029FFEE3AA907751CFFF51D891E80D47B007A00790022E4907841F090784F74C0F0E4907850F0E52C907851F0AE2CE52DF8 -:40148600907852F0907854E523F09078577404F0907FE2E04410F0E054F7F0E4907855F0907855E060FA22E4907841F0E52C90784FF0AE2CE52D907850F090785174C0F081 -:4014C600E4907852F0907854E523F09078577404F0E4907855F0907855E060FA22E5152404F582E43514F583E014600F1460131460178000907FC7EFF08013907FC9EFF081 -:40150600800C907FCBEFF08005907FCDEFF0E516422A22E5152404F582E43514F583E014600F1460131460178000907FB7EFF08013907FB9EFF0800C907FBBEFF08005903B -:401546007FBDEFF0E516422A22AE07E4FFE5152432F582E43514F583E0547FFD1216479078417401F090C000EEF0E4E5152432F582E43514F583E04480FD12164722C0E0A0 -:40158600C0F0C083C082C085C084C086758600C0D075D0085391EF907FA97401F0121312D0D0D086D084D085D082D083D0F0D0E0329078417403F090C00074BFF0907841D0 -:4015C6007402F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F0229078417403F090C00074BFF09078417404F090C000EFF09078417403F0E5156D -:401606002437F582E43514F583E0547F90C000F0229078417403F090C00074BFF09078417406F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F0FF -:40164600229078417403F0E5152437F582E43514F583E0547F90C000F09078417407F090C000EFF09078417405F090C000EDF0229078417403F090C00074BFF0E4907841FA -:40168600F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F022E5152404F582E43514F583E014600E1460111460148000907FC6E0FF22907FC8E015 -:4016C600FF22907FCAE0FF22907FCCE0FF22E5152404F582E43514F583E014600E1460111460148000907FB6E0FF22907FB8E0FF22907FBAE0FF22907FBCE0FF22E515249E -:4017060004F582E43514F583E014600E1460111460148000907FC7E0FF22907FC9E0FF22907FCBE0FF22907FCDE0FF22C0E0C083C082C085C084C086758600907FC4E4F096 -:401746005391EF907FAB7404F0D086D084D085D082D083D0E032907B41E0F536431310A3E06009907FD77417F07437F0907B43E0F537A3E054F0F529E06002D20A22C0E024 -:40178600C083C082C085C084C086758600D2015391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2085391EF907FAB7408F0D0F7 -:4017C60086D084D085D082D083D0E0321218C0AE071218C0AD07EE6D60101218C0AE07EE6D60071218C0AD0780ECAF06227400F58690FDA57C05A3E582458370F922907FD5 -:40180600D6E04480F0438701000000000022907FD6E04404F0E04408F0300B04E04402F07FF47E0112186B907FD6E054F7F02212137C121804907FD6E030E70A7F057E007D -:4018460012186B12189E120AB8220335800000032E810000C185C181C108C100C106012200012400008E188F19E5191519AE18700215184E60081217F31217F380EB22E545 -:40188600152404F582E43514F583E004FF4410907FD7F0EF4430F022907FD6E04401F07F0D7E0012186B907FD6E054FEF0229078417402F090C000E0FF229078417403F0D5 -:4018C60090C000E0FF229078417404F090C000E0FF229078417405F090C000E0FF229078417406F090C000E0FF22E4907841F090C000E0FF2253D8EF320012011001FF00AB -:401906000040CD060A0100000102000409027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240007A -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E003603550053004200200034002D0070006F00720074002000530065007200690061006C00200041006400610070007400650072003C -:401A060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0 -:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060 -:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020 -:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002178400021B26 -:151B06000400021732000217AB00021B1000021B1400021584BE -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa49wlc.HEX b/firmware/keyspan/usa49wlc.HEX deleted file mode 100644 index 8406eb1bf37394ec76f52e9bb56391573e25f588..0000000000000000000000000000000000000000 --- a/firmware/keyspan/usa49wlc.HEX +++ /dev/null @@ -1,153 +0,0 @@ -:017F920001ED -:030033000218FBB5 -:0D003600E51104907841F090C000E0FF2239 -:10004600E4FF74402FF582E4347BF583E0FEE5158A -:100056002404FDE43514FAA9057B01EF7C0029F997 -:10006600EC3AFAEE1211EC0FBF22D7E5152405F58E -:1000760082E43514F583E07003020134E5152409A2 -:10008600F582E43514F583E0700EE515240AF58251 -:10009600E43514F583E060187F01E4FD12166BE584 -:1000A600152431F582E43514F583E054CFF0804110 -:1000B600E5152406F582E43514F583E0FF12000306 -:1000C600E5152407F582E43514F583E0FF1215AB38 -:1000D6007F01E5152408F582E43514F583E0FD1269 -:1000E600166BE5152431F582E43514F583E04430CA -:1000F600F0E5152439F582E43514F583E04480F003 -:1000030090784174F3F090C00074BFF0907841741D -:10001300F0F090C000EFF090784174F3F0E5152410 -:1000230037F582E43514F583E0547F90C000F02265 -:03004300021B009D -:030000000210905B -:4001060090784174F4F0E5152439F582E43514F583E090C000F090784174F2F0E5152436F582E43514F583E0440690C000F0E515240BF582E43514F583E06032E515240C2B -:40014600F582E43514F583E0543FFFE5152437F582E43514F583EFF090784174F3F0E5152437F582E43514F583E090C000F0E515240DF582E43514F583E0700302024FE598 -:40018600152417F582E43514F583E06011E5152432F582E43514F583E04404F0800FE5152432F582E43514F583E054FBF0E4FFE5152432F582E43514F583E0FD12166BE53A -:4001C60015240EF582E43514F583E06011E5152433F582E43514F583E04480F0800FE5152433F582E43514F583E0547FF0E5152433F582E43514F583E054FCF0E515240FEB -:40020600F582E43514F583E0602FE5152433F582E43514F583E04402F0E5152410F582E43514F583E0FF12160BE5152411F582E43514F583E0FF12163BE5152433F582E415 -:400246003514F583E0FF1215DBE5152414F582E43514F583E06044E5152415F582E43514F583E06011E5152439F582E43514F583E04401F0800FE5152439F582E43514F55D -:4002860083E054FEF090784174F4F0E5152439F582E43514F583E090C000F0E5152412F582E43514F583E06044E5152413F582E43514F583E06011E5152439F582E43514F6 -:4002C600F583E04402F0800FE5152439F582E43514F583E054FDF090784174F4F0E5152439F582E43514F583E090C000F0E5152416F582E43514F583E0FFE5152435F5821A -:40030600E43514F583EFF0E5152417F582E43514F583E030E011E5152431F582E43514F583E04440F0800FE5152431F582E43514F583E054BFF0E5152418F582E43514F576 -:4003460083E0FFE515243BF582E43514F583EFF0E5152419F582E43514F583E06011E5152439F582E43514F583E04410F0800FE5152439F582E43514F583E054EFF0907869 -:400386004174F4F0E5152439F582E43514F583E090C000F0E515241AF582E43514F583E0606BE5152437F582E43514F583E054BFF090784174F3F0E5152437F582E435141F -:4003C600F583E0547F90C000F090784174F1F0120036EF54FE90C000F0E5152432F582E43514F583E054FDFFF0FDE4FF12166BE515242CF582E43514F583E4F0E515242BA3 -:40040600F582E43514F583E4F0E5164213E515241BF582E43514F583E0700EE5152425F582E43514F583E06028E5152432F582E43514F583E04402FFF0FDE4FF12166BE523 -:4004460015242BF582E43514F5837401F0E5164213E515241CF582E43514F583E0FF700EE5152425F582E43514F583E0602A90784174F2F0E5152436F582E43514F583E0D6 -:40048600440490C000F0EF600FE5152431F582E43514F583E04404F0E515241DF582E43514F583E06027E5152437F582E43514F583E04440F090784174F3F0E5152437F560 -:4004C60082E43514F583E0547F90C000F0E515241EF582E43514F583E06028E5152432F582E43514F583E054FEFFF0FDE4FF12166BE515242DF582E43514F5837401F0E56B -:40050600164213E515241FF582E43514F583E0700EE5152425F582E43514F583E06027E5152432F582E43514F583E04401FFF0FDE4FF12166BE515242DF582E43514F58373 -:40054600E4F0E5164213E5152420F582E43514F583E0700EE5152425F582E43514F583E0601890784174F2F0E5152436F582E43514F583E0440290C000F0E5152421F582B7 -:40058600E43514F583E0600FE5152431F582E43514F583E04402F0E5152422F582E43514F583E0601FE515242EF582E43514F5837401F0E515243AF582E43514F583E4F0F0 -:4005C600E5164213E5152423F582E43514F583E0600312187AE5152424F582E43514F583E06023E5152431F582E43514F583E04408F0E516C454F0FF4211907F96E04FF000 -:40060600907841E04FF0E5152425F582E43514F583E06024E5152431F582E43514F583E054F7F0E516C454F0F4FF5211907F96E05FF0907841E05FF022907FE9E01211FE43 -:40064600079900080D01087903066206078A08077E0907660A07750B000008C8907FEBE024FE601C1470030207142402600302075C7419907FD4F07400907FD5F00208CF4C -:40068600907FEAE004758217758319F0907FEAE030E0047F0280027F03758282758319EFF075826D758319F0758266758319F075825F758319F0758258758319F0907FEA0A -:4006C600E030E1047F6480027F3275821A758319EFF0907FEFE0FE907FEEE07C002400F518EC3EF517753319753412758214758319E0752700F528D3E5289518E5279517D6 -:40070600400685172785182812130D0208CF907FEAE0FF12145FEA496032907FEEE0751700F518AE02AF018E338F348F828E83E0FEA3E08E27F528D39518E527951740068B -:4007460085172785182812130D0208CF907FB4E04401F00208CF907FB4E04401F00208CF907F00E525F0907FB57401F00208CF907FEAE0F5250208CF907FEAE0F522120A9B -:40078600CE0208CF907F00E522F0907FB57401F00208CF907FE8E0247F60241460312402705BA200E433FF25E0FFA206E4334F907F00F0E4A3F0907FB57402F00208CFE4C9 -:4007C600907F00F0A3F0907FB57402F00208CF907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00208CF907FB45C -:40080600E04401F00208CF907FE8E024FE601D240260030208CF907FEAE0B40105C2000208CF907FB4E04401F00208CF907FEAE07038907FECE0F45480FFC4540FFFE05490 -:40084600072F25E024B4F582E4347FF583E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A90CA -:400886007FEAE0B40104D200803F907FB4E04401F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F046 -:4008C6008007907FB4E04401F0907FB4E04402F022E512540F70030209C812169AEF20E1751216F8EF14F5181218C5EF2518FFE433FEC3EF9480EE64809480505985158201 -:40090600851483E0FEA3E0FFF5828E83E030E011E5152431F582E43514F583E04480F0800FE5152431F582E43514F583E0547FF0E5152431F582E43514F583E020E212E5CC -:4009460018600EF523EF2401F52DE43EF52C1214A0E4FF1214D7E5152431F582E43514F583E030E75D1218C5E515243BF582E43514F583E0FEEFC39E5048E515242FF58207 -:40098600E43514F5837401F0E5152431F582E43514F583E0547BF0E515243AF582E43514F583E4F0E5164213907FC2E030E110E5152426F582E43514F583E0F524800312C5 -:4009C600129C1216C9EF30E103020ACD1217C78F181218D3E5152438F582E43514F583EFF0E5152435F582E43514F583E0FFE518C39F50281218A9EF30E021E5152438F52E -:400A060082E43514F583E020E712E5152431F582E43514F583E020E103020ACDE5152431F582E43514F583E054FDF0E5187003020ACDB4800FE5152438F582E43514F583DE -:400A4600E04402F0E5152438F582E43514F583E0FF30E729E518D394204003751820851823851582851483A3A3E0FCA3E08C2CF52D1213CFE51825E0FF12150D22E518D3C3 -:400A8600943F400375183F851823E5152438F582E43514F583E0FF851582851483A3A3E0FCA3E0F5828C83EFF0851582851483A3A3E0FEA3E02401F52DE43EF52C12141D4F -:400AC600E51804FF12150D22E4907F93F0907F9C74FFF0E4907F96F0907F94F090784A04F0F58E907F9574C0F0907F9E743FF0907F98742FF090784374F7F0E4907841F02C -:400B0600907FDF749FF0907FDEF0907F92E04402F07E7B7FC075147B7515C0907F98742EF0751601120F287E7B7FC075147B7515C0907F98742EF0751601E5152426F58290 -:400B4600E43514F583E4F07E7E7F40851582851483747EF0A37440F07E7E7F80851582851483A3A3747EF0A37480F07E7C7F0075147C751500907F98742DF0751602120F0A -:400B8600287E7C7F0075147C751500907F98742DF0751602E5152426F582E43514F5837401F07E7D7FC0851582851483747DF0A374C0F07E7E7F00851582851483A3A374EE -:400BC6007EF0A37400F07E7C7F4075147C751540907F98742BF0751604120F287E7C7F4075147C751540907F98742BF0751604E5152426F582E43514F5837402F07E7D7F57 -:400C060040851582851483747DF0A37440F07E7D7F80851582851483A3A3747DF0A37480F07E7C7F8075147C751580907F987427F0751608120F287E7C7F8075147C751590 -:400C460080907F987427F0751608E5152426F582E43514F5837403F07E7C7FC0851582851483747CF0A374C0F07E7D7F00851582851483A3A3747DF0A37400F0C20AC209D3 -:400C8600E4F511D20222E510045403F51014601F146031146043240370527E7B7FC075147B7515C0907F98742EF0751601803D7E7C7F0075147C751500907F98742DF07564 -:400CC600160280287E7C7F4075147C751540907F98742BF075160480137E7C7F8075147C751580907F987427F0751608E53255167003020E27E516F45232E526547FFF7095 -:400D060017E52A55166034907F96E0FEE516C454F0F4FDEE5DF08023BF2020E5152431F582E43514F583E030E311E4F52A907F96E0FFE516C454F0FEEF4EF0E515243AF5C3 -:400D460082E43514F583E06003E014F0E5152434F582E43514F583E06003E014F0E06003020E27740AF0120036EF5401FFF518E515242CF582E43514F583E06F6007E518F1 -:400D8600F0E51642131218E18F18E5152427F582E43514F583E0FFE5185410FE6F6006EEF0E5164213E5152428F582E43514F583E0FFE5185480FE6F6006EEF0E516421386 -:400DC600E5152429F582E43514F583E0FFE5185420FE6F6015EEF0E5152431F582E43514F583E030E404E5164213E515242AF582E43514F583E0FFE5185440FE6F6015EE23 -:400E0600F0E5152431F582E43514F583E030E504E5164213E5152430F582E43514F583E4F022300903020F27E52414602A14604114605814606F24046003020EE57E7B7F31 -:400E4600C075147B7515C0907F98742EF075160112129C752401227E7C7F0075147C751500907F98742DF075160212129C752402227E7C7F4075147C751540907F98742B05 -:400E8600F075160412129C752403227E7C7F8075147C751580907F987427F075160812129C75240422300433C2045313DFE4F5187E007B00742E2518F9EE3400FA1211A6CA -:400EC600FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F075240522E536603BD5360A5313EF300A04D209C20AE4F5187E007B0074352518F9EE3400FACC -:400F06001211A6FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F0E4F52422E4F5197E007B01E5152519F9EE3514FAE41211EC0519E519B43CE8E51524FA -:400F460035F582E43514F5837401F090784174F3F0E5152437F582E43514F5837403F090C000F07F0CE4FD12166B7F10E5152433F582E43514F583EFF01215DB9078417464 -:400F8600F2F07F01E5152436F582E43514F583EFF0440690C000F090784174F4F0E5152439F582E43514F5837480F090C000F00FE4FD12166BE4FF7EA3E5152432F582E486 -:400FC6003514F583EEF0FD12166B90784174F1F090C000E4F07F057D7F12166B7F011215437F037D0712166B2253133F907BF1E030E3167E7B7FC075147B7515C0907F986B -:40100600742EF07516011208D7907C31E030E3167E7C7F0075147C751500907F98742DF07516021208D7907C71E030E3167E7C7F4075147C751540907F98742BF0751604C4 -:401046001208D7907CB1E030E3167E7C7F8075147C751580907F987427F07516081208D70512E512540FF517700412111C22E517B40104120C8C22907FC2E020E108E51370 -:401086006004120E2822120C8C22787FE4F6D8FD7581370210D7021224E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F4D7 -:4010C60056800146F6DFE4800B0102040810204080901845E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C589 -:4011060082C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BE907FD2E030E1030211A5C209907B40E014602614603B14605024836064248070637E7B7FC075147B75153A -:40114600C0907F98742EF0751601120046804B7E7C7F0075147C751500907F98742DF075160212004680337E7C7F4075147C751540907F98742BF0751604120046801B7E2B -:401186007C7F8075147C751580907F987427F07516081200468003121751E4907FD3F022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F5B8 -:4011C60082E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E49370B6 -:4012060012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF907FAEE0FFD39200E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFC2 -:40124600F0907FA9F0907FAAF05391EF907FAF7401F0907FAE740DF0D2AFD20B121809C201E4F52BF531C207C20275290F907FD8E06526600675320FE0F526300203120F8C -:40128600EF300107C20112063F80E23008DFC20812182A80D822E5135516606AE515243AF582E43514F583E0705CE516F45213E5152426FFE43514FEE4FD0FEFAA067001C7 -:4012C6000E14F5828A83E0FC74802DF582E4347BF583ECF00DBD0BE2907FC3740BF0E515243AF582E43514F5837410F0E515242EF582E43514F583E4F0E515242FF582E423 -:401306003514F583E4F022E52845276057AE27AF28D3EF9440EE940040047E007F40C3E5289FF528E5279EF527E4FDEDC39FE49E501F853482853383E0FC74002DF582E4BA -:40134600347FF583ECF00D0534E5347002053380DA907FA97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022907F98740FF0E490784AF0907F94F0E1 -:40138600907F9D74FFF0E4907F97F0907841F0907F93F0907F9C74FFF0300007E529540FFF80027F00907F96EFF0907F98741FF0E4907F95F0907F9E743FF0907F9874DFAD -:4013C600F0907F92E054FDF0228F19052DE52DAE2C7002052C14F5828E83E519F01218EF052DE52DAC2C7002052C14F5828C83EFF01523E523601FE5152438F582E4351416 -:40140600F583C083C082E0FE1218D38F19EE4FD082D083F080B522907841E511F090784F74C0F0E4907850F0E52C907851F0AE2CE52D907852F0907854E523F09078577470 -:4014460004F0907FE2E04410F0E054F7F0E4907855F0907855E060FA228F19E4F51A751BFF751C19751D86AB1BAA1CA91D9000011211BFB4031DAF1A051AEFB519012212F9 -:4014860011A67E0029FFEE3AA907751BFFF51C891D80D47B007A00790022907841E511F0E52C90784FF0AE2CE52D907850F090785174C0F0E4907852F0907854E523F0907D -:4014C60078577404F0E4907855F0907855E060FA22E5152404F582E43514F583E014600F1460131460178000907FC7EFF08013907FC9EFF0800C907FCBEFF08005907FCDED -:40150600EFF0E516422A22E5152404F582E43514F583E014600F1460131460178000907FB7EFF08013907FB9EFF0800C907FBBEFF08005907FBDEFF0E516422A22AE07E4A4 -:40154600FFE5152432F582E43514F583E0547FFD12166B90784174F1F090C000EEF0E4E5152432F582E43514F583E04480FD12166B22C0E0C0F0C083C082C085C084C086A1 -:40158600758600C0D075D0085391EF907FA97401F012130DD0D0D086D084D085D082D083D0F0D0E03290784174F3F090C00074BFF090784174F1F090C000EFF090784174A8 -:4015C600F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F090C00074BFF090784174F2F090C000EFF090784174F3F0E5152437F582E43514F583E0547FD7 -:4016060090C000F02290784174F3F090C00074BFF090784174F4F090C000EFF090784174F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F090C00074BF16 -:40164600F090784174F6F090C000EFF090784174F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F0E5152437F582E43514F583E0547F90C000F09078412F -:4016860074F7F090C000EFF090784174F5F090C000EDF022E5152404F582E43514F583E014600E1460111460148000907FC6E0FF22907FC8E0FF22907FCAE0FF22907FCC19 -:4016C600E0FF22E5152404F582E43514F583E014600E1460111460148000907FB6E0FF22907FB8E0FF22907FBAE0FF22907FBCE0FF22E5152404F582E43514F583E0146000 -:401706000E1460111460148000907FC7E0FF22907FC9E0FF22907FCBE0FF22907FCDE0FF22C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086BF -:40174600D084D085D082D083D0E032907B41E0F536431310A3E06009907FD77417F07437F0907B43E0F537A3E054F0F529E06002D20A22C0E0C083C082C085C084C08675A6 -:401786008600D2015391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2085391EF907FAB7408F0D086D084D085D082D083D0E03C -:4017C600321218B7AE071218B7AD07EE6D60101218B7AE07EE6D60071218B7AD0780ECAF06227400F58690FDA57C05A3E582458370F922907FD6E04480F043870100000048 -:40180600000022907FD6E04404F0E04408F0300B04E04402F07FF47E01121860907FD6E054F7F0221213771217F9907FD6E030E70A7F057E00121860121893120ACE220378 -:4018460035800000032E810000C185C181C108C100C106012200012400008E178F18E5181518AE17700215174E60081217E81217E880EB22E5152404F582E43514F583E07E -:4018860004FF4410907FD7F0EF4430F022907FD6E04401F07F0D7E00121860907FD6E054FEF022E5112402907841F090C000E0FF22E5112403907841F090C000E0FF22E597 -:4018C600112404907841F090C000E0FF22E5112405907841F090C000E0FF22E5112406907841F090C000E0FF22907841E511F090C000E0FF2253D8EF320012011001FFFFDE -:40190600FF40CD062A0100000102000409027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240005B -:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 -:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 -:4019C6007300200049006E0063002E0024034B00650079007300700061006E0020005500530041002D003400390057004C00430022035500530041002D00360035002000B5 -:401A060032003000300033006A0061006E0033003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E -:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060 -:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020 -:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002177900021B31 -:151B06000400021727000217A000021B1000021B1400021578E0 -:00000001FF - - The firmware contained herein is - - Copyright (C) 1999-2003 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -static char theFirmwareDate49[] = - "02/14/2002 02:37p 19,347 USA49"; - -static char theFirmwareDate65[] = - "01/31/2003 09:34a 19,331 USA65"; - diff --git a/firmware/keyspan_pda/keyspan_pda.HEX b/firmware/keyspan_pda/keyspan_pda.HEX deleted file mode 100644 index 6fcf02bb4b2dc7ae0a25bff13f27ceae9ef87675..0000000000000000000000000000000000000000 --- a/firmware/keyspan_pda/keyspan_pda.HEX +++ /dev/null @@ -1,83 +0,0 @@ -:03000000020200F9 -:0400230002055F0073 -:0400430002010000B6 -:050030000000000000CB -:10010000020296000200000002000000020000004F -:1001100002000000020000000200000002000000D7 -:1001200002000000020000000204610002048900D5 -:1002000075815EE4F532F533F530F531F534C20031 -:10021000C201A90074FE901000F0A3D9FC74FD90F7 -:100220001100F0A3D9FC7402907F9DF07400907FC0 -:1002300097F07486907F9EF0907F957403F0907F86 -:10024000AFE0D2E0F07401907FABF0907FAEF09021 -:100250007FAC7404F0907FAD7404F0907FC9F074AB -:1002600084907F98F07400F59875C8307B059120D4 -:10027000D2CA759850D2E8D2AFD2AC7400F586904D -:100280007FD67402F0792E7A007B00DBFEDAFAD991 -:10029000F67406F080FEC086C082C083C084C0852C -:1002A000C0E0E591C2E4F591907FAB7401F0907FDE -:1002B000E8E0F9A3E0FAA3E0FBA3E0FCE95460B4B2 -:1002C0000003020339B4406EBA000B12042040034D -:1002D00002040202040ABA010302040ABA02030277 -:1002E000040ABA0303020444BA041EBB000A907F46 -:1002F00095E04402F0020402907F98E054FDF090F3 -:100300007F95E054FDF0020402BA050302040ABA24 -:100310000619BB0008E533D395320203DEBB0108A2 -:10032000E532C395330203DE02040ABA07058B34B3 -:1003300002040202040A02040ABA0020B9801090E2 -:100340007F00E4F0A3F0907FB57402F0020402B9DC -:10035000820280EBB9810280E602040ABA010FBB77 -:10036000000302040ABB010302040202040ABA03E6 -:100370000FBB000302040ABB010302040202040AC9 -:10038000BA0656BC010F907FD47406F0907FD574E6 -:1003900012F0020402BC0212BB006F907FD47406FC -:1003A000F0907FD57424F0020402BC03297404C3C6 -:1003B0009B40576055EB2B9006442582F5827400D4 -:1003C0003583F583E0F9A3E0FA907FD4E9F0907FDC -:1003D000D5EAF002040202040ABA080F7401907F01 -:1003E00000F07401907FB5F0020402BA0903020420 -:1003F00002BA0A0574000203DEBA0B030204020209 -:10040000040A907FB47402F08009907FB4E0440144 -:10041000F08000D0E0D085D084D083D082D08632E6 -:10042000EB20E71EC3940A5019EB2324FEF58274D7 -:10043000053400F583E0F5CBF5CDA3E0F5CAF5CCA6 -:10044000C322D322B94111EB64FF5484FB907F98FF -:10045000E0547B4BF0020402907F9BE064FF0203B8 -:10046000DEC086C082C083C084C085C0E0E591C282 -:10047000E4F591907FA97404F01205A0D0E0D08536 -:10048000D084D083D082D08632C086C082C083C060 -:1004900084C085C0E0E591C2E4F591907FAA740420 -:1004A000F0907FC9E0F9E4F586907DC075851085F0 -:1004B0003284E005860584F0E584B53302800905C1 -:1004C000320586A3D9EC8000907FC9F0B131D0E02D -:1004D000D085D084D083D082D08632E4F586907FD8 -:1004E000BCE020E14B907D00E532F0A3E533F0A3C2 -:1004F000E530F0A3E531F0A3E430000104F0A305FA -:10050000869010007910E0A30586F0A30586D9F641 -:10051000058674FCF0A305869011007910E0A30510 -:1005200086F0A30586D9F6E4F586907FBD7426F0A3 -:1005300022200013E532B53301220533758310857F -:100540003382E0F599D2007400B5340122E533D34B -:100550009532C3953440F5753400D2010205A0C030 -:1005600086C082C083C084C085C0E0309907C2992C -:10057000C20012053430980512058AC298D0E0D026 -:1005800085D084D083D082D0863275831185308225 -:100590000582E599F0E582B53101220530B1A0224E -:1005A000907FB8E020E138200136E530B5310122F6 -:1005B000E4F5867583110586907E00F0A3058679A3 -:1005C00001E530B5310280100531853182E00586C4 -:1005D000F0A3058609B940E9907FB9E96001F022EE -:1005E000C201E4F586907E007401F0A37402F090DD -:1005F0007FB9F022C299F5993099FDC29922E55E42 -:10060000F63CFD8FFEC8FF64FFB2FFD9FFEDFFF39C -:10061000FFFA12010001FFFFFF40CD06040189AB84 -:1006200001020301090220000101008032090400D7 -:100630000002FFFFFF0007058203400001070502DB -:1006400002400000064C0650067206A0040300009B -:100650002203410043004D00450020007500730057 -:100660006200200077006900640067006500740084 -:1006700073002E03410043004D004500200055004B -:1006800053004200200073006500720069006100A1 -:100690006C0020007700690064006700650074004A -:0606A000060334003700E0 -:00000001FF diff --git a/firmware/keyspan_pda/keyspan_pda.S b/firmware/keyspan_pda/keyspan_pda.S deleted file mode 100644 index f3acc197a5efde4fcb9a161c3961f4aee4aaff22..0000000000000000000000000000000000000000 --- a/firmware/keyspan_pda/keyspan_pda.S +++ /dev/null @@ -1,1124 +0,0 @@ -/* $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $ - * - * Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on - * the EzUSB microcontroller. - * - * (C) Copyright 2000 Brian Warner - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the - * company. - * - * This serial adapter is basically an EzUSB chip and an RS-232 line driver - * in a little widget that has a DB-9 on one end and a USB plug on the other. - * It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2 - * as a baud-rate generator. The wiring is: - * PC0/RxD0 <- rxd (DB9 pin 2) PC4 <- dsr pin 6 - * PC1/TxD0 -> txd pin 3 PC5 <- ri pin 9 - * PC2 -> rts pin 7 PC6 <- dcd pin 1 - * PC3 <- cts pin 8 PC7 -> dtr pin 4 - * PB1 -> line driver standby - * - * The EzUSB register constants below come from their excellent documentation - * and sample code (which used to be available at www.anchorchips.com, but - * that has now been absorbed into Cypress' site and the CD-ROM contents - * don't appear to be available online anymore). If we get multiple - * EzUSB-based drivers into the kernel, it might be useful to pull them out - * into a separate .h file. - * - * THEORY OF OPERATION: - * - * There are two 256-byte ring buffers, one for tx, one for rx. - * - * EP2out is pure tx data. When it appears, the data is copied into the tx - * ring and serial transmission is started if it wasn't already running. The - * "tx buffer empty" interrupt may kick off another character if the ring - * still has data. If the host is tx-blocked because the ring filled up, - * it will request a "tx unthrottle" interrupt. If sending a serial character - * empties the ring below the desired threshold, we set a bit that will send - * up the tx unthrottle message as soon as the rx buffer becomes free. - * - * EP2in (interrupt) is used to send both rx chars and rx status messages - * (only "tx unthrottle" at this time) back up to the host. The first byte - * of the rx message indicates data (0) or status msg (1). Status messages - * are sent before any data. - * - * Incoming serial characters are put into the rx ring by the serial - * interrupt, and the EP2in buffer sent if it wasn't already in transit. - * When the EP2in buffer returns, the interrupt prompts us to send more - * rx chars (or status messages) if they are pending. - * - * Device control happens through "vendor specific" control messages on EP0. - * All messages are destined for the "Interface" (with the index always 0, - * so that if their two-port device might someday use similar firmware, we - * can use index=1 to refer to the second port). The messages defined are: - * - * bRequest = 0 : set baud/bits/parity - * 1 : unused - * 2 : reserved for setting HW flow control (CTSRTS) - * 3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc) - * 4 : set break (on/off) - * 5 : reserved for requesting interrupts on pin state change - * 6 : query buffer room or chars in tx buffer - * 7 : request tx unthrottle interrupt - * - * The host-side driver is set to recognize the device ID values stashed in - * serial EEPROM (0x06cd, 0x0103), program this firmware into place, then - * start it running. This firmware will use EzUSB's "renumeration" trick by - * simulating a bus disconnect, then reconnect with a different device ID - * (encoded in the desc_device descriptor below). The host driver then - * recognizes the new device ID and glues it to the real serial driver code. - * - * USEFUL DOCS: - * EzUSB Technical Reference Manual: - * 8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is - * basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports - * use totally different registers! - * USB 1.1 spec: www.usb.org - * - * HOW TO BUILD: - * gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s - * as31 -l keyspan_pda.asm - * mv keyspan_pda.obj keyspan_pda.hex - * perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h - * Get as31 from , and hack on it - * a bit to make it build. - * - * THANKS: - * Greg Kroah-Hartman, for coordinating the whole usb-serial thing. - * AnchorChips, for making such an incredibly useful little microcontroller. - * KeySpan, for making a handy, cheap ($40) widget that was so easy to take - * apart and trace with an ohmmeter. - * - * TODO: - * lots. grep for TODO. Interrupt safety needs stress-testing. Better flow - * control. Interrupting host upon change in DCD, etc, counting transitions. - * Need to find a safe device id to use (the one used by the Keyspan firmware - * under Windows would be ideal.. can anyone figure out what it is?). Parity. - * More baud rates. Oh, and the string-descriptor-length silicon bug - * workaround should be implemented, but I'm lazy, and the consequence is - * that the device name strings that show up in your kernel log will have - * lots of trailing binary garbage in them (appears as ????). Device strings - * should be made more accurate. - * - * Questions, bugs, patches to Brian. - * - * -Brian Warner - * - */ - -#define HIGH(x) (((x) & 0xff00) / 256) -#define LOW(x) ((x) & 0xff) - -#define dpl1 0x84 -#define dph1 0x85 -#define dps 0x86 - -;;; our bit assignments -#define TX_RUNNING 0 -#define DO_TX_UNTHROTTLE 1 - - ;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60 -#define STACK #0x60-1 - -#define EXIF 0x91 -#define EIE 0xe8 - .flag EUSB, EIE.0 - .flag ES0, IE.4 - -#define EP0CS #0x7fb4 -#define EP0STALLbit #0x01 -#define IN0BUF #0x7f00 -#define IN0BC #0x7fb5 -#define OUT0BUF #0x7ec0 -#define OUT0BC #0x7fc5 -#define IN2BUF #0x7e00 -#define IN2BC #0x7fb9 -#define IN2CS #0x7fb8 -#define OUT2BC #0x7fc9 -#define OUT2CS #0x7fc8 -#define OUT2BUF #0x7dc0 -#define IN4BUF #0x7d00 -#define IN4BC #0x7fbd -#define IN4CS #0x7fbc -#define OEB #0x7f9d -#define OUTB #0x7f97 -#define OEC #0x7f9e -#define OUTC #0x7f98 -#define PINSC #0x7f9b -#define PORTCCFG #0x7f95 -#define IN07IRQ #0x7fa9 -#define OUT07IRQ #0x7faa -#define IN07IEN #0x7fac -#define OUT07IEN #0x7fad -#define USBIRQ #0x7fab -#define USBIEN #0x7fae -#define USBBAV #0x7faf -#define USBCS #0x7fd6 -#define SUDPTRH #0x7fd4 -#define SUDPTRL #0x7fd5 -#define SETUPDAT #0x7fe8 - - ;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91) - - .org 0 - ljmp start - ;; interrupt vectors - .org 23H - ljmp serial_int - .byte 0 - - .org 43H - ljmp USB_Jump_Table - .byte 0 ; filled in by the USB core - -;;; local variables. These are not initialized properly: do it by hand. - .org 30H -rx_ring_in: .byte 0 -rx_ring_out: .byte 0 -tx_ring_in: .byte 0 -tx_ring_out: .byte 0 -tx_unthrottle_threshold: .byte 0 - - .org 0x100H ; wants to be on a page boundary -USB_Jump_Table: - ljmp ISR_Sudav ; Setup Data Available - .byte 0 - ljmp 0 ; Start of Frame - .byte 0 - ljmp 0 ; Setup Data Loading - .byte 0 - ljmp 0 ; Global Suspend - .byte 0 - ljmp 0 ; USB Reset - .byte 0 - ljmp 0 ; Reserved - .byte 0 - ljmp 0 ; End Point 0 In - .byte 0 - ljmp 0 ; End Point 0 Out - .byte 0 - ljmp 0 ; End Point 1 In - .byte 0 - ljmp 0 ; End Point 1 Out - .byte 0 - ljmp ISR_Ep2in - .byte 0 - ljmp ISR_Ep2out - .byte 0 - - - .org 0x200 - -start: mov SP,STACK-1 ; set stack - ;; clear local variables - clr a - mov tx_ring_in, a - mov tx_ring_out, a - mov rx_ring_in, a - mov rx_ring_out, a - mov tx_unthrottle_threshold, a - clr TX_RUNNING - clr DO_TX_UNTHROTTLE - - ;; clear fifo with "fe" - mov r1, 0 - mov a, #0xfe - mov dptr, #tx_ring -clear_tx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_tx_ring_loop - - mov a, #0xfd - mov dptr, #rx_ring -clear_rx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_rx_ring_loop - -;;; turn on the RS-232 driver chip (bring the STANDBY pin low) - ;; set OEB.1 - mov a, #02H - mov dptr,OEB - movx @dptr,a - ;; clear PB1 - mov a, #00H - mov dptr,OUTB - movx @dptr,a - ;; set OEC.[127] - mov a, #0x86 - mov dptr,OEC - movx @dptr,a - ;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port - mov dptr, PORTCCFG - mov a, #0x03 - movx @dptr, a - - ;; set up interrupts, autovectoring - mov dptr, USBBAV - movx a,@dptr - setb acc.0 ; AVEN bit to 0 - movx @dptr, a - - mov a,#0x01 ; enable SUDAV: setup data available (for ep0) - mov dptr, USBIRQ - movx @dptr, a ; clear SUDAVI - mov dptr, USBIEN - movx @dptr, a - - mov dptr, IN07IEN - mov a,#0x04 ; enable IN2 int - movx @dptr, a - - mov dptr, OUT07IEN - mov a,#0x04 ; enable OUT2 int - movx @dptr, a - mov dptr, OUT2BC - movx @dptr, a ; arm OUT2 - - mov a, #0x84 ; turn on RTS, DTR - mov dptr,OUTC - movx @dptr, a - ;; setup the serial port. 9600 8N1. - mov a,#01010011 ; mode 1, enable rx, clear int - mov SCON, a - ;; using timer2, in 16-bit baud-rate-generator mode - ;; (xtal 12MHz, internal fosc 24MHz) - ;; RCAP2H,RCAP2L = 65536 - fosc/(32*baud) - ;; 57600: 0xFFF2.F, say 0xFFF3 - ;; 9600: 0xFFB1.E, say 0xFFB2 - ;; 300: 0xF63C -#define BAUD 9600 -#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate)) -#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate)) -#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate)) - - mov T2CON, #030h ; rclk=1,tclk=1,cp=0,tr2=0(enable later) - mov r3, #5 - acall set_baud - setb TR2 - mov SCON, #050h - -#if 0 - mov r1, #0x40 - mov a, #0x41 -send: - mov SBUF, a - inc a - anl a, #0x3F - orl a, #0x40 -; xrl a, #0x02 -wait1: - jnb TI, wait1 - clr TI - djnz r1, send -;done: sjmp done - -#endif - - setb EUSB - setb EA - setb ES0 - ;acall dump_stat - - ;; hey, what say we RENUMERATE! (TRM p.62) - mov a, #0 - mov dps, a - mov dptr, USBCS - mov a, #0x02 ; DISCON=0, DISCOE=0, RENUM=1 - movx @dptr, a - ;; now presence pin is floating, simulating disconnect. wait 0.5s - mov r1, #46 -renum_wait1: - mov r2, #0 -renum_wait2: - mov r3, #0 -renum_wait3: - djnz r3, renum_wait3 - djnz r2, renum_wait2 - djnz r1, renum_wait1 ; wait about n*(256^2) 6MHz clocks - mov a, #0x06 ; DISCON=0, DISCOE=1, RENUM=1 - movx @dptr, a - ;; we are back online. the host device will now re-query us - - -main: sjmp main - - - -ISR_Sudav: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, USBIRQ ; clear USB int - mov a,#01h - movx @dptr,a - - ;; get request type - mov dptr, SETUPDAT - movx a, @dptr - mov r1, a ; r1 = bmRequestType - inc dptr - movx a, @dptr - mov r2, a ; r2 = bRequest - inc dptr - movx a, @dptr - mov r3, a ; r3 = wValueL - inc dptr - movx a, @dptr - mov r4, a ; r4 = wValueH - - ;; main switch on bmRequest.type: standard or vendor - mov a, r1 - anl a, #0x60 - cjne a, #0x00, setup_bmreq_type_not_standard - ;; standard request: now main switch is on bRequest - ljmp setup_bmreq_is_standard - -setup_bmreq_type_not_standard: - ;; a still has bmreq&0x60 - cjne a, #0x40, setup_bmreq_type_not_vendor - ;; Anchor reserves bRequest 0xa0-0xaf, we use small ones - ;; switch on bRequest. bmRequest will always be 0x41 or 0xc1 - cjne r2, #0x00, setup_ctrl_not_00 - ;; 00 is set baud, wValue[0] has baud rate index - lcall set_baud ; index in r3, carry set if error - jc setup_bmreq_type_not_standard__do_stall - ljmp setup_done_ack -setup_bmreq_type_not_standard__do_stall: - ljmp setup_stall -setup_ctrl_not_00: - cjne r2, #0x01, setup_ctrl_not_01 - ;; 01 is reserved for set bits (parity). TODO - ljmp setup_stall -setup_ctrl_not_01: - cjne r2, #0x02, setup_ctrl_not_02 - ;; 02 is set HW flow control. TODO - ljmp setup_stall -setup_ctrl_not_02: - cjne r2, #0x03, setup_ctrl_not_03 - ;; 03 is control pins (RTS, DTR). - ljmp control_pins ; will jump to setup_done_ack, - ; or setup_return_one_byte -setup_ctrl_not_03: - cjne r2, #0x04, setup_ctrl_not_04 - ;; 04 is send break (really "turn break on/off"). TODO - cjne r3, #0x00, setup_ctrl_do_break_on - ;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port - mov dptr, PORTCCFG - movx a, @dptr - orl a, #0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_do_break_on: - ;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low) - mov dptr, OUTC - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - mov dptr, PORTCCFG - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_not_04: - cjne r2, #0x05, setup_ctrl_not_05 - ;; 05 is set desired interrupt bitmap. TODO - ljmp setup_stall -setup_ctrl_not_05: - cjne r2, #0x06, setup_ctrl_not_06 - ;; 06 is query room - cjne r3, #0x00, setup_ctrl_06_not_00 - ;; 06, wValue[0]=0 is query write_room - mov a, tx_ring_out - setb c - subb a, tx_ring_in ; out-1-in = 255 - (in-out) - ljmp setup_return_one_byte -setup_ctrl_06_not_00: - cjne r3, #0x01, setup_ctrl_06_not_01 - ;; 06, wValue[0]=1 is query chars_in_buffer - mov a, tx_ring_in - clr c - subb a, tx_ring_out ; in-out - ljmp setup_return_one_byte -setup_ctrl_06_not_01: - ljmp setup_stall -setup_ctrl_not_06: - cjne r2, #0x07, setup_ctrl_not_07 - ;; 07 is request tx unthrottle interrupt - mov tx_unthrottle_threshold, r3; wValue[0] is threshold value - ljmp setup_done_ack -setup_ctrl_not_07: - ljmp setup_stall - -setup_bmreq_type_not_vendor: - ljmp setup_stall - - -setup_bmreq_is_standard: - cjne r2, #0x00, setup_breq_not_00 - ;; 00: Get_Status (sub-switch on bmRequestType: device, ep, int) - cjne r1, #0x80, setup_Get_Status_not_device - ;; Get_Status(device) - ;; are we self-powered? no. can we do remote wakeup? no - ;; so return two zero bytes. This is reusable -setup_return_two_zero_bytes: - mov dptr, IN0BUF - clr a - movx @dptr, a - inc dptr - movx @dptr, a - mov dptr, IN0BC - mov a, #2 - movx @dptr, a - ljmp setup_done_ack -setup_Get_Status_not_device: - cjne r1, #0x82, setup_Get_Status_not_endpoint - ;; Get_Status(endpoint) - ;; must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0 - ;; for now: cheat. TODO - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_endpoint: - cjne r1, #0x81, setup_Get_Status_not_interface - ;; Get_Status(interface): return two zeros - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_interface: - ljmp setup_stall - -setup_breq_not_00: - cjne r2, #0x01, setup_breq_not_01 - ;; 01: Clear_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Clear_Feature_not_stall - ;; Clear_Feature(stall). should clear a stall bit. TODO - ljmp setup_stall -setup_Clear_Feature_not_stall: - cjne r3, #0x01, setup_Clear_Feature_not_rwake - ;; Clear_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Clear_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_01: - cjne r2, #0x03, setup_breq_not_03 - ;; 03: Set_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Set_Feature_not_stall - ;; Set_Feature(stall). Should set a stall bit. TODO - ljmp setup_stall -setup_Set_Feature_not_stall: - cjne r3, #0x01, setup_Set_Feature_not_rwake - ;; Set_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Set_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_03: - cjne r2, #0x06, setup_breq_not_06 - ;; 06: Get_Descriptor (s-switch on wValueH: dev, config[n], string[n]) - cjne r4, #0x01, setup_Get_Descriptor_not_device - ;; Get_Descriptor(device) - mov dptr, SUDPTRH - mov a, #HIGH(desc_device) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_device) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_device: - cjne r4, #0x02, setup_Get_Descriptor_not_config - ;; Get_Descriptor(config[n]) - cjne r3, #0x00, setup_stall; only handle n==0 - ;; Get_Descriptor(config[0]) - mov dptr, SUDPTRH - mov a, #HIGH(desc_config1) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_config1) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_config: - cjne r4, #0x03, setup_Get_Descriptor_not_string - ;; Get_Descriptor(string[wValueL]) - ;; if (wValueL >= maxstrings) stall - mov a, #((desc_strings_end-desc_strings)/2) - clr c - subb a,r3 ; a=4, r3 = 0..3 . if a<=0 then stall - jc setup_stall - jz setup_stall - mov a, r3 - add a, r3 ; a = 2*wValueL - mov dptr, #desc_strings - add a, dpl - mov dpl, a - mov a, #0 - addc a, dph - mov dph, a ; dph = desc_strings[a]. big endian! (handy) - ;; it looks like my adapter uses a revision of the EZUSB that - ;; contains "rev D errata number 8", as hinted in the EzUSB example - ;; code. I cannot find an actual errata description on the Cypress - ;; web site, but from the example code it looks like this bug causes - ;; the length of string descriptors to be read incorrectly, possibly - ;; sending back more characters than the descriptor has. The workaround - ;; is to manually send out all of the data. The consequence of not - ;; using the workaround is that the strings gathered by the kernel - ;; driver are too long and are filled with trailing garbage (including - ;; leftover strings). Writing this out by hand is a nuisance, so for - ;; now I will just live with the bug. - movx a, @dptr - mov r1, a - inc dptr - movx a, @dptr - mov r2, a - mov dptr, SUDPTRH - mov a, r1 - movx @dptr, a - mov dptr, SUDPTRL - mov a, r2 - movx @dptr, a - ;; done - ljmp setup_done_ack - -setup_Get_Descriptor_not_string: - ljmp setup_stall - -setup_breq_not_06: - cjne r2, #0x08, setup_breq_not_08 - ;; Get_Configuration. always 1. return one byte. - ;; this is reusable - mov a, #1 -setup_return_one_byte: - mov dptr, IN0BUF - movx @dptr, a - mov a, #1 - mov dptr, IN0BC - movx @dptr, a - ljmp setup_done_ack -setup_breq_not_08: - cjne r2, #0x09, setup_breq_not_09 - ;; 09: Set_Configuration. ignored. - ljmp setup_done_ack -setup_breq_not_09: - cjne r2, #0x0a, setup_breq_not_0a - ;; 0a: Get_Interface. get the current altsetting for int[wIndexL] - ;; since we only have one interface, ignore wIndexL, return a 0 - mov a, #0 - ljmp setup_return_one_byte -setup_breq_not_0a: - cjne r2, #0x0b, setup_breq_not_0b - ;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored - ljmp setup_done_ack -setup_breq_not_0b: - ljmp setup_stall - - -setup_done_ack: - ;; now clear HSNAK - mov dptr, EP0CS - mov a, #0x02 - movx @dptr, a - sjmp setup_done -setup_stall: - ;; unhandled. STALL - ;EP0CS |= bmEPSTALL - mov dptr, EP0CS - movx a, @dptr - orl a, EP0STALLbit - movx @dptr, a - sjmp setup_done - -setup_done: - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -;;; ============================================================== - -set_baud: ; baud index in r3 - ;; verify a < 10 - mov a, r3 - jb ACC.7, set_baud__badbaud - clr c - subb a, #10 - jnc set_baud__badbaud - mov a, r3 - rl a ; a = index*2 - add a, #LOW(baud_table) - mov dpl, a - mov a, #HIGH(baud_table) - addc a, #0 - mov dph, a - ;; TODO: shut down xmit/receive - ;; TODO: wait for current xmit char to leave - ;; TODO: shut down timer to avoid partial-char glitch - movx a,@dptr ; BAUD_HIGH - mov RCAP2H, a - mov TH2, a - inc dptr - movx a,@dptr ; BAUD_LOW - mov RCAP2L, a - mov TL2, a - ;; TODO: restart xmit/receive - ;; TODO: reenable interrupts, resume tx if pending - clr c ; c=0: success - ret -set_baud__badbaud: - setb c ; c=1: failure - ret - -;;; ================================================== -control_pins: - cjne r1, #0x41, control_pins_in -control_pins_out: - mov a, r3 ; wValue[0] holds new bits: b7 is new DTR, b2 is new RTS - xrl a, #0xff ; 1 means active, 0V, +12V ? - anl a, #0x84 - mov r3, a - mov dptr, OUTC - movx a, @dptr ; only change bits 7 and 2 - anl a, #0x7b ; ~0x84 - orl a, r3 - movx @dptr, a ; other pins are inputs, bits ignored - ljmp setup_done_ack -control_pins_in: - mov dptr, PINSC - movx a, @dptr - xrl a, #0xff - ljmp setup_return_one_byte - -;;; ======================================== - -ISR_Ep2in: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, IN07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - ;; do stuff - lcall start_in - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -ISR_Ep2out: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, OUT07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - ;; do stuff - - ;; copy data into buffer. for now, assume we will have enough space - mov dptr, OUT2BC ; get byte count - movx a,@dptr - mov r1, a - clr a - mov dps, a - mov dptr, OUT2BUF ; load DPTR0 with source - mov dph1, #HIGH(tx_ring) ; load DPTR1 with target - mov dpl1, tx_ring_in -OUT_loop: - movx a,@dptr ; read - inc dps ; switch to DPTR1: target - inc dpl1 ; target = tx_ring_in+1 - movx @dptr,a ; store - mov a,dpl1 - cjne a, tx_ring_out, OUT_no_overflow - sjmp OUT_overflow -OUT_no_overflow: - inc tx_ring_in ; tx_ring_in++ - inc dps ; switch to DPTR0: source - inc dptr - djnz r1, OUT_loop - sjmp OUT_done -OUT_overflow: - ;; signal overflow - ;; fall through -OUT_done: - ;; ack - mov dptr,OUT2BC - movx @dptr,a - - ;; start tx - acall maybe_start_tx - ;acall dump_stat - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -dump_stat: - ;; fill in EP4in with a debugging message: - ;; tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out - ;; tx_active - ;; tx_ring[0..15] - ;; 0xfc - ;; rx_ring[0..15] - clr a - mov dps, a - - mov dptr, IN4CS - movx a, @dptr - jb acc.1, dump_stat__done; busy: cannot dump, old one still pending - mov dptr, IN4BUF - - mov a, tx_ring_in - movx @dptr, a - inc dptr - mov a, tx_ring_out - movx @dptr, a - inc dptr - - mov a, rx_ring_in - movx @dptr, a - inc dptr - mov a, rx_ring_out - movx @dptr, a - inc dptr - - clr a - jnb TX_RUNNING, dump_stat__no_tx_running - inc a -dump_stat__no_tx_running: - movx @dptr, a - inc dptr - ;; tx_ring[0..15] - inc dps - mov dptr, #tx_ring ; DPTR1: source - mov r1, #16 -dump_stat__tx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__tx_ring_loop - inc dps - - mov a, #0xfc - movx @dptr, a - inc dptr - - ;; rx_ring[0..15] - inc dps - mov dptr, #rx_ring ; DPTR1: source - mov r1, #16 -dump_stat__rx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__rx_ring_loop - - ;; now send it - clr a - mov dps, a - mov dptr, IN4BC - mov a, #38 - movx @dptr, a -dump_stat__done: - ret - -;;; ============================================================ - -maybe_start_tx: - ;; make sure the tx process is running. - jb TX_RUNNING, start_tx_done -start_tx: - ;; is there work to be done? - mov a, tx_ring_in - cjne a,tx_ring_out, start_tx__work - ret ; no work -start_tx__work: - ;; tx was not running. send the first character, setup the TI int - inc tx_ring_out ; [++tx_ring_out] - mov dph, #HIGH(tx_ring) - mov dpl, tx_ring_out - movx a, @dptr - mov sbuf, a - setb TX_RUNNING -start_tx_done: - ;; can we unthrottle the host tx process? - ;; step 1: do we care? - mov a, #0 - cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx - ;; nope -start_tx_really_done: - ret -start_tx__maybe_unthrottle_tx: - ;; step 2: is there now room? - mov a, tx_ring_out - setb c - subb a, tx_ring_in - ;; a is now write_room. If thresh >= a, we can unthrottle - clr c - subb a, tx_unthrottle_threshold - jc start_tx_really_done ; nope - ;; yes, we can unthrottle. remove the threshold and mark a request - mov tx_unthrottle_threshold, #0 - setb DO_TX_UNTHROTTLE - ;; prod rx, which will actually send the message when in2 becomes free - ljmp start_in - - -serial_int: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - jnb TI, serial_int__not_tx - ;; tx finished. send another character if we have one - clr TI ; clear int - clr TX_RUNNING - lcall start_tx -serial_int__not_tx: - jnb RI, serial_int__not_rx - lcall get_rx_char - clr RI ; clear int -serial_int__not_rx: - ;; return - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -get_rx_char: - mov dph, #HIGH(rx_ring) - mov dpl, rx_ring_in - inc dpl ; target = rx_ring_in+1 - mov a, sbuf - movx @dptr, a - ;; check for overflow before incrementing rx_ring_in - mov a, dpl - cjne a, rx_ring_out, get_rx_char__no_overflow - ;; signal overflow - ret -get_rx_char__no_overflow: - inc rx_ring_in - ;; kick off USB INpipe - acall start_in - ret - -start_in: - ;; check if the inpipe is already running. - mov dptr, IN2CS - movx a, @dptr - jb acc.1, start_in__done; int will handle it - jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle - ;; see if there is any work to do. a serial interrupt might occur - ;; during this sequence? - mov a, rx_ring_in - cjne a, rx_ring_out, start_in__have_work - ret ; nope -start_in__have_work: - ;; now copy as much data as possible into the pipe. 63 bytes max. - clr a - mov dps, a - mov dph, #HIGH(rx_ring) ; load DPTR0 with source - inc dps - mov dptr, IN2BUF ; load DPTR1 with target - movx @dptr, a ; in[0] signals that rest of IN is rx data - inc dptr - inc dps - ;; loop until we run out of data, or we have copied 64 bytes - mov r1, #1 ; INbuf size counter -start_in__loop: - mov a, rx_ring_in - cjne a, rx_ring_out, start_inlocal_irq_enablell_copying - sjmp start_in__kick -start_inlocal_irq_enablell_copying: - inc rx_ring_out - mov dpl, rx_ring_out - movx a, @dptr - inc dps - movx @dptr, a ; write into IN buffer - inc dptr - inc dps - inc r1 - cjne r1, #64, start_in__loop; loop -start_in__kick: - ;; either we ran out of data, or we copied 64 bytes. r1 has byte count - ;; kick off IN - mov dptr, IN2BC - mov a, r1 - jz start_in__done - movx @dptr, a - ;; done -start_in__done: - ;acall dump_stat - ret -start_in__do_tx_unthrottle: - ;; special sequence: send a tx unthrottle message - clr DO_TX_UNTHROTTLE - clr a - mov dps, a - mov dptr, IN2BUF - mov a, #1 - movx @dptr, a - inc dptr - mov a, #2 - movx @dptr, a - mov dptr, IN2BC - movx @dptr, a - ret - -putchar: - clr TI - mov SBUF, a -putchar_wait: - jnb TI, putchar_wait - clr TI - ret - - -baud_table: ; baud_high, then baud_low - ;; baud[0]: 110 - .byte BAUD_HIGH(110) - .byte BAUD_LOW(110) - ;; baud[1]: 300 - .byte BAUD_HIGH(300) - .byte BAUD_LOW(300) - ;; baud[2]: 1200 - .byte BAUD_HIGH(1200) - .byte BAUD_LOW(1200) - ;; baud[3]: 2400 - .byte BAUD_HIGH(2400) - .byte BAUD_LOW(2400) - ;; baud[4]: 4800 - .byte BAUD_HIGH(4800) - .byte BAUD_LOW(4800) - ;; baud[5]: 9600 - .byte BAUD_HIGH(9600) - .byte BAUD_LOW(9600) - ;; baud[6]: 19200 - .byte BAUD_HIGH(19200) - .byte BAUD_LOW(19200) - ;; baud[7]: 38400 - .byte BAUD_HIGH(38400) - .byte BAUD_LOW(38400) - ;; baud[8]: 57600 - .byte BAUD_HIGH(57600) - .byte BAUD_LOW(57600) - ;; baud[9]: 115200 - .byte BAUD_HIGH(115200) - .byte BAUD_LOW(115200) - -desc_device: - .byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40 - .byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01 -;;; The "real" device id, which must match the host driver, is that -;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104 - -desc_config1: - .byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32 - .byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00 - .byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01 - .byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 - -desc_strings: - .word string_langids, string_mfg, string_product, string_serial -desc_strings_end: - -string_langids: .byte string_langids_end-string_langids - .byte 3 - .word 0 -string_langids_end: - - ;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now - ;; *that* is a pain in the ass to encode. And they are little-endian - ;; too. Use this perl snippet to get the bytecodes: - /* while (<>) { - @c = split(//); - foreach $c (@c) { - printf("0x%02x, 0x00, ", ord($c)); - } - } - */ - -string_mfg: .byte string_mfg_end-string_mfg - .byte 3 -; .byte "ACME usb widgets" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00 -string_mfg_end: - -string_product: .byte string_product_end-string_product - .byte 3 -; .byte "ACME USB serial widget" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00 -string_product_end: - -string_serial: .byte string_serial_end-string_serial - .byte 3 -; .byte "47" - .byte 0x34, 0x00, 0x37, 0x00 -string_serial_end: - -;;; ring buffer memory - ;; tx_ring_in+1 is where the next input byte will go - ;; [tx_ring_out] has been sent - ;; if tx_ring_in == tx_ring_out, theres no work to do - ;; there are (tx_ring_in - tx_ring_out) chars to be written - ;; dont let _in lap _out - ;; cannot inc if tx_ring_in+1 == tx_ring_out - ;; write [tx_ring_in+1] then tx_ring_in++ - ;; if (tx_ring_in+1 == tx_ring_out), overflow - ;; else tx_ring_in++ - ;; read/send [tx_ring_out+1], then tx_ring_out++ - - ;; rx_ring_in works the same way - - .org 0x1000 -tx_ring: - .skip 0x100 ; 256 bytes -rx_ring: - .skip 0x100 ; 256 bytes - - - .END - diff --git a/firmware/keyspan_pda/xircom_pgs.HEX b/firmware/keyspan_pda/xircom_pgs.HEX deleted file mode 100644 index e9b00d70282fb4faa4a288ba9a2f238d2b532b20..0000000000000000000000000000000000000000 --- a/firmware/keyspan_pda/xircom_pgs.HEX +++ /dev/null @@ -1,87 +0,0 @@ -:03000000020200F9 -:0400230002059B0037 -:050030000000000000CB -:0400430002010000B6 -:100100000202BA000200000002000000020000002B -:1001100002000000020000000200000002000000D7 -:100120000200000002000000020485000204B90081 -:1002000075815EE4F532F533F530F531F534C20031 -:10021000C201A90074FE901000F0A3D9FC74FD90F7 -:100220001100F0A3D9FC907F9474BFF0907F957477 -:10023000EFF07410907F9EF07400907F98F07440FF -:10024000907F9DF07400907F97F07482907F9EF075 -:10025000907F957403F0907FAFE0D2E0F07401904E -:100260007FABF0907FAEF0907FAC7404F0907FADE8 -:100270007404F0907FC9F07407907FAFF074209001 -:100280007F9CF07480907F98F07453F59875C83017 -:100290007B059144D2CA759850D2E8D2AFD2AC74E3 -:1002A00000F586907FD67402F0792E7A007B00DB11 -:1002B000FEDAFAD9F67406F080FEC086C082C083EA -:1002C000C084C085C0E0E591C2E4F591907FAB7435 -:1002D00001F0907FE8E0F9A3E0FAA3E0FBA3E0FCE3 -:1002E000E95460B4000302035DB4406EBA000B121F -:1002F0000444400302042602042EBA010302042E21 -:10030000BA020302042EBA0303020468BA041EBB35 -:10031000000A907F95E04402F0020426907F98E066 -:1003200054FDF0907F95E054FDF0020426BA0503D9 -:1003300002042EBA0619BB0008E533D39532020435 -:1003400002BB0108E532C3953302040202042EBA4F -:1003500007058B3402042602042E02042EBA002064 -:10036000B98010907F00E4F0A3F0907FB57402F0A4 -:10037000020426B9820280EBB9810280E602042ED3 -:10038000BA010FBB000302042EBB010302042602C4 -:10039000042EBA030FBB000302042EBB01030204A8 -:1003A0002602042EBA0656BC010F907FD47406F0C4 -:1003B000907FD5745AF0020426BC0212BB006F90E5 -:1003C0007FD47406F0907FD5746CF0020426BC03D1 -:1003D000297404C39B40576055EB2B90068C2582F3 -:1003E000F58274003583F583E0F9A3E0FA907FD4B9 -:1003F000E9F0907FD5EAF002042602042EBA080F35 -:100400007401907F00F07401907FB5F0020426BA69 -:100410000903020426BA0A057400020402BA0B0397 -:1004200002042602042E907FB47402F08009907FAB -:10043000B4E04401F08000D0E0D085D084D083D0F7 -:1004400082D08632EB20E71EC3940A5019EB232496 -:1004500046F58274063400F583E0F5CBF5CDA3E0D4 -:10046000F5CAF5CCC322D322B94111EB64FF548005 -:10047000FB907F98E0547F4BF0020426907F9BE036 -:1004800064FF020402C086C082C083C084C085C0ED -:10049000E0E591C2E4F591907FA97404F074209096 -:1004A0007F9CF01205DC7420907F9CF0D0E0D0851A -:1004B000D084D083D082D08632C086C082C083C030 -:1004C00084C085C0E07410907F9CF0E591C2E4F593 -:1004D00091907FAA7404F0907FC9E0F9E4F58690CA -:1004E0007DC0758510853284E005860584F0E5843D -:1004F000B53302800905320586A3D9EC8000907FD0 -:10050000C9F0B16D7420907F9CF0D0E0D085D0848C -:10051000D083D082D08632E4F586907FBCE020E1A3 -:100520004B907D00E532F0A3E533F0A3E530F0A376 -:10053000E531F0A3E430000104F0A305869010003B -:100540007910E0A30586F0A30586D9F6058674FC2C -:10055000F0A305869011007910E0A30586F0A305AD -:1005600086D9F6E4F586907FBD7426F0222000132C -:10057000E532B53301220533758310853382E0F50A -:1005800099D2007400B5340122E533D39532C39576 -:100590003440F5753400D2010205DCC086C082C04B -:1005A00083C084C085C0E0309907C299C20012059B -:1005B000703098051205C6C298D0E0D085D084D09E -:1005C00083D082D086327583118530820582E59989 -:1005D000F0E582B53101220530B1DC227410907F44 -:1005E0009CF0907FB8E020E13E20013CE530B53141 -:1005F0000122E4F5867583110586907E00F0A3053F -:10060000867901E530B5310280100531853182E00F -:100610000586F0A3058609B940E97410907F9CF027 -:10062000907FB9E96001F022C201E4F586907E0076 -:100630007401F0A37402F0907FB9F022C299F59989 -:100640003099FDC29922E55EF63CFD8FFEC8FF643D -:10065000FFB2FFD9FFEDFFF3FFFA12010001FFFF28 -:10066000FF40CD06040189AB01020301090220000D -:1006700001010080320904000002FFFFFF000705AE -:10068000820340000107050202400000069406981C -:1006900006BA06E8040300002203410043004D00AF -:1006A000450020007500730062002000770069009B -:1006B000640067006500740073002E03410043006E -:1006C0004D004500200055005300420020007300FB -:1006D00065007200690061006C002000770069000D -:0E06E0006400670065007400060334003700F4 -:00000001FF diff --git a/firmware/keyspan_pda/xircom_pgs.S b/firmware/keyspan_pda/xircom_pgs.S deleted file mode 100644 index 0b79bbf0ae15adadc60821765580383df52e39de..0000000000000000000000000000000000000000 --- a/firmware/keyspan_pda/xircom_pgs.S +++ /dev/null @@ -1,1192 +0,0 @@ -/* $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $ - * - * Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on - * the EzUSB microcontroller. - * - * (C) Copyright 2000 Brian Warner - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the - * company. - * - * This serial adapter is basically an EzUSB chip and an RS-232 line driver - * in a little widget that has a DB-9 on one end and a USB plug on the other. - * It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2 - * as a baud-rate generator. The wiring is: - * PC0/RxD0 <- rxd (DB9 pin 2) PC4 <- dsr pin 6 - * PC1/TxD0 -> txd pin 3 PC5 <- ri pin 9 - * PC2 -> rts pin 7 PC6 <- dcd pin 1 - * PC3 <- cts pin 8 PC7 -> dtr pin 4 - * PB1 -> line driver standby - * - * The EzUSB register constants below come from their excellent documentation - * and sample code (which used to be available at www.anchorchips.com, but - * that has now been absorbed into Cypress' site and the CD-ROM contents - * don't appear to be available online anymore). If we get multiple - * EzUSB-based drivers into the kernel, it might be useful to pull them out - * into a separate .h file. - * - * THEORY OF OPERATION: - * - * There are two 256-byte ring buffers, one for tx, one for rx. - * - * EP2out is pure tx data. When it appears, the data is copied into the tx - * ring and serial transmission is started if it wasn't already running. The - * "tx buffer empty" interrupt may kick off another character if the ring - * still has data. If the host is tx-blocked because the ring filled up, - * it will request a "tx unthrottle" interrupt. If sending a serial character - * empties the ring below the desired threshold, we set a bit that will send - * up the tx unthrottle message as soon as the rx buffer becomes free. - * - * EP2in (interrupt) is used to send both rx chars and rx status messages - * (only "tx unthrottle" at this time) back up to the host. The first byte - * of the rx message indicates data (0) or status msg (1). Status messages - * are sent before any data. - * - * Incoming serial characters are put into the rx ring by the serial - * interrupt, and the EP2in buffer sent if it wasn't already in transit. - * When the EP2in buffer returns, the interrupt prompts us to send more - * rx chars (or status messages) if they are pending. - * - * Device control happens through "vendor specific" control messages on EP0. - * All messages are destined for the "Interface" (with the index always 0, - * so that if their two-port device might someday use similar firmware, we - * can use index=1 to refer to the second port). The messages defined are: - * - * bRequest = 0 : set baud/bits/parity - * 1 : unused - * 2 : reserved for setting HW flow control (CTSRTS) - * 3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc) - * 4 : set break (on/off) - * 5 : reserved for requesting interrupts on pin state change - * 6 : query buffer room or chars in tx buffer - * 7 : request tx unthrottle interrupt - * - * The host-side driver is set to recognize the device ID values stashed in - * serial EEPROM (0x06cd, 0x0103), program this firmware into place, then - * start it running. This firmware will use EzUSB's "renumeration" trick by - * simulating a bus disconnect, then reconnect with a different device ID - * (encoded in the desc_device descriptor below). The host driver then - * recognizes the new device ID and glues it to the real serial driver code. - * - * USEFUL DOCS: - * EzUSB Technical Reference Manual: - * 8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is - * basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports - * use totally different registers! - * USB 1.1 spec: www.usb.org - * - * HOW TO BUILD: - * gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s - * as31 -l keyspan_pda.asm - * mv keyspan_pda.obj keyspan_pda.hex - * perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h - * Get as31 from , and hack on it - * a bit to make it build. - * - * THANKS: - * Greg Kroah-Hartman, for coordinating the whole usb-serial thing. - * AnchorChips, for making such an incredibly useful little microcontroller. - * KeySpan, for making a handy, cheap ($40) widget that was so easy to take - * apart and trace with an ohmmeter. - * - * TODO: - * lots. grep for TODO. Interrupt safety needs stress-testing. Better flow - * control. Interrupting host upon change in DCD, etc, counting transitions. - * Need to find a safe device id to use (the one used by the Keyspan firmware - * under Windows would be ideal.. can anyone figure out what it is?). Parity. - * More baud rates. Oh, and the string-descriptor-length silicon bug - * workaround should be implemented, but I'm lazy, and the consequence is - * that the device name strings that show up in your kernel log will have - * lots of trailing binary garbage in them (appears as ????). Device strings - * should be made more accurate. - * - * Questions, bugs, patches to Brian. - * - * -Brian Warner - * - */ - -#define HIGH(x) (((x) & 0xff00) / 256) -#define LOW(x) ((x) & 0xff) - -#define dpl1 0x84 -#define dph1 0x85 -#define dps 0x86 - -;;; our bit assignments -#define TX_RUNNING 0 -#define DO_TX_UNTHROTTLE 1 - - ;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60 -#define STACK #0x60-1 - -#define EXIF 0x91 -#define EIE 0xe8 - .flag EUSB, EIE.0 - .flag ES0, IE.4 - -#define EP0CS #0x7fb4 -#define EP0STALLbit #0x01 -#define IN0BUF #0x7f00 -#define IN0BC #0x7fb5 -#define OUT0BUF #0x7ec0 -#define OUT0BC #0x7fc5 -#define IN2BUF #0x7e00 -#define IN2BC #0x7fb9 -#define IN2CS #0x7fb8 -#define OUT2BC #0x7fc9 -#define OUT2CS #0x7fc8 -#define OUT2BUF #0x7dc0 -#define IN4BUF #0x7d00 -#define IN4BC #0x7fbd -#define IN4CS #0x7fbc -#define OEB #0x7f9d -#define OUTB #0x7f97 -#define OEC #0x7f9e -#define OUTC #0x7f98 -#define PINSC #0x7f9b -#define PORTBCFG #0x7f94 -#define PORTCCFG #0x7f95 -#define OEA #0x7f9c -#define IN07IRQ #0x7fa9 -#define OUT07IRQ #0x7faa -#define IN07IEN #0x7fac -#define OUT07IEN #0x7fad -#define USBIRQ #0x7fab -#define USBIEN #0x7fae -#define USBBAV #0x7faf -#define USBCS #0x7fd6 -#define SUDPTRH #0x7fd4 -#define SUDPTRL #0x7fd5 -#define SETUPDAT #0x7fe8 - - ;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91) - - .org 0 - ljmp start - ;; interrupt vectors - .org 23H - ljmp serial_int - .byte 0 - - .org 43H - ljmp USB_Jump_Table - .byte 0 ; filled in by the USB core - -;;; local variables. These are not initialized properly: do it by hand. - .org 30H -rx_ring_in: .byte 0 -rx_ring_out: .byte 0 -tx_ring_in: .byte 0 -tx_ring_out: .byte 0 -tx_unthrottle_threshold: .byte 0 - - .org 0x100H ; wants to be on a page boundary -USB_Jump_Table: - ljmp ISR_Sudav ; Setup Data Available - .byte 0 - ljmp 0 ; Start of Frame - .byte 0 - ljmp 0 ; Setup Data Loading - .byte 0 - ljmp 0 ; Global Suspend - .byte 0 - ljmp 0 ; USB Reset - .byte 0 - ljmp 0 ; Reserved - .byte 0 - ljmp 0 ; End Point 0 In - .byte 0 - ljmp 0 ; End Point 0 Out - .byte 0 - ljmp 0 ; End Point 1 In - .byte 0 - ljmp 0 ; End Point 1 Out - .byte 0 - ljmp ISR_Ep2in - .byte 0 - ljmp ISR_Ep2out - .byte 0 - - - .org 0x200 - -start: mov SP,STACK-1 ; set stack - ;; clear local variables - clr a - mov tx_ring_in, a - mov tx_ring_out, a - mov rx_ring_in, a - mov rx_ring_out, a - mov tx_unthrottle_threshold, a - clr TX_RUNNING - clr DO_TX_UNTHROTTLE - - ;; clear fifo with "fe" - mov r1, 0 - mov a, #0xfe - mov dptr, #tx_ring -clear_tx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_tx_ring_loop - - mov a, #0xfd - mov dptr, #rx_ring -clear_rx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_rx_ring_loop - -;;; turn on the RS-232 driver chip (bring the STANDBY pin low) -;;; on Xircom the STANDBY is wired to PB6 and PC4 - mov dptr, PORTBCFG - mov a, #0xBf - movx @dptr, a - mov dptr, PORTCCFG - mov a, #0xef - movx @dptr, a - - ;; set OEC.4 - mov a, #0x10 - mov dptr,OEC - movx @dptr,a - - ;; clear PC4 - mov a, #0x00 - mov dptr,OUTC - movx @dptr,a - - ;; set OEB.6 - mov a, #0x40 - mov dptr,OEB - movx @dptr,a - - ;; clear PB6 - mov a, #0x00 - mov dptr,OUTB - movx @dptr,a - - ;; set OEC.[17] - mov a, #0x82 - mov dptr,OEC - movx @dptr,a - - - ;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port - mov dptr, PORTCCFG - mov a, #0x03 - movx @dptr, a - - ;; set up interrupts, autovectoring - ;; set BKPT - mov dptr, USBBAV - movx a,@dptr - setb acc.0 ; AVEN bit to 0 - movx @dptr, a - - mov a,#0x01 ; enable SUDAV: setup data available (for ep0) - mov dptr, USBIRQ - movx @dptr, a ; clear SUDAVI - mov dptr, USBIEN - movx @dptr, a - - mov dptr, IN07IEN - mov a,#0x04 ; enable IN2 int - movx @dptr, a - - mov dptr, OUT07IEN - mov a,#0x04 ; enable OUT2 int - movx @dptr, a - mov dptr, OUT2BC - movx @dptr, a ; arm OUT2 - -;; mov a, #0x84 ; turn on RTS, DTR -;; mov dptr,OUTC -;; movx @dptr, a - - mov a, #0x7 ; turn on DTR - mov dptr,USBBAV - movx @dptr, a - - mov a, #0x20 ; turn on the RED led - mov dptr,OEA - movx @dptr, a - - mov a, #0x80 ; turn on RTS - mov dptr,OUTC - movx @dptr, a - - ;; setup the serial port. 9600 8N1. - mov a,#0x53 ; mode 1, enable rx, clear int - mov SCON, a - ;; using timer2, in 16-bit baud-rate-generator mode - ;; (xtal 12MHz, internal fosc 24MHz) - ;; RCAP2H,RCAP2L = 65536 - fosc/(32*baud) - ;; 57600: 0xFFF2.F, say 0xFFF3 - ;; 9600: 0xFFB1.E, say 0xFFB2 - ;; 300: 0xF63C -#define BAUD 9600 -#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate)) -#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate)) -#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate)) - - mov T2CON, #030h ; rclk=1,tclk=1,cp=0,tr2=0(enable later) - mov r3, #5 - acall set_baud - setb TR2 - mov SCON, #050h - -#if 0 - mov r1, #0x40 - mov a, #0x41 -send: - mov SBUF, a - inc a - anl a, #0x3F - orl a, #0x40 -; xrl a, #0x02 -wait1: - jnb TI, wait1 - clr TI - djnz r1, send -;done: sjmp done - -#endif - - setb EUSB - setb EA - setb ES0 - ;acall dump_stat - - ;; hey, what say we RENUMERATE! (TRM p.62) - mov a, #0 - mov dps, a - mov dptr, USBCS - mov a, #0x02 ; DISCON=0, DISCOE=0, RENUM=1 - movx @dptr, a - ;; now presence pin is floating, simulating disconnect. wait 0.5s - mov r1, #46 -renum_wait1: - mov r2, #0 -renum_wait2: - mov r3, #0 -renum_wait3: - djnz r3, renum_wait3 - djnz r2, renum_wait2 - djnz r1, renum_wait1 ; wait about n*(256^2) 6MHz clocks - mov a, #0x06 ; DISCON=0, DISCOE=1, RENUM=1 - movx @dptr, a - ;; we are back online. the host device will now re-query us - - -main: sjmp main - - - -ISR_Sudav: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, USBIRQ ; clear USB int - mov a,#01h - movx @dptr,a - - ;; get request type - mov dptr, SETUPDAT - movx a, @dptr - mov r1, a ; r1 = bmRequestType - inc dptr - movx a, @dptr - mov r2, a ; r2 = bRequest - inc dptr - movx a, @dptr - mov r3, a ; r3 = wValueL - inc dptr - movx a, @dptr - mov r4, a ; r4 = wValueH - - ;; main switch on bmRequest.type: standard or vendor - mov a, r1 - anl a, #0x60 - cjne a, #0x00, setup_bmreq_type_not_standard - ;; standard request: now main switch is on bRequest - ljmp setup_bmreq_is_standard - -setup_bmreq_type_not_standard: - ;; a still has bmreq&0x60 - cjne a, #0x40, setup_bmreq_type_not_vendor - ;; Anchor reserves bRequest 0xa0-0xaf, we use small ones - ;; switch on bRequest. bmRequest will always be 0x41 or 0xc1 - cjne r2, #0x00, setup_ctrl_not_00 - ;; 00 is set baud, wValue[0] has baud rate index - lcall set_baud ; index in r3, carry set if error - jc setup_bmreq_type_not_standard__do_stall - ljmp setup_done_ack -setup_bmreq_type_not_standard__do_stall: - ljmp setup_stall -setup_ctrl_not_00: - cjne r2, #0x01, setup_ctrl_not_01 - ;; 01 is reserved for set bits (parity). TODO - ljmp setup_stall -setup_ctrl_not_01: - cjne r2, #0x02, setup_ctrl_not_02 - ;; 02 is set HW flow control. TODO - ljmp setup_stall -setup_ctrl_not_02: - cjne r2, #0x03, setup_ctrl_not_03 - ;; 03 is control pins (RTS, DTR). - ljmp control_pins ; will jump to setup_done_ack, - ; or setup_return_one_byte -setup_ctrl_not_03: - cjne r2, #0x04, setup_ctrl_not_04 - ;; 04 is send break (really "turn break on/off"). TODO - cjne r3, #0x00, setup_ctrl_do_break_on - ;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port - mov dptr, PORTCCFG - movx a, @dptr - orl a, #0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_do_break_on: - ;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low) - mov dptr, OUTC - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - mov dptr, PORTCCFG - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_not_04: - cjne r2, #0x05, setup_ctrl_not_05 - ;; 05 is set desired interrupt bitmap. TODO - ljmp setup_stall -setup_ctrl_not_05: - cjne r2, #0x06, setup_ctrl_not_06 - ;; 06 is query room - cjne r3, #0x00, setup_ctrl_06_not_00 - ;; 06, wValue[0]=0 is query write_room - mov a, tx_ring_out - setb c - subb a, tx_ring_in ; out-1-in = 255 - (in-out) - ljmp setup_return_one_byte -setup_ctrl_06_not_00: - cjne r3, #0x01, setup_ctrl_06_not_01 - ;; 06, wValue[0]=1 is query chars_in_buffer - mov a, tx_ring_in - clr c - subb a, tx_ring_out ; in-out - ljmp setup_return_one_byte -setup_ctrl_06_not_01: - ljmp setup_stall -setup_ctrl_not_06: - cjne r2, #0x07, setup_ctrl_not_07 - ;; 07 is request tx unthrottle interrupt - mov tx_unthrottle_threshold, r3; wValue[0] is threshold value - ljmp setup_done_ack -setup_ctrl_not_07: - ljmp setup_stall - -setup_bmreq_type_not_vendor: - ljmp setup_stall - - -setup_bmreq_is_standard: - cjne r2, #0x00, setup_breq_not_00 - ;; 00: Get_Status (sub-switch on bmRequestType: device, ep, int) - cjne r1, #0x80, setup_Get_Status_not_device - ;; Get_Status(device) - ;; are we self-powered? no. can we do remote wakeup? no - ;; so return two zero bytes. This is reusable -setup_return_two_zero_bytes: - mov dptr, IN0BUF - clr a - movx @dptr, a - inc dptr - movx @dptr, a - mov dptr, IN0BC - mov a, #2 - movx @dptr, a - ljmp setup_done_ack -setup_Get_Status_not_device: - cjne r1, #0x82, setup_Get_Status_not_endpoint - ;; Get_Status(endpoint) - ;; must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0 - ;; for now: cheat. TODO - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_endpoint: - cjne r1, #0x81, setup_Get_Status_not_interface - ;; Get_Status(interface): return two zeros - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_interface: - ljmp setup_stall - -setup_breq_not_00: - cjne r2, #0x01, setup_breq_not_01 - ;; 01: Clear_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Clear_Feature_not_stall - ;; Clear_Feature(stall). should clear a stall bit. TODO - ljmp setup_stall -setup_Clear_Feature_not_stall: - cjne r3, #0x01, setup_Clear_Feature_not_rwake - ;; Clear_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Clear_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_01: - cjne r2, #0x03, setup_breq_not_03 - ;; 03: Set_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Set_Feature_not_stall - ;; Set_Feature(stall). Should set a stall bit. TODO - ljmp setup_stall -setup_Set_Feature_not_stall: - cjne r3, #0x01, setup_Set_Feature_not_rwake - ;; Set_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Set_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_03: - cjne r2, #0x06, setup_breq_not_06 - ;; 06: Get_Descriptor (s-switch on wValueH: dev, config[n], string[n]) - cjne r4, #0x01, setup_Get_Descriptor_not_device - ;; Get_Descriptor(device) - mov dptr, SUDPTRH - mov a, #HIGH(desc_device) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_device) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_device: - cjne r4, #0x02, setup_Get_Descriptor_not_config - ;; Get_Descriptor(config[n]) - cjne r3, #0x00, setup_stall; only handle n==0 - ;; Get_Descriptor(config[0]) - mov dptr, SUDPTRH - mov a, #HIGH(desc_config1) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_config1) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_config: - cjne r4, #0x03, setup_Get_Descriptor_not_string - ;; Get_Descriptor(string[wValueL]) - ;; if (wValueL >= maxstrings) stall - mov a, #((desc_strings_end-desc_strings)/2) - clr c - subb a,r3 ; a=4, r3 = 0..3 . if a<=0 then stall - jc setup_stall - jz setup_stall - mov a, r3 - add a, r3 ; a = 2*wValueL - mov dptr, #desc_strings - add a, dpl - mov dpl, a - mov a, #0 - addc a, dph - mov dph, a ; dph = desc_strings[a]. big endian! (handy) - ;; it looks like my adapter uses a revision of the EZUSB that - ;; contains "rev D errata number 8", as hinted in the EzUSB example - ;; code. I cannot find an actual errata description on the Cypress - ;; web site, but from the example code it looks like this bug causes - ;; the length of string descriptors to be read incorrectly, possibly - ;; sending back more characters than the descriptor has. The workaround - ;; is to manually send out all of the data. The consequence of not - ;; using the workaround is that the strings gathered by the kernel - ;; driver are too long and are filled with trailing garbage (including - ;; leftover strings). Writing this out by hand is a nuisance, so for - ;; now I will just live with the bug. - movx a, @dptr - mov r1, a - inc dptr - movx a, @dptr - mov r2, a - mov dptr, SUDPTRH - mov a, r1 - movx @dptr, a - mov dptr, SUDPTRL - mov a, r2 - movx @dptr, a - ;; done - ljmp setup_done_ack - -setup_Get_Descriptor_not_string: - ljmp setup_stall - -setup_breq_not_06: - cjne r2, #0x08, setup_breq_not_08 - ;; Get_Configuration. always 1. return one byte. - ;; this is reusable - mov a, #1 -setup_return_one_byte: - mov dptr, IN0BUF - movx @dptr, a - mov a, #1 - mov dptr, IN0BC - movx @dptr, a - ljmp setup_done_ack -setup_breq_not_08: - cjne r2, #0x09, setup_breq_not_09 - ;; 09: Set_Configuration. ignored. - ljmp setup_done_ack -setup_breq_not_09: - cjne r2, #0x0a, setup_breq_not_0a - ;; 0a: Get_Interface. get the current altsetting for int[wIndexL] - ;; since we only have one interface, ignore wIndexL, return a 0 - mov a, #0 - ljmp setup_return_one_byte -setup_breq_not_0a: - cjne r2, #0x0b, setup_breq_not_0b - ;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored - ljmp setup_done_ack -setup_breq_not_0b: - ljmp setup_stall - - -setup_done_ack: - ;; now clear HSNAK - mov dptr, EP0CS - mov a, #0x02 - movx @dptr, a - sjmp setup_done -setup_stall: - ;; unhandled. STALL - ;EP0CS |= bmEPSTALL - mov dptr, EP0CS - movx a, @dptr - orl a, EP0STALLbit - movx @dptr, a - sjmp setup_done - -setup_done: - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -;;; ============================================================== - -set_baud: ; baud index in r3 - ;; verify a < 10 - mov a, r3 - jb ACC.7, set_baud__badbaud - clr c - subb a, #10 - jnc set_baud__badbaud - mov a, r3 - rl a ; a = index*2 - add a, #LOW(baud_table) - mov dpl, a - mov a, #HIGH(baud_table) - addc a, #0 - mov dph, a - ;; TODO: shut down xmit/receive - ;; TODO: wait for current xmit char to leave - ;; TODO: shut down timer to avoid partial-char glitch - movx a,@dptr ; BAUD_HIGH - mov RCAP2H, a - mov TH2, a - inc dptr - movx a,@dptr ; BAUD_LOW - mov RCAP2L, a - mov TL2, a - ;; TODO: restart xmit/receive - ;; TODO: reenable interrupts, resume tx if pending - clr c ; c=0: success - ret -set_baud__badbaud: - setb c ; c=1: failure - ret - -;;; ================================================== -control_pins: - cjne r1, #0x41, control_pins_in -control_pins_out: - ;TODO BKPT is DTR - mov a, r3 ; wValue[0] holds new bits: b7 is new RTS - xrl a, #0xff ; 1 means active, 0V, +12V ? - anl a, #0x80 - mov r3, a - mov dptr, OUTC - movx a, @dptr ; only change bit 7 - anl a, #0x7F ; ~0x84 - orl a, r3 - movx @dptr, a ; other pins are inputs, bits ignored - ljmp setup_done_ack -control_pins_in: - mov dptr, PINSC - movx a, @dptr - xrl a, #0xff - ljmp setup_return_one_byte - -;;; ======================================== - -ISR_Ep2in: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, IN07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - mov a, #0x20 ; Turn off the green LED - mov dptr,OEA - movx @dptr, a - - - ;; do stuff - lcall start_in - - mov a, #0x20 ; Turn off the green LED - mov dptr,OEA - movx @dptr, a - - - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -ISR_Ep2out: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - - mov a, #0x10 ; Turn the green LED - mov dptr,OEA - movx @dptr, a - - - - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, OUT07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - ;; do stuff - - ;; copy data into buffer. for now, assume we will have enough space - mov dptr, OUT2BC ; get byte count - movx a,@dptr - mov r1, a - clr a - mov dps, a - mov dptr, OUT2BUF ; load DPTR0 with source - mov dph1, #HIGH(tx_ring) ; load DPTR1 with target - mov dpl1, tx_ring_in -OUT_loop: - movx a,@dptr ; read - inc dps ; switch to DPTR1: target - inc dpl1 ; target = tx_ring_in+1 - movx @dptr,a ; store - mov a,dpl1 - cjne a, tx_ring_out, OUT_no_overflow - sjmp OUT_overflow -OUT_no_overflow: - inc tx_ring_in ; tx_ring_in++ - inc dps ; switch to DPTR0: source - inc dptr - djnz r1, OUT_loop - sjmp OUT_done -OUT_overflow: - ;; signal overflow - ;; fall through -OUT_done: - ;; ack - mov dptr,OUT2BC - movx @dptr,a - - ;; start tx - acall maybe_start_tx - ;acall dump_stat - - mov a, #0x20 ; Turn off the green LED - mov dptr,OEA - movx @dptr, a - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -dump_stat: - ;; fill in EP4in with a debugging message: - ;; tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out - ;; tx_active - ;; tx_ring[0..15] - ;; 0xfc - ;; rx_ring[0..15] - clr a - mov dps, a - - mov dptr, IN4CS - movx a, @dptr - jb acc.1, dump_stat__done; busy: cannot dump, old one still pending - mov dptr, IN4BUF - - mov a, tx_ring_in - movx @dptr, a - inc dptr - mov a, tx_ring_out - movx @dptr, a - inc dptr - - mov a, rx_ring_in - movx @dptr, a - inc dptr - mov a, rx_ring_out - movx @dptr, a - inc dptr - - clr a - jnb TX_RUNNING, dump_stat__no_tx_running - inc a -dump_stat__no_tx_running: - movx @dptr, a - inc dptr - ;; tx_ring[0..15] - inc dps - mov dptr, #tx_ring ; DPTR1: source - mov r1, #16 -dump_stat__tx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__tx_ring_loop - inc dps - - mov a, #0xfc - movx @dptr, a - inc dptr - - ;; rx_ring[0..15] - inc dps - mov dptr, #rx_ring ; DPTR1: source - mov r1, #16 -dump_stat__rx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__rx_ring_loop - - ;; now send it - clr a - mov dps, a - mov dptr, IN4BC - mov a, #38 - movx @dptr, a -dump_stat__done: - ret - -;;; ============================================================ - -maybe_start_tx: - ;; make sure the tx process is running. - jb TX_RUNNING, start_tx_done -start_tx: - ;; is there work to be done? - mov a, tx_ring_in - cjne a,tx_ring_out, start_tx__work - ret ; no work -start_tx__work: - ;; tx was not running. send the first character, setup the TI int - inc tx_ring_out ; [++tx_ring_out] - mov dph, #HIGH(tx_ring) - mov dpl, tx_ring_out - movx a, @dptr - mov sbuf, a - setb TX_RUNNING -start_tx_done: - ;; can we unthrottle the host tx process? - ;; step 1: do we care? - mov a, #0 - cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx - ;; nope -start_tx_really_done: - ret -start_tx__maybe_unthrottle_tx: - ;; step 2: is there now room? - mov a, tx_ring_out - setb c - subb a, tx_ring_in - ;; a is now write_room. If thresh >= a, we can unthrottle - clr c - subb a, tx_unthrottle_threshold - jc start_tx_really_done ; nope - ;; yes, we can unthrottle. remove the threshold and mark a request - mov tx_unthrottle_threshold, #0 - setb DO_TX_UNTHROTTLE - ;; prod rx, which will actually send the message when in2 becomes free - ljmp start_in - - -serial_int: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - jnb TI, serial_int__not_tx - ;; tx finished. send another character if we have one - clr TI ; clear int - clr TX_RUNNING - lcall start_tx -serial_int__not_tx: - jnb RI, serial_int__not_rx - lcall get_rx_char - clr RI ; clear int -serial_int__not_rx: - ;; return - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -get_rx_char: - mov dph, #HIGH(rx_ring) - mov dpl, rx_ring_in - inc dpl ; target = rx_ring_in+1 - mov a, sbuf - movx @dptr, a - ;; check for overflow before incrementing rx_ring_in - mov a, dpl - cjne a, rx_ring_out, get_rx_char__no_overflow - ;; signal overflow - ret -get_rx_char__no_overflow: - inc rx_ring_in - ;; kick off USB INpipe - acall start_in - ret - -start_in: - ;; check if the inpipe is already running. - mov a,#0x10 - mov dptr, OEA - movx @dptr,a - - mov dptr, IN2CS - movx a, @dptr - jb acc.1, start_in__done; int will handle it - jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle - ;; see if there is any work to do. a serial interrupt might occur - ;; during this sequence? - mov a, rx_ring_in - cjne a, rx_ring_out, start_in__have_work - ret ; nope -start_in__have_work: - ;; now copy as much data as possible into the pipe. 63 bytes max. - clr a - mov dps, a - mov dph, #HIGH(rx_ring) ; load DPTR0 with source - inc dps - mov dptr, IN2BUF ; load DPTR1 with target - movx @dptr, a ; in[0] signals that rest of IN is rx data - inc dptr - inc dps - ;; loop until we run out of data, or we have copied 64 bytes - mov r1, #1 ; INbuf size counter -start_in__loop: - mov a, rx_ring_in - cjne a, rx_ring_out, start_inlocal_irq_enablell_copying - sjmp start_in__kick -start_inlocal_irq_enablell_copying: - inc rx_ring_out - mov dpl, rx_ring_out - movx a, @dptr - inc dps - movx @dptr, a ; write into IN buffer - inc dptr - inc dps - inc r1 - cjne r1, #64, start_in__loop; loop -start_in__kick: - ;; either we ran out of data, or we copied 64 bytes. r1 has byte count - ;; kick off IN - mov a, #0x10 ; Turn the green LED - mov dptr,OEA - movx @dptr, a - mov dptr, IN2BC - mov a, r1 - jz start_in__done - movx @dptr, a - ;; done -start_in__done: - ;acall dump_stat - ret -start_in__do_tx_unthrottle: - ;; special sequence: send a tx unthrottle message - clr DO_TX_UNTHROTTLE - clr a - mov dps, a - mov dptr, IN2BUF - mov a, #1 - movx @dptr, a - inc dptr - mov a, #2 - movx @dptr, a - mov dptr, IN2BC - movx @dptr, a - ret - -putchar: - clr TI - mov SBUF, a -putchar_wait: - jnb TI, putchar_wait - clr TI - ret - - -baud_table: ; baud_high, then baud_low - ;; baud[0]: 110 - .byte BAUD_HIGH(110) - .byte BAUD_LOW(110) - ;; baud[1]: 300 - .byte BAUD_HIGH(300) - .byte BAUD_LOW(300) - ;; baud[2]: 1200 - .byte BAUD_HIGH(1200) - .byte BAUD_LOW(1200) - ;; baud[3]: 2400 - .byte BAUD_HIGH(2400) - .byte BAUD_LOW(2400) - ;; baud[4]: 4800 - .byte BAUD_HIGH(4800) - .byte BAUD_LOW(4800) - ;; baud[5]: 9600 - .byte BAUD_HIGH(9600) - .byte BAUD_LOW(9600) - ;; baud[6]: 19200 - .byte BAUD_HIGH(19200) - .byte BAUD_LOW(19200) - ;; baud[7]: 38400 - .byte BAUD_HIGH(38400) - .byte BAUD_LOW(38400) - ;; baud[8]: 57600 - .byte BAUD_HIGH(57600) - .byte BAUD_LOW(57600) - ;; baud[9]: 115200 - .byte BAUD_HIGH(115200) - .byte BAUD_LOW(115200) - -desc_device: - .byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40 - .byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01 -;;; The "real" device id, which must match the host driver, is that -;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104 - -desc_config1: - .byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32 - .byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00 - .byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01 - .byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 - -desc_strings: - .word string_langids, string_mfg, string_product, string_serial -desc_strings_end: - -string_langids: .byte string_langids_end-string_langids - .byte 3 - .word 0 -string_langids_end: - - ;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now - ;; *that* is a pain in the ass to encode. And they are little-endian - ;; too. Use this perl snippet to get the bytecodes: - /* while (<>) { - @c = split(//); - foreach $c (@c) { - printf("0x%02x, 0x00, ", ord($c)); - } - } - */ - -string_mfg: .byte string_mfg_end-string_mfg - .byte 3 -; .byte "ACME usb widgets" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00 -string_mfg_end: - -string_product: .byte string_product_end-string_product - .byte 3 -; .byte "ACME USB serial widget" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00 -string_product_end: - -string_serial: .byte string_serial_end-string_serial - .byte 3 -; .byte "47" - .byte 0x34, 0x00, 0x37, 0x00 -string_serial_end: - -;;; ring buffer memory - ;; tx_ring_in+1 is where the next input byte will go - ;; [tx_ring_out] has been sent - ;; if tx_ring_in == tx_ring_out, theres no work to do - ;; there are (tx_ring_in - tx_ring_out) chars to be written - ;; dont let _in lap _out - ;; cannot inc if tx_ring_in+1 == tx_ring_out - ;; write [tx_ring_in+1] then tx_ring_in++ - ;; if (tx_ring_in+1 == tx_ring_out), overflow - ;; else tx_ring_in++ - ;; read/send [tx_ring_out+1], then tx_ring_out++ - - ;; rx_ring_in works the same way - - .org 0x1000 -tx_ring: - .skip 0x100 ; 256 bytes -rx_ring: - .skip 0x100 ; 256 bytes - - - .END - diff --git a/firmware/korg/k1212.dsp.ihex b/firmware/korg/k1212.dsp.ihex deleted file mode 100644 index b151997b380cb842ff5ca5deb784c9618c477566..0000000000000000000000000000000000000000 --- a/firmware/korg/k1212.dsp.ihex +++ /dev/null @@ -1,987 +0,0 @@ -:1000000001FF18FFF5FFCFFF00FF00FFFFFF00FF1C -:1000100000FF00FFFFFF00FF00FF00FFFFFF00FFEA -:1000200026FF18FFFFFF0FFF00FF00FFFFFF00FF8D -:1000300000FF00FFFFFF00FF00FF00FFFFFF00FFCA -:1000400000FF0AFFFFFF1FFF00FF00FFFFFF00FF91 -:1000500000FF00FFFFFF00FF00FF00FFFFFF00FFAA -:1000600000FF0AFFFFFF1FFF00FF00FFFFFF00FF71 -:1000700000FF00FFFFFF00FF00FF00FFFFFF00FF8A -:1000800000FF0AFFFFFF1FFF00FF00FFFFFF00FF51 -:1000900000FF00FFFFFF00FF00FF00FFFFFF00FF6A -:1000A00038FF18FFFFFFDFFF00FF00FFFFFF00FF2B -:1000B00000FF00FFFFFF00FF00FF00FFFFFF00FF4A -:1000C00000FF0AFFFFFF1FFF00FF00FFFFFF00FF11 -:1000D00000FF00FFFFFF00FF00FF00FFFFFF00FF2A -:1000E00003FF3CFFFFFFFCFF67FF40FFFFFFC0FF78 -:1000F000FFFF93FFFFFFE0FF00FF0CFFFFFF0CFF80 -:100100000CFF0CFFFFFF00FF30FF0CFFFFFF00FFA5 -:100110000FFF40FFFFFFF4FF47FF80FFFFFF0AFFD5 -:1001200082FF23FFFFFF0FFF8DFF93FFFFFF7AFF8B -:100130008DFF83FFFFFF70FF47FF90FFFFFF00FF72 -:1001400000FF48FFFFFF04FFA0FF23FFFFFF0FFF9B -:1001500046FF90FFFFFF6AFF00FF0CFFFFFF20FF3D -:1001600000FF04FFFFFF1CFF00FF04FFFFFF1CFF59 -:1001700000FF04FFFFFF1CFF00FF04FFFFFF1CFF49 -:1001800000FF04FFFFFF10FF00FF04FFFFFF10FF51 -:1001900000FF04FFFFFF10FF00FF04FFFFFF10FF41 -:1001A00000FF04FFFFFF10FF00FF04FFFFFF10FF31 -:1001B00000FF04FFFFFF10FF00FF04FFFFFF10FF21 -:1001C00000FF04FFFFFF10FF00FF04FFFFFF10FF11 -:1001D00000FF04FFFFFF10FF00FF04FFFFFF10FF01 -:1001E00072FF1CFFFFFF5FFF02FF40FFFFFF40FFAA -:1001F00011FF90FFFFFF20FF00FF48FFFFFF00FF00 -:100200008BFF93FFFFFF20FF00FF40FFFFFF00FF7A -:1002100086FF93FFFFFF70FF8BFF93FFFFFF30FF11 -:100220008DFF93FFFFFF40FF02FF91FFFFFF80FF65 -:1002300002FF91FFFFFF90FF8DFF93FFFFFFC0FFC5 -:1002400046FF90FFFFFF20FF8DFF93FFFFFFD0FFD2 -:1002500000FF48FFFFFF00FF8BFF93FFFFFF40FF02 -:10026000FFFF47FFFFFFF0FF8DFF93FFFFFFE0FF62 -:1002700000FF34FFFFFF17FF00FF38FFFFFF17FFEE -:1002800080FF37FFFFFF02FF84FF3BFFFFFF02FFFE -:1002900002FF34FFFFFF4AFF02FF38FFFFFF4AFF64 -:1002A00001FF34FFFFFF2BFF01FF38FFFFFF2BFF94 -:1002B00080FF43FFFFFF00FF82FF93FFFFFF50FF20 -:1002C00081FF43FFFFFF20FF82FF93FFFFFF60FFDF -:1002D00084FF43FFFFFF00FF82FF93FFFFFF70FFDC -:1002E00085FF43FFFFFF20FF83FF93FFFFFFC0FF5A -:1002F00082FF37FFFFFF81FF00FF34FFFFFF89FF11 -:1003000088FF43FFFFFF00FF00FF68FFFFFF07FFBD -:1003100082FF83FFFFFF60FF00FF68FFFFFF07FF13 -:100320008CFF43FFFFFF00FF00FF68FFFFFF07FF99 -:1003300083FF83FFFFFFC0FF00FF68FFFFFF07FF92 -:100340008AFF43FFFFFF00FF00FF68FFFFFF07FF7B -:1003500082FF83FFFFFF50FF00FF68FFFFFF07FFE3 -:100360008EFF43FFFFFF00FF00FF68FFFFFF07FF57 -:1003700082FF83FFFFFF70FF00FF68FFFFFF07FFA3 -:1003800083FF37FFFFFF01FF00FF34FFFFFF89FFFF -:1003900000FF34FFFFFF26FF30FF0CFFFFFF00FFD1 -:1003A00000FF40FFFFFF26FF20FF40FFFFFF04FF8D -:1003B00080FF41FFFFFF02FFE0FF20FFFFFF0FFF75 -:1003C00000FF68FFFFFFB6FF63FF22FFFFFF0FFF85 -:1003D00062FF6AFFFFFFA6FF62FF6AFFFFFFA6FF43 -:1003E00000FF68FFFFFFA6FF00FF09FFFFFF07FFF9 -:1003F00040FF41FFFFFF02FFE0FF20FFFFFF0FFF75 -:1004000000FF68FFFFFFB6FF63FF22FFFFFF0FFF44 -:1004100062FF6AFFFFFFA6FF62FF6AFFFFFFA6FF02 -:1004200000FF68FFFFFFA6FF05FF41FFFFFF02FF80 -:10043000E0FF20FFFFFF0FFF8BFF93FFFFFFBBFFDE -:1004400002FF41FFFFFF82FFE0FF20FFFFFF0FFFE2 -:100450008BFF93FFFFFFCBFF05FF41FFFFFFE2FF95 -:10046000E0FF20FFFFFF0FFF8BFF93FFFFFFDBFF8E -:1004700020FF0CFFFFFF00FF30FF0CFFFFFF00FF1E -:1004800000FF40FFFFFF26FF00FF41FFFFFF02FFCD -:10049000E0FF20FFFFFF0FFF83FF93FFFFFF82FFBF -:1004A00083FF93FFFFFF9BFF03FF41FFFFFF02FF5F -:1004B000E0FF20FFFFFF0FFF83FF93FFFFFFA2FF7F -:1004C00083FF93FFFFFFBBFF20FF0CFFFFFF00FF39 -:1004D00000FF40FFFFFF00FF44FF90FFFFFF60FFB2 -:1004E00000FF00FFFFFF00FF00FF00FFFFFF00FF16 -:1004F00000FF00FFFFFF00FF00FF00FFFFFF00FF06 -:1005000000FF00FFFFFF00FF00FF00FFFFFF00FFF5 -:1005100000FF00FFFFFF00FF00FF00FFFFFF00FFE5 -:1005200021FF40FFFFFF60FF40FF90FFFFFF20FF24 -:1005300002FF35FFFFFF00FF00FF34FFFFFF08FF52 -:1005400000FF3CFFFFFF85FF0AFF14FFFFFFAEFF28 -:1005500000FFA0FFFFFF03FF00FF35FFFFFF00FFCD -:1005600000FF34FFFFFF08FF02FF3CFFFFFF05FF16 -:100570000AFF14FFFFFFFEFF00FFA0FFFFFF03FFC6 -:1005800003FF35FFFFFF00FF00FF34FFFFFF08FF01 -:1005900002FF3CFFFFFF05FF0BFF14FFFFFF4EFFB5 -:1005A00000FFA0FFFFFF03FF00FF35FFFFFF01FF7C -:1005B00078FF1CFFFFFF5FFF03FF35FFFFFF01FF19 -:1005C00078FF1CFFFFFF5FFF5BFF40FFFFFFF0FFB7 -:1005D000FFFF93FFFFFF30FF80FF42FFFFFF70FF31 -:1005E000FFFF93FFFFFF60FFDFFF40FFFFFFF0FF14 -:1005F000FEFF93FFFFFFF0FF80FF42FFFFFF70FF52 -:10060000FFFF93FFFFFF20FFC1FF41FFFFFF80FFC0 -:10061000FFFF93FFFFFFF0FF03FF3CFFFFFFFCFF27 -:1006200000FF3CFFFFFF04FF02FF3CFFFFFF23FF33 -:1006300000FF48FFFFFF00FF8BFF93FFFFFF20FF3E -:1006400059FF18FFFFFFDFFF00FF48FFFFFF00FF1C -:100650008BFF93FFFFFF20FF18FF23FFFFFF0FFF1C -:100660000CFF14FFFFFFE4FF8BFF83FFFFFF24FF5E -:1006700000FF22FFFFFF0FFF0DFF18FFFFFF0FFF1F -:100680008BFF83FFFFFF20FF00FF40FFFFFF14FFF2 -:10069000E0FF22FFFFFF0FFF10FF18FFFFFFD0FF5B -:1006A0008BFF83FFFFFF20FF00FF40FFFFFF24FFC2 -:1006B000E0FF22FFFFFF0FFF10FF18FFFFFF30FFDB -:1006C0008BFF83FFFFFF20FF00FF40FFFFFF44FF82 -:1006D000E0FF22FFFFFF0FFF22FF18FFFFFF90FF49 -:1006E0008BFF83FFFFFF20FF00FF40FFFFFF84FF22 -:1006F000E0FF22FFFFFF0FFF22FF18FFFFFF90FF29 -:100700000CFF18FFFFFF6FFF00FF40FFFFFF00FF20 -:1007100086FF93FFFFFF70FF76FF1CFFFFFF9FFF29 -:1007200086FF83FFFFFF50FF86FF83FFFFFF64FF0D -:1007300060FF22FFFFFF0FFF74FF18FFFFFF81FF25 -:1007400000FF35FFFFFF00FF60FF1CFFFFFF7FFF83 -:1007500061FF1CFFFFFFAFFF77FF1CFFFFFFAFFF35 -:1007600063FF1CFFFFFF4FFF05FF35FFFFFF00FF8B -:1007700092FF3BFFFFFF00FF00FF34FFFFFF08FF7A -:1007800000FF38FFFFFF08FF00FF3CFFFFFF65FF92 -:100790000FFF14FFFFFF6EFF00FF60FFFFFF03FF6F -:1007A00000FF60FFFFFF13FF00FF78FFFFFF13FF55 -:1007B00000FF78FFFFFF03FF05FF35FFFFFFE0FFAE -:1007C0007FFF38FFFFFF00FF00FF34FFFFFF08FF40 -:1007D00000FF38FFFFFF08FF00FF3CFFFFFF65FF42 -:1007E00010FF14FFFFFF0EFF00FF60FFFFFF03FF7E -:1007F00000FF60FFFFFF13FF00FF58FFFFFF13FF25 -:1008000000FF58FFFFFF03FF79FF1CFFFFFFFFFF03 -:1008100000FF0AFFFFFF0FFF0EFF1CFFFFFF1FFF80 -:100820008DFF83FFFFFFE0FF78FF22FFFFFF0FFF39 -:1008300015FF1CFFFFFF85FF75FF1CFFFFFF8FFFEC -:1008400000FF40FFFFFF40FF8BFF93FFFFFF80FF94 -:1008500002FF40FFFFFF60FF11FF90FFFFFF20FF3F -:1008600016FF18FFFFFF1FFF0EFF1CFFFFFF1FFFFC -:1008700075FF1CFFFFFF8FFF80FF35FFFFFF00FFAD -:1008800000FF34FFFFFF08FF00FF40FFFFFF00FFF6 -:1008900040FF3CFFFFFF05FF11FF14FFFFFF4EFF6E -:1008A00000FF68FFFFFF03FF87FF83FFFFFFF0FFED -:1008B00086FF93FFFFFF80FF90FF37FFFFFF00FFE2 -:1008C00002FF34FFFFFF08FF00FF60FFFFFF03FF91 -:1008D00089FF93FFFFFF20FF00FF60FFFFFF03FF83 -:1008E00089FF93FFFFFF30FF00FF60FFFFFF03FF63 -:1008F00089FF93FFFFFF40FF00FF60FFFFFF03FF43 -:1009000089FF93FFFFFF50FF86FF97FFFFFF90FFD8 -:1009100003FF35FFFFFF00FF60FF1CFFFFFF7FFFAE -:1009200063FF1CFFFFFF7FFF00FF40FFFFFF00FF93 -:100930008DFF93FFFFFF60FF82FF93FFFFFF40FFEC -:1009400086FF93FFFFFFA0FF83FF37FFFFFF80FFBE -:1009500075FF1CFFFFFF1FFF83FF43FFFFFF00FF2B -:1009600087FF93FFFFFFE0FF6AFF1CFFFFFF0FFF02 -:1009700040FF41FFFFFF00FF8BFF93FFFFFF90FF52 -:1009800080FF41FFFFFF00FF8BFF93FFFFFFA0FFF2 -:100990008BFF87FFFFFF90FF7EFF38FFFFFF00FF09 -:1009A00040FF34FFFFFF08FF00FF38FFFFFF08FF95 -:1009B00000FF3CFFFFFF55FF13FF14FFFFFFBEFFCB -:1009C00000FF60FFFFFF03FF00FF60FFFFFF13FF5B -:1009D00000FF58FFFFFF13FF00FF58FFFFFF03FF5B -:1009E00000FF60FFFFFF03FF00FF60FFFFFF13FF3B -:1009F00000FF58FFFFFF13FF00FF58FFFFFF03FF3B -:100A000000FF60FFFFFF03FF00FF60FFFFFF13FF1A -:100A100000FF58FFFFFF13FF00FF58FFFFFF03FF1A -:100A200000FF60FFFFFF03FF00FF60FFFFFF03FF0A -:100A30008BFF97FFFFFF90FF05FF41FFFFFF00FFC8 -:100A400092FF43FFFFFF01FF86FF93FFFFFFF0FFD1 -:100A500086FF93FFFFFFE1FF8DFF83FFFFFFE0FFB6 -:100A600078FF22FFFFFF0FFF15FF1CFFFFFF85FF31 -:100A700075FF1CFFFFFF8FFF8DFF83FFFFFF40FF10 -:100A800078FF22FFFFFF0FFF53FF18FFFFFFB4FFA8 -:100A900072FF1CFFFFFF0FFF00FF40FFFFFF00FF83 -:100AA0008BFF93FFFFFF30FF02FF40FFFFFF60FF60 -:100AB00011FF90FFFFFF20FF16FF18FFFFFF4FFF02 -:100AC00038FF42FFFFFF50FF48FF90FFFFFFA0FFEE -:100AD00000FF00FFFFFF00FF00FF00FFFFFF00FF20 -:100AE00000FF00FFFFFF00FF00FF00FFFFFF00FF10 -:100AF00030FF40FFFFFF00FF47FF90FFFFFF50FF69 -:100B000000FF0AFFFFFF0FFF1EFF1CFFFFFF0FFF8D -:100B100020FF1CFFFFFFCFFF16FF18FFFFFF1FFF87 -:100B200000FF40FFFFFF00FF46FF90FFFFFF70FF49 -:100B300018FF1CFFFFFFEFFF6AFF1CFFFFFFBFFF57 -:100B40005CFF1CFFFFFF7FFF18FF1CFFFFFFEFFF95 -:100B500067FF1CFFFFFF3FFF5CFF1CFFFFFF7FFFE6 -:100B600008FF40FFFFFF00FF46FF90FFFFFF70FF01 -:100B700018FF1CFFFFFFEFFF69FF1CFFFFFF0FFFC8 -:100B80005DFF1CFFFFFF2FFF18FF1CFFFFFFEFFFA4 -:100B900079FF1CFFFFFF1FFF5CFF1CFFFFFF7FFFB4 -:100BA00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFF35 -:100BB00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFF25 -:100BC00018FF1CFFFFFFEFFF5DFF1CFFFFFF2FFF64 -:100BD00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFF05 -:100BE00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFF5 -:100BF00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFE5 -:100C000018FF1CFFFFFFEFFF5DFF1CFFFFFF2FFF23 -:100C100018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFC4 -:100C200018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFB4 -:100C300018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFA4 -:100C400018FF1CFFFFFFEFFF5DFF1CFFFFFF2FFFE3 -:100C500018FF1CFFFFFFEFFF66FF1CFFFFFF1FFFDA -:100C60005CFF1CFFFFFF7FFF16FF18FFFFFF4FFF1A -:100C70008BFF87FFFFFF61FF00FF34FFFFFF89FF4E -:100C800000FF34FFFFFF26FF00FF60FFFFFF06FFAE -:100C900083FF93FFFFFFD0FF00FF60FFFFFF06FF12 -:100CA00083FF93FFFFFFE0FF38FF22FFFFFF0FFFEF -:100CB00019FF14FFFFFF85FF8BFF83FFFFFF50FF2E -:100CC00078FF22FFFFFF0FFF00FF60FFFFFF07FF1E -:100CD00004FF0DFFFFFF30FF00FF60FFFFFF07FF76 -:100CE00083FF93FFFFFFF0FF00FF60FFFFFF07FFA1 -:100CF00008FF0DFFFFFF30FF00FF60FFFFFF07FF52 -:100D000086FF93FFFFFF40FF00FF40FFFFFF01FF53 -:100D10008BFF93FFFFFF51FF00FF34FFFFFF46FFF4 -:100D200000FF09FFFFFF06FF8BFF97FFFFFF61FF3B -:100D300083FF8BFFFFFFD0FF83FF8BFFFFFFE1FFF0 -:100D400087FF37FFFFFF01FF6EFF1CFFFFFFBFFFA5 -:100D500087FF37FFFFFF00FF92FF37FFFFFF01FF15 -:100D60007FFF38FFFFFF00FF7EFF38FFFFFF01FF1F -:100D700023FF1CFFFFFFFFFF7EFF38FFFFFF00FF89 -:100D800083FF87FFFFFFF1FF86FF8BFFFFFF41FF20 -:100D90006CFF1CFFFFFF2FFF87FF37FFFFFF00FFE8 -:100DA0008BFF8BFFFFFFA0FF00FF34FFFFFF08FF5B -:100DB00040FF38FFFFFF08FF00FF3CFFFFFF55FF2C -:100DC0001BFF14FFFFFFCEFF00FF60FFFFFF03FFCD -:100DD00000FF60FFFFFF13FF00FF78FFFFFF13FF1F -:100DE00000FF78FFFFFF03FF00FF60FFFFFF03FF2F -:100DF00000FF60FFFFFF13FF00FF78FFFFFF13FFFF -:100E000000FF78FFFFFF03FF00FF60FFFFFF03FF0E -:100E100000FF60FFFFFF13FF00FF78FFFFFF13FFDE -:100E200000FF78FFFFFF03FF8BFF83FFFFFFE1FF62 -:100E30008BFF83FFFFFFF0FF00FF78FFFFFF13FF33 -:100E400000FF78FFFFFF03FF8BFF9BFFFFFFA0FF6B -:100E50008BFF87FFFFFF90FF7EFF38FFFFFF00FF44 -:100E600040FF34FFFFFF08FF00FF38FFFFFF08FFD0 -:100E700000FF3CFFFFFF55FF1DFF14FFFFFF3EFF7C -:100E800000FF60FFFFFF03FF00FF60FFFFFF13FF96 -:100E900000FF58FFFFFF13FF00FF58FFFFFF03FF96 -:100EA00000FF60FFFFFF03FF00FF60FFFFFF13FF76 -:100EB00000FF58FFFFFF13FF00FF58FFFFFF03FF76 -:100EC00000FF60FFFFFF03FF00FF60FFFFFF13FF56 -:100ED00000FF58FFFFFF13FF00FF58FFFFFF03FF56 -:100EE00000FF60FFFFFF03FF00FF60FFFFFF03FF46 -:100EF0008BFF97FFFFFF90FF00FF0AFFFFFF0FFF31 -:100F00008BFF87FFFFFF61FF00FF34FFFFFF89FFBB -:100F100000FF34FFFFFF26FF00FF60FFFFFF06FF1B -:100F200083FF93FFFFFFD0FF00FF60FFFFFF06FF7F -:100F300083FF93FFFFFFE0FF8BFF83FFFFFF51FF66 -:100F400079FF22FFFFFF0FFF74FF18FFFFFFB4FFC1 -:100F500038FF22FFFFFF0FFF1EFF14FFFFFFD5FF2B -:100F60008BFF83FFFFFF50FF78FF22FFFFFF0FFF84 -:100F700000FF60FFFFFF07FF04FF0DFFFFFF30FFD3 -:100F800000FF60FFFFFF07FF83FF93FFFFFFF0FFFE -:100F900000FF60FFFFFF07FF08FF0DFFFFFF30FFAF -:100FA00000FF60FFFFFF07FF86FF93FFFFFF40FF8B -:100FB00000FF40FFFFFF01FF8BFF93FFFFFF51FF8B -:100FC00000FF34FFFFFF46FF00FF09FFFFFF06FFA2 -:100FD0008BFF97FFFFFF61FF83FF8BFFFFFFD0FFBA -:100FE00083FF8BFFFFFFE1FF87FF37FFFFFF01FF5D -:100FF0006EFF1CFFFFFFBFFF87FF37FFFFFF00FFF4 -:1010000092FF37FFFFFF01FF7FFF38FFFFFF00FF69 -:1010100023FF1CFFFFFFFFFF7EFF38FFFFFF00FFE6 -:1010200083FF87FFFFFFF1FF86FF8BFFFFFF41FF7D -:101030006CFF1CFFFFFF2FFF00FF0AFFFFFF0FFFEA -:101040008DFF8FFFFFFFC5FF20FF14FFFFFFAEFFE7 -:1010500000FF00FFFFFF00FF00FF0AFFFFFF0FFF81 -:101060008BFF83FFFFFF84FF00FF23FFFFFF0FFFC6 -:101070008BFF93FFFFFF8AFF64FF1CFFFFFFE0FF72 -:101080007EFF38FFFFFF00FF00FF38FFFFFF08FF74 -:1010900000FF3CFFFFFFE5FF21FF14FFFFFF5EFFA6 -:1010A00000FF40FFFFFF00FF00FF58FFFFFF03FFAF -:1010B00000FF0AFFFFFF0FFF08FF40FFFFFF10FFC9 -:1010C00047FF90FFFFFF20FF00FF04FFFFFF1CFF13 -:1010D00000FF04FFFFFF1CFF00FF04FFFFFF1CFFDA -:1010E00000FF04FFFFFF1CFF00FF04FFFFFF10FFD6 -:1010F00000FF04FFFFFF10FF00FF04FFFFFF10FFD2 -:1011000000FF04FFFFFF10FF00FF04FFFFFF10FFC1 -:1011100000FF04FFFFFF10FF00FF04FFFFFF10FFB1 -:1011200000FF04FFFFFF10FF00FF04FFFFFF10FFA1 -:1011300000FF04FFFFFF10FF00FF04FFFFFF10FF91 -:1011400000FF04FFFFFF10FF02FF40FFFFFF40FF13 -:1011500011FF90FFFFFF20FF78FF42FFFFFF50FFCE -:1011600048FF90FFFFFFA0FF00FF00FFFFFF00FF11 -:1011700000FF00FFFFFF00FF00FF00FFFFFF00FF79 -:1011800000FF00FFFFFF00FF00FF00FFFFFF00FF69 -:10119000B0FF40FFFFFF00FF47FF90FFFFFF50FF42 -:1011A00000FF40FFFFFF00FF8DFF93FFFFFF40FFA9 -:1011B0008DFF93FFFFFF50FF00FF40FFFFFF01FF88 -:1011C0008BFF93FFFFFF51FF00FF40FFFFFF00FF7A -:1011D00046FF90FFFFFF70FF8DFF83FFFFFFD0FFF3 -:1011E00078FF22FFFFFF0FFF0CFF18FFFFFF90FFAC -:1011F0000CFF18FFFFFF6FFF20FF0CFFFFFF00FF3A -:1012000000FF34FFFFFF09FF00FF34FFFFFF08FF6F -:1012100000FF38FFFFFF08FF00FF38FFFFFF09FF57 -:1012200000FF38FFFFFF06FF00FF34FFFFFF26FF30 -:1012300098FFCCFFFFFF37FF00FF3CFFFFFFA5FF3C -:1012400024FF14FFFFFFFEFF00FF60FFFFFF73FF9F -:1012500008FF0DFFFFFF14FF98FF20FFFFFF0FFFA8 -:1012600000FF50FFFFFFC6FF69FFCCFFFFFF37FF06 -:1012700000FF05FFFFFF00FF00FF58FFFFFFC6FF55 -:1012800098FF20FFFFFF0FFF00FF60FFFFFF72FFCF -:1012900008FF0DFFFFFF14FF00FF50FFFFFFC6FF19 -:1012A00069FFCCFFFFFF37FF00FF05FFFFFF00FFD7 -:1012B00000FF58FFFFFFC6FF98FF20FFFFFF0FFF53 -:1012C00000FF60FFFFFF73FF08FF0DFFFFFF14FF2C -:1012D00000FF50FFFFFFC6FF69FF20FFFFFF0FFF6A -:1012E00000FF05FFFFFF00FF00FF58FFFFFFC6FFE5 -:1012F00030FF0CFFFFFF00FF00FF0AFFFFFF0FFFA3 -:1013000000FF0CFFFFFF30FF47FF80FFFFFF58FF8C -:1013100010FF0FFFFFFF01FF66FF23FFFFFF0FFF1F -:1013200026FF18FFFFFF94FF00FF48FFFFFF00FFAD -:101330008BFF93FFFFFF40FF80FF40FFFFFF00FF99 -:1013400049FF90FFFFFF40FF16FF0FFFFFFF02FF67 -:1013500066FF23FFFFFF0FFF38FF18FFFFFFB4FFFB -:101360000FFF40FFFFFFF4FF47FF80FFFFFF0AFF73 -:1013700082FF23FFFFFF0FFF8DFF93FFFFFF7AFF29 -:101380007AFF26FFFFFF0FFF10FF27FFFFFF0FFF72 -:1013900038FF18FFFFFFB4FF27FF18FFFFFFD2FF42 -:1013A00000FF48FFFFFF00FF8BFF93FFFFFF30FFB1 -:1013B0008DFF83FFFFFF70FF47FF90FFFFFF00FFE0 -:1013C00000FF48FFFFFF04FFA0FF23FFFFFF0FFF09 -:1013D00046FF90FFFFFF6AFF00FF0CFFFFFF20FFAB -:1013E00000FF0AFFFFFF1FFF10FF27FFFFFF0FFF98 -:1013F00029FF18FFFFFF92FF46FF80FFFFFF00FF5E -:101400008BFF93FFFFFF20FF8DFF83FFFFFF70FF28 -:1014100047FF90FFFFFF00FF00FF48FFFFFF04FFB3 -:10142000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFB4 -:1014300000FF0CFFFFFF20FF00FF04FFFFFF1CFF6A -:1014400000FF04FFFFFF1CFF00FF04FFFFFF1CFF66 -:1014500000FF04FFFFFF1CFF00FF04FFFFFF10FF62 -:1014600000FF04FFFFFF10FF00FF04FFFFFF10FF5E -:1014700000FF04FFFFFF10FF00FF04FFFFFF10FF4E -:1014800000FF04FFFFFF10FF00FF04FFFFFF10FF3E -:1014900000FF04FFFFFF10FF00FF04FFFFFF10FF2E -:1014A00000FF04FFFFFF10FF00FF04FFFFFF10FF1E -:1014B00000FF04FFFFFF10FF00FF04FFFFFF03FF1B -:1014C0000DFF18FFFFFF0FFF10FF27FFFFFF0FFFAC -:1014D00031FF18FFFFFF12FF30FF0CFFFFFF00FF7F -:1014E00008FF0CFFFFFF00FFFFFF4FFFFFFF89FF1B -:1014F00090FF37FFFFFF00FF02FF34FFFFFF08FFF1 -:1015000000FF34FFFFFF34FF00FF34FFFFFF55FFF4 -:1015100046FF80FFFFFF08FF00FF0EFFFFFF0FFFEA -:1015200000FF0DFFFFFF4EFFA7FF23FFFFFF0FFF91 -:1015300000FF68FFFFFFA3FF00FF0DFFFFFF4AFF53 -:1015400046FF80FFFFFF18FF00FF0EFFFFFF0FFFAA -:1015500000FF0DFFFFFF5EFFAFFF23FFFFFF0FFF49 -:1015600000FF68FFFFFFA0FF00FF0DFFFFFF5AFF16 -:1015700046FF80FFFFFF48FF10FF0FFFFFFFFEFF4A -:1015800087FF93FFFFFFFEFF00FF0DFFFFFF2EFF12 -:1015900002FF40FFFFFF06FFE0FF20FFFFFF0FFFFE -:1015A00000FF40FFFFFF01FF63FF22FFFFFF0FFF70 -:1015B00000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF88 -:1015C00000FF0DFFFFFF5AFF00FF68FFFFFFA0FFB6 -:1015D00000FF0DFFFFFF5AFF63FF22FFFFFF0FFF1A -:1015E00000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF58 -:1015F00000FF0DFFFFFF5AFF00FF68FFFFFFA0FF86 -:1016000063FF22FFFFFF0FFF00FF0DFFFFFF4AFFF9 -:1016100049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF17 -:1016200000FF68FFFFFFA0FF63FF22FFFFFF0FFF28 -:1016300000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF07 -:1016400000FF0DFFFFFF5AFF00FF68FFFFFFA0FF35 -:1016500063FF22FFFFFF0FFF00FF0DFFFFFF4AFFA9 -:1016600049FF6AFFFFFFA3FF00FF0DFFFFFF5AFFC7 -:1016700000FF68FFFFFFA0FF63FF22FFFFFF0FFFD8 -:1016800000FF0DFFFFFF4AFF49FF6AFFFFFFA3FFB7 -:1016900000FF0DFFFFFF5AFF00FF68FFFFFFA0FFE5 -:1016A00063FF22FFFFFF0FFF00FF0DFFFFFF4AFF59 -:1016B00049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF77 -:1016C00000FF68FFFFFFA1FF46FF80FFFFFF28FF2D -:1016D00000FF0EFFFFFF0FFF00FF0DFFFFFF4EFF9C -:1016E000A7FF23FFFFFF0FFF00FF68FFFFFFA3FF20 -:1016F00000FF0DFFFFFF4AFF46FF80FFFFFF38FF9F -:1017000000FF0EFFFFFF0FFF00FF0DFFFFFF5EFF5B -:10171000AFFF23FFFFFF0FFF00FF68FFFFFFA0FFEA -:1017200000FF0DFFFFFF5AFF63FF22FFFFFF0FFFC8 -:1017300000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF06 -:1017400000FF0DFFFFFF5AFF00FF68FFFFFFA0FF34 -:1017500063FF22FFFFFF0FFF00FF0DFFFFFF4AFFA8 -:1017600049FF6AFFFFFFA3FF00FF0DFFFFFF5AFFC6 -:1017700000FF68FFFFFFA0FF63FF22FFFFFF0FFFD7 -:1017800000FF0DFFFFFF4AFF49FF6AFFFFFFA3FFB6 -:1017900000FF0DFFFFFF5AFF00FF68FFFFFFA0FFE4 -:1017A00063FF22FFFFFF0FFF00FF0DFFFFFF4AFF58 -:1017B00049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF76 -:1017C00000FF68FFFFFFA0FF63FF22FFFFFF0FFF87 -:1017D00000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF66 -:1017E00000FF0DFFFFFF5AFF00FF68FFFFFFA0FF94 -:1017F00063FF22FFFFFF0FFF00FF0DFFFFFF4AFF08 -:1018000049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF25 -:1018100000FF68FFFFFFA0FF63FF22FFFFFF0FFF36 -:1018200000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF15 -:1018300000FF0DFFFFFF5AFF00FF68FFFFFFA3FF40 -:10184000FFFF4FFFFFFFF0FF86FF93FFFFFF50FFFB -:101850008DFF83FFFFFF70FF47FF90FFFFFF00FF3B -:1018600000FF48FFFFFF04FFA0FF23FFFFFF0FFF64 -:1018700046FF90FFFFFF6AFF00FF0CFFFFFF20FF06 -:1018800000FF0AFFFFFF1FFF10FF27FFFFFF0FFFF3 -:1018900032FF18FFFFFF42FF8BFF83FFFFFFE4FFD4 -:1018A0008BFF83FFFFFFF5FF46FF90FFFFFF44FF25 -:1018B00008FF22FFFFFF0FFFFFFF4FFFFFFF89FF22 -:1018C00000FF0DFFFFFF8AFF00FF0EFFFFFF0FFF6E -:1018D00000FF0DFFFFFF4EFFA7FF23FFFFFF0FFFDE -:1018E00046FF90FFFFFF5AFF8DFF83FFFFFF70FF52 -:1018F00047FF90FFFFFF00FF00FF48FFFFFF04FFCF -:10190000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFCF -:1019100000FF0CFFFFFF20FF00FF0AFFFFFF1FFF7C -:1019200010FF27FFFFFF0FFF35FF18FFFFFFD2FF5C -:1019300000FF4CFFFFFF00FF00FF93FFFFFF00FFD2 -:101940000BFF40FFFFFF80FF11FF90FFFFFFF0FF45 -:1019500000FF40FFFFFF10FF11FF90FFFFFFE0FFC0 -:1019600046FF80FFFFFF0AFF7AFF26FFFFFF0FFF02 -:1019700035FF1CFFFFFF24FF10FF27FFFFFF0FFFB6 -:1019800033FF18FFFFFFC5FF00FF40FFFFFFC0FF51 -:1019900011FF90FFFFFF60FF8DFF93FFFFFFD0FF60 -:1019A00000FF48FFFFFF00FF8DFF83FFFFFF70FF79 -:1019B00047FF90FFFFFF00FF00FF48FFFFFF04FF0E -:1019C000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF0F -:1019D00000FF0CFFFFFF20FF00FF0AFFFFFF1FFFBC -:1019E00010FF27FFFFFF0FFF34FF18FFFFFF85FFEA -:1019F00000FF40FFFFFF40FF11FF90FFFFFF60FF70 -:101A00008DFF93FFFFFFD0FF8DFF83FFFFFF70FF70 -:101A100047FF90FFFFFF00FF00FF48FFFFFF04FFAD -:101A2000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFAE -:101A300000FF0CFFFFFF20FF00FF0AFFFFFF1FFF5B -:101A400000FF40FFFFFF00FF11FF90FFFFFF60FF5F -:101A50008DFF93FFFFFFD0FF8DFF83FFFFFF70FF20 -:101A600047FF90FFFFFF00FF00FF48FFFFFF04FF5D -:101A7000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF5E -:101A800000FF0CFFFFFF20FF00FF0AFFFFFF1FFF0B -:101A900000FF48FFFFFF00FF8DFF93FFFFFF80FF68 -:101AA00000FF48FFFFFF00FF00FF93FFFFFF00FF65 -:101AB0000DFF40FFFFFFF0FF11FF90FFFFFFF0FF62 -:101AC00000FF40FFFFFF10FF11FF90FFFFFFE0FF4F -:101AD000FFFF40FFFFFFF0FF90FF27FFFFFF0FFF1B -:101AE00000FF0AFFFFFF0FFF10FF27FFFFFF0FFFA1 -:101AF00037FF18FFFFFF42FF46FF80FFFFFF00FF99 -:101B000089FF93FFFFFFA0FF46FF80FFFFFF10FF4D -:101B100089FF93FFFFFFB0FF46FF80FFFFFF20FF1D -:101B200089FF93FFFFFFC0FF46FF80FFFFFF30FFED -:101B300089FF93FFFFFFD0FF46FF80FFFFFF40FFBD -:101B400089FF93FFFFFFE0FF46FF80FFFFFF50FF8D -:101B500089FF93FFFFFFF0FF00FF40FFFFFF10FF33 -:101B600086FF93FFFFFF60FF8DFF83FFFFFF70FF86 -:101B700047FF90FFFFFF00FF00FF48FFFFFF04FF4C -:101B8000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF4D -:101B900000FF0CFFFFFF20FF00FF0AFFFFFF1FFFFA -:101BA00010FF27FFFFFF0FFF39FF18FFFFFF22FF86 -:101BB00046FF80FFFFFF00FF8DFF93FFFFFF20FF29 -:101BC00046FF80FFFFFF10FF8DFF93FFFFFF30FFF9 -:101BD00046FF80FFFFFF20FF78FF22FFFFFF0FFF80 -:101BE00038FF1CFFFFFF84FF00FF40FFFFFF00FFE7 -:101BF00046FF90FFFFFF20FF00FF48FFFFFF00FFB1 -:101C00008DFF93FFFFFF40FF8DFF83FFFFFF70FFFE -:101C100047FF90FFFFFF00FF00FF48FFFFFF04FFAB -:101C2000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFAC -:101C300000FF0CFFFFFF20FF00FF0AFFFFFF1FFF59 -:101C400000FF48FFFFFF00FF8DFF93FFFFFF50FFE6 -:101C500000FF0AFFFFFF0FFF00FF0CFFFFFF20FF49 -:101C600000FF0AFFFFFF1FFF00FF0CFFFFFF30FF19 -:101C700000FF48FFFFFF00FF8BFF93FFFFFF50FFB8 -:101C800000FF0CFFFFFF20FF00FF0AFFFFFF1FFF09 -:101C90008DFF83FFFFFF70FF0FFF40FFFFFFF4FF8B -:101CA000E0FF22FFFFFF0FFF41FF18FFFFFF30FFA4 -:101CB0008DFF83FFFFFF70FF0FFF40FFFFFFE4FF7B -:101CC000E0FF22FFFFFF0FFF42FF18FFFFFF40FF73 -:101CD0008DFF83FFFFFF70FF0FFF40FFFFFFD4FF6B -:101CE000E0FF22FFFFFF0FFF47FF18FFFFFFA0FFEE -:101CF0008DFF83FFFFFF70FF0FFF40FFFFFFC4FF5B -:101D0000E0FF22FFFFFF0FFF46FF18FFFFFFD0FF9E -:101D10008DFF83FFFFFF70FF0FFF40FFFFFFB4FF4A -:101D2000E0FF22FFFFFF0FFF48FF18FFFFFFE0FF6C -:101D30008DFF83FFFFFF70FF0FFF40FFFFFFA4FF3A -:101D4000E0FF22FFFFFF0FFF4AFF18FFFFFF60FFCA -:101D50008DFF83FFFFFF70FF0FFF40FFFFFF94FF2A -:101D6000E0FF22FFFFFF0FFF4CFF18FFFFFF00FF08 -:101D70008DFF83FFFFFF70FF0FFF40FFFFFF84FF1A -:101D8000E0FF22FFFFFF0FFF4DFF18FFFFFFE0FF07 -:101D90008DFF83FFFFFF70FF0FFF40FFFFFF74FF0A -:101DA000E0FF22FFFFFF0FFF4FFF18FFFFFF20FFA5 -:101DB0008DFF83FFFFFF70FF0FFF40FFFFFF64FFFA -:101DC000E0FF22FFFFFF0FFF4FFF18FFFFFFF0FFB5 -:101DD0008DFF83FFFFFF70FF0EFF40FFFFFFF4FF4B -:101DE000E0FF22FFFFFF0FFF44FF18FFFFFF40FF50 -:101DF0008DFF83FFFFFF70FF0EFF40FFFFFFE4FF3B -:101E0000E0FF22FFFFFF0FFF45FF18FFFFFF50FF1E -:101E10008DFF83FFFFFF70FF0AFF40FFFFFF04FFFE -:101E2000E0FF22FFFFFF0FFF3DFF18FFFFFFD0FF86 -:101E30008DFF83FFFFFF70FF0AFF40FFFFFF14FFCE -:101E4000E0FF22FFFFFF0FFF3FFF18FFFFFF10FF24 -:101E50008DFF83FFFFFF70FF0AFF40FFFFFF24FF9E -:101E6000E0FF22FFFFFF0FFF3FFF18FFFFFF80FF94 -:101E70008DFF83FFFFFF70FF0AFF40FFFFFF34FF6E -:101E8000E0FF22FFFFFF0FFF3FFF18FFFFFFF0FF04 -:101E90008DFF83FFFFFF70FF0AFF40FFFFFF44FF3E -:101EA000E0FF22FFFFFF0FFF40FF18FFFFFF60FF73 -:101EB0008DFF83FFFFFF70FF47FF90FFFFFF00FFD5 -:101EC00000FF48FFFFFF04FFA0FF23FFFFFF0FFFFE -:101ED00046FF90FFFFFF6AFF00FF0CFFFFFF20FFA0 -:101EE00000FF0AFFFFFF1FFF8DFF83FFFFFF70FF53 -:101EF00047FF90FFFFFF00FF00FF48FFFFFF04FFC9 -:101F0000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFC9 -:101F100000FF0CFFFFFF08FF00FF40FFFFFF00FF77 -:101F2000FFFF93FFFFFFF0FF00FF40FFFFFF00FFF9 -:101F300044FF90FFFFFF60FF00FF00FFFFFF00FF77 -:101F400000FF00FFFFFF00FF00FF00FFFFFF00FF9B -:101F500000FF00FFFFFF00FF00FF00FFFFFF00FF8B -:101F600000FF00FFFFFF00FF00FF00FFFFFF00FF7B -:101F700000FF00FFFFFF00FF21FF40FFFFFF80FF8A -:101F8000FFFF93FFFFFFF0FF8DFF83FFFFFF70FF59 -:101F900047FF90FFFFFF00FF00FF48FFFFFF04FF28 -:101FA000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF29 -:101FB00025FF40FFFFFF80FFFFFF93FFFFFFF0FFC4 -:101FC0008DFF83FFFFFF70FF47FF90FFFFFF00FFC4 -:101FD00000FF48FFFFFF04FFA0FF23FFFFFF0FFFED -:101FE00046FF90FFFFFF6AFFE9FF41FFFFFF80FF11 -:101FF000FFFF93FFFFFFF0FF8DFF83FFFFFF70FFE9 -:1020000047FF90FFFFFF00FF00FF48FFFFFF04FFB7 -:10201000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFB8 -:10202000EDFF41FFFFFF80FFFFFF93FFFFFFF0FF8A -:102030008DFF83FFFFFF70FF47FF90FFFFFF00FF53 -:1020400000FF48FFFFFF04FFA0FF23FFFFFF0FFF7C -:1020500046FF90FFFFFF6AFF00FF40FFFFFF00FF0A -:1020600044FF90FFFFFF60FF00FF00FFFFFF00FF46 -:1020700000FF00FFFFFF00FF00FF00FFFFFF00FF6A -:1020800000FF00FFFFFF00FFF1FF41FFFFFF80FFA8 -:10209000FFFF93FFFFFFF0FF46FF84FFFFFF00FFFE -:1020A00000FF34FFFFFF08FF00FF60FFFFFF03FF9B -:1020B00000FF00FFFFFF00FF00FF00FFFFFF00FF2A -:1020C00000FF00FFFFFF00FF00FF00FFFFFF00FF1A -:1020D00046FF90FFFFFF60FFF7FF4FFFFFFFF4FF9A -:1020E00046FF90FFFFFF74FF8DFF83FFFFFF70FF30 -:1020F00047FF90FFFFFF00FF00FF48FFFFFF04FFC7 -:10210000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFC7 -:1021100000FF0CFFFFFF20FF00FF0AFFFFFF1FFF74 -:1021200046FF84FFFFFF00FF00FF34FFFFFF08FFB3 -:1021300000FF34FFFFFF06FF00FF00FFFFFF00FF6F -:1021400000FF00FFFFFF00FF00FF00FFFFFF00FF99 -:1021500000FF00FFFFFF00FF46FF80FFFFFF10FFB3 -:1021600000FF00FFFFFF00FF00FF00FFFFFF00FF79 -:1021700000FF00FFFFFF00FF00FF00FFFFFF00FF69 -:1021800000FF68FFFFFF02FF00FF00FFFFFF00FFEF -:1021900000FF00FFFFFF00FF00FF00FFFFFF00FF49 -:1021A00000FF00FFFFFF00FF00FF60FFFFFF22FFB7 -:1021B00000FF00FFFFFF00FF00FF00FFFFFF00FF29 -:1021C00000FF00FFFFFF00FF00FF00FFFFFF00FF19 -:1021D00046FF90FFFFFF62FFF7FF4FFFFFFFF4FF97 -:1021E00046FF90FFFFFF74FF8DFF83FFFFFF70FF2F -:1021F00047FF90FFFFFF00FF00FF48FFFFFF04FFC6 -:10220000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFC6 -:1022100000FF0CFFFFFF20FF00FF0AFFFFFF1FFF73 -:1022200046FF88FFFFFF00FF00FF38FFFFFF08FFAA -:1022300000FF50FFFFFF03FF00FF00FFFFFF00FF55 -:1022400000FF00FFFFFF00FF00FF00FFFFFF00FF98 -:1022500000FF00FFFFFF00FF46FF90FFFFFF60FF52 -:10226000F7FF4FFFFFFFF4FF46FF90FFFFFF74FFF4 -:102270008DFF83FFFFFF70FF47FF90FFFFFF00FF11 -:1022800000FF48FFFFFF04FFA0FF23FFFFFF0FFF3A -:1022900046FF90FFFFFF6AFF00FF0CFFFFFF20FFDC -:1022A00000FF0AFFFFFF1FFF46FF88FFFFFF00FF41 -:1022B00000FF38FFFFFF08FF00FF38FFFFFF04FFAC -:1022C00000FF00FFFFFF00FF00FF00FFFFFF00FF18 -:1022D00000FF00FFFFFF00FF00FF00FFFFFF00FF08 -:1022E00046FF80FFFFFF10FF00FF58FFFFFF03FFC7 -:1022F00000FF50FFFFFF23FF00FF00FFFFFF00FF75 -:1023000000FF00FFFFFF00FF00FF00FFFFFF00FFD7 -:1023100000FF00FFFFFF00FF46FF90FFFFFF62FF8F -:10232000F7FF4FFFFFFFF4FF46FF90FFFFFF74FF33 -:102330008DFF83FFFFFF70FF47FF90FFFFFF00FF50 -:1023400000FF48FFFFFF04FFA0FF23FFFFFF0FFF79 -:1023500046FF90FFFFFF6AFF00FF0CFFFFFF20FF1B -:1023600000FF0AFFFFFF1FFF46FF80FFFFFF00FF88 -:10237000FFFF93FFFFFFE0FFFFFF83FFFFFFE2FF91 -:1023800046FF90FFFFFF62FFF7FF4FFFFFFFF4FFE5 -:1023900046FF90FFFFFF74FF8DFF83FFFFFF70FF7D -:1023A00047FF90FFFFFF00FF00FF48FFFFFF04FF14 -:1023B000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF15 -:1023C00000FF0CFFFFFF20FF00FF0AFFFFFF1FFFC2 -:1023D00003FF0DFFFFFF0FFF00FF00FFFFFF00FFE8 -:1023E00000FF00FFFFFF00FF00FF00FFFFFF00FFF7 -:1023F00000FF00FFFFFF00FF46FF90FFFFFF60FFB1 -:102400000CFF0DFFFFFFF0FF00FF00FFFFFF00FFCD -:1024100000FF00FFFFFF00FF00FF00FFFFFF00FFC6 -:1024200000FF00FFFFFF00FFF7FF4FFFFFFFF4FF7C -:1024300046FF90FFFFFF74FF8DFF83FFFFFF70FFDC -:1024400047FF90FFFFFF00FF00FF48FFFFFF04FF73 -:10245000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF74 -:1024600000FF0CFFFFFF20FF00FF0AFFFFFF1FFF21 -:1024700046FF80FFFFFF02FF00FF00FFFFFF00FF9E -:1024800000FF00FFFFFF00FF00FF00FFFFFF00FF56 -:1024900000FF00FFFFFF00FF00FF00FFFFFF00FF46 -:1024A00000FF00FFFFFF00FF00FF00FFFFFF00FF36 -:1024B00000FF00FFFFFF00FF46FF80FFFFFF13FF4D -:1024C00000FF40FFFFFF00FF11FF90FFFFFF60FFD5 -:1024D0008DFF93FFFFFFD0FF11FF90FFFFFFF2FF83 -:1024E00011FF90FFFFFFE3FFF7FF4FFFFFFFF4FF38 -:1024F00046FF90FFFFFF74FF8DFF83FFFFFF70FF1C -:1025000047FF90FFFFFF00FF00FF48FFFFFF04FFB2 -:10251000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFB3 -:1025200000FF0CFFFFFF20FF00FF0AFFFFFF1FFF60 -:1025300046FF84FFFFFF00FF00FF34FFFFFF08FF9F -:1025400000FF34FFFFFF06FF00FF00FFFFFF00FF5B -:1025500000FF00FFFFFF00FF00FF00FFFFFF00FF85 -:1025600000FF00FFFFFF00FF46FF80FFFFFF10FF9F -:10257000FFFF93FFFFFFE0FF00FF60FFFFFF22FF71 -:1025800067FF40FFFFFF40FFFFFF93FFFFFFE0FFFC -:1025900000FF00FFFFFF00FF00FF00FFFFFF00FF45 -:1025A00000FF00FFFFFF00FF00FF00FFFFFF00FF35 -:1025B00046FF90FFFFFF62FFF7FF4FFFFFFFF4FFB3 -:1025C00046FF90FFFFFF74FF8DFF83FFFFFF70FF4B -:1025D00047FF90FFFFFF00FF00FF48FFFFFF04FFE2 -:1025E000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFE3 -:1025F00000FF0CFFFFFF20FF00FF0AFFFFFF1FFF90 -:1026000046FF84FFFFFF00FF00FF34FFFFFF08FFCE -:1026100000FF34FFFFFF06FF00FF00FFFFFF00FF8A -:1026200000FF00FFFFFF00FF46FF80FFFFFF10FFDE -:1026300000FF00FFFFFF00FF00FF00FFFFFF00FFA4 -:1026400000FF00FFFFFF00FF00FF00FFFFFF00FF94 -:1026500046FF80FFFFFF23FFFFFF93FFFFFFE0FF29 -:1026600000FF68FFFFFF32FF00FF60FFFFFF72FF08 -:1026700067FF40FFFFFF40FFFFFF93FFFFFFE0FF0B -:1026800000FF00FFFFFF00FF00FF00FFFFFF00FF54 -:1026900000FF00FFFFFF00FF00FF00FFFFFF00FF44 -:1026A00046FF90FFFFFF67FFF7FF4FFFFFFFF4FFBD -:1026B00046FF90FFFFFF74FF8DFF83FFFFFF70FF5A -:1026C00047FF90FFFFFF00FF00FF48FFFFFF04FFF1 -:1026D000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFF2 -:1026E00000FF0CFFFFFF20FF00FF0AFFFFFF1FFF9F -:1026F00046FF80FFFFFF05FF03FF0DFFFFFF0FFFFA -:1027000000FF00FFFFFF00FF00FF00FFFFFF00FFD3 -:1027100000FF00FFFFFF00FF00FF00FFFFFF00FFC3 -:102720000CFF0DFFFFFFF5FF00FF00FFFFFF00FFA5 -:1027300000FF00FFFFFF00FF00FF00FFFFFF00FFA3 -:1027400000FF00FFFFFF00FFF7FF4FFFFFFFF4FF59 -:1027500046FF90FFFFFF74FF8DFF83FFFFFF70FFB9 -:1027600047FF90FFFFFF00FF00FF48FFFFFF04FF50 -:10277000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF51 -:1027800000FF0CFFFFFF20FF00FF0AFFFFFF1FFFFE -:1027900046FF80FFFFFF00FF8DFF93FFFFFFC0FF9D -:1027A0008DFF83FFFFFFC7FF46FF90FFFFFF67FF1F -:1027B000F7FF4FFFFFFFF4FF46FF90FFFFFF74FF9F -:1027C0008DFF83FFFFFF70FF47FF90FFFFFF00FFBC -:1027D00000FF48FFFFFF04FFA0FF23FFFFFF0FFFE5 -:1027E00046FF90FFFFFF6AFF00FF0CFFFFFF20FF87 -:1027F00000FF0AFFFFFF1FFF46FF80FFFFFF00FFF4 -:102800008DFF93FFFFFFE0FF8DFF83FFFFFFE7FFDB -:1028100000FF00FFFFFF00FF00FF00FFFFFF00FFC2 -:1028200000FF00FFFFFF00FF00FF00FFFFFF00FFB2 -:1028300046FF90FFFFFF67FFF7FF4FFFFFFFF4FF2B -:1028400046FF90FFFFFF74FF8DFF83FFFFFF70FFC8 -:1028500047FF90FFFFFF00FF00FF48FFFFFF04FF5F -:10286000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF60 -:1028700000FF0CFFFFFF20FF00FF0AFFFFFF1FFF0D -:102880008DFF83FFFFFFD0FF00FF40FFFFFF24FF0E -:10289000A0FF23FFFFFF0FFF11FF90FFFFFF6AFF65 -:1028A00000FF40FFFFFF14FF18FF23FFFFFF0FFF94 -:1028B00051FF14FFFFFF81FF90FF80FFFFFF60FFCC -:1028C00080FF23FFFFFF0FFF8DFF83FFFFFFD0FF80 -:1028D00000FF40FFFFFF14FFA0FF23FFFFFF0FFFDC -:1028E00011FF90FFFFFF6AFF30FF0CFFFFFF00FFAB -:1028F00000FF40FFFFFF16FF10FF40FFFFFF07FF35 -:1029000090FF34FFFFFF71FF00FF34FFFFFF09FF5F -:102910000FFF40FFFFFFF5FF00FF60FFFFFF07FF16 -:1029200088FF63FFFFFF27FFE8FF60FFFFFF07FF50 -:1029300062FF61FFFFFF27FF88FF2BFFFFFF8BFF79 -:10294000E8FF60FFFFFF07FF62FF61FFFFFF17FF68 -:1029500088FF2FFFFFFFFBFF89FF23FFFFFF0FFF14 -:1029600098FF20FFFFFF0FFFEAFF20FFFFFF0FFF91 -:1029700000FF0DFFFFFFABFF00FF0DFFFFFFB8FFE4 -:1029800000FF0DFFFFFFCFFF62FF21FFFFFF0FFFE3 -:1029900010FF22FFFFFF0FFF62FF21FFFFFF0FFF6E -:1029A00000FF40FFFFFF24FF90FF80FFFFFF60FF5D -:1029B00080FF23FFFFFF0FFF51FF18FFFFFF00FF06 -:1029C0008BFF93FFFFFFEBFF8BFF93FFFFFFFCFFEE -:1029D00000FF0AFFFFFF0FFF51FF1CFFFFFF0FFF6C -:1029E0008DFF93FFFFFFACFF82FF3CFFFFFF45FF22 -:1029F00054FF14FFFFFF2EFFFFFF3FFFFFFFF5FF18 -:102A000054FF14FFFFFF1EFF00FF00FFFFFF00FF4A -:102A100000FF00FFFFFF00FF51FF1CFFFFFF0FFF44 -:102A200000FF0DFFFFFF0CFF8DFF83FFFFFFA4FFE3 -:102A3000E0FF22FFFFFF0FFF53FF18FFFFFFB3FF71 -:102A40008DFF83FFFFFFD0FF00FF40FFFFFF24FF4C -:102A5000A0FF23FFFFFF0FFF00FF0DFFFFFFBAFFE7 -:102A60008BFF83FFFFFFF5FF11FF90FFFFFF6BFF61 -:102A700000FF40FFFFFF14FF18FF23FFFFFF0FFFC2 -:102A800055FF14FFFFFF21FF90FF80FFFFFF60FF56 -:102A900080FF23FFFFFF0FFF00FF40FFFFFF20FF2E -:102AA00000FF40FFFFFF01FF8BFF83FFFFFFE4FFFD -:102AB0008BFF83FFFFFFF5FF08FF0CFFFFFF00FF09 -:102AC00060FF22FFFFFF0FFF49FF2AFFFFFFEAFF22 -:102AD00000FF0DFFFFFF4EFF8BFF93FFFFFFEEFF99 -:102AE00000FF0DFFFFFF5AFF8BFF93FFFFFFFAFF71 -:102AF0008DFF83FFFFFF20FF8DFF83FFFFFF31FF6F -:102B0000E0FF22FFFFFF0FFFC9FF2AFFFFFFEAFFE1 -:102B100054FF18FFFFFFD5FF00FF0DFFFFFF4EFF23 -:102B200000FF0DFFFFFF5AFF82FF4FFFFFFFF0FF87 -:102B3000FFFF4FFFFFFFF1FFE0FF22FFFFFF0FFF4F -:102B4000C9FF2AFFFFFFEAFF56FF18FFFFFFB4FF90 -:102B500054FF18FFFFFFDFFF00FF40FFFFFF20FFD4 -:102B600047FF90FFFFFF20FF0CFF0CFFFFFF00FF60 -:102B700002FF40FFFFFF60FF11FF90FFFFFF20FFFC -:102B800016FF18FFFFFF4FFF8DFF83FFFFFFD0FFF2 -:102B900000FF40FFFFFF24FFA0FF23FFFFFF0FFF09 -:102BA00011FF90FFFFFF6AFF00FF40FFFFFF14FFD0 -:102BB00018FF23FFFFFF0FFF57FF14FFFFFF91FFD9 -:102BC00090FF80FFFFFF60FF80FF23FFFFFF0FFFED -:102BD0008DFF83FFFFFFD0FF00FF40FFFFFF14FFCB -:102BE000A0FF23FFFFFF0FFF11FF90FFFFFF6AFF12 -:102BF00030FF0CFFFFFF00FF00FF40FFFFFF16FF4D -:102C000010FF40FFFFFF07FF90FF34FFFFFF71FF42 -:102C100000FF34FFFFFF09FF0FFF40FFFFFFF5FF3D -:102C200000FF60FFFFFF07FF88FF63FFFFFF27FF35 -:102C3000E8FF60FFFFFF07FF62FF61FFFFFF27FF65 -:102C400088FF2BFFFFFF8BFFE8FF60FFFFFF07FF01 -:102C500062FF61FFFFFF17FF88FF2FFFFFFFFBFFF2 -:102C600089FF23FFFFFF0FFF98FF20FFFFFF0FFFEC -:102C7000EAFF20FFFFFF0FFF00FF0DFFFFFFABFF8D -:102C800000FF0DFFFFFFB8FF00FF0DFFFFFFCFFFAD -:102C900062FF21FFFFFF0FFF10FF22FFFFFF0FFF6B -:102CA00062FF21FFFFFF0FFF00FF40FFFFFF24FF38 -:102CB00090FF80FFFFFF60FF80FF23FFFFFF0FFFFC -:102CC00057FF18FFFFFF10FF8BFF93FFFFFFEBFF86 -:102CD0008BFF93FFFFFFFCFF5CFF1CFFFFFF3FFF2D -:102CE00000FF0AFFFFFF0FFF57FF1CFFFFFF1FFF43 -:102CF0008DFF93FFFFFFACFF82FF3CFFFFFF45FF0F -:102D00005AFF14FFFFFF4EFFFFFF3FFFFFFFF5FFDE -:102D10005AFF14FFFFFF3EFF00FF00FFFFFF00FF11 -:102D200000FF00FFFFFF00FF57FF1CFFFFFF1FFF1B -:102D300000FF0DFFFFFF0CFF8DFF83FFFFFFA4FFD0 -:102D4000E0FF22FFFFFF0FFF59FF18FFFFFFD3FF38 -:102D50005CFF1CFFFFFF3FFF8DFF83FFFFFFD0FFE6 -:102D600000FF40FFFFFF24FFA0FF23FFFFFF0FFF37 -:102D700000FF0DFFFFFFBAFF8BFF83FFFFFFF5FF93 -:102D80005CFF1CFFFFFF3FFF11FF90FFFFFF6BFF8A -:102D900000FF40FFFFFF14FF18FF23FFFFFF0FFF9F -:102DA0005BFF14FFFFFF61FF90FF80FFFFFF60FFED -:102DB00080FF23FFFFFF0FFF00FF40FFFFFF20FF0B -:102DC00000FF40FFFFFF01FF8BFF83FFFFFFE4FFDA -:102DD0008BFF83FFFFFFF5FF08FF0CFFFFFF00FFE6 -:102DE00060FF22FFFFFF0FFF49FF2AFFFFFFEAFFFF -:102DF00000FF0DFFFFFF4EFF8BFF93FFFFFFEEFF76 -:102E00008BFF93FFFFFFFAFF5EFF1CFFFFFF0FFF2B -:102E10005BFF18FFFFFF0FFF8BFF83FFFFFF20FF0C -:102E200078FF22FFFFFF0FFF0DFF18FFFFFF05FFD9 -:102E300000FF0AFFFFFF0FFF08FF0CFFFFFF00FF6F -:102E400000FF40FFFFFF14FF00FF40FFFFFF05FFF3 -:102E50008BFF83FFFFFFE0FF8BFF83FFFFFFF1FF8F -:102E600060FF22FFFFFF0FFF49FF2AFFFFFFEAFF7E -:102E70008BFF93FFFFFFFAFF8BFF93FFFFFFEEFF38 -:102E80000CFF0CFFFFFF00FF00FF0AFFFFFF0FFF1B -:102E900008FF0CFFFFFF00FF00FF40FFFFFF14FFD4 -:102EA00000FF40FFFFFF05FF8BFF83FFFFFFE0FFF9 -:102EB0008BFF83FFFFFFF1FF60FF22FFFFFF0FFF8C -:102EC00049FF2AFFFFFFEAFF8BFF93FFFFFFFAFF97 -:102ED0008BFF93FFFFFFEEFF0CFF0CFFFFFF00FFD8 -:102EE0008DFF83FFFFFF40FF78FF22FFFFFF0FFFF3 -:102EF0005EFF1CFFFFFF04FF00FF0AFFFFFF0FFF45 -:102F000008FF0CFFFFFF00FF8DFF83FFFFFF50FF57 -:102F100078FF22FFFFFF0FFF5FFF1CFFFFFF54FF43 -:102F20000FFF40FFFFFFF5FF90FF80FFFFFFA8FFAF -:102F300010FF0FFFFFFF08FF90FF80FFFFFF90FFD4 -:102F400088FF27FFFFFF0FFFB6FF27FFFFFF0FFFE1 -:102F50008BFF83FFFFFFFAFFF2FF22FFFFFF0FFF50 -:102F600000FF0DFFFFFF0AFF00FF40FFFFFF14FF00 -:102F7000E2FF22FFFFFF0FFF74FF18FFFFFFE2FFDA -:102F800038FF23FFFFFF0FFF00FF40FFFFFF24FF7D -:102F9000E2FF22FFFFFF0FFF74FF18FFFFFFE2FFBA -:102FA00000FF0AFFFFFF0FFF0FFF40FFFFFFF5FFCE -:102FB00090FF80FFFFFF80FF8BFF83FFFFFFE2FF9B -:102FC00088FF27FFFFFF0FFF98FF20FFFFFF0FFF86 -:102FD00010FF40FFFFFF07FFE8FF20FFFFFF0FFF8D -:102FE00000FF0DFFFFFFACFFF2FF22FFFFFF0FFF0F -:102FF00000FF0DFFFFFF0AFF01FF40FFFFFF04FF7F -:10300000E2FF22FFFFFF0FFF74FF18FFFFFFE2FF49 -:1030100038FF23FFFFFF0FFF02FF40FFFFFF04FF0A -:10302000E2FF22FFFFFF0FFF74FF18FFFFFFE2FF29 -:1030300000FF0AFFFFFF0FFF00FF34FFFFFF08FF45 -:1030400000FF34FFFFFFD4FF00FF34FFFFFF85FFC9 -:10305000FFFF4FFFFFFF89FF00FF09FFFFFF01FF99 -:1030600089FF83FFFFFFB8FF00FF0EFFFFFF0FFF89 -:1030700000FF0DFFFFFF4EFFA7FF23FFFFFF0FFF26 -:1030800000FF68FFFFFFA3FF89FF83FFFFFFA8FF8B -:1030900000FF0EFFFFFF0FFF00FF0DFFFFFF4EFFC2 -:1030A000A7FF23FFFFFF0FFF00FF68FFFFFFA3FF46 -:1030B00000FF09FFFFFF03FF8BFF83FFFFFFB0FF50 -:1030C00000FF68FFFFFF00FF00FF0AFFFFFF0FFF89 -:1030D00002FF35FFFFFF00FF00FF34FFFFFF08FF87 -:1030E00000FF34FFFFFF26FF89FF83FFFFFFD8FFAC -:1030F00000FF0EFFFFFF0FFF00FF0DFFFFFF4EFF62 -:10310000A7FF23FFFFFF0FFF00FF68FFFFFFA3FFE5 -:1031100089FF83FFFFFFC8FF00FF0EFFFFFF0FFFC8 -:1031200000FF0DFFFFFF4EFFA7FF23FFFFFF0FFF75 -:1031300000FF68FFFFFFA3FF00FF09FFFFFF03FF82 -:103140008BFF83FFFFFFD0FF00FF68FFFFFF02FF41 -:1031500001FF40FFFFFF80FF00FF68FFFFFF02FF4E -:1031600000FF40FFFFFF20FF00FF68FFFFFF03FF9E -:1031700000FF0AFFFFFF0FFF00FF40FFFFFF10FFF0 -:103180008BFF93FFFFFF40FF30FF40FFFFFF00FF7B -:1031900049FF90FFFFFF40FF00FF0AFFFFFF0FFF07 -:1031A00000FF40FFFFFF60FF00FF91FFFFFFF0FF08 -:1031B00000FF0AFFFFFF0FFF01FF42FFFFFF80FF3D -:1031C00000FF91FFFFFF70FF07FF42FFFFFF80FF3F -:1031D00003FF91FFFFFF70FF02FF42FFFFFF00FFB1 -:1031E00000FF91FFFFFFF0FF08FF42FFFFFF00FF1E -:1031F00003FF91FFFFFFF0FF00FF40FFFFFF20FFF5 -:1032000001FF91FFFFFF70FF00FF40FFFFFF20FF66 -:1032100004FF91FFFFFF70FF00FF0AFFFFFF0FFF9A -:1032200004FF42FFFFFF00FF49FF90FFFFFF20FF69 -:1032300062FF1CFFFFFFFFFF00FF0AFFFFFF0FFF02 -:1032400000FF40FFFFFF20FF00FF91FFFFFFF0FFA7 -:1032500001FF42FFFFFF00FF49FF90FFFFFF20FF3C -:1032600062FF1CFFFFFFFFFF00FF0AFFFFFF0FFFD2 -:1032700000FF40FFFFFF40FF8BFF93FFFFFF80FF3A -:1032800005FF35FFFFFF00FF92FF3BFFFFFF00FF41 -:1032900000FF34FFFFFF08FF00FF38FFFFFF08FFBC -:1032A00000FF3CFFFFFF65FF65FF14FFFFFF9EFF70 -:1032B00000FF60FFFFFF03FF00FF60FFFFFF13FF42 -:1032C00000FF78FFFFFF13FF00FF78FFFFFF03FF02 -:1032D00001FF42FFFFFF00FF49FF90FFFFFF20FFBC -:1032E00062FF1CFFFFFFFFFF05FF81FFFFFFC0FF25 -:1032F00078FF22FFFFFF0FFF21FF18FFFFFF71FF85 -:1033000000FF0AFFFFFF0FFF49FF80FFFFFF48FF9D -:1033100010FF0FFFFFFF03FF66FF23FFFFFF0FFFFD -:1033200074FF18FFFFFF54FF86FF83FFFFFFC0FFFE -:1033300049FF90FFFFFF20FF62FF1CFFFFFFFFFF21 -:1033400086FF83FFFFFF80FF01FF40FFFFFF04FFB9 -:10335000E0FF22FFFFFF0FFF86FF93FFFFFF8AFFC3 -:1033600067FF1CFFFFFF00FF86FF87FFFFFFD0FF07 -:1033700075FF1CFFFFFF1FFF00FF0AFFFFFF0FFF8E -:1033800000FF48FFFFFF00FF82FF93FFFFFF40FFAA -:1033900000FF0AFFFFFF0FFF08FF0CFFFFFF00FF0A -:1033A00086FF8BFFFFFFB0FF00FF38FFFFFF08FF26 -:1033B00000FF38FFFFFFF4FFFFFF4FFFFFFF89FF14 -:1033C0008DFF83FFFFFF60FF89FF83FFFFFF44FF47 -:1033D00000FF40FFFFFF01FF89FF83FFFFFF55FF55 -:1033E00060FF26FFFFFF0FFF49FF22FFFFFF0FFFD8 -:1033F00000FF78FFFFFFA3FF10FF22FFFFFF0FFF7B -:1034000000FF78FFFFFFA0FF8DFF83FFFFFF60FF3E -:1034100089FF83FFFFFF24FF00FF40FFFFFF01FF45 -:1034200089FF83FFFFFF35FF60FF26FFFFFF0FFFD0 -:1034300049FF22FFFFFF0FFF00FF78FFFFFFA3FF01 -:1034400010FF22FFFFFF0FFF00FF78FFFFFFA3FF2A -:103450008DFF83FFFFFF60FF20FF40FFFFFF04FFA2 -:1034600060FF22FFFFFF0FFF8DFF93FFFFFF6AFF4B -:103470000CFF0CFFFFFF00FF00FF0AFFFFFF0FFF25 -:1034800008FF0CFFFFFF00FF86FF87FFFFFFB0FF75 -:1034900000FF34FFFFFF08FF01FF34FFFFFF04FFC1 -:1034A00000FF34FFFFFF35FFFFFF4FFFFFFF89FFE6 -:1034B00000FF09FFFFFF01FF87FF8BFFFFFFE0FF1A -:1034C00000FF38FFFFFF88FF00FF70FFFFFF03FFD3 -:1034D00000FF68FFFFFF00FF00FF70FFFFFF03FF1B -:1034E00000FF68FFFFFF03FF87FF9BFFFFFFE0FF79 -:1034F0000CFF0CFFFFFF00FF00FF0AFFFFFF0FFFA5 -:1035000001FF3CFFFFFF05FF6AFF14FFFFFF9EFF67 -:1035100067FF1CFFFFFF3FFF69FF1CFFFFFF0FFF5F -:1035200066FF1CFFFFFF1FFF38FF22FFFFFF0FFF9B -:103530006AFF14FFFFFF85FF8BFF83FFFFFF40FF44 -:1035400078FF22FFFFFF0FFF00FF00FFFFFF00FFDC -:1035500000FF0AFFFFFF0FFF82FF83FFFFFF40FF17 -:1035600078FF22FFFFFF0FFF6AFF1CFFFFFFF4FF42 -:1035700000FF0AFFFFFF0FFF00FF40FFFFFF10FFEC -:1035800047FF90FFFFFF20FF87FF83FFFFFFF0FF54 -:1035900086FF93FFFFFF80FF00FF40FFFFFF00FF5C -:1035A0008DFF93FFFFFF60FF82FF93FFFFFF40FF50 -:1035B00086FF87FFFFFF90FF02FF34FFFFFF08FF3A -:1035C00000FF60FFFFFF03FF89FF93FFFFFF20FF66 -:1035D00000FF60FFFFFF03FF89FF93FFFFFF30FF46 -:1035E00000FF60FFFFFF03FF89FF93FFFFFF40FF26 -:1035F00000FF60FFFFFF03FF89FF93FFFFFF50FF06 -:1036000086FF97FFFFFF90FF00FF0AFFFFFF0FFFFE -:1036100000FF34FFFFFF64FF00FF34FFFFFF35FFB3 -:1036200001FF34FFFFFF96FF00FF38FFFFFF34FF6D -:1036300000FF38FFFFFF65FF01FF38FFFFFF96FF28 -:1036400000FF38FFFFFF08FF02FF34FFFFFF49FFC5 -:1036500002FF38FFFFFF49FF10FF40FFFFFF06FF9B -:1036600010FF40FFFFFF02FF30FF0CFFFFFF00FFD6 -:1036700000FF3CFFFFFF25FF6DFF14FFFFFFBEFFB4 -:1036800098FF50FFFFFF73FF88FF50FFFFFF73FF9E -:1036900083FF68FFFFFFC5FF88FF68FFFFFFC4FFD0 -:1036A00083FF68FFFFFFC5FF00FF68FFFFFFC6FF46 -:1036B00098FF50FFFFFF73FF88FF50FFFFFF73FF6E -:1036C00083FF78FFFFFFC4FF88FF78FFFFFFC5FF80 -:1036D00083FF78FFFFFFC4FF00FF78FFFFFFC6FFF7 -:1036E00098FF50FFFFFF73FF88FF50FFFFFF73FF3E -:1036F00083FF68FFFFFFC5FF88FF68FFFFFFC4FF70 -:1037000083FF68FFFFFFC5FF00FF68FFFFFFC6FFE5 -:1037100000FF3CFFFFFF25FF6EFF14FFFFFF8EFF42 -:1037200098FF50FFFFFF73FF88FF50FFFFFF73FFFD -:1037300083FF78FFFFFFC4FF88FF78FFFFFFC4FF10 -:1037400000FF78FFFFFFC4FF20FF0CFFFFFF00FF1B -:1037500000FF0AFFFFFF0FFF00FF34FFFFFFE9FF3D -:1037600001FF38FFFFFF28FF01FF38FFFFFF29FFA0 -:1037700000FF38FFFFFF66FF00FF38FFFFFF34FF49 -:1037800000FF38FFFFFF75FF10FF40FFFFFF06FF40 -:1037900000FF41FFFFFF07FF30FF0CFFFFFF00FFAF -:1037A00098FF70FFFFFF20FF00FF3CFFFFFF25FF9A -:1037B00070FF14FFFFFF2EFF80FF70FFFFFF42FF2F -:1037C00063FF72FFFFFF20FF80FF68FFFFFFA7FF7F -:1037D00000FF70FFFFFF41FF63FF72FFFFFF24FF49 -:1037E00080FF68FFFFFFA7FF00FF70FFFFFF46FF9E -:1037F00063FF72FFFFFF24FF80FF68FFFFFFA7FF4B -:1038000000FF70FFFFFF45FF63FF72FFFFFF20FF18 -:1038100000FF68FFFFFFA7FF80FF70FFFFFF42FF71 -:1038200063FF72FFFFFF20FF80FF70FFFFFF41FF7C -:1038300063FF6AFFFFFFA7FF00FF70FFFFFF24FF8A -:1038400080FF68FFFFFFA7FF00FF70FFFFFF44FF3F -:1038500063FF72FFFFFF24FF80FF68FFFFFFA7FFEA -:10386000F0FF40FFFFFF05FF00FF4FFFFFFF04FFDA -:1038700000FF0DFFFFFF0BFF80FF27FFFFFF0FFF84 -:1038800088FF23FFFFFF0FFFEAFF20FFFFFF0FFF6F -:1038900074FF22FFFFFF0FFF00FF68FFFFFFA7FF7E -:1038A00000FF70FFFFFF24FF80FF70FFFFFF44FF5A -:1038B00063FF72FFFFFF24FF80FF68FFFFFFA7FF8A -:1038C00000FF4FFFFFFF04FF00FF0DFFFFFF0BFF97 -:1038D00080FF27FFFFFF0FFF88FF23FFFFFF0FFF82 -:1038E000EAFF20FFFFFF0FFF74FF22FFFFFF0FFF24 -:1038F00000FF68FFFFFFA7FF00FF0AFFFFFF0FFFAA -:1039000038FF22FFFFFF0FFF72FF14FFFFFF35FF9D -:103910008BFF83FFFFFF30FF78FF22FFFFFF0FFFCA -:1039200000FF0AFFFFFF0FFF0EFF40FFFFFF00FF3A -:1039300010FF90FFFFFF10FF08FF40FFFFFF00FF99 -:1039400010FF90FFFFFF90FF02FF40FFFFFF40FFCF -:1039500011FF90FFFFFF20FF00FF40FFFFFF00FF70 -:1039600010FF90FFFFFFB0FFB0FF40FFFFFF00FF21 -:1039700047FF90FFFFFF50FF30FF40FFFFFF00FFBA -:1039800047FF90FFFFFF40FF78FF42FFFFFF50FF20 -:1039900048FF90FFFFFFA0FF40FF40FFFFFF00FF39 -:1039A00049FF90FFFFFF70FF18FF40FFFFFF00FF80 -:1039B00047FF90FFFFFF70FF18FF40FFFFFF10FF62 -:1039C00047FF90FFFFFF70FF18FF40FFFFFF00FF62 -:1039D00047FF90FFFFFF70FF00FF40FFFFFF00FF6A -:1039E00011FF90FFFFFF60FF8DFF93FFFFFFD0FFF0 -:1039F0000BFF40FFFFFF80FF11FF90FFFFFFF0FF75 -:103A000000FF40FFFFFF10FF11FF90FFFFFFE0FFEF -:103A100000FF48FFFFFF00FF00FF93FFFFFF00FFD5 -:103A200000FF0AFFFFFF0FFF08FF40FFFFFF00FF3F -:103A300047FF90FFFFFF20FF22FF18FFFFFF9FFFC0 -:103A400000FF48FFFFFF10FF86FF93FFFFFF70FF9F -:103A500022FF18FFFFFF9FFF00FF48FFFFFF00FF4F -:103A600086FF93FFFFFF70FF22FF18FFFFFF9FFFFE -:103A700000FF48FFFFFF20FF86FF93FFFFFF70FF5F -:103A800022FF18FFFFFF9FFF00FF34FFFFFF48FFEB -:103A900000FF60FFFFFF03FF86FF93FFFFFFB0FF04 -:103AA00000FF60FFFFFF03FF86FF93FFFFFFC0FFE4 -:103AB00086FF97FFFFFFD0FF00FF0AFFFFFF0FFF0A -:103AC00080FF37FFFFFF02FF84FF3BFFFFFF02FF86 -:103AD00000FF60FFFFFF0BFF0CFF0DFFFFFF90FFDC -:103AE00000FF70FFFFFF0BFF0CFF0DFFFFFFB0FF9C -:103AF00088FF37FFFFFF03FF8CFF3BFFFFFF03FF44 -:103B000000FF40FFFFFF01FF8BFF93FFFFFF51FF0F -:103B100082FF43FFFFFF80FF8BFF93FFFFFF60FFEC -:103B200000FF34FFFFFF89FF00FF40FFFFFF00FFA2 -:103B30000CFF0DFFFFFF80FF0CFF0DFFFFFFA0FF3D -:103B400000FF0AFFFFFF0FFF80FF37FFFFFF00FFAF -:103B500000FF34FFFFFF08FF02FF3CFFFFFF45FFB0 -:103B600076FF14FFFFFFDEFF00FFA0FFFFFF03FF54 -:103B700084FF37FFFFFF00FF00FF34FFFFFF08FF58 -:103B800002FF3CFFFFFF45FF77FF14FFFFFF2EFF03 -:103B900000FFA0FFFFFF03FF7EFF38FFFFFF00FFD6 -:103BA00000FF38FFFFFF08FF00FF3CFFFFFFE5FFBE -:103BB00077FF14FFFFFF8EFF00FF40FFFFFF00FFB6 -:103BC00000FF58FFFFFF03FF00FF0AFFFFFF0FFF8B -:103BD00064FF1CFFFFFF4FFF38FF22FFFFFF0FFFB7 -:103BE00077FF14FFFFFFE5FF8BFF83FFFFFF40FF21 -:103BF00078FF22FFFFFF0FFF64FF1CFFFFFF8FFF17 -:103C000038FF22FFFFFF0FFF78FF14FFFFFF35FF94 -:103C10008BFF83FFFFFF40FF78FF22FFFFFF0FFFB7 -:103C200000FF0AFFFFFF0FFF00FF34FFFFFF09FF48 -:103C300000FF34FFFFFF85FF00FF34FFFFFF56FF4B -:103C400000FF09FFFFFF06FF20FF40FFFFFF00FF0F -:103C500001FF40FFFFFFC1FF00FF40FFFFFF44FFE8 -:103C600000FF68FFFFFF05FF00FF68FFFFFF15FF74 -:103C700000FF68FFFFFF05FF00FF68FFFFFF45FF34 -:103C800000FF0AFFFFFF0FFF86FF87FFFFFFF0FF28 -:103C900086FF8BFFFFFFE0FF00FF34FFFFFFC8FF41 -:103CA00000FF38FFFFFFC8FF00FF60FFFFFF03FFBB -:103CB00000FF60FFFFFF13FF00FF78FFFFFF13FF10 -:103CC00000FF78FFFFFF03FF86FF97FFFFFFF0FF76 -:103CD00086FF9BFFFFFFE0FF05FF81FFFFFFC0FFA7 -:103CE00078FF22FFFFFF0FFF21FF18FFFFFF71FF8B -:103CF00000FF0AFFFFFF0FFF7FFF38FFFFFF01FFFD -:103D000000FF38FFFFFF09FF00FF38FFFFFF06FF3E -:103D10007EFF40FFFFFF00FF00FF40FFFFFFB1FFFE -:103D200008FF0CFFFFFF00FF00FF3CFFFFFFC5FF88 -:103D30007AFF14FFFFFFBEFF00FF50FFFFFF46FFAB -:103D4000E1FF22FFFFFF0FFF7AFF1CFFFFFFE0FFF5 -:103D500060FF22FFFFFF0FFF00FF58FFFFFFA7FFDD -:103D60000CFF0CFFFFFF00FF00FF0AFFFFFF0FFF2C -:103D700000FF40FFFFFFC4FF00FF0AFFFFFF0FFF30 -:103D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 -:043D9000FFFFFFFF33 -:00000001FF diff --git a/firmware/matrox/g200_warp.H16 b/firmware/matrox/g200_warp.H16 deleted file mode 100644 index 5064b6f01bb46bf0ff34e40674f307e025364224..0000000000000000000000000000000000000000 --- a/firmware/matrox/g200_warp.H16 +++ /dev/null @@ -1,28 +0,0 @@ -/* - * WARP pipes are named according to the functions they perform, where - * - * - T stands for computation of texture stage 0 - * - T2 stands for computation of both texture stage 0 and texture stage 1 - * - G stands for computation of triangle intensity (Gouraud interpolation) - * - Z stands for computation of Z buffer interpolation - * - S stands for computation of specular highlight - * - A stands for computation of the alpha channel - * - F stands for computation of vertex fog interpolation - */ -/* TGZ */ -:04B8000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9728007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2608015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E803800AEA17C12BBD008000E8008000E8B3689725008000E833C033AF3C274FE9573920E9281960EC2B3220E91D3B20E9B30500E0162820E9233B33AD1E2B20E91C8020E9573620E90080A0E94040D8ECFF80C0E990E200E085FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E884FF0AEA008000E8C941C8EC42E100E082FF20EA008000E8008000E8008000E8C840C0EC008000E87FFF20EA008000E8008000E8008000E871 -/* TGZF */ -:0548000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE91750569F008000E8370F5C9F00E02F20008000E8281960ECB30500E0008000E8233B33AD008000E8172617DF35174FE9008000E8008000E8008000E839374FE92F2F17AF008000E8008000E8008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E078FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E877FF0AEA008000E8C941C8EC42E100E075FF20EA008000E8008000E8008000E8C840C0EC008000E872FF20EA008000E8008000E8008000E8BB -/* TGZA */ -:04E80000000098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97D8007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D444CB6254454B603802AEA17C12BBD2D20252007C044C6B3689725008000E833C033AF3C274FE91F62579F008000E83F3D5D9F00E00720008000E8281960ECB30500E0008000E8233B33AD008000E81F261FDF9D1F4FE9008000E8008000E8008000E89E3F4FE907071FAF008000E8008000E8008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E07AFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E879FF0AEA008000E8C941C8EC42E100E077FF20EA008000E8008000E8008000E8C840C0EC008000E874FF20EA008000E8008000E8008000E8D9 -/* TGZAF */ -:0568000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9838007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26F8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B62D444CB6254454B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE900E0252007C044C61750569F00E02D20370F5C9F00E02F201F62579F00E007203F3D5D9F008000E8008000E8281960ECB30500E0172617DF233B33AD35174FE91F261FDF9D1F4FE99E3F4FE939374FE92F2F17AF008000E807071FAF008000E831804FE9008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E074FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E873FF0AEA008000E8C941C8EC42E100E071FF20EA008000E8008000E8008000E8C840C0EC008000E86EFF20EA008000E8008000E8008000E830 -/* TGZS */ -:05C0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98B8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2778015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F3F2F5D9F00E08F20A5374FE90F170FAF06C021C4008000E8008000E8A3804FE9062000E01F261FDFA11F4FE9A23F4FE9008000E8008000E806061FAF008000E8008000E8008000E8A0804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E06CFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E86BFF0AEA008000E8C941C8EC42E100E069FF20EA008000E8008000E8008000E8C840C0EC008000E866FF20EA008000E8008000E8008000E85C -/* TGZSF */ -:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C63F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82F2000E0A3804FE9062000E01F261FDF172617DF35174FE9A11F4FE9A23F4FE906061FAF39374FE92F2F17AF008000E8A0804FE9008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E8F9 -/* TGZSA */ -:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D444CB6054454B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D200520008000E83F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82FC044C6A3804FE9062000E01F261FDF172617DF9D174FE9A11F4FE9A23F4FE906061FAF00E0AF209E374FE92F172FAFA0804FE9008000E8008000E89C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E883 -/* TGZAF */ -:05B8000000008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9948007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2808015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C62D444CB6254454B63F2F5D9F00E00F202D20252007C044C61750569FA5374FE906C021C40F170FAF370F5C9F008000E81E62579F008000E83E3D5D9F00E007202F2000E0A30F4FE9062000E01F261FDF172617DFA11F4FE91E261EDF9D1E4FE935174FE9A23F4FE906061FAF39374FE92F2F17AF07071EAFA0804FE99E3E4FE931804FE99C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E063FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E862FF0AEA008000E8C941C8EC42E100E060FF20EA008000E8008000E8008000E8C840C0EC008000E85DFF20EA008000E8008000E8008000E8D8 -:0000000001FF diff --git a/firmware/matrox/g400_warp.H16 b/firmware/matrox/g400_warp.H16 deleted file mode 100644 index b432d1074d8d51b6fc3dcde11a7fd1a1d3c92c83..0000000000000000000000000000000000000000 --- a/firmware/matrox/g400_warp.H16 +++ /dev/null @@ -1,44 +0,0 @@ -/* - * WARP pipes are named according to the functions they perform, where - * - * - T stands for computation of texture stage 0 - * - T2 stands for computation of both texture stage 0 and texture stage 1 - * - G stands for computation of triangle intensity (Gouraud interpolation) - * - Z stands for computation of Z buffer interpolation - * - S stands for computation of specular highlight - * - A stands for computation of the alpha channel - * - F stands for computation of vertex fog interpolation - */ -/* TGZ */ -:0338000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900588015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4A8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A444CB0024454B02A444CB21A4454B21D803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A444CB41A4454B439E52C9F383D20E988735EE92A201A202A464EBF1A4656BF31532F9F3E304FE939E52C9F3F384FE90A474FBF024757BF31532F9F3A314FE939E52C9F3B394FE92A434BBF1A4353BF30502E9F36314FE938212C9F37394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AFFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD6FF20EA008000E84E334ECF573B57CF9DFF20EA57C0BFEA0080A0E90000D8EC59 -/* TGZF */ -:0360000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005D8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4F8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E827CF75C63C3D20E90A444CB0024454B02A444CB21A4454B220803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F312720E90A444CB4024454B42A454DB61A4555B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AAFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF98FF20EA57C0BFEA0080A0E90000D8EC90 -/* TGZA */ -:0358000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005C8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4E8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E927CF74C63DCF74C20A444CB0024454B02A444CB21A4454B220803AEA0A20022088735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9ABFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF99FF20EA57C0BFEA0080A0E90000D8EC35 -/* TGZAF */ -:0380000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900618015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF538007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C40A444CB0024454B031532F9F343720E939E52C9F3C3D20E92A444CB21A4454B226803AEA0A20022088735EE92A201A203DCF74C227CF74C630502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A454DB6024555B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A464EBF1A4656BF0A474FBF024757BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A6FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCDFF20EA008000E84E334ECF573B57CF94FF20EA57C0BFEA0080A0E90000D8EC89 -/* TGZS */ -:03A0000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900658015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF578007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B229803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A454DB21A4555B20A454DB4024555B438212C9F3B394FE90A2002202A201A202A464EBF1A4656BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A474FBF024757BF31532F9FA4314FE939E52C9FA5394FE92A434BBF1A4353BF30502E9FA1304FE938212C9FA2384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A2FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCAFF20EA008000E84E334ECF573B57CF90FF20EA57C0BFEA0080A0E90000D8ECD8 -/* TGZSF */ -:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF75C62A201A20A7304FE90A20022031532F9F312720E939E52C9FA8384FE92A454DB61A4555B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECD3 -/* TGZSA */ -:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECA0 -/* TGZSAF */ -:03E8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006E8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF608007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B232803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE90A454DB6024555B63DCF75C62A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A474FBF024757BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E999FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC1FF20EA008000E84E334ECF573B57CF87FF20EA57C0BFEA0080A0E90000D8EC83 -/* T2GZ */ -:0438000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900788015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF698007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B225803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A4454B41A4464B439E52C9F383D20E988735EE92A201A202A4656BF1A4666BF31532F9F3E304FE939E52C9F3F384FE90A4757BF024767BF31532F9F3A314FE939E52C9F3B394FE92A4353BF1A4363BF30502E9F36314FE938212C9F37394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99FFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBEFF20EA008000E8583358CF693B69CF7DFF20EA57C0BFEA0080A0E90000D8ECAC -/* T2GZF */ -:0460000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007D8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6E8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E80FCF75C63C3D20E90A4454B0024464B02A4454B21A4464B228803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F310F20E90A4454B4024464B42A4555B61A4565B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99AFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBBFF20EA008000E8583358CF693B69CF78FF20EA57C0BFEA0080A0E90000D8ECFB -/* T2GZA */ -:0458000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007C8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6D8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B229803AEA0A2002200FCF74C63DCF74C288735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99BFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBAFF20EA008000E8583358CF693B69CF79FF20EA57C0BFEA0080A0E90000D8ECA0 -/* T2GZAF */ -:0480000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900818015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF728007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C40A4454B0024464B031532F9F343720E939E52C9F3C3D20E92A4454B21A4464B22E803AEA0A20022088735EE92A201A203DCF74C20FCF74C630502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A4555B6024565B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A4656BF1A4666BF0A4757BF024767BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E996FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB5FF20EA008000E8583358CF693B69CF74FF20EA57C0BFEA0080A0E90000D8ECDC -/* T2GZS */ -:04A0000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900858015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF768007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B231803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A4555B21A4565B20A4555B4024565B438212C9F3B394FE92A201A200A2002202A4656BF1A4666BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A4757BF024767BF31532F9FA4314FE939E52C9FA5394FE92A4353BF1A4363BF30502E9FA1304FE938212C9FA2384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E992FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB2FF20EA008000E8583358CF693B69CF70FF20EA57C0BFEA0080A0E90000D8EC43 -/* T2GZSF */ -:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF75C62A201A20A7304FE90A20022031532F9F310F20E939E52C9FA8384FE92A4555B61A4565B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC56 -/* T2GZSA */ -:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC23 -/* T2GZSAF */ -:04E8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008E8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7F8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B23A803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE90A4555B6024565B63DCF75C62A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A4757BF024767BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E989FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFA9FF20EA008000E8583358CF693B69CF67FF20EA57C0BFEA0080A0E90000D8ECEE -:0000000001FF diff --git a/firmware/mts_cdma.fw.ihex b/firmware/mts_cdma.fw.ihex deleted file mode 100644 index f6ad0cbd30cb075eaa256777f5ddb7221f12d82a..0000000000000000000000000000000000000000 --- a/firmware/mts_cdma.fw.ihex +++ /dev/null @@ -1,867 +0,0 @@ -:1000000014360002001E021AF9FFFFFFFFFF023341 -:100010001DFFFFFFFFFFFFFFFFFFFFFFFFFF02339B -:10002000C87581CE90FDE88583A012353CEC4D600B -:100030007378AB8003760018B89CFA787F800376DB -:100040000018B865FA78208003760018B820FA788E -:10005000208003760018B81FFA90FDDDAE83AF82D2 -:1000600090FBF81200AA6005E4F0A380F690FDE88A -:10007000A88290FDE8A982E8696005E4F20880F7AB -:100080009001081200B390010C1200B390011012FD -:1000900000B39001141200D190011A1200D1900106 -:1000A000201200D175D00012341A020126EF6582A9 -:1000B0007003EE658322E493F8740193F97402935C -:1000C000FE740393F5828E83E869700122E493F64F -:1000D000A30880F4E493FC740193FD740293FE740E -:1000E0000393FF740493F8740593F58288831200D8 -:1000F000AA700122E493A3A883A9828C838D82F045 -:10010000A3AC83AD828883898280E32121049B8014 -:1001100080049BACAE049BFDE8049D049DFBF304AE -:10012000A2049DFBF30502050280FED0F030F00929 -:1001300020F303F68010F7800D30F10920F303F26D -:100140008004F38001F020F404FCD0E0CC22CCC089 -:10015000E0120163020154BC0005D0F0ACF022C3F0 -:1001600013DCFC02012ABF0009ED258275F001F8BD -:10017000E622BF010FED2582F582EE3583F583750A -:10018000F004E022ED258275F002F8E222D083D05F -:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE -:1001A000E493A395F04012A3A3C3E5F033500205F6 -:1001B000832582F58250020583740193C0E0E493A5 -:1001C000C0E022D083D082F5F0E4937009740193EB -:1001D0007004A3A3800C74029365F06005A3A3A32D -:1001E00080E7740193C0E0E493C0E022120264024D -:1001F00001FB1202B80201FB1202DC0201FB30E03B -:100200000720E302E622E72230E10720E302E222B0 -:10021000E32230E202E022E493221202DC02022313 -:100220001202B8020223ABF012022DCBC5F0CB2292 -:1002300030E01020E306E6F5F008E622E7F5F009E5 -:10024000E7192230E11020E306E2F5F008E222E3AC -:10025000F5F009E3192230E206E0F5F0A3E022E42C -:1002600093F5F074019322BB0003740922BB0107CC -:1002700089828A83740422BB020789828A8374106C -:1002800022740A22020284BB0007E92582F8740165 -:1002900022BB010DE92582F582EA3583F5837404DA -:1002A00022BB020DE92582F582EA3583F5837410BD -:1002B00022E92582F87402220202B8BF0005EDF897 -:1002C000740122BF01078D828E83740422BF02074E -:1002D0008D828E83741022EDF87402220202DCBF3C -:1002E0000007ED2582F8740122BF010DED2582F58E -:1002F00082EE3583F583740422BF020DED2582F56D -:1003000082EE3583F583741022ED2582F874022283 -:10031000020310C0E0120264020328C0E01202B817 -:10032000020328C0E01202DC02032830E00B20E3C5 -:1003300004D0E0F622D0E0F72230E10B20E304D035 -:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B -:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069 -:100360002FBF000AFAEDF8E7F60809DAFA22BF0112 -:10037000128D828E83F802037809A3E7F0D8FA225F -:10038000020383FAEDF8E7F20809DAFA2202038D94 -:10039000BB014DBF001489828A83F9EDF802039FE7 -:1003A00008A3E0F6D9FA220203B0BF01228D828EA3 -:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F -:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9 -:1003D000828E83F9EDF8E0F208A3D9FA220203DD58 -:1003E000BB024DBF001289828A83F9EDF80203EF48 -:1003F00008A3E493F6D9F922BF01238D828E83FBF3 -:1004000008C9C582C9CAC583CAE493A3C9C582C93C -:10041000CAC583CAF0A3DBE9D8E722020422898295 -:100420008A83F9EDF8E493F208A3D9F922020433A0 -:10043000BF000DFAEDF8E3F60809DAFA2202043DEE -:10044000BF01128D828E83F802044A09A3E3F0D81B -:10045000FA22020455FAEDF8E3F20809DAFA220268 -:10046000045FE6FB08E6FA08E6F904F618700106F0 -:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379 -:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015 -:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6 -:1004A00000000000000502006105710026059800AB -:1004B000330A0900610A750066154400610CF900F1 -:1004C0006109A9006109E000610DC000610BF10044 -:1004D000610A1C00610A510061173C0033174F008C -:1004E000341E1400431EBF0044202C0044201A0078 -:1004F000471EE600471F8B004D1FDC004F1F080002 -:100500005832A800617CCC7DFF121CC52290FFFCF4 -:10051000E020E72DC2AFAE59AF58755A20E55A1406 -:10052000C55A6019E4FE7F05EE4FCE24FFCECF34CE -:10053000FFCF6007E490FF92F080ED80E08E598F4E -:10054000582212050A7D077CB71232C47D0F7C6EDB -:100550001232DE789D7A06E4F608DAFC7A06120595 -:10056000CD7C03120E55122168E4FEFF7C0F12327F -:100570004DD2A822123138E490FC38F090FFF0E020 -:1005800030E408740190FC39F08005E490FC39F007 -:100590007D0A7C001225461231BB2212313890FCB4 -:1005A00039E014700E90FFF0E04410F07C0012254A -:1005B000DF801990FC39E0700E90FFF0E054EFF00E -:1005C0007C001225DF80057C171225DF1231BB224B -:1005D00090FFF0E054ABF090FFF0E04420F0228C6C -:1005E000378D367882EDF608ECF6EDFEECFD7F01F6 -:1005F0009000051201F57880F67882E6FD08E6FCA9 -:10060000EDFEECFD7F019000041201F5540FFC7D1E -:100610008012176D7880E6700DAD3AAE39AF38E4D0 -:100620001203187C082290FFF0E054FEF090FFF0D7 -:10063000E054FDF0801E7882E6FD08E6FCEDFEEC5D -:10064000FD7F0190000812021725E0440190FFF39E -:10065000F00206D97882E6FD08E6FCEDFEECFD7FAF -:100660000190000612021754FE90FFF3F0802B78E1 -:1006700082E6FD08E6FCEDFEECFD7F01900008122D -:100680000217FAEB90FFF1F01208C8400DAD3AAE38 -:1006900039AF38E41203187C18227882E6FD08E6A8 -:1006A000FCEDFEECFD7F0190000812021790FFF1B7 -:1006B000F01208C8400DAD3AAE39AF38E412031855 -:1006C0007C18227882E6FD08E6FCEDFEECFD7F0159 -:1006D000900006120217440190FFF3F07883E6249D -:1006E00003F618E63400F67880E624FE500990FF01 -:1006F000F0E054FDF0800790FFF0E04402F0E49059 -:10070000FFF1F0788176007880E624FFFCE434FF86 -:10071000FD7881E67F00FEECD39EEF6480CD64809F -:100720009D402F1208AD400F7881E6AD3AAE39AF4B -:10073000381203187C182290FFF2E0FC788286833E -:10074000088682ECF0788106A37882A68308A682C8 -:1007500080B51208AD400F7881E6AD3AAE39AF38BA -:100760001203187C182290FFF2E0FC78828683083E -:100770008682ECF07880E6AD3AAE39AF38120318D5 -:100780007C00228C378D367882EDF608ECF6EDFE93 -:10079000ECFD7F019000051201F57881F67882E684 -:1007A000FD08E6FCEDFEECFD7F019000041201F572 -:1007B000540FFC7D8112176D7881E670037C08224E -:1007C00090FFF0E054FEF090FFF0E054FDF0801B4D -:1007D0007882E6FD08E6FCEDFEECFD7F0190000866 -:1007E00012021725E090FFF3F0805B7882E6FD08A7 -:1007F000E6FCEDFEECFD7F0190000612021754FEB0 -:1008000090FFF3F080217882E6FD08E6FCEDFEEC37 -:10081000FD7F01900008120217FAEB90FFF1F01231 -:1008200008C840037C18227882E6FD08E6FCEDFE4D -:10083000ECFD7F0190000812021790FFF1F0120802 -:10084000C840037C18227883E6240AF618E63400B0 -:10085000F6788076007881E624FFFCE434FFFD78AA -:1008600080E67F00FEECD39EEF6480CD64809D40E7 -:100870002178828683088682E090FFF1F01208C812 -:1008800040037C1822788006788306E618700106FB -:1008900080C390FFF0E04401F0788286830886826E -:1008A000E090FFF1F01208C840037C18227C00227F -:1008B00090FFF0E020E71290FFF0E030E50990FFB4 -:1008C000F0E04420F0C32280E7D32290FFF0E02044 -:1008D000E31290FFF0E030E50990FFF0E04420F0F3 -:1008E000C32280E7D3228C428D417C00ED54F0FD81 -:1008F000EC7003ED64307005753E038003753E04B3 -:10090000AC3E120F72758300858340E541540FF5AC -:100910003FE5407004E53F64037035E53E24FD7516 -:10092000F00AA42402F582E434FCF583E030E60505 -:100930001210598019E53E249DF8E654FBF678A97B -:10094000E62405F58218E63400F583740FF080592B -:10095000E5407004E53F64047048E53E24FD75F011 -:100960000AA42402F582E434FCF583E030E507AC08 -:1009700042AD41121C5AE54230E21578ADE630E056 -:100980000F78ADE630E109E4FF04FE7C0412324D3D -:1009900078A9E62406F58218E63400F583740FF092 -:1009A0008007E4FC7DEE121C5AC203221231381279 -:1009B0000F7278A9E62406F58218E63400F583E084 -:1009C00090FC38F078A9E62405F58218E63400F5A5 -:1009D00083E090FC39F0C2037D027C0012254612B0 -:1009E00031BB221231387895ECF6EC249DF8E630D4 -:1009F000E1077C131225DF800F90FC39E0FD78952C -:100A0000E6FC1213EF1225DF1231BB2212313878C7 -:100A100095ECF67D00120F121225DF1231BB221267 -:100A200031387895ECF6EC249DF8E630E2077C133B -:100A30001225DF801B7895E6249DF8E620E1077CEF -:100A4000121225DF800A7895E6FC1214131225DFB6 -:100A50001231BB221231387895ECF6EC249DF8E681 -:100A600020E2077C111225DF800A7895E6FC12153A -:100A7000141225DF1231BB221231387895ECF612B0 -:100A80000F7278A9E62409F58218E63400F583E0B0 -:100A900090FC3FF078A9E6240AF58218E63400F5C8 -:100AA00083E090FC40F078A9E62403F58218E63450 -:100AB00000F583E0FC78A9E62404F58218E634000A -:100AC000F583E0F56278A9E62402F58218E63400A1 -:100AD000F583E0F5638C61E4EC333354017895F6EB -:100AE0006008E56230E1037895067895E690FC4170 -:100AF000F078A7E62402F58218E63400F583E0FDDD -:100B0000A3E0540CFCED54E68C65F564E56130E53A -:100B100003436501E56220E50EE561547F7008E559 -:100B20006120E703436502E56130E303436510E5B7 -:100B30006130E203436520E561540360034365408F -:100B4000E56130E103436580E56130E4034364011E -:100B5000E56130E603436408E56220E40EE5615494 -:100B60007F7008E56120E7034364105365FB53641D -:100B7000F9AD64E56590FC3ACDF0A3CDF0E56330C6 -:100B8000E30DE5635430C4540F90FC3DF08005E460 -:100B900090FC3DF0E563540390FC3CF0E5635404A5 -:100BA000C31390FC3EF090FC3CE0700E7D357EFC63 -:100BB0007F01740190000912014B78A9E62408F521 -:100BC0008218E63400F583E07C00FD78A9E624076E -:100BD000F58218E63400F583E07F004CFEEF4D907F -:100BE000FC38F0A3CEF0CEC2037D0A7C001225466D -:100BF0001231BB221231387895ECF6789A760108DA -:100C000076FC0876387897760C789A12046E120281 -:100C10001D7898CBF6CB08F67F00EF24EA401FE45E -:100C2000EF25E090357EFD93CD04937899667003AF -:100C3000ED186670067897760080030F80DC789652 -:100C4000EFF6789A12046E9000021202177898CB91 -:100C5000F6CB08F65404CB54064B60047897760B19 -:100C60007899E630E313789A12046E900005120129 -:100C7000F524FB50047897760D7899E654C07D00F2 -:100C800064C04D70047897760B789A12046E9000C9 -:100C9000041201F524FC50047897760F789A120418 -:100CA0006E9000061201F524FD50047897760E78B8 -:100CB0009A12046E9000091201F524FD50047897F1 -:100CC000760A7897E6702A7895E6FC120F72789A81 -:100CD00012046E78A7E6F978A6E6FA7B01740A7822 -:100CE00000120348C2037895E6FC1211157897ECC0 -:100CF000F67897E6FC1225DF1231BB2212313878E4 -:100D000095ECF6120F727895E624FD75F00AA4248E -:100D100014F582E434FCF583AC82AD8378A6868337 -:100D2000088682ECF9EDFA7B0A78011203B0C2035F -:100D30007895E6FC1211151231BB228D2B8C2AED11 -:100D400060407527017529487528FFE52A24FDFCB8 -:100D5000E434FFFDEC7C0325E0CD33CDDCF9FCE58C -:100D6000292CF529E5283DF528AD29AE28AF2774B3 -:100D7000809000061203207480900002120320125B -:100D80000FC5E52B14603B7527017529087528FFF1 -:100D9000E52A24FDFCE434FFFDEC7C0325E0CD33A3 -:100DA000CDDCF9FCE5292CF529E5283DF528AD2910 -:100DB000AE28AF27E4900006120320E49000021250 -:100DC0000320221231387895ECF6EC249DF8E630B9 -:100DD000E2097895E6FC121514D2007895E6FC122B -:100DE0000F727896760090FC39E030E704789676BA -:100DF000017896E6FD7895E6FC120D38C2033000C6 -:100E0000077895E6FC1214137C001225DF1231BB23 -:100E10002278A9E62404F58218E63400F583E0443C -:100E200001F078A9E62404F58218E63400F583E0A1 -:100E300030E00280ED78A9E6240BF58218E6340054 -:100E4000F583E054F8F078A9E62402F58218E63438 -:100E500000F583E04480F022C2038C58120F7278B0 -:100E6000A6868308868279AF7A357B0A78011203D9 -:100E7000FE120E0EAC587D02120D38C203AC581291 -:100E80001115228D538E528F518C50120F72754F47 -:100E90000078A9E62405F58218E63400F583E02001 -:100EA000E41FE54F24F64019054FC2037C181232A7 -:100EB000FB90FF93E04401F0B2B3AC50120F72808C -:100EC000D078A9E62405F58218E63400F583E02001 -:100ED000E405C2037C022278A9E62405F58218E61F -:100EE0003400F583E0540F601678A9E62405F582F6 -:100EF00018E63400F583E0540FF0C2037C01227839 -:100F0000A88683088682E0AD53AE52AF5112031813 -:100F1000C2037C00228D318C30121514E531600F34 -:100F2000E530B4030A7C0112250E7C8112250EAC3B -:100F300030120F72E531601A78AA8683088682E043 -:100F400054E7F0A3A3A3A3E054E7F0AC307D021272 -:100F50000D3878A6868308868279B97A357B0A7837 -:100F6000011203FEC203E530249DF8E654FDF6AC01 -:100F700030121115228C2630030512329A80F87C2B -:100F80000A1231ADD203E52624FD78A3F670077866 -:100F9000AA76FF0876E078A3E67D007C0425E0CD04 -:100FA00033CDDCF9FC24A078A9F6ED34FF18F678EF -:100FB000A3E675F00AA42400FCE434FCFD78A6ED59 -:100FC000F608ECF61232462278A9E62402F58218D9 -:100FD000E63400F583E030E72278A9E62402F582C2 -:100FE00018E63400F583E0547FF078A9E62402F592 -:100FF0008218E63400F583E04480F02278AA8683E4 -:10100000088682E0547FF0AD83E5822404FCE43D51 -:101010008C82F583E0547FF078A9E6240BF58218E2 -:10102000E63400F583E054F8F078ABE62401F5826D -:1010300018E63400F583E04403F078ABE62405F5C8 -:101040008218E63400F583E04403F078A9E624052D -:10105000F58218E63400F583740FF02278AA8683AF -:10106000088682E0543FF0AD83E5822404FCE43D31 -:101070008C82F583E0543FF078A3E624A4F8E6FCE4 -:1010800078ABE62401F58218E63400F583ECF078BD -:10109000A3E624A4F8E6FC78ABE62405F58218E67E -:1010A0003400F583ECF078A9E6240BF58218E634D9 -:1010B00000F583E054FB4402F52678A7E62402F508 -:1010C0008218E63400F583E030E50343260178A971 -:1010D000E62405F58218E63400F583E030E00312DB -:1010E0000FC5E526FC78A9E6240BF58218E6340046 -:1010F000F583ECF078A9E62405F58218E63400F5CE -:1011000083740FF078AA8683088682E04480F0A377 -:10111000A3A3A3E04480F0228C2A120F7278A7E6E2 -:101120002408F58218E63400F583E0FC78A9E6246B -:101130000AF58218E63400F583ECF078A7E6240778 -:10114000F58218E63400F583E0FC78A9E62409F579 -:101150008218E63400F583ECF078A6868308868250 -:10116000E0FDA3E0FCEDFE78A9E62408F58218E690 -:101170003400F583EEF0ECFE78A9E62407F582183A -:10118000E63400F583EEF08C298D28C3EC9405ED50 -:10119000940C400575277C8033D3E5299401E5281C -:1011A0009403400575273C8023D3E5299481E528E5 -:1011B000940140057527188013D3E5299460E5282C -:1011C0009400400575270C8003752708AF27E4EFCE -:1011D000547C4483FF8F27E527FC78ABE62401F598 -:1011E0008218E63400F583ECF0E527FC78ABE624C2 -:1011F00005F58218E63400F583ECF0E527FC78A3CA -:10120000E624A4F8ECF678A9E62402F58218E63480 -:1012100000F583E0F52778A7E62402F58218E63486 -:1012200000F583A3E030E3175327C778A7E624052A -:10123000F58218E63400F583E09035AA93422778CA -:10124000A7E62402F58218E63400F583E030E705CE -:1012500043274080035327BF5327FB78A7E6240684 -:10126000F58218E63400F583E06003432704532732 -:10127000FC78A7E62404F58218E63400F583E04202 -:1012800027432780E527FC78A9E62402F58218E6A3 -:101290003400F583ECF078A9E62404F58218E634EE -:1012A00000F583E0F52778A7E62402F58218E634F6 -:1012B00000F583A3E030E1055327DF8003432720B7 -:1012C00078A7E62402F58218E63400F583E030E4DE -:1012D000055327EF800343271078A7E62409F582FA -:1012E00018E63400F583E0B40203432702E527FC47 -:1012F00078A9E62404F58218E63400F583ECF0784A -:10130000A9E62403F58218E63400F583E0F5277892 -:10131000A7E62409F58218E63400F583E07005534A -:10132000277F800343278078A7E62402F58218E60A -:101330003400F583A3E030E00543272080035327E2 -:10134000DF78A7E62402F58218E63400F583E03062 -:10135000E30543274080035327BF78A7E62402F51F -:101360008218E63400F583E030E00543271080035F -:101370005327EF78A7E62402F58218E63400F583B8 -:10138000A3E030E40543270880035327F778A7E656 -:101390002402F58218E63400F583A3E030E5054326 -:1013A000270480035327FB78A7E62402F58218E67A -:1013B0003400F583A3E030E605432701800353277B -:1013C000FE78A7E62402F58218E63400F583A3E050 -:1013D00030E70543270280035327FDE527FC78A962 -:1013E000E62403F58218E63400F583ECF0C2037CB2 -:1013F00000228D278C26ED54031460037C1022E517 -:1014000027547C24FC40037C0B22E526249DF8E62F -:101410004402F67C00228C30120F72E530249DF8D5 -:10142000E620E24FAC307D02120D38E53024FE4458 -:1014300028FC78AA8683088682ECF0AF83E58224B4 -:1014400004FEE43FFFEC8E828F83F07C038C2CE55E -:101450002CFC78ABE62401F58218E63400F583EC29 -:10146000F0E52CFC78ABE62405F58218E63400F5AF -:1014700083ECF0752D01752F48752EFFE53024FDA6 -:10148000FCE434FFFDEC7C0325E0CD33CDDCF9FC3E -:10149000E52F2CF52FE52E3DF52E78ABE62404F54F -:1014A0008218E63400F583E054E7F52CAD2FAE2E1C -:1014B000AF2DE4900002120320E4900006120320F6 -:1014C0001201EF30E503432C10E52CFC78ABE62449 -:1014D00004F58218E63400F583ECF012105978A96F -:1014E000E62406F58218E63400F583E0C203FCE545 -:1014F00030249DF8E64404F68C2CE530540FC45497 -:10150000F07E00FFEEEF44047D00FFEC4EFCED4F5B -:10151000FD121CC57C00228C2F120F72120FF9785D -:10152000AA8683088682E05408F0A3A3A3A3E0540C -:1015300008F0AC2F7D02120D38C203E52F249DF870 -:10154000E654FBF67C00221231387896ECF6EC2457 -:101550009DF8E630E10A7D007C131225461231BB6E -:101560007896E6249DF8E64401F67896E6FC120F9C -:10157000727896E624FD75F00AA42414F582E4340A -:10158000FCF58378A6E6FA08E6F97B0A78011203EF -:10159000B078A6868308868279B97A357B0A780185 -:1015A0001203FE120FC5C2037896E6FC12111578DD -:1015B00095ECF6EC600A7D007C081225461231BBE2 -:1015C0007896E6FC120F7278A9E62404F58218E6F4 -:1015D0003400F583E0441054DFFC78A9E62404F5D8 -:1015E0008218E63400F583ECF07895ECF6C2037CC3 -:1015F000C81232FB7896E6FC120F7278A9E6240432 -:10160000F58218E63400F583E054EFF0C2037CC89D -:101610001232FB7896E6FC120F7278A9E62404F5E4 -:101620008218E63400F583E04410F0C2037CC8124F -:1016300032FB7896E6FC120F7278A9E62404F58254 -:1016400018E63400F583E04420F0C2037CF0123247 -:10165000FB7896E6FC120F7278A9E62405F582184D -:10166000E63400F583E030E415C2037896E64410D2 -:101670007F00FE7C0712324D1231BB02173B78A966 -:10168000E62404F58218E63400F583E054CFF0C276 -:10169000037CC81232FB7896E6FC120F7278A9E63A -:1016A0002404F58218E63400F583E04430F0C203E8 -:1016B0007CF01232FB7896E6FC120F7278A9E624D1 -:1016C00005F58218E63400F583E030E414C20378AF -:1016D00096E644107F00FE7C0712324D1231BB802B -:1016E0005D78A9E62404F58218E63400F583E05419 -:1016F000EFF078A9E62404F58218E63400F583E0DB -:1017000054DFF07896E624FD75F00AA42414F582DF -:10171000E434FCF583AC82AD8378A68683088682A8 -:10172000ECF9EDFA7B0A78011203B0C2037896E671 -:10173000FC1211157D007C0B1225461231BB2212C2 -:101740003138E490FC39F07D027C001225461231DC -:10175000BB221231387C001225DF1231BB22743CCF -:1017600090FBE0F0743E90FBE0F0E490FC28F02267 -:101770008D358C34ECB401028003D340028028B450 -:1017800002028003D34008A835E625E0F68018B4AD -:1017900004028003D3400AA835E625E025E0F68060 -:1017A00006A83576008000228C3C8D3BEDFEECFDDA -:1017B0007F0175660675670090FC29120477120197 -:1017C000EFB480028006D3500302186E90FC2912F9 -:1017D00004899000031201F554F0B430028003D361 -:1017E000405F90FC29120489900008120217FAFD4C -:1017F000EBFE7F0190FC2C120477EECD9035C3FCFC -:10180000E493FF740193FEF9EFFA7B01EAFFE9FE2E -:10181000ECC39EED9F40259035C5E493FD74019384 -:10182000FCEDFEECFD7F01EECDFC90FC2EE0D39CA8 -:1018300090FC2DE09D5005756680803312198C80D8 -:101840002EB460028003D3400BAC3CAD3B1207804A -:101850008C66801BB41003B34010C3B42003B340A4 -:1018600009C3B440028003D34000756681800080C4 -:1018700075B481028003D3406B90FC2912048990D7 -:1018800000031201F554F0B430028003D3401D90E0 -:10189000FC29120489900008120217FAFDEBFE7F62 -:1018A0000190FC2F1204771218F68036B460028083 -:1018B00003D34013753A67E4F539F538AC3CAD3BDA -:1018C0001205DC8C66801BB41003B34010C3B42037 -:1018D00003B34009C3B440028003D340007566815E -:1018E000800080028000E566FC90FC29120489ECEF -:1018F000900002120320AC672290FC291204899008 -:1019000000041201F5600474018001E4A2E0920178 -:1019100090FC29120489ED2403FD50010E90FC2C4B -:1019200012047790FC291204899000051201F5F544 -:10193000679000041201F5540FFC7D6712176DE5E6 -:10194000677004756608227566007884760078846E -:10195000E6C39567503890FC2F1204891201EFFC02 -:1019600090FC2C120489EC12031830010E90FC310B -:10197000E004F090FC307003E004F078840690FC02 -:101980002EE004F090FC2D7003E004F080C0229063 -:10199000FC2AE0FDA3E0FCEDFEECFD7F01ED240A56 -:1019A000FD50010E90FC3212047790FC291204893C -:1019B0009000041201F5540FB401028003D34017C4 -:1019C00090FC321204890DED70010E90FC2F120470 -:1019D0007778887601804EB402028003D340199054 -:1019E000FC32120489ED2402FD50010E90FC2F12EE -:1019F000047778887602802DB404028003D34019DE -:101A000090FC32120489ED2404FD50010E90FC2F4D -:101A100012047778887604800CB400028003D340E7 -:101A2000007566082290FC291204899000051201B5 -:101A3000F5F567788576007885E6C39567400302FB -:101A40001AF4788676007886E6C378889650769081 -:101A5000FC2C1204891201EFFC90FC321204921249 -:101A600001E9F45CFC1201E9F890FC2F120489E80A -:101A7000C0E01201EFC8D0E0C8584CFC90FC2C121A -:101A80000489EC1203187887ECF690FC31E004F03E -:101A900090FC307003E004F009E970010A90FC3218 -:101AA00012048090FC291204899000041201F53080 -:101AB000E40E90FC2EE004F090FC2D7003E004F0A6 -:101AC00078860680817888E6FDE4FEFFEECDFC9006 -:101AD000FC31E02CF090FC30E03DF07888E6FDE44D -:101AE000FEFFEECDFC90FC34E02CF090FC33E03DAA -:101AF000F0788506021A347566002222C0E0C0F034 -:101B0000C082C083C0D0E8C0E0E9C0E0EAC0E0EB3A -:101B1000C0E0ECC0E0EDC0E0EEC0E0EFC0E090FF60 -:101B200092E01201C01B47301B47321B56381B681E -:101B30003A1B7A3E1B92441B86461B9E501BE0526A -:101B40001BBF541C015600001C2290FF92E07F0036 -:101B5000FE7C0112324D021C32E4FF04FE7C0312B3 -:101B6000324D742090FFFEF0021C32E4FF04FE7C34 -:101B70000212324D744090FFFEF0021C32E4FF046A -:101B8000FE7C0412324D021C32E4FF04FE7C05127E -:101B9000324D021C32E4FF04FE7C0612324D021C60 -:101BA0003290FFA5E07D0090FBF8CDF0A3CDF09042 -:101BB000FBF9E0FCF58390FBF8E04433FD121CC513 -:101BC000807390FFB5E07D0090FBFACDF0A3CDF0DF -:101BD00090FBFBE0FCF58390FBFAE04443FD121C14 -:101BE000C5805290FFA6E07D0090FBFCCDF0A3CD18 -:101BF000F090FBFDE0FCF58390FBFCE04434FD122B -:101C00001CC5803190FFB6E07D0090FBFECDF0A3B7 -:101C1000CDF090FBFFE0FCF58390FBFEE04444FD3B -:101C2000121CC5801090FF92E07D00FCED44AAFDDF -:101C3000121CC58000E490FF92F0D0E0FFD0E0FEDF -:101C4000D0E0FDD0E0FCD0E0FBD0E0FAD0E0F9D06D -:101C5000E0F8D0D0D083D082D0F0D0E0320581053A -:101C60008105810581A881181818EDF608ECF69019 -:101C7000FF5AE020E70280F790FF59E07D00A8813D -:101C800018CDF6CD08F67D03A881E618FCE6CC2534 -:101C9000E0CC33CCDDF9CCF6CC08F6A88118E644CC -:101CA000F8F6A881181818E6FD08E6FCA881188641 -:101CB00083088682EDF0A3ECF0740290FF5AF015D1 -:101CC0008115811581158122E5812405F581E4A81E -:101CD0008118F6A88118181818EDF608ECF690FB94 -:101CE000F5E024F85003021DE6E4A8811818F6A8D0 -:101CF0008118E6FEA88118181818E6FD08E6FC7F92 -:101D000000EF24F8404DE4EF25E0247DF582E43433 -:101D1000FCF583E0FBA3E06C7003FAEB6D700974D3 -:101D200001A8811818F6802BE4EF25E0247DF582C8 -:101D3000E434FCF5837A00E054F0CCF8CCCDF9CD56 -:101D4000FB7800E954F0F9EA687002EB6970010E63 -:101D50000F80AEA88118EEF6A88118181818EDF6B5 -:101D600008ECF6A881EFF6A8811818E67079A8812A -:101D700018E624F74071A88118181818E6540FA81F -:101D800081F664046017A881E664036010A88118D6 -:101D9000181818E6FD08E6FC121C5A804A7C0A1244 -:101DA00031ADA88118181818E6FD08E6FC90FBF480 -:101DB000E025E0247DF582E434FCF583EDF0A3EC2E -:101DC000F090FBF4E0FFE4EF045407FF90FBF4F025 -:101DD00090FBF5E004F012324690FBF6E07008E468 -:101DE000FEFF7C0F12324D802790FBF7E004F05489 -:101DF0003F701D90FBF7E044FE7D00FC90FBF4E09B -:101E000025E0247DF582E434FCF583EDF0A3ECF0CD -:101E1000E58124FBF58122788B7600788C7600743E -:101E20000190FBF6F012313890FBF5E060577C0A28 -:101E30001231AD90FBF3E025E0247DF582E434FC23 -:101E4000F583E0FDA3E0FC90FBF3E025E0247DF5C5 -:101E500082E434FCF583E4F0A3F090FBF3E0FFE4CC -:101E6000EF045407FF90FBF3F090FBF5E014F078DB -:101E700089EDF608ECF61232467889E6FD08E6FCB4 -:101E80001208E380A312329A90FF93E04401F0B26B -:101E9000B3788B06B60011788B7600788CE6F40464 -:101EA00004A2E092B4788CF6021E25E490FBF6F0D2 -:101EB00090FBF5E07D00FCED44CFFD121C5A123181 -:101EC000BB22123138E5706449456F601590FF837D -:101ED000E0540F7D00D39570ED956F5005122F8162 -:101EE00080031230511231BB22123138E57064493F -:101EF000456F600512308B800E90FF80E04408F043 -:101F000090FF83E0547FF01231BB221231388C54A1 -:101F1000EC54F0B41015756A357569FC756801E507 -:101F20006A2403F56AE5693400F569E4F557F55666 -:101F3000E556C394015027E554540FFCAD6AAE69D1 -:101F4000AF68120E808C55EC60028012056AE56A5B -:101F5000700205690557E5577002055680D2E554B1 -:101F6000540F249DF8E654FEF6E554540F7F00FE0E -:101F70007C1212324DE5551470097D007C09122542 -:101F8000468007AD577C001225461231BB22123124 -:101F90003890FFFCE04402F090FF00E030E713903F -:101FA000FF83E04480F0436D8090FFFCE04401F04B -:101FB000801190FF82E04408F0536D7F90FFFCE0B9 -:101FC00054FEF090FF81E04480F01225F990FFFE6E -:101FD000E04405F090FFFCE054FDF01231BB22120A -:101FE00031387C011232FB78ADE64402F674FEFC17 -:101FF00004FD121CC590FF5AE030E70280F7E4F5BB -:102000004E754D10AC4EAD4DE54E154E7002154D52 -:10201000EC4D600280EE4387011231BB2212313851 -:102020007C021231C778ADE654FDF61231BB2212A4 -:10203000313878ADE630E02C78ADE630E12678AD89 -:10204000E6FCF58318E644F0FD121C5A90FFFCE014 -:102050004420F07C021232FB78ADE654FDF6741A8F -:1020600090FFFEF078ADE6FCF58318E644F1FD1232 -:102070001C5A1231BB22756D0090FFFFE0600343D4 -:102080006D01756E00E4F56CF56BE4F56F757049E4 -:10209000748490FF82F0748490FF80F0748090FFCD -:1020A00058F0748090FF5AF0AD46AF457E00EE24A4 -:1020B000FE5003022142E4EE75F007A4247FF5826E -:1020C000E434F8F583E0FFE4EF5480FDE4EF540FCF -:1020D00014FFED6038E4EF75F008A42448F582E4BD -:1020E00034FFF5837490F0E4EF75F008A4244AF50A -:1020F00082E434FFF5837480F0E4EF75F008A424E3 -:102100004EF582E434FFF5837480F08034E4EF759B -:10211000F008A42408F582E434FFF5837490F0E419 -:10212000EF75F008A4240AF582E434FFF583E4F0A7 -:10213000E4EF75F008A4240EF582E434FFF583E49F -:10214000F00E0220AB8D468E448F45747F90FFFDCC -:10215000F0749090FFFCF0228C58EC24F65006E5C9 -:10216000582437FC22E5582430FC22D2B0122543F3 -:10217000EC700302227E755C03AE5B7F00E55C15AC -:102180005C6480247F5035EF2400F582E434FBF555 -:1021900083E0FE24FE501EEF7D00FCE4FB7474C35C -:1021A0009CFAEB9DFBEE7D00FCEAC39CED6480CBCA -:1021B00064809B50028005EF2EFF80C18E5B8F5A9A -:1021C000E55C6480247F500302227EE55A248E5011 -:1021D0000302227E855A5D755B00AE5AAF5B903577 -:1021E000EEE493F55CE55C155C6480247F5018EEAA -:1021F0002400F582E434FBF583E0FCEF9035EE93A8 -:102200006C70040E0F80DE8E5A8F5BE55C64802458 -:102210007F406E755E017560E8755FFFE55D2402C5 -:10222000F55A755C07E55C334057AD60AE5FAF5E55 -:10223000E55CF5823395E0F5831201F5C4540FFC9B -:10224000122155E55A2400F582E434FBF583ECF0C5 -:10225000055A055AAD60AE5FAF5EE55CF582339519 -:10226000E0F5831201F5540FFC122155E55A2400C4 -:10227000F582E434FBF583ECF0055A055A155C80D1 -:10228000A4740290F851F090F86B79C77A357B27E7 -:1022900078011203FE756A357569FC756801E49072 -:1022A000FF83F0748090FF81F0755902E55975F055 -:1022B00007A4247FF582E434F8F583E0788FF6FCF8 -:1022C000540F14FC788FECF6E55975F007A42481BF -:1022D000F582E434F8F583E0789276FD0876E8FC40 -:1022E000788FE675F008A42448F582E434FFF5837E -:1022F000E4F0788FE675F008A4244FF582E434FF0B -:10230000F583ECF07892E6FF08E67E03CFC313CFA7 -:1023100013DEF9FE788FE675F008A42449F582E40F -:1023200034FFF583EEF0788FE675F008A4244AF5C3 -:1023300082E434FFF5837480F07890ECF67D0078C9 -:1023400093E62CF618E63DF67892E6FD08E67C0367 -:10235000CDC313CD13DCF9FC788FE675F008A42407 -:102360004DF582E434FFF583ECF0788FE675F008E4 -:10237000A4244EF582E434FFF583E4F07892E6FD80 -:1023800008E6FC788FE6FF7E00EE24FE5003022470 -:10239000FDE4EE75F007A4247FF582E434F8F583BC -:1023A000E0FFE4EF5480FAE4EF540F14FFE4EE751D -:1023B000F007A42481F582E434F8F583E07890F600 -:1023C000E4EE1313548024F0F8E434FDF9E8FCE95A -:1023D000FD8A5AEA700302246AE4EF75F008A42427 -:1023E00048F582E434FFF583E4F07890E6FAE4EF10 -:1023F00075F008A4244FF582E434FFF583EAF0ED8C -:10240000FBEC7A03CBC313CB13DAF9FAE4EF75F0E4 -:1024100008A42449F582E434FFF583EAF07890E6D5 -:102420007B00FAEC2AFCED3BFDFBEC7A03CBC313FB -:10243000CB13DAF9FAE4EF75F008A4244DF582E441 -:1024400034FFF583EAF0E4EF75F008A4244AF5823E -:10245000E434FFF5837480F0E4EF75F008A4244EB3 -:10246000F582E434FFF5837480F00224F9E4EF751B -:10247000F008A42408F582E434FFF583E4F07890B2 -:10248000E6FAE4EF75F008A4240FF582E434FFF5D2 -:1024900083EAF0EDFBEC7A03CBC313CB13DAF9FA42 -:1024A000E4EF75F008A42409F582E434FFF583EA2B -:1024B000F07890E67B00FAEC2AFCED3BFDFBEC7A31 -:1024C00003CBC313CB13DAF9FAE4EF75F008A424B5 -:1024D0000DF582E434FFF583EAF0E4EF75F008A42B -:1024E000240AF582E434FFF583E4F0E4EF75F008A4 -:1024F000A4240EF582E434FFF583E4F00E02238673 -:102500008E597892EDF608ECF6788FEFF61220737C -:10251000228C26EC30E718E526540F1475F008A439 -:102520002448F582E434FFF583E054DFF08016E5BB -:1025300026540F1475F008A42408F582E434FFF53E -:1025400083E054DFF0227C0022EC90FC37F08C24F6 -:10255000ED2403F5257D00D39572ED95714003853B -:102560007225E52524B75009752503740290FC37C0 -:10257000F0AC2512307622E4F56CF56B12257D2245 -:1025800090FC35E06573600E740490FC37F0E4F560 -:102590006B756C0380467D73E4FEFF79357AFC7BB6 -:1025A0000174057800120348E56C2403F56CE56BB3 -:1025B0003400F56BE56CD39572E56B95714006853B -:1025C000726C85716BD3E56C9448E56B9400400C9C -:1025D000740290FC37F0E4F56B756C03AC6C123050 -:1025E0007622EC90FC37F0E4F56CF56B8C32EC6005 -:1025F0000512306780057C001230762290FF93E050 -:102600004401F0B2B390FF04E0F54A90FF06E0FD0C -:10261000A3E0ED7D00FC7D00FC90FF06E0FFA3E061 -:102620007E00FFE4FEEC4EFCED4FFDC3EC9448ED64 -:102630009400502290FF06E0FDA3E0ED7D00FC7DBC -:1026400000FC90FF06E0FFA3E07E00FFE4FEEC4EFE -:10265000FCED4FFD8004E4FD7C488C728D7190FF91 -:1026600002E0FDA3E0ED7D00FC7D00FC90FF02E0B8 -:10267000FFA3E07E00FFE4FEEC4EF54CED4FF54B82 -:10268000756A357569FC7568017D357EFC7F017959 -:1026900073E4FAFB74057800120348754900E549B4 -:1026A00024FE4019AD6AAE69AF68E412031805490B -:1026B0000DED70010E8D6A8E698F6880E1756A3547 -:1026C0007569FC75680190FF00E05460B4000280F9 -:1026D00006D35003022CBFE54A540FF549E54A548E -:1026E00080A2E0920290FF01E012018A000B2CBA56 -:1026F000270528232CBA292F2CBA2A122A462BADBB -:102700002BB02BF02C632C91E56D30E70EE54C459A -:102710004B7008E572640245716003022CBC90FFA7 -:1027200000E0541FB400028003D34029E54A60034F -:10273000022820AD6AAE69AF68740112031878AD43 -:10274000E630E00BAD6AAE69AF6874021203187C24 -:102750000212307622B401028003D3401BE56D20C3 -:10276000E107E54A6003022820E54A24FE500302FF -:1027700028207C0212307622B402028006D3500355 -:1027800002281EE56D20E10DE54A6009E54A6480F6 -:102790006003022820AC4A1230FD4003022820E5E5 -:1027A00049702530021190FF80E05408AD6AAE698F -:1027B000AF68120318800F90FF82E05408AD6AAE34 -:1027C00069AF68120318803D154930021DE549754F -:1027D000F008A42448F582E434FFF583E05408AD02 -:1027E0006AAE69AF68120318801BE54975F008A44A -:1027F0002408F582E434FFF583E05408AD6AAE693D -:10280000AF68120318AD6AAE69AF681201EF600BD2 -:10281000AD6AAE69AF6874011203187C021230769B -:10282000228000022CBCE56D20E706E57245716050 -:1028300003022CBC90FF00E0541FB400028003D3BD -:10284000401AE54C14454B7004E54A600302292CFC -:1028500078ADE654FEF67C0012307622B401028098 -:1028600003D3402AE56D20E108E56D20E00302294D -:102870002CE56D30E004E54A700BE56D30E109E5CB -:102880004A24FE500302292C7C0012307622B40226 -:10289000028006D3500302292AE54C454B6003020F -:1028A000292CAC4A1230FD400302292CE56D20E1B1 -:1028B00007E56D20E0028077E56D30E006E54960D0 -:1028C00002806CE549700F90FF82E054F7F090FFB2 -:1028D00080E054F7F022E549B401028003D34009B7 -:1028E0007D017C03120F128011B402028003D340D9 -:1028F000097D017C04120F1280001549300215E594 -:102900004975F008A42448F582E434FFF583E054C7 -:10291000F7F08013E54975F008A42408F582E43443 -:10292000FFF583E054F7F07C00123076228000023D -:102930002CBCE56D20E706E57245716003022CBCF6 -:1029400090FF00E0541FB400028003D3401AE54C0E -:1029500014454B7004E54A6003022A0F78ADE64443 -:1029600001F67C0012307622B401028003D34029A4 -:10297000E56D20E108E56D20E003022A0FE56D30EA -:10298000E004E549700BE56D30E108E54924FE50AF -:1029900002807F7C0012307622B402028003D34092 -:1029A0006FE54C454B60028069AC4A1230FD400235 -:1029B0008060E56D20E107E56D20E0028054E54987 -:1029C000701430020990FF80E04408F0800790FF07 -:1029D00082E04408F022E56D30E1331549300215FC -:1029E000E54975F008A42448F582E434FFF583E056 -:1029F0004408F08013E54975F008A42408F582E442 -:102A000034FFF583E04408F07C0012307622800227 -:102A10008000022CBCE56D20E712E5724571700C58 -:102A2000E54A700890FF00E0541F6003022CBCE5EB -:102A30004C90FFFFF090FFFFE06005436D018003C5 -:102A4000536DFE7C0012307622E56D30E70EE572A4 -:102A50004571600890FF00E0541F6003022CBCAD7C -:102A60004BE54CED7D00FC7D00FCBD0002800302C7 -:102A70002BA8B401028003D34032E54A7005E54C2F -:102A8000FC6003022BAA756A407569F8756801D36A -:102A9000E5729412E57194004006E4FD7C12800416 -:102AA000AC72AD718C708D6F12308B22B4020280CB -:102AB00003D34059E54A6003022BAAE54CFC70277A -:102AC000756A527569F8756801D3E5729419E571F4 -:102AD00094004006E4FD7C198004AC72AD718C70EA -:102AE0008D6F12308B8025756A6B7569F87568017A -:102AF000D3E5729427E57194004006E4FD7C2780BD -:102B000004AC72AD718C708D6F12308B22B40302E5 -:102B10008006D35003022BA8E54CF549700F90FFB7 -:102B200004E0FDA3E04D6003022BAA801890FB0295 -:102B3000E0FDA3E0FC90FF05E06C700790FF04E06F -:102B40006D60028068E4F570F56F7F00E54914C59B -:102B500049600FEF2400F582E434FBF583E02FFF9A -:102B600080EA8F4AE54A2400F582E434FBF583E0ED -:102B70007D00D39572ED95714006AC72AD71800FFA -:102B8000E54A2400F582E434FBF583E07D00FC8C0B -:102B9000708D6FE54A2400FCE434FBFDFEECFD7F04 -:102BA000018D6A8E698F6812308B228000022CBCE6 -:102BB000022CBCE56D30E719E5721445717012E521 -:102BC0004A700EE54C454B700890FF00E0541F60C2 -:102BD00003022CBCE56D20E008E56D20E103022C2A -:102BE000BC756A6EE4F569F568E4F56F04F570127A -:102BF000308B22E56D20E727E57245717021E54AAB -:102C0000701DE54C6402454B600DE54C14454B606E -:102C100006E54C454B700890FF00E0541F6003022E -:102C20002CBCE56D20E008E56D20E103022CBC859D -:102C30004C6EE56E700A436D01536DFDD2B080207D -:102C4000E56E64026007E56E1460028072536DFEEB -:102C5000436D02E56E64026005E56E147002C2B059 -:102C60007C0012307622E56D30E71AE5721445716A -:102C70007013E54A700FE54C454B700990FF00E07A -:102C8000541F1460028038E56D20E10280317C0120 -:102C900012307622E56D20E715E5724571700FE57B -:102CA0004C454B700990FF00E0541F146002800FE8 -:102CB000E56D20E10280087C00123076228000025F -:102CC0002F7DB440028006D35003022F7390FF0182 -:102CD000E090FC35F0E54A90FC36F0E490FC37F0EB -:102CE000E56A2403F56AE5693400F569AD4BE54C06 -:102CF000856A82856983CDF0A3CDF090FF01E01253 -:102D000001C02D2A012D50022D7A032DA4042DF28D -:102D1000052E2F062E55072E7B082EA7092ECD0B2C -:102D20002EF30C2F02802F028100002F60E56D2012 -:102D3000E7067C051225DF227D767E357F02793815 -:102D40007AFC7B01740878001203487D087C00122D -:102D5000254622E56D20E7067C051225DF22E54A9F -:102D6000B403004010B40500500BE54A7F00FE7C20 -:102D70001012324D227D007C0712254622E56D207F -:102D8000E7067C051225DF22E54AB403004010B4B3 -:102D90000500500BE54A7F00FE7C1112324D227D6A -:102DA000007C0712254622E56D20E7067C051225EA -:102DB000DF22E54AB405028003D3400AE4FF04FEA3 -:102DC0007C0A12324D22B401028003D3400AE4FF90 -:102DD00004FE7C0812324D22B403004010B40500FA -:102DE000500BE54A7F00FE7C1312324D227D007CA1 -:102DF0000712254622E56D20E734D3E5729448E5B5 -:102E00007194005006E572457170067C021225DF50 -:102E100022E54AB40103B3400BC3B403004009B434 -:102E200006005004123123227C071225DF221225CE -:102E30007D22E56D20E71DE54AB403004010B4058E -:102E400000500BE54A7F00FE7C1612324D227C07B3 -:102E50001225DF2212257D22E56D20E71DE54AB40B -:102E600003004010B40500500BE54A7F00FE7C19BA -:102E700012324D227C071225DF2212257D22E56DBC -:102E800020E723748190FF93F0E54AB403004010DB -:102E9000B40500500BE54A7F00FE7C1712324D222C -:102EA0007C071225DF2212257D22E56D20E71DE536 -:102EB0004AB403004010B40500500BE54A7F00FE01 -:102EC0007C1812324D227C071225DF2212257D222A -:102ED000E56D20E71DE54AB403004010B40500503D -:102EE0000BE54A7F00FE7C1512324D227C0712252D -:102EF000DF2212257D22E56D20E7067C071225DF03 -:102F00002212257D22E56D30E72090FF00E0541F5E -:102F1000701090FF01E0B480051225748003122523 -:102F20007D227D007C051225462290FF00E0541F83 -:102F300060067C051225DF22D3E5729448E5719482 -:102F400000500BC3E5729407E571940050067C03B2 -:102F50001225DF22E54AB40504123123227C071230 -:102F600025DF22E56D30E7087D007C05122546222D -:102F70007C051225DF22B420028003D340008000AC -:102F80001230512275430090FF83E0540FD39543D4 -:102F90004024E54324F0F582E434FEF583E0AD6A95 -:102FA000AE69AF6812031805430DED70010E8D6A0E -:102FB0008E698F6880D1E5437D00FCC3E5709CF588 -:102FC00070E56F9DF56FE570456F6006E490FF83D7 -:102FD000F02290FF82E04408F0E4F56F75704990AC -:102FE000FC35E0B405028003D3404090FC36E0F5A8 -:102FF00043B405028003D3400AE4FF04FE7C0B12B5 -:10300000324D22B401028003D3400AE4FF04FE7C67 -:103010000912324D22B403004010B40500500BE5F4 -:10302000437F00FE7C1412324D2222B480004023E4 -:10303000B48200501E7C357DFC1217A57D008C6C7F -:103040008D6B90FC37E0600512305180057C0012DA -:103050003076222290FF83E0547FF090FF82E0449C -:1030600008F090FF80E04408F02290FF82E04408DE -:10307000F090FF80E04408F0228C237D008C708D5E -:103080006F756A357569FC75680112308B2290FF87 -:1030900083E0547FF0E5706449456F700122C3E519 -:1030A000709408E56F94004015752108E5217D00B6 -:1030B000FCC3E5709CF570E56F9DF56F8009857028 -:1030C00021E4F56F757049752200E522C395215002 -:1030D00026AD6AAE69AF681201EFFCE52224F8F56F -:1030E00082E434FEF583ECF005220DED70010E8DC7 -:1030F0006A8E698F6880D3E521547F90FF81F0222A -:103100008C487F00EF24FD4019E4EF75F007A424FC -:103110007FF582E434F8F583E065487002D3220F2E -:1031200080E28F47C32285727085716F90FF82E0C5 -:1031300054F7F090FF83E0547FF022C000C001C03C -:1031400002C006C007E5782408F8860653067F7C8F -:10315000FF1231AD7C007D00E57B6046FF90FD9560 -:10316000E0547F6E700FC083C082A3E0FDA3E0FC3B -:10317000A3157B8007A3A3A3DFE68026DF06D0820A -:10318000D083801EE0F8A3E0F9A3E0FAD082D083D8 -:10319000E8F0A3E9F0A3EAF0A3C083C082A3A3A34D -:1031A00080DA123246D007D006D002D001D00022F9 -:1031B00085A87A75A888EC70027C3F8C7922E57826 -:1031C0002408F8760012329A80FBC000C001C002C9 -:1031D000C006C007AE047CFF1231ADE57B6042FF44 -:1031E00090FD95E0547F6E700BC083C082A3A3A3B3 -:1031F000157B8007A3A3A3DFEA8026DF06D082D059 -:103200008380D8E0F8A3E0F9A3E0FAD082D083E885 -:10321000F0A3E9F0A3EAF0A3C083C082A3A3A38034 -:10322000DA7808087918097C01E6547F6E70067612 -:10323000007700800608090CBC08EE123246D00761 -:10324000D006D002D001D00022757900857AA8225C -:10325000C0F0C082C083C3E57B24E8500512329AD7 -:1032600080F4EC6031903575E493C39C4028C00431 -:103270007CFF1231ADD004430480E57B75F003A4DC -:103280002495F582E434FDF583ECF0EFA3F0EEA392 -:10329000F0057B123246D083D082D0F022C0047C6D -:1032A00020D28CD28DD504FDD0042275A80075885B -:1032B0000075B80075F00075D000E4F8900000F6D5 -:1032C00008B800FB020000C3ED940250047D037CAB -:1032D000E8ECF4FCEDF4FD0CBC00010D8C7F8D7E60 -:1032E00022C3EC94BCED940250047D077CD0ECF436 -:1032F000FCEDF4FD0CBC00010D8C7D8D7C22EC708E -:103300000122C000E5782418F8A604E5782408F81E -:10331000C6547FF6E630E703D0002212329A80F4DA -:10332000C28C857C8C857D8AD28CC0E0C0D0C0F0F8 -:10333000C082C083C000C001C002C003C004C00579 -:10334000C006C007121AF8E5782408F8E66024E5FC -:10335000782410F8A681E57875F021A4248DF582F3 -:10336000E434FCF58378AEE58104C398F9E6F0080F -:10337000A3D9FA74082578F8057808E65480700C0B -:10338000E578B407F3780875780080EFE5782410C5 -:10339000F88681E57875F021A4248DF582E434FC6B -:1033A000F58378AEE58104C398F9E0F608A3D9FA6D -:1033B000D007D006D005D004D003D002D001D00071 -:1033C000D083D082D0F0D0D0D0E032C0E0C0D0C026 -:1033D00000C001C002C28E857E8D857F8BD28E7823 -:1033E0001979097A07E77004A600800BE6600816D1 -:1033F000E67004E74480F70809DAEAE57960131417 -:10340000F579700EE5782408F87600123246D28CF1 -:10341000D28DD002D001D000D0D0D0E0327581ADB5 -:10342000742A90FF93F0757F30757EF8757D607516 -:103430007CF012053F1234CE12175B90FF93E044EC -:1034400001F0B2B31234F81232A880DA22C0007C44 -:1034500001EC2408F8E660090CBC08F512329A80E9 -:10346000EED00022C0F0C082C083C000C006C007FA -:10347000ED2410F876BCED75F021A4248DF582E4DE -:1034800034FCF583C082C083A3A3E4780DF0A3D8F5 -:10349000FCEC547F75F002A42441F582E5F034354C -:1034A000F583E493FE740193F5828E83E493FE74B6 -:1034B0000193FFD083D082EFF0A3EEF0ED2408F863 -:1034C000EC4480F6D007D006D000D083D082D0F074 -:1034D00022757800757B007A08791878087600776D -:1034E000000809DAF8E478087480447FF67401442F -:1034F00010F58975B808D2ABD2A9227581ADD28EEC -:10350000D28CD2AFE57B6032FF90FD95E0548060B5 -:103510002478087908E0547FFA7B00E6547FB502EE -:10352000027BFF08D9F5EB700CEAF012344AAD04C7 -:10353000AC02123461A3A3A3DFD212329A80C57CFD -:10354000017D002204FE04F204F604EA04E604E22B -:1035500004EE04FA04A604AA04D604DA04A204A21F -:1035600004A204DE04BE04B604BA04B204CA04C64B -:1035700004C204CE04D204AE1901030022004802A2 -:1035800000480E301420C81AD0180A0C0506020391 -:1035900001020001CE0181010000C0008000600036 -:1035A0003000180010000800040002000100081894 -:1035B00028380C05100A0200000000000301100A60 -:1035C000020000000000FBE0FBF2090227000102FC -:1035D00000A0FA0904000003FF00000007058102B3 -:1035E00040000007050102400000070583030200B8 -:1035F00001220354005500530042003300340031CF -:1036000000300020002000200020002000200020AA -:073610000020000000000093 -:00000001FF diff --git a/firmware/mts_edge.fw.ihex b/firmware/mts_edge.fw.ihex deleted file mode 100644 index d14ebd647846f61ba56d2d71022bcf8ec0db70b8..0000000000000000000000000000000000000000 --- a/firmware/mts_edge.fw.ihex +++ /dev/null @@ -1,881 +0,0 @@ -:10000000F0360002001E021AFBFFFFFFFFFF023363 -:10001000F9FFFFFFFFFFFFFFFFFFFFFFFFFF0234BE -:10002000A47581D490FDE88583A0123618EC4D604C -:100030007378AF8003760018B8A0FA787F800376D3 -:100040000018B865FA78208003760018B820FA788E -:10005000208003760018B81FFA90FDDDAE83AF82D2 -:1000600090FBF81200AA6005E4F0A380F690FDE88A -:10007000A88290FDE8A982E8696005E4F20880F7AB -:100080009001081200B390010C1200B390011012FD -:1000900000B39001141200D190011A1200D1900106 -:1000A000201200D175D0001234F6020126EF6582CD -:1000B0007003EE658322E493F8740193F97402935C -:1000C000FE740393F5828E83E869700122E493F64F -:1000D000A30880F4E493FC740193FD740293FE740E -:1000E0000393FF740493F8740593F58288831200D8 -:1000F000AA700122E493A3A883A9828C838D82F045 -:10010000A3AC83AD828883898280E32121049B8014 -:1001100080049BB0B4049BFDE8049F049FFBF304A0 -:10012000A4049FFBF30504050480FED0F030F00921 -:1001300020F303F68010F7800D30F10920F303F26D -:100140008004F38001F020F404FCD0E0CC22CCC089 -:10015000E0120163020154BC0005D0F0ACF022C3F0 -:1001600013DCFC02012ABF0009ED258275F001F8BD -:10017000E622BF010FED2582F582EE3583F583750A -:10018000F004E022ED258275F002F8E222D083D05F -:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE -:1001A000E493A395F04012A3A3C3E5F033500205F6 -:1001B000832582F58250020583740193C0E0E493A5 -:1001C000C0E022D083D082F5F0E4937009740193EB -:1001D0007004A3A3800C74029365F06005A3A3A32D -:1001E00080E7740193C0E0E493C0E022120264024D -:1001F00001FB1202B80201FB1202DC0201FB30E03B -:100200000720E302E622E72230E10720E302E222B0 -:10021000E32230E202E022E493221202DC02022313 -:100220001202B8020223ABF012022DCBC5F0CB2292 -:1002300030E01020E306E6F5F008E622E7F5F009E5 -:10024000E7192230E11020E306E2F5F008E222E3AC -:10025000F5F009E3192230E206E0F5F0A3E022E42C -:1002600093F5F074019322BB0003740922BB0107CC -:1002700089828A83740422BB020789828A8374106C -:1002800022740A22020284BB0007E92582F8740165 -:1002900022BB010DE92582F582EA3583F5837404DA -:1002A00022BB020DE92582F582EA3583F5837410BD -:1002B00022E92582F87402220202B8BF0005EDF897 -:1002C000740122BF01078D828E83740422BF02074E -:1002D0008D828E83741022EDF87402220202DCBF3C -:1002E0000007ED2582F8740122BF010DED2582F58E -:1002F00082EE3583F583740422BF020DED2582F56D -:1003000082EE3583F583741022ED2582F874022283 -:10031000020310C0E0120264020328C0E01202B817 -:10032000020328C0E01202DC02032830E00B20E3C5 -:1003300004D0E0F622D0E0F72230E10B20E304D035 -:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B -:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069 -:100360002FBF000AFAEDF8E7F60809DAFA22BF0112 -:10037000128D828E83F802037809A3E7F0D8FA225F -:10038000020383FAEDF8E7F20809DAFA2202038D94 -:10039000BB014DBF001489828A83F9EDF802039FE7 -:1003A00008A3E0F6D9FA220203B0BF01228D828EA3 -:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F -:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9 -:1003D000828E83F9EDF8E0F208A3D9FA220203DD58 -:1003E000BB024DBF001289828A83F9EDF80203EF48 -:1003F00008A3E493F6D9F922BF01238D828E83FBF3 -:1004000008C9C582C9CAC583CAE493A3C9C582C93C -:10041000CAC583CAF0A3DBE9D8E722020422898295 -:100420008A83F9EDF8E493F208A3D9F922020433A0 -:10043000BF000DFAEDF8E3F60809DAFA2202043DEE -:10044000BF01128D828E83F802044A09A3E3F0D81B -:10045000FA22020455FAEDF8E3F20809DAFA220268 -:10046000045FE6FB08E6FA08E6F904F618700106F0 -:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379 -:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015 -:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6 -:1004A000000000000000000504006105730026053F -:1004B0009A00330A0B00610A770066154600610C4A -:1004C000FB006109AB006109E200610DC200610B34 -:1004D000F300610A1E00610A530061173E003317E2 -:1004E0005100341E1600431EBC0044202900442045 -:1004F0001700471EE300471F88004D1FD9004F1FFC -:10050000050058338400617CCC7DFF121CC722900B -:10051000FFFCE020E72DC2AFAE59AF58755A20E579 -:100520005A14C55A6019E4FE7F05EE4FCE24FFCE63 -:10053000CF34FFCF6007E490FF92F080ED80E08E33 -:10054000598F582212050C7D077CB71233A07D0FFE -:100550007C6E1233BA78A17A06E4F608DAFC7A06E1 -:100560001205CF7C03120E57122165E4FEFF7C0FAB -:10057000123329D2A822123214E490FC38F090FFF2 -:10058000F0E030E408740190FC39F08005E490FC60 -:1005900039F07D0A7C00122547123297221232145C -:1005A00090FC39E014700E90FFF0E04410F07C00F5 -:1005B0001225E0801990FC39E0700E90FFF0E054B5 -:1005C000EFF07C001225E080057C171225E0123246 -:1005D000972290FFF0E054ABF090FFF0E04420F061 -:1005E000228C378D367882EDF608ECF6EDFEECFDC8 -:1005F0007F019000051201F57880F67882E6FD080B -:10060000E6FCEDFEECFD7F019000041201F5540FB5 -:10061000FC7D8012176F7880E6700DAD3AAE39AF71 -:1006200038E41203187C082290FFF0E054FEF090AA -:10063000FFF0E054FDF0801E7882E6FD08E6FCED58 -:10064000FEECFD7F0190000812021725E0440190A6 -:10065000FFF3F00206DB7882E6FD08E6FCEDFEEC37 -:10066000FD7F0190000612021754FE90FFF3F08008 -:100670002B7882E6FD08E6FCEDFEECFD7F019000A4 -:1006800008120217FAEB90FFF1F01208CA400DAD04 -:100690003AAE39AF38E41203187C18227882E6FDAE -:1006A00008E6FCEDFEECFD7F0190000812021790B9 -:1006B000FFF1F01208CA400DAD3AAE39AF38E4127E -:1006C00003187C18227882E6FD08E6FCEDFEECFDBE -:1006D0007F01900006120217440190FFF3F0788327 -:1006E000E62403F618E63400F67880E624FE500986 -:1006F00090FFF0E054FDF0800790FFF0E04402F03E -:10070000E490FFF1F0788176007880E624FFFCE445 -:1007100034FFFD7881E67F00FEECD39EEF6480CD50 -:1007200064809D402F1208AF400F7881E6AD3AAE4D -:1007300039AF381203187C182290FFF2E0FC78825F -:100740008683088682ECF0788106A37882A68308E7 -:10075000A68280B51208AF400F7881E6AD3AAE3977 -:10076000AF381203187C182290FFF2E0FC788286E2 -:1007700083088682ECF07880E6AD3AAE39AF381265 -:1007800003187C00228C378D367882EDF608ECF663 -:10079000EDFEECFD7F019000051201F57881F67801 -:1007A00082E6FD08E6FCEDFEECFD7F019000041200 -:1007B00001F5540FFC7D8112176F7881E670037C80 -:1007C000082290FFF0E054FEF090FFF0E054FDF0BE -:1007D000801B7882E6FD08E6FCEDFEECFD7F0190D3 -:1007E000000812021725E090FFF3F0805B7882E6A4 -:1007F000FD08E6FCEDFEECFD7F01900006120217FD -:1008000054FE90FFF3F080217882E6FD08E6FCEDCF -:10081000FEECFD7F01900008120217FAEB90FFF149 -:10082000F01208CA40037C18227882E6FD08E6FC34 -:10083000EDFEECFD7F0190000812021790FFF1F031 -:100840001208CA40037C18227883E6240AF618E6C8 -:100850003400F6788076007881E624FFFCE434FFEB -:10086000FD7880E67F00FEECD39EEF6480CD64804F -:100870009D402178828683088682E090FFF1F01205 -:1008800008CA40037C1822788006788306E6187030 -:10089000010680C390FFF0E04401F078828683086F -:1008A0008682E090FFF1F01208CA40037C18227C97 -:1008B000002290FFF0E020E71290FFF0E030E50921 -:1008C00090FFF0E04420F0C32280E7D32290FFF0B5 -:1008D000E020E31290FFF0E030E50990FFF0E04403 -:1008E00020F0C32280E7D3228C428D417C00ED545E -:1008F000F0FDEC7003ED64307005753E0380037508 -:100900003E04AC3E120F74758300858340E541546C -:100910000FF53FE5407004E53F64037035E53E2484 -:10092000FD75F00AA42402F582E434FCF583E0307E -:10093000E60512105B8019E53E24A1F8E654FBF6AB -:1009400078ADE62405F58218E63400F583740FF0DF -:100950008059E5407004E53F64047048E53E24FD9D -:1009600075F00AA42402F582E434FCF583E030E556 -:1009700007AC42AD41121C5CE54230E21578B1E6AD -:1009800030E00F78B1E630E109E4FF04FE7C0412A8 -:10099000332978ADE62406F58218E63400F5837431 -:1009A0000FF08007E4FC7DEE121C5CC203221232C1 -:1009B00014120F7478ADE62406F58218E63400F5BB -:1009C00083E090FC38F078ADE62405F58218E63433 -:1009D00000F583E090FC39F0C2037D027C00122513 -:1009E00047123297221232147899ECF6EC24A1F8CF -:1009F000E630E1077C131225E0800F90FC39E0FD22 -:100A00007899E6FC1213F11225E012329722123285 -:100A1000147899ECF67D00120F141225E01232972B -:100A2000221232147899ECF6EC24A1F8E630E207B1 -:100A30007C131225E0801B7899E624A1F8E620E1DA -:100A4000077C121225E0800A7899E6FC1214151230 -:100A500025E0123297221232147899ECF6EC24A198 -:100A6000F8E620E2077C111225E0800A7899E6FC7E -:100A70001215161225E0123297221232147899ECD0 -:100A8000F6120F7478ADE62409F58218E63400F505 -:100A900083E090FC3FF078ADE6240AF58218E63456 -:100AA00000F583E090FC40F078ADE62403F5821871 -:100AB000E63400F583E0FC78ADE62404F58218E620 -:100AC0003400F583E0F56278ADE62402F58218E69D -:100AD0003400F583E0F5638C61E4EC333354017842 -:100AE00099F66008E56230E1037899067899E69016 -:100AF000FC41F078ABE62402F58218E63400F58379 -:100B0000E0FDA3E0540CFCED54E68C65F564E56172 -:100B100030E503436501E56220E50EE561547F7031 -:100B200008E56120E703436502E56130E3034365BF -:100B300010E56130E203436520E56154036003433F -:100B40006540E56130E103436580E56130E40343DE -:100B50006401E56130E603436408E56220E40EE5E4 -:100B600061547F7008E56120E7034364105365FB1F -:100B70005364F9AD64E56590FC3ACDF0A3CDF0E5A2 -:100B80006330E30DE5635430C4540F90FC3DF080B6 -:100B900005E490FC3DF0E563540390FC3CF0E56314 -:100BA0005404C31390FC3EF090FC3CE0700E7D3585 -:100BB0007EFC7F01740190000912014B78ADE624A0 -:100BC00008F58218E63400F583E07C00FD78ADE698 -:100BD0002407F58218E63400F583E07F004CFEEF31 -:100BE0004D90FC38F0A3CEF0CEC2037D0A7C0012FB -:100BF0002547123297221232147899ECF6789E76B5 -:100C0000010876FC087638789B760C789E12046E84 -:100C100012021D789CCBF6CB08F67F00EF24EA4049 -:100C20001FE4EF25E090365AFD93CD0493789D663E -:100C30007003ED18667006789B760080030F80DCE9 -:100C4000789AEFF6789E12046E90000212021778DE -:100C50009CCBF6CB08F65404CB54064B6004789B2F -:100C6000760B789DE630E313789E12046E900005B3 -:100C70001201F524FB5004789B760D789DE654C054 -:100C80007D0064C04D7004789B760B789E12046ED4 -:100C90009000041201F524FC5004789B760F789E96 -:100CA00012046E9000061201F524FD5004789B7624 -:100CB0000E789E12046E9000091201F524FD500476 -:100CC000789B760A789BE6702A7899E6FC120F7476 -:100CD000789E12046E78ABE6F978AAE6FA7B017486 -:100CE0000A7800120348C2037899E6FC12111778BB -:100CF0009BECF6789BE6FC1225E01232972212322A -:100D0000147899ECF6120F747899E624FD75F00AC0 -:100D1000A42414F582E434FCF583AC82AD8378AA74 -:100D20008683088682ECF9EDFA7B0A78011203B01B -:100D3000C2037899E6FC121117123297228D2B8C80 -:100D40002AED60407527017529487528FFE52A249A -:100D5000FDFCE434FFFDEC7C0325E0CD33CDDCF974 -:100D6000FCE5292CF529E5283DF528AD29AE28AF6D -:100D700027748090000612032074809000021203F2 -:100D800020120FC7E52B14603B75270175290875E4 -:100D900028FFE52A24FDFCE434FFFDEC7C0325E07C -:100DA000CD33CDDCF9FCE5292CF529E5283DF528E6 -:100DB000AD29AE28AF27E4900006120320E490008E -:100DC00002120320221232147899ECF6EC24A1F8D6 -:100DD000E630E2097899E6FC121516D2007899E619 -:100DE000FC120F74789A760090FC39E030E70478B2 -:100DF0009A7601789AE6FD7899E6FC120D3AC203DC -:100E00003000077899E6FC1214157C001225E012D8 -:100E100032972278ADE62404F58218E63400F58393 -:100E2000E04401F078ADE62404F58218E63400F5DC -:100E300083E030E00280ED78ADE6240BF58218E621 -:100E40003400F583E054F8F078ADE62402F582181A -:100E5000E63400F583E04480F022C2038C58120F80 -:100E60007478AA8683088682798B7A367B0A780121 -:100E70001203FE120E10AC587D02120D3AC203ACE2 -:100E800058121117228D538E528F518C50120F749D -:100E9000754F0078ADE62405F58218E63400F58339 -:100EA000E020E41FE54F24F64019054FC2037C18EB -:100EB0001233D790FF93E04401F0B2B3AC50120F5D -:100EC0007480D078ADE62405F58218E63400F58309 -:100ED000E020E405C2037C022278ADE62405F58219 -:100EE00018E63400F583E0540F601678ADE624056B -:100EF000F58218E63400F583E0540FF0C2037C015C -:100F00002278AC8683088682E0AD53AE52AF511290 -:100F10000318C2037C00228D318C30121516E53186 -:100F2000600FE530B4030A7C0112250F7C81122585 -:100F30000FAC30120F74E531601A78AE86830886E4 -:100F400082E054E7F0A3A3A3A3E054E7F0AC307D24 -:100F500002120D3A78AA868308868279957A367BC2 -:100F60000A78011203FEC203E53024A1F8E654FD1D -:100F7000F6AC30121117228C26300305123376801E -:100F8000F87C0A123289D203E52624FD78A7F67090 -:100F90000778AE76FF0876E078A7E67D007C04252A -:100FA000E0CD33CDDCF9FC24A078ADF6ED34FF18AC -:100FB000F678A7E675F00AA42400FCE434FCFD787A -:100FC000AAEDF608ECF61233222278ADE62402F5FB -:100FD0008218E63400F583E030E72278ADE624029B -:100FE000F58218E63400F583E0547FF078ADE6240E -:100FF00002F58218E63400F583E04480F02278AEF2 -:101000008683088682E0547FF0AD83E5822404FC69 -:10101000E43D8C82F583E0547FF078ADE6240BF557 -:101020008218E63400F583E054F8F078AFE6240146 -:10103000F58218E63400F583E04403F078AFE62447 -:1010400005F58218E63400F583E04403F078ADE658 -:101050002405F58218E63400F583740FF02278AE8B -:101060008683088682E0543FF0AD83E5822404FC49 -:10107000E43D8C82F583E0543FF078A7E624A8F89D -:10108000E6FC78AFE62401F58218E63400F583EC3F -:10109000F078A7E624A8F8E6FC78AFE62405F58208 -:1010A00018E63400F583ECF078ADE6240BF58218F1 -:1010B000E63400F583E054FB4402F52678ABE624E1 -:1010C00002F58218E63400F583E030E5034326019B -:1010D00078ADE62405F58218E63400F583E030E0CB -:1010E00003120FC7E526FC78ADE6240BF58218E65F -:1010F0003400F583ECF078ADE62405F58218E6348B -:1011000000F583740FF078AE8683088682E0448011 -:10111000F0A3A3A3A3E04480F0228C2A120F7478DA -:10112000ABE62408F58218E63400F583E0FC78ADE0 -:10113000E6240AF58218E63400F583ECF078ABE695 -:101140002407F58218E63400F583E0FC78ADE62448 -:1011500009F58218E63400F583ECF078AA86830856 -:101160008682E0FDA3E0FCEDFE78ADE62408F58282 -:1011700018E63400F583EEF0ECFE78ADE62407F5D2 -:101180008218E63400F583EEF08C298D28C3EC94A8 -:1011900005ED940C400575277C8033D3E529940137 -:1011A000E5289403400575273C8023D3E5299481E5 -:1011B000E528940140057527188013D3E52994602C -:1011C000E5289400400575270C8003752708AF2794 -:1011D000E4EF547C4483FF8F27E527FC78AFE624B7 -:1011E00001F58218E63400F583ECF0E527FC78AFD2 -:1011F000E62405F58218E63400F583ECF0E527FCDB -:1012000078A7E624A8F8ECF678ADE62402F5821873 -:10121000E63400F583E0F52778ABE62402F5821882 -:10122000E63400F583A3E030E3175327C778ABE635 -:101230002405F58218E63400F583E0903686934263 -:101240002778ABE62402F58218E63400F583E03017 -:10125000E70543274080035327BF5327FB78ABE6BE -:101260002406F58218E63400F583E0600343270482 -:101270005327FC78ABE62404F58218E63400F583A6 -:10128000E04227432780E527FC78ADE62402F5827B -:1012900018E63400F583ECF078ADE62404F5821806 -:1012A000E63400F583E0F52778ABE62402F58218F2 -:1012B000E63400F583A3E030E1055327DF800343E4 -:1012C000272078ABE62402F58218E63400F583E0A7 -:1012D00030E4055327EF800343271078ABE6240959 -:1012E000F58218E63400F583E0B40203432702E5F3 -:1012F00027FC78ADE62404F58218E63400F583EC8B -:10130000F078ADE62403F58218E63400F583E0F5C5 -:101310002778ABE62409F58218E63400F583E070FF -:101320000553277F800343278078ABE62402F582AC -:1013300018E63400F583A3E030E00543272080035E -:101340005327DF78ABE62402F58218E63400F583F4 -:10135000E030E30543274080035327BF78ABE62402 -:1013600002F58218E63400F583E030E005432710EB -:1013700080035327EF78ABE62402F58218E63400A9 -:10138000F583A3E030E40543270880035327F7786B -:10139000ABE62402F58218E63400F583A3E030E5DD -:1013A0000543270480035327FB78ABE62402F5822C -:1013B00018E63400F583A3E030E6054327018003F7 -:1013C0005327FE78ABE62402F58218E63400F58355 -:1013D000A3E030E70543270280035327FDE527FC00 -:1013E00078ADE62403F58218E63400F583ECF0C20C -:1013F000037C00228D278C26ED54031460037C109F -:1014000022E527547C24FC40037C0B22E52624A102 -:10141000F8E64402F67C00228C30120F74E530248A -:10142000A1F8E620E24FAC307D02120D3AE53024FF -:10143000FE4428FC78AE8683088682ECF0AF83E514 -:10144000822404FEE43FFFEC8E828F83F07C038CC9 -:101450002CE52CFC78AFE62401F58218E63400F583 -:1014600083ECF0E52CFC78AFE62405F58218E63431 -:1014700000F583ECF0752D01752F48752EFFE530D2 -:1014800024FDFCE434FFFDEC7C0325E0CD33CDDC12 -:10149000F9FCE52F2CF52FE52E3DF52E78AFE6244F -:1014A00004F58218E63400F583E054E7F52CAD2FFF -:1014B000AE2EAF2DE4900002120320E4900006123D -:1014C00003201201EF30E503432C10E52CFC78AF2C -:1014D000E62404F58218E63400F583ECF012105B84 -:1014E00078ADE62406F58218E63400F583E0C20301 -:1014F000FCE53024A1F8E64404F68C2CE530540FCA -:10150000C454F07E00FFEEEF44047D00FFEC4EFC7F -:10151000ED4FFD121CC77C00228C2F120F74120F8E -:10152000FB78AE8683088682E05408F0A3A3A3A3C9 -:10153000E05408F0AC2F7D02120D3AC203E52F24CF -:10154000A1F8E654FBF67C0022123214789AECF6ED -:10155000EC24A1F8E630E10A7D007C131225471245 -:101560003297789AE624A1F8E64401F6789AE6FCE8 -:10157000120F74789AE624FD75F00AA42414F582FB -:10158000E434FCF58378AAE6FA08E6F97B0A7801E8 -:101590001203B078AA868308868279957A367B0A08 -:1015A00078011203FE120FC7C203789AE6FC1211EB -:1015B000177899ECF6EC600A7D007C08122547123A -:1015C0003297789AE6FC120F7478ADE62404F5821F -:1015D00018E63400F583E0441054DFFC78ADE624CF -:1015E00004F58218E63400F583ECF07899ECF6C245 -:1015F000037CC81233D7789AE6FC120F7478ADE6F4 -:101600002404F58218E63400F583E054EFF0C203B9 -:101610007CC81233D7789AE6FC120F7478ADE624B2 -:1016200004F58218E63400F583E04410F0C2037C30 -:10163000C81233D7789AE6FC120F7478ADE624040A -:10164000F58218E63400F583E04420F0C2037CF014 -:101650001233D7789AE6FC120F7478ADE62405F5BC -:101660008218E63400F583E030E415C203789AE688 -:1016700044107F00FE7C0712332912329702173D77 -:1016800078ADE62404F58218E63400F583E054CF03 -:10169000F0C2037CC81233D7789AE6FC120F747834 -:1016A000ADE62404F58218E63400F583E04430F01A -:1016B000C2037CF01233D7789AE6FC120F7478AD2F -:1016C000E62405F58218E63400F583E030E414C220 -:1016D00003789AE644107F00FE7C07123329123209 -:1016E00097805D78ADE62404F58218E63400F58332 -:1016F000E054EFF078ADE62404F58218E63400F506 -:1017000083E054DFF0789AE624FD75F00AA42414EF -:10171000F582E434FCF583AC82AD8378AA86830835 -:101720008682ECF9EDFA7B0A78011203B0C20378E5 -:101730009AE6FC1211177D007C0B12254712329796 -:1017400022123214E490FC39F07D027C001225470D -:10175000123297221232147C001225E012329722A4 -:10176000743C90FBE0F0743E90FBE0F0E490FC28C9 -:10177000F0228D358C34ECB401028003D34002801A -:1017800028B402028003D34008A835E625E0F6809D -:1017900018B404028003D3400AA835E625E025E00A -:1017A000F68006A83576008000228C3C8D3BEDFE4D -:1017B000ECFD7F0175660675670090FC29120477C1 -:1017C0001201EFB480028006D3500302187090FC1F -:1017D000291204899000031201F554F0B4300280FC -:1017E00003D3405F90FC291204899000081202176D -:1017F000FAFDEBFE7F0190FC2C120477EECD9036C3 -:101800009FFCE493FF740193FEF9EFFA7B01EAFF7A -:10181000E9FEECC39EED9F40259036A1E493FD7454 -:101820000193FCEDFEECFD7F01EECDFC90FC2EE083 -:10183000D39C90FC2DE09D50057566808033121975 -:101840008E802EB460028003D3400BAC3CAD3B12C3 -:1018500007828C66801BB41003B34010C3B420030E -:10186000B34009C3B440028003D340007566818051 -:10187000008075B481028003D3406B90FC29120470 -:10188000899000031201F554F0B430028003D34074 -:101890001D90FC29120489900008120217FAFDEB32 -:1018A000FE7F0190FC2F1204771218F88036B46086 -:1018B000028003D34013753A67E4F539F538AC3C40 -:1018C000AD3B1205DE8C66801BB41003B34010C321 -:1018D000B42003B34009C3B440028003D340007571 -:1018E0006681800080028000E566FC90FC2912047D -:1018F00089EC900002120320AC672290FC291204AC -:10190000899000041201F5600474018001E4A2E0F2 -:10191000920190FC29120489ED2403FD50010E90E0 -:10192000FC2C12047790FC29120489900005120106 -:10193000F5F5679000041201F5540FFC7D6712174E -:101940006FE5677004756608227566007884760016 -:101950007884E6C39567503890FC2F1204891201F1 -:10196000EFFC90FC2C120489EC12031830010E904D -:10197000FC31E004F090FC307003E004F078840661 -:1019800090FC2EE004F090FC2D7003E004F080C089 -:101990002290FC2AE0FDA3E0FCEDFEECFD7F01EDD2 -:1019A000240AFD50010E90FC3212047790FC29129B -:1019B00004899000041201F5540FB401028003D38E -:1019C000401790FC321204890DED70010E90FC2F2F -:1019D00012047778887601804EB402028003D340E7 -:1019E0001990FC32120489ED2402FD50010E90FC86 -:1019F0002F12047778887602802DB404028003D3F6 -:101A0000401990FC32120489ED2404FD50010E901F -:101A1000FC2F12047778887604800CB400028003CF -:101A2000D340007566082290FC29120489900005B5 -:101A30001201F5F567788576007885E6C3956740ED -:101A400003021AF6788676007886E6C37888965080 -:101A50007690FC2C1204891201EFFC90FC321204E7 -:101A6000921201E9F45CFC1201E9F890FC2F1204D7 -:101A700089E8C0E01201EFC8D0E0C8584CFC90FCE7 -:101A80002C120489EC1203187887ECF690FC31E0F4 -:101A900004F090FC307003E004F009E970010A9052 -:101AA000FC3212048090FC29120489900004120177 -:101AB000F530E40E90FC2EE004F090FC2D7003E075 -:101AC00004F078860680817888E6FDE4FEFFEECD9E -:101AD000FC90FC31E02CF090FC30E03DF07888E6A2 -:101AE000FDE4FEFFEECDFC90FC34E02CF090FC33E6 -:101AF000E03DF0788506021A367566002222C0E0C5 -:101B0000C0F0C082C083C0D0E8C0E0E9C0E0EAC055 -:101B1000E0EBC0E0ECC0E0EDC0E0EEC0E0EFC0E024 -:101B200090FF92E01201C01B49301B49321B58380C -:101B30001B6A3A1B7C3E1B94441B88461BA0501B0F -:101B4000E2521BC1541C035600001C2490FF92E07B -:101B50007F00FE7C01123329021C34E4FF04FE7C6A -:101B600003123329742090FFFEF0021C34E4FF04BA -:101B7000FE7C02123329744090FFFEF0021C34E414 -:101B8000FF04FE7C04123329021C34E4FF04FE7CB3 -:101B900005123329021C34E4FF04FE7C06123329AB -:101BA000021C3490FFA5E07D0090FBF8CDF0A3CDA2 -:101BB000F090FBF9E0FCF58390FBF8E04433FD1274 -:101BC0001CC7807390FFB5E07D0090FBFACDF0A3B9 -:101BD000CDF090FBFBE0FCF58390FBFAE04443FD85 -:101BE000121CC7805290FFA6E07D0090FBFCCDF058 -:101BF000A3CDF090FBFDE0FCF58390FBFCE04434CA -:101C0000FD121CC7803190FFB6E07D0090FBFECD39 -:101C1000F0A3CDF090FBFFE0FCF58390FBFEE044E9 -:101C200044FD121CC7801090FF92E07D00FCED4443 -:101C3000AAFD121CC78000E490FF92F0D0E0FFD014 -:101C4000E0FED0E0FDD0E0FCD0E0FBD0E0FAD0E058 -:101C5000F9D0E0F8D0D0D083D082D0F0D0E03205F7 -:101C600081058105810581A881181818EDF608EC19 -:101C7000F690FF5AE020E70280F790FF59E07D00E0 -:101C8000A88118CDF6CD08F67D03A881E618FCE6FC -:101C9000CC25E0CC33CCDDF9CCF6CC08F6A8811805 -:101CA000E644F8F6A881181818E6FD08E6FCA881B5 -:101CB000188683088682EDF0A3ECF0740290FF5A38 -:101CC000F0158115811581158122E5812405F581A5 -:101CD000E4A88118F6A88118181818EDF608ECF693 -:101CE00090FBF5E024F85003021DE8E4A8811818E1 -:101CF000F6A88118E6FEA88118181818E6FD08E66F -:101D0000FC7F00EF24F8404DE4EF25E0247DF582D0 -:101D1000E434FCF583E0FBA3E06C7003FAEB6D7038 -:101D2000097401A8811818F6802BE4EF25E0247DC2 -:101D3000F582E434FCF5837A00E054F0CCF8CCCDA5 -:101D4000F9CDFB7800E954F0F9EA687002EB6970AC -:101D5000010E0F80AEA88118EEF6A8811818181889 -:101D6000EDF608ECF6A881EFF6A8811818E6707970 -:101D7000A88118E624F74071A88118181818E654AD -:101D80000FA881F664046017A881E664036010A8B8 -:101D90008118181818E6FD08E6FC121C5C804A7CC5 -:101DA0000A123289A88118181818E6FD08E6FC9076 -:101DB000FBF4E025E0247DF582E434FCF583EDF0CE -:101DC000A3ECF090FBF4E0FFE4EF045407FF90FB7A -:101DD000F4F090FBF5E004F012332290FBF6E07093 -:101DE00008E4FEFF7C0F123329802790FBF7E00404 -:101DF000F0543F701D90FBF7E044FE7D00FC90FB2B -:101E0000F4E025E0247DF582E434FCF583EDF0A3D5 -:101E1000ECF0E58124FBF58122788B7600788C76D6 -:101E200000740190FBF6F012321490FBF5E060575D -:101E30007C0A12328990FBF3E025E0247DF582E4F0 -:101E400034FCF583E0FDA3E0FC90FBF3E025E02407 -:101E50007DF582E434FCF583E4F0A3F090FBF3E03D -:101E6000FFE4EF045407FF90FBF3F090FBF5E01460 -:101E7000F07889EDF608ECF61233227889E6FD0851 -:101E8000E6FC1208E580A312337690FF93E044014C -:101E9000F0B2B3788B06B6000D788B7600788CE6BE -:101EA000F40404788CF68082E490FBF6F090FBF565 -:101EB000E07D00FCED44CFFD121C5C123297221233 -:101EC0003214E5706449456F601590FF83E0540F4C -:101ED0007D00D39570ED956F500512305D80031233 -:101EE000312D12329722123214E5706449456F6029 -:101EF00005123167800E90FF80E04408F090FF8368 -:101F0000E0547FF0123297221232148C54EC54F0C9 -:101F1000B41015756A357569FC756801E56A2403A6 -:101F2000F56AE5693400F569E4F557F556E556C3F9 -:101F300094015027E554540FFCAD6AAE69AF6812A6 -:101F40000E828C55EC60028012056AE56A7002050B -:101F5000690557E5577002055680D2E554540F24A1 -:101F6000A1F8E654FEF6E554540F7F00FE7C1212F1 -:101F70003329E5551470097D007C09122547800737 -:101F8000AD577C001225471232972212321490FF6F -:101F9000FCE04402F090FF00E030E71390FF83E0A4 -:101FA0004480F0436D8090FFFCE04401F08011908C -:101FB000FF82E04408F0536D7F90FFFCE054FEF098 -:101FC00090FF81E04480F01225FA90FFFEE0440586 -:101FD000F090FFFCE054FDF0123297221232147C94 -:101FE000011233D778B1E64402F674FEFC04FD1208 -:101FF0001CC790FF5AE030E70280F7E4F54E754DBC -:1020000010AC4EAD4DE54E154E7002154DEC4D60C9 -:102010000280EE438701123297221232147C0212A0 -:1020200032A378B1E654FDF61232972212321478B8 -:10203000B1E630E02C78B1E630E12678B1E6FCF587 -:102040008318E644F0FD121C5C90FFFCE04420F095 -:102050007C021233D778B1E654FDF6741A90FFFE75 -:10206000F078B1E6FCF58318E644F1FD121C5C1231 -:10207000329722756D0090FFFFE06003436D01759C -:102080006E00E4F56CF56BE4F56F7570497484903F -:10209000FF82F0748490FF80F0748090FF58F07499 -:1020A0008090FF5AF0AD46AF457E00EE24FE50030F -:1020B00002213FE4EE75F007A4247FF582E434F8B2 -:1020C000F583E0FFE4EF5480FDE4EF540F14FFEDDF -:1020D0006038E4EF75F008A42448F582E434FFF595 -:1020E000837490F0E4EF75F008A4244AF582E43498 -:1020F000FFF5837480F0E4EF75F008A4244EF582B8 -:10210000E434FFF5837480F08034E4EF75F008A4C4 -:102110002408F582E434FFF5837490F0E4EF75F061 -:1021200008A4240AF582E434FFF583E4F0E4EF75B3 -:10213000F008A4240EF582E434FFF583E4F00E02E7 -:1021400020A88D468E448F45747F90FFFDF07490DB -:1021500090FFFCF0228C58EC24F65006E55824370A -:10216000FC22E5582430FC22D2B0D2B1C2B41225F0 -:1021700044EC700302227F755C03AE5B7F00E55C7C -:10218000155C6480247F5035EF2400F582E434FB35 -:10219000F583E0FE24FE501EEF7D00FCE4FB74742A -:1021A000C39CFAEB9DFBEE7D00FCEAC39CED6480D2 -:1021B000CB64809B50028005EF2EFF80C18E5B8F29 -:1021C0005AE55C6480247F500302227FE55A248E06 -:1021D000500302227F855A5D755B00AE5AAF5B905B -:1021E00036CAE493F55CE55C155C6480247F501886 -:1021F000EE2400F582E434FBF583E0FCEF9036CA70 -:10220000936C70040E0F80DE8E5A8F5BE55C6480E9 -:10221000247F406E755E017560E8755FFFE55D24A3 -:1022200002F55A755C07E55C334057AD60AE5FAFB1 -:102230005EE55CF5823395E0F5831201F5C4540F39 -:10224000FC122152E55A2400F582E434FBF583ECBC -:10225000F0055A055AAD60AE5FAF5EE55CF58233BE -:1022600095E0F5831201F5540FFC122152E55A2432 -:1022700000F582E434FBF583ECF0055A055A155C51 -:1022800080A4740290F851F090F86B79A37A367BB1 -:102290002778011203FE756A357569FC756801E4DB -:1022A00090FF83F0748090FF81F0755902E55975B5 -:1022B000F007A4247FF582E434F8F583E07893F600 -:1022C000FC540F14FC7893ECF6E55975F007A42440 -:1022D00081F582E434F8F583E0789676FD0876E8B7 -:1022E000FC7893E675F008A42448F582E434FFF501 -:1022F00083E4F07893E675F008A4244FF582E43483 -:10230000FFF583ECF07896E6FF08E67E03CFC31373 -:10231000CF13DEF9FE7893E675F008A42449F58220 -:10232000E434FFF583EEF07893E675F008A4244AD0 -:10233000F582E434FFF5837480F07894ECF67D0048 -:102340007897E62CF618E63DF67896E6FD08E67CEA -:1023500003CDC313CD13DCF9FC7893E675F008A424 -:10236000244DF582E434FFF583ECF07893E675F0C4 -:1023700008A4244EF582E434FFF583E4F07896E671 -:10238000FD08E6FC7893E6FF7E00EE24FE50030293 -:1023900024FEE4EE75F007A4247FF582E434F8F51A -:1023A00083E0FFE4EF5480FAE4EF540F14FFE4EE0F -:1023B00075F007A42481F582E434F8F583E078947D -:1023C000F6E4EE1313548024F0F8E434FDF9E8FC4D -:1023D000E9FD8A5AEA700302246BE4EF75F008A461 -:1023E0002448F582E434FFF583E4F07894E6FAE4D7 -:1023F000EF75F008A4244FF582E434FFF583EAF08A -:10240000EDFBEC7A03CBC313CB13DAF9FAE4EF75E7 -:10241000F008A42449F582E434FFF583EAF07894C7 -:10242000E67B00FAEC2AFCED3BFDFBEC7A03CBC328 -:1024300013CB13DAF9FAE4EF75F008A4244DF58212 -:10244000E434FFF583EAF0E4EF75F008A4244AF5DC -:1024500082E434FFF5837480F0E4EF75F008A4247F -:102460004EF582E434FFF5837480F00224FAE4EF41 -:1024700075F008A42408F582E434FFF583E4F078CD -:1024800094E6FAE4EF75F008A4240FF582E434FF33 -:10249000F583EAF0EDFBEC7A03CBC313CB13DAF947 -:1024A000FAE4EF75F008A42409F582E434FFF5831B -:1024B000EAF07894E67B00FAEC2AFCED3BFDFBECBD -:1024C0007A03CBC313CB13DAF9FAE4EF75F008A45F -:1024D000240DF582E434FFF583EAF0E4EF75F008AB -:1024E000A4240AF582E434FFF583E4F0E4EF75F008 -:1024F00008A4240EF582E434FFF583E4F00E0223F1 -:10250000878E597896EDF608ECF67893EFF6122060 -:1025100070228C26EC30E718E526540F1475F0086D -:10252000A42448F582E434FFF583E054DFF08016FC -:10253000E526540F1475F008A42408F582E434FF4E -:10254000F583E054DFF0227C0022EC90FC37F08C25 -:1025500024ED2403F5257D00D39572ED957140039C -:10256000857225E52524B75009752503740290FC72 -:1025700037F0AC2512315222E4F56CF56B12257E52 -:102580002290FC35E06573600E740490FC37F0E433 -:10259000F56B756C0380467D73E4FEFF79357AFC3C -:1025A0007B0174057800120348E56C2403F56CE5A3 -:1025B0006B3400F56BE56CD39572E56B9571400655 -:1025C00085726C85716BD3E56C9448E56B94004023 -:1025D0000C740290FC37F0E4F56B756C03AC6C1274 -:1025E000315222EC90FC37F0E4F56CF56B8C32EC58 -:1025F000600512314380057C001231522290FF9316 -:10260000E04401F0B2B390FF04E0F54A90FF06E029 -:10261000FDA3E0ED7D00FC7D00FC90FF06E0FFA344 -:10262000E07E00FFE4FEEC4EFCED4FFDC3EC944871 -:10263000ED9400502290FF06E0FDA3E0ED7D00FC4C -:102640007D00FC90FF06E0FFA3E07E00FFE4FEECCF -:102650004EFCED4FFD8004E4FD7C488C728D719042 -:10266000FF02E0FDA3E0ED7D00FC7D00FC90FF0299 -:10267000E0FFA3E07E00FFE4FEEC4EF54CED4FF5ED -:102680004B756A357569FC7568017D357EFC7F0187 -:102690007973E4FAFB74057800120348754900E584 -:1026A0004924FE4019AD6AAE69AF68E4120318050B -:1026B000490DED70010E8D6A8E698F6880E1756A33 -:1026C000357569FC75680178B3E614184660030235 -:1026D00027927890E6FF08E6FE788EE4F608F6C3C7 -:1026E000788FE6940218E69400501DE4FEFFC3EED6 -:1026F00094E8EF940350070EBE00010F80F0788F2E -:1027000006E61870010680D77890EFF608EEF6D24C -:10271000B47890E6FF08E6FE788EE4F608F6C37813 -:102720008FE6941E18E69400501DE4FEFFC3EE945D -:10273000E8EF940350070EBE00010F80F0788F067B -:10274000E61870010680D77890EFF608EEF6C2B171 -:102750007890E6FF08E6FE788EE4F608F6C3788FF8 -:10276000E6943A18E69400501DE4FEFFC3EE94E8A8 -:10277000EF940350070EBE00010F80F0788F06E63D -:102780001870010680D77890EFF608EEF6D2B1788F -:10279000B2E4F608F690FF00E05460B40002800650 -:1027A000D35003022D9BE54A540FF549E54A548066 -:1027B000A2E0920290FF01E012018A000B2D962701 -:1027C000D428F22D9629FE2D962AE12B152C7C2C4F -:1027D0007F2CBF2D3F2D6DE56D30E70EE54C454B51 -:1027E0007008E572640245716003022D9890FF0045 -:1027F000E0541FB400028003D34029E54A6003027D -:1028000028EFAD6AAE69AF68740112031878B1E6BB -:1028100030E00BAD6AAE69AF6874021203187C0237 -:1028200012315222B401028003D3401BE56D20E136 -:1028300007E54A60030228EFE54A24FE5003022818 -:10284000EF7C0212315222B402028006D3500302FE -:1028500028EDE56D20E10DE54A6009E54A648060F8 -:10286000030228EFAC4A1231D940030228EFE549B0 -:10287000702530021190FF80E05408AD6AAE69AF58 -:1028800068120318800F90FF82E05408AD6AAE69A9 -:10289000AF68120318803D154930021DE54975F0F7 -:1028A00008A42448F582E434FFF583E05408AD6AB7 -:1028B000AE69AF68120318801BE54975F008A424BF -:1028C00008F582E434FFF583E05408AD6AAE69AFE1 -:1028D00068120318AD6AAE69AF681201EF600BAD04 -:1028E0006AAE69AF6874011203187C021231522279 -:1028F0008000022D98E56D20E706E57245716003C2 -:10290000022D9890FF00E0541FB400028003D340D2 -:102910001AE54C14454B7004E54A60030229FB7824 -:10292000B1E654FEF67C0012315222B4010280035B -:10293000D3402AE56D20E108E56D20E0030229FB84 -:10294000E56D30E004E54A700BE56D30E109E54ADC -:1029500024FE50030229FB7C0012315222B40202F1 -:102960008006D350030229F9E54C454B6003022948 -:10297000FBAC4A1231D940030229FBE56D20E10787 -:10298000E56D20E0028077E56D30E006E549600204 -:10299000806CE549700F90FF82E054F7F090FF8063 -:1029A000E054F7F022E549B401028003D340097DE9 -:1029B000017C03120F148011B402028003D340097A -:1029C0007D017C04120F1480001549300215E54981 -:1029D00075F008A42448F582E434FFF583E054F749 -:1029E000F08013E54975F008A42408F582E434FF6B -:1029F000F583E054F7F07C00123152228000022D62 -:102A000098E56D20E706E57245716003022D989008 -:102A1000FF00E0541FB400028003D3401AE54C14B9 -:102A2000454B7004E54A6003022ADE78B1E64401B2 -:102A3000F67C0012315222B401028003D34029E512 -:102A40006D20E108E56D20E003022ADEE56D30E04F -:102A500004E549700BE56D30E108E54924FE5002BC -:102A6000807F7C0012315222B402028003D3406F77 -:102A7000E54C454B60028069AC4A1231D940028076 -:102A800060E56D20E107E56D20E0028054E54970C6 -:102A90001430020990FF80E04408F0800790FF8224 -:102AA000E04408F022E56D30E1331549300215E5C8 -:102AB0004975F008A42448F582E434FFF583E04426 -:102AC00008F08013E54975F008A42408F582E43481 -:102AD000FFF583E04408F07C00123152228002802E -:102AE00000022D98E56D20E712E5724571700CE546 -:102AF0004A700890FF00E0541F6003022D98E54CD7 -:102B000090FFFFF090FFFFE06005436D01800353ED -:102B10006DFE7C0012315222E56D30E70EE5724504 -:102B200071600890FF00E0541F6003022D98AD4BC8 -:102B3000E54CED7D00FC7D00FCBD00028003022C15 -:102B400077B401028003D34032E54A7005E54CFCBE -:102B50006003022C79756A407569F8756801D3E5E0 -:102B6000729412E57194004006E4FD7C128004AC7E -:102B700072AD718C708D6F12316722B402028003C6 -:102B8000D34059E54A6003022C79E54CFC70277567 -:102B90006A527569F8756801D3E5729419E5719404 -:102BA000004006E4FD7C198004AC72AD718C708D20 -:102BB0006F1231678025756A6B7569F8756801D386 -:102BC000E5729427E57194004006E4FD7C278004BB -:102BD000AC72AD718C708D6F12316722B4030280BC -:102BE00006D35003022C77E54CF549700F90FF0493 -:102BF000E0FDA3E04D6003022C79801890FB02E019 -:102C0000FDA3E0FC90FF05E06C700790FF04E06D11 -:102C100060028068E4F570F56F7F00E54914C549EE -:102C2000600FEF2400F582E434FBF583E02FFF8092 -:102C3000EA8F4AE54A2400F582E434FBF583E07D1F -:102C400000D39572ED95714006AC72AD71800FE5C1 -:102C50004A2400F582E434FBF583E07D00FC8C70AF -:102C60008D6FE54A2400FCE434FBFDFEECFD7F01A2 -:102C70008D6A8E698F68123167228000022D98025A -:102C80002D98E56D30E719E5721445717012E54A2B -:102C9000700EE54C454B700890FF00E0541F600338 -:102CA000022D98E56D20E008E56D20E103022D98E6 -:102CB000756A6EE4F569F568E4F56F04F570123134 -:102CC0006722E56D20E727E57245717021E54A70BE -:102CD0001DE54C6402454B600DE54C14454B600608 -:102CE000E54C454B700890FF00E0541F6003022D37 -:102CF00098E56D20E008E56D20E103022D98854CF4 -:102D00006EE56E7010436D01536DFDD2B078B2E484 -:102D1000F608F68027E56E64026007E56E1460022F -:102D20008079536DFE436D02E56E64026005E56EC9 -:102D300014700978B2E4F60804F6C2B07C001231CF -:102D40005222E56D30E71AE5721445717013E54AB9 -:102D5000700FE54C454B700990FF00E0541F146064 -:102D6000028038E56D20E10280317C01123152226F -:102D7000E56D20E715E5724571700FE54C454B7028 -:102D80000990FF00E0541F146002800FE56D20E100 -:102D90000280087C00123152228000023059B44077 -:102DA000028006D3500302304F90FF01E090FC35C3 -:102DB000F0E54A90FC36F0E490FC37F0E56A240335 -:102DC000F56AE5693400F569AD4BE54C856A8285A5 -:102DD0006983CDF0A3CDF090FF01E01201C02E0673 -:102DE000012E2C022E56032E80042ECE052F0B060C -:102DF0002F31072F57082F83092FA90B2FCF0C2F07 -:102E0000DE802FDE810000303CE56D20E7067C058A -:102E10001225E0227D527E367F0279387AFC7B01D2 -:102E2000740878001203487D087C0012254722E5CB -:102E30006D20E7067C051225E022E54AB403004038 -:102E400010B40500500BE54A7F00FE7C10123329B8 -:102E5000227D007C0712254722E56D20E7067C05D0 -:102E60001225E022E54AB403004010B40500500BDF -:102E7000E54A7F00FE7C11123329227D007C071277 -:102E8000254722E56D20E7067C051225E022E54A6C -:102E9000B405028003D3400AE4FF04FE7C0A123327 -:102EA0002922B401028003D3400AE4FF04FE7C0817 -:102EB00012332922B403004010B40500500BE54A38 -:102EC0007F00FE7C13123329227D007C07122547E8 -:102ED00022E56D20E734D3E5729448E57194005003 -:102EE00006E572457170067C021225E022E54AB4BF -:102EF0000103B3400BC3B403004009B406005004FF -:102F00001231FF227C071225E02212257E22E56D78 -:102F100020E71DE54AB403004010B40500500BE55E -:102F20004A7F00FE7C16123329227C071225E022FC -:102F300012257E22E56D20E71DE54AB4030040100E -:102F4000B40500500BE54A7F00FE7C19123329229C -:102F50007C071225E02212257E22E56D20E72374EE -:102F60008190FF93F0E54AB403004010B40500508F -:102F70000BE54A7F00FE7C17123329227C071225BD -:102F8000E02212257E22E56D20E71DE54AB403000C -:102F90004010B40500500BE54A7F00FE7C18123348 -:102FA00029227C071225E02212257E22E56D20E7EA -:102FB0001DE54AB403004010B40500500BE54A7FFC -:102FC00000FE7C15123329227C071225E0221225EF -:102FD0007E22E56D20E7067C071225E02212257E81 -:102FE00022E56D30E72090FF00E0541F701090FF45 -:102FF00001E0B48005122575800312257E227D0034 -:103000007C051225472290FF00E0541F60067C05D6 -:103010001225E022D3E5729448E5719400500BC369 -:10302000E5729407E571940050067C031225E022B6 -:10303000E54AB405041231FF227C071225E022E59F -:103040006D30E7087D007C05122547227C0512259E -:10305000E022B420028003D34000800012312D22F0 -:1030600075430090FF83E0540FD395434024E5431C -:1030700024F0F582E434FEF583E0AD6AAE69AF6812 -:1030800012031805430DED70010E8D6A8E698F686D -:1030900080D1E5437D00FCC3E5709CF570E56F9D34 -:1030A000F56FE570456F6006E490FF83F02290FFB6 -:1030B00082E04408F0E4F56F75704990FC35E0B4A7 -:1030C00005028003D3404090FC36E0F543B405028E -:1030D0008003D3400AE4FF04FE7C0B12332922B4A0 -:1030E00001028003D3400AE4FF04FE7C0912332965 -:1030F00022B403004010B40500500BE5437F00FEEE -:103100007C141233292222B480004023B482005060 -:103110001E7C357DFC1217A77D008C6C8D6B90FC9E -:1031200037E0600512312D80057C001231522222D9 -:1031300090FF83E0547FF090FF82E04408F090FF1E -:1031400080E04408F02290FF82E04408F090FF8085 -:10315000E04408F0228C237D008C708D6F756A35F9 -:103160007569FC7568011231672290FF83E0547F16 -:10317000F0E5706449456F700122C3E5709408E57D -:103180006F94004015752108E5217D00FCC3E570B2 -:103190009CF570E56F9DF56F8009857021E4F56FF2 -:1031A000757049752200E522C395215026AD6AAE9F -:1031B00069AF681201EFFCE52224F8F582E434FEE1 -:1031C000F583ECF005220DED70010E8D6A8E698F8E -:1031D0006880D3E521547F90FF81F0228C487F00E6 -:1031E000EF24FD4019E4EF75F007A4247FF582E495 -:1031F00034F8F583E065487002D3220F80E28F47F0 -:10320000C32285727085716F90FF82E054F7F09051 -:10321000FF83E0547FF022C000C001C002C006C09E -:1032200007E5782408F8860653067F7CFF1232896A -:103230007C007D00E57B6046FF90FD95E0547F6E4D -:10324000700FC083C082A3E0FDA3E0FCA3157B80C8 -:1032500007A3A3A3DFE68026DF06D082D083801EEB -:10326000E0F8A3E0F9A3E0FAD082D083E8F0A3E984 -:10327000F0A3EAF0A3C083C082A3A3A380DA123331 -:1032800022D007D006D002D001D0002285A87A75BE -:10329000A888EC70027C3F8C7922E5782408F876C7 -:1032A0000012337680FBC000C001C002C006C00718 -:1032B000AE047CFF123289E57B6042FF90FD95E011 -:1032C000547F6E700BC083C082A3A3A3157B8007BD -:1032D000A3A3A3DFEA8026DF06D082D08380D8E0D4 -:1032E000F8A3E0F9A3E0FAD082D083E8F0A3E9F0F4 -:1032F000A3EAF0A3C083C082A3A3A380DA7808085E -:103300007918097C01E6547F6E700676007700809C -:103310000608090CBC08EE123322D007D006D002F2 -:10332000D001D00022757900857AA822C0F0C08231 -:10333000C083C3E57B24E8500512337680F4EC604B -:1033400031903651E493C39C4028C0047CFF123274 -:1033500089D004430480E57B75F003A42495F582AD -:10336000E434FDF583ECF0EFA3F0EEA3F0057B125F -:103370003322D083D082D0F022C0047C20D28CD2E1 -:103380008DD504FDD0042275A80075880075B8009D -:1033900075F00075D000E4F8900000F608B800FB66 -:1033A000020000C3ED940250047D037CE8ECF4FCC1 -:1033B000EDF4FD0CBC00010D8C7F8D7E22C3EC94DE -:1033C000BCED940250047D077CD0ECF4FCEDF4FDE0 -:1033D0000CBC00010D8C7D8D7C22EC700122C000A4 -:1033E000E5782418F8A604E5782408F8C6547FF692 -:1033F000E630E703D0002212337680F4C28C857C5D -:103400008C857D8AD28CC0E0C0D0C0F0C082C083E1 -:10341000C000C001C002C003C004C005C006C00790 -:10342000121AFAE5782408F8E66024E5782410F802 -:10343000A681E57875F021A4248DF582E434FCF5AD -:103440008378B4E58104C398F9E6F008A3D9FA7447 -:10345000082578F8057808E65480700CE578B407FC -:10346000F3780875780080EFE5782410F88681E518 -:103470007875F021A4248DF582E434FCF58378B4CA -:10348000E58104C398F9E0F608A3D9FAD007D0067D -:10349000D005D004D003D002D001D000D083D08298 -:1034A000D0F0D0D0D0E032C0E0C0D0C000C001C069 -:1034B00002C28E857E8D857F8BD28E781979097AAE -:1034C00007E77004A600800BE6600816E67004E7C4 -:1034D0004480F70809DAEAE579601314F579700E8B -:1034E000E5782408F87600123322D28CD28DD002EF -:1034F000D001D000D0D0D0E0327581B3742A90FFD3 -:1035000093F0757F30757EF8757D60757CF01205DF -:10351000411235AA12175D90FF93E04401F0B2B357 -:103520001235D412338480DA22C0007C01EC2408E6 -:10353000F8E660090CBC08F512337680EED0002264 -:10354000C0F0C082C083C000C006C007ED2410F8E0 -:1035500076C2ED75F021A4248DF582E434FCF58368 -:10356000C082C083A3A3E4780DF0A3D8FCEC547F01 -:1035700075F002A4241DF582E5F03436F583E4935A -:10358000FE740193F5828E83E493FE740193FFD061 -:1035900083D082EFF0A3EEF0ED2408F8EC4480F63F -:1035A000D007D006D000D083D082D0F0227578002A -:1035B000757B007A0879187808760077000809DAB0 -:1035C000F8E478087480447FF674014410F5897536 -:1035D000B808D2ABD2A9227581B3D28ED28CD2AF29 -:1035E000E57B6032FF90FD95E05480602478087997 -:1035F00008E0547FFA7B00E6547FB502027BFF08A7 -:10360000D9F5EB700CEAF0123526AD04AC02123598 -:103610003DA3A3A3DFD212337680C57C017D0022B7 -:10362000050004F404F804EC04E804E404F004FCE9 -:1036300004A804AC04D804DC04A404A404A404E096 -:1036400004C004B804BC04B404CC04C804C404D04A -:1036500004D404B0190103002200480200480E30CF -:103660001420C81AD0180A0C050602030102000132 -:10367000CE0181010000C000800060003000180011 -:1036800010000800040002000100081828380C058A -:10369000100A0200000000000301100A02000000EE -:1036A0000000FBE0FBF209022700010200A0FA097A -:1036B00004000003FF00000007058102400000072E -:1036C00005010240000007058303020001220354A4 -:1036D0000055005300420033003400310030002018 -:1036E00000200020002000200020002000200000FA -:0336F000000000D7 -:00000001FF diff --git a/firmware/mts_gsm.fw.ihex b/firmware/mts_gsm.fw.ihex deleted file mode 100644 index f6ad0cbd30cb075eaa256777f5ddb7221f12d82a..0000000000000000000000000000000000000000 --- a/firmware/mts_gsm.fw.ihex +++ /dev/null @@ -1,867 +0,0 @@ -:1000000014360002001E021AF9FFFFFFFFFF023341 -:100010001DFFFFFFFFFFFFFFFFFFFFFFFFFF02339B -:10002000C87581CE90FDE88583A012353CEC4D600B -:100030007378AB8003760018B89CFA787F800376DB -:100040000018B865FA78208003760018B820FA788E -:10005000208003760018B81FFA90FDDDAE83AF82D2 -:1000600090FBF81200AA6005E4F0A380F690FDE88A -:10007000A88290FDE8A982E8696005E4F20880F7AB -:100080009001081200B390010C1200B390011012FD -:1000900000B39001141200D190011A1200D1900106 -:1000A000201200D175D00012341A020126EF6582A9 -:1000B0007003EE658322E493F8740193F97402935C -:1000C000FE740393F5828E83E869700122E493F64F -:1000D000A30880F4E493FC740193FD740293FE740E -:1000E0000393FF740493F8740593F58288831200D8 -:1000F000AA700122E493A3A883A9828C838D82F045 -:10010000A3AC83AD828883898280E32121049B8014 -:1001100080049BACAE049BFDE8049D049DFBF304AE -:10012000A2049DFBF30502050280FED0F030F00929 -:1001300020F303F68010F7800D30F10920F303F26D -:100140008004F38001F020F404FCD0E0CC22CCC089 -:10015000E0120163020154BC0005D0F0ACF022C3F0 -:1001600013DCFC02012ABF0009ED258275F001F8BD -:10017000E622BF010FED2582F582EE3583F583750A -:10018000F004E022ED258275F002F8E222D083D05F -:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE -:1001A000E493A395F04012A3A3C3E5F033500205F6 -:1001B000832582F58250020583740193C0E0E493A5 -:1001C000C0E022D083D082F5F0E4937009740193EB -:1001D0007004A3A3800C74029365F06005A3A3A32D -:1001E00080E7740193C0E0E493C0E022120264024D -:1001F00001FB1202B80201FB1202DC0201FB30E03B -:100200000720E302E622E72230E10720E302E222B0 -:10021000E32230E202E022E493221202DC02022313 -:100220001202B8020223ABF012022DCBC5F0CB2292 -:1002300030E01020E306E6F5F008E622E7F5F009E5 -:10024000E7192230E11020E306E2F5F008E222E3AC -:10025000F5F009E3192230E206E0F5F0A3E022E42C -:1002600093F5F074019322BB0003740922BB0107CC -:1002700089828A83740422BB020789828A8374106C -:1002800022740A22020284BB0007E92582F8740165 -:1002900022BB010DE92582F582EA3583F5837404DA -:1002A00022BB020DE92582F582EA3583F5837410BD -:1002B00022E92582F87402220202B8BF0005EDF897 -:1002C000740122BF01078D828E83740422BF02074E -:1002D0008D828E83741022EDF87402220202DCBF3C -:1002E0000007ED2582F8740122BF010DED2582F58E -:1002F00082EE3583F583740422BF020DED2582F56D -:1003000082EE3583F583741022ED2582F874022283 -:10031000020310C0E0120264020328C0E01202B817 -:10032000020328C0E01202DC02032830E00B20E3C5 -:1003300004D0E0F622D0E0F72230E10B20E304D035 -:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B -:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069 -:100360002FBF000AFAEDF8E7F60809DAFA22BF0112 -:10037000128D828E83F802037809A3E7F0D8FA225F -:10038000020383FAEDF8E7F20809DAFA2202038D94 -:10039000BB014DBF001489828A83F9EDF802039FE7 -:1003A00008A3E0F6D9FA220203B0BF01228D828EA3 -:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F -:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9 -:1003D000828E83F9EDF8E0F208A3D9FA220203DD58 -:1003E000BB024DBF001289828A83F9EDF80203EF48 -:1003F00008A3E493F6D9F922BF01238D828E83FBF3 -:1004000008C9C582C9CAC583CAE493A3C9C582C93C -:10041000CAC583CAF0A3DBE9D8E722020422898295 -:100420008A83F9EDF8E493F208A3D9F922020433A0 -:10043000BF000DFAEDF8E3F60809DAFA2202043DEE -:10044000BF01128D828E83F802044A09A3E3F0D81B -:10045000FA22020455FAEDF8E3F20809DAFA220268 -:10046000045FE6FB08E6FA08E6F904F618700106F0 -:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379 -:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015 -:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6 -:1004A00000000000000502006105710026059800AB -:1004B000330A0900610A750066154400610CF900F1 -:1004C0006109A9006109E000610DC000610BF10044 -:1004D000610A1C00610A510061173C0033174F008C -:1004E000341E1400431EBF0044202C0044201A0078 -:1004F000471EE600471F8B004D1FDC004F1F080002 -:100500005832A800617CCC7DFF121CC52290FFFCF4 -:10051000E020E72DC2AFAE59AF58755A20E55A1406 -:10052000C55A6019E4FE7F05EE4FCE24FFCECF34CE -:10053000FFCF6007E490FF92F080ED80E08E598F4E -:10054000582212050A7D077CB71232C47D0F7C6EDB -:100550001232DE789D7A06E4F608DAFC7A06120595 -:10056000CD7C03120E55122168E4FEFF7C0F12327F -:100570004DD2A822123138E490FC38F090FFF0E020 -:1005800030E408740190FC39F08005E490FC39F007 -:100590007D0A7C001225461231BB2212313890FCB4 -:1005A00039E014700E90FFF0E04410F07C0012254A -:1005B000DF801990FC39E0700E90FFF0E054EFF00E -:1005C0007C001225DF80057C171225DF1231BB224B -:1005D00090FFF0E054ABF090FFF0E04420F0228C6C -:1005E000378D367882EDF608ECF6EDFEECFD7F01F6 -:1005F0009000051201F57880F67882E6FD08E6FCA9 -:10060000EDFEECFD7F019000041201F5540FFC7D1E -:100610008012176D7880E6700DAD3AAE39AF38E4D0 -:100620001203187C082290FFF0E054FEF090FFF0D7 -:10063000E054FDF0801E7882E6FD08E6FCEDFEEC5D -:10064000FD7F0190000812021725E0440190FFF39E -:10065000F00206D97882E6FD08E6FCEDFEECFD7FAF -:100660000190000612021754FE90FFF3F0802B78E1 -:1006700082E6FD08E6FCEDFEECFD7F01900008122D -:100680000217FAEB90FFF1F01208C8400DAD3AAE38 -:1006900039AF38E41203187C18227882E6FD08E6A8 -:1006A000FCEDFEECFD7F0190000812021790FFF1B7 -:1006B000F01208C8400DAD3AAE39AF38E412031855 -:1006C0007C18227882E6FD08E6FCEDFEECFD7F0159 -:1006D000900006120217440190FFF3F07883E6249D -:1006E00003F618E63400F67880E624FE500990FF01 -:1006F000F0E054FDF0800790FFF0E04402F0E49059 -:10070000FFF1F0788176007880E624FFFCE434FF86 -:10071000FD7881E67F00FEECD39EEF6480CD64809F -:100720009D402F1208AD400F7881E6AD3AAE39AF4B -:10073000381203187C182290FFF2E0FC788286833E -:10074000088682ECF0788106A37882A68308A682C8 -:1007500080B51208AD400F7881E6AD3AAE39AF38BA -:100760001203187C182290FFF2E0FC78828683083E -:100770008682ECF07880E6AD3AAE39AF38120318D5 -:100780007C00228C378D367882EDF608ECF6EDFE93 -:10079000ECFD7F019000051201F57881F67882E684 -:1007A000FD08E6FCEDFEECFD7F019000041201F572 -:1007B000540FFC7D8112176D7881E670037C08224E -:1007C00090FFF0E054FEF090FFF0E054FDF0801B4D -:1007D0007882E6FD08E6FCEDFEECFD7F0190000866 -:1007E00012021725E090FFF3F0805B7882E6FD08A7 -:1007F000E6FCEDFEECFD7F0190000612021754FEB0 -:1008000090FFF3F080217882E6FD08E6FCEDFEEC37 -:10081000FD7F01900008120217FAEB90FFF1F01231 -:1008200008C840037C18227882E6FD08E6FCEDFE4D -:10083000ECFD7F0190000812021790FFF1F0120802 -:10084000C840037C18227883E6240AF618E63400B0 -:10085000F6788076007881E624FFFCE434FFFD78AA -:1008600080E67F00FEECD39EEF6480CD64809D40E7 -:100870002178828683088682E090FFF1F01208C812 -:1008800040037C1822788006788306E618700106FB -:1008900080C390FFF0E04401F0788286830886826E -:1008A000E090FFF1F01208C840037C18227C00227F -:1008B00090FFF0E020E71290FFF0E030E50990FFB4 -:1008C000F0E04420F0C32280E7D32290FFF0E02044 -:1008D000E31290FFF0E030E50990FFF0E04420F0F3 -:1008E000C32280E7D3228C428D417C00ED54F0FD81 -:1008F000EC7003ED64307005753E038003753E04B3 -:10090000AC3E120F72758300858340E541540FF5AC -:100910003FE5407004E53F64037035E53E24FD7516 -:10092000F00AA42402F582E434FCF583E030E60505 -:100930001210598019E53E249DF8E654FBF678A97B -:10094000E62405F58218E63400F583740FF080592B -:10095000E5407004E53F64047048E53E24FD75F011 -:100960000AA42402F582E434FCF583E030E507AC08 -:1009700042AD41121C5AE54230E21578ADE630E056 -:100980000F78ADE630E109E4FF04FE7C0412324D3D -:1009900078A9E62406F58218E63400F583740FF092 -:1009A0008007E4FC7DEE121C5AC203221231381279 -:1009B0000F7278A9E62406F58218E63400F583E084 -:1009C00090FC38F078A9E62405F58218E63400F5A5 -:1009D00083E090FC39F0C2037D027C0012254612B0 -:1009E00031BB221231387895ECF6EC249DF8E630D4 -:1009F000E1077C131225DF800F90FC39E0FD78952C -:100A0000E6FC1213EF1225DF1231BB2212313878C7 -:100A100095ECF67D00120F121225DF1231BB221267 -:100A200031387895ECF6EC249DF8E630E2077C133B -:100A30001225DF801B7895E6249DF8E620E1077CEF -:100A4000121225DF800A7895E6FC1214131225DFB6 -:100A50001231BB221231387895ECF6EC249DF8E681 -:100A600020E2077C111225DF800A7895E6FC12153A -:100A7000141225DF1231BB221231387895ECF612B0 -:100A80000F7278A9E62409F58218E63400F583E0B0 -:100A900090FC3FF078A9E6240AF58218E63400F5C8 -:100AA00083E090FC40F078A9E62403F58218E63450 -:100AB00000F583E0FC78A9E62404F58218E634000A -:100AC000F583E0F56278A9E62402F58218E63400A1 -:100AD000F583E0F5638C61E4EC333354017895F6EB -:100AE0006008E56230E1037895067895E690FC4170 -:100AF000F078A7E62402F58218E63400F583E0FDDD -:100B0000A3E0540CFCED54E68C65F564E56130E53A -:100B100003436501E56220E50EE561547F7008E559 -:100B20006120E703436502E56130E303436510E5B7 -:100B30006130E203436520E561540360034365408F -:100B4000E56130E103436580E56130E4034364011E -:100B5000E56130E603436408E56220E40EE5615494 -:100B60007F7008E56120E7034364105365FB53641D -:100B7000F9AD64E56590FC3ACDF0A3CDF0E56330C6 -:100B8000E30DE5635430C4540F90FC3DF08005E460 -:100B900090FC3DF0E563540390FC3CF0E5635404A5 -:100BA000C31390FC3EF090FC3CE0700E7D357EFC63 -:100BB0007F01740190000912014B78A9E62408F521 -:100BC0008218E63400F583E07C00FD78A9E624076E -:100BD000F58218E63400F583E07F004CFEEF4D907F -:100BE000FC38F0A3CEF0CEC2037D0A7C001225466D -:100BF0001231BB221231387895ECF6789A760108DA -:100C000076FC0876387897760C789A12046E120281 -:100C10001D7898CBF6CB08F67F00EF24EA401FE45E -:100C2000EF25E090357EFD93CD04937899667003AF -:100C3000ED186670067897760080030F80DC789652 -:100C4000EFF6789A12046E9000021202177898CB91 -:100C5000F6CB08F65404CB54064B60047897760B19 -:100C60007899E630E313789A12046E900005120129 -:100C7000F524FB50047897760D7899E654C07D00F2 -:100C800064C04D70047897760B789A12046E9000C9 -:100C9000041201F524FC50047897760F789A120418 -:100CA0006E9000061201F524FD50047897760E78B8 -:100CB0009A12046E9000091201F524FD50047897F1 -:100CC000760A7897E6702A7895E6FC120F72789A81 -:100CD00012046E78A7E6F978A6E6FA7B01740A7822 -:100CE00000120348C2037895E6FC1211157897ECC0 -:100CF000F67897E6FC1225DF1231BB2212313878E4 -:100D000095ECF6120F727895E624FD75F00AA4248E -:100D100014F582E434FCF583AC82AD8378A6868337 -:100D2000088682ECF9EDFA7B0A78011203B0C2035F -:100D30007895E6FC1211151231BB228D2B8C2AED11 -:100D400060407527017529487528FFE52A24FDFCB8 -:100D5000E434FFFDEC7C0325E0CD33CDDCF9FCE58C -:100D6000292CF529E5283DF528AD29AE28AF2774B3 -:100D7000809000061203207480900002120320125B -:100D80000FC5E52B14603B7527017529087528FFF1 -:100D9000E52A24FDFCE434FFFDEC7C0325E0CD33A3 -:100DA000CDDCF9FCE5292CF529E5283DF528AD2910 -:100DB000AE28AF27E4900006120320E49000021250 -:100DC0000320221231387895ECF6EC249DF8E630B9 -:100DD000E2097895E6FC121514D2007895E6FC122B -:100DE0000F727896760090FC39E030E704789676BA -:100DF000017896E6FD7895E6FC120D38C2033000C6 -:100E0000077895E6FC1214137C001225DF1231BB23 -:100E10002278A9E62404F58218E63400F583E0443C -:100E200001F078A9E62404F58218E63400F583E0A1 -:100E300030E00280ED78A9E6240BF58218E6340054 -:100E4000F583E054F8F078A9E62402F58218E63438 -:100E500000F583E04480F022C2038C58120F7278B0 -:100E6000A6868308868279AF7A357B0A78011203D9 -:100E7000FE120E0EAC587D02120D38C203AC581291 -:100E80001115228D538E528F518C50120F72754F47 -:100E90000078A9E62405F58218E63400F583E02001 -:100EA000E41FE54F24F64019054FC2037C181232A7 -:100EB000FB90FF93E04401F0B2B3AC50120F72808C -:100EC000D078A9E62405F58218E63400F583E02001 -:100ED000E405C2037C022278A9E62405F58218E61F -:100EE0003400F583E0540F601678A9E62405F582F6 -:100EF00018E63400F583E0540FF0C2037C01227839 -:100F0000A88683088682E0AD53AE52AF5112031813 -:100F1000C2037C00228D318C30121514E531600F34 -:100F2000E530B4030A7C0112250E7C8112250EAC3B -:100F300030120F72E531601A78AA8683088682E043 -:100F400054E7F0A3A3A3A3E054E7F0AC307D021272 -:100F50000D3878A6868308868279B97A357B0A7837 -:100F6000011203FEC203E530249DF8E654FDF6AC01 -:100F700030121115228C2630030512329A80F87C2B -:100F80000A1231ADD203E52624FD78A3F670077866 -:100F9000AA76FF0876E078A3E67D007C0425E0CD04 -:100FA00033CDDCF9FC24A078A9F6ED34FF18F678EF -:100FB000A3E675F00AA42400FCE434FCFD78A6ED59 -:100FC000F608ECF61232462278A9E62402F58218D9 -:100FD000E63400F583E030E72278A9E62402F582C2 -:100FE00018E63400F583E0547FF078A9E62402F592 -:100FF0008218E63400F583E04480F02278AA8683E4 -:10100000088682E0547FF0AD83E5822404FCE43D51 -:101010008C82F583E0547FF078A9E6240BF58218E2 -:10102000E63400F583E054F8F078ABE62401F5826D -:1010300018E63400F583E04403F078ABE62405F5C8 -:101040008218E63400F583E04403F078A9E624052D -:10105000F58218E63400F583740FF02278AA8683AF -:10106000088682E0543FF0AD83E5822404FCE43D31 -:101070008C82F583E0543FF078A3E624A4F8E6FCE4 -:1010800078ABE62401F58218E63400F583ECF078BD -:10109000A3E624A4F8E6FC78ABE62405F58218E67E -:1010A0003400F583ECF078A9E6240BF58218E634D9 -:1010B00000F583E054FB4402F52678A7E62402F508 -:1010C0008218E63400F583E030E50343260178A971 -:1010D000E62405F58218E63400F583E030E00312DB -:1010E0000FC5E526FC78A9E6240BF58218E6340046 -:1010F000F583ECF078A9E62405F58218E63400F5CE -:1011000083740FF078AA8683088682E04480F0A377 -:10111000A3A3A3E04480F0228C2A120F7278A7E6E2 -:101120002408F58218E63400F583E0FC78A9E6246B -:101130000AF58218E63400F583ECF078A7E6240778 -:10114000F58218E63400F583E0FC78A9E62409F579 -:101150008218E63400F583ECF078A6868308868250 -:10116000E0FDA3E0FCEDFE78A9E62408F58218E690 -:101170003400F583EEF0ECFE78A9E62407F582183A -:10118000E63400F583EEF08C298D28C3EC9405ED50 -:10119000940C400575277C8033D3E5299401E5281C -:1011A0009403400575273C8023D3E5299481E528E5 -:1011B000940140057527188013D3E5299460E5282C -:1011C0009400400575270C8003752708AF27E4EFCE -:1011D000547C4483FF8F27E527FC78ABE62401F598 -:1011E0008218E63400F583ECF0E527FC78ABE624C2 -:1011F00005F58218E63400F583ECF0E527FC78A3CA -:10120000E624A4F8ECF678A9E62402F58218E63480 -:1012100000F583E0F52778A7E62402F58218E63486 -:1012200000F583A3E030E3175327C778A7E624052A -:10123000F58218E63400F583E09035AA93422778CA -:10124000A7E62402F58218E63400F583E030E705CE -:1012500043274080035327BF5327FB78A7E6240684 -:10126000F58218E63400F583E06003432704532732 -:10127000FC78A7E62404F58218E63400F583E04202 -:1012800027432780E527FC78A9E62402F58218E6A3 -:101290003400F583ECF078A9E62404F58218E634EE -:1012A00000F583E0F52778A7E62402F58218E634F6 -:1012B00000F583A3E030E1055327DF8003432720B7 -:1012C00078A7E62402F58218E63400F583E030E4DE -:1012D000055327EF800343271078A7E62409F582FA -:1012E00018E63400F583E0B40203432702E527FC47 -:1012F00078A9E62404F58218E63400F583ECF0784A -:10130000A9E62403F58218E63400F583E0F5277892 -:10131000A7E62409F58218E63400F583E07005534A -:10132000277F800343278078A7E62402F58218E60A -:101330003400F583A3E030E00543272080035327E2 -:10134000DF78A7E62402F58218E63400F583E03062 -:10135000E30543274080035327BF78A7E62402F51F -:101360008218E63400F583E030E00543271080035F -:101370005327EF78A7E62402F58218E63400F583B8 -:10138000A3E030E40543270880035327F778A7E656 -:101390002402F58218E63400F583A3E030E5054326 -:1013A000270480035327FB78A7E62402F58218E67A -:1013B0003400F583A3E030E605432701800353277B -:1013C000FE78A7E62402F58218E63400F583A3E050 -:1013D00030E70543270280035327FDE527FC78A962 -:1013E000E62403F58218E63400F583ECF0C2037CB2 -:1013F00000228D278C26ED54031460037C1022E517 -:1014000027547C24FC40037C0B22E526249DF8E62F -:101410004402F67C00228C30120F72E530249DF8D5 -:10142000E620E24FAC307D02120D38E53024FE4458 -:1014300028FC78AA8683088682ECF0AF83E58224B4 -:1014400004FEE43FFFEC8E828F83F07C038C2CE55E -:101450002CFC78ABE62401F58218E63400F583EC29 -:10146000F0E52CFC78ABE62405F58218E63400F5AF -:1014700083ECF0752D01752F48752EFFE53024FDA6 -:10148000FCE434FFFDEC7C0325E0CD33CDDCF9FC3E -:10149000E52F2CF52FE52E3DF52E78ABE62404F54F -:1014A0008218E63400F583E054E7F52CAD2FAE2E1C -:1014B000AF2DE4900002120320E4900006120320F6 -:1014C0001201EF30E503432C10E52CFC78ABE62449 -:1014D00004F58218E63400F583ECF012105978A96F -:1014E000E62406F58218E63400F583E0C203FCE545 -:1014F00030249DF8E64404F68C2CE530540FC45497 -:10150000F07E00FFEEEF44047D00FFEC4EFCED4F5B -:10151000FD121CC57C00228C2F120F72120FF9785D -:10152000AA8683088682E05408F0A3A3A3A3E0540C -:1015300008F0AC2F7D02120D38C203E52F249DF870 -:10154000E654FBF67C00221231387896ECF6EC2457 -:101550009DF8E630E10A7D007C131225461231BB6E -:101560007896E6249DF8E64401F67896E6FC120F9C -:10157000727896E624FD75F00AA42414F582E4340A -:10158000FCF58378A6E6FA08E6F97B0A78011203EF -:10159000B078A6868308868279B97A357B0A780185 -:1015A0001203FE120FC5C2037896E6FC12111578DD -:1015B00095ECF6EC600A7D007C081225461231BBE2 -:1015C0007896E6FC120F7278A9E62404F58218E6F4 -:1015D0003400F583E0441054DFFC78A9E62404F5D8 -:1015E0008218E63400F583ECF07895ECF6C2037CC3 -:1015F000C81232FB7896E6FC120F7278A9E6240432 -:10160000F58218E63400F583E054EFF0C2037CC89D -:101610001232FB7896E6FC120F7278A9E62404F5E4 -:101620008218E63400F583E04410F0C2037CC8124F -:1016300032FB7896E6FC120F7278A9E62404F58254 -:1016400018E63400F583E04420F0C2037CF0123247 -:10165000FB7896E6FC120F7278A9E62405F582184D -:10166000E63400F583E030E415C2037896E64410D2 -:101670007F00FE7C0712324D1231BB02173B78A966 -:10168000E62404F58218E63400F583E054CFF0C276 -:10169000037CC81232FB7896E6FC120F7278A9E63A -:1016A0002404F58218E63400F583E04430F0C203E8 -:1016B0007CF01232FB7896E6FC120F7278A9E624D1 -:1016C00005F58218E63400F583E030E414C20378AF -:1016D00096E644107F00FE7C0712324D1231BB802B -:1016E0005D78A9E62404F58218E63400F583E05419 -:1016F000EFF078A9E62404F58218E63400F583E0DB -:1017000054DFF07896E624FD75F00AA42414F582DF -:10171000E434FCF583AC82AD8378A68683088682A8 -:10172000ECF9EDFA7B0A78011203B0C2037896E671 -:10173000FC1211157D007C0B1225461231BB2212C2 -:101740003138E490FC39F07D027C001225461231DC -:10175000BB221231387C001225DF1231BB22743CCF -:1017600090FBE0F0743E90FBE0F0E490FC28F02267 -:101770008D358C34ECB401028003D340028028B450 -:1017800002028003D34008A835E625E0F68018B4AD -:1017900004028003D3400AA835E625E025E0F68060 -:1017A00006A83576008000228C3C8D3BEDFEECFDDA -:1017B0007F0175660675670090FC29120477120197 -:1017C000EFB480028006D3500302186E90FC2912F9 -:1017D00004899000031201F554F0B430028003D361 -:1017E000405F90FC29120489900008120217FAFD4C -:1017F000EBFE7F0190FC2C120477EECD9035C3FCFC -:10180000E493FF740193FEF9EFFA7B01EAFFE9FE2E -:10181000ECC39EED9F40259035C5E493FD74019384 -:10182000FCEDFEECFD7F01EECDFC90FC2EE0D39CA8 -:1018300090FC2DE09D5005756680803312198C80D8 -:101840002EB460028003D3400BAC3CAD3B1207804A -:101850008C66801BB41003B34010C3B42003B340A4 -:1018600009C3B440028003D34000756681800080C4 -:1018700075B481028003D3406B90FC2912048990D7 -:1018800000031201F554F0B430028003D3401D90E0 -:10189000FC29120489900008120217FAFDEBFE7F62 -:1018A0000190FC2F1204771218F68036B460028083 -:1018B00003D34013753A67E4F539F538AC3CAD3BDA -:1018C0001205DC8C66801BB41003B34010C3B42037 -:1018D00003B34009C3B440028003D340007566815E -:1018E000800080028000E566FC90FC29120489ECEF -:1018F000900002120320AC672290FC291204899008 -:1019000000041201F5600474018001E4A2E0920178 -:1019100090FC29120489ED2403FD50010E90FC2C4B -:1019200012047790FC291204899000051201F5F544 -:10193000679000041201F5540FFC7D6712176DE5E6 -:10194000677004756608227566007884760078846E -:10195000E6C39567503890FC2F1204891201EFFC02 -:1019600090FC2C120489EC12031830010E90FC310B -:10197000E004F090FC307003E004F078840690FC02 -:101980002EE004F090FC2D7003E004F080C0229063 -:10199000FC2AE0FDA3E0FCEDFEECFD7F01ED240A56 -:1019A000FD50010E90FC3212047790FC291204893C -:1019B0009000041201F5540FB401028003D34017C4 -:1019C00090FC321204890DED70010E90FC2F120470 -:1019D0007778887601804EB402028003D340199054 -:1019E000FC32120489ED2402FD50010E90FC2F12EE -:1019F000047778887602802DB404028003D34019DE -:101A000090FC32120489ED2404FD50010E90FC2F4D -:101A100012047778887604800CB400028003D340E7 -:101A2000007566082290FC291204899000051201B5 -:101A3000F5F567788576007885E6C39567400302FB -:101A40001AF4788676007886E6C378889650769081 -:101A5000FC2C1204891201EFFC90FC321204921249 -:101A600001E9F45CFC1201E9F890FC2F120489E80A -:101A7000C0E01201EFC8D0E0C8584CFC90FC2C121A -:101A80000489EC1203187887ECF690FC31E004F03E -:101A900090FC307003E004F009E970010A90FC3218 -:101AA00012048090FC291204899000041201F53080 -:101AB000E40E90FC2EE004F090FC2D7003E004F0A6 -:101AC00078860680817888E6FDE4FEFFEECDFC9006 -:101AD000FC31E02CF090FC30E03DF07888E6FDE44D -:101AE000FEFFEECDFC90FC34E02CF090FC33E03DAA -:101AF000F0788506021A347566002222C0E0C0F034 -:101B0000C082C083C0D0E8C0E0E9C0E0EAC0E0EB3A -:101B1000C0E0ECC0E0EDC0E0EEC0E0EFC0E090FF60 -:101B200092E01201C01B47301B47321B56381B681E -:101B30003A1B7A3E1B92441B86461B9E501BE0526A -:101B40001BBF541C015600001C2290FF92E07F0036 -:101B5000FE7C0112324D021C32E4FF04FE7C0312B3 -:101B6000324D742090FFFEF0021C32E4FF04FE7C34 -:101B70000212324D744090FFFEF0021C32E4FF046A -:101B8000FE7C0412324D021C32E4FF04FE7C05127E -:101B9000324D021C32E4FF04FE7C0612324D021C60 -:101BA0003290FFA5E07D0090FBF8CDF0A3CDF09042 -:101BB000FBF9E0FCF58390FBF8E04433FD121CC513 -:101BC000807390FFB5E07D0090FBFACDF0A3CDF0DF -:101BD00090FBFBE0FCF58390FBFAE04443FD121C14 -:101BE000C5805290FFA6E07D0090FBFCCDF0A3CD18 -:101BF000F090FBFDE0FCF58390FBFCE04434FD122B -:101C00001CC5803190FFB6E07D0090FBFECDF0A3B7 -:101C1000CDF090FBFFE0FCF58390FBFEE04444FD3B -:101C2000121CC5801090FF92E07D00FCED44AAFDDF -:101C3000121CC58000E490FF92F0D0E0FFD0E0FEDF -:101C4000D0E0FDD0E0FCD0E0FBD0E0FAD0E0F9D06D -:101C5000E0F8D0D0D083D082D0F0D0E0320581053A -:101C60008105810581A881181818EDF608ECF69019 -:101C7000FF5AE020E70280F790FF59E07D00A8813D -:101C800018CDF6CD08F67D03A881E618FCE6CC2534 -:101C9000E0CC33CCDDF9CCF6CC08F6A88118E644CC -:101CA000F8F6A881181818E6FD08E6FCA881188641 -:101CB00083088682EDF0A3ECF0740290FF5AF015D1 -:101CC0008115811581158122E5812405F581E4A81E -:101CD0008118F6A88118181818EDF608ECF690FB94 -:101CE000F5E024F85003021DE6E4A8811818F6A8D0 -:101CF0008118E6FEA88118181818E6FD08E6FC7F92 -:101D000000EF24F8404DE4EF25E0247DF582E43433 -:101D1000FCF583E0FBA3E06C7003FAEB6D700974D3 -:101D200001A8811818F6802BE4EF25E0247DF582C8 -:101D3000E434FCF5837A00E054F0CCF8CCCDF9CD56 -:101D4000FB7800E954F0F9EA687002EB6970010E63 -:101D50000F80AEA88118EEF6A88118181818EDF6B5 -:101D600008ECF6A881EFF6A8811818E67079A8812A -:101D700018E624F74071A88118181818E6540FA81F -:101D800081F664046017A881E664036010A88118D6 -:101D9000181818E6FD08E6FC121C5A804A7C0A1244 -:101DA00031ADA88118181818E6FD08E6FC90FBF480 -:101DB000E025E0247DF582E434FCF583EDF0A3EC2E -:101DC000F090FBF4E0FFE4EF045407FF90FBF4F025 -:101DD00090FBF5E004F012324690FBF6E07008E468 -:101DE000FEFF7C0F12324D802790FBF7E004F05489 -:101DF0003F701D90FBF7E044FE7D00FC90FBF4E09B -:101E000025E0247DF582E434FCF583EDF0A3ECF0CD -:101E1000E58124FBF58122788B7600788C7600743E -:101E20000190FBF6F012313890FBF5E060577C0A28 -:101E30001231AD90FBF3E025E0247DF582E434FC23 -:101E4000F583E0FDA3E0FC90FBF3E025E0247DF5C5 -:101E500082E434FCF583E4F0A3F090FBF3E0FFE4CC -:101E6000EF045407FF90FBF3F090FBF5E014F078DB -:101E700089EDF608ECF61232467889E6FD08E6FCB4 -:101E80001208E380A312329A90FF93E04401F0B26B -:101E9000B3788B06B60011788B7600788CE6F40464 -:101EA00004A2E092B4788CF6021E25E490FBF6F0D2 -:101EB00090FBF5E07D00FCED44CFFD121C5A123181 -:101EC000BB22123138E5706449456F601590FF837D -:101ED000E0540F7D00D39570ED956F5005122F8162 -:101EE00080031230511231BB22123138E57064493F -:101EF000456F600512308B800E90FF80E04408F043 -:101F000090FF83E0547FF01231BB221231388C54A1 -:101F1000EC54F0B41015756A357569FC756801E507 -:101F20006A2403F56AE5693400F569E4F557F55666 -:101F3000E556C394015027E554540FFCAD6AAE69D1 -:101F4000AF68120E808C55EC60028012056AE56A5B -:101F5000700205690557E5577002055680D2E554B1 -:101F6000540F249DF8E654FEF6E554540F7F00FE0E -:101F70007C1212324DE5551470097D007C09122542 -:101F8000468007AD577C001225461231BB22123124 -:101F90003890FFFCE04402F090FF00E030E713903F -:101FA000FF83E04480F0436D8090FFFCE04401F04B -:101FB000801190FF82E04408F0536D7F90FFFCE0B9 -:101FC00054FEF090FF81E04480F01225F990FFFE6E -:101FD000E04405F090FFFCE054FDF01231BB22120A -:101FE00031387C011232FB78ADE64402F674FEFC17 -:101FF00004FD121CC590FF5AE030E70280F7E4F5BB -:102000004E754D10AC4EAD4DE54E154E7002154D52 -:10201000EC4D600280EE4387011231BB2212313851 -:102020007C021231C778ADE654FDF61231BB2212A4 -:10203000313878ADE630E02C78ADE630E12678AD89 -:10204000E6FCF58318E644F0FD121C5A90FFFCE014 -:102050004420F07C021232FB78ADE654FDF6741A8F -:1020600090FFFEF078ADE6FCF58318E644F1FD1232 -:102070001C5A1231BB22756D0090FFFFE0600343D4 -:102080006D01756E00E4F56CF56BE4F56F757049E4 -:10209000748490FF82F0748490FF80F0748090FFCD -:1020A00058F0748090FF5AF0AD46AF457E00EE24A4 -:1020B000FE5003022142E4EE75F007A4247FF5826E -:1020C000E434F8F583E0FFE4EF5480FDE4EF540FCF -:1020D00014FFED6038E4EF75F008A42448F582E4BD -:1020E00034FFF5837490F0E4EF75F008A4244AF50A -:1020F00082E434FFF5837480F0E4EF75F008A424E3 -:102100004EF582E434FFF5837480F08034E4EF759B -:10211000F008A42408F582E434FFF5837490F0E419 -:10212000EF75F008A4240AF582E434FFF583E4F0A7 -:10213000E4EF75F008A4240EF582E434FFF583E49F -:10214000F00E0220AB8D468E448F45747F90FFFDCC -:10215000F0749090FFFCF0228C58EC24F65006E5C9 -:10216000582437FC22E5582430FC22D2B0122543F3 -:10217000EC700302227E755C03AE5B7F00E55C15AC -:102180005C6480247F5035EF2400F582E434FBF555 -:1021900083E0FE24FE501EEF7D00FCE4FB7474C35C -:1021A0009CFAEB9DFBEE7D00FCEAC39CED6480CBCA -:1021B00064809B50028005EF2EFF80C18E5B8F5A9A -:1021C000E55C6480247F500302227EE55A248E5011 -:1021D0000302227E855A5D755B00AE5AAF5B903577 -:1021E000EEE493F55CE55C155C6480247F5018EEAA -:1021F0002400F582E434FBF583E0FCEF9035EE93A8 -:102200006C70040E0F80DE8E5A8F5BE55C64802458 -:102210007F406E755E017560E8755FFFE55D2402C5 -:10222000F55A755C07E55C334057AD60AE5FAF5E55 -:10223000E55CF5823395E0F5831201F5C4540FFC9B -:10224000122155E55A2400F582E434FBF583ECF0C5 -:10225000055A055AAD60AE5FAF5EE55CF582339519 -:10226000E0F5831201F5540FFC122155E55A2400C4 -:10227000F582E434FBF583ECF0055A055A155C80D1 -:10228000A4740290F851F090F86B79C77A357B27E7 -:1022900078011203FE756A357569FC756801E49072 -:1022A000FF83F0748090FF81F0755902E55975F055 -:1022B00007A4247FF582E434F8F583E0788FF6FCF8 -:1022C000540F14FC788FECF6E55975F007A42481BF -:1022D000F582E434F8F583E0789276FD0876E8FC40 -:1022E000788FE675F008A42448F582E434FFF5837E -:1022F000E4F0788FE675F008A4244FF582E434FF0B -:10230000F583ECF07892E6FF08E67E03CFC313CFA7 -:1023100013DEF9FE788FE675F008A42449F582E40F -:1023200034FFF583EEF0788FE675F008A4244AF5C3 -:1023300082E434FFF5837480F07890ECF67D0078C9 -:1023400093E62CF618E63DF67892E6FD08E67C0367 -:10235000CDC313CD13DCF9FC788FE675F008A42407 -:102360004DF582E434FFF583ECF0788FE675F008E4 -:10237000A4244EF582E434FFF583E4F07892E6FD80 -:1023800008E6FC788FE6FF7E00EE24FE5003022470 -:10239000FDE4EE75F007A4247FF582E434F8F583BC -:1023A000E0FFE4EF5480FAE4EF540F14FFE4EE751D -:1023B000F007A42481F582E434F8F583E07890F600 -:1023C000E4EE1313548024F0F8E434FDF9E8FCE95A -:1023D000FD8A5AEA700302246AE4EF75F008A42427 -:1023E00048F582E434FFF583E4F07890E6FAE4EF10 -:1023F00075F008A4244FF582E434FFF583EAF0ED8C -:10240000FBEC7A03CBC313CB13DAF9FAE4EF75F0E4 -:1024100008A42449F582E434FFF583EAF07890E6D5 -:102420007B00FAEC2AFCED3BFDFBEC7A03CBC313FB -:10243000CB13DAF9FAE4EF75F008A4244DF582E441 -:1024400034FFF583EAF0E4EF75F008A4244AF5823E -:10245000E434FFF5837480F0E4EF75F008A4244EB3 -:10246000F582E434FFF5837480F00224F9E4EF751B -:10247000F008A42408F582E434FFF583E4F07890B2 -:10248000E6FAE4EF75F008A4240FF582E434FFF5D2 -:1024900083EAF0EDFBEC7A03CBC313CB13DAF9FA42 -:1024A000E4EF75F008A42409F582E434FFF583EA2B -:1024B000F07890E67B00FAEC2AFCED3BFDFBEC7A31 -:1024C00003CBC313CB13DAF9FAE4EF75F008A424B5 -:1024D0000DF582E434FFF583EAF0E4EF75F008A42B -:1024E000240AF582E434FFF583E4F0E4EF75F008A4 -:1024F000A4240EF582E434FFF583E4F00E02238673 -:102500008E597892EDF608ECF6788FEFF61220737C -:10251000228C26EC30E718E526540F1475F008A439 -:102520002448F582E434FFF583E054DFF08016E5BB -:1025300026540F1475F008A42408F582E434FFF53E -:1025400083E054DFF0227C0022EC90FC37F08C24F6 -:10255000ED2403F5257D00D39572ED95714003853B -:102560007225E52524B75009752503740290FC37C0 -:10257000F0AC2512307622E4F56CF56B12257D2245 -:1025800090FC35E06573600E740490FC37F0E4F560 -:102590006B756C0380467D73E4FEFF79357AFC7BB6 -:1025A0000174057800120348E56C2403F56CE56BB3 -:1025B0003400F56BE56CD39572E56B95714006853B -:1025C000726C85716BD3E56C9448E56B9400400C9C -:1025D000740290FC37F0E4F56B756C03AC6C123050 -:1025E0007622EC90FC37F0E4F56CF56B8C32EC6005 -:1025F0000512306780057C001230762290FF93E050 -:102600004401F0B2B390FF04E0F54A90FF06E0FD0C -:10261000A3E0ED7D00FC7D00FC90FF06E0FFA3E061 -:102620007E00FFE4FEEC4EFCED4FFDC3EC9448ED64 -:102630009400502290FF06E0FDA3E0ED7D00FC7DBC -:1026400000FC90FF06E0FFA3E07E00FFE4FEEC4EFE -:10265000FCED4FFD8004E4FD7C488C728D7190FF91 -:1026600002E0FDA3E0ED7D00FC7D00FC90FF02E0B8 -:10267000FFA3E07E00FFE4FEEC4EF54CED4FF54B82 -:10268000756A357569FC7568017D357EFC7F017959 -:1026900073E4FAFB74057800120348754900E549B4 -:1026A00024FE4019AD6AAE69AF68E412031805490B -:1026B0000DED70010E8D6A8E698F6880E1756A3547 -:1026C0007569FC75680190FF00E05460B4000280F9 -:1026D00006D35003022CBFE54A540FF549E54A548E -:1026E00080A2E0920290FF01E012018A000B2CBA56 -:1026F000270528232CBA292F2CBA2A122A462BADBB -:102700002BB02BF02C632C91E56D30E70EE54C459A -:102710004B7008E572640245716003022CBC90FFA7 -:1027200000E0541FB400028003D34029E54A60034F -:10273000022820AD6AAE69AF68740112031878AD43 -:10274000E630E00BAD6AAE69AF6874021203187C24 -:102750000212307622B401028003D3401BE56D20C3 -:10276000E107E54A6003022820E54A24FE500302FF -:1027700028207C0212307622B402028006D3500355 -:1027800002281EE56D20E10DE54A6009E54A6480F6 -:102790006003022820AC4A1230FD4003022820E5E5 -:1027A00049702530021190FF80E05408AD6AAE698F -:1027B000AF68120318800F90FF82E05408AD6AAE34 -:1027C00069AF68120318803D154930021DE549754F -:1027D000F008A42448F582E434FFF583E05408AD02 -:1027E0006AAE69AF68120318801BE54975F008A44A -:1027F0002408F582E434FFF583E05408AD6AAE693D -:10280000AF68120318AD6AAE69AF681201EF600BD2 -:10281000AD6AAE69AF6874011203187C021230769B -:10282000228000022CBCE56D20E706E57245716050 -:1028300003022CBC90FF00E0541FB400028003D3BD -:10284000401AE54C14454B7004E54A600302292CFC -:1028500078ADE654FEF67C0012307622B401028098 -:1028600003D3402AE56D20E108E56D20E00302294D -:102870002CE56D30E004E54A700BE56D30E109E5CB -:102880004A24FE500302292C7C0012307622B40226 -:10289000028006D3500302292AE54C454B6003020F -:1028A000292CAC4A1230FD400302292CE56D20E1B1 -:1028B00007E56D20E0028077E56D30E006E54960D0 -:1028C00002806CE549700F90FF82E054F7F090FFB2 -:1028D00080E054F7F022E549B401028003D34009B7 -:1028E0007D017C03120F128011B402028003D340D9 -:1028F000097D017C04120F1280001549300215E594 -:102900004975F008A42448F582E434FFF583E054C7 -:10291000F7F08013E54975F008A42408F582E43443 -:10292000FFF583E054F7F07C00123076228000023D -:102930002CBCE56D20E706E57245716003022CBCF6 -:1029400090FF00E0541FB400028003D3401AE54C0E -:1029500014454B7004E54A6003022A0F78ADE64443 -:1029600001F67C0012307622B401028003D34029A4 -:10297000E56D20E108E56D20E003022A0FE56D30EA -:10298000E004E549700BE56D30E108E54924FE50AF -:1029900002807F7C0012307622B402028003D34092 -:1029A0006FE54C454B60028069AC4A1230FD400235 -:1029B0008060E56D20E107E56D20E0028054E54987 -:1029C000701430020990FF80E04408F0800790FF07 -:1029D00082E04408F022E56D30E1331549300215FC -:1029E000E54975F008A42448F582E434FFF583E056 -:1029F0004408F08013E54975F008A42408F582E442 -:102A000034FFF583E04408F07C0012307622800227 -:102A10008000022CBCE56D20E712E5724571700C58 -:102A2000E54A700890FF00E0541F6003022CBCE5EB -:102A30004C90FFFFF090FFFFE06005436D018003C5 -:102A4000536DFE7C0012307622E56D30E70EE572A4 -:102A50004571600890FF00E0541F6003022CBCAD7C -:102A60004BE54CED7D00FC7D00FCBD0002800302C7 -:102A70002BA8B401028003D34032E54A7005E54C2F -:102A8000FC6003022BAA756A407569F8756801D36A -:102A9000E5729412E57194004006E4FD7C12800416 -:102AA000AC72AD718C708D6F12308B22B4020280CB -:102AB00003D34059E54A6003022BAAE54CFC70277A -:102AC000756A527569F8756801D3E5729419E571F4 -:102AD00094004006E4FD7C198004AC72AD718C70EA -:102AE0008D6F12308B8025756A6B7569F87568017A -:102AF000D3E5729427E57194004006E4FD7C2780BD -:102B000004AC72AD718C708D6F12308B22B40302E5 -:102B10008006D35003022BA8E54CF549700F90FFB7 -:102B200004E0FDA3E04D6003022BAA801890FB0295 -:102B3000E0FDA3E0FC90FF05E06C700790FF04E06F -:102B40006D60028068E4F570F56F7F00E54914C59B -:102B500049600FEF2400F582E434FBF583E02FFF9A -:102B600080EA8F4AE54A2400F582E434FBF583E0ED -:102B70007D00D39572ED95714006AC72AD71800FFA -:102B8000E54A2400F582E434FBF583E07D00FC8C0B -:102B9000708D6FE54A2400FCE434FBFDFEECFD7F04 -:102BA000018D6A8E698F6812308B228000022CBCE6 -:102BB000022CBCE56D30E719E5721445717012E521 -:102BC0004A700EE54C454B700890FF00E0541F60C2 -:102BD00003022CBCE56D20E008E56D20E103022C2A -:102BE000BC756A6EE4F569F568E4F56F04F570127A -:102BF000308B22E56D20E727E57245717021E54AAB -:102C0000701DE54C6402454B600DE54C14454B606E -:102C100006E54C454B700890FF00E0541F6003022E -:102C20002CBCE56D20E008E56D20E103022CBC859D -:102C30004C6EE56E700A436D01536DFDD2B080207D -:102C4000E56E64026007E56E1460028072536DFEEB -:102C5000436D02E56E64026005E56E147002C2B059 -:102C60007C0012307622E56D30E71AE5721445716A -:102C70007013E54A700FE54C454B700990FF00E07A -:102C8000541F1460028038E56D20E10280317C0120 -:102C900012307622E56D20E715E5724571700FE57B -:102CA0004C454B700990FF00E0541F146002800FE8 -:102CB000E56D20E10280087C00123076228000025F -:102CC0002F7DB440028006D35003022F7390FF0182 -:102CD000E090FC35F0E54A90FC36F0E490FC37F0EB -:102CE000E56A2403F56AE5693400F569AD4BE54C06 -:102CF000856A82856983CDF0A3CDF090FF01E01253 -:102D000001C02D2A012D50022D7A032DA4042DF28D -:102D1000052E2F062E55072E7B082EA7092ECD0B2C -:102D20002EF30C2F02802F028100002F60E56D2012 -:102D3000E7067C051225DF227D767E357F02793815 -:102D40007AFC7B01740878001203487D087C00122D -:102D5000254622E56D20E7067C051225DF22E54A9F -:102D6000B403004010B40500500BE54A7F00FE7C20 -:102D70001012324D227D007C0712254622E56D207F -:102D8000E7067C051225DF22E54AB403004010B4B3 -:102D90000500500BE54A7F00FE7C1112324D227D6A -:102DA000007C0712254622E56D20E7067C051225EA -:102DB000DF22E54AB405028003D3400AE4FF04FEA3 -:102DC0007C0A12324D22B401028003D3400AE4FF90 -:102DD00004FE7C0812324D22B403004010B40500FA -:102DE000500BE54A7F00FE7C1312324D227D007CA1 -:102DF0000712254622E56D20E734D3E5729448E5B5 -:102E00007194005006E572457170067C021225DF50 -:102E100022E54AB40103B3400BC3B403004009B434 -:102E200006005004123123227C071225DF221225CE -:102E30007D22E56D20E71DE54AB403004010B4058E -:102E400000500BE54A7F00FE7C1612324D227C07B3 -:102E50001225DF2212257D22E56D20E71DE54AB40B -:102E600003004010B40500500BE54A7F00FE7C19BA -:102E700012324D227C071225DF2212257D22E56DBC -:102E800020E723748190FF93F0E54AB403004010DB -:102E9000B40500500BE54A7F00FE7C1712324D222C -:102EA0007C071225DF2212257D22E56D20E71DE536 -:102EB0004AB403004010B40500500BE54A7F00FE01 -:102EC0007C1812324D227C071225DF2212257D222A -:102ED000E56D20E71DE54AB403004010B40500503D -:102EE0000BE54A7F00FE7C1512324D227C0712252D -:102EF000DF2212257D22E56D20E7067C071225DF03 -:102F00002212257D22E56D30E72090FF00E0541F5E -:102F1000701090FF01E0B480051225748003122523 -:102F20007D227D007C051225462290FF00E0541F83 -:102F300060067C051225DF22D3E5729448E5719482 -:102F400000500BC3E5729407E571940050067C03B2 -:102F50001225DF22E54AB40504123123227C071230 -:102F600025DF22E56D30E7087D007C05122546222D -:102F70007C051225DF22B420028003D340008000AC -:102F80001230512275430090FF83E0540FD39543D4 -:102F90004024E54324F0F582E434FEF583E0AD6A95 -:102FA000AE69AF6812031805430DED70010E8D6A0E -:102FB0008E698F6880D1E5437D00FCC3E5709CF588 -:102FC00070E56F9DF56FE570456F6006E490FF83D7 -:102FD000F02290FF82E04408F0E4F56F75704990AC -:102FE000FC35E0B405028003D3404090FC36E0F5A8 -:102FF00043B405028003D3400AE4FF04FE7C0B12B5 -:10300000324D22B401028003D3400AE4FF04FE7C67 -:103010000912324D22B403004010B40500500BE5F4 -:10302000437F00FE7C1412324D2222B480004023E4 -:10303000B48200501E7C357DFC1217A57D008C6C7F -:103040008D6B90FC37E0600512305180057C0012DA -:103050003076222290FF83E0547FF090FF82E0449C -:1030600008F090FF80E04408F02290FF82E04408DE -:10307000F090FF80E04408F0228C237D008C708D5E -:103080006F756A357569FC75680112308B2290FF87 -:1030900083E0547FF0E5706449456F700122C3E519 -:1030A000709408E56F94004015752108E5217D00B6 -:1030B000FCC3E5709CF570E56F9DF56F8009857028 -:1030C00021E4F56F757049752200E522C395215002 -:1030D00026AD6AAE69AF681201EFFCE52224F8F56F -:1030E00082E434FEF583ECF005220DED70010E8DC7 -:1030F0006A8E698F6880D3E521547F90FF81F0222A -:103100008C487F00EF24FD4019E4EF75F007A424FC -:103110007FF582E434F8F583E065487002D3220F2E -:1031200080E28F47C32285727085716F90FF82E0C5 -:1031300054F7F090FF83E0547FF022C000C001C03C -:1031400002C006C007E5782408F8860653067F7C8F -:10315000FF1231AD7C007D00E57B6046FF90FD9560 -:10316000E0547F6E700FC083C082A3E0FDA3E0FC3B -:10317000A3157B8007A3A3A3DFE68026DF06D0820A -:10318000D083801EE0F8A3E0F9A3E0FAD082D083D8 -:10319000E8F0A3E9F0A3EAF0A3C083C082A3A3A34D -:1031A00080DA123246D007D006D002D001D00022F9 -:1031B00085A87A75A888EC70027C3F8C7922E57826 -:1031C0002408F8760012329A80FBC000C001C002C9 -:1031D000C006C007AE047CFF1231ADE57B6042FF44 -:1031E00090FD95E0547F6E700BC083C082A3A3A3B3 -:1031F000157B8007A3A3A3DFEA8026DF06D082D059 -:103200008380D8E0F8A3E0F9A3E0FAD082D083E885 -:10321000F0A3E9F0A3EAF0A3C083C082A3A3A38034 -:10322000DA7808087918097C01E6547F6E70067612 -:10323000007700800608090CBC08EE123246D00761 -:10324000D006D002D001D00022757900857AA8225C -:10325000C0F0C082C083C3E57B24E8500512329AD7 -:1032600080F4EC6031903575E493C39C4028C00431 -:103270007CFF1231ADD004430480E57B75F003A4DC -:103280002495F582E434FDF583ECF0EFA3F0EEA392 -:10329000F0057B123246D083D082D0F022C0047C6D -:1032A00020D28CD28DD504FDD0042275A80075885B -:1032B0000075B80075F00075D000E4F8900000F6D5 -:1032C00008B800FB020000C3ED940250047D037CAB -:1032D000E8ECF4FCEDF4FD0CBC00010D8C7F8D7E60 -:1032E00022C3EC94BCED940250047D077CD0ECF436 -:1032F000FCEDF4FD0CBC00010D8C7D8D7C22EC708E -:103300000122C000E5782418F8A604E5782408F81E -:10331000C6547FF6E630E703D0002212329A80F4DA -:10332000C28C857C8C857D8AD28CC0E0C0D0C0F0F8 -:10333000C082C083C000C001C002C003C004C00579 -:10334000C006C007121AF8E5782408F8E66024E5FC -:10335000782410F8A681E57875F021A4248DF582F3 -:10336000E434FCF58378AEE58104C398F9E6F0080F -:10337000A3D9FA74082578F8057808E65480700C0B -:10338000E578B407F3780875780080EFE5782410C5 -:10339000F88681E57875F021A4248DF582E434FC6B -:1033A000F58378AEE58104C398F9E0F608A3D9FA6D -:1033B000D007D006D005D004D003D002D001D00071 -:1033C000D083D082D0F0D0D0D0E032C0E0C0D0C026 -:1033D00000C001C002C28E857E8D857F8BD28E7823 -:1033E0001979097A07E77004A600800BE6600816D1 -:1033F000E67004E74480F70809DAEAE57960131417 -:10340000F579700EE5782408F87600123246D28CF1 -:10341000D28DD002D001D000D0D0D0E0327581ADB5 -:10342000742A90FF93F0757F30757EF8757D607516 -:103430007CF012053F1234CE12175B90FF93E044EC -:1034400001F0B2B31234F81232A880DA22C0007C44 -:1034500001EC2408F8E660090CBC08F512329A80E9 -:10346000EED00022C0F0C082C083C000C006C007FA -:10347000ED2410F876BCED75F021A4248DF582E4DE -:1034800034FCF583C082C083A3A3E4780DF0A3D8F5 -:10349000FCEC547F75F002A42441F582E5F034354C -:1034A000F583E493FE740193F5828E83E493FE74B6 -:1034B0000193FFD083D082EFF0A3EEF0ED2408F863 -:1034C000EC4480F6D007D006D000D083D082D0F074 -:1034D00022757800757B007A08791878087600776D -:1034E000000809DAF8E478087480447FF67401442F -:1034F00010F58975B808D2ABD2A9227581ADD28EEC -:10350000D28CD2AFE57B6032FF90FD95E0548060B5 -:103510002478087908E0547FFA7B00E6547FB502EE -:10352000027BFF08D9F5EB700CEAF012344AAD04C7 -:10353000AC02123461A3A3A3DFD212329A80C57CFD -:10354000017D002204FE04F204F604EA04E604E22B -:1035500004EE04FA04A604AA04D604DA04A204A21F -:1035600004A204DE04BE04B604BA04B204CA04C64B -:1035700004C204CE04D204AE1901030022004802A2 -:1035800000480E301420C81AD0180A0C0506020391 -:1035900001020001CE0181010000C0008000600036 -:1035A0003000180010000800040002000100081894 -:1035B00028380C05100A0200000000000301100A60 -:1035C000020000000000FBE0FBF2090227000102FC -:1035D00000A0FA0904000003FF00000007058102B3 -:1035E00040000007050102400000070583030200B8 -:1035F00001220354005500530042003300340031CF -:1036000000300020002000200020002000200020AA -:073610000020000000000093 -:00000001FF diff --git a/firmware/myricom/lanai.bin.ihex b/firmware/myricom/lanai.bin.ihex deleted file mode 100644 index bf47f4c74940b054f9eb34d18f929eb9e6b1fc37..0000000000000000000000000000000000000000 --- a/firmware/myricom/lanai.bin.ihex +++ /dev/null @@ -1,4771 +0,0 @@ -:100000004FF8F20EFE00C290000007880008E001E1 -:10001000014C9793FFFCE000001400000001000079 -:1000200000009293FFFC02900008F7062A6C9713D9 -:10003000FFFCF7062C109713FFFC07880008E00070 -:1000400015489793FFFCF702053C9713FFFCF70256 -:1000500000039713FFFCF70629E09713FFFC0788BE -:100060000008E000161C9793FFFCF7062B849713FB -:10007000FFFCF7062C1C9713FFFC07880008E00024 -:1000800015489793FFFCF7020ABC9713FFFCF70291 -:1000900000029713FFFCF7062AF89713FFFC078866 -:1000A0000008E000161C9793FFFC8796FFFC8296E1 -:1000B000FFF802140000013C0000000000019293D0 -:1000C000FFFC02900008F7044A9C85160000203AC5 -:1000D0000001EE00010100000001F70475EC0000D2 -:1000E0000001203A0000E600010000000001F704D2 -:1000F00075F000000001203A0000E600012D00002C -:100100000001F7042D38F6862C2806380001F60584 -:100110002D3877390002F482001220320044E600C4 -:1001200001E0B4BA6802E00001E0F0052D38F70400 -:100130003B64F5844F54F7057A10202E0000E6004A -:100140000199972A002095AA001CF6064A9826AC29 -:10015000000177350001C738680077390002073899 -:10016000000CA4BA60020000000194AA0010C73875 -:100170006000873A000400000001972A0014F70489 -:100180004A9C0000000127380001C02E7200D700F1 -:100190000A01E00001D0F7057A1895AA001CF606BE -:1001A0004A9806AC000177350001C73868007739F6 -:1001B00000020738000CA4BA60020000000194AAF3 -:1001C0000010C7386000873A0004F0057A18972AB3 -:1001D0000014F50579D807880008E00001F497932A -:1001E000FFFC8796FFFC8296FFF802140004013C96 -:1001F0000000000000019293FFFC02900008221012 -:100200000038F7047A10F6843B6400000001C03A1D -:100210006A00470C0001D7000A70203A0000E6008F -:10022000024C00000001F70475EC00000001203AC8 -:100230000000E600024C00000001F70475F0000029 -:100240000001203A0000E6000285F4820000F70475 -:100250002D38F6862C2806380001F6052D3877391A -:100260000002F302001220320044E6000274B33AA6 -:100270006802F0052D38F3062A6CF3052C10E00017 -:100280000528F0057A18F38479D8F6844AA0231457 -:1002900000209316FFC4841E00109696FFD4F70426 -:1002A0004A9C9416FFE0851E0014C0367200EC00D4 -:1002B000036C9516FFE477350001C738680077397D -:1002C0000002F3064A98C6B8300006B4000CC58494 -:1002D00000008736000000000001C03A4200E6003E -:1002E00002FCC62400008736000400000001C03A6A -:1002F0005200E600030020320000F6020001203226 -:100300000000E600030D00000001F58200008636C3 -:1003100000008716FFE000000001C0327200E2001A -:100320000348F5020000C0327200E6000350202AA4 -:10033000000086B600048716FFE400000001C03606 -:100340007200E2000351202A0000F5020001202A79 -:100350000000E6000361202E0000F5820001202E3F -:100360000000E600037020260000F4820001202631 -:100370000000E60003A5F60200018716FFD4F3068D -:100380004A9876B90001C6B4700076B50002C6B4CA -:10039000300006B4001486B600009716FFD8E000BF -:1003A00004189696FFDC2714002C9713FFFC831685 -:1003B000FFC4000000019313FFFCF3064A98931357 -:1003C000FFFC9396FFCC07880008E001256897930F -:1003D000FFFC8396FFCC20220000E6000415F60205 -:1003E00000018716FFD4F3064A9876B90001C6B417 -:1003F000700076B50002C6B4300006B4001486B6AC -:1004000000009716FFD89696FFDCF7054AA0E0009B -:10041000041C20320000F602000020320000E6003A -:10042000042CF4820001E0000484F482000086962B -:10043000FFD80000000177350002C738680077391F -:100440000002F68642C8A63A6802C73868007539C5 -:10045000001E7528FFE505B8000286AE00000738CB -:1004600000049716FFECC63057C07630FFF09616A2 -:10047000FFF475AD001E75ACFFE5C6B45FC076B481 -:10048000FFF09696FFF020260000E6000525F30613 -:1004900029E08696FFF0F5820000C7346800C49C0E -:1004A0007200C02E6A00EC0004F0C5240000C62CC7 -:1004B00000008716FFEC00000001A6B2700205AC38 -:1004C0000001C73070007739001E7738FFE5C6B4E9 -:1004D00077C076B4FFF0F6AB280005280002871637 -:1004E000FFF000000001C02E7200EC0004B10630E5 -:1004F0000002F3020003F30576F48716FFF0869EF0 -:100500000004C7387000C7384800C6B470008716AA -:10051000FFF406B400209702FF6C9482FF5096828D -:10052000FF58F30629E0F3052C108796FFFC82960E -:10053000FFF802140000013C00000000000192934B -:10054000FFFC02900008F7047A1800000001203A2E -:100550000000E60005CD00000001F7047A10F684E3 -:100560003B6400000001C03A6A00470C0001203AD9 -:100570000000E60005CDF5864A98F60479D8F684A1 -:100580004F540000000196B2001C06B400017735FC -:100590000001C7386800773900020738000CA53A17 -:1005A00058020000000195320010C7385800873A01 -:1005B0000004F0057A189732001407880008E0005C -:1005C00001F49793FFFCE00005FC00000001F70434 -:1005D0002D38F6862C2806380001F6052D38773997 -:1005E0000002F502001220320044E60005F4B53A9C -:1005F0006802F0052D38F5062A6CF5052C10879653 -:10060000FFFC8296FFF802140000013C000000008D -:1006100000019293FFFC0290000885960000F70409 -:1006200075EC852E0020203A0000E60006CCF5058A -:100630007A08F70475F000000001203A0000E60097 -:1006400006CC00000001F7047A08F6843B64000041 -:100650000001C03A6A00470C0001D7000A70203A36 -:100660000000E60006CC00000001872E001CF68486 -:100670004F54F7057A00C7347200203A0000EE00AC -:10068000068DF5020001E0000690F50579F8F08589 -:1006900079F8F6847A00C7387000C6B47000F704A1 -:1006A00079F8F68579E8C7387000C6347000F70429 -:1006B0004A9C00000001C0367200EC0006CCF60532 -:1006C00079F020360000EC0006F800000001F70485 -:1006D0002D38F6862C2806380001F6052D38773996 -:1006E0000002F502001320320044E6000738B53A54 -:1006F0006802E0000738F0052D38F7044A9C000036 -:100700000001C0327200EE00071900000001F7047A -:100710004A9CE0000728F70579F020320000EC0041 -:10072000072800000001F08579F0F58579E0078859 -:100730000008E000074C9793FFFC8796FFFC829629 -:10074000FFF802140004013C000000000001929335 -:10075000FFFC0290000822100038F70475EC00003E -:100760000001203A0000E60007A400000001F704A1 -:1007700075F000000001203A0000E60007A4000028 -:100780000001F7047A08F6843B6400000001C03AD7 -:100790006A00470C0001D7000A70203A0000E6000A -:1007A00007D5F4020000F7042D38F6862C28063809 -:1007B0000001F6052D3877390002F30200132032CC -:1007C0000044E60007CCB33A6802F0052D38E0009B -:1007D0000AA4F3062B84F68479E8F6064A9877355E -:1007E0000001C738680077390002F68479E00738DD -:1007F000000CA33A6002C3B4000093360010C7385F -:100800006000873A0004231400209316FFC4973633 -:100810000014849E0010F6844AA09496FFE09696F9 -:10082000FFD4851E0014F7044A9C00000001C03666 -:100830007200EC0008EC9516FFE477350001C7382C -:10084000680077390002C6B8600006B4000CC584A1 -:1008500000008736000000000001C03A4A00E600B0 -:10086000087CC62000008736000400000001C03A62 -:100870005200E600088020320000F602000120321B -:100880000000E600088D00000001F58200008636B9 -:1008900000008716FFE000000001C0327200E20095 -:1008A00008C8F5020000C0327200E60008D0202A15 -:1008B000000086B600048716FFE400000001C03681 -:1008C0007200E20008D1202A0000F5020001202A6F -:1008D0000000E60008E1202E0000F5820001202E35 -:1008E0000000E60008F020220000F40200012022AF -:1008F0000000E6000925F60200018716FFD4F30682 -:100900004A9876B90001C6B4700076B50002C6B444 -:10091000300006B4001486B600009716FFD8E00039 -:1009200009989696FFDC2714002C9713FFFC83167A -:10093000FFC4000000019313FFFCF3064A989313D1 -:10094000FFFC9396FFCC07880008E0012568979389 -:10095000FFFC8396FFCC20220000E6000995F602FA -:1009600000018716FFD4F3064A9876B90001C6B491 -:10097000700076B50002C6B4300006B4001486B626 -:1009800000009716FFD89696FFDCF7054AA0E00016 -:10099000099C20320000F602000020320000E60030 -:1009A00009ACF4820001E0000A04F482000086969B -:1009B000FFD80000000177350002C738680077399A -:1009C0000002F68642C8A63A6802C7386800753940 -:1009D000001E7528FFE505B8000286AE0000073846 -:1009E00000049716FFECC63057C07630FFF096161D -:1009F000FFF475AD001E75ACFFE5C6B45FC076B4FC -:100A0000FFF09696FFF020260000E6000AA5F30608 -:100A10002AF88696FFF0F5820000C7346800C49C6F -:100A20007200C02E6A00EC000A70C5240000C62CBB -:100A300000008716FFEC00000001A6B2700205ACB2 -:100A40000001C73070007739001E7738FFE5C6B463 -:100A500077C076B4FFF0F6AB2800052800028716B1 -:100A6000FFF000000001C02E7200EC000A310630D9 -:100A70000002F3020002F30576F48716FFF0869E6B -:100A80000004C7387000C7384800C6B47000871625 -:100A9000FFF406B400209702FF6C9482FF50968208 -:100AA000FF58F3062AF8F3052C1C8796FFFC829664 -:100AB000FFF802140000013C0000000000019293C6 -:100AC000FFFC02900008F68479E8F70479F800004A -:100AD0000001C6B47000F7047A20F68579E807387B -:100AE0000001F7057A20F70479F0F6047A20C03681 -:100AF0007200E6000B2CF6862C28F7042D38000037 -:100B0000000106380001F6052D3877390002F5821C -:100B1000001320320044E6000B20B5BA6802F0054D -:100B20002D38F5862B84E0000B38F5852C1C0788C2 -:100B30000008E000074C9793FFFC8796FFFC829625 -:100B4000FFF802140000013C000000000001929335 -:100B5000FFFC02900008F7062C109713FFFCF70625 -:100B600029E09713FFFC07880008E00014F497932E -:100B7000FFFCF7062C109713FFFCF7062A6C97135F -:100B8000FFFC07880008E00014F49793FFFCF706C9 -:100B90002C1C9713FFFCF7062AF89713FFFC078815 -:100BA0000008E00014F49793FFFCF7062C1C971341 -:100BB000FFFCF7062B849713FFFC07880008E00072 -:100BC00014F49793FFFC8796FFFC8296FFF80214BB -:100BD0000000013C0000000000019293FFFC029025 -:100BE0000008F0052D38F0052D3C8796FFFC829615 -:100BF000FFF802140000013C000000000001929385 -:100C0000FFFC0290000822100018FF852EDCF7067A -:100C10000C3EC77C7400203A0000E60014299716A9 -:100C2000FFF44738FFFBF6846F50CFB8000083967F -:100C3000FFF4F702003FC39C6D80C71C7400203A8C -:100C4000003FE20012609396FFF477390002F682CB -:100C50000C5CA6B6700200000001C1340000000068 -:100C600012600000126000000D6800000D680000B6 -:100C70000D5C00000D5C00000D6800000D680000B8 -:100C80001250000012500000123C0000123C000004 -:100C90000DE000000DE00000123C0000123C0000DE -:100CA0000DE800000DF400000E0000000E20000012 -:100CB0000E4000000E6000000E8000000EA000003C -:100CC0000EC000000EC800000ED000001228000068 -:100CD0000ED800000EF400000F10000012280000D3 -:100CE0000F1800000F1800000F2400000F24000050 -:100CF0000F4400000F4400000F6400000F64000068 -:100D00000F8400000F8400000F8C00000F8C000087 -:100D10000F9400000F9400000FB000000FB000000F -:100D20000FB800000FD800000FF80000102C0000D2 -:100D3000106000001094000010C8000010FC0000BB -:100D400011300000114C0000116800001214000066 -:100D50001184000011B4000011E400001214F382A9 -:100D60000006E00012549393FFFCF60200052032C7 -:100D70000014E6000DB527000010203A0001E20043 -:100D80000DB5F7062DCCF6842ECC0000000175B50C -:100D90000002B62E700206B40001F6852ECC860243 -:100DA000FF34F7062E4C2036001FE2000DB5B62E9C -:100DB0007002F0052ECCF7042D5800000001873A90 -:100DC000000000000001873A0018000000010788B9 -:100DD0000008C13800009793FFFCE000126000009B -:100DE0000001E0001240F3820006F382000BE000F5 -:100DF00012549393FFFCF3820007E0001254939384 -:100E0000FFFCF382000B9393FFFC07880008E000CF -:100E100015849793FFFCF3820005E000125493932E -:100E2000FFFCF38200079393FFFC07880008E000B3 -:100E300015849793FFFCF3820005E000125493930E -:100E4000FFFCF382000B9393FFFC07880008E0008F -:100E500015849793FFFCF3820006E00012549393ED -:100E6000FFFCF38200079393FFFC07880008E00073 -:100E700015849793FFFCF3820006E00012549393CD -:100E8000FFFCF382000B9393FFFC07880008E0004F -:100E900015849793FFFCF3820005E00012549393AE -:100EA000FFFCF38200079393FFFC07880008E00033 -:100EB00015849793FFFCF3820005E000125493938E -:100EC000FFFCE0001240F382000BE0001240F382CE -:100ED0000007E000122CF382000BF382000B9393C7 -:100EE000FFFC07880008E00015849793FFFCE000F2 -:100EF0001240F3820006F38200079393FFFC0788F9 -:100F00000008E00015849793FFFCE0001240F38294 -:100F10000006E000122CF382000BF3820014E000C4 -:100F200012549393FFFCF38200149393FFFC078801 -:100F30000008E00015849793FFFCF3820005E000B1 -:100F400012549393FFFCF38200149393FFFC0788E1 -:100F50000008E00015849793FFFCF3820006E00090 -:100F600012549393FFFCF38200149393FFFC0788C1 -:100F70000008E00015849793FFFCF3820005E00071 -:100F800012549393FFFCE0001240F3820014E0003F -:100F9000122CF3820014F38200149393FFFC078851 -:100FA0000008E00015849793FFFCE0001240F382F4 -:100FB0000006E000122CF3820014F38200149393D5 -:100FC000FFFC07880008E00015849793FFFCF3827C -:100FD000000BE00012549393FFFCF38200149393F0 -:100FE000FFFC07880008E00015849793FFFCF3825C -:100FF0000007E00012549393FFFCF38200149393D4 -:10100000FFFC07880008E00015849793FFFCF3823B -:10101000000B9393FFFC07880008E000158497936A -:10102000FFFCF3820005E00012549393FFFCF3826F -:1010300000149393FFFC07880008E0001584979341 -:10104000FFFCF38200079393FFFC07880008E00091 -:1010500015849793FFFCF3820005E00012549393EC -:10106000FFFCF38200149393FFFC07880008E00064 -:1010700015849793FFFCF382000B9393FFFC078882 -:101080000008E00015849793FFFCF3820006E0005F -:1010900012549393FFFCF38200149393FFFC078890 -:1010A0000008E00015849793FFFCF38200079393F8 -:1010B000FFFC07880008E00015849793FFFCF3828B -:1010C0000006E00012549393FFFCF3820014939304 -:1010D000FFFC07880008E00015849793FFFCF3826B -:1010E000000B9393FFFC07880008E000158497939A -:1010F000FFFCF3820005E00012549393FFFCF3829F -:1011000000149393FFFC07880008E0001584979370 -:10111000FFFCF38200079393FFFC07880008E000C0 -:1011200015849793FFFCF3820005E000125493931B -:10113000FFFCF38200149393FFFC07880008E00093 -:1011400015849793FFFCE0001240F382000BF382BA -:1011500000149393FFFC07880008E0001584979320 -:10116000FFFCE0001240F3820007F3820014939327 -:10117000FFFC07880008E00015849793FFFCE0005F -:10118000122CF382000BF38200149393FFFC078868 -:101190000008E00015849793FFFCF382000B939303 -:1011A000FFFC07880008E00015849793FFFCE0002F -:1011B0001240F3820006F38200149393FFFC078829 -:1011C0000008E00015849793FFFCF38200079393D7 -:1011D000FFFC07880008E00015849793FFFCE000FF -:1011E0001240F3820006F38200149393FFFC0788F9 -:1011F0000008E00015849793FFFCE000122CF382B6 -:10120000000BF7043528F682000107380008E000DB -:1012100013CCF7053544F38200149393FFFC078841 -:101220000008E00015849793FFFCF3820007939376 -:10123000FFFC07880008E00015849793FFFCF38209 -:1012400000059393FFFC07880008E000158497933E -:10125000FFFC9013FFFC07880008E00015849793BB -:10126000FFFC8396FFF400000001779C0014703EA1 -:10127000FFE1E600129DF7060400F7046F5C000032 -:10128000000107380001F7056F5CF7046F5CE000B0 -:101290000000000000018396FFF4F7060400C01E62 -:1012A0007400E600142900000001F7042ED0F68433 -:1012B00035240738000120360000E6001405F70544 -:1012C0002ED0F704E01400000001203A0000E600F0 -:1012D0001405F6820000F685E014F7042ED8C53414 -:1012E000000007380001F7052ED8202A0002EE0082 -:1012F00013CCF6820000F684352800000001873602 -:10130000000000000001203A0002E60013A005B42E -:1013100000089593FFFC9516FFE89596FFE49696D6 -:10132000FFE007880008E00016649793FFFC85162D -:10133000FFE88596FFE48696FFE020220000E600A5 -:101340001390F70200008636000C000000012032E6 -:10135000000FE20013750000000187360014000042 -:101360000001073800019736001487360014E000AA -:101370001390F702000076B10002C6B46000773522 -:101380000005C7386A00C738600007380010C72C4E -:101390007000203A0000E6001200F705352CF684B4 -:1013A0003528F7046F4C00000001C0367200E600DB -:1013B00013C007341494F3846F44E00013C4F3851E -:1013C0003528F7053528E00012E805280001203609 -:1013D0000000E6001429F6862C28F7042D38F005C5 -:1013E000352406380001F6052D3877390002F382DE -:1013F000000D20320044E6001428B3BA6802E00071 -:101400001428F0052D38F704E01000000001203A00 -:101410000000E6001429F7020000F705E010078835 -:101420000008E00102989793FFFCF4842D38F7043C -:101430002D3C00000001C03A4A00E6000C09F68687 -:101440002C2877390002A53A680200000001202A02 -:101450000014E600149127280015203A0001E2004C -:101460001491F7062DCCF6842ECC8602FF3475B588 -:101470000002B52E700206B40001F6852ECCF706E8 -:101480002E4C2036001FE2001491B62E7002F0059B -:101490002ECCF7062D4476A90002A7367002000074 -:1014A0000001873A000000000001C6B470008736D2 -:1014B00000049496FFEC07880008C1380000979359 -:1014C000FFFCF7042D3C8496FFEC07380001203A1E -:1014D0000044E600142CF7052D3CE000142CF00528 -:1014E0002D3C8796FFFC8296FFF802140000013C19 -:1014F0000000000000019293FFFC02900008841697 -:101500000000F702000085960004203A0021EE005A -:10151000153495A20000F606233807200084C6A0E3 -:101520000000963A000427380004C03A6A00EC0034 -:101530001520000000018796FFFC8296FFF8021438 -:101540000008013C0000000000019293FFFC0290A3 -:1015500000088696000087160004F6042D40973692 -:1015600000009736000407300001F7052D4096363D -:1015700000088796FFFC8296FFF802140008013CE1 -:101580000000000000019293FFFC02900008851605 -:10159000000000000001202A0014E60015D92728C9 -:1015A0000015203A0001E20015D9F7062DCCF6848B -:1015B0002ECC8602FF3475B50002B52E700206B43B -:1015C0000001F6852ECCF7062E4C2036001FE200D7 -:1015D00015D9B62E7002F0052ECCF6862D4477294B -:1015E0000002A6BA68020000000186B600000000F2 -:1015F0000001C7386800873A00040000000107882E -:101600000008C13800009793FFFC8796FFFC829684 -:10161000FFF802140004013C000000000001929356 -:10162000FFFC029000088716000086960004F6066C -:101630002D4476B5000285BA000000000001B5B661 -:101640006002C6B47000859600080000000195B6DF -:1016500000048796FFFC8296FFF80214000C013C00 -:101660000000000000019293FFFC02900008861623 -:101670000000000000018732000400000001203A51 -:10168000000F86B20000C5380000EE0016B4C5B4E5 -:1016900000002036000FEE0016B400000001203AD2 -:1016A0000000EC0016B50000000120360000EC0040 -:1016B00016D0000000018732000C0000000107383E -:1016C00000019732000C8732000CE00016D8F402BB -:1016D0000000C02A5A00440C00018796FFFC829645 -:1016E000FFF802140004013C0000000000010000AB -:1016F00000009293FFFC02900008F7062EE097137B -:10170000FFFCF70632D49713FFFC07880008E000BF -:1017100015489793FFFCF702182C9713FFFCF782EC -:1017200000099793FFFCF7062EE09713FFFC07884C -:101730000008E000161C9793FFFCF702345897133B -:10174000FFFCF702000C9713FFFCF7062F6C9713B2 -:10175000FFFC07880008E000161C9793FFFCF702C7 -:101760003F949713FFFCF782000B9793FFFCF7065B -:101770002FF89713FFFC07880008E000161C9793CA -:10178000FFFCF7023B849713FFFCF782000B979353 -:10179000FFFCF70632289713FFFC07880008E000DB -:1017A000161C9793FFFCF70226E49713FFFCF70241 -:1017B00000139713FFFCF70630849713FFFC07888C -:1017C0000008E000161C9793FFFCF70226A0971371 -:1017D000FFFCF70200119713FFFCF7063110971377 -:1017E000FFFC07880008E000161C9793FFFCF70237 -:1017F000182C9713FFFCF78200099793FFFCF7065C -:10180000319C9713FFFC07880008E000161C979393 -:10181000FFFCF0057A78F00532E88796FFFC8296A7 -:10182000FFF802140000013C000000000001929348 -:10183000FFFC0290000822100050F70471C800005D -:101840000001203A0000E6001855F68671C4E00059 -:10185000186CF6020000F70471D40000000177391B -:101860000002C7386800863A001800000001F6053B -:1018700032C486B2000807018000C5B47400F58543 -:1018800032D087320018F6866F4477390002A73AC3 -:101890006802202E0000F70532C0073809D886B24A -:1018A0000004F70532CCE6001941F68532C8F7048A -:1018B0007198F6847A782738000120360000E60017 -:1018C0001910F7057198F70476FC00000001203A22 -:1018D0000000E60018E8F3020011F30632D4F30525 -:1018E00076FCE00018F8F7020001F30576F8F3063D -:1018F00032D4F3057700F7020000203A0000E6003A -:101900001914F3020001F3063110E000268CF305F0 -:1019100032D4F3020001F3057A78F3063084F3053C -:1019200032D4F30432C4000000019313FFFC078893 -:101930000008E00006109793FFFCE000268C0000F2 -:101940000001F3020000202E0000E6001CB99316EF -:10195000FFE4873200088696FFE4C3040000C03A23 -:101960003200E6001984203600008732000C0000A7 -:101970000001C03A3200E600198420360000F682E9 -:10198000000120360000E6001CB8F3020000F70456 -:1019900032C09316FFACF58432C4863A142803B8DB -:1019A0001420042C000886BA142400000001C03260 -:1019B0006A00EC001A709616FFEC77310001C73808 -:1019C000600077390002C63838000630000C86B255 -:1019D0000000872E00088516FFACC0367200E600B6 -:1019E0001A00C484000086B20004872E000C000098 -:1019F0000001C0367200E6001A04202A0000F50239 -:101A00000001202A0000E6001A1100000001F48203 -:101A1000000086B200008722000000000001C036EE -:101A20007200E2001A4CF5820000C0367200E60037 -:101A30001A54202E000086B2000487220004000001 -:101A40000001C0367200E2001A55202E0000F58217 -:101A50000001202E0000E6001A6520260000F48216 -:101A6000000120260000E6001A70F3020001931620 -:101A7000FFAC8316FFAC00000001201A0000E60056 -:101A80001AB1F60200018716FFEC0000000176B9DA -:101A90000001C6B4700076B50002C6B4380006B4C2 -:101AA000001486B600009716FFF0E0001B1896960B -:101AB000FFF4271400149713FFFC9413FFFC939377 -:101AC000FFFC9396FFBC07880008E0012568979308 -:101AD000FFFC8396FFBC20220000E6001B15F602E7 -:101AE00000018716FFEC0000000176B90001C6B4C2 -:101AF000700076B50002C6B4380006B4001486B68D -:101B000000009716FFF09696FFF4971E0008E0007D -:101B10001B1C20320000F602000020320000E6000C -:101B20001CB8F3020000F60432C09316FFAC86B274 -:101B3000142803B014200430148C873214240000BD -:101B40000001C0367200EC001C049696FFEC77355D -:101B50000001C738680077390002C5B8380005AC05 -:101B6000000C86AE00008732148C8516FFACC036A0 -:101B70007200E6001B94C484000086AE0004873225 -:101B8000149000000001C0367200E6001B98202A65 -:101B90000000F5020001202A0000E6001BA500005D -:101BA0000001F482000086AE0000872200000000E1 -:101BB0000001C0367200E2001BE0F6020000C036F1 -:101BC0007200E6001BE82032000086AE0004872287 -:101BD000000400000001C0367200E2001BE9203260 -:101BE0000000F602000120320000E6001BF920266A -:101BF0000000F482000120260000E6001C04F3022D -:101C000000019316FFAC8316FFAC00000001201A00 -:101C10000000E6001C45F60200018716FFEC0000FC -:101C2000000176B90001C6B4700076B50002C6B4F2 -:101C3000380006B4001486B600009716FFF0E000E6 -:101C40001CAC9696FFF4271400149713FFFC941312 -:101C5000FFFC9393FFFC9396FFBC07880008E0010C -:101C600025689793FFFC8396FFBC20220000E600C6 -:101C70001CA9F60200018716FFEC0000000176B9EE -:101C80000001C6B4700076B50002C6B4380006B4D0 -:101C9000001486B600009716FFF09696FFF4971E84 -:101CA0000008E0001CB020320000F60200002032E4 -:101CB0000000E6001E15F3020001F68432C00000A9 -:101CC000000185B60EF486360EF8202E0010E200D4 -:101CD0001CDC20320010E2001CF9000000018736F5 -:101CE0000F00000000010738000197360F0087360B -:101CF0000F00E0001D24F702000007300001C03A89 -:101D00005A00E6001D1DF682000020320010E60099 -:101D10001D20202E0000E6001D24C7340000F6829E -:101D20000001C7340000203A0000E6001E14F30250 -:101D30000001F30432CC000000019316FFDC931382 -:101D4000FFFC07880008E00043689793FFFC20220F -:101D50000000E6001DFCF30200008316FFDC00001B -:101D60000001861A00000000000120320010E2008D -:101D70001D9176B10002871A000C0000000107389F -:101D80000001971A000C871A000CE0001DFCF302FA -:101D90000000F302004C9313FFFCC6B460007735DB -:101DA0000004C7386A008316FFDCC7386000C738F4 -:101DB0003000073800109713FFFCF3067A289313BE -:101DC000FFFC9616FFB407880008E00126F89793F9 -:101DD000FFFC8616FFB4000000010630000120322F -:101DE0000011E6001DEC00000001F6020000831661 -:101DF000FFDC00000001961A0000F30200019316B8 -:101E0000FFD48316FFD400000001201A0000E60072 -:101E10001E18F30200019316FFE48316FFE400008E -:101E20000001201A0000E6001F35F6820CABF70413 -:101E300032B48316FFD407380001F70532B4F70433 -:101E400032B4201A0000E6001E7000000001F70402 -:101E500032C0F306E030C03A3200E6001E700000E7 -:101E60000001F70432E80000000107380001F7051F -:101E700032E8F70471C400000001203A0000E600D7 -:101E80001EADF6862C28F7042D3800000001063818 -:101E90000001F6052D3877390002F302000A2032DE -:101EA0000044E6001EACB33A6802F0052D38F70492 -:101EB00071D4F68471CC07380001C03A6A00E6009C -:101EC0001EC8F70571D4F00571D4F68471D4F704F7 -:101ED00071D0F00571C4C0367200470C0001F68461 -:101EE00032D00000000120360000E60025D9F705B9 -:101EF00071C8F704719800000001203A0000E60064 -:101F0000257900000001F70475EC00000001203A7B -:101F10000000E600257800000001F70475F00000DD -:101F20000001203A0000E600257800000001E000F2 -:101F300025DCF306319CF00532E8F70432C0F604E4 -:101F40006F5496BA000420320000E6001F60F302CE -:101F5000000CF3020001F3056F54E0001F68F70264 -:101F60000001F3056F58F7020000203A0000E60078 -:101F70001F7CF3062F6CE000268CF30532D4F58429 -:101F80007A7024940010202E0001E6002284F5854A -:101F90007AA0F7020001F60432C8F7057A70F70458 -:101FA00032C4F68432C0F6057A2C9002FF8090028B -:101FB000FF38F5847A28073800249582FF3C970281 -:101FC000FF409602FF448736141000000001C73816 -:101FD0006000973614108736141800000001073887 -:101FE00000019736141887361418F0056F50F7045F -:101FF00032B89596FFECC7386000F70532B8F704A1 -:1020000032BCF3062FF807380001F70532BCF7049D -:1020100032BCF30532D4F7060C3EC07E7400E600F5 -:10202000203400000001C07E7400E600202500007E -:102030000001F7060C3EC77C7400203A0010E60051 -:10204000268C00000001F70432E4FF820010F584C2 -:102050006F5807380001202E0021E2002090F7057C -:1020600032E4F7042D38F6862C2806380001F605F0 -:102070002D387739000220320044E6002084B5BABA -:102080006802F0052D38F3020022E0002094F305E9 -:102090006F58F0056F54F58432C000000001902E97 -:1020A0000004872E000000000001203A0002E60034 -:1020B00021C0000000018702FF38032C0EF49316A4 -:1020C000FFCCF7057A689313FFFC9596FFB8078855 -:1020D0000008E00043A09793FFFC8596FFB82022FC -:1020E0000000E600217C00000001862E0EF80000B2 -:1020F000000120320010E2002119F302004C872E6B -:102100000F000000000107380001972E0F00872EF6 -:102110000F00E000217C000000019313FFFCF30698 -:102120007A289313FFFC76B10002C6B460007735BD -:102130000004C7386A008316FFCCC7386000C73870 -:102140003000073800109713FFFC9596FFB89616DD -:10215000FFB407880008E00126F89793FFFC861675 -:10216000FFB48596FFB80630000120320011E6006A -:10217000217800000001F6020000962E0EF8F70408 -:1021800032C0F306E030C03A3200E60021C0000061 -:102190000001F704E0180000000177B8001E703E4F -:1021A000FFE1E60021C1000000010F814000F704BB -:1021B00079C80000000107380001F70579C8F70465 -:1021C00079C8F70471C400000001203A0000E6005D -:1021D00021FDF6862C28F7042D3800000001063872 -:1021E0000001F6052D3877390002F302000A20328B -:1021F0000044E60021FCB33A6802F0052D38F704EC -:1022000071D4F68471CC07380001C03A6A00E60048 -:102210002218F70571D4F00571D4F68471D4F7044F -:1022200071D0F00571C4C0367200470C0001F6840D -:1022300032D00000000120360000E60025D9F70565 -:1022400071C8F704719800000001203A0000E60010 -:10225000257900000001F70475EC00000001203A28 -:102260000000E600257800000001F70475F000008A -:102270000001203A0000E600257800000001E0009F -:1022800025DCF306319CF0057A889002FF38F005D2 -:102290006F509002FF80F70432C4F3063228F30532 -:1022A00032D4F60432C8F6847A2CF50200000738DE -:1022B0000024F7057A9820320000E60022D5F605C2 -:1022C0007A90C02A5A00E6002620C0326A00EE004A -:1022D000262100000001F68432C00000000187368C -:1022E000141000000001C7386000973614108736BC -:1022F00014180000000107380001973614188736BB -:102300001418F70432B800000001C7386000F70560 -:1023100032B8F70432BC0000000107380001F705AD -:1023200032BCF70432BC20320000E6002345000036 -:102330000001F70432E0F5057A7007380001E0008B -:102340002348F70532E0F5057A70F5846F580000F0 -:102350000001202E0021E200238CF6862C28F704B1 -:102360002D380000000106380001F6052D387739B8 -:10237000000220320044E6002380B5BA6802F0056E -:102380002D38F3020022E0002390F3056F58F0058A -:102390006F54F58432C000000001902E0004872E97 -:1023A000000000000001203A0002E60024BC00000A -:1023B00000018702FF38032C0EF49316FFC4F705C3 -:1023C0007A689313FFFC9596FFB807880008E00031 -:1023D00043A09793FFFC8596FFB820220000E600FB -:1023E000247800000001862E0EF800000001203243 -:1023F0000010E2002415F302004C872E0F000000AD -:10240000000107380001972E0F00872E0F00E00013 -:102410002478000000019313FFFCF3067A2893133D -:10242000FFFC76B10002C6B4600077350004C738FF -:102430006A008316FFC4C7386000C7383000073809 -:1024400000109713FFFC9596FFB89616FFB4078807 -:102450000008E00126F89793FFFC8616FFB48596E6 -:10246000FFB80630000120320011E600247400009D -:102470000001F6020000962E0EF8F70432C0F306B3 -:10248000E030C03A3200E60024BC00000001F7044E -:10249000E0180000000177B8001E703EFFE1E60082 -:1024A00024BD000000010F814000F70479C800003E -:1024B000000107380001F70579C8F70479C8F70467 -:1024C00071C400000001203A0000E60024F9F686FD -:1024D0002C28F7042D380000000106380001F6050D -:1024E0002D3877390002F302000A20320044E6005A -:1024F00024F8B33A6802F0052D38F70471D4F68455 -:1025000071CC07380001C03A6A00E6002514F705CF -:1025100071D4F00571D4F68471D4F70471D0F0054C -:1025200071C4C0367200470C0001F68432D000003E -:10253000000120360000E60025D9F70571C8F70430 -:10254000719800000001203A0000E60025790000A3 -:102550000001F70475EC00000001203A0000E600DD -:10256000257800000001F70475F000000001203A12 -:102570000000E60025D100000001F58476F8000097 -:102580000001202E0021E20025C4F6862C28F70445 -:102590002D380000000106380001F6052D38773986 -:1025A000000220320044E60025B0B5BA6802F0050A -:1025B0002D38F3020022F30576F8F3047700E000EB -:1025C00025C8F30576FCF00576FCE00025D8F0057B -:1025D0007A78E00025DCF306319CF3062EE0F30563 -:1025E00032D4F70471C800000001203A0000E60070 -:1025F000268CF6862C28F7042D38000000010638BA -:102600000001F6052D3877390002F3020009203267 -:102610000044E600268CB33A6802E000268CF00500 -:102620002D38F7047A9000000001C03A6A00EE00ED -:102630002641C5B40000C7385A00E0002648F70517 -:102640007A90C5B80000F0057A90F6847A88F7068B -:102650007A2876350003A732700206B40001971677 -:10266000FFEC84A6FFFCF7067A2CF3047A98948298 -:10267000FF3C9302FF409582FF44B5B27002F7041D -:102680007A98F6857A88C7385800F7057A98879639 -:10269000FFFC8296FFF802140000013C00000000DD -:1026A00000019293FFFC02900008F7020001F70579 -:1026B0007A78F7063084F70532D4F70432C4000084 -:1026C00000019713FFFC07880008E00006109793AD -:1026D000FFFC8796FFFC8296FFF802140000013C85 -:1026E0000000000000019293FFFC029000082210FD -:1026F0000050F70432D0F3020000203A0000E60058 -:102700002A719316FFE4F68432C48616FFE48736F6 -:102710000008C3040000C03A3200E600273C203223 -:1027200000008736000C00000001C03A3200E600CD -:10273000273C20320000F602000120320000E600B3 -:102740002A70F3020000F70432C09316FFACF58440 -:1027500032C4863A142803B81420042C000886BA20 -:10276000142400000001C0326A00EC0028289616EC -:10277000FFEC77310001C738600077390002C638B6 -:1027800038000630000C86B20000872E000885163F -:10279000FFACC0367200E60027B8C484000086B2E1 -:1027A0000004872E000C00000001C0367200E60015 -:1027B00027BC202A0000F5020001202A0000E600C4 -:1027C00027C900000001F482000086B200008722C1 -:1027D000000000000001C0367200E2002804F5820B -:1027E0000000C0367200E600280C202E000086B2E1 -:1027F00000048722000400000001C0367200E200DD -:10280000280D202E0000F5820001202E0000E60099 -:10281000281D20260000F482000120260000E6008A -:102820002828F30200019316FFAC8316FFAC0000CA -:102830000001201A0000E6002869F6020001871650 -:10284000FFEC0000000176B90001C6B4700076B557 -:102850000002C6B4380006B4001486B6000097160D -:10286000FFF0E00028D09696FFF427140014971389 -:10287000FFFC9413FFFC9393FFFC9396FFBC078827 -:102880000008E00125689793FFFC8396FFBC202297 -:102890000000E60028CDF60200018716FFEC0000DC -:1028A000000176B90001C6B4700076B50002C6B466 -:1028B000380006B4001486B600009716FFF096960E -:1028C000FFF4971E0008E00028D420320000F60232 -:1028D000000020320000E6002A70F3020000F60437 -:1028E00032C09316FFAC86B2142803B01420043013 -:1028F000148C8732142400000001C0367200EC00F2 -:1029000029BC9696FFEC77350001C7386800773907 -:102910000002C5B8380005AC000C86AE0000873256 -:10292000148C8516FFACC0367200E600294CC484B6 -:10293000000086AE00048732149000000001C0360B -:102940007200E6002950202A0000F5020001202A2A -:102950000000E600295D00000001F482000086AE60 -:1029600000008722000000000001C0367200E20073 -:102970002998F6020000C0367200E60029A0203235 -:10298000000086AE00048722000400000001C0366B -:102990007200E20029A120320000F602000120327C -:1029A0000000E60029B120260000F4820001202664 -:1029B0000000E60029BCF30200019316FFAC831669 -:1029C000FFAC00000001201A0000E60029FDF6021D -:1029D00000018716FFEC0000000176B90001C6B4C3 -:1029E000700076B50002C6B4380006B4001486B68E -:1029F00000009716FFF0E0002A649696FFF4271473 -:102A000000149713FFFC9413FFFC9393FFFC939621 -:102A1000FFBC07880008E00125689793FFFC8396B8 -:102A2000FFBC20220000E6002A61F60200018716A2 -:102A3000FFEC0000000176B90001C6B4700076B565 -:102A40000002C6B4380006B4001486B6000097161B -:102A5000FFF09696FFF4971E0008E0002A682032E7 -:102A60000000F602000020320000E6002BCDF30249 -:102A70000001F68432C00000000185B60EF48636EF -:102A80000EF8202E0010E2002A9420320010E200FE -:102A90002AB10000000187360F000000000107384E -:102AA000000197360F0087360F00E0002ADCF7029E -:102AB000000007300001C03A5A00E6002AD5F6822D -:102AC000000020320010E6002AD8202E0000E60088 -:102AD0002ADCC7340000F6820001C7340000203A27 -:102AE0000000E6002BCCF3020001F30432CC00001E -:102AF00000019316FFDC9313FFFC07880008E00039 -:102B000043689793FFFC20220000E6002BB4F302F9 -:102B100000008316FFDC00000001861A00000000A0 -:102B2000000120320010E2002B4976B10002871A22 -:102B3000000C0000000107380001971A000C871AEA -:102B4000000CE0002BB4F3020000F302004C9313DE -:102B5000FFFCC6B4600077350004C7386A008316EE -:102B6000FFDCC7386000C738300007380010971303 -:102B7000FFFCF3067A289313FFFC9616FFB4078830 -:102B80000008E00126F89793FFFC8616FFB40000CA -:102B900000010630000120320011E6002BA40000E5 -:102BA0000001F60200008316FFDC00000001961A07 -:102BB0000000F30200019316FFD48316FFD4000037 -:102BC0000001201A0000E6002BD0F302000193164A -:102BD000FFE48316FFE400000001201A0000E60075 -:102BE0002CEDF6820CABF70432B48316FFD4073811 -:102BF0000001F70532B4F70432B4201A0000E600F1 -:102C00002C2800000001F70432C0F306E030C03A7F -:102C10003200E6002C2800000001F70432E8000032 -:102C2000000107380001F70532E8F70471C400001D -:102C30000001203A0000E6002C65F6862C28F704F7 -:102C40002D380000000106380001F6052D387739CF -:102C50000002F302000A20320044E6002C64B33A7A -:102C60006802F0052D38F70471D4F68471CC07386A -:102C70000001C03A6A00E6002C80F70571D4F00527 -:102C800071D4F68471D4F70471D0F00571C4C036E4 -:102C90007200470C0001F68432D00000000120369B -:102CA0000000E6003391F70571C8F7047198000041 -:102CB0000001203A0000E600333100000001F70473 -:102CC00075EC00000001203A0000E60033300000FF -:102CD0000001F70475F000000001203A0000E60052 -:102CE000333000000001E0003394F306319CF0051E -:102CF00032E8F70432C0F6046F5496BA000420326A -:102D00000000E6002D18F302000CF3020001F305A9 -:102D10006F54E0002D20F7020001F3056F58F70211 -:102D20000000203A0000E6002D34F3062F6CE0008E -:102D30003444F30532D4F5847A7024940010202EA4 -:102D40000001E600303CF5857AA0F7020001F604A8 -:102D500032C8F7057A70F70432C4F68432C0F6053B -:102D60007A2C9002FF809002FF38F5847A28073889 -:102D700000249582FF3C9702FF409602FF4487366D -:102D8000141000000001C738600097361410873611 -:102D90001418000000010738000197361418873610 -:102DA0001418F0056F50F70432B89596FFECC73849 -:102DB0006000F70532B8F70432BCF3062FF8073885 -:102DC0000001F70532BCF70432BCF30532D4F70634 -:102DD0000C3EC07E7400E6002DEC00000001C07EB9 -:102DE0007400E6002DDD00000001F7060C3EC77CF4 -:102DF0007400203A0010E600344400000001F7049B -:102E000032E4FF820010F5846F5807380001202E4D -:102E10000021E2002E48F70532E4F7042D38F6864B -:102E20002C2806380001F6052D38773900022032AB -:102E30000044E6002E3CB5BA6802F0052D38F302D6 -:102E40000022E0002E4CF3056F58F0056F54F58416 -:102E500032C000000001902E0004872E0000000008 -:102E60000001203A0002E6002F78000000018702EE -:102E7000FF38032C0EF49316FFCCF7057A689313F2 -:102E8000FFFC9596FFB807880008E00043A09793E1 -:102E9000FFFC8596FFB820220000E6002F340000DA -:102EA0000001862E0EF80000000120320010E20022 -:102EB0002ED1F302004C872E0F00000000010738CE -:102EC0000001972E0F00872E0F00E0002F34000026 -:102ED00000019313FFFCF3067A289313FFFC76B1ED -:102EE0000002C6B4600077350004C7386A00831654 -:102EF000FFCCC7386000C738300007380010971380 -:102F0000FFFC9596FFB89616FFB407880008E0010D -:102F100026F89793FFFC8616FFB48596FFB8063017 -:102F2000000120320011E6002F3000000001F602FF -:102F30000000962E0EF8F70432C0F306E030C03AD7 -:102F40003200E6002F7800000001F704E0180000CE -:102F5000000177B8001E703EFFE1E6002F79000007 -:102F600000010F814000F70479C800000001073814 -:102F70000001F70579C8F70479C8F70471C40000A7 -:102F80000001203A0000E6002FB5F6862C28F70451 -:102F90002D380000000106380001F6052D3877397C -:102FA0000002F302000A20320044E6002FB4B33AD4 -:102FB0006802F0052D38F70471D4F68471CC073817 -:102FC0000001C03A6A00E6002FD0F70571D4F00581 -:102FD00071D4F68471D4F70471D0F00571C4C03691 -:102FE0007200470C0001F68432D000000001203648 -:102FF0000000E6003391F70571C8F70471980000EE -:103000000001203A0000E600333100000001F7041F -:1030100075EC00000001203A0000E60033300000AB -:103020000001F70475F000000001203A0000E600FE -:10303000333000000001E0003394F306319CF005CA -:103040007A889002FF38F0056F509002FF80F704F5 -:1030500032C4F3063228F30532D4F60432C8F684BB -:103060007A2CF502000007380024F7057A98203200 -:103070000000E600308DF6057A90C02A5A00E6007E -:1030800033D8C0326A00EE0033D900000001F68464 -:1030900032C0000000018736141000000001C7385C -:1030A00060009736141087361418000000010738A6 -:1030B00000019736141887361418F70432B8000048 -:1030C0000001C7386000F70532B8F70432BC0000D1 -:1030D000000107380001F70532BCF70432BC20328A -:1030E0000000E60030FD00000001F70432E0F505C5 -:1030F0007A7007380001E0003100F70532E0F5058D -:103100007A70F5846F5800000001202E0021E20043 -:103110003144F6862C28F7042D38000000010638CB -:103120000001F6052D387739000220320044E60010 -:103130003138B5BA6802F0052D38F3020022E000FC -:103140003148F3056F58F0056F54F58432C0000024 -:103150000001902E0004872E000000000001203A9C -:103160000002E6003274000000018702FF38032CE1 -:103170000EF49316FFC4F7057A689313FFFC959637 -:10318000FFB807880008E00043A09793FFFC8596EE -:10319000FFB820220000E600323000000001862E39 -:1031A0000EF80000000120320010E20031CDF302E1 -:1031B000004C872E0F000000000107380001972EF9 -:1031C0000F00872E0F00E000323000000001931343 -:1031D000FFFCF3067A289313FFFC76B10002C6B415 -:1031E000600077350004C7386A008316FFC4C7380B -:1031F0006000C7383000073800109713FFFC959621 -:10320000FFB89616FFB407880008E00126F89793E8 -:10321000FFFC8616FFB48596FFB806300001203209 -:103220000011E600322C00000001F6020000962E8C -:103230000EF8F70432C0F306E030C03A3200E60080 -:10324000327400000001F704E0180000000177B8B4 -:10325000001E703EFFE1E6003275000000010F81A4 -:103260004000F70479C80000000107380001F705A5 -:1032700079C8F70479C8F70471C400000001203A46 -:103280000000E60032B1F6862C28F7042D38000045 -:10329000000106380001F6052D3877390002F302E7 -:1032A000000A20320044E60032B0B33A6802F0056A -:1032B0002D38F70471D4F68471CC07380001C03A78 -:1032C0006A00E60032CCF70571D4F00571D4F684BB -:1032D00071D4F70471D0F00571C4C0367200470C88 -:1032E0000001F68432D00000000120360000E60024 -:1032F0003391F70571C8F704719800000001203A76 -:103300000000E600333100000001F70475EC000016 -:103310000001203A0000E600333000000001F7040D -:1033200075F000000001203A0000E600338900003B -:103330000001F58476F800000001202E0021E20053 -:10334000337CF6862C28F7042D380000000106385F -:103350000001F6052D387739000220320044E600DE -:103360003368B5BA6802F0052D38F3020022F30580 -:1033700076F8F3047700E0003380F30576FCF0057F -:1033800076FCE0003390F0057A78E0003394F306A1 -:10339000319CF3062EE0F30532D4F70471C8000027 -:1033A0000001203A0000E6003444F6862C28F70499 -:1033B0002D380000000106380001F6052D38773958 -:1033C0000002F302000920320044E6003444B33A1C -:1033D0006802E0003444F0052D38F7047A900000CC -:1033E0000001C03A6A00EE0033F9C5B40000C738E6 -:1033F0005A00E0003400F7057A90C5B80000F005E7 -:103400007A90F6847A88F7067A2876350003A73210 -:10341000700206B400019716FFEC84A6FFFCF706C5 -:103420007A2CF3047A989482FF3C9302FF409582B1 -:10343000FF44B5B27002F7047A98F6857A88C738E7 -:103440005800F7057A988796FFFC8296FFF80214D9 -:103450000000013C0000000000019293FFFC02907C -:10346000000822100020F5847A7000000001202E50 -:103470000001E600376CF5857AA0F7020001F6043A -:1034800032C8F7057A70F70432C4F68432C0F60504 -:103490007A2C9002FF809002FF38F5847A28073852 -:1034A00000249582FF3C9702FF409602FF44873636 -:1034B000141000000001C7386000973614108736DA -:1034C00014180000000107380001973614188736D9 -:1034D0001418F0056F50F70432B89596FFF4C7380A -:1034E0006000F70532B8F70432BCF4862FF80738CD -:1034F0000001F70532BCF70432BCF48532D4F7067C -:103500000C3EC07E7400E600351C00000001C07E49 -:103510007400E600350D00000001F7060C3EC77C84 -:103520007400203A0010E6003B7000000001F70430 -:1035300032E4FF820010F5846F5807380001202E16 -:103540000021E2003578F70532E4F7042D38F686DD -:103550002C2806380001F6052D3877390002203274 -:103560000044E600356CB5BA6802F0052D38F482E7 -:103570000022E000357CF4856F58F0056F54F58427 -:1035800032C000000001902E0004872E00000000D1 -:103590000001203A0002E60036A800000001870280 -:1035A000FF3804AC0EF49496FFECF7057A68949318 -:1035B000FFFC9596FFDC07880008E00043A0979386 -:1035C000FFFC8596FFDC20220000E6003664000048 -:1035D0000001862E0EF80000000120320010E200EB -:1035E0003601F482004C872E0F00000000010738DE -:1035F0000001972E0F00872E0F00E00036640000B8 -:1036000000019493FFFCF4867A289493FFFC76B132 -:103610000002C6B4600077350004C7386A0084969B -:10362000FFECC7386000C738480007380010971310 -:10363000FFFC9596FFDC9616FFD807880008E0018E -:1036400026F89793FFFC8616FFD88596FFDC063098 -:10365000000120320011E600366000000001F60291 -:103660000000962E0EF8F70432C0F486E030C03A1F -:103670004A00E60036A800000001F704E018000048 -:10368000000177B8001E703EFFE1E60036A9000099 -:1036900000010F814000F70479C8000000010738DD -:1036A0000001F70579C8F70479C8F70471C4000070 -:1036B0000001203A0000E60036E5F6862C28F704E3 -:1036C0002D380000000106380001F6052D38773945 -:1036D0000002F482000A20320044E60036E4B4BA64 -:1036E0006802F0052D38F70471D4F68471CC0738E0 -:1036F0000001C03A6A00E6003700F70571D4F00512 -:1037000071D4F68471D4F70471D0F00571C4C03659 -:103710007200470C0001F68432D000000001203610 -:103720000000E6003AC1F70571C8F704719800007F -:103730000001203A0000E6003A6100000001F704B1 -:1037400075EC00000001203A0000E6003A6000003D -:103750000001F70475F000000001203A0000E600C7 -:103760003A6000000001E0003AC4F486319CF005A4 -:103770007A889002FF38F0056F509002FF80F704BE -:1037800032C4F4863228F48532D4F60432C8F68482 -:103790007A2CF502000007380024F7057A982032C9 -:1037A0000000E60037BDF6057A90C02A5A00E60010 -:1037B0003B08C0326A00EE003B0900000001F684BD -:1037C00032C0000000018736141000000001C73825 -:1037D000600097361410873614180000000107386F -:1037E00000019736141887361418F70432B8000011 -:1037F0000001C7386000F70532B8F70432BC00009A -:10380000000107380001F70532BCF70432BC203252 -:103810000000E600382D00000001F70432E0F50555 -:103820007A7007380001E0003830F70532E0F5051E -:103830007A70F5846F5800000001202E0021E2000C -:103840003874F6862C28F7042D380000000106385D -:103850000001F6052D387739000220320044E600D9 -:103860003868B5BA6802F0052D38F4820022E0000D -:103870003878F4856F58F0056F54F58432C0000035 -:103880000001902E0004872E000000000001203A65 -:103890000002E60039A4000000018702FF3804ACF2 -:1038A0000EF49496FFE4F7057A689493FFFC9596DE -:1038B000FFDC07880008E00043A09793FFFC859693 -:1038C000FFDC20220000E600396000000001862EA7 -:1038D0000EF80000000120320010E20038FDF482F2 -:1038E000004C872E0F000000000107380001972EC2 -:1038F0000F00872E0F00E000396000000001949354 -:10390000FFFCF4867A289493FFFC76B10002C6B4DB -:10391000600077350004C7386A008496FFE4C73832 -:103920006000C7384800073800109713FFFC9596D1 -:10393000FFDC9616FFD807880008E00126F8979369 -:10394000FFFC8616FFD88596FFDC0630000120328A -:103950000011E600395C00000001F6020000962E1E -:103960000EF8F70432C0F486E030C03A4A00E600B0 -:1039700039A400000001F704E0180000000177B846 -:10398000001E703EFFE1E60039A5000000010F8136 -:103990004000F70479C80000000107380001F7056E -:1039A00079C8F70479C8F70471C400000001203A0F -:1039B0000000E60039E1F6862C28F7042D380000D7 -:1039C000000106380001F6052D3877390002F4822F -:1039D000000A20320044E60039E0B4BA6802F0057B -:1039E0002D38F70471D4F68471CC07380001C03A41 -:1039F0006A00E60039FCF70571D4F00571D4F6844D -:103A000071D4F70471D0F00571C4C0367200470C50 -:103A10000001F68432D00000000120360000E600EC -:103A20003AC1F70571C8F704719800000001203A07 -:103A30000000E6003A6100000001F70475EC0000A8 -:103A40000001203A0000E6003A6000000001F7049F -:103A500075F000000001203A0000E6003AB90000CD -:103A60000001F58476F800000001202E0021E2001C -:103A70003AACF6862C28F7042D38000000010638F1 -:103A80000001F6052D387739000220320044E600A7 -:103A90003A98B5BA6802F0052D38F4820022F48510 -:103AA00076F8F4847700E0003AB0F48576FCF0050F -:103AB00076FCE0003AC0F0057A78E0003AC4F4867B -:103AC000319CF4862EE0F48532D4F70471C80000EE -:103AD0000001203A0000E6003B70F6862C28F7042F -:103AE0002D380000000106380001F6052D38773921 -:103AF0000002F482000920320044E6003B70B4BAB0 -:103B00006802E0003B70F0052D38F7047A90000061 -:103B10000001C03A6A00EE003B29C5B40000C73876 -:103B20005A00E0003B30F7057A90C5B80000F00578 -:103B30007A90F7047A88F6867A2876390003A6B256 -:103B4000680207380001F7057A88F7047A98969694 -:103B5000FFF49682FF3CF4847A98F6867A2CC73874 -:103B600058009482FF409582FF44B5B26802F70581 -:103B70007A988796FFFC8296FFF802140000013CB9 -:103B80000000000000019293FFFC02900008221048 -:103B90000018F5047A88F7067A2CF5847A9076A9CD -:103BA0000003A6B67002202E0000E6003BCD000008 -:103BB0000001F7047AA000000001C02A7200E600AC -:103BC0003F18C02E6A00EE003F1900000001F68485 -:103BD00032C0F60432C88736141000000001C7381E -:103BE000600097361410873614180000000107385B -:103BF00000019736141887361418F70432B80000FD -:103C00000001C7386000F70532B8F70432BC000085 -:103C1000000107380001F70532BCF70432BC202E42 -:103C20000000E6003C3DF6820000F70432E0F68535 -:103C30007A7007380001E0003C40F70532E0F505F6 -:103C40007A70F5846F5800000001202E0021E200F8 -:103C50003C84F6862C28F7042D3800000001063835 -:103C60000001F6052D387739000220320044E600C5 -:103C70003C78B5BA6802F0052D38F4820022E000E5 -:103C80003C88F4856F58F0056F54F58432C000000D -:103C90000001902E0004872E000000000001203A51 -:103CA0000002E6003DB4000000018702FF3804ACCA -:103CB0000EF49496FFECF7057A689493FFFC9596C2 -:103CC000FFE407880008E00043A09793FFFC859677 -:103CD000FFE420220000E6003D7000000001862E77 -:103CE0000EF80000000120320010E2003D0DF482C9 -:103CF000004C872E0F000000000107380001972EAE -:103D00000F00872E0F00E0003D700000000194932B -:103D1000FFFCF4867A289493FFFC76B10002C6B4C7 -:103D2000600077350004C7386A008496FFECC73816 -:103D30006000C7384800073800109713FFFC9596BD -:103D4000FFE49616FFE007880008E00126F8979345 -:103D5000FFFC8616FFE08596FFE406300001203266 -:103D60000011E6003D6C00000001F6020000962EF6 -:103D70000EF8F70432C0F486E030C03A4A00E6009C -:103D80003DB400000001F704E0180000000177B81E -:103D9000001E703EFFE1E6003DB5000000010F810E -:103DA0004000F70479C80000000107380001F7055A -:103DB00079C8F70479C8F70471C400000001203AFB -:103DC0000000E6003DF1F6862C28F7042D380000AF -:103DD000000106380001F6052D3877390002F4821B -:103DE000000A20320044E6003DF0B4BA6802F00553 -:103DF0002D38F70471D4F68471CC07380001C03A2D -:103E00006A00E6003E0CF70571D4F00571D4F68423 -:103E100071D4F70471D0F00571C4C0367200470C3C -:103E20000001F68432D00000000120360000E600D8 -:103E30003ED1F70571C8F704719800000001203ADF -:103E40000000E6003E7100000001F70475EC000080 -:103E50000001203A0000E6003E7000000001F70477 -:103E600075F000000001203A0000E6003EC90000A5 -:103E70000001F58476F800000001202E0021E20008 -:103E80003EBCF6862C28F7042D38000000010638C9 -:103E90000001F6052D387739000220320044E60093 -:103EA0003EA8B5BA6802F0052D38F4820022F485E8 -:103EB00076F8F4847700E0003EC0F48576FCF005E7 -:103EC00076FCE0003ED0F0057A78E0003ED4F4863F -:103ED000319CF4862EE0F48532D4F70471C80000DA -:103EE0000001203A0000E6003F80F6862C28F70407 -:103EF0002D380000000106380001F6052D3877390D -:103F00000002F482000920320044E6003F80B4BA87 -:103F10006802E0003F80F0052D38F7047A90000039 -:103F20000001C03A6A00EE003F39C5B40000C7384E -:103F30005A00E0003F40F7057A90C5B80000F00550 -:103F40007A90F7047A88F6867A2876390003A6B242 -:103F5000680207380001F7057A88F7047A98969680 -:103F6000FFF49682FF3CF4847A98F6867A2CC73860 -:103F700058009482FF409582FF44B5B26802F7056D -:103F80007A988796FFFC8296FFF802140000013CA5 -:103F90000000000000019293FFFC02900008221034 -:103FA0000010F5846F5800000001202E0021E2006F -:103FB0003FE4F6862C28F7042D380000000106386F -:103FC0000001F6052D387739000220320044E60062 -:103FD0003FD8B5BA6802F0052D38F5020022E0009E -:103FE0003FE8F5056F58F0056F54F58432C00000C6 -:103FF0000001902E0004872E000000000001203AEE -:104000000002E6004114000000018702FF38052C81 -:104010000EF49516FFF4F7057A689513FFFC959654 -:10402000FFEC07880008E00043A09793FFFC85960B -:10403000FFEC20220000E60040D000000001862EA8 -:104040000EF80000000120320010E200406DF50281 -:10405000004C872E0F000000000107380001972E4A -:104060000F00872E0F00E00040D0000000019513E4 -:10407000FFFCF5067A289513FFFC76B10002C6B462 -:10408000600077350004C7386A008516FFF4C7382A -:104090006000C7385000073800109713FFFC959652 -:1040A000FFEC9616FFE807880008E00126F89793D2 -:1040B000FFFC8616FFE88596FFEC063000012032F3 -:1040C0000011E60040CC00000001F6020000962E30 -:1040D0000EF8F70432C0F506E030C03A5200E600B0 -:1040E000411400000001F704E0180000000177B857 -:1040F000001E703EFFE1E6004115000000010F8147 -:104100004000F70479C80000000107380001F705F6 -:1041100079C8F70479C8F70471C400000001203A97 -:104120000000E6004151F6862C28F7042D380000E7 -:10413000000106380001F6052D3877390002F50236 -:10414000000A20320044E6004150B53A6802F0050A -:104150002D38F70471D4F68471CC07380001C03AC9 -:104160006A00E600416CF70571D4F00571D4F6845D -:1041700071D4F70471D0F00571C4C0367200470CD9 -:104180000001F68432D00000000120360000E60075 -:104190004231F70571C8F704719800000001203A18 -:1041A0000000E60041D100000001F70475EC0000BA -:1041B0000001203A0000E60041D000000001F704B1 -:1041C00075F000000001203A0000E60042290000DE -:1041D0000001F58476F800000001202E0021E200A5 -:1041E000421CF6862C28F7042D3800000001063802 -:1041F0000001F6052D387739000220320044E60030 -:104200004208B5BA6802F0052D38F5020022F5051E -:1042100076F8F5047700E0004220F50576FCF0051D -:1042200076FCE0004230F0057A78E0004234F50692 -:10423000319CF5062EE0F50532D4F70471C8000074 -:104240000001203A0000E6004274F6862C28F704AC -:104250002D380000000106380001F6052D387739A9 -:104260000002F502000920320044E6004274B53A2B -:104270006802F0052D388796FFFC8296FFF802143D -:104280000000013C0000000000019293FFFC02903E -:104290000008F70632D49713FFFCF7062EE09713B9 -:1042A000FFFC07880008E00014F49793FFFCF70672 -:1042B00032D49713FFFCF7062F6C9713FFFC078887 -:1042C0000008E00014F49793FFFCF70632D497132C -:1042D000FFFCF7062FF89713FFFC07880008E000A3 -:1042E00014F49793FFFCF70632D49713FFFCF706FC -:1042F00030849713FFFC07880008E00014F49793BC -:10430000FFFCF70632D49713FFFCF7063110971322 -:10431000FFFC07880008E00014F49793FFFCF70601 -:1043200032D49713FFFCF706319C9713FFFC0788E4 -:104330000008E00014F49793FFFCF70632D49713BB -:10434000FFFCF70632289713FFFC07880008E000FF -:1043500014F49793FFFC8796FFFC8296FFF80214F3 -:104360000000013C0000000000019293FFFC02905D -:104370000008871600000000000186BA0000873A96 -:10438000000400000001C0367200440C0001879652 -:10439000FFFC8296FFF802140004013C00000000BC -:1043A00000019293FFFC0290000885960000000037 -:1043B0000001862E000086AE000420320010E200CC -:1043C00043D00000000120360010E20043ED073426 -:1043D0000001872E000C0000000107380001972E15 -:1043E000000C872E000CE0004414F4020000C03AD8 -:1043F0006200E6004411F402000020360010E600DE -:1044000044140000000120320000E60044140000C3 -:104410000001F40200018796FFFC8296FFF8021467 -:104420000004013C0000000000019293FFFC029098 -:104430000008F7020001F7053524F7046F44000077 -:104440000001F7053528F70632F49713FFFCF7064D -:1044500035309713FFFC07880008E0001548979354 -:10446000FFFCF70245049713FFFCF702000D9713BA -:10447000FFFCF70632F49713FFFC07880008E00002 -:10448000161C9793FFFCF7024A049713FFFCF702F0 -:10449000000F9713FFFCF70633809713FFFC078884 -:1044A0000008E000161C9793FFFCF7024EEC9713F0 -:1044B000FFFCF70200089713FFFCF706340C971374 -:1044C000FFFC07880008E000161C9793FFFCF7022A -:1044D00057649713FFFCF70200079713FFFCF706DA -:1044E00034989713FFFC07880008E000161C979388 -:1044F000FFFC8796FFFC8296FFF802140000013C47 -:104500000000000000019293FFFC029000082210BE -:104510000014F70475F800000001203A0000E600DE -:10452000452DF68675F8E0004544F7020000F704D3 -:1045300076040000000177390002C7386800873A26 -:10454000001800000001203A0000E600455CF70575 -:104550003548F4863380E00049F0F4853530F704BF -:104560006F5400000001203A0000E6004580F4820C -:104570000008F4820001F4856F54E0004588F702DA -:104580000001F4856F58F7020000203A0000E600B1 -:1045900045A0F4820004F486340CE00049F0F48570 -:1045A0003530F6843548F604352CF4B72800073446 -:1045B0000002F4820001F4BB28008732008CF482F0 -:1045C00000019736001887320090F4856F509736B7 -:1045D000000484B200840000000194B6001084B28C -:1045E00000880000000194B6001484B6001000009A -:1045F000000194B6000884B600140000000194B6CF -:10460000000C84B2009800000001F4853554F48257 -:1046100000019482FF80F5043554F4863498F485C3 -:1046200035309502FF3885B2000006B4002495822B -:10463000FF3C9682FF4087320004F6853550970292 -:10464000FF4486B20004F005354CF704354095165A -:10465000FFF49596FFF4C7386800F7053540F584F8 -:10466000352886B20004872E141400000001C738D4 -:104670006800972E14148732008000000001203A51 -:104680000001EE0049F0F7060C3EC07E7400E60023 -:1046900046A400000001C07E7400E60046950000BC -:1046A0000001F7060C3EC77C7400203A0010E600BB -:1046B00049F000000001FF8200108682FF38F704F5 -:1046C0003558F5846F58F685355407380001202E8B -:1046D0000021E2004708F7053558F7042D38F68623 -:1046E0002C2806380001F6052D38773900022032D3 -:1046F0000044E60046FCB5BA6802F0052D38F482A5 -:104700000022E000470CF4856F58F0056F54F684E2 -:10471000352C0000000187360094C4840000C03AA4 -:104720004A00E60047710000000186360094F684D6 -:1047300035540000000176B4FFF0F7043554969626 -:10474000FFF4473900009716FFF0C6B47000F70475 -:10475000354877B4000F703EFFE107380024E600CB -:104760004769C638600006B40001C7046E00F7331D -:104770002800F6843544000000018736000400005C -:104780000001203A000FE20047BD073800018736DC -:10479000000C00000001073800019736000C873636 -:1047A000000CE00047D000000001F7043528F68235 -:1047B000000107380008E0004968F7053544203A51 -:1047C0000010E60047CC00000001F7020000973619 -:1047D0000004F704353CF684352807380001F70556 -:1047E000353CF704353C8736141C000000010738BF -:1047F00000019736141CF704760486B6141CF604E0 -:1048000075FC07380001F684760000000001C03A0C -:104810006A00E600481CF7057604F0057604F68485 -:104820007604F7047608F00575FCC0367200470C74 -:10483000000120320000E6004881F70575F8F70412 -:104840007648F4867218C03A4A00470C0001203AB4 -:104850000000E6004881F6862C28F7042D38000079 -:10486000000106380001F6052D3877390002F48280 -:10487000000E20320044E6004880B4BA6802F00519 -:104880002D38F5020000202A0002EE004968F68269 -:104890000000F68435280000000187360000000083 -:1048A0000001203A0002E600493C05B40008959357 -:1048B000FFFC9516FFEC9596FFE89696FFE40788B7 -:1048C0000008E0005EDC9793FFFC8516FFEC859600 -:1048D000FFE88696FFE420220000E600492CF7025C -:1048E00000008636000C000000012032000FE200BC -:1048F000491100000001873600140000000107384C -:1049000000019736001487360014E000492CF702A6 -:10491000000076B10002C6B4600077350005C738E4 -:104920006A00C738600007380010C72C7000203AB2 -:104930000000E60047A8F705352CF6843528F70473 -:104940006F4C00000001C0367200E600495C07347D -:104950001494F4846F44E0004960F4853528F70529 -:104960003528E00048840528000120360000E600D4 -:1049700049A1F6862C28F7042D38000000010638DE -:104980000001F6052D3877390002F482000D20323F -:104990000044E60049A8B4BA6802E00049A8F0055E -:1049A0002D38F4820001F4853524F6843528F70487 -:1049B0006F44F48632F4C0367200E60049F0F485A4 -:1049C0003530F704E0180000000177B8001F703E92 -:1049D000FFE1E60049F1000000010F814000F7040B -:1049E00079C80000000107380001F70579C8F7040D -:1049F00079C88796FFFC8296FFF802140000013CFC -:104A00000000000000019293FFFC029000082210B9 -:104A10000014F70475F800000001203A0000E600D9 -:104A20004A2DF68675F8E0004A40F6820000F70449 -:104A300076040000000177390002C738680086BAA2 -:104A40000018F7046F5400000001203A0000E6004F -:104A50004A64F6853548F4820001F4856F54E0001D -:104A60004A70F7020001F4820008F4856F58F702DB -:104A70000000203A0000E6004A88F4820004F48630 -:104A8000340CE0004ED8F4853530F6843548F60411 -:104A9000352CF4B7280007340002F4820001F4BB7F -:104AA00028008732008CF482000197360018873284 -:104AB0000090F4856F509736000484B200840000A3 -:104AC000000194B6001084B200880000000194B682 -:104AD000001484B600100000000194B6000884B6EB -:104AE00000140000000194B6000C84B2009800008D -:104AF0000001F4853554F48200019482FF80F504AE -:104B00003554F4863498F48535309502FF3885B2F3 -:104B1000000006B400249582FF3C9682FF40873255 -:104B20000004F68535509702FF4486B20004F00574 -:104B3000354CF70435409516FFF49596FFF4C738C9 -:104B40006800F7053540F584352886B20004872EC5 -:104B5000141400000001C7386800972E141487321F -:104B6000008000000001203A0001EE004ED8F70658 -:104B70000C3EC07E7400E6004B8C00000001C07E3D -:104B80007400E6004B7D00000001F7060C3EC77C78 -:104B90007400203A0010E6004ED800000001FF82A9 -:104BA00000108682FF38F7043558F5846F58F68573 -:104BB000355407380001202E0021E2004BF0F705A4 -:104BC0003558F7042D38F6862C2806380001F605EE -:104BD0002D387739000220320044E6004BE4B5BAA4 -:104BE0006802F0052D38F4820022E0004BF4F485D1 -:104BF0006F58F0056F54F684352C0000000187369D -:104C00000094C4840000C03A4A00E6004C590000F9 -:104C1000000186360094F68435540000000176B415 -:104C2000FFF0F70435549696FFF4473900009716C5 -:104C3000FFF0C6B47000F704354877B4000F703E3B -:104C4000FFE107380024E6004C51C638600006B486 -:104C50000001C7046E00F7332800F68435440000D5 -:104C600000018736000400000001203A000FE20036 -:104C70004CA5073800018736000C000000010738FA -:104C800000019736000C8736000CE0004CB800009D -:104C90000001F7043528F682000107380008E0001B -:104CA0004E50F7053544203A0010E6004CB40000A1 -:104CB0000001F702000097360004F704353CF68443 -:104CC000352807380001F705353CF704353C8736B1 -:104CD000141C00000001073800019736141CF7046B -:104CE000760486B6141CF60475FC07380001F684B9 -:104CF000760000000001C03A6A00E6004D04F705A6 -:104D00007604F0057604F6847604F7047608F00558 -:104D100075FCC0367200470C000120320000E6002E -:104D20004D69F70575F8F7047648F4867218C03AAD -:104D30004A00470C0001203A0000E6004D69F68663 -:104D40002C28F7042D380000000106380001F60574 -:104D50002D3877390002F482000E20320044E6003C -:104D60004D68B4BA6802F0052D38F5020000202A1B -:104D70000002EE004E50F6820000F6843528000056 -:104D800000018736000000000001203A0002E60022 -:104D90004E2405B400089593FFFC9516FFEC9596FC -:104DA000FFE89696FFE407880008E0005EDC979332 -:104DB000FFFC8516FFEC8596FFE88696FFE420222F -:104DC0000000E6004E14F70200008636000C0000DA -:104DD00000012032000FE2004DF90000000187368B -:104DE00000140000000107380001973600148736D0 -:104DF0000014E0004E14F702000076B10002C6B4C1 -:104E0000600077350005C7386A00C738600007388A -:104E10000010C72C7000203A0000E6004C90F70507 -:104E2000352CF6843528F7046F4C00000001C0369D -:104E30007200E6004E4407341494F4846F44E0009A -:104E40004E48F4853528F7053528E0004D6C0528D7 -:104E5000000120360000E6004E89F6862C28F70473 -:104E60002D380000000106380001F6052D3877398D -:104E70000002F482000D20320044E6004E90B4BAE5 -:104E80006802E0004E90F0052D38F4820001F485B0 -:104E90003524F6843528F7046F44F48632F4C0369E -:104EA0007200E6004ED8F4853530F704E0180000B3 -:104EB000000177B8001F703EFFE1E6004ED9000008 -:104EC00000010F814000F70479C800000001073895 -:104ED0000001F70579C8F70479C88796FFFC829628 -:104EE000FFF802140000013C000000000001929352 -:104EF000FFFC0290000822100014F6843548F604E6 -:104F0000352CF4820004F4B7280007340002F48240 -:104F10000001F4BB28008732008CF4820001973630 -:104F2000001887320090F4856F509736000484B2E1 -:104F300000840000000194B6001084B200880000D4 -:104F4000000194B6001484B600100000000194B66D -:104F5000000884B600140000000194B6000C84B26E -:104F6000009800000001F4853554F4820001948219 -:104F7000FF80F5043554F4863498F4853530950275 -:104F8000FF3885B2000006B400249582FF3C96826B -:104F9000FF4087320004F68535509702FF4486B201 -:104FA0000004F005354CF70435409516FFF495964E -:104FB000FFF4C7386800F7053540F584352886B218 -:104FC0000004872E141400000001C7386800972ED3 -:104FD00014148732008000000001203A0001EE0026 -:104FE000534CF7060C3EC07E7400E60050000000F3 -:104FF0000001C07E7400E6004FF100000001F706DA -:105000000C3EC77C7400203A0010E600534C0000B0 -:105010000001FF8200108682FF38F7043558F584BE -:105020006F58F685355407380001202E0021E20024 -:105030005064F7053558F7042D38F6862C280638C5 -:105040000001F6052D387739000220320044E600D1 -:105050005058B5BA6802F0052D38F4820022E000FD -:105060005068F4856F58F0056F54F684352C0000B5 -:10507000000187360094C4840000C03A4A00E6006C -:1050800050CD0000000186360094F68435540000AF -:10509000000176B4FFF0F70435549696FFF44739D3 -:1050A00000009716FFF0C6B47000F704354877B4D7 -:1050B000000F703EFFE107380024E60050C5C638F7 -:1050C000600006B40001C7046E00F7332800F684C0 -:1050D0003544000000018736000400000001203A3A -:1050E000000FE2005119073800018736000C00005C -:1050F0000001073800019736000C8736000CE000ED -:10510000512C00000001F7043528F6820001073811 -:105110000008E00052C4F7053544203A0010E600CC -:10512000512800000001F702000097360004F70440 -:10513000353CF684352807380001F705353CF7047F -:10514000353C8736141C00000001073800019736F3 -:10515000141CF704760486B6141CF60475FC073894 -:105160000001F684760000000001C03A6A00E60003 -:105170005178F7057604F0057604F6847604F70492 -:105180007608F00575FCC0367200470C000120322D -:105190000000E60051DDF70575F8F7047648F4865F -:1051A0007218C03A4A00470C0001203A0000E6009D -:1051B00051DDF6862C28F7042D3800000001063852 -:1051C0000001F6052D3877390002F482000E2032F6 -:1051D0000044E60051DCB4BA6802F0052D38F5024F -:1051E0000000202A0002EE0052C4F6820000F6847D -:1051F0003528000000018736000000000001203A39 -:105200000002E600529805B400089593FFFC95163D -:10521000FFEC9596FFE89696FFE407880008E0000B -:105220005EDC9793FFFC8516FFEC8596FFE886967B -:10523000FFE420220000E6005288F70200008636D4 -:10524000000C000000012032000FE200526D00004F -:10525000000187360014000000010738000197366E -:10526000001487360014E0005288F702000076B17F -:105270000002C6B4600077350005C7386A00C73839 -:10528000600007380010C72C7000203A0000E600CC -:105290005104F705352CF6843528F7046F4C0000CF -:1052A0000001C0367200E60052B807341494F4844A -:1052B0006F44E00052BCF4853528F7053528E0003E -:1052C00051E00528000120360000E60052FDF68678 -:1052D0002C28F7042D380000000106380001F605DF -:1052E0002D3877390002F482000D20320044E600A8 -:1052F0005304B4BA6802E0005304F0052D38F48278 -:105300000001F4853524F6843528F7046F44F486CB -:1053100032F4C0367200E600534CF4853530F704A1 -:10532000E0180000000177B8001F703EFFE1E600C2 -:10533000534D000000010F814000F70479C80000C0 -:10534000000107380001F70579C8F70479C8879686 -:10535000FFFC8296FFF802140000013C00000000F0 -:1053600000019293FFFC0290000822100014F484C4 -:105370003554F684354CF584352C9482FF3876B557 -:105380000003A52E6802000000019502FF3CF38493 -:105390003550C6AC68009382FF4087360004000099 -:1053A00000019702FF4486360004F70435400000F0 -:1053B0000001C7386000F7053540F604352886B689 -:1053C0000004873214149496FFF4C73868009732AB -:1053D0001414872E008000000001203A0001EE0026 -:1053E00057509516FFF4F7060C3EC07E7400E60099 -:1053F000540400000001C07E7400E60053F5000074 -:105400000001F7060C3EC77C7400203A0010E6004D -:10541000575000000001FF8200108682FF38F70419 -:105420003558F5846F58F685355407380001202E1D -:105430000021E2005468F7053558F7042D38F68648 -:105440002C2806380001F6052D3877390002203265 -:105450000044E600545CB5BA6802F0052D38F382CA -:105460000022E000546CF3856F58F0056F54F68409 -:10547000352C0000000187360094C3840000C03A38 -:105480003A00E60054D10000000186360094F6840C -:1054900035540000000176B4FFF0F70435549696B9 -:1054A000FFF4473900009716FFF0C6B47000F70408 -:1054B000354877B4000F703EFFE107380024E6005E -:1054C00054C9C638600006B40001C7046E00F73343 -:1054D0002800F684354400000001873600040000EF -:1054E0000001203A000FE200551D07380001873601 -:1054F000000C00000001073800019736000C8736C9 -:10550000000CE000553000000001F7043528F68259 -:10551000000107380008E00056C8F7053544203A76 -:105520000010E600552C00000001F702000097363D -:105530000004F704353CF684352807380001F705E8 -:10554000353CF704353C8736141C00000001073851 -:1055500000019736141CF704760486B6141CF60472 -:1055600075FC07380001F684760000000001C03A9F -:105570006A00E600557CF7057604F0057604F684AB -:105580007604F7047608F00575FCC0367200470C07 -:10559000000120320000E60055E1F70575F8F70438 -:1055A0007648F3867218C03A3A00470C0001203A58 -:1055B0000000E60055E1F6862C28F7042D3800009F -:1055C000000106380001F6052D3877390002F38214 -:1055D000000E20320044E60055E0B3BA6802F00540 -:1055E0002D38F5020000202A0002EE0056C8F6828F -:1055F0000000F68435280000000187360000000016 -:105600000001203A0002E600569C05B4000895937C -:10561000FFFC9516FFEC9596FFE89696FFE4078849 -:105620000008E0005EDC9793FFFC8516FFEC859692 -:10563000FFE88696FFE420220000E600568CF70281 -:1056400000008636000C000000012032000FE2004E -:105650005671000000018736001400000001073871 -:1056600000019736001487360014E000568CF702CC -:10567000000076B10002C6B4600077350005C73877 -:105680006A00C738600007380010C72C7000203A45 -:105690000000E6005508F705352CF6843528F70498 -:1056A0006F4C00000001C0367200E60056BC0734A3 -:1056B0001494F3846F44E00056C0F3853528F70551 -:1056C0003528E00055E40528000120360000E600FA -:1056D0005701F6862C28F7042D3800000001063803 -:1056E0000001F6052D3877390002F382000D2032D3 -:1056F0000044E6005708B3BA6802E0005708F00516 -:105700002D38F3820001F3853524F6843528F7041B -:105710006F44F38632F4C0367200E6005750F385CA -:105720003530F704E0180000000177B8001F703E24 -:10573000FFE1E6005751000000010F814000F7042F -:1057400079C80000000107380001F70579C8F7049F -:1057500079C88796FFFC8296FFF802140000013C8E -:105760000000000000019293FFFC0290000822104C -:1057700000148702FF38F384352CF7053554871E53 -:105780000080F504354C27380001C02A7200E6007D -:105790005A4C00000001F5846F5800000001202ED3 -:1057A0000021E20057D8F6862C28F7042D38000097 -:1057B000000106380001F6052D3877390002203245 -:1057C0000044E60057CCB5BA6802F0052D38F30264 -:1057D0000022E00057DCF3056F58F0056F54F684A3 -:1057E000352C0000000187360094C3040000C03A45 -:1057F0003200E60058410000000186360094F6842D -:1058000035540000000176B4FFF0F7043554969645 -:10581000FFF4473900009716FFF0C6B47000F70494 -:10582000354877B4000F703EFFE107380024E600EA -:105830005839C638600006B40001C7046E00F7335B -:105840002800F6843544000000018736000400007B -:105850000001203A000FE200588D0738000187361A -:10586000000C00000001073800019736000C873655 -:10587000000CE00058A000000001F7043528F68273 -:10588000000107380008E0005A38F7053544203A8F -:105890000010E600589C00000001F7020000973657 -:1058A0000004F704353CF684352807380001F70575 -:1058B000353CF704353C8736141C000000010738DE -:1058C00000019736141CF704760486B6141CF604FF -:1058D00075FC07380001F684760000000001C03A2C -:1058E0006A00E60058ECF7057604F0057604F684C5 -:1058F0007604F7047608F00575FCC0367200470C94 -:10590000000120320000E6005951F70575F8F70450 -:105910007648F3067218C03A3200470C0001203A6C -:105920000000E6005951F6862C28F7042D380000B7 -:10593000000106380001F6052D3877390002F30220 -:10594000000E20320044E6005950B33A6802F005D8 -:105950002D38F5020000202A0002EE005A38F682A7 -:105960000000F684352800000001873600000000A2 -:105970000001203A0002E6005A0C05B40008959395 -:10598000FFFC9516FFEC9596FFE89696FFE40788D6 -:105990000008E0005EDC9793FFFC8516FFEC85961F -:1059A000FFE88696FFE420220000E60059FCF7029B -:1059B00000008636000C000000012032000FE200DB -:1059C00059E100000001873600140000000107388B -:1059D00000019736001487360014E00059FCF702E6 -:1059E000000076B10002C6B4600077350005C73804 -:1059F0006A00C738600007380010C72C7000203AD2 -:105A00000000E6005878F705352CF6843528F704B1 -:105A10006F4C00000001C0367200E6005A2C0734BB -:105A20001494F3046F44E0005A30F3053528F70569 -:105A30003528E00059540528000120360000E60012 -:105A40005DC4F3020001E0005DF000000001772971 -:105A50000003C71C7000873A00040528000176A9DE -:105A60000003F4843554F60435509482FF38A41EA4 -:105A70006802C63070009402FF3C9602FF40C69C4C -:105A8000680087360004000000019702FF4485B6D5 -:105A90000004F704354000000001C7385800F7053E -:105AA000354085B60004F505354CF6843528F605F5 -:105AB0003550873614149496FFF4C738580097363B -:105AC0001414871E008000000001203A0001EE003F -:105AD0005E3C9416FFF4F7060C3EC07E7400E600B0 -:105AE0005AF400000001C07E7400E6005AE5000090 -:105AF0000001F7060C3EC77C7400203A0010E60057 -:105B00005E3C00000001FF8200108682FF38F7042F -:105B10003558F5846F58F685355407380001202E26 -:105B20000021E2005B58F7053558F7042D38F6865A -:105B30002C2806380001F6052D387739000220326E -:105B40000044E6005B4CB5BA6802F0052D38F3025C -:105B50000022E0005B5CF3056F58F0056F54F6849B -:105B6000352C0000000187360094C3040000C03AC1 -:105B70003200E6005BC10000000186360094F68426 -:105B800035540000000176B4FFF0F70435549696C2 -:105B9000FFF4473900009716FFF0C6B47000F70411 -:105BA000354877B4000F703EFFE107380024E60067 -:105BB0005BB9C638600006B40001C7046E00F73355 -:105BC0002800F684354400000001873600040000F8 -:105BD0000001203A000FE2005C0D07380001873613 -:105BE000000C00000001073800019736000C8736D2 -:105BF000000CE0005C2000000001F7043528F6826C -:105C0000000107380008E0005DB8F7053544203A88 -:105C10000010E6005C1C00000001F702000097364F -:105C20000004F704353CF684352807380001F705F1 -:105C3000353CF704353C8736141C0000000107385A -:105C400000019736141CF704760486B6141CF6047B -:105C500075FC07380001F684760000000001C03AA8 -:105C60006A00E6005C6CF7057604F0057604F684BD -:105C70007604F7047608F00575FCC0367200470C10 -:105C8000000120320000E6005CD1F70575F8F7044A -:105C90007648F3067218C03A3200470C0001203AE9 -:105CA0000000E6005CD1F6862C28F7042D380000B1 -:105CB000000106380001F6052D3877390002F3029D -:105CC000000E20320044E6005CD0B33A6802F005D2 -:105CD0002D38F5020000202A0002EE005DB8F682A1 -:105CE0000000F6843528000000018736000000001F -:105CF0000001203A0002E6005D8C05B4000895938F -:105D0000FFFC9516FFEC9596FFE89696FFE4078852 -:105D10000008E0005EDC9793FFFC8516FFEC85969B -:105D2000FFE88696FFE420220000E6005D7CF70293 -:105D300000008636000C000000012032000FE20057 -:105D40005D61000000018736001400000001073883 -:105D500000019736001487360014E0005D7CF702DE -:105D6000000076B10002C6B4600077350005C73880 -:105D70006A00C738600007380010C72C7000203A4E -:105D80000000E6005BF8F705352CF6843528F704AB -:105D90006F4C00000001C0367200E6005DAC0734B5 -:105DA0001494F3046F44E0005DB0F3053528F70563 -:105DB0003528E0005CD40528000120360000E6000C -:105DC0005DF1F3020001F7042D38F6862C28063821 -:105DD0000001F6052D3877390002F302000D20325C -:105DE0000044E6005DF4B33A6802E0005DF4F005BB -:105DF0002D38F3053524F6843528F7046F44F3066F -:105E000032F4C0367200E6005E3CF3053530F7042C -:105E1000E0180000000177B8001F703EFFE1E600C7 -:105E20005E3D000000010F814000F70479C80000CA -:105E3000000107380001F70579C8F70479C887968B -:105E4000FFFC8296FFF802140000013C00000000F5 -:105E500000019293FFFC02900008F706353097137B -:105E6000FFFCF70632F49713FFFC07880008E000F8 -:105E700014F49793FFFCF70635309713FFFCF706F1 -:105E800033809713FFFC07880008E00014F4979311 -:105E9000FFFCF70635309713FFFCF706340C971319 -:105EA000FFFC07880008E00014F49793FFFCF70656 -:105EB00035309713FFFCF70634989713FFFC0788DB -:105EC0000008E00014F49793FFFC8796FFFC82968D -:105ED000FFF802140000013C000000000001929352 -:105EE000FFFC0290000886160000000000018732C7 -:105EF000000400000001203A000F86B20000C538FF -:105F00000000EE005F2CC5B400002036000FEE004C -:105F10005F2C00000001203A0000EC005F2D000023 -:105F2000000120360000EC005F48000000018732CD -:105F3000000C00000001073800019732000C873286 -:105F4000000CE0005F50F4020000C02A5A00440C2C -:105F500000018796FFFC8296FFF802140004013CC2 -:105F6000000000000001000000009293FFFC02907E -:105F70000008F68635609693FFFCF68642309693CD -:105F8000FFFC07880008E00015489793FFFCF682A5 -:105F900066F89693FFFCF78200179793FFFCF6864E -:105FA00035609693FFFC07880008E000161C979365 -:105FB000FFFCF68269809693FFFCF78200189793A6 -:105FC000FFFCF68635609693FFFC07880008E0002A -:105FD000161C9793FFFCF6826B509693FFFCF7829A -:105FE00000169793FFFCF68635609693FFFC0788B2 -:105FF0000008E000161C9793FFFCF68261789693E8 -:10600000FFFCF782001F9793FFFCF686356096939E -:10601000FFFC07880008E000161C9793FFFCF6823F -:10602000627C9693FFFCF78200209793FFFCF68634 -:1060300035609693FFFC07880008E000161C9793D4 -:10604000FFFCF68266F89693FFFCF78200179793A1 -:10605000FFFCF68635EC9693FFFC07880008E0000D -:10606000161C9793FFFCF68269809693FFFCF782DB -:1060700000189793FFFCF68635EC9693FFFC078893 -:106080000008E000161C9793FFFCF6826B50969375 -:10609000FFFCF78200169793FFFCF68635EC96938B -:1060A000FFFC07880008E000161C9793FFFCF682AF -:1060B00061789693FFFCF782001F9793FFFCF686AA -:1060C00035EC9693FFFC07880008E000161C9793B8 -:1060D000FFFCF682627C9693FFFCF7820020979388 -:1060E000FFFCF68635EC9693FFFC07880008E0007D -:1060F000161C9793FFFCF704E02800000001203AEB -:106100000000E600611500000001F704E028E0004F -:10611000611877390002F70200F0F7054228F70608 -:10612000408AF03B2800F706408CF03B2800F7023D -:106130000000F7057AC0F7057AB8F7057AB0F705D9 -:106140007AC8F682C3509693FFFCF68200169693A7 -:10615000FFFCF68642309693FFFC07880008E001BA -:106160001EC09793FFFC8796FFFC8296FFF80214EF -:106170000000013C0000000000019293FFFC02902F -:106180000008F6046F340000000120320000E60031 -:1061900061ED76B1001E8732000076B4FFE5C738A6 -:1061A0006FC07739FFF0203A0007E60061EC06B0D7 -:1061B00000028736000076B5001E76B4FFE5C738CA -:1061C0006FC07739FFF0203A0001E60061ECF50678 -:1061D00035ECF704423000000001C03A5200470C91 -:1061E0000001203A0000E6006211F5820000F70489 -:1061F00042A0F60642A276B1001E76B4FFE5C7388B -:106200006FC07739FFF007380001E0006268F733AC -:1062100028008732000400000001F705E00086B284 -:106220000008203A0000E600623CF685E0042036D3 -:106230000000E6006240202E0000F5820001202EC2 -:106240000000E6006265F60642A2F70442A076B1BD -:10625000001E76B4FFE5C7386FC07739FFF0073806 -:106260000001F7332800F00542288796FFFC82964C -:10627000FFF802140000013C0000000000019293AE -:10628000FFFC02900008F704423CF6846F340738A4 -:10629000000120360000E60062B1F705423C873677 -:1062A0000000F59E0002C03A5A00E60062BDF58685 -:1062B00035ECF70442A0E00062DCF60642A2F704E7 -:1062C000423000000001C03A5A00470C0001203A59 -:1062D0000000E60062F9F60642A4F70442A476B193 -:1062E000001E76B4FFE5C7386FC07739FFF0073876 -:1062F0000001E000630CF73328009693FFFC078849 -:106300000008E00063209793FFFCF0054228879681 -:10631000FFFC8296FFF802140000013C0000000020 -:1063200000019293FFFC02900008221000208316C7 -:10633000000000000001871A001800000001203A48 -:106340000000E600636CF7020000839A001C000066 -:106350000001F3857AC0849A0014F7057AC8F485A1 -:106360007AB0F7057AB88316000000000001869A1B -:106370000014F7047AB000000001C0367200E60095 -:1063800063D0F6020000869A001CF7047AC0000071 -:106390000001C0367200E60063D000000001869A5A -:1063A0000018F7047AB800000001C0367200E60059 -:1063B00063D000000001869A0020F7047AC800002C -:1063C0000001C7386800203A0064EE0063D920322B -:1063D0000000F602000120320000E60064580000D0 -:1063E00000018396000000000001871E00180000D5 -:1063F0000001203A0000E600643CF7020000F705C7 -:106400004080F7054084F6846E50F482FFFF831EBF -:10641000000CF4854F5493360010839E0010849630 -:10642000000093B6001484A600080000000194B692 -:106430001DDCF6820064F6854A98F7054A9C8316AF -:10644000000000000001871A002000000001203A2F -:106450000000EE00647CF3820000F70442A4F6061C -:1064600042A676B1001E76B4FFE5C7386FC0773913 -:10647000FFF007380001E00066E4F7332800939648 -:10648000FFF484160000F48642C89496FFECF302F1 -:10649000000C9316FFE4839600008496FFF4871E99 -:1064A000002000000001C0267200EC006648F38660 -:1064B0004A9884A200248316FFE4C5040000B49A1D -:1064C0003802C7183800832200288396FFF4849688 -:1064D000FFE4933A000493BA0008F604E000F306E0 -:1064E0004A98A6A63002F5820000C0326A00E60093 -:1064F0006510C6380000F684E0048732000400000E -:106500000001C0367200E6006514202E0000F582FE -:106510000001202E0000E600652100000001F502C8 -:106520000000F684E0008732000000000001C03661 -:106530007200E200655CF5820000C0367200E60081 -:106540006564202E0000F684E00487320004000019 -:106550000001C0367200E2006565202E0000F58261 -:106560000001202E0000E6006575202A0000F502DB -:106570000001202A0000E6006588000000018396E3 -:10658000FFF400000001F3854F548722002C76A110 -:10659000001E76B4FFE505A0002E762D001E763095 -:1065A000FFE5F48200009496FFDC8316FFEC2026C2 -:1065B0000007C7386FC07738FFF0F71B2800872E19 -:1065C000000006980002C73867C07738FFF0E20085 -:1065D000661CF73728008516FFEC8596FFDC000067 -:1065E0000001C72C400086BA0030062800040528A8 -:1065F000000205AC00028396FFDC7739001E773875 -:10660000FFE5039C00019396FFDC201E0007C6B443 -:1066100077C076B4FFF0E20065E1F6B3280004200D -:10662000001C8496FFEC8316FFE48396FFF404A419 -:1066300000149496FFEC0318000C9316FFE4039CDF -:106640000001E00064949396FFF48496000000003B -:1066500000018726002000000001F7054A9C85A65E -:106660000020F7047AB80000000107380001F705A0 -:106670007AB8F7047AB8F6847AC886260018C6B4C1 -:1066800058008726001C0000000127380001C03296 -:106690007200470C0001203A0000E60066E5F6852E -:1066A0007AC883260008F7046E50F3053B6483A67E -:1066B0000008F682000093BA1DDC84A6000C831645 -:1066C000000094BA0010831A0010F6857AC8933A35 -:1066D0000014F7020001F7054084F6857AC0F685BC -:1066E0007AB8F6857AB08796FFFC8296FFF8021496 -:1066F0000004013C0000000000019293FFFC0290A6 -:10670000000822100008F3846F3400000001871E87 -:106710000018F684E01C00000001C0367200EC0096 -:106720006729F7020001F7020000203A0000E600A6 -:1067300067E8F5820001F704E01C869E001800005F -:106740000001C03A6A00470C0001203A0000E60050 -:1067500067E9C5840000869E0010F704E000F60299 -:106760000000C0367200E6006788051C0010869E97 -:106770000014F704E00400000001C0367200E600D7 -:10678000678C20320000F602000120320000E60093 -:10679000679900000001F582000086AA0000F70456 -:1067A000E00000000001C0367200E20067D4F6028B -:1067B0000000C0367200E60067DC2032000086AAC6 -:1067C0000004F704E00400000001C0367200E2009B -:1067D00067DD20320000F602000120320000E600F2 -:1067E00067ED202E0000F5820001202E0000E6005B -:1067F0006810F606429CF704429C76B1001E76B4FF -:10680000FFE5C7386FC07739FFF007380001F7336D -:106810002800F70475F475ACFFE1203A0000E600AB -:1068200068459596FFF4F7044298F606429876B1CB -:10683000001E76B4FFE5C7386FC07739FFF0073820 -:106840000001F7332800871E0020041C002076A1D9 -:10685000001E76B4FFE5C7386FC07739FFF0203AE5 -:106860000008EE0068C4F3061554F5020000059C0C -:106870000022C4AC0000F60200018722000076A1CD -:10688000001E76B4FFE5C7386FC07739FFF0C02A25 -:106890007200EC0068C0C6A46000A726600276B54E -:1068A000001E76B4FFE505280001C7386FC07739B0 -:1068B000FFE8F72F680005AC0001E00068780630BB -:1068C0000002F30615549313FFFCF704E0240000C4 -:1068D00000019713FFFCF704E01C00000001971370 -:1068E000FFFCF306E0009313FFFC9393FFFCF3021D -:1068F00000019313FFFC07880008E000EE64979303 -:10690000FFFC20220000E6006928F606429EF704FC -:10691000429C76B1001E76B4FFE5C7386FC0773968 -:10692000FFF007380001F73328008316FFF400005A -:106930000001201A0000E600696CF30635ECF7044C -:10694000423000000001C03A3200470C0001203AFA -:106950000000E600696DF0054228F3063560F30596 -:10696000423007880008E000789C9793FFFC8796E8 -:10697000FFFC8296FFF802140000013C00000000BA -:1069800000019293FFFC0290000822100004F5041D -:106990006F34F7044240862A001807380001F68455 -:1069A000E01CF7054240C0366200EC0069B5F70212 -:1069B0000001F7020000203A0000E6006A80F702BA -:1069C0000001F704E01C86AA001800000001C03A8C -:1069D0006A00470C0001203A0000E6006A7DC58489 -:1069E000000086AA0010F704E000F6020000C0369E -:1069F0007200E6006A1404A8001086AA0014F704C6 -:106A0000E00400000001C0367200E6006A1820327F -:106A10000000F602000120320000E6006A250000B6 -:106A20000001F582000086A60000F704E0000000E7 -:106A30000001C0367200E2006A60F6020000C03653 -:106A40007200E6006A682032000086A60004F7049F -:106A5000E00400000001C0367200E2006A692032E2 -:106A60000000F602000120320000E6006A81C72C17 -:106A70000000F5820001E0006A80C72C0000C70416 -:106A80000000203A0000EE006B3DF686408AF704D5 -:106A9000408876B5001E76B4FFE5C7386FC07738FA -:106AA000FFF0203A0000E6006B3CF6820000F6851D -:106AB0004080F68540849693FFFC9693FFFCF70494 -:106AC000E01C000000019713FFFCF386E0009393A5 -:106AD000FFFC9513FFFCF38200029393FFFC969654 -:106AE000FFF407880008E000EE649793FFFCF405CC -:106AF00040848696FFF4F7046E50F38635ECF685F5 -:106B00004090F6854094873A1DDCF6854228F705CB -:106B10003B64F7044230F4054080C03A3A00470C29 -:106B20000001203A0000E6006B3DF3863560F385F6 -:106B3000423007880008E000789C9793FFFC879616 -:106B4000FFFC8296FFF802140000013C00000000E8 -:106B500000019293FFFC02900008F4864230949367 -:106B6000FFFC07880008E00120E49793FFFC202247 -:106B70000000E6006DD9F5820000F704408CF606AF -:106B8000408C7631001EF68442287630FFE506B44C -:106B90000001C73867C07738FFF0203A0000E600F0 -:106BA0006BC8F6854228F7044088F686408A76B599 -:106BB000001E76B4FFE5C7386FC07738FFF0203A83 -:106BC0000000E6006D0D00000001F704408CF68621 -:106BD000408C76B5001E76B4FFE5C7386FC07738B5 -:106BE000FFF0203A0000E6006C35F606408AF70414 -:106BF000408876B1001E76B4FFE5C7386FC077389D -:106C0000FFF0203A0000E6006C34F4863678F70492 -:106C1000424400000001C03A4A00470C0001203AFB -:106C20000000E6006C35F4820001F4B32800E000B7 -:106C30006D10F005422CF704408CF506408C76A9C7 -:106C4000001E76B4FFE5C7386FC07738FFF0203AF2 -:106C50000000E6006CC1F606408AF704408876B171 -:106C6000001E76B4FFE5C7386FC07738FFF0203AD2 -:106C70000000E6006CC100000001F704422C000097 -:106C8000000107380001203A0009EE006D11F705F8 -:106C9000422CF02B2800F0332800F5820001F70485 -:106CA0004294F606429476B1001E76B4FFE5C738EA -:106CB0006FC07739FFF007380001E0006D10F7333F -:106CC0002800F704408CF686408C76B5001E76B41A -:106CD000FFE5C7386FC07738FFF0203A0000E600C4 -:106CE0006D14202E0000F7044088F606408A76B125 -:106CF000001E76B4FFE5C7386FC07738FFF0203A42 -:106D00000000E6006D15202E0000F0332800F5820B -:106D10000001202E0000E6006DB5F48635ECF70486 -:106D2000423000000001C03A4A00470C0001203AFE -:106D30000000E6006D5900000001F704E0280000A3 -:106D40000001203A0000E6006D79F682003CF684EE -:106D5000E028E0006D7800000001F704E028000062 -:106D60000001203A0000E6006D79F68200F0F70499 -:106D7000E0280000000176B90002F7044228000074 -:106D80000001C03A6A00EC006DB5F6862C28F704C5 -:106D90002D38F005422806380001F6052D387739E0 -:106DA0000002F482001920320044E6006DB4B4BA47 -:106DB0006802F0052D38F482C3509493FFFCF482EE -:106DC00000169493FFFCF48642309493FFFC0788EE -:106DD0000008E0011EC09793FFFC8796FFFC829697 -:106DE000FFF802140000013C000000000001929333 -:106DF000FFFC0290000822100004F5863678959377 -:106E0000FFFCF58642449593FFFC07880008E000EC -:106E100015489793FFFCF58274189593FFFCF58253 -:106E200000199593FFFCF58636789593FFFC07884B -:106E30000008E000161C9793FFFCF58274AC959354 -:106E4000FFFCF782001D9793FFFCF58637049593AE -:106E5000FFFC07880008E000161C9793FFFCF582F2 -:106E600078009593FFFCF782001B9793FFFCF58653 -:106E700037049593FFFC07880008E000161C9793E1 -:106E8000FFFCF58278FC9593FFFCF782001A97933C -:106E9000FFFCF58637909593FFFC07880008E0001B -:106EA000161C9793FFFCF58280D89593FFFCF78220 -:106EB000001B9793FFFCF58637909593FFFC07889E -:106EC0000008E000161C9793FFFCF58281749593EF -:106ED000FFFCF782001D9793FFFCF586381C959305 -:106EE000FFFC07880008E000161C9793FFFCF58262 -:106EF00087749593FFFCF782001B9793FFFCF58640 -:106F0000381C9593FFFC07880008E000161C979337 -:106F1000FFFCF58294F89593FFFCF782001B979392 -:106F2000FFFCF58639349593FFFC07880008E000E4 -:106F3000161C9793FFFCF5828A009593FFFCF7825D -:106F4000001C9793FFFCF58639349593FFFC078866 -:106F50000008E000161C9793FFFCF5828E089593BD -:106F6000FFFCF782001A9793FFFCF586393495935E -:106F7000FFFC07880008E000161C9793FFFCF582D1 -:106F8000969C9593FFFCF782001E9793FFFCF58675 -:106F900038A89593FFFC07880008E000161C97931B -:106FA000FFFCF5829B2C9593FFFCF782001B9793C7 -:106FB000FFFCF58638A89593FFFC07880008E000E1 -:106FC000161C9793FFFCF582A2DC9593FFFCF782D9 -:106FD000001E9793FFFCF5863AD89593FFFC07882F -:106FE0000008E000161C9793FFFCF5829E549593D1 -:106FF000FFFCF782001B9793FFFCF5863AD8959328 -:10700000FFFC07880008E000161C9793FFFCF58240 -:10701000A3C09593FFFCF782001C9793FFFCF586B5 -:1070200039C09593FFFC07880008E000161C979371 -:10703000FFFCF582A7649593FFFCF782001E9793EF -:10704000FFFCF58639C09593FFFC07880008E00037 -:10705000161C9793FFFCF582AA049593FFFCF78218 -:10706000001B9793FFFCF58639C09593FFFC0788BA -:107070000008E000161C9793FFFCF582AEF895938C -:10708000FFFCF782001C9793FFFCF5863A4C959322 -:10709000FFFC07880008E000161C9793FFFCF7062A -:1070A0004250F03B2800F7064088F03B2800F602EB -:1070B0000000F6054080F6054084F7063B70F63B7D -:1070C0002800F7063B72F0BB2800F582CA20F58540 -:1070D0003B74F7063B78F03B2800F7063B7AF0BBA1 -:1070E0002800F582B194F5853B7CF7063B80F03BA8 -:1070F0002800F7063B82F0BB2800F582C754F585CF -:107100003B84F7063B88F03B2800F7063B8AF0BB40 -:107110002800F582BEF8F5853B8CF7063B90F03BE6 -:107120002800F7063B92F0BB2800F582C8F8F585E9 -:107130003B94F7063B98F03B2800F7063B9AF0BBE0 -:107140002800F582C5D8F5853B9CF7063BA0F03BAF -:107150002800F7063BA2F0BB2800F582C770F58532 -:107160003BA4F7063BA8F03B2800F7063BAAF0BB80 -:107170002800F582C1B4F5853BAC9616FFF407886C -:107180000008E000D5409793FFFCF6846E50861609 -:10719000FFF40000000196361DDCF6053B6487967F -:1071A000FFFC8296FFF802140000013C0000000082 -:1071B00000019293FFFC02900008221000302594F9 -:1071C0000020F02F280026140038F03328009013F8 -:1071D000FFFCF7044250F686425076B5001E76B4A6 -:1071E000FFE5C7386FC07739FFF09713FFFC9613A0 -:1071F000FFFC9593FFFC07880008E000F5F49793E7 -:10720000FFFC20220000E600721DF5021770F70453 -:1072100042540000000127380001F705425495133D -:10722000FFFCF502001B9513FFFCF5064244951385 -:10723000FFFC07880008E0011EC09793FFFC8796BB -:10724000FFFC8296FFF802140000013C00000000E1 -:1072500000019293FFFC02900008F704E0048616F8 -:107260000000F68200FF7739FFF0C7386C00F73373 -:107270002800F706E006873A000006B00002F7375C -:107280002800F6843B6407300004F6BB2800870220 -:10729000FF3406300006F73328008796FFFC8296FD -:1072A000FFF802140004013C00000000000192936A -:1072B000FFFC029000082210003026140020F0335A -:1072C000280027140038F03B28009713FFFC909308 -:1072D000FFFCF7044250F686425076B5001E76B4A5 -:1072E000FFE5C7386FC07739FFF09713FFFC96139F -:1072F000FFFC07880008E000F3389793FFFC20228A -:107300000000E6007319F5821770F704425400007C -:10731000000127380001F70542549593FFFCF582E0 -:10732000001B9593FFFCF58642449593FFFC07886C -:107330000008E0011EC09793FFFC8796FFFC829631 -:10734000FFF802140000013C0000000000019293CD -:10735000FFFC029000082210004026140020961620 -:10736000FFC4F03328009013FFFC9613FFFC261493 -:1073700000389616FFBC9613FFFC07880008E00053 -:10738000D0DC9793FFFC9013FFFCF7044250F68685 -:10739000425076B5001E76B4FFE5C7386FC0773926 -:1073A000FFF09713FFFC8616FFBC00000001961348 -:1073B000FFFC8616FFC4000000019613FFFC07883F -:1073C0000008E000F5F49793FFFC20220000E6009F -:1073D00073E5F6021770F7044254000000012738E5 -:1073E0000001F70542549613FFFCF602001B9613AA -:1073F000FFFCF60642449613FFFC07880008E001F4 -:107400001EC09793FFFC8796FFFC8296FFF802143C -:107410000000013C0000000000019293FFFC02907C -:10742000000822100004F5820000F5854080959642 -:10743000FFF407880008E000CB509793FFFC859687 -:10744000FFF4F5020064F5053BB4F7044250F486FE -:10745000425076A5001E76B4FFE5F6044F5CF402B8 -:107460000006F4054254F5853B6CF5853BB8953232 -:10747000000095B20004C7386FC07739FFF00738B5 -:107480000001F727280007880008E00071B09793F3 -:10749000FFFCF4063704F40542448796FFFC82960D -:1074A000FFF802140000013C00000000000192936C -:1074B000FFFC0290000822100050F7044250F686AC -:1074C000425076B5001E76B4FFE5F6046F34C73837 -:1074D0006FC086B2000C7739FFF0C0367200E6004C -:1074E00077ECC504000086B20010F704E000F30258 -:1074F0000000C0367200E600751804B0001086B2B5 -:107500000014F704E00400000001C0367200E60039 -:10751000751C201A0000F3020001201A0000E6008A -:10752000752900000001F502000086A60000F7049E -:10753000E00000000001C0367200E2007564F6024F -:107540000000C0367200E600756C2032000086A68E -:107550000004F704E00400000001C0367200E200FD -:10756000756D20320000F602000120320000E600B6 -:10757000757D202A0000F5020001202A0000E600A7 -:1075800077EC0000000107880008E000CBCC97935F -:10759000FFFC26140020F033280004A00002F0278E -:1075A0002800F582000023940022F59F280003A004 -:1075B000001A9396FFD42594002285AE000077AD83 -:1075C000001E77BCFFE5C5AC7FC075ADFFF076311E -:1075D000001E7630FFE506A400022314001E751578 -:1075E000001EF59F2800F384E0007528FFE593A2B4 -:1075F000001CF584E0047399001E739CFFE59396CC -:10760000FFAC7395001E739CFFE59396FFCC23940B -:10761000004295A200208716FFE07595001E75AC0C -:10762000FFE59596FFB47595001E75ACFFE5959640 -:10763000FFC4C73867C07738FFF0F7272800F48405 -:107640004F58871A0000C4A04A0074A4FFFAC5A4CA -:107650000000F59F28008396FFAC2314001A7619CA -:10766000001E7630FFE58596FFB4C7383FC07738F7 -:10767000FFF0F737280006B400028716FFE4839670 -:10768000FFCCC73857C07738FFF0F7372800871A84 -:10769000000006B40002C73867C07738FFF0F7373C -:1076A000280006B400028716FFE823140016761996 -:1076B000001E7630FFE5C7385FC07738FFF0F73738 -:1076C0002800871A000006B40002C73867C0773860 -:1076D000FFF0F737280006B400028716FFEC2314EA -:1076E00000127619001E7630FFE5C7383FC07738A4 -:1076F000FFF0F7372800871A000006B400028596CD -:10770000FFC4C73867C07738FFF0F73728008716FF -:10771000FFF006B40002C7385FC07738FFF0F737D4 -:107720002800F3820002F3A3280004200018259407 -:10773000002285AE000077AD001E77BCFFE5C5AC2A -:107740007FC075ADFFF08396FFD4F5A32800F49FAA -:1077500028002594004285AE000077AD001E77BC5E -:10776000FFE5C5AC7FC075ADFFF044AD000094935C -:10777000FFFCF786E0009793FFFCF3844F5C00006A -:1077800000019393FFFC07880008E00123409793D2 -:10779000FFFC07880008E00078D89793FFFCF0050D -:1077A0004084F786E0009793FFFC07880008E0001C -:1077B000D5A09793FFFCF7046E50F4054084873AF8 -:1077C0001DDC00000001F7053B64F5863678F58581 -:1077D0004244F3863560F3854230F5864244959302 -:1077E000FFFC07880008E0011F489793FFFC87967D -:1077F000FFFC8296FFF802140000013C000000002C -:1078000000019293FFFC02900008F5864244959394 -:10781000FFFC07880008E00120E49793FFFC20228A -:107820000000E600788900000001F70442540000DF -:107830000001203A0000EE007851F6064250078819 -:107840000008E00071B09793FFFCE000788800002A -:107850000001F704425076B1001E76B4FFE5F582D0 -:107860000006F5854254C7386FC07739FFF00738F6 -:107870000001F733280007880008E00072AC9793F6 -:10788000FFFCF5863790F58542448796FFFC82968B -:10789000FFF802140000013C000000000001929378 -:1078A000FFFC02900008F6063678F6054244F7021F -:1078B0000000F7054080F7054094F6846E50F70508 -:1078C000409097361DDC8796FFFC8296FFF80214E5 -:1078D0000000013C0000000000019293FFFC0290B8 -:1078E0000008F7020001F70540808796FFFC8296AA -:1078F000FFF802140000013C000000000001929318 -:10790000FFFC02900008221000A8F7044250F58600 -:10791000425076AD001EF4846F3476B4FFE5949641 -:10792000FFC4C7386FC086A6000C7739FFF0C03699 -:107930007200E6007955F606429AF704429876B14D -:10794000001E76B4FFE5C7386FC07739FFF00738FF -:107950000001F7332800F704425076AD001E76B4DC -:10796000FFE58516FFC4C7386FC086AA000C7739BB -:10797000FFF0C0367200E60080A8F606429A872A19 -:107980000010862A001C203A0000E60079A8F68242 -:107990000000872A001400000001203A0000E600E1 -:1079A00079AC20360000F682000120360000E600A7 -:1079B0007A05249400209496FFBC8516FFC4F02716 -:1079C0002800052800109516FFB49513FFFC0788C2 -:1079D0000008E00072509793FFFC8496FFB400000B -:1079E00000019493FFFC8516FFBC00000001951375 -:1079F000FFFC07880008E000F9349793FFFCE000E3 -:107A000080C40000000120320000E600806C00000D -:107A1000000107880008E000CBCC9793FFFC259479 -:107A20000020F02F280004A000029496FF5CF027AD -:107A30002800F48200002514005AF4AB2800072027 -:107A4000001A2514005A852A000077A9001E77BC69 -:107A5000FFE5C5287FC07529FFF075AD001E75AC28 -:107A6000FFE52314001E7619001EF53B2800F48460 -:107A7000E0007630FFE594A2001CF504E004849653 -:107A8000FF5C952200208716FFE006A40002751512 -:107A9000001E7528FFE59516FF547495001E74A40A -:107AA000FFE59496FF9C7515001E7528FFE5951659 -:107AB000FF947495001E8516FF5C74A4FFE59496F0 -:107AC000FF8C8496FF54C7385FC07738FFF0F72BE0 -:107AD0002800871A00008516FF9CC73867C07738D2 -:107AE000FFF0F737280006B400028716FFE42314DE -:107AF000001A7619001E7630FFE5C7384FC0773878 -:107B0000FFF0F7372800871A000006B400028496B9 -:107B1000FF94C73867C07738FFF0F737280006B4FE -:107B200000028716FFE8231400167619001E76302F -:107B3000FFE5C73857C07738FFF0F7372800871AB6 -:107B4000000006B40002C73867C07738FFF0F73787 -:107B5000280006B400028716FFEC231400127619E1 -:107B6000001E7630FFE5C7384FC07738FFF0F73793 -:107B70002800871A000006B400028516FF8CC7385B -:107B800067C07738FFF0F73728008716FFF006B494 -:107B90000002C73857C07738FFF0F7372800F48263 -:107BA0000002F4A328002514005A852A000077A9B2 -:107BB000001E77BCFFE5C5287FC07529FFF00720B0 -:107BC0000018F53B28009416FFAC07880008E00079 -:107BD000CBCC9793FFFC261400382494005A84A63B -:107BE000000077A5001E77BCFFE5C4A47FC074A584 -:107BF000FFF005A0000206AC000223940036751DBC -:107C0000001E7528FFE50720001AF4B3280076311E -:107C1000001E7630FFE59516FF547495001E74A47F -:107C2000FFE59496FF5C7515001E7528FFE5951617 -:107C3000FF7C7495001E8516FFC474A4FFE594961E -:107C4000FF74852A00342494005A9516FF8484A674 -:107C5000000077A5001E77BCFFE5C4A47FC074A513 -:107C6000FFF02514005AF4AF2800852A000077A9F8 -:107C7000001E77BCFFE5C5287FC07529FFF08496FC -:107C8000FFC4F53B280084A600108516FFC494A20B -:107C9000001C852A00147495001E74A4FFE59496B8 -:107CA000FF6C952200208716FFC88516FF54C73841 -:107CB00067C07738FFF0F72F2800871E00008496F2 -:107CC000FF5CC73857C07738FFF0F737280006B495 -:107CD00000028716FFCC23940032761D001E7630FA -:107CE000FFE58516FF7CC7384FC07738FFF0F737C0 -:107CF0002800871E000006B40002C73867C0773826 -:107D0000FFF0F737280006B400028716FFD023944F -:107D1000002E761D001E7630FFE5C73857C0773835 -:107D2000FFF0F7372800871E000006B40002849693 -:107D3000FF748516FF6CC73867C07738FFF0F737D8 -:107D4000280006B400028716FFD42394002A761D6B -:107D5000001E7630FFE5C7384FC07738FFF0F737A1 -:107D60002800871E000006B40002C73867C07738B5 -:107D7000FFF0F73728008716FFD806B40002C7388F -:107D800057C07738FFF0F7372800F4820002F4A3D9 -:107D90002800072000182514007A852A000077A9FA -:107DA000001E77BCFFE5C5287FC07529FFF08496CB -:107DB000FFC4F53B28008726000400000001203A9C -:107DC0000024F7044F58E6007EF99416FF54C720AC -:107DD0007200F6846E508626002C7738FFFA251440 -:107DE000005A842A000077A9001E77BCFFE5C42052 -:107DF0007FC07421FFF04739000086B61DDC77395B -:107E00000002C0326A00468C0001D6800A68203623 -:107E10000000F6864098E6007EC0C3B86800C584BE -:107E2000000086A60024F704E000F6020000C03639 -:107E30007200E6007E540324002486A60028F7047E -:107E4000E00400000001C0367200E6007E582032D7 -:107E50000000F602000120320000E6007E6500000E -:107E60000001F5820000869A0000F704E00000009F -:107E70000001C0367200E2007EA0F6020000C036AB -:107E80007200E6007EA820320000869A0004F70403 -:107E9000E00400000001C0367200E2007EA920323A -:107EA0000000F602000120320000E6007EB9202E1C -:107EB0000000F5820001202E0000E6007EC50000D3 -:107EC0000001F4020001F7044F58F41F28008496C3 -:107ED000FF548516FFC4F686409AC724720077388F -:107EE000FFFA862A00304739000077390002C73888 -:107EF0006800E0007F4CF63B28008496FF54F606AD -:107F00004098C72472007738FFFAC6B8000046B51B -:107F1000000076B50002C6B46000F5020001F53736 -:107F200028004739000077390002C73860002494E0 -:107F3000005A84A6000077A5001E77BCFFE5C4A404 -:107F40007FC074A5FFF007380002F4BB2800F704D7 -:107F50004F588516FF548496FFACC6A8720076B4BD -:107F6000FFFA0624001AF6B32800C72472007738F7 -:107F7000FFFA06A8001AF7372800473900009713C0 -:107F8000FFFC0724001C9713FFFCF5044F5C000066 -:107F900000019513FFFC07880008E0012340979338 -:107FA000FFFCF7044F588496FF5400000001C724DB -:107FB00072007738FFFA473900009713FFFC072457 -:107FC000001C9713FFFCF5044F5C000000019513A3 -:107FD000FFFC07880008E00123409793FFFC078817 -:107FE0000008E00078D89793FFFCF6846E500000FC -:107FF000000187361DDC00000001073800019736BC -:108000001DDC87361DDCF0054084F486E000949387 -:10801000FFFC07880008E000D5A09793FFFCF4055B -:108020004084F7046E50F005425C873A1DDCF6860A -:108030002C28F7053B64F7042D38F5063A4CF50576 -:10804000424406380001F6052D3877390002F482E3 -:10805000001C20320044E6008060B4BA6802F005DB -:108060002D38F50635ECE000808CF50542302032E5 -:108070000001E60080C40000000107880008E0005D -:10808000789C9793FFFCF4863560F4854230F506C2 -:1080900042449513FFFC07880008E0011F489793AE -:1080A000FFFCE00080C400000001F704429876B1B4 -:1080B000001E76B4FFE5C7386FC07739FFF0073888 -:1080C0000001F73328008796FFFC8296FFF8021420 -:1080D0000000013C0000000000019293FFFC0290B0 -:1080E0000008F58642449593FFFC07880008E001EC -:1080F00020E49793FFFC20220000E600816100004D -:108100000001F704425400000001203A0000EE0094 -:108110008129F606425007880008E00072AC979368 -:10812000FFFCE000816000000001F704425076B1DE -:10813000001E76B4FFE5F5820006F5854254C73887 -:108140006FC07739FFF007380001F7332800078840 -:108150000008E000734C9793FFFCF586381CF5850A -:1081600042448796FFFC8296FFF802140000013C0F -:108170000000000000019293FFFC02900008221012 -:108180000058F7044250F686425076B5001E76B489 -:10819000FFE5F6046F34C7386FC086B2000C77393C -:1081A000FFF0C0367200E6008250F4820000C50481 -:1081B000000086B20010F704E000C5A40000C0363D -:1081C0007200E60081E40430001086B20014F70467 -:1081D000E00400000001C0367200E60081E8202EB5 -:1081E0000000F5820001202E0000E60081F500006D -:1081F0000001F502000086A20000F704E000000084 -:108200000001C0367200E2008230F6020000C03683 -:108210007200E60082382032000086A20004F704D3 -:10822000E00400000001C0367200E2008239203212 -:108230000000F602000120320000E6008249202AF8 -:108240000000F5020001202A0000E60082592026E5 -:108250000000F482000120260000E6008760000094 -:10826000000107880008E000CBCC9793FFFC0720B3 -:108270000002F03B2800F7044F58F4053BB006A07D -:108280000014C72072007738FFFAF737280006A0DD -:108290000016F7372800F3020001F32328000788AF -:1082A0000008E000CBCC9793FFFC26140020F033AD -:1082B000280004A00002F0272800F3020000239405 -:1082C000002AF31F28000720001A2394002A839E07 -:1082D0000000779D001E77BCFFE5C39C7FC0739DA7 -:1082E000FFF07631001E7630FFE506A4000275151A -:1082F000001EF3BB2800F304E0007528FFE593227D -:10830000001CF384E0042314001E9316FFA4759947 -:10831000001E75ACFFE57315001E7318FFE593167C -:10832000FFCC8316FFA493A200208716FFE073956D -:10833000001E739CFFE59396FFAC7395001E739C23 -:10834000FFE5C73867C07738FFF0F7272800871A9E -:1083500000009396FFC4C7385FC07738FFF0F73747 -:10836000280006B400028716FFE42394001A9396AF -:10837000FFA4761D001E7630FFE5C73857C077385A -:10838000FFF0F7372800871E000006B40002C73848 -:1083900067C07738FFF0F737280006B40002871669 -:1083A000FFE8231400169316FFA47619001E839687 -:1083B000FFAC7630FFE5C7383FC07738FFF0F737BE -:1083C0002800871A000006B40002C73867C0773853 -:1083D000FFF0F737280006B400028716FFEC2314DD -:1083E00000129316FFA47619001E8396FFCC7630F8 -:1083F000FFE5C7383FC07738FFF0F7372800871A06 -:10840000000006B40002C73867C07738FFF0F737BE -:1084100028008716FFF08316FFC406B40002C73891 -:1084200037C07738FFF0F7372800F3820002F3A354 -:1084300028002314002A831A00007799001E77BCB5 -:10844000FFE5C3187FC07319FFF007200018F33B46 -:1084500028009416FFDC07880008E000CBCC979337 -:10846000FFFC072000022394002A839E0000779DD2 -:10847000001E77BCFFE5C39C7FC0739DFFF0248086 -:1084800000070520000AF3BB280020260007EE00A5 -:1084900084E00628000E86B200007731001E77388F -:1084A000FFE575B1001E75ACFFE50528000204A4C8 -:1084B0000001C6B477C076B5FFF0F702FF00C6B47E -:1084C0007400F6B3280087320000F30200FFC738BB -:1084D0005FC07739FFF0C7383400E0008488F73395 -:1084E000280005200026862A000076A9001EF584B3 -:1084F0004F5876B4FFE58396FFDCF30200FF941635 -:10850000FFBCC71C5A007738FFFAC6306FC07631FF -:10851000FFF047390000C7383400F682FF00C6304C -:108520006C00C7386000F6843B6CF72B2800C5A0B0 -:108530005A0075ACFFFA8316FFDC07340001F7051B -:108540003B6C0720003AF6BB280007200036F03BC2 -:108550002800F3820003F3A328000718001AF5BBD4 -:10856000280007880008E000CBCC9793FFFC072089 -:108570000002F03B2800248000070520000A202686 -:108580000007EE0085D40628000E86B20000773181 -:10859000001E7738FFE575B1001E75ACFFE50528B4 -:1085A000000204A40001C6B477C076B5FFF0F7025C -:1085B000FF00C6B47400F6B3280087320000F382CF -:1085C00000FFC7385FC07739FFF0C7383C00E000D4 -:1085D000857CF733280005A00026862E000076ADA6 -:1085E000001E76B4FFE5C520000024000007F3025A -:1085F00000019316FFA4F7044F588396FFBC248014 -:10860000000EC71C72007738FFFAC6306FC0763193 -:10861000FFF047390000F68200FFC7386C00F68291 -:10862000FF00C6306C00C7386000F6843B6CF72F43 -:10863000280007340001F7053B6C0728003AF6BB19 -:10864000280007280036F03B2800F3020003F32B34 -:10865000280020220007EE008694C6284800063035 -:1086600000268732000076B1001E76B4FFE504A430 -:108670000002042000018396FFA4C7386FC0773939 -:10868000FFF0F682FF00C7386C00C71C7000E000E6 -:108690008650F73328000628002686B2000077317E -:1086A000001E7738FFE5C6B477C076B5FFF0F70255 -:1086B000FF00C6B47400F6B328009513FFFCF30462 -:1086C0003BB0000000019313FFFC9516FFB4078830 -:1086D0000008E000D42C9793FFFC8516FFB4F0054A -:1086E000407C8396FFBC23000007F3054258F70443 -:1086F0004250F606425076B1001E76B4FFE5F3060E -:108700003934F3054244F5054074F3854260F38241 -:108710000006F3854254C7386FC07739FFF0F684FE -:108720002D3807380001F733280006340001F6051C -:108730002D38F7062C2876B50002F382001C203273 -:108740000044E600874CB3B67002F0052D38F306FE -:1087500042449313FFFC07880008E0011F489793E9 -:10876000FFFC8796FFFC8296FFF802140000013C94 -:108770000000000000019293FFFC0290000822100C -:108780000048F38642449393FFFC07880008E00109 -:1087900020E49793FFFC20220000E60089ED000012 -:1087A0000001F704425400000001203A0000EE00EE -:1087B00087C90000000107880008E000734C979308 -:1087C000FFFCE00089EC0000000107880008E000E1 -:1087D000CBCC9793FFFC26140020F033280005A093 -:1087E0000002F02F2800F382000024940022F3A757 -:1087F000280004A0001A9496FFD423940022839E9C -:108800000000779D001E77BCFFE5C39C7FC0739D71 -:10881000FFF07631001E7630FFE506AC000223142F -:10882000001E7519001EF3A72800F484E0007528C7 -:10883000FFE594A2001CF384E0047495001E74A468 -:10884000FFE59496FFB47495001E74A4FFE594961A -:10885000FFCC8496FFB493A200208716FFE07395A7 -:10886000001E739CFFE59396FFBC7395001E739CDE -:10887000FFE59396FFC48396FFBCC73867C077387F -:10888000FFF0F72F2800F5844F58871A0000C5A085 -:108890005A0075ACFFFAC73857C07738FFF0F73782 -:1088A000280006B400028716FFE42314001A761984 -:1088B000001E7630FFE545AD0000C7384FC0773861 -:1088C000FFF0F7372800871A000006B400028496EC -:1088D000FFCCC73867C07738FFF0F737280006B4F9 -:1088E00000028716FFE8231400167619001E763062 -:1088F000FFE5C7383FC07738FFF0F7372800871A01 -:10890000000006B40002C73867C07738FFF0F737B9 -:10891000280006B400028716FFEC23140012761913 -:10892000001E7630FFE5C7384FC07738FFF0F737C5 -:108930002800871A000006B400028396FFC4C738D7 -:1089400067C07738FFF0F73728008716FFF006B4C6 -:108950000002C7383FC07738FFF0F7372800F482AD -:108960000002F4A328000420001823940022839E10 -:108970000000779D001E77BCFFE5C39C7FC0739D00 -:10898000FFF08496FFD4F3A32800F3820001F3A73D -:1089900028009593FFFCF486E0009493FFFCF38499 -:1089A0004F5C000000019393FFFC07880008E00182 -:1089B00023409793FFFC07880008E00078D897933E -:1089C000FFFCF4863678F4854244F0054084F68452 -:1089D0004F5CF70200649736000090360004F702FF -:1089E0000001F7054084F38635ECF3854230879625 -:1089F000FFFC8296FFF802140000013C000000001A -:108A000000019293FFFC0290000822100090F704EE -:108A10004260F502000005B80018F6044258000054 -:108A2000000120320007EE008A70C7306000C738AE -:108A300058000738000E86BA00007739001E7738D4 -:108A4000FFE5C6B477C076B5FFF0F70200FFC6B405 -:108A50007400C0365200470C0001D7000A70203A5B -:108A60000000E6008A7107300001E0008A18F7056F -:108A70004258F40442580000000120220007EE0092 -:108A80008D9424940036F604426025140038239413 -:108A90000020063000028732000076B1001E76B456 -:108AA000FFE50630000275B1001EC7386FC0773889 -:108AB000FFF0F72B28008732000075ACFFE5C738C0 -:108AC0005FC07738FFF0F727280024940034063081 -:108AD00000028732000076B1001E76B4FFE5C73889 -:108AE0006FC07738FFF0F727280024940032063053 -:108AF00000028732000076B1001E76B4FFE5C73869 -:108B00006FC07738FFF0F727280024940030063034 -:108B100000028732000076B1001E76B4FFE5C73848 -:108B20006FC07738FFF0F72728002494002E063016 -:108B300000028732000076B1001E76B4FFE5C73828 -:108B40006FC07738FFF0F72728002494002C0630F8 -:108B500000028732000076B1001E76B4FFE5C73808 -:108B60006FC07738FFF0F72728002494002A0630DA -:108B700000028732000076B1001E76B4FFE5C738E8 -:108B80006FC07738FFF0F7272800063000028732E1 -:108B90000000249400287631001E7630FFE5C738A7 -:108BA00067C07738FFF0F72728009413FFFC951370 -:108BB000FFFC9396FF7C9393FFFC07880008E0007E -:108BC000D0DC9793FFFCF60442602494007E2514C9 -:108BD000008023940068063000028732000076B1DE -:108BE000001E76B4FFE50630000275B1001EC738DE -:108BF0006FC07738FFF0F72B28008732000075AC84 -:108C0000FFE5C7385FC07738FFF0F72728002494C6 -:108C1000007C063000028732000076B1001E76B478 -:108C2000FFE5C7386FC07738FFF0F7272800249496 -:108C3000007A063000028732000076B1001E76B45A -:108C4000FFE5C7386FC07738FFF0F7272800249476 -:108C50000078063000028732000076B1001E76B43C -:108C6000FFE5C7386FC07738FFF0F7272800249456 -:108C70000076063000028732000076B1001E76B41E -:108C8000FFE5C7386FC07738FFF0F7272800249436 -:108C90000074063000028732000076B1001E76B400 -:108CA000FFE5C7386FC07738FFF0F7272800249416 -:108CB0000072063000028732000076B1001E76B4E2 -:108CC000FFE5C7386FC07738FFF0F7272800063078 -:108CD000000287320000249400707631001E763046 -:108CE000FFE5C73867C07738FFF0F72728009513EE -:108CF000FFFC9396FF749393FFFC07880008E00045 -:108D0000D2589793FFFC8396FF7400000001939361 -:108D1000FFFCF704425823940050C70072009713D9 -:108D2000FFFC9396FF6C9393FFFC07880008E0001C -:108D3000CF249793FFFC8396FF6CF6864250939363 -:108D4000FFFCF384425876B5001E9393FFFCF704B2 -:108D5000425076B4FFE5C7386FC07739FFF09713FC -:108D6000FFFC8396FF7C000000019393FFFC0788C3 -:108D70000008E000F3389793FFFC20220000E60093 -:108D80008D9500000001F7044258000000010738EB -:108D90000001F7054258F704425800000001203A4C -:108DA0000007EE008DD4F3821770F7042D38F68695 -:108DB0002C2806380001F6052D3877390002F38299 -:108DC000001C20320044E6008DF4B3BA6802E000D3 -:108DD0008DF4F0052D389393FFFCF382001B9393E1 -:108DE000FFFCF38642449393FFFC07880008E001F0 -:108DF0001EC09793FFFC8796FFFC8296FFF8021433 -:108E00000000013C0000000000019293FFFC029072 -:108E1000000822100088F7044250F686425076B5CA -:108E2000001EF3846F3476B4FFE59396FFC4C73811 -:108E30006FC0869E000C7739FFF0C0367200E600E6 -:108E40008E65F60642A0F70442A076B1001E76B405 -:108E5000FFE5C7386FC07739FFF007380001E00041 -:108E600094E4F7332800F604426024940036851613 -:108E7000FFC423940038063000028732000076B128 -:108E8000001E76B4FFE5852A001C0630000275B18D -:108E9000001EC7386FC07738FFF09516FFBCF71F6C -:108EA00028008732000075ACFFE58516FFC4C7387F -:108EB0005FC07738FFF0F72728002494003406308D -:108EC00000028732000076B1001E76B4FFE5C73895 -:108ED0006FC07738FFF0F72728002494003206305F -:108EE00000028732000076B1001E76B4FFE5C73875 -:108EF0006FC07738FFF0F727280024940030063041 -:108F000000028732000076B1001E76B4FFE5C73854 -:108F10006FC07738FFF0F72728002494002E063022 -:108F200000028732000076B1001E76B4FFE5C73834 -:108F30006FC07738FFF0F72728002494002C063004 -:108F400000028732000076B1001E76B4FFE5C73814 -:108F50006FC07738FFF0F72728002494002A0630E6 -:108F600000028732000076B1001E76B4FFE5C738F4 -:108F70006FC07738FFF0F7272800063000028732ED -:108F80000000249400287631001E7630FFE5C738B3 -:108F900067C07738FFF0F7272800872A00200000F5 -:108FA00000019713FFFC9393FFFC271400209713F5 -:108FB000FFFC07880008E000D0DC9793FFFC839655 -:108FC000FFC400000001871E001000000001203ACD -:108FD0000000E6008FF0F6820000871E00140000FB -:108FE0000001203A0000E6008FF420360000F682EF -:108FF000000120360000E6009041000000018516C7 -:10900000FFC400000001052800109516FFB4951359 -:10901000FFFC07880008E00072509793FFFC8396DE -:10902000FFB4271400209393FFFC9713FFFC0788DD -:109030000008E000F9349793FFFCE00094E400009E -:1090400000018516FFBC00000001202A0000E60098 -:1090500094BC0000000107880008E000CBCC979387 -:10906000FFFCF502000023940062F51F28007595AF -:10907000001E75ACFFE50620000206B000022314B6 -:10908000001E7399001E739CFFE59396FF7475157F -:10909000001E7528FFE59516FF7C7395001E739CD6 -:1090A000FFE59396FF8C8516FFC47395001E93967B -:1090B000FF84852A0034239400629516FFACF033B8 -:1090C00028000520001A9516FF94839E0000779DC6 -:1090D000001E77BCFFE5C39C7FC0739DFFF07495B5 -:1090E000001EF3AB28008516FFC474A4FFE5852A93 -:1090F00000108396FFC49522001C839E00148516E1 -:10910000FF8493A200208716FFE07528FFE59516DF -:10911000FF84F3844F588516FF74C7385FC07738D3 -:10912000FFF0F7332800871A00009396FFA4C022AF -:109130003A008396FF7CC73857C07738FFF0F7377F -:10914000280006B400028716FFE42314001A7619DB -:10915000001E7630FFE5C7384FC07738FFF0F7378D -:109160002800871A000006B40002C73867C07738A5 -:10917000FFF0F737280006B400028716FFE8231433 -:1091800000167619001E7630FFE5C7383FC07738E5 -:10919000FFF0F7372800871A000006B40002851692 -:1091A000FF8C8396FF84C73867C07738FFF0F737A6 -:1091B000280006B400028716FFEC2314001276196B -:1091C000001E7630FFE5C73857C07738FFF0F73715 -:1091D0002800871A000006B40002C73867C0773835 -:1091E000FFF0F73728008716FFF006B40002C738F3 -:1091F0003FC07738FFF0F7372800F5020002F5236B -:10920000280023940052839E0000779D001E77BCA7 -:10921000FFE5C39C7FC0739DFFF003200018E600AC -:109220009230F39B2800F7044270E000929CF6060F -:1092300042728516FFC40000000186AA00200000CB -:10924000000107340007203A000EE2009294C73470 -:109250006800F5844260F38200FFC72C7000073875 -:10926000002686BA00009716FF747739001E7738FB -:10927000FFE5C6B477C076B5FFF0C6B43C00203633 -:109280000000470C0001D7000A70203A0000E600F9 -:1092900092C900000001F7044274F606427476B1E8 -:1092A000001E76B4FFE5C7386FC07739FFF0073886 -:1092B0000001F733280007880008E000789C9793A6 -:1092C000FFFCE00094E4000000018516FFA48396F3 -:1092D000FF74C720520074B8FFFAC6240000871E2E -:1092E0000000769D001E76B4FFE5C5AC520075AC5B -:1092F000FFFA46310000F50200FFC6305400C738BF -:109300006FC07739FFF0F682FF00C7386C00C630B7 -:109310007000F61F28008396FF948516FFC4F59F02 -:109320002800872A000400000001203A0024E600FB -:109330009469F6864098F7046E50862A002CC6A4DD -:10934000000023940062849E0000779D001E77BC7D -:10935000FFE5C4A47FC074A5FFF046B50000873ABE -:109360001DDC76B50002C0327200470C0001D70048 -:109370000A70203A0000F7064098E6009434C3349F -:109380007000C584000086AA0024F704E000F602FD -:109390000000C036720005280024E60093C495162C -:1093A000FF748396FFC400000001869E0028F70426 -:1093B000E00400000001C0367200E60093C82032CD -:1093C0000000F602000120320000E60093D5000004 -:1093D0000001F58200008516FF74F704E00086AAFC -:1093E000000000000001C0367200E2009414F60292 -:1093F0000000C0367200E600941C2032000086AAED -:109400000004F704E00400000001C0367200E2002E -:10941000941D20320000F602000120320000E60018 -:10942000942D202E0000F5820001202E0000E60081 -:10943000943900000001F4820001F7044F58F49BB6 -:1094400028008396FFC4F686409AC72072007738BA -:10945000FFFA861E00304739000077390002C7380E -:109460006800E00094E4F63B2800472500007739C7 -:109470000002C7386800F5020001F53B28000738F4 -:10948000000223940062839E0000779D001E77BC3B -:10949000FFE5C39C7FC0739DFFF025140062F3BB02 -:1094A0002800852A000077A9001E77BCFFE5C528A3 -:1094B0007FC07529FFF0E00094E4F51B2800839637 -:1094C000FFBC00000001201E0001E60094E4000043 -:1094D000000107880008E000789C9793FFFCF506E0 -:1094E0003560F50542308796FFFC8296FFF802143E -:1094F0000000013C0000000000019293FFFC02907C -:109500000008F50642449513FFFC07880008E001B7 -:1095100020E49793FFFC20220000E60096890000DB -:109520000001F68442540000000120360000EE00E5 -:10953000958DF5864250F7044250762D001E763008 -:10954000FFE526B40001F685425425000007F50525 -:109550004258F6842D38C73867C07739FFF007388E -:109560000001F72F280006340001F6052D38F70614 -:109570002C2876B50002F502001C20320044E600DB -:109580009688B5367002E0009688F0052D38F5040F -:109590004260000000019513FFFC07880008E0000E -:1095A000B2849793FFFCF6844F5800000001073403 -:1095B0000040C0227200E60095ECF6064276F70401 -:1095C000427476B1001E76B4FFE5C7386FC07739B4 -:1095D000FFF007380001F733280007880008E00093 -:1095E000789C9793FFFCE000968800000001F70448 -:1095F000426000000001C0227200E60096240000D4 -:1096000000019713FFFCF5043BB000000001951327 -:10961000FFFC07880008E000D42C9793FFFCE000D3 -:10962000964000000001C0226A00E600967100002A -:1096300000019713FFFC07880008E000CC609793B7 -:10964000FFFCF704407C000000010738000197137D -:10965000FFFCF5044074000000019513FFFC07882F -:109660000008E000BEF89793FFFCE0009688000039 -:109670000001F5044074000000019513FFFC078809 -:109680000008E000C1B49793FFFC8796FFFC829628 -:10969000FFF802140000013C00000000000192935A -:1096A000FFFC0290000822100070F6046F34F704EB -:1096B000426486B2000400000001C0367200E60079 -:1096C0009B1806B0000287360000F404407C76B593 -:1096D000001E76B4FFE5C7386FC07739FFF0C03A97 -:1096E0004200E6009B1824940036F604407423944C -:1096F0000038063000028732000076B1001E76B4D2 -:10970000FFE50630000275B1001EC7386FC077381C -:10971000FFF0F71F28008732000075ACFFE5C7385F -:109720005FC07738FFF0F727280024940034063014 -:1097300000028732000076B1001E76B4FFE5C7381C -:109740006FC07738FFF0F7272800249400320630E6 -:1097500000028732000076B1001E76B4FFE5C738FC -:109760006FC07738FFF0F7272800249400300630C8 -:1097700000028732000076B1001E76B4FFE5C738DC -:109780006FC07738FFF0F72728002494002E0630AA -:1097900000028732000076B1001E76B4FFE5C738BC -:1097A0006FC07738FFF0F72728002494002C06308C -:1097B00000028732000076B1001E76B4FFE5C7389C -:1097C0006FC07738FFF0F72728002494002A06306E -:1097D00000028732000076B1001E76B4FFE5C7387C -:1097E0006FC07738FFF0F727280006300002873275 -:1097F0000000249400287631001E7630FFE5C7383B -:1098000067C07738FFF0F72728009413FFFC939385 -:10981000FFFC271400209713FFFC07880008E000D6 -:10982000D0DC9793FFFC07880008E000CBCC97932F -:10983000FFFCF50440749416FFC407200002F03BBF -:10984000280024800007F40200FF8396FFC49516C9 -:10985000FFBC031C000A20260007EE0098A806188B -:10986000000E86B200007731001E7738FFE575B133 -:10987000001E75ACFFE503180002C6B477C076B5CC -:10988000FFF0F702FF00C6B47400F6B32800873279 -:10989000000004A40001C7385FC07739FFF0C73863 -:1098A0004400E0009854F73328008516FFC47495EF -:1098B000001E74A4FFE58396FFC42314001E7419D0 -:1098C000001E7420FFE5052800269516FF8C85AA4A -:1098D000000076A9001E76B4FFE5039C0002939673 -:1098E000FFB4061C00027395001E739CFFE593965F -:1098F000FFAC7395001E739CFFE59396FF9C8396C7 -:10990000FFBC7515001E7528FFE59516FF947515AB -:10991000001E7528FFE59516FFA48516FFC4C5AC8B -:109920006FC075ADFFF0F5054260F5044F58F68243 -:1099300000FFC71C52007738FFFA47390000C738CC -:109940006C00F682FF00C5AC6C00C73858008396E7 -:10995000FF8CF5843B6C8516FFB4F71F2800871633 -:10996000FFE006AC0001F6853B6C8396FFC4C73868 -:109970004FC07738FFF0F72B2800F5044F58871AAF -:109980000000C01E5200C73847C07738FFF0F733D9 -:109990002800063000028716FFE42314001A769987 -:1099A000001E8396FF9476B4FFE5C7383FC0773832 -:1099B000FFF0F7332800871A000006300002C7388E -:1099C0006FC07738FFF0F7332800063000028716A3 -:1099D000FFE8231400167699001E76B4FFE585167D -:1099E000FFAC8396FFA4C73857C07738FFF0F73332 -:1099F0002800871A0000063000028516FF9CC73831 -:109A00006FC07738FFF0F733280006300002871662 -:109A1000FFEC231400127699001E76B4FFE5C738D8 -:109A20003FC07738FFF0F7332800871A0000063070 -:109A300000028396FFC4C7386FC07738FFF0F73352 -:109A400028008716FFF006300002C73857C0773865 -:109A5000FFF0F7332800071C003AF5BB2800071C6D -:109A60000036F03B2800F5020003E6009AA4F51F3B -:109A70002800F7044278F606427876B1001E76B4E4 -:109A8000FFE5C7386FC07739FFF007380001F733BB -:109A9000280007880008E000789C9793FFFCE0000E -:109AA0009B1800000001F38642449393FFFC078853 -:109AB0000008E0011F489793FFFC25000007F5050B -:109AC0004258F7044250F606425076B1001E76B472 -:109AD000FFE5F3820006F3854254F5063934F505B7 -:109AE0004244C7386FC07739FFF0F6842D38073805 -:109AF0000001F733280006340001F6052D38F7067B -:109B00002C2876B50002F382001C20320044E600C7 -:109B10009B18B3B67002F0052D388796FFFC82962D -:109B2000FFF802140000013C0000000000019293C5 -:109B3000FFFC0290000822100078F38642449393C1 -:109B4000FFFC07880008E00120E49793FFFC202237 -:109B50000000E6009E4100000001F70442540000AE -:109B60000001203A0000EE009D8524940036F604A2 -:109B7000407425140038063000028732000076B1A8 -:109B8000001E76B4FFE50630000275B1001EC7382E -:109B90006FC07738FFF0F72B28008732000075ACD4 -:109BA000FFE5C7385FC07738FFF0F7272800249417 -:109BB0000034063000028732000076B1001E76B411 -:109BC000FFE5C7386FC07738FFF0F72728002494E7 -:109BD0000032063000028732000076B1001E76B4F3 -:109BE000FFE5C7386FC07738FFF0F72728002494C7 -:109BF0000030063000028732000076B1001E76B4D5 -:109C0000FFE5C7386FC07738FFF0F72728002494A6 -:109C1000002E063000028732000076B1001E76B4B6 -:109C2000FFE5C7386FC07738FFF0F7272800249486 -:109C3000002C063000028732000076B1001E76B498 -:109C4000FFE5C7386FC07738FFF0F7272800249466 -:109C5000002A063000028732000076B1001E76B47A -:109C6000FFE5C7386FC07738FFF0F72728000630C8 -:109C7000000287320000249400287631001E7630DE -:109C8000FFE5C73867C07738FFF0F7272800F3846F -:109C9000407C000000019393FFFC9513FFFC23948C -:109CA00000209396FF949393FFFC07880008E00040 -:109CB000D0DC9793FFFC8396FF9400000001939300 -:109CC000FFFC239400689396FF8C9393FFFC078816 -:109CD0000008E000D2589793FFFC8396FF8C0000A9 -:109CE00000019393FFFC9013FFFC23940050939684 -:109CF000FF849393FFFC07880008E000CF2497932C -:109D0000FFFC8702FF3400000001F7054264F38482 -:109D1000407C000000019393FFFC9713FFFC8396A7 -:109D2000FF84000000019393FFFC8396FF940000E2 -:109D300000019393FFFC07880008E000F7C89793A1 -:109D4000FFFC20220000E6009D5DF3821770F704FF -:109D500042540000000127380001F7054254939354 -:109D6000FFFCF382001B9393FFFCF3864244939322 -:109D7000FFFC07880008E0011EC09793FFFCE0008D -:109D80009E4000000001F504407CF4844074C72824 -:109D90005000C724700005B8002686AE0000772D5D -:109DA000001E7738FFE5C6B477C077B40008703E70 -:109DB000FFE8470C0001D7000A70203A0000F704C2 -:109DC0004F58E6009DFDF60200FFF7044278F606C4 -:109DD000427A76B1001E76B4FFE5C7386FC0773996 -:109DE000FFF007380001F733280007880008E0007B -:109DF000789C9793FFFCE0009E400000000186AE37 -:109E00000000772D001E7738FFE5C6B477C076B521 -:109E1000FFF0F7020001C7386400F602FF00C6B485 -:109E20006400C7386800F72F28000728000197133F -:109E3000FFFC9493FFFC07880008E000BEF89793AE -:109E4000FFFC8796FFFC8296FFF802140000013C9D -:109E50000000000000019293FFFC02900008221015 -:109E600000D8F38642449393FFFC07880008E00182 -:109E700020E49793FFFC20220000E600A2C9000026 -:109E80000001F704425400000001203A0000EE00F7 -:109E9000A03524940036F6044074251400380630AA -:109EA00000028732000076B1001E76B4FFE506306E -:109EB000000275B1001EC7386FC07738FFF0F72B6E -:109EC00028008732000075ACFFE5C7385FC07738DF -:109ED000FFF0F72728002494003406300002873270 -:109EE000000076B1001E76B4FFE5C7386FC0773842 -:109EF000FFF0F72728002494003206300002873252 -:109F0000000076B1001E76B4FFE5C7386FC0773821 -:109F1000FFF0F72728002494003006300002873233 -:109F2000000076B1001E76B4FFE5C7386FC0773801 -:109F3000FFF0F72728002494002E06300002873215 -:109F4000000076B1001E76B4FFE5C7386FC07738E1 -:109F5000FFF0F72728002494002C063000028732F7 -:109F6000000076B1001E76B4FFE5C7386FC07738C1 -:109F7000FFF0F72728002494002A063000028732D9 -:109F8000000076B1001E76B4FFE5C7386FC07738A1 -:109F9000FFF0F727280006300002873200002494E3 -:109FA00000287631001E7630FFE5C73867C0773865 -:109FB000FFF0F7272800F384407C00000001939312 -:109FC000FFFC9513FFFC239400209396FF4C939382 -:109FD000FFFC07880008E000D0DC9793FFFC839625 -:109FE000FF4C000000019393FFFC239400509396D4 -:109FF000FF449393FFFC07880008E000D258979332 -:10A00000FFFC8702FF3400000001F7054264F3847F -:10A01000407C000000019393FFFC9713FFFC8396A4 -:10A02000FF44000000019393FFFC8396FF4CE00087 -:10A03000A2809393FFFCF404407CF6044074F38206 -:10A040000000C7204000C73070000738002686BADD -:10A0500000007739001E7738FFE5C6B477C077B4C3 -:10A060000008703EFFE8470C0001D7000A70203A54 -:10A070000000E600A0AD9396FF3CF70442A0F60670 -:10A0800042A076B1001E76B4FFE5C7386FC07739BD -:10A09000FFF007380001F733280007880008E000C8 -:10A0A000789C9793FFFCE000A2C8000000010630F6 -:10A0B00000028732000076B1001E76B4FFE52494DA -:10A0C000007E25140080239400680630000275B1DC -:10A0D000001EC7386FC07738FFF0F72B2800873293 -:10A0E000000075ACFFE5C7385FC07738FFF0F72791 -:10A0F00028002494007C063000028732000076B1EC -:10A10000001E76B4FFE5C7386FC07738FFF0F72739 -:10A1100028002494007A063000028732000076B1CD -:10A12000001E76B4FFE5C7386FC07738FFF0F72719 -:10A13000280024940078063000028732000076B1AF -:10A14000001E76B4FFE5C7386FC07738FFF0F727F9 -:10A15000280024940076063000028732000076B191 -:10A16000001E76B4FFE5C7386FC07738FFF0F727D9 -:10A17000280024940074063000028732000076B173 -:10A18000001E76B4FFE5C7386FC07738FFF0F727B9 -:10A19000280024940072063000028732000076B155 -:10A1A000001E76B4FFE5C7386FC07738FFF0F72799 -:10A1B00028000630000287320000249400707631B7 -:10A1C000001E7630FFE5C73867C07738FFF0F72705 -:10A1D00028009413FFFC9513FFFC9396FF34939390 -:10A1E000FFFC07880008E000D0DC9793FFFC839613 -:10A1F000FF34000000019393FFFC239400B093967A -:10A20000FF2C9393FFFC07880008E000D258979337 -:10A21000FFFC8396FF2C000000019393FFFC8396C4 -:10A22000FF3C000000019393FFFC23940098939659 -:10A23000FF249393FFFC07880008E000CF24979346 -:10A24000FFFCF3820006F38542548702FF34F38655 -:10A2500038A8F3854244F7054264F384407C00004B -:10A2600000019393FFFC9713FFFC8396FF240000EB -:10A2700000019393FFFC8396FF3400000001939349 -:10A28000FFFC07880008E000F7C89793FFFC202236 -:10A290000000E600A2A9F3821770F7044254000000 -:10A2A000000127380001F70542549393FFFCF38225 -:10A2B000001B9393FFFCF38642449393FFFC0788B3 -:10A2C0000008E0011EC09793FFFC8796FFFC829672 -:10A2D000FFF802140000013C00000000000192930E -:10A2E000FFFC02900008F6046F34F704426486B263 -:10A2F000000400000001C0367200E600A3AC06B006 -:10A3000000028736000076B5001E76B4FFE5C73838 -:10A310006FC0F684407C7739FFF0C03A6A00E600EF -:10A32000A3ACC7346800F5844074F6044F580000AD -:10A330000001C62C62007630FFFAC5AC700005AC97 -:10A34000002686AE0000772D001E7738FFE54631E7 -:10A350000000C6B477C076B5FFF0F70200FFC63044 -:10A360007400F702FF00C6B47400C6306800F62F10 -:10A370002800F50642449513FFFC07880008E00119 -:10A380001F489793FFFCF704407C0000000107384A -:10A3900000019713FFFCF5044074000000019513C1 -:10A3A000FFFC07880008E000BEF89793FFFC879643 -:10A3B000FFFC8296FFF802140000013C0000000040 -:10A3C00000019293FFFC0290000822100080F70425 -:10A3D000425800000001203A0000E600A3F4203AB1 -:10A3E0000007F5020001F5054258F7044258000045 -:10A3F0000001203A0007EE00A6F02394001EF604A8 -:10A40000426023140066F4844078063000028732EC -:10A41000000076B1001E76B4FFE504A400027425A6 -:10A42000001E7420FFE5063000027531001E7528FD -:10A43000FFE59516FF7CC7386FC07738FFF025140D -:10A4400000209516FF94F72B280087320000851610 -:10A45000FF7C05A40002C73857C07738FFF0F71F0C -:10A4600028002394001C063000028732000076B1D9 -:10A47000001E76B4FFE525140050C7386FC077384A -:10A48000FFF0F71F28002394001A063000028732DD -:10A49000000076B1001E76B4FFE5C7386FC077388C -:10A4A000FFF0F71F280023940018063000028732BF -:10A4B000000076B1001E76B4FFE5C7386FC077386C -:10A4C000FFF0F71F280023940016063000028732A1 -:10A4D000000076B1001E76B4FFE5C7386FC077384C -:10A4E000FFF0F71F28002394001406300002873283 -:10A4F000000076B1001E76B4FFE5C7386FC077382C -:10A50000FFF0F71F28002394001206300002873264 -:10A51000000076B1001E76B4FFE5C7386FC077380B -:10A52000FFF0F71F28002394001006300002873246 -:10A53000000076AD001E7631001E7630FFE5C7388C -:10A5400067C07738FFF0F71F280087260000261421 -:10A550000068C73847C07738FFF0F7332800872EE8 -:10A56000000076B4FFE5C7386FC07738FFF0F71BFF -:10A5700028002314006405AC0002872E000076AD8D -:10A58000001E76B4FFE5C7386FC07738FFF0F71BC1 -:10A5900028002314006205AC0002872E000076AD6F -:10A5A000001E76B4FFE5C7386FC07738FFF0F71BA1 -:10A5B00028002314006005AC0002872E000076AD51 -:10A5C000001E76B4FFE5C7386FC07738FFF0F71B81 -:10A5D00028002314005E05AC0002872E000076AD33 -:10A5E000001E76B4FFE5C7386FC07738FFF0F71B61 -:10A5F00028002314005C05AC0002872E000076AD15 -:10A60000001E76B4FFE5C7386FC07738FFF0F71B40 -:10A6100028002314005A05AC0002872E000076ADF6 -:10A62000001E76B4FFE5C7386FC07738FFF0F71B20 -:10A63000280005AC0002872E00002314005875ADD9 -:10A64000001E75ACFFE5C7385FC07738FFF0F71B19 -:10A6500028009613FFFC9516FF8C9513FFFC0788C6 -:10A660000008E000D2589793FFFC8516FF8C00008D -:10A6700000019513FFFCF5044258000000019513FA -:10A68000FFFC251400389516FF849513FFFC0788FE -:10A690000008E000CF249793FFFCF5044258000027 -:10A6A00000019513FFFCF5044264000000019513BE -:10A6B000FFFC8516FF84000000019513FFFC851642 -:10A6C000FF94000000019513FFFC07880008E000DC -:10A6D000F7C89793FFFC20220000E600A6F10000D7 -:10A6E0000001F70442580000000107380001F70597 -:10A6F0004258F704425800000001203A0007EE00DB -:10A70000A730F5021770F7042D38F6862C28063886 -:10A710000001F6052D3877390002F502001C2032C1 -:10A720000044E600A750B53A6802E000A750F005E3 -:10A730002D389513FFFCF502001B9513FFFCF50661 -:10A7400042449513FFFC07880008E0011EC0979360 -:10A75000FFFC8796FFFC8296FFF802140000013C84 -:10A760000000000000019293FFFC029000082210FC -:10A770000030F6046F34F704426486B2000400002F -:10A780000001C0367200E600A9F007300002863AE8 -:10A790000000F5820000F684407C7739001E77388F -:10A7A000FFE5C63077C0F7044074C6B46800763160 -:10A7B000FFF0C60062009616FFF4C738680007383D -:10A7C000002686BA00007739001E7738FFE5C6B448 -:10A7D00077C077B40008703EFFE8470C0001D7004F -:10A7E0000A70203A0000E600A834F60200FF831643 -:10A7F000FFF48396FFF4F7044078C6983800C73812 -:10A8000068000738002686BA00007739001E7738BE -:10A81000FFE5C6B477C076B5FFF0C6B46400C036B5 -:10A820005A00470C0001D7000A70203A0000E600E9 -:10A83000A83D202E0000F5820001202E0000E60039 -:10A84000A875F606427CF704427C76B1001E76B409 -:10A85000FFE5C7386FC07739FFF007380001F733DD -:10A86000280007880008E000789C9793FFFCE00030 -:10A87000A9F000000001F3044260000000019313FE -:10A88000FFFC07880008E000CC609793FFFCF4040D -:10A890004078F7044F58F5044074F384407CF30487 -:10A8A000407CC62072007630FFFAC59C3000C5A8F7 -:10A8B000580005AC002686AE000074AD001E74A4DE -:10A8C000FFE573AD001E739CFFE59396FFD4C5288A -:10A8D00072007528FFFA8316FFF48396FFF4463161 -:10A8E000000045290000C7183800C420700004206B -:10A8F00000267321001EC6B44FC076B5FFF0F48267 -:10A9000000FFC6304C00F382FF00C6B43C00C630E6 -:10A910006800F62F2800872E00007318FFE59316B5 -:10A92000FFCC8316FFD48396FFF4C5284C00C738AC -:10A9300037C07739FFF0769D001076B5FFF8C7383D -:10A940004C00C6B47000F6AF28008722000076A144 -:10A95000001E8316FFCCF382FF0076B4FFE5C738F4 -:10A9600037C07739FFF0C7383C00C5287000F523A1 -:10A97000280087220000F304407CC7386FC0773975 -:10A98000FFF0731900109316FFEC7399FFF8C738A6 -:10A990004C00C71C70009716FFDC23140022831A9A -:10A9A00000007799001E77BCFFE5C3187FC07319BC -:10A9B000FFF0F3232800F38642449393FFFC0788BB -:10A9C0000008E0011F489793FFFCF704407C00005B -:10A9D0000001073800019713FFFCF30440740000E6 -:10A9E00000019313FFFC07880008E000BEF897936E -:10A9F000FFFC8796FFFC8296FFF802140000013CE2 -:10AA00000000000000019293FFFC02900008221059 -:10AA10000098F30642449313FFFC07880008E00106 -:10AA200020E49793FFFC20220000E600AEE5000042 -:10AA30000001F704425400000001203A0000EE003B -:10AA4000AD8927380001F70542542394001EF6040F -:10AA50004260249400669496FF64F3044078249442 -:10AA600000209496FF94063000028732000076B1F1 -:10AA7000001E76B4FFE5031800029316FF747419E4 -:10AA8000001E7420FFE505980002063000027531B3 -:10AA9000001EC7386FC07738FFF0F72728008732CD -:10AAA00000007528FFE5C73857C07738FFF0F71F5B -:10AAB00028002394001C063000028732000076B183 -:10AAC000001E76B4FFE58516FF64C7386FC077387F -:10AAD000FFF0F71F28002394001A06300002873287 -:10AAE000000076B1001E76B4FFE5C7386FC0773836 -:10AAF000FFF0F71F28002394001806300002873269 -:10AB0000000076B1001E76B4FFE5C7386FC0773815 -:10AB1000FFF0F71F2800239400160630000287324A -:10AB2000000076B1001E76B4FFE5C7386FC07738F5 -:10AB3000FFF0F71F2800239400140630000287322C -:10AB4000000076B1001E76B4FFE5C7386FC07738D5 -:10AB5000FFF0F71F2800239400120630000287320E -:10AB6000000076B1001E76B4FFE5C7386FC07738B5 -:10AB7000FFF0F71F280023940010063000028732F0 -:10AB8000000076AD001E7631001E7630FFE5C73836 -:10AB900067C07738FFF0F71F2800871A00002614D7 -:10ABA0000068C73847C07738FFF0F7332800872E92 -:10ABB000000076B4FFE5C7386FC07738FFF0F72B99 -:10ABC0002800231400649316FF6405AC0002872E4E -:10ABD000000076AD001E76B4FFE5C7386FC0773849 -:10ABE000FFF0F71B2800249400629496FF6405ACE4 -:10ABF0000002872E000076AD001E76B4FFE5C73850 -:10AC00006FC07738FFF0F7272800251400609516ED -:10AC1000FF6405AC0002872E000076AD001E76B4FE -:10AC2000FFE5C7386FC07738FFF0F72B28002314F3 -:10AC3000005E9316FF6405AC0002872E000076AD1F -:10AC4000001E76B4FFE5C7386FC07738FFF0F71BFA -:10AC500028002494005C9496FF6405AC0002872EC3 -:10AC6000000076AD001E76B4FFE5C7386FC07738B8 -:10AC7000FFF0F72728002514005A9516FF6405AC4D -:10AC80000002872E000076AD001E76B4FFE5249406 -:10AC90000050C7386FC07738FFF0F72B2800231417 -:10ACA000005805AC0002872E00009316FF6475ADB6 -:10ACB000001E75ACFFE5C7385FC07738FFF0F71BA3 -:10ACC00028009613FFFC9496FF8C9493FFFC078852 -:10ACD0000008E000D2589793FFFC8516FF8C2314E0 -:10ACE00000389513FFFC278000079793FFFC93160D -:10ACF000FF849313FFFC07880008E000CF2497939C -:10AD0000FFFC27800007F7854258278000079793AC -:10AD1000FFFCF4844264000000019493FFFC85165C -:10AD2000FF84000000019513FFFC8316FF940000D0 -:10AD300000019313FFFC07880008E000F7C8979311 -:10AD4000FFFC20220000E600AD5D00000001F704DA -:10AD500042580000000107380001F7054258F70487 -:10AD60002D38F6862C2806380001F6052D3877395F -:10AD70000002F482001C20320044E600AEE4B4BAC3 -:10AD80006802E000AEE4F0052D38F7044078F58461 -:10AD90004F580738001686BA0000F4063B90773902 -:10ADA000001E7738FFE5C6B477C076B4FFF076357D -:10ADB0000006A72E6002C52C600076A9001E76B49E -:10ADC000FFE5C7386FC07739FFF077390003C73820 -:10ADD00040000738000286BA00007739001E773835 -:10ADE000FFE5C6B477C073B7FFF0EE00AE55951619 -:10ADF000FF64A72E600276A9001E76B4FFE5C7386F -:10AE00006FC07739FFF077390003C738400086BA42 -:10AE10000004231400887739001E7738FFE5C6B494 -:10AE200077C076B5FFF0A6AA6802771D0003C73881 -:10AE3000680027380008853A000484BA0000000042 -:10AE40000001951A0004949A00008596FF7CE000AA -:10AE5000AE78000000018496FF64A72E600276A5FC -:10AE6000001E76B4FFE5C7386FC07739FFF0773939 -:10AE70000003C738400085BA00048516FF64F60653 -:10AE80003B90872A000076A9001E76B4FFE5C738FC -:10AE90006FC07739FFF077390003A6BA6002201E31 -:10AEA0000000C73860007739001E7738FFE5C6B468 -:10AEB00077C0EE00AEC976B5FFF08316FF780000CC -:10AEC00000017719FFF0C6B868008496FF6400009F -:10AED0000001C72468009713FFFC07880008C12CF5 -:10AEE00000009793FFFC8796FFFC8296FFF8021400 -:10AEF0000000013C0000000000019293FFFC029062 -:10AF0000000822100010F704408400000001203ADD -:10AF10000000E600AF3CF60642B8F70442B876B14E -:10AF2000001E76B4FFE5F3063678F3054244C738D1 -:10AF30006FC07739FFF007380001F7332800F704B6 -:10AF40004F5CF384425C833A0004C43800009316DB -:10AF5000FFEC771D0001C73838007739000204B8CC -:10AF6000000C8316FFEC00000001C01E3200EC0054 -:10AF7000B070C5040000A6A24802F704E000F58204 -:10AF80000000C0367200E600AFA8C620480086B2B6 -:10AF90000004F704E00400000001C0367200E6007F -:10AFA000AFAC202E0000F5820001202E0000E6004C -:10AFB000AFB900000001F502000086B20000F704FE -:10AFC000E00000000001C0367200E200AFF4F5823C -:10AFD0000000C0367200E600AFFC202E000086B2F2 -:10AFE0000004F704E00400000001C0367200E20033 -:10AFF000AFFD202E0000F5820001202E0000E600AB -:10B00000B00D202A0000F5020001202A0000E60011 -:10B01000B05900000001F7047AD000000001203A86 -:10B020000000E600B064C7204800873A0008F60632 -:10B03000409877390002A6BA6002C73860007739B5 -:10B04000001E7738FFE5C6B477C076B5FFF020362E -:10B050000000E600B0640000000104A4000CE00061 -:10B06000AF60039C00018316FFEC00000001C01ECE -:10B070003200EC00B104F3063678F6844F5C771D9D -:10B080000001C7383800773900020738000CC6B411 -:10B09000700087360008F6844F5877390006C6B42A -:10B0A00070009693FFFC9396FFF407880008E00079 -:10B0B000FA989793FFFC20220000F684426C839656 -:10B0C000FFF4470C0001D7000A70C71C7000F70599 -:10B0D000425C06B40001F7042D38F685426CF68612 -:10B0E0002C2806380001F6052D3877390002F302C6 -:10B0F000001C20320044E600B108B33A6802E000C8 -:10B10000B108F0052D38F30542448796FFFC82967E -:10B11000FFF802140000013C0000000000019293BF -:10B12000FFFC02900008F4020000C5A00000F682B7 -:10B130000770F7046E5020360000E600B16D063847 -:10B14000001C8732000000000001C4207000C022F3 -:10B150007200E400B15D0000000105AC000126B4FE -:10B16000000120360000E600B14006300004C42093 -:10B170005800C0225A00E400B18100000001042000 -:10B1800000018796FFFC8296FFF802140000013C44 -:10B190000000000000019293FFFC02900008078865 -:10B1A0000008E00078D89793FFFC07880008E000CB -:10B1B000B11C9793FFFCF704409400000001C022EB -:10B1C0007200E600B1EDF4054090F7046E50000007 -:10B1D000000186BA1DDCF582000106B4000196BAB2 -:10B1E0001DDC873A1DDCE000B1F0F5857AD0F00572 -:10B1F0007AD0F5844090F0054084F5854094F5863A -:10B20000E0009593FFFC07880008E000D5A0979325 -:10B21000FFFCF7046E50F405408485BA1DDC000085 -:10B220000001F5853B64F584E000F005425C95BAC9 -:10B230000010F584E004F6862C2895BA0014F70473 -:10B240002D38F5863A4CF585424406380001F6055E -:10B250002D3877390002F582001C20320044E600C8 -:10B26000B268B5BA6802F0052D38F58635ECF5857B -:10B2700042308796FFFC8296FFF802140008013CDA -:10B280000000000000019293FFFC029000082210D1 -:10B2900000C8F30200009316FF94248000089496DF -:10B2A000FF84238000078316FF940000000193169B -:10B2B000FF54201E0007EE00B564C71C38008496BA -:10B2C000000000000001C72470000738002686BA7D -:10B2D0000000F5844F587739001E7738FFE5C6B473 -:10B2E00077C076B5FFF0F70200FFC6B67400E6003F -:10B2F000B32D20360001E600B32D77350006A6BA3F -:10B300005802C73858007639001E7630FFE5C6B4BB -:10B3100067C076B5FFF020360002E600B331C6B84C -:10B320000000C72C0000E000B330C6B80000F6846F -:10B330004F58F7044F58C5340000C02A7200E60089 -:10B34000B55D00000001F6843BBCF30200009316DB -:10B35000FF3C0428001CF7043BB800000001C03685 -:10B360007200EC00B4409696FFAC77350001C73808 -:10B37000680077390002F4863BB4C63848000630CE -:10B38000000CC30400009316FF3486B20000872A25 -:10B39000001C8596FF3CC0367200E600B3C0202E2C -:10B3A000000086B20004872A002000000001C03699 -:10B3B0007200E600B3C0202E0000F5820001202EAE -:10B3C0000000E600B3D100000001F4820000949672 -:10B3D000FF3486B200008722000000000001C03662 -:10B3E0007200E200B40CF5820000C0367200E60084 -:10B3F000B414202E000086B200048722000400004E -:10B400000001C0367200E200B415202E0000F58263 -:10B410000001202E0000E600B42500000001F30228 -:10B4200000019316FF348496FF34000000012026AB -:10B430000000E600B44000000001F3020001931692 -:10B44000FF3C8496FF3C0000000120260000E6003F -:10B45000B481F60200018716FFACF3063BB476B95F -:10B460000001C6B4700076B50002C6B4300006B460 -:10B47000001486B600009716FFB0E000B4F496966C -:10B48000FFB4271400549713FFFC9413FFFCF486B9 -:10B490003BB49493FFFC9396FF4C9516FF440788AA -:10B4A0000008E00125689793FFFC8396FF4C851602 -:10B4B000FF4420220000E600B4F1F60200018716E6 -:10B4C000FFACF3063BB476B90001C6B4700076B5A4 -:10B4D0000002C6B4300006B4001486B60000971609 -:10B4E000FFB09696FFB4F7053BBCE000B4F82032FD -:10B4F0000000F602000020320000E600B52D2714FF -:10B5000000088496FF5400000001C72470008316D1 -:10B51000FFB404A400049496FF548496FF94933AD5 -:10B52000FFC004A40001E000B5549496FF94831674 -:10B53000FF5400000001C7187000F4844F5803182E -:10B5400000049316FF548316FF9494BAFFC00318A7 -:10B5500000019316FF949516FF3C9396FF8CE00034 -:10B56000B2B0039C00018496FF94000000012026E5 -:10B570000000E600B584F3820001F4044F58E000B7 -:10B58000BEE4000000018316FFB88496FF9400001B -:10B590000001C01E4A00EC00B5CC9316FF7C269437 -:10B5A00000048736FFC08316FF7C00000001C03A0C -:10B5B0003200E600BB98039C00018496FF940000D3 -:10B5C0000001C01E4A00EC00B5A106B40004F4045A -:10B5D0004F588316FF7C00000001C01A4200E600AD -:10B5E000BA2DF48200009496FF7423800007201E79 -:10B5F0000007EE00B748C71C38008316FF7C000028 -:10B600000001C71870000738002686BA0000F584CC -:10B610004F587739001E7738FFE5C6B477C076B546 -:10B62000FFF0F70200FFC6B67400E600B6692036E8 -:10B630000001E600B66977350006A6BA5802C73899 -:10B6400058007639001E7630FFE5C6B467C076B57F -:10B65000FFF020360002E600B66DC6B80000C72C29 -:10B660000000E000B66CC6B80000F6844F58F7043E -:10B670004F58C5340000C02A7200E600B741C584A7 -:10B6800000008496FF7486AA001C8316FF3CF60215 -:10B69000000004A400019496FF74871A001C04A8FB -:10B6A000001C9496FF34C0367200E600B6CC041835 -:10B6B000001C86AA0020871A002000000001C03666 -:10B6C0007200E600B6D020320000F60200012032FF -:10B6D0000000E600B6DD00000001F58200008316E0 -:10B6E000FF3487220000869A000000000001C03667 -:10B6F0007200E200B71CF6020000C0367200E600DD -:10B70000B72420320000869A00048722000400003B -:10B710000001C0367200E200B72520320000F602B8 -:10B72000000120320000E600B735202E0000F5822F -:10B730000001202E0000E600B740000000019396B3 -:10B74000FF84E000B5EC039C00018496FF7483162F -:10B75000FF9400000001C0263200E600BB982300E1 -:10B7600000088496FF8400000001C0263200E60035 -:10B77000BB99F6020000F684407CF7044074C6B41E -:10B780006800C73868000738002686BA0000773995 -:10B79000001E7738FFE5C6B477C077B40008703E66 -:10B7A000FFE8470C0001D7000A70203A0000E600CD -:10B7B000B804F58200FF8496FF848316FF8C000096 -:10B7C0000001C72432008496FF7CC7387000C7246C -:10B7D00070000738002686BA00007739001E7738D7 -:10B7E000FFE5C6B477C076B5FFF0C6B45C00C036DE -:10B7F0006200470C0001D7000A70203A0000E60002 -:10B80000B80D20320000F602000120320000E600F0 -:10B81000BB9823800007201E0007EE00B8C8C71C95 -:10B8200038008316000000000001C71870000738B8 -:10B83000002686BA0000F5844F587739001E773805 -:10B84000FFE5C6B477C076B5FFF0F70200FFC6B6D5 -:10B850007400E600B89120360001E600B891773513 -:10B860000006A6BA5802C73858007639001E76304E -:10B87000FFE5C6B467C076B5FFF020360002E600EB -:10B88000B895C6B80000C72C0000E000B894C6B850 -:10B890000000F6844F58F7044F58C5340000C02A02 -:10B8A0007200E600B8C1000000019513FFFC9396FA -:10B8B000FF4C07880008E000CC609793FFFC83965C -:10B8C000FF4CE000B814039C00018496FF848316AB -:10B8D000FF8CF384407CF5044074C4A43200949639 -:10B8E000FF348316FF34C59C3800C5A8580005AC4A -:10B8F000002686AE0000772D001E7738FFE5742DF8 -:10B90000001E7420FFE5739D0010739DFFF8C4A412 -:10B9100030009496FF3C8316FF7CC6B477C0C49871 -:10B9200048009496FF3C04A400269496FF3C73259F -:10B93000001E7318FFE59316FF6C74A5001E949605 -:10B94000FF6474A4FFE59496FF648316FF7CF4847F -:10B950004F5876B5FFF0C6184A007630FFFA4631E8 -:10B960000000F30200FFC6303400F482FF00C6B4CA -:10B970004C00C6306800F62F2800872E0000831682 -:10B98000FF34C73847C07739FFF07319001093169A -:10B99000FF347499FFF8F30200FFC7383400C7245E -:10B9A00070009716FF34249400CA84A6000077A57F -:10B9B000001E77BCFFE5C4A47FC074A5FFF083160A -:10B9C000FF3CF4AF2800F4844F58871A0000C528C4 -:10B9D0004A007528FFFA8316FF6C45290000F4829F -:10B9E00000FFC5284C008496FF3CC73837C0773924 -:10B9F000FFF0F302FF00C7383400C5287000F527B8 -:10BA00002800872600008316FF648416FF7CC73851 -:10BA100037C07739FFF0F48200FFC7384C00831637 -:10BA2000FF3CC39C7000E000BEE4F39B2800F704D9 -:10BA3000407CF6044074C7387000C7307000073887 -:10BA4000002686BA00007739001E7738FFE5C6B4B5 -:10BA500077C077B40008703EFFE8470C0001D700BC -:10BA60000A70203A0000E600BA7D25800007E00059 -:10BA7000BEE404200040E000BAD8C42C0000C73067 -:10BA80004200849600007538FFFA0624000A202E32 -:10BA90000007EE00BAD40730000E86BA00007739EE -:10BAA000001E7738FFE5C6B477C076B5FFF0F70221 -:10BAB00000FFC6B4740047290000C0367200470C6E -:10BAC0000001203A0000E600BA7406300002E000EF -:10BAD000BA8C05AC0001F402000807200007203AE8 -:10BAE000000EE200BBA4C5A0400083160000F504D0 -:10BAF000407CF48200FFF6044F58C598580005AC0E -:10BB0000002686AE0000772D001E7738FFE5C618A8 -:10BB100062007630FFFA46310000C6304C00C6B4F1 -:10BB200077C076B5FFF0772900107739FFF8C6B4F3 -:10BB30004C00C7386800F72F2800F5844074C528EA -:10BB40005000C5AC500005AC002686AE0000772D35 -:10BB5000001E7738FFE5752D001E7528FFE5C6B479 -:10BB600077C076B5FFF0F702FF00C6B47400C630A8 -:10BB70006800F62F2800872E000076A1001076B509 -:10BB8000FFF8C73857C07739FFF0C7384C00C6B444 -:10BB90007000E000BBF8F6AF2800F4044F58E00056 -:10BBA000BEE404200040F6044F5883160000F7045A -:10BBB000407CF5844074C61862007630FFFAC738BE -:10BBC0007000C5AC700005AC002686AE0000772D75 -:10BBD000001E7738FFE546310000C6B477C076B561 -:10BBE000FFF0F70200FFC6307400F702FF00C6B492 -:10BBF0007400C6306800F62F280023800007201E3E -:10BC00000007EE00BEE0C71C38008496000000006C -:10BC10000001C72470000738002686BA0000F584AA -:10BC20004F587739001E7738FFE5C6B477C076B530 -:10BC3000FFF0F70200FFC6B67400E600BC792036BC -:10BC40000001E600BC7977350006A6BA5802C7386D -:10BC500058007639001E7630FFE5C6B467C076B569 -:10BC6000FFF020360002E600BC7DC6B80000C72CFD -:10BC70000000E000BC7CC6B80000F6844F58F70412 -:10BC80004F58C5340000C02A7200E600BED906A88D -:10BC9000001C83160000000000019313FFFC969324 -:10BCA000FFFCF4863BB49493FFFC9396FF4C9516EF -:10BCB000FF449696FF4007880008E00123409793D1 -:10BCC000FFFCF3044F5CF48200009496FF5C8696C0 -:10BCD000FF408396FF4C8516FF449316FF34861A67 -:10BCE00000089696FF3C871A000400000001C0324D -:10BCF0007200EC00BDB89616FF9C77310001C73882 -:10BD0000600077390002C63830000630000C86B279 -:10BD10000000872A001C8596FF5CC0367200E60092 -:10BD2000BD40C404000086B20004872A0020000041 -:10BD30000001C0367200E600BD44202E0000F582EE -:10BD40000001202E0000E600BD5100000001F402B9 -:10BD500000008316FF3C86B20000871A0000000036 -:10BD60000001C0367200E200BD90F5820000C036CE -:10BD70007200E600BD98202E000086B20004871AEB -:10BD8000000400000001C0367200E200BD99202EC0 -:10BD90000000F5820001202E0000E600BDA920224F -:10BDA0000000F402000120220000E600BDB80000FF -:10BDB0000001F48200019496FF5C8316FF5C000092 -:10BDC0000001201A0000E600BDF9F6020001871606 -:10BDD000FF9C8496FF3476B90001C6B4700076B536 -:10BDE0000002C6B4480006B4001486B600009716D8 -:10BDF000FFA0E000BE709696FFA42714006497137E -:10BE0000FFFC8316FF3C000000019313FFFC8496A7 -:10BE1000FF34000000019493FFFC9396FF4C9516AD -:10BE2000FF4407880008E00125689793FFFC83968C -:10BE3000FF4C8516FF4420220000E600BE71F6028A -:10BE400000008716FF9C8316FF3476B90001C6B444 -:10BE5000700076B50002C6B4300006B4001486B691 -:10BE600000009716FFA09696FFA4971A0008F60206 -:10BE7000000120320000E600BE99F606429CF7045D -:10BE8000429C76B1001E76B4FFE5C7386FC07739A3 -:10BE9000FFF007380001F7332800F7044F5800007F -:10BEA0000001C72872007738FFFA4739000097135E -:10BEB000FFFC0728001C9713FFFCF4844F5C000074 -:10BEC00000019493FFFC9396FF4C07880008E00163 -:10BED00023409793FFFC8396FF4CE000BBFC039C40 -:10BEE0000001841600008796FFFC8296FFF802147A -:10BEF0000004013C0000000000019293FFFC02904E -:10BF0000000822100060851600008616000406A8AE -:10BF10000018C7306000C5B8680020320007EE0086 -:10BF2000BF64072C000E86BA00007739001E7738F0 -:10BF3000FFE5C6B477C076B5FFF0F70200FFC6B4E0 -:10BF4000740020360000470C0001D7000A70203A28 -:10BF50000000E600BF6105AC0002E000BF1806303B -:10BF6000000120320007EE00C04C06A80016F505BF -:10BF70004074F605407CF3020006F3054254961324 -:10BF8000FFFC052800029516FFC49513FFFC2394BF -:10BF900000209396FFBC9393FFFC9616FFAC078896 -:10BFA0000008E000D0DC9793FFFC8496FFC42314C4 -:10BFB00000389493FFFC9316FFB49313FFFC07889B -:10BFC0000008E000D2589793FFFC8702FF348616E2 -:10BFD000FFACF70542649613FFFC9713FFFC8396B2 -:10BFE000FFB4000000019393FFFC8496FFBC0000A7 -:10BFF00000019493FFFC07880008E000F7C89793BE -:10C00000FFFC20220000E600C01DF3063AD8F7042A -:10C0100042540000000127380001F7054254F3059F -:10C020004244F38217709393FFFCF482001B9493B5 -:10C03000FFFCF30642449313FFFC07880008E0016D -:10C040001EC09793FFFCE000C1A0000000018736EE -:10C050000000F5844F58F4063B7076B5001E76B4A8 -:10C06000FFE5C7386FC07738FFF076390006A72E96 -:10C070006002C52C600076A9001E76B4FFE5C738C3 -:10C080006FC07739FFF077390003C73840000738B1 -:10C09000000286BA00007739001E7738FFE5C6B483 -:10C0A00077C076B7FFF0EE00C1159696FF9CA72EDD -:10C0B000600276A9001E76B4FFE58396FF9CC73820 -:10C0C0006FC07739FFF077390003C738400086BA70 -:10C0D0000004249400607739001E7738FFE5C6B469 -:10C0E00077C076B5FFF0A6AA6802771D0003C738AF -:10C0F00068002738000883BA0004833A0000000073 -:10C10000000193A60004932600008596FFA4E0009A -:10C11000C13823000007A72E600276A9001E76B45E -:10C12000FFE5C7386FC07739FFF077390003C738AC -:10C13000400085BA0004230000079313FFFC872A00 -:10C14000000076A9001E76B4FFE58396FF9CF606F4 -:10C150003B70C7386FC07739FFF077390003A6BA54 -:10C160006002201E0000C73860007739001E773853 -:10C17000FFE5C6B477C0EE00C18D76B5FFF08496BA -:10C18000FFA0000000017725FFF0C6B86800C728AF -:10C1900068009713FFFC07880008C12C00009793E4 -:10C1A000FFFC8796FFFC8296FFF802140008013C12 -:10C1B0000000000000019293FFFC02900008221092 -:10C1C000007025000007202A0007EE00C3B8C7282A -:10C1D00050008316000000000001C71870000738E7 -:10C1E000002686BA0000F5844F587739001E77384C -:10C1F000FFE5C6B477C076B5FFF0F70200FFC6B61C -:10C200007400E600C23D20360001E600C23D7735ED -:10C210000006A6BA5802C73858007639001E763094 -:10C22000FFE5C6B467C076B5FFF020360002E60031 -:10C23000C24DC03A5A00E000C248C72C0000F704C3 -:10C240004F58F5844F5800000001C03A5A00E600EC -:10C25000C3B1F4863B908396000000000001069C69 -:10C2600000168736000076B5001E76B4FFE5C738A5 -:10C270006FC07738FFF076390006A72E6002C52C14 -:10C28000600076A9001E76B4FFE5C7386FC0773925 -:10C29000FFF077390003C73848000738000286BA34 -:10C2A00000007739001E7738FFE5C6B477C076B74F -:10C2B000FFF0EE00C3219696FF8CA72E600276A9B0 -:10C2C000001E76B4FFE58316FF8CC7386FC0773940 -:10C2D000FFF077390003C738480086BA0004249479 -:10C2E00000707739001E7738FFE5C6B477C076B5A1 -:10C2F000FFF0A6AA680277190003C738680027383C -:10C30000000883BA0004833A00000000000193A6ED -:10C310000004932600008616FF94E000C34400004A -:10C320000001A72E600276A9001E76B4FFE5F30691 -:10C330003B90C7386FC07739FFF077390003C738B3 -:10C340003000863A0004872A000076A9001E76B4E1 -:10C35000FFE58396FF8CF4863B90C7386FC0773932 -:10C36000FFF077390003A6BA4802201E0000C73844 -:10C3700048007739001E7738FFE5C6B477C0EE0075 -:10C38000C39576B5FFF08316FF9000000001771982 -:10C39000FFF0C6B86800C72868009713FFFC07883D -:10C3A0000008C13000009793FFFCE000C5C4000006 -:10C3B0000001E000C1C40528000183960000F4825A -:10C3C0000006F4854254F60442602514001E23142E -:10C3D00000209316FFACF3854078063000028732C8 -:10C3E000000076B1001E76B4FFE50630000275B19C -:10C3F000001EC7386FC07738FFF0F71B2800873260 -:10C40000000075ACFFE5C7385FC07738FFF0F72B49 -:10C4100028002514001C063000028732000076B187 -:10C42000001E76B4FFE5C7386FC07738FFF0F72BF2 -:10C4300028002514001A063000028732000076B169 -:10C44000001E76B4FFE5C7386FC07738FFF0F72BD2 -:10C45000280025140018063000028732000076B14B -:10C46000001E76B4FFE5C7386FC07738FFF0F72BB2 -:10C47000280025140016063000028732000076B12D -:10C48000001E76B4FFE5C7386FC07738FFF0F72B92 -:10C49000280025140014063000028732000076B10F -:10C4A000001E76B4FFE5C7386FC07738FFF0F72B72 -:10C4B000280025140012063000028732000076B1F1 -:10C4C000001E76B4FFE5C7386FC07738FFF0F72B52 -:10C4D0002800063000028732000025140010763153 -:10C4E000001E7630FFE5C73867C07738FFF0F72BBE -:10C4F0002800071C00029713FFFC2394005093961A -:10C50000FFA49393FFFC07880008E000D25897939C -:10C51000FFFC8496FFA4231400389493FFFC27802B -:10C5200000079793FFFC9316FF9C9313FFFC07886B -:10C530000008E000CF249793FFFC8702FF34278098 -:10C540000007F7854258F705426427800007979354 -:10C55000FFFC9713FFFC8396FF9C00000001939360 -:10C56000FFFC8496FFAC000000019493FFFC078859 -:10C570000008E000F5F49793FFFC20220000E6009D -:10C58000C59500000001F70442580000000107387B -:10C590000001F7054258F7042D38F30639C0F305BA -:10C5A0004244F6862C2806380001F6052D387739E6 -:10C5B0000002F382001C20320044E600C5C4B3BA76 -:10C5C0006802F0052D388796FFFC8296FFF802146A -:10C5D0000004013C0000000000019293FFFC029067 -:10C5E000000825000007F7044074F6844F58F6044D -:10C5F0004260C7386A0075B8FFFA0630000A202A80 -:10C600000007EE00C6480730000E86BA00007739F2 -:10C61000001E7738FFE5C6B477C076B5FFF0F702A5 -:10C6200000FFC6B47400472D0000C0367200470CEE -:10C630000001203A0000E600C64CC3280000063086 -:10C640000002E000C5FC05280001F3020008C5183F -:10C650003000F3844260F6044F58F704407CF484C1 -:10C660004074C51C50000528002685AA00007429C6 -:10C67000001E7420FFE5C61C62007630FFFAC6B8C3 -:10C680007000C4A4680004A4002676A5001E76B439 -:10C69000FFE5773900107739FFF846310000C5AC67 -:10C6A00047C075ADFFF0F40200FFC5AC4400C738C9 -:10C6B0005800F72B28008726000075A5001EC630FD -:10C6C000440075ACFFE5C7386FC07739FFF0F682DC -:10C6D000FF00C7386C00C6307000F6272800872698 -:10C6E00000007699001076B5FFF8C7385FC077393B -:10C6F000FFF0C7384400C6B47000F6A72800939333 -:10C70000FFFCF3843BB0000000019393FFFC07881B -:10C710000008E000D42C9793FFFCF704407C000055 -:10C720000001073800019713FFFCF38440740000F8 -:10C7300000019393FFFC07880008E000BEF8979380 -:10C74000FFFC8796FFFC8296FFF802140004013C70 -:10C750000000000000019293FFFC02900008879601 -:10C76000FFFC8296FFF802140008013C0000000064 -:10C7700000019293FFFC029000088796FFFC8296CE -:10C78000FFF802140004013C000000000001929335 -:10C79000FFFC029000088796FFFC8296FFF80214C7 -:10C7A0000000013C0000000000019293FFFC029099 -:10C7B0000008F70642309713FFFCF7063560971321 -:10C7C000FFFC07880008E00014F49793FFFCF706CD -:10C7D00042309713FFFCF70635EC9713FFFC0788F0 -:10C7E0000008E00014F49793FFFCF7064244971307 -:10C7F000FFFCF70636789713FFFC07880008E00077 -:10C8000014F49793FFFCF70642449713FFFCF706D6 -:10C8100037049713FFFC07880008E00014F497938F -:10C82000FFFCF70642449713FFFCF7063790971377 -:10C83000FFFC07880008E00014F49793FFFCF7065C -:10C8400042449713FFFCF706381C9713FFFC078838 -:10C850000008E00014F49793FFFCF7064244971396 -:10C86000FFFCF70638A89713FFFC07880008E000D4 -:10C8700014F49793FFFCF70642449713FFFCF70666 -:10C8800039349713FFFC07880008E00014F49793ED -:10C89000FFFCF70642449713FFFCF70639C09713D5 -:10C8A000FFFC07880008E00014F49793FFFCF706EC -:10C8B00042449713FFFCF7063A4C9713FFFC078896 -:10C8C0000008E00014F49793FFFCF7064244971326 -:10C8D000FFFCF7063AD89713FFFC07880008E00032 -:10C8E00014F49793FFFC8796FFFC8296FFF80214DE -:10C8F0000000013C0000000000019293FFFC029048 -:10C90000000885960000F5063B90872E000076AD66 -:10C91000001E76B4FFE5C7386FC07739FFF077396E -:10C920000003C73850000738000286BA0000773984 -:10C93000001E7738FFE5C6B477C07637FFF0EE000B -:10C94000C99500000001872E000076AD001E76B468 -:10C95000FFE5C7386FC07739FFF077390003C73874 -:10C96000500086BA00047739001E7738FFE5C6B458 -:10C9700077C076B5FFF0A6AE680277310003C738FE -:10C9800068002738000884BA0004843A0000E000F8 -:10C99000C9B4C5240000872E000076AD001E76B411 -:10C9A000FFE5C7386FC07739FFF077390003C73824 -:10C9B0005000853A0004872E000076AD001E76B444 -:10C9C000FFE520320000F6063B90C7386FC077398C -:10C9D000FFF077390003A6BA6002C73860007739E4 -:10C9E000001E7738FFE5C6B477C0EE00C9F976B50A -:10C9F000FFF07721FFF0C6B86800C72C68009713D6 -:10CA0000FFFC07880008C12800009793FFFC879669 -:10CA1000FFFC8296FFF802140004013C00000000B5 -:10CA200000019293FFFC0290000885960000F50635 -:10CA30003B70872E000076AD001E76B4FFE5C73848 -:10CA40006FC07739FFF077390003C73850000738D7 -:10CA5000000286BA00007739001E7738FFE5C6B4B9 -:10CA600077C07637FFF0EE00CABD00000001872EC8 -:10CA7000000076AD001E76B4FFE5C7386FC0773989 -:10CA8000FFF077390003C738500086BA00047739C1 -:10CA9000001E7738FFE5C6B477C076B5FFF0A6AEC6 -:10CAA000680277310003C73868002738000884BA65 -:10CAB0000004843A0000E000CADCC5240000872E90 -:10CAC000000076AD001E76B4FFE5C7386FC0773939 -:10CAD000FFF077390003C7385000853A0004839689 -:10CAE000000476AD001E76B4FFE52032000093937B -:10CAF000FFFC872E0000F6063B70C7386FC0773901 -:10CB0000FFF077390003A6BA6002C73860007739B2 -:10CB1000001E7738FFE5C6B477C0EE00CB2976B5A6 -:10CB2000FFF07721FFF0C6B86800C72C68009713A4 -:10CB3000FFFC07880008C12800009793FFFC879638 -:10CB4000FFFC8296FFF802140008013C0000000080 -:10CB500000019293FFFC02900008F5044F58F58203 -:10CB6000000206280080202E0062EE00CB900730E5 -:10CB70000040F0332800C6B8520076B4FFFA063001 -:10CB80000014F6B32800C6380000E000CB6405AC02 -:10CB90000001F7044F580000000106B818D4F482D1 -:10CBA0000001F4B72800073818C0F03B2800F7064A -:10CBB00042C0F4820002F4BB28008796FFFC8296F4 -:10CBC000FFF802140000013C0000000000019293F5 -:10CBD000FFFC02900008F68442C0F60642C077319E -:10CBE000001E7738FFE575B1001EC6B477C076B475 -:10CBF000FFF0F7044F5876B50006C4386800872266 -:10CC0000001476A1001E76B4FFE5C7386FC07738F0 -:10CC1000FFF0F7332800F70442C075ACFFE5C738D2 -:10CC20005FC07738FFF0203A0001E600CC4CF606F2 -:10CC30004290F704429076B1001E76B4FFE5C73803 -:10CC40006FC07739FFF007380001F7332800879667 -:10CC5000FFFC8296FFF802140000013C0000000077 -:10CC600000019293FFFC0290000822100004851638 -:10CC70000000000000019513FFFC9516FFF40788E3 -:10CC80000008E000CD009793FFFC8516FFF42022FA -:10CC90000000E600CCBCF58642C0F7044290F606E0 -:10CCA000429276B1001E76B4FFE5C7386FC077397F -:10CCB000FFF007380001E000CCECF7332800F02B40 -:10CCC0002800F68442C0772D001E7738FFE506283D -:10CCD0000014C6B477C076B4FFF0F7044F58F6B32B -:10CCE0002800C72872007738FFFAF72F28008796A8 -:10CCF000FFFC8296FFF802140004013C00000000D3 -:10CD000000019293FFFC0290000886960000F70451 -:10CD10004F58F4020000C6B472007734FFFA273887 -:10CD20000002203A0061F702003FE200CD40C6B4A5 -:10CD3000740020360000E600CD4000000001F4023F -:10CD400000018796FFFC8296FFF802140004013C64 -:10CD50000000000000019293FFFC0290000886167C -:10CD600000008716000885960004C5307000C032A8 -:10CD70005200E600CDA10000000186B2000077312C -:10CD8000001E7738FFE5C6B477C076B5FFE8F6AF8A -:10CD9000680006300001C0325200E600CD7805ACD4 -:10CDA00000018796FFFC8296FFF80214000C013CFC -:10CDB000000000000001000000009293FFFC0290C0 -:10CDC000000884960000841600048596000886A654 -:10CDD00000007725001E7738FFE5C6B477C07535AB -:10CDE000FFF0202A0010E200CE0DF606428EF5027A -:10CDF0000010F704428C76B1001E76B4FFE5C73808 -:10CE00006FC07739FFF007380001F7332800202E74 -:10CE10000001E600CE70202A0000EE00CE7107244B -:10CE2000000225280001A5BA50028622000076A142 -:10CE3000001E76B4FFE5C73850007739001E7738FA -:10CE4000FFE5C5AC77C0C6306FC07631FFF075AD79 -:10CE5000FFE8F68200FFF702F15475AD0002A72E3D -:10CE60007002C6306C00C6307580F623280024207E -:10CE7000000225A80001F302F24603A40002C4AC9C -:10CE80003800252C0001202E0000EC00CF110000FE -:10CE90000001E600CEA0C71C5000E000CEB4F602B0 -:10CEA0000000A69E50027739001E7738FFE5C6B411 -:10CEB00077C07635FFE886A600007725001E773814 -:10CEC000FFE52528000225AC0002C6B477C076B580 -:10CED000FFE877310004C738620077390001C738AE -:10CEE0003000C6B46800C6B4700006B4000E8736C1 -:10CEF000000024A4000276B5001E76B4FFE5C73812 -:10CF00006FC07738FFF0F7232800E000CE8424209C -:10CF100000028796FFFC8296FFF80214000C013C89 -:10CF20000000000000019293FFFC029000088616AA -:10CF3000000883160004839600008732000076B153 -:10CF4000001E76B4FFE5059C0002749D001E74A4CB -:10CF5000FFE5741D001E063000027531001EC73843 -:10CF60006FC07738FFF0F71F280087320000752860 -:10CF7000FFE5C73857C07738FFF0F72F280005AC1A -:10CF80000002063000028732000076B1001E76B43F -:10CF9000FFE5C7386FC07738FFF0F72F280005ACE2 -:10CFA0000002063000028732000076B1001E76B41F -:10CFB000FFE5C7386FC07738FFF0F72F280005ACC2 -:10CFC0000002063000028732000076B1001E76B4FF -:10CFD000FFE5C7386FC07738FFF0F72F280005ACA2 -:10CFE0000002063000028732000076B1001E76B4DF -:10CFF000FFE5C7386FC07738FFF0F72F280005AC82 -:10D000000002063000028732000076B1001E76B4BE -:10D01000FFE5C7386FC07738FFF0F72F280005AC61 -:10D020000002063000028732000076B1001E76B49E -:10D03000FFE5C7386FC07738FFF0F72F28000630BC -:10D0400000028732000005AC00027631001E763007 -:10D05000FFE5C73867C07738FFF0F72F2800871E35 -:10D0600000007420FFE5C7384FC07739FFF007385C -:10D070000001F71F2800871E0000049C0002C7382B -:10D0800047C07739FFF025380001202A0000EE0064 -:10D09000D0BD26280001A7266002C6A4600076B590 -:10D0A000001E76B4FFE5C5A45000C5300000C738A7 -:10D0B0006FC07739FFE8E000D088F72F6800071CC1 -:10D0C0000002F33B6800C41C00008796FFFC8296B8 -:10D0D000FFF80214000C013C0000000000019293D4 -:10D0E000FFFC0290000886160004841600008732B8 -:10D0F000000076B1001E76B4FFE505A0000274A121 -:10D10000001E74A4FFE5063000027531001EC7380A -:10D110006FC07738FFF0F7232800873200007528AA -:10D12000FFE5C73857C07738FFF0F72F280005AC68 -:10D130000002063000028732000076B1001E76B48D -:10D14000FFE5C7386FC07738FFF0F72F280005AC30 -:10D150000002063000028732000076B1001E76B46D -:10D16000FFE5C7386FC07738FFF0F72F280005AC10 -:10D170000002063000028732000076B1001E76B44D -:10D18000FFE5C7386FC07738FFF0F72F280005ACF0 -:10D190000002063000028732000076B1001E76B42D -:10D1A000FFE5C7386FC07738FFF0F72F280005ACD0 -:10D1B0000002063000028732000076B1001E76B40D -:10D1C000FFE5C7386FC07738FFF0F72F280005ACB0 -:10D1D0000002063000028732000076B1001E76B4ED -:10D1E000FFE5C7386FC07738FFF0F72F280005AC90 -:10D1F0000002063000028732000006A000027631ED -:10D20000001E7630FFE5C73867C07738FFF0F72F8C -:10D210002800872200007621001E85960008C73866 -:10D220004FC07739FFF0C6B47000F5B768008722A9 -:10D2300000007630FFE5C73867C07739FFF0073860 -:10D240000001F72328008796FFFC8296FFF802145E -:10D25000000C013C0000000000019293FFFC0290D2 -:10D2600000082210002027140020F03B280084969C -:10D270000004F502000086A600007625001E763028 -:10D28000FFE504240002C6B467C076B4FFF0F6BB25 -:10D2900028008726000076A5001E76B4FFE5C73873 -:10D2A0006FC07739FFF0C02A7200EC00D2F876A583 -:10D2B000001E8726000076B4FFE5062800012594AD -:10D2C000001EC5AC5000C5300000C7386FC07739AC -:10D2D000FFF0C7385200A6A27002C720700077394D -:10D2E000001E7738FFE5C6B477C076B5FFE8C68084 -:10D2F0006A00E000D290F6AF68008716FFE076156E -:10D30000001E7630FFE5839600002314001E7599F9 -:10D31000001E75ACFFE57515001E7528FFE57495B8 -:10D32000001E74A4FFE57415001E7420FFE5069C22 -:10D3300000027395001E9396FFDCC73867C0839682 -:10D3400000007738FFF0F71F28008396FFDC871A6C -:10D350000000739CFFE59396FFDCC7385FC0773809 -:10D36000FFF0F737280006B400028716FFE4231405 -:10D37000001A7619001E7630FFE5C73857C0773897 -:10D38000FFF0F7372800871A000006B40002C738FC -:10D3900067C07738FFF0F737280006B40002871619 -:10D3A000FFE8231400167619001E7630FFE5C73813 -:10D3B0004FC07738FFF0F7372800871A000006B40F -:10D3C0000002C73867C07738FFF0F737280006B487 -:10D3D00000028716FFEC231400127619001E763027 -:10D3E000FFE5C73847C07738FFF0F7372800871ABE -:10D3F000000006B4000284160000C73867C0773802 -:10D40000FFF0F73728008716FFF006B40002C73890 -:10D410003FC07738FFF0F73728008796FFFC8296E9 -:10D42000FFF802140008013C000000000001929384 -:10D43000FFFC029000088616000084160004F684A3 -:10D440004F5887320014033000147519001E7528D8 -:10D45000FFE5C3A06A00739CFFFA04A0001475A541 -:10D46000001EC6306A007630FFFAC73857C07738DA -:10D47000FFF0F7272800F39B280007200016F63B53 -:10D4800028008722001475ACFFE5C7385FC07738E5 -:10D49000FFF077390006C6B4700006B40016F3B783 -:10D4A00028008796FFFC8296FFF802140008013CD2 -:10D4B0000000000000019293FFFC02900008861615 -:10D4C0000000F5844F5805300016872A000076A921 -:10D4D000001E76B4FFE5C7386FC07738FFF07739A4 -:10D4E0000006C42C7000C0226200E600D52906A008 -:10D4F000001687360000C6305A007630FFFA76B53F -:10D50000001E76B4FFE5C7386FC07738FFF0773973 -:10D51000000676B8FFFAF6AB2800C72C7000073873 -:10D520000014E000D52CF63B2800C42C00008796A0 -:10D53000FFFC8296FFF802140004013C000000008A -:10D5400000019293FFFC02900008F7064F844738D1 -:10D55000FFFCF7056F30F686505C46B4FFFCF6859D -:10D560006E50F7066E7C4738FFFCF7056E540734A3 -:10D57000191CF7054F5CF70200649736191CF70277 -:10D5800000009736192006B4001CF6854F58879680 -:10D59000FFFC8296FFF802140000013C000000002E -:10D5A00000019293FFFC0290000822100090F30209 -:10D5B000FFFFF3054F54F38200009396FFAC231452 -:10D5C00000209316FF9C239400389396FF948316B3 -:10D5D000FFACF7044F5CF382000C9396FF74931634 -:10D5E000FF8C873A0004000000019716FFA4831601 -:10D5F000FFAC8396FFA400000001C01A3A00EC00C3 -:10D60000DB78F30204BCF7044F5C8316FF74000060 -:10D610000001C7383000873A0008F6844F58773940 -:10D620000006C4B470009493FFFC9496FF7C0788B6 -:10D630000008E000CD009793FFFC8496FF7C202239 -:10D640000000E600D654C5040000F7044288E0005C -:10D65000D87CF6064288F6044F5C83960000831659 -:10D66000FF74869E0000A7323002F5820000C036AB -:10D670007200E600D694C6303000869E00048732E1 -:10D68000000400000001C0367200E600D698202E8B -:10D690000000F5820001202E0000E600D6A5000063 -:10D6A0000001F50200008396000087320000869E8C -:10D6B000000000000001C0367200E200D6E4F582EE -:10D6C0000000C0367200E600D6EC202E0000869ED8 -:10D6D00000048732000400000001C0367200E2003E -:10D6E000D6ED202E0000F5820001202E0000E6007D -:10D6F000D6FD202A0000F5020001202A0000E600E5 -:10D70000D72804A400028316FFACF70642C883960C -:10D71000FF8CF3054F54C71C7000F03B28000738FE -:10D720000002E000DB50F03B28009496FF6C872657 -:10D73000000076A5001E76B4FFE58316FF6C839685 -:10D74000FF9C2494001E0618000275B1001E75ACE3 -:10D75000FFE5C7386FC07738FFF0F71F2800873222 -:10D760000000751D001E7528FFE5C7385FC07738BB -:10D77000FFF0F72728002494001C063000028732AF -:10D78000000076B1001E76B4FFE5C7386FC0773869 -:10D79000FFF0F72728002494001A06300002873291 -:10D7A000000076B1001E76B4FFE5C7386FC0773849 -:10D7B000FFF0F72728002494001806300002873273 -:10D7C000000076B1001E76B4FFE5C7386FC0773829 -:10D7D000FFF0F72728002494001606300002873255 -:10D7E000000076B1001E76B4FFE5C7386FC0773809 -:10D7F000FFF0F72728002494001406300002873237 -:10D80000000076B1001E76B4FFE5C7386FC07738E8 -:10D81000FFF0F72728002494001206300002873218 -:10D82000000076B1001E76B4FFE5C7386FC07738C8 -:10D83000FFF0F7272800063000028732000024940A -:10D8400000107631001E7630FFE5C73867C07738A4 -:10D85000FFF0F72728008716FFE0F682FFFCC738A5 -:10D8600057C07739FFF007380003C4B86C00202692 -:10D870000010E200D89DF606428AF704428876B18D -:10D88000001E76B4FFE5F4020000C7386FC0773998 -:10D89000FFF007380001E000DBA0F7332800831613 -:10D8A000FF6C251400368396FF94871A0000769942 -:10D8B000001E76B4FFE50618000275B1001EC738D9 -:10D8C0006FC07738FFF0F71F28008732000075AC73 -:10D8D000FFE5C7385FC07738FFF0F72B2800251425 -:10D8E0000034063000028732000076B1001E76B4A4 -:10D8F000FFE5C7386FC07738FFF0F72B28002514F5 -:10D900000032063000028732000076B1001E76B485 -:10D91000FFE5C7386FC07738FFF0F72B28002514D4 -:10D920000030063000028732000076B1001E76B467 -:10D93000FFE5C7386FC07738FFF0F72B28002514B4 -:10D94000002E063000028732000076B1001E76B449 -:10D95000FFE5C7386FC07738FFF0F72B2800251494 -:10D96000002C063000028732000076B1001E76B42B -:10D97000FFE5C7386FC07738FFF0F72B2800251474 -:10D98000002A063000028732000076B1001E76B40D -:10D99000FFE5C7386FC07738FFF0F72B2800251454 -:10D9A0000028063000028732000026A4000274A47A -:10D9B000FFFF7631001E7630FFE5C73867C0773845 -:10D9C000FFF0F72B28009013FFFC8316FF8CF7065F -:10D9D00042CCC7187000C73868009713FFFC9393B8 -:10D9E000FFFC9496FF7C07880008E000CDB8979371 -:10D9F000FFFC8396FF6C2414004E25140050831600 -:10DA0000FF8C8496FF7C871E0000769D001E76B4F6 -:10DA1000FFE5061C000275B1001E75ACFFE5C738B6 -:10DA20006FC07738FFF0F72B280087320000752988 -:10DA3000001E7528FFE5C7385FC07738FFF0F72371 -:10DA400028002414004C063000028732000076B112 -:10DA5000001E76B4FFE5C7386FC07738FFF0F723B4 -:10DA600028002414004A063000028732000076B1F4 -:10DA7000001E76B4FFE5C7386FC07738FFF0F72394 -:10DA8000280024140048063000028732000076B1D6 -:10DA9000001E76B4FFE5C7386FC07738FFF0F72374 -:10DAA000280024140046063000028732000076B1B8 -:10DAB000001E76B4FFE5C7386FC07738FFF0F72354 -:10DAC000280024140044063000028732000076B19A -:10DAD000001E76B4FFE5C7386FC07738FFF0F72334 -:10DAE000280024140042063000028732000076B17C -:10DAF000001E76B4FFE5C7386FC07738FFF0F72314 -:10DB000028000630000287320000241400407631DD -:10DB1000001E7630FFE5C73867C07738FFF0F7237F -:10DB200028008696FFB0F60642C8C6186000F702C5 -:10DB30000003C6B457C076B5FFF0C6B47400F70250 -:10DB40000004C7386A00F733280006300002F4B337 -:10DB500028008396FF8C8316FF74039C0014939611 -:10DB6000FF8C0318000C8396FFAC9316FF74039C84 -:10DB70000001E000D5EC9396FFAC9313FFFCF38417 -:10DB80004F5C000000019393FFFCF3064A98931347 -:10DB9000FFFC07880008E00126F89793FFFCF402D9 -:10DBA00000018796FFFC8296FFF802140004013CF6 -:10DBB0000000000000019293FFFC02900008221078 -:10DBC00001A0F5020000F3846E50F602001C202A2A -:10DBD0000063EE00DC08C59C6000A69E6002772D05 -:10DBE000001E7738FFE5C6B477C076B5FFF0203663 -:10DBF0000003E600DBFC072C0036F03B2800063073 -:10DC00000040E000DBCC05280001F5844F5C0000FB -:10DC1000000186AE0008F4020000872E0004000018 -:10DC20000001C0367200EC00DCF09696FFEC773510 -:10DC30000001C738680077390002C638580006303E -:10DC4000000CC38400008316000086B20000871A0F -:10DC5000000000000001C0367200E600DC7CC52038 -:10DC6000000086B20004871A000400000001C036DC -:10DC70007200E600DC80202A0000F5020001202A64 -:10DC80000000E600DC8D00000001F38200008496B5 -:10DC9000000086B200008726000000000001C036A8 -:10DCA0007200E200DCCCF5020000C0367200E60033 -:10DCB000DCD4202A000086B200048726000400007D -:10DCC0000001C0367200E200DCD5202A0000F50217 -:10DCD0000001202A0000E600DCE5201E0000F3829F -:10DCE0000001201E0000E600DCF420220000F40207 -:10DCF000000120220000E600DD29F602000187165F -:10DD0000FFEC0000000176B90001C6B4700076B5E2 -:10DD10000002C6B4580006B4001486B60000971678 -:10DD2000FFF0E000DD989696FFF427140014971397 -:10DD3000FFFC83160000000000019313FFFC959385 -:10DD4000FFFC9596FE7007880008E0012568979310 -:10DD5000FFFC8596FE7020220000E600DD95F602AD -:10DD600000018716FFEC0000000176B90001C6B47F -:10DD7000700076B50002C6B4580006B4001486B62A -:10DD800000009716FFF09696FFF4972E0008E0002B -:10DD9000DD9C20320000F602000020320000E60088 -:10DDA000DDB0F4820000F704427CE000E09CF6065F -:10DDB000427E9496FF448716FFF4F6044F58773955 -:10DDC0000006C73070009716FF5406B8001A873651 -:10DDD00000008316FF5476B5001E76B4FFE5C73801 -:10DDE0006FC09313FFFC7738FFF077390006C63019 -:10DDF00070009616FF4C07880008E000CD0097934E -:10DE0000FFFC20220000E600DE35F30200018496CC -:10DE1000FF4C000000019493FFFC07880008E0001D -:10DE2000CD009793FFFC20220000E600DE380000C2 -:10DE30000001F30200019316FF448496FF440000A2 -:10DE4000000120260000E600DE59F60642A4F70491 -:10DE500042A4E000E0A076B1001E8316FF4C8616B7 -:10DE6000FF4C871A00007699001E76B4FFE5C7388C -:10DE70006FC07739FFF0203A0002E600DE8500002F -:10DE80000001F6044F58F5844F5800000001C032DD -:10DE90005A00E600E025000000018496FF4C0000D7 -:10DEA000000106A4001A873600008316FF5476B5D9 -:10DEB000001E76B4FFE5C7386FC07738FFF07739BA -:10DEC0000006C72C7000C03A3200E600DEDDF60620 -:10DED0004280F7044280E000E0A076B1001E2614E4 -:10DEE0000030F03328008716FFD07631001E7630E0 -:10DEF000FFE58496FF4C2314002E9316FE6475995B -:10DF0000001E75ACFFE57515001E7528FFE573153D -:10DF1000001E7318FFE59316FF348316FE64042475 -:10DF2000000206A000027495001E74A4FFE59496FA -:10DF3000FF3C7495001EC73867C07738FFF0F723A1 -:10DF40002800871A000074A4FFE59496FF2CC738B8 -:10DF50005FC07738FFF0F737280006B40002871655 -:10DF6000FFD42494002A9496FE647625001E763011 -:10DF7000FFE5C73857C07738FFF0F7372800872606 -:10DF8000000006B40002C73867C07738FFF0F737E3 -:10DF9000280006B400028716FFD823140026931623 -:10DFA000FE647619001E8496FF3C7630FFE5C73884 -:10DFB0004FC07738FFF0F7372800871A000006B403 -:10DFC00000028496FF34C73867C07738FFF0F73710 -:10DFD000280006B400028716FFDC231400229316E3 -:10DFE000FE647619001E7630FFE5C7384FC07738DB -:10DFF000FFF0F7372800871A000006B40002C73880 -:10E0000067C07738FFF0F73728008716FFE08316E0 -:10E01000FF2C06B40002C73837C07738FFF0E000A5 -:10E02000EAA0F737280007880008E000CBCC9793D8 -:10E03000FFFC06A00002F7044F58F037280006A0A6 -:10E0400000149416FF24C72072007738FFFAF737C0 -:10E05000280006A00016F7372800F4820001F4A378 -:10E0600028009413FFFC07880008E000CD00979378 -:10E07000FFFC20220000E600E0BC26940048F704E4 -:10E080004280E000E09CF60642828696FEF4E000C4 -:10E09000E29400000001F7044284F606428476B15F -:10E0A000001E76B4FFE5F4020000C7386FC0773970 -:10E0B000FFF007380001E000EAA4F73328008316D8 -:10E0C000FF4C7515001E7528FFE59316FF1C0718F9 -:10E0D0000036F4820001F4BB2800F03728008716D0 -:10E0E000FFB876B5001E76B4FFE5041800020620DE -:10E0F0000002231400469316FF147599001E75AC98 -:10E10000FFE57495001E74A4FFE59496FF0C73154B -:10E11000001E7318FFE59316FF047495001E74A487 -:10E12000FFE59496FEFC230000079316FEF4849608 -:10E13000FF1C8316FF1404A4000A9496FE7CC738C3 -:10E140006FC07738FFF0F7232800F6844F58849685 -:10E15000FF54871A0000C6A46A007434FFFAC73857 -:10E160005FC07738FFF0F7332800063000028716CB -:10E17000FFBC231400429316FF147699001E76B458 -:10E18000FFE5C73857C07738FFF0F7332800871A04 -:10E19000000006300002C7386FC07738FFF0F73351 -:10E1A0002800063000028716FFC02494003E949693 -:10E1B000FF1476A5001E8316FF0C76B4FFE5C73862 -:10E1C00037C07738FFF0F733280087260000063085 -:10E1D0000002C7386FC07738FFF0F73328000630E9 -:10E1E00000028716FFC42494003A9496FF1476A583 -:10E1F000001E8316FF0476B4FFE5C73837C07738B2 -:10E20000FFF0F73328008726000006300002C738E9 -:10E210006FC07738FFF0F73328008716FFC8849661 -:10E22000FEFC06300002C7384FC07738FFF0F733E6 -:10E2300028008316FEF400000001201A0007EE00FB -:10E24000E294F68200088496FE7C00000001072418 -:10E25000000E86BA00007739001E7738FFE5C6B495 -:10E2600077C076B5FFF0F70200FFC6B4740047210F -:10E270000000C0367200470C0001203A0000E600A2 -:10E28000E08804A400029496FE7C03180001E000DC -:10E29000E2309316FEF48316FF1C000000010718FD -:10E2A0000038F6BB28009313FFFC8496FF2400007F -:10E2B00000019493FFFC07880008E000D42C97939A -:10E2C000FFFC231400789316FEBC849600002314F0 -:10E2D00000A886A60004872600009316FE9CC6B4FC -:10E2E00070009696FEECF7020001C7347400971692 -:10E2F000FEE48496FF24000000019493FFFC07884D -:10E300000008E000D4B49793FFFCF7044F580000D6 -:10E310000001C0227200E600EAA19416FF1C86A24A -:10E3200000387721001E7738FFE5F30200009316CE -:10E33000FED4C6B477C076B5FFF09696FEDC849620 -:10E34000FED4000000012026000EEE00E2F0F302F1 -:10E35000000F9313FFFC8316FEEC00000001C718AA -:10E3600048009713FFFC07880008E00127E897930F -:10E37000FFFCC3A000008496FEE4000000012026FC -:10E380000000E600E38D239C0007C3803A00C71C11 -:10E3900038008316FF1CF48200FFF6044F58C7189C -:10E3A00070000738002686BA00009716FEC4773939 -:10E3B000001E7738FFE5C6B477C076B5FFF0C6B467 -:10E3C0004C0076B50006C330680007300040C01A24 -:10E3D0007200E600E40D9316FECC9313FFFC9396B7 -:10E3E000FE749616FE6C9696FE6807880008E0009C -:10E3F000CD009793FFFC8396FE748616FE6C86967E -:10E40000FE6820220000E600E09500000001F5848F -:10E410004F588496FECC072C0040C0267200E600C0 -:10E42000EA8D00000001A732680276A5001E76B4CE -:10E43000FFE58616FECCC7386FC07739FFF0203A6B -:10E440000002E600E451C0325A00C62C0000C0327F -:10E450005A00E600E6E5251400768316FF1C849634 -:10E46000FEBC061800028732000076B1001E76B4AA -:10E47000FFE58316FEDC0630000275B1001EC738CA -:10E480006FC07738FFF0F72728008732000075AC9F -:10E49000FFE5C7385FC07738FFF0F72B2800251459 -:10E4A0000074063000028732000076B1001E76B498 -:10E4B000FFE5C7386FC07738FFF0F72B2800251429 -:10E4C0000072063000028732000076B1001E76B47A -:10E4D000FFE5C7386FC07738FFF0F72B2800251409 -:10E4E0000070063000028732000076B1001E76B45C -:10E4F000FFE5C7386FC07738FFF0F72B28002514E9 -:10E50000006E063000028732000076B1001E76B43D -:10E51000FFE5C7386FC07738FFF0F72B28002514C8 -:10E52000006C063000028732000076B1001E76B41F -:10E53000FFE5C7386FC07738FFF0F72B28002514A8 -:10E54000006A063000028732000076B1001E76B401 -:10E55000FFE5C7386FC07738FFF0F72B280006308B -:10E56000000287320000251400687631001E7630E4 -:10E57000FFE5C73867C07738FFF0F72B2800C71CC6 -:10E5800032009713FFFC9493FFFC2614006096134F -:10E59000FFFC9616FE6C07880008E000D0DC97931D -:10E5A000FFFC8716FFA08616FE6C8496FECC231413 -:10E5B000005E9316FE5C7599001E75ACFFE5741540 -:10E5C000001E7420FFE57315001E7318FFE59316F7 -:10E5D000FEAC8316FE5C7631001E7630FFE5052426 -:10E5E000000206A800027495001E74A4FFE594962C -:10E5F000FEB47495001EC73867C07738FFF0F72B5C -:10E600002800871A000074A4FFE59496FEA4C7387A -:10E610005FC07738FFF0F737280006B4000287168E -:10E62000FFA42494005A9496FE5C7625001E83165F -:10E63000FEB47630FFE5C73837C07738FFF0F737DC -:10E6400028008726000006B40002C73867C0773864 -:10E65000FFF0F737280006B400028716FFA82494BD -:10E6600000569496FE5C7625001E7630FFE5C7388E -:10E6700047C07738FFF0F73728008726000006B438 -:10E680000002C73867C07738FFF0F737280006B4B4 -:10E6900000028716FFAC231400529316FE5C761915 -:10E6A000001E8496FEAC7630FFE5C7384FC0773841 -:10E6B000FFF0F7372800871A000006B40002C738B9 -:10E6C00067C07738FFF0F73728008716FFB083164A -:10E6D000FEA406B40002C73837C07738FFF0E00068 -:10E6E000EA8CF73728008496FECC0000000104A4D1 -:10E6F00000369496FE5C8726000076A5001E76B450 -:10E70000FFE5C7386FC07739FFF0203A0000470CAB -:10E710000001203A0000E600EA8D000000018316A7 -:10E72000FECC8496FF1C0618003A85B20000072430 -:10E73000003A86BA00007631001E7630FFE5773960 -:10E74000001E7738FFE5C5AC67C0C6B477C075ADAD -:10E75000FFF076B5FFF0C02E6A00EC00E764F5022A -:10E760000002F50200018316FF1C000000010718DB -:10E77000003686BA00007739001E7738FFE5C6B448 -:10E7800077C076B5FFF020360002E600E79C000077 -:10E790000001202A0001E600EA8D000000018496B5 -:10E7A000FE5C8316FF1CF52728000618000287323E -:10E7B000000076B1001E76B4FFE5251400A684960D -:10E7C000FE9C8316FEDC0630000275B1001EC738C1 -:10E7D0006FC07738FFF0F72728008732000075AC4C -:10E7E000FFE5C7385FC07738FFF0F72B2800251406 -:10E7F00000A4063000028732000076B1001E76B415 -:10E80000FFE5C7386FC07738FFF0F72B28002514D5 -:10E8100000A2063000028732000076B1001E76B4F6 -:10E82000FFE5C7386FC07738FFF0F72B28002514B5 -:10E8300000A0063000028732000076B1001E76B4D8 -:10E84000FFE5C7386FC07738FFF0F72B2800251495 -:10E85000009E063000028732000076B1001E76B4BA -:10E86000FFE5C7386FC07738FFF0F72B2800251475 -:10E87000009C063000028732000076B1001E76B49C -:10E88000FFE5C7386FC07738FFF0F72B2800251455 -:10E89000009A063000028732000076B1001E76B47E -:10E8A000FFE5C7386FC07738FFF0F72B2800063038 -:10E8B000000287320000251400987631001E763061 -:10E8C000FFE5C73867C07738FFF0F72B2800C71C73 -:10E8D00032009713FFFC9493FFFC261400909613CC -:10E8E000FFFC9616FE6C07880008E000D0DC9793CA -:10E8F000FFFC8716FF708616FE6C8496FECC239470 -:10E90000008E759D001E75ACFFE57315001E731813 -:10E91000FFE59316FE947415001E7420FFE5731531 -:10E92000001E7318FFE59316FE848316FE9476315D -:10E93000001E7630FFE50524000206A8000274954B -:10E94000001E74A4FFE59496FE8CC73867C0773824 -:10E95000FFF0F72B28008496FEC4871E0000752563 -:10E96000001EC7385FC07738FFF0F737280006B4BD -:10E9700000028716FF742394008A761D001E7630ED -:10E98000FFE58496FE8C7528FFE5C73837C07738D9 -:10E99000FFF0F7372800871E000006B40002831638 -:10E9A000FE84C73867C07738FFF0F737280006B411 -:10E9B00000028716FF7823940086761D001E7630AD -:10E9C000FFE5C73847C07738FFF0F7372800871EC4 -:10E9D000000006B40002C73867C07738FFF0F73789 -:10E9E000280006B400028716FF7C23940082761D5F -:10E9F000001E7630FFE5C7384FC07738FFF0F73795 -:10EA00002800871E000006B400028496FEC4C738A2 -:10EA100067C07738FFF0F73728008716FF8006B405 -:10EA20000002C73837C07738FFF0F737280087264D -:10EA30000000F30200FFC73857C07738FFE8C6B8B8 -:10EA40003400F7020080C73474007739001077393A -:10EA5000FFF0203A0000E600EA6127000100C6B49A -:10EA600075808496FECC0000000107240038F6BBB8 -:10EA700028009493FFFC8316FF24000000019313E9 -:10EA8000FFFC07880008E000D42C9793FFFC8496D5 -:10EA9000FED40000000104A40001E000E33C9496D1 -:10EAA000FED4F40200018796FFFC8296FFF8021460 -:10EAB0000004013C0000000000019293FFFC029062 -:10EAC0000008861600088696000CF502FFFC859665 -:10EAD000000484160010F484E0000730000294B2B1 -:10EAE0000010F484E00406B4000394B20014F4842B -:10EAF000E01CC6B4540094B20018F4820005F4B3CC -:10EB00002800F4820001F4BB280027340008973263 -:10EB1000000486160000072C0003C7385400C6B84E -:10EB200068009693FFFCC63072009613FFFCF70254 -:10EB30000003C5AC7400F7020004C7385A009713ED -:10EB4000FFFC07880008C12000009793FFFC879610 -:10EB5000FFFC8296FFF802140014013C0000000044 -:10EB600000019293FFFC0290000822100018871603 -:10EB700000040000000183BA000084960000939610 -:10EB8000FFF0F3846E54873A00049396FFEC9716D7 -:10EB9000FFF49013FFFC271C00029713FFFC0724CF -:10EBA00000209713FFFC9496FFE407880008E0001C -:10EBB000CDB89793FFFC8496FFE4839600088726E0 -:10EBC00000188516FFECC03A3A00EE00EC7CF582A6 -:10EBD0000001872600188396000800000001C01E6F -:10EBE0007200E600EC7CC584000086A60010871643 -:10EBF000FFF0F6020000C0367200E600EC1C0424B0 -:10EC0000001086A600148716FFF400000001C0362D -:10EC10007200E600EC2020320000F60200012032F3 -:10EC20000000E600EC2D00000001F582000086A245 -:10EC300000008716FFF000000001C0367200E200FD -:10EC4000EC68F6020000C0367200E600EC7020327C -:10EC5000000086A200048716FFF400000001C03601 -:10EC60007200E200EC7120320000F6020001203256 -:10EC70000000E600EC81202E0000F5820001202E2D -:10EC80000000E600ECACF7020001F704429CF60637 -:10EC9000429C76B1001E76B4FFE5C7386FC0773965 -:10ECA000FFF007380001F7332800F7020001972A28 -:10ECB000000883A6000C772CFFE193AA000C972A8A -:10ECC000001C83A6001CF7046E5093AA002083BA90 -:10ECD0001DDCF682000093AA002C8396000CC5B4BC -:10ECE000000093AA003083BA0010C634000093AA33 -:10ECF0000024873A001400000001972A00282036DB -:10ED0000001FEE00ED1CC73050000738003495BAE4 -:10ED1000000006300004E000ECFC06B4000183961D -:10ED2000001076A5001E9393FFFCF38200B493932A -:10ED3000FFFC9513FFFC8726002076B4FFE5C7385B -:10ED40006FC07739FFF09713FFFC8396FFEC00004C -:10ED500000019393FFFC07880008E000EAB897934E -:10ED6000FFFC8796FFFC8296FFF802140014013C1A -:10ED70000000000000019293FFFC029000082210A6 -:10ED800000188716000400000001863A0000000009 -:10ED900000019616FFF0873A000400000001971664 -:10EDA000FFF4F6021DE09613FFFC8616000000003B -:10EDB00000019613FFFCF6046E500000000196134C -:10EDC000FFFC261400109616FFEC07880008E001EF -:10EDD00026F89793FFFCF6846E50F6020000873603 -:10EDE0001DD89616FFE476B5001E76B4FFE5C73849 -:10EDF0006FC07738FFF0F68642C0F73728008616D6 -:10EE0000FFEC000000019613FFFC07880008E000FB -:10EE1000DBB49793FFFC20220000E600EE4D0000DB -:10EE200000018616FFEC000000019613FFFC078826 -:10EE30000008E000D5A09793FFFC20220000E60028 -:10EE4000EE4D00000001F60200019616FFE4841664 -:10EE5000FFE48796FFFC8296FFF802140008013C4D -:10EE60000000000000019293FFFC029000088696CB -:10EE70000004861600008736000885960008203AB0 -:10EE80000000E600EE99203A0003E600EEE9F40205 -:10EE90000000E000EF0C0000000177B0001F703EA2 -:10EEA000FFE1E600EF0DF4020000851600140000FB -:10EEB00000019513FFFC851600100000000195135A -:10EEC000FFFC8516000C000000019513FFFC9593D4 -:10EED000FFFC9693FFFC07880008E000EB60979327 -:10EEE000FFFCE000EF0C0000000177B0001E703E58 -:10EEF000FFE1E600EF0D000000019593FFFC969303 -:10EF0000FFFC07880008E000ED749793FFFC8796EC -:10EF1000FFFC8296FFF802140018013C000000007C -:10EF200000019293FFFC0290000822100018F48266 -:10EF3000000086960000F6044AA023940010843650 -:10EF400000009616FFE4F7044A9C9416FFF08536FD -:10EF50000004C0327200EC00F0149516FFF4773113 -:10EF60000001C738600077390002F3064A98C6B836 -:10EF7000300006B4000CC584000087360000000095 -:10EF80000001C03A4200E600EFA4C6240000873624 -:10EF9000000400000001C03A5200E600EFA8203251 -:10EFA0000000F602000120320000E600EFB500008C -:10EFB0000001F5820000863600008716FFF0000091 -:10EFC0000001C0327200E200EFF0F5020000C03232 -:10EFD0007200E600EFF8202A000086B600048716CB -:10EFE000FFF400000001C0367200E200EFF9202AB1 -:10EFF0000000F5020001202A0000E600F009202EA2 -:10F000000000F5820001202E0000E600F018202606 -:10F010000000F482000120260000E600F04DF60218 -:10F0200000018716FFE4F3064A9876B90001C6B4DA -:10F03000700076B50002C6B4300006B4001486B67F -:10F0400000009716FFE8E000F0B09696FFEC27145A -:10F05000001C9713FFFC9393FFFCF3064A9893134D -:10F06000FFFC07880008E00125689793FFFC202239 -:10F070000000E600F0ADF60200018716FFE4F3069B -:10F080004A9876B90001C6B4700076B50002C6B4DD -:10F09000300006B4001486B600009716FFE8969676 -:10F0A000FFECF7054AA0E000F0B420320000F602C1 -:10F0B000000020320000E600F121F4020001871672 -:10F0C000FFE8F60642C876B90002C6B4700076B50D -:10F0D0000002A736600283160004C6B460007635CD -:10F0E000001E7630FFE50534000275A9001EC73802 -:10F0F00067C07738FFF0971A0000872A000075ACC8 -:10F10000FFE583160008C7385FC07738FFF0971A0D -:10F1100000008316000C06B40004E000F124969A67 -:10F120000000F40200008796FFFC8296FFF80214AC -:10F130000010013C0000000000010000B9000000C8 -:10F14000BA000000BB000000BC000000BD000000D1 -:10F15000BE000000BF000000800000008100000031 -:10F160008200000083000000840000008500000091 -:10F17000860000008700B9B9B9BAB9BBB9BCB9BD3E -:10F18000B9BEB9BFB980B981B982B983B984B9852B -:10F19000B986B987BAB9BABABABBBABCBABDBABE2F -:10F1A000BABFBA80BA81BA82BA83BA84BA85BA863B -:10F1B000BA87BBB9BBBABBBBBBBCBBBDBBBEBBBFCD -:10F1C000BB80BB81BB82BB83BB84BB85BB86BB874B -:10F1D000BCB9BCBABCBBBCBCBCBDBCBEBCBFBC80AB -:10F1E000BC81BC82BC83BC84BC85BC86BC87BDB9E9 -:10F1F000BDBABDBBBDBCBDBDBDBEBDBFBD80BD81BB -:10F20000BD82BD83BD84BD85BD86BD87BEB9BEBA86 -:10F21000BEBBBEBCBEBDBEBEBEBFBE80BE81BE82CA -:10F22000BE83BE84BE85BE86BE87BFB9BFBABFBB24 -:10F23000BFBCBFBDBFBEBFBFBF80BF81BF82BF83DA -:10F24000BF84BF85BF86BF8780B980BA80BB80BCC2 -:10F2500080BD80BE80BF80808081808280838084EA -:10F2600080858086808781B981BA81BB81BC81BD60 -:10F2700081BE81BF818081818182818381848185FA -:10F280008186818782B982BA82BB82BC82BD82BEFE -:10F2900082BF82808281828282838284828582860A -:10F2A000828783B983BA83BB83BC83BD83BE83BF9C -:10F2B000838083818382838383848385838683871A -:10F2C00084B984BA84BB84BC84BD84BE84BF84807A -:10F2D000848184828483848484858486848785B9B8 -:10F2E00085BA85BB85BC85BD85BE85BF858085818A -:10F2F00085828583858485858586858786B986BA56 -:10F3000086BB86BC86BD86BE86BF86808681868299 -:10F310008683868486858686868787B987BA87BBF3 -:10F3200087BC87BD87BE87BF8780878187828783A9 -:10F33000878487858786878700009293FFFC0290E9 -:10F34000000822100018F70475EC00000001203AB4 -:10F350000000E600F37DF6064296F704429476B18B -:10F36000001E76B4FFE5F4020000C7386FC077399D -:10F37000FFF007380001E000F5E0F7332800F384E0 -:10F380006F309013FFFC271C00029713FFFC8316BD -:10F390000000000000019313FFFC9396FFEC078828 -:10F3A0000008E000CDB89793FFFC8396FFECF702CE -:10F3B0000000971E00088316000400000001931E41 -:10F3C000000C83160008049C0022931E001C831668 -:10F3D000000C9396FFF4871A00007699001E76B40D -:10F3E000FFE50618000275B1001E75ACFFE5C738D1 -:10F3F0006FC07738FFF0069C0020F737280087326F -:10F4000000009696FFE47535001EC7385FC0773858 -:10F41000FFF0F7272800049C002406300002873202 -:10F42000000076B1001E76B4FFE5C7386FC07738AC -:10F43000FFF0F7272800049C0026063000028732E0 -:10F44000000076B1001E76B4FFE5C7386FC077388C -:10F45000FFF0F7272800049C0028063000028732BE -:10F46000000076B1001E76B4FFE5C7386FC077386C -:10F47000FFF0F7272800049C002A0630000287329C -:10F48000000076B1001E76B4FFE5C7386FC077384C -:10F49000FFF0F7272800049C002C0630000287327A -:10F4A000000076B1001E76B4FFE5C7386FC077382C -:10F4B000FFF0F7272800049C002E06300002873258 -:10F4C000000076B1001E76B4FFE5C7386FC077380C -:10F4D000FFF0F72728000630000287320000049C66 -:10F4E00000307631001E7630FFE5C73867C07738C8 -:10F4F000FFF0F7272800871E00207528FFE5C73892 -:10F5000057C07739FFF0203A0008EE00F598F3066F -:10F5100014D88316FFE4871E00207699001E76B467 -:10F52000FFE5C7386FC07739FFF025B80001C4ACDC -:10F53000580004240001202E0000EC00F595F5028F -:10F5400000008316FFE40000000106180002A73245 -:10F550005802C6B0580076B5001E76B4FFE5C7382D -:10F560006FC07739FFE8C6B0400077B80018703E2A -:10F57000FFE1E600F57DF7376800F502FFFFC730D1 -:10F580004800F53B680024A4000224200002E000AB -:10F59000F53425AC0001F30614D89313FFFCF302F5 -:10F5A00000349313FFFC8316FFF400000001931353 -:10F5B000FFFC8316000000000001871A0000769906 -:10F5C000001E76B4FFE5C7386FC07739FFF0971398 -:10F5D000FFFC9393FFFC07880008E000EAB89793CC -:10F5E000FFFC8796FFFC8296FFF802140010013C96 -:10F5F0000000000000019293FFFC0290000822101E -:10F600000010F70475EC00000001203A0000E6004D -:10F61000F639F6064296F704429476B1001E76B4A7 -:10F62000FFE5F4020000C7386FC07739FFF00738F4 -:10F630000001E000F748F7332800F5046F300000C0 -:10F6400000019516FFF49013FFFC27280002971382 -:10F65000FFFC85960004000000019593FFFC0788DD -:10F660000008E000CDB89793FFFC85160004F60271 -:10F67000000086AA00007729001E7738FFE5C6B48F -:10F6800077C076B5FFF0F7020001C0367400E600DF -:10F69000F6999696FFECC63800009613FFFC859607 -:10F6A000FFEC8516FFF4472CFFFE07380002C72841 -:10F6B00072009713FFFC85960000000000019593EF -:10F6C000FFFC07880008E000CDB89793FFFC851683 -:10F6D000FFF4F7020002972A000885960008000050 -:10F6E000000195AA000C8596000C0000000195AA67 -:10F6F000001CF50614D89513FFFCF58200209593A5 -:10F70000FFFC8516FFF4000000019513FFFC8596B1 -:10F7100000008516FFEC872E000076AD001E76B443 -:10F72000FFE5C7386FC07739FFF0C738500097132F -:10F73000FFFC8596FFF4000000019593FFFC07880D -:10F740000008E000EAB89793FFFC8796FFFC8296DA -:10F75000FFF802140010013C000000000001929329 -:10F76000FFFC0290000885960000851600048716AD -:10F770000008F602FFFC06A80003C6B464000738C0 -:10F780000003C7386400C73470009713FFFCC5AC92 -:10F790006A009593FFFCF7020003C5287400F70286 -:10F7A0000004C73852009713FFFC07880008E001E7 -:10F7B00014D89793FFFC8796FFFC8296FFF80214FB -:10F7C0000010013C0000000000019293FFFC029039 -:10F7D000000822100010F70475EC00000001203A28 -:10F7E0000000E600F80DF6064296F704429476B162 -:10F7F000001E76B4FFE5F4020000C7386FC0773909 -:10F80000FFF007380001E000F920F7332800F50485 -:10F810006F30000000019516FFF49013FFFC2728BD -:10F8200000029713FFFC85960004000000019593E9 -:10F83000FFFC07880008E000CDB89793FFFC851611 -:10F840000004F602000086AA00007729001E77381F -:10F85000FFE5C6B477C076B5FFF0F7020001C03609 -:10F860007400E600F86D9696FFECC638000096131B -:10F87000FFFC8596FFEC8516FFF4472CFFFE07384A -:10F880000002C72872009713FFFC85960000000055 -:10F8900000019593FFFC07880008E000CDB897931E -:10F8A000FFFC8516FFF4F5820006F5AB280085966F -:10F8B00000080728000295AA00040514000E852AF6 -:10F8C000000077A9001E77BCFFE5C5287FC0752919 -:10F8D000FFF0F53B2800F58614D89593FFFCF50260 -:10F8E00000089513FFFC859600008516FFEC872E17 -:10F8F000000076AD001E76B4FFE5C7386FC07739DB -:10F90000FFF0C73850009713FFFC8596FFF4000006 -:10F9100000019593FFFC07880008E000F75C9793CF -:10F92000FFFC8796FFFC8296FFF802140010013C52 -:10F930000000000000019293FFFC029000082210DA -:10F940000008F70475EC83960004203A0000E600F6 -:10F95000FA64F6064296F5046F309013FFFC2728F0 -:10F9600000029713FFFC83160000000000019313B0 -:10F97000FFFC9396FFF49516FFF007880008E0005F -:10F98000CDB89793FFFC8516FFF0F302000783962E -:10F99000FFF4F32B280007280002F3020001F33BD9 -:10F9A0002800871E0000769D001E76B4FFE5059CAA -:10F9B0000002762D001E7630FFE5749D001E74A4B3 -:10F9C000FFE5041C000683160000C7386FC07738B7 -:10F9D000FFF006A80004F7372800872E000006A8CD -:10F9E000000675A1001EC73867C07738FFF0F737EB -:10F9F0002800871E000475ACFFE506A800087619EC -:10FA0000001EC7384FC07738FFF0F737280087222D -:10FA1000000006A8000AC7385FC07738FFF0F73744 -:10FA20002800F30614D89313FFFCF302000C931381 -:10FA3000FFFC8316000000000001871A00007630EA -:10FA4000FFE5C73867C07739FFF09713FFFC9513C0 -:10FA5000FFFC07880008E000F75C9793FFFCE000DC -:10FA6000FA8400000001F704429476B1001E76B4D7 -:10FA7000FFE5F4020000C7386FC07739FFF00738A0 -:10FA80000001F73328008796FFFC8296FFF80214E6 -:10FA90000008013C0000000000019293FFFC02906E -:10FAA000000822100048F70475EC85960000203A03 -:10FAB0000000E600FD98F606429605AC0002872E8F -:10FAC000000076AD001E76B4FFE52414001E062C5F -:10FAD00000027531001E249400207528FFE5F38490 -:10FAE0006E50C7386FC07738FFF0F727280087328D -:10FAF00000009396FFC4C73857C07738FFF0F7234C -:10FB000028002414001C063000028732000076B161 -:10FB1000001E76B4FFE5C7386FC07738FFF0F723D3 -:10FB200028002414001A063000028732000076B143 -:10FB3000001E76B4FFE5C7386FC07738FFF0F723B3 -:10FB4000280024140018063000028732000076B125 -:10FB5000001E76B4FFE5C7386FC07738FFF0F72393 -:10FB6000280024140016063000028732000076B107 -:10FB7000001E76B4FFE5C7386FC07738FFF0F72373 -:10FB8000280024140014063000028732000076B1E9 -:10FB9000001E76B4FFE5C7386FC07738FFF0F72353 -:10FBA000280024140012063000028732000076B1CB -:10FBB000001E76B4FFE5C7386FC07738FFF0F72333 -:10FBC000280006300002873200002414001076312D -:10FBD000001E7630FFE5C73867C07738FFF0F7239F -:10FBE00028009013FFFC271C00029713FFFC94933E -:10FBF000FFFC9596FFBC07880008E000CDB89793FE -:10FC0000FFFC8596FFBC231400362494003873A5AE -:10FC1000001E739CFFE5F40442C0F68642C076B530 -:10FC2000001E76B4FFE5872E0000762D001E76308C -:10FC3000FFE5C4206FC07420FFF005AC0002752DF5 -:10FC4000001E7528FFE5C73867C07738FFF0F72733 -:10FC50002800872E0000F6046E50C73857C077384A -:10FC6000FFF0F71B28002314003405AC0002872E98 -:10FC7000000076AD001E76B4FFE5C7386FC0773858 -:10FC8000FFF0F71B28002314003205AC0002872E7A -:10FC9000000076AD001E76B4FFE5C7386FC0773838 -:10FCA000FFF0F71B28002314003005AC0002872E5C -:10FCB000000076AD001E76B4FFE5C7386FC0773818 -:10FCC000FFF0F71B28002314002E05AC0002872E3E -:10FCD000000076AD001E76B4FFE5C7386FC07738F8 -:10FCE000FFF0F71B28002314002C05AC0002872E20 -:10FCF000000076AD001E76B4FFE5C7386FC07738D8 -:10FD0000FFF0F71B28002314002A05AC0002872E01 -:10FD1000000076AD001E76B4FFE5C7386FC07738B7 -:10FD2000FFF0F71B280005AC0002872E000023140B -:10FD3000002875AD001E75ACFFE5C7385FC0773889 -:10FD4000FFF0F71B28008716FFC8F6820003C738AC -:10FD50003FC096B2000806B01DD8F4372800F386DD -:10FD600014D89393FFFCF3821DE09393FFFC96134A -:10FD7000FFFC7739FFF09713FFFC8396FFC4000068 -:10FD800000019393FFFC07880008E000EAB897930E -:10FD9000FFFCE000FDB800000001F704429476B1DA -:10FDA000001E76B4FFE5F4020000C7386FC0773953 -:10FDB000FFF007380001F73328008796FFFC829692 -:10FDC000FFF802140004013C0000000000019293BF -:10FDD000FFFC029000088616000000000001873238 -:10FDE000000076B1001E76B4FFE5C7386FC07739E2 -:10FDF000FFF0203A0006E600FE21F582001EF7041F -:10FE000042A8F60642A876B1001E76B4FFE5C738D0 -:10FE10006FC07739FFF007380001E000FE34F73398 -:10FE20002800F6056F349593FFFC07880008E00072 -:10FE300015849793FFFC8796FFFC8296FFF80214C7 -:10FE40000004013C0000000000019293FFFC0290BE -:10FE5000000886160000859600048732000076B1FF -:10FE6000001E76B4FFE5C7386FC07739FFF0203A3F -:10FE70000007E600FE9DF4020000F70442A8F60623 -:10FE800042AA76B1001E76B4FFE5C7386FC0773955 -:10FE9000FFF007380001E000FF1CF73328000730AF -:10FEA000000286BA00007739001E7738FFE5C6B435 -:10FEB00077C076B5FFF020360001E600FED5F605E6 -:10FEC0006F3420360002E600FEE5F5020020E00077 -:10FED000FEFCF60642AC202E000CE600FF1CF402ED -:10FEE0000000F502001F9513FFFC07880008E000E2 -:10FEF00015849793FFFCE000FF1CF4020001F70457 -:10FF000042AC76B1001E76B4FFE5C7386FC07739D2 -:10FF1000FFF007380001F7332800F402000187964C -:10FF2000FFFC8296FFF802140008013C000000006C -:10FF300000019293FFFC02900008869600000000EA -:10FF4000000187360004F6020000073800089736E3 -:10FF500000048736000800000001203A0000EC0091 -:10FF6000FF7DF6856F348736000800000001203AD7 -:10FF70000003EE00FF8020320000F6020001203274 -:10FF80000000E600FFBDF60642AEF7046F34000045 -:10FF90000001873A0008F682FFEC77390002A73AA1 -:10FFA0006802000000019713FFFC07880008E000CA -:10FFB00015849793FFFCE000FFD800000001F704D0 -:10FFC00042AC76B1001E76B4FFE5C7386FC0773912 -:10FFD000FFF007380001F73328008796FFFC829670 -:10FFE000FFF802140004013C0000000000010000C2 -:10FFF00000170000001A0000001D0000001800009B -:020000021000EC -:10000000000056657273696F6E537472696E673A59 -:10001000206D63702D6C34763320332E303863209E -:1000200044656320313120313939362031333A305B -:10003000363A313600009293FFFC02900008F70434 -:10004000E00CFF0200009702FF84F7060C3ECFFC95 -:100050007580F60200029602FF8C9002FF88F7047A -:10006000E02000000001203A0000E6010074F68262 -:100070000000F68200039682FF988796FFFC829626 -:10008000FFF802140000013C000000000001929300 -:10009000FFFC029000082210000CF5021494F505F4 -:1000A0007B00F50EF014F5057B08F706E000F686F8 -:1000B0007B68C7386A00F7057AF0F502004CF682D3 -:1000C000000020360002EE010124F5057AF8C5B4DF -:1000D0000000C6340000F706E030C72C7000F506BB -:1000E0006F44B73250029013FFFC9713FFFC9596B4 -:1000F000FFF49616FFF09696FFEC07880008E001E3 -:10010000031C9793FFFC8596FFF48616FFF08696F6 -:10011000FFEC05AC149406B4000120360002EE0199 -:1001200000D506300004F5020022F5056F58F005F1 -:100130006F54F0056F50F0052D408796FFFC8296B6 -:10014000FFF802140000013C00000000000192933F -:10015000FFFC0290000807880008E00129589793E7 -:10016000FFFCF7020003F705E008F7047AD8F6026F -:1001700000019602FF94203A0000E6010191F70683 -:100180007AE807880008E00103DC9793FFFCF70694 -:100190007AE8F6020005F63B2800F7067AE0868248 -:1001A000FF44F602000320360000E60101C9F63BD9 -:1001B0002800F7046F648682FF4407380001203668 -:1001C0000000E60101B0F7056F6407880008E00150 -:1001D00000349793FFFC07880008E001008C979398 -:1001E000FFFC07880008E00044289793FFFC07887D -:1001F0000008E00016F09793FFFC07880008E00174 -:100200000C609793FFFC07880008E00104089793AF -:10021000FFFC07880008E00000209793FFFC078898 -:100220000008E0000BD89793FFFC07880008E00166 -:100230001D689793FFFC07880008E0011E50979304 -:10024000FFFC07880008E0005F689793FFFC0788C1 -:100250000008E0006DEC9793FFFC07880008E001C0 -:1002600021D09793FFFC07880008E001222C979388 -:10027000FFFC9002FF9407880008E0000BFC9793B6 -:10028000FFFCF40200008796FFFC8296FFF8021440 -:100290000000013C0000000000019293FFFC02906E -:1002A000000822100008F6020000C5B0000020324D -:1002B0000002EE010308F5066F44A6AE50020000EE -:1002C00000018736000000000001203A0001E6012D -:1002D00002FCF50200029513FFFC9693FFFC959635 -:1002E000FFF49616FFF007880008E001031C9793BF -:1002F000FFFC8616FFF08596FFF40000000105ACB8 -:100300000004E00102AC063000018796FFFC8296F3 -:10031000FFF802140000013C00000000000192936D -:10032000FFFC0290000887160000F6020000F6822B -:100330000008963A0008963A000C963A09D8963A80 -:1003400009DC963A0EF4963A0EF896BA1420963ACC -:10035000142490BA148C8696000490BA149096BA1D -:100360000000963A00048796FFFC8296FFF802147C -:100370000008013C0000000000019293FFFC029085 -:100380000008859600008716000886160004773856 -:10039000FFFFC5307000C0325200E40103C9000005 -:1003A0000001872E000076AD001E76B4FFE5C73849 -:1003B0006FC07738FFF0F733280006300002C032F4 -:1003C0005200E40103A005AC00028796FFFC829670 -:1003D000FFF80214000C013C0000000000019293A1 -:1003E000FFFC02900008F7020001E00103E8F705B6 -:1003F0007AD88796FFFC8296FFF802140000013C31 -:10040000000000000001000000009293FFFC029039 -:100410000008F502000AF50571CCF00571D4F0056D -:1004200071D0F00571C4F5020001F682000020369B -:10043000000AEC010464F50571C8F58A1E00F60691 -:1004400071C4472CFFFC973200180630000406B434 -:100450000001F70471CC00000001C0367200EC010D -:10046000044105AC214CF0057198F5066F689513B1 -:10047000FFFCF5067B189513FFFC07880008E000D9 -:1004800015489793FFFCF50605D49513FFFCF782FA -:1004900000059793FFFCF5066F689513FFFC07882E -:1004A0000008E000161C9793FFFCF5060B709513EF -:1004B000FFFCF78200069793FFFCF5066F68951323 -:1004C000FFFC07880008E000161C9793FFFCF50668 -:1004D0000BA09513FFFCF78200059793FFFCF50630 -:1004E00070809513FFFC07880008E000161C9793A6 -:1004F000FFFCF5060B709513FFFCF782000697933F -:10050000FFFCF50670809513FFFC07880008E000EB -:10051000161C9793FFFCF50605589513FFFCF50292 -:10052000000A9513FFFCF506710C9513FFFC078874 -:100530000008E000161C9793FFFC07880008E00104 -:1005400005589793FFFC8796FFFC8296FFF80214EC -:100550000000013C0000000000019293FFFC0290AB -:100560000008F70471C400000001203A0000E60111 -:10057000057DF68671C4E0010594F7020000F704DA -:1005800071D00000000177390002C7386800873A4F -:10059000001800000001203A0000E60105ACF70554 -:1005A0007B10F606710CE00105C0F6057B18F60617 -:1005B0006F68F6057B189702FF48073821289702D5 -:1005C000FF4C8796FFFC8296FFF802140000013C66 -:1005D0000000000000019293FFFC0290000822102E -:1005E00000108682FF48F4866F68F4857B18F50456 -:1005F0007B1026B4000285B60000872A0000762909 -:10060000001E7630FFE576B5001E76B4FFE5C5AC7A -:100610006FC0C73867C07739FFF077B80010703EF9 -:10062000FFE1E601064575ACFFF0F70471AC000090 -:10063000000107380001F70571ACF70471ACE00167 -:1006400008C4F7020001772CFFF8203A0000E60109 -:10065000067176A9001EF70471A800000001073892 -:100660000001F70571A8F70471A8E00108C4F702BA -:100670000001872A000076B4FFE5C7386FC07739DC -:10068000FFF027380004203A0003E20108A400002C -:10069000000177390002F68606A4A6B670020000B3 -:1006A0000001C1340000000106B40001077C000114 -:1006B00007EC00010844872A0004C4840000C03A03 -:1006C0004A00E60106D8000000018702FF4800004A -:1006D0000001C7385200972A0004872A000400004E -:1006E0000001203A2100EE01073CF602000086AA34 -:1006F00000048702FF4800000001C7385200273875 -:100700000028C0367200E601073C0000000177FCBB -:10071000001D703EFFE1E601073C0000000177FC90 -:100720000017703EFFE1E601073D0000000177FC85 -:100730000016703EFFE1E601074420320000F60299 -:10074000000120320000E601088800000001872A2D -:10075000001800000001203A0002EE0108C100006C -:100760000001F70471A40000000107380001F7053B -:1007700071A4F70471A4E00108C4F7020001872AFC -:10078000000400000001203A2100EE0107E0F6021B -:10079000000086AA00048702FF4800000001C73855 -:1007A00052002738000CC0367200E60107E0000056 -:1007B000000177FC001D703EFFE1E60107E000004C -:1007C000000177FC0017703EFFE1E60107E1000041 -:1007D000000177FC0016703EFFE1E6010880203240 -:1007E0000000F6020001E0010880203200008702CC -:1007F000FF4800000001C738520027380004203AA3 -:100800000008E6010838F682000077FC001D703E03 -:10081000FFE1E60108380000000177FC0017703E98 -:10082000FFE1E60108390000000177FC0016703E88 -:10083000FFE1E601088020360000F6820001E001B9 -:10084000088020360000F702000077FC001D703E93 -:10085000FFE1E60108780000000177FC0017703E18 -:10086000FFE1E60108790000000177FC0016703E08 -:10087000FFE1E6010880203A0000F7020001203A7B -:100880000000E60108C100000001F70471A00000AB -:10089000000107380001F70571A0F70471A0E0011D -:1008A00008C4F7020001F704719C0000000107383A -:1008B0000001F705719CF704719CE00108C4F70280 -:1008C0000001F7020000203A0000E601096800007C -:1008D0000001F6847B10000000018736000076B529 -:1008E000001E76B4FFE5C7386FC07739FFF02738B0 -:1008F0000004203A0003E2010B5077390002F6862B -:10090000090CA6B6700200000001C134000000010D -:10091000091C00010AE000010AAC00010B14F704F5 -:1009200071D0F60471CC06B80001C0366200E60151 -:100930000938C7340000F7020000F58471D40000C4 -:100940000001C03A5A00470C0001203A0000E601BD -:10095000098500000001F70471B0000000010738AC -:100960000001F70571B0F70471B0F70471B400002D -:10097000000107380001F70571B4F70471B4E00114 -:100980000B5000000001F48471C8F68571D0949674 -:10099000FFF4F4847B10C0366200E60109A494964B -:1009A000FFECF00571D0F70471D0F00571C88496A2 -:1009B000FFECC03A5A00470C0001F70571C48726C6 -:1009C000000800000001703AFFE1E60109E10000C3 -:1009D0000001F70471980000000107380001F705D5 -:1009E00071988496FFF40000000120260000E601C3 -:1009F0000A710000000107880008E001055897937C -:100A0000FFFCF602000920320014E6010A4D27001F -:100A1000000C203A0001E2010A4DF7062DCCF684C5 -:100A20002ECC0000000175B50002B62E700206B48F -:100A30000001F6852ECC8602FF34F7062E4C2036B8 -:100A4000001FE2010A4DB62E7002F0052ECCF7040D -:100A50002D6800000001873A000000000001873A7D -:100A600000280000000107880008C13800009793A3 -:100A7000FFFCF70471BC8496FFEC07380001F70512 -:100A800071BCF70471BC86A600048496FFF4F704D9 -:100A900071B820260000C7386800F70571B8E60174 -:100AA0000B5100000001E0010B5C00000001F704A5 -:100AB00071C00000000107380001F70571C0F7049C -:100AC00071C0F4847B10000000019493FFFC078840 -:100AD0000008E000FDCC9793FFFCE0010B50000004 -:100AE0000001F70471C00000000107380001F7059C -:100AF00071C0F70471C0F4847B100000000194936E -:100B0000FFFC07880008E000FF309793FFFCE0013E -:100B10000B5000000001F70471C00000000107380D -:100B20000001F70571C0F70471C0F6847B108702DD -:100B3000FF4800000001C7386A00273800049713F7 -:100B4000FFFC9693FFFC07880008E000FE4897939F -:100B5000FFFC07880008E00105589793FFFC879683 -:100B6000FFFC8296FFF802140000013C0000000028 -:100B700000019293FFFC02900008F7067080F705D1 -:100B80007B1807880008E00105589793FFFC8796BB -:100B9000FFFC8296FFF802140000013C00000000F8 -:100BA00000019293FFFC02900008F7066F68F705BA -:100BB0007B1807880008E00105589793FFFC87968B -:100BC000FFFC8296FFF802140000013C00000000C8 -:100BD00000019293FFFC02900008F7067B18971320 -:100BE000FFFCF7066F689713FFFC07880008E0001A -:100BF00014F49793FFFCF7067B189713FFFCF70696 -:100C00006FF49713FFFC07880008E00014F4979333 -:100C1000FFFCF7067B189713FFFCF706708097130D -:100C2000FFFC07880008E00014F49793FFFCF70628 -:100C30007B189713FFFCF706710C9713FFFC0788CE -:100C40000008E00014F49793FFFC8796FFFC82965F -:100C5000FFF802140000013C000000000001000049 -:100C600000009293FFFC02900008F5020004F505D5 -:100C70007600F0057608F0057604F00575F8F502C3 -:100C80000001F682000020360004EC010CBCF505E2 -:100C900075FCF58E6AF8F60675F8472CFFFC97325E -:100CA00000180630000406B40001F70476000000C6 -:100CB0000001C0367200EC010C9905AC214CF50620 -:100CC00072189513FFFCF50676489513FFFC07880C -:100CD0000008E00015489793FFFCF5060DF4951306 -:100CE000FFFCF782000E9793FFFCF5067218951330 -:100CF000FFFC07880008E000161C9793FFFCF50630 -:100D00000DF49513FFFCF782000E9793FFFCF50698 -:100D100072A49513FFFC07880008E000161C979347 -:100D2000FFFCF506132C9513FFFCF7820001979347 -:100D3000FFFCF50673309513FFFC07880008E00000 -:100D4000161C9793FFFCF50616C89513FFFCF78257 -:100D500000019793FFFCF50673BC9513FFFC078811 -:100D60000008E000161C9793FFFCF5061800951389 -:100D7000FFFCF78200109793FFFCF506744895136B -:100D8000FFFC07880008E000161C9793FFFCF5069F -:100D900016409513FFFCF78200109793FFFCF506B1 -:100DA00074D49513FFFC07880008E000161C979385 -:100DB000FFFCF506132C9513FFFCF50200129513AA -:100DC000FFFCF50675609513FFFC07880008E0003E -:100DD000161C9793FFFCF00575F0F00575ECF00517 -:100DE00075F48796FFFC8296FFF802140000013C20 -:100DF0000000000000019293FFFC02900008221006 -:100E00000038F70475EC00000001203A0000E6010C -:100E10000E2800000001F70475F000000001203AE0 -:100E20000000E6010E3D0000000107880008E00117 -:100E300015D09793FFFCE001131800000001F704A0 -:100E400075FC00000001203A0000E6010E59F6860C -:100E500075F8E0010E6CF6820000F70476080000D9 -:100E6000000177390002C738680086BA0018F70415 -:100E700076FC00000001203A0000E6010E90F685A5 -:100E80007660F3067648F30576FCE0010EA4F702DF -:100E90000001F3020010F30576F8F3067648F30537 -:100EA0007700F7020000203A0000E6011315F30670 -:100EB0007448F70475EC00000001203A0000E601D8 -:100EC0000ED800000001F70475F000000001203A80 -:100ED0000000E6010EED0000000107880008E001B7 -:100EE00016409793FFFCE001131800000001F68400 -:100EF0007660000000018736000800000001703AAB -:100F0000FFE1E6010F21F48200009693FFFC0788C1 -:100F10000008E00000BC9793FFFCE0011314F30607 -:100F20007560C3B40000841E0010F6844AA0231428 -:100F300000209316FFC49416FFE09696FFD4851EFA -:100F40000014F7044A9C00000001C0367200EC0156 -:100F5000100C9516FFE477350001C7386800773923 -:100F60000002F3064A98C6B8300006B4000CC584E7 -:100F700000008736000000000001C03A4200E60190 -:100F80000F9CC62400008736000400000001C03A10 -:100F90005200E6010FA020320000F60200012032CC -:100FA0000000E6010FAD00000001F582000086366A -:100FB00000008716FFE000000001C0327200E2016D -:100FC0000FE8F5020000C0327200E6010FF0202A9F -:100FD000000086B600048716FFE400000001C0365A -:100FE0007200E2010FF1202A0000F5020001202A20 -:100FF0000000E6011001202E0000F5820001202EE5 -:101000000000E601101020260000F48200012026D6 -:101010000000E6011045F60200018716FFD4F30632 -:101020004A9876B90001C6B4700076B50002C6B41D -:10103000300006B4001486B600009716FFD8E00111 -:1010400010B89696FFDC2714002C9713FFFC83162C -:10105000FFC4000000019313FFFCF3064A989313AA -:10106000FFFC9396FFCC07880008E0012568979362 -:10107000FFFC8396FFCC20220000E60110B5F602AB -:1010800000018716FFD4F3064A9876B90001C6B46A -:10109000700076B50002C6B4300006B4001486B6FF -:1010A00000009716FFD89696FFDCF7054AA0E001EE -:1010B00010BC20320000F602000020320000E601E1 -:1010C00010CCF4820001E0011124F4820000869625 -:1010D000FFD80000000177350002C7386800773973 -:1010E0000002F68642C8A63A6802C7386800753919 -:1010F000001E7528FFE505B8000286AE000007381F -:1011000000049716FFECC63057C07630FFF09616F5 -:10111000FFF475AD001E75ACFFE5C6B45FC076B4D4 -:10112000FFF09696FFF020260000E6011138F582C8 -:101130000000E00111CCF60200008696FFF00000EE -:101140000001C7346800C49C7200C02E6A00EC0124 -:101150001198C5240000C62C00008716FFEC000083 -:101160000001A6B2700205AC0001C73070007739EB -:10117000001E7738FFE5C6B477C076B4FFF0F6AB53 -:101180002800052800028716FFF000000001C02E8D -:101190007200EC01115906300002F3020001F30560 -:1011A00076F4F60200018716FFF0869E0004C73829 -:1011B0007000C7384800C6B470008716FFF406B444 -:1011C00000209702FF6C9482FF509682FF582032D5 -:1011D0000000E601131000000001F704765CF584BE -:1011E00076F807380001F705765CF704765C202E68 -:1011F0000021E2011230F6862C28F7042D38000079 -:10120000000106380001F6052D387739000220323A -:101210000044E601121CB5BA6802F0052D38F3024D -:101220000022F30576F8F3047700E0011234F305A9 -:1012300076FCF00576FCF70475F800000001203A12 -:101240000000E6011271F6862C28F7042D38000004 -:10125000000106380001F6052D3877390002F30247 -:10126000000F20320044E6011270B33A6802F00524 -:101270002D38F7047608F684760007380001C03A66 -:101280006A00E601128CF7057608F0057608F68408 -:101290007608F7047604F00575F8F60675F8C0369A -:1012A0007200470C0001203A0000E60112B9F70570 -:1012B00075FCE00112C8F702000077350002C7385C -:1012C0006000873A001800000001203A0000E601A3 -:1012D0001309F7057660F7042D38F30672A4F305B9 -:1012E0007648F6862C2806380001F6052D38773921 -:1012F0000002F302000E20320044E6011318B33A54 -:101300006802E0011318F0052D38E0011314F3060C -:101310007218F3067330F30576488796FFFC8296C1 -:10132000FFF802140000013C00000000000192934D -:10133000FFFC02900008F70476600000000186BA06 -:101340000004F704765400000001C7386800F70570 -:101350007654F70476580000000107380001F705BD -:101360007658F70475F8F6847658203A0000E601BE -:10137000139DF6862C28F7042D380000000106384E -:101380000001F6052D3877390002F502000F2032F2 -:101390000044E601139CB53A6802F0052D38F704C5 -:1013A0007608F684760007380001C03A6A00E60144 -:1013B00013B8F7057608F0057608F7047608F68482 -:1013C0007604F00575F8F58476F8C03A6A00470CA3 -:1013D0000001202E0021E2011414F70575FCF7042A -:1013E0002D38F6862C2806380001F6052D38773979 -:1013F000000220320044E6011400B5BA6802F0058C -:101400002D38F5020022F50576F8F5047700E001A5 -:101410001418F50576FCF00576FCF70475ECF50676 -:101420007218203A0000E6011440F5057648F704EA -:1014300075F000000001203A0000E601145500009C -:10144000000107880008E00115D09793FFFCE00138 -:1014500014C400000001F70475FC00000001203AEC -:101460000000E6011471F68675F8E0011488F702B1 -:101470000000F70476080000000177390002C73841 -:101480006800873A001800000001203A0000E601D9 -:1014900014C5F7057660F7042D38F6862C28063833 -:1014A0000001F6052D3877390002F502000E2032D2 -:1014B0000044E60114BCB53A6802F0052D38F50683 -:1014C00072A4F50576488796FFFC8296FFF8021411 -:1014D0000000013C0000000000019293FFFC02901C -:1014E0000008F70475EC00000001203A0000E60156 -:1014F0001540F40200008696000400000001F68505 -:1015000075EC8696000800000001F6857B3886960B -:101510000000F7047648F6857B30F6867218C03AEC -:101520006A00470C0001203A0000E6011541F40270 -:10153000000107880008E00115D09793FFFCF40232 -:1015400000018796FFFC8296FFF80214000C013C14 -:101550000000000000019293FFFC02900008F704D5 -:1015600075F400000001203A0000E60115BCF40209 -:1015700000008696000400000001F68575F086964E -:10158000000800000001F6857B4886960000F704FD -:101590007648F6857B40F6867218C03A6A00470C9A -:1015A0000001203A0000E60115BDF40200010788A1 -:1015B0000008E00115D09793FFFCF4020001879624 -:1015C000FFFC8296FFF80214000C013C00000000B2 -:1015D00000019293FFFC02900008F70476FC0000E3 -:1015E0000001203A0000E60115FCF6820010F686A4 -:1015F0007648F68576FCE001160CF7020001F685C8 -:1016000076F8F6867648F6857700F7020000203AED -:101610000000E6011620F68674D4E001162CF6854B -:10162000764807880008E00116409793FFFC8796EC -:10163000FFFC8296FFF802140000013C000000004D -:1016400000019293FFFC02900008F60475F0000080 -:10165000000120320000E6011685F7020001F705BF -:1016600075F4F6847B48F70576F4F7047B40C6B042 -:10167000680026B400049702FF6C9602FF50E00158 -:1016800016A800000001F70475ECF6847B38F5829B -:101690000001F58576F4F6047B30C6B8680026B400 -:1016A00000049602FF6C9702FF509682FF58F58661 -:1016B00073BCF58576488796FFFC8296FFF8021486 -:1016C0000000013C0000000000019293FFFC02902A -:1016D0000008F7047B280000000107380001F70527 -:1016E0007B28F70475F4F6847B28203A0000E60195 -:1016F000172100000001F00575F4F70475EC0000F7 -:101700000001203A0000E6011725F00575F0078872 -:101710000008E00116409793FFFCE00117EC000081 -:101720000001F00575ECF70475FC00000001203A9B -:101730000000E6011741F68675F8E0011758F70238 -:101740000000F70476080000000177390002C7386E -:101750006800873A001800000001203A0000E60106 -:101760001795F7057660F7042D38F6862C2806388D -:101770000001F6052D3877390002F502000E2032FF -:101780000044E601178CB53A6802F0052D38E001F7 -:101790001798F50672A4F5067218F5057648F584D3 -:1017A00076F800000001202E0021E20117E8F686FD -:1017B0002C28F7042D380000000106380001F6053A -:1017C0002D387739000220320044E60117D4B5BA2B -:1017D0006802F0052D38F5020022F50576F8F504CB -:1017E0007700E00117ECF50576FCF00576FC8796AE -:1017F000FFFC8296FFF802140000013C000000008C -:1018000000019293FFFC0290000822100038F704B8 -:1018100075EC00000001203A0000E60118340000D9 -:101820000001F70475F000000001203A0000E60115 -:1018300018490000000107880008E001164097934E -:10184000FFFCE0011C7400000001F68476600000DB -:1018500000018736000800000001703AFFE1E60150 -:10186000187DF48200009693FFFC07880008E000D2 -:1018700000BC9793FFFCE0011C70F3067560C3B4D5 -:101880000000841E0010F6844AA023140020931642 -:10189000FFC49416FFE09696FFD4851E0014F7044B -:1018A0004A9C00000001C0367200EC0119689516D0 -:1018B000FFE477350001C738680077390002F30686 -:1018C0004A98C6B8300006B4000CC58400008736BC -:1018D000000000000001C03A4200E60118F8C624EA -:1018E00000008736000400000001C03A5200E60103 -:1018F00018FC20320000F602000120320000E60150 -:10190000190900000001F5820000863600008716E4 -:10191000FFE000000001C0327200E2011944F5024C -:101920000000C0327200E601194C202A000086B681 -:1019300000048716FFE400000001C0367200E201D7 -:10194000194D202A0000F5020001202A0000E601BE -:10195000195D202E0000F5820001202E0000E60116 -:10196000196C20260000F482000120260000E60108 -:1019700019A1F60200018716FFD4F3064A9876B93A -:101980000001C6B4700076B50002C6B4300006B4DB -:10199000001486B600009716FFD8E0011A14969638 -:1019A000FFDC2714002C9713FFFC8316FFC40000F4 -:1019B00000019313FFFCF3064A989313FFFC9396E0 -:1019C000FFCC07880008E00125689793FFFC839609 -:1019D000FFCC20220000E6011A11F6020001871652 -:1019E000FFD4F3064A9876B90001C6B4700076B504 -:1019F0000002C6B4300006B4001486B60000971684 -:101A0000FFD89696FFDCF7054AA0E0011A182032AD -:101A10000000F602000020320000E6011A28F482DD -:101A20000001E0011A80F48200008696FFD80000D1 -:101A3000000177350002C738680077390002F68662 -:101A400042C8A63A6802C73868007539001E752872 -:101A5000FFE505B8000286AE0000073800049716BF -:101A6000FFECC63057C07630FFF09616FFF475AD28 -:101A7000001E75ACFFE5C6B45FC076B4FFF0969665 -:101A8000FFF020260000E6011A94F5820000E00134 -:101A90001B28F60200008696FFF000000001C73404 -:101AA0006800C49C7200C02E6A00EC011AF4C524C0 -:101AB0000000C62C00008716FFEC00000001A6B253 -:101AC000700205AC0001C73070007739001E77380E -:101AD000FFE5C6B477C076B4FFF0F6AB2800052862 -:101AE00000028716FFF000000001C02E7200EC011A -:101AF0001AB506300002F3020001F30576F4F6028F -:101B000000018716FFF0869E0004C7387000C738B2 -:101B10004800C6B470008716FFF406B40020970290 -:101B2000FF6C9482FF509682FF5820320000E6013D -:101B30001C6C00000001F704765CF58476F8073829 -:101B40000001F705765CF704765C202E0021E201A7 -:101B50001B8CF6862C28F7042D380000000106386F -:101B60000001F6052D387739000220320044E601E5 -:101B70001B78B5BA6802F0052D38F3020022F30590 -:101B800076F8F3047700E0011B90F30576FCF0058E -:101B900076FCF70475F800000001203A0000E60129 -:101BA0001BCDF6862C28F7042D38000000010638DE -:101BB0000001F6052D3877390002F302000F2032BC -:101BC0000044E6011BCCB33A6802F0052D38F70457 -:101BD0007608F684760007380001C03A6A00E6010C -:101BE0001BE8F7057608F0057608F6847608F70412 -:101BF0007604F00575F8F60675F8C0367200470CE5 -:101C00000001203A0000E6011C15F70575FCE00113 -:101C10001C24F702000077350002C7386000873ABD -:101C2000001800000001203A0000E6011C65F705DD -:101C30007660F7042D38F30672A4F3057648F6862D -:101C40002C2806380001F6052D3877390002F302FA -:101C5000000E20320044E6011C74B33A6802E00131 -:101C60001C74F0052D38E0011C70F3067218F306A1 -:101C70007330F30576488796FFFC8296FFF80214CE -:101C80000000013C0000000000019293FFFC029064 -:101C90000008F70676489713FFFCF70672189713AB -:101CA000FFFC07880008E00014F49793FFFCF70698 -:101CB00076489713FFFCF70672A49713FFFC07887A -:101CC0000008E00014F49793FFFCF706764897139A -:101CD000FFFCF70673309713FFFC07880008E0004D -:101CE00014F49793FFFCF70676489713FFFCF7066A -:101CF00073BC9713FFFC07880008E00014F4979367 -:101D0000FFFCF70676489713FFFCF7067448971315 -:101D1000FFFC07880008E00014F49793FFFCF70627 -:101D200076489713FFFCF70674D49713FFFC0788D7 -:101D30000008E00014F49793FFFCF7067648971329 -:101D4000FFFCF70675609713FFFC07880008E000AA -:101D500014F49793FFFC8796FFFC8296FFF8021419 -:101D60000000013C0000000000019293FFFC029083 -:101D70000008F68676689693FFFCF68677049693BD -:101D8000FFFC07880008E00015489793FFFCF686E3 -:101D90001DD49693FFFC9013FFFCF686766896930D -:101DA000FFFC07880008E000161C9793FFFCF70271 -:101DB0000022F70576F4F70576F8F00576FCF005D5 -:101DC00077008796FFFC8296FFF802140000013C22 -:101DD0000000000000019293FFFC02900008F7044D -:101DE00076F400000001203A0022E6011E01000006 -:101DF00000019713FFFC07880008E0001584979303 -:101E0000FFFC8796FFFC8296FFF802140000013C5D -:101E10000000000000019293FFFC02900008F7060A -:101E200077049713FFFCF70676689713FFFC078883 -:101E30000008E00014F49793FFFC8796FFFC82965D -:101E4000FFF802140000013C000000000001000047 -:101E500000009293FFFC02900008F686781096939B -:101E6000FFFCF68678A49693FFFC07880008E00044 -:101E700015489793FFFCF6861FBC9693FFFCF682ED -:101E800000149693FFFCF68678109693FFFC078863 -:101E90000008E000161C9793FFFCF005789C900268 -:101EA000FF34F7027FFFF70578A09702FF3087968F -:101EB000FFFC8296FFF802140000013C00000000C5 -:101EC00000019293FFFC02900008F604789C8716AC -:101ED000000084960008F5867710873A0008F68699 -:101EE000218C7539000477390002A73A6802203244 -:101EF0000000C6A8580084160004C63075809436C9 -:101F00000004B4AA580287360008F605789C073802 -:101F10000001E6011F2D973600088702FF30000000 -:101F20000001C03A4A00EE011F3500000001F485AF -:101F300078A09482FF308796FFFC8296FFF8021407 -:101F4000000C013C0000000000019293FFFC029095 -:101F500000088596000000000001872E0008F68624 -:101F6000218C77390002A73A6802F604789CC704EE -:101F7000760086AE0008C6307400F7067710F605C6 -:101F8000789C76B50004C6B470008736000820320D -:101F9000000007380001E6011FA897360008F70285 -:101FA0007FFFF70578A09702FF308796FFFC8296A7 -:101FB000FFF802140004013C0000000000019293AD -:101FC000FFFC0290000822100008F704789C000033 -:101FD0000001203A0000E60120D1F6027FFF9616AC -:101FE000FFF4F6842D40F606771026B4000177350D -:101FF0000004C4B86000C338000074350002F6065F -:102000007710C0266200EC0120C1F606218CF38413 -:10201000789CA722600200000001C01E7400E60147 -:1020200020B10000000186A60000F70478A000009F -:102030000001C6B4720020360000EE01209896A67A -:102040000000F7042D38F6067710C5186000F686F4 -:102050002C28862A000405B80001F5852D3877392B -:102060000002202E0044E6012070B63A6802F00516 -:102070002D38862A000800000001962A000CF6067A -:10208000218CA722600200000001C7047600C71C53 -:102090007400E00120B0F705789C8616FFF400007C -:1020A0000001C0366200EC0120B0000000019696ED -:1020B000FFF424A4001023180010E0011FFC2420CA -:1020C00000048616FFF400000001F60578A09602D1 -:1020D000FF308796FFFC8296FFF802140000013C57 -:1020E0000000000000019293FFFC02900008871698 -:1020F000000000000001873A0008F6867710773963 -:102100000004C738680086BA000C873A000800004F -:102110000001C0367200440C00018796FFFC8296D5 -:10212000FFF802140004013C00000000000192933B -:10213000FFFC02900008F702000F203A0000EC01BB -:10214000215DF68677189036000027380001C60416 -:102150000000C03A6200E601214406B40010F60611 -:1021600078A49613FFFCF60678109613FFFC0788F8 -:102170000008E00014F49793FFFC8796FFFC82961A -:10218000FFF802140000013C000000000001000004 -:102190000001000000020000000400000008000030 -:1021A000001000000020000000400000008000003F -:1021B0000100000002000000040000000800000010 -:1021C000100000002000000040000000800000001F -:1021D00000009293FFFC02900008F70678B0971376 -:1021E000FFFCF70679CC9713FFFC07880008E00096 -:1021F00015489793FFFCF706222C9713FFFCF70274 -:1022000000159713FFFCF70678B09713FFFC0788BB -:102210000008E000161C9793FFFC8796FFFC82964F -:10222000FFF802140000013C00000000000192933E -:10223000FFFC02900008F6846F440000000187361E -:10224000000000000001203A0002E6012270F602C0 -:10225000000087360EF486B60EF800000001C03A82 -:102260006A00470C0001203A0000E6012278203283 -:102270000000F602000120320000E6012294000076 -:102280000001F70432E800000001203A0000E601F6 -:1022900022B1F58203E80F814000F70479C80000FD -:1022A000000107380001F70579C8F70479C8F582FD -:1022B00003E89593FFFCF58200159593FFFCF586E6 -:1022C00079CC9593FFFC07880008E0011EC0979326 -:1022D000FFFC8796FFFC8296FFF802140000013C89 -:1022E0000000000000019293FFFC02900008F70636 -:1022F00079CC9713FFFCF70678B09713FFFC07889B -:102300000008E00014F49793FFFCF70679CC9713CC -:10231000FFFCF706793C9713FFFC07880008E000F4 -:1023200014F49793FFFC8796FFFC8296FFF8021443 -:102330000000013C000000000001C13C0000021050 -:1023400000049293FFFC029000082210000C859676 -:1023500000000000000186AE0004000000012036ED -:102360000000E60123842714000C872E00040000DF -:10237000000107380001972E0004872E0004E001B9 -:1023800024349696FFF49713FFFC85160004000092 -:1023900000019513FFFC9593FFFC9596FFEC0788D1 -:1023A0000008E00125689793FFFC8596FFEC20224A -:1023B0000000E60124340000000186AE0004861609 -:1023C000FFF400000001C0366200EE0124217735E1 -:1023D0000001C738680077390002C6B85800773165 -:1023E0000001C738600077390002C73858008536C9 -:1023F0000000000000019536000C85360004000046 -:102400000001953600108536000800000001953661 -:10241000001426B4000CC0367200EE0123EC00005C -:102420000001872E00040000000107380001972EEC -:102430000004872E00048696FFF485160004773585 -:102440000001C738680077390002C72C7000852A60 -:10245000000000000001953A000C85160004000001 -:102460000001852A000400000001953A001085163D -:102470000008F4020001953A001496AE0008879611 -:10248000FFFC8296FFF80214000C013C00000000E3 -:1024900000019293FFFC029000082210000C859628 -:1024A000000000000001842E000400000001202232 -:1024B0000000E60125552714000C9713FFFC851634 -:1024C0000004000000019513FFFC9593FFFC959616 -:1024D000FFEC07880008E00125689793FFFC8596CC -:1024E000FFEC20220000E6012555000000018616C1 -:1024F000FFF40000000120320000EE012545773195 -:102500000001C6AC0000C738600077390002C73848 -:10251000580085360018000000019536000C8536FD -:10252000001C0000000195360010853600200000D8 -:1025300000019536001406B4000CC0367200EC01A0 -:10254000251100000001872E0004F4020001273845 -:102550000001972E00048796FFFC8296FFF8021474 -:102560000008013C0000000000019293FFFC029073 -:102570000008221000088396000483160000C5009E -:102580000000841A0004C4A800009416FFF4C026BA -:102590004200E60126D1000000018316FFF400008E -:1025A0000001C02A3200E60126D1C7204A00951654 -:1025B000FFF476B8FFE1C73868007739FFFFC5241C -:1025C000700077290001C738500077390002831660 -:1025D0000000869E0000C5B8300005AC000C872EB8 -:1025E0000000C6000000C0367200E601261020324E -:1025F0000000869E0004872E000400000001C03603 -:102600007200E601261020320000F602000120329E -:102610000000E601262500000001C7000000E001DF -:102620002678203A0000869E0000872E00000000D9 -:102630000001C0367200E201265C00000001E601E4 -:10264000266420320000869E0004872E00040000CD -:102650000001C0367200E201266520320000F60259 -:102660000001203200004704FFFFE6012679203AEE -:102670000000F7020001203A0000E60126B1203AEE -:102680000000EE0126A0203A00014304FFFFC03AFB -:102690003200E60126C9C0264200E0012590000074 -:1026A0000001E60126C1C0264200E001259000009D -:1026B000000183160008F4020001E00126E0951AEB -:1026C0000000E001258CC4A80000E001258CC4288E -:1026D00000008316000800000001941A0000C400E6 -:1026E00000008796FFFC8296FFF80214000C013C64 -:1026F000000000000001000000009293FFFC029027 -:102700000008859600048416000084960008F702ED -:102710000003C6A04D80C6B67400E6012771C6202E -:10272000000020360002E60127A0C5204800C7208F -:10273000480027380002C0227200E201279CC538F9 -:102740000000872E000076AD001E76B4FFE5C73886 -:102750006FC07738FFF0F733280006300002C03230 -:102760005200E201274105AC0002E00127A0C5208C -:102770004800C720480027380004C0227200E20148 -:1027800027A0C520480083AD00040000000193B1DC -:102790000004C0327200E201278500000001C5205C -:1027A0004800C0325200E40127D50000000186AE87 -:1027B0000000772D001E7738FFE5C6B477C076B5E8 -:1027C000FFE8F6B3680006300001C0325200E401B1 -:1027D00027AC05AC00018796FFFC8296FFF8021437 -:1027E000000C013C0000000000019293FFFC0290ED -:1027F0000008841600008696000400000001C7222D -:102800006D80E601281020360000E0012874C438ED -:102810000000F7020001EE012841F602000076B543 -:10282000000120360000EE01281C77390001E0018C -:10283000284420220000742100017738FFFF063071 -:10284000000120220000EE012834203A0000E601B9 -:10285000287100000001C0226A00E4012864000021 -:102860000001C4206A00773AFFFFE601285476B4DD -:10287000FFFFD42007628796FFFC8296FFF80214C0 -:102880000008013C0000000000019293FFFC029050 -:10289000000822100004E00128CCF70629DC86BAE3 -:1028A00000000000000120360000E60128C90000F9 -:1028B00000019716FFF407880008C13400009793C1 -:1028C000FFFC8716FFF40000000127380004F6061D -:1028D00029E0C03A6200E401289D000000018796CB -:1028E000FFFC8296FFF802140000013C000000008B -:1028F00000019293FFFC0290000822100004E00106 -:102900002934F706299886BA000000000001203615 -:102910000000E6012931000000019716FFF4078846 -:102920000008C13400009793FFFC8716FFF40000F5 -:10293000000107380004F60629E0C03A6200E4010D -:102940002904000000018796FFFC8296FFF802141C -:102950000000013C0000000000019293FFFC029087 -:102960000008F7047B5000000001203A0000E60157 -:102970002984F6820001F6857B5007880008E00173 -:1029800028F09793FFFC8796FFFC8296FFF80214CD -:102990000000013C00000000000100000B4C0000A2 -:1029A0000000000042880000000000005E500000AF -:1029B00000000000C7A80000000000010BD00000CC -:1029C000000000011C880000000000011E1400002F -:1029D00000000001212C00000000000122E40000A2 -:0229E0000000F5 -:00000001FF -/* This is the Myrinet MCP code for LANai4.x */ -/* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */ diff --git a/firmware/ositech/Xilinx7OD.bin.ihex b/firmware/ositech/Xilinx7OD.bin.ihex deleted file mode 100644 index 03e80857a5495d8033f51b8038cf0d8fd171f9a9..0000000000000000000000000000000000000000 --- a/firmware/ositech/Xilinx7OD.bin.ihex +++ /dev/null @@ -1,177 +0,0 @@ -:10000000FF04A036F3ECFFFFFFDFFBFFF3FFFFFF72 -:10001000EF3FFFF7FFFFFFFFEF7FFEFFCEFEFEFE8D -:10002000FEDEBDDDFDFFFDCFF7BF7FFF7F3FFEBFE3 -:10003000FFFFFFBCFFFFBDB57F7FBFBF7FFFEFFFAF -:10004000FFFFFBFFF7F7FFFFFFFFFEDEFEFEFADE1E -:10005000BDFDEDFDFDCFEFEFEFEFC7DFDFDFDFDF52 -:10006000FF7EFEFD7D6DEEFE7CFBF4FBCFDBDFFF54 -:10007000FFBB7FFF7FFFF7FF9EBF3BBFBF7F7F7F41 -:100080007E6FDFEFF5F6FDF6F5EDEBFFEFEFEF7EC0 -:100090007F7F6F7FFFFEFEFEFEFEEFBFFFFFFFFFD5 -:1000A000FFFFFFFFFFFFBC1F1FEEFFBCB7FFDFFF1F -:1000B000DFEF3BE3D3FFFBFFFFDFFFFFFFBABF2D07 -:1000C000DBBDFDDBDFFAFBFFEFFBDBF3FFDFFD7FDB -:1000D000EFFBFFFFBEBF27BAFEFBDFFFF6FFFFEF20 -:1000E000FBDBF3D99A3FFFAFBFFFFFBE3F37BD96A3 -:1000F000FFFFFFFFFFFFAEFBF3F3EBFFFFFFFFFF91 -:10010000FFF7FABCAEFEBEFEBB7FFDFF7FEFF7FB45 -:10011000BBD7F77FFFF7FFFFF7BCEDFDBD9D7D7BF4 -:10012000FB7B7BFBAFFFFEFDFDFEFEFFFFFFFFF74E -:10013000AAB9BF8FBFDFFF7FFFFF7FCFFBEBCBEB0A -:10014000EEFFFFD7FFFFFF3E333F1C7CFCFFFFFFAE -:10015000FFFFCFD3F3E3F3FBFFFFFFFFFFEBFE3522 -:100160003F3DFDFDFFFFFFBFFFEF6FE3E3E3EFFF69 -:10017000FFDFFFFFF7FE3E5EFEFFFFFFFFFDFFFF1D -:10018000AFCFF2CBCF8EFFFFFFFFFFFDFC3E1F9EE8 -:10019000ADFDFFFFBFFFFFEFFFB3F7E7F7FAFFFF8C -:1001A000FFFFFFEEEBABAF9FE37FFFDEFF7FEEFFD6 -:1001B000FFFB3AFAFFF277FFFFF7FEFFFEBDAEDE70 -:1001C0007D7DFDFFBFEEFFFDFFDBFBFFF7EFFBFFDC -:1001D000FFFEFF2DAFB9FD79FBFAFFBFEFFFFF91E7 -:1001E000FAFBDFF7F7FFFFFFFCCF37BFBFFF7F7FD3 -:1001F000FFFFFFAFFFFFF3FBFBFFF5EFFFFFF7FA9A -:10020000FFFFEEFAFEFB55DDFF7FAFFEFFFBFBF5C8 -:10021000FFF7EFFFFFFFBEBDBDBDBD7D7B7B7B7BE1 -:10022000FBAEFFFDFEFFFFFFFFFFFFFFF7DAB76149 -:10023000FFB959F373F3DF7F6FDFEFF7EBEBD7FF16 -:10024000D7FFFFF7FE7FFB3E3873F67FFCFFFFCF43 -:10025000FFB7FBB3B367FFE7FDFFEFF67FB7BCF572 -:100260007BF6F7F5FFFFEFFFF7FFF7CEE7FF9FFF06 -:10027000FFF5FE7DFF5FFFFFFFFFFFFFFFEFFFF6D4 -:10028000CBDBEEFEFFDFFFFFFFFE7FBE1E3EFEFF6D -:100290007DFEFFFFEFBFE7FFE3E3FFDFE7FFFFFFC9 -:1002A000B8EFB72FEEFFDFFFBFFF7FEFEBBFA3D3AA -:1002B000FF7FFFFFFFFFF7BEFD3FCFFDFBFFFFFF0F -:1002C000FFFFAFFBBFBBBFDBFDFBFFFFFFFF3EFE42 -:1002D0003FBABAFEFFFFFFEFFFEFC37FB29BFFFF06 -:1002E000FFFFFEFFFF3CFF3F3CFFFEFFFFFFFFFF66 -:1002F000AFF3FEF3E3EBFFFFFFFBFFF79AFEAF9ECA -:10030000BEFEFFDFFFFF7BEFF7BFFBFBFBFFFF7FC7 -:10031000FFFFFFBCBDFDBDDD7D7B7B7B7BFBAEFFBF -:10032000FFFFFEFEFFFDFFFFFFF79AFF9FFFAFEF0E -:10033000FFFFFFFF7FCFF3FFEBFFEBFFFFBFFFFFF1 -:10034000EFFEFF37FCBFFFFFFFFFFFFFCFEFFDF327 -:10035000FFEEFEFFFFFFFFFF6EFD2FFDFFFDFFFF26 -:10036000FFFFFFEFCFFFF3BF69FFFFFFFFFFFFFEC0 -:10037000FB9FFFBFFDFFFFFFFFFFEF87FEDAEFCF21 -:10038000FFFFFFFFFFFFFEEFBFEFEFFDFFFFFFFFF0 -:10039000FFEFFDFF7BFFEBFEFFFFFFFFEBF8FFEF43 -:1003A000AFFFFFBDFFFFFF7FEE7FEFFFBBFFBFFB98 -:1003B000FFFFFFF7F6FBBDFDDDF5FFFFFFFFFFAF22 -:1003C000FF5FF5DFFF7FFFFFFFFFFFF6F3FFDEFEBE -:1003D000EFFDFFFFFFFFEFFFDEDF5FDFFDFFFFFF52 -:1003E000FFFFFEFFFFFEFEFFFDFFFFFFFFAFFFFF72 -:1003F000EFEDFFDFFFFFFBFFFFDABDBEAEFE7FFDCF -:10040000DFFFFF7FEFFFFBFBFB7FF7FFFFFFFFF748 -:10041000BCFDBDBDBDFD7B7B7B7BFBAEFFFFFDFF60 -:10042000FFFFFDFFFFFFFFFA9FBFBFCF7FFFFFFF73 -:10043000FFFFAFFFEBEBEBFFD7FEFFFFBFE7FEBF1A -:100440007FFCFFFFEDFFFFFFFF4FFFFBFBFFFFDD2B -:10045000FFFFFFFFFFFEBDDF9DFDDFB9FFFFFFFFD9 -:10046000EFFFFBEFEBFFDEFFFFFFFFFFF69FFFFC61 -:10047000FEFBFDFFFFFFFFEFDFFACDCFBF9FFFFFCA -:10048000FFFFF7FEBFFFDFEF5FFFFFFFFF7F6FFFA5 -:10049000BBFDFFFFFFFFFFFFFFFF7EFF5FFFBFBF53 -:1004A000F9FFFFFF7F6E7BFFEFFDEBDFFFFFFFFF3D -:1004B000F7B63EFCFDBF7EFBFFFFFFF7EFF7F3F75C -:1004C000FFFBFFFFFFFFFFFF6E3579FFBFFCFFFF64 -:1004D000FFFFFFEFFB53DFFFEBBFFFFFFFFFFFBCA3 -:1004E000FFFFFFBFFFFDFFFFFFFFAFF5FFF7FFFBC4 -:1004F000FFFFFFFFFFFFBAAAEEFE3F7DFDFFFFFFFC -:100500007FAF77FBFBFFFBF7FFFFFFFFF7BEBDBD34 -:10051000BDBDFD7B7B7B7BFBAEFFEFFFFFFFFFFCE9 -:10052000FFFFFFFF9AD9B8FFFF79FFFFFFFFFFCF63 -:10053000FBFFEBFFEBD7FFFFFFFFE7DEF8FBFE3F24 -:10054000FBFDFFFFFFFFCFADBFFAFF73DFFFFFFF34 -:10055000FFFF3AF5B7FC3FF9FDFFFFFF7FEFF3FF29 -:10056000BFFEF39FFEFFFFFFF73EFFFFFFBFFFFF52 -:10057000FFFFFFFFAFD3FEDBFFDBDFFFFFFFFFFF70 -:100580003EFFBFFF7FFFFDFFFFFFFF8FF3FFEDFF8C -:10059000F7FBFFFFFFFFEFF63CFEFFFFFFFFFFFF54 -:1005A000FF9FEFEFD1FFFFFFFFFFFFFFFFFF7EBFCA -:1005B000FDFFFFFFFFFFFFFFBBEFDFF1FFFFFFFFCF -:1005C000FFFFFFFFFFEE3EFEFFFFFFFFFFFFFFBF4E -:1005D000EFFDC3FFFFFFFFFFFFFFBFFFFC3EFEFF7E -:1005E000FFFFFFFFFFFFFF2EEFF3FFFFFFFFFFFF08 -:1005F000FFFFF7BABEFEFFFFFFFFFFFFFF7FAFFB6E -:10060000FBFDFFFFFFFEFFFFFFF2D6EDBDBDBD7D91 -:100610007B7B7B7BFBAFDFFFFFFFFFFFFFFFFFFF6E -:10062000FF92BFFFFFFFFFFFFFFFFF7FAFEBEBFF7F -:10063000FFFFFFFFFFFFFFE7FE2EFEFFFFFFFFFFB5 -:10064000FFFFFF4FEFF3FFFFFFFFFFFFFFFFFFFE87 -:100650003CFEFFFFFFFFFFFFFFFFEFCEC3FDFFFFED -:10066000FFFFFFFFFFFFFE5DFFFFFFFFFFFFFFFF3D -:10067000FFEFCFEBFFFFFFFFFFFFFFFFF7EE3EFFB8 -:10068000FFFFFFFFFFFFFF7FEFDFE2FFFFFFFBFF4B -:10069000FFFFFFFFF6BEFCFFFFFFFFFFFFFF7FEE48 -:1006A0005FE6FFFFFFFFFFFFFFFFFF3E7DFFFFFF56 -:1006B000FFFFFFFFFFFFEFF3FBFFFFFFFFFFFFFF6A -:1006C000BFF736BEFEFFFFFFFFFFFFFFFFEFD3F6D2 -:1006D000FEFFFFFFFFFFFFFFFFFC7FEEFFFFFFFFBF -:1006E000FFFFFFFFAFEFEBFFFFFFFFFFFFFFFFFF8E -:1006F000BABEFEFFFFFFFFFFFFFFFFEEFBFAFFFFAB -:10070000FFFFFFFFFFFFF7D6FDBDBDBD7D7B7B7B00 -:100710007BFBAEFF7EFFFFFFFFFFFFFFFFF7BABFD0 -:10072000FFFFFFFFFFFFFFFF7FEFEB6BFFFFFFFF11 -:10073000FFFFFFFFF7FEBEFEFFFFFFFFFFFFFFFF14 -:100740004FEFF7FFFFFFFFFFFFFFFFEF3E6EFCFFE6 -:10075000FFFFFFFFFFFFFFEFC3C9FFFFFFFFFFFF2B -:10076000FFFFFF3EBFFFFFFFFFFFFFFFFFFFEFFBAE -:10077000D5FFFFFFFFFFFFFFFFFFFEFEFEFFFFFFB6 -:10078000FFFFFFFFFF6FEFFBFFFFFFFBFFFFFFFF21 -:10079000FFF6DFFFFFFFFFFFFFFF7FFEEFFFFFFF23 -:1007A000FFFFFFFFFFFFE7FFFEFFF7FFFFFFFFFF7A -:1007B000FF7FFAEFBFFFFFFFFFFFFFFFFFE7FFFE37 -:1007C000FFFFFFFFFFFFFFFF7FFEEFBFFFFFFFFF0A -:1007D000FFFFFFFFA7FFFCF7FFFFFFFFFFFFFF7F0C -:1007E000FEAEFFFFFDFFFFFFFFFFFFE7F7FAFFFD94 -:1007F000FFFFFFFFFFFFFF7FAFFFFFFFFFFFFFFFD9 -:10080000FFFFFFF7BEBDBDBDBD7D7B7B7B7BFBAF2F -:100810007FFFFFFFFFFFFFFFFFFFFFCAFFFFFFFF9D -:10082000FFFFFFFFFF7F6FFFFFFFFFFFFFFFFFFFE8 -:10083000FFE7FEFFFFFFFFFFFFFFFFFFFFCFFEFF12 -:10084000FFFFFFFFFFFFFFFFFFFEDFFFFFFFFFFFD9 -:10085000FFFFFFFFEFFFFEFFFFFFFFFFFFFFFFFFB9 -:10086000FEFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFA9 -:10087000FFFFFFFFFFFFF7FEFFFFFFFFFFFFFFFF91 -:10088000FFFFEFFFFEFFFFFFFBFFFFFFFFE7F2FCB5 -:10089000EFFFFFFFFFFFFFFF7FAEEFFFFFFFFFFF59 -:1008A000FFFFFFFFF77EFDFFFFFFFFFFFFFFFFFFE3 -:1008B000EFFFFEFFFFFFBFFFFFFFBFFFFEFEFFFFDB -:1008C000FFFFFFFFFFFFDFEFDDFEFFFFFFFFFFFF8B -:1008D000FFFFFFFEFEFFFFFFFFFFFFFFFFFFAFEF8A -:1008E000FFFFFFFFFFFFFFFFFFFFBAFEFFFFFFFF5E -:1008F000FFFFFFFFFFEFFAFEFFFFFFFFFFFFFFFF1E -:10090000F69CBDBDBDBD7D7B7B7B7BFBAEFFFFFF52 -:10091000FFFFFFFFFFFFFFF77AFFFFFFFFDFFFFF94 -:10092000FFFF6FEFF7FFFFFFDFFFFFFFFFFFF7FEA8 -:10093000FEFFFFFFDFFFFFFFFFFFCFEBFFFFFFFF2C -:10094000FFFFFFFFFFEF9EFCFFFFFFFFFFFFFFFF2B -:10095000FFEFEFFFFFFFFFFFFFFFFFFFFFFEFFFFC8 -:10096000FFFFFFFFFFFFFF7FEFCBFFFFFFFFFFFD5D -:10097000FFFFFFFFBEFDFFFFFFFFFFFFFFFFFFEFDA -:10098000EFFFFFFFDFFFFFFFFFFFFFF8FFFFFFFFAE -:10099000BFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFB7 -:1009A000FFFFFEFFFFFFFFFFFFFFFFFFFBAF7FFF2C -:1009B000FFFFDFFFFFFFFFFFFFFEEFFFFFFFFFFF78 -:1009C000FFFFFFFFEFFFFFFFFFFFFFFFFFFFBFFF87 -:1009D000FEFFFFFFFFFFFFFFFFFFFFAEFFFFFFFF79 -:1009E000FFFFFFFFFFFFF7FAFFFFFFFFFFFFFFFF24 -:1009F000FF7FEFFFFFFFFFFFFFFFFFFFFFF7BCBD24 -:100A0000BDBDBD7D7B7B7B7BFBAFFFFFFFFFFFFFA2 -:100A1000FFFFFFFFF7FAFFFFFFFFFFFFFFFFFF7F73 -:100A2000AF7FFFFFFFFFFFFFFFFFFFEFFEFFFFFFB7 -:100A3000FFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFF6 -:100A4000FFFFFFFEFFFFFFFFFFFFFBFFFFFFEFFFCB -:100A5000FFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFA7 -:100A6000FFFFFFFFFFEFFFFFFFFFFFFFBFFFFFFFE6 -:100A7000FFFCFFFFFFFFFFFFFFFFFFFFEFFFFFFF99 -:100A8000FFFFFBFFFFFFFFEFFEFF9F9F9F3F3F3FEB -:100A90003F3FFFEFDFDFDFDFCFB7BFBFBFBFFFBC31 -:100AA000B99DBDBD7D7B7B7B7BFBEFD7F5F3F1D1A2 -:100AB00065E3E3E3A3FFFE7FFEDEDEFFBDBDBDBD5C -:100AC000DFEFFBF7F3F3F3E7E7E7E7E7FBFEFFFF13 -:0A0AD000FFFFFFFFFFFFFFFFFFFF26 -:00000001FF -This file contains the firmware of Seven of Diamonds from OSITECH. -(Special thanks to Kevin MacPherson of OSITECH) diff --git a/firmware/qlogic/1040.bin.ihex b/firmware/qlogic/1040.bin.ihex deleted file mode 100644 index d1213307f713d10380fd572a542e23118cd5512e..0000000000000000000000000000000000000000 --- a/firmware/qlogic/1040.bin.ihex +++ /dev/null @@ -1,2111 +0,0 @@ -:1000000007410600001078003A1000005841000037 -:100010004320504F525947495448312039392035EF -:100020004C51474F43494320524F4F50415249543E -:100030004E4F49205053303130324920542F462002 -:100040007269776D726120655620726569736E6F93 -:1000500030202E3735362020432073756F74656D40 -:1000600020726F4E202E303050206F727564746392 -:100070004E202E6F2020313024200120FD0404204A -:1000800082A005004800451038004B10780047104A -:1000900028004B10B920121278004D10B9202222EE -:1000A000C120080071201000C3700400C920FF782F -:1000B00089208611C7705349CB702050CF70202003 -:1000C000D3700700003FD670C1200800192000003F -:1000D0000920FFFE00210B20A5A5ECA1FF7F642DC8 -:1000E0006B200A0ADCADFF3F542B5B2050501421DB -:1000F00086A2A5A54000BF1086A30F004000851072 -:100100006A2C5A2AC120000019200F0078006510BF -:100110006A2C5A2AC12008000920FF7F482144295F -:100120004B200A0ABCA9FF3F34273B205050142122 -:1001300086A20A0A4000A9104A283A26C1200400D3 -:100140000920FF3F34210B205050142186A250502B -:100150004000AA1078008E114A283A26C09888A13B -:1001600000102C210B20A5A5142186A2A5A54000D6 -:10017000BC100A258AA10010C1987800C1100A2578 -:100180007800C1106A2C5A2A30218AA14000282107 -:10019000A2A10052248424842484248424842484DA -:1001A00092A1007909200000012031007810261D5D -:1001B000182279200052A02F082411200000A92025 -:1001C0004000A4420981C000DC10F27E2885E67D53 -:1001D000EA7CEE7B8378000031203000CF7801018B -:1001E0000B7802000F7802004F780300692040521C -:1001F0000120FD04042082A00500480004113800FD -:100200000011780008111B683C0078000A11A80052 -:1002100008111B683C001B682800076807000B6872 -:10022000FA000F68080013680500236800002768BB -:100230000600176808002B6800001F681900692075 -:10024000805411202000092010000B680C080F6852 -:100250001900036800FD076818001A6A002DE8A05D -:10026000080090A204000981C000221169200055F5 -:1002700009200200A9200001376800000B68400037 -:10028000F07B86A3FFFEC0004811176800011F68BD -:10029000640078004C11176864001F680200E8AD24 -:1002A000100070005211780039110981C000371117 -:1002B0007810A72278103D497810B5197810334E80 -:1002C000003285A00D009020C370000090006C11DA -:1002D000C07086A00200C0006C11781084127810E3 -:1002E0009611CC7805A0C0007A1178104F1D10002F -:1002F000801168008011781086211000801168003C -:1003000080117810B91AE0006C117810BA4C78009E -:100310006C118E119011AC24AC24BE49BE49AC24A2 -:10032000AC2478008E11780090117800921178003A -:1003300094116800011261200000186084A001007F -:10034000C0000112147805A0C000A711100002120D -:100350007800011209205B52042105A0C00001129F -:10036000092064520B200000147986A14200C000CD -:10037000CC1116780920625264210B20000018600D -:10038000C6701460CA701C618CA100FF206084A03C -:10039000FF0005A1CE7078109A197800FF1114782B -:1003A00086A01800C000D3117810781617780000C6 -:1003B00009206252042165A04000EF117E0C9C6070 -:1003C00060207810171A7F0C9F60000078104E177D -:1003D00009200C000760030178107619C000FB119A -:1003E00078109A19092062520B20000009205C52F3 -:1003F00004210B20000005A04000FF110120054052 -:1004000078008612780084127C00C3700000C770E8 -:100410000000CB700000CF700000C070BCA0C0FF17 -:10042000C00052123820790012128412E512A9126B -:10043000FE120D131313A012661717139812AD12A4 -:10044000AF12B112B3126B179812291365139016DD -:100450006017B512AF15CB15E7151216681576158E -:100460008A159E15E913981297139D13A213A713CB -:10047000AD13B213B713BC13C113C513DA13E613CC -:100480009812981298129812F513FE130D14511425 -:100490005B146214A814B714C614D8144815581560 -:1004A00098129812981298125D15BCA0A0FFC00077 -:1004B0009812382084A01F0079005B12A417A71798 -:1004C000B7179812981231194E199812981298125B -:1004D00052195A199812981298129812DB12F412A3 -:1004E0001F135B1386168217961798124718601908 -:1004F0000D1917191B19291998129812CA72C67169 -:100500000120064078008612CE73CA72C67101209F -:100510000040C27068008712612000001B6001006B -:1005200091200050E0008F12E000911268009112BB -:10053000912080407C00C370014078008712C37016 -:1005400006407800871299204100A1204100A9208F -:100550000500A35378008412C470C37004007A00AD -:100560007800841278008412780084127800841253 -:1005700091200080C3700000C7705349CB70205099 -:10058000CF702020D3700700003FD6707920000084 -:100590001B78010031203000592000102920570419 -:1005A0005120700461207204B920FFFFC1200000B7 -:1005B0009120005091208040780055047810C41B91 -:1005C000C0009C12D875DC74DA75DE747800E8120D -:1005D000292000002025D071C873CC72C470781017 -:1005E000FE1A40008412C370024078008412781012 -:1005F000C41BC0009C12D875DC74DA75DE747800F8 -:100600000113292000002025D071C873CC72C4705A -:1006100078105E1B40008412C37002407800841280 -:10062000C471C87014210A2078008212C471142188 -:1006300078008212C7700700CB704100CF700600AF -:10064000780084127810C41BC0009C12D875DC7628 -:10065000DA75DE7678002C13292000003025C4706E -:10066000C872CC73D074C670CA72CE73D27405A02F -:10067000400055130AA440003C13C80046130180F3 -:10068000927884A000FC40004A13CC7885A0010039 -:10069000CE7801200540780086129A7A9E7BA27D52 -:1006A000A67E967CCC7884A0FCFFCE787800591387 -:1006B000CC7885A00100CE78780084127810C41B15 -:1006C000C0009C12D875DC76DA75DE767800681387 -:1006D000292000003025C470C872CC73D474C67051 -:1006E000CA72CE73D67405A0400091130AA44000CC -:1006F0007813C80082130180AE7884A000FC40000B -:100700008613CC7885A00001CE78012005407800C2 -:100710008612B67ABA7BBE7DC27EB27CCC7884A0CB -:10072000FFFCCE7878009513CC7885A00001CE78B8 -:1007300078008412092061520C21EC7A7800821230 -:10074000092041520C2178008312092042520C21C9 -:1007500078008312612040520C611062780082128E -:10076000092045520C2178008312092046520C21A1 -:1007700078008312092048520C2178008312092046 -:1007800049520C217800831208790C7A7800821281 -:10079000C471078184A00F00038003800380E8A058 -:1007A0008054006A046884A008004000D713086BD6 -:1007B0007800D8130C6B78008112C4777810C519B3 -:1007C000912000801C6B146A91200180082778001A -:1007D00081124C7978008312C4777810C519912062 -:1007E00000800869186A106B9120018078008112DE -:1007F000C47182A11000C8007C1278107F23780099 -:100800008112C47182A11000C8007C1211204152D3 -:1008100004227E001221781038237F017800831291 -:10082000C47119200001042382A0060048001B1493 -:1008300011204914A920080078001F141120411428 -:10084000A9200800042206A140002A14108270008A -:10085000281478001F1478007C12042382A006005C -:100860004800331492A249147800351492A241141E -:100870007E0211204252042212217F017E00781054 -:1008800044237F0178008312E803FA00F401EE02AA -:100890006400190032004B00E803FA00F401EE0294 -:1008A0000400010002000300612040520C6110624C -:1008B000C4700E60C87012607800821261204052CD -:1008C0001461C47016607800831261204052C471B4 -:1008D000112004001F6019001920121286A128009F -:1008E00040008314112005001F6019001920121206 -:1008F00086A1320040008314112006001F600C0006 -:100900001920222286A13C00C0007C1218607E00C3 -:100910001A61007884A00100C0009E140120FD042B -:10092000042082A005004800961438009A1478002C -:100930009E1428009A1478009E1419202222780010 -:10094000A01419201212B823781055237810334EB2 -:100950007F0178008312C47184A1CFFFC0007C1294 -:1009600011204852042212217E00781077237F0143 -:1009700078008312C47182A11000C8007C1211207B -:10098000495204227E001221781066237F017800EC -:100990008312C471C87284A1FDFFC0007B1284A2BF -:1009A000FDFFC0007B12002108790A7800220C7A32 -:1009B0000E7878008212C471078184A00F00038032 -:1009C00003800380E8A0805419200000C872BCD2C4 -:1009D0004000E9149DA31000B4D24000EE149DA382 -:1009E000080000687E0026A240001115026A84A457 -:1009F00000204000FA149DA3100084A400104000C1 -:100A000000159DA3080084A40040400011150F812B -:100A100084A2004040000D1578109923780011152C -:100A200078108B2378001115CC72086806A240005C -:100A30004015A4A2FF0061204052186186A1280041 -:100A40004000271586A1320040002D1586A13C00EC -:100A50004000331582A4640048003D157800371526 -:100A600082A4500048003D157800371582A4430049 -:100A700048003D15C471C6717F02CA7278007D12AC -:100A80000A6A9DA30A00046805A306687F020C6B2E -:100A9000C47178008112C4777810C5199120008044 -:100AA000146A1C6B91200180C8701668CC701E6897 -:100AB000082778008112C4704C794E787800831230 -:100AC000C471C872CC7382A11000C8007C12781067 -:100AD000A72378008112C4777810C519912000806F -:100AE000086A95A202000A6A91200180082778000E -:100AF0008212C4777810C51991200080086A94A2E8 -:100B0000F9FF0A6A046805A04000851578106F2275 -:100B100091200180082778008212C4777810C519C7 -:100B200091200080086A95A204000A6A046805A062 -:100B30004000991578106F229120018008277800D5 -:100B40008212C47741200100492005005120200075 -:100B5000912000807810D219912001800827086A1E -:100B600078008212C477C872CC73C677CA72CE730B -:100B70007810521AC000C715186805A04000C715A4 -:100B800008277810B723C000C715177815009120E3 -:100B900001807C009120018078008412C477C677A0 -:100BA0004120210049200500512020009120008093 -:100BB0007810D219612040526F6003008267936001 -:100BC0000F00736000001778160078106F229120D4 -:100BD00001807C00C877CA77C477C677BCA700FFBE -:100BE00091200080612040526F600200736000001D -:100BF000826793600F001778170078106F2291209A -:100C00000180412021004920040051201000912042 -:100C100000807810D219C8703668388784A71F0002 -:100C2000C0000616912001807C00CC7884A00300CF -:100C3000C000361639200000412021004920040060 -:100C4000512008007810C5199120008008680DA86F -:100C50000A6991200180388784A71F00C0001F16F1 -:100C6000BCA700FF3F8738873F8784A7000FC000DD -:100C70001F169120008069200001306884A0400088 -:100C800040005F164B680400A9201400486884A047 -:100C9000040040004C1670004C16780043164B6858 -:100CA0000900A9201400486884A0010040005916DA -:100CB0007000591678005016A920FA0070005F16CF -:100CC00078005B1679200052177818006120405296 -:100CD0006F6001007360000093600F00CC7885A006 -:100CE0000200CE78086884A0FDFF0A681B684800EF -:100CF000912001807C00CC7884A0FDFFCE7884A078 -:100D00000100C000821678109C1AC471C6714A791D -:100D10007C007810C41BC0009C12D875DC74DA7596 -:100D2000DE7478009316292000002025C471C87352 -:100D3000CC72C671CA73CE727920005291200080A5 -:100D4000781080199120018040004A17A9200500E1 -:100D5000A120185291200080A141912001800920FA -:100D6000200078107B194000B61678109A19780088 -:100D70004A17046084A000FF07800980400019170B -:100D80007E0C682C912000807810801991200180C1 -:100D90004000EA16002C9E680981C000BE169F60C4 -:100DA00000007F0C7E0C18721C7320742475682C54 -:100DB0009C6865A0400018170920200078107B1956 -:100DC000C0000117046084A0FF0086A00200C000DC -:100DD000EA16002D02607800D0167F0C7E0C9C6015 -:100DE00060207810171A7F0C9F60000078104E1753 -:100DF00009200C00086085A000020A6078107619AE -:100E000078109A1978004A177F0C7E0C9C6060203D -:100E10007810171A7F0C9F60000078104E17092079 -:100E20000C00076003011B6003007810761978102E -:100E30009A1978004A177F0CC474C873CC72146076 -:100E400091200080177812007E0E712040526F7042 -:100E500005007370000076737A727E7482708770FA -:100E60000000002C8A708F7000002EA030251C61BD -:100E7000A26184A1600040003C177810D3487F0E27 -:100E80009665A6659A66AA66AF600000B36000002A -:100E900078106F22912001807C00C370054078009B -:100EA0008712A920050099201852912000800A532A -:100EB00091200180002110A299A30000A1A40000AC -:100EC000A9A500007C00C471C770000006797800F5 -:100ED0008412C471C671682178006D1769200010F2 -:100EE0000C6916A0042D10A2688D0981C0006F172F -:100EF00085A20000C0007D17C370004078007F17F6 -:100F0000C3700340CA7078008712112067520C2208 -:100F1000C470038048008F177810513C84A1FF7F74 -:100F2000780093177810443C85A100801220780047 -:100F30008312C47178103B3C006101206752042089 -:100F400084A000800DA10462086378008112E47916 -:100F500078008312C471C6719821A1204200A92093 -:100F60000400A353A02199204200A9200400A35308 -:100F700078008412C470682079200052912000808B -:100F8000781080199120018040004318076001000B -:100F90000B6000002B6000001B600600106A8CA232 -:100FA0000F0084A2F000038003800380038005A16A -:100FB000166084A200084000DE171B600A0078005B -:100FC000E41784A200104000E4171B600C0084A208 -:100FD00000034000ED172B600100048004800480B2 -:100FE00085A001001E60236000002760000084A22D -:100FF00000044000FA172B600000A920060080AC16 -:101000000B00A02080AD05009820A35384A200030C -:10101000C0000F1846604A604E60526096609A6049 -:10102000780019180068466004684A60086E4E66C9 -:101030000C6D526596659A66146091200080177851 -:101040004200082C612040526F6005007360000070 -:10105000776000007B6000007F60000082608A6132 -:1010600084A200048E60912001807E0E71202000F9 -:1010700007700A0007700200037000007F0E9120C5 -:10108000008078106F22912001807C00C3700540A1 -:10109000780087127E0C7E0D7E0E7E0F91200080E0 -:1010A000712040527920000161201000A0706DA0D5 -:1010B00040000319046A94A2FF0086A207004000C2 -:1010C000621886A20F00C00003191C6984A1C00029 -:1010D0004000031984A18000C000D318246884A0B4 -:1010E00000FF85A019002668B071FF8140008918B3 -:1010F0007E0D69202000076810000869086806A1B5 -:10110000C0007A180C690C6806A1C0007F1884A181 -:10111000FF00C0007F187F0DB87884A01F80C0003A -:101120008918487885A00C004A78B071FF8140008A -:10113000AC18B37000007E0D69202000076818000D -:10114000046884A00800C0009D18076808000468AF -:1011500084A00800C000A418076802007F0DC461C5 -:10116000C862CC63C661CA62CE637E0E7120005233 -:1011700066726A7380AE19007F0E487884A00C00F6 -:10118000C000BA187810E147A3780000587884A00E -:10119000FFED5A78B47080A0DA001A787F0F7F0EC6 -:1011A0007F0D7F0C9120018078008412246884A038 -:1011B00000FF85A019002668B87884A01F80C000B1 -:1011C000D918487885A00C004A78487884A00C008B -:1011D000C000E218B071FF8140000119B370000037 -:1011E0007E0D6920200007681800046884A00800AC -:1011F000C000F21807680800046884A00800C00056 -:10120000F918076802007F0D7800CB187F0F7F0E5A -:101210007F0D7F0C9120018001200540780086120F -:101220008079C671C47182A10300C8007C128279E2 -:10123000780084128079C671780084127479C6713E -:10124000C47176797879CA71C8717A797C79CE71EE -:10125000CC717E79780084127479C6717879CA71FC -:101260007C79CE71780084120079C671C4710279DC -:101270000120FD04042082A0050048004019380028 -:10128000421978004C19A8004C198CA10100C0002B -:101290004A19B920222278004C19B920121278007C -:1012A00084120079C67178008412092074520421D6 -:1012B000C670C4700A207800841209207452042178 -:1012C000C67078008412C471078184A00F00038067 -:1012D00003800380E8A08054146AB4D240007119DE -:1012E0001120010078007319112000000C6B7800A8 -:1012F000811280AC01007810801B7C0080AC010062 -:101300007810201B7C00507865A040008819042CC0 -:101310005278632000007C007E0F792000525078C4 -:101320006DA040009819042D5278036800000768EA -:1013300000000B6800007F0F7C00912000807E0F72 -:101340007920005250786220002C05A0C000A71917 -:1013500078108C2452787F0F912001807C007E0FC2 -:101360007920005250786A20002D52787F0F7C003F -:1013700011200079527AEC7B19834000C21980A2B7 -:101380003100122010207800B919132000007C00D1 -:1013900084A7000F0B8084A71F00038003800380B5 -:1013A000038005A1E8A000557C007810C51900292C -:1013B0002A68002A2E68086884A0EFFF0DA80A6931 -:1013C000092052520C21046805A04000041A16A1FD -:1013D000C000EF196020006006687E010B2000004D -:1013E0007800F219092000007E01046865A0400021 -:1013F000011A006006687810311A7810CB1C10684A -:1014000001801268C000F2197F01026906697C0040 -:1014100065A04000161A08209C6005A04000131A21 -:1014200062209F60000065A07800091A5078527908 -:1014300062207C0065A04000301A08209C6005A056 -:101440004000251A62209F60000065A078001B1AEA -:101450007E0F7920005291200080507852797F0FC2 -:101460006220912001807C00076003018F600000F2 -:10147000A9201C0080AC0500A02001200000A44091 -:1014800028681A602C6822607C007E0E7120405211 -:101490004C708CA00002C000501A88A080520A2D07 -:1014A00000804E7006A07F0E7C007810C519912038 -:1014B000008004681E7865A040009B1A7800631ABB -:1014C000002C1E78006065A040009B1A0C6006A3EB -:1014D000C0005D1A106006A2C0005D1A282C012011 -:1014E0005252042006ACC000741A7800991A04689D -:1014F00006ACC000811A006065A00668C0008B1AA7 -:101500000368000078008B1A00641C786020026475 -:1015100086A40000C0008B1A002C02686025781099 -:10152000311A1B600500236020007810CB1C106866 -:10153000018050108C24126885A0FFFF7C003920A8 -:101540000000412021004920040051200800912082 -:1015500000807810D219388784A71F00C000A61A0F -:10156000BCA700FF3F8738873F8784A7000FC000D4 -:10157000A61A912001807C0061200000186084A0E0 -:101580000100C000CA1A91200080E078E3780000D2 -:101590009120018005A0C000CB1A7C008CA0F0FF38 -:1015A0004000D11A78108C247900D31AE31AE61A75 -:1015B000EC1AF01AE41AF41AFA1AE41AE41A951C4E -:1015C000B91CBD1CE41AE41AE41AE41A7C00781071 -:1015D0008C2478109C1A012001807800C31C012003 -:1015E00003807800C31C012004807800C31C78109D -:1015F0009C1A012006807800C31C01200780780017 -:10160000C31C3020382182A721004800061B092076 -:10161000200000267810201BC0001F1BBAA7200046 -:1016200048001E1B40001E1B0827B0A6200090A2E9 -:10163000400099A30000A1A40000A9A50000780023 -:10164000001B06A07C00FF8140005B1B992030003E -:10165000A0200C7084A0FF004000321B0770040023 -:10166000047084A00400C0002D1BA8211770000086 -:101670000B8112711A721E73227426750C7885A064 -:1016800001000270077001000120FD04042082A007 -:101690000500C8004F1B09202200042184A000403F -:1016A000C000411B08700B80C800411B077002007E -:1016B0008CA0E001C0005B1BA55306A003700000D6 -:1016C0007C003020382182A721004800661B0920B9 -:1016D000200000267810801BC0007F1BBAA72000C6 -:1016E00048007E1B40007E1B0827B0A6200090A269 -:1016F000400099A30000A1A40000A9A50000780063 -:10170000601B06A07C00FF814000C11B9820A12027 -:1017100030000C7084A0FF004000921B0770040092 -:10172000047084A00400C0008D1BA8211770000065 -:101730000B8112711A721E73227426750C7885A0A3 -:1017400000000270A653077001000120FD04042070 -:1017500082A00500C800B01B09202200042184A03B -:101760000040C000A21B107084A000F04000B91B14 -:10177000077008007800BD1B08710381C800A21B18 -:101780000770020084A1E001037000007C000120CA -:10179000FD04042082A00400C800CD1B7800D01BEB -:1017A00006A07800D21B85A001007C007E0E71206F -:1017B0000052082D5870026805A0C000DD1B5E7144 -:1017C0005A717F0E7C00082C5878026005A0C0007A -:1017D000E71B5E795A797C009120008014617810B3 -:1017E0008021006984A10001C000352084A100028D -:1017F000C00031201C6805A0C0003D20036000002F -:10180000082C5C7865A0C000051C5A797800061C7D -:1018100002615E799120018078108C227C007E0E1E -:101820007120005258706DA040001A1C00685A7058 -:1018300005A0C000191C5E70FF8D7F0E7C007E0D20 -:101840007E0C7E0F7920005280AF16006020006071 -:1018500005A04000431C6820146806A3C000331C88 -:10186000286884A0FF0006A44000361C602D780084 -:10187000241C006805A00260C000421C80AF160056 -:1018800006AC4000411C002C5E78002D7F0F7F0CC1 -:101890007F0D05A07C007E0D7E0C7E0F792000520E -:1018A00080AF16006020006005A040006B1C68201F -:1018B000146884A0FF0006A340005E1C602D780021 -:1018C000501C006805A00260C0006A1C80AF1600B2 -:1018D00006AC4000691C002C5E78002D7F0F7F0C49 -:1018E0007F0D05A07C007E0D7E0C7E0F79200052BE -:1018F00080AF1600602000606DA04000901C14684E -:1019000006A34000831C602D7800781C006805A0A9 -:101910000260C0008F1C80AF160006AC40008E1C19 -:10192000002C5E78002D7F0F7F0C7F0D05A07C00C2 -:101930009120008069204052006886A0000040008D -:10194000A31C91200180E37809007C008068BCA082 -:1019500000FF412021004920040051201000781090 -:10196000D219388784A71F00C000AC1C91200180C9 -:1019700001200A807800C31C01200C807800C31C61 -:1019800078109C1A01200D807800C31CC270612061 -:1019900000001B600100912080407C000460082C46 -:1019A00063200000847800808678887805A08A7992 -:1019B0004000DA1C022C7800DB1C8E797C00076862 -:1019C00003017E0C61200052082D6B200000846012 -:1019D00000808660886005A08A614000EF1C022DAF -:1019E0007800F01C8E617F0C7C007810031D400095 -:1019F000021D7E0C9C6065A04000FD1C7810171A2B -:101A00007F0C9F60000078109A197C008C7865A08C -:101A10004000151D91200080847801808678042C78 -:101A20008E7805A0C000131D8A7800809120018067 -:101A30007C00A920100006A0048086808E81C8004A -:101A40001F1D00A27000231D78001A1D86808E8144 -:101A50007C007E15A920100005A04000491D1AA198 -:101A6000C800491D13828D8148003A1D1AA1C80083 -:101A70003B1D7000411D78002F1D1AA10823108204 -:101A80007000411D78002F1D7E00003284A0FFF7FA -:101A900080207F007F157C007E00003285A000083A -:101AA0007800451D9479D07006A14000BD1D91209D -:101AB000008071202000047005A0C000BD1D0870CA -:101AC000087206A2C000BD1D86A20800C000BD1D90 -:101AD00071201000781080194000BD1D9C7A987B01 -:101AE000A47CA07D84A100FF40008B1D312000005C -:101AF0000B81B5860B81B5860B81B5860B81B586CA -:101B00000B81B5860B81B586002110A2002619A392 -:101B1000A1A40000A9A500007800951D07810480FC -:101B2000048010A299A30000A1A40000A9A50000B0 -:101B30000920200078107B19912001804000B41DFD -:101B400078109A19A8780080AA7886A00200C000B0 -:101B5000BD1D91200080E3780200AB780000CC78B6 -:101B600085A00300CE78912001807800BD1DAB7860 -:101B7000000078104921046084A00F007900C21D84 -:101B800071201000912001807C00D21DF41D1A1ECE -:101B9000D21D371EE11DC91FE41FD21DEE1D141EEC -:101BA0007F1EEE1E571F691FE01F39200004DC78DE -:101BB00005A7DE78086005A70A60781064209C609D -:101BC000DA78781031217C00DC7884A000014000B4 -:101BD000E81D7800D21D1C6085A080001E60780082 -:101BE000FB1D7810C41BC000D21D78106321DC7867 -:101BF00084A000014000FB1D7800D21DDF780000AA -:101C00000460078084A0FF00D27801809F600000FC -:101C10004000111E781064204000111EDC7885A061 -:101C20000001DE787800131E781088207C00781080 -:101C3000C41BC000D21D78105F21DC788CA0000E80 -:101C4000C000231E84A00001C000251E7800D21D04 -:101C500078106420C000361E04618CA1FF0086A1AC -:101C600007004000212086A10F00400021207810AD -:101C700088207C00DC7884A0000140003E1E7800B3 -:101C8000D21DDF780000146711200100A920010097 -:101C9000186084A0FF0005A04000611E1120010013 -:101CA000BCA700FFA92020008EA001004000611EFB -:101CB0003920000011200200A92000018EA002009E -:101CC0004000611E78007C1E7810C51991200080AC -:101CD0002B6800002F680000086884A0DEFF0A68F7 -:101CE000E8AD1000912001807000751E7800631E21 -:101CF000118240007C1EA92000017800631E78102C -:101D00009A197C0001206752042084A000804000C2 -:101D10004920146178108021006984A101004000ED -:101D2000A01E286084A0FF00C0004120006884A09D -:101D3000010040004920036800000B6800000768AC -:101D4000000078005120112001002060F4D04000F4 -:101D5000A81E95A20200C4D04000AD1E95A20800A6 -:101D6000CCD04000B21E95A200041C6084A00200EA -:101D70004000B91E95A204002C608CA0FF0082A137 -:101D8000020048004D2082A11B00C8004D204000E9 -:101D90004D200E692C6007808CA0FF0082A10200FC -:101DA00048004D2082A11B00C8004D2040004D205E -:101DB0001269306005A0C000DC1E01201E000080FA -:101DC0001668286084A0FF0040004920066828604B -:101DD000078084A0FF00400049200A68026A78005A -:101DE000512001204052042086A00700C000531F4C -:101DF00001206752042084A0008040004920146123 -:101E0000781080210120525204201020FF824000CF -:101E10000E1F80A00500042084A0FF0006A1C000C2 -:101E2000531F91200080046A086B186484A4030087 -:101E300040002D1F28618CA1FF000180C000231FDE -:101E4000002110A24800531F78002D1F0180C00000 -:101E5000531F002112A24800531FFF824000531F4E -:101E600084A40C004000471F28610F818CA1FF0053 -:101E700082A00400C0003F1F002118A34800531F88 -:101E80007800471F82A00400C000531F00211AA33E -:101E90004800531F306005A040004D1F00801668A9 -:101EA000066A0A6B91200180780051209120018000 -:101EB00078004D2014617810802191200080086BFB -:101EC00018834800651F0A6B91200180780060200C -:101ED0009120018078004D202460078084A0FF00BD -:101EE0004000871F86A08000C000C71FA9200800EF -:101EF0006920107691200080006884A0FFFC0268B1 -:101F0000E8AD08007000831F7800791F91200180E0 -:101F100078005120286015A04000C71F1461781078 -:101F200080217E0C7E0DE8AD0700912000800068C6 -:101F30000DA04000C31F06A240009E1F682178002C -:101F4000941F602100600268682C7810AC197F0D26 -:101F500018680DA04000BB1F602000621A6A1C6A4E -:101F600002621E6878108919A02D9821A9203100DD -:101F7000A353602D7810CB1C7800BE1F086800802A -:101F80000A68912001807F0C7800602091200180F8 -:101F90007F0D7F0C78004920146178108021006843 -:101FA00084A001004000392091200080046A108242 -:101FB0004800DC1F066A9120018078006020912093 -:101FC000018078004D207810C41BC000D21D146120 -:101FD00078108021BE60BB600000006984A1080009 -:101FE0004000F31F206085A00001226084A1010051 -:101FF0004000492084A10001C000352084A10002D6 -:10200000C00031201C6805A0C0003D20046084A0F1 -:10201000FF0086A00F00C0000C2078106321DF783D -:1020200000000460078084A0FF00D27801809F60D8 -:102030000000400021207810642040002120DC783E -:1020400085A00001DE787C00D7780000DB780000F6 -:10205000246084A000FF26607810AC3A40004F1D39 -:102060007810E91B78004F1D0920170078005320D5 -:1020700009200E0078005320092007007800532023 -:10208000092035007800532009203E0078005320B5 -:10209000092004007800532009200600780053200E -:1020A000092016007800532009200100246084A034 -:1020B00000FF05A12660912000807810CB1C9120A4 -:1020C000018078004F1D78109A1978004F1DD47840 -:1020D0006DA0C0006F20002CD678DA789F600000D9 -:1020E00078007B20002C9E689F600000D678002D31 -:1020F0000260D87806ADC0007B200260D0780180F5 -:10210000D278C0008720DC7884A0FFFEDE78D87803 -:10211000602006A07C002EA030251C61A26184A155 -:10212000FFE11E6084A16000400097207E0E7810C1 -:10213000D3487F0E9665A6659A66AA66AF600000D2 -:10214000B360000014677810C51991200080A0606A -:1021500084A00080C000BE20086884A00100400068 -:10216000BE20912001807810311A912000807810D3 -:10217000CB1C91200180D7780000DB78000078002C -:102180003021246096A00100C000C5200080266098 -:10219000106A14689120018002A24800D4204000F7 -:1021A000D420392000027810312178003021082C09 -:1021B00091200080A06084A0008040000121006880 -:1021C00065A040000621046A7E0E71204052007016 -:1021D00084A001004000FB20487006A2C000FB2044 -:1021E000046B1C2360210263002305A0C000F620BD -:1021F0000269602202617F0E78000D216021026277 -:1022000006697F0E78000D21006865A04000062158 -:1022100002610269C0000A210669602103600000B2 -:102220006021A06084A0008040001721086884A07D -:10223000FCFF0A681068008012689120018008681D -:102240008CA040004000262186A040000A6878103B -:10225000421A9120008078106F2291200180DB7853 -:102260000000D77800007C00086005A70A60912074 -:1022700000807810CB1C91200180D87865A04000A8 -:1022800044219C60DA789F60000078003421D77880 -:102290000000DB7800007C009079947800800AA12F -:1022A000C800502106A09678D270047805A040009E -:1022B0005E2101800678C0005E2168005E219120C9 -:1022C00080407C00392077217800652139207D21EC -:1022D000042705A04000762100AC6820086B0C6C38 -:1022E0001069146A0A690E6A126B166C38877800D6 -:1022F00065217C00030009000F0015001B00000091 -:1023000015001B0000007E0C78103B3C682C7F0CF5 -:102310007C001000F7216800F72129200000CB780D -:1023200000008C7865A04000F0210920745204213F -:1023300084A001004000BE21046086A00301C0000B -:10234000BE21186005A0C000BE21146005A0C00019 -:10235000BE217E0D69200000186884A00100C00025 -:10236000BD210C60C6701060CA70C37020801B68ED -:102370000100912080407F0D7810F21C7800F5213B -:102380007F0D7810F8214000F021046294A2FF0034 -:1023900096A203004000D021046296A21001C00062 -:1023A000DE21CB780100046294A200FF1782118223 -:1023B0004000DE21FF85C000F021108202A2C8008B -:1023C000F0217E05781007227F054000EB21E078A0 -:1023D00086A003004000F0217800DE212885C8781F -:1023E00005A040008E21FF854000F721912080400C -:1023F000B078D6707C00AC7BB079D47002A1C000FC -:102400000122002305A07C004800052202A37C00D5 -:1024100002807C000120FD04042082A00500C80089 -:1024200021229120008071202000047005A0C000AE -:1024300056220870087206A2C000562286A2080022 -:10244000C00056227120100078105B220920200065 -:10245000046086A00301C0003022286005A0C000EF -:10246000302209200C007810761940004922C478E7 -:102470000080C67886A00200C0005622912000800D -:10248000E3780300C7780000CC7885A00003CE78FD -:102490009120018078005622C77800007810F21C45 -:1024A000AC79B07800800AA1C800542206A0B278A6 -:1024B00006A071201000912001807C00078104801B -:1024C0000480B87AB47BC07CBC7D10A299A30000C4 -:1024D000A1A40000A9A500007C0009205B52912066 -:1024E00000800A207E0F7E0E71204052007086A070 -:1024F0000000C000892209201252042105A0C0005A -:10250000892279200001307884A0C000C00089228F -:10251000180089221B784B007F0E7F0F7C007E0FF6 -:102520007E0E7120405291200080007086A0000035 -:10253000C000A22279200001307884A0C000C00031 -:10254000A2221800A2221B784D00912001807F0E4C -:102550007F0F7C007E129120002371204052792051 -:1025600000014B780F009800B52238787800AE2231 -:10257000A9204000007882A004004800BE22A920C3 -:1025800060009B780000AF780000AF78000070001A -:10259000C8227800C022007882A004004800D72218 -:1025A000B77093001920F04F781013232F7001801B -:1025B0007800E322B77000001920704E78101323C2 -:1025C0001920AF4E781013232F7000800370000085 -:1025D00078102024047084A00F007E010920FD04DF -:1025E0000C218AA105004800F8223800FE2285A0AF -:1025F0008062780000232800FE2285A08062780097 -:10260000002385A0C0627F0106780F7804B243786A -:10261000D800537880000B7808004770080053708A -:102620007F524F7000007F1200207C007E137E14CA -:102630007E157E04A1202B01042305A09A7840007A -:1026400033231883242318839823A82484A400FF09 -:1026500040002B2382A40001A92000012020A653C2 -:1026600005A0C00022231833780019237F047F15AA -:102670007F147F137C008CA10F0011200101042224 -:1026800084A0F0FF05A11220781020247C001120E6 -:102690000101A92009000B8170004D237800482317 -:1026A0008CA1000E042284A0FFF105A112207C0061 -:1026B00009200101A9200500138270005E23780023 -:1026C000592394A2E000042184A01FFF05A20A2040 -:1026D0007C0011200101A9200C000B8170006F23E8 -:1026E00078006A238CA100F0042284A0FF0F05A1CA -:1026F00012207C0011200201042284A0CFFF05A13A -:1027000012207C000381038080A020007E0C6120C9 -:1027100000019A60AC62AC637F0C7C000381038093 -:1027200080A022007E0C612000019A60A46084A039 -:10273000DFFFAE607F0C7C000381038080A022005D -:102740007E0C612000019A60A46085A02000AE602C -:102750007F0C7C000381038080A020007E0C612020 -:1027600000019A60A460AE621020A460AE631820DD -:102770007F0C7C00912000807E0C7E0E186805A0E6 -:102780004000FE2361200076781006244000E823F4 -:10279000A9200000612000757E0C781006244000FE -:1027A000D6237F0C608C7000D4237800C923780076 -:1027B000FE237F0082A000757120405286708271D6 -:1027C000012004006E7093700F0073700000781089 -:1027D0006A227800FA23C06005A0C000FE237120A1 -:1027E00040528271002C8A70012006006E70937036 -:1027F0000F007370000078106A220120000078003A -:102800000024012001009120018005A07F0E7F0C93 -:102810007C00042C05A040001D2460200C6006A351 -:10282000C0001A24106006A2C0001A24146006A179 -:10283000C0001A2406A078001F2400607800072436 -:1028400085A001007C00112041520C228CA10F00B8 -:1028500011203B01042284A00001400036242120E5 -:1028600004FF22210B810B810B810B818DA1000FB5 -:1028700004217C007E0EE4688CA0200040008A24A5 -:1028800084A00600C0008A241460078084A00F0082 -:10289000038003800380F0A08054047084A00A00A9 -:1028A000C0008A24087194A100FF40008A248CA1F2 -:1028B000FF0001200C0006A140007124012012003D -:1028C00006A1400075240120140006A140007924CF -:1028D0000120190006A140007D240120320006A13C -:1028E0004000812478008524092012007800872484 -:1028F0000920140078008724092019007800872413 -:10290000092020007800872409203F0078008724D0 -:1029100011200000002105A20A707F0E7C006800D3 -:102920008C2491200080712000007E00187084A00B -:102930000100C00093247F0071201000CA707F0046 -:10294000C670C3700280DB704107DF700600712023 -:1029500000001B700100912080407800AA247E10A6 -:102960007E007E12912000233C7F587E307C387D93 -:10297000C277C674CA76CE7594A53F009CA40300A6 -:1029800084A40F007900C124D324D324D3240D2898 -:10299000093AD12402250C25D124D124D124D124D3 -:1029A000D124D124D124D12478108C24078584A06B -:1029B0001F007900D82416250D28C729C42AEC2A1F -:1029C0008C2D37309A30FB3080313832D6320225A8 -:1029D000E9280C30F824AC3DCC3D8F3F9B3F744040 -:1029E000F824F82449414D41AA3DF824FA3EF82440 -:1029F0005E3C0C25F82478108C241800B1247F123A -:102A0000912001807F007F107C001920494F7810B1 -:102A100013232F7001001B784F007800FA2419202F -:102A2000AF4E781013232F7000801B78CD007800F4 -:102A3000FA24427209200F520B20000084A50100E5 -:102A4000C000723C4000332578108C2403700000D5 -:102A50004B70000043700000377000007810E039C0 -:102A60001800B12409200F520B200000687005A047 -:102A7000C000FE256C7084A0070079003C25352637 -:102A8000442550256D258F25DC25B5254425781056 -:102A9000C839092048007810D82EC0004E25037090 -:102AA00004007800FA247810C839C0006B258070C3 -:102AB000078082789B781000AB780C009B786000D0 -:102AC000AB7801005B7804000920DD007810CC2E83 -:102AD000C0006B250370040093700F007800FA2487 -:102AE0007810C839C0008D258071078182789B7865 -:102AF00010008CA11F008DA1C000AA79AB78060040 -:102B00009B786000AB7802005B7804000920DD0050 -:102B10007810CC2EC0008D250370040093700F0038 -:102B20007800FA247810C839C000B3258071078175 -:102B300082789B7810008CA11F008DA1C000AA791B -:102B4000AB7820008471AA79AB780D009B78600087 -:102B5000AB7804005B7804000920DD007810CC2EEF -:102B6000C000B3250370040093700F007800FA24AE -:102B70007810C839C000DA258071078182789B7887 -:102B800010008CA11F008DA1C000AA79AB780600AF -:102B90009B786000AB7802005B7804000920DD00C0 -:102BA0007810CC2EC000DA2588708B700000682069 -:102BB0004A700370020093700F007800FA247810B6 -:102BC000C839C000FA2488706820146F7810BD38A6 -:102BD000502C78107A3A9B781000146884A01F005B -:102BE00085A08000AA781C6E412001008C7084A012 -:102BF0000004012004004000FC25012006007800AC -:102C00001D277810C839C000FA249B78100068701E -:102C10006820146F7810BD38502C78107A3A08600C -:102C200085A010000A60246805A040001C2682A030 -:102C3000060048001A2678001C2627680500146B39 -:102C40009CA31F009DA3C000587084A0008040007A -:102C50002A2684A6010040002C269CA3BFFFAA7B45 -:102C600031202000412001000120030078001D27B1 -:102C70001800B1244C7485A4000040004F2680A0A9 -:102C800080523020507108812AA148004626092030 -:102C9000805264210465FF85C00060262184C00045 -:102CA00040265271037000004B700000407005A078 -:102CB0004000723C7800FA244C76B0A680525071E5 -:102CC000002678004B265271682558254A75502CED -:102CD000346085A00000C0005D2608673A7784A7AD -:102CE0003F034000962684A72100C0005D2684A7EC -:102CF000020040007F2684A7040040005D26BCA798 -:102D0000FBFF0A6784A70800C0005D2684A71000A7 -:102D1000C0005D2684A70002C0005D2684A70001D4 -:102D200040009626186005A0C0005D26BCA7FFFEE7 -:102D30000A67236800001C6E84A60E00186140001C -:102D4000A6261C6002A14800A9264000A9267800FA -:102D50005926FF81C0005926C368000084A780005F -:102D6000C000B1260C702260BCA77FFF0A677810F4 -:102D70007A3A1800B1249B78100046A07810C83920 -:102D8000C000FA24146B9CA31F009DA3C0005870C0 -:102D900084A000804000CD2684A601004000CF26FC -:102DA0009CA3BFFF84A610004000D5269DA3200051 -:102DB000AA7B408884A60E00C000E026BDA71000B4 -:102DC0000A6778001B2758718CA100084000CB349B -:102DD0001120200084A60800C000F126108284A6DD -:102DE0000200C000F1261082AA7A40887810E039EB -:102DF000146A0C6108818CA1FF00E0A10075642CAD -:102E0000FF8C40001227146006A2C000FC26B860A8 -:102E10000180BA60C000F7267E0C602A086085A099 -:102E200000010A607F0C780035267810C839C00090 -:102E3000FA24602A0E61AA794088327101200100CB -:102E40007E005C7184A118004000382784A1100026 -:102E500040002B277810D036C0005B2784A10800E3 -:102E600040003827A06984A10006C00038277810E8 -:102E7000BB3578005B27A06984A1000840004F277C -:102E80007E0C7E026029006085A000200260046143 -:102E90008DA1100006617F027F0C7810D036C00033 -:102EA0005B27A06984A100024000572778100C36E8 -:102EB00078005B2784A10004C0003427A06984A1A6 -:102EC00000104000662714698CA100FF0F81781064 -:102ED0008B237F0002708CA6E00084A66000400077 -:102EE000742786A06000C00074278DA10040FF8871 -:102EF000400079278DA104005A79B6699B7860005B -:102F00000028AA789B78610018688DA0008084A0B2 -:102F1000FF7F1A698CA680004000982797700000F8 -:102F20008AA00D00500096278AA00C0096710120FF -:102F30000C000C809A71AA7808800C814000D13472 -:102F40008CA1F800C000D1347E157E137E14A12020 -:102F50002B019B7800000080AC8080AD0B00982096 -:102F6000A6537F147F137F15146807808278946DB1 -:102F7000D67DDE7D986ED27EDA7E7810C839C000AC -:102F8000CF272C7003804800C8271920AF4E781037 -:102F900013232F700080307884A0C000C000CF279A -:102FA0009800D727086084A0EFFF0A607810E03906 -:102FB00078002325007284A2070086A00100C000CB -:102FC000E4271B784F007810E0397800F527B46AC1 -:102FD00095A200205A7A1B784F007810E0390072D1 -:102FE000002505A64000F52784A2070079100328D4 -:102FF00080AD0900367084A2070086A00100C000E1 -:10300000FA24186000801A607800FA240B284B4BD1 -:103010004B4B3A4B4B4B0B283A4B0B2878108C24DC -:103020007810C8397E0F79200052CC787F0F84A0A9 -:103030000100400031286C7086A00100C0002028EB -:103040006E707800C4286C7086A00500C0002F2820 -:10305000887068201B68040017680000206885A03D -:10306000080022686F700000112004006C7186A1B6 -:1030700001004000522886A10700C0004228092014 -:1030800038520B20050078005228092013520421E1 -:10309000092012520A20092038520B2001006F70BB -:1030A000000073700100780054286F7000007810E1 -:1030B00087487E15A9201000392000007810B0370D -:1030C000B8A700017000632878005B287F150070A6 -:1030D0007900672895287C287C286F2895289528D2 -:1030E0009528952821205A52042405A040009528AF -:1030F00006ADC0007C280068222078008C2820685B -:1031000084A00100C0008828146F7810BD387810A2 -:10311000A23478008C2860706020006802601A6A0F -:1031200017680000206885A0080022687810DC1C61 -:10313000212000767810D12821205A527810D128E9 -:103140007E15A9200000212000757810D128208448 -:103150007000A9287800A2286120005521200200D3 -:10316000A920000118601061FF814000B82802A169 -:103170005000B82812601B600000E0AC1000700026 -:10318000C0287800AF282184C000AD287F159C702E -:1031900084A000804000CB287810CE3A0370000055 -:1031A0004B7000007800FA247E04042405A040003F -:1031B000E528682000687E001A6A17680000206809 -:1031C00085A0080022687810DC1C7F007800D328D6 -:1031D0007F04232000007C0082A203005000EF281F -:1031E00078108C2400237900F228F5286829852995 -:1031F00082A202004000FB2878108C246C706F7053 -:10320000000093700000790002290A290A290C297C -:103210004029D7340A2940290A2978108C2480773C -:103220007810B0378077BCA7000F7810BD381860D1 -:1032300005A0400037292120007609200400112034 -:1032400010007810A029400037297E15A920000021 -:10325000212000757E040920040011201000781040 -:10326000A0297F0440003629208470003629780088 -:1032700027297F15388784A71F00C00012297800EE -:1032800023257800232580777810BD38186005A0A5 -:103290004000662921200076092005001120200029 -:1032A0007810A029400066297E15A9200000212061 -:1032B00000757E0409200500112020007810A02947 -:1032C0007F04400065292084700065297800562914 -:1032D0007F1578002325002279006B296E2970293B -:1032E000702978108C24092012006C7086A00200CE -:1032F0004000792909200E00186884A00080400051 -:103300007F291A696F7000007370010078005639C8 -:103310000022790088298D2970298B2978108C2426 -:1033200078108748007086A00100C00067347810CC -:10333000B834086084A0EFFF0A6078105A34400067 -:10334000673478003526042405A04000C32968208E -:10335000042D7E00146806A74000AF29202D7F00B1 -:103360007800A1297F0022201A69176800002068D0 -:1033700005A222687810DC1C1060018012600860D1 -:1033800084A0EFFF0A607810B8347C0085A00100AB -:103390007800C22900237900CA29CF29CD29682ABB -:1033A00078108C24EC7884A00100C000E329007020 -:1033B00086A00400C000DB297800062A7810B83403 -:1033C000086084A0EFFF0A6078006734E47805A005 -:1033D000D000062A1800FA24082084A03000C0007B -:1033E000F2291B784F007800FA24EC7884A00300BF -:1033F0004000EE29002184A007007900FC293F2A23 -:103400004A2A302A042ABB39BB39042A592A78109F -:103410008C24007086A00400C000202A6C7086A056 -:103420000200C000162A11200200192000007800B6 -:10343000E9286C7086A006004000102A6C7086A0F7 -:1034400004004000102AE47984A1300040002A2AB8 -:10345000EC7884A00300C0002C2A78000C300120F6 -:1034600003007800A02D186884A000804000372A4F -:103470001B681D0078108F372B7808301B7856009A -:103480007800FA24186884A000804000462A1B684F -:103490001D0078108F3778008639186884A0008066 -:1034A0004000512A1B681D0078108F372B78083098 -:1034B0001B78CA007800FA24186884A000804000B5 -:1034C000602A1B681D0078108F372B7808301B7816 -:1034D0008F007800FA2484A50F00C000852A0070B0 -:1034E00079006F2A2325792A772A6734673467346D -:1034F0006734772A78108C247810B834086084A058 -:10350000EFFF0A6078105A3440006734780035269F -:10351000E47805A0D000062A1800062A082084A016 -:103520003000C000942A1B784F007800FA24EC7811 -:1035300084A003004000902A002184A107007900A4 -:103540009E2AB02AB42AA82AA62ABB39BB39A62AA1 -:10355000B13978108C24781097372B7808301B7885 -:1035600056007800FA24781097377800863978105A -:1035700097372B7808301B78CA007800FA24781027 -:1035800097372B7808301B788F007800FA240023B7 -:103590007900C72ACC2ACA2ACE2A78108C2478002F -:1035A00080311B680800A3780000E47984A1300012 -:1035B00040008031EC7884A003004000803184A179 -:1035C00007007900E02AE82AB42A302A5639BB39A4 -:1035D000BB39E82AB13978106A397800FA2482A216 -:1035E00005005000F22A78108C2400237900F52A77 -:1035F000F82A4D2D5B2D00227900FB2A152B022B7A -:10360000152B002B322D78108C249B781800A8786D -:1036100084A0FF0082A0200048006B378AA004002D -:10362000C8006B377900112B6B376B376B37193745 -:103630009B781800A87984A180004000262B780090 -:103640006B37007005A0C0001C2B1120040078000F -:10365000E93284A1FF008AA01000C8006B3779000E -:103660002E2B402B3E2B582B5C2B172C6B376B379C -:10367000192C6B376B372E2D2E2D6B376B376B3725 -:10368000302D78108C2484A6001040004D2B012092 -:103690000005008000803A781B788D007800FA24BD -:1036A000186884A000804000562B1B681D0078001D -:1036B000442B780056391B681D0078007B37206941 -:1036C000226984A60018C0009D2B206884A00100F8 -:1036D000C000A52B186886A00800C0006E2B1B68D0 -:1036E000000084A600044000132C84A68000400043 -:1036F000992B97700000186884A03F008AA00D00E5 -:103700005000992B8AA00C00967101200C000C80AF -:103710009A719B786100AA787E157E137E14A12091 -:103720002B019B7800000080AC8080AD0B009820BE -:10373000A6537F147F137F151B7858007800FA2456 -:1037400084A600104000A52B1B7865007800FA24A1 -:1037500084A6600040000F2C84A6000840000F2CB7 -:1037600084A60080C000B32B7800CB2BB4A6FF7FCB -:103770005A7EB66EDC7AD879D0781B80C800BE2B12 -:10378000008084A03F0008A191A20000986B002156 -:1037900002A3B268946B002203A3AE6884A6004023 -:1037A0004000D32BB4A6FFBF5A7EB66E007086A031 -:1037B0000300C000E02B78103D4978103A4B1B788D -:1037C00064007800FA2406A07810414CB06AAC6915 -:1037D000986C946B002205A14000EF2B002222A4DC -:1037E00000211BA3AA6CD27CDA7CA66BD67BDE7B85 -:1037F000002305A4C000012CB5A600405A7EB66E79 -:103800001B7864007800FA241B786400002215A15C -:10381000C0000B2C78104B4B7800FA247810964B94 -:103820007800FA241B7865007800FA241B78580089 -:103830007800FA2478108C2478007A2C206984A1EE -:1038400000014000312C8CA1FFFE22697E0C5470D7 -:103850006020006084A0FFEF0260046084A0F5FF98 -:1038600006607F0C7800692C84A100024000692C5E -:103870008CA1FFFD22697E0C54706020006084A042 -:10388000FFDF0260046084A0EFFF06600820482C80 -:103890007F0C84A108004000692C7810B93878109A -:1038A000BB35FF884000692C9B7860000028AA780F -:1038B000587EB5A604005A7E84A60004C000632C7E -:1038C0002B7808301B7856007800FA242B780830C3 -:1038D0001B7865007800FA24587E84A60004C00096 -:1038E000722C1B7858007800FA241B786500780049 -:1038F000FA24780073377800733719200000907924 -:103900008CA10700C000882C206884A00001400022 -:10391000782C092008009B781000A87894A0FF005C -:1039200086A20100C000BF2C0023A87C00A41820A0 -:1039300002A14000B72C48009C2C7800B92C80A331 -:10394000020002A1C800B72C20698CA1FFFC2269EB -:103950007E0C54706020006084A0EFEF0260046071 -:1039600084A0E5FF06607F0C587EB4A6FBFF5A7E5C -:1039700078006A2C78001B2CA824A87AF000B92CB7 -:1039800078008A2C84A2F00086A02000C0001F2DA1 -:1039900018831883002302A14000CF2C4800CF2CAD -:1039A00078001C2D86A223004000782C1C6884A07F -:1039B000F1FF1E68587E84A6F1FF85A0100030201C -:1039C0005A7E086085A010000A607E0C547060204A -:1039D00004600820482C7F0C84A110004000F32CC8 -:1039E0007810B9387810D0367800022D7E0C5470DB -:1039F000602004600820482C7F0C84A1080040004F -:103A0000692C7810B9387810BB35FF884000692CD4 -:103A10009B7860000028AA78B5A604005A7E84A688 -:103A20000004C000162D2B7808301B785600780053 -:103A3000FA242B7808301B7865007800FA24A87ADD -:103A400078008A2C1883002302A14000282D48000A -:103A5000282D78008A2C84A28000C0007B37780053 -:103A6000733778007B3778006B379B781800A8781D -:103A700084A0FF008EA0010040003D2D78108C2412 -:103A8000A87A94A2FF00A87884A0FF008AA004006E -:103A9000C8006B377900492D6B3708356B376536B1 -:103AA00082A20000C000532D78108C2478108F372C -:103AB0002B7808301B7865007800FA2482A2030076 -:103AC000C000612D78108C2484A40080C000842D57 -:103AD0006C7005A040006B2D78108C24146F8277D9 -:103AE000BCA7000F7810BD38086085A021000A60CF -:103AF000388784A71F00C0006F2D781093376F7030 -:103B00000200092038520B2009007800862D781019 -:103B10009F372B7808301B7865007800FA2482A242 -:103B200004005000922D78108C2400237900952DEC -:103B3000982D812EB42E86A2030040009E2D781071 -:103B40008C24012000007E00C06805A04000A72D45 -:103B500003700300A06884A000204000B02D08601E -:103B600085A002000A607F003E70007084A00700FC -:103B70007900B72D2325C12DC12DB62FF22F232576 -:103B8000F22FBF2D78108C2484A60010C000C92D00 -:103B90007810874840005B2E68788CA0FF004000BA -:103BA000112E86A10800C000E02D7810B8340860FE -:103BB00084A0EFFF0A6078105A344000112E78106C -:103BC00087487800F82D86A12800C000112E7810B3 -:103BD0008748086084A0EFFF0A60186005A04000D5 -:103BE000F82D01801A6005A04000F82D018005A085 -:103BF0004000F82D1E60206884A0010040002325AD -:103C0000206884A0FEFF226860707E0C602000683F -:103C100002607F0C0460026805A0002DC0000E2E1B -:103C200002600660780023257E017810E52E7F0172 -:103C300084A600DF1E682B680000146FFF8140001F -:103C40005B2E86A10200C0005B2E84A60008C00087 -:103C50002E2E84A6600040002E2ED878DC7A2E68A6 -:103C6000326A206884A00008C0005B2E178794A2E7 -:103C70000F0013821382138290A2805490A200003E -:103C80001C2284A30001C000442E78004A2E10821A -:103C9000042285A018001220118284A30004400091 -:103CA000572EA06884A00001C000572E7810692FFD -:103CB00078002325086085A002000A60166918684C -:103CC00084A000804000632E3C701A688CA600DF40 -:103CD0001E697810A9347810B834C000702E0860BE -:103CE00084A0EFFF0A60206884A00100C000792E44 -:103CF0007810A23478007D2E607060200068026029 -:103D00007810DC1C7800232582A204004800872E4E -:103D100078108C24002279008A2E852E8E2E9B2EE0 -:103D20008E2E007086A005004000972E78108F37E9 -:103D30002B7808301B7865007800FA24907807808B -:103D4000018084A0070080A018009A78A8798CA12F -:103D5000FF0086A103004000B02E86A100004000B5 -:103D6000B02E78006B371B7865007800FA24206845 -:103D700085A004002268FF82C000BF2E78108F3714 -:103D80007800C62E11824000C42E78108C24781042 -:103D90009F372B7808301B7865007800FA242C7048 -:103DA00003804800D62E1920AF4E781013232F70B1 -:103DB00000807810E039307884A0C000C000E22E86 -:103DC0001800E22E1A7906A07C0085A001007C0074 -:103DD00084A66000C000EF2E2F680000336800004A -:103DE0007800682F84A60008C000112FB46884A052 -:103DF000004835A684A60008C000112F9869946A6F -:103E00002E69326A3C7005A0C000092F002205A16E -:103E10004000102F3F701500007086A00600400083 -:103E2000102F781087487C0084A620004000332F94 -:103E300084A6004040001F2F2F6800003368000058 -:103E40007800092FB46884A0004835A684A60040F5 -:103E5000C000192F3C7005A0C0002D2F3F70150029 -:103E6000D879DC7A2E69326A7800092F84A600405E -:103E700040003D2F2F680000336800007800092FB4 -:103E8000B46884A0004835A684A60040C000372F3F -:103E90003C7005A0C0004B2F3F701500D879DC7A2C -:103EA000D078FB80C800522F008084A03F0008A17A -:103EB00091A200002E69326A002105A2C0005F2F86 -:103EC0007800092F007086A006004000682F781047 -:103ED000414C7800092F7C00086085A000020A6030 -:103EE00084A300024000752F086085A002000A60CC -:103EF0001B6806008F68000093680000306A2C6918 -:103F00003E6A42692F68030033680000376820006A -:103F1000976800009B682000B3680000AF6800004D -:103F200000707900902F23259A2FA32F982F982F78 -:103F3000982F982F982F78108C24206884A0010047 -:103F4000C000A32F7810A2347800A92F6070502CE5 -:103F5000602000680260602A21205A52042405A0D3 -:103F60004000B22F20207800AB2F222D6B200000C4 -:103F70007C007810A9347810B834086084A0FFFD64 -:103F80000A602B6800009B780E00146F176802000F -:103F90007810894C84A600084000CF2F1C698DA1A1 -:103FA00000201E69186884A000804000DF2F687818 -:103FB0008CA0FF004000DD2F1B681E007800DF2F63 -:103FC0001B68000021205A52042406AD4000E62F51 -:103FD000607400682220C36800003C6A4069326A4D -:103FE0002E697810DC1C780023257810E52E2B68CC -:103FF000000001200E00146F7810E6398CA0FF003D -:104000001669186884A00080400005303C701A686A -:104010008CA600DF1E696F700000780023250070F9 -:1040200005A0C00012307800232506A0781087482C -:10403000176800001B6814008CA600DF1E692B683F -:104040000000206885A0FF002268007079002530FC -:1040500023252F302F3031303130313031302D3079 -:1040600078108C247810B834086084A0EFFF0A60C0 -:1040700078007234002379003A303D303F30983078 -:1040800078108C2484A60080C0007D3000707900F8 -:1040900046302325503050306C30503079306C3001 -:1040A0004E3078108C2484A6600086A06000C0008A -:1040B0006830B4A6DFFFB4A6FFBFB5A600205A7EC5 -:1040C000B66E1C6884A0DFFF1E68781087487810E1 -:1040D0004B4B7800563984A6002040005A301868AF -:1040E00084A00080400079301B68150084A6004041 -:1040F000400079301B68070078106A397800FA248C -:10410000B4A6FF7F5A7EDC7AD879D078D2791B802A -:10411000C8008830008084A03F0008A191A2000060 -:10412000986B002102A3B268946B002203A3AE68CF -:104130001B7865007C0078108C24002379009D306A -:10414000A030A230EB3078108C2484A60080C00010 -:10415000DA3000707900A9302325B330B330CF3086 -:10416000B330D630CF30B13078108C2484A66000C4 -:1041700086A06000C000CB30B4A6BFFFB4A6FFBFCE -:10418000B5A600205A7EB66E1C6884A0BFFF1E68CC -:104190007810874878104B4B7800563984A6002059 -:1041A0004000BD30186884A000804000D6301B68F5 -:1041B00007001B78CA007800FA24B4A6FF7F5A7E55 -:1041C000DC7AD879986B002102A3B268946B002244 -:1041D00003A3AE68D2791B7865007C00206885A0B7 -:1041E0000400226878102139B5A6000878108F37AE -:1041F0002B7808301B7865007800FA2400237900BA -:10420000FE3001310331053178108C2478007B3782 -:1042100084A60004C0002E31E47984A1200040006F -:104220001531EC7884A00300400015312B7809305B -:104230009B786000AB78000084A6FBFF5A78E47995 -:1042400084A1200040002631EC7884A00300C00047 -:104250002A31012014007800A02D84A107007900E4 -:104260006631907A94A207009B786000A879FF815C -:10427000400064319B781000A87B84A30100C0003B -:104280005531A87BA87B86A30100C00048310920D6 -:10429000F7FF78004E3186A30300C0005531092096 -:1042A000EFFF7E0C54706020046004A106607F0C58 -:1042B0009B786000AB78000084A6FBFF5A782B78CF -:1042C000093020698CA1FFFD8CA1FFFE22697800D6 -:1042D00056393F2A4A2A703178316E316E3156395B -:1042E000563978108C2420698CA1FFFD8CA1FFFE2B -:1042F00022697800603920698CA1FFFD8CA1FFFE46 -:10430000226978005639E47984A1300040008A316E -:10431000EC7884A00300C000B131007086A00400D6 -:10432000C000A4316C7086A00200C0009A31112038 -:104330000200192000007800E9286C7086A00600B1 -:10434000400094316C7086A00400400094310070ED -:1043500086A000004000FA24186885A000801A6832 -:10436000012014007800A02D84A107007900B53148 -:1043700056395639BD315639BB39BB39563956399C -:1043800084A680004000EC319471FF814000EC3144 -:1043900082A10D00D000CD31977000007800D2319D -:1043A00082A10C00967009200C009B786100AA790C -:1043B0007E157E137E149870148110A29A7280A0CC -:1043C0000B0000AD9820A1202B019B7800000881F4 -:1043D000AC81A6537F147F137F157800603984A6C3 -:1043E0000004C0002D32206884A001004000603924 -:1043F0008CA6600084A660004000013286A06000A8 -:10440000C00001328DA100408CA1FBFF5A79B66932 -:104410009B786000AB7800009B786100186885A0ED -:1044200000801A68AA7808800C814000D1348CA1E1 -:10443000F800C000D1347E157E137E14A1202B011C -:104440009B7800000080AC8080AD0B009820A653C4 -:104450007F147F137F151468078082787800603995 -:10446000186884A00080400034321B6808001B7864 -:10447000C0007800FA24002379003B324032D43265 -:104480003E3278108C24007084A0070079004532F9 -:1044900023254F3284325A324D3223254D324D324C -:1044A00078108C241C6884A00020400068320860CA -:1044B00085A002000A6078006832C06805A0C000CC -:1044C000843220698DA101002269C368010000685F -:1044D0006A7078007E3220698DA10100226900682F -:1044E000066005A0C000723202601C6884A00E0045 -:1044F00040007E321470BA68307188A1007578006F -:10450000803209200076042102680A2D6271B66E9D -:1045100084A660004000D23284A60008C000983211 -:1045200084A6FF7FB6689468A6689868AA68781021 -:1045300087487800D23284A620004000AD32C0689F -:1045400005A04000A4327810894C7800A73206A05C -:104550007810414CD879DC7AAA69A66A7800B3321F -:104560007810CA38AA69A66A7810414C84A60080DF -:104570004000D23284A6FF7FB668DC7AD87984A660 -:104580002000C000CA32D0781B80C800C53200802D -:1045900084A03F0008A191A20000986B002102A313 -:1045A000B268946B002203A3AE68780023257800DC -:1045B0007B373770000082A206005000DE32781090 -:1045C0008C24007084A00700C0108C3A002379006E -:1045D000E632E9321233263300227900EC3210330E -:1045E0007B37F232103342338433037005000120ED -:1045F000107768204A707E15A92031000320000042 -:104600000080700002337800FB327F1580AD090016 -:10461000367017680000B76800072368000827682D -:10462000030078006B3778108C240370050001209C -:10463000107768204A7080AD09003670002279003A -:104640001E337B3724332433423324337B377810B3 -:104650008C24037005000120107768204A7080AD1B -:10466000090036700022790032333A333833383358 -:104670003A3338333A3378108C2478109F372B78BC -:1046800008301B7865007800FA2403700200807AF5 -:1046900094A2000F9B781800A87C84A41F0015A288 -:1046A00069200076042D082D6271682005A0400065 -:1046B0005D33146806A240007933006878005033F7 -:1046C000037005000120107768204A7036707E154F -:1046D000A920310003200000008070006E337800B4 -:1046E00067337F1580AD09003670166AB76800071A -:1046F0002368000827680300B46E5A7E206884A0EF -:10470000000C4000D333781097377800D333037010 -:104710000200807A94A2000F9B781800A87C84A4E1 -:104720001F0015A2A879A8798CA1FF00E8A1007547 -:10473000042D082D6271682005A04000A333146881 -:1047400006A24000BE33006878009633037005006F -:104750000120107768204A707E15A92031000320BF -:10476000000000807000B3337800AC337F1580AD5B -:1047700009003670166AB7680007236800082768C2 -:104780000300B46E5A7E206884A0000C4000D3332E -:1047900084A000084000CD3378109B377800D333D5 -:1047A000781097378B7000007800D3337E02078231 -:1047B00084A00F0003800380038080A080546020C9 -:1047C000567000605A7004605E7084A660004000FD -:1047D0002B34986B946CAC69B06805A1C0000D34A3 -:1047E000D27BDA7BD67CDE7CB4A6FFB75A7E84A669 -:1047F000600086A0600040002B34C06805A0400027 -:104800000634037003002B68000078103A4B7800E0 -:10481000083478104B4BB5A600205A7E78002B3414 -:10482000B0681AA3002123A4002405A340002B3460 -:10483000D27BDA7BD67CDE7CB068B4A6FFBF5A7E22 -:104840007E00C06805A07F0040002934037003008B -:1048500078103A4B78002B347810964B7F077810FD -:10486000BD380920650084A6040040004C34E4787B -:1048700084A0300040004434EC7884A00300400061 -:1048800044342B7808300920650078004C347E0FC2 -:1048900079200052781087487F0F400023251A792D -:1048A000002D4A70078284A00F00038003800380DC -:1048B00080A0805448207800FA24206005A04000A1 -:1048C000663401802260086085A008000A601070CC -:1048D00026607C0006A078108748176800001B68D7 -:1048E0000100236840001F680001007084A00700D9 -:1048F000790077342325813481349E348934873498 -:1049000089347F3478108C247810A9347810A2343C -:104910007810DC1C780023256C706F700000937099 -:104920000000790090349A349A349834983498344A -:104930009A3498349A34790002296F700000780014 -:1049400023251B6800007800B62F006805A0C00072 -:10495000A734026006607C00106005A04000B234FD -:104960000180D000B23478108C241260086084A0DA -:10497000EFFF0A607C00186005A04000BE34018093 -:104980001A607C007810E0391B6818007800F53454 -:104990007810E0391B6819007800F5347810E03998 -:1049A0001B681A007800F5347810E0391B680300A2 -:1049B0007800F53480777810BD3884718CA1FF00C1 -:1049C000E8A10075042D082D682005A0C000E7347B -:1049D000780023251468807206A24000EF34006836 -:1049E0007800E03400680A201B6805008B70000026 -:1049F0007810A934206884A00100C000FE3478102B -:104A0000A2347810B8341F680000236820007810A2 -:104A1000DC1C7800232582A20300C0006B37A87D30 -:104A2000ACA5FF00A87CA4A4FF0020698DA1800094 -:104A3000226984A1000140006C358CA1FFFE22692F -:104A4000A4A4FF004000563582A40C00480029357C -:104A50004000293521200C002B852B8578102E381D -:104A6000400033357810273678005F357810E93705 -:104A70007E0C6029046084A0F5FF06607810523631 -:104A80007F0C20698DA100012269587EB5A6040023 -:104A90005A7E84A60004C00050352B7808301B785D -:104AA00056007800FA242B7808301B7865007800CF -:104AB000FA247E0C6029046084A0F5FF066078105B -:104AC00052367F0C587E84A60004C00068351B78DF -:104AD00058007800FA241B7865007800FA247E0CD0 -:104AE0005470602000618CA100104000AC35086259 -:104AF000178294A2FF0082A20C004800803540007B -:104B0000803511200C00002402A2C8008535202227 -:104B1000086294A2FF00187086A02800C000953596 -:104B200082A21900C8009B351120190078009B351E -:104B300082A20C00C8009B3511200C00002202A5A7 -:104B4000C800A03528227810ED372B852B857810EA -:104B50002E384000AC35781027367800B035781004 -:104B6000E93778105236587885A004005A787F0CBF -:104B70002B7808301B7865007800FA247E0C6029B9 -:104B80000060E4D0C000D535B4D0C000CF3510608F -:104B900084A00F00C000CF3504618CA1F5FF066131 -:104BA0007F0C7C0011203200192000007800FC35B9 -:104BB000A06884A00002C000CF35086294A2FF0064 -:104BC000187086A02800C000EA3582A21900C8002B -:104BD000F035112019007800F03582A20C00C800D1 -:104BE000F03511200C0008631F839CA3FF0082A3F3 -:104BF0000C004800FC354000FC3519200C00AB7857 -:104C00000100AB780300AB780100AA7AAA7BC0A8A8 -:104C10000500206885A0000122687F0C7C007E0CC6 -:104C200060298CA1F5FF06611120320019200000D7 -:104C300078001736AB780100AB780300AB78010041 -:104C4000AA7AAA7BC0A80500206885A00001226876 -:104C50007F0C7C007E0C5471602178102E367F0C06 -:104C60007C00082084A0F0FF25A4867C18609A7838 -:104C7000AE7C1264A47884A0F8FF8CA1070005A183 -:104C8000A67816608A78A4A40F0027840482048082 -:104C900084A0FF0005A40E60EC788CD0C0005136D3 -:104CA000046084A0F5FF06607C007E0C54706020D8 -:104CB000781059367F0C7C0018609A78A47884A00C -:104CC000F0FFA6781260847884A0F0FF86787C00DC -:104CD00082A20200C0006B37A87A20698DA18000F3 -:104CE000226984A100024000AE368CA1FFFD22693A -:104CF00094A2FF0082A20200C8006B377810F93638 -:104D00007810523680A901000C207810B93878103C -:104D1000BB35FF884000A1369B7860000028AA7848 -:104D2000587EB5A604005A7E84A60004C0009B36B7 -:104D30002B7808301B7856007800FA242B7808303E -:104D40001B7865007800FA24587E84A60004C00011 -:104D5000AA361B7858007800FA241B786500780082 -:104D6000FA2482A20200C800B63684A201004000E4 -:104D7000C036547188A100000C218CA10020C00015 -:104D8000C036112000007810DB377810F936781023 -:104D90005236587885A004005A782B7808301B7852 -:104DA00065007800FA247E0C7E02602900601120E4 -:104DB0000100ECD0C000E936BCD0C000E73614607A -:104DC00084A04000C000E7368CA1EFFF066106A07A -:104DD0007800F63611200000AB780100AB780200B5 -:104DE000AB780300AA7AC0A80400206885A000025E -:104DF00022687F027F0C7C007E0C5470602078104B -:104E000000377F0C7C00FF824000053711204000F6 -:104E1000186080A002009A78A47884A0BFFF05A241 -:104E2000A6788A781660EC788CD0C00018370460B9 -:104E300084A0EFFF06607C007E00007086A0030067 -:104E4000400022377F00780025377F0078006737E1 -:104E500084A6200040006737887884A04000400086 -:104E60006737B87B84A33F001B83C80035370080B9 -:104E700005A040004B371B83C8003E37018040002F -:104E8000633784A6004040004B37B8781B80C800C9 -:104E90004737008084A03F00C0006337B4A6FFBF3F -:104EA0005A7ED879DC7A0120010008A1C800573762 -:104EB00091A20000D279DA79D67ADE7A7810414C64 -:104EC0001B7864007810C64A7800FA241B786400C6 -:104ED0007800FA241B7865007800FA247810A3374C -:104EE0002B7808301B7865007800FA2478108F370B -:104EF0002B7808301B7865007800FA2427680200B8 -:104F000078109737E47884A0300040002325EC78AF -:104F100084A00300400023252B7808301B7865000F -:104F20007800FA24012005007800A53701200C0044 -:104F30007800A537012006007800A53701200D0074 -:104F40007800A537012009007800A5370120070067 -:104F50009B781000AA789B786000AB780100B5A61A -:104F600004005A7E7C007E073F87BCA70F003B876A -:104F70003B870387E0A08054B8A720009A7FA479DC -:104F800084A10F004000C93784A1F0FFA678126009 -:104F9000046085A008000660388738879A7FA47966 -:104FA00084A140004000D93784A1BFFFA6781660D5 -:104FB000046085A0100006607F077C009B781000CD -:104FC000AB780100AB780200AB780300AA7A9B783B -:104FD0006000AB7804007C00212000002920320012 -:104FE0009B781000AB780100AB780300AB78010030 -:104FF000AA7DAA7C9B786000AB7805007C007E15BA -:10500000078084A0FF000380038080A020009A789E -:10501000A4798CA1F0FF01204652042082A0280030 -:10502000400017382120A03819201400A9200C00B6 -:1050300078001D382120AC3819201900A9200D0056 -:1050400011206400042484A0F0FF06A140002C3845 -:105050002084002310A270002C3878001F387F15A0 -:105060007C007E15092046520C2182A132004800A6 -:105070004238400046380920923819201100A920F2 -:105080000E00112032007800583882A1280040001C -:1050900050380920A03819201400A9200C00112034 -:1050A0006400780058380920AC3819201900A9206C -:1050B0000D0011206400002202A54000683848005D -:1050C00068380881002310A27000653878005838CD -:1050D0007F1506A07C007F1582A56400C800773884 -:1050E000087885A070000A78447085A0700046702A -:1050F00078007738EC7884A0000340007F380421E2 -:105100007800903804219EA00211C0009038012040 -:10511000FD04042082A0050048008F380120011200 -:1051200078009038042105A07C0002110230023280 -:105130000342034404540456056605680678067A5B -:10514000070C070C070E0232024202520262027280 -:10515000056605760578057A057C057E057F0222C1 -:105160000232024202520454046404740476047845 -:10517000047A047C047E047F9B78100046A07C00A7 -:1051800084A7000F0B8084A71F0003800380038087 -:10519000038005A1E0A000557C00D879DC7AD078A6 -:1051A0001B80C800D138008084A03F0008A191A2D4 -:1051B00000007C007E0F79200001092040529120E0 -:1051C000008004217900E1381739EB38EB38EB38EF -:1051D000EB38EB38EB381B3978108C244B78040013 -:1051E000487884A00400C000ED384B780800487867 -:1051F00084A00800C000F438B46885A00040B668F8 -:10520000587885A000405A78307884A08000C0008B -:105210001739180017391C6884A02000C000153900 -:105220007E0E7120405278106A397F0E780017394F -:105230001B78CA00912001807F0F7C00B3700000B2 -:105240007810443B780017397E0C1468078084A0DE -:105250000F00038003800380E0A08054046084A0DA -:105260000A00C0005439086194A100FF400054397D -:105270008CA1FF000120190006A140004339012044 -:10528000320006A14000473978004B390920200040 -:1052900078004D3909203F0078004D391120000079 -:1052A000002105A20A60046085A0020006607F0C50 -:1052B0007C001B7865007800FA242B7808301B7876 -:1052C00065007800FA241B7858007800FA242B78BF -:1052D00008301B7856007800FA24092020520C214F -:1052E00086A1000040007E3986A10100400081397E -:1052F000092038520B200B006F7001001B7848000A -:105300007C001B78C4007C00092038520B200A0066 -:105310007C00092020520C2186A100004000A13908 -:1053200086A1010040009B39092038520B200B0058 -:105330006F7001001B7848007800FA240920385269 -:105340000B200A007800FA242B7808301B78C40060 -:105350007800FA241B78CA007800FA242B780830E9 -:105360001B78CA007800FA241B788F007800FA2492 -:105370002B7808301B788F007800FA24186884A0F6 -:1053800000804000C2391B681D006F7001001B784F -:1053900048007800FA247E00307884A0C000C00065 -:1053A000DE39087884A0FCFF0A78050005000500B6 -:1053B0000500EC7884A021004000DE3944700A78B2 -:1053C00005A07F007C00447085A0020046700A782A -:1053D0007C007E00307884A04000C000E73998004F -:1053E000F2397F009A78AC787C00087884A0FDFFC1 -:1053F0000A780500050005000500EC7884A021006E -:105400004000013A9800FF397F009A78AC787E001E -:1054100044700A787F007C00EC7884A00200C00011 -:10542000714884A77D00C000153A002778108C24AD -:1054300084A70100C0000C3084A770004000253A0A -:105440007E0C602D682F78103724782D682C7F0C07 -:1054500084A708004000323A4B780800EC7884A01A -:105460000300400023257800563984A7040040003B -:10547000653AB87884A001404000653A4B7808004E -:10548000EC7884A0030040002325E47884A0070082 -:1054900086A00100C000653AC07885A00048302091 -:1054A0005A7E1B78CA007800FA244B7808001868E6 -:1054B00084A000804000613A1B68150084A600406B -:1054C0004000613A1B68070078106A397800FA24B6 -:1054D0001B680300587884A0003F1E682F680000F6 -:1054E000336800004B780800EC7884A0030040008B -:1054F000062A1800FA2478007337146B078384A0F7 -:105500000F0003800380038080A080546020482027 -:10551000567000605A7004605E70602A7C007900EA -:105520008E3A963A973A963A993A963A963A963AFF -:105530009E3A7C007810B8347810874838700A603A -:105540007C00A07005A04000AB3A68207810D31B07 -:105550007810FE4778100548A37000007C007E0E8E -:105560009120008071204052007086A00700C0008A -:10557000C23A1061BC7006A1C000C23A7F0E78101A -:10558000E01B7810C83A06A07C00912001807F0EB5 -:1055900085A001007C007E0F7E0E712040527800B5 -:1055A00097225B780000AF700E00092000017E0199 -:1055B000A0706DA04000DD3AA37000007800E33ACF -:1055C000B370000078100C1C4000E93AAC702668FB -:1055D0007810C63B7800DD3A7F017E157E0C7E0D8B -:1055E000A920080061201076006005A102601C60FF -:1055F0006DA04000013B00681E607810AC19086087 -:1056000000800A607800F43A18606DA040000B3BFF -:1056100000681A607810AC197800013BE0AC080013 -:105620007000113B7800F13A9C7084A0008040002B -:10563000183B7810443C7F0D7F0C7F157C007E1258 -:1056400091200023046884A00F007900243B343BA0 -:10565000343B343B343B343B343B363B3C3B343BC8 -:10566000343B343B343B343B3E3B343B363B78109D -:105670008C247810D3457810AC197800423B276809 -:105680000B007810D3457810C63B7F127C007E1249 -:10569000912000239800603B307884A0C000C000B7 -:1056A000603B7E0D78101248002D2E680920040002 -:1056B00001200000276884007810C7477810C63B97 -:1056C0007F0D7800943B487985A100404A78980086 -:1056D000693B4A7978004E3B287886A03418C00090 -:1056E000723B85A104007800793B287886A01418C5 -:1056F000C000663B85A10C004A789B780E00AB7811 -:105700000200587884A0FF0085A000045A78B47085 -:1057100080A091001A78276884022C683668306867 -:105720003A6809200400012000007810C7477F1262 -:105730007C007E0D146B7810701C4000A33B682029 -:10574000276802007810C63B7800983B7F0D7C00EC -:105750007E0D146B286CA4A4FF0078101C1C400064 -:10576000B33B6820276802007810C63B7F0D7C00A1 -:105770007E0D146B9CA3FF007810481C4000C43BB6 -:105780006820276802007810C63B7800B93B7F0D7F -:105790007C007E0C146978103B3C04698CA1FF00EE -:1057A00086A106004000E13B86A10D004000003CC0 -:1057B00086A11700C000DD3B7810AC197800DF3BF4 -:1057C0007810DE1C7F0C7C00046001804800FE3BEA -:1057D00006600920000084A60100C000EE3B8DA1F8 -:1057E000008084A604004000F43B8DA102001E69E5 -:1057F0002368000004710F81186805A11A687800F9 -:10580000DD3B78108C24186005A0C0000F3C0860B8 -:10581000018048000F3C0A601C600268002D1E6079 -:105820007800253C88AC0600042105A04000183C07 -:1058300008207800113C02680A2D086001804800A9 -:10584000DF3B0A601860682000681A607800093C35 -:105850007E157E137E147E0C7E0D78108919C00093 -:10586000303C78108C24A02D7F13A9203100A35345 -:105870007F0C7F147F137F157800DD3B84A11F0010 -:1058800003800380038080A0107660207C001920B4 -:105890005152042385A001001A201920020104237B -:1058A00085A001001A207C0019205152042384A0F5 -:1058B000FEFF1A2019200201042384A0FEFF1A20F3 -:1058C0007C0090798CA1F8FF9279B47080A0D80008 -:1058D0001A787800FA24A370000003700000437067 -:1058E0000100377000001800B12478100C1C400033 -:1058F000993C09200F520B200000BC686020006119 -:1059000084A1000340008D3C27680E0084A00002A3 -:105910004000893C276817007810C63B7800683C37 -:10592000007086A00700C0000D3D002DA27080AD64 -:105930000F0036707800A03C407086A00100400047 -:1059400033257800FA24312000001C6984A102006C -:105950004000A93CB5A6040084A1C00003800380D8 -:10596000078080A0A63D042035A6206884A00004FE -:105970004000C13C9B781800AB7803009B78810005 -:10598000AB780100B5A60050206884A000804000DC -:10599000CF3CB5A600049B780E0024680780AA7847 -:1059A0007800EF3C1C68FCD0C000DD3CB5A60008C8 -:1059B0002068C4D04000EF3CB5A600407800EF3C22 -:1059C0002068C4D04000E53CB5A600407800EF3C1C -:1059D0009B781800AB7802009B788100AB780100BF -:1059E000B5A6001084A600024000093D2C68D278BC -:1059F0003068D67884A600014000073D2C6884A05A -:105A000001004000073D887884A040004000073D29 -:105A1000B5A600807810F6475A7EB66E78003548F5 -:105A20007810C839C000A03D2C70048048001B3D90 -:105A30001920494F781013232F70010041200100D5 -:105A4000312000109B781800146884A01F0085A0E6 -:105A50008000AA781C6984A102004000343DB5A6EC -:105A60000400AB7820002868AA78C0A802001C684F -:105A7000F4D040003D3D502C78107A3A781002471F -:105A8000206884A0008040004B3DB5A600049B78B0 -:105A90000E0024680780AA787800523D1C6884A014 -:105AA0000080C000523DB5A60008206884A0000117 -:105AB0004000593DB5A600401C6884A0C00003808A -:105AC0000380078080A0A63D042035A684A600019F -:105AD0004000733D2C6884A001004000733D88782D -:105AE00084A040004000733DB5A600809B787E00F6 -:105AF000AE7EB66E14680780AA7882781028AA7ADB -:105B0000307884A0C000C000A03D1800A03DB47053 -:105B100080A0DD001A787810E03984A600024000E9 -:105B2000943D2C68D2783068D6787810F647002DEE -:105B3000A2704A701068BE700370070080AD0F003D -:105B400036707800FA247810D31B7810E03978008A -:105B5000FA24000000030002000078108C240023C7 -:105B60007900AF3DB23DB23DB43D78108C24781041 -:105B70000548246984A1FF0086A00A004000C63DB4 -:105B800084A100FF85A00A0026687810D31B780046 -:105B9000683C01200A00781097477800683C82A290 -:105BA00005005000D23D78108C24007084A00700BE -:105BB000C0108C3A78108919C000F43D6920FFFFAD -:105BC00084A604004000E53D012000287800E73D60 -:105BD00001200008B47188A191009B780E00078015 -:105BE000AA78312000045A7E1A797800FA240768CE -:105BF00006010B6800009F6800002768000086A36C -:105C00000200C000153E86A20200C000153EA0782A -:105C100005A0C000153E84A40080C000153EE478B5 -:105C200084A008004000153EB5A608001920000019 -:105C300078101742002DA2704A7003700700377069 -:105C40000000246884A080004000273E7810CD42E8 -:105C50007800FA24002379002A3E2D3EAE3EC73E4E -:105C600000227900303E353E453E6B3E773E9A3EFF -:105C70002920010026A0112000007810F3437900AC -:105C80003E3E433EFA24683C433E433E78108C241B -:105C900090798CA10700C0004C3E0920080011201B -:105CA000010084A604004000543E1120030020227D -:105CB0002AA1112001007810F34379005C3E613E77 -:105CC000FA24683C693E633E78003B48AB70673E0F -:105CD0007800FA247800613E78108C2484A61000A5 -:105CE0004000753E78109C424000753E7800FA24D2 -:105CF00078000D43006084A002004000943EB47020 -:105D000080A0CD001A787E0D78101248002D2E68E4 -:105D1000276800007810C63B7F0D7810AC1903701F -:105D20000000377000004B7000007800683C84A6CB -:105D30000400C0009A3E78003B48006084A0040044 -:105D4000C000AC3E006084A001004000AC3EAB70DF -:105D5000AC3E0120070078108F477800414878005A -:105D60003B4800227900B13EB63EB83EB63EB63E54 -:105D7000B63E78108C24A770BC3E78004748E47883 -:105D800084A00800C000B83E78108147AB70C53EC3 -:105D900078003B4800227900CA3ECF3ED13ED13E3A -:105DA000CF3ECF3E78108C24E47884A008004000D9 -:105DB000E63EA770DA3E78004748112004007810CC -:105DC000ED437900E03EE63EFA24683CE63EF03ED4 -:105DD000F43EAB70EE3E0120030078108F47780050 -:105DE000414878003B48AB70E63E7800FA24AB703F -:105DF000F83E7800FA247800EE3E82A203005000BC -:105E0000003F78108C2486A30200C000193F86A2B0 -:105E10000200C0001F3FA07805A0C0001F3F84A45F -:105E20000080C0001F3FE47884A008004000193FB4 -:105E3000B5A608001920000084A6080040001F3FF6 -:105E4000781079421068BE70037007000023790053 -:105E5000263F293F563F5E3F002279002C3F313FCD -:105E60002F3F4A3F78108C249079ACA1070026A0E0 -:105E7000112001007810F34379003B3F403FFA24A2 -:105E8000683C483F423F78003B48AB70463F780053 -:105E9000FA247800403F78108C2484A6100040003B -:105EA000543F78109C424000543F7800FA24780018 -:105EB0000D4300227900593F5C3F5C3F5C3F781006 -:105EC0008C2400227900613F643F663F663F781072 -:105ED0008C24E47884A0080040007B3FA7706F3FCB -:105EE00078004748112004007810ED437900753F91 -:105EF0007B3FFA24683C7B3F853F893FAB70833F03 -:105F00000120030078108F477800414878003B4813 -:105F1000AB707B3F7800FA24AB708D3F7800FA2499 -:105F20007800833F00237900923F973F993F953F48 -:105F300078108C24A4707A00A4707A0082A20200E7 -:105F40005000A13F78108C2484A600024000AB3F93 -:105F50007810FE477810D543781005480023790063 -:105F6000AE3FB13FD93F3F4086ADFFFF4000683CA8 -:105F700086A201004000BB3F78108C2484A600025A -:105F80004000C33F7810FE4778100548012001000B -:105F900078109747B87884A001C04000D53F487872 -:105FA00085A008004A78487884A00800C000D03F47 -:105FB000037000007800683C00227900DC3FDE3F7F -:105FC0000F40A770E23F7800474811200D0078107D -:105FD000ED437900E83FEF3FFA24683CF73FFF3F8D -:105FE00005400740B4A6FF00B5A60004B66E5A7E71 -:105FF00078003548B4A6FF00B5A60004B66E5A7EF8 -:1060000078003548AB7003407800FA247800EF3F01 -:1060100078108C24AB700B407800FA2478104D482F -:106020007800FA24A7701340780047481120120026 -:106030007810ED43790019401F40FA24683C2B404A -:1060400033403940B4A6FF00B5A60004B66E5A7EB0 -:10605000B47080A0AA001A787800FA24B4A6FF00D1 -:10606000B5A60004B66E5A7E78003548AB7037404E -:106070007800FA2478001F40AB703D407800FA2485 -:1060800078002B4086A201004000454078108C2407 -:10609000A770494078004748112015007810ED435B -:1060A00079004F405440FA24683C62406E40B4A6E8 -:1060B000FF00B5A60004B66E5A7E3B780113B4709B -:1060C00080A0B5001A787800FA24B4A6FF00B5A61F -:1060D0000004B66E5A7EB47080A0AA001A787800C8 -:1060E000FA24AB7072407800FA247800544082A2FF -:1060F000030050007A4078108C24002379007D4002 -:106100008040B740144186A20100400086407810CC -:106110008C24046884A0FF0086A00600C000934081 -:106120007810C63B037000007800683C3B680000B4 -:106130003768000084A600024000A1407810FE47A6 -:106140007810D54378100548012001007810974752 -:10615000B87884A001C04000B340487885A008000A -:106160004A78487884A00800C000AE400370000060 -:106170007800683C00227900BA40BC40EF40A7702C -:10618000C0407800474811200D007810ED43790099 -:10619000C640CD40FA24683CD540DD40E340E540B0 -:1061A000B4A6FF00B5A60008B66E5A7E7800354842 -:1061B000B4A6FF00B5A60008B66E5A7E7800354832 -:1061C000AB70E1407800FA247800CD4078108C2440 -:1061D000AB70EB40781005487800FA2478104D48F1 -:1061E0007800FA24A770F340780047481120050092 -:1061F0007810ED437900F940FE40FA24683C0641EE -:106200000E41B4A6FF00B5A60008B66E5A7E78000F -:106210003548B4A6FF00B5A60008B66E5A7E7800D1 -:106220003548AB7012417800FA247800FE4086A20F -:10623000010040001A4178108C24A7701E4178009C -:106240004748112006007810ED4379002441294188 -:10625000FA24683C2F413941B5A60008B66E5A7E33 -:1062600078003548B4A6FF00B5A60008B66EB5A6FE -:1062700000405A7E78003548AB703D417800FA24E2 -:106280007800294100237900424147414541454179 -:1062900078108C2478108C240023A87105A07A0132 -:1062A0001068BE7082A203005000554178108C2403 -:1062B0000023790058415B4169418B4184A600026B -:1062C000400063417810FE47781005480120010026 -:1062D000781097477800FA2496A202004000724195 -:1062E000FF824000724178108C24A77076417800BC -:1062F0004748112018007810ED4379007C41814116 -:10630000FA24683C83418541780035487800354857 -:10631000AB7089417800FA2478008141002279002D -:106320008E419041A941A7709441780047481120BF -:1063300017007810ED4379009A419F41FA24683C98 -:10634000A141A3417800354878003548AB70A7419A -:106350007800FA2478009F4184A40080C0000542A0 -:1063600084A600014000B5417810FE477810D5435F -:10637000D878D278DC78D678B4A6FFEF5A7EA770AA -:10638000C0417800474811200D007810ED43790096 -:10639000C641CD41FA24683CCD41F341F941FB416E -:1063A000D878DC7905A1C000DF41B87884A01F004F -:1063B000C000DF41B3700000587884A0FFFD5A7818 -:1063C0007800354884A600014000F141487885A056 -:1063D00008004A787810BC472C68D2783068D678A4 -:1063E000B37000007810F64778003548AB70F7417D -:1063F0007800FA247800CD4178108C24AB700142EB -:10640000781005487800FA2478104D487800FA246E -:1064100078100548AB700F420120030078108F47B9 -:10642000780041487810F6472C68D2783068D678E2 -:1064300078003548B8701268BE700080BA701B686A -:10644000000084A6080040003A427E157E137E14A8 -:106450009078048004800480048084A00F001A686F -:10646000AC809B78000080AF2B00982080AD0B00A3 -:10647000A020A5537F147F137F15C4A6000F84A608 -:106480000200C00049422C690D810D810D8184A15B -:106490000700082078005C429B781000AC7984A14A -:1064A000200040005C427E01092005000120003DE3 -:1064B0007810C747246885A03B0026687F0184A127 -:1064C0001F0005A8166878103B3CBE6884A604002F -:1064D00040006D428CA100FFA87884A0FF0005A1B8 -:1064E0002A68B4A6FF00006084A00800400077423C -:1064F000B5A60040B66E7C007E157E137E1418692A -:106500009078048004800480048084A00F007E00C2 -:1065100000A11A687F000080048040009842A820F3 -:10652000048180A00B0000ADA0209B78000080AF0C -:106530002B009820A5537F147F137F157C002C68B7 -:1065400084A02000C000A4420C627800A542106222 -:10655000186B002302A24000C542182082A30E003F -:106560004800B5424000B54219200E007800B942FB -:10657000587884A0EFFF5A783B78011B937800008D -:10658000A27BB47080A08E001A7885A001007C00E8 -:10659000587884A0EFFF5A789378000006A07C001A -:1065A00004698CA1FF0096A107004000DA4296A181 -:1065B0000F004000DA4207681701146978103B3C6D -:1065C00000610481C800F5421C6005A04000E9425A -:1065D000012000087800F7427E0D24687E007810C4 -:1065E00012487F002668002D2E687810C63B7F0D6C -:1065F0000120000224698CA1FF000DA126690780FB -:106600009B780E00AA78206885A00080226831203F -:106610000004B66E5A7EB47188A191001A797C008C -:10662000C4A6000F84A60200C00021432C690D817E -:106630000D810D8184A10700082005A81668781037 -:106640003B3CBE6878002443146978103B3C0061F1 -:106650000481C800824384A10003400030430768DE -:10666000170178004E43046005A0C0005743076837 -:1066700017011C6005A0C00044437E0D781012482D -:1066800027683400002D2E687810C63B7F0D84A645 -:10669000040040004E43312000040120002878000F -:1066A00052433120000401200008B47188A19100F8 -:1066B0007800B043186005A0C00044431C6005A0EA -:1066C000C00044439F68000027683D0084A6010085 -:1066D0004000BE4394D6C0007B430061D4D140004B -:1066E0007B432C698CA1FF004000BE4386A10300C0 -:1066F0004000BE4386A112004000BE43B5A600087C -:10670000B47188A1AE007800B94307681701312041 -:1067100000042C698CA1FF0086A11200C0009343E5 -:106720000120CB43092001007800A44386A1030087 -:10673000C0009D430120CC43092012007800A443EF -:1067400001200002B47188A191007800B043781054 -:10675000E147A37800001C6885A040001E68B47162 -:1067600088A1DA0006A0266807809B780E00AA7828 -:10677000206885A000802268B66E5A7E1A7978005B -:10678000FA24B66E7810C63B1068BE70037007001E -:10679000A37000004B7000007800FA242300700002 -:1067A00005000000000A00000000250000000000B5 -:1067B0003B6800003768000084A600024000EC43FC -:1067C000B8788CA01F0084A000804000E5430881B9 -:1067D000D87800A13668DC7881A000003A687C0097 -:1067E00090790F81ACA507002120000080A4100043 -:1067F0009A78A8798CA1FF0084A18000C0001B4476 -:1068000082A12000C800394482A11200C80081473B -:106810000021791009447C008147EB45814781477D -:10682000464449448344B944ED44F0448147814798 -:10683000A44414454E4581478147744584A12000F6 -:10684000C000A8458CA11F00146884A01F0006A1E9 -:1068500040003644B47080A0CD001A7801201400A6 -:106860007810974778100548037000000120020057 -:106870007C00012000007C0082A12400C800814728 -:1068800084A10300791009447C0081478147814736 -:106890008147781081477C00002279004C4477457D -:1068A0007745704470447044704470447044704440 -:1068B00070446E4470446544704470447044704445 -:1068C000704478447B4477457B4470447044704402 -:1068D0007E0C7E07146F7810B0377F077F0C78002E -:1068E000704478108E462768B30209200B000120FF -:1068F00000487800AB45781073477C002768930008 -:1069000009200B000120004878009345582D0468A9 -:1069100084A0FF0086A00600C0008D440768170110 -:106920002768020078101248276836003269002D67 -:106930002E687E0D7810963B7810D345682B781022 -:10694000C63B7F0D7810C63B012002007C0078100A -:10695000D3450120170078109747A3700000092045 -:1069600038520B200600AF70170009200002781083 -:10697000D43A012001007C0000227900BC44774514 -:10698000A845A845A845DD44BA45E544BA45BA45F9 -:10699000BD45BD45C245C245D544D544A845A845D9 -:1069A000BA45A845E5447745E544E544E544E54472 -:1069B0002768840009200B00012000437800CC45A3 -:1069C00027680D0009200B00012000437800AB452B -:1069D0002768930009200B000120004378009345AD -:1069E000012000007C0000227900F34477450C452B -:1069F0000C450C450C45BA45BA45BA45BA45BA45A9 -:106A0000BA45BA45BA450C450C450C450C45BA4546 -:106A10000C450C45BA45BA45BA45BA45774527688D -:106A2000930009200B00012000437800934584A6C1 -:106A30000400C0002845046884A0FF0086A006006A -:106A4000C00081477810D345076817017810C63B0E -:106A5000012002007C00006084A004004000814707 -:106A6000582D046884A0FF0086A00600C0003745AA -:106A70000768170127680200781012482768360057 -:106A80003269002D2E687E0D7810A53B7810D34515 -:106A9000682B7810C63B7F0D7810C63B01200200A2 -:106AA0007C00006084A0040040008147046A94A236 -:106AB000FF0086A20600C0005C4507681701276832 -:106AC0000200582D78101248276836003269002DD0 -:106AD0002E687E0D7810B53B7810D345682B781062 -:106AE000C63B7F0D7810C63B012002007C00781069 -:106AF00081477C00B47080A0CD001A78012001008D -:106B000078109747781005480370000001200200B4 -:106B10007C007810C7477810FE477810D54378106E -:106B2000CD4278100548012001007C007810C7474D -:106B30007810FE477810D543B47080A0CD001A7845 -:106B40000120130078109747781005480370000063 -:106B5000012002007C00781081477C007810C74734 -:106B60007810FE477810D5437810CD42781005484C -:106B700078104D48012001007C00012003007C00BA -:106B800078108E46012000007C007E0C7E07146F7A -:106B90007810B0377F077F0C012000007C00781050 -:106BA000C74778108147012006007C0004698CA14A -:106BB000FF0086A107004000DE4586A10F00C0004F -:106BC000E2457810FE477810D543B47080A0CD0020 -:106BD0001A7878100548037000007C00A87A94A207 -:106BE000FF00A87884A0FF008AA00400C8008147A5 -:106BF0007910F8457C008147FC458147954682A283 -:106C0000030040000346781081477C00A87DACA5B6 -:106C1000FF00A87CA4A4FF00B86984A10001400083 -:106C200042468CA1FFFEBA69A07805A0C00042468A -:106C3000A4A4FF004000364682A40C0040001F467A -:106C4000C80029462B852B8578102E384000294610 -:106C5000781027367800384678106047781052361A -:106C6000B8698DA10001BA69B5A600105A7E7800F6 -:106C70003B4678105236B4A6FFEF5A7EB47080A01F -:106C800091001A78012001007C007E0C7810824669 -:106C90000062E4D2400073460862178294A2FF00AB -:106CA00082A20C00480055464000554611200C00B9 -:106CB000002402A2C8005A462022086294A2FF00C3 -:106CC0001C7002A2C80062461C72002202A5C80005 -:106CD00067462822781064472B852B8578102E383C -:106CE0004000734678102E3678007746781060475B -:106CF00078105936B5A600105A7EB47080A0B9003D -:106D00001A78012004007F0C7C007E001468078044 -:106D100084A00F00038003800380E0A080547F00E4 -:106D20007C007E0C78108246781059367F0C7C00EF -:106D300082A20200C0008147A87A94A2FF00B8692D -:106D400084A100024000CC468CA1FFFDBA69A07866 -:106D500005A0C000CC4682A20200C8006B377810A4 -:106D60002A477810F9367810523684A60001400080 -:106D7000C2462C6884A001004000C246FCC6887848 -:106D800084A040004000C246FDC6B5A600105A7E51 -:106D9000B47080A091001A78012001007C007E0C64 -:106DA0007810824684A2FEFF4000D74611200100E1 -:106DB0007800DB4684A201004000E1460061ECD18E -:106DC000C000E1461120000078101C477810003701 -:106DD0007810593684A600014000F7462C6884A03C -:106DE00001004000F746FCC6887884A040004000BF -:106DF000F746FDC6B5A600105A7EB47080A0B90053 -:106E00001A78012004007F0C7C007E0C6029006051 -:106E10001120010084A00020C0000D4711200000B7 -:106E2000AB780100AB780200AB780300AA7AC0A867 -:106E30000400B86885A00002BA687F0C7C009B78CB -:106E40001800AB780100AB780200AB780300AA7A97 -:106E50009B788100AB7804007C007E0C547060202D -:106E6000006084A00010C000384729203200212093 -:106E70000000780058470865ACA5FF00187086A090 -:106E80002800C000484782A51900C8004E472920A5 -:106E9000190078004E4782A50C00C8004E472920F3 -:106EA0000C0008642784A4A4FF0082A40C004800FE -:106EB000584721200C0078106447B86885A000016D -:106EC000BA687F0C7C0021200000292032009B78CA -:106ED0001800AB780100AB780300AB780100AA7D05 -:106EE000AA7C9B788100AB7805007C000120030020 -:106EF00078108F47B5A600105A7EB47080A0B900F4 -:106F00001A78012005007C000120070078108F47C7 -:106F1000B5A600105A7EB47080A0B9001A7801207E -:106F200004007C009B781800AA789B788100AB78DD -:106F300001007C0004698CA1FF0096A107004000BD -:106F4000A54796A10F004000A5477810AC197C001A -:106F5000246994A13F00C000AE478CA1C0FF05A1E9 -:106F600026687810C63B1C6984A100014000BB471D -:106F7000146978103B3C0462108206627C002C6924 -:106F800034682E6812A13069386832681BA100A2EB -:106F900001A37C007E0CE0AD180003607000066168 -:106FA0000B6000000F60000A136000001760000013 -:106FB00007801A601F600000236000007F0C2468B7 -:106FC00085A0800026687C007E157E137E149820A4 -:106FD00080AF2D00A020AC814000EC47A65384A1D7 -:106FE00001004000F2470433BE787F147F137F1501 -:106FF0007C00B07005A0C0108C24B37000807800B5 -:107000004B4BB071FF81400004487810414C7C002C -:10701000B071FF8140001148487885A008004A7887 -:10702000B3700000781087487C007E0C7E0D7810CD -:107030008919C0001A4878108C247F0C7E157E13A5 -:107040007E14A02D982CA9203100A3537F147F1308 -:107050007F1507680D010B680000047007801A682F -:10706000236800001F6800009F6800007F0C7C0000 -:10707000B47080A091001A787800FA24B47080A0CF -:1070800081001A787800FA24B47080A0B9001A78C8 -:107090007800FA24B47080A0C3001A787800FA242B -:1070A00004698CA1FF0096A1070040005A4896A1F0 -:1070B0000F0040005A4807681701246884A0FF00A9 -:1070C00085A00002266807809B780E00AA782068B9 -:1070D00085A00080226831200004B66E5A7EB4710B -:1070E00088A191001A797C0078100548487885A01D -:1070F0000C004A78B47080A0CD001A7809200B00EB -:10710000012000447810C7470120130078109747EA -:107110007800683C7E129120002249208748007048 -:10712000047205A20C7215A2087084A0F7FF05A2D4 -:107130004000994878009E48037000007F120020AC -:107140007C00007084A00100C000CC48087103815D -:10715000C800AB487810CE497800A3480C708CA0CA -:10716000FF004000CC4804700480C800C34814707D -:1071700005A0C000BF48107005A04000C34802A190 -:10718000C800A348077010007800CC48FF8A400070 -:10719000CC487810184CC000C6484000A34878106E -:1071A0005749037000007F1200207C007E010461BB -:1071B0008CA1FF0086A107004000DF488EA10F00D0 -:1071C000C000E24840607800E34828647F01FF8403 -:1071D00040000D49702C0470BCA00F00B8A71D49D9 -:1071E0003C27FB87C000FB484800F54878108C24FA -:1071F0009C6075A040000D497800E848042768AEFF -:10720000086830A60C6829A5218440000D493887FC -:10721000042705A0C000FC489C7075A0C000E84889 -:107220007C000000050009000D0011001500190088 -:107230001D000000030009000F0015001B000000E6 -:10724000000012490F4900000000008000001249B0 -:1072500000001A49174900000000000000001A4908 -:107260000000154915490000000000800000154984 -:1072700000001B491B4900000000000000001B49E2 -:107280007E12912000227920005271201000077098 -:107290000A000770020003700000712020000770D0 -:1072A0000A000770020003700000492000007F12EE -:1072B00000207C00492057491920000004700480F8 -:1072C000C800AA49077012000871087006A1C00022 -:1072D000614984A1E00140006C4978108C240120B0 -:1072E000FD04042082A00500C800774984A1004065 -:1072F000C00061499CA10C3086A304204000854950 -:1073000086A308004000904986A30C20C000614974 -:1073100000720482480090490C7384A3FF0040006F -:10732000904978108C2407701200007084A001002E -:10733000C000AA49087084A0E001C000AA491073E7 -:10734000147005A34000AA490C7184A10003C00079 -:10735000AA4984A1FF00C0005749077012000770B6 -:107360000800047084A00800C000AE490770120035 -:10737000087103814800B3490370000049200000F0 -:107380007C007E107E007E127E1591200022087106 -:107390007810CE497F157F12912001807F007F10E9 -:1073A0007C00047200750C7384A30003C000F549CF -:1073B00084A1E001C000194A087184A1E001C00065 -:1073C000194A0120FD04042082A00500C800E949F3 -:1073D00084A10040C000D94984A107007900ED498B -:1073E000F749094AF549094AF549554AF549534AC1 -:1073F00078108C24047084A0100085A00200067010 -:10740000FF8AC000044A492000007800084A78102A -:10741000184CC000044A7C00047084A0100085A0B1 -:1074200002000670FF8AC000144A7800184A7810DB -:10743000184CC000144A7C00077012000871E0006C -:107440001C4A91200060E000204A912000600770F3 -:10745000120007700800047084A00800C000284AC9 -:10746000077012000871038148002D4A0370000064 -:10747000007005A0C000414A047005A0C000414A48 -:107480000C7005A04000434A7800244A49200000BF -:107490007810D738186884A0008040004E4A1B68D6 -:1074A00002007C0078108C2478108C247810B14A6B -:1074B000107214710C709CA0FF00002800A311A290 -:1074C00089A100007810B14A0427582C60AC0863E9 -:1074D000002222A30C6300211BA3002405A340006B -:1074E000784AC800784A128410820A8389A1000071 -:1074F000602B78005F4A602B078A7E00046084A0BE -:1075000008004000844ABAA717497800864ABAA7FB -:107510000F497F003DA7002C86688A6F926C8E6BA6 -:1075200007701200781057497C003887042705A09F -:10753000C000A54A9C6005A04000AE4A60200460DF -:1075400084A00F0080A01D493C20FB8740108C24A4 -:10755000518A4000AD4A087084A0030086A0030051 -:107560007C00512000007C00508A3987042704A049 -:10757000C000C54A006064A0C000BC4A602D046021 -:1075800084A00F0080A02D493C20FB8740108C2454 -:107590007C007E127E0D912000227F0D8468602089 -:1075A00088688C6B906C5780D4AAFF0084A0FF0081 -:1075B0007E00046884A008007F004000E04AB8A074 -:1075C00017497800E24AB8A00F49087EB5A60C001A -:1075D00004698CA1FF0086A107004000F04A8EA13B -:1075E0000F00C000F94A1C6884A040004000004B16 -:1075F000B5A601007800004B1C6884A04000400044 -:10760000004BB5A6010007700400047084A00400BC -:10761000C000024B002405A3C0000D4B7800334B83 -:10762000582C0427046160AC006000A41A70046048 -:1076300001A31E7084A108004000234B106081A0AC -:1076400000002270146081A00000267008620024EF -:1076500002A212700C62002303A216700276077059 -:107660000100602B7810924A7800354B7810184C46 -:10767000C000334B7F1200207C007E127E0D9120D3 -:1076800000227F0D07700400047084A00400C00075 -:10769000414B037008007F1200207C007E127E0D9B -:1076A000912000227F0D49204B4B0770040004708D -:1076B00084A00400C000544B087EB5A60C000469E9 -:1076C0008CA1FF0086A107004000674B8EA10F0030 -:1076D000C000724B1C6884A0400040006E4BB5A6F1 -:1076E00001004068502078007B4B1C6884A020007B -:1076F000C000794BB5A6010028685020602D0460B9 -:10770000BCA00F00B8A71D493C27FB87C0008F4BCA -:107710004800894B78108C249C6865A04000934BEE -:1077200078007C4B7810184CC0008F4B7F120020E3 -:107730007C007E127E007E017E0D912000227F0D56 -:107740007F037F04087EB5A60C0004698CA1FF00AE -:1077500086A107004000AD4B8EA10F00C000B64BC4 -:107760001C6884A040004000BD4BB5A60100780015 -:10777000BD4B1C6884A040004000BD4BB5A6010075 -:107780004920964B7E0104698CA1FF0086A1070069 -:107790004000CB4B8EA10F00C000CE4B406878005C -:1077A000CF4B28687F0155A04000154C702D602EEE -:1077B0000470BCA00F00B8A71D493C27FB87C00080 -:1077C000E94B4800E24B78108C249C7075A0602037 -:1077D0004000154C7800D54B042768AE086822A4F9 -:1077E0000C681BA34800024C518AC000F64B78106D -:1077F0008C243887042705A0C000EA4B9C7075A034 -:1078000060204000154C7800D54B228420841A83D8 -:1078100099A300000869002422A10C6900231BA180 -:10782000C800114C78108C24712020007800004B87 -:107830007F1200207C00087084A0030086A0030053 -:107840004000404C042708AC04211A700881042130 -:107850001E700881042112700881042116700460D2 -:1078600084A008004000374C088104212270088160 -:10787000042126700276047084A0100085A0010007 -:1078800006707810924A7C007E127E007E0D912058 -:1078900000224920414C7F0D7F08087184A103001C -:1078A000C0006B4C7E0104698CA1FF0086A107001B -:1078B00040005B4C8EA10F00C0005E4C4068780019 -:1078C0005F4C28687F0105A04000794C78009E48F5 -:1078D00020006B4C7810554A7800794CA000724C0F -:1078E00008717810CE4978004A4C07701000A0004B -:1078F000744C08717810CE49087086A00800C0004A -:107900004A4C007005A0C0004A4C0370000049209A -:1079100000007F1200207C007E127E147E137E15F4 -:107920007E0C7E0D912000227F0D4920894C80AD78 -:107930001100A020992031000C7084A0FF002A685B -:107940000770080007700200037001004000A84C97 -:107950000080AC80A55307700400047084A004006C -:10796000C000AA4C7F0C49200000037000007F1566 -:107970007F137F147F1200207C00912000609120F3 -:107980000080CC7805A04000D14C9479D07006A13D -:10799000C000D14C047805A04000D14C077800000D -:1079A0006800D14C91208040207801802278C0006E -:1079B0002C4D2478227869204052006884A007006A -:1079C0004000EF4C86A002004000EF4C34680DA050 -:1079D0004000EF4C042105A04000EF4C01800A203C -:1079E0004000D44D487805A04000FD4C01804A7805 -:1079F000C000FD4C0920020144680A2078106F2263 -:107A0000906805A04000094D01809268C000094DB2 -:107A10006F6800007368010061200055A920000113 -:107A200009200200346005A040001F4D018036602F -:107A3000C0001F4D106005A040001F4D7E01781052 -:107A40006F227F01E0AC10007000254D78000F4DD3 -:107A5000098140002C4DA920000178000F4D7810BD -:107A6000394D78105E4D0920515204210920020140 -:107A70000A20912001807C00347801803678C00093 -:107A80005D4D3878367891200080447805A0C0009C -:107A9000484D012001010180467880A000754020FA -:107AA000042065A040005D4D246005A04000594DB4 -:107AB0000180266040008D4D0060402C78004E4DC6 -:107AC0007C00287801802A78C0008C4D2C782A7898 -:107AD000307805A0C0006B4D012000020180327893 -:107AE000038003800380038090A0005598A20200C9 -:107AF000042384A0080040008C4D90A209000422B9 -:107B000005A04000844D01801220C0008C4D04234C -:107B100084A0F7FF85A080001A2078106F227C00D7 -:107B200069204052006805A04000974D486806ACA7 -:107B30004000D44D1B600600B46084A0003F1E606E -:107B4000206084A0FF0085A06000226000604220C9 -:107B50001467826F7810C519186805A04000AF4DF2 -:107B600001801A68086884A0EFFF0A681068018025 -:107B7000D000B94D78108C2412682F60000033605B -:107B80000000682C7810DC1C69204052447984A1E4 -:107B90000001012006006E68C000CF4D86690120FB -:107BA00004006E6878106A22912001807C006920B0 -:107BB000000109204052042184A007004000304EFB -:107BC00086A00700C000EA4D7E0D092052526C21AC -:107BD00078101C3B7F0D7800304E092052526421F2 -:107BE000781037241B600600586884A0003F1E6090 -:107BF000206084A0FF0085A0480022602F60000064 -:107C000033600000306884A040004000244E4B6880 -:107C10000400A9201400486884A004004000114E0C -:107C20007000114E7800084E4B680900A92014001E -:107C3000486884A0010040001E4E70001E4E78006F -:107C4000154EA920FA007000244E7800204E0868D6 -:107C500084A0FDFF0A681B68480009205B520B20C6 -:107C600007004C784A78912001807C0079200052EE -:107C700078105E4E7810424E7810504E33780000E7 -:107C8000477800004B7800007C0019200300112089 -:107C90004652042286A03C0040004D4E19200200AE -:107CA0002A7B2E7B7C0019203900112046520422A9 -:107CB00086A03C0040005B4E19202700367B3A7BB3 -:107CC0007C001920713911204652042286A03C0004 -:107CD0004000694E19202626227B267B3F78000033 -:107CE00043780A007C0020002B00000020000000E8 -:107CF0002000000020000000200000002000000004 -:107D000020000000200000002000000020000000F3 -:107D100020000000200000002000000020000000E3 -:107D200020000000200000002000000014001400CB -:107D300049981400140014001400140014001400D6 -:107D400080000F00000001020406080C20212240E0 -:107D500080F818000B3001A2140000A2140000A249 -:107D6000140200006C0002001400CD989E009300E5 -:107D700002A2388806383988C32064088598C1284B -:107D8000AE9C03A20C30462861816A840083561899 -:107D90003A886598F228919C58980C30E128919C7B -:107DA000022806A2C3642E2807A2A064E06DA06783 -:107DB000C06F14183B882478C16864783E8879982D -:107DC000768577866B20C128AE9C44200321A220B3 -:107DD0008120659809A201298D98140005A200A3AD -:107DE00072189A873C88E21F01C60AA26E850407B2 -:107DF000919C140004A200A30930E21964F86E8576 -:107E00003F88E608919881F88C9801C81400C1F861 -:107E10001600B285F080329502FBE21D1400328517 -:107E200041F21400E21DA884A0D7E61F140008A2A6 -:107E300043600880C11D1600008360812A8441F0E0 -:107E40000830A884D6114270DD201100D520228888 -:107E50001600008047281110C098008000A002285A -:107E60001110C69865983E281110CA980BA21700E9 -:107E70000C3000A3E21D81DB14001002D79814001F -:107E8000E0263A8702FBF219E21F14000DA2063821 -:107E90001002B39C040700006C0002004F9814000D -:107EA0009E00A0001700FF600C30208711A2D09C1C -:107EB0007287378801217A98D210E278D39C59983A -:107EC00084D9E2F0A1F0CD981400318866D13088D1 -:107ED0000F80019420B502C820887A9801237A98EF -:107EE000D210E478D39C21882088599823F142F15C -:107EF00001F1C698D210F670328803820C879ED9A1 -:107F000001601400456814021BA2D09C0120C59892 -:107F10000182521884D163D1348801808D98273032 -:107F2000A884561A3388140018A28169BC9C26695B -:107F30000269341A9998141A2170140000A341613F -:107F40006469108092852680B984E4692380E116F3 -:107F50000180F110466913A2621413A20080E11699 -:107F6000B598696914A2C2610280E1140480E11627 -:107F700001010A302788140017A2BC9C140000A33A -:107F800081812A84A884E61C2C88160012A2D09C29 -:107F9000D210E4700400078024941ACCD39CC598B6 -:107FA00027880A3013000080A4841600C2111E2105 -:107FB0000E871DA214008E8716001CA23510919802 -:107FC00010A200A0108092853B8544D02280073803 -:107FD000BB84EA9821800738B9840C307E812B87D6 -:107FE00072879198000020002B0000002000000004 -:107FF0002000000020000000200000002000000001 -:1080000020000000200000002000000020000000F0 -:1080100020000000200000002000000020000000E0 -:1080200020000000200000002000000014001400C8 -:10803000499814001400E298CD981400140014001C -:1080400080003701000001020406080C20212240B4 -:1080500080F818000B3001A2140000A2140000A246 -:10806000140202A2388806383988C32064082FA871 -:10807000C128AE9C03A20C30462861816A8400832B -:1080800056183A8804A8F228919CF4A80C30E128EC -:10809000919C022806A2C3642E2807A2A064E06D6A -:1080A000A067C06F14183B882478C16864783E8844 -:1080B00002A8768577866B20C128AE9C44200321D8 -:1080C000A2208120E4A809A2012909A8140005A280 -:1080D00000A372189A873C88E21F01C60AA26E8527 -:1080E0000407919C140004A200A30930E21964F86B -:1080F0006E853F88E608F7A881F8F0A801C814004B -:10810000C1F81600B285F080329502FBE21D140022 -:10811000328541F21400E21DA884A0D7E61F1400A6 -:1081200008A243600880C11D1600008360812A8474 -:1081300041F00830A884D6114270DD201100D5200E -:1081400022881600008047281110FCA8008000A09B -:1081500002281110FDA89BA83E281110FDA80BA213 -:1081600017000C3000A3E21D81DB1400100201A8EF -:108170001400E0263A8702FBF219E21F14000DA258 -:1081800006381002B39C04071700FF600C302087EC -:1081900011A2639D72873788012121A8D210E2784D -:1081A000669DFCA884D9E2F0A1F06CA81400318887 -:1081B00066D130880F80019420B502C820880FA8AE -:1081C00001230DA8D210E478669D21882088E6A8B6 -:1081D00023F142F101F14FA8D210F67032880382E8 -:1081E0000C879ED901601400456814021BA2639D90 -:1081F000012040A80182521884D163D134880180C3 -:1082000001A82730A884561A3388140018A281695F -:108210004F9D26690269341A01A8141A21701400AE -:1082200000A341616469108092852680B984E46965 -:108230002380E1160180F110466913A2621413A293 -:108240000080E11607A8696914A2C2610280E114E6 -:108250000480E11601010A302788140017A24F9DFF -:10826000140000A381812A84A884E61C2C881600AF -:1082700012A2639DD210E4700400078024941ACCEB -:10828000669DF8A827880A3013000080A484160091 -:10829000C2111E210E871DA214008E8716001CA27B -:1082A0003510B4A810A207380C307E812B87728756 -:0682B000ADA800000C0D5A -:00000001FF -/************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * Copyright (C) 2004 QLogic Corporation - * (www.qlogic.com) - * - *************************************************************************/ - -/************************************************************************ - * * - * --- ISP1040 Initiator/Target Firmware --- * - * 32 LUN Support * - * * - ************************************************************************/ - -/* - * Firmware Version 7.65.06 (14:38 Jan 07, 2002) - */ diff --git a/firmware/qlogic/12160.bin.ihex b/firmware/qlogic/12160.bin.ihex deleted file mode 100644 index dc800ecdaf3acd1ce4e584ff3db684b74ef346cb..0000000000000000000000000000000000000000 --- a/firmware/qlogic/12160.bin.ihex +++ /dev/null @@ -1,1771 +0,0 @@ -:100000000A042A000010040841100000C93600004C -:100010004320504F525947495448312039392C31E7 -:1000200039313239312C39392C3339313439512085 -:100030004F4C494720434F435052524F54414F4930 -:10004000004E492050533231363146207269776D67 -:10005000726120655620726569736E6F31202E3093 -:1000600034302020432073756F74656D20726F4E9D -:10007000202E303050206F72756474634E202E6FC6 -:100080002020303020200024C920FF907120000261 -:10009000A070A2700120FF010420FCD0201171206B -:1000A0000001A070A270C1202000892021127120BF -:1000B0001000C3700400C7705349CB702050CF703C -:1000C0002020D3700A000120FD040420D6700920EE -:1000D000FFFE30212821A2A1004724842484248407 -:1000E00024842484248492A100910920000001200A -:1000F00032000C08051E182279200047A02F082482 -:1001000011200000A9204000A4420981D81D092027 -:1001100000FF003402A118021001A820A4421B789D -:1001200064001478CDC0D5C0167871200002D600C6 -:10013000692040470C085C460120FF010420FCD0E8 -:10014000301169208047712000010C085C4614784A -:10015000D4C01678DE00CA7EC27CC67B67780000F9 -:1001600000788DC0027831203000AF78010123780B -:1001700002002778020009200200692040471B681E -:100180000300236807002768FA002B6808002F681F -:10019000280037680600336808003B6800000981C2 -:1001A0000005CF680A00BF68C04779200047D368C0 -:1001B0002D76C368C04CC768C04BCB68C08CA7689D -:1001C000448FAB68498FAF68448FB368448FA3688E -:1001D00001000120FF010420FCD0C81169208047E4 -:1001E0007008CF680A00BF68C049D3683978C3680F -:1001F000C06CC768404CCB68D08DA768498FAB688E -:100200004E8FAF68498FB368498FA3680100E6003D -:100210006920C04B71200002EC70E4D0192009184D -:1002200021200900201119200C1821200C000C0895 -:10023000751D0120FF010420FCD088116920404C6D -:1002400071200001EC70E4D0192009182120090068 -:10025000201119200C1821200C000C08751DEE002F -:10026000112002006920C04C09200200A9200001D1 -:10027000376800000B684000C87B86A3FFFE28118A -:10028000176800011F6864002000176864001F6879 -:100290000200E8AD1000041F35110981381D01204E -:1002A000FF010420FCD02811118218016920C06CC4 -:1002B000D8080C08F6220C083D400C088C1B0C08D2 -:1002C000154691200022792000477120500091208E -:1002D00000247920004771202000912000267920F9 -:1002E00000027120404791200028792000017120F0 -:1002F00080479120002079200047712010000032B3 -:1003000085A03D30902071201000C37000000410C3 -:100310008C11C07086A0020010110C08BA1339208D -:1003200000000C08AB12AC7805A08011040E9A11E5 -:100330006C7865A010010C08A1200C08261E040E84 -:10034000AF116C7865A010010C08A120040EAF114C -:10035000092047471120874704210C2205A11001DD -:100360000C089B1C71204047A07005A0E8014C744C -:1003700085A40000C8017920000291200080D0727D -:100380008CA23D3090210C084C27912000809120B8 -:100390003D30040ED111792000476C7865A0200112 -:1003A000712010000C08A120041DD91179200047EC -:1003B000712010000C08294471208047A07005A00E -:1003C00088014C7025A070017920000191200080E7 -:1003D000D0728CA23D3090210C084C2791200080D7 -:1003E00091203D307920004771201000040EFA1151 -:1003F0006C7865A010010C08A120041D8E110C085A -:10040000294404088E11003C84A0070002000C124D -:100410000C120E120E1213121312181218120C08CC -:100420007525912000240C08D5400500912000225C -:100430000C08D5400500912000220C08D5409120E1 -:1004400000240C08D540050041124112421242120C -:100450004D124D124D124D1256125612611261126A -:100460004D124D124D124D12701270127012701208 -:10047000701270127012701270127012701270126C -:100480007012701270127012F80C0600060126012C -:10049000912000280C0892252E010E010E000D005F -:1004A0000600060126010C0800122E010E010E00A6 -:1004B0000D00060006012601912000260C08922559 -:1004C0002E010E010E000D000600060126019120EE -:1004D00000260C089225912000280C0892252E0158 -:1004E0000E010E000D00060006012601D600E600F2 -:1004F000F600792000477120000269204047003D46 -:100500008CD03001EC7084A0001CE2780C085C46B2 -:10051000003D84D050016920804771200001EC70BB -:1005200084A0001CE6780C085C460C082625FE001A -:10053000EE00DE002E010E010E000D0008700B8093 -:100540004012077002008CA0E00120119CD008012D -:1005500087089708C37002400408BD13040E1E13D9 -:1005600061200000186084D004191E13287805A0AB -:10057000201104001F1304081E13FCD030010600D4 -:100580000C08291B0E005001280006000C081E1B39 -:100590000E002001012007400408BC131079FCD094 -:1005A0002811612040479CC1FCC720006120804782 -:1005B0009DC1FDC7606005A004191E1312797E60FD -:1005C0002878FCC086A018002011C6000C08261947 -:1005D000CE002B780000786065A0E001C6009C602A -:1005E0000C08F31BCE009F6000000C08601A092065 -:1005F00018008760030110780600FF841011FF8542 -:100600001001C5C012780C08341B0E001278981126 -:100610000C087F1B10789CD01811612040472000E7 -:10062000612080479CC012787B600000D060C4D0FD -:100630003001C4C0D260012005400408BC13040886 -:10064000BA13050006A0C270C670CA70CE70DA7008 -:10065000C0703DA08AA04000041A6C130200BA13B7 -:100660000814D6133C1470147014CE13781A7A142C -:10067000C813DA13DB13DC13DD137C1AC8138714D9 -:10068000DB144119721ADE13C817FE1730187618DA -:1006900085179217A517B717BF15C8130D1518158D -:1006A000261534154B1559155C156E157C158615D8 -:1006B000A515B115C813C813C813C813CC15DD157B -:1006C000F7152B165416661669169316CC16DE16F9 -:1006D00053176317C813C813C813C813751700211D -:1006E0008AA04000041AC8130200C813C813C81314 -:1006F000C813C8139E1AA41AC813C813C813A81A7B -:10070000E81AC813C813C813C81303146B1482144F -:10071000D6143C19C813C8130B19C813EC1A901A35 -:100720009A1AC813C813C813C813C813C813C81318 -:10073000C813C813C813C813C813C813C813C813E1 -:10074000C813C813C813C813C813C813C813C813D1 -:10075000C813C813C813C813C813C813C813C813C1 -:10076000C813C813C813C813C813CA72C6710120AE -:1007700006402800CE73CA72C67101200040C270C4 -:10078000040EBD13612000001B6001009120005089 -:10079000912080400500C3700140900CC37006405A -:1007A000780C99204100A1204100A9200500A35305 -:1007B000200CC470C37004000708F808F008E808AB -:1007C000E00891200080C3700400C7705349CB70CB -:1007D0002050CF702020D3700A0001200400D67072 -:1007E000792000001B7801003120300059200010D2 -:1007F00029201A045120450461204704C12020000B -:10080000912000509120804004081804D875DC74B1 -:10081000DA75DE741800292000002025D071C87216 -:10082000CC73C470A02099203000037001000770C1 -:1008300006001A731E722274267521204000FF8163 -:100840000409BA1382A140001012202106A008203A -:100850000384127007700400077001000870FCD058 -:10086000E80D0770020084A0E0012001C37002407F -:100870000408BD13A824A553100C0408BA1329209A -:1008800000002025D071C872CC73C4709820A120BC -:10089000300003700000077006001A731E72227485 -:1008A00026752120400007700600FF810409BA1355 -:1008B00082A140001012202106A00820038412709B -:1008C000A824A653077001000870FCD0E80D84A08E -:1008D000E001480DC37002400408BD13D875DC74F4 -:1008E000DA75DE747808C471C87014219EA70400FC -:1008F00008110A20CA720408B913C7700A00CB7025 -:100900000400CF702A000408BA13D875DC76DA75B3 -:10091000DE761800292000003025C470C872CC7320 -:10092000D074C670CA72CE73D27405A0E8050AA44A -:10093000080140120180727884A000FC3801AC7874 -:1009400085C0AE78012005400408BC137E7B7A7A0E -:10095000867E827D767C8CA400FF700107840480F3 -:1009600004800C810C810F8118A191A20000B1A616 -:10097000000081A50000500007840480048018A3B3 -:1009800091A20000B1A6000081A500001A731E729A -:100990002276267005A61801107AC5C2127AAC78A4 -:1009A00084A0FCFFAE781800AC7885C0AE7804084F -:1009B000BA13D875DC76DA75DE76180029200000C7 -:1009C0003025C470C872CC73D474C670CA72CE732A -:1009D000D67405A000050AA41001041ABC130180F6 -:1009E000927884A000FC3801AC78C5C0AE780120B4 -:1009F00005400408BC139A7A9E7BA27DA67E002641 -:100A000005A51801107AC5C2127A967CAC7884A02C -:100A1000FFFCAE781800AC78C5C0AE780408BA13F5 -:100A2000092000006C7865A0180108810060D80CCE -:100A3000C47A0408B813092048470C210120FF019B -:100A40000420FCD00419B91311208847142204088B -:100A5000B813092049470C210120FF010420FCD0D4 -:100A60000419B9131120894714220408B81361200E -:100A7000404728612C621482148214820120FF01F5 -:100A80000420FCD04811612080472863DA732C636E -:100A90001C831C831C83DE730408B81309204C4795 -:100AA0000C210120FF010420FCD00419B9131120EE -:100AB0008C4714220408B81318790408B9130920C4 -:100AC00002020C218CA1300F0120FF010420FCD078 -:100AD0000419B91311200201142294A2300F040842 -:100AE000B81309204D470C210120FF010420FCD040 -:100AF0000419B91311208D4714220408B813207962 -:100B00000120FF010420FCD00419B913247A040841 -:100B1000B8131120404CC471FCD110111120C04BEE -:100B2000078184A00F0003800380038068A2006A0D -:100B3000086B1C6CDA74FCD1181121203B021000E8 -:100B400021203B012424A4A4001CDE740408B71354 -:100B5000C4770C089A1B912000801C6B146A9120AA -:100B6000018008270408B71361204047186101205D -:100B7000FF010420FCD00419B913612080471862DA -:100B80000408B813C4770C089A1B912000800869E8 -:100B9000186A106BDA77912001800408B713C471CA -:100BA000102194A20F0082A21000041AB3130C08A3 -:100BB000B42384A30040100195A220000408B713B9 -:100BC000C4710021BCC082A01000041AB313BCD1B0 -:100BD00020111120484704222000112088470422B8 -:100BE000BDC006000021BCC012200C0858231E0006 -:100BF0000408B913C471212049470424C670192080 -:100C000000003000C871212089470424CA70FDC348 -:100C100011202316A9200800042206A13801108201 -:100C2000041F0916C471C8720408B21392A22316D5 -:100C3000260022211E000C086A230120FF01042047 -:100C4000FCD01011FCD3F0090408BA13E803FA0031 -:100C5000F401EE020400010002000300612040479D -:100C600028612C62148214821482C4702A60C870B5 -:100C70000380038003802E600120FF010420FCD04C -:100C8000A011260016006120804728612C62148282 -:100C900014821482D8702A60DC7003800380038081 -:100CA0002E60DA71DE721E002E000408B813612077 -:100CB00040473061C47032600120FF010420FCD045 -:100CC0000419B913612080473062C870326004088B -:100CD000B81318790408B913C47184A1CFF048017E -:100CE0000120FF010420FCD00419B313C8720408CA -:100CF000B213192000000C08A62336000120FF01C2 -:100D00000420FCD018011E000408B913C87184A186 -:100D1000CFF028010E001021C4710408B213FDC3E6 -:100D20000C08A62310231E000408B813C47182A166 -:100D3000100048020120FF010420FCD00419B31365 -:100D4000C8720408B21311204D4704220600048122 -:100D5000081208811221192000000C089323012099 -:100D6000FF010420FCD018011E000408B913C8714B -:100D700082A11000280206001021C4710408B213D9 -:100D800011208D47042206000481081208811221D7 -:100D9000FDC30C0893232E001E000408B813C47171 -:100DA000C87284A1FDFF0419B21384A2FDFF0419C7 -:100DB000B2130021207922780022247A26780408B0 -:100DC000B8131120404CC471FCD110111120C04B3C -:100DD000078184A00F0003800380038068A2C8728B -:100DE000CC73D874C6710068CA70CE73DA7491205F -:100DF0000080026AACD2181121200000900084A467 -:100E0000FF0082A00200041A4F173F84BCA7FF0016 -:100E1000400186A7020004194F1784A4FF000409AB -:100E20004F1761200002FCD1100161200001292030 -:100E30000900312062003F84BCA7FF003001078316 -:100E400084A0FF0010113DA738114120190084A390 -:100E5000FF0082A01A001002A4A4FF00078384A050 -:100E6000FF00880142A8F00286A0100020119CA378 -:100E7000FF009DA3000FBCA3FF00002502A7900266 -:100E8000002602A7781239203A00046805A70668F0 -:100E90000A6B0C6BCE731C68DA701E6C912001809B -:100EA0000408BA13912001800408B413C4770C0815 -:100EB0009A1B91200080146A1C6B91200180C870DD -:100EC0001668CC701E6808270408B713C470612028 -:100ED000404718611A600120FF010420FCD004196A -:100EE000B913C8706120804718621A600408B813EB -:100EF000C471C872CC7382A11000041AB3130C0819 -:100F0000D82384A30040100195A220000408B71341 -:100F1000C4770C089A1B91200080086A8DC20A6A67 -:100F20009120018008270408B813C4770C089A1B85 -:100F300091200080086A94A2F9FF0A6A046805A05B -:100F400010010C08D5229120018008270408B8134D -:100F5000C4770C089A1B91200080086A95C20A6A1F -:100F6000046805A010010C08D522912001800827F3 -:100F70000408B813C477412001004920050051201E -:100F80002000912000800C08B21B912001800827CE -:100F9000086A0408B813C477FCD728010C08291B79 -:100FA00038010408BC130C081E1B10010408BC13F4 -:100FB000C873CC72C677CA73CE720C082A1CE811AB -:100FC000186805A0A001082776000C08F7237E000A -:100FD000701101201500FCD718116120404718003E -:100FE000FDC0612080472A78912001800500912072 -:100FF0000180012005400408BC13912001800408F1 -:10100000BA13C477FCD728010C08291B380104083F -:10101000BC130C081E1B10010408BC13C67741202A -:1010200021004920050051202000912000800C085B -:10103000B21B09201600FCD7181161204047180088 -:1010400061208047FDC1636003007B600000726720 -:101050007F600F002A79D061C4C1D2610C08D5220B -:10106000912001800500C877CA77C477C677FCD77E -:1010700028010C08291B38010408BC130C081E1B8E -:1010800010010408BC13BCA700FF912000800920B8 -:101090001700FCD7181161204047180061208047D5 -:1010A000FDC17B6000006360020072677F600F001B -:1010B0002A79D061C4C1D2610C08D5229120018067 -:1010C000412021004920050051201000912000807E -:1010D000C87005A01801D060FDC0D2600C08B21B1A -:1010E000C8703668388784A71F00C01D9120018012 -:1010F000050019200000C87284D228010C08291BA1 -:1011000038010408BC130C081E1B10010408BC1392 -:10111000C872CA72AC7884A0030018153920000088 -:1011200084D20801FDC7412021004920040051203C -:1011300008000C089A1B912000800868D4C00DA8F4 -:101140000A693768000091200180388784A71F0052 -:10115000801DBCA700FF3F8738873F8784A7000F0B -:10116000401D91200080C8726920000184D21011B6 -:1011700069200002086884A0FDFF0A683068B4D0C6 -:10118000B0014B680400A9201400486894D01001F5 -:10119000041FC2184B680900A9201400486884D0B5 -:1011A0001001041FCB18A920FA00041FD2187920BF -:1011B000004709201800C87284D2181161204047E6 -:1011C000180061208047FDC17B6000002A796360C0 -:1011D00001007F600F00A3600000A460AE60B260F9 -:1011E000D060B4D06001B4C0D260C600B46065A065 -:1011F0000860D4C00A60186001801A60CE00D06018 -:1012000084A0FF7ED260AC788DC0AE78FF830801E9 -:1012100005001B685400912001800500CC730C0868 -:101220007818EC69486A85A100184A6885A14000D1 -:10123000EE68CC7321200400A920FF09041F1B19AC -:101240002184D01D1983B01DEE694A6A9120018066 -:101250000500FCD71811692040471000692080471D -:10126000C471C6711669FF811011A3680100AC78C2 -:101270008CC0AE7884D010110C087A1C0500D8758B -:10128000DC74DA75DE7410002EA02025C471C873DA -:10129000CC72C671CA73CE7279200047DE7DDA7CCB -:1012A000D67BD27A0C08771B04095C1AA9200500AA -:1012B000A120144791200080A141912001800920A4 -:1012C00040000C08411D20010C087F1B04085C1A1B -:1012D00004608CA0FF008EA10900201106000C08FC -:1012E00086200E0084A000FF078009800409F11900 -:1012F000C600682C0C08771BA805002C9E68098185 -:10130000C01D9F600000CE00C600DC7DD87CD47B71 -:10131000D07A90A2400099A30000A1A40000A9A542 -:101320000000DE7DDA7CD67BD27A682C9C6865A0D2 -:101330000409F019092040000C08411DA0150460A3 -:1013400084A0FF0086A002005001046084A0FF007A -:1013500086A00A00381116000C0883201E00002DFC -:1013600002609808CE00C6009C600C08F31BCE00FB -:101370009F6000000C08601A092018000860CDC0AA -:101380000A600460866010780600FF841011FF85F3 -:101390001001C5C012780C08341B0E0012780C081E -:1013A0007F1B04085C1ACE00C6009C600C08F31B6F -:1013B000CE009F6000000C08601A092018008760AA -:1013C00003011B60030010780600FF841011FF85E5 -:1013D0001001C5C012780C08341B0E0012780C08DE -:1013E0007F1B04085C1ACE001461FCD120010C089C -:1013F000291BF00118000C081E1BD0010C08601AF4 -:1014000009201800876003011B6021001078060086 -:10141000FF841011FF851001C5C012780C08341B21 -:101420000E0012780C087F1B012007400408BC1333 -:1014300004618CA1FF0086A1050018111C60BDC0CD -:101440001E60C474C873CC72146091200080E600E2 -:1014500009201200FCD0181171204047180071209B -:101460008047FDC12A7963700500D071C4C1D27173 -:1014700066736A726E74727077700000002C7A70F6 -:101480002EA030251C6184A1600010010C08E93FEA -:10149000EE009665A6659A66AA66AF600000B36026 -:1014A0000000146723600000246096A00100101162 -:1014B000008026600C08D522912001800500C370B1 -:1014C00005400408BD13A920050099201447912068 -:1014D00000800A5391200180002110A299A30000EE -:1014E000A1A40000A9A500000500C471C7700000F8 -:1014F0001E790408BA13C471C671682110006920EE -:1015000000100C6916A0042D10A2688D0981D81D49 -:1015100085A200001811C37000401000C370034082 -:10152000CA700408BD136479C671C47182A1030036 -:10153000041AB31366790408BA136479C6710408EF -:10154000BA130079C671C47102790408BA1300791C -:10155000C6710408BA13C470112000008CA00D00DD -:1015600060010C81300210820C810C81100210820B -:101570000C81FF810419B41310820E7A8CD23805C5 -:101580001079CDC11279092021001920030084D2DD -:10159000C00108811920410011204E8F122319200B -:1015A00042001082122319204300108212231920B6 -:1015B000460010821223192047001082122319209E -:1015C00006001120538F12211120738F12230479EA -:1015D00006780408B9130478C6700408BA13C471F5 -:1015E000FCD118111120C04B10001120404C078174 -:1015F00084A00F0003800380038068A211200000F4 -:101600001468FCD0100195A20002B4D0100195A27C -:1016100001000C6B0068DA700408B7131478F4D07A -:10162000300101200740DB70000005A04800FCD01D -:10163000300101200740DB70010005A0080006A072 -:1016400005001478F4D0300101200740DB70000061 -:1016500005A0080006A005001478FCD03001012088 -:101660000740DB70010005A0080006A0050012710C -:101670001A721E731078C4D010012274267580ACC3 -:10168000010008810C81A9819880A120300003709D -:1016900000008460A220A65307700100747984A121 -:1016A00000FF40010F810C810C81048004800780C1 -:1016B00000A118000781048004807C7908A1787A51 -:1016C00006A011A2107DC4D52001847B19A3807CC3 -:1016D00021A40870FCD0E80D03700100077006001B -:1016E0001A711E72107DC4D510012273267484A055 -:1016F000E0010500487865A02001042C4A786320A9 -:1017000000000500F6007920004748786220002C90 -:1017100005A010110C0875254A78FE00050011205F -:1017200000914A7AC47B1983280180A232001220DA -:101730001020C80C13200000050016002600FCD75E -:1017400018111120C04C10001120C06C84A7000F8C -:101750000B8084A71F002001038003800380038087 -:1017600005A168A22E001E000500390C00292A6878 -:10177000002A2E68086884A0EFF90DA80A69E6001F -:10178000FCD728110920524771204047200009202A -:101790009247712080470C21046805A0480116A1DA -:1017A000381160200060066816000B200000180049 -:1017B000092000001600046865A078010060066832 -:1017C00021040C08B21D1068087909810A7901808A -:1017D0001268881D1079A5C112791E000269066978 -:1017E000002D60200C08BF26EE00050065A06001FA -:1017F00008209C6005A0280162209F60000065A071 -:10180000C00C48784A7962200500076003018F60A8 -:101810000000A9201C0080AC0500A02001200000D1 -:10182000A44028681A602C6822600500E600FCD7F6 -:101830002811712040473120C04720007120804787 -:101840003120C0494C708CA00002281108A60A2D36 -:1018500000804E7006A0EE000500F600FCD71811BF -:10186000792040471000792080470C089A1B91206E -:10187000008004680A7865A0F0053000002C0A7822 -:101880006020006065A0B805106006A3B81D0C605C -:1018900006A2A01D282C487806AC0811480404684C -:1018A00006AC401100606020066805A018110368AE -:1018B00000004800006408786020026486A40000EC -:1018C0001011002C026860250C08021C1B6005002A -:1018D00023602000FE000C08B21DF6000879098183 -:1018E0000A7910680180126818111078A5C0127862 -:1018F0000120FFFF05A0FE0005007600002739202B -:101900000000FCD00801FDC741202100492004004F -:1019100051200800912000800C08B21B388784A752 -:101920001F00D01DBCA700FF3F8738873F8784A7D3 -:10193000000F901D912001807E0005006C78092029 -:10194000748F0C210DA1180165A00408A12061204D -:101950000000186084D0B81110788CD030018CC091 -:101960001278FCC76920404728008DC01278692092 -:101970008047FDC7912000801C681F6800009120EF -:10198000018005A0081105008CA0F0FF10010C08D3 -:1019900075250200D71CDA1CE01CE41CD81CE81CCE -:1019A000D81CD81CD81CEE1C181D1B1D201D291D61 -:1019B000D81CD81C05000C0875250C087A1C0120C1 -:1019C00001800408321D012003800408321D01201B -:1019D00004800408321D0C087A1C012006800408CB -:1019E000321D11200A8091200080FCD71811692037 -:1019F00040471000692080473820006886A000001A -:101A000020011E6F91200180050026007068BCA097 -:101A100000FF4120210049200400512010000C0843 -:101A2000B21B388784A71F00D01D912001800E00B3 -:101A30007069C671D00001200C80B8000C087A1CB7 -:101A400001200D809000FCD71001E4780800E078B8 -:101A5000C67001200E804800FCD71001EC78080009 -:101A6000E878C67001200F800000C270FCD7181102 -:101A7000DB7000001000DB700100612000001B60C3 -:101A8000010091208040050080AC0100FF81180515 -:101A900099203000A0200C7084A0FF07000118706E -:101AA00006001C70060020700600247006001271EB -:101AB000AC811A721E7322742675037001000770C0 -:101AC000010008700B80E81E077002008CA0E00186 -:101AD0001011A55306A003700000077004000E004B -:101AE00026700E0022700E001E700E001A70050087 -:101AF00011202000092010000A6B0E6C1F680102E3 -:101B0000036820FD076838001A6A002DE8A0080065 -:101B100090A204000981801D0500EC70DCD0201526 -:101B2000292001001478CCD06011EC70E4D0192089 -:101B30000A0C21200A00201119200C0C21200C0075 -:101B40007000EC70E4D0281119200C1821200C0032 -:101B500030001920091821200900ADA500020A6BE8 -:101B60000E6C1E6D07683800050004608660082C46 -:101B700063200000687805A06A791001022C080033 -:101B80006E790500C6006120004787680301082DB3 -:101B90006B200000686005A06A611001022D08003A -:101BA0006E61CE00050091200080042C6E7805A0A7 -:101BB00008116A78912001809C6005A08801C60008 -:101BC000602008209C6005A0380162209F60000012 -:101BD00065A09C6005A0C81D48784A796220CE00A7 -:101BE000487862209F60000085AC000010110C084E -:101BF00075254A780500A920100006A0048086807B -:101C00008E81081200A2041FFC1D86808E810500B3 -:101C10005601A920100005A0B8011AA1A81213822C -:101C20008D8128021AA12012041F0C1E28001AA15F -:101C300008231082041F0C1E0600003284A0FFEF50 -:101C400080200E005E0105000600003285A0001015 -:101C5000B80C747DD07006A50409DA1E10785020E7 -:101C60000C08771B0409DA1E46A070790025008055 -:101C700012A10920400008123000D07206A21801FB -:101C8000408809208000C600127107700100992069 -:101C90003000A920200080AC0100A02061200000BD -:101CA000FF8810010C08771B0870FCD0E80D077046 -:101CB0000200912001808CA0E0013815A553FF8C13 -:101CC0002011FF880409C71E5000002C8E78A9201F -:101CD000200080AC0100A020A5530408C71E46A028 -:101CE00018721C73C4DA10012074247592A240008B -:101CF0009BA30000A3A40000ABA500001A721E73F2 -:101D0000C4DA18012274267506A0077004000409BD -:101D1000C71EFF8C10010C087F1BCE000C087F1B18 -:101D200046A0887800808A7886A00200C0017C7A6C -:101D3000787BC4DA1001847C807D7479078104800B -:101D4000048010A299A30000A1A40000A9A500008E -:101D50001A721E73C4DA8805227426757004146022 -:101D6000FCD018116920404710006920804791205D -:101D700000801F680200FF88200146A08C78602048 -:101D8000700C8B780000AC7885A00300AE789120B1 -:101D900001809800CE008B7800000C085C20046065 -:101DA00084A00F005900FF8830018C786020046007 -:101DB00084A00F0019000408261E05000200EC1E76 -:101DC000071F201FEC1E2D1FFD1EEC1EEC1EEC1E1F -:101DD000051F1E1FEC1EEC1EEC1EEC1EEC1E392017 -:101DE0000004BC7805A7BE78086005A70A600C0847 -:101DF000691F9C60BA789F6000000C0848200500AD -:101E0000BC78C4D00801580C1C60BDC01E603000F6 -:101E10000C088620BC78C4D00801080CBF780000EC -:101E20000460078084A0FF00B278018038010C08AC -:101E3000691F2001BC78C5C0BE7810000408841F4B -:101E400005000C088320BC788CA0000E1011C4D0B3 -:101E5000081128080C08691F10110408841F0500C8 -:101E6000BC78C4D010010408EC1EBF7800001467D1 -:101E700011200100A822186084A0FF0005A088019D -:101E8000BCA700FFA92020008EA001005001BCA724 -:101E9000008011200200A92000018EA0020008018C -:101EA000C0000C089A1B002D912000802B680000B8 -:101EB0002F680000086884A0DEFF0A68E8AD100003 -:101EC00091200180041F511F11821801A9200001D7 -:101ED000580C0C087F1B05009F600000B4786DA0B3 -:101EE000002CB6781011BA7838009E68002D026078 -:101EF000B87806AD08110260B0780180B278301170 -:101F0000BC78C4C0BE78B878602006A00500E600A2 -:101F10002EA03025BA7DB67DAE65B2651C60A2608C -:101F2000482084A9FFE11E6084A9600060010C08BC -:101F3000E93FFF864011FF853011392000080C0869 -:101F40004820040846209665A6659A66AA66146726 -:101F500071208047FCD710117120404784A7000FE3 -:101F60000B8084A71F00200103800380038003806F -:101F700005A1C07168A10027078084A00F0003801D -:101F800003800380C47100A1C26091200080147896 -:101F9000C4D03801FCD71811F4D040111000FCD087 -:101FA0002811086E84D6F001FCD9E011912001803F -:101FB0000C08021C912000800C08B21D91200180A9 -:101FC0001478C4D004094620FCD72011F4D0301175 -:101FD00004084620FCD01011040846201B60210094 -:101FE00004084620246096A001001011008026609D -:101FF000106A146802A268026001912001803920F1 -:1020000000029C60BA789F6000000C084820040819 -:102010004620082CFCD9F001006865A0D801046AAC -:10202000007084A002006801487006A25011046B81 -:1020300060210423026005A0081102696022026188 -:102040009800002D60200C08BF26086E60210262F7 -:10205000066950000068026965A01001026108006D -:1020600006696021036000006021FCD91801B4A654 -:10207000FCFF0A6E1068087D28850A7D00801268C2 -:1020800091200180B4D62801B6A640000A6E0C0843 -:10209000131CEE000500086005A70A60912000806F -:1020A0000C08B21D91200180B87865A028019C60C1 -:1020B000BA789F600000780CB678BA78050070791D -:1020C0007478182884D31801008012A1200200809F -:1020D00012A1781284C37C7A1A72787A1E72C4DADA -:1020E0002001847A2272807A267206A084D30801A5 -:1020F00000807678D2701C7805A0380101801E78A7 -:102100002011040E82209120804005003920982063 -:10211000100039209E20042705A0600100AC682033 -:102120000869106812690A680C69146816690E68F3 -:102130003887880C0500030009000F0015001B00FC -:10214000000015001B000000412000000C78020078 -:102150004A222522A92019213920748F3427107D85 -:10216000C000846086A00301041903211461186073 -:1021700005A12001FF86D81104080321038680A051 -:10218000558F0C6202220080106202220C08D01DC2 -:1021900030868EA60F00040984216C7865A0081D86 -:1021A000087802A62012ACD510113A26050082A6A6 -:1021B0000300041A8421912000806920000018681F -:1021C00084D0F8111120558F0422C6701082042289 -:1021D000CA7084D6301110820422DA701082042270 -:1021E000DE7085A62080C2701B68010091208040AF -:1021F000107884A0CFFF1278912001803B2000004E -:1022000005001078ADC01278040884213A260C0825 -:10221000502204196C226C7865A00419AE2091201C -:102220000080107884A0CFFFFF860801ADC012782F -:102230009120018004086C223920748F3427107D8E -:10224000A000846086A0030104196E211461186047 -:1022500005A12001FF86B81104086E2180A6558FC4 -:102260000C6202220C08D01D30868EA61E000409C6 -:1022700084216C7865A0281D087802A62012ACD5B0 -:1022800010113A26050082A60600041A8421912026 -:10229000008069200000186884D0F8111120558F43 -:1022A00009204E8FA8261C2104221A2008811082A2 -:1022B000041F502185A63080C2701B680100912048 -:1022C0008040107884A0CFFF12789120018006A072 -:1022D0000920758F0A203A2005001078ADC01278C9 -:1022E000B0003A260C08502204196C226C7865A0C4 -:1022F00004191E2191200080107884A0CFFFFF8652 -:102300000801ADC012789120018004086C22912050 -:102310000080077004009479D47002A1280268013B -:10232000907B02A350111000028038113A261078D9 -:10233000ADC0127891200180050084A100FF40010A -:102340000F810C810C8104800480078000A118009B -:102350000781048004809C7A10A21A72987A06A0E1 -:1023600011A21E72C4D43001A47A11A22272A07AE2 -:1023700011A22672A1203000037000000920548FA2 -:102380000A2609819821042184D008013386B0A649 -:102390000200A826A65303861270077001009079E8 -:1023A000947800800AA1081206A02820747984A1DC -:1023B00000FF40010F810C810C81048004800780A4 -:1023C00000A118000781048004807C7908A1787A34 -:1023D00006A011A2C4D42001847B19A3807C21A46F -:1023E0000870FCD0E80D84A0E001D001107D312000 -:1023F000548F3426A8780080AA788CD038110770C2 -:102400000600047094D0E81D04088621692047471F -:102410006B200300AC7885A00003AE7806A04800CE -:102420003020D67591208040967D107DACA5CFFFE1 -:10243000127D91200180AA78077006003A26037069 -:1024400001001A711E72C4D5100122732674050092 -:10245000846086A00301D8111461186005A1B81129 -:1024600069200000186884D090110C60C67010605C -:10247000CA70C37020801B680100912080400C0846 -:10248000D01D040E43226C7865A0101D0500590074 -:1024900030156C7865A0E0191004290000156C78DF -:1024A00065A0D81DE000846086A003016811186053 -:1024B000FCC01A6086A0040038110478A4D0200162 -:1024C0000C08D01D06A005007900181185A0010098 -:1024D0000500B900101141200100107D0500FF88A2 -:1024E0001001912080400500907B9479D47002A166 -:1024F000181185A300000500100202A30500028048 -:10250000050084A100FF40010F810C810C81048033 -:102510000480078000A118000781048004809C7A51 -:10252000987BA47CA07D10A206A019A321A429A5B4 -:1025300009201800286005A01001092040000C089F -:10254000341BD001A8780080AA788CD010151460B4 -:10255000FCD0181169204047100069208047912065 -:1025600000801F680300AB780000AC7885A00003F2 -:10257000AE78912001806800AB7800000C08D01D77 -:102580009079947800800AA1081206A09678D670F7 -:1025900006A071201000912001800500FCD71811C1 -:1025A00009205847100009209847912000800A20F0 -:1025B000F6000920804779200001FCD7201109206E -:1025C000404779200002042186A000008011FCD73A -:1025D000181109204547100009208547042105A04E -:1025E0003011307884A0C00010111B785200FE001A -:1025F000050009200200692000470120FF01042096 -:10260000FCD004194B237120804779200001212040 -:10261000BF494B780F000120FF010420FCD01801B6 -:102620001920373E3000A1202B011920373E84D1DC -:102630001001A1202B02042305A040019A781883E1 -:10264000AC2318839823A6531833A80C9B7800005A -:102650009B782000A9201000AF780000AF782020E0 -:10266000041F29230370000016008CD109200000EC -:102670000801BDC10C086C241E00207084A00F004E -:1026800085A0006306780F7800904378D8005378CF -:1026900090000B78082F52744F70000009814001A0 -:1026A00071204047792000022120BF4704080623FB -:1026B0000C0826250500160011200101BCD11011BF -:1026C000112001028CA10F00042284A0F0FF05A1BB -:1026D00012201E000C086C24050011200101FCD3FF -:1026E000101111200102A92009000B81041F72237F -:1026F0008CA1000E042284A0FFF105A11220050088 -:102700001920020009200101A92005001382041FDD -:10271000832394A2E000042184A01FFF05A20A20C5 -:102720001983180109200102780C0500112001010C -:10273000FCD3101111200102A9200C000B81041FF1 -:102740009B238CA100F0042284A0FF0F05A112207E -:10275000050011200201FCD31011112002020422F5 -:102760009CA0300F84A0CFF005A112200500C60068 -:1027700061200001BCD1101161200002BCC10381A5 -:10278000038080A020009A60AC62AC63CE0005009C -:10279000C60061200001BCD1101161200002BCC143 -:1027A0000381038080A022009A60A46084A0DFFFE0 -:1027B000AE60CE000500C60061200001BCD1101142 -:1027C00061200002BCC10381038080A020009A60C8 -:1027D000A4608CA220001801ACC29DA30040ECC3F1 -:1027E000B4D30811EDC3AE621020A460AE6318200C -:1027F000CE00050091200080C600E600186805A004 -:1028000004095024FCD118016120D08E10006120F1 -:10281000C08D0C0858246005A9200101FCD11801C5 -:102820006120D08D10006120C08CC6000C08582497 -:102830002801CE00608C041F1224A8040E00FCD1D5 -:10284000280182A0D08D71208047200082A0C08CFA -:102850007120404776707271382101200400627047 -:102860007F700F00D071C4C1D2710C08CB22C000A0 -:10287000FCD1181171204047100071208047206062 -:10288000DDC0226072713821002C7A7001200600B0 -:1028900062707F700F00D071C4C1D2710C08CB225E -:1028A000012000001000012001009120018005A0FE -:1028B000EE00CE000500042C05A070016020106021 -:1028C00006A340110C6006A22811146006A1101185 -:1028D00006A020000060800C85A001000500F60025 -:1028E000E60016007920804771200001BCD120113C -:1028F000792040477120000220798CA10F00EC70F4 -:10290000C4D010111E0060000B810B810B810B8164 -:102910000E008DA10008BCD010118DA1000F042164 -:10292000EE00FE000500012001470420ACD0381164 -:10293000E468ACD0200184A006000811090005005D -:102940001460E600360018207120404CFCD01011B5 -:102950007120C04B078084A00F0003800380038098 -:1029600070AE047084A00A0004192325087194A194 -:1029700000FF040923258CA1FF001C7084A000FF28 -:10298000C001047085A03A0006700120090002A170 -:10299000D81601200A0002A1D01601200C0002A1C5 -:1029A000C8161C7084A0FF001E70047084A0DFFF96 -:1029B000067001200A0006A1A80101200C0006A152 -:1029C000A0010120120006A198010120140006A117 -:1029D00090010120190006A188010120320006A102 -:1029E0008001D80009200C00D00009201200B80096 -:1029F00009201400A00009201900880009202000E7 -:102A0000700009203F00580009200A0040000920FA -:102A10000C002800092019001000112000000021DE -:102A200005A20A70047085A00A0006707120004794 -:102A30000470BCD05801FCD32011EA7371204047C8 -:102A40001800EE73712080471F700D003E00EE00ED -:102A500005000120FF010420FCD0D0110120FD045D -:102A6000042082A00500A01271200002EC718CA14C -:102A7000001C0F810C810C8179200001EC7884A06E -:102A8000001C07800480048005A18AA007000802BA -:102A90000500020074255B2574255B254E256825FD -:102AA0004E25087084A0FFC385A000300A70087806 -:102AB00084A0FFC385A000300A780500087084A0B8 -:102AC000FFC385A000200A70087884A0FFC385A0FA -:102AD00000200A780500087084A0FFC385A0000CC0 -:102AE0000A70087884A0FFC385A0000C0A7805004E -:102AF000040E7525912000807120000006001870DA -:102B000084D0E81D0E0071201000CA700E00C6703F -:102B1000C3700280DB70040ADF702A00712000009D -:102B20001B70010091208040F80C3C7F587E307C67 -:102B3000387DA0788A708E75927496769A7794A56F -:102B40003F00F4D43801BCD7281184A77D000419B4 -:102B50009C3C71089CA40F0082A304002003A6A340 -:102B6000070030191824078584A00F0002006C2B81 -:102B7000572C952CFB2E7932D03276330534D9344C -:102B8000AB35C725C4259E29852A4D32C4250C089E -:102B90007525050006A0380008788DC00A7806A0C3 -:102BA00002704A704270CE705C7005A0041918273C -:102BB000607084A007000200E12552265A26632691 -:102BC0006C26FE26752652263078BCD0101DD0719A -:102BD000BCD1F819B4D104192F26A07086A0010029 -:102BE000C009147005A0A819B0706DA0006865A098 -:102BF00055A09B7880000C6BAA7B086845A0106DDF -:102C000004686DA05DA086A801001801BC69AA7DBA -:102C1000AA79C0684DA01C6E0120100004084B2842 -:102C20005C7005A00419C625C600D600B0706DA062 -:102C3000006865A055A09B7880000C6BAA7B086893 -:102C400045A0106D04686DA05DA086A80100180164 -:102C5000BC69AA7DAA79C0684DA01C6E0120200025 -:102C600004084B280C085B3C0419C6251B78680037 -:102C7000B8706DA0B4685A789468D678DE78986891 -:102C8000D278DA7808788DC00A78BC683E70B4C112 -:102C9000D271B47065A0C068567003700200002D38 -:102CA0004A7080AD0900427005000C085B3C2011A1 -:102CB0001B7854000370040005000C085B3C2811CD -:102CC00011200C0019040370040005000C085B3C83 -:102CD000281111200600D1000370040005000C0823 -:102CE0005B3C281111200D008900037004000500D1 -:102CF0000C085B3C501111200600410078707B707D -:102D0000000068204A700370040005007071FCC167 -:102D1000078182789B78800086A20C002011AA7A15 -:102D20000120010098008CA11F008DA1C000AA798C -:102D300086A20D002001AA7A012002003800AB789B -:102D400020007471AA79AA7A012004009B7860009F -:102D5000AA785B7804001B7813010C086E3C7F7026 -:102D60000F00D070B4D06801B4C0D270C600B47087 -:102D700065A0086084A0EFFB0A60186001801A60FB -:102D8000CE000500147005A03811D070B4D0280111 -:102D9000B47006AC1011290C05001600A07186A1B4 -:102DA00001002805D600260000211120010012A2F2 -:102DB000B0706820006806AC20011182B001C90023 -:102DC000C80CC60000211120010012A2B0706820BA -:102DD00000686020086084A0EFFB0A601182100187 -:102DE0004100B00CA3700100CE002E00DE001E00DA -:102DF0000500E8AD0500A87006AD1011A4706820AC -:102E000005000C085B3C0419C625787068207077B3 -:102E10000C08953B502C0C08F63C9B7880001468FD -:102E200084A01F00BDC0AA781C6E412001000120B3 -:102E30000400040850280C085B3C0419C6259B7844 -:102E400080005C706820146FD070B4D06801B4C08A -:102E5000D270C600B47065A0086084A0EFFB0A6061 -:102E6000186001801A60CE000C08953B502C0C08AD -:102E7000F63C246805A0300182A00600080210007C -:102E800027680500146884A01F00BDC0AA783120FF -:102E900020004120010001200300040850288DC2B9 -:102EA000D272BC7200A215A0507108812AA108023A -:102EB000BC7164210465FF85701152712184A81DC5 -:102EC000D0708CD02801CC7005A01011CF700A00F2 -:102ED00005000022900CD0708CC0D270CF70000022 -:102EE000346005A0B01D086784A73F07D001D4D780 -:102EF000801D84A72100681D84A70200300184A7DB -:102F00000400380DBCA7FBFF0A6784A71802081D40 -:102F100084A700013001186005A0D819BCA7FFFEE6 -:102F20000A676825236800001C6E84A60E001863DB -:102F300028011C6002A3200218015808FF834819C9 -:102F4000582D502C5271BCD72011287022603A6045 -:102F50001000BCC70A67C06865A04DA00061602A68 -:102F600041200100146B9CA31F009DA3C000FCD155 -:102F7000100184D610019CA3BFFFA4D610019DA30D -:102F8000200084A60E0004190228A5C70A67002C99 -:102F9000C668A07786A701007811D070B4D0601100 -:102FA000007082A0020040123078BCD028119B78BB -:102FB0008000AA7B040849283987A2775027AC777C -:102FC000B0A70500A87006A60811A476AE763A2C24 -:102FD00038873A2D38873A2838873A2338873A2570 -:102FE0003078BCD050019120008091203D30D070CD -:102FF00084A03D30912000809020D5AA00002001BF -:1030000021840022041951270500DCD10409F1377D -:10301000292020009CD6201128858CD608112885CF -:103020004088146F0C6108818CA1FF00C87060A1FA -:10303000642CFF8C8801146006A7D01DB860018045 -:10304000BA60881D602A086085A000010A6000221D -:103050002184041951270500602A0E61BE69002CE5 -:10306000C66840880860D5C00A60A07786A70100BE -:103070000419D927D070B4D00419D927007082A0C0 -:103080000200041AD9273078BCD00419D9279B78BC -:103090008000AA7BAA7DAA790120020006001860A0 -:1030A00000801A600800060060290461602A0C088C -:1030B000093D901584A11800800184A11000180119 -:1030C0000C089A39481584A108003801A06984A128 -:1030D000000618110C08B838F800A06984A1001E79 -:1030E000280584A100087801C6006029006085A039 -:1030F0000020026004618DA110000661CE000C0862 -:103100009A395011A06984A1000218010C08FD38F9 -:10311000180084A10004F019A06984A100103001F6 -:1031200014698CA100FF0F810C08C5232E008CA60A -:10313000E00084A66000280186A0600010118DA127 -:1031400000408DA10401B6699B7860000028AA7830 -:103150001868FDC01A68BCD66801FCC08370000006 -:103160008AA00D0028038AA00C00827101200C00A7 -:103170000C808671AA781835403328340080AC80E2 -:1031800080AF2B00A0209B78000080AD0B00982022 -:10319000A653A8239828A02586A220000815D07041 -:1031A000B5C0D270002CB670002DBA701468FCC087 -:1031B0000780827886A2020004092129A07000807D -:1031C000A270B07498A40500A87006A30811A47397 -:1031D000B27386A210000409C625DE00CE000500E9 -:1031E000007005A0E01986A20200041938290C0815 -:1031F0005B3CA8191468FCC007808278912000808D -:103200001B786800B4685A789468D678DE78986835 -:10321000D278DA789120018008788DC00A7826016A -:10322000D600C600D07084A0002E9020CE00DE0014 -:103230002E0100295670BC683E7003700200002DFC -:103240004A7080AD090042703078BCD040019120B6 -:103250003D30D07084A03D30912000809020A0703F -:1032600005A0081105002184E80D4C72BC7000A275 -:1032700015A00408512786A2100060150C085B3CBD -:103280000419CC281468FCC0078082781B78680079 -:10329000B4685A789468D678DE789868D278DA7804 -:1032A00008788DC00A78A0700080A270B07490A4D5 -:1032B0000500A87006A20811A472B2720029567007 -:1032C000BC683E7003700200002D4A7080AD09009A -:1032D00042700500B46B9DA300205A7B1468FCC0AB -:1032E00007808278946BD67BDE7B986ED27EDA7E06 -:1032F0001B78680000295670027208788DC00A7821 -:10330000002305A67001D07084A0002E86A00026A0 -:1033100018110920000010000920010084A20F00EC -:10332000330080AD09004270002D4A7005009C29D1 -:1033300008420842F64108429C299C299C290C0815 -:103340007525087884A0FDFF0A78F60079200047EB -:10335000AC78FE0084D0C001607186A10100040930 -:10336000612A86A10700700186A1050058117870B6 -:1033700068201B68040017680000206884A0FF0014 -:103380009DC0226863700000A3700000A470AE703E -:10339000B2700C08AE26560111200400607186A19F -:1033A0000100580186A1070018111F7005001000C8 -:1033B0001F700100D070C5C0D27001200A470420E0 -:1033C00084A0FF0086A0180030011870167005A0B8 -:1033D0001011A370010066000C084E3FA9201000D8 -:1033E000392000000C088B3AB8A70001041FEF2910 -:1033F0006E00007002002C2A0A2A0A2A022A2C2AAD -:103400002C2A2C2A002A0C0875255C7005A038058A -:1034100006AD181100685E708000206884D04811E5 -:10342000146F0C08953B0860D4C00A600C08C737BD -:103430002000587060200068026084A6005F1E684B -:103440001868FCD008011A6A176800002B68000091 -:10345000206884A0FF009DC022680C08BF1D1120B9 -:103460000400C874A0A40001B104A0AE1700990420 -:10347000A9200101C87479042084041F382AC0706F -:10348000602021200200A92000011061FF81980125 -:10349000186016000600112002470C2202A112201B -:1034A0000E001E0002A138031260281111200447EB -:1034B0000422A5C012201B600000E0AC1000041F15 -:1034C000422A2184001D5E01637000000370000029 -:1034D0004B70000005004600042405A0A8016820E8 -:1034E000006806001A6A176800002B680000B468BC -:1034F00084A0005F1E68206884A0FF009DC0226831 -:103500000C08BF1D0E00480C4E00232000000500D3 -:1035100082A2030010030C087525002302008F2AE5 -:103520000C2B1A2B82A2020010010C08752560706A -:10353000637000007F7000002200D077C5C7D2778B -:103540000200A62AA62AA82AE02AFB37A62AE02AF1 -:10355000A62A0C08752570770C088B3A7077BCA7E3 -:10356000008F0C08953B186005A02805FCD71811A2 -:103570002120C08D10002120D08E092005001120AF -:1035800010000C08342BB8015601A9200101FCD70A -:1035900018112120C08C10002120D08D4600092058 -:1035A0000500112010000C08342B4E001801208457 -:1035B000041FCB2A5E01388784A71F0090190408D6 -:1035C000C9250408C92570770C08953B186005A02B -:1035D0002005FCD718112120C08D10002120D08E8D -:1035E00009200500112020000C08342BB0015601E1 -:1035F000A9200101FCD718112120C08C1000212026 -:10360000D08D4600092005001120200081044E00C5 -:1036100018012084041FFE2A5E010408C925002227 -:103620000200112B132B132B0C087525637000005F -:10363000D070C5C0D2700408C92500220200212B19 -:10364000132B1F2B0C0875250C084E3F007086A00D -:103650000200041980370C08E137086084A0EFFBF2 -:103660000A600C087237040980370408C92504244D -:1036700005A090056820042D0600146806A718010F -:10368000202D0E00A80C0E0022201A6917680000D9 -:103690002B680000B46884A0005F1E68206884A0C6 -:1036A000FF0005A222680C08BF1D212002471C2430 -:1036B0001983222310600180126028112120044701 -:1036C0000424A5C02220086084A0EFF90A600C0839 -:1036D000CA260C08E137050085A00100E00C002394 -:1036E0000200732B712BEE2B0C087525E47805A0D6 -:1036F000B01708328CA1000818010401C62510007B -:103700000403C625082084A03000101104084D329F -:10371000EC7884A00300D00D8478FCD0181184A12B -:103720000700900084A1070086A004001811012062 -:103730000000500084A1070086A00500180184A1A4 -:1037400007001000012001000200D12BDA2BC72B4B -:10375000AA2B4F3C4F3CAA2BE42B0C08752500707C -:1037600086A004009011607086A002003011112024 -:103770000200192000000408852A607086A0060057 -:10378000B00D607086A00400900DE4790120030064 -:1037900004083B2F1868FCD010011B681D000C08A2 -:1037A000613A1B786E0005001868FCD010011B6898 -:1037B0001D000C08613A04082D3C1868FCD010016B -:1037C0001B681D000C08613A1B78FA000500186898 -:1037D000FCD010011B681D000C08613A1B78CB005F -:1037E000050084A50F00C01100700200C925FB2B45 -:1037F000FD2B803780378037FB2BFB2B0C08752582 -:103800000C08E137086084A0EFFB0A600C087237EF -:10381000040980370408C925E47805A0041BAC2BF3 -:1038200008328CA1000818010401AC2B100004031D -:10383000AC2B082084A0300018111B78680005000C -:10384000EC7884A00300C80D8478FCD0181184A102 -:103850000700900084A1070086A004001811012031 -:103860000000500084A1070086A00500180184A173 -:1038700007001000012001000200492C4D2C442CAF -:10388000422C4F3C4F3C422C493C0C0875250C08FF -:10389000673A1B786E0005000C08673A04082D3C57 -:1038A0000C08673A1B78FA0005000C08673A1B7889 -:1038B000CB000500002302005E2C5C2C602C0C0861 -:1038C0007525040805341B681600A3780000E47908 -:1038D00084A1300004090534EC7884A003000409B5 -:1038E000053484A10001980D8478FCD0181184A1BE -:1038F0000700900084A1070086A004001811012091 -:103900000000500084A1070086A00500180184A1D2 -:1039100007001000012001000200922C4D2CC72B43 -:103920000B3C4F3C4F3C0B3C493C0C08173C050002 -:1039300082A2050010030C0875259878402000230A -:103940000200A12CCB2ED52E00220200BD2CAA2CC9 -:10395000BD2CA82CAD2E0C0875259B781800A878D6 -:10396000102084A0FF0082A02000040A303A8AA020 -:103970000400041A303A0200303A303A303AE4395E -:103980009B781800A87984A1800048010408303A87 -:10399000007005A0D81D112004000408B73584A1CB -:1039A000FF008AA01000041A303A0200E52CE32C34 -:1039B000F72CFB2CA92D303A303AAB2D303A303A67 -:1039C000A92EA92E303A303A303AAB2E0C08752584 -:1039D000E4D6400101200003008000803A781B7883 -:1039E000C70005001868FCD018011B681D00900C6A -:1039F00004080B3C1B681D0004085B3A206922691F -:103A000084A6001804194C2D206884D00419542D64 -:103A1000186886A0080010111B680000D4D668053D -:103A2000BCD6580583700000186884A03F008AA0A7 -:103A30000D0018078AA00C00827101200C000C8078 -:103A400086719B786100AA785601360146011600FE -:103A500008328CA100061801A1202B021000A12021 -:103A60002B011E009B7800000080AC8080AD0B0015 -:103A70009820A6534E013E015E01386005A050110A -:103A80001C6884A00E0004095B3A0C086D3A2B7880 -:103A90000830100001803A601B7871000500E4D600 -:103AA00030011B78830005001B788300050084A685 -:103AB0006000D00DDCD6C00DFCD6A001FCC65A7E3D -:103AC000B66EDC7AD879D078078084A07F0008A110 -:103AD00091A20000986B002102A3B268946B0022AF -:103AE00003A3AE68F4D61801F4C65A7EB66E007011 -:103AF00086A00300481106000C084E3F0C0808423F -:103B00000E001B788000050006A00C08E842B06A91 -:103B1000AC69986C946B002205A12001002222A4BC -:103B200000211BA3AA6CD27CDA7CA66BD67BDE7B41 -:103B3000002305A43011F5C65A7EB66E1B788000AE -:103B400005001B788000002215A118110C080842FE -:103B500005000C08354205000C08752504083F2EA9 -:103B6000C6005470602020698CA1FFEC22690060BF -:103B700084A0DFCF02600C08173906A0402038204F -:103B80000C08BF390408332EC60054706020482C3E -:103B9000A87A94A2FF0086A20400D8112069E4D17B -:103BA000701139200000412000003120000006A0E3 -:103BB00010200C081A390C08BF390408332E8CA1C8 -:103BC000FFEC226904618CA1DDFF06610060ACC0DE -:103BD000026086A20300D001046184A110004805A0 -:103BE0000C08913B0C089A39FF881805CE009B7889 -:103BF00060000028AA78587E95C65A7ED4D618113F -:103C00001B786E0005001B78820005002069CCD16E -:103C100030018CA1FFFD22690060ECC002603920F8 -:103C20000000412000003120000006A010200C08F8 -:103C3000BF3986A201005801046184A10800B001C7 -:103C40000C08913B0C08B838FF888019780020696F -:103C5000C4D130018CA1FFFE22690060E4C0026083 -:103C60003120000006A010200C081A39CE00587E22 -:103C7000D4D618111B78710005001B78830005004D -:103C80000408573A08289B78800019208000A878FB -:103C900094A0FF0086A20100B811002302A186A013 -:103CA00001000409AD2DA87CA4A4FF0080A402009B -:103CB00000A3182002A1040AC12D0409C12DA824C3 -:103CC000A87A041F5D2E180C84A2F00082A02000A8 -:103CD000B806002282A021009816A87A18831883BB -:103CE000002102A3A00A86A2230050091C6884A018 -:103CF000F1FF1E68587E84A6F1FFA5C030205A7ED1 -:103D00000860A5C00A60A07805A00409342EA82088 -:103D100098799B786000AA78112080009A79A87819 -:103D200098799A7AAA78987A041F8B2E95C65A7E2B -:103D3000D4D618111B786E0005001B788200050090 -:103D40001883002102A3040A442E84A280000419CF -:103D50005B3AA07805A0C80804085B3A0408303A2A -:103D600054704DA09B781800A87884A0FF008EA006 -:103D7000010010010C087525A87A94A2FF004B7869 -:103D80000800A87884A0FF008AA00500041A303A31 -:103D90000200303A2F38303A4A39593D82A20000A9 -:103DA00010110C0875250C08613A1B78820005007B -:103DB00082A2030010110C087525FCD4D01160708C -:103DC00005A010010C087525146F7277BCA7008F31 -:103DD0000C08953B086085A021000A60388784A7FD -:103DE0001F00B01D0C08643A637002001F700900C8 -:103DF00010000C08703A1B788200050082A20400B3 -:103E000010030C08752500230200052F9B30D730C6 -:103E100086A2030098050072D87CDC7DD07FD0712B -:103E2000B4D12805BCD11815012001470420C4D005 -:103E3000F011687884A0FF00D01182A20200B812AD -:103E4000D6003B7800831B785900B8706DA0B46829 -:103E50005A789468D678DE789868D278DA78B4C1DF -:103E6000D27103703000DE000120000058003B7862 -:103E700000131B7857000120000020000072D87C3E -:103E8000DC7DD07F4670A068ECD0180108608DC042 -:103E90000A6084A20F0002007C30562F532FA731F6 -:103EA0003232C925512F512F0C0875250860D4C016 -:103EB0000A60E4D62001447086A01400E8110C08C2 -:103EC0004E3F092000001868FCD00801447086A00D -:103ED00014006801186886A0080004193E3058785C -:103EE0009CD004093E302068ACD004093E301B68E9 -:103EF000140009200200A80468788CA0FF0088053F -:103F000086A1080058110860A4C00A600C08723726 -:103F100040050C08E1370C084E3F600086A12800E0 -:103F20000015186005A0780D0180680D0180580DFE -:103F30001E60480C206884D00409C92584C022680A -:103F40000C08BF265870C600602000680260CE00D2 -:103F50000460026805A0002D0811026006600408D4 -:103F6000C9251600FF81F015007086A03000D0052D -:103F7000D071BCD1B815B4D1E8115C7005A0901512 -:103F8000A07086A001007005037000004600560076 -:103F900076006600C600D6000C08F125DE00CE00D3 -:103FA0006E007E005E004E00D071B4D1D811037057 -:103FB0004000C0000C085B3CA8111B786800D600CC -:103FC000B8706DA0B4685A789468D678DE7898682E -:103FD000D278DA78B4C1D2710370300008788DC01D -:103FE0000A78DE000C08FF301E00FF8104093E3015 -:103FF00084A600DF1E682B680000146F86A10200F3 -:1040000004193F30186886A0140030110820E4D647 -:10401000180168788CA0FF000C087A3A0C08CA26B0 -:104020002068DCD07815178794A20F0013821382C2 -:10403000138284B20006180190A2C04B100090A217 -:10404000404C90A200001C22C4D370012068E4D030 -:10405000280184A0FFEF2268ACC31223108204223F -:1040600085A0380012201182D4D33801A068C4D0B2 -:1040700020110C0867310408C92508608DC00A604A -:1040800008002A6916691868FCD0100144701A6883 -:104090008CA600DF1E691064FF84680109200247B6 -:1040A000042101800A202184126428112120044760 -:1040B0000424A5C02220186005A0180101801A6000 -:1040C00018110860A4C00A60206884D0301100680C -:1040D00005A008110260066020005870602000688A -:1040E00002606120004787680301082D6B200000F3 -:1040F000686005A06A611001022D08006E610072FF -:1041000086A23000580186A240000419C925037018 -:10411000020048706820C468602005000370020037 -:10412000B8706DA0BC683E70B47065A0C068567071 -:10413000002D4A7080AD09004270050082A2040083 -:1041400010020C08752500220200A630B530C130DF -:10415000B53086A50013600186A50083901D03700D -:104160000000186001801A60086084A0EFFB0A60FC -:10417000007086A0050028010C08613A1B788200B7 -:1041800005001B788300050090780780018084A0DB -:10419000070080A018009A78A8798CA1FF0086A15A -:1041A0000300280186A1000010010408303A1B78A2 -:1041B00083000500206895C02268FF8218110C0852 -:1041C000613A3000118210010C0875250C08703A14 -:1041D0001B78820005000C086E3C307884A0C0007B -:1041E0007011160008328CA100081E00180104018D -:1041F000FC3010000403FC301A7906A0050085A0ED -:104200000100050084A6600030112F6800003368AB -:10421000000004086631DCD69811B468DCD0801147 -:104220009869946A2E69326A447005A030110022A0 -:1042300005A104094E3F4770150004084E3F0500D4 -:10424000ACD6F001F4D630012F68000033680000CE -:1042500004084E3FB46884A0004035A6F4D6A01DE3 -:10426000447005A0101147701500DCD62811B46801 -:10427000DCD01001A86CA46D2E6C326D04084E3F8A -:10428000F4D630012F6800003368000004084E3F68 -:10429000B46884A0004835A6F4D6A01D447005A0DB -:1042A000101147701500082410250027078084A0EE -:1042B0007F0008A191A200002E69326A002105A2A8 -:1042C000101104084E3F007086A00600100104087B -:1042D0004E3F050046690860CDC0CCD308018DC0B3 -:1042E0000A6018683A681B6806008F6800009368C7 -:1042F0000000306A2C693E6A42692F680300336807 -:10430000000037682000976800009B68200000705C -:104310000200C925963190318E318E318E318E3129 -:104320008E310C087525206884D018110C08C73709 -:1043300030005870502C602000680260602AA0AEE7 -:104340001700042405A010012020D80C222D6B207A -:10435000000005000C08CD370C08E1370860CCC020 -:104360000A602B6800009B780E00146F38691A6988 -:10437000446916690920000086AE404710010920F3 -:1043800001000C081F43DCD6C8011C69EDC11E6981 -:10439000286882A00E009002486884A00F0086A0C2 -:1043A0000B0060115C6886A04700401101200147A6 -:1043B0000420ACD0181100270C089E241868FCD0EB -:1043C00040011B68000068788CA0FF0010011B688A -:1043D0001E00A0AE1700006822203C6A4069326AC5 -:1043E0002E69C06860200060A4D0800541202100B3 -:1043F0004920050051202000D600F6005601460154 -:10440000792000470C08B21B4E015E01FE00C87007 -:10441000102009200101260004226DA0400114682B -:1044200006A710010068C80C2068D5C022682E00BD -:1044300010820981801DDE00637003007B70000024 -:1044400072777F700F00D071C4C1D271186886A0D6 -:1044500002003811176800002B6800001C68ECC0CF -:104460001E680C08BF1D0408C925D87CDC7DD07FE0 -:104470000C08FF302B6800009B780E00146F0C08AE -:10448000723C8CA0FF0016691868FCD010014470C3 -:104490001A688CA600DF1E69637000000408C92535 -:1044A000007005A010110408C92506A00C084E3F95 -:1044B0002069ACD110111B6814008CA600DF1E69A6 -:1044C0002B680000206884A0FF00226800700200B2 -:1044D000C9256F326F327232723272326D326D3282 -:1044E0000C087525186804083B2F0860A4C00A60F2 -:1044F0001768000004089537002302007E328032DE -:10450000CE320C087525FCD604195B2D00700DA069 -:104510000200C92590329032BA329032CB328E32BC -:104520008E320C08752584A66000380586A06000D0 -:104530001015ACC6F4C6EDC65A7EB66E1C68ACC08B -:104540001E6886A1020048010C084E3FAC69B068A5 -:1045500015A118010C08354210000C0808421B7800 -:104560008300D071B4D10419C625A07086A00100C3 -:1045700004190D260500ECD6F0091868FCD070016E -:10458000F4D630111B6815001B7883000408C6257B -:104590001B6807002F680000336800000C08173CF8 -:1045A00005000C08752500230200D732F93251337B -:1045B0000C08752500700200E132E332EA32E13284 -:1045C000E132E132E132E1320C087525AC69B068C4 -:1045D00015A118010C08354210000C0808421C688F -:1045E000B4C01E68D070B4D00419C625A07086A0CF -:1045F000010004190D260500FCD604194133007092 -:104600000DA00200C9250F33093339330F333E3370 -:10461000073307330C0875259468D678DE789868D8 -:10462000D278DA7884A66000380586A0600010157C -:10463000B4A6BFBFEDC65A7EB66E86A10200480181 -:104640000C084E3FAC69B06815A118010C08354242 -:1046500010000C0808421B7883001C68B4C01E6858 -:10466000D071B4D10419C625A07086A00100041928 -:104670000D260500ECD6F0091868FCD010011B6867 -:1046800007001B78FB000500FCC65A7EDC7AD8794F -:10469000986B002102A3B268946B002203A3AE685A -:1046A000D2791B7883000500DCD630012B780930E5 -:1046B0001B7883000408C6258478ACC08678E4782B -:1046C00084A00800501184A400020801F5C6DDC6CC -:1046D0005A7E1B7883000408C625206895C022688E -:1046E0000C08023CDDC60C08613A1B788200040805 -:1046F000C625002302007B337D337F330C087525EC -:1047000004085B3A987DD4D6A815E479ACD1300181 -:10471000EC7884A0030010012B7809309B786000AE -:10472000AB78000084A6FBFF5A789A7DE479ACD17F -:104730002001EC7884A0030020110120140004085B -:104740003B2F8478FCD0181184A10700900084A12D -:10475000070086A00400181101200000500084A169 -:10476000070086A00500180184A1070010000120A1 -:104770000100C204907A94A207009B786000A87997 -:10478000FF8168059B788000A87B84A30100D0117D -:10479000A87BA87B86A3040018110920DFFF58001E -:1047A00086A3010018110920F7FF280086A3030043 -:1047B00048110920EFFFC60054706020046004A176 -:1047C0000660CE009B786000AB78000084A6FBFFFB -:1047D0005A782B78093020698CA1FFEC22699A7DE8 -:1047E00004080B3CD12BDA2BF933FF33F733F733C3 -:1047F0000B3C0B3C0C08752520698CA1FFFC226941 -:104800000408113C20698CA1FFFC226904080B3CC0 -:10481000E47984A130002001EC7884A003007015B5 -:10482000007086A004009011607086A00200301114 -:1048300011200200192000000408852A607086A05B -:104840000600B00D607086A00400900D007086A078 -:1048500000000409C625206984A120042801D4C1D0 -:104860002269186804083B2F18688EA002002001F6 -:10487000FDC01A680120140004083B2F8478FCD086 -:10488000181184A10700900084A1070086A00400ED -:10489000181101200000500084A1070086A0050027 -:1048A000180184A1070010000120010002000B3C48 -:1048B0000B3C5C340B3C4F3C4F3C0B3C0B3CBCD6A4 -:1048C00070058071FF81580582A10D001813837057 -:1048D0000000280082A10C00827009200C009B7847 -:1048E0006100AA795601360146018470148110A234 -:1048F000867280A00B0000AD982084B200061801DB -:10490000A1202B021000A1202B019B780000088120 -:10491000AC81A6534E013E015E010408113CD4D681 -:104920000419CF34206884D00409113C8CA660009F -:1049300084A66000200186A060000811F5C194C122 -:104940005A79B6699B786000AB7800009B7861006B -:104950001868FDC01A68AA7808800C810409F63727 -:104960008CA1F8000419F6375601360146011600ED -:10497000A1202B0108328CA100061001A1202B02DE -:104980001E009B7800000080AC8080AD0B0098205A -:10499000A6534E013E015E011468FCC00780827878 -:1049A0000408113C1868FCD010011B6808000C08B2 -:1049B000613A1B78ED00050000230200E0349D35CC -:1049C000DE340C087525D87CDC7DD07FFF8228156D -:1049D000007286A203000409092FD071BCD1F8111E -:1049E000B4D1E801012001470420C4D0C011D60091 -:1049F0003B7800881B785900B8706DA0B468A5C0DA -:104A00005A789468D678DE789868D278DA78B4C123 -:104A1000D27103703000DE003000007220003B785D -:104A200000181B78570084A20F0002008835453516 -:104A30001D35382F1B3588351B351B350C08752562 -:104A40001C68ECD0180108608DC00A60206985C11F -:104A500022690068066005A0081102600860D4C0E1 -:104A60000A601C6884A00E002011C87188A1000192 -:104A700028003070BA683C71C87008A1042102682F -:104A80000A2D5A71DCD62011FCC6B66E0408883592 -:104A9000B66E84A66000201184A6FF7FB668D80495 -:104AA000DCD6501184A6FF7FB6689468A668986823 -:104AB000AA680C084E3F7804ACD6400106A00C084A -:104AC0004E3F08241025AA69A66A6800082410250C -:104AD0000027078084A07F0008A191A20000AA6996 -:104AE000A66A0C084E3FFCD6B00184A6FF7FB668CC -:104AF00010250824ACD638110027078084A07F0039 -:104B000008A191A20000986B002102A3B268946BE7 -:104B1000002203A3AE68007086A030000419C925E6 -:104B200003700200B8706DA0BC683E70B47065A0E0 -:104B3000C0685670002D4A7080AD090042700500B3 -:104B400086A50088481103700000186001801A6073 -:104B5000086084A0EFFB0A6004085B3A4370000021 -:104B600082A2060010030C08752500230200B73549 -:104B7000C835D23500220200BF355B3AC135BF359A -:104B8000033651360C087525807A94A2000F0C0864 -:104B9000A5360408303AC10002005B3AD035D03562 -:104BA0000336D0355B3A0C08752571000200DC3500 -:104BB000DA35DA35DC35DA35DC350C0875250C08E4 -:104BC000703A1B7882000500007086A00200501128 -:104BD0000C08E13710000C084E3F086084A0EFFB82 -:104BE0000A602000007086A00300A80D0370050075 -:104BF0000120E08E8EAE404710010120128F682008 -:104C00004A7080AD0900427000220500007086A045 -:104C100002005811D070B5C0D270002CB670002DB3 -:104C2000BA7038000C084E3F2000007086A00300C8 -:104C3000C80D03700100807A94A2000F9B781800C1 -:104C4000A87C84A41F0015A26920C08D84B2000630 -:104C50001811FDC26920D08E042D082D5A716DA047 -:104C60002801146806A220010068B80C0C08A536BB -:104C7000B46E5A7E206984A1000C0409CB366070A2 -:104C800086A006002811707006A2101162707A705A -:104C90001B680500ADC11B680500ADC1D4C1226908 -:104CA0000C08673A0408CB36007286A2020058113D -:104CB000D070B5C0D270002CB670002DBA70300024 -:104CC0000C084E3F180086A20300D00D03700100AF -:104CD000807A94A2000F9B781800A87C84A41F00FF -:104CE00015A286AE40470801FDC2A879A8798CA11B -:104CF000FF001821C87068A1042D082D5A716DA0FD -:104D00002801146806A218010068B80C0904B46EE2 -:104D1000206984A1000C0409CB36DCD078016070D6 -:104D200086A004004011707006A22811747006A3BA -:104D3000101162707A700C086D3A80041B680500CF -:104D4000ADC1D4C122690C08673A7B700000300401 -:104D50000370050084B2000618010120E08E1000E7 -:104D60000120128F68204A705601A92032000320CA -:104D700000000080041FB4365E0184B200061001FA -:104D8000FCC20800FDC2166A80AD09004270B76817 -:104D9000000723680008276803000500ECC6ACA6DE -:104DA000600004091237986B946CAC69B06805A177 -:104DB000E011D27BDA7BD67CDE7C86A56000C8055C -:104DC000F4D60811EDC6B4A6FFB75A7E09208300B9 -:104DD0009CD62801092082001920000020231A797E -:104DE000ECD688050C0808427004B0681AA30021AC -:104DF00023A4002405A3F801D27BDA7BD67CDE7CD9 -:104E0000B068F4D60811EDC6F4C65A7E11208300AE -:104E10009CD62801112082001920000020231A7A34 -:104E2000ECD688010C0835427000192000002023C0 -:104E30001000B4A6FFB75A7E092083009CD610014B -:104E4000092082001A79C0685670002D4A70C46823 -:104E50006020D071012001470420C4D0C815D4704F -:104E60002DA0B801BCD14805807A94A2000FD8705B -:104E700006A21801E07804A55815D670BCC1D271FD -:104E80003804312001002C85180233861082D80C9A -:104E90000500E07D94A500FF3001112008002F855A -:104EA000810C37860800690C1782807884A0000F77 -:104EB00006A27001DA72D6765800807A94A2000FAA -:104EC000D87036A2C00DE07834A5A80DBDC1D2714E -:104ED000B4D10419C625002305A40409C625A07071 -:104EE00086A0010004190D260500206005A05001D0 -:104EF00001802260086085A008000A600F70000130 -:104F00002C702660050006A00C084E3F007086A09D -:104F100002002001607086A0050050112B6800007F -:104F2000176800001B680100236840001F6800012B -:104F3000007084A00F000200C925A637A337C3372D -:104F4000AF37C925A137A1370C08752549041104CD -:104F50002800310458706020006802600C08BF1DF2 -:104F60000408C9256070637000007F7000000200B3 -:104F7000BF37BF37BD37BD37BD37BF37BD37BF3789 -:104F800004089A2A637000000408C9251B68000001 -:104F90000408A731006805A008110260066005003A -:104FA0001064FF84680109200247042101800A205F -:104FB000218412642811212004470424A5C0222042 -:104FC0000860A4C00A600500186005A010010180F7 -:104FD0001A6005000C086E3C1B68180090040C0851 -:104FE0006E3C1B68190068040C086E3C1B681A00B4 -:104FF00040040C086E3C1B680300180470770C0812 -:10500000953B74718CA1FF00103294A20006180128 -:10501000E8A1C08C1000E8A1D08D042D082D6820D7 -:1050200005A018117A700408C9251468707206A2C8 -:1050300010010068980C00680A201B6805007B704E -:1050400000000C08CD37206884D010110C08C73739 -:105050000C08E1371F680000236820000C08BF1D02 -:105060000408C92582A203000419353AA87DACA51D -:10507000FF00A87EB4A6FF002069BDC12269C4D18B -:10508000B005C4C12269B4A6FF00300582A618008D -:10509000180210013120180086A610000811308671 -:1050A0002B852B85412000000C08EE3A18010C08D6 -:1050B0001A39A0000C08BA3A0C0817392069C5C182 -:1050C0002269587E95C65A7ED4D618111B786E0078 -:1050D00005001B78820005000C081739587ED4D6CD -:1050E00018111B78710005001B7883000500C600AD -:1050F000547060200061E4D198050862178294A280 -:10510000FF0082A2180018021001112018000026CA -:1051100002A20812302286A610000811308608620A -:1051200094A2FF00EC78E4D0300182A20A00401281 -:1051300011200A00280082A20C00101211200C007D -:10514000002202A5081228220C08BE3A2B852B85C6 -:10515000412000000C08EE3A18010C081A39200012 -:105160000C08BA3A0C081739587895C05A78CE000E -:105170001B7882000500C60060290060E4D0881119 -:10518000B4D05011106084A00F00301104618CA1C4 -:10519000F5FF0661CE000500112032001920000045 -:1051A000F000A068CCD0C01D086294A2FF00EC788B -:1051B000E4D0300182A20B00181211200A0028004E -:1051C00082A20C00101211200C0008631F839CA304 -:1051D000FF0082A318001802100119201800AB78F4 -:1051E0000100AB780300AB780100AA7AAA7BC0A8C3 -:1051F00005002068C5C022680C087A3ACE00050078 -:10520000C600602904618CA1F5FF066111203200FF -:10521000192000000000AB780100AB780300AB78E8 -:105220000100AA7AAA7BC0A805002068C5C0226830 -:10523000CE00050006A030201020C6005471602169 -:105240001820082084A0E0FF35A6867E18609A7892 -:10525000AE7E1266A47884A070778CA10F0005A1A1 -:10526000292005472C25CCD54001A4D3100185A0C9 -:105270000008FCD3100185A08080A67816608A788B -:10528000B4A61F0037860482048005A60E60046061 -:1052900084A0D5FF0660CE00050082A2020004199A -:1052A0003F3AA87A2069BDC12269CCD16805CCC13A -:1052B000226994A2FF0082A20200041A303A0C086C -:1052C000C1390C08173980A901000C200C08913B4A -:1052D0000C08B838FF8878019B7860000028AA780D -:1052E000587E95C65A7ED4D618111B786E000500DC -:1052F0001B7882000500587ED4D618111B787100E7 -:1053000005001B788300050082A20200181284A207 -:1053100001004001547188A100000C21ECD1101152 -:10532000112000000C08AC3A79040C0817395878A1 -:1053300095C05A781B7882000500C60026006029B7 -:10534000006011200100ECD05811BCD0381114605D -:10535000B4D02011A4C1066106A08800112000006D -:10536000AB780100AB780200AB780300AA7AC0A842 -:1053700004000C087A3A206885A0000222682E00FA -:10538000CE000500078815A7C6000920000054704C -:105390006020FF82100109204000186080A00200F8 -:1053A0009A78A47884A09FFF05A1ECC0B4D008111E -:1053B000EDC00061F4D1100185A02000A678166030 -:1053C0008A78046084A0EFFF0660CE000500060026 -:1053D000007086A0030010010E0010000E0098045B -:1053E000ACD68805887884A040006805B87B078320 -:1053F00084A07F001815078284A0FF000409573A93 -:105400009AA00400041A573AF4D6D011D879DC7A5D -:1054100008A191A20000D279DA79D67ADE7A0C0856 -:10542000E8421B78800084B20006180101200000C9 -:105430001000012001000C089A4105000C08752598 -:105440001B78800005001B788300050039200000D0 -:10545000412000003120000006A010200C081A395D -:105460000C08BF39587E0C08733A1B78820005007F -:10547000D10C2068C4C02268C600547060200C089B -:105480004439B000810C2068CCC02268C60054703A -:1054900060200C08DE396000310C206884A0FFEC2D -:1054A0002268C60054706020046084A0C5FF0660B6 -:1054B000CE00050049001B78820005002768020025 -:1054C00049001B78820005000120050088000120AA -:1054D0000C0070002068D5C0226801200600400042 -:1054E00001200D0028000120090010000120070004 -:1054F0009B787E00AA789DC65A7ED070B4D0680191 -:10550000B4C0D270C600B47065A0086084A0EFFB80 -:105510000A60186001801A60CE00050076003F879F -:10552000BCA70F003B873B870387E0A0C04B8EAE34 -:1055300040471001E0A0404CB8A720009A7FA47912 -:1055400084A1E07FAE781260A47984A13F77A67829 -:105550001660046085A0380006607E0005009B7818 -:105560008000AB780100AB780200AB780300AA7A28 -:105570009B786000AB7804000008312000002920EF -:1055800032009B788000AB780100AB780300AB78E9 -:105590000100AA7DAA7E9B786000AB780500040814 -:1055A0007A3A5601078084A0FF000380038080A020 -:1055B00020009A78A4798CA1E0FF21207A3B192061 -:1055C0001100A9200E0011203200042484A0E0FF65 -:1055D00006A128012084002310A2041FE23A5E01E4 -:1055E000050056010408303B2120883BA920090012 -:1055F0001120290082A5280050052084A99511209A -:10560000330082A5330018062084A99519200A00CA -:1056100011206500002202A5D0022084002310A2E0 -:10562000041F073B5E01880021207A3B19201100EE -:10563000A9200E0011203300002202A54002208480 -:10564000002310A2041F193B5E0106A00500118271 -:105650005E0182A564002012087885A070000A7897 -:10566000042405A0050086A80200E8012120663B6D -:10567000A9200D001120280082A52800480D2084B3 -:105680001920190011203300002202A5000E2084E9 -:10569000002310A2041F413B5E011120840182A55A -:1056A0008501B00A90082120753BA9200300112034 -:1056B000240086A52400600920841120280086A5E6 -:1056C0002800300920841920190011203300040813 -:1056D000193B21100222033404460558066A077C50 -:1056E000104612461258125A146A146C146E177E21 -:1056F000219002B004E210E210E2091202300232FC -:105700000342034404540456056605680678067A85 -:10571000070C070C070EE1100A330558055A066AF4 -:10572000066C077C077E000E9B78800046A0050073 -:1057300084A7000F0B8084A71F00038003800380D1 -:10574000038005A1FCD71801E0A0C06C1000E0A008 -:10575000C04C0500E600F60084D038017920000135 -:105760000920804771208047300009204047792078 -:1057700000027120404791200080042184A00F0086 -:105780000200C83BC83BC83BC83BC83BC83BC63B04 -:10579000C63B0C087525B469F5C18CA19FFFB6699D -:1057A00005A08005587884A09FFF85A000605A78E6 -:1057B000287886A0141830154B780400487884A007 -:1057C0000400E01D4B780800487884A00800E01D24 -:1057D0003078BCD0B81184B2000818010401FF3B36 -:1057E00010000403FF3BE47984A130005801EC78F9 -:1057F00084A0030038011C68ACD01011D90010003F -:105800001B78FB00FE00EE0005000120014704208C -:10581000ACD0181114680C089E2405001B78830076 -:1058200005001B78820005001B78710005001B78BD -:105830006E000500092019470C2186A100005001C7 -:1058400086A1010050011F700B00637001001B78DE -:10585000540005001B78F30005001F700A000500C6 -:10586000092019470C2186A10000680186A10100CA -:1058700038011F700B00637001001B785400050095 -:105880001F700A0005001B78F20005001B78FB0062 -:1058900005001B78FA0005001B78CC0005001B787A -:1058A000CB0005001868FCD010011B681D001F709C -:1058B0000B00637001001B7854000500307884A051 -:1058C000C000701108788CC00A7800E000E000E0A9 -:1058D00000E0EC7884A02100180108788DC00A78D7 -:1058E000050008788DC00A780500307884A0400053 -:1058F000E01D84B2000818010411803C100004135C -:10590000803CAC780500087884A0FDFF0A7800E0B0 -:1059100000E000E000E0EC7884A02100400184B2C7 -:105920000008180104118F3C10000413923CAC785D -:105930000600087885A002000A780E00050084A7FA -:10594000010004194D3284A770004001C600602D8B -:10595000682F0C089024782D682CCE0084A70800AE -:1059600048014B780800EC7884A0030004094D320C -:1059700004080B3C84A70400C801B87884A0008008 -:10598000A8014B780800EC7884A0030004094D328C -:10599000E47884A0070086A001004011C07885A6A5 -:1059A000004830205A7E1B78FB00050084A7800049 -:1059B00040018478FCD028010C08573A1B6822006B -:1059C00005001B680300587884A0005F1E682F68DC -:1059D0000000336800004B780800EC7884A00300D6 -:1059E0000409AC2B84B2000810010401C62504038D -:1059F000C625146B078384A00F00038003800380F7 -:105A0000FCD3180180A0404C100080A0C04B602047 -:105A100048205670602A0500C60060290060ACD09E -:105A20000409573DA068ACD1201184A0000E0409E0 -:105A3000553D086117818CA1FF001C632F83DCD0CA -:105A400010019DA30100CCD0C81184A5FF0038012E -:105A5000EC78E4D010011382B8002920000082A164 -:105A60000C009012EC78E4D0181109200C006000B2 -:105A700082A10B00481209200A00300009203200E0 -:105A80001120000029200000AB780100AB7806004F -:105A9000AB780400AA79AB780000AA7AAA7BAA7D29 -:105AA000C0A80800206885A0001022680C087A3A77 -:105AB00085A00100CE00050082A206000419493A23 -:105AC000A87DAC7E3786ACA5FF00B4A6FF00AC7FF6 -:105AD0004787BCA7FF00C4A8FF002069BDC1226999 -:105AE000E4D10409CB3D8CA1FFEC226982A702001E -:105AF000041A233AB4A6FF000409C83D82A6310067 -:105B0000041A233A82A50900040A233A82A8030052 -:105B1000041A233A86A80200D00186A800000419BE -:105B2000233A01200C00EC79E4D1100101200A0095 -:105B300002A590120C08233AC6006029046085A0D3 -:105B40001A0006600060ACC00260CE00050086A7A7 -:105B500000000409233A348682A618002802200196 -:105B6000312018000408193E86A61000081130865E -:105B70002B852B850C08EE3A0409233A0C081A39B8 -:105B80000C08BF39587ED4D618111B787100050057 -:105B90001B78830005000C081739900C86A80200BA -:105BA00008113486547188A100000C21ACD104097D -:105BB000233AECD120113920000041200000E4D12B -:105BC0002011312000004120000082A70200C812ED -:105BD0001C6284A2FF0006A710013920000005A660 -:105BE000900108611F819CA3FF00680102A30812B5 -:105BF0003023078805A786A00102600186A800005F -:105C0000680139200000412000003120000006A07A -:105C10001020700084A200FF0811402084A1FF0022 -:105C200002A5080128212B852B850C08EE3A580D7A -:105C30000C081A390C08BF399B788000AB7801003A -:105C4000AB780600AB780400AA7DAB780000AA7E92 -:105C5000AA7F0028AA789B786000AB7808002068AB -:105C6000E5C022680C087A3A587895C05A781B78B3 -:105C7000820005002000200000002000000020001D -:105C80000000200000002000000020000000200094 -:105C90000000200000002000000020000000200084 -:105CA0000000200000002000000020000000200074 -:105CB0000000200000002000620009001400140011 -:105CC00055984D9814001199FF98140014009000F5 -:105CD000E70000010204082080F8180017000F8474 -:105CE000C1D8140016000AA214000B300CA2140034 -:105CF00000251300002510001000100010001000F7 -:105D00001000100010001000100010001000100013 -:105D1000100000A206383988C420640850A8083052 -:105D2000C128189D01A20C30472861816A84008037 -:105D3000A48456183A8808A8E228CE9CF3A86408E0 -:105D40003EA80C3001A80830E128CE9CA22863713F -:105D500031A8212018A805A20C87DED8A064E06D28 -:105D6000C06FA467806C120205A23D882B881418AE -:105D70003B882770F28537A732A503F076857786B2 -:105D800013A83E8811A88228627114A80A2804A2C8 -:105D9000C064E06DA067C06F14183B8823707685DF -:105DA000778602A861783E886A20C128189D422023 -:105DB0000121CAA802290EA20BA807A2140003A25F -:105DC0000080A48572189A873C88E21F01F608A219 -:105DD0006E852171140004070830CE9C140002A2C5 -:105DE0000080A4850930A884E21944F86E853F88B4 -:105DF000E608F5A861F8EBA801F8140081F8160090 -:105E0000B285F0803295A2FAE21D1400328521F2AB -:105E10001400E21DA884E0D6E61F140008300080BC -:105E200049281110FCA80830008000A08120022819 -:105E30001110FCA889A80830A1203C281110FCA84A -:105E400009A217000C300080A485E21DC1DA1400FD -:105E5000100201A81400E0263A87A3FAF219E026FE -:105E6000F21814000BA214000DA206381002229D95 -:105E7000040706A265687E812A84C11D2388160056 -:105E800042600880FAA860812A84808121F008306D -:105E9000A884D7114270DD201100D5202288160079 -:105EA00000002601D07084A0004C04809020047271 -:105EB00008709CC005A2A0110C72FF822801FF8A05 -:105EC0007811007284D260110478CCD010010C08D3 -:105ED0005B4307700800037008002E0100200500D6 -:105EE000007084A0030002709CC684D088050871ED -:105EF00000E0087006A1D81D84A103000409CA3F70 -:105F000084A1E0010419CA3FF4D1881D84A10030A6 -:105F100086A00010600D112080010C7111823001EB -:105F20000870F4D0201D0C7006A1C00D077012007F -:105F3000087100E0087006A1D81D84A1030068055F -:105F400094D1B00DF4D148050770020080082804F0 -:105F50000871FCD130010C08D640FF8A0409543F77 -:105F6000B80C0C708CA0FF07E801047084D0780195 -:105F7000147005A048111070107306A3E01D0023D3 -:105F800005A0280102A1201E077010003000FF8A22 -:105F900048010C089A42E81DD8090C085C402E0103 -:105FA00000200500047208719CC10381181207705B -:105FB0000200C00C05A2881D0770080003700800CD -:105FC0000600012001470420CCD010010C085B43DF -:105FD0000E002E01002005002864FF840805702CA7 -:105FE0000470BCA00F00B8A71D403C27FB874811D8 -:105FF00010020C0875259C6075A09001880C392052 -:106000001240042768AE086830A60C6829A52184D0 -:1060100038013887042705A0A81D9C7075A0001DB5 -:1060200005000000050009000D0011001500190011 -:106030001D000000030009000F0015001B000000F8 -:10604000000012400F4000000000008000001240DD -:1060500000001A40174000000000000000001A4035 -:1060600000001540154000000000008000001540B1 -:1060700000001B401B4000000000000000001B400F -:10608000792000477120100007700A000770020095 -:1060900003700100092002007120500007700A00FF -:1060A00007700200037000000120FF010420FCD0F3 -:1060B00028110981180171202000800C050004704E -:1060C0000480041AB2400871087006A1E01D84A182 -:1060D000E00120010C080E410408D24007701200B4 -:1060E000192000000871087006A1E01D84A1E001DC -:1060F00020010C080E410408D2409CA10C3086A35C -:106100000420900186A30800C001047084D04811C7 -:106110000871087006A1E01D84A1030010010408A5 -:106120000E4186A30C20F0190072048230020C7319 -:1061300084A3FF0710010C0875250871087006A1DB -:10614000E01D84A1E00118010C080E4170040770E5 -:106150001200007084D048111073147005A3280138 -:106160000C7184A1FF0704195C400871087006A136 -:10617000E01D84A1E00118010C080E41B000077079 -:1061800012000770080004709CD0E81D08710870A8 -:1061900006A1E01D84A1E00118010C080E412800B1 -:1061A0000770120008710381880E03700800050053 -:1061B000087184A1E001A815087184A1E001881587 -:1061C00084A107000200EA40F840E840F840E840B7 -:1061D0004841E84046410C087525047084A0100031 -:1061E0008DC00670FF8A18114920000005000C08B8 -:1061F0009A42E81D0500047084A010008DC006704E -:10620000047084D040110871087006A1E01D84A1BB -:10621000030008013000FF8A18010C089A42E81DAB -:106220000500077012000871041D114191200060E3 -:10623000041D1541912000600770120007700800CE -:1062400004709CD0E81D077012000871FCD1D81DA5 -:1062500003700000007005A03011047005A0181133 -:106260000C7005A00801400C4920000084B2000217 -:106270001801012000001000012001000C08A73BBC -:106280001B6802005120000005000C0875250C0851 -:1062900075250C088741107214710C709CA0FF07C3 -:1062A000002800A311A289A10000A1040427582CF2 -:1062B00060AC0863002222A30C6300211BA300240E -:1062C00005A340013812128410820A8389A10000BC -:1062D000602B580C602B078A060004609CD01801C4 -:1062E000BAA717401000BAA70F400E003DA7002C18 -:1062F00086688A6F926C8E6B0871087006A1E01D2B -:1063000084A1E00110010C080E41077012000C0876 -:106310005C400500508A3987042704A0681100609A -:1063200064A00811602D046084A00F0080A02D409F -:106330003C20FB870C09752505002601D600D0708E -:1063400084A0004C04809020DE008468602088686F -:106350008C6B906C5780D4AAFF0084A0FF000600CD -:10636000046884A008000E001801B8A017401000AF -:10637000B8A00F4084B200021001207E0800247EE5 -:10638000B5A60C001C68B4D0080185C6002405A37E -:106390005005582C0427046160AC006000A448201C -:1063A000CCA9040018010C08A34300041A7004606F -:1063B00001A31E709CD14001106081A000002270DA -:1063C000146081A0000026700862002402A21270EE -:1063D0000C62002303A21670027607700100602B86 -:1063E0000C08C54210000C089A42E81D2E0100203E -:1063F00005002601D600D07084A0004C04809020B7 -:10640000DE0007700400047094D0E81D03700800DB -:106410002E01002005002601D600D07084A0004C7B -:1064200004809020DE00207E84B200020811247EC9 -:10643000B5A60C001C68ACD0181185C6037000000E -:1064400028685020602D0460BCA00F00B8A71D4034 -:106450003C27FB87381110020C0875259C6865A045 -:106460002001880C0C089A42E81D2E01002005002E -:10647000260106001600D600D07084A0004C0480CF -:106480009020207E84B200020811247EDE003E00AF -:106490004E00B5A60C001C68B4D0280185C6037058 -:1064A00000000770040049203542286855A0D60036 -:1064B00004099642702D602E0470BCA00F00B8A78E -:1064C0001D403C27FB87401110020C0875259C706D -:1064D00075A060207005800C042768AE086822A4AF -:1064E0000C681BA36802518A10110C0875253887A7 -:1064F000042705A0901D9C7075A06020D001E008C5 -:10650000228420841A8399A300000869002422A110 -:106510000C6900231BA110120C08752584B200021F -:10652000180171205000100071202000DE000408C6 -:10653000C341DE002E01002005000870060084A083 -:10654000E0010E00100106A0050084A0030086A053 -:10655000030008110500042778AC0078082F94D0B8 -:106560000419A6431A7004781E70087812700C780B -:10657000167004609CD02001107822701478267068 -:106580000276047084A0100085C006707920004750 -:10659000518AE8013887042705A068119C6005A08E -:1065A000B8016020046084A00F0080A01D403C2042 -:1065B000FB870C0975250870060084A0E0010E0019 -:1065C000100106A0280084A0030086A00300050097 -:1065D00051200000050026010600D600D07084A0DE -:1065E000004C04809020DE008E00087184A103001E -:1065F0002811286805A0780104086D3F0871FCD1B6 -:1066000018010C08D640880C077010000871FCD1E6 -:10661000E80D0C08D640087086A00800301D0070F8 -:1066200005A0181D0370000049200000060001208D -:1066300001470420CCD010010C085B430E002E0152 -:10664000002005002601460136015601C600D6008D -:10665000D07084A0004C04809020DE0049201F43AD -:1066600080AD1100A02084B20002180199203200F0 -:106670001000992031000C7084A0FF072A68077071 -:106680000800077002000370010018010080AC8050 -:10669000A5530C7084A0FF0730010770040004703C -:1066A00084A00400E01DCE0049200000037000001B -:1066B0005E013E014E012E01002005001468FCD051 -:1066C00004099E43007084D0E005247EB5A6040032 -:1066D00007700400047084A00400E01D1871160007 -:1066E0001C71160020711600247116001B7000002A -:1066F0001F70FF3F2370000027700000137004001C -:10670000177000000276077001000120FFFF0920CA -:1067100031000A200A200871087006A1E01DFCD192 -:10672000D00D2E0026722E0022722E001E722E0018 -:106730001A7207700200087086A008001001040891 -:106740000E41077004000370000005004920C3419A -:106750006800087084A00300100106A0050006A0D0 -:1067600020201820582C602149200000588B0061FF -:10677000002108A41A71046001A31E700600042BF6 -:1067800084A008005001106081A000002270060063 -:10679000146081A000002670060084A1070011206B -:1067A00008002AA20862002412A226000C624022DD -:1067B000002343A82E00FF887011002502A20801C3 -:1067C0005012202241200000042B9CD010010E000A -:1067D0000E000E005004127517700000027686A994 -:1067E000C3411811077001002800047084A0100034 -:1067F00085C00670002500A11A70042B84A0080033 -:1068000010010E004E001E0089A100001E710C2B0D -:106810008CA108003001A1A40000227481A0000016 -:106820002670002522A2C3A8000012742028167426 -:10683000027686A9C3411811077001002800047070 -:1068400084A0100085C00670598B602B792000470A -:106850000C08C54206A00500912000809120006030 -:10686000AC7805A068117479D07006A148111C7825 -:1068700005A030011F780000040E3D4491208040A7 -:1068800069208047FDC7006884A00F009811D06878 -:10689000B4D08001BCD07011F60079200001FCD783 -:1068A000101179200002307884A0C00010110C086B -:1068B000D522FE00FCD7200169204047FCC7180CF8 -:1068C0003078018032780419C744347832786120F6 -:1068D000C06C69208047FDC7CC6805A028010180F5 -:1068E000CE6810110C083946006884A00F006801BA -:1068F00086A00100500140680DA03801042105A0C8 -:10690000200101800A200409D645146805A0A801C9 -:10691000018016689011A3680100F600FCD71811D9 -:10692000792000021000792000010C086E3CFE0066 -:10693000606805A010010C08D5227C6805A0400104 -:1069400001807E68281163680000D068C5C0D268E5 -:10695000D068FCD0B001FCC0D268A920000234602D -:1069600005A0580101803660D068FDC0D2682811AA -:10697000106005A010010C08D522E0AC1000041F27 -:10698000AC44FCD738016120C04C69204047FCC7AB -:10699000040869445904387801803A78A0113C7899 -:1069A0003A786120C04C69204047FCC70C6805A0BC -:1069B00010010C084345FCD730116120C06C6920E0 -:1069C0008047FDC7980C1078CCD06801ACD020115E -:1069D000A4D04801ADC0127891200180040EEF448C -:1069E0000C08A1200500912001800500407801805D -:1069F0004278041942454478427869204047FCC7F0 -:106A000079200002D46805A03801E07D04A520119A -:106A1000D668D068BCC0D26879200047106805A04D -:106A200010110120010101801268FCD7180180A01B -:106A3000D08D100080A0C08C4020042065A0E00113 -:106A4000246005A0B001018026609811006805A0AF -:106A50003001486806AC18110C08D645680060681B -:106A600005A018012760010020000C0884450428B7 -:106A7000280C0060402C100CFCD73811692080478E -:106A8000FDC7792000010408FF440500092000002B -:106A9000A920000208609CD05805246005A01801B8 -:106AA00001802660180408609CC084D01011ACD00E -:106AB000C0010A60046005A0D801D600C600160017 -:106AC00068201060018012600C08C737002D682C08 -:106AD00060200C08021C0C08B21D1E00CE00DE0057 -:106AE0003800BDC00A608DA1010010008DA1000119 -:106AF000E0AC1000041F474584A1010030018CA1C7 -:106B0000FEFF0E690C08D52208000E690500002C56 -:106B10007A681467726F176000002B6000001B60BA -:106B20000600B46084A0005F1E60206084A0FF00A7 -:106B300085A0600022600060422069208047FCD769 -:106B4000101169204047586806AC101100285A6897 -:106B50000C089A1B186805A0100101801A680868C3 -:106B6000A4C00A681068087909810A7901801013A5 -:106B70000C087525126818111079A5C112792F60BB -:106B8000000033600000682C0C08BF1DFCD71811F2 -:106B900069204047100069208047106984A10001E6 -:106BA0000120060018117669012004000C08CB2290 -:106BB0000500D60048696021FCD718116920000241 -:106BC0001000692000010C0890241B600600586822 -:106BD00084A0005F1E60206084A0FF0085A04800A4 -:106BE00022602F60000033600000086884A0FDFF71 -:106BF0000A683068B4D0B0014B680400A9201400C2 -:106C0000486894D01001041FFD454B680900A92075 -:106C10001400486884D01001041F0646A920FA0019 -:106C2000041F0D461B685400DE0063680700050062 -:106C300079200047E1008900A900092002006920AD -:106C400080470F6800001368000017680000098182 -:106C5000180169204047A80C05001920A3003A7BC1 -:106C60003E7B050019203300427B467B050019203E -:106C7000DD32327B367B05004C6A85A20000F001D4 -:106C80005069BC6B00A3C60064210463FF83381104 -:106C90001182480108811AA1B80EBC69A80CCF68FE -:106CA0000A00CE0005004C69BC6A64220860B5C0C9 -:106CB0000A6010820981C81D4E69CE0005001600C9 -:106CC000041D5D4691200060041D61469120006016 -:106CD000EC70DCD01811D4D09001A0008EAE000171 -:106CE00038011478F5C0C5C01678D4D0801560047A -:106CF0001478FDC0C5C01678D4D048152804E4D057 -:106D00000409C446041D7F469120006009200C0040 -:106D1000041D8546912000600981D01DE47084A087 -:106D2000FF0186A0FF011011EC70C0088EAE0001BB -:106D300028011478F4C0FCD0301120001478FCC075 -:106D4000F4D00811C4C0167804788CD00005C600B1 -:106D500061200000186084D0B81186AE0002E60001 -:106D6000712010002001DB700100E4781800DB7056 -:106D70000000E078C670C3700E801B600100912097 -:106D80008040EE00CE001800CE001F680C001E00F0 -:086D9000A070A2700500260CA2 -:00000001FF -/***************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP12160 device driver for Linux 2.2.x and 2.4.x - * Copyright (C) 2002 Qlogic Corporation (www.qlogic.com) - * - *****************************************************************************/ - -/************************************************************************ - * --- ISP12160A Initiator Firmware --- * - * 32 LUN Support * - ************************************************************************/ - -/* - * Firmware Version 10.04.42 (15:44 Apr 18, 2003) - */ diff --git a/firmware/qlogic/1280.bin.ihex b/firmware/qlogic/1280.bin.ihex deleted file mode 100644 index 612c2633f8cd726d49f370498331826b9ebf7ed2..0000000000000000000000000000000000000000 --- a/firmware/qlogic/1280.bin.ihex +++ /dev/null @@ -1,2008 +0,0 @@ -:10000000080F0B0000107800411000002E3E000089 -:100010004320504F525947495448312039392C31E7 -:1000200039313239312C39392C3339313439512085 -:100030004F4C494720434F435052524F54414F4930 -:10004000004E492050533231303446207269776D6A -:10005000726120655620726569736E6F30202E388C -:1000600035312020432073756F74656D20726F4E9B -:10007000202E303050206F72756474634E202E6FC6 -:100080002020303020200024C920FF980120FC04CB -:10009000042086A08010C000541071200001A070C0 -:1000A000A270C12010008920741378006D10012007 -:1000B000FC04042086A08012C00069107120000298 -:1000C000A070A27071200001A070A270C120100069 -:1000D0008920F81378006D10C120200089201C139E -:1000E00071201000C3700400C7705349CB702050BA -:1000F000CF702020D37008000120FE04D670C120EC -:100100002100192000000920FFFE00210B20A5A5D9 -:10011000ECA1FF7F642D6B200A0ADCADFF3F542B5E -:100120005B205050142186A2A5A54000A41086A3F0 -:100130000F004000A0106A2C5A2AC120200019206C -:100140000F00780080106A2C5A2A7800A2106A2CBE -:100150005A2A30212821A2A1004F248424842484F7 -:1001600024842484248492A1009909200000012081 -:1001700032007810C12018227920004FA02F0824C7 -:1001800011200000A9204000A4420981C000BF1036 -:10019000092000FF003402A14800CF104000CF101A -:1001A000A820A4420120FC04042086A08010C000E6 -:1001B000E510712000017E0D6920404F7810B04D90 -:1001C0007F0D1078EDC012781B78640078000A115A -:1001D0000120FC04042086A08012C00005111478C0 -:1001E000EDC0D5C016781B786400712000027E0D2A -:1001F0006920404F7810B04D6920804F7120000178 -:100200007810B04D1478D4C016787F0D78000A119C -:100210001478E5C016781B783C00CA7EC27CC67B89 -:100220006778000000788DC0027831203000AF7808 -:1002300001012378020027780200092002006920CA -:10024000404F1B680300236807002768FA002B68EB -:1002500008002F682800376800003B6806003368F4 -:1002600008003F680000098140005E11D3680A0061 -:10027000C368C04F7920004F1478E4D0C000441107 -:10028000ECD0C0004811D768297378004A11D768AC -:100290000D7378004A11D7682D73C768C054CB68B6 -:1002A000C053CF68C094AB684497AF684997B368B0 -:1002B0004497B7684497A76801006920804F780089 -:1002C0001E11D3680A00C368C0511478E4D0C0007E -:1002D0006A11D768397478006C11D7681974C768C7 -:1002E000C074CB684054CF68D095AB684997AF686D -:1002F0004E97B3684997B7684997A7680100107887 -:10030000ECD0C000C2111478E4D0C000B4117E0E4D -:100310006920C05371200002EC70E4D0C000951138 -:1003200019200C0C21200C007810502078009B1113 -:1003300019200A0C21200A0078105020692040540E -:1003400071200001EC70E4D0C000AB1119200C0C3E -:1003500021200C00781050207800B11119200A0CCF -:1003600021200A00781050207F0E7800DB11192020 -:100370000C0C21200C006920C053781050206920FB -:100380004054781050207800DB116920C0537E0E55 -:1003900071200001EC70E4D0C000D41119200C0CC5 -:1003A00021200C00781050207F0E7800DB111920DE -:1003B0000A0C21200A00781050207F0E1120020024 -:1003C0006920C05409200200A920000137680000FC -:1003D0000B684000C87B86A3FFFEC000F2111768BF -:1003E00000011F6864007800F611176864001F6838 -:1003F0000200E8AD1000F000E3110981C000E11136 -:100400001182400004126920C0747800DF11781056 -:10041000A2267810124778101B1E7810424D9120AA -:1004200000217920004F1078ECD040001812712084 -:10043000200078001A1271205000912000227920AB -:10044000004F71202000912000237920004F107868 -:10045000ECD040002C127920000178002E12792077 -:1004600000027120404F912000247920000171206A -:10047000804F912000207920004F71201000003221 -:1004800085A03D30902071201000C37000009000C6 -:100490004D12C07086A00200C0004D127810C11528 -:1004A000392000001078ECD0C000CF1278108E14E4 -:1004B000AC7805A0C0006B12680061126C7865A072 -:1004C000400061127810DC237810E8206800781270 -:1004D0006C7865A040006B127810DC2368007812FD -:1004E0000920474F1120874F04210C2205A140000D -:1004F00078127810511F7120404FA47005A0400061 -:100500009D12507485A4000040009D1279200002C5 -:1005100091200080D4728CA23D3090217810B12BB4 -:100520009120008091203D3068009D127920004F7D -:100530006C7865A040009D12712010007810DC23BB -:10054000E000A5127920004F712010007810164BA2 -:100550007120804FA47005A04000BD12507025A0EE -:100560004000BD127920000191200080D4728CA23D -:100570003D3090217810B12B9120008091203D30AA -:100580007920004F712010006800C9126C7865A0B6 -:100590004000C9127810DC23E00053127810164B8B -:1005A0007800531278108E14AC7805A0C000E712C2 -:1005B0006800DD126C7865A04000DD127810DC2345 -:1005C0007810E8206800F1126C7865A04000E7120E -:1005D0007810DC236800F1120920474F042105A0A0 -:1005E0004000F1127810511F7120404FA47005A0F7 -:1005F00040000C13507485A4000040000C137920B7 -:10060000000191200080D4728CA23D30902178109E -:10061000B12B9120008091203D307920004F712036 -:100620001000680016136C7865A04000161378104F -:10063000DC23E000CF127810164B7800CF123C1369 -:100640003C133E133E134B134B134B134B135613D8 -:100650005613631363134B134B134B134B133C137E -:100660003C133E133E134B134B134B134B135613B8 -:100670005613631363134B134B134B134B13780035 -:100680003C137E007E107E12912000247810D12928 -:100690007F127F107F00912001807C007E007E1001 -:1006A0007E127810C8137F127F107F009120018086 -:1006B0007C007E007E107E12912000237810D129CC -:1006C0007F127F107F00912001807C007E007E10D1 -:1006D0007E12912000237810D129912000247810D7 -:1006E000D1297F127F107F00912001807C0094131C -:1006F000941396139613A313A313A313A313AE1368 -:10070000AE1396139613A313A313A313A313AF133C -:10071000AF13AF13AF13AF13AF13AF13AF13AF13C9 -:10072000AF13AF13AF13AF13AF13AF13AF13780003 -:1007300094137E007E107E12912000237810D12920 -:100740007F127F107F00912001807C007E007E1050 -:100750007E127810D5137F127F107F0091200180C8 -:100760007C007C007E107E127E0D7E0E7E0F7E0051 -:10077000712000016920404F7920004FEC7084A067 -:10078000001CE2787810B04D7F007F0F7F0E7F0D48 -:100790007F127F107C00003C84A007007900CD13FD -:1007A000DE13DE13E013E013E513E513EA13EA1397 -:1007B000003C84A003007900DA13DE13DE13F31388 -:1007C000F3137810B229912000227810EC477C00B6 -:1007D000912000217810EC477C00912000217810B6 -:1007E000EC47912000227810EC477C0091200021FA -:1007F0007810EC477C00181418141A141A142714D3 -:10080000271427142714321432143F143F142714CA -:100810002714271427145014501450145014501433 -:1008200050145014501450145014501450145014A8 -:10083000501450145014780018147E007E107E124C -:10084000912000247810D1297F127F107F00912001 -:1008500001807C007E007E107E127810C8137F120B -:100860007F107F00912001807C007E007E107E1230 -:10087000912000237810D1297F127F107F009120D2 -:1008800001807C007E007E107E1291200023781073 -:10089000D129912000247810D1297F127F107F0068 -:1008A000912001807C007E007E107E127E0D7E0EE7 -:1008B0007E0F7920004F712000026920404F003DDB -:1008C0008CD040006614EC7084A0001CE278781094 -:1008D000B04D003D84D0400074146920804F7120D9 -:1008E0000001EC7084A0001CE6787810B04D7F0FFA -:1008F0007F0E7F0D7F127F107F007C0008700B80C1 -:10090000C8008914077002008CA0E001C0008A149E -:100910009CD0400089147A087A09C370024078009C -:10092000C41568001A1561200000186084D0C0004A -:100930001A15287805A0C0009E1410001B15780019 -:100940001A151079F4D14000A4147800B914147960 -:10095000ECD14000BD14FCD04000B3147E007810F0 -:10096000AE1D7F004000BD147800B9147E007810E1 -:10097000A11D7F004000BD14012007407800C31571 -:100980001079FCD0C000C7146120404F9CC1FCC747 -:100990007800CB146120804F9DC1FDC7646005A025 -:1009A000C0001A15127982602878FCC086A0180051 -:1009B000C000DB147E0C7810851B7F0C2B780000A8 -:1009C0007C6065A0400000157E0C9C607810901E35 -:1009D0007F0C9F6000007810D51C092018008760EC -:1009E000030110787E00FF84C000F614FF854000EC -:1009F000F814C5C012787810BB1D7F001278C000B3 -:100A0000141578100D1E10789CD0C00008156120B8 -:100A1000404F78000C156120804F9CC012787F6099 -:100A20000000D460DCD040001815DCC0D660012086 -:100A300005407800C3157800C1157C001078F4D00B -:100A400040002315012007407800C31506A0C2709E -:100A5000C670CA70CE70DA70C0703DA08AA0400027 -:100A6000C80031157900381500218AA04000C8005F -:100A7000CF1579007815C1151716E0154F16871692 -:100A80008716D715ED1C9216CF15E415E615E81557 -:100A9000EA15F21CCF15A016FD16A51BE71CEC15D8 -:100AA000EA192C1A671AB81AA519B219C619D91950 -:100AB000EB17CF15341741174D1759176F177B17C1 -:100AC0007E178A1796179E17D317DF17CF15CF15E6 -:100AD000CF15CF15F8170A1826185C188418941823 -:100AE0009718C818F9180B1974198419CF15CF1550 -:100AF000CF15CF159419CF15CF15CF15CF15CF150D -:100B0000171D1D1DCF15CF15CF15211D661DCF1526 -:100B1000CF15CF15CF15111681169A16F7169F1BF4 -:100B2000CF15CF15681BCF156A1D091D131DCF15D5 -:100B3000CF15CF15CF15CF15CF15CF15CF15CF1595 -:100B4000CF15CF15CF15CF15CF15CF15CF15CF1585 -:100B5000CF15CF15CF15CF15CF15CF15CF15CF1575 -:100B6000CF15CF15CF15CF15CF15CF15CF15CF1565 -:100B7000CF15CF15CF15CA72C67101200640780077 -:100B8000C315CE73CA72C67101200040C2706800DE -:100B9000C415612000001B600100912000509120CD -:100BA00080407C00C37001407800C415C3700640CB -:100BB0007800C41599204100A1204100A92005001A -:100BC000A3537800C115C470C37004007A00780084 -:100BD000C1157800C1157800C1157800C1159120A4 -:100BE0000080C3700400C7705349CB702050CF7091 -:100BF0002020D370080001200F00D670792000005B -:100C00001B780100312030005920001029201A04DF -:100C10005120450461204704C1202000912000504C -:100C20009120804078001804D875DC74DA75DE7481 -:100C300078001A16292000002025D071C872CC73C4 -:100C4000C470A020992030000370010007700600D6 -:100C50001A731E722274267521204000FF81400005 -:100C6000C11582A14000C8003416202106A008202A -:100C70000384127007700400077001000870FCD034 -:100C800040003B160770020084A0E00140004916B6 -:100C9000C37002407800C415A824A55378002B1611 -:100CA0007800C115292000002025D071C872CC73AE -:100CB000C4709820A1203000037000000770060067 -:100CC0001A731E72227426752120400007700600D8 -:100CD000FF814000C11582A14000C8006E1620218E -:100CE00006A0082003841270A824A65307700100F0 -:100CF0000870FCD04000751684A0E0014000631627 -:100D0000C37002407800C415D875DC74DA75DE74DF -:100D100078005216C471C87014219EA70400C00048 -:100D20008F160A20CA727800C015C7700800CB70F1 -:100D30000F00CF700B007800C115D875DC76DA751E -:100D4000DE767800A316292000003025C470C87212 -:100D5000CC73D074C670CA72CE73D27405A0400032 -:100D6000F2160AA44000B316C800BC1601807278BF -:100D700084A000FC4000C016AC7885C0AE7801208D -:100D800005407800C3157E7B7A7A867E827D767CEC -:100D90008CA400FF4000D8160784048004800C81D6 -:100DA0000C810F8118A191A20000B1A6000081A5BD -:100DB00000007800E21607840480048018A391A242 -:100DC0000000B1A6000081A500001A731E722276F1 -:100DD000267005A64000EC16107AC5C2127AAC78CF -:100DE00084A0FCFFAE787800F516AC7885C0AE78AC -:100DF0007800C115D875DC76DA75DE7678000017D4 -:100E0000292000003025C470C872CC73D474C67019 -:100E1000CA72CE73D67405A040002F170AA44000F2 -:100E20001017C80019170180927884A000FC4000B8 -:100E30001D17AC78C5C0AE78012005407800C315F9 -:100E40009A7A9E7BA27DA67E002605A540002817E3 -:100E5000107AC5C2127A967CAC7884A0FFFCAE787A -:100E600078003217AC78C5C0AE787800C11509207B -:100E700000006C7865A040003E1708810060780093 -:100E80003717C47A7800BF150920484F0C21107815 -:100E9000ECD0C000C0151120884F14227800BF1577 -:100EA0000920494F0C211078ECD0C000C01511204A -:100EB000894F14227800BF156120404F28612C62B1 -:100EC0001482148214821078ECD0C0006D17612057 -:100ED000804F2863DA732C631C831C831C83DE73AE -:100EE0007800BF1509204C4F0C211078ECD0C000C1 -:100EF000C01511208C4F14227800BF151879780086 -:100F0000C01509204D4F0C211078ECD0C000C01541 -:100F100011208D4F14227800BF1509204E4F0C214F -:100F20001078ECD0C000C01511208E4F142278002C -:100F3000BF1520791078ECD0C000C015247A780055 -:100F4000BF15C471FCD1C000A6171120C053780092 -:100F5000A81711204054078184A00F00038003804C -:100F6000038068A2006A04689CD04000B717086B31 -:100F70007800B8170C6BFCD1C000BF1721203B02D2 -:100F80007800C11721203B0124241479E4D14000CA -:100F9000CD17C4D4C000CC17D5C47800CD17DDC49C -:100FA000A4A4001CDE74C4717800BE15C477781048 -:100FB0002B1E912000801C6B146A91200180082751 -:100FC0007800BE156120404F18611078ECD0C00049 -:100FD000C0156120804F18627800BF15C477781063 -:100FE0002B1E912000800869186A106BDA77912017 -:100FF00001807800BE15C471102194A20F0082A256 -:101000001000C800B9157810C62784A3004040001E -:10101000081895A220007800BE15C4710021BCC03C -:1010200082A01000C800B915BCD1C0001918112049 -:10103000484F042278001D181120884F0422BDC09B -:101040007E000021BCC01220781023277F01780089 -:10105000C015C4712120494F0424C6701920000016 -:1010600078003518C8712120894F0424CA70FDC347 -:1010700011205418A9200800042206A14000441899 -:101080001082F0003918C471C8727800B81592A2A5 -:1010900054187E0222217F01781044271078ECD06A -:1010A000C0005218FCD340002F187800C115E80387 -:1010B000FA00F401EE0204000100020003006120C6 -:1010C000404F28612C62148214821482C4702A60FA -:1010D000C8700380038003802E601078ECD0C000BD -:1010E00082187E027E016120804F28612C6214826A -:1010F00014821482D8702A60DC700380038003801D -:101100002E60DA71DE727F017F027800BF156120E8 -:10111000404F3061C47032601078ECD0C000C01510 -:101120006120804F3062C87032607800BF15187936 -:101130007800C015C47184A1CFFF4000A3181078B7 -:10114000ECD0C000B915C8727800B81511204D4F09 -:10115000042212217E00192000007810AB2710789D -:10116000ECD04000B3187F017800C015C87184A18D -:10117000CFFF4000BC181021C4717800B8151120B1 -:101180008D4F042212217E00FDC37810AB277F0211 -:101190007F017800BF15C47182A110004800D418E7 -:1011A0001078ECD0C000B915C8727800B8151120BD -:1011B0004E4F04227E00122119200000781089274A -:1011C0001078ECD04000E4187F017800C015C87199 -:1011D00082A110004800ED181021C4717800B815E4 -:1011E00011208E4F04227E001221FDC37810892722 -:1011F0007F027F017800BF15C471C87284A1FDFF12 -:10120000C000B81584A2FDFFC000B81500212079E8 -:1012100022780022247A26787800BF15C471FCD188 -:10122000C00013191120C053780015191120405423 -:10123000078184A00F0003800380038068A2192027 -:101240000000C872BCD2400024199DA31000B4D283 -:10125000400029199DA308009120008000687E00AD -:1012600026A240004819026AECD440003519A5C3F3 -:10127000E4D4400039199DC3F4D4400048190F81CB -:10128000F4D24000441978100828780048197810E2 -:10129000E62778004819CC72086806A240006A194F -:1012A000A4A2FF001478E4D0C0005B1982A4280037 -:1012B000480067194000671978005F1982A443004D -:1012C00048006719C471C6717F02CA7291200180FB -:1012D0007800BA150A6A9DA30A00046805A3066887 -:1012E0007F020C6BC471912001807800BE15C47719 -:1012F00078102B1E91200080146A1C6B91200180B5 -:10130000C8701668CC701E6808277800BE15C470B7 -:101310006120404F18611A601078ECD0C000C015F1 -:10132000C8706120804F18621A607800BF15C471C0 -:10133000C872CC7382A11000C800B91578102A2891 -:1013400084A300404000A31995A220007800BE1598 -:10135000C47778102B1E91200080086A8DC20A6A1B -:101360009120018008277800BF15C47778102B1EC4 -:1013700091200080086A94A2F9FF0A6A046805A017 -:101380004000C11978106F2691200180082778004D -:10139000BF15C47778102B1E91200080086A95C273 -:1013A0000A6A046805A04000D41978106F269120BD -:1013B000018008277800BF15C4774120010049202B -:1013C000050051202000912000807810461E9120B9 -:1013D00001800827086A7800BF15C4771478E4D024 -:1013E000C000FE19FCD74000F8197810AE1D40006F -:1013F000FE197800C3157810A11D4000FE19780071 -:10140000C315C873CC72C677CA73CE727810CD1E5E -:10141000C000281A186805A04000221A08277E0775 -:1014200078105A287F07C000221A01201500FCD727 -:10143000C0001B1A6120404F78001E1AFDC06120B9 -:10144000804F2A78912001807C009120018001202A -:1014500005407800C315912001807800C115C4773C -:101460001478E4D0C000401AFCD740003A1A781033 -:10147000AE1D4000401A7800C3157810A11D400031 -:10148000401A7800C315C677412021004920050085 -:1014900051202000912000807810461E092016005F -:1014A000FCD7C000541A6120404F7800571A6120C1 -:1014B000804FFDC1676003007F6000007667836036 -:1014C0000F002A79D461DCC1D66178106F26912093 -:1014D00001807C00C877CA77C477C6771478E4D0D7 -:1014E000C0007E1AFCD74000781A7810AE1D40006C -:1014F0007E1A7800C3157810A11D40007E1A78006E -:10150000C315BCA700FF9120008009201700FCD75D -:10151000C0008B1A6120404F78008E1A6120804FE6 -:10152000FDC17F60000067600200766783600F0086 -:101530002A79D461DCC1D66178106F2691200180B0 -:1015400041202100492005005120100091200080F9 -:10155000C87005A04000AC1AD460FDC0D6607810F9 -:10156000461EC8703668388784A71F00C000AC1AB2 -:10157000912001807C00192000001478E4D0C00084 -:10158000CE1AC87284D24000C81A7810AE1D40002E -:10159000CE1A7800C3157810A11D4000CE1A78002D -:1015A000C315C872CA72AC7884A00300C000F91ACF -:1015B0003920000084D24000DB1AFDC74120210001 -:1015C000492004005120080078102B1E9120008033 -:1015D0000868D4C00DA80A6991200180388784A7C3 -:1015E0001F00C000E11ABCA700FF3F8738873F8774 -:1015F00084A7000FC000E11A91200080C87284D235 -:10160000C0000B1B1078ECD04000071B69200001C4 -:1016100078000D1B6920000278000D1B6920000175 -:10162000086884A0FDFF0A683068B4D040002D1B14 -:101630004B680400A9201400486894D040001F1B88 -:10164000F000191B4B680900A9201400486884D0D9 -:101650004000291BF000231BA920FA00F0002B1BDF -:101660007920004F09201800C87284D2C000391BAD -:101670006120404F78003C1B6120804FFDC17F609E -:1016800000002A796760010083600F00A7600000F6 -:10169000A860B260B660D460B4D04000581BB4C03B -:1016A000D6607E0CB86065A00860D4C00A6018607F -:1016B00001801A607F0CD46084A0FF77D660AC787C -:1016C0008DC0AE78FF834000631B7C001B68470021 -:1016D000912001807C00CC737810BA1AEC69486ABA -:1016E00085A100184A6885A14000EE68CC732120CE -:1016F0000400A920FF09F000781B2184C000761B9C -:101700001983C000741BEE694A6A912001807C0035 -:10171000FCD7C0008C1B6920404F78008E1B6920CD -:10172000804FC471C6711669FF81C000961BA768FF -:101730000100AC788CC0AE7884D0C0009E1B7810BD -:101740002D1F7C00D875DC74DA75DE747800A71B59 -:101750002EA02025C471C873CC72C671CA73CE7214 -:101760007920004FDE7DDA7CD67BD27A7810041E99 -:101770004000D11CA9200500A120144F9120008019 -:10178000A1419120018009204000781018204000DC -:10179000CA1B78100D1E7800D11C04608CA0FF00BD -:1017A0008EA10900C000D51B7E007810BF237F00EA -:1017B00084A000FF078009804000611C7E0C682C1B -:1017C0007810041E40001B1C002C9E680981C0007C -:1017D000DC1B9F6000007F0C7E0CDC7DD87CD47B02 -:1017E000D07A90A2400099A30000A1A40000A9A56E -:1017F0000000DE7DDA7CD67BD27A682C9C6865A0FE -:101800004000601C0920400078101820C0003E1CD9 -:10181000046084A0FF0086A00200C0001B1C0460BE -:1018200084A0FF0086A00A00C000171C7E0178106B -:10183000BB237F01002D02607800EA1B7F0C7E0C29 -:101840009C607810901E7F0C9F6000007810D51C63 -:10185000092018000860CDC00A6004608660107816 -:101860007E00FF84C000341CFF854000361CC5C0CC -:1018700012787810BB1D7F00127878100D1E78004A -:10188000D11C7F0C7E0C9C607810901E7F0C9F609A -:1018900000007810D51C09201800876003011B6028 -:1018A000030010787E00FF84C000561CFF854000B6 -:1018B000581CC5C012787810BB1D7F0012787810B4 -:1018C0000D1E7800D11C7F0C1478E4D0C0008F1C52 -:1018D0001461FCD140006F1C7810AE1D40008F1CBD -:1018E0007800731C7810A11D40008F1C7810D51C47 -:1018F00009201800876003011B60210010787E001A -:10190000FF84C000831CFF854000851CC5C0127881 -:101910007810BB1D7F00127878100D1E0120074043 -:101920007800C315C474C873CC7214609120008011 -:101930007E0E09201200FCD0C0009F1C7120404F79 -:101940007800A21C7120804FFDC12A7967700500C4 -:10195000D471DCC1D6716A736E72727476707B70EA -:101960000000002C7E702EA030251C6184A1600038 -:101970004000B91C7810B6467F0E9665A6659A663B -:10198000AA66AF600000B360000014672360000027 -:10199000246096A00100C000CC1C00802660781056 -:1019A0006F26912001807C00C37005407800C4152B -:1019B000A92005009920144F912000800A539120FE -:1019C0000180002110A299A30000A1A40000A9A5F4 -:1019D00000007C00C471C77000001E797800C1153A -:1019E000C471C67168217800F41C692000100C696C -:1019F00016A0042D10A2688D0981C000F61C85A2D6 -:101A00000000C000041DC37000407800061DC370B4 -:101A10000340CA707800C4156479C671C47182A18C -:101A20000300C800B91566797800C1156479C671DC -:101A30007800C1150079C671C47102797800C115AA -:101A40000079C6717800C115C470112000008CA007 -:101A50000D004000361D0C814800321D10820C81A3 -:101A60000C814800321D10820C81FF81C000BA1524 -:101A700010820E7A8CD24000621D1079CDC112798D -:101A8000092021001920030084D240005C1D088138 -:101A90001920410011204E97122319204200108274 -:101AA00012231920430010821223192046001082AD -:101AB000122319204700108212231920060011203A -:101AC0005397122111207397122304790678780016 -:101AD000C0150478C6707800C115C471FCD1C0006F -:101AE000721D1120C0537800741D112040540781CD -:101AF00084A00F0003800380038068A2146AB4D21C -:101B00004000831D112001007800851D1120000078 -:101B10000C6B0068DA707800BE151478F4D04000C1 -:101B2000951D01200740DB70000005A07800A01D76 -:101B3000FCD040009F1D01200740DB70010005A084 -:101B40007800A01D06A07C001478F4D04000AC1DE5 -:101B500001200740DB70000005A07800AD1D06A045 -:101B60007C001478FCD04000B91D01200740DB70D8 -:101B7000010005A07800BA1D06A07C0012711A723F -:101B80001E731078C4D04000C41D2274267580AC2A -:101B9000010008810C81A9819880A1203000037088 -:101BA00000008460A220A65307700100747984A10C -:101BB00000FF4000E11D0F810C810C810480048036 -:101BC000078000A17800E41D0781048004807C79EF -:101BD00008A1787A06A011A2107DC4D54000F11D9D -:101BE000847B19A3807C21A40870FCD04000F11DE7 -:101BF00003700100077006001A711E72107DC4D5B3 -:101C00004000011E2273267484A0E0017C00487805 -:101C100065A040000C1E042C4A78632000007C0064 -:101C20007E0F7920004F48786220002C05A0C0006C -:101C3000181E7810B2294A787F0F7C001120009975 -:101C40004A7AC47B19834000281E80A232001220E9 -:101C5000102078001F1E132000007C007E017E02F1 -:101C6000FCD7C000341E1120C0547800361E11204D -:101C7000C07484A7000F0B8084A71F004000411E82 -:101C8000038003800380038005A168A27F027F0197 -:101C90007C0078102B1E00292A68002A2E6808680C -:101CA00084A0EFF90DA80A697E0EFCD7C0005B1E68 -:101CB0000920534F7120404F78005F1E0920934F39 -:101CC0007120804F0C21046805A040006F1E16A1F2 -:101CD000C0006F1E6020006006687E010B200000BF -:101CE0007800721E092000007E01046865A0400093 -:101CF000871E006006687810A21E781064201068A5 -:101D0000087909810A7901801268C000721E107971 -:101D1000A5C112797F0102690669002D6020781043 -:101D2000132B7F0E7C0065A04000A11E08209C6044 -:101D300005A040009E1E62209F60000065A0780004 -:101D4000941E48784A7962207C00076003018F6006 -:101D50000000A9201C0080AC0500A020012000008C -:101D6000A44028681A602C6822607C007E0EFCD794 -:101D7000C000BD1E7120404F3120C04F7800C11EF1 -:101D80007120804F3120C05150708CA00002C000E3 -:101D9000CB1E08A60A2D0080527006A07F0E7C0084 -:101DA0007E0FFCD7C000D51E7920404F7800D71E8B -:101DB0007920804F78102B1E9120008004680A78CB -:101DC00065A040002B1F7800E91E002C0A786020D7 -:101DD000006065A040002B1F106006A3C000E21E3B -:101DE0000C6006A2C000E21E282C4C7806ACC00095 -:101DF000F81E7800281F046806ACC000061F0060AB -:101E00006020066805A0C000061F03680000780077 -:101E1000101F006408786020026486A40000C000DF -:101E2000101F002C026860257F0F7810A21E7E0F05 -:101E30001B600500236020007F0F781064207E0F58 -:101E4000087909810A79106801801268C000281F8A -:101E50001078A5C012780120FFFF05A07F0F7C003D -:101E60007E07002739200000FCD04000351FFDC749 -:101E700041202100492004005120080091200080C9 -:101E80007810461E388784A71F00C0003D1FBCA7DE -:101E900000FF3F8738873F8784A7000FC0003D1FA2 -:101EA000912001807F077C006C78092074970C21B9 -:101EB0000DA140005B1F65A07800DC2361200000BD -:101EC000186084D0C0007B1F10788CD040006C1F3D -:101ED0008CC01278FCC76920404F7800711F8DC0FC -:101EE00012786920804FFDC7912000801C681F6810 -:101EF00000009120018005A0C0007C1F7C008CA008 -:101F0000F0FF4000821F7810B2297900841F941FCF -:101F1000971F9D1FA11F951FA51F951F951F951FFB -:101F2000AB1FDC1FE01FE61FFB1F951F951F7C00EA -:101F30007810B22978102D1F012001807800072029 -:101F4000012003807800072001200480780007200A -:101F500078102D1F01200680780007209120008036 -:101F60007E07FCD7C000B71F6920404F3920090009 -:101F70007800BB1F6920804F39200900006886A0C7 -:101F800000004000C51F7F001E6F912001807C0073 -:101F900074687F07BCA000FF412021004920040095 -:101FA000512010007810461E388784A71F00C000FB -:101FB000CF1F9120018001200A8078000720012096 -:101FC0000C807800072078102D1F01200D807800EC -:101FD00007201478E4D0C000F91FECD04000F31FB4 -:101FE000FCD74000F31FE4787800F41FE078C67057 -:101FF00001200E80780007207800951FFCD7400054 -:102000000120EC7878000220E878C67001200F806B -:1020100078000720C270FCD7C0000F20DB700000E2 -:1020200078001120DB700100612000001B600100BE -:10203000912080407C0080AC0100FF814000432063 -:1020400099203000A0200C7084A0FF0340002520C0 -:1020500018707E001C707E0020707E0024707E0050 -:102060001271AC811A721E732274267503700100FE -:102070000770010008700B80C8003720077002004D -:102080008CA0E001C0004320A55306A0037000000F -:10209000077004007F0026707F0022707F001E7092 -:1020A0007F001A707C0011202000092010000A6BAC -:1020B0000E6C036800FD076818001A6A002DE8A07E -:1020C000080090A204000981C00054207C00046034 -:1020D0008660082C63200000687805A06A794000BB -:1020E0007120022C780072206E797C007E0C6120B9 -:1020F000004F87680301082D6B200000686005A071 -:102100006A6140008320022D780084206E617F0C7C -:102110007C0091200080042C6E7805A0C0008E20E9 -:102120006A78912001809C6005A04000A7207E0C69 -:10213000602008209C6005A04000A32062209F60D2 -:10214000000065A09C6005A0C0009B2048784A79EB -:1021500062207F0C487862209F60000085AC000000 -:10216000C000B1207810B2294A787C00A920100064 -:1021700006A0048086808E81C800BC2000A2F000EA -:10218000B72086808E817C007E15A920100005A0D6 -:102190004000E2201AA1C800E22013828D8148008D -:1021A000D5201AA1C800D620F000CA207800DA2075 -:1021B0001AA108231082F000CA207E00003284A0F9 -:1021C000FFF780207F007F157C007E00003285A015 -:1021D00000087800DE20747DD07006A54000CE2176 -:1021E0001078502000788CD040000A21ECDA4000B2 -:1021F0000A217E0E9120008071202000047005A02D -:10220000C000072108707F0E86A0080040000A2148 -:102210007800CE217F0E7800CE217810041E400079 -:10222000CE2146A070790025008012A1092040002F -:10223000C800192178002021D07206A24000202178 -:102240004088092080007E0C1271077001009920DF -:102250003000A920200080AC0100A02061200000F7 -:10226000FF88400032217810041E0870FCD0400026 -:10227000322107700200912001808CA0E001C00093 -:102280006921A553FF8CC0004721FF884000B82179 -:1022900078005121002C8E78A920200080AC01000C -:1022A000A020A5537800B82146A018721C73C4DA88 -:1022B000400059212074247592A240009BA3000085 -:1022C000A3A40000ABA500001A721E73C4DA40007C -:1022D00069212274267506A0077004004000B82109 -:1022E000FF8C4000722178100D1E7F0C78100D1E9F -:1022F00046A0887800808A7886A002004000982155 -:102300007C7A787BC4DA40008421847C807D747977 -:1023100007810480048010A299A30000A1A40000FA -:10232000A9A500001A721E73C4DA4000CE212274DF -:1023300026757800CE211460FCD0C000A021692051 -:10234000404F7800A2216920804F912000801F68B3 -:102350000200FF884000AE2146A08C786020780003 -:1023600098218B780000AC7885A00300AE7891208E -:1023700001807800CE217F0C8B78000078108D23AF -:10238000046084A00F007810CF21FF884000CC218A -:102390008C786020046084A00F007810CF21780032 -:1023A000E8207C007900D121E121FF211D22E121DB -:1023B0002E22F221E121E121E121FD211B22E12157 -:1023C000E121E121E121E12139200004BC7805A7C8 -:1023D000BE78086005A70A60781071229C60BA7800 -:1023E0009F600000781077237C00BC78C4D0400048 -:1023F000F8217800E1211C60BDC01E607800052234 -:102400007810BF23BC78C4D0400005227800E121B9 -:10241000BF7800000460078084A0FF00B2780180CC -:10242000400018227810712240001822BC78C5C0E4 -:10243000BE7878001A22780090227C007810BB23A6 -:10244000BC788CA0000EC0002522C4D0C00027227A -:102450007800E12178107122C0002D2278009022AE -:102460007C00BC78C4D0400034227800E121BF78E1 -:102470000000146711200100A822186084A0FF004A -:1024800005A040005422BCA700FFA92020008EA078 -:10249000010040005422BCA7008011200200A920A6 -:1024A00000018EA002004000542278006E227810B5 -:1024B0002B1E002D912000802B6800002F6800004B -:1024C000086884A0DEFF0A68E8AD10009120018052 -:1024D000F0005722118240006E22A92000017800EE -:1024E000572278100D1E7C009F600000B4786DA00C -:1024F000002CB678C0007C22BA78780084229E68CE -:10250000002D0260B87806ADC00084220260B07869 -:102510000180B278C0008F22BC78C4C0BE78B87881 -:10252000602006A07C007E0E2EA03025BA7DB67DF0 -:10253000AE65B2651C60A260482084A9FFE11E6000 -:1025400084A960004000A3227810B6469665A6656F -:102550009A66AA6614677120804FFCD7C000AF222C -:102560007120404F84A7000F0B8084A71F004000FC -:10257000BA22038003800380038005A1C47168A18F -:102580000027078084A00F00038003800380C871A8 -:1025900000A1C260912000801478C4D04000DF22E6 -:1025A000ECD04000DB22FCD7C000D822F4D0C00021 -:1025B000E6227800DF22FCD0C000E6221078F4D0BA -:1025C000C000E622086E84D640001023FCD9C0006B -:1025D0001023912001807810A21E91200080781095 -:1025E0006420912001801478E4D0C0007523147811 -:1025F000C4D040007523ECD040000823FCD7C000B5 -:102600000323F4D0C0000C2378007523FCD0C00055 -:102610000C23780075231078F4D0400075231B60DC -:10262000210078007523246096A00100C0001723C4 -:1026300000802660106A146802A248002A23400025 -:102640002A2391200180392000029C60BA789F6083 -:1026500000007810772378007523082CFCD94000FF -:102660005223006865A040005223046A007084A0D1 -:102670000200400048234C7006A2C0004823046BAF -:1026800060210423026005A0C00044230269602287 -:10269000026178005E23002D60207810132B086EF5 -:1026A00060210262066978005E230068026965A005 -:1026B00040005A23026178005B23066960210360B1 -:1026C00000006021FCD940006523B4A6FCFF0A6E1F -:1026D0001068087D28850A7D00801268912001809D -:1026E000B4D640007523B6A640000A6E7810B31E1B -:1026F0007F0E7C00086005A70A609120008078109A -:10270000642091200180B87865A040008A239C60F5 -:10271000BA789F60000078007723B678BA787C009A -:1027200070797478182884D340009723008012A110 -:1027300048009C23008012A1C800AC2384C37C7A8B -:102740001A72787A1E72C4DA4000A723847A227241 -:10275000807A267206A084D34000AC23008076786D -:10276000D2701C7805A04000BA2301801E78C000FA -:10277000BA236800BA23912080407C003920D323FB -:102780007800C1233920D923042705A04000D22393 -:1027900000AC68200869106812690A680C6914683E -:1027A00016690E6838877800C1237C000300090091 -:1027B0000F0015001B00000015001B000000412049 -:1027C00000000C787900E123B3258625E5235E24FB -:1027D000392074973427107D78000524846086A002 -:1027E0000301C00047241461186005A14000FA23CA -:1027F000FF86C000162478004724038680A05597E2 -:102800000C6202220080106202227810862030863C -:102810008EA60F004000D2246C7865A0C000EB2388 -:10282000087802A6C8001624ACD5C00016243A26A3 -:102830007C0082A60300C800D22491200080692079 -:102840000000186884D0C00042241120559704224B -:10285000C67010820422CA7084D6C000322410824E -:102860000422DA7010820422DE7085A62080C270F5 -:102870001B68010091208040107884A0CFFF12785F -:10288000912001803B2000007C001078ADC01278C0 -:102890007800D2243A267810BD25C000E0256C7857 -:1028A00065A0C000EB2391200080107884A0CFFFAA -:1028B000FF8640005924ADC0127891200180780035 -:1028C000E025392074973427107D78007A248460BD -:1028D00086A00301C000BB241461186005A140005C -:1028E0007324FF86C0008B247800BB2480A65597F4 -:1028F0000C6202227810862030868EA61E004000D0 -:10290000D2246C7865A0C0006424087802A6C800B0 -:102910008B24ACD5C0008B243A267C0082A606000E -:10292000C800D2249120008069200000186884D05B -:10293000C000B6241120559709204E97A8261C21C7 -:1029400004221A2008811082F0009C2485A6308081 -:10295000C2701B68010091208040107884A0CFFFD6 -:1029600012789120018006A0092075970A203A204C -:102970007C001078ADC012787800D2243A26781006 -:10298000BD25C000E0256C7865A0C00064249120BE -:102990000080107884A0CFFFFF864000CD24ADC01A -:1029A0001278912001807800E02591200080077046 -:1029B00004009479D47002A14800E3244000ED247F -:1029C000907B02A3C000ED247800E6240280C000C2 -:1029D000ED243A261078ADC01278912001807C0059 -:1029E00084A100FF4000FA240F810C810C81048037 -:1029F0000480078000A17800FD2407810480048002 -:102A00009C7A10A21A72987A06A011A21E72C4D4DF -:102A100040000D25A47A11A22272A07A11A226727A -:102A2000A120300003700000092054970A26098174 -:102A30009821042184D040001B253386B0A60200D3 -:102A4000A826A65303861270077001009079947827 -:102A500000800AA1C8002A2506A02820747984A134 -:102A600000FF400039250F810C810C810480048017 -:102A7000078000A178003C250781048004807C79D0 -:102A800008A1787A06A011A2C4D440004825847B0E -:102A900019A3807C21A40870FCD04000482584A0A4 -:102AA000E00140006D25107D312054973426A87830 -:102AB0000080AA788CD0C0006225077006000470E0 -:102AC00094D0C0005C257800D4246920474F6B2047 -:102AD0000300AC7885A00003AE7806A078007625C8 -:102AE0003020D67591208040967D107DACA5CFFF1B -:102AF000127D91200180AA78077006003A260370A3 -:102B000001001A711E72C4D54000852522732674F7 -:102B10007C00846086A00301C000A92514611860B0 -:102B200005A1C000A92569200000186884D0C00054 -:102B3000A9250C60C6701060CA70C37020801B6825 -:102B4000010091208040781086206800A8256C78CC -:102B500065A0C00086257C007810BD25C000E0255A -:102B60006C7865A0C00086257800E0257810BD252A -:102B7000C000E0256C7865A0C000B3257800E02592 -:102B8000846086A00301C000D1251860FCC01A60D3 -:102B900086A00400C000D1250478A4D04000D1252F -:102BA0007810862006A07C007810E625C000D82585 -:102BB00085A001007C007810F525C000DE254120AD -:102BC0000100107D7C00FF884000E52591208040B9 -:102BD0007C00907B9479D47002A1C000EF2585A37E -:102BE00000007C004800F32502A37C0002807C00EA -:102BF0001078ECD040000D267E0E912000807120D0 -:102C00002000047005A0C0000A2608707F0E86A070 -:102C1000080040000D2678005E267F0E78005E26B4 -:102C200084A100FF40001A260F810C810C810480D2 -:102C30000480078000A178001D260781048004809D -:102C40009C7A987BA47CA07D10A206A019A321A445 -:102C500029A509201800286005A040002E2609207B -:102C600040007810BB1D40005026A8780080AA784C -:102C70008CD0C0005E261460FCD0C00040266920C5 -:102C8000404F780042266920804F912000801F68C5 -:102C90000300AB780000AC7885A00003AE789120EB -:102CA000018078005E26AB7800007810862090794D -:102CB000947800800AA1C8005B2606A09678D6709A -:102CC00006A071201000912001807C00FCD7C0007C -:102CD0006A260920594F78006C260920994F9120C7 -:102CE00000800A207E0FFCD7C00083260920404FB9 -:102CF0000120044F0420ECD040007F267920000101 -:102D00007800872679200002780087260920804FE6 -:102D100079200001042186A00000C000A026FCD775 -:102D2000C00093260920454F780095260920854F3D -:102D3000042105A0C000A026307884A0C000C000F7 -:102D4000A0261B7845007F0F7C0009200200692027 -:102D5000004F1068ECD0C0000F277120804F792001 -:102D600000012120BF514B780F001920A74484D1C6 -:102D70004000C3261068ECD04000BF26A1202B01E4 -:102D80007800C526A1202B027800C526A1202B01A2 -:102D9000042305A04000D2269A781883AC23188318 -:102DA0009823A65318337800C5269B782000A920C5 -:102DB00010001468E4D04000E226AF780000AF783D -:102DC0002090F000DA267800E826AF780000AF788F -:102DD0002080F000E226037000007E018CD10920E3 -:102DE00000004000F126BDC17810E2287F0120706C -:102DF00084A00F007E001468E4D07F00C00001278B -:102E000085A040637800032785A0C06206780F780C -:102E100000924378D800537880000B7808005674ED -:102E2000537000000981400022277120404F106834 -:102E3000ECD040001C277920000178001E27792063 -:102E400000022120BF4F7800B0267C007E01BCD15B -:102E5000C00037277E000120044F0420ECD07F0003 -:102E60004000332711200101780039271120010289 -:102E700078003927112001018CA10F00042284A0C1 -:102E8000F0FF05A112207F017810E2287C00FCD31E -:102E9000C00057277E000120044F0420ECD07F00A3 -:102EA0004000532711200101780059271120010209 -:102EB0007800592711200101A92009000B81F00099 -:102EC0005B278CA1000E042284A0FFF105A1122033 -:102ED0007C00192002000120044F0420ECD04000A7 -:102EE0007327198309200101780075270920010142 -:102EF000A92005001382F000772794A2E0000421A6 -:102F000084A01FFF05A20A201983400088270920FA -:102F10000102780075277C00FCD3C0009C277E004E -:102F20000120044F0420ECD07F004000982711209E -:102F3000010178009E271120010278009E271120B0 -:102F40000101A9200C000B81F000A0278CA100F04A -:102F5000042284A0FF0F05A112207C00FCD3C00036 -:102F6000BE277E000120044F0420ECD07F004000EB -:102F7000BA27112002017800C02711200202780030 -:102F8000C02711200201042284A0CFFF05A1122036 -:102F90007C007E0CBCD1C000DA277E000120044FEB -:102FA0000420ECD07F004000D6276120000178008B -:102FB000DC27612000027800DC2761200001BCC111 -:102FC0000381038080A020009A60AC62AC637F0C18 -:102FD0007C007E0CBCD1C000FA277E000120044F8B -:102FE0000420ECD07F004000F6276120000178002B -:102FF000FC27612000027800FC2761200001BCC191 -:103000000381038080A022009A60A46084A0DFFF77 -:10301000AE607F0C7C007E0CBCD1C0001C287E0002 -:103020000120044F0420ECD07F00400018286120CC -:10303000000178001E286120000278001E2861200F -:103040000001BCC10381038080A022009A60A460BB -:1030500085A02000AE607F0C7C007E0CBCD1C0003F -:103060003E287E000120044F0420ECD07F00400069 -:103070003A28612000017800402861200002780091 -:10308000402861200001BCC10381038080A0200092 -:103090009A60A4608CA2200040004E28ACC29DA380 -:1030A0000040FCC3B4D3C0005328FDC3AE6210205F -:1030B000A460AE6318207F0C7C00912000807E0C01 -:1030C0007E0E186805A04000C028FCD14000692889 -:1030D0006120D09678006B286120C0957810C828B0 -:1030E0004000A228A9200101FCD1400078286120DD -:1030F000D09578007A286120C0947E0C7810C8287A -:10310000400085287F0C608CF0007A287800C02869 -:103110007F00FCD140008F2882A0D0957120804F85 -:103120007800932882A0C0947120404F7A70767105 -:10313000382101200400667083700F00D471DCC157 -:10314000D671781063267800BC28FCD1C000A9286D -:103150007120404F7800AB287120804F2060DDC087 -:10316000226076713821002C7E7001200600667086 -:1031700083700F00D471DCC1D671781063260120F2 -:1031800000007800C228012001009120018005A0E4 -:103190007F0E7F0C7C00042C05A04000DF286020FF -:1031A000106006A3C000DC280C6006A2C000DC286A -:1031B000146006A1C000DC2806A07800E1280060A9 -:1031C0007800C92885A001007C007E0F7E0E7E015C -:1031D000BCD1C000FA287920404F7E000120044F66 -:1031E0000420ECD07F004000F62871200001780018 -:1031F000FE28712000027800FE287920804F71207F -:10320000000120798CA10F00EC70C4D0C000082907 -:103210007F01780023290B810B810B810B817F00BB -:10322000BCD0C00020297E000120044F0420ECD037 -:103230007F0040001C298DA1000F780022298DA15C -:10324000000F780022298DA1000804217F0E7F0F36 -:103250007C007E0E0120014F0420ACD0C000A329C9 -:10326000E468ACD04000A32984A00600C000A329D4 -:103270001460FCD0C0003D297120C05378003F2964 -:1032800071204054078084A00F00038003800380D6 -:1032900070AE047084A00A00C000A329087194A134 -:1032A00000FF4000A3298CA1FF0001200A0006A115 -:1032B0004000722901200C0006A14000762901205F -:1032C000120006A140007A290120140006A1400046 -:1032D0007E290120190006A1400082290120320028 -:1032E00006A14000862978008A2909200C00780070 -:1032F0008C290920120078008C29092014007800FC -:103300008C290920190078008C29092020007800D8 -:103310008C2909203F0078008C2911200000002111 -:1033200005A20A707120004F0470BCD04000A32990 -:103330001460FCD0C0009E29EA707120404F7800D4 -:10334000A129EE707120804F1F700D007F0E7C0050 -:103350000120054F0420E4D0C000B129047884A0E6 -:103360001FFF85A0406306787C006800B229912089 -:103370000080712000007E00187084D0C000B92940 -:103380007F0071201000CA707F00C670C370028079 -:10339000DB700F08DF700B00712000001B70010054 -:1033A000912080407800CF293C7F587E307C387D4A -:1033B000A0788E70927596749A769E7794A53F0049 -:1033C000F4D44000E62984A77D00C0001D44781095 -:1033D000B2299CA40F0082A304005000F129A6A3E7 -:1033E0000700C000B2291824078584A00F007900C7 -:1033F000F629713062318D31FF33E8376238173981 -:10340000A839963A853B092A062A422E652FB937F4 -:10341000062A7810B2297C0006A07800132A0878C2 -:103420008DC00A7806A002704E704670D27060702F -:1034300005A0C000792B647084A0070079001D2AC4 -:10344000252A982AA12AAC2AB72A5F2BC22A982AB1 -:103450003078BCD0C000082AD471BCD1C000082A82 -:10346000B4D1C000752AA47086A001004000082ACB -:10347000B4706DA0006865A055A09B7810000C6B1F -:10348000AA7B086845A0106D04686DA05DA086A8A1 -:10349000010040004B2ABC69AA7DAA79C0684DA0F2 -:1034A0001C6E012010007800D32C607005A0C000B5 -:1034B000082A7E0C7E0DB4706DA0006865A055A032 -:1034C0009B7810000C6BAA7B086845A0106D0468FF -:1034D0006DA05DA086A8010040006E2ABC69AA7D8F -:1034E000AA79C0684DA01C6E012020007800D32C62 -:1034F0007810B043C000082A1B785B00BC706DA038 -:10350000B4685A789468D678DE789868D278DA7891 -:1035100008788DC00A78BC684270B4C1D671B870A2 -:1035200065A0C0685A7003700200002D4E7080AD17 -:10353000090046707C007810B043C000A02A1B78B8 -:103540004700037004007C007810B043C000AB2A31 -:1035500011200C007810D22A037004007C0078102F -:10356000B043C000B62A112006007810D22A03709A -:1035700004007C007810B043C000C12A11200D0067 -:103580007810D22A037004007C007810B043C00089 -:10359000D12A112006007810D22A7C707F7000009A -:1035A00068204E70037001007C007471FCC10781BB -:1035B00082789B78100086A20C00C000E12AAA7ACB -:1035C000012001007800F62A8CA11F008DA1C00007 -:1035D000AA7986A20D004000EF2AAA7A01200200F3 -:1035E0007800F62AAB7820007871AA79AA7A0120AF -:1035F00004009B786000AA785B7804001B781601B1 -:103600007810D34383700F00D470B4D04000122BD5 -:10361000B4C0D6707E0CB87065A0086084A0EFFBC3 -:103620000A60186001801A607F0C7C00147005A08D -:10363000C000212BD470B4D04000222BB87006AC4F -:10364000C000222B7810012B7C007E01A47186A182 -:1036500001004000542B7E0D7E020021112001004C -:1036600012A2B4706820006806AC40003B2B1182A7 -:103670004000522B7810562B7800302B7E0C002106 -:103680001120010012A2B470682000686020086058 -:1036900084A0EFFB0A60118240004F2B7810562B5C -:1036A0007800422BA77001007F0C7F027F0D7F0105 -:1036B0007C00E8AD0500AC7006ADC0005E2BA870C4 -:1036C00068207C007810B043C000082A7C70682015 -:1036D000747778104E42502C781092449B781000EA -:1036E000146884A01F00BDC0AA781C6E4120010090 -:1036F000012004007800D92C7810B043C000082ABB -:103700009B78100060706820146FD470B4D04000B3 -:10371000932BB4C0D6707E0CB87065A0086084A0EE -:10372000EFFB0A60186001801A607F0C78104E422F -:10373000502C78109244246805A04000A42B82A04D -:1037400006004800A22B7800A42B27680500146807 -:1037500084A01F00BDC0AA783120200041200100B4 -:10376000012003007800D92C8DC2D672C07200A24D -:1037700015A0547108812AA14800BC2BC071642196 -:103780000465FF85C000D32B56712184C000B72B80 -:10379000D4708CD04000CF2BD07005A0C000CF2BB0 -:1037A000D3700A007C0000227800C12BD4708CC03A -:1037B000D670D3700000346005A0C000D02B08671D -:1037C00084A73F074000022CD4D7C000D02B84A789 -:1037D0002100C000D02B84A702004000F32B84A757 -:1037E00004004000D02BBCA7FBFF0A6784A7180287 -:1037F000C000D02B84A700014000022C186005A057 -:10380000C000D02BBCA7FFFE0A6768252368000014 -:103810001C6E84A60E0018634000132C1C6002A3CB -:103820004800162C4000162C7800D02BFF83C000D7 -:10383000D02B582D502C5671BCD7C0001F2C28708F -:1038400022603A60BCC70A67C06865A04DA00061ED -:10385000602A41200100146B9CA31F009DA3C0009F -:10386000FCD14000332C84D64000352C9CA3BFFFF4 -:10387000A4D640003A2C9DA3200084A60E00C000D0 -:10388000852CA5C70A67002CC668A47786A7010007 -:10389000C000592CD470B4D0C000592C007082A044 -:1038A0000200C800592C3078BCD0C000592C9B783D -:1038B0001000AA7B7800D12C3987A6775027B077E3 -:1038C000B0A70500AC7006A6C000642CA876B2763E -:1038D0003A2C38873A2D38873A2838873A23388760 -:1038E0003A253078BCD040007C2C9120008091207B -:1038F0003D30D47084A03D30912000809020D5AA26 -:1039000000004000842C21840022C000B62B7C00E3 -:10391000DCD14000493E292020009CD6C000922CDA -:1039200028858CD6C000922C28854088146F0C61A5 -:1039300008818CA1FF00CC7060A1642CFF8C40003A -:10394000B12C146006A7C0009A2CB8600180BA6040 -:10395000C000952C602A086085A000010A60002242 -:103960002184C000B62B7C00602A0E61BE69002C49 -:10397000C66840880860D5C00A60A47786A70100A1 -:10398000C000592CD470B4D0C000592C007082A053 -:103990000200C800592C3078BCD0C000592C9B784C -:1039A0001000AA7BAA7DAA79012002007E0018607F -:1039B00000801A607800DA2C7E0060290461602A99 -:1039C00084A118004000F62C84A110004000E92CCE -:1039D00078105E40C0001B2D84A108004000F62C2A -:1039E000A06984A10006C000F62C78103E3F780044 -:1039F0001B2DA06984A1001E4000262D84A1000873 -:103A000040000F2D7E0C6029006085A00020026020 -:103A100004618DA1100006617F0C78105E40C0002B -:103A20001B2DA06984A100024000172D7810A13F32 -:103A300078001B2D84A10004C000F22CA06984A191 -:103A400000104000262D14698CA100FF0F81781012 -:103A5000E6277F028CA6E00084A660004000332D9C -:103A600086A06000C000332D8DA100408DA104010F -:103A7000B6699B7860000028AA781868FDC01A68AB -:103A8000BCD640004E2DFCC0877000008AA00D00FF -:103A900050004C2D8AA00C00867101200C000C8077 -:103AA0008A71AA781835403328340080AC8080AF02 -:103AB0002B00A0209B78000080AD0B009820A6531F -:103AC000A8239828A02586A22000C000862DD470A7 -:103AD000B5C0D670002CBA70002DBE701468FCC042 -:103AE0000780827886A202004000BC2DA47000806E -:103AF000A670B47498A40500AC7006A3C0007E2D17 -:103B0000A873B67386A210004000082A7F0D7F0CB0 -:103B10007C00007005A0C000642D86A20200C000D9 -:103B2000D62D7810B043C000642D1468FCC0078007 -:103B30008278912000801B785B00B4685A78946882 -:103B4000D678DE789868D278DA7891200180087883 -:103B50008DC00A787E127E0D7E0CD47084A0002762 -:103B600090207F0C7F0D7F1200295A70BC68427034 -:103B700003700200002D4E7080AD09004670307851 -:103B8000BCD04000C82D91203D30D47084A03D3081 -:103B9000912000809020A47005A0C000CD2D7C0055 -:103BA00021844000CC2D5072C07000A215A0780076 -:103BB000B62B86A21000C000072E7810B043C000BC -:103BC000642D1468FCC0078082781B785B00B468A1 -:103BD0005A789468D678DE789868D278DA78087857 -:103BE0008DC00A78A4700080A670B47490A40500FB -:103BF000AC7006A2C000FA2DA872B67200295A70E5 -:103C0000BC68427003700200002D4E7080AD090048 -:103C100046707C00B46B9DA300205A7B1468FCC0E6 -:103C200007808278946BD67BDE7B986ED27EDA7EBC -:103C30001B785B0000295A70027208788DC00A78E0 -:103C4000002305A64000322ED47084A0002786A051 -:103C50000023C0002C2E0920000078002E2E092001 -:103C6000010084A20F007910382E80AD0900467043 -:103C7000002D4E707C00402E3F493F492C493F4962 -:103C8000402E402E402E7810B229087884A0FDFFE7 -:103C90000A787810A5297E0F7920004FAC787F0F25 -:103CA00084D040006A2E647086A00100C000582EA7 -:103CB00066707800412F647086A00500C000682EF1 -:103CC0007C7068201B68040017680000206884A0CE -:103CD000FF009DC0226867700000A7700000A870F8 -:103CE000B270B6707810012B7E151120040064713B -:103CF00086A1010040008A2E86A10700C000812E07 -:103D00001F70050078008A2E1F7001006770000088 -:103D1000D470DDC0D67078008C2E67700000012052 -:103D20000A4F042084A0FF0086A0180040009C2EAB -:103D30001870167005A0C0009C2EA77001007E06AA -:103D40007810D645A920100039200000781048418D -:103D5000B8A70001F000A32E7F0600707900AD2EF9 -:103D6000E72EC22EC22EB72EE72EE72EE72EB52E57 -:103D70007810B229607005A04000E72E06ADC000A3 -:103D8000C22E006862707800D42E206884D0C000F3 -:103D9000D02E146F78104E420860D4C00A6078109C -:103DA000193E7800D42E5C7060200068026084A602 -:103DB000005F1E681868FCD04000DC2E1A6A176885 -:103DC00000002B680000206884A0FF009DC02268CE -:103DD0007810732084B200044000EF2E2120D0968A -:103DE0007800F12E2120C0957810462F84B200046F -:103DF0004000FB2E2120984F7800FD2E2120584FA7 -:103E00007810462FA920010184B200044000092F38 -:103E10002120D09578000B2F2120C0947810462FB8 -:103E20002084F0000B2F84B200034000182F612083 -:103E3000C05478001A2F6120C07421200200A920EC -:103E400000011061FF814000372F18607E017E0065 -:103E50001120024F0C2202A112207F007F0102A13B -:103E60005000372F1260C000372F1120044F04225A -:103E7000A5C012201B600000E0AC1000F0001E2F57 -:103E80002184C0001C2F7F15037000004F700000BC -:103E90007C007E04042405A04000612F6820006897 -:103EA0007E001A6A176800002B680000B46884A0BE -:103EB000005F1E68206884A0FF009DC02268781003 -:103EC00073207F007800482F7F04232000007C00AF -:103ED00082A2030050006B2F7810B22900237900D2 -:103EE0006E2F712FFC2F193082A202004000772F15 -:103EF0007810B22964706770000083700000790048 -:103F00007E2F862F862F882FC82F553E862FC82FAD -:103F1000862F7810B2297477781048417477BCA73F -:103F2000008F78104E42186005A04000BF2FFCD7CC -:103F3000C0009B2F2120C09578009D2F2120D09676 -:103F40000920050011201000781034304000BF2FE8 -:103F50007E15A9200101FCD7C000AF2F2120C094FD -:103F60007800B12F2120D0957E0409200500112072 -:103F70001000781034307F044000BE2F2084F00001 -:103F8000B12F7F15388784A71F00C0008E2F7800BF -:103F90000C2A78000C2A747778104E42186005A01D -:103FA0004000FA2FFCD7C000D62F2120C095780002 -:103FB000D82F2120D096092005001120200078104C -:103FC00034304000FA2F7E15A9200101FCD7C00033 -:103FD000EA2F2120C0947800EC2F2120D0957E0478 -:103FE0000920050011202000781034307F044000A3 -:103FF000F92F2084F000EC2F7F1578000C2A002286 -:104000007900FF2F0230043004307810B2290920E3 -:104010001200647086A0020040000D3009200E00DE -:104020001868FCD0400012301A6967700000D47024 -:10403000DDC0D67078005D43002279001C3021304D -:1040400004301F307810B2297810D645007086A051 -:104050000200C000C73D7810363E086084A0EFFB28 -:104060000A607810B83D4000C73D78000C2A04244F -:1040700005A040006D306820042D7E00146806A75E -:1040800040004330202D7F00780035307F00222013 -:104090001A69176800002B680000B46884A0005FEC -:1040A0001E68206884A0FF0005A222687810732093 -:1040B0002120024F1C2419832223106001801260EA -:1040C000C00064302120044F0424A5C022200860D1 -:1040D00084A0EFF90A607810222B7810363E7C001D -:1040E00085A0010078006C300023790074307930AD -:1040F0007730F9307810B229E47805A0D000AF30DD -:1041000008327E000120044F0420ECD07F004000E4 -:104110008A308CA1000378008C308CA10004400010 -:1041200092301800082A780094302800082A0820C5 -:1041300084A03000C0009B307800B937EC7884A0B0 -:10414000030040009930002184A007007900A530C9 -:10415000D930E330CE30AD30A543A543AD30EE309D -:104160007810B229007086A00400C000C9306470C5 -:1041700086A00200C000BF301120020019200000FC -:104180007800652F647086A006004000B930647026 -:1041900086A004004000B930E479012003007800D3 -:1041A00043341868FCD04000D4301B681D007810E0 -:1041B00018411B7864007C001868FCD04000DF3098 -:1041C0001B681D0078101841780081431868FCD0E6 -:1041D0004000E9301B681D00781018411B78F8007A -:1041E0007C001868FCD04000F4301B681D0078107B -:1041F00018411B78C8007C0084A50F00C00018314E -:104200007810A5290070790002310C2A0A310C318E -:10421000C73DC73DC73D0A310A317810B229781031 -:10422000363E086084A0EFFB0A607810B83D40007D -:10423000C73D78000C2AE47805A0D000AF300832E2 -:104240007E000120044F0420ECD07F004000293183 -:104250008CA1000378002B318CA100044000313187 -:104260001800AF30780033312800AF30082084A028 -:104270003000C0003B311B785B007C00EC7884A0F0 -:10428000030040003831002184A107007900453146 -:10429000543158314F314D31A543A5434D319F43E2 -:1042A0007810B229781020411B7864007C007810C7 -:1042B000204178008143781020411B78F8007C0071 -:1042C000781020411B78C8007C00002379006531FC -:1042D0006A3168316C317810B2297800A8391B68CE -:1042E0001600A3780000E47984A130004000A839CA -:1042F000EC7884A003004000A83984A100014000AC -:10430000703184A10700790082318A315831CE3072 -:104310005D43A543A5435D439F43781069437C00FB -:1043200082A20500500093317810B2290023790051 -:1043300096319931C933D433002279009C31B6319A -:10434000A331B631A131AC337810B2299B78180073 -:10435000A87884A0FF0082A02000480007418AA01E -:104360000400C80007417900B23107410741074105 -:10437000B1409B781800A87984A180004000C73123 -:1043800078000741007005A0C000BD311120040075 -:104390007800933B84A1FF008AA01000C800074169 -:1043A0007900CF31E131DF31F631FA31CD320741D9 -:1043B0000741CF3207410741A833A83307410741DE -:1043C0000741AA337810B229E4D64000EC3101202D -:1043D0000003008000803A781B78C3007C001868D6 -:1043E000FCD04000F4311B681D007800E4317800F7 -:1043F0005D431B681D00780011412069226984A675 -:104400000018C0005F32206884D0C0006532186890 -:1044100086A00800C0000B321B680000D4D6400004 -:10442000CA32BCD640004B3287700000186884A0A6 -:104430003F008AA00D0050004B328AA00C0086710C -:1044400001200C000C808A719B786100AA787E158F -:104450007E137E147E0108328CA1000340003D32A1 -:104460007E000120044F0420ECD07F004000393250 -:10447000A1202B0178003F32A1202B0278003F328F -:10448000A1202B017F019B7800000080AC8080ADD3 -:104490000B009820A6537F147F137F15386005A06A -:1044A000C0005A321C6884A00E00400011417810F0 -:1044B00027412B78083078005C3201803A601B7805 -:1044C00067007C00E4D6400065321B7879007C00F0 -:1044D00084A660004000C732DCD64000C732FCD65C -:1044E000C000713278008832FCC65A7EB66EDC7A23 -:1044F000D879D0781B80C8007B32008084A03F0030 -:1045000008A191A20000986B002102A3B268946BED -:10451000002203A3AE68F4D640008E32F4C65A7E61 -:10452000B66E007086A00300C0009C327E0078103A -:10453000D64578103F497F001B7876007C0006A0A6 -:104540007810444AB06AAC69986C946B002205A15B -:104550004000AB32002222A400211BA3AA6CD27C13 -:10456000DA7CA66BD67BDE7B002305A4C000BB32C1 -:10457000F5C65A7EB66E1B7876007C001B787600F6 -:10458000002215A1C000C43278103F497C00781089 -:1045900077497C001B7879007C001B7867007C00E1 -:1045A0007810B22978001B332069C4D14000E4326E -:1045B000C4C122697E0C587060200060E4C00260B3 -:1045C000046084A0F5FF06607F0C78000F33CCD127 -:1045D00040000F33CCC122697E0C5870602000600F -:1045E000ECC002600460A4C006600820482C7F0C68 -:1045F0009CD140000F3378104A4278103E3FFF882C -:1046000040000F339B7860000028AA78587E95C63A -:104610005A7ED4D6C0000C331B7864007C001B7813 -:1046200078007C00587ED4D6C00016331B78670013 -:104630007C001B7879007C0078000C411920000078 -:1046400090798CA10700C0002933206884A0000164 -:1046500040001933092008009B781000A87894A026 -:10466000FF0086A20100C00045330023A87C00A4FF -:10467000182002A140003D3348003D3378003F330D -:104680007800D132A824A87AF0003F3378002B3389 -:1046900084A2F00086A02000C000993318831883FC -:1046A000002302A14000553348005533780096336B -:1046B00086A22300400019331C6884A0F1FF1E6805 -:1046C000587E84A6F1FFA5C030205A7E0860A5C0A0 -:1046D0000A607E0C5870602004600820482C7F0C13 -:1046E000A4D14000763378104A4278105E407800BA -:1046F00084337E0C5870602004600820482C7F0CA6 -:104700009CD140000F3378104A4278103E3FFF881A -:1047100040000F339B7860000028AA7895C65A7E27 -:10472000D4D6C00093331B7864007C001B787800DB -:104730007C00A87A78002B331883002302A1400064 -:10474000A2334800A23378002B3384A28000C0003B -:10475000114178000C4178001141780007415870F0 -:104760004DA09B781800A87884A0FF008EA00100BF -:104770004000B9337810B229A87A94A2FF00A87833 -:1047800084A0FF008AA00400C80007417900C53357 -:1047900007418F3E0741064082A20000C000CF3390 -:1047A0007810B229781018411B7878007C0082A21A -:1047B0000300C000DA337810B229FCD4C000FA3309 -:1047C000647005A04000E3337810B229146F767747 -:1047D000BCA7008F78104E42086085A021000A60B7 -:1047E000388784A71F00C000E73378101C4167702A -:1047F00002001F7009007800FC3378102B411B78F1 -:1048000078007C0082A20400500005347810B229A0 -:104810000023790008340B34CB350E3686A2030012 -:10482000400043340072D87CDC7DD07FD471BCD191 -:10483000C0003B34B4D140003B34687884A0FF0012 -:10484000C0003B3482A20200C8003B347E0D3B789E -:1048500000831B784C00BC706DA0B4685A789468D3 -:10486000D678DE789868D278DA78B4C1D6710370D9 -:1048700030007F0D01200000780047343B780013A2 -:104880001B784A0001200000780047340072D87C71 -:10489000DC7DD07F4A70A068ECD040004F340860C7 -:1048A0008DC00A6084A20F0079005334AB356034A8 -:1048B0005D3411379D370C2A5B345B347810B22994 -:1048C0000860D4C00A60E4D640006834487086A00E -:1048D0001400C00088347810D645092000001868FC -:1048E000FCD040007134487086A01400400082342F -:1048F000186886A00800C000633558789CD0400036 -:1049000063352068ACD0400063351B681400092073 -:1049100002007800C73468788CA0FF004000C734DC -:1049200086A10800C0009E340860A4C00A60781008 -:10493000B83D4000C7347810363E7810D645780030 -:10494000AF3486A12800C000C734186005A040001D -:1049500091340180400091340180400091341E6008 -:1049600078009134206884D040000C2A84C02268EA -:104970007810132B5C707E0C6020006802607F0C46 -:104980000460026805A0002DC000C4340260066007 -:1049900078000C2A7E01FF81C0001135007086A0CE -:1049A000300040001135D471BCD1C0001135B4D1F4 -:1049B000C000F834607005A0C0001135A47086A056 -:1049C000010040001135037000007E047E057E0763 -:1049D0007E067E0C7E0D7810352A7F0D7F0C7F06BB -:1049E0007F077F057F04D471B4D1C00011350370F7 -:1049F0004000780011357810B043C00011351B78A5 -:104A00005B007E0DBC706DA0B4685A789468D6784F -:104A1000DE789868D278DA78B4C1D6710370300045 -:104A200008788DC00A787F0D781048367F01FF81A5 -:104A30004000633584A600DF1E682B680000146FF9 -:104A400086A10200C0006435186886A01400C0006A -:104A50002D350820E4D640002D3568788CA0FF0065 -:104A60007810012B7810222B2068DCD0C000643530 -:104A7000178794A20F0013821382138284B200035B -:104A80004000433590A2C0537800453590A2405471 -:104A900090A200001C22C4D3C0004D3578005335CD -:104AA0001082042285A0180012201182D4D3400065 -:104AB0005E35A068C4D0C0005E357810C23678007C -:104AC0000C2A08608DC00A60780064352A6916696E -:104AD0001868FCD040006B3548701A688CA600DF5F -:104AE0001E691064FF84400080350920024F0421B4 -:104AF00001800A2021841264C00080352120044FE7 -:104B00000424A5C02220186005A04000883501803B -:104B10001A60C0008B350860A4C00A60206884D089 -:104B2000C0009735006805A0C0009435026006609B -:104B300078009B355C706020006802606120004F47 -:104B400087680301082D6B200000686005A06A617A -:104B50004000AA35022D7800AB356E61007286A246 -:104B600030004000BB3586A24000C0000C2A037014 -:104B700002004C706820C46860207C000370020052 -:104B8000BC706DA0BC684270B87065A0C0685A70F7 -:104B9000002D4E7080AD090046707C0082A204009A -:104BA0004800D1357810B22900227900D435D835A3 -:104BB000E935F635E93586A500134000E93586A5C7 -:104BC0000083C000CF3503700000186001801A60B8 -:104BD000086084A0EFFB0A60007086A0050040001A -:104BE000F335781018411B7878007C001B78790029 -:104BF0007C0090780780018084A0070080A01800C6 -:104C00009A78A8798CA1FF0086A1030040000B369A -:104C100086A1000040000B36780007411B78790020 -:104C20007C00206895C02268FF82C000183678108A -:104C3000184178001F36118240001D367810B229C5 -:104C400078102B411B7878007C007810D3433078A3 -:104C500084A0C000C00045367E0108327E000120DD -:104C6000044F0420ECD07F00400037368CA10003B5 -:104C7000780039368CA100047F01400040361800CE -:104C8000453678004236280045361A7906A07C0061 -:104C900085A001007C0084A66000C00052362F6809 -:104CA0000000336800007800C136DCD6C0006A36E8 -:104CB000B468DCD0C0006A369869946A2E69326A9A -:104CC000487005A0C0006736002205A14000D64507 -:104CD0004B7015007800D6457C00ACD6400090366D -:104CE000F4D6400076362F68000033680000780064 -:104CF000D645B46884A0004035A6F4D6C00070360E -:104D0000487005A0C00083364B701500DCD6C0008B -:104D10008C36B468DCD040008C36A86CA46D2E6C48 -:104D2000326D7800D645F4D6400099362F680000E1 -:104D3000336800007800D645B46884A0004835A6E2 -:104D4000F4D6C0009336487005A0C000A6364B705C -:104D50001500082410250027FB80C800AD36008010 -:104D600084A03F0008A191A200002E69326A0021B0 -:104D700005A2C000BA367800D645007086A00600AD -:104D80004000C1367800D6457C0046690860CDC039 -:104D9000CCD34000C9368DC00A6018683A681B68D9 -:104DA00006008F68000093680000306A2C693E6A34 -:104DB00042692F6803003368000037682000976855 -:104DC00000009B68200000707900E3360C2AF5365D -:104DD000ED36EB36EB36EB36EB36EB367810B229A8 -:104DE000206884D0C000F5367810193E7800FB3674 -:104DF0005C70502C602000680260602A08328CA130 -:104E00000003400004372120584F78000637212046 -:104E1000984F042405A040000D3720207800063765 -:104E2000222D6B2000007C007810203E7810363E4A -:104E30000860CCC00A602B6800009B780E00146FDD -:104E400038691A694469166908328CA10003400068 -:104E50002A370920000078002C370920010078103B -:104E6000814ADCD6400034371C69EDC11E691868E0 -:104E7000FCD04000433768788CA0FF0040004137E9 -:104E80001B681E00780043371B68000084B20003D3 -:104E9000C0004B372120984F78004D372120584FC4 -:104EA000006822203C6A4069326A2E69C06860202E -:104EB0000060A4D040008D3741202100492005002A -:104EC000512020007E0D7E0F7E157E147920004F2C -:104ED0007810461E7F147F157F0FCC70102009209C -:104EE00001017E0204226DA040007D37146806A7F0 -:104EF00040007A370068780070372068D5C0226893 -:104F00007F0210820981C0006E377F0D6770030039 -:104F10007F700000767783700F00D471DCC1D6718A -:104F2000186886A00200C0009937176800002B6837 -:104F300000001C68ECC01E687810732078000C2AF2 -:104F4000D87CDC7DD07F781048362B6800009B78B9 -:104F50000E00146F7810D7438CA0FF0016691868F4 -:104F6000FCD04000B23748701A688CA600DF1E697A -:104F70006770000078000C2A007005A0C000BF37E1 -:104F800078000C2A06A07810D6452069ACD1C00064 -:104F9000C8371B6814008CA600DF1E692B68000050 -:104FA000206884A0FF00226800707900D4370C2AA2 -:104FB000DE37DE37E137E137E137DC37DC377810D1 -:104FC000B2291868780043340860A4C00A601768E2 -:104FD00000007800DE3D00237900EB37EE37F03734 -:104FE00060387810B229FCD6C000473800700DA098 -:104FF0007900F7370C2A0138013831380138443844 -:10500000FF37FF377810B22984A66000400031389E -:1050100086A06000C0002E38ACC6F4C6EDC65A7E2D -:10502000B66E1C68ACC01E6886A102004000203825 -:105030007810D645AC69B06815A1400020387810CA -:1050400077497800223878103F491B787900D4716D -:10505000B4D1C000082AA47086A00100C000522A62 -:105060007C00ECD640000B381868FCD04000443877 -:10507000F4D6C0003E381B6815001B787900780014 -:10508000082A1B6807002F680000336800007810AA -:1050900069437C00FCC65A7EDC7AD879D0781B80C4 -:1050A000C8005038008084A03F0008A191A20000F1 -:1050B000986B002102A3B268946B002203A3AE6830 -:1050C0001B7879007C007810B229002379006538BC -:1050D0006A388F38EF387810B229007079006D384F -:1050E000753877388038753875387538753875384B -:1050F0007810B229AC69B06815A1400080387810EA -:1051000077497800823878103F491C68B4C01E681F -:10511000D470B4D0C000082AA47086A00100C000DA -:10512000522A7C00FCD6C000DF3800700DA0790048 -:1051300096380C2AA638A038D638A638DC389E38DF -:105140009E387810B2299468D678DE789868D2783C -:10515000DA7884A660004000D63886A06000C000DF -:10516000D338B4A6BFBFEDC65A7EB66E86A1020084 -:105170004000C2387810D645AC69B06815A140002F -:10518000C238781077497800C43878103F491B78C6 -:1051900079001C68B4C01E68D471B4D1C000082A5C -:1051A000A47086A00100C000522A7C00ECD640000A -:1051B000B0381868FCD04000DC381B6807001B784A -:1051C000F9007C00FCC65A7EDC7AD879986B002105 -:1051D00002A3B268946B002203A3AE68D2791B7855 -:1051E00079007C00DCD64000F8382B7809301B7839 -:1051F00079007800082A8478ACC08678E47884A0A6 -:105200000800C0000B3984A4000240000539F5C62F -:10521000DDC65A7E1B7879007800082A206895C080 -:1052200022687810E242DDC6781018411B787800B9 -:105230007800082A002379001A391D391F392139CD -:105240007810B22978001141D4D6C0005C39E479D5 -:10525000ACD140002F39EC7884A0030040002F39F6 -:105260002B7809309B786000AB78000084A6FBFFA8 -:105270005A78E479ACD140003F39EC7884A003003F -:10528000C00058390120044F0420E4D0C000543934 -:105290002068C4D0400054397E0C587060200460EF -:1052A0009DC00660086084A0FF000A607F0C01209A -:1052B00014007800433484A1070079009239907A71 -:1052C00094A207009B786000A879FF814000903984 -:1052D0009B781000A87B84A30100C0008339A87BC1 -:1052E000A87B86A30100C00076390920F7FF78006B -:1052F0007C3986A30300C00083390920EFFF7E0CB0 -:1053000058706020046004A106607F0C9B786000E8 -:10531000AB78000084A6FBFF5A782B78093020690F -:105320008CA1FFFC226978005D43D930E3309C39C1 -:10533000A2399A399A395D435D437810B2292069C0 -:105340008CA1FFFC22697800634320698CA1FFFCDB -:10535000226978005D43E47984A130004000B239CD -:10536000EC7884A00300C000E639007086A0040039 -:10537000C000CC39647086A00200C000C239112080 -:105380000200192000007800652F647086A00600D6 -:105390004000BC39647086A004004000BC39007035 -:1053A00086A000004000082A206984A12004400053 -:1053B000DB39D4C1226918687800433418688EA09C -:1053C00002004000E439FDC01A6801201400780092 -:1053D000433484A107007900EA395D435D43F23923 -:1053E0005D43A543A5435D435D43BCD64000343ACD -:1053F0008471FF814000343A82A10D00D000013A4F -:10540000877000007800063A82A10C00867009209F -:105410000C009B786100AA797E157E137E1488703B -:10542000148110A28A7280A00B0000AD982084B273 -:1054300000034000283A7E000120044F0420ECD0F5 -:105440007F004000243AA1202B0178002A3AA120B5 -:105450002B0278002A3AA1202B019B7800000881BA -:10546000AC81A6537F147F137F1578006343D4D695 -:10547000C000883A206884D0400063438CA6600056 -:1054800084A660004000463A86A06000C000463A0C -:10549000F5C194C15A79B6699B786000AB78000079 -:1054A0009B7861001868FDC01A68AA7808800C8192 -:1054B00040004F3E8CA1F800C0004F3E7E157E1389 -:1054C0007E147E0108328CA100034000743A7E00F5 -:1054D0000120044F0420ECD07F004000703AA1204E -:1054E0002B017800763AA1202B027800763AA12091 -:1054F0002B017F019B7800000080AC8080AD0B0009 -:105500009820A6537F147F137F151468FCC0078072 -:105510008278780063431868FCD040008E3A1B689C -:1055200008002068ADC02268781020411B78EA008E -:105530007C0000237900993A9E3A763B9C3A781099 -:10554000B229D87CDC7DD07FFF82C000C73A0072D0 -:1055500086A2030040001034D471BCD1C000CA3A06 -:10556000B4D14000CA3A7E0D3B7800881B784C00CD -:10557000BC706DA0B468A5C05A789468D678DE78FF -:105580009868D278DA78B4C1D671037030007F0D94 -:105590007800CE3A00727800CE3A3B7800181B783B -:1055A0004A0084A20F007900D23A613B103BDC3AFA -:1055B0003F34DA3A613BDA3ADA3A7810B2291C68B9 -:1055C000ECD04000E33A08608DC00A60206985C1D4 -:1055D00022690068066005A0C000EC3A026008601D -:1055E000D4C00A601C6884A00E00C000003B84B2D6 -:1055F00000034000FC3A0920C0957800053B0920D3 -:10560000D0967800053B3070BA684071CC7008A124 -:10561000042102680A2D5E71DCD6C000103BFCC676 -:10562000B66E7800613BB66E84A66000C0001A3B7F -:1056300084A6FF7FB6687800613BDCD6C000283BBB -:1056400084A6FF7FB6689468A6689868AA687810F0 -:10565000D6457800613BACD64000343B06A07810BC -:10566000D64508241025AA69A66A7800443B082478 -:10567000102500271B80C8003B3B008084A03F0012 -:1056800008A191A20000AA69A66A7810D645FCD6A6 -:105690004000613B84A6FF7FB66810250824ACD685 -:1056A000C000593B00271B80C800543B008084A0E9 -:1056B0003F0008A191A20000986B002102A3B268EC -:1056C000946B002203A3AE68007086A03000C00077 -:1056D0000C2A03700200BC706DA0BC684270B870E8 -:1056E00065A0C0685A70002D4E7080AD09004670EC -:1056F0007C0086A50088C000833B03700000186012 -:1057000001801A60086084A0EFFB0A6078001141F4 -:105710004770000082A2060050008D3B7810B2292D -:1057200000237900903B933BA53BB13B00227900DD -:10573000963B9C3B11419E3B9C3BEB3B403C781095 -:10574000B229807A94A2000F7810CA3C78000741F1 -:105750007810C23B7900A93B1141AF3BAF3BEB3B1B -:10576000AF3B11417810B2297810C23B7900B53BAC -:10577000BD3BBB3BBB3BBD3BBB3BBD3B7810B229FC -:1057800078102B411B7878007C00007086A0020006 -:10579000C000D33B7810363E7800CD3B7810D6451C -:1057A000086084A0EFFB0A607800D83B007086A0F8 -:1057B00003004000CB3B0370050084B200034000AF -:1057C000E23B0120E0967800E43B0120129768203C -:1057D0004E7080AD0900467000227C00007086A0EB -:1057E0000200C000FD3BD470B5C0D670002CBA706A -:1057F000002DBE707800023C7810D6457800023C3F -:10580000007086A003004000F93B03700100807A1D -:1058100094A2000F9B781800A87C84A41F0015A2F6 -:105820006920C09584B20003C000163CFDC2692007 -:10583000D096042D082D5E716DA04000233C1468A5 -:1058400006A24000253C00687800173C7810CA3C4E -:10585000B46E5A7E206984A1000C4000F43C647050 -:1058600086A00600C000373C747006A2C000373C1A -:1058700066707E701B680500ADC1D4C122697810C6 -:1058800020417800F43C007286A20200C000523C25 -:10589000D470B5C0D670002CBA70002DBE707800E0 -:1058A000563C7810D6457800563C86A2030040004E -:1058B0004E3C03700100807A94A2000F9B78180080 -:1058C000A87C84A41F0015A284B20003C000663C1B -:1058D000FDC2A879A8798CA1FF001821CC7068A11D -:1058E000042D082D5E716DA040007A3C146806A25C -:1058F0004000A33C006878006E3C0370050084B251 -:1059000000034000843C0120E0967800863C0120A2 -:10591000129768204E707E15A920320003200000E7 -:105920000080F0008B3C7F1584B200034000983C5F -:10593000FCC27800993CFDC2166A80AD0900467031 -:10594000B76800072368000827680300B46E206961 -:1059500084A1000C4000F43CDCD04000BF3C6470EB -:1059600086A00400C000BB3C747006A2C000BB3C13 -:10597000787006A3C000BB3C66707E70781027412B -:105980007800F43C1B680500ADC1D4C122697810D1 -:1059900020417F7000007800F43C0370050084B261 -:1059A00000034000D43C0120E0967800D63C012062 -:1059B000129768204E707E15A92032000320000047 -:1059C0000080F000DB3C7F1584B200034000E83C1F -:1059D000FCC27800E93CFDC2166A80AD0900467041 -:1059E000B768000723680008276803007C00ECC63E -:1059F000ACA660004000463D986B946CAC69B06802 -:105A000005A1C000213DD27BDA7BD67CDE7C86A559 -:105A1000600040004B3DF4D6C0000C3DEDC6B4A67E -:105A2000FFB75A7E092079009CD64000193D092015 -:105A300078001920000020231A79ECD64000563D4A -:105A400078103F497800563DB0681AA3002123A47E -:105A5000002405A340004D3DD27BDA7BD67CDE7C62 -:105A6000B068F4D6C000323DEDC6F4C65A7E1120AF -:105A700079009CD640003E3D11207800192000009E -:105A800020231A7AECD64000563D781077497800EA -:105A9000563D19200000202378004D3DB4A6FFB7E5 -:105AA0005A7E092079009CD64000553D0920780097 -:105AB0001A79C0685A70002D4E70C4686020D47185 -:105AC0000120014F0420C4D0C000AB3DD8702DA0F0 -:105AD0004000843DBCD140009E3D807A94A2000FDE -:105AE000DC7006A24000753DE07804A5C000AB3D27 -:105AF000DA70BCC1D6717800AB3D312001002C8535 -:105B00004800833D3386108278007C3D7C00E07D38 -:105B100094A500FF4000913D112008002F857810CA -:105B20007A3D37867800933D78107A3D17828078E9 -:105B300084A0000F06A24000AB3DDE72DA7678004A -:105B4000AB3D807A94A2000FDC7036A240009B3DF2 -:105B5000E07834A540009B3DBDC1D671B4D1C000F2 -:105B6000082A002305A44000082AA47086A001008A -:105B7000C000522A7C00206005A04000C63D018084 -:105B80002260086085A008000A600F7000012C7078 -:105B900026607C0006A07810D645007086A0020022 -:105BA0004000D43D647086A00500C000DE3D2B6837 -:105BB0000000176800001B680100236840001F6890 -:105BC0000001007084A00F007900E33D0C2AF33D32 -:105BD000ED3D153EFD3D0C2AEB3DEB3D7810B22925 -:105BE0007810203E7810193E7800F93D7810203E5C -:105BF0005C706020006802607810732078000C2AC6 -:105C0000647067700000837000007900043E113EEC -:105C1000113E0C3E0C3E0C3E113E0C3E113ED47724 -:105C2000DDC7D67779007E2F6770000078000C2AD8 -:105C30001B68000078001137006805A0C0001E3EF8 -:105C4000026006607C001064FF844000323E092040 -:105C5000024F042101800A2021841264C000323ED8 -:105C60002120044F0424A5C022200860A4C00A609B -:105C70007C00186005A040003C3E01801A607C005A -:105C80007810D3431B68180078007D3E7810D3430A -:105C90001B68190078007D3E7810D3431B681A00FA -:105CA00078007D3E7810D3431B68030078007D3E6A -:105CB000747778104E4278718CA1FF00103294A254 -:105CC00000034000643EE8A1C0947800663EE8A16D -:105CD000D095042D082D682005A0C0006F3E7E7071 -:105CE00078000C2A1468747206A24000773E00689F -:105CF0007800673E00680A201B6805007F7000007E -:105D00007810203E206884D0C000853E7810193E6F -:105D10007810363E1F68000023682000781073203A -:105D200078000C2A82A20300C0000741A87DACA520 -:105D3000FF005A7EA87EB4A6FF002069BDC122697B -:105D4000C4D14000EA3EC4C12269B4A6FF004000AD -:105D5000D73E82A60C004800AE3E4000AE3E312049 -:105D60000C00002586A00A004000B53E2B852B853F -:105D70007810E0414000BD3E7810BC3F7800E03E26 -:105D800078109B417E0C6029046084A0F5FF0660BA -:105D90007810F23F7F0C2069C5C12269587E95C6F4 -:105DA0005A7ED4D6C000D43E1B7864007C001B7899 -:105DB00078007C007E0C6029046084A0F5FF0660FA -:105DC0007810F23F7F0C587ED4D6C000E73E1B7897 -:105DD00067007C001B7879007C007E0C5870602086 -:105DE0000061E4D14000333F0862178294A2FF00B3 -:105DF00082A20C004800FD3E4000FD3E11200C0038 -:105E0000002602A2C800023F3022086294A2FF00CE -:105E10000120054F0420E4D0C000173FEC78E4D007 -:105E20004000173F82A20A00C8001D3F11200A004F -:105E300078001D3F82A20C00C8001D3F11200C00FD -:105E4000002202A5C800223F282278109F41002589 -:105E500086A00A0040002B3F2B852B857810E0415F -:105E60004000333F7810BC3F7800373F78109B41AB -:105E70007810F23F587895C05A787F0C1B787800DC -:105E80007C007E0C60290060E4D0C000583FB4D094 -:105E9000C000523F106084A00F00C000523F046158 -:105EA0008CA1F5FF06617F0C7C00112032001920C7 -:105EB00000007800833FA068CCD0C000523F086249 -:105EC00094A2FF000120054F0420E4D0C000713FE0 -:105ED000EC78E4D04000713F82A20B00C800713F13 -:105EE00011200A007800773F82A20C00C800773F9B -:105EF00011200C0008631F839CA3FF0082A30C00E9 -:105F00004800833F4000833F19200C00AB7801001C -:105F1000AB780300AB780100AA7AAA7BC0A8050081 -:105F20002068C5C02268D470B4D040009F3FB4C080 -:105F3000D670B87065A0086084A0EFFB0A60186096 -:105F400001801A607F0C7C007E0C602904618CA1AA -:105F5000F5FF066111203200192000007800AD3FE6 -:105F6000AB780100AB780300AB780100AA7AAA7B7A -:105F7000C0A805002068C5C022687F0C7C007E0C8C -:105F80005871602118208CA020004000C53FACC093 -:105F9000082084A0F0FF35A6867E18609A78AE7E31 -:105FA0001266A47884A0F0FF8CA10F0005A1F4C0B4 -:105FB0009CA320004000DB3F85A00040FCC0B4D083 -:105FC000C000E03FFDC0A67816608A78B4A60F0036 -:105FD00037860482048084A0FF0005A60E6004605A -:105FE00084A0F5FF06607F0C7C007E0C587060205A -:105FF00018609A78A47884A0F0FFA678126084785C -:1060000084A0F0FF86780C6084A0FF000E607F0CF7 -:106010007C0082A20200C0000741A87A2069BDC1AD -:106020002269CCD140004140CCC1226994A2FF003A -:1060300082A20200C8000741781094407810F23F15 -:1060400080A901000C2078104A4278103E3FFF885A -:10605000400037409B7860000028AA78587E95C69B -:106060005A7ED4D6C00034401B7864007C001B7874 -:1060700078007C00587ED4D6C0003E401B78670074 -:106080007C001B7879007C0082A20200C800494095 -:1060900084A2010040005240587188A100000C21E8 -:1060A000ECD1C00052401120000078107C417810E3 -:1060B00094407810F23F587895C05A781B78780051 -:1060C0007C007E0C7E026029006011200100ECD073 -:1060D000C0007540BCD0C00073401460B4D0C00094 -:1060E0007340A4C1066106A0780091401120000011 -:1060F000AB780100AB780200AB780300AA7AC0A8A5 -:106100000400D470B4D040008D40B4C0D670B870D4 -:1061100065A0086084A0EFFB0A60186001801A6027 -:10612000206885A0000222687F027F0C7C007E0C24 -:1061300058706020FF8240009C4011204000186091 -:1061400080A002009A78A47884A0BFFF05A2FCC0BA -:10615000B4D0C000A940FDC0A67816608A7804605B -:10616000A4C006607F0C7C007E00007086A0030047 -:106170004000BA407F007800BD407F0078000441B5 -:10618000ACD640000441887884A04000400004411F -:10619000B87B84A33F001B83C800CC40008005A0CF -:1061A0004000E1401B83C800D54001804000014110 -:1061B000F4D64000E140B8781B80C800DD40008084 -:1061C00084A03F00C0000141F4C65A7ED879DC7A31 -:1061D0000120010008A1C800EC4091A20000D27982 -:1061E000DA79D67ADE7A7810444A1B78760084B25F -:1061F00000034000FC40012000007800FE40012028 -:1062000001007810CE487C001B7876007C001B785B -:1062100079007C0078102F411B7878007C00781082 -:1062200018411B7878007C00276802007810204114 -:106230001B7878007C0001200500780031410120A6 -:106240000C00780031412068D5C02268012006008A -:106250007800314101200D00780031410120090012 -:1062600078003141012007009B787E00AA789DC606 -:106270005A7ED470B4D040004741B4C0D6707E0C72 -:10628000B87065A0086084A0EFFB0A601860018008 -:106290001A607F0C7C007E073F87BCA70F003B87FE -:1062A0003B8703877E018CB2000340005841E0A089 -:1062B000C05378005A41E0A040547F01B8A72000A5 -:1062C0009A7FA47984A10F0040006A4184A1F0FF65 -:1062D000A678126004609DC00660388738879A7F70 -:1062E000A47984A1400040007A4184A1BFFFFDC091 -:1062F000A67816600460A5C006607F077C009B78C6 -:106300001000AB780100AB780200AB780300AA7AEA -:106310009B786000AB780400D470B4D040009A4100 -:10632000B4C0D6707E0CB87065A0086084A0EFFB86 -:106330000A60186001801A607F0C7C003120000028 -:10634000292032009B781000AB780100AB78030065 -:10635000AB780100AA7DAA7E9B786000AB7805002F -:10636000D470B4D04000BE41B4C0D6707E0CB870BA -:1063700065A0086084A0EFFB0A60186001801A60C5 -:106380007F0C7C007E15078084A0FF0003800380C3 -:1063900080A020009A78A4798CA1F0FF21203342BC -:1063A00019201100A9200E0011203200042484A01D -:1063B000F0FF06A14000DE412084002310A2F0007F -:1063C000D3417F157C007E150120054F0420E4D0C9 -:1063D000C000114221204142A920090011202800BB -:1063E00082A5190040002742480027422084A99531 -:1063F0001120320082A53200400027424800274287 -:106400002084A99519200A0011206400002202A509 -:1064100040002742480027422084002310A2F000B9 -:1064200003427F15780025422120334219201100B4 -:10643000A9200E0011203200002202A540002742B0 -:10644000480027422084002310A2F00019427F1543 -:1064500006A07C007F1582A56400C8003042087841 -:1064600085A070000A78042405A07C00091202307F -:106470000232034203440454045605660568067854 -:10648000067A070C070C070EE1100A330558055A67 -:10649000066A066C077C077E000E9B78100046A0FB -:1064A0007C0084A7000F0B8084A71F00038003805B -:1064B0000380038005A1FCD740005F42E0A0C074C8 -:1064C00078006142E0A0C0547C007E0E7E0F84D034 -:1064D00040006F42792000010920804F7120804FD9 -:1064E00078007F420920404F7120404F0120044F27 -:1064F0000420ECD040007D427920000178007F42EA -:106500007920000291200080042184A00F007900EE -:1065100086429042904290429042904290428E42F7 -:106520008E427810B229B469F5C18CA19FFFB6697B -:1065300005A04000DF42587884A09FFF85A000603E -:106540005A78287886A01418C000DF424B780400DF -:10655000487884A00400C000A5424B780800487821 -:1065600084A00800C000AC423078BCD0C000DF423C -:106570007E000120044F0420ECD07F004000C14287 -:1065800084B200037800C34284B200044000C942D0 -:106590001800DF427800CB422800DF42E47984A172 -:1065A00030004000DF42EC7884A003004000DF426E -:1065B0001C68ACD0C000DD42781069437800DF422F -:1065C0001B78F9007F0F7F0E7C007E0C0120014FAD -:1065D0000420ACD0C0005B431468078084A00F0087 -:1065E0000380038003808CB200034000F842E0A0E7 -:1065F000C0537800FA42E0A04054046084A00A002E -:10660000C0005B43086194A100FF40005B438CA184 -:10661000FF0001200A0006A14000264301200C00D3 -:1066200006A140002A430120120006A140002E438B -:106630000120140006A1400032430120190006A1E8 -:10664000400036430120320006A140003A43780062 -:106650003E4309200C0078004043092012007800D6 -:1066600040430920140078004043092019007800B5 -:106670004043092020007800404309203F00780073 -:10668000404311200000002105A20A60046085A09B -:10669000020006606120004F0460BCD040005B43F4 -:1066A0001468FCD0C0005643EA606120404F780077 -:1066B0005943EE606120804F1F600F807F0C7C008B -:1066C0001B7879007C001B7878007C001B786700C1 -:1066D0007C001B7864007C000920194F0C2186A1E6 -:1066E000000040007B4386A1010040007E431F70F4 -:1066F0000B00677001001B7847007C001B78F000DE -:106700007C001F700A007C000920194F0C2186A113 -:1067100000004000964386A10100400093431F7093 -:106720000B00677001001B7847007C001F700A0097 -:106730007C001B78EF007C001B78F9007C001B7844 -:10674000F8007C001B78C9007C001B78C8007C0026 -:106750001868FCD04000AB431B681D006770010047 -:106760001B7847007C00307884A0C000C000D24372 -:1067700008788CC00A780500050005000500EC7853 -:1067800084A02100C000CF430120054F0420E4D0A5 -:10679000C000CD43047884A01FFF85A0E0000678E8 -:1067A00006A07C0008788DC00A787C0008788DC02F -:1067B0000A787C00307884A04000C000D7430120D4 -:1067C000044F0420ECD04000E64384B2000378007C -:1067D000E84384B200044000EE439800F24378009E -:1067E000F043A800F243AC787C00087884A0FDFF59 -:1067F0000A780500050005000500EC7884A021005A -:10680000400015447E000120044F0420ECD07F009E -:1068100040000B4484B2000378000D4484B20004AD -:106820004000134498000F4478001544A800134416 -:10683000AC787E00087885A002000A787F007C0092 -:1068400084A70100C000B93784A7700040002D4420 -:106850007E0C602D682F78102629782D682C7F0CEF -:1068600084A7080040003A444B780800EC7884A0E4 -:1068700003004000B93778005D4384A7040040005E -:106880006944B87884A00140400069444B7808000E -:10689000EC7884A003004000B937E47884A00700B6 -:1068A00086A00100C0006944C07885A60048302059 -:1068B0005A7E1B78F9007C004B7808001868FCD0E1 -:1068C000400066441B681500F4D6400066441B680F -:1068D0000700781069437C001B680300587884A087 -:1068E000003F1E682F680000336800004B780800E6 -:1068F000EC7884A003004000AF307E000120044FFC -:106900000420ECD07F004000864484B2000378006D -:10691000884484B2000440008E441800082A78009D -:1069200090442800082A78000C41146B078384A047 -:106930000F00038003800380FCD34000A04480A0AC -:1069400040547800A24480A0C053602048205A7070 -:10695000602A7C00200020000000200000002000B1 -:1069600000002000000020000000200000002000A7 -:106970000000200000002000000020000000200097 -:106980000000200000002000000020000000200087 -:106990000000200000002000620009001400140024 -:1069A0004898140014001499FD98140014008000F5 -:1069B000FF0000010204082080F818000AA2140059 -:1069C0000B300CA21400002513000025100010004D -:1069D0001000100010001000100010001000100037 -:1069E000100010001000100000A2063802715F8035 -:1069F00081943988C420640856A80830C1281B9D9A -:106A000001A20C30472861816A840080A484561852 -:106A10003A8808A8E228CB9CF3A8640844A80C3064 -:106A200001A80830E128CB9C21201DA805A20C87D5 -:106A3000DED8A064E06DC06FA463806C120205A272 -:106A40003D8842792080A1A42B8814183B88DF80E0 -:106A5000A1942770F28537A732A503F07685778653 -:106A600016A83E8814A8012012A804A2C064E06DF4 -:106A7000A067C06F42792080A1A41418DF80A19480 -:106A80003B8823707685778602A861783E886B20E4 -:106A9000C1281B9D44200321A2208120C3A807A256 -:106AA00004090EA209A803A20080A48572189A877F -:106AB0003C88E21F01F608A26E856F8661711400A2 -:106AC00004070830CB9C140002A20080A485093082 -:106AD000A884E21944F86E853F88E608F5A861F8B5 -:106AE000EAA801F8140081F81600B285F08032950A -:106AF000A2FAE21D1400328521F21400E21DA884DE -:106B0000E0D6E61F1400083000804A281110FCA8C7 -:106B10000830339D008000A002281110FDA8399D87 -:106B2000BDA80830339D3B281110FDA809A20271B1 -:106B30005F80819417000C3009A20080A485E21DBB -:106B400009A2C1DA1400100201A81400E0263A8755 -:106B5000A3FAF219E026F21814000BA214000DA2F9 -:106B600006381002259D040706A265687E812A84E6 -:106B7000C11D2388160042600880FAA80080A48402 -:106B800060812A8421F00830A884D6114270DD206B -:106B90001100D420228816004479218420A032A537 -:106BA000A184160044792184DFA03295A1841600C7 -:106BB00000007E12D47084A00046048090200472ED -:106BC00008709CC005A2C00002460C72FF82400003 -:106BD000ED45FF8AC0000246007284D2C000024622 -:106BE0000478CCD04000F3457810CC4A23700000E4 -:106BF00027700000007084D04000FD45077004003D -:106C0000037008007F1200207C00007084A0030045 -:106C100002709CC684D040005B4608710500087075 -:106C200006A1C0000A4684A1030040008C4684A14E -:106C3000E001C0008C46F4D1C0000A4684A10030B7 -:106C400086A0001040000A460120054F0420E4D031 -:106C500040003746112080010C71118240004546EA -:106C60000870F4D0C0000A460C7006A140002A4605 -:106C700078002746112080010C71118240004546A2 -:106C80000870F4D0C0000A460C7006A140003A46D5 -:106C90000770120008710500087006A1C000474681 -:106CA00084A1030040008C4694D140004746F4D1B3 -:106CB00040008C460770020078000A460871FCD13B -:106CC000400066467810ED47FF8A4000DC457800BA -:106CD0005B460C708CA0FF0340009146047084D08A -:106CE00040008346147005A0C0007F4610701073EA -:106CF00006A3C0007346002305A04000834602A1FE -:106D0000C8005B460770100078008C46FF8A400080 -:106D100091467810F249C000864640005B467810E4 -:106D200038477F1200207C00047208719CC10381E7 -:106D3000C800A04607700200780091460370080062 -:106D40007F1200207C0005A2C0008C46237000004A -:106D500027700000037008007E000120014F04200E -:106D6000CCD04000B2467810CC4A7F007F12002081 -:106D70007C002864FF844000E246702C0470BCA0B4 -:106D80000F00B8A7F2463C27FB87C000D04648005A -:106D9000C8467810B2299C6075A04000E246780091 -:106DA000BB463920E746042768AE086830A60C6861 -:106DB00029A521844000E2463887042705A0C000A9 -:106DC000D1469C7075A0C000BB467C000000050049 -:106DD00009000D001100150019001D00000003003E -:106DE00009000F0015001B0000000000E746E44604 -:106DF0000000000000800000E7460000EF46EC467F -:106E00000000000000000000EF460000EA46EA46ED -:106E10000000000000800000EA460000F046F04656 -:106E20000000000000000000F0467920004F7120B3 -:106E3000100007700A00077002000370010010784C -:106E4000ECD0400026470920010071202000780086 -:106E50002A47092002007120500007700A000770BD -:106E600002000370000009814000374771202000B4 -:106E700078002A477C0004700480C800C14708716C -:106E8000087006A1C0003C4784A1E00140004947CA -:106E9000781030487800E947077012001920000088 -:106EA0000871087006A1C0004D4784A1E0014000B0 -:106EB0005A47781030487800E9471078ECD0400005 -:106EC00074470120FD04042086A00300C000784719 -:106ED00084A1004040007C4782A30300C8007C4797 -:106EE00084A1040040004D47188378004D47147872 -:106EF000ECD0C0007C4784A10040C0004D479CA15D -:106F00000C3086A304204000994786A30800400067 -:106F1000A447047084D0C00095470871087006A18A -:106F2000C0008A4784A1030040009547780030489C -:106F300086A30C20C0004D47007204824800A4477D -:106F40000C7384A3FF034000A4477810B229087192 -:106F5000087006A1C000A44784A1E0014000B14729 -:106F6000781030487800E94707701200007084D02C -:106F7000C000C1471073147005A34000C1470C71D5 -:106F800084A1FF03C00038470871087006A1C00043 -:106F9000C14784A1E0014000CE4778103048780016 -:106FA000E947077012000770080004709CD0C00009 -:106FB000D2470871087006A1C000D64784A1E0013D -:106FC0004000E347781030487800E9470770120026 -:106FD000087103814800D647037008007C000871DF -:106FE00084A1E001C0003048087184A1E001C00024 -:106FF000304884A107007900FA4704481448024841 -:10700000144802487248024870487810B229047047 -:1070100084A010008DC00670FF8AC0000F48492070 -:1070200000007C007810F249C0000F487C0004701A -:1070300084A010008DC00670047084D0C000284861 -:107040000871087006A1C0001D4884A1030040001B -:10705000284878003048FF8A40002F487810F249CD -:10706000C0002B487C00077012000871E000334814 -:1070700091200060E0003748912000600770120006 -:107080000770080004709CD0C0003F4807701200D1 -:107090000871FCD1C000434803700000007005A0D7 -:1070A000C0005748047005A0C00057480C7005A0E8 -:1070B0004000594878003B484920000084B2000154 -:1070C000400063480120000078006548012001006D -:1070D000781062421B680200512000007C0078108A -:1070E000B2297810B2297810B948107214710C7056 -:1070F0009CA0FF03002800A311A289A10000781022 -:10710000B9480427582C60AC0863002222A30C6302 -:1071100000211BA3002405A340009548C800954802 -:10712000128410820A8389A10000602B78007C48B9 -:10713000602B078A7E0004609CD04000A048BAA75C -:10714000EC467800A248BAA7E4467F003DA7002C91 -:1071500086688A6F926C8E6B0871087006A1C000F9 -:10716000A94884A1E0014000B44878103048077075 -:107170001200781038477C00508A3987042704A011 -:10718000C000CD48006064A0C000C448602D046009 -:1071900084A00F0080A002473C20FB874010B2294A -:1071A0007C007E127E0DD47084A000460480902066 -:1071B0007F0D8468602088688C6B906C5780D4AA9F -:1071C000FF0084A0FF007E00046884A008007F0008 -:1071D0004000EB48B8A0EC467800ED48B8A0E44683 -:1071E00084B200014000F448207E7800F548247EF7 -:1071F000B5A60C001C68B4D04000FC4885C600242D -:1072000005A340002549582C0427046160AC0060A8 -:1072100000A41A70046001A31E709CD1400015499F -:10722000106081A000002270146081A00000267010 -:107230000862002402A212700C62002303A21670DE -:10724000027607700100602B78101C4A78002749ED -:107250007810F249C00025497F1200207C007E1280 -:107260007E0DD47084A00046048090207F0D0770AE -:107270000400047094D0C0003649037008007F12E7 -:1072800000207C007E127E0DD47084A00046048015 -:107290007E0090207F007F0D207E84B20001C00020 -:1072A0004F49247EB5A60C001C68ACD0C0005A49DA -:1072B00085C6037000000770040028685020602D08 -:1072C0000460BCA00F00B8A7F2463C27FB87C000B3 -:1072D000704948006A497810B2299C6865A040004E -:1072E000744978005D497810F249C00070497F12F6 -:1072F00000207C007E127E007E017E0DD47084A072 -:10730000004604807E0090207F00207E84B2000131 -:10731000C0008849247E7F0D7F037F04B5A60C0042 -:107320001C68B4D04000964985C603700000077001 -:10733000040049207749286855A07E0D4000EE4999 -:10734000702D602E0470BCA00F00B8A7F2463C2739 -:10735000FB87C000B3494800AC497810B2299C7043 -:1073600075A060204000EE4978009F49042768AE70 -:10737000086822A40C681BA34800CC49518AC000AD -:10738000C0497810B2293887042705A0C000B44945 -:107390009C7075A060204000EE4978009F492284CF -:1073A00020841A8399A300000869002422A10C6993 -:1073B00000231BA1C800DB497810B22984B2000168 -:1073C0004000E9490120044F0420ECD0C000E94905 -:1073D000712050007800EB49712020007F0D78006B -:1073E000FC487F0D7F1200207C0008707E0084A086 -:1073F000E0017F004000FB4906A07C0084A0030060 -:1074000086A00300C000024A7C00042778AC007804 -:107410001A7004781E70087812700C781670046068 -:107420009CD04000144A107822701478267002769E -:10743000047084A0100085C006707920004F388742 -:10744000518A4000404A042705A0C000324A9C608F -:1074500005A04000414A6020046084A00F0080A085 -:10746000F2463C20FB874010B22908707E0084A0C1 -:10747000E0017F0040003C4A06A07800414A84A019 -:10748000030086A003007C00512000007C007E12D7 -:107490007E007E0DD47084A00046048090207F0D75 -:1074A0007F08087184A10300C000594A286805A01C -:1074B0004000694A780002460871FCD14000614AE8 -:1074C0007810ED4778004E4A077010000871FCD123 -:1074D0004000634A7810ED47087086A00800C0009D -:1074E0004E4A007005A0C0004E4A037000004920BB -:1074F00000007E000478CCD040007D4A7810CC4A51 -:107500007F007F1200207C007E127E147E137E1589 -:107510007E0C7E0DD47084A00046048090207F0DE8 -:107520004920814A80AD1100A02084B200014000B2 -:10753000A44A0120044F0420ECD04000A04A992026 -:1075400031007800A64A992032007800A64A992096 -:1075500031000C7084A0FF032A68077008000770D0 -:107560000200037001004000B54A0080AC80A553C2 -:107570000C7084A0FF034000C14A0770040004702F -:1075800084A00400C000BC4A7F0C492000000370A6 -:1075900000007F157F137F147F1200207C00146889 -:1075A000FCD04000114B007084D04000114B247E71 -:1075B000B5A6040007700400047084A00400C00095 -:1075C000D94A18717E011C717E0120717E012471DF -:1075D0007E010EA01A711F70FF3F22712671137079 -:1075E000040016710276077001000120FFFF0920D8 -:1075F00031000A200A200871087006A1C000F84A6C -:10760000FCD14000F84A7F0226727F0222727F027C -:107610001E727F021A7207700200087086A00800AE -:107620004000114B780030480770040003700000E0 -:107630007C009120008091200060AC7805A0C00003 -:107640002D4B7479D07006A1C0002D4B1C7805A07D -:1076500040002D4B1F78000068002D4B912080408A -:10766000307801803278C000B54B347832781078A9 -:10767000ECD0C000AE4B6120C0746920804FFDC7C4 -:10768000D06805A04000474B0180D268C000474B3E -:107690007810834D006884A00F0040005C4B86A0EA -:1076A000010040005C4B44680DA040005C4B04218D -:1076B00005A040005C4B01800A204000F64C146895 -:1076C00005A04000814B01801668C000814BA7686F -:1076D00001007E0FFCD7C000764B1078ECD0400044 -:1076E000724B792000017800784B792000027800F5 -:1076F000784B792000017810D3437F0F646805A090 -:107700004000814B78106F26806805A040008E4BAA -:1077100001808268C0008E4B67680000D468DDC0BD -:10772000D668D468FCD04000AB4BFCC0D668A9201A -:107730000002346005A04000A74B01803660D46889 -:10774000FDC0D668C000A74B106005A04000A74B45 -:1077500078106F26E0AC1000F000964BFCD740008C -:10776000B54B6120C0546920404FFCC778003D4BA9 -:107770007810F14B387801803A78C000D74B3C78CC -:107780003A786120C0546920404FFCC70C6805A0BE -:107790004000C94B78105B4CFCD7C000D74B107829 -:1077A000ECD0C000D74B6120C0746920804FFDC76A -:1077B0007800C34B1478E4D0C000DB4B1078CCD0F9 -:1077C0004000EE4BACD0C000E74BA4D04000EE4BE5 -:1077D000ADC01278912001806800ED4B7810DC2359 -:1077E0007C00912001807C00407801804278C000BC -:1077F0005A4C447842786920404FFCC71078792071 -:107800000002ECD04000034C79200001D86805A0AC -:1078100040000F4CE07D04A5C0000F4CDA68D4682E -:10782000BCC0D6687920004F106805A0C000174C76 -:107830000120010101801268FCD74000204C80A08B -:10784000D0957800224C80A0C0944020042065A0F0 -:1078500040004C4C246005A04000484C018026604C -:10786000C000484C006805A040003B4C4C6806AC8A -:10787000C0003B4C7810F64C78004C4C646805A076 -:107880004000434C276001007800484C7810A94C18 -:1078900004287800244C0060402C7800244CFCD74D -:1078A000C0005A4C1078ECD0C0005A4C6920804F70 -:1078B000FDC7792000017800034C7C0009200000FE -:1078C000A920000208609CD04000954C246005A0CF -:1078D00040006B4C018026607800934C08609CC08F -:1078E00084D0C000734CACD040008D4C0A60046062 -:1078F00005A04000954C7E0D7E0C7E016820106036 -:10790000018012607810193E002D682C60207810DC -:10791000A21E781064207F017F0C7F0D7800954CAB -:10792000BDC00A608DA101007800954C8DA10001B9 -:10793000E0AC1000F0005F4C84A101004000A44CBA -:107940008CA1FEFF0E6978106F267800A54C0E6999 -:107950007C00C000A54C6C78002C7E681467766FA4 -:10796000176000002B6000001B600600B46084A05C -:10797000003F1E60206084A0FF0085A060002260A0 -:107980000060422078102B1E186805A04000C74CEC -:1079900001801A680868A4C00A681068087909811B -:1079A0000A790180D000D34C7810B2291268C00047 -:1079B000D94C1079A5C112792F6000003360000006 -:1079C000682C78107320FCD7C000E74C6920404F2A -:1079D0007800E94C6920804F106984A100010120E2 -:1079E0000600C000F34C7A69012004007810632679 -:1079F0007C007E0D4C696021FCD7C000084D1078DA -:107A0000ECD04000044D6920000178000A4D692047 -:107A1000000278000A4D69200001781026291B60B9 -:107A20000600586884A0003F1E60206084A0FF000C -:107A300085A0480022602F600000336000000868C5 -:107A400084A0FDFF0A683068B4D040003C4D4B680C -:107A50000400A9201400486894D040002E4DF00086 -:107A6000284D4B680900A9201400486884D04000C4 -:107A7000384DF000324DA920FA00F0003A4D1B6855 -:107A800047007F0D676807007C007920004F781061 -:107A9000764D78105C4D7810694D09200200692000 -:107AA000804F0F680000136800001768000009810C -:107AB00040005B4D6920404F78004E4D7C001078AF -:107AC000ECD04000644D1920CC007800664D1920A0 -:107AD0007B003A7B3E7B7C001478E4D0C000714D83 -:107AE000192040007800734D19202600427B467B08 -:107AF0007C001478E4D0C0007E4D1920943F7800BB -:107B0000804D19202426327B367B7C00506A85A26A -:107B100000004000AF4D5469C06B00A37E0C64218F -:107B20000463FF83C0009B4D118240009F4D08817C -:107B30001AA148008C4DC06978008C4DD3680A00AA -:107B40007F0C7C005069C06A64222B6000002F60AB -:107B500000000860B5C00A6010820981C000A14D14 -:107B600052697F0C7C00E000B04D91200060E00085 -:107B7000B44D91200060EC70DCD0C000C14DD4D079 -:107B80004000EA4D7800ED4D08201078ECD0400020 -:107B9000D44DC4D1C0000E4E1478C5C016781078EC -:107BA000F5C01278ECD040000A4E7800064E8EAE3A -:107BB00000014000E14D1478F5C0C5C01678D4D05E -:107BC000C0000A4E7800064E1478FDC0C5C0167875 -:107BD000D4D0C0000A4E7800064EE4D040000C4ECF -:107BE000E000ED4D9120006009200C00E000F34D15 -:107BF000912000600981C000F34DE47084A0FF0172 -:107C000086A0FF01C000044EEC707800C14D7810D2 -:107C10000F4E04788CD040000C4E1F680C00A070F2 -:107C2000A2707C001079ECD14000194E1478C4C0C9 -:107C3000F4C1127978002B4E8EAE00014000254E23 -:107C40001478F4C0FCD0C0002B4EC4C078002B4E7A -:107C50001478FCC0F4D0C0002B4EC4C016787C0051 -:027C6000E3142B -:00000001FF -/***************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x - * Copyright (C) 2001 Qlogic Corporation (www.qlogic.com) - * - *****************************************************************************/ - -/************************************************************************ - * --- ISP1240/1080/1280 Initiator Firmware --- * - * 32 LUN Support * - ************************************************************************/ - -/* - * Firmware Version 8.15.11 (10:20 Jan 02, 2002) - */ diff --git a/firmware/qlogic/isp1000.bin.ihex b/firmware/qlogic/isp1000.bin.ihex deleted file mode 100644 index a5c242cda2203c03cef93d631245e77e8dfbfd74..0000000000000000000000000000000000000000 --- a/firmware/qlogic/isp1000.bin.ihex +++ /dev/null @@ -1,1158 +0,0 @@ -:1000000078003010000019240000FF124320504FE8 -:10001000525947495448312039392C313931323914 -:10002000312C39392C333931343951204F4C49472F -:1000300020434F435052524F54414F49004E4920A4 -:1000400050533031303046207269776D72612065CF -:100050005620726569736E6F30202E313133202047 -:10006000B9201212C120080071201000C3700400D2 -:10007000C920FF3F8920C810C7705349CB7020505A -:10008000CF702020D3700100003FD67031203000A7 -:100090007920003563780000A02F09202703112064 -:1000A0000000A9204000A4420981C00051109B78A3 -:1000B00001010B7802000F7802004F78B80B69201D -:1000C0004035A8006A101B683C0009201313B821B2 -:1000D00078006C101B682800076807000B68FA009E -:1000E0000F680800136805001F68000023680600F9 -:1000F00017680800276800006920003611202000DA -:10010000092010000B68190C0F681900036800DD46 -:1001100007681A001A6A002DE8A0080090A20400DF -:100120000981C000821069208036A92080003768CC -:1001300000000B684000176800011F686400E8AD0C -:1001400010007000A510780097107810381A7810F9 -:100150003A2F781081167810BA33003285A00D003E -:100160009020C37000009000BC10C07086A00200F8 -:10017000C000BC107810BA117810EC107810171865 -:100180007810A81978107D3278107D177800BC108F -:10019000D010D210C31BC31B982F982FC31BC31B97 -:1001A0007800D0107800D2107800D4107800D610E3 -:1001B00008700C80C800E710077002008CA00C00CB -:1001C000C000E81004800480C800E7107A087A09AB -:1001D000C37002407800BD11147805A0C000F4106F -:1001E0001000301178002F1109206835042105A076 -:1001F000C0002F11147886A00100C00001117810F2 -:1002000036151778000009206F35042165A04000DD -:100210001D1109206A351C2108811421088104213F -:1002200010A299A3000009201C008360030178102C -:100230001116C00029117810781609206F350B208F -:1002400000000920693504210B20000005A04000B2 -:100250002D11012005407800BC117800BA117C00F6 -:1002600061200000186084A00100400038117C006B -:10027000C3700000C7700000CB700000CF7000009A -:10028000C070BCA0C0FFC0008811382079004811A0 -:10029000BA110512D311051256125612CA11901531 -:1002A0006112C611D711D911DB11DD119515C611D7 -:1002B0006712831244158A15DF116B148D14A7146D -:1002C000D0142414321446145A14EF12C6119F127B -:1002D000A612AB12B012B612BB12C012C512CA12CD -:1002E000CE12E312C611C611C611C611C611FB12F9 -:1002F00004131313391343134A1370137F138E130C -:10030000A0130914C611C611C611C611C6111914BD -:10031000BCA0A0FFC000C611382084A01F00790037 -:100320009111C611C611C611C611C611C611C6114A -:10033000C611C611C611C611C611C611C611C61105 -:10034000C611C611C611C611C611C611C611C611F5 -:10035000C611C611C611ED15F715FB150916C61104 -:10036000C611CA72C671012006407800BC11CE7356 -:10037000CA72C67101200040C270612000001B607B -:10038000010091200050912080407C00C37001400A -:100390007800BD1199204100A1204100A92005004D -:1003A000A3537800BA11C470C37004007A007800B7 -:1003B000BA117800BA117800BA117800BA119120F8 -:1003C0000080C3700000C7705349CB702050CF70BD -:1003D0002020D3700100003FD670792000001B78E8 -:1003E00001003120300059200010292057045120ED -:1003F000700461207204B920FFFFC1200000912029 -:1004000000509120804078005504D071C872CC73A0 -:10041000C470A020982031203000FF814000BA1124 -:10042000077004001A731E72512012004920341202 -:100430004120BA110370020086A70100C0002612F5 -:100440004920421241204E12037003001770000031 -:100450000B811271C8002E12177001000770010085 -:1004600086A70100400042120C7084A07F00048027 -:100470000920200002A142094A09A820A026A6536B -:100480007800D8100C7084A07F0040004212AC802D -:10049000480042129826A5537800D8100C7084A00A -:1004A0007F00AC809826A5537800BA11C471C8703B -:1004B00014219EA70400C0005E120A20CA727800B0 -:1004C000B911C7700100CB701F007800BA11C47059 -:1004D000C872CC73D074C670CA72CE73D27405A0C1 -:1004E00040007D12018072787A7A7E7B767C9878E3 -:1004F00084A0FCFF9A7878008112987885A001008A -:100500009A787800BA11C470C872CC73D474C6706B -:10051000CA72CE73D67405A0400099120180867805 -:100520008E7A927B8A7C987884A0FFFC9A787800F7 -:100530009D12987885A000019A787800BA11092058 -:1005400059350C21112010047800B81109204135CB -:100550000C217800B911092042350C217800B9111D -:10056000612040350C6110627800B81109204535D2 -:100570000C217800B911092046350C217800B911F9 -:10058000092047350C217800B911092048350C2184 -:100590007800B91108790C7A7800B811C471078114 -:1005A00084A00F00038003800380E8A00036006A67 -:1005B000046884A008004000E012086B7800E11293 -:1005C0000C6B7800B711C4777810921691200080D8 -:1005D0001C6B146A9120018008277800B711C4773A -:1005E00078109216912000800869186A106B91208B -:1005F00001807800B711C47182A11000C800B21147 -:100600007810BC1A7800B711C47182A11000C8001C -:10061000B2111120413504227E0012217810751A82 -:100620007F017800B911C47111203113A92008008D -:10063000042206A1400023131082700021137800C9 -:1006400018137800B21192A231137E0211204235A4 -:10065000042212217F017E007810811A7F01780028 -:10066000B911E803FA00F401EE0264001900320047 -:100670004B00612040350C611062C4700E60C87080 -:1006800012607800B811612040351461C4701660A2 -:100690007800B911C471112004001920121286A12A -:1006A000280040006313112005001920121286A1B2 -:1006B000320040006313112006001920131386A195 -:1006C0003C00C000B2116120403518607E001A6104 -:1006D000B8237810921A7810BA337F017800B911D4 -:1006E000C47184A1CFFFC000B2111120473504228C -:1006F00012217E007810B41A7F017800B911C471FC -:1007000082A11000C800B2111120483504227E00D9 -:1007100012217810A31A7F017800B911C471C87230 -:1007200084A1FDFFC000B11184A2FDFFC000B11182 -:10073000002108790A7800220C7A0E787800B81126 -:10074000C471078184A00F00038003800380E8A0A8 -:10075000003619200000C87200687E0026A2400002 -:10076000CF13026A84A400204000B8139DA3100098 -:1007700084A400104000BE139DA3080084A4004080 -:100780004000CF130F8184A200404000CB137810AB -:10079000D61A7800CF137810C81A7800CF13CC720D -:1007A000FF8240000114086806A240000114A4A2C0 -:1007B000FF0061204035186186A128004000E81341 -:1007C00086A132004000EE1386A13C004000F413E5 -:1007D00082A464004800FE137800F81382A450003D -:1007E0004800FE137800F81382A443004800FE136B -:1007F000C471C6717F02CA727800B3110A6A9DA3E0 -:100800000A00046805A306687F020C6BC4717800B7 -:10081000B711C4777810921691200080146A1C6B6F -:1008200091200180C8701668CC701E680827780077 -:10083000B711C471C872CC7382A11000C800B21184 -:100840007810E41A7800B711C477781092169120C6 -:100850000080086A95A202000A6A91200180082798 -:100860007800B811C4777810921691200080086A39 -:1008700094A2F9FF0A6A046805A0400041147810A8 -:10088000191A9120018008277800B811C4777810D0 -:10089000921691200080086A95A204000A6A0468F2 -:1008A00005A0400055147810191A912001800827DE -:1008B0007800B811C477412001004920050051207B -:1008C00020009120008078109F1691200180082739 -:1008D000086A7800B811C477C872CC73C677CA7238 -:1008E000CE7378101817C0008914186805A040004E -:1008F000831408277810F41AC00083141778FFFFB8 -:10090000912001807C009120018001200540780029 -:10091000BC11912001807800BA11C477C6774120BC -:1009200021004920050051202000912000807810EE -:100930009F1661204035A3600300B667A7600000E2 -:100940001778FFFF912001807810191A7C00C87772 -:10095000CA77C477C677BCA700FF912000806120CA -:100960004035A3600200A7600000B6671778FFFF5C -:100970007810191A9120018041202100492004009B -:10098000512010009120008078109F16C8703668A2 -:10099000388784A70700C000C414912001807C0020 -:1009A000987884A00300C000F4143920000041208E -:1009B000210049200400512008007810921691204F -:1009C000008008680DA80A6991200180388784A7F3 -:1009D0000700C000DD14BCA700FF3F8738873F87B2 -:1009E00084A7000FC000DD14912000806920000161 -:1009F000306884A0400040001D154B680400A92009 -:100A00001400486884A0040040000A1570000A150C -:100A1000780001154B680900A9201400486884A0DB -:100A20000100400017157000171578000E15A92059 -:100A3000FA0070001D157800191579200035177817 -:100A4000010061204035A3600100A7600000C36081 -:100A50000F00987885A002009A78086884A0FDFFAE -:100A60000A681B684600912001807C00987884A069 -:100A7000FDFF9A7884A00100C0004015781060172F -:100A8000C471C6714A797C00C474C873CC72C674D0 -:100A9000CA73CE72792000350920400078106F1695 -:100AA0004000861578103F1640005A1578107816C9 -:100AB000780086151060912001801778FFFF0920CB -:100AC00068350B20050008810B20000008810A23EF -:100AD00008810A2208810A2408810A2008810B2043 -:100AE000000008810A2C2EA030257E0E7810132FCE -:100AF0007F0E9265A2659666A666AB600000AF6049 -:100B00000000912001807810191A7C00C370054004 -:100B10007800BD11C471C770000006797800BA1161 -:100B2000C471C671682178009715692000100C699E -:100B300016A0042D10A2688D0981C000991585A208 -:100B40000000C000A715C37000407800A915C3704D -:100B50000340CA707800BD11C471C872CC73002103 -:100B600084A1FCFFC000C61100217900B715CE1585 -:100B7000E315E515E715C3700340CE71D272D67345 -:100B80007800CA15C3700040CF700000D370000019 -:100B9000D7700000C677CA717800BA113120E91504 -:100BA000242630861224042246A4C000BB1584A447 -:100BB000FFFFC000D0153120E9151082198384A3EE -:100BC000FFFFC000D0157800C2157800C21578006C -:100BD000C2155555AAAAFFFF00006079C671C471FD -:100BE00082A10300C800B21162797800BA1160795D -:100BF000C6717800BA115479C671C47156795879A2 -:100C0000CA71C8715A795C79CE71CC715E797800FD -:100C1000BA115479C6715879CA715C79CE7178006D -:100C2000BA110C7084A07F0040001D1607700400EC -:100C3000047084A00400C000181617700000127120 -:100C40001A721E7308810C81A981988CA120300032 -:100C50008060A220A6530C7885A000000270077067 -:100C6000010008710481C80031160770020084A1D8 -:100C70000C000C7184A10003037000007C000C7058 -:100C800084A07F0040004B1607700400047084A00D -:100C90000400C00046161770000012711A721E730D -:100CA000992030000881AC810C7885A00100027089 -:100CB0000770010008700C80C8005A160770020007 -:100CC0008CA00C00C0006C160C7184A10003C00045 -:100CD0006C16A02CA55306A0037000007C00507871 -:100CE00065A040007716042C5278632000007C0039 -:100CF0007E0F7920003550786220002C52787F0FCB -:100D00007C0011200040527A192010041983400001 -:100D10008F1680A22F001220102078008616132034 -:100D200000007C0084A7000F0C8084A707000380CC -:100D300003800380038005A1E8A080367C00781042 -:100D4000921600292A68002A2E68086884A0EFFFFE -:100D50000DA80A6909204F350C21046805A0400040 -:100D6000BC1616A1C000BC166020006006687E019B -:100D70000B2000007800BF16092000007E010468E7 -:100D800065A04000CE16006006687810DF16781067 -:100D9000CB17106801801268C000BF167F0102697E -:100DA00006697C0065A04000DE1698609B6000002C -:100DB00008207810781600217800D2167C00036095 -:100DC0000301A9201C0080AC0400A0200120000029 -:100DD000A440286816602C681E607C007E0E71207E -:100DE000403540708CA08000C000FC1688A0803583 -:100DF0000A2D0080427006A07F0E7C007E0E7120BE -:100E00004035092080354072218211824800161732 -:100E10000421088106ADC000051719811E21088133 -:100E200018831182C8000E17427406A07F0E7C0042 -:100E3000781092169120008004681E7865A040000A -:100E40005F1778002917002C1E78006065A040000D -:100E50005F170C6006A3C0002317086006A2C0003D -:100E60002317282C01204F35042006AC40005F17C3 -:100E7000046806ACC000461700606020066805A044 -:100E8000C0004617036800007800501700641C7803 -:100E90006020026486A40000C0005017002C026885 -:100EA00060257810DF16176005001F60200078109D -:100EB000CB171068018012680120FFFF05A07C009D -:100EC0003920000041202100492004005120080061 -:100ED0009120008078109F16388784A70700C000F3 -:100EE0006A17BCA700FF3F8738873F8784A7000F9A -:100EF000C0006A17912001807C006120000018600A -:100F000084A00100C0008A17AC78AF78000005A06B -:100F1000C0008B177C008CA0F0FF40009117781068 -:100F2000A51B79009317A317A517AB17AF17A31726 -:100F3000B317A317A317A317A317B917BD17A317A1 -:100F4000A317A317A3177810A51B7810601701200B -:100F500001807800C317012003807800C3170120A7 -:100F600004807800C317781060170120068078008D -:100F7000C31701200C807800C31778106017012078 -:100F80000D807800C317C270612000001B60010053 -:100F9000912080407C00042C8260082C632000009B -:100FA000647800806678687805A06A794000DB176D -:100FB000022C7800DC176E797C007E0C61200035F5 -:100FC00083680301082D6B20000064600080666068 -:100FD000686005A06A614000F017022D7800F117E3 -:100FE0006E617F0C7C0078100418400003187E0CA2 -:100FF000986065A04000FE177810D2167F0C9B60A9 -:101000000000781078167C006C7865A040001618F7 -:1010100091200080647801806678042C6E7805A0A9 -:10102000C00014186A780080912001807C009878B4 -:1010300005A0C00065187479D07005000500D07255 -:1010400006A2C0001C18002206A1C00033180478B4 -:1010500005A0400065180778000068006518912019 -:1010600080407800651878106F16400065187C7A0B -:10107000787B07810480048010A299A300000920D6 -:10108000400078103F1640005C1878107816807881 -:101090000080827886A00200C00065189120008040 -:1010A000AF78020083780000987885A003009A78D2 -:1010B00091200180780065188378000078109219DB -:1010C000006084A00700790066187C006E187D1807 -:1010D0009D186E18AF186E186E186E18392000041F -:1010E000A87805A7AA78046005A706607810ED180F -:1010F0001860A67878107A197C00A87884A000017E -:101100004000841878006E18AB78000000600780FB -:1011100084A0FF009E7801809B60000040009A1828 -:101120007810ED1840009A18A87885A00001AA78D8 -:1011300078009C18781011197C00A8788CA0000EFB -:10114000C000A61884A00001C000A81878006E187E -:101150007810ED18C000AE18781011197C00A8782E -:1011600084A000014000B61878006E18AB7800002B -:101170001067A9200100146084A0FF0005A04000B2 -:10118000D318BCA700FFA92008008EA001004000D2 -:10119000D31839200000A92080008EA00200400052 -:1011A000D3187800EA1878109216002D912000804C -:1011B0002B6800002F680000086884A0DEFF0A6822 -:1011C000002D80A010006820912001807000EA1896 -:1011D0007800D618781078167C00A0786DA0C00032 -:1011E000F818002CA278A6789B60000078000419FB -:1011F000002C9A689B600000A278002D0260A47801 -:1012000006ADC000041902609C7801809E78C00081 -:101210001019A87884A00000AA78A478602006A0FD -:101220007C002EA03025186184A160009E614000E2 -:101230001D197E0E7810132F7F0E9265A26596669B -:10124000A666AB600000AF600000106778109216D1 -:1012500091200080086884A0010040003F1991207F -:1012600001807810DF16912000807810CB17912034 -:101270000180A3780000A778000078007919206029 -:1012800096A00100C000461900802260106A146810 -:101290009120018002A248005519400055193920BB -:1012A000000278107A1978007919082C91200080B2 -:1012B000006865A040005D1902610269C000611903 -:1012C00006696021036000001068008012689120A8 -:1012D000018008688CA040004000731986A040007F -:1012E0000A687810EE167810191AA7780000A3780B -:1012F00000007C00046005A7066091200080781043 -:10130000CB1791200180A47865A040008D199860CA -:10131000A6789B60000078007D19A3780000A7786C -:1013200000007C007079747800800AA1C8009919C7 -:1013300006A07678D270047805A04000A719018035 -:101340000678C000A7196800A719912080407C008A -:101350006800C219292000006C7865A04000BD1902 -:101360007810C3194000BD197E057810D9197F0582 -:10137000C000BD1928857800AC19FF854000C2194E -:10138000912080407C00847B8879D4720500050020 -:10139000D47006A2C000C519002202A1C000D31952 -:1013A000002305A07C004800D71902A37C0002801E -:1013B0007C0078100B1A09201C00246005A0400056 -:1013C000E31909204000781011164000FC199478A8 -:1013D0000080967886A00200C0000A1A9120008042 -:1013E000AF78030097780000987885A000039A787A -:1013F0009120018078000A1A977800007810F3177E -:101400008479887800800AA1C800071A06A08A7823 -:10141000D67006A07C00078104800480907A8C7BC3 -:1014200010A299A300007C0009206835912000805B -:101430000A207E0F7920000109204035912000808C -:10144000042186A00000C000341A092012350421AE -:1014500005A0C000341A307884A0C000C000341A3F -:101460001800341A1B784400912001807F0F7C0003 -:101470007E1291200023712040357920000119202F -:10148000D82DA1202B01042305A04000501A9A78E2 -:101490001883AC2318839823A65318337800431A73 -:1014A0009B782000A9201000AF780000AF782002C0 -:1014B00070005C1A7800541A0370000078105B1BEF -:1014C000047084A00F0085A0806206780F780092D7 -:1014D0004378D800537880000B78380047707F3508 -:1014E000437000007F1200207C008CA10F001120AF -:1014F0000101042284A0F0FF05A1122078105B1BDB -:101500007C0011200101A92009000B8170008A1ABA -:101510007800851A8CA1000E042284A0FFF105A199 -:1015200012207C0009200101A9200500138270000F -:101530009B1A7800961A94A2E000042184A01FFF51 -:1015400005A20A207C0011200101A9200C000B81BA -:101550007000AC1A7800A71A8CA100F0042284A0B5 -:10156000FF0F05A112207C0011200201042284A09B -:10157000CFFF05A112207C000381038080A0200002 -:101580007E0C612000019A60AC62AC637F0C7C0031 -:101590000381038080A022007E0C612000019A60FC -:1015A000A46084A0DFFFAE607F0C7C000381038019 -:1015B00080A022007E0C612000019A60A46085A0BA -:1015C0002000AE607F0C7C000381038080A020009F -:1015D0007E0C612000019A60A460AE621020A460BD -:1015E000AE6318207F0C7C00912000807E0C7E0E64 -:1015F000186805A04000391B6120803F7810411B0E -:101600004000271BA92000006120803E7E0C78103E -:10161000411B4000131B7F0C608C7000111B780075 -:10162000061B7800391B7F0082A0803E7120403568 -:10163000BA701C6085A000081E60B671A76000002B -:1016400001200400A2707810141A7800351B712054 -:1016500040351C6085A000081E60B671A7600000C0 -:1016600001200600A2707810141A012000007800F2 -:101670003B1B012001009120018005A07F0E7F0C03 -:101680007C00042C05A04000581B60200C6006A3C1 -:10169000C000551B086006A2C000551B106006A1C3 -:1016A000C000551B06A078005A1B00607800421B42 -:1016B00085A001007C00112041350C228CA10F0077 -:1016C00011203B01042284A0000140006A1B21205C -:1016D00080FF22217C007E0EE4688CA02000400068 -:1016E000A31B84A00600C000A31B1060078084A079 -:1016F0000F00038003800380F0A00036047084A0F4 -:101700000A00C000A31B087194A100FF4000A31BA6 -:101710008CA1FF000120190006A14000961B0120AA -:10172000320006A140009A1B78009E1B0920200071 -:101730007800A01B09203F007800A01B11200000AA -:10174000002105A20A707F0E7C006800A51B7E00A8 -:1017500071200000187084A00100C000AA1B7F0047 -:10176000082E71201000CA707F00C670C3700280FE -:10177000712000001B700100912080407F007020CC -:101780007F007800C11B7E107E007E129120002316 -:101790003C7F587E307C387D94A53F0084A4004077 -:1017A0004000D81B84A77C00C0009C2D7810A51B8E -:1017B0009CA40F0082A304005000E01B7810A51B1E -:1017C000078584A00F007900E51BEA1F9A20C0203E -:1017D000E6226B25B325EA256526BF2644270B1C88 -:1017E000F51B531E1D1F4A25F51B7810A51B18005D -:1017F000C81B7F12912001807F007F107C00037046 -:1018000000003F700000307005A04000091C3370DC -:1018100000001800C81B5C7005A0C000B61CA070BA -:1018200084A007007900141CD61C1C1C2A1C4B1C0D -:10183000711C9D1C9B1C1C1C087884A0FDFF0A7851 -:101840000920460078101224C000281C03700400F0 -:101850007800F71B78105E2DC000491CB47007801B -:101860009B787E00AA789B781000AB780C009B7860 -:101870006000AB7801005B7804000920F700781065 -:101880001024C000491C03700400C3700F003370A3 -:1018900070357800F71B78105E2DC0006F1CB47196 -:1018A00007819B787E00AA789B7810008CA10700A6 -:1018B0008DA1C000AA79AB7806009B786000AB7858 -:1018C00002005B7804000920F70078101024C000A3 -:1018D0006F1C03700400C3700F0033707035780004 -:1018E000F71B78105E2DC000991CB47107819B789E -:1018F0007E00AA789B7810008CA107008DA1C00003 -:10190000AA79AB782000B871AA79AB780D009B78E2 -:101910006000AB7804005B7804000920F7007810C1 -:101920001024C000991C03700400C3700F003370B2 -:1019300070357800F71B78004B1C78105E2DC000C6 -:10194000F71BBC7068209B781000106F7810A12CDA -:10195000502C106884A0070085A08000AA78186E1B -:1019600041200100012004007800DE1D78105E2D6A -:10197000C000F71B9B7810005C706820106F781017 -:10198000A12C502C086085A010000A60106884A06B -:10199000070085A08000AA783120200041200100A6 -:1019A0007810C52D012003007800C91D1800C81B40 -:1019B000407485A400004000F01C80A080353020D9 -:1019C000447108812AA14800E71C09208035642160 -:1019D0000465FF85C000FD1C2184C000E11C467128 -:1019E000037000003F7000007800F71B4076B0A63F -:1019F0008035447100267800EC1C46716825582516 -:101A00003E75502C346085A00000C000FA1C0867A9 -:101A1000367784A73F0140002F1D84A72100C00016 -:101A2000FA1C84A7020040001C1D84A7040040008B -:101A3000FA1CBCA7FBFF0A6784A70800C000FA1CB9 -:101A400084A71000C000FA1C84A7000140002F1DCD -:101A5000186005A0C000FA1CBCA7FFFE0A671F683B -:101A60000000186E84A60E00186140003F1D1C6027 -:101A700002A14800421D4000421D7800F61CFF8173 -:101A8000C000F61C84A78000C000481D0C702260B6 -:101A9000BCA77FFF0A67106B078384A00F00038039 -:101AA0000380038080A00036602048204A700060D8 -:101AB0004E7004605270602A1800C81B9B7810009A -:101AC00046A078105E2DC000F71B106B9CA307008A -:101AD0009DA3C0004C7084A000804000731D84A6AC -:101AE00001004000751D9CA3BFFF84A610004000AC -:101AF0007B1D9DA32000AA7B408884A60E00C00009 -:101B0000861DBDA710000A677800C71D4C718CA107 -:101B100000084000022911202100048004804800B0 -:101B20009D1D11202200048048009D1D11202000D1 -:101B3000048048009D1D4000C71DAA7A4088781087 -:101B4000772D106A0C6108818CA1FF00E0A1803E16 -:101B5000642CFF8C4000BE1D106006A2C000A81DB2 -:101B6000B4600180B660C000A31D7E0C602A0860CE -:101B700085A000010A607F0C7800D61C78105E2DCD -:101B8000C000F71B602A0E61AA7940882E710120DF -:101B900001007E00507184A118004000DD1D84A169 -:101BA00010004000D71D7810CC2AC000DD1D84A194 -:101BB00008004000DD1D7810E6297F0002708CA629 -:101BC0006000FF884000E61D8DA104005A79B269CB -:101BD0009B7860000028AA789B786100146885A033 -:101BE00000801668AA787E157E137E14A1202C0131 -:101BF0009B7800000080AC8080AD0A009820A6533E -:101C00007F147F137F15106807809B787E00AA7869 -:101C1000906DD67DDE7D946ED27EDA7E307884A0A3 -:101C2000C000C000151E98001D1E086084A0EFFFB4 -:101C30000A607810772D7800FF1B007284A20700DD -:101C400086A00100C0002A1E1B7849007810772D5D -:101C500078003B1EB06A95A200205A7A1B78490092 -:101C60007810772D0072002505A640003B1E84A247 -:101C700007007910491E80AD0800327084A2070069 -:101C800086A00100C000471E186000801A6078001E -:101C9000F71B511EF030F030DF30F030511E511E76 -:101CA000511E7810A51B087884A0FDFF0A787E0FCE -:101CB0007920003598787F0F84A001004000791EBC -:101CC000A07086A00100C000681EA2707800011FED -:101CD000A07086A00500C000771EBC706820176841 -:101CE0000400136800001C6885A008001E68A3702B -:101CF00000007E1511200400A07186A101004000A3 -:101D00009B1E86A10700C0008B1E09202B350B20CF -:101D1000050078009B1E0920133504210920123587 -:101D20000A2009202B350B200100A3700000A770AA -:101D3000010078009D1EA37000007810C72EA92016 -:101D40001000392000007810A62BB8A70001700001 -:101D5000AB1E7800A31E007020207900AF1EDD1E90 -:101D6000C61EC61EB91EDD1EDD1EB71EB71E7810AC -:101D7000A51B21205735042405A04000C61E06AD32 -:101D8000C000C61E006822207800D61E1C6884A0F1 -:101D90000100C000D21E106F7810A12C7810D92835 -:101DA0007800D61E5470602000680260166A1C68B5 -:101DB00085A008001E687810DD172120803F78106C -:101DC000071F212057357810071FA9200000212068 -:101DD000803E7810071F20847000F01E7800E91EF6 -:101DE000A9208000612080361860106102A1126075 -:101DF0001B600000E0AC10007000001F7800F41EB3 -:101E00007F15037000003F7000007800F71B7E0410 -:101E1000042405A04000191F682000687E00166A8F -:101E20001C6885A008001E687810DD177F00780008 -:101E3000091F7F04232000007C0082A203005000C1 -:101E4000231F7810A51B00237900261F291F9C1F24 -:101E5000AA1F82A2020040002F1F7810A51BA070AD -:101E6000A3700000C37000007900361F3E1F3E1FA4 -:101E7000401F741F08293E1F741F3E1F7810A51BAA -:101E8000B4777810A62BB477BCA7000F7810A12CDC -:101E9000186005A040006B1F2120803F092004002E -:101EA000112010007810C51F40006B1F7E15A9205F -:101EB00000002120803E7E04092004001120100033 -:101EC0007810C51F7F0440006A1F208470006A1FBD -:101ED00078005B1F7F15388784A70700C000461F66 -:101EE0007800FF1B7800FF1BB4777810A12C1860D6 -:101EF00005A040009A1F2120803F092005001120E5 -:101F000020007810C51F40009A1F7E15A9200000F0 -:101F10002120803E7E040920050011202000781039 -:101F2000C51F7F044000991F20847000991F78000E -:101F30008A1F7F157800FF1B002279009F1FA21FB8 -:101F4000A41FA41F7810A51BA3700000A770010098 -:101F50007800F71B00227900AD1FB21FA41FB01F2D -:101F60007810A51B78101F24007086A00100C00007 -:101F7000AF287810EF28086084A0EFFF0A6078107F -:101F8000A2284000AF287800D61C042405A04000F9 -:101F9000E61F6820042D7E00106806A74000D41FAD -:101FA000202D7F007800C61F7F00222016691C6844 -:101FB00005A21E687810DD171060018012600860AD -:101FC00084A0EFFF0A607810EF287C0085A0010054 -:101FD0007800E51F00237900ED1FF21FF01F352068 -:101FE0007810A51BE47805A0D00015201800152056 -:101FF000082084A03000C00001201B784900780030 -:10200000F71BEC7884A003004000FD1F002184A092 -:10201000070079000B20232029201D201320582D94 -:10202000582D13202F207810A51B007005A040000C -:10203000FF1B012003007800FA227810892B1B78FF -:1020400055007800F71B7810892B1B78DC0078008E -:10205000F71B7810892B1B78E3007800F71B7810AA -:10206000892B1B789D007800F71B84A50F00C0000A -:102070005F2078101F24007079003E2046205320F6 -:102080004620AF284820AF28462046207810A51BC0 -:10209000A071A370000086A10400C0005120780048 -:1020A00008297800AF287810EF28086084A0EFFF97 -:1020B0000A607810A2284000AF287800D61CE47887 -:1020C00005A0D000152018001520082084A030009D -:1020D000C0006E201B7849007800F71BEC7884A0C4 -:1020E000030040006A20002184A1070079007820C5 -:1020F00088208E2082208020582D582D8020502D21 -:102100007810A51B7810912B1B7855007800F71BD1 -:102110007810912B1B78DC007800F71B7810912B3E -:102120001B78E3007800F71B7810912B1B789D003B -:102130007800F71B002379009D20A220A020A42076 -:102140007810A51B7800652617680800A3780000A2 -:10215000E47984A1300040006526EC7884A0030077 -:102160004000652684A107007900B620232029209D -:102170001D20302D582D582DBE20502D7810A51B18 -:1021800082A205005000C6207810A51B002379000C -:10219000C920CC20CE22DA2200227900CF20D42000 -:1021A000D620E920D420B3227810A51B9B781800F4 -:1021B000A87884A0FF0082A0200048006A2B8AA093 -:1021C0000400C8006A2B7900E5206A2B6A2B6A2B71 -:1021D0000C2B9B781800A87984A180004000FE2079 -:1021E00084A118004000FA2078006A2B007005A036 -:1021F000C000F420112003007800522784A1FF00C2 -:102200008AA01000C8006A2B790006211821162127 -:102210002E213021C2216A2B6A2BC4216A2B6A2B02 -:10222000AF22AF226A2B6A2B6A2BB1227810A51B32 -:1022300084A60010400025210120000300800080BA -:102240003A781B789A007800F71B146884A0008005 -:1022500040002C21176803007800302D7810A51B52 -:102260001C691E6984A60018C0004A211C6884A04D -:102270000100C0005221146886A00800C00042215D -:102280001768000084A600044000BE211B78580097 -:102290007800F71B84A60010400052211B785800DC -:1022A0007800F71B84A660004000BA2184A60008CD -:1022B0004000BA2184A60080C000602178007A2105 -:1022C000B4A6FF7F5A7EB26E9B787400AC7AAC796C -:1022D000AC781B80C8006D21008084A03F0008A15D -:1022E00091A20000946B002102A3AE68906B0022C3 -:1022F00003A3AA6884A6004040008221B4A6FFBFC1 -:102300005A7EB26E007086A00300C0008F21781044 -:102310003A2F7810DF301B7867007800F71B06A093 -:1023200078109431AC6AA869946C906B002205A176 -:1023300040009E21002222A400211BA3D27CD67B38 -:10234000002305A4C000AC21B5A600405A7EB26EA1 -:102350001B7867007800F71B1B786700002215A127 -:10236000C000B6217810F0307800F71B78101D31CE -:102370007800F71B1B786A007800F71B1B78580061 -:102380007800F71B7810A51B780021221C6984A116 -:1023900000014000DC218CA1FFFE1E697E0C48700C -:1023A0006020006084A0FFEF0260046084A0F5FF5D -:1023B00006607F0C7800102284A1000240001022E9 -:1023C0008CA1FFFD1E697E0C48706020006084A017 -:1023D000FFDF0260046084A0EFFF06600820482C45 -:1023E0007F0C84A108004000102278109D2C7810EA -:1023F000E629FF88400010229B7860000028AA7818 -:10240000587EB5A604005A7E84A60004C0000C22A3 -:102410001B7855007800F71B1B7869007800F71BC4 -:10242000587E84A60004C00019221B78580078004A -:10243000F71B1B786A007800F71B7800702B780078 -:10244000702B1920000090798CA1070040001F22FA -:102450009B781000A87894A0FF0086A20100C0001D -:1024600044220023A87C00A4182002A140003C22A2 -:1024700048003C2278003E227800C621A824A87A91 -:10248000F0003E2278002A2284A2F00086A02000DC -:10249000C000A02218831883002302A14000542208 -:1024A0004800542278009D2286A2230040001F226B -:1024B000186884A0F1FF1A68587E84A6F1FF85A0F1 -:1024C000100030205A7E086085A010000A607E0C43 -:1024D0004870602004600820482C7F0C84A1100004 -:1024E0004000782278109D2C7810CC2A7800872222 -:1024F0007E0C4870602004600820482C7F0C84A16A -:1025000008004000102278109D2C7810E629FF88E2 -:10251000400010229B7860000028AA78B5A604002D -:102520005A7E84A60004C00099221B7855007800CA -:10253000F71B1B7869007800F71BA87A78002A221D -:102540001883002302A14000A9224800A922780094 -:102550002A2284A28000C000762B7800702B78009D -:10256000762B78006A2B9B781800A87884A0FF004F -:102570008EA001004000BE227810A51BA87A94A26C -:10258000FF00A87884A0FF008AA00400C8006A2B7E -:102590007900CA226A2B39296A2B672A82A2000095 -:1025A000C000D4227810A51B7810892B1B786900F5 -:1025B0007800F71B82A20300C000E0227810A51B60 -:1025C0007810992B1B7869007800F71B82A2040011 -:1025D0005000EC227810A51B00237900EF22F22294 -:1025E000C923FA2386A203004000F8227810A51B15 -:1025F000012000003A70007084A0070079000023D9 -:1026000008230A230A2308253025D2240823082377 -:102610007810A51B84A60010C00012237810C72EC6 -:102620004000A32368788CA0FF0040005A2386A1B5 -:102630000800C00029237810EF28086084A0EFFF6D -:102640000A607810A22840005A237810C72E78001C -:10265000412386A12800C0005A237810C72E0860A5 -:1026600084A0EFFF0A60186005A0400041230180AC -:102670001A6005A040004123018005A040004123CD -:102680001E601C6884A001004000FF1B1C6884A021 -:10269000FEFF1E6854707E0C6020006802607F0C94 -:1026A0000460026805A0002DC00057230260066088 -:1026B0007800FF1B7E0178101F247F0184A600DFB5 -:1026C0001A6827680000106FFF814000A32386A1CD -:1026D0000200C0009B2384A60008C000772384A6C4 -:1026E000600040007723D878DC7A2E682A6A178742 -:1026F00094A20F0013821382138290A2003690A23C -:1027000000001C2284A30001C000882378008E23CF -:102710001082042285A018001220118284A30004D4 -:1027200040009B239C6884A00001C0009B2378107C -:1027300091247800FF1B86A118004000A32386A1E6 -:1027400014004000FF1B1269146884A00080400040 -:10275000AB23387016688CA600DF1A697810E02861 -:102760007810EF28C000B823086084A0EFFF0A604B -:102770001C6884A00100C000C1237810D92878000B -:10278000C52354706020006802607810DD1778005F -:10279000FF1B82A204004800CF237810A51B002253 -:1027A0007900D223D623D823E523D8237810A51B7C -:1027B000007086A005004000E1237810892B1B786B -:1027C00069001B786A007800F71B90780780018009 -:1027D00084A0070080A018009A78A8798CA1FF0037 -:1027E00086A103004000F62378006A2B1B786A005C -:1027F0007800F71B1C6885A004001E68FF82C000DB -:1028000005247810892B78000C24118240000A24BA -:102810007810A51B7810992B1B7869007800F71B9E -:102820007810772D307884A0C000C0001C241800D8 -:102830001C241A7906A07C0085A001007C0084A6D7 -:102840006000C00029242F6800002B680000780079 -:10285000902484A60008C0003824B06884A00048F2 -:1028600035A684A60008C00038247810C72E7C0046 -:1028700084A6200040006224D0780380C80046244B -:1028800006A078109431D4787810F93184A60040ED -:10289000400050242F6800002B6800007800352489 -:1028A000B06884A0004835A684A60040C0004A2431 -:1028B000387005A0C0005C24D879DC7A2E692A6AB9 -:1028C0007800352484A6004040006C242F68000066 -:1028D0002B68000078003524B06884A0004835A635 -:1028E00084A60040C0006624387005A0C0007A2489 -:1028F0003B700700D879DC7AD078F380C800812457 -:10290000008084A03F0008A191A200002E692A6ADD -:10291000002105A2C0008E2478003524781094315F -:102920007C0084A3000240009924086085A0020076 -:102930000A6017680600286A2C693A6A3E692B68A3 -:1029400000032F6800003368002093680000976838 -:10295000200000707900AC24B424B624BF24B42431 -:10296000B424B424B424B4247810A51B1C6884A017 -:102970000100C000BF247810D9287800C524547005 -:10298000502C602000680260602A21205735042402 -:1029900005A04000CE2420207800C724222D6B20E3 -:1029A00000007C00B4777810A62BBCA7000F78102D -:1029B000A12C186005A0400001257E0D0120903F4C -:1029C00068207F0D2120803F092004001120100085 -:1029D0007810C51F400001257E15A9200000212088 -:1029E000803E7E0409200400112010007810C51FCD -:1029F0007F04400000252084700000257800F12429 -:102A00007F15388784A70700C000D7247800FF1BF4 -:102A10007810E0287810EF28276800009B780E00D7 -:102A2000106F136802007810CA3184A600084000B5 -:102A30001D2518698DA100201A69146884A00080E2 -:102A40004000242517680000212057350068222007 -:102A5000386A3C692A6A2E697810DD177800FF1BF6 -:102A600078101F24276800009B780E00106F7810E4 -:102A70007C2D8CA0FF001269146884A000804000A7 -:102A80004325387016688CA600DF1A69A370000011 -:102A90007800FF1B06A07810C72E13680000176887 -:102AA00001008CA600DF1A69276800000070790019 -:102AB00059256125632563256525652565256125DE -:102AC00061257810A51B7810EF28086084A0EFFF1F -:102AD0000A607800BA28002379006E2571257325D5 -:102AE000B1257810A51B0070790076257E258025FC -:102AF00080258B25802592257E257E257810A51B97 -:102B000084A60020C0008B25B5A600205A7E781030 -:102B1000F0307800302D146884A0008040009225A9 -:102B200017680700092018350C2186A10000400015 -:102B3000A72586A101004000AB2509202B350B20DD -:102B40000B00A37001001B7846007800F71B1B7870 -:102B5000DD007800F71B09202B350B200A007800D8 -:102B6000F71B7810A51B00237900B625B925BB25D6 -:102B7000DE257810A51B00707900BE25C625C82566 -:102B8000C825D325C825DA25C625C6257810A51B56 -:102B900084A60020C000D325B5A600205A7E781058 -:102BA000F0307800302D146884A000804000DA25D1 -:102BB000176807001B78E4007800F71B1C6885A0E5 -:102BC00004001E68B5A600087810892B1B786900E0 -:102BD0007800F71B00237900ED25F025F225F42578 -:102BE0007810A51B7810A51B84A60004C00013262E -:102BF0002B7809309B786000AB78000084A6FBFF3F -:102C00005A78E47984A1200040000B26EC7884A057 -:102C10000300C0000F26012014007800FA2284A1CE -:102C2000070079004B26907A94A207009B786000F9 -:102C3000A879FF81400049269B781000A87B84A3D7 -:102C40000100C0003A26A87BA87B86A30100C00033 -:102C50002D260920F7FF7800332686A30300C00045 -:102C60003A260920EFFF7E0C48706020046004A122 -:102C700006607F0C9B786000AB78000084A6FBFFA9 -:102C80005A782B7809301C698CA1FFFD8CA1FFFEBE -:102C90001E697800302D2320292055265D265326D5 -:102CA00053265326302D7810A51B1C698CA1FFFDDF -:102CB0008CA1FFFE1E697800382D1C698CA1FFFDD8 -:102CC0008CA1FFFE1E697800302DE47984A13000CC -:102CD00040006F26EC7884A00300C00077261468BB -:102CE00085A000801668012014007800FA2284A1D3 -:102CF000070079007B26302D302D8326302D582D6E -:102D0000582D302D302D84A60004C000B4261C6838 -:102D100084A001004000382D8CA660208CA1FBFF10 -:102D20005A79B2699B786000AB7800009B786100AB -:102D3000146885A000801668AA787E157E137E141C -:102D4000A1202C019B7800000080AC8080AD0A009F -:102D50009820A6537F147F137F15106807809B78F7 -:102D60007E00AA787800382D146884A00080400086 -:102D7000BB26176808001B78D8007800F71B0023D3 -:102D80007900C226C7264227C5267810A51B0070E9 -:102D900084A007007900CC26D426D626F226D42695 -:102DA000D426D224D426D4267810A51B1C698DA144 -:102DB00001001E690068066005A0C000E0260260F0 -:102DC000186884A00E004000EC261470B6682C71C0 -:102DD00088A1803E7800EE260920803F0421026809 -:102DE0000A2D5671B26E84A660004000402784A66A -:102DF0000008C000042784A6FF7FB268906894682A -:102E00007810C72E7800402784A62000400016279F -:102E100006A078109431D0780380C8001227D478A7 -:102E20007810F931D879DC7A78001A277810AE2C2E -:102E30007810943184A600804000402784A6FF7F4C -:102E4000B2689B78740078107C2D102078107C2D4F -:102E5000082084A62000C000382778107C2D1B8015 -:102E6000C8003327008084A03F0008A191A2000081 -:102E7000946B002102A3AE68906B002203A3AA68A2 -:102E80007800FF1B7800762B3370000082A20500CB -:102E900050004C277810A51B002379004F2752279C -:102EA0005C277F270022790055275A27762B5A273F -:102EB000A827F9277810A51B007086A00100C00084 -:102EC00069277810EF287810C72E34700A607800D0 -:102ED0006E27007086A00300400063270370050082 -:102EE0000120903F68203E703270002279007827E0 -:102EF000762B7D27A8277D27762B7810A51B0070C1 -:102F000086A00100C0008C277810EF287810C72E0B -:102F100034700A6078009127007086A0030040009A -:102F20008627037005000120903F68203E703270B4 -:102F3000002279009B27A227A027A227A027A2274B -:102F40007810A51B7810992B1B7869007800F71B67 -:102F5000007086A00100C000B5277810EF28781017 -:102F6000C72E34700A607800BA27007086A003006C -:102F70004000AF2703700200807A94A2000F9B7874 -:102F80001800A87C84A4070015A26920803F042DA6 -:102F9000082D5671682005A04000D527106806A2AC -:102FA0004000EE2700687800C82703700500012064 -:102FB000903F68203E7032707E15A9202F000320BC -:102FC000000000807000E6277800DF277F15126A76 -:102FD000B36800071F68000823680300B06E5A7EBC -:102FE0001C6884A0000C40004F287810912B7800BA -:102FF0004F28007086A00100C00006287810EF2836 -:103000007810C72E34700A6078000B28007086A0F4 -:1030100003004000002803700200807A94A2000F91 -:103020009B781800A87C84A4070015A2A879A87929 -:103030008CA1FF00E8A1803E042D082D5671682068 -:1030400005A040002A28106806A240004328006816 -:1030500078001D28037005000120903F68203E7015 -:1030600032707E15A9202F00032000000080700020 -:103070003B28780034287F15126AB36800071F6860 -:10308000000823680300B06E5A7E1C6884A0000C00 -:1030900040004F2878108D2B587E78004F287E02F4 -:1030A000078284A00F0003800380038080A0003685 -:1030B00060204A7000604E700460527084A6600008 -:1030C00040008628946B906CA869AC6805A1C0008C -:1030D0007428D27BDA7BD67CDE7CB4A6FFB75A7E1E -:1030E0007810F03078008628AC681AA3002123A459 -:1030F000002405A340008628D27BDA7BD67CDE7CC8 -:10310000AC68B4A6FFBF5A7E78101D317F077810D7 -:10311000A12C09206A0084A60800400091280920FB -:103120006900B5A600205A7E1A79002D3E700782EC -:1031300084A00F0003800380038080A00036482015 -:103140007800F71B206005A04000AE2801802260B7 -:10315000086085A008000A60107026607C0006A048 -:103160007810C72E13680000176801001F68400020 -:103170001B680001007084A007007900BF28C728E1 -:10318000C928C928D528D128C728C728C728781012 -:10319000A51B7810E0287810D9287810DD17780062 -:1031A000FF1BA37000007800FF1B17680000780069 -:1031B0000825006805A0C000DE28026006607C00CB -:1031C000106005A04000E9280180D000E9287810AF -:1031D000A51B1260086084A0EFFF0A607C001860E5 -:1031E00005A04000F52801801A607C007810772D3A -:1031F00017681800780026297810772D17681900AD -:10320000780026297810772D17681A00780026296B -:10321000B4777810A12CB8718CA1FF00E8A1803E92 -:10322000042D082D682005A0C00018297800FF1B78 -:103230001068B47206A240002029006878001129A5 -:1032400000680A2017680500BF7000007810E028A9 -:103250001C6884A00100C0002F297810D92878109C -:10326000EF281B6800001F6820007810DD17780029 -:10327000FF1B82A20300C0006A2BA87DACA5FF0043 -:10328000A87EB4A6FF001C698DA180001E6984A1E0 -:103290000001400099298CA1FFFE1E69B4A6FF0021 -:1032A0004000832982A60F0048005A2940005A296D -:1032B00031200F002B852B857810242C40006429A9 -:1032C0007810332A78008C297810DF2B7E0C602947 -:1032D000046084A0F5FF06607810572A7F0C1C69F3 -:1032E0008DA100011E69587EB5A604005A7E84A6F1 -:1032F0000004C0007F291B7855007800F71B1B785D -:1033000069007800F71B7E0C6029046084A0F5FF3B -:1033100006607810572A7F0C587E84A60004C000EF -:1033200095291B7858007800F71B1B786A007800F5 -:10333000F71B7E0C4870602000618CA100104000DB -:10334000D9290862178294A2FF0082A20F004800C8 -:10335000AD294000AD2911200F00002602A2C800AF -:10336000B2293022086294A2FF00187086A02800BB -:10337000C000C22982A21900C800C8291120190062 -:103380007800C82982A20C00C800C82911200C00AE -:10339000002202A5C800CD2928227810E32B2B8516 -:1033A0002B857810242C4000D9297810332A7800F6 -:1033B000DD297810DF2B7810572A587885A0040073 -:1033C0005A787F0C1B7869007800F71B7E0C602907 -:1033D000006084A00010C000012A106084A00F00CB -:1033E000C000FB298CA10200C000FB298CA1F5FFC5 -:1033F00006617F0C7C00112032001920000078004B -:10340000232A086294A2FF00187086A02800C0003A -:10341000112A82A21900C800172A11201900780069 -:10342000172A82A20C00C800172A11200C0008637A -:103430001F839CA3FF0082A30F004800232A4000A3 -:10344000232A19200F00AB780100AB780300AB787A -:103450000100AA7AAA7BC0A805001C6885A000010B -:103460001E687F0C7C007E0C48716021082084A0BF -:10347000F0FF35A6867E18609A78AE7E1266A47834 -:1034800084A0F8FF8CA1070005A1A67816608A78B1 -:10349000B4A60F0037860482048084A0FF0005A62E -:1034A0000E60046084A0F5FF06607F0C7C007E0C3B -:1034B0004870602018609A78A47884A0F0FFA678FD -:1034C0001260847884A0F0FF86787F0C7C0082A252 -:1034D0000200C0006A2BA87A1C698DA180001E69B9 -:1034E00084A100024000AC2A8CA1FFFD1E6994A2B9 -:1034F000FF0082A20200C8006A2B7810F32A78101D -:10350000572A80A901000C2078109D2C7810E629FC -:10351000FF8840009F2A9B7860000028AA78587E88 -:10352000B5A604005A7E84A60004C0009B2A1B781E -:1035300055007800F71B1B7869007800F71B587E50 -:1035400084A60004C000A82A1B7858007800F71B46 -:103550001B786A007800F71B82A20200C800B42A18 -:1035600084A201004000BE2A487188A100000C21FD -:103570008CA10020C000BE2A112000007810D12BA1 -:103580007810F32A7810572A587885A004005A78C2 -:103590001B7869007800F71B7E0C7E0260290060B2 -:1035A0001120010084A00020C000E32A146084A040 -:1035B0004000C000E12A8CA1EFFF066106A0780060 -:1035C000F02A11200000AB780100AB780200AB7844 -:1035D0000300AA7AC0A804001C6885A000021E6827 -:1035E0007F027F0C7C007E0C48706020FF824000D0 -:1035F000FB2A11204000186080A002009A78A4786D -:1036000084A0BFFF05A2A67816608A78046084A013 -:10361000EFFF06607F0C7C007E00007086A0030038 -:103620004000152B7F007800182B7F007800662B58 -:1036300084A620004000662B887884A040004000CB -:10364000662BA87801804000252BB87B84A33F001F -:103650001B83C8002C2B008005A040004D2B1B8332 -:10366000C800352B01804000622B06A078109431F1 -:10367000B4787810F9317800662B84A600404000B9 -:103680004D2BB8781B80C800462B008084A03F00DB -:10369000C000622BB4A6FFBF5A7ED879DC7A012025 -:1036A000010008A1C800562B91A20000D279DA7956 -:1036B000D67ADE7A781094311B78670078105E3005 -:1036C0007800F71B1B7867007800F71B1B786A00EF -:1036D0007800F71B78109D2B1B7869007800F71B8A -:1036E0007810892B1B7869007800F71B236802008B -:1036F0007810912B1C698DA120001E69146884A08C -:1037000000804000852B176805001B786900780051 -:10371000F71B0120050078009F2B01200C0078008A -:103720009F2B0120060078009F2B01200D007800C0 -:103730009F2B0120090078009F2B012007009B7818 -:103740007F00AA78B5A608005A7E7C007E073F87D6 -:10375000BCA70F003B873B870387E0A00036B8A7D4 -:1037600020009A7FA47984A10F004000BF2B84A180 -:10377000F0FFA6781260046085A008000660388714 -:1037800038879A7FA47984A140004000CF2B84A180 -:10379000BFFFA6781660046085A0100006607F0752 -:1037A0007C009B781000AB780100AB780200AB780E -:1037B0000300AA7A9B786000AB7804007C0031207B -:1037C0000000292032009B781000AB780100AB7814 -:1037D0000300AB780100AA7DAA7E9B786000AB78DD -:1037E00005007C007E15078084A0FF000380038015 -:1037F00080A020009A78A4798CA1F0FF01204635A2 -:10380000042082A0280040000D2C2120842C1920A7 -:103810001400A9200C007800132C2120902C1920D2 -:103820001900A9200D0011206400042484A0F0FFD9 -:1038300006A14000222C2084002310A27000222C1C -:103840007800152C7F157C007E151120463514223A -:1038500082A232004800382C40003C2C2120762CDB -:1038600019201100A9200E001120320078004C2CE4 -:1038700082A228004000442C2120842C192014000E -:10388000A9200C0078004A2C2120902C1920190026 -:10389000A9200D0011206400002202A540005C2C2C -:1038A00048005C2C2084002310A27000592C780062 -:1038B0004C2C7F1506A07C007F1582A56400C800F3 -:1038C000652C087885A070000A78EC7884A0000345 -:1038D0004000732C04249EA00112C000732C012010 -:1038E00001217800742C042405A07C000112023010 -:1038F0000232034203440454045605660568067800 -:10390000067A070A070C070E0232024202520262CE -:103910000272056605760578057A057C057E057FC9 -:1039200002220232024202520454046404740476F5 -:103930000478047A047C047E047F9B78100046A0FF -:103940007C0084A7000F0C8084A7070003800380FD -:103950000380038005A1E0A080367C00D879DC7A62 -:10396000D0781B80C800B52C008084A03F0008A13F -:1039700091A200007C007E0F7920000109204035D3 -:103980009120008004217900C52CF72CCF2CCF2C5E -:10399000CF2CCF2CCF2CCD2CCD2C7810A51B4B7839 -:1039A0000400487884A00400C000D12C4B780800A3 -:1039B000487884A00800C000D82CB06885A00040DA -:1039C000B268587885A000405A78307884A080008A -:1039D000C000F72C1800F72C186884A02000C00045 -:1039E000F52C1B78DD007800F72C1B78E400912083 -:1039F00001807F0F7C007E0C1068078084A00F0080 -:103A0000038003800380E0A00036046084A00A00E5 -:103A1000C0002E2D086194A100FF40002E2D8CA126 -:103A2000FF000120190006A140001D2D01203200D9 -:103A300006A14000212D7800252D092020007800C6 -:103A4000272D09203F007800272D1120000000219C -:103A500005A20A60046085A0020006607F0C7C005D -:103A60001B786A007800F71B1B7869007800F71B49 -:103A70001B7858007800F71B1B7855007800F71B5F -:103A80001B78DD007800F71B1B78DC007800F71B43 -:103A90001B78E4007800F71B1B78E3007800F71B25 -:103AA0001B789E007800F71B1B789D007800F71BA1 -:103AB000A37001001B7846007800F71B7E00307869 -:103AC00084A0C000C000752D087884A0FDFF0A788E -:103AD0000500050005000500EC7884A021004000E9 -:103AE000752D087885A002000A787F007C00087890 -:103AF00085A002000A787C00307884A04000C000D5 -:103B00007C2D9800852DAC787C00087884A0FDFF82 -:103B10000A780500050005000500EC7884A0210066 -:103B20004000942D9800922DAC787E00087885A0F6 -:103B300002000A787F007C0084A770004000A82D56 -:103B40007E0C602D682F78106B1B782D682C7F0CF5 -:103B500017680300587884A0003F1A682F68000097 -:103B60002B6800004B780800E47805A0D0001520F1 -:103B700084A0200040001520EC7884A003004000C1 -:103B80001520180015207800702B7E0C1068078017 -:103B900084A00F0003800380038080A00036602093 -:103BA00048204A7000604E70046052707F0C7C00A8 -:103BB0002000200000002000000020000000200065 -:103BC0000000200000002000000020000000200075 -:103BD0000000200000002000000020000000200065 -:103BE0000000200000002000000020000000200055 -:103BF000000020006200090014001400479814001F -:103C00001400F598E798140014008000BF0000012C -:103C10000204082080F80AA214000B300CA2140041 -:103C200000A238887E812A84A08406383988C22878 -:103C3000C39C05A864083BA80830C128C39C01A206 -:103C40000C30472861816A840080A48456183A8821 -:103C500008A8E228A09CF3A8640829A80C3001A8B1 -:103C60000830E128A09C0D2804A2C064A067C06FA2 -:103C700014183B882370768577860FA86E783E8867 -:103C80000CA82B2805A2A064A067C06F14183B885D -:103C900023707685778601A83E886920C128C39C59 -:103CA00044200321A2208120DCA807A2140003A243 -:103CB0000080A884A48572189A843C88E21F01F6CB -:103CC00008A26E856F8604070830A09C140002A22B -:103CD0000080A4850930A884E21948F87481EB8635 -:103CE000EB852E87A9873F88E608F1A861F8E8A848 -:103CF00001F8140081F81600B285F0803295A2FA1E -:103D0000E21D1400328521F21400E21DA884E0D6E1 -:103D1000E61F140006A265687F812A84C11D2388DE -:103D2000160042600880FAA80080A48460812A847A -:103D300021F00830A884C61DD720228816000080F4 -:103D400048281110FCA80830008000A0022811109B -:103D5000FDA887A808303D281110FDA809A217006A -:103D60000C300080A485E21DC1DA1400E0263A87F9 -:103D7000A2FAF219E21F14000BA214000DA27E8118 -:103D80002A84A08406381002CD9C040700007E120D -:103D9000912000224920C72E0070047205A20C72E7 -:103DA00015A2087084A0FDFF05A24000D92E78005E -:103DB000DE2E037000007F1200207C00007084A0C3 -:103DC0000100C0000C2F08710481C800EB2E781090 -:103DD000A82F7800E32E0C708CA07F0040000C2FE1 -:103DE00004700480C800032F147005A0C000FF2ECB -:103DF000107005A04000032F02A1C800E32E077039 -:103E0000100078000C2FFF8A40000C2F78106B31C7 -:103E1000C000062F4000E32E7810562F03700000DC -:103E20007F1200207C002464FF844000302F702C1F -:103E30003920352F042768AE0C6830A6086829A5FC -:103E400021844000302F3887042705A0C0001B2F95 -:103E5000987075A04000302F3920322F78001A2F2B -:103E60007C000000040008000C0010001400180082 -:103E70001C0000007E129120002279200035712064 -:103E8000100007700A000770020003700000712024 -:103E9000200007700A00077002000370000049202C -:103EA0000000B37800007F1200207C004920562FCC -:103EB00004700480C800822F077012000871087017 -:103EC00006A1C0005E2F84A1300040006B2F86A0A9 -:103ED0003000C0005E2F007084A00100C000822F5F -:103EE000087084A00C00C000802F0C7184A1000316 -:103EF000C000802F84A17F00C000562F7800822F41 -:103F0000176803000770120007700800047084A08F -:103F10000800C000862F0770120008710481480055 -:103F20008B2FB378000003700000492000007C0054 -:103F30007E107E007E127E1591200022087178107E -:103F4000A82F7F157F12912001807F007F107C00B9 -:103F50000472182108710C7084A00003C000EA2FBD -:103F600084A10C00C000EA2F1382138213821382F3 -:103F700084A200010DA10B810B810F8184A1070098 -:103F80007900C22FCC2FDC2FEA2FDC2FFE2FFE2F43 -:103F9000EA2FFC2F7810A51B07700200FF8AC000D3 -:103FA000D52F492000007800D92F78106B31C00040 -:103FB000D52FB37800007C0007700200FF8AC00094 -:103FC000E32F7800E72F78106B31C000E32FB37830 -:103FD00000007C00077002007810562F7810BB2C70 -:103FE000146884A000804000F72F176802007C004E -:103FF0007810A51B7810A51B781050301072147122 -:104000000C709CA07F00002800A311A289A10000D1 -:10401000B07805A040001030B3780000780033304D -:10402000781050300427582C60AC0C63002222A377 -:10403000086300211BA3002405A340002930C80009 -:104040002930128410820A8389A10000602B780035 -:104050001030602B078ABAA7322F3DA7002C826848 -:10406000866F8E6C8A6B077012007810562F7C005A -:104070003887042705A0C0004430986005A04000A0 -:104080004D3060203920322F518A40004C3008706A -:1040900084A0C00086A0C0007C00512000007C00ED -:1040A000508A3987042704A0C0005D303920382F9A -:1040B000006064A0C0005D30602D7C007E127E0D2B -:1040C000912000227F0D806860208468886B8C6C52 -:1040D0005780D4AAFF0084A0FF00B8A0322F087E2A -:1040E000B5A60C00186884A0400040007930B5A641 -:1040F00001007E0F7920000158787F0F84A04000D6 -:104100004000883084A60100C0008830B5A60100B8 -:1041100007700400047084A00400C0008A3000709E -:1041200005A0400095307810A51B002405A3C00011 -:104130009B307800D830582C042760AC046000A471 -:104140007E001A70006001A31E700920FD04042186 -:1041500086A0FD047F00C000C83084A0010040009C -:10416000C83084A60100C000C83013700100177069 -:104170000000027607700100B3780100A0A40100DE -:1041800099A30000046000A41A70006001A31E70CF -:104190000C62002402A212700862002303A21670AF -:1041A000027607700100602B781038307800DA3022 -:1041B00078106B31C000D8307F1200207C007E1256 -:1041C0007E0D912000227F0D07700400047084A0F2 -:1041D0000400C000E630037008007F1200207C005D -:1041E0007E127E0D912000227F0D4920F030077055 -:1041F0000400047084A00400C000F930007005A021 -:10420000400004317810A51B087EB5A60C00186884 -:1042100084A0400040000E31B5A60100246805A02E -:1042200040001A3150203920352F602D78106B3125 -:10423000C00016317F1200207C007E127E007E01BD -:104240007E0D912000227F0D7F037F04087EB5A69E -:104250000C00186884A0400040003031B5A6010071 -:1042600049201D31246855A040006831702D602E12 -:104270003920352F042768AE0C6822A408681BA3D8 -:1042800048005531518AC00047317810A51B388746 -:10429000042705A0C0003B31987075A06020400045 -:1042A00068313920322F78003A31228420841A83F1 -:1042B00099A300000C69002422A1086900231BA116 -:1042C000C80064317810A51B712020007800883068 -:1042D0007F1200207C00087084A0C00086A0C0006F -:1042E00040009331042708AC04211E70088104218A -:1042F0001A700881042116700881042112707E0F43 -:104300007920000158787F0F84A0400040008E3152 -:1043100084A60100C0008E31B5A6010002760770A8 -:104320000100781038307C007E127E007E0D9120D6 -:104330000022492094317F0D7F08087184A1C000BC -:10434000C000AA31246805A04000BA317800DE2EF2 -:104350007800BA3108710481C800B2317810A82FF2 -:1043600078009D310770100008710481C800B431D5 -:104370007810A82F087086A00200C0009D31007040 -:1043800005A0C0009D3103700000492000007F128D -:1043900000207C007E127E147E137E157E0D9120FF -:1043A00000227F0D4920CA3180AD1000A020992045 -:1043B00031000C7084A07F00266807700800077029 -:1043C0000200037001004000E8310080AC80A5537A -:1043D00007700400047084A00400C000EA31492082 -:1043E0000000037000007F157F137F147F120020F0 -:1043F0007C007E127E007E0D912000227F0D4920E0 -:10440000F931806860208468886B8C6C5780D4AAEE -:10441000FF0084A0FF00B8A0322F087EB5A60400DC -:1044200007700400047084A00400C0001232582CED -:10443000042760AC046000A41A70006001A31E7021 -:1044400013700100177000000276077001007F00F2 -:104450000780092031000A20A0002C320871077063 -:1044600002000C81C8002C320C81480039327800DF -:10447000EA2FA0A4010099A300008A6B8E6C07703C -:10448000040049200000037000007F1200207C001F -:10449000A920100006A0048086808E81C8005132B9 -:1044A00000A2F0004C3286808E817C007E15A9200F -:1044B000100005A0400077321AA1C800773213829D -:1044C0008D8148006A321AA1C8006B32F0005F3259 -:1044D00078006F321AA108231082F0005F327E004C -:1044E000003284A0FFF780207F007F157C007E00D3 -:1044F000003285A0000878007332E000BF329120BE -:104500000060207801802278C000B93224782278B7 -:104510009120008069204035006884A00700400099 -:10452000A13286A002004000A13230680DA04000F8 -:10453000A132042105A04000A13201800A204000E0 -:104540006F3361208036A9208000346005A04000D0 -:10455000B33201803660C000B332106005A0400065 -:10456000B3327810191AE0AC10007000B93278003C -:10457000A5327810D4327810C2327810F9329120F6 -:1045800001807C003C7801803E78C000D3324078C6 -:104590003E78487805A04000D33201804A78C000B8 -:1045A000D3327810191A7C00347801803678C00034 -:1045B000F8323878367891200080447805A0C00021 -:1045C000E332012001010180467880A0803E402036 -:1045D000042065A04000F832206005A04000F432BD -:1045E00001802260400028330060402C7800E932CE -:1045F0007C00287801802A78C00027332C782A781C -:10460000307805A0C0000633012080000180327898 -:10461000038003800380038090A0803698A202006C -:10462000042384A008004000273390A2090004223C -:1046300005A040001F3301801220C000273304234F -:1046400084A0F7FF85A080001A207810191A7C003A -:1046500069204035006805A0400032333C6806AC54 -:1046600040006F3317600600B06084A0003F1A60FE -:104670001C6084A0FF0085A060001E6000604220D6 -:104680001067B66F78109216186805A040004A337C -:1046900001801A68086884A0EFFF0A68106801802A -:1046A000D00054337810A51B12682F6000002B60D7 -:1046B0000000682C7810DD176920403501200600C5 -:1046C000A268447984A10001C0006A33BA6901205C -:1046D0000400A2687810141A912001807C0009203F -:1046E0004F3564216920000178106B1B17600600AC -:1046F000586884A0003F1A601C6084A0FF0085A059 -:1047000048001E602F6000002B600000306884A00D -:1047100040004000AB334B680400A92014004868F7 -:1047200084A00400400098337000983378008F33E1 -:104730004B680900A9201400486884A001004000CB -:10474000A5337000A53378009C33A920FA007000CF -:10475000AB337800A733086884A0FDFF0A681B68A4 -:104760004600092068350B2007004C784A789120D4 -:1047700001807C0079200035781003347810CB3329 -:104780007810E0337810F533337800004778000074 -:104790004B7800007C0019200A00112046350422C5 -:1047A00086A032004000DD3319200C00042286A0D0 -:1047B0003C004000DD33192008002A7B2E7B7C0062 -:1047C0001920300011204635042286A03200400016 -:1047D000F23319203900042286A03C004000F23355 -:1047E00019202700367B3A7B7C0019200D00112010 -:1047F0004635042286A03C004000003419200A00FF -:104800003E7B427B7C001920AF2F112046350422CD -:1048100086A032004000153419207139042286A088 -:104820003C004000153419202626227B267B7C0084 -:02483000A7924D -:00000001FF -/* Version 1.31.00 ISP1000 Initiator RISC firmware */ diff --git a/firmware/qlogic/sd7220.fw.ihex b/firmware/qlogic/sd7220.fw.ihex deleted file mode 100644 index a3363631911243906f9654b8a5d75d1a3dcf0ff2..0000000000000000000000000000000000000000 --- a/firmware/qlogic/sd7220.fw.ihex +++ /dev/null @@ -1,513 +0,0 @@ -:10000000020A29020A87E5E630E6047F0180027FC2 -:1000100000E5E230E4047E0180027E00EE5F6008CD -:1000200053F9F7E4F5FE80087F0A121731120EA289 -:1000300075FC08E4F5FDE5E720E70343F908220035 -:1000400001201100042000755101E4F552F553F52B -:1000500052F57E7F04020438C2360552E552D3942D -:100060000C4005755201D23690070C7407F0A3744A -:10007000FFF0E4F50CA3F0900714F0A3F0750B204B -:10008000F509E4F508E508D39430400302040412AE -:100090000006150BE50870047F0180027F00E5096A -:1000A00070047E0180027E00EE5F6005121871D23E -:1000B0003553E1F7E5084509FFE50B25E025E02488 -:1000C00083F582E43407F583EFF085E220E552D32F -:1000D0009401400D1219F3E054A064407003020330 -:1000E000FB53F9F8909470E4F0E0F510AF09121E9C -:1000F000B3AF08EF4408F582758380E0F529EF443B -:1001000007121A3CF5225440D39400401EE52954AE -:10011000F070211219F3E04480F0E52254306508B4 -:1001200070091219F3E054BFF080091219F37440FA -:10013000F00203FB121A127583AE74FFF0AF087E53 -:1001400000EF4407F582E0FDE50B25E025E0248182 -:10015000F582E43407F583EDF090070EE004F0EF4C -:100160004407F582758398E0F528121A23400C1293 -:1001700019F3E04401121A320203F6AF087E00744C -:1001800080CDEFCD8D82F583E030E00A1219F3E0E7 -:100190004420F00203FB1219F3E054DFF0EE44AE0A -:1001A000121A4330E4030203FB749E121A0520E086 -:1001B000030203FB8F828E83E020E0030203FB1225 -:1001C00019F3E04410F0E5E320E708E508121A3AD5 -:1001D0004404F0AF087E00EF121A3A20E2341219FC -:1001E000F3E04408F0E5E430E6047D0180027D00A0 -:1001F000E57EC3940450047C0180027C00EC4D60D9 -:1002000005C2350203FBEE44D2121A434440F00209 -:1002100003FB1219F3E054F7F0121A127583D2E0BF -:1002200054BFF0900714E004F0E57E7003757E0182 -:10023000AF087E00121A2340121219F3E044011293 -:1002400019F2E05402121A320203FB1219F3E044CD -:10025000021219F2E054FEF0C235EE448A8F82F5A4 -:1002600083E0F517548F4440F07490FCE508440790 -:10027000FDF5828C83E0543F900702F0E054C08D7E -:10028000828C83F07492121A05900703121A197463 -:1002900082121A05900704121A1974B4121A0590E2 -:1002A0000705121A197494FEE5084406121A0AF595 -:1002B0001030E004D2378002C237E510547F8F82BD -:1002C0008E83F0304430121A035480D394004004DB -:1002D000D2398002C2398F828E83E04480F0121AB4 -:1002E000035440D394004004D23A8002C23A8F8231 -:1002F0008E83E04440F07492FEE5084406121A0A28 -:1003000030E704D2388002C2388F828E83E0547F77 -:10031000F0121E46E4F50A20030280033043031264 -:1003200019952002028003304203120C8F303006F0 -:10033000121995120C8F120D471219F3E054FBF0AD -:10034000E50AC39401404643E1081219F3E044046E -:10035000F0E5E420E72A121A127583D2E05408D39C -:10036000940040047F0180027F00E50AC3940140AD -:10037000047E0180027E00EF5E6005121DD78017AB -:10038000121A127583D2E04408F00203FB121A120B -:100390007583D2E054F7F0121E467F0812173174AD -:1003A0008EFE121A128E83E0F51054FEF0E5104412 -:1003B00001FFE508FDED4407F582EFF0E51054FE7E -:1003C000FFED4407F582EF121A11758386E04410A1 -:1003D000121A11E04410F01219F3E054FD4401FF29 -:1003E0001219F3EF121A3230320CE5084408F58284 -:1003F0007583827405F0AF0B1218D774102508F5B9 -:10040000080200850509E509D3940750030200821C -:10041000E57ED3940040047F0180027F00E57EC327 -:1004200094FA50047E0180027E00EE5F6002057E39 -:1004300030350B43E1017F0912173102005853E1B7 -:10044000FE0200588E6A8F6B8C6C8D6D756E017517 -:100450006F01757001E4F573F574F57590072FF071 -:10046000F53CF53EF546F547F53DF53FF56FE56F93 -:10047000700FE56B456A12072A758380743AF08025 -:100480000912072A758380741AF0E4F56EC3743F6D -:10049000956EFF120865758382EFF0121A4D1208EF -:1004A000C6E533F01208FA1208B140E1E56F700BAF -:1004B00012072A7583807436F0800912072A758323 -:1004C000807416F0756E0112072A7583B4E56EF01C -:1004D000121A4D743F256EF582E43400F583E5333E -:1004E000F074BF256EF582E434001208B140D8E400 -:1004F000F570F546F547F56E1208FAF583E0FE1241 -:1005000008C6E07C002400FFEC3EFEAD3BD3EF9D2F -:10051000EE9C50047B0180027B00E57070047A0140 -:1005200080027A00EB5A6006856E46757001D3EF43 -:100530009DEE9C50047F0180027F00E570B40104B1 -:100540007E0180027E00EF5E6003856E47056EE5EA -:100550006E647F70A3E5466005E547B47E0385467B -:1005600047E56F7008854676854777800EC3747FB0 -:100570009546F578C3747F9547F579E56F7037E553 -:10058000466547700C757301757401F53CF53D8047 -:1005900035E4F54EC3E5479546F53CC313F57125A3 -:1005A00046F572C3943F4005E4F53D8040C3743F77 -:1005B0009572F53D8037E5466547700F7573017597 -:1005C0007501F53EF53F754E018022E4F54EC3E519 -:1005D000479546F53EC313F5712546F572D3943F12 -:1005E0005005E4F53F8006E57224C1F53F056FE54F -:1005F0006FC39402500302046EE56D456C70028077 -:1006000004E574457590072FF07F01E53E6004E531 -:100610003C7014E4F53CF53DF53EF53F1208D27010 -:1006200004F00206A4807AE53CC3953E4007E53C11 -:10063000953EFF8006C3E53E953CFFE576D3957970 -:10064000400585767A800385797AE577C395785079 -:100650000585777B800385787BE57BD3957A403071 -:10066000E57B957AF53CF53EC3E57B957A900719D5 -:10067000F0E53CC313F571257AF572C3943F40054C -:10068000E4F53D801FC3743F9572F53DF53F80143E -:10069000E4F53CF53E900719F01208D27003F080A3 -:1006A000037401F01208657583D0E0540FFEAD3C71 -:1006B00070027E07BE0F027E80EEFBEFD39B74803C -:1006C000F898401FE4F53CF53E1208D27003F08024 -:1006D000127401F0E508FBEB4407F5827583D2E064 -:1006E0004410F0E508FBEB4409F58275839EEDF0BC -:1006F000EB4407F5827583CAEDF01208657583CC6B -:10070000EFF022E5084407F5827583BCE054F0F071 -:10071000E5084407F5827583BEE054F0F0E508442F -:1007200007F5827583C0E054F0F0E5084407F582D0 -:1007300022F0900728E0FEA3E0F5828E8322854216 -:100740004285414185404074C02FF58274023EF5D8 -:1007500083E542F074E02FF58274023EF58322E5D2 -:100760004229FDE433FCE53CC39DEC6480F87480D1 -:100770009822F583E0900722541FFDE0FAA3E0F5EC -:10078000828A83EDF022900722E0FCA3E0F5828CC0 -:100790008322900724FFED4407CFF0A3EFF02285DA -:1007A0003838853939853A3A74C02FF58274023E5B -:1007B000F58322900726FFED4407CFF0A3EFF02248 -:1007C000F074A02FF58274023EF5832274C02511C7 -:1007D000F582E43401F5832274002511F582E434B6 -:1007E00002F5832274602511F582E43403F5832237 -:1007F00074802511F582E43403F5832274E0251119 -:10080000F582E43403F5832274402511F582E43443 -:1008100006F5832274802FF58274023EF58322AFA1 -:10082000087E00EF4407F58222F583E5824407F550 -:1008300082E540F02274402511F582E43402F5830C -:100840002274C02511F582E43403F5832274002557 -:1008500011F582E43406F5832274202511F582E433 -:100860003406F58322E508FDED4407F58222E541D3 -:10087000F0E56564014564227E00FB7A00FD7C00A2 -:100880002274202511F582E434022274A02511F58A -:1008900082E4340322853E42853F418F4022853CDD -:1008A00042853D418F402275453F900720E4F0A3EB -:1008B00022F583E532F0056EE56EC3944022F0E543 -:1008C000084406F582227400256EF582E43400F5B2 -:1008D0008322E56D456C90072F22E4F9E53CD39522 -:1008E0003E2274802EF582E43402F583E02274A067 -:1008F0002EF582E43402F583E0227480256EF582C1 -:10090000E43400222542FDE433FC22854242854145 -:100910004185404022ED4C60030209E5EF4E7037FF -:10092000900726120789E0FD1207CCEDF09007280A -:10093000120789E0FD1207D8EDF0120786E0541F78 -:10094000FD120881F583EDF0900724120789E05429 -:100950001FFD120835EDF0EF64044E703790072646 -:10096000120789E0FD1207E4EDF0900728120789CD -:10097000E0FD1207F0EDF0120786E0541FFD1208AB -:100980008BF583EDF0900724120789E0541FFD12C8 -:100990000841EDF0EF64014E70047D0180027D009E -:1009A000EF64024E70047F0180027F00EF4D60789B -:1009B000900726120735E0FF1207FCEF120731E01F -:1009C000FF120808EFF0900722120735E0541FFFCE -:1009D00012084DEFF0900724120735E0541FFF1264 -:1009E0000859EFF0221207CCE4F01207D8E4F01215 -:1009F0000881F583E4F01208357414F01207E4E47A -:100A0000F01207F0E4F012088BF583E4F0120841CD -:100A10007414F01207FCE4F0120808E4F012084D18 -:100A2000E4F01208597414F02253F9F775FC10E43D -:100A3000F5FD75FE30F5FFE5E720E70343F908E52E -:100A4000E620E70B78FFE4F6D8FD53E6FE80097850 -:100A500008E4F6D8FD53E6FE758180E4F5A8D2A837 -:100A6000C2A9D2AFE5E220E50520E602800343E11A -:100A700002E5E220E00E9000007F007E08E4F0A393 -:100A8000DFFCDEFA020ADB43FA01C0E0C0F0C083FB -:100A9000C082C0D0121CE7D0D0D082D083D0F0D09A -:100AA000E053FAFE32021B55E493A3F8E493A3F655 -:100AB00008DFF98029E493A3F85407240CC8C33352 -:100AC000C4540F4420C8834004F456800146F6DF26 -:100AD000E4800B010204081020408090003FE47E77 -:100AE000019360C1A3FF543F30E509541FFEE49316 -:100AF000A360010ECF54C025E060AD40B880FE8CED -:100B0000648D658A668B67E4F569EF4E7003021D9C -:100B100055E4F568E5674566703212072A758390DB -:100B2000E41207297583C2E41207297583C4E4120D -:100B30000870702912072A758392E41207297583B9 -:100B4000C6E41207297583C8E4F0801190072612C5 -:100B50000735E41208707005120732E4F0121D55D3 -:100B6000121EBFE5674566703312072A758390E54C -:100B7000411207297583C2E5411207297583C41202 -:100B8000086E702912072A758392E54012072975AD -:100B900083C6E5401207297583C8800E9007261288 -:100BA000073512086E7006120732E540F0AF697E15 -:100BB00000AD67AC6612044412072A7583CAE0D3FD -:100BC0009400500C0568E568C394055003020B14AB -:100BD000228C608D611208DA7420400D2FF582742A -:100BE000033EF583E53EF0800B2FF58274033EF55E -:100BF00083E53CF0E53CD3953E403CE561456070C3 -:100C000010E9120904E53E120768403B120895807E -:100C100018E53EC39538401D853E38E53E600585A4 -:100C20003F3980038539398F3A120814E53E12079F -:100C3000C0E53FF0228043E5614560701912075F0F -:100C4000400512089E802712090B120814E5421273 -:100C500007C0E541F022E53CC39538401D853C388E -:100C6000E53C6005853D3980038539398F3A1208A6 -:100C700014E53C1207C0E53DF02285383885393946 -:100C8000853A3A120814E5381207C0E539F0227F98 -:100C900006121731121D23120E04120E33E0440AFD -:100CA000F0748EFE120E04120E0BEFF0E52830E504 -:100CB00003D38001C3400575142080037514081206 -:100CC0000E0475838AE514F0B4FF05751280800662 -:100CD000E514C313F512E4F516F57F121936121355 -:100CE000A3E50AC3940150090516E516C394144000 -:100CF000EAE5E420E728120E047583D2E05408D315 -:100D0000940040047F0180027F00E50AC394014003 -:100D1000047E0180027E00EF5E6003121DD7E57F36 -:100D2000C394114014120E047583D2E04480F0E5A0 -:100D3000E420E70F121DD7800A120E047583D2E05B -:100D4000547FF0121D2322748A850882F583E517EB -:100D5000F0120E3AE4F0900702E0120E177583903D -:100D6000EFF07492FEE5084407FFF5828E83E054AD -:100D7000C0FD900703E0543F4D8F828E83F09007B3 -:100D800004E0120E17758382EFF0900705E0FFED87 -:100D90004407F5827583B4EF120E03758380E05427 -:100DA000BFF030370A120E91758394E04480F03022 -:100DB000380A120E91758392E04480F0E52830E401 -:100DC0001A20390A120E04758388E0547FF0203A05 -:100DD0000A120E04758388E054BFF0748CFE120E64 -:100DE000048E83E0540F120E03758386E054BFF027 -:100DF000E5084406120DFD75838AE4F022F582753C -:100E00008382E4F0E5084407F582228E83E0F51042 -:100E100054FEF0E5104401FFE508FDED4407F582BE -:100E200022E515C45407FFE508FDED4408F5827579 -:100E3000838222758380E04440F0E5084408F5820F -:100E400075838A22E51625E025E024AFF582E43497 -:100E50001AF583E493F50D2243E11043E18053E159 -:100E6000FD85E11022E51625E025E024B2F582E4B7 -:100E7000341AF583E49322855582855483E515F071 -:100E800022E5E25420D3940022E5E25440D39400BA -:100E900022E5084406F58222FDE508FBEB4407F550 -:100EA000822253F9F775FE3022EF4E70261207CCDE -:100EB000E0FD90072612077B1207D8E0FD90072877 -:100EC00012077B120881120772120835E09007247E -:100ED000120778EF64044E70291207E4E0FD9007D2 -:100EE0002612077B1207F0E0FD90072812077B12FD -:100EF000088B120772120841E0541FFD900724125C -:100F0000077BEF64014E70047D0180027D00EF6479 -:100F1000024E70047F0180027F00EF4D60351207A2 -:100F2000FCE0FF900726120789EFF0120808E0FFA7 -:100F3000900728120789EFF012084DE0541FFF12A6 -:100F40000786EFF0120859E0541FFF90072412079C -:100F500089EFF022E4F553120E8140047F018002F4 -:100F60007F00120E8940047E0180027E00EE4F70E9 -:100F700003020FF685E11043E10253E10F85E11012 -:100F8000E4F551E5E3543FF552120E89401DAD5290 -:100F9000AF51121118EF600885E11043E140800B5A -:100FA00053E1BF120E5812000680FBE5E3543FF5F3 -:100FB00051E5E4543FF552120E81401DAD52AF5140 -:100FC000121118EF600885E11043E120800B53E116 -:100FD000DF120E5812000680FB120E8140047F01C2 -:100FE00080027F00120E8940047E0180027E00EEA6 -:100FF0004F6003120E5B22120E21EFF012109122AD -:1010000002110002104002109000000000000000D9 -:1010100001200120E4F5571216BD121644E4121007 -:10102000561214B7900726120735E4120731E4F080 -:101030001210561214B7900726120735E541120711 -:1010400031E540F0AF577E00AD567C00120444AF4E -:10105000567E000211EEFF900720A3E0FDE4F55656 -:10106000F540FEFCAB56FA1211517F0F7D18E4F5E6 -:1010700056F540FEFCAB56FA121541AF567E0012F3 -:101080001AFFE4FFF5567D1FF540FEFCAB56FA2231 -:1010900022E4F555E508FD74A0F556ED4407F55733 -:1010A000E52830E503D38001C340057F28EF8004A5 -:1010B0007F14EFC313F554E4F9120E1875838EE014 -:1010C000F510CEEFCEEED394004026E51054FE127C -:1010D0000E9875838EEDF0E5104401FDEB4407F5A5 -:1010E00082EDF0855782855683E030E301091E804A -:1010F000D4C234E9C395544002D2342202000622FD -:10110000303011901000E493F510901010E493F536 -:101110001012109012115022E4FCC3ED9FFAEFF56B -:101120008375820079FFE493CC6CCCA3D9F8DAF60E -:10113000E5E230E4028CE5ED24FFFFEF7582FFF578 -:1011400083E4936C70037F01227F00222211000050 -:10115000228E588F598C5A8D5B8A5C8B5D755E012F -:10116000E4F55FF560F56212072A7583D0E0FFC4ED -:10117000540FF561121EA585595ED3E55E955BE5BA -:101180005A12076B504B1207037583BCE0455E1281 -:1011900007297583BEE0455E1207297583C0E045C7 -:1011A0005EF0AF5FE560120878120AFFAF627E0062 -:1011B000AD5DAC5C120444E561AF5E7E00B4030536 -:1011C000121E218007AD5DAC5C121317055E021183 -:1011D0007A1207037583BCE045401207297583BE68 -:1011E000E045401207297583C0E04540F0228E5843 -:1011F0008F59755A017901755B01E4FB12072A7555 -:1012000083AEE0541AFF120865E0C4135407FEEFE2 -:10121000700CEE6535700790072FE0B4010DAF3507 -:101220007E00120EA9CFEBCF021E60E55964024585 -:101230005870047F0180027F00E559455870047E94 -:101240000180027E00EE4F602385414985404BE5D9 -:10125000594558702CAF5AFECDE9CDFCAB59AA5870 -:10126000120AFFAF5B7E00121E608015AF5B7E002E -:10127000121E60900726120735E549120731E54B2B -:10128000F0E4FDAF35FEFC120915228C648D651269 -:1012900008DA403CE56545647010120904C3E53E78 -:1012A000120769403B1208958018E53EC395384007 -:1012B0001D853E38E53E6005853F39800385393917 -:1012C0008F3A1207A8E53E120753E53FF022803B14 -:1012D000E5654564701112075F400512089E801F86 -:1012E00012073EE541F022E53CC39538401D853CA0 -:1012F00038E53C6005853D3980038539398F3A12E0 -:1013000007A8E53C120753E53DF02212079FE53898 -:10131000120753E539F0228C638D641208DA403CE1 -:10132000E56445637010120904C3E53E1207694085 -:101330003B1208958018E53EC39538401D853E3820 -:10134000E53E6005853F3980038539398F3A1207BC -:10135000A8E53E120753E53FF022803BE564456374 -:10136000701112075F400512089E801F12073EE5AC -:1013700041F022E53CC39538401D853C38E53C6092 -:1013800005853D3980038539398F3A1207A8E53C38 -:10139000120753E53DF02212079FE538120753E587 -:1013A00039F022E50DFEE5088E544405F555751516 -:1013B0000FF582120E7A1217A320310575150380DE -:1013C0000375150BE50AC39401503812142020311F -:1013D0000605150515800415151515E50AC39401B4 -:1013E0005021121420203104051580021515E50A3C -:1013F000C39401500E120E771217A3203105051564 -:10140000120E77E515B408047F0180027F00E51510 -:10141000B407047E0180027E00EE4F6002057F2249 -:10142000855582855483E515F01217A32212072AE9 -:101430007583AE74FF120729E0541AF534E0C41323 -:101440005407F53524FE602424FE603C24047063B8 -:1014500075312DE508FD74B612079274BC90072211 -:1014600012079574901207B37492803C75313AE577 -:1014700008FD74BA12079274C09007221207B6745E -:10148000C41207B374C88020753135E508FD74B8FF -:1014900012079274BEFFED4407900722CFF0A3EF2E -:1014A000F074C21207B374C6FFED4407A3CFF0A3D4 -:1014B000EFF022753401228E588F598C5A8D5B8A39 -:1014C0005C8B5D755E01E4F55F121EA585595ED3E8 -:1014D000E55E955BE55A12076B5057E55D455C701C -:1014E0003012072A758392E55E1207297583C6E5D7 -:1014F0005E1207297583C8E55E120729758390E59A -:101500005E1207297583C2E55E1207297583C480C0 -:1015100003120732E55EF0AF5F7E00AD5DAC5C129A -:101520000444AF5E7E00AD5DAC5C120BD1055E0283 -:1015300014CFAB5DAA5CAD5BAC5AAF59AE58021B81 -:10154000FB8C5C8D5D8A5E8B5F756001E4F561F5F7 -:1015500062F563121EA58F60D3E560955DE55C12B0 -:10156000076B5061E55F455E702712072A7583B6E9 -:10157000E5601207297583B8E5601207297583BAFB -:10158000E560F0AF617E00E56212087A120AFF8022 -:1015900019900724120735E56012072975838EE438 -:1015A0001207297401120729E4F0AF637E00AD5FD2 -:1015B000AC5E120444AF607E00AD5FAC5E12128B75 -:1015C00005600215582290114DE49390072EF012F9 -:1015D000081F7583AEE0541AF5347067EF4407F5C1 -:1015E000827583CEE0FF1313135407F536540FD3DF -:1015F0009400400612142D121BA9E536540F24FE48 -:10160000600C14600C146019240370378010021EE3 -:1016100091121E9112072A7583CEE054EFF0021D3D -:10162000AE121014E4F555121D850555E555C39409 -:101630000540F412072A7583CEE054C7120729E04B -:101640004408F022E4F558F559AF08EF4407F58255 -:101650007583D0E0FDC4540FF55AEF4407F5827549 -:1016600083807401F0120821758382E545F0EF4410 -:1016700007F58275838A74FFF0121A4D12072A75D6 -:1016800083BCE054EF1207297583BEE054EF1207C4 -:10169000297583C0E054EF1207297583BCE044101C -:1016A0001207297583BEE044101207297583C0E034 -:1016B0004410F0AF58E559120878020AFFE4F558D3 -:1016C0007D01F559AF35FEFC12091512072A758305 -:1016D000B674101207297583B87410120729758320 -:1016E000BA74101207297583BC7410120729758308 -:1016F000BE74101207297583C074101207297583F0 -:1017000090E41207297583C2E41207297583C4E4A3 -:10171000120729758392E41207297583C6E412071C -:10172000297583C8E4F0AF58FEE55912087A020A19 -:10173000FFE5E230E46CE5E754C064407064E5091D -:10174000C45430FEE50825E025E054C04EFEEF54B9 -:101750003F4EFDE52BAE2A7802C333CE33CED8F907 -:10176000F5828E83EDF0E52BAE2A7802C333CE33BB -:10177000CED8F9FFF5828E83A3E5FEF08F828E83AB -:10178000A3A3E5FDF08F828E83A3A3A3E5FCF0C3A2 -:10179000E52B94FAE52A94005008052BE52B7002FE -:1017A000052A22E4FFE4F558F556F5577482FC1239 -:1017B0000E048C83E0F510547FF0E5104480120E87 -:1017C00098EDF07E0A120E047583A0E020E026DE7C -:1017D000F40557E55770020556E5142401FDE4337E -:1017E000FCD3E5579DE5569C40D9E50A942050026C -:1017F000050A43E108C231120E047583A6E05512B2 -:1018000065127003D23122C23122900726E0FAA37A -:10181000E0F5828A83E0F541E539C395414026E54C -:10182000399541C39FEE12076B40047C0180027C16 -:1018300000E541643F60047B0180027B00EC5B605B -:101840002905418028C3E5419539C39FEE12076BF6 -:1018500040047F0180027F00E54160047E01800238 -:101860007E00EF5E600415418003853941853A4072 -:1018700022E5E230E460E5E130E25BE50970047FF7 -:101880000180027F00E50870047E0180027E00EE88 -:101890005F604353F9F8E5E230E43BE5E130E22EE6 -:1018A00043FA0253FAFBE4F510909470E510F0E56A -:1018B000E130E2E7909470E06510600343FA0405BC -:1018C00010909470E510F070E612000680E153FA73 -:1018D000FD53FAFB80C0228F54120006E5E130E090 -:1018E000047F0180027F00E57ED3940540047E01E1 -:1018F00080027E00EE4F603D855411E5E220E1322A -:1019000074CE121A0530E7047D0180027D008F82BB -:101910008E83E030E6047F0180027F00EF5D70156A -:101920001215C674CE121A0530E607E04480F04363 -:10193000F98012187122120E44E51625E025E024E4 -:10194000B0F582E4341AF583E493F50FE51625E04B -:1019500025E024B1F582E4341AF583E493F50E1200 -:101960000E65F510E50F54F0120E1775838CEFF02D -:10197000E50F30E00C120E04758386E04440F080E1 -:101980000A120E04758386E054BFF0120E9175831F -:1019900082E50EF0227F05121731120E04120E336B -:1019A0007402F0748EFE120E04120E0BEFF0751519 -:1019B00070120FF72034057515108003751550123D -:1019C0000FF72034047410800274F02515F51512F9 -:1019D0000E21EFF0121091203417E5156430600CE1 -:1019E00074102515F515B48003E4F515120E21EFDA -:1019F000F022F0E50B25E025E02482F582E43407AF -:101A0000F583227488FEE5084407FFF5828E83E0A3 -:101A100022F0E5084407F58222F0E054C08F828E60 -:101A200083F022EF4407F582758386E05410D39447 -:101A30000022F0900715E004F0224406F582758339 -:101A40009EE022FEEF4407F5828E83E022E49007B9 -:101A50002AF0A3F012072A758382E0547F12072927 -:101A6000E04480F01210FC12081F7583A0E020E013 -:101A70001A90072BE004F0700690072AE004F0901B -:101A8000072AE0B410E1A3E0B400DCEE44A6FCEFCA -:101A90004407F5828C83E0F532EE44A8FEEF44075C -:101AA000F5828E83E0F5332201201100042000909E -:101AB00000200F9200210F9400220F9600230F9810 -:101AC00000240F9A00250F9C00260F9E00270FA0D0 -:101AD000012001A2012101A4012201A6012301A8E4 -:101AE000012401AA012501AC012601AE012701B0A4 -:101AF000012801B400280FB640280FB8612801CB97 -:101B0000EFCBCAEECA7F01E4FDEB4A7024E508F58D -:101B10008274B6120829E508F58274B8120829E51E -:101B200008F58274BA1208297E007C00120AFF8030 -:101B300012900726120735E541F090072412073569 -:101B4000E540F012072A75838EE41207297401120A -:101B50000729E4F022E4F526F52753E1FEF52A757E -:101B60002B01F5087F0112173130301C901AA9E4BF -:101B700093F510901FF9E493F510900041E493F56C -:101B800010901ECAE493F5107F02121731120F5401 -:101B90007F03121731120006E5E230E70912100048 -:101BA00030300312110002004712081F7583D0E085 -:101BB000C4540FFD7543017544FF1208AA7404F064 -:101BC000753B01ED14600C14600B14600F2403705E -:101BD0000B800980001208A704F080061208A77481 -:101BE00004F0EE4482FEEF4407F5828E83E5451251 -:101BF00008BE758382E531F002114C8E608F611250 -:101C00001EA5E4FFCEEDCEEED39561E56012076B25 -:101C1000403974202EF582E43403F583E07003FF2D -:101C200080261208E2FDC39F401ECFEDCFEB4A7025 -:101C30000B8D421208EEF5418E40800C1208E2F541 -:101C4000381208EEF5398E3A1E80BC22755801E52F -:101C500035700C1207CCE0F54A1207D8E0F54CE5D8 -:101C600035B4040C1207E4E0F54A1207F0E0F54C35 -:101C7000E535B401047F0180027F00E535B402043C -:101C80007E0180027E00EE4F600C1207FCE0F54AF8 -:101C9000120808E0F54C85414985404B22755B01EF -:101CA000900724120735E0541FFFD3940250048F8D -:101CB000588005EF24FEF558EFC394184005755978 -:101CC000188004EF04F55985435AAF587E00AD598A -:101CD0007C00AB5B7A00121541AF5A7E0012180AE5 -:101CE000AF5B7E00021AFFE5E230E70E121003C27E -:101CF000303030031210FF203328E5E730E70512BB -:101D00000EA2800DE5FEC394205006120EA243F9E8 -:101D100008E5F230E70353F97FE5F15470D39400FE -:101D200050D822120E04758380E4F0E508440712AF -:101D30000DFD758384120E02758386120E02758363 -:101D40008CE054F3120E0375838E120E0275839489 -:101D5000E054FBF02212072A75838EE412072974DF -:101D600001120729E41208BE75838CE04420120892 -:101D7000BEE054DFF07484850882F583E0547FF080 -:101D8000E04480F022755601E4FDF557AF35FEFCC6 -:101D9000120915121C9D121E7A121C4CAF577E00A0 -:101DA000AD567C00120444AF567E000211EE75560B -:101DB00001E4FDF557AF35FEFC120915121C9D120A -:101DC0001E7A121C4CAF577E00AD567C00120444A4 -:101DD000AF567E000211EEE4F516120E44FEE50841 -:101DE0004405FF120E658F828E83F00516E516C33B -:101DF000941440E6E508120E2BE4F022E4F558F5C1 -:101E000059F55AFFFEAD58FC1209157F047E00AD4E -:101E1000587C001209157F027E00AD587C00020933 -:101E200015E53C253EFCE5422400FBE433FAECC317 -:101E30009BEA12076B400B8C42E53D253FF5418F35 -:101E4000402212090B227484F5188508198519821D -:101E5000851883E0547FF0E04480F0E04480F02275 -:101E6000EF4E700B12072A7583D2E054DFF0221276 -:101E7000072A7583D2E04420F02275580190072686 -:101E8000120735E0543FF541120732E0543FF54068 -:101E900022755602E4F557121DFCAF577E00AD5671 -:101EA0007C00020444E4F542F541F540F538F5398B -:101EB000F53A22EF5407FFE5F954F84FF5F9227F80 -:101EC00001E4FE0F0EBEFFFB2201200001042000F2 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF000000000000000000001201100042000810A -:00000001FF diff --git a/firmware/r128/r128_cce.bin.ihex b/firmware/r128/r128_cce.bin.ihex deleted file mode 100644 index 4831315d7b99c17b53150f9104868ec340bc5ce1..0000000000000000000000000000000000000000 --- a/firmware/r128/r128_cce.bin.ihex +++ /dev/null @@ -1,129 +0,0 @@ -:1000000000000000108038000000000010003800E0 -:10001000000000020000008E0000000200000091BD -:1000200000000000402E2423000000006062124FF8 -:10003000000000002E2B596D000000007677753E01 -:1000400000000000898984820000000023BC8B0D21 -:10005000000000002323232300000000238DABB405 -:1000600000000000232323230000000100B028002B -:100070000000000100032800000000010004C0008F -:100080000000000100030800000000023660300E8E -:100090000000000B00040000000000000000000051 -:1000A000000000010200151D0000000100001D0EEF -:1000B00000000001000039D900000001000019D73C -:1000C0000000000C0000001C00000001000019D618 -:1000D0000000000C0000001C0000000200000017DF -:1000E0000000000B01200000000000000100358A24 -:1000F0000000000100064000000000090000001E92 -:100100000000000108D015B4000000101910100004 -:100110000000000300002000000000000000280094 -:1001200000000001000308000000000100003D0E77 -:10013000000000010000C8000000000A0000882A3A -:10014000000000090000002A000000010200150F55 -:1001500000000002000028240000000100003D65AE -:100160000000000100003D66000000020000002BBE -:100170000000000100F32DB4000000012200D8BFF0 -:100180000000000100E088BF0000000C1333383786 -:1001900000000001020615650000000C0000003799 -:1001A00000000001020015640000000100003D662F -:1001B000000000020000002E000000040020083AA9 -:1001C0000000000100080800000000010006C0FF58 -:1001D000000000040040003D000000010007C800CE -:1001E00000000001000700FF000000030000000005 -:1001F0000000000C0000005C000000020000002E67 -:100200000000000C000000B00000000100003D767E -:100210000000000100032800000000010000480069 -:1002200000000001000208000000000106001D0E91 -:1002300000000001000248000000000100028800E8 -:100240000000000100F3C5F80000000100100000EC -:10025000000000060030004E0000000100003D6379 -:100260000000001080303DF0000000021000384314 -:1002700000000002000028430000000C000000B055 -:100280000000000100003D760000000100003D7705 -:100290000000000100003D0E0000000100003D0FC5 -:1002A000000000010050280000000006003000524D -:1002B0000000001080303DF00000000100003DF81B -:1002C00000000002000000520000000100053D0E89 -:1002D0000000000100103D0F00000002003000553A -:1002E0000000000100003D700000000100001E89B8 -:1002F0000000000100003D710000000300003D729D -:100300000000000C0000005C000000020000006221 -:100310000000000100003F280000000100003F270E -:100320000000000100003E820000000100003E8845 -:100330000000000100003E660000000100003E6772 -:100340000000000100003E760000000100003E6851 -:100350000000000100003E690000000100003E6C4A -:100360000000000000003E6D0000000100002800B9 -:1003700000000001005028000000000100003D685E -:100380000000000100030800000000060000006EED -:10039000000000010002C0000000000106303D62C4 -:1003A0000000000200000070000000020030006F3A -:1003B00000000000200038C0000000010001C0C0A3 -:1003C0000000000E0000007D0000000C0003287FEC -:1003D00000000001020015BB0000000C00030880B3 -:1003E0000000000002003DBC0000000100003DBB19 -:1003F0000000000000003DBC00000003000480007D -:100400000000000100048000000000030006C0029C -:100410000000000100B0280000000000306038003B -:100420000000000100C028000000000100B008002A -:100430000000000100D600000000000712801086B6 -:10044000000000000000280000000001000039CC7E -:1004500000000001000039CD00000001000039C992 -:1004600000000001000039CA00000000000039CB84 -:10047000000000011003B80000000001009000001F -:100480000000000110003800000000010003080017 -:100490000000000100903D1B0000000140203D0ACB -:1004A0000000000140203D0B00000001000880001A -:1004B000000000010001C0C00000000E0000009F0D -:1004C0000000000C000308800000000142203DBD38 -:1004D0000000000C0003087F0000000142003DBB4B -:1004E0000000000C000308800000000142203DBC19 -:1004F00000000002000000A20000000140203DBDFD -:100500000000000140003DBB0000000140203DBC58 -:1005100000000001000840000000000100A00000F1 -:1005200000000006003000A6000000101060380037 -:1005300000000009000000A80000000300400000C7 -:100540000000000300403D1D00000000000000000E -:1005500000000000000001000000000E000000AEDE -:10056000000000010001C0A900000001020015C741 -:100570000000000C000000B0000000000000280097 -:10058000000000010001C0AA00000001020015D215 -:10059000000000010001C0A900000003020015C70F -:1005A0000000000100003E88000000010001C0BA08 -:1005B0000000000102001728000000010001C0BB7C -:1005C000000000010200165A0000000000003E5B1F -:1005D000000000000000010000000000000010000A -:1005E000000000010006400B00000009000000BCF4 -:1005F00000000000000028000000000000000000D3 -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF diff --git a/firmware/radeon/R100_cp.bin.ihex b/firmware/radeon/R100_cp.bin.ihex deleted file mode 100644 index 151647b04fc42942a94d47a75efbf692fc45f41c..0000000000000000000000000000000000000000 --- a/firmware/radeon/R100_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:1000000000000000210070000000000020007000CF -:1000100000000004000000B400000004000000B86C -:10002000000000006F5B4D4C000000004C4C427F14 -:10003000000000005B568A92000000004CA09C6DFE -:1000400000000000AD4C4C4C000000004CE1AF3D06 -:1000500000000000D8AFAFAF00000000D64C4CDC71 -:10006000000000004CD10D1000000016000F000031 -:1000700000000000362F242D0000000400000012B4 -:1000800000000016000F000000000000362F282D91 -:1000900000000002000380E70000000204002C972B -:1000A00000000016000F000100000000333A373056 -:1000B00000000002000077EF0000000200061000C0 -:1000C0000000001A000000210000001E0000400097 -:1000D00000000002000610000000001A00000021CD -:1000E0000000001E0000400000000002000610009A -:1000F0000000001A000000210000001E0000400067 -:100100000000000400000017000000020003802B24 -:1001100000000002040067E0000000040000001777 -:1001200000000002000077E000000002000650001E -:1001300000000002000037E100000006040067E153 -:1001400000000002000077E000000002000077E1FC -:1001500000000006000077E100000000FFFFFFFF45 -:100160000000000010000000000000020003802BCF -:1001700000000006040067E0000000020000767541 -:100180000000000200007676000000020000767792 -:100190000000000600007678000000020003802CBA -:1001A00000000002040026760000000200007677BE -:1001B0000000000600007678000000180000002F04 -:1001C000000000180000002F0000000600000000E2 -:1001D000000000180000003000000018000000308F -:1001E0000000000600000000000000020160500056 -:1001F000000000020006500000000002000980001C -:1002000000000002000610000000000464C0603E10 -:1002100000000002000380E600000002040025C583 -:1002200000000016000800000000000000000000B0 -:10023000000000020400251D00000002000075807F -:100240000000000200067581000000020400258005 -:100250000000000200067581000000040000004953 -:10026000000000000000500000000002000380E6D3 -:1002700000000002040025C5000000020006100076 -:10028000000000020000750E000000020001900056 -:10029000000000140001105500000012000000557D -:1002A000000000020400250F000000040000504F71 -:1002B00000000002000380E600000002040025C5E3 -:1002C0000000000200007565000000020000756675 -:1002D000000000040000005800000002000380E657 -:1002E00000000002040025C50000000201E655B42C -:1002F000000000024401B0E40000000201C110E46B -:10030000000000182666706600000002040C2565D7 -:1003100000000018000000660000000204002564D0 -:100320000000000200007566000000040000005D8F -:1003300000000008004010690000000200101000DA -:1003400000000002000D80FF000000080080006C2B -:1003500000000002000F900000000002000E00FFED -:100360000000000600000000000000180000008FE0 -:10037000000000040000005B00000002000380E6B3 -:1003800000000002040025C5000000020000757690 -:100390000000000200065000000000020000900073 -:1003A0000000000200041000000000020C00350EE6 -:1003B0000000000200049000000000020005100090 -:1003C0000000000201E785F80000000200200000A4 -:1003D0000000000C0060007E000000020000756359 -:1003E00000000021006075F0000000042000707320 -:1003F000000000040000507300000002000380E6CB -:1004000000000002040025C500000002000075760F -:100410000000000200007577000000020000750E69 -:10042000000000020000750F0000000200A0500054 -:100430000000000C0060008300000021006075F0E7 -:1004400000000002000075F80000000400000083B6 -:1004500000000002000A750E00000002000380E6A2 -:1004600000000002040025C5000000020020750FF6 -:1004700000000004006000860000000200007570AB -:100480000000000200007571000000060000757297 -:1004900000000002000380E600000002040025C501 -:1004A00000000002000050000000000200A0500008 -:1004B0000000000200007568000000020006100045 -:1004C0000000000C00000095000000020005800004 -:1004D000000000020C60756200000004000000973C -:1004E00000000002000380E600000002040025C5B1 -:1004F000000000040060009600000000400070E56D -:1005000000000002000380E600000002040025C590 -:1005100000000002000380E50000001C000000A8AD -:1005200000000018000650AA00000002040025BBCD -:1005300000000018000610AB00000000040075BCAD -:1005400000000002000075BB00000000000075BC48 -:100550000000000600090000000000020009000081 -:1005600000000006000D800200000002000078324A -:10057000000000020000500000000002000380E7BD -:100580000000000204002C97000000020000782008 -:100590000000000200007821000000000000780048 -:1005A000000000020120000000000002200770008F -:1005B0000000000201200000000000022000700086 -:1005C0000000000200061000000000020120751B60 -:1005D000000000028040750A000000028040750B98 -:1005E000000000020011000000000002000380E58E -:1005F0000000001C000000C600000018000610AB40 -:1006000000000002844075BD00000018000610AA1A -:1006100000000002840075BB00000018000610AB4B -:1006200000000002844075BC00000004000000C906 -:1006300000000002804075BD00000002800075BB14 -:1006400000000002804075BC000000020010800025 -:1006500000000002014000000000000C006000CD1E -:100660000000002020C0700000000012000000CF39 -:100670000000000600800000000000060080751DDC -:100680000000000000000000000000020000775C95 -:100690000000000200A050000000000200661000F0 -:1006A000000000200460275D000000000000400002 -:1006B0000000000201E0083000000000210070008E -:1006C000000000006464614D00000000696874204F -:1006D00000000000000000730000000000000000A7 -:1006E000000000020000500000000002000380D063 -:1006F00000000002040025E000000000000075E199 -:10070000000000000000000100000002000380E083 -:1007100000000002040023940000000000005000CC -:1007200000000000000000000000000000000000C9 -:1007300000000000000000080000000000000004AD -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/R200_cp.bin.ihex b/firmware/radeon/R200_cp.bin.ihex deleted file mode 100644 index 3a0bd73111c4b95882b0586c0a94ba6737c8a50c..0000000000000000000000000000000000000000 --- a/firmware/radeon/R200_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:1000000000000000210070000000000020007000CF -:1000100000000004000000BF00000004000000C356 -:10002000000000007A685E5D000000005D5D55889C -:100030000000000068659197000000005DA19F78B6 -:10004000000000005D5D5D5D000000005DEE5D5044 -:1000500000000000F2ACACAC00000000E75DF9E984 -:1000600000000000B1DD0E1100000000E2AFAFAFF4 -:1000700000000016000F000000000000452F232D97 -:10008000000000040000001300000016000F000034 -:1000900000000000452F272D00000016000F000172 -:1000A000000000003E4D4A3700000002000077EFDC -:1000B00000000002000610000000001A00000020EE -:1000C0000000001E000040000000000200061000BA -:1000D0000000001A000000200000001E0000400088 -:1000E00000000002000610000000001A00000020BE -:1000F0000000001E00004000000000040000001688 -:10010000000000020003802A00000002040067E0F3 -:10011000000000040000001600000002000077E06C -:10012000000000020006500000000002000037E15D -:1001300000000006040067E100000002000077E014 -:1001400000000002000077E100000006000077E1F7 -:1001500000000000FFFFFFFF000000001000000093 -:100160000000000007F007F0000000020003802AF2 -:1001700000000006040067E0000000020003802C7D -:100180000000000204002741000000020400274193 -:100190000000000204002743000000020000767502 -:1001A0000000000200007676000000020000767772 -:1001B0000000000600007678000000020003802C9A -:1001C0000000000204002741000000020400274153 -:1001D00000000002040027430000000200007676C1 -:1001E000000000020000767700000006000076782C -:1001F000000000020003802B0000000204002676AD -:100200000000000200007677000000020003802C4E -:100210000000000204002741000000020400274300 -:100220000000000600007678000000020003802C29 -:1002300000000002040027410000000204002741E2 -:10024000000000020400274300000006000076784A -:10025000000000180000002F000000180000002F10 -:100260000000000600000000000000180000003739 -:100270000000001800000037000000060000000029 -:100280000000000201605000000000020006500063 -:1002900000000002000980000000000200061000BB -:1002A0000000000464C06051000000160008000057 -:1002B0000000000000000000000000020400251DF6 -:1002C0000000000200007580000000020006758139 -:1002D0000000000204002580000000020006758175 -:1002E000000000040000005A000000000000500060 -:1002F0000000000200061000000000020000750E61 -:1003000000000002000190000000001400011064D1 -:100310000000001200000064000000020400250F2D -:10032000000000040000505E00000002000075653F -:100330000000000200007566000000040000006577 -:100340000000000201E655B4000000024401B0F0D4 -:100350000000000201C110F0000000182666707154 -:1003600000000002040C2565000000180000007168 -:100370000000000204002564000000020000756611 -:100380000000000400000068000000080040107435 -:10039000000000020010100000000002000D80FFAD -:1003A000000000080080007700000002000F9000AD -:1003B00000000002000E00FF000000060000000028 -:1003C0000000001800000094000000040000006815 -:1003D00000000002000075760000000200065000D8 -:1003E0000000000200009000000000020004100065 -:1003F000000000020C00350E000000020004900016 -:1004000000000002000510000000000201E785F86E -:1004100000000002002000000000000C00600087C7 -:10042000000000020000756300000021006075F00C -:10043000000000042000707C000000040000507CDC -:1004400000000002000075760000000200007577D1 -:10045000000000020000750E000000020000750F91 -:100460000000000200A050000000000C0060008AA4 -:1004700000000021006075F000000002000075F827 -:10048000000000040000008A00000002000A750E4F -:10049000000000020020750F000000040060008DC5 -:1004A000000000020000757000000002000075717D -:1004B00000000006000075720000000200005000FD -:1004C0000000000200A0500000000002000075685B -:1004D00000000002000610000000000C0000009860 -:1004E0000000000200058000000000020C60756240 -:1004F000000000040000009A000000040060009961 -:1005000000000000400070F100000002000380F1D4 -:100510000000001C000000A700000018000650A901 -:1005200000000002040025BB00000018000610AA0D -:1005300000000000040075BC00000002000075BB54 -:1005400000000000000075BC00000006000900006B -:10055000000000020009000000000006000D8002FB -:10056000000000020000500000000002000078219E -:100570000000000000007800000000020000782168 -:10058000000000000000780000000002016650003A -:1005900000000002000A000000000002000671CC0A -:1005A000000000020286F1CD00000010000000B73C -:1005B00000000000210070000000001C000000BED0 -:1005C000000000020006500000000002000A0000C7 -:1005D000000000020006100000000002000B0000F6 -:1005E000000000023806700000000004000A00BA93 -:1005F0000000000020007000000000020120000048 -:10060000000000022007700000000002012000002E -:100610000000000020007000000000020006100032 -:10062000000000020120751B000000028040750AD6 -:10063000000000028040750B000000020011000065 -:1006400000000002000380F10000001C000000D147 -:1006500000000018000610AA00000002844075BDCA -:1006600000000018000610A900000002840075BBFD -:1006700000000018000610AA00000002844075BCAB -:1006800000000004000000D400000002804075BD9E -:1006900000000002800075BB00000002804075BCB5 -:1006A0000000000200108000000000020140000075 -:1006B0000000000C006000D80000002020C0700086 -:1006C00000000012000000DA0000000600800000B8 -:1006D000000000060080751D00000002000025BB20 -:1006E00000000004000040D4000000020000775C1D -:1006F0000000000200A05000000000020066100090 -:10070000000000200460275D0000000000004000A1 -:1007100000000002000079990000000200A05000D3 -:100720000000000200661000000000200460299B09 -:1007300000000000000040000000000201E008305E -:1007400000000000210070000000000200005000C6 -:10075000000000020003805600000002040025E0B3 -:1007600000000000000075E1000000000000000132 -:1007700000000002000380ED0000000004007394FC -:100780000000000000000000000000000000000069 -:1007900000000002000078C400000002000078C5DC -:1007A00000000002000078C600000002000079246A -:1007B00000000002000079250000000200007926F8 -:1007C00000000004000000F2000000020000792494 -:1007D00000000002000079250000000200007926D8 -:1007E00000000004000000F900000000000000000C -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/R300_cp.bin.ihex b/firmware/radeon/R300_cp.bin.ihex deleted file mode 100644 index d307d56882c9e1cb4da5015796e594a5ba8e8ca1..0000000000000000000000000000000000000000 --- a/firmware/radeon/R300_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:10000000000000004200E000000000004000E000AE -:1000100000000008000000AE00000008000000B270 -:100020000000000067554B4A000000004A4A447532 -:100030000000000055527D83000000004A8C8B6553 -:10004000000000004AEF4AF6000000004AE14A4A78 -:1000500000000000E497979700000000DB4AEBDD0A -:10006000000000009CCC4A4A00000000D1989898FB -:10007000000000004A0F9AD600000004000CA00007 -:1000800000000038000D0012000000040000E8B479 -:1000900000000038000D0014000000040000E8B665 -:1000A00000000038000D0016000000040000E854B5 -:1000B00000000038000D0018000000040000E855A2 -:1000C00000000038000D001A000000040000E8568F -:1000D00000000038000D001C000000040000E8577C -:1000E00000000038000D001E000000040000E8249D -:1000F00000000038000D0020000000040000E8258A -:1001000000000038000D0022000000040000E8306C -:1001100000000038000D0024000000040000F0C0C2 -:1001200000000038000D0026000000040000F0C1AF -:1001300000000038000D0028000000040000F0411D -:1001400000000038000D002A000000040000F184C7 -:1001500000000038000D002C000000040000F185B4 -:1001600000000038000D002E000000040000F186A1 -:1001700000000038000D0030000000040000F1878E -:1001800000000038000D0032000000040000F18083 -:1001900000000038000D0034000000040000F3935C -:1001A00000000038000D0036000000040000F38A53 -:1001B00000000038000D0038000000040000F38E3D -:1001C000000000040000E821000000040140A0003D -:1001D00000000018000000430000000400CCE8000C -:1001E00000000004001B000100000004080048009B -:1001F00000000004001B000100000004080048008B -:1002000000000004001B000100000004080048007A -:10021000000000080000003A000000000000A000FC -:10022000000000042000451D000000040000E580DF -:1002300000000004000CE581000000040800458077 -:1002400000000004000CE5810000000800000047E9 -:10025000000000000000A00000000004000C2000CE -:10026000000000040000E50E000000040003200070 -:10027000000000280002205100000024000000516E -:10028000000000040800450F000000080000A04B1B -:10029000000000040000E565000000040000E566C1 -:1002A00000000008000000520000000403CCA5B4C8 -:1002B00000000004054320000000000400022000AC -:1002C000000000304CCCE05E0000000408274565CB -:1002D000000000300000005E0000000408004564DB -:1002E000000000040000E566000000080000005562 -:1002F00000000010008020610000000400202000A9 -:1003000000000004001B00FF00000010010000645A -:1003100000000004001F200000000004001C00FF7B -:100320000000000C00000000000000300000008011 -:100330000000000800000055000000040000E57601 -:1003400000000004000CA0000000000400012000D8 -:100350000000000400082000000000041800650EE2 -:10036000000000040009200000000004000A200032 -:1003700000000004000F0000000000040040000026 -:100380000000001800000074000000040000E56395 -:10039000000000C200C0E5F900000008000000698C -:1003A000000000080000A069000000040000E576DD -:1003B000000000040000E577000000040000E50EE6 -:1003C000000000040000E50F000000040140A00050 -:1003D0000000001800000077000000C200C0E5F92E -:1003E0000000000800000077000000040014E50E83 -:1003F000000000040040E50F0000000800C0007A83 -:10040000000000040000E570000000040000E57139 -:100410000000000C0000E572000000040000A000D5 -:10042000000000040140A000000000040000E56896 -:1004300000000004000C20000000001800000084F0 -:1004400000000004000B00000000000418C0E5627A -:1004500000000008000000860000000800C00085C1 -:1004600000000004000700E30000003800000092D4 -:1004700000000030000CA09400000004080045BB00 -:1004800000000030000C2095000000000800E5BCD2 -:10049000000000040000E5BB000000000000E5BC17 -:1004A0000000000C00120000000000040012000018 -:1004B0000000000C001B0002000000040000A0006F -:1004C000000000040000E821000000000000E80037 -:1004D000000000040000E821000000000000E82EF9 -:1004E0000000000402CCA000000000040014000082 -:1004F00000000004000CE1CC00000004050DE1CD7B -:10050000000000040040000000000018000000A4EB -:100510000000000400C0A00000000008000000A1CE -:1005200000000020000000A6000000004200E000E3 -:1005300000000038000000AD00000004000CA00026 -:10054000000000040014000000000004000C200063 -:10055000000000040016000000000004700CE00021 -:1005600000000008001400A9000000004000E000A6 -:10057000000000040240000000000004400EE00003 -:100580000000000402400000000000004000E00005 -:1005900000000004000C2000000000040240E51BE5 -:1005A000000000050080E50A000000050080E50B62 -:1005B000000000040022000000000004000700E327 -:1005C00000000038000000C000000030000C209542 -:1005D000000000050880E5BD00000030000C2094FC -:1005E000000000050800E5BB00000030000C20956D -:1005F000000000050880E5BC00000008000000C302 -:10060000000000050080E5BD000000050000E5BB1E -:10061000000000050080E5BC00000004002100008F -:1006200000000004028000000000001800C000C7A5 -:10063000000000404180E00000000024000000C9EC -:100640000000000C010000000000000C0100E51D8E -:1006500000000004000045BB00000008000080C34B -:10066000000000040000F3CE000000040140A000E0 -:100670000000000400CC20000000004008C053CF60 -:100680000000000000008000000000040000F3D221 -:10069000000000040140A0000000000400CC200085 -:1006A0000000004008C053D300000000000080009C -:1006B000000000040000F39D000000040140A000C1 -:1006C0000000000400CC20000000004008C0539E41 -:1006D00000000000000080000000000403C008309B -:1006E000000000004200E000000000040000A00044 -:1006F00000000004200045E0000000000000E5E1EB -:10070000000000000000000100000004000700E0FD -:10071000000000000800E39400000000000000005A -:10072000000000040000E8C4000000040000E8C568 -:10073000000000040000E8C6000000040000E928F2 -:10074000000000040000E929000000040000E92A7C -:1007500000000008000000E4000000040000E92898 -:10076000000000040000E929000000040000E92A5C -:1007700000000008000000EB0000000402C02000A0 -:10078000000000040006000000000034000000F338 -:1007900000000008000000F00000000400008000DD -:1007A00000000000C000E0000000000000000000A9 -:1007B00000000004000C200000000004001D0018D0 -:1007C00000000004001A000100000034000000FBDB -:1007D000000000080000004A000000080500A04AD0 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/R420_cp.bin.ihex b/firmware/radeon/R420_cp.bin.ihex deleted file mode 100644 index 3815891275f99d93b906d739c40b918031396b4a..0000000000000000000000000000000000000000 --- a/firmware/radeon/R420_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:10000000000000004200E000000000004000E000AE -:100010000000000800000099000000080000009D9A -:10002000000000004A554B4A000000004A4A44675D -:100030000000000055526F75000000004A7E7D658B -:1000400000000000D9D3DFF6000000004AC54A4A8C -:1000500000000000C882828200000000BF4ACFC1B9 -:100060000000000087B04A4A00000000B583838387 -:10007000000000004A0F85BA00000004000CA00038 -:1000800000000038000D0012000000040000E8B479 -:1000900000000038000D0014000000040000E8B665 -:1000A00000000038000D0016000000040000E854B5 -:1000B00000000038000D0018000000040000E855A2 -:1000C00000000038000D001A000000040000E8568F -:1000D00000000038000D001C000000040000E8577C -:1000E00000000038000D001E000000040000E8249D -:1000F00000000038000D0020000000040000E8258A -:1001000000000038000D0022000000040000E8306C -:1001100000000038000D0024000000040000F0C0C2 -:1001200000000038000D0026000000040000F0C1AF -:1001300000000038000D0028000000040000F0411D -:1001400000000038000D002A000000040000F184C7 -:1001500000000038000D002C000000040000F185B4 -:1001600000000038000D002E000000040000F186A1 -:1001700000000038000D0030000000040000F1878E -:1001800000000038000D0032000000040000F18083 -:1001900000000038000D0034000000040000F3935C -:1001A00000000038000D0036000000040000F38A53 -:1001B00000000038000D0038000000040000F38E3D -:1001C000000000040000E821000000040140A0003D -:1001D00000000018000000430000000400CCE8000C -:1001E00000000004001B000100000004080048009B -:1001F00000000004001B000100000004080048008B -:1002000000000004001B000100000004080048007A -:10021000000000080000003A000000000000A000FC -:10022000000000042000451D000000040000E580DF -:1002300000000004000CE581000000040800458077 -:1002400000000004000CE5810000000800000047E9 -:10025000000000000000A00000000004000C2000CE -:10026000000000040000E50E000000040003200070 -:10027000000000280002205100000024000000516E -:10028000000000040800450F000000080000A04B1B -:10029000000000040000E565000000040000E566C1 -:1002A00000000008000000520000000403CCA5B4C8 -:1002B00000000004054320000000000400022000AC -:1002C000000000304CCCE05E0000000408274565CB -:1002D000000000300000005E0000000408004564DB -:1002E000000000040000E566000000080000005562 -:1002F00000000010008020610000000400202000A9 -:1003000000000004001B00FF00000010010000645A -:1003100000000004001F200000000004001C00FF7B -:100320000000000C0000000000000030000000721F -:100330000000000800000055000000040000E57601 -:10034000000000040000E577000000040000E50E56 -:10035000000000040000E50F000000040140A000C0 -:100360000000001800000069000000C200C0E5F9AC -:100370000000000800000069000000040014E50E01 -:10038000000000040040E50F0000000800C0006C01 -:10039000000000040000E570000000040000E571AA -:1003A0000000000C0000E572000000040000A00046 -:1003B000000000040140A000000000040000E56807 -:1003C00000000004000C200000000018000000766F -:1003D00000000004000B00000000000418C0E562EB -:1003E00000000008000000780000000800C000774E -:1003F00000000004000700C7000000380000008073 -:10040000000000040000E5BB000000000000E5BCA7 -:10041000000000040000A000000000040000E8212B -:10042000000000000000E800000000040000E821D7 -:10043000000000000000E82E0000000402CCA00034 -:10044000000000040014000000000004000CE1CCD7 -:1004500000000004050DE1CD000000040040000094 -:10046000000000180000008F0000000400C0A00081 -:10047000000000080000008C000000200000009137 -:10048000000000004200E00000000038000000987A -:1004900000000004000CA000000000040014000094 -:1004A00000000004000C2000000000040016000002 -:1004B00000000004700CE00000000008001400942C -:1004C000000000004000E0000000000402400000C6 -:1004D00000000004400EE0000000000402400000A4 -:1004E000000000004000E00000000004000C2000BC -:1004F000000000040240E51B000000050080E50A42 -:10050000000000050080E50B000000040022000050 -:1005100000000004000700C700000038000000A42D -:10052000000000050080E5BD000000050000E5BBFF -:10053000000000050080E5BC000000040021000070 -:1005400000000004028000000000001800C000ABA2 -:10055000000000404180E00000000024000000ADE9 -:100560000000000C010000000000000C0100E51D6F -:1005700000000004000045BB00000008000080A748 -:10058000000000040000F3CE000000040140A000C1 -:100590000000000400CC20000000004008C053CF41 -:1005A0000000000000008000000000040000F3D202 -:1005B000000000040140A0000000000400CC200066 -:1005C0000000004008C053D300000000000080007D -:1005D000000000040000F39D000000040140A000A2 -:1005E0000000000400CC20000000004008C0539E22 -:1005F00000000000000080000000000403C008307C -:10060000000000004200E000000000040000A00024 -:1006100000000004200045E0000000000000E5E1CB -:10062000000000000000000100000004000700C4FA -:10063000000000000800E39400000000000000003B -:10064000000000040000E8C4000000040000E8C549 -:10065000000000040000E8C6000000040000E928D3 -:10066000000000040000E929000000040000E92A5D -:1006700000000008000000C8000000040000E92895 -:10068000000000040000E929000000040000E92A3D -:1006900000000008000000CF0000000402C020009D -:1006A000000000040006000000000034000000D735 -:1006B00000000008000000D40000000400008000DA -:1006C00000000000C000E000000000040000E1CCD9 -:1006D000000000040500E1CD00000004000CA000B3 -:1006E00000000034000000DE00000008000000DA16 -:1006F000000000000000A000000000040019E1CC90 -:1007000000000004001B0001000000040500A00020 -:1007100000000004080041CD00000004000CA0000F -:1007200000000034000000FB000000080000004A48 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B00000000004000C200000000004001D0018D0 -:1007C00000000004001A000100000034000000FBDB -:1007D000000000080000004A000000080500A04AD0 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/R520_cp.bin.ihex b/firmware/radeon/R520_cp.bin.ihex deleted file mode 100644 index 372ff82a014314a06545fe29a6255d57a2c04673..0000000000000000000000000000000000000000 --- a/firmware/radeon/R520_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:10000000000000004200E000000000004000E000AE -:100010000000000800000099000000080000009D9A -:10002000000000004A554B4A000000004A4A44675D -:100030000000000055526F75000000004A7E7D658B -:1000400000000000E0DAE6F6000000004AC54A4A77 -:1000500000000000C882828200000000BF4ACFC1B9 -:100060000000000087B04AD500000000B5838383FC -:10007000000000004A0F85BA00000004000CA00038 -:1000800000000038000D0012000000040000E8B479 -:1000900000000038000D0014000000040000E8B665 -:1000A00000000038000D0016000000040000E854B5 -:1000B00000000038000D0018000000040000E855A2 -:1000C00000000038000D001A000000040000E8568F -:1000D00000000038000D001C000000040000E8577C -:1000E00000000038000D001E000000040000E8249D -:1000F00000000038000D0020000000040000E8258A -:1001000000000038000D0022000000040000E8306C -:1001100000000038000D0024000000040000F0C0C2 -:1001200000000038000D0026000000040000F0C1AF -:1001300000000038000D0028000000040000E0006E -:1001400000000038000D002A000000040000E0005C -:1001500000000038000D002C000000040000E0004A -:1001600000000038000D002E000000040000E00038 -:1001700000000038000D0030000000040000E00026 -:1001800000000038000D0032000000040000F18083 -:1001900000000038000D0034000000040000F3935C -:1001A00000000038000D0036000000040000F38A53 -:1001B00000000038000D0038000000040000F38E3D -:1001C000000000040000E821000000040140A0003D -:1001D00000000018000000430000000400CCE8000C -:1001E00000000004001B000100000004080048009B -:1001F00000000004001B000100000004080048008B -:1002000000000004001B000100000004080048007A -:10021000000000080000003A000000000000A000FC -:10022000000000042000451D000000040000E580DF -:1002300000000004000CE581000000040800458077 -:1002400000000004000CE5810000000800000047E9 -:10025000000000000000A00000000004000C2000CE -:10026000000000040000E50E000000040003200070 -:10027000000000280002205100000024000000516E -:10028000000000040800450F000000080000A04B1B -:10029000000000040000E565000000040000E566C1 -:1002A00000000008000000520000000403CCA5B4C8 -:1002B00000000004054320000000000400022000AC -:1002C000000000304CCCE05E0000000408274565CB -:1002D000000000300000005E0000000408004564DB -:1002E000000000040000E566000000080000005562 -:1002F00000000010008020610000000400202000A9 -:1003000000000004001B00FF00000010010000645A -:1003100000000004001F200000000004001C00FF7B -:100320000000000C0000000000000030000000721F -:100330000000000800000055000000040000E57601 -:10034000000000040000E577000000040000E50E56 -:10035000000000040000E50F000000040140A000C0 -:100360000000001800000069000000C200C0E5F9AC -:100370000000000800000069000000040014E50E01 -:10038000000000040040E50F0000000800C0006C01 -:10039000000000040000E570000000040000E571AA -:1003A0000000000C0000E572000000040000A00046 -:1003B000000000040140A000000000040000E56807 -:1003C00000000004000C200000000018000000766F -:1003D00000000004000B00000000000418C0E562EB -:1003E00000000008000000780000000800C000774E -:1003F00000000004000700C7000000380000008073 -:10040000000000040000E5BB000000000000E5BCA7 -:10041000000000040000A000000000040000E8212B -:10042000000000000000E800000000040000E821D7 -:10043000000000000000E82E0000000402CCA00034 -:10044000000000040014000000000004000CE1CCD7 -:1004500000000004050DE1CD000000040040000094 -:10046000000000180000008F0000000400C0A00081 -:10047000000000080000008C000000200000009137 -:10048000000000004200E00000000038000000987A -:1004900000000004000CA000000000040014000094 -:1004A00000000004000C2000000000040016000002 -:1004B00000000004700CE00000000008001400942C -:1004C000000000004000E0000000000402400000C6 -:1004D00000000004400EE0000000000402400000A4 -:1004E000000000004000E00000000004000C2000BC -:1004F000000000040240E51B000000050080E50A42 -:10050000000000050080E50B000000040022000050 -:1005100000000004000700C700000038000000A42D -:10052000000000050080E5BD000000050000E5BBFF -:10053000000000050080E5BC000000040021000070 -:1005400000000004028000000000001800C000ABA2 -:10055000000000404180E00000000024000000ADE9 -:100560000000000C010000000000000C0100E51D6F -:1005700000000004000045BB00000008000080A748 -:10058000000000040000F3CE000000040140A000C1 -:100590000000000400CC20000000004008C053CF41 -:1005A0000000000000008000000000040000F3D202 -:1005B000000000040140A0000000000400CC200066 -:1005C0000000004008C053D300000000000080007D -:1005D000000000040000F39D000000040140A000A2 -:1005E0000000000400CC20000000004008C0539E22 -:1005F00000000000000080000000000403C008307C -:10060000000000004200E000000000040000A00024 -:1006100000000004200045E0000000000000E5E1CB -:10062000000000000000000100000004000700C4FA -:10063000000000000800E39400000000000000003B -:10064000000000040000E8C4000000040000E8C549 -:10065000000000040000E8C6000000040000E928D3 -:10066000000000040000E929000000040000E92A5D -:1006700000000008000000C8000000040000E92895 -:10068000000000040000E929000000040000E92A3D -:1006900000000008000000CF00000000DEADBEEF4B -:1006A000000000000000011600000004000700D355 -:1006B00000000004080050E700000004000700D418 -:1006C000000000040800401C000000000000E01DC5 -:1006D0000000000402C0200000000004000600002A -:1006E00000000034000000DE00000008000000DB15 -:1006F000000000040000800000000000C000E000D6 -:10070000000000040000E1CC000000040500E1CD81 -:1007100000000004000CA00000000034000000E510 -:1007200000000008000000E1000000000000A00040 -:10073000000000040019E1CC00000004001B0001CF -:10074000000000040500A00000000004080041CDE6 -:1007500000000004000CA00000000034000000FBBA -:10076000000000080000004A000000000000000037 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B00000000004000C200000000004001D0018D0 -:1007C00000000004001A000100000034000000FBDB -:1007D000000000080000004A000000080500A04AD0 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/R600_me.bin.ihex b/firmware/radeon/R600_me.bin.ihex deleted file mode 100644 index 30d4c14a308d3e91cc1039306bb5e7a4c3e79fc2..0000000000000000000000000000000000000000 --- a/firmware/radeon/R600_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A0000060441100000614000000000060000021 -:1000B000000005B20000000000600000000005C55F -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E0000000000000000020002036250000000075 -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000003100204A2D82 -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000002100203625C1 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001D00200E2D54 -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001D12 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000300020362407 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:1003800000000000000000100020362300000000E4 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E230000000000000011C7 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000003000204A2D0000000046 -:1003F0000000000000204811000000000000003252 -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A0000000000000204804000000000000002DB2 -:1005B0000020162D0000000000000000002F00A306 -:1005C00000000000000000000CC0000000000080DF -:1005D0000000002E0020162D00000000000000008A -:1005E000002F00A400000000000000000CC000006C -:1005F00000000081000000000040000000000087B3 -:100600000000002D00203623000000000000002E16 -:1006100000203624000000000000001D00201E2DD8 -:10062000000000000000000200210227000000007E -:100630000000000014E0000000000087000000003F -:1006400000600000000005ED0000000000600000F8 -:10065000000005E10000000200210E220000000061 -:100660000000000014C000000000008A0000001814 -:10067000C040362000000090000000002EE0000086 -:100680000000008E000000002CE000000000008D43 -:100690000000000200400E2D0000008F000000034B -:1006A00000400E2D0000008F0000000C00200E2DD9 -:1006B00000000000000000180020362300000000A9 -:1006C0000000000300210E220000000000000000D6 -:1006D00014C00000000000950000A00C0020441190 -:1006E0000000000000000000C020480000000000E2 -:1006F00000000000C04048000000009D0000A00C69 -:1007000000204411000000000000000000204811FB -:1007100000000000000000002EE000000000009B30 -:10072000000000002CE000000000009A0000000221 -:1007300000400E2D0000009C0000000300400E2D24 -:100740000000009C0000000C00200E2D00000000A6 -:10075000000000000020480300000000000000002E -:10076000003A0C0200000000003F000000280E23A9 -:10077000000000000000001000210E230000000017 -:100780000000001300203623000000000000001EBF -:100790000021022B000000000000000014C0000037 -:1007A000000000A40000001CC02036200000000053 -:1007B0000000001F0021022B0000000000000000CC -:1007C00014C00000000000A70000001BC02036205D -:1007D000000000000000000800210E2B00000000B7 -:1007E0000000007F00280E23000000000000000031 -:1007F000002F022300000000000000000CE00000B9 -:10080000000000DB000000002700000000000000E6 -:1008100000000000006000000000028C8100000069 -:1008200000204411000000000000000600204811D4 -:10083000000000000000000C00221E30000000003C -:100840009980000000204411000000000000000416 -:100850000020122D000000000000000800221224D9 -:10086000000000000000001000201811000000002F -:100870000000000000291CE400000000000000004F -:1008800000604807000001289B0000000020441180 -:1008900000000000000000000020480200000000EE -:1008A0009C00000000204411000000000000000037 -:1008B0000033146F000000000000000100333E23ED -:1008C0000000000000000000D90048000000000007 -:1008D0000000000000203C05000000008100000036 -:1008E00000204411000000000000000E002048110C -:1008F00000000000000000000020101000000000B8 -:100900000000E00700204411000000000000000F7C -:100910000021022B000000000000000014C00000B5 -:10092000000000C500F8FF0800204811000000008A -:100930009800000000404811000000D6000000F0C0 -:1009400000280E2200000000000000A0002F02235B -:1009500000000000000000000CC00000000000D4F7 -:100960000000001300200E2D000000000000000118 -:10097000002F022300000000000000000CE0000037 -:10098000000000CF00000002002F02230000000042 -:10099000000000000CE00000000000CE00003F005E -:1009A00000400C11000000D000001F0000400C119E -:1009B000000000D000000F0000200C11000000001B -:1009C0000038000900294A23000000003F00000011 -:1009D00000280E2B000000000000000200220E2361 -:1009E000000000000000000700494A23000000D674 -:1009F00000380F09002048110000000068000007BF -:100A000000204811000000000000000800214A27D3 -:100A1000000000000000000000204811000000005D -:100A2000060A020000294A2400000000000000001D -:100A300000204811000000000000000000204811C4 -:100A4000000000000000A20200204411000000008D -:100A500000FF000000284A220000000000000030D3 -:100A600000200E2D000000000000002E0020122D9E -:100A70000000000000000000002F008300000000C4 -:100A8000000000000CE00000000000E30000000097 -:100A900000600000000005E70000000000400000CA -:100AA000000000E40000000000600000000005EA13 -:100AB000000000070020222D0000000000000005BB -:100AC00000220E22000000000010000000280E236B -:100AD0000000000000000000002920680000000065 -:100AE00000000000003A0C0200000000000000EFCF -:100AF00000280E23000000000000000000292068EC -:100B0000000000000000001D00200E2D000000006D -:100B1000000000030021022300000000000000008C -:100B200014E00000000000F10000000B002102288A -:100B3000000000000000000014C00000000000F1F0 -:100B40000000040000292228000000000000001A14 -:100B500000203628000000000000001C00210E22AA -:100B6000000000000000000014C00000000000F6BB -:100B70000000A30C00204411000000000000000051 -:100B800000204811000000000000001E00210E227D -:100B9000000000000000000014C00000000001047C -:100BA0000000A30F0020441100000000000000130B -:100BB00000200E2D0000000000000001002F022385 -:100BC00000000000000000000CC00000000000FD5C -:100BD000FFFFFFFF00404811000001040000000279 -:100BE000002F022300000000000000000CC00000E5 -:100BF000000001000000FFFF004048110000010458 -:100C000000000004002F022300000000000000008C -:100C10000CC0000000000103000000FF004048116C -:100C20000000010400000001002048110000000045 -:100C30000002C40000204411000000000000001F5A -:100C400000210E22000000000000000014C000007F -:100C50000000010B0000001040210E2000000000E9 -:100C600000000019002036230000000000000018DA -:100C700040224A200000000000000010C0424A202C -:100C80000000010D0000000000200C110000000019 -:100C900000000019002036230000000000000000C2 -:100CA0000020481100000000000000000020481152 -:100CB000000000000000000A0020101100000000E9 -:100CC00000000000002F02240000000000000000CF -:100CD0000CE000000000011400000000002048119A -:100CE0000000000000000001005312240000011069 -:100CF000FFBFFFFF00283A2E000000000000001B8D -:100D000000210222000000000000000014C00000CA -:100D100000000127810000000020441100000000B5 -:100D20000000000D00204811000000000000001825 -:100D300000220E3000000000FC00000000280E23FE -:100D400000000000810000000020441100000000AD -:100D50000000000E0020481100000000000000000C -:100D600000201010000000000000E00E00204411E0 -:100D70000000000007F8FF080020481100000000F4 -:100D80000000000000294A230000000000000024A9 -:100D900000201E2D000000000000000800214A274E -:100DA00000000000000000000020481100000000CA -:100DB000060A020000294A2400000000000000008A -:100DC0000020481100000000000000000020481131 -:100DD0000000000000000000008000000000000093 -:100DE000810000000020441100000000000000010C -:100DF00000204811000000000000217C0020441168 -:100E000000000000008000000020481100000000E9 -:100E1000000000000020480600000000000000085C -:100E200000214A2700000000000000001700000019 -:100E3000000000000004217F00604411000006143F -:100E40000000001F00210230000000000000000030 -:100E500014C00000000006130000000400404C1104 -:100E60000000012E00000000006000000000000BE8 -:100E70000000000000600411000002FE00000000FD -:100E800000200411000000000000000000600811B4 -:100E90000000019F00000000006000000000015100 -:100EA0000000FFFF40280E2000000000000000109E -:100EB000C0211220000000000000FFFF4028062093 -:100EC0000000000000000010C0210A200000000007 -:100ED0000000000000341461000000000000000069 -:100EE00000741882000002A40001A1FD00604411FA -:100EF000000002C900003FFF002F022F0000000089 -:100F0000000000000CC000000000013800000000DC -:100F1000C04004000000000100000000006000006C -:100F20000000000B0000000000600411000002FE41 -:100F3000000000000020041100000000000000007C -:100F4000006008110000019F00003FFF002F022FEA -:100F500000000000000000000CE0000000000000A5 -:100F600000000000006000000000015100000010BF -:100F700040210E20000000000000FFFFC0281220CA -:100F800000000000000000104021162000000000BA -:100F90000000FFFFC0681A20000002A40001A1FDAC -:100FA00000604411000002C900003FFF002F022F23 -:100FB00000000000000000000CC00000000001491B -:100FC00000000000C0400400000000010000225C9E -:100FD00000204411000000000000000100300A2F32 -:100FE000000000000000000100210A2200000000B3 -:100FF0000000000300384A220000000000002256D2 -:1010000000204411000000000000001A00204811D8 -:10101000000000000000A1FC0020441100000000BE -:1010200000000001008048110000000000000000E6 -:10103000006000000000000B0000000000600000E5 -:101040000000017C00000000006000000000018D35 -:1010500000003FFF002F022F0000000000000000F2 -:101060000CE00000000000000000000000202C0840 -:10107000000000000000000000202411000000001B -:10108000000000000020281100000000000022568F -:10109000002044110000000000000016002048114C -:1010A000000000000000225C00204411000000004D -:1010B00000000003002048110000000093800000A1 -:1010C00000204411000000000000000200221E2940 -:1010D0000000000000000000007048EB00000189E3 -:1010E0000000000000600000000002A400000001F9 -:1010F000403306200000000000000000C03024093A -:101100000000000000003FFF002F022F0000000041 -:10111000000000000CE000000000000000000000E3 -:10112000006000000000028C9500000000204411C7 -:101130000000000000000000002F0221000000005D -:10114000000000000CE0000000000173000000003F -:10115000C0204800000000000000000100530621EC -:101160000000016F92000000002044110000000008 -:1011700000000000C0604800000001840001A1FDE3 -:101180000020441100000000000000130020062D84 -:1011900000000000000000000078042A000002E4C3 -:1011A00000000000002028090000000000003FFFB0 -:1011B000002F022F00000000000000000CC0000003 -:1011C0000000016500000000C040040000000001B4 -:1011D0000000021000600411000002FE00003FFF4A -:1011E000002F022F00000000000000000CE00000B3 -:1011F000000001810000001BC0203620000000001C -:101200000000001CC0203620000000003F800000CD -:1012100000200411000000004600000000600811DA -:101220000000019F0000000000800000000000009E -:101230000000A1FC002044110000000000003FFF5E -:10124000002F022F00000000000000000CC0000072 -:10125000000001880000000100804811000000002B -:101260000000002100804811000000000000FFFF86 -:1012700040280E200000000000000010C0211220B5 -:10128000000000000000FFFF4028162000000000C2 -:1012900000000010C0811A20000000008100000042 -:1012A000002044110000000000000006002048114A -:1012B000000000000000000800221E3000000000B6 -:1012C0000000003200201A2D000000000000E000A5 -:1012D0000020441100000000FFFBFF09002048111E -:1012E00000000000000000110020222D000000007E -:1012F00000001FFF00294A2800000000000000062F -:101300000020222D0000000000000000002920E83D -:10131000000000000000000000204808000000005D -:10132000000000000020481100000000060A020032 -:1013300000294A260000000000000000002048119B -:101340000000000000000000002048110000000024 -:10135000000001000020181100000000000000083B -:1013600000621E28000001280000000800822228D8 -:10137000000000000002C000002044110000000036 -:101380000000001B00600E2D000001AA0000001CE0 -:1013900000600E2D000001AA0000C00800204411CA -:1013A000000000000000001D00200E2D00000000C5 -:1013B0000000000014C00000000001A600000000B2 -:1013C000002004110000000000000000002048017F -:1013D000000000003900000000204811000000005B -:1013E0000000000000204811000000000000000084 -:1013F00000804802000000000000002000202E2D88 -:101400000000000000000000003B0D630000000031 -:101410000000000800224A23000000000000001025 -:1014200000224A23000000000000001800224A2386 -:1014300000000000000000000080480300000000E1 -:1014400000000000006000000000000B0000100021 -:1014500000600411000002FE0000000000200411E2 -:101460000000000000000000006008110000019F63 -:10147000000000070021062F0000000000000019F6 -:1014800000200A2D000000000000000100202C11A7 -:10149000000000000000FFFF4028222000000000A4 -:1014A0000000000F002622280000000000000010AD -:1014B00040212620000000000000000F0026262901 -:1014C00000000000000000000020280200000000D2 -:1014D0000000225600204411000000000000001B04 -:1014E000002048110000000000000000002F022131 -:1014F00000000000000000000CE00000000001CD32 -:101500000000225C00204411000000000000008167 -:1015100000204811000000000000A1FC0020441140 -:101520000000000000000001002048110000000041 -:101530000000008000201C110000000000000000DE -:10154000002F022700000000000000000CE0000057 -:10155000000001C90000000000600000000001D68A -:101560000000000100531E27000001C5000000011B -:1015700000202C11000000000000001F00280A229B -:10158000000000000000001F00282A2A00000000C0 -:101590000000000100530621000001BE0000225C93 -:1015A00000204411000000000000000200304A2F1B -:1015B000000000000000A1FC002044110000000019 -:1015C00000000001002048110000000000000001A0 -:1015D00000301E2F0000000000000000002F022736 -:1015E00000000000000000000CE00000000000000F -:1015F0000000000000600000000001D600000001B3 -:1016000000531E27000001D20000FFFF40280E20DB -:10161000000000000000000F00260E230000000064 -:1016200000000010C0211220000000000000000F88 -:101630000026122400000000000000000020141109 -:10164000000000000000000000601811000002A46B -:101650000001A1FD00204411000000000000000076 -:10166000002F022B00000000000000000CE0000032 -:10167000000001E500000010002216280000000014 -:10168000FFFF000000281625000000000000FFFFFB -:1016900000281A290000000000000000002948C5A9 -:1016A00000000000000000000020480A00000000C8 -:1016B0000000000000202C110000000000000010BD -:1016C0000022162300000000FFFF0000002816255E -:1016D000000000000000FFFF00281A2400000000A6 -:1016E00000000000002948C50000000000000000C4 -:1016F00000731503000001F200000000002018052F -:10170000000000000000000000731524000001F23A -:1017100000000000002D14C50000000000000000C3 -:10172000003008A200000000000000000020480275 -:10173000000000000000000000202802000000005F -:101740000000000000202003000000000000000056 -:1017500000802404000000000000000F002102258A -:10176000000000000000000014C00000000006138C -:1017700000000000002B1405000000000000000124 -:10178000009016250000000000000000006000002E -:101790000000000B0000000000600411000002FEC9 -:1017A0000000000000200411000000000000000004 -:1017B000006008110000019F000022560020441123 -:1017C000000000000000001A00294A22000000006A -:1017D00000000000C02000000000000000003FFFEB -:1017E000002F022F00000000000000000CE00000AD -:1017F0000000000000000000C02004000000000005 -:101800000000225C002044110000000000000003E2 -:1018100000384A21000000000000A1FC0020441113 -:10182000000000000000000100204811000000003E -:101830000000FFFF40281220000000000000001000 -:10184000C0211A20000000000000FFFF40280E20E9 -:101850000000000000000010C02116200000000061 -:101860000000000000741465000002A40001A1FD46 -:1018700000604411000002C900000001003306218D -:101880000000000000000000002F02210000000006 -:10189000000000000CC000000000020600003FFF36 -:1018A000002F022F00000000000000000CC000000C -:1018B000000001FF00000000C04004000000000123 -:1018C0000000000000600000000005C500000000EE -:1018D0000040040F00000200000000000060000053 -:1018E000000005B20000000000600000000005C517 -:1018F0000000021000600411000002FE0000000061 -:10190000006000000000018D000000000060000089 -:10191000000001890000000000600000000002A437 -:1019200000000000006000000000028C93800000B6 -:1019300000204411000000000000000000204808C2 -:10194000000000009500000000204411000000008D -:1019500000000000002F022F000000000000000027 -:101960000CE000000000021F00000000C040480022 -:101970000000021C92000000002044110000000042 -:1019800000000000C02048000000000000002256B7 -:101990000020441100000000000000160020481143 -:1019A000000000000000225C002044110000000044 -:1019B0000000000300204811000000000000A1FC0E -:1019C0000020441100000000000000010020481128 -:1019D000000000000001A1FD0020441100000000F3 -:1019E0000000000000600411000002E4000000009C -:1019F000C040040000000001000000000060000082 -:101A0000000005B20000A00C0020441100000000FE -:101A100000000000C020480000000000000000009E -:101A2000C04048000000000000000000006000000E -:101A30000000000B0000001840210A2000000000F8 -:101A400000000003002F0222000000000000000040 -:101A50000AE00000000002350000001A0020222DDC -:101A600000000000000801010029222800000000F9 -:101A70000000001A00203628000000000000A30C1F -:101A8000002044110000000000000000C0204800B9 -:101A90000000000000000000C0204800000000001E -:101AA00000000000C04048000000023A00000000B2 -:101AB000006000000000000B000000100060041136 -:101AC000000002FE3F800000002004110000000022 -:101AD00000000000006008110000019F0000225C6F -:101AE0000020441100000000000000030020481105 -:101AF000000000000000000000600000000002651F -:101B00000000001D00201E2D00000000000000014C -:101B100000211E27000000000000000014E000006B -:101B2000000002530000001800201E2D00000000DD -:101B30000000FFFF00281E2700000000000000003A -:101B400000341C27000000000000000012C000004C -:101B5000000002480000000000201C1100000000EE -:101B600000000000002F00E5000000000000000061 -:101B700008C000000000024B000000000020140715 -:101B8000000000000000001800201E2D00000000D2 -:101B90000000001000211E270000000000000000CF -:101BA00000341C47000000000000000012C00000CC -:101BB000000002500000000000201C110000000086 -:101BC00000000000002F00E6000000000000000000 -:101BD00008C00000000002530000000000201807A9 -:101BE000000000000000000000600000000002AAE9 -:101BF00000002256002044110000000000000000F8 -:101C000000342023000000000000000012C000008B -:101C10000000025B000000000034204400000000CF -:101C20000000000012C000000000025A0000001670 -:101C3000004048110000025F0000001800404811F9 -:101C40000000025F0000000000342044000000009B -:101C50000000000012C000000000025E000000173B -:101C6000004048110000025F0000001900204811E8 -:101C7000000000000000A1FC002044110000000052 -:101C80000000000100204811000000000001A1FD3B -:101C900000604411000002D200003FFF002F022F1D -:101CA00000000000000000000CC000000000023F27 -:101CB00000000000C040040000000001000000100F -:101CC00040210620000000000000FFFFC0280A207D -:101CD000000000000000001040210E200000000065 -:101CE0000000FFFFC02812200000000000000010CC -:101CF00040211620000000000000FFFFC0881A20CD -:101D000000000000810000000020441100000000DD -:101D10000000000100204811000000000004200421 -:101D20000060441100000614000000000060000084 -:101D3000000005B200000000C06000000000028C3E -:101D40000000000500200A2D00000000000000082F -:101D500000220A22000000000000003400201A2D9A -:101D6000000000000000002400201E2D00000000E4 -:101D70000000700000281E27000000000000000086 -:101D800000311CE6000000000000003300201A2D86 -:101D9000000000000000000C00221A2600000000D5 -:101DA00000000000002F00E600000000000000001E -:101DB00006E000000000027B0000000000201C1173 -:101DC000000000000000000000200C1100000000D6 -:101DD0000000003400203623000000000000001046 -:101DE00000201811000000000000000000691CE243 -:101DF0000000012893800000002044110000000032 -:101E000000000000002048070000000095000000CE -:101E1000002044110000000000000000002F022FED -:101E200000000000000000000CE00000000002863E -:101E30000000000100333E2F000000000000000001 -:101E4000D90048000000000092000000002044116A -:101E50000000000000000000C0204800000000005A -:101E60000000002400403627000000000000000CA5 -:101E7000C0220A20000000000000003200203622AC -:101E80000000000000000031C040362000000000CB -:101E90000000A2A40020441100000000000000097E -:101EA0000020481100000000A100000000204411A3 -:101EB0000000000000000001008048110000000048 -:101EC0000000002900201E2D00000000000000007E -:101ED000002C1CE300000000000000290020362731 -:101EE000000000000000002A00201E2D000000005D -:101EF00000000000002C1CE4000000000000002A8C -:101F000000203627000000000000002B00201E2DBE -:101F10000000000000000000003120A300000000CD -:101F200000000000002D1D07000000000000002B35 -:101F300000203627000000000000002C00201E2D8D -:101F40000000000000000000003120C4000000007C -:101F500000000000002D1D07000000000000002C04 -:101F600000803627000000000000002900203623F2 -:101F7000000000000000002A0020362400000000BD -:101F80000000000000311CA3000000000000002B36 -:101F900000203627000000000000000000311CC4B3 -:101FA000000000000000002C008036270000000028 -:101FB000000000220020362700000000000000235F -:101FC00000203628000000000000001D00201E2D0B -:101FD00000000000000000020021022700000000B5 -:101FE0000000000014C00000000002C50000000056 -:101FF00000400000000002C200000022002036273E -:10200000000000000000002300203628000000002F -:102010000000001D00201E2D000000000000000236 -:1020200000210227000000000000000014E0000072 -:10203000000002C20000000300210227000000008F -:102040000000000014E00000000002C50000002BAA -:1020500000201E2D0000000000000000002E00E106 -:10206000000000000000000002C00000000002C5E7 -:102070000000002900201E2D0000000000000000CC -:10208000003120A10000000000000000002E00E848 -:10209000000000000000000006C00000000002C5B3 -:1020A0000000002C00201E2D000000000000000099 -:1020B000002E00E2000000000000000002C000004E -:1020C000000002C50000002A00201E2D00000000B4 -:1020D00000000000003120C20000000000000000ED -:1020E000002E00E8000000000000000006C0000014 -:1020F000000002C50000000000600000000005EDC7 -:1021000000000000006000000000029E00000000CF -:1021100000400000000002C7000000000060000056 -:102120000000029E0000000000600000000005E4C6 -:102130000000000000400000000002C70000000096 -:10214000006000000000029000000000004000005D -:10215000000002C70000002200201E2D0000000029 -:10216000000000230080222D00000000000000106D -:1021700000221E2300000000000000000029488704 -:10218000000000000000000000311CA3000000005F -:102190000000001000221E270000000000000000C8 -:1021A00000294887000000000000001000221E23C4 -:1021B0000000000000000000003120C4000000000A -:1021C0000000FFFF0028222800000000000000009F -:1021D00000894907000000000000001000221E23B3 -:1021E00000000000000000000029488700000000F7 -:1021F0000000001000221E2100000000000000006E -:1022000000294847000000000000000000311CA326 -:10221000000000000000001000221E270000000047 -:1022200000000000002948870000000000000000B6 -:1022300000311CA1000000000000001000221E2739 -:1022400000000000000000000029484700000000D6 -:102250000000001000221E2300000000000000000B -:10226000003120C4000000000000FFFF00282228E9 -:1022700000000000000000000029490700000000E5 -:102280000000001000221E210000000000000000DD -:10229000003120C2000000000000FFFF00282228BB -:1022A0000000000000000000008949070000000055 -:1022B0000000001000221E230000000000000000AB -:1022C00000294887000000000000000100220A21C8 -:1022D0000000000000000000003308A20000000021 -:1022E0000000001000221E2200000000000000106C -:1022F0000021222200000000000000000029490700 -:10230000000000000000000000311CA300000000DD -:102310000000001000221E27000000000000000046 -:1023200000294887000000000000000100220A2167 -:102330000000000000000000003008A200000000C3 -:102340000000001000221E2200000000000000100B -:10235000002122220000000000000000002949079F -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:102390000000000000000000003808C50000000038 -:1023A00000000000003008410000000000000001B3 -:1023B00000220A220000000000000000003308A2F2 -:1023C000000000000000001000221E22000000009B -:1023D0000000001000212222000000000000000088 -:1023E00000894907000000000000001D0020222D88 -:1023F000000000000000000014C000000000030105 -:10240000FFFFFFEF00280621000000000000001A77 -:102410000020222D000000000000F8E00020441100 -:102420000000000000000000002949010000000039 -:1024300000000000008949010000000000000000C9 -:10244000002048110000000000000000002048119A -:1024500000000000060A0200008048110000000091 -:1024600000000000C02000000000000097000000F5 -:10247000C02044110000000000000000C0204811EE -:10248000000000008A00000000204411000000004D -:102490000000000000204811000000000000225C45 -:1024A000002044110000000000000000C02048008F -:1024B000000000000000A1FC00204411000000000A -:1024C00000000000C02048000000000000000000E4 -:1024D000C0200400000000000000000000A0000A6E -:1024E00000000000970000000020441100000000E0 -:1024F0000000000000204811000000008A000000D9 -:1025000000204411000000000000000000204811DD -:10251000000000000000225C0020441100000000C8 -:1025200000000000C0204800000000000000A1FCE6 -:10253000002044110000000000000000C0204800FE -:102540000000000000000000C020040000000000A7 -:102550000000000000A0000A00000000970000003A -:10256000002044110000000000000000002048117D -:10257000000000008A00000000204411000000005C -:102580000000000000204811000000000000225C54 -:10259000002044110000000000000000C02048009E -:1025A000000000000000A1FC002044110000000019 -:1025B00000000000C0204800000000000001A1FD54 -:1025C000002044110000000000000000D900480075 -:1025D0000000000000000000C02004000000000017 -:1025E0000000000000A0000A0000000000002257C8 -:1025F000002044110000000000000003C0484A20F1 -:10260000000000000000225D0020441100000000D6 -:1026100000000000C0404800000000000000000072 -:1026200000600000000005C500000000C020080098 -:10263000000000000000225C0020441100000000A7 -:102640000000000300384A22000000000000A1FC46 -:10265000002044110000000000000000C0204800DD -:10266000000000000001A1FD002044110000000056 -:1026700000000000002F0222000000000000000007 -:102680000CE00000000000000000000040204800B6 -:10269000000000000000000140304A20000000005F -:1026A00000000002C0304A200000000000000001CD -:1026B00000530A22000003340000003FC0280A2013 -:1026C0000000000081000000002044110000000014 -:1026D000000000010020481100000000000021F867 -:1026E00000204411000000000000001700204811E5 -:1026F00000000000000421F90060441100000614ED -:102700000000001100210230000000000000000065 -:1027100014E000000000033D00000014002F02221E -:1027200000000000000000000CC000000000035189 -:102730000000201000204411000000000000800074 -:1027400000204811000000000001A2A40020441154 -:102750000000000000000000002048110000000000 -:1027600000000016006048110000035E0000210018 -:10277000002044110000000000000000C0204800BC -:102780000000000000000000C02048000000000021 -:1027900000000000C0204800000000000000000011 -:1027A000C0204800000000000001A2A40020441145 -:1027B00000000000000000000020481100000000A0 -:1027C000000000000040480200000000000000047B -:1027D000002F022200000000000000000CC00000DA -:1027E00000000355000020100020441100000000EC -:1027F000000080000040481100000349000000284C -:10280000002F022200000000000000000CE0000089 -:1028100000000349000021040020441100000000D2 -:1028200000000000C0204800000000000000000080 -:10283000C02048000000000000000000C020480048 -:102840000000000000000000C02048000000000060 -:102850000000A2A4002044110000000000000000BD -:10286000004048020000000000000035002036262D -:1028700000000000000000490020181100000000C6 -:1028800000000000002048110000000000000001CE -:1028900000331A260000000000000000002F02266E -:1028A00000000000000000000CC0000000000360F9 -:1028B0000000003500801A2D000000000000003FDD -:1028C000C0280A200000000000000015002F02228E -:1028D00000000000000000000CE000000000037693 -:1028E0000000001E002F0222000000000000000077 -:1028F0000CE000000000038000000020002F0222F6 -:1029000000000000000000000CE000000000038C4C -:102910000000000F002F0222000000000000000055 -:102920000CE000000000039800000010002F0222BD -:1029300000000000000000000CE000000000039810 -:1029400000000006002F022200000000000000002E -:102950000CE000000000039A00000016002F022285 -:1029600000000000000000000CE000000000039FD9 -:102970000000A2A40020441100000000000000009C -:1029800000404802000000000800000000290A2260 -:10299000000000000000000340210E2000000000A5 -:1029A0000000000CC0211220000000000008000000 -:1029B000002812240000000000000014C02216208D -:1029C0000000000000000000002914A40000000026 -:1029D0000000A2A40020441100000000000000003C -:1029E000002948A2000000000000A1FE00204411C0 -:1029F000000000000000000000404803000000004C -:102A000081000000002044110000000000000001CF -:102A10000020481100000000000021F800204411AF -:102A20000000000000000015002048110000000018 -:102A3000000421F900604411000006140000001594 -:102A400000210230000000000000000014E000003F -:102A5000000003820000210E00204411000000004D -:102A600000000000C020480000000000000000003E -:102A7000C0204800000000000000A2A40020441173 -:102A800000000000000000000040480200000000BC -:102A9000810000000020441100000000000000013F -:102AA0000020481100000000000021F8002044111F -:102AB0000000000000000016002048110000000087 -:102AC000000421F900604411000006140000000316 -:102AD00000210230000000000000000014E00000AF -:102AE0000000038E000021080020441100000000B7 -:102AF00000000000C02048000000000000000000AE -:102B0000C0204800000000000000A2A400204411E2 -:102B1000000000000000000000404802000000002B -:102B20000000201000204411000000000000800080 -:102B30000040481100000000000020100020441157 -:102B4000000000000000800000204811000000008C -:102B50000001A2A4002044110000000000000000B9 -:102B6000002048110000000000000006004048114D -:102B700000000000000020100020441100000000B0 -:102B80000000800000204811000000000001A2A405 -:102B90000020441100000000000000000020481147 -:102BA0000000000000000016006048110000035EF5 -:102BB0000000001600404811000000000000000066 -:102BC000C02008000000000000000000C0200C0031 -:102BD000000000000000001D002102230000000092 -:102BE0000000000014E00000000003B981000000B4 -:102BF00000204411000000000000000100204811E6 -:102C000000000000000021F8002044110000000036 -:102C1000000000170020481100000000000421F906 -:102C20000060441100000614000000110021023071 -:102C3000000000000000000014E00000000003ABF2 -:102C400000002100002044110000000000000000EE -:102C5000002048020000000000000000002048039F -:102C600000000000BABECAFE0020481100000000AB -:102C7000CAFEBABE0020481100000000000020106B -:102C800000204411000000000000800000204811D6 -:102C9000000000000000A2A4002044110000000079 -:102CA00000000004004048110000000000002170F6 -:102CB0000020441100000000000000000020480235 -:102CC0000000000000000000002048030000000099 -:102CD0008100000000204411000000000000000AF4 -:102CE000002048110000000000000000002000103B -:102CF000000000000000000014C00000000003BE3F -:102D00008C0000000020441100000000CAFEBABE82 -:102D10000040481100000000810000000020441124 -:102D20000000000000000001002048110000000029 -:102D300000003FFF40280A20000000008000000043 -:102D400040280E200000000040000000C028122093 -:102D50000000000000040000006946220000061484 -:102D6000000000000020141000000000000000001F -:102D7000002F022300000000000000000CC0000033 -:102D8000000003CC00000000C0401800000003CF8A -:102D900000003FFFC0281A200000000000040000CF -:102DA00000694626000006140000000000201810EC -:102DB0000000000000000000002F022400000000BE -:102DC000000000000CC00000000003D20000000062 -:102DD000C0401C00000003D500003FFFC0281E209B -:102DE00000000000000400000069462700000614EF -:102DF0000000000000201C10000000000000000087 -:102E0000002044020000000000000000002820C54F -:102E10000000000000000000004948E80000000039 -:102E2000A580000000200811000000000000200024 -:102E300000200C110000000083000000006044111D -:102E4000000003FD0000000000204402000000001C -:102E500000000000C020480000000000000000004A -:102E600040204800000000000000001FC021022098 -:102E7000000000000000000014C00000000003E299 -:102E8000000020100020441100000000000080001D -:102E900000204811000000000000FFFFC048122081 -:102EA000000003EAA78000000020081100000000D5 -:102EB0000000A00000200C110000000083000000B2 -:102EC00000604411000003FD0000000000204402E7 -:102ED0000000000000000000C020480000000000CA -:102EE00000000000C0204800000000000000FFFFBC -:102EF000C0281220000000008300000000204411C0 -:102F000000000000000000000030488300000000C6 -:102F100084000000002044110000000000000000B8 -:102F2000C020480000000000000000001D0000005C -:102F3000000000008300000000604411000003FD59 -:102F400000000000C040040000000001A980000053 -:102F500000200811000000000000C00000400C111B -:102F6000000003E5AB800000002008110000000015 -:102F70000000F8E000400C11000003E5AD80000007 -:102F800000200811000000000000F88000400C1133 -:102F9000000003E5B38000000020081100000000DD -:102FA0000000F3FC00400C11000003E5AF800000BE -:102FB00000200811000000000000E00000400C119B -:102FC000000003E5B18000000020081100000000AF -:102FD0000000F00000400C11000003E58300000039 -:102FE000002044110000000000002148002048118A -:102FF00000000000840000000020441100000000D8 -:1030000000000000C0204800000000000000000098 -:103010001D00000000000000000000000080000013 -:103020000000000000182000C03046200000000012 -:1030300000000000D900480000000000000000006F -:10304000C0200400000000000000000000A0000AF2 -:10305000000000000018A000C03046200000000062 -:1030600000000000D900480000000000000000003F -:10307000C0200400000000000000000000A0000AC2 -:10308000000000000018C000C03046200000000012 -:1030900000000000D900480000000000000000000F -:1030A000C0200400000000000000000000A0000A92 -:1030B000000000000018F8E0C030462000000000CA -:1030C00000000000D90048000000000000000000DF -:1030D000C0200400000000000000000000A0000A62 -:1030E000000000000018F880C030462000000000FA -:1030F00000000000D90048000000000000000000AF -:10310000C0200400000000000000000000A0000A31 -:10311000000000000018E000C03046200000000061 -:1031200000000000D900480000000000000000007E -:10313000C0200400000000000000000000A0000A01 -:10314000000000000018F000C03046200000000021 -:1031500000000000D900480000000000000000004E -:10316000C0200400000000000000000000A0000AD1 -:10317000000000000018F3FCC030462000000000F2 -:1031800000000000D900480000000000000000001E -:10319000C0200400000000000000000000A0000AA1 -:1031A0000000000086000000002044110000000024 -:1031B0000000000000404801000000008500000001 -:1031C0000020441100000000000000000040480101 -:1031D000000000000000217C0020441100000000DD -:1031E00000000000C02048000000000000000000B7 -:1031F000C02048000000000000000000C02048007F -:1032000000000000810000000020441100000000C8 -:103210000000000100204811000000000000000034 -:10322000C02008000000000000000000170000009F -:10323000000000000004217F00604411000006141B -:103240000000001F0021023000000000000000000C -:1032500014C00000000000000000000000404C020C -:103260000000042E00000000C0200C000000000040 -:1032700000000000C020100000000000000000005E -:10328000C02014000000000000000000C020180052 -:103290000000000000000000C0201C000000000032 -:1032A00000007F0000280A21000000000000450007 -:1032B000002F022200000000000000000CE00000CF -:1032C0000000043C00000000C020200000000000BE -:1032D00000000000170000000000000000000010C7 -:1032E00000280A230000000000000010002F022226 -:1032F00000000000000000000CE00000000004449A -:1033000081000000002044110000000000000001C6 -:10331000002048110000000000040000006946245D -:103320000000061400000000004000000000044DF2 -:103330008100000000204411000000000000000097 -:1033400000204811000000000000216D0020441101 -:103350000000000000000000002048040000000001 -:1033600000000000002048050000000000000000F0 -:103370001AC00000000004499E0000000020441113 -:1033800000000000CAFEBABE002048110000000084 -:10339000000000001AE000000000044C00000000E3 -:1033A000002824F0000000000000000700280A2385 -:1033B0000000000000000001002F022200000000B9 -:1033C000000000000AE000000000045400000000BB -:1033D000002F00C9000000000000000004E0000011 -:1033E0000000046D00000000004000000000047AAE -:1033F00000000002002F0222000000000000000078 -:103400000AE000000000045900000000002F00C97D -:10341000000000000000000002E000000000046D59 -:1034200000000000004000000000047A00000003DB -:10343000002F022200000000000000000AE000004F -:103440000000045E00000000002F00C90000000022 -:10345000000000000CE000000000046D000000000F -:10346000004000000000047A00000004002F022247 -:1034700000000000000000000AE0000000000463FB -:1034800000000000002F00C9000000000000000044 -:103490000AE000000000046D000000000040000091 -:1034A0000000047A00000005002F02220000000046 -:1034B000000000000AE000000000046800000000B6 -:1034C000002F00C9000000000000000006E000001E -:1034D0000000046D00000000004000000000047ABD -:1034E00000000006002F0222000000000000000083 -:1034F0000AE000000000046D00000000002F00C979 -:10350000000000000000000008E000000000046D62 -:1035100000000000004000000000047A00007F006E -:1035200000280A210000000000004500002F0222B0 -:1035300000000000000000000AE0000000000000A1 -:103540000000000800210A23000000000000000025 -:1035500014C000000000047700002169002044111D -:103560000000000000000000C02048000000000033 -:1035700000000000C0204800000000000000000023 -:10358000C020480000000000CAFEBABE004048113A -:103590000000000000000000C02044000000000007 -:1035A00000000000C020000000000000000000003B -:1035B000C04048000000000000007F0000280A21F1 -:1035C0000000000000004500002F02220000000063 -:1035D000000000000AE0000000000480000000007D -:1035E000C02000000000000000000000C02000001B -:1035F0000000000000000000C040000000000000CB -:103600000000000000404C080000043C00000000E6 -:10361000C0200800000000000000001040210E2023 -:1036200000000000000000114021122000000000F6 -:103630000000001240211620000000000000216957 -:10364000002044110000000000000000002048029B -:103650000000000000000000002102250000000022 -:103660000000000014E000000000048A00040000D4 -:10367000C0494A200000048BFFFBFFFFC0284A20FE -:1036800000000000000000000021022300000000F4 -:103690000000000014E0000000000497000000009B -:1036A000C02048000000000000000000C0204800CA -:1036B00000000000000000000021022400000000C3 -:1036C0000000000014C000000000000081000000A5 -:1036D00000204411000000000000000C00204811F0 -:1036E00000000000000000000020001000000000AA -:1036F0000000000014C0000000000493A0000000BF -:103700000020441100000000CAFEBABE004048116B -:1037100000000000810000000020441100000000B3 -:103720000000000400204811000000000000216B90 -:10373000002044110000000000000000C0204810DC -:103740000000000081000000002044110000000083 -:103750000000000500204811000000000000216C5E -:10376000002044110000000000000000C0204810AC -:103770000000000000000000002F022400000000F4 -:10378000000000000CE0000000000000000000004D -:10379000004000000000049100000000C0210A2049 -:1037A000000000000000000014C00000000004AE93 -:1037B0008100000000204411000000000000000013 -:1037C00000204811000000000000216D002044117D -:1037D0000000000000000000C020480000000000C1 -:1037E00000000000C02048000000000000000000B1 -:1037F0001AC00000000004A99E000000002044112F -:1038000000000000CAFEBABE0020481100000000FF -:10381000000000001AE00000000004AC00000000FE -:1038200000400000000004B28100000000204411AC -:10383000000000000000000100204811000000000E -:1038400000040000C0294620000000000000000025 -:10385000C0600000000006140000000100210222E8 -:10386000000000000000000014C00000000004B9C7 -:103870000000216900204411000000000000000049 -:10388000C02048000000000000000000C0204800E8 -:1038900000000000000000000020481000000000B0 -:1038A000CAFEBABE0040481100000000000000003F -:1038B000C02044000000000000000000C04048108C -:1038C0000000000081000000002044110000000002 -:1038D000000000010020481100000000000021F855 -:1038E00000204411000000000000000D00204811DD -:1038F00000000000000421F90060441100000614DB -:103900000000000000210230000000000000000064 -:1039100014C00000000004BB0000218000204411FE -:103920000000000000000000C0204800000000006F -:1039300000000000C02000000000000000000000A7 -:10394000C02048000000000000000000C02000006F -:103950000000000000000000C0404800000000001F -:103960000000000300333E2F0000000000000001B3 -:1039700000210221000000000000000014E000000F -:10398000000004EB0000003500200A2D00000000BC -:103990000004000018E00C11000004DA000000012F -:1039A00000333E2F00000000000021690020441178 -:1039B000000000000000000000204802000000009D -:1039C0000000000000204803000000000000000884 -:1039D00000300A220000000000000000C020480063 -:1039E0000000000000000000C020480000000000AF -:1039F00000002169002044110000000000000000C8 -:103A000000204802000000000000000000204803E1 -:103A1000000000000000000800300A220000000042 -:103A200000000000C020480000000000000000006E -:103A3000D8C04800000004CE0000216900204411D5 -:103A4000000000000000000000204802000000000C -:103A500000000000002048030000000000000008F3 -:103A600000300A220000000000000000C0204800D2 -:103A70000000000000000000C0204800000000001E -:103A8000000000360020122D0000000000000000A1 -:103A900000290C830000000000002169002044116F -:103AA00000000000000000000020480200000000AC -:103AB0000000000000204803000000000000000893 -:103AC00000300A220000000000000000C020480072 -:103AD0000000000000000000C020480000000000BE -:103AE000000000110021022400000000000000007E -:103AF00014C00000000000000000000000400000B2 -:103B00000000049100000035C020362000000000B5 -:103B100000000036C0403620000000000000304A9F -:103B20000020441100000000E0000000C0484A20CE -:103B3000000000000000000F002102210000000032 -:103B40000000000014C00000000004F200000000AB -:103B5000006000000000000B00000000D900000021 -:103B60000000000000000000C04004000000000150 -:103B7000810000000020441100000000000000024D -:103B80000020481100000000000000FF00280E3057 -:103B90000000000000000000002F022300000000D1 -:103BA000000000000CC00000000004F6000000004F -:103BB000C0200800000000000000000014C0000049 -:103BC0000000050B0000000000200C1100000000A8 -:103BD0000000002400203623000000000000003414 -:103BE00000203623000000000000003200203623B1 -:103BF000000000000000003100203623000000001B -:103C00000000001D00203623000000000000002DF1 -:103C100000203623000000000000002E0020362384 -:103C2000000000000000001B002036230000000000 -:103C30000000001C0020362300000000FFFFE00011 -:103C400000200C1100000000000000290020362395 -:103C5000000000000000002A0020362300000000C1 -:103C600000001FFF00200C11000000000000002BCE -:103C700000203623000000000000002C0020362326 -:103C800000000000F1FFFFFF00283A2E00000000B6 -:103C90000000001AC0220E200000000000000000FA -:103CA0000029386E0000000081000000002044114F -:103CB0000000000000000006002048110000000085 -:103CC0000000003340203620000000008700000084 -:103CD000002044110000000000000000C020480047 -:103CE000000000000000A1F40020441100000000CA -:103CF0000000000000204810000000009D000000AF -:103D000000204411000000000000001F40214A2054 -:103D10000000000096000000002044110000000098 -:103D200000000000C020480000000000000000006B -:103D3000C0200C000000000000000000C0201000A7 -:103D4000000000000000001F0021162400000000F9 -:103D50000000000014C0000000000000000000256A -:103D600000203623000000000000000300281E236E -:103D700000000000000000080022222300000000D4 -:103D8000FFFFF000002822280000000000000000D3 -:103D9000002920E80000000000000027002036284D -:103DA000000000000000001800211E230000000099 -:103DB000000000280020362700000000000000025C -:103DC000002216240000000000000000003014A8AB -:103DD0000000000000000026002036250000000042 -:103DE0000000000300211A24000000001000000061 -:103DF00000281A2600000000EFFFFFFF00283A2EDF -:103E00000000000000000000004938CE000006025B -:103E10000000000140280A20000000000000000609 -:103E200040280E200000000000000300C0281220DF -:103E30000000000000000008002112240000000023 -:103E400000000000C020162000000000000000005C -:103E5000C0201A2000000000000000000021022203 -:103E6000000000000000000014C000000000054138 -:103E7000810000000020441100000000000000014B -:103E800000204811000000000000225800300A24E1 -:103E90000000000000040000006946220000061433 -:103EA0000000216900204411000000000000000013 -:103EB00000204805000000000002000000294A26FA -:103EC000000000000000000000204810000000007A -:103ED000CAFEBABE00204811000000000000000227 -:103EE000002F022300000000000000000CC00000B2 -:103EF0000000054900000000C0201C100000000068 -:103F000000000000C04000000000055B000000024F -:103F1000002F022300000000000000000CC0000081 -:103F2000000005498100000000204411000000004D -:103F3000000000010020481100000000000022588D -:103F400000300A240000000000040000006946223E -:103F50000000061400000000C0201C10000000003B -:103F600000000000C04000000000055B00000000F1 -:103F7000002F022300000000000000000CC0000021 -:103F80000000054D00000000C0201C0000000000E3 -:103F900000000000C04000000000055B00000004BD -:103FA000002F022300000000000000000CC00000F1 -:103FB00000000559810000000020441100000000AD -:103FC0000000000000204811000000000000216DEA -:103FD000002044110000000000000000C020480044 -:103FE0000000000000000000C020480000000000A9 -:103FF000000000001AC00000000005549E000000F0 -:104000000020441100000000CAFEBABE0020481182 -:1040100000000000000000001AE00000000005574A -:104020000000000000401C100000055B00000000C4 -:10403000C02000000000000000000000C0400000A0 -:1040400000000000000000000EE000000000055D20 -:104050000000000000600000000005A40000000057 -:10406000002F022400000000000000000CC000002F -:104070000000056D0000A2B7002044110000000000 -:104080000000000000204807000000008100000040 -:104090000020441100000000000000010020481131 -:1040A000000000000004A2B60060441100000614E5 -:1040B0000000001A0021223000000000000000066D -:1040C00000222630000000000000A2C4002044119D -:1040D0000000000000000000003048E9000000007F -:1040E0000000000000E000000000056B0000A2D10D -:1040F00000204411000000000000000000404808BB -:10410000000000000000A2D10020441100000000C7 -:104110000000000100504A280000000000000001DB -:10412000002F022400000000000000000CC000006E -:104130000000057D0000A2BB00204411000000002B -:10414000000000000020480700000000810000007F -:104150000020441100000000000000010020481170 -:10416000000000000004A2BA006044110000061420 -:104170000000001A002122300000000000000006AC -:1041800000222630000000000000A2C500204411DB -:104190000000000000000000003048E900000000BE -:1041A0000000000000E000000000057B0000A2D23B -:1041B00000204411000000000000000000404808FA -:1041C000000000000000A2D2002044110000000006 -:1041D0000000000100504A2800000000000000021A -:1041E000002F022400000000000000000CC00000AE -:1041F0000000058D0000A2BF002044110000000057 -:1042000000000000002048070000000081000000BE -:1042100000204411000000000000000100204811AF -:10422000000000000004A2BE00604411000006145B -:104230000000001A002122300000000000000006EB -:1042400000222630000000000000A2C60020441119 -:104250000000000000000000003048E900000000FD -:104260000000000000E000000000058B0000A2D369 -:104270000020441100000000000000000040480839 -:10428000000000000000A2D3002044110000000044 -:104290000000000100504A28000000000000A2C3F6 -:1042A000002044110000000000000000002048072A -:1042B0000000000081000000002044110000000008 -:1042C0000000000100204811000000000004A2C20C -:1042D00000604411000006140000001A0021223082 -:1042E0000000000000000006002226300000000050 -:1042F0000000A2C7002044110000000000000000E0 -:10430000003048E9000000000000000000E000006C -:10431000000005990000A2D4002044110000000014 -:104320000000000000404808000000000000A2D487 -:1043300000204411000000000000000100504A2845 -:104340000000000085000000002044110000000073 -:104350000000000000204801000000000000304A7A -:10436000002044110000000001000000002048115E -:104370000000000000000000004000000000059F59 -:10438000A4000000C0204411000000000000000054 -:10439000C04048000000000000000000C0600000B5 -:1043A000000005A400000000C0400400000000015F -:1043B0000001A2A400204411000000000000000041 -:1043C00000204811000000000000000000204811FB -:1043D0000000000000000000002048110000000064 -:1043E000000000000020481100000000000000054F -:1043F00000204811000000000000A1F4002044113A -:104400000000000000000000002048110000000033 -:10441000880000000020441100000000000000019E -:104420000020481100000000FF000000002044119F -:104430000000000000000000002048110000000003 -:1044400000000001002048110000000000000002F0 -:104450000080481100000000000000000EE0000095 -:10446000000005B700001000002008110000000047 -:104470000000003400203622000000000000000090 -:1044800000600000000005BB0000000000600000AC -:10449000000005A498000000002044110000000066 -:1044A0000000000000804811000000000000000033 -:1044B000C0600000000005BB00000000C040040018 -:1044C000000000010000A2A4002044110000000030 -:1044D00000000022002048110000000089000000B8 -:1044E00000204411000000000000000100204811DD -:1044F00000000000FF000000002044110000000048 -:104500000000000000204811000000000000000131 -:104510000020481100000000000000020080481147 -:10452000000000000000217AC020441100000000BB -:10453000000000000040481100000000970000004B -:10454000002044110000000000000000002048117D -:10455000000000008A00000000204411000000005C -:10456000000000000020481100000000FF000000D3 -:10457000002044110000000000000000002048114D -:1045800000000000000000010020481100000000B1 -:104590000000000200804811000000000000000040 -:1045A00000600000000005E1000020100020441120 -:1045B0000000000000008000002048110000000002 -:1045C0000001A2A4C020441100000000000000006F -:1045D0000020481100000000000000160060481193 -:1045E0000000035E000000160020481100000000DB -:1045F0000000201000204411000000000001000015 -:10460000002048110000000081000000002044113B -:104610000000000000000001002048110000000020 -:104620000000217C002044110000000009800000EF -:104630000020481100000000FFFFFFFF002048118C -:1046400000000000000000000020481100000000F1 -:104650000000000017000000000000000004217F9F -:1046600000604411000006140000001F0021023009 -:10467000000000000000000014C000000000000066 -:104680000000000400404C11000005DC0000001D8B -:1046900000201E2D000000000000000400291E273D -:1046A000000000000000001D008036270000000010 -:1046B0000000001D00201E2D00000000FFFFFFFB7A -:1046C00000281E27000000000000001D0080362783 -:1046D000000000000000001D00201E2D0000000052 -:1046E0000000000800291E27000000000000001D37 -:1046F00000803627000000000000001D00201E2D55 -:1047000000000000FFFFFFF700281E270000000048 -:104710000000001D0080362700000000000020106F -:10472000002044110000000000008000002048111B -:10473000000000000001A2A40020441100000000BD -:1047400000000000002048110000000000000016DA -:10475000006048110000035E0000001600204811B0 -:1047600000000000000020100020441100000000A4 -:104770000001000000204811000000000000217C22 -:1047800000204411000000000180000000204811BA -:104790000000000000FFFFFF0020481100000000A3 -:1047A0000000000000204811000000000000000090 -:1047B00017000000000000008100000000204411EC -:1047C000000000000000000100204811000000006F -:1047D0000004217F00604411000006140000000066 -:1047E00000200010000000000000000014C00000C5 -:1047F000000006130000001000404C11000005F9F5 -:1048000000000000C02004000000000000000000C4 -:1048100038C00000000000000000002500200A2D24 -:10482000000000000000002600200E2D0000000007 -:10483000000000270020122D0000000000000028CA -:104840000020162D00000000000021690020441106 -:1048500000000000000000000020480400000000EC -:1048600000000000002048050000000000000000DB -:104870000020480100000000CAFEBABE0020481116 -:1048800000000000000000040030122400000000BE -:1048900000000000002F0064000000000000000085 -:1048A0000CC00000000006120000000300281A22BD -:1048B000000000000000000800221222000000009A -:1048C000FFFFF0000028122400000000000000009C -:1048D000002910C40000000000000027004036241A -:1048E0000000000000000000008000000000000048 -:1048F000000000001AC00000000006149F00000025 -:104900000020441100000000CAFEBABE0020481179 -:1049100000000000000000001AE000000000061780 -:104920000000000000800000000000000000000007 -:10493000006000000000000B000010000060041187 -:10494000000002FE00000000002004110000000032 -:1049500000000000006008110000019F0000225CC0 -:104960000020441100000000000000030020481156 -:10497000000000000000225600204411000000004A -:104980000000001B00204811000000000000A1FCF6 -:104990000020441100000000000000010020481128 -:1049A000000000000001A1FDC02044110000000033 -:1049B0000000002900201E2D000000000000001053 -:1049C00000221E27000000000000002C0020222DE5 -:1049D000000000000000FFFF002822280000000067 -:1049E000000000000029490700000000000000004E -:1049F00000204811000000000000002A0020222DA5 -:104A0000000000000000FFFF002822280000000036 -:104A1000000000000029490700000000000000001D -:104A200000204811000000000000002B00201E2D77 -:104A3000000000000000001000221E2700000000FF -:104A400000000000002949070000000000000000ED -:104A500000404811000000000000000000000000BD -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B000013304EF059B02390000000001B00159E1 -:1052C0000425059B00000000021201F6023901428C -:1052D000000000000210022E0289022A00000000D5 -:1052E00003C2059B059B059B0000000005CD05CE74 -:1052F0000308059B00000000059B05A00309032986 -:10530000000000000313026B032B031D00000000CC -:10531000059B059B059B059B00000000059B052C3C -:10532000059B059B0000000003A5059B04A2032D1F -:1053300000000000048104330423059B00000000EA -:1053400004BB04ED042704C800000000043304F487 -:10535000033A036500000000059B059B059B059B28 -:1053600000000000059B059B059B059B00000000BD -:10537000059B059B05B905A200000000059B059B48 -:105380000007059B00000000059B059B059B059BF6 -:1053900000000000059B059B059B059B000000008D -:1053A00003E303D803F303F10000000003F903F55E -:1053B00003F703FB0000000004070403040F040BC1 -:1053C0000000000004170413041F041B0000000069 -:1053D000059B059B059B059B00000000059B059B0D -:1053E000059B059B00000000059B059B059B059BFD -:1053F0000000000000020600061900060000000080 -:00000001FF diff --git a/firmware/radeon/R600_pfp.bin.ihex b/firmware/radeon/R600_pfp.bin.ihex deleted file mode 100644 index 52361086c280eaf8f195407c6f30fb82ca6943eb..0000000000000000000000000000000000000000 --- a/firmware/radeon/R600_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000D4007100D4007200CA040000A00000F7 -:10001000007E828B0080000300CA040000D4401ED2 -:1000200000EE001E00CA040000A00000007E828BCB -:1000300000C4183800CA240000CA2800009581A80E -:1000400000C41C3A00C3C00000CA080000CA0C006B -:10005000007C744B00C200050099C00000C41C3A2B -:10006000007C744C00C0FFF000042C0400309002AF -:10007000007D250000351402007D350B002554035A -:10008000007CD58000259C030095C00400D5001B92 -:10009000007EDDC1007D9D8000D6801B00D5801BC9 -:1000A00000D4401E00D5401E00D6401E00D6801E43 -:1000B00000D4801E00D4C01E009783D400D5C01E7B -:1000C00000CA08000080001B00CA0C0000E4011EEA -:1000D00000D4001E0080000D00C4183800E4013E6A -:1000E00000D4001E0080000D00C4183800D4401E4B -:1000F00000EE001E00CA040000A00000007E828BFB -:1001000000E4011E00D4001E00D4401E00EE001EBC -:1001100000CA040000A00000007E828B00E4013EC3 -:1001200000D4001E00D4401E00EE001E00CA0400D1 -:1001300000A00000007E828B00CA180000D4401E80 -:1001400000D5801E0080005400D4007300D4401EEF -:1001500000CA080000CA0C0000CA100000D48019B0 -:1001600000D4C01800D5001700D4801E00D4C01ED3 -:1001700000D5001E00E2001E00CA040000A000001E -:10018000007E828B00CA080000D4806000D4401E2C -:100190000080000200D4801E00CA080000D48061E4 -:1001A00000D4401E0080000200D4801E00CA080057 -:1001B00000CA0C0000D4401E00D4801600D4C01623 -:1001C00000D4801E008001B900D4C01E00C6083EC5 -:1001D00000CA0C0000CA10000094800400CA140079 -:1001E00000E420F300D4201300D5606500D4E01CA7 -:1001F00000D5201C00D5601C0080000200062001F4 -:1002000000C6083E00CA0C0000CA1000009483F724 -:1002100000CA140000E420F30080007A00D4201308 -:1002200000C6083E00CA0C0000CA1000009883EF08 -:1002300000CA140000D400640080008E000000009A -:1002400000C4143200C6183E00C4082F00954005B3 -:1002500000C40C3000D4401E0080000200EE001EDE -:10026000009583F500C4103100D4403300D52065DB -:1002700000D4A01C00D4E01C00D5201C00D40073C6 -:1002800000E4015E00D4001E008001B900062001D8 -:10029000000A200100D6007400C4083600C61040D1 -:1002A0000098800700CC38350095010F00D4001F5E -:1002B00000D460620080000200D4206200CC1433BD -:1002C000008401BC00D4007000D5401E00800002F4 -:1002D00000EE001E00CA0C0000CA100000D4C01AB4 -:1002E000008401BC00D5001A00CC04430035101F67 -:1002F000002C9401007D098B00984005007D15CBF2 -:1003000000D4001A008001B900D4006D003444010B -:1003100000CC0C440098403A00CC2C460095800458 -:1003200000CC0445008001B900D4001A00D4C01AE2 -:1003300000282801008400F300CC10030098801BE3 -:100340000004380C008400F300CC100300988017E0 -:1003500000043808008400F300CC100300988013D8 -:1003600000043804008400F300CC100300988014CB -:1003700000CC1047009A800900CC1448009840DA5D -:1003800000D4006D00CC184400D5001A00D5401AE6 -:10039000008000CC00D5801A0096C0D300D4006D38 -:1003A000008001B900D4006E009AC00300D4006D33 -:1003B00000D4006E0080000200EC007F009AC0CAEA -:1003C00000D4006D008001B900D4006E00CC14038D -:1003D00000CC180300CC1C03007D9103007DD58365 -:1003E000007D190C0035CC1F0035701F007CF0CB50 -:1003F000007CD08B00880000007E8E8B0095C004AE -:1004000000D4006E008001B900D4001A00D4C01AD4 -:1004100000CC080300CC0C0300CC100300CC140368 -:1004200000CC180300CC1C0300CC240300CC280310 -:100430000035C41F0036B01F007C704B0034F01F25 -:10044000007C704B0035701F007C704B007D8881F4 -:10045000007DCCC1007E5101007E9541007C9082E0 -:10046000007CD4C2007C848B009AC003007C8C8BFF -:10047000002C88010098809C00D4006D0098409A60 -:1004800000D4006E00CC084700CC0C4800CC1044CF -:1004900000D4801A00D4C01A0080010400D5001ACC -:1004A00000CC083200D40032009482D800CA0C007C -:1004B00000D4401E0080000200D4001E00E4011E93 -:1004C00000D4001E00CA080000CA0C0000CA1000B8 -:1004D00000D4401E00CA140000D4801E00D4C01EE8 -:1004E00000D5001E00D5401E00D54034008000021B -:1004F00000EE001E0028040400E2001A00E2001AC8 -:1005000000D4401A00CA380000CC080300CC0C0309 -:1005100000CC0C0300CC0C03009882BC000000004F -:10052000008401BC00D7806F0080000200EE001F35 -:1005300000CA040000C2FF0000CC083400C13FFF25 -:10054000007C74CB007CC90B007D010F009902AFC9 -:10055000007C738B008401BC00D7806F0080000298 -:1005600000EE001F00CA080000281900007D898BDA -:10057000009580140028140400CA0C0000CA100062 -:1005800000CA1C0000CA240000E2001F00D4C01AE8 -:1005900000D5001A00D5401A00CC180300CC2C035B -:1005A00000CC2C0300CC2C03007DA58B007D9C4748 -:1005B00000984296000000000080016400D4C01A38 -:1005C00000D4401E00D4801E0080000200EE001EF9 -:1005D00000E4011E00D4001E00D4401E00EE001EE8 -:1005E00000CA040000A00000007E828B00E4013EEF -:1005F00000D4001E00D4401E00EE001E00CA0400FD -:1006000000A00000007E828B00CA080000248C0637 -:10061000000CCC060098C00600CC104900990004DC -:1006200000D4007100E4011E00D4001E00D4401E5E -:1006300000D4801E0080000200EE001E00CA0800E8 -:1006400000CA0C000034D018002510010095001FCE -:1006500000C17FFF00CA100000CA140000CA1800C1 -:1006600000D4801D00D4C01D007DB18B00C14202AA -:1006700000C2C00100D5801D0034DC0E007D5D4C41 -:10068000007F734C00D7401E00D5001E00D5401ED1 -:1006900000C1420000C2C00000099C010031DC1012 -:1006A000007F5F4C007F734C007D838000D5806F9E -:1006B00000D5806600D7401E00EC005E00C8240212 -:1006C000008001B900D6007400D4401E00D4801E02 -:1006D00000D4C01E0080000200EE001E0080000258 -:1006E00000EE001F00D4001F0080000200D4001F95 -:1006F00000D4001F0088000000D4001F000000008C -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:10080000000101740002017B0003009000040080DD -:100810000005000500060040000700330008012F16 -:1008200000090047000A0037001001B7001700A4B4 -:100830000022013D0023014C002000B500240128C6 -:100840000027004E0028006B002A0061002B005397 -:10085000002F00660032008800340182003C0159FC -:10086000003F00730041018F0044013100550176C3 -:100870000056017D0060000C006100350062003907 -:1008800000630039006400390065003900660039F2 -:10089000006700390068003B00690042006A0049B7 -:1008A000006B0049006C0049006D0049006E004972 -:1008B000006F0049007301B7000000070000000747 -:1008C000000000070000000700000007000000070C -:1008D00000000007000000070000000700000007FC -:1008E00000000007000000070000000700000007EC -:1008F00000000007000000070000000700000007DC -:00000001FF diff --git a/firmware/radeon/RS600_cp.bin.ihex b/firmware/radeon/RS600_cp.bin.ihex deleted file mode 100644 index 4a895016aca4861a012e6cfba99dd052f6ac4d59..0000000000000000000000000000000000000000 --- a/firmware/radeon/RS600_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:10000000000000004200E000000000004000E000AE -:1000100000000008000000A000000008000000A48C -:10002000000000004A554B4A000000004A4A44675D -:100030000000000055526F75000000004A7E7D658B -:10004000000000004AE74AF6000000004AD34A4A8E -:1000500000000000D689898900000000CD4ADDCF6C -:10006000000000008EBE4AE200000000C38A8A8AB7 -:10007000000000004A0F8CC800000004000CA00023 -:1000800000000038000D0012000000040000E8B479 -:1000900000000038000D0014000000040000E8B665 -:1000A00000000038000D0016000000040000E854B5 -:1000B00000000038000D0018000000040000E855A2 -:1000C00000000038000D001A000000040000E8568F -:1000D00000000038000D001C000000040000E8577C -:1000E00000000038000D001E000000040000E8249D -:1000F00000000038000D0020000000040000E8258A -:1001000000000038000D0022000000040000E8306C -:1001100000000038000D0024000000040000F0C0C2 -:1001200000000038000D0026000000040000F0C1AF -:1001300000000038000D0028000000040000F0411D -:1001400000000038000D002A000000040000F184C7 -:1001500000000038000D002C000000040000F185B4 -:1001600000000038000D002E000000040000F186A1 -:1001700000000038000D0030000000040000F1878E -:1001800000000038000D0032000000040000F18083 -:1001900000000038000D0034000000040000F3935C -:1001A00000000038000D0036000000040000F38A53 -:1001B00000000038000D0038000000040000F38E3D -:1001C000000000040000E821000000040140A0003D -:1001D00000000018000000430000000400CCE8000C -:1001E00000000004001B000100000004080048009B -:1001F00000000004001B000100000004080048008B -:1002000000000004001B000100000004080048007A -:10021000000000080000003A000000000000A000FC -:10022000000000042000451D000000040000E580DF -:1002300000000004000CE581000000040800458077 -:1002400000000004000CE5810000000800000047E9 -:10025000000000000000A00000000004000C2000CE -:10026000000000040000E50E000000040003200070 -:10027000000000280002205100000024000000516E -:10028000000000040800450F000000080000A04B1B -:10029000000000040000E565000000040000E566C1 -:1002A00000000008000000520000000403CCA5B4C8 -:1002B00000000004054320000000000400022000AC -:1002C000000000304CCCE05E0000000408274565CB -:1002D000000000300000005E0000000408004564DB -:1002E000000000040000E566000000080000005562 -:1002F00000000010008020610000000400202000A9 -:1003000000000004001B00FF00000010010000645A -:1003100000000004001F200000000004001C00FF7B -:100320000000000C0000000000000030000000721F -:100330000000000800000055000000040000E57601 -:10034000000000040000E577000000040000E50E56 -:10035000000000040000E50F000000040140A000C0 -:100360000000001800000069000000C200C0E5F9AC -:100370000000000800000069000000040014E50E01 -:10038000000000040040E50F0000000800C0006C01 -:10039000000000040000E570000000040000E571AA -:1003A0000000000C0000E572000000040000A00046 -:1003B000000000040140A000000000040000E56807 -:1003C00000000004000C200000000018000000766F -:1003D00000000004000B00000000000418C0E562EB -:1003E00000000008000000780000000800C000774E -:1003F00000000004000700D5000000380000008461 -:1004000000000030000CA08600000004080045BB7E -:1004100000000030000C2087000000000800E5BC50 -:10042000000000040000E5BB000000000000E5BC87 -:100430000000000C00120000000000040012000088 -:100440000000000C001B0002000000040000A000DF -:10045000000000040000E821000000000000E800A7 -:10046000000000040000E821000000000000E82E69 -:100470000000000402CCA0000000000400140000F2 -:1004800000000004000CE1CC00000004050DE1CDEB -:10049000000000040040000000000018000000966A -:1004A0000000000400C0A00000000008000000934D -:1004B0000000002000000098000000004200E00062 -:1004C000000000380000009F00000004000CA000A5 -:1004D000000000040014000000000004000C2000D4 -:1004E000000000040016000000000004700CE00092 -:1004F000000000080014009B000000004000E00025 -:10050000000000040240000000000004400EE00073 -:100510000000000402400000000000004000E00075 -:1005200000000004000C2000000000040240E51B55 -:10053000000000050080E50A000000050080E50BD2 -:10054000000000040022000000000004000700D5A5 -:1005500000000038000000B200000030000C2087CE -:10056000000000050880E5BD00000030000C20867A -:10057000000000050800E5BB00000030000C2087EB -:10058000000000050880E5BC00000008000000B580 -:10059000000000050080E5BD000000050000E5BB8F -:1005A000000000050080E5BC000000040021000000 -:1005B00000000004028000000000001800C000B924 -:1005C000000000404180E00000000024000000BB6B -:1005D0000000000C010000000000000C0100E51DFF -:1005E00000000004000045BB00000008000080B5CA -:1005F000000000040000F3CE000000040140A00051 -:100600000000000400CC20000000004008C053CFD0 -:100610000000000000008000000000040000F3D291 -:10062000000000040140A0000000000400CC2000F5 -:100630000000004008C053D300000000000080000C -:10064000000000040000F39D000000040140A00031 -:100650000000000400CC20000000004008C0539EB1 -:1006600000000000000080000000000403C008300B -:10067000000000004200E000000000040000A000B4 -:1006800000000004200045E0000000000000E5E15B -:10069000000000000000000100000004000700D27C -:1006A000000000000800E3940000000000000000CB -:1006B000000000040000E8C4000000040000E8C5D9 -:1006C000000000040000E8C6000000040000E92863 -:1006D000000000040000E929000000040000E92AED -:1006E00000000008000000D6000000040000E92817 -:1006F000000000040000E929000000040000E92ACD -:1007000000000008000000DD0000000000E001160D -:1007100000000004000700E1000000040800401C85 -:1007200000000004200050E7000000040000E01D6D -:1007300000000008000000E40000000402C02000E7 -:10074000000000040006000000000034000000EB80 -:1007500000000008000000E8000000040000800025 -:1007600000000000C000E0000000000000000000E9 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B00000000004000C200000000004001D0018D0 -:1007C00000000004001A000100000034000000FBDB -:1007D000000000080000004A000000080500A04AD0 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/RS690_cp.bin.ihex b/firmware/radeon/RS690_cp.bin.ihex deleted file mode 100644 index 689627441d8b7041e523f8aae6ff35fea8ea960d..0000000000000000000000000000000000000000 --- a/firmware/radeon/RS690_cp.bin.ihex +++ /dev/null @@ -1,130 +0,0 @@ -:1000000000000008000000DD00000008000000DF24 -:1000100000000008000000A000000008000000A48C -:10002000000000004A554B4A000000004A4A44675D -:100030000000000055526F75000000004A7E7D658B -:10004000000000004AD74AF6000000004AC94A4AA8 -:1000500000000000CC89898900000000C34AD3C594 -:10006000000000008E4A4A4A000000004A8A8A8A3C -:10007000000000004A0F8C4A00000004000CA000A1 -:1000800000000038000D0012000000040000E8B479 -:1000900000000038000D0014000000040000E8B665 -:1000A00000000038000D0016000000040000E854B5 -:1000B00000000038000D0018000000040000E855A2 -:1000C00000000038000D001A000000040000E8568F -:1000D00000000038000D001C000000040000E8577C -:1000E00000000038000D001E000000040000E8249D -:1000F00000000038000D0020000000040000E8258A -:1001000000000038000D0022000000040000E8306C -:1001100000000038000D0024000000040000F0C0C2 -:1001200000000038000D0026000000040000F0C1AF -:1001300000000038000D0028000000040000F0411D -:1001400000000038000D002A000000040000F184C7 -:1001500000000038000D002C000000040000F185B4 -:1001600000000038000D002E000000040000F186A1 -:1001700000000038000D0030000000040000F1878E -:1001800000000038000D0032000000040000F18083 -:1001900000000038000D0034000000040000F3935C -:1001A00000000038000D0036000000040000F38A53 -:1001B00000000038000D0038000000040000F38E3D -:1001C000000000040000E821000000040140A0003D -:1001D00000000018000000430000000400CCE8000C -:1001E00000000004001B000100000004080048009B -:1001F00000000004001B000100000004080048008B -:1002000000000004001B000100000004080048007A -:10021000000000080000003A000000000000A000FC -:10022000000000042000451D000000040000E580DF -:1002300000000004000CE581000000040800458077 -:1002400000000004000CE5810000000800000047E9 -:10025000000000000000A00000000004000C2000CE -:10026000000000040000E50E000000040003200070 -:10027000000000280002205100000024000000516E -:10028000000000040800450F000000080000A04B1B -:10029000000000040000E565000000040000E566C1 -:1002A00000000008000000520000000403CCA5B4C8 -:1002B00000000004054320000000000400022000AC -:1002C000000000304CCCE05E0000000408274565CB -:1002D000000000300000005E0000000408004564DB -:1002E000000000040000E566000000080000005562 -:1002F00000000010008020610000000400202000A9 -:1003000000000004001B00FF00000010010000645A -:1003100000000004001F200000000004001C00FF7B -:100320000000000C0000000000000030000000721F -:100330000000000800000055000000040000E57601 -:10034000000000040000E577000000040000E50E56 -:10035000000000040000E50F000000040140A000C0 -:100360000000001800000069000000C200C0E5F9AC -:100370000000000800000069000000040014E50E01 -:10038000000000040040E50F0000000800C0006C01 -:10039000000000040000E570000000040000E571AA -:1003A0000000000C0000E572000000040000A00046 -:1003B000000000040140A000000000040000E56807 -:1003C00000000004000C200000000018000000766F -:1003D00000000004000B00000000000418C0E562EB -:1003E00000000008000000780000000800C000774E -:1003F00000000004000700CB00000038000000846B -:1004000000000030000CA08600000004080045BB7E -:1004100000000030000C2087000000000800E5BC50 -:10042000000000040000E5BB000000000000E5BC87 -:100430000000000C00120000000000040012000088 -:100440000000000C001B0002000000040000A000DF -:10045000000000040000E821000000000000E800A7 -:10046000000000040000E821000000000000E82E69 -:100470000000000402CCA0000000000400140000F2 -:1004800000000004000CE1CC00000004050DE1CDEB -:10049000000000040040000000000018000000966A -:1004A0000000000400C0A00000000008000000934D -:1004B0000000002000000098000000004200E00062 -:1004C000000000380000009F00000004000CA000A5 -:1004D000000000040014000000000004000C2000D4 -:1004E000000000040016000000000004700CE00092 -:1004F000000000080014009B000000004000E00025 -:10050000000000040240000000000004400EE00073 -:100510000000000402400000000000004000E00075 -:100520000000002C0010000000000000000040004F -:1005300000000004080045C8000000040024000575 -:100540000000000408004D0B00000004000C200017 -:10055000000000040240E51B000000050080E50AE1 -:10056000000000050080E50B0000000400220000F0 -:1005700000000004000700CB00000038000000B7B6 -:1005800000000030000C2087000000050880E5BD59 -:1005900000000030000C2086000000050800E5BBCC -:1005A00000000030000C2087000000050880E5BC3A -:1005B00000000008000000BA000000050080E5BD52 -:1005C000000000050000E5BB000000050080E5BC60 -:1005D0000000000400210000000000040280000070 -:1005E0000000001800C000BE000000404180E00094 -:1005F00000000024000000C00000000C010000000A -:100600000000000C0100E51D00000004000045BBD7 -:1006100000000008000080BA0000000403C0083099 -:10062000000000004200E000000000040000A00004 -:1006300000000004200045E0000000000000E5E1AB -:10064000000000000000000100000004000700C8D6 -:10065000000000000800E39400000000000000001B -:10066000000000040000E8C4000000040000E8C529 -:10067000000000040000E8C6000000040000E928B3 -:10068000000000040000E929000000040000E92A3D -:1006900000000008000000CC000000040000E92871 -:1006A000000000040000E929000000040000E92A1D -:1006B00000000008000000D30000000402C0200079 -:1006C000000000040006000000000034000000DB11 -:1006D00000000008000000D80000000400008000B6 -:1006E00000000000C000E00000000030000000E159 -:1006F000000000004200E00000000030000000E1C7 -:10070000000000004000E000000000040025001B85 -:100710000000000400230000000000040025000584 -:1007200000000034000000E60000000C00000000A3 -:10073000000000040024400000000004080045C838 -:1007400000000004002400050000000C08004D0B10 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B00000000004000C200000000004001D0018D0 -:1007C00000000004001A000100000034000000FBDB -:1007D000000000080000004A000000080500A04AD0 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:00000001FF -/* production radeon ucode r1xx-r6xx */ diff --git a/firmware/radeon/RS780_me.bin.ihex b/firmware/radeon/RS780_me.bin.ihex deleted file mode 100644 index 6479c106b91f5b2df520cfa126f0d13011840de5..0000000000000000000000000000000000000000 --- a/firmware/radeon/RS780_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A0000060441100000622000000000060000013 -:1000B000000005D10000000000600000000005DE27 -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E000000000000000001800203625000000007D -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000002800204A2D8B -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000001900203625C9 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001700200E2D5A -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001718 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000270020362410 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:10038000000000000000000E0020362300000000E6 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E23000000000000000FC9 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000002700204A2D000000004F -:1003F000000000000020481100000000000000295B -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A00000000000002048040000000000000030AF -:1005B0000020162D00000000000000020029162572 -:1005C0000000000000000030002036250000000080 -:1005D000000000250020162D000000000000000093 -:1005E000002F00A300000000000000000CC000006D -:1005F00000000083000000260020162D00000000EF -:1006000000000000002F00A4000000000000000017 -:100610000CC000000000008400000000004000004A -:100620000000008A000000250020362300000000A2 -:100630000000002600203624000000000000001703 -:1006400000201E2D000000000000000200210227F3 -:10065000000000000000000014E000000000008A1C -:100660000000000000600000000005FF0000000026 -:1006700000600000000005F30000000200210E22CF -:10068000000000000000000014C000000000008D09 -:1006900000000012C040362000000093000000005F -:1006A0002EE0000000000091000000002CE000009F -:1006B000000000900000000200400E2D000000929B -:1006C0000000000300400E2D000000920000000C0E -:1006D00000200E2D00000000000000120020362334 -:1006E000000000000000000300210E2200000000B6 -:1006F0000000000014C00000000000980000A00CE2 -:10070000002044110000000000000000C02048004C -:100710000000000000000000C0404800000000A0F1 -:100720000000A00C002044110000000000000000A8 -:100730000020481100000000000000002EE0000032 -:100740000000009E000000002CE000000000009D62 -:100750000000000200400E2D0000009F000000037A -:1007600000400E2D0000009F0000000C00200E2D08 -:10077000000000000000000000204803000000000E -:1007800000000000003A0C0200000000003F0000E2 -:1007900000280E23000000000000001000210E239E -:1007A00000000000000000110020362300000000BF -:1007B0000000001E0021022B0000000000000000CD -:1007C00014C00000000000A700000016C020362062 -:1007D000000000000000001F0021022B00000000AC -:1007E0000000000014C00000000000AA0000001576 -:1007F000C0203620000000000000000800210E2B61 -:10080000000000000000007F00280E230000000010 -:1008100000000000002F0223000000000000000084 -:100820000CE00000000000E10000000027000000D4 -:10083000000000000000000000600000000002A3B3 -:1008400000000001002F0223000000000000000053 -:100850000AE00000000000B300000000006000009B -:100860000000013A81000000002044110000000057 -:100870000000000600204811000000000000000CED -:1008800000221E300000000099800000002044116A -:1008900000000000000000040020122D00000000F5 -:1008A00000000008002212240000000000000010D8 -:1008B00000201811000000000000000000291CE4C6 -:1008C0000000000000000000006048070000012F49 -:1008D0009B00000000204411000000000000000008 -:1008E00000204802000000009C000000002044118D -:1008F00000000000000000000033146F0000000042 -:100900000000000100333E23000000000000000052 -:10091000D9004800000000000000000000203C0555 -:1009200000000000810000000020441100000000D1 -:100930000000000E00204811000000000000000030 -:1009400000201010000000000000E007002044110B -:10095000000000000000000F0021022B000000003A -:100960000000000014C00000000000CB00F8FF08E9 -:1009700000204811000000009800000000404811CD -:10098000000000DC000000F000280E220000000043 -:10099000000000A0002F0223000000000000000063 -:1009A0000CC00000000000DA0000001100200E2D35 -:1009B0000000000000000001002F022300000000E2 -:1009C000000000000CE00000000000D50000000264 -:1009D000002F022300000000000000000CE00000D7 -:1009E000000000D400003F0000400C11000000D6C1 -:1009F00000001F0000400C11000000D600000F0096 -:100A000000200C11000000000038000900294A23D2 -:100A1000000000003F00000000280E2B0000000036 -:100A20000000000200220E2300000000000000076A -:100A300000494A23000000DC00380F09002048115B -:100A400000000000680000070020481100000000BE -:100A50000000000800214A270000000000000000FC -:100A60000020481100000000060A020000294A2464 -:100A700000000000000000000020481100000000FD -:100A80000000000000204811000000000000A20249 -:100A9000002044110000000000FF000000280E228A -:100AA000000000000000008000294A230000000030 -:100AB0000000002700200E2D00000000000000268E -:100AC0000020122D0000000000000000002F008315 -:100AD00000000000000000000CE00000000000EA40 -:100AE0000000000000600000000005F900000000A8 -:100AF00000400000000000EB00000000006000006B -:100B0000000005FC000000070020222D000000006E -:100B10000000000500220E2200000000001000006E -:100B200000280E23000000000000000000292068BB -:100B30000000000000000000003A0C02000000006D -:100B4000000000EF00280E2300000000000000005D -:100B500000292068000000000000001700200E2D72 -:100B6000000000000000000300210223000000003C -:100B70000000000014E00000000000F80000000B7E -:100B800000210228000000000000000014C0000046 -:100B9000000000F8000004000029222800000000E6 -:100BA0000000001400203628000000000000001C97 -:100BB00000210E22000000000000000014C0000010 -:100BC000000000FD0000A30C002044110000000004 -:100BD0000000000000204811000000000000001E7E -:100BE00000210E22000000000000000014C00000E0 -:100BF0000000010B0000A30F0020441100000000C2 -:100C00000000001100200E2D000000000000000177 -:100C1000002F022300000000000000000CC00000B4 -:100C200000000104FFFFFFFF004048110000010B1E -:100C300000000002002F022300000000000000005E -:100C40000CC00000000001070000FFFF0040481139 -:100C50000000010B00000004002F02230000000030 -:100C6000000000000CC000000000010A000000FFAE -:100C7000004048110000010B000000010020481155 -:100C8000000000000002C400002044110000000029 -:100C90000000001F00210E220000000000000000E4 -:100CA00014C00000000001120000001040210E20BE -:100CB00000000000000000130020362300000000A8 -:100CC0000000001840224A20000000000000001030 -:100CD000C0424A20000001140000000000200C1156 -:100CE0000000000000000013002036230000000078 -:100CF000000000000020481100000000000000007B -:100D000000204811000000000000000A002010111F -:100D10000000000000000000002F0224000000007E -:100D2000000000000CE000000000011B00000000BB -:100D300000204811000000000000000100531224B0 -:100D400000000117FFBFFFFF00283A2E000000003F -:100D50000000001B00210222000000000000000033 -:100D600014C000000000012E81000000002044118A -:100D7000000000000000000D0020481100000000ED -:100D80000000001800220E3000000000FC000000EF -:100D900000280E2300000000810000000020441104 -:100DA000000000000000000E0020481100000000BC -:100DB0000000000000201010000000000000E00E05 -:100DC000002044110000000007F8FF08002048112F -:100DD000000000000000000000294A23000000007D -:100DE0000000001C00201E2D000000000000000874 -:100DF00000214A27000000000000000000204811E8 -:100E000000000000060A020000294A240000000039 -:100E10000000000000204811000000000000000059 -:100E200000204811000000000000000000800000C9 -:100E300000000000810000000020441100000000BC -:100E40000000000100204811000000000000217C8B -:100E50000020441100000000008000000020481124 -:100E60000000000000000000002048060000000014 -:100E70000000000800214A270000000000000000D8 -:100E800017000000000000000004217F00604411F2 -:100E9000000006220000001F0021023000000000B8 -:100EA0000000000014C00000000006210000000443 -:100EB00000404C1100000135810000000020441169 -:100EC00000000000000000010020481100000000A8 -:100ED000000021F800204411000000000000001C68 -:100EE0000020481100000000000421F900604411B6 -:100EF0000000062200000011002102300000000066 -:100F00000000000014E000000000013C00000000B0 -:100F100000800000000000000000000000600000F1 -:100F20000000000B00000000006004110000031529 -:100F3000000000000020041100000000000000007C -:100F400000600811000001B2000000000060000015 -:100F5000000001600000FFFF40280E20000000009C -:100F600000000010C0211220000000000000FFFF60 -:100F7000402806200000000000000010C0210A20C8 -:100F800000000000000000000034146100000000B8 -:100F90000000000000741882000002BB0001A1FDE7 -:100FA00000604411000002E000003FFF002F022F0C -:100FB00000000000000000000CC00000000001471D -:100FC00000000000C040040000000001000000001C -:100FD000006000000000000B000000000060041131 -:100FE00000000315000000000020041100000000B4 -:100FF0000000000000600811000001B200003FFF87 -:10100000002F022F00000000000000000CE0000094 -:10101000000000000000000000600000000001600F -:101020000000001040210E20000000000000FFFF23 -:10103000C0281220000000000000001040211620EF -:10104000000000000000FFFFC0681A20000002BB83 -:101050000001A1FD00604411000002E000003FFF1C -:10106000002F022F00000000000000000CC0000054 -:101070000000015800000000C04004000000000112 -:101080000000225C0020441100000000000000016C -:1010900000300A2F000000000000000100210A2299 -:1010A000000000000000000300384A220000000099 -:1010B0000000225600204411000000000000001A29 -:1010C00000204811000000000000A1FC0020441195 -:1010D0000000000000000001008048110000000036 -:1010E00000000000006000000000000B0000000095 -:1010F000006000000000018F0000000000600000A0 -:10110000000001A000003FFF002F022F00000000A0 -:10111000000000000CE000000000000000000000E3 -:1011200000202C0800000000000000000020241116 -:101130000000000000000000002028110000000056 -:10114000000022560020441100000000000000169C -:1011500000204811000000000000225C0020441123 -:101160000000000000000003002048110000000003 -:1011700093800000002044110000000000000002E5 -:1011800000221E290000000000000000007048EB53 -:101190000000019C0000000000600000000002BB95 -:1011A00000000001403306200000000000000000A5 -:1011B000C03024090000000000003FFF002F022F74 -:1011C00000000000000000000CE000000000000033 -:1011D0000000000000600000000002A3000000000A -:1011E000002F022100000000000000000AE00000C3 -:1011F0000000018100000000006000000000013AD2 -:101200000000000000400000000001869500000082 -:10121000002044110000000000000000002F022107 -:1012200000000000000000000CE00000000001864B -:1012300000000000C0204800000000000000000185 -:10124000005306210000018292000000002044119A -:101250000000000000000000C0604800000001978E -:101260000001A1FD00204411000000000000001159 -:101270000020062D00000000000000000078042A75 -:10128000000002FB00000000002028090000000010 -:1012900000003FFF002F022F0000000000000000B0 -:1012A0000CC000000000017400000000C0400400F9 -:1012B000000000010000021000600411000003158E -:1012C00000003FFF002F022F000000000000000080 -:1012D0000CE000000000019400000015C020362042 -:1012E0000000000000000016C020362000000000B2 -:1012F0003F800000002004110000000046000000B4 -:1013000000600811000001B2000000000080000031 -:10131000000000000000A1FC0020441100000000BB -:1013200000003FFF002F022F00000000000000001F -:101330000CC000000000019B00000001008048116B -:1013400000000000000000210080481100000000A3 -:101350000000FFFF40280E200000000000000010E9 -:10136000C0211220000000000000FFFF40281620CE -:101370000000000000000010C0811A2000000000E2 -:101380008100000000204411000000000000000661 -:1013900000204811000000000000000800221E305C -:1013A000000000000000002900201A2D00000000AD -:1013B0000000E0000020441100000000FFFBFF09D6 -:1013C00000204811000000000000000F0020222D26 -:1013D0000000000000001FFF00294A280000000054 -:1013E000000000060020222D000000000000000088 -:1013F000002920E80000000000000000002048084C -:101400000000000000000000002048110000000063 -:10141000060A020000294A26000000000000000021 -:1014200000204811000000000000000000204811CA -:101430000000000000000100002018110000000062 -:101440000000000800621E280000012F00000008B4 -:1014500000822228000000000002C0000020441189 -:10146000000000000000001500600E2D000001BD0E -:101470000000001600600E2D000001BD0000C00835 -:1014800000204411000000000000001700200E2D75 -:10149000000000000000000014C00000000001B9BE -:1014A0000000000000200411000000000000000007 -:1014B0000020480100000000390000000020481111 -:1014C00000000000000000000020481100000000A3 -:1014D000000000000080480200000000000000182A -:1014E00000202E2D0000000000000000003B0D63D6 -:1014F000000000000000000800224A230000000055 -:101500000000001000224A23000000000000001824 -:1015100000224A2300000000000000000080480371 -:101520000000000000000000006000000000000B50 -:10153000000010000060041100000315000000000E -:1015400000200411000000000000000000600811ED -:10155000000001B2000000070021062F000000007B -:101560000000001300200A2D000000000000000110 -:1015700000202C11000000000000FFFF4028222066 -:10158000000000000000000F0026222800000000DC -:101590000000001040212620000000000000000F85 -:1015A000002626290000000000000000002028027C -:1015B000000000000000225600204411000000003E -:1015C0000000001B00204811000000000000000087 -:1015D000002F022100000000000000000CE00000CD -:1015E000000001E00000225C002044110000000027 -:1015F0000000008100204811000000000000A1FC54 -:1016000000204411000000000000000100204811EB -:10161000000000000000008000201C1100000000FD -:1016200000000000002F0227000000000000000062 -:101630000CE00000000001DC000000000060000081 -:10164000000001E90000000100531E27000001D83E -:101650000000000100202C11000000000000001F0D -:1016600000280A22000000000000001F00282A2A8B -:10167000000000000000000100530621000001D11D -:101680000000225C00204411000000000000000265 -:1016900000304A2F000000000000A1FC002044118F -:1016A00000000000000000010020481100000000C0 -:1016B0000000000100301E2F0000000000000000AC -:1016C000002F022700000000000000000CE00000D6 -:1016D000000000000000000000600000000001E9C0 -:1016E0000000000100531E27000001E50000FFFF7D -:1016F00040280E20000000000000000F00260E23EE -:101700000000000000000010C021122000000000B6 -:101710000000000F0026122400000000000000005E -:1017200000201411000000000000000000601811EB -:10173000000002BB0001A1FD0020441100000000D8 -:1017400000000000002F022B00000000000000003D -:101750000CE00000000001F8000000100022162834 -:1017600000000000FFFF0000002816250000000018 -:101770000000FFFF00281A29000000000000000000 -:10178000002948C500000000000000000020480AB1 -:10179000000000000000000000202C1100000000EC -:1017A000000000100022162300000000FFFF0000D0 -:1017B00000281625000000000000FFFF00281A2462 -:1017C0000000000000000000002948C500000000E3 -:1017D0000000000000731503000002050000000077 -:1017E0000020180500000000000000000073152410 -:1017F0000000020500000000002D14C500000000DC -:1018000000000000003008A20000000000000000FE -:101810000020480200000000000000000020280214 -:101820000000000000000000002020030000000075 -:101830000000000000802404000000000000000FF1 -:1018400000210225000000000000000014C000007C -:101850000000062100000000002B1405000000001D -:1018600000000001009016250000000000000000AC -:10187000006000000000000B000000000060041188 -:10188000000003150000000000200411000000000B -:101890000000000000600811000001B200002256A4 -:1018A00000204411000000000000001A00294A2214 -:1018B0000000000000000000C02000000000000048 -:1018C00000003FFF002F022F00000000000000007A -:1018D0000CE000000000000000000000C020040038 -:1018E000000000000000225C002044110000000005 -:1018F0000000000300384A21000000000000A1FCA5 -:1019000000204411000000000000000100204811E8 -:10191000000000000000FFFF40281220000000002F -:1019200000000010C0211A20000000000000FFFF8E -:1019300040280E200000000000000010C0211620EA -:10194000000000000000000000741465000002BBED -:101950000001A1FD00604411000002E00000000150 -:10196000003306210000000000000000002F0221CB -:1019700000000000000000000CC000000000021980 -:1019800000003FFF002F022F0000000000000000B9 -:101990000CC000000000021200000000C040040063 -:1019A000000000010000000000600000000005DEF3 -:1019B000000000000040040F0000021300000000BF -:1019C00000600000000005D1000000000060000081 -:1019D000000005DE00000210006004110000031585 -:1019E0000000000000600000000001A000000000F6 -:1019F000006000000000019C00000000006000008A -:101A0000000002BB0000000000600000000002A314 -:101A1000938000000020441100000000000000003E -:101A2000002048080000000000000000002F022FE6 -:101A300000000000000000000AE000000000023288 -:101A400000000000006000000000013A00000000FB -:101A50000040000000000236950000000020441104 -:101A60000000000000000000002F022F0000000016 -:101A7000000000000CE00000000002360000000042 -:101A8000C0404800000002339200000000204411D2 -:101A90000000000000000000C0204800000000001E -:101AA0000000225600204411000000000000001633 -:101AB00000204811000000000000225C00204411BA -:101AC000000000000000000300204811000000009A -:101AD0000000A1FC002044110000000000000001F3 -:101AE00000204811000000000001A1FD0020441169 -:101AF000000000000000000000600411000002FB74 -:101B000000000000C04004000000000100000000D0 -:101B100000600000000005D10000A00C002044116E -:101B20000000000000000000C0204800000000008D -:101B300000000000C040480000000000000000005D -:101B4000006000000000000B0000001840210A2087 -:101B50000000000000000003002F0222000000002F -:101B6000000000000AE000000000024C0000001429 -:101B70000020222D00000000000801010029222879 -:101B800000000000000000140020362800000000C3 -:101B90000000A30C00204411000000000000000021 -:101BA000C02048000000000000000000C0204800E5 -:101BB0000000000000000000C0404800000002518A -:101BC00000000000006000000000000B000000109A -:101BD00000600411000003153F8000000020041184 -:101BE000000000000000000000600811000001B2C9 -:101BF0000000225C002044110000000000000003EF -:101C000000204811000000000000000000600000FB -:101C10000000027C0000001700201E2D00000000C4 -:101C20000000000100211E2700000000000000004D -:101C300014E000000000026A0000001200201E2DC7 -:101C4000000000000000FFFF00281E270000000029 -:101C50000000000000341C2700000000000000000D -:101C600012C000000000025F0000000000201C11F4 -:101C70000000000000000000002F00E50000000050 -:101C80000000000008C00000000002620000000028 -:101C900000201407000000000000001200201E2D8C -:101CA000000000000000001000211E2700000000BE -:101CB0000000000000341C4700000000000000008D -:101CC00012C00000000002670000000000201C118C -:101CD0000000000000000000002F00E600000000EF -:101CE0000000000008C000000000026A00000000C0 -:101CF0000020180700000000000000000060000045 -:101D0000000002C100002256002044110000000023 -:101D1000000000000034202300000000000000004C -:101D200012C00000000002720000000000342044D5 -:101D3000000000000000000012C00000000002715E -:101D40000000001600404811000002760000001854 -:101D500000404811000002760000000000342044DA -:101D6000000000000000000012C00000000002752A -:101D70000000001700404811000002760000001922 -:101D800000204811000000000000A1FC00204411C8 -:101D900000000000000000010020481100000000C9 -:101DA0000001A1FD00604411000002E900003FFFB6 -:101DB000002F022F00000000000000000CC00000F7 -:101DC0000000025600000000C040040000000001B6 -:101DD0000000001040210620000000000000FFFF6E -:101DE000C0280A20000000000000001040210E2042 -:101DF000000000000000FFFFC028122000000000CB -:101E00000000001040211620000000000000FFFF2D -:101E1000C0881A200000000081000000002044114A -:101E20000000000000000001002048110000000038 -:101E3000000420040060441100000622000000009D -:101E400000600000000005D100000000C06000003C -:101E5000000002A30000000500200A2D0000000081 -:101E60000000000800220A22000000000000002BF1 -:101E700000201A2D000000000000001C00201E2D74 -:101E8000000000000000700000281E270000000075 -:101E90000000000000311CE6000000000000002AE5 -:101EA00000201A2D000000000000000C00221A265D -:101EB0000000000000000000002F00E6000000000D -:101EC0000000000006E00000000002920000000098 -:101ED00000201C11000000000000000000200C1178 -:101EE000000000000000002B00203623000000004E -:101EF0000000001000201811000000000000000089 -:101F000000691CE20000012F9380000000204411B2 -:101F10000000000000000000002048070000000052 -:101F200095000000002044110000000000000000A7 -:101F3000002F022F00000000000000000CE0000055 -:101F40000000029D0000000100333E2F0000000051 -:101F500000000000D90048000000000092000000CE -:101F6000002044110000000000000000C0204800D4 -:101F7000000000000000001C0040362700000000A8 -:101F80000000000CC0220A20000000000000002910 -:101F9000002036220000000000000028C04036204B -:101FA000000000000000A2A4002044110000000076 -:101FB000000000090020481100000000A1000000FE -:101FC00000204411000000000000000100804811C2 -:101FD000000000000000002100201E2D0000000075 -:101FE00000000000002C1CE30000000000000021A5 -:101FF00000203627000000000000002200201E2DD7 -:102000000000000000000000002C1CE400000000A4 -:1020100000000022002036270000000000000023FE -:1020200000201E2D0000000000000000003120A351 -:102030000000000000000000002D1D07000000004F -:1020400000000023002036270000000000000024CC -:1020500000201E2D0000000000000000003120C400 -:102060000000000000000000002D1D07000000001F -:10207000000000240080362700000000000000213E -:10208000002036230000000000000022002036243B -:10209000000000000000000000311CA30000000050 -:1020A0000000002300203627000000000000000090 -:1020B00000311CC40000000000000024008036270E -:1020C000000000000000001A002036270000000079 -:1020D0000000001B00203628000000000000001750 -:1020E00000201E2D00000000000000020021022739 -:1020F000000000000000000014C00000000002DC2E -:102100000000000000400000000002D90000001A9A -:1021100000203627000000000000001B00203628A9 -:10212000000000000000001700201E2D000000002D -:102130000000000200210227000000000000000053 -:1021400014E00000000002D9000000030021022773 -:10215000000000000000000014E00000000002DCAD -:102160000000002300201E2D0000000000000000E1 -:10217000002E00E1000000000000000002C000008E -:10218000000002DC0000002100201E2D00000000E5 -:1021900000000000003120A100000000000000004D -:1021A000002E00E8000000000000000006C0000053 -:1021B000000002DC0000002400201E2D00000000B2 -:1021C00000000000002E00E20000000000000000FF -:1021D00002C00000000002DC0000002200201E2DD2 -:1021E0000000000000000000003120C200000000DC -:1021F00000000000002E00E80000000000000000C9 -:1022000006C00000000002DC0000000000600000CA -:10221000000005FF0000000000600000000002B5A3 -:102220000000000000400000000002DE000000008E -:1022300000600000000002B5000000000060000027 -:10224000000005F60000000000400000000002DE73 -:102250000000000000600000000002A70000000075 -:1022600000400000000002DE0000001A00201E2DC9 -:10227000000000000000001B0080222D0000000074 -:102280000000001000221E230000000000000000DB -:1022900000294887000000000000000000311CA356 -:1022A000000000000000001000221E2700000000B7 -:1022B0000000000000294887000000000000001016 -:1022C00000221E230000000000000000003120C496 -:1022D000000000000000FFFF00282228000000008E -:1022E0000000000000894907000000000000001005 -:1022F00000221E2300000000000000000029488783 -:10230000000000000000001000221E21000000005C -:102310000000000000294847000000000000000005 -:1023200000311CA3000000000000001000221E2746 -:1023300000000000000000000029488700000000A5 -:102340000000000000311CA100000000000000108F -:1023500000221E270000000000000000002948475E -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:10239000000000000000001000221E2100000000CC -:1023A00000000000003120C2000000000000FFFF1C -:1023B00000282228000000000000000000894907D2 -:1023C000000000000000001000221E23000000009A -:1023D0000000000000294887000000000000000104 -:1023E00000220A210000000000000000003308A2C3 -:1023F000000000000000001000221E22000000006B -:102400000000001000212222000000000000000057 -:1024100000294907000000000000000000311CA353 -:10242000000000000000001000221E270000000035 -:1024300000000000002948870000000000000001A3 -:1024400000220A210000000000000000003008A265 -:10245000000000000000001000221E22000000000A -:1024600000000010002122220000000000000000F7 -:1024700000294907000000000000001000221E2370 -:102480000000000000000000003120C40000000037 -:102490000000FFFF002822280000000000000000CC -:1024A000002949070000000000000000003808C5AE -:1024B00000000000000000000030084100000000A3 -:1024C0000000000100220A220000000000000000BD -:1024D000003308A2000000000000001000221E22AD -:1024E0000000000000000010002122220000000077 -:1024F00000000000008949070000000000000017EC -:102500000020222D000000000000000014C0000088 -:1025100000000318FFFFFFEF002806210000000065 -:10252000000000140020222D000000000000F8E050 -:1025300000204411000000000000000000294901B3 -:1025400000000000000000000089490100000000B8 -:102550000000000000204811000000000000000002 -:102560000020481100000000060A02000080481107 -:102570000000000000000000C0200000000000007B -:1025800097000000C020441100000000000000007F -:10259000C0204811000000008A0000000020441103 -:1025A00000000000000000000020481100000000B2 -:1025B0000000225C00204411000000000000000028 -:1025C000C0204800000000000000A1FC00204411D1 -:1025D0000000000000000000C020480000000000D3 -:1025E00000000000C0200400000000000000000007 -:1025F00000A0000A0000000097000000C020441165 -:102600000000000000000000C02048110000000091 -:102610008A000000C02044110000000000000000FB -:1026200000204811000000000000225C002044113E -:102630000000000000000000C02048000000000072 -:102640000000A1FC00204411000000000000000078 -:10265000C02048000000000000000000C02004006E -:10266000000000000000000000A0000A00000000C0 -:10267000970000000020441100000000000000004E -:1026800000204811000000008A00000000204411D2 -:1026900000000000000000000020481100000000C1 -:1026A0000000225C00204411000000000000000037 -:1026B000C0204800000000000000A1FC00204411E0 -:1026C0000000000000000000C020480000000000E2 -:1026D00000000000C0200400000000000000000016 -:1026E00000A0000A00000000970000000020441134 -:1026F0000000000000000000002048110000000061 -:102700008A000000002044110000000000000000CA -:1027100000204811000000000000225C002044114D -:102720000000000000000000C02048000000000081 -:102730000000A1FC00204411000000000000000087 -:10274000C0204800000000000001A1FD002044114D -:102750000000000000000000D90048000000000058 -:1027600000000000C0200400000000000000000085 -:1027700000A0000A000000000000225700204411C1 -:102780000000000000000003C0484A2000000000D4 -:102790000000225D00204411000000000000000045 -:1027A000C040480000000000000000000060000081 -:1027B000000005DE00000000C0200800000000004E -:1027C0000000225C00204411000000000000000313 -:1027D00000384A22000000000000A1FC0020441143 -:1027E0000000000000000000C020480000000000C1 -:1027F0000001A1FD002044110000000000000000C5 -:10280000002F022200000000000000000CE0000089 -:102810000000000000000000402048000000000010 -:102820000000000140304A200000000000000002CB -:10283000C0304A20000000000000000100530A22BE -:10284000000003550000003FC0280A2000000000DF -:102850008100000000204411000000000000000181 -:102860000020481100000000000021F80020441161 -:1028700000000000000000180020481100000000C7 -:10288000000421F90060441100000622000000113C -:1028900000210230000000000000000014E00000F1 -:1028A0000000035E00000014002F02220000000060 -:1028B000000000000CC000000000036C0001A2A496 -:1028C00000204411000000000000000000604802E9 -:1028D00000000374000021000020441100000000EB -:1028E00000000000C02048000000000000000000C0 -:1028F000C02048000000000000000000C020480088 -:102900000000000000000000C0404800000000007F -:1029100000000004002F0222000000000000000060 -:102920000CC00000000003700001A2A400204411AC -:1029300000000000000000000040480200000367A3 -:1029400000000028002F022200000000000000000C -:102950000CC00000000005BA0001A2A40020441130 -:102960000000000000000000004048020000036773 -:102970000000002C00203626000000000000004966 -:1029800000201811000000000000003F0020481146 -:10299000000000000000000100331A2600000000C3 -:1029A00000000000002F02260000000000000000D0 -:1029B0000CC00000000003760000002C00801A2DDF -:1029C000000000000000003FC0280A2000000000B6 -:1029D00000000015002F022200000000000000008F -:1029E0000CE000000000038C00000006002F022213 -:1029F00000000000000000000CE00000000003B731 -:102A000000000016002F022200000000000000005D -:102A10000CE00000000003B900000020002F02229B -:102A200000000000000000000CE00000000003A215 -:102A30000000000F002F0222000000000000000034 -:102A40000CE00000000003AE00000010002F022286 -:102A500000000000000000000CE00000000003AED9 -:102A60000000001E002F02220000000000000000F5 -:102A70000CE00000000003960000A2A40020441116 -:102A800000000000000000000040480200000000BC -:102A90000800000000290A220000000000000003D6 -:102AA00040210E20000000000000000CC021122078 -:102AB00000000000000800000028122400000000B0 -:102AC00000000014C02216200000000000000000DA -:102AD000002914A4000000000000A2A4002044115A -:102AE0000000000000000000002948A200000000D3 -:102AF0000000A1FE002044110000000000000000C2 -:102B00000040480300000000810000000020441144 -:102B1000000000000000000100204811000000003B -:102B2000000021F800204411000000000000001601 -:102B30000020481100000000000421F90060441149 -:102B400000000622000000150021023000000000F5 -:102B50000000000014E00000000003980000210EB7 -:102B6000002044110000000000000000C0204800C8 -:102B70000000000000000000C0204800000000002D -:102B80000000A2A40020441100000000000000008A -:102B900000404802000000008100000000204411B5 -:102BA00000000000000000010020481100000000AB -:102BB000000021F800204411000000000000001770 -:102BC0000020481100000000000421F900604411B9 -:102BD0000000062200000003002102300000000077 -:102BE0000000000014E00000000003A40000210821 -:102BF000002044110000000000000000C020480038 -:102C00000000000000000000C0204800000000009C -:102C10000000A2A4002044110000000000000000F9 -:102C200000404802000000000000A2A4002044115F -:102C3000000000000000000000204802000000002A -:102C4000800000000020441100000000000000008F -:102C50000020481100000000810000000020441105 -:102C600000000000000000100020481100000000DB -:102C70000000000000200010000000000000000024 -:102C800014C00000000003B4000000000040000079 -:102C9000000000000001A2A4002044110000000078 -:102CA0000000000600404811000000000001A2A43E -:102CB00000204411000000000000001600604811D0 -:102CC000000003740000000000400000000000004D -:102CD00000000000C020080000000000000000000C -:102CE000C0200C00000000000000001D0021022395 -:102CF000000000000000000014E00000000003CE0F -:102D000081000000002044110000000000000001CC -:102D10000020481100000000000021F800204411AC -:102D20000000000000000018002048110000000012 -:102D3000000421F900604411000006220000001187 -:102D400000210230000000000000000014E000003C -:102D5000000003C200002100002044110000000018 -:102D600000000000002048020000000000000000F9 -:102D70000020480300000000BABECAFE002048112F -:102D800000000000CAFEBABE00204811000000008A -:102D90000000A2A400204411000000000000000474 -:102DA0000040481100000000000021700020441184 -:102DB00000000000000000000020480200000000A9 -:102DC0000000000000204803000000008100000017 -:102DD00000204411000000000000000A00204811FB -:102DE00000000000000000000020001000000000B3 -:102DF0000000000014C00000000003D38C0000009D -:102E00000020441100000000CAFEBABE0040481174 -:102E100000000000810000000020441100000000BC -:102E200000000001002048110000000000003FFFEA -:102E300040280A20000000008000000040280E20EA -:102E40000000000040000000C02812200000000028 -:102E50000004000000694622000006220000000075 -:102E6000002014100000000000000000002F0223CA -:102E700000000000000000000CC00000000003E1A2 -:102E800000000000C0401800000003E400003FFF05 -:102E9000C0281A2000000000000400000069462637 -:102EA00000000622000000000020181000000000B2 -:102EB00000000000002F02240000000000000000BD -:102EC0000CC00000000003E700000000C0401C0030 -:102ED000000003EA00003FFFC0281E2000000000A1 -:102EE00000040000006946270000062200000000E0 -:102EF00000201C1000000000000000000020440220 -:102F00000000000000000000002820C500000000B4 -:102F100000000000004948E800000000A580000013 -:102F200000200811000000000000200000200C110B -:102F30000000000083000000006044110000041243 -:102F4000000000000020440200000000000000001B -:102F5000C0204800000000000000000040204800A1 -:102F6000000000000000001FC0210220000000003F -:102F70000000000014C00000000003F70000201053 -:102F800000204411000000000000800000204811D3 -:102F9000000000000000FFFFC0481220000003FFF7 -:102FA000A780000000200811000000000000A00021 -:102FB00000200C110000000083000000006044119C -:102FC0000000041200000000002044020000000085 -:102FD00000000000C02048000000000000000000C9 -:102FE000C0204800000000000000FFFFC0281220A1 -:102FF00000000000830000000020441100000000D9 -:103000000000000000304883000000008400000041 -:10301000002044110000000000000000C020480013 -:1030200000000000000000001D0000000000000083 -:103030008300000000604411000004120000000042 -:10304000C040040000000001A98000000020081119 -:10305000000000000000C00000400C11000003FA56 -:10306000AB80000000200811000000000000F8E024 -:1030700000400C11000003FAAD8000000020081190 -:10308000000000000000F88000400C11000003FA6E -:10309000B380000000200811000000000000F3FCD5 -:1030A00000400C11000003FAAF800000002008115E -:1030B000000000000000E00000400C11000003FAD6 -:1030C000B180000000200811000000000000F000A6 -:1030D00000400C11000003FA83000000002044119E -:1030E00000000000000021480020481100000000FE -:1030F00084000000002044110000000000000000D7 -:10310000C020480000000000000000001D0000007A -:10311000000000000000000000800000000000002F -:1031200001182000C0304620000000000000000010 -:10313000D90048000000000000000000C02004008A -:10314000000000000000000000A0000A00000000D5 -:103150000218A000C030462000000000000000005F -:10316000D90048000000000000000000C02004005A -:10317000000000000000000000A0000A00000000A5 -:103180000318C000C030462000000000000000000E -:10319000D90048000000000000000000C02004002A -:1031A000000000000000000000A0000A0000000075 -:1031B0000418F8E0C03046200000000000000000C5 -:1031C000D90048000000000000000000C0200400FA -:1031D000000000000000000000A0000A0000000045 -:1031E0000518F880C03046200000000000000000F4 -:1031F000D90048000000000000000000C0200400CA -:10320000000000000000000000A0000A0000000014 -:103210000618E000C030462000000000000000005A -:10322000D90048000000000000000000C020040099 -:10323000000000000000000000A0000A00000000E4 -:103240000718F000C0304620000000000000000019 -:10325000D90048000000000000000000C020040069 -:10326000000000000000000000A0000A00000000B4 -:103270000818F3FCC03046200000000000000000E9 -:10328000D90048000000000000000000C020040039 -:10329000000000000000000000A0000A0000000084 -:1032A00000000033C0300A200000000000000000D1 -:1032B000C0403440000000000000003000200A2D13 -:1032C0000000000000000000C0290C4000000000C9 -:1032D0000000003000203623000000000000000045 -:1032E000C0200400000000000000000000A0000A50 -:1032F00000000000860000000020441100000000D3 -:1033000000000000004048010000000085000000AF -:10331000C0204411000000000000000000404801EF -:10332000000000000000217C00204411000000008B -:1033300000000018402102200000000000000000F2 -:1033400014C000000000044700800000C0494A206B -:103350000000044800000000C020480000000000F9 -:1033600000000000C0204800000000000000000035 -:10337000C02048000000000081000000002044112F -:1033800000000000000000010020481100000000C3 -:1033900000000000C0200800000000000000000441 -:1033A000002F0222000000000000000006E00000E4 -:1033B000000004500000000400200811000000007C -:1033C0000000000017000000000000000004217F42 -:1033D00000604411000006220000001F002102309E -:1033E000000000000000000014C000000000000009 -:1033F0000000000000404C020000045000000000EB -:10340000C0200C000000000000000000C0201000E0 -:103410000000000000000000C020140000000000B8 -:1034200000000000C02018000000000000000000A4 -:10343000C0201C000000000000007F0000280A21BE -:103440000000000000004500002F022200000000E4 -:10345000000000000CE0000000000461000000001B -:10346000C02020000000000000000004002F0228FF -:10347000000000000000000006E000000000046101 -:1034800000000004002020110000000000000000E7 -:1034900017000000000000000000001000280A23B0 -:1034A0000000000000000010002F022200000000B9 -:1034B000000000000CE00000000004698100000032 -:1034C000002044110000000000000001002048110D -:1034D00000000000000400000069462400000622ED -:1034E00000000000004000000000046E81000000A9 -:1034F00000204411000000000000000000204811DE -:10350000000000000000216D0020441100000000B8 -:10351000000000000020480400000000000000003F -:10352000006048050000062700000000002824F085 -:10353000000000000000000700280A23000000002F -:1035400000000001002F0222000000000000000027 -:103550000AE000000000047500000000002F00C910 -:10356000000000000000000004E000000000048EE5 -:1035700000000000004000000000049B000000026A -:10358000002F022200000000000000000AE00000FE -:103590000000047A00000000002F00C900000000B5 -:1035A0000000000002E000000000048E00000000A7 -:1035B000004000000000049B00000003002F0222D6 -:1035C00000000000000000000AE000000000047F8E -:1035D00000000000002F00C90000000000000000F3 -:1035E0000CE000000000048E00000000004000001D -:1035F0000000049B00000004002F022200000000D5 -:10360000000000000AE00000000004840000000048 -:10361000002F00C900000000000000000AE00000C8 -:103620000000048E00000000004000000000049B29 -:1036300000000005002F0222000000000000000032 -:103640000AE000000000048900000000002F00C90B -:10365000000000000000000006E000000000048EF2 -:1036600000000000004000000000049B0000000675 -:10367000002F022200000000000000000AE000000D -:103680000000048E00000000002F00C900000000B0 -:103690000000000008E000000000048E00000000B0 -:1036A000004000000000049B00007F0000280A2169 -:1036B0000000000000004500002F02220000000072 -:1036C000000000000AE00000000000000000000808 -:1036D00000210A23000000000000000014C00000C8 -:1036E000000004980000216900204411000000003F -:1036F00000000000C02048000000000000000000A2 -:10370000C02048000000000000000000C020480069 -:1037100000000000CAFEBABE0040481100000000D0 -:1037200000000000C0204400000000000000000075 -:10373000C02000000000000000000000C040480061 -:103740000000000000007F0000280A2100000000A7 -:1037500000004500002F02220000000000000000D1 -:103760000AE00000000004A100000000C0200000EA -:103770000000000000000000C02000000000000069 -:1037800000000000C0400000000000000000000039 -:1037900000404C080000046100000000C020080048 -:1037A000000000000000001040210E20000000007A -:1037B0000000001140211220000000000000001253 -:1037C0004021162000000000000021690020441163 -:1037D000000000000000000000204802000000007F -:1037E0000000000000210225000000000000000091 -:1037F00014E00000000004AB00040000C0494A20AF -:10380000000004ACFFFBFFFFC0284A2000000000BE -:103810000000000000210223000000000000000062 -:1038200014E00000000004B800000000C0204800C0 -:103830000000000000000000C02048000000000060 -:103840000000000000210224000000000000000031 -:1038500014C000000000000081000000002044119E -:10386000000000000000000C0020481100000000D3 -:103870000000000000200010000000000000000018 -:1038800014C00000000004B4A00000000020441197 -:1038900000000000CAFEBABE00404811000000004F -:1038A000810000000020441100000000000000041E -:1038B00000204811000000000000216B002044118E -:1038C0000000000000000000C020481000000000C0 -:1038D00081000000002044110000000000000005ED -:1038E00000204811000000000000216C002044115D -:1038F0000000000000000000C02048100000000090 -:1039000000000000002F0224000000000000000062 -:103910000CE000000000000000000000004000007B -:10392000000004B200000000C0210A2000000000D6 -:103930000000000014C00000000004CB8100000063 -:103940000020441100000000000000000020481189 -:10395000000000000000216D002044110000000064 -:1039600000000000C020480000000000000000002F -:10397000C060480000000627000000000040000072 -:10398000000004CF8100000000204411000000006E -:1039900000000001002048110000000000040000A9 -:1039A000C02946200000000000000000C0600000A8 -:1039B0000000062200000001002102220000000099 -:1039C0000000000014C00000000004D600002169BF -:1039D000002044110000000000000000C02048004A -:1039E0000000000000000000C020480000000000AF -:1039F000000000000020481000000000CAFEBABE0F -:103A0000004048110000000000000000C0204400F9 -:103A10000000000000000000C0404810000000004E -:103A2000810000000020441100000000000000019F -:103A30000020481100000000000021F8002044117F -:103A4000000000000000000E0020481100000000EF -:103A5000000421F90060441100000622000000006B -:103A600000210230000000000000000014C000002F -:103A7000000004D800002180002044110000000054 -:103A800000000000C020480000000000000000000E -:103A9000C02000000000000000000000C02048001E -:103AA0000000000000000000C02000000000000036 -:103AB00000000000C04048000000000000000003BB -:103AC00000333E2F00000000000000010021022111 -:103AD000000000000000000014E0000000000508E5 -:103AE0000000002C00200A2D00000000000400004F -:103AF00018E00C11000004F70000000100333E2F15 -:103B000000000000000021690020441100000000B6 -:103B1000000000000020480200000000000000003B -:103B200000204803000000000000000800300A22C6 -:103B30000000000000000000C0204800000000005D -:103B400000000000C02048000000000000002169C3 -:103B50000020441100000000000000000020480286 -:103B600000000000000000000020480300000000EA -:103B70000000000800300A220000000000000000E1 -:103B8000C02048000000000000000000D8C048002D -:103B9000000004EB00002169002044110000000037 -:103BA00000000000002048020000000000000000AB -:103BB00000204803000000000000000800300A2236 -:103BC0000000000000000000C020480000000000CD -:103BD00000000000C0204800000000000000002D90 -:103BE0000020122D000000000000000000290C83BE -:103BF00000000000000021690020441100000000C6 -:103C0000000000000020480200000000000000004A -:103C100000204803000000000000000800300A22D5 -:103C20000000000000000000C0204800000000006C -:103C300000000000C020480000000000000000114B -:103C400000210224000000000000000014C0000059 -:103C5000000000000000000000400000000004B26E -:103C60000000002CC0203620000000000000002DC5 -:103C7000C0403620000000000000000F002102219B -:103C8000000000000000000014C000000000050D4E -:103C900000000000006000000000000B00000000B9 -:103CA000D90000000000000000000000C040040037 -:103CB00000000001B50000000020441100000000D9 -:103CC000000020000020481100000000B6000000A5 -:103CD00000204411000000000000A0000020481156 -:103CE00000000000B70000000020441100000000A8 -:103CF0000000C0000020481100000000B8000000D3 -:103D000000204411000000000000F8E000204811ED -:103D100000000000B9000000002044110000000075 -:103D20000000F8800020481100000000BA000000E8 -:103D300000204411000000000000E00000204811B5 -:103D400000000000BB000000002044110000000043 -:103D50000000F0000020481100000000BC0000003E -:103D600000204411000000000000F3FC0020481176 -:103D7000000000008100000000204411000000004D -:103D8000000000020020481100000000000000FFB9 -:103D900000280E300000000000000000002F022369 -:103DA00000000000000000000CC000000000052121 -:103DB00000000000C020080000000000000000001B -:103DC00014C00000000005360000000000200C11A7 -:103DD000000000000000001C00203623000000004E -:103DE0000000002B00203623000000000000002906 -:103DF00000203623000000000000002800203623A9 -:103E00000000000000000017002036230000000022 -:103E100000000025002036230000000000000026DE -:103E2000002036230000000000000015002036238B -:103E300000000000000000160020362300000000F3 -:103E4000FFFFE00000200C11000000000000002136 -:103E5000002036230000000000000022002036234E -:103E60000000000000001FFF00200C1100000000F7 -:103E70000000002300203623000000000000002482 -:103E80000020362300000000F1FFFFFF00283A2E3B -:103E9000000000000000001AC0220E2000000000F8 -:103EA000000000000029386E0000000081000000C2 -:103EB000002044110000000000000006002048110E -:103EC000000000000000002A402036200000000012 -:103ED00087000000002044110000000000000000E6 -:103EE000C0204800000000000000A1F400204411A0 -:103EF000000000000000000000204810000000004A -:103F00009D00000000204411000000000000001F80 -:103F100040214A20000000009600000000204411CB -:103F20000000000000000000C02048000000000069 -:103F300000000000C0200C00000000000000000095 -:103F4000C0201000000000000000001F0021162407 -:103F5000000000000000000014C00000000000008D -:103F60000000001D002036230000000000000003B8 -:103F700000281E2300000000000000080022222369 -:103F800000000000FFFFF0000028222800000000D1 -:103F900000000000002920E8000000000000001FD1 -:103FA00000203628000000000000001800211E2319 -:103FB0000000000000000020002036270000000064 -:103FC0000000000200221624000000000000000093 -:103FD000003014A8000000000000001E002036255C -:103FE000000000000000000300211A24000000006F -:103FF0001000000000281A2600000000EFFFFFFF5D -:1040000000283A2E0000000000000000004938CED1 -:10401000000006100000000140280A2000000000F7 -:104020000000000640280E200000000000000300F1 -:10403000C028122000000000000000080021122407 -:104040000000000000000000C0201620000000005A -:1040500000000000C0201A20000000000000000046 -:1040600000210222000000000000000014C0000037 -:104070000000056C810000000020441100000000D9 -:10408000000000010020481100000000000022583C -:1040900000300A24000000000004000000694622ED -:1040A00000000622000021690020441100000000E9 -:1040B0000000000000204805000000000002000091 -:1040C00000294A26000000000000000000204810DF -:1040D00000000000CAFEBABE002048110000000027 -:1040E00000000002002F022300000000000000007A -:1040F0000CC000000000057400000000C0201C106F -:104100000000000000000000C04000000000058228 -:1041100000000002002F0223000000000000000049 -:104120000CC0000000000574810000000020441154 -:104130000000000000000001002048110000000005 -:104140000000225800300A24000000000004000093 -:10415000006946220000062200000000C0201C105A -:104160000000000000000000C040000000000582C8 -:1041700000000000002F02230000000000000000EB -:104180000CC000000000057800000000C0201C00EA -:104190000000000000000000C04000000000058298 -:1041A00000000004002F02230000000000000000B7 -:1041B0000CC00000000005808100000000204411B8 -:1041C0000000000000000000002048110000000076 -:1041D0000000216D002044110000000000000000DC -:1041E000C02048000000000000000000C06048003F -:1041F000000006270000000000401C10000005829F -:1042000000000000C02000000000000000000000CE -:10421000C040000000000000000000000EE00000B0 -:10422000000005840000000000600000000005C3DD -:1042300000000000002F0224000000000000000029 -:104240000CC00000000005920000A2B7002044113D -:1042500000000000000000000020480700000000EF -:10426000000000330020262D000000000000001A8E -:10427000002122290000000000000006002226295B -:10428000000000000000A2C4002044110000000053 -:1042900000000000003048E90000000000000000BD -:1042A00000E00000000005900000A2D100204411B1 -:1042B000000000000000000000404808000000006E -:1042C0000000A2D100204411000000000000000105 -:1042D00000504A280000000000000001002F0224C6 -:1042E00000000000000000000CC00000000005A05D -:1042F0000000A2BB002044110000000000000000EC -:104300000020480700000000000000340020262D97 -:10431000000000000000001A002122290000000017 -:104320000000000600222629000000000000A2C5AF -:10433000002044110000000000000000003048E9A7 -:10434000000000000000000000E000000000059EEA -:104350000000A2D200204411000000000000000074 -:1043600000404808000000000000A2D200204411D4 -:10437000000000000000000100504A28000000007A -:1043800000000002002F02240000000000000000D6 -:104390000CC00000000005AE0000A2BF00204411C8 -:1043A000000000000000000000204807000000009E -:1043B000000000350020262D000000000000001A3B -:1043C000002122290000000000000006002226290A -:1043D000000000000000A2C6002044110000000000 -:1043E00000000000003048E900000000000000006C -:1043F00000E00000000005AC0000A2D30020441142 -:10440000000000000000000000404808000000001C -:104410000000A2D3002044110000000000000001B1 -:1044200000504A28000000000000A2C300204411F0 -:10443000000000000000000000204807000000000D -:10444000000000360020262D000000000000001AA9 -:104450000021222900000000000000060022262979 -:10446000000000000000A2C700204411000000006E -:1044700000000000003048E90000000000000000DB -:1044800000E00000000005B80000A2D400204411A4 -:10449000000000000000000000404808000000008C -:1044A0000000A2D400204411000000000000000120 -:1044B00000504A2800000000850000000020441140 -:1044C0000000000000000000002048010000000083 -:1044D0000000304A002044110000000001000000EC -:1044E0000020481100000000000000000040000013 -:1044F000000005BEA4000000C02044110000000020 -:1045000000000000C0404800000000000000000063 -:10451000C0600000000005C300000000C0400400AF -:10452000000000010001A2A40020441100000000CE -:104530000000003F00204811000000000000003F84 -:1045400000204811000000000000003F002048113A -:10455000000000000000003F0020481100000000A3 -:104560000000000500204811000000000000A1F438 -:10457000002044110000000000000000002048114D -:10458000000000008800000000204411000000002E -:10459000000000010020481100000000FF000000A2 -:1045A000002044110000000000000000002048111D -:1045B0000000000000000001002048110000000081 -:1045C0000000000200804811000000000000000010 -:1045D0000EE00000000005D60000100000200811C9 -:1045E000000000000000002B002036220000000028 -:1045F0000000000000600000000005DA000000007C -:1046000000600000000005C3980000000020441175 -:1046100000000000000000000080481100000000C1 -:1046200000000000C0600000000005DA000000008B -:10463000C0400400000000010000A2A400204411BA -:1046400000000000000000220020481100000000CF -:10465000890000000020441100000000000000015B -:1046600000404811000005CD9700000000204411D3 -:1046700000000000000000000020481100000000C1 -:104680008A0000000020441100000000000000002B -:1046900000404811000005CD00000000006000004F -:1046A000000005F30001A2A4C02044110000000096 -:1046B0000000001600604811000003740000201084 -:1046C00000204411000000000001000000204811FB -:1046D00000000000810000000020441100000000E4 -:1046E0000000000100204811000000000000217CB3 -:1046F0000020441100000000098000000020481143 -:1047000000000000FFFFFFFF002048110000000034 -:104710000000000000204811000000000000000020 -:1047200017000000000000000004217F0060441119 -:10473000000006220000001F0021023000000000DF -:104740000000000014C00000000000000000000491 -:1047500000404C11000005ED00000000004000008A -:10476000000000000000001700201E2D00000000C7 -:104770000000000400291E270000000000000017B0 -:1047800000803627000000000000001700201E2DCA -:1047900000000000FFFFFFFB00281E2700000000B4 -:1047A00000000017008036270000000000000017FE -:1047B00000201E2D000000000000000800291E2718 -:1047C00000000000000000170080362700000000F5 -:1047D0000000001700201E2D00000000FFFFFFF763 -:1047E00000281E2700000000000000170080362768 -:1047F000000000000001A2A40020441100000000FD -:104800000000001600604811000003740000201032 -:1048100000204411000000000001000000204811A9 -:10482000000000000000217C002044110000000076 -:10483000018000000020481100000000FFFFFFFF82 -:104840000020481100000000000000000020481176 -:104850000000000000000000170000000000000041 -:104860008100000000204411000000000000000151 -:1048700000204811000000000004217F0060441166 -:10488000000006220000001F00210230000000008E -:104890000000000014C0000000000621000000100D -:1048A00000404C110000060700000000C02004007A -:1048B000000000000000000038C000000000000000 -:1048C0000000001D00200A2D000000000000001E56 -:1048D00000200E2D000000000000001F0020122DFF -:1048E00000000000000000200020162D0000000045 -:1048F00000002169002044110000000000000000B9 -:1049000000204804000000000000000000204805CE -:10491000000000000000000000204801000000002E -:10492000CAFEBABE002048110000000000000004CA -:10493000003012240000000000000000002F00647E -:1049400000000000000000000CC000000000062075 -:104950000000000300281A220000000000000008E8 -:104960000022122200000000FFFFF00000281224A5 -:104970000000000000000000002910C4000000003A -:104980000000001F0040362400000000000000006E -:104990000080000000000000000000001AC00000BD -:1049A000000006229F0000000020441100000000CB -:1049B000CAFEBABE0020481100000000000000003E -:1049C0001AE0000000000625000000000080000042 -:1049D00000000000000000001AC0000000000627D0 -:1049E0009E0000000020441100000000CAFEBABE74 -:1049F0000020481100000000000000001AE0000044 -:104A00000000062A000000000080000000000000F6 -:104A100000000000006000000000000B000010001B -:104A200000600411000003150000000000200411C4 -:104A3000000000000000000000600811000001B24A -:104A40000000225C00204411000000000000000370 -:104A500000204811000000000000225600204411F0 -:104A6000000000000000001B0020481100000000B2 -:104A70000000A1FC00204411000000000000000123 -:104A800000204811000000000001A1FDC0204411D9 -:104A9000000000000000002100201E2D000000008A -:104AA0000000001000221E2700000000000000246B -:104AB0000020222D000000000000FFFF0028222817 -:104AC000000000000000000000294907000000006D -:104AD000000000000020481100000000000000223B -:104AE0000020222D000000000000FFFF00282228E7 -:104AF000000000000000000000294907000000003D -:104B00000000000000204811000000000000002309 -:104B100000201E2D000000000000001000221E27B3 -:104B2000000000000000000000294907000000000C -:104B300000000000004048110000000000000000DC -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B0000142050A05BA02500000000001C301685E -:1052C000044105BA00000000022502090250015104 -:1052D000000000000223024502A00241000000007D -:1052E00003D705BA05BA05BA0000000005E205E3D8 -:1052F000031F05BA00000000032005BF0320034A76 -:105300000000000003340282034C033E0000000052 -:1053100005BA05BA05BA05BA0000000005BA055776 -:1053200005BA032A0000000003BC05BA04C3034EFB -:105330000000000004A20455043F05BA000000006C -:1053400004D805BA044304E5000000000455050F25 -:10535000035B037B0000000005BA05BA05BA05BA75 -:105360000000000005BA05BA05BA05BA0000000041 -:1053700005BA05BA05D805C10000000005BA05BA8E -:10538000000705BA0000000005BA05BA05BA05BA5B -:105390000000000005BA05BA05BA05BA0000000011 -:1053A00003F803ED0408040600000000040E040ADC -:1053B000040C041000000000041C04180424042041 -:1053C00000000000042C0428043404300000000015 -:1053D00005BA05BA043A04380000000005BA05BA57 -:1053E00005BA05BA0000000005BA05BA05BA05BA43 -:1053F000000000000002060E062C0006000000005F -:00000001FF diff --git a/firmware/radeon/RS780_pfp.bin.ihex b/firmware/radeon/RS780_pfp.bin.ihex deleted file mode 100644 index 40880411e785084851514b018caab01204854a87..0000000000000000000000000000000000000000 --- a/firmware/radeon/RS780_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000CA040000A00000007E828B007C038BED -:10001000008001DB007C038B00D4401E00EE001E3C -:1000200000CA040000A00000007E828B00C41838C3 -:1000300000CA240000CA2800009581CB00C41C3AE5 -:1000400000C3C00000CA080000CA0C00007C744B4A -:1000500000C200050099C00000C41C3A007C744C2A -:1000600000C0FFE000042C0800309002007D250055 -:1000700000351402007D350B00255407007CD58027 -:1000800000259C070095C00400D5001B007EDDC143 -:10009000007D9D8000D6801B00D5801B00D4401EB3 -:1000A00000D5401E00D6401E00D6801E00D4801E03 -:1000B00000D4C01E009783D300D5C01E00CA08001C -:1000C0000080001A00CA0C0000E4011E00D4001ECB -:1000D0000080000C00C4183800E4013E00D4001E6B -:1000E0000080000C00C4183800D4401E00EE001E32 -:1000F00000CA040000A00000007E828B00E4011E04 -:1001000000D4001E00D4401E00EE001E00CA0400F1 -:1001100000A00000007E828B00E4013E00D4001E9F -:1001200000D4401E00EE001E00CA040000A0000023 -:10013000007E828B00CA080000CA0C00008001DB30 -:1001400000D4802400CA0800007C00C000C8142528 -:1001500000C81824007C9488007C988000C20003AA -:1001600000D40075007C744C0080006400D4401EF4 -:1001700000CA180000D4401E00D5801E0080006216 -:1001800000D4007500D4401E00CA080000CA0C004C -:1001900000CA100000D4801900D4C01800D5001780 -:1001A00000D4801E00D4C01E00D5001E00E2001E38 -:1001B00000CA040000A00000007E828B00D40075FD -:1001C00000D4401E00CA080000CA0C0000CA10007B -:1001D00000D4801900D4C01800D5001700D4801EA8 -:1001E00000D4C01E00D5001E00EE001E00CA040090 -:1001F00000A00000007E828B00CA080000248C0151 -:1002000000D480600094C0030004100100041002B8 -:1002100000D5002500D4401E0080000000D4801EC0 -:1002200000CA080000D4806100D4401E0080000095 -:1002300000D4801E00CA080000CA0C0000D4401E72 -:1002400000D4801600D4C01600D4801E008001DBCC -:1002500000D4C01E00C6084300CA0C0000CA10002B -:100260000094800400CA140000E420F300D420139A -:1002700000D5606500D4E01C00D5201C00D5601CB2 -:10028000008000000006200100C6084300CA0C00E0 -:1002900000CA1000009483F700CA140000E420F3A1 -:1002A0000080009C00D4201300C6084300CA0C0044 -:1002B00000CA1000009883EF00CA140000D4006444 -:1002C000008000B00000000000C4143200C61843D3 -:1002D00000C4082F0095400500C40C3000D4401E17 -:1002E0000080000000EE001E009583F500C4103170 -:1002F00000D4403300D5206500D4A01C00D4E01CFD -:1003000000D5201C00E4015E00D4001E0080000027 -:100310000006200100CA1800000A200100D600765D -:1003200000C408360098800700C6104500950110EB -:1003300000D4001F00D460620080000000D420625E -:1003400000CC383500CC1433008401DE00D40072B8 -:1003500000D5401E0080000000EE001E00E2001AE2 -:10036000008401DE00E2001A00CC104B00CC0447F0 -:10037000002C9401007D098B00984005007D15CB71 -:1003800000D4001A008001DB00D4006D0034440169 -:1003900000CC0C480098403A00CC2C4A00958004D0 -:1003A00000CC0449008001DB00D4001A00D4C01A3C -:1003B000002828010084011300CC10030098801B42 -:1003C0000004380C0084011300CC1003009880173F -:1003D000000438080084011300CC10030098801337 -:1003E000000438040084011300CC1003009880142A -:1003F00000CC104C009A800900CC144D009840DCD1 -:1004000000D4006D00CC184800D5001A00D5401A61 -:10041000008000EC00D5801A0096C0D500D4006D95 -:10042000008001DB00D4006E009AC00300D4006D90 -:1004300000D4006E0080000000EC007F009AC0CC69 -:1004400000D4006D008001DB00D4006E00CC1403EA -:1004500000CC180300CC1C03007D9103007DD583E4 -:10046000007D190C0035CC1F0035701F007CF0CBCF -:10047000007CD08B00880000007E8E8B0095C0042D -:1004800000D4006E008001DB00D4001A00D4C01A32 -:1004900000CC080300CC0C0300CC100300CC1403E8 -:1004A00000CC180300CC1C0300CC240300CC280390 -:1004B0000035C41F0036B01F007C704B0034F01FA5 -:1004C000007C704B0035701F007C704B007D888174 -:1004D000007DCCC1007E5101007E9541007C908260 -:1004E000007CD4C2007C848B009AC003007C8C8B7F -:1004F000002C88010098809E00D4006D0098409CDC -:1005000000D4006E00CC084C00CC0C4D00CC104840 -:1005100000D4801A00D4C01A0080012400D5001A2B -:1005200000CC083200D40032009482B600CA0C001D -:1005300000D4401E0080000000D4001E00E4011E14 -:1005400000D4001E00CA080000CA0C0000CA100037 -:1005500000D4401E00CA140000D4801E00D4C01E67 -:1005600000D5001E00D5401E00D54034008000009C -:1005700000EE001E0028040400E2001A00E2001A47 -:1005800000D4401A00CA380000CC080300CC0C0389 -:1005900000CC0C0300CC0C030098829A00000000F1 -:1005A000008401DE00D7A06F0080000000EE001F75 -:1005B00000CA040000C2FF0000CC083400C13FFFA5 -:1005C000007C74CB007CC90B007D010F0099028D6B -:1005D000007C738B008401DE00D7A06F00800000D8 -:1005E00000EE001F00CA080000281900007D898B5A -:1005F000009580140028140400CA0C0000CA1000E2 -:1006000000CA1C0000CA240000E2001F00D4C01A67 -:1006100000D5001A00D5401A00CC180300CC2C03DA -:1006200000CC2C0300CC2C03007DA58B007D9C47C7 -:1006300000984274000000000080018400D4C01AB9 -:1006400000D4401E00D4801E0080000000EE001E7A -:1006500000E4011E00D4001E00D4401E00EE001E67 -:1006600000CA040000A00000007E828B00E4013E6E -:1006700000D4001E00D4401E00EE001E00CA04007C -:1006800000A00000007E828B00CA080000248C06B7 -:10069000000CCC060098C00600CC104E0099000457 -:1006A00000D4007300E4011E00D4001E00D4401EDC -:1006B00000D4801E0080000000EE001E00CA08006A -:1006C00000CA0C000034D01800251001009500214C -:1006D00000C17FFF00CA100000CA140000CA180041 -:1006E00000D4801D00D4C01D007DB18B00C142022A -:1006F00000C2C00100D5801D0034DC0E007D5D4CC1 -:10070000007F734C00D7401E00D5001E00D5401E50 -:1007100000C1420000C2C00000099C010031DC1091 -:10072000007F5F4C007F734C00042802007D8380B3 -:1007300000D5A86F00D5806600D7401E00EC005E93 -:1007400000C8240200C82402008001DB00D6007625 -:1007500000D4401E00D4801E00D4C01E00800000C3 -:1007600000EE001E0080000000EE001F00D4001FFD -:100770000080000000D4001F00D4001F008800008B -:1007800000D4001F00000000000000000000000076 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:10080000000101940002019B000300B2000400A259 -:10081000000500030006003F000700320008014FFA -:1008200000090046000A0036001001D9001700C573 -:100830000022015D0023016C002000D70024014844 -:100840000026004D0027005C0028008D0029005183 -:10085000002A007E002B0061002F0088003200AAD1 -:10086000003401A20036006F003C0179003F009582 -:10087000004101AF00440151005501960056019D11 -:100880000060000B00610034006200380063003833 -:1008900000640038006500380066003800670038E2 -:1008A0000068003A00690041006A0048006B004897 -:1008B000006C0048006D0048006E0048006F004862 -:1008C000007301D9000000060000000600000006C9 -:1008D0000000000600000006000000060000000600 -:1008E00000000006000000060000000600000006F0 -:1008F00000000006000000060000000600000006E0 -:00000001FF diff --git a/firmware/radeon/RV610_me.bin.ihex b/firmware/radeon/RV610_me.bin.ihex deleted file mode 100644 index ba19ed8929207bfa1d2daaf8d7d480dc197e550b..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV610_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A000006044110000068D0000000000600000A8 -:1000B000000006310000000000600000000006455E -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E000000000000000001800203625000000007D -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000002800204A2D8B -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000001900203625C9 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001700200E2D5A -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001718 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000270020362410 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:10038000000000000000000E0020362300000000E6 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E23000000000000000FC9 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000002700204A2D000000004F -:1003F000000000000020481100000000000000295B -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A00000000000002048040000000000000030AF -:1005B0000020162D00000000000000020029162572 -:1005C0000000000000000030002036250000000080 -:1005D000000000250020162D000000000000000093 -:1005E000002F00A300000000000000000CC000006D -:1005F00000000083000000260020162D00000000EF -:1006000000000000002F00A4000000000000000017 -:100610000CC000000000008400000000004000004A -:100620000000008A000000250020362300000000A2 -:100630000000002600203624000000000000001703 -:1006400000201E2D000000000000000200210227F3 -:10065000000000000000000014E000000000008A1C -:1006600000000000006000000000066800000000BC -:10067000006000000000065C0000000200210E2265 -:10068000000000000000000014C000000000008D09 -:1006900000000012C040362000000093000000005F -:1006A0002EE0000000000091000000002CE000009F -:1006B000000000900000000200400E2D000000929B -:1006C0000000000300400E2D000000920000000C0E -:1006D00000200E2D00000000000000120020362334 -:1006E000000000000000000300210E2200000000B6 -:1006F0000000000014C00000000000980000A00CE2 -:10070000002044110000000000000000C02048004C -:100710000000000000000000C0404800000000A0F1 -:100720000000A00C002044110000000000000000A8 -:100730000020481100000000000000002EE0000032 -:100740000000009E000000002CE000000000009D62 -:100750000000000200400E2D0000009F000000037A -:1007600000400E2D0000009F0000000C00200E2D08 -:10077000000000000000000000204803000000000E -:1007800000000000003A0C0200000000003F0000E2 -:1007900000280E23000000000000001000210E239E -:1007A00000000000000000110020362300000000BF -:1007B0000000001E0021022B0000000000000000CD -:1007C00014C00000000000A700000016C020362062 -:1007D000000000000000001F0021022B00000000AC -:1007E0000000000014C00000000000AA0000001576 -:1007F000C0203620000000000000000800210E2B61 -:10080000000000000000007F00280E230000000010 -:1008100000000000002F0223000000000000000084 -:100820000CE00000000000E10000000027000000D4 -:10083000000000000000000000600000000002A3B3 -:1008400000000001002F0223000000000000000053 -:100850000AE00000000000B300000000006000009B -:100860000000013A81000000002044110000000057 -:100870000000000600204811000000000000000CED -:1008800000221E300000000099800000002044116A -:1008900000000000000000040020122D00000000F5 -:1008A00000000008002212240000000000000010D8 -:1008B00000201811000000000000000000291CE4C6 -:1008C0000000000000000000006048070000012F49 -:1008D0009B00000000204411000000000000000008 -:1008E00000204802000000009C000000002044118D -:1008F00000000000000000000033146F0000000042 -:100900000000000100333E23000000000000000052 -:10091000D9004800000000000000000000203C0555 -:1009200000000000810000000020441100000000D1 -:100930000000000E00204811000000000000000030 -:1009400000201010000000000000E007002044110B -:10095000000000000000000F0021022B000000003A -:100960000000000014C00000000000CB00F8FF08E9 -:1009700000204811000000009800000000404811CD -:10098000000000DC000000F000280E220000000043 -:10099000000000A0002F0223000000000000000063 -:1009A0000CC00000000000DA0000001100200E2D35 -:1009B0000000000000000001002F022300000000E2 -:1009C000000000000CE00000000000D50000000264 -:1009D000002F022300000000000000000CE00000D7 -:1009E000000000D400003F0000400C11000000D6C1 -:1009F00000001F0000400C11000000D600000F0096 -:100A000000200C11000000000038000900294A23D2 -:100A1000000000003F00000000280E2B0000000036 -:100A20000000000200220E2300000000000000076A -:100A300000494A23000000DC00380F09002048115B -:100A400000000000680000070020481100000000BE -:100A50000000000800214A270000000000000000FC -:100A60000020481100000000060A020000294A2464 -:100A700000000000000000000020481100000000FD -:100A80000000000000204811000000000000A20249 -:100A9000002044110000000000FF000000280E228A -:100AA000000000000000008000294A230000000030 -:100AB0000000002700200E2D00000000000000268E -:100AC0000020122D0000000000000000002F008315 -:100AD00000000000000000000CE00000000000EA40 -:100AE000000000000060000000000662000000003E -:100AF00000400000000000EB00000000006000006B -:100B000000000665000000070020222D0000000004 -:100B10000000000500220E2200000000001000006E -:100B200000280E23000000000000000000292068BB -:100B30000000000000000000003A0C02000000006D -:100B4000000000EF00280E2300000000000000005D -:100B500000292068000000000000001700200E2D72 -:100B6000000000000000000300210223000000003C -:100B70000000000014E00000000000F80000000B7E -:100B800000210228000000000000000014C0000046 -:100B9000000000F8000004000029222800000000E6 -:100BA0000000001400203628000000000000001C97 -:100BB00000210E22000000000000000014C0000010 -:100BC000000000FD0000A30C002044110000000004 -:100BD0000000000000204811000000000000001E7E -:100BE00000210E22000000000000000014C00000E0 -:100BF0000000010B0000A30F0020441100000000C2 -:100C00000000001100200E2D000000000000000177 -:100C1000002F022300000000000000000CC00000B4 -:100C200000000104FFFFFFFF004048110000010B1E -:100C300000000002002F022300000000000000005E -:100C40000CC00000000001070000FFFF0040481139 -:100C50000000010B00000004002F02230000000030 -:100C6000000000000CC000000000010A000000FFAE -:100C7000004048110000010B000000010020481155 -:100C8000000000000002C400002044110000000029 -:100C90000000001F00210E220000000000000000E4 -:100CA00014C00000000001120000001040210E20BE -:100CB00000000000000000130020362300000000A8 -:100CC0000000001840224A20000000000000001030 -:100CD000C0424A20000001140000000000200C1156 -:100CE0000000000000000013002036230000000078 -:100CF000000000000020481100000000000000007B -:100D000000204811000000000000000A002010111F -:100D10000000000000000000002F0224000000007E -:100D2000000000000CE000000000011B00000000BB -:100D300000204811000000000000000100531224B0 -:100D400000000117FFBFFFFF00283A2E000000003F -:100D50000000001B00210222000000000000000033 -:100D600014C000000000012E81000000002044118A -:100D7000000000000000000D0020481100000000ED -:100D80000000001800220E3000000000FC000000EF -:100D900000280E2300000000810000000020441104 -:100DA000000000000000000E0020481100000000BC -:100DB0000000000000201010000000000000E00E05 -:100DC000002044110000000007F8FF08002048112F -:100DD000000000000000000000294A23000000007D -:100DE0000000001C00201E2D000000000000000874 -:100DF00000214A27000000000000000000204811E8 -:100E000000000000060A020000294A240000000039 -:100E10000000000000204811000000000000000059 -:100E200000204811000000000000000000800000C9 -:100E300000000000810000000020441100000000BC -:100E40000000000100204811000000000000217C8B -:100E50000020441100000000008000000020481124 -:100E60000000000000000000002048060000000014 -:100E70000000000800214A270000000000000000D8 -:100E800017000000000000000004217F00604411F2 -:100E90000000068D0000001F00210230000000004D -:100EA0000000000014C000000000068C00000004D8 -:100EB00000404C1100000135810000000020441169 -:100EC00000000000000000010020481100000000A8 -:100ED000000021F800204411000000000000001C68 -:100EE0000020481100000000000421F900604411B6 -:100EF0000000068D000000110021023000000000FB -:100F00000000000014E000000000013C00000000B0 -:100F100000800000000000000000000000600000F1 -:100F20000000000B00000000006004110000031529 -:100F3000000000000020041100000000000000007C -:100F400000600811000001B2000000000060000015 -:100F5000000001600000FFFF40280E20000000009C -:100F600000000010C0211220000000000000FFFF60 -:100F7000402806200000000000000010C0210A20C8 -:100F800000000000000000000034146100000000B8 -:100F90000000000000741882000002BB0001A1FDE7 -:100FA00000604411000002E000003FFF002F022F0C -:100FB00000000000000000000CC00000000001471D -:100FC00000000000C040040000000001000000001C -:100FD000006000000000000B000000000060041131 -:100FE00000000315000000000020041100000000B4 -:100FF0000000000000600811000001B200003FFF87 -:10100000002F022F00000000000000000CE0000094 -:10101000000000000000000000600000000001600F -:101020000000001040210E20000000000000FFFF23 -:10103000C0281220000000000000001040211620EF -:10104000000000000000FFFFC0681A20000002BB83 -:101050000001A1FD00604411000002E000003FFF1C -:10106000002F022F00000000000000000CC0000054 -:101070000000015800000000C04004000000000112 -:101080000000225C0020441100000000000000016C -:1010900000300A2F000000000000000100210A2299 -:1010A000000000000000000300384A220000000099 -:1010B0000000225600204411000000000000001A29 -:1010C00000204811000000000000A1FC0020441195 -:1010D0000000000000000001008048110000000036 -:1010E00000000000006000000000000B0000000095 -:1010F000006000000000018F0000000000600000A0 -:10110000000001A000003FFF002F022F00000000A0 -:10111000000000000CE000000000000000000000E3 -:1011200000202C0800000000000000000020241116 -:101130000000000000000000002028110000000056 -:10114000000022560020441100000000000000169C -:1011500000204811000000000000225C0020441123 -:101160000000000000000003002048110000000003 -:1011700093800000002044110000000000000002E5 -:1011800000221E290000000000000000007048EB53 -:101190000000019C0000000000600000000002BB95 -:1011A00000000001403306200000000000000000A5 -:1011B000C03024090000000000003FFF002F022F74 -:1011C00000000000000000000CE000000000000033 -:1011D0000000000000600000000002A3000000000A -:1011E000002F022100000000000000000AE00000C3 -:1011F0000000018100000000006000000000013AD2 -:101200000000000000400000000001869500000082 -:10121000002044110000000000000000002F022107 -:1012200000000000000000000CE00000000001864B -:1012300000000000C0204800000000000000000185 -:10124000005306210000018292000000002044119A -:101250000000000000000000C0604800000001978E -:101260000001A1FD00204411000000000000001159 -:101270000020062D00000000000000000078042A75 -:10128000000002FB00000000002028090000000010 -:1012900000003FFF002F022F0000000000000000B0 -:1012A0000CC000000000017400000000C0400400F9 -:1012B000000000010000021000600411000003158E -:1012C00000003FFF002F022F000000000000000080 -:1012D0000CE000000000019400000015C020362042 -:1012E0000000000000000016C020362000000000B2 -:1012F0003F800000002004110000000046000000B4 -:1013000000600811000001B2000000000080000031 -:10131000000000000000A1FC0020441100000000BB -:1013200000003FFF002F022F00000000000000001F -:101330000CC000000000019B00000001008048116B -:1013400000000000000000210080481100000000A3 -:101350000000FFFF40280E200000000000000010E9 -:10136000C0211220000000000000FFFF40281620CE -:101370000000000000000010C0811A2000000000E2 -:101380008100000000204411000000000000000661 -:1013900000204811000000000000000800221E305C -:1013A000000000000000002900201A2D00000000AD -:1013B0000000E0000020441100000000FFFBFF09D6 -:1013C00000204811000000000000000F0020222D26 -:1013D0000000000000001FFF00294A280000000054 -:1013E000000000060020222D000000000000000088 -:1013F000002920E80000000000000000002048084C -:101400000000000000000000002048110000000063 -:10141000060A020000294A26000000000000000021 -:1014200000204811000000000000000000204811CA -:101430000000000000000100002018110000000062 -:101440000000000800621E280000012F00000008B4 -:1014500000822228000000000002C0000020441189 -:10146000000000000000001500600E2D000001BD0E -:101470000000001600600E2D000001BD0000C00835 -:1014800000204411000000000000001700200E2D75 -:10149000000000000000000014C00000000001B9BE -:1014A0000000000000200411000000000000000007 -:1014B0000020480100000000390000000020481111 -:1014C00000000000000000000020481100000000A3 -:1014D000000000000080480200000000000000182A -:1014E00000202E2D0000000000000000003B0D63D6 -:1014F000000000000000000800224A230000000055 -:101500000000001000224A23000000000000001824 -:1015100000224A2300000000000000000080480371 -:101520000000000000000000006000000000000B50 -:10153000000010000060041100000315000000000E -:1015400000200411000000000000000000600811ED -:10155000000001B2000000070021062F000000007B -:101560000000001300200A2D000000000000000110 -:1015700000202C11000000000000FFFF4028222066 -:10158000000000000000000F0026222800000000DC -:101590000000001040212620000000000000000F85 -:1015A000002626290000000000000000002028027C -:1015B000000000000000225600204411000000003E -:1015C0000000001B00204811000000000000000087 -:1015D000002F022100000000000000000CE00000CD -:1015E000000001E00000225C002044110000000027 -:1015F0000000008100204811000000000000A1FC54 -:1016000000204411000000000000000100204811EB -:10161000000000000000008000201C1100000000FD -:1016200000000000002F0227000000000000000062 -:101630000CE00000000001DC000000000060000081 -:10164000000001E90000000100531E27000001D83E -:101650000000000100202C11000000000000001F0D -:1016600000280A22000000000000001F00282A2A8B -:10167000000000000000000100530621000001D11D -:101680000000225C00204411000000000000000265 -:1016900000304A2F000000000000A1FC002044118F -:1016A00000000000000000010020481100000000C0 -:1016B0000000000100301E2F0000000000000000AC -:1016C000002F022700000000000000000CE00000D6 -:1016D000000000000000000000600000000001E9C0 -:1016E0000000000100531E27000001E50000FFFF7D -:1016F00040280E20000000000000000F00260E23EE -:101700000000000000000010C021122000000000B6 -:101710000000000F0026122400000000000000005E -:1017200000201411000000000000000000601811EB -:10173000000002BB0001A1FD0020441100000000D8 -:1017400000000000002F022B00000000000000003D -:101750000CE00000000001F8000000100022162834 -:1017600000000000FFFF0000002816250000000018 -:101770000000FFFF00281A29000000000000000000 -:10178000002948C500000000000000000020480AB1 -:10179000000000000000000000202C1100000000EC -:1017A000000000100022162300000000FFFF0000D0 -:1017B00000281625000000000000FFFF00281A2462 -:1017C0000000000000000000002948C500000000E3 -:1017D0000000000000731503000002050000000077 -:1017E0000020180500000000000000000073152410 -:1017F0000000020500000000002D14C500000000DC -:1018000000000000003008A20000000000000000FE -:101810000020480200000000000000000020280214 -:101820000000000000000000002020030000000075 -:101830000000000000802404000000000000000FF1 -:1018400000210225000000000000000014C000007C -:101850000000068C00000000002B140500000000B2 -:1018600000000001009016250000000000000000AC -:10187000006000000000000B000000000060041188 -:10188000000003150000000000200411000000000B -:101890000000000000600811000001B200002256A4 -:1018A00000204411000000000000001A00294A2214 -:1018B0000000000000000000C02000000000000048 -:1018C00000003FFF002F022F00000000000000007A -:1018D0000CE000000000000000000000C020040038 -:1018E000000000000000225C002044110000000005 -:1018F0000000000300384A21000000000000A1FCA5 -:1019000000204411000000000000000100204811E8 -:10191000000000000000FFFF40281220000000002F -:1019200000000010C0211A20000000000000FFFF8E -:1019300040280E200000000000000010C0211620EA -:10194000000000000000000000741465000002BBED -:101950000001A1FD00604411000002E00000000150 -:10196000003306210000000000000000002F0221CB -:1019700000000000000000000CC000000000021980 -:1019800000003FFF002F022F0000000000000000B9 -:101990000CC000000000021200000000C040040063 -:1019A000000000010000000000600000000006458B -:1019B000000000000040040F0000021300000000BF -:1019C0000060000000000631000000000060000020 -:1019D000000006450000021000600411000003151D -:1019E0000000000000600000000001A000000000F6 -:1019F000006000000000019C00000000006000008A -:101A0000000002BB0000000000600000000002A314 -:101A1000938000000020441100000000000000003E -:101A2000002048080000000000000000002F022FE6 -:101A300000000000000000000AE000000000023288 -:101A400000000000006000000000013A00000000FB -:101A50000040000000000236950000000020441104 -:101A60000000000000000000002F022F0000000016 -:101A7000000000000CE00000000002360000000042 -:101A8000C0404800000002339200000000204411D2 -:101A90000000000000000000C0204800000000001E -:101AA0000000225600204411000000000000001633 -:101AB00000204811000000000000225C00204411BA -:101AC000000000000000000300204811000000009A -:101AD0000000A1FC002044110000000000000001F3 -:101AE00000204811000000000001A1FD0020441169 -:101AF000000000000000000000600411000002FB74 -:101B000000000000C04004000000000100000000D0 -:101B100000600000000006310000A00C002044110D -:101B20000000000000000000C0204800000000008D -:101B300000000000C040480000000000000000005D -:101B4000006000000000000B0000001840210A2087 -:101B50000000000000000003002F0222000000002F -:101B6000000000000AE000000000024C0000001429 -:101B70000020222D00000000000801010029222879 -:101B800000000000000000140020362800000000C3 -:101B90000000A30C00204411000000000000000021 -:101BA000C02048000000000000000000C0204800E5 -:101BB0000000000000000000C0404800000002518A -:101BC00000000000006000000000000B000000109A -:101BD00000600411000003153F8000000020041184 -:101BE000000000000000000000600811000001B2C9 -:101BF0000000225C002044110000000000000003EF -:101C000000204811000000000000000000600000FB -:101C10000000027C0000001700201E2D00000000C4 -:101C20000000000100211E2700000000000000004D -:101C300014E000000000026A0000001200201E2DC7 -:101C4000000000000000FFFF00281E270000000029 -:101C50000000000000341C2700000000000000000D -:101C600012C000000000025F0000000000201C11F4 -:101C70000000000000000000002F00E50000000050 -:101C80000000000008C00000000002620000000028 -:101C900000201407000000000000001200201E2D8C -:101CA000000000000000001000211E2700000000BE -:101CB0000000000000341C4700000000000000008D -:101CC00012C00000000002670000000000201C118C -:101CD0000000000000000000002F00E600000000EF -:101CE0000000000008C000000000026A00000000C0 -:101CF0000020180700000000000000000060000045 -:101D0000000002C100002256002044110000000023 -:101D1000000000000034202300000000000000004C -:101D200012C00000000002720000000000342044D5 -:101D3000000000000000000012C00000000002715E -:101D40000000001600404811000002760000001854 -:101D500000404811000002760000000000342044DA -:101D6000000000000000000012C00000000002752A -:101D70000000001700404811000002760000001922 -:101D800000204811000000000000A1FC00204411C8 -:101D900000000000000000010020481100000000C9 -:101DA0000001A1FD00604411000002E900003FFFB6 -:101DB000002F022F00000000000000000CC00000F7 -:101DC0000000025600000000C040040000000001B6 -:101DD0000000001040210620000000000000FFFF6E -:101DE000C0280A20000000000000001040210E2042 -:101DF000000000000000FFFFC028122000000000CB -:101E00000000001040211620000000000000FFFF2D -:101E1000C0881A200000000081000000002044114A -:101E20000000000000000001002048110000000038 -:101E300000042004006044110000068D0000000032 -:101E4000006000000000063100000000C0600000DB -:101E5000000002A30000000500200A2D0000000081 -:101E60000000000800220A22000000000000002BF1 -:101E700000201A2D000000000000001C00201E2D74 -:101E8000000000000000700000281E270000000075 -:101E90000000000000311CE6000000000000002AE5 -:101EA00000201A2D000000000000000C00221A265D -:101EB0000000000000000000002F00E6000000000D -:101EC0000000000006E00000000002920000000098 -:101ED00000201C11000000000000000000200C1178 -:101EE000000000000000002B00203623000000004E -:101EF0000000001000201811000000000000000089 -:101F000000691CE20000012F9380000000204411B2 -:101F10000000000000000000002048070000000052 -:101F200095000000002044110000000000000000A7 -:101F3000002F022F00000000000000000CE0000055 -:101F40000000029D0000000100333E2F0000000051 -:101F500000000000D90048000000000092000000CE -:101F6000002044110000000000000000C0204800D4 -:101F7000000000000000001C0040362700000000A8 -:101F80000000000CC0220A20000000000000002910 -:101F9000002036220000000000000028C04036204B -:101FA000000000000000A2A4002044110000000076 -:101FB000000000090020481100000000A1000000FE -:101FC00000204411000000000000000100804811C2 -:101FD000000000000000002100201E2D0000000075 -:101FE00000000000002C1CE30000000000000021A5 -:101FF00000203627000000000000002200201E2DD7 -:102000000000000000000000002C1CE400000000A4 -:1020100000000022002036270000000000000023FE -:1020200000201E2D0000000000000000003120A351 -:102030000000000000000000002D1D07000000004F -:1020400000000023002036270000000000000024CC -:1020500000201E2D0000000000000000003120C400 -:102060000000000000000000002D1D07000000001F -:10207000000000240080362700000000000000213E -:10208000002036230000000000000022002036243B -:10209000000000000000000000311CA30000000050 -:1020A0000000002300203627000000000000000090 -:1020B00000311CC40000000000000024008036270E -:1020C000000000000000001A002036270000000079 -:1020D0000000001B00203628000000000000001750 -:1020E00000201E2D00000000000000020021022739 -:1020F000000000000000000014C00000000002DC2E -:102100000000000000400000000002D90000001A9A -:1021100000203627000000000000001B00203628A9 -:10212000000000000000001700201E2D000000002D -:102130000000000200210227000000000000000053 -:1021400014E00000000002D9000000030021022773 -:10215000000000000000000014E00000000002DCAD -:102160000000002300201E2D0000000000000000E1 -:10217000002E00E1000000000000000002C000008E -:10218000000002DC0000002100201E2D00000000E5 -:1021900000000000003120A100000000000000004D -:1021A000002E00E8000000000000000006C0000053 -:1021B000000002DC0000002400201E2D00000000B2 -:1021C00000000000002E00E20000000000000000FF -:1021D00002C00000000002DC0000002200201E2DD2 -:1021E0000000000000000000003120C200000000DC -:1021F00000000000002E00E80000000000000000C9 -:1022000006C00000000002DC0000000000600000CA -:10221000000006680000000000600000000002B539 -:102220000000000000400000000002DE000000008E -:1022300000600000000002B5000000000060000027 -:102240000000065F0000000000400000000002DE09 -:102250000000000000600000000002A70000000075 -:1022600000400000000002DE0000001A00201E2DC9 -:10227000000000000000001B0080222D0000000074 -:102280000000001000221E230000000000000000DB -:1022900000294887000000000000000000311CA356 -:1022A000000000000000001000221E2700000000B7 -:1022B0000000000000294887000000000000001016 -:1022C00000221E230000000000000000003120C496 -:1022D000000000000000FFFF00282228000000008E -:1022E0000000000000894907000000000000001005 -:1022F00000221E2300000000000000000029488783 -:10230000000000000000001000221E21000000005C -:102310000000000000294847000000000000000005 -:1023200000311CA3000000000000001000221E2746 -:1023300000000000000000000029488700000000A5 -:102340000000000000311CA100000000000000108F -:1023500000221E270000000000000000002948475E -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:10239000000000000000001000221E2100000000CC -:1023A00000000000003120C2000000000000FFFF1C -:1023B00000282228000000000000000000894907D2 -:1023C000000000000000001000221E23000000009A -:1023D0000000000000294887000000000000000104 -:1023E00000220A210000000000000000003308A2C3 -:1023F000000000000000001000221E22000000006B -:102400000000001000212222000000000000000057 -:1024100000294907000000000000000000311CA353 -:10242000000000000000001000221E270000000035 -:1024300000000000002948870000000000000001A3 -:1024400000220A210000000000000000003008A265 -:10245000000000000000001000221E22000000000A -:1024600000000010002122220000000000000000F7 -:1024700000294907000000000000001000221E2370 -:102480000000000000000000003120C40000000037 -:102490000000FFFF002822280000000000000000CC -:1024A000002949070000000000000000003808C5AE -:1024B00000000000000000000030084100000000A3 -:1024C0000000000100220A220000000000000000BD -:1024D000003308A2000000000000001000221E22AD -:1024E0000000000000000010002122220000000077 -:1024F00000000000008949070000000000000017EC -:102500000020222D000000000000000014C0000088 -:1025100000000318FFFFFFEF002806210000000065 -:10252000000000140020222D000000000000F8E050 -:1025300000204411000000000000000000294901B3 -:1025400000000000000000000089490100000000B8 -:102550000000000000204811000000000000000002 -:102560000020481100000000060A02000080481107 -:102570000000000000000000C0200000000000007B -:1025800097000000C020441100000000000000007F -:10259000C0204811000000008A0000000020441103 -:1025A00000000000000000000020481100000000B2 -:1025B0000000225C00204411000000000000000028 -:1025C000C0204800000000000000A1FC00204411D1 -:1025D0000000000000000000C020480000000000D3 -:1025E00000000000C0200400000000000000000007 -:1025F00000A0000A00000000970000000020441125 -:102600000000000000000000002048110000000051 -:102610008A000000002044110000000000000000BB -:1026200000204811000000000000225C002044113E -:102630000000000000000000C02048000000000072 -:102640000000A1FC00204411000000000000000078 -:10265000C02048000000000000000000C02004006E -:10266000000000000000000000A0000A00000000C0 -:10267000970000000020441100000000000000004E -:1026800000204811000000008A00000000204411D2 -:1026900000000000000000000020481100000000C1 -:1026A0000000225C00204411000000000000000037 -:1026B000C0204800000000000000A1FC00204411E0 -:1026C0000000000000000000C020480000000000E2 -:1026D0000001A1FD002044110000000000000000E6 -:1026E000D90048000000000000000000C0200400E5 -:1026F000000000000000000000A0000A0000000030 -:1027000000002257002044110000000000000003D8 -:10271000C0484A20000000000000225D0020441153 -:102720000000000000000000C04048000000000061 -:1027300000000000006000000000064500000000EE -:10274000C0200800000000000000225C00204411AE -:10275000000000000000000300384A2200000000D2 -:102760000000A1FC00204411000000000000000057 -:10277000C0204800000000000001A1FD002044111D -:102780000000000000000000002F022200000000F6 -:10279000000000000CE0000000000000000000004D -:1027A00040204800000000000000000140304A20A6 -:1027B0000000000000000002C0304A2000000000BD -:1027C0000000000100530A220000034B0000003FFC -:1027D000C0280A20000000008100000000204411F1 -:1027E000000000000000000100204811000000006F -:1027F000000021F800204411000000000000001833 -:102800000020481100000000000421F9006044117C -:102810000000068D000000110021023000000000C1 -:102820000000000014E00000000003540000001449 -:10283000002F022200000000000000000CC0000079 -:10284000000003640000201000204411000000007C -:102850000000800000204811000000000001A2A438 -:102860000020441100000000000000000060480249 -:102870000000036E00002100002044110000000051 -:1028800000000000C0204800000000000000000020 -:10289000C02048000000000000000000C0204800E8 -:1028A0000000000000000000C040480000000000E0 -:1028B00000000004002F02220000000000000000C1 -:1028C0000CC000000000036A00002010002044112A -:1028D00000000000000080000020481100000000FF -:1028E0000001A2A40020441100000000000000002C -:1028F000004048020000035F00000028002F022271 -:1029000000000000000000000CC00000000005C036 -:102910000001A2A4002044110000000000000000FB -:10292000004048020000035F0000002C0020362613 -:102930000000000000000049002018110000000005 -:102940000000003F002048110000000000000001CE -:1029500000331A260000000000000000002F0226AD -:1029600000000000000000000CC000000000037028 -:102970000000002C00801A2D000000000000003F25 -:10298000C0280A200000000000000015002F0222CD -:1029900000000000000000000CE0000000000386C2 -:1029A00000000006002F02220000000000000000CE -:1029B0000CE00000000003B100000016002F02220E -:1029C00000000000000000000CE00000000003B563 -:1029D00000000020002F0222000000000000000084 -:1029E0000CE000000000039C0000000F002F0222FA -:1029F00000000000000000000CE00000000003A840 -:102A000000000010002F0222000000000000000063 -:102A10000CE00000000003A80000001E002F0222AE -:102A200000000000000000000CE000000000039027 -:102A30000000A2A4002044110000000000000000DB -:102A400000404802000000000800000000290A229F -:102A5000000000000000000340210E2000000000E4 -:102A60000000000CC021122000000000000800003F -:102A7000002812240000000000000014C0221620CC -:102A80000000000000000000002914A40000000065 -:102A90000000A2A40020441100000000000000007B -:102AA000002948A2000000000000A1FE00204411FF -:102AB000000000000000000000404803000000008B -:102AC000810000000020441100000000000000010F -:102AD0000020481100000000000021F800204411EF -:102AE0000000000000000016002048110000000057 -:102AF000000421F9006044110000068D000000155B -:102B000000210230000000000000000014E000007E -:102B1000000003920000210E00204411000000007C -:102B200000000000C020480000000000000000007D -:102B3000C0204800000000000000A2A400204411B2 -:102B400000000000000000000040480200000000FB -:102B5000810000000020441100000000000000017E -:102B60000020481100000000000021F8002044115E -:102B700000000000000000170020481100000000C5 -:102B8000000421F9006044110000068D00000003DC -:102B900000210230000000000000000014E00000EE -:102BA0000000039E000021080020441100000000E6 -:102BB00000000000C02048000000000000000000ED -:102BC000C0204800000000000000A2A40020441122 -:102BD000000000000000000000404802000000006B -:102BE0000000A2A40020441100000000000000002A -:102BF0000020480200000000800000000020441176 -:102C0000000000000000000000204811000000004B -:102C100081000000002044110000000000000010AE -:102C200000204811000000000000000000200010FB -:102C3000000000000000000014C00000000003AE0F -:102C40000000000000400000000000000000201014 -:102C50000020441100000000000080000020481106 -:102C6000000000000001A2A40020441100000000A8 -:102C70000000000600404811000000000000201085 -:102C800000204411000000000000800000204811D6 -:102C9000000000000001A2A4002044110000000078 -:102CA00000000016006048110000036E00000000E4 -:102CB000004000000000000000000000C0200800EC -:102CC0000000000000000000C0200C000000000018 -:102CD0000000001D00210223000000000000000091 -:102CE00014E00000000003CE810000000020441129 -:102CF000000000000000000100204811000000005A -:102D0000000021F80020441100000000000000181D -:102D10000020481100000000000421F90060441167 -:102D20000000068D000000110021023000000000AC -:102D30000000000014E00000000003C000002100BB -:102D400000204411000000000000000000204802A4 -:102D50000000000000000000002048030000000008 -:102D6000BABECAFE0020481100000000CAFEBABE6A -:102D70000020481100000000000020100020441135 -:102D8000000000000000800000204811000000004A -:102D90000000A2A400204411000000000000000474 -:102DA0000040481100000000000021700020441184 -:102DB00000000000000000000020480200000000A9 -:102DC0000000000000204803000000008100000017 -:102DD00000204411000000000000000A00204811FB -:102DE00000000000000000000020001000000000B3 -:102DF0000000000014C00000000003D38C0000009D -:102E00000020441100000000CAFEBABE0040481174 -:102E100000000000810000000020441100000000BC -:102E200000000001002048110000000000003FFFEA -:102E300040280A20000000008000000040280E20EA -:102E40000000000040000000C02812200000000028 -:102E500000040000006946220000068D000000000A -:102E6000002014100000000000000000002F0223CA -:102E700000000000000000000CC00000000003E1A2 -:102E800000000000C0401800000003E400003FFF05 -:102E9000C0281A2000000000000400000069462637 -:102EA0000000068D00000000002018100000000047 -:102EB00000000000002F02240000000000000000BD -:102EC0000CC00000000003E700000000C0401C0030 -:102ED000000003EA00003FFFC0281E2000000000A1 -:102EE00000040000006946270000068D0000000075 -:102EF00000201C1000000000000000000020440220 -:102F00000000000000000000002820C500000000B4 -:102F100000000000004948E800000000A580000013 -:102F200000200811000000000000200000200C110B -:102F30000000000083000000006044110000041243 -:102F4000000000000020440200000000000000001B -:102F5000C0204800000000000000000040204800A1 -:102F6000000000000000001FC0210220000000003F -:102F70000000000014C00000000003F70000201053 -:102F800000204411000000000000800000204811D3 -:102F9000000000000000FFFFC0481220000003FFF7 -:102FA000A780000000200811000000000000A00021 -:102FB00000200C110000000083000000006044119C -:102FC0000000041200000000002044020000000085 -:102FD00000000000C02048000000000000000000C9 -:102FE000C0204800000000000000FFFFC0281220A1 -:102FF00000000000830000000020441100000000D9 -:103000000000000000304883000000008400000041 -:10301000002044110000000000000000C020480013 -:1030200000000000000000001D0000000000000083 -:103030008300000000604411000004120000000042 -:10304000C040040000000001A98000000020081119 -:10305000000000000000C00000400C11000003FA56 -:10306000AB80000000200811000000000000F8E024 -:1030700000400C11000003FAAD8000000020081190 -:10308000000000000000F88000400C11000003FA6E -:10309000B380000000200811000000000000F3FCD5 -:1030A00000400C11000003FAAF800000002008115E -:1030B000000000000000E00000400C11000003FAD6 -:1030C000B180000000200811000000000000F000A6 -:1030D00000400C11000003FA83000000002044119E -:1030E00000000000000021480020481100000000FE -:1030F00084000000002044110000000000000000D7 -:10310000C020480000000000000000001D0000007A -:10311000000000000000000000800000000000002F -:1031200001182000C0304620000000000000000010 -:10313000D90048000000000000000000C02004008A -:10314000000000000000000000A0000A00000000D5 -:103150000218A000C030462000000000000000005F -:10316000D90048000000000000000000C02004005A -:10317000000000000000000000A0000A00000000A5 -:103180000318C000C030462000000000000000000E -:10319000D90048000000000000000000C02004002A -:1031A000000000000000000000A0000A0000000075 -:1031B0000418F8E0C03046200000000000000000C5 -:1031C000D90048000000000000000000C0200400FA -:1031D000000000000000000000A0000A0000000045 -:1031E0000518F880C03046200000000000000000F4 -:1031F000D90048000000000000000000C0200400CA -:10320000000000000000000000A0000A0000000014 -:103210000618E000C030462000000000000000005A -:10322000D90048000000000000000000C020040099 -:10323000000000000000000000A0000A00000000E4 -:103240000718F000C0304620000000000000000019 -:10325000D90048000000000000000000C020040069 -:10326000000000000000000000A0000A00000000B4 -:103270000818F3FCC03046200000000000000000E9 -:10328000D90048000000000000000000C020040039 -:10329000000000000000000000A0000A0000000084 -:1032A0000000003000200A2D000000000000000097 -:1032B000C0290C4000000000000000300020362330 -:1032C0000000000000000000C0200400000000001A -:1032D0000000000000A0000A0000000086000000BE -:1032E00000204411000000000000000000404801E0 -:1032F0000000000085000000C02044110000000014 -:103300000000000000404801000000000000217C97 -:10331000002044110000000000000018402102209D -:10332000000000000000000014C000000000044580 -:1033300000800000C0494A20000004460000000050 -:10334000C02048000000000000000000C02048002D -:103350000000000000000000C02048000000000045 -:103360008100000000204411000000000000000166 -:10337000002048110000000000000000C0200800EC -:103380000000000000000000170000000000000026 -:103390000004217F006044110000068D0000001F22 -:1033A00000210230000000000000000014C00000F6 -:1033B000000000000000000000404C020000044B30 -:1033C00000000000C0200C00000000000000000011 -:1033D000C02010000000000000000000C020140009 -:1033E0000000000000000000C020180000000000E5 -:1033F00000000000C0201C000000000000007F0052 -:1034000000280A210000000000004500002F0222D1 -:1034100000000000000000000CE000000000045963 -:1034200000000000C020200000000000000000009C -:1034300017000000000000000000001000280A2310 -:103440000000000000000010002F02220000000019 -:10345000000000000CE0000000000461810000009A -:10346000002044110000000000000001002048116D -:103470000000000000040000006946240000068DE2 -:103480000000000000400000000004668100000011 -:10349000002044110000000000000000002048113E -:1034A000000000000000216D002044110000000019 -:1034B00000000000002048040000000000000000A0 -:1034C000006048050000069200000000002824F07B -:1034D000000000000000000700280A230000000090 -:1034E00000000001002F0222000000000000000088 -:1034F0000AE000000000046D00000000002F00C979 -:10350000000000000000000004E00000000004864D -:1035100000000000004000000000049300000002D2 -:10352000002F022200000000000000000AE000005E -:103530000000047200000000002F00C9000000001D -:103540000000000002E0000000000486000000000F -:10355000004000000000049300000003002F02223E -:1035600000000000000000000AE0000000000477F6 -:1035700000000000002F00C9000000000000000053 -:103580000CE0000000000486000000000040000085 -:103590000000049300000004002F0222000000003D -:1035A000000000000AE000000000047C00000000B1 -:1035B000002F00C900000000000000000AE0000029 -:1035C000000004860000000000400000000004939A -:1035D00000000005002F0222000000000000000093 -:1035E0000AE000000000048100000000002F00C974 -:1035F000000000000000000006E00000000004865B -:1036000000000000004000000000049300000006DD -:10361000002F022200000000000000000AE000006D -:103620000000048600000000002F00C90000000018 -:103630000000000008E00000000004860000000018 -:10364000004000000000049300007F0000280A21D1 -:103650000000000000004500002F022200000000D2 -:10366000000000000AE00000000000000000000868 -:1036700000210A23000000000000000014C0000028 -:1036800000000490000021690020441100000000A7 -:1036900000000000C0204800000000000000000002 -:1036A000C02048000000000000000000C0204800CA -:1036B00000000000CAFEBABE004048110000000031 -:1036C00000000000C02044000000000000000000D6 -:1036D000C02000000000000000000000C0404800C2 -:1036E0000000000000007F0000280A210000000008 -:1036F00000004500002F0222000000000000000032 -:103700000AE000000000049900000000C020000052 -:103710000000000000000000C020000000000000C9 -:1037200000000000C0400000000000000000000099 -:1037300000404C080000045900000000C0200800B0 -:10374000000000000000001040210E2000000000DA -:1037500000000011402112200000000000000012B3 -:1037600040211620000000000000216900204411C3 -:1037700000000000000000000020480200000000DF -:1037800000000000002102250000000000000000F1 -:1037900014E00000000004A300040000C0494A2017 -:1037A000000004A4FFFBFFFFC0284A200000000027 -:1037B00000000000002102230000000000000000C3 -:1037C00014E00000000004B000000000C020480029 -:1037D0000000000000000000C020480000000000C1 -:1037E0000000000000210224000000000000000092 -:1037F00014C00000000000008100000000204411FF -:10380000000000000000000C002048110000000033 -:103810000000000000200010000000000000000078 -:1038200014C00000000004ACA000000000204411FF -:1038300000000000CAFEBABE0040481100000000AF -:10384000810000000020441100000000000000047E -:1038500000204811000000000000216B00204411EE -:103860000000000000000000C02048100000000020 -:10387000810000000020441100000000000000054D -:1038800000204811000000000000216C00204411BD -:103890000000000000000000C020481000000000F0 -:1038A00000000000002F02240000000000000000C3 -:1038B0000CE00000000000000000000000400000DC -:1038C000000004AA00000000C0210A20000000003F -:1038D0000000000014C00000000004C381000000CC -:1038E00000204411000000000000000000204811EA -:1038F000000000000000216D0020441100000000C5 -:1039000000000000C020480000000000000000008F -:10391000C060480000000692000000000040000067 -:10392000000004C7810000000020441100000000D6 -:103930000000000100204811000000000004000009 -:10394000C02946200000000000000000C060000008 -:103950000000068D0000000100210222000000008E -:103960000000000014C00000000004CE0000216927 -:10397000002044110000000000000000C0204800AA -:103980000000000000000000C0204800000000000F -:10399000000000000020481000000000CAFEBABE6F -:1039A000004048110000000000000000C02044005A -:1039B0000000000000000000C040481000000000AF -:1039C0008100000000204411000000000000000100 -:1039D0000020481100000000000021F800204411E0 -:1039E000000000000000000E002048110000000050 -:1039F000000421F9006044110000068D0000000061 -:103A000000210230000000000000000014C000008F -:103A1000000004D0000021800020441100000000BC -:103A200000000000C020480000000000000000006E -:103A3000C02000000000000000000000C02048007E -:103A40000000000000000000C02000000000000096 -:103A500000000000C040480000000000000000031B -:103A600000333E2F00000000000000010021022171 -:103A7000000000000000000014E00000000005004D -:103A80000000002C00200A2D0000000000040000AF -:103A900018E00C11000004EF0000000100333E2F7D -:103AA0000000000000002169002044110000000017 -:103AB000000000000020480200000000000000009C -:103AC00000204803000000000000000800300A2227 -:103AD0000000000000000000C020480000000000BE -:103AE00000000000C0204800000000000000216924 -:103AF00000204411000000000000000000204802E7 -:103B0000000000000000000000204803000000004A -:103B10000000000800300A22000000000000000041 -:103B2000C02048000000000000000000D8C048008D -:103B3000000004E30000216900204411000000009F -:103B4000000000000020480200000000000000000B -:103B500000204803000000000000000800300A2296 -:103B60000000000000000000C0204800000000002D -:103B700000000000C0204800000000000000002DF0 -:103B80000020122D000000000000000000290C831E -:103B90000000000000002169002044110000000026 -:103BA00000000000002048020000000000000000AB -:103BB00000204803000000000000000800300A2236 -:103BC0000000000000000000C020480000000000CD -:103BD00000000000C02048000000000000000011AC -:103BE00000210224000000000000000014C00000BA -:103BF000000000000000000000400000000004AAD7 -:103C00000000002CC0203620000000000000002D25 -:103C1000C0403620000000000000000F00210221FB -:103C2000000000000000000014C0000000000505B6 -:103C300000000000006000000000000B0000000019 -:103C4000D90000000000000000000000C040040097 -:103C500000000001B5000000002044110000000039 -:103C6000000020000020481100000000B600000005 -:103C700000204411000000000000A00000204811B6 -:103C800000000000B7000000002044110000000008 -:103C90000000C0000020481100000000B800000033 -:103CA00000204411000000000000F8E0002048114E -:103CB00000000000B90000000020441100000000D6 -:103CC0000000F8800020481100000000BA00000049 -:103CD00000204411000000000000E0000020481116 -:103CE00000000000BB0000000020441100000000A4 -:103CF0000000F0000020481100000000BC0000009F -:103D000000204411000000000000F3FC00204811D6 -:103D100000000000810000000020441100000000AD -:103D2000000000020020481100000000000000FF19 -:103D300000280E300000000000000000002F0223C9 -:103D400000000000000000000CC000000000051989 -:103D500000000000C020080000000000000000007B -:103D600014C000000000052E0000000000200C110F -:103D7000000000000000001C0020362300000000AE -:103D80000000002B00203623000000000000002966 -:103D90000020362300000000000000280020362309 -:103DA0000000000000000017002036230000000083 -:103DB000000000250020362300000000000000263F -:103DC00000203623000000000000001500203623EC -:103DD0000000000000000016002036230000000054 -:103DE000FFFFE00000200C11000000000000002197 -:103DF00000203623000000000000002200203623AF -:103E00000000000000001FFF00200C110000000057 -:103E100000000023002036230000000000000024E2 -:103E20000020362300000000F1FFFFFF00283A2E9B -:103E3000000000000000001AC0220E200000000058 -:103E4000000000000029386E000000008100000022 -:103E5000002044110000000000000006002048116E -:103E6000000000000000002A402036200000000072 -:103E70008700000000204411000000000000000046 -:103E8000C0204800000000000000A1F40020441100 -:103E900000000000000000000020481000000000AA -:103EA0000000000000200C110000000000000030A5 -:103EB00000203623000000009D0000000020441177 -:103EC000000000000000001F40214A200000000008 -:103ED00096000000002044110000000000000000D7 -:103EE000C02048000000000000000000C0200C00BE -:103EF0000000000000000000C020100000000000D2 -:103F00000000001F00211624000000000000000037 -:103F100014C00000000000000000001D0020362337 -:103F2000000000000000000300281E230000000025 -:103F3000000000080022222300000000FFFFF00024 -:103F4000002822280000000000000000002920E8CE -:103F5000000000000000001F0020362800000000C4 -:103F60000000001800211E230000000000000020B7 -:103F70000020362700000000000000020022162466 -:103F80000000000000000000003014A80000000045 -:103F90000000001E00203625000000000000000385 -:103FA00000211A24000000001000000000281A263A -:103FB00000000000EFFFFFFF00283A2E0000000085 -:103FC00000000000004938CE0000067B0000000120 -:103FD00040280A20000000000000000640280E20B3 -:103FE0000000000000000300C028122000000000B4 -:103FF0000000000800211224000000000000000062 -:10400000C02016200000000000000000C0201A2080 -:10401000000000000000000000210222000000005B -:104020000000000014C000000000056681000000D0 -:104030000020441100000000000000010020481191 -:10404000000000000000225800300A240000000098 -:1040500000040000006946220000068D000021696E -:10406000002044110000000000000000002048056E -:10407000000000000002000000294A2600000000A5 -:10408000000000000020481000000000CAFEBABE78 -:10409000002048110000000000000002002F022351 -:1040A00000000000000000000CC000000000056ED1 -:1040B00000000000C0201C100000000000000000F4 -:1040C000C04000000000057C00000002002F022319 -:1040D00000000000000000000CC000000000056EA1 -:1040E00081000000002044110000000000000001D9 -:1040F00000204811000000000000225800300A246F -:104100000000000000040000006946220000068D47 -:1041100000000000C0201C10000000000000000093 -:10412000C04000000000057C00000000002F0223BA -:1041300000000000000000000CC00000000005723C -:1041400000000000C0201C00000000000000000073 -:10415000C04000000000057C00000004002F022386 -:1041600000000000000000000CC000000000057A04 -:104170008100000000204411000000000000000049 -:1041800000204811000000000000216D00204411B3 -:104190000000000000000000C020480000000000F7 -:1041A00000000000C060480000000692000000000F -:1041B00000401C100000057C00000000C020000032 -:1041C0000000000000000000C040000000000000EF -:1041D000000000000EE000000000057E000000006E -:1041E00000600000000005C900000000002F02244C -:1041F00000000000000000000CC000000000058F5F -:104200000000A2B7002044110000000000000000E0 -:104210000020480700000000810000000020441139 -:104220000000000000000001002048110000000014 -:104230000004A2B6006044110000068D0000001AC0 -:10424000002122300000000000000006002226307D -:104250000000000000042004006044110000068DEE -:104260000000A2C400204411000000000000000073 -:10427000003048E9000000000000000000E00000FD -:104280000000058D0000A2D10020441100000000B4 -:104290000000000000404808000000000000A2D11B -:1042A00000204411000000000000000100504A28D6 -:1042B0000000000000000001002F022400000000A8 -:1042C000000000000CC00000000005A00000A2BB20 -:1042D00000204411000000000000000000204807FA -:1042E00000000000810000000020441100000000D8 -:1042F0000000000100204811000000000004A2BAE4 -:10430000006044110000068D0000001A00212230D8 -:10431000000000000000000600222630000000001F -:1043200000042004006044110000068D0000A2C5B6 -:10433000002044110000000000000000003048E9A7 -:10434000000000000000000000E000000000059EEA -:104350000000A2D200204411000000000000000074 -:1043600000404808000000000000A2D200204411D4 -:10437000000000000000000100504A28000000007A -:1043800000000002002F02240000000000000000D6 -:104390000CC00000000005B10000A2BF00204411C5 -:1043A000000000000000000000204807000000009E -:1043B0008100000000204411000000000000000106 -:1043C00000204811000000000004A2BE006044115B -:1043D0000000068D0000001A0021223000000000BD -:1043E0000000000600222630000000000004200427 -:1043F000006044110000068D0000A2C60020441198 -:104400000000000000000000003048E9000000004B -:104410000000000000E00000000005AF0000A2D393 -:104420000020441100000000000000000040480887 -:10443000000000000000A2D3002044110000000092 -:104440000000000100504A28000000000000A2C344 -:104450000020441100000000000000000020480778 -:104460000000000081000000002044110000000056 -:104470000000000100204811000000000004A2C25A -:10448000006044110000068D0000001A0021223057 -:10449000000000000000000600222630000000009E -:1044A00000042004006044110000068D0000A2C733 -:1044B000002044110000000000000000003048E926 -:1044C000000000000000000000E00000000005BE49 -:1044D0000000A2D4002044110000000000000000F1 -:1044E00000404808000000000000A2D40020441151 -:1044F000000000000000000100504A2800000000F9 -:1045000085000000002044110000000000000000B1 -:1045100000204801000000000000304A0020441143 -:104520000000000001000000002048110000000011 -:104530000000000000400000000005C4A4000000CE -:10454000C02044110000000000000000C0404800EE -:104550000000000000000000C0600000000005C96D -:1045600000000000C0400400000000010000002C1A -:1045700000203621000000008100000000204411CE -:1045800000000000000000060020481100000000AC -:1045900000000000002F02300000000000000000BA -:1045A0000CC00000000005D0000000000020041135 -:1045B000000000000000003000403621000005E34C -:1045C000000000300020062D0000000000007E00EA -:1045D000002806210000000000000000002F02213A -:1045E00000000000000000000CE00000000005E3F7 -:1045F00081000000002044110000000000000001C4 -:1046000000204811000000000004A0920060441146 -:104610000000068D00000031002036300000000050 -:104620000004A093006044110000068D00000032D9 -:1046300000203630000000000004A2B600604411E3 -:104640000000068D0000003300203630000000001E -:104650000004A2BA006044110000068D000000347E -:1046600000203630000000000004A2BE00604411AB -:104670000000068D000000350020363000000000EC -:104680000004A2C2006044110000068D0000003644 -:1046900000203630000000000004200400604411B7 -:1046A0000000068D0001A2A40020441100000000BB -:1046B0000000003F00204811000000000000003F03 -:1046C00000204811000000000000003F00204811B9 -:1046D000000000000000003F002048110000000022 -:1046E0000000000500204811000000000000A1F4B7 -:1046F00000204411000000000000000000204811CC -:1047000000000000880000000020441100000000AC -:10471000000000010020481100000000810000009E -:104720000020441100000000000000060020481195 -:104730000000000000000001002F02300000000017 -:10474000000000000CE000000000062C000000301B -:104750000020062D0000000000000000002F0221B4 -:1047600000000000000000000CE000000000062C2B -:104770008100000000204411000000000000000142 -:10478000002048110000000000007E0000280621E3 -:104790000000000000000000002F022100000000C7 -:1047A000000000000CE00000000006050000A092E0 -:1047B00000204411000000000000003100204A2DBC -:1047C000000000000000A093002044110000000041 -:1047D0000000003200204A2D000000000000A2B6B8 -:1047E00000204411000000000000003300204A2D8A -:1047F000000000000000A2BA0020441100000000E8 -:104800000000003400204A2D000000000000A2BE7D -:1048100000204411000000000000003500204A2D57 -:10482000000000000000A2C20020441100000000AF -:104830000000003600204A2D00000000000000307B -:104840000020062D00000000000001FF00280621C6 -:104850000000000000000000002F02210000000006 -:10486000000000000CE000000000062B000000002B -:1048700000210221000000000000000014C0000020 -:104880000000060E0004A003006044110000068D25 -:104890000000A00300204411000000000000000000 -:1048A0000020481000000000000000010021062147 -:1048B000000000000000000014C00000000006130B -:1048C0000004A010006044110000068D0000A0103C -:1048D00000204411000000000000000000204810EB -:1048E000000000000000000100210621000000007F -:1048F00000000000002F0221000000000000000066 -:104900000CE000000000062B0004A0110060441120 -:104910000000068D0000A0110020441100000000DE -:104920000000000000204810000000000004A01259 -:10493000006044110000068D0000A0120020441108 -:1049400000000000000000000020481000000000EF -:104950000004A013006044110000068D0000A013A5 -:10496000002044110000000000000000002048105A -:10497000000000000004A014006044110000068D37 -:104980000000A014002044110000000000000000FE -:1049900000204810000000000004A0150060441131 -:1049A0000000068D0000A01500204411000000004A -:1049B0000000000000204810000000000004A016C5 -:1049C000006044110000068D0000A0160020441174 -:1049D000000000000000000000204810000000005F -:1049E0000004A017006044110000068D0000A0170D -:1049F00000204411000000000000000000204810CA -:104A00000000000000042004006044110000068D36 -:104A10000000002C0080062D00000000FF000000B8 -:104A20000020441100000000000000000020481198 -:104A300000000000000000010020481100000000FC -:104A4000000000020080481100000000000000008B -:104A50000EE000000000063D000000300020062DA2 -:104A600000000000000000020028062100000000F5 -:104A700000000000002F02210000000000000000E4 -:104A80000CE000000000063B810000000020441103 -:104A9000000000000000000100204811000000009C -:104AA00000042004006044110000068D0000100086 -:104AB00000200811000000000000002B002036221A -:104AC000000000000000000000600000000006413F -:104AD0000000000000600000000005C99800000010 -:104AE0000020441100000000000000000080481178 -:104AF0000000000000000000C0600000000006414F -:104B000000000000C0400400000000010000A2A45A -:104B10000020441100000000000000220020481185 -:104B20000000000089000000002044110000000087 -:104B300000000001004048110000062D9700000011 -:104B40000020441100000000000000000020481177 -:104B5000000000008A000000002044110000000056 -:104B600000000000004048110000062D0000000079 -:104B7000006000000000065C0000201000204411CE -:104B8000000000000000800000204811000000002C -:104B90000001A2A4C0204411000000000000001683 -:104BA000006048110000036E000020100020441136 -:104BB000000000000001000000204811000000007B -:104BC00081000000002044110000000000000001EE -:104BD00000204811000000000000217C002044114A -:104BE00000000000098000000020481100000000C3 -:104BF000FFFFFFFF00204811000000000000000040 -:104C00000020481100000000000000001700000014 -:104C1000000000000004217F006044110000068DA8 -:104C20000000001F00210230000000000000000012 -:104C300014C00000000000000000000400404C11FF -:104C400000000656000000000040000000000000C8 -:104C50000000001700201E2D0000000000000004CE -:104C600000291E27000000000000001700803627E2 -:104C7000000000000000001700201E2D00000000B2 -:104C8000FFFFFFFB00281E270000000000000017A8 -:104C900000803627000000000000001700201E2DB5 -:104CA000000000000000000800291E27000000008E -:104CB00000000017008036270000000000000017E9 -:104CC00000201E2D00000000FFFFFFF700281E2718 -:104CD00000000000000000170080362700000000E0 -:104CE000000020100020441100000000000080009F -:104CF00000204811000000000001A2A4002044117F -:104D00000000000000000016006048110000036E63 -:104D100000002010002044110000000000010000ED -:104D200000204811000000000000217C00204411F8 -:104D30000000000001800000002048110000000079 -:104D4000FFFFFFFF002048110000000000000000EE -:104D500000204811000000000000000017000000C3 -:104D6000000000008100000000204411000000004D -:104D70000000000100204811000000000004217F15 -:104D8000006044110000068D0000001F0021023069 -:104D9000000000000000000014C000000000068CAD -:104DA0000000001000404C110000067200000000DE -:104DB000C0200400000000000000000038C0000017 -:104DC000000000000000001D00200A2D000000006F -:104DD0000000001E00200E2D000000000000001F3B -:104DE0000020122D00000000000000200020162DE1 -:104DF00000000000000021690020441100000000B4 -:104E00000000000000204804000000000000000036 -:104E100000204805000000000000000000204801BC -:104E200000000000CAFEBABE0020481100000000C9 -:104E30000000000400301224000000000000000008 -:104E4000002F006400000000000000000CC0000003 -:104E50000000068B0000000300281A22000000005A -:104E6000000000080022122200000000FFFFF000F6 -:104E7000002812240000000000000000002910C4D7 -:104E8000000000000000001F004036240000000069 -:104E90000000000000800000000000000000000092 -:104EA0001AC000000000068D9F0000000020441181 -:104EB00000000000CAFEBABE002048110000000039 -:104EC000000000001AE00000000006900000000052 -:104ED0000080000000000000000000001AC0000078 -:104EE000000006929E000000002044110000000017 -:104EF000CAFEBABE002048110000000000000000F9 -:104F00001AE000000000069500000000008000008C -:104F10000000000000000000006000000000000B26 -:104F200000001000006004110000031500000000E4 -:104F300000200411000000000000000000600811C3 -:104F4000000001B20000225C0020441100000000BB -:104F5000000000030020481100000000000022565D -:104F600000204411000000000000001B0020481138 -:104F7000000000000000A1FC00204411000000001F -:104F80000000000100204811000000000001A1FD08 -:104F9000C0204411000000000000002100201E2D50 -:104FA000000000000000001000221E27000000008A -:104FB000000000240020222D000000000000FFFF60 -:104FC00000282228000000000000000000294907F6 -:104FD0000000000000000000002048110000000058 -:104FE000000000220020222D000000000000FFFF32 -:104FF00000282228000000000000000000294907C6 -:105000000000000000000000002048110000000027 -:105010000000002300201E2D0000000000000010F2 -:1050200000221E27000000000000000000294907A0 -:1050300000000000000000000040481100000000D7 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B0000142050205C002500000000001C3016860 -:1052C000043F05C000000000022502090250015100 -:1052D000000000000223024502A00241000000007D -:1052E00003D705C005C005C0000000000649064AF6 -:1052F000031F05C00000000005C005C503200340D2 -:1053000000000000032A0282034203340000000070 -:1053100005C005C005C005C00000000005C005515E -:1053200005C005C00000000003BA05C004BB03446B -:1053300000000000049A0450043D05C00000000075 -:1053400004D005C0044104DD00000000045005073E -:10535000035103750000000005C005C005C005C06D -:105360000000000005C005C005C005C00000000029 -:1053700005C005C0063F05C70000000005C005C008 -:10538000000705C00000000005C005C005C005C03D -:105390000000000005C005C005C005C000000000F9 -:1053A00003F803ED0408040600000000040E040ADC -:1053B000040C041000000000041C04180424042041 -:1053C00000000000042C0428043404300000000015 -:1053D00005C005C0043805C00000000005C005C0B8 -:1053E00005C005C00000000005C005C005C005C01F -:1053F0000000000000020679069700060000000089 -:00000001FF diff --git a/firmware/radeon/RV610_pfp.bin.ihex b/firmware/radeon/RV610_pfp.bin.ihex deleted file mode 100644 index f55292c97b7937d5da76127dbb21745b72d8039d..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV610_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000CA040000A00000007E828B007C038BED -:10001000008001B8007C038B00D4401E00EE001E5F -:1000200000CA040000A00000007E828B00C41838C3 -:1000300000CA240000CA2800009581A800C41C3A08 -:1000400000C3C00000CA080000CA0C00007C744B4A -:1000500000C200050099C00000C41C3A007C744C2A -:1000600000C0FFF000042C0400309002007D250049 -:1000700000351402007D350B00255403007CD5802B -:1000800000259C030095C00400D5001B007EDDC147 -:10009000007D9D8000D6801B00D5801B00D4401EB3 -:1000A00000D5401E00D6401E00D6801E00D4801E03 -:1000B00000D4C01E009783D300D5C01E00CA08001C -:1000C0000080001A00CA0C0000E4011E00D4001ECB -:1000D0000080000C00C4183800E4013E00D4001E6B -:1000E0000080000C00C4183800D4401E00EE001E32 -:1000F00000CA040000A00000007E828B00E4011E04 -:1001000000D4001E00D4401E00EE001E00CA0400F1 -:1001100000A00000007E828B00E4013E00D4001E9F -:1001200000D4401E00EE001E00CA040000A0000023 -:10013000007E828B00CA180000D4401E00D5801EAD -:100140000080005300D4007500D4401E00CA08008F -:1001500000CA0C0000CA100000D4801900D4C018D6 -:1001600000D5001700D4801E00D4C01E00D5001E8C -:1001700000E2001E00CA040000A00000007E828B86 -:1001800000CA080000D4806000D4401E0080000037 -:1001900000D4801E00CA080000D4806100D4401E34 -:1001A0000080000000D4801E00CA080000CA0C00B5 -:1001B00000D4401E00D4801600D4C01600D4801E87 -:1001C000008001B800D4C01E00C6084300CA0C005D -:1001D00000CA10000094800400CA140000E420F358 -:1001E00000D4201300D5606500D4E01C00D5201C8D -:1001F00000D5601C008000000006200100C60843F6 -:1002000000CA0C0000CA1000009483F700CA140052 -:1002100000E420F30080007900D4201300C60843D6 -:1002200000CA0C0000CA1000009883EF00CA140036 -:1002300000D400640080008D0000000000C414326F -:1002400000C6184300C4082F0095400500C40C30B8 -:1002500000D4401E0080000000EE001E009583F5D3 -:1002600000C4103100D4403300D5206500D4A01C58 -:1002700000D4E01C00D5201C00E4015E00D4001E68 -:10028000008000000006200100CA1800000A2001BA -:1002900000D6007600C408360098800700C61045D6 -:1002A0000095011000D4001F00D46062008000009F -:1002B00000D4206200CC383500CC1433008401BB5C -:1002C00000D4007200D5401E0080000000EE001E29 -:1002D00000E2001A008401BB00E2001A00CC104BBF -:1002E00000CC0447002C9401007D098B0098400548 -:1002F000007D15CB00D4001A008001B800D4006D39 -:100300000034440100CC0C480098403A00CC2C4A00 -:100310000095800400CC0449008001B800D4001A84 -:1003200000D4C01A00282801008400F000CC10037B -:100330000098801B0004380C008400F000CC1003EF -:100340000098801700043808008400F000CC1003E7 -:100350000098801300043804008400F000CC1003DF -:100360000098801400CC104C009A800900CC144DE9 -:10037000009840DC00D4006D00CC184800D5001A6D -:1003800000D5401A008000C900D5801A0096C0D55B -:1003900000D4006D008001B800D4006E009AC00344 -:1003A00000D4006D00D4006E0080000000EC007FDF -:1003B000009AC0CC00D4006D008001B800D4006E5B -:1003C00000CC140300CC180300CC1C03007D910367 -:1003D000007DD583007D190C0035CC1F0035701FC2 -:1003E000007CF0CB007CD08B00880000007E8E8BE0 -:1003F0000095C00400D4006E008001B800D4001A3B -:1004000000D4C01A00CC080300CC0C0300CC1003AD -:1004100000CC140300CC180300CC1C0300CC240334 -:1004200000CC28030035C41F0036B01F007C704B81 -:100430000034F01F007C704B0035701F007C704B47 -:10044000007D8881007DCCC1007E5101007E9541F8 -:10045000007C9082007CD4C2007C848B009AC00314 -:10046000007C8C8B002C88010098809E00D4006D4D -:100470000098409C00D4006E00CC084C00CC0C4D81 -:1004800000CC104800D4801A00D4C01A00800101AA -:1004900000D5001A00CC083200D40032009482D972 -:1004A00000CA0C0000D4401E0080000000D4001ED2 -:1004B00000E4011E00D4001E00CA080000CA0C009F -:1004C00000CA100000D4401E00CA140000D4801ED0 -:1004D00000D4C01E00D5001E00D5401E00D54034FB -:1004E0000080000000EE001E0028040400E2001A54 -:1004F00000E2001A00D4401A00CA380000CC0803F9 -:1005000000CC0C0300CC0C0300CC0C03009882BD83 -:1005100000000000008401BB00D7A06F0080000035 -:1005200000EE001F00CA040000C2FF0000CC083427 -:1005300000C13FFF007C74CB007CC90B007D010F24 -:10054000009902B0007C738B008401BB00D7A06FC0 -:100550000080000000EE001F00CA080000281900FB -:10056000007D898B009580140028140400CA0C00BB -:1005700000CA100000CA1C0000CA240000E2001FCC -:1005800000D4C01A00D5001A00D5401A00CC1803B8 -:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -:1005A000007D9C4700984297000000000080016198 -:1005B00000D4C01A00D4401E00D4801E0080000069 -:1005C00000EE001E00E4011E00D4001E00D4401EF8 -:1005D00000EE001E00CA040000A00000007E828B16 -:1005E00000E4013E00D4001E00D4401E00EE001EB8 -:1005F00000CA040000A00000007E828B00CA080030 -:1006000000248C06000CCC060098C00600CC104ECE -:100610000099000400D4007300E4011E00D4001E01 -:1006200000D4401E00D4801E0080000000EE001E9A -:1006300000CA080000CA0C000034D01800251001C0 -:100640000095002100C17FFF00CA100000CA1400FD -:1006500000CA180000D4801D00D4C01D007DB18BDD -:1006600000C1420200C2C00100D5801D0034DC0E72 -:10067000007D5D4C007F734C00D7401E00D5001EEE -:1006800000D5401E00C1420000C2C00000099C010C -:100690000031DC10007F5F4C007F734C00042802A7 -:1006A000007D838000D5A86F00D5806600D7401EEE -:1006B00000EC005E00C8240200C82402008001B8DB -:1006C00000D6007600D4401E00D4801E00D4C01E88 -:1006D0000080000000EE001E0080000000EE001F01 -:1006E00000D4001F0080000000D4001F00D4001FB1 -:1006F0000088000000D4001F00000000000000007F -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000010171000201780003008F0004007FE5 -:10081000000500030006003F000700320008012C1D -:1008200000090046000A0036001001B6001700A2B9 -:100830000022013A00230149002000B400240125D0 -:100840000027004D0028006A002A0060002B00529B -:10085000002F0065003200870034017F003C015604 -:10086000003F00720041018C0044012E00550173CD -:100870000056017A0060000B00610034006200380D -:1008800000630038006400380065003800660038F6 -:10089000006700380068003A00690041006A0048BB -:1008A000006B0048006C0048006D0048006E004876 -:1008B000006F00480000000600000006000000066F -:1008C0000000000600000006000000060000000610 -:1008D0000000000600000006000000060000000600 -:1008E00000000006000000060000000600000006F0 -:1008F00000000006000000060000000600000006E0 -:00000001FF diff --git a/firmware/radeon/RV620_me.bin.ihex b/firmware/radeon/RV620_me.bin.ihex deleted file mode 100644 index ba19ed8929207bfa1d2daaf8d7d480dc197e550b..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV620_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A000006044110000068D0000000000600000A8 -:1000B000000006310000000000600000000006455E -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E000000000000000001800203625000000007D -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000002800204A2D8B -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000001900203625C9 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001700200E2D5A -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001718 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000270020362410 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:10038000000000000000000E0020362300000000E6 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E23000000000000000FC9 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000002700204A2D000000004F -:1003F000000000000020481100000000000000295B -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A00000000000002048040000000000000030AF -:1005B0000020162D00000000000000020029162572 -:1005C0000000000000000030002036250000000080 -:1005D000000000250020162D000000000000000093 -:1005E000002F00A300000000000000000CC000006D -:1005F00000000083000000260020162D00000000EF -:1006000000000000002F00A4000000000000000017 -:100610000CC000000000008400000000004000004A -:100620000000008A000000250020362300000000A2 -:100630000000002600203624000000000000001703 -:1006400000201E2D000000000000000200210227F3 -:10065000000000000000000014E000000000008A1C -:1006600000000000006000000000066800000000BC -:10067000006000000000065C0000000200210E2265 -:10068000000000000000000014C000000000008D09 -:1006900000000012C040362000000093000000005F -:1006A0002EE0000000000091000000002CE000009F -:1006B000000000900000000200400E2D000000929B -:1006C0000000000300400E2D000000920000000C0E -:1006D00000200E2D00000000000000120020362334 -:1006E000000000000000000300210E2200000000B6 -:1006F0000000000014C00000000000980000A00CE2 -:10070000002044110000000000000000C02048004C -:100710000000000000000000C0404800000000A0F1 -:100720000000A00C002044110000000000000000A8 -:100730000020481100000000000000002EE0000032 -:100740000000009E000000002CE000000000009D62 -:100750000000000200400E2D0000009F000000037A -:1007600000400E2D0000009F0000000C00200E2D08 -:10077000000000000000000000204803000000000E -:1007800000000000003A0C0200000000003F0000E2 -:1007900000280E23000000000000001000210E239E -:1007A00000000000000000110020362300000000BF -:1007B0000000001E0021022B0000000000000000CD -:1007C00014C00000000000A700000016C020362062 -:1007D000000000000000001F0021022B00000000AC -:1007E0000000000014C00000000000AA0000001576 -:1007F000C0203620000000000000000800210E2B61 -:10080000000000000000007F00280E230000000010 -:1008100000000000002F0223000000000000000084 -:100820000CE00000000000E10000000027000000D4 -:10083000000000000000000000600000000002A3B3 -:1008400000000001002F0223000000000000000053 -:100850000AE00000000000B300000000006000009B -:100860000000013A81000000002044110000000057 -:100870000000000600204811000000000000000CED -:1008800000221E300000000099800000002044116A -:1008900000000000000000040020122D00000000F5 -:1008A00000000008002212240000000000000010D8 -:1008B00000201811000000000000000000291CE4C6 -:1008C0000000000000000000006048070000012F49 -:1008D0009B00000000204411000000000000000008 -:1008E00000204802000000009C000000002044118D -:1008F00000000000000000000033146F0000000042 -:100900000000000100333E23000000000000000052 -:10091000D9004800000000000000000000203C0555 -:1009200000000000810000000020441100000000D1 -:100930000000000E00204811000000000000000030 -:1009400000201010000000000000E007002044110B -:10095000000000000000000F0021022B000000003A -:100960000000000014C00000000000CB00F8FF08E9 -:1009700000204811000000009800000000404811CD -:10098000000000DC000000F000280E220000000043 -:10099000000000A0002F0223000000000000000063 -:1009A0000CC00000000000DA0000001100200E2D35 -:1009B0000000000000000001002F022300000000E2 -:1009C000000000000CE00000000000D50000000264 -:1009D000002F022300000000000000000CE00000D7 -:1009E000000000D400003F0000400C11000000D6C1 -:1009F00000001F0000400C11000000D600000F0096 -:100A000000200C11000000000038000900294A23D2 -:100A1000000000003F00000000280E2B0000000036 -:100A20000000000200220E2300000000000000076A -:100A300000494A23000000DC00380F09002048115B -:100A400000000000680000070020481100000000BE -:100A50000000000800214A270000000000000000FC -:100A60000020481100000000060A020000294A2464 -:100A700000000000000000000020481100000000FD -:100A80000000000000204811000000000000A20249 -:100A9000002044110000000000FF000000280E228A -:100AA000000000000000008000294A230000000030 -:100AB0000000002700200E2D00000000000000268E -:100AC0000020122D0000000000000000002F008315 -:100AD00000000000000000000CE00000000000EA40 -:100AE000000000000060000000000662000000003E -:100AF00000400000000000EB00000000006000006B -:100B000000000665000000070020222D0000000004 -:100B10000000000500220E2200000000001000006E -:100B200000280E23000000000000000000292068BB -:100B30000000000000000000003A0C02000000006D -:100B4000000000EF00280E2300000000000000005D -:100B500000292068000000000000001700200E2D72 -:100B6000000000000000000300210223000000003C -:100B70000000000014E00000000000F80000000B7E -:100B800000210228000000000000000014C0000046 -:100B9000000000F8000004000029222800000000E6 -:100BA0000000001400203628000000000000001C97 -:100BB00000210E22000000000000000014C0000010 -:100BC000000000FD0000A30C002044110000000004 -:100BD0000000000000204811000000000000001E7E -:100BE00000210E22000000000000000014C00000E0 -:100BF0000000010B0000A30F0020441100000000C2 -:100C00000000001100200E2D000000000000000177 -:100C1000002F022300000000000000000CC00000B4 -:100C200000000104FFFFFFFF004048110000010B1E -:100C300000000002002F022300000000000000005E -:100C40000CC00000000001070000FFFF0040481139 -:100C50000000010B00000004002F02230000000030 -:100C6000000000000CC000000000010A000000FFAE -:100C7000004048110000010B000000010020481155 -:100C8000000000000002C400002044110000000029 -:100C90000000001F00210E220000000000000000E4 -:100CA00014C00000000001120000001040210E20BE -:100CB00000000000000000130020362300000000A8 -:100CC0000000001840224A20000000000000001030 -:100CD000C0424A20000001140000000000200C1156 -:100CE0000000000000000013002036230000000078 -:100CF000000000000020481100000000000000007B -:100D000000204811000000000000000A002010111F -:100D10000000000000000000002F0224000000007E -:100D2000000000000CE000000000011B00000000BB -:100D300000204811000000000000000100531224B0 -:100D400000000117FFBFFFFF00283A2E000000003F -:100D50000000001B00210222000000000000000033 -:100D600014C000000000012E81000000002044118A -:100D7000000000000000000D0020481100000000ED -:100D80000000001800220E3000000000FC000000EF -:100D900000280E2300000000810000000020441104 -:100DA000000000000000000E0020481100000000BC -:100DB0000000000000201010000000000000E00E05 -:100DC000002044110000000007F8FF08002048112F -:100DD000000000000000000000294A23000000007D -:100DE0000000001C00201E2D000000000000000874 -:100DF00000214A27000000000000000000204811E8 -:100E000000000000060A020000294A240000000039 -:100E10000000000000204811000000000000000059 -:100E200000204811000000000000000000800000C9 -:100E300000000000810000000020441100000000BC -:100E40000000000100204811000000000000217C8B -:100E50000020441100000000008000000020481124 -:100E60000000000000000000002048060000000014 -:100E70000000000800214A270000000000000000D8 -:100E800017000000000000000004217F00604411F2 -:100E90000000068D0000001F00210230000000004D -:100EA0000000000014C000000000068C00000004D8 -:100EB00000404C1100000135810000000020441169 -:100EC00000000000000000010020481100000000A8 -:100ED000000021F800204411000000000000001C68 -:100EE0000020481100000000000421F900604411B6 -:100EF0000000068D000000110021023000000000FB -:100F00000000000014E000000000013C00000000B0 -:100F100000800000000000000000000000600000F1 -:100F20000000000B00000000006004110000031529 -:100F3000000000000020041100000000000000007C -:100F400000600811000001B2000000000060000015 -:100F5000000001600000FFFF40280E20000000009C -:100F600000000010C0211220000000000000FFFF60 -:100F7000402806200000000000000010C0210A20C8 -:100F800000000000000000000034146100000000B8 -:100F90000000000000741882000002BB0001A1FDE7 -:100FA00000604411000002E000003FFF002F022F0C -:100FB00000000000000000000CC00000000001471D -:100FC00000000000C040040000000001000000001C -:100FD000006000000000000B000000000060041131 -:100FE00000000315000000000020041100000000B4 -:100FF0000000000000600811000001B200003FFF87 -:10100000002F022F00000000000000000CE0000094 -:10101000000000000000000000600000000001600F -:101020000000001040210E20000000000000FFFF23 -:10103000C0281220000000000000001040211620EF -:10104000000000000000FFFFC0681A20000002BB83 -:101050000001A1FD00604411000002E000003FFF1C -:10106000002F022F00000000000000000CC0000054 -:101070000000015800000000C04004000000000112 -:101080000000225C0020441100000000000000016C -:1010900000300A2F000000000000000100210A2299 -:1010A000000000000000000300384A220000000099 -:1010B0000000225600204411000000000000001A29 -:1010C00000204811000000000000A1FC0020441195 -:1010D0000000000000000001008048110000000036 -:1010E00000000000006000000000000B0000000095 -:1010F000006000000000018F0000000000600000A0 -:10110000000001A000003FFF002F022F00000000A0 -:10111000000000000CE000000000000000000000E3 -:1011200000202C0800000000000000000020241116 -:101130000000000000000000002028110000000056 -:10114000000022560020441100000000000000169C -:1011500000204811000000000000225C0020441123 -:101160000000000000000003002048110000000003 -:1011700093800000002044110000000000000002E5 -:1011800000221E290000000000000000007048EB53 -:101190000000019C0000000000600000000002BB95 -:1011A00000000001403306200000000000000000A5 -:1011B000C03024090000000000003FFF002F022F74 -:1011C00000000000000000000CE000000000000033 -:1011D0000000000000600000000002A3000000000A -:1011E000002F022100000000000000000AE00000C3 -:1011F0000000018100000000006000000000013AD2 -:101200000000000000400000000001869500000082 -:10121000002044110000000000000000002F022107 -:1012200000000000000000000CE00000000001864B -:1012300000000000C0204800000000000000000185 -:10124000005306210000018292000000002044119A -:101250000000000000000000C0604800000001978E -:101260000001A1FD00204411000000000000001159 -:101270000020062D00000000000000000078042A75 -:10128000000002FB00000000002028090000000010 -:1012900000003FFF002F022F0000000000000000B0 -:1012A0000CC000000000017400000000C0400400F9 -:1012B000000000010000021000600411000003158E -:1012C00000003FFF002F022F000000000000000080 -:1012D0000CE000000000019400000015C020362042 -:1012E0000000000000000016C020362000000000B2 -:1012F0003F800000002004110000000046000000B4 -:1013000000600811000001B2000000000080000031 -:10131000000000000000A1FC0020441100000000BB -:1013200000003FFF002F022F00000000000000001F -:101330000CC000000000019B00000001008048116B -:1013400000000000000000210080481100000000A3 -:101350000000FFFF40280E200000000000000010E9 -:10136000C0211220000000000000FFFF40281620CE -:101370000000000000000010C0811A2000000000E2 -:101380008100000000204411000000000000000661 -:1013900000204811000000000000000800221E305C -:1013A000000000000000002900201A2D00000000AD -:1013B0000000E0000020441100000000FFFBFF09D6 -:1013C00000204811000000000000000F0020222D26 -:1013D0000000000000001FFF00294A280000000054 -:1013E000000000060020222D000000000000000088 -:1013F000002920E80000000000000000002048084C -:101400000000000000000000002048110000000063 -:10141000060A020000294A26000000000000000021 -:1014200000204811000000000000000000204811CA -:101430000000000000000100002018110000000062 -:101440000000000800621E280000012F00000008B4 -:1014500000822228000000000002C0000020441189 -:10146000000000000000001500600E2D000001BD0E -:101470000000001600600E2D000001BD0000C00835 -:1014800000204411000000000000001700200E2D75 -:10149000000000000000000014C00000000001B9BE -:1014A0000000000000200411000000000000000007 -:1014B0000020480100000000390000000020481111 -:1014C00000000000000000000020481100000000A3 -:1014D000000000000080480200000000000000182A -:1014E00000202E2D0000000000000000003B0D63D6 -:1014F000000000000000000800224A230000000055 -:101500000000001000224A23000000000000001824 -:1015100000224A2300000000000000000080480371 -:101520000000000000000000006000000000000B50 -:10153000000010000060041100000315000000000E -:1015400000200411000000000000000000600811ED -:10155000000001B2000000070021062F000000007B -:101560000000001300200A2D000000000000000110 -:1015700000202C11000000000000FFFF4028222066 -:10158000000000000000000F0026222800000000DC -:101590000000001040212620000000000000000F85 -:1015A000002626290000000000000000002028027C -:1015B000000000000000225600204411000000003E -:1015C0000000001B00204811000000000000000087 -:1015D000002F022100000000000000000CE00000CD -:1015E000000001E00000225C002044110000000027 -:1015F0000000008100204811000000000000A1FC54 -:1016000000204411000000000000000100204811EB -:10161000000000000000008000201C1100000000FD -:1016200000000000002F0227000000000000000062 -:101630000CE00000000001DC000000000060000081 -:10164000000001E90000000100531E27000001D83E -:101650000000000100202C11000000000000001F0D -:1016600000280A22000000000000001F00282A2A8B -:10167000000000000000000100530621000001D11D -:101680000000225C00204411000000000000000265 -:1016900000304A2F000000000000A1FC002044118F -:1016A00000000000000000010020481100000000C0 -:1016B0000000000100301E2F0000000000000000AC -:1016C000002F022700000000000000000CE00000D6 -:1016D000000000000000000000600000000001E9C0 -:1016E0000000000100531E27000001E50000FFFF7D -:1016F00040280E20000000000000000F00260E23EE -:101700000000000000000010C021122000000000B6 -:101710000000000F0026122400000000000000005E -:1017200000201411000000000000000000601811EB -:10173000000002BB0001A1FD0020441100000000D8 -:1017400000000000002F022B00000000000000003D -:101750000CE00000000001F8000000100022162834 -:1017600000000000FFFF0000002816250000000018 -:101770000000FFFF00281A29000000000000000000 -:10178000002948C500000000000000000020480AB1 -:10179000000000000000000000202C1100000000EC -:1017A000000000100022162300000000FFFF0000D0 -:1017B00000281625000000000000FFFF00281A2462 -:1017C0000000000000000000002948C500000000E3 -:1017D0000000000000731503000002050000000077 -:1017E0000020180500000000000000000073152410 -:1017F0000000020500000000002D14C500000000DC -:1018000000000000003008A20000000000000000FE -:101810000020480200000000000000000020280214 -:101820000000000000000000002020030000000075 -:101830000000000000802404000000000000000FF1 -:1018400000210225000000000000000014C000007C -:101850000000068C00000000002B140500000000B2 -:1018600000000001009016250000000000000000AC -:10187000006000000000000B000000000060041188 -:10188000000003150000000000200411000000000B -:101890000000000000600811000001B200002256A4 -:1018A00000204411000000000000001A00294A2214 -:1018B0000000000000000000C02000000000000048 -:1018C00000003FFF002F022F00000000000000007A -:1018D0000CE000000000000000000000C020040038 -:1018E000000000000000225C002044110000000005 -:1018F0000000000300384A21000000000000A1FCA5 -:1019000000204411000000000000000100204811E8 -:10191000000000000000FFFF40281220000000002F -:1019200000000010C0211A20000000000000FFFF8E -:1019300040280E200000000000000010C0211620EA -:10194000000000000000000000741465000002BBED -:101950000001A1FD00604411000002E00000000150 -:10196000003306210000000000000000002F0221CB -:1019700000000000000000000CC000000000021980 -:1019800000003FFF002F022F0000000000000000B9 -:101990000CC000000000021200000000C040040063 -:1019A000000000010000000000600000000006458B -:1019B000000000000040040F0000021300000000BF -:1019C0000060000000000631000000000060000020 -:1019D000000006450000021000600411000003151D -:1019E0000000000000600000000001A000000000F6 -:1019F000006000000000019C00000000006000008A -:101A0000000002BB0000000000600000000002A314 -:101A1000938000000020441100000000000000003E -:101A2000002048080000000000000000002F022FE6 -:101A300000000000000000000AE000000000023288 -:101A400000000000006000000000013A00000000FB -:101A50000040000000000236950000000020441104 -:101A60000000000000000000002F022F0000000016 -:101A7000000000000CE00000000002360000000042 -:101A8000C0404800000002339200000000204411D2 -:101A90000000000000000000C0204800000000001E -:101AA0000000225600204411000000000000001633 -:101AB00000204811000000000000225C00204411BA -:101AC000000000000000000300204811000000009A -:101AD0000000A1FC002044110000000000000001F3 -:101AE00000204811000000000001A1FD0020441169 -:101AF000000000000000000000600411000002FB74 -:101B000000000000C04004000000000100000000D0 -:101B100000600000000006310000A00C002044110D -:101B20000000000000000000C0204800000000008D -:101B300000000000C040480000000000000000005D -:101B4000006000000000000B0000001840210A2087 -:101B50000000000000000003002F0222000000002F -:101B6000000000000AE000000000024C0000001429 -:101B70000020222D00000000000801010029222879 -:101B800000000000000000140020362800000000C3 -:101B90000000A30C00204411000000000000000021 -:101BA000C02048000000000000000000C0204800E5 -:101BB0000000000000000000C0404800000002518A -:101BC00000000000006000000000000B000000109A -:101BD00000600411000003153F8000000020041184 -:101BE000000000000000000000600811000001B2C9 -:101BF0000000225C002044110000000000000003EF -:101C000000204811000000000000000000600000FB -:101C10000000027C0000001700201E2D00000000C4 -:101C20000000000100211E2700000000000000004D -:101C300014E000000000026A0000001200201E2DC7 -:101C4000000000000000FFFF00281E270000000029 -:101C50000000000000341C2700000000000000000D -:101C600012C000000000025F0000000000201C11F4 -:101C70000000000000000000002F00E50000000050 -:101C80000000000008C00000000002620000000028 -:101C900000201407000000000000001200201E2D8C -:101CA000000000000000001000211E2700000000BE -:101CB0000000000000341C4700000000000000008D -:101CC00012C00000000002670000000000201C118C -:101CD0000000000000000000002F00E600000000EF -:101CE0000000000008C000000000026A00000000C0 -:101CF0000020180700000000000000000060000045 -:101D0000000002C100002256002044110000000023 -:101D1000000000000034202300000000000000004C -:101D200012C00000000002720000000000342044D5 -:101D3000000000000000000012C00000000002715E -:101D40000000001600404811000002760000001854 -:101D500000404811000002760000000000342044DA -:101D6000000000000000000012C00000000002752A -:101D70000000001700404811000002760000001922 -:101D800000204811000000000000A1FC00204411C8 -:101D900000000000000000010020481100000000C9 -:101DA0000001A1FD00604411000002E900003FFFB6 -:101DB000002F022F00000000000000000CC00000F7 -:101DC0000000025600000000C040040000000001B6 -:101DD0000000001040210620000000000000FFFF6E -:101DE000C0280A20000000000000001040210E2042 -:101DF000000000000000FFFFC028122000000000CB -:101E00000000001040211620000000000000FFFF2D -:101E1000C0881A200000000081000000002044114A -:101E20000000000000000001002048110000000038 -:101E300000042004006044110000068D0000000032 -:101E4000006000000000063100000000C0600000DB -:101E5000000002A30000000500200A2D0000000081 -:101E60000000000800220A22000000000000002BF1 -:101E700000201A2D000000000000001C00201E2D74 -:101E8000000000000000700000281E270000000075 -:101E90000000000000311CE6000000000000002AE5 -:101EA00000201A2D000000000000000C00221A265D -:101EB0000000000000000000002F00E6000000000D -:101EC0000000000006E00000000002920000000098 -:101ED00000201C11000000000000000000200C1178 -:101EE000000000000000002B00203623000000004E -:101EF0000000001000201811000000000000000089 -:101F000000691CE20000012F9380000000204411B2 -:101F10000000000000000000002048070000000052 -:101F200095000000002044110000000000000000A7 -:101F3000002F022F00000000000000000CE0000055 -:101F40000000029D0000000100333E2F0000000051 -:101F500000000000D90048000000000092000000CE -:101F6000002044110000000000000000C0204800D4 -:101F7000000000000000001C0040362700000000A8 -:101F80000000000CC0220A20000000000000002910 -:101F9000002036220000000000000028C04036204B -:101FA000000000000000A2A4002044110000000076 -:101FB000000000090020481100000000A1000000FE -:101FC00000204411000000000000000100804811C2 -:101FD000000000000000002100201E2D0000000075 -:101FE00000000000002C1CE30000000000000021A5 -:101FF00000203627000000000000002200201E2DD7 -:102000000000000000000000002C1CE400000000A4 -:1020100000000022002036270000000000000023FE -:1020200000201E2D0000000000000000003120A351 -:102030000000000000000000002D1D07000000004F -:1020400000000023002036270000000000000024CC -:1020500000201E2D0000000000000000003120C400 -:102060000000000000000000002D1D07000000001F -:10207000000000240080362700000000000000213E -:10208000002036230000000000000022002036243B -:10209000000000000000000000311CA30000000050 -:1020A0000000002300203627000000000000000090 -:1020B00000311CC40000000000000024008036270E -:1020C000000000000000001A002036270000000079 -:1020D0000000001B00203628000000000000001750 -:1020E00000201E2D00000000000000020021022739 -:1020F000000000000000000014C00000000002DC2E -:102100000000000000400000000002D90000001A9A -:1021100000203627000000000000001B00203628A9 -:10212000000000000000001700201E2D000000002D -:102130000000000200210227000000000000000053 -:1021400014E00000000002D9000000030021022773 -:10215000000000000000000014E00000000002DCAD -:102160000000002300201E2D0000000000000000E1 -:10217000002E00E1000000000000000002C000008E -:10218000000002DC0000002100201E2D00000000E5 -:1021900000000000003120A100000000000000004D -:1021A000002E00E8000000000000000006C0000053 -:1021B000000002DC0000002400201E2D00000000B2 -:1021C00000000000002E00E20000000000000000FF -:1021D00002C00000000002DC0000002200201E2DD2 -:1021E0000000000000000000003120C200000000DC -:1021F00000000000002E00E80000000000000000C9 -:1022000006C00000000002DC0000000000600000CA -:10221000000006680000000000600000000002B539 -:102220000000000000400000000002DE000000008E -:1022300000600000000002B5000000000060000027 -:102240000000065F0000000000400000000002DE09 -:102250000000000000600000000002A70000000075 -:1022600000400000000002DE0000001A00201E2DC9 -:10227000000000000000001B0080222D0000000074 -:102280000000001000221E230000000000000000DB -:1022900000294887000000000000000000311CA356 -:1022A000000000000000001000221E2700000000B7 -:1022B0000000000000294887000000000000001016 -:1022C00000221E230000000000000000003120C496 -:1022D000000000000000FFFF00282228000000008E -:1022E0000000000000894907000000000000001005 -:1022F00000221E2300000000000000000029488783 -:10230000000000000000001000221E21000000005C -:102310000000000000294847000000000000000005 -:1023200000311CA3000000000000001000221E2746 -:1023300000000000000000000029488700000000A5 -:102340000000000000311CA100000000000000108F -:1023500000221E270000000000000000002948475E -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:10239000000000000000001000221E2100000000CC -:1023A00000000000003120C2000000000000FFFF1C -:1023B00000282228000000000000000000894907D2 -:1023C000000000000000001000221E23000000009A -:1023D0000000000000294887000000000000000104 -:1023E00000220A210000000000000000003308A2C3 -:1023F000000000000000001000221E22000000006B -:102400000000001000212222000000000000000057 -:1024100000294907000000000000000000311CA353 -:10242000000000000000001000221E270000000035 -:1024300000000000002948870000000000000001A3 -:1024400000220A210000000000000000003008A265 -:10245000000000000000001000221E22000000000A -:1024600000000010002122220000000000000000F7 -:1024700000294907000000000000001000221E2370 -:102480000000000000000000003120C40000000037 -:102490000000FFFF002822280000000000000000CC -:1024A000002949070000000000000000003808C5AE -:1024B00000000000000000000030084100000000A3 -:1024C0000000000100220A220000000000000000BD -:1024D000003308A2000000000000001000221E22AD -:1024E0000000000000000010002122220000000077 -:1024F00000000000008949070000000000000017EC -:102500000020222D000000000000000014C0000088 -:1025100000000318FFFFFFEF002806210000000065 -:10252000000000140020222D000000000000F8E050 -:1025300000204411000000000000000000294901B3 -:1025400000000000000000000089490100000000B8 -:102550000000000000204811000000000000000002 -:102560000020481100000000060A02000080481107 -:102570000000000000000000C0200000000000007B -:1025800097000000C020441100000000000000007F -:10259000C0204811000000008A0000000020441103 -:1025A00000000000000000000020481100000000B2 -:1025B0000000225C00204411000000000000000028 -:1025C000C0204800000000000000A1FC00204411D1 -:1025D0000000000000000000C020480000000000D3 -:1025E00000000000C0200400000000000000000007 -:1025F00000A0000A00000000970000000020441125 -:102600000000000000000000002048110000000051 -:102610008A000000002044110000000000000000BB -:1026200000204811000000000000225C002044113E -:102630000000000000000000C02048000000000072 -:102640000000A1FC00204411000000000000000078 -:10265000C02048000000000000000000C02004006E -:10266000000000000000000000A0000A00000000C0 -:10267000970000000020441100000000000000004E -:1026800000204811000000008A00000000204411D2 -:1026900000000000000000000020481100000000C1 -:1026A0000000225C00204411000000000000000037 -:1026B000C0204800000000000000A1FC00204411E0 -:1026C0000000000000000000C020480000000000E2 -:1026D0000001A1FD002044110000000000000000E6 -:1026E000D90048000000000000000000C0200400E5 -:1026F000000000000000000000A0000A0000000030 -:1027000000002257002044110000000000000003D8 -:10271000C0484A20000000000000225D0020441153 -:102720000000000000000000C04048000000000061 -:1027300000000000006000000000064500000000EE -:10274000C0200800000000000000225C00204411AE -:10275000000000000000000300384A2200000000D2 -:102760000000A1FC00204411000000000000000057 -:10277000C0204800000000000001A1FD002044111D -:102780000000000000000000002F022200000000F6 -:10279000000000000CE0000000000000000000004D -:1027A00040204800000000000000000140304A20A6 -:1027B0000000000000000002C0304A2000000000BD -:1027C0000000000100530A220000034B0000003FFC -:1027D000C0280A20000000008100000000204411F1 -:1027E000000000000000000100204811000000006F -:1027F000000021F800204411000000000000001833 -:102800000020481100000000000421F9006044117C -:102810000000068D000000110021023000000000C1 -:102820000000000014E00000000003540000001449 -:10283000002F022200000000000000000CC0000079 -:10284000000003640000201000204411000000007C -:102850000000800000204811000000000001A2A438 -:102860000020441100000000000000000060480249 -:102870000000036E00002100002044110000000051 -:1028800000000000C0204800000000000000000020 -:10289000C02048000000000000000000C0204800E8 -:1028A0000000000000000000C040480000000000E0 -:1028B00000000004002F02220000000000000000C1 -:1028C0000CC000000000036A00002010002044112A -:1028D00000000000000080000020481100000000FF -:1028E0000001A2A40020441100000000000000002C -:1028F000004048020000035F00000028002F022271 -:1029000000000000000000000CC00000000005C036 -:102910000001A2A4002044110000000000000000FB -:10292000004048020000035F0000002C0020362613 -:102930000000000000000049002018110000000005 -:102940000000003F002048110000000000000001CE -:1029500000331A260000000000000000002F0226AD -:1029600000000000000000000CC000000000037028 -:102970000000002C00801A2D000000000000003F25 -:10298000C0280A200000000000000015002F0222CD -:1029900000000000000000000CE0000000000386C2 -:1029A00000000006002F02220000000000000000CE -:1029B0000CE00000000003B100000016002F02220E -:1029C00000000000000000000CE00000000003B563 -:1029D00000000020002F0222000000000000000084 -:1029E0000CE000000000039C0000000F002F0222FA -:1029F00000000000000000000CE00000000003A840 -:102A000000000010002F0222000000000000000063 -:102A10000CE00000000003A80000001E002F0222AE -:102A200000000000000000000CE000000000039027 -:102A30000000A2A4002044110000000000000000DB -:102A400000404802000000000800000000290A229F -:102A5000000000000000000340210E2000000000E4 -:102A60000000000CC021122000000000000800003F -:102A7000002812240000000000000014C0221620CC -:102A80000000000000000000002914A40000000065 -:102A90000000A2A40020441100000000000000007B -:102AA000002948A2000000000000A1FE00204411FF -:102AB000000000000000000000404803000000008B -:102AC000810000000020441100000000000000010F -:102AD0000020481100000000000021F800204411EF -:102AE0000000000000000016002048110000000057 -:102AF000000421F9006044110000068D000000155B -:102B000000210230000000000000000014E000007E -:102B1000000003920000210E00204411000000007C -:102B200000000000C020480000000000000000007D -:102B3000C0204800000000000000A2A400204411B2 -:102B400000000000000000000040480200000000FB -:102B5000810000000020441100000000000000017E -:102B60000020481100000000000021F8002044115E -:102B700000000000000000170020481100000000C5 -:102B8000000421F9006044110000068D00000003DC -:102B900000210230000000000000000014E00000EE -:102BA0000000039E000021080020441100000000E6 -:102BB00000000000C02048000000000000000000ED -:102BC000C0204800000000000000A2A40020441122 -:102BD000000000000000000000404802000000006B -:102BE0000000A2A40020441100000000000000002A -:102BF0000020480200000000800000000020441176 -:102C0000000000000000000000204811000000004B -:102C100081000000002044110000000000000010AE -:102C200000204811000000000000000000200010FB -:102C3000000000000000000014C00000000003AE0F -:102C40000000000000400000000000000000201014 -:102C50000020441100000000000080000020481106 -:102C6000000000000001A2A40020441100000000A8 -:102C70000000000600404811000000000000201085 -:102C800000204411000000000000800000204811D6 -:102C9000000000000001A2A4002044110000000078 -:102CA00000000016006048110000036E00000000E4 -:102CB000004000000000000000000000C0200800EC -:102CC0000000000000000000C0200C000000000018 -:102CD0000000001D00210223000000000000000091 -:102CE00014E00000000003CE810000000020441129 -:102CF000000000000000000100204811000000005A -:102D0000000021F80020441100000000000000181D -:102D10000020481100000000000421F90060441167 -:102D20000000068D000000110021023000000000AC -:102D30000000000014E00000000003C000002100BB -:102D400000204411000000000000000000204802A4 -:102D50000000000000000000002048030000000008 -:102D6000BABECAFE0020481100000000CAFEBABE6A -:102D70000020481100000000000020100020441135 -:102D8000000000000000800000204811000000004A -:102D90000000A2A400204411000000000000000474 -:102DA0000040481100000000000021700020441184 -:102DB00000000000000000000020480200000000A9 -:102DC0000000000000204803000000008100000017 -:102DD00000204411000000000000000A00204811FB -:102DE00000000000000000000020001000000000B3 -:102DF0000000000014C00000000003D38C0000009D -:102E00000020441100000000CAFEBABE0040481174 -:102E100000000000810000000020441100000000BC -:102E200000000001002048110000000000003FFFEA -:102E300040280A20000000008000000040280E20EA -:102E40000000000040000000C02812200000000028 -:102E500000040000006946220000068D000000000A -:102E6000002014100000000000000000002F0223CA -:102E700000000000000000000CC00000000003E1A2 -:102E800000000000C0401800000003E400003FFF05 -:102E9000C0281A2000000000000400000069462637 -:102EA0000000068D00000000002018100000000047 -:102EB00000000000002F02240000000000000000BD -:102EC0000CC00000000003E700000000C0401C0030 -:102ED000000003EA00003FFFC0281E2000000000A1 -:102EE00000040000006946270000068D0000000075 -:102EF00000201C1000000000000000000020440220 -:102F00000000000000000000002820C500000000B4 -:102F100000000000004948E800000000A580000013 -:102F200000200811000000000000200000200C110B -:102F30000000000083000000006044110000041243 -:102F4000000000000020440200000000000000001B -:102F5000C0204800000000000000000040204800A1 -:102F6000000000000000001FC0210220000000003F -:102F70000000000014C00000000003F70000201053 -:102F800000204411000000000000800000204811D3 -:102F9000000000000000FFFFC0481220000003FFF7 -:102FA000A780000000200811000000000000A00021 -:102FB00000200C110000000083000000006044119C -:102FC0000000041200000000002044020000000085 -:102FD00000000000C02048000000000000000000C9 -:102FE000C0204800000000000000FFFFC0281220A1 -:102FF00000000000830000000020441100000000D9 -:103000000000000000304883000000008400000041 -:10301000002044110000000000000000C020480013 -:1030200000000000000000001D0000000000000083 -:103030008300000000604411000004120000000042 -:10304000C040040000000001A98000000020081119 -:10305000000000000000C00000400C11000003FA56 -:10306000AB80000000200811000000000000F8E024 -:1030700000400C11000003FAAD8000000020081190 -:10308000000000000000F88000400C11000003FA6E -:10309000B380000000200811000000000000F3FCD5 -:1030A00000400C11000003FAAF800000002008115E -:1030B000000000000000E00000400C11000003FAD6 -:1030C000B180000000200811000000000000F000A6 -:1030D00000400C11000003FA83000000002044119E -:1030E00000000000000021480020481100000000FE -:1030F00084000000002044110000000000000000D7 -:10310000C020480000000000000000001D0000007A -:10311000000000000000000000800000000000002F -:1031200001182000C0304620000000000000000010 -:10313000D90048000000000000000000C02004008A -:10314000000000000000000000A0000A00000000D5 -:103150000218A000C030462000000000000000005F -:10316000D90048000000000000000000C02004005A -:10317000000000000000000000A0000A00000000A5 -:103180000318C000C030462000000000000000000E -:10319000D90048000000000000000000C02004002A -:1031A000000000000000000000A0000A0000000075 -:1031B0000418F8E0C03046200000000000000000C5 -:1031C000D90048000000000000000000C0200400FA -:1031D000000000000000000000A0000A0000000045 -:1031E0000518F880C03046200000000000000000F4 -:1031F000D90048000000000000000000C0200400CA -:10320000000000000000000000A0000A0000000014 -:103210000618E000C030462000000000000000005A -:10322000D90048000000000000000000C020040099 -:10323000000000000000000000A0000A00000000E4 -:103240000718F000C0304620000000000000000019 -:10325000D90048000000000000000000C020040069 -:10326000000000000000000000A0000A00000000B4 -:103270000818F3FCC03046200000000000000000E9 -:10328000D90048000000000000000000C020040039 -:10329000000000000000000000A0000A0000000084 -:1032A0000000003000200A2D000000000000000097 -:1032B000C0290C4000000000000000300020362330 -:1032C0000000000000000000C0200400000000001A -:1032D0000000000000A0000A0000000086000000BE -:1032E00000204411000000000000000000404801E0 -:1032F0000000000085000000C02044110000000014 -:103300000000000000404801000000000000217C97 -:10331000002044110000000000000018402102209D -:10332000000000000000000014C000000000044580 -:1033300000800000C0494A20000004460000000050 -:10334000C02048000000000000000000C02048002D -:103350000000000000000000C02048000000000045 -:103360008100000000204411000000000000000166 -:10337000002048110000000000000000C0200800EC -:103380000000000000000000170000000000000026 -:103390000004217F006044110000068D0000001F22 -:1033A00000210230000000000000000014C00000F6 -:1033B000000000000000000000404C020000044B30 -:1033C00000000000C0200C00000000000000000011 -:1033D000C02010000000000000000000C020140009 -:1033E0000000000000000000C020180000000000E5 -:1033F00000000000C0201C000000000000007F0052 -:1034000000280A210000000000004500002F0222D1 -:1034100000000000000000000CE000000000045963 -:1034200000000000C020200000000000000000009C -:1034300017000000000000000000001000280A2310 -:103440000000000000000010002F02220000000019 -:10345000000000000CE0000000000461810000009A -:10346000002044110000000000000001002048116D -:103470000000000000040000006946240000068DE2 -:103480000000000000400000000004668100000011 -:10349000002044110000000000000000002048113E -:1034A000000000000000216D002044110000000019 -:1034B00000000000002048040000000000000000A0 -:1034C000006048050000069200000000002824F07B -:1034D000000000000000000700280A230000000090 -:1034E00000000001002F0222000000000000000088 -:1034F0000AE000000000046D00000000002F00C979 -:10350000000000000000000004E00000000004864D -:1035100000000000004000000000049300000002D2 -:10352000002F022200000000000000000AE000005E -:103530000000047200000000002F00C9000000001D -:103540000000000002E0000000000486000000000F -:10355000004000000000049300000003002F02223E -:1035600000000000000000000AE0000000000477F6 -:1035700000000000002F00C9000000000000000053 -:103580000CE0000000000486000000000040000085 -:103590000000049300000004002F0222000000003D -:1035A000000000000AE000000000047C00000000B1 -:1035B000002F00C900000000000000000AE0000029 -:1035C000000004860000000000400000000004939A -:1035D00000000005002F0222000000000000000093 -:1035E0000AE000000000048100000000002F00C974 -:1035F000000000000000000006E00000000004865B -:1036000000000000004000000000049300000006DD -:10361000002F022200000000000000000AE000006D -:103620000000048600000000002F00C90000000018 -:103630000000000008E00000000004860000000018 -:10364000004000000000049300007F0000280A21D1 -:103650000000000000004500002F022200000000D2 -:10366000000000000AE00000000000000000000868 -:1036700000210A23000000000000000014C0000028 -:1036800000000490000021690020441100000000A7 -:1036900000000000C0204800000000000000000002 -:1036A000C02048000000000000000000C0204800CA -:1036B00000000000CAFEBABE004048110000000031 -:1036C00000000000C02044000000000000000000D6 -:1036D000C02000000000000000000000C0404800C2 -:1036E0000000000000007F0000280A210000000008 -:1036F00000004500002F0222000000000000000032 -:103700000AE000000000049900000000C020000052 -:103710000000000000000000C020000000000000C9 -:1037200000000000C0400000000000000000000099 -:1037300000404C080000045900000000C0200800B0 -:10374000000000000000001040210E2000000000DA -:1037500000000011402112200000000000000012B3 -:1037600040211620000000000000216900204411C3 -:1037700000000000000000000020480200000000DF -:1037800000000000002102250000000000000000F1 -:1037900014E00000000004A300040000C0494A2017 -:1037A000000004A4FFFBFFFFC0284A200000000027 -:1037B00000000000002102230000000000000000C3 -:1037C00014E00000000004B000000000C020480029 -:1037D0000000000000000000C020480000000000C1 -:1037E0000000000000210224000000000000000092 -:1037F00014C00000000000008100000000204411FF -:10380000000000000000000C002048110000000033 -:103810000000000000200010000000000000000078 -:1038200014C00000000004ACA000000000204411FF -:1038300000000000CAFEBABE0040481100000000AF -:10384000810000000020441100000000000000047E -:1038500000204811000000000000216B00204411EE -:103860000000000000000000C02048100000000020 -:10387000810000000020441100000000000000054D -:1038800000204811000000000000216C00204411BD -:103890000000000000000000C020481000000000F0 -:1038A00000000000002F02240000000000000000C3 -:1038B0000CE00000000000000000000000400000DC -:1038C000000004AA00000000C0210A20000000003F -:1038D0000000000014C00000000004C381000000CC -:1038E00000204411000000000000000000204811EA -:1038F000000000000000216D0020441100000000C5 -:1039000000000000C020480000000000000000008F -:10391000C060480000000692000000000040000067 -:10392000000004C7810000000020441100000000D6 -:103930000000000100204811000000000004000009 -:10394000C02946200000000000000000C060000008 -:103950000000068D0000000100210222000000008E -:103960000000000014C00000000004CE0000216927 -:10397000002044110000000000000000C0204800AA -:103980000000000000000000C0204800000000000F -:10399000000000000020481000000000CAFEBABE6F -:1039A000004048110000000000000000C02044005A -:1039B0000000000000000000C040481000000000AF -:1039C0008100000000204411000000000000000100 -:1039D0000020481100000000000021F800204411E0 -:1039E000000000000000000E002048110000000050 -:1039F000000421F9006044110000068D0000000061 -:103A000000210230000000000000000014C000008F -:103A1000000004D0000021800020441100000000BC -:103A200000000000C020480000000000000000006E -:103A3000C02000000000000000000000C02048007E -:103A40000000000000000000C02000000000000096 -:103A500000000000C040480000000000000000031B -:103A600000333E2F00000000000000010021022171 -:103A7000000000000000000014E00000000005004D -:103A80000000002C00200A2D0000000000040000AF -:103A900018E00C11000004EF0000000100333E2F7D -:103AA0000000000000002169002044110000000017 -:103AB000000000000020480200000000000000009C -:103AC00000204803000000000000000800300A2227 -:103AD0000000000000000000C020480000000000BE -:103AE00000000000C0204800000000000000216924 -:103AF00000204411000000000000000000204802E7 -:103B0000000000000000000000204803000000004A -:103B10000000000800300A22000000000000000041 -:103B2000C02048000000000000000000D8C048008D -:103B3000000004E30000216900204411000000009F -:103B4000000000000020480200000000000000000B -:103B500000204803000000000000000800300A2296 -:103B60000000000000000000C0204800000000002D -:103B700000000000C0204800000000000000002DF0 -:103B80000020122D000000000000000000290C831E -:103B90000000000000002169002044110000000026 -:103BA00000000000002048020000000000000000AB -:103BB00000204803000000000000000800300A2236 -:103BC0000000000000000000C020480000000000CD -:103BD00000000000C02048000000000000000011AC -:103BE00000210224000000000000000014C00000BA -:103BF000000000000000000000400000000004AAD7 -:103C00000000002CC0203620000000000000002D25 -:103C1000C0403620000000000000000F00210221FB -:103C2000000000000000000014C0000000000505B6 -:103C300000000000006000000000000B0000000019 -:103C4000D90000000000000000000000C040040097 -:103C500000000001B5000000002044110000000039 -:103C6000000020000020481100000000B600000005 -:103C700000204411000000000000A00000204811B6 -:103C800000000000B7000000002044110000000008 -:103C90000000C0000020481100000000B800000033 -:103CA00000204411000000000000F8E0002048114E -:103CB00000000000B90000000020441100000000D6 -:103CC0000000F8800020481100000000BA00000049 -:103CD00000204411000000000000E0000020481116 -:103CE00000000000BB0000000020441100000000A4 -:103CF0000000F0000020481100000000BC0000009F -:103D000000204411000000000000F3FC00204811D6 -:103D100000000000810000000020441100000000AD -:103D2000000000020020481100000000000000FF19 -:103D300000280E300000000000000000002F0223C9 -:103D400000000000000000000CC000000000051989 -:103D500000000000C020080000000000000000007B -:103D600014C000000000052E0000000000200C110F -:103D7000000000000000001C0020362300000000AE -:103D80000000002B00203623000000000000002966 -:103D90000020362300000000000000280020362309 -:103DA0000000000000000017002036230000000083 -:103DB000000000250020362300000000000000263F -:103DC00000203623000000000000001500203623EC -:103DD0000000000000000016002036230000000054 -:103DE000FFFFE00000200C11000000000000002197 -:103DF00000203623000000000000002200203623AF -:103E00000000000000001FFF00200C110000000057 -:103E100000000023002036230000000000000024E2 -:103E20000020362300000000F1FFFFFF00283A2E9B -:103E3000000000000000001AC0220E200000000058 -:103E4000000000000029386E000000008100000022 -:103E5000002044110000000000000006002048116E -:103E6000000000000000002A402036200000000072 -:103E70008700000000204411000000000000000046 -:103E8000C0204800000000000000A1F40020441100 -:103E900000000000000000000020481000000000AA -:103EA0000000000000200C110000000000000030A5 -:103EB00000203623000000009D0000000020441177 -:103EC000000000000000001F40214A200000000008 -:103ED00096000000002044110000000000000000D7 -:103EE000C02048000000000000000000C0200C00BE -:103EF0000000000000000000C020100000000000D2 -:103F00000000001F00211624000000000000000037 -:103F100014C00000000000000000001D0020362337 -:103F2000000000000000000300281E230000000025 -:103F3000000000080022222300000000FFFFF00024 -:103F4000002822280000000000000000002920E8CE -:103F5000000000000000001F0020362800000000C4 -:103F60000000001800211E230000000000000020B7 -:103F70000020362700000000000000020022162466 -:103F80000000000000000000003014A80000000045 -:103F90000000001E00203625000000000000000385 -:103FA00000211A24000000001000000000281A263A -:103FB00000000000EFFFFFFF00283A2E0000000085 -:103FC00000000000004938CE0000067B0000000120 -:103FD00040280A20000000000000000640280E20B3 -:103FE0000000000000000300C028122000000000B4 -:103FF0000000000800211224000000000000000062 -:10400000C02016200000000000000000C0201A2080 -:10401000000000000000000000210222000000005B -:104020000000000014C000000000056681000000D0 -:104030000020441100000000000000010020481191 -:10404000000000000000225800300A240000000098 -:1040500000040000006946220000068D000021696E -:10406000002044110000000000000000002048056E -:10407000000000000002000000294A2600000000A5 -:10408000000000000020481000000000CAFEBABE78 -:10409000002048110000000000000002002F022351 -:1040A00000000000000000000CC000000000056ED1 -:1040B00000000000C0201C100000000000000000F4 -:1040C000C04000000000057C00000002002F022319 -:1040D00000000000000000000CC000000000056EA1 -:1040E00081000000002044110000000000000001D9 -:1040F00000204811000000000000225800300A246F -:104100000000000000040000006946220000068D47 -:1041100000000000C0201C10000000000000000093 -:10412000C04000000000057C00000000002F0223BA -:1041300000000000000000000CC00000000005723C -:1041400000000000C0201C00000000000000000073 -:10415000C04000000000057C00000004002F022386 -:1041600000000000000000000CC000000000057A04 -:104170008100000000204411000000000000000049 -:1041800000204811000000000000216D00204411B3 -:104190000000000000000000C020480000000000F7 -:1041A00000000000C060480000000692000000000F -:1041B00000401C100000057C00000000C020000032 -:1041C0000000000000000000C040000000000000EF -:1041D000000000000EE000000000057E000000006E -:1041E00000600000000005C900000000002F02244C -:1041F00000000000000000000CC000000000058F5F -:104200000000A2B7002044110000000000000000E0 -:104210000020480700000000810000000020441139 -:104220000000000000000001002048110000000014 -:104230000004A2B6006044110000068D0000001AC0 -:10424000002122300000000000000006002226307D -:104250000000000000042004006044110000068DEE -:104260000000A2C400204411000000000000000073 -:10427000003048E9000000000000000000E00000FD -:104280000000058D0000A2D10020441100000000B4 -:104290000000000000404808000000000000A2D11B -:1042A00000204411000000000000000100504A28D6 -:1042B0000000000000000001002F022400000000A8 -:1042C000000000000CC00000000005A00000A2BB20 -:1042D00000204411000000000000000000204807FA -:1042E00000000000810000000020441100000000D8 -:1042F0000000000100204811000000000004A2BAE4 -:10430000006044110000068D0000001A00212230D8 -:10431000000000000000000600222630000000001F -:1043200000042004006044110000068D0000A2C5B6 -:10433000002044110000000000000000003048E9A7 -:10434000000000000000000000E000000000059EEA -:104350000000A2D200204411000000000000000074 -:1043600000404808000000000000A2D200204411D4 -:10437000000000000000000100504A28000000007A -:1043800000000002002F02240000000000000000D6 -:104390000CC00000000005B10000A2BF00204411C5 -:1043A000000000000000000000204807000000009E -:1043B0008100000000204411000000000000000106 -:1043C00000204811000000000004A2BE006044115B -:1043D0000000068D0000001A0021223000000000BD -:1043E0000000000600222630000000000004200427 -:1043F000006044110000068D0000A2C60020441198 -:104400000000000000000000003048E9000000004B -:104410000000000000E00000000005AF0000A2D393 -:104420000020441100000000000000000040480887 -:10443000000000000000A2D3002044110000000092 -:104440000000000100504A28000000000000A2C344 -:104450000020441100000000000000000020480778 -:104460000000000081000000002044110000000056 -:104470000000000100204811000000000004A2C25A -:10448000006044110000068D0000001A0021223057 -:10449000000000000000000600222630000000009E -:1044A00000042004006044110000068D0000A2C733 -:1044B000002044110000000000000000003048E926 -:1044C000000000000000000000E00000000005BE49 -:1044D0000000A2D4002044110000000000000000F1 -:1044E00000404808000000000000A2D40020441151 -:1044F000000000000000000100504A2800000000F9 -:1045000085000000002044110000000000000000B1 -:1045100000204801000000000000304A0020441143 -:104520000000000001000000002048110000000011 -:104530000000000000400000000005C4A4000000CE -:10454000C02044110000000000000000C0404800EE -:104550000000000000000000C0600000000005C96D -:1045600000000000C0400400000000010000002C1A -:1045700000203621000000008100000000204411CE -:1045800000000000000000060020481100000000AC -:1045900000000000002F02300000000000000000BA -:1045A0000CC00000000005D0000000000020041135 -:1045B000000000000000003000403621000005E34C -:1045C000000000300020062D0000000000007E00EA -:1045D000002806210000000000000000002F02213A -:1045E00000000000000000000CE00000000005E3F7 -:1045F00081000000002044110000000000000001C4 -:1046000000204811000000000004A0920060441146 -:104610000000068D00000031002036300000000050 -:104620000004A093006044110000068D00000032D9 -:1046300000203630000000000004A2B600604411E3 -:104640000000068D0000003300203630000000001E -:104650000004A2BA006044110000068D000000347E -:1046600000203630000000000004A2BE00604411AB -:104670000000068D000000350020363000000000EC -:104680000004A2C2006044110000068D0000003644 -:1046900000203630000000000004200400604411B7 -:1046A0000000068D0001A2A40020441100000000BB -:1046B0000000003F00204811000000000000003F03 -:1046C00000204811000000000000003F00204811B9 -:1046D000000000000000003F002048110000000022 -:1046E0000000000500204811000000000000A1F4B7 -:1046F00000204411000000000000000000204811CC -:1047000000000000880000000020441100000000AC -:10471000000000010020481100000000810000009E -:104720000020441100000000000000060020481195 -:104730000000000000000001002F02300000000017 -:10474000000000000CE000000000062C000000301B -:104750000020062D0000000000000000002F0221B4 -:1047600000000000000000000CE000000000062C2B -:104770008100000000204411000000000000000142 -:10478000002048110000000000007E0000280621E3 -:104790000000000000000000002F022100000000C7 -:1047A000000000000CE00000000006050000A092E0 -:1047B00000204411000000000000003100204A2DBC -:1047C000000000000000A093002044110000000041 -:1047D0000000003200204A2D000000000000A2B6B8 -:1047E00000204411000000000000003300204A2D8A -:1047F000000000000000A2BA0020441100000000E8 -:104800000000003400204A2D000000000000A2BE7D -:1048100000204411000000000000003500204A2D57 -:10482000000000000000A2C20020441100000000AF -:104830000000003600204A2D00000000000000307B -:104840000020062D00000000000001FF00280621C6 -:104850000000000000000000002F02210000000006 -:10486000000000000CE000000000062B000000002B -:1048700000210221000000000000000014C0000020 -:104880000000060E0004A003006044110000068D25 -:104890000000A00300204411000000000000000000 -:1048A0000020481000000000000000010021062147 -:1048B000000000000000000014C00000000006130B -:1048C0000004A010006044110000068D0000A0103C -:1048D00000204411000000000000000000204810EB -:1048E000000000000000000100210621000000007F -:1048F00000000000002F0221000000000000000066 -:104900000CE000000000062B0004A0110060441120 -:104910000000068D0000A0110020441100000000DE -:104920000000000000204810000000000004A01259 -:10493000006044110000068D0000A0120020441108 -:1049400000000000000000000020481000000000EF -:104950000004A013006044110000068D0000A013A5 -:10496000002044110000000000000000002048105A -:10497000000000000004A014006044110000068D37 -:104980000000A014002044110000000000000000FE -:1049900000204810000000000004A0150060441131 -:1049A0000000068D0000A01500204411000000004A -:1049B0000000000000204810000000000004A016C5 -:1049C000006044110000068D0000A0160020441174 -:1049D000000000000000000000204810000000005F -:1049E0000004A017006044110000068D0000A0170D -:1049F00000204411000000000000000000204810CA -:104A00000000000000042004006044110000068D36 -:104A10000000002C0080062D00000000FF000000B8 -:104A20000020441100000000000000000020481198 -:104A300000000000000000010020481100000000FC -:104A4000000000020080481100000000000000008B -:104A50000EE000000000063D000000300020062DA2 -:104A600000000000000000020028062100000000F5 -:104A700000000000002F02210000000000000000E4 -:104A80000CE000000000063B810000000020441103 -:104A9000000000000000000100204811000000009C -:104AA00000042004006044110000068D0000100086 -:104AB00000200811000000000000002B002036221A -:104AC000000000000000000000600000000006413F -:104AD0000000000000600000000005C99800000010 -:104AE0000020441100000000000000000080481178 -:104AF0000000000000000000C0600000000006414F -:104B000000000000C0400400000000010000A2A45A -:104B10000020441100000000000000220020481185 -:104B20000000000089000000002044110000000087 -:104B300000000001004048110000062D9700000011 -:104B40000020441100000000000000000020481177 -:104B5000000000008A000000002044110000000056 -:104B600000000000004048110000062D0000000079 -:104B7000006000000000065C0000201000204411CE -:104B8000000000000000800000204811000000002C -:104B90000001A2A4C0204411000000000000001683 -:104BA000006048110000036E000020100020441136 -:104BB000000000000001000000204811000000007B -:104BC00081000000002044110000000000000001EE -:104BD00000204811000000000000217C002044114A -:104BE00000000000098000000020481100000000C3 -:104BF000FFFFFFFF00204811000000000000000040 -:104C00000020481100000000000000001700000014 -:104C1000000000000004217F006044110000068DA8 -:104C20000000001F00210230000000000000000012 -:104C300014C00000000000000000000400404C11FF -:104C400000000656000000000040000000000000C8 -:104C50000000001700201E2D0000000000000004CE -:104C600000291E27000000000000001700803627E2 -:104C7000000000000000001700201E2D00000000B2 -:104C8000FFFFFFFB00281E270000000000000017A8 -:104C900000803627000000000000001700201E2DB5 -:104CA000000000000000000800291E27000000008E -:104CB00000000017008036270000000000000017E9 -:104CC00000201E2D00000000FFFFFFF700281E2718 -:104CD00000000000000000170080362700000000E0 -:104CE000000020100020441100000000000080009F -:104CF00000204811000000000001A2A4002044117F -:104D00000000000000000016006048110000036E63 -:104D100000002010002044110000000000010000ED -:104D200000204811000000000000217C00204411F8 -:104D30000000000001800000002048110000000079 -:104D4000FFFFFFFF002048110000000000000000EE -:104D500000204811000000000000000017000000C3 -:104D6000000000008100000000204411000000004D -:104D70000000000100204811000000000004217F15 -:104D8000006044110000068D0000001F0021023069 -:104D9000000000000000000014C000000000068CAD -:104DA0000000001000404C110000067200000000DE -:104DB000C0200400000000000000000038C0000017 -:104DC000000000000000001D00200A2D000000006F -:104DD0000000001E00200E2D000000000000001F3B -:104DE0000020122D00000000000000200020162DE1 -:104DF00000000000000021690020441100000000B4 -:104E00000000000000204804000000000000000036 -:104E100000204805000000000000000000204801BC -:104E200000000000CAFEBABE0020481100000000C9 -:104E30000000000400301224000000000000000008 -:104E4000002F006400000000000000000CC0000003 -:104E50000000068B0000000300281A22000000005A -:104E6000000000080022122200000000FFFFF000F6 -:104E7000002812240000000000000000002910C4D7 -:104E8000000000000000001F004036240000000069 -:104E90000000000000800000000000000000000092 -:104EA0001AC000000000068D9F0000000020441181 -:104EB00000000000CAFEBABE002048110000000039 -:104EC000000000001AE00000000006900000000052 -:104ED0000080000000000000000000001AC0000078 -:104EE000000006929E000000002044110000000017 -:104EF000CAFEBABE002048110000000000000000F9 -:104F00001AE000000000069500000000008000008C -:104F10000000000000000000006000000000000B26 -:104F200000001000006004110000031500000000E4 -:104F300000200411000000000000000000600811C3 -:104F4000000001B20000225C0020441100000000BB -:104F5000000000030020481100000000000022565D -:104F600000204411000000000000001B0020481138 -:104F7000000000000000A1FC00204411000000001F -:104F80000000000100204811000000000001A1FD08 -:104F9000C0204411000000000000002100201E2D50 -:104FA000000000000000001000221E27000000008A -:104FB000000000240020222D000000000000FFFF60 -:104FC00000282228000000000000000000294907F6 -:104FD0000000000000000000002048110000000058 -:104FE000000000220020222D000000000000FFFF32 -:104FF00000282228000000000000000000294907C6 -:105000000000000000000000002048110000000027 -:105010000000002300201E2D0000000000000010F2 -:1050200000221E27000000000000000000294907A0 -:1050300000000000000000000040481100000000D7 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B0000142050205C002500000000001C3016860 -:1052C000043F05C000000000022502090250015100 -:1052D000000000000223024502A00241000000007D -:1052E00003D705C005C005C0000000000649064AF6 -:1052F000031F05C00000000005C005C503200340D2 -:1053000000000000032A0282034203340000000070 -:1053100005C005C005C005C00000000005C005515E -:1053200005C005C00000000003BA05C004BB03446B -:1053300000000000049A0450043D05C00000000075 -:1053400004D005C0044104DD00000000045005073E -:10535000035103750000000005C005C005C005C06D -:105360000000000005C005C005C005C00000000029 -:1053700005C005C0063F05C70000000005C005C008 -:10538000000705C00000000005C005C005C005C03D -:105390000000000005C005C005C005C000000000F9 -:1053A00003F803ED0408040600000000040E040ADC -:1053B000040C041000000000041C04180424042041 -:1053C00000000000042C0428043404300000000015 -:1053D00005C005C0043805C00000000005C005C0B8 -:1053E00005C005C00000000005C005C005C005C01F -:1053F0000000000000020679069700060000000089 -:00000001FF diff --git a/firmware/radeon/RV620_pfp.bin.ihex b/firmware/radeon/RV620_pfp.bin.ihex deleted file mode 100644 index f55292c97b7937d5da76127dbb21745b72d8039d..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV620_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000CA040000A00000007E828B007C038BED -:10001000008001B8007C038B00D4401E00EE001E5F -:1000200000CA040000A00000007E828B00C41838C3 -:1000300000CA240000CA2800009581A800C41C3A08 -:1000400000C3C00000CA080000CA0C00007C744B4A -:1000500000C200050099C00000C41C3A007C744C2A -:1000600000C0FFF000042C0400309002007D250049 -:1000700000351402007D350B00255403007CD5802B -:1000800000259C030095C00400D5001B007EDDC147 -:10009000007D9D8000D6801B00D5801B00D4401EB3 -:1000A00000D5401E00D6401E00D6801E00D4801E03 -:1000B00000D4C01E009783D300D5C01E00CA08001C -:1000C0000080001A00CA0C0000E4011E00D4001ECB -:1000D0000080000C00C4183800E4013E00D4001E6B -:1000E0000080000C00C4183800D4401E00EE001E32 -:1000F00000CA040000A00000007E828B00E4011E04 -:1001000000D4001E00D4401E00EE001E00CA0400F1 -:1001100000A00000007E828B00E4013E00D4001E9F -:1001200000D4401E00EE001E00CA040000A0000023 -:10013000007E828B00CA180000D4401E00D5801EAD -:100140000080005300D4007500D4401E00CA08008F -:1001500000CA0C0000CA100000D4801900D4C018D6 -:1001600000D5001700D4801E00D4C01E00D5001E8C -:1001700000E2001E00CA040000A00000007E828B86 -:1001800000CA080000D4806000D4401E0080000037 -:1001900000D4801E00CA080000D4806100D4401E34 -:1001A0000080000000D4801E00CA080000CA0C00B5 -:1001B00000D4401E00D4801600D4C01600D4801E87 -:1001C000008001B800D4C01E00C6084300CA0C005D -:1001D00000CA10000094800400CA140000E420F358 -:1001E00000D4201300D5606500D4E01C00D5201C8D -:1001F00000D5601C008000000006200100C60843F6 -:1002000000CA0C0000CA1000009483F700CA140052 -:1002100000E420F30080007900D4201300C60843D6 -:1002200000CA0C0000CA1000009883EF00CA140036 -:1002300000D400640080008D0000000000C414326F -:1002400000C6184300C4082F0095400500C40C30B8 -:1002500000D4401E0080000000EE001E009583F5D3 -:1002600000C4103100D4403300D5206500D4A01C58 -:1002700000D4E01C00D5201C00E4015E00D4001E68 -:10028000008000000006200100CA1800000A2001BA -:1002900000D6007600C408360098800700C61045D6 -:1002A0000095011000D4001F00D46062008000009F -:1002B00000D4206200CC383500CC1433008401BB5C -:1002C00000D4007200D5401E0080000000EE001E29 -:1002D00000E2001A008401BB00E2001A00CC104BBF -:1002E00000CC0447002C9401007D098B0098400548 -:1002F000007D15CB00D4001A008001B800D4006D39 -:100300000034440100CC0C480098403A00CC2C4A00 -:100310000095800400CC0449008001B800D4001A84 -:1003200000D4C01A00282801008400F000CC10037B -:100330000098801B0004380C008400F000CC1003EF -:100340000098801700043808008400F000CC1003E7 -:100350000098801300043804008400F000CC1003DF -:100360000098801400CC104C009A800900CC144DE9 -:10037000009840DC00D4006D00CC184800D5001A6D -:1003800000D5401A008000C900D5801A0096C0D55B -:1003900000D4006D008001B800D4006E009AC00344 -:1003A00000D4006D00D4006E0080000000EC007FDF -:1003B000009AC0CC00D4006D008001B800D4006E5B -:1003C00000CC140300CC180300CC1C03007D910367 -:1003D000007DD583007D190C0035CC1F0035701FC2 -:1003E000007CF0CB007CD08B00880000007E8E8BE0 -:1003F0000095C00400D4006E008001B800D4001A3B -:1004000000D4C01A00CC080300CC0C0300CC1003AD -:1004100000CC140300CC180300CC1C0300CC240334 -:1004200000CC28030035C41F0036B01F007C704B81 -:100430000034F01F007C704B0035701F007C704B47 -:10044000007D8881007DCCC1007E5101007E9541F8 -:10045000007C9082007CD4C2007C848B009AC00314 -:10046000007C8C8B002C88010098809E00D4006D4D -:100470000098409C00D4006E00CC084C00CC0C4D81 -:1004800000CC104800D4801A00D4C01A00800101AA -:1004900000D5001A00CC083200D40032009482D972 -:1004A00000CA0C0000D4401E0080000000D4001ED2 -:1004B00000E4011E00D4001E00CA080000CA0C009F -:1004C00000CA100000D4401E00CA140000D4801ED0 -:1004D00000D4C01E00D5001E00D5401E00D54034FB -:1004E0000080000000EE001E0028040400E2001A54 -:1004F00000E2001A00D4401A00CA380000CC0803F9 -:1005000000CC0C0300CC0C0300CC0C03009882BD83 -:1005100000000000008401BB00D7A06F0080000035 -:1005200000EE001F00CA040000C2FF0000CC083427 -:1005300000C13FFF007C74CB007CC90B007D010F24 -:10054000009902B0007C738B008401BB00D7A06FC0 -:100550000080000000EE001F00CA080000281900FB -:10056000007D898B009580140028140400CA0C00BB -:1005700000CA100000CA1C0000CA240000E2001FCC -:1005800000D4C01A00D5001A00D5401A00CC1803B8 -:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -:1005A000007D9C4700984297000000000080016198 -:1005B00000D4C01A00D4401E00D4801E0080000069 -:1005C00000EE001E00E4011E00D4001E00D4401EF8 -:1005D00000EE001E00CA040000A00000007E828B16 -:1005E00000E4013E00D4001E00D4401E00EE001EB8 -:1005F00000CA040000A00000007E828B00CA080030 -:1006000000248C06000CCC060098C00600CC104ECE -:100610000099000400D4007300E4011E00D4001E01 -:1006200000D4401E00D4801E0080000000EE001E9A -:1006300000CA080000CA0C000034D01800251001C0 -:100640000095002100C17FFF00CA100000CA1400FD -:1006500000CA180000D4801D00D4C01D007DB18BDD -:1006600000C1420200C2C00100D5801D0034DC0E72 -:10067000007D5D4C007F734C00D7401E00D5001EEE -:1006800000D5401E00C1420000C2C00000099C010C -:100690000031DC10007F5F4C007F734C00042802A7 -:1006A000007D838000D5A86F00D5806600D7401EEE -:1006B00000EC005E00C8240200C82402008001B8DB -:1006C00000D6007600D4401E00D4801E00D4C01E88 -:1006D0000080000000EE001E0080000000EE001F01 -:1006E00000D4001F0080000000D4001F00D4001FB1 -:1006F0000088000000D4001F00000000000000007F -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000010171000201780003008F0004007FE5 -:10081000000500030006003F000700320008012C1D -:1008200000090046000A0036001001B6001700A2B9 -:100830000022013A00230149002000B400240125D0 -:100840000027004D0028006A002A0060002B00529B -:10085000002F0065003200870034017F003C015604 -:10086000003F00720041018C0044012E00550173CD -:100870000056017A0060000B00610034006200380D -:1008800000630038006400380065003800660038F6 -:10089000006700380068003A00690041006A0048BB -:1008A000006B0048006C0048006D0048006E004876 -:1008B000006F00480000000600000006000000066F -:1008C0000000000600000006000000060000000610 -:1008D0000000000600000006000000060000000600 -:1008E00000000006000000060000000600000006F0 -:1008F00000000006000000060000000600000006E0 -:00000001FF diff --git a/firmware/radeon/RV630_me.bin.ihex b/firmware/radeon/RV630_me.bin.ihex deleted file mode 100644 index ba3a7e632d97f03ee553ea7ece2cf6a7f65b1105..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV630_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A000006044110000068A0000000000600000AB -:1000B0000000062E00000000006000000000064264 -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E000000000000000001800203625000000007D -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000002800204A2D8B -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000001900203625C9 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001700200E2D5A -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001718 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000270020362410 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:10038000000000000000000E0020362300000000E6 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E23000000000000000FC9 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000002700204A2D000000004F -:1003F000000000000020481100000000000000295B -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A00000000000002048040000000000000030AF -:1005B0000020162D00000000000000020029162572 -:1005C0000000000000000030002036250000000080 -:1005D000000000250020162D000000000000000093 -:1005E000002F00A300000000000000000CC000006D -:1005F00000000083000000260020162D00000000EF -:1006000000000000002F00A4000000000000000017 -:100610000CC000000000008400000000004000004A -:100620000000008A000000250020362300000000A2 -:100630000000002600203624000000000000001703 -:1006400000201E2D000000000000000200210227F3 -:10065000000000000000000014E000000000008A1C -:1006600000000000006000000000066500000000BF -:1006700000600000000006590000000200210E2268 -:10068000000000000000000014C000000000008D09 -:1006900000000012C040362000000093000000005F -:1006A0002EE0000000000091000000002CE000009F -:1006B000000000900000000200400E2D000000929B -:1006C0000000000300400E2D000000920000000C0E -:1006D00000200E2D00000000000000120020362334 -:1006E000000000000000000300210E2200000000B6 -:1006F0000000000014C00000000000980000A00CE2 -:10070000002044110000000000000000C02048004C -:100710000000000000000000C0404800000000A0F1 -:100720000000A00C002044110000000000000000A8 -:100730000020481100000000000000002EE0000032 -:100740000000009E000000002CE000000000009D62 -:100750000000000200400E2D0000009F000000037A -:1007600000400E2D0000009F0000000C00200E2D08 -:10077000000000000000000000204803000000000E -:1007800000000000003A0C0200000000003F0000E2 -:1007900000280E23000000000000001000210E239E -:1007A00000000000000000110020362300000000BF -:1007B0000000001E0021022B0000000000000000CD -:1007C00014C00000000000A700000016C020362062 -:1007D000000000000000001F0021022B00000000AC -:1007E0000000000014C00000000000AA0000001576 -:1007F000C0203620000000000000000800210E2B61 -:10080000000000000000007F00280E230000000010 -:1008100000000000002F0223000000000000000084 -:100820000CE00000000000E10000000027000000D4 -:10083000000000000000000000600000000002A3B3 -:1008400000000001002F0223000000000000000053 -:100850000AE00000000000B300000000006000009B -:100860000000013A81000000002044110000000057 -:100870000000000600204811000000000000000CED -:1008800000221E300000000099800000002044116A -:1008900000000000000000040020122D00000000F5 -:1008A00000000008002212240000000000000010D8 -:1008B00000201811000000000000000000291CE4C6 -:1008C0000000000000000000006048070000012F49 -:1008D0009B00000000204411000000000000000008 -:1008E00000204802000000009C000000002044118D -:1008F00000000000000000000033146F0000000042 -:100900000000000100333E23000000000000000052 -:10091000D9004800000000000000000000203C0555 -:1009200000000000810000000020441100000000D1 -:100930000000000E00204811000000000000000030 -:1009400000201010000000000000E007002044110B -:10095000000000000000000F0021022B000000003A -:100960000000000014C00000000000CB00F8FF08E9 -:1009700000204811000000009800000000404811CD -:10098000000000DC000000F000280E220000000043 -:10099000000000A0002F0223000000000000000063 -:1009A0000CC00000000000DA0000001100200E2D35 -:1009B0000000000000000001002F022300000000E2 -:1009C000000000000CE00000000000D50000000264 -:1009D000002F022300000000000000000CE00000D7 -:1009E000000000D400003F0000400C11000000D6C1 -:1009F00000001F0000400C11000000D600000F0096 -:100A000000200C11000000000038000900294A23D2 -:100A1000000000003F00000000280E2B0000000036 -:100A20000000000200220E2300000000000000076A -:100A300000494A23000000DC00380F09002048115B -:100A400000000000680000070020481100000000BE -:100A50000000000800214A270000000000000000FC -:100A60000020481100000000060A020000294A2464 -:100A700000000000000000000020481100000000FD -:100A80000000000000204811000000000000A20249 -:100A9000002044110000000000FF000000280E228A -:100AA000000000000000008000294A230000000030 -:100AB0000000002700200E2D00000000000000268E -:100AC0000020122D0000000000000000002F008315 -:100AD00000000000000000000CE00000000000EA40 -:100AE00000000000006000000000065F0000000041 -:100AF00000400000000000EB00000000006000006B -:100B000000000662000000070020222D0000000007 -:100B10000000000500220E2200000000001000006E -:100B200000280E23000000000000000000292068BB -:100B30000000000000000000003A0C02000000006D -:100B4000000000EF00280E2300000000000000005D -:100B500000292068000000000000001700200E2D72 -:100B6000000000000000000300210223000000003C -:100B70000000000014E00000000000F80000000B7E -:100B800000210228000000000000000014C0000046 -:100B9000000000F8000004000029222800000000E6 -:100BA0000000001400203628000000000000001C97 -:100BB00000210E22000000000000000014C0000010 -:100BC000000000FD0000A30C002044110000000004 -:100BD0000000000000204811000000000000001E7E -:100BE00000210E22000000000000000014C00000E0 -:100BF0000000010B0000A30F0020441100000000C2 -:100C00000000001100200E2D000000000000000177 -:100C1000002F022300000000000000000CC00000B4 -:100C200000000104FFFFFFFF004048110000010B1E -:100C300000000002002F022300000000000000005E -:100C40000CC00000000001070000FFFF0040481139 -:100C50000000010B00000004002F02230000000030 -:100C6000000000000CC000000000010A000000FFAE -:100C7000004048110000010B000000010020481155 -:100C8000000000000002C400002044110000000029 -:100C90000000001F00210E220000000000000000E4 -:100CA00014C00000000001120000001040210E20BE -:100CB00000000000000000130020362300000000A8 -:100CC0000000001840224A20000000000000001030 -:100CD000C0424A20000001140000000000200C1156 -:100CE0000000000000000013002036230000000078 -:100CF000000000000020481100000000000000007B -:100D000000204811000000000000000A002010111F -:100D10000000000000000000002F0224000000007E -:100D2000000000000CE000000000011B00000000BB -:100D300000204811000000000000000100531224B0 -:100D400000000117FFBFFFFF00283A2E000000003F -:100D50000000001B00210222000000000000000033 -:100D600014C000000000012E81000000002044118A -:100D7000000000000000000D0020481100000000ED -:100D80000000001800220E3000000000FC000000EF -:100D900000280E2300000000810000000020441104 -:100DA000000000000000000E0020481100000000BC -:100DB0000000000000201010000000000000E00E05 -:100DC000002044110000000007F8FF08002048112F -:100DD000000000000000000000294A23000000007D -:100DE0000000001C00201E2D000000000000000874 -:100DF00000214A27000000000000000000204811E8 -:100E000000000000060A020000294A240000000039 -:100E10000000000000204811000000000000000059 -:100E200000204811000000000000000000800000C9 -:100E300000000000810000000020441100000000BC -:100E40000000000100204811000000000000217C8B -:100E50000020441100000000008000000020481124 -:100E60000000000000000000002048060000000014 -:100E70000000000800214A270000000000000000D8 -:100E800017000000000000000004217F00604411F2 -:100E90000000068A0000001F002102300000000050 -:100EA0000000000014C000000000068900000004DB -:100EB00000404C1100000135810000000020441169 -:100EC00000000000000000010020481100000000A8 -:100ED000000021F800204411000000000000001C68 -:100EE0000020481100000000000421F900604411B6 -:100EF0000000068A000000110021023000000000FE -:100F00000000000014E000000000013C00000000B0 -:100F100000800000000000000000000000600000F1 -:100F20000000000B00000000006004110000031529 -:100F3000000000000020041100000000000000007C -:100F400000600811000001B2000000000060000015 -:100F5000000001600000FFFF40280E20000000009C -:100F600000000010C0211220000000000000FFFF60 -:100F7000402806200000000000000010C0210A20C8 -:100F800000000000000000000034146100000000B8 -:100F90000000000000741882000002BB0001A1FDE7 -:100FA00000604411000002E000003FFF002F022F0C -:100FB00000000000000000000CC00000000001471D -:100FC00000000000C040040000000001000000001C -:100FD000006000000000000B000000000060041131 -:100FE00000000315000000000020041100000000B4 -:100FF0000000000000600811000001B200003FFF87 -:10100000002F022F00000000000000000CE0000094 -:10101000000000000000000000600000000001600F -:101020000000001040210E20000000000000FFFF23 -:10103000C0281220000000000000001040211620EF -:10104000000000000000FFFFC0681A20000002BB83 -:101050000001A1FD00604411000002E000003FFF1C -:10106000002F022F00000000000000000CC0000054 -:101070000000015800000000C04004000000000112 -:101080000000225C0020441100000000000000016C -:1010900000300A2F000000000000000100210A2299 -:1010A000000000000000000300384A220000000099 -:1010B0000000225600204411000000000000001A29 -:1010C00000204811000000000000A1FC0020441195 -:1010D0000000000000000001008048110000000036 -:1010E00000000000006000000000000B0000000095 -:1010F000006000000000018F0000000000600000A0 -:10110000000001A000003FFF002F022F00000000A0 -:10111000000000000CE000000000000000000000E3 -:1011200000202C0800000000000000000020241116 -:101130000000000000000000002028110000000056 -:10114000000022560020441100000000000000169C -:1011500000204811000000000000225C0020441123 -:101160000000000000000003002048110000000003 -:1011700093800000002044110000000000000002E5 -:1011800000221E290000000000000000007048EB53 -:101190000000019C0000000000600000000002BB95 -:1011A00000000001403306200000000000000000A5 -:1011B000C03024090000000000003FFF002F022F74 -:1011C00000000000000000000CE000000000000033 -:1011D0000000000000600000000002A3000000000A -:1011E000002F022100000000000000000AE00000C3 -:1011F0000000018100000000006000000000013AD2 -:101200000000000000400000000001869500000082 -:10121000002044110000000000000000002F022107 -:1012200000000000000000000CE00000000001864B -:1012300000000000C0204800000000000000000185 -:10124000005306210000018292000000002044119A -:101250000000000000000000C0604800000001978E -:101260000001A1FD00204411000000000000001159 -:101270000020062D00000000000000000078042A75 -:10128000000002FB00000000002028090000000010 -:1012900000003FFF002F022F0000000000000000B0 -:1012A0000CC000000000017400000000C0400400F9 -:1012B000000000010000021000600411000003158E -:1012C00000003FFF002F022F000000000000000080 -:1012D0000CE000000000019400000015C020362042 -:1012E0000000000000000016C020362000000000B2 -:1012F0003F800000002004110000000046000000B4 -:1013000000600811000001B2000000000080000031 -:10131000000000000000A1FC0020441100000000BB -:1013200000003FFF002F022F00000000000000001F -:101330000CC000000000019B00000001008048116B -:1013400000000000000000210080481100000000A3 -:101350000000FFFF40280E200000000000000010E9 -:10136000C0211220000000000000FFFF40281620CE -:101370000000000000000010C0811A2000000000E2 -:101380008100000000204411000000000000000661 -:1013900000204811000000000000000800221E305C -:1013A000000000000000002900201A2D00000000AD -:1013B0000000E0000020441100000000FFFBFF09D6 -:1013C00000204811000000000000000F0020222D26 -:1013D0000000000000001FFF00294A280000000054 -:1013E000000000060020222D000000000000000088 -:1013F000002920E80000000000000000002048084C -:101400000000000000000000002048110000000063 -:10141000060A020000294A26000000000000000021 -:1014200000204811000000000000000000204811CA -:101430000000000000000100002018110000000062 -:101440000000000800621E280000012F00000008B4 -:1014500000822228000000000002C0000020441189 -:10146000000000000000001500600E2D000001BD0E -:101470000000001600600E2D000001BD0000C00835 -:1014800000204411000000000000001700200E2D75 -:10149000000000000000000014C00000000001B9BE -:1014A0000000000000200411000000000000000007 -:1014B0000020480100000000390000000020481111 -:1014C00000000000000000000020481100000000A3 -:1014D000000000000080480200000000000000182A -:1014E00000202E2D0000000000000000003B0D63D6 -:1014F000000000000000000800224A230000000055 -:101500000000001000224A23000000000000001824 -:1015100000224A2300000000000000000080480371 -:101520000000000000000000006000000000000B50 -:10153000000010000060041100000315000000000E -:1015400000200411000000000000000000600811ED -:10155000000001B2000000070021062F000000007B -:101560000000001300200A2D000000000000000110 -:1015700000202C11000000000000FFFF4028222066 -:10158000000000000000000F0026222800000000DC -:101590000000001040212620000000000000000F85 -:1015A000002626290000000000000000002028027C -:1015B000000000000000225600204411000000003E -:1015C0000000001B00204811000000000000000087 -:1015D000002F022100000000000000000CE00000CD -:1015E000000001E00000225C002044110000000027 -:1015F0000000008100204811000000000000A1FC54 -:1016000000204411000000000000000100204811EB -:10161000000000000000008000201C1100000000FD -:1016200000000000002F0227000000000000000062 -:101630000CE00000000001DC000000000060000081 -:10164000000001E90000000100531E27000001D83E -:101650000000000100202C11000000000000001F0D -:1016600000280A22000000000000001F00282A2A8B -:10167000000000000000000100530621000001D11D -:101680000000225C00204411000000000000000265 -:1016900000304A2F000000000000A1FC002044118F -:1016A00000000000000000010020481100000000C0 -:1016B0000000000100301E2F0000000000000000AC -:1016C000002F022700000000000000000CE00000D6 -:1016D000000000000000000000600000000001E9C0 -:1016E0000000000100531E27000001E50000FFFF7D -:1016F00040280E20000000000000000F00260E23EE -:101700000000000000000010C021122000000000B6 -:101710000000000F0026122400000000000000005E -:1017200000201411000000000000000000601811EB -:10173000000002BB0001A1FD0020441100000000D8 -:1017400000000000002F022B00000000000000003D -:101750000CE00000000001F8000000100022162834 -:1017600000000000FFFF0000002816250000000018 -:101770000000FFFF00281A29000000000000000000 -:10178000002948C500000000000000000020480AB1 -:10179000000000000000000000202C1100000000EC -:1017A000000000100022162300000000FFFF0000D0 -:1017B00000281625000000000000FFFF00281A2462 -:1017C0000000000000000000002948C500000000E3 -:1017D0000000000000731503000002050000000077 -:1017E0000020180500000000000000000073152410 -:1017F0000000020500000000002D14C500000000DC -:1018000000000000003008A20000000000000000FE -:101810000020480200000000000000000020280214 -:101820000000000000000000002020030000000075 -:101830000000000000802404000000000000000FF1 -:1018400000210225000000000000000014C000007C -:101850000000068900000000002B140500000000B5 -:1018600000000001009016250000000000000000AC -:10187000006000000000000B000000000060041188 -:10188000000003150000000000200411000000000B -:101890000000000000600811000001B200002256A4 -:1018A00000204411000000000000001A00294A2214 -:1018B0000000000000000000C02000000000000048 -:1018C00000003FFF002F022F00000000000000007A -:1018D0000CE000000000000000000000C020040038 -:1018E000000000000000225C002044110000000005 -:1018F0000000000300384A21000000000000A1FCA5 -:1019000000204411000000000000000100204811E8 -:10191000000000000000FFFF40281220000000002F -:1019200000000010C0211A20000000000000FFFF8E -:1019300040280E200000000000000010C0211620EA -:10194000000000000000000000741465000002BBED -:101950000001A1FD00604411000002E00000000150 -:10196000003306210000000000000000002F0221CB -:1019700000000000000000000CC000000000021980 -:1019800000003FFF002F022F0000000000000000B9 -:101990000CC000000000021200000000C040040063 -:1019A000000000010000000000600000000006428E -:1019B000000000000040040F0000021300000000BF -:1019C000006000000000062E000000000060000023 -:1019D0000000064200000210006004110000031520 -:1019E0000000000000600000000001A000000000F6 -:1019F000006000000000019C00000000006000008A -:101A0000000002BB0000000000600000000002A314 -:101A1000938000000020441100000000000000003E -:101A2000002048080000000000000000002F022FE6 -:101A300000000000000000000AE000000000023288 -:101A400000000000006000000000013A00000000FB -:101A50000040000000000236950000000020441104 -:101A60000000000000000000002F022F0000000016 -:101A7000000000000CE00000000002360000000042 -:101A8000C0404800000002339200000000204411D2 -:101A90000000000000000000C0204800000000001E -:101AA0000000225600204411000000000000001633 -:101AB00000204811000000000000225C00204411BA -:101AC000000000000000000300204811000000009A -:101AD0000000A1FC002044110000000000000001F3 -:101AE00000204811000000000001A1FD0020441169 -:101AF000000000000000000000600411000002FB74 -:101B000000000000C04004000000000100000000D0 -:101B1000006000000000062E0000A00C0020441110 -:101B20000000000000000000C0204800000000008D -:101B300000000000C040480000000000000000005D -:101B4000006000000000000B0000001840210A2087 -:101B50000000000000000003002F0222000000002F -:101B6000000000000AE000000000024C0000001429 -:101B70000020222D00000000000801010029222879 -:101B800000000000000000140020362800000000C3 -:101B90000000A30C00204411000000000000000021 -:101BA000C02048000000000000000000C0204800E5 -:101BB0000000000000000000C0404800000002518A -:101BC00000000000006000000000000B000000109A -:101BD00000600411000003153F8000000020041184 -:101BE000000000000000000000600811000001B2C9 -:101BF0000000225C002044110000000000000003EF -:101C000000204811000000000000000000600000FB -:101C10000000027C0000001700201E2D00000000C4 -:101C20000000000100211E2700000000000000004D -:101C300014E000000000026A0000001200201E2DC7 -:101C4000000000000000FFFF00281E270000000029 -:101C50000000000000341C2700000000000000000D -:101C600012C000000000025F0000000000201C11F4 -:101C70000000000000000000002F00E50000000050 -:101C80000000000008C00000000002620000000028 -:101C900000201407000000000000001200201E2D8C -:101CA000000000000000001000211E2700000000BE -:101CB0000000000000341C4700000000000000008D -:101CC00012C00000000002670000000000201C118C -:101CD0000000000000000000002F00E600000000EF -:101CE0000000000008C000000000026A00000000C0 -:101CF0000020180700000000000000000060000045 -:101D0000000002C100002256002044110000000023 -:101D1000000000000034202300000000000000004C -:101D200012C00000000002720000000000342044D5 -:101D3000000000000000000012C00000000002715E -:101D40000000001600404811000002760000001854 -:101D500000404811000002760000000000342044DA -:101D6000000000000000000012C00000000002752A -:101D70000000001700404811000002760000001922 -:101D800000204811000000000000A1FC00204411C8 -:101D900000000000000000010020481100000000C9 -:101DA0000001A1FD00604411000002E900003FFFB6 -:101DB000002F022F00000000000000000CC00000F7 -:101DC0000000025600000000C040040000000001B6 -:101DD0000000001040210620000000000000FFFF6E -:101DE000C0280A20000000000000001040210E2042 -:101DF000000000000000FFFFC028122000000000CB -:101E00000000001040211620000000000000FFFF2D -:101E1000C0881A200000000081000000002044114A -:101E20000000000000000001002048110000000038 -:101E300000042004006044110000068A0000000035 -:101E4000006000000000062E00000000C0600000DE -:101E5000000002A30000000500200A2D0000000081 -:101E60000000000800220A22000000000000002BF1 -:101E700000201A2D000000000000001C00201E2D74 -:101E8000000000000000700000281E270000000075 -:101E90000000000000311CE6000000000000002AE5 -:101EA00000201A2D000000000000000C00221A265D -:101EB0000000000000000000002F00E6000000000D -:101EC0000000000006E00000000002920000000098 -:101ED00000201C11000000000000000000200C1178 -:101EE000000000000000002B00203623000000004E -:101EF0000000001000201811000000000000000089 -:101F000000691CE20000012F9380000000204411B2 -:101F10000000000000000000002048070000000052 -:101F200095000000002044110000000000000000A7 -:101F3000002F022F00000000000000000CE0000055 -:101F40000000029D0000000100333E2F0000000051 -:101F500000000000D90048000000000092000000CE -:101F6000002044110000000000000000C0204800D4 -:101F7000000000000000001C0040362700000000A8 -:101F80000000000CC0220A20000000000000002910 -:101F9000002036220000000000000028C04036204B -:101FA000000000000000A2A4002044110000000076 -:101FB000000000090020481100000000A1000000FE -:101FC00000204411000000000000000100804811C2 -:101FD000000000000000002100201E2D0000000075 -:101FE00000000000002C1CE30000000000000021A5 -:101FF00000203627000000000000002200201E2DD7 -:102000000000000000000000002C1CE400000000A4 -:1020100000000022002036270000000000000023FE -:1020200000201E2D0000000000000000003120A351 -:102030000000000000000000002D1D07000000004F -:1020400000000023002036270000000000000024CC -:1020500000201E2D0000000000000000003120C400 -:102060000000000000000000002D1D07000000001F -:10207000000000240080362700000000000000213E -:10208000002036230000000000000022002036243B -:10209000000000000000000000311CA30000000050 -:1020A0000000002300203627000000000000000090 -:1020B00000311CC40000000000000024008036270E -:1020C000000000000000001A002036270000000079 -:1020D0000000001B00203628000000000000001750 -:1020E00000201E2D00000000000000020021022739 -:1020F000000000000000000014C00000000002DC2E -:102100000000000000400000000002D90000001A9A -:1021100000203627000000000000001B00203628A9 -:10212000000000000000001700201E2D000000002D -:102130000000000200210227000000000000000053 -:1021400014E00000000002D9000000030021022773 -:10215000000000000000000014E00000000002DCAD -:102160000000002300201E2D0000000000000000E1 -:10217000002E00E1000000000000000002C000008E -:10218000000002DC0000002100201E2D00000000E5 -:1021900000000000003120A100000000000000004D -:1021A000002E00E8000000000000000006C0000053 -:1021B000000002DC0000002400201E2D00000000B2 -:1021C00000000000002E00E20000000000000000FF -:1021D00002C00000000002DC0000002200201E2DD2 -:1021E0000000000000000000003120C200000000DC -:1021F00000000000002E00E80000000000000000C9 -:1022000006C00000000002DC0000000000600000CA -:10221000000006650000000000600000000002B53C -:102220000000000000400000000002DE000000008E -:1022300000600000000002B5000000000060000027 -:102240000000065C0000000000400000000002DE0C -:102250000000000000600000000002A70000000075 -:1022600000400000000002DE0000001A00201E2DC9 -:10227000000000000000001B0080222D0000000074 -:102280000000001000221E230000000000000000DB -:1022900000294887000000000000000000311CA356 -:1022A000000000000000001000221E2700000000B7 -:1022B0000000000000294887000000000000001016 -:1022C00000221E230000000000000000003120C496 -:1022D000000000000000FFFF00282228000000008E -:1022E0000000000000894907000000000000001005 -:1022F00000221E2300000000000000000029488783 -:10230000000000000000001000221E21000000005C -:102310000000000000294847000000000000000005 -:1023200000311CA3000000000000001000221E2746 -:1023300000000000000000000029488700000000A5 -:102340000000000000311CA100000000000000108F -:1023500000221E270000000000000000002948475E -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:10239000000000000000001000221E2100000000CC -:1023A00000000000003120C2000000000000FFFF1C -:1023B00000282228000000000000000000894907D2 -:1023C000000000000000001000221E23000000009A -:1023D0000000000000294887000000000000000104 -:1023E00000220A210000000000000000003308A2C3 -:1023F000000000000000001000221E22000000006B -:102400000000001000212222000000000000000057 -:1024100000294907000000000000000000311CA353 -:10242000000000000000001000221E270000000035 -:1024300000000000002948870000000000000001A3 -:1024400000220A210000000000000000003008A265 -:10245000000000000000001000221E22000000000A -:1024600000000010002122220000000000000000F7 -:1024700000294907000000000000001000221E2370 -:102480000000000000000000003120C40000000037 -:102490000000FFFF002822280000000000000000CC -:1024A000002949070000000000000000003808C5AE -:1024B00000000000000000000030084100000000A3 -:1024C0000000000100220A220000000000000000BD -:1024D000003308A2000000000000001000221E22AD -:1024E0000000000000000010002122220000000077 -:1024F00000000000008949070000000000000017EC -:102500000020222D000000000000000014C0000088 -:1025100000000318FFFFFFEF002806210000000065 -:10252000000000140020222D000000000000F8E050 -:1025300000204411000000000000000000294901B3 -:1025400000000000000000000089490100000000B8 -:102550000000000000204811000000000000000002 -:102560000020481100000000060A02000080481107 -:102570000000000000000000C0200000000000007B -:1025800097000000C020441100000000000000007F -:10259000C0204811000000008A0000000020441103 -:1025A00000000000000000000020481100000000B2 -:1025B0000000225C00204411000000000000000028 -:1025C000C0204800000000000000A1FC00204411D1 -:1025D0000000000000000000C020480000000000D3 -:1025E00000000000C0200400000000000000000007 -:1025F00000A0000A00000000970000000020441125 -:102600000000000000000000002048110000000051 -:102610008A000000002044110000000000000000BB -:1026200000204811000000000000225C002044113E -:102630000000000000000000C02048000000000072 -:102640000000A1FC00204411000000000000000078 -:10265000C02048000000000000000000C02004006E -:10266000000000000000000000A0000A00000000C0 -:10267000970000000020441100000000000000004E -:1026800000204811000000008A00000000204411D2 -:1026900000000000000000000020481100000000C1 -:1026A0000000225C00204411000000000000000037 -:1026B000C0204800000000000000A1FC00204411E0 -:1026C0000000000000000000C020480000000000E2 -:1026D0000001A1FD002044110000000000000000E6 -:1026E000D90048000000000000000000C0200400E5 -:1026F000000000000000000000A0000A0000000030 -:1027000000002257002044110000000000000003D8 -:10271000C0484A20000000000000225D0020441153 -:102720000000000000000000C04048000000000061 -:1027300000000000006000000000064200000000F1 -:10274000C0200800000000000000225C00204411AE -:10275000000000000000000300384A2200000000D2 -:102760000000A1FC00204411000000000000000057 -:10277000C0204800000000000001A1FD002044111D -:102780000000000000000000002F022200000000F6 -:10279000000000000CE0000000000000000000004D -:1027A00040204800000000000000000140304A20A6 -:1027B0000000000000000002C0304A2000000000BD -:1027C0000000000100530A220000034B0000003FFC -:1027D000C0280A20000000008100000000204411F1 -:1027E000000000000000000100204811000000006F -:1027F000000021F800204411000000000000001833 -:102800000020481100000000000421F9006044117C -:102810000000068A000000110021023000000000C4 -:102820000000000014E00000000003540000001449 -:10283000002F022200000000000000000CC0000079 -:10284000000003640000201000204411000000007C -:102850000000800000204811000000000001A2A438 -:102860000020441100000000000000000060480249 -:102870000000036E00002100002044110000000051 -:1028800000000000C0204800000000000000000020 -:10289000C02048000000000000000000C0204800E8 -:1028A0000000000000000000C040480000000000E0 -:1028B00000000004002F02220000000000000000C1 -:1028C0000CC000000000036A00002010002044112A -:1028D00000000000000080000020481100000000FF -:1028E0000001A2A40020441100000000000000002C -:1028F000004048020000035F00000028002F022271 -:1029000000000000000000000CC00000000005BD39 -:102910000001A2A4002044110000000000000000FB -:10292000004048020000035F0000002C0020362613 -:102930000000000000000049002018110000000005 -:102940000000003F002048110000000000000001CE -:1029500000331A260000000000000000002F0226AD -:1029600000000000000000000CC000000000037028 -:102970000000002C00801A2D000000000000003F25 -:10298000C0280A200000000000000015002F0222CD -:1029900000000000000000000CE0000000000386C2 -:1029A00000000006002F02220000000000000000CE -:1029B0000CE00000000003B100000016002F02220E -:1029C00000000000000000000CE00000000003B563 -:1029D00000000020002F0222000000000000000084 -:1029E0000CE000000000039C0000000F002F0222FA -:1029F00000000000000000000CE00000000003A840 -:102A000000000010002F0222000000000000000063 -:102A10000CE00000000003A80000001E002F0222AE -:102A200000000000000000000CE000000000039027 -:102A30000000A2A4002044110000000000000000DB -:102A400000404802000000000800000000290A229F -:102A5000000000000000000340210E2000000000E4 -:102A60000000000CC021122000000000000800003F -:102A7000002812240000000000000014C0221620CC -:102A80000000000000000000002914A40000000065 -:102A90000000A2A40020441100000000000000007B -:102AA000002948A2000000000000A1FE00204411FF -:102AB000000000000000000000404803000000008B -:102AC000810000000020441100000000000000010F -:102AD0000020481100000000000021F800204411EF -:102AE0000000000000000016002048110000000057 -:102AF000000421F9006044110000068A000000155E -:102B000000210230000000000000000014E000007E -:102B1000000003920000210E00204411000000007C -:102B200000000000C020480000000000000000007D -:102B3000C0204800000000000000A2A400204411B2 -:102B400000000000000000000040480200000000FB -:102B5000810000000020441100000000000000017E -:102B60000020481100000000000021F8002044115E -:102B700000000000000000170020481100000000C5 -:102B8000000421F9006044110000068A00000003DF -:102B900000210230000000000000000014E00000EE -:102BA0000000039E000021080020441100000000E6 -:102BB00000000000C02048000000000000000000ED -:102BC000C0204800000000000000A2A40020441122 -:102BD000000000000000000000404802000000006B -:102BE0000000A2A40020441100000000000000002A -:102BF0000020480200000000800000000020441176 -:102C0000000000000000000000204811000000004B -:102C100081000000002044110000000000000010AE -:102C200000204811000000000000000000200010FB -:102C3000000000000000000014C00000000003AE0F -:102C40000000000000400000000000000000201014 -:102C50000020441100000000000080000020481106 -:102C6000000000000001A2A40020441100000000A8 -:102C70000000000600404811000000000000201085 -:102C800000204411000000000000800000204811D6 -:102C9000000000000001A2A4002044110000000078 -:102CA00000000016006048110000036E00000000E4 -:102CB000004000000000000000000000C0200800EC -:102CC0000000000000000000C0200C000000000018 -:102CD0000000001D00210223000000000000000091 -:102CE00014E00000000003CE810000000020441129 -:102CF000000000000000000100204811000000005A -:102D0000000021F80020441100000000000000181D -:102D10000020481100000000000421F90060441167 -:102D20000000068A000000110021023000000000AF -:102D30000000000014E00000000003C000002100BB -:102D400000204411000000000000000000204802A4 -:102D50000000000000000000002048030000000008 -:102D6000BABECAFE0020481100000000CAFEBABE6A -:102D70000020481100000000000020100020441135 -:102D8000000000000000800000204811000000004A -:102D90000000A2A400204411000000000000000474 -:102DA0000040481100000000000021700020441184 -:102DB00000000000000000000020480200000000A9 -:102DC0000000000000204803000000008100000017 -:102DD00000204411000000000000000A00204811FB -:102DE00000000000000000000020001000000000B3 -:102DF0000000000014C00000000003D38C0000009D -:102E00000020441100000000CAFEBABE0040481174 -:102E100000000000810000000020441100000000BC -:102E200000000001002048110000000000003FFFEA -:102E300040280A20000000008000000040280E20EA -:102E40000000000040000000C02812200000000028 -:102E500000040000006946220000068A000000000D -:102E6000002014100000000000000000002F0223CA -:102E700000000000000000000CC00000000003E1A2 -:102E800000000000C0401800000003E400003FFF05 -:102E9000C0281A2000000000000400000069462637 -:102EA0000000068A0000000000201810000000004A -:102EB00000000000002F02240000000000000000BD -:102EC0000CC00000000003E700000000C0401C0030 -:102ED000000003EA00003FFFC0281E2000000000A1 -:102EE00000040000006946270000068A0000000078 -:102EF00000201C1000000000000000000020440220 -:102F00000000000000000000002820C500000000B4 -:102F100000000000004948E800000000A580000013 -:102F200000200811000000000000200000200C110B -:102F30000000000083000000006044110000041243 -:102F4000000000000020440200000000000000001B -:102F5000C0204800000000000000000040204800A1 -:102F6000000000000000001FC0210220000000003F -:102F70000000000014C00000000003F70000201053 -:102F800000204411000000000000800000204811D3 -:102F9000000000000000FFFFC0481220000003FFF7 -:102FA000A780000000200811000000000000A00021 -:102FB00000200C110000000083000000006044119C -:102FC0000000041200000000002044020000000085 -:102FD00000000000C02048000000000000000000C9 -:102FE000C0204800000000000000FFFFC0281220A1 -:102FF00000000000830000000020441100000000D9 -:103000000000000000304883000000008400000041 -:10301000002044110000000000000000C020480013 -:1030200000000000000000001D0000000000000083 -:103030008300000000604411000004120000000042 -:10304000C040040000000001A98000000020081119 -:10305000000000000000C00000400C11000003FA56 -:10306000AB80000000200811000000000000F8E024 -:1030700000400C11000003FAAD8000000020081190 -:10308000000000000000F88000400C11000003FA6E -:10309000B380000000200811000000000000F3FCD5 -:1030A00000400C11000003FAAF800000002008115E -:1030B000000000000000E00000400C11000003FAD6 -:1030C000B180000000200811000000000000F000A6 -:1030D00000400C11000003FA83000000002044119E -:1030E00000000000000021480020481100000000FE -:1030F00084000000002044110000000000000000D7 -:10310000C020480000000000000000001D0000007A -:10311000000000000000000000800000000000002F -:1031200001182000C0304620000000000000000010 -:10313000D90048000000000000000000C02004008A -:10314000000000000000000000A0000A00000000D5 -:103150000218A000C030462000000000000000005F -:10316000D90048000000000000000000C02004005A -:10317000000000000000000000A0000A00000000A5 -:103180000318C000C030462000000000000000000E -:10319000D90048000000000000000000C02004002A -:1031A000000000000000000000A0000A0000000075 -:1031B0000418F8E0C03046200000000000000000C5 -:1031C000D90048000000000000000000C0200400FA -:1031D000000000000000000000A0000A0000000045 -:1031E0000518F880C03046200000000000000000F4 -:1031F000D90048000000000000000000C0200400CA -:10320000000000000000000000A0000A0000000014 -:103210000618E000C030462000000000000000005A -:10322000D90048000000000000000000C020040099 -:10323000000000000000000000A0000A00000000E4 -:103240000718F000C0304620000000000000000019 -:10325000D90048000000000000000000C020040069 -:10326000000000000000000000A0000A00000000B4 -:103270000818F3FCC03046200000000000000000E9 -:10328000D90048000000000000000000C020040039 -:10329000000000000000000000A0000A0000000084 -:1032A0000000003000200A2D000000000000000097 -:1032B000C0290C4000000000000000300020362330 -:1032C0000000000000000000C0200400000000001A -:1032D0000000000000A0000A0000000086000000BE -:1032E00000204411000000000000000000404801E0 -:1032F0000000000085000000C02044110000000014 -:103300000000000000404801000000000000217C97 -:10331000002044110000000000000000C020480010 -:103320000000000000000000C02048000000000075 -:1033300000000000C02048000000000081000000E4 -:10334000002044110000000000000001002048118E -:103350000000000000000000C02008000000000085 -:103360000000000017000000000000000004217FA2 -:10337000006044110000068A0000001F0021023096 -:10338000000000000000000014C000000000000069 -:103390000000000000404C02000004480000000053 -:1033A000C0200C000000000000000000C020100041 -:1033B0000000000000000000C02014000000000019 -:1033C00000000000C0201800000000000000000005 -:1033D000C0201C000000000000007F0000280A211F -:1033E0000000000000004500002F02220000000045 -:1033F000000000000CE00000000004560000000087 -:10340000C0202000000000000000000017000000A5 -:10341000000000000000001000280A230000000047 -:1034200000000010002F0222000000000000000039 -:103430000CE000000000045E810000000020441148 -:103440000000000000000001002048110000000002 -:1034500000040000006946240000068A0000000005 -:1034600000400000000004638100000000204411BF -:1034700000000000000000000020481100000000D3 -:103480000000216D00204411000000000000000039 -:103490000020480400000000000000000060480513 -:1034A0000000068F00000000002824F0000000004B -:1034B0000000000700280A230000000000000001AF -:1034C000002F022200000000000000000AE00000BF -:1034D0000000046A00000000002F00C90000000086 -:1034E0000000000004E00000000004830000000071 -:1034F000004000000000049000000002002F0222A3 -:1035000000000000000000000AE000000000046F5E -:1035100000000000002F00C90000000000000000B3 -:1035200002E00000000004830000000000400000F2 -:103530000000049000000003002F022200000000A1 -:10354000000000000AE00000000004740000000019 -:10355000002F00C900000000000000000CE0000087 -:103560000000048300000000004000000000049000 -:1035700000000004002F02220000000000000000F4 -:103580000AE000000000047900000000002F00C9DC -:1035900000000000000000000AE0000000000483BA -:1035A0000000000000400000000004900000000542 -:1035B000002F022200000000000000000AE00000CE -:1035C0000000047E00000000002F00C90000000081 -:1035D0000000000006E0000000000483000000007E -:1035E000004000000000049000000006002F0222AE -:1035F00000000000000000000AE00000000004835A -:1036000000000000002F00C90000000000000000C2 -:1036100008E00000000004830000000000400000FB -:103620000000049000007F0000280A210000000034 -:1036300000004500002F02220000000000000000F2 -:103640000AE00000000000000000000800210A233A -:10365000000000000000000014C000000000048D05 -:10366000000021690020441100000000000000005B -:10367000C02048000000000000000000C0204800FA -:103680000000000000000000C02048000000000012 -:10369000CAFEBABE00404811000000000000000051 -:1036A000C02044000000000000000000C020000016 -:1036B0000000000000000000C040480000000000C2 -:1036C00000007F0000280A210000000000004500E3 -:1036D000002F022200000000000000000AE00000AD -:1036E0000000049600000000C02000000000000060 -:1036F00000000000C02000000000000000000000EA -:10370000C0400000000000000000000000404C0825 -:103710000000045600000000C02008000000000067 -:103720000000001040210E200000000000000011E9 -:10373000402112200000000000000012402116204D -:10374000000000000000216900204411000000007A -:1037500000000000002048020000000000000000FF -:1037600000210225000000000000000014E000001D -:10377000000004A000040000C0494A20000004A189 -:10378000FFFBFFFFC0284A200000000000000000EF -:1037900000210223000000000000000014E00000EF -:1037A000000004AD00000000C02048000000000040 -:1037B00000000000C02048000000000000000000E1 -:1037C00000210224000000000000000014C00000DE -:1037D00000000000810000000020441100000000F3 -:1037E0000000000C00204811000000000000000054 -:1037F00000200010000000000000000014C00000C5 -:10380000000004A9A00000000020441100000000F6 -:10381000CAFEBABE0040481100000000810000004E -:1038200000204411000000000000000400204811A6 -:10383000000000000000216B002044110000000087 -:1038400000000000C02048100000000081000000BF -:103850000020441100000000000000050020481175 -:10386000000000000000216C002044110000000056 -:1038700000000000C0204810000000000000000010 -:10388000002F022400000000000000000CE00000F7 -:10389000000000000000000000400000000004A73D -:1038A00000000000C0210A2000000000000000000D -:1038B00014C00000000004C081000000002044117A -:1038C000000000000000000000204811000000007F -:1038D0000000216D002044110000000000000000E5 -:1038E000C02048000000000000000000C060480048 -:1038F0000000068F0000000000400000000004C42B -:1039000081000000002044110000000000000001C0 -:10391000002048110000000000040000C0294620DB -:103920000000000000000000C06000000000068AE7 -:103930000000000100210222000000000000000041 -:1039400014C00000000004CB0000216900204411D5 -:103950000000000000000000C0204800000000003F -:1039600000000000C020480000000000000000002F -:103970000020481000000000CAFEBABE00404811F6 -:103980000000000000000000C02044000000000013 -:1039900000000000C040481000000000810000004E -:1039A0000020441100000000000000010020481128 -:1039B00000000000000021F8002044110000000079 -:1039C0000000000E0020481100000000000421F952 -:1039D000006044110000068A00000000002102304F -:1039E000000000000000000014C00000000004CD32 -:1039F00000002180002044110000000000000000B1 -:103A0000C02048000000000000000000C0200000AE -:103A10000000000000000000C0204800000000007E -:103A200000000000C02000000000000000000000B6 -:103A3000C0404800000000000000000300333E2F9B -:103A40000000000000000001002102210000000031 -:103A50000000000014E00000000004FD0000002C45 -:103A600000200A2D000000000004000018E00C11E6 -:103A7000000004EC0000000100333E2F00000000B5 -:103A80000000216900204411000000000000000037 -:103A90000020480200000000000000000020480351 -:103AA000000000000000000800300A2200000000B2 -:103AB00000000000C02048000000000000000000DE -:103AC000C0204800000000000000216900204411CF -:103AD000000000000000000000204802000000007C -:103AE0000000000000204803000000000000000863 -:103AF00000300A220000000000000000C020480042 -:103B00000000000000000000D8C04800000004E0F1 -:103B100000002169002044110000000000000000A6 -:103B200000204802000000000000000000204803C0 -:103B3000000000000000000800300A220000000021 -:103B400000000000C020480000000000000000004D -:103B5000C0204800000000000000002D0020122DB1 -:103B6000000000000000000000290C83000000009D -:103B70000000216900204411000000000000000046 -:103B80000020480200000000000000000020480360 -:103B9000000000000000000800300A2200000000C1 -:103BA00000000000C02048000000000000000000ED -:103BB000C020480000000000000000110021022485 -:103BC000000000000000000014C000000000000021 -:103BD0000000000000400000000004A70000002CCE -:103BE000C0203620000000000000002DC04036201C -:103BF000000000000000000F002102210000000072 -:103C00000000000014C000000000050200000000D9 -:103C1000006000000000000B00000000D900000060 -:103C20000000000000000000C0400400000000018F -:103C3000B50000000020441100000000000020003A -:103C40000020481100000000B600000000204411D0 -:103C5000000000000000A00000204811000000004B -:103C6000B700000000204411000000000000C00068 -:103C70000020481100000000B8000000002044119E -:103C8000000000000000F8E00020481100000000E3 -:103C9000B900000000204411000000000000F8807E -:103CA0000020481100000000BA000000002044116C -:103CB000000000000000E0000020481100000000AB -:103CC000BB00000000204411000000000000F000D4 -:103CD0000020481100000000BC000000002044113A -:103CE000000000000000F3FC00204811000000006C -:103CF00081000000002044110000000000000002CC -:103D00000020481100000000000000FF00280E30D5 -:103D10000000000000000000002F0223000000004F -:103D2000000000000CC000000000051600000000AC -:103D3000C0200800000000000000000014C00000C7 -:103D40000000052B0000000000200C110000000006 -:103D50000000001C00203623000000000000002BA3 -:103D60000020362300000000000000290020362338 -:103D700000000000000000280020362300000000A2 -:103D8000000000170020362300000000000000257E -:103D9000002036230000000000000026002036230B -:103DA0000000000000000015002036230000000085 -:103DB000000000160020362300000000FFFFE00096 -:103DC00000200C110000000000000021002036231C -:103DD0000000000000000022002036230000000048 -:103DE00000001FFF00200C11000000000000002355 -:103DF00000203623000000000000002400203623AD -:103E000000000000F1FFFFFF00283A2E0000000034 -:103E10000000001AC0220E20000000000000000078 -:103E20000029386E000000008100000000204411CD -:103E30000000000000000006002048110000000003 -:103E40000000002A4020362000000000870000000B -:103E5000002044110000000000000000C0204800C5 -:103E6000000000000000A1F4002044110000000048 -:103E700000000000002048100000000000000000CA -:103E800000200C110000000000000030002036234C -:103E9000000000009D000000002044110000000010 -:103EA0000000001F40214A20000000009600000092 -:103EB000002044110000000000000000C020480065 -:103EC0000000000000000000C0200C000000000006 -:103ED00000000000C0201000000000000000001FD3 -:103EE00000211624000000000000000014C00000A3 -:103EF000000000000000001D00203623000000002C -:103F00000000000300281E2300000000000000083D -:103F10000022222300000000FFFFF00000282228DA -:103F20000000000000000000002920E80000000060 -:103F30000000001F002036280000000000000018CC -:103F400000211E2300000000000000200020362772 -:103F50000000000000000002002216240000000003 -:103F600000000000003014A8000000000000001E47 -:103F700000203625000000000000000300211A2464 -:103F8000000000001000000000281A2600000000B9 -:103F9000EFFFFFFF00283A2E0000000000000000A5 -:103FA000004938CE000006780000000140280A20B1 -:103FB000000000000000000640280E200000000065 -:103FC00000000300C02812200000000000000008CC -:103FD000002112240000000000000000C020162074 -:103FE0000000000000000000C0201A2000000000B7 -:103FF000000000000021022200000000000000007C -:1040000014C000000000056381000000002044117E -:104010000000000000000001002048110000000026 -:104020000000225800300A240000000000040000B4 -:10403000006946220000068A000021690020441120 -:104040000000000000000000002048050000000003 -:104050000002000000294A260000000000000000C5 -:104060000020481000000000CAFEBABE002048111F -:104070000000000000000002002F022300000000EA -:10408000000000000CC000000000056B00000000F4 -:10409000C0201C100000000000000000C040000014 -:1040A0000000057900000002002F0223000000003C -:1040B000000000000CC000000000056B8100000043 -:1040C0000020441100000000000000010020481101 -:1040D000000000000000225800300A240000000008 -:1040E00000040000006946220000068A000000006B -:1040F000C0201C100000000000000000C0400000B4 -:104100000000057900000000002F022300000000DD -:10411000000000000CC000000000056F000000005F -:10412000C0201C000000000000000000C040000093 -:104130000000057900000004002F022300000000A9 -:10414000000000000CC000000000057781000000A6 -:104150000020441100000000000000000020481171 -:10416000000000000000216D00204411000000004C -:1041700000000000C0204800000000000000000017 -:10418000C06048000000068F0000000000401C10C6 -:104190000000057900000000C020000000000000C1 -:1041A00000000000C040000000000000000000000F -:1041B0000EE000000000057B000000000060000031 -:1041C000000005C600000000002F022400000000CF -:1041D000000000000CC000000000058C0000A2B729 -:1041E00000204411000000000000000000204807EB -:1041F00000000000810000000020441100000000C9 -:104200000000000100204811000000000004A2B6D8 -:10421000006044110000068A0000001A00212230CC -:104220000000000000000006002226300000000010 -:1042300000042004006044110000068A0000A2C4AB -:10424000002044110000000000000000003048E998 -:10425000000000000000000000E000000000058AEF -:104260000000A2D100204411000000000000000066 -:1042700000404808000000000000A2D100204411C6 -:10428000000000000000000100504A28000000006B -:1042900000000001002F02240000000000000000C8 -:1042A0000CC000000000059D0000A2BB00204411CE -:1042B000000000000000000000204807000000008F -:1042C00081000000002044110000000000000001F7 -:1042D00000204811000000000004A2BA0060441150 -:1042E0000000068A0000001A0021223000000000B1 -:1042F0000000000600222630000000000004200418 -:10430000006044110000068A0000A2C5002044118C -:104310000000000000000000003048E9000000003C -:104320000000000000E000000000059B0000A2D299 -:104330000020441100000000000000000040480878 -:10434000000000000000A2D2002044110000000084 -:104350000000000100504A28000000000000000298 -:10436000002F022400000000000000000CC000002C -:10437000000005AE0000A2BF0020441100000000B4 -:10438000000000000020480700000000810000003D -:10439000002044110000000000000001002048112E -:1043A000000000000004A2BE006044110000068A64 -:1043B0000000001A0021223000000000000000066A -:1043C0000022263000000000000420040060441198 -:1043D0000000068A0000A2C6002044110000000070 -:1043E00000000000003048E900000000000000006C -:1043F00000E00000000005AC0000A2D30020441142 -:10440000000000000000000000404808000000001C -:104410000000A2D3002044110000000000000001B1 -:1044200000504A28000000000000A2C300204411F0 -:10443000000000000000000000204807000000000D -:104440008100000000204411000000000000000175 -:1044500000204811000000000004A2C200604411C6 -:104460000000068A0000001A00212230000000002F -:104470000000000600222630000000000004200496 -:10448000006044110000068A0000A2C70020441109 -:104490000000000000000000003048E900000000BB -:1044A0000000000000E00000000005BB0000A2D4F6 -:1044B00000204411000000000000000000404808F7 -:1044C000000000000000A2D4002044110000000001 -:1044D0000000000100504A28000000008500000094 -:1044E00000204411000000000000000000204801EE -:1044F000000000000000304A0020441100000000CD -:104500000100000000204811000000000000000031 -:1045100000400000000005C1A4000000C0204411BC -:104520000000000000000000C04048000000000043 -:1045300000000000C0600000000005C60000000090 -:10454000C0400400000000010000002C00203621C3 -:104550000000000081000000002044110000000065 -:1045600000000006002048110000000000000000CC -:10457000002F023000000000000000000CC000000E -:10458000000005CD00000000002004110000000024 -:104590000000003000403621000005E0000000303F -:1045A0000020062D0000000000007E0000280621EB -:1045B0000000000000000000002F022100000000A9 -:1045C000000000000CE00000000005E08100000099 -:1045D00000204411000000000000000100204811EC -:1045E000000000000004A092006044110000068A50 -:1045F0000000003100203630000000000004A093CD -:10460000006044110000068A0000003200203630AD -:10461000000000000004A2B6006044110000068AF9 -:104620000000003300203630000000000004A2BA71 -:10463000006044110000068A00000034002036307B -:10464000000000000004A2BE006044110000068AC1 -:104650000000003500203630000000000004A2C237 -:10466000006044110000068A000000360020363049 -:104670000000000000042004006044110000068ACD -:104680000001A2A400204411000000000000003F2F -:1046900000204811000000000000003F00204811E9 -:1046A000000000000000003F002048110000000052 -:1046B0000000003F0020481100000000000000053D -:1046C00000204811000000000000A1F40020441167 -:1046D0000000000000000000002048110000000061 -:1046E00088000000002044110000000000000001CC -:1046F000002048110000000081000000002044114B -:10470000000000000000000600204811000000002A -:1047100000000001002F0230000000000000000037 -:104720000CE0000000000629000000300020062DEB -:104730000000000000000000002F02210000000027 -:10474000000000000CE000000000062981000000CD -:10475000002044110000000000000001002048116A -:104760000000000000007E0000280621000000007C -:1047700000000000002F02210000000000000000E7 -:104780000CE00000000006020000A092002044118E -:10479000000000000000003100204A2D0000000051 -:1047A0000000A0930020441100000000000000322F -:1047B00000204A2D000000000000A2B60020441195 -:1047C000000000000000003300204A2D000000001F -:1047D0000000A2BA002044110000000000000034D4 -:1047E00000204A2D000000000000A2BE002044115D -:1047F000000000000000003500204A2D00000000ED -:104800000000A2C200204411000000000000003699 -:1048100000204A2D00000000000000300020062D7E -:1048200000000000000001FF002806210000000039 -:1048300000000000002F0221000000000000000026 -:104840000CE000000000062800000000002102210A -:10485000000000000000000014C000000000060B73 -:104860000004A003006044110000068A0000A003B9 -:10487000002044110000000000000000002048104B -:1048800000000000000000010021062100000000DF -:104890000000000014C00000000006100004A0107A -:1048A000006044110000068A0000A010002044119E -:1048B0000000000000000000002048100000000080 -:1048C000000000010021062100000000000000009F -:1048D000002F022100000000000000000CE000009A -:1048E000000006280004A011006044110000068AA0 -:1048F0000000A01100204411000000000000000092 -:1049000000204810000000000004A01200604411C4 -:104910000000068A0000A0120020441100000000E0 -:104920000000000000204810000000000004A01358 -:10493000006044110000068A0000A013002044110A -:1049400000000000000000000020481000000000EF -:104950000004A014006044110000068A0000A014A6 -:10496000002044110000000000000000002048105A -:10497000000000000004A015006044110000068A39 -:104980000000A015002044110000000000000000FD -:1049900000204810000000000004A0160060441130 -:1049A0000000068A0000A01600204411000000004C -:1049B0000000000000204810000000000004A017C4 -:1049C000006044110000068A0000A0170020441176 -:1049D000000000000000000000204810000000005F -:1049E00000042004006044110000068A0000002C2E -:1049F0000080062D00000000FF0000000020441190 -:104A0000000000000000000000204811000000002D -:104A1000000000010020481100000000000000021A -:104A20000080481100000000000000000EE00000BF -:104A30000000063A000000300020062D00000000B3 -:104A40000000000200280621000000000000000015 -:104A5000002F022100000000000000000CE0000018 -:104A60000000063881000000002044110000000012 -:104A70000000000100204811000000000004200494 -:104A8000006044110000068A000010000020081198 -:104A9000000000000000002B002036220000000073 -:104AA00000000000006000000000063E0000000062 -:104AB00000600000000005C69800000000204411BE -:104AC000000000000000000000804811000000000D -:104AD00000000000C06000000000063E0000000072 -:104AE000C0400400000000010000A2A40020441106 -:104AF000000000000000002200204811000000001B -:104B000089000000002044110000000000000001A6 -:104B1000004048110000062A9700000000204411C0 -:104B2000000000000000000000204811000000000C -:104B30008A00000000204411000000000000000076 -:104B4000004048110000062A00000000006000003C -:104B50000000065900002010002044110000000051 -:104B60000000800000204811000000000001A2A405 -:104B7000C020441100000000000000160060481131 -:104B80000000036E0000201000204411000000000F -:104B9000000100000020481100000000810000001A -:104BA0000020441100000000000000010020481116 -:104BB000000000000000217C0020441100000000E3 -:104BC000098000000020481100000000FFFFFFFFE7 -:104BD00000204811000000000000000000204811E3 -:104BE00000000000000000001700000000000000AE -:104BF0000004217F006044110000068A0000001FAD -:104C000000210230000000000000000014C000007D -:104C1000000000000000000400404C11000006539A -:104C2000000000000040000000000000000000172D -:104C300000201E2D000000000000000400291E2797 -:104C40000000000000000017008036270000000070 -:104C50000000001700201E2D00000000FFFFFFFBDA -:104C600000281E27000000000000001700803627E3 -:104C7000000000000000001700201E2D00000000B2 -:104C80000000000800291E27000000000000001797 -:104C900000803627000000000000001700201E2DB5 -:104CA00000000000FFFFFFF700281E2700000000A3 -:104CB00000000017008036270000000000002010D0 -:104CC0000020441100000000000080000020481176 -:104CD000000000000001A2A4002044110000000018 -:104CE00000000016006048110000036E0000201054 -:104CF00000204411000000000001000000204811C5 -:104D0000000000000000217C002044110000000091 -:104D1000018000000020481100000000FFFFFFFF9D -:104D20000020481100000000000000000020481191 -:104D3000000000000000000017000000000000005C -:104D4000810000000020441100000000000000016C -:104D500000204811000000000004217F0060441181 -:104D60000000068A0000001F002102300000000041 -:104D70000000000014C000000000068900000010C0 -:104D800000404C110000066F00000000C02004002D -:104D9000000000000000000038C00000000000001B -:104DA0000000001D00200A2D000000000000001E71 -:104DB00000200E2D000000000000001F0020122D1A -:104DC00000000000000000200020162D0000000060 -:104DD00000002169002044110000000000000000D4 -:104DE00000204804000000000000000000204805EA -:104DF000000000000000000000204801000000004A -:104E0000CAFEBABE002048110000000000000004E5 -:104E1000003012240000000000000000002F006499 -:104E200000000000000000000CC000000000068828 -:104E30000000000300281A22000000000000000803 -:104E40000022122200000000FFFFF00000281224C0 -:104E50000000000000000000002910C40000000055 -:104E60000000001F00403624000000000000000089 -:104E70000080000000000000000000001AC00000D8 -:104E80000000068A9F00000000204411000000007E -:104E9000CAFEBABE00204811000000000000000059 -:104EA0001AE000000000068D0000000000800000F5 -:104EB00000000000000000001AC000000000068F83 -:104EC0009E0000000020441100000000CAFEBABE8F -:104ED0000020481100000000000000001AE000005F -:104EE00000000692000000000080000000000000AA -:104EF00000000000006000000000000B0000100037 -:104F000000600411000003150000000000200411DF -:104F1000000000000000000000600811000001B265 -:104F20000000225C0020441100000000000000038B -:104F3000002048110000000000002256002044110B -:104F4000000000000000001B0020481100000000CD -:104F50000000A1FC0020441100000000000000013E -:104F600000204811000000000001A1FDC0204411F4 -:104F7000000000000000002100201E2D00000000A5 -:104F80000000001000221E27000000000000002486 -:104F90000020222D000000000000FFFF0028222832 -:104FA0000000000000000000002949070000000088 -:104FB0000000000000204811000000000000002256 -:104FC0000020222D000000000000FFFF0028222802 -:104FD0000000000000000000002949070000000058 -:104FE0000000000000204811000000000000002325 -:104FF00000201E2D000000000000001000221E27CF -:105000000000000000000000002949070000000027 -:1050100000000000004048110000000000000000F7 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B000014204FF05BD02500000000001C3016867 -:1052C000043F05BD00000000022502090250015103 -:1052D000000000000223024502A00241000000007D -:1052E00003D705BD05BD05BD000000000646064705 -:1052F000031F05BD0000000005BD05C203200340DB -:1053000000000000032A0282034203340000000070 -:1053100005BD05BD05BD05BD0000000005BD054E70 -:1053200005BD05BD0000000003BA05BD04B8034477 -:10533000000000000497044D043D05BD000000007E -:1053400004CD05BD044104DA00000000044D05044D -:10535000035103750000000005BD05BD05BD05BD79 -:105360000000000005BD05BD05BD05BD0000000035 -:1053700005BD05BD063C05C40000000005BD05BD1A -:10538000000705BD0000000005BD05BD05BD05BD4C -:105390000000000005BD05BD05BD05BD0000000005 -:1053A00003F803ED0408040600000000040E040ADC -:1053B000040C041000000000041C04180424042041 -:1053C00000000000042C0428043404300000000015 -:1053D00005BD05BD043805BD0000000005BD05BDC7 -:1053E00005BD05BD0000000005BD05BD05BD05BD31 -:1053F000000000000002067606940006000000008F -:00000001FF diff --git a/firmware/radeon/RV630_pfp.bin.ihex b/firmware/radeon/RV630_pfp.bin.ihex deleted file mode 100644 index f55292c97b7937d5da76127dbb21745b72d8039d..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV630_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000CA040000A00000007E828B007C038BED -:10001000008001B8007C038B00D4401E00EE001E5F -:1000200000CA040000A00000007E828B00C41838C3 -:1000300000CA240000CA2800009581A800C41C3A08 -:1000400000C3C00000CA080000CA0C00007C744B4A -:1000500000C200050099C00000C41C3A007C744C2A -:1000600000C0FFF000042C0400309002007D250049 -:1000700000351402007D350B00255403007CD5802B -:1000800000259C030095C00400D5001B007EDDC147 -:10009000007D9D8000D6801B00D5801B00D4401EB3 -:1000A00000D5401E00D6401E00D6801E00D4801E03 -:1000B00000D4C01E009783D300D5C01E00CA08001C -:1000C0000080001A00CA0C0000E4011E00D4001ECB -:1000D0000080000C00C4183800E4013E00D4001E6B -:1000E0000080000C00C4183800D4401E00EE001E32 -:1000F00000CA040000A00000007E828B00E4011E04 -:1001000000D4001E00D4401E00EE001E00CA0400F1 -:1001100000A00000007E828B00E4013E00D4001E9F -:1001200000D4401E00EE001E00CA040000A0000023 -:10013000007E828B00CA180000D4401E00D5801EAD -:100140000080005300D4007500D4401E00CA08008F -:1001500000CA0C0000CA100000D4801900D4C018D6 -:1001600000D5001700D4801E00D4C01E00D5001E8C -:1001700000E2001E00CA040000A00000007E828B86 -:1001800000CA080000D4806000D4401E0080000037 -:1001900000D4801E00CA080000D4806100D4401E34 -:1001A0000080000000D4801E00CA080000CA0C00B5 -:1001B00000D4401E00D4801600D4C01600D4801E87 -:1001C000008001B800D4C01E00C6084300CA0C005D -:1001D00000CA10000094800400CA140000E420F358 -:1001E00000D4201300D5606500D4E01C00D5201C8D -:1001F00000D5601C008000000006200100C60843F6 -:1002000000CA0C0000CA1000009483F700CA140052 -:1002100000E420F30080007900D4201300C60843D6 -:1002200000CA0C0000CA1000009883EF00CA140036 -:1002300000D400640080008D0000000000C414326F -:1002400000C6184300C4082F0095400500C40C30B8 -:1002500000D4401E0080000000EE001E009583F5D3 -:1002600000C4103100D4403300D5206500D4A01C58 -:1002700000D4E01C00D5201C00E4015E00D4001E68 -:10028000008000000006200100CA1800000A2001BA -:1002900000D6007600C408360098800700C61045D6 -:1002A0000095011000D4001F00D46062008000009F -:1002B00000D4206200CC383500CC1433008401BB5C -:1002C00000D4007200D5401E0080000000EE001E29 -:1002D00000E2001A008401BB00E2001A00CC104BBF -:1002E00000CC0447002C9401007D098B0098400548 -:1002F000007D15CB00D4001A008001B800D4006D39 -:100300000034440100CC0C480098403A00CC2C4A00 -:100310000095800400CC0449008001B800D4001A84 -:1003200000D4C01A00282801008400F000CC10037B -:100330000098801B0004380C008400F000CC1003EF -:100340000098801700043808008400F000CC1003E7 -:100350000098801300043804008400F000CC1003DF -:100360000098801400CC104C009A800900CC144DE9 -:10037000009840DC00D4006D00CC184800D5001A6D -:1003800000D5401A008000C900D5801A0096C0D55B -:1003900000D4006D008001B800D4006E009AC00344 -:1003A00000D4006D00D4006E0080000000EC007FDF -:1003B000009AC0CC00D4006D008001B800D4006E5B -:1003C00000CC140300CC180300CC1C03007D910367 -:1003D000007DD583007D190C0035CC1F0035701FC2 -:1003E000007CF0CB007CD08B00880000007E8E8BE0 -:1003F0000095C00400D4006E008001B800D4001A3B -:1004000000D4C01A00CC080300CC0C0300CC1003AD -:1004100000CC140300CC180300CC1C0300CC240334 -:1004200000CC28030035C41F0036B01F007C704B81 -:100430000034F01F007C704B0035701F007C704B47 -:10044000007D8881007DCCC1007E5101007E9541F8 -:10045000007C9082007CD4C2007C848B009AC00314 -:10046000007C8C8B002C88010098809E00D4006D4D -:100470000098409C00D4006E00CC084C00CC0C4D81 -:1004800000CC104800D4801A00D4C01A00800101AA -:1004900000D5001A00CC083200D40032009482D972 -:1004A00000CA0C0000D4401E0080000000D4001ED2 -:1004B00000E4011E00D4001E00CA080000CA0C009F -:1004C00000CA100000D4401E00CA140000D4801ED0 -:1004D00000D4C01E00D5001E00D5401E00D54034FB -:1004E0000080000000EE001E0028040400E2001A54 -:1004F00000E2001A00D4401A00CA380000CC0803F9 -:1005000000CC0C0300CC0C0300CC0C03009882BD83 -:1005100000000000008401BB00D7A06F0080000035 -:1005200000EE001F00CA040000C2FF0000CC083427 -:1005300000C13FFF007C74CB007CC90B007D010F24 -:10054000009902B0007C738B008401BB00D7A06FC0 -:100550000080000000EE001F00CA080000281900FB -:10056000007D898B009580140028140400CA0C00BB -:1005700000CA100000CA1C0000CA240000E2001FCC -:1005800000D4C01A00D5001A00D5401A00CC1803B8 -:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -:1005A000007D9C4700984297000000000080016198 -:1005B00000D4C01A00D4401E00D4801E0080000069 -:1005C00000EE001E00E4011E00D4001E00D4401EF8 -:1005D00000EE001E00CA040000A00000007E828B16 -:1005E00000E4013E00D4001E00D4401E00EE001EB8 -:1005F00000CA040000A00000007E828B00CA080030 -:1006000000248C06000CCC060098C00600CC104ECE -:100610000099000400D4007300E4011E00D4001E01 -:1006200000D4401E00D4801E0080000000EE001E9A -:1006300000CA080000CA0C000034D01800251001C0 -:100640000095002100C17FFF00CA100000CA1400FD -:1006500000CA180000D4801D00D4C01D007DB18BDD -:1006600000C1420200C2C00100D5801D0034DC0E72 -:10067000007D5D4C007F734C00D7401E00D5001EEE -:1006800000D5401E00C1420000C2C00000099C010C -:100690000031DC10007F5F4C007F734C00042802A7 -:1006A000007D838000D5A86F00D5806600D7401EEE -:1006B00000EC005E00C8240200C82402008001B8DB -:1006C00000D6007600D4401E00D4801E00D4C01E88 -:1006D0000080000000EE001E0080000000EE001F01 -:1006E00000D4001F0080000000D4001F00D4001FB1 -:1006F0000088000000D4001F00000000000000007F -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000010171000201780003008F0004007FE5 -:10081000000500030006003F000700320008012C1D -:1008200000090046000A0036001001B6001700A2B9 -:100830000022013A00230149002000B400240125D0 -:100840000027004D0028006A002A0060002B00529B -:10085000002F0065003200870034017F003C015604 -:10086000003F00720041018C0044012E00550173CD -:100870000056017A0060000B00610034006200380D -:1008800000630038006400380065003800660038F6 -:10089000006700380068003A00690041006A0048BB -:1008A000006B0048006C0048006D0048006E004876 -:1008B000006F00480000000600000006000000066F -:1008C0000000000600000006000000060000000610 -:1008D0000000000600000006000000060000000600 -:1008E00000000006000000060000000600000006F0 -:1008F00000000006000000060000000600000006E0 -:00000001FF diff --git a/firmware/radeon/RV635_me.bin.ihex b/firmware/radeon/RV635_me.bin.ihex deleted file mode 100644 index ba3a7e632d97f03ee553ea7ece2cf6a7f65b1105..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV635_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A000006044110000068A0000000000600000AB -:1000B0000000062E00000000006000000000064264 -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E000000000000000001800203625000000007D -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000002800204A2D8B -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000001900203625C9 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001700200E2D5A -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001718 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000270020362410 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:10038000000000000000000E0020362300000000E6 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E23000000000000000FC9 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000002700204A2D000000004F -:1003F000000000000020481100000000000000295B -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A00000000000002048040000000000000030AF -:1005B0000020162D00000000000000020029162572 -:1005C0000000000000000030002036250000000080 -:1005D000000000250020162D000000000000000093 -:1005E000002F00A300000000000000000CC000006D -:1005F00000000083000000260020162D00000000EF -:1006000000000000002F00A4000000000000000017 -:100610000CC000000000008400000000004000004A -:100620000000008A000000250020362300000000A2 -:100630000000002600203624000000000000001703 -:1006400000201E2D000000000000000200210227F3 -:10065000000000000000000014E000000000008A1C -:1006600000000000006000000000066500000000BF -:1006700000600000000006590000000200210E2268 -:10068000000000000000000014C000000000008D09 -:1006900000000012C040362000000093000000005F -:1006A0002EE0000000000091000000002CE000009F -:1006B000000000900000000200400E2D000000929B -:1006C0000000000300400E2D000000920000000C0E -:1006D00000200E2D00000000000000120020362334 -:1006E000000000000000000300210E2200000000B6 -:1006F0000000000014C00000000000980000A00CE2 -:10070000002044110000000000000000C02048004C -:100710000000000000000000C0404800000000A0F1 -:100720000000A00C002044110000000000000000A8 -:100730000020481100000000000000002EE0000032 -:100740000000009E000000002CE000000000009D62 -:100750000000000200400E2D0000009F000000037A -:1007600000400E2D0000009F0000000C00200E2D08 -:10077000000000000000000000204803000000000E -:1007800000000000003A0C0200000000003F0000E2 -:1007900000280E23000000000000001000210E239E -:1007A00000000000000000110020362300000000BF -:1007B0000000001E0021022B0000000000000000CD -:1007C00014C00000000000A700000016C020362062 -:1007D000000000000000001F0021022B00000000AC -:1007E0000000000014C00000000000AA0000001576 -:1007F000C0203620000000000000000800210E2B61 -:10080000000000000000007F00280E230000000010 -:1008100000000000002F0223000000000000000084 -:100820000CE00000000000E10000000027000000D4 -:10083000000000000000000000600000000002A3B3 -:1008400000000001002F0223000000000000000053 -:100850000AE00000000000B300000000006000009B -:100860000000013A81000000002044110000000057 -:100870000000000600204811000000000000000CED -:1008800000221E300000000099800000002044116A -:1008900000000000000000040020122D00000000F5 -:1008A00000000008002212240000000000000010D8 -:1008B00000201811000000000000000000291CE4C6 -:1008C0000000000000000000006048070000012F49 -:1008D0009B00000000204411000000000000000008 -:1008E00000204802000000009C000000002044118D -:1008F00000000000000000000033146F0000000042 -:100900000000000100333E23000000000000000052 -:10091000D9004800000000000000000000203C0555 -:1009200000000000810000000020441100000000D1 -:100930000000000E00204811000000000000000030 -:1009400000201010000000000000E007002044110B -:10095000000000000000000F0021022B000000003A -:100960000000000014C00000000000CB00F8FF08E9 -:1009700000204811000000009800000000404811CD -:10098000000000DC000000F000280E220000000043 -:10099000000000A0002F0223000000000000000063 -:1009A0000CC00000000000DA0000001100200E2D35 -:1009B0000000000000000001002F022300000000E2 -:1009C000000000000CE00000000000D50000000264 -:1009D000002F022300000000000000000CE00000D7 -:1009E000000000D400003F0000400C11000000D6C1 -:1009F00000001F0000400C11000000D600000F0096 -:100A000000200C11000000000038000900294A23D2 -:100A1000000000003F00000000280E2B0000000036 -:100A20000000000200220E2300000000000000076A -:100A300000494A23000000DC00380F09002048115B -:100A400000000000680000070020481100000000BE -:100A50000000000800214A270000000000000000FC -:100A60000020481100000000060A020000294A2464 -:100A700000000000000000000020481100000000FD -:100A80000000000000204811000000000000A20249 -:100A9000002044110000000000FF000000280E228A -:100AA000000000000000008000294A230000000030 -:100AB0000000002700200E2D00000000000000268E -:100AC0000020122D0000000000000000002F008315 -:100AD00000000000000000000CE00000000000EA40 -:100AE00000000000006000000000065F0000000041 -:100AF00000400000000000EB00000000006000006B -:100B000000000662000000070020222D0000000007 -:100B10000000000500220E2200000000001000006E -:100B200000280E23000000000000000000292068BB -:100B30000000000000000000003A0C02000000006D -:100B4000000000EF00280E2300000000000000005D -:100B500000292068000000000000001700200E2D72 -:100B6000000000000000000300210223000000003C -:100B70000000000014E00000000000F80000000B7E -:100B800000210228000000000000000014C0000046 -:100B9000000000F8000004000029222800000000E6 -:100BA0000000001400203628000000000000001C97 -:100BB00000210E22000000000000000014C0000010 -:100BC000000000FD0000A30C002044110000000004 -:100BD0000000000000204811000000000000001E7E -:100BE00000210E22000000000000000014C00000E0 -:100BF0000000010B0000A30F0020441100000000C2 -:100C00000000001100200E2D000000000000000177 -:100C1000002F022300000000000000000CC00000B4 -:100C200000000104FFFFFFFF004048110000010B1E -:100C300000000002002F022300000000000000005E -:100C40000CC00000000001070000FFFF0040481139 -:100C50000000010B00000004002F02230000000030 -:100C6000000000000CC000000000010A000000FFAE -:100C7000004048110000010B000000010020481155 -:100C8000000000000002C400002044110000000029 -:100C90000000001F00210E220000000000000000E4 -:100CA00014C00000000001120000001040210E20BE -:100CB00000000000000000130020362300000000A8 -:100CC0000000001840224A20000000000000001030 -:100CD000C0424A20000001140000000000200C1156 -:100CE0000000000000000013002036230000000078 -:100CF000000000000020481100000000000000007B -:100D000000204811000000000000000A002010111F -:100D10000000000000000000002F0224000000007E -:100D2000000000000CE000000000011B00000000BB -:100D300000204811000000000000000100531224B0 -:100D400000000117FFBFFFFF00283A2E000000003F -:100D50000000001B00210222000000000000000033 -:100D600014C000000000012E81000000002044118A -:100D7000000000000000000D0020481100000000ED -:100D80000000001800220E3000000000FC000000EF -:100D900000280E2300000000810000000020441104 -:100DA000000000000000000E0020481100000000BC -:100DB0000000000000201010000000000000E00E05 -:100DC000002044110000000007F8FF08002048112F -:100DD000000000000000000000294A23000000007D -:100DE0000000001C00201E2D000000000000000874 -:100DF00000214A27000000000000000000204811E8 -:100E000000000000060A020000294A240000000039 -:100E10000000000000204811000000000000000059 -:100E200000204811000000000000000000800000C9 -:100E300000000000810000000020441100000000BC -:100E40000000000100204811000000000000217C8B -:100E50000020441100000000008000000020481124 -:100E60000000000000000000002048060000000014 -:100E70000000000800214A270000000000000000D8 -:100E800017000000000000000004217F00604411F2 -:100E90000000068A0000001F002102300000000050 -:100EA0000000000014C000000000068900000004DB -:100EB00000404C1100000135810000000020441169 -:100EC00000000000000000010020481100000000A8 -:100ED000000021F800204411000000000000001C68 -:100EE0000020481100000000000421F900604411B6 -:100EF0000000068A000000110021023000000000FE -:100F00000000000014E000000000013C00000000B0 -:100F100000800000000000000000000000600000F1 -:100F20000000000B00000000006004110000031529 -:100F3000000000000020041100000000000000007C -:100F400000600811000001B2000000000060000015 -:100F5000000001600000FFFF40280E20000000009C -:100F600000000010C0211220000000000000FFFF60 -:100F7000402806200000000000000010C0210A20C8 -:100F800000000000000000000034146100000000B8 -:100F90000000000000741882000002BB0001A1FDE7 -:100FA00000604411000002E000003FFF002F022F0C -:100FB00000000000000000000CC00000000001471D -:100FC00000000000C040040000000001000000001C -:100FD000006000000000000B000000000060041131 -:100FE00000000315000000000020041100000000B4 -:100FF0000000000000600811000001B200003FFF87 -:10100000002F022F00000000000000000CE0000094 -:10101000000000000000000000600000000001600F -:101020000000001040210E20000000000000FFFF23 -:10103000C0281220000000000000001040211620EF -:10104000000000000000FFFFC0681A20000002BB83 -:101050000001A1FD00604411000002E000003FFF1C -:10106000002F022F00000000000000000CC0000054 -:101070000000015800000000C04004000000000112 -:101080000000225C0020441100000000000000016C -:1010900000300A2F000000000000000100210A2299 -:1010A000000000000000000300384A220000000099 -:1010B0000000225600204411000000000000001A29 -:1010C00000204811000000000000A1FC0020441195 -:1010D0000000000000000001008048110000000036 -:1010E00000000000006000000000000B0000000095 -:1010F000006000000000018F0000000000600000A0 -:10110000000001A000003FFF002F022F00000000A0 -:10111000000000000CE000000000000000000000E3 -:1011200000202C0800000000000000000020241116 -:101130000000000000000000002028110000000056 -:10114000000022560020441100000000000000169C -:1011500000204811000000000000225C0020441123 -:101160000000000000000003002048110000000003 -:1011700093800000002044110000000000000002E5 -:1011800000221E290000000000000000007048EB53 -:101190000000019C0000000000600000000002BB95 -:1011A00000000001403306200000000000000000A5 -:1011B000C03024090000000000003FFF002F022F74 -:1011C00000000000000000000CE000000000000033 -:1011D0000000000000600000000002A3000000000A -:1011E000002F022100000000000000000AE00000C3 -:1011F0000000018100000000006000000000013AD2 -:101200000000000000400000000001869500000082 -:10121000002044110000000000000000002F022107 -:1012200000000000000000000CE00000000001864B -:1012300000000000C0204800000000000000000185 -:10124000005306210000018292000000002044119A -:101250000000000000000000C0604800000001978E -:101260000001A1FD00204411000000000000001159 -:101270000020062D00000000000000000078042A75 -:10128000000002FB00000000002028090000000010 -:1012900000003FFF002F022F0000000000000000B0 -:1012A0000CC000000000017400000000C0400400F9 -:1012B000000000010000021000600411000003158E -:1012C00000003FFF002F022F000000000000000080 -:1012D0000CE000000000019400000015C020362042 -:1012E0000000000000000016C020362000000000B2 -:1012F0003F800000002004110000000046000000B4 -:1013000000600811000001B2000000000080000031 -:10131000000000000000A1FC0020441100000000BB -:1013200000003FFF002F022F00000000000000001F -:101330000CC000000000019B00000001008048116B -:1013400000000000000000210080481100000000A3 -:101350000000FFFF40280E200000000000000010E9 -:10136000C0211220000000000000FFFF40281620CE -:101370000000000000000010C0811A2000000000E2 -:101380008100000000204411000000000000000661 -:1013900000204811000000000000000800221E305C -:1013A000000000000000002900201A2D00000000AD -:1013B0000000E0000020441100000000FFFBFF09D6 -:1013C00000204811000000000000000F0020222D26 -:1013D0000000000000001FFF00294A280000000054 -:1013E000000000060020222D000000000000000088 -:1013F000002920E80000000000000000002048084C -:101400000000000000000000002048110000000063 -:10141000060A020000294A26000000000000000021 -:1014200000204811000000000000000000204811CA -:101430000000000000000100002018110000000062 -:101440000000000800621E280000012F00000008B4 -:1014500000822228000000000002C0000020441189 -:10146000000000000000001500600E2D000001BD0E -:101470000000001600600E2D000001BD0000C00835 -:1014800000204411000000000000001700200E2D75 -:10149000000000000000000014C00000000001B9BE -:1014A0000000000000200411000000000000000007 -:1014B0000020480100000000390000000020481111 -:1014C00000000000000000000020481100000000A3 -:1014D000000000000080480200000000000000182A -:1014E00000202E2D0000000000000000003B0D63D6 -:1014F000000000000000000800224A230000000055 -:101500000000001000224A23000000000000001824 -:1015100000224A2300000000000000000080480371 -:101520000000000000000000006000000000000B50 -:10153000000010000060041100000315000000000E -:1015400000200411000000000000000000600811ED -:10155000000001B2000000070021062F000000007B -:101560000000001300200A2D000000000000000110 -:1015700000202C11000000000000FFFF4028222066 -:10158000000000000000000F0026222800000000DC -:101590000000001040212620000000000000000F85 -:1015A000002626290000000000000000002028027C -:1015B000000000000000225600204411000000003E -:1015C0000000001B00204811000000000000000087 -:1015D000002F022100000000000000000CE00000CD -:1015E000000001E00000225C002044110000000027 -:1015F0000000008100204811000000000000A1FC54 -:1016000000204411000000000000000100204811EB -:10161000000000000000008000201C1100000000FD -:1016200000000000002F0227000000000000000062 -:101630000CE00000000001DC000000000060000081 -:10164000000001E90000000100531E27000001D83E -:101650000000000100202C11000000000000001F0D -:1016600000280A22000000000000001F00282A2A8B -:10167000000000000000000100530621000001D11D -:101680000000225C00204411000000000000000265 -:1016900000304A2F000000000000A1FC002044118F -:1016A00000000000000000010020481100000000C0 -:1016B0000000000100301E2F0000000000000000AC -:1016C000002F022700000000000000000CE00000D6 -:1016D000000000000000000000600000000001E9C0 -:1016E0000000000100531E27000001E50000FFFF7D -:1016F00040280E20000000000000000F00260E23EE -:101700000000000000000010C021122000000000B6 -:101710000000000F0026122400000000000000005E -:1017200000201411000000000000000000601811EB -:10173000000002BB0001A1FD0020441100000000D8 -:1017400000000000002F022B00000000000000003D -:101750000CE00000000001F8000000100022162834 -:1017600000000000FFFF0000002816250000000018 -:101770000000FFFF00281A29000000000000000000 -:10178000002948C500000000000000000020480AB1 -:10179000000000000000000000202C1100000000EC -:1017A000000000100022162300000000FFFF0000D0 -:1017B00000281625000000000000FFFF00281A2462 -:1017C0000000000000000000002948C500000000E3 -:1017D0000000000000731503000002050000000077 -:1017E0000020180500000000000000000073152410 -:1017F0000000020500000000002D14C500000000DC -:1018000000000000003008A20000000000000000FE -:101810000020480200000000000000000020280214 -:101820000000000000000000002020030000000075 -:101830000000000000802404000000000000000FF1 -:1018400000210225000000000000000014C000007C -:101850000000068900000000002B140500000000B5 -:1018600000000001009016250000000000000000AC -:10187000006000000000000B000000000060041188 -:10188000000003150000000000200411000000000B -:101890000000000000600811000001B200002256A4 -:1018A00000204411000000000000001A00294A2214 -:1018B0000000000000000000C02000000000000048 -:1018C00000003FFF002F022F00000000000000007A -:1018D0000CE000000000000000000000C020040038 -:1018E000000000000000225C002044110000000005 -:1018F0000000000300384A21000000000000A1FCA5 -:1019000000204411000000000000000100204811E8 -:10191000000000000000FFFF40281220000000002F -:1019200000000010C0211A20000000000000FFFF8E -:1019300040280E200000000000000010C0211620EA -:10194000000000000000000000741465000002BBED -:101950000001A1FD00604411000002E00000000150 -:10196000003306210000000000000000002F0221CB -:1019700000000000000000000CC000000000021980 -:1019800000003FFF002F022F0000000000000000B9 -:101990000CC000000000021200000000C040040063 -:1019A000000000010000000000600000000006428E -:1019B000000000000040040F0000021300000000BF -:1019C000006000000000062E000000000060000023 -:1019D0000000064200000210006004110000031520 -:1019E0000000000000600000000001A000000000F6 -:1019F000006000000000019C00000000006000008A -:101A0000000002BB0000000000600000000002A314 -:101A1000938000000020441100000000000000003E -:101A2000002048080000000000000000002F022FE6 -:101A300000000000000000000AE000000000023288 -:101A400000000000006000000000013A00000000FB -:101A50000040000000000236950000000020441104 -:101A60000000000000000000002F022F0000000016 -:101A7000000000000CE00000000002360000000042 -:101A8000C0404800000002339200000000204411D2 -:101A90000000000000000000C0204800000000001E -:101AA0000000225600204411000000000000001633 -:101AB00000204811000000000000225C00204411BA -:101AC000000000000000000300204811000000009A -:101AD0000000A1FC002044110000000000000001F3 -:101AE00000204811000000000001A1FD0020441169 -:101AF000000000000000000000600411000002FB74 -:101B000000000000C04004000000000100000000D0 -:101B1000006000000000062E0000A00C0020441110 -:101B20000000000000000000C0204800000000008D -:101B300000000000C040480000000000000000005D -:101B4000006000000000000B0000001840210A2087 -:101B50000000000000000003002F0222000000002F -:101B6000000000000AE000000000024C0000001429 -:101B70000020222D00000000000801010029222879 -:101B800000000000000000140020362800000000C3 -:101B90000000A30C00204411000000000000000021 -:101BA000C02048000000000000000000C0204800E5 -:101BB0000000000000000000C0404800000002518A -:101BC00000000000006000000000000B000000109A -:101BD00000600411000003153F8000000020041184 -:101BE000000000000000000000600811000001B2C9 -:101BF0000000225C002044110000000000000003EF -:101C000000204811000000000000000000600000FB -:101C10000000027C0000001700201E2D00000000C4 -:101C20000000000100211E2700000000000000004D -:101C300014E000000000026A0000001200201E2DC7 -:101C4000000000000000FFFF00281E270000000029 -:101C50000000000000341C2700000000000000000D -:101C600012C000000000025F0000000000201C11F4 -:101C70000000000000000000002F00E50000000050 -:101C80000000000008C00000000002620000000028 -:101C900000201407000000000000001200201E2D8C -:101CA000000000000000001000211E2700000000BE -:101CB0000000000000341C4700000000000000008D -:101CC00012C00000000002670000000000201C118C -:101CD0000000000000000000002F00E600000000EF -:101CE0000000000008C000000000026A00000000C0 -:101CF0000020180700000000000000000060000045 -:101D0000000002C100002256002044110000000023 -:101D1000000000000034202300000000000000004C -:101D200012C00000000002720000000000342044D5 -:101D3000000000000000000012C00000000002715E -:101D40000000001600404811000002760000001854 -:101D500000404811000002760000000000342044DA -:101D6000000000000000000012C00000000002752A -:101D70000000001700404811000002760000001922 -:101D800000204811000000000000A1FC00204411C8 -:101D900000000000000000010020481100000000C9 -:101DA0000001A1FD00604411000002E900003FFFB6 -:101DB000002F022F00000000000000000CC00000F7 -:101DC0000000025600000000C040040000000001B6 -:101DD0000000001040210620000000000000FFFF6E -:101DE000C0280A20000000000000001040210E2042 -:101DF000000000000000FFFFC028122000000000CB -:101E00000000001040211620000000000000FFFF2D -:101E1000C0881A200000000081000000002044114A -:101E20000000000000000001002048110000000038 -:101E300000042004006044110000068A0000000035 -:101E4000006000000000062E00000000C0600000DE -:101E5000000002A30000000500200A2D0000000081 -:101E60000000000800220A22000000000000002BF1 -:101E700000201A2D000000000000001C00201E2D74 -:101E8000000000000000700000281E270000000075 -:101E90000000000000311CE6000000000000002AE5 -:101EA00000201A2D000000000000000C00221A265D -:101EB0000000000000000000002F00E6000000000D -:101EC0000000000006E00000000002920000000098 -:101ED00000201C11000000000000000000200C1178 -:101EE000000000000000002B00203623000000004E -:101EF0000000001000201811000000000000000089 -:101F000000691CE20000012F9380000000204411B2 -:101F10000000000000000000002048070000000052 -:101F200095000000002044110000000000000000A7 -:101F3000002F022F00000000000000000CE0000055 -:101F40000000029D0000000100333E2F0000000051 -:101F500000000000D90048000000000092000000CE -:101F6000002044110000000000000000C0204800D4 -:101F7000000000000000001C0040362700000000A8 -:101F80000000000CC0220A20000000000000002910 -:101F9000002036220000000000000028C04036204B -:101FA000000000000000A2A4002044110000000076 -:101FB000000000090020481100000000A1000000FE -:101FC00000204411000000000000000100804811C2 -:101FD000000000000000002100201E2D0000000075 -:101FE00000000000002C1CE30000000000000021A5 -:101FF00000203627000000000000002200201E2DD7 -:102000000000000000000000002C1CE400000000A4 -:1020100000000022002036270000000000000023FE -:1020200000201E2D0000000000000000003120A351 -:102030000000000000000000002D1D07000000004F -:1020400000000023002036270000000000000024CC -:1020500000201E2D0000000000000000003120C400 -:102060000000000000000000002D1D07000000001F -:10207000000000240080362700000000000000213E -:10208000002036230000000000000022002036243B -:10209000000000000000000000311CA30000000050 -:1020A0000000002300203627000000000000000090 -:1020B00000311CC40000000000000024008036270E -:1020C000000000000000001A002036270000000079 -:1020D0000000001B00203628000000000000001750 -:1020E00000201E2D00000000000000020021022739 -:1020F000000000000000000014C00000000002DC2E -:102100000000000000400000000002D90000001A9A -:1021100000203627000000000000001B00203628A9 -:10212000000000000000001700201E2D000000002D -:102130000000000200210227000000000000000053 -:1021400014E00000000002D9000000030021022773 -:10215000000000000000000014E00000000002DCAD -:102160000000002300201E2D0000000000000000E1 -:10217000002E00E1000000000000000002C000008E -:10218000000002DC0000002100201E2D00000000E5 -:1021900000000000003120A100000000000000004D -:1021A000002E00E8000000000000000006C0000053 -:1021B000000002DC0000002400201E2D00000000B2 -:1021C00000000000002E00E20000000000000000FF -:1021D00002C00000000002DC0000002200201E2DD2 -:1021E0000000000000000000003120C200000000DC -:1021F00000000000002E00E80000000000000000C9 -:1022000006C00000000002DC0000000000600000CA -:10221000000006650000000000600000000002B53C -:102220000000000000400000000002DE000000008E -:1022300000600000000002B5000000000060000027 -:102240000000065C0000000000400000000002DE0C -:102250000000000000600000000002A70000000075 -:1022600000400000000002DE0000001A00201E2DC9 -:10227000000000000000001B0080222D0000000074 -:102280000000001000221E230000000000000000DB -:1022900000294887000000000000000000311CA356 -:1022A000000000000000001000221E2700000000B7 -:1022B0000000000000294887000000000000001016 -:1022C00000221E230000000000000000003120C496 -:1022D000000000000000FFFF00282228000000008E -:1022E0000000000000894907000000000000001005 -:1022F00000221E2300000000000000000029488783 -:10230000000000000000001000221E21000000005C -:102310000000000000294847000000000000000005 -:1023200000311CA3000000000000001000221E2746 -:1023300000000000000000000029488700000000A5 -:102340000000000000311CA100000000000000108F -:1023500000221E270000000000000000002948475E -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:10239000000000000000001000221E2100000000CC -:1023A00000000000003120C2000000000000FFFF1C -:1023B00000282228000000000000000000894907D2 -:1023C000000000000000001000221E23000000009A -:1023D0000000000000294887000000000000000104 -:1023E00000220A210000000000000000003308A2C3 -:1023F000000000000000001000221E22000000006B -:102400000000001000212222000000000000000057 -:1024100000294907000000000000000000311CA353 -:10242000000000000000001000221E270000000035 -:1024300000000000002948870000000000000001A3 -:1024400000220A210000000000000000003008A265 -:10245000000000000000001000221E22000000000A -:1024600000000010002122220000000000000000F7 -:1024700000294907000000000000001000221E2370 -:102480000000000000000000003120C40000000037 -:102490000000FFFF002822280000000000000000CC -:1024A000002949070000000000000000003808C5AE -:1024B00000000000000000000030084100000000A3 -:1024C0000000000100220A220000000000000000BD -:1024D000003308A2000000000000001000221E22AD -:1024E0000000000000000010002122220000000077 -:1024F00000000000008949070000000000000017EC -:102500000020222D000000000000000014C0000088 -:1025100000000318FFFFFFEF002806210000000065 -:10252000000000140020222D000000000000F8E050 -:1025300000204411000000000000000000294901B3 -:1025400000000000000000000089490100000000B8 -:102550000000000000204811000000000000000002 -:102560000020481100000000060A02000080481107 -:102570000000000000000000C0200000000000007B -:1025800097000000C020441100000000000000007F -:10259000C0204811000000008A0000000020441103 -:1025A00000000000000000000020481100000000B2 -:1025B0000000225C00204411000000000000000028 -:1025C000C0204800000000000000A1FC00204411D1 -:1025D0000000000000000000C020480000000000D3 -:1025E00000000000C0200400000000000000000007 -:1025F00000A0000A00000000970000000020441125 -:102600000000000000000000002048110000000051 -:102610008A000000002044110000000000000000BB -:1026200000204811000000000000225C002044113E -:102630000000000000000000C02048000000000072 -:102640000000A1FC00204411000000000000000078 -:10265000C02048000000000000000000C02004006E -:10266000000000000000000000A0000A00000000C0 -:10267000970000000020441100000000000000004E -:1026800000204811000000008A00000000204411D2 -:1026900000000000000000000020481100000000C1 -:1026A0000000225C00204411000000000000000037 -:1026B000C0204800000000000000A1FC00204411E0 -:1026C0000000000000000000C020480000000000E2 -:1026D0000001A1FD002044110000000000000000E6 -:1026E000D90048000000000000000000C0200400E5 -:1026F000000000000000000000A0000A0000000030 -:1027000000002257002044110000000000000003D8 -:10271000C0484A20000000000000225D0020441153 -:102720000000000000000000C04048000000000061 -:1027300000000000006000000000064200000000F1 -:10274000C0200800000000000000225C00204411AE -:10275000000000000000000300384A2200000000D2 -:102760000000A1FC00204411000000000000000057 -:10277000C0204800000000000001A1FD002044111D -:102780000000000000000000002F022200000000F6 -:10279000000000000CE0000000000000000000004D -:1027A00040204800000000000000000140304A20A6 -:1027B0000000000000000002C0304A2000000000BD -:1027C0000000000100530A220000034B0000003FFC -:1027D000C0280A20000000008100000000204411F1 -:1027E000000000000000000100204811000000006F -:1027F000000021F800204411000000000000001833 -:102800000020481100000000000421F9006044117C -:102810000000068A000000110021023000000000C4 -:102820000000000014E00000000003540000001449 -:10283000002F022200000000000000000CC0000079 -:10284000000003640000201000204411000000007C -:102850000000800000204811000000000001A2A438 -:102860000020441100000000000000000060480249 -:102870000000036E00002100002044110000000051 -:1028800000000000C0204800000000000000000020 -:10289000C02048000000000000000000C0204800E8 -:1028A0000000000000000000C040480000000000E0 -:1028B00000000004002F02220000000000000000C1 -:1028C0000CC000000000036A00002010002044112A -:1028D00000000000000080000020481100000000FF -:1028E0000001A2A40020441100000000000000002C -:1028F000004048020000035F00000028002F022271 -:1029000000000000000000000CC00000000005BD39 -:102910000001A2A4002044110000000000000000FB -:10292000004048020000035F0000002C0020362613 -:102930000000000000000049002018110000000005 -:102940000000003F002048110000000000000001CE -:1029500000331A260000000000000000002F0226AD -:1029600000000000000000000CC000000000037028 -:102970000000002C00801A2D000000000000003F25 -:10298000C0280A200000000000000015002F0222CD -:1029900000000000000000000CE0000000000386C2 -:1029A00000000006002F02220000000000000000CE -:1029B0000CE00000000003B100000016002F02220E -:1029C00000000000000000000CE00000000003B563 -:1029D00000000020002F0222000000000000000084 -:1029E0000CE000000000039C0000000F002F0222FA -:1029F00000000000000000000CE00000000003A840 -:102A000000000010002F0222000000000000000063 -:102A10000CE00000000003A80000001E002F0222AE -:102A200000000000000000000CE000000000039027 -:102A30000000A2A4002044110000000000000000DB -:102A400000404802000000000800000000290A229F -:102A5000000000000000000340210E2000000000E4 -:102A60000000000CC021122000000000000800003F -:102A7000002812240000000000000014C0221620CC -:102A80000000000000000000002914A40000000065 -:102A90000000A2A40020441100000000000000007B -:102AA000002948A2000000000000A1FE00204411FF -:102AB000000000000000000000404803000000008B -:102AC000810000000020441100000000000000010F -:102AD0000020481100000000000021F800204411EF -:102AE0000000000000000016002048110000000057 -:102AF000000421F9006044110000068A000000155E -:102B000000210230000000000000000014E000007E -:102B1000000003920000210E00204411000000007C -:102B200000000000C020480000000000000000007D -:102B3000C0204800000000000000A2A400204411B2 -:102B400000000000000000000040480200000000FB -:102B5000810000000020441100000000000000017E -:102B60000020481100000000000021F8002044115E -:102B700000000000000000170020481100000000C5 -:102B8000000421F9006044110000068A00000003DF -:102B900000210230000000000000000014E00000EE -:102BA0000000039E000021080020441100000000E6 -:102BB00000000000C02048000000000000000000ED -:102BC000C0204800000000000000A2A40020441122 -:102BD000000000000000000000404802000000006B -:102BE0000000A2A40020441100000000000000002A -:102BF0000020480200000000800000000020441176 -:102C0000000000000000000000204811000000004B -:102C100081000000002044110000000000000010AE -:102C200000204811000000000000000000200010FB -:102C3000000000000000000014C00000000003AE0F -:102C40000000000000400000000000000000201014 -:102C50000020441100000000000080000020481106 -:102C6000000000000001A2A40020441100000000A8 -:102C70000000000600404811000000000000201085 -:102C800000204411000000000000800000204811D6 -:102C9000000000000001A2A4002044110000000078 -:102CA00000000016006048110000036E00000000E4 -:102CB000004000000000000000000000C0200800EC -:102CC0000000000000000000C0200C000000000018 -:102CD0000000001D00210223000000000000000091 -:102CE00014E00000000003CE810000000020441129 -:102CF000000000000000000100204811000000005A -:102D0000000021F80020441100000000000000181D -:102D10000020481100000000000421F90060441167 -:102D20000000068A000000110021023000000000AF -:102D30000000000014E00000000003C000002100BB -:102D400000204411000000000000000000204802A4 -:102D50000000000000000000002048030000000008 -:102D6000BABECAFE0020481100000000CAFEBABE6A -:102D70000020481100000000000020100020441135 -:102D8000000000000000800000204811000000004A -:102D90000000A2A400204411000000000000000474 -:102DA0000040481100000000000021700020441184 -:102DB00000000000000000000020480200000000A9 -:102DC0000000000000204803000000008100000017 -:102DD00000204411000000000000000A00204811FB -:102DE00000000000000000000020001000000000B3 -:102DF0000000000014C00000000003D38C0000009D -:102E00000020441100000000CAFEBABE0040481174 -:102E100000000000810000000020441100000000BC -:102E200000000001002048110000000000003FFFEA -:102E300040280A20000000008000000040280E20EA -:102E40000000000040000000C02812200000000028 -:102E500000040000006946220000068A000000000D -:102E6000002014100000000000000000002F0223CA -:102E700000000000000000000CC00000000003E1A2 -:102E800000000000C0401800000003E400003FFF05 -:102E9000C0281A2000000000000400000069462637 -:102EA0000000068A0000000000201810000000004A -:102EB00000000000002F02240000000000000000BD -:102EC0000CC00000000003E700000000C0401C0030 -:102ED000000003EA00003FFFC0281E2000000000A1 -:102EE00000040000006946270000068A0000000078 -:102EF00000201C1000000000000000000020440220 -:102F00000000000000000000002820C500000000B4 -:102F100000000000004948E800000000A580000013 -:102F200000200811000000000000200000200C110B -:102F30000000000083000000006044110000041243 -:102F4000000000000020440200000000000000001B -:102F5000C0204800000000000000000040204800A1 -:102F6000000000000000001FC0210220000000003F -:102F70000000000014C00000000003F70000201053 -:102F800000204411000000000000800000204811D3 -:102F9000000000000000FFFFC0481220000003FFF7 -:102FA000A780000000200811000000000000A00021 -:102FB00000200C110000000083000000006044119C -:102FC0000000041200000000002044020000000085 -:102FD00000000000C02048000000000000000000C9 -:102FE000C0204800000000000000FFFFC0281220A1 -:102FF00000000000830000000020441100000000D9 -:103000000000000000304883000000008400000041 -:10301000002044110000000000000000C020480013 -:1030200000000000000000001D0000000000000083 -:103030008300000000604411000004120000000042 -:10304000C040040000000001A98000000020081119 -:10305000000000000000C00000400C11000003FA56 -:10306000AB80000000200811000000000000F8E024 -:1030700000400C11000003FAAD8000000020081190 -:10308000000000000000F88000400C11000003FA6E -:10309000B380000000200811000000000000F3FCD5 -:1030A00000400C11000003FAAF800000002008115E -:1030B000000000000000E00000400C11000003FAD6 -:1030C000B180000000200811000000000000F000A6 -:1030D00000400C11000003FA83000000002044119E -:1030E00000000000000021480020481100000000FE -:1030F00084000000002044110000000000000000D7 -:10310000C020480000000000000000001D0000007A -:10311000000000000000000000800000000000002F -:1031200001182000C0304620000000000000000010 -:10313000D90048000000000000000000C02004008A -:10314000000000000000000000A0000A00000000D5 -:103150000218A000C030462000000000000000005F -:10316000D90048000000000000000000C02004005A -:10317000000000000000000000A0000A00000000A5 -:103180000318C000C030462000000000000000000E -:10319000D90048000000000000000000C02004002A -:1031A000000000000000000000A0000A0000000075 -:1031B0000418F8E0C03046200000000000000000C5 -:1031C000D90048000000000000000000C0200400FA -:1031D000000000000000000000A0000A0000000045 -:1031E0000518F880C03046200000000000000000F4 -:1031F000D90048000000000000000000C0200400CA -:10320000000000000000000000A0000A0000000014 -:103210000618E000C030462000000000000000005A -:10322000D90048000000000000000000C020040099 -:10323000000000000000000000A0000A00000000E4 -:103240000718F000C0304620000000000000000019 -:10325000D90048000000000000000000C020040069 -:10326000000000000000000000A0000A00000000B4 -:103270000818F3FCC03046200000000000000000E9 -:10328000D90048000000000000000000C020040039 -:10329000000000000000000000A0000A0000000084 -:1032A0000000003000200A2D000000000000000097 -:1032B000C0290C4000000000000000300020362330 -:1032C0000000000000000000C0200400000000001A -:1032D0000000000000A0000A0000000086000000BE -:1032E00000204411000000000000000000404801E0 -:1032F0000000000085000000C02044110000000014 -:103300000000000000404801000000000000217C97 -:10331000002044110000000000000000C020480010 -:103320000000000000000000C02048000000000075 -:1033300000000000C02048000000000081000000E4 -:10334000002044110000000000000001002048118E -:103350000000000000000000C02008000000000085 -:103360000000000017000000000000000004217FA2 -:10337000006044110000068A0000001F0021023096 -:10338000000000000000000014C000000000000069 -:103390000000000000404C02000004480000000053 -:1033A000C0200C000000000000000000C020100041 -:1033B0000000000000000000C02014000000000019 -:1033C00000000000C0201800000000000000000005 -:1033D000C0201C000000000000007F0000280A211F -:1033E0000000000000004500002F02220000000045 -:1033F000000000000CE00000000004560000000087 -:10340000C0202000000000000000000017000000A5 -:10341000000000000000001000280A230000000047 -:1034200000000010002F0222000000000000000039 -:103430000CE000000000045E810000000020441148 -:103440000000000000000001002048110000000002 -:1034500000040000006946240000068A0000000005 -:1034600000400000000004638100000000204411BF -:1034700000000000000000000020481100000000D3 -:103480000000216D00204411000000000000000039 -:103490000020480400000000000000000060480513 -:1034A0000000068F00000000002824F0000000004B -:1034B0000000000700280A230000000000000001AF -:1034C000002F022200000000000000000AE00000BF -:1034D0000000046A00000000002F00C90000000086 -:1034E0000000000004E00000000004830000000071 -:1034F000004000000000049000000002002F0222A3 -:1035000000000000000000000AE000000000046F5E -:1035100000000000002F00C90000000000000000B3 -:1035200002E00000000004830000000000400000F2 -:103530000000049000000003002F022200000000A1 -:10354000000000000AE00000000004740000000019 -:10355000002F00C900000000000000000CE0000087 -:103560000000048300000000004000000000049000 -:1035700000000004002F02220000000000000000F4 -:103580000AE000000000047900000000002F00C9DC -:1035900000000000000000000AE0000000000483BA -:1035A0000000000000400000000004900000000542 -:1035B000002F022200000000000000000AE00000CE -:1035C0000000047E00000000002F00C90000000081 -:1035D0000000000006E0000000000483000000007E -:1035E000004000000000049000000006002F0222AE -:1035F00000000000000000000AE00000000004835A -:1036000000000000002F00C90000000000000000C2 -:1036100008E00000000004830000000000400000FB -:103620000000049000007F0000280A210000000034 -:1036300000004500002F02220000000000000000F2 -:103640000AE00000000000000000000800210A233A -:10365000000000000000000014C000000000048D05 -:10366000000021690020441100000000000000005B -:10367000C02048000000000000000000C0204800FA -:103680000000000000000000C02048000000000012 -:10369000CAFEBABE00404811000000000000000051 -:1036A000C02044000000000000000000C020000016 -:1036B0000000000000000000C040480000000000C2 -:1036C00000007F0000280A210000000000004500E3 -:1036D000002F022200000000000000000AE00000AD -:1036E0000000049600000000C02000000000000060 -:1036F00000000000C02000000000000000000000EA -:10370000C0400000000000000000000000404C0825 -:103710000000045600000000C02008000000000067 -:103720000000001040210E200000000000000011E9 -:10373000402112200000000000000012402116204D -:10374000000000000000216900204411000000007A -:1037500000000000002048020000000000000000FF -:1037600000210225000000000000000014E000001D -:10377000000004A000040000C0494A20000004A189 -:10378000FFFBFFFFC0284A200000000000000000EF -:1037900000210223000000000000000014E00000EF -:1037A000000004AD00000000C02048000000000040 -:1037B00000000000C02048000000000000000000E1 -:1037C00000210224000000000000000014C00000DE -:1037D00000000000810000000020441100000000F3 -:1037E0000000000C00204811000000000000000054 -:1037F00000200010000000000000000014C00000C5 -:10380000000004A9A00000000020441100000000F6 -:10381000CAFEBABE0040481100000000810000004E -:1038200000204411000000000000000400204811A6 -:10383000000000000000216B002044110000000087 -:1038400000000000C02048100000000081000000BF -:103850000020441100000000000000050020481175 -:10386000000000000000216C002044110000000056 -:1038700000000000C0204810000000000000000010 -:10388000002F022400000000000000000CE00000F7 -:10389000000000000000000000400000000004A73D -:1038A00000000000C0210A2000000000000000000D -:1038B00014C00000000004C081000000002044117A -:1038C000000000000000000000204811000000007F -:1038D0000000216D002044110000000000000000E5 -:1038E000C02048000000000000000000C060480048 -:1038F0000000068F0000000000400000000004C42B -:1039000081000000002044110000000000000001C0 -:10391000002048110000000000040000C0294620DB -:103920000000000000000000C06000000000068AE7 -:103930000000000100210222000000000000000041 -:1039400014C00000000004CB0000216900204411D5 -:103950000000000000000000C0204800000000003F -:1039600000000000C020480000000000000000002F -:103970000020481000000000CAFEBABE00404811F6 -:103980000000000000000000C02044000000000013 -:1039900000000000C040481000000000810000004E -:1039A0000020441100000000000000010020481128 -:1039B00000000000000021F8002044110000000079 -:1039C0000000000E0020481100000000000421F952 -:1039D000006044110000068A00000000002102304F -:1039E000000000000000000014C00000000004CD32 -:1039F00000002180002044110000000000000000B1 -:103A0000C02048000000000000000000C0200000AE -:103A10000000000000000000C0204800000000007E -:103A200000000000C02000000000000000000000B6 -:103A3000C0404800000000000000000300333E2F9B -:103A40000000000000000001002102210000000031 -:103A50000000000014E00000000004FD0000002C45 -:103A600000200A2D000000000004000018E00C11E6 -:103A7000000004EC0000000100333E2F00000000B5 -:103A80000000216900204411000000000000000037 -:103A90000020480200000000000000000020480351 -:103AA000000000000000000800300A2200000000B2 -:103AB00000000000C02048000000000000000000DE -:103AC000C0204800000000000000216900204411CF -:103AD000000000000000000000204802000000007C -:103AE0000000000000204803000000000000000863 -:103AF00000300A220000000000000000C020480042 -:103B00000000000000000000D8C04800000004E0F1 -:103B100000002169002044110000000000000000A6 -:103B200000204802000000000000000000204803C0 -:103B3000000000000000000800300A220000000021 -:103B400000000000C020480000000000000000004D -:103B5000C0204800000000000000002D0020122DB1 -:103B6000000000000000000000290C83000000009D -:103B70000000216900204411000000000000000046 -:103B80000020480200000000000000000020480360 -:103B9000000000000000000800300A2200000000C1 -:103BA00000000000C02048000000000000000000ED -:103BB000C020480000000000000000110021022485 -:103BC000000000000000000014C000000000000021 -:103BD0000000000000400000000004A70000002CCE -:103BE000C0203620000000000000002DC04036201C -:103BF000000000000000000F002102210000000072 -:103C00000000000014C000000000050200000000D9 -:103C1000006000000000000B00000000D900000060 -:103C20000000000000000000C0400400000000018F -:103C3000B50000000020441100000000000020003A -:103C40000020481100000000B600000000204411D0 -:103C5000000000000000A00000204811000000004B -:103C6000B700000000204411000000000000C00068 -:103C70000020481100000000B8000000002044119E -:103C8000000000000000F8E00020481100000000E3 -:103C9000B900000000204411000000000000F8807E -:103CA0000020481100000000BA000000002044116C -:103CB000000000000000E0000020481100000000AB -:103CC000BB00000000204411000000000000F000D4 -:103CD0000020481100000000BC000000002044113A -:103CE000000000000000F3FC00204811000000006C -:103CF00081000000002044110000000000000002CC -:103D00000020481100000000000000FF00280E30D5 -:103D10000000000000000000002F0223000000004F -:103D2000000000000CC000000000051600000000AC -:103D3000C0200800000000000000000014C00000C7 -:103D40000000052B0000000000200C110000000006 -:103D50000000001C00203623000000000000002BA3 -:103D60000020362300000000000000290020362338 -:103D700000000000000000280020362300000000A2 -:103D8000000000170020362300000000000000257E -:103D9000002036230000000000000026002036230B -:103DA0000000000000000015002036230000000085 -:103DB000000000160020362300000000FFFFE00096 -:103DC00000200C110000000000000021002036231C -:103DD0000000000000000022002036230000000048 -:103DE00000001FFF00200C11000000000000002355 -:103DF00000203623000000000000002400203623AD -:103E000000000000F1FFFFFF00283A2E0000000034 -:103E10000000001AC0220E20000000000000000078 -:103E20000029386E000000008100000000204411CD -:103E30000000000000000006002048110000000003 -:103E40000000002A4020362000000000870000000B -:103E5000002044110000000000000000C0204800C5 -:103E6000000000000000A1F4002044110000000048 -:103E700000000000002048100000000000000000CA -:103E800000200C110000000000000030002036234C -:103E9000000000009D000000002044110000000010 -:103EA0000000001F40214A20000000009600000092 -:103EB000002044110000000000000000C020480065 -:103EC0000000000000000000C0200C000000000006 -:103ED00000000000C0201000000000000000001FD3 -:103EE00000211624000000000000000014C00000A3 -:103EF000000000000000001D00203623000000002C -:103F00000000000300281E2300000000000000083D -:103F10000022222300000000FFFFF00000282228DA -:103F20000000000000000000002920E80000000060 -:103F30000000001F002036280000000000000018CC -:103F400000211E2300000000000000200020362772 -:103F50000000000000000002002216240000000003 -:103F600000000000003014A8000000000000001E47 -:103F700000203625000000000000000300211A2464 -:103F8000000000001000000000281A2600000000B9 -:103F9000EFFFFFFF00283A2E0000000000000000A5 -:103FA000004938CE000006780000000140280A20B1 -:103FB000000000000000000640280E200000000065 -:103FC00000000300C02812200000000000000008CC -:103FD000002112240000000000000000C020162074 -:103FE0000000000000000000C0201A2000000000B7 -:103FF000000000000021022200000000000000007C -:1040000014C000000000056381000000002044117E -:104010000000000000000001002048110000000026 -:104020000000225800300A240000000000040000B4 -:10403000006946220000068A000021690020441120 -:104040000000000000000000002048050000000003 -:104050000002000000294A260000000000000000C5 -:104060000020481000000000CAFEBABE002048111F -:104070000000000000000002002F022300000000EA -:10408000000000000CC000000000056B00000000F4 -:10409000C0201C100000000000000000C040000014 -:1040A0000000057900000002002F0223000000003C -:1040B000000000000CC000000000056B8100000043 -:1040C0000020441100000000000000010020481101 -:1040D000000000000000225800300A240000000008 -:1040E00000040000006946220000068A000000006B -:1040F000C0201C100000000000000000C0400000B4 -:104100000000057900000000002F022300000000DD -:10411000000000000CC000000000056F000000005F -:10412000C0201C000000000000000000C040000093 -:104130000000057900000004002F022300000000A9 -:10414000000000000CC000000000057781000000A6 -:104150000020441100000000000000000020481171 -:10416000000000000000216D00204411000000004C -:1041700000000000C0204800000000000000000017 -:10418000C06048000000068F0000000000401C10C6 -:104190000000057900000000C020000000000000C1 -:1041A00000000000C040000000000000000000000F -:1041B0000EE000000000057B000000000060000031 -:1041C000000005C600000000002F022400000000CF -:1041D000000000000CC000000000058C0000A2B729 -:1041E00000204411000000000000000000204807EB -:1041F00000000000810000000020441100000000C9 -:104200000000000100204811000000000004A2B6D8 -:10421000006044110000068A0000001A00212230CC -:104220000000000000000006002226300000000010 -:1042300000042004006044110000068A0000A2C4AB -:10424000002044110000000000000000003048E998 -:10425000000000000000000000E000000000058AEF -:104260000000A2D100204411000000000000000066 -:1042700000404808000000000000A2D100204411C6 -:10428000000000000000000100504A28000000006B -:1042900000000001002F02240000000000000000C8 -:1042A0000CC000000000059D0000A2BB00204411CE -:1042B000000000000000000000204807000000008F -:1042C00081000000002044110000000000000001F7 -:1042D00000204811000000000004A2BA0060441150 -:1042E0000000068A0000001A0021223000000000B1 -:1042F0000000000600222630000000000004200418 -:10430000006044110000068A0000A2C5002044118C -:104310000000000000000000003048E9000000003C -:104320000000000000E000000000059B0000A2D299 -:104330000020441100000000000000000040480878 -:10434000000000000000A2D2002044110000000084 -:104350000000000100504A28000000000000000298 -:10436000002F022400000000000000000CC000002C -:10437000000005AE0000A2BF0020441100000000B4 -:10438000000000000020480700000000810000003D -:10439000002044110000000000000001002048112E -:1043A000000000000004A2BE006044110000068A64 -:1043B0000000001A0021223000000000000000066A -:1043C0000022263000000000000420040060441198 -:1043D0000000068A0000A2C6002044110000000070 -:1043E00000000000003048E900000000000000006C -:1043F00000E00000000005AC0000A2D30020441142 -:10440000000000000000000000404808000000001C -:104410000000A2D3002044110000000000000001B1 -:1044200000504A28000000000000A2C300204411F0 -:10443000000000000000000000204807000000000D -:104440008100000000204411000000000000000175 -:1044500000204811000000000004A2C200604411C6 -:104460000000068A0000001A00212230000000002F -:104470000000000600222630000000000004200496 -:10448000006044110000068A0000A2C70020441109 -:104490000000000000000000003048E900000000BB -:1044A0000000000000E00000000005BB0000A2D4F6 -:1044B00000204411000000000000000000404808F7 -:1044C000000000000000A2D4002044110000000001 -:1044D0000000000100504A28000000008500000094 -:1044E00000204411000000000000000000204801EE -:1044F000000000000000304A0020441100000000CD -:104500000100000000204811000000000000000031 -:1045100000400000000005C1A4000000C0204411BC -:104520000000000000000000C04048000000000043 -:1045300000000000C0600000000005C60000000090 -:10454000C0400400000000010000002C00203621C3 -:104550000000000081000000002044110000000065 -:1045600000000006002048110000000000000000CC -:10457000002F023000000000000000000CC000000E -:10458000000005CD00000000002004110000000024 -:104590000000003000403621000005E0000000303F -:1045A0000020062D0000000000007E0000280621EB -:1045B0000000000000000000002F022100000000A9 -:1045C000000000000CE00000000005E08100000099 -:1045D00000204411000000000000000100204811EC -:1045E000000000000004A092006044110000068A50 -:1045F0000000003100203630000000000004A093CD -:10460000006044110000068A0000003200203630AD -:10461000000000000004A2B6006044110000068AF9 -:104620000000003300203630000000000004A2BA71 -:10463000006044110000068A00000034002036307B -:10464000000000000004A2BE006044110000068AC1 -:104650000000003500203630000000000004A2C237 -:10466000006044110000068A000000360020363049 -:104670000000000000042004006044110000068ACD -:104680000001A2A400204411000000000000003F2F -:1046900000204811000000000000003F00204811E9 -:1046A000000000000000003F002048110000000052 -:1046B0000000003F0020481100000000000000053D -:1046C00000204811000000000000A1F40020441167 -:1046D0000000000000000000002048110000000061 -:1046E00088000000002044110000000000000001CC -:1046F000002048110000000081000000002044114B -:10470000000000000000000600204811000000002A -:1047100000000001002F0230000000000000000037 -:104720000CE0000000000629000000300020062DEB -:104730000000000000000000002F02210000000027 -:10474000000000000CE000000000062981000000CD -:10475000002044110000000000000001002048116A -:104760000000000000007E0000280621000000007C -:1047700000000000002F02210000000000000000E7 -:104780000CE00000000006020000A092002044118E -:10479000000000000000003100204A2D0000000051 -:1047A0000000A0930020441100000000000000322F -:1047B00000204A2D000000000000A2B60020441195 -:1047C000000000000000003300204A2D000000001F -:1047D0000000A2BA002044110000000000000034D4 -:1047E00000204A2D000000000000A2BE002044115D -:1047F000000000000000003500204A2D00000000ED -:104800000000A2C200204411000000000000003699 -:1048100000204A2D00000000000000300020062D7E -:1048200000000000000001FF002806210000000039 -:1048300000000000002F0221000000000000000026 -:104840000CE000000000062800000000002102210A -:10485000000000000000000014C000000000060B73 -:104860000004A003006044110000068A0000A003B9 -:10487000002044110000000000000000002048104B -:1048800000000000000000010021062100000000DF -:104890000000000014C00000000006100004A0107A -:1048A000006044110000068A0000A010002044119E -:1048B0000000000000000000002048100000000080 -:1048C000000000010021062100000000000000009F -:1048D000002F022100000000000000000CE000009A -:1048E000000006280004A011006044110000068AA0 -:1048F0000000A01100204411000000000000000092 -:1049000000204810000000000004A01200604411C4 -:104910000000068A0000A0120020441100000000E0 -:104920000000000000204810000000000004A01358 -:10493000006044110000068A0000A013002044110A -:1049400000000000000000000020481000000000EF -:104950000004A014006044110000068A0000A014A6 -:10496000002044110000000000000000002048105A -:10497000000000000004A015006044110000068A39 -:104980000000A015002044110000000000000000FD -:1049900000204810000000000004A0160060441130 -:1049A0000000068A0000A01600204411000000004C -:1049B0000000000000204810000000000004A017C4 -:1049C000006044110000068A0000A0170020441176 -:1049D000000000000000000000204810000000005F -:1049E00000042004006044110000068A0000002C2E -:1049F0000080062D00000000FF0000000020441190 -:104A0000000000000000000000204811000000002D -:104A1000000000010020481100000000000000021A -:104A20000080481100000000000000000EE00000BF -:104A30000000063A000000300020062D00000000B3 -:104A40000000000200280621000000000000000015 -:104A5000002F022100000000000000000CE0000018 -:104A60000000063881000000002044110000000012 -:104A70000000000100204811000000000004200494 -:104A8000006044110000068A000010000020081198 -:104A9000000000000000002B002036220000000073 -:104AA00000000000006000000000063E0000000062 -:104AB00000600000000005C69800000000204411BE -:104AC000000000000000000000804811000000000D -:104AD00000000000C06000000000063E0000000072 -:104AE000C0400400000000010000A2A40020441106 -:104AF000000000000000002200204811000000001B -:104B000089000000002044110000000000000001A6 -:104B1000004048110000062A9700000000204411C0 -:104B2000000000000000000000204811000000000C -:104B30008A00000000204411000000000000000076 -:104B4000004048110000062A00000000006000003C -:104B50000000065900002010002044110000000051 -:104B60000000800000204811000000000001A2A405 -:104B7000C020441100000000000000160060481131 -:104B80000000036E0000201000204411000000000F -:104B9000000100000020481100000000810000001A -:104BA0000020441100000000000000010020481116 -:104BB000000000000000217C0020441100000000E3 -:104BC000098000000020481100000000FFFFFFFFE7 -:104BD00000204811000000000000000000204811E3 -:104BE00000000000000000001700000000000000AE -:104BF0000004217F006044110000068A0000001FAD -:104C000000210230000000000000000014C000007D -:104C1000000000000000000400404C11000006539A -:104C2000000000000040000000000000000000172D -:104C300000201E2D000000000000000400291E2797 -:104C40000000000000000017008036270000000070 -:104C50000000001700201E2D00000000FFFFFFFBDA -:104C600000281E27000000000000001700803627E3 -:104C7000000000000000001700201E2D00000000B2 -:104C80000000000800291E27000000000000001797 -:104C900000803627000000000000001700201E2DB5 -:104CA00000000000FFFFFFF700281E2700000000A3 -:104CB00000000017008036270000000000002010D0 -:104CC0000020441100000000000080000020481176 -:104CD000000000000001A2A4002044110000000018 -:104CE00000000016006048110000036E0000201054 -:104CF00000204411000000000001000000204811C5 -:104D0000000000000000217C002044110000000091 -:104D1000018000000020481100000000FFFFFFFF9D -:104D20000020481100000000000000000020481191 -:104D3000000000000000000017000000000000005C -:104D4000810000000020441100000000000000016C -:104D500000204811000000000004217F0060441181 -:104D60000000068A0000001F002102300000000041 -:104D70000000000014C000000000068900000010C0 -:104D800000404C110000066F00000000C02004002D -:104D9000000000000000000038C00000000000001B -:104DA0000000001D00200A2D000000000000001E71 -:104DB00000200E2D000000000000001F0020122D1A -:104DC00000000000000000200020162D0000000060 -:104DD00000002169002044110000000000000000D4 -:104DE00000204804000000000000000000204805EA -:104DF000000000000000000000204801000000004A -:104E0000CAFEBABE002048110000000000000004E5 -:104E1000003012240000000000000000002F006499 -:104E200000000000000000000CC000000000068828 -:104E30000000000300281A22000000000000000803 -:104E40000022122200000000FFFFF00000281224C0 -:104E50000000000000000000002910C40000000055 -:104E60000000001F00403624000000000000000089 -:104E70000080000000000000000000001AC00000D8 -:104E80000000068A9F00000000204411000000007E -:104E9000CAFEBABE00204811000000000000000059 -:104EA0001AE000000000068D0000000000800000F5 -:104EB00000000000000000001AC000000000068F83 -:104EC0009E0000000020441100000000CAFEBABE8F -:104ED0000020481100000000000000001AE000005F -:104EE00000000692000000000080000000000000AA -:104EF00000000000006000000000000B0000100037 -:104F000000600411000003150000000000200411DF -:104F1000000000000000000000600811000001B265 -:104F20000000225C0020441100000000000000038B -:104F3000002048110000000000002256002044110B -:104F4000000000000000001B0020481100000000CD -:104F50000000A1FC0020441100000000000000013E -:104F600000204811000000000001A1FDC0204411F4 -:104F7000000000000000002100201E2D00000000A5 -:104F80000000001000221E27000000000000002486 -:104F90000020222D000000000000FFFF0028222832 -:104FA0000000000000000000002949070000000088 -:104FB0000000000000204811000000000000002256 -:104FC0000020222D000000000000FFFF0028222802 -:104FD0000000000000000000002949070000000058 -:104FE0000000000000204811000000000000002325 -:104FF00000201E2D000000000000001000221E27CF -:105000000000000000000000002949070000000027 -:1050100000000000004048110000000000000000F7 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B000014204FF05BD02500000000001C3016867 -:1052C000043F05BD00000000022502090250015103 -:1052D000000000000223024502A00241000000007D -:1052E00003D705BD05BD05BD000000000646064705 -:1052F000031F05BD0000000005BD05C203200340DB -:1053000000000000032A0282034203340000000070 -:1053100005BD05BD05BD05BD0000000005BD054E70 -:1053200005BD05BD0000000003BA05BD04B8034477 -:10533000000000000497044D043D05BD000000007E -:1053400004CD05BD044104DA00000000044D05044D -:10535000035103750000000005BD05BD05BD05BD79 -:105360000000000005BD05BD05BD05BD0000000035 -:1053700005BD05BD063C05C40000000005BD05BD1A -:10538000000705BD0000000005BD05BD05BD05BD4C -:105390000000000005BD05BD05BD05BD0000000005 -:1053A00003F803ED0408040600000000040E040ADC -:1053B000040C041000000000041C04180424042041 -:1053C00000000000042C0428043404300000000015 -:1053D00005BD05BD043805BD0000000005BD05BDC7 -:1053E00005BD05BD0000000005BD05BD05BD05BD31 -:1053F000000000000002067606940006000000008F -:00000001FF diff --git a/firmware/radeon/RV635_pfp.bin.ihex b/firmware/radeon/RV635_pfp.bin.ihex deleted file mode 100644 index f55292c97b7937d5da76127dbb21745b72d8039d..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV635_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000CA040000A00000007E828B007C038BED -:10001000008001B8007C038B00D4401E00EE001E5F -:1000200000CA040000A00000007E828B00C41838C3 -:1000300000CA240000CA2800009581A800C41C3A08 -:1000400000C3C00000CA080000CA0C00007C744B4A -:1000500000C200050099C00000C41C3A007C744C2A -:1000600000C0FFF000042C0400309002007D250049 -:1000700000351402007D350B00255403007CD5802B -:1000800000259C030095C00400D5001B007EDDC147 -:10009000007D9D8000D6801B00D5801B00D4401EB3 -:1000A00000D5401E00D6401E00D6801E00D4801E03 -:1000B00000D4C01E009783D300D5C01E00CA08001C -:1000C0000080001A00CA0C0000E4011E00D4001ECB -:1000D0000080000C00C4183800E4013E00D4001E6B -:1000E0000080000C00C4183800D4401E00EE001E32 -:1000F00000CA040000A00000007E828B00E4011E04 -:1001000000D4001E00D4401E00EE001E00CA0400F1 -:1001100000A00000007E828B00E4013E00D4001E9F -:1001200000D4401E00EE001E00CA040000A0000023 -:10013000007E828B00CA180000D4401E00D5801EAD -:100140000080005300D4007500D4401E00CA08008F -:1001500000CA0C0000CA100000D4801900D4C018D6 -:1001600000D5001700D4801E00D4C01E00D5001E8C -:1001700000E2001E00CA040000A00000007E828B86 -:1001800000CA080000D4806000D4401E0080000037 -:1001900000D4801E00CA080000D4806100D4401E34 -:1001A0000080000000D4801E00CA080000CA0C00B5 -:1001B00000D4401E00D4801600D4C01600D4801E87 -:1001C000008001B800D4C01E00C6084300CA0C005D -:1001D00000CA10000094800400CA140000E420F358 -:1001E00000D4201300D5606500D4E01C00D5201C8D -:1001F00000D5601C008000000006200100C60843F6 -:1002000000CA0C0000CA1000009483F700CA140052 -:1002100000E420F30080007900D4201300C60843D6 -:1002200000CA0C0000CA1000009883EF00CA140036 -:1002300000D400640080008D0000000000C414326F -:1002400000C6184300C4082F0095400500C40C30B8 -:1002500000D4401E0080000000EE001E009583F5D3 -:1002600000C4103100D4403300D5206500D4A01C58 -:1002700000D4E01C00D5201C00E4015E00D4001E68 -:10028000008000000006200100CA1800000A2001BA -:1002900000D6007600C408360098800700C61045D6 -:1002A0000095011000D4001F00D46062008000009F -:1002B00000D4206200CC383500CC1433008401BB5C -:1002C00000D4007200D5401E0080000000EE001E29 -:1002D00000E2001A008401BB00E2001A00CC104BBF -:1002E00000CC0447002C9401007D098B0098400548 -:1002F000007D15CB00D4001A008001B800D4006D39 -:100300000034440100CC0C480098403A00CC2C4A00 -:100310000095800400CC0449008001B800D4001A84 -:1003200000D4C01A00282801008400F000CC10037B -:100330000098801B0004380C008400F000CC1003EF -:100340000098801700043808008400F000CC1003E7 -:100350000098801300043804008400F000CC1003DF -:100360000098801400CC104C009A800900CC144DE9 -:10037000009840DC00D4006D00CC184800D5001A6D -:1003800000D5401A008000C900D5801A0096C0D55B -:1003900000D4006D008001B800D4006E009AC00344 -:1003A00000D4006D00D4006E0080000000EC007FDF -:1003B000009AC0CC00D4006D008001B800D4006E5B -:1003C00000CC140300CC180300CC1C03007D910367 -:1003D000007DD583007D190C0035CC1F0035701FC2 -:1003E000007CF0CB007CD08B00880000007E8E8BE0 -:1003F0000095C00400D4006E008001B800D4001A3B -:1004000000D4C01A00CC080300CC0C0300CC1003AD -:1004100000CC140300CC180300CC1C0300CC240334 -:1004200000CC28030035C41F0036B01F007C704B81 -:100430000034F01F007C704B0035701F007C704B47 -:10044000007D8881007DCCC1007E5101007E9541F8 -:10045000007C9082007CD4C2007C848B009AC00314 -:10046000007C8C8B002C88010098809E00D4006D4D -:100470000098409C00D4006E00CC084C00CC0C4D81 -:1004800000CC104800D4801A00D4C01A00800101AA -:1004900000D5001A00CC083200D40032009482D972 -:1004A00000CA0C0000D4401E0080000000D4001ED2 -:1004B00000E4011E00D4001E00CA080000CA0C009F -:1004C00000CA100000D4401E00CA140000D4801ED0 -:1004D00000D4C01E00D5001E00D5401E00D54034FB -:1004E0000080000000EE001E0028040400E2001A54 -:1004F00000E2001A00D4401A00CA380000CC0803F9 -:1005000000CC0C0300CC0C0300CC0C03009882BD83 -:1005100000000000008401BB00D7A06F0080000035 -:1005200000EE001F00CA040000C2FF0000CC083427 -:1005300000C13FFF007C74CB007CC90B007D010F24 -:10054000009902B0007C738B008401BB00D7A06FC0 -:100550000080000000EE001F00CA080000281900FB -:10056000007D898B009580140028140400CA0C00BB -:1005700000CA100000CA1C0000CA240000E2001FCC -:1005800000D4C01A00D5001A00D5401A00CC1803B8 -:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -:1005A000007D9C4700984297000000000080016198 -:1005B00000D4C01A00D4401E00D4801E0080000069 -:1005C00000EE001E00E4011E00D4001E00D4401EF8 -:1005D00000EE001E00CA040000A00000007E828B16 -:1005E00000E4013E00D4001E00D4401E00EE001EB8 -:1005F00000CA040000A00000007E828B00CA080030 -:1006000000248C06000CCC060098C00600CC104ECE -:100610000099000400D4007300E4011E00D4001E01 -:1006200000D4401E00D4801E0080000000EE001E9A -:1006300000CA080000CA0C000034D01800251001C0 -:100640000095002100C17FFF00CA100000CA1400FD -:1006500000CA180000D4801D00D4C01D007DB18BDD -:1006600000C1420200C2C00100D5801D0034DC0E72 -:10067000007D5D4C007F734C00D7401E00D5001EEE -:1006800000D5401E00C1420000C2C00000099C010C -:100690000031DC10007F5F4C007F734C00042802A7 -:1006A000007D838000D5A86F00D5806600D7401EEE -:1006B00000EC005E00C8240200C82402008001B8DB -:1006C00000D6007600D4401E00D4801E00D4C01E88 -:1006D0000080000000EE001E0080000000EE001F01 -:1006E00000D4001F0080000000D4001F00D4001FB1 -:1006F0000088000000D4001F00000000000000007F -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000010171000201780003008F0004007FE5 -:10081000000500030006003F000700320008012C1D -:1008200000090046000A0036001001B6001700A2B9 -:100830000022013A00230149002000B400240125D0 -:100840000027004D0028006A002A0060002B00529B -:10085000002F0065003200870034017F003C015604 -:10086000003F00720041018C0044012E00550173CD -:100870000056017A0060000B00610034006200380D -:1008800000630038006400380065003800660038F6 -:10089000006700380068003A00690041006A0048BB -:1008A000006B0048006C0048006D0048006E004876 -:1008B000006F00480000000600000006000000066F -:1008C0000000000600000006000000060000000610 -:1008D0000000000600000006000000060000000600 -:1008E00000000006000000060000000600000006F0 -:1008F00000000006000000060000000600000006E0 -:00000001FF diff --git a/firmware/radeon/RV670_me.bin.ihex b/firmware/radeon/RV670_me.bin.ihex deleted file mode 100644 index 9fbfc0e4438c0897dbc76cf6dd3045b13d211aee..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV670_me.bin.ihex +++ /dev/null @@ -1,1345 +0,0 @@ -:1000000000000000C020040000000000000000000C -:1000100000A0000A000000000000FFFF00284621A9 -:100020000000000000000000D900480000000000AF -:1000300000000000C02004000000000000000000DC -:1000400000A0000A000000000000000000E0000026 -:100050000000000000010000C02946200000000050 -:1000600000000000D900480000000000000000006F -:10007000C0200400000000000000000000A0000AF2 -:10008000000000008100000000204411000000007A -:1000900000000001002048110000000000042004BE -:1000A000006044110000067C0000000000600000B9 -:1000B0000000062400000000006000000000063878 -:1000C00000000000C02008000000000000000F0039 -:1000D000002816220000000000000008002116255C -:1000E000000000000000001800203625000000007D -:1000F0008D000000002044110000000000000004FA -:10010000002F022500000000000000000CE00000AD -:1001100000000018004120000040481100000019B4 -:100120000042200000204811000000008E00000066 -:1001300000204411000000000000002800204A2D8B -:1001400000000000900000000020441100000000AA -:100150000000000000204805000000000000000C26 -:1001600000211622000000000000000300281625D0 -:10017000000000000000001900211A220000000009 -:100180000000000400281A26000000000000000003 -:10019000002914C5000000000000001900203625C9 -:1001A0000000000000000000003A140200000000FF -:1001B00000000016002116250000000000000003CA -:1001C00000281625000000000000001700200E2D5A -:1001D00000000000FFFFFFFC00280E2300000000CD -:1001E00000000000002914A3000000000000001718 -:1001F00000203625000000000000800000280E22AC -:10020000000000000000000700220E230000000094 -:10021000000000000029386E0000000020000000EF -:1002200000280E22000000000000000600210E231E -:1002300000000000000000000029386E00000000EF -:100240000000000000220222000000000000000068 -:1002500014E0000000000038000000002EE0000064 -:1002600000000035000000002CE000000000003716 -:100270000000000000400E2D0000003900000008C2 -:1002800000200E2D00000000000000090040122D8B -:10029000000000460000000100400E2D0000003963 -:1002A00000000000C0200C0000000000003FFFFC28 -:1002B0000028122300000000000000020022122487 -:1002C000000000000000001F00211E2300000000AD -:1002D0000000000014E000000000003E00000008E4 -:1002E00000401C11000000410000000D00201E2DE8 -:1002F000000000000000000F00281E270000000082 -:100300000000000300221E27000000007FC0000044 -:1003100000281A23000000000000001400211A2603 -:10032000000000000000000100331A260000000059 -:100330000000000800221A26000000000000000053 -:1003400000290CC700000000000000270020362410 -:100350000000000000007F000028122100000000C3 -:1003600000001400002F0224000000000000000024 -:100370000CE000000000004B0000000100290E23EB -:10038000000000000000000E0020362300000000E6 -:100390000000E0000020441100000000FFF8000011 -:1003A00000294A230000000000000000003A2C024F -:1003B000000000000000000200220E2B00000000E0 -:1003C000FC00000000280E23000000000000000FC9 -:1003D000002036230000000000001FFF00294A23F0 -:1003E000000000000000002700204A2D000000004F -:1003F000000000000020481100000000000000295B -:1004000000200E2D00000000060A020000294A23E9 -:100410000000000000000000002048110000000063 -:100420000000000000204811000000000000000152 -:1004300000210222000000000000000014E0000083 -:1004400000000061000000002EE000000000005FDE -:10045000000000002CE000000000005E0000000032 -:1004600000400E2D000000620000000100400E2D33 -:10047000000000620000000A00200E2D00000000B5 -:100480000000000B0040122D0000006A0000000078 -:10049000C0200C0000000000003FFFFC00281223D9 -:1004A00000000000000000020022122400000000F2 -:1004B0007FC0000000281623000000000000001488 -:1004C0000021162500000000000000010033162561 -:1004D000000000008000000000280E230000000043 -:1004E0000000000000290CA3000000003FFFFC00FA -:1004F00000290E23000000000000001F00211E2321 -:10050000000000000000000014E000000000006D8A -:100510000000010000401C11000000700000000DF0 -:1005200000201E2D00000000000000F000281E2703 -:10053000000000000000000400221E270000000050 -:100540008100000000204411000000000000000DA8 -:100550000020481100000000FFFFF0FF00281A30C3 -:10056000000000000000A02800204411000000004E -:1005700000000000002948E6000000000000A0186C -:1005800000204411000000003FFFFFFF00284A2325 -:10059000000000000000A010002044110000000036 -:1005A00000000000002048040000000000000030AF -:1005B0000020162D00000000000000020029162572 -:1005C0000000000000000030002036250000000080 -:1005D000000000250020162D000000000000000093 -:1005E000002F00A300000000000000000CC000006D -:1005F00000000083000000260020162D00000000EF -:1006000000000000002F00A4000000000000000017 -:100610000CC000000000008400000000004000004A -:100620000000008A000000250020362300000000A2 -:100630000000002600203624000000000000001703 -:1006400000201E2D000000000000000200210227F3 -:10065000000000000000000014E000000000008A1C -:1006600000000000006000000000065900000000CB -:10067000006000000000064D0000000200210E2274 -:10068000000000000000000014C000000000008D09 -:1006900000000012C040362000000093000000005F -:1006A0002EE0000000000091000000002CE000009F -:1006B000000000900000000200400E2D000000929B -:1006C0000000000300400E2D000000920000000C0E -:1006D00000200E2D00000000000000120020362334 -:1006E000000000000000000300210E2200000000B6 -:1006F0000000000014C00000000000980000A00CE2 -:10070000002044110000000000000000C02048004C -:100710000000000000000000C0404800000000A0F1 -:100720000000A00C002044110000000000000000A8 -:100730000020481100000000000000002EE0000032 -:100740000000009E000000002CE000000000009D62 -:100750000000000200400E2D0000009F000000037A -:1007600000400E2D0000009F0000000C00200E2D08 -:10077000000000000000000000204803000000000E -:1007800000000000003A0C0200000000003F0000E2 -:1007900000280E23000000000000001000210E239E -:1007A00000000000000000110020362300000000BF -:1007B0000000001E0021022B0000000000000000CD -:1007C00014C00000000000A700000016C020362062 -:1007D000000000000000001F0021022B00000000AC -:1007E0000000000014C00000000000AA0000001576 -:1007F000C0203620000000000000000800210E2B61 -:10080000000000000000007F00280E230000000010 -:1008100000000000002F0223000000000000000084 -:100820000CE00000000000E10000000027000000D4 -:10083000000000000000000000600000000002A3B3 -:1008400000000001002F0223000000000000000053 -:100850000AE00000000000B300000000006000009B -:100860000000013A81000000002044110000000057 -:100870000000000600204811000000000000000CED -:1008800000221E300000000099800000002044116A -:1008900000000000000000040020122D00000000F5 -:1008A00000000008002212240000000000000010D8 -:1008B00000201811000000000000000000291CE4C6 -:1008C0000000000000000000006048070000012F49 -:1008D0009B00000000204411000000000000000008 -:1008E00000204802000000009C000000002044118D -:1008F00000000000000000000033146F0000000042 -:100900000000000100333E23000000000000000052 -:10091000D9004800000000000000000000203C0555 -:1009200000000000810000000020441100000000D1 -:100930000000000E00204811000000000000000030 -:1009400000201010000000000000E007002044110B -:10095000000000000000000F0021022B000000003A -:100960000000000014C00000000000CB00F8FF08E9 -:1009700000204811000000009800000000404811CD -:10098000000000DC000000F000280E220000000043 -:10099000000000A0002F0223000000000000000063 -:1009A0000CC00000000000DA0000001100200E2D35 -:1009B0000000000000000001002F022300000000E2 -:1009C000000000000CE00000000000D50000000264 -:1009D000002F022300000000000000000CE00000D7 -:1009E000000000D400003F0000400C11000000D6C1 -:1009F00000001F0000400C11000000D600000F0096 -:100A000000200C11000000000038000900294A23D2 -:100A1000000000003F00000000280E2B0000000036 -:100A20000000000200220E2300000000000000076A -:100A300000494A23000000DC00380F09002048115B -:100A400000000000680000070020481100000000BE -:100A50000000000800214A270000000000000000FC -:100A60000020481100000000060A020000294A2464 -:100A700000000000000000000020481100000000FD -:100A80000000000000204811000000000000A20249 -:100A9000002044110000000000FF000000280E228A -:100AA000000000000000008000294A230000000030 -:100AB0000000002700200E2D00000000000000268E -:100AC0000020122D0000000000000000002F008315 -:100AD00000000000000000000CE00000000000EA40 -:100AE000000000000060000000000653000000004D -:100AF00000400000000000EB00000000006000006B -:100B000000000656000000070020222D0000000013 -:100B10000000000500220E2200000000001000006E -:100B200000280E23000000000000000000292068BB -:100B30000000000000000000003A0C02000000006D -:100B4000000000EF00280E2300000000000000005D -:100B500000292068000000000000001700200E2D72 -:100B6000000000000000000300210223000000003C -:100B70000000000014E00000000000F80000000B7E -:100B800000210228000000000000000014C0000046 -:100B9000000000F8000004000029222800000000E6 -:100BA0000000001400203628000000000000001C97 -:100BB00000210E22000000000000000014C0000010 -:100BC000000000FD0000A30C002044110000000004 -:100BD0000000000000204811000000000000001E7E -:100BE00000210E22000000000000000014C00000E0 -:100BF0000000010B0000A30F0020441100000000C2 -:100C00000000001100200E2D000000000000000177 -:100C1000002F022300000000000000000CC00000B4 -:100C200000000104FFFFFFFF004048110000010B1E -:100C300000000002002F022300000000000000005E -:100C40000CC00000000001070000FFFF0040481139 -:100C50000000010B00000004002F02230000000030 -:100C6000000000000CC000000000010A000000FFAE -:100C7000004048110000010B000000010020481155 -:100C8000000000000002C400002044110000000029 -:100C90000000001F00210E220000000000000000E4 -:100CA00014C00000000001120000001040210E20BE -:100CB00000000000000000130020362300000000A8 -:100CC0000000001840224A20000000000000001030 -:100CD000C0424A20000001140000000000200C1156 -:100CE0000000000000000013002036230000000078 -:100CF000000000000020481100000000000000007B -:100D000000204811000000000000000A002010111F -:100D10000000000000000000002F0224000000007E -:100D2000000000000CE000000000011B00000000BB -:100D300000204811000000000000000100531224B0 -:100D400000000117FFBFFFFF00283A2E000000003F -:100D50000000001B00210222000000000000000033 -:100D600014C000000000012E81000000002044118A -:100D7000000000000000000D0020481100000000ED -:100D80000000001800220E3000000000FC000000EF -:100D900000280E2300000000810000000020441104 -:100DA000000000000000000E0020481100000000BC -:100DB0000000000000201010000000000000E00E05 -:100DC000002044110000000007F8FF08002048112F -:100DD000000000000000000000294A23000000007D -:100DE0000000001C00201E2D000000000000000874 -:100DF00000214A27000000000000000000204811E8 -:100E000000000000060A020000294A240000000039 -:100E10000000000000204811000000000000000059 -:100E200000204811000000000000000000800000C9 -:100E300000000000810000000020441100000000BC -:100E40000000000100204811000000000000217C8B -:100E50000020441100000000008000000020481124 -:100E60000000000000000000002048060000000014 -:100E70000000000800214A270000000000000000D8 -:100E800017000000000000000004217F00604411F2 -:100E90000000067C0000001F00210230000000005E -:100EA0000000000014C000000000067B00000004E9 -:100EB00000404C1100000135810000000020441169 -:100EC00000000000000000010020481100000000A8 -:100ED000000021F800204411000000000000001C68 -:100EE0000020481100000000000421F900604411B6 -:100EF0000000067C0000001100210230000000000C -:100F00000000000014E000000000013C00000000B0 -:100F100000800000000000000000000000600000F1 -:100F20000000000B00000000006004110000031529 -:100F3000000000000020041100000000000000007C -:100F400000600811000001B2000000000060000015 -:100F5000000001600000FFFF40280E20000000009C -:100F600000000010C0211220000000000000FFFF60 -:100F7000402806200000000000000010C0210A20C8 -:100F800000000000000000000034146100000000B8 -:100F90000000000000741882000002BB0001A1FDE7 -:100FA00000604411000002E000003FFF002F022F0C -:100FB00000000000000000000CC00000000001471D -:100FC00000000000C040040000000001000000001C -:100FD000006000000000000B000000000060041131 -:100FE00000000315000000000020041100000000B4 -:100FF0000000000000600811000001B200003FFF87 -:10100000002F022F00000000000000000CE0000094 -:10101000000000000000000000600000000001600F -:101020000000001040210E20000000000000FFFF23 -:10103000C0281220000000000000001040211620EF -:10104000000000000000FFFFC0681A20000002BB83 -:101050000001A1FD00604411000002E000003FFF1C -:10106000002F022F00000000000000000CC0000054 -:101070000000015800000000C04004000000000112 -:101080000000225C0020441100000000000000016C -:1010900000300A2F000000000000000100210A2299 -:1010A000000000000000000300384A220000000099 -:1010B0000000225600204411000000000000001A29 -:1010C00000204811000000000000A1FC0020441195 -:1010D0000000000000000001008048110000000036 -:1010E00000000000006000000000000B0000000095 -:1010F000006000000000018F0000000000600000A0 -:10110000000001A000003FFF002F022F00000000A0 -:10111000000000000CE000000000000000000000E3 -:1011200000202C0800000000000000000020241116 -:101130000000000000000000002028110000000056 -:10114000000022560020441100000000000000169C -:1011500000204811000000000000225C0020441123 -:101160000000000000000003002048110000000003 -:1011700093800000002044110000000000000002E5 -:1011800000221E290000000000000000007048EB53 -:101190000000019C0000000000600000000002BB95 -:1011A00000000001403306200000000000000000A5 -:1011B000C03024090000000000003FFF002F022F74 -:1011C00000000000000000000CE000000000000033 -:1011D0000000000000600000000002A3000000000A -:1011E000002F022100000000000000000AE00000C3 -:1011F0000000018100000000006000000000013AD2 -:101200000000000000400000000001869500000082 -:10121000002044110000000000000000002F022107 -:1012200000000000000000000CE00000000001864B -:1012300000000000C0204800000000000000000185 -:10124000005306210000018292000000002044119A -:101250000000000000000000C0604800000001978E -:101260000001A1FD00204411000000000000001159 -:101270000020062D00000000000000000078042A75 -:10128000000002FB00000000002028090000000010 -:1012900000003FFF002F022F0000000000000000B0 -:1012A0000CC000000000017400000000C0400400F9 -:1012B000000000010000021000600411000003158E -:1012C00000003FFF002F022F000000000000000080 -:1012D0000CE000000000019400000015C020362042 -:1012E0000000000000000016C020362000000000B2 -:1012F0003F800000002004110000000046000000B4 -:1013000000600811000001B2000000000080000031 -:10131000000000000000A1FC0020441100000000BB -:1013200000003FFF002F022F00000000000000001F -:101330000CC000000000019B00000001008048116B -:1013400000000000000000210080481100000000A3 -:101350000000FFFF40280E200000000000000010E9 -:10136000C0211220000000000000FFFF40281620CE -:101370000000000000000010C0811A2000000000E2 -:101380008100000000204411000000000000000661 -:1013900000204811000000000000000800221E305C -:1013A000000000000000002900201A2D00000000AD -:1013B0000000E0000020441100000000FFFBFF09D6 -:1013C00000204811000000000000000F0020222D26 -:1013D0000000000000001FFF00294A280000000054 -:1013E000000000060020222D000000000000000088 -:1013F000002920E80000000000000000002048084C -:101400000000000000000000002048110000000063 -:10141000060A020000294A26000000000000000021 -:1014200000204811000000000000000000204811CA -:101430000000000000000100002018110000000062 -:101440000000000800621E280000012F00000008B4 -:1014500000822228000000000002C0000020441189 -:10146000000000000000001500600E2D000001BD0E -:101470000000001600600E2D000001BD0000C00835 -:1014800000204411000000000000001700200E2D75 -:10149000000000000000000014C00000000001B9BE -:1014A0000000000000200411000000000000000007 -:1014B0000020480100000000390000000020481111 -:1014C00000000000000000000020481100000000A3 -:1014D000000000000080480200000000000000182A -:1014E00000202E2D0000000000000000003B0D63D6 -:1014F000000000000000000800224A230000000055 -:101500000000001000224A23000000000000001824 -:1015100000224A2300000000000000000080480371 -:101520000000000000000000006000000000000B50 -:10153000000010000060041100000315000000000E -:1015400000200411000000000000000000600811ED -:10155000000001B2000000070021062F000000007B -:101560000000001300200A2D000000000000000110 -:1015700000202C11000000000000FFFF4028222066 -:10158000000000000000000F0026222800000000DC -:101590000000001040212620000000000000000F85 -:1015A000002626290000000000000000002028027C -:1015B000000000000000225600204411000000003E -:1015C0000000001B00204811000000000000000087 -:1015D000002F022100000000000000000CE00000CD -:1015E000000001E00000225C002044110000000027 -:1015F0000000008100204811000000000000A1FC54 -:1016000000204411000000000000000100204811EB -:10161000000000000000008000201C1100000000FD -:1016200000000000002F0227000000000000000062 -:101630000CE00000000001DC000000000060000081 -:10164000000001E90000000100531E27000001D83E -:101650000000000100202C11000000000000001F0D -:1016600000280A22000000000000001F00282A2A8B -:10167000000000000000000100530621000001D11D -:101680000000225C00204411000000000000000265 -:1016900000304A2F000000000000A1FC002044118F -:1016A00000000000000000010020481100000000C0 -:1016B0000000000100301E2F0000000000000000AC -:1016C000002F022700000000000000000CE00000D6 -:1016D000000000000000000000600000000001E9C0 -:1016E0000000000100531E27000001E50000FFFF7D -:1016F00040280E20000000000000000F00260E23EE -:101700000000000000000010C021122000000000B6 -:101710000000000F0026122400000000000000005E -:1017200000201411000000000000000000601811EB -:10173000000002BB0001A1FD0020441100000000D8 -:1017400000000000002F022B00000000000000003D -:101750000CE00000000001F8000000100022162834 -:1017600000000000FFFF0000002816250000000018 -:101770000000FFFF00281A29000000000000000000 -:10178000002948C500000000000000000020480AB1 -:10179000000000000000000000202C1100000000EC -:1017A000000000100022162300000000FFFF0000D0 -:1017B00000281625000000000000FFFF00281A2462 -:1017C0000000000000000000002948C500000000E3 -:1017D0000000000000731503000002050000000077 -:1017E0000020180500000000000000000073152410 -:1017F0000000020500000000002D14C500000000DC -:1018000000000000003008A20000000000000000FE -:101810000020480200000000000000000020280214 -:101820000000000000000000002020030000000075 -:101830000000000000802404000000000000000FF1 -:1018400000210225000000000000000014C000007C -:101850000000067B00000000002B140500000000C3 -:1018600000000001009016250000000000000000AC -:10187000006000000000000B000000000060041188 -:10188000000003150000000000200411000000000B -:101890000000000000600811000001B200002256A4 -:1018A00000204411000000000000001A00294A2214 -:1018B0000000000000000000C02000000000000048 -:1018C00000003FFF002F022F00000000000000007A -:1018D0000CE000000000000000000000C020040038 -:1018E000000000000000225C002044110000000005 -:1018F0000000000300384A21000000000000A1FCA5 -:1019000000204411000000000000000100204811E8 -:10191000000000000000FFFF40281220000000002F -:1019200000000010C0211A20000000000000FFFF8E -:1019300040280E200000000000000010C0211620EA -:10194000000000000000000000741465000002BBED -:101950000001A1FD00604411000002E00000000150 -:10196000003306210000000000000000002F0221CB -:1019700000000000000000000CC000000000021980 -:1019800000003FFF002F022F0000000000000000B9 -:101990000CC000000000021200000000C040040063 -:1019A0000000000100000000006000000000063898 -:1019B000000000000040040F0000021300000000BF -:1019C000006000000000062400000000006000002D -:1019D000000006380000021000600411000003152A -:1019E0000000000000600000000001A000000000F6 -:1019F000006000000000019C00000000006000008A -:101A0000000002BB0000000000600000000002A314 -:101A1000938000000020441100000000000000003E -:101A2000002048080000000000000000002F022FE6 -:101A300000000000000000000AE000000000023288 -:101A400000000000006000000000013A00000000FB -:101A50000040000000000236950000000020441104 -:101A60000000000000000000002F022F0000000016 -:101A7000000000000CE00000000002360000000042 -:101A8000C0404800000002339200000000204411D2 -:101A90000000000000000000C0204800000000001E -:101AA0000000225600204411000000000000001633 -:101AB00000204811000000000000225C00204411BA -:101AC000000000000000000300204811000000009A -:101AD0000000A1FC002044110000000000000001F3 -:101AE00000204811000000000001A1FD0020441169 -:101AF000000000000000000000600411000002FB74 -:101B000000000000C04004000000000100000000D0 -:101B100000600000000006240000A00C002044111A -:101B20000000000000000000C0204800000000008D -:101B300000000000C040480000000000000000005D -:101B4000006000000000000B0000001840210A2087 -:101B50000000000000000003002F0222000000002F -:101B6000000000000AE000000000024C0000001429 -:101B70000020222D00000000000801010029222879 -:101B800000000000000000140020362800000000C3 -:101B90000000A30C00204411000000000000000021 -:101BA000C02048000000000000000000C0204800E5 -:101BB0000000000000000000C0404800000002518A -:101BC00000000000006000000000000B000000109A -:101BD00000600411000003153F8000000020041184 -:101BE000000000000000000000600811000001B2C9 -:101BF0000000225C002044110000000000000003EF -:101C000000204811000000000000000000600000FB -:101C10000000027C0000001700201E2D00000000C4 -:101C20000000000100211E2700000000000000004D -:101C300014E000000000026A0000001200201E2DC7 -:101C4000000000000000FFFF00281E270000000029 -:101C50000000000000341C2700000000000000000D -:101C600012C000000000025F0000000000201C11F4 -:101C70000000000000000000002F00E50000000050 -:101C80000000000008C00000000002620000000028 -:101C900000201407000000000000001200201E2D8C -:101CA000000000000000001000211E2700000000BE -:101CB0000000000000341C4700000000000000008D -:101CC00012C00000000002670000000000201C118C -:101CD0000000000000000000002F00E600000000EF -:101CE0000000000008C000000000026A00000000C0 -:101CF0000020180700000000000000000060000045 -:101D0000000002C100002256002044110000000023 -:101D1000000000000034202300000000000000004C -:101D200012C00000000002720000000000342044D5 -:101D3000000000000000000012C00000000002715E -:101D40000000001600404811000002760000001854 -:101D500000404811000002760000000000342044DA -:101D6000000000000000000012C00000000002752A -:101D70000000001700404811000002760000001922 -:101D800000204811000000000000A1FC00204411C8 -:101D900000000000000000010020481100000000C9 -:101DA0000001A1FD00604411000002E900003FFFB6 -:101DB000002F022F00000000000000000CC00000F7 -:101DC0000000025600000000C040040000000001B6 -:101DD0000000001040210620000000000000FFFF6E -:101DE000C0280A20000000000000001040210E2042 -:101DF000000000000000FFFFC028122000000000CB -:101E00000000001040211620000000000000FFFF2D -:101E1000C0881A200000000081000000002044114A -:101E20000000000000000001002048110000000038 -:101E300000042004006044110000067C0000000043 -:101E4000006000000000062400000000C0600000E8 -:101E5000000002A30000000500200A2D0000000081 -:101E60000000000800220A22000000000000002BF1 -:101E700000201A2D000000000000001C00201E2D74 -:101E8000000000000000700000281E270000000075 -:101E90000000000000311CE6000000000000002AE5 -:101EA00000201A2D000000000000000C00221A265D -:101EB0000000000000000000002F00E6000000000D -:101EC0000000000006E00000000002920000000098 -:101ED00000201C11000000000000000000200C1178 -:101EE000000000000000002B00203623000000004E -:101EF0000000001000201811000000000000000089 -:101F000000691CE20000012F9380000000204411B2 -:101F10000000000000000000002048070000000052 -:101F200095000000002044110000000000000000A7 -:101F3000002F022F00000000000000000CE0000055 -:101F40000000029D0000000100333E2F0000000051 -:101F500000000000D90048000000000092000000CE -:101F6000002044110000000000000000C0204800D4 -:101F7000000000000000001C0040362700000000A8 -:101F80000000000CC0220A20000000000000002910 -:101F9000002036220000000000000028C04036204B -:101FA000000000000000A2A4002044110000000076 -:101FB000000000090020481100000000A1000000FE -:101FC00000204411000000000000000100804811C2 -:101FD000000000000000002100201E2D0000000075 -:101FE00000000000002C1CE30000000000000021A5 -:101FF00000203627000000000000002200201E2DD7 -:102000000000000000000000002C1CE400000000A4 -:1020100000000022002036270000000000000023FE -:1020200000201E2D0000000000000000003120A351 -:102030000000000000000000002D1D07000000004F -:1020400000000023002036270000000000000024CC -:1020500000201E2D0000000000000000003120C400 -:102060000000000000000000002D1D07000000001F -:10207000000000240080362700000000000000213E -:10208000002036230000000000000022002036243B -:10209000000000000000000000311CA30000000050 -:1020A0000000002300203627000000000000000090 -:1020B00000311CC40000000000000024008036270E -:1020C000000000000000001A002036270000000079 -:1020D0000000001B00203628000000000000001750 -:1020E00000201E2D00000000000000020021022739 -:1020F000000000000000000014C00000000002DC2E -:102100000000000000400000000002D90000001A9A -:1021100000203627000000000000001B00203628A9 -:10212000000000000000001700201E2D000000002D -:102130000000000200210227000000000000000053 -:1021400014E00000000002D9000000030021022773 -:10215000000000000000000014E00000000002DCAD -:102160000000002300201E2D0000000000000000E1 -:10217000002E00E1000000000000000002C000008E -:10218000000002DC0000002100201E2D00000000E5 -:1021900000000000003120A100000000000000004D -:1021A000002E00E8000000000000000006C0000053 -:1021B000000002DC0000002400201E2D00000000B2 -:1021C00000000000002E00E20000000000000000FF -:1021D00002C00000000002DC0000002200201E2DD2 -:1021E0000000000000000000003120C200000000DC -:1021F00000000000002E00E80000000000000000C9 -:1022000006C00000000002DC0000000000600000CA -:10221000000006590000000000600000000002B548 -:102220000000000000400000000002DE000000008E -:1022300000600000000002B5000000000060000027 -:10224000000006500000000000400000000002DE18 -:102250000000000000600000000002A70000000075 -:1022600000400000000002DE0000001A00201E2DC9 -:10227000000000000000001B0080222D0000000074 -:102280000000001000221E230000000000000000DB -:1022900000294887000000000000000000311CA356 -:1022A000000000000000001000221E2700000000B7 -:1022B0000000000000294887000000000000001016 -:1022C00000221E230000000000000000003120C496 -:1022D000000000000000FFFF00282228000000008E -:1022E0000000000000894907000000000000001005 -:1022F00000221E2300000000000000000029488783 -:10230000000000000000001000221E21000000005C -:102310000000000000294847000000000000000005 -:1023200000311CA3000000000000001000221E2746 -:1023300000000000000000000029488700000000A5 -:102340000000000000311CA100000000000000108F -:1023500000221E270000000000000000002948475E -:10236000000000000000001000221E2300000000FA -:1023700000000000003120C4000000000000FFFF4A -:102380000028222800000000000000000029490762 -:10239000000000000000001000221E2100000000CC -:1023A00000000000003120C2000000000000FFFF1C -:1023B00000282228000000000000000000894907D2 -:1023C000000000000000001000221E23000000009A -:1023D0000000000000294887000000000000000104 -:1023E00000220A210000000000000000003308A2C3 -:1023F000000000000000001000221E22000000006B -:102400000000001000212222000000000000000057 -:1024100000294907000000000000000000311CA353 -:10242000000000000000001000221E270000000035 -:1024300000000000002948870000000000000001A3 -:1024400000220A210000000000000000003008A265 -:10245000000000000000001000221E22000000000A -:1024600000000010002122220000000000000000F7 -:1024700000294907000000000000001000221E2370 -:102480000000000000000000003120C40000000037 -:102490000000FFFF002822280000000000000000CC -:1024A000002949070000000000000000003808C5AE -:1024B00000000000000000000030084100000000A3 -:1024C0000000000100220A220000000000000000BD -:1024D000003308A2000000000000001000221E22AD -:1024E0000000000000000010002122220000000077 -:1024F00000000000008949070000000000000017EC -:102500000020222D000000000000000014C0000088 -:1025100000000318FFFFFFEF002806210000000065 -:10252000000000140020222D000000000000F8E050 -:1025300000204411000000000000000000294901B3 -:1025400000000000000000000089490100000000B8 -:102550000000000000204811000000000000000002 -:102560000020481100000000060A02000080481107 -:102570000000000000000000C0200000000000007B -:1025800097000000C020441100000000000000007F -:10259000C0204811000000008A0000000020441103 -:1025A00000000000000000000020481100000000B2 -:1025B0000000225C00204411000000000000000028 -:1025C000C0204800000000000000A1FC00204411D1 -:1025D0000000000000000000C020480000000000D3 -:1025E00000000000C0200400000000000000000007 -:1025F00000A0000A00000000970000000020441125 -:102600000000000000000000002048110000000051 -:102610008A000000002044110000000000000000BB -:1026200000204811000000000000225C002044113E -:102630000000000000000000C02048000000000072 -:102640000000A1FC00204411000000000000000078 -:10265000C02048000000000000000000C02004006E -:10266000000000000000000000A0000A00000000C0 -:10267000970000000020441100000000000000004E -:1026800000204811000000008A00000000204411D2 -:1026900000000000000000000020481100000000C1 -:1026A0000000225C00204411000000000000000037 -:1026B000C0204800000000000000A1FC00204411E0 -:1026C0000000000000000000C020480000000000E2 -:1026D0000001A1FD002044110000000000000000E6 -:1026E000D90048000000000000000000C0200400E5 -:1026F000000000000000000000A0000A0000000030 -:1027000000002257002044110000000000000003D8 -:10271000C0484A20000000000000225D0020441153 -:102720000000000000000000C04048000000000061 -:1027300000000000006000000000063800000000FB -:10274000C0200800000000000000225C00204411AE -:10275000000000000000000300384A2200000000D2 -:102760000000A1FC00204411000000000000000057 -:10277000C0204800000000000001A1FD002044111D -:102780000000000000000000002F022200000000F6 -:10279000000000000CE0000000000000000000004D -:1027A00040204800000000000000000140304A20A6 -:1027B0000000000000000002C0304A2000000000BD -:1027C0000000000100530A220000034B0000003FFC -:1027D000C0280A20000000008100000000204411F1 -:1027E000000000000000000100204811000000006F -:1027F000000021F800204411000000000000001833 -:102800000020481100000000000421F9006044117C -:102810000000067C000000110021023000000000D2 -:102820000000000014E00000000003540000001449 -:10283000002F022200000000000000000CC0000079 -:10284000000003620001A2A4002044110000000067 -:1028500000000000006048020000036A0000210040 -:10286000002044110000000000000000C0204800CB -:102870000000000000000000C02048000000000030 -:1028800000000000C0204800000000000000000020 -:10289000C04048000000000000000004002F022299 -:1028A00000000000000000000CC0000000000366F3 -:1028B0000001A2A40020441100000000000000005C -:1028C000004048020000035D00000028002F0222A3 -:1028D00000000000000000000CC00000000005B374 -:1028E0000001A2A40020441100000000000000002C -:1028F000004048020000035D0000002C0020362646 -:102900000000000000000049002018110000000035 -:102910000000003F002048110000000000000001FE -:1029200000331A260000000000000000002F0226DD -:1029300000000000000000000CC000000000036C5C -:102940000000002C00801A2D000000000000003F55 -:10295000C0280A200000000000000015002F0222FD -:1029600000000000000000000CE0000000000382F6 -:1029700000000006002F02220000000000000000FE -:102980000CE00000000003AD00000016002F022242 -:1029900000000000000000000CE00000000003AF99 -:1029A00000000020002F02220000000000000000B4 -:1029B0000CE00000000003980000000F002F02222E -:1029C00000000000000000000CE00000000003A474 -:1029D00000000010002F0222000000000000000094 -:1029E0000CE00000000003A40000001E002F0222E3 -:1029F00000000000000000000CE000000000038C5C -:102A00000000A2A40020441100000000000000000B -:102A100000404802000000000800000000290A22CF -:102A2000000000000000000340210E200000000014 -:102A30000000000CC021122000000000000800006F -:102A4000002812240000000000000014C0221620FC -:102A50000000000000000000002914A40000000095 -:102A60000000A2A4002044110000000000000000AB -:102A7000002948A2000000000000A1FE002044112F -:102A800000000000000000000040480300000000BB -:102A9000810000000020441100000000000000013F -:102AA0000020481100000000000021F8002044111F -:102AB0000000000000000016002048110000000087 -:102AC000000421F9006044110000067C000000159C -:102AD00000210230000000000000000014E00000AF -:102AE0000000038E0000210E0020441100000000B1 -:102AF00000000000C02048000000000000000000AE -:102B0000C0204800000000000000A2A400204411E2 -:102B1000000000000000000000404802000000002B -:102B200081000000002044110000000000000001AE -:102B30000020481100000000000021F8002044118E -:102B400000000000000000170020481100000000F5 -:102B5000000421F9006044110000067C000000031D -:102B600000210230000000000000000014E000001E -:102B70000000039A0000210800204411000000001A -:102B800000000000C020480000000000000000001D -:102B9000C0204800000000000000A2A40020441152 -:102BA000000000000000000000404802000000009B -:102BB0000000A2A40020441100000000000000005A -:102BC00000204802000000008000000000204411A6 -:102BD000000000000000000000204811000000007C -:102BE00081000000002044110000000000000010DF -:102BF000002048110000000000000000002000102C -:102C0000000000000000000014C00000000003AA43 -:102C10000000000000400000000000000001A2A42D -:102C20000020441100000000000000060040481190 -:102C3000000000000001A2A40020441100000000D8 -:102C400000000016006048110000036A0000000048 -:102C5000004000000000000000000000C02008004C -:102C60000000000000000000C0200C000000000078 -:102C70000000001D002102230000000000000000F1 -:102C800014E00000000003C4810000000020441193 -:102C900000000000000000010020481100000000BA -:102CA000000021F80020441100000000000000187E -:102CB0000020481100000000000421F900604411C8 -:102CC0000000067C0000001100210230000000001E -:102CD0000000000014E00000000003B80000210024 -:102CE0000020441100000000000000000020480205 -:102CF0000000000000000000002048030000000069 -:102D0000BABECAFE0020481100000000CAFEBABECA -:102D100000204811000000000000A2A4002044117F -:102D20000000000000000004004048110000000006 -:102D3000000021700020441100000000000000008D -:102D400000204802000000000000000000204803AE -:102D5000000000008100000000204411000000007D -:102D60000000000A002048110000000000000000E0 -:102D700000200010000000000000000014C000004F -:102D8000000003C98C000000002044110000000076 -:102D9000CAFEBABE004048110000000081000000D9 -:102DA0000020441100000000000000010020481134 -:102DB0000000000000003FFF40280A200000000043 -:102DC0008000000040280E200000000040000000AD -:102DD000C028122000000000000400000069462204 -:102DE0000000067C0000000000201410000000001D -:102DF00000000000002F022300000000000000007F -:102E00000CC00000000003D700000000C040180004 -:102E1000000003DA00003FFFC0281A200000000075 -:102E200000040000006946260000067C0000000047 -:102E3000002018100000000000000000002F0224F5 -:102E400000000000000000000CC00000000003DDD6 -:102E500000000000C0401C00000003E000003FFF35 -:102E6000C0281E2000000000000400000069462762 -:102E70000000067C0000000000201C100000000084 -:102E800000000000002044020000000000000000DC -:102E9000002820C50000000000000000004948E8AC -:102EA00000000000A58000000020081100000000C4 -:102EB0000000200000200C11000000008300000032 -:102EC00000604411000004080000000000204402DB -:102ED0000000000000000000C020480000000000CA -:102EE0000000000040204800000000000000001F1B -:102EF000C0210220000000000000000014C00000FB -:102F0000000003ED0000201000204411000000002C -:102F10000000800000204811000000000000FFFFBA -:102F2000C0481220000003F5A7800000002008110F -:102F3000000000000000A00000200C1100000000B4 -:102F4000830000000060441100000408000000003D -:102F5000002044020000000000000000C0204800E3 -:102F60000000000000000000C02048000000000039 -:102F70000000FFFFC02812200000000083000000B6 -:102F800000204411000000000000000000304883D1 -:102F90000000000084000000002044110000000038 -:102FA00000000000C02048000000000000000000F9 -:102FB0001D000000000000008300000000604411BC -:102FC0000000040800000000C040040000000001F0 -:102FD000A980000000200811000000000000C000CF -:102FE00000400C11000003F0AB800000002008112D -:102FF000000000000000F8E000400C11000003F0A9 -:10300000AD80000000200811000000000000F880E2 -:1030100000400C11000003F0B380000000200811F4 -:10302000000000000000F3FC00400C11000003F061 -:10303000AF80000000200811000000000000E00048 -:1030400000400C11000003F0B180000000200811C6 -:10305000000000000000F00000400C11000003F030 -:1030600083000000002044110000000000002148FF -:1030700000204811000000008400000000204411DE -:103080000000000000000000C02048000000000018 -:10309000000000001D000000000000000000000013 -:1030A000008000000000000001182000C030462011 -:1030B0000000000000000000D900480000000000EF -:1030C00000000000C020040000000000000000001C -:1030D00000A0000A000000000218A000C030462036 -:1030E0000000000000000000D900480000000000BF -:1030F00000000000C02004000000000000000000EC -:1031000000A0000A000000000318C000C0304620E4 -:103110000000000000000000D9004800000000008E -:1031200000000000C02004000000000000000000BB -:1031300000A0000A000000000418F8E0C03046209B -:103140000000000000000000D9004800000000005E -:1031500000000000C020040000000000000000008B -:1031600000A0000A000000000518F880C0304620CA -:103170000000000000000000D9004800000000002E -:1031800000000000C020040000000000000000005B -:1031900000A0000A000000000618E000C030462031 -:1031A0000000000000000000D900480000000000FE -:1031B00000000000C020040000000000000000002B -:1031C00000A0000A000000000718F000C0304620F0 -:1031D0000000000000000000D900480000000000CE -:1031E00000000000C02004000000000000000000FB -:1031F00000A0000A000000000818F3FCC0304620C0 -:103200000000000000000000D9004800000000009D -:1032100000000000C02004000000000000000000CA -:1032200000A0000A000000000000003000200A2D6D -:103230000000000000000000C0290C400000000059 -:1032400000000030002036230000000000000000D5 -:10325000C0200400000000000000000000A0000AE0 -:103260000000000086000000002044110000000063 -:103270000000000000404801000000008500000040 -:10328000C020441100000000000000000040480180 -:10329000000000000000217C00204411000000001C -:1032A00000000000C02048000000000000000000F6 -:1032B000C02048000000000000000000C0204800BE -:1032C0000000000081000000002044110000000008 -:1032D0000000000100204811000000000000000074 -:1032E000C0200800000000000000000017000000DF -:1032F000000000000004217F006044110000067CF3 -:103300000000001F0021023000000000000000004B -:1033100014C00000000000000000000000404C024B -:103320000000043E00000000C0200C00000000006F -:1033300000000000C020100000000000000000009D -:10334000C02014000000000000000000C020180091 -:103350000000000000000000C0201C000000000071 -:1033600000007F0000280A21000000000000450046 -:10337000002F022200000000000000000CE000000E -:103380000000044C00000000C020200000000000ED -:103390000000000017000000000000000000001006 -:1033A00000280A230000000000000010002F022265 -:1033B00000000000000000000CE0000000000454C9 -:1033C0008100000000204411000000000000000106 -:1033D000002048110000000000040000006946249D -:1033E0000000067C000000000040000000000459BE -:1033F00081000000002044110000000000000000D7 -:1034000000204811000000000000216D0020441140 -:103410000000000000000000002048040000000040 -:103420000000000000604805000006810000000068 -:10343000002824F0000000000000000700280A23F4 -:103440000000000000000001002F02220000000028 -:10345000000000000AE0000000000460000000001E -:10346000002F00C9000000000000000004E0000080 -:103470000000047900000000004000000000048605 -:1034800000000002002F02220000000000000000E7 -:103490000AE000000000046500000000002F00C9E1 -:1034A000000000000000000002E0000000000479BD -:1034B000000000000040000000000486000000033F -:1034C000002F022200000000000000000AE00000BF -:1034D0000000046A00000000002F00C90000000086 -:1034E000000000000CE00000000004790000000073 -:1034F000004000000000048600000004002F0222AB -:1035000000000000000000000AE000000000046F5E -:1035100000000000002F00C90000000000000000B3 -:103520000AE00000000004790000000000400000F4 -:103530000000048600000005002F022200000000A9 -:10354000000000000AE00000000004740000000019 -:10355000002F00C9000000000000000006E000008D -:103560000000047900000000004000000000048614 -:1035700000000006002F02220000000000000000F2 -:103580000AE000000000047900000000002F00C9DC -:10359000000000000000000008E0000000000479C6 -:1035A00000000000004000000000048600007F00D2 -:1035B00000280A210000000000004500002F022220 -:1035C00000000000000000000AE000000000000011 -:1035D0000000000800210A23000000000000000095 -:1035E00014C0000000000483000021690020441181 -:1035F0000000000000000000C020480000000000A3 -:1036000000000000C0204800000000000000000092 -:10361000C020480000000000CAFEBABE00404811A9 -:103620000000000000000000C02044000000000076 -:1036300000000000C02000000000000000000000AA -:10364000C04048000000000000007F0000280A2160 -:103650000000000000004500002F022200000000D2 -:10366000000000000AE000000000048C00000000E0 -:10367000C02000000000000000000000C02000008A -:103680000000000000000000C0400000000000003A -:103690000000000000404C080000044C0000000046 -:1036A000C0200800000000000000001040210E2093 -:1036B0000000000000000011402112200000000066 -:1036C00000000012402116200000000000002169C7 -:1036D000002044110000000000000000002048020B -:1036E0000000000000000000002102250000000092 -:1036F0000000000014E00000000004960004000038 -:10370000C0494A2000000497FFFBFFFFC0284A2061 -:103710000000000000000000002102230000000063 -:103720000000000014E00000000004A300000000FE -:10373000C02048000000000000000000C020480039 -:103740000000000000000000002102240000000032 -:103750000000000014C00000000000008100000014 -:1037600000204411000000000000000C002048115F -:103770000000000000000000002000100000000019 -:103780000000000014C000000000049FA000000022 -:103790000020441100000000CAFEBABE00404811DB -:1037A0000000000081000000002044110000000023 -:1037B0000000000400204811000000000000216B00 -:1037C000002044110000000000000000C02048104C -:1037D00000000000810000000020441100000000F3 -:1037E0000000000500204811000000000000216CCE -:1037F000002044110000000000000000C02048101C -:103800000000000000000000002F02240000000063 -:10381000000000000CE000000000000000000000BC -:10382000004000000000049D00000000C0210A20AC -:10383000000000000000000014C00000000004B6FA -:103840008100000000204411000000000000000082 -:1038500000204811000000000000216D00204411EC -:103860000000000000000000C02048000000000030 -:1038700000000000C0604800000006810000000059 -:1038800000400000000004BA810000000020441144 -:1038900000000000000000010020481100000000AE -:1038A00000040000C02946200000000000000000C5 -:1038B000C06000000000067C000000010021022220 -:1038C000000000000000000014C00000000004C15F -:1038D00000002169002044110000000000000000E9 -:1038E000C02048000000000000000000C020480088 -:1038F0000000000000000000002048100000000050 -:10390000CAFEBABE004048110000000000000000DE -:10391000C02044000000000000000000C04048102B -:1039200000000000810000000020441100000000A1 -:10393000000000010020481100000000000021F8F4 -:1039400000204411000000000000000E002048117B -:1039500000000000000421F9006044110000067C12 -:103960000000000000210230000000000000000004 -:1039700014C00000000004C3000021800020441196 -:103980000000000000000000C0204800000000000F -:1039900000000000C0200000000000000000000047 -:1039A000C02048000000000000000000C02000000F -:1039B0000000000000000000C040480000000000BF -:1039C0000000000300333E2F000000000000000153 -:1039D00000210221000000000000000014E00000AF -:1039E000000004F30000002C00200A2D000000005D -:1039F0000004000018E00C11000004E200000001C7 -:103A000000333E2F00000000000021690020441117 -:103A1000000000000000000000204802000000003C -:103A20000000000000204803000000000000000823 -:103A300000300A220000000000000000C020480002 -:103A40000000000000000000C0204800000000004E -:103A50000000216900204411000000000000000067 -:103A60000020480200000000000000000020480381 -:103A7000000000000000000800300A2200000000E2 -:103A800000000000C020480000000000000000000E -:103A9000D8C04800000004D600002169002044116D -:103AA00000000000000000000020480200000000AC -:103AB0000000000000204803000000000000000893 -:103AC00000300A220000000000000000C020480072 -:103AD0000000000000000000C020480000000000BE -:103AE0000000002D0020122D00000000000000004A -:103AF00000290C830000000000002169002044110F -:103B0000000000000000000000204802000000004B -:103B10000000000000204803000000000000000832 -:103B200000300A220000000000000000C020480011 -:103B30000000000000000000C0204800000000005D -:103B4000000000110021022400000000000000001D -:103B500014C0000000000000000000000040000051 -:103B60000000049D0000002CC02036200000000052 -:103B70000000002DC0403620000000000000000FB3 -:103B800000210221000000000000000014C000001D -:103B9000000004F800000000006000000000000BBE -:103BA00000000000D900000000000000000000003C -:103BB000C040040000000001B500000000204411D6 -:103BC000000000000000200000204811000000005C -:103BD000B600000000204411000000000000A0001A -:103BE0000020481100000000B70000000020441130 -:103BF000000000000000C00000204811000000008C -:103C0000B800000000204411000000000000F8E0AF -:103C10000020481100000000B900000000204411FD -:103C2000000000000000F8800020481100000000A3 -:103C3000BA00000000204411000000000000E00075 -:103C40000020481100000000BB00000000204411CB -:103C5000000000000000F0000020481100000000FB -:103C6000BC00000000204411000000000000F3FC34 -:103C700000204811000000008100000000204411D5 -:103C800000000000000000020020481100000000B9 -:103C9000000000FF00280E300000000000000000BF -:103CA000002F022300000000000000000CC00000F4 -:103CB0000000050C00000000C0200800000000000B -:103CC0000000000014C000000000052100000000FA -:103CD00000200C11000000000000001C0020362312 -:103CE000000000000000002B002036230000000030 -:103CF00000000029002036230000000000000028FA -:103D000000203623000000000000001700203623AA -:103D10000000000000000025002036230000000005 -:103D200000000026002036230000000000000015DF -:103D3000002036230000000000000016002036237B -:103D400000000000FFFFE00000200C110000000058 -:103D500000000021002036230000000000000022A7 -:103D6000002036230000000000001FFF00200C117F -:103D700000000000000000230020362300000000A7 -:103D8000000000240020362300000000F1FFFFFFA8 -:103D900000283A2E000000000000001AC0220E2069 -:103DA00000000000000000000029386E0000000044 -:103DB0008100000000204411000000000000000607 -:103DC00000204811000000000000002A402036209A -:103DD00000000000870000000020441100000000E7 -:103DE00000000000C0204800000000000000A1F416 -:103DF00000204411000000000000000000204810D6 -:103E0000000000000000000000200C110000000075 -:103E10000000003000203623000000009D0000005C -:103E200000204411000000000000001F40214A2033 -:103E30000000000096000000002044110000000077 -:103E400000000000C020480000000000000000004A -:103E5000C0200C000000000000000000C020100086 -:103E6000000000000000001F0021162400000000D8 -:103E70000000000014C00000000000000000001D51 -:103E800000203623000000000000000300281E234D -:103E900000000000000000080022222300000000B3 -:103EA000FFFFF000002822280000000000000000B2 -:103EB000002920E8000000000000001F0020362834 -:103EC000000000000000001800211E230000000078 -:103ED0000000002000203627000000000000000243 -:103EE000002216240000000000000000003014A88A -:103EF000000000000000001E002036250000000029 -:103F00000000000300211A2400000000100000003F -:103F100000281A2600000000EFFFFFFF00283A2EBD -:103F20000000000000000000004938CE0000066AD2 -:103F30000000000140280A200000000000000006E8 -:103F400040280E200000000000000300C0281220BE -:103F50000000000000000008002112240000000002 -:103F600000000000C020162000000000000000003B -:103F7000C0201A20000000000000000000210222E2 -:103F8000000000000000000014C0000000000559FF -:103F9000810000000020441100000000000000012A -:103FA00000204811000000000000225800300A24C0 -:103FB0000000000000040000006946220000067CAA -:103FC00000002169002044110000000000000000F2 -:103FD00000204805000000000002000000294A26D9 -:103FE0000000000000000000002048100000000059 -:103FF000CAFEBABE00204811000000000000000206 -:10400000002F022300000000000000000CC0000090 -:104010000000056100000000C0201C10000000002E -:1040200000000000C04000000000056F000000021A -:10403000002F022300000000000000000CC0000060 -:104040000000056181000000002044110000000014 -:10405000000000010020481100000000000022586C -:1040600000300A240000000000040000006946221D -:104070000000067C00000000C0201C1000000000B2 -:1040800000000000C04000000000056F00000000BC -:10409000002F022300000000000000000CC0000000 -:1040A0000000056500000000C0201C0000000000AA -:1040B00000000000C04000000000056F0000000488 -:1040C000002F022300000000000000000CC00000D0 -:1040D0000000056D81000000002044110000000078 -:1040E0000000000000204811000000000000216DC9 -:1040F000002044110000000000000000C020480023 -:104100000000000000000000C060480000000681C0 -:104110000000000000401C100000056F00000000BF -:10412000C02000000000000000000000C0400000AF -:1041300000000000000000000EE00000000005711B -:104140000000000000600000000005BC000000004E -:10415000002F022400000000000000000CC000003E -:10416000000005820000A2B70020441100000000FA -:10417000000000000020480700000000810000004F -:104180000020441100000000000000010020481140 -:10419000000000000004A2B6006044110000067C8C -:1041A0000000001A0021223000000000000000067C -:1041B00000222630000000000004200400604411AA -:1041C0000000067C0000A2C4002044110000000092 -:1041D00000000000003048E900000000000000007E -:1041E00000E00000000005800000A2D10020441182 -:1041F000000000000000000000404808000000002F -:104200000000A2D1002044110000000000000001C5 -:1042100000504A280000000000000001002F022486 -:1042200000000000000000000CC00000000005932A -:104230000000A2BB002044110000000000000000AC -:104240000020480700000000810000000020441109 -:1042500000000000000000010020481100000000E4 -:104260000004A2BA006044110000067C0000001A9D -:10427000002122300000000000000006002226304D -:104280000000000000042004006044110000067CCF -:104290000000A2C500204411000000000000000042 -:1042A000003048E9000000000000000000E00000CD -:1042B000000005910000A2D200204411000000007F -:1042C0000000000000404808000000000000A2D2EA -:1042D00000204411000000000000000100504A28A6 -:1042E0000000000000000002002F02240000000077 -:1042F000000000000CC00000000005A40000A2BFE8 -:1043000000204411000000000000000000204807C9 -:1043100000000000810000000020441100000000A7 -:104320000000000100204811000000000004A2BEAF -:10433000006044110000067C0000001A00212230B9 -:1043400000000000000000060022263000000000EF -:1043500000042004006044110000067C0000A2C696 -:10436000002044110000000000000000003048E977 -:10437000000000000000000000E00000000005A2B6 -:104380000000A2D300204411000000000000000043 -:1043900000404808000000000000A2D300204411A3 -:1043A000000000000000000100504A28000000004A -:1043B0000000A2C300204411000000000000000023 -:1043C0000020480700000000810000000020441188 -:1043D0000000000000000001002048110000000063 -:1043E0000004A2C2006044110000067C0000001A14 -:1043F00000212230000000000000000600222630CC -:104400000000000000042004006044110000067C4D -:104410000000A2C7002044110000000000000000BE -:10442000003048E9000000000000000000E000004B -:10443000000005B10000A2D40020441100000000DB -:104440000000000000404808000000000000A2D466 -:1044500000204411000000000000000100504A2824 -:104460000000000085000000002044110000000052 -:104470000000000000204801000000000000304A59 -:10448000002044110000000001000000002048113D -:10449000000000000000000000400000000005B720 -:1044A000A4000000C0204411000000000000000033 -:1044B000C04048000000000000000000C060000094 -:1044C000000005BC00000000C04004000000000126 -:1044D0000000002C002036210000000081000000B8 -:1044E00000204411000000000000000600204811D8 -:1044F0000000000000000000002F0230000000005B -:10450000000000000CC00000000005C30000000017 -:10451000002004110000000000000030004036219F -:10452000000005D6000000300020062D000000002D -:1045300000007E00002806210000000000000000AE -:10454000002F022100000000000000000CE000002D -:10455000000005D68100000000204411000000008A -:104560000000000100204811000000000004A0929B -:10457000006044110000067C00000031002036304D -:10458000000000000004A093006044110000067CBD -:104590000000003200203630000000000004A2B607 -:1045A000006044110000067C00000033002036301B -:1045B000000000000004A2BA006044110000067C64 -:1045C0000000003400203630000000000004A2BECD -:1045D000006044110000067C0000003500203630E9 -:1045E000000000000004A2C2006044110000067C2C -:1045F00000000036002036300000000000042004D7 -:10460000006044110000067C0001A2A400204411B7 -:10461000000000000000003F0020481100000000E2 -:104620000000003F00204811000000000000003F93 -:1046300000204811000000000000003F0020481149 -:1046400000000000000000050020481100000000EC -:104650000000A1F400204411000000000000000050 -:1046600000204811000000008800000000204411D4 -:1046700000000000000000010020481100000000C0 -:10468000810000000020441100000000000000062E -:10469000002048110000000000000001002F02303F -:1046A00000000000000000000CE000000000061FF9 -:1046B000000000300020062D000000000000000077 -:1046C000002F022100000000000000000CE00000AC -:1046D0000000061F810000000020441100000000BF -:1046E00000000001002048110000000000007E00D2 -:1046F000002806210000000000000000002F022119 -:1047000000000000000000000CE00000000005F8C0 -:104710000000A092002044110000000000000031C1 -:1047200000204A2D000000000000A093002044114A -:10473000000000000000003200204A2D00000000B0 -:104740000000A2B600204411000000000000003369 -:1047500000204A2D000000000000A2BA00204411F1 -:10476000000000000000003400204A2D000000007E -:104770000000A2BE0020441100000000000000352F -:1047800000204A2D000000000000A2C200204411B9 -:10479000000000000000003600204A2D000000004C -:1047A000000000300020062D00000000000001FF86 -:1047B000002806210000000000000000002F022158 -:1047C00000000000000000000CE000000000061ED9 -:1047D0000000000000210221000000000000000095 -:1047E00014C00000000006010004A0030060441192 -:1047F0000000067C0000A00300204411000000001F -:10480000000000000020481000000000000000012F -:1048100000210621000000000000000014C000007C -:10482000000006060004A010006044110000067C91 -:104830000000A01000204411000000000000000053 -:1048400000204810000000000000000100210621A7 -:104850000000000000000000002F02210000000006 -:10486000000000000CE000000000061E0004A01183 -:10487000006044110000067C0000A01100204411DB -:1048800000000000000000000020481000000000B0 -:104890000004A012006044110000067C0000A01279 -:1048A000002044110000000000000000002048101B -:1048B000000000000004A013006044110000067C0A -:1048C0000000A013002044110000000000000000C0 -:1048D00000204810000000000004A01400604411F3 -:1048E0000000067C0000A01400204411000000001D -:1048F0000000000000204810000000000004A01587 -:10490000006044110000067C0000A0150020441146 -:10491000000000000000000000204810000000001F -:104920000004A016006044110000067C0000A016E0 -:10493000002044110000000000000000002048108A -:10494000000000000004A017006044110000067C75 -:104950000000A0170020441100000000000000002B -:1049600000204810000000000004200400604411F2 -:104970000000067C0000002C0080062D00000000D6 -:10498000FF000000002044110000000000000000B3 -:104990000020481100000000000000010020481124 -:1049A000000000000000000200804811000000002C -:1049B000000000000EE000000000063000000030A3 -:1049C0000020062D00000000000000020028062143 -:1049D0000000000000000000002F02210000000085 -:1049E000000000000CE000000000062E8100000026 -:1049F00000204411000000000000000100204811C8 -:104A00000000000000042004006044110000067C47 -:104A10000000100000200811000000000000002B22 -:104A200000203622000000000000000000600000AE -:104A3000000006340000000000600000000005BC1B -:104A40009800000000204411000000000000000059 -:104A5000008048110000000000000000C06000005D -:104A60000000063400000000C04004000000000107 -:104A70000000A2A400204411000000000000002259 -:104A800000204811000000008900000000204411AF -:104A90000000000000000001004048110000062056 -:104AA00097000000002044110000000000000000FA -:104AB00000204811000000008A000000002044117E -:104AC0000000000000000000004048110000062027 -:104AD00000000000006000000000064D0001A2A4DC -:104AE000C0204411000000000000001600604811C2 -:104AF0000000036A000020100020441100000000A4 -:104B000000010000002048110000000081000000AA -:104B100000204411000000000000000100204811A6 -:104B2000000000000000217C002044110000000073 -:104B3000098000000020481100000000FFFFFFFF77 -:104B40000020481100000000000000000020481173 -:104B5000000000000000000017000000000000003E -:104B60000004217F006044110000067C0000001F4B -:104B700000210230000000000000000014C000000E -:104B8000000000000000000400404C110000064737 -:104B900000000000004000000000000000000017BE -:104BA00000201E2D000000000000000400291E2728 -:104BB0000000000000000017008036270000000001 -:104BC0000000001700201E2D00000000FFFFFFFB6B -:104BD00000281E2700000000000000170080362774 -:104BE000000000000000001700201E2D0000000043 -:104BF0000000000800291E27000000000000001728 -:104C000000803627000000000000001700201E2D45 -:104C100000000000FFFFFFF700281E270000000033 -:104C20000000001700803627000000000001A2A449 -:104C30000020441100000000000000160060481130 -:104C40000000036A00002010002044110000000052 -:104C50000001000000204811000000000000217C3D -:104C600000204411000000000180000000204811D5 -:104C700000000000FFFFFFFF0020481100000000BF -:104C800000000000002048110000000000000000AB -:104C90001700000000000000810000000020441107 -:104CA000000000000000000100204811000000008A -:104CB0000004217F006044110000067C0000001FFA -:104CC00000210230000000000000000014C00000BD -:104CD0000000067B0000001000404C11000006613F -:104CE00000000000C02004000000000000000000E0 -:104CF00038C00000000000000000001D00200A2D48 -:104D0000000000000000001E00200E2D000000002A -:104D10000000001F0020122D0000000000000020F5 -:104D20000020162D00000000000021690020441121 -:104D30000000000000000000002048040000000007 -:104D400000000000002048050000000000000000F6 -:104D50000020480100000000CAFEBABE0020481131 -:104D600000000000000000040030122400000000D9 -:104D700000000000002F00640000000000000000A0 -:104D80000CC000000000067A0000000300281A2270 -:104D900000000000000000080022122200000000B5 -:104DA000FFFFF000002812240000000000000000B7 -:104DB000002910C4000000000000001F004036243D -:104DC0000000000000000000008000000000000063 -:104DD000000000001AC000000000067C9F000000D8 -:104DE0000020441100000000CAFEBABE0020481195 -:104DF00000000000000000001AE000000000067F34 -:104E00000000000000800000000000000000000022 -:104E10001AC00000000006819E000000002044111E -:104E200000000000CAFEBABE0020481100000000C9 -:104E3000000000001AE000000000068400000000EE -:104E40000080000000000000000000000060000082 -:104E50000000000B000010000060041100000315AA -:104E6000000000000020041100000000000000000D -:104E700000600811000001B20000225C0020441113 -:104E800000000000000000030020481100000000A6 -:104E90000000225600204411000000000000001B0A -:104EA00000204811000000000000A1FC0020441177 -:104EB0000000000000000001002048110000000078 -:104EC0000001A1FDC02044110000000000000021ED -:104ED00000201E2D000000000000001000221E27F0 -:104EE00000000000000000240020222D000000002F -:104EF0000000FFFF00282228000000000000000042 -:104F000000294907000000000000000000204811AF -:104F100000000000000000220020222D0000000000 -:104F20000000FFFF00282228000000000000000011 -:104F3000002949070000000000000000002048117F -:104F4000000000000000002300201E2D00000000D3 -:104F50000000001000221E270000000000000000DA -:104F6000002949070000000000000000004048112F -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B000014204F505B302500000000001C301687B -:1052C000043505B300000000022502090250015117 -:1052D000000000000223024502A00241000000007D -:1052E00003CD05B305B305B300000000063C063D41 -:1052F000031F05B30000000005B305B803200340F9 -:1053000000000000032A0282034203340000000070 -:1053100005B305B305B305B30000000005B30544AC -:1053200005B305B30000000003B205B304AE0344A7 -:1053300000000000048D0443043305B300000000A6 -:1053400004C305B3043704D000000000044304FA8A -:10535000035103710000000005B305B305B305B3A5 -:105360000000000005B305B305B305B3000000005D -:1053700005B305B3063205BA0000000005B305B356 -:10538000000705B30000000005B305B305B305B37E -:105390000000000005B305B305B305B3000000002D -:1053A00003EE03E303FE03FC00000000040404001A -:1053B00004020406000000000412040E041A04167D -:1053C000000000000422041E042A0426000000003D -:1053D00005B305B3042E05B30000000005B305B303 -:1053E00005B305B30000000005B305B305B305B36D -:1053F00000000000000206680686000600000000AB -:00000001FF diff --git a/firmware/radeon/RV670_pfp.bin.ihex b/firmware/radeon/RV670_pfp.bin.ihex deleted file mode 100644 index f55292c97b7937d5da76127dbb21745b72d8039d..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV670_pfp.bin.ihex +++ /dev/null @@ -1,145 +0,0 @@ -:1000000000CA040000A00000007E828B007C038BED -:10001000008001B8007C038B00D4401E00EE001E5F -:1000200000CA040000A00000007E828B00C41838C3 -:1000300000CA240000CA2800009581A800C41C3A08 -:1000400000C3C00000CA080000CA0C00007C744B4A -:1000500000C200050099C00000C41C3A007C744C2A -:1000600000C0FFF000042C0400309002007D250049 -:1000700000351402007D350B00255403007CD5802B -:1000800000259C030095C00400D5001B007EDDC147 -:10009000007D9D8000D6801B00D5801B00D4401EB3 -:1000A00000D5401E00D6401E00D6801E00D4801E03 -:1000B00000D4C01E009783D300D5C01E00CA08001C -:1000C0000080001A00CA0C0000E4011E00D4001ECB -:1000D0000080000C00C4183800E4013E00D4001E6B -:1000E0000080000C00C4183800D4401E00EE001E32 -:1000F00000CA040000A00000007E828B00E4011E04 -:1001000000D4001E00D4401E00EE001E00CA0400F1 -:1001100000A00000007E828B00E4013E00D4001E9F -:1001200000D4401E00EE001E00CA040000A0000023 -:10013000007E828B00CA180000D4401E00D5801EAD -:100140000080005300D4007500D4401E00CA08008F -:1001500000CA0C0000CA100000D4801900D4C018D6 -:1001600000D5001700D4801E00D4C01E00D5001E8C -:1001700000E2001E00CA040000A00000007E828B86 -:1001800000CA080000D4806000D4401E0080000037 -:1001900000D4801E00CA080000D4806100D4401E34 -:1001A0000080000000D4801E00CA080000CA0C00B5 -:1001B00000D4401E00D4801600D4C01600D4801E87 -:1001C000008001B800D4C01E00C6084300CA0C005D -:1001D00000CA10000094800400CA140000E420F358 -:1001E00000D4201300D5606500D4E01C00D5201C8D -:1001F00000D5601C008000000006200100C60843F6 -:1002000000CA0C0000CA1000009483F700CA140052 -:1002100000E420F30080007900D4201300C60843D6 -:1002200000CA0C0000CA1000009883EF00CA140036 -:1002300000D400640080008D0000000000C414326F -:1002400000C6184300C4082F0095400500C40C30B8 -:1002500000D4401E0080000000EE001E009583F5D3 -:1002600000C4103100D4403300D5206500D4A01C58 -:1002700000D4E01C00D5201C00E4015E00D4001E68 -:10028000008000000006200100CA1800000A2001BA -:1002900000D6007600C408360098800700C61045D6 -:1002A0000095011000D4001F00D46062008000009F -:1002B00000D4206200CC383500CC1433008401BB5C -:1002C00000D4007200D5401E0080000000EE001E29 -:1002D00000E2001A008401BB00E2001A00CC104BBF -:1002E00000CC0447002C9401007D098B0098400548 -:1002F000007D15CB00D4001A008001B800D4006D39 -:100300000034440100CC0C480098403A00CC2C4A00 -:100310000095800400CC0449008001B800D4001A84 -:1003200000D4C01A00282801008400F000CC10037B -:100330000098801B0004380C008400F000CC1003EF -:100340000098801700043808008400F000CC1003E7 -:100350000098801300043804008400F000CC1003DF -:100360000098801400CC104C009A800900CC144DE9 -:10037000009840DC00D4006D00CC184800D5001A6D -:1003800000D5401A008000C900D5801A0096C0D55B -:1003900000D4006D008001B800D4006E009AC00344 -:1003A00000D4006D00D4006E0080000000EC007FDF -:1003B000009AC0CC00D4006D008001B800D4006E5B -:1003C00000CC140300CC180300CC1C03007D910367 -:1003D000007DD583007D190C0035CC1F0035701FC2 -:1003E000007CF0CB007CD08B00880000007E8E8BE0 -:1003F0000095C00400D4006E008001B800D4001A3B -:1004000000D4C01A00CC080300CC0C0300CC1003AD -:1004100000CC140300CC180300CC1C0300CC240334 -:1004200000CC28030035C41F0036B01F007C704B81 -:100430000034F01F007C704B0035701F007C704B47 -:10044000007D8881007DCCC1007E5101007E9541F8 -:10045000007C9082007CD4C2007C848B009AC00314 -:10046000007C8C8B002C88010098809E00D4006D4D -:100470000098409C00D4006E00CC084C00CC0C4D81 -:1004800000CC104800D4801A00D4C01A00800101AA -:1004900000D5001A00CC083200D40032009482D972 -:1004A00000CA0C0000D4401E0080000000D4001ED2 -:1004B00000E4011E00D4001E00CA080000CA0C009F -:1004C00000CA100000D4401E00CA140000D4801ED0 -:1004D00000D4C01E00D5001E00D5401E00D54034FB -:1004E0000080000000EE001E0028040400E2001A54 -:1004F00000E2001A00D4401A00CA380000CC0803F9 -:1005000000CC0C0300CC0C0300CC0C03009882BD83 -:1005100000000000008401BB00D7A06F0080000035 -:1005200000EE001F00CA040000C2FF0000CC083427 -:1005300000C13FFF007C74CB007CC90B007D010F24 -:10054000009902B0007C738B008401BB00D7A06FC0 -:100550000080000000EE001F00CA080000281900FB -:10056000007D898B009580140028140400CA0C00BB -:1005700000CA100000CA1C0000CA240000E2001FCC -:1005800000D4C01A00D5001A00D5401A00CC1803B8 -:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -:1005A000007D9C4700984297000000000080016198 -:1005B00000D4C01A00D4401E00D4801E0080000069 -:1005C00000EE001E00E4011E00D4001E00D4401EF8 -:1005D00000EE001E00CA040000A00000007E828B16 -:1005E00000E4013E00D4001E00D4401E00EE001EB8 -:1005F00000CA040000A00000007E828B00CA080030 -:1006000000248C06000CCC060098C00600CC104ECE -:100610000099000400D4007300E4011E00D4001E01 -:1006200000D4401E00D4801E0080000000EE001E9A -:1006300000CA080000CA0C000034D01800251001C0 -:100640000095002100C17FFF00CA100000CA1400FD -:1006500000CA180000D4801D00D4C01D007DB18BDD -:1006600000C1420200C2C00100D5801D0034DC0E72 -:10067000007D5D4C007F734C00D7401E00D5001EEE -:1006800000D5401E00C1420000C2C00000099C010C -:100690000031DC10007F5F4C007F734C00042802A7 -:1006A000007D838000D5A86F00D5806600D7401EEE -:1006B00000EC005E00C8240200C82402008001B8DB -:1006C00000D6007600D4401E00D4801E00D4C01E88 -:1006D0000080000000EE001E0080000000EE001F01 -:1006E00000D4001F0080000000D4001F00D4001FB1 -:1006F0000088000000D4001F00000000000000007F -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000010171000201780003008F0004007FE5 -:10081000000500030006003F000700320008012C1D -:1008200000090046000A0036001001B6001700A2B9 -:100830000022013A00230149002000B400240125D0 -:100840000027004D0028006A002A0060002B00529B -:10085000002F0065003200870034017F003C015604 -:10086000003F00720041018C0044012E00550173CD -:100870000056017A0060000B00610034006200380D -:1008800000630038006400380065003800660038F6 -:10089000006700380068003A00690041006A0048BB -:1008A000006B0048006C0048006D0048006E004876 -:1008B000006F00480000000600000006000000066F -:1008C0000000000600000006000000060000000610 -:1008D0000000000600000006000000060000000600 -:1008E00000000006000000060000000600000006F0 -:1008F00000000006000000060000000600000006E0 -:00000001FF diff --git a/firmware/radeon/RV710_me.bin.ihex b/firmware/radeon/RV710_me.bin.ihex deleted file mode 100644 index 5cdfe306eea5e2df1a2adf8b2ebfa98d3e7e8cc6..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV710_me.bin.ihex +++ /dev/null @@ -1,341 +0,0 @@ -:10000000CC0003EA04080003CC8000437C4080005D -:10001000A0000000CC80006280000003D040007F80 -:1000200080000003CC4000417C40C000C0160004AA -:1000300030D03FFF7D15000CCC11000028D8001EE9 -:100040003198000128DC001FC820000495C000067C -:100050007C424000CC0000627E56800CCC2900001F -:10006000C82400047E26000B958000067C42C00058 -:10007000CC0000627ED7000CCC310000C82C0004FC -:100080007E2E000CCC00006231103FFF8000000388 -:10009000CE1100007C40C00080000003CC40004036 -:1000A00080000003CC4122577C418000CC400045B9 -:1000B000CC400048CC41225CCC41A1FC7C4080007B -:1000C000A0000000CC800062CC400045CC4000483D -:1000D0007C40C000CC41225CCC41A1FC7C40800033 -:1000E000A0000000CC800062CC000045CC0000489D -:1000F000CC41225CCC41A1FC7C408000A0000000EF -:10010000CC800062040CA1FDC0120001CC000045AF -:10011000CC0000487CD0C00CCC41225CCC41A1FC7E -:10012000D04D00007C408000A0000000CC80006228 -:1001300080000003CC41225D7C4080007C40C000F8 -:10014000C02A00027C4100007D29000C309400018F -:1001500030980006309C030029DC00087C42000037 -:100160007C4240009540000FC02E000405F022584C -:100170007F2F000CCC310000C8280004CCC12169BD -:10018000CD01216ACE81216B0DB40002CC01216C1E -:100190009740000E0DB400008000007DC834000AB6 -:1001A0000DB40002974000090DB40000C02E0004F9 -:1001B00005F022587F2F000CCC310000C828000425 -:1001C0008000007DC834000A974000047E02800051 -:1001D0008000007DC834000A0DB400049740FF8CF5 -:1001E00000000000CE01216DCE41216EC828000321 -:1001F000C834000A9B400004043C00058400026DE2 -:10020000CC0000620DF400009740000BC82C03E600 -:10021000CE81A2B7C03000067EF34028C030002057 -:100220007F6B80207FB3C029CF81A2C480000003F0 -:10023000CFC1A2D10DF400019740000BC82C03E7F9 -:10024000CE81A2BBC03000067EF34028C030002023 -:100250007F6B80207FB3C029CF81A2C580000003BF -:10026000CFC1A2D20DF400029740000BC82C03E8C6 -:10027000CE81A2BFC03000067EF34028C0300020EF -:100280007F6B80207FB3C029CF81A2C6800000038E -:10029000CFC1A2D3C82C03E9CE81A2C3C0300006CF -:1002A0007EF34028C03000207F6B80207FB3C029C0 -:1002B000CF81A2C780000003CFC1A2D48000000379 -:1002C000CC4000427C40C0007C4100002914001D4D -:1002D000315400019940000C31181000C81C001165 -:1002E00095C00000C81C0011CCC12100CD01210126 -:1002F000CCC12102CD012103041800048000037E3B -:10030000CD81A2A4C02A00049580000836A821A3AC -:10031000CC290000C8280004C81C00110DE40040CE -:100320009640FFFFC81C0011CCC12170CD01217186 -:10033000C820001296000000C82000128000037E32 -:10034000CC0000647C40C0007C410000CC00004533 -:10035000CC00004840D40003CD41225CCD01A1FC7B -:10036000C01A0001041CA1FD7DD9C00C7C42000014 -:1003700008CC00010624000106280002CE1D000062 -:10038000CE5D000098C0FFFACE9D00007C4080004A -:10039000A0000000CC8000627C40C00030D0000192 -:1003A00028CC00017C414000950000067C41800083 -:1003B000CD41216DCD81216E800000F4C81C000369 -:1003C000C02200047E16000CCC210000C81C0004D2 -:1003D0007C42400098C000047C4280008000000302 -:1003E000CDE50000CE412169CE81216ACDC1216BCE -:1003F00080000003CC01216C7C40C0007C410000E7 -:100400007C4140007C4180007C41C00028A4000861 -:10041000326400FF0E68003C9680000A7C020000F7 -:100420007C4200001E300003CC00006A9B000003E9 -:100430004220000504200040800001117C024000A1 -:100440007E0240009A4000000A64000130EC001077 -:100450009AC0000ACC000062C02A0004C82C002107 -:100460007E92800CCC000041CC290000CEC000213F -:1004700080000121C8300004CD01216DCD41216EE5 -:10048000C83000037F1F000B30F4000727780001FD -:100490009740002A07B801269F8000000000000056 -:1004A000800001367F1B80048000013A7F1B80059D -:1004B0008000013E7F1B8002800001427F1B800381 -:1004C000800001467F1B80078000014A7F1B800659 -:1004D0008000014F28A400089B80001928A4000870 -:1004E0008000015F326400FF9B80001528A4000893 -:1004F0008000015F326400FF9B80001128A4000887 -:100500008000015F326400FF9B80000D28A400087A -:100510008000015F326400FF9B80000928A400086E -:100520008000015F326400FF9B80000528A4000862 -:100530008000015F326400FF28A40008326400FFDD -:100540000E68003C9A80FEB228EC00087C43400014 -:100550007C4380007C43C00096C00007CC00006252 -:10056000CF412169CF81216ACFC1216B8000000377 -:10057000CC01216C80000003CFF50000CC00006BA3 -:10058000840003810E68003C9A800004C82800158E -:1005900080000003D040007F9680FFAB7E024000C9 -:1005A0008400023BC00E0002CC00004180000239F2 -:1005B000CCC1304A7C40C0007C410000C01E00011C -:1005C00029240012C022000296400005C026000423 -:1005D000C027FFFB7D25000BC02600007DD2800BCD -:1005E0007E12C00B7D25000C7C4140007C418000C8 -:1005F000CCC121699A80000ACD01216ACD41216BCD -:1006000096C0FE83CD81216CC83000189700000091 -:10061000C830001880000003CC000018840003815B -:10062000CC00007FC8140013C8180014CD41216B02 -:1006300096C0FE77CD81216C80000183C830001800 -:10064000C80C000898C00000C80C00087C410000DD -:1006500095000002000000007C414000C820000915 -:10066000CC400043CE01A1F4CC400044C00E800039 -:100670007C4240007C4280002AAC001F96C0FE6491 -:10068000C035F000CE4003E232780003267C00083B -:100690007FF7C00B7FFBC00C2A780018CFC003E3A4 -:1006A000CF8003E426B000027F3F0000CF0003E5C7 -:1006B0008000031F7C80C0007C40C00028D0000860 -:1006C0003110000F9500000F2528000106A801B485 -:1006D0009E80000000000000800001D5C0120800CC -:1006E000800001E3C814000F800001EAC814001064 -:1006F000800001F1CCC1A2A4800001FAC81400114D -:1007000030D0003F0D2800159A8000120D28001EE1 -:100710009A80001E0D2800209A8000230D24000FCF -:100720000D2800107E6A800C9A8000260D2000049F -:100730000D2400140D2800287E62400C7EA6800C3B -:100740009A80002AC814001180000003CCC1A2A422 -:10075000C01208007C4140007D0CC00CC012000893 -:1007600029580003295C000C7C4200007DD1C00B9D -:10077000262000147E1E400C7E4E800CCE81A2A44A -:1007800080000003CD81A1FEC814000F0410210ECB -:1007900095400000C814000FD051000080000003F5 -:1007A000CCC1A2A4C8140010041021089540000078 -:1007B000C8140010D051000080000003CCC1A2A4D6 -:1007C000CCC1A2A404100001CD0000198400038153 -:1007D000CC00007FC810001999000000C810001953 -:1007E000800000047C40800004102100954000003F -:1007F000C8140011D05100008000037ECCC1A2A417 -:100800007C40C000CC40000D94C0FE01CC40000EE6 -:100810007C4100009500000508CC0001C8140005CB -:10082000994000140000000098C0FFFB7C410000CC -:10083000800000047D008000C81400057C40C000DA -:100840009940000CC818000C7C4100009580FDF018 -:10085000C820000EC81C000D662000207E1E002C43 -:10086000252400027E62402080000003CCE60000C8 -:100870007C410000CC00006CCC00006DC818001F4B -:10088000C81C001E659800207DD9C02C7CD4C00CEB -:10089000CCDE000045DC0004C82800179680000F5D -:1008A000C00E0001286800082AAC001632A800FF1C -:1008B0000EB000497F2F000B9700000600000000DB -:1008C000C81400057C40C000800002237C41000069 -:1008D00080000226D040007F8400023BCC00004113 -:1008E000CCC1304A94000000C83C001A043C00050A -:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8 -:100900007F7B400CCF41217CCFC1217DCC01217E5A -:10091000C03A00040434217F7F7B400CCC350000BA -:10092000C83C00042BFC001F0438002097C00005C1 -:10093000CC0000629B8000000BB8000180000247E1 -:10094000CC000071CC01A1F404380016C0360002BE -:10095000CF81A2A488000000CF4120107C40C000BD -:1009600028D0001C9500000504D40001CD4000658E -:1009700080000003CD40006809540002800000039D -:10098000CD4000668400026CC81803EA7C40C000B9 -:100990009980FD9FC814001608D000019940002BD3 -:1009A000CD0000687C408000A0000000CC80006288 -:1009B000043C0005CFC1A2A4CC01A1F484000381B2 -:1009C000CC00004688000000CC00007F8400027E3E -:1009D000C81803EA7C40C0009980FD8DC814001639 -:1009E00008D0000199400019CD0000687C408000CB -:1009F000A0000000CC800062043C0022CFC1A2A471 -:100A000084000381CC00004788000000CC00007FF8 -:100A1000C81000169900000DCC400067800000044B -:100A20007C408000C81803EA9980FD797C40C000B2 -:100A300094C00003C810001699000004CCC00068E0 -:100A4000800000047C4080008400023BC0148000D1 -:100A5000CC000041CD41304AC01480009900000014 -:100A6000C8100016800000047C408000C012000105 -:100A70007C51400C80000003D05500007C40C00039 -:100A80007C4100007C4140007C418000291C001F0B -:100A9000CCC0004ACD00004B95C00003C01C8000B4 -:100AA000CDC12010DD830000055C2000CC00006279 -:100AB00080000003D81F41007C40C0007C41000042 -:100AC0007C4140007C418000CCC0004CCD00004DFA -:100AD000DD830000055CA00080000003D81F4100FA -:100AE0007C40C0007C4100007C4140007C41800093 -:100AF000CCC0004ECD00004FDD830000055CC0007F -:100B000080000003D81F41007C40C0007C410000F1 -:100B10007C4140007C418000CCC00050CD000051A1 -:100B2000DD830000055CF8E080000003D81F410071 -:100B30007C40C0007C4100007C4140007C41800042 -:100B4000CCC00052CD000053DD830000055CF8806E -:100B500080000003D81F41007C40C0007C410000A1 -:100B60007C4140007C418000CCC00054CD00005549 -:100B7000DD830000055CE00080000003D81F410019 -:100B80007C40C0007C4100007C4140007C418000F2 -:100B9000CCC00056CD000057DD830000055CF0009E -:100BA00080000003D81F41007C40C0007C41000051 -:100BB0007C4140007C418000CCC00058CD000059F1 -:100BC000DD830000055CF3FC80000003D81F4100BA -:100BD000D04320007C408000A0000000CC80006258 -:100BE000D043A0007C408000A0000000CC800062C8 -:100BF000D043C0007C408000A0000000CC80006298 -:100C0000D043F8E07C408000A0000000CC8000626F -:100C1000D043F8807C408000A0000000CC800062BF -:100C2000D043E0007C408000A0000000CC80006247 -:100C3000D043F0007C408000A0000000CC80006227 -:100C4000D043F3FC7C408000A0000000CC80006218 -:100C5000C81403E0CC430000CC430000CC430000A8 -:100C60007D45C000CDC30000D04300007C40800023 -:100C7000A0000000CC8000627C40C000C81003E2ED -:100C8000C81403E5C81803E3C81C03E4CD81216937 -:100C9000CDC1216ACCC1216BCC01216C04200004A0 -:100CA0007DA180007D9640029640FCD9CD8003E373 -:100CB00031280003C02DF000251800087DAD800B01 -:100CC0007DA9800C80000003CD8003E3308CFFFF02 -:100CD000D04D00007C408000A0000000CC8000626D -:100CE000C8140020155800029580FFFFC81400208A -:100CF000CC00006ECC4121807C40C000CCC1218D55 -:100D0000CC41218128D0001F34588000CD81218C16 -:100D10009500FCBFCC412182C81400209940FFFF00 -:100D2000C8140020800000047C4080007C40C0008B -:100D300028D0001831100001C01600809500000373 -:100D4000C02A00047CD4C00CCCC1217CCC41217DC4 -:100D5000CC41217E7C4180001DB0000336A0217F64 -:100D60009B000003419C0005041C004099C000004A -:100D700009DC0001CC210000C82400042A6C001FFB -:100D8000419C00059AC0FFFACC80006280000004FC -:100D90007C4080007C40C00004D403E68000000357 -:100DA000CC5400008000037ECC4003EAC01C8000CD -:100DB000044CA000CDC120107C410000C8140009E3 -:100DC00004180000041C0008CD80007109DC00013B -:100DD00005980001CD0D000099C0FFFCCC80006299 -:100DE0008000037ECD400071C00E0100CC000041A8 -:100DF000CCC1304AC83C007FCC00007F800000039B -:100E0000CC00007FCC00007F88000000CC00007F79 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:101400000001033300100006001700080021000A45 -:101410000027002A002800250029002B002A002888 -:10142000002B002B002D003A002E0041002F004C15 -:101430000034004E00360032003900B1003A00D1CD -:10144000003B00E6003C00FE003D016D003F00AFA8 -:10145000004103380043034B00440190004500FE67 -:10146000004601AE004701AE004802000049020EEE -:10147000004A0257004B028400520261005302737B -:10148000005402890057029B0060029F006102AE77 -:10149000006202B8006302C2006402CC006502D69A -:1014A000006602E0006702EA006802F4006902F8E0 -:1014B000006A02FC006B0300006C0304006D03086B -:1014C000006E030C006F03100070031400720365BC -:1014D0000074036B00790369007C031E000F037A1C -:1014E000000F037A000F037A000F037A000F037ACC -:1014F000000F037A000F037A000F037A000F037ABC -:10150000000F037A000F037A000F037A000F037AAB -:10151000000F037A000F037A000F037A000F037A9B -:10152000000F037A000F037A000F037A000F037A8B -:10153000000F037A000F037A000F037A000F037A7B -:00000001FF diff --git a/firmware/radeon/RV710_pfp.bin.ihex b/firmware/radeon/RV710_pfp.bin.ihex deleted file mode 100644 index 3d811ff0a1a8a727604bb0fe556c4c5bb352b012..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV710_pfp.bin.ihex +++ /dev/null @@ -1,213 +0,0 @@ -:100000007C408000A00000007E82800B8000000009 -:10001000DC030000CC800040D04000407C408000E9 -:10002000A00000007E82800BC818000E31980001ED -:100030007C4240009580023A7C428000C81C001C33 -:10004000C037C0007C40C0007C4100007CB4800B05 -:10005000C036000399C00000C81C001C7CB4800C92 -:1000600024D400027D654000CD400043CE80004393 -:10007000CD000043CC800040CE400040CE80004008 -:10008000CCC00040DC3A00009780FFDECD0000408D -:100090007C40C000800000187C410000D400034078 -:1000A000D4000FC0D4000FA2C818000E8000000CAE -:1000B00031980002D40003C0D4000FC0D4000FA2B6 -:1000C000C818000E288C000830CC000F3410000136 -:1000D0007D0D00088000000C7D91800BCC800040DD -:1000E000D04000407C408000A00000007E82800B59 -:1000F000D4000340D4000FC0D4000FA2CC80004035 -:10010000D04000407C408000A00000007E82800B38 -:10011000D40003C0D4000FC0D4000FA2CC80004094 -:10012000D04000407C408000A00000007E82800B18 -:10013000CC4003F980000249CC4003F8C037FFFFF0 -:100140007C414000CF41A29EC82003F8C81C03F99F -:1001500066200020C81803FB7DE1C02C7D58C00834 -:100160007CDCC02069100020C0360003CC000054A5 -:100170007CB4800C80000069CC8000407C41800011 -:10018000CD81A29ECC80004080000067CD800040E1 -:10019000C019FFFFCC800040CD81A29E7C40C000F2 -:1001A0007C4100007C414000CCC1A1FACD01A1F905 -:1001B000CD41A29DCCC00040CD000040CD400040CC -:1001C000CC4000407C408000A00000007E82800B7C -:1001D000CC000054CC8000407C40C0007C4100003A -:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35 -:1001F000CCC00040CD000040CD400040D040004089 -:100200007C408000A00000007E82800B7C40C0000B -:1002100030D00001CCC1A29F95000003041400015E -:1002200004140002CD4003FBCC800040800000009D -:10023000CCC000407C40C000CC800040CCC1A2A219 -:1002400080000000CCC000407C40C00028D4001FCB -:10025000CC800040954000037C410000CCC000579A -:100260002918001FCCC0004095800003CD0000403D -:10027000CD00005880000249CC00007FC820001744 -:10028000C83000229A0000060E280001C824001E73 -:100290000A640001D4001240CE400040C036C000C5 -:1002A0009680000737747900041C0001CF4000409D -:1002B000CDC00040CF0003FA7C030000CA0C001040 -:1002C0007C41000094C000047C414000D42002C462 -:1002D000CDE000449B00000B7C418000CC00004B33 -:1002E000CDA00049CD200041CD600041CDA000410E -:1002F00006200001CE00005680000249CC00007F9D -:10030000C8280020C82C0021CC0000637EEA4001F0 -:10031000657400207F53402C269C00027DF5C02090 -:1003200069F80020CE80004BCE600049CDE000414E -:10033000CFA00041CE600041271C00027DF5C02007 -:1003400069F800207DB24001CF00004BCE6000492B -:10035000CDE00041CFA00041800000BCCE60004154 -:10036000C8200017C83000229A0000060E2800019D -:10037000C824001E0A640001D4001240CE40004090 -:10038000CA0C00107C41000094C0000BC036C000B5 -:100390009680000737747900041C0001CF400040AC -:1003A000CDC00040CF0003FA7C030000800000B500 -:1003B0007C414000CC000048800000EE00000000BE -:1003C000C8200017C81C00230E24000299C0001585 -:1003D0007C4180000A200001CE000056D400044079 -:1003E000CC000040C036C000CA140013964000077D -:1003F00037747900CF400040CC000040C83003FA89 -:1004000080000103CF000022CC000022954001466D -:10041000CC00007FCCA0004680000000CC2000462D -:1004200080000249CC000064C8200017C810001FDB -:100430009600000509100001D4000440CD000040E2 -:10044000CD000022CC800040D0400040C80C0025E8 -:1004500094C0FEECC8100008CD000040D4000FC0CE -:1004600080000000D4000FA27C40C0007C4100004E -:10047000CCC003FDCD0003FCCCC00042CD00004247 -:100480002914001F29180010319800073B5C000157 -:100490007D76000B998000057D5E400BCC0000420C -:1004A00080000249CC00004D29980001292C000849 -:1004B0009980003D32EC0001960000042930000CC8 -:1004C00080000249CC00004204140010CD400042DC -:1004D00033300001342800018400015DC81400039A -:1004E0009B40001B0438000C8400015DC81400030D -:1004F0009B400017043800088400015DC814000305 -:100500009B400013043800048400015DC8140003FC -:100510009B400015C80C03FD9A800009C81003FC1D -:100520009B000101CC00004D04140010CCC000421F -:10053000CD00004280000135CD40004296C000FA57 -:10054000CC00004D80000249CC00004E9AC0000350 -:10055000CC00004DCC00004EDF8300008000000086 -:10056000D80301FF9AC000F0CC00004D8000024982 -:10057000CC00004EC8180003C81C0003C8200003AC -:100580007D5D40037DA1C0037D5D400C2A10001FEE -:10059000299C001F7D1D000B7D17400B880000006B -:1005A0007E92800B96400004CC00004E80000249F1 -:1005B000CC00004204380008CF800042C808000385 -:1005C000C80C0003C8100003C8140003C8180003B7 -:1005D000C81C0003C8240003C828000329FC001F0E -:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61 -:1005F0002970001F7FF3C00B7D8880017DCCC00176 -:100600007E5100017E9540017C9080027CD4C00226 -:100610007CBC800B9AC000037C8F400B38B4000177 -:100620009B4000C1CC00004D9BC000BFCC00004EE1 -:10063000C80C03FDC81003FCCCC000428000016E52 -:10064000CD000042D4000340D4000FC0D4000FA25C -:10065000CC800040CC400040CC400040CC4000402A -:100660007C40C000CCC00040CCC0000D8000000029 -:10067000D04000407C40C0007C4100006514002058 -:100680007D4D402C245800027D5980207C41C000C3 -:10069000CD80004269980020CD800042CDC000424C -:1006A000C023C00005E400027CA0800B266400107B -:1006B0007CA4800CCC800040CDC00040CCC0004069 -:1006C00095C0000ECD00004009DC0001C8280003E1 -:1006D00096800008CE800040C834001D974000007E -:1006E000C834001D26A800088400024CCC2B000052 -:1006F00099C0FFF709DC0001DC3A00009780000494 -:100700007C418000800001A225980002A00000002A -:100710007D808000C818001D7C40C00064D00008A7 -:1007200095800000C818001DCC130000CC8000404C -:10073000CCC0004080000000CC400040C810001F2A -:100740007C40C000CC8000407CD1400CCD400040BB -:100750000518000180000000CD8000227C40C00010 -:10076000645000208400024CCC0000617CD0C02C7E -:10077000C8200017C8D60000994000087C438000BC -:10078000DF830000CFA0004F8400024CCC00006249 -:1007900080000000D040007F80000249CC00006251 -:1007A0008400024CCC000061C82000177C40C000CF -:1007B000C036FF00C810000DC0303FFF7CF5400B75 -:1007C0007D51800B7D81800F998000087CF3800B28 -:1007D000DF830000CFA0004F8400024CCC000062F9 -:1007E00080000000D040007F80000249CC00006201 -:1007F0008400024C7C40C00028DC000895C0001931 -:1008000030DC00107C41000099C0000464540020DA -:1008100080000208C91D00007D15002CC91E0000C3 -:100820007C4200007C4240007C4180007DE5C00BA2 -:100830007DE280079A80000E41AC00059AC000005E -:100840000AEC000130DC001099C000040000000038 -:100850008000020BC91D00008000020BC91E0000B1 -:10086000CC800040CCC00040D0400040C80C0025E7 -:1008700094C0FDE4C8100008CD000040D4000FC0B3 -:1008800080000000D4000FA2D4000340D4000FC0A9 -:10089000D4000FA2CC800040D04000407C408000BB -:1008A000A00000007E82800BD40003C0D4000FC0E3 -:1008B000D4000FA2CC800040D04000407C4080009B -:1008C000A00000007E82800B7C40C00030D000067B -:1008D0000D10000699000007C81400159940000586 -:1008E000CC000052D4000340D4000FC0D4000FA2AB -:1008F000CC800040CCC0004080000000D0400040D0 -:100900007C40C000CC4D0000DC3A00009780FDBD6B -:1009100004CC000180000242CC4D000080000000A9 -:10092000D040007FCC00007F80000000CC00007F22 -:10093000CC00007F88000000CC00007F0000000099 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C0000000302220004022A0005009F00020003E4 -:100C10000006003C0007002700080191000900447D -:100C2000000A002D00100247001700F0002201D733 -:100C3000002301E80026004C0027005F0020011A75 -:100C4000002800920029004F002A0083002B006436 -:100C5000002F008D003200D80034023200360074BC -:100C60000039010A003C01FC003F009F00410005E3 -:100C7000004401940048019D004901C5004A01CF8C -:100C8000005502250056022D0060000A0061002A6E -:100C90000062003000630030006400300065003006 -:100CA0000066003000670030006800370069003FD0 -:100CB000006A0047006B0047006C0047006D00476A -:100CC000006E0047006F0047007000470073024746 -:100CD000007B024000000005000000050000000548 -:100CE00000000005000000050000000500000005F0 -:100CF00000000005000000050000000500000005E0 -:100D000000000005000000050000000500000005CF -:100D100000000005000000050000000500000005BF -:100D200000000005000000050000000500000005AF -:100D3000000000050000000500000005000000059F -:00000001FF diff --git a/firmware/radeon/RV730_me.bin.ihex b/firmware/radeon/RV730_me.bin.ihex deleted file mode 100644 index 390c18e7cef30c069b56060bbe2572f4352521a5..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV730_me.bin.ihex +++ /dev/null @@ -1,341 +0,0 @@ -:10000000CC0003EA7C408000A0000000CC800062AD -:1000100080000001D040007F80000001CC40004102 -:100020007C40C000C016000430D03FFF7D15000C9E -:10003000CC11000028D8001E3198000128DC001FD8 -:10004000C820000495C000067C424000CC0000623D -:100050007E56800CCC290000C82400047E26000BAC -:10006000958000067C42C000CC0000627ED7000C68 -:10007000CC310000C82C00047E2E000CCC000062A5 -:1000800031103FFF80000001CE1100007C40C00015 -:1000900080000001CC40004080000001CC4122578C -:1000A0007C418000CC400045CC400048CC41225CE3 -:1000B000CC41A1FC7C408000A0000000CC8000620C -:1000C000CC400045CC4000487C40C000CC41225C84 -:1000D000CC41A1FC7C408000A0000000CC800062EC -:1000E000CC000045CC000048CC41225CCC41A1FCB6 -:1000F0007C408000A0000000CC800062040CA1FDC8 -:10010000C0120001CC000045CC0000487CD0C00CDF -:10011000CC41225CCC41A1FCD04D00007C40800051 -:10012000A0000000CC80006280000001CC41225D74 -:100130007C4080007C40C000C02A00027C4100005E -:100140007D29000C3094000130980006309C03009B -:1001500029DC00087C4200007C4240009540000FF2 -:10016000C02E000405F022587F2F000CCC31000077 -:10017000C8280004CCC12169CD01216ACE81216B40 -:100180000DB40002CC01216C9740000E0DB40000AC -:100190008000007BC834000A0DB4000297400009BB -:1001A0000DB40000C02E000405F022587F2F000C73 -:1001B000CC310000C82800048000007BC834000A4D -:1001C000974000047E0280008000007BC834000A53 -:1001D0000DB400049740FF8C00000000CE01216D9B -:1001E000CE41216EC8280003C834000A9B40000499 -:1001F000043C00058400026BCC0000620DF400009A -:100200009740000BC82C03E6CE81A2B7C030000691 -:100210007EF34028C03000207F6B80207FB3C02950 -:10022000CF81A2C480000001CFC1A2D10DF4000192 -:100230009740000BC82C03E7CE81A2BBC03000065C -:100240007EF34028C03000207F6B80207FB3C02920 -:10025000CF81A2C580000001CFC1A2D20DF400025F -:100260009740000BC82C03E8CE81A2BFC030000627 -:100270007EF34028C03000207F6B80207FB3C029F0 -:10028000CF81A2C680000001CFC1A2D3C82C03E950 -:10029000CE81A2C3C03000067EF34028C0300020CB -:1002A0007F6B80207FB3C029CF81A2C7800000016F -:1002B000CFC1A2D480000001CC4000427C40C000ED -:1002C0007C4100002914001D315400019940000CAC -:1002D00031181000C81C001195C00000C81C001186 -:1002E000CCC12100CD012101CCC12102CD012103CE -:1002F000041800048000037CCD81A2A4C02A00045D -:100300009580000836A821A3CC290000C828000445 -:10031000C81C00110DE400409640FFFFC81C0011EE -:10032000CCC12170CD012171C820001296000000BF -:10033000C82000128000037CCC0000647C40C00018 -:100340007C410000CC000045CC00004840D40003B4 -:10035000CD41225CCD01A1FCC01A0001041CA1FD0D -:100360007DD9C00C7C42000008CC000106240001AD -:1003700006280002CE1D0000CE5D000098C0FFFAE6 -:10038000CE9D00007C408000A0000000CC80006278 -:100390007C40C00030D0000128CC00017C414000EE -:1003A000950000067C418000CD41216DCD81216EFC -:1003B000800000F2C81C0003C02200047E16000C5E -:1003C000CC210000C81C00047C42400098C00004FE -:1003D0007C42800080000001CDE50000CE41216913 -:1003E000CE81216ACDC1216B80000001CC01216C3E -:1003F0007C40C0007C4100007C4140007C4180008A -:100400007C41C00028A40008326400FF0E68003C54 -:100410009680000A7C0200007C4200001E3000032F -:10042000CC00006A9B00000342200005042000402D -:100430008000010F7C0240007E0240009A400000D4 -:100440000A64000130EC00109AC0000ACC0000627F -:10045000C02A0004C82C00217E92800CCC000041F0 -:10046000CC290000CEC000218000011FC83000044C -:10047000CD01216DCD41216EC83000037F1F000BDF -:1004800030F40007277800019740002A07B80124BC -:100490009F80000000000000800001347F1B80046A -:1004A000800001387F1B80058000013C7F1B80029B -:1004B000800001407F1B8003800001447F1B800778 -:1004C000800001487F1B80068000014D28A40008A1 -:1004D0009B80001928A400088000015D326400FFA1 -:1004E0009B80001528A400088000015D326400FF95 -:1004F0009B80001128A400088000015D326400FF89 -:100500009B80000D28A400088000015D326400FF7C -:100510009B80000928A400088000015D326400FF70 -:100520009B80000528A400088000015D326400FF64 -:1005300028A40008326400FF0E68003C9A80FEB2D6 -:1005400028EC00087C4340007C4380007C43C000D2 -:1005500096C00007CC000062CF412169CF81216A9B -:10056000CFC1216B80000001CC01216C8000000113 -:10057000CFF50000CC00006B8400037F0E68003CC8 -:100580009A800004C828001580000001D040007F38 -:100590009680FFAB7E02400084000239C00E00024C -:1005A000CC00004180000237CCC1304A7C40C00002 -:1005B0007C410000C01E000129240012C02200025C -:1005C00096400005C0260004C027FFFB7D25000BD8 -:1005D000C02600007DD2800B7E12C00B7D25000C52 -:1005E0007C4140007C418000CCC121699A80000A96 -:1005F000CD01216ACD41216B96C0FE83CD81216C56 -:10060000C830001897000000C830001880000001B2 -:10061000CC0000188400037FCC00007FC8140013B6 -:10062000C8180014CD41216B96C0FE77CD81216C96 -:1006300080000181C8300018C80C000898C0000074 -:10064000C80C00087C41000095000002000000007A -:100650007C414000C8200009CC400043CE01A1F4F9 -:10066000CC400044C00E80007C4240007C428000B0 -:100670002AAC001F96C0FE64C035F000CE4003E2F5 -:1006800032780003267C00087FF7C00B7FFBC00C8C -:100690002A780018CFC003E3CF8003E426B000021D -:1006A0007F3F0000CF0003E58000031D7C80C00079 -:1006B0007C40C00028D000083110000F9500000FCA -:1006C0002528000106A801B29E800000000000005D -:1006D000800001D3C0120800800001E1C814000F9F -:1006E000800001E8C8140010800001EFCCC1A2A472 -:1006F000800001F8C814001130D0003F0D2800150B -:100700009A8000120D28001E9A80001E0D280020DD -:100710009A8000230D24000F0D2800107E6A800CA3 -:100720009A8000260D2000040D2400140D280028B6 -:100730007E62400C7EA6800C9A80002AC8140011AC -:1007400080000001CCC1A2A4C01208007C4140007E -:100750007D0CC00CC012000829580003295C000C55 -:100760007C4200007DD1C00B262000147E1E400C70 -:100770007E4E800CCE81A2A480000001CD81A1FE1E -:10078000C814000F0410210E95400000C814000F7B -:10079000D051000080000001CCC1A2A4C8140010F8 -:1007A0000410210895400000C8140010D05100002A -:1007B00080000001CCC1A2A4CCC1A2A404100001FD -:1007C000CD0000198400037FCC00007FC810001901 -:1007D00099000000C8100019800000027C408000D1 -:1007E0000410210095400000C8140011D0510000F1 -:1007F0008000037CCCC1A2A47C40C000CC40000D92 -:1008000094C0FE01CC40000E7C4100009500000524 -:1008100008CC0001C8140005994000140000000035 -:1008200098C0FFFB7C410000800000027D0080003A -:10083000C81400057C40C0009940000CC818000C8A -:100840007C4100009580FDF0C820000EC81C000D02 -:10085000662000207E1E002C252400027E6240209F -:1008600080000001CCE600007C410000CC00006C60 -:10087000CC00006DC818001FC81C001E6598002021 -:100880007DD9C02C7CD4C00CCCDE000045DC00043B -:10089000C82800179680000FC00E000128680008C5 -:1008A0002AAC001632A800FF0EB000497F2F000BC3 -:1008B0009700000600000000C81400057C40C0003E -:1008C000800002217C41000080000224D040007F93 -:1008D00084000239CC000041CCC1304A94000000B1 -:1008E000C83C001A043C0005CFC1A2A4C0361F902A -:1008F000C0387FFF7C03C0107F7B400CCF41217C40 -:10090000CFC1217DCC01217EC03A00040434217F77 -:100910007F7B400CCC350000C83C00042BFC001F42 -:100920000438002097C00005CC0000629B800000C6 -:100930000BB8000180000245CC000071CC01A1F48D -:1009400004380016C0360002CF81A2A4880000003F -:10095000CF4120107C40C00028D0001C950000052D -:1009600004D40001CD40006580000001CD40006846 -:100970000954000280000001CD4000668400026A34 -:10098000C81803EA7C40C0009980FD9FC814001677 -:1009900008D000019940002BCD0000687C40800009 -:1009A000A0000000CC800062043C0005CFC1A2A4DE -:1009B000CC01A1F48400037FCC0000468800000035 -:1009C000CC00007F8400027CC81803EA7C40C00091 -:1009D0009980FD8DC814001608D0000199400019B7 -:1009E000CD0000687C408000A0000000CC80006248 -:1009F000043C0022CFC1A2A48400037FCC000047A6 -:100A000088000000CC00007FC81000169900000D7F -:100A1000CC400067800000027C408000C81803EAD8 -:100A20009980FD797C40C00094C00003C810001676 -:100A300099000004CCC00068800000027C40800067 -:100A400084000239C0148000CC000041CD41304AFE -:100A5000C014800099000000C81000168000000239 -:100A60007C408000C01200017C51400C80000001DD -:100A7000D05500007C40C0007C4100007C4140001B -:100A80007C418000291C001FCCC0004ACD00004BD7 -:100A900095C00003C01C8000CDC12010DD83000084 -:100AA000055C2000CC00006280000001D81F4100DE -:100AB0007C40C0007C4100007C4140007C418000C3 -:100AC000CCC0004CCD00004DDD830000055CA000D3 -:100AD00080000001D81F41007C40C0007C41000024 -:100AE0007C4140007C418000CCC0004ECD00004FD6 -:100AF000DD830000055CC00080000001D81F4100BC -:100B00007C40C0007C4100007C4140007C41800072 -:100B1000CCC00050CD000051DD830000055CF8E042 -:100B200080000001D81F41007C40C0007C410000D3 -:100B30007C4140007C418000CCC00052CD0000537D -:100B4000DD830000055CF88080000001D81F4100B3 -:100B50007C40C0007C4100007C4140007C41800022 -:100B6000CCC00054CD000055DD830000055CE000E2 -:100B700080000001D81F41007C40C0007C41000083 -:100B80007C4140007C418000CCC00056CD00005725 -:100B9000DD830000055CF00080000001D81F4100EB -:100BA0007C40C0007C4100007C4140007C418000D2 -:100BB000CCC00058CD000059DD830000055CF3FC7B -:100BC00080000001D81F4100D04320007C408000FD -:100BD000A0000000CC800062D043A0007C408000D8 -:100BE000A0000000CC800062D043C0007C408000A8 -:100BF000A0000000CC800062D043F8E07C40800080 -:100C0000A0000000CC800062D043F8807C408000CF -:100C1000A0000000CC800062D043E0007C40800057 -:100C2000A0000000CC800062D043F0007C40800037 -:100C3000A0000000CC800062D043F3FC7C40800028 -:100C4000A0000000CC800062C81403E0CC43000088 -:100C5000CC430000CC4300007D45C000CDC3000064 -:100C6000D04300007C408000A0000000CC800062E7 -:100C70007C40C000C81003E2C81403E5C81803E3B1 -:100C8000C81C03E4CD812169CDC1216ACCC1216B8F -:100C9000CC01216C042000047DA180007D964002DF -:100CA0009640FCD9CD8003E331280003C02DF0002D -:100CB000251800087DAD800B7DA9800C8000000107 -:100CC000CD8003E3308CFFFFD04D00007C408000DE -:100CD000A0000000CC800062C8140020155800025B -:100CE0009580FFFFC8140020CC00006ECC4121800D -:100CF0007C40C000CCC1218DCC41218128D0001F77 -:100D000034588000CD81218C9500FCBFCC412182DC -:100D1000C81400209940FFFFC81400208000000282 -:100D20007C4080007C40C00028D0001831100001B9 -:100D3000C016008095000003C02A00047CD4C00CBB -:100D4000CCC1217CCC41217DCC41217E7C418000E5 -:100D50001DB0000336A0217F9B000003419C0005CD -:100D6000041C004099C0000009DC0001CC210000F7 -:100D7000C82400042A6C001F419C00059AC0FFFA99 -:100D8000CC800062800000027C4080007C40C0007B -:100D900004D403E680000001CC5400008000037CF2 -:100DA000CC4003EAC01C8000044CA000CDC1201040 -:100DB0007C410000C814000904180000041C00084D -:100DC000CD80007109DC000105980001CD0D000007 -:100DD00099C0FFFCCC8000628000037CCD40007194 -:100DE000C00E0100CC000041CCC1304AC83C007F9D -:100DF000CC00007F80000001CC00007FCC00007F91 -:100E000088000000CC00007F00000000000000000F -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:10140000000103310010000400170006002100084D -:10141000002700280028002300290029002A002690 -:10142000002B0029002D0038002E003F002F004A1D -:101430000034004C00360030003900AF003A00CFD5 -:10144000003B00E4003C00FC003D016B003F00ADB0 -:1014500000410336004303490044018E004500FC6F -:10146000004601AC004701AC004801FE0049020CF7 -:10147000004A0255004B02820052025F0053027183 -:1014800000540287005702990060029D006102AC7F -:10149000006202B6006302C0006402CA006502D4A2 -:1014A000006602DE006702E8006802F2006902F6E8 -:1014B000006A02FA006B02FE006C0302006D030674 -:1014C000006E030A006F030E0070031200720363C4 -:1014D0000074036900790367007C031C000F037824 -:1014E000000F0378000F0378000F0378000F0378D4 -:1014F000000F0378000F0378000F0378000F0378C4 -:10150000000F0378000F0378000F0378000F0378B3 -:10151000000F0378000F0378000F0378000F0378A3 -:10152000000F0378000F0378000F0378000F037893 -:10153000000F0378000F0378000F0378000F037883 -:00000001FF diff --git a/firmware/radeon/RV730_pfp.bin.ihex b/firmware/radeon/RV730_pfp.bin.ihex deleted file mode 100644 index 3d811ff0a1a8a727604bb0fe556c4c5bb352b012..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV730_pfp.bin.ihex +++ /dev/null @@ -1,213 +0,0 @@ -:100000007C408000A00000007E82800B8000000009 -:10001000DC030000CC800040D04000407C408000E9 -:10002000A00000007E82800BC818000E31980001ED -:100030007C4240009580023A7C428000C81C001C33 -:10004000C037C0007C40C0007C4100007CB4800B05 -:10005000C036000399C00000C81C001C7CB4800C92 -:1000600024D400027D654000CD400043CE80004393 -:10007000CD000043CC800040CE400040CE80004008 -:10008000CCC00040DC3A00009780FFDECD0000408D -:100090007C40C000800000187C410000D400034078 -:1000A000D4000FC0D4000FA2C818000E8000000CAE -:1000B00031980002D40003C0D4000FC0D4000FA2B6 -:1000C000C818000E288C000830CC000F3410000136 -:1000D0007D0D00088000000C7D91800BCC800040DD -:1000E000D04000407C408000A00000007E82800B59 -:1000F000D4000340D4000FC0D4000FA2CC80004035 -:10010000D04000407C408000A00000007E82800B38 -:10011000D40003C0D4000FC0D4000FA2CC80004094 -:10012000D04000407C408000A00000007E82800B18 -:10013000CC4003F980000249CC4003F8C037FFFFF0 -:100140007C414000CF41A29EC82003F8C81C03F99F -:1001500066200020C81803FB7DE1C02C7D58C00834 -:100160007CDCC02069100020C0360003CC000054A5 -:100170007CB4800C80000069CC8000407C41800011 -:10018000CD81A29ECC80004080000067CD800040E1 -:10019000C019FFFFCC800040CD81A29E7C40C000F2 -:1001A0007C4100007C414000CCC1A1FACD01A1F905 -:1001B000CD41A29DCCC00040CD000040CD400040CC -:1001C000CC4000407C408000A00000007E82800B7C -:1001D000CC000054CC8000407C40C0007C4100003A -:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35 -:1001F000CCC00040CD000040CD400040D040004089 -:100200007C408000A00000007E82800B7C40C0000B -:1002100030D00001CCC1A29F95000003041400015E -:1002200004140002CD4003FBCC800040800000009D -:10023000CCC000407C40C000CC800040CCC1A2A219 -:1002400080000000CCC000407C40C00028D4001FCB -:10025000CC800040954000037C410000CCC000579A -:100260002918001FCCC0004095800003CD0000403D -:10027000CD00005880000249CC00007FC820001744 -:10028000C83000229A0000060E280001C824001E73 -:100290000A640001D4001240CE400040C036C000C5 -:1002A0009680000737747900041C0001CF4000409D -:1002B000CDC00040CF0003FA7C030000CA0C001040 -:1002C0007C41000094C000047C414000D42002C462 -:1002D000CDE000449B00000B7C418000CC00004B33 -:1002E000CDA00049CD200041CD600041CDA000410E -:1002F00006200001CE00005680000249CC00007F9D -:10030000C8280020C82C0021CC0000637EEA4001F0 -:10031000657400207F53402C269C00027DF5C02090 -:1003200069F80020CE80004BCE600049CDE000414E -:10033000CFA00041CE600041271C00027DF5C02007 -:1003400069F800207DB24001CF00004BCE6000492B -:10035000CDE00041CFA00041800000BCCE60004154 -:10036000C8200017C83000229A0000060E2800019D -:10037000C824001E0A640001D4001240CE40004090 -:10038000CA0C00107C41000094C0000BC036C000B5 -:100390009680000737747900041C0001CF400040AC -:1003A000CDC00040CF0003FA7C030000800000B500 -:1003B0007C414000CC000048800000EE00000000BE -:1003C000C8200017C81C00230E24000299C0001585 -:1003D0007C4180000A200001CE000056D400044079 -:1003E000CC000040C036C000CA140013964000077D -:1003F00037747900CF400040CC000040C83003FA89 -:1004000080000103CF000022CC000022954001466D -:10041000CC00007FCCA0004680000000CC2000462D -:1004200080000249CC000064C8200017C810001FDB -:100430009600000509100001D4000440CD000040E2 -:10044000CD000022CC800040D0400040C80C0025E8 -:1004500094C0FEECC8100008CD000040D4000FC0CE -:1004600080000000D4000FA27C40C0007C4100004E -:10047000CCC003FDCD0003FCCCC00042CD00004247 -:100480002914001F29180010319800073B5C000157 -:100490007D76000B998000057D5E400BCC0000420C -:1004A00080000249CC00004D29980001292C000849 -:1004B0009980003D32EC0001960000042930000CC8 -:1004C00080000249CC00004204140010CD400042DC -:1004D00033300001342800018400015DC81400039A -:1004E0009B40001B0438000C8400015DC81400030D -:1004F0009B400017043800088400015DC814000305 -:100500009B400013043800048400015DC8140003FC -:100510009B400015C80C03FD9A800009C81003FC1D -:100520009B000101CC00004D04140010CCC000421F -:10053000CD00004280000135CD40004296C000FA57 -:10054000CC00004D80000249CC00004E9AC0000350 -:10055000CC00004DCC00004EDF8300008000000086 -:10056000D80301FF9AC000F0CC00004D8000024982 -:10057000CC00004EC8180003C81C0003C8200003AC -:100580007D5D40037DA1C0037D5D400C2A10001FEE -:10059000299C001F7D1D000B7D17400B880000006B -:1005A0007E92800B96400004CC00004E80000249F1 -:1005B000CC00004204380008CF800042C808000385 -:1005C000C80C0003C8100003C8140003C8180003B7 -:1005D000C81C0003C8240003C828000329FC001F0E -:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61 -:1005F0002970001F7FF3C00B7D8880017DCCC00176 -:100600007E5100017E9540017C9080027CD4C00226 -:100610007CBC800B9AC000037C8F400B38B4000177 -:100620009B4000C1CC00004D9BC000BFCC00004EE1 -:10063000C80C03FDC81003FCCCC000428000016E52 -:10064000CD000042D4000340D4000FC0D4000FA25C -:10065000CC800040CC400040CC400040CC4000402A -:100660007C40C000CCC00040CCC0000D8000000029 -:10067000D04000407C40C0007C4100006514002058 -:100680007D4D402C245800027D5980207C41C000C3 -:10069000CD80004269980020CD800042CDC000424C -:1006A000C023C00005E400027CA0800B266400107B -:1006B0007CA4800CCC800040CDC00040CCC0004069 -:1006C00095C0000ECD00004009DC0001C8280003E1 -:1006D00096800008CE800040C834001D974000007E -:1006E000C834001D26A800088400024CCC2B000052 -:1006F00099C0FFF709DC0001DC3A00009780000494 -:100700007C418000800001A225980002A00000002A -:100710007D808000C818001D7C40C00064D00008A7 -:1007200095800000C818001DCC130000CC8000404C -:10073000CCC0004080000000CC400040C810001F2A -:100740007C40C000CC8000407CD1400CCD400040BB -:100750000518000180000000CD8000227C40C00010 -:10076000645000208400024CCC0000617CD0C02C7E -:10077000C8200017C8D60000994000087C438000BC -:10078000DF830000CFA0004F8400024CCC00006249 -:1007900080000000D040007F80000249CC00006251 -:1007A0008400024CCC000061C82000177C40C000CF -:1007B000C036FF00C810000DC0303FFF7CF5400B75 -:1007C0007D51800B7D81800F998000087CF3800B28 -:1007D000DF830000CFA0004F8400024CCC000062F9 -:1007E00080000000D040007F80000249CC00006201 -:1007F0008400024C7C40C00028DC000895C0001931 -:1008000030DC00107C41000099C0000464540020DA -:1008100080000208C91D00007D15002CC91E0000C3 -:100820007C4200007C4240007C4180007DE5C00BA2 -:100830007DE280079A80000E41AC00059AC000005E -:100840000AEC000130DC001099C000040000000038 -:100850008000020BC91D00008000020BC91E0000B1 -:10086000CC800040CCC00040D0400040C80C0025E7 -:1008700094C0FDE4C8100008CD000040D4000FC0B3 -:1008800080000000D4000FA2D4000340D4000FC0A9 -:10089000D4000FA2CC800040D04000407C408000BB -:1008A000A00000007E82800BD40003C0D4000FC0E3 -:1008B000D4000FA2CC800040D04000407C4080009B -:1008C000A00000007E82800B7C40C00030D000067B -:1008D0000D10000699000007C81400159940000586 -:1008E000CC000052D4000340D4000FC0D4000FA2AB -:1008F000CC800040CCC0004080000000D0400040D0 -:100900007C40C000CC4D0000DC3A00009780FDBD6B -:1009100004CC000180000242CC4D000080000000A9 -:10092000D040007FCC00007F80000000CC00007F22 -:10093000CC00007F88000000CC00007F0000000099 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C0000000302220004022A0005009F00020003E4 -:100C10000006003C0007002700080191000900447D -:100C2000000A002D00100247001700F0002201D733 -:100C3000002301E80026004C0027005F0020011A75 -:100C4000002800920029004F002A0083002B006436 -:100C5000002F008D003200D80034023200360074BC -:100C60000039010A003C01FC003F009F00410005E3 -:100C7000004401940048019D004901C5004A01CF8C -:100C8000005502250056022D0060000A0061002A6E -:100C90000062003000630030006400300065003006 -:100CA0000066003000670030006800370069003FD0 -:100CB000006A0047006B0047006C0047006D00476A -:100CC000006E0047006F0047007000470073024746 -:100CD000007B024000000005000000050000000548 -:100CE00000000005000000050000000500000005F0 -:100CF00000000005000000050000000500000005E0 -:100D000000000005000000050000000500000005CF -:100D100000000005000000050000000500000005BF -:100D200000000005000000050000000500000005AF -:100D3000000000050000000500000005000000059F -:00000001FF diff --git a/firmware/radeon/RV770_me.bin.ihex b/firmware/radeon/RV770_me.bin.ihex deleted file mode 100644 index a0e16990a20a4cd7177f553b7aca90530d355f80..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV770_me.bin.ihex +++ /dev/null @@ -1,341 +0,0 @@ -:10000000CC0003EA7C408000A0000000CC800062AD -:1000100080000001D040007F80000001CC40004102 -:100020007C40C000C016000430D03FFF7D15000C9E -:10003000CC11000028D8001E3198000128DC001FD8 -:10004000C820000495C000067C424000CC0000623D -:100050007E56800CCC290000C82400047E26000BAC -:10006000958000067C42C000CC0000627ED7000C68 -:10007000CC310000C82C00047E2E000CCC000062A5 -:1000800031103FFF80000001CE1100007C40C00015 -:1000900080000001CC40004080000001CC4122578C -:1000A0007C418000CC400045CC400048CC41225CE3 -:1000B000CC41A1FC7C408000A0000000CC8000620C -:1000C000CC400045CC4000487C40C000CC41225C84 -:1000D000CC41A1FC7C408000A0000000CC800062EC -:1000E000CC000045CC000048CC41225CCC41A1FCB6 -:1000F0007C408000A0000000CC800062040CA1FDC8 -:10010000C0120001CC000045CC0000487CD0C00CDF -:10011000CC41225CCC41A1FCD04D00007C40800051 -:10012000A0000000CC80006280000001CC41225D74 -:100130007C4080007C40C000C02A00027C4100005E -:100140007D29000C3094000130980006309C03009B -:1001500029DC00087C4200007C4240009540000FF2 -:10016000C02E000405F022587F2F000CCC31000077 -:10017000C8280004CCC12169CD01216ACE81216B40 -:100180000DB40002CC01216C9740000E0DB40000AC -:100190008000007BC834000A0DB4000297400009BB -:1001A0000DB40000C02E000405F022587F2F000C73 -:1001B000CC310000C82800048000007BC834000A4D -:1001C000974000047E0280008000007BC834000A53 -:1001D0000DB400049740FF8C00000000CE01216D9B -:1001E000CE41216EC8280003C834000A9B40000499 -:1001F000043C00058400026DCC0000620DF4000098 -:100200009740000BC82C03E6CE81A2B7C030000691 -:100210007EF34028C03000207F6B80207FB3C02950 -:10022000CF81A2C480000001CFC1A2D10DF4000192 -:100230009740000BC82C03E7CE81A2BBC03000065C -:100240007EF34028C03000207F6B80207FB3C02920 -:10025000CF81A2C580000001CFC1A2D20DF400025F -:100260009740000BC82C03E8CE81A2BFC030000627 -:100270007EF34028C03000207F6B80207FB3C029F0 -:10028000CF81A2C680000001CFC1A2D3C82C03E950 -:10029000CE81A2C3C03000067EF34028C0300020CB -:1002A0007F6B80207FB3C029CF81A2C7800000016F -:1002B000CFC1A2D480000001CC4000427C40C000ED -:1002C0007C4100002914001D315400019940000DAB -:1002D00031181000C81C001109DC000195C0FFFF97 -:1002E000C81C0011CCC12100CD012101CCC12102CB -:1002F000CD012103041800048000039FCD81A2A436 -:10030000C02A00049580000836A821A3CC2900004B -:10031000C8280004C81C00110DE400409640FFFFEF -:10032000C81C0011CCC12170CD012171C820001260 -:1003300096000000C82000128000039FCC000064DB -:100340007C40C0007C410000CC000045CC0000484F -:1003500040D40003CD41225CCD01A1FCC01A0001B4 -:10036000041CA1FD7DD9C00C7C42000008CC00011A -:100370000624000106280002CE1D0000CE5D00000C -:1003800098C0FFFACE9D00007C408000A0000000D5 -:10039000CC8000627C40C00030D0000128CC00013D -:1003A0007C414000950000067C418000CD41216DDC -:1003B000CD81216E800000F3C81C0003C022000420 -:1003C0007E16000CCC210000C81C00047C424000BA -:1003D00098C000047C42800080000001CDE5000050 -:1003E000CE412169CE81216ACDC1216B80000001FF -:1003F000CC01216C7C40C0007C4100007C4140006D -:100400007C4180007C41C00028A40008326400FFC9 -:100410000E68003C9680000A7C0200007C420000CE -:100420001E300003CC00006A9B0000034220000540 -:1004300004200040800001107C0240007E02400049 -:100440009A4000000A64000130EC00109AC0000AD3 -:10045000CC000062C02A0004C82C00217E92800CCF -:10046000CC000041CC290000CEC00021800001203A -:10047000C8300004CD01216DCD41216EC83000038C -:100480007F1F000B30F40007277800019740002AF7 -:1004900007B801259F8000000000000080000135A2 -:1004A0007F1B8004800001397F1B80058000013D97 -:1004B0007F1B8002800001417F1B8003800001457B -:1004C0007F1B8007800001497F1B80068000014E52 -:1004D00028A400089B80001928A400088000015E61 -:1004E000326400FF9B80001528A400088000015E94 -:1004F000326400FF9B80001128A400088000015E88 -:10050000326400FF9B80000D28A400088000015E7B -:10051000326400FF9B80000928A400088000015E6F -:10052000326400FF9B80000528A400088000015E63 -:10053000326400FF28A40008326400FF0E68003C0B -:100540009A80FEB128EC00087C4340007C43800088 -:100550007C43C00096C00007CC000062CF412169F7 -:10056000CF81216ACFC1216B80000001CC01216CB9 -:1005700080000001CFF50000CC00006B840003A2D6 -:100580000E68003C9A800004C82800158000000115 -:10059000D040007F9680FFAB7E0240008400023B8B -:1005A000C00E0002CC00004180000239CCC1304AAC -:1005B0007C40C0007C410000C01E000129240012C4 -:1005C000C022000296400005C0260004C027FFFBA1 -:1005D0007D25000BC02600007DD2800B7E12C00B53 -:1005E0007D25000C7C4140007C418000CCC121690C -:1005F0009A80000ACD01216ACD41216B96C0FE820E -:10060000CD81216CC830001897000000C830001858 -:1006100080000001CC000018840003A2CC00007F01 -:10062000C8140013C8180014CD41216B96C0FE7683 -:10063000CD81216C80000182C8300018C80C0008F0 -:1006400098C00000C80C00087C4100009500000222 -:10065000000000007C414000C8200009CC4000435D -:10066000CE01A1F4CC400044C00E80007C4240008A -:100670007C4280002AAC001F96C0FE63C035F000AB -:10068000CE4003E232780003267C00087FF7C00BDF -:100690007FFBC00C2A780018CFC003E3CF8003E4AF -:1006A00026B000027F3F0000CF0003E58000031F5B -:1006B0007C80C0007C40C00028D000083110000FB2 -:1006C0009500000F2528000106A801B39E800000B8 -:1006D00000000000800001D4C0120800800001E288 -:1006E000C814000F800001E9C8140010800001F058 -:1006F000CCC1A2A4800001F9C814001130D0003F81 -:100700000D2800159A8000120D28001E9A80001EE8 -:100710000D2800209A8000230D24000F0D280010C2 -:100720007E6A800C9A8000260D2000040D2400149F -:100730000D2800287E62400C7EA6800C9A80002A3C -:10074000C814001180000001CCC1A2A4C01208008E -:100750007C4140007D0CC00CC012000829580003E9 -:10076000295C000C7C4200007DD1C00B26200014C7 -:100770007E1E400C7E4E800CCE81A2A48000000123 -:10078000CD81A1FEC814000F0410210E9540000079 -:10079000C814000FD051000080000001CCC1A2A4F9 -:1007A000C81400100410210895400000C81400105F -:1007B000D051000080000001CCC1A2A4CCC1A2A4F1 -:1007C00004100001CD000019840003A2CC00007FBA -:1007D000C810001999000000C8100019800000021C -:1007E0007C40800004102100095400019540FFFF67 -:1007F000C8140011D05100008000039FCCC1A2A4F6 -:100800007C40C000CC40000D94C0FDFFCC40000EE9 -:100810007C4100009500000508CC0001C8140005CB -:10082000994000140000000098C0FFFB7C410000CC -:10083000800000027D008000C81400057C40C000DC -:100840009940000CC818000C7C4100009580FDEE1A -:10085000C820000EC81C000D662000207E1E002C43 -:10086000252400027E62402080000001CCE60000CA -:100870007C410000CC00006CCC00006DC818001F4B -:10088000C81C001E659800207DD9C02C7CD4C00CEB -:10089000CCDE000045DC0004C82800179680000F5D -:1008A000C00E0001286800082AAC001632A800FF1C -:1008B0000EB000497F2F000B9700000600000000DB -:1008C000C81400057C40C000800002237C41000069 -:1008D00080000226D040007F8400023BCC00004113 -:1008E000CCC1304A94000000C83C001A043C00050A -:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8 -:100900007F7B400CCF41217CCFC1217DCC01217E5A -:10091000C03A00040434217F7F7B400CCC350000BA -:10092000C83C00042BFC001F0438002097C00005C1 -:10093000CC0000629B8000000BB8000180000247E1 -:10094000CC000071CC01A1F404380016C0360002BE -:10095000CF81A2A488000000CF4120107C40C000BD -:1009600028D0001C9500000504D40001CD4000658E -:1009700080000001CD4000680954000280000001A1 -:10098000CD4000668400026CC81803EA7C40C000B9 -:100990009980FD9DC814001608D000019940002BD5 -:1009A000CD0000687C408000A0000000CC80006288 -:1009B000043C0005CFC1A2A4CC01A1F4840003A291 -:1009C000CC00004688000000CC00007F8400027E3E -:1009D000C81803EA7C40C0009980FD8BC81400163B -:1009E00008D0000199400019CD0000687C408000CB -:1009F000A0000000CC800062043C0022CFC1A2A471 -:100A0000840003A2CC00004788000000CC00007FD7 -:100A1000C81000169900000DCC400067800000024D -:100A20007C408000C81803EA9980FD777C40C000B4 -:100A300094C00003C810001699000004CCC00068E0 -:100A4000800000027C4080008400023BC0148000D3 -:100A5000CC000041CD41304AC01480009900000014 -:100A6000C8100016800000027C408000C012000107 -:100A70007C51400C80000001D05500007C40C0003B -:100A80007C4100007C4140007C418000291C001F0B -:100A9000CCC0004ACD00004B95C00003C01C8000B4 -:100AA000CDC12010DD830000055C2000CC00006279 -:100AB00080000001D81F41007C40C0007C41000044 -:100AC0007C4140007C418000CCC0004CCD00004DFA -:100AD000DD830000055CA00080000001D81F4100FC -:100AE0007C40C0007C4100007C4140007C41800093 -:100AF000CCC0004ECD00004FDD830000055CC0007F -:100B000080000001D81F41007C40C0007C410000F3 -:100B10007C4140007C418000CCC00050CD000051A1 -:100B2000DD830000055CF8E080000001D81F410073 -:100B30007C40C0007C4100007C4140007C41800042 -:100B4000CCC00052CD000053DD830000055CF8806E -:100B500080000001D81F41007C40C0007C410000A3 -:100B60007C4140007C418000CCC00054CD00005549 -:100B7000DD830000055CE00080000001D81F41001B -:100B80007C40C0007C4100007C4140007C418000F2 -:100B9000CCC00056CD000057DD830000055CF0009E -:100BA00080000001D81F41007C40C0007C41000053 -:100BB0007C4140007C418000CCC00058CD000059F1 -:100BC000DD830000055CF3FC80000001D81F4100BC -:100BD000D04320007C408000A0000000CC80006258 -:100BE000D043A0007C408000A0000000CC800062C8 -:100BF000D043C0007C408000A0000000CC80006298 -:100C0000D043F8E07C408000A0000000CC8000626F -:100C1000D043F8807C408000A0000000CC800062BF -:100C2000D043E0007C408000A0000000CC80006247 -:100C3000D043F0007C408000A0000000CC80006227 -:100C4000D043F3FC7C408000A0000000CC80006218 -:100C5000C81403E0CC430000CC430000CC430000A8 -:100C60007D45C000CDC30000D04300007C40800023 -:100C7000A0000000CC8000627C40C000C81003E2ED -:100C8000C81403E5C81803E3C81C03E4CD81216937 -:100C9000CDC1216ACCC1216BCC01216C04200004A0 -:100CA0007DA180007D9640029640FCD7CD8003E375 -:100CB00031280003C02DF000251800087DAD800B01 -:100CC0007DA9800C80000001CD8003E3308CFFFF04 -:100CD000D04D00007C408000A0000000CC8000626D -:100CE0007C40C0007C4100002924001832640001CF -:100CF0009A400013C8140020155800029580FFFF89 -:100D0000C8140020CC00006ECCC12180CD01218D03 -:100D1000CC4121812914001F34588000CD81218CC1 -:100D20009540FCB9CC412182C81400209940FFFFB6 -:100D3000C8140020800000027C4080007C414000FC -:100D40007C4180007C41C00065B400207F57402C6E -:100D5000D437810047740004D437810047740004FD -:100D6000D43781004774000409DC0004D4378100C3 -:100D700099C0FFF8477400042924001FC0380019E7 -:100D80009640FCA1C03E0004CF8121F837E021F954 -:100D9000CC210000C82000042A20001832200001C5 -:100DA0009A00FFFBCF8121F8800000027C40800088 -:100DB0007C40C00028D0001831100001C01600800F -:100DC00095000003C02A00047CD4C00CCCC1217C57 -:100DD000CC41217DCC41217E7C4180001DB00003AF -:100DE00036A0217F9B000003419C0005041C0040AD -:100DF00099C0000009DC0001CC210000C8240004D7 -:100E00002A6C001F419C00059AC0FFFACC8000624A -:100E1000800000027C4080007C40C00004D403E6D7 -:100E200080000001CC5400008000039FCC4003EA06 -:100E3000C01C8000044CA000CDC120107C410000EB -:100E4000C814000904180000041C0008CD800071BB -:100E500009DC000105980001CD0D000099C0FFFCE0 -:100E6000CC8000628000039FCD400071C00E010065 -:100E7000CC000041CCC1304AC83C007FCC00007F90 -:100E800080000001CC00007FCC00007F88000000C3 -:100E9000CC00007F00000000000000000000000007 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:10140000000103330010000400170006002100084B -:10141000002700280028002300290029002A002690 -:10142000002B0029002D0038002E003F002F004A1D -:101430000034004C00360030003900AF003A00D0D4 -:10144000003B00E5003C00FD003D016C003F00ADAD -:10145000004103380043036C0044018F004500FD48 -:10146000004601AD004701AD004802000049020EF0 -:10147000004A0257004B028400520261005302737B -:10148000005402890057029B0060029F006102AE77 -:10149000006202B8006302C2006402CC006502D69A -:1014A000006602E0006702EA006802F4006902F8E0 -:1014B000006A02FC006B0300006C0304006D03086B -:1014C000006E030C006F031000700314007203869B -:1014D0000074038C0079038A007C031E000F039BB9 -:1014E000000F039B000F039B000F039B000F039B48 -:1014F000000F039B000F039B000F039B000F039B38 -:10150000000F039B000F039B000F039B000F039B27 -:10151000000F039B000F039B000F039B000F039B17 -:10152000000F039B000F039B000F039B000F039B07 -:10153000000F039B000F039B000F039B000F039BF7 -:00000001FF diff --git a/firmware/radeon/RV770_pfp.bin.ihex b/firmware/radeon/RV770_pfp.bin.ihex deleted file mode 100644 index a2d1619107deb70a5c073f954091954038fb1d03..0000000000000000000000000000000000000000 --- a/firmware/radeon/RV770_pfp.bin.ihex +++ /dev/null @@ -1,213 +0,0 @@ -:100000007C408000A00000007E82800B8000000009 -:10001000DC030000CC800040D04000407C408000E9 -:10002000A00000007E82800BC818000E31980001ED -:100030007C424000958002527C428000C81C001C1B -:10004000C037C0007C40C0007C4100007CB4800B05 -:10005000C036000399C00000C81C001C7CB4800C92 -:1000600024D400027D654000CD400043CE80004393 -:10007000CD000043CC800040CE400040CE80004008 -:10008000CCC00040DC3A00009780FFDECD0000408D -:100090007C40C000800000187C410000D400034078 -:1000A000D4000FC0D4000FA2C818000E8000000CAE -:1000B00031980002D40003C0D4000FC0D4000FA2B6 -:1000C000C818000E288C000830CC000F3410000136 -:1000D0007D0D00088000000C7D91800BCC800040DD -:1000E000D04000407C408000A00000007E82800B59 -:1000F000D4000340D4000FC0D4000FA2CC80004035 -:10010000D04000407C408000A00000007E82800B38 -:10011000D40003C0D4000FC0D4000FA2CC80004094 -:10012000D04000407C408000A00000007E82800B18 -:10013000CC4003F980000261CC4003F8C82003F8EA -:10014000C81C03F9C81803FBC037FFFF7C414000FF -:10015000CF41A29E662000207DE1C02C7D58C008C2 -:100160007CDCC02068D00020C0360003CC000054E6 -:100170007CB4800C8000006ACC8000407C41800010 -:10018000CD81A29ECC800040CD80004080000068E0 -:10019000CC000054C019FFFFCC800040CD81A29E4E -:1001A0007C40C0007C4100007C414000CCC1A1FAF1 -:1001B000CD01A1F9CD41A29DCCC00040CD000040B1 -:1001C000CD400040CC4000407C408000A0000000BA -:1001D0007E82800BCC000054CC8000407C40C0006C -:1001E0007C4100007C414000CCC1A1FACD01A1F9C5 -:1001F000CD41A29DCCC00040CD000040CD4000408C -:10020000D04000407C408000A00000007E82800B37 -:100210007C40C00030D00001CCC1A29F95000003FB -:100220000414000104140002CD4003FBCC80004004 -:1002300080000000CCC000407C40C000CC8000406A -:10024000CCC1A2A280000000CCC000407C40C00015 -:1002500028D4001FCC800040954000037C41000062 -:10026000CCC000572918001FCCC000409580000367 -:10027000CD000040CD00005880000261CC00007F1E -:10028000C8200017C83000229A0000060E2800017E -:10029000C824001E0A640001D4001240CE40004071 -:1002A000C036C0009680000737747900041C000136 -:1002B000CF400040CDC00040CF0003FA7C030000D7 -:1002C000CA0C00107C41000094C000047C41400036 -:1002D000D42002C4CDE000449B00000B7C41800090 -:1002E000CC00004BCDA00049CD200041CD600041A5 -:1002F000CDA0004106200001CE0000568000026122 -:10030000CC00007FC8280020C82C0021CC0000634E -:100310007EEA4001657400207F53402C269C000239 -:100320007DF5C02069F80020CE80004BCE600049EA -:10033000CDE00041CFA00041CE600041271C00026B -:100340007DF5C02069F800207DB24001CF00004B50 -:10035000CE600049CDE00041CFA00041800000BD4B -:10036000CE600041C8200017C83000229A00000665 -:100370000E280001C824001E0A640001D4001240A7 -:10038000CE400040CA0C00107C41000094C0000B1D -:10039000C036C0009680000737747900041C000145 -:1003A000CF400040CDC00040CF0003FA7C030000E6 -:1003B000800000B67C414000CC000048800000EF87 -:1003C00000000000C8200017C81C00230E240002F3 -:1003D00099C000157C4180000A200001CE00005623 -:1003E000D4000440CC000040C036C000CA14001342 -:1003F0009640000737747900CF400040CC000040A1 -:10040000C83003FA80000104CF000022CC00002293 -:100410009540015DCC00007FCCA00046800000002C -:10042000CC20004680000261CC000064C820001788 -:10043000C810001F9600000509100001D4000440F8 -:10044000CD000040CD000022CC800040D0400040D4 -:10045000C80C002594C0FEEBC8100008CD00004079 -:10046000D4000FC080000000D4000FA27C40C00068 -:100470007C410000CCC003FDCD0003FCCCC0004299 -:10048000CD0000422914001F2918001031980007E0 -:100490003B5C00017D76000B998000057D5E400B82 -:1004A000CC00004280000261CC00004D2998000180 -:1004B000292C00089980003D32EC000196000004D0 -:1004C0002930000C80000261CC00004204140010AE -:1004D000CD40004233300001342800018400015E29 -:1004E000C81400039B40001B0438000C8400015E0C -:1004F000C81400039B400017043800088400015E04 -:10050000C81400039B400013043800048400015EFB -:10051000C81400039B400015C80C03FD9A80000915 -:10052000C81003FC9B000118CC00004D04140010FF -:10053000CCC00042CD00004280000136CD400042D8 -:1005400096C00111CC00004D80000261CC00004E2D -:100550009AC00003CC00004DCC00004EDF830000A9 -:1005600080000000D80301FF9AC00107CC00004DB5 -:1005700080000261CC00004EC8180003C81C0003B4 -:10058000C82000037D5D40037DA1C0037D5D400C5C -:100590002A10001F299C001F7D1D000B7D17400B9A -:1005A000880000007E92800B96400004CC00004E34 -:1005B00080000261CC00004204380008CF80004275 -:1005C000C8080003C80C0003C8100003C8140003C7 -:1005D000C8180003C81C0003C8240003C82800036F -:1005E00029FC001F2AB0001F7FF3C00B28F0001F5A -:1005F0007FF3C00B2970001F7FF3C00B7D88800143 -:100600007DCCC0017E5100017E9540017C9080022E -:100610007CD4C0027CBC800B9AC000037C8F400B52 -:1006200038B400019B4000D8CC00004D9BC000D6E0 -:10063000CC00004EC80C03FDC81003FCCCC0004227 -:100640008000016FCD000042D4000340D4000FC0F1 -:10065000D4000FA2CC800040CC400040CC400040F1 -:10066000CC4000407C40C000CCC00040CCC0000D5D -:1006700080000000D04000407C40C0007C41000071 -:10068000651400207D4D402C245800027D598020A7 -:100690007C41C000CD80004269980020CD8000429E -:1006A000CDC00042C023C00005E400027CA0800B46 -:1006B000266400107CA4800CCC800040CDC000409B -:1006C000CCC0004095C0000ECD00004009DC000108 -:1006D000C828000396800008CE800040C834001D62 -:1006E00097400000C834001D26A80008840002645A -:1006F000CC2B000099C0FFF709DC0001DC3A0000B8 -:10070000978000047C418000800001A325980002AE -:10071000A00000007D808000C818001D7C40C00043 -:1007200064D0000895800000C818001DCC1300009C -:10073000CC800040CCC0004080000000CC40004095 -:10074000C810001F7C40C000CC8000407CD1400C11 -:10075000CD4000400518000180000000CD8000223F -:100760007C40C0006450002084000264CC00006122 -:100770007CD0C02CC8200017C8D6000099400008C3 -:100780007C438000DF830000CFA0004F8400026420 -:10079000CC00006280000000D040007F8000026139 -:1007A000CC00006284000264CC000061C820001705 -:1007B0007C40C000C036FF00C810000DC0303FFFB5 -:1007C0007CF5400B7D51800B7D81800F9980000866 -:1007D0007CF3800BDF830000CFA0004F8400026415 -:1007E000CC00006280000000D040007F80000261E9 -:1007F000CC000062840002647C40C00028DC000859 -:1008000095C0001930DC00107C41000099C0000444 -:100810006454002080000209C91D00007D15002CD1 -:10082000C91E00007C4200007C4240007C418000E8 -:100830007DE5C00B7DE280079A80000E41AC00058B -:100840009AC000000AEC000130DC001099C00004DE -:10085000000000008000020CC91D00008000020C96 -:10086000C91E0000CC800040CCC00040D0400040F9 -:10087000C80C002594C0FDE3C8100008CD0000405E -:10088000D4000FC080000000D4000FA2D4000340A9 -:10089000D4000FC0D4000FA2CC800040D040004054 -:1008A0007C408000A00000007E82800BD40003C04A -:1008B000D4000FC0D4000FA2CC800040D040004034 -:1008C0007C408000A00000007E82800B7C40C00045 -:1008D00030D000060D10000699000007C81400155E -:1008E00099400005CC000052D4000340D4000FC052 -:1008F000D4000FA2CC800040CCC00040800000009B -:10090000D04000407C40C000CC4D0000DC3A0000EC -:100910009780FDBC04CC000180000243CC4D000058 -:100920007C40C0007C410000292400183264000192 -:100930009640000FCC8000407C4140007C4180000C -:100940007C41C000CCC00043CD00004331DC7FFFC0 -:10095000CDC00043CCC00040CD000040CD400040A1 -:10096000CD80004080000000CDC00040CCC00040E1 -:10097000CD00004080000000D0400040800000001A -:10098000D040007FCC00007F80000000CC00007FC2 -:10099000CC00007F88000000CC00007F0000000039 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C0000000302230004022B000500A000020003E1 -:100C10000006003C0007002700080192000900447C -:100C2000000A002D0010025F001700F1002201D819 -:100C3000002301E90026004C0027005F0020011B73 -:100C4000002800930029004F002A0084002B006533 -:100C5000002F008E003200D90034023300360075B8 -:100C60000039010B003C01FD003F00A0004102489B -:100C7000004401950048019E004901C6004A01D088 -:100C8000005502260056022E0060000A0061002A6C -:100C90000062003000630030006400300065003006 -:100CA0000066003000670030006800370069003FD0 -:100CB000006A0047006B0047006C0047006D00476A -:100CC000006E0047006F0047007000470073025F2E -:100CD000007B024100000005000000050000000547 -:100CE00000000005000000050000000500000005F0 -:100CF00000000005000000050000000500000005E0 -:100D000000000005000000050000000500000005CF -:100D100000000005000000050000000500000005BF -:100D200000000005000000050000000500000005AF -:100D3000000000050000000500000005000000059F -:00000001FF diff --git a/firmware/sb16/alaw_main.csp.ihex b/firmware/sb16/alaw_main.csp.ihex deleted file mode 100644 index 04502707c42afc62df17e92de354c2325583a5ff..0000000000000000000000000000000000000000 --- a/firmware/sb16/alaw_main.csp.ihex +++ /dev/null @@ -1,87 +0,0 @@ -:10000000001000440800004400B1004400610044B6 -:10001000085000440DF261A8440404190000404552 -:10002000404939AC5555718B500563800000063945 -:10003000FF2E2149FF0FD4492001090E2000718BAA -:10004000A801A8808801A880A8000080D200718B38 -:100050008800A880A804B3802007B3808803B180FB -:10006000C000095CC2010082A100718BCD0004199F -:100070002120718BCF0004190000B180C200041947 -:100080000040001408400424000034490C4000449F -:1000900044040439000040453200095C00000C397A -:1000A00000004045404009EFFF2009CF000463A154 -:1000B000500333800004A38000FFC28B00D004549F -:1000C00004E000C4200380C03000008800007A0AE9 -:1000D000D001008200600044C0000099006000442C -:1000E00000FFC28B20000080000D428B083200C44C -:1000F000000E428B00A200C4001E428B0CB200C452 -:10010000008E428B006200C4009E428B085200C4E5 -:1001100000BE428B085200C40004428B047200C42B -:100120000024428B00D200C40055428B006000C402 -:1001300000004045200179800030428B088200C4D5 -:10014000000040450000718B4001008000600044C9 -:10015000FF00E2AB00B200C40FF2A8A82000B188F3 -:10016000000041024DF20039C001008200600044ED -:100170000DF2A3A84DF2003900600044FF00E2AB8D -:1001800020000088000061024DF204190060004464 -:10019000FF00E2ABA0000088000061104DF20419DE -:1001A00000600044FF20E2AB60000088000071C0E6 -:1001B0004DF20419006000440000798000E20084E0 -:1001C0000303044904C20054006004640060004456 -:1001D0000000638000000619030004490060004429 -:1001E00020016380000006190020E28B0CF20084DD -:1001F000BE00518BC020003908010044EC00518B37 -:10020000C02000390002E28B042100843F00518BA2 -:10021000C2200039001100443D00518BC22000393A -:10022000E500718BCD0000390000B180C9200419B0 -:10023000CB200419C1200419C32004191000718BAC -:10024000C7200419DE00518BCF0000390001B180B6 -:10025000C4200419C6200419C8200419CA2004198E -:100260002000718BCC200419030004490060004475 -:10027000090461A8C10004190B0461A8CA0004198B -:10028000046000D40D00610A9040098F0001004510 -:100290000F00610A0040098F000100458200092E0D -:1002A000804009CF02006122432561224033008053 -:1002B0000848004420B1495C9200094E0203092E0F -:1002C0000000A302C00071C02000EB800004C28BBC -:1002D0002004618000047A02C00000820CC3084937 -:1002E000B001F3800000103920000C890C88084907 -:1002F0000300A81800001039BDFF628B20010080A8 -:10030000000063CB00007A024000015B2000008007 -:1003100000004ACB2000138020007A80E02100C03A -:10032000080008491041098EAEAE628B00046122BC -:1003300000030045220133802001A30200007A80DF -:10034000C00000820720400A08A3008440210080EA -:1003500040059310C7200039000040450720400A9F -:100360000C930084080000820C246150400100803E -:10037000C7200039000040450004638000000639B2 -:100380004201090E0220610A000100450C20600AAA -:1003900000C300840004B180000006390C6104D45D -:1003A000002471C0203333C0E001A38222037A020B -:1003B000C301A3822001338000007A80C201B350C0 -:1003C000CC20003900007180000800440C20600A35 -:1003D00000F300840004B180000006390C6104D4ED -:1003E000000071C000009310CC20003900080044C8 -:1003F000CC200039002000C0003071C0000800444B -:1004000020010080AEAE628B20013380000083802B -:1004100020007A8020A1495C8200096E804A098E02 -:10042000E001B3822004A38000007ACB2804EA1004 -:100430000C047A107000C08B00001039900300800B -:100440004000215B900061800C8A084900001C1963 -:100450004000085B08000849200200800300A8183B -:1004600000001419400021CB000041020000EB8085 -:10047000F2010082402133020820610AC4000419FD -:10048000C70000990200610A0C0A04140100610A05 -:100490000300480A00580454C30004190C580044CF -:1004A0000800C80A0C580454C80004190A00610A5C -:1004B0000900480A00C80454C90004190CC80044C3 -:1004C0000B00C80A0CC80454CB0004190400610ACC -:1004D0000600480A00D80454C60004190CD8004489 -:1004E0000500C80A0CD80454C50004190700610AA5 -:1004F0000C00480A000A0454CC0004190C0A0044F9 -:100500000E00C80A0C0A0454CE000419000040452D -:080510002010718B0842060067 -:00000001FF -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - */ diff --git a/firmware/sb16/ima_adpcm_capture.csp.ihex b/firmware/sb16/ima_adpcm_capture.csp.ihex deleted file mode 100644 index 9a50a58564ae83600f9ffdb84e702ae8ee4a0630..0000000000000000000000000000000000000000 --- a/firmware/sb16/ima_adpcm_capture.csp.ihex +++ /dev/null @@ -1,121 +0,0 @@ -:1000000000100044080000440070004408D0004480 -:1000100000F000440DF261A84404041900004045BA -:100020000004638000000639FF2E2149FF0CD449EB -:10003000404939AC5555718B5001B1800000718B2E -:10004000C2300419C0A00419C2A004198900718B20 -:10005000C83004197100718BCD000419CF00041948 -:100060008000718BCB2004192000718BC4200419EF -:100070004700518BC020003900006380C1A00419E3 -:100080009300014FCD300009CF3000090C4000141F -:1000900000600014000461A8020461A80C6004243C -:1000A000000034490850004444040439000040452D -:1000B0000830610A05B0E8180CC00454C8300419AF -:1000C000090400A80B0400A800004045090461A829 -:1000D000C10004190B0461A8CA0004190D00610ACB -:1000E000000100450F00610A0040098F0001004532 -:1000F000404009EFFF2009CF000463A15003338083 -:100100000004A38000FFC28B0C120454081200C428 -:10011000200380C03000008800007A0AD0010082ED -:1001200004500044C00000990450004400FFC28BFA -:1001300020000080000D428B044200C4000E428B60 -:10014000085200C4001E428B00E200C4008E428BA5 -:1001500008D200C4009E428B04F200C400BE428B51 -:1001600004F200C40004428B041100C40024428B3A -:100170000C6100C40055428B045000C4003F428B08 -:100180000C0100C400004045200179800030428B02 -:10019000046200C4000040450000718B40010080F3 -:1001A00004500044FF00E2AB08C200C40FF2A8A84C -:1001B0002000B188000041024DF20039C0010082E8 -:1001C000045000440DF2A3A84DF20039045000443D -:1001D000FF00E2AB20000088000061024DF204192C -:1001E00004500044FF00E2ABA00000880000611052 -:1001F0004DF2041904500044FF20E2AB6000008877 -:10020000000071C04DF204190450004400007A0A45 -:100210002001F08001A0410A001100C42001F080FB -:10022000C130041904500044000079800C4100845E -:100230008900718BC83004199700718BCD0000398B -:100240000001B1808000041982000419C120041942 -:10025000C3200419C2300419CD100419CF10041999 -:10026000B000718B84000419860004198000718B22 -:10027000CB2004199300014FCD300009CF30000985 -:100280000302044908410014045000440000638044 -:100290000000061903000449045000442001638053 -:1002A000000006190020E28B00C100844700518B3A -:1002B000C020003900006380C1A0041900E100449F -:1002C000BD00518BC02000390000B180C1A00419CD -:1002D00003000449045000440020610A0001004565 -:1002E0000230610A0C8300C40C780844045A0844A4 -:1002F000B200094F1042098E05B0E01804230084B3 -:100300000C01001108056110004908440048084428 -:10031000B200094F8000718BC00000820C013310C5 -:100320002801A31000017A808C0100800230610A4C -:10033000200004190C8300C405B0C818084300C489 -:100340000130C80A0C3800C4088800440C780844FE -:10035000045A08440000A318800004190B0461A883 -:10036000C3200039C33004190F10610ACA300419C0 -:10037000090441A8E1200039D100094F00046102BD -:10038000086300440330410A20000039A300094FEC -:100390000004610200480844088800440230610AF1 -:1003A000000800C40C780844045A0844B200090F3D -:1003B0001040098E0000685B2004B1800200615B80 -:1003C00088037A80AC01008005B0E01800D3008477 -:1003D0000049084400480844B200090F8000718BAE -:1003E000C00000820230610A000800C405B0C818CD -:1003F0000C1800C40130C80A0C3800C40888004436 -:100400000C780844000061182005B180000068CB1A -:10041000800004190D10610AC33004190B0441A8AF -:10042000090441A8E1200039083800440330410A9A -:100430002004B18000480844088800440000B180CE -:10044000C23004190CB800D40F30610A0D30C80A4C -:100450000CB800C49300014FE700016F0F30610A30 -:1004600020000088020061024104041902046102B4 -:1004700043040439CF3000092000094900590044E1 -:100480009300014FE700016F0D30610A2000618881 -:10049000C2000082C2030082CD3000092000094959 -:1004A0000F30610A0D30C80A0C5800840230610A0E -:1004B00005B0A818C2300419000000469040098F0A -:1004C0001204096E0300090E0001718220010080F0 -:1004D000000061CB8004B1800001E0600CD80414FE -:1004E0000001EB804000521B80007980C00171C286 -:1004F0002000C080080A0454C004A8828000721B37 -:10050000800000800001F0802000C0800C2A04548C -:10051000C004A8821000721B800000800001F080DF -:100520002000C080083A0454C004A8822000721B36 -:1005300080000080C003F0822000A0800001001134 -:100540004000C28B00AA00C40000E98005B0A818D2 -:100550000001A822D0010082F000E21B0620A80AB8 -:100560002D10610AD100092E0001A8020E10C80A40 -:100570000CBA04140E10610A044A00440C10C80A94 -:10058000044A04540C10610AD00100820010A8181B -:10059000A0000088000171820300090E9A0100602A -:1005A0003200092E00000046000171822001008007 -:1005B000000061CB8024B1C00031E0600CCA04149B -:1005C0000001EB804000521B80007980C00171C2A5 -:1005D0002000C08008DA0454C004A8828000721B86 -:1005E000800000800001F0802000C0800CFA0454DC -:1005F000C004A8821000721B800000800001F080FF -:100600002000C08008290454C004A8822000721B66 -:1006100080000080C003F0822000A0800001001153 -:100620004000C28B003900C40000E98005B0A81862 -:100630000001A822D0010082B000E21B0620A80A17 -:100640002F10610AF100092E0001A8020E10C80A3D -:100650000CA904140E10610A049900440C10C80A75 -:10066000049904540C10610AD00100820010A818EB -:10067000A0000088000171829F0100600000004618 -:10068000000033800000838020007A8020073380C0 -:100690000000838020047A80200100800000004652 -:1006A0000200610A041B04140100610A0300480AE5 -:1006B0000C790454C300041904C900440800C80A92 -:1006C00004C90454C80004190A00610A0900480A50 -:1006D0000CE90454C900041904D900440B00C80AE9 -:1006E00004D90454CB0004190400610A0600480A26 -:1006F0000CF90454C6000419040B00440500C80A90 -:10070000040B0454C50004190700610A0C00480AD0 -:100710000C2B0454CC000419041B00440E00C80A1E -:10072000041B0454CE000419000040459220718B34 -:04073000A6C5110049 -:00000001FF -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - */ diff --git a/firmware/sb16/ima_adpcm_init.csp.ihex b/firmware/sb16/ima_adpcm_init.csp.ihex deleted file mode 100644 index a899a9e743f4137475313c72489e9c564caf4b3a..0000000000000000000000000000000000000000 --- a/firmware/sb16/ima_adpcm_init.csp.ihex +++ /dev/null @@ -1,70 +0,0 @@ -:10000000001000440000404500004045000040450D -:1000100000004045AAAA718B440404190000404521 -:10002000FF6E2149FF0FD449404939AC5555718BBA -:100030005005B1806200190E2100718B880000808C -:10004000B000718B880000804000718B88000080B8 -:100050006000718B880000805000718B88000080E8 -:100060007000718B88000080C000718B8800008058 -:10007000E000718B88000080D000718B88000080C8 -:100080000200718B880000802200718B8800008044 -:100090003200718B88000080A200718B8800008084 -:1000A000B200718B880000806200718B8800008034 -:1000B000C200718B88000080F200718B8800008084 -:1000C0001100718B88000080A100718B8800008076 -:1000D0006100718B88000080E100718B88000080D6 -:1000E0001300718B88000080B300718B8800008042 -:1000F000C300718B880000801800718B880000801D -:100100006800718B880000800A00718B8800008075 -:100110004A00718B880000802900718B8800008064 -:100120007900718B880000809B00718B88000080B3 -:100130001400718B88000080F400718B88000080AF -:10014000E600718B88000080E500718B88000080DC -:10015000D700718B880000802E00718B8800008092 -:100160009D00718B88000080EF00718B88000080FB -:10017000B220718B880000803320718B8800008052 -:100180002A20718B880000803B20718B88000080C2 -:100190004620718B880000802C20718B88000080A5 -:1001A000DD20718B880000800110718B8800008039 -:1001B0009A10718B880000801610718B8800008067 -:1001C0008E10718B88000080C230718B8800008097 -:1001D000C930718B880000803C30718B88000080B2 -:1001E0008180718B88000080D480718B88000080B2 -:1001F00010A0718B8800008034A0718B8800008073 -:100200000290718B880000807590718B880000804F -:100210009AB0718B880000801240718B880000803A -:100220000D40718B880000803C60718B88000080DD -:10023000E750718B880000800E70718B8800008001 -:10024000FFC0718B88000080C8D0718B880000804F -:1002500057F0718B88000080C822718B8800008065 -:10026000B032718B88000080DD82718B8800008045 -:1002700090B2718B880000808A62718B8800008048 -:10028000CE72718B88000080A5D2718B88000080AF -:100290009721718B88000080A2A1718B880000805B -:1002A0005C41718B88000080FEC1718B88000080EA -:1002B0007A23718B880000807893718B880000808E -:1002C0006773718B880000801728718B880000800D -:1002D0008848718B88000080DBF8718B8800008073 -:1002E0002BBA718B88000080F109718B8800008027 -:1002F000DC69718B88000080198B718B880000800D -:10030000FFFB718B880000802000718B88000080CB -:100310005200718BC2000082FFFF718BC20000820D -:10032000C2000082C2000082C20000821000718BF5 -:10033000C20000828000718BC20000829000718B2D -:10034000C20000824000718BC2000082FFFF718BEF -:10035000C2000082C2000082C2000082C20000828D -:100360001000718BC20000828000718BC20000827D -:100370009000718BC20000824000718BC20000822D -:10038000FFFB718BC20000820004718BC2000082EF -:100390004A00718BC20000820000718BC200008293 -:1003A0000000718BC2000082C2000082C2300419BA -:1003B0001000094FC2010082C2010082C201008206 -:1003C000C2010082C2010082C2010082C201008219 -:1003D000C2010082C2010082C2010082C201008209 -:1003E000C2010082C20100820010718BC130041969 -:1003F0009300014FCD300009CF300009000034498F -:0804000000080044C85411007B -:00000001FF -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - */ diff --git a/firmware/sb16/ima_adpcm_playback.csp.ihex b/firmware/sb16/ima_adpcm_playback.csp.ihex deleted file mode 100644 index f09f18cf35e2a1fab97673b40e8b137cb19d14b7..0000000000000000000000000000000000000000 --- a/firmware/sb16/ima_adpcm_playback.csp.ihex +++ /dev/null @@ -1,122 +0,0 @@ -:1000000000100044080000440C50004400700044FC -:10001000047000440DF261A8440404190000404536 -:100020000004638000000639FF2E2149FF0DD449EA -:10003000404939AC5555718B5001B1800001B180F8 -:10004000C92004195100718BCD000419E420718B73 -:10005000CF0004198000718BCB2004191000718B24 -:10006000C42004196500518BC22000390000B18002 -:10007000C230041900006380C1A004199300014F2D -:10008000CD300009CF300009044000140C400014AA -:10009000000461A8020461A804600424000034493B -:1000A000005000444404043900004045000040452D -:1000B0000F00610A00010045404009EFFF2009CF11 -:1000C000000463A1500333800004A38000FFC28BAF -:1000D00008F004540CD000C4200380C03000008815 -:1000E00000007A0AD001008208500044C000009944 -:1000F0000850004400FFC28B20000080000D428B9E -:1001000000A200C4000E428B0C9200C4001E428B61 -:10011000046200C4008E428B0C5200C4009E428BCD -:1001200000C200C400BE428B00C200C40004428B67 -:1001300000F200C40024428B009100C40055428BA1 -:10014000085000C4003F428B08E200C40000404554 -:10015000200179800030428B009200C400004045AD -:100160000000718B4001008008500044FF00E2ABAA -:100170000C4200C40FF2A8A82000B1880000410280 -:100180004DF20039C0010082085000440DF2A3A8CE -:100190004DF2003908500044FF00E2AB2000008817 -:1001A000000061024DF2041908500044FF00E2AB68 -:1001B000A0000088000061104DF2041908500044AE -:1001C000FF20E2AB60000088000071C04DF204190E -:1001D0000850004400007A0A2001F08001A0410A82 -:1001E00004D200C42001F080C1300419085000443A -:1001F0000000798000A10084B500518BCF00003948 -:100200000001B180880004198A000419C82004196B -:10021000CA200419C2300419CD100419CF100419D2 -:10022000B000718B8C0004198E0004191000718BC2 -:10023000C42004199300014FCD300009CF300009CC -:100240000303044904810054085004640850004426 -:1002500000006380000006190300044908500044B0 -:1002600020016380000006190002E28B084100842F -:100270006500518BC220003900006380C1A00419C1 -:10028000086100442D00518BC22000390000B1806C -:10029000C1A0041903000449085000440220610A67 -:1002A000000100450230610A040300C405B0C8180B -:1002B000047100C4001300440079084400047980EC -:1002C000004900C4CA2004194A040419FF00E28B43 -:1002D0000CF90844CF1004190C2B08448E000419A3 -:1002E0000330610AC8200039480400390A30610A25 -:1002F0000CF90844CD1004190C2B08448C00041987 -:100300000CD908440C5A0044007908440004798050 -:10031000004900C4C3300419CA3000990CD90844FC -:10032000420A090E000133118C01A38000017A10EA -:100330008005B18005B0E01800930084007908447E -:1003400000047980004900C40C1B0844880004198B -:100350008A0000990CD90844420A090E8000718B6A -:10036000C004B1821000E00B004300840230610A37 -:100370000130C80A004300840000B180C230041973 -:100380000CA800440230610A00D300C405B0C818AC -:10039000046300C408F30044007908440004798031 -:1003A000004900C420000419FF00E28B0CF9084446 -:1003B000CD100419CF1004190C2B08448C0004191B -:1003C0008E0004190330610AC8200039CA200039A0 -:1003D000480400394A0400390CD908440C5A004436 -:1003E0000079084400047980004900C4C33004192E -:1003F0000CD90844420A090E05B0E0180018008420 -:100400000079084400047980004900C40C1B0844AA -:10041000800100800CD90844420A090E8000718BCB -:10042000C004B1821000E00B008800840230610A31 -:100430000130C80A008800840000B180C23004196D -:1004400000010011000FE28B000041CB8C00008006 -:10045000000048CB20007A8080010080820C096E69 -:100460000308090E804009CF000171C20008C21BB9 -:1004700004B800C42005A8802001F0800001C21B40 -:10048000044800C42005A8802001F0800002C21B9F -:10049000046800C42005A8802001F0802003A88003 -:1004A000000100110004C28B087800C40000E9803C -:1004B00005B0A81800004ACB2000A822D001008275 -:1004C00040010080C4000419B000E28B0620A80A95 -:1004D0002D10610AD108092E0001A8020CF9084468 -:1004E000CD1004190C2B08440308090E9A25B1609D -:1004F000A20E096E0300090F000171822001008025 -:10050000000061CB800100800300090F000171C26F -:100510000008C21B0C2A00C42005A8802001F0801E -:100520000001C21B0C1A00C42005A8802001F08025 -:100530000002C21B0C3A00C42005A8802001F080F4 -:100540002003A880000100110004C28B04AA00C48B -:100550000000E98005B0A81800004ACB2000A822BE -:10056000D001008240010080C7000419B000E28B76 -:100570000620A80A2F10610AF108092E0001A8021E -:100580000CF90844CF1004190C2B08449F35B160B6 -:100590000308090E0001718220010080000061CB78 -:1005A00080010080E420718B000100459040098F9C -:1005B0000005638000000639081904D49300014F38 -:1005C000E700016F0D30610A200461A8C2000082BB -:1005D000020461A8C2000082CD30000902000002BE -:1005E00002000002C0800009200009490F30610AA2 -:1005F0000D30C80A002900C40080C80A002900C4C0 -:100600000004B18000000639C920043900390044D3 -:1006100000046380000006390004B180C920043959 -:10062000003900440920230A00000619C9200419D2 -:10063000000040450200610A0CB904140400610A7C -:100640000600480A00A90454C60004190CA9004475 -:100650000500C80A0CA90454C50004190700610A62 -:100660000C00480A00B90454CC0004190CB9004429 -:100670000E00C80A0CB90454CE0004190C5A0044E8 -:10068000820D092E804009CF00DF718B8001008030 -:1006900002C1002203C1002200016580D2056582EB -:1006A00040210080D3030082403300800C5A004474 -:1006B0000F30610A0D30C80A08D900C49300014FF9 -:1006C000E700016F0F30610A20000088020061021C -:1006D00002000003CF3000092000094900046380B4 -:1006E00004D900440004B180000000460230610AD1 -:1006F00005B0A818C2300419000000460E10C80A40 -:100700000C0B04140E10610A042B00440C10C80AD0 -:10071000042B04540C10610A000000460010A818B5 -:10072000A0000088000171820000004600043380B0 -:100730000000838020047A802001338000008380C1 -:1007400020007A80200300800000004616CE1100B1 -:00000001FF -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - */ diff --git a/firmware/sb16/mulaw_main.csp.ihex b/firmware/sb16/mulaw_main.csp.ihex deleted file mode 100644 index b64b565f22963110db7b129c534803ff3e7853ec..0000000000000000000000000000000000000000 --- a/firmware/sb16/mulaw_main.csp.ihex +++ /dev/null @@ -1,84 +0,0 @@ -:10000000001000440800004400B1004400610044B6 -:10001000085000440DF261A8440404190000404552 -:10002000404939AC5555718B500563800000063945 -:10003000FF2E2149FF0FD4492001090E2000718BAA -:10004000A801A8808801A880A8000080D200718B38 -:100050008800A880A804B3802007B3808803B180FB -:10006000C000095CC2010082A100718BCD0004199F -:10007000A220718BCF0004190000B180C2000419C6 -:100080000040001408400424000034490C4000449F -:1000900044040439000040453200095C00000C397A -:1000A00000004045404009EFFF2009CF000463A154 -:1000B000500333800004A38000FFC28B00D004549F -:1000C00004E000C4200380C03000008800007A0AE9 -:1000D000D001008200600044C0000099006000442C -:1000E00000FFC28B20000080000D428B083200C44C -:1000F000000E428B00A200C4001E428B0CB200C452 -:10010000008E428B006200C4009E428B085200C4E5 -:1001100000BE428B085200C40004428B047200C42B -:100120000024428B00D200C40055428B006000C402 -:1001300000004045200179800030428B088200C4D5 -:10014000000040450000718B4001008000600044C9 -:10015000FF00E2AB00B200C40FF2A8A82000B188F3 -:10016000000041024DF20039C001008200600044ED -:100170000DF2A3A84DF2003900600044FF00E2AB8D -:1001800020000088000061024DF204190060004464 -:10019000FF00E2ABA0000088000061104DF20419DE -:1001A00000600044FF20E2AB60000088000071C0E6 -:1001B0004DF20419006000440000798000E20084E0 -:1001C0000303044908C20054006004640060004452 -:1001D0000000638000000619030004490060004429 -:1001E00020016380000006190020E28B0CF20084DD -:1001F0003E00518BC0200039080100446C00518B37 -:10020000C02000390002E28B04210084FD00518BE4 -:10021000C220003900110044FE00518BC220003979 -:10022000E500718BCD0000390000B180C9200419B0 -:10023000CB200419C1200419C32004191000718BAC -:10024000C72004195E00718BCF0000390000B18017 -:10025000C4200419C6200419C8200419CA2004198E -:100260002000718BCC200419030004490060004475 -:10027000090461A8C10004190B0461A8CA0004198B -:10028000046000D40D00610A9040098F0001004510 -:100290000F00610A0040098F000100458200092E0D -:1002A000804009CF02006122432561224033008053 -:1002B00008A800442031495C9200094E0203092E2F -:1002C0000000A302C00071C02000EB800004C28BBC -:1002D0002004618000047A02CB00A858B005F380A6 -:1002E0002004A81000001039B000E08B200100802D -:1002F000000063CB00007A024000015B2000008018 -:1003000000004ACB2000138020007A80E02100C04A -:10031000080008491041098EFFFF628B000461222A -:1003200000030045220133802001A30200007A80EF -:10033000C00000820720400A08830084402100801A -:1003400040059310C7200039000040450720400AAF -:100350000CA30084080000820C246150400100803E -:10036000C7200039000040450004638000000639C2 -:100370004201090E0220610A000100450C20600ABA -:10038000007300840004B180000006390C6104D4BD -:10039000002471C0203333C0E001A38222037A021B -:1003A000C301A3822001338000007A80C201B350D0 -:1003B000CC2000390000718000F300440C20600A5A -:1003C00000D300840004B180000006390C6104D41D -:1003D0000000B310CC200039000071C000F30044CD -:1003E000CC200039002071C0003071C000F30044FF -:1003F00020010080FFFF628B20013380000083809A -:1004000020007A8020E1095C8200092F804A098E51 -:10041000E001B3822004A38000007ACB0300A81877 -:10042000000010390804EA1008047A102000008047 -:10043000400021CB0C00E810000041020C00EB1042 -:10044000F2010082402133020820610AC40004192D -:10045000C70000990200610A0CE804140100610A57 -:100460000300480A00B80454C30004190CB800443F -:100470000800C80A0CB80454C80004190A00610A2C -:100480000900480A00680454C90004190C680044B3 -:100490000B00C80A0C680454CB0004190400610A5C -:1004A0000600480A00780454C60004190C78004479 -:1004B0000500C80A0C780454C50004190700610A35 -:1004C0000C00480A00E80454CC0004190CE800446D -:1004D0000E00C80A0CE80454CE0004190000404580 -:0804E0002010718B093F070099 -:00000001FF -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - */ diff --git a/firmware/sun/cassini.bin.ihex b/firmware/sun/cassini.bin.ihex deleted file mode 100644 index 5cd7ae70e71ffad379828fda8dd130ccb16c3b14..0000000000000000000000000000000000000000 --- a/firmware/sun/cassini.bin.ihex +++ /dev/null @@ -1,143 +0,0 @@ -:1000000000827E82090000000000008E8EFFCE82FA -:1000100025FF010FCE8426FF0111CE853DDFE58649 -:1000200039B78FF87EC3C2964784F38A009747CECC -:100030008233FF010F9646840C8104270B96468479 -:100040000C810827577E8425964784F38A049747B6 -:10005000CE8254FF010F9646840C81042638B612D6 -:1000600020842026037E8425967BD67CFE8F56BD79 -:10007000F7B6FE8F4EBDEC8EBDFAF7BDF728CE82E7 -:1000800082FF010F9646840C8104260AB612208452 -:100090002027B57E8425BDF71F7E841F964784F3F5 -:1000A0008A089747DEE1AD00CE82AFFF010F7E8464 -:1000B00025964185102606962385402706BDED002E -:1000C0007E83A2DE42BDEB8E9624840827037E83C6 -:1000D000DF967BD67CFE8F56BDF7B6FE8F50BDEC0B -:1000E0008EBDFAF78611C649BDE412CE82EFFF013C -:1000F0000F9646840C81002717C649BDE491240D54 -:10010000B612208520260CCE82C1FF010F7E8425E9 -:100110007E8416FE8F52BDEC8EBDFAF7866AC64904 -:10012000BDE412CE8327FF010F9646840C81002781 -:100130000AC649BDE49125067E84257E8416B6183C -:1001400070BB19702A0481AF2E19967BF62007FA2E -:100150002027C4388138270BF62007FA2027CB0840 -:100160007E82D3BDF7668674C649BDE412CE837124 -:10017000FF010F9646840C8108260AC649BDE4910A -:1001800025067E84257E8416BDF73E260EBDE50934 -:100190002606CE82C1FF010F7E8425FE8F54BDEC62 -:1001A0008EBDFAF7BDF733860FC651BDE412CE837C -:1001B000B2FF010F9646840C8108265CB61220849B -:1001C0003F813A271C9623854027037E8425C6510C -:1001D000BDE49125037E8425CE82C1FF010F7E847C -:1001E00025BDF8377C007ACE83EEFF010F7E842593 -:1001F0009646840C81082620962484082629B61861 -:1002000082BB1982B1013B2209B6122084378132A8 -:100210002715BDF8447E82C1BDF71FBDF844BDFC63 -:1002200029CE8225FF010F39964784FC8A00974723 -:10023000CE8434FF011196468403810227037E8514 -:100240001E964784FC8A029747DEE1AD008601B71F -:100250001251BDF714B6103184FDB71031BDF81E30 -:100260009681D682FE8F5ABDF7B6FE8F5CBDEC8EAE -:10027000BDFAF78608D600C51026028B20C651BDF0 -:10028000E412CE8486FF011196468403810227037F -:100290007E850FC651BDE49125037E851E9644855B -:1002A00010260AB61250BA013C851027A8BDF76681 -:1002B000CE84B7FF01117E851E96468403810226F7 -:1002C00050B612308403810127037E851E96448533 -:1002D000102613B61250BA013C85102609CE84535D -:1002E000FF01117E851EB610318A02B71031BD851F -:1002F0001FBDF8377C0080CE84FEFF01117E851E75 -:100300009646840381022609B612308403810127B0 -:100310000FBDF844BDF70BBDFC29CE8426FF0111AB -:1003200039D622C40FB61230BA12328404270D9681 -:100330002285042705CA107E853ACA20D72239862D -:1003400000978318CE1C00BDEB4696578501270207 -:100350004F3985022701397F8F7D8604B7120486C5 -:1003600008B712078610B7120C8607B71206B68FA9 -:100370007DB712708601BA1204B71204010101019F -:100380000101B6120484FE8A02B7120401010101C0 -:10039000010186FDB41204B71204B612008408816C -:1003A000082716B68F7D810C27088B04B78F7D7EBA -:1003B000856C860397407E896E8607B712065FF7C5 -:1003C0008F825FF78F7FF78F70F78F71F78F72F7DC -:1003D0008F73F78F74F78F75F78F76F78F77F78FA7 -:1003E00078F78F79F78F7AF78F7BB612048A10B778 -:1003F000120486E4B71270B71207F71205F7120954 -:100400008608BA1204B7120486F7B41204B71204AD -:10041000010101010101B61208277F8180260B86A8 -:1004200008CE8F79BD897B7E868E8140260B86041F -:10043000CE8F76BD897B7E868E8120260B8602CE6E -:100440008F73BD897B7E868E8110260B8601CE8FB1 -:1004500070BD897B7E868E8108260B8608CE8F79BB -:10046000BD897F7E868E8104260B8604CE8F76BD65 -:10047000897F7E868E8102260B8A02CE8F73BD898C -:100480007F7E868E810126088601CE8F70BD897F92 -:10049000B68F7F810F26037E8747B61209840381BA -:1004A0000327067C12097E85FEB6120684078107A3 -:1004B00027088B01B712067E86D5B68F82260A7C66 -:1004C0008F824FB712067E85C0B61206843F813FE9 -:1004D00027108B08B71206B6120984FCB712097EE2 -:1004E00085FECE8F7018CE8F84C60CBD896FCE8FDF -:1004F0008418CE8F70C60CBD896FD683C14F2D0373 -:100500007E8740B68F7F8107270F810B2715810DCE -:10051000271B810E27217E8740F78F7B8602B78FAE -:100520007A201CF78F788602B78F772012F78F75A5 -:100530008602B78F742008F78F728602B78F717E9C -:100540008747860497407E896ECE8F72BD89F7CE2D -:100550008F75BD89F7CE8F78BD89F7CE8F7BBD892A -:10056000F74FB78F7DB78F81B68F7227477C8F7D0E -:10057000B68F75273F7C8F7DB68F7827377C8F7D30 -:10058000B68F7B272F7F8F7D7C8F817A8F72271B81 -:100590007C8F7D7A8F7527167C8F7D7A8F782711D7 -:1005A0007C8F7D7A8F7B270C7E87837A8F757A8FFD -:1005B000787A8F7BCEC1FCF68F7D3AA600B7127099 -:1005C000B68F7226037E87FAB68F75260A18CE8FED -:1005D00073BD89D57E87FAB68F78260A18CE8F76B6 -:1005E000BD89D57E87FAB68F7B260A18CE8F79BD56 -:1005F00089D57E87FA860597407E8900B68F7581FA -:10060000072EF2F61206C4F81BB71206B68F7881D1 -:10061000072EE2484848F61206C4C71BB71206B6B2 -:100620008F7B81072ECFF61205C4F81BB712058603 -:1006300000F68F71BD89948601F68F74BD8994860A -:1006400002F68F77BD89948603F68F7ABD8994CEA2 -:100650008F70A60181012707810327037E8866A684 -:1006600000B88F818401260B8C8F792C0E08080826 -:100670007E8850B612048A40B71204B6120484FB76 -:1006800084EFB71204B6120736B68F7C4848B7120B -:10069000078601BA1204B7120401010101010186A3 -:1006A000FEB41204B712048602BA1204B71204860A -:1006B000FDB41204B7120432B71207B61200840850 -:1006C0008108270F7C82082607867697407E896EF0 -:1006D0007E86ECB68F7F810F273CBDE6C7B7120D33 -:1006E000BDE6CBB612048A20B71204CEFFFFB612C5 -:1006F00000810C26050926F6271CB6120484DFB7F4 -:100700001204968381072C057C0083200696838B38 -:100710000897837E85417F8F7E8680B7120C860185 -:10072000B78F7DB6120C847FB7120C8A80B7120C7B -:10073000860ABD8A06B6120A2A09B6120CBA8F7D3D -:10074000B7120CB68F7E8160271A8B20B78F7EB6CA -:10075000120C849FBA8F7EB7120CB68F7D48B78F6C -:100760007D7E8921B612048A20B71204BD8A0A4F01 -:1007700039A60018A7000818085A26F539366C0063 -:1007800032BA8F7FB78F7FB612098403A701B612E2 -:1007900006843FA70239368603B78F8032C1002610 -:1007A00006B78F7C7E89C9C1012718C102270CC1F9 -:1007B000032700F68F800505F78F80F68F800505EB -:1007C000F78F80F68F800505F78F80F68F8053F4C2 -:1007D00012071BB7120739CE8F70A60018E6001853 -:1007E000A700E700A60118E60118A701E701A60285 -:1007F00018E60218A702E70239A6008407E600C43B -:10080000385454541BA700394A26FD399622840FC8 -:1008100097228601B78F70B61207B78F71F6120C48 -:10082000C40FC80FF78F72F68F72B68F71840327CB -:10083000148101271C81022724F48F70272A962215 -:100840008A807E8A64F48F70271E96228A107E8AA0 -:1008500064F48F70271296228A207E8A64F48F7047 -:10086000270696228A409722748F71748F71788F31 -:1008700070B68F70851027AFD622C41058B612708C -:1008800081E4273681E1260C96228420441BD6225F -:10089000C4CF20235881C6260D9622844044441B91 -:1008A000D622C4AF2011588127260F962284804477 -:1008B00044441BD622C46F1B972239270C7C820626 -:0D08C000BDD9EDB682077E8AB97F82063968 -:00000001FF -/* firmware patch for NS_DP83065 */ diff --git a/firmware/tehuti/bdx.bin.ihex b/firmware/tehuti/bdx.bin.ihex deleted file mode 100644 index b029e4c85795ee18b0cd4926a0a11f1fc5b10afb..0000000000000000000000000000000000000000 --- a/firmware/tehuti/bdx.bin.ihex +++ /dev/null @@ -1,2678 +0,0 @@ -:1000000002000F00008071402D000000000000C0C1 -:1000100002000F00018071002D000000000080C070 -:1000200002000F00028071002D000000000000C1DE -:1000300002000F00038071002D000000000080C14D -:1000400002000F00048071002D000000000000C2BB -:1000500002000F00058071002D000000000080C22A -:1000600002000F00068071002D000000000000C398 -:1000700002000F00078071002D000000000080C307 -:1000800002000F00088071002D000000000000C475 -:1000900002000F00098071002D000000000080C4E4 -:1000A00002000F000A8071002D000000000000C552 -:1000B00002000F000B8071002D000000000080C5C1 -:1000C00002000F000C8071002D000000000000C62F -:1000D00002000F000D8071002D000000000080C69E -:1000E00002000F000E8071002D000000000000C70C -:1000F00002000F000F8071002D000000000080C77B -:1001000002000F00108071002D000000000000C8E8 -:1001100002000F00118071002D000000000080C857 -:1001200002000F00128071002D000000000000C9C5 -:1001300002000F00138071002D000000000080C934 -:1001400002000F00148071002D000000000000CAA2 -:1001500002000F00158071002D000000000080CA11 -:1001600002000F00168071002D000000000000CB7F -:1001700002000F00178071002D000000000080CBEE -:1001800002000F00188071002D000000000000CC5C -:1001900002000F00198071002D000000000080CCCB -:1001A00002000F001A8071002D000000000000CD39 -:1001B00002000F001B8071002D000000000080CDA8 -:1001C00002000F001C8071002D000000000000CE16 -:1001D00002000F001D8071002D000000000080CE85 -:1001E00002000F001E8071002D000000000000CFF3 -:1001F00002000F001F8071002D000000000080CF62 -:1002000002000F00208071002D000000000000D0CF -:1002100002000F00218071002D000000000080D03E -:1002200002000F00228071002D000000000000D1AC -:1002300002000F00238071002D000000000080D11B -:1002400002000F00248071002D000000000000D289 -:1002500002000F00258071002D000000000080D2F8 -:1002600002000F00268071002D000000000000D366 -:1002700002000F00278071002D000000000080D3D5 -:1002800002000F00288071002D000000000000D443 -:1002900002000F00298071002D000000000080D4B2 -:1002A00002000F002A8071002D000000000000D520 -:1002B00002000F002B8071002D000000000080D58F -:1002C00002000F002C8071002D000000000000D6FD -:1002D00002000F002D8071002D000000000080D66C -:1002E00002000F002E8071002D000000000000D7DA -:1002F00002000F002F8071002D000000000080D749 -:1003000002000F00308071002D000000000000D8B6 -:1003100002000F00318071002D000000000080D825 -:1003200002000F00328071002D000000000000D993 -:1003300002000F00338071002D000000000080D902 -:1003400002000F00348071002D000000000000DA70 -:1003500002000F00358071002D000000000080DADF -:1003600002000F00368071002D000000000000DB4D -:1003700002000F00378071002D000000000080DBBC -:1003800002000F00388071007B000000008060DDFB -:1003900002000F00398071002D000000000000DD18 -:1003A00002000F003A8071002D000000000080DB89 -:1003B00002000F003B8071002D000000000000DDF6 -:1003C00002000F003C8071002D000000000000DDE5 -:1003D00002000F003D8071000000000000000000DE -:1003E00002000F003E8071000000000000000000CD -:1003F00002000F003F8071000000000000000000BC -:1004000002000F00408071000000000000000000AA -:1004100002000F0041807100000000000000000099 -:1004200002000F0042807100000000000000000088 -:1004300002000F0043807100000000000000000077 -:1004400002000F0044807100000000000000000066 -:1004500002000F0045807100000000000000000055 -:1004600002000F0046807100000000000000000044 -:1004700002000F0047807100000000000000000033 -:1004800002000F0048807100000000000000000022 -:1004900002000F0049807100000000000000000011 -:1004A00002000F004A807100000000000000000000 -:1004B00002000F004B8071000000000000000000EF -:1004C00002000F004C8071000000000000000000DE -:1004D00002000F004D8071000000000000000000CD -:1004E00002000F004E8071000000000000000000BC -:1004F00002000F004F8071000000000000000000AB -:1005000002000F0050807100000000000000000099 -:1005100002000F0051807100000000000000000088 -:1005200002000F0052807100000000000000000077 -:1005300002000F0053807100000000000000000066 -:1005400002000F0054807100000000000000000055 -:1005500002000F0055807100000000000000000044 -:1005600002000F0056807100000000000000000033 -:1005700002000F0057807100000000000000000022 -:1005800002000F0058807100000000000000000011 -:1005900002000F0059807100000000000000000000 -:1005A00002000F005A8071000000000000000000EF -:1005B00002000F005B8071000000000000000000DE -:1005C00002000F005C8071000000000000000000CD -:1005D00002000F005D8071000000000000000000BC -:1005E00002000F005E8071000000000000000000AB -:1005F00002000F005F80710000000000000000009A -:1006000002000F0060807100000000000000000088 -:1006100002000F0061807100000000000000000077 -:1006200002000F0062807100000000000000000066 -:1006300002000F0063807100000000000000000055 -:1006400002000F00648071002D000000000000DB3C -:1006500002000F00658071003F000000040100DD12 -:1006600002000F00668071003F000000010018DDED -:1006700002000F0067807100690000007A3D00DD14 -:1006800002000F00688071003F000000040800DDD8 -:1006900002000F0069807100690000007A3D00DDF2 -:1006A00002000F006A8071003F000000043000DD8E -:1006B00002000F006B8071003F000000010018DD98 -:1006C00002000F006C807100690000007A3D00DDBF -:1006D00002000F006D8071003F000000040000DD8B -:1006E00002000F006E807100690000007A3D00DD9D -:1006F00002000F006F8071003F000000043D00DD2C -:1007000002000F00708071003F000000010018DD42 -:1007100002000F0071807100690000007A3D00DD69 -:1007200002000F00728071003F000000040700DD2E -:1007300002000F0073807100690000007A3D00DD47 -:1007400002000F00748071003F000000842800DD6B -:1007500002000F00758071003F000000010018DDED -:1007600002000F0076807100690000007A3D00DD14 -:1007700002000F00778071003F000000043700DDA9 -:1007800002000F0078807100690000007A3D00DDF2 -:1007900002000F00798071003F000000042900DD95 -:1007A00002000F007A8071003F000000010018DD98 -:1007B00002000F007B807100690000007A3D00DDBF -:1007C00002000F007C8071003F00000004AA04DDDD -:1007D00002000F007D807100690000007A3D00DD9D -:1007E00002000F007E8071003F000000042800DD41 -:1007F00002000F007F8071003F000000010018DD43 -:1008000002000F0080807100690000007A3D00DD69 -:1008100002000F00818071003F000000043100DD04 -:1008200002000F0082807100690000007A3D00DD47 -:1008300002000F00838071003F000000842B00DD68 -:1008400002000F00848071003F000000010018DDED -:1008500002000F0085807100690000007A3D00DD14 -:1008600002000F00868071003F00000004E401DDFB -:1008700002000F0087807100690000007A3D00DDF2 -:1008800002000F00888071003F000000840080D7C4 -:1008900002000F00898071003F000000010098D71E -:1008A00002000F008A80710059000000EF3780D7E6 -:1008B00002000F008B8071003D0000006F0080F788 -:1008C00002000F008C8071003D0000006F0080F777 -:1008D00002000F008D8071003D0000006F0080F766 -:1008E00002000F008E8071002D0000007F02D6D71D -:1008F00002000F008F807100180000008100FF17B8 -:1009000002000F00908071003D0000006F0080F732 -:1009100002000F00918071003D0000006F0080F721 -:1009200002000F00928071002D000000B800D8D79F -:1009300002000F0093807100180000008100EB1787 -:1009400002000F00948071003F000000042900DDC8 -:1009500002000F00958071003F000000010018DDCB -:1009600002000F0096807100690000007A3D00DDF2 -:1009700002000F00978071003F00000084AA04DD90 -:1009800002000F0098807100690000007A3D00DDD0 -:1009900002000F00998071003F000000042B00DD71 -:1009A00002000F009A8071003F000000010018DD76 -:1009B00002000F009B807100690000007A3D00DD9D -:1009C00002000F009C8071003F000000040000DD69 -:1009D00002000F009D807100690000007A3D00DD7B -:1009E00002000F009E8071003F000000842900DD9E -:1009F00002000F009F8071003F000000010018DD21 -:100A000002000F00A0807100690000007A3D00DD47 -:100A100002000F00A18071003F000000040000DD13 -:100A200002000F00A2807100690000007A3D00DD25 -:100A300002000F00A38071003F000000042A00DDC7 -:100A400002000F00A48071003F000000010018DDCB -:100A500002000F00A5807100690000007A3D00DDF2 -:100A600002000F00A68071003F000000849100DDAD -:100A700002000F00A7807100690000007A3D00DDD0 -:100A800002000F00A88071003F000000841980D68A -:100A900002000F00A98071003F000000010080D615 -:100AA00002000F00AA80710035000000ED0080D622 -:100AB00002000F00AB807100180000008100FF37BA -:100AC00002000F00AC8071003F000000042B00DD2D -:100AD00002000F00AD8071003F000000010018DD32 -:100AE00002000F00AE807100690000007A3D00DD59 -:100AF00002000F00AF8071003F000000040000DD25 -:100B000002000F00B0807100690000007A3D00DD36 -:100B100002000F00B18071003F000000842A00DD58 -:100B200002000F00B28071003F000000010018DDDC -:100B300002000F00B3807100690000007A3D00DD03 -:100B400002000F00B48071003F000000040000DDCF -:100B500002000F00B5807100690000007A3D00DDE1 -:100B600002000F00B68071003F000000840C80D6A8 -:100B700002000F00B78071003F000000010080D626 -:100B800002000F00B880710035000000ED0080D633 -:100B900002000F00B9807100180000008100FF37CB -:100BA00002000F00BA8071003F000000842A00DDBF -:100BB00002000F00BB8071003F000000010018DD43 -:100BC00002000F00BC807100690000007A3D00DD6A -:100BD00002000F00BD8071003F000000040000DD36 -:100BE00002000F00BE807100690000007A3D00DD48 -:100BF00002000F00BF8071003F000000840F80D60C -:100C000002000F00C08071003F000000010080D68C -:100C100002000F00C180710035000000ED0080D699 -:100C200002000F00C2807100180000008100FF3731 -:100C300002000F00C38071003F000000042A00DDA5 -:100C400002000F00C48071003F000000010018DDA9 -:100C500002000F00C5807100690000007A3D00DDD0 -:100C600002000F00C68071003F000000841100DD0B -:100C700002000F00C7807100690000007A3D00DDAE -:100C800002000F00C88071003F000000842800DDD2 -:100C900002000F00C98071003F000000010018DD54 -:100CA00002000F00CA807100690000007A3D00DD7B -:100CB00002000F00CB8071003F000000843700DD90 -:100CC00002000F00CC807100690000007A3D00DD59 -:100CD00002000F00CD8071002D000000000080D3C5 -:100CE00002000F00CE8071003F000000803700D26C -:100CF00002000F00CF8071003F000000040480D18B -:100D000002000F00D08071003F000000010084D17C -:100D100002000F00D180710069000000763B00DD09 -:100D200002000F00D280710069000000763B00DDF8 -:100D300002000F00D380710069000000763B00DDE7 -:100D400002000F00D48071003F00000084FF7FD1BB -:100D500002000F00D58071003F00000081FF7FD1AD -:100D600002000F00D680710069000000763B00DDB4 -:100D700002000F00D780710069000000763B00DDA3 -:100D800002000F00D880710069000000763B00DD92 -:100D900002000F00D980710069000000763B00DD81 -:100DA00002000F00DA80710069000000763B00DD70 -:100DB00002000F00DB80710069000000763B00DD5F -:100DC00002000F00DC8071003F000000840780D625 -:100DD00002000F00DD8071003F000000010080D69E -:100DE00002000F00DE80710035000000ED0080D6AB -:100DF00002000F00DF807100180000008100FF3743 -:100E000002000F00E080710049000000633B00DD3C -:100E100002000F00E180710059000000763B00DD08 -:100E200002000F00E28071003D0000006F0080F7BB -:100E300002000F00E38071003D0000006F0080F7AA -:100E400002000F00E48071003D0000006F0080F799 -:100E500002000F00E58071002D0000007F0206DD1A -:100E600002000F00E6807100180000007A3D7F1D2F -:100E700002000F00E780710045000000393100DDFD -:100E800002000F00E8807100940000003B310B006D -:100E900002000F00E9807100940000003D3109005C -:100EA00002000F00EA807100940000003F3107004B -:100EB00002000F00EB80710094000000763B0500FB -:100EC00002000F00EC807100090000007A3DEDC1C6 -:100ED00002000F00ED8071003F00000080B700D2DB -:100EE00002000F00EE8071003F000000842800DD4A -:100EF00002000F00EF8071003F000000010018DDCC -:100F000002000F00F080710069000000643200DD13 -:100F100002000F00F1807100690000007A3D00DDE1 -:100F200002000F00F28071003F000000840780D6AD -:100F300002000F00F38071003F000000010080D626 -:100F400002000F00F480710035000000ED0080D633 -:100F500002000F00F5807100180000008100FF37CB -:100F600002000F00F680710049000000633B00DDC5 -:100F700002000F00F780710059000000763B00DD91 -:100F800002000F00F88071003D0000006F0080F744 -:100F900002000F00F98071003D0000006F0080F733 -:100FA00002000F00FA8071003D0000006F0080F722 -:100FB00002000F00FB8071002D0000007F0206DDA3 -:100FC00002000F00FC807100180000007A3D7F1DB8 -:100FD00002000F00FD807100450000003A3100DD85 -:100FE00002000F00FE80710018000000763B2D1DEE -:100FF00002000F00FF807100450000003C3100DD61 -:1010000002000F000081710018000000763B131DE4 -:1010100002000F0001817100450000003E3100DD3B -:1010200002000F000281710018000000763B1B1DBA -:1010300002000F00038171003F000000043000DD5A -:1010400002000F00048171003F000000010018DD64 -:1010500002000F0005817100690000007A3D00DD8B -:1010600002000F00068171003F000000040100DD56 -:1010700002000F0007817100690000007A3D00DD69 -:1010800002000F0008817100090000007A3D2DC5A3 -:1010900002000F000981710029000000640001D2E4 -:1010A00002000F000A8171003F000000842800DD6B -:1010B00002000F000B8171003F000000010018DDED -:1010C00002000F000C81710069000000643200DD35 -:1010D00002000F000D817100690000007A3D00DD03 -:1010E00002000F000E817100090000007A3D29C244 -:1010F00002000F000F81710029000000640000D27F -:1011000002000F00108171003F000000842800DD04 -:1011100002000F00118171003F000000010018DD86 -:1011200002000F001281710069000000643200DDCE -:1011300002000F0013817100690000007A3D00DD9C -:1011400002000F001481710049000000633B00DDC4 -:1011500002000F001581710059000000763B00DD90 -:1011600002000F00168171003D0000006F0080F743 -:1011700002000F00178171003D0000006F0080F732 -:1011800002000F00188171003D0000006F0080F721 -:1011900002000F00198171002D0000007F0206DDA2 -:1011A00002000F001A817100180000007A3D7F1DB7 -:1011B00002000F001B817100450000003A3100DD84 -:1011C00002000F001C81710018000000763B0F1D0B -:1011D00002000F001D8171003F000000043000DD9F -:1011E00002000F001E8171003F000000010018DDA9 -:1011F00002000F001F817100690000007A3D00DDD0 -:1012000002000F00208171003F000000040100DD9A -:1012100002000F0021817100690000007A3D00DDAD -:1012200002000F0022817100090000007A3D2DC5E7 -:1012300002000F00238171002D000000820008D100 -:1012400002000F0024817100080000007A3DC323D2 -:1012500002000F0025817100490000000A3B00D602 -:1012600002000F00268171003F000000040000D33F -:1012700002000F00278171003F000000010004D32D -:1012800002000F00288171002F000000854081D6E8 -:1012900002000F00298171003F00000084FFFFD48D -:1012A00002000F002A8171003F000000810780D4F6 -:1012B00002000F002B8171003F00000084FFFFD16E -:1012C00002000F002C8171003F000000010080D15E -:1012D00002000F002D81710049000000663600DD1C -:1012E00002000F002E81710069000000763B00DDD6 -:1012F00002000F002F81710069000000763B00DDC5 -:1013000002000F003081710069000000763B00DDB3 -:1013100002000F003181710069000000693B00DDAF -:1013200002000F003281710069000000763B00DD91 -:1013300002000F003381710069000000763B00DD80 -:1013400002000F003481710069000000763B00DD6F -:1013500002000F003581710069000000693B00DD6B -:1013600002000F0036817100610000006C0400F67D -:1013700002000F003781710035000000ED0080D6BB -:1013800002000F00388171001800000081006B3DE1 -:1013900002000F0039817100490000008B0500D662 -:1013A00002000F003A8171002F000000060181D673 -:1013B00002000F003B8171002D000000000000D2F0 -:1013C00002000F003C81710021000000E40000D207 -:1013D00002000F003D8171003D0000006F0080F7AA -:1013E00002000F003E8171002D0000007F0106DD2C -:1013F00002000F003F817100180000007A3D7F1D40 -:1014000002000F0040817100490000006C3600D8D6 -:1014100002000F004181710069000000E73300D82D -:1014200002000F004281710069000000E73300D81C -:1014300002000F004381710069000000EF3700D8FF -:1014400002000F0044817100310000006C0100D6E1 -:1014500002000F00458171002D000000000000D146 -:1014600002000F004681710049000000E4337AD188 -:1014700002000F00478171002F000000620171D14E -:1014800002000F00488171002F000000620161D14D -:1014900002000F004981710049000000E33340D190 -:1014A00002000F004A8171003D0000006F0080F7CC -:1014B00002000F004B8171002D0000007F0106DD4E -:1014C00002000F004C817100180000007A3D7F1D62 -:1014D00002000F004D817100490000006C3600D8F9 -:1014E00002000F004E81710069000000E73300D850 -:1014F00002000F004F81710069000000623100D8C6 -:1015000002000F005081710069000000EF3700D821 -:1015100002000F0051817100310000006C0100D603 -:1015200002000F00528171003D0000006F0080F743 -:1015300002000F00538171002D0000007F0106DDC5 -:1015400002000F0054817100180000007A3D7F1DD9 -:1015500002000F0055817100490000006C3600D870 -:1015600002000F005681710069000000E73300D8C7 -:1015700002000F005781710069000000E73300D8B6 -:1015800002000F005881710069000000EF3700D899 -:1015900002000F0059817100310000006C0100D67B -:1015A00002000F005A8171002D000000000000D1E0 -:1015B00002000F005B8171002D000000E4076CD178 -:1015C00002000F005C81710049000000E33340D14C -:1015D00002000F005D8171003D0000006F0080F788 -:1015E00002000F005E8171002D0000007F0106DD0A -:1015F00002000F005F817100180000007A3D7F1D1E -:1016000002000F0060817100490000006C3600D8B4 -:1016100002000F006181710069000000E73300D80B -:1016200002000F006281710069000000623100D881 -:1016300002000F006381710069000000EF3700D8DD -:1016400002000F0064817100310000006C0100D6BF -:1016500002000F00658171003D0000006F0080F7FF -:1016600002000F00668171002D0000007F0106DD81 -:1016700002000F0067817100180000007A3D7F1D95 -:1016800002000F0068817100490000006C3600D82C -:1016900002000F006981710069000000E73300D883 -:1016A00002000F006A81710069000000E73300D872 -:1016B00002000F006B81710069000000EF3700D855 -:1016C00002000F006C817100310000006C0100D637 -:1016D00002000F006D8171002D000000000000D19C -:1016E00002000F006E81710049000000E43378D1E0 -:1016F00002000F006F8171002F000000620171D1A4 -:1017000002000F00708171002F000000620161D1A2 -:1017100002000F007181710049000000E33340D1E5 -:1017200002000F00728171003D0000006F0080F721 -:1017300002000F00738171002D0000007F0106DDA3 -:1017400002000F0074817100180000007A3D7F1DB7 -:1017500002000F0075817100490000006C3600D84E -:1017600002000F007681710069000000E73300D8A5 -:1017700002000F007781710069000000623100D81B -:1017800002000F007881710069000000EF3700D877 -:1017900002000F0079817100310000006C0100D659 -:1017A00002000F007A8171003D0000006F0080F799 -:1017B00002000F007B8171002D0000007F0106DD1B -:1017C00002000F007C817100180000007A3D7F1D2F -:1017D00002000F007D817100490000006C3600D8C6 -:1017E00002000F007E81710069000000E73300D81D -:1017F00002000F007F81710069000000E73300D80C -:1018000002000F008081710069000000EF3700D8EE -:1018100002000F0081817100310000006C0100D6D0 -:1018200002000F00828171002D000000000000D135 -:1018300002000F00838171002D000000E40768D1D1 -:1018400002000F008481710049000000E33340D1A1 -:1018500002000F00858171003D0000006F0080F7DD -:1018600002000F00868171002D0000007F0106DD5F -:1018700002000F0087817100180000007A3D7F1D73 -:1018800002000F0088817100490000006C3600D80A -:1018900002000F008981710069000000E73300D861 -:1018A00002000F008A81710069000000623100D8D7 -:1018B00002000F008B81710069000000EF3700D833 -:1018C00002000F008C817100310000006C0100D615 -:1018D00002000F008D81710035000000ED0080D600 -:1018E00002000F008E817100080000008100792243 -:1018F00002000F008F817100490000000C0600D625 -:1019000002000F00908171002F000000060181D6B7 -:1019100002000F00918171003F000000020080D49E -:1019200002000F00928171003F000000840080D40B -:1019300002000F00938171003F000000020100D5FA -:1019400002000F00948171003F000000840100D567 -:1019500002000F00958171003F000000020280D557 -:1019600002000F00968171003F000000040280D544 -:1019700002000F00978171003D0000006F0080F7AA -:1019800002000F00988171002D0000007F0106DD2C -:1019900002000F0099817100180000007A3D7F1D40 -:1019A00002000F009A817100490000006C3600D8D7 -:1019B00002000F009B81710069000000E93400D82B -:1019C00002000F009C817100690000006A3500D898 -:1019D00002000F009D81710069000000EF3700D800 -:1019E00002000F009E817100310000006C0100D6E2 -:1019F00002000F009F81710041000000EB3480D491 -:101A000002000F00A0817100410000006B3500D57D -:101A100002000F00A181710035000000ED0080D6AA -:101A200002000F00A2817100180000008100EB3756 -:101A300002000F00A3817100490000000D3B00D699 -:101A400002000F00A481710049000000073B80D60E -:101A500002000F00A58171002D000000000000D1E0 -:101A600002000F00A681710049000000663600DD0B -:101A700002000F00A781710069000000763B00DDC5 -:101A800002000F00A881710069000000763B00DDB4 -:101A900002000F00A981710069000000763B00DDA3 -:101AA00002000F00AA81710069000000763B00DD92 -:101AB00002000F00AB81710069000000763B00DD81 -:101AC00002000F00AC81710069000000763B00DD70 -:101AD00002000F00AD81710069000000763B00DD5F -:101AE00002000F00AE81710069000000763B00DD4E -:101AF00002000F00AF817100610000006C0400F66D -:101B000002000F00B081710035000000ED0080D6AA -:101B100002000F00B1817100180000008100EB3756 -:101B200002000F00B2817100490000000E3B00D698 -:101B300002000F00B381710049000000083B80D60D -:101B400002000F00B481710049000000093B80D5FC -:101B500002000F00B58171003D0000006F0080F7AA -:101B600002000F00B68171002D0000007F0106DD2C -:101B700002000F00B7817100180000007A3D7F1D40 -:101B800002000F00B8817100490000006C3600D8D7 -:101B900002000F00B981710069000000EB3500D828 -:101BA00002000F00BA81710069000000E73300D81D -:101BB00002000F00BB81710069000000EF3700D800 -:101BC00002000F00BC81710041000000EC0700D64C -:101BD00002000F00BD817100410000006B0880D53C -:101BE00002000F00BE81710035000000ED0080D6BC -:101BF00002000F00BF817100180000008100ED3766 -:101C000002000F00C08171003F00000080FFFFD480 -:101C100002000F00C18171003F000000040002D5E6 -:101C200002000F00C28171003F000000010018D5C2 -:101C300002000F00C3817100490000006A3B00DD13 -:101C400002000F00C481710069000000693B00DDE3 -:101C500002000F00C581710069000000693B00DDD2 -:101C600002000F00C681710021000000EA0000D5CB -:101C700002000F00C7817100490000006A3B0EDDC1 -:101C800002000F00C8817100350000007A0004D105 -:101C900002000F00C9817100180000008100F537B3 -:101CA00002000F00CA8171003F00000080FFFFD4D6 -:101CB00002000F00CB8171003F000000040004D53A -:101CC00002000F00CC8171003F000000010018D518 -:101CD00002000F00CD81710069000000693B00DD4A -:101CE00002000F00CE81710069000000693B00DD39 -:101CF00002000F00CF817100490000006A3B00DD47 -:101D000002000F00D081710051000000EA0000F5D0 -:101D100002000F00D18171003D0000006F0080F7CC -:101D200002000F00D28171003D0000006F0080F7BB -:101D300002000F00D3817100490000006A3B0EDDF4 -:101D400002000F00D4817100350000007A8004D1B8 -:101D500002000F00D5817100180000008100F537E6 -:101D600002000F00D68171003F000000047F7FC792 -:101D700002000F00D78171003F000000017F7FC784 -:101D800002000F00D88171003F000000004080D6A3 -:101D900002000F00D98171003F00000000C003D194 -:101DA00002000F00DA81710025000000E20020DE51 -:101DB00002000F00DB817100490000004E2780DE29 -:101DC00002000F00DC8171003D0000006F0080F711 -:101DD00002000F00DD8171003D0000006F0080F700 -:101DE00002000F00DE81710035000000E20000D12A -:101DF00002000F00DF81710035000000ED0080D689 -:101E000002000F00E0817100180000008100F5372A -:101E100002000F00E18171003F000000043000DD8E -:101E200002000F00E28171003F000000010018DD98 -:101E300002000F00E3817100690000003A1D00DD1F -:101E400002000F00E4817100690000007A3D00DDAE -:101E500002000F00E58171007D00000013A760C73C -:101E600002000F00E681710031000000410080C0D7 -:101E700002000F00E781710031000000480000C43B -:101E800002000F00E881710031000000450080C2AF -:101E900002000F00E9817100000000000000000056 -:101EA00002000F00EA817100000000000000000045 -:101EB00002000F00EB817100000000000000000034 -:101EC00002000F00EC817100000000000000000023 -:101ED00002000F00ED817100000000000000000012 -:101EE00002000F00EE817100000000000000000001 -:101EF00002000F00EF8171000000000000000000F0 -:101F000002000F00F08171000000000000000000DE -:101F100002000F00F18171000000000000000000CD -:101F200002000F00F28171000000000000000000BC -:101F300002000F00F38171000000000000000000AB -:101F400002000F00F48171002D000000000000DB92 -:101F500002000F00F58171003F000000043000DD39 -:101F600002000F00F68171003F000000010018DD43 -:101F700002000F00F7817100690000007A3D00DD6A -:101F800002000F00F88171003F000000040000DD36 -:101F900002000F00F9817100690000007A3D00DD48 -:101FA00002000F00FA8171002D000000000080D3B4 -:101FB00002000F00FB8171003F000000040400DDFF -:101FC00002000F00FC8171003F000000010018DDDD -:101FD00002000F00FD81710069000000140A00DD9D -:101FE00002000F00FE817100690000007A3D00DDF3 -:101FF00002000F00FF81710049000000943304D1FA -:1020000002000F00008271003F000000840400DD28 -:1020100002000F00018271003F000000010018DD86 -:1020200002000F000282710069000000623100DDD1 -:1020300002000F0003827100690000007A3D00DD9C -:1020400002000F00048271003F000000040500DD63 -:1020500002000F00058271003F000000010018DD42 -:1020600002000F000682710069000000950A00DD81 -:1020700002000F0007827100690000007A3D00DD58 -:1020800002000F000882710049000000953304D15E -:1020900002000F00098271003F000000840500DD8E -:1020A00002000F000A8271003F000000010018DDED -:1020B00002000F000B82710069000000623100DD38 -:1020C00002000F000C827100690000007A3D00DD03 -:1020D00002000F000D8271003F000000040600DDC9 -:1020E00002000F000E8271003F000000010018DDA9 -:1020F00002000F000F827100690000007A3D00DDD0 -:1021000002000F00108271003F000000840000DD1B -:1021100002000F0011827100690000007A3D00DDAD -:1021200002000F00128271003F000000040000DD79 -:1021300002000F00138271003F000000010018DD53 -:1021400002000F001482710069000000160B00DD10 -:1021500002000F0015827100690000007A3D00DD69 -:1021600002000F00168271003F000000041000DD25 -:1021700002000F00178271003F000000010018DD0F -:1021800002000F0018827100690000007A3D00DD36 -:1021900002000F00198271003F000000040000DD02 -:1021A00002000F001A827100690000007A3D00DD14 -:1021B00002000F001B8271003F000000841000DD50 -:1021C00002000F001C8271003F000000010018DDBA -:1021D00002000F001D827100690000007A3D00DDE1 -:1021E00002000F001E8271003F000000048001DD2C -:1021F00002000F001F827100690000007A3D00DDBF -:1022000002000F00208271003F000000041100DD79 -:1022100002000F00218271003F000000010018DD64 -:1022200002000F0022827100690000007A3D00DD8B -:1022300002000F00238271003F000000040000DD57 -:1022400002000F0024827100690000007A3D00DD69 -:1022500002000F00258271003F000000841100DDA4 -:1022600002000F00268271003F000000010018DD0F -:1022700002000F0027827100690000007A3D00DD36 -:1022800002000F00288271003F000000040016DDEC -:1022900002000F0029827100690000007A3D00DD14 -:1022A00002000F002A8271003F000000041200DDCE -:1022B00002000F002B8271003F000000010018DDBA -:1022C00002000F002C827100690000007A3D00DDE1 -:1022D00002000F002D8271003F000000040000DDAD -:1022E00002000F002E827100690000007A3D00DDBF -:1022F00002000F002F8271003F000000841200DDF9 -:1023000002000F00308271003F000000010018DD64 -:1023100002000F0031827100690000007A3D00DD8B -:1023200002000F00328271003F000000040000DD57 -:1023300002000F0033827100690000007A3D00DD69 -:1023400002000F00348271003F000000041300DD22 -:1023500002000F00358271003F000000010018DD0F -:1023600002000F0036827100690000007A3D00DD36 -:1023700002000F00378271003F000000040000DD02 -:1023800002000F0038827100690000007A3D00DD14 -:1023900002000F00398271003F000000841300DD4D -:1023A00002000F003A8271003F000000010018DDBA -:1023B00002000F003B827100690000007A3D00DDE1 -:1023C00002000F003C8271003F000000040005DDA8 -:1023D00002000F003D827100690000007A3D00DDBF -:1023E00002000F003E8271003F000000042000DD6B -:1023F00002000F003F8271003F000000010018DD65 -:1024000002000F0040827100690000007A3D00DD8B -:1024100002000F00418271003F000000040000DD57 -:1024200002000F0042827100690000007A3D00DD69 -:1024300002000F00438271003F000000842000DD95 -:1024400002000F00448271003F000000010018DD0F -:1024500002000F0045827100690000007A3D00DD36 -:1024600002000F00468271003F000000049001DD71 -:1024700002000F0047827100690000007A3D00DD14 -:1024800002000F00488271003F000000042100DDBF -:1024900002000F00498271003F000000010018DDBA -:1024A00002000F004A827100690000007A3D00DDE1 -:1024B00002000F004B8271003F000000840000DD2D -:1024C00002000F004C827100690000007A3D00DDBF -:1024D00002000F004D8271003F000000842100DDEA -:1024E00002000F004E8271003F000000010018DD65 -:1024F00002000F004F827100690000007A3D00DD8C -:1025000002000F00508271003F000000040000DD57 -:1025100002000F0051827100690000007A3D00DD69 -:1025200002000F00528271003F000000042200DD13 -:1025300002000F00538271003F000000010018DD0F -:1025400002000F0054827100690000007A3D00DD36 -:1025500002000F00558271003F000000840200DD80 -:1025600002000F0056827100690000007A3D00DD14 -:1025700002000F00578271003F000000842200DD3E -:1025800002000F00588271003F000000010018DDBA -:1025900002000F0059827100690000007A3D00DDE1 -:1025A00002000F005A8271003F000000040000DDAD -:1025B00002000F005B827100690000007A3D00DDBF -:1025C00002000F005C8271003F000000042300DD68 -:1025D00002000F005D8271003F000000010018DD65 -:1025E00002000F005E827100690000007A3D00DD8C -:1025F00002000F005F8271003F000000040000DD58 -:1026000002000F0060827100690000007A3D00DD69 -:1026100002000F00618271003F000000041800DD1D -:1026200002000F00628271003F000000010018DD0F -:1026300002000F006382710069000000970B00DD4B -:1026400002000F0064827100690000007A3D00DD25 -:1026500002000F006582710049000000973304D129 -:1026600002000F00668271003F000000841800DD48 -:1026700002000F00678271003F000000010018DDBA -:1026800002000F006882710069000000623100DD05 -:1026900002000F0069827100690000007A3D00DDD0 -:1026A00002000F006A8271003F000000041900DD83 -:1026B00002000F006B8271003F000000010018DD76 -:1026C00002000F006C82710069000000180C00DD30 -:1026D00002000F006D827100690000007A3D00DD8C -:1026E00002000F006E82710049000000983304D18F -:1026F00002000F006F8271003F000000841900DDAE -:1027000002000F00708271003F000000010018DD20 -:1027100002000F007182710069000000623100DD6B -:1027200002000F0072827100690000007A3D00DD36 -:1027300002000F00738271003F000000041A00DDE8 -:1027400002000F00748271003F000000010018DDDC -:1027500002000F0075827100690000007A3D00DD03 -:1027600002000F00768271003F000000040000DDCF -:1027700002000F0077827100690000007A3D00DDE1 -:1027800002000F00788271003F000000841A00DD13 -:1027900002000F00798271003F000000010018DD87 -:1027A00002000F007A82710069000000160B00DD44 -:1027B00002000F007B827100690000007A3D00DD9D -:1027C00002000F007C8271003F000000041C00DD4D -:1027D00002000F007D8271003F000000010018DD43 -:1027E00002000F007E82710069000000990C00DD7C -:1027F00002000F007F827100690000007A3D00DD59 -:1028000002000F00808271003F000000841C00DD88 -:1028100002000F00818271003F000000010018DDFE -:1028200002000F0082827100690000001A0D00DDB5 -:1028300002000F0083827100690000007A3D00DD14 -:1028400002000F00848271003F000000041D00DDC3 -:1028500002000F00858271003F000000010018DDBA -:1028600002000F0086827100690000009B0D00DDF0 -:1028700002000F0087827100690000007A3D00DDD0 -:1028800002000F0088827100490000009B3304D1D0 -:1028900002000F00898271003F000000841D00DDEE -:1028A00002000F008A8271003F000000010018DD65 -:1028B00002000F008B82710069000000623100DDB0 -:1028C00002000F008C827100690000007A3D00DD7B -:1028D00002000F008D8271003F000000041E00DD29 -:1028E00002000F008E8271003F000000010018DD21 -:1028F00002000F008F827100690000001C0E00DDD5 -:1029000002000F0090827100690000007A3D00DD36 -:1029100002000F00918271003F000000040100DD01 -:1029200002000F00928271003F000000010018DDDC -:1029300002000F0093827100690000007A3D00DD03 -:1029400002000F00948271003F000000040F00DDC0 -:1029500002000F0095827100690000007A3D00DDE1 -:1029600002000F00968271007D00000013A760C76F -:1029700002000F009782710031000000410080C00A -:1029800002000F009882710031000000480000C46E -:1029900002000F009982710031000000450080C2E2 -:1029A00002000F009A827100310000006D0080D695 -:1029B0000F000F0064007000000000000000000025 -:1029C00000000000400000000001000000040000C2 -:1029D000640000005400000000000000002400001B -:1029E0000028000000040000802800008001000092 -:1029F00003000000000000000000000000000000D4 -:102A0000510000007D01000008000000510000009E -:102A10005D00000000000000090000000050000000 -:102A200000000000000000000F000F00F401700023 -:102A30000000000000000000000000004000000056 -:102A400000010000000400006400000054000000C9 -:102A50000000000000240000002800000004000026 -:102A6000802800008001000003000000000000003A -:102A70000000000000000000510000007D01000087 -:102A800008000000510000005D0000000000000090 -:102A900009000000005000000000000000000000DD -:102AA00002000F00000070000100000000000000A4 -:102AB00002000F0000007000010000000000000094 -:102AC00002000F00008071002500000002000EDDF2 -:102AD00002000F000180710004000000763BD1016C -:102AE00002000F00028071002500000082000EDD50 -:102AF00002000F000380710004000000763B890291 -:102B000002000F00048071002500000002010EDDAC -:102B100002000F000580710004000000763B850272 -:102B200002000F00068071002500000082010EDD0A -:102B300002000F000780710004000000763BFD03D7 -:102B400002000F000880710009000000763B81CF71 -:102B500002000F000980710000000000000000006A -:102B600002000F000A807100000000000000000059 -:102B700002000F000B807100000000000000000048 -:102B800002000F000C807100000000000000000037 -:102B900002000F000D807100000000000000000026 -:102BA00002000F000E807100000000000000000015 -:102BB00002000F000F807100000000000000000004 -:102BC00002000F00108071000000000000000000F3 -:102BD00002000F00118071000000000000000000E2 -:102BE00002000F00128071000000000000000000D1 -:102BF00002000F00138071000000000000000000C0 -:102C000002000F00148071000000000000000000AE -:102C100002000F001580710000000000000000009D -:102C200002000F001680710000000000000000008C -:102C300002000F001780710000000000000000007B -:102C400002000F001880710000000000000000006A -:102C500002000F0019807100000000000000000059 -:102C600002000F001A807100000000000000000048 -:102C700002000F001B807100000000000000000037 -:102C800002000F001C807100000000000000000026 -:102C900002000F001D807100000000000000000015 -:102CA00002000F001E807100000000000000000004 -:102CB00002000F001F8071000000000000000000F3 -:102CC00002000F00208071000000000000000000E2 -:102CD00002000F00218071000000000000000000D1 -:102CE00002000F00228071000000000000000000C0 -:102CF00002000F00238071000000000000000000AF -:102D000002000F002480710000000000000000009D -:102D100002000F002580710000000000000000008C -:102D200002000F002680710000000000000000007B -:102D300002000F002780710000000000000000006A -:102D400002000F002880710049000000003B00C015 -:102D500002000F002980710049000000023B80C082 -:102D600002000F002A80710049000000033B00C1EF -:102D700002000F002B80710049000000043B80C15D -:102D800002000F002C80710029000000760060DF37 -:102D900002000F002D807100490000007D3B44DFE0 -:102DA00002000F002E80710079000000769060FD17 -:102DB00002000F002F8071003D0000006F0080F7BF -:102DC00002000F00308071003D0000006F0080F7AE -:102DD00002000F00318071003D0000006F0080F79D -:102DE00002000F00328071003D0000006F0080F78C -:102DF00002000F003380710000000000000000009E -:102E000002000F003480710000000000000000008C -:102E100002000F003580710000000000000000007B -:102E200002000F003680710000000000000000006A -:102E300002000F0037807100000000000000000059 -:102E400002000F0038807100000000000000000048 -:102E500002000F0039807100000000000000000037 -:102E600002000F003A807100000000000000000026 -:102E700002000F003B807100000000000000000015 -:102E800002000F003C807100000000000000000004 -:102E900002000F003D8071000000000000000000F3 -:102EA00002000F003E8071000000000000000000E2 -:102EB00002000F003F8071000000000000000000D1 -:102EC00002000F00408071000000000000000000C0 -:102ED00002000F00418071000000000000000000AF -:102EE00002000F004280710000000000000000009E -:102EF00002000F004380710000000000000000008D -:102F000002000F004480710000000000000000007B -:102F100002000F004580710000000000000000006A -:102F200002000F0046807100000000000000000059 -:102F300002000F0047807100000000000000000048 -:102F400002000F0048807100000000000000000037 -:102F500002000F0049807100000000000000000026 -:102F600002000F004A807100000000000000000015 -:102F700002000F004B807100000000000000000004 -:102F800002000F004C8071000000000000000000F3 -:102F900002000F004D8071000000000000000000E2 -:102FA00002000F004E8071000000000000000000D1 -:102FB00002000F004F8071000000000000000000C0 -:102FC00002000F00508071000000000000000000AF -:102FD00002000F005180710000000000000000009E -:102FE00002000F005280710000000000000000008D -:102FF00002000F005380710000000000000000007C -:1030000002000F005480710000000000000000006A -:1030100002000F0055807100000000000000000059 -:1030200002000F0056807100000000000000000048 -:1030300002000F0057807100000000000000000037 -:1030400002000F0058807100000000000000000026 -:1030500002000F0059807100000000000000000015 -:1030600002000F005A807100000000000000000004 -:1030700002000F005B8071000000000000000000F3 -:1030800002000F005C8071000000000000000000E2 -:1030900002000F005D8071000000000000000000D1 -:1030A00002000F005E8071000000000000000000C0 -:1030B00002000F005F8071000000000000000000AF -:1030C00002000F00608071003F000000030000DF7D -:1030D00002000F00618071002D000000810FE0DD13 -:1030E00002000F00628071003F000000830280DD5B -:1030F00002000F00638071002D000000800104DDDC -:1031000002000F00648071007D000000800015FD4A -:1031100002000F00658071007A000000763B2010ED -:1031200002000F00668071007A000000767B20307C -:1031300002000F006780710021000000600024D0B1 -:1031400002000F00688071003F000000040100DDF4 -:1031500002000F00698071003F000000810240DD25 -:1031600002000F006A8071007900000003BB31DDAE -:1031700002000F006B8071007900000004FB31DD5C -:1031800002000F006C8071007900000076BB31DD19 -:1031900002000F006D8071007900000076FB31DDC8 -:1031A00002000F006E80710079000000010121FD16 -:1031B00002000F006F8071007D00000081402BFD38 -:1031C00002000F0070807100400000000230003DDE -:1031D00002000F007180710048000000023B001DDA -:1031E00002000F007280710079000000767B21DD03 -:1031F00002000F00738071002D0000007F0504DDC8 -:1032000002000F007480710018000000763B7F3DC3 -:1032100002000F00758071003D0000006F0080F714 -:1032200002000F00768071003D0000006F0080F703 -:1032300002000F00778071003D0000006F0080F7F2 -:1032400002000F007880710021000000761F37E334 -:1032500002000F007980710049000000793B00DD19 -:1032600002000F007A8071007900000076BB21DD3A -:1032700002000F007B80710049000000793B00DDF7 -:1032800002000F007C8071007900000076BB21DD18 -:1032900002000F007D80710049000000793B00DDD5 -:1032A00002000F007E8071007900000076BB21DDF6 -:1032B00002000F007F80710079000000769060FDB1 -:1032C00002000F00808071007900000076FB21DD94 -:1032D00002000F00818071003F000000830000DFCA -:1032E00002000F00828071003D0000006F0080F737 -:1032F00002000F0083807100000000000000000049 -:1033000002000F0084807100000000000000000037 -:1033100002000F0085807100000000000000000026 -:1033200002000F0086807100000000000000000015 -:1033300002000F0087807100000000000000000004 -:1033400002000F00888071000000000000000000F3 -:1033500002000F00898071000000000000000000E2 -:1033600002000F008A8071000000000000000000D1 -:1033700002000F008B8071000000000000000000C0 -:1033800002000F008C8071000000000000000000AF -:1033900002000F008D80710000000000000000009E -:1033A00002000F008E80710000000000000000008D -:1033B00002000F008F80710000000000000000007C -:1033C00002000F009080710000000000000000006B -:1033D00002000F009180710000000000000000005A -:1033E00002000F0092807100000000000000000049 -:1033F00002000F0093807100000000000000000038 -:1034000002000F0094807100000000000000000026 -:1034100002000F0095807100000000000000000015 -:1034200002000F0096807100000000000000000004 -:1034300002000F00978071000000000000000000F3 -:1034400002000F00988071000000000000000000E2 -:1034500002000F00998071000000000000000000D1 -:1034600002000F009A8071000000000000000000C0 -:1034700002000F009B8071000000000000000000AF -:1034800002000F009C80710000000000000000009E -:1034900002000F009D80710000000000000000008D -:1034A00002000F009E80710000000000000000007C -:1034B00002000F009F80710000000000000000006B -:1034C00002000F00A08071002D000000030808D04A -:1034D00002000F00A18071000800000076FBB521FA -:1034E00002000F00A280710079000000810001DD60 -:1034F00002000F00A380710079000000028101DD4D -:1035000002000F00A48071007D000000838001FD97 -:1035100002000F00A580710079000000763B90D07A -:1035200002000F00A6807100490000007A3B58D0CD -:1035300002000F00A780710049000000003B04D288 -:1035400002000F00A88071003D000000030040DD74 -:1035500002000F00A9807100240000006402003204 -:1035600002000F00AA8071003D00000003F87FDD1B -:1035700002000F00AB807100290000007A0120D00A -:1035800002000F00AC807100490000000E3BA4D087 -:1035900002000F00AD8071002D000000FF4204DD2D -:1035A00002000F00AE80710018000000763B7F3DE6 -:1035B00002000F00AF8071002D000000820006DDC8 -:1035C00002000F00B080710038000000E001003000 -:1035D00002000F00B180710039000000600100D0CE -:1035E00002000F00B2807100790000007C3BB1D175 -:1035F00002000F00B38071002D000000E30FE0DD3A -:1036000002000F00B480710049000000E43080D057 -:1036100002000F00B5807100790000007C7B31DD75 -:1036200002000F00B6807100790000007C3B31DDA4 -:1036300002000F00B78071007D000000824037FD5E -:1036400002000F00B880710008000000763B7D0189 -:1036500002000F00B98071003D0000006F0080F78C -:1036600002000F00BA8071003D0000006F0080F77B -:1036700002000F00BB80710049000000870300DDDD -:1036800002000F00BC80710079000000080431DDE9 -:1036900002000F00BD807100790000007A7D31DDED -:1036A00002000F00BE807100490000007C3B00D387 -:1036B00002000F00BF807100790000007CBB81D345 -:1036C00002000F00C08071007F0000007CB201D1B9 -:1036D00002000F00C18071004800000064320051F8 -:1036E00002000F00C28071003D000000030040DDB9 -:1036F00002000F00C38071000800000062319501D4 -:1037000002000F00C480710021000000660600D393 -:1037100002000F00C580710020000000E700805308 -:1037200002000F00C68071003F000000000800DDAD -:1037300002000F00C78071007900000066B301DD50 -:1037400002000F00C880710079000000E7B301DDBE -:1037500002000F00C980710075000000628601F14F -:1037600002000F00CA8071007500000064B101D230 -:1037700002000F00CB80710078000000767B001DF6 -:1037800002000F00CC80710025000000E30100DD85 -:1037900002000F00CD807100080000006231B1010D -:1037A00002000F00CE8071003D0000006F0080F726 -:1037B00002000F00CF8071003D0000006F0080F715 -:1037C00002000F00D08071003D0000006F0080F704 -:1037D00002000F00D180710021000000639F37E3D9 -:1037E00002000F00D2807100490000007C3B00D332 -:1037F00002000F00D3807100790000007CBB81D3F0 -:1038000002000F00D48071007F0000007CB201D163 -:1038100002000F00D58071004800000064320051A2 -:1038200002000F00D68071007500000064B101D263 -:1038300002000F00D780710078000000767B001D29 -:1038400002000F00D88071003F000000040000DD7E -:1038500002000F00D98071007900000081C001DDF5 -:1038600002000F00DA80710079000000769060FDA0 -:1038700002000F00DB8071002D000000030808DD4E -:1038800002000F00DC8071007800000081C0013D63 -:1038900002000F00DD8071003D0000006F0080F726 -:1038A00002000F00DE807100000000000000000038 -:1038B00002000F00DF807100000000000000000027 -:1038C00002000F00E0807100000000000000000016 -:1038D00002000F00E1807100000000000000000005 -:1038E00002000F00E28071000000000000000000F4 -:1038F00002000F00E38071000000000000000000E3 -:1039000002000F00E48071000000000000000000D1 -:1039100002000F00E58071000000000000000000C0 -:1039200002000F00E68071000000000000000000AF -:1039300002000F00E780710000000000000000009E -:1039400002000F00E880710049000000033B8ED1A7 -:1039500002000F00E98071002F000000E30081D118 -:1039600002000F00EA8071003F000000031880D1C0 -:1039700002000F00EB80710049000000033B04D1FE -:1039800002000F00EC8071003F000000030280DDA8 -:1039900002000F00ED80710049000000023B04D2DC -:1039A00002000F00EE80710049000000003B84D24D -:1039B00002000F00EF80710025000000E20000DD32 -:1039C00002000F00F08071009400000062411300BB -:1039D00002000F00F18071009400000062430B00B0 -:1039E00002000F00F280710094000000E248150010 -:1039F00002000F00F38071009400000062491B0078 -:103A000002000F00F48071009400000076402F0047 -:103A100002000F00F5807100090000007A3D81CF9F -:103A200002000F00F68071001D000000E5802BFDF4 -:103A300002000F00F78071003000000063808331C6 -:103A400002000F00F88071003000000063808211D6 -:103A500002000F00F98071001D000000E58025FDC7 -:103A600002000F00FA807100300000006300833113 -:103A700002000F00FB807100300000006300821123 -:103A800002000F00FC8071002F000000E30081D1D4 -:103A900002000F00FD8071001D000000E58009FD9F -:103AA00002000F00FE8071003000000063D38331FC -:103AB00002000F00FF8071003000000063D283110C -:103AC00002000F00008171002F000000E30081D18F -:103AD00002000F00018171003F000000840180D6C8 -:103AE00002000F00028171003F000000010080D63B -:103AF00002000F000381710035000000ED0080D648 -:103B000002000F0004817100180000008100FF37DF -:103B100002000F000581710025000000640200D240 -:103B200002000F0006817100180000007AFD777D09 -:103B300002000F000781710049000000633B20DE96 -:103B400002000F000881710049000000793B80DE0F -:103B500002000F000981710021000000E30080D104 -:103B600002000F000A817100090000007A3D81CF38 -:103B700002000F000B81710049000000E33100DDFD -:103B800002000F000C81710069000000783B0EDD1F -:103B900002000F000D81710061000000763B00DD26 -:103BA00002000F000E8171003F000000840100DD63 -:103BB00002000F000F8171003F000000010000DDD6 -:103BC00002000F001081710035000000FA0000DDD6 -:103BD00002000F001181710018000000763B7F3B4E -:103BE00002000F00128171003D0000006F0080F79D -:103BF00002000F00138171003D0000006F0080F78C -:103C000002000F00148171003D0000006F0080F77A -:103C100002000F001581710021000000E30080D137 -:103C200002000F001681710069000000793B04DD7D -:103C300002000F001781710061000000E30080F1B5 -:103C400002000F00188171003F000000840180D63F -:103C500002000F00198171003F000000010080D6B2 -:103C600002000F001A81710035000000ED0080D6BF -:103C700002000F001B817100180000008100FF3757 -:103C800002000F001C81710025000000640200D2B8 -:103C900002000F001D8171009800000076BB5D607E -:103CA00002000F001E817100090000007A3D81CFE3 -:103CB00002000F001F8171000000000000000000E2 -:103CC00002000F00208171000000000000000000D1 -:103CD00002000F00218171000000000000000000C0 -:103CE00002000F00228171000000000000000000AF -:103CF00002000F002381710000000000000000009E -:103D000002000F002481710000000000000000008C -:103D100002000F002581710000000000000000007B -:103D200002000F002681710000000000000000006A -:103D300002000F0027817100000000000000000059 -:103D400002000F0028817100000000000000000048 -:103D500002000F0029817100000000000000000037 -:103D600002000F002A817100000000000000000026 -:103D700002000F002B817100000000000000000015 -:103D800002000F002C817100000000000000000004 -:103D900002000F002D8171000000000000000000F3 -:103DA00002000F002E8171000000000000000000E2 -:103DB00002000F002F8171000000000000000000D1 -:103DC00002000F00308171000000000000000000C0 -:103DD00002000F00318171000000000000000000AF -:103DE00002000F003281710000000000000000009E -:103DF00002000F003381710000000000000000008D -:103E000002000F003481710000000000000000007B -:103E100002000F003581710000000000000000006A -:103E200002000F0036817100000000000000000059 -:103E300002000F0037817100000000000000000048 -:103E400002000F0038817100000000000000000037 -:103E500002000F0039817100000000000000000026 -:103E600002000F003A817100000000000000000015 -:103E700002000F003B817100000000000000000004 -:103E800002000F003C8171000000000000000000F3 -:103E900002000F003D8171000000000000000000E2 -:103EA00002000F003E8171000000000000000000D1 -:103EB00002000F003F8171000000000000000000C0 -:103EC00002000F004081710049000000013B08D44E -:103ED00002000F0041817100090000007A3D8BC291 -:103EE00002000F00428171003F000000800300D4F7 -:103EF00002000F0043817100090000007A3D8BC26F -:103F000002000F004481710049000000033B0ED401 -:103F100002000F00458171003F000000000042D602 -:103F200002000F00468171002F000000804081D206 -:103F300002000F00478171002D000000650384D24C -:103F400002000F00488171003F000000800080D611 -:103F500002000F00498171003F000000040004DDF1 -:103F600002000F004A8171003F000000010018DDCF -:103F700002000F004B817100690000006D3B00DD05 -:103F800002000F004C817100690000006D3B00DDF4 -:103F900002000F004D8171003100000065D203D393 -:103FA00002000F004E81710049000000663B40DEB8 -:103FB00002000F004F8171003F000000840180D695 -:103FC00002000F00508171003F000000010080D608 -:103FD00002000F005181710035000000ED0080D615 -:103FE00002000F0052817100180000008100FF37AD -:103FF00002000F0053817100490000007E3B80D514 -:1040000002000F005481710021000000E60040DE34 -:1040100002000F00558171003F000000840180D62E -:1040200002000F00568171003F000000010080D6A1 -:1040300002000F005781710035000000ED0080D6AE -:1040400002000F0058817100180000008100FF3746 -:1040500002000F0059817100490000007E3B00D52D -:1040600002000F005A81710079000000763B01DDEB -:1040700002000F005B8171002D0000007F4004DD15 -:1040800002000F005C81710018000000763B7F3D4C -:1040900002000F005D8171007900000076BB01DD38 -:1040A00002000F005E81710075000000E88001FDD4 -:1040B00002000F005F81710094000000684115004C -:1040C00002000F006081710094000000E8442500A8 -:1040D00002000F006181710094000000E84123009C -:1040E00002000F0062817100940000006845170013 -:1040F00002000F0063817100940000006842150007 -:1041000002000F006481710094000000E842270063 -:1041100002000F00658171009400000068432D00CB -:1041200002000F00668171009400000068442D00B9 -:1041300002000F006781710094000000E843330023 -:1041400002000F006881710004000000763B9703B5 -:1041500002000F00698171000D00000065C10DE3D0 -:1041600002000F006A817100300000007600033207 -:1041700002000F006B817100300000007600021217 -:1041800002000F006C8171003F000000000080D42D -:1041900002000F006D8171003F000000008080D19F -:1041A00002000F006E8171000D00000065C13FE349 -:1041B00002000F006F817100300000007660043251 -:1041C00002000F0070817100300000007640041280 -:1041D00002000F00718171003F000000008082D456 -:1041E00002000F00728171003F000000008080D14A -:1041F00002000F00738171000D00000065C13FE3F4 -:1042000002000F007481710030000000762004323B -:1042100002000F007581710030000000760004126A -:1042200002000F00768171003F000000000082D480 -:1042300002000F00778171000D00000065C163E38B -:1042400002000F00788171003000000076200332F8 -:1042500002000F0079817100300000007600031227 -:1042600002000F007A8171003F000000000083D43B -:1042700002000F007B81710049000000763B80D274 -:1042800002000F007C8171000D00000065C10DE38C -:1042900002000F007D817100300000007680033243 -:1042A00002000F007E817100300000007680021253 -:1042B00002000F007F8171003F000000000081D4E8 -:1042C00002000F00808171003F000000000002D654 -:1042D00002000F00818171003F000000000081D1C9 -:1042E00002000F00828171000D00000065C13FE3F4 -:1042F00002000F008381710030000000762004323C -:1043000002000F008481710030000000760004126A -:1043100002000F00858171003F000000000082D480 -:1043200002000F008681710041000000EB3480D450 -:1043300002000F0087817100790000006ABB01DD77 -:1043400002000F00888171007900000076BB01DD5A -:1043500002000F00898171003F000000031800D2A5 -:1043600002000F008A8171003F000000000081D12F -:1043700002000F008B81710075000000638001FD59 -:1043800002000F008C81710098000000643B69807E -:1043900002000F008D81710051000000E40000F266 -:1043A00002000F008E8171003F000000840180D662 -:1043B00002000F008F8171003F000000010080D6D5 -:1043C00002000F009081710035000000ED0080D6E2 -:1043D00002000F0091817100180000008100FF377A -:1043E00002000F00928171002D0000007F4004DD6B -:1043F00002000F009381710018000000763B7F3DA2 -:1044000002000F009481710049000000383BC0D3C6 -:1044100002000F009581710049000000643B00DD3F -:1044200002000F009681710051000000E40000F2CC -:1044300002000F00978171003F000000840180D6C8 -:1044400002000F00988171003F000000010080D63B -:1044500002000F009981710035000000ED0080D648 -:1044600002000F009A817100180000008100FF37E0 -:1044700002000F009B81710049000000383BA0D36F -:1044800002000F009C8171001900000076BB61DD05 -:1044900002000F009D81710049000000673B00DDB4 -:1044A00002000F009E81710075000000638281F19F -:1044B00002000F009F81710041000000EB3480D4A6 -:1044C00002000F00A0817100790000006ABB01DDCD -:1044D00002000F00A18171007900000076BB01DDB0 -:1044E00002000F00A28171003F000000031800D2FB -:1044F00002000F00A38171003F000000008080D106 -:1045000002000F00A481710075000000638001FDAE -:1045100002000F00A581710098000000643B378005 -:1045200002000F00A681710051000000E40000F2BB -:1045300002000F00A78171003F000000840180D6B7 -:1045400002000F00A88171003F000000010080D62A -:1045500002000F00A981710035000000ED0080D637 -:1045600002000F00AA817100180000008100FF37CF -:1045700002000F00AB8171002D0000007F4004DDC0 -:1045800002000F00AC81710018000000763B7F3DF7 -:1045900002000F00AD81710049000000383B80D35C -:1045A00002000F00AE8171001900000076BB6FDDC4 -:1045B00002000F00AF81710049000000673B00DD81 -:1045C00002000F00B081710075000000638281F16C -:1045D00002000F00B181710041000000EB3480D473 -:1045E00002000F00B2817100790000006ABB01DD9A -:1045F00002000F00B38171007900000063BB01DD90 -:1046000002000F00B481710075000000638001FD9D -:1046100002000F00B581710098000000643B178014 -:1046200002000F00B681710049000000643B40DECB -:1046300002000F00B78171003F000000840180D6A6 -:1046400002000F00B88171003F000000010080D619 -:1046500002000F00B981710035000000ED0080D626 -:1046600002000F00BA817100180000008100FF37BE -:1046700002000F00BB8171002D0000007F4004DDAF -:1046800002000F00BC81710018000000763B7F3DE6 -:1046900002000F00BD81710021000000E40000D283 -:1046A00002000F00BE817100190000007E7BEFD375 -:1046B00002000F00BF81710075000000638281F16C -:1046C00002000F00C08171003F000000000080D692 -:1046D00002000F00C18171003F000000040004DDF2 -:1046E00002000F00C28171003F000000010018DDD0 -:1046F00002000F00C3817100690000006D3B00DD06 -:1047000002000F00C4817100690000006D3B00DDF4 -:1047100002000F00C58171003F000000000000DDB5 -:1047200002000F00C68171002D000000800154DDE1 -:1047300002000F00C7817100790000007680E0F36D -:1047400002000F00C8817100490000007A3600D6CF -:1047500002000F00C98171007900000076FB01DDC5 -:1047600002000F00CA8171003D0000006F0080F759 -:1047700002000F00CB81710049000000033B00DD07 -:1047800002000F00CC81710059000000763B00FD53 -:1047900002000F00CD8171003F000000031C80DD8E -:1047A00002000F00CE8171003D0000006F0080F715 -:1047B00002000F00CF8171003D0000006F0080F704 -:1047C00002000F00D08171003D0000006F0080F7F3 -:1047D00002000F00D18171002D0000007F0206DD74 -:1047E00002000F00D2817100180000007A3D7F1D89 -:1047F00002000F00D3817100310000006B8883D468 -:1048000002000F00D4817100790000006ABB01DD55 -:1048100002000F00D581710079000000769081F1CF -:1048200002000F00D681710075000000638001FD59 -:1048300002000F00D78171009800000076BB538002 -:1048400002000F00D881710019000000797B7FDD24 -:1048500002000F00D981710075000000638281F1B0 -:1048600002000F00DA81710000000000000000006B -:1048700002000F00DB81710000000000000000005A -:1048800002000F00DC817100000000000000000049 -:1048900002000F00DD817100000000000000000038 -:1048A00002000F00DE817100000000000000000027 -:1048B00002000F00DF817100000000000000000016 -:1048C00002000F00E0817100000000000000000005 -:1048D00002000F00E18171000000000000000000F4 -:1048E00002000F00E28171000000000000000000E3 -:1048F00002000F00E38171000000000000000000D2 -:1049000002000F00E48171000000000000000000C0 -:1049100002000F00E58171000000000000000000AF -:1049200002000F00E681710000000000000000009E -:1049300002000F00E781710000000000000000008D -:1049400002000F00E881710000000000000000007C -:1049500002000F00E981710000000000000000006B -:1049600002000F00EA81710000000000000000005A -:1049700002000F00EB817100000000000000000049 -:1049800002000F00EC817100000000000000000038 -:1049900002000F00ED817100000000000000000027 -:1049A00002000F00EE817100000000000000000016 -:1049B00002000F00EF817100000000000000000005 -:1049C00002000F00F08171000000000000000000F4 -:1049D00002000F00F18171000000000000000000E3 -:1049E00002000F00F28171000000000000000000D2 -:1049F00002000F00F38171000000000000000000C1 -:104A000002000F00F48171000000000000000000AF -:104A100002000F00F581710000000000000000009E -:104A200002000F00F681710000000000000000008D -:104A300002000F00F781710000000000000000007C -:104A400002000F00F881710000000000000000006B -:104A500002000F00F981710000000000000000005A -:104A600002000F00FA817100000000000000000049 -:104A700002000F00FB817100000000000000000038 -:104A800002000F00FC817100000000000000000027 -:104A900002000F00FD817100000000000000000016 -:104AA00002000F00FE8171003F000000030280DD64 -:104AB00002000F00FF81710049000000023B84D119 -:104AC00002000F000082710049000000033B00DD7E -:104AD00002000F0001827100690000007A3B00DDD6 -:104AE00002000F000282710049000000793B00DDE6 -:104AF00002000F000382710065000000630280F174 -:104B000002000F000482710018000000763B7D7DDA -:104B100002000F0005827100090000007A3D81CF7C -:104B200002000F000682710000000000000000007B -:104B300002000F000782710000000000000000006A -:104B400002000F0008827100000000000000000059 -:104B500002000F0009827100000000000000000048 -:104B600002000F000A827100000000000000000037 -:104B700002000F000B827100000000000000000026 -:104B800002000F000C827100000000000000000015 -:104B900002000F000D827100000000000000000004 -:104BA00002000F000E8271000000000000000000F3 -:104BB00002000F000F8271000000000000000000E2 -:104BC00002000F00108271000000000000000000D1 -:104BD00002000F00118271000000000000000000C0 -:104BE00002000F00128271000000000000000000AF -:104BF00002000F001382710000000000000000009E -:104C000002000F001482710000000000000000008C -:104C100002000F001582710000000000000000007B -:104C200002000F001682710000000000000000006A -:104C300002000F0017827100000000000000000059 -:104C400002000F0018827100000000000000000048 -:104C500002000F0019827100000000000000000037 -:104C600002000F001A827100000000000000000026 -:104C700002000F001B827100000000000000000015 -:104C800002000F001C827100000000000000000004 -:104C900002000F001D8271000000000000000000F3 -:104CA00002000F001E8271000000000000000000E2 -:104CB00002000F001F8271000000000000000000D1 -:104CC00002000F00208271000000000000000000C0 -:104CD00002000F00218271000000000000000000AF -:104CE00002000F002282710000000000000000009E -:104CF00002000F002382710000000000000000008D -:104D000002000F002482710000000000000000007B -:104D100002000F002582710000000000000000006A -:104D200002000F0026827100000000000000000059 -:104D300002000F0027827100000000000000000048 -:104D400002000F0028827100000000000000000037 -:104D500002000F0029827100000000000000000026 -:104D600002000F002A827100000000000000000015 -:104D700002000F002B827100000000000000000004 -:104D800002000F002C8271000000000000000000F3 -:104D900002000F002D8271000000000000000000E2 -:104DA00002000F002E8271000000000000000000D1 -:104DB00002000F002F8271000000000000000000C0 -:104DC00002000F00308271000000000000000000AF -:104DD00002000F003182710000000000000000009E -:104DE00002000F003282710000000000000000008D -:104DF00002000F003382710000000000000000007C -:104E000002000F003482710000000000000000006A -:104E100002000F0035827100000000000000000059 -:104E200002000F0036827100000000000000000048 -:104E300002000F0037827100000000000000000037 -:104E400002000F0038827100000000000000000026 -:104E500002000F0039827100000000000000000015 -:104E600002000F003A827100000000000000000004 -:104E700002000F003B8271000000000000000000F3 -:104E800002000F003C8271000000000000000000E2 -:104E900002000F003D8271000000000000000000D1 -:104EA00002000F003E8271000000000000000000C0 -:104EB00002000F003F8271000000000000000000AF -:104EC00002000F004082710000000000000000009E -:104ED00002000F004182710000000000000000008D -:104EE00002000F004282710000000000000000007C -:104EF00002000F004382710000000000000000006B -:104F000002000F0044827100000000000000000059 -:104F100002000F0045827100000000000000000048 -:104F200002000F0046827100000000000000000037 -:104F300002000F0047827100000000000000000026 -:104F400002000F0048827100000000000000000015 -:104F500002000F0049827100000000000000000004 -:104F600002000F004A8271000000000000000000F3 -:104F700002000F004B8271000000000000000000E2 -:104F800002000F004C8271000000000000000000D1 -:104F900002000F004D8271000000000000000000C0 -:104FA00002000F004E8271000000000000000000AF -:104FB00002000F004F82710000000000000000009E -:104FC00002000F005082710000000000000000008D -:104FD00002000F005182710000000000000000007C -:104FE00002000F005282710000000000000000006B -:104FF00002000F005382710000000000000000005A -:1050000002000F0054827100000000000000000048 -:1050100002000F0055827100000000000000000037 -:1050200002000F0056827100000000000000000026 -:1050300002000F0057827100000000000000000015 -:1050400002000F0058827100000000000000000004 -:1050500002000F00598271000000000000000000F3 -:1050600002000F005A8271000000000000000000E2 -:1050700002000F005B8271000000000000000000D1 -:1050800002000F005C8271000000000000000000C0 -:1050900002000F005D8271000000000000000000AF -:1050A00002000F005E82710000000000000000009E -:1050B00002000F005F82710000000000000000008D -:1050C00002000F006082710000000000000000007C -:1050D00002000F006182710000000000000000006B -:1050E00002000F006282710000000000000000005A -:1050F00002000F0063827100000000000000000049 -:1051000002000F0064827100000000000000000037 -:1051100002000F0065827100000000000000000026 -:1051200002000F0066827100000000000000000015 -:1051300002000F0067827100000000000000000004 -:1051400002000F00688271000000000000000000F3 -:1051500002000F00698271000000000000000000E2 -:1051600002000F006A8271000000000000000000D1 -:1051700002000F006B8271000000000000000000C0 -:1051800002000F006C8271000000000000000000AF -:1051900002000F006D82710000000000000000009E -:1051A00002000F006E82710000000000000000008D -:1051B00002000F006F82710000000000000000007C -:1051C00002000F007082710000000000000000006B -:1051D00002000F007182710000000000000000005A -:1051E00002000F0072827100000000000000000049 -:1051F00002000F0073827100000000000000000038 -:1052000002000F0074827100000000000000000026 -:1052100002000F0075827100000000000000000015 -:1052200002000F0076827100000000000000000004 -:1052300002000F00778271000000000000000000F3 -:1052400002000F00788271000000000000000000E2 -:1052500002000F00798271000000000000000000D1 -:1052600002000F007A8271000000000000000000C0 -:1052700002000F007B8271000000000000000000AF -:1052800002000F007C82710000000000000000009E -:1052900002000F007D82710000000000000000008D -:1052A00002000F007E82710000000000000000007C -:1052B00002000F007F82710000000000000000006B -:1052C00002000F008082710000000000000000005A -:1052D00002000F0081827100000000000000000049 -:1052E00002000F0082827100000000000000000038 -:1052F00002000F0083827100000000000000000027 -:1053000002000F0084827100000000000000000015 -:1053100002000F0085827100000000000000000004 -:1053200002000F00868271000000000000000000F3 -:1053300002000F00878271000000000000000000E2 -:1053400002000F00888271000000000000000000D1 -:1053500002000F00898271000000000000000000C0 -:1053600002000F008A8271000000000000000000AF -:1053700002000F008B82710000000000000000009E -:1053800002000F008C82710000000000000000008D -:1053900002000F008D82710000000000000000007C -:1053A00002000F008E82710000000000000000006B -:1053B00002000F008F82710000000000000000005A -:1053C00002000F0090827100000000000000000049 -:1053D00002000F0091827100000000000000000038 -:1053E00002000F0092827100000000000000000027 -:1053F00002000F0093827100000000000000000016 -:1054000002000F0094827100000000000000000004 -:1054100002000F00958271000000000000000000F3 -:1054200002000F00968271000000000000000000E2 -:1054300002000F00978271000000000000000000D1 -:1054400002000F00988271000000000000000000C0 -:1054500002000F00998271000000000000000000AF -:1054600002000F009A82710000000000000000009E -:1054700002000F009B82710000000000000000008D -:1054800002000F009C82710000000000000000007C -:1054900002000F009D82710000000000000000006B -:1054A00002000F009E82710000000000000000005A -:1054B00002000F009F827100000000000000000049 -:1054C00002000F00A0827100000000000000000038 -:1054D00002000F00A1827100000000000000000027 -:1054E00002000F00A2827100000000000000000016 -:1054F00002000F00A3827100000000000000000005 -:1055000002000F00A48271000000000000000000F3 -:1055100002000F00A58271000000000000000000E2 -:1055200002000F00A68271000000000000000000D1 -:1055300002000F00A78271000000000000000000C0 -:1055400002000F00A88271000000000000000000AF -:1055500002000F00A982710000000000000000009E -:1055600002000F00AA82710000000000000000008D -:1055700002000F00AB82710000000000000000007C -:1055800002000F00AC82710000000000000000006B -:1055900002000F00AD82710000000000000000005A -:1055A00002000F00AE827100000000000000000049 -:1055B00002000F00AF827100000000000000000038 -:1055C00002000F00B0827100000000000000000027 -:1055D00002000F00B1827100000000000000000016 -:1055E00002000F00B2827100000000000000000005 -:1055F00002000F00B38271000000000000000000F4 -:1056000002000F00B48271000000000000000000E2 -:1056100002000F00B58271000000000000000000D1 -:1056200002000F00B68271000000000000000000C0 -:1056300002000F00B78271000000000000000000AF -:1056400002000F00B882710000000000000000009E -:1056500002000F00B982710000000000000000008D -:1056600002000F00BA82710000000000000000007C -:1056700002000F00BB82710000000000000000006B -:1056800002000F00BC82710000000000000000005A -:1056900002000F00BD827100000000000000000049 -:1056A00002000F00BE827100000000000000000038 -:1056B00002000F00BF827100000000000000000027 -:1056C00002000F00C0827100000000000000000016 -:1056D00002000F00C1827100000000000000000005 -:1056E00002000F00C28271000000000000000000F4 -:1056F00002000F00C38271000000000000000000E3 -:1057000002000F00C48271000000000000000000D1 -:1057100002000F00C58271000000000000000000C0 -:1057200002000F00C68271000000000000000000AF -:1057300002000F00C782710000000000000000009E -:1057400002000F00C882710000000000000000008D -:1057500002000F00C982710000000000000000007C -:1057600002000F00CA82710000000000000000006B -:1057700002000F00CB82710000000000000000005A -:1057800002000F00CC827100000000000000000049 -:1057900002000F00CD827100000000000000000038 -:1057A00002000F00CE827100000000000000000027 -:1057B00002000F00CF827100000000000000000016 -:1057C00002000F00D0827100000000000000000005 -:1057D00002000F00D18271000000000000000000F4 -:1057E00002000F00D28271000000000000000000E3 -:1057F00002000F00D38271000000000000000000D2 -:1058000002000F00D48271000000000000000000C0 -:1058100002000F00D58271000000000000000000AF -:1058200002000F00D682710000000000000000009E -:1058300002000F00D782710000000000000000008D -:1058400002000F00D882710000000000000000007C -:1058500002000F00D982710000000000000000006B -:1058600002000F00DA82710000000000000000005A -:1058700002000F00DB827100000000000000000049 -:1058800002000F00DC827100000000000000000038 -:1058900002000F00DD827100000000000000000027 -:1058A00002000F00DE827100000000000000000016 -:1058B00002000F00DF827100000000000000000005 -:1058C00002000F00E08271000000000000000000F4 -:1058D00002000F00E18271000000000000000000E3 -:1058E00002000F00E28271000000000000000000D2 -:1058F00002000F00E38271000000000000000000C1 -:1059000002000F00E48271000000000000000000AF -:1059100002000F00E582710000000000000000009E -:1059200002000F00E682710000000000000000008D -:1059300002000F00E782710000000000000000007C -:1059400002000F00E882710000000000000000006B -:1059500002000F00E982710000000000000000005A -:1059600002000F00EA827100000000000000000049 -:1059700002000F00EB827100000000000000000038 -:1059800002000F00EC827100000000000000000027 -:1059900002000F00ED827100000000000000000016 -:1059A00002000F00EE827100000000000000000005 -:1059B00002000F00EF8271000000000000000000F4 -:1059C00002000F00F08271000000000000000000E3 -:1059D00002000F00F18271000000000000000000D2 -:1059E00002000F00F28271000000000000000000C1 -:1059F00002000F00F38271000000000000000000B0 -:105A000002000F00F482710000000000000000009E -:105A100002000F00F582710000000000000000008D -:105A200002000F00F682710000000000000000007C -:105A300002000F00F782710000000000000000006B -:105A400002000F00F882710000000000000000005A -:105A500002000F00F9827100000000000000000049 -:105A600002000F00FA827100000000000000000038 -:105A700002000F00FB827100000000000000000027 -:105A800002000F00FC827100000000000000000016 -:105A900002000F00FD827100000000000000000005 -:105AA00002000F00FE8271000000000000000000F4 -:105AB00002000F00FF8271000000000000000000E3 -:105AC00002000F00008371000000000000000000D1 -:105AD00002000F00018371000000000000000000C0 -:105AE00002000F00028371000000000000000000AF -:105AF00002000F000383710000000000000000009E -:105B000002000F000483710000000000000000008C -:105B100002000F000583710000000000000000007B -:105B200002000F000683710000000000000000006A -:105B300002000F0007837100000000000000000059 -:105B400002000F0008837100000000000000000048 -:105B500002000F0009837100000000000000000037 -:105B600002000F000A837100000000000000000026 -:105B700002000F000B837100000000000000000015 -:105B800002000F000C837100000000000000000004 -:105B900002000F000D8371000000000000000000F3 -:105BA00002000F000E8371000000000000000000E2 -:105BB00002000F000F8371000000000000000000D1 -:105BC00002000F00108371000000000000000000C0 -:105BD00002000F00118371000000000000000000AF -:105BE00002000F001283710000000000000000009E -:105BF00002000F001383710000000000000000008D -:105C000002000F001483710000000000000000007B -:105C100002000F001583710000000000000000006A -:105C200002000F0016837100000000000000000059 -:105C300002000F0017837100000000000000000048 -:105C400002000F0018837100000000000000000037 -:105C500002000F0019837100000000000000000026 -:105C600002000F001A837100000000000000000015 -:105C700002000F001B837100000000000000000004 -:105C800002000F001C8371000000000000000000F3 -:105C900002000F001D8371000000000000000000E2 -:105CA00002000F001E8371000000000000000000D1 -:105CB00002000F001F8371000000000000000000C0 -:105CC00002000F00208371000000000000000000AF -:105CD00002000F002183710000000000000000009E -:105CE00002000F002283710000000000000000008D -:105CF00002000F002383710000000000000000007C -:105D000002000F002483710000000000000000006A -:105D100002000F0025837100000000000000000059 -:105D200002000F0026837100000000000000000048 -:105D300002000F0027837100000000000000000037 -:105D400002000F0028837100000000000000000026 -:105D500002000F0029837100000000000000000015 -:105D600002000F002A837100000000000000000004 -:105D700002000F002B8371000000000000000000F3 -:105D800002000F002C8371000000000000000000E2 -:105D900002000F002D8371000000000000000000D1 -:105DA00002000F002E8371000000000000000000C0 -:105DB00002000F002F8371000000000000000000AF -:105DC00002000F003083710000000000000000009E -:105DD00002000F003183710000000000000000008D -:105DE00002000F003283710000000000000000007C -:105DF00002000F003383710000000000000000006B -:105E000002000F0034837100000000000000000059 -:105E100002000F0035837100000000000000000048 -:105E200002000F0036837100000000000000000037 -:105E300002000F0037837100000000000000000026 -:105E400002000F0038837100000000000000000015 -:105E500002000F0039837100000000000000000004 -:105E600002000F003A8371000000000000000000F3 -:105E700002000F003B8371000000000000000000E2 -:105E800002000F003C8371000000000000000000D1 -:105E900002000F003D8371000000000000000000C0 -:105EA00002000F003E8371000000000000000000AF -:105EB00002000F003F83710000000000000000009E -:105EC00002000F004083710000000000000000008D -:105ED00002000F004183710000000000000000007C -:105EE00002000F004283710000000000000000006B -:105EF00002000F004383710000000000000000005A -:105F000002000F0044837100000000000000000048 -:105F100002000F0045837100000000000000000037 -:105F200002000F0046837100000000000000000026 -:105F300002000F0047837100000000000000000015 -:105F400002000F0048837100000000000000000004 -:105F500002000F00498371000000000000000000F3 -:105F600002000F004A8371000000000000000000E2 -:105F700002000F004B8371000000000000000000D1 -:105F800002000F004C8371000000000000000000C0 -:105F900002000F004D8371000000000000000000AF -:105FA00002000F004E83710000000000000000009E -:105FB00002000F004F83710000000000000000008D -:105FC00002000F005083710000000000000000007C -:105FD00002000F005183710000000000000000006B -:105FE00002000F005283710000000000000000005A -:105FF00002000F0053837100000000000000000049 -:1060000002000F0054837100000000000000000037 -:1060100002000F0055837100000000000000000026 -:1060200002000F0056837100000000000000000015 -:1060300002000F0057837100000000000000000004 -:1060400002000F00588371000000000000000000F3 -:1060500002000F00598371000000000000000000E2 -:1060600002000F005A8371000000000000000000D1 -:1060700002000F005B8371000000000000000000C0 -:1060800002000F005C8371000000000000000000AF -:1060900002000F005D83710000000000000000009E -:1060A00002000F005E83710000000000000000008D -:1060B00002000F005F83710000000000000000007C -:1060C00002000F006083710000000000000000006B -:1060D00002000F006183710000000000000000005A -:1060E00002000F0062837100000000000000000049 -:1060F00002000F0063837100000000000000000038 -:1061000002000F0064837100000000000000000026 -:1061100002000F0065837100000000000000000015 -:1061200002000F0066837100000000000000000004 -:1061300002000F00678371000000000000000000F3 -:1061400002000F00688371000000000000000000E2 -:1061500002000F00698371000000000000000000D1 -:1061600002000F006A8371000000000000000000C0 -:1061700002000F006B8371000000000000000000AF -:1061800002000F006C83710000000000000000009E -:1061900002000F006D83710000000000000000008D -:1061A00002000F006E83710000000000000000007C -:1061B00002000F006F83710000000000000000006B -:1061C00002000F007083710000000000000000005A -:1061D00002000F0071837100000000000000000049 -:1061E00002000F0072837100000000000000000038 -:1061F00002000F0073837100000000000000000027 -:1062000002000F0074837100000000000000000015 -:1062100002000F0075837100000000000000000004 -:1062200002000F00768371000000000000000000F3 -:1062300002000F00778371000000000000000000E2 -:1062400002000F00788371000000000000000000D1 -:1062500002000F00798371000000000000000000C0 -:1062600002000F007A8371000000000000000000AF -:1062700002000F007B83710000000000000000009E -:1062800002000F007C83710000000000000000008D -:1062900002000F007D83710000000000000000007C -:1062A00002000F007E83710000000000000000006B -:1062B00002000F007F83710000000000000000005A -:1062C00002000F0080837100000000000000000049 -:1062D00002000F0081837100000000000000000038 -:1062E00002000F0082837100000000000000000027 -:1062F00002000F0083837100000000000000000016 -:1063000002000F0084837100000000000000000004 -:1063100002000F00858371000000000000000000F3 -:1063200002000F00868371000000000000000000E2 -:1063300002000F00878371000000000000000000D1 -:1063400002000F00888371000000000000000000C0 -:1063500002000F00898371000000000000000000AF -:1063600002000F008A83710000000000000000009E -:1063700002000F008B83710000000000000000008D -:1063800002000F008C83710000000000000000007C -:1063900002000F008D83710000000000000000006B -:1063A00002000F008E83710000000000000000005A -:1063B00002000F008F837100000000000000000049 -:1063C00002000F0090837100000000000000000038 -:1063D00002000F0091837100000000000000000027 -:1063E00002000F0092837100000000000000000016 -:1063F00002000F0093837100000000000000000005 -:1064000002000F00948371000000000000000000F3 -:1064100002000F00958371000000000000000000E2 -:1064200002000F00968371000000000000000000D1 -:1064300002000F00978371000000000000000000C0 -:1064400002000F00988371000000000000000000AF -:1064500002000F009983710000000000000000009E -:1064600002000F009A83710000000000000000008D -:1064700002000F009B83710000000000000000007C -:1064800002000F009C83710000000000000000006B -:1064900002000F009D83710000000000000000005A -:1064A00002000F009E837100000000000000000049 -:1064B00002000F009F837100000000000000000038 -:1064C00002000F00A0837100000000000000000027 -:1064D00002000F00A1837100000000000000000016 -:1064E00002000F00A2837100000000000000000005 -:1064F00002000F00A38371000000000000000000F4 -:1065000002000F00A48371000000000000000000E2 -:1065100002000F00A58371000000000000000000D1 -:1065200002000F00A68371000000000000000000C0 -:1065300002000F00A78371000000000000000000AF -:1065400002000F00A883710000000000000000009E -:1065500002000F00A983710000000000000000008D -:1065600002000F00AA83710000000000000000007C -:1065700002000F00AB83710000000000000000006B -:1065800002000F00AC83710000000000000000005A -:1065900002000F00AD837100000000000000000049 -:1065A00002000F00AE837100000000000000000038 -:1065B00002000F00AF837100000000000000000027 -:1065C00002000F00B0837100000000000000000016 -:1065D00002000F00B1837100000000000000000005 -:1065E00002000F00B28371000000000000000000F4 -:1065F00002000F00B38371000000000000000000E3 -:1066000002000F00B48371000000000000000000D1 -:1066100002000F00B58371000000000000000000C0 -:1066200002000F00B68371000000000000000000AF -:1066300002000F00B783710000000000000000009E -:1066400002000F00B883710000000000000000008D -:1066500002000F00B983710000000000000000007C -:1066600002000F00BA83710000000000000000006B -:1066700002000F00BB83710000000000000000005A -:1066800002000F00BC837100000000000000000049 -:1066900002000F00BD837100000000000000000038 -:1066A00002000F00BE837100000000000000000027 -:1066B00002000F00BF837100000000000000000016 -:1066C00002000F00C0837100000000000000000005 -:1066D00002000F00C18371000000000000000000F4 -:1066E00002000F00C28371000000000000000000E3 -:1066F00002000F00C38371000000000000000000D2 -:1067000002000F00C48371000000000000000000C0 -:1067100002000F00C58371000000000000000000AF -:1067200002000F00C683710000000000000000009E -:1067300002000F00C783710000000000000000008D -:1067400002000F00C883710000000000000000007C -:1067500002000F00C983710000000000000000006B -:1067600002000F00CA83710000000000000000005A -:1067700002000F00CB837100000000000000000049 -:1067800002000F00CC837100000000000000000038 -:1067900002000F00CD837100000000000000000027 -:1067A00002000F00CE837100000000000000000016 -:1067B00002000F00CF837100000000000000000005 -:1067C00002000F00D08371000000000000000000F4 -:1067D00002000F00D18371000000000000000000E3 -:1067E00002000F00D28371000000000000000000D2 -:1067F00002000F00D38371000000000000000000C1 -:1068000002000F00D48371000000000000000000AF -:1068100002000F00D583710000000000000000009E -:1068200002000F00D683710000000000000000008D -:1068300002000F00D783710000000000000000007C -:1068400002000F00D883710000000000000000006B -:1068500002000F00D983710000000000000000005A -:1068600002000F00DA837100000000000000000049 -:1068700002000F00DB837100000000000000000038 -:1068800002000F00DC837100000000000000000027 -:1068900002000F00DD837100000000000000000016 -:1068A00002000F00DE837100000000000000000005 -:1068B00002000F00DF8371000000000000000000F4 -:1068C00002000F00E08371000000000000000000E3 -:1068D00002000F00E18371000000000000000000D2 -:1068E00002000F00E28371000000000000000000C1 -:1068F00002000F00E38371000000000000000000B0 -:1069000002000F00E483710000000000000000009E -:1069100002000F00E583710000000000000000008D -:1069200002000F00E683710000000000000000007C -:1069300002000F00E783710000000000000000006B -:1069400002000F00E883710000000000000000005A -:1069500002000F00E9837100000000000000000049 -:1069600002000F00EA837100000000000000000038 -:1069700002000F00EB837100000000000000000027 -:1069800002000F00EC837100000000000000000016 -:1069900002000F00ED837100000000000000000005 -:1069A00002000F00EE8371000000000000000000F4 -:1069B00002000F00EF8371000000000000000000E3 -:1069C00002000F00F08371000000000000000000D2 -:1069D00002000F00F18371000000000000000000C1 -:1069E00002000F00F28371000000000000000000B0 -:1069F00002000F00F383710000000000000000009F -:106A000002000F00F483710000000000000000008D -:106A100002000F00F583710000000000000000007C -:106A200002000F00F683710000000000000000006B -:106A300002000F00F783710000000000000000005A -:106A400002000F00F8837100000000000000000049 -:106A500002000F00F9837100000000000000000038 -:106A600002000F00FA837100000000000000000027 -:106A700002000F00FB837100000000000000000016 -:106A800002000F00FC837100000000000000000005 -:106A900002000F00FD8371000000000000000000F4 -:106AA00002000F00FE8371000000000000000000E3 -:106AB00002000F00FF8371000000000000000000D2 -:106AC00002000F00008471000000000000000000C0 -:106AD00002000F00018471000000000000000000AF -:106AE00002000F000284710000000000000000009E -:106AF00002000F000384710000000000000000008D -:106B000002000F000484710000000000000000007B -:106B100002000F000584710000000000000000006A -:106B200002000F0006847100000000000000000059 -:106B300002000F0007847100000000000000000048 -:106B400002000F0008847100000000000000000037 -:106B500002000F0009847100000000000000000026 -:106B600002000F000A847100000000000000000015 -:106B700002000F000B847100000000000000000004 -:106B800002000F000C8471000000000000000000F3 -:106B900002000F000D8471000000000000000000E2 -:106BA00002000F000E8471000000000000000000D1 -:106BB00002000F000F8471000000000000000000C0 -:106BC00002000F00108471000000000000000000AF -:106BD00002000F001184710000000000000000009E -:106BE00002000F001284710000000000000000008D -:106BF00002000F001384710000000000000000007C -:106C000002000F001484710000000000000000006A -:106C100002000F0015847100000000000000000059 -:106C200002000F0016847100000000000000000048 -:106C300002000F0017847100000000000000000037 -:106C400002000F0018847100000000000000000026 -:106C500002000F0019847100000000000000000015 -:106C600002000F001A847100000000000000000004 -:106C700002000F001B8471000000000000000000F3 -:106C800002000F001C8471000000000000000000E2 -:106C900002000F001D8471000000000000000000D1 -:106CA00002000F001E8471000000000000000000C0 -:106CB00002000F001F8471000000000000000000AF -:106CC00002000F002084710000000000000000009E -:106CD00002000F002184710000000000000000008D -:106CE00002000F002284710000000000000000007C -:106CF00002000F002384710000000000000000006B -:106D000002000F0024847100000000000000000059 -:106D100002000F0025847100000000000000000048 -:106D200002000F0026847100000000000000000037 -:106D300002000F0027847100000000000000000026 -:106D400002000F0028847100000000000000000015 -:106D500002000F0029847100000000000000000004 -:106D600002000F002A8471000000000000000000F3 -:106D700002000F002B8471000000000000000000E2 -:106D800002000F002C8471000000000000000000D1 -:106D900002000F002D8471000000000000000000C0 -:106DA00002000F002E8471000000000000000000AF -:106DB00002000F002F84710000000000000000009E -:106DC00002000F003084710000000000000000008D -:106DD00002000F003184710000000000000000007C -:106DE00002000F003284710000000000000000006B -:106DF00002000F003384710000000000000000005A -:106E000002000F0034847100000000000000000048 -:106E100002000F0035847100000000000000000037 -:106E200002000F0036847100000000000000000026 -:106E300002000F0037847100000000000000000015 -:106E400002000F0038847100000000000000000004 -:106E500002000F00398471000000000000000000F3 -:106E600002000F003A8471000000000000000000E2 -:106E700002000F003B8471000000000000000000D1 -:106E800002000F003C8471000000000000000000C0 -:106E900002000F003D8471000000000000000000AF -:106EA00002000F003E84710000000000000000009E -:106EB00002000F003F84710000000000000000008D -:106EC00002000F004084710000000000000000007C -:106ED00002000F004184710000000000000000006B -:106EE00002000F004284710000000000000000005A -:106EF00002000F0043847100000000000000000049 -:106F000002000F0044847100000000000000000037 -:106F100002000F0045847100000000000000000026 -:106F200002000F0046847100000000000000000015 -:106F300002000F0047847100000000000000000004 -:106F400002000F00488471000000000000000000F3 -:106F500002000F00498471000000000000000000E2 -:106F600002000F004A8471000000000000000000D1 -:106F700002000F004B8471000000000000000000C0 -:106F800002000F004C8471000000000000000000AF -:106F900002000F004D84710000000000000000009E -:106FA00002000F004E84710000000000000000008D -:106FB00002000F004F84710000000000000000007C -:106FC00002000F005084710000000000000000006B -:106FD00002000F005184710000000000000000005A -:106FE00002000F0052847100000000000000000049 -:106FF00002000F0053847100000000000000000038 -:1070000002000F0054847100000000000000000026 -:1070100002000F0055847100000000000000000015 -:1070200002000F0056847100000000000000000004 -:1070300002000F00578471000000000000000000F3 -:1070400002000F00588471000000000000000000E2 -:1070500002000F00598471000000000000000000D1 -:1070600002000F005A8471000000000000000000C0 -:1070700002000F005B8471000000000000000000AF -:1070800002000F005C84710000000000000000009E -:1070900002000F005D84710000000000000000008D -:1070A00002000F005E84710000000000000000007C -:1070B00002000F005F84710000000000000000006B -:1070C00002000F006084710000000000000000005A -:1070D00002000F0061847100000000000000000049 -:1070E00002000F0062847100000000000000000038 -:1070F00002000F0063847100000000000000000027 -:1071000002000F0064847100000000000000000015 -:1071100002000F0065847100000000000000000004 -:1071200002000F00668471000000000000000000F3 -:1071300002000F00678471000000000000000000E2 -:1071400002000F00688471000000000000000000D1 -:1071500002000F00698471000000000000000000C0 -:1071600002000F006A8471000000000000000000AF -:1071700002000F006B84710000000000000000009E -:1071800002000F006C84710000000000000000008D -:1071900002000F006D84710000000000000000007C -:1071A00002000F006E84710000000000000000006B -:1071B00002000F006F84710000000000000000005A -:1071C00002000F0070847100000000000000000049 -:1071D00002000F0071847100000000000000000038 -:1071E00002000F0072847100000000000000000027 -:1071F00002000F0073847100000000000000000016 -:1072000002000F0074847100000000000000000004 -:1072100002000F00758471000000000000000000F3 -:1072200002000F00768471000000000000000000E2 -:1072300002000F00778471000000000000000000D1 -:1072400002000F00788471000000000000000000C0 -:1072500002000F00798471000000000000000000AF -:1072600002000F007A84710000000000000000009E -:1072700002000F007B84710000000000000000008D -:1072800002000F007C84710000000000000000007C -:1072900002000F007D84710000000000000000006B -:1072A00002000F007E84710000000000000000005A -:1072B00002000F007F847100000000000000000049 -:1072C00002000F0080847100000000000000000038 -:1072D00002000F0081847100000000000000000027 -:1072E00002000F0082847100000000000000000016 -:1072F00002000F0083847100000000000000000005 -:1073000002000F00848471000000000000000000F3 -:1073100002000F00858471000000000000000000E2 -:1073200002000F00868471000000000000000000D1 -:1073300002000F00878471000000000000000000C0 -:1073400002000F00888471000000000000000000AF -:1073500002000F008984710000000000000000009E -:1073600002000F008A84710000000000000000008D -:1073700002000F008B84710000000000000000007C -:1073800002000F008C84710000000000000000006B -:1073900002000F008D84710000000000000000005A -:1073A00002000F008E847100000000000000000049 -:1073B00002000F008F847100000000000000000038 -:1073C00002000F0090847100000000000000000027 -:1073D00002000F0091847100000000000000000016 -:1073E00002000F0092847100000000000000000005 -:1073F00002000F00938471000000000000000000F4 -:1074000002000F00948471000000000000000000E2 -:1074100002000F00958471000000000000000000D1 -:1074200002000F00968471000000000000000000C0 -:1074300002000F00978471000000000000000000AF -:1074400002000F009884710000000000000000009E -:1074500002000F009984710000000000000000008D -:1074600002000F009A84710000000000000000007C -:1074700002000F009B84710000000000000000006B -:1074800002000F009C84710000000000000000005A -:1074900002000F009D847100000000000000000049 -:1074A00002000F009E847100000000000000000038 -:1074B00002000F009F847100000000000000000027 -:1074C00002000F00A0847100000000000000000016 -:1074D00002000F00A1847100000000000000000005 -:1074E00002000F00A28471000000000000000000F4 -:1074F00002000F00A38471000000000000000000E3 -:1075000002000F00A48471000000000000000000D1 -:1075100002000F00A58471000000000000000000C0 -:1075200002000F00A68471000000000000000000AF -:1075300002000F00A784710000000000000000009E -:1075400002000F00A884710000000000000000008D -:1075500002000F00A984710000000000000000007C -:1075600002000F00AA84710000000000000000006B -:1075700002000F00AB84710000000000000000005A -:1075800002000F00AC847100000000000000000049 -:1075900002000F00AD847100000000000000000038 -:1075A00002000F00AE847100000000000000000027 -:1075B00002000F00AF847100000000000000000016 -:1075C00002000F00B0847100000000000000000005 -:1075D00002000F00B18471000000000000000000F4 -:1075E00002000F00B28471000000000000000000E3 -:1075F00002000F00B38471000000000000000000D2 -:1076000002000F00B48471000000000000000000C0 -:1076100002000F00B58471000000000000000000AF -:1076200002000F00B684710000000000000000009E -:1076300002000F00B784710000000000000000008D -:1076400002000F00B884710000000000000000007C -:1076500002000F00B984710000000000000000006B -:1076600002000F00BA84710000000000000000005A -:1076700002000F00BB847100000000000000000049 -:1076800002000F00BC847100000000000000000038 -:1076900002000F00BD847100000000000000000027 -:1076A00002000F00BE847100000000000000000016 -:1076B00002000F00BF847100000000000000000005 -:1076C00002000F00C08471000000000000000000F4 -:1076D00002000F00C18471000000000000000000E3 -:1076E00002000F00C28471000000000000000000D2 -:1076F00002000F00C38471000000000000000000C1 -:1077000002000F00C48471000000000000000000AF -:1077100002000F00C584710000000000000000009E -:1077200002000F00C684710000000000000000008D -:1077300002000F00C784710000000000000000007C -:1077400002000F00C884710000000000000000006B -:1077500002000F00C984710000000000000000005A -:1077600002000F00CA847100000000000000000049 -:1077700002000F00CB847100000000000000000038 -:1077800002000F00CC847100000000000000000027 -:1077900002000F00CD847100000000000000000016 -:1077A00002000F00CE847100000000000000000005 -:1077B00002000F00CF8471000000000000000000F4 -:1077C00002000F00D08471000000000000000000E3 -:1077D00002000F00D18471000000000000000000D2 -:1077E00002000F00D28471000000000000000000C1 -:1077F00002000F00D38471000000000000000000B0 -:1078000002000F00D484710000000000000000009E -:1078100002000F00D584710000000000000000008D -:1078200002000F00D684710000000000000000007C -:1078300002000F00D784710000000000000000006B -:1078400002000F00D884710000000000000000005A -:1078500002000F00D9847100000000000000000049 -:1078600002000F00DA847100000000000000000038 -:1078700002000F00DB847100000000000000000027 -:1078800002000F00DC847100000000000000000016 -:1078900002000F00DD847100000000000000000005 -:1078A00002000F00DE8471000000000000000000F4 -:1078B00002000F00DF8471000000000000000000E3 -:1078C00002000F00E08471000000000000000000D2 -:1078D00002000F00E18471000000000000000000C1 -:1078E00002000F00E28471000000000000000000B0 -:1078F00002000F00E384710000000000000000009F -:1079000002000F00E484710000000000000000008D -:1079100002000F00E584710000000000000000007C -:1079200002000F00E684710000000000000000006B -:1079300002000F00E784710000000000000000005A -:1079400002000F00E8847100000000000000000049 -:1079500002000F00E9847100000000000000000038 -:1079600002000F00EA847100000000000000000027 -:1079700002000F00EB847100000000000000000016 -:1079800002000F00EC847100000000000000000005 -:1079900002000F00ED8471000000000000000000F4 -:1079A00002000F00EE8471000000000000000000E3 -:1079B00002000F00EF8471000000000000000000D2 -:1079C00002000F00F08471000000000000000000C1 -:1079D00002000F00F18471000000000000000000B0 -:1079E00002000F00F284710000000000000000009F -:1079F00002000F00F384710000000000000000008E -:107A000002000F00F484710000000000000000007C -:107A100002000F00F584710000000000000000006B -:107A200002000F00F684710000000000000000005A -:107A300002000F00F7847100000000000000000049 -:107A400002000F00F8847100000000000000000038 -:107A500002000F00F9847100000000000000000027 -:107A600002000F00FA847100000000000000000016 -:107A700002000F00FB847100000000000000000005 -:107A800002000F00FC8471000000000000000000F4 -:107A900002000F00FD8471000000000000000000E3 -:107AA00002000F00FE8471000000000000000000D2 -:107AB00002000F00FF8471000000000000000000C1 -:107AC00002000F00008571000000000000000000AF -:107AD00002000F000185710000000000000000009E -:107AE00002000F000285710000000000000000008D -:107AF00002000F000385710000000000000000007C -:107B000002000F000485710000000000000000006A -:107B100002000F0005857100000000000000000059 -:107B200002000F0006857100000000000000000048 -:107B300002000F0007857100000000000000000037 -:107B400002000F0008857100000000000000000026 -:107B500002000F0009857100000000000000000015 -:107B600002000F000A857100000000000000000004 -:107B700002000F000B8571000000000000000000F3 -:107B800002000F000C8571000000000000000000E2 -:107B900002000F000D8571000000000000000000D1 -:107BA00002000F000E8571000000000000000000C0 -:107BB00002000F000F8571000000000000000000AF -:107BC00002000F001085710000000000000000009E -:107BD00002000F001185710000000000000000008D -:107BE00002000F001285710000000000000000007C -:107BF00002000F001385710000000000000000006B -:107C000002000F0014857100000000000000000059 -:107C100002000F0015857100000000000000000048 -:107C200002000F0016857100000000000000000037 -:107C300002000F0017857100000000000000000026 -:107C400002000F0018857100000000000000000015 -:107C500002000F0019857100000000000000000004 -:107C600002000F001A8571000000000000000000F3 -:107C700002000F001B8571000000000000000000E2 -:107C800002000F001C8571000000000000000000D1 -:107C900002000F001D8571000000000000000000C0 -:107CA00002000F001E8571000000000000000000AF -:107CB00002000F001F85710000000000000000009E -:107CC00002000F002085710000000000000000008D -:107CD00002000F002185710000000000000000007C -:107CE00002000F002285710000000000000000006B -:107CF00002000F002385710000000000000000005A -:107D000002000F0024857100000000000000000048 -:107D100002000F0025857100000000000000000037 -:107D200002000F0026857100000000000000000026 -:107D300002000F0027857100000000000000000015 -:107D400002000F0028857100000000000000000004 -:107D500002000F00298571000000000000000000F3 -:107D600002000F002A8571000000000000000000E2 -:107D700002000F002B8571000000000000000000D1 -:107D800002000F002C8571000000000000000000C0 -:107D900002000F002D8571000000000000000000AF -:107DA00002000F002E85710000000000000000009E -:107DB00002000F002F85710000000000000000008D -:107DC00002000F003085710000000000000000007C -:107DD00002000F003185710000000000000000006B -:107DE00002000F003285710000000000000000005A -:107DF00002000F0033857100000000000000000049 -:107E000002000F0034857100000000000000000037 -:107E100002000F0035857100000000000000000026 -:107E200002000F0036857100000000000000000015 -:107E300002000F0037857100000000000000000004 -:107E400002000F00388571000000000000000000F3 -:107E500002000F00398571000000000000000000E2 -:107E600002000F003A8571000000000000000000D1 -:107E700002000F003B8571000000000000000000C0 -:107E800002000F003C8571000000000000000000AF -:107E900002000F003D85710000000000000000009E -:107EA00002000F003E85710000000000000000008D -:107EB00002000F003F85710000000000000000007C -:107EC00002000F004085710000000000000000006B -:107ED00002000F004185710000000000000000005A -:107EE00002000F0042857100000000000000000049 -:107EF00002000F0043857100000000000000000038 -:107F000002000F0044857100000000000000000026 -:107F100002000F0045857100000000000000000015 -:107F200002000F0046857100000000000000000004 -:107F300002000F00478571000000000000000000F3 -:107F400002000F00488571000000000000000000E2 -:107F500002000F00498571000000000000000000D1 -:107F600002000F004A8571000000000000000000C0 -:107F700002000F004B8571000000000000000000AF -:107F800002000F004C85710000000000000000009E -:107F900002000F004D85710000000000000000008D -:107FA00002000F004E85710000000000000000007C -:107FB00002000F004F85710000000000000000006B -:107FC00002000F005085710000000000000000005A -:107FD00002000F0051857100000000000000000049 -:107FE00002000F0052857100000000000000000038 -:107FF00002000F0053857100000000000000000027 -:1080000002000F0054857100000000000000000015 -:1080100002000F0055857100000000000000000004 -:1080200002000F00568571000000000000000000F3 -:1080300002000F00578571000000000000000000E2 -:1080400002000F00588571000000000000000000D1 -:1080500002000F00598571000000000000000000C0 -:1080600002000F005A8571000000000000000000AF -:1080700002000F005B85710000000000000000009E -:1080800002000F005C85710000000000000000008D -:1080900002000F005D85710000000000000000007C -:1080A00002000F005E85710000000000000000006B -:1080B00002000F005F85710000000000000000005A -:1080C00002000F0060857100000000000000000049 -:1080D00002000F0061857100000000000000000038 -:1080E00002000F0062857100000000000000000027 -:1080F00002000F0063857100000000000000000016 -:1081000002000F0064857100000000000000000004 -:1081100002000F00658571000000000000000000F3 -:1081200002000F00668571000000000000000000E2 -:1081300002000F00678571000000000000000000D1 -:1081400002000F00688571000000000000000000C0 -:1081500002000F00698571000000000000000000AF -:1081600002000F006A85710000000000000000009E -:1081700002000F006B85710000000000000000008D -:1081800002000F006C85710000000000000000007C -:1081900002000F006D85710000000000000000006B -:1081A00002000F006E85710000000000000000005A -:1081B00002000F006F857100000000000000000049 -:1081C00002000F0070857100000000000000000038 -:1081D00002000F0071857100000000000000000027 -:1081E00002000F0072857100000000000000000016 -:1081F00002000F0073857100000000000000000005 -:1082000002000F00748571000000000000000000F3 -:1082100002000F00758571000000000000000000E2 -:1082200002000F00768571000000000000000000D1 -:1082300002000F00778571000000000000000000C0 -:1082400002000F00788571000000000000000000AF -:1082500002000F007985710000000000000000009E -:1082600002000F007A85710000000000000000008D -:1082700002000F007B85710000000000000000007C -:1082800002000F007C85710000000000000000006B -:1082900002000F007D85710000000000000000005A -:1082A00002000F007E857100000000000000000049 -:1082B00002000F007F857100000000000000000038 -:1082C00002000F0080857100000000000000000027 -:1082D00002000F0081857100000000000000000016 -:1082E00002000F0082857100000000000000000005 -:1082F00002000F00838571000000000000000000F4 -:1083000002000F00848571000000000000000000E2 -:1083100002000F00858571000000000000000000D1 -:1083200002000F00868571000000000000000000C0 -:1083300002000F00878571000000000000000000AF -:1083400002000F008885710000000000000000009E -:1083500002000F008985710000000000000000008D -:1083600002000F008A85710000000000000000007C -:1083700002000F008B85710000000000000000006B -:1083800002000F008C85710000000000000000005A -:1083900002000F008D857100000000000000000049 -:1083A00002000F008E857100000000000000000038 -:1083B00002000F008F857100000000000000000027 -:1083C00002000F0090857100000000000000000016 -:1083D00002000F0091857100000000000000000005 -:1083E00002000F00928571000000000000000000F4 -:1083F00002000F00938571000000000000000000E3 -:1084000002000F00948571000000000000000000D1 -:1084100002000F00958571000000000000000000C0 -:1084200002000F00968571000000000000000000AF -:1084300002000F009785710000000000000000009E -:1084400002000F009885710000000000000000008D -:1084500002000F009985710000000000000000007C -:1084600002000F009A85710000000000000000006B -:1084700002000F009B85710000000000000000005A -:1084800002000F009C857100000000000000000049 -:1084900002000F009D857100000000000000000038 -:1084A00002000F009E857100000000000000000027 -:1084B00002000F009F857100000000000000000016 -:1084C00002000F00A0857100000000000000000005 -:1084D00002000F00A18571000000000000000000F4 -:1084E00002000F00A28571000000000000000000E3 -:1084F00002000F00A38571000000000000000000D2 -:1085000002000F00A48571000000000000000000C0 -:1085100002000F00A58571000000000000000000AF -:1085200002000F00A685710000000000000000009E -:1085300002000F00A785710000000000000000008D -:1085400002000F00A885710000000000000000007C -:1085500002000F00A985710000000000000000006B -:1085600002000F00AA85710000000000000000005A -:1085700002000F00AB857100000000000000000049 -:1085800002000F00AC857100000000000000000038 -:1085900002000F00AD857100000000000000000027 -:1085A00002000F00AE857100000000000000000016 -:1085B00002000F00AF857100000000000000000005 -:1085C00002000F00B08571000000000000000000F4 -:1085D00002000F00B18571000000000000000000E3 -:1085E00002000F00B28571000000000000000000D2 -:1085F00002000F00B38571000000000000000000C1 -:1086000002000F00B48571000000000000000000AF -:1086100002000F00B585710000000000000000009E -:1086200002000F00B685710000000000000000008D -:1086300002000F00B785710000000000000000007C -:1086400002000F00B885710000000000000000006B -:1086500002000F00B985710000000000000000005A -:1086600002000F00BA857100000000000000000049 -:1086700002000F00BB857100000000000000000038 -:1086800002000F00BC857100000000000000000027 -:1086900002000F00BD857100000000000000000016 -:1086A00002000F00BE857100000000000000000005 -:1086B00002000F00BF8571000000000000000000F4 -:1086C00002000F00C08571000000000000000000E3 -:1086D00002000F00C18571000000000000000000D2 -:1086E00002000F00C28571000000000000000000C1 -:1086F00002000F00C38571000000000000000000B0 -:1087000002000F00C485710000000000000000009E -:1087100002000F00C585710000000000000000008D -:1087200002000F00C685710000000000000000007C -:1087300002000F00C785710000000000000000006B -:1087400002000F00C885710000000000000000005A -:1087500002000F00C9857100000000000000000049 -:1087600002000F00CA857100000000000000000038 -:1087700002000F00CB857100000000000000000027 -:1087800002000F00CC857100000000000000000016 -:1087900002000F00CD857100000000000000000005 -:1087A00002000F00CE8571000000000000000000F4 -:1087B00002000F00CF8571000000000000000000E3 -:1087C00002000F00D08571000000000000000000D2 -:1087D00002000F00D18571000000000000000000C1 -:1087E00002000F00D28571000000000000000000B0 -:1087F00002000F00D385710000000000000000009F -:1088000002000F00D485710000000000000000008D -:1088100002000F00D585710000000000000000007C -:1088200002000F00D685710000000000000000006B -:1088300002000F00D785710000000000000000005A -:1088400002000F00D8857100000000000000000049 -:1088500002000F00D9857100000000000000000038 -:1088600002000F00DA857100000000000000000027 -:1088700002000F00DB857100000000000000000016 -:1088800002000F00DC857100000000000000000005 -:1088900002000F00DD8571000000000000000000F4 -:1088A00002000F00DE8571000000000000000000E3 -:1088B00002000F00DF8571000000000000000000D2 -:1088C00002000F00E08571000000000000000000C1 -:1088D00002000F00E18571000000000000000000B0 -:1088E00002000F00E285710000000000000000009F -:1088F00002000F00E385710000000000000000008E -:1089000002000F00E485710000000000000000007C -:1089100002000F00E585710000000000000000006B -:1089200002000F00E685710000000000000000005A -:1089300002000F00E7857100000000000000000049 -:1089400002000F00E8857100000000000000000038 -:1089500002000F00E9857100000000000000000027 -:1089600002000F00EA857100000000000000000016 -:1089700002000F00EB857100000000000000000005 -:1089800002000F00EC8571000000000000000000F4 -:1089900002000F00ED8571000000000000000000E3 -:1089A00002000F00EE8571000000000000000000D2 -:1089B00002000F00EF8571000000000000000000C1 -:1089C00002000F00F08571000000000000000000B0 -:1089D00002000F00F185710000000000000000009F -:1089E00002000F00F285710000000000000000008E -:1089F00002000F00F385710000000000000000007D -:108A000002000F00F485710000000000000000006B -:108A100002000F00F585710000000000000000005A -:108A200002000F00F6857100000000000000000049 -:108A300002000F00F7857100000000000000000038 -:108A400002000F00F8857100000000000000000027 -:108A500002000F00F9857100000000000000000016 -:108A600002000F00FA857100000000000000000005 -:108A700002000F00FB8571000000000000000000F4 -:108A800002000F00FC8571000000000000000000E3 -:108A900002000F00FD8571000000000000000000D2 -:108AA00002000F00FE8571000000000000000000C1 -:108AB00002000F00FF8571000000000000000000B0 -:108AC00002000F000086710000000000000000009E -:108AD00002000F000186710000000000000000008D -:108AE00002000F000286710000000000000000007C -:108AF00002000F000386710000000000000000006B -:108B000002000F0004867100000000000000000059 -:108B100002000F0005867100000000000000000048 -:108B200002000F0006867100000000000000000037 -:108B300002000F0007867100000000000000000026 -:108B400002000F0008867100000000000000000015 -:108B500002000F0009867100000000000000000004 -:108B600002000F000A8671000000000000000000F3 -:108B700002000F000B8671000000000000000000E2 -:108B800002000F000C8671000000000000000000D1 -:108B900002000F000D8671000000000000000000C0 -:108BA00002000F000E8671000000000000000000AF -:108BB00002000F000F86710000000000000000009E -:108BC00002000F001086710000000000000000008D -:108BD00002000F001186710000000000000000007C -:108BE00002000F001286710000000000000000006B -:108BF00002000F001386710000000000000000005A -:108C000002000F0014867100000000000000000048 -:108C100002000F0015867100000000000000000037 -:108C200002000F0016867100000000000000000026 -:108C300002000F0017867100000000000000000015 -:108C400002000F0018867100000000000000000004 -:108C500002000F00198671000000000000000000F3 -:108C600002000F001A8671000000000000000000E2 -:108C700002000F001B8671000000000000000000D1 -:108C800002000F001C8671000000000000000000C0 -:108C900002000F001D8671000000000000000000AF -:108CA00002000F001E86710000000000000000009E -:108CB00002000F001F86710000000000000000008D -:108CC00002000F002086710000000000000000007C -:108CD00002000F002186710000000000000000006B -:108CE00002000F002286710000000000000000005A -:108CF00002000F0023867100000000000000000049 -:108D000002000F0024867100000000000000000037 -:108D100002000F0025867100000000000000000026 -:108D200002000F0026867100000000000000000015 -:108D300002000F0027867100000000000000000004 -:108D400002000F00288671000000000000000000F3 -:108D500002000F00298671000000000000000000E2 -:108D600002000F002A8671000000000000000000D1 -:108D700002000F002B8671000000000000000000C0 -:108D800002000F002C8671000000000000000000AF -:108D900002000F002D86710000000000000000009E -:108DA00002000F002E86710000000000000000008D -:108DB00002000F002F86710000000000000000007C -:108DC00002000F003086710000000000000000006B -:108DD00002000F003186710000000000000000005A -:108DE00002000F0032867100000000000000000049 -:108DF00002000F0033867100000000000000000038 -:108E000002000F0034867100000000000000000026 -:108E100002000F0035867100000000000000000015 -:108E200002000F0036867100000000000000000004 -:108E300002000F00378671000000000000000000F3 -:108E400002000F00388671000000000000000000E2 -:108E500002000F00398671000000000000000000D1 -:108E600002000F003A8671000000000000000000C0 -:108E700002000F003B8671000000000000000000AF -:108E800002000F003C86710000000000000000009E -:108E900002000F003D86710000000000000000008D -:108EA00002000F003E86710000000000000000007C -:108EB00002000F003F86710000000000000000006B -:108EC00002000F004086710000000000000000005A -:108ED00002000F0041867100000000000000000049 -:108EE00002000F0042867100000000000000000038 -:108EF00002000F0043867100000000000000000027 -:108F000002000F0044867100000000000000000015 -:108F100002000F0045867100000000000000000004 -:108F200002000F00468671000000000000000000F3 -:108F300002000F00478671000000000000000000E2 -:108F400002000F00488671000000000000000000D1 -:108F500002000F00498671000000000000000000C0 -:108F600002000F004A8671000000000000000000AF -:108F700002000F004B86710000000000000000009E -:108F800002000F004C86710000000000000000008D -:108F900002000F004D86710000000000000000007C -:108FA00002000F004E86710000000000000000006B -:108FB00002000F004F86710000000000000000005A -:108FC00002000F0050867100000000000000000049 -:108FD00002000F0051867100000000000000000038 -:108FE00002000F0052867100000000000000000027 -:108FF00002000F0053867100000000000000000016 -:1090000002000F0054867100000000000000000004 -:1090100002000F00558671000000000000000000F3 -:1090200002000F00568671000000000000000000E2 -:1090300002000F00578671000000000000000000D1 -:1090400002000F00588671000000000000000000C0 -:1090500002000F00598671000000000000000000AF -:1090600002000F005A86710000000000000000009E -:1090700002000F005B86710000000000000000008D -:1090800002000F005C86710000000000000000007C -:1090900002000F005D86710000000000000000006B -:1090A00002000F005E86710000000000000000005A -:1090B00002000F005F867100000000000000000049 -:1090C00002000F0060867100000000000000000038 -:1090D00002000F0061867100000000000000000027 -:1090E00002000F0062867100000000000000000016 -:1090F00002000F0063867100000000000000000005 -:1091000002000F00648671000000000000000000F3 -:1091100002000F00658671000000000000000000E2 -:1091200002000F00668671000000000000000000D1 -:1091300002000F00678671000000000000000000C0 -:1091400002000F00688671000000000000000000AF -:1091500002000F006986710000000000000000009E -:1091600002000F006A86710000000000000000008D -:1091700002000F006B86710000000000000000007C -:1091800002000F006C86710000000000000000006B -:1091900002000F006D86710000000000000000005A -:1091A00002000F006E867100000000000000000049 -:1091B00002000F006F867100000000000000000038 -:1091C00002000F0070867100000000000000000027 -:1091D00002000F0071867100000000000000000016 -:1091E00002000F0072867100000000000000000005 -:1091F00002000F00738671000000000000000000F4 -:1092000002000F00748671000000000000000000E2 -:1092100002000F00758671000000000000000000D1 -:1092200002000F00768671000000000000000000C0 -:1092300002000F00778671000000000000000000AF -:1092400002000F007886710000000000000000009E -:1092500002000F007986710000000000000000008D -:1092600002000F007A86710000000000000000007C -:1092700002000F007B86710000000000000000006B -:1092800002000F007C86710000000000000000005A -:1092900002000F007D867100000000000000000049 -:1092A00002000F007E867100000000000000000038 -:1092B00002000F007F867100000000000000000027 -:1092C00002000F0080867100000000000000000016 -:1092D00002000F0081867100000000000000000005 -:1092E00002000F00828671000000000000000000F4 -:1092F00002000F00838671000000000000000000E3 -:1093000002000F00848671000000000000000000D1 -:1093100002000F00858671000000000000000000C0 -:1093200002000F00868671000000000000000000AF -:1093300002000F008786710000000000000000009E -:1093400002000F008886710000000000000000008D -:1093500002000F008986710000000000000000007C -:1093600002000F008A86710000000000000000006B -:1093700002000F008B86710000000000000000005A -:1093800002000F008C867100000000000000000049 -:1093900002000F008D867100000000000000000038 -:1093A00002000F008E867100000000000000000027 -:1093B00002000F008F867100000000000000000016 -:1093C00002000F0090867100000000000000000005 -:1093D00002000F00918671000000000000000000F4 -:1093E00002000F00928671000000000000000000E3 -:1093F00002000F00938671000000000000000000D2 -:1094000002000F00948671000000000000000000C0 -:1094100002000F00958671000000000000000000AF -:1094200002000F009686710000000000000000009E -:1094300002000F009786710000000000000000008D -:1094400002000F009886710000000000000000007C -:1094500002000F009986710000000000000000006B -:1094600002000F009A86710000000000000000005A -:1094700002000F009B867100000000000000000049 -:1094800002000F009C867100000000000000000038 -:1094900002000F009D867100000000000000000027 -:1094A00002000F009E867100000000000000000016 -:1094B00002000F009F867100000000000000000005 -:1094C00002000F00A08671000000000000000000F4 -:1094D00002000F00A18671000000000000000000E3 -:1094E00002000F00A28671000000000000000000D2 -:1094F00002000F00A38671000000000000000000C1 -:1095000002000F00A48671000000000000000000AF -:1095100002000F00A586710000000000000000009E -:1095200002000F00A686710000000000000000008D -:1095300002000F00A786710000000000000000007C -:1095400002000F00A886710000000000000000006B -:1095500002000F00A986710000000000000000005A -:1095600002000F00AA867100000000000000000049 -:1095700002000F00AB867100000000000000000038 -:1095800002000F00AC867100000000000000000027 -:1095900002000F00AD867100000000000000000016 -:1095A00002000F00AE867100000000000000000005 -:1095B00002000F00AF8671000000000000000000F4 -:1095C00002000F00B08671000000000000000000E3 -:1095D00002000F00B18671000000000000000000D2 -:1095E00002000F00B28671000000000000000000C1 -:1095F00002000F00B38671000000000000000000B0 -:1096000002000F00B486710000000000000000009E -:1096100002000F00B586710000000000000000008D -:1096200002000F00B686710000000000000000007C -:1096300002000F00B786710000000000000000006B -:1096400002000F00B886710000000000000000005A -:1096500002000F00B9867100000000000000000049 -:1096600002000F00BA867100000000000000000038 -:1096700002000F00BB867100000000000000000027 -:1096800002000F00BC867100000000000000000016 -:1096900002000F00BD867100000000000000000005 -:1096A00002000F00BE8671000000000000000000F4 -:1096B00002000F00BF8671000000000000000000E3 -:1096C00002000F00C08671000000000000000000D2 -:1096D00002000F00C18671000000000000000000C1 -:1096E00002000F00C28671000000000000000000B0 -:1096F00002000F00C386710000000000000000009F -:1097000002000F00C486710000000000000000008D -:1097100002000F00C586710000000000000000007C -:1097200002000F00C686710000000000000000006B -:1097300002000F00C786710000000000000000005A -:1097400002000F00C8867100000000000000000049 -:1097500002000F00C9867100000000000000000038 -:1097600002000F00CA867100000000000000000027 -:1097700002000F00CB867100000000000000000016 -:1097800002000F00CC867100000000000000000005 -:1097900002000F00CD8671000000000000000000F4 -:1097A00002000F00CE8671000000000000000000E3 -:1097B00002000F00CF8671000000000000000000D2 -:1097C00002000F00D08671000000000000000000C1 -:1097D00002000F00D18671000000000000000000B0 -:1097E00002000F00D286710000000000000000009F -:1097F00002000F00D386710000000000000000008E -:1098000002000F00D486710000000000000000007C -:1098100002000F00D586710000000000000000006B -:1098200002000F00D686710000000000000000005A -:1098300002000F00D7867100000000000000000049 -:1098400002000F00D8867100000000000000000038 -:1098500002000F00D9867100000000000000000027 -:1098600002000F00DA867100000000000000000016 -:1098700002000F00DB867100000000000000000005 -:1098800002000F00DC8671000000000000000000F4 -:1098900002000F00DD8671000000000000000000E3 -:1098A00002000F00DE8671000000000000000000D2 -:1098B00002000F00DF8671000000000000000000C1 -:1098C00002000F00E08671000000000000000000B0 -:1098D00002000F00E186710000000000000000009F -:1098E00002000F00E286710000000000000000008E -:1098F00002000F00E386710000000000000000007D -:1099000002000F00E486710000000000000000006B -:1099100002000F00E586710000000000000000005A -:1099200002000F00E6867100000000000000000049 -:1099300002000F00E7867100000000000000000038 -:1099400002000F00E8867100000000000000000027 -:1099500002000F00E9867100000000000000000016 -:1099600002000F00EA867100000000000000000005 -:1099700002000F00EB8671000000000000000000F4 -:1099800002000F00EC8671000000000000000000E3 -:1099900002000F00ED8671000000000000000000D2 -:1099A00002000F00EE8671000000000000000000C1 -:1099B00002000F00EF8671000000000000000000B0 -:1099C00002000F00F086710000000000000000009F -:1099D00002000F00F186710000000000000000008E -:1099E00002000F00F286710000000000000000007D -:1099F00002000F00F386710000000000000000006C -:109A000002000F00F486710000000000000000005A -:109A100002000F00F5867100000000000000000049 -:109A200002000F00F6867100000000000000000038 -:109A300002000F00F7867100000000000000000027 -:109A400002000F00F8867100000000000000000016 -:109A500002000F00F9867100000000000000000005 -:109A600002000F00FA8671000000000000000000F4 -:109A700002000F00FB8671000000000000000000E3 -:109A800002000F00FC8671000000000000000000D2 -:109A900002000F00FD8671000000000000000000C1 -:109AA00002000F00FE8671000000000000000000B0 -:109AB00002000F00FF86710000000000000000009F -:109AC00002000F000087710000000000000000008D -:109AD00002000F000187710000000000000000007C -:109AE00002000F000287710000000000000000006B -:109AF00002000F000387710000000000000000005A -:109B000002000F0004877100000000000000000048 -:109B100002000F0005877100000000000000000037 -:109B200002000F0006877100000000000000000026 -:109B300002000F0007877100000000000000000015 -:109B400002000F0008877100000000000000000004 -:109B500002000F00098771000000000000000000F3 -:109B600002000F000A8771000000000000000000E2 -:109B700002000F000B8771000000000000000000D1 -:109B800002000F000C8771000000000000000000C0 -:109B900002000F000D8771000000000000000000AF -:109BA00002000F000E87710000000000000000009E -:109BB00002000F000F87710000000000000000008D -:109BC00002000F001087710000000000000000007C -:109BD00002000F001187710000000000000000006B -:109BE00002000F001287710000000000000000005A -:109BF00002000F0013877100000000000000000049 -:109C000002000F0014877100000000000000000037 -:109C100002000F0015877100000000000000000026 -:109C200002000F0016877100000000000000000015 -:109C300002000F0017877100000000000000000004 -:109C400002000F00188771000000000000000000F3 -:109C500002000F00198771000000000000000000E2 -:109C600002000F001A8771000000000000000000D1 -:109C700002000F001B8771000000000000000000C0 -:109C800002000F001C8771000000000000000000AF -:109C900002000F001D87710000000000000000009E -:109CA00002000F001E87710000000000000000008D -:109CB00002000F001F87710000000000000000007C -:109CC00002000F002087710000000000000000006B -:109CD00002000F002187710000000000000000005A -:109CE00002000F0022877100000000000000000049 -:109CF00002000F0023877100000000000000000038 -:109D000002000F0024877100000000000000000026 -:109D100002000F0025877100000000000000000015 -:109D200002000F0026877100000000000000000004 -:109D300002000F00278771000000000000000000F3 -:109D400002000F00288771000000000000000000E2 -:109D500002000F00298771000000000000000000D1 -:109D600002000F002A8771000000000000000000C0 -:109D700002000F002B8771000000000000000000AF -:109D800002000F002C87710000000000000000009E -:109D900002000F002D87710000000000000000008D -:109DA00002000F002E87710000000000000000007C -:109DB00002000F002F87710000000000000000006B -:109DC00002000F003087710000000000000000005A -:109DD00002000F0031877100000000000000000049 -:109DE00002000F0032877100000000000000000038 -:109DF00002000F0033877100000000000000000027 -:109E000002000F0034877100000000000000000015 -:109E100002000F0035877100000000000000000004 -:109E200002000F00368771000000000000000000F3 -:109E300002000F00378771000000000000000000E2 -:109E400002000F00388771000000000000000000D1 -:109E500002000F00398771000000000000000000C0 -:109E600002000F003A8771000000000000000000AF -:109E700002000F003B87710000000000000000009E -:109E800002000F003C87710000000000000000008D -:109E900002000F003D87710000000000000000007C -:109EA00002000F003E87710000000000000000006B -:109EB00002000F003F87710000000000000000005A -:109EC00002000F0040877100000000000000000049 -:109ED00002000F0041877100000000000000000038 -:109EE00002000F0042877100000000000000000027 -:109EF00002000F0043877100000000000000000016 -:109F000002000F0044877100000000000000000004 -:109F100002000F00458771000000000000000000F3 -:109F200002000F00468771000000000000000000E2 -:109F300002000F00478771000000000000000000D1 -:109F400002000F00488771000000000000000000C0 -:109F500002000F00498771000000000000000000AF -:109F600002000F004A87710000000000000000009E -:109F700002000F004B87710000000000000000008D -:109F800002000F004C87710000000000000000007C -:109F900002000F004D87710000000000000000006B -:109FA00002000F004E87710000000000000000005A -:109FB00002000F004F877100000000000000000049 -:109FC00002000F0050877100000000000000000038 -:109FD00002000F0051877100000000000000000027 -:109FE00002000F0052877100000000000000000016 -:109FF00002000F0053877100000000000000000005 -:10A0000002000F00548771000000000000000000F3 -:10A0100002000F00558771000000000000000000E2 -:10A0200002000F00568771000000000000000000D1 -:10A0300002000F00578771000000000000000000C0 -:10A0400002000F00588771000000000000000000AF -:10A0500002000F005987710000000000000000009E -:10A0600002000F005A87710000000000000000008D -:10A0700002000F005B87710000000000000000007C -:10A0800002000F005C87710000000000000000006B -:10A0900002000F005D87710000000000000000005A -:10A0A00002000F005E877100000000000000000049 -:10A0B00002000F005F877100000000000000000038 -:10A0C00002000F0060877100000000000000000027 -:10A0D00002000F0061877100000000000000000016 -:10A0E00002000F0062877100000000000000000005 -:10A0F00002000F00638771000000000000000000F4 -:10A1000002000F00648771000000000000000000E2 -:10A1100002000F00658771000000000000000000D1 -:10A1200002000F00668771000000000000000000C0 -:10A1300002000F00678771000000000000000000AF -:10A1400002000F006887710000000000000000009E -:10A1500002000F006987710000000000000000008D -:10A1600002000F006A87710000000000000000007C -:10A1700002000F006B87710000000000000000006B -:10A1800002000F006C87710000000000000000005A -:10A1900002000F006D877100000000000000000049 -:10A1A00002000F006E877100000000000000000038 -:10A1B00002000F006F877100000000000000000027 -:10A1C00002000F0070877100000000000000000016 -:10A1D00002000F0071877100000000000000000005 -:10A1E00002000F00728771000000000000000000F4 -:10A1F00002000F00738771000000000000000000E3 -:10A2000002000F00748771000000000000000000D1 -:10A2100002000F00758771000000000000000000C0 -:10A2200002000F00768771000000000000000000AF -:10A2300002000F007787710000000000000000009E -:10A2400002000F007887710000000000000000008D -:10A2500002000F007987710000000000000000007C -:10A2600002000F007A87710000000000000000006B -:10A2700002000F007B87710000000000000000005A -:10A2800002000F007C877100000000000000000049 -:10A2900002000F007D877100000000000000000038 -:10A2A00002000F007E877100000000000000000027 -:10A2B00002000F007F877100000000000000000016 -:10A2C00002000F0080877100000000000000000005 -:10A2D00002000F00818771000000000000000000F4 -:10A2E00002000F00828771000000000000000000E3 -:10A2F00002000F00838771000000000000000000D2 -:10A3000002000F00848771000000000000000000C0 -:10A3100002000F00858771000000000000000000AF -:10A3200002000F008687710000000000000000009E -:10A3300002000F008787710000000000000000008D -:10A3400002000F008887710000000000000000007C -:10A3500002000F008987710000000000000000006B -:10A3600002000F008A87710000000000000000005A -:10A3700002000F008B877100000000000000000049 -:10A3800002000F008C877100000000000000000038 -:10A3900002000F008D877100000000000000000027 -:10A3A00002000F008E877100000000000000000016 -:10A3B00002000F008F877100000000000000000005 -:10A3C00002000F00908771000000000000000000F4 -:10A3D00002000F00918771000000000000000000E3 -:10A3E00002000F00928771000000000000000000D2 -:10A3F00002000F00938771000000000000000000C1 -:10A4000002000F00948771000000000000000000AF -:10A4100002000F009587710000000000000000009E -:10A4200002000F009687710000000000000000008D -:10A4300002000F009787710000000000000000007C -:10A4400002000F009887710000000000000000006B -:10A4500002000F009987710000000000000000005A -:10A4600002000F009A877100000000000000000049 -:10A4700002000F009B877100000000000000000038 -:10A4800002000F009C877100000000000000000027 -:10A4900002000F009D877100000000000000000016 -:10A4A00002000F009E877100000000000000000005 -:10A4B00002000F009F8771000000000000000000F4 -:10A4C00002000F00A08771000000000000000000E3 -:10A4D00002000F00A18771000000000000000000D2 -:10A4E00002000F00A28771000000000000000000C1 -:10A4F00002000F00A38771000000000000000000B0 -:10A5000002000F00A487710000000000000000009E -:10A5100002000F00A587710000000000000000008D -:10A5200002000F00A687710000000000000000007C -:10A5300002000F00A787710000000000000000006B -:10A5400002000F00A887710000000000000000005A -:10A5500002000F00A9877100000000000000000049 -:10A5600002000F00AA877100000000000000000038 -:10A5700002000F00AB877100000000000000000027 -:10A5800002000F00AC877100000000000000000016 -:10A5900002000F00AD877100000000000000000005 -:10A5A00002000F00AE8771000000000000000000F4 -:10A5B00002000F00AF8771000000000000000000E3 -:10A5C00002000F00B08771000000000000000000D2 -:10A5D00002000F00B18771000000000000000000C1 -:10A5E00002000F00B28771000000000000000000B0 -:10A5F00002000F00B387710000000000000000009F -:10A6000002000F00B487710000000000000000008D -:10A6100002000F00B587710000000000000000007C -:10A6200002000F00B687710000000000000000006B -:10A6300002000F00B787710000000000000000005A -:10A6400002000F00B8877100000000000000000049 -:10A6500002000F00B9877100000000000000000038 -:10A6600002000F00BA877100000000000000000027 -:10A6700002000F00BB877100000000000000000016 -:10A6800002000F00BC877100000000000000000005 -:10A6900002000F00BD8771000000000000000000F4 -:10A6A00002000F00BE8771000000000000000000E3 -:10A6B00002000F00BF8771000000000000000000D2 -:10A6C00002000F00C087710079000000769060FDE5 -:10A6D00002000F00C18771003D0000006F0080F78D -:10A6E00002000F00C28771003D0000006F0080F77C -:10A6F00002000F00C38771003D0000006F0080F76B -:10A7000002000F00C48771803D0000006F0080F7D9 -:00000001FF -/* Loading Firmware */ -/* INT_MEM Ver */ - * Tehuti Networks(R) Network Driver - * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved diff --git a/firmware/ti_3410.fw.ihex b/firmware/ti_3410.fw.ihex deleted file mode 100644 index b22c0425980e9bd324fe6f04bd8c4db88a99b20d..0000000000000000000000000000000000000000 --- a/firmware/ti_3410.fw.ihex +++ /dev/null @@ -1,862 +0,0 @@ -:10000000C2350002001E021ADBFFFFFFFFFF0232B3 -:10001000CBFFFFFFFFFFFFFFFFFFFFFFFFFF0233ED -:10002000767581CE90FDE88583A01234EAEC4D60B0 -:100030006A78AB8003760018B89CFA787F800376E4 -:100040000018B865FA78208003760018B820FA9076 -:10005000FDDDAE83AF8290FBF81200A16005E4F0F5 -:10006000A380F690FDE8A88290FDE8A982E8C399F4 -:10007000500576000880F69000FF1200AA90010358 -:100080001200AA9001071200AA90010B1200C8905A -:1000900001111200C89001171200C875D000123368 -:1000A000C802011DEF65827003EE658322E493F8B8 -:1000B000740193F9740293FE740393F5828E83E8BE -:1000C00069700122E493F6A30880F4E493FC7401C0 -:1000D00093FD740293FE740393FF740493F8740504 -:1000E00093F58288831200A1700122E493A3A88370 -:1000F000A9828C838D82F0A3AC83AD8288838982B0 -:1001000080E32121049280800492ACAE0492FDE849 -:1001100004940494FBF304990494FBF304F904F9A4 -:1001200080FED0F030F00920F303F68010F7800D48 -:1001300030F10920F303F28004F38001F020F4048D -:10014000FCD0E0CC22CCC0E012015A02014BBC0032 -:1001500005D0F0ACF022C313DCFC020121BF000982 -:10016000ED258275F001F8E622BF010FED2582F53D -:1001700082EE3583F58375F004E022ED258275F07B -:1001800002F8E222D083D082F5F0C3E493A3C5F055 -:1001900095F0C0E0C3D0F0E493A395F04012A3A380 -:1001A000C3E5F033500205832582F58250020583B2 -:1001B000740193C0E0E493C0E022D083D082F5F0D4 -:1001C000E49370097401937004A3A3800C740293E8 -:1001D00065F06005A3A3A380E7740193C0E0E493F6 -:1001E000C0E02212025B0201F21202AF0201F2121F -:1001F00002D30201F230E00720E302E622E72230D8 -:10020000E10720E302E222E32230E202E022E4936B -:10021000221202D302021A1202AF02021AABF01229 -:100220000224CBC5F0CB2230E01020E306E6F5F047 -:1002300008E622E7F5F009E7192230E11020E3068D -:10024000E2F5F008E222E3F5F009E3192230E206D4 -:10025000E0F5F0A3E022E493F5F074019322BB00F3 -:1002600003740922BB010789828A83740422BB02BA -:100270000789828A83741022740A2202027BBB00DF -:1002800007E92582F8740122BB010DE92582F58278 -:10029000EA3583F583740422BB020DE92582F582D9 -:1002A000EA3583F583741022E92582F8740222026C -:1002B00002AFBF0005EDF8740122BF01078D828EE9 -:1002C00083740422BF02078D828E83741022EDF89E -:1002D0007402220202D3BF0007ED2582F8740122C6 -:1002E000BF010DED2582F582EE3583F5837404227E -:1002F000BF020DED2582F582EE3583F58374102261 -:10030000ED2582F8740222020307C0E012025B02AC -:10031000031FC0E01202AF02031FC0E01202D302AB -:10032000031F30E00B20E304D0E0F622D0E0F722F8 -:1003300030E10B20E304D0E0F222D0E0F322D0E061 -:10034000F022C9CDC9CACECACBCFCB120352EDF928 -:10035000EEFAEFFB22BB002FBF000AFAEDF8E7F63A -:100360000809DAFA22BF01128D828E83F802036F28 -:1003700009A3E7F0D8FA2202037AFAEDF8E7F208C7 -:1003800009DAFA22020384BB014DBF001489828A74 -:1003900083F9EDF802039608A3E0F6D9FA220203E6 -:1003A000A7BF01228D828E83FB08C9C582C9CAC539 -:1003B00083CAE0A3C9C582C9CAC583CAF0A3DBEA60 -:1003C000D8E8220203CA8D828E83F9EDF8E0F208A4 -:1003D000A3D9FA220203D4BB024DBF001289828A3C -:1003E00083F9EDF80203E608A3E493F6D9F922BFF6 -:1003F00001238D828E83FB08C9C582C9CAC583CA01 -:10040000E493A3C9C582C9CAC583CAF0A3DBE9D8EE -:10041000E72202041989828A83F9EDF8E493F2084D -:10042000A3D9F92202042ABF000DFAEDF8E3F60879 -:1004300009DAFA22020434BF01128D828E83F80297 -:10044000044109A3E3F0D8FA2202044CFAEDF8E3E0 -:10045000F20809DAFA22020456E6FB08E6FA08E690 -:10046000F904F61870010622E6FF08E6FE08E6FD2C -:1004700022EFF0A3EEF0A3EDF022EBF0A3EAF0A35D -:10048000E9F022E0FFA3E0FEA3E0FD22E0FBA3E011 -:10049000FAA3E0F9220000000000000004F9006166 -:1004A00005680026058F00330A0000610A6C0066AB -:1004B000151D00610CF0006109A0006109D7006101 -:1004C0000DB700610BE800610A1300610A48006182 -:1004D00017150033172800341DF600431EA10044F1 -:1004E000200E00441FFC00471EC800471F6D004D32 -:1004F0001FBE004F1EEA0058325600617CCC7DFFC3 -:10050000121CA72290FFFCE020E72DC2AFAE59AF2E -:1005100058755A20E55A14C55A6019E4FE7F05EE55 -:100520004FCE24FFCECF34FFCF6007E490FF92F090 -:1005300080ED80E08E598F58221205017D077CB72F -:100540001232727D0F7C6E12328C789D7A06E4F640 -:1005500008DAFC7A061205C47C03120E4C12214AFA -:10056000E4FEFF7C0F1231FBD2A8221230E6E490A9 -:10057000FC38F090FFF0E030E408740190FC39F0B2 -:100580008005E490FC39F07D0A7C001225261231AA -:1005900069221230E690FC39E014700E90FFF0E012 -:1005A0004410F07C001225BF801990FC39E0700ED9 -:1005B00090FFF0E054EFF07C001225BF80057C171F -:1005C0001225BF1231692290FFF0E054ABF090FF8A -:1005D000F0E04420F0228C378D367882EDF608EC7E -:1005E000F6EDFEECFD7F019000051201EC7880F63F -:1005F0007882E6FD08E6FCEDFEECFD7F019000044C -:100600001201EC540FFC7D801217467880E6700DC5 -:10061000AD3AAE39AF38E412030F7C082290FFF0F8 -:10062000E054FEF090FFF0E054FDF0801E7882E68A -:10063000FD08E6FCEDFEECFD7F0190000812020EC5 -:1006400025E0440190FFF3F00206D07882E6FD0831 -:10065000E6FCEDFEECFD7F0190000612020E54FE5A -:1006600090FFF3F0802B7882E6FD08E6FCEDFEECCF -:10067000FD7F0190000812020EFAEB90FFF1F012DC -:1006800008BF400DAD3AAE39AF38E412030F7C1805 -:10069000227882E6FD08E6FCEDFEECFD7F0190008D -:1006A0000812020E90FFF1F01208BF400DAD3AAEF5 -:1006B00039AF38E412030F7C18227882E6FD08E691 -:1006C000FCEDFEECFD7F0190000612020E4401904D -:1006D000FFF3F07883E62403F618E63400F678801A -:1006E000E624FE500990FFF0E054FDF0800790FFF3 -:1006F000F0E04402F0E490FFF1F078817600788039 -:10070000E624FFFCE434FFFD7881E67F00FEECD3B5 -:100710009EEF6480CD64809D402F1208A4400F7826 -:1007200081E6AD3AAE39AF3812030F7C182290FF44 -:10073000F2E0FC78828683088682ECF0788106A35A -:100740007882A68308A68280B51208A4400F78811B -:10075000E6AD3AAE39AF3812030F7C182290FFF2A3 -:10076000E0FC78828683088682ECF07880E6AD3AF9 -:10077000AE39AF3812030F7C00228C378D36788269 -:10078000EDF608ECF6EDFEECFD7F019000051201A0 -:10079000EC7881F67882E6FD08E6FCEDFEECFD7F64 -:1007A000019000041201EC540FFC7D811217467871 -:1007B00081E670037C082290FFF0E054FEF090FF89 -:1007C000F0E054FDF0801B7882E6FD08E6FCEDFECB -:1007D000ECFD7F0190000812020E25E090FFF3F07F -:1007E000805B7882E6FD08E6FCEDFEECFD7F019083 -:1007F000000612020E54FE90FFF3F080217882E68C -:10080000FD08E6FCEDFEECFD7F0190000812020EF3 -:10081000FAEB90FFF1F01208BF40037C18227882B7 -:10082000E6FD08E6FCEDFEECFD7F019000081202FB -:100830000E90FFF1F01208BF40037C18227883E687 -:10084000240AF618E63400F6788076007881E624EB -:10085000FFFCE434FFFD7880E67F00FEECD39EEFE2 -:100860006480CD64809D402178828683088682E002 -:1008700090FFF1F01208BF40037C182278800678C0 -:100880008306E61870010680C390FFF0E04401F093 -:1008900078828683088682E090FFF1F01208BF40DC -:1008A000037C18227C002290FFF0E020E71290FFEA -:1008B000F0E030E50990FFF0E04420F0C32280E74B -:1008C000D32290FFF0E020E31290FFF0E030E50942 -:1008D00090FFF0E04420F0C32280E7D3228C428DC9 -:1008E000417C00ED54F0FDEC7003ED643070057553 -:1008F0003E038003753E04AC3E120F69758300858C -:100900008340E541540FF53FE5407004E53F640343 -:100910007035E53E24FD75F00AA42402F582E43426 -:10092000FCF583E030E60512104B8019E53E249D6E -:10093000F8C654FBF678A9E62405F58218E63400DB -:10094000F583740FF08059E5407004E53F6404704E -:1009500048E53E24FD75F00AA42402F582E434FC47 -:10096000F583E030E507AC42AD41121C3CE5423076 -:10097000E21578ADE630E00F78ADE630E109E4FF4E -:1009800004FE7C041231FB78A9E62406F58218E601 -:100990003400F583740FF08007E4FC7DEE121C3CFC -:1009A000C203221230E6120F6978A9E62406F58206 -:1009B00018E63400F583E090FC38F078A9E62405C9 -:1009C000F58218E63400F583E090FC39F0C2037D2F -:1009D000027C00122526123169221230E67895EC4D -:1009E000F6EC249DF8E630E1077C131225BF800F5A -:1009F00090FC39E0FD7895E6FC1213C81225BF1271 -:100A00003169221230E67895ECF67D00120F09125A -:100A100025BF123169221230E67895ECF6EC249D60 -:100A2000F8E630E2077C131225BF801B7895E62498 -:100A30009DF8E620E1077C121225BF800A7895E632 -:100A4000FC1213EC1225BF123169221230E67895A0 -:100A5000ECF6EC249DF8E620E2077C111225BF801D -:100A60000A7895E6FC1214ED1225BF1231692212A4 -:100A700030E67895ECF6120F6978A9E62409F5823C -:100A800018E63400F583E090FC3FF078A9E6240AEC -:100A9000F58218E63400F583E090FC40F078A9E692 -:100AA0002403F58218E63400F583E0FC78A9E624F7 -:100AB00004F58218E63400F583E0F56278A9E624AF -:100AC00002F58218E63400F583E0F5638C61E4EC0E -:100AD000333354017895F66008E56230E103789588 -:100AE000067895E690FC41F078A7E62402F5821896 -:100AF000E63400F583E0FDA3E0540CFCED54E68CF5 -:100B000065F564E56130E503436501E56220E50EC6 -:100B1000E561547F7008E56120E703436502E56104 -:100B200030E303436510E56130E203436520E5618E -:100B300054036003436540E56130E103436580E5AC -:100B40006130E403436401E56130E603436408E592 -:100B50006220E40EE561547F7008E56120E70343FD -:100B600064105365FB536479AD64E56590FC3ACD40 -:100B7000F0A3CDF0E56330E30DE5635430C4540FCA -:100B800090FC3DF08005E490FC3DF0E5635403905B -:100B9000FC3CF0E5635404C31390FC3EF090FC3C35 -:100BA000E0700E7D357EFC7F01740190000912011A -:100BB0004278A9E62408F58218E63400F583E07C43 -:100BC00000FD78A9E62407F58218E63400F583E0F5 -:100BD0007F004CFEEF4D90FC38F0A3CEF0CEC20368 -:100BE0007D0A7C00122526123169221230E67895A2 -:100BF000ECF6789A76010876FC0876387897760CC9 -:100C0000789A1204651202147898CBF6CB08F67F16 -:100C100000EF24EA401FE4EF25E090352CFD93CD52 -:100C200004937899667003ED1866700678977600DD -:100C300080030F80DC7896EFF6789A1204659000B6 -:100C40000212020E7898CBF6CB08F65404CB5486E9 -:100C50004B60047897760B7899E630E313789A1214 -:100C600004659000051201EC24FB50047897760D82 -:100C70007899E654C07D0064C04D70047897760B77 -:100C8000789A1204659000041201EC24FC50047858 -:100C900097760F789A1204659000061201EC24FDF5 -:100CA00050047897760E789A120465900009120124 -:100CB000EC24FD50047897760A7897E6702A7895A8 -:100CC000E6FC120F69789A12046578A7E6F978A60F -:100CD000E6FA7B01740A780012033FC2037895E6B6 -:100CE000FC1211077897ECF67897E6FC1225BF12F4 -:100CF0003169221230E67895ECF6120F697895E6A4 -:100D000024FD75F00AA42414F582E434FCF583ACC8 -:100D100082AD8378A68683088682ECF9EDFA7B0A99 -:100D200078011203A7C2037895E6FC12110712316D -:100D300069228D2B8C2AED60407527017529487535 -:100D400028FFE52A24FDFCE434FFFDEC7C0325E0CC -:100D5000CD33CDDCF9FCE5292CF529E5283DF52836 -:100D6000AD29AE28AF277480900006120317748057 -:100D7000900002120317120FB7E52B14603B752782 -:100D8000017529087528FFE52A24FDFCE434FFFDE0 -:100D9000EC7C0325E0CD33CDDCF9FCE5292CF529ED -:100DA000E5283DF528AD29AE28AF27E490000612CE -:100DB0000317E4900002120317221230E67895EC34 -:100DC000F6EC249DF8E630E2097895E6FC1214ED85 -:100DD000D2007895E6FC120F697896760090FC397F -:100DE000E030E704789676017896E6FD7895E6FCA3 -:100DF000120D2FC2033000077895E6FC1213EC7C2D -:100E0000001225BF1231692278A9E62404F5821860 -:100E1000E63400F583E04401F078A9E62404F58285 -:100E200018E63400F583E030E00280ED78A9E6248E -:100E30000BF58218E63400F583E054F8F078A9E663 -:100E40002402F58218E63400F583E04480F022C2E3 -:100E5000038C58120F6978A68683088682795D7A9A -:100E6000357B0A78011203F5120E05AC587D02128B -:100E70000D2FC203AC58121107228D538E528F5181 -:100E80008C50120F69754F0078A9E62405F5821879 -:100E9000E63400F583E020E41FE54F24F640190511 -:100EA0004FC2037C181232A990FF93E04401F0B2C4 -:100EB000B3AC50120F6980D078A9E62405F58218EA -:100EC000E63400F583E020E405C2037C022278A921 -:100ED000E62405F58218E63400F583E0540F601629 -:100EE00078A9E62405F58218E63400F583E0540F6E -:100EF000F0C2037C012278A88683088682E0AD5385 -:100F0000AE52AF5112030FC2037C00228D318C30E0 -:100F10001214EDE531600FE530B4030A7C011224B0 -:100F2000EE7C811224EEAC30120F69E531601A7844 -:100F3000AA8683088682E054E7F0A3A3A3A3E05423 -:100F4000E7F0AC307D02120D2F78A68683088682EA -:100F500079677A357B0A78011203F5C203E53024FC -:100F60009DF8C654FDF6AC30121107228C263003D2 -:100F70000512324880F87C0A12315BD203E5262440 -:100F8000FD78A3F6700778AA76FF0876E078A3E6E6 -:100F900075F010A4ADF0FC24A078A9F6ED34FF188C -:100FA000F678A3E675F00AA42400FCE434FCFD788E -:100FB000A6EDF608ECF61231F42278A9E62402F543 -:100FC0008218E63400F583E030E72278A9E62402AF -:100FD000F58218E63400F583E0547FF078A9E62422 -:100FE00002F58218E63400F583E04480F02278AA06 -:100FF0008683088682E0547FF0AD83E5822404FC7A -:10100000E43D8C82F583E0547FF078A9E6240BF56B -:101010008218E63400F583E054F8F078ABE624015A -:10102000F58218E63400F583E04403F078ABE6245B -:1010300005F58218E63400F583E04403F078A9E66C -:101040002405F58218E63400F583740FF02278AA9F -:101050008683088682E0543FF0AD83E5822404FC59 -:10106000E43D8C82F583E0543FF078A3E624A4F8B5 -:10107000E6FC78ABE62401F58218E63400F583EC53 -:10108000F078A3E624A4F8E6FC78ABE62405F58224 -:1010900018E63400F583ECF078A9E6240BF5821805 -:1010A000E63400F583E054FB4402F52678A7E624F5 -:1010B00002F58218E63400F583E030E503432601AB -:1010C00078A9E62405F58218E63400F583E030E0DF -:1010D00003120FB7E526FC78A9E6240BF58218E683 -:1010E0003400F583ECF078A9E62405F58218E6349F -:1010F00000F583740FF078AA8683088682E0448026 -:10110000F0A3A3A3A3E04480F0228C2A120F6978F5 -:10111000A7E62408F58218E63400F583E0FC78A9F8 -:10112000E6240AF58218E63400F583ECF078A7E6A9 -:101130002407F58218E63400F583E0FC78A9E6245C -:1011400009F58218E63400F583ECF078A68683086A -:101150008682E0FDA3E0FCEDFE78A9E62408F58296 -:1011600018E63400F583EEF0ECFE78A9E62407F5E6 -:101170008218E63400F583EEF08C298D28C3EC94B8 -:1011800005ED940C400575277C8033D3E529940147 -:10119000E5289403400575273C8023D3E5299481F5 -:1011A000E528940140057527188013D3E52994603C -:1011B000E5289400400575270C8003752708AF27A4 -:1011C000E4EF547C4483FF8F27E527FC78ABE624CB -:1011D00001F58218E63400F583ECF0E527FC78ABE6 -:1011E000E62405F58218E63400F583ECF0E527FCEB -:1011F00078A3E624A4F8ECF678A9E62402F5821890 -:10120000E63400F583E0F52778A7E62402F5821896 -:10121000E63400F583A3E030E3175327C778A7E649 -:101220002405F58218E63400F583E09035589342A2 -:10123000275327FB78A7E62406F58218E63400F545 -:1012400083E060034327045327FC78A7E62404F5D2 -:101250008218E63400F583E04227432780E527FC27 -:1012600078A9E62402F58218E63400F583ECF078DC -:10127000A9E62404F58218E63400F583E0F5277822 -:10128000A7E62402F58218E63400F583A3E030E1F6 -:10129000055327DF800343272078A7E62402F58241 -:1012A00018E63400F583E030E4055327EF8003436C -:1012B000271078A7E62409F58218E63400F583E0C4 -:1012C000B40203432702E527FC78A9E62404F5824B -:1012D00018E63400F583ECF078A9E62403F58218CB -:1012E000E63400F583E0F52778A7E62409F58218AF -:1012F000E63400F583E0700553277F8003432780A1 -:1013000078A7E62402F58218E63400F583A3E030DE -:10131000E00543272080035327DF78A7E62402F562 -:101320008218E63400F583E030E30543274080036C -:101330005327BF78A7E62402F58218E63400F58328 -:10134000E030E00543271080035327EF78A7E62419 -:1013500002F58218E63400F583A3E030E405432764 -:101360000880035327F778A7E62402F58218E634AD -:1013700000F583A3E030E50543270480035327FBF2 -:1013800078A7E62402F58218E63400F583A3E0305E -:10139000E60543270180035327FE78A7E62402F5DC -:1013A0008218E63400F583A3E030E7054327028086 -:1013B000035327FDE527FC78A9E62403F58218E608 -:1013C0003400F583ECF0C2037C00228D278C26EDDF -:1013D00054031460037C1022E527547C24FC400352 -:1013E0007C0B22E526249DF8C64402F67C00228C64 -:1013F00030120F69E530249DF8E620E24FAC307DD5 -:1014000002120D2FE53024FE4428FC78AA868308BA -:101410008682ECF0AF83E5822404FEE43FFFEC8E8D -:10142000828F83F07C038C2CE52CFC78ABE62401C6 -:10143000F58218E63400F583ECF0E52CFC78ABE699 -:101440002405F58218E63400F583ECF0752D01755E -:101450002F48752EFFE53024FDFCE434FFFDEC7CC5 -:101460000325E0CD33CDDCF9FCE52F2CF52FE52E5F -:101470003DF52E78ABE62404F58218E63400F583BA -:10148000E054E7F52CAD2FAE2EAF2DE49000021204 -:101490000317E49000061203171201E630E5034338 -:1014A0002C10E52CFC78ABE62404F58218E6340019 -:1014B000F583ECF012104B78A9E62406F58218E6C5 -:1014C0003400F583E0C203FCE530249DF8C64404F3 -:1014D000F68C2CE530540FC454F07E00FFEEEF4440 -:1014E000047D00FFEC4EFCED4FFD121CA77C00229A -:1014F0008C2F120F69120FEB78AA8683088682E080 -:101500005408F0A3A3A3A3E05408F0AC2F7D02126B -:101510000D2FC203E52F249DF8C654FBF67C002254 -:101520001230E67896ECF6EC249DF8E630E10A7D80 -:10153000007C131225261231697896E6249DF8C6A0 -:101540004401F67896E6FC120F697896E624FD755C -:10155000F00AA42414F582E434FCF58378A6E6FAB4 -:1015600008E6F97B0A78011203A778A68683088625 -:101570008279677A357B0A78011203F5120FB7C2B8 -:10158000037896E6FC1211077895ECF6EC600A7D7C -:10159000007C081225261231697896E6FC120F6944 -:1015A00078A9E62404F58218E63400F583E04410B7 -:1015B00054DFFC78A9E62404F58218E63400F583AC -:1015C000ECF07895ECF6C2037CC81232A97896E666 -:1015D000FC120F6978A9E62404F58218E63400F5B8 -:1015E00083E054EFF0C2037CC81232A97896E6FC7F -:1015F000120F6978A9E62404F58218E63400F58311 -:10160000E04410F0C2037CC81232A97896E6FC12BE -:101610000F6978A9E62404F58218E63400F583E022 -:101620004420F0C2037CF01232A97896E6FC120F37 -:101630006978A9E62405F58218E63400F583E030E0 -:10164000E415C2037896E644107F00FE7C07123151 -:10165000FB12316902171478A9E62404F58218E612 -:101660003400F583E054CFF0C2037CC81232A9786D -:1016700096E6FC120F6978A9E62404F58218E63490 -:1016800000F583E04430F0C2037CF01232A9789672 -:10169000E6FC120F6978A9E62405F58218E6340005 -:1016A000F583E030E414C2037896E644107F00FE30 -:1016B0007C071231FB123169805D78A9E62404F5BC -:1016C0008218E63400F583E054EFF078A9E62404AC -:1016D000F58218E63400F583E054DFF07896E624CE -:1016E000FD75F00AA42414F582E434FCF583AC8281 -:1016F000AD8378A68683088682ECF9EDFA7B0A78BA -:10170000011203A7C2037896E6FC1211077D007C44 -:101710000B122526123169221230E6E490FC39F0D2 -:101720007D027C00122526123169221230E67C00EF -:101730001225BF12316922743C90FBE0F0743E9098 -:10174000FBE0F0E490FC28F0228D358C34ECB40101 -:10175000028003D340028028B402028003D34008F1 -:10176000A835C625E0F68018B404028003D3400AE9 -:10177000A835C625E025E0F68006A835760080006D -:10178000228C3C8D3BEDFEECFD7F01756606756796 -:101790000090FC2912046E1201E6B480028006D388 -:1017A000500302184790FC29120480900003120194 -:1017B000EC54F0B430028003D3405F90FC29120453 -:1017C0008090000812020EFAFDEBFE7F0190FC2CC7 -:1017D00012046EEECD903571FCE493FF740193FE1C -:1017E000F9EFFA7B01EAFFE9FEECC39EED9F40258D -:1017F000903573E493FD740193FCEDFEECFD7F01E5 -:10180000EECDFC90FC2EE0D39C90FC2DE09D50058D -:101810007566808033121965802EB460028003D310 -:10182000400BAC3CAD3B1207778C66801BB41003B9 -:10183000B34010C3B42003B34009C3B440028003D3 -:10184000D3400075668180008075B481028003D327 -:10185000406B90FC291204809000031201EC54F0BC -:10186000B430028003D3401D90FC29120480900004 -:101870000812020EFAFDEBFE7F0190FC2F12046E9F -:101880001218CF8036B460028003D34013753A67D4 -:10189000E4F539F538AC3CAD3B1205D38C66801BC2 -:1018A000B41003B34010C3B42003B34009C3B44021 -:1018B000028003D34000756681800080028000E5CD -:1018C00066FC90FC29120480EC900002120317AC15 -:1018D000672290FC291204809000041201EC60043D -:1018E00074018001E4A2E0920190FC29120480EDD1 -:1018F0002403FD50010E90FC2C12046E90FC291262 -:1019000004809000051201ECF5679000041201ECD0 -:10191000540FFC7D67121746E56770047566082250 -:10192000756600788476007884E6C39567503890B1 -:10193000FC2F1204801201E6FC90FC2C120480ECB7 -:1019400012030F30010E90FC31E004F090FC307077 -:1019500003E004F078840690FC2EE004F090FC2D67 -:101960007003E004F080C02290FC2AE0FDA3E0FCBC -:10197000EDFEECFD7F01ED240AFD50010E90FC32DE -:1019800012046E90FC291204809000041201EC54A1 -:101990000FB401028003D3401790FC321204800D73 -:1019A000ED70010E90FC2F12046E78887601804E47 -:1019B000B402028003D3401990FC32120480ED245B -:1019C00002FD50010E90FC2F12046E788876028082 -:1019D0002DB404028003D3401990FC32120480ED30 -:1019E0002404FD50010E90FC2F12046E78887604BA -:1019F000800CB400028003D340007566082290FC7E -:101A0000291204809000051201ECF56778857600B4 -:101A10007885E6C395674003021ACD78867600780C -:101A200086E6C3788896507690FC2C1204801201CA -:101A3000E6FC90FC321204891201E0F45CFC120115 -:101A4000E0F890FC2F120480E8C0E01201E6C8D054 -:101A5000E0C8584CFC90FC2C120480EC12030F7868 -:101A600087ECF690FC31E004F090FC307003E00469 -:101A7000F009E970010A90FC3212047790FC2912F7 -:101A800004809000041201EC30E40E90FC2EE0047F -:101A9000F090FC2D7003E004F07886068081788851 -:101AA000E6FDE4FEFFEECDFC90FC31E02CF090FC76 -:101AB00030E03DF07888E6FDE4FEFFEECDFC90FCE2 -:101AC00034E02CF090FC33E03DF0788506021A0DEE -:101AD00075660022E53D053D047002B2B022C0E00B -:101AE000C0F0C082C083C0D0E8C0E0E9C0E0EAC076 -:101AF000E0EBC0E0ECC0E0EDC0E0EEC0E0EFC0E045 -:101B000090FF92E01201B71B29301B29321B383895 -:101B10001B4A3A1B5C3E1B74441B68461B80501BCF -:101B2000C2521BA1541BE35600001C0490FF92E01C -:101B30007F00FE7C011231FB021C14E4FF04FE7CDA -:101B4000031231FB742090FFFEF0021C14E4FF042A -:101B5000FE7C021231FB744090FFFEF0021C14E484 -:101B6000FF04FE7C041231FB021C14E4FF04FE7C23 -:101B7000051231FB021C14E4FF04FE7C061231FB4B -:101B8000021C1490FFA5E07D0090FBF8CDF0A3CDE2 -:101B9000F090FBF9E0FCF58390FBF8E04433FD1294 -:101BA0001CA7807390FFB5E07D0090FBFACDF0A3F9 -:101BB000CDF090FBFBE0FCF58390FBFAE04443FDA5 -:101BC000121CA7805290FFA6E07D0090FBFCCDF098 -:101BD000A3CDF090FBFDE0FCF58390FBFCE04434EA -:101BE000FD121CA7803190FFB6E07D0090FBFECD7A -:101BF000F0A3CDF090FBFFE0FCF58390FBFEE0440A -:101C000044FD121CA7801090FF92E07D00FCED4483 -:101C1000AAFD121CA78000E490FF92F0D0E0FFD054 -:101C2000E0FED0E0FDD0E0FCD0E0FBD0E0FAD0E078 -:101C3000F9D0E0F8D0D0D083D082D0F0D0E0320517 -:101C400081058105810581A881181818EDF608EC39 -:101C5000F690FF5AE020E70280F790FF59E07D0000 -:101C6000A88118CDF6CD08F67D03A881E618FCE61C -:101C7000CC25E0CC33CCDDF9CCF6CC08F6A8811825 -:101C8000E644F8F6A881181818E6FD08E6FCA881D5 -:101C9000188683088682EDF0A3ECF0740290FF5A58 -:101CA000F0158115811581158122E5812405F581C5 -:101CB000E4A88118F6A88118181818EDF608ECF6B3 -:101CC00090FBF5E024F85003021DC8E4A881181821 -:101CD000F6A88118E6FEA88118181818E6FD08E68F -:101CE000FC7F00EF24F8404DE4EF25E0247DF582F1 -:101CF000E434FCF583E0FBA3E06C7003FAEB6D7059 -:101D0000097401A8811818F6802BE4EF25E0247DE2 -:101D1000F582E434FCF5837A00E054F0CCF8CCCDC5 -:101D2000F9CDFB7800E954F0F9EA687002EB6970CC -:101D3000010E0F80AEA88118EEF6A88118181818A9 -:101D4000EDF608ECF6A881EFF6A8811818E6707990 -:101D5000A88118E624F74071A88118181818E654CD -:101D60000FA881F664046017A881E664036010A8D8 -:101D70008118181818E6FD08E6FC121C3C804A7C05 -:101D80000A12315BA88118181818E6FD08E6FC90C5 -:101D9000FBF4E025E0247DF582E434FCF583EDF0EE -:101DA000A3ECF090FBF4E0FFE4EF045407FF90FB9A -:101DB000F4F090FBF5E004F01231F490FBF6E070E3 -:101DC00008E4FEFF7C0F1231FB802790FBF7E00454 -:101DD000F0543F701D90FBF7E044FE7D00FC90FB4B -:101DE000F4E025E0247DF582E434FCF583EDF0A3F6 -:101DF000ECF0E58124FBF58122788B7600788C76F7 -:101E000000740190FBF6F01230E690FBF5E06057AD -:101E10007C0A12315B90FBF3E025E0247DF582E43F -:101E200034FCF583E0FDA3E0FC90FBF3E025E02427 -:101E30007DF582E434FCF583E4F0A3F090FBF3E05D -:101E4000FFE4EF045407FF90FBF3F090FBF5E01480 -:101E5000F07889EDF608ECF61231F47889E6FD08A1 -:101E6000E6FC1208DA80A312324890FF93E04401A6 -:101E7000F0B2B3788B06B60011788B7600788CE6DA -:101E8000F40404A2E092B4788CF6021E07E490FBFE -:101E9000F6F090FBF5E07D00FCED44CFFD121C3C1C -:101EA000123169221230E6E5706449456F60159081 -:101EB000FF83E0540F7D00D39570ED956F500512B0 -:101EC0002F2F8003122FFF123169221230E6E570A6 -:101ED0006449456F6005123039800E90FF80E04400 -:101EE00008F090FF83E0547FF0123169221230E64F -:101EF0008C54EC54F0B41015756A357569FC75682E -:101F000001E56A2403F56AE5693400F569E4F557EB -:101F1000F556E556C394015027E554540FFCAD6ABD -:101F2000AE69AF68120E778C55EC60028012056ABC -:101F3000E56A700205690557E5577002055680D2BB -:101F4000E554540F249DF8C654FEF6E554540F7F13 -:101F500000FE7C121231FBE5551470097D007C09EE -:101F60001225268007AD577C0012252612316922E2 -:101F70001230E690FFFCE04402F090FF00E030E712 -:101F80001390FF83E04480F0436D8090FFFCE044B9 -:101F900001F0801190FF82E04408F0536D7F90FFC4 -:101FA000FCE054FEF090FF81E04480F01225D990CF -:101FB000FFFEE04405F090FFFCE054FDF0123169B3 -:101FC000221230E67C011232A978ADE64402F674A2 -:101FD000FEFC04FD121CA790FF5AE030E70280F7D8 -:101FE000E4F54E754D10AC4EAD4DE54E154E7002FC -:101FF000154DEC4D600280EE4387011231692212CB -:1020000030E67C0212317578ADE654FDF612316986 -:10201000221230E678ADE630E02C78ADE630E126ED -:1020200078ADE6FCF58318E644F0FD121C3C90FF09 -:10203000FCE04420F07C021232A978ADE654FDF6B3 -:10204000741A90FFFEF078ADE6FCF58318E644F1D3 -:10205000FD121C3C12316922756D0090FFFFE0609B -:1020600003436D01756E00E4F56CF56BE4F56F7577 -:102070007049748490FF82F0748490FF80F07480C3 -:1020800090FF58F0748090FF5AF0AD46AF457E0047 -:10209000EE24FE5003022124E4EE75F007A4247F11 -:1020A000F582E434F8F583E0FFE4EF5480FDE4EFDB -:1020B000540F14FFED6038E4EF75F008A42448F5E0 -:1020C00082E434FFF5837490F0E4EF75F008A42403 -:1020D0004AF582E434FFF5837480F0E4EF75F0088C -:1020E000A4244EF582E434FFF5837480F08034E458 -:1020F000EF75F008A42408F582E434FFF5837490AA -:10210000F0E4EF75F008A4240AF582E434FFF583C7 -:10211000E4F0E4EF75F008A4240EF582E434FFF552 -:1021200083E4F00E02208D8D468E448F45747F909F -:10213000FFFDF0749090FFFCF0228C58EC24F650D8 -:1021400006E5582437FC22E5582430FC22122523CA -:10215000EC700302225E755C03AE5B7F00E55C15EC -:102160005C6480247F5035EF2400F582E434FBF575 -:1021700083E0FE24FE501EEF7D00FCE4FB7474C37C -:102180009CFAEB9DFBEE7D00FCEAC39CED6480CBEA -:1021900064809B50028005EF2EFF80C18E5B8F5ABA -:1021A000E55C6480247F500302225EE55A248E5051 -:1021B0000302225E855A5D755B00AE5AAF5B9035B7 -:1021C0009CE493F55CE55C155C6480247F5018EE1C -:1021D0002400F582E434FBF583E0FCEF90359C931A -:1021E0006C70040E0F80DE8E5A8F5BE55C64802479 -:1021F0007F406E755E017560E8755FFFE55D2402E6 -:10220000F55A755C07E55C334057AD60AE5FAF5E75 -:10221000E55CF5823395E0F5831201ECC4540FFCC4 -:10222000122137E55A2400F582E434FBF583ECF003 -:10223000055A055AAD60AE5FAF5EE55CF582339539 -:10224000E0F5831201EC540FFC122137E55A24000B -:10225000F582E434FBF583ECF0055A055A155C80F1 -:10226000A4740290F851F090F86B79757A357B2759 -:1022700078011203F5756A357569FC756801E4909B -:10228000FF83F0748090FF81F0755902E55975F075 -:1022900007A4247FF582E434F8F583E0788FF6FC18 -:1022A000540F14FC788FECF6E55975F007A42481DF -:1022B000F582E434F8F583E0789276FD0876E8FC60 -:1022C000788FE675F008A42448F582E434FFF5839E -:1022D000E4F0788FE675F008A4244FF582E434FF2B -:1022E000F583ECF07892E6FF08E67E03CFC313CFC8 -:1022F00013DEF9FE788FE675F008A42449F582E430 -:1023000034FFF583EEF0788FE675F008A4244AF5E3 -:1023100082E434FFF5837480F07890ECF67D0078E9 -:1023200093E62CF618E63DF67892E6FD08E67C0387 -:10233000CDC313CD13DCF9FC788FE675F008A42427 -:102340004DF582E434FFF583ECF0788FE675F00804 -:10235000A4244EF582E434FFF583E4F07892E6FDA0 -:1023600008E6FC788FE6FF7E00EE24FE5003022490 -:10237000DDE4EE75F007A4247FF582E434F8F583FC -:10238000E0FFE4EF5480FAE4EF540F14FFE4EE753D -:10239000F007A42481F582E434F8F583E07890F620 -:1023A000E4EE1313548024F0F8E434FDF9E8FCE97A -:1023B000FD8A5AEA700302244AE4EF75F008A42467 -:1023C00048F582E434FFF583E4F07890E6FAE4EF30 -:1023D00075F008A4244FF582E434FFF583EAF0EDAC -:1023E000FBEC7A03CBC313CB13DAF9FAE4EF75F005 -:1023F00008A42449F582E434FFF583EAF07890E6F6 -:102400007B00FAEC2AFCED3BFDFBEC7A03CBC3131B -:10241000CB13DAF9FAE4EF75F008A4244DF582E461 -:1024200034FFF583EAF0E4EF75F008A4244AF5825E -:10243000E434FFF5837480F0E4EF75F008A4244ED3 -:10244000F582E434FFF5837480F00224D9E4EF755B -:10245000F008A42408F582E434FFF583E4F07890D2 -:10246000E6FAE4EF75F008A4240FF582E434FFF5F2 -:1024700083EAF0EDFBEC7A03CBC313CB13DAF9FA62 -:10248000E4EF75F008A42409F582E434FFF583EA4B -:10249000F07890E67B00FAEC2AFCED3BFDFBEC7A51 -:1024A00003CBC313CB13DAF9FAE4EF75F008A424D5 -:1024B0000DF582E434FFF583EAF0E4EF75F008A44B -:1024C000240AF582E434FFF583E4F0E4EF75F008C4 -:1024D000A4240EF582E434FFF583E4F00E022366B3 -:1024E0008E597892EDF608ECF6788FEFF6122055BB -:1024F000228C26EC30E718E526540F1475F008A45A -:102500002448F582E434FFF583E054DFF08016E5DB -:1025100026540F1475F008A42408F582E434FFF55E -:1025200083E054DFF0227C0022EC90FC37F08C2416 -:10253000ED2403F5257D00D39572ED95714003855B -:102540007225E52524B75009752503740290FC37E0 -:10255000F0AC2512302422E4F56CF56B12255D22D7 -:1025600090FC35E06573600E740490FC37F0E4F580 -:102570006B756C0380467D73E4FEFF79357AFC7BD6 -:10258000017405780012033FE56C2403F56CE56BDC -:102590003400F56BE56CD39572E56B95714006855B -:1025A000726C85716BD3E56C9448E56B9400400CBC -:1025B000740290FC37F0E4F56B756C03AC6C123070 -:1025C0002422EC90FC37F0E4F56CF56B8C32EC6077 -:1025D0000512301580057C001230242290FF93E014 -:1025E0004401F0B2B390FF04E0F54A90FF06E0FD2D -:1025F000A3E0ED7D00FC7D00FC90FF06E0FFA3E082 -:102600007E00FFE4FEEC4EFCED4FFDC3EC9448ED84 -:102610009400502290FF06E0FDA3E0ED7D00FC7DDC -:1026200000FC90FF06E0FFA3E07E00FFE4FEEC4E1E -:10263000FCED4FFD8004E4FD7C488C728D7190FFB1 -:1026400002E0FDA3E0ED7D00FC7D00FC90FF02E0D8 -:10265000FFA3E07E00FFE4FEEC4EF54CED4FF54BA2 -:10266000756A357569FC7568017D357EFC7F017979 -:1026700073E4FAFB7405780012033F754900E549DD -:1026800024FE4019AD6AAE69AF68E412030F054934 -:102690000DED70010E8D6A8E698F6880E1756A3567 -:1026A0007569FC75680190FF00E05460B400028019 -:1026B00006D35003022C6DE54A540FF549E54A5400 -:1026C00080A2E0920290FF01E0120181000B2C68D1 -:1026D00026E528032C68290F2C6829F22A262B8D41 -:1026E0002B902BD02C112C3FE56D30E70EE54C459F -:1026F0004B7008E572640245716003022C6A90FF1A -:1027000000E0541FB400028003D34029E54A60036F -:10271000022800AD6AAE69AF68740112030F78AD8C -:10272000E630E00BAD6AAE69AF68740212030F7C4D -:102730000212302422B401028003D3401BE56D2035 -:10274000E107E54A6003022800E54A24FE5003023F -:1027500028007C0212302422B402028006D35003E7 -:102760000227FEE56D20E10DE54A6009E54A648037 -:102770006003022800AC4A1230AB4003022800E597 -:1027800049702530021190FF80E05408AD6AAE69AF -:10279000AF6812030F800F90FF82E05408AD6AAE5D -:1027A00069AF6812030F803D154930021DE5497578 -:1027B000F008A42448F582E434FFF583E05408AD22 -:1027C0006AAE69AF6812030F801BE54975F008A473 -:1027D0002408F582E434FFF583E05408AD6AAE695D -:1027E000AF6812030FAD6AAE69AF681201E6600B05 -:1027F000AD6AAE69AF68740112030F7C0212302417 -:10280000228000022C6AE56D20E706E572457160C2 -:1028100003022C6A90FF00E0541FB400028003D32F -:10282000401AE54C14454B7004E54A600302290C3C -:1028300078ADE654FEF67C0012302422B40102800A -:1028400003D3402AE56D20E108E56D20E00302296D -:102850000CE56D30E004E54A700BE56D30E109E50B -:102860004A24FE500302290C7C0012302422B402B8 -:10287000028006D3500302290AE54C454B6003024F -:10288000290CAC4A1230AB400302290CE56D20E163 -:1028900007E56D20E0028077E56D30E006E54960F0 -:1028A00002806CE549700F90FF82E054F7F090FFD2 -:1028B00080E054F7F022E549B401028003D34009D7 -:1028C0007D017C03120F098011B402028003D34002 -:1028D000097D017C04120F0980001549300215E5BD -:1028E0004975F008A42448F582E434FFF583E054E8 -:1028F000F7F08013E54975F008A42408F582E43464 -:10290000FFF583E054F7F07C0012302422800002AF -:102910002C6AE56D20E706E57245716003022C6ABA -:1029200090FF00E0541FB400028003D3401AE54C2E -:1029300014454B7004E54A60030229EF78ADE64484 -:1029400001F67C0012302422B401028003D3402916 -:10295000E56D20E108E56D20E0030229EFE56D302B -:10296000E004E549700BE56D30E108E54924FE50CF -:1029700002807F7C0012302422B402028003D34004 -:102980006FE54C454B60028069AC4A1230AB4002A7 -:102990008060E56D20E107E56D20E0028054E549A7 -:1029A000701430020990FF80E04408F0800790FF27 -:1029B00082E04408F022E56D30E13315493002151C -:1029C000E54975F008A42448F582E434FFF583E076 -:1029D0004408F08013E54975F008A42408F582E462 -:1029E00034FFF583E04408F07C001230242280029A -:1029F0008000022C6AE56D20E712E5724571700CCB -:102A0000E54A700890FF00E0541F6003022C6AE55D -:102A10004C90FFFFF090FFFFE06005436D018003E5 -:102A2000536DFE7C0012302422E56D30E70EE57216 -:102A30004571600890FF00E0541F6003022C6AADEE -:102A40004BE54CED7D00FC7D00FCBD0002800302E7 -:102A50002B88B401028003D34032E54A7005E54C6F -:102A6000FC6003022B8A756A407569F8756801D3AA -:102A7000E5729412E57194004006E4FD7C12800436 -:102A8000AC72AD718C708D6F12303922B40202803D -:102A900003D34059E54A6003022B8AE54CFC7027BA -:102AA000756A527569F8756801D3E5729419E57114 -:102AB00094004006E4FD7C198004AC72AD718C700A -:102AC0008D6F1230398025756A6B7569F8756801EC -:102AD000D3E5729427E57194004006E4FD7C2780DD -:102AE00004AC72AD718C708D6F12303922B4030258 -:102AF0008006D35003022B88E54CF549700F90FFF8 -:102B000004E0FDA3E04D6003022B8A801890FB02D5 -:102B1000E0FDA3E0FC90FF05E06C700790FF04E08F -:102B20006D60028068E4F570F56F7F00E54914C5BB -:102B300049600FEF2400F582E434FBF583E02FFFBA -:102B400080EA8F4AE54A2400F582E434FBF583E00D -:102B50007D00D39572ED95714006AC72AD71800F1A -:102B6000E54A2400F582E434FBF583E07D00FC8C2B -:102B7000708D6FE54A2400FCE434FBFDFEECFD7F24 -:102B8000018D6A8E698F68123039228000022C6AAA -:102B9000022C6AE56D30E719E5721445717012E593 -:102BA0004A700EE54C454B700890FF00E0541F60E2 -:102BB00003022C6AE56D20E008E56D20E103022C9C -:102BC0006A756A6EE4F569F568E4F56F04F57012EC -:102BD000303922E56D20E712E5724571700CE54A47 -:102BE000700890FF00E0541F6003022C6AE56D201E -:102BF000E007E56D20E1028074854C6EE56E70089B -:102C0000436D01536DFD8006536DFE436D027C00E4 -:102C100012302422E56D30E71AE572144571701305 -:102C2000E54A700FE54C454B700990FF00E0541FDA -:102C30001460028038E56D20E10280317C011230A1 -:102C40002422E56D20E715E5724571700FE54C45CE -:102C50004B700990FF00E0541F146002800FE56D77 -:102C600020E10280087C00123024228000022F2BF9 -:102C7000B440028006D35003022F2190FF01E09060 -:102C8000FC35F0E54A90FC36F0E490FC37F0E56A5C -:102C90002403F56AE5693400F569AD4BE54C856AB6 -:102CA00082856983CDF0A3CDF090FF01E01201B7DA -:102CB0002CD8012CFE022D28032D52042DA0052D09 -:102CC000DD062E03072E29082E55092E7B0B2EA17B -:102CD0000C2EB0802EB08100002F0EE56D20E7068F -:102CE0007C051225BF227D247E357F0279387AFC4F -:102CF0007B017408780012033F7D087C00122526B2 -:102D000022E56D20E7067C051225BF22E54AB403C3 -:102D1000004010B40500500BE54A7F00FE7C101205 -:102D200031FB227D007C0712252622E56D20E70677 -:102D30007C051225BF22E54AB403004010B405000B -:102D4000500BE54A7F00FE7C111231FB227D007C96 -:102D50000712252622E56D20E7067C051225BF22F5 -:102D6000E54AB405028003D3400AE4FF04FE7C0A6E -:102D70001231FB22B401028003D3400AE4FF04FEB7 -:102D80007C081231FB22B403004010B40500500B44 -:102D9000E54A7F00FE7C131231FB227D007C071286 -:102DA000252622E56D20E734D3E5729448E5719439 -:102DB000005006E572457170067C021225BF22E5BF -:102DC0004AB40103B3400BC3B403004009B4060086 -:102DD00050041230D1227C071225BF2212255D2219 -:102DE000E56D20E71DE54AB403004010B40500502E -:102DF0000BE54A7F00FE7C161231FB227C07122570 -:102E0000BF2212255D22E56D20E71DE54AB40300CF -:102E10004010B40500500BE54A7F00FE7C191231CA -:102E2000FB227C071225BF2212255D22E56D20E7DB -:102E300023748190FF93F0E54AB403004010B40579 -:102E400000500BE54A7F00FE7C171231FB227C0705 -:102E50001225BF2212255D22E56D20E71DE54AB44B -:102E600003004010B40500500BE54A7F00FE7C18BB -:102E70001231FB227C071225BF2212255D22E56D4F -:102E800020E71DE54AB403004010B40500500BE5EF -:102E90004A7F00FE7C151231FB227C071225BF22DF -:102EA00012255D22E56D20E7067C071225BF221260 -:102EB000255D22E56D30E72090FF00E0541F701083 -:102EC00090FF01E0B48005122554800312255D2295 -:102ED0007D007C051225262290FF00E0541F60062D -:102EE0007C051225BF22D3E5729448E57194005009 -:102EF0000BC3E5729407E571940050067C0312251C -:102F0000BF22E54AB405041230D1227C071225BF46 -:102F100022E56D30E7087D007C05122526227C0520 -:102F20001225BF22B420028003D340008000122F5C -:102F3000FF2275430090FF83E0540FD39543402454 -:102F4000E54324F0F582E434FEF583E0AD6AAE6932 -:102F5000AF6812030F05430DED70010E8D6A8E6987 -:102F60008F6880D1E5437D00FCC3E5709CF570E57A -:102F70006F9DF56FE570456F6006E490FF83F0226A -:102F800090FF82E04408F0E4F56F75704990FC35DD -:102F9000E0B405028003D3404090FC36E0F543B432 -:102FA00005028003D3400AE4FF04FE7C0B1231FBD0 -:102FB00022B401028003D3400AE4FF04FE7C09121C -:102FC00031FB22B403004010B40500500BE5437FF1 -:102FD00000FE7C141231FB2222B480004023B48214 -:102FE00000501E7C357DFC12177E7D008C6C8D6B35 -:102FF00090FC37E06005122FFF80057C0012302422 -:10300000222290FF83E0547FF090FF82E04408F09A -:1030100090FF80E04408F02290FF82E04408F090A6 -:10302000FF80E04408F0228C237D008C708D6F754A -:103030006A357569FC7568011230392290FF83E0AA -:10304000547FF0E5706449456F700122C3E57094C8 -:1030500008E56F94004015752108E5217D00FCC34B -:10306000E5709CF570E56F9DF56F8009857021E432 -:10307000F56F757049752200E522C395215026AD84 -:103080006AAE69AF681201E6FCE52224F8F582E435 -:1030900034FEF583ECF005220DED70010E8D6A8E85 -:1030A000698F6880D3E521547F90FF81F0228C489E -:1030B0007F00EF24FD4019E4EF75F007A4247FF5AD -:1030C00082E434F8F583E065487002D3220F80E291 -:1030D0008F47C32285727085716F90FF82E054F72D -:1030E000F090FF83E0547FF022C000C001C002C016 -:1030F00006C007E5782408F8860653067F7CFF1291 -:10310000315B7C007D00E57B6046FF90FD95E054DF -:103110007F6E700FC083C082A3E0FDA3E0FCA31507 -:103120007B8007A3A3A3DFE68026DF06D082D083BF -:10313000801EE0F8A3E0F9A3E0FAD082D083E8F0A3 -:10314000A3E9F0A3EAF0A3C083C082A3A3A380DA1B -:103150001231F4D007D006D002D001D0002285A8C9 -:103160007A75A888EC70027C3F8C7922E578240877 -:10317000F8760012324880FBC000C001C002C006D1 -:10318000C007AE047CFF12315BE57B6042FF90FD1F -:1031900095E0547F6E700BC083C082A3A3A3157B00 -:1031A0008007A3A3A3DFEA8026DF06D082D0838036 -:1031B000D8E0F8A3E0F9A3E0FAD082D083E8F0A346 -:1031C000E9F0A3EAF0A3C083C082A3A3A380DA78C6 -:1031D00008087918097C01E6547F6E70067600773E -:1031E00000800608090CBC08EE1231F4D007D006A6 -:1031F000D002D001D00022757900857AA822C0F0D3 -:10320000C082C083C3E57B24E8500512324880F4B5 -:10321000EC6031903523E493C39C4028C0047CFFCC -:1032200012315BD004430480E57B75F003A4249540 -:10323000F582E434FDF583ECF0EFA3F0EEA3F005A6 -:103240007B1231F4D083D082D0F022C0047C20D213 -:103250008CD28DD504FDD0042275A8007588007528 -:10326000B80075F00075D000E4F8900000F608B8DA -:1032700000FB020000C3ED940250047D037CE8ECE7 -:10328000F4FCEDF4FD0CBC00010D8C7F8D7E22C39F -:10329000EC94BCED940250047D077CD0ECF4FCED82 -:1032A000F4FD0CBC00010D8C7D8D7C22EC700122A4 -:1032B000C000E5782418F8A604E5782408F8C65478 -:1032C0007FF6E630E703D0002212324880F4C28C49 -:1032D000857C8C857D8AD28CC0E0C0D0C0F0C08255 -:1032E000C083C000C001C002C003C004C005C00646 -:1032F000C007121AD1E5782408F8E66024E578249E -:1033000010F8A681E57875F021A4248DF582E434C7 -:10331000FCF58378AEE58104C398F9E6F008A3D9FB -:10332000FA74082578F8057808E65480700CE5787A -:10333000B407F3780875780080EFE5782410F886F4 -:1033400081E57875F021A4248DF582E434FCF583C1 -:1033500078AEE58104C398F9E0F608A3D9FAD0075E -:10336000D006D005D004D003D002D001D000D08345 -:10337000D082D0F0D0D0D0E032C0E0C0D0C000C009 -:1033800001C002C28E857E8D857F8BD28E781979A1 -:10339000097A07E77004A600800BE6600816E6705D -:1033A00004E74480F70809DAEAE579601314F5794F -:1033B000700EE5782408F876001231F4D28CD28DA4 -:1033C000D002D001D000D0D0D0E0327581AD742AC7 -:1033D00090FF93F0757F30757EF8757D60757CF099 -:1033E00012053612347C12173490FF93E04401F03A -:1033F000B2B31234A612325680DA22C0007C01EC3D -:103400002408F8E660090CBC08F512324880EED0BA -:103410000022C0F0C082C083C000C006C007ED24F7 -:1034200010F876BCED75F021A4248DF582E434FC0F -:10343000F583C082C083A3A3E4780DF0A3D8FCEC8D -:10344000547F75F002A424EFF582E5F03434F5835F -:10345000E493FE740193F5828E83E493FE740193EA -:10346000FFD083D082EFF0A3EEF0ED2408F8EC4417 -:1034700080F6D007D006D000D083D082D0F022755D -:103480007800757B007A087918780876007700084C -:1034900009DAF8E478087480447FF674014410F582 -:1034A0008975B808D2ABD2A9227581ADD28ED28CE3 -:1034B000D2AFE57B6032FF90FD95E05480602478C8 -:1034C000087908E0547FFA7B00E6547FB502027B5E -:1034D000FF08D9F5EB700CEAF01233F8AD04AC023A -:1034E00012340FA3A3A3DFD212324880C57C017D22 -:1034F000002204F504E904ED04E104DD04D904E547 -:1035000004F1049D04A104CD04D104990499049903 -:1035100004D504B504AD04B104A904C104BD04B9C3 -:1035200004C504C904A5190103002200480200488B -:103530000E301420C81AD0180A0C05060203010226 -:103540000001CE0181010000C00080006000300059 -:1035500018001000080004000200010008183828B4 -:103560000C05100A0200000000000301100A02000E -:1035700000000000FBE0FBF209022700010200A0AE -:10358000320904000003FF0000000705810240002B -:103590000007050102400000070583030200012225 -:1035A0000354005500530042003300340031003012 -:1035B000002000200020002000200020002000200B -:0535C000000000000006 -:00000001FF diff --git a/firmware/ti_5052.fw.ihex b/firmware/ti_5052.fw.ihex deleted file mode 100644 index b529e07cd6ec906350d6f6d2a4544e94426012c1..0000000000000000000000000000000000000000 --- a/firmware/ti_5052.fw.ihex +++ /dev/null @@ -1,862 +0,0 @@ -:10000000C1350002001E021B32FFFFFFFFFF02325C -:100010006AFFFFFFFFFFFFFFFFFFFFFFFFFF02334E -:10002000157581C890FEF08583A012347DEC4D607B -:100030006A78A58003760018B896FA7879800376F6 -:100040000018B85FFA78208003760018B820FA907C -:10005000FEE5AE83AF8290FD001200A16005E4F0E2 -:10006000A380F690FEF0A88290FEF0A982E8C399E2 -:10007000500576000880F69000FF1200AA90010358 -:100080001200AA9001071200AA90010B1200C8905A -:1000900001111200C89001171200C875D000123368 -:1000A0006702011DEF65827003EE658322E493F819 -:1000B000740193F9740293FE740393F5828E83E8BE -:1000C00069700122E493F6A30880F4E493FC7401C0 -:1000D00093FD740293FE740393FF740493F8740504 -:1000E00093F58288831200A1700122E493A3A88370 -:1000F000A9828C838D82F0A3AC83AD8288838982B0 -:1001000080E3212104927A7A0492A6A80492FEF058 -:1001100004940494FBFB04990494FBFB04F904F994 -:1001200080FED0F030F00920F303F68010F7800D48 -:1001300030F10920F303F28004F38001F020F4048D -:10014000FCD0E0CC22CCC0E012015A02014BBC0032 -:1001500005D0F0ACF022C313DCFC020121BF000982 -:10016000ED258275F001F8E622BF010FED2582F53D -:1001700082EE3583F58375F004E022ED258275F07B -:1001800002F8E222D083D082F5F0C3E493A3C5F055 -:1001900095F0C0E0C3D0F0E493A395F04012A3A380 -:1001A000C3E5F033500205832582F58250020583B2 -:1001B000740193C0E0E493C0E022D083D082F5F0D4 -:1001C000E49370097401937004A3A3800C740293E8 -:1001D00065F06005A3A3A380E7740193C0E0E493F6 -:1001E000C0E02212025B0201F21202AF0201F2121F -:1001F00002D30201F230E00720E302E622E72230D8 -:10020000E10720E302E222E32230E202E022E4936B -:10021000221202D302021A1202AF02021AABF01229 -:100220000224CBC5F0CB2230E01020E306E6F5F047 -:1002300008E622E7F5F009E7192230E11020E3068D -:10024000E2F5F008E222E3F5F009E3192230E206D4 -:10025000E0F5F0A3E022E493F5F074019322BB00F3 -:1002600003740922BB010789828A83740422BB02BA -:100270000789828A83741022740A2202027BBB00DF -:1002800007E92582F8740122BB010DE92582F58278 -:10029000EA3583F583740422BB020DE92582F582D9 -:1002A000EA3583F583741022E92582F8740222026C -:1002B00002AFBF0005EDF8740122BF01078D828EE9 -:1002C00083740422BF02078D828E83741022EDF89E -:1002D0007402220202D3BF0007ED2582F8740122C6 -:1002E000BF010DED2582F582EE3583F5837404227E -:1002F000BF020DED2582F582EE3583F58374102261 -:10030000ED2582F8740222020307C0E012025B02AC -:10031000031FC0E01202AF02031FC0E01202D302AB -:10032000031F30E00B20E304D0E0F622D0E0F722F8 -:1003300030E10B20E304D0E0F222D0E0F322D0E061 -:10034000F022C9CDC9CACECACBCFCB120352EDF928 -:10035000EEFAEFFB22BB002FBF000AFAEDF8E7F63A -:100360000809DAFA22BF01128D828E83F802036F28 -:1003700009A3E7F0D8FA2202037AFAEDF8E7F208C7 -:1003800009DAFA22020384BB014DBF001489828A74 -:1003900083F9EDF802039608A3E0F6D9FA220203E6 -:1003A000A7BF01228D828E83FB08C9C582C9CAC539 -:1003B00083CAE0A3C9C582C9CAC583CAF0A3DBEA60 -:1003C000D8E8220203CA8D828E83F9EDF8E0F208A4 -:1003D000A3D9FA220203D4BB024DBF001289828A3C -:1003E00083F9EDF80203E608A3E493F6D9F922BFF6 -:1003F00001238D828E83FB08C9C582C9CAC583CA01 -:10040000E493A3C9C582C9CAC583CAF0A3DBE9D8EE -:10041000E72202041989828A83F9EDF8E493F2084D -:10042000A3D9F92202042ABF000DFAEDF8E3F60879 -:1004300009DAFA22020434BF01128D828E83F80297 -:10044000044109A3E3F0D8FA2202044CFAEDF8E3E0 -:10045000F20809DAFA22020456E6FB08E6FA08E690 -:10046000F904F61870010622E6FF08E6FE08E6FD2C -:1004700022EFF0A3EEF0A3EDF022EBF0A3EAF0A35D -:10048000E9F022E0FFA3E0FEA3E0FD22E0FBA3E011 -:10049000FAA3E0F9220000000000000004F9005B6C -:1004A00005730026059A00330A0B005B0A7700608B -:1004B0001552005B0CFB005B09AB005B09E2005BC3 -:1004C0000DC2005B0BF3005B0A1E005B0A53005B6E -:1004D000174A0033176000341E4D00431EF00044DD -:1004E000205D0044204B00471F1700471FBC004DF4 -:1004F000200D004F1F39005831F5005B7CCC7DFF8B -:10050000121CFE22749090FF91F090FFFCE020E717 -:100510002DC2AFAE59AF58755A20E55A14C55A606E -:1005200019E4FE7F05EE4FCE24FFCECF34FFCF601F -:1005300007E490FF92F080ED80E08E598F582212F0 -:1005400005017D077CB71232117D0F7C6E12322BB4 -:1005500078977A06E4F608DAFC7A061205CF7C036F -:10056000120E577C04120E5712218BE4FEFF7C0FF3 -:1005700012319AD2A822123085E490FD40F090FF0B -:10058000F0E030E408740190FD41F08005E490FD56 -:1005900041F07D0A7C001224B1123108221230850C -:1005A00090FD41E014700E90FFF0E04410F07C00EC -:1005B00012254A801990FD41E0700E90FFF0E05442 -:1005C000EFF07C0012254A80057C1712254A123173 -:1005D000082290FFF0E054ABF090FFF0E04420F0F0 -:1005E000228C378D36787CEDF608ECF6EDFEECFDCE -:1005F0007F019000051201EC787AF6787CE6FD0820 -:10060000E6FCEDFEECFD7F019000041201EC540FBE -:10061000FC7D7A12179D787AE6700DAD3AAE39AF4F -:1006200038E412030F7C082290FFF0E054FEF090B3 -:10063000FFF0E054FDF0801E787CE6FD08E6FCED5E -:10064000FEECFD7F0190000812020E25E0440190AF -:10065000FFF3F00206DB787CE6FD08E6FCEDFEEC3D -:10066000FD7F0190000612020E54FE90FFF3F08011 -:100670002B787CE6FD08E6FCEDFEECFD7F019000AA -:100680000812020EFAEB90FFF1F01208CA400DAD0D -:100690003AAE39AF38E412030F7C1822787CE6FDBD -:1006A00008E6FCEDFEECFD7F0190000812020E90C2 -:1006B000FFF1F01208CA400DAD3AAE39AF38E4127E -:1006C000030F7C1822787CE6FD08E6FCEDFEECFDCD -:1006D0007F0190000612020E440190FFF3F0787D36 -:1006E000E62403F618E63400F6787AE624FE50098C -:1006F00090FFF0E054FDF0800790FFF0E04402F03E -:10070000E490FFF1F0787B7600787AE624FFFCE451 -:1007100034FFFD787BE67F00FEECD39EEF6480CD56 -:1007200064809D402F1208AF400F787BE6AD3AAE53 -:1007300039AF3812030F7C182290FFF2E0FC787C6E -:100740008683088682ECF0787B06A3787CA68308F3 -:10075000A68280B51208AF400F787BE6AD3AAE397D -:10076000AF3812030F7C182290FFF2E0FC787C86F1 -:1007700083088682ECF0787AE6AD3AAE39AF38126B -:10078000030F7C00228C378D36787CEDF608ECF672 -:10079000EDFEECFD7F019000051201EC787BF67810 -:1007A0007CE6FD08E6FCEDFEECFD7F019000041206 -:1007B00001EC540FFC7D7B12179D787BE670037C67 -:1007C000082290FFF0E054FEF090FFF0E054FDF0BE -:1007D000801B787CE6FD08E6FCEDFEECFD7F0190D9 -:1007E000000812020E25E090FFF3F0805B787CE6B3 -:1007F000FD08E6FCEDFEECFD7F0190000612020E06 -:1008000054FE90FFF3F08021787CE6FD08E6FCEDD5 -:10081000FEECFD7F0190000812020EFAEB90FFF152 -:10082000F01208CA40037C1822787CE6FD08E6FC3A -:10083000EDFEECFD7F0190000812020E90FFF1F03A -:100840001208CA40037C1822787DE6240AF618E6CE -:100850003400F6787A7600787BE624FFFCE434FFF7 -:10086000FD787AE67F00FEECD39EEF6480CD648055 -:100870009D4021787C8683088682E090FFF1F0120B -:1008800008CA40037C1822787A06787D06E618703C -:10089000010680C390FFF0E04401F0787C86830875 -:1008A0008682E090FFF1F01208CA40037C18227C97 -:1008B000002290FFF0E020E71290FFF0E030E50921 -:1008C00090FFF0E04420F0C32280E7D32290FFF0B5 -:1008D000E020E31290FFF0E030E50990FFF0E04403 -:1008E00020F0C32280E7D3228C428D417C00ED545E -:1008F000F0FDEC7003ED64307005753E0380037508 -:100900003E04AC3E120F7C758300858340E5415464 -:100910000FF53FE5407004E53F64037035E53E2484 -:10092000FD75F00AA4240AF582E434FDF583E03075 -:10093000E6051210678019E53E2497F8C654FBF6C9 -:1009400078A3E62405F58218E63400F583740FF0E9 -:100950008059E5407004E53F64047048E53E24FD9D -:1009600075F00AA4240AF582E434FDF583E030E54D -:1009700007AC42AD41121C93E54230E21578A7E680 -:1009800030E00F78A7E630E109E4FF04FE7C0412B2 -:10099000319A78A3E62406F58218E63400F58374CC -:1009A0000FF08007E4FC7DEE121C93C2032212308C -:1009B00085120F7C78A3E62406F58218E63400F54C -:1009C00083E090FD40F078A3E62405F58218E63434 -:1009D00000F583E090FD41F0C2037D027C0012240B -:1009E000B112310822123085788FECF6EC2497F89A -:1009F000E630E1077C1312254A800F90FD41E0FDAF -:100A0000788FE6FC1213FD12254A123108221230AB -:100A100085788FECF67D00120F0B12254A123108F3 -:100A200022123085788FECF6EC2497F8E630E20756 -:100A30007C1312254A801B788FE62497F8E620E184 -:100A4000077C1212254A800A788FE6FC12142112C4 -:100A5000254A12310822123085788FECF6EC249763 -:100A6000F8E620E2077C1112254A800A788FE6FC1E -:100A700012152212254A12310822123085788FEC85 -:100A8000F6120F7C78A3E62409F58218E63400F507 -:100A900083E090FD47F078A3E6240AF58218E63457 -:100AA00000F583E090FD48F078A3E62403F5821872 -:100AB000E63400F583E0FC78A3E62404F58218E62A -:100AC0003400F583E0F55C78A3E62402F58218E6AD -:100AD0003400F583E0F55D8C5BE4EC33335401784E -:100AE0008FF66008E55C30E103788F06788FE6903A -:100AF000FD49F078A1E62402F58218E63400F5837A -:100B0000E0FDA3E0540CFCED54E68C5FF55EE55B84 -:100B100030E503435F01E55C20E50EE55B547F7043 -:100B200008E55B20E703435F02E55B30E303435FD7 -:100B300010E55B30E203435F20E55B540360034351 -:100B40005F40E55B30E103435F80E55B30E40343F6 -:100B50005E01E55B30E603435E08E55C20E40EE5FC -:100B60005B547F7008E55B20E703435E10535FFB37 -:100B7000535EF9AD5EE55F90FD42CDF0A3CDF0E5AB -:100B80005D30E30DE55D5430C4540F90FD45F080B9 -:100B900005E490FD45F0E55D540390FD44F0E55D0E -:100BA0005404C31390FD46F090FD44E0700E7D3D6B -:100BB0007EFD7F01740190000912014278A3E624B2 -:100BC00008F58218E63400F583E07C00FD78A3E6A2 -:100BD0002407F58218E63400F583E07F004CFEEF31 -:100BE0004D90FD40F0A3CEF0CEC2037D0A7C0012F2 -:100BF00024B112310822123085788FECF678947681 -:100C0000010876FD0876407891760C789412046598 -:100C10001202147892CBF6CB08F67F00EF24EB405B -:100C20001FE4EF25E09034BFFD93CD0493789366E5 -:100C30007003ED186670067891760080030F80DCF3 -:100C40007890EFF6789412046590000212020E7804 -:100C500092CBF6CB08F65404CB54064B6004789143 -:100C6000760B7893E630E3137894120465900005D0 -:100C70001201EC24FB50047891760D7893E654C071 -:100C80007D0064C04D70047891760B7894120465F1 -:100C90009000041201EC24FC50047891760F7894B3 -:100CA0001204659000061201EC24FD500478917640 -:100CB0000E78941204659000091201EC24FD500492 -:100CC0007891760A7891E6702A788FE6FC120F7C8C -:100CD000789412046578A1E6F978A0E6FA7B0174AD -:100CE0000A780012033FC203788FE6FC12112378C2 -:100CF00091ECF67891E6FC12254A12310822123066 -:100D000085788FECF6120F7C788FE624FD75F00A5B -:100D1000A4241CF582E434FDF583AC82AD8378A075 -:100D20008683088682ECF9EDFA7B0A78011203A724 -:100D3000C203788FE6FC121123123108228D2B8C0E -:100D40002AED60407527017529487528FFE52A249A -:100D5000FDFCE434FFFDEC7C0325E0CD33CDDCF974 -:100D6000FCE5292CF529E5283DF528AD29AE28AF6D -:100D700027748090000612031774809000021203FB -:100D800017120FD3E52B14603B75270175290875E1 -:100D900028FFE52A24FDFCE434FFFDEC7C0325E07C -:100DA000CD33CDDCF9FCE5292CF529E5283DF528E6 -:100DB000AD29AE28AF27E4900006120317E4900097 -:100DC0000212031722123085788FECF6EC2497F884 -:100DD000E630E209788FE6FC121522D200788FE621 -:100DE000FC120F7C7890760090FD41E030E70478AB -:100DF0009076017890E6FD788FE6FC120D3AC203FA -:100E0000300007788FE6FC1214217C0012254A126C -:100E100031082278A3E62404F58218E63400F5832D -:100E2000E04401F078A3E62404F58218E63400F5E6 -:100E300083E030E00280ED78A3E6240BF58218E62B -:100E40003400F583E054F8F078A3E62402F5821824 -:100E5000E63400F583E04480F022C2038C58120F80 -:100E60007C78A0868308868279EE7A347B0A7801C2 -:100E70001203F5120E10AC587D02120D3AC203ACEB -:100E800058121123228D538E528F518C50120F7C89 -:100E9000754F0078A3E62405F58218E63400F58343 -:100EA000E020E416E54F24F64010054FC2037C18FD -:100EB000123248AC50120F7C80D978A3E62405F595 -:100EC0008218E63400F583E020E405C2037C0222A8 -:100ED00078A3E62405F58218E63400F583E0540F84 -:100EE000601678A3E62405F58218E63400F583E061 -:100EF000540FF0C2037C012278A28683088682E028 -:100F0000AD53AE52AF5112030FC2037C00228D319C -:100F10008C30121522E5316020E530B4030C7C01E1 -:100F200012247C7C8112247C800FE530B4040A7C7E -:100F30000212247C7C8212247CAC30120F7CE531BE -:100F4000601A78A48683088682E054E7F0A3A3A3FE -:100F5000A3E054E7F0AC307D02120D3A78A086830E -:100F600008868279F87A347B0A78011203F5C20385 -:100F7000E5302497F8C654FDF6AC30121123228CCC -:100F8000263003051231E780F87C0A1230FAD203CA -:100F9000E52624FD789DF6700978A476FF0876E0B2 -:100FA000800778A476FF0876E2789DE675F010A4B5 -:100FB000ADF0FC24A078A3F6ED34FF18F6789DE69A -:100FC00075F00AA42408FCE434FDFD78A0EDF608D1 -:100FD000ECF61231932278A3E62402F58218E63467 -:100FE00000F583E030E72278A3E62402F58218E6D4 -:100FF0003400F583E0547FF078A3E62402F58218EC -:10100000E63400F583E04480F02278A486830886E5 -:1010100082E0547FF0AD83E5822404FCE43D8C82C1 -:10102000F583E0547FF078A3E6240BF58218E634CC -:1010300000F583E054F8F078A5E62401F58218E67F -:101040003400F583E04403F078A5E62405F5821822 -:10105000E63400F583E04403F078A3E62405F58246 -:1010600018E63400F583740FF02278A4868308868E -:1010700082E0543FF0AD83E5822404FCE43D8C82A1 -:10108000F583E0543FF0789DE6249EF8E6FC78A5D1 -:10109000E62401F58218E63400F583ECF0789DE64D -:1010A000249EF8E6FC78A5E62405F58218E63400CF -:1010B000F583ECF078A3E6240BF58218E63400F50E -:1010C00083E054FB4402F52678A1E62402F5821859 -:1010D000E63400F583E030E50343260178A3E624F7 -:1010E00005F58218E63400F583E030E003120FD3F3 -:1010F000E526FC78A3E6240BF58218E63400F58398 -:10110000ECF078A3E62405F58218E63400F5837444 -:101110000FF078A48683088682E04480F0A3A3A31E -:10112000A3E04480F0228C2A120F7C78A1E62408E8 -:10113000F58218E63400F583E0FC78A3E6240AF58E -:101140008218E63400F583ECF078A1E62407F582F6 -:1011500018E63400F583E0FC78A3E62409F582184C -:10116000E63400F583ECF078A08683088682E0FD03 -:10117000A3E0FCEDFE78A3E62408F58218E634002F -:10118000F583EEF0ECFE78A3E62407F58218E6344A -:1011900000F583EEF08C298D28C3EC9402ED9406C3 -:1011A000400575277C8033D3E5299481E528940197 -:1011B000400575273C8023D3E52994C0E528940099 -:1011C00040057527188013D3E5299430E52894004D -:1011D000400575270C8003752708AF27E4EF547C82 -:1011E0004483FF8F27E527FC78A5E62401F58218C4 -:1011F000E63400F583ECF0E527FC78A5E62405F558 -:101200008218E63400F583ECF0E527FC789DE624AF -:101210009EF8ECF678A3E62402F58218E63400F591 -:1012200083E0F52778A1E62402F58218E63400F57C -:1012300083A3E030E3175327C778A1E62405F5829E -:1012400018E63400F583E09034E993422778A1E66C -:101250002402F58218E63400F583E030E7054327E1 -:101260004080035327BF5327FB78A1E62406F5826D -:1012700018E63400F583E060034327045327FC7825 -:10128000A1E62404F58218E63400F583E042274302 -:101290002780E527FC78A3E62402F58218E63400CF -:1012A000F583ECF078A3E62404F58218E63400F523 -:1012B00083E0F52778A1E62402F58218E63400F5EC -:1012C00083A3E030E1055327DF800343272078A183 -:1012D000E62402F58218E63400F583E030E4055395 -:1012E00027EF800343271078A1E62409F58218E64A -:1012F0003400F583E0B40203432702E527FC78A31A -:10130000E62404F58218E63400F583ECF078A3E6D1 -:101310002403F58218E63400F583E0F52778A1E68A -:101320002409F58218E63400F583E0700553277F21 -:10133000800343278078A1E62402F58218E6340072 -:10134000F583A3E030E00543272080035327DF78AF -:10135000A1E62402F58218E63400F583E030E305C7 -:1013600043274080035327BF78A1E62402F5821863 -:10137000E63400F583E030E005432710800353276F -:10138000EF78A1E62402F58218E63400F583A3E0A5 -:1013900030E40543270880035327F778A1E62402A9 -:1013A000F58218E63400F583A3E030E50543270411 -:1013B00080035327FB78A1E62402F58218E6340067 -:1013C000F583A3E030E60543270180035327FE7829 -:1013D000A1E62402F58218E63400F583A3E030E7A5 -:1013E0000543270280035327FDE527FC78A3E62465 -:1013F00003F58218E63400F583ECF0C2037C00228A -:101400008D278C26ED54031460037C1022E52754AD -:101410007C24FC40037C0B22E5262497F8C644027A -:10142000F67C00228C30120F7CE5302497F8E62001 -:10143000E24FAC307D02120D3AE53024FE4428FC28 -:1014400078A48683088682ECF0AF83E5822404FECC -:10145000E43FFFEC8E828F83F07C038C2CE52CFC28 -:1014600078A5E62401F58218E63400F583ECF0E572 -:101470002CFC78A5E62405F58218E63400F583EC0B -:10148000F0752D01752F48752EFFE53024FDFCE425 -:1014900034FFFDEC7C0325E0CD33CDDCF9FCE52FFA -:1014A0002CF52FE52E3DF52E78A5E62404F58218BF -:1014B000E63400F583E054E7F52CAD2FAE2EAF2DCA -:1014C000E4900002120317E49000061203171201C1 -:1014D000E630E503432C10E52CFC78A5E62404F562 -:1014E0008218E63400F583ECF012106778A3E62446 -:1014F00006F58218E63400F583E0C203FCE53024EB -:1015000097F8C64404F68C2CE530540FC454F07E92 -:1015100000FFEEEF44047D00FFEC4EFCED4FFD12AA -:101520001CFE7C00228C2F120F7C12100778A486E0 -:1015300083088682E05408F0A3A3A3A3E05408F034 -:10154000AC2F7D02120D3AC203E52F2497F8C65442 -:10155000FBF67C00221230857890ECF6EC2497F8AC -:10156000E630E10A7D007C131224B1123108789034 -:10157000E62497F8C64401F67890E6FC120F7C78D2 -:1015800090E624FD75F00AA4241CF582E434FDF5F0 -:101590008378A0E6FA08E6F97B0A78011203A778B7 -:1015A000A0868308868279F87A347B0A7801120350 -:1015B000F5120FD3C2037890E6FC121123788FEC5A -:1015C000F6EC600A7D007C081224B1123108789094 -:1015D000E6FC120F7C78A3E62404F58218E63400BA -:1015E000F583E0441054DFFC78A3E62404F5821868 -:1015F000E63400F583ECF0788FECF6C2037CC81279 -:1016000032487890E6FC120F7C78A3E62404F58239 -:1016100018E63400F583E054EFF0C2037CC81232C0 -:10162000487890E6FC120F7C78A3E62404F5821833 -:10163000E63400F583E04410F0C2037CC81232485F -:101640007890E6FC120F7C78A3E62404F58218E675 -:101650003400F583E04420F0C2037CF01232487875 -:1016600090E6FC120F7C78A3E62405F58218E63498 -:1016700000F583E030E415C2037890E644107F0063 -:10168000FE7C0712319A12310802174978A3E6242A -:1016900004F58218E63400F583E054CFF0C2037CF1 -:1016A000C81232487890E6FC120F7C78A3E6240436 -:1016B000F58218E63400F583E04430F0C2037CF094 -:1016C0001232487890E6FC120F7C78A3E62405F5E8 -:1016D0008218E63400F583E030E414C2037890E623 -:1016E00044107F00FE7C0712319A123108805D7829 -:1016F000A3E62404F58218E63400F583E054EFF005 -:1017000078A3E62404F58218E63400F583E054DF7C -:10171000F07890E624FD75F00AA4241CF582E434E8 -:10172000FDF583AC82AD8378A08683088682ECF9D0 -:10173000EDFA7B0A78011203A7C2037890E6FC1247 -:1017400011237D007C0B1224B11231082212308546 -:1017500090FF91E090FD41F07D027C001224B112D7 -:1017600031082212308590FD40E0F4FC90FF91E0BA -:101770005CF53390FD41E0FC90FD40E05C4233E5D8 -:101780003390FF91F07C0012254A12310822743CFC -:1017900090FBE8F0743E90FBE8F0E490FD30F0221E -:1017A0008D358C34ECB401028003D340028028B420 -:1017B00002028003D34008A835C625E0F68018B49D -:1017C00004028003D3400AA835C625E025E0F68050 -:1017D00006A83576008000228C3C8D3BEDFEECFDAA -:1017E0007F0175600675610090FD3112046E120173 -:1017F000E6B480028006D3500302189E90FD311299 -:1018000004809000031201EC54F0B430028003D342 -:10181000405F90FD3112048090000812020EFAFD24 -:10182000EBFE7F0190FD3412046EEECD903502FC8C -:10183000E493FF740193FEF9EFFA7B01EAFFE9FEFE -:10184000ECC39EED9F4025903504E493FD74019315 -:10185000FCEDFEECFD7F01EECDFC90FD36E0D39C6F -:1018600090FD35E09D500575608080331219BC8075 -:101870002EB460028003D3400BAC3CAD3B12078218 -:101880008C60801BB41003B34010C3B42003B3407A -:1018900009C3B440028003D340007560818000809A -:1018A00075B481028003D3406B90FD3112048090A7 -:1018B00000031201EC54F0B430028003D3401D90B9 -:1018C000FD3112048090000812020EFAFDEBFE7F3B -:1018D0000190FD3712046E1219268036B460028022 -:1018E00003D34013753A61E4F539F538AC3CAD3BB0 -:1018F0001205DE8C60801BB41003B34010C3B4200B -:1019000003B34009C3B440028003D3400075608133 -:10191000800080028000E560FC90FD31120480ECC4 -:10192000900002120317AC612290FD3112048090E6 -:1019300000041201EC600474018001E4A2E0920151 -:1019400090FD31120480ED2403FD50010E90FD3412 -:1019500012046E90FD311204809000051201ECF526 -:10196000619000041201EC540FFC7D6112179DE59B -:1019700061700475600822756000787E7600787E5C -:10198000E6C39561503890FD371204801201E6FCE1 -:1019900090FD34120480EC12030F30010E90FD39DB -:1019A000E004F090FD387003E004F0787E0690FDCE -:1019B00036E004F090FD357003E004F080C0229022 -:1019C000FD32E0FDA3E0FCEDFEECFD7F01ED240A1D -:1019D000FD50010E90FD3A12046E90FD311204800C -:1019E0009000041201EC540FB401028003D340179D -:1019F00090FD3A1204800DED70010E90FD37120437 -:101A00006E78827601804EB402028003D340199032 -:101A1000FD3A120480ED2402FD50010E90FD3712B4 -:101A2000046E78827602802DB404028003D34019BC -:101A300090FD3A120480ED2404FD50010E90FD3714 -:101A400012046E78827604800CB400028003D340C6 -:101A5000007560082290FD3112048090000512018B -:101A6000ECF561787F7600787FE6C39561400302EC -:101A70001B24788076007880E6C378829650769032 -:101A8000FD341204801201E6FC90FD3A1204891222 -:101A900001E0F45CFC1201E0F890FD37120480E8EC -:101AA000C0E01201E6C8D0E0C8584CFC90FD3412EA -:101AB0000480EC12030F7881ECF690FD39E004F01D -:101AC00090FD387003E004F009E970010A90FD3AD6 -:101AD00012047790FD311204809000041201EC3062 -:101AE000E40E90FD36E004F090FD357003E004F064 -:101AF00078800680817882E6FDE4FEFFEECDFC90E2 -:101B0000FD39E02CF090FD38E03DF07882E6FDE410 -:101B1000FEFFEECDFC90FD3CE02CF090FD3BE03D67 -:101B2000F0787F06021A6475600022E53D053D04E9 -:101B30007002B2B022C0E0C0F0C082C083C0D0E862 -:101B4000C0E0E9C0E0EAC0E0EBC0E0ECC0E0EDC01E -:101B5000E0EEC0E0EFC0E090FF92E01201B71B8022 -:101B6000301B80321B8F381BA13A1BB33E1BCB446A -:101B70001BBF461BD7501C19521BF8541C3A560069 -:101B8000001C5B90FF92E07F00FE7C0112319A0204 -:101B90001C6BE4FF04FE7C0312319A742090FFFE5C -:101BA000F0021C6BE4FF04FE7C0212319A74409038 -:101BB000FFFEF0021C6BE4FF04FE7C0412319A026B -:101BC0001C6BE4FF04FE7C0512319A021C6BE4FFDF -:101BD00004FE7C0612319A021C6B90FFA5E07D008A -:101BE00090FD00CDF0A3CDF090FD01E0FCF58390D9 -:101BF000FD00E04433FD121CFE807390FFB5E07DD4 -:101C00000090FD02CDF0A3CDF090FD03E0FCF58344 -:101C100090FD02E04443FD121CFE805290FFA6E0BE -:101C20007D0090FD04CDF0A3CDF090FD05E0FCF526 -:101C30008390FD04E04434FD121CFE803190FFB619 -:101C4000E07D0090FD06CDF0A3CDF090FD07E0FC17 -:101C5000F58390FD06E04444FD121CFE801090FFC9 -:101C600092E07D00FCED44AAFD121CFE8000E49091 -:101C7000FF92F0D0E0FFD0E0FED0E0FDD0E0FCD05D -:101C8000E0FBD0E0FAD0E0F9D0E0F8D0D0D083D0BB -:101C900082D0F0D0E0320581058105810581A881DF -:101CA000181818EDF608ECF690FF6AE020E70280BD -:101CB000F790FF69E07D00A88118CDF6CD08F67D8C -:101CC00003A881E618FCE6CC25E0CC33CCDDF9CCCA -:101CD000F6CC08F6A88118E644F8F6A8811818187A -:101CE000E6FD08E6FCA881188683088682EDF0A34D -:101CF000ECF0740290FF6AF0158115811581158151 -:101D000022E5812405F581E4A88118F6A881181838 -:101D10001818EDF608ECF690FBFDE024F8500302ED -:101D20001E1FE4A8811818F6A88118E6FEA88118DD -:101D3000181818E6FD08E6FC7F00EF24F8404DE493 -:101D4000EF25E02485F582E434FDF583E0FBA3E094 -:101D50006C7003FAEB6D70097401A8811818F68095 -:101D60002BE4EF25E02485F582E434FDF5837A0049 -:101D7000E054F0CCF8CCCDF9CDFB7800E954F0F983 -:101D8000EA687002EB6970010E0F80AEA88118EE50 -:101D9000F6A88118181818EDF608ECF6A881EFF6E9 -:101DA000A8811818E67079A88118E624F74071A870 -:101DB0008118181818E6540FA881F664046017A853 -:101DC00081E664036010A88118181818E6FD08E67B -:101DD000FC121C93804A7C0A1230FAA88118181849 -:101DE00018E6FD08E6FC90FBFCE025E02485F58282 -:101DF000E434FDF583EDF0A3ECF090FBFCE0FFE4B0 -:101E0000EF045407FF90FBFCF090FBFDE004F012A0 -:101E1000319390FBFEE07008E4FEFF7C0F12319AD4 -:101E2000802790FBFFE004F0543F701D90FBFFE023 -:101E300044FE7D00FC90FBFCE025E02485F582E477 -:101E400034FDF583EDF0A3ECF0E58124FBF5812270 -:101E50007885760078867600740190FBFEF012306B -:101E60008590FBFDE060597C0A1230FA90FBFBE0A4 -:101E700025E02485F582E434FDF583E0FDA3E0FC54 -:101E800090FBFBE025E02485F582E434FDF583E456 -:101E9000F0A3F090FBFBE0FFE4EF045407FF90FB9E -:101EA000FBF090FBFDE014F07883EDF608ECF61201 -:101EB0003193B2B37883E6FD08E6FC1208E580A111 -:101EC0001231E7788506B60011788576007886E6C7 -:101ED000F40404A2E092B47886F68085E490FBFED8 -:101EE000F090FBFDE07D00FCED44CFFD121C931251 -:101EF000310822123085E56A64494569601590FF12 -:101F000083E0540F7D00D3956AED95695005122E3C -:101F1000CE8003122F9E12310822123085E56A64AA -:101F20004945696005122FD8800E90FF80E0440873 -:101F3000F090FF83E0547FF0123108221230858C3C -:101F400054EC54F0B4101575643D7563FD75620171 -:101F5000E5642403F564E5633400F563E4F557F5BF -:101F600056E556C394015027E554540FFCAD64AEBA -:101F700063AF62120E828C55EC600280120564E53C -:101F800064700205630557E5577002055680D2E577 -:101F900054540F2497F8C654FEF6E554540F7F00AE -:101FA000FE7C1212319AE5551470097D007C0912ED -:101FB00024B18007AD577C001224B11231082212DF -:101FC000308590FFFCE04402F090FF00E030E71322 -:101FD00090FF83E04480F043678090FFFCE0440181 -:101FE000F0801190FF82E04408F053677F90FFFC7F -:101FF000E054FEF090FF81E04480F012256490FFF1 -:10200000FEE04405F090FFFCE054FDF012310822A0 -:102010001230857C0112324878A7E64402F674FE3D -:10202000FC04FD121CFE90FF6AE030E70280F7E43A -:10203000F54E754D10AC4EAD4DE54E154E7002157A -:102040004DEC4D600280EE438701123108221230C0 -:10205000857C0212311478A7E654FDF6123108226D -:1020600012308578A7E630E02C78A7E630E12678B4 -:10207000A7E6FCF58318E644F0FD121C9390FFFCE4 -:10208000E04420F07C0212324878A7E654FDF67452 -:102090001A90FFFEF078A7E6FCF58318E644F1FD00 -:1020A000121C9312310822756700756800E4F5660A -:1020B000F565E4F569756A49748490FF82F074846B -:1020C00090FF80F0748090FF68F0748090FF6AF059 -:1020D000AD46AF457E00EE24FC500302216AE4EEDB -:1020E00075F007A4243FF582E434FCF583E0FFE4B7 -:1020F000EF5480FDE4EF540F14FFED6038E4EF750A -:10210000F008A42448F582E434FFF5837490F0E4E9 -:10211000EF75F008A4244AF582E434FFF583748057 -:10212000F0E4EF75F008A4244EF582E434FFF58363 -:102130007480F08034E4EF75F008A42408F582E49C -:1021400034FFF5837490F0E4EF75F008A4240AF5E9 -:1021500082E434FFF583E4F0E4EF75F008A4240E84 -:10216000F582E434FFF583E4F00E0220D38D468E31 -:10217000448F45747F90FFFDF0749090FFFCF090C9 -:10218000FC19E030E60790FFFCE04404F02290FCEC -:102190000DE014700490FC0CE0703990FC0079069E -:1021A0007A357B1278011203F57F00EF334015EF8B -:1021B00090354D93FCEF2480F582E434FCF583ECFC -:1021C000F00F80E78F5990FC2B79187A357B3578A2 -:1021D000011203F5E490FFFFF0745190FFFAF074E0 -:1021E0000490FFFBF0745390FFF8F0745190FFF9E6 -:1021F000F0745590FFF7F0749390FFF6F0743290FE -:10220000FFF5F075643D7563FD756201E490FF8331 -:10221000F0748090FF81F0755804E55875F007A4BC -:10222000243FF582E434FCF583E07889F6FC540F12 -:1022300014FC7889ECF6E55875F007A42441F58282 -:10224000E434FCF583E0788C76F8087600FC788935 -:10225000E675F008A42448F582E434FFF583E4F041 -:102260007889E675F008A4244FF582E434FFF583FD -:10227000ECF0788CE6FF08E67E03CFC313CF13DEC5 -:10228000F9FE7889E675F008A42449F582E434FF64 -:10229000F583EEF07889E675F008A4244AF582E427 -:1022A00034FFF5837480F0788AECF67D00788DE653 -:1022B0002CF618E63DF6788CE6FD08E67C03CDC3E7 -:1022C00013CD13DCF9FC7889E675F008A4244DF5EC -:1022D00082E434FFF583ECF07889E675F008A424F5 -:1022E0004EF582E434FFF583E4F0788CE6FD08E6F1 -:1022F000FC7889E6FF7E00EE24FC500302246BE4A8 -:10230000EE75F007A4243FF582E434FCF583E0FF8A -:10231000E4EF5480FAE4EF540F14FFE4EE75F00795 -:10232000A42441F582E434FCF583E0788AF6EE7566 -:10233000F080A42408F8E5F034F8F9E8FCE9FD8A17 -:1023400059EA70030223D8E4EF75F008A42448F595 -:1023500082E434FFF583E4F0788AE6FAE4EF75F07E -:1023600008A4244FF582E434FFF583EAF0EDFBEC9A -:102370007A03CBC313CB13DAF9FAE4EF75F008A4B0 -:102380002449F582E434FFF583EAF0788AE67B009D -:10239000FAEC2AFCED3BFDFBEC7A03CBC313CB1329 -:1023A000DAF9FAE4EF75F008A4244DF582E434FF7D -:1023B000F583EAF0E4EF75F008A4244AF582E434EA -:1023C000FFF5837480F0E4EF75F008A4244EF582E5 -:1023D000E434FFF5837480F0022467E4EF75F008BD -:1023E000A42408F582E434FFF583E4F0788AE6FA61 -:1023F000E4EF75F008A4240FF582E434FFF583EAD6 -:10240000F0EDFBEC7A03CBC313CB13DAF9FAE4EF6C -:1024100075F008A42409F582E434FFF583EAF07826 -:102420008AE67B00FAEC2AFCED3BFDFBEC7A03CB61 -:10243000C313CB13DAF9FAE4EF75F008A4240DF511 -:1024400082E434FFF583EAF0E4EF75F008A4240A8F -:10245000F582E434FFF583E4F0E4EF75F008A4249A -:102460000EF582E434FFF583E4F00E0222F48E5878 -:10247000788CEDF608ECF67889EFF61220A4228C21 -:1024800026EC30E718E526540F1475F008A424480C -:10249000F582E434FFF583E054DFF08016E526543E -:1024A0000F1475F008A42408F582E434FFF583E0E6 -:1024B00054DFF022EC90FD3FF08C24ED2403F52551 -:1024C0007D00D3956CED956B4003856C25E5252447 -:1024D000B75009752503740290FD3FF0AC25122F0B -:1024E000C322E4F566F5651224E82290FD3DE0651F -:1024F0006D600E740490FD3FF0E4F5657566038031 -:10250000467D6DE4FEFF793D7AFD7B017405780020 -:1025100012033FE5662403F566E5653400F565E5DD -:1025200066D3956CE565956B4006856C66856B6535 -:10253000D3E5669448E5659400400C740290FD3F35 -:10254000F0E4F565756603AC66122FC322EC90FDCE -:102550003FF0E4F566F5658C32EC6005122FB4802F -:10256000057C00122FC32290FF04E0F54A90FF067D -:10257000E0FDA3E0ED7D00FC7D00FC90FF06E0FFA8 -:10258000A3E07E00FFE4FEEC4EFCED4FFDC3EC94B7 -:1025900048ED9400502290FF06E0FDA3E0ED7D00A1 -:1025A000FC7D00FC90FF06E0FFA3E07E00FFE4FE60 -:1025B000EC4EFCED4FFD8004E4FD7C488C6C8D6B93 -:1025C00090FF02E0FDA3E0ED7D00FC7D00FC90FFAC -:1025D00002E0FFA3E07E00FFE4FEEC4EF54CED4F81 -:1025E000F54B75643D7563FD7562017D3D7EFD7F34 -:1025F00001796DE4FAFB7405780012033F75490018 -:10260000E54924FE4019AD64AE63AF62E412030FE6 -:1026100005490DED70010E8D648E638F6280E1754A -:10262000643D7563FD75620190FF00E05460B40085 -:10263000028006D35003022C12E54A540FF549E5F7 -:102640004A5480A2E0920290FF01E0120181000B47 -:102650002C0D266727852C0D28912C0D297429A86F -:102660002B0F2B122B522BB62BE4E56730E70EE530 -:102670004C454B7008E56C6402456B6003022C0FFF -:1026800090FF00E0541FB400028003D34029E54AC4 -:102690006003022782AD64AE63AF62740112030F60 -:1026A00078A7E630E00BAD64AE63AF62740212034C -:1026B0000F7C02122FC322B401028003D3401BE51A -:1026C0006720E107E54A6003022782E54A24FE50BD -:1026D000030227827C02122FC322B402028006D397 -:1026E0005003022780E56720E10DE54A6009E54ACD -:1026F00064806003022782AC4A12304A40030227FA -:1027000082E549702530021190FF80E05408AD64E5 -:10271000AE63AF6212030F800F90FF82E05408ADEA -:1027200064AE63AF6212030F803D154930021DE5B0 -:102730004975F008A42448F582E434FFF583E05499 -:1027400008AD64AE63AF6212030F801BE54975F0FC -:1027500008A42408F582E434FFF583E05408AD644E -:10276000AE63AF6212030FAD64AE63AF621201E6F7 -:10277000600BAD64AE63AF62740112030F7C021292 -:102780002FC3228000022C0FE56720E706E56C4589 -:102790006B6003022C0F90FF00E0541FB400028016 -:1027A00003D3401AE54C14454B7004E54A6003021C -:1027B000288E78A7E654FEF67C00122FC322B401BF -:1027C000028003D3402AE56720E108E56720E003A3 -:1027D00002288EE56730E004E54A700BE56730E1DA -:1027E00009E54A24FE500302288E7C00122FC322E2 -:1027F000B402028006D3500302288CE54C454B609E -:102800000302288EAC4A12304A400302288EE56744 -:1028100020E107E56720E0028077E56730E006E524 -:10282000496002806CE549700F90FF82E054F7F038 -:1028300090FF80E054F7F022E549B401028003D311 -:1028400040097D017C03120F0B8011B4020280034A -:10285000D340097D017C04120F0B80001549300222 -:1028600015E54975F008A42448F582E434FFF583A2 -:10287000E054F7F08013E54975F008A42408F582C8 -:10288000E434FFF583E054F7F07C00122FC322807C -:1028900000022C0FE56720E706E56C456B6003023C -:1028A0002C0F90FF00E0541FB400028003D3401AA5 -:1028B000E54C14454B7004E54A600302297178A782 -:1028C000E64401F67C00122FC322B401028003D338 -:1028D0004029E56720E108E56720E003022971E56A -:1028E0006730E004E549700BE56730E108E549240D -:1028F000FE5002807F7C00122FC322B402028003AC -:10290000D3406FE54C454B60028069AC4A12304AB7 -:1029100040028060E56720E107E56720E00280541F -:10292000E549701430020990FF80E04408F0800708 -:1029300090FF82E04408F022E56730E1331549302A -:102940000215E54975F008A42448F582E434FFF542 -:1029500083E04408F08013E54975F008A42408F5E5 -:1029600082E434FFF583E04408F07C00122FC32298 -:1029700080028000022C0FE56720E712E56C456BB2 -:10298000700CE54A700890FF00E0541F6003022CB1 -:102990000FE54C90FFFFF090FFFFE06005436701FB -:1029A00080035367FE7C00122FC322E56730E70ED9 -:1029B000E56C456B600890FF00E0541F6003022C3B -:1029C0000FAD4BE54CED7D00FC7D00FCBD000280B1 -:1029D00003022B0AB401028003D34032E54A70059A -:1029E000E54CFC6003022B0C7564007563FC75629A -:1029F00001D3E56C9412E56B94004006E4FD7C1273 -:102A00008004AC6CAD6B8C6A8D69122FD822B40235 -:102A1000028003D34059E54A6003022B0CE54CFCCD -:102A200070277564127563FC756201D3E56C9419A7 -:102A3000E56B94004006E4FD7C198004AC6CAD6B42 -:102A40008C6A8D69122FD8802575642B7563FC758F -:102A50006201D3E56C9435E56B94004006E4FD7C9F -:102A6000358004AC6CAD6B8C6A8D69122FD822B4A2 -:102A700003028006D35003022B0AE54CF549700F80 -:102A800090FF04E0FDA3E04D6003022B0C80189042 -:102A9000FC82E0FDA3E0FC90FF05E06C700790FF76 -:102AA00004E06D60028068E4F56AF5697F00E5493D -:102AB00014C549600FEF2480F582E434FCF583E00F -:102AC0002FFF80EA8F4AE54A2480F582E434FCF542 -:102AD00083E07D00D3956CED956B4006AC6CAD6BDF -:102AE000800FE54A2480F582E434FCF583E07D0024 -:102AF000FC8C6A8D69E54A2480FCE434FCFDFEEC24 -:102B0000FD7F018D648E638F62122FD822800002B8 -:102B10002C0F022C0FE56730E719E56C14456B703C -:102B200012E54A700EE54C454B700890FF00E054EA -:102B30001F6003022C0FE56720E008E56720E10332 -:102B4000022C0F756468E4F563F562E4F56904F539 -:102B50006A122FD822E56720E727E56C456B7021C4 -:102B6000E54A701DE54C6402454B600DE54C14458B -:102B70004B6006E54C454B700890FF00E0541F6029 -:102B800003022C0FE56720E008E56720E103022C33 -:102B90000F854C68E56870084367015367FD801333 -:102BA000E56864026007E56814600280655367FEAB -:102BB0004367027C00122FC322E56730E71AE56CF9 -:102BC00014456B7013E54A700FE54C454B70099046 -:102BD000FF00E0541F1460028038E56720E10280A6 -:102BE000317C01122FC322E56720E715E56C456BA8 -:102BF000700FE54C454B700990FF00E0541F1460C6 -:102C000002800FE56720E10280087C00122FC322BA -:102C10008000022ECAB440028006D35003022EC0A8 -:102C200090FF01E090FD3DF0E54A90FD3EF0E4901C -:102C3000FD3FF0E5642403F564E5633400F563AD1E -:102C40004BE54C856482856383CDF0A3CDF090FF86 -:102C500001E01201B72C7D012CA3022CCD032CF72F -:102C6000042D45052D82062DA8072DCE082DF4092B -:102C70002E1A0B2E400C2E4F802E4F8100002EADB1 -:102C8000E56720E7067C0512254A227DB77E347F62 -:102C90000279407AFD7B017408780012033F7D08B9 -:102CA0007C001224B122E56720E7067C0512254A44 -:102CB00022E54AB403004010B40500500BE54A7FFA -:102CC00000FE7C1012319A227D007C071224B12272 -:102CD000E56720E7067C0512254A22E54AB4030091 -:102CE0004010B40500500BE54A7F00FE7C11123104 -:102CF0009A227D007C071224B122E56720E7067C3A -:102D00000512254A22E54AB405028003D3400AE4AD -:102D1000FF04FE7C0A12319A22B401028003D340E0 -:102D20000AE4FF04FE7C0812319A22B4030040102A -:102D3000B40500500BE54A7F00FE7C1312319A2245 -:102D40007D007C071224B122E56720E734D3E56CCF -:102D50009448E56B94005006E56C456B70067C0268 -:102D600012254A22E54AB40103B3400BC3B4030061 -:102D70004009B406005004123070227C0712254A24 -:102D8000221224E822E56720E71DE54AB40300404B -:102D900010B40500500BE54A7F00FE7C1612319AF4 -:102DA000227C0712254A221224E822E56720E71D2B -:102DB000E54AB403004010B40500500BE54A7F001B -:102DC000FE7C1912319A227C0712254A221224E82D -:102DD00022E56720E71DE54AB403004010B4050072 -:102DE000500BE54A7F00FE7C1712319A227C0712B5 -:102DF000254A221224E822E56720E71DE54AB403AC -:102E0000004010B40500500BE54A7F00FE7C18120C -:102E1000319A227C0712254A221224E822E56720F3 -:102E2000E71DE54AB403004010B40500500BE54A25 -:102E30007F00FE7C1512319A227C0712254A22124D -:102E400024E822E56720E7067C0712254A2212249F -:102E5000E822E56730E72090FF00E0541F701090F3 -:102E6000FF01E0B480051224DF80031224E8227DF4 -:102E7000007C051224B12290FF00E0541F60067C04 -:102E80000512254A22D3E56C9448E56B9400500B5B -:102E9000C3E56C9407E56B940050067C0312254A49 -:102EA00022E54AB40504123070227C0712254A221A -:102EB000E56730E7087D007C051224B1227C05120D -:102EC000254A22B420028003D340008000122F9EA6 -:102ED0002275430090FF83E0540FD395434024E5CF -:102EE0004324F0F582E434FEF583E0AD64AE63AFD5 -:102EF0006212030F05430DED70010E8D648E638F1A -:102F00006280D1E5437D00FCC3E56A9CF56AE56912 -:102F10009DF569E56A45696006E490FF83F02290BB -:102F2000FF82E04408F0E4F569756A4990FD3DE0F0 -:102F3000B405028003D3404090FD3EE0F543B40564 -:102F4000028003D3400AE4FF04FE7C0B12319A2274 -:102F5000B401028003D3400AE4FF04FE7C0912316D -:102F60009A22B403004010B40500500BE5437F00E3 -:102F7000FE7C1412319A2222B480004023B48200D5 -:102F8000501E7C3D7DFD1217D57D008C668D6590B1 -:102F9000FD3FE06005122F9E80057C00122FC322AA -:102FA0002290FF83E0547FF090FF82E04408F0908D -:102FB000FF80E04408F02290FF82E04408F090FF98 -:102FC00080E04408F0228C237D008C6A8D69756452 -:102FD0003D7563FD756201122FD82290FF83E05486 -:102FE0007FF0E56A64494569700122C3E56A940887 -:102FF000E56994004015752108E5217D00FCC3E5D5 -:103000006A9CF56AE5699DF5698009856A21E4F5A0 -:1030100069756A49752200E522C395215026AD6481 -:10302000AE63AF621201E6FCE52224F8F582E434D7 -:10303000FEF583ECF005220DED70010E8D648E63BC -:103040008F6280D3E521547F90FF81F0228C487FEE -:1030500000EF24FB4019E4EF75F007A4243FF5824C -:10306000E434FCF583E065487002D3220F80E28FE0 -:1030700047C322856C6A856B6990FF82E054F7F044 -:1030800090FF83E0547FF022C000C001C002C00660 -:10309000C007E5722408F8860653067F7CFF1230CD -:1030A000FA7C007D00E5756046FF90FE9DE0547F50 -:1030B0006E700FC083C082A3E0FDA3E0FCA3157572 -:1030C0008007A3A3A3DFE68026DF06D082D083801B -:1030D0001EE0F8A3E0F9A3E0FAD082D083E8F0A3E1 -:1030E000E9F0A3EAF0A3C083C082A3A3A380DA120D -:1030F0003193D007D006D002D001D0002285A87429 -:1031000075A888EC70027C3F8C7322E5722408F865 -:1031100076001231E780FBC000C001C002C006C0CB -:1031200007AE047CFF1230FAE5756042FF90FE9D09 -:10313000E0547F6E700BC083C082A3A3A31575807B -:1031400007A3A3A3DFEA8026DF06D082D08380D83E -:10315000E0F8A3E0F9A3E0FAD082D083E8F0A3E995 -:10316000F0A3EAF0A3C083C082A3A3A380DA780807 -:10317000087918097C01E6547F6E700676007700A6 -:10318000800608090CBC08EE123193D007D006D097 -:1031900002D001D000227573008574A822C0F0C04F -:1031A00082C083C3E57524E850051231E780F4EC52 -:1031B00060319034B6E493C39C4028C0047CFF1275 -:1031C00030FAD004430480E57575F003A4249DF51E -:1031D00082E434FEF583ECF0EFA3F0EEA3F0057586 -:1031E000123193D083D082D0F022C0047C20D28CC4 -:1031F000D28DD504FDD0042275A80075880075B85D -:103200000075F00075D000E4F8900000F608B800F2 -:10321000FB020000C3ED940250047D037CE8ECF453 -:10322000FCEDF4FD0CBC00010D8C798D7822C3EC13 -:1032300094BCED940250047D077CD0ECF4FCEDF4DA -:10324000FD0CBC00010D8C778D7622EC700122C044 -:1032500000E5722418F8A604E5722408F8C6547F25 -:10326000F6E630E703D000221231E780F4C28C8505 -:10327000768C85778AD28CC0E0C0D0C0F0C082C086 -:1032800083C000C001C002C003C004C005C006C0A6 -:1032900007121B28E5722408F8E66024E572241062 -:1032A000F8A681E57275F021A42495F582E434FD39 -:1032B000F58378A8E58104C398F9E6F008A3D9FA64 -:1032C00074082572F8057208E65480700CE572B433 -:1032D00007F3780875720080EFE5722410F8868194 -:1032E000E57275F021A42495F582E434FDF5837828 -:1032F000A8E58104C398F9E0F608A3D9FAD007D06D -:1033000006D005D004D003D002D001D000D083D0A5 -:1033100082D0F0D0D0D0E032C0E0C0D0C000C00138 -:10332000C002C28E85788D85798BD28E7819790905 -:103330007A07E77004A600800BE6600816E67004C2 -:10334000E74480F70809DAEAE573601314F573704F -:103350000EE5722408F87600123193D28CD28DD00B -:1033600002D001D000D0D0D0E0327581A775900096 -:103370007579307578F87577607576F012053C12BE -:10338000340F12178B1234391231F580E322C0004A -:103390007C01EC2408F8E660090CBC08F51231E762 -:1033A00080EED00022C0F0C082C083C000C006C042 -:1033B00007ED2410F876B6ED75F021A42495F5827A -:1033C000E434FDF583C082C083A3A3E4780DF0A3A9 -:1033D000D8FCEC547F75F002A42482F582E5F03429 -:1033E00034F583E493FE740193F5828E83E493FEB7 -:1033F000740193FFD083D082EFF0A3EEF0ED2408A8 -:10340000F8EC4480F6D007D006D000D083D082D02C -:10341000F0227572007575007A08791878087600C0 -:1034200077000809DAF8E478087480447FF67401BC -:103430004410F58975B808D2ABD2A9227581A7D2FC -:103440008ED28CD2AFE5756032FF90FE9DE0548045 -:10345000602478087908E0547FFA7B00E6547FB551 -:1034600002027BFF08D9F5EB700CEAF012338BAD4A -:1034700004AC021233A2A3A3A3DFD21231E780C5AA -:103480007C017D002204F504E904ED04E104DD047F -:10349000D904E504F1049D04A104CD04D1049904E8 -:1034A00099049904D504B504AD04B104A904C10478 -:1034B000BD04B904C504C904A519010300220048CC -:1034C0000200240F180A10640D680C05060203019F -:1034D0000181010000E700C0008000600040003072 -:1034E0000018000C00080004000200010008183851 -:1034F000280602100A0200000000000181100A02E2 -:103500000000000000FBE8FBFA12011001FF0000C0 -:103510000851045F50160101020002090235000142 -:103520000200E0000904000005FF0000000705811B -:10353000024000000705010240000007058202402A -:103540000000070502024000000705850302000194 -:10355000040309042403540065007800610073002B -:10356000200049006E0073007400720075006D0049 -:1035700065006E00740073002A0354005500530068 -:103580004200350030003500320020005300650055 -:103590007200690061006C00200050006F00720032 -:1035A00074002203540055005300420035003000DF -:1035B00035003200200020002000200020002000E4 -:0435C00020002000C7 -:00000001FF diff --git a/firmware/tigon/tg3.bin.ihex b/firmware/tigon/tg3.bin.ihex deleted file mode 100644 index d842d7cc91b5036fad1f34cdeab5ef6f14a94d38..0000000000000000000000000000000000000000 --- a/firmware/tigon/tg3.bin.ihex +++ /dev/null @@ -1,175 +0,0 @@ -:10000000000000000800000000000A80000000005E -:1000100010000003000000000000000D0000000DB3 -:100020003C1D080037BD3FFC03A0F0213C10080038 -:10003000261000000E000018000000000000000D57 -:100040003C1D080037BD3FFC03A0F0213C10080018 -:10005000261000340E00021C000000000000000DFD -:1000600000000000000000000000000027BDFFE0CD -:100070003C1CC000AFBF0018AF80680C0E00004CE5 -:10008000241B210597850000978700029782002C8A -:100090009783002E3C040800248409C0AFA00014FC -:1000A000000214000062182500052C00AFA3001008 -:1000B0008F86001000E528250E000060240701024D -:1000C0003C02AC00344201003C03AC01346301004B -:1000D000AF8204903C02FFFFAF820494AF83049888 -:1000E000AF82049C24020001AF825CE00E00003F5E -:1000F000AF825D000E000140000000008FBF0018BD -:1001000003E0000827BD00202402FFFFAF82540453 -:100110008F83540034630400AF835400AF825404CF -:100120003C02080024420034AF82541C03E0000863 -:10013000AF80540000000000000000003C020800F6 -:10014000344230003C030800346330003C040800B3 -:10015000348437FF3C010800AC220A6424020040CA -:100160003C010800AC220A683C010800AC200A608F -:10017000AC600000246300040083102B5040FFFD9E -:10018000AC60000003E0000800000000008048218F -:100190008FAA00103C0208008C420A603C04080050 -:1001A0008C840A688FAB0014244300010044102B98 -:1001B0003C010800AC230A60144000030000402109 -:1001C0003C010800AC200A603C0208008C420A6036 -:1001D0003C0308008C630A64912400000002114073 -:1001E000004310210048102125080001A044000010 -:1001F000290200081440FFF4252900013C020800F0 -:100200008C420A603C0308008C630A648F84680C8B -:100210000002114000431021AC440008AC45000C22 -:10022000AC460010AC470014AC4A001803E00008CC -:10023000AC4B001C000000000000000000000000AB -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000002000008E3 -:10031000000000000A0001E33C0A00010A0001E3BA -:100320003C0A00020A0001E3000000000A0001E3A9 -:10033000000000000A0001E3000000000A0001E3E1 -:10034000000000000A0001E3000000000A0001E3D1 -:10035000000000000A0001E3000000000A0001E3C1 -:10036000000000000A0001E3000000000A0001E3B1 -:100370003C0A00070A0001E33C0A00080A0001E306 -:100380003C0A00090A0001E3000000000A0001E342 -:10039000000000000A0001E33C0A000B0A0001E330 -:1003A0003C0A000C0A0001E33C0A000D0A0001E3CC -:1003B000000000000A0001E3000000000A0001E361 -:1003C0003C0A000E0A0001E3000000000A0001E3FD -:1003D000000000000A0001E3000000000A0001E341 -:1003E000000000000A0001E3000000000A0001E331 -:1003F000000000000A0001E3000000000A0001E321 -:10040000000000000A0001E33C0A00130A0001E3B7 -:100410003C0A001400000000000000000000000082 -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000027BDFFE028 -:100510000000182100001021AFBF0018AFB1001477 -:10052000AFB000103C01080000220821AC200A7086 -:100530003C01080000220821AC200A743C0108009C -:1005400000220821AC200A78246300011860FFF51E -:100550002442000C241100018F9068103202000424 -:1005600014400005240400013C0208008C420A7873 -:1005700018400003000020210E000182000000004E -:100580003202000110400003000000000E0001696B -:10059000000000000A000153AF9150288FBF0018DF -:1005A0008FB100148FB0001003E0000827BD0020B9 -:1005B0003C0508008CA50A703C0608008CC60A8021 -:1005C0003C0708008CE70A7827BDFFE03C040800E0 -:1005D000248409D0AFBF0018AFA000100E00006047 -:1005E000AFA000140E00017B000020218FBF001877 -:1005F00003E0000827BD0020240200018F8368105B -:1006000000821004000210270062182403E0000892 -:10061000AF83681027BDFFD8AFBF00241080002E25 -:10062000AFB000208F825CECAFA200188F825CEC30 -:100630003C10080026100A78AFA2001C340280008B -:10064000AF825CEC8E020000184000160000000033 -:100650003C02080094420A748FA3001C000221C0CF -:10066000AC8300048FA2001C3C0108000E000201B4 -:10067000AC220A7410400005000000008E02000049 -:10068000244200010A0001DFAE0200003C02080023 -:100690008C420A7000021C02000321C00A0001C53E -:1006A000AFA2001C0E000201000000001040001F5D -:1006B000000000008E0200008FA3001C24420001F5 -:1006C0003C010800AC230A703C010800AC230A740A -:1006D0000A0001DFAE0200003C10080026100A7874 -:1006E0008E02000018400028000000000E000201E9 -:1006F0000000000014400024000000008E020000F2 -:100700003C0308008C630A702442FFFFAFA3001C67 -:1007100018400006AE02000000031402000221C0CF -:100720008C8200043C010800AC220A7097A2001ED3 -:100730002442FF002C4203001440000B240240001E -:100740003C040800248409DCAFA00010AFA0001412 -:100750008FA6001C240500080E0000600000382150 -:100760000A0001DF00000000AF825CF83C020800D4 -:100770008C420A408FA3001C24420001AF835CF826 -:100780003C010800AC220A408FBF00248FB000203B -:1007900003E0000827BD002827BDFFE03C04080057 -:1007A000248409E8000028210000302100003821BD -:1007B000AFBF0018AFA000100E000060AFA0001483 -:1007C0008FBF001803E0000827BD00208F82680C4F -:1007D0008F85680C000218270003182B00031823CC -:1007E000004310240044102100A2282B10A0000672 -:1007F00000000000004018218F82680C0043102B7D -:100800001440FFFD0000000003E0000800000000AD -:100810003C0408008C8400003C0308008C630A4000 -:100820000064102B54400002008310230064102346 -:100830002C42000803E000083842000127BDFFE019 -:10084000008028213C04080024840A000000302194 -:1008500000003821AFBF0018AFA000100E000060EC -:10086000AFA000140A000216000000008FBF00189D -:1008700003E0000827BD00200000000027BDFFE0C6 -:100880003C1CC000AFBF00180E00004CAF80680CCD -:100890003C04080024840A10038028210000302131 -:1008A00000003821AFA000100E000060AFA00014BF -:1008B0002402FFFFAF8254043C0200AA0E0002345F -:1008C000AF8254348FBF001803E0000827BD00201A -:1008D00000000000000000000000000027BDFFE84D -:1008E000AFB0001024100001AFBF00143C01C003E2 -:1008F000AC2000008F8268103042200010400003BE -:10090000000000000E000246000000000A00023A4B -:10091000AF9054288FBF00148FB0001003E0000880 -:1009200027BD001827BDFFF88F845D0C3C0200FF37 -:100930003C0308008C630A503442FFF80082102404 -:100940001043001E3C0500FF34A5FFF83C06C00321 -:100950003C074000008518248C6200103C01080010 -:10096000AC230A50304200081040000500871025D3 -:100970008CC2000024420001ACC200000087102598 -:10098000AF825D0C8FA2000024420001AFA20000E4 -:100990008FA200008FA2000024420001AFA200003D -:1009A0008FA200008F845D0C3C0308008C630A500A -:1009B000008510241443FFE80085182427BD000893 -:1009C00003E000080000000000000000353730316F -:1009D000726C734100000000000000005377457600 -:1009E000656E743000000000726C704576656E7440 -:1009F00031000000556E6B6E45766E74000000008D -:100A0000000000000000000000000000666174614A -:100A10006C45727200000000000000004D61696EBC -:100A2000437075420000000000000000000000005C -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:0C0A60000000000000000000000000008A -:00000001FF - * Firmware is: - * Derived from proprietary unpublished source code, - * Copyright (C) 2000-2003 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware - * data in hexadecimal or equivalent format, provided this copyright - * notice is accompanying it. diff --git a/firmware/tigon/tg3_tso.bin.ihex b/firmware/tigon/tg3_tso.bin.ihex deleted file mode 100644 index f10c4ef905136f8d2738fd09e8300da6d77e676d..0000000000000000000000000000000000000000 --- a/firmware/tigon/tg3_tso.bin.ihex +++ /dev/null @@ -1,446 +0,0 @@ -:100000000106000008000000000024140E00000398 -:100010000000000008001B24000000001000000386 -:10002000000000000000000D0000000D3C1D080055 -:1000300037BD400003A0F0213C100800261000004E -:100040000E000010000000000000000D27BDFFE0C2 -:100050003C04FEFEAFBF00180E0005D83484000239 -:100060000E000668000000003C03080090631B6857 -:10007000240200023C04080024841AAC1462000329 -:10008000240500013C04080024841AA0240600066C -:1000900000003821AFA000100E00067CAFA00014B5 -:1000A0008F625C5034420001AF625C508F625C90A2 -:1000B00034420001AF625C902402FFFF0E00003466 -:1000C000AF6254048FBF001803E0000827BD002072 -:1000D00000000000000000000000000027BDFFE05D -:1000E000AFBF001CAFB20018AFB100140E00005B30 -:1000F000AFB0001024120002241100018F7068209C -:100100003202010010400003000000000E0000BB9E -:10011000000000008F7068203202200010400004B0 -:10012000320200010E0001F024040001320200013D -:1001300010400003000000000E0000A300000000BB -:100140003C02080090421B9814520003000000007B -:100150000E0004C0000000000A00003CAF715028EF -:100160008FBF001C8FB200188FB100148FB0001029 -:1001700003E0000827BD002027BDFFE03C04080085 -:1001800024841AC0000028210000302100003821FA -:10019000AFBF0018AFA000100E00067CAFA0001487 -:1001A0003C040800248423D8A48000003C010800FB -:1001B000A0201B983C010800AC201B9C3C010800BF -:1001C000AC201BA03C010800AC201BA43C01080093 -:1001D000AC201BAC3C010800AC201BB83C01080063 -:1001E000AC201BBC8F6244343C010800AC221B884D -:1001F0008F6244383C010800AC221B8C8F62441093 -:10020000AC80F7A83C010800AC201B843C0108002E -:10021000AC2023E03C010800AC2023C83C010800CE -:10022000AC2023CC3C010800AC2024003C01080099 -:10023000AC221B908F6200682403000700021702A3 -:1002400010430005000000008F62006800021702E2 -:1002500014400004240200013C0108000A00009739 -:10026000AC20240CAC8200343C04080024841ACC5A -:100270003C0508008CA5240C00003021000038212A -:10028000AFA000100E00067CAFA000148FBF0018B6 -:1002900003E0000827BD002027BDFFE03C04080064 -:1002A00024841AD8000028210000302100003821C1 -:1002B000AFBF0018AFA000100E00067CAFA0001466 -:1002C0000E00005B000000000E0000B400002021C2 -:1002D0008FBF001803E0000827BD002024020001A2 -:1002E0008F63682000821004000210270062182427 -:1002F00003E00008AF63682027BDFFD0AFBF002C2C -:10030000AFB60028AFB50024AFB40020AFB3001CD7 -:10031000AFB20018AFB10014AFB000108F675C5CD3 -:100320003C03080024631BBC8C62000014470005DA -:100330003C0200FF3C02080090421B981440011947 -:100340003C0200FF3442FFF800E28824AC67000062 -:1003500000111902306300FF30E20003000211C0F7 -:100360000062282500A04021000716023C03080077 -:1003700090631B983044000F1460003600804821C1 -:10038000240200013C010800A0221B980005110076 -:10039000008210253C010800AC201B9C3C01080099 -:1003A000AC201BA03C010800AC201BA43C010800B1 -:1003B000AC201BAC3C010800AC201BB83C01080081 -:1003C000AC201BB03C010800AC201BB43C01080071 -:1003D000A42223D89622000C30437FFF3C01080062 -:1003E000A4222410304280003C010800A4231BC634 -:1003F00010400005240200013C010800AC2223F457 -:100400000A0001022406003E240600363C010800D2 -:10041000AC2023F49622000A3C03080094631BC618 -:100420003C010800AC2023F03C010800AC2023F87C -:10043000000213020002108000C210210062182185 -:100440003C010800A42223D03C0108000A00011549 -:10045000A4231B969622000C3C010800A42223EC46 -:100460003C04080024841B9C8C82000000021100C4 -:100470003C01080000220821AC311BC88C8200001E -:10048000000211003C01080000220821AC271BCC0F -:100490008C82000025030001306601FF000211007C -:1004A0003C01080000220821AC261BD08C820000F1 -:1004B000000211003C01080000220821AC291BD4D5 -:1004C000962300083C0208008C421BAC0043282104 -:1004D0003C010800AC251BAC9622000A3042000407 -:1004E00014400018000611008F630C143063000FD5 -:1004F0002C6200021440000B3C02C0008F630C14FD -:100500003C0208008C421B403063000F2442000173 -:100510003C010800AC221B402C6200021040FFF797 -:100520003C02C00000E21825AF635C5C8F625C5047 -:100530003042000210400014000000000A00014791 -:10054000000000003C0308008C631B803C04080092 -:1005500094841B94012210253C010800A42223DA74 -:10056000240200013C010800AC221BB824630001F6 -:100570000085202A3C01080010800003AC231B806A -:100580003C010800A4251B943C06080024C61B9CC3 -:100590008CC2000024420001ACC20000284200804E -:1005A00014400005000000000E000656240400025E -:1005B0000A0001E6000000003C0208008C421BB863 -:1005C00010400078240200013C05080090A51B980B -:1005D00014A20072000000003C15080096B51B969E -:1005E0003C0408008C841BAC32A3FFFF0083102A5C -:1005F0001440006C000000001483000300000000A1 -:100600003C010800AC2523F01060005C0000902144 -:1006100024D600040060A02124D300148EC2000060 -:10062000000281003C110800023088210E000625DE -:100630008E311BC80040282110A00054000000008B -:100640009628000A31020040104000052407180CCB -:100650008E22000C2407188C00021400ACA2001893 -:100660003C030800007018218C631BD03C0208007A -:10067000005010218C421BD400031D000002140006 -:1006800000621825ACA300148EC300049622000853 -:10069000004320233242FFFF3083FFFF004310213D -:1006A0000282102A1440000202B23023008030215E -:1006B0008E62000030C4FFFF00441021AE620000D3 -:1006C0008E220000ACA200008E2200048E63FFF494 -:1006D00000431021ACA20004A4A6000E8E62FFF419 -:1006E00000441021AE62FFF4962300080043102A54 -:1006F00014400005024690218E62FFF0AE60FFF4C8 -:1007000024420001AE62FFF0ACA000083242FFFFBD -:1007100014540008240203053102008054400001F3 -:1007200034E7001024020905A4A2000C0A0001CB42 -:1007300034E70020A4A2000C3C0208008C4223F005 -:10074000104000033C024B650A0001D3344276544A -:100750003C02B49A344289ABACA2001C30E2FFFFE9 -:10076000ACA200100E0005A200A020213242FFFF23 -:100770000054102B1440FFA90000000024020002C6 -:100780003C0108000A0001E6A0221B988EC2083C2A -:10079000244200010A0001E6AEC2083C0E0004C07B -:1007A000000000008FBF002C8FB600288FB50024FA -:1007B0008FB400208FB3001C8FB200188FB10014CB -:1007C0008FB0001003E0000827BD003027BDFFD028 -:1007D000AFBF0028AFB30024AFB20020AFB1001C00 -:1007E000AFB000188F725C9C3C0200FF3442FFF8EF -:1007F0003C07080024E71BB4024288249623000E1D -:100800008CE2000000431021ACE200008E220010B8 -:100810003042002014400011008098210E00063B59 -:10082000022020213C02C00002421825AF635C9CDC -:100830008F625C90304200021040011E00000000F8 -:10084000AF635C9C8F625C903042000210400119E3 -:10085000000000000A00020D000000008E240008C5 -:100860008E23001400041402000231C0000315029C -:10087000304201FF2442FFFF3042007F0003194253 -:1008800030637800000211002442400000624821D9 -:100890009522000A3084FFFF30420008104000B06B -:1008A000000429C03C0208008C42240014400024AB -:1008B00024C5000894C200143C010800A42223D0DF -:1008C0008CC40010000414023C010800A42223D2AE -:1008D0003C010800A42423D494C2000E3083FFFFFF -:1008E000004310233C010800AC22240894C2001AE3 -:1008F0003C010800AC2624003C010800AC32240472 -:100900003C010800AC2223FC3C02C0000242182536 -:10091000AF635C9C8F625C9030420002104000E547 -:1009200000000000AF635C9C8F625C90304200026C -:10093000104000E0000000000A0002460000000035 -:1009400094C2000E3C030800946323D40043402368 -:100950003103FFFF2C6200081040001C0000000063 -:1009600094C200142442002800A22821000310424F -:100970001840000B0000202124E6084800403821E0 -:1009800094A300008CC200002484000100431021C5 -:10099000ACC200000087102A1440FFF924A5000211 -:1009A000310200011040001F3C0240003C040800DE -:1009B000248423FCA0A0000194A300008C820000EA -:1009C000004310210A000285AC8200008F6268009B -:1009D0003C030010004310241040000900000000F8 -:1009E00094C2001A3C0308008C6323FC00431021CE -:1009F0003C010800AC2223FC0A0002863C024000B5 -:100A000094C2001A94C4001C3C0308008C6323FCAD -:100A100000441023006218213C010800AC2323FC91 -:100A20003C02400002421825AF635C9C8F625C90E0 -:100A3000304200021440FFFC000000009522000A32 -:100A4000304200101040009B000000003C030800F2 -:100A5000946323D43C07080024E724008CE40000BE -:100A60008F62680024630030008328213C0300105B -:100A7000004310241440000A0000000094A2000467 -:100A80003C0408008C8424083C0308008C6323FC8D -:100A900000441023006218213C010800AC2323FC11 -:100AA0003C0408008C8423FC00041C023082FFFFFD -:100AB000006220210004140200822021000410277B -:100AC000A4A200063C0308008C6324043C0200FF3F -:100AD0003442FFF8006288249622000824050001B1 -:100AE00024034000000231C000801021A4C2001A7B -:100AF000A4C0001CACE000003C010800AC251B6059 -:100B0000AF635CB88F625CB03042000210400003FB -:100B1000000000003C010800AC201B608E22000891 -:100B2000AF625CB88F625CB03042000210400003DC -:100B3000000000003C010800AC201B603C020800E3 -:100B40008C421B601040FFEC000000003C040800D9 -:100B50000E00063B8C8424040A00032A00000000D7 -:100B60003C03080090631B982402000214620003F7 -:100B70003C034B650A0002E1000080218E22001C2C -:100B80003463765410430002241000022410000144 -:100B900000C020210E000350020030212402000377 -:100BA0003C010800A0221B98240200021202000A45 -:100BB000240200013C0308008C6323F0106200064D -:100BC000000000003C020800944223D800021400F8 -:100BD0000A00031FAE2200143C040800248423DA18 -:100BE0009482000000021400AE2200143C020800AF -:100BF0008C421BBC3C03C0003C010800A0201B9899 -:100C000000431025AF625C5C8F625C503042000292 -:100C100010400009000000002484F7E28C820000EC -:100C200000431025AF625C5C8F625C503042000272 -:100C30001440FFFA000000003C02080024421B841C -:100C40008C43000024630001AC4300008F630C144C -:100C50003063000F2C6200021440000C3C02400084 -:100C60008F630C143C0208008C421B403063000F61 -:100C7000244200013C010800AC221B402C6200020F -:100C80001040FFF7000000003C024000024218251F -:100C9000AF635C9C8F625C90304200021440FFFCAA -:100CA0000000000012600003000000000E0004C0FD -:100CB000000000008FBF00288FB300248FB20020F7 -:100CC0008FB1001C8FB0001803E0000827BD003072 -:100CD0008F6344503C04080024841B888C820000ED -:100CE00000031C020043102B144000073C0380004B -:100CF0008C8400048F62445000021C020083102B7D -:100D00001040FFFC3C038000AF6344448F624444C6 -:100D1000004310241440FFFD000000008F6244488F -:100D200003E000083042FFFF3C0240000082202523 -:100D3000AF645C388F625C30304200021440FFFCCC -:100D40000000000003E000080000000027BDFFE0F5 -:100D50000080582114C00011256E00083C020800D4 -:100D60008C4223F410400007240200163C010800C6 -:100D7000A42223D22402002A3C0108000A000364B2 -:100D8000A42223D48D670010000714023C01080040 -:100D9000A42223D23C010800A42723D43C04080049 -:100DA000948423D43C030800946323D295CF000697 -:100DB0003C020800944223D00083202301E2C02398 -:100DC0003065FFFF24A2002801C248213082FFFFC6 -:100DD00014C0001A012260219582000C3042003FAD -:100DE0003C010800A42223D69582000495830006C6 -:100DF0003C010800AC2023E43C010800AC2023E8BF -:100E000000021400004310253C010800AC221BC066 -:100E1000952200043C010800A4221BC49523000273 -:100E200001E510230043102A1040001024020001A5 -:100E30003C0108000A000398AC2223F83C03080098 -:100E40008C6323E83C02080094421BC40043102139 -:100E5000A52200043C02080094421BC0A5820004A5 -:100E60003C0208008C421BC0A58200063C02080020 -:100E70008C4223F03C0D08008DAD23E43C0A0800B1 -:100E8000144000E58D4A23E83C02080094421BC44C -:100E9000004A18213063FFFF0062182B2402000271 -:100EA00010C2000D014350233C020800944223D697 -:100EB0003042000910400008000000009582000C3C -:100EC0003042FFF6A582000C3C020800944223D673 -:100ED0003042000901A268233C0208008C4223F83A -:100EE0001040004A012038213C020800944223D2DD -:100EF00000004021A520000A01E21023A5220002E3 -:100F00003082FFFF0002104218400008000030212C -:100F10000040182194E200002508000100C23021A1 -:100F20000103102A1440FFFB24E7000200061C0204 -:100F300030C2FFFF006230210006140200C23021DF -:100F400000C0282100061027A522000A0000302139 -:100F50002527000C0000402194E200002508000134 -:100F600000C230212D0200041440FFFB24E70002E0 -:100F70009522000200004021912300090044202313 -:100F8000018038213082FFFFA4E0001000621821A8 -:100F9000000210421840001000C3302100404821D8 -:100FA00094E2000024E7000200C2302130E2007F1A -:100FB00014400006250800018D6300003C02007FFC -:100FC0003442FF8000625824256700080109102A76 -:100FD0001440FFF3000000003082000110400005C3 -:100FE00000061C02A0E0000194E2000000C23021D3 -:100FF00000061C0230C2FFFF00623021000614020E -:1010000000C230210A00047D30C6FFFF2402000226 -:1010100014C20081000000003C0208008C42240C35 -:1010200014400007000000003C020800944223D254 -:101030009523000201E210231062007700000000F7 -:101040003C020800944223D201E21023A5220002B0 -:101050003C0208008C42240C1040001A31E3FFFFD0 -:101060008DC700103C02080094421B9600E040210E -:1010700000072C0200AA20210043102300823823FD -:101080000007240230E2FFFF00823821000710270A -:10109000A522000A3102FFFF3C040800948423D4F7 -:1010A0000045302300E0282100641823006D18213A -:1010B00000C3302100061C0230C2FFFF0A00047D7D -:1010C0000062302101203821000040213082FFFFE2 -:1010D0000002104218400008000030210040182192 -:1010E00094E200002508000100C230210103102A0B -:1010F0001440FFFB24E7000200061C0230C2FFFF81 -:10110000006230210006140200C2302100C02821F4 -:1011100000061027A522000A000030212527000C18 -:101120000000402194E200002508000100C23021A7 -:101130002D0200041440FFFB24E700029522000268 -:101140000000402191230009004420230180382120 -:101150003082FFFFA4E000103C040800948423D4F4 -:101160000062182100C3302100061C0230C2FFFFBC -:101170000062302100061C023C020800944223D089 -:1011800000C348210044102300021FC20043102165 -:1011900000021043184000100000302100402021C0 -:1011A00094E2000024E7000200C2302130E2007F18 -:1011B00014400006250800018D6300003C02007FFA -:1011C0003442FF8000625824256700080104102A79 -:1011D0001440FFF3000000003C020800944223EC9E -:1011E00000C230213122FFFF00C2302100061C0264 -:1011F00030C2FFFF006230210006140200C230211D -:1012000000C0402100061027A5820010ADC00014C8 -:101210000A00049DADC000008DC7001000E0402111 -:101220001140000700072C0200AA3021000614021A -:1012300030C3FFFF004330210006140200C2282102 -:1012400000051027A522000A3C030800946323D45C -:101250003102FFFF01E210210043302300CD302195 -:1012600000061C0230C2FFFF00623021000614029B -:1012700000C2302100C0402100061027A5820010C6 -:101280003102FFFF00051C0000431025ADC2001015 -:101290003C0208008C4223F4104000052DE205EBCF -:1012A0001440000225E2FFF234028870A5C2003427 -:1012B0003C030800246323E88C6200002442000100 -:1012C000AC6200003C0408008C8423E43C0208006B -:1012D0008C421BC03303FFFF0083202100431821F1 -:1012E0000062102B3C010800AC2423E410400003F2 -:1012F0002482FFFF3C010800AC2223E43C010800EB -:10130000AC231BC003E0000827BD002027BDFFB8A9 -:101310003C05080024A51B96AFBF0044AFBE0040AB -:10132000AFB7003CAFB60038AFB50034AFB4003053 -:10133000AFB3002CAFB20028AFB10024AFB0002093 -:1013400094A900003C020800944223D03C0308000A -:101350008C631BB03C0408008C841BAC012210235E -:101360000064182AA7A9001E106000BEA7A20016DC -:1013700024BE002297B6001E24B3001A24B700161C -:101380008FC2000014400008000000008FC2FFF868 -:1013900097A300168FC4FFF4004310210082202A77 -:1013A000148000B00000000097D5081832A2FFFF9B -:1013B000104000A3000090210040A02100008821DF -:1013C0000E000625000000000040302114C0000778 -:1013D000000000003C0208008C4223DC2442000193 -:1013E0003C0108000A000596AC2223DC3C100800F2 -:1013F000021180218E101BC89608000A310200409D -:10140000104000052407180C8E02000C2407188CCD -:1014100000021400ACC200183102008054400001E8 -:1014200034E700103C020800005110218C421BD010 -:101430003C030800007118218C631BD400021500C6 -:1014400000031C0000431025ACC2001496040008E1 -:101450003242FFFF008210210282102A1440000253 -:1014600002B22823008028218E020000024590212C -:10147000ACC200008E02000400C020212631001002 -:10148000AC82000430E2FFFFAC800008A485000EAF -:10149000AC820010240203050E0005A2A482000CF9 -:1014A0003242FFFF0054102B1440FFC53242FFFFB1 -:1014B0000A00058E000000008E6200008E63FFFCB3 -:1014C0000043102A10400067000000008E62FFF009 -:1014D000000289003C100800021180210E00062540 -:1014E0008E101BC80040302114C000050000000011 -:1014F0008E62082C244200010A000596AE62082C78 -:101500009608000A31020040104000052407180C1C -:101510008E02000C2407188C00021400ACC20018C4 -:101520003C020800005110218C421BD03C030800F3 -:10153000007118218C631BD40002150000031C00ED -:1015400000431025ACC200148E63FFF4960200081D -:10155000004320233242FFFF3083FFFF004310216E -:1015600002C2102A104000030080282197A9001E03 -:10157000013228238E62000030A4FFFF00441021B6 -:10158000AE620000A4C5000E8E020000ACC20000D6 -:101590008E0200048E63FFF400431021ACC20004ED -:1015A0008E63FFF496020008006418210062102A7E -:1015B00014400006024590218E62FFF0AE60FFF4F9 -:1015C000244200010A000571AE62FFF0AE63FFF431 -:1015D000ACC000083242FFFF105600033102000485 -:1015E000104000062402030531020080544000012F -:1015F00034E7001034E7002024020905A4C2000CDF -:101600008EE300008EE20004146200073C02B49AEC -:101610008EE208605440000134E704003C024B6550 -:101620000A00058834427654344289ABACC2001CAF -:1016300030E2FFFFACC200100E0005A200C0202166 -:101640003242FFFF0056102B1440FF9B00000000A9 -:101650008E6200008E63FFFC0043102A1440FF4896 -:10166000000000008FBF00448FBE00408FB7003CD9 -:101670008FB600388FB500348FB400308FB3002C94 -:101680008FB200288FB100248FB0002003E0000843 -:1016900027BD004827BDFFE8AFBF0014AFB0001062 -:1016A0008F6244508F6344100A0005B1008080218E -:1016B0008F626820304220001040000300000000CC -:1016C0000E0001F0000020218F6244508F6344100F -:1016D0003042FFFF0043102B1440FFF500000000D4 -:1016E0008F630C143063000F2C6200021440000B57 -:1016F000000000008F630C143C0208008C421B4069 -:101700003063000F244200013C010800AC221B4062 -:101710002C6200021040FFF700000000AF705C1860 -:101720008F625C103042000210400009000000008F -:101730008F626820304220001040FFF80000000057 -:101740000E0001F0000020210A0005C40000000086 -:101750008FBF00148FB0001003E0000827BD0018F1 -:1017600000000000000000000000000027BDFFE8AE -:101770003C1BC000AFBF0014AFB00010AF60680CDE -:101780008F62680434420082AF6268048F63400055 -:1017900024020B503C010800AC221B5424020B789D -:1017A0003C010800AC221B6434630002AF634000BC -:1017B0000E000605008080213C010800A0221B6865 -:1017C000304200FF24030002144300050000000023 -:1017D0003C0208008C421B540A0005F8AC5000C0C3 -:1017E0003C0208008C421B54AC5000BC8F62443455 -:1017F0008F6344388F6444103C010800AC221B5CAA -:101800003C010800AC231B6C3C010800AC241B58B5 -:101810008FBF00148FB0001003E0000827BD001830 -:101820003C0408008C8700003C03AA553463AA5589 -:101830003C06C003AC8300008CC2000014430007C8 -:10184000240500023C0355AA346355AAAC8300006A -:101850008CC2000050430001240500013C02080036 -:10186000AC47000003E0000800A0102127BDFFF8EE -:1018700018800009000028218F63680C8F62680CB3 -:101880001043FFFE0000000024A5000100A4102A60 -:101890001440FFF90000000003E0000827BD000825 -:1018A0008F6344503C0208008C421B5C00031C0206 -:1018B0000043102B144000083C0380003C04080047 -:1018C0008C841B6C8F62445000021C020083102B1E -:1018D0001040FFFC3C038000AF6344448F624444EB -:1018E000004310241440FFFD000000008F624448B4 -:1018F00003E000083042FFFF3082FFFF2442E00097 -:101900002C422001144000033C0240000A0006481B -:101910002402FFFF00822025AF645C388F625C30B8 -:10192000304200021440FFFC0000102103E00008D8 -:10193000000000008F6244503C0308008C631B5879 -:101940000A0006513042FFFF8F6244503042FFFFD1 -:101950000043102B1440FFFC0000000003E00008CF -:101960000000000027BDFFE0008028213C040800A3 -:1019700024841AF00000302100003821AFBF001885 -:10198000AFA000100E00067CAFA000140A00066095 -:10199000000000008FBF001803E0000827BD0020F2 -:1019A0000000000000000000000000003C020800F1 -:1019B000344230003C030800346330003C0408002B -:1019C000348437FF3C010800AC221B742402004021 -:1019D0003C010800AC221B783C010800AC201B70C5 -:1019E000AC600000246300040083102B5040FFFD16 -:1019F000AC60000003E00008000000000080482107 -:101A00008FAA00103C0208008C421B703C040800A6 -:101A10008C841B788FAB0014244300010044102BEE -:101A20003C010800AC231B7014400003000040215F -:101A30003C010800AC201B703C0208008C421B706B -:101A40003C0308008C631B749124000000021140C9 -:101A5000004310210048102125080001A044000087 -:101A6000290200081440FFF4252900013C02080067 -:101A70008C421B703C0308008C631B748F64680CE1 -:101A80000002114000431021AC440008AC45000C9A -:101A9000AC460010AC470014AC4A001803E0000844 -:101AA000AC4B001C00000000000000004D61696E9E -:101AB00043707542000000004D61696E43707541CE -:101AC00000000000000000000000000073746B6F55 -:101AD00066666C64496E000073746B6F66662A2AD2 -:101AE0000000000053774576656E743000000000FA -:101AF000000000000000000000000000666174614A -:101B00006C45727200000000000000000000000040 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300073746B6F66666C645F76312E362E300080 -:101B40000000000000000000000000000000000095 -:0C1B500000000000000000000000000089 -:00000001FF - * Firmware is: - * Derived from proprietary unpublished source code, - * Copyright (C) 2000-2003 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware - * data in hexadecimal or equivalent format, provided this copyright - * notice is accompanying it. diff --git a/firmware/tigon/tg3_tso5.bin.ihex b/firmware/tigon/tg3_tso5.bin.ihex deleted file mode 100644 index 33672514eab3e2e8fff9418b26eb3db353fce868..0000000000000000000000000000000000000000 --- a/firmware/tigon/tg3_tso5.bin.ihex +++ /dev/null @@ -1,252 +0,0 @@ -:10000000010200000001000000000FD80C004003B6 -:100010000000000000010F040000000010000003B9 -:10002000000000000000000D0000000D3C1D00015C -:1000300037BDE00003A0F0213C10000126100000B5 -:100040000C004010000000000000000D27BDFFE084 -:100050003C04FEFEAFBF00180C0042E834840002EE -:100060000C004364000000003C03000190630F3467 -:10007000240200023C04000124840E9C146200034C -:10008000240500013C04000124840E902406000293 -:1000900000003821AFA000100C004378AFA000147E -:1000A0000C00402C000000008FBF001803E0000887 -:1000B00027BD0020000000000000000027BDFFE079 -:1000C000AFBF001CAFB20018AFB100140C0042D497 -:1000D000AFB000103C128000241100018F70681036 -:1000E0003202040010400007000000008F64100876 -:1000F0000092102414400003000000000C00406433 -:10010000000000003C02000190420F561051000315 -:10011000320202001040FFF1000000000C0041B468 -:100120000000000008004034000000008FBF001CE9 -:100130008FB200188FB100148FB0001003E00008D8 -:1001400027BD002027BDFFE03C04000124840EB041 -:10015000000028210000302100003821AFBF001826 -:10016000AFA000100C004378AFA000140000D02115 -:1001700024020130AF6250003C010001A4200F5066 -:100180003C010001A0200F578FBF001803E00008BA -:1001900027BD002000000000000000003C0300011B -:1001A00024630F609062000027BDFFF0144000033D -:1001B0000080C02108004073000048213C0220005C -:1001C00003021024104000032409000208004073B9 -:1001D000A0600000240900010018104030431F8077 -:1001E000346F80081520004B25EB00283C040001EB -:1001F000008320218C8480103C05000124A50F7A07 -:1002000000041402A0A200003C010001A0240F7B06 -:100210003C02000100431021944280143C01000183 -:10022000A0220F7C3C0C0001018360218D8C801882 -:10023000304200FF24420008000220C324020001D3 -:100240003C010001A0220F600124102B1040000C83 -:100250000000382124A6000E016028218CA2000095 -:100260008CA3000424A5000824E70001ACC2000010 -:10027000ACC3000400E4102B1440FFF824C60008AF -:10028000000038213C08000125080F7B9106000082 -:100290003C02000190420F7C2503000D00C3282181 -:1002A0000046102300021FC2004310210002104329 -:1002B0001840000C0000202191020001004610238C -:1002C00000021FC2004310210002184394A2000044 -:1002D00024E700010082202100E3102A1440FFFBE4 -:1002E00024A5000200041C023082FFFF00622021CE -:1002F00000041402008220213C02FFFF018210242E -:100300003083FFFF004310253C010001080040FA44 -:10031000AC220F803C05000124A50F7C90A20000B8 -:100320003C0C0001018360218D8C8018000220C2EA -:100330001080000E000038210160302124A5000C3F -:100340008CA200008CA3000424A5000824E700016F -:10035000ACC20000ACC3000400E4102B1440FFF852 -:1003600024C600083C05000124A50F7C90A20000D3 -:1003700030430007240200041062001128620005C7 -:10038000104000052402000210620008000710C09F -:10039000080040FA00000000240200061062000E6F -:1003A000000710C0080040FA0000000000A2182159 -:1003B0009463000C004B1021080040FAA443000095 -:1003C000000710C000A218218C63000C004B102104 -:1003D000080040FAAC43000000A218218C63000C16 -:1003E000004B202100A21021AC8300009442001099 -:1003F000A482000495E700063C02000190420F7CB5 -:100400003C03000190630F7A00E2C8233C02000124 -:1004100090420F7B2463002801E3402124420028FE -:100420001520001201E2302194C2000C3C010001B1 -:10043000A4220F7894C2000494C300063C0100017A -:10044000A4200F763C010001A4200F7200021400CA -:10045000004310253C010001AC220F6C9502000402 -:100460003C01000108004124A4220F703C0200015D -:1004700094420F703C03000194630F7200431021FB -:10048000A50200043C02000194420F6CA4C20004C7 -:100490003C0200018C420F6CA4C200063C04000127 -:1004A00094840F723C02000194420F703C0A0001D8 -:1004B000954A0F76004418213063FFFF0062182A26 -:1004C000240200021122000B008320233C030001C0 -:1004D00094630F7830620009104000063062FFF626 -:1004E000A4C2000C3C02000194420F783042000983 -:1004F00001425023240200011122001B2922000284 -:1005000050400005240200021120000731A2FFFF25 -:1005100008004197000000001122001D240200166F -:100520000800419731A2FFFF3C0E000195CE0F80DD -:10053000108000050180682101C4202100041C02F4 -:100540003082FFFF00627021000E1027A502000A12 -:100550003C03000190630F7B31A2FFFF00E21021FA -:100560000800418D004320233C02000194420F808B -:100570000044202100041C023082FFFF0062202181 -:10058000008070210004102708004185A502000AA0 -:100590003C05000124A50F7A90A30000146200021C -:1005A00024E2FFF2A5E2003490A2000000E2102352 -:1005B000A50200023C03000194630F803C0200018D -:1005C00094420F5A30E5FFFF0064182100451023C4 -:1005D0000062202300041C023082FFFF0062202101 -:1005E00000041027A502000A3C03000190630F7C61 -:1005F0002462000114A20005008070210163102113 -:10060000904200000800418500026200246200025E -:1006100014A20003306200FE004B1021944C000035 -:100620003C02000194420F823183FFFF3C04000131 -:1006300090840F7B0043102100E21021004420230E -:10064000008A202100041C023082FFFF006220216A -:100650000004140200822021008068210004102779 -:10066000A4C2001031A2FFFF000E1C0000431025A1 -:100670003C04000124840F72ADE20010948200005B -:100680003C05000194A50F763C0300018C630F6CC0 -:100690002442000100B92821A48200003322FFFF78 -:1006A000006220210083182B3C010001A4250F7655 -:1006B0001060000324A2FFFF3C010001A4220F767A -:1006C0003C024000030210253C010001AC240F6CE9 -:1006D000AF62100803E0000827BD00103C030001D2 -:1006E00090630F5627BDFFE824020001AFBF00143E -:1006F00010620026AFB000108F620CF42442FFFF9E -:100700003042007F000211008C4340003C01000198 -:10071000AC230F648C434008244440008C5C4004AC -:1007200030620040144000022402008824020008C5 -:100730003C010001A4220F68306200041040000553 -:10074000240200013C010001A0220F57080041D5FE -:10075000000314023C010001A0200F570003140203 -:100760003C010001A4220F549483000C24020001D8 -:100770003C010001A4200F503C010001A0220F56B3 -:100780003C010001A4230F62240200011342001E59 -:10079000000000001340000524020003134200671C -:1007A00000000000080042CF000000003C020001F1 -:1007B00094420F62241A00013C010001A4200F5E44 -:1007C0003C010001A4200F52304407FF00021BC26D -:1007D000000318233063003E3463003600021242E7 -:1007E0003042003C006218213C010001A4240F5853 -:1007F00000832021246300303C010001A4240F5A0F -:100800003C010001A4230F5C3C06000124C60F52EA -:1008100094C5000094C300023C04000194840F5A64 -:10082000006510210044102A104000133C10800085 -:1008300000A31021A4C200003C02A000AF620CF48F -:100840003C010001A0200F568F6410080090102476 -:1008500014400003000000000C0040640000000091 -:100860008F620CF400501024104000B7000000000C -:100870000800420F000000003C03000194630F5089 -:1008800000851023A4C40000006218213042FFFF3D -:100890003C010001A4230F50AF620CE83C020001B0 -:1008A00094420F6834420024AF620CEC94C30002FF -:1008B0003C02000194420F50146200123C0280007E -:1008C0003C1080003C02A000AF620CF43C0100012F -:1008D000A0200F568F6410080090102414400003CD -:1008E000000000000C004064000000008F620CF467 -:1008F000005010241440FFF700000000080042CF11 -:10090000241A0003AF620CF43C1080008F641008BE -:100910000090102414400003000000000C0040640C -:10092000000000008F620CF4005010241440FFF708 -:1009300000000000080042CF241A00033C07000119 -:1009400024E70F5094E2000003821021AF620CE014 -:100950003C0200018C420F64AF620CE43C050001D4 -:1009600094A50F5494E300003C04000194840F58B4 -:100970003C02000194420F5E00A328230082202342 -:1009800030A6FFFF3083FFFF00C3102B144000434D -:10099000000000003C02000194420F5C00021400C1 -:1009A00000621025AF620CE894E200003C030001F5 -:1009B00094630F5400441021A4E200003042FFFF72 -:1009C000144300213C0200083C02000190420F57F2 -:1009D000104000063C03000C3C02000194420F68EA -:1009E000346306240800427C0000D0213C02000150 -:1009F00094420F683C03000834630624004310252A -:100A0000AF620CEC3C1080003C02A000AF620CF422 -:100A10003C010001A0200F568F64100800901024A4 -:100A200014400003000000000C00406400000000BF -:100A30008F620CF4005010241040001500000000DC -:100A400008004283000000003C03000194630F682B -:100A5000344206243C108000006218253C028000CD -:100A6000AF630CECAF620CF48F641008009010249C -:100A700014400003000000000C004064000000006F -:100A80008F620CF4005010241440FFF700000000A7 -:100A90003C010001080042CFA4200F5E3C0200018F -:100AA00094420F5C0002140000C21025AF620CE8F3 -:100AB0003C02000190420F57104000093C03000C1B -:100AC0003C02000194420F68346306240000D021E8 -:100AD00000431025AF620CEC080042C13C108000BE -:100AE0003C02000194420F683C0300083463060492 -:100AF00000431025AF620CEC3C02000194420F5EF3 -:100B0000004510213C010001A4220F5E3C10800032 -:100B10003C02A000AF620CF43C010001A0200F5683 -:100B20008F6410080090102414400003000000009F -:100B30000C004064000000008F620CF40050102490 -:100B40001440FFF7000000008FBF00148FB00010AA -:100B500003E0000827BD00180000000027BDFFE0EB -:100B60003C04000124840EC0000028210000302134 -:100B700000003821AFBF0018AFA000100C00437870 -:100B8000AFA000140000D02124020130AF62500059 -:100B90003C010001A4200F503C010001A0200F5790 -:100BA0008FBF001803E0000827BD002027BDFFE825 -:100BB0003C1BC000AFBF0014AFB00010AF60680CAA -:100BC0008F62680434420082AF6268048F63400021 -:100BD00024020B503C010001AC220F2024020B78B0 -:100BE0003C010001AC220F3034630002AF634000CF -:100BF0000C004315008080213C010001A0220F342D -:100C0000304200FF240300021443000500000000EE -:100C10003C0200018C420F2008004308AC5000C089 -:100C20003C0200018C420F20AC5000BC8F62443467 -:100C30008F6344388F6444103C010001AC220F28BC -:100C40003C010001AC230F383C010001AC240F240F -:100C50008FBF00148FB0001003E0000827BD0018FC -:100C600003E000082402000127BDFFF818800009F6 -:100C7000000028218F63680C8F62680C1043FFFE10 -:100C80000000000024A5000100A4102A1440FFF970 -:100C90000000000003E0000827BD00088F634450F7 -:100CA0003C0200018C420F2800031C020043102B61 -:100CB000144000083C0380003C0400018C840F3881 -:100CC0008F62445000021C020083102B1040FFFC76 -:100CD0003C038000AF6344448F62444400431024CB -:100CE0001440FFFD000000008F62444803E000084C -:100CF0003042FFFF3082FFFF2442E0002C422001FF -:100D0000144000033C024000080043472402FFFF58 -:100D100000822025AF645C388F625C303042000274 -:100D20001440FFFC0000102103E000080000000058 -:100D30008F6244503C0300018C630F240800435031 -:100D40003042FFFF8F6244503042FFFF0043102BC0 -:100D50001440FFFC0000000003E000080000000059 -:100D600027BDFFE0008028213C04000124840ED030 -:100D70000000302100003821AFBF0018AFA00010E4 -:100D80000C004378AFA000140800435F000000008F -:100D90008FBF001803E0000827BD00203C020001BF -:100DA0003442D6003C0300013463D6003C04000109 -:100DB0003484DDFF3C010001AC220F4024020040DE -:100DC0003C010001AC220F443C010001AC200F3C6F -:100DD000AC600000246300040083102B5040FFFD32 -:100DE000AC60000003E00008000000000080482123 -:100DF0008FAA00103C0200018C420F3C3C04000111 -:100E00008C840F448FAB0014244300010044102B4A -:100E10003C010001AC230F3C1440000300004021C2 -:100E20003C010001AC200F3C3C0200018C420F3C15 -:100E30003C0300018C630F4091240000000211402C -:100E4000004310210048102125080001A0440000A3 -:100E5000290200081440FFF4252900013C0200018A -:100E60008C420F3C3C0300018C630F408F64680C84 -:100E70000002114000431021AC440008AC45000CB6 -:100E8000AC460010AC470014AC4A001803E0000860 -:100E9000AC4B001C00000000000000004D61696EBA -:100EA00043707542000000004D61696E43707541EA -:100EB00000000000000000000000000073746B6F71 -:100EC00066666C64000000000000000073746B6FC5 -:100ED00066666C64000000000000000066617461DA -:100EE0006C4572720000000000000000000000006D -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100073746B6F66666C645F76312E322E3000B0 -:0C0F2000000000000000000000000000C5 -:00000001FF - * Firmware is: - * Derived from proprietary unpublished source code, - * Copyright (C) 2000-2003 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware - * data in hexadecimal or equivalent format, provided this copyright - * notice is accompanying it. -/* 5705 needs a special version of the TSO firmware. */ diff --git a/firmware/ttusb-budget/dspbootcode.bin.ihex b/firmware/ttusb-budget/dspbootcode.bin.ihex deleted file mode 100644 index b4b2247077c49f4a92cd516bd8a735594f0d2499..0000000000000000000000000000000000000000 --- a/firmware/ttusb-budget/dspbootcode.bin.ihex +++ /dev/null @@ -1,820 +0,0 @@ -:1000000008AA001800030800001000000180185F13 -:100010000000018077182AEB6BF8001803FF68F8DE -:100020000018FFFEF7B8F7BEF6B9F4A0F6B7F6B5BC -:10003000F6B6F02019DFF1000001F84D01ABF6B87B -:10004000F02019DFF07301A57EF80012F000000126 -:1000500047F800117E9200F80011F00000017EF8D0 -:100060000011F00000016C89019AF7B8EEFCF02055 -:10007000FFFFF1000001F84D01BFF27301B94E021C -:10008000F495F5E356027E001100FA4C01B76B03BC -:100090000001F6B8EE04F0740DA7F07401C54A1122 -:1000A0004A1672112AE610F80011FA4501DBF495A0 -:1000B000EEFF4811F0002AC68816F495F49510EE6C -:1000C000FFFFF4E36CE9FFFF01D510F82AE7F845DC -:1000D00001E210F82AE7F4E3F07401FFEE018A165A -:1000E0008A11FC00F7B8E9204A1109F82AE6F84E0F -:1000F00001F3F27301FDF495E80172112AE649114A -:1001000080E12AC6F3000001E80081F82AE68A119E -:10011000FC00F495F073020010F82A0FFC004A115D -:10012000F074020280F82A107308000940F82A15BA -:1001300082F80011F495771003E8F5A9F830022150 -:1001400071F82A102A1556F82A0CF0E34EF82A16F0 -:10015000E8004EF82A0C8A11FC004A064A074A1D9C -:1001600068F800077D3F69F80007400068F8001D47 -:10017000FFFC6BF82A0F00018A1D8A078A06F4EB40 -:10018000EEFD76F82A0F000076000000FB80194C87 -:10019000F495E80080F82A11F980190780F82A0EF2 -:1001A000F980166676002A1210F82A11F98018E3F1 -:1001B00010F82A0EF980166610F82A0EF9801687B4 -:1001C000EE03FC004A11F6B8F495F020800011F817 -:1001D0002A5AF84D029311F82A9FF84C027C7712A4 -:1001E0002A39491201F82A9F8911F495F4957181F1 -:1001F00000116CE1FFAB02936BF82A9F0001E90547 -:1002000001E2000381F82AA0F073029572112A9F7F -:10021000F49510E12A396BF82A9F000111F82A9F02 -:1002200009F82AA0F84C029376F82A5A000076F8CA -:100230002A9F000076F82AA000008811F495481142 -:100240008A11FC004A11EEFE10F82A5AF84402B254 -:1002500076F82A5A0001F07402588811F495771044 -:100260008000F4A9F83002B24811F03000FF80009D -:1002700010F82A5BF98018D6EE028A11FC00F4957A -:100280004A084A094A0A4A0B4A0C4A0D4A104A11BE -:100290004A124A134A144A154A164A174A174A1963 -:1002A0004A0E4A064A074A1A4A1D4A1B4A1C68F85F -:1002B00000077D3F69F80007400068F8001DFFFC5B -:1002C000481868F80018FFFEF495F4954A08EEFD0A -:1002D000F07402588811F49577108000F4A9F83072 -:1002E00002EF4811F03000FF800010F82A5BF9801F -:1002F00018D6EE038A18F4958A1C8A1B8A1D8A1A5E -:100300008A078A068A0E8A198A178A178A168A1510 -:100310008A148A138A128A118A108A0D8A0C8A0B0F -:100320008A0A8A098A08F4EB4A1177112A397681F8 -:10033000005577122A1810E2000180E1000110E256 -:10034000000280E1000276E10003000076E1000493 -:1003500000AAF07402988A11FC004A118811F495E1 -:10036000F49510816FF82A9E0C88E8FF18E10001CF -:100370001AF82A9EF0301FFF80F82A9E8A11FC008E -:100380004A1177112A397681005577122A1811E21D -:10039000000181E1000111E2000281E1000276E149 -:1003A0000003000248086FE100040C98F03000FFE1 -:1003B00080E1000576E1000600AAF07402988A1137 -:1003C000FC004A1177112A397681005577122A18D4 -:1003D00010E2000180E1000110E2000280E1000271 -:1003E00076E1000300044811F00000048812F4953F -:1003F00077132A76E900E598F3000001F6B8480B78 -:1004000008F82A3CF8430371768200AAF074029837 -:100410008A11FC004A11EEF08811F495F49571816F -:10042000001471E1000100154911F3000002891167 -:10043000E7826DEA0004E7836DEB000A771A000596 -:10044000F07203AA1181F2E88082E9FF19E100014C -:10045000F1A0819211E1000CF2E88083E9FF19E13B -:10046000000DF1A081936DE9000248184918700051 -:100470000015F0000004F300000A80018102F2740C -:100480000E54F4954814EE108A11FC004A11F074D1 -:100490000C5E80F82A5C77122A3976820055771133 -:1004A0002A1810E1000180E2000110E1000280E260 -:1004B000000276E20003001CF6B856F82A16F0F0A7 -:1004C000F0F880E2000756F82A16F1F0E8FFF28013 -:1004D00080E2000656F82A16F1F8E8FFF28080E282 -:1004E000000557F82A16E8FFF28080E2000456F86B -:1004F000276CF0F0F0F880E2000B56F8276CF1F072 -:10050000E8FFF28080E2000A56F8276CF1F8E8FF75 -:10051000F28080E20009E8FF57F8276CF28080E261 -:10052000000856F8276AF0F0F0F880E2000F56F85D -:10053000276AF1F0E8FFF28080E2000E56F8276AA1 -:10054000F1F8E8FFF28080E2000D57F8276AE8FF33 -:10055000F28080E2000C76E20013000076E20012E6 -:1005600000006FF82A5C0C5880E20011E8FF18F8D0 -:100570002A5C80E2001076E20017000076E20016A6 -:1005800000006FF82A9E0C5880E20015E8FF18F86A -:100590002A9E80E2001476E2001B000076E2001A38 -:1005A000000076E20019000070E20018276E76E283 -:1005B000001F000076E2001E000076E2001D000031 -:1005C00076E2001C000076E2002000AAF074029897 -:1005D0008A11FC004A11EEFE10F82A38F84504EDA5 -:1005E00077122A1810E200028811F495771000089B -:1005F0006DE9FFDFF6A9F8200475F073047DF010B3 -:100600000021F0001A8348087EF80008F4E2F07434 -:10061000030AF07304EA4812F2740323F0000004A2 -:10062000F2740336F495E800F07304EA77112A189F -:10063000E8FF6FE100040D4818E10005F274096954 -:10064000F495F2A0F0740336F07304EA77112A18D7 -:10065000E8FF6FE100040D4818E10005F27409415C -:10066000F495F2A0F0740336F07304EAF0740357C3 -:10067000F07304EA10F82A1CF07412A4F274033622 -:10068000F495E800F07304EA4812F2740380F00075 -:100690000004F2740336F495E800F07304EA10F8ED -:1006A0002A1CF07412C5F2740336F495E800F07356 -:1006B00004EA77112A18E8FF6FE100060D4818E1F7 -:1006C000000771E100050012F2A070000012800125 -:1006D00010E10004F0740E7AF2740336F495E80029 -:1006E000F07304EAF07403BC76F82A380000EE02D6 -:1006F0008A11FC004A1177112A3976810055771248 -:100700002A1810E2000180E1000110E2000280E1FD -:10071000000276E1000300094811F000000488128D -:10072000F49577132A86E900E598F3000001F6B8FE -:10073000480B08F82A3CF843050A768200AAF074B0 -:1007400002988A11FC004A1177112A3976810055E6 -:1007500077132A1810E3000180E1000110E3000282 -:1007600080E1000213E3000381E1000348117711E7 -:100770000000F84D0544F000000488124813F00012 -:1007800000048813F495F495E5986D91F6B8481136 -:1007900008F82A3CF843053AF0202A394911F500B7 -:1007A0008911F495F49576E1000400AAF07402989A -:1007B0008A11FC004A1177112A3976810055771287 -:1007C0002A1810E2000180E1000110E2000280E13D -:1007D000000276E10003000C4811F00000048812CA -:1007E000F49577132A7AE900E598F3000001F6B84A -:1007F000480B08F82A3CF843056A768200AAF07490 -:1008000002988A11FC004A1177112A397681005525 -:1008100077122A1810E2000180E1000110E20002C4 -:1008200080E1000276E1000300194811F0000004A5 -:100830008812F49577132A5DE900E598F30000012A -:10084000F6B8480B08F82A3CF8430593768200AACC -:10085000F07402988A11FC004A11881110F82A38A5 -:10086000F84405E310F82AA1F84405BA6CE1FF56F4 -:1008700005E372122AA1F49570E22A1800116BF8B0 -:100880002AA10001F07305E372122AA1F49570E227 -:100890002A18001110F82AA1F00000018812F4951E -:1008A000F4956EE2FFFC05D173122AA14811F00005 -:1008B000000580F82AA210F82AA108F82AA2F84414 -:1008C00005E36CE1FFAB05DD76F82A38000176F828 -:1008D0002AA1000076F82AA200008A11FC00F495F3 -:1008E0004A084A094A0A4A0B4A0C4A0D4A104A1158 -:1008F0004A124A134A144A154A164A174A174A19FD -:100900004A0E4A064A074A1A4A1D4A1B4A1C68F8F8 -:1009100000077D3F69F80007400068F8001DFFFCF4 -:10092000481868F80018FFFEF495F4954A08EEFFA1 -:1009300010F82A5BF9801804F07405A2EE018A18F9 -:10094000F4958A1C8A1B8A1D8A1A8A078A068A0ECF -:100950008A198A178A178A168A158A148A138A129C -:100960008A118A108A0D8A0C8A0B8A0A8A098A08D7 -:10097000F4EBEEFD76F82A38000076F82A5A0000EB -:10098000E8014E00FB8017D6F495E80180F82A5B59 -:1009900076002A8FF98016AA10F82A5BF980175C76 -:1009A00010F82A5BF980176FFB801666F495E81A39 -:1009B000FB801687F495E81AFB801666F495E81B11 -:1009C000FB801687F495E81BEE03FC004A11F495B2 -:1009D00013028811E800F84D066AF3100001891A25 -:1009E000F495F07206691C918A11FC004A11881175 -:1009F00012031102F8450679F0100001881AF495E7 -:100A0000F072067881918A11FC004A11F495710206 -:100A10000011110361F800110001F8300691F6B8D9 -:100A20006FF800110C1F8811F3E8E8FF1881F1A09E -:100A30008181F073069DF6B86FF800110C1F8811C4 -:100A4000F33000FFF020FF001881F1A081818A11AE -:100A5000FC004A11F495110261F8000B0001F82026 -:100A600006B1490BF61F8811F495F4951081F273C5 -:100A700006B8F03000FF490BF61F8811F495F49585 -:100A80001281F4788A11FC004A11F4957102001267 -:100A900013038811E800F84D06CCF3100001891A01 -:100AA000F495F07206CB1192F2C081918A11FC008C -:100AB0008812120271010013F84506DBF0100001E4 -:100AC000881AF495F07206DAE598FC004A11EEFEF9 -:100AD0008811110410067105001261F8001200015E -:100AE000F82006EAF0000001F6B8F00000016FF807 -:100AF00000120F1F48088100F47F8001F27406BACB -:100B0000F4954811EE028A11FC004A11EEFE88129B -:100B1000110410067105001361F800130001F8209C -:100B20000709F0000001F00000018811F6B86FF825 -:100B300000130F1F81004811F47F8001F27406CE6C -:100B4000F49548124811F030FFFEEE028A11FC00C5 -:100B50004A114A164A17EEFCF495800271080016F5 -:100B60001009710B00178003710A00114817F8452E -:100B7000073F700000111003F074069F80017000A1 -:100B800000161002F074067B6D916D966CEFFFFFFE -:100B9000072FEE048A178A168A11FC004A11EEFE0E -:100BA00010F82AE808F82AE9F845076476000001F9 -:100BB00062F82AE9005EF274120BF0003040721104 -:100BC0002AE97710000FF5A9F82007616BF82AE9E8 -:100BD0000001F073076476F82AE90000EE028A113A -:100BE000FC004A118811E80075F800080008E800C8 -:100BF00075F800080009F6B8F495F020FC3F75F888 -:100C00000008000DF0200C3075F80008000C76F894 -:100C10002AE8000076F82AE900006C81079276F84D -:100C20002AEA0000FB801676F495E810E80075F8D3 -:100C300000080000F07307A876F82AEA0001FB809C -:100C40001666F495E810FB801687F495E810E80026 -:100C500075F800080000F6B8F495F020FFFF75F86D -:100C6000000800008A11FC00F4954A084A094A0A63 -:100C70004A064A074A1D68F800077D3F69F80007E1 -:100C8000400068F8001DFFFC10F82AEAF84507E16B -:100C900010F82AE8F0000001F030000F80F82AE890 -:100CA00010F82AE8F84407D6F6B8F495F020FC3F8F -:100CB00075F80008000DF0200C3075F80008000CE5 -:100CC000E80075F800080000F6B8F495F020FFFF82 -:100CD00075F8000800008A1D8A078A068A0A8A09B0 -:100CE0008A08F4EBEEFFF2740767F495E801EE0171 -:100CF000FC004A074A1D68F800077D3F69F80007B5 -:100D0000400068F8001DFFFC8A1D8A07F4EB4A11B9 -:100D10007711002876812400E80075F800080001AA -:100D2000F2740767F495E8007711001D6881007F71 -:100D3000F6B8F495F020FF807711001DF030010027 -:100D40001A818081F0740A33F07411ACF980132594 -:100D5000F9801653F9801782F074062FF98014B2C7 -:100D6000F9801910F0740DE3F07407E8F07402369E -:100D70008A11FC004A1160F8277BFFFFF830083920 -:100D800071F8277B277960F82779FFFFF83008B2E0 -:100D900010F8298608F82779F0307FFF8811F4953C -:100DA00077104000F6A9F830085810F8277908F8AD -:100DB000277AF0307FFF8811F49577104000F6A96C -:100DC000F820086376F82779FFFF76F8277BFFFF86 -:100DD000F7B8F27308D9F020FFFFF6B856F8277479 -:100DE000F0F9881156F82772F0F98812F495F49505 -:100DF000E720F4A9F830088FF120277C4811F6008D -:100E00008813F495F495108308F82779F0307FFF64 -:100E10008813F49577104000F5ABF830088F6D918A -:100E20004811F03001FF8811F495E720F7A9F83058 -:100E300008746D894811F03001FFF0E7F495480817 -:100E40004EF827744808F1F98911F495F49571E189 -:100E5000277C277A60F8277BFFFFF83008AB48082B -:100E60004EF8277276F8277BFFFF76F82779FFFF89 -:100E7000F27308D9F495E80044F8277340F8277511 -:100E800082F80011F49577108000F6A9F82008D8B0 -:100E9000F6B810F82773F000800048084EF8277461 -:100EA0004808F0F98811F495F49571E1277C277AC8 -:100EB000F7B857F82774F062FFFFF040FF80F28028 -:100EC0004EF82774E8008A11FC004A114A16EEFB1E -:100ED00011F8277109F8277389118810F495F49592 -:100EE000F6A9F82008EDF273090EF495E800F62053 -:100EF00076000041F07412EE8816F495F7B86D96FE -:100F000010F80016F847090AE7617600000076013C -:100F10000080760200FF76030000F2740CB9F495AD -:100F2000E8006CE9FFFF08FB7316000EF066004155 -:100F3000EE058A168A11FC004A11F495710200131D -:100F4000F6B877117FFF57F827724811F280F0004A -:100F500080008811F640F0E0F1F1E801F28080F8BD -:100F600027787712800057F827724812F28088128B -:100F7000F495F4956C820938E80075F800080001D2 -:100F8000F073093DF020800175F8000800017081C0 -:100F900000138A11FC004A11F0307FFF11F82986F6 -:100FA000F520F3307FFF8911F49577104000F6A902 -:100FB000F8200954F2730967F495E8026FF8277A6C -:100FC0000D20F3307FFF8911F49577104000F6A9CA -:100FD000F8200964F2730967F495E80180F8277B2B -:100FE000E8008A11FC004A1111F82986F520F33037 -:100FF0007FFF8911F49577104000F6A9F820097A4F -:10100000F273098DF495E8026FF8277A0D20F3301A -:101010007FFF8911F49577104000F6A9F820098A1E -:10102000F273098DF495E80180F82779E8008A11B8 -:10103000FC004A11F495710200128811F6B857F8B5 -:101040002772F0207FFFF280F0008000808157F847 -:101050002772E801F3F1F28080F827787711800099 -:10106000481157F82772F2808811F495F4956C8135 -:1010700009B5E80075F800080001F07309BAF0201E -:10108000800175F80008000145F8277143F82773BF -:1010900083F80011F495E720F6A9F83009C9F27336 -:1010A00009E47712000057F82772F0207FFFF280E2 -:1010B0004912F500F300800061F8000B8000F83061 -:1010C00009DCF1208000F5208912F49548126FF8B0 -:1010D00027730D00F495490B4FF827728A11FE0013 -:1010E0004812F4954A114A164A17EEFCF495710815 -:1010F00000168817F0740830481870000016F27453 -:10110000098FF00000028811F495F4956C810A0AA9 -:10111000F27408DBF4954816481870000016F27453 -:10112000098FF00000028811100270010011800088 -:10113000F27406CEF495481749114817F60088173F -:10114000E760F5A9F8200A2D4816F62088114818FE -:1011500070000011F274098FF00000028811700114 -:10116000001110028000F27406CEF4954817EE04C8 -:1011700048168A178A168A11FC00EEFDE8004EF820 -:101180002770E8004EF82772E8004EF82774E80050 -:101190004EF8277676F82779FFFF76F8277A000051 -:1011A00076F8277BFFFF76F827780000E80075F8CF -:1011B000000800017600000076010200F27412DCE3 -:1011C000F020277CEE03FC004A11EEFCF4954E0063 -:1011D00077127FFFF6B84912F180F3008000891280 -:1011E000F0E0F1F14F02E901F495480BF5405602A9 -:1011F000F18081F827787711800056004911F1803D -:101200008911F495F4956C810A81E80075F800085D -:101210000001F0730A86F020800175F800080001D3 -:101220001082EE048A11FC004A11EEFEF4954E0085 -:1012300077117FFFF6B84911F180F3008000891122 -:10124000F0E0F1F1E801F28080F827785600F12013 -:101250008000F180F495490BF84D0AABF020800135 -:1012600075F800080001F0730AAFE80075F800088F -:101270000001EE0248118A11FC004A118812130283 -:1012800077110000F84D0ACBF3100001891AF4958C -:10129000F0720ACA48111CF8297E881111F8297EBB -:1012A000F200000180F8297E819248118A11FC0029 -:1012B0004A11F495710200118812F6B8F0207FFFF0 -:1012C00057F82770F280F0008000808257F827706E -:1012D000E801F3F1F28080F8277877128000481255 -:1012E00057F82770F2808812F495F4956C820AF40E -:1012F000E80075F800080001F0730AF9F020800199 -:1013000075F80008000145F82775E71043F82771C4 -:1013100083F800126DE800046D8AF6AAF8300B0A13 -:10132000F2730B257711000057F82770F0207FFF2C -:10133000F2804911F500F300800061F8000B800095 -:10134000F8300B1DF1208000F5208911F49548112B -:101350006FF827710D00F495490B4FF8277048116D -:101360008A11FC004A114A164A17EEF08817101726 -:1013700080051016800610158007711400111005E5 -:10138000F030000188101006F0300001800849118B -:101390001005F6018009100661F800080001F82028 -:1013A0000B4B1009F0000001800971080012F4AA2B -:1013B000F8300B541009F00000018009120949119E -:1013C000F47F8009F620800A56F827704E0C100929 -:1013D00080004818F2740ACEF00000048816F495D4 -:1013E000F4956C860B6DF2730C59F495E800F6B821 -:1013F000F495560CF0F98812F495F49570E2277C78 -:101400002986E800800E4811F8450BCC77100001C2 -:10141000F4A9F8300B896CE1FFFD0B8B10E700029B -:10142000800EF0730B8B1087800EE710F5AEF8205E -:101430000BB270000017700100161004F07406CE95 -:1014400048174916F60088174811F6208811100928 -:10145000F62080004818F2740ACEF00000048816C6 -:1014600010047000001770010011F07406CE4811CE -:1014700000048004F0730BBC7000001770010011B1 -:101480001004F07406CE4811000480044911481677 -:10149000F6208816F495F4956C860BCC100A800023 -:1014A0004818F2740ACEF00000048816120AF845B3 -:1014B0000C33710A0010F4AEF8300C1C4816F0E141 -:1014C00088111208F8450BDB6D891207F8450BE906 -:1014D0001007800070020011100680011004F074E3 -:1014E00006DCF0730BEF48116F000C9F1004F074D2 -:1014F0000AB3110EF1C0810E10064911F6008006E4 -:101500001005F6208811F000000148086F000C9FBC -:101510004818F2740ACEF00000041207F8450C11C6 -:101520001007800070020011100680011004F07492 -:1015300006DCF0730C1748116F000C9F1004F07458 -:101540000AB3110EF1C0810EF0730C331207F84587 -:101550000C2A10078000100680011005800210047C -:10156000F07406DCF0730C3012056F000C9F100451 -:10157000F0740AB3110EF1C0810E76000001481814 -:10158000F2740ACEF0000004710400117081298603 -:10159000100E1CF82986800E760000014818F2749F -:1015A0000ACEF0000004100E71040011808110F8C2 -:1015B0002986F0000001F0307FFF80F829861009AD -:1015C000F00000028009EE108A178A168A11FC00CA -:1015D00010F8277508F82771F01000014808FC0082 -:1015E0004A114A16EEFFF49571040016F00000014E -:1015F00048084EF8297C6DEEFFFD4816F8450C9919 -:1016000056F8297CF0740A5A881110F8297DF000E8 -:10161000000148084EF8297C10F82982F0000001EA -:101620008810F495F495F4A9FA300C9680F8298284 -:1016300056F82980F00000014EF8298073112982A4 -:101640006CEEFFFF0C76EE018A168A11FC004A113F -:1016500076F82984000076F829850001E8004EF824 -:101660002A0C76F82986000076F829870000771181 -:1016700029887681AAAA76E10001AAAA76E1000269 -:1016800000008A11FC004A11EEFCF495710600146A -:10169000710700137108001271090015771000FF1F -:1016A000F4AAF8300D44491353F82A0C4FF82A0CC9 -:1016B0007312000EF166000D8911F4957710000188 -:1016C00071E124000011F4A9F8300D177710000221 -:1016D000F4A9F8300CEC7711298A76810000E80033 -:1016E0007714000077130000F0730D486C830CFA38 -:1016F0007711298A4812F0E8F04080008081E800E4 -:1017000077140000F0730D484913F340800081F80E -:10171000298A61F800150001F8200D0769F8298A67 -:10172000400061F800140001F8200D0F69F8298AC3 -:1017300020007711298A4912F3E81B818181F07317 -:101740000D4811F82984F84C0D37771129887681D6 -:10175000AAAA11F82985F3100001F340AA0081E13B -:101760000001760000028001700200147003001373 -:10177000F2740B28F495481171F829852984F073C7 -:101780000D737600000080017602000070030013E4 -:10179000F2740B28F495E800F0730D737711298A21 -:1017A0007081001311F82984F84C0D68771129888D -:1017B0007681AAAA11F82985F3100001F340AA0046 -:1017C00081E10001760000038001700200147003C3 -:1017D0000013F2740B28F495481171F829852984B7 -:1017E000F0730D7376000001800170020014700325 -:1017F0000013F2740B28F49548116BF82984FFFF4D -:10180000EE048A11FC004A11F540F495480BF47877 -:101810008811F495F4956CE1FFB90D88F2730DA56C -:10182000F495E860F200000661F800110020F8303D -:101830000D9861F8000B0001F8200DA3F2000007DD -:10184000F0730DA361F8000B0001F8200DA1F273F5 -:101850000DA3F0000001F00000024808F47F8A1197 -:10186000FC00EEFFF07407FDF0740744F0740DB453 -:10187000F0740205F0740460F0730DAAEEFD10F828 -:101880002AA3F8440DCB10F82AA4F8450DD776000A -:101890000200F27409E8F020220076F82AA4000081 -:1018A00076F82AA70000F0730DD776000200F274D4 -:1018B00009E8F020200076F82AA3000076F82AA78D -:1018C0000001F0740C5EF0E0F0103A98F8470DE17A -:1018D00076F8276E0000EE03FC004A11EEFE771149 -:1018E00020007600AAAA76010200F274066CF49534 -:1018F000481176005555760102004811F274066CC5 -:10190000F000020076F82AA3000076F82AA400006E -:10191000E8004E00FB80153EF495E80480F82AA507 -:1019200076002AA8F980148776002AADFB8013621E -:10193000F495E80210F82AA5F9801463FB80166676 -:10194000F495E81CFB801687F495E81CE8014E002E -:10195000FB8017D6F495E80080F82AA676002AB70F -:10196000F98016AA10F82AA6F980175C10F82AA6A2 -:10197000F980176FEE028A11FC00F4954A084A09B3 -:101980004A0A4A074A1D68F800077D3F69F80007C0 -:10199000400068F8001DFFFC10F82AA7F8440E4B21 -:1019A00076F82AA30001F0730E4E76F82AA40001FF -:1019B0008A1D8A078A0A8A098A08F4EB4A114A169C -:1019C0004A17EEFE880E71080016710600171107FF -:1019D000F066000DF00025A0881176010006810058 -:1019E000F27406CEF00000017601000670000016C9 -:1019F0004811F27406CEF000000770810017EE0265 -:101A00008A178A168A11FC004A11880E7102001288 -:101A10001103F066000DF00024008811F495708128 -:101A200000126EE2FFFE0E8DF495E800E80180E101 -:101A3000000276E1000300FF76E10004000076E199 -:101A4000000B000076E1000C000081E100018A112A -:101A5000FC004A11EEFC880EF495F166000DF300CF -:101A600024008911F495F49576E1000C000076E1EC -:101A7000000B000076E10002000176000000760114 -:101A80000000800276030000F2740CB9F495E800BF -:101A9000EE048A11FC004A118819F4957319000E9E -:101AA000F166000DF2002400771525A077140000E0 -:101AB000771A001FF0720F14F6B849190985F84C0F -:101AC0000F13F100000589114915F3000001891376 -:101AD0004915F3000007891211931D91199289107D -:101AE000F495F4956C800F1311931D911992891040 -:101AF000F495F4956C800F1311931D911992891030 -:101B0000F495F4956C800F1311931D91199289101F -:101B1000F495F4956C800F1311931D91199289100F -:101B2000F495F4956C800F1311931D9119928911FE -:101B3000F495F4956C810F136D946DED000D4814C0 -:101B40008A11FC004A114A164A17EEF88817100D40 -:101B50008004100C8005710E00167317000EF066DD -:101B6000000DF0002400881110F82763F8450F32AB -:101B7000F2740E9FF495481710F82760F8440F3D53 -:101B800060E100020001F8200F6DF07311331004C2 -:101B900080001005F074069F1104F3000001810419 -:101BA0006D8E7710000171E100020012F4AAF83086 -:101BB0000F6277100002F4AAF8300F6D45E1000BB8 -:101BC000881043E1000C83F80012F495F495F4AA10 -:101BD000F8300F6DF0730F96F50081044916F5206B -:101BE000891676E1000C000076E10004000048163A -:101BF000F8451133F7B871E10002001210F8001235 -:101C0000F0100003F8460F8C10F80012F0100003DB -:101C1000F845101677100001F4AAF8300F9C7710E1 -:101C20000002F4AAF8300FA8F0730F9677100004A2 -:101C3000F4AAF83010B777100005F4AAF83010BCF9 -:101C4000F2740E9FF4954817F073113176E1000C91 -:101C5000000076E1000B000076E10004000076E170 -:101C60000002000211E1000CE803F6208912F4954D -:101C700077100003F5AAF8300FB66BF8276F000154 -:101C80008810F495F495F5AEF8200FBD481680063F -:101C90008813F49577100003F6ABF8200FC86BF8A3 -:101CA000276F00011206F845100010E100048000C3 -:101CB0001005800110048002100680034811F274A0 -:101CC000071EF0000005100600E1000480E100049A -:101CD000100600E1000C80E1000C881211061004CF -:101CE000F60080044816F62088168913F4957710BC -:101CF0000003F6ABF8200FF56BF8276F00017710A3 -:101D0000000C71E100040013F6ABF82010006BF832 -:101D1000276F00016CE2FFFD1131F6B86FE100059D -:101D20000C486FE100060C18F0300FFFF0000003C4 -:101D300080E1000B76E1000200034816F8451133FC -:101D400071E1000C001210E1000B4912F62088131B -:101D5000E80CF6208810F495F495F5ABF8201027E0 -:101D6000481380068810F495F495F5AEF8201030ED -:101D7000700600161206F845105F10E1000480009E -:101D80001005800110048002100680034811F274CF -:101D9000071EF0000005100600E1000480E10004C9 -:101DA000100600E1000C80E1000C881211061004FE -:101DB000F60080044816F6208816F4957710000C7B -:101DC00071E100040013F6ABF820105F6BF8276F89 -:101DD00000017710000CF6AAF820106BF2740E9F29 -:101DE000F495481771E1000C00127710000CF4AA6A -:101DF000F830107C7710000C71E1000B0013F6AB8B -:101E0000F83010B4E730F7AAF83010B4F2740EC10D -:101E1000F49548178812F495F4956C82108D76E14C -:101E20000004000076E100020005F07310B476E1D2 -:101E3000000200047710000C71E1000B0012F5AAFB -:101E4000F820109AF073109C7712000C76000000B6 -:101E50007001001270020017760300014811F2743D -:101E60000CB9F000000576E1000400007710000CCA -:101E700071E1000B0012F6AAF820111C4816F84573 -:101E8000113360E100020005F82010DF10E1000BC3 -:101E900008E1000C11E10004F84D10C76BF8276F42 -:101EA00000018810F495F495F5AEF82010CF48168F -:101EB000F4954808F84511166FE1000C0D0081E11A -:101EC000000C1104F50081044916F5208916F07301 -:101ED000110E10E1000B71E1000C00128810F49556 -:101EE000F495F6AAF83011164912F6208810F495E8 -:101EF000F495F5AEF82010F3481680064808F8452A -:101F000011161004700200178000760300001006FE -:101F100080011005F0740CB9100600E1000C80E19E -:101F2000000C11061004F60080044816F6208816EE -:101F300010E1000C08E1000BF845111CF0731131A1 -:101F4000F2740E9FF4954817F073113376E1000C8C -:101F5000000076E1000B000076E1000200011004B1 -:101F600080001005F074069F8812F495771000FF2A -:101F7000F4AAF83011336C860F70EE088A178A16AF -:101F80008A11FC004A11EEFCF495710600128811CA -:101F90007312000EF166000DF30024008914138102 -:101FA000F77AF330000181F8276013E10001F77C34 -:101FB000F330000381F82761E90F19E1000181F88E -:101FC000276271E400030013F6B84913F30000011F -:101FD000F330000F490B09F82762F84D117577109F -:101FE00000FFF4ABF830117557F8276CF3000001CF -:101FF0004FF8276C76F827630001F073117876F8B4 -:102000002763000070E40003276276F8276400006D -:1020100011F8276161F8000B0002F820118DE90129 -:102020006FE100020F1881F8276411F8276161F849 -:10203000000B0001F82011A910F82764F10000043A -:102040008913E9B8F52081F8276560840002F8203B -:1020500011A9700000117001001370022765F2745D -:102060000F18F4954812EE048A11FC004A114A1622 -:102070004A17EEFCE8004EF82766E8004EF827689D -:10208000E8004EF8276CE8004EF8276A77122740E0 -:1020900077112400771A001FF07211DB7092001183 -:1020A00076E10001FFFF7681000076E1000200008A -:1020B00076E1000300FF76E1000C000076E1000B02 -:1020C000000076E1000400006DE9000DF02025A07D -:1020D000F10000078911F100000181028816F495D2 -:1020E00077170020768600FF760000007601000654 -:1020F0001002F074066C7600000076010006F2749F -:10210000066CF49548111002F000000D80026DE994 -:10211000000D6DEE000D6CEFFFFF11E8F0740C9DEB -:10212000EE048A178A168A11FC004A114A164A17C9 -:10213000EEFA8811100A4911F84D129F4808F84527 -:10214000129F80041281F5788912F495F4956CE25F -:10215000FFB9128A61F800080080F830128A13E192 -:102160000001F0E8F778F1A0F2301FFF8817F4952E -:10217000771224007716000077130020F6B848176E -:1021800008E20001F84512426DEA000D6D966CEB15 -:10219000FFFF1234F073129056F8276AF000000126 -:1021A0004EF8276A60820001F83012547000001661 -:1021B000F2741138F4954811F07312907000001603 -:1021C000F2741138F495481172102A9EF495F4AF08 -:1021D000F830126E76000000760100BC7002001626 -:1021E00076030000F2740CB9F4954811F073129064 -:1021F00010F8276EF844129076000000760100BCBB -:102200007002001676030000F2740CB9F4954811C0 -:10221000F0740C5EF0E0F0101388F842129076F83B -:10222000276E0001F073129056F82766F000000147 -:102230004EF827666DE9005E56F82768F000000149 -:102240004EF82768710400126EEAFFFF121870043E -:102250000012EE068A178A168A11FC004A11EEFE59 -:10226000880EF495F066000DF00025A08811F49515 -:10227000F495768100FF7600000076010006F27486 -:10228000066CF0000001760000007601000648119F -:10229000F274066CF0000007EE028A11FC004A118D -:1022A000880EF495F066000DF00024008811F49576 -:1022B000F49576E10001FFFF7681000076E10002EF -:1022C000000076E1000300FF8A11FC004A11F4953A -:1022D00013038811FA4D12EC71020012F310000181 -:1022E000891AF495F07212EB709100128A11FC00B9 -:1022F000F4954A0B4A0C4A0DF7B8EEFE10F80008A8 -:102300001106F1C08300F4851106F7858106F6B841 -:10231000EC0F1E0661008000F8201305F484EE0225 -:102320008A0D8A0C8A0BFC00F4954A0B4A0C4A0D64 -:10233000EEFEF7B8800010F80008F4851106F78566 -:102340008106F6B8EC0F1E06F0F061008000F82060 -:102350001320F484EE028A0D8A0C8A0BFC004A11C9 -:102360007711007B76812EEC7711007BEEFF718177 -:102370000011EE0176E10001000076E100040000AA -:1023800076E10006000076E10062000076E100766A -:10239000000076E10092000076E10094000076E112 -:1023A00000B0000076E100B3000076E100BE00005E -:1023B00076E100BF000076E100C1000076E100C3D5 -:1023C000000076E100C5000076E100C700007681DC -:1023D00000008A11F495F4E44A114A164A17EEFFF8 -:1023E000F49571060016FB8016A28817F495F7B8CD -:1023F00010F80017F0100002FA4613887711000059 -:1024000010F80017F0100002F84513F910F8001743 -:10241000F845143910F80017F0100001F845141FA2 -:10242000F073145210F80017F0100003F84513D39E -:1024300010F80017F0100006F84414527712007BD1 -:102440007182001461E400070040F830145249140E -:102450004817F6008812F495771300557711005746 -:102460006DEA003BE50110E600068081481400F8A3 -:1024700000178812F4957711005510E20040808112 -:102480007711005710E6000780817711005510E2A0 -:102490000045808110E60008771100578081771190 -:1024A000005510E2004A80817711005710E60009BC -:1024B0008081F2731452771103C07712007B10826F -:1024C000F00000078813F495F495961BF830145229 -:1024D00010E300357712005580827712005710E61E -:1024E000000480827712005510E300378082771253 -:1024F000005710E6000580824811F0400010F2738A -:102500001450F04000207712007B1082F00000078A -:102510008812F495F495960DF830145210E20034B8 -:102520007713005580837713005710E600028083ED -:1025300010E200367712005580827712005710E6BD -:10254000000380824811F0400004F2731450F04000 -:1025500000087712007B1082F00000078812F495C3 -:10256000F495960EF830145210E2003377120055AD -:1025700080827712005710E6000180824811F273C2 -:102580001450F04000027712007B1082F000000728 -:102590008812F495F495960FF830145210E2003238 -:1025A000771200557713005780824811E762F04098 -:1025B0000001E5018811F4957712007B48117182C2 -:1025C00000121AE2000780E20007F980169AEE0175 -:1025D0008A1748118A168A11F4E44A118811770E75 -:1025E000000577120055E804F6B828E10002EEFF76 -:1025F000808277120057F0208000EE011A82771255 -:1026000000578082E80132E10002F5827711005420 -:10261000F693188177110054F2A080818A11F49505 -:10262000F4E44A114A16F49571040011FB8016A2D5 -:102630008816F4957712005510E600038082771211 -:10264000005610E100027713005680827712005680 -:1026500010E10003808210E10004771200568082AE -:102660007712005610E100018082E712E501F9803F -:10267000169A8A168A11F4E44A114A164A17EEF994 -:102680007711007B76000016760100177602001A9B -:102690007603001B7604001C7605001D718100176F -:1026A00071E7000600111081F84414DFF980165319 -:1026B000F6B8FB801585F020FFFFF6B8FB80160802 -:1026C000F020FFFF7711007B7181001776E700068D -:1026D00000014817771600007710000477150003F3 -:1026E0007714000277130001F000003976E7000844 -:1026F000001F76E700070000880E771A00054817CC -:10270000F0000009881248188819E800F072152CAA -:10271000731900117682000011917311001970E293 -:102720000003001670E20004001370E200050014BC -:1027300081E2000170E20006001570E2000700105F -:1027400080E20002730E0011F100001E6DEE000524 -:102750006DEB00056DEC00056DED00056DE8000505 -:10276000F000000181916DEA00087311000EEE0780 -:1027700076E70041002476E70046002576E7004B27 -:10278000002676E7005000278A178A168A11F4E49B -:102790004A114A16EEFE881156064E00F98016A21E -:1027A000F7B810F80011F010FFFFFA451560771622 -:1027B000FFFF7712007B49111082F603F000000939 -:1027C0008811F495F4951081F8441571F273157120 -:1027D000F495E7167711007B1081F000000988114D -:1027E000F495771200061081F845155C6EEAFFFF3C -:1027F00015696DE9000876860001E9015600F1804F -:1028000010F8000BF845157EFB801585F4954816E9 -:10281000F980169AEE0248168A168A11F4E44A11D3 -:10282000EEFFFB8016A28811F4957710FFFFF4A944 -:10283000F83015C410E1000377120055808277123A -:1028400000567682000077120056768200007712DA -:1028500000567682000077120056768200007712CA -:1028600000567682000010E10002F000000832F805 -:10287000000877120054E801F482F493188277126A -:102880000054F0400000808210E10001F9801676CB -:1028900010E10001F9801666F07316037711007BD2 -:1028A0007181001171E1000700127682000010E1D1 -:1028B0000009F98015857711007B7181001110E105 -:1028C0000009FB801585F00000087711007B7181FD -:1028D000001110E10009FB801585F0000010771150 -:1028E000007B7181001110E10009FB801585F0006B -:1028F00000187711007B7181001110E10009FB8045 -:102900001585F00000207711007B7181001110E126 -:102910000009FB801585F0000028F980169AEE0169 -:102920008A11F4E44A11EEFFFB8016A28811F49597 -:102930007710FFFFF4A9F830164177110055768122 -:10294000001E7711005676810000771100567681BF -:1029500000007711005676810000771100567681CD -:1029600000007711005676810000771100567681BD -:1029700000007711005676810000771100567681AD -:102980000000771100567681000077110056F2732F -:10299000164E768100007711007B7181001171E184 -:1029A000000700127682000010E10039F980160855 -:1029B000F980169AEE018A11F4E44A117711007B2E -:1029C0001081F00000048811F495F4951081FA4408 -:1029D0001663F495EEFF76810001EE018A11F4E4AE -:1029E000F01000104A1132F80008EEFF77110001D4 -:1029F000E801EE01F4821A8180818A11F495F4E4F1 -:102A0000F01000104A1132F80008EEFFE8017711CB -:102A10000000F482EE01F493188180818A11F4950C -:102A2000F4E44A11F01000107711000032F80008A9 -:102A3000EEFF1181E801EE0177110000F482F2A0AF -:102A400080818A11F495F4E4F273169EF6BBF49536 -:102A5000F495F495F495F4E4F27316A6F7BBF495A7 -:102A6000F495F495F495F4E44A114A16F49571043A -:102A70000016FB8016A28811F49571E10005001282 -:102A80007682000E10E6000E71E1000600128082D0 -:102A900071E1000500127682000D71E1000600125E -:102AA00010E6000D808271E1000500127682000CB4 -:102AB00010E6000C71E100060012808271E1000551 -:102AC00000127682000B10E6000B71E10006001286 -:102AD000808271E1000500127682000A71E1000631 -:102AE000001210E6000A808271E100050012768271 -:102AF000000910E6000971E100060012808271E110 -:102B0000000500127682000871E10006001210E64E -:102B10000008808271E1000500127682000710E64D -:102B2000000771E100060012808271E100050012C9 -:102B30007682000671E10006001210E6000680822F -:102B400071E1000500127682000571E100060012B5 -:102B500010E60005808271E1000500127682000413 -:102B600071E10006001210E60004808271E10005A8 -:102B700000127682000371E10006001210E60003E5 -:102B8000808271E1000500127682000210E60002E8 -:102B900071E100060012808271E100050012768268 -:102BA000000110E6000171E100060012808271E16F -:102BB000000500127682000071E100060013E76252 -:102BC000E501F980169A8A168A11F4E44A118811EF -:102BD000F495F49571E100050012EEFF7682000095 -:102BE000EE0171E100060011698100018A11F4957E -:102BF000F4E44A118811F495F49571E1000500128E -:102C0000EEFF76820001EE0171E10006001169819C -:102C100000018A11F495F4E44A117711007B1081C8 -:102C2000F00000948811F495F4951081FA44179CF3 -:102C3000F495EEFFF98016537711007B1081F000B8 -:102C400000948811F495F49576810001EE0176E107 -:102C50000001000076E10002002176E1000300207F -:102C600076E10004002376E10005002276E100060B -:102C7000003876E10007003976E10008001576E1BA -:102C80000009001476E1000A000076E1000B004123 -:102C900076E1000C004076E1000D004376E1000E85 -:102CA000004276E1000F004876E10010004976E12D -:102CB0000011001B76E10012001A8A11F495F4E469 -:102CC0004A11EEFD881156064E00F98016A27712C1 -:102CD000007B770E0009108228F80011F0000095A3 -:102CE0008811F495F4951081F84517F0F27317FDEB -:102CF0007711FFFF76810001E9015600F18010F89D -:102D0000000BF84517FDFB801810F4954811F98069 -:102D1000169AEE0348118A11F495F4E44A118811C9 -:102D2000F495EEFF71E100010011EE0110818A11AE -:102D3000F495F4E44A11EEFFFB8016A28811F49595 -:102D40007710FFFFF4A9F83018C371E100050012F5 -:102D50007682000071E1000600127682000071E1C7 -:102D6000000500127682000171E1000600127682F1 -:102D7000000071E1000500127682000271E1000698 -:102D800000127682000071E10005001276820003D5 -:102D900071E1000600127682000071E10005001268 -:102DA0007682000471E1000600127682000071E173 -:102DB000000500127682000571E10006001276829D -:102DC000000071E1000500127682000671E1000644 -:102DD00000127682000171E1000500127682000780 -:102DE00071E1000600127682200071E100050012F8 -:102DF0007682000871E1000600127682000071E11F -:102E0000000500127682000971E100060012768248 -:102E1000000071E1000500127682000A71E10006EF -:102E200000127682000071E1000500127682000B2C -:102E300071E1000600127682000071E100050012C7 -:102E40007682000C71E1000600127682000071E1CA -:102E5000000500127682000D71E1000600127682F4 -:102E6000000071E1000500127682000E71E100069B -:102E700000127682000010E10007F980167610E15A -:102E80000008F980167610E10007F980166610E157 -:102E90000008F9801666F07318D17711007B108155 -:102EA000FB801810F00000957711007B1081FB80EB -:102EB0001810F000009EF980169AEE018A11F4E4D1 -:102EC0004A118811EEFFF495100471E1000300111E -:102ED000EE0180818A11F495F4E44A114A16F495C2 -:102EE00071040016FB8016A28811F49571E10002AE -:102EF00000127682001010E6000171E1000300125A -:102F0000808271E10004001210E600028082E76214 -:102F100071E100020013E501F980169A8A168A1100 -:102F2000F4E44A118811EEFFEE0110E100018A116C -:102F3000F495F4E44A117711007B1081F00000B39E -:102F40008811F495F4951081FA44192AF495EEFF4E -:102F5000F98016537711007B1081F00000B38811BF -:102F6000F495F49576810001EE0176E10001000010 -:102F700076E10002001376E10003002676E100040A -:102F8000002576E10005002476E10006000076E1E8 -:102F90000007001776E10008003276E100090031F1 -:102FA00076E1000A00308A11F495F4E44A114A16D9 -:102FB0004A17EEFFF49571060017FB8016A28811E0 -:102FC000F495F7B810F80011F010FFFFFA451973E7 -:102FD0007716FFFF7712007B770E0005108228F826 -:102FE0000011F00000B48811F495F4951081F844B4 -:102FF0001984F2731984F495E7167711007B108118 -:10300000F00000B48811F495771200021081F845A1 -:10301000196F6EEAFFFF197C6DE9000561F8001772 -:103020000001FA20198F76860001FB801997F4952C -:103030004816F980169AEE018A1748168A168A11E0 -:10304000F4E44A11EEFFFB8016A28811F495771084 -:10305000FFFFF4A9F83019CC71E100020012698277 -:10306000001071E1000200126882F7FF71E10002B6 -:1030700000126882FBFF71E1000200126882FFF01B -:1030800071E1000300127682FFFF71E1000400127B -:103090007682FFFF71E1000200126982002071E177 -:1030A00000020011F27319DA6881FFEF7711007BDB -:1030B0001081FB801997F00000B47711007B10811C -:1030C000FB801997F00000B9F980169AEE018A1179 -:1030D000F4E400A4000019DF00012AE6000000016A -:1030E0002AE7000000032A120C01C34F0000000170 -:1030F0002A15000000022A160000000000192A5DAF -:103100000043006F0070007900720069006700687A -:10311000007400200054006500630068006E006FBA -:10312000005400720065006E0064002000410047FA -:10313000000000042A760030002E00300000000C51 -:103140002A7A004600650062002000320037002025 -:103150000032003000300031000000092A860031C2 -:103160000034003A00330035003A003300330000E9 -:10317000000F2A8F00000000000000010000000185 -:10318000000000000000000000000000000000003F -:10319000000000012A9E000000012A9F000000019B -:1031A0002AA0000000012AA1000000012AA20000BC -:1031B0000001297E000000022980000000000001BB -:1031C0002982FFFF00012AA7000000052AA87141FB -:1031D0002000200000230400000A2AAD00000000A7 -:1031E00000000000000000000000000000000000DF -:1031F000000F2AB7000000000000004000A082403D -:103200000008307F00800180000000000000000006 -:1032100000000001276E00000001276F0000000081 -:10322000000900001A8304E804CF04C504BA04B0FE -:1032300004AC049C048C0481007800000100F2734B -:1032400007EFF495F495F27307EFF495F495F273A4 -:1032500007EFF495F495F27307EFF495F495F27394 -:1032600007EFF495F495F27307EFF495F495F27384 -:1032700007EFF495F495F27307EFF495F495F27374 -:1032800007EFF495F495F27307EFF495F495F27364 -:1032900007EFF495F495F27307EFF495F495F27354 -:1032A00007EFF495F495F27307EFF495F495F27344 -:1032B00007EFF495F495F27307EFF495F495F27334 -:1032C00007AAF495F495F27307EFF495F495F27369 -:1032D00007EFF495F495F2730223F495F495F273E5 -:1032E00007EFF495F495F27307EFF495F495F27304 -:1032F00007EFF495F495F27307EFF495F495F273F4 -:1033000007EFF495F495F27307EFF495F495F273E3 -:1033100005E5F495F495F27302B5F495F495F2731E -:103320000E33F495F495F27307EFF495F4950000DD -:00000001FF diff --git a/firmware/vicam/firmware.H16 b/firmware/vicam/firmware.H16 deleted file mode 100644 index cac0cba68cc7750867c083b313ed6091879e022d..0000000000000000000000000000000000000000 --- a/firmware/vicam/firmware.H16 +++ /dev/null @@ -1,7 +0,0 @@ -:0026000000B6C31F000264E767FDFF0EC0E709DE008E00C0094003C01744034BAFC00700004BAF97CF00001D -:000A000000B6C30300036418000000FB -:0008000000B6C301000664000014 -:0696000000B6C38F060264E707000008C0E70700003EC0E7075401AA00E707C805B600E7074201D200E7077C001600E70756001800E707060092C0E70700001EC0E707FFFF22C0E707040024C0E707EC2728C0E70716018E00E78701000EC097CFD70900C0E777010092C009C1E709FE052401E70904062601E707070092C0E70500C0C0DF97CF170057001702D70900C0E777010092C00AC1E757FFFFFA050DC0E7570000FA050FC09FAFC600E70500C0C805C105C005C0DF97CF27DAFA05EF0701000B0673CF9FAF78019FAF1A036ECFE709FC052401E70902062601E707070092C0E709FC05FE05E70902060406E7090006FC05E709FE05000627DAFA05E7570100FA0502CA04C097CF9FAF660597CFE70740000206C809FC059FAFDA0297CFCF170200EF57810009069FA0B601EF57800009069FA04002EF5701000B069FA04603E70701000AC046AF47AF9FAF4002E7072E000AC0EF878000090697CF000E0100C05751009FC09E02C057500020C0C057550012C0C05756009FC072029FCFD602C10B080601D06F900806C0070800C10B08069FAF280597CF2F0E02000806C0070800C10B08069FAF28059FCFD6022F0E02000906EF87800009069FCFD602EF677FFF0906E767FFFD22C0E767EFFF24C0E787100028C09FAFB805E787E02124C09FAFA805E787080024C0E767DFFF24C0C8070A00C0070000C10701009FAF28059FAFB805C0079E009FAF4405E767FFFE24C0C00920C0E787000124C0C07700020FC1E767F7FF24C0E767F7FF24C0E787080024C008DA5EC1EF078000090697CFEF0701000A0697CFEF0700000B06EF0700000A06EF677FFF0906EF0700000D06E767EFFF28C0E76717D824C0E70700001EC0E707FFFF22C097CFC8070E069FAFDA02E7070000F205E7071000F605E7070E06F405E707D602F805C807F205C107008050AF97CF2F0C020007062F0C04000606E7070000F205E7071000F605E707E205F405E707CE02F805C807F205C107008051AF97CF9FAF66049FAF1A0359AF97CFC0070E00C10B0C0641D19FAF2805C0073C009FAF44056800C0073B009FAF44056F000C066800E0070401E80B0A06E8070000E0070002E007EC01E007FCFF97CFE707FFFFFA05EF0700000B06E7070E062401E7070E06FE05E70740002601E70740000406E707070092C097CFEF0702000B069FAF7801EF77800007069FC01404EF770100070637C0EF7701000D060FC1EF0701000D06C0070200C10730009FAF2805C0070100C10702009FAF2805C807FF4F9FAFA805C00738009FAF4405C177030002C108DA75C1C17701000AC1C0070100C10702009FAF2805EF07010006062CCFC0070100C10704009FAF2805EF070000060622CFEF0700000D06EF57010006061BC0C0070100C10701009FAF2805C0070200C10730009FAF2805C807FF4F9FAFA805C00738009FAF4405C1670300C157030002C008DA73C1C0070200C1071200EF570000060602C0C10723009FAF2805C0071400C10BEA059FAF2805C0073E009FAF0A05E709E405FA0527D8FA05E7070E06FC05E7074E060006E707400002069FAF66059FAFC60097CFC10BE20541D001D2C11723009FAFDC04C0070400C10BE3059FAF2805C0070600C109E6059FAF2805C0070700C109E605C1D19FAF2805C0070B00C109E8059FAF2805C0070C00C109E805C1D19FAF2805C0070D00C10709009FAF2805C0070300C10732009FAF2805C0070F00C10700009FAF280597CFE767FFD924C0C8070A004000C0670002278024C0E787000424C0E767FFF924C001D208DA72C1E787002024C097CF27001EC0E787FF0022C0E7677FFF24C0E787800024C0E787800024C097CF9FAF0A0567001EC0E767BFFF24C0E787400024C0E787400024C097CF9FAF0A05E76700FF22C0E767FFFE24C0E767FFFE24C0C10920C0E787000124C097CFC0074000C809FC05E76700FF22C0E767FFFE24C0E767BFFF24C0E767BFFF24C000DAE80920C0E787400024C0E787400024C000DAE80920C06DC1E787000124C097CFE707320012C0E777008012C07CC097CFE707204E12C0E777008012C07CC097CF0902190001010080960904000001000000000705810240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1 -:0136000000B6C32F0103640E0014001A00200026004A0064006A0092009A00A000B200B800BE00C200C800CE00DC00DA00E200E000E800E600EE00EC00F200F80002010A010E0112011E01220128012C0132013601440150015E01720176017A01800188018C0194019C01A001A401AA01B001B401BA01D001DA01F601FA01020234023C0244024A0250025602740278027E0284028A02880290028E029402A202A802AE02B402BA02B802C002BE02C402D002D402E002E602EE02F802FC0206031E032403280330032E033C034A034E03540358035E0366036E037A0386038E039603B203B803C603CC03D403DA03E803F403FC03040420042A04320436043E044404420448044E044C04540452045A045E046204680474047C04800488048C0494049A04A204A604AE04B404C004CC04D8042A0546056C0500005E -:0008000000B6C301000664000014 -:0000000001FF diff --git a/firmware/whiteheat.HEX b/firmware/whiteheat.HEX deleted file mode 100644 index 8dae60295d55a08213af20d3a65fab9277843b1e..0000000000000000000000000000000000000000 --- a/firmware/whiteheat.HEX +++ /dev/null @@ -1,1097 +0,0 @@ -:030000000297E381 -:03000300021312D3 -:03000B00020BB530 -:0300330002081CA4 -:03004300020A00AE -:03005B0002833BE2 -:10037000907FE9E070030204731470030204E72421 -:10038000FE700302054F24FB700302046414700323 -:1003900002045214700302043A1470030204492444 -:1003A00005600302059E907FEBE024FE601614605A -:1003B000362402707B7412907FD4F07400907FD545 -:1003C000F00205A5907FEAE0FF120A99EA49600D64 -:1003D000EA907FD4F0E9907FD5F00205A5907FB434 -:1003E000E04401F00205A5907FEAE0FF120A58EA16 -:1003F00049603312A23BF54E907FEEE0FFE54ED30D -:100400009F4003E0F54EE54ED394404003754E40C7 -:10041000AE02AF017C7F7D00AB4E129137907FB56D -:10042000E54EF00205A5907FB4E04401F00205A579 -:10043000907FB4E04401F00205A5907F00E521F033 -:10044000907FB57401F00205A5907FEAE0F52102E6 -:1004500005A5907FEAE0F535D202438810D2EBD2B1 -:10046000A80205A5907F00E535F0907FB57401F0F6 -:100470000205A5907FE8E0247F6024146031240207 -:10048000705BA200E433FF25E0FFA205E4334F9048 -:100490007F00F0E4A3F0907FB57402F00205A5E4BC -:1004A000907F00F0A3F0907FB57402F00205A59054 -:1004B0007FECE0F45480FFC4540FFFE054072F2575 -:1004C000E024B4F582E4347FF583E05401907F00AA -:1004D000F0E4A3F0907FB57402F00205A5907FB41C -:1004E000E04401F00205A5907FE8E024FE601D24B1 -:1004F0000260030205A5907FEAE0B40105C2000294 -:1005000005A5907FB4E04401F00205A5907FEAE0E4 -:100510007034907FECE0FF5407FEF54EEF30E703B8 -:10052000434E10907FD7E54EF0E54E4420F0EFF4B7 -:100530005480FDC4540F2E25E024B4F582E4347FAA -:10054000F583E4F0805F907FB4E04401F080569042 -:100550007FE8E024FE60182402704A907FEAE0B44D -:100560000104D200803F907FB4E04401F0803690D7 -:100570007FEAE07020907FECE0F45480FFC4540FD9 -:10058000FFE054072F25E024B4F582E4347FF5839F -:100590007401F08010907FB4E04401F08007907FF8 -:0C05A000B4E04401F0907FB4E04402F0AD -:0105AC00222C -:1005AD00754AFF7549FF75480F754700D203C2069E -:1005BD00C202C200C205C2019003007419F0E4909A -:1005CD0001BCF0C2049001C0F0A3F0C2AFC2A812EA -:1005DD000C22E49002AFF09001BDF0900100F0A369 -:1005ED00F0A3F0A3F0A3F0A37410F0A37401F0A393 -:1005FD007408F07E017F001219C1754C12754D0AF9 -:10060D0090010BE0FF054DE54DAC4C7002054C140F -:10061D00F5828C83EFF090010CE04480FF054DE5F1 -:10062D004DAC4C7002054C14F5828C83EFF09001AB -:10063D000DE0FF054DE54DAC4C7002054C14F582F7 -:10064D008C83EFF090010EE0FF054DE54DAC4C7045 -:10065D0002054C14F5828C83EFF090120AE493FF9F -:10066D0074019390011CCFF0A3EFF090011CE0FFFB -:10067D00A3E0FEEF6EFF90011CF0A3E06FFFF09082 -:10068D00011CE06FF0E0FEA3E0FFE4FCFD755210ED -:10069D007553027554127555AC129426754C12751E -:1006AD004DB290010DE0FF054DE54DAC4C700205CE -:1006BD004C14F5828C83EFF090010EE0FF054DE5B3 -:1006CD004DAC4C7002054C14F5828C83EFF0907F8D -:1006DD0092E0FFC4540F2441FF054DE54DAC4C7025 -:1006ED0002054C14F5828C83EFF0054DE54DAE4CB3 -:1006FD007002054C14F5828E83E4F07582107583BB -:10070D0001E0FCA3E0FDA3E0FEA3E0FF90011812C1 -:10071D00A3EE7E017F181286BE900118E0FCA3E0C7 -:10072D00FDA3E0FEA3E0FF75520A75530675541242 -:10073D007555B8129426D2E843D820907FAB74FF3C -:10074D00F05391EF907FAFE04401F0907FAEE04425 -:10075D001FF0D2AF20012E20012BA2039207120908 -:10076D00C575465075456D7544337543002001E4DC -:10077D007FFF7EFF7DFF7CFF784312A3D7EC4D4EAC -:10078D004F60D180E8300105120370C20130060AB6 -:10079D001209FB5003120AE8C20612965E9001BDC3 -:1007AD00E0600C129201E49001BDF0907FD3F090C7 -:1007BD0002AFE0B40F031299B912A095E4FF7401D2 -:1007CD00A807088002C333D8FCFE9001BCE05E6030 -:1007DD001474282FF8E6D3940A40047E0180027E1B -:1007ED00008E4B8003754B0174682FF582E4342025 -:1007FD00F583E54BF00FBF04C5E52CD3940A4004F7 -:0E080D007F0180027F0090206CEFF0020792C6 -:01081B0022BA -:04081C0053D8EF328C -:10082000E533C39401400E907F93E04430F0907F15 -:1008300095E044C0F07FF47E011209AE907F96E00F -:1008400054FEF07F0A7E001209AE907F96E04408C5 -:10085000F07F057E001209AE907F96E054FBF07F9A -:10086000057E001209AEE533C39401500E7F027D70 -:10087000FF1282EA7F057E001209AE907F96E04467 -:1008800002F0E0547FF07F057E001209AE907F9663 -:10089000E04440F07F057E001209AE907F96E05460 -:1008A000BFF07F327E001209AE907F96E04440F0A8 -:0808B0007F327E001209AE2226 -:1008B800907F96E054FDF0E04480F07F0A7E0012BD -:1008C80009AEE533C39401500E7F02E4FD1282EABB -:1008D8007F057E001209AE907F96E054BFF07F0539 -:1008E8007E001209AE907F96E04404F07F057E00FA -:1008F8001209AE907F96E054F7F07F057E0012094A -:10090800AE907F96E04401F07F057E001209AEE5C7 -:1009180033C39401400E907F93E054CFF0907F95BD -:08092800E0543FF0120B002225 -:10093000900AF4E4937076907F937430F0907F94F3 -:10094000743CF0907F9574C6F07F0A7E001209AE69 -:10095000E4907F9CF0907F967408F0907F9C74CF19 -:10096000F07F0A7E001209AE902070E0FFC4540FA1 -:10097000F533C394015007907F96E04480F0E490F3 -:100980007F97F0907F9D7402F0E533C39401400B94 -:10099000E4907F98F0907F9E74C0F0907FE2741294 -:0E09A000F01208207582F475830A74FFF022AD -:1009AE008E5D8F5EE55E155EAE5D7002155D4E600E -:0709BE00051209EA80EE2298 -:1009C500907FD6E054FBF0E04408F0300704E044A3 -:1009D50002F07FD07E071209AE907FD6E054F7F083 -:0509E500E04404F022D3 -:1009EA007400F58690FDA57C05A3E582458370F920 -:0109FA0022DA -:0509FB001208B8D32230 -:100A0000020C4E00020C8100020C6600020CC000B9 -:100A1000020CAA00020AED00020AEE00020AEF0030 -:100A2000020CDB00020DCB00020D1700020E2B00A2 -:100A3000020D5300020E8B00020D8F00020EEB0020 -:100A4000020AF000020AF200020AF100020AF300B0 -:080A5000020F4B00020F6100D0 -:020A58008F4FBE -:100A5A00E4F5507551FF75521275536AAB51AA529B -:100A6A00A95390000112A254B4031DAF500550EFD0 -:100A7A00B54F012212A23B7E0029FFEE3AA9077563 -:0E0A8A0051FFF552895380D47B007A00790029 -:010A9800223B -:100A9900E4FE7551FF755212755312AB51AA52A952 -:100AA9005390000112A2546402702DAD060EEDB5EB -:100AB90007012290000212A2AD85F04FF550624F56 -:100AC900E54F6250E550624F29FDE54F3AA905759A -:0E0AD90051FFF552895380C37B007A007900EB -:010AE70022EC -:050AE800120820D322DA -:010AED0032D6 -:010AEE0032D5 -:010AEF0032D4 -:010AF00032D3 -:010AF10032D2 -:010AF20032D1 -:010AF30032D0 -:030AF400000407F4 -:090B0000907FD6E04480F080747F -:100B7D00438701000000000000000000000000227B -:100B8D00538EF7E58954F14401F589758CB1D2A9DD -:100B9D0075984075CBFF75CAF375C834E4FF7F05B2 -:070BAD007828E4F608DFFCE4 -:010BB400221E -:100BB500C0E0C083C082C0D075D000C000C006C0F0 -:010BC5000728 -:100BC600300416758CF8758A307F2FAE071FEE60DD -:100BD6003C9020007455F080F2758CB17F28EFD3DD -:100BE600942C5009A807E66001160F80F1900300C7 -:100BF600E0600214F09001C0E07002A3E0600E9085 -:0D0C060001C1E024FFF09001C0E034FFF0D8 -:0F0C1300D007D006D000D0D0D082D083D0E0322E -:100C2200D200758E10120930E533C394014008904A -:100C32007F927402F08005E4907F92F0128000129D -:0C0C42000F7D1294F7121B0C120B8D2278 -:100C4E00C0E0C083C082D2015391EF907FAB74019C -:080C5E00F0D082D083D0E03217 -:100C6600C0E0C083C082907FC4E4F05391EF907FD0 -:0B0C7600AB7404F0D082D083D0E032D9 -:100C8100C0E0C083C0825391EF907FAB7402F090BB -:100C91007FD8E0700D907FD9E07007E52C70037567 -:090CA1002C14D082D083D0E03283 -:100CAA00C0E0C083C0825391EF907FAB7410F0D044 -:060CBA0082D083D0E0327D -:100CC000C0E0C083C082300202D2065391EF907F11 -:0B0CD000AB7408F0D082D083D0E0327B -:100CDB00C0E0C083C082C0D075D0105391EF907F1D -:100CEB00A97402F0E53430E013E53230E0079020D0 -:100CFB0004E04401F0902001E04401F0E52C700386 -:0C0D0B00752C14D0D0D082D083D0E03200 -:100D1700C0E0C083C082C0D075D0105391EF907FE0 -:100D2700A97404F0E53430E113E53230E10790208F -:100D37000CE04401F0902009E04401F0E52C700339 -:0C0D4700752C14D0D0D082D083D0E032C4 -:100D5300C0E0C083C082C0D075D0105391EF907FA4 -:100D6300A97408F0E53430E213E53230E20790204D -:100D730014E04401F0902011E04401F0E52C7003ED -:0C0D8300752C14D0D0D082D083D0E03288 -:100D8F00C0E0C083C082C0D075D0105391EF907F68 -:100D9F00A97410F0E53430E313E53230E307902007 -:100DAF001CE04401F0902019E04401F0E52C7003A1 -:0C0DBF00752C14D0D0D082D083D0E0324C -:100DCB00C0E0C083C082C085C084C086758600C069 -:100DDB00D075D0105391EF907FAA7402F0E53420B8 -:100DEB00E006907FC7F08022E53130E00A907FC7A4 -:100DFB00E09002F8F08013E52230E007902004E049 -:100E0B004402F0902001E04402F0E52C7003752CB5 -:100E1B0014D0D0D086D084D085D082D083D0E0328D -:100E2B00C0E0C083C082C085C084C086758600C008 -:100E3B00D075D0105391EF907FAA7404F0E5342055 -:100E4B00E106907FC9F08022E53130E10A907FC93D -:100E5B00E09002F9F08013E52230E10790200CE0DE -:100E6B004402F0902009E04402F0E52C7003752C4D -:100E7B0014D0D0D086D084D085D082D083D0E0322D -:100E8B00C0E0C083C082C085C084C086758600C0A8 -:100E9B00D075D0105391EF907FAA7408F0E53420F1 -:100EAB00E206907FCBF08022E53130E20A907FCBD7 -:100EBB00E09002FAF08013E52230E207902014E074 -:100ECB004402F0902011E04402F0E52C7003752CE5 -:100EDB0014D0D0D086D084D085D082D083D0E032CD -:100EEB00C0E0C083C082C085C084C086758600C048 -:100EFB00D075D0105391EF907FAA7410F0E5342089 -:100F0B00E306907FCDF08022E53130E30A907FCD70 -:100F1B00E09002FBF08013E52230E30790201CE009 -:100F2B004402F0902019E04402F0E52C7003752C7C -:100F3B0014D0D0D086D084D085D082D083D0E0326C -:100F4B00C0E0C083C0825391EF907FA97480F0D032 -:060F5B0082D083D0E032D9 -:100F6100C0E0C083C0825391EF907FAA7480F0905B -:0C0F710001BD74FFF0D082D083D0E032CC -:100F7D0090012012A3FA000025809001247408F03E -:100F8D00A37401F0A3746EF0A3F0A37413F0A37413 -:100F9D0011F0E4A3F0A3F090011EF090011EE0FF0C -:100FAD0004A3F0EF75F00DA42401F9740335F0A836 -:100FBD0001FC7D017B017A01791F7E007F0D12A25C -:100FCD00127E017F1F1287A690011EE004F0E0C380 -:100FDD00940440C7E4F52790011EF090011EE0FF38 -:100FED00C39404501A74F82FF582E43402F583E4A7 -:100FFD00F074232FF8E4F690011EE004F080DCE499 -:10100D00F534E5C0602F90011E7401F090011EE0D3 -:10101D00FFD39404501FEF14FF7401A8070880023A -:10102D00C333D8FC42347E017F1E12844190011ED1 -:10103D00E004F080D7E4F53EF522F531F53290016C -:10104D001EF090011EE0FF75F008A42406F582E461 -:10105D003420F583E054F0FE74C52FF582E434019D -:10106D00F583EEF0743A2FF8A60674362FF8E4F6F1 -:10107D00742D2FF8E4F674FC2FF582E43402F58319 -:10108D00E4F090011EE004F0E0B404B6902060E0BE -:04109D00540FF54EA9 -:1010A1007003021126E490011EF090011EE0FFC3BF -:1010B100940450E47401A807088002C333D8FC5596 -:1010C1004E605A90011EE0FE75F008A42402F582DC -:1010D100E43420F583E0FFEE75F008A42405F582E1 -:1010E100E43420F583E0EE75F008A42406F582E4EB -:1010F1003420F583E0FFAF06EE75F00DA42402F570 -:1011010082E43403F583E0FCA3E0FDA3E0FEA3E069 -:10111100F5668E658D648C637D061283DF90011EFA -:06112100E004F0808522CD -:02112700AC0713 -:10112900907FA5E04480F0EC25E04441907FA6F053 -:101139007B3CAF031BEF7016907FA5E04440F09015 -:101149007FA6E0FD7D32AF051DEF60D480F8907F6A -:10115900A5E0FD30E0DC20E109E04440F07EFF7FBE -:10116900F922ED30E20C907FA5E04440F07EFF7F4C -:10117900FA22907FA5E04420F0907FA6E0FD7B1E37 -:10118900AF031BEF7016907FA5E04440F0907FA657 -:10119900E0FD7D32AF051DEF608680F8907FA5E008 -:1011A900FD20E0DC7B3CAF031BEF7019907FA5E0CD -:1011B9004440F0907FA6E0FD7D32AF051DEF70033E -:1011C90002112980F5907FA5E0FD30E0D930E209D0 -:1011D900E04440F07EFF7FFA22C2AF907FA5E04451 -:0C11E90040F0907FA6E0FDD2AFFF7E003A -:0111F50022D7 -:1012000012010001FFFFFF401007018042000102B0 -:10121000030109025800010104803C090400000A8E -:10122000FFFFFF050705810240000007050102409E -:10123000000007058202400000070502024000008E -:101240000705830240000007050302400000070570 -:1012500084024000000705040240000007058702E1 -:1012600040000007050702400000040309042403AE -:1012700043006F006E006E00650063007400200084 -:101280005400650063006800200049006E006300A0 -:101290002E001803570068006900740065004800BC -:1012A0004500410054002D0034001A035800580036 -:1012B0002D00580058002D005800580058005800C4 -:1012C000580058002A0343006F006E006600690052 -:1012D0006700750072006100740069006F006E00A5 -:1012E000200053007400720069006E006700220342 -:1012F00049006E00740065007200660061006300C2 -:101300006500200053007400720069006E006700E1 -:021310000000DB -:10131200C0E0C0F0C083C082C085C084C086C0D097 -:1013220075860075D018902060E0540FF5F07011AA -:10133200D0D0D086D084D085D082D083D0F0D0E0F7 -:101342003275860010F00B10F11210F21910F32012 -:1013520080D4E528700375281402137CE5297003F4 -:1013620075291402150DE52A7003752A1402169EBA -:10137200E52B7003752B1402182F902002E0543FC6 -:1013820020E23A20E10B20E40B20E514600902136D -:1013920043021465021343438204E0F53A02134305 -:1013A200438204E0432D010213435382F843820532 -:1013B200E042365382FBE054FBF002134330E10279 -:1013C20080E8F585E53230E00A5382F8438204E092 -:1013D20054FEF0E58520E3569020507400F09020F2 -:1013E200587401F0907FE2E04440F0907FE305867C -:1013F200907E800586E585F0A3E584F00586907FE2 -:10140200E5E53FFD030303FEF0F0F0F0F0F0F0F04D -:10141200DEF6907FE2E054BFF09020587400F09026 -:101422007FB7EDF0902001E054FEF00213437F40BD -:10143200907E800586902000E584FE2405FD8D8443 -:10144200E08E8430E009E00586F0A30586DFEF0533 -:1014520086C374409F907FB7F00586A3E054FEF0E8 -:10146200021343532DFAE5236008752300D2E7FEE9 -:10147200800A907FC7E0FE70030214FF9020507430 -:1014820000F09020587401F0907FE2E04440F09028 -:101492007FE30586907E400586E585F0A3E584F02E -:1014A2000586907FE5EE30E7080586E02438F005F2 -:1014B20086EE547FFE5407FBEE547860300303033C -:1014C20030E30474077B08FDFCE0E0E0E0E0E0E0EC -:1014D200E0DDF6EBFE6019EC640770118B23907F60 -:1014E200E2E054BFF09020587400F0801BE0DEFD73 -:1014F200907FE2E054BFF09020587400F0902001F9 -:10150200E054FDF0907FC7F002134390200AE054AC -:101512003F20E23A20E10B20E40B20E514600902AF -:1015220013430215F6021343438204E0F53B021310 -:1015320043438204E0432E010213435382F8438261 -:1015420005E042375382FBE054FBF002134330E1E3 -:101552000280E8F585E53230E10A5382F8438204DD -:10156200E054FEF0E58520E3569020507401F0909F -:1015720020587401F0907FE2E04440F0907FE30550 -:1015820086907E000586E585F0A3E584F0058690C9 -:101592007FE5E540FD030303FEF0F0F0F0F0F0F02C -:1015A200F0DEF6907FE2E054BFF09020587400F035 -:1015B200907FB9EDF0902009E054FEF00213437FD2 -:1015C20040907E000586902008E584FE2405FD8D6E -:1015D20084E08E8430E009E00586F0A30586DFEF23 -:1015E2000586C374409F907FB9F00586A3E054FE40 -:1015F200F0021343532EFAE5246008752400D2E763 -:10160200FE800A907FC9E0FE70030216909020507F -:101612007401F09020587401F0907FE2E04440F0B1 -:10162200907FE30586907DC00586E585F0A3E5847D -:10163200F00586907FE5EE30E7080586E02438F075 -:101642000586EE547FFE5407FBEE547860300303A8 -:101652000330E30474077B08FDFCE0E0E0E0E0E037 -:10166200E0E0DDF6EBFE6019EC640770118B24906C -:101672007FE2E054BFF09020587400F0801BE0DE5F -:0E168200FD907FE2E054BFF09020587400F01D -:10169000902009E054FDF0907FC9F00213439020A0 -:1016A00012E0543F20E23A20E10B20E40B20E51445 -:1016B0006009021343021787021343438204E0F5D3 -:1016C0003C021343438204E0432F0102134353823D -:1016D000F8438205E042385382FBE054FBF00213EA -:1016E0004330E10280E8F585E53230E20A5382F8C2 -:1016F000438204E054FEF0E58520E35690205074C8 -:1017000002F09020587401F0907FE2E04440F090A5 -:101710007FE30586907D800586E585F0A3E584F06E -:101720000586907FE5E541FD030303FEF0F0F0F050 -:10173000F0F0F0F0DEF6907FE2E054BFF090205839 -:101740007400F0907FBBEDF0902011E054FEF002A9 -:1017500013437F40907D800586902010E584FE2411 -:1017600005FD8D84E08E8430E009E00586F0A30558 -:1017700086DFEF0586C374409F907FBBF00586A38C -:10178000E054FEF0021343532FFAE5256008752557 -:1017900000D2E7FE800A907FCBE0FE7003021821A2 -:1017A0009020507402F09020587401F0907FE2E095 -:1017B0004440F0907FE30586907D400586E585F006 -:1017C000A3E584F00586907FE5EE30E7080586E026 -:1017D0002438F00586EE547FFE5407FBEE54786003 -:1017E0003003030330E30474077B08FDFCE0E0E012 -:1017F000E0E0E0E0E0DDF6EBFE6019EC640770117C -:101800008B25907FE2E054BFF09020587400F08068 -:101810001BE0DEFD907FE2E054BFF09020587400A2 -:10182000F0902011E054FDF0907FCBF00213439034 -:10183000201AE0543F20E23A20E10B20E40B20E59F -:10184000146009021343021918021343438204E08F -:10185000F53D021343438204E04330010213435336 -:1018600082F8438205E042395382FBE054FBF002E8 -:10187000134330E10280E8F585E53230E30A538214 -:10188000F8438204E054FEF0E58520E356902050B2 -:101890007403F09020587401F0907FE2E04440F02F -:1018A000907FE30586907D000586E585F0A3E584BD -:1018B000F00586907FE5E542FD030303FEF0F0F0BE -:1018C000F0F0F0F0F0DEF6907FE2E054BFF0902010 -:1018D000587400F0907FBDEDF0902019E054FEF0B8 -:1018E0000213437F40907D000586902018E584FE1A -:1018F0002405FD8D84E08E8430E009E00586F0A3A8 -:101900000586DFEF0586C374409F907FBDF0058696 -:10191000A3E054FEF00213435330FAE52660087545 -:101920002600D2E7FE800A907FCDE0FE7003021908 -:10193000B29020507403F09020587401F0907FE230 -:10194000E04440F0907FE30586907CC00586E58505 -:10195000F0A3E584F00586907FE5EE30E708058684 -:10196000E02438F00586EE547FFE5407FBEE5478F1 -:10197000603003030330E30474077B08FDFCE0E000 -:10198000E0E0E0E0E0E0DDF6EBFE6019EC6407701B -:10199000118B26907FE2E054BFF09020587400F045 -:1019A000801BE0DEFD907FE2E054BFF09020587491 -:1019B00000F0902019E054FDF0907FCDF002134329 -:0119C00032F4 -:0419C100AD07AC06BC -:1019C5007906ED2404F582E43CF583E0FAA3E0FB17 -:1019D5004A7003021B09E9B407004003021ADB90B1 -:1019E50019EBF8282873021AB9021A71021A5A0259 -:1019F5001A40021A2F021A1A021A00907FA5E04413 -:101A050080F08D828C83A3E0FF25E044A0907FA623 -:101A1500F019021ADB198D828C83E0C39420400AE9 -:101A2500A3A3E0907FA6F0021ADB8D828C83A3A38B -:101A3500E0A3E0907FA6F019021ADB907FA5E044B1 -:101A450080F08D828C83A3E0FF25E044A1907FA6E2 -:101A5500F019021ADBEB64014A7008907FA5E04497 -:101A650020F019907FA6E0F55919806AED2404F558 -:101A750082E43CF583E0FEA3E064024E7008907FAB -:101A8500A5E04420F019907FA6E0FFED2406F5823D -:101A9500E43CF583E475F00112A29785F082F583A5 -:101AA500EFF0ED2404F582E43CF58374FFF5F012C4 -:101AB500A2818022907FA5E04440F0907FA6E0FFC0 -:101AC500ED2406F582E43CF583E0FAA3E0F5828A8D -:101AD50083EFF07F0822907FA5E0F55930E0F730DD -:101AE500E207E04440F07F0622E9D3940250030266 -:101AF50019C7E55930E1030219C7907FA5E04440B5 -:061B0500F07F07227F08BB -:011B0B0022B7 -:101B0C00E533C39401501C7F057E001209AE7F02A1 -:101B1C007DFF1282EA7F057E001209AE7F037DFFF6 -:041B2C001282EA2215 -:108000007BFF7A12791B90000412A254FD8B5075ED -:108010005112755224E4907FE1F0907FE0F0F54E2C -:10802000F54F9002AEF0907FDFF0907FDEF0907F12 -:10803000A974FFF0907FAAF0E4FCEC25E024B4F5ED -:1080400082E4347FF583E4F00CBC10EEE4907FDD35 -:10805000F0AF051DEF70030281C6AB50AA51A952C3 -:1080600090000112A254640560030281B5900003E0 -:1080700012A2546401600302813C90000212A254D7 -:10808000FF547FFCD394075003028116ECC3941075 -:108090004003028116EF30E742E54FAE4E7802CE44 -:1080A000C313CE13D8F9FF74F02CF582E4347FF5B6 -:1080B00083EFF0907FE0E0FFEC24F8FE7401A80667 -:1080C000088002C333D8FC4F907FE0F09002AEE00E -:1080D00004F0907FDDE04480F0803EE54FAE4E78C6 -:1080E00002CEC313CE13D8F9FF74E82CF582E43422 -:1080F0007FF583EFF0907FE1E0FFEC24F8FE740160 -:10810000A806088002C333D8FC4F907FE1F09002AC -:10811000AEE004F080037FFF2290000412A25425F9 -:108120004FF54FE4354EF54E90000512A254FEE493 -:10813000254FF54FEE354EF54E0281B8AB50AA51A2 -:10814000A95290000312A254FF64026005EF640379 -:10815000706090000212A254FF547FFCD394075029 -:108160004EEF30E71E907FDEE0FF7401A804088028 -:1081700002C333D8FCFE4F907FDEF0907FACE04E20 -:10818000F08035907FDFE0FF7401A804088002C30F -:1081900033D8FCFE4F907FDFF0907FADE04EF0ECE7 -:1081A00025E024C5F582E4347FF583ECF080097F77 -:1081B000FF227FFF227FFF2274072552F552E4350C -:1081C00051F55102805120030D9002AEE0600790FE -:0881D0007FAEE04402F07F00E5 -:0181D8002284 -:0481D9008E598F5AD2 -:1081DD00755B03E55A2404F582E43559F583E0FE19 -:1081ED00A3E04E70030282E7E55B604E1460381425 -:1081FD00602014600302828B907FA5E04480F0859F -:10820D005A82855983A3E0FF25E044A0907FA6F014 -:10821D00806C855A82855983E0C394204009A3A3BD -:10822D00E0907FA6F08057155B855A82855983A310 -:10823D00A3E0A3E0907FA6F08044E55A2406F582E2 -:10824D00E43559F583E475F00112A29785F082F5B6 -:10825D0083E0907FA6F0907FA5E04440F0E55A249E -:10826D0004F582E43559F58374FFF5F012A281858A -:10827D005A82855983A3A3E475F00112A281907FE0 -:10828D00A5E0F55C30E0F730E207E04440F07F0612 -:10829D0022E55C20E10A907FA5E04440F07F0722B3 -:1082AD00E55B70317F017E001209AE907FA5E04441 -:1082BD0080F0855A82855983A3E0FF25E044A09084 -:1082CD007FA6F0907FA5E0F55C30E0F730E1D57545 -:0C82DD005B030281E0155B0281E07F087A -:0182E9002272 -:0282EA00AE07DD -:1082EC007C02EC14601514701E907FA5E04480F0A5 -:1082FC00EE25E04440907FA6F0800C907FA6EDF038 -:10830C00907FA5E04440F0907FA5E0FB30E0F8BC06 -:10831C00020A20E107E04440F07F0722EB30E20A3A -:0E832C00907FA5E04440F07F0622DCB67F087B -:01833A002220 -:10833B00C0E0C083C082C2A99003007419F0D2A917 -:0F834B0053917F9001C4E4F0D082D083D0E03210 -:10835A00EF75F008A42400F582E43420AB82FAF524 -:10836A0083A3E4F08B828A83A3A3A3E0F56174BF9D -:10837A00F08B828A83A3A3E04410F08B828A83A3C2 -:10838A00A3A3E4F08B828A83A3F0F9ED601D740144 -:10839A007E00A807088005C333CE33CED8F9FFE4A0 -:1083AA00EF5531600479098002790D8B828A83A3A3 -:1083BA00A3A374BFF08B828A83A3A3E054EFF08B4C -:1083CA00828A83A3A3A3E561F0AE02AF038F828EF4 -:0483DA0083A3E9F0A0 -:0183DE00227C -:0483DF008F618D62BB -:1083E300E4F567743F2FF876087F807E257D007C57 -:1083F30000AB66AA65A964A863D312A3B340267F22 -:10840300007E967D007C00A863D312A3B3500C7545 -:108413006740743F2561F87610800A756780743F62 -:108423002561F87638E56745624401FFE56175F03B -:0D84330008A42402F582E43420F583EFF064 -:018440002219 -:108441008F828E83E014F557C3940440037FFF228B -:10845100E55775F008A42400F582E43420AF82F5D5 -:10846100588F59E55725E024C6F582E4347FF5831A -:10847100E020E10FE55725E024C7F582E4347FF5DC -:1084810083E4F074232557F8E4F6E5592404F582D2 -:10849100E43558F583E04403F0E55775F00DA42465 -:1084A10002F582E43403F583E0FCA3E0FDA3E0FEE2 -:1084B100A3E0F5668E658D648C637D06AF571283EC -:1084C100DFAF577D0112835A855982855883A3A353 -:1084D100E020E043E0FFE5592405F582E43558F555 -:1084E10083E0E5592406F582E43558F583E0FFE59C -:1084F1005775F00DA42402F582E43403F583E0FC02 -:10850100A3E0FDA3E0FEA3E0F5668E658D648C63B8 -:108511007D06AF571283DF74F82557F582E43402E4 -:10852100F583E4F0E55725E0FFC3740C9F75F04037 -:10853100A42440F582E5F0347BAF82FEE55725E0C7 -:1085410024EFF582E43402F583EEF0A3EFF0AF57A8 -:0F8551007401A807088002C333D8FC42347F00AE -:0185600022F8 -:108561008F828E83E014F557C3940440037FFF226A -:10857100AF57E4FD12835A74F82557F582E43402AB -:10858100F583E4F0E55775F008A42400F582E4349E -:1085910020AF82F5598F5AF583E5822404F582E4F0 -:1085A1003583F583E054FCF0E55775F00DA4240CF8 -:1085B100F582E43403F583E4F0E55775F00DA42466 -:1085C10002F582E43403F583E0FCA3E0FDA3E0FEC1 -:1085D100A3E0F5668E658D648C637D06AF571283CB -:1085E100DFE55A2405F582E43559F583E030E009E9 -:1085F100855A82855983E0F558AF577401A8070859 -:108601008002C333D8FCF45234E55725E024C6F583 -:1086110082E4347FF583E020E10FE55725E024C7AC -:0B862100F582E4347FF583E4F07F0075 -:01862C00222B -:04862D008E578F587D -:108631008F828E83E014F559C3940440037FFF2297 -:10864100E55975F008A42401F582E43420F583E0AE -:1086510054037066855882855783A3E030E028E58E -:108661005975F00DA42402F582E43403F583E0FC8E -:10867100A3E0FDA3E0FEA3E0F5668E658D648C6347 -:108681007D02AF591283DF855882855783A3E0307D -:10869100E128E55975F00DA42402F582E43403F5CF -:1086A10083E0FCA3E0FDA3E0FEA3E0F5668E658D0B -:0C86B100648C637D04AF591283DF7F00EE -:0186BD00229A -:1086BE008F828E83C083C082E0FDA3A3A3E0FCED76 -:1086CE006CD082D083F08F828E83A3A3A3C083C08D -:1086DE0082E0FD8F828E83E0FCED6CD082D083F041 -:1086EE008F828E83C083C082A3A3A3E0FDEC6DD0E6 -:1086FE0082D083F08F828E83A3C083C082E0FD8FF1 -:10870E00828E83A3A3E0FCED6CD082D083F08F82A7 -:10871E008E83A3A3C083C082E0FD8F828E83A3E0ED -:10872E00FCED6CD082D083F08F828E83A3C083C089 -:10873E0082E0FD8F828E83A3A3E0FFED6FD082D007 -:03874E0083F02293 -:04875100AD07AC06BE -:10875500790D8D828C83E014FEC3940440037FFF62 -:10876500228C578D58EE75F00DA42401F582E43462 -:1087750003AF82FEAD0119ED60240FEFAC06700169 -:108785000E14F5828C83E0FD0558E558AA57700252 -:10879500055714F5828A83E06D60D97F01227F0039 -:0187A50022B1 -:0487A6008E578F5803 -:1087AA008F828E83E014F55EC3940440037FFF2218 -:1087BA00E55E75F008A42400F582E43420AF82F562 -:1087CA005F8F60855882855783A3E0FCA3E0FDA3F1 -:1087DA00E0FEA3E0FF7B087A0079007800D312A3B9 -:1087EA00B34010855882855783A312A3FA0000006C -:1087FA0008802E855882855783A3E0FCA3E0FDA359 -:10880A00E0FEA3E0FF7B007A0879077800C312A391 -:10881A00B3500E855882855783A312A3FA0007081E -:10882A0000855882855783A3E0F8A3E0F9A3E0FA0C -:10883A00A3E0FB7F007E507D467C0012A3218F5C63 -:10884A008E5B8D5A8C597B0A7A007900780012A3C4 -:10885A0021AF038F5DAF5CAE5BAD5AAC597B0A7A30 -:10886A00007900780012A3218F5C8E5B8D5A8C5997 -:10887A00E55DC394054015E55C2401F55CE4355BD0 -:10888A00F55BE4355AF55AE43559F5598560828520 -:10889A005F83A3E4F0856082855F83A3A3A3E0449A -:1088AA0080F0856082855F83E55CF0AF5CAE5BAD8E -:1088BA005AAC59780812A3C4856082855F83A3EFF6 -:1088CA00F0856082855F83A3A3A3E0547FF0E4F57B -:1088DA005DE558240BF582E43557F583E0FF30E077 -:1088EA00235401F0E5602404F582E4355FF583E062 -:1088FA0054FDF0AF5E7401A807088002C333D8FCA8 -:10890A004222803674017E00A85E088005C333CEF9 -:10891A0033CED8F9FFE4EF5522601FE5602404F551 -:10892A0082E4355FF583E04402F0AF5E7401A80784 -:10893A00088002C333D8FCF45222E5582408F58291 -:10894A00E43557F583E0FFB46205435D0A801AEF08 -:10895A00B47205435D088011EFB47405435D02806B -:10896A0008EF646E60037FFF22E558240BF582E46A -:10897A003557F583E0FF30E303435D80EF30E712BC -:10898A00435D40E5602404F582E4355FF583E04405 -:10899A0002F0E558240BF582E43557F583E030E11F -:1089AA0020AF5E7401A807088002C333D8FC4232A4 -:1089BA00E5602404F582E4355FF583E04401F08044 -:1089CA0010AF5E7401A807088002C333D8FCF452C2 -:1089DA0032E558240BF582E43557F583E0FF30E49D -:1089EA0011AE5E7401A806088002C333D8FC423176 -:1089FA008010AE5E7401A806088002C333D8FCF466 -:108A0A005231EF20E10330E403E4F55D85608285AD -:108A1A005F83A3A3A374BFF0856082855F83A3A34A -:108A2A00E4F0E55DF0E558240AF582E43557F5836C -:108A3A00E0FFE5602404F582E4355FF583EFF0E5B5 -:108A4A0058240AF582E43557F583E0FFE5602405EA -:108A5A00F582E4355FF583EFF0E5582409F582E401 -:108A6A003557F583E0FFE5602406F582E4355FF5C6 -:108A7A0083EFF0E5582409F582E43557F583E0FFE2 -:108A8A00E5602407F582E4355FF583EFF0856082BF -:108A9A00855F83A3A3A3E4F0856082855F83A3A394 -:108AAA00F0855882855783A3E0FCA3E0FDA3E0FE8E -:108ABA00A3E0F5668E658D648C637D06AF5E1283D6 -:108ACA00DF755D08E558240CF582E43557F583E037 -:108ADA006003435D10E5602404F582E4355FF583A5 -:108AEA00E05403455DF0E5582405F582E43557F571 -:108AFA0083E0FEC394054006EED3940840037FFF4B -:108B0A0022E5582406F582E43557F583E0FDC3943F -:108B1A00014006EDD3940240037FFF22ED14FF25A6 -:108B2A00E025E0FFEE24FB4FF55DE5582407F582CA -:108B3A00E43557F583E024D0601814601A24C36022 -:108B4A001E146009240A7014435D188012435D08DC -:108B5A00800D435D388008435D2880037FFF2285AE -:108B6A006082855F83A3A3A3E55DF074017E00A8FC -:108B7A005E088005C333CE33CED8F9FFE4EF55340F -:108B8A006007AF5E7D0112835AAA57A9587B01C0BC -:108B9A0003C001E55E75F00DA42401F9740335F0F4 -:108BAA00A801FCAD03D001D0037E007F0D12A212F2 -:028BBA007F003A -:018BBC002296 -:108BBD008F828E83E014FEC3940440037FFF22EE68 -:108BCD0075F008A42400F582E43420AD82FC9001F8 -:108BDD002C7408F0EE04A3F0E4A3F08D828C83E5F1 -:108BED00822406F582E43583F583E090012FF08D24 -:108BFD00828C83E5822405F582E43583F583E05488 -:108C0D001E900130F0742D2EF8E6A3F0AF0674011E -:108C1D00A807088002C333D8FCF557E533C3940188 -:108C2D00400D902078E0540F755800F55980097F5C -:108C3D00021211278E588F59C3E5586480948040D5 -:108C4D00DAE5575559900132F07E017F2C7D0712E0 -:048C5D00916A7F0099 -:018C610022F0 -:108C62008F828E83E014FEC3940440037FFF22EEC2 -:108C720075F008A42400F582E43420AF82FE90014E -:108C820033740AF08F828E83E5822404F582E43500 -:108C920083F583E0900134F07E017F337D021291EF -:038CA2006A7F00E6 -:018CA50022AC -:048CA6008E578F58FE -:108CAA008F828E83E014FEC3940440037FFF22EE7A -:108CBA0075F008A42400F582E43420AD82FC8558BE -:108CCA0082855783A3E0600FED2404F582E43CF526 -:108CDA0083E04402F08043EE75F00DA4240CF58283 -:108CEA00E43403F583E030E020EE25E024C6F58283 -:108CFA00E4347FF583E030E1F07F60ED2405F5820E -:108D0A00E43CF583E05FB507F2AE04AF05EF240457 -:0C8D1A00F582E43EF583E054FDF07F009C -:018D2600222A -:048D2700AD07AC06E2 -:108D2B008D828C83E014FEC3940440037FFF22EEFC -:108D3B0075F008A42400F582E43420AF82FE8D8206 -:108D4B008C83A3E0600FEF2404F582E43EF583E00F -:108D5B004401F0800DEF2404F582E43EF583E054EA -:048D6B00FEF07F0097 -:018D6F0022E1 -:048D7000AD07AC0699 -:108D74008D828C83E014FEC3940440037FFF22EEB3 -:108D840075F008A42400F582E43420AF82FE8D82BD -:108D94008C83A3E0600D8F828E83A3A3A3E0444061 -:108DA400F0800B8F828E83A3A3A3E054BFF07F00D7 -:018DB400229C -:108DB5008F828E83E014FEC3940440037FFF22AFAD -:108DC500067401A807088002C333D8FC423E7F0021 -:018DD500227B -:048DD6008E578F58CD -:108DDA008F828E83A3E0F55C8F828E83E0F559D370 -:108DEA00940440037FFF22E55924FE601614601F95 -:108DFA001460282403702E7E7E7F80755A7E755BF0 -:108E0A008080227E7E7F00755A7E755B0080167E8A -:108E1A007D7F80755A7D755B80800A7E7D7F0075B7 -:108E2A005A7D755B00E55C701B855B82855A83748D -:108E3A00FFF0E55925E024B5F582E4347FF5837423 -:108E4A0001F08048E5582402FFE43557FEE55C60EE -:108E5A00230FEFAC0670010E14F5828C83E0FD053A -:108E6A005BE55BAA5A7002055A14F5828A83EDF013 -:108E7A00155C80D9855882855783A3E0FFE559257B -:0E8E8A00E024B5F582E4347FF583EFF07F003D -:018E980022B7 -:108E9900EF2405F558E43EF5579001357407F09035 -:108EA900017A7401F0A37436F0855882855783A33B -:108EB900A3A3E0FEA3E08E59F55A8558828557830E -:108EC900E0249E606124F9600E24F17003028F7A18 -:108ED90024146003028FC8855882855783A3E0FE56 -:108EE900A3E0FFC3E49FF55C74019EF55BD3E55CE9 -:108EF900943FE55B94004006755B00755C3FD3E5E4 -:108F09005A955CE559955B5003028FCBAE5BAF5C1C -:108F1900855882855783A3A3A3EEF0FEA3EFF08EB5 -:108F290059F55A028FCB855882855783A3E0FEA352 -:108F3900E0FFC374309FF55CE49EF55BD3E55C9478 -:108F490010E55B94004006755B00755C10D3E55A2B -:108F5900955CE559955B406AAE5BAF5C8558828547 -:108F69005783A3A3A3EEF0FEA3EFF08E59F55A8021 -:108F790051855882855783A3E0FEA3E0FFC3E49F90 -:108F8900F55CE49EF55B455C600BD3E55C943FE5DD -:108F99005B94004006755B00755C3FD3E55A955CB0 -:108FA900E559955B401CAE5BAF5C8558828557835C -:108FB900A3A3A3EEF0FEA3EFF08E59F55A80037F29 -:108FC9000122855882855783E0249E700302908B85 -:108FD90024F9605824F170030290DB241460030221 -:108FE900911F855882855783A3E0FEA3E0FFD394A0 -:108FF900FFEE9400400302911F900175EFF0E55ACE -:10900900155AAE59700215594E700302911F9001FD -:1090190075E0FF04F0A807E6FF90017AE475F00116 -:1090290012A29785F082F583EFF080D28558828568 -:109039005783A3E0FEA3E0FFC39480EE940050039E -:1090490002911FD3EF94FFEE9400400302911F9009 -:109059000176EFF0E55A155AAE59700215594E705E -:109069000302911F900176E0FF04F0A807E6FF9044 -:10907900017AE475F00112A29785F082F583EFF089 -:1090890080D2855882855783A3E0FEA3E0FFC3946D -:1090990020EE9400500302911FD3EF942FEE940019 -:1090A9005074900177EFF0E55A155AAE59700215D0 -:1090B900594E6062900177E0FF04F0A807E6FF903F -:1090C900017AE475F00112A29785F082F583EFF039 -:1090D90080D5855882855783A3E0FFA3E090017866 -:1090E900CFF0A3EFF0E55A155AAE59700215594E53 -:1090F9006024900178E475F00112A29785F082F559 -:1091090083E0FF90017AE475F00112A29785F0825D -:10911900F583EFF080CF7E017F35855882855783AF -:0D912900A3A3A3E0A3E004FD12916A7F0060 -:019136002216 -:109137008E628F638C648D65AF031BEF60240563BC -:10914700E563AE627002056214F5828E83E0FF0567 -:1091570065E565AC647002056414F5828C83EFF0F5 -:0391670080D6228D -:06916A008D5DAB07AA06B3 -:1091700075614075600D755F03755E00907FC2E09C -:1091800020E1F9AF61AE60AD5FAC5EEC4D4E4F706B -:1091900008907FC27402F080D7907FC2E020E11671 -:1091A000AF03AE027C7B7D80AB5D129137907FC3B5 -:0891B000E55DF07F01227F0064 -:0191B8002294 -:1091B900900184740BF0A3E533F0900AF5E49390E1 -:1091C9000186F0900AF6E493900187F0E490017C1F -:1091D900F0A3F0A3F0A3F0A3F0A37410F0A374011B -:1091E900F0A37488F07E017F7C1219C17E017F840F -:0791F9007D1412916A7F0052 -:01920000224B -:109201007E7B7F40754E7B754F40907FD3E0FF851D -:109211004E51854F52E5522401F556E43551F5552D -:10922100E4F550855282855183E0FE14B40C005060 -:109231005B909239F828287302925D02925D029246 -:109241006702927102927102927102928502925D9D -:1092510002927B02925D02928D02925DEF64026046 -:109261002B7550FF8026EF640E60217550FF801C26 -:10927100EF640360177550FF8012EF6403600D7592 -:1092810050FF8008EF640660037550FFE5506015DC -:109291009001987411F0A3EEF07E017F987D021287 -:1092A100916AAF5022E4F550855282855183E014D2 -:1092B100B40F0040030293CF9092C0F828287302A4 -:1092C10092ED0292F902930502935302935E029387 -:1092D1006902937402937F02938A0293950293A089 -:1092E1000293A70293CF0293B20293BDAF56AE553C -:1092F1001284418F500293D2AF56AE551285618FC1 -:10930100500293D2855553855654E5542401FFE408 -:109311003553FE1286BEAF54AE531287518F50EFB4 -:10932100640160030293D2AF54AE531287A68F50EB -:10933100E55070030293D2855482855383E075F022 -:109341000DA424F4F582E43402AF82FE1287A60252 -:1093510093D2AF56AE55128CA68F508074AF56AED5 -:1093610055128D278F508069AF56AE55128D708F73 -:1093710050805EAF4FAE4E128E998F508053AF56D4 -:10938100AE55128BBD8F508048AF56AE5512862D0B -:109391008F50803DAF56AE55128C628F5080321285 -:1093A10091B98F50802BAF56AE55128DB58F50802D -:1093B10020AF56AE55128DD68F508015AF4FAE4EA1 -:1093C1007C027DAF7B40129137E4F55080037550EC -:1093D100FFE550601D9001987411F085528285510E -:1093E10083E0900199F07E017F987D0212916AAF2E -:1093F1005022855282855183E0FF1424FA500424BF -:10940100FE701F9001987410F0A3EFF085568285CD -:109411005583E090019AF07E017F987D0312916A55 -:049421008F50AF5069 -:019425002224 -:089426008F518E508D4F8C4ECA -:10942E0075580175599CE4F557AF531553EF7003FA -:10943E000294C4AF52E4FCFDFEF8F9FAAB07AF514B -:10944E00AE50AD4FAC4E12A321AF038F56AF51AEFF -:10945E0050AD4FAC4EC004C005C006C007AF52E4BD -:10946E00FCFDFEF8F9FAAB07D007D006D005D00404 -:10947E0012A3218F518E508D4F8C4EE5562430F510 -:10948E0056D39439400674072556F5560559E559B5 -:10949E00AE587002055814F5828E83E4F00559E536 -:1094AE0059AE587002055814F5828E83E556F005B4 -:1094BE00570557029437E559155970021558AF578D -:1094CE001557EF6023E5591559AE5870021558F52A -:1094DE00828E83E0FF0555E555AC54700205541499 -:0894EE00F5828C83EFF080D6BB -:0194F6002253 -:1094F700E49001C9F07E017FCA9001BEEEF0A3EFB0 -:0A950700F09001C2EEF0A3EFF02295 -:10951100AA07A9059001C9E0C394405061AC027447 -:10952100017E00A804088005C333CE33CED8F9FFED -:10953100E4EF55346045EA04FF9001C2E0FCA3E08A -:10954100FDF5828C83EFF0A3E9F08D828C83A3A3D8 -:10955100EBF09001C2E475F00312A281FCD3E5F0B7 -:109561009487EC9402400A9001C27401F0A374CA7A -:10957100F0C2AF9001C9E004F0D2AF7F01227F00B9 -:0195810022C7 -:109582009001C9E0D3940040559001BEE0FCA3E0F5 -:10959200AA04F97B01C003C002C001AA06A907A858 -:1095A20001AC02AD03D001D002D0037E007F0312D2 -:1095B200A2129001BEE475F00312A281FCD3E5F081 -:1095C2009487EC9402400A9001BE7401F0A374CA1D -:1095D200F0C2AF9001C9E014F0D2AF7F01227F0048 -:0195E2002266 -:1095E300907FC2E020E1737E7B7F8075537B75544F -:1095F30080E5542401FFE43553A9077B018B55F51E -:10960300568957FE129582EF6050AB55AA56A9575B -:1096130012A23B14FF90000112A254B40216C2AF6F -:10962300EF75F008A42401F582E43420F583E044C7 -:1096330004F0D2AF74017E00A807088005C333CEBF -:1096430033CED8F9FFE4EF5534600F855482855348 -:0A96530083740DF0907FC37404F0DF -:01965D0022EA -:10965E001295E3E4F54E743A254EF8E654F0F54FC4 -:10966E0074C5254EF582E43401F583E0654FFFC4E1 -:10967E00540FF550602274C5254EF582E43401F581 -:10968E0083E54FF0AF4E7D01E54F4550FB1295112E -:10969E00EF70051295E380EC054EE54EC394044041 -:1096AE00B51295E3E53E6048E4F54EAF4E7401A861 -:1096BE0007088002C333D8FCF54F553E6029E54EAE -:1096CE0075F008A42405F582E43420F583E030E635 -:1096DE0016AF4E7D047B80129511EF70051295E347 -:1096EE0080EFE54FF4523E054EE54EC3940440BB69 -:1096FE00900300E060030297DF7419F0E533C39422 -:10970E0001400D902078E0540F755100F5528009FC -:10971E007F021211278E518F52C3E55164809480BF -:10972E0040DA9001BCE06552F06037E4F54EAF4E82 -:10973E007401A807088002C333D8FCF54F9001BC12 -:10974E00E0554F6014AF4E7D08E54F5552FB129514 -:10975E0011EF70051295E380EC054EE54EC39404AF -:10976E0040CC9001BCE552F0E4F54EC2AF74362504 -:10977E004EF8E6F54FE4F6D2AF534F1EE54F6011AB -:10978E00AF4E7D02AB4F129511EF70051295E3802F -:10979E00EF742D254EF8E6F54F74FC254EF582E458 -:1097AE003402F583E0654F6011AF4E7D04AB4F126E -:1097BE009511EF70051295E380EF74FC254EF5823E -:1097CE00E43402F583E54FF0054EE54EC3940440B4 -:0497DE009A1295E363 -:0197E2002264 -:0C97E300787FE4F6D8FD75816702982AB3 -:1097EF000205ADE493A3F8E493A34003F68001F2DE -:1097FF0008DFF48029E493A3F85407240CC8C3337B -:10980F00C4540F4420C8834004F456800146F6DF49 -:10981F00E4800B010204081020408090986FE47ED2 -:10982F00019360BCA3FF543F30E509541FFEE4933E -:10983F00A360010ECF54C025E060A840B8E493A305 -:10984F00FAE493A3F8E493A3C8C582C8CAC583CA30 -:10985F00F0A3C8C582C8CAC583CADFE9DEE780BEE8 -:10986F006024028A010204081020408081828488CB -:10987F0090A0C0C1C2C4C8D0E0E1E2E4E8F0F1F2C8 -:08988F00F4F8F9FAFCFDFEFFFC -:0198970000D0 -:089898008B598A5A895B8D5C33 -:1098A000E4F55DF55EAF5C155CEF6036AB59055BCA -:1098B000E55BAA5A7002055A14F912A23BFFE55D56 -:1098C000E55E6F25E0FFE433FE74952FF582EE34FC -:1098D0009EF583E55DFFE493F55D7401936FF55E9E -:0698E00080C3AE5DAF5E27 -:0198E600225F -:0B98E700C0E0C083C082C0D075D01864 -:1098F200902060E0540FFE30E005902002E0FFEE81 -:1099020030E10590200AE0FFEE30E205902012E0FF -:10991200FFEE30E30590201AE0FF9001C4E0B51E8F -:0A99220004E4F080059001C4EEF0AB -:09992C00D0D0D082D083D0E0320B -:02993500A90384 -:10993700EF75F008A42400F582E43420AB82FAE541 -:109947005C455DF55EE960148A83E5822404F5824F -:10995700E43583F583E04DF0E4FE8013EB2404F552 -:1099670082E43AF583E0FFEDF4FCEF5CF0AE5EEBEA -:109977002406F582E43AF583E0555EFCB50603AFAD -:109987000522E55C5CFEE55D5CFDE96016EE7004B2 -:109997007F0180027F00AE07ED70047F0180027FA8 -:1099A70000AD07EE6003AF5C22ED6003AF5D227F81 -:0199B70000AF -:0199B800228C -:1099B9007555027556B0900335740FF0855682853A -:1099C9005583A3E0FF900337F0855682855583E0E0 -:1099D900900336F090033874FFF0755703755839C2 -:1099E900EF14B40B004003029E5D9099FAF8282801 -:1099F90073029A1B029ABA029BBF029BDE029BDE8C -:109A0900029C94029CCF029CF4029DB2029DE20248 -:109A19009E0EE4F54EE54E75F008A42400F582E4A7 -:109A29003420AF82F5538F54E4FFE4FEEF601074E5 -:109A39008A2EF582E43402F583E0F4F54F800D7443 -:109A49008A2EF582E43402F583E0F54FE5542407C4 -:109A5900F582E43553F583E54FF0E0F550654F6045 -:109A690038E4900338F0E54E04FD0558E558AA5747 -:109A79007002055714F5828A83EDF00558E558AC54 -:109A8900577002055714F5828C83E54FF08558828B -:109A9900855783E550F0029E630EBE248F0FEF6455 -:109AA900027087054EE54E64046003029A1E029E09 -:109AB90063E4F54EAF4EE4FD12835A054EE54ED3ED -:109AC900940340F09000047498F0A374E7F0E4F56F -:109AD900507E207F00755320755400F54EAF4E74AB -:109AE90001A807088002C333D8FCF54F9001C4F0E0 -:109AF9009001C0E4F0A3740AF0855482855383A3CE -:109B09007402F09001C4E0B54F349001C0E07002D6 -:109B1900A3E070EF900338F0E54E04FF0558E558CF -:109B2900AC577002055714F5828C83EFF085588283 -:109B390085578374FFF0E49001C4F07550FF9001DC -:109B4900C4E0FF6037E4900338F0E54E04FE0558A1 -:109B5900E558AC577002055714F5828C83EEF00571 -:109B690058E558AC577002055714F5828C83EFF00D -:109B7900855882855783E54FF07550FFE55070167B -:109B890074082554F554E43553F553054EE54E64F0 -:109B9900046003029AE6E4F54EAF4E7D0112835A42 -:109BA900054EE54ED3940340F09000047413F0A3DE -:109BB9007412F0029E63855682855583E014FF7402 -:109BC90001A807088002C333D8FC9002F7F090017E -:109BD900C4F0029E639001C07403F0A374E8F0E43A -:109BE900F5509002F7E0FF9001C4E0B50719900124 -:109BF900C0E07002A3E070EA900338F085588285CE -:109C0900578374FFF0F550E5506003029E6390019D -:109C1900C0F0A37496F09001C0E07002A3E070F662 -:109C2900E533C39401400D902078E0540F7551003D -:109C3900F55280097F021211278E518F52C3E551C7 -:109C49006480948040DAE552540FF5509002F7E0B1 -:109C5900555070047F0180027F008F4F85568285A1 -:109C69005583A3E0B4050CE54F70047F0180027FA2 -:109C7900008F4FE54F7003029E63E4900338F0852F -:109C89005882855783E550F0029E63E4FFFD1283F5 -:109C99005A7E207F00755320755400855482855360 -:109CA90083A3A3A3E04480F0855482855383740180 -:109CB900F0A3E4F0855482855383A3A3A3E0547FE2 -:109CC900F0D204029E63C2047E207F007553207582 -:109CD9005400E5542405F582E43553F583E030E674 -:109CE900F1E4FF7D0112835A029E63E4F550F54EBB -:109CF900AF4EE4FD12835AE54E75F008A42400F531 -:109D090082E43420AF82F5538F54F583E58224042D -:109D1900F582E43583F583E054FCF0AF4E7D017B99 -:109D290001755C80755D401299358F50E550701151 -:109D3900AF4E7D027B01755C10755D201299358FE0 -:109D490050E5507010AF4E7D01FB755C80755D402C -:109D59001299358F50E5507010AF4E7D02FB755C3E -:109D690010755D201299358F50AF4E7D0112835ABF -:109D7900E5506026E4900338F0E54E04FF0558E508 -:109D890058AC577002055714F5828C83EFF085584B -:109D990082855783E550F0029E63054EE54ED394C4 -:109DA900035003029CF9029E63E4900359F0A3F067 -:109DB900A3F0A3F0A3F0A37410F0A3749EF0A3740E -:109DC90085F07E037F591281D9EF64087003029EE2 -:109DD90063E4900338F0029E63E4900359F0A3F022 -:109DE900A3F0A3F0A3F0A37410F0A3E557F0A3E543 -:109DF90058F07E037F591219C1EF6408605CE49042 -:109E09000338F08055E5562402FFE43555FAA907D1 -:109E19007B017D10129898EF4E7032900359F0A390 -:109E2900F0A3F0A3F0A3F0A37410F0E55624029078 -:109E39000360F0E4355590035FF07E037F5912818A -:109E4900D9EF64086014E4900338F0800DE49003BE -:109E590038F080069003387401F09001C0E4F0A353 -:109E6900740AF09001C0E07002A3E070F67E037FEF -:0B9E7900357D2412916AE49002AFF0E6 -:019E840022BB -:109E8500FFFEFCF8F0E0C080000103070F1F3F7FD5 -:109E95000000C0C1C1810140C30103C00280C241AD -:109EA500C60106C00780C7410500C5C1C48104407D -:109EB500CC010CC00D80CD410F00CFC1CE810E402D -:109EC5000A00CAC1CB810B40C90109C00880C8413D -:109ED500D80118C01980D9411B00DBC1DA811A40AD -:109EE5001E00DEC1DF811F40DD011DC01C80DC417D -:109EF5001400D4C1D5811540D70117C01680D641AD -:109F0500D20112C01380D3411100D1C1D0811040BC -:109F1500F00130C03180F1413300F3C1F2813240AC -:109F25003600F6C1F7813740F50135C03480F4417C -:109F35003C00FCC1FD813D40FF013FC03E80FE412C -:109F4500FA013AC03B80FB413900F9C1F88138403C -:109F55002800E8C1E9812940EB012BC02A80EA41AC -:109F6500EE012EC02F80EF412D00EDC1EC812C407C -:109F7500E40124C02580E5412700E7C1E6812640AC -:109F85002200E2C1E3812340E10121C02080E041BC -:109F9500A00160C06180A1416300A3C1A2816240AC -:109FA5006600A6C1A7816740A50165C06480A4417C -:109FB5006C00ACC1AD816D40AF016FC06E80AE412C -:109FC500AA016AC06B80AB416900A9C1A88168403C -:109FD5007800B8C1B9817940BB017BC07A80BA41AC -:109FE500BE017EC07F80BF417D00BDC1BC817C407C -:109FF500B40174C07580B5417700B7C1B6817640AC -:10A005007200B2C1B3817340B10171C07080B041BB -:10A01500500090C191815140930153C052809241AB -:10A02500960156C057809741550095C1948154407B -:10A035009C015CC05D809D415F009FC19E815E402B -:10A045005A009AC19B815B40990159C0588098413B -:10A05500880148C0498089414B008BC18A814A40AB -:10A065004E008EC18F814F408D014DC04C808C417B -:10A07500440084C185814540870147C046808641AB -:10A08500820142C043808341410081C180814040BB -:10A09500E4FF74F82FF582E43402F583E0700302DF -:10A0A500A138743A2FF8E620E50302A138EF75F0E0 -:10A0B50008A42400F582E43420AD82FCF583E58212 -:10A0C5002405F582E43583F583E0546064607063AC -:10A0D500EF25E024EFF582E43402F583E475F00121 -:10A0E50012A29785F082F583E08D828C83F074F857 -:10A0F5002FF582E43402F583E014F07036EF25E0A5 -:10A1050024C7F582E4347FF583E4F0EF25E0FEC350 -:10A11500740C9E75F040A42440F582E5F0347BADC7 -:10A1250082FCEF25E024EFF582E43402F583ECF0C0 -:0CA13500A3EDF00FEF6404600302A0979C -:01A1410022FB -:10A14200E709F608DFFA8046E709F208DFFA803EFF -:10A1520088828C83E709F0A3DFFA8032E309F608EC -:10A16200DFFA8078E309F208DFFA807088828C8354 -:10A17200E309F0A3DFFA806489828A83E0A3F60808 -:10A18200DFFA805889828A83E0A3F208DFFA804CE2 -:10A1920080D280FA80C680D4806980F280338010B9 -:10A1A20080A680EA809A80A880DA80E280CA803322 -:10A1B20089828A83ECFAE493A3C8C582C8CCC5839A -:10A1C200CCF0A3C8C582C8CCC583CCDFE9DEE7806A -:10A1D2000D89828A83E493A3F608DFF9ECFAA9F0E9 -:10A1E200EDFB2289828A83ECFAE0A3C8C582C8CC3F -:10A1F200C583CCF0A3C8C582C8CCC583CCDFEADE58 -:10A20200E880DB89828A83E493A3F208DFF980CCB9 -:10A2120088F0ED2402B4040050C2F582EB2402B4AB -:10A22200040050B823234582F582EF4E60AEEF6002 -:09A23200010EE5822390A1927354 -:10A23B00BB010689828A83E0225002E722BBFE0221 -:09A24B00E32289828A83E4932254 -:10A25400BB010CE58229F582E5833AF583E02250BF -:10A2640006E92582F8E622BBFE06E92582F8E22209 -:0DA27400E58229F582E5833AF583E4932223 -:10A28100C5F0F8A3E028F0C5F0F8E5821582700268 -:06A291001583E038F02205 -:10A29700A3F8E0C5F025F0F0E5821582700215837A -:06A2A700E0C838F0E822D7 -:10A2AD00BB0110E58229F582E5833AF583E0F5F0EF -:10A2BD00A3E0225009E92582F886F008E622BBFECC -:10A2CD000AE92582F8E2F5F008E222E5832AF58312 -:08A2DD00E993F5F0A3E99322D7 -:10A2E50075F008758200EF2FFFEE33FECD33CDCC30 -:10A2F50033CCC58233C5829BED9AEC99E5829840B3 -:10A305000CF582EE9BFEED9AFDEC99FC0FD5F0D68F -:10A31500E4CEFBE4CDFAE4CCF9A88222B800C1B9B9 -:10A325000059BA002DEC8BF084CFCECDFCE5F0CBF7 -:10A33500F97818EF2FFFEE33FEED33FDEC33FCEB30 -:10A3450033FB10D703994004EB99FB0FD8E5E4F9EB -:10A35500FA227818EF2FFFEE33FEED33FDEC33FCD8 -:10A36500C933C910D7059BE99A4007EC9BFCE99ACC -:10A37500F90FD8E0E4C9FAE4CCFB2275F010EF2F11 -:10A38500FFEE33FEED33FDCC33CCC833C810D70711 -:10A395009BEC9AE899400AED9BFDEC9AFCE899F84C -:0EA3A5000FD5F0DAE4CDFBE4CCFAE4C8F922DF -:10A3B300EB9FF5F0EA9E42F0E99D42F0E89C45F000 -:01A3C3002277 -:10A3C400E8600FECC313FCED13FDEE13FEEF13FF77 -:03A3D400D8F1229B -:10A3D700080808E6CF2FF618E6CE3EF618E6CD3D7C -:07A3E700F618E6CC3CF6225B -:0CA3EE00ECF0A3EDF0A3EEF0A3EFF022E2 -:10A3FA00A8828583F0D083D08212A41112A41112EC -:10A40A00A41112A411E473E493A3C583C5F0C58310 -:10A41A00C8C582C8F0A3C583C5F0C583C8C582C8AC -:01A42A00220F -:00000001FF -/***************************************************************************** - * - * whiteheat.h -- ConnectTech WhiteHEAT Firmware. - * - * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.com/) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (10/09/2002) Stuart MacDonald - * Firmware 4.06 - * - * (04/09/2000) gkh - * Updated the firmware with the latest provided by ConnectTech. - * - * (01/16/2000) gkh - * Fixed my intel hex processing tool, so now the firmware actually - * matches the original file (this was causing a few problems...) - * - * (01/15/2000) gkh - * Added debug loader firmware if DEBUG is #defined: - * Port 1 LED flashes when the vend_ax program is running - * Port 2 LED flashes when any SETUP command arrives - * Port 3 LED flashes when any valid VENDOR request occurs - * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs - * - * version 1.0 (01/09/2000) gkh - * Original firmware from ConnectTech massaged a little to be program - * readable. - * - *****************************************************************************/ - -#define whiteheat_DATE "20000106" diff --git a/firmware/whiteheat_loader.HEX b/firmware/whiteheat_loader.HEX deleted file mode 100644 index 5f663f6a28494eb3096e2433402308b9669346ab..0000000000000000000000000000000000000000 --- a/firmware/whiteheat_loader.HEX +++ /dev/null @@ -1,314 +0,0 @@ -:0300000002098D65 -:030033000208FBC5 -:03004300020B00AD -:03004B000205AA01 -:10010000907FA5E05410FFC4540F4450F50F13E442 -:1001100033F511907FE9E0245EB407004003020349 -:1001200078900128F82828730201BC0201BC020162 -:100130009102013D02015302016F02019A907F007A -:10014000E511F0907FB57401F0907FB4E04402F0C7 -:10015000020378907F92E0FFC4540F907F00F090EC -:100160007FB57401F0907FB4E04402F0020378128E -:100170000A895007E4907F00F08006907F00740F9A -:10018000F0907FB57401F0907FB4E04402F0020378 -:1001900078907FEAE0F50F020378907F007407F013 -:1001A000907FB57401F0907FB4E04402F07FE87E68 -:1001B00003120D94D206120CCC020378907FEAE071 -:1001C000752800F529A3E0FEE4EE4228907FEEE0DA -:1001D000752A00F52BA3E0FEE4EE422A907FE8E0CA -:1001E00064C060030202C9E52B452A70030203784C -:1001F000C3E52B9440E52A94005008852A2C852BD2 -:100200002D8006752C00752D40907FE9E064A37069 -:1002100034F530F531C3E531952DE530952C505C42 -:10022000E5292531F582E5303528F583E0FF7400B6 -:100230002531F582E4347FF583EFF00531E5317047 -:1002400002053080D0E4F530F531C3E531952DE578 -:1002500030952C501874002531F582E4347FF583F5 -:1002600074CDF00531E5317002053080DDAF29AE87 -:1002700028AD2D7A7F79007B00120BF4907FB5E5D5 -:100280002DF0E52D2529F529E52C3528F528C3E5A0 -:100290002B952DF52BE52A952CF52A907F92E0FFE2 -:1002A000C4540F752E00F52FD39400E52E94005002 -:1002B0000C907FB4E020E1030201E780F4907FB46A -:1002C000E020E2030201E780F4907FE8E064406010 -:1002D00003020378E52B452A7003020378E4907F3C -:1002E000C5F0907F92E0FFC4540F752E00F52FD318 -:1002F0009400E52E94005009907FC4E030E109801D -:10030000F7907FB4E020E3F9907FC5E0752C00F50D -:100310002D907FE9E064A37034F530F531C3E53109 -:10032000952DE530952C503474C02531F582E43498 -:010330007E4E -:10033100F583E0FFE5292531F582E5303528F583A0 -:10034100EFF00531E5317002053080D0AF29AE28DC -:10035100AD2D7A7E79C07BC0120C3FE52D2529F5A4 -:1003610029E52C3528F528C3E52B952DF52BE52A14 -:09037100952CF52A0202D4C322E6 -:10037A00907FE9E070030204521470030204CE2451 -:10038A00FE700302054224FB700302044C1470033E -:10039A0002044614700302043A147003020440244F -:1003AA00056003020596120E4440030205A2907FDF -:1003BA00EBE024FE60161460402402706974119008 -:1003CA007FD4F07400907FD5F00205A2907FEAE016 -:1003DA00FF120B588B258A268927EA496011AE023B -:1003EA00EE907FD4F0AF01EF907FD5F00205A29096 -:1003FA007FB4E04401F00205A2907FEAE0FF120810 -:10040A00BA8B258A268927EA496011AE02EE907FC7 -:10041A00D4F0AF01EF907FD5F00205A2907FB4E04F -:10042A004401F00205A2907FB4E04401F00205A263 -:10043A00120E1F0205A2120E2D0205A2120AF702BF -:10044A0005A2120E110205A2120E4640030205A2CF -:10045A00907FE8E0247F60241460312402705BA25C -:10046A0000E433FF25E0FFA202E4334F907F00F05F -:10047A00E4A3F0907FB57402F00205A2E4907F0035 -:10048A00F0A3F0907FB57402F00205A2907FECE031 -:10049A00F45480FFC4540FFFE054072F25E024B41E -:1004AA00F582E4347FF583E054FD907F00F0E4A305 -:1004BA00F0907FB57402F00205A2907FB4E0440187 -:1004CA00F00205A2120E4840030205A2907FE8E05E -:1004DA0024FE601D240260030205A2907FEAE0B4B4 -:1004EA000105C2000205A2907FB4E04401F00205B2 -:1004FA00A2907FEAE07038907FECE0F45480FFC469 -:10050A00540FFFE054072F25E024B4F582E4347F2A -:10051A00F583E4F0907FECE05480FF131313541F2B -:10052A00FFE054072F907FD7F0E04420F0806990D5 -:10053A007FB4E04401F08060120E4A505B907FE87D -:10054A00E024FE60182402704F907FEAE0B40104B0 -:10055A00D2008044907FB4E04401F0803B907FEA6F -:10056A00E07020907FECE0F45480FFC4540FFFE069 -:10057A0054072F25E024B4F582E4347FF58374010F -:10058A00F08015907FB4E04401F0800C1201005015 -:10059A0007907FB4E04401F0907FB4E04402F02277 -:1005AA00C0E0C083C082C085C084C086758600C092 -:1005BA00D0C000C001C002C003C006C007907FA51A -:1005CA00E030E206750D06020676907FA5E020E18E -:1005DA000CE50D64026006750D07020676AF0DEF95 -:1005EA0024FE604814602C24FE6077240460030211 -:1005FA000676AB09AA0AA90BAF0C050C8F82758384 -:10060A0000120822907FA6F0E50C6508705E750D51 -:10061A00058059907FA6E0AB09AA0AA90BAE0C8EF9 -:10062A008275830012084F750D028040E50824FE8A -:10063A00B50C07907FA5E04420F0E50814B50C0A34 -:10064A00907FA5E04440F0E4F50D907FA6E0AB0969 -:10065A00AA0AA90BAE0C8E8275830012084F050CEC -:10066A00800A907FA5E04440F0E4F50D5391DFD075 -:10067A0007D006D003D002D001D000D0D0D086D087 -:0A068A0084D085D082D083D0E03206 -:100694008C338D34907F95E044C0F0E4F535F53625 -:1006A400C3E5369534E53595335069EF2536F58243 -:1006B400E5353EF58374FFF0F46002C322EF25367E -:1006C400F582E5353EF583E4F06002C322EF25367A -:1006D400F582E5353EF58374AAF064AA6002C3226C -:1006E400EF2536F582E5353EF5837455F0645560A3 -:1006F40002C322AD36E5362FF582E5353EF583EDAE -:10070400F0FCAC05ED6C6002C3220536E5367002E0 -:100714000535808CE4F535F536C3E5369534E53595 -:1007240095335027EF2536F582E5353EF583E065B0 -:10073400366002C322EF2536F582E5353EF583E4C3 -:0D074400F00536E5367002053580CED32273 -:10075100C204D205C203C200C202C201120E3DD2BE -:10076100E843D820907FAB74FFF0907FA9F0907F91 -:10077100AAF05391EF907F95E044C0F0907F93747D -:1007810030F0120A19907FAFE04401F0907FAEE0A3 -:10079100440DF0D2AF120E352001427524007523AD -:1007A100007522007521007F487E927D007C00ABA0 -:1007B10024AA23A922A821C31208A950DB2001D809 -:1007C1007A0079007800E5242401F524EA3523F53F -:1007D10023E93522F522E83521F52180CA300105CA -:1007E10012037AC20130041A120E4050131209008A -:1007F100300007907FD6E030E7F3120D4A120E4227 -:08080100C2031208FF80D62299 -:10080900BB010689828A83E0225002E722BBFE02ED -:09081900E32289828A83E4932220 -:10082200BB010CE58229F582E5833AF583E022508B -:1008320006E92582F8E622BBFE06E92582F8E222D5 -:0D084200E58229F582E5833AF583E49322EF -:10084F00F8BB010DE58229F582E5833AF583E8F0DF -:10085F00225006E92582C8F622BBFE05E92582C88B -:02086F00F22273 -:10087100BB0110E58229F582E5833AF583E0F5F0C5 -:10088100A3E0225009E92582F886F008E622BBFEA2 -:100891000AE92582F8E2F5F008E222E5832AF583E8 -:0808A100E993F5F0A3E99322AD -:1008A900EB9FF5F0EA9E42F0E99D42F0E89C45F0A5 -:0108B900221C -:0208BA008F2885 -:1008BC00E4F529752AFF752B11752C32AB2AAA2B5E -:1008CC00A92C900001120822B4031DAF290529EFB1 -:1008DC00B52801221208097E0029FFEE3AA90775F6 -:0E08EC002AFFF52B892C80D47B007A0079003E -:0108FA0022DB -:0408FB0053D8EF32AD -:0108FF0022D6 -:09090000907FD6E04480F0807481 -:10097D00438701000000000000000000000000227D -:0C098D00787FE4F6D8FD7581390209D4AA -:10099900020751E493A3F8E493A34003F68001F21C -:1009A90008DFF48029E493A3F85407240CC8C3335F -:1009B900C4540F4420C8834004F456800146F6DF2E -:1009C900E4800B0102040810204080900DECE47EC5 -:1009D900019360BCA3FF543F30E509541FFEE49323 -:1009E900A360010ECF54C025E060A840B8E493A3EA -:1009F900FAE493A3F8E493A3C8C582C8CAC583CA15 -:100A0900F0A3C8C582C8CAC583CADFE9DEE780BECC -:100A1900E4907F9CF07F0AFE120D94907F96748972 -:100A2900F0907F9C74CFF07FF47E01120D94907F3B -:100A390096E054FEF07F0A7E00120D947F057E0039 -:100A4900120D94907F96E04402F0E0547FF07F0508 -:100A59007E00120D94907F96E04440F07F057E0061 -:100A6900120D94907F96E054BFF07F327E00120DF4 -:100A790094907F96E04440F07F327E00120D9422DC -:100A8900753201E532601B7F01120DD77F007E0EA2 -:100A99007D007C01120694E433F53270057F0F1254 -:100AA9000DD7E532601B7F02120DD77F007E807D56 -:100AB900007C80120694E433F53270057F0F120D25 -:100AC900D7E532601B7F03120DD77F007E207D4062 -:100AD9007C5B120694E433F53270057F0F120DD753 -:0E0AE900E5326005E4FF120DD7E53224FF224E -:080AF700907FEAE0F510D32224 -:010AFF0032C4 -:100B0000020D6400020DAB00020D2F00020D7C00EF -:100B1000020DC100020AFF00020E4C00020E4D0041 -:100B2000020E4E00020E4F00020E5000020E510047 -:100B3000020E5200020E5300020E5400020E550027 -:100B4000020E5600020E5700020E5800020E590007 -:080B5000020E5A00020E5B00C8 -:100B5800E4FE752AFF752B11752C12AB2AAA2BA956 -:100B68002C9000011208226402702DAD060EEDB51E -:100B780007012290000212087185F028F5296228E1 -:100B8800E5286229E529622829FDE5283AA905759D -:0E0B98002AFFF52B892C80C37B007A007900A0 -:010BA600222C -:100BA700AB07AA06AC05E4FDE5116011EAFFAE0547 -:100BB7000DEE2410F582E4340FF583EFF0EBAE056C -:100BC7000D74102EF582E4340FF583EBF0AF050DAD -:100BD70074102FF582E4340FF583ECF0AF0F7A0F22 -:0D0BE7007B10120D107F0A7E00120D94226B -:100BF4008E328F338D348A358B36E4FDF537E5112B -:100C04006012E532FFAE050DEE2413F582E4340FD5 -:100C1400F583EFF0E533AE050D74132EF582E4345D -:100C24000FF583E533F0AF0F7A0F7B13120D10AF7E -:0B0C34000FAD34AB36AA35120CF122D4 -:100C3F008E328F338D348A358B36E4F537E537C3F3 -:100C4F00953450200533E533AE327002053214FF70 -:100C5F00E5362537F582E43535F583E0FD120BA730 -:050C6F00053780D922C9 -:100C7400A907E50D7025907FA5E04480F0E925E003 -:100C84004401907FA6F08D08AF03A9077509018A76 -:0D0C94000A890BE4F50C750D03D322C32271 -:100CA100A907E50D7023907FA5E04480F0E925E0D8 -:100CB100907FA6F08D08AF03A9077509018A0A89FB -:0B0CC1000BE4F50C750D01D322C322DB -:100CCC00907FD6E054FBF0E04408F0300604E0449A -:100CDC0002F07FD07E07120D94907FD6E054F7F08F -:050CEC00E04404F022C9 -:100CF100120C74E50D24FA6010146007240770F3D8 -:0F0D01007F0822E4F50D7F0722E4F50D7F06221F -:100D1000120CA1E50D24FA6010146007240770F38B -:0F0D20007F0822E4F50D7F0722E4F50D7F062200 -:100D2F00C0E0C083C082907FC4E4F05391EF907F06 -:0B0D3F00AB7404F0D082D083D0E0320F -:100D4A00907FD6E030E712E04401F07F147E001273 -:0A0D5A000D94907FD6E054FEF022C5 -:100D6400C0E0C083C082D2015391EF907FAB740185 -:080D7400F0D082D083D0E03200 -:100D7C00C0E0C083C082D2035391EF907FAB740864 -:080D8C00F0D082D083D0E032E8 -:100D94008E388F39E5391539AE38700215384E6002 -:070DA40005120E0080EE2293 -:100DAB00C0E0C083C0825391EF907FAB7402F0D050 -:060DBB0082D083D0E0327B -:100DC100C0E0C083C0825391EF907FAB7410F0D02C -:060DD10082D083D0E03265 -:100DD700AE077F217D0174002EF582E4340FAB82CC -:050DE700FA120D1022BC -:100DEC00500F00C0F9A4B0999282F880988883C6FD -:030DFC00A1868E3F -:010DFF0000F3 -:100E00007400F58690FDA57C05A3E582458370F905 -:010E100022BF -:0E0E1100907F00E510F0907FB57401F0D322C1 -:0E0E1F00907F00E50EF0907FB57401F0D322B5 -:080E2D00907FEAE0F50ED322EC -:080E3500E4F50DD2E9D2AF2271 -:030E3D00D20022BE -:020E4000D322BB -:020E4200D322B9 -:020E4400D322B7 -:020E4600D322B5 -:020E4800D322B3 -:020E4A00D322B1 -:010E4C003273 -:010E4D003272 -:010E4E003271 -:010E4F003270 -:010E5000326F -:010E5100326E -:010E5200326D -:010E5300326C -:010E5400326B -:010E5500326A -:010E56003269 -:010E57003268 -:010E58003267 -:010E59003266 -:010E5A003265 -:010E5B003264 -:101100001201000100000040470510270100010204 -:10111000000109022000010103A0000904000002EF -:10112000FF0000040705820240000007050202409C -:10113000000004030904260341006E0063006800F8 -:101140006F007200200043006800690070007300A7 -:101150002C00200049006E0063002E00280346008A -:10116000690072006D007700610072006500200068 -:101170004600720061006D00650057006F0072004C -:101180006B0073002A0343006F006E006600690065 -:101190006700750072006100740069006F006E00E6 -:1011A000200053007400720069006E006700220383 -:1011B00049006E0074006500720066006100630003 -:1011C0006500200053007400720069006E00670023 -:0211D00000001D -:00000001FF -/***************************************************************************** - * - * whiteheat.h -- ConnectTech WhiteHEAT Firmware. - * - * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.com/) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (10/09/2002) Stuart MacDonald - * Firmware 4.06 - * - * (04/09/2000) gkh - * Updated the firmware with the latest provided by ConnectTech. - * - * (01/16/2000) gkh - * Fixed my intel hex processing tool, so now the firmware actually - * matches the original file (this was causing a few problems...) - * - * (01/15/2000) gkh - * Added debug loader firmware if DEBUG is #defined: - * Port 1 LED flashes when the vend_ax program is running - * Port 2 LED flashes when any SETUP command arrives - * Port 3 LED flashes when any valid VENDOR request occurs - * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs - * - * version 1.0 (01/09/2000) gkh - * Original firmware from ConnectTech massaged a little to be program - * readable. - * - *****************************************************************************/ - -#define whiteheat_DATE "20000106" diff --git a/firmware/whiteheat_loader_debug.HEX b/firmware/whiteheat_loader_debug.HEX deleted file mode 100644 index 5633d588613e151609672f01b3500f47a8d4d1cb..0000000000000000000000000000000000000000 --- a/firmware/whiteheat_loader_debug.HEX +++ /dev/null @@ -1,403 +0,0 @@ -:10000000000000000302098D0000003303020E709F -:100010000000004303020B000000004B030205B385 -:100020000000010010907FA5E05410FFC4540F445D -:1000300050F50F13E4000110000001101033F5110A -:10004000907FE9E0245EB407004003020300012032 -:1000500000000120107C900128F82828730201BCC0 -:100060000201BC02010001300000013010910201C8 -:100070003D02015302016F02019A907F000001408E -:100080000000014010E511F0907FB57401F0907F01 -:10009000B4E04402F0000150000001501002037C63 -:1000A000907F92E0FFC4540F907F00F090000160B9 -:1000B00000000160107FB57401F0907FB4E044024D -:1000C000F002037C1200017000000170100A8950D8 -:1000D00007E4907F00F08006907F00740F0001809D -:1000E0000000018010F0907FB57401F0907FB4E0C3 -:1000F0004402F0020300019000000190107C907F08 -:10010000EAE0F50F02037C907F007407F00001A085 -:10011000000001A010907FB57401F0907FB4E0441E -:1001200002F07FE87E0001B0000001B01003120D64 -:10013000D5D206120D0D02037C907FEAE00001C0CB -:10014000000001C010752900F52AA3E0FEE4EE428C -:1001500029907FEEE00001D0000001D010752B0047 -:10016000F52CA3E0FEE4EE422B907FE8E00001E0F6 -:10017000000001E01064C060030202C9E52C452BB9 -:10018000700302037C0001F0000001F010C3E52CB5 -:100190009440E52B94005008852B2D852C000200FF -:1001A00000000200102E8006752D00752E40907FF5 -:1001B000E9E064A370000210000002101034F53171 -:1001C000F532C3E532952EE531952D505C000220C5 -:1001D0000000022010E52A2532F582E5313529F5A7 -:1001E00083E0FF740000023000000230102532F579 -:1001F00082E4347FF583EFF00532E532700002408F -:10020000000002401002053180D0E4F531F532C320 -:10021000E532952EE5000250000002501031952D78 -:10022000501874002532F582E4347FF583000260B3 -:10023000000002601074CDF00532E5327002053125 -:1002400080DDAF2AAE000270000002701029AD2ED2 -:100250007A7F79007B00120BF4907FB5E500028075 -:1002600000000280102EF0E52E252AF52AE52D3516 -:1002700029F529C3E500029000000290102C952E6C -:10028000F52CE52B952DF52B907F92E0FF0002A039 -:10029000000002A010C4540F752F00F530D3940055 -:1002A000E52F9400500002B0000002B0100C907FC7 -:1002B000B4E020E1030201E780F4907FB40002C0C3 -:1002C000000002C010E020E2030201E780F4907F0A -:1002D000E8E06440600002D0000002D01003020396 -:1002E0007CE52C452B700302037CE4907F0002E048 -:1002F000000002E010C5F0907F92E0FFC4540F753B -:100300002F00F530D30002F0000002F0109400E559 -:100310002F94005009907FC4E030E1098000030071 -:100320000000030010F7907FB4E020E3F9907FC550 -:10033000E0752D00F500031000000310102E907FD3 -:10034000E9E064A3703890206BF0F531F5000320EC -:10035000000003201032C3E532952EE531952D5073 -:100360003474C025320003300000033010F582E4FD -:10037000347EF583E0FFE52A2532F582E50003406F -:100380000000034010313529F583EFF00532E532E6 -:1003900070020531800003500000035010D0AF2AD6 -:1003A000AE29AD2E7A7E79C07BC0120C800003602E -:1003B0000000036010E52E252AF52AE52D3529F5E4 -:1003C00029C3E52C95000370000003700D2EF52C59 -:1003D000E52B952DF52B0202D4C300000000037D10 -:1003E000012200000000037E10907FE9E07003020C -:1003F00004561470030204D22400038E0000038EFE -:1004000010FE700302054624FB70030204501470B2 -:100410000300039E0000039E1002044A14700302AE -:10042000043E147003020444240003AE000003AE33 -:100430001005600302059A120E7B40030205AB9083 -:100440007F0003BE000003BE10EBE024FE60161424 -:100450006040240270697411900003CE000003CE46 -:10046000107FD4F07400907FD5F00205AB907FEA46 -:10047000E00003DE000003DE10FF120B588B268A1B -:10048000278928EA496011AE020003EE000003EE5E -:1004900010EE907FD4F0AF01EF907FD5F00205AB66 -:1004A000900003FE000003FE107FB4E04401F00260 -:1004B00005AB907FEAE0FF120C00040E0000040E72 -:1004C000103F8B268A278928EA496011AE02EE90F8 -:1004D0007F00041E0000041E10D4F0AF01EF907FD7 -:1004E000D5F00205AB907FB4E000042E0000042E8E -:1004F000104401F00205AB907FB4E04401F0020526 -:10050000AB00043E0000043E10120E520205AB1276 -:100510000E600205AB120AF70200044E0000044E02 -:100520001005AB1208F10205AB120E7D4003020567 -:10053000AB00045E0000045E10907FE8E0247F6062 -:10054000241460312402705BA200046E0000046E6B -:100550001000E433FF25E0FFA202E4334F907F0058 -:10056000F000047E0000047E10E4A3F0907FB574D8 -:1005700002F00205ABE4907F0000048E0000048EC0 -:1005800010F0A3F0907FB57402F00205AB907FEC01 -:10059000E000049E0000049E10F45480FFC4540F39 -:1005A000FFE054072F25E024B40004AE000004AEA1 -:1005B00010F582E4347FF583E054FD907F00F0E491 -:1005C000A30004BE000004BE10F0907FB57402F0DA -:1005D0000205AB907FB4E044010004CE000004CEDD -:1005E00010F00205AB120E7F40030205AB907FE8CE -:1005F000E00004DE000004DE1024FE601D24026022 -:10060000030205AB907FEAE0B40004EE000004EEC4 -:10061000100105C2000205AB907FB4E04401F00276 -:10062000050004FE000004FE10AB907FEAE0703885 -:10063000907FECE0F45480FFC400050E0000050E2E -:1006400010540FFFE054072F25E024B4F582E43462 -:100650007F00051E0000051E10F583E4F0907FEC7E -:10066000E05480FF131313541F00052E0000052EC5 -:1006700010FFE054072F907FD7F0E04420F0806E09 -:100680009000053E0000053E107FB4E04401F0807C -:1006900065120E815060907FE800054E0000054E07 -:1006A00010E024FE601824027054907FEAE0B40148 -:1006B0000400055E0000055E10D2008049907FB402 -:1006C000E04401F08040907FEA00056E0000056E76 -:1006D00010E07020907FECE0F45480FFC4540FFFD2 -:1006E000E000057E0000057E1054072F25E024B4AD -:1006F000F582E4347FF583740100058E0000058ED9 -:1007000010F0801A907FB4E04401F08011E4902052 -:100710006A00059E0000059E10F01201005007902F -:100720007FB4E04401F0907FB40005AE000005AE58 -:1007300004E04402F0000000000005B201220000C5 -:10074000000005B310C0E0C083C082C085C084C073 -:1007500086758600C00005C3000005C310D0C00028 -:10076000C001C002C003C006C007907FA50005D32A -:10077000000005D310E030E206750D0602067F90FA -:100780007FA5E020E10005E3000005E3100CE50D86 -:1007900064026006750D0702067FAF0DEF0005F3DA -:1007A000000005F31024FE604814602C24FE6077DE -:1007B00024046003020006030000060310067FAB5A -:1007C00009AA0AA90BAF0C050C8F827583000613CA -:1007D000000006131000120785907FA6F0E50C6557 -:1007E00008705E750D000623000006231005805971 -:1007F000907FA6E0AB09AA0AA90BAE0C8E000633C7 -:100800000000063310827583001207B2750D028056 -:1008100040E50824FE0006430000064310B50C071F -:10082000907FA5E04420F0E50814B50C0A000653BB -:100830000000065310907FA5E04440F0E4F50D90D1 -:100840007FA6E0AB090006630000066310AA0AA9B0 -:100850000BAE0C8E827583001207B2050C00067376 -:100860000000067310800A907FA5E04440F0E4F594 -:100870000D5391DFD0000683000006831007D006D9 -:10088000D003D002D001D000D0D0D086D0000693C3 -:10089000000006930A84D085D082D083D0E0320055 -:1008A0000000069D10C204D205E4F525C203C20073 -:1008B000C202C201120006AD000006AD100E74D2D5 -:1008C000E843D820907FAB74FFF0907FA90006BD6D -:1008D000000006BD10F0907FAAF05391EF907F9535 -:1008E000E044C0F0900006CD000006CD107F937468 -:1008F00030F0120A1975244875239275220006DD1E -:10090000000006DD1000752100E4FFFE7E0590204A -:10091000687401F0A30006ED000006ED10DEFC7E19 -:10092000007F05907FAFE04401F0907FAE0006FDB0 -:10093000000006FD10E0440DF0D2AF120E68300149 -:100940000AE490206900070D0000070D10F0120363 -:100950007EC20130041A120E775013120900071DCF -:100960000000071D1000300007907FD6E030E7F34D -:10097000120D8B120E00072D0000072D1079C203F7 -:100980007FFF7EFF7DFF7CFF782112081D00073D61 -:100990000000073D107B007A0079007800C3120840 -:1009A0000C701B752400074D0000074D104875237F -:1009B00092F522F5216325FF902068E52500075D6B -:1009C0000000075D0EF0A37401F0A3F0A3F012087D -:1009D000FF809B000000076B012200000000076CF5 -:1009E00010BB010689828A83E0225002E722BBFE07 -:1009F0000200077C0000077C09E32289828A83E4E5 -:100A0000932200000000078510BB010CE58229F548 -:100A100082E5833AF583E0225000079500000795B0 -:100A20001006E92582F8E622BBFE06E92582F8E2F7 -:100A3000220007A5000007A50DE58229F582E583C0 -:100A40003AF583E493220000000007B210F8BB01DE -:100A50000DE58229F582E5833AF583E8F00007C2C7 -:100A6000000007C210225006E92582C8F622BBFE0C -:100A700005E92582C80007D2000007D202F2220051 -:100A8000000007D410BB0110E58229F582E5833A06 -:100A9000F583E0F5F00007E4000007E410A3E0228E -:100AA0005009E92582F886F008E622BBFE0007F42B -:100AB000000007F4100AE92582F8E2F5F008E222C6 -:100AC000E5832AF5830008040000080408E993F58B -:100AD000F0A3E993220000000000080C10EB9FF542 -:100AE000F0EA9E42F0E99D42F0E89C45F000081CC7 -:100AF0000000081C012200000000081D1008080862 -:100B0000E62FFFF618E63EFEF618E63DFD00082D3E -:100B10000000082D07F618E63CFCF6220000083419 -:100B2000048C348D350000000000083810907F954B -:100B3000E044C0F0E4F536F537C3E53795000848E2 -:100B4000000008481035E53695345069EF2537F533 -:100B500082E5363EF500085800000858108374FFFF -:100B6000F0F46002C322EF2537F582E5360008680D -:100B700000000868103EF583E4F06002C322EF2510 -:100B800037F582E53600087800000878103EF583D6 -:100B900074AAF064AA6002C322EF2537F500088822 -:100BA000000008881082E5363EF5837455F06455E0 -:100BB0006002C322AD000898000008981037E5379E -:100BC0002FF582E5363EF583EDF0FCAC050008A874 -:100BD000000008A810ED6C6002C3220537E53770ED -:100BE000020536808C0008B8000008B810E4F5361D -:100BF000F537C3E5379535E536953450270008C8F5 -:100C0000000008C810EF2537F582E5363EF583E091 -:100C100065376002C30008D8000008D81022EF250D -:100C200037F582E5363EF583E4F00537E50008E860 -:100C3000000008E808377002053680CED3000000B7 -:100C4000000008F001220000000008F10E907F0073 -:100C5000E510F0907FB57401F0D32200000008FF8A -:100C6000012200000000090009907FD6E04480F0D6 -:100C7000807400000000097D10438701000000001F -:100C800000000000000000002200098D0000098D16 -:100C90000C787FE4F6D8FD75813A0209D400000093 -:100CA000000009991002069DE493A3F8E493A34081 -:100CB00003F68001F20009A9000009A91008DFF479 -:100CC0008029E493A3F85407240CC8C3330009B95E -:100CD000000009B910C4540F4420C8834004F456DE -:100CE000800146F6DF0009C9000009C910E4800B45 -:100CF0000102040810204080900E2DE47E0009D9E6 -:100D0000000009D910019360BCA3FF543F30E509EE -:100D1000541FFEE4930009E9000009E910A36001F3 -:100D20000ECF54C025E060A840B8E493A30009F9B1 -:100D3000000009F910FAE493A3F8E493A3C8C5826C -:100D4000C8CAC583CA000A0900000A0910F0A3C86E -:100D5000C582C8CAC583CADFE9DEE780BE000A19BA -:100D600000000A1910E4907F9CF07F0AFE120DD556 -:100D7000907F967489000A2900000A2910F0907F5C -:100D80009C74CFF07FF47E01120DD5907F000A395C -:100D900000000A391096E054FEF07F0A7E00120D22 -:100DA000D57F057E00000A4900000A4910120DD5C2 -:100DB000907F96E04402F0E0547FF07F05000A59EE -:100DC00000000A59107E00120DD5907F96E0444035 -:100DD000F07F057E00000A6900000A6910120DD537 -:100DE000907F96E054BFF07F327E00120D000A79AA -:100DF00000000A7910D5907F96E04440F07F327E63 -:100E000000120DD522000A8900000A8910753301ED -:100E1000E533601B7F01120E187F007E0E000A99D9 -:100E200000000A99107D007C01120834E433F53388 -:100E300070057F0F12000AA900000AA9100E18E51C -:100E400033601B7F02120E187F007E807D000AB97E -:100E500000000AB910007C80120834E433F53370C6 -:100E6000057F0F120E000AC900000AC91018E533E9 -:100E7000601B7F03120E187F007E207D40000AD980 -:100E800000000AD9107C5B120834E433F533700596 -:100E90007F0F120E18000AE900000AE90DE5336021 -:100EA00005E4FF120E18E53324FF000000000AF6E7 -:100EB0000122000000000AF708907FEAE0F510D355 -:100EC0002200000000000AFF0132000000000B00B9 -:100ED00010020DA500020DEC00020D7000020DBD08 -:100EE00000000B1000000B1010020E0200020AFF9F -:100EF00000020E8300020E8400000B2000000B2075 -:100F000010020E8500020E8600020E8700020E8877 -:100F100000000B3000000B3010020E8900020E8A18 -:100F200000020E8B00020E8C00000B4000000B40F4 -:100F300010020E8D00020E8E00020E8F00020E9027 -:100F400000000B5000000B5008020E9100020E92A0 -:100F50000000000000000B5810E4FE752BFF752CFC -:100F600011752D12AB2BAA2CA9000B6800000B6881 -:100F7000102D9000011207856402702DAD060EED54 -:100F8000B5000B7800000B781007012290000212C8 -:100F900007D485F029F52A6229000B8800000B8808 -:100FA00010E529622AE52A622929FDE5293AA905E1 -:100FB00075000B9800000B980E2BFFF52C892D80E7 -:100FC000C37B007A0079000000000BA6012200001C -:100FD00000000BA706AB07AA06AC050000000BAD8E -:100FE00010E4FDE5116011EAFFAE050DEE2410F5E9 -:100FF00082000BBD00000BBD10E4340FF583EFF051 -:10100000EBAE050D74102EF582000BCD00000BCD5C -:1010100010E4340FF583EBF0AF050D74102FF5825B -:10102000E4000BDD00000BDD10340FF583ECF0AFB6 -:101030000F7A0F7B10120D517F000BED00000BEDAE -:10104000060A7E00120DD50000000BF301220000FD -:1010500000000BF40A8E338F348D358A368B3700BF -:1010600000000BFE10E4FDF538E5116012E533FFDA -:10107000AE050DEE24000C0E00000C0E1013F582D0 -:10108000E4340FF583EFF0E534AE050D74000C1E6B -:1010900000000C1E10132EF582E4340FF583E534A6 -:1010A000F0AF0F7A0F000C2E00000C2E107B1312E5 -:1010B0000D51AF0FAD35AB37AA36120D32000C3ED5 -:1010C00000000C3E0122000000000C3F028F2900AE -:1010D00000000C4110E4F52A752BFF752C11752DBD -:1010E00032AB2BAA2C000C5100000C5110A92D90F2 -:1010F0000001120785B4031DAF2A052AEF000C6119 -:1011000000000C6110B529012212076C7E0029FF36 -:10111000EE3AA90775000C7100000C710E2BFFF55B -:101120002C892D80D47B007A0079000000000C7F90 -:101130000122000000000C800A8E338F348D358A26 -:10114000368B370000000C8A10E4F538E538C3957B -:101150003550200534E534AE33000C9A00000C9A6B -:10116000107002053314FFE5372538F582E4353673 -:10117000F5000CAA00000CAA0A83E0FD120BA705DB -:101180003880D90000000CB40122000000000CB52A -:1011900010A907E50D7025907FA5E04480F0E925B2 -:1011A000E0000CC500000CC5104401907FA6F08D36 -:1011B00008AF03A9077509018A000CD500000CD5FA -:1011C0000D0A890BE4F50C750D03D322C322000030 -:1011D00000000CE210A907E50D7023907FA5E04404 -:1011E00080F0E925E0000CF200000CF210907FA6E0 -:1011F000F08D08AF03A9077509018A0A89000D025D -:1012000000000D020B0BE4F50C750D01D322C32277 -:1012100000000D0D10907FD6E054FBF0E04408F084 -:10122000300604E044000D1D00000D1D1002F07F8B -:10123000D07E07120DD5907FD6E054F7F0000D2D2B -:1012400000000D2D05E04404F022000000000D32E6 -:1012500010120CB5E50D24FA601014600724077015 -:10126000F3000D4200000D420F7F0822E4F50D7FD0 -:101270000722E4F50D7F062200000D5110120CE24A -:10128000E50D24FA6010146007240770F3000D6167 -:1012900000000D610F7F0822E4F50D7F0722E4F5C1 -:1012A0000D7F062200000D7010C0E0C083C0829048 -:1012B0007FC4E4F05391EF907F000D8000000D801B -:1012C0000BAB7404F0D082D083D0E03200000D8BE1 -:1012D00010907FD6E030E712E04401F07F147E00EA -:1012E00012000D9B00000D9B0A0DD5907FD6E05497 -:1012F000FEF0220000000DA510C0E0C083C082D225 -:10130000015391EF907FAB7401000DB500000DB556 -:1013100008F0D082D083D0E03200000000000DBD84 -:1013200010C0E0C083C082D2035391EF907FAB74B2 -:1013300008000DCD00000DCD08F0D082D083D0E0A4 -:101340003200000000000DD5108E398F3AE53A15B5 -:101350003AAE39700215394E60000DE500000DE51A -:101360000705120E4180EE2200000DEC10C0E0C017 -:1013700083C0825391EF907FAB7402F0D0000DFCDC -:1013800000000DFC0682D083D0E0320000000E0287 -:1013900010C0E0C083C0825391EF907FAB7410F017 -:1013A000D0000E1200000E120682D083D0E0320070 -:1013B00000000E1810AE077F217D0174002EF5820B -:1013C000E4340FAB82000E2800000E2805FA120D3F -:1013D0005122000000000E2D10500F00C0F9A4B0E3 -:1013E000999282F880988883C6000E3D00000E3DD9 -:1013F00003A1868E00000E400100000000000E4197 -:10140000107400F58690FDA57C05A3E582458370E8 -:10141000F9000E5100000E510122000000000E5292 -:101420000E907F00E50EF0907FB57401F0D322009E -:1014300000000E6008907FEAE0F50ED32200000065 -:1014400000000E6808E4F50DD2E9D2AF22000000DA -:1014500000000E700453D8EF3200000000000E743C -:1014600003D2002200000E7702D3220000000E7982 -:1014700002D3220000000E7B02D3220000000E7D6A -:1014800002D3220000000E7F02D3220000000E8152 -:1014900002D3220000000E830132000000000E84FF -:1014A0000132000000000E850132000000000E86AF -:1014B0000132000000000E870132000000000E889B -:1014C0000132000000000E890132000000000E8A87 -:1014D0000132000000000E8B0132000000000E8C73 -:1014E0000132000000000E8D0132000000000E8E5F -:1014F0000132000000000E8F0132000000000E904B -:101500000132000000000E910132000000000E9236 -:101510000132000000001100101201000100000063 -:1015200040470510270100010200111000001110B2 -:1015300010000109022000010103A00009040000BD -:10154000020011200000112010FF00000407058296 -:101550000240000007050202400011300000113077 -:1015600010000004030904260341006E00630068B4 -:101570000000114000001140106F00720020004375 -:1015800000680069007000730000115000001150E5 -:10159000102C00200049006E0063002E0028034636 -:1015A000000011600000116010690072006D00778A -:1015B00000610072006500200000117000001170D1 -:1015C000104600720061006D00650057006F0072E8 -:1015D0000000118000001180106B0073002A03438B -:1015E000006F006E0066006900001190000011900D -:1015F000106700750072006100740069006F006E72 -:10160000000011A0000011A010200053007400720F -:101610000069006E00670022030011B0000011B0E5 -:101620001049006E0074006500720066006100637E -:10163000000011C0000011C01065002000530074AC -:1016400000720069006E0067000011D0000011D028 -:091650000200000000000000008F -:00000001FF -/***************************************************************************** - * - * whiteheat.h -- ConnectTech WhiteHEAT Firmware. - * - * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.com/) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (10/09/2002) Stuart MacDonald - * Firmware 4.06 - * - * (04/09/2000) gkh - * Updated the firmware with the latest provided by ConnectTech. - * - * (01/16/2000) gkh - * Fixed my intel hex processing tool, so now the firmware actually - * matches the original file (this was causing a few problems...) - * - * (01/15/2000) gkh - * Added debug loader firmware if DEBUG is #defined: - * Port 1 LED flashes when the vend_ax program is running - * Port 2 LED flashes when any SETUP command arrives - * Port 3 LED flashes when any valid VENDOR request occurs - * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs - * - * version 1.0 (01/09/2000) gkh - * Original firmware from ConnectTech massaged a little to be program - * readable. - * - *****************************************************************************/ - -#define whiteheat_DATE "20000106" diff --git a/firmware/yam/1200.bin.ihex b/firmware/yam/1200.bin.ihex deleted file mode 100644 index 9d34e5680e381c2010535c833a2fbb4a5f414337..0000000000000000000000000000000000000000 --- a/firmware/yam/1200.bin.ihex +++ /dev/null @@ -1,342 +0,0 @@ -:10000000FFF200A5ADFFFE9FFFEFF3CBFFDBFCF29D -:10001000FFF6FF3CBFFDBFDF6E3F6FF17DB4FDBF5C -:10002000DF6F3F6FF70BFFDBFDF2FFF6FFFFFFFF18 -:10003000F0CFFFFFFFFEFFFFDFFFFFFFEFFFFFFF40 -:10004000FDFFFFFFFEFFFFFFFFFFF1FFFFFFFFBF11 -:10005000FFFFF7FFFFFBFFFFFFFCFFFEFFFFFFF0CF -:100060005FFFFFFFFEFFFFFFFFFFFFFFFFFFFFFF41 -:10007000FFFFFFFFFFF7FFFFFFF1FFFFFE7FBFFF67 -:10008000FFFFFFFFFFFFFFFFF7FFFBFFFFFFF09FFB -:10009000FFFFFFFEFFFDFFFFFFFFDFFFFFFFF7FF9B -:1000A000FFFFFBFFFBFFFFFFF0FFFFFFFFFFFFFF77 -:1000B000F7FFFFFBFFFFFFFEFFFFFFEFFFF05FFF1C -:1000C000FFFFFEFFFFEFFFFFFBFFFFFFFFFFFFFF55 -:1000D000FFBFFFFFDFF7FFF1FFFFFFFFFFFFFFFFA6 -:1000E000FFFFFFFFFFFBFEFFFFFFFFFFF0FFFFFF34 -:1000F000FFFEFFFFFFFFFFFFFFFFFFFFFFFFFFEB25 -:10010000FFFFFFFDFFBFF1FFFFFFFFDFFFFFFFFB73 -:10011000FFFFFFFFFFFFFFFFFFFFFFF06FFFFFFF8E -:10012000FEFFFFFFFFFFFFFFFFFFDFFFFFFFFFFF00 -:10013000FFFFF7FFFFF1FFFFF7BFE7FFFFFFFFFB49 -:10014000FFFFFFFFFFFF77FFFFFFF0FFFFFFFFFE57 -:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF -:10016000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFAD -:10017000FFFFFFFFFFFFFFFFFFF01FFFFFFFFEDBA3 -:10018000FFFFF5A5FD4B6EEF3332DDD34AD692FE6D -:10019000B33FBDF1FADBFEF7F696BDBDFFBDFFED47 -:1001A0007F6B7FFBDFFEFBFE90CFFFFFFFFEBEEF0E -:1001B000FFFFDB5FF6FFF68FFDA5DDFFFFFFFF6FA3 -:1001C0007FDBF1FCBFFF6FFFEFFC5B5DDADFF4FF6D -:1001D000F2FFFDBFFFFFFFD01FFFFFFFFEFFFFFF8E -:1001E000FFFBEFB7FC33FFFBFF046AF33C36FFF085 -:1001F0000FF10FFFFFFFF315720FF16FFFFE943F3A -:10020000FFFFFF7BFFFFF0FFFFFFFFFEFFFFFFF0A1 -:10021000F7EFB7FC33FFFFFF046AF33C36FFF00F44 -:10022000F10FFFFFFFF315738FF26FFFFE943FFF97 -:10023000FFFF7D9FFFF00FFFFFFFFEFFFFFFFF9E11 -:10024000FFFCEFD3FBFF7FF55FFE59FFFFFFFCF1E3 -:10025000FE7FFFFFFA17FFE7EFEFFFFF3FF1FFFF22 -:10026000FFFFFFFFF0FFFFFFFFFEF5FFBFFFFCEA10 -:10027000FFF0FFFFBFF93FB1EFFFD7FFFBFFF0FF3C -:10028000FFF3FFDFFF7BFFFDFFF6FFBFFFFFBFFFB9 -:10029000FFFFDAF0FFFFFFFFFEF2C00100000202E5 -:1002A0000202004040401000000020000001000059 -:1002B000000000001900040400000000000000100D -:1002C000003CF0AFFFFFFFFEFDBFFFFFFBFFFDFFA8 -:1002D000FF7FFFFFBFFFEFFFFFFDFFFFF1FFDFFF2E -:1002E000FFFFFFFFFFBFFEFFFFFEFFFFFFFFFFDF80 -:1002F000DBF06FFFFFFFFEF0BFDFFF7FFFFFFFFFC1 -:10030000DFDFFFEFFF9EEFFFFF7FFFF1EFFFFFFF5C -:10031000F7FABFFFFFFE47EFFFBDF6FFFFDFF5F087 -:10032000F0EFFFFFFFFEF8300000000400010208BC -:1003300016000000800001020080010C0200000194 -:100340000000200000060020001000140004C1F08E -:100350002FFFFFFFFEFFFFFFFFFFFFFFFBFFFF7F02 -:10036000ECFFFFFAFFBFFF6FFFE1FFFFFFFFBDFEE6 -:1003700046FFEF7FCDDFFFFFFDFFBDFF7F7FF04F2B -:10038000FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7E -:10039000FFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFF7B -:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFF00FFF5C -:1003B000FFFFFEFFFFFFFDA4BCCD6D6B6F5BDC3369 -:1003C0005AF6F7F6B33FBDC1FA5AF6F6B6F7FFBDD7 -:1003D000BB3CCECF34EF33BBCCFFFFFFF04FFFFF72 -:1003E000FFFEBFFFFFFFDBFFF6D6FFFDFDBFFFAD4A -:1003F000BFF97F6FFCDBF1FDBFFF6FFFFFDADBFCB6 -:10040000DBFF768FF6FFCDABFEFBFFD0FFFFFFFFDC -:10041000FEFF9FFFF420AF6D0BC17BFFFFFFCBFF03 -:100420003FF0EF7F0FF1C33CFFFFFFFFFFFFF80B33 -:100430001D6A64056B9901FFFDEFF02FFFFFFFFEC2 -:10044000FFFFFFF4002FCC0BC37FFFFFFF0ADFBFCE -:10045000FD7FFFFFF1C3BFFFFFFFFFFFFFF04A0E6D -:10046000966402979910FFFFFFF0DFFFFFFFFEFF8A -:10047000FFFFFE84F9D527F17FFFF8EBDFF3CF3FD5 -:100480001FFFF711FFCFFFFE67FFFFFFFFC4FFFF56 -:10049000B3A1FFF9E0FFFFFFF0EFFFFFFFFEF5FF65 -:1004A000FFFB7FE0FFC7FE7F3FFFFD778D7F0FFFE4 -:1004B000C3FFF1BF8FCFFFFFDD7BFFF6FAF7FF40F1 -:1004C0009FF97FD8FFFFFAF01FFFFFFFFEF1C0008A -:1004D00000030000000000000000400010000010B9 -:1004E00000010010202000001000040105000000A1 -:1004F00000404000003CF01FFFFFFFFEFDBFFFFF7C -:10050000FFFFFE7F7FFFEFFFFFDFFFFFDFFFEFF764 -:10051000F1FFFFFFFFDFFFFFF7FFFFFFFCFDFF7FA6 -:100520007EFFFFFFDBF06FFFFFFFFEF0BBFFFFFF73 -:10053000FFFFFEEBFD6FFFF7FEF57FFFFF7FBFB113 -:10054000FFFF9FBFFBFFFEFFFEFFF7EBDFBF5FDD9F -:10055000FFDBFDD0F06FFFFFFFFEF8302000420010 -:100560000000301804080921828002000800010000 -:1005700000000C2010001100448400202084800022 -:100580000000C1F0DFFFFFFFFEFFF7FFFBDDF9FF1B -:10059000DAFFDCDDFCFBFFBFFB3ED796FE61F7FF19 -:1005A0007FFF3FFDFFDFCFF7DFF7BFFDFFFEEFEF80 -:1005B000FEFFF07FFFFFFFFEFFFFFFFFFFFFFFFFDC -:1005C000FFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFF49 -:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B -:1005E000FFF02FFFFFFFFEFFFFFFF3BDFD4B74CFBA -:1005F000735BCB3BDFFEF7FED375ACA1FBDFFEF7F1 -:100600007696B524BDA5AD492F692B525BBDFFFF82 -:10061000F0CFFFFFFFFEBFFFFFFFDBFFF6FEFFCCCB -:10062000A7FBADFF7F6FFF6D7FDBF1FDBFFF6FFFAE -:100630006FFFDBFFDBFFF697F6FFB5B5FFFFFFD0DF -:10064000EFFFFFFFFEFFFFFFFDA5BC43FC7C03E7C0 -:10065000FFFF20FFFFFFCCFD7DF1FFFFFFFFD5591E -:10066000BA56666AAD9AA99A97A5AABBFFFFF00F82 -:10067000FFFFFFFEFEFBFFFDF7FD43FFFD6BE7FF06 -:10068000FFDFFFFFFFFFFF3FF1FFFFFFFFD559B582 -:10069000A6666AAD9AA9996B5AAAFFFFB7F03FFF09 -:1006A000FFFFFEFFFFFFFE9CF7FDD241FFFFF27F41 -:1006B0008FFFFF3DF3FF17F1FFFFFFFFFF7FDFFC21 -:1006C0008F38FFEF23FFFBF7C8FFFFFFF09FFFFF0F -:1006D000FFFEF57FFFFDFFE4FFEBFFCFBFFAFFABAF -:1006E000EFFFFBFFF3FD61FFFFFFFFFAFFFBFD0DD7 -:1006F000FFFEFF437FFEBFD0FDFFFAF03FFFFFFF8D -:10070000FEF3C0000000020002010060C0400000D3 -:100710000000340400010000000000000008880010 -:100720000003000040004000003CF03FFFFFFFFEE0 -:10073000FD3FFFFFFFFFFFFF7F7FBFFFFFFFFFFFCB -:10074000FFFFFFF7F1FFFFFFFFFFF7FFFFFFFDFFD9 -:10075000FFFFFFFEFE5FFFFFCBF0DFFFFFFFFEF0BE -:10076000FFFFFDFFEFE3DEEED9C593FFFFFEFEFFC7 -:10077000FBEEFEF1FFFFFFFFFFFDFFBFF7FFFF7F77 -:10078000AFBDDFDFFBF3F3F0F0AFFFFFFFFEF834A8 -:10079000000661001801A0051700200528200000B0 -:1007A0000500410000400009000120868208400346 -:1007B000803070081402C1F0CFFFFFFFFEFFFFFF83 -:1007C000FFFFBDEFFBFFFFFB9C7FEFDFFFBFEBDE1B -:1007D000FFC17FFFFB7FFFFFFF5FFFFFFFDFBFEF7B -:1007E0003FF78FEF7FFFF07FFFFFFFFEFFFFFFFF71 -:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 -:10080000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 -:10081000FFFFFFFFFFF03FFFFFFFFEFFFFFFFFBDFA -:10082000DFEF7D6D2B5A5DD2DFF692B6B2B3ACA18D -:10083000FBDFFEF1EEF5F6BC6BBD7DAF1AEF5F6B33 -:10084000C6FFFFFFF05FFFFFFFFEBFFFFFFFDBFF05 -:10085000F6FFF6B7FDADFDBFF36FFF6FFFDBD1FD18 -:10086000BFFF6FF56BBC5B3CDAEF16AF16FFCDAB8D -:10087000FF6FFFD0FFFFFFFFFEFFFFFFFCBFFFFF8B -:10088000FF6C0310C1F3FFF33AF3CAFFAFF1FFFFB0 -:10089000FFFFD996A665A6666A9569696A5A5AFFE6 -:1008A000FF5FF01FFFFFFFFEFFFFFFFFBFFFFFFF28 -:1008B000EA0F50C3F37FFFF3F3C3FFAFF1FFFFFF76 -:1008C000FFD996A665A6666A9569696A5A5AFFFFB6 -:1008D000FFF03FFFFFFFFEFFFFFFFFD7FFFF5FC1FE -:1008E0003FF75EF5CE9E5F3F17FFF3E1FFFFFFFF8F -:1008F000D8FFFAFE67FFFEBF5AFFFFAFF5FFFFFF0D -:10090000F02FFFFFFFFEF5FFFFFDFFF7FFFD4E3D60 -:100910003FE70BBF8FF9FFEBE3FFE1FFFFFCFFC7F2 -:100920009FFF3E39E5FFCF9BF9FFFFC5FFFFFAF0C0 -:100930005FFFFFFFFEF3C00000000000000040006A -:100940000000006000000000000100000020002006 -:10095000000110080000000000000000003CF04F03 -:10096000FFFFFFFEFDBFFFFFFFFFFFFFFEFFFFBF1B -:100970003FFFFFBFFFFFFFFBF1FFFFFFFFF7FFF7A9 -:10098000FFEDFFFBFEFF7FFF7FDFFFFFDDF03FFF9F -:10099000FFFFFEF0FFFFF3FFF7FFFE5FFFF7FFFF34 -:1009A000DFFFFFFFF7FE7BF1FFFDFDFFDFDFFF7DD8 -:1009B00073F9FFC37EFEFFEFD7FFCFD0F06FFFFFCD -:1009C000FFFEF83000004004000141200004000256 -:1009D000D50900028002010000000A04000700019E -:1009E000500180026140410C1408C1F09FFFFFFFDD -:1009F000FEFFFFFFFEFFFFFFFEDFCB5FFEEFFFFE10 -:100A0000FF3FFF7FFDC1FFFF7FFFDFFDFCFDF7EE36 -:100A1000FFFF4EFFDFCFDBEBFFFFF01FFFFFFFFE0F -:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 -:100A3000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFD4 -:100A4000FFFFFFFFFFFFFFFFFFF02FFFFFFFFE7F16 -:100A5000FFFFFFFDFFFFFFFFFFFFFFFFDFFFFFFFC8 -:100A6000F7FBFFF1FFFFFFFFFFFFFFFFFFFFFFFFB0 -:100A7000FFFF7FFFFFFF7FFFF01FFFFFFFFEDDFF98 -:100A8000FFFFA5FF6F6BE96FDACAFBDDEEF7F6B289 -:100A9000B3A4A15B5BF6D7F4F77BBDBDADCFEF7F11 -:100AA0006B7F3BDFDBFFFF30CFFFFFFFFEBFFFFFB2 -:100AB000FFFFFFF6FE96FFFDB5FDBFAD7FFF6FFFA9 -:100AC000DED1ADADE9FFF1ECEFDE3FCBFFF6FF325B -:100AD000FFC5BDFFFFFFD0BFFFFFFFFEFEFBFFF422 -:100AE00028BFFFFDFBD3FFFF42FFFFFFEAB3FCC3BC -:100AF000C1FF33FFC0156B70FFF0F24FFFFC3E9754 -:100B00003CFFFFFDEFF0BFFFFFFFFEFFFFFFFE78A2 -:100B1000BFFFFDF3EF55FF7EFFFFFFEAB3FCC3C14C -:100B2000FF33FFC0156FFF0FF0F00FFFFC3D6BC3ED -:100B3000FFFFFEF7F0CFFFFFFFFEFFFFFFFFFCFF11 -:100B4000FF23F87FFF4EFFFFFFFBF917FFF6F1FFD2 -:100B5000CFEFFFFF13DFE62FC7FFFFE7C1FDFFFE6B -:100B6000FFFFFFF04FFFFFFFFEF5FFFFFFFEAEFFB1 -:100B7000FF7F3B3FFC7FFCEFFFFCE27BFFF1FDEDE5 -:100B8000EFFFFF3573FFFFFEFAFFFFFFFEBFFFFF22 -:100B9000FFFAF08FFFFFFFFEF1C000000000000031 -:100BA000000000800000400000000C0401404000F4 -:100BB00000302804000800000001000100000000CF -:100BC00038F00FFFFFFFFEFDBFFFFFFFFFFBFF7FC2 -:100BD000FFFF9FFFFFFFFFFFFFFFFFF1FFDFDFFFD3 -:100BE000FFFFFFEDFFFDFFFFFFFFFFBFBFFFFFC3E5 -:100BF000F03FFFFFFFFEF0BFFDFFBFFFFFFDFFFF68 -:100C0000FFFFFFFD7BFF7FFFBDFFF1EFFFFFFDDF7C -:100C1000FDFBFFFFBFBEFFCD7FFCF7F76FBFD8F036 -:100C2000EFFFFFFFFEF830000000040000A000000E -:100C3000C0000020340000000C810020A42000101F -:100C400008044808004093001000381820C1F03F05 -:100C5000FFFFFFFEFFFBFFFFB9DFFEB3FFFFE7FD76 -:100C6000FFFF3BFF7FFFBFFFC1FFFCFFFF3F77FEA2 -:100C7000FECFFFBFFDBFFFFEEDF2FDF7FFF02FFF40 -:100C8000FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFF75 -:100C9000FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFF72 -:100CA000FFFFFFFFFFFFFFFFFFFFFFFFF0BFFFFFA3 -:100CB000FFFEFFFFFFF3ADCFEF70C9733BDF5B4A71 -:100CC000F6B7FED7F5BCC133CAD6B76EF7FBBDC5C4 -:100CD00024CF6F2F4D2BBA5AFFFFFFF0AFFFFFFF5E -:100CE000FEBFFFFFFFFFF6F6D7FFFFADBDFFFFFF23 -:100CF000EFF77FFC5BB1FDBD756FEF6AFD5BFBDB62 -:100D00003ABF8E9FFFBFFDFF6FFFD06FFFFFFFFE5B -:100D1000FFBBFFF03FFFFFFDFB7FDEFFFF5AD6BFAB -:100D2000D82ABFBFF1E5FFCCC0A970FFF33C3CFD62 -:100D300057FD980300C3FFFFFFF0AFFFFFFFFEFF6B -:100D4000FFFFFF3DBFFFFDFBFFDBFFFF0FFC3FD8B9 -:100D50002ABFBFF1EFFFCCC096BEFFF33FFFFD57A8 -:100D6000FD990FFFC3FFFFFFF04FFFFFFFFEFFFFE7 -:100D7000FFF1E7FFFFF38E7BFFA8FFDF7F8E787325 -:100D8000FFF15162FFFC4BFFF3FF7ECFF9FFFDFF48 -:100D9000FF7FFFE0FFFFFFF04FFFFFFFFEF5FFFFCC -:100DA000FBFDAEFFFCFE6F3FF8FD77AFFE37FE7B2D -:100DB000FFB18CFFEFFDF8E7BFFFF1FE3EF7FE95B8 -:100DC0003EBFFFFFFFFAF0BFFFFFFFFEF1C00000D4 -:100DD0000104000000008002000010001000100854 -:100DE0004180100000081084000C040261000081A2 -:100DF000000000003DF07FFFFFFFFEFDBFFFFFFF93 -:100E0000FFFF7FFFFEFDBFFFFFFFFFFFFFFFFFF1C3 -:100E10007FBFF77FEFFFEFFFF7FDFFFFFD7FFFBE17 -:100E2000DFFFFFD9F0BFFFFFFFFEF0BBFF7FFBFF3F -:100E3000FBFFBFFFF37FFBFDEB7FDFFAFFDEF0ED93 -:100E4000FFB1F7F91FB55BFE7EF7BEFD7F5FB5F71B -:100E5000FFFFD0F04FFFFFFFFEF830010007420117 -:100E6000006A185080000002400101200101241492 -:100E700021100208070800401080580084801810D4 -:100E800040C1F0BFFFFFFFFEFFFFFFF7FFDBB7F33F -:100E9000DF7CF874FFFF6F7D3F7EEC7FC1F5FFCFF5 -:100EA0006F9FF9DFBEE5E7FFD7F3DDFBFFFCFFBF78 -:100EB000FFF0FFFFFFFFFEFFFFFFFFFFFFFFFFFF52 -:100EC000FFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFF40 -:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:100EE000F02FFFFFFFFED7FFFFFFB4CFEF776F7349 -:100EF0003A4A3ACBD4F72ED6BDBDA13BDFD6F7EEAA -:100F0000D335BDFBBDCEEB2B4D2FBBDAFFFFFEB0C3 -:100F10005FFFFFFFFEBFFFFFFFDF5F36AF3FEDB7B5 -:100F2000F5FDF32BEF77FFFBDAB1BDA377697F4FB8 -:100F3000FFDBFA5BFFF2FEFF96FFFFFEDFFFD0AFA5 -:100F4000FFFFFFFEFFFFFFFD8FFD406F9E835A0FE7 -:100F5000FAC3FFFFFCE97FF301D000FEBFCD3FF0F5 -:100F6000EFFCC50C3FFD680BFFFFFFFEDFF0FFFF4E -:100F7000FFFFFEFFBBFFFD85FFD46F9FC35A0FFF2E -:100F8000FFFFFFFCE97FF301F0FBC2BFFC0037EF7E -:100F9000FCCDBC3FFF0CBFFFFFFFFFFFF05FFFFF7B -:100FA000FFFEFFFFFFFFD9F7D1B77E7FF1E4FDFF22 -:100FB000FBFBFF5FFF7FB1BC0F67EBB83FFFE2FFBA -:100FC000E9FFFDE3FF3F9FC2FFFFFFF09FFFFFFF31 -:100FD000FEF57FFFF03FBCFFD5F5CE3FFEFFFE6D77 -:100FE000FFF1BF7BFFF1FDFF4FFF87FFAEFFB1F8C1 -:100FF000FEFFFF7801B9FFFFFFFAF02FFFFFFFFEB2 -:10100000F3C00000000402130200804000901000B2 -:1010100010000200012080121000400800040000AF -:1010200002000140008000003CF0EFFFFFFFFEFDEA -:101030001FFFFFFF7FFFFFFFFF7FFF7FF7DFF7FF50 -:10104000F7FBEBD1FFFFFFFFEFF7FFFFFBFFFEFF1B -:10105000FF7EFFFBFFFFFFDBF0FFFFFFFFFEF0FF68 -:10106000FFB7EBF7DFFFFEF56BE7EDF73EECFF5464 -:10107000EF6FF1F5AF6FF6FDFFDD7BFFEFBF7FFF99 -:10108000FFF7FFF35FF7D0F0CFFFFFFFFEF8300070 -:1010900080400400812C0424000201C802000224C4 -:1010A0000001B442DC4402159002034839100224C6 -:1010B000A0BA000040C1F0BFFFFFFFFEFFFFFFFF2F -:1010C000FEFCF7F0EEB65DFDF5FFDBF77F7FBEFFC0 -:1010D000C1FEBFFAFA5FFFADFFEFFF7FDF7FFEBF0C -:1010E000B794BFFFFFF09FFFFFFFFEFFFFFFFFFF73 -:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10E -:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF -:10111000FFFFFFFFF08FFFFFFFFED7FFFFFBB5FFD5 -:10112000EF7CEB2B525B3BDAD4F33696B5BDF1FB8B -:10113000DAEEF6FED335BDDFADCFEF7ECD6BBBDF94 -:10114000FFFFFDB0EFFFFFFFFEBFFFFFFFD35FF626 -:10115000FFF6FFFDADFDFF7FEFFF6F7FDBF1A5A386 -:101160007F6F6B4FFFDBFBCBFFF6FFF4D7FDBFFEBE -:10117000DFFFD0CFFFFFFFFEFFFFFFF7DFFFFFFF27 -:101180003F7FFCE5FF20FEFFFFDF7FFFF17FFFFEDB -:10119000FFF07C3D4FF3C33FFFFF6FC3FF0FFFFF27 -:1011A000AFF02FFFFFFFFEFFFFFBB7E00FFFFF2BAE -:1011B000FF7DBFFFDFFFFFF89F7FFFF155FFFFFFC0 -:1011C000FD7C3CFFF3C33FFFFFEFC3FFDFFFFFFFEB -:1011D000F09FFFFFFFFEFFFFFFFFEFFFFF9FBF7FBF -:1011E000F919478EE79F3F17FFFC81C17EF3D9F9BC -:1011F00073DFF47FFAFFFFFFFB7F77C7FFFFFFF08E -:101200002FFFFFFFFEF5F7FFFBFFF73FFCBF3E3F61 -:10121000ECFF81AFFE4FF3BBFFF07EFF6FFF87FF58 -:10122000BBFFD5FCFF7FFC6FFFEFE7FFFFFAF03F4E -:10123000FFFFFFFEF3C00000000000000000008080 -:101240000030106020000800012080001000040021 -:101250000000000000020080400008203CF06FFF0A -:10126000FFFFFEF5BFFFFFFEFFFFFFFF7FFE3FFF1B -:10127000FFFFFFFFEFFFFFF1DFDFFFFFFF7FDFFF7C -:10128000FDBDFFFFFFFBDFFFFFFFFF5BF0FFFFFF89 -:10129000FFFEF0BFBFBFFFF7FBFFFEEEFAFFFFFF51 -:1012A0003D3BFFFFFEFBF1FFBF7BFFFFEFFFBFFFFB -:1012B000FFFFFFFFFEFFF7EFFFFBD0F0DFFFFFFFB9 -:1012C000FEF83000000000000B10050100080002CD -:1012D000010100001001C8080000000042020000E7 -:1012E000008002000040248000C1F03FFFFFFFFEAD -:1012F000FFFFFFFFF7FDF7FAEFEEF9FDFFF7FEBF87 -:101300001FFD9EFDD1EFFFF77F9FFFEFFFF6FFFE72 -:10131000FE7BFFBDFF7EFFFFFFF03FFFFFFFFEFFF5 -:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:10133000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFCB -:10134000FFFFFFFFFFFFFFFFF0AFFFFFFFFEFFFF0D -:10135000FFF7FFFFFFFF7FFFFFFFDFFDFFFFDFFF67 -:10136000FF5FF1BFFFFFFFFFFFFFFFFFFFFFFFFF7B -:10137000FFFFFFFFFFFFFFF0DFFFFFFFFEFFEFFFBD -:10138000F7FFFFFFFFFFFFFFFF3FFBFFFFEFFBFD4F -:10139000FFF1FFFFFBFFFFFFFFFFFFFFFFFFFFFF6F -:1013A000FFFFFFFFFFFFF02FFFFFFFFEF7FFFFFF35 -:1013B000FFFFFFFFFDFFFFFFFFFFFF7FFFFFE7FFD7 -:1013C000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B -:1013D000FFFFFFFFFFF0FFFFFFFFFEFFFFFFFFFF2D -:1013E000FFFFFFFFFFFFFFFFFFFFCFFFFBFFFBF153 -:1013F000FFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFF01 -:10140000FFFFFFFFF02FFFFFFFFEFFFFFFFFFFFFCC -:10141000FFFFFFFFFFFFFFFF7BFFFFFF7FFFF1FFEE -:10142000FFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFEC -:10143000FFFFFFF07FFFFFFFFEFFFFFFEFFFFFFF5C -:10144000FFFFFFFFFFFFFFDF57FFFEBFFBF1FFFFC7 -:10145000FDF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 -:10146000D7FFF07FFFFFFFFEFFFFFFF7DBFFDBFD96 -:10147000F6FFF6FF3CBCBCBFDF6FEF2FF13CBFBCFB -:10148000BFDF6FFF6FF7DBFFDBFDF6FFF6FFFFFF50 -:1014900001E2EFFFFFFFFEFFFFFFFFFFFFFFFFFF88 -:1014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C -:0614B000FFFFFFFFFFFF3C -:00000001FF -/* - * - * File yam1k2b5.mcs converted to h format by mcs2h - * - * (C) F6FBB 1998 - * - * Tue Aug 25 20:24:08 1998 - * - */ diff --git a/firmware/yam/9600.bin.ihex b/firmware/yam/9600.bin.ihex deleted file mode 100644 index 817a34be22cc158e7bd824287b0ce22c72e08bda..0000000000000000000000000000000000000000 --- a/firmware/yam/9600.bin.ihex +++ /dev/null @@ -1,342 +0,0 @@ -:10000000FFF200A5ADFFFE9FFFEFFBCBFFDBFEF293 -:10001000FFF6FF9CBFFDBFEF2E3F6FF1FDB4FDBFAC -:10002000FF6FFF6FFF0BFFDBFFF2FFF6FFFFFFFF2E -:10003000F06FFFFFFFFEFFFDDFFFFFFFF7FFFFFF9A -:10004000FBFFFFF7FFFFFFFEFF7FF1FFFEFFBFBFDC -:10005000FFFFFFFFFFF7FFFFFFFEFFFEFFFFFFF0C9 -:10006000EFFFFFFFFEFFFFFFFFFFFFBFFFFFFFF7F9 -:10007000FFFFF7EFFFFFFFFFFFF1FFFFFF7EFFFF37 -:10008000FFFFFFFFDFFFFFFFFFFFFDFFFFFFF0DFD1 -:10009000FFFFFFFEFFFFDFFFFFFFFFFFFFFFFFFF91 -:1000A000FFFFEFFFF3FBFEFFF1FFFDFFFFFFFFFF91 -:1000B000FFFFFFFFFFFFFFFEFFFFFFDFFFF07FFF00 -:1000C000FFFFFEFFFFEFFFFFFFFFFFFFFFFFFFFF51 -:1000D000FFFFDFFFFFFFF7F1FFFFFFDFFFFFFFFF86 -:1000E000FFFFFFFFFFFFFFFEFFFFFFFFF00FFFFF20 -:1000F000FFFEFFFFFFFFFFFFFFFFFFFFFFFF7FFF91 -:10010000FFFFFFFFFFFFF1FFFFFFFFFFFFFFFFF517 -:10011000FFFFFFFFFFFFFFFFFFFFFFF02FFFFFFFCE -:10012000FEFFFFFFFFFFFFFBFFFFFFEFFF7FFFEF84 -:10013000FFEFFF7FEFF1FFEFFF7FFFFFFFFFFFFF0D -:10014000FFFFFFFFFFFEFFFFFFFFF09FFFFFFFFE30 -:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF -:10016000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFAD -:10017000FFFFFFFFFFFFFFFFFFF0BFFFFFFFFEFFDF -:10018000FFFFFFBDFFEF7FEF7FFBDFD35AFED7D628 -:10019000F77FBDF1BB5DD6F7FE96FFBDAFADBFEFFC -:1001A0007F6B7FFBD6FEF7FF10EFFFFFFFFEBEEF7A -:1001B000FFFFDBFFF6FFF6FFFDBFFDBFFF7FFF7F09 -:1001C000DFDBF1FD35FF6FFF6FFFDBFFCBFFF6FFDE -:1001D000F2FDFDBFFFFFFFD0EFFFFFFFFEFFFFFFC0 -:1001E000FFFFFFFFFFFFFFFFFFFF55FFCCC03FFFFB -:1001F000FFF124F0FFFFCFEF3FFFF0FFFFFFFC3FD9 -:10020000FFFFFFFFFFFFF0CFFFFFFFFEFFFFFFFF3E -:10021000FFFFFFFFFFFFFFFFFF55FFCCC03FFFFFCA -:10022000F100F0FFFFCFDFFFFFF0FFFFFFFC3FFF1C -:10023000FFFF7DFFFFF0FFFFFFFFFEFFFFFFFFFF60 -:10024000FFFFFFFFFFFFFFFFDFFE7FDFFFFFFFF18D -:10025000FFCFFFF3FF97FFFF8FE7FFFFFC71FFFF6B -:10026000FFFFFFFFF0EFFFFFFFFEF5FFBFFFFFFF08 -:10027000FFFFFFFFFFFFE3F7EFFFFFFC7BFFF13F17 -:10028000FFEFFFCFE3E3FFFFFFFF3FFFFFFFBFFFF6 -:10029000BFFFDAF07FFFFFFFFEF2C00000000000AA -:1002A000000000000000000000000000000100004D -:1002B000000000000000000100000200000000003B -:1002C000013CF0AFFFFFFFFEFDBFFFFFFFFFFFFFA1 -:1002D000FFFFFFFFFFDBFFFFFFFFFFFFF1FF9FFFC0 -:1002E000FFFFF7FFEFFFFFFFFFFFFFFFFFFFFFFF36 -:1002F000DBF07FFFFFFFFEF0BBDFFFFFFFFFFFFF35 -:10030000FFFFFFFFFFFFFFEFFBDFBFF1FEFDF7FF8A -:10031000FFFFFFFFFEFFFFFFFFFFFFFFFF77FDF285 -:10032000F01FFFFFFFFEF838000000000000000390 -:100330000000000200900000000C010000042400F6 -:100340004001000000400000000002000001C0F079 -:100350004FFFFFFFFEFFFFFFFFFFFFFFFFFFFFFF5E -:10036000FFFFBFFFFF6FFFDFFFD1FFFEFFFFFFFFBC -:10037000FFFFDFFFFBFFFBEFFFFFEEFFFF7FF0DF85 -:10038000FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7E -:10039000FFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFF7B -:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFF08FFFDC -:1003B000FFFFFEFFFFFFF5ADFF692AED6BFBDF3AA4 -:1003C000DCF496EEB33D35C1BBDDFEF6FED6B5AD31 -:1003D000BFA5AD492F4F2BDA5FFFFFFFF02FFFFFC7 -:1003E000FFFEBFFFFFFB5BF7F6FFF6FFFDBFFDA5BE -:1003F000F36FF36EFA7BD1FDB5776FE96FFFDBFB2F -:10040000DBDFF6FFF6FFFD3FFEF7FFD04FFFFFFFFC -:10041000FEFF9FFFFF0FFFC03F9C03FFFF8BA5FE6A -:10042000803EC2BFACB124FFFFFFFFFFFF0FFFA361 -:10043000FFFD6BFFFFF0A5FFFFFFF0AFFFFFFFFE2B -:10044000FFFFFFFF0FFFC03FD46BFFFFDBFFFE8608 -:10045000BFC2BF30A124FFFFFFFFCCFF0FFFA3FFF0 -:10046000056BFFFFF0A5FFFFFFF07FFFFFFFFEFF23 -:10047000FFFFFBC7FFC4FFFF7FFFECFE7FDFD8B9A4 -:1004800047FC36C1DFFFFFF9FFF3FFF7FFFCFFFD7D -:100490003FFFFFFF3FFFFFFFF07FFFFFFFFEF5FF86 -:1004A000FFFFFFFEFFFF7EBD3FFF2BFE2FF5A3FCEE -:1004B0005BFE619F7FEFFFFFA7FBFFFFFAFEFF33AD -:1004C000F1FFBFFFFFFFFAF07FFFFFFFFEF1C0006B -:1004D0000000000000000000000000400030240484 -:1004E000000100804000080000000201010002003D -:1004F00000000000013DF02FFFFFFFFEFDBDFFFDEE -:10050000FFFFFFFFFFFBFFFF7FF6EFBFF7FF73EB80 -:10051000F1FFFFFFDFFFFFFFFFFFF9FFFDFEFFFF22 -:10052000FFFFFFFFD9F0DFFFFFFFFEF0BF7FFFFF00 -:10053000FF7FFFFFDEFFFFEFDDDE77F2FBEDE7F190 -:1005400073FDFDDFFF7DBEDFFFFBFFEFFFEFFFFF72 -:10055000FFFFFFD0F0BFFFFFFFFEF83020020022B8 -:1005600040C0000000080002410212002187810003 -:100570000080040B2801B000820040000000000051 -:100580000000C1F0DFFFFFFFFEFFFFFFFFFFFDFFE9 -:10059000F7FFFE7FED79FFDEEB7F74F7F7E1F9FF00 -:1005A000F65F7FFFFFFFD7DBEFFFBBFFFFFFCCFF57 -:1005B000FFFFF0CFFFFFFFFEFFFFFFFFFFFFFFFF8B -:1005C000FFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFF49 -:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B -:1005E000FFF00FFFFFFFFEFFFFFFFD3DCD497F6FD7 -:1005F0002BBA5CD2DAF6F33EF7FFBDF1FADFFEF775 -:10060000CCF6BBA5B3ADBF6F7D6F6BDBDFBDFFFE6F -:10061000B05FFFFFFFFEBFFFFFFBDB57F6FE9FD57E -:10062000B7FFAFE53FFFFF6FFFDBF1FDBFFF6F6976 -:100630006CDFDADFCBFFF6FF76FDFDBFFFFFFFD0FB -:100640003FFFFFFFFEFFFFFFFFFDBD0803894F5A7D -:100650000FF0FFF8BFFFFFFFFFF15AFFFFFFFFF3AF -:10066000FAA0F0F2BFFFFFFFFFFFFFFFFFFFF0FF69 -:10067000FFFFFFFEFFFFFFFFFCFD006BFFFF5A0FB8 -:10068000F0FFFFFFFFFFFFFFF15AFFFFFFFFB3F592 -:1006900050F0F0FFFFFFD7FFFFFFFFFFFFF07FFFEE -:1006A000FFFFFEFFFFFFFDBCFFE4E771FFF9C4F4AD -:1006B0007F7FCFFFFFFFFFF1FFFFFFFBF773BF144B -:1006C000FFE6FFFFE17DFFFFE7FFFFFFF03FFFFFDA -:1006D000FFFEF5FFFFFED2FAFFC4F45CBFFAFFFF96 -:1006E000EC7EBFFFFFFFF1FFFFEFFFFF6BDBFFDFE4 -:1006F000F9FBBFFFF1FFBFFFFFFFFBF0BFFFFFFFF5 -:10070000FEF3C00002000000008200000000800034 -:10071000000000400001000000010820000000006F -:100720000100010000800200013CF05FFFFFFFFEBE -:10073000FDBFFFFFFFDFFFFFFFFF7FFFDFFFEFFFDB -:10074000FFFFFFFFF1FFFFFFFFFFF7FFFBFFFDFFD5 -:10075000FFFFFFFFFFFDFFFFC3F0AFFFFFFFFEF056 -:10076000FFDFFFFFF723FFFFFDFFEFFFFE7F7DF7BA -:10077000FEFF7F71FFFB7FFFFFFF6EFDF7FDFFBFF9 -:10078000FFBFF9FDFFDFEFF0F0AFFFFFFFFEF83036 -:10079000400100830000000C060804262600000625 -:1007A0000300010000000004007008800020012008 -:1007B000000200300000C1F05FFFFFFFFEFFFFFFFF -:1007C000FFFF7B3FF7FFD7FEFEFBFE3BFEBDFF2F8B -:1007D000FF71FFFB7FE7FFF9EFFFD7FAFFB7BBFE23 -:1007E000FFFF74FFF7FFF0CFFFFFFFFEFFFFFFFFEC -:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 -:10080000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 -:10081000FFFFFFFFFFF08FFFFFFFFEFFFFFFFFB5B2 -:10082000BD6F7CEB7FFBDBD34BEED6F6B7FDACA107 -:10083000FBDFFEF7F496BDB4C5A5AF6F694F7FBA75 -:10084000DBFFFFFFF03FFFFFFFFEBFFFFFFFDBFF10 -:10085000F6FFF6FFBDBFA5BFFF7D7FEFFFFBF1FDFC -:10086000BFFF6FFF6B7ADBFFDBDFF6FEB6FDFDBF80 -:10087000FEF7FFD0EFFFFFFFFEFFFFFFFFF42FFFAC -:10088000FC436BFFFFFF0DFFFC333FF05FF1FFFF09 -:10089000FFFFF9DEF04CFE77AFFFFFEFFFF0FFDB6D -:1008A000FF5FF0EFFFFFFFFEFFFEF7FFF02FFFFD02 -:1008B000437FFFFFF10FFFFC333FFFAFF1FFFFFF6F -:1008C000FFF6D7FFBCFDBDFFFFFFFFFFF0FFFFFFFF -:1008D000FFF0EFFFFFFFFEFFFFFFFFFCFFFFFBF15D -:1008E000BFFFF9FDCFF270FF1F9FF3F1FFFFFFFF86 -:1008F000FCF7FF139FFCFFFF84F7FFFF47FFFFFF9D -:10090000F0BFFFFFFFFEF5FFFFFFF1FCFFFEFE79EA -:100910003FFF1D46CFFFCFFC7BFFF1FFFFFFFFED49 -:10092000F3ABFFCBFFF8FFFCF5FFBFFFFFFFFAF0D3 -:100930008FFFFFFFFEF3C200000000000000010077 -:10094000000020002000000408010000000000203A -:100950000C0000040100010000800000013CF07F59 -:10096000FFFFFFFEFDBFFFFFFDFEFFFFFFFFFEFFDE -:10097000DFFFFFF7FFFFFFEFF1FFFFFFFFFFFFEBE1 -:10098000FFDFFFFFFBF77FFFFEFFFFBFDBF0FFFF97 -:10099000FFFFFEF0FFFFFFFFFFDFFFFFFF7FF7FF1F -:1009A000BFBFCFFFFFFF3EF17FFFFFEFFFFFFFFE67 -:1009B000FFFDFFBFBDFEFFFBF7DFFBD0F09FFFFF9A -:1009C000FFFEF8302000400180C030000020001001 -:1009D00050882000001301000000000000100000FB -:1009E00000000180080000A00010C1F0EFFFFFFF31 -:1009F000FEFDEF7FFFFFBFFFF7FFEFFBFD77EFBFD0 -:100A0000F77FFFFFBFD17FFFFFF7FFFFFFFFAFFFC4 -:100A1000DFF7FBFFFDFFFCFFFDFFF0FFFFFFFFFE29 -:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 -:100A3000FFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFD4 -:100A4000FFFFFFFFFFFFFFFFFFF05FFFFFFFFEFF66 -:100A5000FFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFC6 -:100A6000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFA4 -:100A7000FFFFFFFFFFFFFFFFE03FFFFFFFFEDDFF88 -:100A8000FFFFA5FD6F7D6D7F52DF5A4BEEB6EEF294 -:100A9000BBACA15B4DD6F7FEB2BD35B5B5DD6F7F02 -:100AA000E95F52DFBDFFFFF0DFFFFFFFFEBFFFFF8B -:100AB000FFDBFEF6FFF6FFFDBFFDB5BFF97F6FFF61 -:100AC000DBF1FDBFFF6FFF697FDBFFD3FFF6FEF2B7 -:100AD000FFADBFFFFFFFD0DFFFFFFFFEFFFFFFF512 -:100AE000300FFFFFFD6BCAFFF00FD6BFCF3FFFFFF8 -:100AF000F1FFFFFFCAFEBFFFF005AF0FFFFCF0CF15 -:100B0000F0FFFFFFFFF0EFFFFFFFFEFFFFFFF530FD -:100B10000FFFFFFC3FCAFF0F0FD6BFFFFFF55FF1CE -:100B2000FF8BFFC3FFFFFFFFFFFF0FFFFCF0CFF0C6 -:100B3000FFFFFFFFF03FFFFFFFFEFFFFFFFFCFFFC5 -:100B4000FFBF9F3FFEFCFF4FFFFFFFFFFFF7F1FFDF -:100B5000DFFE7E3F9FF4FC7FFCFFFF3FFF3FFE3F39 -:100B6000FFFFFFF04FFFFFFFFEF5FFFFFBFFFEFF64 -:100B7000FFFFFFBFFBFFF8EDFF8FFFBBFFB1F3EF00 -:100B80008FF7FFFFDBFFFFFFEFBFFD79BFBFFFFF69 -:100B9000FFFBF0DFFFFFFFFEF3C0000000040000DA -:100BA000000000000000008000040808010100901F -:100BB000000000040008000000000800040000011C -:100BC0003CF0DFFFFFFFFEFDBFFFFFFFFFFFFFFF6A -:100BD000FFFFFFFF9FFFAFDFFFFFFFF1FFFFFFFF03 -:100BE000BFEFFFFFFFEDFFFFFFEFFFBFFFFFFFC303 -:100BF000F03FFFFFFFFEF0FFFDFFFFFFFBFFBBFF2E -:100C0000FFFF7FF6FF7FFBFDEDFFF1FFFE7FFFFFA4 -:100C1000FF5FFFF7FF7EFFFDFFEFFFFFFFEFF0F04D -:100C20008FFFFFFFFEF83080000400004002000349 -:100C300000050420000001D0008100200404000011 -:100C4000810408801000C0000000200008C1F06F7F -:100C5000FFFFFFFEFFFF7FFFFFFFFFF3FDFFEDFC48 -:100C6000FFFF9FFBFDFFFFFFF1FFFF7FFB3EFF9FAD -:100C7000FFFFFFFFFDF9FFFFFFFDFFFFFFF06FFF2D -:100C8000FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFF75 -:100C9000FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFF72 -:100CA000FFFFFFFFFFFFFFFFFFFFFFFFF0CFFFFF93 -:100CB000FFFEFFFFFFFDBDFFEF7CEB7FFBDBFADC00 -:100CC000EEF7F6D7F52DA1BBDDEEF754F7FB2CB50B -:100CD000B4BD6B6FEF6FBBDFFFFFFFF01FFFFFFFC8 -:100CE000FEBFFFFFFFFBFFF6FFF6FFFDBFFFBFEFFD -:100CF0006FFF6FFADBF1C5BDF56FFF6FCADBFFDB7E -:100D0000FBF697F6FFFDBFFEF7FFD09FFFFFFFFE4C -:100D1000FFFFFFFFFFFFFFFF8B7FFFFFE763FFFF8B -:100D2000FFFC77DFF1DBFFD6A83FFFFF082FF0FFC6 -:100D3000C3FFEBFFFFFFFFFF5FF0EFFFFFFFFEFFD3 -:100D4000FFFFFFFFFFFFFF8BFFFFFFFFFFFFFFFF27 -:100D5000FCFFCFF1DBFFD6A83FFFFF082FF0FFC35A -:100D6000FFEBFFFFFFFFFFFFF05FFFFFFFFEFFFF57 -:100D7000FFFFFFFFFFFFF5BFFFCAFF9FFFFAB9E7C5 -:100D80009FF381FFFFFC73D7FFFF77FFFDFFFCFFA1 -:100D9000FFFFFFCFFFFFFFF01FFFFFFFFEF5FFFF8D -:100DA000FFF7DEFFFE7EFFBFFFBFF1B3FFFFE3FBF8 -:100DB000FFE11F7FFFF878FFFB1EFFF7FEE7FFFF55 -:100DC000FFBFFFFFFFFAF04FFFFFFFFEF3C0000081 -:100DD00000000000000000000000500000000400BF -:100DE00001804040200000080000000003000000D7 -:100DF000800000013CF0AFFFFFFFFEFDBFFFFBFFE7 -:100E0000FFFFFFFFFFFEFFFFFFFFFFFFFFEFF7F119 -:100E1000FDFFFFFFDFFFEFFFFFFFFFFFFFFF7FFF94 -:100E2000FFFFFFDBF08FFFFFFFFEF0FFDFFFFF7F25 -:100E3000FFFFFFBED7FFEDBD7EBFFEF67FBF71FF98 -:100E4000FFDAFFF9FFBF7FFEFF6F7FFFFFFFFFFFAE -:100E50007FFFD0F0CFFFFFFFFEF830420000000020 -:100E600080C100009000C400001220432281840051 -:100E700000140001000880000200020004020000CB -:100E800010C1F01FFFFFFFFEFFFFFDFFFFDDFEFFB4 -:100E9000B676E5BCF9F7AF5FBFFCDFCFF1FFEF79C6 -:100EA000FFBDFFEFFFFFF76F5FFFFFFDEFEFBFFF3E -:100EB000FFF09FFFFFFFFEFFFFFFFFFFFFFFFFFFB2 -:100EC000FFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFF40 -:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:100EE000F0FFFFFFFFFEDBFFFFFD2DFF692AEF771D -:100EF000BBDD5ADFF6F6D6F77DBDD1B24AD6B2BE1B -:100F000097F5BDB3ADFFEF7F696BFBDFFFFFFFF030 -:100F10002FFFFFFFFEBFFFFFFFDBFFF6FE9FD4BFEB -:100F2000EDAFFF6B6FF7FFDDDB31FDBFFF6F7FFFC5 -:100F3000FFDBFFCBDFF6FFF6FFFDBFFEF7FFD08F35 -:100F4000FFFFFFFEFFFFFFFD1FFF462F9FFFFFFF7D -:100F5000A5FFFFFFDFB7FFFFF1FFFFFFF7E96ABF64 -:100F6000FFFFFDFFFFFD5557FFFFFFFFAFF04FFFF6 -:100F7000FFFFFEFEDFFFFD1FFF462F9FFFFFFFA5C8 -:100F8000FFFFFFC037FFFFF1998EDC7FE96ABFFFEB -:100F9000F00FFFFFFD5557FFFFFFFFFFF00FFFFFB3 -:100FA000FFFEFFFFFFFF07FFC0BEFFFFCFEF9FFF6A -:100FB000FFFBFFE7FFFFA1E3CE3C583FF3FFFDEF50 -:100FC000F9FFFFF7F17FFFCBFFFFFFF02FFFFFFFE0 -:100FD000FEF57FFFF0FFFEFFC475E7B9FFFFFFEFEF -:100FE000FFC7373BFFF0139E0FF4FFFEFBFFFFF937 -:100FF000FCFFFFFFFFBFFFFFFFFAF0EFFFFFFFFE69 -:10100000F3C0010000020002220000C040004000C6 -:101010000408040A0101102020000004080804004C -:1010200000000000010000013CF0CFFFFFFFFEFDCB -:101030003FFFFFFFFFFFFF7FFF7FFF7FFFCF9DFF92 -:10104000FFF7FDF1FFFFFFEEBFFFFFFFFFFEFFFF1A -:10105000FFFFFFFFFFFFFFDBF06FFFFFFFFEF0FF73 -:10106000FFFFF7F7FFFFFEBFF7FFFF5BFFBFF7FFD5 -:10107000FD7F71FDFFEDF7FEEFFFFF7FFFFFFFFF3D -:10108000FFFFEFFF7FFFD0F0FFFFFFFFFEF8301103 -:10109000004860408260246000CC008004010000B1 -:1010A00014010C0400300000000808000100C20018 -:1010B0000002008000C1F05FFFFFFFFEFFFFFFFFA7 -:1010C000F77BFFF3EBBFFFF7FFFFFFE75D3FFFF6A7 -:1010D000D1FDFFEBF73DFFFFFF5FFF7F7FF3FFFFDA -:1010E000EFFDBFFFFFF05FFFFFFFFEFFFFFFFFFF12 -:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10E -:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF -:10111000FFFFFFFFF0DFFFFFFFFEFFFFFFF5B5DF83 -:101120006F7D697FFBDF525FF6F7FEF6F3BDB1DA44 -:10113000CDFEF6EED2BDA5AFBDFF6F7CEB2BFADA8C -:10114000FFFEDFF04FFFFFFFFEBFFFFFFFDBFFF6FD -:10115000FFF6FFBDBFCDBFEB6FF76FDFDB51FDBD0E -:10116000FF6FFF6FFB5BFFDBFFF6FEF6FDFDBFFED3 -:10117000F7FFD0FFFFFFFFFEFFFFFFFA50FFFFFF6B -:10118000F06FFFFFF096FFFFC62BFFFFF1FCFFFFA4 -:10119000F7DBC3FF00FFFFFFFFFFC14FC3FFFFFFF0 -:1011A000AFF09FFFFFFFFEFFFFFFF5A0FFFFFFF087 -:1011B0006FFFFFF096FFFFC62BFFFFF15AFFFFFF07 -:1011C000F3C3FF00FFFFFFFFFFC14FC3FFFFFFFFA0 -:1011D000F0CFFFFFFFFEFFFFFFFFFCFFFF9FF07F51 -:1011E000FFF9FC4FF3FF27EBFFFC81FC7FFE7BFF49 -:1011F000F7FF127FFFFFFFFF18FFFFFFFFFFFFF06A -:101200007FFFFFFFFEF5FFFFFFDFFEFFFC7E7FBFDE -:10121000FFFFAFEFFFDFDFFBFFF1C3FE6FF1CF3F5B -:10122000FBFFFFCFFEFFFFFE7FBFFFFFBFFAF0DF38 -:10123000FFFFFFFEF3C000000100000000010000FE -:10124000200001001000000001000200000000006A -:101250000000000200008000028000023CF02FFF2E -:10126000FFFFFEFDBFFFFBFDFFFFFFFFFFFFFFFFD7 -:10127000FFFFFFFFFFFFF5F1FF7FFFFFFFFFEFFF26 -:10128000FFFFFFFFFEFFFFFFFFFFFFDBF02FFFFF72 -:10129000FFFEF0FFFFFFFBFFBFFFFFFFFFF7BFFBFE -:1012A000FFFFFFDFF7FFF1F7BFFBFFFFFF7FDEFF71 -:1012B000FFFFFFFFFFEDF7FFFF7FD0F03FFFFFFFD6 -:1012C000FEF830000000004000000000E000008058 -:1012D0002001019200010100E01C6020300808009C -:1012E000000000000000008000C1F06FFFFFFFFE63 -:1012F000FFFFFFFFFFDBFEFFFFDFFFFC7FFBBFFF0A -:10130000FFFFFFFFF1F6FFF77E3FFF7FFFFFFFF7D5 -:10131000FFFFFFEDFFDFFFB7FFF03FFFFFFFFEFF27 -:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:10133000FFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFCB -:10134000FFFFFFFFFFFFFFFFF0FFFFFFFFFEFFFFBD -:10135000FFFFFFFFDFFFFFFFDFFFFFFFFFBFFFDF3D -:1013600057EFF1FDFE7FFFFFFFFFFFFFFFDFFBFFFA -:10137000FFFFFFFFFFFFFFF07FFFFFFFFEFFFFFF0D -:10138000FFFFFF7FFFFFFFFFFFFFFFFFFBFFDFFF11 -:10139000FFF1FDFF7FBFFFFFFFFFFFFFFFFFFFFF2D -:1013A000FFFEFFFFFFFFF09FFFFFFFFEF7FDFFFFC8 -:1013B000FFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFF7D -:1013C000F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B -:1013D000FFFFFFFFFFF06FFFFFFFFEFFFFFFFFFFBD -:1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11B -:1013F000FFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF -:10140000FFFFFFFFF0CFFFFFFFFEFFFFFFFFFFFF2C -:10141000FFFBFFFFFFFEFFFFFB6FFFFEBFFFF1FFC4 -:10142000F7FFFF7FFFFFFFFFFFFFFFFFFFFFFFFD56 -:10143000FFFFFFF0EFFFFFFFFEFFFFFFFFFFFFFFDC -:10144000FBFFFFFFFEFFFFFF57FFFDBFFFF1FFEFB9 -:10145000FEFFBFFFFFFFFFFFFFFFFFFFFFFFFEFFDE -:10146000DEFFF0CFFFFFFFFEFFFFFFF7DBFFDBFD3F -:10147000F6FFF6FF3CBCBCBFDF6FE72FF13CBFFDC2 -:10148000BFDF6FFF6FF7DBFFDBFDF6FFF6FFFFFF50 -:101490000201DFFFFFFFFEFFFFFFFFFFFFFFFFFF78 -:1014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C -:0614B000FFFFFFFFFFFF3C -:00000001FF -/* - * - * File yam111.mcs converted to h format by mcs2h - * - * (C) F6FBB 1998 - * - * Tue Aug 25 20:23:03 1998 - * - */ diff --git a/firmware/yamaha/ds1_ctrl.fw.ihex b/firmware/yamaha/ds1_ctrl.fw.ihex deleted file mode 100644 index aa9b1d7dcb0bed182f3f94d68a1235828995f9c9..0000000000000000000000000000000000000000 --- a/firmware/yamaha/ds1_ctrl.fw.ihex +++ /dev/null @@ -1,769 +0,0 @@ -:10000000070000000700240007000C0007001C0088 -:1000100007000600020070002000000040000300FE -:100020000471000086420000400003000D0F000034 -:10003000100800003A042000820200000D020000B7 -:10004000100800003A04200082120000820E2000F6 -:10005000821A00000D2D0300100800003A04100061 -:100060008DD30200100800003A0418000D010000B2 -:1000700015000200FD000000200000006088030061 -:100080006090030060800300408003004080030014 -:1000900040800300408001007D0A00004080030092 -:1000A000408003004080010002042000820800001C -:1000B0001A0008000409000086590100070000002A -:1000C000070026000700000007000000068A010064 -:1000D000070000008D0C0300100800003A0418000F -:1000E000070026007D080000428001000A1600007B -:1000F00006A20400070000008D2100001008000087 -:100100003A04080006C2210007000000FD070000B5 -:10011000428001000A0008000409000086930200E2 -:1001200095010000040D09000700000020080000F0 -:10013000F50000007D0B000060F00100FD000000F4 -:1001400006220300408001007D0A00004280030077 -:100150004A8013000A001800201800006090050073 -:100160006088050040800100FD0000004280010021 -:100170000A007000150100004411070086230300E7 -:100180000000030020700000064A030040800100C8 -:100190008D340000100800003A04080006EA21002F -:1001A000070000008DD30200100800003A04180078 -:1001B0000682010007000000070024008D0F0000E8 -:1001C000100800003A16000002240000025C000043 -:1001D000FD28000020000000408001000D00080004 -:1001E0001508000084095100070000004D000000C0 -:1001F0005D0E0000020E00008D410000100800009E -:100200003A040800068A2C00070000008D00000058 -:1002100024090000020F00008D45000010080000B6 -:100220003A040800068A2C00070000007D38000010 -:10023000428001000A000800151000008409010036 -:10024000868301000700000006AA010007000000E5 -:10025000FD080000428001000A0018000419000097 -:100260008680210007002800101800003A042800AA -:10027000020C28000D000000100800003A142800AD -:100280008D80080020080000FD0200004080010071 -:10029000070020000D02000004991800070000006C -:1002A0002D400000BD000000FD0200004280010062 -:1002B0000A00080004090000865A05000700000033 -:1002C00000010000200A00007D04000040800100C1 -:1002D000428001000A002000153000004421010086 -:1002E000864903000700000004210000864903003E -:1002F000070000008D0F0000100800003A0C2800D5 -:100300004439020086C906000700000010180000EA -:100310003A0428000D81080020080000FD020000BA -:100320004080010007002000102800003A007800FB -:100330008D680000100800003A040800068A2800B2 -:10034000070000000D40000015100000049918007F -:1003500004292900043939000700000006020600BC -:1003600007000000F50400007D00000020000000F0 -:100370008D00000060080100408001007D04000045 -:10038000428003004A8021000A001800441902003C -:1003900086582100070000007540000004F171003C -:1003A00007000000420001000A00280004290000A4 -:1003B00086202100070000000D3C000004A9300049 -:1003C000070000007D070000428001000A000800CD -:1003D0000409000086DA07007D05000020280000DF -:1003E00060B0030006F207004080010020300000EA -:1003F00060A8030040800100FD020000428001006F -:100400000A0008000409000086FA0700070000003F -:100410007D050000428001000A0428008D0E0000C6 -:10042000100800003A0C28000D0000001008000021 -:100430003A1428000D00090020080000FD02000009 -:100440004080010007002000FD3D0000200000006A -:10045000408001007D1000008D8D0000100800001C -:100460003A040800068A280007000000150800006A -:100470001A00080084090100865109007D1300005C -:1004800000052000200F2800608F3300608F3B00A4 -:10049000608F4300608F4B00608F5300608F5B0064 -:1004A000608A030040800100BD7F0000C43D380029 -:1004B000070000007D1A0000751300004280010053 -:1004C0004A0009000A001000048D0B000495130077 -:1004D00007000000200800006090010004110000E7 -:1004E0008620210040000100FD170000428001002D -:1004F0000A0008000409000086222100070000000D -:100500007D190000428003004A8009000A001000A3 -:100510002409000064160000FD1100004280030061 -:100520004A802B004A8019008D0000004489210078 -:10053000070000004422000086E10A0007000000D6 -:10054000641A0000242A00007D190000020108003E -:10055000220110002008000060900300408001008C -:10056000FD3D00008D0000002008000040800100DB -:10057000751300007D1A0000420001004A80090046 -:100580000A0010001D020000E4890100E492290025 -:1005900044913000070000000D060000150A00001D -:1005A0001D0C000025100000E4A90000E42B010050 -:1005B00064040000E4B30100E432020064040000BB -:1005C0006404000064040000640400000D040000E2 -:1005D000C4B108000700000020080000F50B00006F -:1005E000400003007D190000428003004A8009009A -:1005F000240A00000A000800640E0800070000003A -:1006000022011000200800006010030040000100DB -:10061000AC6400007D02000020000000408001006A -:100620007D10000042800100FD1100004A803B0067 -:100630004A8009000A0020009500000044111A00B9 -:1006400044A1000086200D000D04000084B90000C4 -:1006500086210D00FD18000042800100FD10000001 -:100660004A8009000A0028009500000024090100C2 -:10067000642A000086110D00070000000429000014 -:1006800086220D0007000000062A0D000200080067 -:100690008D0000007D38000020080000408001002F -:1006A0007D120000428001000A00100004390000A1 -:1006B00086D10D000D080000B5FF7F0084B9000051 -:1006C00086A10D0025000000067A0E002D00000016 -:1006D000150000002D0800008DC702002008000052 -:1006E00006C20E000D00000035807F0084B90000B6 -:1006F00086710E00250040008D00000044091100A5 -:10070000070000008D0100000495100007000000A4 -:10071000649100002404000024040000240400006C -:1007200002011000020028008DC60200200800000F -:1007300006C20E008D0100002D0400008D00000097 -:1007400004951000070000000D02000084911000C5 -:10075000070000000DC70200200800008D00000007 -:10076000FD38000040800100FD3B0000201000002B -:1007700060A80300150800008431310084212100A5 -:100780000700000060B0030060A00300408001008B -:10079000FD2200009500000024090100240400004F -:1007A0002404000064120000020110002008000070 -:1007B0006090030040800100241900008DFB0000C0 -:1007C0007D390000200800004080050042800300C1 -:1007D0004A840900060600000A04080024040000F8 -:1007E000240400007D110000428001000A0008007E -:1007F000240A000002052800020C28000D800900D0 -:1008000020080000FD0200004080010007002000D9 -:10081000FD220000428001000A000800950000004F -:10082000C40D2800241901007D1900004280010038 -:10083000FD1100004A8009000A001000B500000008 -:1008400044311100048D0A0007000000440A08002A -:100850000495120007000000FD2300002010000096 -:100860004080030044121000070000002008000030 -:100870006090030040800100FD0200004280010002 -:100880000A0008000409000086FA100007000000B2 -:10089000FD3B000000010000100A00007A800B0000 -:1008A0004A80130084090900070000009500000039 -:1008B000043D0100868011000A00100002001000B3 -:1008C0008409090007000000428003004A801100EB -:1008D000040D0900070000000A001000840D090043 -:1008E000070000007D250000200800004080010076 -:1008F0000D010000100800003A1428007D120000CD -:10090000428001000A0020007D19000042800100A1 -:100910007D1100004A8031000A00100024310000DF -:100920000D2801007D3900002008000040800500EE -:10093000428003004A840900060600000A040800F9 -:1009400002013000243100002404000024040000CF -:1009500024120000020528004C1A00008601130032 -:10096000020070002D000000000003007D38000030 -:10097000428001000A001000062A13002421000012 -:10098000AD000000020010000D010000240900006D -:10099000246B00008D3601007D3900002008000026 -:1009A00040800500428003004A84090006060000DA -:1009B0000A040800643200008D000000240A0000D0 -:1009C000201000007D220000408001000D3C01004D -:1009D000100800003A04080006D2290007000000B1 -:1009E000202800007D200000408001007D110000D3 -:1009F000428003004A8013000A8033007D380000E3 -:100A0000428001000A00080004090000863A16002E -:100A1000070000008D000000640903008D470100FD -:100A20007D3900002008000040800500428003005E -:100A30004A840900060600000A0408000201380082 -:100A4000240400002404000024120000FD02000021 -:100A5000428001000A0008000409000086A2140078 -:100A600007000000020528004C1A00008639160015 -:100A700007000000642103002C630000FD3D00001E -:100A8000428001000A0008009500000004090900E6 -:100A900007000000200800004C1A000086611500C5 -:100AA0004080010000000300067A150024210000A8 -:100AB0000D01000024090000246B00008D5B010083 -:100AC0007D390000200800004080050042800300BE -:100AD0004A840900060600000A040800643A00007F -:100AE0009500000024120000FD0200004280010079 -:100AF0000A0008000409000086DA1500070000005B -:100B00008D620100100800003A04080006D2290096 -:100B10000700000006D2140007000000207000004B -:100B20000A0108002A011000FD200000608803006F -:100B300060900300408001007D220000428001009F -:100B4000FD3D00000A0008004A843100040900004D -:100B500086D816008B0018008D000000049918003C -:100B60002C31000006AA1700070000004C320000DC -:100B700086331700070000000419000086301700B4 -:100B80000700000095000000449119002C2200008D -:100B9000243100006C6300003D0E0000751300005E -:100BA000FD0B0000420001004A8009000A0010000D -:100BB000EC8A0300EC9303004C22000086A9170086 -:100BC000070000008D000000049918006C2200004E -:100BD0002C3200000A053000AB1D300083200000DD -:100BE000FD180000428001000A000800248901006D -:100BF000020530008310000075180000420001005B -:100C00000A0010008D000000240901007513000087 -:100C100042053300CB0C3300CB2C3300CB343300F4 -:100C2000CB3C3300CB443300CB4C3300CB543300AC -:100C30008B5C300083600000F50200004200010080 -:100C40000A00080004090000867A18000700000066 -:100C50002D1E0000FD050000428001000A00080072 -:100C600024890200020528000D060000100800007B -:100C70003A0C28008D000000100800003A142800EB -:100C80008D800A0020080000F502000040000100ED -:100C90000700220075120000420003004A002100F4 -:100CA0008D00000044091A00070000000D980100A3 -:100CB000100800003A04080006222B00070000007C -:100CC000F5010000420003004A000D000A00100078 -:100CD00044910800070000002008000040000100C7 -:100CE000F525000044310A0007000000200800003C -:100CF00060280300400003007D21000042800300C3 -:100D00004A800B000A001000200800006010030059 -:100D1000400003008D000000240100002C010000B1 -:100D2000640E0000641A00006C6300000A010800F1 -:100D30002A0110002008000060100300400003009A -:100D4000FD200000428001000A0008007D22000012 -:100D5000428001000A00100020080000601003001B -:100D6000400003007D190000428001000A000800D5 -:100D7000FD220000428003000A001000200800004D -:100D80006010030040000300040D0900070000008C -:100D90002008000040000300428003004A800B004E -:100DA0000A0010002008000060100300400003004B -:100DB000428003004A8013004A801900040D11008C -:100DC000048D1900070000000A0008002010000030 -:100DD0006018030060080300400003008D0000005D -:100DE00044090B000700000020080000400001003B -:100DF000F5050000420003000A000800200800007A -:100E000040000100F5000000420001000A00080057 -:100E10000409000086601C00751E000042000300EB -:100E20004A0401000A0C000006721C0007000000C2 -:100E300002040000020C00007D170000F51A0000FB -:100E4000428001004A1403004A1C03004A240300A4 -:100E50004A2C03004A3403004A3C03004A4403007E -:100E60000A4C00003D040000F5130000FD1A0000CC -:100E7000420003004A000B004A801B004A80130016 -:100E80000A0020004491080044A11900E4890300ED -:100E9000EC990300025500000A5D000042000300C7 -:100EA0004A000B004A801B004A8013000A00200001 -:100EB0004491080044A11900E4890300EC9903005F -:100EC000026500000A6D0000420003004A000B00AA -:100ED0004A0019004A802B004A8013004A802100F2 -:100EE0000A0030004491080044A1190044B12A00CE -:100EF000E4890300EC990300027500000A7D0000FC -:100F0000E4A90300020700007D10000015040000A2 -:100F1000428001000A000800E4090100020F0000FD -:100F2000F52A0000FD190000420001004A80090076 -:100F30000A0010003409000074160000F5290000B2 -:100F4000420001000A0010007C91000075200000A2 -:100F5000420001000A0008000409000086D21E00B9 -:100F6000F5260000F5270000420003004A000900B2 -:100F70000A0010003C0A00007C160000751A0000F0 -:100F8000FD0B0000420001004A8051000A004800A9 -:100F90000700160075100000420001000A2C28000E -:100FA000121D280012252800321F000007001E0015 -:100FB00007000E007519000042000100F52D000029 -:100FC0004A000D000A0010004491000086B21F0084 -:100FD000420001000A3428005D0E00008D00000070 -:100FE000750300002008000040000100F4D2050055 -:100FF00004D154005C7300008653200007000000F9 -:1010000007000C000700080007000A000D0402009A -:10101000100800003A040800062233000700000010 -:10102000065A200007000000070008007522000093 -:10103000420001000A002000042100008620210057 -:101040002D1E0000F5020000420001000A00080009 -:101050000409000086922000070000001020000014 -:101060003A0430007D050000C38001000A0008003A -:101070002489020002052800020C28000D810A00C4 -:1010800020080000F50200004000010007002200D7 -:10109000FD040000428001000A007000000003000F -:1010A0002070000006FA0600408001000D180200C2 -:1010B000100800003A04080006222B000700000078 -:1010C000FD020000428001000A000800040900003F -:1010D000868A21000700000006F2010007000000D8 -:1010E00075080000FD0900000D010000060A22003D -:1010F00095020000750B00007D0900000D00000046 -:1011000015050000420001000A0018000419000043 -:1011100086782800F506000020100000400001003D -:10112000F5040000200800004000010075070000E1 -:10113000420001004A8009000A001000241100004A -:101140000409000086BA2200150800000201080008 -:101150000412100006DA22007505000004120800CF -:1011600007000000020110007505000025040000C2 -:10117000241102000201100020080000601003008A -:101180004000010024190000867828008D0000002E -:1011900064040000049D00008688270002011800F6 -:1011A00075050000420001000A0428008D010000BE -:1011B00024090000020D28000D0000002409000091 -:1011C000021528000D00100020080000F5020000A4 -:1011D000400001000700200075110000FD02000022 -:1011E000428001000A0008000409000086C22300B2 -:1011F0000700000000010000200B0800600B130036 -:10120000600B1B00600A0300400001004200050063 -:101210004A003D004A0035004A002D000A00200027 -:10122000F5060000420001000A142800F504000041 -:10123000420001000A00080015030000040D01002F -:1012400086CA24001540000095000000040D01002E -:1012500086B82400220010002A00100006E22400B4 -:10126000070000000431330004A92A000700000031 -:10127000242103000205280024110000240400009A -:1012800024040000243200002C2900006C630000BC -:1012900086F325000700000064B10200640400002A -:1012A000640400008D000000640A0000020D2800A4 -:1012B0008D00100020080000F50200004000010031 -:1012C000070022008D00000004B93800070000006C -:1012D0006C2903000A013000F50200004200010001 -:1012E0000A0008000409000086BA25000700000073 -:1012F0002C3102000A0528008D0000006C09010055 -:101300000A0D28000D01100020080000F502000061 -:101310004000010007002200241100002404000006 -:10132000240400002432000002013000442903009C -:10133000867A26000700000002003000F504000055 -:10134000420001000A00080015030000040D01001E -:1013500086C0260024310000640400000201300031 -:10136000F5020000420001000A0008000409000024 -:1013700086CA260007000000243100000205300064 -:10138000243900008305300083080000F5050000C3 -:10139000420001000A0428008D00000024810000A2 -:1013A000020D28008D000000248100000215280095 -:1013B0008D01100020080000F5020000400001002F -:1013C0000700220025100000750500004200030000 -:1013D0004A0009000A00100004090A000411120062 -:1013E0000700000020100000600805004000050014 -:1013F000FD060000428001004A0009000A001000BA -:10140000A500000004090A000411120007000000F2 -:10141000200800006090010040000100F50200007B -:10142000420001000A00080004090000864228006A -:1014300007000000060A230007000000060600005F -:1014400007000000F5020000420001000A00080049 -:101450000409000086922800070000000001000037 -:10146000200B0800608B1300608B1B00608B230037 -:10147000608B2B00608B3300608B3B00608B4300E4 -:10148000608B4B00608B5300608B5B00608B630054 -:10149000608B6B00608B7300608B7B00608F030040 -:1014A000608F0B00608F1300608F1B00608F230024 -:1014B000608F2B00608F3300608F3B00608F430094 -:1014C000608F4B00608F5300608F5B00608F630004 -:1014D000608F6B00608F7300608F7B00608A0300F9 -:1014E00006060000408001008D000000640A000034 -:1014F000020D2800240A00007D0200004280010045 -:101500000A00100024120000FD03000042800100C8 -:101510000A0008000409000086822A000700000073 -:101520008D010000240A000064040000640400002F -:101530000201080024090000240400002404000023 -:10154000020110000D0002004491000086D92A001B -:1015500007000000FD010000428001000A000800B1 -:10156000440A000086BB2A00428001000D000A00E8 -:1015700020080000FD02000040800100070020005C -:101580007D020000201000000606000040800100DF -:10159000F5020000420001000A00080004090000F2 -:1015A000862A2B00070000007D0300004280010016 -:1015B0000A00080004090000865A2B0007000000FA -:1015C000750000007D2E0000420001004A800B00E3 -:1015D0002000000004090000860600004000010011 -:1015E0004A8431008B043000830800008D00000025 -:1015F000100800003A1428008D00000010080000B8 -:101600003A0C280075060000420001000A0008009C -:101610001538000024090100020528000D000B0008 -:1016200020080000F502000040000100060600004E -:1016300007002200640400006404000006060000A5 -:1016400007000000340100008D7F00003C0900000D -:10165000121D280012252800321F000007000E006E -:101660000D0100007D030000200800004080010003 -:10167000F4D2050007000000070008007D03000009 -:10168000428001000A0008000409000086022D00C3 -:101690000700000006060000070000000700000029 -:1016A0001200000007001000070032000700600071 -:1016B000800010001A0048000449000086612D00D7 -:1016C00007000000101200003A0058004501000019 -:1016D000045D5C0007000000800000001A00480064 -:1016E0000449000086B12D00070000001012000020 -:1016F0003A0050000459000086082E004500000002 -:10170000C5000000F5FF7F007DFF7F0024D50700A6 -:101710002442000002015000020520008200000067 -:101720001A0040000441000086392E000700000026 -:10173000653800001A004000204000004D100000F5 -:1017400084C10400861B3000400000000700040034 -:10175000650100004501000020400000400000003D -:1017600065070000800008001A00400004410000E6 -:1017700086C92E0007000000101200003A00400049 -:101780000441000086222F004D000000CD00000023 -:10179000104800003A042000820800001A004000AF -:1017A0000441000086312F0007000000204800009F -:1017B000045900008608300040000000E5070000E2 -:1017C00080042000A0162800E0163200E0163A003F -:1017D000E0164200601202004000000032000000EB -:1017E000750040007D00000074D507001205200040 -:1017F000820000001A0040000441000086E12F0032 -:1018000007000000067203000700640007000600DE -:10181000E50000002000000040000000650A000014 -:1018200020000000400002004000020040000000D4 -:1018300065010000420000000A0070000471000011 -:1018400086A2300007000000068201000700640045 -:101850000000050020700000400000000672030038 -:1018600007006400070000006D300000608802007F -:10187000609002000A0008006088020040800000BA -:10188000120010000D10000084910000864131000C -:101890000D0E000084910000865132000700000008 -:1018A00007003000201000006D3B00004080000069 -:1018B000800000001A000800040900008661310061 -:1018C0000700000020120000ED0D00004080000025 -:1018D000428000000A0010000D00400044951000F6 -:1018E0000700000020100000ED0D00004080000007 -:1018F000428000000A042000820000001A00080054 -:101900000409000086F13100070000006D3B000073 -:10191000428000000A000800150E00008409010042 -:10192000869B3200070060001A000800150C0000BA -:1019300084090100868332002000000007001A009D -:10194000ED02000040800000070062006D300000E2 -:10195000428002004A800A00200800004A800A00F3 -:10196000060600004A80100007000000122528002B -:10197000321F0000F4D2050004D154005C73000053 -:10198000860700000700000007000C0007000A009F -:1019900007001C00653400004000020020480000E1 -:1019A000605002000A004000604002004000000059 -:1019B000444945000700000020400000E53A0000CF -:1019C00040000000E5280000420000000A00480036 -:1019D0000449000086683800652C000042000000C1 -:1019E0000A004000D5000000044145000700000047 -:1019F000550600000445050086F23400D5010000BC -:101A00000445050086F03400652B0000420000000C -:101A1000E53A00004A0050000A004000D4C34500E7 -:101A2000070000000445450007000000CD0000004D -:101A30004449440007000000044545000700000039 -:101A40004D010000444955000700000044510400C6 -:101A500086E93400652C0000420000000A004800BE -:101A600004D14C000700000044C1040086F3340098 -:101A70000700000007001600E52C000042000400EB -:101A80000A004000204000004000000065290000DE -:101A9000420000000A00400004410000866035005A -:101AA000070000000224000006A23600025C0000CD -:101AB000E5250000420000000A00400074420000DA -:101AC000E52A0000420000000A00400074420000C5 -:101AD00012015000E5290000420000000A00400009 -:101AE000344200000441450007000000204000008F -:101AF00040000000E53E0000200000004000000023 -:101B0000E52D0000520140000A005000445104003D -:101B1000864A3600C5000000E53E00002040000077 -:101B200040000000E52B0000420000000A004000D9 -:101B30005442400007000000E52A00002040000059 -:101B400040000000320150003401040074560000CF -:101B5000E5290000420002000A00420042000000A5 -:101B60000A0050007C410500E5280000420000000A -:101B70000A004800C500000044C14C008610370030 -:101B8000E5260000E5270000420002004A00400070 -:101B90000A0050003C4200007C560000E52800008E -:101BA0002048000040000000121D280012252800D7 -:101BB000721F000065290000420000000A0040007A -:101BC0000441000086AA370007000E000700160037 -:101BD00007001E00E53E0000420000000A00400031 -:101BE0000441000086E83700652D00004200000037 -:101BF0000A34280065340000420002004A00420016 -:101C0000204000004A004A004A005000F4D205007B -:101C100004D154005C7300008651380007000000B6 -:101C2000060600000700080007000C000700080077 -:101C300007000A00E5010000450002002040000006 -:101C4000600000006503000040000000652E0000F9 -:101C5000201A0000601A0A004000000065340000ED -:101C6000420002004A004200204000004A004A00B0 -:101C7000060600004A0050000000000000000000BE -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:00000001FF diff --git a/firmware/yamaha/ds1_dsp.fw.ihex b/firmware/yamaha/ds1_dsp.fw.ihex deleted file mode 100644 index acb0ba48f112d97d38b8e2d45b43a132b5a0c268..0000000000000000000000000000000000000000 --- a/firmware/yamaha/ds1_dsp.fw.ihex +++ /dev/null @@ -1,9 +0,0 @@ -:1000000081000000A40100000A0000002F00000091 -:1000100053020800170380017B4000003F8400006A -:100020003C4801003C9401003CD805003C1C000009 -:100030007BC000003F0C05003C5021010000000087 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:00000001FF diff --git a/firmware/yamaha/ds1e_ctrl.fw.ihex b/firmware/yamaha/ds1e_ctrl.fw.ihex deleted file mode 100644 index 597f429ee31a8a34f203acf69157e07435aca6dd..0000000000000000000000000000000000000000 --- a/firmware/yamaha/ds1e_ctrl.fw.ihex +++ /dev/null @@ -1,769 +0,0 @@ -:10000000070000000700240007000C0007001C0088 -:1000100007000600020070002000000040000300FE -:100020000471000086420000400003000D0F000034 -:10003000100800003A042000820200000D020000B7 -:10004000100800003A04200082120000820E2000F6 -:100050000D800000100800003A042000821A000001 -:100060000D460300100800003A0410000DEC0200D9 -:10007000100800003A0418000D01000015000200ED -:10008000FD00000020000000608803006090030075 -:100090006080030040800300408003004080030034 -:1000A000408001007D0A0000408003004080030082 -:1000B0004080010002042000820800001A000800AD -:1000C00004090000867101000700000007002600F7 -:1000D00007004000070000008D2503001008000005 -:1000E0003A04180007002600024428007D0800009A -:1000F000428001000A16000006A205000700000069 -:10010000070044000D230000100800003A04080016 -:1001100006FA220007000000FD07000042800100EF -:100120000A0008000409000086AB020095010000E7 -:10013000040D09000700000020080000F500000081 -:100140007D0B000060F00100FD000000063A030096 -:10015000408001007D0A0000428003004A801300B5 -:100160000A00180020180000609005006088050053 -:1001700040800100FD000000428001000A00700084 -:100180001501000044110700863B03000000030036 -:100190002070000006620300408001000D36000060 -:1001A000100800003A04080006222300070000009F -:1001B0000DEC0200100800003A041800069A010035 -:1001C00007000000070024008D0F00001008000049 -:1001D0003A16000002240000025C0000FD28000026 -:1001E00020000000408001000D00080015080000FC -:1001F00084095100070000004D0000005D0E000062 -:10020000020E00000D430000100800003A04080030 -:1002100006122E00070000008D00000024090000D7 -:10022000020F00000D470000100800003A0408000B -:1002300006122E0007000000800448001012000083 -:100240003A0428008D770000100800003A0C2800BE -:100250008D060000100800003A142800024428000F -:100260008D250300100800003A0418008DFF0700D8 -:1002700020080000FD020000408001000700260069 -:1002800007002000FD020000428001000A00080073 -:100290000409000086120500070000000700240082 -:1002A0000DEC0200100800003A0418007D38000030 -:1002B000428001000A0008001510000084090100B6 -:1002C000869B01000700000006B201000700000045 -:1002D000FD080000428001000A0018000419000017 -:1002E00086B8220007002800101800003A042800F1 -:1002F000020C28000D000000100800003A1428002D -:100300008D80080020080000FD02000040800100F0 -:10031000070020000D0200000499180007000000EB -:100320002D400000BD000000FD02000042800100E1 -:100330000A00080004090000865A060007000000B1 -:1003400000010000200A00007D0400004080010040 -:10035000428001000A002000153000004421010005 -:10036000866103000700000004210000866103008D -:10037000070000008D0F0000100800003A0C280054 -:100380004439020086C90700070000001018000069 -:100390003A0428000D81080020080000FD0200003A -:1003A0004080010007002000102800003A0078007B -:1003B0008D780000100800003A04080006122A0098 -:1003C000070000000D4000001510000004991800FF -:1003D000042929000439390007000000060207003B -:1003E00007000000F50400007D0000002000000070 -:1003F0008D00000060080100408001007D040000C5 -:10040000428003004A8021000A00180044190200BB -:1004100086902200070000007540000004F1710082 -:1004200007000000420001000A0028000429000023 -:1004300086582200070000000D3C000004A930008F -:10044000070000007D070000428001000A0008004C -:100450000409000086DA08007D050000202800005D -:1004600060B0030006F20800408001002030000068 -:1004700060A8030040800100FD02000042800100EE -:100480000A0008000409000086FA080007000000BE -:100490007D050000428001000A0428008D0E000046 -:1004A000100800003A0C28000D00000010080000A1 -:1004B0003A1428000D00090020080000FD02000089 -:1004C0004080010007002000FD3D000020000000EA -:1004D000408001007D1000008D9D0000100800008C -:1004E0003A04080006122A00070000001508000060 -:1004F0001A0008008409010086510A007D130000DB -:1005000000052000200F2800608F3300608F3B0023 -:10051000608F4300608F4B00608F5300608F5B00E3 -:10052000608A0300408001007D10000042800100CD -:100530000A000800150200008409010086813A00C3 -:1005400007000000BD7F0000C43D38000700000028 -:100550007D1A000075130000428001004A00090066 -:100560000A001000048D0B00049513000700000022 -:10057000200800006090010004110000865822004D -:1005800040000100FD170000428001000A00080041 -:1005900004090000865A2200070000007D190000AF -:1005A000428003004A8009000A001000240900006C -:1005B00064160000FD110000428003004A802B00F9 -:1005C0004A8019008D0000004489210007000000C6 -:1005D0004422000086190C0007000000641A000085 -:1005E000242A00007D1900000201080022011000E9 -:1005F000200800006090030040800100FD3D0000E5 -:100600008D000000200800004080010075130000EC -:100610007D1A0000420001004A8009000A00100013 -:100620001D020000E4890100E49229004491300099 -:10063000070000000D060000150A00001D0C000058 -:1006400025100000E4A90000E42B01006404000070 -:10065000E4B30100E432020064040000640400001A -:1006600064040000640400000D040000C4B108002C -:100670000700000020080000F50B00004000030008 -:100680007D190000428003004A800900240A00000E -:100690000A000800640E0800070000002201100094 -:1006A000200800006010030040000100AC6400005E -:1006B0007D02000020000000408001007D1000004D -:1006C00042800100FD1100004A803B004A80090081 -:1006D0000A0020009500000044111A0044A1000007 -:1006E00086580E000D04000084B9000086590E00E3 -:1006F000FD18000042800100FD1000004A80090042 -:100700000A0028009500000024090100642A000066 -:1007100086490E000700000004290000865A0E00DA -:100720000700000006620E00020008008D000000B5 -:100730007D38000020080000408001007D1200008C -:10074000428001000A0010000439000086090F00F1 -:100750000D080000B5FF7F0084B9000086D90E00A7 -:100760002500000006B20F002D000000150000005B -:100770002D0800000DE002002008000006FA0F001E -:100780000D00000035807F0084B9000086A90F00AD -:10079000250040008D000000440911000700000002 -:1007A0008D01000004951000070000006491000016 -:1007B00024040000240400002404000002011000AE -:1007C000020028000DDF02002008000006FA0F00DA -:1007D0008D0100002D0400008D0000000495100024 -:1007E000070000000D0200008491100007000000C7 -:1007F0008DDF0200200800008D000000FD380000A1 -:1008000040800100FD3B00002010000060A80300B4 -:100810001508000084313100842121000700000008 -:1008200060B0030060A0030040800100FD220000D2 -:1008300095000000240901002404000024040000A5 -:100840006412000002011000200800006090030004 -:1008500040800100241900000D0F01007D390000C7 -:100860002008000040800500428003004A840900FF -:10087000060600000A040800240400002404000006 -:100880007D110000428001000A000800240A0000D7 -:1008900002052800020C28000D8009002008000035 -:1008A000FD0200004080010007002000FD22000042 -:1008B000428001000A00080095000000C40D2800D5 -:1008C000241901007D19000042800100FD11000083 -:1008D0004A8009000A001000B500000044311100F0 -:1008E000048D0A0007000000440A08000495120065 -:1008F00007000000FD2300002010000040800300DE -:10090000441210000700000020080000609003005F -:1009100040800100FD020000428001000A00080042 -:10092000040900008632120007000000FD3B0000B1 -:1009300000010000100A00007A800B004A801300BA -:10094000840909000700000095000000043D010033 -:1009500086B812000A001000020010008409090085 -:1009600007000000428003004A801100040D0900C6 -:10097000070000000A001000840D090007000000B5 -:100980007D25000020080000408001000D010000CE -:10099000100800003A1428007D1200004280010077 -:1009A0000A0020007D190000428001007D11000036 -:1009B0004A8031000A001000243100008D3B010004 -:1009C0007D390000200800004080050042800300BF -:1009D0004A840900060600000A04080002013000EB -:1009E000243100002404000024040000241200002C -:1009F000020528004C1A000086391400020070001D -:100A00002D000000000003007D380000428001003E -:100A10000A0010000662140024210000AD0000004E -:100A2000020010000D01000024090000246B0000EA -:100A30000D4A01007D3900002008000040800500BB -:100A4000428003004A840900060600000A040800E8 -:100A5000643200008D000000240A00002010000015 -:100A60007D220000408001008D4F01001008000031 -:100A70003A040800065A2B00070000002028000056 -:100A80007D200000408001007D11000042800300B5 -:100A90004A8013000A8033007D3800004280010044 -:100AA0000A00080004090000867217000700000011 -:100AB0008D000000640903000D5B01007D3900001A -:100AC0002008000040800500428003004A8409009D -:100AD000060600000A040800020138002404000091 -:100AE0002404000024120000FD02000042800100E6 -:100AF0000A0008000409000086DA1500070000005B -:100B0000020528004C1A000086711700070000003B -:100B1000642103002C630000FD3D000042800100C1 -:100B20000A00080095000000040909000700000001 -:100B3000200800004C1A0000869916004080010031 -:100B40000000030006B21600242100000D01000081 -:100B500024090000246B00000D6F01007D390000A6 -:100B60002008000040800500428003004A840900FC -:100B7000060600000A040800643A00009500000020 -:100B800024120000FD020000428001000A0008005B -:100B90000409000086121700070000000D7601000E -:100BA000100800003A040800065A2B000700000055 -:100BB000060A160007000000207000000A01080065 -:100BC0002A011000FD2000006088030060900300EF -:100BD000408001007D22000042800100FD3D0000B8 -:100BE0000A0008004A843100040900008610180039 -:100BF0008B0018008D000000049918002C310000B3 -:100C000006E21800070000004C320000866B180056 -:100C100007000000041900008668180007000000A3 -:100C200095000000449119002C220000243100009E -:100C30006C6300003D0E000075130000FD0B00000A -:100C4000420001004A8009000A001000EC8A0300FB -:100C5000EC9303004C22000086E11800070000001E -:100C60008D000000049918006C2200002C32000056 -:100C70000A053000AB1D300083200000FD18000085 -:100C8000428001000A0008002489010002053000AA -:100C90008310000075180000420001000A001000D7 -:100CA0008D00000024090100751300004205330087 -:100CB000CB0C3300CB2C3300CB343300CB3C330094 -:100CC000CB443300CB4C3300CB5433008B5C30002F -:100CD00083600000F5020000420001000A000800E5 -:100CE0000409000086B21900070000002D1E000054 -:100CF000FD050000428001000A000800248902006E -:100D0000020528000D060000100800003A0C28001B -:100D10008D000000100800003A1428008D800A00A1 -:100D200020080000F502000040000100070022003A -:100D300075120000420003004A0021008D000000EF -:100D400044091A00070000008DAB010010080000E4 -:100D50003A04080006AA2C0007000000F501000074 -:100D6000420003004A000D000A00100044910800F0 -:100D7000070000002008000040000100F5250000E9 -:100D800044310A000700000020080000602803002A -:100D9000400003007D210000428003004A800B00D8 -:100DA0000A0010002008000060100300400003004B -:100DB0008D000000240100002C010000640E0000E2 -:100DC000641A00006C6300000A0108002A01100088 -:100DD000200800006010030040000300FD20000018 -:100DE000428001000A0008007D22000042800100CC -:100DF0000A001000200800006010030040000300FB -:100E00007D190000428001000A000800FD22000058 -:100E1000428003000A001000200800006010030058 -:100E200040000300040D0900070000002008000036 -:100E300040000300428003004A800B000A001000BB -:100E400020080000601003004000030042800300FF -:100E50004A8013004A801900040D1100048D190006 -:100E6000070000000A0008002010000060180300BE -:100E700060080300400003008D00000044090B00DF -:100E8000070000002008000040000100F5050000F8 -:100E9000420003000A000800200800004000010092 -:100EA000F5000000420001000A00080004090000EB -:100EB00086981D00751E0000420003004A040100D0 -:100EC0000A0C000006AA1D00070000000204000032 -:100ED000020C00007D170000F51A0000428001009E -:100EE0004A1403004A1C03004A2403004A2C03004E -:100EF0004A3403004A3C03004A4403000A4C000001 -:100F00003D040000F5130000FD1A0000420003003C -:100F10004A000B004A801B004A8013000A00200090 -:100F20004491080044A11900E4890300EC990300EE -:100F3000025500000A5D0000420003004A000B0059 -:100F40004A801B004A8013000A00200044910800D8 -:100F500044A11900E4890300EC9903000265000034 -:100F60000A6D0000420003004A000B004A0019000D -:100F70004A802B004A8013004A8021000A0030007A -:100F80004491080044A1190044B12A00E4890300F7 -:100F9000EC990300027500000A7D0000E4A903003B -:100FA000020700007D1000001504000042800100CF -:100FB0000A000800E4090100020F0000F52A000001 -:100FC000FD190000420001004A8009000A001000DB -:100FD0003409000074160000F529000042000100E9 -:100FE0000A0010007C910000752000004200010002 -:100FF0000A00080004090000860A2000F526000007 -:10100000F5270000420003004A0009000A00100012 -:101010003C0A00007C160000751A0000FD0B000061 -:10102000420001004A8051000A00480007001600F3 -:1010300075100000420001000A2C2800121D280033 -:1010400012252800321F000007001E0007000E00B6 -:101050007519000042000100F52D00004A000D0046 -:101060000A0010004491000086EA200042000100BE -:101070000A3428005D0E00008D000000750300009A -:101080002008000040000100F4D2050004D1540003 -:101090005C730000868B21000700000007000C0035 -:1010A0000700080007000A008D1702001008000062 -:1010B0003A04080006B2340007000000069221003E -:1010C0000700000007000800752200004200010030 -:1010D0000A00200004210000865822002D1E000076 -:1010E000F5020000420001000A00080004090000A7 -:1010F00086CA210007000000102000003A043000DA -:101100007D050000C38001000A0008002489020058 -:1011100002052800020C28000D810A0020080000AA -:10112000F50200004000010007002200FD0400005D -:10113000428001000A0070000000030020700000DF -:1011400006FA0700408001008D2B02001008000005 -:101150003A04080006AA2C0007000000FD02000067 -:10116000428001000A0008000409000086C2220033 -:1011700007000000060202000700000075080000DA -:10118000FD0900000D010000064223009502000049 -:10119000750B00007D0900000D0000001505000022 -:1011A000420001000A0018000419000086002A000D -:1011B000F50600002010000040000100F5040000CA -:1011C00020080000400001007507000042000100F7 -:1011D0004A8009000A0010002411000004090000E0 -:1011E00086F2230015080000020108000412100016 -:1011F0000612240075050000041208000700000014 -:1012000002011000750500002504000024110200F1 -:1012100002011000200800006010030040000100DF -:101220002419000086002A008D00000064040000DC -:10123000049D0000861029000201180075050000B9 -:10124000420001000A0428008D010000240900006A -:10125000020D28000D0000002409000002152800DE -:101260000D00100020080000F50200004000010001 -:101270000700200075110000FD02000042800100FF -:101280000A0008000409000086FA24000700000094 -:1012900000010000200B0800600B1300600B1B0016 -:1012A000600A030040000100420005004A003D00C2 -:1012B0004A0035004A002D000A002000F506000013 -:1012C000420001000A142800F50400004200010059 -:1012D0000A00080015030000040D01008602260024 -:1012E0001540000095000000040D010086F0250067 -:1012F000220010002A001000061A26000700000035 -:101300000431330004A92A0007000000242103004F -:1013100002052800024428002411000002014000B8 -:101320002404000024040000243200002C290000C2 -:101330006C630000867327000700000064B10200A0 -:1013400064040000640400008D000000640A0000D2 -:10135000020D28008D00100020080000F50200009A -:1013600040000100070022008D00000004B9380091 -:10137000070000006C2903000A013000F50200009C -:10138000420001000A00080004090000860227004C -:10139000070000002C2100000A0528006C31000025 -:1013A0006C0400006C0400000A45280024110000B1 -:1013B000646B0000020110008D0000006C09010048 -:1013C0000A0D28000D01100020080000F5020000A1 -:1013D0004000010007002200244100002404000016 -:1013E00024040000243200000201300044290300DC -:1013F00086FA27000700000002003000F504000014 -:10140000420001000A00080015030000040D01005D -:1014100086402800243100006404000002013000EE -:10142000F5020000420001000A0008000409000063 -:10143000864A2800070000000244280024310000EA -:1014400002053000243900008305300083080000C5 -:10145000F5050000420001000A0428008D0000008C -:1014600024810000020D28008D000000248100006E -:10147000021528008D01100020080000F502000070 -:101480004000010007002200251000007505000043 -:10149000420003004A0009000A00100004090A0083 -:1014A0000411120007000000201000006008050071 -:1014B00040000500FD060000428001004A000900CE -:1014C0000A001000A500000004090A00041112001F -:1014D00007000000200800006090010040000100AB -:1014E000F5020000420001000A00080004090000A3 -:1014F00086CA2900070000000642240007000000F9 -:101500000606000007000000F5020000420001008E -:101510000A00080004090000861A2A0007000000DB -:1015200000010000200B0800608B1300608B1B0083 -:10153000608B2300608B2B00608B3300608B3B0043 -:10154000608B4300608B4B00608B5300608B5B00B3 -:10155000608B6300608B6B00608B7300608B7B0023 -:10156000608F0300608F0B00608F1300608F1B0083 -:10157000608F2300608F2B00608F3300608F3B00F3 -:10158000608F4300608F4B00608F5300608F5B0063 -:10159000608F6300608F6B00608F7300608F7B00D3 -:1015A000608A030006060000408001008D000000F4 -:1015B000640A0000020D2800240A00007D020000D9 -:1015C000428001000A00100024120000FD03000008 -:1015D000428001000A00080004090000860A2C006D -:1015E000070000008D010000240A000064040000D0 -:1015F0006404000002010800240900002404000023 -:1016000024040000020110000D00020044910000BB -:1016100086612C0007000000FD01000042800100EF -:101620000A000800440A000086432C0042800100A2 -:101630000D000A0020080000FD02000040800100AB -:10164000070020007D0200002010000006060000B8 -:1016500040800100F5020000420001000A0008007D -:101660000409000086B22C00070000007D03000082 -:10167000428001000A0008000409000086E22C00F4 -:1016800007000000750000007D2E000042000100F0 -:101690004A800B00200000000409000086060000BC -:1016A000400001004A8431008B04300083080000B0 -:1016B0008D000000100800003A1428008D00000082 -:1016C000100800003A0C28007506000042000100D6 -:1016D0000A0008001538000024090100020528004E -:1016E0000D000B0020080000F50200004000010082 -:1016F00006060000070022006404000064040000E5 -:101700000606000007000000340100008D7F000085 -:101710003C090000121D280012252800321F00007D -:1017200007000E000D0100007D03000020080000EE -:1017300040800100F4D20500070000000700080007 -:101740007D030000428001000A0008000409000037 -:10175000868A2E0007000000060600000700000031 -:101760000700000012000000070010000700320010 -:101770000700600007004600800010001A004800C3 -:101780000449000086F12E0007000000101200003E -:101790003A00580045010000045D5C0007000000AD -:1017A000800000001A0048000449000086412F0014 -:1017B00007000000101200003A0050000459000019 -:1017C00086982F0045000000C5000000F5FF7F004F -:1017D0007DFF7F0024D50700244200000201500055 -:1017E00002052000820000001A00400004410000B1 -:1017F00086C92F0007000000653800001A0040006D -:10180000204000004D10000084C1040086AB310070 -:1018100040000000070004006501000045010000D1 -:101820002040000040000000650700008000080024 -:101830001A004000044100008659300007000000F3 -:10184000101200003A0040000441000086B230004F -:101850004D000000CD000000104800003A042000B8 -:10186000820800001A0040000441000086C13000D8 -:10187000070000002048000004590000869831004D -:1018800040000000E507000080042000A0162800AA -:10189000E0163200E0163A00E01642006012020044 -:1018A0004000000032000000750040007D00000094 -:1018B00074D5070012052000820000001A004000C5 -:1018C000044100008671310007000000068A030011 -:1018D00007006400E5000000200000004000000058 -:1018E000650A0000200000004000020040000200E5 -:1018F0004000000065010000420000000A00700086 -:101900000471000086323200070000000700060064 -:10191000069A010007006400000005002070000026 -:1019200040000000068A0300070064000700000072 -:101930006D30000060880200609002000A0008001C -:101940006088020040800000120010000D100000AE -:101950008491000086D132000D0E000084910000B9 -:1019600086E133000700000007003000201000006F -:101970006D3B000040800000800000001A0008005D -:101980000409000086F13200070000002012000068 -:10199000ED0D000040800000428000000A001000B1 -:1019A0000D004000449510000700000020100000CA -:1019B000ED0D000040800000428000000A0420007D -:1019C000820000001A00080004090000868133002C -:1019D000070000006D3B0000428000000A00080084 -:1019E000150E000084090100862B340007006000FA -:1019F0001A000800150C0000840901008613340049 -:101A00002000000007001A00ED02000040800000E6 -:101A1000070062006D300000428002004A800A0028 -:101A2000200800004A800A00060600004A801000D4 -:101A30000700000012252800321F0000F4D2050024 -:101A400004D154005C73000086070000070000000A -:101A500007000C0007000A0007001C0065340000A6 -:101A60004000020020480000605002000A004000D0 -:101A700060400200400000004449450007000000AB -:101A800020400000E53A000040000000E52800008A -:101A9000420000000A0048000449000086F83900AE -:101AA000652C0000420000000A004000D500000044 -:101AB00004414500070000005506000004450500EC -:101AC00086823600D5010000044505008680360078 -:101AD000652B000042000000E53A00004A0050007B -:101AE0000A004000D4C3450007000000044545003B -:101AF00007000000CD00000044494400070000003A -:101B000004454500070000004D0100004449550010 -:101B1000070000004451040086793600652C00005F -:101B2000420000000A00480004D14C0007000000F9 -:101B300044C1040086833600070000000700160039 -:101B4000E52C0000420004000A0040002040000094 -:101B50004000000065290000420000000A0040002B -:101B60000441000086F03600070000000224000057 -:101B700006323800025C0000E5250000420000004B -:101B80000A00400074420000E52A00004200000004 -:101B90000A0040007442000012015000E5290000D4 -:101BA000420000000A0040003442000004414500A9 -:101BB000070000002040000040000000E53E00005B -:101BC0002000000040000000E52D00005201400010 -:101BD0000A0050004451040086DA3700C5000000B6 -:101BE000E53E00002040000040000000E52B000022 -:101BF000420000000A00400054424000070000007C -:101C0000E52A0000204000004000000032015000A2 -:101C10003401040074560000E5290000420002006F -:101C20000A004200420000000A0050007C4105000A -:101C3000E5280000420000000A004800C50000003E -:101C400044C14C0086A03800E5260000E5270000CE -:101C5000420002004A0040000A0050003C420000DE -:101C60007C560000E52800002048000040000000ED -:101C7000121D280012252800721F0000652900008F -:101C8000420000000A00400004410000863A39008A -:101C900007000E000700160007001E00E53E0000CA -:101CA000420000000A00400004410000867839002C -:101CB000652D0000420000000A3428006534000051 -:101CC000420002004A004200204000004A004A0050 -:101CD0004A005000F4D2050004D154005C730000A7 -:101CE00086E1390007000000060600000700080032 -:101CF00007000C000700080007000A00E5010000CB -:101D00004500020020400000600000006503000064 -:101D100040000000652E0000201A0000601A0A0032 -:101D20004000000065340000420002004A0042000A -:101D3000204000004A004A00060600004A00500009 -:101D4000FD170000428001000A000800040900009D -:101D5000865A2200070000007D100000428001002A -:101D6000FD1100004A8033004A8019000A0020005B -:101D70009500000044112A0044A1010086903B0018 -:101D80000D04000084B1000086913B00FD180000A6 -:101D900042800100FD1000004A8009000A0038005E -:101DA0009500000024090100643A000086813B0090 -:101DB000070000000439000086923B000700000085 -:101DC000069A3B000D0000008D0000002008000076 -:101DD0007D38000040800100020070007D1100008D -:101DE000428001007D1900004A8029000A0030006D -:101DF0000200380024310000240400002404000004 -:101E0000242A0000020528008D06000010080000AA -:101E10003A1428000D75000024B10000642200006F -:101E200086033D0002442800100800003A0C2800F8 -:101E30000D800B0020080000FD0200004080010022 -:101E4000070020008D75000024B100000201100081 -:101E50004421010086493E00101800003A0010009D -:101E60007D380000428001000A00080004090000DB -:101E700086483E0000000300064A3E00BD00000008 -:101E80008D00000064310200640A0000020D280089 -:101E90008D800B0020080000FD0200004080010042 -:101EA000070020007D380000428001000A00080081 -:101EB0000409000086323E0000000300FD0200001D -:101EC000428001000A0008000409000086823D00EB -:101ED00007000000102800003A0428000D750000DB -:101EE0002409030064220000020D28006C31020066 -:101EF0000A4528000D810B0020080000FD020000AB -:101F000040800100070020008D000000240A00002E -:101F1000064A3E0002011000101800003A001000AE -:101F2000BD000000103800003A0430007D180000A9 -:101F300042800100FD1800004A8009000A002000CC -:101F4000AD000000248902002C21070010100000C1 -:101F5000830530008B0D3000BB143000831C300033 -:101F6000832000007D130000428003004A84330078 -:101F7000CBAC3300CBB43300CBBC3300CBC4330089 -:101F8000CBCC3300CBD433008B5C300083600000BB -:101F90000D1E0000FD050000428001000A00200027 -:101FA000240902008D0600006CA900009D000000BD -:101FB000FD020000428001000A0008000409000040 -:101FC000866A3F0007000000020528000A0D28006D -:101FD00002442800101800003A1428008D000C005C -:101FE00020080000FD0200004080010007002200E0 -:101FF00004390000865822000D1E00007D050000F7 -:10200000428001000A00200024090200A50000000F -:10201000FD020000428001000A00080004090000DF -:10202000862A40000700000002052800020C280054 -:10203000102000003A1428000D010C0020080000B8 -:10204000FD02000040800100065A22000700220025 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:00000001FF diff --git a/firmware/yamaha/yss225_registers.bin.ihex b/firmware/yamaha/yss225_registers.bin.ihex deleted file mode 100644 index 6dd3d8c4de2bb040d86bdca63f3f3c4adf7452ab..0000000000000000000000000000000000000000 --- a/firmware/yamaha/yss225_registers.bin.ihex +++ /dev/null @@ -1,998 +0,0 @@ -:10000000FF000E100F00FF000E110F00FF000E1278 -:100010000F00FF000E130F00FF000E140F00FF0073 -:100020000E150F00FF000E160F00FF000E170F0039 -:10003000FF000E180F00FF000E190F00FF000E1A30 -:100040000F00FF000E1B0F00FF000E1C0F00FF0033 -:100050000E1D0F00FF000E1E0F00FF000E1F0F00F1 -:10006000FF000E200F00FF000E210F00FF000E22E8 -:100070000F00FF000E230F00FF000E240F00FF00F3 -:100080000E250F00FF000E260F00FF000E270F00A9 -:10009000FF000E280F00FF000E290F00FF000E2AA0 -:1000A0000F00FF000E2B0F00FF000E2C0F00FF00B3 -:1000B0000E2D0F00FF000E2E0F00FF000E2F0F0061 -:1000C000FF000E300F00FF000E310F00FF000E3258 -:1000D0000F00FF000E330F00FF000E340F00FF0073 -:1000E0000E350F00FF000E360F00FF000E370F0019 -:1000F000FF000E380F00FF000E390F00FF000E3A10 -:100100000F00FF000E3B0F00FF000E3C0F00FF0032 -:100110000E3D0F00FF000E3E0F00FF000E3F0F00D0 -:10012000FF000E400F00FF000E410F00FF000E42C7 -:100130000F00FF000E430F00FF000E440F00FF00F2 -:100140000E450F00FF000E460F00FF000E470F0088 -:10015000FF000E480F00FF000E490F00FF000E4A7F -:100160000F00FF000E4B0F00FF000E4C0F00FF00B2 -:100170000E4D0F00FF000E4E0F00FF000E4F0F0040 -:10018000FF000E500F00FF000E510F00FF000E5237 -:100190000F00FF000E530F00FF000E540F00FF0072 -:1001A0000E550F00FF000E560F00FF000E570F00F8 -:1001B000FF000E580F00FF000E590F00FF000E5AEF -:1001C0000F00FF000E5B0F00FF000E5C0F00FF0032 -:1001D0000E5D0F00FF000E5E0F00FF000E5F0F00B0 -:1001E000FF000E600F00FF000E610F00FF000E62A7 -:1001F0000F00FF000E630F00FF000E640F00FF00F2 -:100200000E650F00FF000E660F00FF000E670F0067 -:10021000FF000E680F00FF000E690F00FF000E6A5E -:100220000F00FF000E6B0F00FF000E6C0F00FF00B1 -:100230000E6D0F00FF000E6E0F00FF000E6F0F001F -:10024000FF000E700F00FF000E710F00FF000E7216 -:100250000F00FF000E730F00FF000E740F00FF0071 -:100260000E750F00FF000E760F00FF000E770F00D7 -:10027000FF000E780F00FF000E790F00FF000E7ACE -:100280000F00FF000E7B0F00FF000E7C0F00FF0031 -:100290000E7D0F00FF000E7E0F00FF000E7F0F008F -:1002A000FF000E800F00FF000E810F00FF000E8286 -:1002B0000F00FF000E830F00FF000E840F00FF00F1 -:1002C0000E850F00FF000E860F00FF000E870F0047 -:1002D000FF000E880F00FF000E890F00FF000E8A3E -:1002E0000F00FF000E8B0F00FF000E8C0F00FF00B1 -:1002F0000E8D0F00FF000E8E0F00FF000E8F0F00FF -:10030000FF000E900F00FF000E910F00FF000E92F5 -:100310000F00FF000E930F00FF000E940F00FF0070 -:100320000E950F00FF000E960F00FF000E970F00B6 -:10033000FF000E980F00FF000E990F00FF000E9AAD -:100340000F00FF000E9B0F00FF000E9C0F00FF0030 -:100350000E9D0F00FF000E9E0F00FF000E9F0F006E -:10036000FF000EA00F00FF000EA10F00FF000EA265 -:100370000F00FF000EA30F00FF000EA40F00FF00F0 -:100380000EA50F00FF000EA60F00FF000EA70F0026 -:10039000FF000EA80F00FF000EA90F00FF000EAA1D -:1003A0000F00FF000EAB0F00FF000EAC0F00FF00B0 -:1003B0000EAD0F00FF000EAE0F00FF000EAF0F00DE -:1003C000FF000EB00F00FF000EB10F00FF000EB2D5 -:1003D0000F00FF000EB30F00FF000EB40F00FF0070 -:1003E0000EB50F00FF000EB60F00FF000EB70F0096 -:1003F000FF000EB80F00FF000EB90F00FF000EBA8D -:100400000F00FF000EBB0F00FF000EBC0F00FF002F -:100410000EBD0F00FF000EBE0F00FF000EBF0F004D -:10042000FF000EC00F00FF000EC10F00FF000EC244 -:100430000F00FF000EC30F00FF000EC40F00FF00EF -:100440000EC50F00FF000EC60F00FF000EC70F0005 -:10045000FF000EC80F00FF000EC90F00FF000ECAFC -:100460000F00FF000ECB0F00FF000ECC0F00FF00AF -:100470000ECD0F00FF000ECE0F00FF000ECF0F00BD -:10048000FF000ED00F00FF000ED10F00FF000ED2B4 -:100490000F00FF000ED30F00FF000ED40F00FF006F -:1004A0000ED50F00FF000ED60F00FF000ED70F0075 -:1004B000FF000ED80F00FF000ED90F00FF000EDA6C -:1004C0000F00FF000EDB0F00FF000EDC0F00FF002F -:1004D0000EDD0F00FF000EDE0F00FF000EDF0F002D -:1004E000FF000EE00F00FF000EE10F00FF000EE224 -:1004F0000F00FF000EE30F00FF000EE40F00FF00EF -:100500000EE50F00FF000EE60F00FF000EE70F00E4 -:10051000FF000EE80F00FF000EE90F00FF000EEADB -:100520000F00FF000EEB0F00FF000EEC0F00FF00AE -:100530000EED0F00FF000EEE0F00FF000EEF0F009C -:10054000FF000EF00F00FF000EF10F00FF000EF293 -:100550000F00FF000EF30F00FF000EF40F00FF006E -:100560000EF50F00FF000EF60F00FF000EF70F0054 -:10057000FF000EF80F00FF000EF90F00FF000EFA4B -:100580000F00FF000EFB0F00FF000EFC0F00FF002E -:100590000EFD0F00FF000EFE0F00FF000EFF0F000C -:1005A000FF000E100F00FF000E110F00FF000E12D3 -:1005B0000F00FF000E130F00FF000E140F00FF00CE -:1005C0000E150F00FF000E160F00FF000E170F0094 -:1005D000FF000E180F00FF000E190F00FF000E1A8B -:1005E0000F00FF000E1B0F00FF000E1C0F00FF008E -:1005F0000E1D0F00FF000E1E0F00FF000E1F0F004C -:10060000FF000E200F00FF000E210F00FF000E2242 -:100610000F00FF000E230F00FF000E240F00FF004D -:100620000E250F00FF000E260F00FF000E270F0003 -:10063000FF000E280F00FF000E290F00FF000E2AFA -:100640000F00FF000E2B0F00FF000E2C0F00FF000D -:100650000E2D0F00FF000E2E0F00FF000E2F0F00BB -:10066000FF000E300F00FF000E310F00FF000E32B2 -:100670000F00FF000E330F00FF000E340F00FF00CD -:100680000E350F00FF000E360F00FF000E370F0073 -:10069000FF000E380F00FF000E390F00FF000E3A6A -:1006A0000F00FF000E3B0F00FF000E3C0F00FF008D -:1006B0000E3D0F00FF000E3E0F00FF000E3F0F002B -:1006C000FF000E400F00FF000E410F00FF000E4222 -:1006D0000F00FF000E430F00FF000E440F00FF004D -:1006E0000E450F00FF000E460F00FF000E470F00E3 -:1006F000FF000E480F00FF000E490F00FF000E4ADA -:100700000F00FF000E4B0F00FF000E4C0F00FF000C -:100710000E4D0F00FF000E4E0F00FF000E4F0F009A -:10072000FF000E500F00FF000E510F00FF000E5291 -:100730000F00FF000E530F00FF000E540F00FF00CC -:100740000E550F00FF000E560F00FF000E570F0052 -:10075000FF000E580F00FF000E590F00FF000E5A49 -:100760000F00FF000E5B0F00FF000E5C0F00FF008C -:100770000E5D0F00FF000E5E0F00FF000E5F0F000A -:10078000FF000E600F00FF000E610F00FF000E6201 -:100790000F00FF000E630F00FF000E640F00FF004C -:1007A0000E650F00FF000E660F00FF000E670F00C2 -:1007B000FF000E680F00FF000E690F00FF000E6AB9 -:1007C0000F00FF000E6B0F00FF000E6C0F00FF000C -:1007D0000E6D0F00FF000E6E0F00FF000E6F0F007A -:1007E000FF000E700F00FF000E710F00FF000E7271 -:1007F0000F00FF000E730F00FF000E740F00FF00CC -:100800000E750F00FF000E760F00FF000E770F0031 -:10081000FF000E780F00FF000E790F00FF000E7A28 -:100820000F00FF000E7B0F00FF000E7C0F00FF008B -:100830000E7D0F00FF000E7E0F00FF000E7F0F00E9 -:10084000FF000E800F00FF000E810F00FF000E82E0 -:100850000F00FF000E830F00FF000E840F00FF004B -:100860000E850F00FF000E860F00FF000E870F00A1 -:10087000FF000E880F00FF000E890F00FF000E8A98 -:100880000F00FF000E8B0F00FF000E8C0F00FF000B -:100890000E8D0F00FF000E8E0F00FF000E8F0F0059 -:1008A000FF000E900F00FF000E910F00FF000E9250 -:1008B0000F00FF000E930F00FF000E940F00FF00CB -:1008C0000E950F00FF000E960F00FF000E970F0011 -:1008D000FF000E980F00FF000E990F00FF000E9A08 -:1008E0000F00FF000E9B0F00FF000E9C0F00FF008B -:1008F0000E9D0F00FF000E9E0F00FF000E9F0F00C9 -:10090000FF000EA00F00FF000EA10F00FF000EA2BF -:100910000F00FF000EA30F00FF000EA40F00FF004A -:100920000EA50F00FF000EA60F00FF000EA70F0080 -:10093000FF000EA80F00FF000EA90F00FF000EAA77 -:100940000F00FF000EAB0F00FF000EAC0F00FF000A -:100950000EAD0F00FF000EAE0F00FF000EAF0F0038 -:10096000FF000EB00F00FF000EB10F00FF000EB22F -:100970000F00FF000EB30F00FF000EB40F00FF00CA -:100980000EB50F00FF000EB60F00FF000EB70F00F0 -:10099000FF000EB80F00FF000EB90F00FF000EBAE7 -:1009A0000F00FF000EBB0F00FF000EBC0F00FF008A -:1009B0000EBD0F00FF000EBE0F00FF000EBF0F00A8 -:1009C000FF000EC00F00FF000EC10F00FF000EC29F -:1009D0000F00FF000EC30F00FF000EC40F00FF004A -:1009E0000EC50F00FF000EC60F00FF000EC70F0060 -:1009F000FF000EC80F00FF000EC90F00FF000ECA57 -:100A00000F00FF000ECB0F00FF000ECC0F00FF0009 -:100A10000ECD0F00FF000ECE0F00FF000ECF0F0017 -:100A2000FF000ED00F00FF000ED10F00FF000ED20E -:100A30000F00FF000ED30F00FF000ED40F00FF00C9 -:100A40000ED50F00FF000ED60F00FF000ED70F00CF -:100A5000FF000ED80F00FF000ED90F00FF000EDAC6 -:100A60000F00FF000EDB0F00FF000EDC0F00FF0089 -:100A70000EDD0F00FF000EDE0F00FF000EDF0F0087 -:100A8000FF000EE00F00FF000EE10F00FF000EE27E -:100A90000F00FF000EE30F00FF000EE40F00FF0049 -:100AA0000EE50F00FF000EE60F00FF000EE70F003F -:100AB000FF000EE80F00FF000EE90F00FF000EEA36 -:100AC0000F00FF000EEB0F00FF000EEC0F00FF0009 -:100AD0000EED0F00FF000EEE0F00FF000EEF0F00F7 -:100AE000FF000EF00F00FF000EF10F00FF000EF2EE -:100AF0000F00FF000EF30F00FF000EF40F00FF00C9 -:100B00000EF50F00FF000EF60F00FF000EF70F00AE -:100B1000FF000EF80F00FF000EF90F00FF000EFAA5 -:100B20000F00FF000EFB0F00FF000EFC0F00FF0088 -:100B30000EFD0F00FF000EFE0F00FF000EFF0F0066 -:100B4000FF000802FF000B070A440D000C00FF0025 -:100B50000B070A420D000C00FF000B070A430D00B3 -:100B60000C00FF000B070A7C0D000C00FF000B07B8 -:100B70000A7E0D000C00FF000B070A460D000C005A -:100B8000FF000B070A490D000C00FF000B070A4786 -:100B90000D000C00FF000B070A4A0D000C00FF00BF -:100BA0000E100F00FF000E110F00FF000E120F00BD -:100BB000FF000E130F00FF000E140F00FF000E15B4 -:100BC0000F00FF000E160F00FF000E170F00FF00B2 -:100BD0000E180F00FF000E190F00FF000E1A0F0075 -:100BE000FF000E1B0F00FF000E1C0F00FF000E1D6C -:100BF0000F00FF000E1E0F00FF000E1F0F00FF0072 -:100C00000E200F00FF000E210F00FF000E220F002C -:100C1000FF000E230F00FF000E240F00FF000E2523 -:100C20000F00FF000E260F00FF000E270F00FF0031 -:100C30000E280F00FF000E290F00FF000E2A0F00E4 -:100C4000FF000E2B0F00FF000E2C0F00FF000E2DDB -:100C50000F00FF000E2E0F00FF000E2F0F00FF00F1 -:100C60000E300F00FF000E310F00FF000E320F009C -:100C7000FF000E330F00FF000E340F00FF000E3593 -:100C80000F00FF000E360F00FF000E370F00FF00B1 -:100C90000E380F00FF000E390F00FF000E3A0F0054 -:100CA000FF000E3B0F00FF000E3C0F00FF000E3D4B -:100CB0000F00FF000E3E0F00FF000E3F0F00FF0071 -:100CC0000E400F00FF000E410F00FF000E420F000C -:100CD000FF000E430F00FF000E440F00FF000E4503 -:100CE0000F00FF000E460F00FF000E470F00FF0031 -:100CF0000E480F00FF000E490F00FF000E4A0F00C4 -:100D0000FF000E4B0F00FF000E4C0F00FF000E4DBA -:100D10000F00FF000E4E0F00FF000E4F0F00FF00F0 -:100D20000E500F00FF000E510F00FF000E520F007B -:100D3000FF000E530F00FF000E540F00FF000E5572 -:100D40000F00FF000E560F00FF000E570F00FF00B0 -:100D50000E580F00FF000E590F00FF000E5A0F0033 -:100D6000FF000E5B0F00FF000E5C0F00FF000E5D2A -:100D70000F00FF000E5E0F00FF000E5F0F00FF0070 -:100D80000E600F00FF000E610F00FF000E620F00EB -:100D9000FF000E630F00FF000E640F00FF000E65E2 -:100DA0000F00FF000E660F00FF000E670F00FF0030 -:100DB0000E680F00FF000E690F00FF000E6A0F00A3 -:100DC000FF000E6B0F00FF000E6C0F00FF000E6D9A -:100DD0000F00FF000E6E0F00FF000E6F0F00FF00F0 -:100DE0000E700F00FF000E710F00FF000E720F005B -:100DF000FF000E730F00FF000E740F00FF000E7552 -:100E00000F00FF000E760F00FF000E770F00FF00AF -:100E10000E780F00FF000E790F00FF000E7A0F0012 -:100E2000FF000E7B0F00FF000E7C0F00FF000E7D09 -:100E30000F00FF000E7E0F00FF000E7F0F00FF006F -:100E40000E800F00FF000E810F00FF000E820F00CA -:100E5000FF000E830F00FF000E840F00FF000E85C1 -:100E60000F00FF000E860F00FF000E870F00FF002F -:100E70000E880F00FF000E890F00FF000E8A0F0082 -:100E8000FF000E8B0F00FF000E8C0F00FF000E8D79 -:100E90000F00FF000E8E0F00FF000E8F0F00FF00EF -:100EA0000E900F00FF000E910F00FF000E920F003A -:100EB000FF000E930F00FF000E940F00FF000E9531 -:100EC0000F00FF000E960F00FF000E970F00FF00AF -:100ED0000E980F00FF000E990F00FF000E9A0F00F2 -:100EE000FF000E9B0F00FF000E9C0F00FF000E9DE9 -:100EF0000F00FF000E9E0F00FF000E9F0F00FF006F -:100F00000EA00F00FF000EA10F00FF000EA20F00A9 -:100F1000FF000EA30F00FF000EA40F00FF000EA5A0 -:100F20000F00FF000EA60F00FF000EA70F00FF002E -:100F30000EA80F00FF000EA90F00FF000EAA0F0061 -:100F4000FF000EAB0F00FF000EAC0F00FF000EAD58 -:100F50000F00FF000EAE0F00FF000EAF0F00FF00EE -:100F60000EB00F00FF000EB10F00FF000EB20F0019 -:100F7000FF000EB30F00FF000EB40F00FF000EB510 -:100F80000F00FF000EB60F00FF000EB70F00FF00AE -:100F90000EB80F00FF000EB90F00FF000EBA0F00D1 -:100FA000FF000EBB0F00FF000EBC0F00FF000EBDC8 -:100FB0000F00FF000EBE0F00FF000EBF0F00FF006E -:100FC0000EC00F00FF000EC10F00FF000EC20F0089 -:100FD000FF000EC30F00FF000EC40F00FF000EC580 -:100FE0000F00FF000EC60F00FF000EC70F00FF002E -:100FF0000EC80F00FF000EC90F00FF000ECA0F0041 -:10100000FF000ECB0F00FF000ECC0F00FF000ECD37 -:101010000F00FF000ECE0F00FF000ECF0F00FF00ED -:101020000ED00F00FF000ED10F00FF000ED20F00F8 -:10103000FF000ED30F00FF000ED40F00FF000ED5EF -:101040000F00FF000ED60F00FF000ED70F00FF00AD -:101050000ED80F00FF000ED90F00FF000EDA0F00B0 -:10106000FF000EDB0F00FF000EDC0F00FF000EDDA7 -:101070000F00FF000EDE0F00FF000EDF0F00FF006D -:101080000EE00F00FF000EE10F00FF000EE20F0068 -:10109000FF000EE30F00FF000EE40F00FF000EE55F -:1010A0000F00FF000EE60F00FF000EE70F00FF002D -:1010B0000EE80F00FF000EE90F00FF000EEA0F0020 -:1010C000FF000EEB0F00FF000EEC0F00FF000EED17 -:1010D0000F00FF000EEE0F00FF000EEF0F00FF00ED -:1010E0000EF00F00FF000EF10F00FF000EF20F00D8 -:1010F000FF000EF30F00FF000EF40F00FF000EF5CF -:101100000F00FF000EF60F00FF000EF70F00FF00AC -:101110000EF80F00FF000EF90F00FF000EFA0F008F -:10112000FF000EFB0F00FF000EFC0F00FF000EFD86 -:101130000F00FF000EFE0F00FF000EFF0F0009055D -:101140000B000A000D010C7CFF000D000C1EFF00BF -:101150000D000C00FF000D000C00FF000D000CF551 -:10116000FF000D000C11FF000D000C20FF000D0012 -:101170000C32FF000D000C40FF000D000C13FF00AF -:101180000D000C00FF000D000C14FF000D020C768A -:10119000FF000D000C60FF000D000C80FF000D0231 -:1011A0000C00FF000D000C00FF000D000C00FF0004 -:1011B0000D020C00FF000D000C00FF000D000C00E4 -:1011C000FF000D000C00FF000D000C00FF000D00E3 -:1011D0000C00FF000D000C00FF000D000C00FF00D4 -:1011E0000D000C00FF000D000C00FF000D000C00B6 -:1011F000FF000D000C00FF000D000C00FF000D00B3 -:101200000C00FF000D000C00FF000D000C00FF00A3 -:101210000D000C00FF000D000C00FF000D000C0085 -:10122000FF000D000C00FF000D000C00FF000D0082 -:101230000C00FF000D000C00FF000D000C00FF0073 -:101240000D000C00FF000D000C00FF000D000C0055 -:10125000FF000D000C00FF000D000C00FF000D0052 -:101260000C00FF000D000C00FF000D000C00FF0043 -:101270000D000C00FF000D000C00FF000D000C0025 -:10128000FF000D000C00FF000D000C00FF000D0022 -:101290000C00FF000D000C00FF000D000C00FF0013 -:1012A0000D000C00FF000D000C00FF000D000C00F5 -:1012B000FF000D000C00FF000D000C00FF000D00F2 -:1012C0000C00FF000D000C18FF000D000C19FF00B2 -:1012D0000D010C1AFF000D010C20FF000D010C4048 -:1012E000FF000D010C17FF000D000C00FF000D01A9 -:1012F0000C80FF000D010C20FF000D000C10FF0002 -:101300000D010CA0FF000D030CD1FF000D000C001F -:10131000FF000D010CF2FF000D020C00FF000D009C -:101320000C13FF000D000C00FF000D000CF4FF007B -:101330000D020CE0FF000D000C15FF000D000C006D -:10134000FF000D000C16FF000D000C00FF000D004B -:101350000C17FF000D000C20FF000D000C00FF001B -:101360000D000C20FF000D000C50FF000D000C00C4 -:10137000FF000D000C40FF000D000C00FF000D00F1 -:101380000C71FF000D020C00FF000D000C60FF004F -:101390000D000C00FF000D000C92FF000D000C0072 -:1013A000FF000D000C80FF000D000C00FF000D0081 -:1013B0000CB3FF000D020C00FF000D000CA0FF009D -:1013C0000D000C00FF000D000CD4FF000D000C0000 -:1013D000FF000D000C40FF000D000C80FF000D0011 -:1013E0000CF5FF000D000C20FF000D000C70FF003D -:1013F0000D000CA0FF000D020C11FF000D000C16DB -:10140000FF000D000C00FF000D000C00FF000D00A0 -:101410000C00FF000D000C20FF000D020C00FF006F -:101420000D000C20FF000D000C10FF000D000C172C -:10143000FF000D000C1BFF000D000C1DFF000D0236 -:101440000CDFFF0009050B010A000D000C00FF0076 -:101450000D000C00FF000D000C00FF000D020C0041 -:10146000FF000D000C19FF000D000C1FFF000D0008 -:101470000C00FF000D000C00FF000D000C00FF0031 -:101480000D030CD8FF000D000C00FF000D020C2016 -:10149000FF000D000C19FF000D000C00FF000D00F7 -:1014A0000C00FF000D000C18FF000D010CC0FF0028 -:1014B0000D010CFAFF000D000C1AFF000D000C00CE -:1014C000FF000D000C00FF000D000C00FF000D00E0 -:1014D0000C00FF000D000C00FF000D000C00FF00D1 -:1014E0000D000C00FF000D000C00FF000D000C00B3 -:1014F000FF000D000C00FF000D000C00FF000D00B0 -:101500000C00FF000D000C00FF000D000C00FF00A0 -:101510000D000C00FF000D000C00FF000D000C0082 -:10152000FF000D000C00FF000D000C00FF000D007F -:101530000C00FF000D000C00FF000D000C00FF0070 -:101540000D000C00FF000D000C00FF000D000C0052 -:10155000FF000D000C00FF000D000C00FF000D004F -:101560000C00FF000D000C00FF000D000C00FF0040 -:101570000D000C00FF000D000C00FF000D000C0022 -:10158000FF000D000C00FF000D000C00FF000D001F -:101590000C00FF000D000C00FF000D000C00FF0010 -:1015A0000D000C00FF000D000C00FF000D000C00F2 -:1015B000FF000D000C00FF000D000C00FF000D00EF -:1015C0000C00FF000D000C00FF000D020C40FF009E -:1015D0000D020C60FF000D000C00FF000D000C0060 -:1015E000FF000D000C00FF000D020CC0FF000D02FB -:1015F0000C80FF000D000C00FF000D020CFBFF0033 -:101600000D020CA0FF000D000C00FF000D000C1BD4 -:10161000FF000D020CD7FF000D000C00FF000D02B3 -:101620000CF7FF000D030C20FF000D030C00FF0062 -:101630000D000C00FF000D000C1CFF000D030C3C06 -:10164000FF000D000C00FF000D030C3FFF000D001C -:101650000C00FF000D030CC0FF000D000C00FF008C -:101660000D030CDFFF000D000C00FF000D000C004F -:10167000FF000D030C5DFF000D000C00FF000D03CB -:101680000CC0FF000D000C00FF000D030C7DFF00DF -:101690000D000C00FF000D030CC0FF000D000C003E -:1016A000FF000D030C9EFF000D000C00FF000D035A -:1016B0000CC0FF000D000C00FF000D030CBEFF006E -:1016C0000D000C00FF000D030CC0FF000D000C000E -:1016D000FF000D000C00FF000D000C00FF000D00CE -:1016E0000C00FF000D000C1BFF000D000C00FF00A4 -:1016F0000D000C00FF000D000C00FF000D020CDBC4 -:10170000FF000D000C00FF000D020CDBFF000D00C0 -:101710000C00FF000D020CE0FF000D000C00FF00AC -:101720000D020CFBFF000D000C00FF000D020CC0B1 -:10173000FF000D020C40FF000D020CFBFF000D022C -:101740000C60FF000D000C1BFF0009050B020A00D6 -:101750000CC4FF000C00FF000C44FF000C07FF004E -:101760000C44FF000C00FF000C40FF000C25FF00A4 -:101770000C01FF000C06FF000CC4FF000C07FF006B -:101780000C40FF000C25FF000C01FF000C00FF00C7 -:101790000C46FF000C46FF000C00FF000C00FF0091 -:1017A0000C00FF000C00FF000C00FF000C00FF000D -:1017B0000C00FF000C00FF000C00FF000C00FF00FD -:1017C0000C00FF000C00FF000C00FF000C00FF00ED -:1017D0000C00FF000C00FF000C00FF000C00FF00DD -:1017E0000C00FF000C00FF000C00FF000C00FF00CD -:1017F0000C00FF000C00FF000C00FF000C00FF00BD -:101800000C00FF000C00FF000C00FF000C00FF00AC -:101810000C00FF000C00FF000C00FF000C00FF009C -:101820000C00FF000C00FF000C00FF000C00FF008C -:101830000C00FF000C00FF000C00FF000C00FF007C -:101840000C00FF000C00FF000C00FF000C00FF006C -:101850000C46FF000C07FF000C05FF000C05FF0005 -:101860000C05FF000C04FF000C07FF000C05FF0037 -:101870000C04FF000C07FF000C05FF000C44FF00E8 -:101880000C46FF000C44FF000C46FF000C46FF0016 -:101890000C07FF000C05FF000C44FF000C46FF0086 -:1018A0000C05FF000C46FF000C05FF000C46FF0076 -:1018B0000C05FF000C46FF000C05FF000C44FF0068 -:1018C0000C46FF000C05FF000C07FF000C44FF0056 -:1018D0000C46FF000C05FF000C07FF000C44FF0046 -:1018E0000C46FF000C05FF000C07FF000C44FF0036 -:1018F0000C46FF000C05FF000C07FF000C44FF0026 -:101900000C05FF000C05FF000C05FF000C44FF0058 -:101910000C05FF000C05FF000C05FF000C46FF0046 -:101920000C05FF000C46FF000C05FF000C46FF00F5 -:101930000C05FF000C46FF000C05FF000C46FF00E5 -:101940000C07FF000C46FF000C07FF000C44FF00D3 -:1019500009050B030A000C07FF000C40FF000C00F8 -:10196000FF000C00FF000C00FF000C47FF000C0004 -:10197000FF000C40FF000C00FF000C40FF000C06B5 -:10198000FF000C40FF000C00FF000C00FF000C00EB -:10199000FF000C00FF000C00FF000C00FF000C001B -:1019A000FF000C00FF000C00FF000C00FF000C000B -:1019B000FF000C00FF000C00FF000C00FF000C00FB -:1019C000FF000C00FF000C00FF000C00FF000C00EB -:1019D000FF000C00FF000C00FF000C00FF000C00DB -:1019E000FF000C00FF000C00FF000C00FF000C00CB -:1019F000FF000C00FF000C00FF000C00FF000C00BB -:101A0000FF000C00FF000C00FF000C00FF000C00AA -:101A1000FF000C00FF000C00FF000C00FF000C009A -:101A2000FF000C00FF000C00FF000C00FF000C008A -:101A3000FF000C00FF000C00FF000C00FF000C007A -:101A4000FF000C00FF000C00FF000C00FF000C006A -:101A5000FF000C00FF000C80FF000C80FF000CC09A -:101A6000FF000C00FF000C00FF000C40FF000C000A -:101A7000FF000C00FF000C00FF000C40FF000C00FA -:101A8000FF000C40FF000C00FF000C60FF000C008A -:101A9000FF000C70FF000C00FF000C40FF000C006A -:101AA000FF000C40FF000C00FF000C42FF000C0088 -:101AB000FF000C40FF000C00FF000C02FF000C00B8 -:101AC000FF000C40FF000C00FF000C00FF000C00AA -:101AD000FF000C40FF000C00FF000C00FF000C009A -:101AE000FF000C40FF000C00FF000C00FF000C008A -:101AF000FF000C40FF000C00FF000C00FF000C007A -:101B0000FF000C40FF000C00FF000C00FF000C0069 -:101B1000FF000C42FF000C00FF000C40FF000C0017 -:101B2000FF000C42FF000C00FF000C02FF000C0045 -:101B3000FF000C02FF000C00FF000C02FF000C0075 -:101B4000FF000C42FF000C00FF000CC0FF000C0067 -:101B5000FF000C40FF0009050B040A000C63FF00A6 -:101B60000C03FF000C26FF000C02FF000C2CFF00F2 -:101B70000C00FF000C24FF000C00FF000C2EFF00E7 -:101B80000C02FF000C02FF000C02FF000C00FF0023 -:101B90000C00FF000C00FF000C00FF000C00FF0019 -:101BA0000C00FF000C00FF000C00FF000C00FF0009 -:101BB0000C00FF000C00FF000C00FF000C00FF00F9 -:101BC0000C00FF000C00FF000C00FF000C00FF00E9 -:101BD0000C00FF000C00FF000C00FF000C00FF00D9 -:101BE0000C00FF000C00FF000C00FF000C00FF00C9 -:101BF0000C00FF000C00FF000C00FF000C00FF00B9 -:101C00000C00FF000C00FF000C00FF000C00FF00A8 -:101C10000C00FF000C00FF000C00FF000C00FF0098 -:101C20000C00FF000C00FF000C00FF000C00FF0088 -:101C30000C00FF000C00FF000C00FF000C00FF0078 -:101C40000C00FF000C00FF000C00FF000C00FF0068 -:101C50000C00FF000C00FF000C00FF000C00FF0058 -:101C60000C01FF000C20FF000C00FF000C60FF00C7 -:101C70000C00FF000C20FF000C00FF000C20FF00F8 -:101C80000C00FF000C20FF000C00FF000C20FF00E8 -:101C90000C00FF000C20FF000C00FF000C20FF00D8 -:101CA0000C00FF000C20FF000C00FF000C20FF00C8 -:101CB0000C00FF000C60FF000C00FF000C20FF0078 -:101CC0000C00FF000C60FF000C00FF000C20FF0068 -:101CD0000C00FF000C60FF000C00FF000C20FF0058 -:101CE0000C00FF000C60FF000C00FF000C20FF0048 -:101CF0000C00FF000C60FF000C00FF000C20FF0038 -:101D00000C00FF000C60FF000C00FF000C20FF0027 -:101D10000C00FF000C20FF000C00FF000C22FF0055 -:101D20000C02FF000C22FF000C02FF000C20FF0041 -:101D30000C00FF000C60FF000C00FF000C22FF00F5 -:101D40000C02FF000C62FF000C02FF000C20FF00E1 -:101D50000C01FF000C21FF000C01FF0009010B0624 -:101D60000A000D000C00FF000A020D000C00FF002D -:101D70000A040D000C00FF000A060D000C00FF0015 -:101D80000A080D000C00FF000A0A0D000C00FF00FD -:101D90000A0C0D000C00FF000A0E0D000C00FF00E5 -:101DA0000A100D000C00FF000A120D000C00FF00CD -:101DB0000A140D000C00FF000A160D000C00FF00B5 -:101DC0000A180D000C00FF000A1A0D000C00FF009D -:101DD0000A1C0D000C00FF000A1E0D000C00FF0085 -:101DE0000A200D000C00FF000A220D000C00FF006D -:101DF0000A240D000C00FF000A260D000C00FF0055 -:101E00000A280D000C00FF000A2A0D000C00FF003C -:101E10000A2C0D000C00FF000A2E0D000C00FF0024 -:101E20000A300D000C00FF000A320D000C00FF000C -:101E30000A340D000C00FF000A360D000C00FF00F4 -:101E40000A380D000C00FF000A3A0D000C00FF00DC -:101E50000A3C0D000C00FF000A3E0D000C00FF00C4 -:101E60000A400D000C00FF000A420D030C00FF00A9 -:101E70000A440D010C00FF000A460D0A0C21FF0068 -:101E80000A480D0D0C23FF000A4A0D230C1BFF000E -:101E90000A4C0D370C8FFF000A4E0D450C77FF00E2 -:101EA0000A500D520CE2FF000A520D1C0C92FF006A -:101EB0000A540D1C0C52FF000A560D070C00FF00BF -:101EC0000A580D2F0CC6FF000A5A0D0B0C00FF001C -:101ED0000A5C0D300C06FF000A5E0D170C00FF00B7 -:101EE0000A600D3D0CDAFF000A620D290C00FF00AC -:101EF0000A640D3E0C41FF000A660D390C00FF001C -:101F00000A680D4C0C48FF000A6A0D490C00FF00DE -:101F10000A6C0D4C0C6CFF000A6E0D110CD2FF0008 -:101F20000A700D160C0CFF000A720D000C00FF0069 -:101F30000A740D000C80FF000A760D0F0C00FF00E4 -:101F40000A780D000C80FF000A7A0D130C00FF00C8 -:101F50000A7C0D800C00FF000A7E0D800C80FF00C3 -:101F600009050B070A000D0F0CFFFF000D000C0008 -:101F7000FF000D080C00FF000D080C00FF000D0213 -:101F80000C00FF000D000C00FF000D000C00FF0016 -:101F90000D0F0CFFFF000D000C00FF000D000C00EA -:101FA000FF000D080C00FF000D080C00FF000D00E5 -:101FB0000C00FF000D0F0CFFFF000D000C00FF00D8 -:101FC0000D000C00FF000D0F0CFFFF000D0F0CFFAC -:101FD000FF000D000C00FF000D000C00FF000D00C5 -:101FE0000C00FF000D000C00FF000D000C00FF00B6 -:101FF0000D000C00FF000D000C00FF000D000C0098 -:10200000FF000D000C00FF000D000C00FF000D0094 -:102010000C00FF000D000C00FF000D000C00FF0085 -:102020000D000C00FF000D000C00FF000D000C0067 -:10203000FF000D000C00FF000D000C00FF000D0064 -:102040000C00FF000D000C00FF000D000C00FF0055 -:102050000D000C00FF000D000C00FF000D000C0037 -:10206000FF000D000C00FF000D000C00FF000D0034 -:102070000C00FF000D000C00FF000D000C00FF0025 -:102080000D000C00FF000D000C00FF000D000C0007 -:10209000FF000D000C00FF000D000C00FF000D0004 -:1020A0000C00FF000D000C00FF000D000C00FF00F5 -:1020B0000D000C00FF000D000C00FF000D000C00D7 -:1020C000FF000D000C00FF000D000C00FF000D00D4 -:1020D0000C00FF000D000C00FF000D000C00FF00C5 -:1020E0000D000C00FF000D000C00FF000D000C00A7 -:1020F000FF000D000C00FF000D000C00FF000D00A4 -:102100000C00FF000D000C00FF000D000C00FF0094 -:102110000D000C00FF000D000C00FF000D000C0076 -:10212000FF000D000C00FF000D0F0CFFFF000D0F56 -:102130000CFFFF000D0F0CFFFF000D0F0CFFFF0049 -:102140000D020CE9FF000D060C8CFF000D060C8C37 -:10215000FF000D0F0CFFFF000D1A0C75FF000D0D99 -:102160000C8BFF000D040CE9FF000D0B0C16FF009B -:102170000D1A0C38FF000D0D0CC8FF000D040C6F7C -:10218000FF000D0B0C91FF000D0F0CFFFF000D0663 -:102190000C40FF000D060C40FF000D020C8FFF00ED -:1021A0000D0F0CFFFF000D060C62FF000D060C6208 -:1021B000FF000D020C7BFF000D0F0CFFFF000D0652 -:1021C0000C97FF000D060C97FF000D020C52FF004C -:1021D0000D0F0CFFFF000D060CF6FF000D060CF6B0 -:1021E000FF000D020C19FF000D050C55FF000D0539 -:1021F0000C55FF000D050C55FF000D050C55FF009B -:102200000D050C55FF000D050C55FF000D050C5577 -:10221000FF000D050C55FF000D140CDAFF000D0D2D -:102220000C93FF000D040CDAFF000D050C93FF006A -:102230000D140CDAFF000D0D0C93FF000D040CDAE9 -:10224000FF000D050C93FF000D000C00FF000D00BA -:102250000C00FF000D000C00FF000D000C00FF0043 -:102260000D020C00FF000E010F00FF000E020F0018 -:10227000FF000E010F01FF000E020F00FF000E0114 -:102280000F02FF000E020F00FF000E010F03FF0000 -:102290000E020F00FF000E010F04FF000E020F00E0 -:1022A000FF000E010F05FF000E020F00FF000E01E0 -:1022B0000F06FF000E020F00FF000E010F07FF00C8 -:1022C0000E020F00FF000E010F08FF000E020F00AC -:1022D000FF000E010F09FF000E020F00FF000E01AC -:1022E0000F0AFF000E020F00FF000E010F0BFF0090 -:1022F0000E020F00FF000E010F0CFF000E020F0078 -:10230000FF000E010F0DFF000E020F00FF000E0177 -:102310000F0EFF000E020F00FF000E010F0FFF0057 -:102320000E020F00FF000EB00F20FF000EB10F20B5 -:10233000FF000EB20F20FF000EB30F20FF000EB4FF -:102340000F20FF000EB50F20FF000EB60F20FF007C -:102350000EB70F20FF000EB80F20FF000EB90F20A0 -:10236000FF000EBA0F20FF000EBB0F20FF000EBCB7 -:102370000F20FF000EBD0F20FF000EBE0F20FF003C -:102380000EBF0F20FF000EF00F20FF000EF10F20F8 -:10239000FF000EF20F20FF000EF30F20FF000EF4DF -:1023A0000F20FF000EF50F20FF000EF60F20FF009C -:1023B0000EF70F20FF000EF80F20FF000EF90F2080 -:1023C000FF000EFA0F20FF000EFB0F20FF000EFC97 -:1023D0000F20FF000EFD0F20FF000EFE0F20FF005C -:1023E0000EFF0F20FF000E100FFFFF000E110FFF5A -:1023F000FF000E120FFFFF000E130FFFFF000E1461 -:102400000FFFFF000E150FFFFF000E160FFFFF005E -:102410000E170FFFFF000E180FFFFF000E190FFF22 -:10242000FF000E1A0FFFFF000E1B0FFFFF000E1C18 -:102430000FFFFF000E1D0FFFFF000E1E0F40FF00DD -:102440000E1F0FFFFF000E200FFFFF000E210FFFDA -:10245000FF000E220FFFFF000E230FFFFF000E24D0 -:102460000FFFFF000E250FFFFF000E260FFFFF00DE -:102470000E270FFFFF000E280FFFFF000E290FFF92 -:10248000FF000E2A0FFFFF000E2B0FFFFF000E2C88 -:102490000FFFFF000E2D0FFFFF000E2E0F00FF009D -:1024A0000E2F0F00FF000E300F00FF000E310F0047 -:1024B000FF000E320F00FF000E330F00FF000E343E -:1024C0000F00FF000E350F00FF000E360F00FF005B -:1024D0000E370F00FF000E380F00FF000E390F00FF -:1024E000FF000E3A0F00FF000E3B0F00FF000E3CF6 -:1024F0000F00FF000E3D0F00FF000E3E0F00FF001B -:102500000E3F0F20FF000E400F00FF000E410F0096 -:10251000FF000E420F00FF000E430F00FF000E44AD -:102520000F00FF000E450F00FF000E460F00FF00DA -:102530000E470F00FF000E480F00FF000E490F006E -:10254000FF000E4A0F00FF000E4B0F00FF000E4C65 -:102550000F00FF000E4D0F00FF000E4E0F0EFF008C -:102560000E4F0F0EFF000E500F00FF000E510F0018 -:10257000FF000E520F00FF000E530F00FF000E541D -:102580000F00FF000E550F00FF000E560F00FF005A -:102590000E570F00FF000E580F00FF000E590F00DE -:1025A000FF000E5A0F00FF000E5B0F00FF000E5CD5 -:1025B0000F00FF000E5D0F00FF000E5E0F00FF001A -:1025C0000E5F0F00FF000E600F00FF000E610F0096 -:1025D000FF000E620F00FF000E630F00FF000E648D -:1025E0000F00FF000E650F00FF000E660F00FF00DA -:1025F0000E670F00FF000E680F00FF000E690F004E -:10260000FF000E6A0F00FF000E6B0F00FF000E6C44 -:102610000F40FF000E6D0F00FF000E6E0F40FF0019 -:102620000E6F0F40FF000E700FC0FF000E710FC045 -:10263000FF000E720FC0FF000E730FC0FF000E747C -:102640000FC0FF000E750FC0FF000E760FC0FF0019 -:102650000E770FC0FF000E780FC0FF000E790FC07D -:10266000FF000E7A0FC0FF000E7B0FC0FF000E7C34 -:102670000FC0FF000E7D0FC0FF000E7E0FC0FF00D9 -:102680000E7F0FC0FF000E800F00FF000E810F00B5 -:10269000FF000E820F00FF000E830F00FF000E846C -:1026A0000F00FF000E850F00FF000E860F00FF00D9 -:1026B0000E870F00FF000E880F00FF000E890F002D -:1026C000FF000E8A0F00FF000E8B0F00FF000E8C24 -:1026D0000F00FF000E8D0F00FF000E8E0F00FF0099 -:1026E0000E8F0F00FF000E900F00FF000E910F00E5 -:1026F000FF000E920F00FF000E930F00FF000E94DC -:102700000F00FF000E950F00FF000E960F00FF0058 -:102710000E970F00FF000E980F00FF000E990F009C -:10272000FF000E9A0F00FF000E9B0F00FF000E9C93 -:102730000F00FF000E9D0F00FF000E9E0F00FF0018 -:102740000E9F0F00FF000EA00F00FF000EA10F0054 -:10275000FF000EA20F00FF000EA30F00FF000EA44B -:102760000F00FF000EA50F00FF000EA60F00FF00D8 -:102770000EA70F00FF000EA80F00FF000EA90F000C -:10278000FF000EAA0F00FF000EAB0F00FF000EAC03 -:102790000F00FF000EAD0F00FF000EAE0F00FF0098 -:1027A0000EAF0F00FF000EC00F00FF000EC10F00A4 -:1027B000FF000EC20F00FF000EC30F00FF000EC48B -:1027C0000F00FF000EC50F00FF000EC60F00FF0038 -:1027D0000EC70F00FF000EC80F00FF000EC90F004C -:1027E000FF000ECA0F00FF000ECB0F00FF000ECC43 -:1027F0000F00FF000ECD0F00FF000ECE0F00FF00F8 -:102800000ECF0F00FF000ED00F00FF000ED10F0003 -:10281000FF000ED20F00FF000ED30F00FF000ED4FA -:102820000F00FF000ED50F00FF000ED60F00FF00B7 -:102830000ED70F00FF000ED80F00FF000ED90F00BB -:10284000FF000EDA0F00FF000EDB0F00FF000EDCB2 -:102850000F00FF000EDD0F00FF000EDE0F10FF0067 -:102860000EDF0F10FF000EE00F00FF000EE10F0063 -:10287000FF000EE20F00FF000EE30F00FF000EE46A -:102880000F00FF000EE50F00FF000EE60F00FF0037 -:102890000EE70F00FF000EE80F00FF000EE90F002B -:1028A000FF000EEA0F00FF000EEB0F00FF000EEC22 -:1028B0000F00FF000EED0F00FF000EEE0F00FF00F7 -:1028C0000EEF0F00FF000E010F000E020F01FF00C0 -:1028D0000E010F010E020F01FF000E010F020E028A -:1028E0000F01FF000E010F030E020F01FF000E018A -:1028F0000F040E020F01FF000E010F050E020F0163 -:10290000FF000E010F060E020F01FF000E010F0760 -:102910000E020F01FF000E010F080E020F01FF0053 -:102920000E010F090E020F01FF000E010F0A0E0229 -:102930000F01FF000E010F0B0E020F01FF000E0131 -:102940000F0C0E020F01FF000E010F0D0E020F0102 -:10295000FF000E010F0E0E020F01FF000E010F0F00 -:102960000E020F01FF0008020B070A460D000C00C3 -:10297000FF000B070A490D000C00FF000B000A4B7B -:102980000D030C11FF000B000A4D0D010C32FF006E -:102990000B070A460D000C00FF000B070A490D004B -:1029A0000C00FF000B070A400D000C00FF000B0796 -:1029B0000A410D000C00FF000B010A400D020C4003 -:1029C000FF000B010A410D020C60FF000B070A40DB -:1029D0000D000C00FF000B070A410D000C00FF006A -:1029E0000B070A470D000C00FF000B070A4A0D00F9 -:1029F0000C00FF000B000A470D010C00FF000B004C -:102A00000A4A0D010C20FF000B070A470D000C00BD -:102A1000FF000B070A4A0D000C00FF000B070A7CA1 -:102A20000D000C00FF000B070A7E0D000C00FF00DC -:102A30000B000A000D010C1CFF000B070A7C0D00A7 -:102A40000C00FF000B070A7E0D000C00FF000B07B7 -:102A50000A440D000C00FF000B000A440D010C009D -:102A6000FF000B070A440D000C00FF000B070A4291 -:102A70000D000C00FF000B070A430D000C00FF00C7 -:102A80000B000A420D010C1AFF000B000A430D0156 -:102A90000C20FF000B070A420D000C00FF000B0783 -:102AA0000A430D000C00FF000B070A400D000C004C -:102AB000FF000B070A410D000C00FF000B010A404C -:102AC0000D020C40FF000B010A410D020C60FF00DB -:102AD0000B070A400D000C00FF000B070A410D0018 -:102AE0000C00FF000B070A440D0F0CFFFF000B0743 -:102AF0000A420D000C00FF000B070A430D000C00FA -:102B0000FF000B070A400D000C00FF000B070A41F5 -:102B10000D000C00FF000B070A510D060C40FF00D2 -:102B20000B070A500D060C40FF000B070A4F0D0360 -:102B30000C81FF000B070A530D1A0C76FF000B07E0 -:102B40000A540D0D0C8BFF000B070A550D040CE900 -:102B5000FF000B070A560D0B0C17FF000B070A5757 -:102B60000D1A0C38FF000B070A580D0D0CC9FF0099 -:102B70000B070A590D040C6FFF000B070A5A0D0BC7 -:102B80000C91FF000B070A730D140CDAFF000B0702 -:102B90000A740D0D0C93FF000B070A750D040CD978 -:102BA000FF000B070A760D050C93FF000B070A7751 -:102BB0000D140CDAFF000B070A780D0D0C93FF00C3 -:102BC0000B070A790D040CD9FF000B070A7A0D05D3 -:102BD0000C93FF000B070A5E0D030C68FF000B0748 -:102BE0000A5C0D040C31FF000B070A5D0D040C316B -:102BF000FF000B070A620D030C52FF000B070A606F -:102C00000D040C76FF000B070A610D040C76FF0023 -:102C10000B070A660D030C2EFF000B070A640D0458 -:102C20000CDAFF000B070A650D040CDAFF000B0736 -:102C30000A6A0D020CF6FF000B070A680D050C620C -:102C4000FF000B070A690D050C62FF000B060A4620 -:102C50000D0A0C22FF000B060A480D0D0C24FF0084 -:102C60000B060A6E0D110CD3FF000B060A700D1532 -:102C70000CCBFF000B060A520D200C93FF000B0635 -:102C80000A540D200C54FF000B060A4A0D270C1D98 -:102C9000FF000B060A580D2F0CC8FF000B060A5C3C -:102CA0000D300C07FF000B060A4C0D370C90FF008F -:102CB0000B060A600D3D0CDBFF000B060A640D3E9F -:102CC0000C42FF000B060A4E0D450C78FF000B0668 -:102CD0000A680D4C0C48FF000B060A6C0D4C0C6C7E -:102CE000FF000B060A500D520CE2FF000B060A42D1 -:102CF0000D020CBAFF00FF000E1E0F14FF000EDEC7 -:102D00000F20FF000EDF0F20FF000B060A780D00DA -:102D10000C40FF000B070A030D0F0CFFFF000B0711 -:102D20000A0B0D0F0CFFFF000B070A020D000C0031 -:102D3000FF000B070A0A0D000C00FF000B070A46F4 -:102D40000D000C00FF000B070A490D000C000905DF -:102D50000B000A100D000C00FF000D000C00FF001E -:102D60000D020C00FF000D000C00FF000D000C0018 -:102D7000FF000D000C00FF000D000C00FF000D0017 -:102D80000C00FF000D000C00FF000D000C00FF0008 -:102D90000D000C00FF000D000C00FF000D000C00EA -:102DA000FF000D000C00FF000D000C00FF000D00E7 -:102DB0000C00FF000D000C00FF000D000C00FF00D8 -:102DC0000D000C00FF000D000C00FF000D000C00BA -:102DD000FF000D000C00FF000D000C00FF000D00B7 -:102DE0000C00FF000D000C00FF000D000C00FF00A8 -:102DF0000D000C00FF000D000C00FF000D000C008A -:102E0000FF000D000C00FF000D000C00FF000D0086 -:102E10000C00FF000D000C00FF000D000C00FF0077 -:102E20000D000C00FF000D000C00FF000D000C0059 -:102E3000FF000D000C00FF000D000C00FF000D0056 -:102E40000C00FF000D000C00FF000D000C00FF0047 -:102E50000D000C00FF000D000C00FF000D000C0029 -:102E6000FF000D000C00FF000D000C00FF000D0026 -:102E70000C00FF0009050B010A100D010CC0FF003A -:102E80000D010CFAFF000D000C1AFF000D000C00E4 -:102E9000FF000D000C00FF000D000C00FF000D00F6 -:102EA0000C00FF000D000C00FF000D000C00FF00E7 -:102EB0000D000C00FF000D000C00FF000D000C00C9 -:102EC000FF000D000C00FF000D000C00FF000D00C6 -:102ED0000C00FF000D000C00FF000D000C00FF00B7 -:102EE0000D000C00FF000D000C00FF000D000C0099 -:102EF000FF000D000C00FF000D000C00FF000D0096 -:102F00000C00FF000D000C00FF000D000C00FF0086 -:102F10000D000C00FF000D000C00FF000D000C0068 -:102F2000FF000D000C00FF000D000C00FF000D0065 -:102F30000C00FF000D000C00FF000D000C00FF0056 -:102F40000D000C00FF000D000C00FF000D000C0038 -:102F5000FF000D000C00FF000D000C00FF000D0035 -:102F60000C00FF000D000C00FF000D000C00FF0026 -:102F70000D000C00FF000D000C00FF000D000C0008 -:102F8000FF000D000C00FF000D000C00FF000D0005 -:102F90000C00FF000D000C00FF00FF00FF00090502 -:102FA0000B020A100C46FF000C46FF000C00FF004D -:102FB0000C00FF000C00FF000C00FF000C00FF00E5 -:102FC0000C00FF000C00FF000C00FF000C00FF00D5 -:102FD0000C00FF000C00FF000C00FF000C00FF00C5 -:102FE0000C00FF000C00FF000C00FF000C00FF00B5 -:102FF0000C00FF000C00FF000C00FF000C00FF00A5 -:103000000C00FF000C00FF000C00FF000C00FF0094 -:103010000C00FF000C00FF000C00FF000C00FF0084 -:103020000C00FF000C00FF000C00FF000C00FF0074 -:103030000C00FF000C00FF000C00FF000C00FF0064 -:103040000C00FF000C00FF000C00FF000C00FF0054 -:103050000C00FF000C00FF000C00FF000C00FF0044 -:103060000C00FF0009050B030A100C00FF000C0008 -:10307000FF000C00FF000C00FF000C00FF000C0024 -:10308000FF000C00FF000C00FF000C00FF000C0014 -:10309000FF000C00FF000C00FF000C00FF000C0004 -:1030A000FF000C00FF000C00FF000C00FF000C00F4 -:1030B000FF000C00FF000C00FF000C00FF000C00E4 -:1030C000FF000C00FF000C00FF000C00FF000C00D4 -:1030D000FF000C00FF000C00FF000C00FF000C00C4 -:1030E000FF000C00FF000C00FF000C00FF000C00B4 -:1030F000FF000C00FF000C00FF000C00FF000C00A4 -:10310000FF000C00FF000C00FF000C00FF000C0093 -:10311000FF000C00FF000C00FF000C00FF000C0083 -:10312000FF000C00FF000C00FF0009050B040A1053 -:103130000C00FF000C00FF000C00FF000C00FF0063 -:103140000C00FF000C00FF000C00FF000C00FF0053 -:103150000C00FF000C00FF000C00FF000C00FF0043 -:103160000C00FF000C00FF000C00FF000C00FF0033 -:103170000C00FF000C00FF000C00FF000C00FF0023 -:103180000C00FF000C00FF000C00FF000C00FF0013 -:103190000C00FF000C00FF000C00FF000C00FF0003 -:1031A0000C00FF000C00FF000C00FF000C00FF00F3 -:1031B0000C00FF000C00FF000C00FF000C00FF00E3 -:1031C0000C00FF000C00FF000C00FF000C00FF00D3 -:1031D0000C00FF000C00FF000C00FF000C00FF00C3 -:1031E0000C00FF000C00FF000C00FF000C00FF00B3 -:1031F00009010B060A100D000C00FF000A120D0059 -:103200000C00FF000A140D000C00FF000A160D0050 -:103210000C00FF000A180D000C00FF000A1A0D0038 -:103220000C00FF000A1C0D000C00FF000A1E0D0020 -:103230000C00FF000A200D000C00FF000A220D0008 -:103240000C00FF000A240D000C00FF000A260D00F0 -:103250000C00FF000A280D000C00FF000A2A0D00D8 -:103260000C00FF000A2C0D000C00FF000A2E0D00C0 -:103270000C00FF000A300D000C00FF000A320D00A8 -:103280000C00FF000A340D000C00FF000A360D0090 -:103290000C00FF000A380D000C00FF000A3A0D0078 -:1032A0000C00FF000A3C0D000C00FF000A3E0D0060 -:1032B0000C00FF0009050B070A100D0F0CFFFF00A3 -:1032C0000D0F0CFFFF000D000C00FF000D000C00A7 -:1032D000FF000D000C00FF000D000C00FF000D00B2 -:1032E0000C00FF000D000C00FF000D000C00FF00A3 -:1032F0000D000C00FF000D000C00FF000D000C0085 -:10330000FF000D000C00FF000D000C00FF000D0081 -:103310000C00FF000D000C00FF000D000C00FF0072 -:103320000D000C00FF000D000C00FF000D000C0054 -:10333000FF000D000C00FF000D000C00FF000D0051 -:103340000C00FF000D000C00FF000D000C00FF0042 -:103350000D000C00FF000D000C00FF000D000C0024 -:10336000FF000D000C00FF000D000C00FF000D0021 -:103370000C00FF000D000C00FF000D000C00FF0012 -:103380000D000C00FF000D000C00FF000D000C00F4 -:10339000FF000D000C00FF000D000C00FF000D00F1 -:1033A0000C00FF000D000C00FF000D000C00FF00E2 -:1033B0000D000C00FF000D000C00FF000D000C00C4 -:1033C000FF000D000C00FF000D000C00FF000D00C1 -:1033D0000C00FF000D000C00FF000E010F00FF00AD -:1033E0000E020F00FF000E010F01FF000E020F0082 -:1033F000FF000E010F02FF000E020F00FF000E0182 -:103400000F03FF000E020F00FF000E010F04FF006C -:103410000E020F00FF000E010F05FF000E020F004D -:10342000FF000E010F06FF000E020F00FF000E014D -:103430000F07FF000E020F00FF000EB00F20FF006D -:103440000EB10F20FF000EB20F20FF000EB30F20B1 -:10345000FF000EB40F20FF000EB50F20FF000EB6C8 -:103460000F20FF000EB70F20FF000EF00F20FF000F -:103470000EF10F20FF000EF20F20FF000EF30F20C1 -:10348000FF000EF40F20FF000EF50F20FF000EF6D8 -:103490000F20FF000EF70F20FF000E100FFFFF00A0 -:1034A0000E110FFFFF000E120FFFFF000E130FFF94 -:1034B000FF000E140FFFFF000E150FFFFF000E168A -:1034C0000FFFFF000E170FFFFF000E200FFFFF0082 -:1034D0000E210FFFFF000E220FFFFF000E230FFF34 -:1034E000FF000E240FFFFF000E250FFFFF000E262A -:1034F0000FFFFF000E270FFFFF000E300F00FF0031 -:103500000E310F00FF000E320F00FF000E330F00D0 -:10351000FF000E340F00FF000E350F00FF000E36C7 -:103520000F00FF000E370F00FF000E400F00FF00DE -:103530000E410F00FF000E420F00FF000E430F0070 -:10354000FF000E440F00FF000E450F00FF000E4667 -:103550000F00FF000E470F00FF000E500F00FF008E -:103560000E510F00FF000E520F00FF000E530F0010 -:10357000FF000E540F00FF000E550F00FF000E5607 -:103580000F00FF000E570F00FF000E600F00FF003E -:103590000E610F00FF000E620F00FF000E630F00B0 -:1035A000FF000E640F00FF000E650F00FF000E66A7 -:1035B0000F00FF000E670F00FF000E700FC0FF002E -:1035C0000E710FC0FF000E720FC0FF000E730FC010 -:1035D000FF000E740FC0FF000E750FC0FF000E76C7 -:1035E0000FC0FF000E770FC0FF000E800F00FF001E -:1035F0000E810F00FF000E820F00FF000E830F00F0 -:10360000FF000E840F00FF000E850F00FF000E86E6 -:103610000F00FF000E870F00FF000E900F00FF004D -:103620000E910F00FF000E920F00FF000E930F008F -:10363000FF000E940F00FF000E950F00FF000E9686 -:103640000F00FF000E970F00FF000EA00F00FF00FD -:103650000EA10F00FF000EA20F00FF000EA30F002F -:10366000FF000EA40F00FF000EA50F00FF000EA626 -:103670000F00FF000EA70F00FF000EC00F00FF009D -:103680000EC10F00FF000EC20F00FF000EC30F009F -:10369000FF000EC40F00FF000EC50F00FF000EC696 -:1036A0000F00FF000EC70F00FF000ED00F00FF003D -:1036B0000ED10F00FF000ED20F00FF000ED30F003F -:1036C000FF000ED40F00FF000ED50F00FF000ED636 -:1036D0000F00FF000ED70F00FF000EE00F00FF00ED -:1036E0000EE10F00FF000EE20F00FF000EE30F00DF -:1036F000FF000EE40F00FF000EE50F00FF000EE6D6 -:103700000F00FF000EE70F00FF000E010F00FF008B -:103710000E020F01FF000E010F01FF000E020F014C -:10372000FF000E010F02FF000E020F01FF000E014D -:103730000F03FF000E020F01FF000E010F04FF0038 -:103740000E020F01FF000E010F05FF000E020F0118 -:10375000FF000E010F06FF000E020F01FF000E0119 -:103760000F07FF000E020F01FF000B070A460D00B6 -:103770000C00FF000B070A490D000C00FF000B07AF -:103780000A450D0F0CFFFF000B070A480D0F0CFF39 -:10379000FF000B070A7B0D040CCCFF000B070A7D12 -:1037A0000D040CCCFF000B070A7C0D000C00FF0081 -:1037B0000B070A7E0D000C00FF000B070A460D00E8 -:1037C0000C00FF000B070A490D000C00FF000B075F -:1037D0000A470D000C00FF000B070A4A0D000C0001 -:1037E000FF000B070A4C0D000C00FF000B070A4EF0 -:1037F0000D000C00FF000B070A4C0D000C000B071E -:103800000A4E0D000C000B070A4C0D000C280B078C -:103810000A4E0D000C280B070A4C0D000C510B072B -:103820000A4E0D000C510B070A4C0D000C7A0B07C9 -:103830000A4E0D000C7A0B070A4C0D000CA30B0767 -:103840000A4E0D000CA30B070A4C0D000CCC0B0705 -:103850000A4E0D000CCC0B070A4C0D000CF50B07A3 -:103860000A4E0D000CF50B070A4C0D010C1E0B0740 -:103870000A4E0D010C1E0B070A4C0D010C470B07DD -:103880000A4E0D010C470B070A4C0D010C700B077B -:103890000A4E0D010C700B070A4C0D010C990B0719 -:1038A0000A4E0D010C990B070A4C0D010CC20B07B7 -:1038B0000A4E0D010CC20B070A4C0D010CEB0B0755 -:1038C0000A4E0D010CEB0B070A4C0D020C140B07F2 -:1038D0000A4E0D020C140B070A4C0D020C3D0B078F -:1038E0000A4E0D020C3D0B070A4C0D020C660B072D -:1038F0000A4E0D020C660B070A4C0D020C8F0B07CB -:103900000A4E0D020C8F0B070A4C0D020CB80B0768 -:103910000A4E0D020CB80B070A4C0D020CE10B0706 -:103920000A4E0D020CE10B070A4C0D030C0A0B07A3 -:103930000A4E0D030C0A0B070A4C0D030C330B0740 -:103940000A4E0D030C330B070A4C0D030C5C0B07DE -:103950000A4E0D030C5C0B070A4C0D030C850B077C -:103960000A4E0D030C850B070A4C0D030CAE0B071A -:103970000A4E0D030CAE0B070A4C0D030CD70B07B8 -:103980000A4E0D030CD70B070A4C0D040C000B0755 -:103990000A4E0D040C000B070A4C0D040C280B07F3 -:1039A0000A4E0D040C280B070A4C0D040C510B0792 -:1039B0000A4E0D040C510B070A4C0D040C7A0B0730 -:1039C0000A4E0D040C7A0B070A4C0D040CA30B07CE -:1039D0000A4E0D040CA30B070A4C0D040CCC0B076C -:1039E0000A4E0D040CCC0B070A4C0D040CF50B070A -:1039F0000A4E0D040CF50B070A4C0D050C1E0B07A7 -:103A00000A4E0D050C1E0B070A4C0D050C470B0743 -:103A10000A4E0D050C470B070A4C0D050C700B07E1 -:103A20000A4E0D050C700B070A4C0D050C990B077F -:103A30000A4E0D050C990B070A4C0D050CC20B071D -:103A40000A4E0D050CC20B070A4C0D050CEB0B07BB -:103A50000A4E0D050CEB0B070A4C0D060C140B0758 -:103A60000A4E0D060C140B070A4C0D060C3D0B07F5 -:103A70000A4E0D060C3D0B070A4C0D060C660B0793 -:103A80000A4E0D060C660B070A4C0D060C8F0B0731 -:103A90000A4E0D060C8F0B070A4C0D060CB80B07CF -:103AA0000A4E0D060CB80B070A4C0D060CE10B076D -:103AB0000A4E0D060CE10B070A4C0D070C0A0B070A -:103AC0000A4E0D070C0A0B070A4C0D070C330B07A7 -:103AD0000A4E0D070C330B070A4C0D070C5C0B0745 -:103AE0000A4E0D070C5C0B070A4C0D070C850B07E3 -:103AF0000A4E0D070C850B070A4C0D070CAE0B0781 -:103B00000A4E0D070CAE0B070A4C0D070CD70B071E -:103B10000A4E0D070CD70B070A4C0D080C000B07BB -:103B20000A4E0D080C000B070A4C0D080C280B0759 -:103B30000A4E0D080C280B070A4C0D080C510B07F8 -:103B40000A4E0D080C510B070A4C0D080C7A0B0796 -:103B50000A4E0D080C7A0B070A4C0D080CA30B0734 -:103B60000A4E0D080CA30B070A4C0D080CCC0B07D2 -:103B70000A4E0D080CCC0B070A4C0D080CF50B0770 -:103B80000A4E0D080CF50B070A4C0D090C1E0B070D -:103B90000A4E0D090C1E0B070A4C0D090C470B07AA -:103BA0000A4E0D090C470B070A4C0D090C700B0748 -:103BB0000A4E0D090C700B070A4C0D090C990B07E6 -:103BC0000A4E0D090C990B070A4C0D090CC20B0784 -:103BD0000A4E0D090CC20B070A4C0D090CEB0B0722 -:103BE0000A4E0D090CEB0B070A4C0D0A0C140B07BF -:103BF0000A4E0D0A0C140B070A4C0D0A0C3D0B075C -:103C00000A4E0D0A0C3D0B070A4C0D0A0C660B07F9 -:103C10000A4E0D0A0C660B070A4C0D0A0C8F0B0797 -:103C20000A4E0D0A0C8F0B070A4C0D0A0CB80B0735 -:103C30000A4E0D0A0CB80B070A4C0D0A0CE10B07D3 -:103C40000A4E0D0A0CE10B070A4C0D0B0C0A0B0770 -:103C50000A4E0D0B0C0A0B070A4C0D0B0C330B070D -:103C60000A4E0D0B0C330B070A4C0D0B0C5C0B07AB -:103C70000A4E0D0B0C5C0B070A4C0D0B0C850B0749 -:103C80000A4E0D0B0C850B070A4C0D0B0CAE0B07E7 -:103C90000A4E0D0B0CAE0B070A4C0D0B0CD70B0785 -:103CA0000A4E0D0B0CD70B070A4C0D0C0C000B0722 -:103CB0000A4E0D0C0C000B070A4C0D0C0C280B07C0 -:103CC0000A4E0D0C0C280B070A4C0D0C0C510B075F -:103CD0000A4E0D0C0C510B070A4C0D0C0C7A0B07FD -:103CE0000A4E0D0C0C7A0B070A4C0D0C0CA30B079B -:103CF0000A4E0D0C0CA30B070A4C0D0C0CCC0B0739 -:103D00000A4E0D0C0CCC0B070A4C0D0C0CF50B07D6 -:103D10000A4E0D0C0CF50B070A4C0D0D0C1E0B0773 -:103D20000A4E0D0D0C1E0B070A4C0D0D0C470B0710 -:103D30000A4E0D0D0C470B070A4C0D0D0C700B07AE -:103D40000A4E0D0D0C700B070A4C0D0D0C990B074C -:103D50000A4E0D0D0C990B070A4C0D0D0CC20B07EA -:103D60000A4E0D0D0CC20B070A4C0D0D0CEB0B0788 -:103D70000A4E0D0D0CEB0B070A4C0D0E0C140B0725 -:103D80000A4E0D0E0C140B070A4C0D0E0C3D0B07C2 -:103D90000A4E0D0E0C3D0B070A4C0D0E0C660B0760 -:103DA0000A4E0D0E0C660B070A4C0D0E0C8F0B07FE -:103DB0000A4E0D0E0C8F0B070A4C0D0E0CB80B079C -:103DC0000A4E0D0E0CB80B070A4C0D0E0CE10B073A -:103DD0000A4E0D0E0CE10B070A4C0D0F0C0A0B07D7 -:103DE0000A4E0D0F0C0A0B070A4C0D0F0C330B0774 -:103DF0000A4E0D0F0C330B070A4C0D0F0C5C0B0712 -:103E00000A4E0D0F0C5C0B070A4C0D0F0C850B07AF -:103E10000A4E0D0F0C850B070A4C0D0F0CAE0B074D -:103E20000A4E0D0F0CAE0B070A4C0D0F0CD70B07EB -:103E30000A4E0D0F0CD70B070A4C0D0F0CFF0B078A -:0A3E40000A4E0D0F0CFF0800FF00F2 -:00000001FF diff --git a/fs/9p/cache.c b/fs/9p/cache.c index 103ca5e1267beb2229999e0711e50ba83f4c0abb..64c58eb26159324245a7581a67bfe5a5afd9f552 100644 --- a/fs/9p/cache.c +++ b/fs/9p/cache.c @@ -151,34 +151,6 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data, return FSCACHE_CHECKAUX_OKAY; } -static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data) -{ - struct v9fs_inode *v9inode = cookie_netfs_data; - struct pagevec pvec; - pgoff_t first; - int loop, nr_pages; - - pagevec_init(&pvec, 0); - first = 0; - - for (;;) { - nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping, - first, - PAGEVEC_SIZE - pagevec_count(&pvec)); - if (!nr_pages) - break; - - for (loop = 0; loop < nr_pages; loop++) - ClearPageFsCache(pvec.pages[loop]); - - first = pvec.pages[nr_pages - 1]->index + 1; - - pvec.nr = nr_pages; - pagevec_release(&pvec); - cond_resched(); - } -} - const struct fscache_cookie_def v9fs_cache_inode_index_def = { .name = "9p.inode", .type = FSCACHE_COOKIE_TYPE_DATAFILE, @@ -186,7 +158,6 @@ const struct fscache_cookie_def v9fs_cache_inode_index_def = { .get_attr = v9fs_cache_inode_get_attr, .get_aux = v9fs_cache_inode_get_aux, .check_aux = v9fs_cache_inode_check_aux, - .now_uncached = v9fs_cache_inode_now_uncached, }; void v9fs_cache_inode_get_cookie(struct inode *inode) diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3de3b4a89d89a16a2f23b63a990f8959568583df..03c9e325bfbc1f41e785d45aed5d563b778f959f 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -288,7 +288,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) fl->fl_end = OFFSET_MAX; else fl->fl_end = glock.start + glock.length - 1; - fl->fl_pid = glock.proc_id; + fl->fl_pid = -glock.proc_id; } kfree(glock.client_id); return res; @@ -445,7 +445,7 @@ static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end, struct p9_wstat wstat; int retval; - retval = filemap_write_and_wait_range(inode->i_mapping, start, end); + retval = file_write_and_wait_range(filp, start, end); if (retval) return retval; @@ -468,7 +468,7 @@ int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end, struct inode *inode = filp->f_mapping->host; int retval; - retval = filemap_write_and_wait_range(inode->i_mapping, start, end); + retval = file_write_and_wait_range(filp, start, end); if (retval) return retval; diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index b573c3b9a3287014c469ea957be95546a23c8b77..8cf941c3b511d681249dcaf7364cd4e172e595a1 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c @@ -450,7 +450,7 @@ affs_error(struct super_block *sb, const char *function, const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; pr_crit("error (device %s): %s(): %pV\n", sb->s_id, function, &vaf); - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) pr_warn("Remounting filesystem read-only\n"); sb->s_flags |= MS_RDONLY; va_end(args); diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index 675148950fed973963f8229c41f964070fe60039..2b2112475ec20675c787f67f351910ffec5ee6c6 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c @@ -19,7 +19,7 @@ affs_count_free_blocks(struct super_block *sb) pr_debug("%s()\n", __func__); - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; mutex_lock(&AFFS_SB(sb)->s_bmlock); diff --git a/fs/affs/file.c b/fs/affs/file.c index 196ee7f6fdc40e45235178b55abbc54461fbbb49..00331810f69084162d08c1fff7272d47050e2a0a 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -954,7 +954,7 @@ int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) struct inode *inode = filp->f_mapping->host; int ret, err; - err = filemap_write_and_wait_range(inode->i_mapping, start, end); + err = file_write_and_wait_range(filp, start, end); if (err) return err; diff --git a/fs/affs/super.c b/fs/affs/super.c index 7bf47a41cb4f759e4006e3497330bbefe8602b28..884bedab7266a528b60884c7ab3d91e9a703724d 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -80,7 +80,7 @@ void affs_mark_sb_dirty(struct super_block *sb) struct affs_sb_info *sbi = AFFS_SB(sb); unsigned long delay; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; spin_lock(&sbi->work_lock); @@ -464,7 +464,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) * not recommended. */ if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS - || chksum == MUFS_DCOFS) && !(sb->s_flags & MS_RDONLY)) { + || chksum == MUFS_DCOFS) && !sb_rdonly(sb)) { pr_notice("Dircache FS - mounting %s read only\n", sb->s_id); sb->s_flags |= MS_RDONLY; } @@ -596,7 +596,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) memcpy(sbi->s_volume, volume, 32); spin_unlock(&sbi->symlink_lock); - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) return 0; if (*flags & MS_RDONLY) diff --git a/fs/afs/cache.c b/fs/afs/cache.c index 577763c3d88bb51e1ee41003298a4b545a1bb2fb..1fe855191261fce57a85be27f59690743957ecd6 100644 --- a/fs/afs/cache.c +++ b/fs/afs/cache.c @@ -39,7 +39,6 @@ static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, const void *buffer, uint16_t buflen); -static void afs_vnode_cache_now_uncached(void *cookie_netfs_data); struct fscache_netfs afs_cache_netfs = { .name = "afs", @@ -75,7 +74,6 @@ struct fscache_cookie_def afs_vnode_cache_index_def = { .get_attr = afs_vnode_cache_get_attr, .get_aux = afs_vnode_cache_get_aux, .check_aux = afs_vnode_cache_check_aux, - .now_uncached = afs_vnode_cache_now_uncached, }; /* @@ -359,44 +357,3 @@ static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, _leave(" = SUCCESS"); return FSCACHE_CHECKAUX_OKAY; } - -/* - * indication the cookie is no longer uncached - * - this function is called when the backing store currently caching a cookie - * is removed - * - the netfs should use this to clean up any markers indicating cached pages - * - this is mandatory for any object that may have data - */ -static void afs_vnode_cache_now_uncached(void *cookie_netfs_data) -{ - struct afs_vnode *vnode = cookie_netfs_data; - struct pagevec pvec; - pgoff_t first; - int loop, nr_pages; - - _enter("{%x,%x,%Lx}", - vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version); - - pagevec_init(&pvec, 0); - first = 0; - - for (;;) { - /* grab a bunch of pages to clean */ - nr_pages = pagevec_lookup(&pvec, vnode->vfs_inode.i_mapping, - first, - PAGEVEC_SIZE - pagevec_count(&pvec)); - if (!nr_pages) - break; - - for (loop = 0; loop < nr_pages; loop++) - ClearPageFsCache(pvec.pages[loop]); - - first = pvec.pages[nr_pages - 1]->index + 1; - - pvec.nr = nr_pages; - pagevec_release(&pvec); - cond_resched(); - } - - _leave(""); -} diff --git a/fs/afs/misc.c b/fs/afs/misc.c index 100b207efc9eaddff4ed9f7e0e4415ed62ba2880..c05f1f1c0d4161a1c48a370dea1d6ca5a6d59eda 100644 --- a/fs/afs/misc.c +++ b/fs/afs/misc.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "internal.h" #include "afs_fs.h" diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 02781e78ffb69683d529a2930fa2f6b3d552e64a..0bf191f0dbafa7d65277f227cabc4578e707eac5 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -14,7 +14,6 @@ #include #include -#include #include "internal.h" #include "afs_cm.h" @@ -292,6 +291,19 @@ static void afs_load_bvec(struct afs_call *call, struct msghdr *msg, iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC, bv, nr, bytes); } +/* + * Advance the AFS call state when the RxRPC call ends the transmit phase. + */ +static void afs_notify_end_request_tx(struct sock *sock, + struct rxrpc_call *rxcall, + unsigned long call_user_ID) +{ + struct afs_call *call = (struct afs_call *)call_user_ID; + + if (call->state == AFS_CALL_REQUESTING) + call->state = AFS_CALL_AWAIT_REPLY; +} + /* * attach the data from a bunch of pages on an inode to a call */ @@ -311,14 +323,8 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg) bytes = msg->msg_iter.count; nr = msg->msg_iter.nr_segs; - /* Have to change the state *before* sending the last - * packet as RxRPC might give us the reply before it - * returns from sending the request. - */ - if (first + nr - 1 >= last) - call->state = AFS_CALL_AWAIT_REPLY; - ret = rxrpc_kernel_send_data(afs_socket, call->rxcall, - msg, bytes); + ret = rxrpc_kernel_send_data(afs_socket, call->rxcall, msg, + bytes, afs_notify_end_request_tx); for (loop = 0; loop < nr; loop++) put_page(bv[loop].bv_page); if (ret < 0) @@ -410,7 +416,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, if (!call->send_pages) call->state = AFS_CALL_AWAIT_REPLY; ret = rxrpc_kernel_send_data(afs_socket, rxcall, - &msg, call->request_size); + &msg, call->request_size, + afs_notify_end_request_tx); if (ret < 0) goto error_do_abort; @@ -741,6 +748,20 @@ static int afs_deliver_cm_op_id(struct afs_call *call) return call->type->deliver(call); } +/* + * Advance the AFS call state when an RxRPC service call ends the transmit + * phase. + */ +static void afs_notify_end_reply_tx(struct sock *sock, + struct rxrpc_call *rxcall, + unsigned long call_user_ID) +{ + struct afs_call *call = (struct afs_call *)call_user_ID; + + if (call->state == AFS_CALL_REPLYING) + call->state = AFS_CALL_AWAIT_ACK; +} + /* * send an empty reply */ @@ -760,7 +781,8 @@ void afs_send_empty_reply(struct afs_call *call) msg.msg_flags = 0; call->state = AFS_CALL_AWAIT_ACK; - switch (rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, 0)) { + switch (rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, 0, + afs_notify_end_reply_tx)) { case 0: _leave(" [replied]"); return; @@ -798,7 +820,8 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) msg.msg_flags = 0; call->state = AFS_CALL_AWAIT_ACK; - n = rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, len); + n = rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, len, + afs_notify_end_reply_tx); if (n >= 0) { /* Success */ _leave(" [replied]"); diff --git a/fs/afs/write.c b/fs/afs/write.c index 2d2fccd5044bcd9b02127246824c1221ec502484..106e43db11153fc1faed12ab326e25d4a9dc3c7d 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -714,7 +714,7 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync) vnode->fid.vid, vnode->fid.vnode, file, datasync); - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(file, start, end); if (ret) return ret; inode_lock(inode); diff --git a/fs/aio.c b/fs/aio.c index dcad3a66748c041a48588b612f85fae78086f5f5..5a2487217072d18b1b5a25b6961e6cdd938375fc 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -373,6 +373,14 @@ static int aio_migratepage(struct address_space *mapping, struct page *new, pgoff_t idx; int rc; + /* + * We cannot support the _NO_COPY case here, because copy needs to + * happen under the ctx->completion_lock. That does not work with the + * migration workflow of MIGRATE_SYNC_NO_COPY. + */ + if (mode == MIGRATE_SYNC_NO_COPY) + return -EINVAL; + rc = 0; /* mapping->private_lock here protects against the kioctx teardown. */ @@ -441,10 +449,9 @@ static const struct address_space_operations aio_ctx_aops = { #endif }; -static int aio_setup_ring(struct kioctx *ctx) +static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events) { struct aio_ring *ring; - unsigned nr_events = ctx->max_reqs; struct mm_struct *mm = current->mm; unsigned long size, unused; int nr_pages; @@ -706,6 +713,12 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) struct kioctx *ctx; int err = -ENOMEM; + /* + * Store the original nr_events -- what userspace passed to io_setup(), + * for counting against the global limit -- before it changes. + */ + unsigned int max_reqs = nr_events; + /* * We keep track of the number of available ringbuffer slots, to prevent * overflow (reqs_available), and we also use percpu counters for this. @@ -724,14 +737,14 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) return ERR_PTR(-EINVAL); } - if (!nr_events || (unsigned long)nr_events > (aio_max_nr * 2UL)) + if (!nr_events || (unsigned long)max_reqs > aio_max_nr) return ERR_PTR(-EAGAIN); ctx = kmem_cache_zalloc(kioctx_cachep, GFP_KERNEL); if (!ctx) return ERR_PTR(-ENOMEM); - ctx->max_reqs = nr_events; + ctx->max_reqs = max_reqs; spin_lock_init(&ctx->ctx_lock); spin_lock_init(&ctx->completion_lock); @@ -753,7 +766,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) if (!ctx->cpu) goto err; - err = aio_setup_ring(ctx); + err = aio_setup_ring(ctx, nr_events); if (err < 0) goto err; @@ -764,8 +777,8 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) /* limit the number of system wide aios */ spin_lock(&aio_nr_lock); - if (aio_nr + nr_events > (aio_max_nr * 2UL) || - aio_nr + nr_events < aio_nr) { + if (aio_nr + ctx->max_reqs > aio_max_nr || + aio_nr + ctx->max_reqs < aio_nr) { spin_unlock(&aio_nr_lock); err = -EAGAIN; goto err_ctx; @@ -1593,12 +1606,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, goto out_put_req; } - if ((req->common.ki_flags & IOCB_NOWAIT) && - !(req->common.ki_flags & IOCB_DIRECT)) { - ret = -EOPNOTSUPP; - goto out_put_req; - } - ret = put_user(KIOCB_KEY, &user_iocb->aio_key); if (unlikely(ret)) { pr_debug("EFAULT: aio_key\n"); diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index beef981aa54f34f40478b019f2afe7e0d81d4c7b..4737615f0eaaa4a43e3050b4adc4aa20ba2850a3 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -11,10 +11,21 @@ #include #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include /* This is the range of ioctl() numbers we claim as ours */ #define AUTOFS_IOC_FIRST AUTOFS_IOC_READY @@ -24,17 +35,6 @@ #define AUTOFS_DEV_IOCTL_IOC_COUNT \ (AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD - AUTOFS_DEV_IOCTL_VERSION_CMD) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #ifdef pr_fmt #undef pr_fmt #endif diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index dd9f1bebb5a3a980b55e5d0fb758c93e4f694722..b7c816f3940402f21002cb6e6cbc391b35cb32b9 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -93,17 +93,17 @@ static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param) * at the end of the struct. */ static struct autofs_dev_ioctl * - copy_dev_ioctl(struct autofs_dev_ioctl __user *in) +copy_dev_ioctl(struct autofs_dev_ioctl __user *in) { struct autofs_dev_ioctl tmp, *res; - if (copy_from_user(&tmp, in, sizeof(tmp))) + if (copy_from_user(&tmp, in, AUTOFS_DEV_IOCTL_SIZE)) return ERR_PTR(-EFAULT); - if (tmp.size < sizeof(tmp)) + if (tmp.size < AUTOFS_DEV_IOCTL_SIZE) return ERR_PTR(-EINVAL); - if (tmp.size > (PATH_MAX + sizeof(tmp))) + if (tmp.size > AUTOFS_DEV_IOCTL_SIZE + PATH_MAX) return ERR_PTR(-ENAMETOOLONG); res = memdup_user(in, tmp.size); @@ -133,8 +133,8 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) goto out; } - if (param->size > sizeof(*param)) { - err = invalid_str(param->path, param->size - sizeof(*param)); + if (param->size > AUTOFS_DEV_IOCTL_SIZE) { + err = invalid_str(param->path, param->size - AUTOFS_DEV_IOCTL_SIZE); if (err) { pr_warn( "path string terminator missing for cmd(0x%08x)\n", @@ -258,11 +258,6 @@ static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid) if (err) goto out; - /* - * Find autofs super block that has the device number - * corresponding to the autofs fs we want to open. - */ - filp = dentry_open(&path, O_RDONLY, current_cred()); path_put(&path); if (IS_ERR(filp)) { @@ -451,7 +446,7 @@ static int autofs_dev_ioctl_requester(struct file *fp, dev_t devid; int err = -ENOENT; - if (param->size <= sizeof(*param)) { + if (param->size <= AUTOFS_DEV_IOCTL_SIZE) { err = -EINVAL; goto out; } @@ -539,7 +534,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp, unsigned int devid, magic; int err = -ENOENT; - if (param->size <= sizeof(*param)) { + if (param->size <= AUTOFS_DEV_IOCTL_SIZE) { err = -EINVAL; goto out; } @@ -628,10 +623,6 @@ static int _autofs_dev_ioctl(unsigned int command, ioctl_fn fn = NULL; int err = 0; - /* only root can play with this */ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST); cmd = _IOC_NR(command); @@ -640,6 +631,14 @@ static int _autofs_dev_ioctl(unsigned int command, return -ENOTTY; } + /* Only root can use ioctls other than AUTOFS_DEV_IOCTL_VERSION_CMD + * and AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD + */ + if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD && + cmd != AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD && + !capable(CAP_SYS_ADMIN)) + return -EPERM; + /* Copy the parameters into kernel space. */ param = copy_dev_ioctl(user); if (IS_ERR(param)) @@ -706,7 +705,8 @@ static int _autofs_dev_ioctl(unsigned int command, return err; } -static long autofs_dev_ioctl(struct file *file, uint command, ulong u) +static long autofs_dev_ioctl(struct file *file, unsigned int command, + unsigned long u) { int err; @@ -715,9 +715,10 @@ static long autofs_dev_ioctl(struct file *file, uint command, ulong u) } #ifdef CONFIG_COMPAT -static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u) +static long autofs_dev_ioctl_compat(struct file *file, unsigned int command, + unsigned long u) { - return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u)); + return autofs_dev_ioctl(file, command, (unsigned long) compat_ptr(u)); } #else #define autofs_dev_ioctl_compat NULL @@ -733,7 +734,8 @@ static const struct file_operations _dev_ioctl_fops = { static struct miscdevice _autofs_dev_ioctl_misc = { .minor = AUTOFS_MINOR, .name = AUTOFS_DEVICE_NAME, - .fops = &_dev_ioctl_fops + .fops = &_dev_ioctl_fops, + .mode = 0644, }; MODULE_ALIAS_MISCDEV(AUTOFS_MINOR); diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 24a58bf9ca72ce3b51f1188162594654de1c4f82..4ac49d038bf38f3745888e82214491e64aa6da9a 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -56,19 +56,14 @@ static int autofs4_write(struct autofs_sb_info *sbi, struct file *file, const void *addr, int bytes) { unsigned long sigpipe, flags; - mm_segment_t fs; const char *data = (const char *)addr; ssize_t wr = 0; sigpipe = sigismember(¤t->pending.signal, SIGPIPE); - /* Save pointer to user space and point back to kernel space */ - fs = get_fs(); - set_fs(KERNEL_DS); - mutex_lock(&sbi->pipe_mutex); while (bytes) { - wr = __vfs_write(file, data, bytes, &file->f_pos); + wr = __kernel_write(file, data, bytes, &file->f_pos); if (wr <= 0) break; data += wr; @@ -76,8 +71,6 @@ static int autofs4_write(struct autofs_sb_info *sbi, } mutex_unlock(&sbi->pipe_mutex); - set_fs(fs); - /* Keep the currently executing process from receiving a * SIGPIPE unless it was already supposed to get one */ diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 4a4a5a3661583ca4c88e2abe0f169686cd7b481c..a92355cc453bf6cb09016e7f30fdba677c44bb48 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -838,7 +838,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) befs_debug(sb, "---> %s", __func__); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { befs_warning(sb, "No write support. Marking filesystem read-only"); sb->s_flags |= MS_RDONLY; diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 9be82c4e14a409a4872094190ea63aa23ef0c1d1..ce1824f47ba6a32222e4df6cea90099de101b9f8 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -341,11 +341,12 @@ static int load_aout_library(struct file *file) unsigned long error; int retval; struct exec ex; + loff_t pos = 0; inode = file_inode(file); retval = -ENOEXEC; - error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); + error = kernel_read(file, &ex, sizeof(ex), &pos); if (error != sizeof(ex)) goto out; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 879ff9c7ffd01a0f1f2d6a7e92c32926af5ef4c2..73b01e474fdc630bcc71e6c883d59b5009b64502 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -252,7 +252,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid)); NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid)); NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid)); - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); + NEW_AUX_ENT(AT_SECURE, bprm->secureexec); NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes); #ifdef ELF_HWCAP2 NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2); @@ -409,6 +409,7 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, { struct elf_phdr *elf_phdata = NULL; int retval, size, err = -1; + loff_t pos = elf_ex->e_phoff; /* * If the size of this structure has changed, then punt, since @@ -432,8 +433,7 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, goto out; /* Read in the program headers */ - retval = kernel_read(elf_file, elf_ex->e_phoff, - (char *)elf_phdata, size); + retval = kernel_read(elf_file, elf_phdata, size, &pos); if (retval != size) { err = (retval < 0) ? retval : -EIO; goto out; @@ -664,8 +664,7 @@ static unsigned long randomize_stack_top(unsigned long stack_top) { unsigned long random_variable = 0; - if ((current->flags & PF_RANDOMIZE) && - !(current->personality & ADDR_NO_RANDOMIZE)) { + if (current->flags & PF_RANDOMIZE) { random_variable = get_random_long(); random_variable &= STACK_RND_MASK; random_variable <<= PAGE_SHIFT; @@ -699,6 +698,7 @@ static int load_elf_binary(struct linux_binprm *bprm) struct elfhdr interp_elf_ex; } *loc; struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE; + loff_t pos; loc = kmalloc(sizeof(*loc), GFP_KERNEL); if (!loc) { @@ -751,9 +751,9 @@ static int load_elf_binary(struct linux_binprm *bprm) if (!elf_interpreter) goto out_free_ph; - retval = kernel_read(bprm->file, elf_ppnt->p_offset, - elf_interpreter, - elf_ppnt->p_filesz); + pos = elf_ppnt->p_offset; + retval = kernel_read(bprm->file, elf_interpreter, + elf_ppnt->p_filesz, &pos); if (retval != elf_ppnt->p_filesz) { if (retval >= 0) retval = -EIO; @@ -777,9 +777,9 @@ static int load_elf_binary(struct linux_binprm *bprm) would_dump(bprm, interpreter); /* Get the exec headers */ - retval = kernel_read(interpreter, 0, - (void *)&loc->interp_elf_ex, - sizeof(loc->interp_elf_ex)); + pos = 0; + retval = kernel_read(interpreter, &loc->interp_elf_ex, + sizeof(loc->interp_elf_ex), &pos); if (retval != sizeof(loc->interp_elf_ex)) { if (retval >= 0) retval = -EIO; @@ -1176,9 +1176,10 @@ static int load_elf_library(struct file *file) unsigned long elf_bss, bss, len; int retval, error, i, j; struct elfhdr elf_ex; + loff_t pos = 0; error = -ENOEXEC; - retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex)); + retval = kernel_read(file, &elf_ex, sizeof(elf_ex), &pos); if (retval != sizeof(elf_ex)) goto out; @@ -1202,7 +1203,8 @@ static int load_elf_library(struct file *file) eppnt = elf_phdata; error = -ENOEXEC; - retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j); + pos = elf_ex.e_phoff; + retval = kernel_read(file, eppnt, j, &pos); if (retval != j) goto out_free_ph; diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index cf93a4fad01218575e3b0f4c9b2806a2b16111dc..e70c039ac19067f1a0b490bf2ffe8d5c0ba52498 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -145,6 +145,7 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct elf32_phdr *phdr; unsigned long size; int retval, loop; + loff_t pos = params->hdr.e_phoff; if (params->hdr.e_phentsize != sizeof(struct elf_phdr)) return -ENOMEM; @@ -156,8 +157,7 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, if (!params->phdrs) return -ENOMEM; - retval = kernel_read(file, params->hdr.e_phoff, - (char *) params->phdrs, size); + retval = kernel_read(file, params->phdrs, size, &pos); if (unlikely(retval != size)) return retval < 0 ? retval : -ENOEXEC; @@ -199,6 +199,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) char *interpreter_name = NULL; int executable_stack; int retval, i; + loff_t pos; kdebug("____ LOAD %d ____", current->pid); @@ -246,10 +247,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) if (!interpreter_name) goto error; - retval = kernel_read(bprm->file, - phdr->p_offset, - interpreter_name, - phdr->p_filesz); + pos = phdr->p_offset; + retval = kernel_read(bprm->file, interpreter_name, + phdr->p_filesz, &pos); if (unlikely(retval != phdr->p_filesz)) { if (retval >= 0) retval = -ENOEXEC; @@ -277,8 +277,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) */ would_dump(bprm, interpreter); - retval = kernel_read(interpreter, 0, bprm->buf, - BINPRM_BUF_SIZE); + pos = 0; + retval = kernel_read(interpreter, bprm->buf, + BINPRM_BUF_SIZE, &pos); if (unlikely(retval != BINPRM_BUF_SIZE)) { if (retval >= 0) retval = -ENOEXEC; @@ -650,7 +651,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, NEW_AUX_ENT(AT_EUID, (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid)); NEW_AUX_ENT(AT_GID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->gid)); NEW_AUX_ENT(AT_EGID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->egid)); - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); + NEW_AUX_ENT(AT_SECURE, bprm->secureexec); NEW_AUX_ENT(AT_EXECFN, bprm->exec); #ifdef ARCH_DLINFO diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index a1e6860b6f46a091e28855eb5b6ed48c937aebac..475d083f808845db1949bf471238158777935317 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -176,41 +176,32 @@ static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ -static int decompress_exec( - struct linux_binprm *bprm, - unsigned long offset, - char *dst, - long len, - int fd) +static int decompress_exec(struct linux_binprm *bprm, loff_t fpos, char *dst, + long len, int fd) { unsigned char *buf; z_stream strm; - loff_t fpos; int ret, retval; - pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n", offset, dst, len); + pr_debug("decompress_exec(offset=%llx,buf=%p,len=%lx)\n", fpos, dst, len); memset(&strm, 0, sizeof(strm)); strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); - if (strm.workspace == NULL) { - pr_debug("no memory for decompress workspace\n"); + if (!strm.workspace) return -ENOMEM; - } + buf = kmalloc(LBUFSIZE, GFP_KERNEL); - if (buf == NULL) { - pr_debug("no memory for read buffer\n"); + if (!buf) { retval = -ENOMEM; goto out_free; } /* Read in first chunk of data and parse gzip header. */ - fpos = offset; - ret = kernel_read(bprm->file, offset, buf, LBUFSIZE); + ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos); strm.next_in = buf; strm.avail_in = ret; strm.total_in = 0; - fpos += ret; retval = -ENOEXEC; @@ -276,7 +267,7 @@ static int decompress_exec( } while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { - ret = kernel_read(bprm->file, fpos, buf, LBUFSIZE); + ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos); if (ret <= 0) break; len -= ret; @@ -284,7 +275,6 @@ static int decompress_exec( strm.next_in = buf; strm.avail_in = ret; strm.total_in = 0; - fpos += ret; } if (ret < 0) { @@ -890,7 +880,7 @@ static int load_flat_shared_library(int id, struct lib_info *libs) * as we're past the point of no return and are dealing with shared * libraries. */ - bprm.cred_prepared = 1; + bprm.called_set_creds = 1; res = prepare_binprm(&bprm); diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index f4718098ac31885b64ebaba7c03af5fe75515092..2a46762def315638e31a2042a3e2d7ccd06a52de 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -54,7 +54,7 @@ typedef struct { int size; /* size of magic/mask */ char *magic; /* magic or filename extension */ char *mask; /* mask, NULL for exact match */ - char *interpreter; /* filename of interpreter */ + const char *interpreter; /* filename of interpreter */ char *name; struct dentry *dentry; struct file *interp_file; @@ -131,27 +131,26 @@ static int load_misc_binary(struct linux_binprm *bprm) { Node *fmt; struct file *interp_file = NULL; - char iname[BINPRM_BUF_SIZE]; - const char *iname_addr = iname; int retval; int fd_binary = -1; retval = -ENOEXEC; if (!enabled) - goto ret; + return retval; /* to keep locking time low, we copy the interpreter string */ read_lock(&entries_lock); fmt = check_file(bprm); if (fmt) - strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE); + dget(fmt->dentry); read_unlock(&entries_lock); if (!fmt) - goto ret; + return retval; /* Need to be able to load the file after exec */ + retval = -ENOENT; if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) - return -ENOENT; + goto ret; if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { retval = remove_arg_zero(bprm); @@ -195,22 +194,22 @@ static int load_misc_binary(struct linux_binprm *bprm) bprm->argc++; /* add the interp as argv[0] */ - retval = copy_strings_kernel(1, &iname_addr, bprm); + retval = copy_strings_kernel(1, &fmt->interpreter, bprm); if (retval < 0) goto error; bprm->argc++; /* Update interp in case binfmt_script needs it. */ - retval = bprm_change_interp(iname, bprm); + retval = bprm_change_interp(fmt->interpreter, bprm); if (retval < 0) goto error; - if (fmt->flags & MISC_FMT_OPEN_FILE && fmt->interp_file) { + if (fmt->flags & MISC_FMT_OPEN_FILE) { interp_file = filp_clone_open(fmt->interp_file); if (!IS_ERR(interp_file)) deny_write_access(interp_file); } else { - interp_file = open_exec(iname); + interp_file = open_exec(fmt->interpreter); } retval = PTR_ERR(interp_file); if (IS_ERR(interp_file)) @@ -218,12 +217,15 @@ static int load_misc_binary(struct linux_binprm *bprm) bprm->file = interp_file; if (fmt->flags & MISC_FMT_CREDENTIALS) { + loff_t pos = 0; + /* * No need to call prepare_binprm(), it's already been * done. bprm->buf is stale, update from interp_file. */ memset(bprm->buf, 0, BINPRM_BUF_SIZE); - retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE); + retval = kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, + &pos); } else retval = prepare_binprm(bprm); @@ -235,6 +237,7 @@ static int load_misc_binary(struct linux_binprm *bprm) goto error; ret: + dput(fmt->dentry); return retval; error: if (fd_binary > 0) @@ -591,8 +594,13 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode) static void bm_evict_inode(struct inode *inode) { + Node *e = inode->i_private; + + if (e->flags & MISC_FMT_OPEN_FILE) + filp_close(e->interp_file, NULL); + clear_inode(inode); - kfree(inode->i_private); + kfree(e); } static void kill_node(Node *e) @@ -600,24 +608,14 @@ static void kill_node(Node *e) struct dentry *dentry; write_lock(&entries_lock); - dentry = e->dentry; - if (dentry) { - list_del_init(&e->list); - e->dentry = NULL; - } + list_del_init(&e->list); write_unlock(&entries_lock); - if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) { - filp_close(e->interp_file, NULL); - e->interp_file = NULL; - } - - if (dentry) { - drop_nlink(d_inode(dentry)); - d_drop(dentry); - dput(dentry); - simple_release_fs(&bm_mnt, &entry_count); - } + dentry = e->dentry; + drop_nlink(d_inode(dentry)); + d_drop(dentry); + dput(dentry); + simple_release_fs(&bm_mnt, &entry_count); } /* / */ @@ -662,7 +660,8 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, root = file_inode(file)->i_sb->s_root; inode_lock(d_inode(root)); - kill_node(e); + if (!list_empty(&e->list)) + kill_node(e); inode_unlock(d_inode(root)); break; @@ -791,7 +790,7 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, inode_lock(d_inode(root)); while (!list_empty(&entries)) - kill_node(list_entry(entries.next, Node, list)); + kill_node(list_first_entry(&entries, Node, list)); inode_unlock(d_inode(root)); break; diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c index afdf4e3cafc2aa5f1c1ff1dc0e8cfb256c6a3b89..7cde3f46ad263ab084aafaefa14161902f33d4f1 100644 --- a/fs/binfmt_script.c +++ b/fs/binfmt_script.c @@ -19,7 +19,6 @@ static int load_script(struct linux_binprm *bprm) const char *i_arg, *i_name; char *cp; struct file *file; - char interp[BINPRM_BUF_SIZE]; int retval; if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!')) @@ -55,7 +54,7 @@ static int load_script(struct linux_binprm *bprm) break; } for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++); - if (*cp == '\0') + if (*cp == '\0') return -ENOEXEC; /* No interpreter name found */ i_name = cp; i_arg = NULL; @@ -65,7 +64,6 @@ static int load_script(struct linux_binprm *bprm) *cp++ = '\0'; if (*cp) i_arg = cp; - strcpy (interp, i_name); /* * OK, we've parsed out the interpreter name and * (optional) argument. @@ -80,24 +78,27 @@ static int load_script(struct linux_binprm *bprm) if (retval) return retval; retval = copy_strings_kernel(1, &bprm->interp, bprm); - if (retval < 0) return retval; + if (retval < 0) + return retval; bprm->argc++; if (i_arg) { retval = copy_strings_kernel(1, &i_arg, bprm); - if (retval < 0) return retval; + if (retval < 0) + return retval; bprm->argc++; } retval = copy_strings_kernel(1, &i_name, bprm); - if (retval) return retval; + if (retval) + return retval; bprm->argc++; - retval = bprm_change_interp(interp, bprm); + retval = bprm_change_interp(i_name, bprm); if (retval < 0) return retval; /* * OK, now restart the process with the interpreter's dentry. */ - file = open_exec(interp); + file = open_exec(i_name); if (IS_ERR(file)) return PTR_ERR(file); diff --git a/fs/block_dev.c b/fs/block_dev.c index 9941dc8342dfd7671eb96ad27a736d5220d670c8..93d088ffc05c679c7f0f35b847eb1d4341fc3761 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -223,7 +223,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, } bio_init(&bio, vecs, nr_pages); - bio.bi_bdev = bdev; + bio_set_dev(&bio, bdev); bio.bi_iter.bi_sector = pos >> 9; bio.bi_write_hint = iocb->ki_hint; bio.bi_private = current; @@ -362,7 +362,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) blk_start_plug(&plug); for (;;) { - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector = pos >> 9; bio->bi_write_hint = iocb->ki_hint; bio->bi_private = dio; @@ -1451,6 +1451,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) bdev->bd_disk = disk; bdev->bd_queue = disk->queue; bdev->bd_contains = bdev; + bdev->bd_partno = partno; if (!partno) { ret = -ENXIO; @@ -1739,6 +1740,8 @@ static int blkdev_open(struct inode * inode, struct file * filp) */ filp->f_flags |= O_LARGEFILE; + filp->f_mode |= FMODE_NOWAIT; + if (filp->f_flags & O_NDELAY) filp->f_mode |= FMODE_NDELAY; if (filp->f_flags & O_EXCL) @@ -1891,6 +1894,9 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) if (iocb->ki_pos >= size) return -ENOSPC; + if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT) + return -EOPNOTSUPP; + iov_iter_truncate(from, size - iocb->ki_pos); blk_start_plug(&plug); diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index 80e9c18ea64f69b68f84e3953256654774bd0b7e..a26c63b4ad68755def7be4d3e284f23e82f7b5c3 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig @@ -6,6 +6,8 @@ config BTRFS_FS select ZLIB_DEFLATE select LZO_COMPRESS select LZO_DECOMPRESS + select ZSTD_COMPRESS + select ZSTD_DECOMPRESS select RAID6_PQ select XOR_BLOCKS select SRCU diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 128ce17a80b0fd3a1e68f41ea2cb0af5cbfb53cf..962a95aefb811eb965185323d1954d6b04f1530d 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile @@ -6,7 +6,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ transaction.o inode.o file.o tree-defrag.o \ extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \ extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ - export.o tree-log.o free-space-cache.o zlib.o lzo.o \ + export.o tree-log.o free-space-cache.o zlib.o lzo.o zstd.o \ compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \ uuid-tree.o props.o hash.o free-space-tree.o diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 8d8370ddb6b29655f05ffe2855bd78f9937c7363..1ba49ebe67da39f6daf0a9a6f0ff63fff8554935 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -114,13 +114,17 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans, int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int ret; + umode_t old_mode = inode->i_mode; if (type == ACL_TYPE_ACCESS && acl) { ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); if (ret) return ret; } - return __btrfs_set_acl(NULL, inode, acl, type); + ret = __btrfs_set_acl(NULL, inode, acl, type); + if (ret) + inode->i_mode = old_mode; + return ret; } /* diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index ff0b0be92d6122402f02c039eed8e4599fdce4df..e00c8a9fd5bbc0182f27c3cf3e60027a293f077f 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -75,18 +75,18 @@ void btrfs_##name(struct work_struct *arg) \ } struct btrfs_fs_info * -btrfs_workqueue_owner(struct __btrfs_workqueue *wq) +btrfs_workqueue_owner(const struct __btrfs_workqueue *wq) { return wq->fs_info; } struct btrfs_fs_info * -btrfs_work_owner(struct btrfs_work *work) +btrfs_work_owner(const struct btrfs_work *work) { return work->wq->fs_info; } -bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq) +bool btrfs_workqueue_normal_congested(const struct btrfs_workqueue *wq) { /* * We could compare wq->normal->pending with num_online_cpus() diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h index 1f9597355c9d974ef11489afbed69d4a7df087d9..fc957e00cef144385e8368a44cfc418b412eadc0 100644 --- a/fs/btrfs/async-thread.h +++ b/fs/btrfs/async-thread.h @@ -82,7 +82,7 @@ void btrfs_queue_work(struct btrfs_workqueue *wq, void btrfs_destroy_workqueue(struct btrfs_workqueue *wq); void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max); void btrfs_set_work_high_priority(struct btrfs_work *work); -struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work); -struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq); -bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq); +struct btrfs_fs_info *btrfs_work_owner(const struct btrfs_work *work); +struct btrfs_fs_info *btrfs_workqueue_owner(const struct __btrfs_workqueue *wq); +bool btrfs_workqueue_normal_congested(const struct btrfs_workqueue *wq); #endif diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index f723c11bb763b1ebd028d08d5a45151f6d897c8c..b517ef1477ea5634d5ae9910e1c5a7f2b2becc7a 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -18,6 +18,7 @@ #include #include +#include #include "ctree.h" #include "disk-io.h" #include "backref.h" @@ -26,11 +27,6 @@ #include "delayed-ref.h" #include "locking.h" -enum merge_mode { - MERGE_IDENTICAL_KEYS = 1, - MERGE_IDENTICAL_PARENTS, -}; - /* Just an arbitrary number so we can be sure this happened */ #define BACKREF_FOUND_SHARED 6 @@ -40,269 +36,11 @@ struct extent_inode_elem { struct extent_inode_elem *next; }; -/* - * ref_root is used as the root of the ref tree that hold a collection - * of unique references. - */ -struct ref_root { - struct rb_root rb_root; - - /* - * The unique_refs represents the number of ref_nodes with a positive - * count stored in the tree. Even if a ref_node (the count is greater - * than one) is added, the unique_refs will only increase by one. - */ - unsigned int unique_refs; -}; - -/* ref_node is used to store a unique reference to the ref tree. */ -struct ref_node { - struct rb_node rb_node; - - /* For NORMAL_REF, otherwise all these fields should be set to 0 */ - u64 root_id; - u64 object_id; - u64 offset; - - /* For SHARED_REF, otherwise parent field should be set to 0 */ - u64 parent; - - /* Ref to the ref_mod of btrfs_delayed_ref_node */ - int ref_mod; -}; - -/* Dynamically allocate and initialize a ref_root */ -static struct ref_root *ref_root_alloc(void) -{ - struct ref_root *ref_tree; - - ref_tree = kmalloc(sizeof(*ref_tree), GFP_NOFS); - if (!ref_tree) - return NULL; - - ref_tree->rb_root = RB_ROOT; - ref_tree->unique_refs = 0; - - return ref_tree; -} - -/* Free all nodes in the ref tree, and reinit ref_root */ -static void ref_root_fini(struct ref_root *ref_tree) -{ - struct ref_node *node; - struct rb_node *next; - - while ((next = rb_first(&ref_tree->rb_root)) != NULL) { - node = rb_entry(next, struct ref_node, rb_node); - rb_erase(next, &ref_tree->rb_root); - kfree(node); - } - - ref_tree->rb_root = RB_ROOT; - ref_tree->unique_refs = 0; -} - -static void ref_root_free(struct ref_root *ref_tree) -{ - if (!ref_tree) - return; - - ref_root_fini(ref_tree); - kfree(ref_tree); -} - -/* - * Compare ref_node with (root_id, object_id, offset, parent) - * - * The function compares two ref_node a and b. It returns an integer less - * than, equal to, or greater than zero , respectively, to be less than, to - * equal, or be greater than b. - */ -static int ref_node_cmp(struct ref_node *a, struct ref_node *b) -{ - if (a->root_id < b->root_id) - return -1; - else if (a->root_id > b->root_id) - return 1; - - if (a->object_id < b->object_id) - return -1; - else if (a->object_id > b->object_id) - return 1; - - if (a->offset < b->offset) - return -1; - else if (a->offset > b->offset) - return 1; - - if (a->parent < b->parent) - return -1; - else if (a->parent > b->parent) - return 1; - - return 0; -} - -/* - * Search ref_node with (root_id, object_id, offset, parent) in the tree - * - * if found, the pointer of the ref_node will be returned; - * if not found, NULL will be returned and pos will point to the rb_node for - * insert, pos_parent will point to pos'parent for insert; -*/ -static struct ref_node *__ref_tree_search(struct ref_root *ref_tree, - struct rb_node ***pos, - struct rb_node **pos_parent, - u64 root_id, u64 object_id, - u64 offset, u64 parent) -{ - struct ref_node *cur = NULL; - struct ref_node entry; - int ret; - - entry.root_id = root_id; - entry.object_id = object_id; - entry.offset = offset; - entry.parent = parent; - - *pos = &ref_tree->rb_root.rb_node; - - while (**pos) { - *pos_parent = **pos; - cur = rb_entry(*pos_parent, struct ref_node, rb_node); - - ret = ref_node_cmp(cur, &entry); - if (ret > 0) - *pos = &(**pos)->rb_left; - else if (ret < 0) - *pos = &(**pos)->rb_right; - else - return cur; - } - - return NULL; -} - -/* - * Insert a ref_node to the ref tree - * @pos used for specifiy the position to insert - * @pos_parent for specifiy pos's parent - * - * success, return 0; - * ref_node already exists, return -EEXIST; -*/ -static int ref_tree_insert(struct ref_root *ref_tree, struct rb_node **pos, - struct rb_node *pos_parent, struct ref_node *ins) -{ - struct rb_node **p = NULL; - struct rb_node *parent = NULL; - struct ref_node *cur = NULL; - - if (!pos) { - cur = __ref_tree_search(ref_tree, &p, &parent, ins->root_id, - ins->object_id, ins->offset, - ins->parent); - if (cur) - return -EEXIST; - } else { - p = pos; - parent = pos_parent; - } - - rb_link_node(&ins->rb_node, parent, p); - rb_insert_color(&ins->rb_node, &ref_tree->rb_root); - - return 0; -} - -/* Erase and free ref_node, caller should update ref_root->unique_refs */ -static void ref_tree_remove(struct ref_root *ref_tree, struct ref_node *node) -{ - rb_erase(&node->rb_node, &ref_tree->rb_root); - kfree(node); -} - -/* - * Update ref_root->unique_refs - * - * Call __ref_tree_search - * 1. if ref_node doesn't exist, ref_tree_insert this node, and update - * ref_root->unique_refs: - * if ref_node->ref_mod > 0, ref_root->unique_refs++; - * if ref_node->ref_mod < 0, do noting; - * - * 2. if ref_node is found, then get origin ref_node->ref_mod, and update - * ref_node->ref_mod. - * if ref_node->ref_mod is equal to 0,then call ref_tree_remove - * - * according to origin_mod and new_mod, update ref_root->items - * +----------------+--------------+-------------+ - * | |new_count <= 0|new_count > 0| - * +----------------+--------------+-------------+ - * |origin_count < 0| 0 | 1 | - * +----------------+--------------+-------------+ - * |origin_count > 0| -1 | 0 | - * +----------------+--------------+-------------+ - * - * In case of allocation failure, -ENOMEM is returned and the ref_tree stays - * unaltered. - * Success, return 0 - */ -static int ref_tree_add(struct ref_root *ref_tree, u64 root_id, u64 object_id, - u64 offset, u64 parent, int count) -{ - struct ref_node *node = NULL; - struct rb_node **pos = NULL; - struct rb_node *pos_parent = NULL; - int origin_count; - int ret; - - if (!count) - return 0; - - node = __ref_tree_search(ref_tree, &pos, &pos_parent, root_id, - object_id, offset, parent); - if (node == NULL) { - node = kmalloc(sizeof(*node), GFP_NOFS); - if (!node) - return -ENOMEM; - - node->root_id = root_id; - node->object_id = object_id; - node->offset = offset; - node->parent = parent; - node->ref_mod = count; - - ret = ref_tree_insert(ref_tree, pos, pos_parent, node); - ASSERT(!ret); - if (ret) { - kfree(node); - return ret; - } - - ref_tree->unique_refs += node->ref_mod > 0 ? 1 : 0; - - return 0; - } - - origin_count = node->ref_mod; - node->ref_mod += count; - - if (node->ref_mod > 0) - ref_tree->unique_refs += origin_count > 0 ? 0 : 1; - else if (node->ref_mod <= 0) - ref_tree->unique_refs += origin_count > 0 ? -1 : 0; - - if (!node->ref_mod) - ref_tree_remove(ref_tree, node); - - return 0; -} - -static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb, - struct btrfs_file_extent_item *fi, - u64 extent_item_pos, - struct extent_inode_elem **eie) +static int check_extent_in_eb(const struct btrfs_key *key, + const struct extent_buffer *eb, + const struct btrfs_file_extent_item *fi, + u64 extent_item_pos, + struct extent_inode_elem **eie) { u64 offset = 0; struct extent_inode_elem *e; @@ -344,9 +82,9 @@ static void free_inode_elem_list(struct extent_inode_elem *eie) } } -static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte, - u64 extent_item_pos, - struct extent_inode_elem **eie) +static int find_extent_in_eb(const struct extent_buffer *eb, + u64 wanted_disk_byte, u64 extent_item_pos, + struct extent_inode_elem **eie) { u64 disk_byte; struct btrfs_key key; @@ -383,26 +121,44 @@ static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte, return 0; } +struct preftree { + struct rb_root root; + unsigned int count; +}; + +#define PREFTREE_INIT { .root = RB_ROOT, .count = 0 } + +struct preftrees { + struct preftree direct; /* BTRFS_SHARED_[DATA|BLOCK]_REF_KEY */ + struct preftree indirect; /* BTRFS_[TREE_BLOCK|EXTENT_DATA]_REF_KEY */ + struct preftree indirect_missing_keys; +}; + /* - * this structure records all encountered refs on the way up to the root + * Checks for a shared extent during backref search. + * + * The share_count tracks prelim_refs (direct and indirect) having a + * ref->count >0: + * - incremented when a ref->count transitions to >0 + * - decremented when a ref->count transitions to <1 */ -struct __prelim_ref { - struct list_head list; - u64 root_id; - struct btrfs_key key_for_search; - int level; - int count; - struct extent_inode_elem *inode_list; - u64 parent; - u64 wanted_disk_byte; +struct share_check { + u64 root_objectid; + u64 inum; + int share_count; }; +static inline int extent_is_shared(struct share_check *sc) +{ + return (sc && sc->share_count > 1) ? BACKREF_FOUND_SHARED : 0; +} + static struct kmem_cache *btrfs_prelim_ref_cache; int __init btrfs_prelim_ref_init(void) { btrfs_prelim_ref_cache = kmem_cache_create("btrfs_prelim_ref", - sizeof(struct __prelim_ref), + sizeof(struct prelim_ref), 0, SLAB_MEM_SPREAD, NULL); @@ -416,6 +172,134 @@ void btrfs_prelim_ref_exit(void) kmem_cache_destroy(btrfs_prelim_ref_cache); } +static void free_pref(struct prelim_ref *ref) +{ + kmem_cache_free(btrfs_prelim_ref_cache, ref); +} + +/* + * Return 0 when both refs are for the same block (and can be merged). + * A -1 return indicates ref1 is a 'lower' block than ref2, while 1 + * indicates a 'higher' block. + */ +static int prelim_ref_compare(struct prelim_ref *ref1, + struct prelim_ref *ref2) +{ + if (ref1->level < ref2->level) + return -1; + if (ref1->level > ref2->level) + return 1; + if (ref1->root_id < ref2->root_id) + return -1; + if (ref1->root_id > ref2->root_id) + return 1; + if (ref1->key_for_search.type < ref2->key_for_search.type) + return -1; + if (ref1->key_for_search.type > ref2->key_for_search.type) + return 1; + if (ref1->key_for_search.objectid < ref2->key_for_search.objectid) + return -1; + if (ref1->key_for_search.objectid > ref2->key_for_search.objectid) + return 1; + if (ref1->key_for_search.offset < ref2->key_for_search.offset) + return -1; + if (ref1->key_for_search.offset > ref2->key_for_search.offset) + return 1; + if (ref1->parent < ref2->parent) + return -1; + if (ref1->parent > ref2->parent) + return 1; + + return 0; +} + +void update_share_count(struct share_check *sc, int oldcount, int newcount) +{ + if ((!sc) || (oldcount == 0 && newcount < 1)) + return; + + if (oldcount > 0 && newcount < 1) + sc->share_count--; + else if (oldcount < 1 && newcount > 0) + sc->share_count++; +} + +/* + * Add @newref to the @root rbtree, merging identical refs. + * + * Callers should assume that newref has been freed after calling. + */ +static void prelim_ref_insert(const struct btrfs_fs_info *fs_info, + struct preftree *preftree, + struct prelim_ref *newref, + struct share_check *sc) +{ + struct rb_root *root; + struct rb_node **p; + struct rb_node *parent = NULL; + struct prelim_ref *ref; + int result; + + root = &preftree->root; + p = &root->rb_node; + + while (*p) { + parent = *p; + ref = rb_entry(parent, struct prelim_ref, rbnode); + result = prelim_ref_compare(ref, newref); + if (result < 0) { + p = &(*p)->rb_left; + } else if (result > 0) { + p = &(*p)->rb_right; + } else { + /* Identical refs, merge them and free @newref */ + struct extent_inode_elem *eie = ref->inode_list; + + while (eie && eie->next) + eie = eie->next; + + if (!eie) + ref->inode_list = newref->inode_list; + else + eie->next = newref->inode_list; + trace_btrfs_prelim_ref_merge(fs_info, ref, newref, + preftree->count); + /* + * A delayed ref can have newref->count < 0. + * The ref->count is updated to follow any + * BTRFS_[ADD|DROP]_DELAYED_REF actions. + */ + update_share_count(sc, ref->count, + ref->count + newref->count); + ref->count += newref->count; + free_pref(newref); + return; + } + } + + update_share_count(sc, 0, newref->count); + preftree->count++; + trace_btrfs_prelim_ref_insert(fs_info, newref, NULL, preftree->count); + rb_link_node(&newref->rbnode, parent, p); + rb_insert_color(&newref->rbnode, root); +} + +/* + * Release the entire tree. We don't care about internal consistency so + * just free everything and then reset the tree root. + */ +static void prelim_release(struct preftree *preftree) +{ + struct prelim_ref *ref, *next_ref; + + rbtree_postorder_for_each_entry_safe(ref, next_ref, &preftree->root, + rbnode) + free_pref(ref); + + preftree->root = RB_ROOT; + preftree->count = 0; +} + /* * the rules for all callers of this function are: * - obtaining the parent is the goal @@ -448,19 +332,19 @@ void btrfs_prelim_ref_exit(void) * * - column 1, 3: we've the parent -> done * - column 2: we take the first key from the block to find the parent - * (see __add_missing_keys) + * (see add_missing_keys) * - column 4: we use the key to find the parent * * additional information that's available but not required to find the parent * block might help in merging entries to gain some speed. */ - -static int __add_prelim_ref(struct list_head *head, u64 root_id, - struct btrfs_key *key, int level, - u64 parent, u64 wanted_disk_byte, int count, - gfp_t gfp_mask) +static int add_prelim_ref(const struct btrfs_fs_info *fs_info, + struct preftree *preftree, u64 root_id, + const struct btrfs_key *key, int level, u64 parent, + u64 wanted_disk_byte, int count, + struct share_check *sc, gfp_t gfp_mask) { - struct __prelim_ref *ref; + struct prelim_ref *ref; if (root_id == BTRFS_DATA_RELOC_TREE_OBJECTID) return 0; @@ -503,13 +387,37 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id, ref->count = count; ref->parent = parent; ref->wanted_disk_byte = wanted_disk_byte; - list_add_tail(&ref->list, head); + prelim_ref_insert(fs_info, preftree, ref, sc); + return extent_is_shared(sc); +} - return 0; +/* direct refs use root == 0, key == NULL */ +static int add_direct_ref(const struct btrfs_fs_info *fs_info, + struct preftrees *preftrees, int level, u64 parent, + u64 wanted_disk_byte, int count, + struct share_check *sc, gfp_t gfp_mask) +{ + return add_prelim_ref(fs_info, &preftrees->direct, 0, NULL, level, + parent, wanted_disk_byte, count, sc, gfp_mask); +} + +/* indirect refs use parent == 0 */ +static int add_indirect_ref(const struct btrfs_fs_info *fs_info, + struct preftrees *preftrees, u64 root_id, + const struct btrfs_key *key, int level, + u64 wanted_disk_byte, int count, + struct share_check *sc, gfp_t gfp_mask) +{ + struct preftree *tree = &preftrees->indirect; + + if (!key) + tree = &preftrees->indirect_missing_keys; + return add_prelim_ref(fs_info, tree, root_id, key, level, 0, + wanted_disk_byte, count, sc, gfp_mask); } static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, - struct ulist *parents, struct __prelim_ref *ref, + struct ulist *parents, struct prelim_ref *ref, int level, u64 time_seq, const u64 *extent_item_pos, u64 total_refs) { @@ -599,11 +507,10 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, * resolve an indirect backref in the form (root_id, key, level) * to a logical address */ -static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, - struct btrfs_path *path, u64 time_seq, - struct __prelim_ref *ref, - struct ulist *parents, - const u64 *extent_item_pos, u64 total_refs) +static int resolve_indirect_ref(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 time_seq, + struct prelim_ref *ref, struct ulist *parents, + const u64 *extent_item_pos, u64 total_refs) { struct btrfs_root *root; struct btrfs_key root_key; @@ -681,52 +588,90 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, return ret; } +static struct extent_inode_elem * +unode_aux_to_inode_list(struct ulist_node *node) +{ + if (!node) + return NULL; + return (struct extent_inode_elem *)(uintptr_t)node->aux; +} + /* - * resolve all indirect backrefs from the list + * We maintain three seperate rbtrees: one for direct refs, one for + * indirect refs which have a key, and one for indirect refs which do not + * have a key. Each tree does merge on insertion. + * + * Once all of the references are located, we iterate over the tree of + * indirect refs with missing keys. An appropriate key is located and + * the ref is moved onto the tree for indirect refs. After all missing + * keys are thus located, we iterate over the indirect ref tree, resolve + * each reference, and then insert the resolved reference onto the + * direct tree (merging there too). + * + * New backrefs (i.e., for parent nodes) are added to the appropriate + * rbtree as they are encountered. The new backrefs are subsequently + * resolved as above. */ -static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, - struct btrfs_path *path, u64 time_seq, - struct list_head *head, - const u64 *extent_item_pos, u64 total_refs, - u64 root_objectid) +static int resolve_indirect_refs(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 time_seq, + struct preftrees *preftrees, + const u64 *extent_item_pos, u64 total_refs, + struct share_check *sc) { int err; int ret = 0; - struct __prelim_ref *ref; - struct __prelim_ref *ref_safe; - struct __prelim_ref *new_ref; struct ulist *parents; struct ulist_node *node; struct ulist_iterator uiter; + struct rb_node *rnode; parents = ulist_alloc(GFP_NOFS); if (!parents) return -ENOMEM; /* - * _safe allows us to insert directly after the current item without - * iterating over the newly inserted items. - * we're also allowed to re-assign ref during iteration. + * We could trade memory usage for performance here by iterating + * the tree, allocating new refs for each insertion, and then + * freeing the entire indirect tree when we're done. In some test + * cases, the tree can grow quite large (~200k objects). */ - list_for_each_entry_safe(ref, ref_safe, head, list) { - if (ref->parent) /* already direct */ - continue; - if (ref->count == 0) + while ((rnode = rb_first(&preftrees->indirect.root))) { + struct prelim_ref *ref; + + ref = rb_entry(rnode, struct prelim_ref, rbnode); + if (WARN(ref->parent, + "BUG: direct ref found in indirect tree")) { + ret = -EINVAL; + goto out; + } + + rb_erase(&ref->rbnode, &preftrees->indirect.root); + preftrees->indirect.count--; + + if (ref->count == 0) { + free_pref(ref); continue; - if (root_objectid && ref->root_id != root_objectid) { + } + + if (sc && sc->root_objectid && + ref->root_id != sc->root_objectid) { + free_pref(ref); ret = BACKREF_FOUND_SHARED; goto out; } - err = __resolve_indirect_ref(fs_info, path, time_seq, ref, - parents, extent_item_pos, - total_refs); + err = resolve_indirect_ref(fs_info, path, time_seq, ref, + parents, extent_item_pos, + total_refs); /* * we can only tolerate ENOENT,otherwise,we should catch error * and return directly. */ if (err == -ENOENT) { + prelim_ref_insert(fs_info, &preftrees->direct, ref, + NULL); continue; } else if (err) { + free_pref(ref); ret = err; goto out; } @@ -735,68 +680,65 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, ULIST_ITER_INIT(&uiter); node = ulist_next(parents, &uiter); ref->parent = node ? node->val : 0; - ref->inode_list = node ? - (struct extent_inode_elem *)(uintptr_t)node->aux : NULL; + ref->inode_list = unode_aux_to_inode_list(node); - /* additional parents require new refs being added here */ + /* Add a prelim_ref(s) for any other parent(s). */ while ((node = ulist_next(parents, &uiter))) { + struct prelim_ref *new_ref; + new_ref = kmem_cache_alloc(btrfs_prelim_ref_cache, GFP_NOFS); if (!new_ref) { + free_pref(ref); ret = -ENOMEM; goto out; } memcpy(new_ref, ref, sizeof(*ref)); new_ref->parent = node->val; - new_ref->inode_list = (struct extent_inode_elem *) - (uintptr_t)node->aux; - list_add(&new_ref->list, &ref->list); + new_ref->inode_list = unode_aux_to_inode_list(node); + prelim_ref_insert(fs_info, &preftrees->direct, + new_ref, NULL); } + + /* + * Now it's a direct ref, put it in the the direct tree. We must + * do this last because the ref could be merged/freed here. + */ + prelim_ref_insert(fs_info, &preftrees->direct, ref, NULL); + ulist_reinit(parents); + cond_resched(); } out: ulist_free(parents); return ret; } -static inline int ref_for_same_block(struct __prelim_ref *ref1, - struct __prelim_ref *ref2) -{ - if (ref1->level != ref2->level) - return 0; - if (ref1->root_id != ref2->root_id) - return 0; - if (ref1->key_for_search.type != ref2->key_for_search.type) - return 0; - if (ref1->key_for_search.objectid != ref2->key_for_search.objectid) - return 0; - if (ref1->key_for_search.offset != ref2->key_for_search.offset) - return 0; - if (ref1->parent != ref2->parent) - return 0; - - return 1; -} - /* * read tree blocks and add keys where required. */ -static int __add_missing_keys(struct btrfs_fs_info *fs_info, - struct list_head *head) +static int add_missing_keys(struct btrfs_fs_info *fs_info, + struct preftrees *preftrees) { - struct __prelim_ref *ref; + struct prelim_ref *ref; struct extent_buffer *eb; + struct preftree *tree = &preftrees->indirect_missing_keys; + struct rb_node *node; - list_for_each_entry(ref, head, list) { - if (ref->parent) - continue; - if (ref->key_for_search.type) - continue; + while ((node = rb_first(&tree->root))) { + ref = rb_entry(node, struct prelim_ref, rbnode); + rb_erase(node, &tree->root); + + BUG_ON(ref->parent); /* should not be a direct ref */ + BUG_ON(ref->key_for_search.type); BUG_ON(!ref->wanted_disk_byte); + eb = read_tree_block(fs_info, ref->wanted_disk_byte, 0); if (IS_ERR(eb)) { + free_pref(ref); return PTR_ERR(eb); } else if (!extent_buffer_uptodate(eb)) { + free_pref(ref); free_extent_buffer(eb); return -EIO; } @@ -807,73 +749,33 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0); btrfs_tree_read_unlock(eb); free_extent_buffer(eb); + prelim_ref_insert(fs_info, &preftrees->indirect, ref, NULL); + cond_resched(); } return 0; } -/* - * merge backrefs and adjust counts accordingly - * - * FIXME: For MERGE_IDENTICAL_KEYS, if we add more keys in __add_prelim_ref - * then we can merge more here. Additionally, we could even add a key - * range for the blocks we looked into to merge even more (-> replace - * unresolved refs by those having a parent). - */ -static void __merge_refs(struct list_head *head, enum merge_mode mode) -{ - struct __prelim_ref *pos1; - - list_for_each_entry(pos1, head, list) { - struct __prelim_ref *pos2 = pos1, *tmp; - - list_for_each_entry_safe_continue(pos2, tmp, head, list) { - struct __prelim_ref *ref1 = pos1, *ref2 = pos2; - struct extent_inode_elem *eie; - - if (!ref_for_same_block(ref1, ref2)) - continue; - if (mode == MERGE_IDENTICAL_KEYS) { - if (!ref1->parent && ref2->parent) - swap(ref1, ref2); - } else { - if (ref1->parent != ref2->parent) - continue; - } - - eie = ref1->inode_list; - while (eie && eie->next) - eie = eie->next; - if (eie) - eie->next = ref2->inode_list; - else - ref1->inode_list = ref2->inode_list; - ref1->count += ref2->count; - - list_del(&ref2->list); - kmem_cache_free(btrfs_prelim_ref_cache, ref2); - cond_resched(); - } - - } -} - /* * add all currently queued delayed refs from this head whose seq nr is * smaller or equal that seq to the list */ -static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, - struct list_head *prefs, u64 *total_refs, - u64 inum) +static int add_delayed_refs(const struct btrfs_fs_info *fs_info, + struct btrfs_delayed_ref_head *head, u64 seq, + struct preftrees *preftrees, u64 *total_refs, + struct share_check *sc) { struct btrfs_delayed_ref_node *node; struct btrfs_delayed_extent_op *extent_op = head->extent_op; struct btrfs_key key; - struct btrfs_key op_key = {0}; - int sgn; + struct btrfs_key tmp_op_key; + struct btrfs_key *op_key = NULL; + int count; int ret = 0; - if (extent_op && extent_op->update_key) - btrfs_disk_key_to_cpu(&op_key, &extent_op->key); + if (extent_op && extent_op->update_key) { + btrfs_disk_key_to_cpu(&tmp_op_key, &extent_op->key); + op_key = &tmp_op_key; + } spin_lock(&head->lock); list_for_each_entry(node, &head->ref_list, list) { @@ -886,36 +788,40 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, WARN_ON(1); continue; case BTRFS_ADD_DELAYED_REF: - sgn = 1; + count = node->ref_mod; break; case BTRFS_DROP_DELAYED_REF: - sgn = -1; + count = node->ref_mod * -1; break; default: BUG_ON(1); } - *total_refs += (node->ref_mod * sgn); + *total_refs += count; switch (node->type) { case BTRFS_TREE_BLOCK_REF_KEY: { + /* NORMAL INDIRECT METADATA backref */ struct btrfs_delayed_tree_ref *ref; ref = btrfs_delayed_node_to_tree_ref(node); - ret = __add_prelim_ref(prefs, ref->root, &op_key, - ref->level + 1, 0, node->bytenr, - node->ref_mod * sgn, GFP_ATOMIC); + ret = add_indirect_ref(fs_info, preftrees, ref->root, + &tmp_op_key, ref->level + 1, + node->bytenr, count, sc, + GFP_ATOMIC); break; } case BTRFS_SHARED_BLOCK_REF_KEY: { + /* SHARED DIRECT METADATA backref */ struct btrfs_delayed_tree_ref *ref; ref = btrfs_delayed_node_to_tree_ref(node); - ret = __add_prelim_ref(prefs, 0, NULL, - ref->level + 1, ref->parent, - node->bytenr, - node->ref_mod * sgn, GFP_ATOMIC); + + ret = add_direct_ref(fs_info, preftrees, ref->level + 1, + ref->parent, node->bytenr, count, + sc, GFP_ATOMIC); break; } case BTRFS_EXTENT_DATA_REF_KEY: { + /* NORMAL INDIRECT DATA backref */ struct btrfs_delayed_data_ref *ref; ref = btrfs_delayed_node_to_data_ref(node); @@ -927,42 +833,53 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, * Found a inum that doesn't match our known inum, we * know it's shared. */ - if (inum && ref->objectid != inum) { + if (sc && sc->inum && ref->objectid != sc->inum) { ret = BACKREF_FOUND_SHARED; - break; + goto out; } - ret = __add_prelim_ref(prefs, ref->root, &key, 0, 0, - node->bytenr, - node->ref_mod * sgn, GFP_ATOMIC); + ret = add_indirect_ref(fs_info, preftrees, ref->root, + &key, 0, node->bytenr, count, sc, + GFP_ATOMIC); break; } case BTRFS_SHARED_DATA_REF_KEY: { + /* SHARED DIRECT FULL backref */ struct btrfs_delayed_data_ref *ref; ref = btrfs_delayed_node_to_data_ref(node); - ret = __add_prelim_ref(prefs, 0, NULL, 0, - ref->parent, node->bytenr, - node->ref_mod * sgn, GFP_ATOMIC); + + ret = add_direct_ref(fs_info, preftrees, 0, ref->parent, + node->bytenr, count, sc, + GFP_ATOMIC); break; } default: WARN_ON(1); } - if (ret) + /* + * We must ignore BACKREF_FOUND_SHARED until all delayed + * refs have been checked. + */ + if (ret && (ret != BACKREF_FOUND_SHARED)) break; } + if (!ret) + ret = extent_is_shared(sc); +out: spin_unlock(&head->lock); return ret; } /* * add all inline backrefs for bytenr to the list + * + * Returns 0 on success, <0 on error, or BACKREF_FOUND_SHARED. */ -static int __add_inline_refs(struct btrfs_path *path, u64 bytenr, - int *info_level, struct list_head *prefs, - struct ref_root *ref_tree, - u64 *total_refs, u64 inum) +static int add_inline_refs(const struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 bytenr, + int *info_level, struct preftrees *preftrees, + u64 *total_refs, struct share_check *sc) { int ret = 0; int slot; @@ -1012,14 +929,18 @@ static int __add_inline_refs(struct btrfs_path *path, u64 bytenr, int type; iref = (struct btrfs_extent_inline_ref *)ptr; - type = btrfs_extent_inline_ref_type(leaf, iref); + type = btrfs_get_extent_inline_ref_type(leaf, iref, + BTRFS_REF_TYPE_ANY); + if (type == BTRFS_REF_TYPE_INVALID) + return -EINVAL; + offset = btrfs_extent_inline_ref_offset(leaf, iref); switch (type) { case BTRFS_SHARED_BLOCK_REF_KEY: - ret = __add_prelim_ref(prefs, 0, NULL, - *info_level + 1, offset, - bytenr, 1, GFP_NOFS); + ret = add_direct_ref(fs_info, preftrees, + *info_level + 1, offset, + bytenr, 1, NULL, GFP_NOFS); break; case BTRFS_SHARED_DATA_REF_KEY: { struct btrfs_shared_data_ref *sdref; @@ -1027,21 +948,15 @@ static int __add_inline_refs(struct btrfs_path *path, u64 bytenr, sdref = (struct btrfs_shared_data_ref *)(iref + 1); count = btrfs_shared_data_ref_count(leaf, sdref); - ret = __add_prelim_ref(prefs, 0, NULL, 0, offset, - bytenr, count, GFP_NOFS); - if (ref_tree) { - if (!ret) - ret = ref_tree_add(ref_tree, 0, 0, 0, - bytenr, count); - if (!ret && ref_tree->unique_refs > 1) - ret = BACKREF_FOUND_SHARED; - } + + ret = add_direct_ref(fs_info, preftrees, 0, offset, + bytenr, count, sc, GFP_NOFS); break; } case BTRFS_TREE_BLOCK_REF_KEY: - ret = __add_prelim_ref(prefs, offset, NULL, - *info_level + 1, 0, - bytenr, 1, GFP_NOFS); + ret = add_indirect_ref(fs_info, preftrees, offset, + NULL, *info_level + 1, + bytenr, 1, NULL, GFP_NOFS); break; case BTRFS_EXTENT_DATA_REF_KEY: { struct btrfs_extent_data_ref *dref; @@ -1055,23 +970,16 @@ static int __add_inline_refs(struct btrfs_path *path, u64 bytenr, key.type = BTRFS_EXTENT_DATA_KEY; key.offset = btrfs_extent_data_ref_offset(leaf, dref); - if (inum && key.objectid != inum) { + if (sc && sc->inum && key.objectid != sc->inum) { ret = BACKREF_FOUND_SHARED; break; } root = btrfs_extent_data_ref_root(leaf, dref); - ret = __add_prelim_ref(prefs, root, &key, 0, 0, - bytenr, count, GFP_NOFS); - if (ref_tree) { - if (!ret) - ret = ref_tree_add(ref_tree, root, - key.objectid, - key.offset, 0, - count); - if (!ret && ref_tree->unique_refs > 1) - ret = BACKREF_FOUND_SHARED; - } + + ret = add_indirect_ref(fs_info, preftrees, root, + &key, 0, bytenr, count, + sc, GFP_NOFS); break; } default: @@ -1087,11 +995,13 @@ static int __add_inline_refs(struct btrfs_path *path, u64 bytenr, /* * add all non-inline backrefs for bytenr to the list + * + * Returns 0 on success, <0 on error, or BACKREF_FOUND_SHARED. */ -static int __add_keyed_refs(struct btrfs_fs_info *fs_info, - struct btrfs_path *path, u64 bytenr, - int info_level, struct list_head *prefs, - struct ref_root *ref_tree, u64 inum) +static int add_keyed_refs(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 bytenr, + int info_level, struct preftrees *preftrees, + struct share_check *sc) { struct btrfs_root *extent_root = fs_info->extent_root; int ret; @@ -1121,34 +1031,32 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, switch (key.type) { case BTRFS_SHARED_BLOCK_REF_KEY: - ret = __add_prelim_ref(prefs, 0, NULL, - info_level + 1, key.offset, - bytenr, 1, GFP_NOFS); + /* SHARED DIRECT METADATA backref */ + ret = add_direct_ref(fs_info, preftrees, + info_level + 1, key.offset, + bytenr, 1, NULL, GFP_NOFS); break; case BTRFS_SHARED_DATA_REF_KEY: { + /* SHARED DIRECT FULL backref */ struct btrfs_shared_data_ref *sdref; int count; sdref = btrfs_item_ptr(leaf, slot, struct btrfs_shared_data_ref); count = btrfs_shared_data_ref_count(leaf, sdref); - ret = __add_prelim_ref(prefs, 0, NULL, 0, key.offset, - bytenr, count, GFP_NOFS); - if (ref_tree) { - if (!ret) - ret = ref_tree_add(ref_tree, 0, 0, 0, - bytenr, count); - if (!ret && ref_tree->unique_refs > 1) - ret = BACKREF_FOUND_SHARED; - } + ret = add_direct_ref(fs_info, preftrees, 0, + key.offset, bytenr, count, + sc, GFP_NOFS); break; } case BTRFS_TREE_BLOCK_REF_KEY: - ret = __add_prelim_ref(prefs, key.offset, NULL, - info_level + 1, 0, - bytenr, 1, GFP_NOFS); + /* NORMAL INDIRECT METADATA backref */ + ret = add_indirect_ref(fs_info, preftrees, key.offset, + NULL, info_level + 1, bytenr, + 1, NULL, GFP_NOFS); break; case BTRFS_EXTENT_DATA_REF_KEY: { + /* NORMAL INDIRECT DATA backref */ struct btrfs_extent_data_ref *dref; int count; u64 root; @@ -1161,23 +1069,15 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, key.type = BTRFS_EXTENT_DATA_KEY; key.offset = btrfs_extent_data_ref_offset(leaf, dref); - if (inum && key.objectid != inum) { + if (sc && sc->inum && key.objectid != sc->inum) { ret = BACKREF_FOUND_SHARED; break; } root = btrfs_extent_data_ref_root(leaf, dref); - ret = __add_prelim_ref(prefs, root, &key, 0, 0, - bytenr, count, GFP_NOFS); - if (ref_tree) { - if (!ret) - ret = ref_tree_add(ref_tree, root, - key.objectid, - key.offset, 0, - count); - if (!ret && ref_tree->unique_refs > 1) - ret = BACKREF_FOUND_SHARED; - } + ret = add_indirect_ref(fs_info, preftrees, root, + &key, 0, bytenr, count, + sc, GFP_NOFS); break; } default: @@ -1197,15 +1097,15 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, * indirect refs to their parent bytenr. * When roots are found, they're added to the roots list * - * NOTE: This can return values > 0 - * * If time_seq is set to SEQ_LAST, it will not search delayed_refs, and behave * much like trans == NULL case, the difference only lies in it will not * commit root. * The special case is for qgroup to search roots in commit_transaction(). * - * If check_shared is set to 1, any extent has more than one ref item, will - * be returned BACKREF_FOUND_SHARED immediately. + * @sc - if !NULL, then immediately return BACKREF_FOUND_SHARED when a + * shared extent is detected. + * + * Otherwise this returns 0 for success and <0 for an error. * * FIXME some caching might speed things up */ @@ -1213,7 +1113,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 bytenr, u64 time_seq, struct ulist *refs, struct ulist *roots, const u64 *extent_item_pos, - u64 root_objectid, u64 inum, int check_shared) + struct share_check *sc) { struct btrfs_key key; struct btrfs_path *path; @@ -1221,15 +1121,16 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_head *head; int info_level = 0; int ret; - struct list_head prefs_delayed; - struct list_head prefs; - struct __prelim_ref *ref; + struct prelim_ref *ref; + struct rb_node *node; struct extent_inode_elem *eie = NULL; - struct ref_root *ref_tree = NULL; + /* total of both direct AND indirect refs! */ u64 total_refs = 0; - - INIT_LIST_HEAD(&prefs); - INIT_LIST_HEAD(&prefs_delayed); + struct preftrees preftrees = { + .direct = PREFTREE_INIT, + .indirect = PREFTREE_INIT, + .indirect_missing_keys = PREFTREE_INIT + }; key.objectid = bytenr; key.offset = (u64)-1; @@ -1257,18 +1158,6 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, again: head = NULL; - if (check_shared) { - if (!ref_tree) { - ref_tree = ref_root_alloc(); - if (!ref_tree) { - ret = -ENOMEM; - goto out; - } - } else { - ref_root_fini(ref_tree); - } - } - ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); if (ret < 0) goto out; @@ -1304,45 +1193,14 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, goto again; } spin_unlock(&delayed_refs->lock); - ret = __add_delayed_refs(head, time_seq, - &prefs_delayed, &total_refs, - inum); + ret = add_delayed_refs(fs_info, head, time_seq, + &preftrees, &total_refs, sc); mutex_unlock(&head->mutex); if (ret) goto out; } else { spin_unlock(&delayed_refs->lock); } - - if (check_shared && !list_empty(&prefs_delayed)) { - /* - * Add all delay_ref to the ref_tree and check if there - * are multiple ref items added. - */ - list_for_each_entry(ref, &prefs_delayed, list) { - if (ref->key_for_search.type) { - ret = ref_tree_add(ref_tree, - ref->root_id, - ref->key_for_search.objectid, - ref->key_for_search.offset, - 0, ref->count); - if (ret) - goto out; - } else { - ret = ref_tree_add(ref_tree, 0, 0, 0, - ref->parent, ref->count); - if (ret) - goto out; - } - - } - - if (ref_tree->unique_refs > 1) { - ret = BACKREF_FOUND_SHARED; - goto out; - } - - } } if (path->slots[0]) { @@ -1356,42 +1214,48 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, if (key.objectid == bytenr && (key.type == BTRFS_EXTENT_ITEM_KEY || key.type == BTRFS_METADATA_ITEM_KEY)) { - ret = __add_inline_refs(path, bytenr, - &info_level, &prefs, - ref_tree, &total_refs, - inum); + ret = add_inline_refs(fs_info, path, bytenr, + &info_level, &preftrees, + &total_refs, sc); if (ret) goto out; - ret = __add_keyed_refs(fs_info, path, bytenr, - info_level, &prefs, - ref_tree, inum); + ret = add_keyed_refs(fs_info, path, bytenr, info_level, + &preftrees, sc); if (ret) goto out; } } - btrfs_release_path(path); - list_splice_init(&prefs_delayed, &prefs); + btrfs_release_path(path); - ret = __add_missing_keys(fs_info, &prefs); + ret = add_missing_keys(fs_info, &preftrees); if (ret) goto out; - __merge_refs(&prefs, MERGE_IDENTICAL_KEYS); + WARN_ON(!RB_EMPTY_ROOT(&preftrees.indirect_missing_keys.root)); - ret = __resolve_indirect_refs(fs_info, path, time_seq, &prefs, - extent_item_pos, total_refs, - root_objectid); + ret = resolve_indirect_refs(fs_info, path, time_seq, &preftrees, + extent_item_pos, total_refs, sc); if (ret) goto out; - __merge_refs(&prefs, MERGE_IDENTICAL_PARENTS); + WARN_ON(!RB_EMPTY_ROOT(&preftrees.indirect.root)); - while (!list_empty(&prefs)) { - ref = list_first_entry(&prefs, struct __prelim_ref, list); + /* + * This walks the tree of merged and resolved refs. Tree blocks are + * read in as needed. Unique entries are added to the ulist, and + * the list of found roots is updated. + * + * We release the entire tree in one go before returning. + */ + node = rb_first(&preftrees.direct.root); + while (node) { + ref = rb_entry(node, struct prelim_ref, rbnode); + node = rb_next(&ref->rbnode); WARN_ON(ref->count < 0); if (roots && ref->count && ref->root_id && ref->parent == 0) { - if (root_objectid && ref->root_id != root_objectid) { + if (sc && sc->root_objectid && + ref->root_id != sc->root_objectid) { ret = BACKREF_FOUND_SHARED; goto out; } @@ -1442,24 +1306,16 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, } eie = NULL; } - list_del(&ref->list); - kmem_cache_free(btrfs_prelim_ref_cache, ref); + cond_resched(); } out: btrfs_free_path(path); - ref_root_free(ref_tree); - while (!list_empty(&prefs)) { - ref = list_first_entry(&prefs, struct __prelim_ref, list); - list_del(&ref->list); - kmem_cache_free(btrfs_prelim_ref_cache, ref); - } - while (!list_empty(&prefs_delayed)) { - ref = list_first_entry(&prefs_delayed, struct __prelim_ref, - list); - list_del(&ref->list); - kmem_cache_free(btrfs_prelim_ref_cache, ref); - } + + prelim_release(&preftrees.direct); + prelim_release(&preftrees.indirect); + prelim_release(&preftrees.indirect_missing_keys); + if (ret < 0) free_inode_elem_list(eie); return ret; @@ -1475,7 +1331,7 @@ static void free_leaf_list(struct ulist *blocks) while ((node = ulist_next(blocks, &uiter))) { if (!node->aux) continue; - eie = (struct extent_inode_elem *)(uintptr_t)node->aux; + eie = unode_aux_to_inode_list(node); free_inode_elem_list(eie); node->aux = 0; } @@ -1503,7 +1359,7 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, return -ENOMEM; ret = find_parent_nodes(trans, fs_info, bytenr, time_seq, - *leafs, NULL, extent_item_pos, 0, 0, 0); + *leafs, NULL, extent_item_pos, NULL); if (ret < 0 && ret != -ENOENT) { free_leaf_list(*leafs); return ret; @@ -1525,9 +1381,9 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, * * returns 0 on success, < 0 on error. */ -static int __btrfs_find_all_roots(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, u64 bytenr, - u64 time_seq, struct ulist **roots) +static int btrfs_find_all_roots_safe(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, u64 bytenr, + u64 time_seq, struct ulist **roots) { struct ulist *tmp; struct ulist_node *node = NULL; @@ -1546,7 +1402,7 @@ static int __btrfs_find_all_roots(struct btrfs_trans_handle *trans, ULIST_ITER_INIT(&uiter); while (1) { ret = find_parent_nodes(trans, fs_info, bytenr, time_seq, - tmp, *roots, NULL, 0, 0, 0); + tmp, *roots, NULL, NULL); if (ret < 0 && ret != -ENOENT) { ulist_free(tmp); ulist_free(*roots); @@ -1571,7 +1427,8 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, if (!trans) down_read(&fs_info->commit_root_sem); - ret = __btrfs_find_all_roots(trans, fs_info, bytenr, time_seq, roots); + ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr, + time_seq, roots); if (!trans) up_read(&fs_info->commit_root_sem); return ret; @@ -1580,26 +1437,32 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, /** * btrfs_check_shared - tell us whether an extent is shared * - * @trans: optional trans handle - * * btrfs_check_shared uses the backref walking code but will short * circuit as soon as it finds a root or inode that doesn't match the * one passed in. This provides a significant performance benefit for * callers (such as fiemap) which want to know whether the extent is * shared but do not need a ref count. * + * This attempts to allocate a transaction in order to account for + * delayed refs, but continues on even when the alloc fails. + * * Return: 0 if extent is not shared, 1 if it is shared, < 0 on error. */ -int btrfs_check_shared(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, u64 root_objectid, - u64 inum, u64 bytenr) +int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr) { + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_trans_handle *trans; struct ulist *tmp = NULL; struct ulist *roots = NULL; struct ulist_iterator uiter; struct ulist_node *node; struct seq_list elem = SEQ_LIST_INIT(elem); int ret = 0; + struct share_check shared = { + .root_objectid = root->objectid, + .inum = inum, + .share_count = 0, + }; tmp = ulist_alloc(GFP_NOFS); roots = ulist_alloc(GFP_NOFS); @@ -1609,14 +1472,18 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans, return -ENOMEM; } - if (trans) - btrfs_get_tree_mod_seq(fs_info, &elem); - else + trans = btrfs_join_transaction(root); + if (IS_ERR(trans)) { + trans = NULL; down_read(&fs_info->commit_root_sem); + } else { + btrfs_get_tree_mod_seq(fs_info, &elem); + } + ULIST_ITER_INIT(&uiter); while (1) { ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp, - roots, NULL, root_objectid, inum, 1); + roots, NULL, &shared); if (ret == BACKREF_FOUND_SHARED) { /* this is the only condition under which we return 1 */ ret = 1; @@ -1631,10 +1498,13 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans, bytenr = node->val; cond_resched(); } - if (trans) + + if (trans) { btrfs_put_tree_mod_seq(fs_info, &elem); - else + btrfs_end_transaction(trans); + } else { up_read(&fs_info->commit_root_sem); + } ulist_free(tmp); ulist_free(roots); return ret; @@ -1649,7 +1519,7 @@ int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid, struct btrfs_key key; struct btrfs_key found_key; struct btrfs_inode_extref *extref; - struct extent_buffer *leaf; + const struct extent_buffer *leaf; unsigned long ptr; key.objectid = inode_objectid; @@ -1806,7 +1676,7 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical, u64 flags; u64 size = 0; u32 item_size; - struct extent_buffer *eb; + const struct extent_buffer *eb; struct btrfs_extent_item *ei; struct btrfs_key key; @@ -1870,15 +1740,17 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical, * helper function to iterate extent inline refs. ptr must point to a 0 value * for the first call and may be modified. it is used to track state. * if more refs exist, 0 is returned and the next call to - * __get_extent_inline_ref must pass the modified ptr parameter to get the + * get_extent_inline_ref must pass the modified ptr parameter to get the * next ref. after the last ref was processed, 1 is returned. * returns <0 on error */ -static int __get_extent_inline_ref(unsigned long *ptr, struct extent_buffer *eb, - struct btrfs_key *key, - struct btrfs_extent_item *ei, u32 item_size, - struct btrfs_extent_inline_ref **out_eiref, - int *out_type) +static int get_extent_inline_ref(unsigned long *ptr, + const struct extent_buffer *eb, + const struct btrfs_key *key, + const struct btrfs_extent_item *ei, + u32 item_size, + struct btrfs_extent_inline_ref **out_eiref, + int *out_type) { unsigned long end; u64 flags; @@ -1908,7 +1780,10 @@ static int __get_extent_inline_ref(unsigned long *ptr, struct extent_buffer *eb, end = (unsigned long)ei + item_size; *out_eiref = (struct btrfs_extent_inline_ref *)(*ptr); - *out_type = btrfs_extent_inline_ref_type(eb, *out_eiref); + *out_type = btrfs_get_extent_inline_ref_type(eb, *out_eiref, + BTRFS_REF_TYPE_ANY); + if (*out_type == BTRFS_REF_TYPE_INVALID) + return -EINVAL; *ptr += btrfs_extent_inline_ref_size(*out_type); WARN_ON(*ptr > end); @@ -1921,7 +1796,7 @@ static int __get_extent_inline_ref(unsigned long *ptr, struct extent_buffer *eb, /* * reads the tree block backref for an extent. tree level and root are returned * through out_level and out_root. ptr must point to a 0 value for the first - * call and may be modified (see __get_extent_inline_ref comment). + * call and may be modified (see get_extent_inline_ref comment). * returns 0 if data was provided, 1 if there was no more data to provide or * <0 on error. */ @@ -1937,7 +1812,7 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, return 1; while (1) { - ret = __get_extent_inline_ref(ptr, eb, key, ei, item_size, + ret = get_extent_inline_ref(ptr, eb, key, ei, item_size, &eiref, &type); if (ret < 0) return ret; @@ -2034,8 +1909,8 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ULIST_ITER_INIT(&ref_uiter); while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) { - ret = __btrfs_find_all_roots(trans, fs_info, ref_node->val, - tree_mod_seq_elem.seq, &roots); + ret = btrfs_find_all_roots_safe(trans, fs_info, ref_node->val, + tree_mod_seq_elem.seq, &roots); if (ret) break; ULIST_ITER_INIT(&root_uiter); diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h index 9c41fbac30091f39bad52a3f21ebf6e931db364b..e410335841aacfb0f672f90292cd9c8c621054ee 100644 --- a/fs/btrfs/backref.h +++ b/fs/btrfs/backref.h @@ -68,10 +68,20 @@ int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid, u64 start_off, struct btrfs_path *path, struct btrfs_inode_extref **ret_extref, u64 *found_off); -int btrfs_check_shared(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, u64 root_objectid, - u64 inum, u64 bytenr); +int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr); int __init btrfs_prelim_ref_init(void); void btrfs_prelim_ref_exit(void); + +struct prelim_ref { + struct rb_node rbnode; + u64 root_id; + struct btrfs_key key_for_search; + int level; + int count; + struct extent_inode_elem *inode_list; + u64 parent; + u64 wanted_disk_byte; +}; + #endif diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index d87ac27a5f2b4cbf2e415e6a34ac88f66647b008..eccadb5f62a5ed60929f173d814698d266f4e27c 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -179,9 +179,14 @@ struct btrfs_inode { unsigned reserved_extents; /* - * always compress this one file + * Cached values of inode properties */ - unsigned force_compress; + unsigned prop_compress; /* per-file compression algorithm */ + /* + * Force compression on the file using the defrag ioctl, could be + * different from prop_compress and takes precedence if set + */ + unsigned defrag_compress; struct btrfs_delayed_node *delayed_node; @@ -207,7 +212,7 @@ struct btrfs_inode { extern unsigned char btrfs_filetype_table[]; -static inline struct btrfs_inode *BTRFS_I(struct inode *inode) +static inline struct btrfs_inode *BTRFS_I(const struct inode *inode) { return container_of(inode, struct btrfs_inode, vfs_inode); } @@ -231,7 +236,7 @@ static inline void btrfs_insert_inode_hash(struct inode *inode) __insert_inode_hash(inode, h); } -static inline u64 btrfs_ino(struct btrfs_inode *inode) +static inline u64 btrfs_ino(const struct btrfs_inode *inode) { u64 ino = inode->location.objectid; diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 11d37c94ce058b6c7f09bfb1a546038b85977eb0..7d5a9b51f0d7a81fa7d5adf9900e4fcc744a80c0 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -296,8 +296,7 @@ static void btrfsic_dev_state_hashtable_add( struct btrfsic_dev_state *ds, struct btrfsic_dev_state_hashtable *h); static void btrfsic_dev_state_hashtable_remove(struct btrfsic_dev_state *ds); -static struct btrfsic_dev_state *btrfsic_dev_state_hashtable_lookup( - struct block_device *bdev, +static struct btrfsic_dev_state *btrfsic_dev_state_hashtable_lookup(dev_t dev, struct btrfsic_dev_state_hashtable *h); static struct btrfsic_stack_frame *btrfsic_stack_frame_alloc(void); static void btrfsic_stack_frame_free(struct btrfsic_stack_frame *sf); @@ -385,8 +384,7 @@ static int btrfsic_process_superblock_dev_mirror( int superblock_mirror_num, struct btrfsic_dev_state **selected_dev_state, struct btrfs_super_block *selected_super); -static struct btrfsic_dev_state *btrfsic_dev_state_lookup( - struct block_device *bdev); +static struct btrfsic_dev_state *btrfsic_dev_state_lookup(dev_t dev); static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, u64 bytenr, struct btrfsic_dev_state *dev_state, @@ -626,17 +624,15 @@ static void btrfsic_dev_state_hashtable_remove(struct btrfsic_dev_state *ds) list_del(&ds->collision_resolving_node); } -static struct btrfsic_dev_state *btrfsic_dev_state_hashtable_lookup( - struct block_device *bdev, +static struct btrfsic_dev_state *btrfsic_dev_state_hashtable_lookup(dev_t dev, struct btrfsic_dev_state_hashtable *h) { const unsigned int hashval = - (((unsigned int)((uintptr_t)bdev)) & - (BTRFSIC_DEV2STATE_HASHTABLE_SIZE - 1)); + dev & (BTRFSIC_DEV2STATE_HASHTABLE_SIZE - 1); struct btrfsic_dev_state *ds; list_for_each_entry(ds, h->table + hashval, collision_resolving_node) { - if (ds->bdev == bdev) + if (ds->bdev->bd_dev == dev) return ds; } @@ -668,7 +664,7 @@ static int btrfsic_process_superblock(struct btrfsic_state *state, if (!device->bdev || !device->name) continue; - dev_state = btrfsic_dev_state_lookup(device->bdev); + dev_state = btrfsic_dev_state_lookup(device->bdev->bd_dev); BUG_ON(NULL == dev_state); for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { ret = btrfsic_process_superblock_dev_mirror( @@ -795,12 +791,12 @@ static int btrfsic_process_superblock_dev_mirror( dev_bytenr = btrfs_sb_offset(superblock_mirror_num); if (dev_bytenr + BTRFS_SUPER_INFO_SIZE > device->commit_total_bytes) return -1; - bh = __bread(superblock_bdev, dev_bytenr / 4096, + bh = __bread(superblock_bdev, dev_bytenr / BTRFS_BDEV_BLOCKSIZE, BTRFS_SUPER_INFO_SIZE); if (NULL == bh) return -1; super_tmp = (struct btrfs_super_block *) - (bh->b_data + (dev_bytenr & 4095)); + (bh->b_data + (dev_bytenr & (BTRFS_BDEV_BLOCKSIZE - 1))); if (btrfs_super_bytenr(super_tmp) != dev_bytenr || btrfs_super_magic(super_tmp) != BTRFS_MAGIC || @@ -1556,7 +1552,7 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, } device = multi->stripes[0].dev; - block_ctx_out->dev = btrfsic_dev_state_lookup(device->bdev); + block_ctx_out->dev = btrfsic_dev_state_lookup(device->bdev->bd_dev); block_ctx_out->dev_bytenr = multi->stripes[0].physical; block_ctx_out->start = bytenr; block_ctx_out->len = len; @@ -1639,7 +1635,7 @@ static int btrfsic_read_block(struct btrfsic_state *state, unsigned int j; bio = btrfs_io_bio_alloc(num_pages - i); - bio->bi_bdev = block_ctx->dev->bdev; + bio_set_dev(bio, block_ctx->dev->bdev); bio->bi_iter.bi_sector = dev_bytenr >> 9; bio_set_op_attrs(bio, REQ_OP_READ, 0); @@ -1732,7 +1728,7 @@ static int btrfsic_test_for_metadata(struct btrfsic_state *state, num_pages = state->metablock_size >> PAGE_SHIFT; h = (struct btrfs_header *)datav[0]; - if (memcmp(h->fsid, fs_info->fsid, BTRFS_UUID_SIZE)) + if (memcmp(h->fsid, fs_info->fsid, BTRFS_FSID_SIZE)) return 1; for (i = 0; i < num_pages; i++) { @@ -2654,7 +2650,7 @@ static struct btrfsic_block *btrfsic_block_lookup_or_add( pr_info("btrfsic: error, kmalloc failed!\n"); return NULL; } - dev_state = btrfsic_dev_state_lookup(block_ctx->dev->bdev); + dev_state = btrfsic_dev_state_lookup(block_ctx->dev->bdev->bd_dev); if (NULL == dev_state) { pr_info("btrfsic: error, lookup dev_state failed!\n"); btrfsic_block_free(block); @@ -2734,10 +2730,9 @@ static void btrfsic_cmp_log_and_dev_bytenr(struct btrfsic_state *state, } } -static struct btrfsic_dev_state *btrfsic_dev_state_lookup( - struct block_device *bdev) +static struct btrfsic_dev_state *btrfsic_dev_state_lookup(dev_t dev) { - return btrfsic_dev_state_hashtable_lookup(bdev, + return btrfsic_dev_state_hashtable_lookup(dev, &btrfsic_dev_state_hashtable); } @@ -2751,14 +2746,14 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh) mutex_lock(&btrfsic_mutex); /* since btrfsic_submit_bh() might also be called before * btrfsic_mount(), this might return NULL */ - dev_state = btrfsic_dev_state_lookup(bh->b_bdev); + dev_state = btrfsic_dev_state_lookup(bh->b_bdev->bd_dev); /* Only called to write the superblock (incl. FLUSH/FUA) */ if (NULL != dev_state && (op == REQ_OP_WRITE) && bh->b_size > 0) { u64 dev_bytenr; - dev_bytenr = 4096 * bh->b_blocknr; + dev_bytenr = BTRFS_BDEV_BLOCKSIZE * bh->b_blocknr; if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) pr_info("submit_bh(op=0x%x,0x%x, blocknr=%llu (bytenr %llu), size=%zu, data=%p, bdev=%p)\n", @@ -2808,7 +2803,7 @@ static void __btrfsic_submit_bio(struct bio *bio) mutex_lock(&btrfsic_mutex); /* since btrfsic_submit_bio() is also called before * btrfsic_mount(), this might return NULL */ - dev_state = btrfsic_dev_state_lookup(bio->bi_bdev); + dev_state = btrfsic_dev_state_lookup(bio_dev(bio)); if (NULL != dev_state && (bio_op(bio) == REQ_OP_WRITE) && bio_has_data(bio)) { unsigned int i = 0; @@ -2824,10 +2819,10 @@ static void __btrfsic_submit_bio(struct bio *bio) bio_is_patched = 0; if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) - pr_info("submit_bio(rw=%d,0x%x, bi_vcnt=%u, bi_sector=%llu (bytenr %llu), bi_bdev=%p)\n", + pr_info("submit_bio(rw=%d,0x%x, bi_vcnt=%u, bi_sector=%llu (bytenr %llu), bi_disk=%p)\n", bio_op(bio), bio->bi_opf, segs, (unsigned long long)bio->bi_iter.bi_sector, - dev_bytenr, bio->bi_bdev); + dev_bytenr, bio->bi_disk); mapped_datav = kmalloc_array(segs, sizeof(*mapped_datav), GFP_NOFS); @@ -2856,8 +2851,8 @@ static void __btrfsic_submit_bio(struct bio *bio) } else if (NULL != dev_state && (bio->bi_opf & REQ_PREFLUSH)) { if (dev_state->state->print_mask & BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH) - pr_info("submit_bio(rw=%d,0x%x FLUSH, bdev=%p)\n", - bio_op(bio), bio->bi_opf, bio->bi_bdev); + pr_info("submit_bio(rw=%d,0x%x FLUSH, disk=%p)\n", + bio_op(bio), bio->bi_opf, bio->bi_disk); if (!dev_state->dummy_block_for_bio_bh_flush.is_iodone) { if ((dev_state->state->print_mask & (BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH | @@ -2998,7 +2993,7 @@ void btrfsic_unmount(struct btrfs_fs_devices *fs_devices) continue; ds = btrfsic_dev_state_hashtable_lookup( - device->bdev, + device->bdev->bd_dev, &btrfsic_dev_state_hashtable); if (NULL != ds) { state = ds->state; diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index d2ef9ac2a63038e279239012fdec7de0cf9573e3..280384bf34f13b20b7a0817a36fe49a53d618285 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -107,7 +107,8 @@ static void end_compressed_bio_read(struct bio *bio) struct inode *inode; struct page *page; unsigned long index; - int ret; + unsigned int mirror = btrfs_io_bio(bio)->mirror_num; + int ret = 0; if (bio->bi_status) cb->errors = 1; @@ -118,6 +119,21 @@ static void end_compressed_bio_read(struct bio *bio) if (!refcount_dec_and_test(&cb->pending_bios)) goto out; + /* + * Record the correct mirror_num in cb->orig_bio so that + * read-repair can work properly. + */ + ASSERT(btrfs_io_bio(cb->orig_bio)); + btrfs_io_bio(cb->orig_bio)->mirror_num = mirror; + cb->mirror_num = mirror; + + /* + * Some IO in this cb have failed, just skip checksum as there + * is no way it could be correct. + */ + if (cb->errors == 1) + goto csum_failed; + inode = cb->inode; ret = check_compressed_csum(BTRFS_I(inode), cb, (u64)bio->bi_iter.bi_sector << 9); @@ -704,6 +720,7 @@ static struct { static const struct btrfs_compress_op * const btrfs_compress_op[] = { &btrfs_zlib_compress, &btrfs_lzo_compress, + &btrfs_zstd_compress, }; void __init btrfs_init_compress(void) @@ -825,7 +842,7 @@ static void free_workspace(int type, struct list_head *workspace) int *free_ws = &btrfs_comp_ws[idx].free_ws; spin_lock(ws_lock); - if (*free_ws < num_online_cpus()) { + if (*free_ws <= num_online_cpus()) { list_add(workspace, idle_ws); (*free_ws)++; spin_unlock(ws_lock); @@ -1047,3 +1064,36 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start, return 1; } + +/* + * Compression heuristic. + * + * For now is's a naive and optimistic 'return true', we'll extend the logic to + * quickly (compared to direct compression) detect data characteristics + * (compressible/uncompressible) to avoid wasting CPU time on uncompressible + * data. + * + * The following types of analysis can be performed: + * - detect mostly zero data + * - detect data with low "byte set" size (text, etc) + * - detect data with low/high "core byte" set + * + * Return non-zero if the compression should be done, 0 otherwise. + */ +int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end) +{ + u64 index = start >> PAGE_SHIFT; + u64 end_index = end >> PAGE_SHIFT; + struct page *page; + int ret = 1; + + while (index <= end_index) { + page = find_get_page(inode->i_mapping, index); + kmap(page); + kunmap(page); + put_page(page); + index++; + } + + return ret; +} diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 87f6d3332163e2949465a9b85f8c7c73d963e584..d2781ff8f994bd412d2ed36abfe8938bfeb35437 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -99,8 +99,8 @@ enum btrfs_compression_type { BTRFS_COMPRESS_NONE = 0, BTRFS_COMPRESS_ZLIB = 1, BTRFS_COMPRESS_LZO = 2, - BTRFS_COMPRESS_TYPES = 2, - BTRFS_COMPRESS_LAST = 3, + BTRFS_COMPRESS_ZSTD = 3, + BTRFS_COMPRESS_TYPES = 3, }; struct btrfs_compress_op { @@ -128,5 +128,8 @@ struct btrfs_compress_op { extern const struct btrfs_compress_op btrfs_zlib_compress; extern const struct btrfs_compress_op btrfs_lzo_compress; +extern const struct btrfs_compress_op btrfs_zstd_compress; + +int btrfs_compress_heuristic(struct inode *inode, u64 start, u64 end); #endif diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 3f4daa9d6e2cc8df872e9cf6141eaaf89a4155f9..6d49db7d86be29c1fa256b60a7ee9beab3d9b1ed 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -4650,7 +4650,7 @@ void btrfs_truncate_item(struct btrfs_fs_info *fs_info, btrfs_mark_buffer_dirty(leaf); if (btrfs_leaf_free_space(fs_info, leaf) < 0) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); BUG(); } } @@ -4679,7 +4679,7 @@ void btrfs_extend_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path, data_end = leaf_data_end(fs_info, leaf); if (btrfs_leaf_free_space(fs_info, leaf) < data_size) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); BUG(); } slot = path->slots[0]; @@ -4687,7 +4687,7 @@ void btrfs_extend_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path, BUG_ON(slot < 0); if (slot >= nritems) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); btrfs_crit(fs_info, "slot %d too large, nritems %d", slot, nritems); BUG_ON(1); @@ -4718,7 +4718,7 @@ void btrfs_extend_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path, btrfs_mark_buffer_dirty(leaf); if (btrfs_leaf_free_space(fs_info, leaf) < 0) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); BUG(); } } @@ -4757,7 +4757,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, data_end = leaf_data_end(fs_info, leaf); if (btrfs_leaf_free_space(fs_info, leaf) < total_size) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); btrfs_crit(fs_info, "not enough freespace need %u have %d", total_size, btrfs_leaf_free_space(fs_info, leaf)); BUG(); @@ -4767,7 +4767,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, unsigned int old_data = btrfs_item_end_nr(leaf, slot); if (old_data < data_end) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); btrfs_crit(fs_info, "slot %d old_data %d data_end %d", slot, old_data, data_end); BUG_ON(1); @@ -4811,7 +4811,7 @@ void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, btrfs_mark_buffer_dirty(leaf); if (btrfs_leaf_free_space(fs_info, leaf) < 0) { - btrfs_print_leaf(fs_info, leaf); + btrfs_print_leaf(leaf); BUG(); } } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3f3eb7b17cac5c84be5883a5577b547eb8847b90..8fc690384c585779a9a6838b08228b41468a49b6 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -270,6 +270,7 @@ struct btrfs_super_block { BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \ BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \ BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \ + BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD | \ BTRFS_FEATURE_INCOMPAT_RAID56 | \ BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \ BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA | \ @@ -470,8 +471,8 @@ struct btrfs_block_rsv { /* * free clusters are used to claim free space in relatively large chunks, - * allowing us to do less seeky writes. They are used for all metadata - * allocations and data allocations in ssd mode. + * allowing us to do less seeky writes. They are used for all metadata + * allocations. In ssd_spread mode they are also used for data allocations. */ struct btrfs_free_cluster { spinlock_t lock; @@ -558,7 +559,6 @@ struct btrfs_block_group_cache { u64 bytes_super; u64 flags; u64 cache_generation; - u32 sectorsize; /* * If the free space extent count exceeds this number, convert the block @@ -709,7 +709,6 @@ struct btrfs_delayed_root; #define BTRFS_FS_OPEN 5 #define BTRFS_FS_QUOTA_ENABLED 6 #define BTRFS_FS_QUOTA_ENABLING 7 -#define BTRFS_FS_QUOTA_DISABLING 8 #define BTRFS_FS_UPDATE_UUID_TREE_GEN 9 #define BTRFS_FS_CREATING_FREE_SPACE_TREE 10 #define BTRFS_FS_BTREE_ERR 11 @@ -723,7 +722,7 @@ struct btrfs_delayed_root; * Indicate that a whole-filesystem exclusive operation is running * (device replace, resize, device add/delete, balance) */ -#define BTRFS_FS_EXCL_OP 14 +#define BTRFS_FS_EXCL_OP 16 struct btrfs_fs_info { u8 fsid[BTRFS_FSID_SIZE]; @@ -968,7 +967,7 @@ struct btrfs_fs_info { struct reloc_control *reloc_ctl; - /* data_alloc_cluster is only used in ssd mode */ + /* data_alloc_cluster is only used in ssd_spread mode */ struct btrfs_free_cluster data_alloc_cluster; /* all metadata allocations go through this cluster */ @@ -1072,8 +1071,6 @@ struct btrfs_fs_info { /* next backup root to be overwritten */ int backup_root_index; - int num_tolerated_disk_barrier_failures; - /* device replace state */ struct btrfs_dev_replace dev_replace; @@ -1261,12 +1258,17 @@ struct btrfs_root { */ int send_in_progress; struct btrfs_subvolume_writers *subv_writers; - atomic_t will_be_snapshoted; + atomic_t will_be_snapshotted; /* For qgroup metadata space reserve */ atomic64_t qgroup_meta_rsv; }; +struct btrfs_file_private { + struct btrfs_trans_handle *trans; + void *filldir_buf; +}; + static inline u32 btrfs_inode_sectorsize(const struct inode *inode) { return btrfs_sb(inode->i_sb)->sectorsize; @@ -1435,7 +1437,7 @@ do { \ #define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) struct btrfs_map_token { - struct extent_buffer *eb; + const struct extent_buffer *eb; char *kaddr; unsigned long offset; }; @@ -1469,18 +1471,19 @@ static inline void btrfs_init_map_token (struct btrfs_map_token *token) sizeof(((type *)0)->member))) #define DECLARE_BTRFS_SETGET_BITS(bits) \ -u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ - unsigned long off, \ - struct btrfs_map_token *token); \ -void btrfs_set_token_##bits(struct extent_buffer *eb, void *ptr, \ +u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \ + const void *ptr, unsigned long off, \ + struct btrfs_map_token *token); \ +void btrfs_set_token_##bits(struct extent_buffer *eb, const void *ptr, \ unsigned long off, u##bits val, \ struct btrfs_map_token *token); \ -static inline u##bits btrfs_get_##bits(struct extent_buffer *eb, void *ptr, \ +static inline u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ + const void *ptr, \ unsigned long off) \ { \ return btrfs_get_token_##bits(eb, ptr, off, NULL); \ } \ -static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \ +static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr,\ unsigned long off, u##bits val) \ { \ btrfs_set_token_##bits(eb, ptr, off, val, NULL); \ @@ -1492,7 +1495,8 @@ DECLARE_BTRFS_SETGET_BITS(32) DECLARE_BTRFS_SETGET_BITS(64) #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ -static inline u##bits btrfs_##name(struct extent_buffer *eb, type *s) \ +static inline u##bits btrfs_##name(const struct extent_buffer *eb, \ + const type *s) \ { \ BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ return btrfs_get_##bits(eb, s, offsetof(type, member)); \ @@ -1503,7 +1507,8 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, type *s, \ BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ btrfs_set_##bits(eb, s, offsetof(type, member), val); \ } \ -static inline u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, \ +static inline u##bits btrfs_token_##name(const struct extent_buffer *eb,\ + const type *s, \ struct btrfs_map_token *token) \ { \ BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ @@ -1518,9 +1523,9 @@ static inline void btrfs_set_token_##name(struct extent_buffer *eb, \ } #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ -static inline u##bits btrfs_##name(struct extent_buffer *eb) \ +static inline u##bits btrfs_##name(const struct extent_buffer *eb) \ { \ - type *p = page_address(eb->pages[0]); \ + const type *p = page_address(eb->pages[0]); \ u##bits res = le##bits##_to_cpu(p->member); \ return res; \ } \ @@ -1532,7 +1537,7 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \ } #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ -static inline u##bits btrfs_##name(type *s) \ +static inline u##bits btrfs_##name(const type *s) \ { \ return le##bits##_to_cpu(s->member); \ } \ @@ -1799,7 +1804,6 @@ static inline u32 btrfs_extent_inline_ref_size(int type) if (type == BTRFS_EXTENT_DATA_REF_KEY) return sizeof(struct btrfs_extent_data_ref) + offsetof(struct btrfs_extent_inline_ref, offset); - BUG(); return 0; } @@ -1857,7 +1861,7 @@ static inline unsigned long btrfs_node_key_ptr_offset(int nr) sizeof(struct btrfs_key_ptr) * nr; } -void btrfs_node_key(struct extent_buffer *eb, +void btrfs_node_key(const struct extent_buffer *eb, struct btrfs_disk_key *disk_key, int nr); static inline void btrfs_set_node_key(struct extent_buffer *eb, @@ -1886,28 +1890,28 @@ static inline struct btrfs_item *btrfs_item_nr(int nr) return (struct btrfs_item *)btrfs_item_nr_offset(nr); } -static inline u32 btrfs_item_end(struct extent_buffer *eb, +static inline u32 btrfs_item_end(const struct extent_buffer *eb, struct btrfs_item *item) { return btrfs_item_offset(eb, item) + btrfs_item_size(eb, item); } -static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) +static inline u32 btrfs_item_end_nr(const struct extent_buffer *eb, int nr) { return btrfs_item_end(eb, btrfs_item_nr(nr)); } -static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) +static inline u32 btrfs_item_offset_nr(const struct extent_buffer *eb, int nr) { return btrfs_item_offset(eb, btrfs_item_nr(nr)); } -static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) +static inline u32 btrfs_item_size_nr(const struct extent_buffer *eb, int nr) { return btrfs_item_size(eb, btrfs_item_nr(nr)); } -static inline void btrfs_item_key(struct extent_buffer *eb, +static inline void btrfs_item_key(const struct extent_buffer *eb, struct btrfs_disk_key *disk_key, int nr) { struct btrfs_item *item = btrfs_item_nr(nr); @@ -1943,8 +1947,8 @@ BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, BTRFS_SETGET_STACK_FUNCS(stack_dir_transid, struct btrfs_dir_item, transid, 64); -static inline void btrfs_dir_item_key(struct extent_buffer *eb, - struct btrfs_dir_item *item, +static inline void btrfs_dir_item_key(const struct extent_buffer *eb, + const struct btrfs_dir_item *item, struct btrfs_disk_key *key) { read_eb_member(eb, item, struct btrfs_dir_item, location, key); @@ -1952,7 +1956,7 @@ static inline void btrfs_dir_item_key(struct extent_buffer *eb, static inline void btrfs_set_dir_item_key(struct extent_buffer *eb, struct btrfs_dir_item *item, - struct btrfs_disk_key *key) + const struct btrfs_disk_key *key) { write_eb_member(eb, item, struct btrfs_dir_item, location, key); } @@ -1964,8 +1968,8 @@ BTRFS_SETGET_FUNCS(free_space_bitmaps, struct btrfs_free_space_header, BTRFS_SETGET_FUNCS(free_space_generation, struct btrfs_free_space_header, generation, 64); -static inline void btrfs_free_space_key(struct extent_buffer *eb, - struct btrfs_free_space_header *h, +static inline void btrfs_free_space_key(const struct extent_buffer *eb, + const struct btrfs_free_space_header *h, struct btrfs_disk_key *key) { read_eb_member(eb, h, struct btrfs_free_space_header, location, key); @@ -1973,7 +1977,7 @@ static inline void btrfs_free_space_key(struct extent_buffer *eb, static inline void btrfs_set_free_space_key(struct extent_buffer *eb, struct btrfs_free_space_header *h, - struct btrfs_disk_key *key) + const struct btrfs_disk_key *key) { write_eb_member(eb, h, struct btrfs_free_space_header, location, key); } @@ -2000,25 +2004,25 @@ static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk, disk->objectid = cpu_to_le64(cpu->objectid); } -static inline void btrfs_node_key_to_cpu(struct extent_buffer *eb, - struct btrfs_key *key, int nr) +static inline void btrfs_node_key_to_cpu(const struct extent_buffer *eb, + struct btrfs_key *key, int nr) { struct btrfs_disk_key disk_key; btrfs_node_key(eb, &disk_key, nr); btrfs_disk_key_to_cpu(key, &disk_key); } -static inline void btrfs_item_key_to_cpu(struct extent_buffer *eb, - struct btrfs_key *key, int nr) +static inline void btrfs_item_key_to_cpu(const struct extent_buffer *eb, + struct btrfs_key *key, int nr) { struct btrfs_disk_key disk_key; btrfs_item_key(eb, &disk_key, nr); btrfs_disk_key_to_cpu(key, &disk_key); } -static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, - struct btrfs_dir_item *item, - struct btrfs_key *key) +static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb, + const struct btrfs_dir_item *item, + struct btrfs_key *key) { struct btrfs_disk_key disk_key; btrfs_dir_item_key(eb, item, &disk_key); @@ -2050,7 +2054,7 @@ BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, nritems, 32); BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64); -static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag) +static inline int btrfs_header_flag(const struct extent_buffer *eb, u64 flag) { return (btrfs_header_flags(eb) & flag) == flag; } @@ -2069,7 +2073,7 @@ static inline int btrfs_clear_header_flag(struct extent_buffer *eb, u64 flag) return (flags & flag) == flag; } -static inline int btrfs_header_backref_rev(struct extent_buffer *eb) +static inline int btrfs_header_backref_rev(const struct extent_buffer *eb) { u64 flags = btrfs_header_flags(eb); return flags >> BTRFS_BACKREF_REV_SHIFT; @@ -2089,12 +2093,12 @@ static inline unsigned long btrfs_header_fsid(void) return offsetof(struct btrfs_header, fsid); } -static inline unsigned long btrfs_header_chunk_tree_uuid(struct extent_buffer *eb) +static inline unsigned long btrfs_header_chunk_tree_uuid(const struct extent_buffer *eb) { return offsetof(struct btrfs_header, chunk_tree_uuid); } -static inline int btrfs_is_leaf(struct extent_buffer *eb) +static inline int btrfs_is_leaf(const struct extent_buffer *eb) { return btrfs_header_level(eb) == 0; } @@ -2128,12 +2132,12 @@ BTRFS_SETGET_STACK_FUNCS(root_stransid, struct btrfs_root_item, BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item, rtransid, 64); -static inline bool btrfs_root_readonly(struct btrfs_root *root) +static inline bool btrfs_root_readonly(const struct btrfs_root *root) { return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; } -static inline bool btrfs_root_dead(struct btrfs_root *root) +static inline bool btrfs_root_dead(const struct btrfs_root *root) { return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0; } @@ -2190,51 +2194,51 @@ BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup, /* struct btrfs_balance_item */ BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64); -static inline void btrfs_balance_data(struct extent_buffer *eb, - struct btrfs_balance_item *bi, +static inline void btrfs_balance_data(const struct extent_buffer *eb, + const struct btrfs_balance_item *bi, struct btrfs_disk_balance_args *ba) { read_eb_member(eb, bi, struct btrfs_balance_item, data, ba); } static inline void btrfs_set_balance_data(struct extent_buffer *eb, - struct btrfs_balance_item *bi, - struct btrfs_disk_balance_args *ba) + struct btrfs_balance_item *bi, + const struct btrfs_disk_balance_args *ba) { write_eb_member(eb, bi, struct btrfs_balance_item, data, ba); } -static inline void btrfs_balance_meta(struct extent_buffer *eb, - struct btrfs_balance_item *bi, +static inline void btrfs_balance_meta(const struct extent_buffer *eb, + const struct btrfs_balance_item *bi, struct btrfs_disk_balance_args *ba) { read_eb_member(eb, bi, struct btrfs_balance_item, meta, ba); } static inline void btrfs_set_balance_meta(struct extent_buffer *eb, - struct btrfs_balance_item *bi, - struct btrfs_disk_balance_args *ba) + struct btrfs_balance_item *bi, + const struct btrfs_disk_balance_args *ba) { write_eb_member(eb, bi, struct btrfs_balance_item, meta, ba); } -static inline void btrfs_balance_sys(struct extent_buffer *eb, - struct btrfs_balance_item *bi, +static inline void btrfs_balance_sys(const struct extent_buffer *eb, + const struct btrfs_balance_item *bi, struct btrfs_disk_balance_args *ba) { read_eb_member(eb, bi, struct btrfs_balance_item, sys, ba); } static inline void btrfs_set_balance_sys(struct extent_buffer *eb, - struct btrfs_balance_item *bi, - struct btrfs_disk_balance_args *ba) + struct btrfs_balance_item *bi, + const struct btrfs_disk_balance_args *ba) { write_eb_member(eb, bi, struct btrfs_balance_item, sys, ba); } static inline void btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, - struct btrfs_disk_balance_args *disk) + const struct btrfs_disk_balance_args *disk) { memset(cpu, 0, sizeof(*cpu)); @@ -2254,7 +2258,7 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, static inline void btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk, - struct btrfs_balance_args *cpu) + const struct btrfs_balance_args *cpu) { memset(disk, 0, sizeof(*disk)); @@ -2322,7 +2326,7 @@ BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64); BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, uuid_tree_generation, 64); -static inline int btrfs_super_csum_size(struct btrfs_super_block *s) +static inline int btrfs_super_csum_size(const struct btrfs_super_block *s) { u16 t = btrfs_super_csum_type(s); /* @@ -2337,8 +2341,8 @@ static inline int btrfs_super_csum_size(struct btrfs_super_block *s) * this returns the address of the start of the last item, * which is the stop of the leaf data stack */ -static inline unsigned int leaf_data_end(struct btrfs_fs_info *fs_info, - struct extent_buffer *leaf) +static inline unsigned int leaf_data_end(const struct btrfs_fs_info *fs_info, + const struct extent_buffer *leaf) { u32 nr = btrfs_header_nritems(leaf); @@ -2363,7 +2367,7 @@ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_compression, struct btrfs_file_extent_item, compression, 8); static inline unsigned long -btrfs_file_extent_inline_start(struct btrfs_file_extent_item *e) +btrfs_file_extent_inline_start(const struct btrfs_file_extent_item *e) { return (unsigned long)e + BTRFS_FILE_EXTENT_INLINE_DATA_START; } @@ -2397,8 +2401,9 @@ BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, * size of any extent headers. If a file is compressed on disk, this is * the compressed size */ -static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, - struct btrfs_item *e) +static inline u32 btrfs_file_extent_inline_item_len( + const struct extent_buffer *eb, + struct btrfs_item *e) { return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START; } @@ -2406,9 +2411,9 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, /* this returns the number of file bytes represented by the inline item. * If an item is compressed, this is the uncompressed size */ -static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, - int slot, - struct btrfs_file_extent_item *fi) +static inline u32 btrfs_file_extent_inline_len(const struct extent_buffer *eb, + int slot, + const struct btrfs_file_extent_item *fi) { struct btrfs_map_token token; @@ -2430,8 +2435,8 @@ static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, /* btrfs_dev_stats_item */ -static inline u64 btrfs_dev_stats_value(struct extent_buffer *eb, - struct btrfs_dev_stats_item *ptr, +static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb, + const struct btrfs_dev_stats_item *ptr, int index) { u64 val; @@ -2561,6 +2566,17 @@ static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping) /* extent-tree.c */ +enum btrfs_inline_ref_type { + BTRFS_REF_TYPE_INVALID = 0, + BTRFS_REF_TYPE_BLOCK = 1, + BTRFS_REF_TYPE_DATA = 2, + BTRFS_REF_TYPE_ANY = 3, +}; + +int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb, + struct btrfs_extent_inline_ref *iref, + enum btrfs_inline_ref_type is_data); + u64 btrfs_csum_bytes_to_leaves(struct btrfs_fs_info *fs_info, u64 csum_bytes); static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_fs_info *fs_info, @@ -2670,8 +2686,7 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info); int btrfs_can_relocate(struct btrfs_fs_info *fs_info, u64 bytenr); int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 bytes_used, - u64 type, u64 chunk_objectid, u64 chunk_offset, - u64 size); + u64 type, u64 chunk_offset, u64 size); struct btrfs_trans_handle *btrfs_start_trans_remove_block_group( struct btrfs_fs_info *fs_info, const u64 chunk_offset); @@ -2772,8 +2787,8 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info); int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int __get_raid_index(u64 flags); -int btrfs_start_write_no_snapshoting(struct btrfs_root *root); -void btrfs_end_write_no_snapshoting(struct btrfs_root *root); +int btrfs_start_write_no_snapshotting(struct btrfs_root *root); +void btrfs_end_write_no_snapshotting(struct btrfs_root *root); void btrfs_wait_for_snapshot_creation(struct btrfs_root *root); void check_system_chunk(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, const u64 type); @@ -2973,8 +2988,8 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, const char *name, int name_len); -int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, - const struct btrfs_key *key); +int btrfs_del_root(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, const struct btrfs_key *key); int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, const struct btrfs_key *key, struct btrfs_root_item *item); @@ -3135,21 +3150,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, u64 *orig_start, u64 *orig_block_len, u64 *ram_bytes); -/* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */ -#if defined(ClearPageFsMisc) && !defined(ClearPageChecked) -#define ClearPageChecked ClearPageFsMisc -#define SetPageChecked SetPageFsMisc -#define PageChecked PageFsMisc -#endif - -/* This forces readahead on a given range of bytes in an inode */ -static inline void btrfs_force_ra(struct address_space *mapping, - struct file_ra_state *ra, struct file *file, - pgoff_t offset, unsigned long req_size) -{ - page_cache_sync_readahead(mapping, ra, file, offset, req_size); -} - struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index); int btrfs_unlink_inode(struct btrfs_trans_handle *trans, @@ -3229,7 +3229,6 @@ long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int btrfs_ioctl_get_supported_features(void __user *arg); void btrfs_update_iflags(struct inode *inode); -void btrfs_inherit_iflags(struct inode *inode, struct inode *dir); int btrfs_is_empty_uuid(u8 *uuid); int btrfs_defrag_file(struct inode *inode, struct file *file, struct btrfs_ioctl_defrag_range_args *range, diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 8ae409b5a61d7186f050780beced1bf72cd572ca..19e4ad2f3f2e4a32050024f34b4e0ebc3c6511b9 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -1727,6 +1727,7 @@ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, if (over) return 1; + ctx->pos++; } return 0; } diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index bee3edeea7a37404de4d428a57e90c6bbcac6bc1..7c655f9a7a504e5d758323e6be536cfb39753b2d 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -639,11 +639,39 @@ static void btrfs_dev_replace_update_device_in_mapping_tree( write_unlock(&em_tree->lock); } +/* + * Read progress of device replace status according to the state and last + * stored position. The value format is the same as for + * btrfs_dev_replace::progress_1000 + */ +static u64 btrfs_dev_replace_progress(struct btrfs_fs_info *fs_info) +{ + struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; + u64 ret = 0; + + switch (dev_replace->replace_state) { + case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: + case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: + ret = 0; + break; + case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: + ret = 1000; + break; + case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: + case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: + ret = div64_u64(dev_replace->cursor_left, + div_u64(btrfs_device_get_total_bytes( + dev_replace->srcdev), 1000)); + break; + } + + return ret; +} + void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, struct btrfs_ioctl_dev_replace_args *args) { struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; - struct btrfs_device *srcdev; btrfs_dev_replace_lock(dev_replace, 0); /* even if !dev_replace_is_valid, the values are good enough for @@ -656,21 +684,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, atomic64_read(&dev_replace->num_write_errors); args->status.num_uncorrectable_read_errors = atomic64_read(&dev_replace->num_uncorrectable_read_errors); - switch (dev_replace->replace_state) { - case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: - case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: - args->status.progress_1000 = 0; - break; - case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: - args->status.progress_1000 = 1000; - break; - case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: - case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: - srcdev = dev_replace->srcdev; - args->status.progress_1000 = div64_u64(dev_replace->cursor_left, - div_u64(btrfs_device_get_total_bytes(srcdev), 1000)); - break; - } + args->status.progress_1000 = btrfs_dev_replace_progress(fs_info); btrfs_dev_replace_unlock(dev_replace, 0); } @@ -690,7 +704,7 @@ static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) u64 result; int ret; - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) return -EROFS; mutex_lock(&dev_replace->lock_finishing_cancel_unmount); @@ -795,25 +809,19 @@ static int btrfs_dev_replace_kthread(void *data) { struct btrfs_fs_info *fs_info = data; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; - struct btrfs_ioctl_dev_replace_args *status_args; u64 progress; - status_args = kzalloc(sizeof(*status_args), GFP_KERNEL); - if (status_args) { - btrfs_dev_replace_status(fs_info, status_args); - progress = status_args->status.progress_1000; - kfree(status_args); - progress = div_u64(progress, 10); - btrfs_info_in_rcu(fs_info, - "continuing dev_replace from %s (devid %llu) to %s @%u%%", - dev_replace->srcdev->missing ? "" : - rcu_str_deref(dev_replace->srcdev->name), - dev_replace->srcdev->devid, - dev_replace->tgtdev ? - rcu_str_deref(dev_replace->tgtdev->name) : - "", - (unsigned int)progress); - } + progress = btrfs_dev_replace_progress(fs_info); + progress = div_u64(progress, 10); + btrfs_info_in_rcu(fs_info, + "continuing dev_replace from %s (devid %llu) to %s @%u%%", + dev_replace->srcdev->missing ? "" + : rcu_str_deref(dev_replace->srcdev->name), + dev_replace->srcdev->devid, + dev_replace->tgtdev ? rcu_str_deref(dev_replace->tgtdev->name) + : "", + (unsigned int)progress); + btrfs_dev_replace_continue_on_mount(fs_info); clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 080e2ebb8aa0137baef69edda45aa895bf8b7c7c..dfdab849037b70887e9a61d5b1044a313658d437 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -529,7 +529,7 @@ static int check_tree_block_fsid(struct btrfs_fs_info *fs_info, struct extent_buffer *eb) { struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; - u8 fsid[BTRFS_UUID_SIZE]; + u8 fsid[BTRFS_FSID_SIZE]; int ret = 1; read_extent_buffer(eb, fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); @@ -1343,7 +1343,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, atomic_set(&root->log_batch, 0); atomic_set(&root->orphan_inodes, 0); refcount_set(&root->refs, 1); - atomic_set(&root->will_be_snapshoted, 0); + atomic_set(&root->will_be_snapshotted, 0); atomic64_set(&root->qgroup_meta_rsv, 0); root->log_transid = 0; root->log_transid_committed = -1; @@ -2478,7 +2478,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, return ret; } - if (fs_info->sb->s_flags & MS_RDONLY) { + if (sb_rdonly(fs_info->sb)) { ret = btrfs_commit_super(fs_info); if (ret) return ret; @@ -2694,8 +2694,8 @@ int open_ctree(struct super_block *sb, btrfs_init_balance(fs_info); btrfs_init_async_reclaim_work(&fs_info->async_reclaim_work); - sb->s_blocksize = 4096; - sb->s_blocksize_bits = blksize_bits(4096); + sb->s_blocksize = BTRFS_BDEV_BLOCKSIZE; + sb->s_blocksize_bits = blksize_bits(BTRFS_BDEV_BLOCKSIZE); btrfs_init_btree_inode(fs_info); @@ -2828,6 +2828,8 @@ int open_ctree(struct super_block *sb, features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; if (fs_info->compress_type == BTRFS_COMPRESS_LZO) features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; + else if (fs_info->compress_type == BTRFS_COMPRESS_ZSTD) + features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD; if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA) btrfs_info(fs_info, "has skinny extents"); @@ -2874,7 +2876,7 @@ int open_ctree(struct super_block *sb, features = btrfs_super_compat_ro_flags(disk_super) & ~BTRFS_FEATURE_COMPAT_RO_SUPP; - if (!(sb->s_flags & MS_RDONLY) && features) { + if (!sb_rdonly(sb) && features) { btrfs_err(fs_info, "cannot mount read-write because of unsupported optional features (%llx)", features); @@ -3035,15 +3037,10 @@ int open_ctree(struct super_block *sb, btrfs_err(fs_info, "failed to read block groups: %d", ret); goto fail_sysfs; } - fs_info->num_tolerated_disk_barrier_failures = - btrfs_calc_num_tolerated_disk_barrier_failures(fs_info); - if (fs_info->fs_devices->missing_devices > - fs_info->num_tolerated_disk_barrier_failures && - !(sb->s_flags & MS_RDONLY)) { + + if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info)) { btrfs_warn(fs_info, -"missing devices (%llu) exceeds the limit (%d), writeable mount is not allowed", - fs_info->fs_devices->missing_devices, - fs_info->num_tolerated_disk_barrier_failures); + "writeable mount is not allowed due to too many missing devices"); goto fail_sysfs; } @@ -3058,11 +3055,9 @@ int open_ctree(struct super_block *sb, if (IS_ERR(fs_info->transaction_kthread)) goto fail_cleaner; - if (!btrfs_test_opt(fs_info, SSD) && - !btrfs_test_opt(fs_info, NOSSD) && + if (!btrfs_test_opt(fs_info, NOSSD) && !fs_info->fs_devices->rotating) { - btrfs_info(fs_info, "detected SSD devices, enabling SSD mode"); - btrfs_set_opt(fs_info->mount_opt, SSD); + btrfs_set_and_info(fs_info, SSD, "enabling ssd optimizations"); } /* @@ -3102,7 +3097,7 @@ int open_ctree(struct super_block *sb, if (ret) goto fail_qgroup; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { ret = btrfs_cleanup_fs_roots(fs_info); if (ret) goto fail_qgroup; @@ -3128,7 +3123,7 @@ int open_ctree(struct super_block *sb, goto fail_qgroup; } - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; if (btrfs_test_opt(fs_info, CLEAR_CACHE) && @@ -3321,7 +3316,7 @@ int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num, if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode)) return -EINVAL; - bh = __bread(bdev, bytenr / 4096, BTRFS_SUPER_INFO_SIZE); + bh = __bread(bdev, bytenr / BTRFS_BDEV_BLOCKSIZE, BTRFS_SUPER_INFO_SIZE); /* * If we fail to read from the underlying devices, as of now * the best option we have is to mark it EIO. @@ -3378,19 +3373,17 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) } /* - * this should be called twice, once with wait == 0 and - * once with wait == 1. When wait == 0 is done, all the buffer heads - * we write are pinned. + * Write superblock @sb to the @device. Do not wait for completion, all the + * buffer heads we write are pinned. * - * They are released when wait == 1 is done. - * max_mirrors must be the same for both runs, and it indicates how - * many supers on this one device should be written. + * Write @max_mirrors copies of the superblock, where 0 means default that fit + * the expected device size at commit time. Note that max_mirrors must be + * same for write and wait phases. * - * max_mirrors == 0 means to write them all. + * Return number of errors when buffer head is not found or submission fails. */ static int write_dev_supers(struct btrfs_device *device, - struct btrfs_super_block *sb, - int wait, int max_mirrors) + struct btrfs_super_block *sb, int max_mirrors) { struct buffer_head *bh; int i; @@ -3408,57 +3401,33 @@ static int write_dev_supers(struct btrfs_device *device, device->commit_total_bytes) break; - if (wait) { - bh = __find_get_block(device->bdev, bytenr / 4096, - BTRFS_SUPER_INFO_SIZE); - if (!bh) { - errors++; - continue; - } - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) - errors++; + btrfs_set_super_bytenr(sb, bytenr); - /* drop our reference */ - brelse(bh); + crc = ~(u32)0; + crc = btrfs_csum_data((const char *)sb + BTRFS_CSUM_SIZE, crc, + BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); + btrfs_csum_final(crc, sb->csum); - /* drop the reference from the wait == 0 run */ - brelse(bh); + /* One reference for us, and we leave it for the caller */ + bh = __getblk(device->bdev, bytenr / BTRFS_BDEV_BLOCKSIZE, + BTRFS_SUPER_INFO_SIZE); + if (!bh) { + btrfs_err(device->fs_info, + "couldn't get super buffer head for bytenr %llu", + bytenr); + errors++; continue; - } else { - btrfs_set_super_bytenr(sb, bytenr); - - crc = ~(u32)0; - crc = btrfs_csum_data((const char *)sb + - BTRFS_CSUM_SIZE, crc, - BTRFS_SUPER_INFO_SIZE - - BTRFS_CSUM_SIZE); - btrfs_csum_final(crc, sb->csum); - - /* - * one reference for us, and we leave it for the - * caller - */ - bh = __getblk(device->bdev, bytenr / 4096, - BTRFS_SUPER_INFO_SIZE); - if (!bh) { - btrfs_err(device->fs_info, - "couldn't get super buffer head for bytenr %llu", - bytenr); - errors++; - continue; - } + } - memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); + memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); - /* one reference for submit_bh */ - get_bh(bh); + /* one reference for submit_bh */ + get_bh(bh); - set_buffer_uptodate(bh); - lock_buffer(bh); - bh->b_end_io = btrfs_end_buffer_write_sync; - bh->b_private = device; - } + set_buffer_uptodate(bh); + lock_buffer(bh); + bh->b_end_io = btrfs_end_buffer_write_sync; + bh->b_private = device; /* * we fua the first super. The others we allow @@ -3466,9 +3435,10 @@ static int write_dev_supers(struct btrfs_device *device, */ if (i == 0) { ret = btrfsic_submit_bh(REQ_OP_WRITE, - REQ_SYNC | REQ_FUA, bh); + REQ_SYNC | REQ_FUA | REQ_META | REQ_PRIO, bh); } else { - ret = btrfsic_submit_bh(REQ_OP_WRITE, REQ_SYNC, bh); + ret = btrfsic_submit_bh(REQ_OP_WRITE, + REQ_SYNC | REQ_META | REQ_PRIO, bh); } if (ret) errors++; @@ -3476,6 +3446,50 @@ static int write_dev_supers(struct btrfs_device *device, return errors < i ? 0 : -1; } +/* + * Wait for write completion of superblocks done by write_dev_supers, + * @max_mirrors same for write and wait phases. + * + * Return number of errors when buffer head is not found or not marked up to + * date. + */ +static int wait_dev_supers(struct btrfs_device *device, int max_mirrors) +{ + struct buffer_head *bh; + int i; + int errors = 0; + u64 bytenr; + + if (max_mirrors == 0) + max_mirrors = BTRFS_SUPER_MIRROR_MAX; + + for (i = 0; i < max_mirrors; i++) { + bytenr = btrfs_sb_offset(i); + if (bytenr + BTRFS_SUPER_INFO_SIZE >= + device->commit_total_bytes) + break; + + bh = __find_get_block(device->bdev, + bytenr / BTRFS_BDEV_BLOCKSIZE, + BTRFS_SUPER_INFO_SIZE); + if (!bh) { + errors++; + continue; + } + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) + errors++; + + /* drop our reference */ + brelse(bh); + + /* drop the reference from the writing run */ + brelse(bh); + } + + return errors < i ? 0 : -1; +} + /* * endio for the write_dev_flush, this will wake anyone waiting * for the barrier when it is done @@ -3499,12 +3513,12 @@ static void write_dev_flush(struct btrfs_device *device) bio_reset(bio); bio->bi_end_io = btrfs_end_empty_barrier; - bio->bi_bdev = device->bdev; + bio_set_dev(bio, device->bdev); bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH; init_completion(&device->flush_wait); bio->bi_private = &device->flush_wait; - submit_bio(bio); + btrfsic_submit_bio(bio); device->flush_bio_sent = 1; } @@ -3516,7 +3530,7 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device) struct bio *bio = device->flush_bio; if (!device->flush_bio_sent) - return 0; + return BLK_STS_OK; device->flush_bio_sent = 0; wait_for_completion_io(&device->flush_wait); @@ -3524,20 +3538,10 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device) return bio->bi_status; } -static int check_barrier_error(struct btrfs_fs_devices *fsdevs) +static int check_barrier_error(struct btrfs_fs_info *fs_info) { - int dev_flush_error = 0; - struct btrfs_device *dev; - - list_for_each_entry_rcu(dev, &fsdevs->devices, dev_list) { - if (!dev->bdev || dev->last_flush_error) - dev_flush_error++; - } - - if (dev_flush_error > - fsdevs->fs_info->num_tolerated_disk_barrier_failures) + if (!btrfs_check_rw_degradable(fs_info)) return -EIO; - return 0; } @@ -3563,7 +3567,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info) continue; write_dev_flush(dev); - dev->last_flush_error = 0; + dev->last_flush_error = BLK_STS_OK; } /* wait for all the barriers */ @@ -3592,7 +3596,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info) * to arrive at the volume status. So error checking * is being pushed to a separate loop. */ - return check_barrier_error(info->fs_devices); + return check_barrier_error(info); } return 0; } @@ -3626,60 +3630,6 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags) return min_tolerated; } -int btrfs_calc_num_tolerated_disk_barrier_failures( - struct btrfs_fs_info *fs_info) -{ - struct btrfs_ioctl_space_info space; - struct btrfs_space_info *sinfo; - u64 types[] = {BTRFS_BLOCK_GROUP_DATA, - BTRFS_BLOCK_GROUP_SYSTEM, - BTRFS_BLOCK_GROUP_METADATA, - BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA}; - int i; - int c; - int num_tolerated_disk_barrier_failures = - (int)fs_info->fs_devices->num_devices; - - for (i = 0; i < ARRAY_SIZE(types); i++) { - struct btrfs_space_info *tmp; - - sinfo = NULL; - rcu_read_lock(); - list_for_each_entry_rcu(tmp, &fs_info->space_info, list) { - if (tmp->flags == types[i]) { - sinfo = tmp; - break; - } - } - rcu_read_unlock(); - - if (!sinfo) - continue; - - down_read(&sinfo->groups_sem); - for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) { - u64 flags; - - if (list_empty(&sinfo->block_groups[c])) - continue; - - btrfs_get_block_group_info(&sinfo->block_groups[c], - &space); - if (space.total_bytes == 0 || space.used_bytes == 0) - continue; - flags = space.flags; - - num_tolerated_disk_barrier_failures = min( - num_tolerated_disk_barrier_failures, - btrfs_get_num_tolerated_disk_barrier_failures( - flags)); - } - up_read(&sinfo->groups_sem); - } - - return num_tolerated_disk_barrier_failures; -} - int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) { struct list_head *head; @@ -3693,7 +3643,14 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) u64 flags; do_barriers = !btrfs_test_opt(fs_info, NOBARRIER); - backup_super_roots(fs_info); + + /* + * max_mirrors == 0 indicates we're from commit_transaction, + * not from fsync where the tree roots in fs_info have not + * been consistent on disk. + */ + if (max_mirrors == 0) + backup_super_roots(fs_info); sb = fs_info->super_for_commit; dev_item = &sb->dev_item; @@ -3732,12 +3689,12 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) btrfs_set_stack_device_io_width(dev_item, dev->io_width); btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); - memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE); + memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_FSID_SIZE); flags = btrfs_super_flags(sb); btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); - ret = write_dev_supers(dev, sb, 0, max_mirrors); + ret = write_dev_supers(dev, sb, max_mirrors); if (ret) total_errors++; } @@ -3760,7 +3717,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) if (!dev->in_fs_metadata || !dev->writeable) continue; - ret = write_dev_supers(dev, sb, 1, max_mirrors); + ret = wait_dev_supers(dev, max_mirrors); if (ret) total_errors++; } @@ -3928,7 +3885,7 @@ void close_ctree(struct btrfs_fs_info *fs_info) cancel_work_sync(&fs_info->async_reclaim_work); - if (!(fs_info->sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(fs_info->sb)) { /* * If the cleaner thread is stopped and there are * block groups queued for removal, the deletion will be @@ -3995,7 +3952,6 @@ void close_ctree(struct btrfs_fs_info *fs_info) __btrfs_free_block_rsv(root->orphan_block_rsv); root->orphan_block_rsv = NULL; - mutex_lock(&fs_info->chunk_mutex); while (!list_empty(&fs_info->pinned_chunks)) { struct extent_map *em; @@ -4004,7 +3960,6 @@ void close_ctree(struct btrfs_fs_info *fs_info) list_del_init(&em->list); free_extent_map(em); } - mutex_unlock(&fs_info->chunk_mutex); } int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, @@ -4053,7 +4008,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) fs_info->dirty_metadata_batch); #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY if (btrfs_header_level(buf) == 0 && check_leaf(root, buf)) { - btrfs_print_leaf(fs_info, buf); + btrfs_print_leaf(buf); ASSERT(0); } #endif @@ -4173,7 +4128,7 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info) ret = -EINVAL; } - if (memcmp(fs_info->fsid, sb->dev_item.fsid, BTRFS_UUID_SIZE) != 0) { + if (memcmp(fs_info->fsid, sb->dev_item.fsid, BTRFS_FSID_SIZE) != 0) { btrfs_err(fs_info, "dev_item UUID does not match fsid: %pU != %pU", fs_info->fsid, sb->dev_item.fsid); diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 0a634d3ffc16d1069fbfeab1e02dc42c6bf481d2..7f7c35d6347a39107ee0d43e4160b7ca7efabdc8 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -25,6 +25,14 @@ #define BTRFS_SUPER_MIRROR_MAX 3 #define BTRFS_SUPER_MIRROR_SHIFT 12 +/* + * Fixed blocksize for all devices, applies to specific ways of reading + * metadata like superblock. Must meet the set_blocksize requirements. + * + * Do not change. + */ +#define BTRFS_BDEV_BLOCKSIZE (4096) + enum btrfs_wq_endio_type { BTRFS_WQ_ENDIO_DATA = 0, BTRFS_WQ_ENDIO_METADATA = 1, @@ -142,8 +150,6 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, int btree_lock_page_hook(struct page *page, void *data, void (*flush_fn)(void *)); int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags); -int btrfs_calc_num_tolerated_disk_barrier_failures( - struct btrfs_fs_info *fs_info); int __init btrfs_end_io_wq_init(void); void btrfs_end_io_wq_exit(void); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e3b0b4196d3df173fd52d62076396f21029f073d..e2d7e86b51d1b24059dda46fda085174ac993a3f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -1148,6 +1148,64 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, } #endif +/* + * is_data == BTRFS_REF_TYPE_BLOCK, tree block type is required, + * is_data == BTRFS_REF_TYPE_DATA, data type is requried, + * is_data == BTRFS_REF_TYPE_ANY, either type is OK. + */ +int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb, + struct btrfs_extent_inline_ref *iref, + enum btrfs_inline_ref_type is_data) +{ + int type = btrfs_extent_inline_ref_type(eb, iref); + u64 offset = btrfs_extent_inline_ref_offset(eb, iref); + + if (type == BTRFS_TREE_BLOCK_REF_KEY || + type == BTRFS_SHARED_BLOCK_REF_KEY || + type == BTRFS_SHARED_DATA_REF_KEY || + type == BTRFS_EXTENT_DATA_REF_KEY) { + if (is_data == BTRFS_REF_TYPE_BLOCK) { + if (type == BTRFS_TREE_BLOCK_REF_KEY) + return type; + if (type == BTRFS_SHARED_BLOCK_REF_KEY) { + ASSERT(eb->fs_info); + /* + * Every shared one has parent tree + * block, which must be aligned to + * nodesize. + */ + if (offset && + IS_ALIGNED(offset, eb->fs_info->nodesize)) + return type; + } + } else if (is_data == BTRFS_REF_TYPE_DATA) { + if (type == BTRFS_EXTENT_DATA_REF_KEY) + return type; + if (type == BTRFS_SHARED_DATA_REF_KEY) { + ASSERT(eb->fs_info); + /* + * Every shared one has parent tree + * block, which must be aligned to + * nodesize. + */ + if (offset && + IS_ALIGNED(offset, eb->fs_info->nodesize)) + return type; + } + } else { + ASSERT(is_data == BTRFS_REF_TYPE_ANY); + return type; + } + } + + btrfs_print_leaf((struct extent_buffer *)eb); + btrfs_err(eb->fs_info, "eb %llu invalid extent inline ref type %d", + eb->start, type); + WARN_ON(1); + + return BTRFS_REF_TYPE_INVALID; +} + static u64 hash_extent_data_ref(u64 root_objectid, u64 owner, u64 offset) { u32 high_crc = ~(u32)0; @@ -1417,12 +1475,18 @@ static noinline u32 extent_data_ref_count(struct btrfs_path *path, struct btrfs_extent_data_ref *ref1; struct btrfs_shared_data_ref *ref2; u32 num_refs = 0; + int type; leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); if (iref) { - if (btrfs_extent_inline_ref_type(leaf, iref) == - BTRFS_EXTENT_DATA_REF_KEY) { + /* + * If type is invalid, we should have bailed out earlier than + * this call. + */ + type = btrfs_get_extent_inline_ref_type(leaf, iref, BTRFS_REF_TYPE_DATA); + ASSERT(type != BTRFS_REF_TYPE_INVALID); + if (type == BTRFS_EXTENT_DATA_REF_KEY) { ref1 = (struct btrfs_extent_data_ref *)(&iref->offset); num_refs = btrfs_extent_data_ref_count(leaf, ref1); } else { @@ -1583,6 +1647,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, int ret; int err = 0; bool skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA); + int needed; key.objectid = bytenr; key.type = BTRFS_EXTENT_ITEM_KEY; @@ -1674,6 +1739,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, BUG_ON(ptr > end); } + if (owner >= BTRFS_FIRST_FREE_OBJECTID) + needed = BTRFS_REF_TYPE_DATA; + else + needed = BTRFS_REF_TYPE_BLOCK; + err = -ENOENT; while (1) { if (ptr >= end) { @@ -1681,7 +1751,12 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, break; } iref = (struct btrfs_extent_inline_ref *)ptr; - type = btrfs_extent_inline_ref_type(leaf, iref); + type = btrfs_get_extent_inline_ref_type(leaf, iref, needed); + if (type == BTRFS_REF_TYPE_INVALID) { + err = -EINVAL; + goto out; + } + if (want < type) break; if (want > type) { @@ -1873,7 +1948,12 @@ void update_inline_extent_backref(struct btrfs_fs_info *fs_info, if (extent_op) __run_delayed_extent_op(extent_op, leaf, ei); - type = btrfs_extent_inline_ref_type(leaf, iref); + /* + * If type is invalid, we should have bailed out after + * lookup_inline_extent_backref(). + */ + type = btrfs_get_extent_inline_ref_type(leaf, iref, BTRFS_REF_TYPE_ANY); + ASSERT(type != BTRFS_REF_TYPE_INVALID); if (type == BTRFS_EXTENT_DATA_REF_KEY) { dref = (struct btrfs_extent_data_ref *)(&iref->offset); @@ -3158,6 +3238,7 @@ static noinline int check_committed_ref(struct btrfs_root *root, struct btrfs_extent_item *ei; struct btrfs_key key; u32 item_size; + int type; int ret; key.objectid = bytenr; @@ -3199,8 +3280,9 @@ static noinline int check_committed_ref(struct btrfs_root *root, goto out; iref = (struct btrfs_extent_inline_ref *)(ei + 1); - if (btrfs_extent_inline_ref_type(leaf, iref) != - BTRFS_EXTENT_DATA_REF_KEY) + + type = btrfs_get_extent_inline_ref_type(leaf, iref, BTRFS_REF_TYPE_DATA); + if (type != BTRFS_EXTENT_DATA_REF_KEY) goto out; ref = (struct btrfs_extent_data_ref *)(&iref->offset); @@ -4199,9 +4281,9 @@ static u64 btrfs_space_info_used(struct btrfs_space_info *s_info, int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes) { - struct btrfs_space_info *data_sinfo; struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_space_info *data_sinfo = fs_info->data_sinfo; u64 used; int ret = 0; int need_commit = 2; @@ -4215,10 +4297,6 @@ int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes) ASSERT(current->journal_info); } - data_sinfo = fs_info->data_sinfo; - if (!data_sinfo) - goto alloc; - again: /* make sure we have enough space to handle the data first */ spin_lock(&data_sinfo->lock); @@ -4236,7 +4314,7 @@ int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes) data_sinfo->force_alloc = CHUNK_ALLOC_FORCE; spin_unlock(&data_sinfo->lock); -alloc: + alloc_target = btrfs_data_alloc_profile(fs_info); /* * It is ugly that we don't call nolock join @@ -4264,9 +4342,6 @@ int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes) } } - if (!data_sinfo) - data_sinfo = fs_info->data_sinfo; - goto again; } @@ -4425,8 +4500,7 @@ static int should_alloc_chunk(struct btrfs_fs_info *fs_info, struct btrfs_space_info *sinfo, int force) { struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; - u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; - u64 num_allocated = sinfo->bytes_used + sinfo->bytes_reserved; + u64 bytes_used = btrfs_space_info_used(sinfo, false); u64 thresh; if (force == CHUNK_ALLOC_FORCE) @@ -4438,7 +4512,7 @@ static int should_alloc_chunk(struct btrfs_fs_info *fs_info, * global_rsv, it doesn't change except when the transaction commits. */ if (sinfo->flags & BTRFS_BLOCK_GROUP_METADATA) - num_allocated += calc_global_rsv_need_space(global_rsv); + bytes_used += calc_global_rsv_need_space(global_rsv); /* * in limited mode, we want to have some free space up to @@ -4448,11 +4522,11 @@ static int should_alloc_chunk(struct btrfs_fs_info *fs_info, thresh = btrfs_super_total_bytes(fs_info->super_copy); thresh = max_t(u64, SZ_64M, div_factor_fine(thresh, 1)); - if (num_bytes - num_allocated < thresh) + if (sinfo->total_bytes - bytes_used < thresh) return 1; } - if (num_allocated + SZ_2M < div_factor(num_bytes, 8)) + if (bytes_used + SZ_2M < div_factor(sinfo->total_bytes, 8)) return 0; return 1; } @@ -4904,9 +4978,14 @@ struct reserve_ticket { wait_queue_head_t wait; }; -static int flush_space(struct btrfs_fs_info *fs_info, +/* + * Try to flush some data based on policy set by @state. This is only advisory + * and may fail for various reasons. The caller is supposed to examine the + * state of @space_info to detect the outcome. + */ +static void flush_space(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 num_bytes, - u64 orig_bytes, int state) + int state) { struct btrfs_root *root = fs_info->extent_root; struct btrfs_trans_handle *trans; @@ -4931,7 +5010,7 @@ static int flush_space(struct btrfs_fs_info *fs_info, break; case FLUSH_DELALLOC: case FLUSH_DELALLOC_WAIT: - shrink_delalloc(fs_info, num_bytes * 2, orig_bytes, + shrink_delalloc(fs_info, num_bytes * 2, num_bytes, state == FLUSH_DELALLOC_WAIT); break; case ALLOC_CHUNK: @@ -4949,16 +5028,16 @@ static int flush_space(struct btrfs_fs_info *fs_info, break; case COMMIT_TRANS: ret = may_commit_transaction(fs_info, space_info, - orig_bytes, 0); + num_bytes, 0); break; default: ret = -ENOSPC; break; } - trace_btrfs_flush_space(fs_info, space_info->flags, num_bytes, - orig_bytes, state, ret); - return ret; + trace_btrfs_flush_space(fs_info, space_info->flags, num_bytes, state, + ret); + return; } static inline u64 @@ -5060,11 +5139,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) flush_state = FLUSH_DELAYED_ITEMS_NR; do { - struct reserve_ticket *ticket; - int ret; - - ret = flush_space(fs_info, space_info, to_reclaim, to_reclaim, - flush_state); + flush_space(fs_info, space_info, to_reclaim, flush_state); spin_lock(&space_info->lock); if (list_empty(&space_info->tickets)) { space_info->flush = 0; @@ -5074,8 +5149,6 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info, false); - ticket = list_first_entry(&space_info->tickets, - struct reserve_ticket, list); if (last_tickets_id == space_info->tickets_id) { flush_state++; } else { @@ -5120,8 +5193,7 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info, spin_unlock(&space_info->lock); do { - flush_space(fs_info, space_info, to_reclaim, to_reclaim, - flush_state); + flush_space(fs_info, space_info, to_reclaim, flush_state); flush_state++; spin_lock(&space_info->lock); if (ticket->bytes == 0) { @@ -6664,19 +6736,20 @@ fetch_cluster_info(struct btrfs_fs_info *fs_info, struct btrfs_space_info *space_info, u64 *empty_cluster) { struct btrfs_free_cluster *ret = NULL; - bool ssd = btrfs_test_opt(fs_info, SSD); *empty_cluster = 0; if (btrfs_mixed_space_info(space_info)) return ret; - if (ssd) - *empty_cluster = SZ_2M; if (space_info->flags & BTRFS_BLOCK_GROUP_METADATA) { ret = &fs_info->meta_alloc_cluster; - if (!ssd) + if (btrfs_test_opt(fs_info, SSD)) + *empty_cluster = SZ_2M; + else *empty_cluster = SZ_64K; - } else if ((space_info->flags & BTRFS_BLOCK_GROUP_DATA) && ssd) { + } else if ((space_info->flags & BTRFS_BLOCK_GROUP_DATA) && + btrfs_test_opt(fs_info, SSD_SPREAD)) { + *empty_cluster = SZ_2M; ret = &fs_info->data_alloc_cluster; } @@ -6755,7 +6828,7 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info, if (!readonly && return_free_space && global_rsv->space_info == space_info) { u64 to_add = len; - WARN_ON(!return_free_space); + spin_lock(&global_rsv->lock); if (!global_rsv->full) { to_add = min(len, global_rsv->size - @@ -6841,7 +6914,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, if (ret) { const char *errstr = btrfs_decode_error(ret); btrfs_warn(fs_info, - "Discard failed while removing blockgroup: errno=%d %s\n", + "discard failed while removing blockgroup: errno=%d %s", ret, errstr); } } @@ -6969,7 +7042,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, "umm, got %d back from search, was looking for %llu", ret, bytenr); if (ret > 0) - btrfs_print_leaf(info, path->nodes[0]); + btrfs_print_leaf(path->nodes[0]); } if (ret < 0) { btrfs_abort_transaction(trans, ret); @@ -6978,7 +7051,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, extent_slot = path->slots[0]; } } else if (WARN_ON(ret == -ENOENT)) { - btrfs_print_leaf(info, path->nodes[0]); + btrfs_print_leaf(path->nodes[0]); btrfs_err(info, "unable to find ref byte nr %llu parent %llu root %llu owner %llu offset %llu", bytenr, parent, root_objectid, owner_objectid, @@ -7015,7 +7088,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, btrfs_err(info, "umm, got %d back from search, was looking for %llu", ret, bytenr); - btrfs_print_leaf(info, path->nodes[0]); + btrfs_print_leaf(path->nodes[0]); } if (ret < 0) { btrfs_abort_transaction(trans, ret); @@ -9193,7 +9266,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, if (err) goto out_end_trans; - ret = btrfs_del_root(trans, tree_root, &root->root_key); + ret = btrfs_del_root(trans, fs_info, &root->root_key); if (ret) { btrfs_abort_transaction(trans, ret); goto out_end_trans; @@ -9952,11 +10025,8 @@ btrfs_create_block_group_cache(struct btrfs_fs_info *fs_info, cache->key.offset = size; cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; - cache->sectorsize = fs_info->sectorsize; cache->fs_info = fs_info; - cache->full_stripe_len = btrfs_full_stripe_len(fs_info, - &fs_info->mapping_tree, - start); + cache->full_stripe_len = btrfs_full_stripe_len(fs_info, start); set_free_space_tree_thresholds(cache); atomic_set(&cache->count, 1); @@ -10192,8 +10262,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 bytes_used, - u64 type, u64 chunk_objectid, u64 chunk_offset, - u64 size) + u64 type, u64 chunk_offset, u64 size) { struct btrfs_block_group_cache *cache; int ret; @@ -10205,7 +10274,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, return -ENOMEM; btrfs_set_block_group_used(&cache->item, bytes_used); - btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid); + btrfs_set_block_group_chunk_objectid(&cache->item, + BTRFS_FIRST_CHUNK_TREE_OBJECTID); btrfs_set_block_group_flags(&cache->item, type); cache->flags = type; @@ -11001,14 +11071,14 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) } /* - * btrfs_{start,end}_write_no_snapshoting() are similar to + * btrfs_{start,end}_write_no_snapshotting() are similar to * mnt_{want,drop}_write(), they are used to prevent some tasks from writing * data into the page cache through nocow before the subvolume is snapshoted, * but flush the data into disk after the snapshot creation, or to prevent - * operations while snapshoting is ongoing and that cause the snapshot to be + * operations while snapshotting is ongoing and that cause the snapshot to be * inconsistent (writes followed by expanding truncates for example). */ -void btrfs_end_write_no_snapshoting(struct btrfs_root *root) +void btrfs_end_write_no_snapshotting(struct btrfs_root *root) { percpu_counter_dec(&root->subv_writers->counter); /* @@ -11019,9 +11089,9 @@ void btrfs_end_write_no_snapshoting(struct btrfs_root *root) wake_up(&root->subv_writers->wait); } -int btrfs_start_write_no_snapshoting(struct btrfs_root *root) +int btrfs_start_write_no_snapshotting(struct btrfs_root *root) { - if (atomic_read(&root->will_be_snapshoted)) + if (atomic_read(&root->will_be_snapshotted)) return 0; percpu_counter_inc(&root->subv_writers->counter); @@ -11029,14 +11099,14 @@ int btrfs_start_write_no_snapshoting(struct btrfs_root *root) * Make sure counter is updated before we check for snapshot creation. */ smp_mb(); - if (atomic_read(&root->will_be_snapshoted)) { - btrfs_end_write_no_snapshoting(root); + if (atomic_read(&root->will_be_snapshotted)) { + btrfs_end_write_no_snapshotting(root); return 0; } return 1; } -static int wait_snapshoting_atomic_t(atomic_t *a) +static int wait_snapshotting_atomic_t(atomic_t *a) { schedule(); return 0; @@ -11047,11 +11117,11 @@ void btrfs_wait_for_snapshot_creation(struct btrfs_root *root) while (true) { int ret; - ret = btrfs_start_write_no_snapshoting(root); + ret = btrfs_start_write_no_snapshotting(root); if (ret) break; - wait_on_atomic_t(&root->will_be_snapshoted, - wait_snapshoting_atomic_t, + wait_on_atomic_t(&root->will_be_snapshotted, + wait_snapshotting_atomic_t, TASK_UNINTERRUPTIBLE); } } diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 0aff9b278c1990f55feb2693a9fff65d5bf693ed..970190cd347edd5878479618222dc814b4736573 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -20,7 +20,6 @@ #include "locking.h" #include "rcu-string.h" #include "backref.h" -#include "transaction.h" static struct kmem_cache *extent_state_cache; static struct kmem_cache *extent_buffer_cache; @@ -1998,7 +1997,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start, * read repair operation. */ btrfs_bio_counter_inc_blocked(fs_info); - if (btrfs_is_parity_mirror(fs_info, logical, length, mirror_num)) { + if (btrfs_is_parity_mirror(fs_info, logical, length)) { /* * Note that we don't use BTRFS_MAP_WRITE because it's supposed * to update all raid stripes, but here we just want to correct @@ -2033,7 +2032,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start, bio_put(bio); return -EIO; } - bio->bi_bdev = dev->bdev; + bio_set_dev(bio, dev->bdev); bio->bi_opf = REQ_OP_WRITE | REQ_SYNC; bio_add_page(bio, page, length, pg_offset); @@ -2061,7 +2060,7 @@ int repair_eb_io_failure(struct btrfs_fs_info *fs_info, unsigned long i, num_pages = num_extent_pages(eb->start, eb->len); int ret = 0; - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) return -EROFS; for (i = 0; i < num_pages; i++) { @@ -2111,7 +2110,7 @@ int clean_io_failure(struct btrfs_fs_info *fs_info, failrec->start); goto out; } - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) goto out; spin_lock(&io_tree->lock); @@ -2335,7 +2334,7 @@ struct bio *btrfs_create_repair_bio(struct inode *inode, struct bio *failed_bio, bio = btrfs_io_bio_alloc(1); bio->bi_end_io = endio_func; bio->bi_iter.bi_sector = failrec->logical >> 9; - bio->bi_bdev = fs_info->fs_devices->latest_bdev; + bio_set_dev(bio, fs_info->fs_devices->latest_bdev); bio->bi_iter.bi_size = 0; bio->bi_private = data; @@ -2675,7 +2674,7 @@ struct bio *btrfs_bio_alloc(struct block_device *bdev, u64 first_byte) struct bio *bio; bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, btrfs_bioset); - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector = first_byte >> 9; btrfs_io_bio_init(btrfs_io_bio(bio)); return bio; @@ -2757,7 +2756,10 @@ static int merge_bio(struct extent_io_tree *tree, struct page *page, } -static int submit_extent_page(int op, int op_flags, struct extent_io_tree *tree, +/* + * @opf: bio REQ_OP_* and REQ_* flags as one value + */ +static int submit_extent_page(unsigned int opf, struct extent_io_tree *tree, struct writeback_control *wbc, struct page *page, sector_t sector, size_t size, unsigned long offset, @@ -2799,12 +2801,12 @@ static int submit_extent_page(int op, int op_flags, struct extent_io_tree *tree, } } - bio = btrfs_bio_alloc(bdev, sector << 9); + bio = btrfs_bio_alloc(bdev, (u64)sector << 9); bio_add_page(bio, page, page_size, offset); bio->bi_end_io = end_io_func; bio->bi_private = tree; bio->bi_write_hint = page->mapping->host->i_write_hint; - bio_set_op_attrs(bio, op, op_flags); + bio->bi_opf = opf; if (wbc) { wbc_init_bio(wbc, bio); wbc_account_io(wbc, page, page_size); @@ -2878,7 +2880,7 @@ static int __do_readpage(struct extent_io_tree *tree, get_extent_t *get_extent, struct extent_map **em_cached, struct bio **bio, int mirror_num, - unsigned long *bio_flags, int read_flags, + unsigned long *bio_flags, unsigned int read_flags, u64 *prev_em_start) { struct inode *inode = page->mapping->host; @@ -3059,7 +3061,7 @@ static int __do_readpage(struct extent_io_tree *tree, continue; } - ret = submit_extent_page(REQ_OP_READ, read_flags, tree, NULL, + ret = submit_extent_page(REQ_OP_READ | read_flags, tree, NULL, page, sector, disk_io_size, pg_offset, bdev, bio, end_bio_extent_readpage, mirror_num, @@ -3164,7 +3166,8 @@ static int __extent_read_full_page(struct extent_io_tree *tree, struct page *page, get_extent_t *get_extent, struct bio **bio, int mirror_num, - unsigned long *bio_flags, int read_flags) + unsigned long *bio_flags, + unsigned int read_flags) { struct inode *inode = page->mapping->host; struct btrfs_ordered_extent *ordered; @@ -3311,7 +3314,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, struct extent_page_data *epd, loff_t i_size, unsigned long nr_written, - int write_flags, int *nr_ret) + unsigned int write_flags, int *nr_ret) { struct extent_io_tree *tree = epd->tree; u64 start = page_offset(page); @@ -3427,7 +3430,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode, page->index, cur, end); } - ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc, + ret = submit_extent_page(REQ_OP_WRITE | write_flags, tree, wbc, page, sector, iosize, pg_offset, bdev, &epd->bio, end_bio_extent_writepage, @@ -3465,11 +3468,10 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, size_t pg_offset = 0; loff_t i_size = i_size_read(inode); unsigned long end_index = i_size >> PAGE_SHIFT; - int write_flags = 0; + unsigned int write_flags = 0; unsigned long nr_written = 0; - if (wbc->sync_mode == WB_SYNC_ALL) - write_flags = REQ_SYNC; + write_flags = wbc_to_write_flags(wbc); trace___extent_writepage(page, inode, wbc); @@ -3715,7 +3717,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, unsigned long i, num_pages; unsigned long bio_flags = 0; unsigned long start, end; - int write_flags = (epd->sync_io ? REQ_SYNC : 0) | REQ_META; + unsigned int write_flags = wbc_to_write_flags(wbc) | REQ_META; int ret = 0; clear_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags); @@ -3745,7 +3747,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, clear_page_dirty_for_io(p); set_page_writeback(p); - ret = submit_extent_page(REQ_OP_WRITE, write_flags, tree, wbc, + ret = submit_extent_page(REQ_OP_WRITE | write_flags, tree, wbc, p, offset >> 9, PAGE_SIZE, 0, bdev, &epd->bio, end_bio_extent_buffer_writepage, @@ -4060,9 +4062,6 @@ static void flush_epd_write_bio(struct extent_page_data *epd) if (epd->bio) { int ret; - bio_set_op_attrs(epd->bio, REQ_OP_WRITE, - epd->sync_io ? REQ_SYNC : 0); - ret = submit_one_bio(epd->bio, 0, epd->bio_flags); BUG_ON(ret < 0); /* -ENOMEM */ epd->bio = NULL; @@ -4606,24 +4605,11 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, flags |= (FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN); } else if (fieinfo->fi_extents_max) { - struct btrfs_trans_handle *trans; - u64 bytenr = em->block_start - (em->start - em->orig_start); disko = em->block_start + offset_in_extent; - /* - * We need a trans handle to get delayed refs - */ - trans = btrfs_join_transaction(root); - /* - * It's OK if we can't start a trans we can still check - * from commit_root - */ - if (IS_ERR(trans)) - trans = NULL; - /* * As btrfs supports shared space, this information * can be exported to userspace tools via @@ -4631,11 +4617,9 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, * then we're just getting a count and we can skip the * lookup stuff. */ - ret = btrfs_check_shared(trans, root->fs_info, - root->objectid, - btrfs_ino(BTRFS_I(inode)), bytenr); - if (trans) - btrfs_end_transaction(trans); + ret = btrfs_check_shared(root, + btrfs_ino(BTRFS_I(inode)), + bytenr); if (ret < 0) goto out_free; if (ret) @@ -5405,9 +5389,8 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, return ret; } -void read_extent_buffer(struct extent_buffer *eb, void *dstv, - unsigned long start, - unsigned long len) +void read_extent_buffer(const struct extent_buffer *eb, void *dstv, + unsigned long start, unsigned long len) { size_t cur; size_t offset; @@ -5417,8 +5400,12 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, size_t start_offset = eb->start & ((u64)PAGE_SIZE - 1); unsigned long i = (start_offset + start) >> PAGE_SHIFT; - WARN_ON(start > eb->len); - WARN_ON(start + len > eb->start + eb->len); + if (start + len > eb->len) { + WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, wanted %lu %lu\n", + eb->start, eb->len, start, len); + memset(dst, 0, len); + return; + } offset = (start_offset + start) & (PAGE_SIZE - 1); @@ -5436,9 +5423,9 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, } } -int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, - unsigned long start, - unsigned long len) +int read_extent_buffer_to_user(const struct extent_buffer *eb, + void __user *dstv, + unsigned long start, unsigned long len) { size_t cur; size_t offset; @@ -5478,10 +5465,10 @@ int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, * return 1 if the item spans two pages. * return -EINVAL otherwise. */ -int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, - unsigned long min_len, char **map, - unsigned long *map_start, - unsigned long *map_len) +int map_private_extent_buffer(const struct extent_buffer *eb, + unsigned long start, unsigned long min_len, + char **map, unsigned long *map_start, + unsigned long *map_len) { size_t offset = start & (PAGE_SIZE - 1); char *kaddr; @@ -5491,6 +5478,12 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, unsigned long end_i = (start_offset + start + min_len - 1) >> PAGE_SHIFT; + if (start + min_len > eb->len) { + WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, wanted %lu %lu\n", + eb->start, eb->len, start, min_len); + return -EINVAL; + } + if (i != end_i) return 1; @@ -5502,12 +5495,6 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, *map_start = ((u64)i << PAGE_SHIFT) - start_offset; } - if (start + min_len > eb->len) { - WARN(1, KERN_ERR "btrfs bad mapping eb start %llu len %lu, wanted %lu %lu\n", - eb->start, eb->len, start, min_len); - return -EINVAL; - } - p = eb->pages[i]; kaddr = page_address(p); *map = kaddr + offset; @@ -5515,9 +5502,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, return 0; } -int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, - unsigned long start, - unsigned long len) +int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, + unsigned long start, unsigned long len) { size_t cur; size_t offset; diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4f030912f3efe784cfec3117a4459c07d77518c8..faffa28ba707f3733e841aff16b02da259730249 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -449,14 +449,13 @@ static inline void extent_buffer_get(struct extent_buffer *eb) atomic_inc(&eb->refs); } -int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, - unsigned long start, - unsigned long len); -void read_extent_buffer(struct extent_buffer *eb, void *dst, +int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, + unsigned long start, unsigned long len); +void read_extent_buffer(const struct extent_buffer *eb, void *dst, unsigned long start, unsigned long len); -int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dst, - unsigned long start, +int read_extent_buffer_to_user(const struct extent_buffer *eb, + void __user *dst, unsigned long start, unsigned long len); void write_extent_buffer_fsid(struct extent_buffer *eb, const void *src); void write_extent_buffer_chunk_tree_uuid(struct extent_buffer *eb, @@ -486,10 +485,10 @@ void set_extent_buffer_uptodate(struct extent_buffer *eb); void clear_extent_buffer_uptodate(struct extent_buffer *eb); int extent_buffer_uptodate(struct extent_buffer *eb); int extent_buffer_under_io(struct extent_buffer *eb); -int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset, - unsigned long min_len, char **map, - unsigned long *map_start, - unsigned long *map_len); +int map_private_extent_buffer(const struct extent_buffer *eb, + unsigned long offset, unsigned long min_len, + char **map, unsigned long *map_start, + unsigned long *map_len); void extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end); void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end); void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 9e75d8a39aacf7dbcfdd961dd41ddd71e924a3a3..aafcc785f8408c1714e159ed68e3f0f57847ae2e 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1536,7 +1536,7 @@ static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, u64 num_bytes; int ret; - ret = btrfs_start_write_no_snapshoting(root); + ret = btrfs_start_write_no_snapshotting(root); if (!ret) return -ENOSPC; @@ -1561,7 +1561,7 @@ static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, NULL, NULL, NULL); if (ret <= 0) { ret = 0; - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); } else { *write_bytes = min_t(size_t, *write_bytes , num_bytes - pos + lockstart); @@ -1664,7 +1664,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, data_reserved, pos, write_bytes); else - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); break; } @@ -1767,7 +1767,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, release_bytes = 0; if (only_release_metadata) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); if (only_release_metadata && copied > 0) { lockstart = round_down(pos, @@ -1797,7 +1797,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (release_bytes) { if (only_release_metadata) { - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); btrfs_delalloc_release_metadata(BTRFS_I(inode), release_bytes); } else { @@ -1886,6 +1886,10 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, loff_t oldsize; int clean_page = 0; + if (!(iocb->ki_flags & IOCB_DIRECT) && + (iocb->ki_flags & IOCB_NOWAIT)) + return -EOPNOTSUPP; + if (!inode_trylock(inode)) { if (iocb->ki_flags & IOCB_NOWAIT) return -EAGAIN; @@ -1990,8 +1994,15 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, int btrfs_release_file(struct inode *inode, struct file *filp) { - if (filp->private_data) + struct btrfs_file_private *private = filp->private_data; + + if (private && private->trans) btrfs_ioctl_trans_end(filp); + if (private && private->filldir_buf) + kfree(private->filldir_buf); + kfree(private); + filp->private_data = NULL; + /* * ordered_data_close is set by settattr when we are about to truncate * a file from a non-zero size to a zero size. This tries to @@ -3105,7 +3116,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence) static int btrfs_file_open(struct inode *inode, struct file *filp) { - filp->f_mode |= FMODE_AIO_NOWAIT; + filp->f_mode |= FMODE_NOWAIT; return generic_file_open(inode, filp); } diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index c5e6180cdb8c9250e3a525e311a42795c4831c32..cdc9f4015ec36c08688a81bb1ba2bf657a9845ef 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -709,7 +709,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, if (!BTRFS_I(inode)->generation) { btrfs_info(fs_info, - "The free space cache file (%llu) is invalid. skip it\n", + "the free space cache file (%llu) is invalid, skip it", offset); return 0; } diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c index a5e34de06c2fe593e7578d59a27614f73a57ea1a..684f12247db7e376350789b6161190c6412431b7 100644 --- a/fs/btrfs/free-space-tree.c +++ b/fs/btrfs/free-space-tree.c @@ -1257,7 +1257,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) if (ret) goto abort; - ret = btrfs_del_root(trans, tree_root, &free_space_root->root_key); + ret = btrfs_del_root(trans, fs_info, &free_space_root->root_key); if (ret) goto abort; diff --git a/fs/btrfs/free-space-tree.h b/fs/btrfs/free-space-tree.h index 54ffced3bce8c037f045441155e86f03842e5da7..ba3787df43c3076520aff16bce5929a0293ac964 100644 --- a/fs/btrfs/free-space-tree.h +++ b/fs/btrfs/free-space-tree.h @@ -44,7 +44,7 @@ int remove_from_free_space_tree(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 start, u64 size); -/* Exposed for testing. */ +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS struct btrfs_free_space_info * search_free_space_info(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, @@ -68,5 +68,6 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, struct btrfs_path *path); int free_space_test_bit(struct btrfs_block_group_cache *block_group, struct btrfs_path *path, u64 offset); +#endif #endif diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 95c212037095fea727f4a35ea19d9d7e54ad8cfe..d94e3f68b9b134f8e3027dec70f1952c42e8ce52 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -135,6 +135,18 @@ static inline void btrfs_cleanup_ordered_extents(struct inode *inode, const u64 offset, const u64 bytes) { + unsigned long index = offset >> PAGE_SHIFT; + unsigned long end_index = (offset + bytes - 1) >> PAGE_SHIFT; + struct page *page; + + while (index <= end_index) { + page = find_get_page(inode->i_mapping, index); + index++; + if (!page) + continue; + ClearPagePrivate2(page); + put_page(page); + } return __endio_write_update_ordered(inode, offset + PAGE_SIZE, bytes - PAGE_SIZE, false); } @@ -392,20 +404,23 @@ static noinline int add_async_extent(struct async_cow *cow, return 0; } -static inline int inode_need_compress(struct inode *inode) +static inline int inode_need_compress(struct inode *inode, u64 start, u64 end) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); /* force compress */ if (btrfs_test_opt(fs_info, FORCE_COMPRESS)) return 1; + /* defrag ioctl */ + if (BTRFS_I(inode)->defrag_compress) + return 1; /* bad compression ratios */ if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) return 0; if (btrfs_test_opt(fs_info, COMPRESS) || BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS || - BTRFS_I(inode)->force_compress) - return 1; + BTRFS_I(inode)->prop_compress) + return btrfs_compress_heuristic(inode, start, end); return 0; } @@ -503,7 +518,7 @@ static noinline void compress_file_range(struct inode *inode, * inode has not been flagged as nocompress. This flag can * change at any time if we discover bad compression ratios. */ - if (inode_need_compress(inode)) { + if (inode_need_compress(inode, start, end)) { WARN_ON(pages); pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); if (!pages) { @@ -511,8 +526,10 @@ static noinline void compress_file_range(struct inode *inode, goto cont; } - if (BTRFS_I(inode)->force_compress) - compress_type = BTRFS_I(inode)->force_compress; + if (BTRFS_I(inode)->defrag_compress) + compress_type = BTRFS_I(inode)->defrag_compress; + else if (BTRFS_I(inode)->prop_compress) + compress_type = BTRFS_I(inode)->prop_compress; /* * we need to call clear_page_dirty_for_io on each @@ -645,7 +662,7 @@ static noinline void compress_file_range(struct inode *inode, /* flag the file so we don't compress in the future */ if (!btrfs_test_opt(fs_info, FORCE_COMPRESS) && - !(BTRFS_I(inode)->force_compress)) { + !(BTRFS_I(inode)->prop_compress)) { BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; } } @@ -1381,7 +1398,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, * we fall into common COW way. */ if (!nolock) { - err = btrfs_start_write_no_snapshoting(root); + err = btrfs_start_write_no_snapshotting(root); if (!err) goto out_check; } @@ -1393,12 +1410,12 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (csum_exist_in_range(fs_info, disk_bytenr, num_bytes)) { if (!nolock) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); goto out_check; } if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) { if (!nolock) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); goto out_check; } nocow = 1; @@ -1415,7 +1432,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (extent_end <= start) { path->slots[0]++; if (!nolock && nocow) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); goto next_slot; @@ -1438,7 +1455,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, NULL); if (ret) { if (!nolock && nocow) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); @@ -1459,7 +1476,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, BTRFS_ORDERED_PREALLOC); if (IS_ERR(em)) { if (!nolock && nocow) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); @@ -1499,7 +1516,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, PAGE_UNLOCK | PAGE_SET_PRIVATE2); if (!nolock && nocow) - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); cur_offset = extent_end; /* @@ -1576,7 +1593,7 @@ static int run_delalloc_range(void *private_data, struct page *locked_page, } else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC && !force_cow) { ret = run_delalloc_nocow(inode, locked_page, start, end, page_started, 0, nr_written); - } else if (!inode_need_compress(inode)) { + } else if (!inode_need_compress(inode, start, end)) { ret = cow_file_range(inode, locked_page, start, end, end, page_started, nr_written, 1, NULL); } else { @@ -1796,10 +1813,11 @@ static void btrfs_clear_bit_hook(void *private_data, u64 len = state->end + 1 - state->start; u32 num_extents = count_max_extents(len); - spin_lock(&inode->lock); - if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG)) + if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG)) { + spin_lock(&inode->lock); inode->defrag_bytes -= len; - spin_unlock(&inode->lock); + spin_unlock(&inode->lock); + } /* * set_bit and clear bit hooks normally require _irqsave/restore @@ -3159,8 +3177,6 @@ static int __readpage_endio_check(struct inode *inode, memset(kaddr + pgoff, 1, len); flush_dcache_page(page); kunmap_atomic(kaddr); - if (csum_expected == 0) - return 0; return -EIO; } @@ -5055,7 +5071,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) if (newsize > oldsize) { /* - * Don't do an expanding truncate while snapshoting is ongoing. + * Don't do an expanding truncate while snapshotting is ongoing. * This is to ensure the snapshot captures a fully consistent * state of this file - if the snapshot captures this expanding * truncation, it must capture all writes that happened before @@ -5064,13 +5080,13 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_wait_for_snapshot_creation(root); ret = btrfs_cont_expand(inode, oldsize, newsize); if (ret) { - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); return ret; } trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); return PTR_ERR(trans); } @@ -5078,7 +5094,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); pagecache_isize_extended(inode, oldsize, newsize); ret = btrfs_update_inode(trans, root, inode); - btrfs_end_write_no_snapshoting(root); + btrfs_end_write_no_snapshotting(root); btrfs_end_transaction(trans); } else { @@ -5817,7 +5833,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) if (!IS_ERR(inode) && root != sub_root) { down_read(&fs_info->cleanup_work_sem); - if (!(inode->i_sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(inode->i_sb)) ret = btrfs_orphan_cleanup(sub_root); up_read(&fs_info->cleanup_work_sem); if (ret) { @@ -5873,25 +5889,74 @@ unsigned char btrfs_filetype_table[] = { DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK }; +/* + * All this infrastructure exists because dir_emit can fault, and we are holding + * the tree lock when doing readdir. For now just allocate a buffer and copy + * our information into that, and then dir_emit from the buffer. This is + * similar to what NFS does, only we don't keep the buffer around in pagecache + * because I'm afraid I'll mess that up. Long term we need to make filldir do + * copy_to_user_inatomic so we don't have to worry about page faulting under the + * tree lock. + */ +static int btrfs_opendir(struct inode *inode, struct file *file) +{ + struct btrfs_file_private *private; + + private = kzalloc(sizeof(struct btrfs_file_private), GFP_KERNEL); + if (!private) + return -ENOMEM; + private->filldir_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!private->filldir_buf) { + kfree(private); + return -ENOMEM; + } + file->private_data = private; + return 0; +} + +struct dir_entry { + u64 ino; + u64 offset; + unsigned type; + int name_len; +}; + +static int btrfs_filldir(void *addr, int entries, struct dir_context *ctx) +{ + while (entries--) { + struct dir_entry *entry = addr; + char *name = (char *)(entry + 1); + + ctx->pos = entry->offset; + if (!dir_emit(ctx, name, entry->name_len, entry->ino, + entry->type)) + return 1; + addr += sizeof(struct dir_entry) + entry->name_len; + ctx->pos++; + } + return 0; +} + static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) { struct inode *inode = file_inode(file); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_file_private *private = file->private_data; struct btrfs_dir_item *di; struct btrfs_key key; struct btrfs_key found_key; struct btrfs_path *path; + void *addr; struct list_head ins_list; struct list_head del_list; int ret; struct extent_buffer *leaf; int slot; - unsigned char d_type; - int over = 0; - char tmp_name[32]; char *name_ptr; int name_len; + int entries = 0; + int total_len = 0; bool put = false; struct btrfs_key location; @@ -5902,12 +5967,14 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) if (!path) return -ENOMEM; + addr = private->filldir_buf; path->reada = READA_FORWARD; INIT_LIST_HEAD(&ins_list); INIT_LIST_HEAD(&del_list); put = btrfs_readdir_get_delayed_items(inode, &ins_list, &del_list); +again: key.type = BTRFS_DIR_INDEX_KEY; key.offset = ctx->pos; key.objectid = btrfs_ino(BTRFS_I(inode)); @@ -5917,6 +5984,8 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) goto err; while (1) { + struct dir_entry *entry; + leaf = path->nodes[0]; slot = path->slots[0]; if (slot >= btrfs_header_nritems(leaf)) { @@ -5938,41 +6007,43 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) goto next; if (btrfs_should_delete_dir_index(&del_list, found_key.offset)) goto next; - - ctx->pos = found_key.offset; - di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); if (verify_dir_item(fs_info, leaf, slot, di)) goto next; name_len = btrfs_dir_name_len(leaf, di); - if (name_len <= sizeof(tmp_name)) { - name_ptr = tmp_name; - } else { - name_ptr = kmalloc(name_len, GFP_KERNEL); - if (!name_ptr) { - ret = -ENOMEM; - goto err; - } + if ((total_len + sizeof(struct dir_entry) + name_len) >= + PAGE_SIZE) { + btrfs_release_path(path); + ret = btrfs_filldir(private->filldir_buf, entries, ctx); + if (ret) + goto nopos; + addr = private->filldir_buf; + entries = 0; + total_len = 0; + goto again; } + + entry = addr; + entry->name_len = name_len; + name_ptr = (char *)(entry + 1); read_extent_buffer(leaf, name_ptr, (unsigned long)(di + 1), name_len); - - d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; + entry->type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; btrfs_dir_item_key_to_cpu(leaf, di, &location); - - over = !dir_emit(ctx, name_ptr, name_len, location.objectid, - d_type); - - if (name_ptr != tmp_name) - kfree(name_ptr); - - if (over) - goto nopos; - ctx->pos++; + entry->ino = location.objectid; + entry->offset = found_key.offset; + entries++; + addr += sizeof(struct dir_entry) + name_len; + total_len += sizeof(struct dir_entry) + name_len; next: path->slots[0]++; } + btrfs_release_path(path); + + ret = btrfs_filldir(private->filldir_buf, entries, ctx); + if (ret) + goto nopos; ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list); if (ret) @@ -6185,6 +6256,37 @@ static int btrfs_insert_inode_locked(struct inode *inode) btrfs_find_actor, &args); } +/* + * Inherit flags from the parent inode. + * + * Currently only the compression flags and the cow flags are inherited. + */ +static void btrfs_inherit_iflags(struct inode *inode, struct inode *dir) +{ + unsigned int flags; + + if (!dir) + return; + + flags = BTRFS_I(dir)->flags; + + if (flags & BTRFS_INODE_NOCOMPRESS) { + BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS; + BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; + } else if (flags & BTRFS_INODE_COMPRESS) { + BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; + BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; + } + + if (flags & BTRFS_INODE_NODATACOW) { + BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW; + if (S_ISREG(inode->i_mode)) + BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; + } + + btrfs_update_iflags(inode); +} + static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *dir, @@ -7924,11 +8026,12 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, return ret; } -static inline int submit_dio_repair_bio(struct inode *inode, struct bio *bio, - int mirror_num) +static inline blk_status_t submit_dio_repair_bio(struct inode *inode, + struct bio *bio, + int mirror_num) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - int ret; + blk_status_t ret; BUG_ON(bio_op(bio) == REQ_OP_WRITE); @@ -7980,31 +8083,32 @@ static int btrfs_check_dio_repairable(struct inode *inode, return 1; } -static int dio_read_error(struct inode *inode, struct bio *failed_bio, - struct page *page, unsigned int pgoff, - u64 start, u64 end, int failed_mirror, - bio_end_io_t *repair_endio, void *repair_arg) +static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio, + struct page *page, unsigned int pgoff, + u64 start, u64 end, int failed_mirror, + bio_end_io_t *repair_endio, void *repair_arg) { struct io_failure_record *failrec; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree; struct bio *bio; int isector; - int read_mode = 0; + unsigned int read_mode = 0; int segs; int ret; + blk_status_t status; BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE); ret = btrfs_get_io_failure_record(inode, start, end, &failrec); if (ret) - return ret; + return errno_to_blk_status(ret); ret = btrfs_check_dio_repairable(inode, failed_bio, failrec, failed_mirror); if (!ret) { free_io_failure(failure_tree, io_tree, failrec); - return -EIO; + return BLK_STS_IOERR; } segs = bio_segments(failed_bio); @@ -8019,16 +8123,16 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, bio_set_op_attrs(bio, REQ_OP_READ, read_mode); btrfs_debug(BTRFS_I(inode)->root->fs_info, - "Repair DIO Read Error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d\n", + "repair DIO read error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d", read_mode, failrec->this_mirror, failrec->in_validation); - ret = submit_dio_repair_bio(inode, bio, failrec->this_mirror); - if (ret) { + status = submit_dio_repair_bio(inode, bio, failrec->this_mirror); + if (status) { free_io_failure(failure_tree, io_tree, failrec); bio_put(bio); } - return ret; + return status; } struct btrfs_retry_complete { @@ -8065,8 +8169,8 @@ static void btrfs_retry_endio_nocsum(struct bio *bio) bio_put(bio); } -static int __btrfs_correct_data_nocsum(struct inode *inode, - struct btrfs_io_bio *io_bio) +static blk_status_t __btrfs_correct_data_nocsum(struct inode *inode, + struct btrfs_io_bio *io_bio) { struct btrfs_fs_info *fs_info; struct bio_vec bvec; @@ -8076,8 +8180,8 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, unsigned int pgoff; u32 sectorsize; int nr_sectors; - int ret; - int err = 0; + blk_status_t ret; + blk_status_t err = BLK_STS_OK; fs_info = BTRFS_I(inode)->root->fs_info; sectorsize = fs_info->sectorsize; @@ -8104,7 +8208,7 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, goto next; } - wait_for_completion(&done.done); + wait_for_completion_io(&done.done); if (!done.uptodate) { /* We might have another mirror, so try again */ @@ -8183,11 +8287,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode, int csum_pos; bool uptodate = (err == 0); int ret; + blk_status_t status; fs_info = BTRFS_I(inode)->root->fs_info; sectorsize = fs_info->sectorsize; - err = 0; + err = BLK_STS_OK; start = io_bio->logical; done.inode = inode; io_bio->bio.bi_iter = io_bio->iter; @@ -8209,16 +8314,16 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode, done.start = start; init_completion(&done.done); - ret = dio_read_error(inode, &io_bio->bio, bvec.bv_page, - pgoff, start, start + sectorsize - 1, - io_bio->mirror_num, - btrfs_retry_endio, &done); - if (ret) { - err = errno_to_blk_status(ret); + status = dio_read_error(inode, &io_bio->bio, bvec.bv_page, + pgoff, start, start + sectorsize - 1, + io_bio->mirror_num, btrfs_retry_endio, + &done); + if (status) { + err = status; goto next; } - wait_for_completion(&done.done); + wait_for_completion_io(&done.done); if (!done.uptodate) { /* We might have another mirror, so try again */ @@ -8250,7 +8355,7 @@ static blk_status_t btrfs_subio_endio_read(struct inode *inode, if (unlikely(err)) return __btrfs_correct_data_nocsum(inode, io_bio); else - return 0; + return BLK_STS_OK; } else { return __btrfs_subio_endio_read(inode, io_bio, err); } @@ -8264,11 +8369,8 @@ static void btrfs_endio_direct_read(struct bio *bio) struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); blk_status_t err = bio->bi_status; - if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) { + if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED) err = btrfs_subio_endio_read(inode, io_bio, err); - if (!err) - bio->bi_status = 0; - } unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, dip->logical_offset + dip->bytes - 1); @@ -8276,7 +8378,7 @@ static void btrfs_endio_direct_read(struct bio *bio) kfree(dip); - dio_bio->bi_status = bio->bi_status; + dio_bio->bi_status = err; dio_end_io(dio_bio); if (io_bio->end_io) @@ -8294,6 +8396,7 @@ static void __endio_write_update_ordered(struct inode *inode, btrfs_work_func_t func; u64 ordered_offset = offset; u64 ordered_bytes = bytes; + u64 last_offset; int ret; if (btrfs_is_free_space_inode(BTRFS_I(inode))) { @@ -8305,6 +8408,7 @@ static void __endio_write_update_ordered(struct inode *inode, } again: + last_offset = ordered_offset; ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, &ordered_offset, ordered_bytes, @@ -8315,6 +8419,12 @@ static void __endio_write_update_ordered(struct inode *inode, btrfs_init_work(&ordered->work, func, finish_ordered_fn, NULL, NULL); btrfs_queue_work(wq, &ordered->work); out_test: + /* + * If btrfs_dec_test_ordered_pending does not find any ordered extent + * in the range, we can exit. + */ + if (ordered_offset == last_offset) + return; /* * our bio might span multiple ordered extents. If we haven't * completed the accounting for the whole dio, go back and try again @@ -8423,9 +8533,9 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode, return 0; } -static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, - u64 file_offset, int skip_sum, - int async_submit) +static inline blk_status_t +__btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, u64 file_offset, + int async_submit) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_dio_private *dip = bio->bi_private; @@ -8443,7 +8553,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, goto err; } - if (skip_sum) + if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM) goto map; if (write && async_submit) { @@ -8473,8 +8583,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, return ret; } -static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, - int skip_sum) +static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip) { struct inode *inode = dip->inode; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); @@ -8488,6 +8597,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, int clone_offset = 0; int clone_len; int ret; + blk_status_t status; map_length = orig_bio->bi_iter.bi_size; submit_len = map_length; @@ -8537,9 +8647,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, */ atomic_inc(&dip->pending_bios); - ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, - async_submit); - if (ret) { + status = __btrfs_submit_dio_bio(bio, inode, file_offset, + async_submit); + if (status) { bio_put(bio); atomic_dec(&dip->pending_bios); goto out_err; @@ -8557,9 +8667,8 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, } while (submit_len > 0); submit: - ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum, - async_submit); - if (!ret) + status = __btrfs_submit_dio_bio(bio, inode, file_offset, async_submit); + if (!status) return 0; bio_put(bio); @@ -8583,12 +8692,9 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, struct btrfs_dio_private *dip = NULL; struct bio *bio = NULL; struct btrfs_io_bio *io_bio; - int skip_sum; bool write = (bio_op(dio_bio) == REQ_OP_WRITE); int ret = 0; - skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; - bio = btrfs_bio_clone(dio_bio); dip = kzalloc(sizeof(*dip), GFP_NOFS); @@ -8631,7 +8737,7 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, dio_data->unsubmitted_oe_range_end; } - ret = btrfs_submit_direct_hook(dip, skip_sum); + ret = btrfs_submit_direct_hook(dip); if (!ret) return; @@ -8731,7 +8837,6 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) return 0; inode_dio_begin(inode); - smp_mb__after_atomic(); /* * The generic stuff only does filemap_write_and_wait_range, which @@ -9404,7 +9509,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) ei->reserved_extents = 0; ei->runtime_flags = 0; - ei->force_compress = BTRFS_COMPRESS_NONE; + ei->prop_compress = BTRFS_COMPRESS_NONE; + ei->defrag_compress = BTRFS_COMPRESS_NONE; ei->delayed_node = NULL; @@ -10744,6 +10850,7 @@ static const struct file_operations btrfs_dir_file_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, .iterate_shared = btrfs_real_readdir, + .open = btrfs_opendir, .unlocked_ioctl = btrfs_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = btrfs_compat_ioctl, diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index fa1b78cf25f68083de3db86ead690a41563316ce..6c7a49faf4e0636e67c9f818893975dc48d7436a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -156,37 +156,6 @@ void btrfs_update_iflags(struct inode *inode) new_fl); } -/* - * Inherit flags from the parent inode. - * - * Currently only the compression flags and the cow flags are inherited. - */ -void btrfs_inherit_iflags(struct inode *inode, struct inode *dir) -{ - unsigned int flags; - - if (!dir) - return; - - flags = BTRFS_I(dir)->flags; - - if (flags & BTRFS_INODE_NOCOMPRESS) { - BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS; - BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; - } else if (flags & BTRFS_INODE_COMPRESS) { - BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; - BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; - } - - if (flags & BTRFS_INODE_NODATACOW) { - BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW; - if (S_ISREG(inode->i_mode)) - BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; - } - - btrfs_update_iflags(inode); -} - static int btrfs_ioctl_getflags(struct file *file, void __user *arg) { struct btrfs_inode *ip = BTRFS_I(file_inode(file)); @@ -327,8 +296,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) if (fs_info->compress_type == BTRFS_COMPRESS_LZO) comp = "lzo"; - else + else if (fs_info->compress_type == BTRFS_COMPRESS_ZLIB) comp = "zlib"; + else + comp = "zstd"; ret = btrfs_set_prop(inode, "btrfs.compression", comp, strlen(comp), 0); if (ret) @@ -638,7 +609,7 @@ static noinline int create_subvol(struct inode *dir, return ret; } -static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root) +static void btrfs_wait_for_no_snapshotting_writes(struct btrfs_root *root) { s64 writers; DEFINE_WAIT(wait); @@ -681,9 +652,9 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, goto free_pending; } - atomic_inc(&root->will_be_snapshoted); + atomic_inc(&root->will_be_snapshotted); smp_mb__after_atomic(); - btrfs_wait_for_no_snapshoting_writes(root); + btrfs_wait_for_no_snapshotting_writes(root); ret = btrfs_start_delalloc_inodes(root, 0); if (ret) @@ -754,8 +725,8 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, fail: btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv); dec_and_free: - if (atomic_dec_and_test(&root->will_be_snapshoted)) - wake_up_atomic_t(&root->will_be_snapshoted); + if (atomic_dec_and_test(&root->will_be_snapshotted)) + wake_up_atomic_t(&root->will_be_snapshotted); free_pending: kfree(pending_snapshot->root_item); btrfs_free_path(pending_snapshot->path); @@ -1286,6 +1257,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, unsigned long cluster = max_cluster; u64 new_align = ~((u64)SZ_128K - 1); struct page **pages = NULL; + bool do_compress = range->flags & BTRFS_DEFRAG_RANGE_COMPRESS; if (isize == 0) return 0; @@ -1293,7 +1265,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (range->start >= isize) return -EINVAL; - if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) { + if (do_compress) { if (range->compress_type > BTRFS_COMPRESS_TYPES) return -EINVAL; if (range->compress_type) @@ -1304,20 +1276,19 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, extent_thresh = SZ_256K; /* - * if we were not given a file, allocate a readahead - * context + * If we were not given a file, allocate a readahead context. As + * readahead is just an optimization, defrag will work without it so + * we don't error out. */ if (!file) { - ra = kzalloc(sizeof(*ra), GFP_NOFS); - if (!ra) - return -ENOMEM; - file_ra_state_init(ra, inode->i_mapping); + ra = kzalloc(sizeof(*ra), GFP_KERNEL); + if (ra) + file_ra_state_init(ra, inode->i_mapping); } else { ra = &file->f_ra; } - pages = kmalloc_array(max_cluster, sizeof(struct page *), - GFP_NOFS); + pages = kmalloc_array(max_cluster, sizeof(struct page *), GFP_KERNEL); if (!pages) { ret = -ENOMEM; goto out_ra; @@ -1373,8 +1344,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (!should_defrag_range(inode, (u64)i << PAGE_SHIFT, extent_thresh, &last_len, &skip, - &defrag_end, range->flags & - BTRFS_DEFRAG_RANGE_COMPRESS)) { + &defrag_end, do_compress)){ unsigned long next; /* * the should_defrag function tells us how much to skip @@ -1395,14 +1365,15 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (i + cluster > ra_index) { ra_index = max(i, ra_index); - btrfs_force_ra(inode->i_mapping, ra, file, ra_index, - cluster); + if (ra) + page_cache_sync_readahead(inode->i_mapping, ra, + file, ra_index, cluster); ra_index += cluster; } inode_lock(inode); - if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) - BTRFS_I(inode)->force_compress = compress_type; + if (do_compress) + BTRFS_I(inode)->defrag_compress = compress_type; ret = cluster_pages_for_defrag(inode, pages, i, cluster); if (ret < 0) { inode_unlock(inode); @@ -1449,7 +1420,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, filemap_flush(inode->i_mapping); } - if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { + if (do_compress) { /* the filemap_flush will queue IO into the worker threads, but * we have to make sure the IO is actually started and that * ordered extents get created before we return @@ -1466,14 +1437,16 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (range->compress_type == BTRFS_COMPRESS_LZO) { btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); + } else if (range->compress_type == BTRFS_COMPRESS_ZSTD) { + btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD); } ret = defrag_count; out_ra: - if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) { + if (do_compress) { inode_lock(inode); - BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE; + BTRFS_I(inode)->defrag_compress = BTRFS_COMPRESS_NONE; inode_unlock(inode); } if (!file) @@ -1600,8 +1573,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, goto out_free; } - new_size = div_u64(new_size, fs_info->sectorsize); - new_size *= fs_info->sectorsize; + new_size = round_down(new_size, fs_info->sectorsize); btrfs_info_in_rcu(fs_info, "new size for %s is %llu", rcu_str_deref(device->name), new_size); @@ -2201,9 +2173,6 @@ static noinline int btrfs_ioctl_tree_search_v2(struct file *file, buf_size = args.buf_size; - if (buf_size < sizeof(struct btrfs_ioctl_search_header)) - return -EOVERFLOW; - /* limit result size to 16MB */ if (buf_size > buf_limit) buf_size = buf_limit; @@ -2804,9 +2773,9 @@ static long btrfs_ioctl_fs_info(struct btrfs_fs_info *fs_info, } mutex_unlock(&fs_devices->device_list_mutex); - fi_args->nodesize = fs_info->super_copy->nodesize; - fi_args->sectorsize = fs_info->super_copy->sectorsize; - fi_args->clone_alignment = fs_info->super_copy->sectorsize; + fi_args->nodesize = fs_info->nodesize; + fi_args->sectorsize = fs_info->sectorsize; + fi_args->clone_alignment = fs_info->sectorsize; if (copy_to_user(arg, fi_args, sizeof(*fi_args))) ret = -EFAULT; @@ -3063,7 +3032,7 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff, out: if (ret) btrfs_cmp_data_free(cmp); - return 0; + return ret; } static int btrfs_cmp_data(u64 len, struct cmp_pages *cmp) @@ -3998,15 +3967,35 @@ static long btrfs_ioctl_trans_start(struct file *file) struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; + struct btrfs_file_private *private; int ret; + static bool warned = false; ret = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto out; + if (!warned) { + btrfs_warn(fs_info, + "Userspace transaction mechanism is considered " + "deprecated and slated to be removed in 4.17. " + "If you have a valid use case please " + "speak up on the mailing list"); + WARN_ON(1); + warned = true; + } + ret = -EINPROGRESS; - if (file->private_data) + private = file->private_data; + if (private && private->trans) goto out; + if (!private) { + private = kzalloc(sizeof(struct btrfs_file_private), + GFP_KERNEL); + if (!private) + return -ENOMEM; + file->private_data = private; + } ret = -EROFS; if (btrfs_root_readonly(root)) @@ -4023,7 +4012,7 @@ static long btrfs_ioctl_trans_start(struct file *file) if (IS_ERR(trans)) goto out_drop; - file->private_data = trans; + private->trans = trans; return 0; out_drop: @@ -4072,6 +4061,10 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) ret = PTR_ERR(new_root); goto out; } + if (!is_fstree(new_root->objectid)) { + ret = -ENOENT; + goto out; + } path = btrfs_alloc_path(); if (!path) { @@ -4278,14 +4271,13 @@ long btrfs_ioctl_trans_end(struct file *file) { struct inode *inode = file_inode(file); struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_trans_handle *trans; + struct btrfs_file_private *private = file->private_data; - trans = file->private_data; - if (!trans) + if (!private || !private->trans) return -EINVAL; - file->private_data = NULL; - btrfs_end_transaction(trans); + btrfs_end_transaction(private->trans); + private->trans = NULL; atomic_dec(&root->fs_info->open_ioctl_trans); @@ -4438,7 +4430,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info, switch (p->cmd) { case BTRFS_IOCTL_DEV_REPLACE_CMD_START: - if (fs_info->sb->s_flags & MS_RDONLY) { + if (sb_rdonly(fs_info->sb)) { ret = -EROFS; goto out; } diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index fcae61e175f38899e3424c13120f06f510efa90b..569205e651c7dd46c98a8fe3d0798140322d4ec3 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -44,7 +44,7 @@ static void print_dev_item(struct extent_buffer *eb, static void print_extent_data_ref(struct extent_buffer *eb, struct btrfs_extent_data_ref *ref) { - pr_info("\t\textent data backref root %llu objectid %llu offset %llu count %u\n", + pr_cont("extent data backref root %llu objectid %llu offset %llu count %u\n", btrfs_extent_data_ref_root(eb, ref), btrfs_extent_data_ref_objectid(eb, ref), btrfs_extent_data_ref_offset(eb, ref), @@ -63,6 +63,7 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type) u32 item_size = btrfs_item_size_nr(eb, slot); u64 flags; u64 offset; + int ref_index = 0; if (item_size < sizeof(*ei)) { #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 @@ -104,12 +105,20 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type) iref = (struct btrfs_extent_inline_ref *)ptr; type = btrfs_extent_inline_ref_type(eb, iref); offset = btrfs_extent_inline_ref_offset(eb, iref); + pr_info("\t\tref#%d: ", ref_index++); switch (type) { case BTRFS_TREE_BLOCK_REF_KEY: - pr_info("\t\ttree block backref root %llu\n", offset); + pr_cont("tree block backref root %llu\n", offset); break; case BTRFS_SHARED_BLOCK_REF_KEY: - pr_info("\t\tshared block backref parent %llu\n", offset); + pr_cont("shared block backref parent %llu\n", offset); + /* + * offset is supposed to be a tree block which + * must be aligned to nodesize. + */ + if (!IS_ALIGNED(offset, eb->fs_info->nodesize)) + pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n", + offset, (unsigned long long)eb->fs_info->nodesize); break; case BTRFS_EXTENT_DATA_REF_KEY: dref = (struct btrfs_extent_data_ref *)(&iref->offset); @@ -117,11 +126,20 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type) break; case BTRFS_SHARED_DATA_REF_KEY: sref = (struct btrfs_shared_data_ref *)(iref + 1); - pr_info("\t\tshared data backref parent %llu count %u\n", + pr_cont("shared data backref parent %llu count %u\n", offset, btrfs_shared_data_ref_count(eb, sref)); + /* + * offset is supposed to be a tree block which + * must be aligned to nodesize. + */ + if (!IS_ALIGNED(offset, eb->fs_info->nodesize)) + pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n", + offset, (unsigned long long)eb->fs_info->nodesize); break; default: - BUG(); + pr_cont("(extent %llu has INVALID ref type %d)\n", + eb->start, type); + return; } ptr += btrfs_extent_inline_ref_size(type); } @@ -161,8 +179,9 @@ static void print_uuid_item(struct extent_buffer *l, unsigned long offset, } } -void btrfs_print_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *l) +void btrfs_print_leaf(struct extent_buffer *l) { + struct btrfs_fs_info *fs_info; int i; u32 type, nr; struct btrfs_item *item; @@ -180,6 +199,7 @@ void btrfs_print_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *l) if (!l) return; + fs_info = l->fs_info; nr = btrfs_header_nritems(l); btrfs_info(fs_info, "leaf %llu total ptrs %d free space %d", @@ -318,18 +338,20 @@ void btrfs_print_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *l) } } -void btrfs_print_tree(struct btrfs_fs_info *fs_info, struct extent_buffer *c) +void btrfs_print_tree(struct extent_buffer *c) { + struct btrfs_fs_info *fs_info; int i; u32 nr; struct btrfs_key key; int level; if (!c) return; + fs_info = c->fs_info; nr = btrfs_header_nritems(c); level = btrfs_header_level(c); if (level == 0) { - btrfs_print_leaf(fs_info, c); + btrfs_print_leaf(c); return; } btrfs_info(fs_info, @@ -359,7 +381,7 @@ void btrfs_print_tree(struct btrfs_fs_info *fs_info, struct extent_buffer *c) if (btrfs_header_level(next) != level - 1) BUG(); - btrfs_print_tree(fs_info, next); + btrfs_print_tree(next); free_extent_buffer(next); } } diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h index 4f2e0ea0e95aaaab8ee9e117397d9b1def371995..3afd508ed8c51895e187e8804dce9f238111b150 100644 --- a/fs/btrfs/print-tree.h +++ b/fs/btrfs/print-tree.h @@ -18,6 +18,6 @@ #ifndef __PRINT_TREE_ #define __PRINT_TREE_ -void btrfs_print_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *l); -void btrfs_print_tree(struct btrfs_fs_info *fs_info, struct extent_buffer *c); +void btrfs_print_leaf(struct extent_buffer *l); +void btrfs_print_tree(struct extent_buffer *c); #endif diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index 4b23ae5d0e5c0330260ae96d2574b9422c16978d..f6a05f8366297ef791f74de39f2a884972dfb7a7 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -390,6 +390,8 @@ static int prop_compression_validate(const char *value, size_t len) return 0; else if (!strncmp("zlib", value, len)) return 0; + else if (!strncmp("zstd", value, len)) + return 0; return -EINVAL; } @@ -403,32 +405,36 @@ static int prop_compression_apply(struct inode *inode, if (len == 0) { BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS; - BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE; + BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE; return 0; } - if (!strncmp("lzo", value, len)) + if (!strncmp("lzo", value, 3)) type = BTRFS_COMPRESS_LZO; - else if (!strncmp("zlib", value, len)) + else if (!strncmp("zlib", value, 4)) type = BTRFS_COMPRESS_ZLIB; + else if (!strncmp("zstd", value, len)) + type = BTRFS_COMPRESS_ZSTD; else return -EINVAL; BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS; BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS; - BTRFS_I(inode)->force_compress = type; + BTRFS_I(inode)->prop_compress = type; return 0; } static const char *prop_compression_extract(struct inode *inode) { - switch (BTRFS_I(inode)->force_compress) { + switch (BTRFS_I(inode)->prop_compress) { case BTRFS_COMPRESS_ZLIB: return "zlib"; case BTRFS_COMPRESS_LZO: return "lzo"; + case BTRFS_COMPRESS_ZSTD: + return "zstd"; } return NULL; diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 4ce351efe2813e101c74658873a25cff434633d6..e172d4843eae2d8eb6f0d29dce38fb7f693f4ed0 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -807,7 +807,6 @@ static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans, } ret = 0; out: - set_bit(BTRFS_FS_QUOTA_DISABLING, &root->fs_info->flags); btrfs_free_path(path); return ret; } @@ -946,7 +945,6 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, int btrfs_quota_disable(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info) { - struct btrfs_root *tree_root = fs_info->tree_root; struct btrfs_root *quota_root; int ret = 0; @@ -954,7 +952,6 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, if (!fs_info->quota_root) goto out; clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); - set_bit(BTRFS_FS_QUOTA_DISABLING, &fs_info->flags); btrfs_qgroup_wait_for_completion(fs_info, false); spin_lock(&fs_info->qgroup_lock); quota_root = fs_info->quota_root; @@ -968,7 +965,7 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans, if (ret) goto out; - ret = btrfs_del_root(trans, tree_root, "a_root->root_key); + ret = btrfs_del_root(trans, fs_info, "a_root->root_key); if (ret) goto out; @@ -1308,6 +1305,8 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, } } ret = del_qgroup_item(trans, quota_root, qgroupid); + if (ret && ret != -ENOENT) + goto out; while (!list_empty(&qgroup->groups)) { list = list_first_entry(&qgroup->groups, @@ -1603,7 +1602,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, struct extent_buffer *eb = root_eb; struct btrfs_path *path = NULL; - BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL); + BUG_ON(root_level < 0 || root_level >= BTRFS_MAX_LEVEL); BUG_ON(root_eb == NULL); if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) @@ -2087,8 +2086,6 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans, if (test_and_clear_bit(BTRFS_FS_QUOTA_ENABLING, &fs_info->flags)) set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); - if (test_and_clear_bit(BTRFS_FS_QUOTA_DISABLING, &fs_info->flags)) - clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); spin_lock(&fs_info->qgroup_lock); while (!list_empty(&fs_info->dirty_qgroups)) { @@ -2646,7 +2643,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) if (IS_ERR(trans)) { err = PTR_ERR(trans); btrfs_err(fs_info, - "fail to start transaction for status update: %d\n", + "fail to start transaction for status update: %d", err); goto done; } diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index 208638384cd2abfb1206b2f5927b5763a6330283..24a62224b24b1b5b307c84f38b07af31552729d7 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -905,7 +905,7 @@ static void raid_write_end_io(struct bio *bio) if (!atomic_dec_and_test(&rbio->stripes_pending)) return; - err = 0; + err = BLK_STS_OK; /* OK, we have read all the stripes we need to. */ max_errors = (rbio->operation == BTRFS_RBIO_PARITY_SCRUB) ? @@ -1090,7 +1090,8 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio, */ if (last_end == disk_start && stripe->dev->bdev && !last->bi_status && - last->bi_bdev == stripe->dev->bdev) { + last->bi_disk == stripe->dev->bdev->bd_disk && + last->bi_partno == stripe->dev->bdev->bd_partno) { ret = bio_add_page(last, page, PAGE_SIZE, 0); if (ret == PAGE_SIZE) return 0; @@ -1100,7 +1101,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio, /* put a new bio on the list */ bio = btrfs_io_bio_alloc(bio_max_len >> PAGE_SHIFT ?: 1); bio->bi_iter.bi_size = 0; - bio->bi_bdev = stripe->dev->bdev; + bio_set_dev(bio, stripe->dev->bdev); bio->bi_iter.bi_sector = disk_start >> 9; bio_add_page(bio, page, PAGE_SIZE, 0); @@ -1324,7 +1325,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) return; cleanup: - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); } /* @@ -1347,7 +1348,8 @@ static int find_bio_stripe(struct btrfs_raid_bio *rbio, stripe_start = stripe->physical; if (physical >= stripe_start && physical < stripe_start + rbio->stripe_len && - bio->bi_bdev == stripe->dev->bdev) { + bio->bi_disk == stripe->dev->bdev->bd_disk && + bio->bi_partno == stripe->dev->bdev->bd_partno) { return i; } } @@ -1475,7 +1477,7 @@ static void raid_rmw_end_io(struct bio *bio) cleanup: - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); } static void async_rmw_stripe(struct btrfs_raid_bio *rbio) @@ -1579,7 +1581,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio) return 0; cleanup: - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); return -EIO; finish: @@ -1795,12 +1797,12 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) void **pointers; int faila = -1, failb = -1; struct page *page; - int err; + blk_status_t err; int i; pointers = kcalloc(rbio->real_stripes, sizeof(void *), GFP_NOFS); if (!pointers) { - err = -ENOMEM; + err = BLK_STS_RESOURCE; goto cleanup_io; } @@ -1856,7 +1858,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) * a bad data or Q stripe. * TODO, we should redo the xor here. */ - err = -EIO; + err = BLK_STS_IOERR; goto cleanup; } /* @@ -1882,7 +1884,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) if (rbio->bbio->raid_map[failb] == RAID6_Q_STRIPE) { if (rbio->bbio->raid_map[faila] == RAID5_P_STRIPE) { - err = -EIO; + err = BLK_STS_IOERR; goto cleanup; } /* @@ -1954,13 +1956,13 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) } } - err = 0; + err = BLK_STS_OK; cleanup: kfree(pointers); cleanup_io: if (rbio->operation == BTRFS_RBIO_READ_REBUILD) { - if (err == 0) + if (err == BLK_STS_OK) cache_rbio_pages(rbio); else clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags); @@ -1968,7 +1970,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) rbio_orig_end_io(rbio, err); } else if (rbio->operation == BTRFS_RBIO_REBUILD_MISSING) { rbio_orig_end_io(rbio, err); - } else if (err == 0) { + } else if (err == BLK_STS_OK) { rbio->faila = -1; rbio->failb = -1; @@ -2005,7 +2007,7 @@ static void raid_recover_end_io(struct bio *bio) return; if (atomic_read(&rbio->error) > rbio->bbio->max_errors) - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); else __raid_recover_end_io(rbio); } @@ -2104,7 +2106,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio) cleanup: if (rbio->operation == BTRFS_RBIO_READ_REBUILD || rbio->operation == BTRFS_RBIO_REBUILD_MISSING) - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); return -EIO; } @@ -2431,7 +2433,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, nr_data = bio_list_size(&bio_list); if (!nr_data) { /* Every parity is right */ - rbio_orig_end_io(rbio, 0); + rbio_orig_end_io(rbio, BLK_STS_OK); return; } @@ -2451,7 +2453,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, return; cleanup: - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); } static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe) @@ -2519,7 +2521,7 @@ static void validate_rbio_for_parity_scrub(struct btrfs_raid_bio *rbio) return; cleanup: - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); } /* @@ -2633,7 +2635,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio) return; cleanup: - rbio_orig_end_io(rbio, -EIO); + rbio_orig_end_io(rbio, BLK_STS_IOERR); return; finish: diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 65661d1aae4e65c7314c98ad27d9139708e71103..9841faef08ea72d0b50aa3ad3c881bd27bd7fc76 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -32,6 +32,7 @@ #include "free-space-cache.h" #include "inode-map.h" #include "qgroup.h" +#include "print-tree.h" /* * backref_node, mapping_node and tree_block start with this @@ -799,9 +800,17 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, if (ptr < end) { /* update key for inline back ref */ struct btrfs_extent_inline_ref *iref; + int type; iref = (struct btrfs_extent_inline_ref *)ptr; - key.type = btrfs_extent_inline_ref_type(eb, iref); + type = btrfs_get_extent_inline_ref_type(eb, iref, + BTRFS_REF_TYPE_BLOCK); + if (type == BTRFS_REF_TYPE_INVALID) { + err = -EINVAL; + goto out; + } + key.type = type; key.offset = btrfs_extent_inline_ref_offset(eb, iref); + WARN_ON(key.type != BTRFS_TREE_BLOCK_REF_KEY && key.type != BTRFS_SHARED_BLOCK_REF_KEY); } @@ -1308,8 +1317,6 @@ static int __must_check __add_reloc_root(struct btrfs_root *root) btrfs_panic(fs_info, -EEXIST, "Duplicate root found for start=%llu while inserting into relocation tree", node->bytenr); - kfree(node); - return -EEXIST; } list_add_tail(&root->root_list, &rc->reloc_roots); @@ -2393,11 +2400,11 @@ void free_reloc_roots(struct list_head *list) while (!list_empty(list)) { reloc_root = list_entry(list->next, struct btrfs_root, root_list); + __del_reloc_root(reloc_root); free_extent_buffer(reloc_root->node); free_extent_buffer(reloc_root->commit_root); reloc_root->node = NULL; reloc_root->commit_root = NULL; - __del_reloc_root(reloc_root); } } @@ -3477,7 +3484,16 @@ static int __add_tree_block(struct reloc_control *rc, goto again; } } - BUG_ON(ret); + if (ret) { + ASSERT(ret == 1); + btrfs_print_leaf(path->nodes[0]); + btrfs_err(fs_info, + "tree block extent item (%llu) is not found in extent tree", + bytenr); + WARN_ON(1); + ret = -EINVAL; + goto out; + } ret = add_tree_block(rc, &key, path, blocks); out: @@ -3755,7 +3771,8 @@ int add_data_references(struct reloc_control *rc, while (ptr < end) { iref = (struct btrfs_extent_inline_ref *)ptr; - key.type = btrfs_extent_inline_ref_type(eb, iref); + key.type = btrfs_get_extent_inline_ref_type(eb, iref, + BTRFS_REF_TYPE_DATA); if (key.type == BTRFS_SHARED_DATA_REF_KEY) { key.offset = btrfs_extent_inline_ref_offset(eb, iref); ret = __add_tree_block(rc, key.offset, blocksize, @@ -3765,7 +3782,10 @@ int add_data_references(struct reloc_control *rc, ret = find_data_references(rc, extent_key, eb, dref, blocks); } else { - BUG(); + ret = -EINVAL; + btrfs_err(rc->extent_root->fs_info, + "extent %llu slot %d has an invalid inline ref type", + eb->start, path->slots[0]); } if (ret) { err = ret; diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 460db0cb2d0734db78c52a934620953b5677de23..95bcc3cce78f80e4096d470d97d41f7b6df89329 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -151,7 +151,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root } if (ret != 0) { - btrfs_print_leaf(fs_info, path->nodes[0]); + btrfs_print_leaf(path->nodes[0]); btrfs_crit(fs_info, "unable to update root key %llu %u %llu", key->objectid, key->type, key->offset); BUG_ON(1); @@ -228,7 +228,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info) int ret; bool can_recover = true; - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) can_recover = false; path = btrfs_alloc_path(); @@ -335,10 +335,11 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info) return err; } -/* drop the root item for 'key' from 'root' */ -int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, - const struct btrfs_key *key) +/* drop the root item for 'key' from the tree root */ +int btrfs_del_root(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, const struct btrfs_key *key) { + struct btrfs_root *root = fs_info->tree_root; struct btrfs_path *path; int ret; diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 6f1e4c984b94a5ed479530bc606ba8d9653bff9a..e3f6c49e5c4d8aad323b77f72ed6e12da26bee72 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -182,8 +182,8 @@ struct scrub_ctx { struct scrub_bio *wr_curr_bio; struct mutex wr_lock; int pages_per_wr_bio; /* <= SCRUB_PAGES_PER_WR_BIO */ - atomic_t flush_all_writes; struct btrfs_device *wr_tgtdev; + bool flush_all_writes; /* * statistics @@ -717,7 +717,7 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace) WARN_ON(!fs_info->dev_replace.tgtdev); sctx->pages_per_wr_bio = SCRUB_PAGES_PER_WR_BIO; sctx->wr_tgtdev = fs_info->dev_replace.tgtdev; - atomic_set(&sctx->flush_all_writes, 0); + sctx->flush_all_writes = false; } return sctx; @@ -1704,7 +1704,7 @@ static int scrub_submit_raid56_bio_wait(struct btrfs_fs_info *fs_info, if (ret) return ret; - wait_for_completion(&done.event); + wait_for_completion_io(&done.event); if (done.status) return -EIO; @@ -1738,7 +1738,7 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info, WARN_ON(!page->page); bio = btrfs_io_bio_alloc(1); - bio->bi_bdev = page->dev->bdev; + bio_set_dev(bio, page->dev->bdev); bio_add_page(bio, page->page, PAGE_SIZE, 0); if (!retry_failed_mirror && scrub_is_page_on_raid56(page)) { @@ -1769,7 +1769,7 @@ static inline int scrub_check_fsid(u8 fsid[], struct btrfs_fs_devices *fs_devices = spage->dev->fs_devices; int ret; - ret = memcmp(fsid, fs_devices->fsid, BTRFS_UUID_SIZE); + ret = memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE); return !ret; } @@ -1826,7 +1826,7 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, } bio = btrfs_io_bio_alloc(1); - bio->bi_bdev = page_bad->dev->bdev; + bio_set_dev(bio, page_bad->dev->bdev); bio->bi_iter.bi_sector = page_bad->physical >> 9; bio_set_op_attrs(bio, REQ_OP_WRITE, 0); @@ -1921,7 +1921,7 @@ static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx, bio->bi_private = sbio; bio->bi_end_io = scrub_wr_bio_end_io; - bio->bi_bdev = sbio->dev->bdev; + bio_set_dev(bio, sbio->dev->bdev); bio->bi_iter.bi_sector = sbio->physical >> 9; bio_set_op_attrs(bio, REQ_OP_WRITE, 0); sbio->status = 0; @@ -1964,7 +1964,7 @@ static void scrub_wr_submit(struct scrub_ctx *sctx) sbio = sctx->wr_curr_bio; sctx->wr_curr_bio = NULL; - WARN_ON(!sbio->bio->bi_bdev); + WARN_ON(!sbio->bio->bi_disk); scrub_pending_bio_inc(sctx); /* process all writes in a single worker thread. Then the block layer * orders the requests before sending them to the driver which @@ -2321,7 +2321,7 @@ static int scrub_add_page_to_rd_bio(struct scrub_ctx *sctx, bio->bi_private = sbio; bio->bi_end_io = scrub_bio_end_io; - bio->bi_bdev = sbio->dev->bdev; + bio_set_dev(bio, sbio->dev->bdev); bio->bi_iter.bi_sector = sbio->physical >> 9; bio_set_op_attrs(bio, REQ_OP_READ, 0); sbio->status = 0; @@ -2402,8 +2402,7 @@ static void scrub_missing_raid56_worker(struct btrfs_work *work) scrub_block_put(sblock); - if (sctx->is_dev_replace && - atomic_read(&sctx->flush_all_writes)) { + if (sctx->is_dev_replace && sctx->flush_all_writes) { mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); mutex_unlock(&sctx->wr_lock); @@ -2607,8 +2606,7 @@ static void scrub_bio_end_io_worker(struct btrfs_work *work) sctx->first_free = sbio->index; spin_unlock(&sctx->list_lock); - if (sctx->is_dev_replace && - atomic_read(&sctx->flush_all_writes)) { + if (sctx->is_dev_replace && sctx->flush_all_writes) { mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); mutex_unlock(&sctx->wr_lock); @@ -2622,7 +2620,8 @@ static inline void __scrub_mark_bitmap(struct scrub_parity *sparity, u64 start, u64 len) { u64 offset; - int nsectors; + u64 nsectors64; + u32 nsectors; int sectorsize = sparity->sctx->fs_info->sectorsize; if (len >= sparity->stripe_len) { @@ -2633,7 +2632,10 @@ static inline void __scrub_mark_bitmap(struct scrub_parity *sparity, start -= sparity->logic_start; start = div64_u64_rem(start, sparity->stripe_len, &offset); offset = div_u64(offset, sectorsize); - nsectors = (int)len / sectorsize; + nsectors64 = div_u64(len, sectorsize); + + ASSERT(nsectors64 < UINT_MAX); + nsectors = (u32)nsectors64; if (offset + nsectors <= sparity->nsectors) { bitmap_set(bitmap, offset, nsectors); @@ -2706,7 +2708,9 @@ static int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum) if (!sum) return 0; - index = ((u32)(logical - sum->bytenr)) / sctx->fs_info->sectorsize; + index = div_u64(logical - sum->bytenr, sctx->fs_info->sectorsize); + ASSERT(index < UINT_MAX); + num_sectors = sum->len / sctx->fs_info->sectorsize; memcpy(csum, sum->sums + index, sctx->csum_size); if (index == num_sectors - 1) { @@ -3440,14 +3444,14 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, */ if (atomic_read(&fs_info->scrub_pause_req)) { /* push queued extents */ - atomic_set(&sctx->flush_all_writes, 1); + sctx->flush_all_writes = true; scrub_submit(sctx); mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); mutex_unlock(&sctx->wr_lock); wait_event(sctx->list_wait, atomic_read(&sctx->bios_in_flight) == 0); - atomic_set(&sctx->flush_all_writes, 0); + sctx->flush_all_writes = false; scrub_blocked_if_needed(fs_info); } @@ -3869,8 +3873,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, ro_set = 0; } else { btrfs_warn(fs_info, - "failed setting block group ro, ret=%d\n", - ret); + "failed setting block group ro: %d", ret); btrfs_put_block_group(cache); break; } @@ -3893,7 +3896,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, * write requests are really completed when bios_in_flight * changes to 0. */ - atomic_set(&sctx->flush_all_writes, 1); + sctx->flush_all_writes = true; scrub_submit(sctx); mutex_lock(&sctx->wr_lock); scrub_wr_submit(sctx); @@ -3911,7 +3914,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, */ wait_event(sctx->list_wait, atomic_read(&sctx->workers_pending) == 0); - atomic_set(&sctx->flush_all_writes, 0); + sctx->flush_all_writes = false; scrub_pause_off(fs_info); @@ -4012,14 +4015,8 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, int max_active = fs_info->thread_pool_size; if (fs_info->scrub_workers_refcnt == 0) { - if (is_dev_replace) - fs_info->scrub_workers = - btrfs_alloc_workqueue(fs_info, "scrub", flags, - 1, 4); - else - fs_info->scrub_workers = - btrfs_alloc_workqueue(fs_info, "scrub", flags, - max_active, 4); + fs_info->scrub_workers = btrfs_alloc_workqueue(fs_info, "scrub", + flags, is_dev_replace ? 1 : max_active, 4); if (!fs_info->scrub_workers) goto fail_scrub_workers; @@ -4627,7 +4624,7 @@ static int write_page_nocow(struct scrub_ctx *sctx, bio = btrfs_io_bio_alloc(1); bio->bi_iter.bi_size = 0; bio->bi_iter.bi_sector = physical_for_dev_replace >> 9; - bio->bi_bdev = dev->bdev; + bio_set_dev(bio, dev->bdev); bio->bi_opf = REQ_OP_WRITE | REQ_SYNC; ret = bio_add_page(bio, page, PAGE_SIZE, 0); if (ret != PAGE_SIZE) { diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index b082210df9c8b44d822dcb20ae07fb56a76fdde3..8fd195cfe81b97b92412b95ac645188eb9a5a693 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -539,33 +539,23 @@ static struct btrfs_path *alloc_path_for_send(void) static int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off) { int ret; - mm_segment_t old_fs; u32 pos = 0; - old_fs = get_fs(); - set_fs(KERNEL_DS); - while (pos < len) { - ret = vfs_write(filp, (__force const char __user *)buf + pos, - len - pos, off); + ret = kernel_write(filp, buf + pos, len - pos, off); /* TODO handle that correctly */ /*if (ret == -ERESTARTSYS) { continue; }*/ if (ret < 0) - goto out; + return ret; if (ret == 0) { - ret = -EIO; - goto out; + return -EIO; } pos += ret; } - ret = 0; - -out: - set_fs(old_fs); - return ret; + return 0; } static int tlv_put(struct send_ctx *sctx, u16 attr, const void *data, int len) @@ -2640,7 +2630,7 @@ static int send_create_inode(struct send_ctx *sctx, u64 ino) } else { btrfs_warn(sctx->send_root->fs_info, "unexpected inode type %o", (int)(mode & S_IFMT)); - ret = -ENOTSUPP; + ret = -EOPNOTSUPP; goto out; } @@ -4733,7 +4723,7 @@ static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len) /* initial readahead */ memset(&sctx->ra, 0, sizeof(struct file_ra_state)); file_ra_state_init(&sctx->ra, inode->i_mapping); - btrfs_force_ra(inode->i_mapping, &sctx->ra, NULL, index, + page_cache_sync_readahead(inode->i_mapping, &sctx->ra, NULL, index, last_index - index + 1); while (index <= last_index) { @@ -4992,6 +4982,25 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_key key; int ret; + /* + * Prevent cloning from a zero offset with a length matching the sector + * size because in some scenarios this will make the receiver fail. + * + * For example, if in the source filesystem the extent at offset 0 + * has a length of sectorsize and it was written using direct IO, then + * it can never be an inline extent (even if compression is enabled). + * Then this extent can be cloned in the original filesystem to a non + * zero file offset, but it may not be possible to clone in the + * destination filesystem because it can be inlined due to compression + * on the destination filesystem (as the receiver's write operations are + * always done using buffered IO). The same happens when the original + * filesystem does not have compression enabled but the destination + * filesystem has. + */ + if (clone_root->offset == 0 && + len == sctx->send_root->fs_info->sectorsize) + return send_extent_data(sctx, offset, len); + path = alloc_path_for_send(); if (!path) return -ENOMEM; diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c index 875c757e73e2a8eacae1d9817bd83d56d32b21cf..5e2b92d8361735fb27d2b17ff132439821b4fb34 100644 --- a/fs/btrfs/struct-funcs.c +++ b/fs/btrfs/struct-funcs.c @@ -50,8 +50,8 @@ static inline void put_unaligned_le8(u8 val, void *p) */ #define DEFINE_BTRFS_SETGET_BITS(bits) \ -u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ - unsigned long off, \ +u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \ + const void *ptr, unsigned long off, \ struct btrfs_map_token *token) \ { \ unsigned long part_offset = (unsigned long)ptr; \ @@ -90,7 +90,8 @@ u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ return res; \ } \ void btrfs_set_token_##bits(struct extent_buffer *eb, \ - void *ptr, unsigned long off, u##bits val, \ + const void *ptr, unsigned long off, \ + u##bits val, \ struct btrfs_map_token *token) \ { \ unsigned long part_offset = (unsigned long)ptr; \ @@ -133,7 +134,7 @@ DEFINE_BTRFS_SETGET_BITS(16) DEFINE_BTRFS_SETGET_BITS(32) DEFINE_BTRFS_SETGET_BITS(64) -void btrfs_node_key(struct extent_buffer *eb, +void btrfs_node_key(const struct extent_buffer *eb, struct btrfs_disk_key *disk_key, int nr) { unsigned long ptr = btrfs_node_key_ptr_offset(nr); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 12540b6104b5d9269baf4b35de420eca930b15af..35a128acfbd157b302386f9890d2a1de160c7be7 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -61,6 +61,7 @@ #include "tests/btrfs-tests.h" #include "qgroup.h" +#include "backref.h" #define CREATE_TRACE_POINTS #include @@ -102,7 +103,7 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) { struct super_block *sb = fs_info->sb; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { @@ -138,7 +139,7 @@ void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function * Special case: if the error is EROFS, and we're already * under MS_RDONLY, then it is safe here. */ - if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) + if (errno == -EROFS && sb_rdonly(sb)) return; #ifdef CONFIG_PRINTK @@ -425,7 +426,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, * strsep changes the string, duplicate it because parse_options * gets called twice */ - options = kstrdup(options, GFP_NOFS); + options = kstrdup(options, GFP_KERNEL); if (!options) return -ENOMEM; @@ -498,14 +499,14 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, btrfs_test_opt(info, FORCE_COMPRESS); if (token == Opt_compress || token == Opt_compress_force || - strcmp(args[0].from, "zlib") == 0) { + strncmp(args[0].from, "zlib", 4) == 0) { compress_type = "zlib"; info->compress_type = BTRFS_COMPRESS_ZLIB; btrfs_set_opt(info->mount_opt, COMPRESS); btrfs_clear_opt(info->mount_opt, NODATACOW); btrfs_clear_opt(info->mount_opt, NODATASUM); no_compress = 0; - } else if (strcmp(args[0].from, "lzo") == 0) { + } else if (strncmp(args[0].from, "lzo", 3) == 0) { compress_type = "lzo"; info->compress_type = BTRFS_COMPRESS_LZO; btrfs_set_opt(info->mount_opt, COMPRESS); @@ -513,6 +514,14 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, btrfs_clear_opt(info->mount_opt, NODATASUM); btrfs_set_fs_incompat(info, COMPRESS_LZO); no_compress = 0; + } else if (strcmp(args[0].from, "zstd") == 0) { + compress_type = "zstd"; + info->compress_type = BTRFS_COMPRESS_ZSTD; + btrfs_set_opt(info->mount_opt, COMPRESS); + btrfs_clear_opt(info->mount_opt, NODATACOW); + btrfs_clear_opt(info->mount_opt, NODATASUM); + btrfs_set_fs_incompat(info, COMPRESS_ZSTD); + no_compress = 0; } else if (strncmp(args[0].from, "no", 2) == 0) { compress_type = "no"; btrfs_clear_opt(info->mount_opt, COMPRESS); @@ -548,20 +557,22 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, break; case Opt_ssd: btrfs_set_and_info(info, SSD, - "use ssd allocation scheme"); + "enabling ssd optimizations"); btrfs_clear_opt(info->mount_opt, NOSSD); break; case Opt_ssd_spread: + btrfs_set_and_info(info, SSD, + "enabling ssd optimizations"); btrfs_set_and_info(info, SSD_SPREAD, - "use spread ssd allocation scheme"); - btrfs_set_opt(info->mount_opt, SSD); + "using spread ssd allocation scheme"); btrfs_clear_opt(info->mount_opt, NOSSD); break; case Opt_nossd: - btrfs_set_and_info(info, NOSSD, - "not using ssd allocation scheme"); - btrfs_clear_opt(info->mount_opt, SSD); - btrfs_clear_opt(info->mount_opt, SSD_SPREAD); + btrfs_set_opt(info->mount_opt, NOSSD); + btrfs_clear_and_info(info, SSD, + "not using ssd optimizations"); + btrfs_clear_and_info(info, SSD_SPREAD, + "not using spread ssd allocation scheme"); break; case Opt_barrier: btrfs_clear_and_info(info, NOBARRIER, @@ -949,7 +960,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, } path->leave_spinning = 1; - name = kmalloc(PATH_MAX, GFP_NOFS); + name = kmalloc(PATH_MAX, GFP_KERNEL); if (!name) { ret = -ENOMEM; goto err; @@ -1227,8 +1238,10 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) if (btrfs_test_opt(info, COMPRESS)) { if (info->compress_type == BTRFS_COMPRESS_ZLIB) compress_type = "zlib"; - else + else if (info->compress_type == BTRFS_COMPRESS_LZO) compress_type = "lzo"; + else + compress_type = "zstd"; if (btrfs_test_opt(info, FORCE_COMPRESS)) seq_printf(seq, ",compress-force=%s", compress_type); else @@ -1335,10 +1348,11 @@ static char *setup_root_args(char *args) char *buf, *dst, *sep; if (!args) - return kstrdup("subvolid=0", GFP_NOFS); + return kstrdup("subvolid=0", GFP_KERNEL); /* The worst case is that we add ",subvolid=0" to the end. */ - buf = dst = kmalloc(strlen(args) + strlen(",subvolid=0") + 1, GFP_NOFS); + buf = dst = kmalloc(strlen(args) + strlen(",subvolid=0") + 1, + GFP_KERNEL); if (!buf) return NULL; @@ -1567,7 +1581,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, * it for searching for existing supers, so this lets us do that and * then open_ctree will properly initialize everything later. */ - fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); + fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); if (!fs_info) { error = -ENOMEM; goto error_sec_opts; @@ -1575,8 +1589,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, fs_info->fs_devices = fs_devices; - fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); - fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); + fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); + fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); security_init_mnt_opts(&fs_info->security_opts); if (!fs_info->super_copy || !fs_info->super_for_commit) { error = -ENOMEM; @@ -1687,8 +1701,7 @@ static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info, * close or the filesystem is read only. */ if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && - (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || - (fs_info->sb->s_flags & MS_RDONLY))) { + (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || sb_rdonly(fs_info->sb))) { btrfs_cleanup_defrag_inodes(fs_info); } @@ -1735,7 +1748,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) btrfs_resize_thread_pool(fs_info, fs_info->thread_pool_size, old_thread_pool_size); - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) goto out; if (*flags & MS_RDONLY) { @@ -1780,8 +1793,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) goto restore; } - if (fs_info->fs_devices->missing_devices > - fs_info->num_tolerated_disk_barrier_failures) { + if (!btrfs_check_rw_degradable(fs_info)) { btrfs_warn(fs_info, "too many missing devices, writeable remount is not allowed"); ret = -EACCES; @@ -1814,6 +1826,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) goto restore; } + btrfs_qgroup_rescan_resume(fs_info); + if (!fs_info->uuid_root) { btrfs_info(fs_info, "creating UUID tree"); ret = btrfs_create_uuid_tree(fs_info); @@ -1835,7 +1849,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) restore: /* We've hit an error - don't reset MS_RDONLY */ - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) old_flags |= MS_RDONLY; sb->s_flags = old_flags; fs_info->mount_opt = old_opts; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index c2d5f3580b4cff9fe00352f2daabe07f14e6dfd8..883881b16c86f7539b1de2eb9243c951e112f408 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -120,7 +120,7 @@ static ssize_t btrfs_feature_attr_store(struct kobject *kobj, if (!fs_info) return -EPERM; - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) return -EROFS; ret = kstrtoul(skip_spaces(buf), 0, &val); @@ -200,6 +200,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(mixed_backref, MIXED_BACKREF); BTRFS_FEAT_ATTR_INCOMPAT(default_subvol, DEFAULT_SUBVOL); BTRFS_FEAT_ATTR_INCOMPAT(mixed_groups, MIXED_GROUPS); BTRFS_FEAT_ATTR_INCOMPAT(compress_lzo, COMPRESS_LZO); +BTRFS_FEAT_ATTR_INCOMPAT(compress_zstd, COMPRESS_ZSTD); BTRFS_FEAT_ATTR_INCOMPAT(big_metadata, BIG_METADATA); BTRFS_FEAT_ATTR_INCOMPAT(extended_iref, EXTENDED_IREF); BTRFS_FEAT_ATTR_INCOMPAT(raid56, RAID56); @@ -212,6 +213,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = { BTRFS_FEAT_ATTR_PTR(default_subvol), BTRFS_FEAT_ATTR_PTR(mixed_groups), BTRFS_FEAT_ATTR_PTR(compress_lzo), + BTRFS_FEAT_ATTR_PTR(compress_zstd), BTRFS_FEAT_ATTR_PTR(big_metadata), BTRFS_FEAT_ATTR_PTR(extended_iref), BTRFS_FEAT_ATTR_PTR(raid56), @@ -388,7 +390,7 @@ static ssize_t btrfs_label_store(struct kobject *kobj, if (!fs_info) return -EPERM; - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) return -EROFS; /* diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index b18ab8f327a53dd10b09bee6169f34ecff5eb809..d3f25376a0f86d255fa2db7999ff8da612422da9 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c @@ -211,7 +211,6 @@ btrfs_alloc_dummy_block_group(struct btrfs_fs_info *fs_info, cache->key.objectid = 0; cache->key.offset = length; cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; - cache->sectorsize = fs_info->sectorsize; cache->full_stripe_len = fs_info->sectorsize; cache->fs_info = fs_info; diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c index b29954c016738ad05c40ebefb2ba34f4cb8d75ca..1458bb0ea124a3784403adf6196e9bd146098b0d 100644 --- a/fs/btrfs/tests/free-space-tree-tests.c +++ b/fs/btrfs/tests/free-space-tree-tests.c @@ -81,7 +81,7 @@ static int __check_free_space_extents(struct btrfs_trans_handle *trans, i++; } prev_bit = bit; - offset += cache->sectorsize; + offset += fs_info->sectorsize; } } if (prev_bit == 1) { diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3a11ae63676ea8a299828c18fc772e74e57a07e5..c800d067fcbf0c8eec90c479eefe5df13e2dc945 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1143,8 +1143,6 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, goto again; } kfree(victim_name); - if (ret) - return ret; next: cur_offset += victim_name_len + sizeof(*extref); } @@ -3690,7 +3688,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, src_offset = btrfs_item_ptr_offset(src, start_slot + i); - if ((i == (nr - 1))) + if (i == nr - 1) last_key = ins_keys[i]; if (ins_keys[i].type == BTRFS_INODE_ITEM_KEY) { @@ -4183,6 +4181,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, struct extent_map *em, *n; struct list_head extents; struct extent_map_tree *tree = &inode->extent_tree; + u64 logged_start, logged_end; u64 test_gen; int ret = 0; int num = 0; @@ -4192,10 +4191,11 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, down_write(&inode->dio_sem); write_lock(&tree->lock); test_gen = root->fs_info->last_trans_committed; + logged_start = start; + logged_end = end; list_for_each_entry_safe(em, n, &tree->modified_extents, list) { list_del_init(&em->list); - /* * Just an arbitrary number, this can be really CPU intensive * once we start getting a lot of extents, and really once we @@ -4210,6 +4210,12 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, if (em->generation <= test_gen) continue; + + if (em->start < logged_start) + logged_start = em->start; + if ((em->start + em->len - 1) > logged_end) + logged_end = em->start + em->len - 1; + /* Need a ref to keep it from getting evicted from cache */ refcount_inc(&em->refs); set_bit(EXTENT_FLAG_LOGGING, &em->flags); @@ -4218,7 +4224,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, } list_sort(NULL, &extents, extent_cmp); - btrfs_get_logged_extents(inode, logged_list, start, end); + btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end); /* * Some ordered extents started by fsync might have completed * before we could collect them into the list logged_list, which @@ -4450,7 +4456,10 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans, len = btrfs_file_extent_inline_len(leaf, path->slots[0], extent); - ASSERT(len == i_size); + ASSERT(len == i_size || + (len == fs_info->sectorsize && + btrfs_file_extent_compression(leaf, extent) != + BTRFS_COMPRESS_NONE)); return 0; } diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index e8b9a269fddec78fdf42adec32eabaffdf9c3636..b39737568c223c208d92b2f4ab73ac0263ad3ff4 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -152,7 +152,15 @@ struct list_head *btrfs_get_fs_uuids(void) return &fs_uuids; } -static struct btrfs_fs_devices *__alloc_fs_devices(void) +/* + * alloc_fs_devices - allocate struct btrfs_fs_devices + * @fsid: if not NULL, copy the uuid to fs_devices::fsid + * + * Return a pointer to a new struct btrfs_fs_devices on success, or ERR_PTR(). + * The returned struct is not linked onto any lists and can be destroyed with + * kfree() right away. + */ +static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid) { struct btrfs_fs_devices *fs_devs; @@ -166,31 +174,8 @@ static struct btrfs_fs_devices *__alloc_fs_devices(void) INIT_LIST_HEAD(&fs_devs->resized_devices); INIT_LIST_HEAD(&fs_devs->alloc_list); INIT_LIST_HEAD(&fs_devs->list); - - return fs_devs; -} - -/** - * alloc_fs_devices - allocate struct btrfs_fs_devices - * @fsid: a pointer to UUID for this FS. If NULL a new UUID is - * generated. - * - * Return: a pointer to a new &struct btrfs_fs_devices on success; - * ERR_PTR() on error. Returned struct is not linked onto any lists and - * can be destroyed with kfree() right away. - */ -static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid) -{ - struct btrfs_fs_devices *fs_devs; - - fs_devs = __alloc_fs_devices(); - if (IS_ERR(fs_devs)) - return fs_devs; - if (fsid) memcpy(fs_devs->fsid, fsid, BTRFS_FSID_SIZE); - else - generate_random_uuid(fs_devs->fsid); return fs_devs; } @@ -269,9 +254,17 @@ static struct btrfs_device *__alloc_device(void) return dev; } -static noinline struct btrfs_device *__find_device(struct list_head *head, - u64 devid, u8 *uuid) +/* + * Find a device specified by @devid or @uuid in the list of @fs_devices, or + * return NULL. + * + * If devid and uuid are both specified, the match must be exact, otherwise + * only devid is used. + */ +static struct btrfs_device *find_device(struct btrfs_fs_devices *fs_devices, + u64 devid, const u8 *uuid) { + struct list_head *head = &fs_devices->devices; struct btrfs_device *dev; list_for_each_entry(dev, head, dev_list) { @@ -310,7 +303,7 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder, if (flush) filemap_write_and_wait((*bdev)->bd_inode->i_mapping); - ret = set_blocksize(*bdev, 4096); + ret = set_blocksize(*bdev, BTRFS_BDEV_BLOCKSIZE); if (ret) { blkdev_put(*bdev, flags); goto error; @@ -636,8 +629,8 @@ static noinline int device_list_add(const char *path, device = NULL; } else { - device = __find_device(&fs_devices->devices, devid, - disk_super->dev_item.uuid); + device = find_device(fs_devices, devid, + disk_super->dev_item.uuid); } if (!device) { @@ -1578,7 +1571,6 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, struct btrfs_device *device, - u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 start, u64 num_bytes) { int ret; @@ -1606,12 +1598,12 @@ static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; extent = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dev_extent); - btrfs_set_dev_extent_chunk_tree(leaf, extent, chunk_tree); - btrfs_set_dev_extent_chunk_objectid(leaf, extent, chunk_objectid); + btrfs_set_dev_extent_chunk_tree(leaf, extent, + BTRFS_CHUNK_TREE_OBJECTID); + btrfs_set_dev_extent_chunk_objectid(leaf, extent, + BTRFS_FIRST_CHUNK_TREE_OBJECTID); btrfs_set_dev_extent_chunk_offset(leaf, extent, chunk_offset); - write_extent_buffer_chunk_tree_uuid(leaf, fs_info->chunk_tree_uuid); - btrfs_set_dev_extent_length(leaf, extent, num_bytes); btrfs_mark_buffer_dirty(leaf); out: @@ -1726,7 +1718,7 @@ static int btrfs_add_device(struct btrfs_trans_handle *trans, ptr = btrfs_device_uuid(dev_item); write_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE); ptr = btrfs_device_fsid(dev_item); - write_extent_buffer(leaf, fs_info->fsid, ptr, BTRFS_UUID_SIZE); + write_extent_buffer(leaf, fs_info->fsid, ptr, BTRFS_FSID_SIZE); btrfs_mark_buffer_dirty(leaf); ret = 0; @@ -1872,7 +1864,6 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, struct btrfs_fs_devices *cur_devices; u64 num_devices; int ret = 0; - bool clear_super = false; mutex_lock(&uuid_mutex); @@ -1908,7 +1899,6 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, list_del_init(&device->dev_alloc_list); device->fs_devices->rw_devices--; mutex_unlock(&fs_info->chunk_mutex); - clear_super = true; } mutex_unlock(&uuid_mutex); @@ -1987,9 +1977,6 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, free_fs_devices(cur_devices); } - fs_info->num_tolerated_disk_barrier_failures = - btrfs_calc_num_tolerated_disk_barrier_failures(fs_info); - out: mutex_unlock(&uuid_mutex); return ret; @@ -2202,7 +2189,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info) if (!fs_devices->seeding) return -EINVAL; - seed_devices = __alloc_fs_devices(); + seed_devices = alloc_fs_devices(NULL); if (IS_ERR(seed_devices)) return PTR_ERR(seed_devices); @@ -2261,7 +2248,7 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans, struct btrfs_dev_item *dev_item; struct btrfs_device *device; struct btrfs_key key; - u8 fs_uuid[BTRFS_UUID_SIZE]; + u8 fs_uuid[BTRFS_FSID_SIZE]; u8 dev_uuid[BTRFS_UUID_SIZE]; u64 devid; int ret; @@ -2304,7 +2291,7 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans, read_extent_buffer(leaf, dev_uuid, btrfs_device_uuid(dev_item), BTRFS_UUID_SIZE); read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item), - BTRFS_UUID_SIZE); + BTRFS_FSID_SIZE); device = btrfs_find_device(fs_info, devid, dev_uuid, fs_uuid); BUG_ON(!device); /* Logic error */ @@ -2337,7 +2324,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path int seeding_dev = 0; int ret = 0; - if ((sb->s_flags & MS_RDONLY) && !fs_info->fs_devices->seeding) + if (sb_rdonly(sb) && !fs_info->fs_devices->seeding) return -EROFS; bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL, @@ -2407,7 +2394,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path device->is_tgtdev_for_dev_replace = 0; device->mode = FMODE_EXCL; device->dev_stats_valid = 1; - set_blocksize(device->bdev, 4096); + set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE); if (seeding_dev) { sb->s_flags &= ~MS_RDONLY; @@ -2487,8 +2474,6 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path "sysfs: failed to create fsid for sprout"); } - fs_info->num_tolerated_disk_barrier_failures = - btrfs_calc_num_tolerated_disk_barrier_failures(fs_info); ret = btrfs_commit_transaction(trans); if (seeding_dev) { @@ -2612,7 +2597,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, device->is_tgtdev_for_dev_replace = 1; device->mode = FMODE_EXCL; device->dev_stats_valid = 1; - set_blocksize(device->bdev, 4096); + set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE); device->fs_devices = fs_info->fs_devices; list_add(&device->dev_list, &fs_info->fs_devices->devices); fs_info->fs_devices->num_devices++; @@ -2728,8 +2713,7 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans, } static int btrfs_free_chunk(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, u64 chunk_objectid, - u64 chunk_offset) + struct btrfs_fs_info *fs_info, u64 chunk_offset) { struct btrfs_root *root = fs_info->chunk_root; int ret; @@ -2740,7 +2724,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans, if (!path) return -ENOMEM; - key.objectid = chunk_objectid; + key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; key.offset = chunk_offset; key.type = BTRFS_CHUNK_ITEM_KEY; @@ -2763,8 +2747,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans, return ret; } -static int btrfs_del_sys_chunk(struct btrfs_fs_info *fs_info, - u64 chunk_objectid, u64 chunk_offset) +static int btrfs_del_sys_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset) { struct btrfs_super_block *super_copy = fs_info->super_copy; struct btrfs_disk_key *disk_key; @@ -2797,7 +2780,7 @@ static int btrfs_del_sys_chunk(struct btrfs_fs_info *fs_info, ret = -EIO; break; } - if (key.objectid == chunk_objectid && + if (key.objectid == BTRFS_FIRST_CHUNK_TREE_OBJECTID && key.offset == chunk_offset) { memmove(ptr, ptr + len, array_size - (cur + len)); array_size -= len; @@ -2846,7 +2829,6 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, struct extent_map *em; struct map_lookup *map; u64 dev_extent_len = 0; - u64 chunk_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; int i, ret = 0; struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; @@ -2902,7 +2884,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, } mutex_unlock(&fs_devices->device_list_mutex); - ret = btrfs_free_chunk(trans, fs_info, chunk_objectid, chunk_offset); + ret = btrfs_free_chunk(trans, fs_info, chunk_offset); if (ret) { btrfs_abort_transaction(trans, ret); goto out; @@ -2911,8 +2893,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, trace_btrfs_chunk_free(fs_info, map, chunk_offset, em->len); if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) { - ret = btrfs_del_sys_chunk(fs_info, chunk_objectid, - chunk_offset); + ret = btrfs_del_sys_chunk(fs_info, chunk_offset); if (ret) { btrfs_abort_transaction(trans, ret); goto out; @@ -3312,7 +3293,6 @@ static int chunk_devid_filter(struct extent_buffer *leaf, /* [pstart, pend) */ static int chunk_drange_filter(struct extent_buffer *leaf, struct btrfs_chunk *chunk, - u64 chunk_offset, struct btrfs_balance_args *bargs) { struct btrfs_stripe *stripe; @@ -3439,7 +3419,7 @@ static int should_balance_chunk(struct btrfs_fs_info *fs_info, /* drange filter, makes sense only with devid filter */ if ((bargs->flags & BTRFS_BALANCE_ARGS_DRANGE) && - chunk_drange_filter(leaf, chunk, chunk_offset, bargs)) { + chunk_drange_filter(leaf, chunk, bargs)) { return 0; } @@ -3898,13 +3878,6 @@ int btrfs_balance(struct btrfs_balance_control *bctl, meta_target, data_target); } - if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) { - fs_info->num_tolerated_disk_barrier_failures = min( - btrfs_calc_num_tolerated_disk_barrier_failures(fs_info), - btrfs_get_num_tolerated_disk_barrier_failures( - bctl->sys.target)); - } - ret = insert_balance_item(fs_info, bctl); if (ret && ret != -EEXIST) goto out; @@ -3927,11 +3900,6 @@ int btrfs_balance(struct btrfs_balance_control *bctl, mutex_lock(&fs_info->balance_mutex); atomic_dec(&fs_info->balance_running); - if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) { - fs_info->num_tolerated_disk_barrier_failures = - btrfs_calc_num_tolerated_disk_barrier_failures(fs_info); - } - if (bargs) { memset(bargs, 0, sizeof(*bargs)); update_ioctl_balance_args(fs_info, 0, bargs); @@ -4085,7 +4053,7 @@ int btrfs_pause_balance(struct btrfs_fs_info *fs_info) int btrfs_cancel_balance(struct btrfs_fs_info *fs_info) { - if (fs_info->sb->s_flags & MS_RDONLY) + if (sb_rdonly(fs_info->sb)) return -EROFS; mutex_lock(&fs_info->balance_mutex); @@ -4127,7 +4095,6 @@ static int btrfs_uuid_scan_kthread(void *data) struct btrfs_fs_info *fs_info = data; struct btrfs_root *root = fs_info->tree_root; struct btrfs_key key; - struct btrfs_key max_key; struct btrfs_path *path = NULL; int ret = 0; struct extent_buffer *eb; @@ -4146,10 +4113,6 @@ static int btrfs_uuid_scan_kthread(void *data) key.type = BTRFS_ROOT_ITEM_KEY; key.offset = 0; - max_key.objectid = (u64)-1; - max_key.type = BTRFS_ROOT_ITEM_KEY; - max_key.offset = (u64)-1; - while (1) { ret = btrfs_search_forward(root, &key, path, 0); if (ret) { @@ -4601,12 +4564,6 @@ static int btrfs_cmp_device_info(const void *a, const void *b) return 0; } -static u32 find_raid56_stripe_len(u32 data_devices, u32 dev_stripe_target) -{ - /* TODO allow them to set a preferred stripe size */ - return SZ_64K; -} - static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type) { if (!(type & BTRFS_BLOCK_GROUP_RAID56_MASK)) @@ -4629,7 +4586,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, { struct btrfs_fs_info *info = trans->fs_info; struct btrfs_fs_devices *fs_devices = info->fs_devices; - struct list_head *cur; + struct btrfs_device *device; struct map_lookup *map = NULL; struct extent_map_tree *em_tree; struct extent_map *em; @@ -4649,7 +4606,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 max_chunk_size; u64 stripe_size; u64 num_bytes; - u64 raid_stripe_len = BTRFS_STRIPE_LEN; int ndevs; int i; int j; @@ -4703,22 +4659,15 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, if (!devices_info) return -ENOMEM; - cur = fs_devices->alloc_list.next; - /* * in the first pass through the devices list, we gather information * about the available holes on each device. */ ndevs = 0; - while (cur != &fs_devices->alloc_list) { - struct btrfs_device *device; + list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { u64 max_avail; u64 dev_offset; - device = list_entry(cur, struct btrfs_device, dev_alloc_list); - - cur = cur->next; - if (!device->writeable) { WARN(1, KERN_ERR "BTRFS: read-only device in alloc_list\n"); @@ -4769,15 +4718,15 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, btrfs_cmp_device_info, NULL); /* round down to number of usable stripes */ - ndevs -= ndevs % devs_increment; + ndevs = round_down(ndevs, devs_increment); if (ndevs < devs_increment * sub_stripes || ndevs < devs_min) { ret = -ENOSPC; goto error; } - if (devs_max && ndevs > devs_max) - ndevs = devs_max; + ndevs = min(ndevs, devs_max); + /* * the primary goal is to maximize the number of stripes, so use as many * devices as possible, even if the stripes are not maximum sized. @@ -4791,16 +4740,11 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, */ data_stripes = num_stripes / ncopies; - if (type & BTRFS_BLOCK_GROUP_RAID5) { - raid_stripe_len = find_raid56_stripe_len(ndevs - 1, - info->stripesize); + if (type & BTRFS_BLOCK_GROUP_RAID5) data_stripes = num_stripes - 1; - } - if (type & BTRFS_BLOCK_GROUP_RAID6) { - raid_stripe_len = find_raid56_stripe_len(ndevs - 2, - info->stripesize); + + if (type & BTRFS_BLOCK_GROUP_RAID6) data_stripes = num_stripes - 2; - } /* * Use the number of data stripes to figure out how big this chunk @@ -4825,8 +4769,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, stripe_size = div_u64(stripe_size, dev_stripes); /* align to BTRFS_STRIPE_LEN */ - stripe_size = div64_u64(stripe_size, raid_stripe_len); - stripe_size *= raid_stripe_len; + stripe_size = round_down(stripe_size, BTRFS_STRIPE_LEN); map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); if (!map) { @@ -4843,10 +4786,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, j * stripe_size; } } - map->sector_size = info->sectorsize; - map->stripe_len = raid_stripe_len; - map->io_align = raid_stripe_len; - map->io_width = raid_stripe_len; + map->stripe_len = BTRFS_STRIPE_LEN; + map->io_align = BTRFS_STRIPE_LEN; + map->io_width = BTRFS_STRIPE_LEN; map->type = type; map->sub_stripes = sub_stripes; @@ -4881,9 +4823,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, goto error; } - ret = btrfs_make_block_group(trans, info, 0, type, - BTRFS_FIRST_CHUNK_TREE_OBJECTID, - start, num_bytes); + ret = btrfs_make_block_group(trans, info, 0, type, start, num_bytes); if (ret) goto error_del_extent; @@ -4963,11 +4903,8 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans, ret = btrfs_update_device(trans, device); if (ret) break; - ret = btrfs_alloc_dev_extent(trans, device, - chunk_root->root_key.objectid, - BTRFS_FIRST_CHUNK_TREE_OBJECTID, - chunk_offset, dev_offset, - stripe_size); + ret = btrfs_alloc_dev_extent(trans, device, chunk_offset, + dev_offset, stripe_size); if (ret) break; } @@ -5172,7 +5109,6 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len) } unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info, - struct btrfs_mapping_tree *map_tree, u64 logical) { struct extent_map *em; @@ -5180,29 +5116,30 @@ unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info, unsigned long len = fs_info->sectorsize; em = get_chunk_map(fs_info, logical, len); - WARN_ON(IS_ERR(em)); - map = em->map_lookup; - if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) - len = map->stripe_len * nr_data_stripes(map); - free_extent_map(em); + if (!WARN_ON(IS_ERR(em))) { + map = em->map_lookup; + if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) + len = map->stripe_len * nr_data_stripes(map); + free_extent_map(em); + } return len; } -int btrfs_is_parity_mirror(struct btrfs_fs_info *fs_info, - u64 logical, u64 len, int mirror_num) +int btrfs_is_parity_mirror(struct btrfs_fs_info *fs_info, u64 logical, u64 len) { struct extent_map *em; struct map_lookup *map; int ret = 0; em = get_chunk_map(fs_info, logical, len); - WARN_ON(IS_ERR(em)); - map = em->map_lookup; - if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) - ret = 1; - free_extent_map(em); + if(!WARN_ON(IS_ERR(em))) { + map = em->map_lookup; + if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) + ret = 1; + free_extent_map(em); + } return ret; } @@ -6188,7 +6125,7 @@ static void submit_stripe_bio(struct btrfs_bio *bbio, struct bio *bio, rcu_read_unlock(); } #endif - bio->bi_bdev = dev->bdev; + bio_set_dev(bio, dev->bdev); btrfs_bio_counter_inc_noblocked(fs_info); @@ -6212,8 +6149,8 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical) } } -int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, - int mirror_num, int async_submit) +blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, + int mirror_num, int async_submit) { struct btrfs_device *dev; struct bio *first_bio = bio; @@ -6229,11 +6166,11 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, map_length = length; btrfs_bio_counter_inc_blocked(fs_info); - ret = __btrfs_map_block(fs_info, bio_op(bio), logical, + ret = __btrfs_map_block(fs_info, btrfs_op(bio), logical, &map_length, &bbio, mirror_num, 1); if (ret) { btrfs_bio_counter_dec(fs_info); - return ret; + return errno_to_blk_status(ret); } total_devs = bbio->num_stripes; @@ -6256,7 +6193,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, } btrfs_bio_counter_dec(fs_info); - return ret; + return errno_to_blk_status(ret); } if (map_length < length) { @@ -6283,7 +6220,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, dev_nr, async_submit); } btrfs_bio_counter_dec(fs_info); - return 0; + return BLK_STS_OK; } struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid, @@ -6295,9 +6232,8 @@ struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid, cur_devices = fs_info->fs_devices; while (cur_devices) { if (!fsid || - !memcmp(cur_devices->fsid, fsid, BTRFS_UUID_SIZE)) { - device = __find_device(&cur_devices->devices, - devid, uuid); + !memcmp(cur_devices->fsid, fsid, BTRFS_FSID_SIZE)) { + device = find_device(cur_devices, devid, uuid); if (device) return device; } @@ -6450,7 +6386,6 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, struct extent_map *em; u64 logical; u64 length; - u64 stripe_len; u64 devid; u8 uuid[BTRFS_UUID_SIZE]; int num_stripes; @@ -6459,7 +6394,6 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, logical = key->offset; length = btrfs_chunk_length(leaf, chunk); - stripe_len = btrfs_chunk_stripe_len(leaf, chunk); num_stripes = btrfs_chunk_num_stripes(leaf, chunk); ret = btrfs_check_chunk_valid(fs_info, leaf, chunk, logical); @@ -6498,7 +6432,6 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, map->num_stripes = num_stripes; map->io_width = btrfs_chunk_io_width(leaf, chunk); map->io_align = btrfs_chunk_io_align(leaf, chunk); - map->sector_size = btrfs_chunk_sector_size(leaf, chunk); map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk); map->type = btrfs_chunk_type(leaf, chunk); map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk); @@ -6514,6 +6447,7 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, if (!map->stripes[i].dev && !btrfs_test_opt(fs_info, DEGRADED)) { free_extent_map(em); + btrfs_report_missing_device(fs_info, devid, uuid); return -EIO; } if (!map->stripes[i].dev) { @@ -6524,8 +6458,7 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, free_extent_map(em); return -EIO; } - btrfs_warn(fs_info, "devid %llu uuid %pU is missing", - devid, uuid); + btrfs_report_missing_device(fs_info, devid, uuid); } map->stripes[i].dev->in_fs_metadata = 1; } @@ -6569,10 +6502,11 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, int ret; BUG_ON(!mutex_is_locked(&uuid_mutex)); + ASSERT(fsid); fs_devices = fs_info->fs_devices->seed; while (fs_devices) { - if (!memcmp(fs_devices->fsid, fsid, BTRFS_UUID_SIZE)) + if (!memcmp(fs_devices->fsid, fsid, BTRFS_FSID_SIZE)) return fs_devices; fs_devices = fs_devices->seed; @@ -6625,16 +6559,16 @@ static int read_one_dev(struct btrfs_fs_info *fs_info, struct btrfs_device *device; u64 devid; int ret; - u8 fs_uuid[BTRFS_UUID_SIZE]; + u8 fs_uuid[BTRFS_FSID_SIZE]; u8 dev_uuid[BTRFS_UUID_SIZE]; devid = btrfs_device_id(leaf, dev_item); read_extent_buffer(leaf, dev_uuid, btrfs_device_uuid(dev_item), BTRFS_UUID_SIZE); read_extent_buffer(leaf, fs_uuid, btrfs_device_fsid(dev_item), - BTRFS_UUID_SIZE); + BTRFS_FSID_SIZE); - if (memcmp(fs_uuid, fs_info->fsid, BTRFS_UUID_SIZE)) { + if (memcmp(fs_uuid, fs_info->fsid, BTRFS_FSID_SIZE)) { fs_devices = open_seed_devices(fs_info, fs_uuid); if (IS_ERR(fs_devices)) return PTR_ERR(fs_devices); @@ -6642,17 +6576,21 @@ static int read_one_dev(struct btrfs_fs_info *fs_info, device = btrfs_find_device(fs_info, devid, dev_uuid, fs_uuid); if (!device) { - if (!btrfs_test_opt(fs_info, DEGRADED)) + if (!btrfs_test_opt(fs_info, DEGRADED)) { + btrfs_report_missing_device(fs_info, devid, dev_uuid); return -EIO; + } device = add_missing_dev(fs_devices, devid, dev_uuid); if (!device) return -ENOMEM; - btrfs_warn(fs_info, "devid %llu uuid %pU missing", - devid, dev_uuid); + btrfs_report_missing_device(fs_info, devid, dev_uuid); } else { - if (!device->bdev && !btrfs_test_opt(fs_info, DEGRADED)) - return -EIO; + if (!device->bdev) { + btrfs_report_missing_device(fs_info, devid, dev_uuid); + if (!btrfs_test_opt(fs_info, DEGRADED)) + return -EIO; + } if(!device->bdev && !device->missing) { /* @@ -6818,6 +6756,70 @@ int btrfs_read_sys_array(struct btrfs_fs_info *fs_info) return -EIO; } +void btrfs_report_missing_device(struct btrfs_fs_info *fs_info, u64 devid, + u8 *uuid) +{ + btrfs_warn_rl(fs_info, "devid %llu uuid %pU is missing", devid, uuid); +} + +/* + * Check if all chunks in the fs are OK for read-write degraded mount + * + * Return true if all chunks meet the minimal RW mount requirements. + * Return false if any chunk doesn't meet the minimal RW mount requirements. + */ +bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info) +{ + struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; + struct extent_map *em; + u64 next_start = 0; + bool ret = true; + + read_lock(&map_tree->map_tree.lock); + em = lookup_extent_mapping(&map_tree->map_tree, 0, (u64)-1); + read_unlock(&map_tree->map_tree.lock); + /* No chunk at all? Return false anyway */ + if (!em) { + ret = false; + goto out; + } + while (em) { + struct map_lookup *map; + int missing = 0; + int max_tolerated; + int i; + + map = em->map_lookup; + max_tolerated = + btrfs_get_num_tolerated_disk_barrier_failures( + map->type); + for (i = 0; i < map->num_stripes; i++) { + struct btrfs_device *dev = map->stripes[i].dev; + + if (!dev || !dev->bdev || dev->missing || + dev->last_flush_error) + missing++; + } + if (missing > max_tolerated) { + btrfs_warn(fs_info, + "chunk %llu missing %d devices, max tolerance is %d for writeable mount", + em->start, missing, max_tolerated); + free_extent_map(em); + ret = false; + goto out; + } + next_start = extent_map_end(em); + free_extent_map(em); + + read_lock(&map_tree->map_tree.lock); + em = lookup_extent_mapping(&map_tree->map_tree, next_start, + (u64)(-1) - next_start); + read_unlock(&map_tree->map_tree.lock); + } +out: + return ret; +} + int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info) { struct btrfs_root *root = fs_info->chunk_root; diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 6f45fd60d15a92d7aea7a5711bb365a201cb09f9..6108fdfec67fb4340042030435ac959a77b03997 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -74,7 +74,7 @@ struct btrfs_device { int missing; int can_discard; int is_tgtdev_for_dev_replace; - int last_flush_error; + blk_status_t last_flush_error; int flush_bio_sent; #ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED @@ -353,7 +353,6 @@ struct map_lookup { int io_align; int io_width; u64 stripe_len; - int sector_size; int num_stripes; int sub_stripes; struct btrfs_bio_stripe stripes[]; @@ -416,8 +415,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 type); void btrfs_mapping_init(struct btrfs_mapping_tree *tree); void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree); -int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, - int mirror_num, int async_submit); +blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, + int mirror_num, int async_submit); int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, fmode_t flags, void *holder); int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, @@ -481,9 +480,8 @@ void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info, struct btrfs_device *tgtdev); void btrfs_scratch_superblocks(struct block_device *bdev, const char *device_path); int btrfs_is_parity_mirror(struct btrfs_fs_info *fs_info, - u64 logical, u64 len, int mirror_num); + u64 logical, u64 len); unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info, - struct btrfs_mapping_tree *map_tree, u64 logical); int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, @@ -543,4 +541,8 @@ struct list_head *btrfs_get_fs_uuids(void); void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info); void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info); +bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info); +void btrfs_report_missing_device(struct btrfs_fs_info *fs_info, u64 devid, + u8 *uuid); + #endif diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c new file mode 100644 index 0000000000000000000000000000000000000000..607ce47b483aad98b64189e3e566b2ec95f0ac9a --- /dev/null +++ b/fs/btrfs/zstd.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "compression.h" + +#define ZSTD_BTRFS_MAX_WINDOWLOG 17 +#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG) +#define ZSTD_BTRFS_DEFAULT_LEVEL 3 + +static ZSTD_parameters zstd_get_btrfs_parameters(size_t src_len) +{ + ZSTD_parameters params = ZSTD_getParams(ZSTD_BTRFS_DEFAULT_LEVEL, + src_len, 0); + + if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG) + params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG; + WARN_ON(src_len > ZSTD_BTRFS_MAX_INPUT); + return params; +} + +struct workspace { + void *mem; + size_t size; + char *buf; + struct list_head list; +}; + +static void zstd_free_workspace(struct list_head *ws) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + + kvfree(workspace->mem); + kfree(workspace->buf); + kfree(workspace); +} + +static struct list_head *zstd_alloc_workspace(void) +{ + ZSTD_parameters params = + zstd_get_btrfs_parameters(ZSTD_BTRFS_MAX_INPUT); + struct workspace *workspace; + + workspace = kzalloc(sizeof(*workspace), GFP_KERNEL); + if (!workspace) + return ERR_PTR(-ENOMEM); + + workspace->size = max_t(size_t, + ZSTD_CStreamWorkspaceBound(params.cParams), + ZSTD_DStreamWorkspaceBound(ZSTD_BTRFS_MAX_INPUT)); + workspace->mem = kvmalloc(workspace->size, GFP_KERNEL); + workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!workspace->mem || !workspace->buf) + goto fail; + + INIT_LIST_HEAD(&workspace->list); + + return &workspace->list; +fail: + zstd_free_workspace(&workspace->list); + return ERR_PTR(-ENOMEM); +} + +static int zstd_compress_pages(struct list_head *ws, + struct address_space *mapping, + u64 start, + struct page **pages, + unsigned long *out_pages, + unsigned long *total_in, + unsigned long *total_out) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + ZSTD_CStream *stream; + int ret = 0; + int nr_pages = 0; + struct page *in_page = NULL; /* The current page to read */ + struct page *out_page = NULL; /* The current page to write to */ + ZSTD_inBuffer in_buf = { NULL, 0, 0 }; + ZSTD_outBuffer out_buf = { NULL, 0, 0 }; + unsigned long tot_in = 0; + unsigned long tot_out = 0; + unsigned long len = *total_out; + const unsigned long nr_dest_pages = *out_pages; + unsigned long max_out = nr_dest_pages * PAGE_SIZE; + ZSTD_parameters params = zstd_get_btrfs_parameters(len); + + *out_pages = 0; + *total_out = 0; + *total_in = 0; + + /* Initialize the stream */ + stream = ZSTD_initCStream(params, len, workspace->mem, + workspace->size); + if (!stream) { + pr_warn("BTRFS: ZSTD_initCStream failed\n"); + ret = -EIO; + goto out; + } + + /* map in the first page of input data */ + in_page = find_get_page(mapping, start >> PAGE_SHIFT); + in_buf.src = kmap(in_page); + in_buf.pos = 0; + in_buf.size = min_t(size_t, len, PAGE_SIZE); + + + /* Allocate and map in the output buffer */ + out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -ENOMEM; + goto out; + } + pages[nr_pages++] = out_page; + out_buf.dst = kmap(out_page); + out_buf.pos = 0; + out_buf.size = min_t(size_t, max_out, PAGE_SIZE); + + while (1) { + size_t ret2; + + ret2 = ZSTD_compressStream(stream, &out_buf, &in_buf); + if (ZSTD_isError(ret2)) { + pr_debug("BTRFS: ZSTD_compressStream returned %d\n", + ZSTD_getErrorCode(ret2)); + ret = -EIO; + goto out; + } + + /* Check to see if we are making it bigger */ + if (tot_in + in_buf.pos > 8192 && + tot_in + in_buf.pos < + tot_out + out_buf.pos) { + ret = -E2BIG; + goto out; + } + + /* We've reached the end of our output range */ + if (out_buf.pos >= max_out) { + tot_out += out_buf.pos; + ret = -E2BIG; + goto out; + } + + /* Check if we need more output space */ + if (out_buf.pos == out_buf.size) { + tot_out += PAGE_SIZE; + max_out -= PAGE_SIZE; + kunmap(out_page); + if (nr_pages == nr_dest_pages) { + out_page = NULL; + ret = -E2BIG; + goto out; + } + out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -ENOMEM; + goto out; + } + pages[nr_pages++] = out_page; + out_buf.dst = kmap(out_page); + out_buf.pos = 0; + out_buf.size = min_t(size_t, max_out, PAGE_SIZE); + } + + /* We've reached the end of the input */ + if (in_buf.pos >= len) { + tot_in += in_buf.pos; + break; + } + + /* Check if we need more input */ + if (in_buf.pos == in_buf.size) { + tot_in += PAGE_SIZE; + kunmap(in_page); + put_page(in_page); + + start += PAGE_SIZE; + len -= PAGE_SIZE; + in_page = find_get_page(mapping, start >> PAGE_SHIFT); + in_buf.src = kmap(in_page); + in_buf.pos = 0; + in_buf.size = min_t(size_t, len, PAGE_SIZE); + } + } + while (1) { + size_t ret2; + + ret2 = ZSTD_endStream(stream, &out_buf); + if (ZSTD_isError(ret2)) { + pr_debug("BTRFS: ZSTD_endStream returned %d\n", + ZSTD_getErrorCode(ret2)); + ret = -EIO; + goto out; + } + if (ret2 == 0) { + tot_out += out_buf.pos; + break; + } + if (out_buf.pos >= max_out) { + tot_out += out_buf.pos; + ret = -E2BIG; + goto out; + } + + tot_out += PAGE_SIZE; + max_out -= PAGE_SIZE; + kunmap(out_page); + if (nr_pages == nr_dest_pages) { + out_page = NULL; + ret = -E2BIG; + goto out; + } + out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -ENOMEM; + goto out; + } + pages[nr_pages++] = out_page; + out_buf.dst = kmap(out_page); + out_buf.pos = 0; + out_buf.size = min_t(size_t, max_out, PAGE_SIZE); + } + + if (tot_out >= tot_in) { + ret = -E2BIG; + goto out; + } + + ret = 0; + *total_in = tot_in; + *total_out = tot_out; +out: + *out_pages = nr_pages; + /* Cleanup */ + if (in_page) { + kunmap(in_page); + put_page(in_page); + } + if (out_page) + kunmap(out_page); + return ret; +} + +static int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + struct page **pages_in = cb->compressed_pages; + u64 disk_start = cb->start; + struct bio *orig_bio = cb->orig_bio; + size_t srclen = cb->compressed_len; + ZSTD_DStream *stream; + int ret = 0; + unsigned long page_in_index = 0; + unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE); + unsigned long buf_start; + unsigned long total_out = 0; + ZSTD_inBuffer in_buf = { NULL, 0, 0 }; + ZSTD_outBuffer out_buf = { NULL, 0, 0 }; + + stream = ZSTD_initDStream( + ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size); + if (!stream) { + pr_debug("BTRFS: ZSTD_initDStream failed\n"); + ret = -EIO; + goto done; + } + + in_buf.src = kmap(pages_in[page_in_index]); + in_buf.pos = 0; + in_buf.size = min_t(size_t, srclen, PAGE_SIZE); + + out_buf.dst = workspace->buf; + out_buf.pos = 0; + out_buf.size = PAGE_SIZE; + + while (1) { + size_t ret2; + + ret2 = ZSTD_decompressStream(stream, &out_buf, &in_buf); + if (ZSTD_isError(ret2)) { + pr_debug("BTRFS: ZSTD_decompressStream returned %d\n", + ZSTD_getErrorCode(ret2)); + ret = -EIO; + goto done; + } + buf_start = total_out; + total_out += out_buf.pos; + out_buf.pos = 0; + + ret = btrfs_decompress_buf2page(out_buf.dst, buf_start, + total_out, disk_start, orig_bio); + if (ret == 0) + break; + + if (in_buf.pos >= srclen) + break; + + /* Check if we've hit the end of a frame */ + if (ret2 == 0) + break; + + if (in_buf.pos == in_buf.size) { + kunmap(pages_in[page_in_index++]); + if (page_in_index >= total_pages_in) { + in_buf.src = NULL; + ret = -EIO; + goto done; + } + srclen -= PAGE_SIZE; + in_buf.src = kmap(pages_in[page_in_index]); + in_buf.pos = 0; + in_buf.size = min_t(size_t, srclen, PAGE_SIZE); + } + } + ret = 0; + zero_fill_bio(orig_bio); +done: + if (in_buf.src) + kunmap(pages_in[page_in_index]); + return ret; +} + +static int zstd_decompress(struct list_head *ws, unsigned char *data_in, + struct page *dest_page, + unsigned long start_byte, + size_t srclen, size_t destlen) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + ZSTD_DStream *stream; + int ret = 0; + size_t ret2; + ZSTD_inBuffer in_buf = { NULL, 0, 0 }; + ZSTD_outBuffer out_buf = { NULL, 0, 0 }; + unsigned long total_out = 0; + unsigned long pg_offset = 0; + char *kaddr; + + stream = ZSTD_initDStream( + ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size); + if (!stream) { + pr_warn("BTRFS: ZSTD_initDStream failed\n"); + ret = -EIO; + goto finish; + } + + destlen = min_t(size_t, destlen, PAGE_SIZE); + + in_buf.src = data_in; + in_buf.pos = 0; + in_buf.size = srclen; + + out_buf.dst = workspace->buf; + out_buf.pos = 0; + out_buf.size = PAGE_SIZE; + + ret2 = 1; + while (pg_offset < destlen && in_buf.pos < in_buf.size) { + unsigned long buf_start; + unsigned long buf_offset; + unsigned long bytes; + + /* Check if the frame is over and we still need more input */ + if (ret2 == 0) { + pr_debug("BTRFS: ZSTD_decompressStream ended early\n"); + ret = -EIO; + goto finish; + } + ret2 = ZSTD_decompressStream(stream, &out_buf, &in_buf); + if (ZSTD_isError(ret2)) { + pr_debug("BTRFS: ZSTD_decompressStream returned %d\n", + ZSTD_getErrorCode(ret2)); + ret = -EIO; + goto finish; + } + + buf_start = total_out; + total_out += out_buf.pos; + out_buf.pos = 0; + + if (total_out <= start_byte) + continue; + + if (total_out > start_byte && buf_start < start_byte) + buf_offset = start_byte - buf_start; + else + buf_offset = 0; + + bytes = min_t(unsigned long, destlen - pg_offset, + out_buf.size - buf_offset); + + kaddr = kmap_atomic(dest_page); + memcpy(kaddr + pg_offset, out_buf.dst + buf_offset, bytes); + kunmap_atomic(kaddr); + + pg_offset += bytes; + } + ret = 0; +finish: + if (pg_offset < destlen) { + kaddr = kmap_atomic(dest_page); + memset(kaddr + pg_offset, 0, destlen - pg_offset); + kunmap_atomic(kaddr); + } + return ret; +} + +const struct btrfs_compress_op btrfs_zstd_compress = { + .alloc_workspace = zstd_alloc_workspace, + .free_workspace = zstd_free_workspace, + .compress_pages = zstd_compress_pages, + .decompress_bio = zstd_decompress_bio, + .decompress = zstd_decompress, +}; diff --git a/fs/buffer.c b/fs/buffer.c index 5715dac7821fe1c49a1c1ecd8f6b12192f3f1d1c..170df856bdb99715b126b2d129ff19ea95d46ad8 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1627,20 +1627,17 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len) struct pagevec pvec; pgoff_t index = block >> (PAGE_SHIFT - bd_inode->i_blkbits); pgoff_t end; - int i; + int i, count; struct buffer_head *bh; struct buffer_head *head; end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits); pagevec_init(&pvec, 0); - while (index <= end && pagevec_lookup(&pvec, bd_mapping, index, - min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) { - for (i = 0; i < pagevec_count(&pvec); i++) { + while (pagevec_lookup_range(&pvec, bd_mapping, &index, end)) { + count = pagevec_count(&pvec); + for (i = 0; i < count; i++) { struct page *page = pvec.pages[i]; - index = page->index; - if (index > end) - break; if (!page_has_buffers(page)) continue; /* @@ -1670,7 +1667,9 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len) } pagevec_release(&pvec); cond_resched(); - index++; + /* End of range already reached? */ + if (index > end || !index) + break; } } EXPORT_SYMBOL(clean_bdev_aliases); @@ -3057,7 +3056,7 @@ void guard_bio_eod(int op, struct bio *bio) struct bio_vec *bvec = &bio->bi_io_vec[bio->bi_vcnt - 1]; unsigned truncated_bytes; - maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; + maxsector = get_capacity(bio->bi_disk); if (!maxsector) return; @@ -3116,7 +3115,7 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, } bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); - bio->bi_bdev = bh->b_bdev; + bio_set_dev(bio, bh->b_bdev); bio->bi_write_hint = write_hint; bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh)); @@ -3549,10 +3548,10 @@ page_cache_seek_hole_data(struct inode *inode, loff_t offset, loff_t length, pagevec_init(&pvec, 0); do { - unsigned want, nr_pages, i; + unsigned nr_pages, i; - want = min_t(unsigned, end - index, PAGEVEC_SIZE); - nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, want); + nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping, &index, + end - 1); if (nr_pages == 0) break; @@ -3573,10 +3572,6 @@ page_cache_seek_hole_data(struct inode *inode, loff_t offset, loff_t length, lastoff < page_offset(page)) goto check_range; - /* Searching done if the page index is out of range. */ - if (page->index >= end) - goto not_found; - lock_page(page); if (likely(page->mapping == inode->i_mapping) && page_has_buffers(page)) { @@ -3589,12 +3584,6 @@ page_cache_seek_hole_data(struct inode *inode, loff_t offset, loff_t length, unlock_page(page); lastoff = page_offset(page) + PAGE_SIZE; } - - /* Searching done if fewer pages returned than wanted. */ - if (nr_pages < want) - break; - - index = pvec.pages[i - 1]->index + 1; pagevec_release(&pvec); } while (index < end); diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 3ff867f87d73ee4abbb9b6d8b94b5bd78532f305..d9f001078e08f677591495935c29c3aabad87d56 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -133,7 +133,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) goto error_unsupported; ret = -EROFS; - if (root->d_sb->s_flags & MS_RDONLY) + if (sb_rdonly(root->d_sb)) goto error_unsupported; /* determine the security of the on-disk cache as this governs diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 50836280a6f8a3a2d1a82d3c00f3f274e5844f7e..b3e3edc09d80382c72a1d2d42515ad67ea51bdb3 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -152,17 +152,10 @@ static void ceph_invalidatepage(struct page *page, unsigned int offset, ceph_invalidate_fscache_page(inode, page); + WARN_ON(!PageLocked(page)); if (!PagePrivate(page)) return; - /* - * We can get non-dirty pages here due to races between - * set_page_dirty and truncate_complete_page; just spit out a - * warning, in case we end up with accounting problems later. - */ - if (!PageDirty(page)) - pr_err("%p invalidatepage %p page not dirty\n", inode, page); - ClearPageChecked(page); dout("%p invalidatepage %p idx %lu full dirty page\n", @@ -189,7 +182,7 @@ static int ceph_releasepage(struct page *page, gfp_t g) /* * read a single page, without unlocking it. */ -static int readpage_nounlock(struct file *filp, struct page *page) +static int ceph_do_readpage(struct file *filp, struct page *page) { struct inode *inode = file_inode(filp); struct ceph_inode_info *ci = ceph_inode(inode); @@ -219,7 +212,7 @@ static int readpage_nounlock(struct file *filp, struct page *page) err = ceph_readpage_from_fscache(inode, page); if (err == 0) - goto out; + return -EINPROGRESS; dout("readpage inode %p file %p page %p index %lu\n", inode, filp, page, page->index); @@ -249,8 +242,11 @@ static int readpage_nounlock(struct file *filp, struct page *page) static int ceph_readpage(struct file *filp, struct page *page) { - int r = readpage_nounlock(filp, page); - unlock_page(page); + int r = ceph_do_readpage(filp, page); + if (r != -EINPROGRESS) + unlock_page(page); + else + r = 0; return r; } @@ -452,13 +448,9 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, if (rc == 0) goto out; - if (fsc->mount_options->rsize >= PAGE_SIZE) - max = (fsc->mount_options->rsize + PAGE_SIZE - 1) - >> PAGE_SHIFT; - - dout("readpages %p file %p nr_pages %d max %d\n", inode, - file, nr_pages, - max); + max = fsc->mount_options->rsize >> PAGE_SHIFT; + dout("readpages %p file %p nr_pages %d max %d\n", + inode, file, nr_pages, max); while (!list_empty(page_list)) { rc = start_read(inode, page_list, max); if (rc < 0) @@ -471,14 +463,22 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, return rc; } +struct ceph_writeback_ctl +{ + loff_t i_size; + u64 truncate_size; + u32 truncate_seq; + bool size_stable; + bool head_snapc; +}; + /* * Get ref for the oldest snapc for an inode with dirty data... that is, the * only snap context we are allowed to write back. */ -static struct ceph_snap_context *get_oldest_context(struct inode *inode, - loff_t *snap_size, - u64 *truncate_size, - u32 *truncate_seq) +static struct ceph_snap_context * +get_oldest_context(struct inode *inode, struct ceph_writeback_ctl *ctl, + struct ceph_snap_context *page_snapc) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_snap_context *snapc = NULL; @@ -488,30 +488,78 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode, list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, capsnap->context, capsnap->dirty_pages); - if (capsnap->dirty_pages) { - snapc = ceph_get_snap_context(capsnap->context); - if (snap_size) - *snap_size = capsnap->size; - if (truncate_size) - *truncate_size = capsnap->truncate_size; - if (truncate_seq) - *truncate_seq = capsnap->truncate_seq; - break; + if (!capsnap->dirty_pages) + continue; + + /* get i_size, truncate_{seq,size} for page_snapc? */ + if (snapc && capsnap->context != page_snapc) + continue; + + if (ctl) { + if (capsnap->writing) { + ctl->i_size = i_size_read(inode); + ctl->size_stable = false; + } else { + ctl->i_size = capsnap->size; + ctl->size_stable = true; + } + ctl->truncate_size = capsnap->truncate_size; + ctl->truncate_seq = capsnap->truncate_seq; + ctl->head_snapc = false; } + + if (snapc) + break; + + snapc = ceph_get_snap_context(capsnap->context); + if (!page_snapc || + page_snapc == snapc || + page_snapc->seq > snapc->seq) + break; } if (!snapc && ci->i_wrbuffer_ref_head) { snapc = ceph_get_snap_context(ci->i_head_snapc); dout(" head snapc %p has %d dirty pages\n", snapc, ci->i_wrbuffer_ref_head); - if (truncate_size) - *truncate_size = ci->i_truncate_size; - if (truncate_seq) - *truncate_seq = ci->i_truncate_seq; + if (ctl) { + ctl->i_size = i_size_read(inode); + ctl->truncate_size = ci->i_truncate_size; + ctl->truncate_seq = ci->i_truncate_seq; + ctl->size_stable = false; + ctl->head_snapc = true; + } } spin_unlock(&ci->i_ceph_lock); return snapc; } +static u64 get_writepages_data_length(struct inode *inode, + struct page *page, u64 start) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_snap_context *snapc = page_snap_context(page); + struct ceph_cap_snap *capsnap = NULL; + u64 end = i_size_read(inode); + + if (snapc != ci->i_head_snapc) { + bool found = false; + spin_lock(&ci->i_ceph_lock); + list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { + if (capsnap->context == snapc) { + if (!capsnap->writing) + end = capsnap->size; + found = true; + break; + } + } + spin_unlock(&ci->i_ceph_lock); + WARN_ON(!found); + } + if (end > page_offset(page) + PAGE_SIZE) + end = page_offset(page) + PAGE_SIZE; + return end > start ? end - start : 0; +} + /* * Write a single page, but leave the page locked. * @@ -523,30 +571,25 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) struct inode *inode; struct ceph_inode_info *ci; struct ceph_fs_client *fsc; - struct ceph_osd_client *osdc; struct ceph_snap_context *snapc, *oldest; loff_t page_off = page_offset(page); - loff_t snap_size = -1; long writeback_stat; - u64 truncate_size; - u32 truncate_seq; int err, len = PAGE_SIZE; + struct ceph_writeback_ctl ceph_wbc; dout("writepage %p idx %lu\n", page, page->index); inode = page->mapping->host; ci = ceph_inode(inode); fsc = ceph_inode_to_client(inode); - osdc = &fsc->client->osdc; /* verify this is a writeable snap context */ snapc = page_snap_context(page); - if (snapc == NULL) { + if (!snapc) { dout("writepage %p page %p not dirty?\n", inode, page); return 0; } - oldest = get_oldest_context(inode, &snap_size, - &truncate_size, &truncate_seq); + oldest = get_oldest_context(inode, &ceph_wbc, snapc); if (snapc->seq > oldest->seq) { dout("writepage %p page %p snapc %p not writeable - noop\n", inode, page, snapc); @@ -558,20 +601,18 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) } ceph_put_snap_context(oldest); - if (snap_size == -1) - snap_size = i_size_read(inode); - /* is this a partial page at end of file? */ - if (page_off >= snap_size) { - dout("%p page eof %llu\n", page, snap_size); + if (page_off >= ceph_wbc.i_size) { + dout("%p page eof %llu\n", page, ceph_wbc.i_size); + page->mapping->a_ops->invalidatepage(page, 0, PAGE_SIZE); return 0; } - if (snap_size < page_off + len) - len = snap_size - page_off; + if (ceph_wbc.i_size < page_off + len) + len = ceph_wbc.i_size - page_off; - dout("writepage %p page %p index %lu on %llu~%u snapc %p\n", - inode, page, page->index, page_off, len, snapc); + dout("writepage %p page %p index %lu on %llu~%u snapc %p seq %lld\n", + inode, page, page->index, page_off, len, snapc, snapc->seq); writeback_stat = atomic_long_inc_return(&fsc->writeback_count); if (writeback_stat > @@ -579,10 +620,10 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) set_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC); set_page_writeback(page); - err = ceph_osdc_writepages(osdc, ceph_vino(inode), - &ci->i_layout, snapc, - page_off, len, - truncate_seq, truncate_size, + err = ceph_osdc_writepages(&fsc->client->osdc, ceph_vino(inode), + &ci->i_layout, snapc, page_off, len, + ceph_wbc.truncate_seq, + ceph_wbc.truncate_size, &inode->i_mtime, &page, 1); if (err < 0) { struct writeback_control tmp_wbc; @@ -743,31 +784,17 @@ static int ceph_writepages_start(struct address_space *mapping, struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_fs_client *fsc = ceph_inode_to_client(inode); struct ceph_vino vino = ceph_vino(inode); - pgoff_t index, start, end; - int range_whole = 0; - int should_loop = 1; - pgoff_t max_pages = 0, max_pages_ever = 0; + pgoff_t index, start_index, end = -1; struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc; struct pagevec pvec; - int done = 0; int rc = 0; unsigned int wsize = i_blocksize(inode); struct ceph_osd_request *req = NULL; - int do_sync = 0; - loff_t snap_size, i_size; - u64 truncate_size; - u32 truncate_seq; + struct ceph_writeback_ctl ceph_wbc; + bool should_loop, range_whole = false; + bool stop, done = false; - /* - * Include a 'sync' in the OSD request if this is a data - * integrity write (e.g., O_SYNC write or fsync()), or if our - * cap is being revoked. - */ - if ((wbc->sync_mode == WB_SYNC_ALL) || - ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER)) - do_sync = 1; - dout("writepages_start %p dosync=%d (mode=%s)\n", - inode, do_sync, + dout("writepages_start %p (mode=%s)\n", inode, wbc->sync_mode == WB_SYNC_NONE ? "NONE" : (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD")); @@ -780,35 +807,17 @@ static int ceph_writepages_start(struct address_space *mapping, mapping_set_error(mapping, -EIO); return -EIO; /* we're in a forced umount, don't write! */ } - if (fsc->mount_options->wsize && fsc->mount_options->wsize < wsize) + if (fsc->mount_options->wsize < wsize) wsize = fsc->mount_options->wsize; - if (wsize < PAGE_SIZE) - wsize = PAGE_SIZE; - max_pages_ever = wsize >> PAGE_SHIFT; pagevec_init(&pvec, 0); - /* where to start/end? */ - if (wbc->range_cyclic) { - start = mapping->writeback_index; /* Start from prev offset */ - end = -1; - dout(" cyclic, start at %lu\n", start); - } else { - start = wbc->range_start >> PAGE_SHIFT; - end = wbc->range_end >> PAGE_SHIFT; - if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) - range_whole = 1; - should_loop = 0; - dout(" not cyclic, %lu to %lu\n", start, end); - } - index = start; + start_index = wbc->range_cyclic ? mapping->writeback_index : 0; + index = start_index; retry: /* find oldest snap context with dirty data */ - ceph_put_snap_context(snapc); - snap_size = -1; - snapc = get_oldest_context(inode, &snap_size, - &truncate_size, &truncate_seq); + snapc = get_oldest_context(inode, &ceph_wbc, NULL); if (!snapc) { /* hmm, why does writepages get called when there is no dirty data? */ @@ -818,40 +827,56 @@ static int ceph_writepages_start(struct address_space *mapping, dout(" oldest snapc is %p seq %lld (%d snaps)\n", snapc, snapc->seq, snapc->num_snaps); - i_size = i_size_read(inode); - - if (last_snapc && snapc != last_snapc) { - /* if we switched to a newer snapc, restart our scan at the - * start of the original file range. */ - dout(" snapc differs from last pass, restarting at %lu\n", - index); - index = start; + should_loop = false; + if (ceph_wbc.head_snapc && snapc != last_snapc) { + /* where to start/end? */ + if (wbc->range_cyclic) { + index = start_index; + end = -1; + if (index > 0) + should_loop = true; + dout(" cyclic, start at %lu\n", index); + } else { + index = wbc->range_start >> PAGE_SHIFT; + end = wbc->range_end >> PAGE_SHIFT; + if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) + range_whole = true; + dout(" not cyclic, %lu to %lu\n", index, end); + } + } else if (!ceph_wbc.head_snapc) { + /* Do not respect wbc->range_{start,end}. Dirty pages + * in that range can be associated with newer snapc. + * They are not writeable until we write all dirty pages + * associated with 'snapc' get written */ + if (index > 0 || wbc->sync_mode != WB_SYNC_NONE) + should_loop = true; + dout(" non-head snapc, range whole\n"); } + + ceph_put_snap_context(last_snapc); last_snapc = snapc; - while (!done && index <= end) { - unsigned i; - int first; - pgoff_t strip_unit_end = 0; + stop = false; + while (!stop && index <= end) { int num_ops = 0, op_idx; - int pvec_pages, locked_pages = 0; + unsigned i, pvec_pages, max_pages, locked_pages = 0; struct page **pages = NULL, **data_pages; mempool_t *pool = NULL; /* Becomes non-null if mempool used */ struct page *page; - int want; + pgoff_t strip_unit_end = 0; u64 offset = 0, len = 0; - max_pages = max_pages_ever; + max_pages = wsize >> PAGE_SHIFT; get_more_pages: - first = -1; - want = min(end - index, - min((pgoff_t)PAGEVEC_SIZE, - max_pages - (pgoff_t)locked_pages) - 1) - + 1; + pvec_pages = min_t(unsigned, PAGEVEC_SIZE, + max_pages - locked_pages); + if (end - index < (u64)(pvec_pages - 1)) + pvec_pages = (unsigned)(end - index) + 1; + pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY, - want); + pvec_pages); dout("pagevec_lookup_tag got %d\n", pvec_pages); if (!pvec_pages && !locked_pages) break; @@ -868,11 +893,15 @@ static int ceph_writepages_start(struct address_space *mapping, unlikely(page->mapping != mapping)) { dout("!dirty or !mapping %p\n", page); unlock_page(page); - break; + continue; } - if (!wbc->range_cyclic && page->index > end) { + if (page->index > end) { dout("end of range %p\n", page); - done = 1; + /* can't be range_cyclic (1st pass) because + * end == -1 in that case. */ + stop = true; + if (ceph_wbc.head_snapc) + done = true; unlock_page(page); break; } @@ -881,39 +910,37 @@ static int ceph_writepages_start(struct address_space *mapping, unlock_page(page); break; } - if (wbc->sync_mode != WB_SYNC_NONE) { - dout("waiting on writeback %p\n", page); - wait_on_page_writeback(page); - } - if (page_offset(page) >= - (snap_size == -1 ? i_size : snap_size)) { - dout("%p page eof %llu\n", page, - (snap_size == -1 ? i_size : snap_size)); - done = 1; + if (page_offset(page) >= ceph_wbc.i_size) { + dout("%p page eof %llu\n", + page, ceph_wbc.i_size); + /* not done if range_cyclic */ + stop = true; unlock_page(page); break; } if (PageWriteback(page)) { - dout("%p under writeback\n", page); - unlock_page(page); - break; + if (wbc->sync_mode == WB_SYNC_NONE) { + dout("%p under writeback\n", page); + unlock_page(page); + continue; + } + dout("waiting on writeback %p\n", page); + wait_on_page_writeback(page); } /* only if matching snap context */ pgsnapc = page_snap_context(page); - if (pgsnapc->seq > snapc->seq) { - dout("page snapc %p %lld > oldest %p %lld\n", + if (pgsnapc != snapc) { + dout("page snapc %p %lld != oldest %p %lld\n", pgsnapc, pgsnapc->seq, snapc, snapc->seq); unlock_page(page); - if (!locked_pages) - continue; /* keep looking for snap */ - break; + continue; } if (!clear_page_dirty_for_io(page)) { dout("%p !clear_page_dirty_for_io\n", page); unlock_page(page); - break; + continue; } /* @@ -939,7 +966,7 @@ static int ceph_writepages_start(struct address_space *mapping, break; } - num_ops = 1 + do_sync; + num_ops = 1; strip_unit_end = page->index + ((len - 1) >> PAGE_SHIFT); @@ -969,8 +996,6 @@ static int ceph_writepages_start(struct address_space *mapping, } /* note position of first page in pvec */ - if (first < 0) - first = i; dout("%p will write page %p idx %lu\n", inode, page, page->index); @@ -981,8 +1006,10 @@ static int ceph_writepages_start(struct address_space *mapping, BLK_RW_ASYNC); } - pages[locked_pages] = page; - locked_pages++; + + pages[locked_pages++] = page; + pvec.pages[i] = NULL; + len += PAGE_SIZE; } @@ -990,23 +1017,23 @@ static int ceph_writepages_start(struct address_space *mapping, if (!locked_pages) goto release_pvec_pages; if (i) { - int j; - BUG_ON(!locked_pages || first < 0); + unsigned j, n = 0; + /* shift unused page to beginning of pvec */ + for (j = 0; j < pvec_pages; j++) { + if (!pvec.pages[j]) + continue; + if (n < j) + pvec.pages[n] = pvec.pages[j]; + n++; + } + pvec.nr = n; if (pvec_pages && i == pvec_pages && locked_pages < max_pages) { dout("reached end pvec, trying for more\n"); - pagevec_reinit(&pvec); + pagevec_release(&pvec); goto get_more_pages; } - - /* shift unused pages over in the pvec... we - * will need to release them below. */ - for (j = i; j < pvec_pages; j++) { - dout(" pvec leftover page %p\n", pvec.pages[j]); - pvec.pages[j-i+first] = pvec.pages[j]; - } - pvec.nr -= i-first; } new_request: @@ -1016,10 +1043,9 @@ static int ceph_writepages_start(struct address_space *mapping, req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, vino, offset, &len, 0, num_ops, - CEPH_OSD_OP_WRITE, - CEPH_OSD_FLAG_WRITE, - snapc, truncate_seq, - truncate_size, false); + CEPH_OSD_OP_WRITE, CEPH_OSD_FLAG_WRITE, + snapc, ceph_wbc.truncate_seq, + ceph_wbc.truncate_size, false); if (IS_ERR(req)) { req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, vino, @@ -1028,8 +1054,8 @@ static int ceph_writepages_start(struct address_space *mapping, CEPH_OSD_SLAB_OPS), CEPH_OSD_OP_WRITE, CEPH_OSD_FLAG_WRITE, - snapc, truncate_seq, - truncate_size, true); + snapc, ceph_wbc.truncate_seq, + ceph_wbc.truncate_size, true); BUG_ON(IS_ERR(req)); } BUG_ON(len < page_offset(pages[locked_pages - 1]) + @@ -1045,7 +1071,7 @@ static int ceph_writepages_start(struct address_space *mapping, for (i = 0; i < locked_pages; i++) { u64 cur_offset = page_offset(pages[i]); if (offset + len != cur_offset) { - if (op_idx + do_sync + 1 == req->r_num_ops) + if (op_idx + 1 == req->r_num_ops) break; osd_req_op_extent_dup_last(req, op_idx, cur_offset - offset); @@ -1066,14 +1092,15 @@ static int ceph_writepages_start(struct address_space *mapping, len += PAGE_SIZE; } - if (snap_size != -1) { - len = min(len, snap_size - offset); + if (ceph_wbc.size_stable) { + len = min(len, ceph_wbc.i_size - offset); } else if (i == locked_pages) { /* writepages_finish() clears writeback pages * according to the data length, so make sure * data length covers all locked pages */ u64 min_len = len + 1 - PAGE_SIZE; - len = min(len, (u64)i_size_read(inode) - offset); + len = get_writepages_data_length(inode, pages[i - 1], + offset); len = max(len, min_len); } dout("writepages got pages at %llu~%llu\n", offset, len); @@ -1082,17 +1109,12 @@ static int ceph_writepages_start(struct address_space *mapping, 0, !!pool, false); osd_req_op_extent_update(req, op_idx, len); - if (do_sync) { - op_idx++; - osd_req_op_init(req, op_idx, CEPH_OSD_OP_STARTSYNC, 0); - } BUG_ON(op_idx + 1 != req->r_num_ops); pool = NULL; if (i < locked_pages) { BUG_ON(num_ops <= req->r_num_ops); num_ops -= req->r_num_ops; - num_ops += do_sync; locked_pages -= i; /* allocate new pages array for next request */ @@ -1124,22 +1146,50 @@ static int ceph_writepages_start(struct address_space *mapping, if (pages) goto new_request; - if (wbc->nr_to_write <= 0) - done = 1; + /* + * We stop writing back only if we are not doing + * integrity sync. In case of integrity sync we have to + * keep going until we have written all the pages + * we tagged for writeback prior to entering this loop. + */ + if (wbc->nr_to_write <= 0 && wbc->sync_mode == WB_SYNC_NONE) + done = stop = true; release_pvec_pages: dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr, pvec.nr ? pvec.pages[0] : NULL); pagevec_release(&pvec); - - if (locked_pages && !done) - goto retry; } if (should_loop && !done) { /* more to do; loop back to beginning of file */ dout("writepages looping back to beginning of file\n"); - should_loop = 0; + end = start_index - 1; /* OK even when start_index == 0 */ + + /* to write dirty pages associated with next snapc, + * we need to wait until current writes complete */ + if (wbc->sync_mode != WB_SYNC_NONE && + start_index == 0 && /* all dirty pages were checked */ + !ceph_wbc.head_snapc) { + struct page *page; + unsigned i, nr; + index = 0; + while ((index <= end) && + (nr = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_WRITEBACK, + PAGEVEC_SIZE))) { + for (i = 0; i < nr; i++) { + page = pvec.pages[i]; + if (page_snap_context(page) != snapc) + continue; + wait_on_page_writeback(page); + } + pagevec_release(&pvec); + cond_resched(); + } + } + + start_index = 0; index = 0; goto retry; } @@ -1149,8 +1199,8 @@ static int ceph_writepages_start(struct address_space *mapping, out: ceph_osdc_put_request(req); - ceph_put_snap_context(snapc); - dout("writepages done, rc = %d\n", rc); + ceph_put_snap_context(last_snapc); + dout("writepages dend - startone, rc = %d\n", rc); return rc; } @@ -1162,8 +1212,7 @@ static int ceph_writepages_start(struct address_space *mapping, static int context_is_writeable_or_written(struct inode *inode, struct ceph_snap_context *snapc) { - struct ceph_snap_context *oldest = get_oldest_context(inode, NULL, - NULL, NULL); + struct ceph_snap_context *oldest = get_oldest_context(inode, NULL, NULL); int ret = !oldest || snapc->seq <= oldest->seq; ceph_put_snap_context(oldest); @@ -1208,8 +1257,7 @@ static int ceph_update_writeable_page(struct file *file, * this page is already dirty in another (older) snap * context! is it writeable now? */ - oldest = get_oldest_context(inode, NULL, NULL, NULL); - + oldest = get_oldest_context(inode, NULL, NULL); if (snapc->seq > oldest->seq) { ceph_put_snap_context(oldest); dout(" page %p snapc %p not current or oldest\n", @@ -1237,7 +1285,7 @@ static int ceph_update_writeable_page(struct file *file, goto retry_locked; r = writepage_nounlock(page, NULL); if (r < 0) - goto fail_nosnap; + goto fail_unlock; goto retry_locked; } @@ -1265,11 +1313,14 @@ static int ceph_update_writeable_page(struct file *file, } /* we need to read it. */ - r = readpage_nounlock(file, page); - if (r < 0) - goto fail_nosnap; + r = ceph_do_readpage(file, page); + if (r < 0) { + if (r == -EINPROGRESS) + return -EAGAIN; + goto fail_unlock; + } goto retry_locked; -fail_nosnap: +fail_unlock: unlock_page(page); return r; } diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c index fd1172823f8621b6701e91172a0f0f83c2bb3f5c..a3ab265d3215ae20bfab1d97fa89756512e6161e 100644 --- a/fs/ceph/cache.c +++ b/fs/ceph/cache.c @@ -194,36 +194,6 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux( return FSCACHE_CHECKAUX_OKAY; } -static void ceph_fscache_inode_now_uncached(void* cookie_netfs_data) -{ - struct ceph_inode_info* ci = cookie_netfs_data; - struct pagevec pvec; - pgoff_t first; - int loop, nr_pages; - - pagevec_init(&pvec, 0); - first = 0; - - dout("ceph inode 0x%p now uncached", ci); - - while (1) { - nr_pages = pagevec_lookup(&pvec, ci->vfs_inode.i_mapping, first, - PAGEVEC_SIZE - pagevec_count(&pvec)); - - if (!nr_pages) - break; - - for (loop = 0; loop < nr_pages; loop++) - ClearPageFsCache(pvec.pages[loop]); - - first = pvec.pages[nr_pages - 1]->index + 1; - - pvec.nr = nr_pages; - pagevec_release(&pvec); - cond_resched(); - } -} - static const struct fscache_cookie_def ceph_fscache_inode_object_def = { .name = "CEPH.inode", .type = FSCACHE_COOKIE_TYPE_DATAFILE, @@ -231,7 +201,6 @@ static const struct fscache_cookie_def ceph_fscache_inode_object_def = { .get_attr = ceph_fscache_inode_get_attr, .get_aux = ceph_fscache_inode_get_aux, .check_aux = ceph_fscache_inode_check_aux, - .now_uncached = ceph_fscache_inode_now_uncached, }; void ceph_fscache_register_inode_cookie(struct inode *inode) @@ -240,7 +209,7 @@ void ceph_fscache_register_inode_cookie(struct inode *inode) struct ceph_fs_client *fsc = ceph_inode_to_client(inode); /* No caching for filesystem */ - if (fsc->fscache == NULL) + if (!fsc->fscache) return; /* Only cache for regular files that are read only */ @@ -297,13 +266,7 @@ void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp) } } -static void ceph_vfs_readpage_complete(struct page *page, void *data, int error) -{ - if (!error) - SetPageUptodate(page); -} - -static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, int error) +static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error) { if (!error) SetPageUptodate(page); @@ -331,7 +294,7 @@ int ceph_readpage_from_fscache(struct inode *inode, struct page *page) return -ENOBUFS; ret = fscache_read_or_alloc_page(ci->fscache, page, - ceph_vfs_readpage_complete, NULL, + ceph_readpage_from_fscache_complete, NULL, GFP_KERNEL); switch (ret) { @@ -360,7 +323,7 @@ int ceph_readpages_from_fscache(struct inode *inode, return -ENOBUFS; ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages, - ceph_vfs_readpage_complete_unlock, + ceph_readpage_from_fscache_complete, NULL, mapping_gfp_mask(mapping)); switch (ret) { diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7007ae2a5ad2ec4e506ca8216c2fd5253ee35bca..157fe59fbabe5c9f5608d4e186154c8372643d6f 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -490,13 +490,14 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap, } /* - * if we are newly issued FILE_SHARED, mark dir not complete; we - * don't know what happened to this directory while we didn't - * have the cap. + * If FILE_SHARED is newly issued, mark dir not complete. We don't + * know what happened to this directory while we didn't have the cap. + * If FILE_SHARED is being revoked, also mark dir not complete. It + * stops on-going cached readdir. */ - if ((issued & CEPH_CAP_FILE_SHARED) && - (had & CEPH_CAP_FILE_SHARED) == 0) { - ci->i_shared_gen++; + if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) { + if (issued & CEPH_CAP_FILE_SHARED) + ci->i_shared_gen++; if (S_ISDIR(ci->vfs_inode.i_mode)) { dout(" marking %p NOT complete\n", &ci->vfs_inode); __ceph_dir_clear_complete(ci); @@ -611,7 +612,7 @@ void ceph_add_cap(struct inode *inode, } if (flags & CEPH_CAP_FLAG_AUTH) { - if (ci->i_auth_cap == NULL || + if (!ci->i_auth_cap || ceph_seq_cmp(ci->i_auth_cap->mseq, mseq) < 0) { ci->i_auth_cap = cap; cap->mds_wanted = wanted; @@ -728,7 +729,7 @@ static void __touch_cap(struct ceph_cap *cap) struct ceph_mds_session *s = cap->session; spin_lock(&s->s_cap_lock); - if (s->s_cap_iterator == NULL) { + if (!s->s_cap_iterator) { dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap, s->s_mds); list_move_tail(&cap->session_caps, &s->s_caps); @@ -1248,7 +1249,10 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, arg.mode = inode->i_mode; arg.inline_data = ci->i_inline_version != CEPH_INLINE_NONE; - arg.flags = 0; + if (list_empty(&ci->i_cap_snaps)) + arg.flags = CEPH_CLIENT_CAPS_NO_CAPSNAP; + else + arg.flags = CEPH_CLIENT_CAPS_PENDING_CAPSNAP; if (sync) arg.flags |= CEPH_CLIENT_CAPS_SYNC; @@ -1454,13 +1458,19 @@ void ceph_flush_snaps(struct ceph_inode_info *ci, goto retry; } + // make sure flushsnap messages are sent in proper order. + if (ci->i_ceph_flags & CEPH_I_KICK_FLUSH) { + __kick_flushing_caps(mdsc, session, ci, 0); + ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH; + } + __ceph_flush_snaps(ci, session); out: spin_unlock(&ci->i_ceph_lock); if (psession) { *psession = session; - } else { + } else if (session) { mutex_unlock(&session->s_mutex); ceph_put_mds_session(session); } @@ -1901,11 +1911,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, (ci->i_ceph_flags & (CEPH_I_KICK_FLUSH | CEPH_I_FLUSH_SNAPS))) { if (ci->i_ceph_flags & CEPH_I_KICK_FLUSH) { - spin_lock(&mdsc->cap_dirty_lock); - oldest_flush_tid = __get_oldest_flush_tid(mdsc); - spin_unlock(&mdsc->cap_dirty_lock); - __kick_flushing_caps(mdsc, session, ci, - oldest_flush_tid); + __kick_flushing_caps(mdsc, session, ci, 0); ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH; } if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS) @@ -2110,7 +2116,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) dout("fsync %p%s\n", inode, datasync ? " datasync" : ""); - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(file, start, end); if (ret < 0) goto out; @@ -3422,7 +3428,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, tcap = __get_cap_for_mds(ci, target); if (tcap) { /* already have caps from the target */ - if (tcap->cap_id != t_cap_id || + if (tcap->cap_id == t_cap_id && ceph_seq_cmp(tcap->seq, t_seq) < 0) { dout(" updating import cap %p mds%d\n", tcap, target); tcap->cap_id = t_cap_id; diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 4e2d112c982f4b12852ba7b8bad58327783bc3db..d635496ea1899dc06195812d2f0644d33ecff6c6 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -24,7 +24,7 @@ static int mdsmap_show(struct seq_file *s, void *p) struct ceph_fs_client *fsc = s->private; struct ceph_mdsmap *mdsmap; - if (fsc->mdsc == NULL || fsc->mdsc->mdsmap == NULL) + if (!fsc->mdsc || !fsc->mdsc->mdsmap) return 0; mdsmap = fsc->mdsc->mdsmap; seq_printf(s, "epoch %d\n", mdsmap->m_epoch); diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index ef7240ace5767a0439f9eab941725b900281e844..019c2036d36f3e15b86a4da732b5cfd862e4670a 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -377,8 +377,10 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) } /* hints to request -> mds selection code */ req->r_direct_mode = USE_AUTH_MDS; - req->r_direct_hash = ceph_frag_value(frag); - __set_bit(CEPH_MDS_R_DIRECT_IS_HASH, &req->r_req_flags); + if (op == CEPH_MDS_OP_READDIR) { + req->r_direct_hash = ceph_frag_value(frag); + __set_bit(CEPH_MDS_R_DIRECT_IS_HASH, &req->r_req_flags); + } if (fi->last_name) { req->r_path2 = kstrdup(fi->last_name, GFP_KERNEL); if (!req->r_path2) { diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 3d48c415f3cb197505b70686031a175c7e2ade1b..65a6fa12c857319900fa45b323947ca054998a16 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -175,7 +175,7 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode) dout("init_file %p %p 0%o (regular)\n", inode, file, inode->i_mode); cf = kmem_cache_zalloc(ceph_file_cachep, GFP_KERNEL); - if (cf == NULL) { + if (!cf) { ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */ return -ENOMEM; } @@ -562,8 +562,7 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to, ssize_t ret; size_t len = iov_iter_count(to); - dout("sync_read on file %p %llu~%u %s\n", file, off, - (unsigned)len, + dout("sync_read on file %p %llu~%u %s\n", file, off, (unsigned)len, (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); if (!len) @@ -788,7 +787,7 @@ static void ceph_aio_retry_work(struct work_struct *work) goto out; } - req->r_flags = CEPH_OSD_FLAG_ORDERSNAP | CEPH_OSD_FLAG_WRITE; + req->r_flags = /* CEPH_OSD_FLAG_ORDERSNAP | */ CEPH_OSD_FLAG_WRITE; ceph_oloc_copy(&req->r_base_oloc, &orig_req->r_base_oloc); ceph_oid_copy(&req->r_base_oid, &orig_req->r_base_oid); @@ -800,7 +799,6 @@ static void ceph_aio_retry_work(struct work_struct *work) } req->r_ops[0] = orig_req->r_ops[0]; - osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); req->r_mtime = aio_req->mtime; req->r_data_offset = req->r_ops[0].extent.offset; @@ -847,8 +845,9 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP) return -EROFS; - dout("sync_direct_read_write (%s) on file %p %lld~%u\n", - (write ? "write" : "read"), file, pos, (unsigned)count); + dout("sync_direct_%s on file %p %lld~%u snapc %p seq %lld\n", + (write ? "write" : "read"), file, pos, (unsigned)count, + snapc, snapc->seq); ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + count); if (ret < 0) @@ -861,7 +860,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, if (ret2 < 0) dout("invalidate_inode_pages2_range returned %d\n", ret2); - flags = CEPH_OSD_FLAG_ORDERSNAP | CEPH_OSD_FLAG_WRITE; + flags = /* CEPH_OSD_FLAG_ORDERSNAP | */ CEPH_OSD_FLAG_WRITE; } else { flags = CEPH_OSD_FLAG_READ; } @@ -874,8 +873,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, vino = ceph_vino(inode); req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, vino, pos, &size, 0, - /*include a 'startsync' command*/ - write ? 2 : 1, + 1, write ? CEPH_OSD_OP_WRITE : CEPH_OSD_OP_READ, flags, snapc, @@ -887,6 +885,11 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, break; } + if (write) + size = min_t(u64, size, fsc->mount_options->wsize); + else + size = min_t(u64, size, fsc->mount_options->rsize); + len = size; pages = dio_get_pages_alloc(iter, len, &start, &num_pages); if (IS_ERR(pages)) { @@ -922,7 +925,6 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, truncate_inode_pages_range(inode->i_mapping, pos, (pos+len) | (PAGE_SIZE - 1)); - osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); req->r_mtime = mtime; } @@ -1048,7 +1050,8 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) return -EROFS; - dout("sync_write on file %p %lld~%u\n", file, pos, (unsigned)count); + dout("sync_write on file %p %lld~%u snapc %p seq %lld\n", + file, pos, (unsigned)count, snapc, snapc->seq); ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + count); if (ret < 0) @@ -1060,7 +1063,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, if (ret < 0) dout("invalidate_inode_pages2_range returned %d\n", ret); - flags = CEPH_OSD_FLAG_ORDERSNAP | CEPH_OSD_FLAG_WRITE; + flags = /* CEPH_OSD_FLAG_ORDERSNAP | */ CEPH_OSD_FLAG_WRITE; while ((len = iov_iter_count(from)) > 0) { size_t left; @@ -1307,6 +1310,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) if (!prealloc_cf) return -ENOMEM; +retry_snap: inode_lock(inode); /* We can write back this queue in page reclaim */ @@ -1338,7 +1342,6 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out; } -retry_snap: /* FIXME: not complete since it doesn't account for being at quota */ if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL)) { err = -ENOSPC; @@ -1387,14 +1390,6 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) &prealloc_cf); else written = ceph_sync_write(iocb, &data, pos, snapc); - if (written == -EOLDSNAPC) { - dout("aio_write %p %llx.%llx %llu~%u" - "got EOLDSNAPC, retrying\n", - inode, ceph_vinop(inode), - pos, (unsigned)count); - inode_lock(inode); - goto retry_snap; - } if (written > 0) iov_iter_advance(from, written); ceph_put_snap_context(snapc); @@ -1428,10 +1423,15 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) ceph_cap_string(got)); ceph_put_cap_refs(ci, got); + if (written == -EOLDSNAPC) { + dout("aio_write %p %llx.%llx %llu~%u" "got EOLDSNAPC, retrying\n", + inode, ceph_vinop(inode), pos, (unsigned)count); + goto retry_snap; + } + if (written >= 0) { if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_NEARFULL)) iocb->ki_flags |= IOCB_DSYNC; - written = generic_write_sync(iocb, written); } @@ -1481,13 +1481,13 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence) offset += file->f_pos; break; case SEEK_DATA: - if (offset >= i_size) { + if (offset < 0 || offset >= i_size) { ret = -ENXIO; goto out; } break; case SEEK_HOLE: - if (offset >= i_size) { + if (offset < 0 || offset >= i_size) { ret = -ENXIO; goto out; } diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 220dfd87cbfaa139d2d8f959d353bd70f032a82d..373dab5173cac540d27eb3b6b889569cb69415db 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -52,7 +52,7 @@ struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino) ino_t t = ceph_vino_to_ino(vino); inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino); - if (inode == NULL) + if (!inode) return ERR_PTR(-ENOMEM); if (inode->i_state & I_NEW) { dout("get_inode created new inode %p %llx.%llx ino %llx\n", @@ -133,12 +133,9 @@ static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci, } frag = kmalloc(sizeof(*frag), GFP_NOFS); - if (!frag) { - pr_err("__get_or_create_frag ENOMEM on %p %llx.%llx " - "frag %x\n", &ci->vfs_inode, - ceph_vinop(&ci->vfs_inode), f); + if (!frag) return ERR_PTR(-ENOMEM); - } + frag->frag = f; frag->split_by = 0; frag->mds = -1; @@ -1070,7 +1067,6 @@ static void update_dentry_lease(struct dentry *dentry, spin_unlock(&dentry->d_lock); if (old_lease_session) ceph_put_mds_session(old_lease_session); - return; } /* @@ -1177,7 +1173,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) dn = d_alloc(parent, &dname); dout("d_alloc %p '%.*s' = %p\n", parent, dname.len, dname.name, dn); - if (dn == NULL) { + if (!dn) { dput(parent); err = -ENOMEM; goto done; @@ -1477,7 +1473,6 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, struct dentry *dn; struct inode *in; int err = 0, skipped = 0, ret, i; - struct inode *snapdir = NULL; struct ceph_mds_request_head *rhead = req->r_request->front.iov_base; u32 frag = le32_to_cpu(rhead->args.readdir.frag); u32 last_hash = 0; @@ -1510,8 +1505,6 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, } if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) { - snapdir = ceph_get_snapdir(d_inode(parent)); - parent = d_find_alias(snapdir); dout("readdir_prepopulate %d items under SNAPDIR dn %p\n", rinfo->dir_nr, parent); } else { @@ -1519,15 +1512,18 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, rinfo->dir_nr, parent); if (rinfo->dir_dir) ceph_fill_dirfrag(d_inode(parent), rinfo->dir_dir); - } - if (ceph_frag_is_leftmost(frag) && req->r_readdir_offset == 2 && - !(rinfo->hash_order && last_hash)) { - /* note dir version at start of readdir so we can tell - * if any dentries get dropped */ - req->r_dir_release_cnt = atomic64_read(&ci->i_release_count); - req->r_dir_ordered_cnt = atomic64_read(&ci->i_ordered_count); - req->r_readdir_cache_idx = 0; + if (ceph_frag_is_leftmost(frag) && + req->r_readdir_offset == 2 && + !(rinfo->hash_order && last_hash)) { + /* note dir version at start of readdir so we can + * tell if any dentries get dropped */ + req->r_dir_release_cnt = + atomic64_read(&ci->i_release_count); + req->r_dir_ordered_cnt = + atomic64_read(&ci->i_ordered_count); + req->r_readdir_cache_idx = 0; + } } cache_ctl.index = req->r_readdir_cache_idx; @@ -1566,7 +1562,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, dn = d_alloc(parent, &dname); dout("d_alloc %p '%.*s' = %p\n", parent, dname.len, dname.name, dn); - if (dn == NULL) { + if (!dn) { dout("d_alloc badness\n"); err = -ENOMEM; goto out; @@ -1650,10 +1646,6 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, req->r_readdir_cache_idx = cache_ctl.index; } ceph_readdir_cache_release(&cache_ctl); - if (snapdir) { - iput(snapdir); - dput(parent); - } dout("readdir_prepopulate done\n"); return err; } @@ -1841,9 +1833,20 @@ void __ceph_do_pending_vmtruncate(struct inode *inode) * possibly truncate them.. so write AND block! */ if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) { + struct ceph_cap_snap *capsnap; + to = ci->i_truncate_size; + list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { + // MDS should have revoked Frw caps + WARN_ON_ONCE(capsnap->writing); + if (capsnap->dirty_pages && capsnap->size > to) + to = capsnap->size; + } + spin_unlock(&ci->i_ceph_lock); dout("__do_pending_vmtruncate %p flushing snaps first\n", inode); - spin_unlock(&ci->i_ceph_lock); + + truncate_pagecache(inode, to); + filemap_write_and_wait_range(&inode->i_data, 0, inode->i_sb->s_maxbytes); goto retry; diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 64ae7447204692a6ee4d22eb6f886edb1655a201..8cd63e8123d8f10f2f81734a32658d0c07f5feab 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c @@ -79,7 +79,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, err = ceph_mdsc_do_request(mdsc, inode, req); if (operation == CEPH_MDS_OP_GETFILELOCK) { - fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid); + fl->fl_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid); if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) fl->fl_type = F_RDLCK; else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 666a9f2748321b8f73b956e876908a2ae7d306be..f23c820daaedc6e460982d80d55a653a2379debf 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "super.h" @@ -408,7 +407,7 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc, { struct ceph_mds_session *session; - if (mds >= mdsc->max_sessions || mdsc->sessions[mds] == NULL) + if (mds >= mdsc->max_sessions || !mdsc->sessions[mds]) return NULL; session = mdsc->sessions[mds]; dout("lookup_mds_session %p %d\n", session, @@ -483,7 +482,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, dout("register_session realloc to %d\n", newmax); sa = kcalloc(newmax, sizeof(void *), GFP_NOFS); - if (sa == NULL) + if (!sa) goto fail_realloc; if (mdsc->sessions) { memcpy(sa, mdsc->sessions, @@ -731,8 +730,16 @@ static int __choose_mds(struct ceph_mds_client *mdsc, inode = NULL; if (req->r_inode) { - inode = req->r_inode; - ihold(inode); + if (ceph_snap(req->r_inode) != CEPH_SNAPDIR) { + inode = req->r_inode; + ihold(inode); + } else { + /* req->r_dentry is non-null for LSSNAP request */ + rcu_read_lock(); + inode = get_nonsnap_parent(req->r_dentry); + rcu_read_unlock(); + dout("__choose_mds using snapdir's parent %p\n", inode); + } } else if (req->r_dentry) { /* ignore race with rename; old or new d_parent is okay */ struct dentry *parent; @@ -877,8 +884,8 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 void *p; const char* metadata[][2] = { - {"hostname", utsname()->nodename}, - {"kernel_version", utsname()->release}, + {"hostname", mdsc->nodename}, + {"kernel_version", init_utsname()->release}, {"entity_id", opt->name ? : ""}, {"root", fsopt->server_path ? : "/"}, {NULL, NULL} @@ -886,7 +893,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 /* Calculate serialized length of metadata */ metadata_bytes = 4; /* map length */ - for (i = 0; metadata[i][0] != NULL; ++i) { + for (i = 0; metadata[i][0]; ++i) { metadata_bytes += 8 + strlen(metadata[i][0]) + strlen(metadata[i][1]); metadata_key_count++; @@ -919,7 +926,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 ceph_encode_32(&p, metadata_key_count); /* Two length-prefixed strings for each entry in the map */ - for (i = 0; metadata[i][0] != NULL; ++i) { + for (i = 0; metadata[i][0]; ++i) { size_t const key_len = strlen(metadata[i][0]); size_t const val_len = strlen(metadata[i][1]); @@ -1122,7 +1129,7 @@ static int iterate_session_caps(struct ceph_mds_session *session, spin_lock(&session->s_cap_lock); p = p->next; - if (cap->ci == NULL) { + if (!cap->ci) { dout("iterate_session_caps finishing cap %p removal\n", cap); BUG_ON(cap->session != session); @@ -1748,7 +1755,7 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, int len, pos; unsigned seq; - if (dentry == NULL) + if (!dentry) return ERR_PTR(-EINVAL); retry: @@ -1771,7 +1778,7 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, len--; /* no leading '/' */ path = kmalloc(len+1, GFP_NOFS); - if (path == NULL) + if (!path) return ERR_PTR(-ENOMEM); pos = len; path[pos] = 0; /* trailing null */ @@ -2875,7 +2882,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, } if (list_empty(&ci->i_cap_snaps)) { - snap_follows = 0; + snap_follows = ci->i_head_snapc ? ci->i_head_snapc->seq : 0; } else { struct ceph_cap_snap *capsnap = list_first_entry(&ci->i_cap_snaps, @@ -3133,7 +3140,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, newmap->m_epoch, oldmap->m_epoch); for (i = 0; i < oldmap->m_num_mds && i < mdsc->max_sessions; i++) { - if (mdsc->sessions[i] == NULL) + if (!mdsc->sessions[i]) continue; s = mdsc->sessions[i]; oldstate = ceph_mdsmap_get_state(oldmap, i); @@ -3280,7 +3287,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, mutex_lock(&session->s_mutex); session->s_seq++; - if (inode == NULL) { + if (!inode) { dout("handle_lease no inode %llx\n", vino.ino); goto release; } @@ -3438,7 +3445,7 @@ static void delayed_work(struct work_struct *work) for (i = 0; i < mdsc->max_sessions; i++) { struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i); - if (s == NULL) + if (!s) continue; if (s->s_state == CEPH_MDS_SESSION_CLOSING) { dout("resending session close request for mds%d\n", @@ -3490,7 +3497,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) fsc->mdsc = mdsc; mutex_init(&mdsc->mutex); mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS); - if (mdsc->mdsmap == NULL) { + if (!mdsc->mdsmap) { kfree(mdsc); return -ENOMEM; } @@ -3532,6 +3539,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) init_rwsem(&mdsc->pool_perm_rwsem); mdsc->pool_perm_tree = RB_ROOT; + strncpy(mdsc->nodename, utsname()->nodename, + sizeof(mdsc->nodename) - 1); return 0; } diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index db57ae98ed345e280358a2ac65e75ac6c71e7c2b..636d6b2ec49cbab44954dc8e3e7fb93616e6756d 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -368,6 +369,8 @@ struct ceph_mds_client { struct rw_semaphore pool_perm_rwsem; struct rb_root pool_perm_tree; + + char nodename[__NEW_UTS_LEN + 1]; }; extern const char *ceph_mds_op_name(int op); diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 1a748cf88535bc80b8060be0cae2d4a92f85599f..33ced4c22732a86a159f66d91c1ae7a533e192b1 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -112,7 +112,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) u16 mdsmap_ev; m = kzalloc(sizeof(*m), GFP_NOFS); - if (m == NULL) + if (!m) return ERR_PTR(-ENOMEM); ceph_decode_need(p, end, 1 + 1, bad); @@ -138,7 +138,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) m->m_num_mds = m->m_max_mds; m->m_info = kcalloc(m->m_num_mds, sizeof(*m->m_info), GFP_NOFS); - if (m->m_info == NULL) + if (!m->m_info) goto nomem; /* pick out active nodes from mds_info (state > 0) */ @@ -232,7 +232,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) if (num_export_targets) { info->export_targets = kcalloc(num_export_targets, sizeof(u32), GFP_NOFS); - if (info->export_targets == NULL) + if (!info->export_targets) goto nomem; for (j = 0; j < num_export_targets; j++) info->export_targets[j] = diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index dab5d6732345b218e12f9bf7d6fea1c5dac38d55..7fc0b850c35279646a6eb48a595870a2ce9d6cfd 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -299,7 +299,8 @@ static int cmpu64_rev(const void *a, const void *b) /* * build the snap context for a given realm. */ -static int build_snap_context(struct ceph_snap_realm *realm) +static int build_snap_context(struct ceph_snap_realm *realm, + struct list_head* dirty_realms) { struct ceph_snap_realm *parent = realm->parent; struct ceph_snap_context *snapc; @@ -313,7 +314,7 @@ static int build_snap_context(struct ceph_snap_realm *realm) */ if (parent) { if (!parent->cached_context) { - err = build_snap_context(parent); + err = build_snap_context(parent, dirty_realms); if (err) goto fail; } @@ -332,7 +333,7 @@ static int build_snap_context(struct ceph_snap_realm *realm) " (unchanged)\n", realm->ino, realm, realm->cached_context, realm->cached_context->seq, - (unsigned int) realm->cached_context->num_snaps); + (unsigned int)realm->cached_context->num_snaps); return 0; } @@ -375,6 +376,8 @@ static int build_snap_context(struct ceph_snap_realm *realm) ceph_put_snap_context(realm->cached_context); realm->cached_context = snapc; + /* queue realm for cap_snap creation */ + list_add_tail(&realm->dirty_item, dirty_realms); return 0; fail: @@ -394,15 +397,16 @@ static int build_snap_context(struct ceph_snap_realm *realm) /* * rebuild snap context for the given realm and all of its children. */ -static void rebuild_snap_realms(struct ceph_snap_realm *realm) +static void rebuild_snap_realms(struct ceph_snap_realm *realm, + struct list_head *dirty_realms) { struct ceph_snap_realm *child; dout("rebuild_snap_realms %llx %p\n", realm->ino, realm); - build_snap_context(realm); + build_snap_context(realm, dirty_realms); list_for_each_entry(child, &realm->children, child_item) - rebuild_snap_realms(child); + rebuild_snap_realms(child, dirty_realms); } @@ -624,13 +628,11 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) { struct ceph_inode_info *ci; struct inode *lastinode = NULL; - struct ceph_snap_realm *child; dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino); spin_lock(&realm->inodes_with_caps_lock); - list_for_each_entry(ci, &realm->inodes_with_caps, - i_snap_realm_item) { + list_for_each_entry(ci, &realm->inodes_with_caps, i_snap_realm_item) { struct inode *inode = igrab(&ci->vfs_inode); if (!inode) continue; @@ -643,14 +645,6 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) spin_unlock(&realm->inodes_with_caps_lock); iput(lastinode); - list_for_each_entry(child, &realm->children, child_item) { - dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n", - realm, realm->ino, child, child->ino); - list_del_init(&child->dirty_item); - list_add(&child->dirty_item, &realm->dirty_item); - } - - list_del_init(&realm->dirty_item); dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); } @@ -721,8 +715,6 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, if (err < 0) goto fail; - /* queue realm for cap_snap creation */ - list_add(&realm->dirty_item, &dirty_realms); if (realm->seq > mdsc->last_snap_seq) mdsc->last_snap_seq = realm->seq; @@ -741,7 +733,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, /* invalidate when we reach the _end_ (root) of the trace */ if (invalidate && p >= e) - rebuild_snap_realms(realm); + rebuild_snap_realms(realm, &dirty_realms); if (!first_realm) first_realm = realm; @@ -758,6 +750,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, while (!list_empty(&dirty_realms)) { realm = list_first_entry(&dirty_realms, struct ceph_snap_realm, dirty_item); + list_del_init(&realm->dirty_item); queue_realm_cap_snaps(realm); } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index aa06a8c24792c7a5e0f5378c31beffbae0b3b59d..e4082afedcb15a447ee7fd344aa2a3def391d43c 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -49,9 +49,16 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) struct ceph_statfs st; u64 fsid; int err; + u64 data_pool; + + if (fsc->mdsc->mdsmap->m_num_data_pg_pools == 1) { + data_pool = fsc->mdsc->mdsmap->m_data_pg_pools[0]; + } else { + data_pool = CEPH_NOPOOL; + } dout("statfs\n"); - err = ceph_monc_do_statfs(&fsc->client->monc, &st); + err = ceph_monc_do_statfs(&fsc->client->monc, data_pool, &st); if (err < 0) return err; @@ -113,7 +120,6 @@ enum { Opt_rasize, Opt_caps_wanted_delay_min, Opt_caps_wanted_delay_max, - Opt_cap_release_safety, Opt_readdir_max_entries, Opt_readdir_max_bytes, Opt_congestion_kb, @@ -152,7 +158,6 @@ static match_table_t fsopt_tokens = { {Opt_rasize, "rasize=%d"}, {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"}, {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"}, - {Opt_cap_release_safety, "cap_release_safety=%d"}, {Opt_readdir_max_entries, "readdir_max_entries=%d"}, {Opt_readdir_max_bytes, "readdir_max_bytes=%d"}, {Opt_congestion_kb, "write_congestion_kb=%d"}, @@ -235,27 +240,43 @@ static int parse_fsopt_token(char *c, void *private) break; /* misc */ case Opt_wsize: - fsopt->wsize = intval; + if (intval < PAGE_SIZE || intval > CEPH_MAX_WRITE_SIZE) + return -EINVAL; + fsopt->wsize = ALIGN(intval, PAGE_SIZE); break; case Opt_rsize: - fsopt->rsize = intval; + if (intval < PAGE_SIZE || intval > CEPH_MAX_READ_SIZE) + return -EINVAL; + fsopt->rsize = ALIGN(intval, PAGE_SIZE); break; case Opt_rasize: - fsopt->rasize = intval; + if (intval < 0) + return -EINVAL; + fsopt->rasize = ALIGN(intval + PAGE_SIZE - 1, PAGE_SIZE); break; case Opt_caps_wanted_delay_min: + if (intval < 1) + return -EINVAL; fsopt->caps_wanted_delay_min = intval; break; case Opt_caps_wanted_delay_max: + if (intval < 1) + return -EINVAL; fsopt->caps_wanted_delay_max = intval; break; case Opt_readdir_max_entries: + if (intval < 1) + return -EINVAL; fsopt->max_readdir = intval; break; case Opt_readdir_max_bytes: + if (intval < PAGE_SIZE && intval != 0) + return -EINVAL; fsopt->max_readdir_bytes = intval; break; case Opt_congestion_kb: + if (intval < 1024) /* at least 1M */ + return -EINVAL; fsopt->congestion_kb = intval; break; case Opt_dirstat: @@ -392,7 +413,8 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, fsopt->sb_flags = flags; fsopt->flags = CEPH_MOUNT_OPT_DEFAULT; - fsopt->rsize = CEPH_RSIZE_DEFAULT; + fsopt->wsize = CEPH_MAX_WRITE_SIZE; + fsopt->rsize = CEPH_MAX_READ_SIZE; fsopt->rasize = CEPH_RASIZE_DEFAULT; fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); if (!fsopt->snapdir_name) { @@ -402,7 +424,6 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; - fsopt->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT; fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT; fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; fsopt->congestion_kb = default_congestion_kb(); @@ -508,7 +529,7 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) seq_printf(m, ",mds_namespace=%s", fsopt->mds_namespace); if (fsopt->wsize) seq_printf(m, ",wsize=%d", fsopt->wsize); - if (fsopt->rsize != CEPH_RSIZE_DEFAULT) + if (fsopt->rsize != CEPH_MAX_READ_SIZE) seq_printf(m, ",rsize=%d", fsopt->rsize); if (fsopt->rasize != CEPH_RASIZE_DEFAULT) seq_printf(m, ",rasize=%d", fsopt->rasize); @@ -520,9 +541,6 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) if (fsopt->caps_wanted_delay_max != CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT) seq_printf(m, ",caps_wanted_delay_max=%d", fsopt->caps_wanted_delay_max); - if (fsopt->cap_release_safety != CEPH_CAP_RELEASE_SAFETY_DEFAULT) - seq_printf(m, ",cap_release_safety=%d", - fsopt->cap_release_safety); if (fsopt->max_readdir != CEPH_MAX_READDIR_DEFAULT) seq_printf(m, ",readdir_max_entries=%d", fsopt->max_readdir); if (fsopt->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT) @@ -576,7 +594,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, } fsc->client->extra_mon_dispatch = extra_mon_dispatch; - if (fsopt->mds_namespace == NULL) { + if (!fsopt->mds_namespace) { ceph_monc_want_map(&fsc->client->monc, CEPH_SUB_MDSMAP, 0, true); } else { @@ -597,13 +615,13 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, * to be processed in parallel, limit concurrency. */ fsc->wb_wq = alloc_workqueue("ceph-writeback", 0, 1); - if (fsc->wb_wq == NULL) + if (!fsc->wb_wq) goto fail_client; fsc->pg_inv_wq = alloc_workqueue("ceph-pg-invalid", 0, 1); - if (fsc->pg_inv_wq == NULL) + if (!fsc->pg_inv_wq) goto fail_wb_wq; fsc->trunc_wq = alloc_workqueue("ceph-trunc", 0, 1); - if (fsc->trunc_wq == NULL) + if (!fsc->trunc_wq) goto fail_pg_inv_wq; /* set up mempools */ @@ -674,26 +692,26 @@ static int __init init_caches(void) __alignof__(struct ceph_inode_info), SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| SLAB_ACCOUNT, ceph_inode_init_once); - if (ceph_inode_cachep == NULL) + if (!ceph_inode_cachep) return -ENOMEM; ceph_cap_cachep = KMEM_CACHE(ceph_cap, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); - if (ceph_cap_cachep == NULL) + if (!ceph_cap_cachep) goto bad_cap; ceph_cap_flush_cachep = KMEM_CACHE(ceph_cap_flush, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); - if (ceph_cap_flush_cachep == NULL) + if (!ceph_cap_flush_cachep) goto bad_cap_flush; ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); - if (ceph_dentry_cachep == NULL) + if (!ceph_dentry_cachep) goto bad_dentry; ceph_file_cachep = KMEM_CACHE(ceph_file_info, SLAB_MEM_SPREAD); - if (ceph_file_cachep == NULL) + if (!ceph_file_cachep) goto bad_file; if ((error = ceph_fscache_register())) @@ -947,20 +965,10 @@ static int ceph_setup_bdi(struct super_block *sb, struct ceph_fs_client *fsc) return err; /* set ra_pages based on rasize mount option? */ - if (fsc->mount_options->rasize >= PAGE_SIZE) - sb->s_bdi->ra_pages = - (fsc->mount_options->rasize + PAGE_SIZE - 1) - >> PAGE_SHIFT; - else - sb->s_bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_SIZE; - - if (fsc->mount_options->rsize > fsc->mount_options->rasize && - fsc->mount_options->rsize >= PAGE_SIZE) - sb->s_bdi->io_pages = - (fsc->mount_options->rsize + PAGE_SIZE - 1) - >> PAGE_SHIFT; - else if (fsc->mount_options->rsize == 0) - sb->s_bdi->io_pages = ULONG_MAX; + sb->s_bdi->ra_pages = fsc->mount_options->rasize >> PAGE_SHIFT; + + /* set io_pages based on max osd read size */ + sb->s_bdi->io_pages = fsc->mount_options->rsize >> PAGE_SHIFT; return 0; } diff --git a/fs/ceph/super.h b/fs/ceph/super.h index f02a2225fe422a5a976c29c3336c0fb2d5880e78..279a2f401cf5f40929970e0eb37d7be0d43d7246 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -46,12 +46,25 @@ #define ceph_test_mount_opt(fsc, opt) \ (!!((fsc)->mount_options->flags & CEPH_MOUNT_OPT_##opt)) -#define CEPH_RSIZE_DEFAULT (64*1024*1024) /* max read size */ +/* max size of osd read request, limited by libceph */ +#define CEPH_MAX_READ_SIZE CEPH_MSG_MAX_DATA_LEN +/* osd has a configurable limitaion of max write size. + * CEPH_MSG_MAX_DATA_LEN should be small enough. */ +#define CEPH_MAX_WRITE_SIZE CEPH_MSG_MAX_DATA_LEN #define CEPH_RASIZE_DEFAULT (8192*1024) /* max readahead */ #define CEPH_MAX_READDIR_DEFAULT 1024 #define CEPH_MAX_READDIR_BYTES_DEFAULT (512*1024) #define CEPH_SNAPDIRNAME_DEFAULT ".snap" +/* + * Delay telling the MDS we no longer want caps, in case we reopen + * the file. Delay a minimum amount of time, even if we send a cap + * message for some other reason. Otherwise, take the oppotunity to + * update the mds to avoid sending another message later. + */ +#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT 5 /* cap release delay */ +#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT 60 /* cap release delay */ + struct ceph_mount_options { int flags; int sb_flags; @@ -61,7 +74,6 @@ struct ceph_mount_options { int rasize; /* max readahead */ int congestion_kb; /* max writeback in flight */ int caps_wanted_delay_min, caps_wanted_delay_max; - int cap_release_safety; int max_readdir; /* max readdir result (entires) */ int max_readdir_bytes; /* max readdir result (bytes) */ diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 11263f102e4c914eaf849c39a35c95e33eefe3c6..3542b2c364cfd8e2c517111beee04a6191bbbe4d 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -777,7 +777,7 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value, spin_unlock(&ci->i_ceph_lock); /* security module gets xattr while filling trace */ - if (current->journal_info != NULL) { + if (current->journal_info) { pr_warn_ratelimited("sync getxattr %p " "during filling trace\n", inode); return -EBUSY; @@ -809,7 +809,7 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value, memcpy(value, xattr->val, xattr->val_len); - if (current->journal_info != NULL && + if (current->journal_info && !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) ci->i_ceph_flags |= CEPH_I_SEC_INITED; out: @@ -1058,7 +1058,7 @@ int __ceph_setxattr(struct inode *inode, const char *name, up_read(&mdsc->snap_rwsem); /* security module set xattr while filling trace */ - if (current->journal_info != NULL) { + if (current->journal_info) { pr_warn_ratelimited("sync setxattr %p " "during filling trace\n", inode); err = -EBUSY; @@ -1108,7 +1108,7 @@ bool ceph_security_xattr_deadlock(struct inode *in) { struct ceph_inode_info *ci; bool ret; - if (in->i_security == NULL) + if (!in->i_security) return false; ci = ceph_inode(in); spin_lock(&ci->i_ceph_lock); diff --git a/fs/char_dev.c b/fs/char_dev.c index fb8507f521b265ba8feba385154cc908eb812f44..ebcc8fb3fa6641363e302082aacd92812142e6b1 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -28,6 +28,8 @@ static struct kobj_map *cdev_map; static DEFINE_MUTEX(chrdevs_lock); +#define CHRDEV_MAJOR_HASH_SIZE 255 + static struct char_device_struct { struct char_device_struct *next; unsigned int major; @@ -49,16 +51,39 @@ void chrdev_show(struct seq_file *f, off_t offset) { struct char_device_struct *cd; - if (offset < CHRDEV_MAJOR_HASH_SIZE) { - mutex_lock(&chrdevs_lock); - for (cd = chrdevs[offset]; cd; cd = cd->next) + mutex_lock(&chrdevs_lock); + for (cd = chrdevs[major_to_index(offset)]; cd; cd = cd->next) { + if (cd->major == offset) seq_printf(f, "%3d %s\n", cd->major, cd->name); - mutex_unlock(&chrdevs_lock); } + mutex_unlock(&chrdevs_lock); } #endif /* CONFIG_PROC_FS */ +static int find_dynamic_major(void) +{ + int i; + struct char_device_struct *cd; + + for (i = ARRAY_SIZE(chrdevs)-1; i > CHRDEV_MAJOR_DYN_END; i--) { + if (chrdevs[i] == NULL) + return i; + } + + for (i = CHRDEV_MAJOR_DYN_EXT_START; + i > CHRDEV_MAJOR_DYN_EXT_END; i--) { + for (cd = chrdevs[major_to_index(i)]; cd; cd = cd->next) + if (cd->major == i) + break; + + if (cd == NULL || cd->major != i) + return i; + } + + return -EBUSY; +} + /* * Register a single major with a specified minor range. * @@ -84,22 +109,21 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, mutex_lock(&chrdevs_lock); - /* temporary */ if (major == 0) { - for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) { - if (chrdevs[i] == NULL) - break; - } - - if (i < CHRDEV_MAJOR_DYN_END) - pr_warn("CHRDEV \"%s\" major number %d goes below the dynamic allocation range\n", - name, i); - - if (i == 0) { - ret = -EBUSY; + ret = find_dynamic_major(); + if (ret < 0) { + pr_err("CHRDEV \"%s\" dynamic allocation region is full\n", + name); goto out; } - major = i; + major = ret; + } + + if (major >= CHRDEV_MAJOR_MAX) { + pr_err("CHRDEV \"%s\" major requested (%d) is greater than the maximum (%d)\n", + name, major, CHRDEV_MAJOR_MAX); + ret = -EINVAL; + goto out; } cd->major = major; diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c index 6c665bf4a27c2985b9baa5b0f888fc0f0a7bed65..2c14020e5e1d866afbb98b9779712ec8375ee6c0 100644 --- a/fs/cifs/cache.c +++ b/fs/cifs/cache.c @@ -292,36 +292,6 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, return FSCACHE_CHECKAUX_OKAY; } -static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data) -{ - struct cifsInodeInfo *cifsi = cookie_netfs_data; - struct pagevec pvec; - pgoff_t first; - int loop, nr_pages; - - pagevec_init(&pvec, 0); - first = 0; - - cifs_dbg(FYI, "%s: cifs inode 0x%p now uncached\n", __func__, cifsi); - - for (;;) { - nr_pages = pagevec_lookup(&pvec, - cifsi->vfs_inode.i_mapping, first, - PAGEVEC_SIZE - pagevec_count(&pvec)); - if (!nr_pages) - break; - - for (loop = 0; loop < nr_pages; loop++) - ClearPageFsCache(pvec.pages[loop]); - - first = pvec.pages[nr_pages - 1]->index + 1; - - pvec.nr = nr_pages; - pagevec_release(&pvec); - cond_resched(); - } -} - const struct fscache_cookie_def cifs_fscache_inode_object_def = { .name = "CIFS.uniqueid", .type = FSCACHE_COOKIE_TYPE_DATAFILE, @@ -329,5 +299,4 @@ const struct fscache_cookie_def cifs_fscache_inode_object_def = { .get_attr = cifs_fscache_inode_get_attr, .get_aux = cifs_fscache_inode_get_aux, .check_aux = cifs_fscache_inode_check_aux, - .now_uncached = cifs_fscache_inode_now_uncached, }; diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 9727e1dcacd558a89e5fa0c206e82b6f0941a99c..cbb9534b89b40bc3f3cc3be31254485b976d2bcb 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -160,8 +160,13 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) || (ses->serverNOS == NULL)) { - seq_printf(m, "\n%d) entry for %s not fully " - "displayed\n\t", i, ses->serverName); + seq_printf(m, "\n%d) Name: %s Uses: %d Capability: 0x%x\tSession Status: %d\t", + i, ses->serverName, ses->ses_count, + ses->capabilities, ses->status); + if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) + seq_printf(m, "Guest\t"); + else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) + seq_printf(m, "Anonymous\t"); } else { seq_printf(m, "\n%d) Name: %s Domain: %s Uses: %d OS:" diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 180b3356ff8612dfc7f3cd702e350bb284ca1a0d..8c8b75d33f310ce5e258042ff489f942379cdd27 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -461,6 +461,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_puts(s, ",nocase"); if (tcon->retry) seq_puts(s, ",hard"); + else + seq_puts(s, ",soft"); if (tcon->use_persistent) seq_puts(s, ",persistenthandles"); else if (tcon->use_resilient) @@ -1447,7 +1449,7 @@ exit_cifs(void) exit_cifs_idmap(); #endif #ifdef CONFIG_CIFS_UPCALL - unregister_key_type(&cifs_spnego_key_type); + exit_cifs_spnego(); #endif cifs_destroy_request_bufs(); cifs_destroy_mids(); diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 30bf89b1fd9a789ec02070f534d9d9f68b593650..5a10e566f0e610fcaadf0d949e307087f01ecc90 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -149,5 +149,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "2.09" +#define CIFS_VERSION "2.10" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 221693fe49ec8114d307f3f3974f0420e871b73c..de5b2e1fcce5f35153a84c9cb1c191911b48a728 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -188,6 +188,8 @@ enum smb_version { #ifdef CONFIG_CIFS_SMB311 Smb_311, #endif /* SMB311 */ + Smb_3any, + Smb_default, Smb_version_err }; @@ -421,7 +423,7 @@ struct smb_version_operations { size_t, struct cifs_sb_info *); int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, const char *, const void *, const __u16, - const struct nls_table *, int); + const struct nls_table *, struct cifs_sb_info *); struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, const char *, u32 *); struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, @@ -1701,6 +1703,10 @@ extern struct smb_version_values smb20_values; #define SMB21_VERSION_STRING "2.1" extern struct smb_version_operations smb21_operations; extern struct smb_version_values smb21_values; +#define SMBDEFAULT_VERSION_STRING "default" +extern struct smb_version_values smbdefault_values; +#define SMB3ANY_VERSION_STRING "3" +extern struct smb_version_values smb3any_values; #define SMB30_VERSION_STRING "3.0" extern struct smb_version_operations smb30_operations; extern struct smb_version_values smb30_values; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 6eb3147132e30c2225b610b01281111bb896c617..4143c9dec46398328aa4c78af849c6032a0edfd3 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -484,7 +484,8 @@ extern ssize_t CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, const char *fileName, const char *ea_name, const void *ea_value, const __u16 ea_value_len, - const struct nls_table *nls_codepage, int remap_special_chars); + const struct nls_table *nls_codepage, + struct cifs_sb_info *cifs_sb); extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 72a53bd198656d0d3a536b4fc6751d4a95d29a5d..35dc5bf01ee2ab96f62a793c466e033bf0659de4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -178,6 +178,18 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) * reconnect the same SMB session */ mutex_lock(&ses->session_mutex); + + /* + * Recheck after acquire mutex. If another thread is negotiating + * and the server never sends an answer the socket will be closed + * and tcpStatus set to reconnect. + */ + if (server->tcpStatus == CifsNeedReconnect) { + rc = -EHOSTDOWN; + mutex_unlock(&ses->session_mutex); + goto out; + } + rc = cifs_negotiate_protocol(0, ses); if (rc == 0 && ses->need_reconnect) rc = cifs_setup_session(0, ses, nls_codepage); @@ -2522,7 +2534,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon, pLockData->fl_start = le64_to_cpu(parm_data->start); pLockData->fl_end = pLockData->fl_start + le64_to_cpu(parm_data->length) - 1; - pLockData->fl_pid = le32_to_cpu(parm_data->pid); + pLockData->fl_pid = -le32_to_cpu(parm_data->pid); } } @@ -6264,7 +6276,7 @@ int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, const char *fileName, const char *ea_name, const void *ea_value, const __u16 ea_value_len, const struct nls_table *nls_codepage, - int remap) + struct cifs_sb_info *cifs_sb) { struct smb_com_transaction2_spi_req *pSMB = NULL; struct smb_com_transaction2_spi_rsp *pSMBr = NULL; @@ -6273,6 +6285,7 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; int bytes_returned = 0; __u16 params, param_offset, byte_count, offset, count; + int remap = cifs_remap(cifs_sb); cifs_dbg(FYI, "In SetEA\n"); SetEARetry: diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 59647eb72c5fb29e73068df8e02a1b35decbe1a4..0bfc2280436df86c7414288b5cb4afefb401127d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -301,6 +301,8 @@ static const match_table_t cifs_smb_version_tokens = { { Smb_311, SMB311_VERSION_STRING }, { Smb_311, ALT_SMB311_VERSION_STRING }, #endif /* SMB311 */ + { Smb_3any, SMB3ANY_VERSION_STRING }, + { Smb_default, SMBDEFAULT_VERSION_STRING }, { Smb_version_err, NULL } }; @@ -509,7 +511,8 @@ server_unresponsive(struct TCP_Server_Info *server) * 65s kernel_recvmsg times out, and we see that we haven't gotten * a response in >60s. */ - if (server->tcpStatus == CifsGood && + if ((server->tcpStatus == CifsGood || + server->tcpStatus == CifsNeedNegotiate) && time_after(jiffies, server->lstrp + 2 * server->echo_interval)) { cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", server->hostname, (2 * server->echo_interval) / HZ); @@ -1147,6 +1150,14 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol) vol->vals = &smb311_values; break; #endif /* SMB311 */ + case Smb_3any: + vol->ops = &smb30_operations; /* currently identical with 3.0 */ + vol->vals = &smb3any_values; + break; + case Smb_default: + vol->ops = &smb30_operations; /* currently identical with 3.0 */ + vol->vals = &smbdefault_values; + break; default: cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); return 1; @@ -1223,6 +1234,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, char *tmp_end, *value; char delim; bool got_ip = false; + bool got_version = false; unsigned short port = 0; struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr; @@ -1272,9 +1284,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->actimeo = CIFS_DEF_ACTIMEO; - /* FIXME: add autonegotiation for SMB3 or later rather than just SMB3 */ - vol->ops = &smb30_operations; /* both secure and accepted widely */ - vol->vals = &smb30_values; + /* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */ + vol->ops = &smb30_operations; + vol->vals = &smbdefault_values; vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT; @@ -1874,24 +1886,35 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, pr_warn("CIFS: server netbiosname longer than 15 truncated.\n"); break; case Opt_ver: + /* version of mount userspace tools, not dialect */ string = match_strdup(args); if (string == NULL) goto out_nomem; + /* If interface changes in mount.cifs bump to new ver */ if (strncasecmp(string, "1", 1) == 0) { + if (strlen(string) > 1) { + pr_warn("Bad mount helper ver=%s. Did " + "you want SMB1 (CIFS) dialect " + "and mean to type vers=1.0 " + "instead?\n", string); + goto cifs_parse_mount_err; + } /* This is the default */ break; } /* For all other value, error */ - pr_warn("CIFS: Invalid version specified\n"); + pr_warn("CIFS: Invalid mount helper version specified\n"); goto cifs_parse_mount_err; case Opt_vers: + /* protocol version (dialect) */ string = match_strdup(args); if (string == NULL) goto out_nomem; if (cifs_parse_smb_version(string, vol) != 0) goto cifs_parse_mount_err; + got_version = true; break; case Opt_sec: string = match_strdup(args); @@ -1973,6 +1996,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, else if (override_gid == 1) pr_notice("CIFS: ignoring forcegid mount option specified with no gid= option.\n"); + if (got_version == false) + pr_warn("No dialect specified on mount. Default has changed to " + "a more secure dialect, SMB2.1 or later (e.g. SMB3), from CIFS " + "(SMB1). To use the less secure SMB1 dialect to access " + "old servers which do not support SMB3 (or SMB2.1) specify vers=1.0" + " on mount.\n"); + kfree(mountdata_copy); return 0; @@ -2112,6 +2142,7 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol) if (vol->nosharesock) return 0; + /* BB update this for smb3any and default case */ if ((server->vals != vol->vals) || (server->ops != vol->ops)) return 0; @@ -4123,6 +4154,14 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n", server->sec_mode, server->capabilities, server->timeAdj); + if (ses->auth_key.response) { + cifs_dbg(VFS, "Free previous auth_key.response = %p\n", + ses->auth_key.response); + kfree(ses->auth_key.response); + ses->auth_key.response = NULL; + ses->auth_key.len = 0; + } + if (server->ops->sess_setup) rc = server->ops->sess_setup(xid, ses, nls_info); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 56366e9840769dd8a45250ec3a7b65097c979ff9..e702d48bd023411f3bbed69c6cc6a571f2fc059c 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -194,15 +194,20 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, bool prefix) } /* + * Don't allow path components longer than the server max. * Don't allow the separator character in a path component. * The VFS will not allow "/", but "\" is allowed by posix. */ static int -check_name(struct dentry *direntry) +check_name(struct dentry *direntry, struct cifs_tcon *tcon) { struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); int i; + if (unlikely(direntry->d_name.len > + le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength))) + return -ENAMETOOLONG; + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { for (i = 0; i < direntry->d_name.len; i++) { if (direntry->d_name.name[i] == '\\') { @@ -500,10 +505,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, return finish_no_open(file, res); } - rc = check_name(direntry); - if (rc) - return rc; - xid = get_xid(); cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", @@ -516,6 +517,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, } tcon = tlink_tcon(tlink); + + rc = check_name(direntry, tcon); + if (rc) + goto out_free_xid; + server = tcon->ses->server; if (server->ops->new_lease_key) @@ -776,7 +782,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, } pTcon = tlink_tcon(tlink); - rc = check_name(direntry); + rc = check_name(direntry, pTcon); if (rc) goto lookup_out; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index bc09df6b473ae309a693b1c6accaa5ff9c3b24de..92fdf9c35de2153fd6f008c4d1306ead6d806c89 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -224,6 +224,13 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, if (backup_cred(cifs_sb)) create_options |= CREATE_OPEN_BACKUP_INTENT; + /* O_SYNC also has bit for O_DSYNC so following check picks up either */ + if (f_flags & O_SYNC) + create_options |= CREATE_WRITE_THROUGH; + + if (f_flags & O_DIRECT) + create_options |= CREATE_NO_BUFFER; + oparms.tcon = tcon; oparms.cifs_sb = cifs_sb; oparms.desired_access = desired_access; @@ -1102,8 +1109,10 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) struct cifs_tcon *tcon; unsigned int num, max_num, max_buf; LOCKING_ANDX_RANGE *buf, *cur; - int types[] = {LOCKING_ANDX_LARGE_FILES, - LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES}; + static const int types[] = { + LOCKING_ANDX_LARGE_FILES, + LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES + }; int i; xid = get_xid(); @@ -1434,8 +1443,10 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, unsigned int xid) { int rc = 0, stored_rc; - int types[] = {LOCKING_ANDX_LARGE_FILES, - LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES}; + static const int types[] = { + LOCKING_ANDX_LARGE_FILES, + LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES + }; unsigned int i; unsigned int max_num, num, max_buf; LOCKING_ANDX_RANGE *buf, *cur; @@ -2329,7 +2340,7 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, struct inode *inode = file_inode(file); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - rc = filemap_write_and_wait_range(inode->i_mapping, start, end); + rc = file_write_and_wait_range(file, start, end); if (rc) return rc; inode_lock(inode); @@ -2371,7 +2382,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); struct inode *inode = file->f_mapping->host; - rc = filemap_write_and_wait_range(inode->i_mapping, start, end); + rc = file_write_and_wait_range(file, start, end); if (rc) return rc; inode_lock(inode); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index a8693632235f02b349db28e8d77aa45e30d4c783..7c732cb4416411e597f2e1a4af96fd8bf7e49beb 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -234,6 +234,8 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime); fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange); + /* old POSIX extensions don't get create time */ + fattr->cf_mode = le64_to_cpu(info->Permissions); /* @@ -2024,6 +2026,19 @@ int cifs_getattr(const struct path *path, struct kstat *stat, stat->blksize = CIFS_MAX_MSGSIZE; stat->ino = CIFS_I(inode)->uniqueid; + /* old CIFS Unix Extensions doesn't return create time */ + if (CIFS_I(inode)->createtime) { + stat->result_mask |= STATX_BTIME; + stat->btime = + cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime)); + } + + stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED); + if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_COMPRESSED) + stat->attributes |= STATX_ATTR_COMPRESSED; + if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_ENCRYPTED) + stat->attributes |= STATX_ATTR_ENCRYPTED; + /* * If on a multiuser mount without unix extensions or cifsacl being * enabled, and the admin hasn't overridden them, set the ownership diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index cfacf2c97e9418c991b7264f7b75ee271039b260..0dafdbae1f8cb35539a138e73330a214f7f72da3 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -426,6 +426,196 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, return rc; } +#ifdef CONFIG_CIFS_XATTR +static ssize_t +move_smb2_ea_to_cifs(char *dst, size_t dst_size, + struct smb2_file_full_ea_info *src, size_t src_size, + const unsigned char *ea_name) +{ + int rc = 0; + unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; + char *name, *value; + size_t name_len, value_len, user_name_len; + + while (src_size > 0) { + name = &src->ea_data[0]; + name_len = (size_t)src->ea_name_length; + value = &src->ea_data[src->ea_name_length + 1]; + value_len = (size_t)le16_to_cpu(src->ea_value_length); + + if (name_len == 0) { + break; + } + + if (src_size < 8 + name_len + 1 + value_len) { + cifs_dbg(FYI, "EA entry goes beyond length of list\n"); + rc = -EIO; + goto out; + } + + if (ea_name) { + if (ea_name_len == name_len && + memcmp(ea_name, name, name_len) == 0) { + rc = value_len; + if (dst_size == 0) + goto out; + if (dst_size < value_len) { + rc = -ERANGE; + goto out; + } + memcpy(dst, value, value_len); + goto out; + } + } else { + /* 'user.' plus a terminating null */ + user_name_len = 5 + 1 + name_len; + + rc += user_name_len; + + if (dst_size >= user_name_len) { + dst_size -= user_name_len; + memcpy(dst, "user.", 5); + dst += 5; + memcpy(dst, src->ea_data, name_len); + dst += name_len; + *dst = 0; + ++dst; + } else if (dst_size == 0) { + /* skip copy - calc size only */ + } else { + /* stop before overrun buffer */ + rc = -ERANGE; + break; + } + } + + if (!src->next_entry_offset) + break; + + if (src_size < le32_to_cpu(src->next_entry_offset)) { + /* stop before overrun buffer */ + rc = -ERANGE; + break; + } + src_size -= le32_to_cpu(src->next_entry_offset); + src = (void *)((char *)src + + le32_to_cpu(src->next_entry_offset)); + } + + /* didn't find the named attribute */ + if (ea_name) + rc = -ENODATA; + +out: + return (ssize_t)rc; +} + +static ssize_t +smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, + const unsigned char *path, const unsigned char *ea_name, + char *ea_data, size_t buf_size, + struct cifs_sb_info *cifs_sb) +{ + int rc; + __le16 *utf16_path; + __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; + struct cifs_open_parms oparms; + struct cifs_fid fid; + struct smb2_file_full_ea_info *smb2_data; + + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); + if (!utf16_path) + return -ENOMEM; + + oparms.tcon = tcon; + oparms.desired_access = FILE_READ_EA; + oparms.disposition = FILE_OPEN; + oparms.create_options = 0; + oparms.fid = &fid; + oparms.reconnect = false; + + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); + kfree(utf16_path); + if (rc) { + cifs_dbg(FYI, "open failed rc=%d\n", rc); + return rc; + } + + smb2_data = kzalloc(SMB2_MAX_EA_BUF, GFP_KERNEL); + if (smb2_data == NULL) { + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + return -ENOMEM; + } + + rc = SMB2_query_eas(xid, tcon, fid.persistent_fid, fid.volatile_fid, + smb2_data); + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + + if (!rc) + rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data, + SMB2_MAX_EA_BUF, ea_name); + + kfree(smb2_data); + return rc; +} + + +static int +smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + const char *path, const char *ea_name, const void *ea_value, + const __u16 ea_value_len, const struct nls_table *nls_codepage, + struct cifs_sb_info *cifs_sb) +{ + int rc; + __le16 *utf16_path; + __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; + struct cifs_open_parms oparms; + struct cifs_fid fid; + struct smb2_file_full_ea_info *ea; + int ea_name_len = strlen(ea_name); + int len; + + if (ea_name_len > 255) + return -EINVAL; + + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); + if (!utf16_path) + return -ENOMEM; + + oparms.tcon = tcon; + oparms.desired_access = FILE_WRITE_EA; + oparms.disposition = FILE_OPEN; + oparms.create_options = 0; + oparms.fid = &fid; + oparms.reconnect = false; + + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); + kfree(utf16_path); + if (rc) { + cifs_dbg(FYI, "open failed rc=%d\n", rc); + return rc; + } + + len = sizeof(ea) + ea_name_len + ea_value_len + 1; + ea = kzalloc(len, GFP_KERNEL); + if (ea == NULL) { + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + return -ENOMEM; + } + + ea->ea_name_length = ea_name_len; + ea->ea_value_length = cpu_to_le16(ea_value_len); + memcpy(ea->ea_data, ea_name, ea_name_len + 1); + memcpy(ea->ea_data + ea_name_len + 1, ea_value, ea_value_len); + + rc = SMB2_set_ea(xid, tcon, fid.persistent_fid, fid.volatile_fid, ea, + len); + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + + return rc; +} +#endif + static bool smb2_can_echo(struct TCP_Server_Info *server) { @@ -2572,6 +2762,10 @@ struct smb_version_operations smb20_operations = { .dir_needs_close = smb2_dir_needs_close, .get_dfs_refer = smb2_get_dfs_refer, .select_sectype = smb2_select_sectype, +#ifdef CONFIG_CIFS_XATTR + .query_all_EAs = smb2_query_eas, + .set_EA = smb2_set_ea, +#endif /* CIFS_XATTR */ #ifdef CONFIG_CIFS_ACL .get_acl = get_smb2_acl, .get_acl_by_fid = get_smb2_acl_by_fid, @@ -2662,6 +2856,10 @@ struct smb_version_operations smb21_operations = { .enum_snapshots = smb3_enum_snapshots, .get_dfs_refer = smb2_get_dfs_refer, .select_sectype = smb2_select_sectype, +#ifdef CONFIG_CIFS_XATTR + .query_all_EAs = smb2_query_eas, + .set_EA = smb2_set_ea, +#endif /* CIFS_XATTR */ #ifdef CONFIG_CIFS_ACL .get_acl = get_smb2_acl, .get_acl_by_fid = get_smb2_acl_by_fid, @@ -2762,6 +2960,10 @@ struct smb_version_operations smb30_operations = { .receive_transform = smb3_receive_transform, .get_dfs_refer = smb2_get_dfs_refer, .select_sectype = smb2_select_sectype, +#ifdef CONFIG_CIFS_XATTR + .query_all_EAs = smb2_query_eas, + .set_EA = smb2_set_ea, +#endif /* CIFS_XATTR */ #ifdef CONFIG_CIFS_ACL .get_acl = get_smb2_acl, .get_acl_by_fid = get_smb2_acl_by_fid, @@ -2863,6 +3065,10 @@ struct smb_version_operations smb311_operations = { .receive_transform = smb3_receive_transform, .get_dfs_refer = smb2_get_dfs_refer, .select_sectype = smb2_select_sectype, +#ifdef CONFIG_CIFS_XATTR + .query_all_EAs = smb2_query_eas, + .set_EA = smb2_set_ea, +#endif /* CIFS_XATTR */ }; #endif /* CIFS_SMB311 */ @@ -2906,6 +3112,46 @@ struct smb_version_values smb21_values = { .create_lease_size = sizeof(struct create_lease), }; +struct smb_version_values smb3any_values = { + .version_string = SMB3ANY_VERSION_STRING, + .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */ + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, + .large_lock_type = 0, + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, + .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, + .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, + .header_size = sizeof(struct smb2_hdr), + .max_header_size = MAX_SMB2_HDR_SIZE, + .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, + .cap_large_files = SMB2_LARGE_FILES, + .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, + .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, + .create_lease_size = sizeof(struct create_lease_v2), +}; + +struct smb_version_values smbdefault_values = { + .version_string = SMBDEFAULT_VERSION_STRING, + .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */ + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, + .large_lock_type = 0, + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, + .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, + .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, + .header_size = sizeof(struct smb2_hdr), + .max_header_size = MAX_SMB2_HDR_SIZE, + .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, + .cap_large_files = SMB2_LARGE_FILES, + .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, + .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, + .create_lease_size = sizeof(struct create_lease_v2), +}; + struct smb_version_values smb30_values = { .version_string = SMB30_VERSION_STRING, .protocol_id = SMB30_PROT_ID, diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 5fb2fc2d0080b6e62fd0ad10e1a9c90c08308f2d..6f0e6343c15e7e329e6de896220c693f337d9829 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -238,6 +238,18 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) * the same SMB session */ mutex_lock(&tcon->ses->session_mutex); + + /* + * Recheck after acquire mutex. If another thread is negotiating + * and the server never sends an answer the socket will be closed + * and tcpStatus set to reconnect. + */ + if (server->tcpStatus == CifsNeedReconnect) { + rc = -EHOSTDOWN; + mutex_unlock(&tcon->ses->session_mutex); + goto out; + } + rc = cifs_negotiate_protocol(0, tcon->ses); if (!rc && tcon->ses->need_reconnect) rc = cifs_setup_session(0, tcon->ses, nls_codepage); @@ -427,7 +439,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req) build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt); req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT); req->NegotiateContextCount = cpu_to_le16(2); - inc_rfc1001_len(req, 4 + sizeof(struct smb2_preauth_neg_context) + 2 + inc_rfc1001_len(req, 4 + sizeof(struct smb2_preauth_neg_context) + sizeof(struct smb2_encryption_neg_context)); /* calculate hash */ } #else @@ -479,10 +491,25 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) req->hdr.sync_hdr.SessionId = 0; - req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); - - req->DialectCount = cpu_to_le16(1); /* One vers= at a time for now */ - inc_rfc1001_len(req, 2); + if (strcmp(ses->server->vals->version_string, + SMB3ANY_VERSION_STRING) == 0) { + req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); + req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); + req->DialectCount = cpu_to_le16(2); + inc_rfc1001_len(req, 4); + } else if (strcmp(ses->server->vals->version_string, + SMBDEFAULT_VERSION_STRING) == 0) { + req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); + req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); + req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); + req->DialectCount = cpu_to_le16(3); + inc_rfc1001_len(req, 6); + } else { + /* otherwise send specific dialect */ + req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); + req->DialectCount = cpu_to_le16(1); + inc_rfc1001_len(req, 2); + } /* only one of SMB2 signing flags may be set in SMB2 request */ if (ses->sign) @@ -514,13 +541,45 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) * No tcon so can't do * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); */ - if (rc != 0) + if (rc == -EOPNOTSUPP) { + cifs_dbg(VFS, "Dialect not supported by server. Consider " + "specifying vers=1.0 or vers=2.0 on mount for accessing" + " older servers\n"); + goto neg_exit; + } else if (rc != 0) goto neg_exit; + if (strcmp(ses->server->vals->version_string, + SMB3ANY_VERSION_STRING) == 0) { + if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { + cifs_dbg(VFS, + "SMB2 dialect returned but not requested\n"); + return -EIO; + } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { + cifs_dbg(VFS, + "SMB2.1 dialect returned but not requested\n"); + return -EIO; + } + } else if (strcmp(ses->server->vals->version_string, + SMBDEFAULT_VERSION_STRING) == 0) { + if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { + cifs_dbg(VFS, + "SMB2 dialect returned but not requested\n"); + return -EIO; + } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { + /* ops set to 3.0 by default for default so update */ + ses->server->ops = &smb21_operations; + } + } else if (le16_to_cpu(rsp->DialectRevision) != + ses->server->vals->protocol_id) { + /* if requested single dialect ensure returned dialect matched */ + cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", + le16_to_cpu(rsp->DialectRevision)); + return -EIO; + } + cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode); - /* BB we may eventually want to match the negotiated vs. requested - dialect, even though we are only requesting one at a time */ if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) cifs_dbg(FYI, "negotiated smb2.0 dialect\n"); else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) @@ -541,6 +600,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) } server->dialect = le16_to_cpu(rsp->DialectRevision); + /* BB: add check that dialect was valid given dialect(s) we asked for */ + /* SMB2 only has an extended negflavor */ server->negflavor = CIFS_NEGFLAVOR_EXTENDED; /* set it to the maximum buffer size value we can send with 1 credit */ @@ -589,19 +650,27 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) struct validate_negotiate_info_req vneg_inbuf; struct validate_negotiate_info_rsp *pneg_rsp; u32 rsplen; + u32 inbuflen; /* max of 4 dialects */ cifs_dbg(FYI, "validate negotiate\n"); /* * validation ioctl must be signed, so no point sending this if we - * can not sign it. We could eventually change this to selectively + * can not sign it (ie are not known user). Even if signing is not + * required (enabled but not negotiated), in those cases we selectively * sign just this, the first and only signed request on a connection. - * This is good enough for now since a user who wants better security - * would also enable signing on the mount. Having validation of - * negotiate info for signed connections helps reduce attack vectors + * Having validation of negotiate info helps reduce attack vectors. */ - if (tcon->ses->server->sign == false) + if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) + return 0; /* validation requires signing */ + + if (tcon->ses->user_name == NULL) { + cifs_dbg(FYI, "Can't validate negotiate: null user mount\n"); return 0; /* validation requires signing */ + } + + if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) + cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); vneg_inbuf.Capabilities = cpu_to_le32(tcon->ses->server->vals->req_capabilities); @@ -617,9 +686,30 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) else vneg_inbuf.SecurityMode = 0; - vneg_inbuf.DialectCount = cpu_to_le16(1); - vneg_inbuf.Dialects[0] = - cpu_to_le16(tcon->ses->server->vals->protocol_id); + + if (strcmp(tcon->ses->server->vals->version_string, + SMB3ANY_VERSION_STRING) == 0) { + vneg_inbuf.Dialects[0] = cpu_to_le16(SMB30_PROT_ID); + vneg_inbuf.Dialects[1] = cpu_to_le16(SMB302_PROT_ID); + vneg_inbuf.DialectCount = cpu_to_le16(2); + /* structure is big enough for 3 dialects, sending only 2 */ + inbuflen = sizeof(struct validate_negotiate_info_req) - 2; + } else if (strcmp(tcon->ses->server->vals->version_string, + SMBDEFAULT_VERSION_STRING) == 0) { + vneg_inbuf.Dialects[0] = cpu_to_le16(SMB21_PROT_ID); + vneg_inbuf.Dialects[1] = cpu_to_le16(SMB30_PROT_ID); + vneg_inbuf.Dialects[2] = cpu_to_le16(SMB302_PROT_ID); + vneg_inbuf.DialectCount = cpu_to_le16(3); + /* structure is big enough for 3 dialects */ + inbuflen = sizeof(struct validate_negotiate_info_req); + } else { + /* otherwise specific dialect was requested */ + vneg_inbuf.Dialects[0] = + cpu_to_le16(tcon->ses->server->vals->protocol_id); + vneg_inbuf.DialectCount = cpu_to_le16(1); + /* structure is big enough for 3 dialects, sending only 1 */ + inbuflen = sizeof(struct validate_negotiate_info_req) - 4; + } rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, @@ -1093,6 +1183,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, while (sess_data->func) sess_data->func(sess_data); + if ((ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) && (ses->sign)) + cifs_dbg(VFS, "signing requested but authenticated as guest\n"); rc = sess_data->result; out: kfree(sess_data); @@ -1617,7 +1709,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, struct cifs_tcon *tcon = oparms->tcon; struct cifs_ses *ses = tcon->ses; struct kvec iov[4]; - struct kvec rsp_iov; + struct kvec rsp_iov = {NULL, 0}; int resp_buftype; int uni_path_len; __le16 *copy_path = NULL; @@ -1746,7 +1838,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, if (rc != 0) { cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); - if (err_buf) + if (err_buf && rsp) *err_buf = kmemdup(rsp, get_rfc1002_length(rsp) + 4, GFP_KERNEL); goto creat_exit; @@ -2140,6 +2232,18 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, return rc; } +int SMB2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + struct smb2_file_full_ea_info *data) +{ + return query_info(xid, tcon, persistent_fid, volatile_fid, + FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, 0, + SMB2_MAX_EA_BUF, + sizeof(struct smb2_file_full_ea_info), + (void **)&data, + NULL); +} + int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, struct smb2_file_all_info *data) { @@ -3179,6 +3283,16 @@ SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 1, (void **)&pnntsd, &pacllen); } +int +SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + struct smb2_file_full_ea_info *buf, int len) +{ + return send_set_info(xid, tcon, persistent_fid, volatile_fid, + current->tgid, FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, + 0, 1, (void **)&buf, &len); +} + int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, const u64 persistent_fid, const u64 volatile_fid, @@ -3219,8 +3333,8 @@ copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf, kst->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) * le32_to_cpu(pfs_inf->SectorsPerAllocationUnit); kst->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits); - kst->f_bfree = le64_to_cpu(pfs_inf->ActualAvailableAllocationUnits); - kst->f_bavail = le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits); + kst->f_bfree = kst->f_bavail = + le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits); return; } diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 18700fd25a0b3f6ceebce14d59716dc4cf2d3cb0..6c9653a130c8bf38f5c38d6965cea32d105e708d 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -84,8 +84,8 @@ #define NUMBER_OF_SMB2_COMMANDS 0x0013 -/* BB FIXME - analyze following length BB */ -#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */ +/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */ +#define MAX_SMB2_HDR_SIZE 0x00b0 #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe) #define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd) @@ -716,7 +716,7 @@ struct validate_negotiate_info_req { __u8 Guid[SMB2_CLIENT_GUID_SIZE]; __le16 SecurityMode; __le16 DialectCount; - __le16 Dialects[1]; /* dialect (someday maybe list) client asked for */ + __le16 Dialects[3]; /* BB expand this if autonegotiate > 3 dialects */ } __packed; struct validate_negotiate_info_rsp { @@ -1178,6 +1178,16 @@ struct smb2_file_link_info { /* encoding of request for level 11 */ char FileName[0]; /* Name to be assigned to new link */ } __packed; /* level 11 Set */ +#define SMB2_MAX_EA_BUF 2048 + +struct smb2_file_full_ea_info { /* encoding of response for level 15 */ + __le32 next_entry_offset; + __u8 flags; + __u8 ea_name_length; + __le16 ea_value_length; + char ea_data[0]; /* \0 terminated name plus value */ +} __packed; /* level 15 Set */ + /* * This level 18, although with struct with same name is different from cifs * level 0x107. Level 0x107 has an extra u64 between AccessFlags and diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 1cadaf9f3c588ea3acc673f883baacfbf8c70b5f..003217099ef3e6831a36ed81f7c13f1f611efb9d 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -132,6 +132,9 @@ extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id); extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id); +extern int SMB2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id, + struct smb2_file_full_ea_info *data); extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id, struct smb2_file_all_info *data); @@ -169,6 +172,9 @@ extern int SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon, extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, struct cifs_ntsd *pnntsd, int pacllen, int aclflag); +extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + struct smb2_file_full_ea_info *buf, int len); extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid); extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index de50e749ff058d79c67f7462962614c8c835ecdb..52f975d848a076e6873d55b6429c0c62588ecb51 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -84,7 +84,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, if (pTcon->ses->server->ops->set_EA) rc = pTcon->ses->server->ops->set_EA(xid, pTcon, full_path, name, value, (__u16)size, - cifs_sb->local_nls, cifs_remap(cifs_sb)); + cifs_sb->local_nls, cifs_sb); break; case XATTR_CIFS_ACL: { diff --git a/fs/coda/dir.c b/fs/coda/dir.c index c0474ac6cbf200eb458eaf5e3f2359e9b0edfcab..274ab5586dd064a49fba35cad7201be9dc47e84b 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -368,9 +368,10 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx) goto out; while (1) { + loff_t pos = ctx->pos - 2; + /* read entries from the directory file */ - ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir, - sizeof(*vdir)); + ret = kernel_read(host_file, vdir, sizeof(*vdir), &pos); if (ret < 0) { pr_err("%s: read dir %s failed %d\n", __func__, coda_f2s(&cii->c_fid), ret); diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 2dd4a7af7dd736f185541cd6dad413cd1d8090ba..d27b326d96f4e0402a01cdf8f7ba7233bd022aa3 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1331,8 +1331,6 @@ COMPATIBLE_IOCTL(DMX_SET_FILTER) COMPATIBLE_IOCTL(DMX_SET_PES_FILTER) COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE) COMPATIBLE_IOCTL(DMX_GET_PES_PIDS) -COMPATIBLE_IOCTL(DMX_GET_CAPS) -COMPATIBLE_IOCTL(DMX_SET_SOURCE) COMPATIBLE_IOCTL(DMX_GET_STC) COMPATIBLE_IOCTL(FE_GET_INFO) COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD) diff --git a/fs/coredump.c b/fs/coredump.c index 592683711c6432e3a9fa8eabcb95a7934b2b5571..0eec03696707f03d498d1e4596c1c2cfdbb66873 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -161,7 +161,7 @@ static int cn_print_exe_file(struct core_name *cn) if (!exe_file) return cn_esc_printf(cn, "%s (path unknown)", current->comm); - pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); + pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); if (!pathbuf) { ret = -ENOMEM; goto put_exe_file; diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 6181e9526860708df8f906830f76ba454e2bb2af..483784d5eb7362b0a682d7ba745ccbf1eec4a511 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -115,7 +115,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, err = -ENOMEM; goto errout; } - bio->bi_bdev = inode->i_sb->s_bdev; + bio_set_dev(bio, inode->i_sb->s_bdev); bio->bi_iter.bi_sector = pblk << (inode->i_sb->s_blocksize_bits - 9); bio_set_op_attrs(bio, REQ_OP_WRITE, 0); diff --git a/fs/dax.c b/fs/dax.c index 306c2b603fb8aa8845558a2bf8226523e5282cdb..f001d8c72a065173bc4f68733872a4c36413aece 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -42,6 +42,9 @@ #define DAX_WAIT_TABLE_BITS 12 #define DAX_WAIT_TABLE_ENTRIES (1 << DAX_WAIT_TABLE_BITS) +/* The 'colour' (ie low bits) within a PMD of a page offset. */ +#define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) + static wait_queue_head_t wait_table[DAX_WAIT_TABLE_ENTRIES]; static int __init init_dax_wait_table(void) @@ -54,6 +57,40 @@ static int __init init_dax_wait_table(void) } fs_initcall(init_dax_wait_table); +/* + * We use lowest available bit in exceptional entry for locking, one bit for + * the entry size (PMD) and two more to tell us if the entry is a zero page or + * an empty entry that is just used for locking. In total four special bits. + * + * If the PMD bit isn't set the entry has size PAGE_SIZE, and if the ZERO_PAGE + * and EMPTY bits aren't set the entry is a normal DAX entry with a filesystem + * block allocation. + */ +#define RADIX_DAX_SHIFT (RADIX_TREE_EXCEPTIONAL_SHIFT + 4) +#define RADIX_DAX_ENTRY_LOCK (1 << RADIX_TREE_EXCEPTIONAL_SHIFT) +#define RADIX_DAX_PMD (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 1)) +#define RADIX_DAX_ZERO_PAGE (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 2)) +#define RADIX_DAX_EMPTY (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 3)) + +static unsigned long dax_radix_sector(void *entry) +{ + return (unsigned long)entry >> RADIX_DAX_SHIFT; +} + +static void *dax_radix_locked_entry(sector_t sector, unsigned long flags) +{ + return (void *)(RADIX_TREE_EXCEPTIONAL_ENTRY | flags | + ((unsigned long)sector << RADIX_DAX_SHIFT) | + RADIX_DAX_ENTRY_LOCK); +} + +static unsigned int dax_radix_order(void *entry) +{ + if ((unsigned long)entry & RADIX_DAX_PMD) + return PMD_SHIFT - PAGE_SHIFT; + return 0; +} + static int dax_is_pmd_entry(void *entry) { return (unsigned long)entry & RADIX_DAX_PMD; @@ -66,7 +103,7 @@ static int dax_is_pte_entry(void *entry) static int dax_is_zero_entry(void *entry) { - return (unsigned long)entry & RADIX_DAX_HZP; + return (unsigned long)entry & RADIX_DAX_ZERO_PAGE; } static int dax_is_empty_entry(void *entry) @@ -98,7 +135,7 @@ static wait_queue_head_t *dax_entry_waitqueue(struct address_space *mapping, * the range covered by the PMD map to the same bit lock. */ if (dax_is_pmd_entry(entry)) - index &= ~((1UL << (PMD_SHIFT - PAGE_SHIFT)) - 1); + index &= ~PG_PMD_COLOUR; key->mapping = mapping; key->entry_start = index; @@ -120,6 +157,31 @@ static int wake_exceptional_entry_func(wait_queue_entry_t *wait, unsigned int mo return autoremove_wake_function(wait, mode, sync, NULL); } +/* + * We do not necessarily hold the mapping->tree_lock when we call this + * function so it is possible that 'entry' is no longer a valid item in the + * radix tree. This is okay because all we really need to do is to find the + * correct waitqueue where tasks might be waiting for that old 'entry' and + * wake them. + */ +static void dax_wake_mapping_entry_waiter(struct address_space *mapping, + pgoff_t index, void *entry, bool wake_all) +{ + struct exceptional_entry_key key; + wait_queue_head_t *wq; + + wq = dax_entry_waitqueue(mapping, index, entry, &key); + + /* + * Checking for locked entry and prepare_to_wait_exclusive() happens + * under mapping->tree_lock, ditto for entry handling in our callers. + * So at this point all tasks that could have seen our entry locked + * must be in the waitqueue and the following check will see them. + */ + if (waitqueue_active(wq)) + __wake_up(wq, TASK_NORMAL, wake_all ? 0 : 1, &key); +} + /* * Check whether the given slot is locked. The function must be called with * mapping->tree_lock held @@ -181,7 +243,8 @@ static void *get_unlocked_mapping_entry(struct address_space *mapping, for (;;) { entry = __radix_tree_lookup(&mapping->page_tree, index, NULL, &slot); - if (!entry || !radix_tree_exceptional_entry(entry) || + if (!entry || + WARN_ON_ONCE(!radix_tree_exceptional_entry(entry)) || !slot_locked(mapping, slot)) { if (slotp) *slotp = slot; @@ -216,14 +279,9 @@ static void dax_unlock_mapping_entry(struct address_space *mapping, } static void put_locked_mapping_entry(struct address_space *mapping, - pgoff_t index, void *entry) + pgoff_t index) { - if (!radix_tree_exceptional_entry(entry)) { - unlock_page(entry); - put_page(entry); - } else { - dax_unlock_mapping_entry(mapping, index); - } + dax_unlock_mapping_entry(mapping, index); } /* @@ -233,7 +291,7 @@ static void put_locked_mapping_entry(struct address_space *mapping, static void put_unlocked_mapping_entry(struct address_space *mapping, pgoff_t index, void *entry) { - if (!radix_tree_exceptional_entry(entry)) + if (!entry) return; /* We have to wake up next waiter for the radix tree entry lock */ @@ -241,15 +299,15 @@ static void put_unlocked_mapping_entry(struct address_space *mapping, } /* - * Find radix tree entry at given index. If it points to a page, return with - * the page locked. If it points to the exceptional entry, return with the - * radix tree entry locked. If the radix tree doesn't contain given index, - * create empty exceptional entry for the index and return with it locked. + * Find radix tree entry at given index. If it points to an exceptional entry, + * return it with the radix tree entry locked. If the radix tree doesn't + * contain given index, create an empty exceptional entry for the index and + * return with it locked. * * When requesting an entry with size RADIX_DAX_PMD, grab_mapping_entry() will * either return that locked entry or will return an error. This error will - * happen if there are any 4k entries (either zero pages or DAX entries) - * within the 2MiB range that we are requesting. + * happen if there are any 4k entries within the 2MiB range that we are + * requesting. * * We always favor 4k entries over 2MiB entries. There isn't a flow where we * evict 4k entries in order to 'upgrade' them to a 2MiB entry. A 2MiB @@ -276,18 +334,21 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, spin_lock_irq(&mapping->tree_lock); entry = get_unlocked_mapping_entry(mapping, index, &slot); + if (WARN_ON_ONCE(entry && !radix_tree_exceptional_entry(entry))) { + entry = ERR_PTR(-EIO); + goto out_unlock; + } + if (entry) { if (size_flag & RADIX_DAX_PMD) { - if (!radix_tree_exceptional_entry(entry) || - dax_is_pte_entry(entry)) { + if (dax_is_pte_entry(entry)) { put_unlocked_mapping_entry(mapping, index, entry); entry = ERR_PTR(-EEXIST); goto out_unlock; } } else { /* trying to grab a PTE entry */ - if (radix_tree_exceptional_entry(entry) && - dax_is_pmd_entry(entry) && + if (dax_is_pmd_entry(entry) && (dax_is_zero_entry(entry) || dax_is_empty_entry(entry))) { pmd_downgrade = true; @@ -321,7 +382,7 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM); if (err) { if (pmd_downgrade) - put_locked_mapping_entry(mapping, index, entry); + put_locked_mapping_entry(mapping, index); return ERR_PTR(err); } spin_lock_irq(&mapping->tree_lock); @@ -371,52 +432,12 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, spin_unlock_irq(&mapping->tree_lock); return entry; } - /* Normal page in radix tree? */ - if (!radix_tree_exceptional_entry(entry)) { - struct page *page = entry; - - get_page(page); - spin_unlock_irq(&mapping->tree_lock); - lock_page(page); - /* Page got truncated? Retry... */ - if (unlikely(page->mapping != mapping)) { - unlock_page(page); - put_page(page); - goto restart; - } - return page; - } entry = lock_slot(mapping, slot); out_unlock: spin_unlock_irq(&mapping->tree_lock); return entry; } -/* - * We do not necessarily hold the mapping->tree_lock when we call this - * function so it is possible that 'entry' is no longer a valid item in the - * radix tree. This is okay because all we really need to do is to find the - * correct waitqueue where tasks might be waiting for that old 'entry' and - * wake them. - */ -void dax_wake_mapping_entry_waiter(struct address_space *mapping, - pgoff_t index, void *entry, bool wake_all) -{ - struct exceptional_entry_key key; - wait_queue_head_t *wq; - - wq = dax_entry_waitqueue(mapping, index, entry, &key); - - /* - * Checking for locked entry and prepare_to_wait_exclusive() happens - * under mapping->tree_lock, ditto for entry handling in our callers. - * So at this point all tasks that could have seen our entry locked - * must be in the waitqueue and the following check will see them. - */ - if (waitqueue_active(wq)) - __wake_up(wq, TASK_NORMAL, wake_all ? 0 : 1, &key); -} - static int __dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index, bool trunc) { @@ -426,7 +447,7 @@ static int __dax_invalidate_mapping_entry(struct address_space *mapping, spin_lock_irq(&mapping->tree_lock); entry = get_unlocked_mapping_entry(mapping, index, NULL); - if (!entry || !radix_tree_exceptional_entry(entry)) + if (!entry || WARN_ON_ONCE(!radix_tree_exceptional_entry(entry))) goto out; if (!trunc && (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) || @@ -468,50 +489,6 @@ int dax_invalidate_mapping_entry_sync(struct address_space *mapping, return __dax_invalidate_mapping_entry(mapping, index, false); } -/* - * The user has performed a load from a hole in the file. Allocating - * a new page in the file would cause excessive storage usage for - * workloads with sparse files. We allocate a page cache page instead. - * We'll kick it out of the page cache if it's ever written to, - * otherwise it will simply fall out of the page cache under memory - * pressure without ever having been dirtied. - */ -static int dax_load_hole(struct address_space *mapping, void **entry, - struct vm_fault *vmf) -{ - struct inode *inode = mapping->host; - struct page *page; - int ret; - - /* Hole page already exists? Return it... */ - if (!radix_tree_exceptional_entry(*entry)) { - page = *entry; - goto finish_fault; - } - - /* This will replace locked radix tree entry with a hole page */ - page = find_or_create_page(mapping, vmf->pgoff, - vmf->gfp_mask | __GFP_ZERO); - if (!page) { - ret = VM_FAULT_OOM; - goto out; - } - -finish_fault: - vmf->page = page; - ret = finish_fault(vmf); - vmf->page = NULL; - *entry = page; - if (!ret) { - /* Grab reference for PTE that is now referencing the page */ - get_page(page); - ret = VM_FAULT_NOPAGE; - } -out: - trace_dax_load_hole(inode, vmf, ret); - return ret; -} - static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev, sector_t sector, size_t size, struct page *to, unsigned long vaddr) @@ -552,47 +529,27 @@ static void *dax_insert_mapping_entry(struct address_space *mapping, unsigned long flags) { struct radix_tree_root *page_tree = &mapping->page_tree; - int error = 0; - bool hole_fill = false; void *new_entry; pgoff_t index = vmf->pgoff; if (vmf->flags & FAULT_FLAG_WRITE) __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); - /* Replacing hole page with block mapping? */ - if (!radix_tree_exceptional_entry(entry)) { - hole_fill = true; - /* - * Unmap the page now before we remove it from page cache below. - * The page is locked so it cannot be faulted in again. - */ - unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT, - PAGE_SIZE, 0); - error = radix_tree_preload(vmf->gfp_mask & ~__GFP_HIGHMEM); - if (error) - return ERR_PTR(error); - } else if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_HZP)) { - /* replacing huge zero page with PMD block mapping */ - unmap_mapping_range(mapping, - (vmf->pgoff << PAGE_SHIFT) & PMD_MASK, PMD_SIZE, 0); + if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_ZERO_PAGE)) { + /* we are replacing a zero page with block mapping */ + if (dax_is_pmd_entry(entry)) + unmap_mapping_range(mapping, + (vmf->pgoff << PAGE_SHIFT) & PMD_MASK, + PMD_SIZE, 0); + else /* pte entry */ + unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT, + PAGE_SIZE, 0); } spin_lock_irq(&mapping->tree_lock); new_entry = dax_radix_locked_entry(sector, flags); - if (hole_fill) { - __delete_from_page_cache(entry, NULL); - /* Drop pagecache reference */ - put_page(entry); - error = __radix_tree_insert(page_tree, index, - dax_radix_order(new_entry), new_entry); - if (error) { - new_entry = ERR_PTR(error); - goto unlock; - } - mapping->nrexceptional++; - } else if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry)) { + if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry)) { /* * Only swap our new entry into the radix tree if the current * entry is a zero page or an empty entry. If a normal PTE or @@ -609,23 +566,14 @@ static void *dax_insert_mapping_entry(struct address_space *mapping, WARN_ON_ONCE(ret != entry); __radix_tree_replace(page_tree, node, slot, new_entry, NULL, NULL); + entry = new_entry; } + if (vmf->flags & FAULT_FLAG_WRITE) radix_tree_tag_set(page_tree, index, PAGECACHE_TAG_DIRTY); - unlock: + spin_unlock_irq(&mapping->tree_lock); - if (hole_fill) { - radix_tree_preload_end(); - /* - * We don't need hole page anymore, it has been replaced with - * locked radix tree entry now. - */ - if (mapping->a_ops->freepage) - mapping->a_ops->freepage(entry); - unlock_page(entry); - put_page(entry); - } - return new_entry; + return entry; } static inline unsigned long @@ -646,11 +594,10 @@ static void dax_mapping_entry_mkclean(struct address_space *mapping, pte_t pte, *ptep = NULL; pmd_t *pmdp = NULL; spinlock_t *ptl; - bool changed; i_mmap_lock_read(mapping); vma_interval_tree_foreach(vma, &mapping->i_mmap, index, index) { - unsigned long address; + unsigned long address, start, end; cond_resched(); @@ -658,8 +605,13 @@ static void dax_mapping_entry_mkclean(struct address_space *mapping, continue; address = pgoff_address(index, vma); - changed = false; - if (follow_pte_pmd(vma->vm_mm, address, &ptep, &pmdp, &ptl)) + + /* + * Note because we provide start/end to follow_pte_pmd it will + * call mmu_notifier_invalidate_range_start() on our behalf + * before taking any lock. + */ + if (follow_pte_pmd(vma->vm_mm, address, &start, &end, &ptep, &pmdp, &ptl)) continue; if (pmdp) { @@ -676,7 +628,7 @@ static void dax_mapping_entry_mkclean(struct address_space *mapping, pmd = pmd_wrprotect(pmd); pmd = pmd_mkclean(pmd); set_pmd_at(vma->vm_mm, address, pmdp, pmd); - changed = true; + mmu_notifier_invalidate_range(vma->vm_mm, start, end); unlock_pmd: spin_unlock(ptl); #endif @@ -691,13 +643,12 @@ static void dax_mapping_entry_mkclean(struct address_space *mapping, pte = pte_wrprotect(pte); pte = pte_mkclean(pte); set_pte_at(vma->vm_mm, address, ptep, pte); - changed = true; + mmu_notifier_invalidate_range(vma->vm_mm, start, end); unlock_pte: pte_unmap_unlock(ptep, ptl); } - if (changed) - mmu_notifier_invalidate_page(vma->vm_mm, address); + mmu_notifier_invalidate_range_end(vma->vm_mm, start, end); } i_mmap_unlock_read(mapping); } @@ -724,7 +675,7 @@ static int dax_writeback_one(struct block_device *bdev, spin_lock_irq(&mapping->tree_lock); entry2 = get_unlocked_mapping_entry(mapping, index, &slot); /* Entry got punched out / reallocated? */ - if (!entry2 || !radix_tree_exceptional_entry(entry2)) + if (!entry2 || WARN_ON_ONCE(!radix_tree_exceptional_entry(entry2))) goto put_unlocked; /* * Entry got reallocated elsewhere? No need to writeback. We have to @@ -783,7 +734,7 @@ static int dax_writeback_one(struct block_device *bdev, } dax_mapping_entry_mkclean(mapping, index, pfn_t_to_pfn(pfn)); - dax_flush(dax_dev, pgoff, kaddr, size); + dax_flush(dax_dev, kaddr, size); /* * After we have flushed the cache, we can clear the dirty tag. There * cannot be new dirty data in the pfn after the flush has completed as @@ -796,7 +747,7 @@ static int dax_writeback_one(struct block_device *bdev, trace_dax_writeback_one(mapping->host, index, size >> PAGE_SHIFT); dax_unlock: dax_read_unlock(id); - put_locked_mapping_entry(mapping, index, entry); + put_locked_mapping_entry(mapping, index); return ret; put_unlocked: @@ -871,11 +822,10 @@ EXPORT_SYMBOL_GPL(dax_writeback_mapping_range); static int dax_insert_mapping(struct address_space *mapping, struct block_device *bdev, struct dax_device *dax_dev, - sector_t sector, size_t size, void **entryp, + sector_t sector, size_t size, void *entry, struct vm_area_struct *vma, struct vm_fault *vmf) { unsigned long vaddr = vmf->address; - void *entry = *entryp; void *ret, *kaddr; pgoff_t pgoff; int id, rc; @@ -896,47 +846,48 @@ static int dax_insert_mapping(struct address_space *mapping, ret = dax_insert_mapping_entry(mapping, vmf, entry, sector, 0); if (IS_ERR(ret)) return PTR_ERR(ret); - *entryp = ret; trace_dax_insert_mapping(mapping->host, vmf, ret); - return vm_insert_mixed(vma, vaddr, pfn); + if (vmf->flags & FAULT_FLAG_WRITE) + return vm_insert_mixed_mkwrite(vma, vaddr, pfn); + else + return vm_insert_mixed(vma, vaddr, pfn); } -/** - * dax_pfn_mkwrite - handle first write to DAX page - * @vmf: The description of the fault +/* + * The user has performed a load from a hole in the file. Allocating a new + * page in the file would cause excessive storage usage for workloads with + * sparse files. Instead we insert a read-only mapping of the 4k zero page. + * If this page is ever written to we will re-fault and change the mapping to + * point to real DAX storage instead. */ -int dax_pfn_mkwrite(struct vm_fault *vmf) +static int dax_load_hole(struct address_space *mapping, void *entry, + struct vm_fault *vmf) { - struct file *file = vmf->vma->vm_file; - struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; - void *entry, **slot; - pgoff_t index = vmf->pgoff; + unsigned long vaddr = vmf->address; + int ret = VM_FAULT_NOPAGE; + struct page *zero_page; + void *entry2; - spin_lock_irq(&mapping->tree_lock); - entry = get_unlocked_mapping_entry(mapping, index, &slot); - if (!entry || !radix_tree_exceptional_entry(entry)) { - if (entry) - put_unlocked_mapping_entry(mapping, index, entry); - spin_unlock_irq(&mapping->tree_lock); - trace_dax_pfn_mkwrite_no_entry(inode, vmf, VM_FAULT_NOPAGE); - return VM_FAULT_NOPAGE; + zero_page = ZERO_PAGE(0); + if (unlikely(!zero_page)) { + ret = VM_FAULT_OOM; + goto out; } - radix_tree_tag_set(&mapping->page_tree, index, PAGECACHE_TAG_DIRTY); - entry = lock_slot(mapping, slot); - spin_unlock_irq(&mapping->tree_lock); - /* - * If we race with somebody updating the PTE and finish_mkwrite_fault() - * fails, we don't care. We need to return VM_FAULT_NOPAGE and retry - * the fault in either case. - */ - finish_mkwrite_fault(vmf); - put_locked_mapping_entry(mapping, index, entry); - trace_dax_pfn_mkwrite(inode, vmf, VM_FAULT_NOPAGE); - return VM_FAULT_NOPAGE; + + entry2 = dax_insert_mapping_entry(mapping, vmf, entry, 0, + RADIX_DAX_ZERO_PAGE); + if (IS_ERR(entry2)) { + ret = VM_FAULT_SIGBUS; + goto out; + } + + vm_insert_mixed(vmf->vma, vaddr, page_to_pfn_t(zero_page)); +out: + trace_dax_load_hole(inode, vmf, ret); + return ret; } -EXPORT_SYMBOL_GPL(dax_pfn_mkwrite); static bool dax_range_is_aligned(struct block_device *bdev, unsigned int offset, unsigned int length) @@ -978,7 +929,7 @@ int __dax_zero_page_range(struct block_device *bdev, return rc; } memset(kaddr + offset, 0, size); - dax_flush(dax_dev, pgoff, kaddr + offset, size); + dax_flush(dax_dev, kaddr + offset, size); dax_read_unlock(id); } return 0; @@ -1056,6 +1007,11 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data, if (map_len > end - pos) map_len = end - pos; + /* + * The userspace address for the memory copy has already been + * validated via access_ok() in either vfs_read() or + * vfs_write(), depending on which operation we are doing. + */ if (iov_iter_rw(iter) == WRITE) map_len = dax_copy_from_iter(dax_dev, pgoff, kaddr, map_len, iter); @@ -1220,7 +1176,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, major = VM_FAULT_MAJOR; } error = dax_insert_mapping(mapping, iomap.bdev, iomap.dax_dev, - sector, PAGE_SIZE, &entry, vmf->vma, vmf); + sector, PAGE_SIZE, entry, vmf->vma, vmf); /* -EBUSY is fine, somebody else faulted on the same PTE */ if (error == -EBUSY) error = 0; @@ -1228,7 +1184,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, case IOMAP_UNWRITTEN: case IOMAP_HOLE: if (!(vmf->flags & FAULT_FLAG_WRITE)) { - vmf_ret = dax_load_hole(mapping, &entry, vmf); + vmf_ret = dax_load_hole(mapping, entry, vmf); goto finish_iomap; } /*FALLTHRU*/ @@ -1255,21 +1211,15 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, ops->iomap_end(inode, pos, PAGE_SIZE, copied, flags, &iomap); } unlock_entry: - put_locked_mapping_entry(mapping, vmf->pgoff, entry); + put_locked_mapping_entry(mapping, vmf->pgoff); out: trace_dax_pte_fault_done(inode, vmf, vmf_ret); return vmf_ret; } #ifdef CONFIG_FS_DAX_PMD -/* - * The 'colour' (ie low bits) within a PMD of a page offset. This comes up - * more often than one might expect in the below functions. - */ -#define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) - static int dax_pmd_insert_mapping(struct vm_fault *vmf, struct iomap *iomap, - loff_t pos, void **entryp) + loff_t pos, void *entry) { struct address_space *mapping = vmf->vma->vm_file->f_mapping; const sector_t sector = dax_iomap_sector(iomap, pos); @@ -1280,7 +1230,7 @@ static int dax_pmd_insert_mapping(struct vm_fault *vmf, struct iomap *iomap, void *ret = NULL, *kaddr; long length = 0; pgoff_t pgoff; - pfn_t pfn; + pfn_t pfn = {}; int id; if (bdev_dax_pgoff(bdev, sector, size, &pgoff) != 0) @@ -1300,11 +1250,10 @@ static int dax_pmd_insert_mapping(struct vm_fault *vmf, struct iomap *iomap, goto unlock_fallback; dax_read_unlock(id); - ret = dax_insert_mapping_entry(mapping, vmf, *entryp, sector, + ret = dax_insert_mapping_entry(mapping, vmf, entry, sector, RADIX_DAX_PMD); if (IS_ERR(ret)) goto fallback; - *entryp = ret; trace_dax_pmd_insert_mapping(inode, vmf, length, pfn, ret); return vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd, @@ -1318,7 +1267,7 @@ static int dax_pmd_insert_mapping(struct vm_fault *vmf, struct iomap *iomap, } static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, - void **entryp) + void *entry) { struct address_space *mapping = vmf->vma->vm_file->f_mapping; unsigned long pmd_addr = vmf->address & PMD_MASK; @@ -1333,11 +1282,10 @@ static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, if (unlikely(!zero_page)) goto fallback; - ret = dax_insert_mapping_entry(mapping, vmf, *entryp, 0, - RADIX_DAX_PMD | RADIX_DAX_HZP); + ret = dax_insert_mapping_entry(mapping, vmf, entry, 0, + RADIX_DAX_PMD | RADIX_DAX_ZERO_PAGE); if (IS_ERR(ret)) goto fallback; - *entryp = ret; ptl = pmd_lock(vmf->vma->vm_mm, vmf->pmd); if (!pmd_none(*(vmf->pmd))) { @@ -1383,6 +1331,16 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, trace_dax_pmd_fault(inode, vmf, max_pgoff, 0); + /* + * Make sure that the faulting address's PMD offset (color) matches + * the PMD offset from the start of the file. This is necessary so + * that a PMD range in the page table overlaps exactly with a PMD + * range in the radix tree. + */ + if ((vmf->pgoff & PG_PMD_COLOUR) != + ((vmf->address >> PAGE_SHIFT) & PG_PMD_COLOUR)) + goto fallback; + /* Fall back to PTEs if we're going to COW */ if (write && !(vma->vm_flags & VM_SHARED)) goto fallback; @@ -1403,10 +1361,10 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, goto fallback; /* - * grab_mapping_entry() will make sure we get a 2M empty entry, a DAX - * PMD or a HZP entry. If it can't (because a 4k page is already in - * the tree, for instance), it will return -EEXIST and we just fall - * back to 4k entries. + * grab_mapping_entry() will make sure we get a 2MiB empty entry, a + * 2MiB zero page entry or a DAX PMD. If it can't (because a 4k page + * is already in the tree, for instance), it will return -EEXIST and + * we just fall back to 4k entries. */ entry = grab_mapping_entry(mapping, pgoff, RADIX_DAX_PMD); if (IS_ERR(entry)) @@ -1439,13 +1397,13 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, switch (iomap.type) { case IOMAP_MAPPED: - result = dax_pmd_insert_mapping(vmf, &iomap, pos, &entry); + result = dax_pmd_insert_mapping(vmf, &iomap, pos, entry); break; case IOMAP_UNWRITTEN: case IOMAP_HOLE: if (WARN_ON_ONCE(write)) break; - result = dax_pmd_load_hole(vmf, &iomap, &entry); + result = dax_pmd_load_hole(vmf, &iomap, entry); break; default: WARN_ON_ONCE(1); @@ -1468,7 +1426,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, &iomap); } unlock_entry: - put_locked_mapping_entry(mapping, pgoff, entry); + put_locked_mapping_entry(mapping, pgoff); fallback: if (result == VM_FAULT_FALLBACK) { split_huge_pmd(vma, vmf->pmd, vmf->address); diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 108df2e3602c2c63186b61b2fede52794cb46482..7eae33ffa3fcc1d709790b79225521472c6f8281 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -133,6 +133,50 @@ static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb) return sb->s_fs_info; } +static int devpts_ptmx_path(struct path *path) +{ + struct super_block *sb; + int err; + + /* Has the devpts filesystem already been found? */ + if (path->mnt->mnt_sb->s_magic == DEVPTS_SUPER_MAGIC) + return 0; + + /* Is a devpts filesystem at "pts" in the same directory? */ + err = path_pts(path); + if (err) + return err; + + /* Is the path the root of a devpts filesystem? */ + sb = path->mnt->mnt_sb; + if ((sb->s_magic != DEVPTS_SUPER_MAGIC) || + (path->mnt->mnt_root != sb->s_root)) + return -ENODEV; + + return 0; +} + +struct vfsmount *devpts_mntget(struct file *filp, struct pts_fs_info *fsi) +{ + struct path path; + int err; + + path = filp->f_path; + path_get(&path); + + err = devpts_ptmx_path(&path); + dput(path.dentry); + if (err) { + mntput(path.mnt); + path.mnt = ERR_PTR(err); + } + if (DEVPTS_SB(path.mnt->mnt_sb) != fsi) { + mntput(path.mnt); + path.mnt = ERR_PTR(-ENODEV); + } + return path.mnt; +} + struct pts_fs_info *devpts_acquire(struct file *filp) { struct pts_fs_info *result; @@ -143,27 +187,16 @@ struct pts_fs_info *devpts_acquire(struct file *filp) path = filp->f_path; path_get(&path); - /* Has the devpts filesystem already been found? */ - sb = path.mnt->mnt_sb; - if (sb->s_magic != DEVPTS_SUPER_MAGIC) { - /* Is a devpts filesystem at "pts" in the same directory? */ - err = path_pts(&path); - if (err) { - result = ERR_PTR(err); - goto out; - } - - /* Is the path the root of a devpts filesystem? */ - result = ERR_PTR(-ENODEV); - sb = path.mnt->mnt_sb; - if ((sb->s_magic != DEVPTS_SUPER_MAGIC) || - (path.mnt->mnt_root != sb->s_root)) - goto out; + err = devpts_ptmx_path(&path); + if (err) { + result = ERR_PTR(err); + goto out; } /* * pty code needs to hold extra references in case of last /dev/tty close */ + sb = path.mnt->mnt_sb; atomic_inc(&sb->s_active); result = DEVPTS_SB(sb); diff --git a/fs/direct-io.c b/fs/direct-io.c index 08cf27811e5af22b62a5330a2f21b0d0af25de77..62cf812ed0e5803ac9148a9ea8a27f00efca7f2a 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -111,7 +111,7 @@ struct dio { int op; int op_flags; blk_qc_t bio_cookie; - struct block_device *bio_bdev; + struct gendisk *bio_disk; struct inode *inode; loff_t i_size; /* i_size when submitted */ dio_iodone_t *end_io; /* IO completion function */ @@ -229,6 +229,7 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async) { loff_t offset = dio->iocb->ki_pos; ssize_t transferred = 0; + int err; /* * AIO submission can race with bio completion to get here while @@ -258,8 +259,22 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async) if (ret == 0) ret = transferred; + /* + * Try again to invalidate clean pages which might have been cached by + * non-direct readahead, or faulted in by get_user_pages() if the source + * of the write was an mmap'ed region of the file we're writing. Either + * one is a pretty crazy thing to do, so we don't support it 100%. If + * this invalidation fails, tough, the write still worked... + */ + if (ret > 0 && dio->op == REQ_OP_WRITE && + dio->inode->i_mapping->nrpages) { + err = invalidate_inode_pages2_range(dio->inode->i_mapping, + offset >> PAGE_SHIFT, + (offset + ret - 1) >> PAGE_SHIFT); + WARN_ON_ONCE(err); + } + if (dio->end_io) { - int err; // XXX: ki_pos?? err = dio->end_io(dio->iocb, offset, ret, dio->private); @@ -304,6 +319,7 @@ static void dio_bio_end_aio(struct bio *bio) struct dio *dio = bio->bi_private; unsigned long remaining; unsigned long flags; + bool defer_completion = false; /* cleanup the bio */ dio_bio_complete(dio, bio); @@ -315,7 +331,19 @@ static void dio_bio_end_aio(struct bio *bio) spin_unlock_irqrestore(&dio->bio_lock, flags); if (remaining == 0) { - if (dio->result && dio->defer_completion) { + /* + * Defer completion when defer_completion is set or + * when the inode has pages mapped and this is AIO write. + * We need to invalidate those pages because there is a + * chance they contain stale data in the case buffered IO + * went in between AIO submission and completion into the + * same region. + */ + if (dio->result) + defer_completion = dio->defer_completion || + (dio->op == REQ_OP_WRITE && + dio->inode->i_mapping->nrpages); + if (defer_completion) { INIT_WORK(&dio->complete_work, dio_aio_complete_work); queue_work(dio->inode->i_sb->s_dio_done_wq, &dio->complete_work); @@ -377,7 +405,7 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio, */ bio = bio_alloc(GFP_KERNEL, nr_vecs); - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector = first_sector; bio_set_op_attrs(bio, dio->op, dio->op_flags); if (dio->is_async) @@ -412,7 +440,7 @@ static inline void dio_bio_submit(struct dio *dio, struct dio_submit *sdio) if (dio->is_async && dio->op == REQ_OP_READ && dio->should_dirty) bio_set_pages_dirty(bio); - dio->bio_bdev = bio->bi_bdev; + dio->bio_disk = bio->bi_disk; if (sdio->submit_io) { sdio->submit_io(bio, dio->inode, sdio->logical_offset_in_bio); @@ -458,7 +486,7 @@ static struct bio *dio_await_one(struct dio *dio) dio->waiter = current; spin_unlock_irqrestore(&dio->bio_lock, flags); if (!(dio->iocb->ki_flags & IOCB_HIPRI) || - !blk_mq_poll(bdev_get_queue(dio->bio_bdev), dio->bio_cookie)) + !blk_mq_poll(dio->bio_disk->queue, dio->bio_cookie)) io_schedule(); /* wake up sets us TASK_RUNNING */ spin_lock_irqsave(&dio->bio_lock, flags); @@ -1210,10 +1238,19 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, * For AIO O_(D)SYNC writes we need to defer completions to a workqueue * so that we can call ->fsync. */ - if (dio->is_async && iov_iter_rw(iter) == WRITE && - ((iocb->ki_filp->f_flags & O_DSYNC) || - IS_SYNC(iocb->ki_filp->f_mapping->host))) { - retval = dio_set_defer_completion(dio); + if (dio->is_async && iov_iter_rw(iter) == WRITE) { + retval = 0; + if ((iocb->ki_filp->f_flags & O_DSYNC) || + IS_SYNC(iocb->ki_filp->f_mapping->host)) + retval = dio_set_defer_completion(dio); + else if (!dio->inode->i_sb->s_dio_done_wq) { + /* + * In case of AIO write racing with buffered read we + * need to defer completion. We can't decide this now, + * however the workqueue needs to be initialized here. + */ + retval = sb_init_dio_done_wq(dio->inode->i_sb); + } if (retval) { /* * We grab i_mutex only for reads so we don't have diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index ca7089aeadabb5c0801fdc337a681c82aadfff14..fa08448e35dd7dd50fedaae4b95e48e974d343c4 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -68,7 +68,7 @@ static void print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb, if (lkb->lkb_wait_type) seq_printf(s, " wait_type: %d", lkb->lkb_wait_type); - seq_puts(s, "\n"); + seq_putc(s, '\n'); } static void print_format1(struct dlm_rsb *res, struct seq_file *s) @@ -111,7 +111,7 @@ static void print_format1(struct dlm_rsb *res, struct seq_file *s) } if (rsb_flag(res, RSB_VALNOTVALID)) seq_puts(s, " (INVALID)"); - seq_puts(s, "\n"); + seq_putc(s, '\n'); if (seq_has_overflowed(s)) goto out; } @@ -156,7 +156,7 @@ static void print_format1(struct dlm_rsb *res, struct seq_file *s) lkb->lkb_id, print_lockmode(lkb->lkb_rqmode)); if (lkb->lkb_wait_type) seq_printf(s, " wait_type: %d", lkb->lkb_wait_type); - seq_puts(s, "\n"); + seq_putc(s, '\n'); if (seq_has_overflowed(s)) goto out; } @@ -287,7 +287,7 @@ static void print_format3(struct dlm_rsb *r, struct seq_file *s) else seq_printf(s, " %02x", (unsigned char)r->res_name[i]); } - seq_puts(s, "\n"); + seq_putc(s, '\n'); if (seq_has_overflowed(s)) goto out; @@ -298,7 +298,7 @@ static void print_format3(struct dlm_rsb *r, struct seq_file *s) for (i = 0; i < lvblen; i++) seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]); - seq_puts(s, "\n"); + seq_putc(s, '\n'); if (seq_has_overflowed(s)) goto out; @@ -361,8 +361,7 @@ static void print_format4(struct dlm_rsb *r, struct seq_file *s) else seq_printf(s, " %02x", (unsigned char)r->res_name[i]); } - seq_puts(s, "\n"); - + seq_putc(s, '\n'); unlock_rsb(r); } @@ -436,7 +435,7 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos) if (bucket >= ls->ls_rsbtbl_size) return NULL; - ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_NOFS); + ri = kzalloc(sizeof(*ri), GFP_NOFS); if (!ri) return NULL; if (n == 0) @@ -742,7 +741,7 @@ void dlm_delete_debug_file(struct dlm_ls *ls) int dlm_create_debug_file(struct dlm_ls *ls) { - char name[DLM_LOCKSPACE_LEN+8]; + char name[DLM_LOCKSPACE_LEN + 8]; /* format 1 */ @@ -757,7 +756,7 @@ int dlm_create_debug_file(struct dlm_ls *ls) /* format 2 */ memset(name, 0, sizeof(name)); - snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name); + snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_locks", ls->ls_name); ls->ls_debug_locks_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, @@ -770,7 +769,7 @@ int dlm_create_debug_file(struct dlm_ls *ls) /* format 3 */ memset(name, 0, sizeof(name)); - snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_all", ls->ls_name); + snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_all", ls->ls_name); ls->ls_debug_all_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, @@ -783,7 +782,7 @@ int dlm_create_debug_file(struct dlm_ls *ls) /* format 4 */ memset(name, 0, sizeof(name)); - snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_toss", ls->ls_name); + snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_toss", ls->ls_name); ls->ls_debug_toss_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, @@ -794,7 +793,7 @@ int dlm_create_debug_file(struct dlm_ls *ls) goto fail; memset(name, 0, sizeof(name)); - snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name); + snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_waiters", ls->ls_name); ls->ls_debug_waiters_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 6df332296c661a688289da35e890f89696bfdccb..d4aaddec1b16207c6ae394075b31110b8cead77d 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1426,7 +1426,7 @@ void dlm_scan_waiters(struct dlm_ls *ls) if (!num_nodes) { num_nodes = ls->ls_num_nodes; - warned = kzalloc(num_nodes * sizeof(int), GFP_KERNEL); + warned = kcalloc(num_nodes, sizeof(int), GFP_KERNEL); } if (!warned) continue; @@ -5119,11 +5119,9 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) int wait_type, stub_unlock_result, stub_cancel_result; int dir_nodeid; - ms_stub = kmalloc(sizeof(struct dlm_message), GFP_KERNEL); - if (!ms_stub) { - log_error(ls, "dlm_recover_waiters_pre no mem"); + ms_stub = kmalloc(sizeof(*ms_stub), GFP_KERNEL); + if (!ms_stub) return; - } mutex_lock(&ls->ls_waiters_mutex); diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 91592b75c309adf729710613c3fc572831782618..78a7c855b06b374f87223b41282cdae1c8f798e8 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -235,7 +235,7 @@ static int dlm_uevent(struct kset *kset, struct kobject *kobj, return 0; } -static struct kset_uevent_ops dlm_uevent_ops = { +static const struct kset_uevent_ops dlm_uevent_ops = { .uevent = dlm_uevent, }; @@ -453,9 +453,14 @@ static int new_lockspace(const char *name, const char *cluster, *ops_result = 0; } + if (!cluster) + log_print("dlm cluster name '%s' is being used without an application provided cluster name", + dlm_config.ci_cluster_name); + if (dlm_config.ci_recover_callbacks && cluster && strncmp(cluster, dlm_config.ci_cluster_name, DLM_LOCKSPACE_LEN)) { - log_print("dlm cluster name %s mismatch %s", + log_print("dlm cluster name '%s' does not match " + "the application cluster name '%s'", dlm_config.ci_cluster_name, cluster); error = -EBADR; goto out; diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 9382db998ec9549319f47b55ccd561abf1169874..4813d0e0cd9babf3f9f64c95da0f40bbe2131781 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -729,7 +729,7 @@ static int tcp_accept_from_sock(struct connection *con) mutex_unlock(&connections_lock); memset(&peeraddr, 0, sizeof(peeraddr)); - result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, + result = sock_create_lite(dlm_local_addr[0]->ss_family, SOCK_STREAM, IPPROTO_TCP, &newsock); if (result < 0) return -ENOMEM; diff --git a/fs/dlm/member.c b/fs/dlm/member.c index 9c47f1c14a8badb59048a88cf33b674e93a679e4..3fda3832cf6a62761e5aa8294c4c1e81919267eb 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -217,8 +217,7 @@ int dlm_slots_assign(struct dlm_ls *ls, int *num_slots, int *slots_size, } array_size = max + need; - - array = kzalloc(array_size * sizeof(struct dlm_slot), GFP_NOFS); + array = kcalloc(array_size, sizeof(*array), GFP_NOFS); if (!array) return -ENOMEM; @@ -319,7 +318,7 @@ static int dlm_add_member(struct dlm_ls *ls, struct dlm_config_node *node) struct dlm_member *memb; int error; - memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS); + memb = kzalloc(sizeof(*memb), GFP_NOFS); if (!memb) return -ENOMEM; @@ -405,8 +404,7 @@ static void make_member_array(struct dlm_ls *ls) } ls->ls_total_weight = total; - - array = kmalloc(sizeof(int) * total, GFP_NOFS); + array = kmalloc_array(total, sizeof(*array), GFP_NOFS); if (!array) return; @@ -492,8 +490,7 @@ void dlm_lsop_recover_done(struct dlm_ls *ls) return; num = ls->ls_num_nodes; - - slots = kzalloc(num * sizeof(struct dlm_slot), GFP_KERNEL); + slots = kcalloc(num, sizeof(*slots), GFP_KERNEL); if (!slots) return; @@ -673,11 +670,11 @@ int dlm_ls_stop(struct dlm_ls *ls) int dlm_ls_start(struct dlm_ls *ls) { - struct dlm_recover *rv = NULL, *rv_old; + struct dlm_recover *rv, *rv_old; struct dlm_config_node *nodes; int error, count; - rv = kzalloc(sizeof(struct dlm_recover), GFP_NOFS); + rv = kzalloc(sizeof(*rv), GFP_NOFS); if (!rv) return -ENOMEM; diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index d401425f602a45c9a70828f15ee2f35aee1601b6..e631b16892287064d449f658fd8e3a1e3aa2edff 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -367,7 +367,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, locks_init_lock(fl); fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; fl->fl_flags = FL_POSIX; - fl->fl_pid = op->info.pid; + fl->fl_pid = -op->info.pid; fl->fl_start = op->info.start; fl->fl_end = op->info.end; rv = 0; diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 23488f559cf969180a5c9b827477196acef5ff8e..d18e7a539f116209e3a7d0a972d7ca4a28522a09 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -123,6 +123,8 @@ static void compat_input(struct dlm_write_request *kb, static void compat_output(struct dlm_lock_result *res, struct dlm_lock_result32 *res32) { + memset(res32, 0, sizeof(*res32)); + res32->version[0] = res->version[0]; res32->version[1] = res->version[1]; res32->version[2] = res->version[2]; @@ -355,6 +357,10 @@ static int dlm_device_register(struct dlm_ls *ls, char *name) error = misc_register(&ls->ls_device); if (error) { kfree(ls->ls_device.name); + /* this has to be set to NULL + * to avoid a double-free in dlm_device_deregister + */ + ls->ls_device.name = NULL; } fail: return error; diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index ca4e83750214adc2b0ea77358937c167d02d6ba7..c74ed3ca3372f8b8e91ed9da35de617c7b25ce08 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -328,7 +328,7 @@ ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) { int rc; - rc = filemap_write_and_wait(file->f_mapping); + rc = file_write_and_wait(file); if (rc) return rc; diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 9014479d01600be356b87c284c675ada55b6a723..6b801186baa588ce996ed1a69cb6bc1dfe74b234 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -568,8 +568,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags * 1) The lower mount is ro * 2) The ecryptfs_encrypted_view mount option is specified */ - if (path.dentry->d_sb->s_flags & MS_RDONLY || - mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) + if (sb_rdonly(path.dentry->d_sb) || mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) s->s_flags |= MS_RDONLY; s->s_maxbytes = path.dentry->d_sb->s_maxbytes; diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 039e627194a93b99eca8d20ca483c42598d517ca..c596e7c03424c5ba11ad854e9c939e9eca338e6f 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c @@ -47,7 +47,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; if (!lower_file) return -EIO; - rc = kernel_write(lower_file, data, size, offset); + rc = kernel_write(lower_file, data, size, &offset); mark_inode_dirty_sync(ecryptfs_inode); return rc; } @@ -237,7 +237,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; if (!lower_file) return -EIO; - return kernel_read(lower_file, offset, data, size); + return kernel_read(lower_file, data, size, &offset); } /** diff --git a/fs/efs/super.c b/fs/efs/super.c index 368f7dd21c610e602478603fe1fb5122a2b453b2..5c42f1e34a2ffa10e7135236a84e523f7918718a 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -306,7 +306,7 @@ static int efs_fill_super(struct super_block *s, void *d, int silent) } brelse(bh); - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { #ifdef DEBUG pr_info("forcing read-only mode\n"); #endif diff --git a/fs/eventpoll.c b/fs/eventpoll.c index e767e4389cb13da3525a1e3ec9c2b4e7501f110c..2fabd19cdeea76e32f51f3c84348a22b9fe22843 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -205,7 +205,7 @@ struct eventpoll { struct list_head rdllist; /* RB tree root used to store monitored fd structs */ - struct rb_root rbr; + struct rb_root_cached rbr; /* * This is a single linked list that chains all the "struct epitem" that @@ -600,8 +600,13 @@ static void ep_remove_wait_queue(struct eppoll_entry *pwq) wait_queue_head_t *whead; rcu_read_lock(); - /* If it is cleared by POLLFREE, it should be rcu-safe */ - whead = rcu_dereference(pwq->whead); + /* + * If it is cleared by POLLFREE, it should be rcu-safe. + * If we read NULL we need a barrier paired with + * smp_store_release() in ep_poll_callback(), otherwise + * we rely on whead->lock. + */ + whead = smp_load_acquire(&pwq->whead); if (whead) remove_wait_queue(whead, &pwq->wait); rcu_read_unlock(); @@ -791,7 +796,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) list_del_rcu(&epi->fllink); spin_unlock(&file->f_lock); - rb_erase(&epi->rbn, &ep->rbr); + rb_erase_cached(&epi->rbn, &ep->rbr); spin_lock_irqsave(&ep->lock, flags); if (ep_is_linked(&epi->rdllink)) @@ -835,7 +840,7 @@ static void ep_free(struct eventpoll *ep) /* * Walks through the whole tree by unregistering poll callbacks. */ - for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) { + for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) { epi = rb_entry(rbp, struct epitem, rbn); ep_unregister_pollwait(ep, epi); @@ -851,7 +856,7 @@ static void ep_free(struct eventpoll *ep) * a lockdep warning. */ mutex_lock(&ep->mtx); - while ((rbp = rb_first(&ep->rbr)) != NULL) { + while ((rbp = rb_first_cached(&ep->rbr)) != NULL) { epi = rb_entry(rbp, struct epitem, rbn); ep_remove(ep, epi); cond_resched(); @@ -958,7 +963,7 @@ static void ep_show_fdinfo(struct seq_file *m, struct file *f) struct rb_node *rbp; mutex_lock(&ep->mtx); - for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) { + for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) { struct epitem *epi = rb_entry(rbp, struct epitem, rbn); struct inode *inode = file_inode(epi->ffd.file); @@ -1035,7 +1040,7 @@ static int ep_alloc(struct eventpoll **pep) init_waitqueue_head(&ep->wq); init_waitqueue_head(&ep->poll_wait); INIT_LIST_HEAD(&ep->rdllist); - ep->rbr = RB_ROOT; + ep->rbr = RB_ROOT_CACHED; ep->ovflist = EP_UNACTIVE_PTR; ep->user = user; @@ -1061,7 +1066,7 @@ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd) struct epoll_filefd ffd; ep_set_ffd(&ffd, file, fd); - for (rbp = ep->rbr.rb_node; rbp; ) { + for (rbp = ep->rbr.rb_root.rb_node; rbp; ) { epi = rb_entry(rbp, struct epitem, rbn); kcmp = ep_cmp_ffd(&ffd, &epi->ffd); if (kcmp > 0) @@ -1083,7 +1088,7 @@ static struct epitem *ep_find_tfd(struct eventpoll *ep, int tfd, unsigned long t struct rb_node *rbp; struct epitem *epi; - for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) { + for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) { epi = rb_entry(rbp, struct epitem, rbn); if (epi->ffd.fd == tfd) { if (toff == 0) @@ -1134,17 +1139,6 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v struct eventpoll *ep = epi->ep; int ewake = 0; - if ((unsigned long)key & POLLFREE) { - ep_pwq_from_wait(wait)->whead = NULL; - /* - * whead = NULL above can race with ep_remove_wait_queue() - * which can do another remove_wait_queue() after us, so we - * can't use __remove_wait_queue(). whead->lock is held by - * the caller. - */ - list_del_init(&wait->entry); - } - spin_lock_irqsave(&ep->lock, flags); ep_set_busy_poll_napi_id(epi); @@ -1228,10 +1222,26 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v if (pwake) ep_poll_safewake(&ep->poll_wait); - if (epi->event.events & EPOLLEXCLUSIVE) - return ewake; + if (!(epi->event.events & EPOLLEXCLUSIVE)) + ewake = 1; - return 1; + if ((unsigned long)key & POLLFREE) { + /* + * If we race with ep_remove_wait_queue() it can miss + * ->whead = NULL and do another remove_wait_queue() after + * us, so we can't use __remove_wait_queue(). + */ + list_del_init(&wait->entry); + /* + * ->whead != NULL protects us from the race with ep_free() + * or ep_remove(), ep_remove_wait_queue() takes whead->lock + * held by the caller. Once we nullify it, nothing protects + * ep/epi or even wait. + */ + smp_store_release(&ep_pwq_from_wait(wait)->whead, NULL); + } + + return ewake; } /* @@ -1263,20 +1273,22 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) { int kcmp; - struct rb_node **p = &ep->rbr.rb_node, *parent = NULL; + struct rb_node **p = &ep->rbr.rb_root.rb_node, *parent = NULL; struct epitem *epic; + bool leftmost = true; while (*p) { parent = *p; epic = rb_entry(parent, struct epitem, rbn); kcmp = ep_cmp_ffd(&epi->ffd, &epic->ffd); - if (kcmp > 0) + if (kcmp > 0) { p = &parent->rb_right; - else + leftmost = false; + } else p = &parent->rb_left; } rb_link_node(&epi->rbn, parent, p); - rb_insert_color(&epi->rbn, &ep->rbr); + rb_insert_color_cached(&epi->rbn, &ep->rbr, leftmost); } @@ -1520,7 +1532,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, list_del_rcu(&epi->fllink); spin_unlock(&tfile->f_lock); - rb_erase(&epi->rbn, &ep->rbr); + rb_erase_cached(&epi->rbn, &ep->rbr); error_unregister: ep_unregister_pollwait(ep, epi); @@ -1868,7 +1880,7 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests) mutex_lock_nested(&ep->mtx, call_nests + 1); ep->visited = 1; list_add(&ep->visited_list_link, &visited_list); - for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) { + for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) { epi = rb_entry(rbp, struct epitem, rbn); if (unlikely(is_file_epoll(epi->ffd.file))) { ep_tovisit = epi->ffd.file->private_data; diff --git a/fs/exec.c b/fs/exec.c index 62175cbcc80171df25da8e8bdd07547c83515b06..5470d3c1892af7101dbb4c13d085d4000c558746 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -885,23 +885,6 @@ struct file *open_exec(const char *name) } EXPORT_SYMBOL(open_exec); -int kernel_read(struct file *file, loff_t offset, - char *addr, unsigned long count) -{ - mm_segment_t old_fs; - loff_t pos = offset; - int result; - - old_fs = get_fs(); - set_fs(get_ds()); - /* The cast to a user pointer is valid due to the set_fs() */ - result = vfs_read(file, (void __user *)addr, count, &pos); - set_fs(old_fs); - return result; -} - -EXPORT_SYMBOL(kernel_read); - int kernel_read_file(struct file *file, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id) { @@ -939,8 +922,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, pos = 0; while (pos < i_size) { - bytes = kernel_read(file, pos, (char *)(*buf) + pos, - i_size - pos); + bytes = kernel_read(file, *buf + pos, i_size - pos, &pos); if (bytes < 0) { ret = bytes; goto out; @@ -948,7 +930,6 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, if (bytes == 0) break; - pos += bytes; } if (pos != i_size) { @@ -974,7 +955,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, } EXPORT_SYMBOL_GPL(kernel_read_file); -int kernel_read_file_from_path(char *path, void **buf, loff_t *size, +int kernel_read_file_from_path(const char *path, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id) { struct file *file; @@ -1259,6 +1240,12 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec) perf_event_comm(tsk, exec); } +/* + * Calling this is the point of no return. None of the failures will be + * seen by userspace since either the process is already taking a fatal + * signal (via de_thread() or coredump), or will have SEGV raised + * (after exec_mmap()) by search_binary_handlers (see below). + */ int flush_old_exec(struct linux_binprm * bprm) { int retval; @@ -1286,7 +1273,13 @@ int flush_old_exec(struct linux_binprm * bprm) if (retval) goto out; - bprm->mm = NULL; /* We're using it now */ + /* + * After clearing bprm->mm (to mark that current is using the + * prepared mm now), we have nothing left of the original + * process. If anything from here on returns an error, the check + * in search_binary_handler() will SEGV current. + */ + bprm->mm = NULL; set_fs(USER_DS); current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | @@ -1331,15 +1324,38 @@ EXPORT_SYMBOL(would_dump); void setup_new_exec(struct linux_binprm * bprm) { + /* + * Once here, prepare_binrpm() will not be called any more, so + * the final state of setuid/setgid/fscaps can be merged into the + * secureexec flag. + */ + bprm->secureexec |= bprm->cap_elevated; + + if (bprm->secureexec) { + /* Make sure parent cannot signal privileged process. */ + current->pdeath_signal = 0; + + /* + * For secureexec, reset the stack limit to sane default to + * avoid bad behavior from the prior rlimits. This has to + * happen before arch_pick_mmap_layout(), which examines + * RLIMIT_STACK, but after the point of no return to avoid + * needing to clean up the change on failure. + */ + if (current->signal->rlim[RLIMIT_STACK].rlim_cur > _STK_LIM) + current->signal->rlim[RLIMIT_STACK].rlim_cur = _STK_LIM; + } + arch_pick_mmap_layout(current->mm); - /* This is the point of no return */ current->sas_ss_sp = current->sas_ss_size = 0; - if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid())) - set_dumpable(current->mm, SUID_DUMP_USER); - else + /* Figure out dumpability. */ + if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP || + bprm->secureexec) set_dumpable(current->mm, suid_dumpable); + else + set_dumpable(current->mm, SUID_DUMP_USER); arch_setup_new_exec(); perf_event_exec(); @@ -1351,15 +1367,6 @@ void setup_new_exec(struct linux_binprm * bprm) */ current->mm->task_size = TASK_SIZE; - /* install the new credentials */ - if (!uid_eq(bprm->cred->uid, current_euid()) || - !gid_eq(bprm->cred->gid, current_egid())) { - current->pdeath_signal = 0; - } else { - if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) - set_dumpable(current->mm, suid_dumpable); - } - /* An exec changes our domain. We are no longer part of the thread group */ current->self_exec_id++; @@ -1403,7 +1410,7 @@ static void free_bprm(struct linux_binprm *bprm) kfree(bprm); } -int bprm_change_interp(char *interp, struct linux_binprm *bprm) +int bprm_change_interp(const char *interp, struct linux_binprm *bprm) { /* If a binfmt changed the interp, free it first. */ if (bprm->interp != bprm->filename) @@ -1541,6 +1548,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm) int prepare_binprm(struct linux_binprm *bprm) { int retval; + loff_t pos = 0; bprm_fill_uid(bprm); @@ -1548,10 +1556,10 @@ int prepare_binprm(struct linux_binprm *bprm) retval = security_bprm_set_creds(bprm); if (retval) return retval; - bprm->cred_prepared = 1; + bprm->called_set_creds = 1; memset(bprm->buf, 0, BINPRM_BUF_SIZE); - return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE); + return kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, &pos); } EXPORT_SYMBOL(prepare_binprm); @@ -1737,9 +1745,9 @@ static int do_execveat_common(int fd, struct filename *filename, bprm->filename = filename->name; } else { if (filename->name[0] == '\0') - pathbuf = kasprintf(GFP_TEMPORARY, "/dev/fd/%d", fd); + pathbuf = kasprintf(GFP_KERNEL, "/dev/fd/%d", fd); else - pathbuf = kasprintf(GFP_TEMPORARY, "/dev/fd/%d/%s", + pathbuf = kasprintf(GFP_KERNEL, "/dev/fd/%d/%s", fd, filename->name); if (!pathbuf) { retval = -ENOMEM; diff --git a/fs/exofs/file.c b/fs/exofs/file.c index 28645f0640f735b7f168b14258cc22c110bc0f1d..a94594ea2aa346ecf5eb854f314041c51b2e9e23 100644 --- a/fs/exofs/file.c +++ b/fs/exofs/file.c @@ -48,7 +48,7 @@ static int exofs_file_fsync(struct file *filp, loff_t start, loff_t end, struct inode *inode = filp->f_mapping->host; int ret; - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(filp, start, end); if (ret) return ret; diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index 8bb72807e70d46ae2ab32e7e8d29de4d034454f5..3c6a9c156b7accb06d96905bc454fe41b2e7c857 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c @@ -869,7 +869,7 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) goto out; } - bio->bi_bdev = NULL; + bio->bi_disk = NULL; bio->bi_next = NULL; per_dev->offset = master_dev->offset; per_dev->length = master_dev->length; diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 23ebb92484c602ba075d4725694e3380827397cc..28de3edd4f4dc32e9c9dec3d3c12ac1af6c0ddc1 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -114,6 +114,7 @@ struct ext2_sb_info { */ spinlock_t s_lock; struct mb_cache *s_ea_block_cache; + struct dax_device *s_daxdev; }; static inline spinlock_t * diff --git a/fs/ext2/file.c b/fs/ext2/file.c index d34d32bdc944add56a4375827e044c8482665c8c..ff3a3636a5cab588fb05f0644e1892ce6e236c6f 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -107,29 +107,6 @@ static int ext2_dax_fault(struct vm_fault *vmf) return ret; } -static int ext2_dax_pfn_mkwrite(struct vm_fault *vmf) -{ - struct inode *inode = file_inode(vmf->vma->vm_file); - struct ext2_inode_info *ei = EXT2_I(inode); - loff_t size; - int ret; - - sb_start_pagefault(inode->i_sb); - file_update_time(vmf->vma->vm_file); - down_read(&ei->dax_sem); - - /* check that the faulting page hasn't raced with truncate */ - size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; - if (vmf->pgoff >= size) - ret = VM_FAULT_SIGBUS; - else - ret = dax_pfn_mkwrite(vmf); - - up_read(&ei->dax_sem); - sb_end_pagefault(inode->i_sb); - return ret; -} - static const struct vm_operations_struct ext2_dax_vm_ops = { .fault = ext2_dax_fault, /* @@ -138,7 +115,7 @@ static const struct vm_operations_struct ext2_dax_vm_ops = { * will always fail and fail back to regular faults. */ .page_mkwrite = ext2_dax_fault, - .pfn_mkwrite = ext2_dax_pfn_mkwrite, + .pfn_mkwrite = ext2_dax_fault, }; static int ext2_file_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 30163d007b2f287180d9d22827e638618038de22..4dca6f3487149a6e3b876157a1f6f2223d7a8e8b 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -800,10 +800,10 @@ int ext2_get_block(struct inode *inode, sector_t iblock, static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length, unsigned flags, struct iomap *iomap) { - struct block_device *bdev; unsigned int blkbits = inode->i_blkbits; unsigned long first_block = offset >> blkbits; unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits; + struct ext2_sb_info *sbi = EXT2_SB(inode->i_sb); bool new = false, boundary = false; u32 bno; int ret; @@ -814,13 +814,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length, return ret; iomap->flags = 0; - bdev = inode->i_sb->s_bdev; - iomap->bdev = bdev; + iomap->bdev = inode->i_sb->s_bdev; iomap->offset = (u64)first_block << blkbits; - if (blk_queue_dax(bdev->bd_queue)) - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name); - else - iomap->dax_dev = NULL; + iomap->dax_dev = sbi->s_daxdev; if (ret == 0) { iomap->type = IOMAP_HOLE; @@ -842,7 +838,6 @@ static int ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length, ssize_t written, unsigned flags, struct iomap *iomap) { - fs_put_dax(iomap->dax_dev); if (iomap->type == IOMAP_MAPPED && written < length && (flags & IOMAP_WRITE)) diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 7b1bc9059863b37c2ff508bd331a736cef403bb6..1458706bd2ec6ac5ed9c0acb6c150d661bd14595 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -52,7 +52,7 @@ void ext2_error(struct super_block *sb, const char *function, struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { spin_lock(&sbi->s_lock); sbi->s_mount_state |= EXT2_ERROR_FS; es->s_state |= cpu_to_le16(EXT2_ERROR_FS); @@ -151,7 +151,7 @@ static void ext2_put_super (struct super_block * sb) ext2_xattr_destroy_cache(sbi->s_ea_block_cache); sbi->s_ea_block_cache = NULL; } - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { struct ext2_super_block *es = sbi->s_es; spin_lock(&sbi->s_lock); @@ -171,6 +171,7 @@ static void ext2_put_super (struct super_block * sb) brelse (sbi->s_sbh); sb->s_fs_info = NULL; kfree(sbi->s_blockgroup_lock); + fs_put_dax(sbi->s_daxdev); kfree(sbi); } @@ -813,6 +814,7 @@ static unsigned long descriptor_loc(struct super_block *sb, static int ext2_fill_super(struct super_block *sb, void *data, int silent) { + struct dax_device *dax_dev = fs_dax_get_by_bdev(sb->s_bdev); struct buffer_head * bh; struct ext2_sb_info * sbi; struct ext2_super_block * es; @@ -842,6 +844,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) } sb->s_fs_info = sbi; sbi->s_sb_block = sb_block; + sbi->s_daxdev = dax_dev; spin_lock_init(&sbi->s_lock); @@ -940,8 +943,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) le32_to_cpu(features)); goto failed_mount; } - if (!(sb->s_flags & MS_RDONLY) && - (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){ + if (!sb_rdonly(sb) && (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){ ext2_msg(sb, KERN_ERR, "error: couldn't mount RDWR because of " "unsupported optional features (%x)", le32_to_cpu(features)); @@ -1170,7 +1172,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) ext2_msg(sb, KERN_WARNING, "warning: mounting ext3 filesystem as ext2"); - if (ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY)) + if (ext2_setup_super (sb, es, sb_rdonly(sb))) sb->s_flags |= MS_RDONLY; ext2_write_super(sb); return 0; @@ -1200,6 +1202,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) kfree(sbi->s_blockgroup_lock); kfree(sbi); failed: + fs_put_dax(dax_dev); return ret; } @@ -1301,7 +1304,7 @@ static int ext2_unfreeze(struct super_block *sb) static void ext2_write_super(struct super_block *sb) { - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) ext2_sync_fs(sb, 1); } @@ -1339,7 +1342,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) "dax flag with busy inodes while remounting"); sbi->s_mount_opt ^= EXT2_MOUNT_DAX; } - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) { spin_unlock(&sbi->s_lock); return 0; } diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 09441ae07a5be9de1f18cdc01d896808ba1e02be..46ff2229ff5efed30a498d05a416ea7e5c1e6d22 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -193,13 +193,6 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type, switch (type) { case ACL_TYPE_ACCESS: name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - error = posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; - inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - } break; case ACL_TYPE_DEFAULT: @@ -221,8 +214,9 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type, value, size, xattr_flags); kfree(value); - if (!error) + if (!error) { set_cached_acl(inode, type, acl); + } return error; } @@ -233,6 +227,8 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type) handle_t *handle; int error, credits, retries = 0; size_t acl_size = acl ? ext4_acl_size(acl->a_count) : 0; + umode_t mode = inode->i_mode; + int update_mode = 0; error = dquot_initialize(inode); if (error) @@ -247,7 +243,20 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type) if (IS_ERR(handle)) return PTR_ERR(handle); + if ((type == ACL_TYPE_ACCESS) && acl) { + error = posix_acl_update_mode(inode, &mode, &acl); + if (error) + goto out_stop; + update_mode = 1; + } + error = __ext4_set_acl(handle, inode, type, acl, 0 /* xattr_flags */); + if (!error && update_mode) { + inode->i_mode = mode; + inode->i_ctime = current_time(inode); + ext4_mark_inode_dirty(handle, inode); + } +out_stop: ext4_journal_stop(handle); if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index e8b365000d730d6a5f6f532bead918f535b83709..b04e882179c68240a83a562e61c7840ca71f8ca8 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -411,7 +411,7 @@ static struct dir_private_info *ext4_htree_create_dir_info(struct file *filp, { struct dir_private_info *p; - p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return NULL; p->curr_hash = pos2maj_hash(filp, pos); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 9ebde0cd632e77b69fecd7800ed196e67b059507..e2abe01c8c6bac60e04ef26fd4559c854fbef280 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -838,13 +838,11 @@ static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) { if (unlikely(sizeof(time->tv_sec) > 4 && (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) + +#if 1 /* Handle legacy encoding of pre-1970 dates with epoch - * bits 1,1. We assume that by kernel version 4.20, - * everyone will have run fsck over the affected - * filesystems to correct the problem. (This - * backwards compatibility may be removed before this - * time, at the discretion of the ext4 developers.) + * bits 1,1. (This backwards compatibility may be removed + * at the discretion of the ext4 developers.) */ u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK; if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0) @@ -961,7 +959,7 @@ struct ext4_inode_info { /* * i_block_group is the number of the block group which contains * this file's inode. Constant across the lifetime of the inode, - * it is ued for making block allocation decisions - we try to + * it is used for making block allocation decisions - we try to * place a file's data blocks near its inode block, and new inodes * near to their parent directory's inode. */ @@ -1049,10 +1047,8 @@ struct ext4_inode_info { ext4_group_t i_last_alloc_group; /* allocation reservation info for delalloc */ - /* In case of bigalloc, these refer to clusters rather than blocks */ + /* In case of bigalloc, this refer to clusters rather than blocks */ unsigned int i_reserved_data_blocks; - unsigned int i_reserved_meta_blocks; - unsigned int i_allocated_meta_blocks; ext4_lblk_t i_da_metadata_calc_last_lblock; int i_da_metadata_calc_len; @@ -1530,6 +1526,7 @@ struct ext4_sb_info { /* Barrier between changing inodes' journal flags and writepages ops. */ struct percpu_rw_semaphore s_journal_flag_rwsem; + struct dax_device *s_daxdev; }; static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) @@ -1569,6 +1566,7 @@ enum { nolocking */ EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */ EXT4_STATE_EXT_PRECACHED, /* extents have been precached */ + EXT4_STATE_LUSTRE_EA_INODE, /* Lustre-style ea_inode */ }; #define EXT4_INODE_BIT_FNS(name, field, offset) \ @@ -2022,7 +2020,8 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize) #define is_dx(dir) (ext4_has_feature_dir_index((dir)->i_sb) && \ ext4_test_inode_flag((dir), EXT4_INODE_INDEX)) -#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX) +#define EXT4_DIR_LINK_MAX(dir) unlikely((dir)->i_nlink >= EXT4_LINK_MAX && \ + !(ext4_has_feature_dir_nlink((dir)->i_sb) && is_dx(dir))) #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) /* Legal values for the dx_root hash_version field: */ @@ -2462,6 +2461,8 @@ extern void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid); int ext4_inode_is_fast_symlink(struct inode *inode); struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int); struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int); +int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count, + bool wait, struct buffer_head **bhs); int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create); int ext4_get_block(struct inode *inode, sector_t iblock, @@ -3074,7 +3075,7 @@ extern int ext4_handle_dirty_dirent_node(handle_t *handle, struct inode *inode, struct buffer_head *bh); #define S_SHIFT 12 -static const unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = { +static const unsigned char ext4_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = { [S_IFREG >> S_SHIFT] = EXT4_FT_REG_FILE, [S_IFDIR >> S_SHIFT] = EXT4_FT_DIR, [S_IFCHR >> S_SHIFT] = EXT4_FT_CHRDEV, diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index dd106b1d5d89155d850f5320b7739342455959bd..5b342ac67d2ede320eb98234139ca000a268aa8c 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -47,7 +47,7 @@ static int ext4_journal_check_start(struct super_block *sb) if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) return -EIO; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE); journal = EXT4_SB(sb)->s_journal; diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index dabad1bc861723932fd7f25da1d86cdd0a641ce9..48143e32411c4cabfdd56bebe41c8fdc522c9665 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h @@ -227,6 +227,9 @@ int ext4_reserve_inode_write(handle_t *handle, struct inode *inode, int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode); +int ext4_expand_extra_isize(struct inode *inode, + unsigned int new_extra_isize, + struct ext4_iloc *iloc); /* * Wrapper functions with which ext4 calls into JBD. */ diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e0a8425ff74da9e60427f09f5525e1bc85952d51..97f0fd06728d7bb18bb05637db169cfeb91f9bcf 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4652,7 +4652,7 @@ int ext4_ext_truncate(handle_t *handle, struct inode *inode) static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, ext4_lblk_t len, loff_t new_size, - int flags, int mode) + int flags) { struct inode *inode = file_inode(file); handle_t *handle; @@ -4815,7 +4815,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, round_down(offset, 1 << blkbits) >> blkbits, (round_up((offset + len), 1 << blkbits) - round_down(offset, 1 << blkbits)) >> blkbits, - new_size, flags, mode); + new_size, flags); if (ret) goto out_dio; @@ -4841,7 +4841,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, inode->i_mtime = inode->i_ctime = current_time(inode); ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, - flags, mode); + flags); up_write(&EXT4_I(inode)->i_mmap_sem); if (ret) goto out_dio; @@ -4976,8 +4976,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) ext4_inode_block_unlocked_dio(inode); inode_dio_wait(inode); - ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, - flags, mode); + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags); ext4_inode_resume_unlocked_dio(inode); if (ret) goto out; @@ -5837,7 +5836,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1, if (e1_blk > lblk1) next1 = e1_blk; if (e2_blk > lblk2) - next2 = e1_blk; + next2 = e2_blk; /* Do we have something to swap */ if (next1 == EXT_MAX_BLOCKS || next2 == EXT_MAX_BLOCKS) goto finish; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 58294c9a7e1df0028f267e4eaad67d7b0d2a910b..b1da660ac3bcf97c8cd799fcc6823a23666c8ea5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -223,6 +223,8 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (IS_DAX(inode)) return ext4_dax_write_iter(iocb, from); #endif + if (!o_direct && (iocb->ki_flags & IOCB_NOWAIT)) + return -EOPNOTSUPP; if (!inode_trylock(inode)) { if (iocb->ki_flags & IOCB_NOWAIT) @@ -279,7 +281,20 @@ static int ext4_dax_huge_fault(struct vm_fault *vmf, handle_t *handle = NULL; struct inode *inode = file_inode(vmf->vma->vm_file); struct super_block *sb = inode->i_sb; - bool write = vmf->flags & FAULT_FLAG_WRITE; + + /* + * We have to distinguish real writes from writes which will result in a + * COW page; COW writes should *not* poke the journal (the file will not + * be changed). Doing so would cause unintended failures when mounted + * read-only. + * + * We check for VM_SHARED rather than vmf->cow_page since the latter is + * unset for pe_size != PE_SIZE_PTE (i.e. only in do_cow_fault); for + * other sizes, dax_iomap_fault will handle splitting / fallback so that + * we eventually come back with a COW page. + */ + bool write = (vmf->flags & FAULT_FLAG_WRITE) && + (vmf->vma->vm_flags & VM_SHARED); if (write) { sb_start_pagefault(sb); @@ -311,41 +326,11 @@ static int ext4_dax_fault(struct vm_fault *vmf) return ext4_dax_huge_fault(vmf, PE_SIZE_PTE); } -/* - * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_fault() - * handler we check for races agaist truncate. Note that since we cycle through - * i_mmap_sem, we are sure that also any hole punching that began before we - * were called is finished by now and so if it included part of the file we - * are working on, our pte will get unmapped and the check for pte_same() in - * wp_pfn_shared() fails. Thus fault gets retried and things work out as - * desired. - */ -static int ext4_dax_pfn_mkwrite(struct vm_fault *vmf) -{ - struct inode *inode = file_inode(vmf->vma->vm_file); - struct super_block *sb = inode->i_sb; - loff_t size; - int ret; - - sb_start_pagefault(sb); - file_update_time(vmf->vma->vm_file); - down_read(&EXT4_I(inode)->i_mmap_sem); - size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; - if (vmf->pgoff >= size) - ret = VM_FAULT_SIGBUS; - else - ret = dax_pfn_mkwrite(vmf); - up_read(&EXT4_I(inode)->i_mmap_sem); - sb_end_pagefault(sb); - - return ret; -} - static const struct vm_operations_struct ext4_dax_vm_ops = { .fault = ext4_dax_fault, .huge_fault = ext4_dax_huge_fault, .page_mkwrite = ext4_dax_fault, - .pfn_mkwrite = ext4_dax_pfn_mkwrite, + .pfn_mkwrite = ext4_dax_fault, }; #else #define ext4_dax_vm_ops ext4_file_vm_ops @@ -388,7 +373,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp) return -EIO; if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) && - !(sb->s_flags & MS_RDONLY))) { + !sb_rdonly(sb))) { sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED; /* * Sample where the filesystem has been mounted and @@ -448,9 +433,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp) return ret; } - /* Set the flags to support nowait AIO */ - filp->f_mode |= FMODE_AIO_NOWAIT; - + filp->f_mode |= FMODE_NOWAIT; return dquot_file_open(inode, filp); } @@ -494,12 +477,11 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, pagevec_init(&pvec, 0); do { - int i, num; + int i; unsigned long nr_pages; - num = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1; - nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, - (pgoff_t)num); + nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping, + &index, end); if (nr_pages == 0) break; @@ -518,9 +500,6 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, goto out; } - if (page->index > end) - goto out; - lock_page(page); if (unlikely(page->mapping != inode->i_mapping)) { @@ -537,6 +516,8 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, lastoff = page_offset(page); bh = head = page_buffers(page); do { + if (lastoff + bh->b_size <= startoff) + goto next; if (buffer_uptodate(bh) || buffer_unwritten(bh)) { if (whence == SEEK_DATA) @@ -551,6 +532,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, unlock_page(page); goto out; } +next: lastoff += bh->b_size; bh = bh->b_this_page; } while (bh != head); @@ -560,14 +542,10 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, unlock_page(page); } - /* The no. of pages is less than our desired, we are done. */ - if (nr_pages < num) - break; - - index = pvec.pages[i - 1]->index + 1; pagevec_release(&pvec); } while (index <= end); + /* There are no pages upto endoff - that would be a hole in there. */ if (whence == SEEK_HOLE && lastoff < endoff) { found = 1; *offset = lastoff; @@ -592,7 +570,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) inode_lock(inode); isize = i_size_read(inode); - if (offset >= isize) { + if (offset < 0 || offset >= isize) { inode_unlock(inode); return -ENXIO; } @@ -655,7 +633,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) inode_lock(inode); isize = i_size_read(inode); - if (offset >= isize) { + if (offset < 0 || offset >= isize) { inode_unlock(inode); return -ENXIO; } diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index aae2c3971cef2dc70065f85431584b7feed8cb36..f9230580a84b2efd9317ad175c71dabcffbf2c5d 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -107,7 +107,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) trace_ext4_sync_file_enter(file, datasync); - if (inode->i_sb->s_flags & MS_RDONLY) { + if (sb_rdonly(inode->i_sb)) { /* Make sure that we read updated s_mount_flags value */ smp_rmb(); if (EXT4_SB(inode->i_sb)->s_mount_flags & EXT4_MF_FS_ABORTED) diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c index 38b8a96eb97c2f59932993e704b15a4b6b89e207..00c6dd29e621f91a0adab2c1acfef4096347f810 100644 --- a/fs/ext4/hash.c +++ b/fs/ext4/hash.c @@ -148,8 +148,6 @@ static void str2hashbuf_signed(const char *msg, int len, __u32 *buf, int num) if (len > num*4) len = num * 4; for (i = 0; i < len; i++) { - if ((i % 4) == 0) - val = pad; val = ((int) scp[i]) + (val << 8); if ((i % 4) == 3) { *buf++ = val; @@ -176,8 +174,6 @@ static void str2hashbuf_unsigned(const char *msg, int len, __u32 *buf, int num) if (len > num*4) len = num * 4; for (i = 0; i < len; i++) { - if ((i % 4) == 0) - val = pad; val = ((int) ucp[i]) + (val << 8); if ((i % 4) == 3) { *buf++ = val; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 507bfb3344d41d1cc857022e61eb7c09ab184231..ee823022aa344a2723bfac9c11d61ace60b32e69 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -692,24 +692,25 @@ static int find_group_other(struct super_block *sb, struct inode *parent, * somewhat arbitrary...) */ #define RECENTCY_MIN 5 -#define RECENTCY_DIRTY 30 +#define RECENTCY_DIRTY 300 static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino) { struct ext4_group_desc *gdp; struct ext4_inode *raw_inode; struct buffer_head *bh; - unsigned long dtime, now; - int inodes_per_block = EXT4_SB(sb)->s_inodes_per_block; - int offset, ret = 0, recentcy = RECENTCY_MIN; + int inodes_per_block = EXT4_SB(sb)->s_inodes_per_block; + int offset, ret = 0; + int recentcy = RECENTCY_MIN; + u32 dtime, now; gdp = ext4_get_group_desc(sb, group, NULL); if (unlikely(!gdp)) return 0; - bh = sb_getblk(sb, ext4_inode_table(sb, gdp) + + bh = sb_find_get_block(sb, ext4_inode_table(sb, gdp) + (ino / inodes_per_block)); - if (unlikely(!bh) || !buffer_uptodate(bh)) + if (!bh || !buffer_uptodate(bh)) /* * If the block is not in the buffer cache, then it * must have been written out. @@ -718,18 +719,45 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino) offset = (ino % inodes_per_block) * EXT4_INODE_SIZE(sb); raw_inode = (struct ext4_inode *) (bh->b_data + offset); + + /* i_dtime is only 32 bits on disk, but we only care about relative + * times in the range of a few minutes (i.e. long enough to sync a + * recently-deleted inode to disk), so using the low 32 bits of the + * clock (a 68 year range) is enough, see time_before32() */ dtime = le32_to_cpu(raw_inode->i_dtime); - now = get_seconds(); + now = ktime_get_real_seconds(); if (buffer_dirty(bh)) recentcy += RECENTCY_DIRTY; - if (dtime && (dtime < now) && (now < dtime + recentcy)) + if (dtime && time_before32(dtime, now) && + time_before32(now, dtime + recentcy)) ret = 1; out: brelse(bh); return ret; } +static int find_inode_bit(struct super_block *sb, ext4_group_t group, + struct buffer_head *bitmap, unsigned long *ino) +{ +next: + *ino = ext4_find_next_zero_bit((unsigned long *) + bitmap->b_data, + EXT4_INODES_PER_GROUP(sb), *ino); + if (*ino >= EXT4_INODES_PER_GROUP(sb)) + return 0; + + if ((EXT4_SB(sb)->s_journal == NULL) && + recently_deleted(sb, group, *ino)) { + *ino = *ino + 1; + if (*ino < EXT4_INODES_PER_GROUP(sb)) + goto next; + return 0; + } + + return 1; +} + /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -892,19 +920,13 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, /* * Check free inodes count before loading bitmap. */ - if (ext4_free_inodes_count(sb, gdp) == 0) { - if (++group == ngroups) - group = 0; - continue; - } + if (ext4_free_inodes_count(sb, gdp) == 0) + goto next_group; grp = ext4_get_group_info(sb, group); /* Skip groups with already-known suspicious inode tables */ - if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { - if (++group == ngroups) - group = 0; - continue; - } + if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) + goto next_group; brelse(inode_bitmap_bh); inode_bitmap_bh = ext4_read_inode_bitmap(sb, group); @@ -912,27 +934,20 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp) || IS_ERR(inode_bitmap_bh)) { inode_bitmap_bh = NULL; - if (++group == ngroups) - group = 0; - continue; + goto next_group; } repeat_in_this_group: - ino = ext4_find_next_zero_bit((unsigned long *) - inode_bitmap_bh->b_data, - EXT4_INODES_PER_GROUP(sb), ino); - if (ino >= EXT4_INODES_PER_GROUP(sb)) + ret2 = find_inode_bit(sb, group, inode_bitmap_bh, &ino); + if (!ret2) goto next_group; - if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) { + + if (group == 0 && (ino + 1) < EXT4_FIRST_INO(sb)) { ext4_error(sb, "reserved inode found cleared - " "inode=%lu", ino + 1); - continue; - } - if ((EXT4_SB(sb)->s_journal == NULL) && - recently_deleted(sb, group, ino)) { - ino++; - goto next_inode; + goto next_group; } + if (!handle) { BUG_ON(nblocks <= 0); handle = __ext4_journal_start_sb(dir->i_sb, line_no, @@ -952,11 +967,23 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, } ext4_lock_group(sb, group); ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data); + if (ret2) { + /* Someone already took the bit. Repeat the search + * with lock held. + */ + ret2 = find_inode_bit(sb, group, inode_bitmap_bh, &ino); + if (ret2) { + ext4_set_bit(ino, inode_bitmap_bh->b_data); + ret2 = 0; + } else { + ret2 = 1; /* we didn't grab the inode */ + } + } ext4_unlock_group(sb, group); ino++; /* the inode bitmap is zero-based */ if (!ret2) goto got; /* we grabbed the inode! */ -next_inode: + if (ino < EXT4_INODES_PER_GROUP(sb)) goto repeat_in_this_group; next_group: @@ -1355,7 +1382,7 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group, int num, ret = 0, used_blks = 0; /* This should not happen, but just to be sure check this */ - if (sb->s_flags & MS_RDONLY) { + if (sb_rdonly(sb)) { ret = 1; goto out; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3c600f02673f07ca829195605acaebd0eb9ad7cd..31db875bc7a13dde67b9a6b17ce498b4c16bd17f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -892,7 +892,7 @@ static int ext4_dio_get_block_unwritten_async(struct inode *inode, /* * Get block function for non-AIO DIO writes when we create unwritten extent if * blocks are not allocated yet. The extent will be converted to written - * after IO is complete from ext4_ext_direct_IO() function. + * after IO is complete by ext4_direct_IO_write(). */ static int ext4_dio_get_block_unwritten_sync(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) @@ -907,7 +907,7 @@ static int ext4_dio_get_block_unwritten_sync(struct inode *inode, /* * Mark inode as having pending DIO writes to unwritten extents. - * ext4_ext_direct_IO() checks this flag and converts extents to + * ext4_direct_IO_write() checks this flag and converts extents to * written. */ if (!ret && buffer_unwritten(bh_result)) @@ -1015,6 +1015,50 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, return ERR_PTR(-EIO); } +/* Read a contiguous batch of blocks. */ +int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count, + bool wait, struct buffer_head **bhs) +{ + int i, err; + + for (i = 0; i < bh_count; i++) { + bhs[i] = ext4_getblk(NULL, inode, block + i, 0 /* map_flags */); + if (IS_ERR(bhs[i])) { + err = PTR_ERR(bhs[i]); + bh_count = i; + goto out_brelse; + } + } + + for (i = 0; i < bh_count; i++) + /* Note that NULL bhs[i] is valid because of holes. */ + if (bhs[i] && !buffer_uptodate(bhs[i])) + ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, + &bhs[i]); + + if (!wait) + return 0; + + for (i = 0; i < bh_count; i++) + if (bhs[i]) + wait_on_buffer(bhs[i]); + + for (i = 0; i < bh_count; i++) { + if (bhs[i] && !buffer_uptodate(bhs[i])) { + err = -EIO; + goto out_brelse; + } + } + return 0; + +out_brelse: + for (i = 0; i < bh_count; i++) { + brelse(bhs[i]); + bhs[i] = NULL; + } + return err; +} + int ext4_walk_page_buffers(handle_t *handle, struct buffer_head *head, unsigned from, @@ -1676,13 +1720,12 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd, pagevec_init(&pvec, 0); while (index <= end) { - nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); + nr_pages = pagevec_lookup_range(&pvec, mapping, &index, end); if (nr_pages == 0) break; for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; - if (page->index > end) - break; + BUG_ON(!PageLocked(page)); BUG_ON(PageWriteback(page)); if (invalidate) { @@ -1693,7 +1736,6 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd, } unlock_page(page); } - index = pvec.pages[nr_pages - 1]->index + 1; pagevec_release(&pvec); } } @@ -2304,17 +2346,13 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd) pagevec_init(&pvec, 0); while (start <= end) { - nr_pages = pagevec_lookup(&pvec, inode->i_mapping, start, - PAGEVEC_SIZE); + nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping, + &start, end); if (nr_pages == 0) break; for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; - if (page->index > end) - break; - /* Up to 'end' pages must be contiguous */ - BUG_ON(page->index != start); bh = head = page_buffers(page); do { if (lblk < mpd->map.m_lblk) @@ -2359,7 +2397,6 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd) pagevec_release(&pvec); return err; } - start++; } pagevec_release(&pvec); } @@ -3360,7 +3397,7 @@ static int ext4_releasepage(struct page *page, gfp_t wait) static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, unsigned flags, struct iomap *iomap) { - struct block_device *bdev; + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); unsigned int blkbits = inode->i_blkbits; unsigned long first_block = offset >> blkbits; unsigned long last_block = (offset + length - 1) >> blkbits; @@ -3429,12 +3466,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, } iomap->flags = 0; - bdev = inode->i_sb->s_bdev; - iomap->bdev = bdev; - if (blk_queue_dax(bdev->bd_queue)) - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name); - else - iomap->dax_dev = NULL; + iomap->bdev = inode->i_sb->s_bdev; + iomap->dax_dev = sbi->s_daxdev; iomap->offset = first_block << blkbits; if (ret == 0) { @@ -3467,7 +3500,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length, int blkbits = inode->i_blkbits; bool truncate = false; - fs_put_dax(iomap->dax_dev); if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT)) return 0; @@ -4853,14 +4885,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) brelse(iloc.bh); ext4_set_inode_flags(inode); - if (ei->i_flags & EXT4_EA_INODE_FL) { - ext4_xattr_inode_set_class(inode); - - inode_lock(inode); - inode->i_flags |= S_NOQUOTA; - inode_unlock(inode); - } - unlock_new_inode(inode); return inode; @@ -5658,22 +5682,16 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode, return err; } -/* - * Expand an inode by new_extra_isize bytes. - * Returns 0 on success or negative error number on failure. - */ -static int ext4_expand_extra_isize(struct inode *inode, - unsigned int new_extra_isize, - struct ext4_iloc iloc, - handle_t *handle) +static int __ext4_expand_extra_isize(struct inode *inode, + unsigned int new_extra_isize, + struct ext4_iloc *iloc, + handle_t *handle, int *no_expand) { struct ext4_inode *raw_inode; struct ext4_xattr_ibody_header *header; + int error; - if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) - return 0; - - raw_inode = ext4_raw_inode(&iloc); + raw_inode = ext4_raw_inode(iloc); header = IHDR(inode, raw_inode); @@ -5688,8 +5706,98 @@ static int ext4_expand_extra_isize(struct inode *inode, } /* try to expand with EAs present */ - return ext4_expand_extra_isize_ea(inode, new_extra_isize, - raw_inode, handle); + error = ext4_expand_extra_isize_ea(inode, new_extra_isize, + raw_inode, handle); + if (error) { + /* + * Inode size expansion failed; don't try again + */ + *no_expand = 1; + } + + return error; +} + +/* + * Expand an inode by new_extra_isize bytes. + * Returns 0 on success or negative error number on failure. + */ +static int ext4_try_to_expand_extra_isize(struct inode *inode, + unsigned int new_extra_isize, + struct ext4_iloc iloc, + handle_t *handle) +{ + int no_expand; + int error; + + if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) + return -EOVERFLOW; + + /* + * In nojournal mode, we can immediately attempt to expand + * the inode. When journaled, we first need to obtain extra + * buffer credits since we may write into the EA block + * with this same handle. If journal_extend fails, then it will + * only result in a minor loss of functionality for that inode. + * If this is felt to be critical, then e2fsck should be run to + * force a large enough s_min_extra_isize. + */ + if (ext4_handle_valid(handle) && + jbd2_journal_extend(handle, + EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) != 0) + return -ENOSPC; + + if (ext4_write_trylock_xattr(inode, &no_expand) == 0) + return -EBUSY; + + error = __ext4_expand_extra_isize(inode, new_extra_isize, &iloc, + handle, &no_expand); + ext4_write_unlock_xattr(inode, &no_expand); + + return error; +} + +int ext4_expand_extra_isize(struct inode *inode, + unsigned int new_extra_isize, + struct ext4_iloc *iloc) +{ + handle_t *handle; + int no_expand; + int error, rc; + + if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { + brelse(iloc->bh); + return -EOVERFLOW; + } + + handle = ext4_journal_start(inode, EXT4_HT_INODE, + EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); + brelse(iloc->bh); + return error; + } + + ext4_write_lock_xattr(inode, &no_expand); + + BUFFER_TRACE(iloc.bh, "get_write_access"); + error = ext4_journal_get_write_access(handle, iloc->bh); + if (error) { + brelse(iloc->bh); + goto out_stop; + } + + error = __ext4_expand_extra_isize(inode, new_extra_isize, iloc, + handle, &no_expand); + + rc = ext4_mark_iloc_dirty(handle, inode, iloc); + if (!error) + error = rc; + + ext4_write_unlock_xattr(inode, &no_expand); +out_stop: + ext4_journal_stop(handle); + return error; } /* @@ -5709,44 +5817,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) { struct ext4_iloc iloc; struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - static unsigned int mnt_count; - int err, ret; + int err; might_sleep(); trace_ext4_mark_inode_dirty(inode, _RET_IP_); err = ext4_reserve_inode_write(handle, inode, &iloc); if (err) return err; - if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && - !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { - /* - * In nojournal mode, we can immediately attempt to expand - * the inode. When journaled, we first need to obtain extra - * buffer credits since we may write into the EA block - * with this same handle. If journal_extend fails, then it will - * only result in a minor loss of functionality for that inode. - * If this is felt to be critical, then e2fsck should be run to - * force a large enough s_min_extra_isize. - */ - if (!ext4_handle_valid(handle) || - jbd2_journal_extend(handle, - EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) == 0) { - ret = ext4_expand_extra_isize(inode, - sbi->s_want_extra_isize, - iloc, handle); - if (ret) { - if (mnt_count != - le16_to_cpu(sbi->s_es->s_mnt_count)) { - ext4_warning(inode->i_sb, - "Unable to expand inode %lu. Delete" - " some EAs or run e2fsck.", - inode->i_ino); - mnt_count = - le16_to_cpu(sbi->s_es->s_mnt_count); - } - } - } - } + + if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize) + ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize, + iloc, handle); + return ext4_mark_iloc_dirty(handle, inode, &iloc); } diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 42b3a73143cf1a3b2cadef40459a50714b6b80d5..afb66d4ab5cfb895ce99574f18740621c37815db 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -64,18 +64,16 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2) ei1 = EXT4_I(inode1); ei2 = EXT4_I(inode2); - memswap(&inode1->i_flags, &inode2->i_flags, sizeof(inode1->i_flags)); - memswap(&inode1->i_version, &inode2->i_version, - sizeof(inode1->i_version)); - memswap(&inode1->i_blocks, &inode2->i_blocks, - sizeof(inode1->i_blocks)); - memswap(&inode1->i_bytes, &inode2->i_bytes, sizeof(inode1->i_bytes)); - memswap(&inode1->i_atime, &inode2->i_atime, sizeof(inode1->i_atime)); - memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime)); + swap(inode1->i_flags, inode2->i_flags); + swap(inode1->i_version, inode2->i_version); + swap(inode1->i_blocks, inode2->i_blocks); + swap(inode1->i_bytes, inode2->i_bytes); + swap(inode1->i_atime, inode2->i_atime); + swap(inode1->i_mtime, inode2->i_mtime); memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data)); - memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags)); - memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize)); + swap(ei1->i_flags, ei2->i_flags); + swap(ei1->i_disksize, ei2->i_disksize); ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS); ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS); @@ -351,11 +349,14 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) raw_inode = ext4_raw_inode(&iloc); if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) { - err = -EOVERFLOW; + err = ext4_expand_extra_isize(inode, + EXT4_SB(sb)->s_want_extra_isize, + &iloc); + if (err) + goto out_unlock; + } else { brelse(iloc.bh); - goto out_unlock; } - brelse(iloc.bh); dquot_initialize(inode); diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 581e357e8406c7cdea04999bdd89a12762c55e89..701085620cd82cee3fda28ff6ca65921a9119fc1 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2295,6 +2295,9 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) int err, buddy_loaded = 0; struct ext4_buddy e4b; struct ext4_group_info *grinfo; + unsigned char blocksize_bits = min_t(unsigned char, + sb->s_blocksize_bits, + EXT4_MAX_BLOCK_LOG_SIZE); struct sg { struct ext4_group_info info; ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2]; @@ -2306,8 +2309,9 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) " 2^0 2^1 2^2 2^3 2^4 2^5 2^6 " " 2^7 2^8 2^9 2^10 2^11 2^12 2^13 ]\n"); - i = (sb->s_blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) + + i = (blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) + sizeof(struct ext4_group_info); + grinfo = ext4_get_group_info(sb, group); /* Load the group info in memory only if not already loaded. */ if (unlikely(EXT4_MB_GRP_NEED_INIT(grinfo))) { @@ -2327,7 +2331,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free, sg.info.bb_fragments, sg.info.bb_first_free); for (i = 0; i <= 13; i++) - seq_printf(seq, " %-5u", i <= sb->s_blocksize_bits + 1 ? + seq_printf(seq, " %-5u", i <= blocksize_bits + 1 ? sg.info.bb_counters[i] : 0); seq_printf(seq, " ]\n"); @@ -2892,8 +2896,10 @@ void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid) break; } - if (discard_bio) + if (discard_bio) { submit_bio_wait(discard_bio); + bio_put(discard_bio); + } } list_for_each_entry_safe(entry, tmp, &freed_data_list, efd_list) diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c index eb98356386808bfc4880f29ac89daefdc11bbbfe..84c54f15f1dd7f1163e06c75bd6c0ec5d6b2c6cd 100644 --- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c @@ -185,7 +185,7 @@ static int kmmpd(void *data) goto exit_thread; } - if (sb->s_flags & MS_RDONLY) { + if (sb_rdonly(sb)) { ext4_warning(sb, "kmmpd being stopped since filesystem " "has been remounted as readonly."); goto exit_thread; @@ -367,7 +367,7 @@ int ext4_multi_mount_protect(struct super_block *sb, goto failed; } - mmpd_data = kmalloc(sizeof(struct mmpd_data), GFP_KERNEL); + mmpd_data = kmalloc(sizeof(*mmpd_data), GFP_KERNEL); if (!mmpd_data) { ext4_warning(sb, "not enough memory for mmpd_data"); goto failed; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 13f0cadb1238e61983629e02cda233a60b84f6d1..c1cf020d18895ccedca1690431e009c1f05ad846 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1342,13 +1342,12 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, struct super_block *sb; struct buffer_head *bh_use[NAMEI_RA_SIZE]; struct buffer_head *bh, *ret = NULL; - ext4_lblk_t start, block, b; + ext4_lblk_t start, block; const u8 *name = d_name->name; - int ra_max = 0; /* Number of bh's in the readahead + size_t ra_max = 0; /* Number of bh's in the readahead buffer, bh_use[] */ - int ra_ptr = 0; /* Current index into readahead + size_t ra_ptr = 0; /* Current index into readahead buffer */ - int num = 0; ext4_lblk_t nblocks; int i, namelen, retval; struct ext4_filename fname; @@ -1411,31 +1410,17 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, if (ra_ptr >= ra_max) { /* Refill the readahead buffer */ ra_ptr = 0; - b = block; - for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) { - /* - * Terminate if we reach the end of the - * directory and must wrap, or if our - * search has finished at this block. - */ - if (b >= nblocks || (num && block == start)) { - bh_use[ra_max] = NULL; - break; - } - num++; - bh = ext4_getblk(NULL, dir, b++, 0); - if (IS_ERR(bh)) { - if (ra_max == 0) { - ret = bh; - goto cleanup_and_exit; - } - break; - } - bh_use[ra_max] = bh; - if (bh) - ll_rw_block(REQ_OP_READ, - REQ_META | REQ_PRIO, - 1, &bh); + if (block < start) + ra_max = start - block; + else + ra_max = nblocks - block; + ra_max = min(ra_max, ARRAY_SIZE(bh_use)); + retval = ext4_bread_batch(dir, block, ra_max, + false /* wait */, bh_use); + if (retval) { + ret = ERR_PTR(retval); + ra_max = 0; + goto cleanup_and_exit; } } if ((bh = bh_use[ra_ptr++]) == NULL) @@ -2395,19 +2380,22 @@ static int ext4_delete_entry(handle_t *handle, } /* - * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2, - * since this indicates that nlinks count was previously 1. + * Set directory link count to 1 if nlinks > EXT4_LINK_MAX, or if nlinks == 2 + * since this indicates that nlinks count was previously 1 to avoid overflowing + * the 16-bit i_links_count field on disk. Directories with i_nlink == 1 mean + * that subdirectory link counts are not being maintained accurately. + * + * The caller has already checked for i_nlink overflow in case the DIR_LINK + * feature is not enabled and returned -EMLINK. The is_dx() check is a proxy + * for checking S_ISDIR(inode) (since the INODE_INDEX feature will not be set + * on regular files) and to avoid creating huge/slow non-HTREE directories. */ static void ext4_inc_count(handle_t *handle, struct inode *inode) { inc_nlink(inode); - if (is_dx(inode) && inode->i_nlink > 1) { - /* limit is 16-bit i_links_count */ - if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) { - set_nlink(inode, 1); - ext4_set_feature_dir_nlink(inode->i_sb); - } - } + if (is_dx(inode) && + (inode->i_nlink > EXT4_LINK_MAX || inode->i_nlink == 2)) + set_nlink(inode, 1); } /* diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index c2fce4478cca26445c0605ff61a1f1b00302c41c..55ad7dd149d005dca26109fd0f018fdd0e075220 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -300,7 +300,7 @@ static void ext4_end_bio(struct bio *bio) char b[BDEVNAME_SIZE]; if (WARN_ONCE(!io_end, "io_end is NULL: %s: sector %Lu len %u err %d\n", - bdevname(bio->bi_bdev, b), + bio_devname(bio, b), (long long) bio->bi_iter.bi_sector, (unsigned) bio_sectors(bio), bio->bi_status)) { @@ -375,7 +375,7 @@ static int io_submit_init_bio(struct ext4_io_submit *io, return -ENOMEM; wbc_init_bio(io->io_wbc, bio); bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); - bio->bi_bdev = bh->b_bdev; + bio_set_dev(bio, bh->b_bdev); bio->bi_end_io = ext4_end_bio; bio->bi_private = ext4_get_io_end(io->io_end); io->io_bio = bio; diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c index 40a5497b0f605c8bbc9b2192591bb49acdb0d2b7..04c90643af7a4763647919188e67f5e0479cec1b 100644 --- a/fs/ext4/readpage.c +++ b/fs/ext4/readpage.c @@ -254,7 +254,7 @@ int ext4_mpage_readpages(struct address_space *mapping, fscrypt_release_ctx(ctx); goto set_error_page; } - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector = blocks[0] << (blkbits - 9); bio->bi_end_io = mpage_end_io; bio->bi_private = ctx; diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index c3ed9021b781c57cce5d6cff163c216be6c20020..035cd3f4785e2d824be923cbed2c5012b18abb9c 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1927,7 +1927,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) n_desc_blocks = o_desc_blocks + le16_to_cpu(es->s_reserved_gdt_blocks); n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb); - n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb); + n_blocks_count = (ext4_fsblk_t)n_group * + EXT4_BLOCKS_PER_GROUP(sb); n_group--; /* set to last group number */ } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0886fe82e9c49202311922680a33723c513c9983..b104096fce9eeec4e6079d3d1b05dd8b83fe796b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -405,7 +405,7 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn) static void ext4_handle_error(struct super_block *sb) { - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; if (!test_opt(sb, ERRORS_CONT)) { @@ -587,8 +587,7 @@ void __ext4_std_error(struct super_block *sb, const char *function, /* Special case: if the error is EROFS, and we're not already * inside a transaction, then there's really no point in logging * an error. */ - if (errno == -EROFS && journal_current_handle() == NULL && - (sb->s_flags & MS_RDONLY)) + if (errno == -EROFS && journal_current_handle() == NULL && sb_rdonly(sb)) return; if (ext4_error_ratelimit(sb)) { @@ -628,7 +627,7 @@ void __ext4_abort(struct super_block *sb, const char *function, sb->s_id, function, line, &vaf); va_end(args); - if ((sb->s_flags & MS_RDONLY) == 0) { + if (sb_rdonly(sb) == 0) { ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; /* @@ -889,11 +888,11 @@ static void ext4_put_super(struct super_block *sb) ext4_mb_release(sb); ext4_ext_release(sb); - if (!(sb->s_flags & MS_RDONLY) && !aborted) { + if (!sb_rdonly(sb) && !aborted) { ext4_clear_feature_journal_needs_recovery(sb); es->s_state = cpu_to_le16(sbi->s_mount_state); } - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) ext4_commit_super(sb, 1); for (i = 0; i < sbi->s_gdb_count; i++) @@ -951,6 +950,7 @@ static void ext4_put_super(struct super_block *sb) if (sbi->s_chksum_driver) crypto_free_shash(sbi->s_chksum_driver); kfree(sbi->s_blockgroup_lock); + fs_put_dax(sbi->s_daxdev); kfree(sbi); } @@ -978,8 +978,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) ei->i_es_shk_nr = 0; ei->i_es_shrink_lblk = 0; ei->i_reserved_data_blocks = 0; - ei->i_reserved_meta_blocks = 0; - ei->i_allocated_meta_blocks = 0; ei->i_da_metadata_calc_len = 0; ei->i_da_metadata_calc_last_lblock = 0; spin_lock_init(&(ei->i_block_reservation_lock)); @@ -2101,7 +2099,7 @@ int ext4_seq_options_show(struct seq_file *seq, void *offset) struct super_block *sb = seq->private; int rc; - seq_puts(seq, (sb->s_flags & MS_RDONLY) ? "ro" : "rw"); + seq_puts(seq, sb_rdonly(sb) ? "ro" : "rw"); rc = _ext4_show_options(seq, sb, 1); seq_puts(seq, "\n"); return rc; @@ -2369,7 +2367,7 @@ static int ext4_check_descriptors(struct super_block *sb, "Checksum for group %u failed (%u!=%u)", i, le16_to_cpu(ext4_group_desc_csum(sb, i, gdp)), le16_to_cpu(gdp->bg_checksum)); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { ext4_unlock_group(sb, i); return 0; } @@ -2406,6 +2404,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, unsigned int s_flags = sb->s_flags; int ret, nr_orphans = 0, nr_truncates = 0; #ifdef CONFIG_QUOTA + int quota_update = 0; int i; #endif if (!es->s_last_orphan) { @@ -2444,14 +2443,32 @@ static void ext4_orphan_cleanup(struct super_block *sb, #ifdef CONFIG_QUOTA /* Needed for iput() to work correctly and not trash data */ sb->s_flags |= MS_ACTIVE; - /* Turn on quotas so that they are updated correctly */ + + /* + * Turn on quotas which were not enabled for read-only mounts if + * filesystem has quota feature, so that they are updated correctly. + */ + if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) { + int ret = ext4_enable_quotas(sb); + + if (!ret) + quota_update = 1; + else + ext4_msg(sb, KERN_ERR, + "Cannot turn on quotas: error %d", ret); + } + + /* Turn on journaled quotas used for old sytle */ for (i = 0; i < EXT4_MAXQUOTAS; i++) { if (EXT4_SB(sb)->s_qf_names[i]) { int ret = ext4_quota_on_mount(sb, i); - if (ret < 0) + + if (!ret) + quota_update = 1; + else ext4_msg(sb, KERN_ERR, "Cannot turn on journaled " - "quota: error %d", ret); + "quota: type %d: error %d", i, ret); } } #endif @@ -2512,10 +2529,12 @@ static void ext4_orphan_cleanup(struct super_block *sb, ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up", PLURAL(nr_truncates)); #ifdef CONFIG_QUOTA - /* Turn quotas off */ - for (i = 0; i < EXT4_MAXQUOTAS; i++) { - if (sb_dqopt(sb)->files[i]) - dquot_quota_off(sb, i); + /* Turn off quotas if they were enabled for orphan cleanup */ + if (quota_update) { + for (i = 0; i < EXT4_MAXQUOTAS; i++) { + if (sb_dqopt(sb)->files[i]) + dquot_quota_off(sb, i); + } } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ @@ -3116,8 +3135,7 @@ int ext4_register_li_request(struct super_block *sb, goto out; } - if (first_not_zeroed == ngroups || - (sb->s_flags & MS_RDONLY) || + if (first_not_zeroed == ngroups || sb_rdonly(sb) || !test_opt(sb, INIT_INODE_TABLE)) goto out; @@ -3379,6 +3397,7 @@ static void ext4_set_resv_clusters(struct super_block *sb) static int ext4_fill_super(struct super_block *sb, void *data, int silent) { + struct dax_device *dax_dev = fs_dax_get_by_bdev(sb->s_bdev); char *orig_data = kstrdup(data, GFP_KERNEL); struct buffer_head *bh; struct ext4_super_block *es = NULL; @@ -3404,6 +3423,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) if ((data && !orig_data) || !sbi) goto out_free_base; + sbi->s_daxdev = dax_dev; sbi->s_blockgroup_lock = kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); if (!sbi->s_blockgroup_lock) @@ -3661,7 +3681,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) * previously didn't change the revision level when setting the flags, * so there is a chance incompat flags are set on a rev 0 filesystem. */ - if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY))) + if (!ext4_feature_set_ok(sb, (sb_rdonly(sb)))) goto failed_mount; blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); @@ -3790,12 +3810,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_hash_unsigned = 3; else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { #ifdef __CHAR_UNSIGNED__ - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); sbi->s_hash_unsigned = 3; #else - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); #endif @@ -3995,7 +4015,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) needs_recovery = (es->s_last_orphan != 0 || ext4_has_feature_journal_needs_recovery(sb)); - if (ext4_has_feature_mmp(sb) && !(sb->s_flags & MS_RDONLY)) + if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb)) if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block))) goto failed_mount3a; @@ -4007,7 +4027,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) err = ext4_load_journal(sb, es, journal_devnum); if (err) goto failed_mount3a; - } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && + } else if (test_opt(sb, NOLOAD) && !sb_rdonly(sb) && ext4_has_feature_journal_needs_recovery(sb)) { ext4_msg(sb, KERN_ERR, "required journal recovery " "suppressed and not mounted read-only"); @@ -4121,7 +4141,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount_wq; } - if (DUMMY_ENCRYPTION_ENABLED(sbi) && !(sb->s_flags & MS_RDONLY) && + if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) && !ext4_has_feature_encrypt(sb)) { ext4_set_feature_encrypt(sb); ext4_commit_super(sb, 1); @@ -4175,7 +4195,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount4; } - if (ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY)) + if (ext4_setup_super(sb, es, sb_rdonly(sb))) sb->s_flags |= MS_RDONLY; /* determine the minimum size of new large inodes, if present */ @@ -4263,7 +4283,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) #ifdef CONFIG_QUOTA /* Enable quota usage during mount. */ - if (ext4_has_feature_quota(sb) && !(sb->s_flags & MS_RDONLY)) { + if (ext4_has_feature_quota(sb) && !sb_rdonly(sb)) { err = ext4_enable_quotas(sb); if (err) goto failed_mount8; @@ -4380,6 +4400,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) out_free_base: kfree(sbi); kfree(orig_data); + fs_put_dax(dax_dev); return err ? err : ret; } @@ -4586,7 +4607,7 @@ static int ext4_load_journal(struct super_block *sb, * can get read-write access to the device. */ if (ext4_has_feature_journal_needs_recovery(sb)) { - if (sb->s_flags & MS_RDONLY) { + if (sb_rdonly(sb)) { ext4_msg(sb, KERN_INFO, "INFO: recovery " "required on readonly filesystem"); if (really_read_only) { @@ -4741,8 +4762,7 @@ static void ext4_mark_recovery_complete(struct super_block *sb, if (jbd2_journal_flush(journal) < 0) goto out; - if (ext4_has_feature_journal_needs_recovery(sb) && - sb->s_flags & MS_RDONLY) { + if (ext4_has_feature_journal_needs_recovery(sb) && sb_rdonly(sb)) { ext4_clear_feature_journal_needs_recovery(sb); ext4_commit_super(sb, 1); } @@ -4798,7 +4818,7 @@ int ext4_force_commit(struct super_block *sb) { journal_t *journal; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; journal = EXT4_SB(sb)->s_journal; @@ -4863,7 +4883,7 @@ static int ext4_freeze(struct super_block *sb) int error = 0; journal_t *journal; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; journal = EXT4_SB(sb)->s_journal; @@ -4898,7 +4918,7 @@ static int ext4_freeze(struct super_block *sb) */ static int ext4_unfreeze(struct super_block *sb) { - if ((sb->s_flags & MS_RDONLY) || ext4_forced_shutdown(EXT4_SB(sb))) + if (sb_rdonly(sb) || ext4_forced_shutdown(EXT4_SB(sb))) return 0; if (EXT4_SB(sb)->s_journal) { @@ -5036,7 +5056,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (*flags & MS_LAZYTIME) sb->s_flags |= MS_LAZYTIME; - if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) { + if ((bool)(*flags & MS_RDONLY) != sb_rdonly(sb)) { if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) { err = -EROFS; goto restore_opts; @@ -5131,7 +5151,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) * Reinitialize lazy itable initialization thread based on * current settings */ - if ((sb->s_flags & MS_RDONLY) || !test_opt(sb, INIT_INODE_TABLE)) + if (sb_rdonly(sb) || !test_opt(sb, INIT_INODE_TABLE)) ext4_unregister_li_request(sb); else { ext4_group_t first_not_zeroed; @@ -5196,7 +5216,7 @@ static int ext4_statfs_project(struct super_block *sb, dquot = dqget(sb, qid); if (IS_ERR(dquot)) return PTR_ERR(dquot); - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); limit = (dquot->dq_dqb.dqb_bsoftlimit ? dquot->dq_dqb.dqb_bsoftlimit : @@ -5219,7 +5239,7 @@ static int ext4_statfs_project(struct super_block *sb, (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; } - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); dqput(dquot); return 0; } @@ -5265,18 +5285,13 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } -/* Helper function for writing quotas on sync - we need to start transaction - * before quota file is locked for write. Otherwise the are possible deadlocks: - * Process 1 Process 2 - * ext4_create() quota_sync() - * jbd2_journal_start() write_dquot() - * dquot_initialize() down(dqio_mutex) - * down(dqio_mutex) jbd2_journal_start() - * - */ #ifdef CONFIG_QUOTA +/* + * Helper functions so that transaction is started before we acquire dqio_sem + * to keep correct lock ordering of transaction > dqio_sem + */ static inline struct inode *dquot_to_inode(struct dquot *dquot) { return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type]; @@ -5411,6 +5426,13 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, ext4_msg(sb, KERN_WARNING, "Quota file not on filesystem root. " "Journaled quota will not work"); + sb_dqopt(sb)->flags |= DQUOT_NOLIST_DIRTY; + } else { + /* + * Clear the flag just in case mount options changed since + * last time. + */ + sb_dqopt(sb)->flags &= ~DQUOT_NOLIST_DIRTY; } /* @@ -5507,13 +5529,16 @@ static int ext4_enable_quotas(struct super_block *sb) test_opt(sb, PRJQUOTA), }; - sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE; + sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE | DQUOT_NOLIST_DIRTY; for (type = 0; type < EXT4_MAXQUOTAS; type++) { if (qf_inums[type]) { err = ext4_quota_enable(sb, type, QFMT_VFS_V1, DQUOT_USAGE_ENABLED | (quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0)); if (err) { + for (type--; type >= 0; type--) + dquot_quota_off(sb, type); + ext4_warning(sb, "Failed to enable quota tracking " "(type=%d, err=%d). Please run " @@ -5703,7 +5728,7 @@ static inline int ext2_feature_set_ok(struct super_block *sb) { if (ext4_has_unknown_ext2_incompat_features(sb)) return 0; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 1; if (ext4_has_unknown_ext2_ro_compat_features(sb)) return 0; @@ -5734,7 +5759,7 @@ static inline int ext3_feature_set_ok(struct super_block *sb) return 0; if (!ext4_has_feature_journal(sb)) return 0; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 1; if (ext4_has_unknown_ext3_ro_compat_features(sb)) return 0; diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index cff4f41ced612d9b0f344be66a17e434981f8861..3b69330a42506dc85bf5a51812326b862d499c50 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -317,32 +317,47 @@ static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash) */ static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size) { - unsigned long block = 0; - struct buffer_head *bh; - int blocksize = ea_inode->i_sb->s_blocksize; - size_t csize, copied = 0; - void *copy_pos = buf; - - while (copied < size) { - csize = (size - copied) > blocksize ? blocksize : size - copied; - bh = ext4_bread(NULL, ea_inode, block, 0); - if (IS_ERR(bh)) - return PTR_ERR(bh); - if (!bh) - return -EFSCORRUPTED; + int blocksize = 1 << ea_inode->i_blkbits; + int bh_count = (size + blocksize - 1) >> ea_inode->i_blkbits; + int tail_size = (size % blocksize) ?: blocksize; + struct buffer_head *bhs_inline[8]; + struct buffer_head **bhs = bhs_inline; + int i, ret; + + if (bh_count > ARRAY_SIZE(bhs_inline)) { + bhs = kmalloc_array(bh_count, sizeof(*bhs), GFP_NOFS); + if (!bhs) + return -ENOMEM; + } - memcpy(copy_pos, bh->b_data, csize); - brelse(bh); + ret = ext4_bread_batch(ea_inode, 0 /* block */, bh_count, + true /* wait */, bhs); + if (ret) + goto free_bhs; - copy_pos += csize; - block += 1; - copied += csize; + for (i = 0; i < bh_count; i++) { + /* There shouldn't be any holes in ea_inode. */ + if (!bhs[i]) { + ret = -EFSCORRUPTED; + goto put_bhs; + } + memcpy((char *)buf + blocksize * i, bhs[i]->b_data, + i < bh_count - 1 ? blocksize : tail_size); } - return 0; + ret = 0; +put_bhs: + for (i = 0; i < bh_count; i++) + brelse(bhs[i]); +free_bhs: + if (bhs != bhs_inline) + kfree(bhs); + return ret; } +#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode)->i_mtime.tv_sec) + static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, - struct inode **ea_inode) + u32 ea_inode_hash, struct inode **ea_inode) { struct inode *inode; int err; @@ -372,6 +387,24 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, goto error; } + ext4_xattr_inode_set_class(inode); + + /* + * Check whether this is an old Lustre-style xattr inode. Lustre + * implementation does not have hash validation, rather it has a + * backpointer from ea_inode to the parent inode. + */ + if (ea_inode_hash != ext4_xattr_inode_get_hash(inode) && + EXT4_XATTR_INODE_GET_PARENT(inode) == parent->i_ino && + inode->i_generation == parent->i_generation) { + ext4_set_inode_state(inode, EXT4_STATE_LUSTRE_EA_INODE); + ext4_xattr_inode_set_ref(inode, 1); + } else { + inode_lock(inode); + inode->i_flags |= S_NOQUOTA; + inode_unlock(inode); + } + *ea_inode = inode; return 0; error: @@ -404,8 +437,6 @@ ext4_xattr_inode_verify_hashes(struct inode *ea_inode, return 0; } -#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode)->i_mtime.tv_sec) - /* * Read xattr value from the EA inode. */ @@ -418,7 +449,7 @@ ext4_xattr_inode_get(struct inode *inode, struct ext4_xattr_entry *entry, int err; err = ext4_xattr_inode_iget(inode, le32_to_cpu(entry->e_value_inum), - &ea_inode); + le32_to_cpu(entry->e_hash), &ea_inode); if (err) { ea_inode = NULL; goto out; @@ -436,28 +467,20 @@ ext4_xattr_inode_get(struct inode *inode, struct ext4_xattr_entry *entry, if (err) goto out; - err = ext4_xattr_inode_verify_hashes(ea_inode, entry, buffer, size); - /* - * Compatibility check for old Lustre ea_inode implementation. Old - * version does not have hash validation, but it has a backpointer - * from ea_inode to the parent inode. - */ - if (err == -EFSCORRUPTED) { - if (EXT4_XATTR_INODE_GET_PARENT(ea_inode) != inode->i_ino || - ea_inode->i_generation != inode->i_generation) { + if (!ext4_test_inode_state(ea_inode, EXT4_STATE_LUSTRE_EA_INODE)) { + err = ext4_xattr_inode_verify_hashes(ea_inode, entry, buffer, + size); + if (err) { ext4_warning_inode(ea_inode, "EA inode hash validation failed"); goto out; } - /* Do not add ea_inode to the cache. */ - ea_inode_cache = NULL; - } else if (err) - goto out; - if (ea_inode_cache) - mb_cache_entry_create(ea_inode_cache, GFP_NOFS, - ext4_xattr_inode_get_hash(ea_inode), - ea_inode->i_ino, true /* reusable */); + if (ea_inode_cache) + mb_cache_entry_create(ea_inode_cache, GFP_NOFS, + ext4_xattr_inode_get_hash(ea_inode), + ea_inode->i_ino, true /* reusable */); + } out: iput(ea_inode); return err; @@ -824,10 +847,15 @@ static int ext4_xattr_inode_alloc_quota(struct inode *inode, size_t len) return err; } -static void ext4_xattr_inode_free_quota(struct inode *inode, size_t len) +static void ext4_xattr_inode_free_quota(struct inode *parent, + struct inode *ea_inode, + size_t len) { - dquot_free_space_nodirty(inode, round_up_cluster(inode, len)); - dquot_free_inode(inode); + if (ea_inode && + ext4_test_inode_state(ea_inode, EXT4_STATE_LUSTRE_EA_INODE)) + return; + dquot_free_space_nodirty(parent, round_up_cluster(parent, len)); + dquot_free_inode(parent); } int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode, @@ -1057,7 +1085,9 @@ static int ext4_xattr_inode_inc_ref_all(handle_t *handle, struct inode *parent, if (!entry->e_value_inum) continue; ea_ino = le32_to_cpu(entry->e_value_inum); - err = ext4_xattr_inode_iget(parent, ea_ino, &ea_inode); + err = ext4_xattr_inode_iget(parent, ea_ino, + le32_to_cpu(entry->e_hash), + &ea_inode); if (err) goto cleanup; err = ext4_xattr_inode_inc_ref(handle, ea_inode); @@ -1079,7 +1109,9 @@ static int ext4_xattr_inode_inc_ref_all(handle_t *handle, struct inode *parent, if (!entry->e_value_inum) continue; ea_ino = le32_to_cpu(entry->e_value_inum); - err = ext4_xattr_inode_iget(parent, ea_ino, &ea_inode); + err = ext4_xattr_inode_iget(parent, ea_ino, + le32_to_cpu(entry->e_hash), + &ea_inode); if (err) { ext4_warning(parent->i_sb, "cleanup ea_ino %u iget error %d", ea_ino, @@ -1117,7 +1149,9 @@ ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent, if (!entry->e_value_inum) continue; ea_ino = le32_to_cpu(entry->e_value_inum); - err = ext4_xattr_inode_iget(parent, ea_ino, &ea_inode); + err = ext4_xattr_inode_iget(parent, ea_ino, + le32_to_cpu(entry->e_hash), + &ea_inode); if (err) continue; @@ -1145,7 +1179,7 @@ ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent, } if (!skip_quota) - ext4_xattr_inode_free_quota(parent, + ext4_xattr_inode_free_quota(parent, ea_inode, le32_to_cpu(entry->e_value_size)); /* @@ -1529,7 +1563,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, /* Clear padding bytes. */ memset(val + i->value_len, 0, new_size - i->value_len); } - return 0; + goto update_hash; } /* Compute min_offs and last. */ @@ -1577,6 +1611,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, if (!s->not_found && here->e_value_inum) { ret = ext4_xattr_inode_iget(inode, le32_to_cpu(here->e_value_inum), + le32_to_cpu(here->e_hash), &old_ea_inode); if (ret) { old_ea_inode = NULL; @@ -1595,7 +1630,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, &new_ea_inode); if (ret) { new_ea_inode = NULL; - ext4_xattr_inode_free_quota(inode, i->value_len); + ext4_xattr_inode_free_quota(inode, NULL, i->value_len); goto out; } } @@ -1614,13 +1649,13 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, ext4_warning_inode(new_ea_inode, "dec ref new_ea_inode err=%d", err); - ext4_xattr_inode_free_quota(inode, + ext4_xattr_inode_free_quota(inode, new_ea_inode, i->value_len); } goto out; } - ext4_xattr_inode_free_quota(inode, + ext4_xattr_inode_free_quota(inode, old_ea_inode, le32_to_cpu(here->e_value_size)); } @@ -1693,6 +1728,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, here->e_value_size = cpu_to_le32(i->value_len); } +update_hash: if (i->value) { __le32 hash = 0; @@ -1711,7 +1747,8 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, here->e_name_len, &crc32c_hash, 1); } else if (is_block) { - __le32 *value = s->base + min_offs - new_size; + __le32 *value = s->base + le16_to_cpu( + here->e_value_offs); hash = ext4_xattr_hash_entry(here->e_name, here->e_name_len, value, @@ -1789,8 +1826,10 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, struct mb_cache_entry *ce = NULL; int error = 0; struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode); - struct inode *ea_inode = NULL; - size_t old_ea_inode_size = 0; + struct inode *ea_inode = NULL, *tmp_inode; + size_t old_ea_inode_quota = 0; + unsigned int ea_ino; + #define header(x) ((struct ext4_xattr_header *)(x)) @@ -1815,9 +1854,6 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, ea_bdebug(bs->bh, "modifying in-place"); error = ext4_xattr_set_entry(i, s, handle, inode, true /* is_block */); - if (!error) - ext4_xattr_block_cache_insert(ea_block_cache, - bs->bh); ext4_xattr_block_csum_set(inode, bs->bh); unlock_buffer(bs->bh); if (error == -EFSCORRUPTED) @@ -1852,12 +1888,24 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, * like it has an empty value. */ if (!s->not_found && s->here->e_value_inum) { - /* - * Defer quota free call for previous inode - * until success is guaranteed. - */ - old_ea_inode_size = le32_to_cpu( + ea_ino = le32_to_cpu(s->here->e_value_inum); + error = ext4_xattr_inode_iget(inode, ea_ino, + le32_to_cpu(s->here->e_hash), + &tmp_inode); + if (error) + goto cleanup; + + if (!ext4_test_inode_state(tmp_inode, + EXT4_STATE_LUSTRE_EA_INODE)) { + /* + * Defer quota free call for previous + * inode until success is guaranteed. + */ + old_ea_inode_quota = le32_to_cpu( s->here->e_value_size); + } + iput(tmp_inode); + s->here->e_value_inum = 0; s->here->e_value_size = 0; } @@ -1884,8 +1932,6 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, goto cleanup; if (i->value && s->here->e_value_inum) { - unsigned int ea_ino; - /* * A ref count on ea_inode has been taken as part of the call to * ext4_xattr_set_entry() above. We would like to drop this @@ -1893,7 +1939,9 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, * initialized and has its own ref count on the ea_inode. */ ea_ino = le32_to_cpu(s->here->e_value_inum); - error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode); + error = ext4_xattr_inode_iget(inode, ea_ino, + le32_to_cpu(s->here->e_hash), + &ea_inode); if (error) { ea_inode = NULL; goto cleanup; @@ -1973,6 +2021,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, } else if (bs->bh && s->base == bs->bh->b_data) { /* We were modifying this block in-place. */ ea_bdebug(bs->bh, "keeping this block"); + ext4_xattr_block_cache_insert(ea_block_cache, bs->bh); new_bh = bs->bh; get_bh(new_bh); } else { @@ -2042,8 +2091,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, } } - if (old_ea_inode_size) - ext4_xattr_inode_free_quota(inode, old_ea_inode_size); + if (old_ea_inode_quota) + ext4_xattr_inode_free_quota(inode, NULL, old_ea_inode_quota); /* Update the inode. */ EXT4_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; @@ -2070,7 +2119,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, /* If there was an error, revert the quota charge. */ if (error) - ext4_xattr_inode_free_quota(inode, + ext4_xattr_inode_free_quota(inode, ea_inode, i_size_read(ea_inode)); iput(ea_inode); } @@ -2625,23 +2674,21 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, struct ext4_inode *raw_inode, handle_t *handle) { struct ext4_xattr_ibody_header *header; - struct buffer_head *bh = NULL; + struct buffer_head *bh; + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + static unsigned int mnt_count; size_t min_offs; size_t ifree, bfree; int total_ino; void *base, *end; int error = 0, tried_min_extra_isize = 0; - int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); + int s_min_extra_isize = le16_to_cpu(sbi->s_es->s_min_extra_isize); int isize_diff; /* How much do we need to grow i_extra_isize */ - int no_expand; - - if (ext4_write_trylock_xattr(inode, &no_expand) == 0) - return 0; retry: isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) - goto out; + return 0; header = IHDR(inode, raw_inode); @@ -2676,6 +2723,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, EXT4_ERROR_INODE(inode, "bad block %llu", EXT4_I(inode)->i_file_acl); error = -EFSCORRUPTED; + brelse(bh); goto cleanup; } base = BHDR(bh); @@ -2683,11 +2731,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, min_offs = end - base; bfree = ext4_xattr_free_space(BFIRST(bh), &min_offs, base, NULL); + brelse(bh); if (bfree + ifree < isize_diff) { if (!tried_min_extra_isize && s_min_extra_isize) { tried_min_extra_isize++; new_extra_isize = s_min_extra_isize; - brelse(bh); goto retry; } error = -ENOSPC; @@ -2705,7 +2753,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, s_min_extra_isize) { tried_min_extra_isize++; new_extra_isize = s_min_extra_isize; - brelse(bh); goto retry; } goto cleanup; @@ -2717,18 +2764,13 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, EXT4_GOOD_OLD_INODE_SIZE + new_extra_isize, (void *)header, total_ino); EXT4_I(inode)->i_extra_isize = new_extra_isize; - brelse(bh); -out: - ext4_write_unlock_xattr(inode, &no_expand); - return 0; cleanup: - brelse(bh); - /* - * Inode size expansion failed; don't try again - */ - no_expand = 1; - ext4_write_unlock_xattr(inode, &no_expand); + if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) { + ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.", + inode->i_ino); + mnt_count = le16_to_cpu(sbi->s_es->s_mnt_count); + } return error; } @@ -2793,6 +2835,7 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, struct ext4_xattr_ibody_header *header; struct ext4_iloc iloc = { .bh = NULL }; struct ext4_xattr_entry *entry; + struct inode *ea_inode; int error; error = ext4_xattr_ensure_credits(handle, inode, extra_credits, @@ -2847,10 +2890,19 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, if (ext4_has_feature_ea_inode(inode->i_sb)) { for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); - entry = EXT4_XATTR_NEXT(entry)) - if (entry->e_value_inum) - ext4_xattr_inode_free_quota(inode, + entry = EXT4_XATTR_NEXT(entry)) { + if (!entry->e_value_inum) + continue; + error = ext4_xattr_inode_iget(inode, + le32_to_cpu(entry->e_value_inum), + le32_to_cpu(entry->e_hash), + &ea_inode); + if (error) + continue; + ext4_xattr_inode_free_quota(inode, ea_inode, le32_to_cpu(entry->e_value_size)); + iput(ea_inode); + } } diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index b4b8438c42ef9cbbe9805fbc233a5a9cde216ada..436b3a1464d9bd29c8756750b3a38154b2e1c313 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -207,15 +207,16 @@ static int __f2fs_set_acl(struct inode *inode, int type, void *value = NULL; size_t size = 0; int error; + umode_t mode = inode->i_mode; switch (type) { case ACL_TYPE_ACCESS: name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; if (acl && !ipage) { - error = posix_acl_update_mode(inode, &inode->i_mode, &acl); + error = posix_acl_update_mode(inode, &mode, &acl); if (error) return error; - set_acl_inode(inode, inode->i_mode); + set_acl_inode(inode, mode); } break; diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 5b876f6d3f6b1d81a661f00a3d7c40cb99a83597..04fe1df052b2b9e6a0c3f662797c3f46727ccdbe 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -230,8 +230,9 @@ void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index) ra_meta_pages(sbi, index, BIO_MAX_PAGES, META_POR, true); } -static int f2fs_write_meta_page(struct page *page, - struct writeback_control *wbc) +static int __f2fs_write_meta_page(struct page *page, + struct writeback_control *wbc, + enum iostat_type io_type) { struct f2fs_sb_info *sbi = F2FS_P_SB(page); @@ -244,7 +245,7 @@ static int f2fs_write_meta_page(struct page *page, if (unlikely(f2fs_cp_error(sbi))) goto redirty_out; - write_meta_page(sbi, page); + write_meta_page(sbi, page, io_type); dec_page_count(sbi, F2FS_DIRTY_META); if (wbc->for_reclaim) @@ -263,6 +264,12 @@ static int f2fs_write_meta_page(struct page *page, return AOP_WRITEPAGE_ACTIVATE; } +static int f2fs_write_meta_page(struct page *page, + struct writeback_control *wbc) +{ + return __f2fs_write_meta_page(page, wbc, FS_META_IO); +} + static int f2fs_write_meta_pages(struct address_space *mapping, struct writeback_control *wbc) { @@ -283,7 +290,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping, trace_f2fs_writepages(mapping->host, wbc, META); diff = nr_pages_to_write(sbi, META, wbc); - written = sync_meta_pages(sbi, META, wbc->nr_to_write); + written = sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO); mutex_unlock(&sbi->cp_mutex); wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); return 0; @@ -295,7 +302,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping, } long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, - long nr_to_write) + long nr_to_write, enum iostat_type io_type) { struct address_space *mapping = META_MAPPING(sbi); pgoff_t index = 0, end = ULONG_MAX, prev = ULONG_MAX; @@ -346,7 +353,7 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, if (!clear_page_dirty_for_io(page)) goto continue_unlock; - if (mapping->a_ops->writepage(page, &wbc)) { + if (__f2fs_write_meta_page(page, &wbc, io_type)) { unlock_page(page); break; } @@ -581,11 +588,24 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) int recover_orphan_inodes(struct f2fs_sb_info *sbi) { block_t start_blk, orphan_blocks, i, j; - int err; + unsigned int s_flags = sbi->sb->s_flags; + int err = 0; if (!is_set_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG)) return 0; + if (s_flags & MS_RDONLY) { + f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs"); + sbi->sb->s_flags &= ~MS_RDONLY; + } + +#ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sbi->sb->s_flags |= MS_ACTIVE; + /* Turn on quotas so that they are updated correctly */ + f2fs_enable_quota_files(sbi); +#endif + start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi); orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi); @@ -601,14 +621,21 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi) err = recover_orphan_inode(sbi, ino); if (err) { f2fs_put_page(page, 1); - return err; + goto out; } } f2fs_put_page(page, 1); } /* clear Orphan Flag */ clear_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG); - return 0; +out: +#ifdef CONFIG_QUOTA + /* Turn quotas off */ + f2fs_quota_off_umount(sbi->sb); +#endif + sbi->sb->s_flags = s_flags; /* Restore MS_RDONLY status */ + + return err; } static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) @@ -904,7 +931,14 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) if (inode) { unsigned long cur_ino = inode->i_ino; + if (is_dir) + F2FS_I(inode)->cp_task = current; + filemap_fdatawrite(inode->i_mapping); + + if (is_dir) + F2FS_I(inode)->cp_task = NULL; + iput(inode); /* We need to give cpu to another writers. */ if (ino == cur_ino) { @@ -1017,7 +1051,7 @@ static int block_operations(struct f2fs_sb_info *sbi) if (get_pages(sbi, F2FS_DIRTY_NODES)) { up_write(&sbi->node_write); - err = sync_node_pages(sbi, &wbc); + err = sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO); if (err) { up_write(&sbi->node_change); f2fs_unlock_all(sbi); @@ -1115,7 +1149,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* Flush all the NAT/SIT pages */ while (get_pages(sbi, F2FS_DIRTY_META)) { - sync_meta_pages(sbi, META, LONG_MAX); + sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); if (unlikely(f2fs_cp_error(sbi))) return -EIO; } @@ -1194,7 +1228,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* Flush all the NAT BITS pages */ while (get_pages(sbi, F2FS_DIRTY_META)) { - sync_meta_pages(sbi, META, LONG_MAX); + sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); if (unlikely(f2fs_cp_error(sbi))) return -EIO; } @@ -1249,7 +1283,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) percpu_counter_set(&sbi->alloc_valid_block_count, 0); /* Here, we only have one bio having CP pack */ - sync_meta_pages(sbi, META_FLUSH, LONG_MAX); + sync_meta_pages(sbi, META_FLUSH, LONG_MAX, FS_CP_META_IO); /* wait for previous submitted meta pages writeback */ wait_on_all_pages_writeback(sbi); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 87c1f4150c645c83c64cd7f90243d347121f8886..36b535207c88906efae946f71195781497be87f5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -142,7 +142,7 @@ struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi, } } if (bio) { - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(blk_addr); } return bdev; @@ -161,7 +161,8 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr) static bool __same_bdev(struct f2fs_sb_info *sbi, block_t blk_addr, struct bio *bio) { - return f2fs_target_device(sbi, blk_addr, NULL) == bio->bi_bdev; + struct block_device *b = f2fs_target_device(sbi, blk_addr, NULL); + return bio->bi_disk == b->bd_disk && bio->bi_partno == b->bd_partno; } /* @@ -456,14 +457,65 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio) return err; } +static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, + unsigned nr_pages) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct fscrypt_ctx *ctx = NULL; + struct bio *bio; + + if (f2fs_encrypted_file(inode)) { + ctx = fscrypt_get_ctx(inode, GFP_NOFS); + if (IS_ERR(ctx)) + return ERR_CAST(ctx); + + /* wait the page to be moved by cleaning */ + f2fs_wait_on_block_writeback(sbi, blkaddr); + } + + bio = bio_alloc(GFP_KERNEL, min_t(int, nr_pages, BIO_MAX_PAGES)); + if (!bio) { + if (ctx) + fscrypt_release_ctx(ctx); + return ERR_PTR(-ENOMEM); + } + f2fs_target_device(sbi, blkaddr, bio); + bio->bi_end_io = f2fs_read_end_io; + bio->bi_private = ctx; + bio_set_op_attrs(bio, REQ_OP_READ, 0); + + return bio; +} + +/* This can handle encryption stuffs */ +static int f2fs_submit_page_read(struct inode *inode, struct page *page, + block_t blkaddr) +{ + struct bio *bio = f2fs_grab_read_bio(inode, blkaddr, 1); + + if (IS_ERR(bio)) + return PTR_ERR(bio); + + if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { + bio_put(bio); + return -EFAULT; + } + __submit_bio(F2FS_I_SB(inode), bio, DATA); + return 0; +} + static void __set_data_blkaddr(struct dnode_of_data *dn) { struct f2fs_node *rn = F2FS_NODE(dn->node_page); __le32 *addr_array; + int base = 0; + + if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode)) + base = get_extra_isize(dn->inode); /* Get physical address of data block */ addr_array = blkaddr_in_node(rn); - addr_array[dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr); + addr_array[base + dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr); } /* @@ -507,8 +559,8 @@ int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count) f2fs_wait_on_page_writeback(dn->node_page, NODE, true); for (; count > 0; dn->ofs_in_node++) { - block_t blkaddr = - datablock_addr(dn->node_page, dn->ofs_in_node); + block_t blkaddr = datablock_addr(dn->inode, + dn->node_page, dn->ofs_in_node); if (blkaddr == NULL_ADDR) { dn->data_blkaddr = NEW_ADDR; __set_data_blkaddr(dn); @@ -569,16 +621,6 @@ struct page *get_read_data_page(struct inode *inode, pgoff_t index, struct page *page; struct extent_info ei = {0,0,0}; int err; - struct f2fs_io_info fio = { - .sbi = F2FS_I_SB(inode), - .type = DATA, - .op = REQ_OP_READ, - .op_flags = op_flags, - .encrypted_page = NULL, - }; - - if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) - return read_mapping_page(mapping, index, NULL); page = f2fs_grab_cache_page(mapping, index, for_write); if (!page) @@ -619,9 +661,7 @@ struct page *get_read_data_page(struct inode *inode, pgoff_t index, return page; } - fio.new_blkaddr = fio.old_blkaddr = dn.data_blkaddr; - fio.page = page; - err = f2fs_submit_page_bio(&fio); + err = f2fs_submit_page_read(inode, page, dn.data_blkaddr); if (err) goto put_err; return page; @@ -755,7 +795,8 @@ static int __allocate_data_block(struct dnode_of_data *dn) if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) return -EPERM; - dn->data_blkaddr = datablock_addr(dn->node_page, dn->ofs_in_node); + dn->data_blkaddr = datablock_addr(dn->inode, + dn->node_page, dn->ofs_in_node); if (dn->data_blkaddr == NEW_ADDR) goto alloc; @@ -781,7 +822,7 @@ static int __allocate_data_block(struct dnode_of_data *dn) static inline bool __force_buffered_io(struct inode *inode, int rw) { - return ((f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) || + return (f2fs_encrypted_file(inode) || (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS)) || F2FS_I_SB(inode)->s_ndevs); } @@ -813,7 +854,7 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from) F2FS_GET_BLOCK_PRE_AIO : F2FS_GET_BLOCK_PRE_DIO); } - if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA) { + if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) { err = f2fs_convert_inline_inode(inode); if (err) return err; @@ -902,7 +943,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, end_offset = ADDRS_PER_PAGE(dn.node_page, inode); next_block: - blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + blkaddr = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node); if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { if (create) { @@ -1039,7 +1080,7 @@ static int get_data_block_dio(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { return __get_data_block(inode, iblock, bh_result, create, - F2FS_GET_BLOCK_DIO, NULL); + F2FS_GET_BLOCK_DEFAULT, NULL); } static int get_data_block_bmap(struct inode *inode, sector_t iblock, @@ -1145,35 +1186,6 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, return ret; } -static struct bio *f2fs_grab_bio(struct inode *inode, block_t blkaddr, - unsigned nr_pages) -{ - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct fscrypt_ctx *ctx = NULL; - struct bio *bio; - - if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { - ctx = fscrypt_get_ctx(inode, GFP_NOFS); - if (IS_ERR(ctx)) - return ERR_CAST(ctx); - - /* wait the page to be moved by cleaning */ - f2fs_wait_on_encrypted_page_writeback(sbi, blkaddr); - } - - bio = bio_alloc(GFP_KERNEL, min_t(int, nr_pages, BIO_MAX_PAGES)); - if (!bio) { - if (ctx) - fscrypt_release_ctx(ctx); - return ERR_PTR(-ENOMEM); - } - f2fs_target_device(sbi, blkaddr, bio); - bio->bi_end_io = f2fs_read_end_io; - bio->bi_private = ctx; - - return bio; -} - /* * This function was originally taken from fs/mpage.c, and customized for f2fs. * Major change was from block_size == page_size in f2fs by default. @@ -1239,7 +1251,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping, map.m_len = last_block - block_in_file; if (f2fs_map_blocks(inode, &map, 0, - F2FS_GET_BLOCK_READ)) + F2FS_GET_BLOCK_DEFAULT)) goto set_error_page; } got_it: @@ -1270,12 +1282,11 @@ static int f2fs_mpage_readpages(struct address_space *mapping, bio = NULL; } if (bio == NULL) { - bio = f2fs_grab_bio(inode, block_nr, nr_pages); + bio = f2fs_grab_read_bio(inode, block_nr, nr_pages); if (IS_ERR(bio)) { bio = NULL; goto set_error_page; } - bio_set_op_attrs(bio, REQ_OP_READ, 0); } if (bio_add_page(bio, page, blocksize, 0) < blocksize) @@ -1340,11 +1351,11 @@ static int encrypt_one_page(struct f2fs_io_info *fio) struct inode *inode = fio->page->mapping->host; gfp_t gfp_flags = GFP_NOFS; - if (!f2fs_encrypted_inode(inode) || !S_ISREG(inode->i_mode)) + if (!f2fs_encrypted_file(inode)) return 0; /* wait for GCed encrypted page writeback */ - f2fs_wait_on_encrypted_page_writeback(fio->sbi, fio->old_blkaddr); + f2fs_wait_on_block_writeback(fio->sbi, fio->old_blkaddr); retry_encrypt: fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page, @@ -1470,7 +1481,8 @@ int do_write_data_page(struct f2fs_io_info *fio) } static int __write_data_page(struct page *page, bool *submitted, - struct writeback_control *wbc) + struct writeback_control *wbc, + enum iostat_type io_type) { struct inode *inode = page->mapping->host; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); @@ -1491,6 +1503,7 @@ static int __write_data_page(struct page *page, bool *submitted, .encrypted_page = NULL, .submitted = false, .need_lock = LOCK_RETRY, + .io_type = io_type, }; trace_f2fs_writepage(page, DATA); @@ -1597,7 +1610,7 @@ static int __write_data_page(struct page *page, bool *submitted, static int f2fs_write_data_page(struct page *page, struct writeback_control *wbc) { - return __write_data_page(page, NULL, wbc); + return __write_data_page(page, NULL, wbc, FS_DATA_IO); } /* @@ -1606,7 +1619,8 @@ static int f2fs_write_data_page(struct page *page, * warm/hot data page. */ static int f2fs_write_cache_pages(struct address_space *mapping, - struct writeback_control *wbc) + struct writeback_control *wbc, + enum iostat_type io_type) { int ret = 0; int done = 0; @@ -1696,7 +1710,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, if (!clear_page_dirty_for_io(page)) goto continue_unlock; - ret = __write_data_page(page, &submitted, wbc); + ret = __write_data_page(page, &submitted, wbc, io_type); if (unlikely(ret)) { /* * keep nr_to_write, since vfs uses this to @@ -1751,8 +1765,9 @@ static int f2fs_write_cache_pages(struct address_space *mapping, return ret; } -static int f2fs_write_data_pages(struct address_space *mapping, - struct writeback_control *wbc) +int __f2fs_write_data_pages(struct address_space *mapping, + struct writeback_control *wbc, + enum iostat_type io_type) { struct inode *inode = mapping->host; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); @@ -1789,7 +1804,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, goto skip_write; blk_start_plug(&plug); - ret = f2fs_write_cache_pages(mapping, wbc); + ret = f2fs_write_cache_pages(mapping, wbc, io_type); blk_finish_plug(&plug); if (wbc->sync_mode == WB_SYNC_ALL) @@ -1808,6 +1823,16 @@ static int f2fs_write_data_pages(struct address_space *mapping, return 0; } +static int f2fs_write_data_pages(struct address_space *mapping, + struct writeback_control *wbc) +{ + struct inode *inode = mapping->host; + + return __f2fs_write_data_pages(mapping, wbc, + F2FS_I(inode)->cp_task == current ? + FS_CP_DATA_IO : FS_DATA_IO); +} + static void f2fs_write_failed(struct address_space *mapping, loff_t to) { struct inode *inode = mapping->host; @@ -1857,7 +1882,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, set_new_dnode(&dn, inode, ipage, ipage, 0); if (f2fs_has_inline_data(inode)) { - if (pos + len <= MAX_INLINE_DATA) { + if (pos + len <= MAX_INLINE_DATA(inode)) { read_inline_data(page, ipage); set_inode_flag(inode, FI_DATA_EXIST); if (inode->i_nlink) @@ -1955,8 +1980,8 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, f2fs_wait_on_page_writeback(page, DATA, false); /* wait for GCed encrypted page writeback */ - if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) - f2fs_wait_on_encrypted_page_writeback(sbi, blkaddr); + if (f2fs_encrypted_file(inode)) + f2fs_wait_on_block_writeback(sbi, blkaddr); if (len == PAGE_SIZE || PageUptodate(page)) return 0; @@ -1970,21 +1995,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, zero_user_segment(page, 0, PAGE_SIZE); SetPageUptodate(page); } else { - struct bio *bio; - - bio = f2fs_grab_bio(inode, blkaddr, 1); - if (IS_ERR(bio)) { - err = PTR_ERR(bio); - goto fail; - } - bio->bi_opf = REQ_OP_READ; - if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { - bio_put(bio); - err = -EFAULT; + err = f2fs_submit_page_read(inode, page, blkaddr); + if (err) goto fail; - } - - __submit_bio(sbi, bio, DATA); lock_page(page); if (unlikely(page->mapping != mapping)) { @@ -2074,10 +2087,13 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) up_read(&F2FS_I(inode)->dio_rwsem[rw]); if (rw == WRITE) { - if (err > 0) + if (err > 0) { + f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_IO, + err); set_inode_flag(inode, FI_UPDATE_WRITE); - else if (err < 0) + } else if (err < 0) { f2fs_write_failed(mapping, offset + count); + } } trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); @@ -2252,7 +2268,10 @@ int f2fs_migrate_page(struct address_space *mapping, SetPagePrivate(newpage); set_page_private(newpage, page_private(page)); - migrate_page_copy(newpage, page); + if (mode != MIGRATE_SYNC_NO_COPY) + migrate_page_copy(newpage, page); + else + migrate_page_states(newpage, page); return MIGRATEPAGE_SUCCESS; } diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 37f9c7f556058fcda91b15b411acfeebdf48824d..c0c933ad43c8dce1910fe18615def9c96853bacb 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -705,6 +705,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, struct f2fs_dentry_block *dentry_blk; unsigned int bit_pos; int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); + struct address_space *mapping = page_mapping(page); + unsigned long flags; int i; f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); @@ -735,6 +737,11 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, if (bit_pos == NR_DENTRY_IN_BLOCK && !truncate_hole(dir, page->index, page->index + 1)) { + spin_lock_irqsave(&mapping->tree_lock, flags); + radix_tree_tag_clear(&mapping->page_tree, page_index(page), + PAGECACHE_TAG_DIRTY); + spin_unlock_irqrestore(&mapping->tree_lock, flags); + clear_page_dirty_for_io(page); ClearPagePrivate(page); ClearPageUptodate(page); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 94a88b233e98df304e4067c636791f76cf73279c..9a7c903869477835afe192e15b064c6832297520 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -91,6 +91,8 @@ extern char *fault_name[FAULT_MAX]; #define F2FS_MOUNT_LFS 0x00040000 #define F2FS_MOUNT_USRQUOTA 0x00080000 #define F2FS_MOUNT_GRPQUOTA 0x00100000 +#define F2FS_MOUNT_PRJQUOTA 0x00200000 +#define F2FS_MOUNT_QUOTA 0x00400000 #define clear_opt(sbi, option) ((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option) #define set_opt(sbi, option) ((sbi)->mount_opt.opt |= F2FS_MOUNT_##option) @@ -110,8 +112,12 @@ struct f2fs_mount_info { unsigned int opt; }; -#define F2FS_FEATURE_ENCRYPT 0x0001 -#define F2FS_FEATURE_BLKZONED 0x0002 +#define F2FS_FEATURE_ENCRYPT 0x0001 +#define F2FS_FEATURE_BLKZONED 0x0002 +#define F2FS_FEATURE_ATOMIC_WRITE 0x0004 +#define F2FS_FEATURE_EXTRA_ATTR 0x0008 +#define F2FS_FEATURE_PRJQUOTA 0x0010 +#define F2FS_FEATURE_INODE_CHKSUM 0x0020 #define F2FS_HAS_FEATURE(sb, mask) \ ((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0) @@ -142,6 +148,8 @@ enum { (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) #define MAX_DISCARD_BLOCKS(sbi) BLKS_PER_SEC(sbi) #define DISCARD_ISSUE_RATE 8 +#define DEF_MIN_DISCARD_ISSUE_TIME 50 /* 50 ms, if exists */ +#define DEF_MAX_DISCARD_ISSUE_TIME 60000 /* 60 s, if no candidates */ #define DEF_CP_INTERVAL 60 /* 60 secs */ #define DEF_IDLE_INTERVAL 5 /* 5 secs */ @@ -190,11 +198,18 @@ struct discard_entry { unsigned char discard_map[SIT_VBLOCK_MAP_SIZE]; /* segment discard bitmap */ }; +/* default discard granularity of inner discard thread, unit: block count */ +#define DEFAULT_DISCARD_GRANULARITY 16 + /* max discard pend list number */ #define MAX_PLIST_NUM 512 #define plist_idx(blk_num) ((blk_num) >= MAX_PLIST_NUM ? \ (MAX_PLIST_NUM - 1) : (blk_num - 1)) +#define P_ACTIVE 0x01 +#define P_TRIM 0x02 +#define plist_issue(tag) (((tag) & P_ACTIVE) || ((tag) & P_TRIM)) + enum { D_PREP, D_SUBMIT, @@ -230,11 +245,14 @@ struct discard_cmd_control { struct task_struct *f2fs_issue_discard; /* discard thread */ struct list_head entry_list; /* 4KB discard entry list */ struct list_head pend_list[MAX_PLIST_NUM];/* store pending entries */ + unsigned char pend_list_tag[MAX_PLIST_NUM];/* tag for pending entries */ struct list_head wait_list; /* store on-flushing entries */ wait_queue_head_t discard_wait_queue; /* waiting queue for wake-up */ + unsigned int discard_wake; /* to wake up discard thread */ struct mutex cmd_lock; unsigned int nr_discards; /* # of discards in the list */ unsigned int max_discards; /* max. discards to be issued */ + unsigned int discard_granularity; /* discard granularity */ unsigned int undiscard_blks; /* # of undiscard blocks */ atomic_t issued_discard; /* # of issued discard */ atomic_t issing_discard; /* # of issing discard */ @@ -308,6 +326,7 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal, struct f2fs_flush_device) #define F2FS_IOC_GARBAGE_COLLECT_RANGE _IOW(F2FS_IOCTL_MAGIC, 11, \ struct f2fs_gc_range) +#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, __u32) #define F2FS_IOC_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY #define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY @@ -332,6 +351,9 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal, #define F2FS_IOC32_GETVERSION FS_IOC32_GETVERSION #endif +#define F2FS_IOC_FSGETXATTR FS_IOC_FSGETXATTR +#define F2FS_IOC_FSSETXATTR FS_IOC_FSSETXATTR + struct f2fs_gc_range { u32 sync; u64 start; @@ -355,16 +377,36 @@ struct f2fs_flush_device { u32 segments; /* # of segments to flush */ }; +/* for inline stuff */ +#define DEF_INLINE_RESERVED_SIZE 1 +static inline int get_extra_isize(struct inode *inode); +#define MAX_INLINE_DATA(inode) (sizeof(__le32) * \ + (CUR_ADDRS_PER_INODE(inode) - \ + DEF_INLINE_RESERVED_SIZE - \ + F2FS_INLINE_XATTR_ADDRS)) + +/* for inline dir */ +#define NR_INLINE_DENTRY(inode) (MAX_INLINE_DATA(inode) * BITS_PER_BYTE / \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + BITS_PER_BYTE + 1)) +#define INLINE_DENTRY_BITMAP_SIZE(inode) ((NR_INLINE_DENTRY(inode) + \ + BITS_PER_BYTE - 1) / BITS_PER_BYTE) +#define INLINE_RESERVED_SIZE(inode) (MAX_INLINE_DATA(inode) - \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + NR_INLINE_DENTRY(inode) + \ + INLINE_DENTRY_BITMAP_SIZE(inode))) + /* * For INODE and NODE manager */ /* for directory operations */ struct f2fs_dentry_ptr { struct inode *inode; - const void *bitmap; + void *bitmap; struct f2fs_dir_entry *dentry; __u8 (*filename)[F2FS_SLOT_LEN]; int max; + int nr_bitmap; }; static inline void make_dentry_ptr_block(struct inode *inode, @@ -372,19 +414,26 @@ static inline void make_dentry_ptr_block(struct inode *inode, { d->inode = inode; d->max = NR_DENTRY_IN_BLOCK; + d->nr_bitmap = SIZE_OF_DENTRY_BITMAP; d->bitmap = &t->dentry_bitmap; d->dentry = t->dentry; d->filename = t->filename; } static inline void make_dentry_ptr_inline(struct inode *inode, - struct f2fs_dentry_ptr *d, struct f2fs_inline_dentry *t) + struct f2fs_dentry_ptr *d, void *t) { + int entry_cnt = NR_INLINE_DENTRY(inode); + int bitmap_size = INLINE_DENTRY_BITMAP_SIZE(inode); + int reserved_size = INLINE_RESERVED_SIZE(inode); + d->inode = inode; - d->max = NR_INLINE_DENTRY; - d->bitmap = &t->dentry_bitmap; - d->dentry = t->dentry; - d->filename = t->filename; + d->max = entry_cnt; + d->nr_bitmap = bitmap_size; + d->bitmap = t; + d->dentry = t + bitmap_size + reserved_size; + d->filename = t + bitmap_size + reserved_size + + SIZE_OF_DIR_ENTRY * entry_cnt; } /* @@ -473,12 +522,13 @@ struct f2fs_map_blocks { }; /* for flag in get_data_block */ -#define F2FS_GET_BLOCK_READ 0 -#define F2FS_GET_BLOCK_DIO 1 -#define F2FS_GET_BLOCK_FIEMAP 2 -#define F2FS_GET_BLOCK_BMAP 3 -#define F2FS_GET_BLOCK_PRE_DIO 4 -#define F2FS_GET_BLOCK_PRE_AIO 5 +enum { + F2FS_GET_BLOCK_DEFAULT, + F2FS_GET_BLOCK_FIEMAP, + F2FS_GET_BLOCK_BMAP, + F2FS_GET_BLOCK_PRE_DIO, + F2FS_GET_BLOCK_PRE_AIO, +}; /* * i_advise uses FADVISE_XXX_BIT. We can add additional hints later. @@ -521,6 +571,7 @@ struct f2fs_inode_info { f2fs_hash_t chash; /* hash value of given file name */ unsigned int clevel; /* maximum level of given file name */ struct task_struct *task; /* lookup and create consistency */ + struct task_struct *cp_task; /* separate cp/wb IO stats*/ nid_t i_xattr_nid; /* node id that contains xattrs */ loff_t last_disk_size; /* lastly written file size */ @@ -533,10 +584,15 @@ struct f2fs_inode_info { struct list_head dirty_list; /* dirty list for dirs and files */ struct list_head gdirty_list; /* linked in global dirty list */ struct list_head inmem_pages; /* inmemory pages managed by f2fs */ + struct task_struct *inmem_task; /* store inmemory task */ struct mutex inmem_lock; /* lock for inmemory pages */ struct extent_tree *extent_tree; /* cached extent_tree entry */ struct rw_semaphore dio_rwsem[2];/* avoid racing between dio and gc */ struct rw_semaphore i_mmap_sem; + struct rw_semaphore i_xattr_sem; /* avoid racing between reading and changing EAs */ + + int i_extra_isize; /* size of extra space located in i_addr */ + kprojid_t i_projid; /* id for project quota */ }; static inline void get_extent_info(struct extent_info *ext, @@ -823,6 +879,23 @@ enum need_lock_type { LOCK_RETRY, }; +enum iostat_type { + APP_DIRECT_IO, /* app direct IOs */ + APP_BUFFERED_IO, /* app buffered IOs */ + APP_WRITE_IO, /* app write IOs */ + APP_MAPPED_IO, /* app mapped IOs */ + FS_DATA_IO, /* data IOs from kworker/fsync/reclaimer */ + FS_NODE_IO, /* node IOs from kworker/fsync/reclaimer */ + FS_META_IO, /* meta IOs from kworker/reclaimer */ + FS_GC_DATA_IO, /* data IOs from forground gc */ + FS_GC_NODE_IO, /* node IOs from forground gc */ + FS_CP_DATA_IO, /* data IOs from checkpoint */ + FS_CP_NODE_IO, /* node IOs from checkpoint */ + FS_CP_META_IO, /* meta IOs from checkpoint */ + FS_DISCARD, /* discard */ + NR_IO_TYPE, +}; + struct f2fs_io_info { struct f2fs_sb_info *sbi; /* f2fs_sb_info pointer */ enum page_type type; /* contains DATA/NODE/META/META_FLUSH */ @@ -837,6 +910,7 @@ struct f2fs_io_info { bool submitted; /* indicate IO submission */ int need_lock; /* indicate we need to lock cp_rwsem */ bool in_list; /* indicate fio is in io_list */ + enum iostat_type io_type; /* io type */ }; #define is_read_io(rw) ((rw) == READ) @@ -1028,6 +1102,11 @@ struct f2fs_sb_info { #endif spinlock_t stat_lock; /* lock for stat operations */ + /* For app/fs IO statistics */ + spinlock_t iostat_lock; + unsigned long long write_iostat[NR_IO_TYPE]; + bool iostat_enable; + /* For sysfs suppport */ struct kobject s_kobj; struct completion s_kobj_unregister; @@ -1046,10 +1125,19 @@ struct f2fs_sb_info { /* Reference to checksum algorithm driver via cryptoapi */ struct crypto_shash *s_chksum_driver; + /* Precomputed FS UUID checksum for seeding other checksums */ + __u32 s_chksum_seed; + /* For fault injection */ #ifdef CONFIG_F2FS_FAULT_INJECTION struct f2fs_fault_info fault_info; #endif + +#ifdef CONFIG_QUOTA + /* Names of quota files with journalled quota */ + char *s_qf_names[MAXQUOTAS]; + int s_jquota_fmt; /* Format of quota to use */ +#endif }; #ifdef CONFIG_F2FS_FAULT_INJECTION @@ -1137,6 +1225,27 @@ static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc, return f2fs_crc32(sbi, buf, buf_size) == blk_crc; } +static inline u32 f2fs_chksum(struct f2fs_sb_info *sbi, u32 crc, + const void *address, unsigned int length) +{ + struct { + struct shash_desc shash; + char ctx[4]; + } desc; + int err; + + BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver) != sizeof(desc.ctx)); + + desc.shash.tfm = sbi->s_chksum_driver; + desc.shash.flags = 0; + *(u32 *)desc.ctx = crc; + + err = crypto_shash_update(&desc.shash, address, length); + BUG_ON(err); + + return *(u32 *)desc.ctx; +} + static inline struct f2fs_inode_info *F2FS_I(struct inode *inode) { return container_of(inode, struct f2fs_inode_info, vfs_inode); @@ -1760,20 +1869,38 @@ static inline bool IS_INODE(struct page *page) return RAW_IS_INODE(p); } +static inline int offset_in_addr(struct f2fs_inode *i) +{ + return (i->i_inline & F2FS_EXTRA_ATTR) ? + (le16_to_cpu(i->i_extra_isize) / sizeof(__le32)) : 0; +} + static inline __le32 *blkaddr_in_node(struct f2fs_node *node) { return RAW_IS_INODE(node) ? node->i.i_addr : node->dn.addr; } -static inline block_t datablock_addr(struct page *node_page, - unsigned int offset) +static inline int f2fs_has_extra_attr(struct inode *inode); +static inline block_t datablock_addr(struct inode *inode, + struct page *node_page, unsigned int offset) { struct f2fs_node *raw_node; __le32 *addr_array; + int base = 0; + bool is_inode = IS_INODE(node_page); raw_node = F2FS_NODE(node_page); + + /* from GC path only */ + if (!inode) { + if (is_inode) + base = offset_in_addr(&raw_node->i); + } else if (f2fs_has_extra_attr(inode) && is_inode) { + base = get_extra_isize(inode); + } + addr_array = blkaddr_in_node(raw_node); - return le32_to_cpu(addr_array[offset]); + return le32_to_cpu(addr_array[base + offset]); } static inline int f2fs_test_bit(unsigned int nr, char *addr) @@ -1836,6 +1963,20 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) *addr ^= mask; } +#define F2FS_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) +#define F2FS_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) +#define F2FS_FL_INHERITED (FS_PROJINHERIT_FL) + +static inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags) +{ + if (S_ISDIR(mode)) + return flags; + else if (S_ISREG(mode)) + return flags & F2FS_REG_FLMASK; + else + return flags & F2FS_OTHER_FLMASK; +} + /* used for f2fs_inode_info->flags */ enum { FI_NEW_INODE, /* indicate newly allocated inode */ @@ -1864,6 +2005,8 @@ enum { FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */ FI_NO_PREALLOC, /* indicate skipped preallocated blocks */ FI_HOT_DATA, /* indicate file is hot */ + FI_EXTRA_ATTR, /* indicate file has extra attribute */ + FI_PROJ_INHERIT, /* indicate file inherits projectid */ }; static inline void __mark_inode_dirty_flag(struct inode *inode, @@ -1983,6 +2126,8 @@ static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri) set_bit(FI_DATA_EXIST, &fi->flags); if (ri->i_inline & F2FS_INLINE_DOTS) set_bit(FI_INLINE_DOTS, &fi->flags); + if (ri->i_inline & F2FS_EXTRA_ATTR) + set_bit(FI_EXTRA_ATTR, &fi->flags); } static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri) @@ -1999,6 +2144,13 @@ static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri) ri->i_inline |= F2FS_DATA_EXIST; if (is_inode_flag_set(inode, FI_INLINE_DOTS)) ri->i_inline |= F2FS_INLINE_DOTS; + if (is_inode_flag_set(inode, FI_EXTRA_ATTR)) + ri->i_inline |= F2FS_EXTRA_ATTR; +} + +static inline int f2fs_has_extra_attr(struct inode *inode) +{ + return is_inode_flag_set(inode, FI_EXTRA_ATTR); } static inline int f2fs_has_inline_xattr(struct inode *inode) @@ -2009,8 +2161,8 @@ static inline int f2fs_has_inline_xattr(struct inode *inode) static inline unsigned int addrs_per_inode(struct inode *inode) { if (f2fs_has_inline_xattr(inode)) - return DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS; - return DEF_ADDRS_PER_INODE; + return CUR_ADDRS_PER_INODE(inode) - F2FS_INLINE_XATTR_ADDRS; + return CUR_ADDRS_PER_INODE(inode); } static inline void *inline_xattr_addr(struct page *page) @@ -2069,11 +2221,12 @@ static inline bool f2fs_is_drop_cache(struct inode *inode) return is_inode_flag_set(inode, FI_DROP_CACHE); } -static inline void *inline_data_addr(struct page *page) +static inline void *inline_data_addr(struct inode *inode, struct page *page) { struct f2fs_inode *ri = F2FS_INODE(page); + int extra_size = get_extra_isize(inode); - return (void *)&(ri->i_addr[1]); + return (void *)&(ri->i_addr[extra_size + DEF_INLINE_RESERVED_SIZE]); } static inline int f2fs_has_inline_dentry(struct inode *inode) @@ -2164,10 +2317,50 @@ static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi, return kmalloc(size, flags); } +static inline int get_extra_isize(struct inode *inode) +{ + return F2FS_I(inode)->i_extra_isize / sizeof(__le32); +} + #define get_inode_mode(i) \ ((is_inode_flag_set(i, FI_ACL_MODE)) ? \ (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) +#define F2FS_TOTAL_EXTRA_ATTR_SIZE \ + (offsetof(struct f2fs_inode, i_extra_end) - \ + offsetof(struct f2fs_inode, i_extra_isize)) \ + +#define F2FS_OLD_ATTRIBUTE_SIZE (offsetof(struct f2fs_inode, i_addr)) +#define F2FS_FITS_IN_INODE(f2fs_inode, extra_isize, field) \ + ((offsetof(typeof(*f2fs_inode), field) + \ + sizeof((f2fs_inode)->field)) \ + <= (F2FS_OLD_ATTRIBUTE_SIZE + extra_isize)) \ + +static inline void f2fs_reset_iostat(struct f2fs_sb_info *sbi) +{ + int i; + + spin_lock(&sbi->iostat_lock); + for (i = 0; i < NR_IO_TYPE; i++) + sbi->write_iostat[i] = 0; + spin_unlock(&sbi->iostat_lock); +} + +static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, + enum iostat_type type, unsigned long long io_bytes) +{ + if (!sbi->iostat_enable) + return; + spin_lock(&sbi->iostat_lock); + sbi->write_iostat[type] += io_bytes; + + if (type == APP_WRITE_IO || type == APP_DIRECT_IO) + sbi->write_iostat[APP_BUFFERED_IO] = + sbi->write_iostat[APP_WRITE_IO] - + sbi->write_iostat[APP_DIRECT_IO]; + spin_unlock(&sbi->iostat_lock); +} + /* * file.c */ @@ -2187,6 +2380,8 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); * inode.c */ void f2fs_set_inode_flags(struct inode *inode); +bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page); +void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page); struct inode *f2fs_iget(struct super_block *sb, unsigned long ino); struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino); int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink); @@ -2255,6 +2450,8 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) */ int f2fs_inode_dirtied(struct inode *inode, bool sync); void f2fs_inode_synced(struct inode *inode); +void f2fs_enable_quota_files(struct f2fs_sb_info *sbi); +void f2fs_quota_off_umount(struct super_block *sb); int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover); int f2fs_sync_fs(struct super_block *sb, int sync); extern __printf(3, 4) @@ -2285,15 +2482,15 @@ int truncate_xattr_node(struct inode *inode, struct page *page); int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino); int remove_inode_page(struct inode *inode); struct page *new_inode_page(struct inode *inode); -struct page *new_node_page(struct dnode_of_data *dn, - unsigned int ofs, struct page *ipage); +struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs); void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid); struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid); struct page *get_node_page_ra(struct page *parent, int start); void move_node_page(struct page *node_page, int gc_type); int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, struct writeback_control *wbc, bool atomic); -int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc); +int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc, + bool do_balance, enum iostat_type io_type); void build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount); bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid); void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid); @@ -2314,6 +2511,7 @@ void destroy_node_manager_caches(void); /* * segment.c */ +bool need_SSR(struct f2fs_sb_info *sbi); void register_inmem_page(struct inode *inode, struct page *page); void drop_inmem_pages(struct inode *inode); void drop_inmem_page(struct inode *inode, struct page *page); @@ -2336,7 +2534,8 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range); bool exist_trim_candidates(struct f2fs_sb_info *sbi, struct cp_control *cpc); struct page *get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno); void update_meta_page(struct f2fs_sb_info *sbi, void *src, block_t blk_addr); -void write_meta_page(struct f2fs_sb_info *sbi, struct page *page); +void write_meta_page(struct f2fs_sb_info *sbi, struct page *page, + enum iostat_type io_type); void write_node_page(unsigned int nid, struct f2fs_io_info *fio); void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio); int rewrite_data_page(struct f2fs_io_info *fio); @@ -2353,8 +2552,7 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, struct f2fs_io_info *fio, bool add_list); void f2fs_wait_on_page_writeback(struct page *page, enum page_type type, bool ordered); -void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi, - block_t blkaddr); +void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr); void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk); void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk); int lookup_journal_in_cursum(struct f2fs_journal *journal, int type, @@ -2377,7 +2575,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type, bool sync); void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index); long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, - long nr_to_write); + long nr_to_write, enum iostat_type io_type); void add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type); void remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type); void release_ino_entry(struct f2fs_sb_info *sbi, bool all); @@ -2430,6 +2628,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len); void f2fs_set_page_dirty_nobuffers(struct page *page); +int __f2fs_write_data_pages(struct address_space *mapping, + struct writeback_control *wbc, + enum iostat_type io_type); void f2fs_invalidate_page(struct page *page, unsigned int offset, unsigned int length); int f2fs_release_page(struct page *page, gfp_t wait); @@ -2726,10 +2927,10 @@ void destroy_extent_cache(void); /* * sysfs.c */ -int __init f2fs_register_sysfs(void); -void f2fs_unregister_sysfs(void); -int f2fs_init_sysfs(struct f2fs_sb_info *sbi); -void f2fs_exit_sysfs(struct f2fs_sb_info *sbi); +int __init f2fs_init_sysfs(void); +void f2fs_exit_sysfs(void); +int f2fs_register_sysfs(struct f2fs_sb_info *sbi); +void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi); /* * crypto support @@ -2739,6 +2940,11 @@ static inline bool f2fs_encrypted_inode(struct inode *inode) return file_is_encrypt(inode); } +static inline bool f2fs_encrypted_file(struct inode *inode) +{ + return f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode); +} + static inline void f2fs_set_encrypted_inode(struct inode *inode) { #ifdef CONFIG_F2FS_FS_ENCRYPTION @@ -2761,6 +2967,21 @@ static inline int f2fs_sb_mounted_blkzoned(struct super_block *sb) return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_BLKZONED); } +static inline int f2fs_sb_has_extra_attr(struct super_block *sb) +{ + return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_EXTRA_ATTR); +} + +static inline int f2fs_sb_has_project_quota(struct super_block *sb) +{ + return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_PRJQUOTA); +} + +static inline int f2fs_sb_has_inode_chksum(struct super_block *sb) +{ + return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_INODE_CHKSUM); +} + #ifdef CONFIG_BLK_DEV_ZONED static inline int get_blkz_type(struct f2fs_sb_info *sbi, struct block_device *bdev, block_t blkaddr) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 2706130c261b060f46cb526b8e7ac501789808a7..517e112c8a9a943467492435c9f15c1668e079a8 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -98,14 +98,16 @@ static int f2fs_vm_page_mkwrite(struct vm_fault *vmf) if (!PageUptodate(page)) SetPageUptodate(page); + f2fs_update_iostat(sbi, APP_MAPPED_IO, F2FS_BLKSIZE); + trace_f2fs_vm_page_mkwrite(page, DATA); mapped: /* fill the page */ f2fs_wait_on_page_writeback(page, DATA, false); /* wait for GCed encrypted page writeback */ - if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) - f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); + if (f2fs_encrypted_file(inode)) + f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr); out_sem: up_read(&F2FS_I(inode)->i_mmap_sem); @@ -206,7 +208,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, /* if fdatasync is triggered, let's do in-place-update */ if (datasync || get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) set_inode_flag(inode, FI_NEED_IPU); - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(file, start, end); clear_inode_flag(inode, FI_NEED_IPU); if (ret) { @@ -274,9 +276,19 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, goto sync_nodes; } - ret = wait_on_node_pages_writeback(sbi, ino); - if (ret) - goto out; + /* + * If it's atomic_write, it's just fine to keep write ordering. So + * here we don't need to wait for node write completion, since we use + * node chain which serializes node blocks. If one of node writes are + * reordered, we can see simply broken chain, resulting in stopping + * roll-forward recovery. It means we'll recover all or none node blocks + * given fsync mark. + */ + if (!atomic) { + ret = wait_on_node_pages_writeback(sbi, ino); + if (ret) + goto out; + } /* once recovery info is written, don't need to tack this */ remove_ino_entry(sbi, ino, APPEND_INO); @@ -382,7 +394,8 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) dn.ofs_in_node++, pgofs++, data_ofs = (loff_t)pgofs << PAGE_SHIFT) { block_t blkaddr; - blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + blkaddr = datablock_addr(dn.inode, + dn.node_page, dn.ofs_in_node); if (__found_offset(blkaddr, dirty, pgofs, whence)) { f2fs_put_dnode(&dn); @@ -467,9 +480,13 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count) struct f2fs_node *raw_node; int nr_free = 0, ofs = dn->ofs_in_node, len = count; __le32 *addr; + int base = 0; + + if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode)) + base = get_extra_isize(dn->inode); raw_node = F2FS_NODE(dn->node_page); - addr = blkaddr_in_node(raw_node) + ofs; + addr = blkaddr_in_node(raw_node) + base + ofs; for (; count > 0; count--, addr++, dn->ofs_in_node++) { block_t blkaddr = le32_to_cpu(*addr); @@ -647,7 +664,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat, struct f2fs_inode_info *fi = F2FS_I(inode); unsigned int flags; - flags = fi->i_flags & FS_FL_USER_VISIBLE; + flags = fi->i_flags & (FS_FL_USER_VISIBLE | FS_PROJINHERIT_FL); if (flags & FS_APPEND_FL) stat->attributes |= STATX_ATTR_APPEND; if (flags & FS_COMPR_FL) @@ -927,7 +944,8 @@ static int __read_out_blkaddrs(struct inode *inode, block_t *blkaddr, done = min((pgoff_t)ADDRS_PER_PAGE(dn.node_page, inode) - dn.ofs_in_node, len); for (i = 0; i < done; i++, blkaddr++, do_replace++, dn.ofs_in_node++) { - *blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + *blkaddr = datablock_addr(dn.inode, + dn.node_page, dn.ofs_in_node); if (!is_checkpointed_data(sbi, *blkaddr)) { if (test_opt(sbi, LFS)) { @@ -1003,8 +1021,8 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, ADDRS_PER_PAGE(dn.node_page, dst_inode) - dn.ofs_in_node, len - i); do { - dn.data_blkaddr = datablock_addr(dn.node_page, - dn.ofs_in_node); + dn.data_blkaddr = datablock_addr(dn.inode, + dn.node_page, dn.ofs_in_node); truncate_data_blocks_range(&dn, 1); if (do_replace[i]) { @@ -1173,7 +1191,8 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start, int ret; for (; index < end; index++, dn->ofs_in_node++) { - if (datablock_addr(dn->node_page, dn->ofs_in_node) == NULL_ADDR) + if (datablock_addr(dn->inode, dn->node_page, + dn->ofs_in_node) == NULL_ADDR) count++; } @@ -1184,8 +1203,8 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start, dn->ofs_in_node = ofs_in_node; for (index = start; index < end; index++, dn->ofs_in_node++) { - dn->data_blkaddr = - datablock_addr(dn->node_page, dn->ofs_in_node); + dn->data_blkaddr = datablock_addr(dn->inode, + dn->node_page, dn->ofs_in_node); /* * reserve_new_blocks will not guarantee entire block * allocation. @@ -1495,33 +1514,67 @@ static int f2fs_release_file(struct inode *inode, struct file *filp) return 0; } -#define F2FS_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) -#define F2FS_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) - -static inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags) +static int f2fs_file_flush(struct file *file, fl_owner_t id) { - if (S_ISDIR(mode)) - return flags; - else if (S_ISREG(mode)) - return flags & F2FS_REG_FLMASK; - else - return flags & F2FS_OTHER_FLMASK; + struct inode *inode = file_inode(file); + + /* + * If the process doing a transaction is crashed, we should do + * roll-back. Otherwise, other reader/write can see corrupted database + * until all the writers close its file. Since this should be done + * before dropping file lock, it needs to do in ->flush. + */ + if (f2fs_is_atomic_file(inode) && + F2FS_I(inode)->inmem_task == current) + drop_inmem_pages(inode); + return 0; } static int f2fs_ioc_getflags(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); struct f2fs_inode_info *fi = F2FS_I(inode); - unsigned int flags = fi->i_flags & FS_FL_USER_VISIBLE; + unsigned int flags = fi->i_flags & + (FS_FL_USER_VISIBLE | FS_PROJINHERIT_FL); return put_user(flags, (int __user *)arg); } +static int __f2fs_ioc_setflags(struct inode *inode, unsigned int flags) +{ + struct f2fs_inode_info *fi = F2FS_I(inode); + unsigned int oldflags; + + /* Is it quota file? Do not allow user to mess with it */ + if (IS_NOQUOTA(inode)) + return -EPERM; + + flags = f2fs_mask_flags(inode->i_mode, flags); + + oldflags = fi->i_flags; + + if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) + if (!capable(CAP_LINUX_IMMUTABLE)) + return -EPERM; + + flags = flags & (FS_FL_USER_MODIFIABLE | FS_PROJINHERIT_FL); + flags |= oldflags & ~(FS_FL_USER_MODIFIABLE | FS_PROJINHERIT_FL); + fi->i_flags = flags; + + if (fi->i_flags & FS_PROJINHERIT_FL) + set_inode_flag(inode, FI_PROJ_INHERIT); + else + clear_inode_flag(inode, FI_PROJ_INHERIT); + + inode->i_ctime = current_time(inode); + f2fs_set_inode_flags(inode); + f2fs_mark_inode_dirty_sync(inode, false); + return 0; +} + static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); - struct f2fs_inode_info *fi = F2FS_I(inode); unsigned int flags; - unsigned int oldflags; int ret; if (!inode_owner_or_capable(inode)) @@ -1536,31 +1589,8 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) inode_lock(inode); - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) { - ret = -EPERM; - goto unlock_out; - } - - flags = f2fs_mask_flags(inode->i_mode, flags); - - oldflags = fi->i_flags; - - if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) { - if (!capable(CAP_LINUX_IMMUTABLE)) { - ret = -EPERM; - goto unlock_out; - } - } - - flags = flags & FS_FL_USER_MODIFIABLE; - flags |= oldflags & ~FS_FL_USER_MODIFIABLE; - fi->i_flags = flags; + ret = __f2fs_ioc_setflags(inode, flags); - inode->i_ctime = current_time(inode); - f2fs_set_inode_flags(inode); - f2fs_mark_inode_dirty_sync(inode, false); -unlock_out: inode_unlock(inode); mnt_drop_write_file(filp); return ret; @@ -1610,10 +1640,12 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX); if (ret) { clear_inode_flag(inode, FI_ATOMIC_FILE); + clear_inode_flag(inode, FI_HOT_DATA); goto out; } inc_stat: + F2FS_I(inode)->inmem_task = current; stat_inc_atomic_write(inode); stat_update_max_atomic_write(inode); out: @@ -1647,10 +1679,11 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true); if (!ret) { clear_inode_flag(inode, FI_ATOMIC_FILE); + clear_inode_flag(inode, FI_HOT_DATA); stat_dec_atomic_write(inode); } } else { - ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true); + ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false); } err_out: inode_unlock(inode); @@ -1786,7 +1819,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) f2fs_stop_checkpoint(sbi, false); break; case F2FS_GOING_DOWN_METAFLUSH: - sync_meta_pages(sbi, META, LONG_MAX); + sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO); f2fs_stop_checkpoint(sbi, false); break; default: @@ -2043,7 +2076,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, */ while (map.m_lblk < pg_end) { map.m_len = pg_end - map.m_lblk; - err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); + err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT); if (err) goto out; @@ -2085,7 +2118,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, do_map: map.m_len = pg_end - map.m_lblk; - err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); + err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT); if (err) goto clear_out; @@ -2384,6 +2417,210 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg) return ret; } +static int f2fs_ioc_get_features(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + u32 sb_feature = le32_to_cpu(F2FS_I_SB(inode)->raw_super->feature); + + /* Must validate to set it with SQLite behavior in Android. */ + sb_feature |= F2FS_FEATURE_ATOMIC_WRITE; + + return put_user(sb_feature, (u32 __user *)arg); +} + +#ifdef CONFIG_QUOTA +static int f2fs_ioc_setproject(struct file *filp, __u32 projid) +{ + struct inode *inode = file_inode(filp); + struct f2fs_inode_info *fi = F2FS_I(inode); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct super_block *sb = sbi->sb; + struct dquot *transfer_to[MAXQUOTAS] = {}; + struct page *ipage; + kprojid_t kprojid; + int err; + + if (!f2fs_sb_has_project_quota(sb)) { + if (projid != F2FS_DEF_PROJID) + return -EOPNOTSUPP; + else + return 0; + } + + if (!f2fs_has_extra_attr(inode)) + return -EOPNOTSUPP; + + kprojid = make_kprojid(&init_user_ns, (projid_t)projid); + + if (projid_eq(kprojid, F2FS_I(inode)->i_projid)) + return 0; + + err = mnt_want_write_file(filp); + if (err) + return err; + + err = -EPERM; + inode_lock(inode); + + /* Is it quota file? Do not allow user to mess with it */ + if (IS_NOQUOTA(inode)) + goto out_unlock; + + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + err = PTR_ERR(ipage); + goto out_unlock; + } + + if (!F2FS_FITS_IN_INODE(F2FS_INODE(ipage), fi->i_extra_isize, + i_projid)) { + err = -EOVERFLOW; + f2fs_put_page(ipage, 1); + goto out_unlock; + } + f2fs_put_page(ipage, 1); + + dquot_initialize(inode); + + transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid)); + if (!IS_ERR(transfer_to[PRJQUOTA])) { + err = __dquot_transfer(inode, transfer_to); + dqput(transfer_to[PRJQUOTA]); + if (err) + goto out_dirty; + } + + F2FS_I(inode)->i_projid = kprojid; + inode->i_ctime = current_time(inode); +out_dirty: + f2fs_mark_inode_dirty_sync(inode, true); +out_unlock: + inode_unlock(inode); + mnt_drop_write_file(filp); + return err; +} +#else +static int f2fs_ioc_setproject(struct file *filp, __u32 projid) +{ + if (projid != F2FS_DEF_PROJID) + return -EOPNOTSUPP; + return 0; +} +#endif + +/* Transfer internal flags to xflags */ +static inline __u32 f2fs_iflags_to_xflags(unsigned long iflags) +{ + __u32 xflags = 0; + + if (iflags & FS_SYNC_FL) + xflags |= FS_XFLAG_SYNC; + if (iflags & FS_IMMUTABLE_FL) + xflags |= FS_XFLAG_IMMUTABLE; + if (iflags & FS_APPEND_FL) + xflags |= FS_XFLAG_APPEND; + if (iflags & FS_NODUMP_FL) + xflags |= FS_XFLAG_NODUMP; + if (iflags & FS_NOATIME_FL) + xflags |= FS_XFLAG_NOATIME; + if (iflags & FS_PROJINHERIT_FL) + xflags |= FS_XFLAG_PROJINHERIT; + return xflags; +} + +#define F2FS_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \ + FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \ + FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT) + +/* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */ +#define F2FS_FL_XFLAG_VISIBLE (FS_SYNC_FL | \ + FS_IMMUTABLE_FL | \ + FS_APPEND_FL | \ + FS_NODUMP_FL | \ + FS_NOATIME_FL | \ + FS_PROJINHERIT_FL) + +/* Transfer xflags flags to internal */ +static inline unsigned long f2fs_xflags_to_iflags(__u32 xflags) +{ + unsigned long iflags = 0; + + if (xflags & FS_XFLAG_SYNC) + iflags |= FS_SYNC_FL; + if (xflags & FS_XFLAG_IMMUTABLE) + iflags |= FS_IMMUTABLE_FL; + if (xflags & FS_XFLAG_APPEND) + iflags |= FS_APPEND_FL; + if (xflags & FS_XFLAG_NODUMP) + iflags |= FS_NODUMP_FL; + if (xflags & FS_XFLAG_NOATIME) + iflags |= FS_NOATIME_FL; + if (xflags & FS_XFLAG_PROJINHERIT) + iflags |= FS_PROJINHERIT_FL; + + return iflags; +} + +static int f2fs_ioc_fsgetxattr(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_inode_info *fi = F2FS_I(inode); + struct fsxattr fa; + + memset(&fa, 0, sizeof(struct fsxattr)); + fa.fsx_xflags = f2fs_iflags_to_xflags(fi->i_flags & + (FS_FL_USER_VISIBLE | FS_PROJINHERIT_FL)); + + if (f2fs_sb_has_project_quota(inode->i_sb)) + fa.fsx_projid = (__u32)from_kprojid(&init_user_ns, + fi->i_projid); + + if (copy_to_user((struct fsxattr __user *)arg, &fa, sizeof(fa))) + return -EFAULT; + return 0; +} + +static int f2fs_ioc_fssetxattr(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_inode_info *fi = F2FS_I(inode); + struct fsxattr fa; + unsigned int flags; + int err; + + if (copy_from_user(&fa, (struct fsxattr __user *)arg, sizeof(fa))) + return -EFAULT; + + /* Make sure caller has proper permission */ + if (!inode_owner_or_capable(inode)) + return -EACCES; + + if (fa.fsx_xflags & ~F2FS_SUPPORTED_FS_XFLAGS) + return -EOPNOTSUPP; + + flags = f2fs_xflags_to_iflags(fa.fsx_xflags); + if (f2fs_mask_flags(inode->i_mode, flags) != flags) + return -EOPNOTSUPP; + + err = mnt_want_write_file(filp); + if (err) + return err; + + inode_lock(inode); + flags = (fi->i_flags & ~F2FS_FL_XFLAG_VISIBLE) | + (flags & F2FS_FL_XFLAG_VISIBLE); + err = __f2fs_ioc_setflags(inode, flags); + inode_unlock(inode); + mnt_drop_write_file(filp); + if (err) + return err; + + err = f2fs_ioc_setproject(filp, fa.fsx_projid); + if (err) + return err; + + return 0; +} long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -2426,6 +2663,12 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_ioc_move_range(filp, arg); case F2FS_IOC_FLUSH_DEVICE: return f2fs_ioc_flush_device(filp, arg); + case F2FS_IOC_GET_FEATURES: + return f2fs_ioc_get_features(filp, arg); + case F2FS_IOC_FSGETXATTR: + return f2fs_ioc_fsgetxattr(filp, arg); + case F2FS_IOC_FSSETXATTR: + return f2fs_ioc_fssetxattr(filp, arg); default: return -ENOTTY; } @@ -2455,6 +2698,9 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ret = __generic_file_write_iter(iocb, from); blk_finish_plug(&plug); clear_inode_flag(inode, FI_NO_PREALLOC); + + if (ret > 0) + f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret); } inode_unlock(inode); @@ -2491,6 +2737,9 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case F2FS_IOC_DEFRAGMENT: case F2FS_IOC_MOVE_RANGE: case F2FS_IOC_FLUSH_DEVICE: + case F2FS_IOC_GET_FEATURES: + case F2FS_IOC_FSGETXATTR: + case F2FS_IOC_FSSETXATTR: break; default: return -ENOIOCTLCMD; @@ -2506,6 +2755,7 @@ const struct file_operations f2fs_file_operations = { .open = f2fs_file_open, .release = f2fs_release_file, .mmap = f2fs_file_mmap, + .flush = f2fs_file_flush, .fsync = f2fs_sync_file, .fallocate = f2fs_fallocate, .unlocked_ioctl = f2fs_ioctl, diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index fa3d2e2df8e70e883011afc5e46c9989e0e834ff..bfe6a8ccc3a0207d51e0f11878de931958b699c1 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -28,16 +28,21 @@ static int gc_thread_func(void *data) struct f2fs_sb_info *sbi = data; struct f2fs_gc_kthread *gc_th = sbi->gc_thread; wait_queue_head_t *wq = &sbi->gc_thread->gc_wait_queue_head; - long wait_ms; + unsigned int wait_ms; wait_ms = gc_th->min_sleep_time; set_freezable(); do { wait_event_interruptible_timeout(*wq, - kthread_should_stop() || freezing(current), + kthread_should_stop() || freezing(current) || + gc_th->gc_wake, msecs_to_jiffies(wait_ms)); + /* give it a try one time */ + if (gc_th->gc_wake) + gc_th->gc_wake = 0; + if (try_to_freeze()) continue; if (kthread_should_stop()) @@ -55,6 +60,9 @@ static int gc_thread_func(void *data) } #endif + if (!sb_start_write_trylock(sbi->sb)) + continue; + /* * [GC triggering condition] * 0. GC is not conducted currently. @@ -69,19 +77,24 @@ static int gc_thread_func(void *data) * So, I'd like to wait some time to collect dirty segments. */ if (!mutex_trylock(&sbi->gc_mutex)) - continue; + goto next; + + if (gc_th->gc_urgent) { + wait_ms = gc_th->urgent_sleep_time; + goto do_gc; + } if (!is_idle(sbi)) { increase_sleep_time(gc_th, &wait_ms); mutex_unlock(&sbi->gc_mutex); - continue; + goto next; } if (has_enough_invalid_blocks(sbi)) decrease_sleep_time(gc_th, &wait_ms); else increase_sleep_time(gc_th, &wait_ms); - +do_gc: stat_inc_bggc_count(sbi); /* if return value is not zero, no victim was selected */ @@ -93,6 +106,8 @@ static int gc_thread_func(void *data) /* balancing f2fs's metadata periodically */ f2fs_balance_fs_bg(sbi); +next: + sb_end_write(sbi->sb); } while (!kthread_should_stop()); return 0; @@ -110,11 +125,14 @@ int start_gc_thread(struct f2fs_sb_info *sbi) goto out; } + gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME; gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME; gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME; gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME; gc_th->gc_idle = 0; + gc_th->gc_urgent = 0; + gc_th->gc_wake= 0; sbi->gc_thread = gc_th; init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head); @@ -259,20 +277,11 @@ static unsigned int get_greedy_cost(struct f2fs_sb_info *sbi, valid_blocks * 2 : valid_blocks; } -static unsigned int get_ssr_cost(struct f2fs_sb_info *sbi, - unsigned int segno) -{ - struct seg_entry *se = get_seg_entry(sbi, segno); - - return se->ckpt_valid_blocks > se->valid_blocks ? - se->ckpt_valid_blocks : se->valid_blocks; -} - static inline unsigned int get_gc_cost(struct f2fs_sb_info *sbi, unsigned int segno, struct victim_sel_policy *p) { if (p->alloc_mode == SSR) - return get_ssr_cost(sbi, segno); + return get_seg_entry(sbi, segno)->ckpt_valid_blocks; /* alloc_mode == LFS */ if (p->gc_mode == GC_GREEDY) @@ -582,7 +591,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } *nofs = ofs_of_node(node_page); - source_blkaddr = datablock_addr(node_page, ofs_in_node); + source_blkaddr = datablock_addr(NULL, node_page, ofs_in_node); f2fs_put_page(node_page, 1); if (source_blkaddr != blkaddr) @@ -590,8 +599,12 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, return true; } -static void move_encrypted_block(struct inode *inode, block_t bidx, - unsigned int segno, int off) +/* + * Move data block via META_MAPPING while keeping locked data page. + * This can be used to move blocks, aka LBAs, directly on disk. + */ +static void move_data_block(struct inode *inode, block_t bidx, + unsigned int segno, int off) { struct f2fs_io_info fio = { .sbi = F2FS_I_SB(inode), @@ -684,6 +697,8 @@ static void move_encrypted_block(struct inode *inode, block_t bidx, fio.new_blkaddr = newaddr; f2fs_submit_page_write(&fio); + f2fs_update_iostat(fio.sbi, FS_GC_DATA_IO, F2FS_BLKSIZE); + f2fs_update_data_blkaddr(&dn, newaddr); set_inode_flag(inode, FI_APPEND_WRITE); if (page->index == 0) @@ -731,6 +746,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .page = page, .encrypted_page = NULL, .need_lock = LOCK_REQ, + .io_type = FS_GC_DATA_IO, }; bool is_dirty = PageDirty(page); int err; @@ -819,8 +835,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, continue; /* if encrypted inode, let's go phase 3 */ - if (f2fs_encrypted_inode(inode) && - S_ISREG(inode->i_mode)) { + if (f2fs_encrypted_file(inode)) { add_gc_inode(gc_list, inode); continue; } @@ -854,14 +869,18 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, continue; } locked = true; + + /* wait for all inflight aio data */ + inode_dio_wait(inode); } start_bidx = start_bidx_of_node(nofs, inode) + ofs_in_node; - if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) - move_encrypted_block(inode, start_bidx, segno, off); + if (f2fs_encrypted_file(inode)) + move_data_block(inode, start_bidx, segno, off); else - move_data_page(inode, start_bidx, gc_type, segno, off); + move_data_page(inode, start_bidx, gc_type, + segno, off); if (locked) { up_write(&fi->dio_rwsem[WRITE]); @@ -898,7 +917,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, struct blk_plug plug; unsigned int segno = start_segno; unsigned int end_segno = start_segno + sbi->segs_per_sec; - int sec_freed = 0; + int seg_freed = 0; unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ? SUM_TYPE_DATA : SUM_TYPE_NODE; @@ -944,6 +963,10 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, gc_type); stat_inc_seg_count(sbi, type, gc_type); + + if (gc_type == FG_GC && + get_valid_blocks(sbi, segno, false) == 0) + seg_freed++; next: f2fs_put_page(sum_page, 0); } @@ -954,21 +977,17 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, blk_finish_plug(&plug); - if (gc_type == FG_GC && - get_valid_blocks(sbi, start_segno, true) == 0) - sec_freed = 1; - stat_inc_call_count(sbi->stat_info); - return sec_freed; + return seg_freed; } int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background, unsigned int segno) { int gc_type = sync ? FG_GC : BG_GC; - int sec_freed = 0; - int ret; + int sec_freed = 0, seg_freed = 0, total_freed = 0; + int ret = 0; struct cp_control cpc; unsigned int init_segno = segno; struct gc_inode_list gc_list = { @@ -976,6 +995,15 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, .iroot = RADIX_TREE_INIT(GFP_NOFS), }; + trace_f2fs_gc_begin(sbi->sb, sync, background, + get_pages(sbi, F2FS_DIRTY_NODES), + get_pages(sbi, F2FS_DIRTY_DENTS), + get_pages(sbi, F2FS_DIRTY_IMETA), + free_sections(sbi), + free_segments(sbi), + reserved_segments(sbi), + prefree_segments(sbi)); + cpc.reason = __get_cp_reason(sbi); gc_more: if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) { @@ -1002,17 +1030,20 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, gc_type = FG_GC; } - ret = -EINVAL; /* f2fs_balance_fs doesn't need to do BG_GC in critical path. */ - if (gc_type == BG_GC && !background) + if (gc_type == BG_GC && !background) { + ret = -EINVAL; goto stop; - if (!__get_victim(sbi, &segno, gc_type)) + } + if (!__get_victim(sbi, &segno, gc_type)) { + ret = -ENODATA; goto stop; - ret = 0; + } - if (do_garbage_collect(sbi, segno, &gc_list, gc_type) && - gc_type == FG_GC) + seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type); + if (gc_type == FG_GC && seg_freed == sbi->segs_per_sec) sec_freed++; + total_freed += seg_freed; if (gc_type == FG_GC) sbi->cur_victim_sec = NULL_SEGNO; @@ -1029,6 +1060,16 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, stop: SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0; SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno; + + trace_f2fs_gc_end(sbi->sb, ret, total_freed, sec_freed, + get_pages(sbi, F2FS_DIRTY_NODES), + get_pages(sbi, F2FS_DIRTY_DENTS), + get_pages(sbi, F2FS_DIRTY_IMETA), + free_sections(sbi), + free_segments(sbi), + reserved_segments(sbi), + prefree_segments(sbi)); + mutex_unlock(&sbi->gc_mutex); put_gc_inode(&gc_list); diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index a993967dcdb979160ec5bced54fa7df565bf1e65..9325191fab2d6f4d571541c79c55ede3d5e47775 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h @@ -13,6 +13,7 @@ * whether IO subsystem is idle * or not */ +#define DEF_GC_THREAD_URGENT_SLEEP_TIME 500 /* 500 ms */ #define DEF_GC_THREAD_MIN_SLEEP_TIME 30000 /* milliseconds */ #define DEF_GC_THREAD_MAX_SLEEP_TIME 60000 #define DEF_GC_THREAD_NOGC_SLEEP_TIME 300000 /* wait 5 min */ @@ -27,12 +28,15 @@ struct f2fs_gc_kthread { wait_queue_head_t gc_wait_queue_head; /* for gc sleep time */ + unsigned int urgent_sleep_time; unsigned int min_sleep_time; unsigned int max_sleep_time; unsigned int no_gc_sleep_time; /* for changing gc mode */ unsigned int gc_idle; + unsigned int gc_urgent; + unsigned int gc_wake; }; struct gc_inode_list { @@ -65,25 +69,32 @@ static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi) } static inline void increase_sleep_time(struct f2fs_gc_kthread *gc_th, - long *wait) + unsigned int *wait) { + unsigned int min_time = gc_th->min_sleep_time; + unsigned int max_time = gc_th->max_sleep_time; + if (*wait == gc_th->no_gc_sleep_time) return; - *wait += gc_th->min_sleep_time; - if (*wait > gc_th->max_sleep_time) - *wait = gc_th->max_sleep_time; + if ((long long)*wait + (long long)min_time > (long long)max_time) + *wait = max_time; + else + *wait += min_time; } static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th, - long *wait) + unsigned int *wait) { + unsigned int min_time = gc_th->min_sleep_time; + if (*wait == gc_th->no_gc_sleep_time) *wait = gc_th->max_sleep_time; - *wait -= gc_th->min_sleep_time; - if (*wait <= gc_th->min_sleep_time) - *wait = gc_th->min_sleep_time; + if ((long long)*wait - (long long)min_time < (long long)min_time) + *wait = min_time; + else + *wait -= min_time; } static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index e0fd4376e6fb0dca33cca4fbb045744c91a7c3f3..8322e4e7bb3fc432aabc8067b7ab459274c6d326 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -22,10 +22,10 @@ bool f2fs_may_inline_data(struct inode *inode) if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) return false; - if (i_size_read(inode) > MAX_INLINE_DATA) + if (i_size_read(inode) > MAX_INLINE_DATA(inode)) return false; - if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) + if (f2fs_encrypted_file(inode)) return false; return true; @@ -44,6 +44,7 @@ bool f2fs_may_inline_dentry(struct inode *inode) void read_inline_data(struct page *page, struct page *ipage) { + struct inode *inode = page->mapping->host; void *src_addr, *dst_addr; if (PageUptodate(page)) @@ -51,12 +52,12 @@ void read_inline_data(struct page *page, struct page *ipage) f2fs_bug_on(F2FS_P_SB(page), page->index); - zero_user_segment(page, MAX_INLINE_DATA, PAGE_SIZE); + zero_user_segment(page, MAX_INLINE_DATA(inode), PAGE_SIZE); /* Copy the whole inline data block */ - src_addr = inline_data_addr(ipage); + src_addr = inline_data_addr(inode, ipage); dst_addr = kmap_atomic(page); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); flush_dcache_page(page); kunmap_atomic(dst_addr); if (!PageUptodate(page)) @@ -67,13 +68,13 @@ void truncate_inline_inode(struct inode *inode, struct page *ipage, u64 from) { void *addr; - if (from >= MAX_INLINE_DATA) + if (from >= MAX_INLINE_DATA(inode)) return; - addr = inline_data_addr(ipage); + addr = inline_data_addr(inode, ipage); f2fs_wait_on_page_writeback(ipage, NODE, true); - memset(addr + from, 0, MAX_INLINE_DATA - from); + memset(addr + from, 0, MAX_INLINE_DATA(inode) - from); set_page_dirty(ipage); if (from == 0) @@ -116,6 +117,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) .op_flags = REQ_SYNC | REQ_PRIO, .page = page, .encrypted_page = NULL, + .io_type = FS_DATA_IO, }; int dirty, err; @@ -200,6 +202,8 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) { void *src_addr, *dst_addr; struct dnode_of_data dn; + struct address_space *mapping = page_mapping(page); + unsigned long flags; int err; set_new_dnode(&dn, inode, NULL, NULL, 0); @@ -216,11 +220,16 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) f2fs_wait_on_page_writeback(dn.inode_page, NODE, true); src_addr = kmap_atomic(page); - dst_addr = inline_data_addr(dn.inode_page); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + dst_addr = inline_data_addr(inode, dn.inode_page); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); kunmap_atomic(src_addr); set_page_dirty(dn.inode_page); + spin_lock_irqsave(&mapping->tree_lock, flags); + radix_tree_tag_clear(&mapping->page_tree, page_index(page), + PAGECACHE_TAG_DIRTY); + spin_unlock_irqrestore(&mapping->tree_lock, flags); + set_inode_flag(inode, FI_APPEND_WRITE); set_inode_flag(inode, FI_DATA_EXIST); @@ -255,9 +264,9 @@ bool recover_inline_data(struct inode *inode, struct page *npage) f2fs_wait_on_page_writeback(ipage, NODE, true); - src_addr = inline_data_addr(npage); - dst_addr = inline_data_addr(ipage); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + src_addr = inline_data_addr(inode, npage); + dst_addr = inline_data_addr(inode, ipage); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); set_inode_flag(inode, FI_INLINE_DATA); set_inode_flag(inode, FI_DATA_EXIST); @@ -285,11 +294,11 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, struct fscrypt_name *fname, struct page **res_page) { struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); - struct f2fs_inline_dentry *inline_dentry; struct qstr name = FSTR_TO_QSTR(&fname->disk_name); struct f2fs_dir_entry *de; struct f2fs_dentry_ptr d; struct page *ipage; + void *inline_dentry; f2fs_hash_t namehash; ipage = get_node_page(sbi, dir->i_ino); @@ -300,9 +309,9 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, namehash = f2fs_dentry_hash(&name, fname); - inline_dentry = inline_data_addr(ipage); + inline_dentry = inline_data_addr(dir, ipage); - make_dentry_ptr_inline(NULL, &d, inline_dentry); + make_dentry_ptr_inline(dir, &d, inline_dentry); de = find_target_dentry(fname, namehash, NULL, &d); unlock_page(ipage); if (de) @@ -316,19 +325,19 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, int make_empty_inline_dir(struct inode *inode, struct inode *parent, struct page *ipage) { - struct f2fs_inline_dentry *inline_dentry; struct f2fs_dentry_ptr d; + void *inline_dentry; - inline_dentry = inline_data_addr(ipage); + inline_dentry = inline_data_addr(inode, ipage); - make_dentry_ptr_inline(NULL, &d, inline_dentry); + make_dentry_ptr_inline(inode, &d, inline_dentry); do_make_empty_dir(inode, parent, &d); set_page_dirty(ipage); /* update i_size to MAX_INLINE_DATA */ - if (i_size_read(inode) < MAX_INLINE_DATA) - f2fs_i_size_write(inode, MAX_INLINE_DATA); + if (i_size_read(inode) < MAX_INLINE_DATA(inode)) + f2fs_i_size_write(inode, MAX_INLINE_DATA(inode)); return 0; } @@ -337,11 +346,12 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent, * release ipage in this function. */ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, - struct f2fs_inline_dentry *inline_dentry) + void *inline_dentry) { struct page *page; struct dnode_of_data dn; struct f2fs_dentry_block *dentry_blk; + struct f2fs_dentry_ptr src, dst; int err; page = f2fs_grab_cache_page(dir->i_mapping, 0, false); @@ -356,25 +366,24 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, goto out; f2fs_wait_on_page_writeback(page, DATA, true); - zero_user_segment(page, MAX_INLINE_DATA, PAGE_SIZE); + zero_user_segment(page, MAX_INLINE_DATA(dir), PAGE_SIZE); dentry_blk = kmap_atomic(page); + make_dentry_ptr_inline(dir, &src, inline_dentry); + make_dentry_ptr_block(dir, &dst, dentry_blk); + /* copy data from inline dentry block to new dentry block */ - memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap, - INLINE_DENTRY_BITMAP_SIZE); - memset(dentry_blk->dentry_bitmap + INLINE_DENTRY_BITMAP_SIZE, 0, - SIZE_OF_DENTRY_BITMAP - INLINE_DENTRY_BITMAP_SIZE); + memcpy(dst.bitmap, src.bitmap, src.nr_bitmap); + memset(dst.bitmap + src.nr_bitmap, 0, dst.nr_bitmap - src.nr_bitmap); /* * we do not need to zero out remainder part of dentry and filename * field, since we have used bitmap for marking the usage status of * them, besides, we can also ignore copying/zeroing reserved space * of dentry block, because them haven't been used so far. */ - memcpy(dentry_blk->dentry, inline_dentry->dentry, - sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY); - memcpy(dentry_blk->filename, inline_dentry->filename, - NR_INLINE_DENTRY * F2FS_SLOT_LEN); + memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max); + memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN); kunmap_atomic(dentry_blk); if (!PageUptodate(page)) @@ -395,14 +404,13 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, return err; } -static int f2fs_add_inline_entries(struct inode *dir, - struct f2fs_inline_dentry *inline_dentry) +static int f2fs_add_inline_entries(struct inode *dir, void *inline_dentry) { struct f2fs_dentry_ptr d; unsigned long bit_pos = 0; int err = 0; - make_dentry_ptr_inline(NULL, &d, inline_dentry); + make_dentry_ptr_inline(dir, &d, inline_dentry); while (bit_pos < d.max) { struct f2fs_dir_entry *de; @@ -444,19 +452,19 @@ static int f2fs_add_inline_entries(struct inode *dir, } static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage, - struct f2fs_inline_dentry *inline_dentry) + void *inline_dentry) { - struct f2fs_inline_dentry *backup_dentry; + void *backup_dentry; int err; backup_dentry = f2fs_kmalloc(F2FS_I_SB(dir), - sizeof(struct f2fs_inline_dentry), GFP_F2FS_ZERO); + MAX_INLINE_DATA(dir), GFP_F2FS_ZERO); if (!backup_dentry) { f2fs_put_page(ipage, 1); return -ENOMEM; } - memcpy(backup_dentry, inline_dentry, MAX_INLINE_DATA); + memcpy(backup_dentry, inline_dentry, MAX_INLINE_DATA(dir)); truncate_inline_inode(dir, ipage, 0); unlock_page(ipage); @@ -473,9 +481,9 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage, return 0; recover: lock_page(ipage); - memcpy(inline_dentry, backup_dentry, MAX_INLINE_DATA); + memcpy(inline_dentry, backup_dentry, MAX_INLINE_DATA(dir)); f2fs_i_depth_write(dir, 0); - f2fs_i_size_write(dir, MAX_INLINE_DATA); + f2fs_i_size_write(dir, MAX_INLINE_DATA(dir)); set_page_dirty(ipage); f2fs_put_page(ipage, 1); @@ -484,7 +492,7 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage, } static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, - struct f2fs_inline_dentry *inline_dentry) + void *inline_dentry) { if (!F2FS_I(dir)->i_dir_level) return f2fs_move_inline_dirents(dir, ipage, inline_dentry); @@ -500,7 +508,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, struct page *ipage; unsigned int bit_pos; f2fs_hash_t name_hash; - struct f2fs_inline_dentry *inline_dentry = NULL; + void *inline_dentry = NULL; struct f2fs_dentry_ptr d; int slots = GET_DENTRY_SLOTS(new_name->len); struct page *page = NULL; @@ -510,10 +518,11 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, if (IS_ERR(ipage)) return PTR_ERR(ipage); - inline_dentry = inline_data_addr(ipage); - bit_pos = room_for_filename(&inline_dentry->dentry_bitmap, - slots, NR_INLINE_DENTRY); - if (bit_pos >= NR_INLINE_DENTRY) { + inline_dentry = inline_data_addr(dir, ipage); + make_dentry_ptr_inline(dir, &d, inline_dentry); + + bit_pos = room_for_filename(d.bitmap, slots, d.max); + if (bit_pos >= d.max) { err = f2fs_convert_inline_dir(dir, ipage, inline_dentry); if (err) return err; @@ -534,7 +543,6 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, f2fs_wait_on_page_writeback(ipage, NODE, true); name_hash = f2fs_dentry_hash(new_name, NULL); - make_dentry_ptr_inline(NULL, &d, inline_dentry); f2fs_update_dentry(ino, mode, &d, new_name, name_hash, bit_pos); set_page_dirty(ipage); @@ -557,7 +565,8 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *new_name, void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, struct inode *dir, struct inode *inode) { - struct f2fs_inline_dentry *inline_dentry; + struct f2fs_dentry_ptr d; + void *inline_dentry; int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); unsigned int bit_pos; int i; @@ -565,11 +574,12 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, lock_page(page); f2fs_wait_on_page_writeback(page, NODE, true); - inline_dentry = inline_data_addr(page); - bit_pos = dentry - inline_dentry->dentry; + inline_dentry = inline_data_addr(dir, page); + make_dentry_ptr_inline(dir, &d, inline_dentry); + + bit_pos = dentry - d.dentry; for (i = 0; i < slots; i++) - __clear_bit_le(bit_pos + i, - &inline_dentry->dentry_bitmap); + __clear_bit_le(bit_pos + i, d.bitmap); set_page_dirty(page); f2fs_put_page(page, 1); @@ -586,20 +596,21 @@ bool f2fs_empty_inline_dir(struct inode *dir) struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct page *ipage; unsigned int bit_pos = 2; - struct f2fs_inline_dentry *inline_dentry; + void *inline_dentry; + struct f2fs_dentry_ptr d; ipage = get_node_page(sbi, dir->i_ino); if (IS_ERR(ipage)) return false; - inline_dentry = inline_data_addr(ipage); - bit_pos = find_next_bit_le(&inline_dentry->dentry_bitmap, - NR_INLINE_DENTRY, - bit_pos); + inline_dentry = inline_data_addr(dir, ipage); + make_dentry_ptr_inline(dir, &d, inline_dentry); + + bit_pos = find_next_bit_le(d.bitmap, d.max, bit_pos); f2fs_put_page(ipage, 1); - if (bit_pos < NR_INLINE_DENTRY) + if (bit_pos < d.max) return false; return true; @@ -609,25 +620,27 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx, struct fscrypt_str *fstr) { struct inode *inode = file_inode(file); - struct f2fs_inline_dentry *inline_dentry = NULL; struct page *ipage = NULL; struct f2fs_dentry_ptr d; + void *inline_dentry = NULL; int err; - if (ctx->pos == NR_INLINE_DENTRY) + make_dentry_ptr_inline(inode, &d, inline_dentry); + + if (ctx->pos == d.max) return 0; ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); if (IS_ERR(ipage)) return PTR_ERR(ipage); - inline_dentry = inline_data_addr(ipage); + inline_dentry = inline_data_addr(inode, ipage); make_dentry_ptr_inline(inode, &d, inline_dentry); err = f2fs_fill_dentries(ctx, &d, 0, fstr); if (!err) - ctx->pos = NR_INLINE_DENTRY; + ctx->pos = d.max; f2fs_put_page(ipage, 1); return err < 0 ? err : 0; @@ -652,7 +665,7 @@ int f2fs_inline_data_fiemap(struct inode *inode, goto out; } - ilen = min_t(size_t, MAX_INLINE_DATA, i_size_read(inode)); + ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode)); if (start >= ilen) goto out; if (start + len < ilen) @@ -661,7 +674,8 @@ int f2fs_inline_data_fiemap(struct inode *inode, get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni); byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits; - byteaddr += (char *)inline_data_addr(ipage) - (char *)F2FS_INODE(ipage); + byteaddr += (char *)inline_data_addr(inode, ipage) - + (char *)F2FS_INODE(ipage); err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags); out: f2fs_put_page(ipage, 1); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 6cd312a17c695948b8a04e797857c2ead807f811..50c88e37ed668106b20cf4993c4bff6b11f95009 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -49,20 +49,22 @@ void f2fs_set_inode_flags(struct inode *inode) static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) { + int extra_size = get_extra_isize(inode); + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { - if (ri->i_addr[0]) - inode->i_rdev = - old_decode_dev(le32_to_cpu(ri->i_addr[0])); + if (ri->i_addr[extra_size]) + inode->i_rdev = old_decode_dev( + le32_to_cpu(ri->i_addr[extra_size])); else - inode->i_rdev = - new_decode_dev(le32_to_cpu(ri->i_addr[1])); + inode->i_rdev = new_decode_dev( + le32_to_cpu(ri->i_addr[extra_size + 1])); } } static bool __written_first_block(struct f2fs_inode *ri) { - block_t addr = le32_to_cpu(ri->i_addr[0]); + block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]); if (addr != NEW_ADDR && addr != NULL_ADDR) return true; @@ -71,25 +73,27 @@ static bool __written_first_block(struct f2fs_inode *ri) static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri) { + int extra_size = get_extra_isize(inode); + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { if (old_valid_dev(inode->i_rdev)) { - ri->i_addr[0] = + ri->i_addr[extra_size] = cpu_to_le32(old_encode_dev(inode->i_rdev)); - ri->i_addr[1] = 0; + ri->i_addr[extra_size + 1] = 0; } else { - ri->i_addr[0] = 0; - ri->i_addr[1] = + ri->i_addr[extra_size] = 0; + ri->i_addr[extra_size + 1] = cpu_to_le32(new_encode_dev(inode->i_rdev)); - ri->i_addr[2] = 0; + ri->i_addr[extra_size + 2] = 0; } } } static void __recover_inline_status(struct inode *inode, struct page *ipage) { - void *inline_data = inline_data_addr(ipage); + void *inline_data = inline_data_addr(inode, ipage); __le32 *start = inline_data; - __le32 *end = start + MAX_INLINE_DATA / sizeof(__le32); + __le32 *end = start + MAX_INLINE_DATA(inode) / sizeof(__le32); while (start < end) { if (*start++) { @@ -104,12 +108,84 @@ static void __recover_inline_status(struct inode *inode, struct page *ipage) return; } +static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) +{ + struct f2fs_inode *ri = &F2FS_NODE(page)->i; + int extra_isize = le32_to_cpu(ri->i_extra_isize); + + if (!f2fs_sb_has_inode_chksum(sbi->sb)) + return false; + + if (!RAW_IS_INODE(F2FS_NODE(page)) || !(ri->i_inline & F2FS_EXTRA_ATTR)) + return false; + + if (!F2FS_FITS_IN_INODE(ri, extra_isize, i_inode_checksum)) + return false; + + return true; +} + +static __u32 f2fs_inode_chksum(struct f2fs_sb_info *sbi, struct page *page) +{ + struct f2fs_node *node = F2FS_NODE(page); + struct f2fs_inode *ri = &node->i; + __le32 ino = node->footer.ino; + __le32 gen = ri->i_generation; + __u32 chksum, chksum_seed; + __u32 dummy_cs = 0; + unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum); + unsigned int cs_size = sizeof(dummy_cs); + + chksum = f2fs_chksum(sbi, sbi->s_chksum_seed, (__u8 *)&ino, + sizeof(ino)); + chksum_seed = f2fs_chksum(sbi, chksum, (__u8 *)&gen, sizeof(gen)); + + chksum = f2fs_chksum(sbi, chksum_seed, (__u8 *)ri, offset); + chksum = f2fs_chksum(sbi, chksum, (__u8 *)&dummy_cs, cs_size); + offset += cs_size; + chksum = f2fs_chksum(sbi, chksum, (__u8 *)ri + offset, + F2FS_BLKSIZE - offset); + return chksum; +} + +bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page) +{ + struct f2fs_inode *ri; + __u32 provided, calculated; + + if (!f2fs_enable_inode_chksum(sbi, page) || + PageDirty(page) || PageWriteback(page)) + return true; + + ri = &F2FS_NODE(page)->i; + provided = le32_to_cpu(ri->i_inode_checksum); + calculated = f2fs_inode_chksum(sbi, page); + + if (provided != calculated) + f2fs_msg(sbi->sb, KERN_WARNING, + "checksum invalid, ino = %x, %x vs. %x", + ino_of_node(page), provided, calculated); + + return provided == calculated; +} + +void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page) +{ + struct f2fs_inode *ri = &F2FS_NODE(page)->i; + + if (!f2fs_enable_inode_chksum(sbi, page)) + return; + + ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page)); +} + static int do_read_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); struct page *node_page; struct f2fs_inode *ri; + projid_t i_projid; /* Check if ino is within scope */ if (check_nid_range(sbi, inode->i_ino)) { @@ -153,6 +229,9 @@ static int do_read_inode(struct inode *inode) get_inline_info(inode, ri); + fi->i_extra_isize = f2fs_has_extra_attr(inode) ? + le16_to_cpu(ri->i_extra_isize) : 0; + /* check data exist */ if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) __recover_inline_status(inode, node_page); @@ -166,6 +245,16 @@ static int do_read_inode(struct inode *inode) if (!need_inode_block_update(sbi, inode->i_ino)) fi->last_disk_size = inode->i_size; + if (fi->i_flags & FS_PROJINHERIT_FL) + set_inode_flag(inode, FI_PROJ_INHERIT); + + if (f2fs_has_extra_attr(inode) && f2fs_sb_has_project_quota(sbi->sb) && + F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_projid)) + i_projid = (projid_t)le32_to_cpu(ri->i_projid); + else + i_projid = F2FS_DEF_PROJID; + fi->i_projid = make_kprojid(&init_user_ns, i_projid); + f2fs_put_page(node_page, 1); stat_inc_inline_xattr(inode); @@ -292,6 +381,20 @@ int update_inode(struct inode *inode, struct page *node_page) ri->i_generation = cpu_to_le32(inode->i_generation); ri->i_dir_level = F2FS_I(inode)->i_dir_level; + if (f2fs_has_extra_attr(inode)) { + ri->i_extra_isize = cpu_to_le16(F2FS_I(inode)->i_extra_isize); + + if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)->sb) && + F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, + i_projid)) { + projid_t i_projid; + + i_projid = from_kprojid(&init_user_ns, + F2FS_I(inode)->i_projid); + ri->i_projid = cpu_to_le32(i_projid); + } + } + __set_inode_rdev(inode, ri); set_cold_node(inode, node_page); @@ -416,6 +519,9 @@ void f2fs_evict_inode(struct inode *inode) stat_dec_inline_dir(inode); stat_dec_inline_inode(inode); + if (!is_set_ckpt_flags(sbi, CP_ERROR_FLAG)) + f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)); + /* ino == 0, if f2fs_new_inode() was failed t*/ if (inode->i_ino) invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 760d85223c8133b8b0ac808205df1f49aa42a4c2..a4dab98c4b7ba7c2d2b69086e5b439c36d323382 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -58,6 +58,13 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) goto fail; } + if (f2fs_sb_has_project_quota(sbi->sb) && + (F2FS_I(dir)->i_flags & FS_PROJINHERIT_FL)) + F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid; + else + F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns, + F2FS_DEF_PROJID); + err = dquot_initialize(inode); if (err) goto fail_drop; @@ -72,6 +79,11 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) set_inode_flag(inode, FI_NEW_INODE); + if (f2fs_sb_has_extra_attr(sbi->sb)) { + set_inode_flag(inode, FI_EXTRA_ATTR); + F2FS_I(inode)->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE; + } + if (test_opt(sbi, INLINE_XATTR)) set_inode_flag(inode, FI_INLINE_XATTR); if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) @@ -85,6 +97,15 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) stat_inc_inline_inode(inode); stat_inc_inline_dir(inode); + F2FS_I(inode)->i_flags = + f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED); + + if (S_ISDIR(inode->i_mode)) + F2FS_I(inode)->i_flags |= FS_INDEX_FL; + + if (F2FS_I(inode)->i_flags & FS_PROJINHERIT_FL) + set_inode_flag(inode, FI_PROJ_INHERIT); + trace_f2fs_new_inode(inode, 0); return inode; @@ -204,6 +225,11 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, !fscrypt_has_permitted_context(dir, inode)) return -EPERM; + if (is_inode_flag_set(dir, FI_PROJ_INHERIT) && + (!projid_eq(F2FS_I(dir)->i_projid, + F2FS_I(old_dentry->d_inode)->i_projid))) + return -EXDEV; + err = dquot_initialize(dir); if (err) return err; @@ -261,6 +287,10 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) return 0; } + err = dquot_initialize(dir); + if (err) + return err; + f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); @@ -724,6 +754,11 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; } + if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && + (!projid_eq(F2FS_I(new_dir)->i_projid, + F2FS_I(old_dentry->d_inode)->i_projid))) + return -EXDEV; + err = dquot_initialize(old_dir); if (err) goto out; @@ -912,6 +947,14 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, !fscrypt_has_permitted_context(old_dir, new_inode))) return -EPERM; + if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && + !projid_eq(F2FS_I(new_dir)->i_projid, + F2FS_I(old_dentry->d_inode)->i_projid)) || + (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && + !projid_eq(F2FS_I(old_dir)->i_projid, + F2FS_I(new_dentry->d_inode)->i_projid))) + return -EXDEV; + err = dquot_initialize(old_dir); if (err) goto out; diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index d53fe620939ee15f370099956b32984198e93b94..fca87835a1da3f19a36a651f71493397e0fd7f8c 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -19,6 +19,7 @@ #include "f2fs.h" #include "node.h" #include "segment.h" +#include "xattr.h" #include "trace.h" #include @@ -554,7 +555,7 @@ static int get_node_path(struct inode *inode, long block, level = 3; goto got; } else { - BUG(); + return -E2BIG; } got: return level; @@ -578,6 +579,8 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) int err = 0; level = get_node_path(dn->inode, index, offset, noffset); + if (level < 0) + return level; nids[0] = dn->inode->i_ino; npage[0] = dn->inode_page; @@ -613,7 +616,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) } dn->nid = nids[i]; - npage[i] = new_node_page(dn, noffset[i], NULL); + npage[i] = new_node_page(dn, noffset[i]); if (IS_ERR(npage[i])) { alloc_nid_failed(sbi, nids[i]); err = PTR_ERR(npage[i]); @@ -654,7 +657,8 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) dn->nid = nids[level]; dn->ofs_in_node = offset[level]; dn->node_page = npage[level]; - dn->data_blkaddr = datablock_addr(dn->node_page, dn->ofs_in_node); + dn->data_blkaddr = datablock_addr(dn->inode, + dn->node_page, dn->ofs_in_node); return 0; release_pages: @@ -876,6 +880,8 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) trace_f2fs_truncate_inode_blocks_enter(inode, from); level = get_node_path(inode, from, offset, noffset); + if (level < 0) + return level; page = get_node_page(sbi, inode->i_ino); if (IS_ERR(page)) { @@ -1022,11 +1028,10 @@ struct page *new_inode_page(struct inode *inode) set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); /* caller should f2fs_put_page(page, 1); */ - return new_node_page(&dn, 0, NULL); + return new_node_page(&dn, 0); } -struct page *new_node_page(struct dnode_of_data *dn, - unsigned int ofs, struct page *ipage) +struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) { struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct node_info new_ni; @@ -1170,6 +1175,11 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, err = -EIO; goto out_err; } + + if (!f2fs_inode_chksum_verify(sbi, page)) { + err = -EBADMSG; + goto out_err; + } page_hit: if(unlikely(nid != nid_of_node(page))) { f2fs_msg(sbi->sb, KERN_WARNING, "inconsistent node block, " @@ -1177,9 +1187,9 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, nid, nid_of_node(page), ino_of_node(page), ofs_of_node(page), cpver_of_node(page), next_blkaddr_of_node(page)); - ClearPageUptodate(page); err = -EINVAL; out_err: + ClearPageUptodate(page); f2fs_put_page(page, 1); return ERR_PTR(err); } @@ -1326,7 +1336,8 @@ static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino) } static int __write_node_page(struct page *page, bool atomic, bool *submitted, - struct writeback_control *wbc) + struct writeback_control *wbc, bool do_balance, + enum iostat_type io_type) { struct f2fs_sb_info *sbi = F2FS_P_SB(page); nid_t nid; @@ -1339,6 +1350,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, .page = page, .encrypted_page = NULL, .submitted = false, + .io_type = io_type, }; trace_f2fs_writepage(page, NODE); @@ -1395,6 +1407,8 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, if (submitted) *submitted = fio.submitted; + if (do_balance) + f2fs_balance_fs(sbi, false); return 0; redirty_out: @@ -1405,7 +1419,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, static int f2fs_write_node_page(struct page *page, struct writeback_control *wbc) { - return __write_node_page(page, false, NULL, wbc); + return __write_node_page(page, false, NULL, wbc, false, FS_NODE_IO); } int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, @@ -1493,7 +1507,8 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, ret = __write_node_page(page, atomic && page == last_page, - &submitted, wbc); + &submitted, wbc, true, + FS_NODE_IO); if (ret) { unlock_page(page); f2fs_put_page(last_page, 0); @@ -1530,7 +1545,8 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, return ret ? -EIO: 0; } -int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc) +int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc, + bool do_balance, enum iostat_type io_type) { pgoff_t index, end; struct pagevec pvec; @@ -1608,7 +1624,8 @@ int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc) set_fsync_mark(page, 0); set_dentry_mark(page, 0); - ret = __write_node_page(page, false, &submitted, wbc); + ret = __write_node_page(page, false, &submitted, + wbc, do_balance, io_type); if (ret) unlock_page(page); else if (submitted) @@ -1697,7 +1714,7 @@ static int f2fs_write_node_pages(struct address_space *mapping, diff = nr_pages_to_write(sbi, NODE, wbc); wbc->sync_mode = WB_SYNC_NONE; blk_start_plug(&plug); - sync_node_pages(sbi, wbc); + sync_node_pages(sbi, wbc, true, FS_NODE_IO); blk_finish_plug(&plug); wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff); return 0; @@ -2191,7 +2208,8 @@ int recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid; - nid_t new_xnid = nid_of_node(page); + nid_t new_xnid; + struct dnode_of_data dn; struct node_info ni; struct page *xpage; @@ -2207,22 +2225,22 @@ int recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr) recover_xnid: /* 2: update xattr nid in inode */ - remove_free_nid(sbi, new_xnid); - f2fs_i_xnid_write(inode, new_xnid); - if (unlikely(inc_valid_node_count(sbi, inode, false))) - f2fs_bug_on(sbi, 1); + if (!alloc_nid(sbi, &new_xnid)) + return -ENOSPC; + + set_new_dnode(&dn, inode, NULL, NULL, new_xnid); + xpage = new_node_page(&dn, XATTR_NODE_OFFSET); + if (IS_ERR(xpage)) { + alloc_nid_failed(sbi, new_xnid); + return PTR_ERR(xpage); + } + + alloc_nid_done(sbi, new_xnid); update_inode_page(inode); /* 3: update and set xattr node page dirty */ - xpage = grab_cache_page(NODE_MAPPING(sbi), new_xnid); - if (!xpage) - return -ENOMEM; - - memcpy(F2FS_NODE(xpage), F2FS_NODE(page), PAGE_SIZE); + memcpy(F2FS_NODE(xpage), F2FS_NODE(page), VALID_XATTR_BLOCK_SIZE); - get_node_info(sbi, new_xnid, &ni); - ni.ino = inode->i_ino; - set_node_addr(sbi, &ni, NEW_ADDR, false); set_page_dirty(xpage); f2fs_put_page(xpage, 1); @@ -2262,7 +2280,14 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) dst->i_blocks = cpu_to_le64(1); dst->i_links = cpu_to_le32(1); dst->i_xattr_nid = 0; - dst->i_inline = src->i_inline & F2FS_INLINE_XATTR; + dst->i_inline = src->i_inline & (F2FS_INLINE_XATTR | F2FS_EXTRA_ATTR); + if (dst->i_inline & F2FS_EXTRA_ATTR) { + dst->i_extra_isize = src->i_extra_isize; + if (f2fs_sb_has_project_quota(sbi->sb) && + F2FS_FITS_IN_INODE(src, le16_to_cpu(src->i_extra_isize), + i_projid)) + dst->i_projid = src->i_projid; + } new_ni = old_ni; new_ni.ino = ino; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 907d6b7dde6a7f636ea7027d461cfd029b8b1ae5..9626758bc76242ca4a91057924d7492e6c217a85 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -69,20 +69,34 @@ static struct fsync_inode_entry *get_fsync_inode(struct list_head *head, } static struct fsync_inode_entry *add_fsync_inode(struct f2fs_sb_info *sbi, - struct list_head *head, nid_t ino) + struct list_head *head, nid_t ino, bool quota_inode) { struct inode *inode; struct fsync_inode_entry *entry; + int err; inode = f2fs_iget_retry(sbi->sb, ino); if (IS_ERR(inode)) return ERR_CAST(inode); + err = dquot_initialize(inode); + if (err) + goto err_out; + + if (quota_inode) { + err = dquot_alloc_inode(inode); + if (err) + goto err_out; + } + entry = f2fs_kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO); entry->inode = inode; list_add_tail(&entry->list, head); return entry; +err_out: + iput(inode); + return ERR_PTR(err); } static void del_fsync_inode(struct fsync_inode_entry *entry) @@ -107,7 +121,8 @@ static int recover_dentry(struct inode *inode, struct page *ipage, entry = get_fsync_inode(dir_list, pino); if (!entry) { - entry = add_fsync_inode(F2FS_I_SB(inode), dir_list, pino); + entry = add_fsync_inode(F2FS_I_SB(inode), dir_list, + pino, false); if (IS_ERR(entry)) { dir = ERR_CAST(entry); err = PTR_ERR(entry); @@ -140,6 +155,13 @@ static int recover_dentry(struct inode *inode, struct page *ipage, err = -EEXIST; goto out_unmap_put; } + + err = dquot_initialize(einode); + if (err) { + iput(einode); + goto out_unmap_put; + } + err = acquire_orphan_inode(F2FS_I_SB(inode)); if (err) { iput(einode); @@ -226,18 +248,22 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, entry = get_fsync_inode(head, ino_of_node(page)); if (!entry) { + bool quota_inode = false; + if (!check_only && IS_INODE(page) && is_dent_dnode(page)) { err = recover_inode_page(sbi, page); if (err) break; + quota_inode = true; } /* * CP | dnode(F) | inode(DF) * For this case, we should not give up now. */ - entry = add_fsync_inode(sbi, head, ino_of_node(page)); + entry = add_fsync_inode(sbi, head, ino_of_node(page), + quota_inode); if (IS_ERR(entry)) { err = PTR_ERR(entry); if (err == -ENOENT) { @@ -291,7 +317,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, return 0; /* Get the previous summary */ - for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) { + for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { struct curseg_info *curseg = CURSEG_I(sbi, i); if (curseg->segno == segno) { sum = curseg->sum_blk->entries[blkoff]; @@ -328,10 +354,18 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, f2fs_put_page(node_page, 1); if (ino != dn->inode->i_ino) { + int ret; + /* Deallocate previous index in the node page */ inode = f2fs_iget_retry(sbi->sb, ino); if (IS_ERR(inode)) return PTR_ERR(inode); + + ret = dquot_initialize(inode); + if (ret) { + iput(inode); + return ret; + } } else { inode = dn->inode; } @@ -361,7 +395,8 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, return 0; truncate_out: - if (datablock_addr(tdn.node_page, tdn.ofs_in_node) == blkaddr) + if (datablock_addr(tdn.inode, tdn.node_page, + tdn.ofs_in_node) == blkaddr) truncate_data_blocks_range(&tdn, 1); if (dn->inode->i_ino == nid && !dn->inode_page_locked) unlock_page(dn->inode_page); @@ -414,8 +449,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, for (; start < end; start++, dn.ofs_in_node++) { block_t src, dest; - src = datablock_addr(dn.node_page, dn.ofs_in_node); - dest = datablock_addr(page, dn.ofs_in_node); + src = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node); + dest = datablock_addr(dn.inode, page, dn.ofs_in_node); /* skip recovering if dest is the same as src */ if (src == dest) @@ -557,12 +592,27 @@ int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) struct list_head dir_list; int err; int ret = 0; + unsigned long s_flags = sbi->sb->s_flags; bool need_writecp = false; + if (s_flags & MS_RDONLY) { + f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs"); + sbi->sb->s_flags &= ~MS_RDONLY; + } + +#ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sbi->sb->s_flags |= MS_ACTIVE; + /* Turn on quotas so that they are updated correctly */ + f2fs_enable_quota_files(sbi); +#endif + fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry", sizeof(struct fsync_inode_entry)); - if (!fsync_entry_slab) - return -ENOMEM; + if (!fsync_entry_slab) { + err = -ENOMEM; + goto out; + } INIT_LIST_HEAD(&inode_list); INIT_LIST_HEAD(&dir_list); @@ -573,11 +623,11 @@ int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) /* step #1: find fsynced inode numbers */ err = find_fsync_dnodes(sbi, &inode_list, check_only); if (err || list_empty(&inode_list)) - goto out; + goto skip; if (check_only) { ret = 1; - goto out; + goto skip; } need_writecp = true; @@ -586,7 +636,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) err = recover_data(sbi, &inode_list, &dir_list); if (!err) f2fs_bug_on(sbi, !list_empty(&inode_list)); -out: +skip: destroy_fsync_dnodes(&inode_list); /* truncate meta pages to be used by the recovery */ @@ -599,8 +649,6 @@ int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) } clear_sbi_flag(sbi, SBI_POR_DOING); - if (err) - set_ckpt_flags(sbi, CP_ERROR_FLAG); mutex_unlock(&sbi->cp_mutex); /* let's drop all the directory inodes for clean checkpoint */ @@ -614,5 +662,12 @@ int recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) } kmem_cache_destroy(fsync_entry_slab); +out: +#ifdef CONFIG_QUOTA + /* Turn quotas off */ + f2fs_quota_off_umount(sbi->sb); +#endif + sbi->sb->s_flags = s_flags; /* Restore MS_RDONLY status */ + return ret ? ret: err; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index f964b68718c18f5953971351a5358ccaa841a6ca..621b9b3d320bba293f68b5eaf74b91aa364dd567 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -17,10 +17,12 @@ #include #include #include +#include #include "f2fs.h" #include "segment.h" #include "node.h" +#include "gc.h" #include "trace.h" #include @@ -167,6 +169,21 @@ static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, return result - size + __reverse_ffz(tmp); } +bool need_SSR(struct f2fs_sb_info *sbi) +{ + int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); + int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); + int imeta_secs = get_blocktype_secs(sbi, F2FS_DIRTY_IMETA); + + if (test_opt(sbi, LFS)) + return false; + if (sbi->gc_thread && sbi->gc_thread->gc_urgent) + return true; + + return free_sections(sbi) <= (node_secs + 2 * dent_secs + imeta_secs + + 2 * reserved_sections(sbi)); +} + void register_inmem_page(struct inode *inode, struct page *page) { struct f2fs_inode_info *fi = F2FS_I(inode); @@ -213,9 +230,15 @@ static int __revoke_inmem_pages(struct inode *inode, struct node_info ni; trace_f2fs_commit_inmem_page(page, INMEM_REVOKE); - +retry: set_new_dnode(&dn, inode, NULL, NULL, 0); - if (get_dnode_of_data(&dn, page->index, LOOKUP_NODE)) { + err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE); + if (err) { + if (err == -ENOMEM) { + congestion_wait(BLK_RW_ASYNC, HZ/50); + cond_resched(); + goto retry; + } err = -EAGAIN; goto next; } @@ -248,6 +271,7 @@ void drop_inmem_pages(struct inode *inode) mutex_unlock(&fi->inmem_lock); clear_inode_flag(inode, FI_ATOMIC_FILE); + clear_inode_flag(inode, FI_HOT_DATA); stat_dec_atomic_write(inode); } @@ -292,6 +316,7 @@ static int __commit_inmem_pages(struct inode *inode, .type = DATA, .op = REQ_OP_WRITE, .op_flags = REQ_SYNC | REQ_PRIO, + .io_type = FS_DATA_IO, }; pgoff_t last_idx = ULONG_MAX; int err = 0; @@ -309,17 +334,21 @@ static int __commit_inmem_pages(struct inode *inode, inode_dec_dirty_pages(inode); remove_dirty_inode(inode); } - +retry: fio.page = page; fio.old_blkaddr = NULL_ADDR; fio.encrypted_page = NULL; fio.need_lock = LOCK_DONE; err = do_write_data_page(&fio); if (err) { + if (err == -ENOMEM) { + congestion_wait(BLK_RW_ASYNC, HZ/50); + cond_resched(); + goto retry; + } unlock_page(page); break; } - /* record old blkaddr for revoking */ cur->old_addr = fio.old_blkaddr; last_idx = page->index; @@ -447,7 +476,7 @@ static int __submit_flush_wait(struct f2fs_sb_info *sbi, int ret; bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH; - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); ret = submit_bio_wait(bio); bio_put(bio); @@ -481,6 +510,8 @@ static int issue_flush_thread(void *data) if (kthread_should_stop()) return 0; + sb_start_intwrite(sbi->sb); + if (!llist_empty(&fcc->issue_list)) { struct flush_cmd *cmd, *next; int ret; @@ -499,6 +530,8 @@ static int issue_flush_thread(void *data) fcc->dispatch_list = NULL; } + sb_end_intwrite(sbi->sb); + wait_event_interruptible(*q, kthread_should_stop() || !llist_empty(&fcc->issue_list)); goto repeat; @@ -519,8 +552,7 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi) return ret; } - if (!atomic_read(&fcc->issing_flush)) { - atomic_inc(&fcc->issing_flush); + if (atomic_inc_return(&fcc->issing_flush) == 1) { ret = submit_flush_wait(sbi); atomic_dec(&fcc->issing_flush); @@ -530,18 +562,39 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi) init_completion(&cmd.wait); - atomic_inc(&fcc->issing_flush); llist_add(&cmd.llnode, &fcc->issue_list); - if (!fcc->dispatch_list) + /* update issue_list before we wake up issue_flush thread */ + smp_mb(); + + if (waitqueue_active(&fcc->flush_wait_queue)) wake_up(&fcc->flush_wait_queue); if (fcc->f2fs_issue_flush) { wait_for_completion(&cmd.wait); atomic_dec(&fcc->issing_flush); } else { - llist_del_all(&fcc->issue_list); - atomic_set(&fcc->issing_flush, 0); + struct llist_node *list; + + list = llist_del_all(&fcc->issue_list); + if (!list) { + wait_for_completion(&cmd.wait); + atomic_dec(&fcc->issing_flush); + } else { + struct flush_cmd *tmp, *next; + + ret = submit_flush_wait(sbi); + + llist_for_each_entry_safe(tmp, next, list, llnode) { + if (tmp == &cmd) { + cmd.ret = ret; + atomic_dec(&fcc->issing_flush); + continue; + } + tmp->ret = ret; + complete(&tmp->wait); + } + } } return cmd.ret; @@ -778,11 +831,14 @@ void __check_sit_bitmap(struct f2fs_sb_info *sbi, sentry = get_seg_entry(sbi, segno); offset = GET_BLKOFF_FROM_SEG0(sbi, blk); - size = min((unsigned long)(end - blk), max_blocks); + if (end < START_BLOCK(sbi, segno + 1)) + size = GET_BLKOFF_FROM_SEG0(sbi, end); + else + size = max_blocks; map = (unsigned long *)(sentry->cur_valid_map); offset = __find_rev_next_bit(map, size, offset); f2fs_bug_on(sbi, offset != size); - blk += size; + blk = START_BLOCK(sbi, segno + 1); } #endif } @@ -815,6 +871,8 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi, submit_bio(bio); list_move_tail(&dc->list, &dcc->wait_list); __check_sit_bitmap(sbi, dc->start, dc->start + dc->len); + + f2fs_update_iostat(sbi, FS_DISCARD, 1); } } else { __remove_discard_cmd(sbi, dc); @@ -996,32 +1054,81 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi, return 0; } -static void __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond) +static int __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond) { struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; struct list_head *pend_list; struct discard_cmd *dc, *tmp; struct blk_plug plug; - int i, iter = 0; + int iter = 0, issued = 0; + int i; + bool io_interrupted = false; mutex_lock(&dcc->cmd_lock); f2fs_bug_on(sbi, !__check_rb_tree_consistence(sbi, &dcc->root)); blk_start_plug(&plug); - for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { + for (i = MAX_PLIST_NUM - 1; + i >= 0 && plist_issue(dcc->pend_list_tag[i]); i--) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state != D_PREP); - if (!issue_cond || is_idle(sbi)) + /* Hurry up to finish fstrim */ + if (dcc->pend_list_tag[i] & P_TRIM) { + __submit_discard_cmd(sbi, dc); + issued++; + + if (fatal_signal_pending(current)) + break; + continue; + } + + if (!issue_cond) { __submit_discard_cmd(sbi, dc); - if (issue_cond && iter++ > DISCARD_ISSUE_RATE) + issued++; + continue; + } + + if (is_idle(sbi)) { + __submit_discard_cmd(sbi, dc); + issued++; + } else { + io_interrupted = true; + } + + if (++iter >= DISCARD_ISSUE_RATE) goto out; } + if (list_empty(pend_list) && dcc->pend_list_tag[i] & P_TRIM) + dcc->pend_list_tag[i] &= (~P_TRIM); } out: blk_finish_plug(&plug); mutex_unlock(&dcc->cmd_lock); + + if (!issued && io_interrupted) + issued = -1; + + return issued; +} + +static void __drop_discard_cmd(struct f2fs_sb_info *sbi) +{ + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; + struct list_head *pend_list; + struct discard_cmd *dc, *tmp; + int i; + + mutex_lock(&dcc->cmd_lock); + for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { + pend_list = &dcc->pend_list[i]; + list_for_each_entry_safe(dc, tmp, pend_list, list) { + f2fs_bug_on(sbi, dc->state != D_PREP); + __remove_discard_cmd(sbi, dc); + } + } + mutex_unlock(&dcc->cmd_lock); } static void __wait_one_discard_bio(struct f2fs_sb_info *sbi, @@ -1102,34 +1209,63 @@ void stop_discard_thread(struct f2fs_sb_info *sbi) } } -/* This comes from f2fs_put_super */ +/* This comes from f2fs_put_super and f2fs_trim_fs */ void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi) { __issue_discard_cmd(sbi, false); + __drop_discard_cmd(sbi); __wait_discard_cmd(sbi, false); } +static void mark_discard_range_all(struct f2fs_sb_info *sbi) +{ + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; + int i; + + mutex_lock(&dcc->cmd_lock); + for (i = 0; i < MAX_PLIST_NUM; i++) + dcc->pend_list_tag[i] |= P_TRIM; + mutex_unlock(&dcc->cmd_lock); +} + static int issue_discard_thread(void *data) { struct f2fs_sb_info *sbi = data; struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; wait_queue_head_t *q = &dcc->discard_wait_queue; + unsigned int wait_ms = DEF_MIN_DISCARD_ISSUE_TIME; + int issued; set_freezable(); do { - wait_event_interruptible(*q, kthread_should_stop() || - freezing(current) || - atomic_read(&dcc->discard_cmd_cnt)); + wait_event_interruptible_timeout(*q, + kthread_should_stop() || freezing(current) || + dcc->discard_wake, + msecs_to_jiffies(wait_ms)); if (try_to_freeze()) continue; if (kthread_should_stop()) return 0; - __issue_discard_cmd(sbi, true); - __wait_discard_cmd(sbi, true); + if (dcc->discard_wake) { + dcc->discard_wake = 0; + if (sbi->gc_thread && sbi->gc_thread->gc_urgent) + mark_discard_range_all(sbi); + } + + sb_start_intwrite(sbi->sb); + + issued = __issue_discard_cmd(sbi, true); + if (issued) { + __wait_discard_cmd(sbi, true); + wait_ms = DEF_MIN_DISCARD_ISSUE_TIME; + } else { + wait_ms = DEF_MAX_DISCARD_ISSUE_TIME; + } + + sb_end_intwrite(sbi->sb); - congestion_wait(BLK_RW_SYNC, HZ/50); } while (!kthread_should_stop()); return 0; } @@ -1320,7 +1456,8 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi) void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc) { - struct list_head *head = &(SM_I(sbi)->dcc_info->entry_list); + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; + struct list_head *head = &dcc->entry_list; struct discard_entry *entry, *this; struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); unsigned long *prefree_map = dirty_i->dirty_segmap[PRE]; @@ -1402,11 +1539,11 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc) goto find_next; list_del(&entry->list); - SM_I(sbi)->dcc_info->nr_discards -= total_len; + dcc->nr_discards -= total_len; kmem_cache_free(discard_entry_slab, entry); } - wake_up(&SM_I(sbi)->dcc_info->discard_wait_queue); + wake_up_discard_thread(sbi, false); } static int create_discard_cmd_control(struct f2fs_sb_info *sbi) @@ -1424,9 +1561,13 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi) if (!dcc) return -ENOMEM; + dcc->discard_granularity = DEFAULT_DISCARD_GRANULARITY; INIT_LIST_HEAD(&dcc->entry_list); - for (i = 0; i < MAX_PLIST_NUM; i++) + for (i = 0; i < MAX_PLIST_NUM; i++) { INIT_LIST_HEAD(&dcc->pend_list[i]); + if (i >= dcc->discard_granularity - 1) + dcc->pend_list_tag[i] |= P_ACTIVE; + } INIT_LIST_HEAD(&dcc->wait_list); mutex_init(&dcc->cmd_lock); atomic_set(&dcc->issued_discard, 0); @@ -1491,6 +1632,10 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) struct seg_entry *se; unsigned int segno, offset; long int new_vblocks; + bool exist; +#ifdef CONFIG_F2FS_CHECK_FS + bool mir_exist; +#endif segno = GET_SEGNO(sbi, blkaddr); @@ -1507,17 +1652,25 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) /* Update valid block bitmap */ if (del > 0) { - if (f2fs_test_and_set_bit(offset, se->cur_valid_map)) { + exist = f2fs_test_and_set_bit(offset, se->cur_valid_map); #ifdef CONFIG_F2FS_CHECK_FS - if (f2fs_test_and_set_bit(offset, - se->cur_valid_map_mir)) - f2fs_bug_on(sbi, 1); - else - WARN_ON(1); -#else + mir_exist = f2fs_test_and_set_bit(offset, + se->cur_valid_map_mir); + if (unlikely(exist != mir_exist)) { + f2fs_msg(sbi->sb, KERN_ERR, "Inconsistent error " + "when setting bitmap, blk:%u, old bit:%d", + blkaddr, exist); f2fs_bug_on(sbi, 1); + } #endif + if (unlikely(exist)) { + f2fs_msg(sbi->sb, KERN_ERR, + "Bitmap was wrongly set, blk:%u", blkaddr); + f2fs_bug_on(sbi, 1); + se->valid_blocks--; + del = 0; } + if (f2fs_discard_en(sbi) && !f2fs_test_and_set_bit(offset, se->discard_map)) sbi->discard_blks--; @@ -1528,17 +1681,25 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) se->ckpt_valid_blocks++; } } else { - if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) { + exist = f2fs_test_and_clear_bit(offset, se->cur_valid_map); #ifdef CONFIG_F2FS_CHECK_FS - if (!f2fs_test_and_clear_bit(offset, - se->cur_valid_map_mir)) - f2fs_bug_on(sbi, 1); - else - WARN_ON(1); -#else + mir_exist = f2fs_test_and_clear_bit(offset, + se->cur_valid_map_mir); + if (unlikely(exist != mir_exist)) { + f2fs_msg(sbi->sb, KERN_ERR, "Inconsistent error " + "when clearing bitmap, blk:%u, old bit:%d", + blkaddr, exist); f2fs_bug_on(sbi, 1); + } #endif + if (unlikely(!exist)) { + f2fs_msg(sbi->sb, KERN_ERR, + "Bitmap was wrongly cleared, blk:%u", blkaddr); + f2fs_bug_on(sbi, 1); + se->valid_blocks++; + del = 0; } + if (f2fs_discard_en(sbi) && f2fs_test_and_clear_bit(offset, se->discard_map)) sbi->discard_blks++; @@ -1900,7 +2061,7 @@ static void __refresh_next_blkoff(struct f2fs_sb_info *sbi, * This function always allocates a used segment(from dirty seglist) by SSR * manner, so it should recover the existing segment information of valid blocks */ -static void change_curseg(struct f2fs_sb_info *sbi, int type, bool reuse) +static void change_curseg(struct f2fs_sb_info *sbi, int type) { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); struct curseg_info *curseg = CURSEG_I(sbi, type); @@ -1921,12 +2082,10 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type, bool reuse) curseg->alloc_type = SSR; __next_free_blkoff(sbi, curseg, 0); - if (reuse) { - sum_page = get_sum_page(sbi, new_segno); - sum_node = (struct f2fs_summary_block *)page_address(sum_page); - memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE); - f2fs_put_page(sum_page, 1); - } + sum_page = get_sum_page(sbi, new_segno); + sum_node = (struct f2fs_summary_block *)page_address(sum_page); + memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE); + f2fs_put_page(sum_page, 1); } static int get_ssr_segment(struct f2fs_sb_info *sbi, int type) @@ -1990,7 +2149,7 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi, else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type)) new_curseg(sbi, type, false); else if (need_SSR(sbi) && get_ssr_segment(sbi, type)) - change_curseg(sbi, type, true); + change_curseg(sbi, type); else new_curseg(sbi, type, false); @@ -2083,6 +2242,9 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) schedule(); } + /* It's time to issue all the filed discards */ + mark_discard_range_all(sbi); + f2fs_wait_discard_bios(sbi); out: range->len = F2FS_BLK_TO_BYTES(cpc.trimmed); return err; @@ -2202,9 +2364,12 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, mutex_unlock(&sit_i->sentry_lock); - if (page && IS_NODESEG(type)) + if (page && IS_NODESEG(type)) { fill_node_footer_blkaddr(page, NEXT_FREE_BLKADDR(sbi, curseg)); + f2fs_inode_chksum_set(sbi, page); + } + if (add_list) { struct f2fs_bio_info *io; @@ -2236,7 +2401,8 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) } } -void write_meta_page(struct f2fs_sb_info *sbi, struct page *page) +void write_meta_page(struct f2fs_sb_info *sbi, struct page *page, + enum iostat_type io_type) { struct f2fs_io_info fio = { .sbi = sbi, @@ -2255,6 +2421,8 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page) set_page_writeback(page); f2fs_submit_page_write(&fio); + + f2fs_update_iostat(sbi, io_type, F2FS_BLKSIZE); } void write_node_page(unsigned int nid, struct f2fs_io_info *fio) @@ -2263,6 +2431,8 @@ void write_node_page(unsigned int nid, struct f2fs_io_info *fio) set_summary(&sum, nid, 0, 0); do_write_page(&sum, fio); + + f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE); } void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio) @@ -2276,13 +2446,22 @@ void write_data_page(struct dnode_of_data *dn, struct f2fs_io_info *fio) set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); do_write_page(&sum, fio); f2fs_update_data_blkaddr(dn, fio->new_blkaddr); + + f2fs_update_iostat(sbi, fio->io_type, F2FS_BLKSIZE); } int rewrite_data_page(struct f2fs_io_info *fio) { + int err; + fio->new_blkaddr = fio->old_blkaddr; stat_inc_inplace_blocks(fio->sbi); - return f2fs_submit_page_bio(fio); + + err = f2fs_submit_page_bio(fio); + + f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE); + + return err; } void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, @@ -2324,7 +2503,7 @@ void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, /* change the current segment */ if (segno != curseg->segno) { curseg->next_segno = segno; - change_curseg(sbi, type, true); + change_curseg(sbi, type); } curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); @@ -2343,7 +2522,7 @@ void __f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (recover_curseg) { if (old_cursegno != curseg->segno) { curseg->next_segno = old_cursegno; - change_curseg(sbi, type, true); + change_curseg(sbi, type); } curseg->next_blkoff = old_blkoff; } @@ -2382,8 +2561,7 @@ void f2fs_wait_on_page_writeback(struct page *page, } } -void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi, - block_t blkaddr) +void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr) { struct page *cpage; diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 6b871b492fd5cdc7fc81dcad4684b0a0680e4c72..e0a6cc23ace3a66ddcd5975c0e3f5ee14ace3946 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -492,29 +492,11 @@ static inline int overprovision_segments(struct f2fs_sb_info *sbi) return SM_I(sbi)->ovp_segments; } -static inline int overprovision_sections(struct f2fs_sb_info *sbi) -{ - return GET_SEC_FROM_SEG(sbi, (unsigned int)overprovision_segments(sbi)); -} - static inline int reserved_sections(struct f2fs_sb_info *sbi) { return GET_SEC_FROM_SEG(sbi, (unsigned int)reserved_segments(sbi)); } -static inline bool need_SSR(struct f2fs_sb_info *sbi) -{ - int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); - int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); - int imeta_secs = get_blocktype_secs(sbi, F2FS_DIRTY_IMETA); - - if (test_opt(sbi, LFS)) - return false; - - return free_sections(sbi) <= (node_secs + 2 * dent_secs + imeta_secs + - 2 * reserved_sections(sbi)); -} - static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed, int needed) { @@ -577,6 +559,10 @@ static inline bool need_inplace_update_policy(struct inode *inode, if (test_opt(sbi, LFS)) return false; + /* if this is cold file, we should overwrite to avoid fragmentation */ + if (file_is_cold(inode)) + return true; + if (policy & (0x1 << F2FS_IPU_FORCE)) return true; if (policy & (0x1 << F2FS_IPU_SSR) && need_SSR(sbi)) @@ -799,3 +785,28 @@ static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type, wbc->nr_to_write = desired; return desired - nr_to_write; } + +static inline void wake_up_discard_thread(struct f2fs_sb_info *sbi, bool force) +{ + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; + bool wakeup = false; + int i; + + if (force) + goto wake_up; + + mutex_lock(&dcc->cmd_lock); + for (i = MAX_PLIST_NUM - 1; + i >= 0 && plist_issue(dcc->pend_list_tag[i]); i--) { + if (!list_empty(&dcc->pend_list[i])) { + wakeup = true; + break; + } + } + mutex_unlock(&dcc->cmd_lock); + if (!wakeup) + return; +wake_up: + dcc->discard_wake = 1; + wake_up_interruptible_all(&dcc->discard_wait_queue); +} diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 32e4c025e97e556eafdefb887eab06d4217f1ddb..89f61eb3d1671c3c5686a002adca8c0c427abd1c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" @@ -107,8 +108,20 @@ enum { Opt_fault_injection, Opt_lazytime, Opt_nolazytime, + Opt_quota, + Opt_noquota, Opt_usrquota, Opt_grpquota, + Opt_prjquota, + Opt_usrjquota, + Opt_grpjquota, + Opt_prjjquota, + Opt_offusrjquota, + Opt_offgrpjquota, + Opt_offprjjquota, + Opt_jqfmt_vfsold, + Opt_jqfmt_vfsv0, + Opt_jqfmt_vfsv1, Opt_err, }; @@ -144,8 +157,20 @@ static match_table_t f2fs_tokens = { {Opt_fault_injection, "fault_injection=%u"}, {Opt_lazytime, "lazytime"}, {Opt_nolazytime, "nolazytime"}, + {Opt_quota, "quota"}, + {Opt_noquota, "noquota"}, {Opt_usrquota, "usrquota"}, {Opt_grpquota, "grpquota"}, + {Opt_prjquota, "prjquota"}, + {Opt_usrjquota, "usrjquota=%s"}, + {Opt_grpjquota, "grpjquota=%s"}, + {Opt_prjjquota, "prjjquota=%s"}, + {Opt_offusrjquota, "usrjquota="}, + {Opt_offgrpjquota, "grpjquota="}, + {Opt_offprjjquota, "prjjquota="}, + {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, + {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, + {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"}, {Opt_err, NULL}, }; @@ -157,7 +182,7 @@ void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...) va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; - printk("%sF2FS-fs (%s): %pV\n", level, sb->s_id, &vaf); + printk_ratelimited("%sF2FS-fs (%s): %pV\n", level, sb->s_id, &vaf); va_end(args); } @@ -168,6 +193,104 @@ static void init_once(void *foo) inode_init_once(&fi->vfs_inode); } +#ifdef CONFIG_QUOTA +static const char * const quotatypes[] = INITQFNAMES; +#define QTYPE2NAME(t) (quotatypes[t]) +static int f2fs_set_qf_name(struct super_block *sb, int qtype, + substring_t *args) +{ + struct f2fs_sb_info *sbi = F2FS_SB(sb); + char *qname; + int ret = -EINVAL; + + if (sb_any_quota_loaded(sb) && !sbi->s_qf_names[qtype]) { + f2fs_msg(sb, KERN_ERR, + "Cannot change journaled " + "quota options when quota turned on"); + return -EINVAL; + } + qname = match_strdup(args); + if (!qname) { + f2fs_msg(sb, KERN_ERR, + "Not enough memory for storing quotafile name"); + return -EINVAL; + } + if (sbi->s_qf_names[qtype]) { + if (strcmp(sbi->s_qf_names[qtype], qname) == 0) + ret = 0; + else + f2fs_msg(sb, KERN_ERR, + "%s quota file already specified", + QTYPE2NAME(qtype)); + goto errout; + } + if (strchr(qname, '/')) { + f2fs_msg(sb, KERN_ERR, + "quotafile must be on filesystem root"); + goto errout; + } + sbi->s_qf_names[qtype] = qname; + set_opt(sbi, QUOTA); + return 0; +errout: + kfree(qname); + return ret; +} + +static int f2fs_clear_qf_name(struct super_block *sb, int qtype) +{ + struct f2fs_sb_info *sbi = F2FS_SB(sb); + + if (sb_any_quota_loaded(sb) && sbi->s_qf_names[qtype]) { + f2fs_msg(sb, KERN_ERR, "Cannot change journaled quota options" + " when quota turned on"); + return -EINVAL; + } + kfree(sbi->s_qf_names[qtype]); + sbi->s_qf_names[qtype] = NULL; + return 0; +} + +static int f2fs_check_quota_options(struct f2fs_sb_info *sbi) +{ + /* + * We do the test below only for project quotas. 'usrquota' and + * 'grpquota' mount options are allowed even without quota feature + * to support legacy quotas in quota files. + */ + if (test_opt(sbi, PRJQUOTA) && !f2fs_sb_has_project_quota(sbi->sb)) { + f2fs_msg(sbi->sb, KERN_ERR, "Project quota feature not enabled. " + "Cannot enable project quota enforcement."); + return -1; + } + if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA] || + sbi->s_qf_names[PRJQUOTA]) { + if (test_opt(sbi, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) + clear_opt(sbi, USRQUOTA); + + if (test_opt(sbi, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) + clear_opt(sbi, GRPQUOTA); + + if (test_opt(sbi, PRJQUOTA) && sbi->s_qf_names[PRJQUOTA]) + clear_opt(sbi, PRJQUOTA); + + if (test_opt(sbi, GRPQUOTA) || test_opt(sbi, USRQUOTA) || + test_opt(sbi, PRJQUOTA)) { + f2fs_msg(sbi->sb, KERN_ERR, "old and new quota " + "format mixing"); + return -1; + } + + if (!sbi->s_jquota_fmt) { + f2fs_msg(sbi->sb, KERN_ERR, "journaled quota format " + "not specified"); + return -1; + } + } + return 0; +} +#endif + static int parse_options(struct super_block *sb, char *options) { struct f2fs_sb_info *sbi = F2FS_SB(sb); @@ -175,6 +298,9 @@ static int parse_options(struct super_block *sb, char *options) substring_t args[MAX_OPT_ARGS]; char *p, *name; int arg = 0; +#ifdef CONFIG_QUOTA + int ret; +#endif if (!options) return 0; @@ -386,15 +512,76 @@ static int parse_options(struct super_block *sb, char *options) sb->s_flags &= ~MS_LAZYTIME; break; #ifdef CONFIG_QUOTA + case Opt_quota: case Opt_usrquota: set_opt(sbi, USRQUOTA); break; case Opt_grpquota: set_opt(sbi, GRPQUOTA); break; + case Opt_prjquota: + set_opt(sbi, PRJQUOTA); + break; + case Opt_usrjquota: + ret = f2fs_set_qf_name(sb, USRQUOTA, &args[0]); + if (ret) + return ret; + break; + case Opt_grpjquota: + ret = f2fs_set_qf_name(sb, GRPQUOTA, &args[0]); + if (ret) + return ret; + break; + case Opt_prjjquota: + ret = f2fs_set_qf_name(sb, PRJQUOTA, &args[0]); + if (ret) + return ret; + break; + case Opt_offusrjquota: + ret = f2fs_clear_qf_name(sb, USRQUOTA); + if (ret) + return ret; + break; + case Opt_offgrpjquota: + ret = f2fs_clear_qf_name(sb, GRPQUOTA); + if (ret) + return ret; + break; + case Opt_offprjjquota: + ret = f2fs_clear_qf_name(sb, PRJQUOTA); + if (ret) + return ret; + break; + case Opt_jqfmt_vfsold: + sbi->s_jquota_fmt = QFMT_VFS_OLD; + break; + case Opt_jqfmt_vfsv0: + sbi->s_jquota_fmt = QFMT_VFS_V0; + break; + case Opt_jqfmt_vfsv1: + sbi->s_jquota_fmt = QFMT_VFS_V1; + break; + case Opt_noquota: + clear_opt(sbi, QUOTA); + clear_opt(sbi, USRQUOTA); + clear_opt(sbi, GRPQUOTA); + clear_opt(sbi, PRJQUOTA); + break; #else + case Opt_quota: case Opt_usrquota: case Opt_grpquota: + case Opt_prjquota: + case Opt_usrjquota: + case Opt_grpjquota: + case Opt_prjjquota: + case Opt_offusrjquota: + case Opt_offgrpjquota: + case Opt_offprjjquota: + case Opt_jqfmt_vfsold: + case Opt_jqfmt_vfsv0: + case Opt_jqfmt_vfsv1: + case Opt_noquota: f2fs_msg(sb, KERN_INFO, "quota operations not supported"); break; @@ -406,6 +593,10 @@ static int parse_options(struct super_block *sb, char *options) return -EINVAL; } } +#ifdef CONFIG_QUOTA + if (f2fs_check_quota_options(sbi)) + return -EINVAL; +#endif if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) { f2fs_msg(sb, KERN_ERR, @@ -439,6 +630,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) init_rwsem(&fi->dio_rwsem[READ]); init_rwsem(&fi->dio_rwsem[WRITE]); init_rwsem(&fi->i_mmap_sem); + init_rwsem(&fi->i_xattr_sem); #ifdef CONFIG_QUOTA memset(&fi->i_dquot, 0, sizeof(fi->i_dquot)); @@ -446,6 +638,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) #endif /* Will be used by directory only */ fi->i_dir_level = F2FS_SB(sb)->dir_level; + return &fi->vfs_inode; } @@ -584,7 +777,6 @@ static void destroy_device_list(struct f2fs_sb_info *sbi) kfree(sbi->devs); } -static void f2fs_quota_off_umount(struct super_block *sb); static void f2fs_put_super(struct super_block *sb) { struct f2fs_sb_info *sbi = F2FS_SB(sb); @@ -642,7 +834,7 @@ static void f2fs_put_super(struct super_block *sb) kfree(sbi->ckpt); - f2fs_exit_sysfs(sbi); + f2fs_unregister_sysfs(sbi); sb->s_fs_info = NULL; if (sbi->s_chksum_driver) @@ -651,6 +843,10 @@ static void f2fs_put_super(struct super_block *sb) destroy_device_list(sbi); mempool_destroy(sbi->write_io_dummy); +#ifdef CONFIG_QUOTA + for (i = 0; i < MAXQUOTAS; i++) + kfree(sbi->s_qf_names[i]); +#endif destroy_percpu_info(sbi); for (i = 0; i < NR_PAGE_TYPE; i++) kfree(sbi->write_io[i]); @@ -664,6 +860,9 @@ int f2fs_sync_fs(struct super_block *sb, int sync) trace_f2fs_sync_fs(sb, sync); + if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) + return -EAGAIN; + if (sync) { struct cp_control cpc; @@ -698,6 +897,48 @@ static int f2fs_unfreeze(struct super_block *sb) return 0; } +#ifdef CONFIG_QUOTA +static int f2fs_statfs_project(struct super_block *sb, + kprojid_t projid, struct kstatfs *buf) +{ + struct kqid qid; + struct dquot *dquot; + u64 limit; + u64 curblock; + + qid = make_kqid_projid(projid); + dquot = dqget(sb, qid); + if (IS_ERR(dquot)) + return PTR_ERR(dquot); + spin_lock(&dq_data_lock); + + limit = (dquot->dq_dqb.dqb_bsoftlimit ? + dquot->dq_dqb.dqb_bsoftlimit : + dquot->dq_dqb.dqb_bhardlimit) >> sb->s_blocksize_bits; + if (limit && buf->f_blocks > limit) { + curblock = dquot->dq_dqb.dqb_curspace >> sb->s_blocksize_bits; + buf->f_blocks = limit; + buf->f_bfree = buf->f_bavail = + (buf->f_blocks > curblock) ? + (buf->f_blocks - curblock) : 0; + } + + limit = dquot->dq_dqb.dqb_isoftlimit ? + dquot->dq_dqb.dqb_isoftlimit : + dquot->dq_dqb.dqb_ihardlimit; + if (limit && buf->f_files > limit) { + buf->f_files = limit; + buf->f_ffree = + (buf->f_files > dquot->dq_dqb.dqb_curinodes) ? + (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; + } + + spin_unlock(&dq_data_lock); + dqput(dquot); + return 0; +} +#endif + static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; @@ -733,9 +974,49 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); +#ifdef CONFIG_QUOTA + if (is_inode_flag_set(dentry->d_inode, FI_PROJ_INHERIT) && + sb_has_quota_limits_enabled(sb, PRJQUOTA)) { + f2fs_statfs_project(sb, F2FS_I(dentry->d_inode)->i_projid, buf); + } +#endif return 0; } +static inline void f2fs_show_quota_options(struct seq_file *seq, + struct super_block *sb) +{ +#ifdef CONFIG_QUOTA + struct f2fs_sb_info *sbi = F2FS_SB(sb); + + if (sbi->s_jquota_fmt) { + char *fmtname = ""; + + switch (sbi->s_jquota_fmt) { + case QFMT_VFS_OLD: + fmtname = "vfsold"; + break; + case QFMT_VFS_V0: + fmtname = "vfsv0"; + break; + case QFMT_VFS_V1: + fmtname = "vfsv1"; + break; + } + seq_printf(seq, ",jqfmt=%s", fmtname); + } + + if (sbi->s_qf_names[USRQUOTA]) + seq_show_option(seq, "usrjquota", sbi->s_qf_names[USRQUOTA]); + + if (sbi->s_qf_names[GRPQUOTA]) + seq_show_option(seq, "grpjquota", sbi->s_qf_names[GRPQUOTA]); + + if (sbi->s_qf_names[PRJQUOTA]) + seq_show_option(seq, "prjjquota", sbi->s_qf_names[PRJQUOTA]); +#endif +} + static int f2fs_show_options(struct seq_file *seq, struct dentry *root) { struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb); @@ -809,11 +1090,16 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) sbi->fault_info.inject_rate); #endif #ifdef CONFIG_QUOTA + if (test_opt(sbi, QUOTA)) + seq_puts(seq, ",quota"); if (test_opt(sbi, USRQUOTA)) seq_puts(seq, ",usrquota"); if (test_opt(sbi, GRPQUOTA)) seq_puts(seq, ",grpquota"); + if (test_opt(sbi, PRJQUOTA)) + seq_puts(seq, ",prjquota"); #endif + f2fs_show_quota_options(seq, sbi->sb); return 0; } @@ -862,6 +1148,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) #ifdef CONFIG_F2FS_FAULT_INJECTION struct f2fs_fault_info ffi = sbi->fault_info; #endif +#ifdef CONFIG_QUOTA + int s_jquota_fmt; + char *s_qf_names[MAXQUOTAS]; + int i, j; +#endif /* * Save the old mount options in case we @@ -871,6 +1162,23 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) old_sb_flags = sb->s_flags; active_logs = sbi->active_logs; +#ifdef CONFIG_QUOTA + s_jquota_fmt = sbi->s_jquota_fmt; + for (i = 0; i < MAXQUOTAS; i++) { + if (sbi->s_qf_names[i]) { + s_qf_names[i] = kstrdup(sbi->s_qf_names[i], + GFP_KERNEL); + if (!s_qf_names[i]) { + for (j = 0; j < i; j++) + kfree(s_qf_names[j]); + return -ENOMEM; + } + } else { + s_qf_names[i] = NULL; + } + } +#endif + /* recover superblocks we couldn't write due to previous RO mount */ if (!(*flags & MS_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) { err = f2fs_commit_super(sbi, false); @@ -952,6 +1260,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) goto restore_gc; } skip: +#ifdef CONFIG_QUOTA + /* Release old quota file names */ + for (i = 0; i < MAXQUOTAS; i++) + kfree(s_qf_names[i]); +#endif /* Update the POSIXACL Flag */ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0); @@ -966,6 +1279,13 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) stop_gc_thread(sbi); } restore_opts: +#ifdef CONFIG_QUOTA + sbi->s_jquota_fmt = s_jquota_fmt; + for (i = 0; i < MAXQUOTAS; i++) { + kfree(sbi->s_qf_names[i]); + sbi->s_qf_names[i] = s_qf_names[i]; + } +#endif sbi->mount_opt = org_mount_opt; sbi->active_logs = active_logs; sb->s_flags = old_sb_flags; @@ -1065,7 +1385,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, } if (len == towrite) - return err; + return 0; inode->i_version++; inode->i_mtime = inode->i_ctime = current_time(inode); f2fs_mark_inode_dirty_sync(inode, false); @@ -1082,6 +1402,27 @@ static qsize_t *f2fs_get_reserved_space(struct inode *inode) return &F2FS_I(inode)->i_reserved_quota; } +static int f2fs_quota_on_mount(struct f2fs_sb_info *sbi, int type) +{ + return dquot_quota_on_mount(sbi->sb, sbi->s_qf_names[type], + sbi->s_jquota_fmt, type); +} + +void f2fs_enable_quota_files(struct f2fs_sb_info *sbi) +{ + int i, ret; + + for (i = 0; i < MAXQUOTAS; i++) { + if (sbi->s_qf_names[i]) { + ret = f2fs_quota_on_mount(sbi, i); + if (ret < 0) + f2fs_msg(sbi->sb, KERN_ERR, + "Cannot turn on journaled " + "quota: error %d", ret); + } + } +} + static int f2fs_quota_sync(struct super_block *sb, int type) { struct quota_info *dqopt = sb_dqopt(sb); @@ -1119,7 +1460,7 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id, struct inode *inode; int err; - err = f2fs_quota_sync(sb, -1); + err = f2fs_quota_sync(sb, type); if (err) return err; @@ -1147,7 +1488,7 @@ static int f2fs_quota_off(struct super_block *sb, int type) if (!inode || !igrab(inode)) return dquot_quota_off(sb, type); - f2fs_quota_sync(sb, -1); + f2fs_quota_sync(sb, type); err = dquot_quota_off(sb, type); if (err) @@ -1163,7 +1504,7 @@ static int f2fs_quota_off(struct super_block *sb, int type) return err; } -static void f2fs_quota_off_umount(struct super_block *sb) +void f2fs_quota_off_umount(struct super_block *sb) { int type; @@ -1171,6 +1512,12 @@ static void f2fs_quota_off_umount(struct super_block *sb) f2fs_quota_off(sb, type); } +int f2fs_get_projid(struct inode *inode, kprojid_t *projid) +{ + *projid = F2FS_I(inode)->i_projid; + return 0; +} + static const struct dquot_operations f2fs_quota_operations = { .get_reserved_space = f2fs_get_reserved_space, .write_dquot = dquot_commit, @@ -1180,6 +1527,7 @@ static const struct dquot_operations f2fs_quota_operations = { .write_info = dquot_commit_info, .alloc_dquot = dquot_alloc, .destroy_dquot = dquot_destroy, + .get_projid = f2fs_get_projid, .get_next_id = dquot_get_next_id, }; @@ -1194,12 +1542,12 @@ static const struct quotactl_ops f2fs_quotactl_ops = { .get_nextdqblk = dquot_get_next_dqblk, }; #else -static inline void f2fs_quota_off_umount(struct super_block *sb) +void f2fs_quota_off_umount(struct super_block *sb) { } #endif -static struct super_operations f2fs_sops = { +static const struct super_operations f2fs_sops = { .alloc_inode = f2fs_alloc_inode, .drop_inode = f2fs_drop_inode, .destroy_inode = f2fs_destroy_inode, @@ -1303,9 +1651,16 @@ static const struct export_operations f2fs_export_ops = { static loff_t max_file_blocks(void) { - loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS); + loff_t result = 0; loff_t leaf_count = ADDRS_PER_BLOCK; + /* + * note: previously, result is equal to (DEF_ADDRS_PER_INODE - + * F2FS_INLINE_XATTR_ADDRS), but now f2fs try to reserve more + * space in inode.i_addr, it will be more safe to reassign + * result as zero. + */ + /* two direct node blocks */ result += (leaf_count * 2); @@ -1922,6 +2277,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) sb->s_fs_info = sbi; sbi->raw_super = raw_super; + /* precompute checksum seed for metadata */ + if (f2fs_sb_has_inode_chksum(sb)) + sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid, + sizeof(raw_super->uuid)); + /* * The BLKZONED feature indicates that the drive was formatted with * zone alignment optimization. This is optional for host-aware @@ -1956,7 +2316,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) #ifdef CONFIG_QUOTA sb->dq_op = &f2fs_quota_operations; sb->s_qcop = &f2fs_quotactl_ops; - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; #endif sb->s_op = &f2fs_sops; @@ -1980,6 +2340,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) set_sbi_flag(sbi, SBI_POR_DOING); spin_lock_init(&sbi->stat_lock); + /* init iostat info */ + spin_lock_init(&sbi->iostat_lock); + sbi->iostat_enable = false; + for (i = 0; i < NR_PAGE_TYPE; i++) { int n = (i == META) ? 1: NR_TEMP_TYPE; int j; @@ -2098,11 +2462,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) if (err) goto free_nm; - /* if there are nt orphan nodes free them */ - err = recover_orphan_inodes(sbi); - if (err) - goto free_node_inode; - /* read root inode and dentry */ root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); if (IS_ERR(root)) { @@ -2122,10 +2481,15 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_root_inode; } - err = f2fs_init_sysfs(sbi); + err = f2fs_register_sysfs(sbi); if (err) goto free_root_inode; + /* if there are nt orphan nodes free them */ + err = recover_orphan_inodes(sbi); + if (err) + goto free_sysfs; + /* recover fsynced data */ if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { /* @@ -2135,7 +2499,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) if (bdev_read_only(sb->s_bdev) && !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { err = -EROFS; - goto free_sysfs; + goto free_meta; } if (need_fsck) @@ -2149,7 +2513,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) need_fsck = true; f2fs_msg(sb, KERN_ERR, "Cannot recover all fsync data errno=%d", err); - goto free_sysfs; + goto free_meta; } } else { err = recover_fsync_data(sbi, true); @@ -2173,7 +2537,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* After POR, we can run background GC thread.*/ err = start_gc_thread(sbi); if (err) - goto free_sysfs; + goto free_meta; } kfree(options); @@ -2191,9 +2555,17 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) f2fs_update_time(sbi, REQ_TIME); return 0; -free_sysfs: +free_meta: f2fs_sync_inode_meta(sbi); - f2fs_exit_sysfs(sbi); + /* + * Some dirty meta pages can be produced by recover_orphan_inodes() + * failed by EIO. Then, iput(node_inode) can trigger balance_fs_bg() + * followed by write_checkpoint() through f2fs_write_node_pages(), which + * falls into an infinite loop in sync_meta_pages(). + */ + truncate_inode_pages_final(META_MAPPING(sbi)); +free_sysfs: + f2fs_unregister_sysfs(sbi); free_root_inode: dput(sb->s_root); sb->s_root = NULL; @@ -2202,13 +2574,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) mutex_lock(&sbi->umount_mutex); release_ino_entry(sbi, true); f2fs_leave_shrinker(sbi); - /* - * Some dirty meta pages can be produced by recover_orphan_inodes() - * failed by EIO. Then, iput(node_inode) can trigger balance_fs_bg() - * followed by write_checkpoint() through f2fs_write_node_pages(), which - * falls into an infinite loop in sync_meta_pages(). - */ - truncate_inode_pages_final(META_MAPPING(sbi)); iput(sbi->node_inode); mutex_unlock(&sbi->umount_mutex); f2fs_destroy_stats(sbi); @@ -2228,6 +2593,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) for (i = 0; i < NR_PAGE_TYPE; i++) kfree(sbi->write_io[i]); destroy_percpu_info(sbi); +#ifdef CONFIG_QUOTA + for (i = 0; i < MAXQUOTAS; i++) + kfree(sbi->s_qf_names[i]); +#endif kfree(options); free_sb_buf: kfree(raw_super); @@ -2311,7 +2680,7 @@ static int __init init_f2fs_fs(void) err = create_extent_cache(); if (err) goto free_checkpoint_caches; - err = f2fs_register_sysfs(); + err = f2fs_init_sysfs(); if (err) goto free_extent_cache; err = register_shrinker(&f2fs_shrinker_info); @@ -2330,7 +2699,7 @@ static int __init init_f2fs_fs(void) free_shrinker: unregister_shrinker(&f2fs_shrinker_info); free_sysfs: - f2fs_unregister_sysfs(); + f2fs_exit_sysfs(); free_extent_cache: destroy_extent_cache(); free_checkpoint_caches: @@ -2350,7 +2719,7 @@ static void __exit exit_f2fs_fs(void) f2fs_destroy_root_stats(); unregister_filesystem(&f2fs_fs_type); unregister_shrinker(&f2fs_shrinker_info); - f2fs_unregister_sysfs(); + f2fs_exit_sysfs(); destroy_extent_cache(); destroy_checkpoint_caches(); destroy_segment_manager_caches(); diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 71191d89917d8c1aa78dcedc36a71307a878d96b..e2c258f717cd11214eb9fe9dd7f4bb202ccd6bc4 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -18,7 +18,6 @@ #include "gc.h" static struct proc_dir_entry *f2fs_proc_root; -static struct kset *f2fs_kset; /* Sysfs support for f2fs */ enum { @@ -41,6 +40,7 @@ struct f2fs_attr { const char *, size_t); int struct_type; int offset; + int id; }; static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) @@ -76,6 +76,34 @@ static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, BD_PART_WRITTEN(sbi))); } +static ssize_t features_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + struct super_block *sb = sbi->sb; + int len = 0; + + if (!sb->s_bdev->bd_part) + return snprintf(buf, PAGE_SIZE, "0\n"); + + if (f2fs_sb_has_crypto(sb)) + len += snprintf(buf, PAGE_SIZE - len, "%s", + "encryption"); + if (f2fs_sb_mounted_blkzoned(sb)) + len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "blkzoned"); + if (f2fs_sb_has_extra_attr(sb)) + len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "extra_attr"); + if (f2fs_sb_has_project_quota(sb)) + len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "projquota"); + if (f2fs_sb_has_inode_chksum(sb)) + len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "inode_checksum"); + len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + return len; +} + static ssize_t f2fs_sbi_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { @@ -124,7 +152,39 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a, spin_unlock(&sbi->stat_lock); return count; } + + if (!strcmp(a->attr.name, "discard_granularity")) { + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; + int i; + + if (t == 0 || t > MAX_PLIST_NUM) + return -EINVAL; + if (t == *ui) + return count; + + mutex_lock(&dcc->cmd_lock); + for (i = 0; i < MAX_PLIST_NUM; i++) { + if (i >= t - 1) + dcc->pend_list_tag[i] |= P_ACTIVE; + else + dcc->pend_list_tag[i] &= (~P_ACTIVE); + } + mutex_unlock(&dcc->cmd_lock); + + *ui = t; + return count; + } + *ui = t; + + if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0) + f2fs_reset_iostat(sbi); + if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) { + sbi->gc_thread->gc_wake = 1; + wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head); + wake_up_discard_thread(sbi, true); + } + return count; } @@ -155,6 +215,30 @@ static void f2fs_sb_release(struct kobject *kobj) complete(&sbi->s_kobj_unregister); } +enum feat_id { + FEAT_CRYPTO = 0, + FEAT_BLKZONED, + FEAT_ATOMIC_WRITE, + FEAT_EXTRA_ATTR, + FEAT_PROJECT_QUOTA, + FEAT_INODE_CHECKSUM, +}; + +static ssize_t f2fs_feature_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + switch (a->id) { + case FEAT_CRYPTO: + case FEAT_BLKZONED: + case FEAT_ATOMIC_WRITE: + case FEAT_EXTRA_ATTR: + case FEAT_PROJECT_QUOTA: + case FEAT_INODE_CHECKSUM: + return snprintf(buf, PAGE_SIZE, "supported\n"); + } + return 0; +} + #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ @@ -172,12 +256,23 @@ static struct f2fs_attr f2fs_attr_##_name = { \ #define F2FS_GENERAL_RO_ATTR(name) \ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) +#define F2FS_FEATURE_RO_ATTR(_name, _id) \ +static struct f2fs_attr f2fs_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0444 }, \ + .show = f2fs_feature_show, \ + .id = _id, \ +} + +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time, + urgent_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards); +F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity); F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); @@ -191,20 +286,36 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable); #ifdef CONFIG_F2FS_FAULT_INJECTION F2FS_RW_ATTR(FAULT_INFO_RATE, f2fs_fault_info, inject_rate, inject_rate); F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); #endif F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes); +F2FS_GENERAL_RO_ATTR(features); + +#ifdef CONFIG_F2FS_FS_ENCRYPTION +F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); +#endif +#ifdef CONFIG_BLK_DEV_ZONED +F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); +#endif +F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); +F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); +F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); +F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { + ATTR_LIST(gc_urgent_sleep_time), ATTR_LIST(gc_min_sleep_time), ATTR_LIST(gc_max_sleep_time), ATTR_LIST(gc_no_gc_sleep_time), ATTR_LIST(gc_idle), + ATTR_LIST(gc_urgent), ATTR_LIST(reclaim_segments), ATTR_LIST(max_small_discards), + ATTR_LIST(discard_granularity), ATTR_LIST(batched_trim_sections), ATTR_LIST(ipu_policy), ATTR_LIST(min_ipu_util), @@ -217,26 +328,59 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(dirty_nats_ratio), ATTR_LIST(cp_interval), ATTR_LIST(idle_interval), + ATTR_LIST(iostat_enable), #ifdef CONFIG_F2FS_FAULT_INJECTION ATTR_LIST(inject_rate), ATTR_LIST(inject_type), #endif ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(features), ATTR_LIST(reserved_blocks), NULL, }; +static struct attribute *f2fs_feat_attrs[] = { +#ifdef CONFIG_F2FS_FS_ENCRYPTION + ATTR_LIST(encryption), +#endif +#ifdef CONFIG_BLK_DEV_ZONED + ATTR_LIST(block_zoned), +#endif + ATTR_LIST(atomic_write), + ATTR_LIST(extra_attr), + ATTR_LIST(project_quota), + ATTR_LIST(inode_checksum), + NULL, +}; + static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, }; -static struct kobj_type f2fs_ktype = { +static struct kobj_type f2fs_sb_ktype = { .default_attrs = f2fs_attrs, .sysfs_ops = &f2fs_attr_ops, .release = f2fs_sb_release, }; +static struct kobj_type f2fs_ktype = { + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kset f2fs_kset = { + .kobj = {.ktype = &f2fs_ktype}, +}; + +static struct kobj_type f2fs_feat_ktype = { + .default_attrs = f2fs_feat_attrs, + .sysfs_ops = &f2fs_attr_ops, +}; + +static struct kobject f2fs_feat = { + .kset = &f2fs_kset, +}; + static int segment_info_seq_show(struct seq_file *seq, void *offset) { struct super_block *sb = seq->private; @@ -288,6 +432,48 @@ static int segment_bits_seq_show(struct seq_file *seq, void *offset) return 0; } +static int iostat_info_seq_show(struct seq_file *seq, void *offset) +{ + struct super_block *sb = seq->private; + struct f2fs_sb_info *sbi = F2FS_SB(sb); + time64_t now = ktime_get_real_seconds(); + + if (!sbi->iostat_enable) + return 0; + + seq_printf(seq, "time: %-16llu\n", now); + + /* print app IOs */ + seq_printf(seq, "app buffered: %-16llu\n", + sbi->write_iostat[APP_BUFFERED_IO]); + seq_printf(seq, "app direct: %-16llu\n", + sbi->write_iostat[APP_DIRECT_IO]); + seq_printf(seq, "app mapped: %-16llu\n", + sbi->write_iostat[APP_MAPPED_IO]); + + /* print fs IOs */ + seq_printf(seq, "fs data: %-16llu\n", + sbi->write_iostat[FS_DATA_IO]); + seq_printf(seq, "fs node: %-16llu\n", + sbi->write_iostat[FS_NODE_IO]); + seq_printf(seq, "fs meta: %-16llu\n", + sbi->write_iostat[FS_META_IO]); + seq_printf(seq, "fs gc data: %-16llu\n", + sbi->write_iostat[FS_GC_DATA_IO]); + seq_printf(seq, "fs gc node: %-16llu\n", + sbi->write_iostat[FS_GC_NODE_IO]); + seq_printf(seq, "fs cp data: %-16llu\n", + sbi->write_iostat[FS_CP_DATA_IO]); + seq_printf(seq, "fs cp node: %-16llu\n", + sbi->write_iostat[FS_CP_NODE_IO]); + seq_printf(seq, "fs cp meta: %-16llu\n", + sbi->write_iostat[FS_CP_META_IO]); + seq_printf(seq, "fs discard: %-16llu\n", + sbi->write_iostat[FS_DISCARD]); + + return 0; +} + #define F2FS_PROC_FILE_DEF(_name) \ static int _name##_open_fs(struct inode *inode, struct file *file) \ { \ @@ -303,28 +489,47 @@ static const struct file_operations f2fs_seq_##_name##_fops = { \ F2FS_PROC_FILE_DEF(segment_info); F2FS_PROC_FILE_DEF(segment_bits); +F2FS_PROC_FILE_DEF(iostat_info); -int __init f2fs_register_sysfs(void) +int __init f2fs_init_sysfs(void) { - f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); + int ret; - f2fs_kset = kset_create_and_add("f2fs", NULL, fs_kobj); - if (!f2fs_kset) - return -ENOMEM; - return 0; + kobject_set_name(&f2fs_kset.kobj, "f2fs"); + f2fs_kset.kobj.parent = fs_kobj; + ret = kset_register(&f2fs_kset); + if (ret) + return ret; + + ret = kobject_init_and_add(&f2fs_feat, &f2fs_feat_ktype, + NULL, "features"); + if (ret) + kset_unregister(&f2fs_kset); + else + f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); + return ret; } -void f2fs_unregister_sysfs(void) +void f2fs_exit_sysfs(void) { - kset_unregister(f2fs_kset); + kobject_put(&f2fs_feat); + kset_unregister(&f2fs_kset); remove_proc_entry("fs/f2fs", NULL); + f2fs_proc_root = NULL; } -int f2fs_init_sysfs(struct f2fs_sb_info *sbi) +int f2fs_register_sysfs(struct f2fs_sb_info *sbi) { struct super_block *sb = sbi->sb; int err; + sbi->s_kobj.kset = &f2fs_kset; + init_completion(&sbi->s_kobj_unregister); + err = kobject_init_and_add(&sbi->s_kobj, &f2fs_sb_ktype, NULL, + "%s", sb->s_id); + if (err) + return err; + if (f2fs_proc_root) sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); @@ -333,33 +538,19 @@ int f2fs_init_sysfs(struct f2fs_sb_info *sbi) &f2fs_seq_segment_info_fops, sb); proc_create_data("segment_bits", S_IRUGO, sbi->s_proc, &f2fs_seq_segment_bits_fops, sb); + proc_create_data("iostat_info", S_IRUGO, sbi->s_proc, + &f2fs_seq_iostat_info_fops, sb); } - - sbi->s_kobj.kset = f2fs_kset; - init_completion(&sbi->s_kobj_unregister); - err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL, - "%s", sb->s_id); - if (err) - goto err_out; return 0; -err_out: - if (sbi->s_proc) { - remove_proc_entry("segment_info", sbi->s_proc); - remove_proc_entry("segment_bits", sbi->s_proc); - remove_proc_entry(sb->s_id, f2fs_proc_root); - } - return err; } -void f2fs_exit_sysfs(struct f2fs_sb_info *sbi) +void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) { - kobject_del(&sbi->s_kobj); - kobject_put(&sbi->s_kobj); - wait_for_completion(&sbi->s_kobj_unregister); - if (sbi->s_proc) { + remove_proc_entry("iostat_info", sbi->s_proc); remove_proc_entry("segment_info", sbi->s_proc); remove_proc_entry("segment_bits", sbi->s_proc); remove_proc_entry(sbi->sb->s_id, f2fs_proc_root); } + kobject_del(&sbi->s_kobj); } diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 832c5110abab51208e77751056436e7ba7e7ff16..7c65540148f8b1b787c54e8eaff3a6813f4a5f9e 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -442,7 +442,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize, } else { struct dnode_of_data dn; set_new_dnode(&dn, inode, NULL, NULL, new_nid); - xpage = new_node_page(&dn, XATTR_NODE_OFFSET, ipage); + xpage = new_node_page(&dn, XATTR_NODE_OFFSET); if (IS_ERR(xpage)) { alloc_nid_failed(sbi, new_nid); return PTR_ERR(xpage); @@ -473,8 +473,10 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, if (len > F2FS_NAME_LEN) return -ERANGE; + down_read(&F2FS_I(inode)->i_xattr_sem); error = lookup_all_xattrs(inode, ipage, index, len, name, &entry, &base_addr); + up_read(&F2FS_I(inode)->i_xattr_sem); if (error) return error; @@ -503,7 +505,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) int error = 0; size_t rest = buffer_size; + down_read(&F2FS_I(inode)->i_xattr_sem); error = read_all_xattrs(inode, NULL, &base_addr); + up_read(&F2FS_I(inode)->i_xattr_sem); if (error) return error; @@ -686,7 +690,9 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, f2fs_lock_op(sbi); /* protect xattr_ver */ down_write(&F2FS_I(inode)->i_sem); + down_write(&F2FS_I(inode)->i_xattr_sem); err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags); + up_write(&F2FS_I(inode)->i_xattr_sem); up_write(&F2FS_I(inode)->i_sem); f2fs_unlock_op(sbi); diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 1d9a8c4e9de05827496ee5ce49b66b83a9422bfe..48b2336692f9f70a3d8c230ee3a9169af5e634be 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -309,7 +309,7 @@ static void mark_fsinfo_dirty(struct super_block *sb) { struct msdos_sb_info *sbi = MSDOS_SB(sb); - if (sb->s_flags & MS_RDONLY || sbi->fat_bits != 32) + if (sb_rdonly(sb) || sbi->fat_bits != 32) return; __mark_inode_dirty(sbi->fsinfo_inode, I_DIRTY_SYNC); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index a2c05f2ada6dd86576df1dede141c05248126187..30c52394a7adbc4041c5331d1c10dd9b52ee4bec 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -657,7 +657,7 @@ static void fat_set_state(struct super_block *sb, struct msdos_sb_info *sbi = MSDOS_SB(sb); /* do not change any thing if mounted read only */ - if ((sb->s_flags & MS_RDONLY) && !force) + if (sb_rdonly(sb) && !force) return; /* do not change state if fs was dirty */ @@ -787,7 +787,7 @@ static int fat_remount(struct super_block *sb, int *flags, char *data) /* make sure we update state on remount. */ new_rdonly = *flags & MS_RDONLY; - if (new_rdonly != (sb->s_flags & MS_RDONLY)) { + if (new_rdonly != sb_rdonly(sb)) { if (new_rdonly) fat_set_state(sb, 0, 0); else diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 8a8698119ff74dad0081792f0effc0483f2e0a69..acc3aa30ee54988bd99e172e3db2b8ae83067c31 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -32,7 +32,7 @@ void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...) if (opts->errors == FAT_ERRORS_PANIC) panic("FAT-fs (%s): fs panic from previous error\n", sb->s_id); - else if (opts->errors == FAT_ERRORS_RO && !(sb->s_flags & MS_RDONLY)) { + else if (opts->errors == FAT_ERRORS_RO && !sb_rdonly(sb)) { sb->s_flags |= MS_RDONLY; fat_msg(sb, KERN_ERR, "Filesystem has been set read-only"); } diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 6a7152d0c2503944d5e870ca8d3b78eb159b1003..02c066663a3a8329500836933383cc45bcd2e372 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -19,6 +19,8 @@ #include #include #include +#include + #include "fat.h" static inline unsigned long vfat_d_version(struct dentry *dentry) @@ -510,10 +512,8 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, struct nls_table *nls) { const unsigned char *ip; - unsigned char nc; unsigned char *op; - unsigned int ec; - int i, k, fill; + int i, fill; int charlen; if (utf8) { @@ -530,33 +530,22 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname, i < len && *outlen < FAT_LFN_LEN; *outlen += 1) { if (escape && (*ip == ':')) { + u8 uc[2]; + if (i > len - 5) return -EINVAL; - ec = 0; - for (k = 1; k < 5; k++) { - nc = ip[k]; - ec <<= 4; - if (nc >= '0' && nc <= '9') { - ec |= nc - '0'; - continue; - } - if (nc >= 'a' && nc <= 'f') { - ec |= nc - ('a' - 10); - continue; - } - if (nc >= 'A' && nc <= 'F') { - ec |= nc - ('A' - 10); - continue; - } + + if (hex2bin(uc, ip + 1, 2) < 0) return -EINVAL; - } - *op++ = ec & 0xFF; - *op++ = ec >> 8; + + *(wchar_t *)op = uc[0] << 8 | uc[1]; + + op += 2; ip += 5; i += 5; } else { charlen = nls->char2uni(ip, len - i, - (wchar_t *)op); + (wchar_t *)op); if (charlen < 0) return -EINVAL; ip += charlen; diff --git a/fs/fcntl.c b/fs/fcntl.c index 3b01b646e528e189b57a1876abf2d4f13364a1bb..448a1119f0becff3d871a98d8e6cee9b673b2652 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -741,10 +741,21 @@ static void send_sigio_to_task(struct task_struct *p, si.si_signo = signum; si.si_errno = 0; si.si_code = reason; + /* + * Posix definies POLL_IN and friends to be signal + * specific si_codes for SIG_POLL. Linux extended + * these si_codes to other signals in a way that is + * ambiguous if other signals also have signal + * specific si_codes. In that case use SI_SIGIO instead + * to remove the ambiguity. + */ + if ((signum != SIGPOLL) && sig_specific_sicodes(signum)) + si.si_code = SI_SIGIO; + /* Make sure we are called with one of the POLL_* reasons, otherwise we could leak kernel stack into userspace. */ - BUG_ON((reason & __SI_MASK) != __SI_POLL); + BUG_ON((reason < POLL_IN) || ((reason - POLL_IN) >= NSIGPOLL)); if (reason - POLL_IN >= NSIGPOLL) si.si_band = ~0L; else diff --git a/fs/file_table.c b/fs/file_table.c index 72e861a35a7f7a05d185b496da5615c74a02552f..61517f57f8ef744e9915c33659cfba96c0a1f767 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -233,12 +233,10 @@ static LLIST_HEAD(delayed_fput_list); static void delayed_fput(struct work_struct *unused) { struct llist_node *node = llist_del_all(&delayed_fput_list); - struct llist_node *next; + struct file *f, *t; - for (; node; node = next) { - next = llist_next(node); - __fput(llist_entry(node, struct file, f_u.fu_llist)); - } + llist_for_each_entry_safe(f, t, node, f_u.fu_llist) + __fput(f); } static void ____fput(struct callback_head *work) @@ -312,7 +310,7 @@ void put_filp(struct file *file) } void __init files_init(void) -{ +{ filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); percpu_counter_init(&nr_files, 0, GFP_KERNEL); @@ -331,4 +329,4 @@ void __init files_maxfiles_init(void) n = ((totalram_pages - memreserve) * (PAGE_SIZE / 1024)) / 10; files_stat.max_files = max_t(unsigned long, n, NR_FILE); -} +} diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c index 67f940892ef810dca6710a7f7c14dc2acd9b2619..b5ab06fabc60a3bd0a7a308f45e4cb5b850398c1 100644 --- a/fs/fscache/object-list.c +++ b/fs/fscache/object-list.c @@ -262,7 +262,8 @@ static int fscache_objlist_show(struct seq_file *m, void *v) type = "DT"; break; default: - sprintf(_type, "%02u", cookie->def->type); + snprintf(_type, sizeof(_type), "%02u", + cookie->def->type); type = _type; break; } diff --git a/fs/fscache/page.c b/fs/fscache/page.c index c8c4f79c7ce167b65549557ca397d9f49a43ca10..0ad3fd3ad0b477c3e0ee2b74d4af78977e405f7b 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -1178,11 +1178,10 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, pagevec_init(&pvec, 0); next = 0; do { - if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) + if (!pagevec_lookup(&pvec, mapping, &next)) break; for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; - next = page->index; if (PageFsCache(page)) { __fscache_wait_on_page_write(cookie, page); __fscache_uncache_page(cookie, page); @@ -1190,7 +1189,7 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, } pagevec_release(&pvec); cond_resched(); - } while (++next); + } while (next); _leave(""); } diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index c5b6b71654893b2bb7fe0276a40ac57ddb3350a0..e9e97803442a6dd33421d250068b71eb4dd63241 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -90,7 +90,7 @@ static struct list_head *cuse_conntbl_head(dev_t devt) static ssize_t cuse_read_iter(struct kiocb *kiocb, struct iov_iter *to) { - struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb->ki_filp); + struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb); loff_t pos = 0; return fuse_direct_io(&io, to, &pos, FUSE_DIO_CUSE); @@ -98,7 +98,7 @@ static ssize_t cuse_read_iter(struct kiocb *kiocb, struct iov_iter *to) static ssize_t cuse_write_iter(struct kiocb *kiocb, struct iov_iter *from) { - struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb->ki_filp); + struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb); loff_t pos = 0; /* * No locking or generic_write_checks(), the server is diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index c16d00e5326459c6608268f9ce3f68f30467eac6..13c65dd2d37d1ab1af358f82b42c43ba8c2cc2de 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1222,9 +1222,6 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, struct fuse_in *in; unsigned reqsize; - if (task_active_pid_ns(current) != fc->pid_ns) - return -EIO; - restart: spin_lock(&fiq->waitq.lock); err = -EAGAIN; @@ -1262,6 +1259,13 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, in = &req->in; reqsize = in->h.len; + + if (task_active_pid_ns(current) != fc->pid_ns) { + rcu_read_lock(); + in->h.pid = pid_vnr(find_pid_ns(in->h.pid, fc->pid_ns)); + rcu_read_unlock(); + } + /* If request is too large, reply with an error and restart the read */ if (nbytes < reqsize) { req->out.h.error = -EIO; @@ -1823,9 +1827,6 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, struct fuse_req *req; struct fuse_out_header oh; - if (task_active_pid_ns(current) != fc->pid_ns) - return -EIO; - if (nbytes < sizeof(struct fuse_out_header)) return -EINVAL; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 00800c07ba1c89bda7abd8f15aa760b9ddccc869..622081b97426d5b439bb1db5ee57dc4c3eead253 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -923,33 +923,29 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, return err; } -int fuse_update_attributes(struct inode *inode, struct kstat *stat, - struct file *file, bool *refreshed) +static int fuse_update_get_attr(struct inode *inode, struct file *file, + struct kstat *stat) { struct fuse_inode *fi = get_fuse_inode(inode); - int err; - bool r; + int err = 0; if (time_before64(fi->i_time, get_jiffies_64())) { - r = true; forget_all_cached_acls(inode); err = fuse_do_getattr(inode, stat, file); - } else { - r = false; - err = 0; - if (stat) { - generic_fillattr(inode, stat); - stat->mode = fi->orig_i_mode; - stat->ino = fi->orig_ino; - } + } else if (stat) { + generic_fillattr(inode, stat); + stat->mode = fi->orig_i_mode; + stat->ino = fi->orig_ino; } - if (refreshed != NULL) - *refreshed = r; - return err; } +int fuse_update_attributes(struct inode *inode, struct file *file) +{ + return fuse_update_get_attr(inode, file, NULL); +} + int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid, u64 child_nodeid, struct qstr *name) { @@ -1786,7 +1782,7 @@ static int fuse_getattr(const struct path *path, struct kstat *stat, if (!fuse_allow_current_process(fc)) return -EACCES; - return fuse_update_attributes(inode, stat, NULL, NULL); + return fuse_update_get_attr(inode, NULL, stat); } static const struct inode_operations fuse_dir_inode_operations = { diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3ee4fdc3da9ec359ad847afa36354240329a2da6..cb7dff5c45d767991698058d8d52027572ebea41 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -46,7 +46,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) { struct fuse_file *ff; - ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); + ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL); if (unlikely(!ff)) return NULL; @@ -457,7 +457,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, * wait for all outstanding writes, before sending the FSYNC * request. */ - err = filemap_write_and_wait_range(inode->i_mapping, start, end); + err = file_write_and_wait_range(file, start, end); if (err) goto out; @@ -465,10 +465,10 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, /* * Due to implementation of fuse writeback - * filemap_write_and_wait_range() does not catch errors. + * file_write_and_wait_range() does not catch errors. * We have to do this directly after fuse_sync_writes() */ - err = filemap_check_errors(file->f_mapping); + err = file_check_and_advance_wb_err(file); if (err) goto out; @@ -609,7 +609,7 @@ static void fuse_aio_complete_req(struct fuse_conn *fc, struct fuse_req *req) struct fuse_io_priv *io = req->io; ssize_t pos = -1; - fuse_release_user_pages(req, !io->write); + fuse_release_user_pages(req, io->should_dirty); if (io->write) { if (req->misc.write.in.size != req->misc.write.out.size) @@ -645,7 +645,7 @@ static size_t fuse_async_req_send(struct fuse_conn *fc, struct fuse_req *req, static size_t fuse_send_read(struct fuse_req *req, struct fuse_io_priv *io, loff_t pos, size_t count, fl_owner_t owner) { - struct file *file = io->file; + struct file *file = io->iocb->ki_filp; struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; @@ -707,7 +707,8 @@ static void fuse_short_read(struct fuse_req *req, struct inode *inode, static int fuse_do_readpage(struct file *file, struct page *page) { - struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file); + struct kiocb iocb; + struct fuse_io_priv io; struct inode *inode = page->mapping->host; struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_req *req; @@ -735,6 +736,8 @@ static int fuse_do_readpage(struct file *file, struct page *page) req->num_pages = 1; req->pages[0] = page; req->page_descs[0].length = count; + init_sync_kiocb(&iocb, file); + io = (struct fuse_io_priv) FUSE_IO_PRIV_SYNC(&iocb); num_read = fuse_send_read(req, &io, pos, count, NULL); err = req->out.h.error; @@ -923,7 +926,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to) if (fc->auto_inval_data || (iocb->ki_pos + iov_iter_count(to) > i_size_read(inode))) { int err; - err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); + err = fuse_update_attributes(inode, iocb->ki_filp); if (err) return err; } @@ -957,13 +960,18 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, static size_t fuse_send_write(struct fuse_req *req, struct fuse_io_priv *io, loff_t pos, size_t count, fl_owner_t owner) { - struct file *file = io->file; + struct kiocb *iocb = io->iocb; + struct file *file = iocb->ki_filp; struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; struct fuse_write_in *inarg = &req->misc.write.in; fuse_write_fill(req, ff, pos, count); inarg->flags = file->f_flags; + if (iocb->ki_flags & IOCB_DSYNC) + inarg->flags |= O_DSYNC; + if (iocb->ki_flags & IOCB_SYNC) + inarg->flags |= O_SYNC; if (owner != NULL) { inarg->write_flags |= FUSE_WRITE_LOCKOWNER; inarg->lock_owner = fuse_lock_owner_id(fc, owner); @@ -993,14 +1001,14 @@ bool fuse_write_update_size(struct inode *inode, loff_t pos) return ret; } -static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file, +static size_t fuse_send_write_pages(struct fuse_req *req, struct kiocb *iocb, struct inode *inode, loff_t pos, size_t count) { size_t res; unsigned offset; unsigned i; - struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file); + struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb); for (i = 0; i < req->num_pages; i++) fuse_wait_on_page_writeback(inode, req->pages[i]->index); @@ -1100,7 +1108,7 @@ static inline unsigned fuse_wr_pages(loff_t pos, size_t len) FUSE_MAX_PAGES_PER_REQ); } -static ssize_t fuse_perform_write(struct file *file, +static ssize_t fuse_perform_write(struct kiocb *iocb, struct address_space *mapping, struct iov_iter *ii, loff_t pos) { @@ -1133,7 +1141,7 @@ static ssize_t fuse_perform_write(struct file *file, } else { size_t num_written; - num_written = fuse_send_write_pages(req, file, inode, + num_written = fuse_send_write_pages(req, iocb, inode, pos, count); err = req->out.h.error; if (!err) { @@ -1169,7 +1177,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (get_fuse_conn(inode)->writeback_cache) { /* Update size (EOF optimization) and mode (SUID clearing) */ - err = fuse_update_attributes(mapping->host, NULL, file, NULL); + err = fuse_update_attributes(mapping->host, file); if (err) return err; @@ -1201,7 +1209,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) pos += written; - written_buffered = fuse_perform_write(file, mapping, from, pos); + written_buffered = fuse_perform_write(iocb, mapping, from, pos); if (written_buffered < 0) { err = written_buffered; goto out; @@ -1220,13 +1228,15 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) written += written_buffered; iocb->ki_pos = pos + written_buffered; } else { - written = fuse_perform_write(file, mapping, from, iocb->ki_pos); + written = fuse_perform_write(iocb, mapping, from, iocb->ki_pos); if (written >= 0) iocb->ki_pos += written; } out: current->backing_dev_info = NULL; inode_unlock(inode); + if (written > 0) + written = generic_write_sync(iocb, written); return written ? written : err; } @@ -1316,9 +1326,8 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, loff_t *ppos, int flags) { int write = flags & FUSE_DIO_WRITE; - bool should_dirty = !write && iter_is_iovec(iter); int cuse = flags & FUSE_DIO_CUSE; - struct file *file = io->file; + struct file *file = io->iocb->ki_filp; struct inode *inode = file->f_mapping->host; struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; @@ -1346,6 +1355,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, inode_unlock(inode); } + io->should_dirty = !write && iter_is_iovec(iter); while (count) { size_t nres; fl_owner_t owner = current->files; @@ -1360,7 +1370,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, nres = fuse_send_read(req, io, pos, nbytes, owner); if (!io->async) - fuse_release_user_pages(req, should_dirty); + fuse_release_user_pages(req, io->should_dirty); if (req->out.h.error) { err = req->out.h.error; break; @@ -1399,8 +1409,7 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io, loff_t *ppos) { ssize_t res; - struct file *file = io->file; - struct inode *inode = file_inode(file); + struct inode *inode = file_inode(io->iocb->ki_filp); if (is_bad_inode(inode)) return -EIO; @@ -1414,15 +1423,14 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io, static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to) { - struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb->ki_filp); + struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb); return __fuse_direct_read(&io, to, &iocb->ki_pos); } static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from) { - struct file *file = iocb->ki_filp; - struct inode *inode = file_inode(file); - struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file); + struct inode *inode = file_inode(iocb->ki_filp); + struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb); ssize_t res; if (is_bad_inode(inode)) @@ -1669,6 +1677,7 @@ static int fuse_writepage_locked(struct page *page) err_free: fuse_request_free(req); err: + mapping_set_error(page->mapping, error); end_page_writeback(page); return error; } @@ -2101,11 +2110,11 @@ static int convert_fuse_file_lock(struct fuse_conn *fc, fl->fl_end = ffl->end; /* - * Convert pid into the caller's pid namespace. If the pid - * does not map into the namespace fl_pid will get set to 0. + * Convert pid into init's pid namespace. The locks API will + * translate it into the caller's pid namespace. */ rcu_read_lock(); - fl->fl_pid = pid_vnr(find_pid_ns(ffl->pid, fc->pid_ns)); + fl->fl_pid = pid_nr_ns(find_pid_ns(ffl->pid, fc->pid_ns), &init_pid_ns); rcu_read_unlock(); break; @@ -2180,9 +2189,6 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) if ((fl->fl_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX) return 0; - if (pid && pid_nr == 0) - return -EOVERFLOW; - fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg); err = fuse_simple_request(fc, &args); @@ -2302,7 +2308,7 @@ static loff_t fuse_lseek(struct file *file, loff_t offset, int whence) return vfs_setpos(file, outarg.offset, inode->i_sb->s_maxbytes); fallback: - err = fuse_update_attributes(inode, NULL, file, NULL); + err = fuse_update_attributes(inode, file); if (!err) return generic_file_llseek(file, offset, whence); else @@ -2322,7 +2328,7 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence) break; case SEEK_END: inode_lock(inode); - retval = fuse_update_attributes(inode, NULL, file, NULL); + retval = fuse_update_attributes(inode, file); if (!retval) retval = generic_file_llseek(file, offset, whence); inode_unlock(inode); @@ -2873,7 +2879,6 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) io->offset = offset; io->write = (iov_iter_rw(iter) == WRITE); io->err = 0; - io->file = file; /* * By default, we want to optimize all I/Os with async request * submission to the client filesystem if supported. diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1bd7ffdad593977013c1ddd233b2a91093471471..d5773ca67ad2bbc36155a30fafa596dd7e44502a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -249,18 +249,18 @@ struct fuse_io_priv { size_t size; __u64 offset; bool write; + bool should_dirty; int err; struct kiocb *iocb; - struct file *file; struct completion *done; bool blocking; }; -#define FUSE_IO_PRIV_SYNC(f) \ +#define FUSE_IO_PRIV_SYNC(i) \ { \ .refcnt = KREF_INIT(1), \ .async = 0, \ - .file = f, \ + .iocb = i, \ } /** @@ -904,8 +904,7 @@ u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id); void fuse_update_ctime(struct inode *inode); -int fuse_update_attributes(struct inode *inode, struct kstat *stat, - struct file *file, bool *refreshed); +int fuse_update_attributes(struct inode *inode, struct file *file); void fuse_flush_writepages(struct inode *inode); diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 2524807ee0703643867e7e04c803d10b1aab9182..9d5eecb123de6d73a02fea79ebeffd959ecc82aa 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -86,19 +86,6 @@ int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) char *data; const char *name = gfs2_acl_name(type); - if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode))) - return -E2BIG; - - if (type == ACL_TYPE_ACCESS) { - umode_t mode = inode->i_mode; - - error = posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; - if (mode != inode->i_mode) - mark_inode_dirty(inode); - } - if (acl) { len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0); if (len == 0) @@ -129,6 +116,10 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) struct gfs2_holder gh; bool need_unlock = false; int ret; + umode_t mode; + + if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode))) + return -E2BIG; ret = gfs2_rsqa_alloc(ip); if (ret) @@ -140,7 +131,20 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) return ret; need_unlock = true; } + + mode = inode->i_mode; + if (type == ACL_TYPE_ACCESS && acl) { + ret = posix_acl_update_mode(inode, &mode, &acl); + if (ret) + goto unlock; + } + ret = __gfs2_set_acl(inode, acl, type); + if (!ret && mode != inode->i_mode) { + inode->i_mode = mode; + mark_inode_dirty(inode); + } +unlock: if (need_unlock) gfs2_glock_dq_uninit(&gh); return ret; diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index ed7a2e252ad802bf587006b00939696ea2cbe9eb..68ed069625370fa821de91b058c4c9d229db3a89 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -234,7 +234,19 @@ static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc static int gfs2_writepages(struct address_space *mapping, struct writeback_control *wbc) { - return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc); + struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping); + int ret = mpage_writepages(mapping, wbc, gfs2_get_block_noalloc); + + /* + * Even if we didn't write any pages here, we might still be holding + * dirty pages in the ail. We forcibly flush the ail because we don't + * want balance_dirty_pages() to loop indefinitely trying to write out + * pages held in the ail that it can't find. + */ + if (ret == 0) + set_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); + + return ret; } /** diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 9fa3aef9a5b358ec7f78fa6fd08f8c6d008611f6..3dd0cceefa435bb623de0b1ee8dd33d83a6bdba8 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -291,8 +291,9 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl, if (trylock_buffer(rabh)) { if (!buffer_uptodate(rabh)) { rabh->b_end_io = end_buffer_read_sync; - submit_bh(REQ_OP_READ, REQ_RAHEAD | REQ_META, - rabh); + submit_bh(REQ_OP_READ, + REQ_RAHEAD | REQ_META | REQ_PRIO, + rabh); continue; } unlock_buffer(rabh); @@ -1103,8 +1104,15 @@ static bool find_nonnull_ptr(struct gfs2_sbd *sdp, struct metapath *mp, while (true) { ptr = metapointer(h, mp); - if (*ptr) /* if we have a non-null pointer */ + if (*ptr) { /* if we have a non-null pointer */ + /* Now zero the metapath after the current height. */ + h++; + if (h < GFS2_MAX_META_HEIGHT) + memset(&mp->mp_list[h], 0, + (GFS2_MAX_META_HEIGHT - h) * + sizeof(mp->mp_list[0])); return true; + } if (mp->mp_list[h] < ptrs) mp->mp_list[h]++; @@ -1120,6 +1128,13 @@ enum dealloc_states { DEALLOC_DONE = 3, /* process complete */ }; +static bool mp_eq_to_hgt(struct metapath *mp, __u16 *nbof, unsigned int h) +{ + if (memcmp(mp->mp_list, nbof, h * sizeof(mp->mp_list[0]))) + return false; + return true; +} + /** * trunc_dealloc - truncate a file down to a desired size * @ip: inode to truncate @@ -1197,8 +1212,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize) /* If we're truncating to a non-zero size and the mp is at the beginning of file for the strip height, we need to preserve the first metadata pointer. */ - preserve1 = (newsize && - (mp.mp_list[mp_h] == nbof[mp_h])); + preserve1 = (newsize && mp_eq_to_hgt(&mp, nbof, mp_h)); bh = mp.mp_bh[mp_h]; gfs2_assert_withdraw(sdp, bh); if (gfs2_assert_withdraw(sdp, diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 5ee2e2f8576cd8811509e33769515e3a5a403281..06a0d1947c7721bed1cc779c0b13607843f9b6a9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1513,7 +1513,9 @@ static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index, continue; } bh->b_end_io = end_buffer_read_sync; - submit_bh(REQ_OP_READ, REQ_RAHEAD | REQ_META, bh); + submit_bh(REQ_OP_READ, + REQ_RAHEAD | REQ_META | REQ_PRIO, + bh); continue; } brelse(bh); diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index c2062a108d19602544276f596de75b1f593a1e61..33a0cb5701a330623ded09e427f79d53d6cee4db 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -668,12 +668,14 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end, if (ret) return ret; if (gfs2_is_jdata(ip)) - filemap_write_and_wait(mapping); + ret = file_write_and_wait(file); + if (ret) + return ret; gfs2_ail_flush(ip->i_gl, 1); } if (mapping->nrpages) - ret = filemap_fdatawait_range(mapping, start, end); + ret = file_fdatawait_range(file, start, end); return ret ? ret : ret1; } @@ -1030,8 +1032,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) mutex_lock(&fp->f_fl_mutex); - gl = fl_gh->gh_gl; - if (gl) { + if (gfs2_holder_initialized(fl_gh)) { if (fl_gh->gh_state == state) goto out; locks_lock_file_wait(file, diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index c38ab6c818983803d67815ac4a32b9302e48795d..11066d8647d29320dcb30d063536aa4f218cf5ec 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,7 @@ static DEFINE_SPINLOCK(lru_lock); #define GFS2_GL_HASH_SHIFT 15 #define GFS2_GL_HASH_SIZE BIT(GFS2_GL_HASH_SHIFT) -static struct rhashtable_params ht_parms = { +static const struct rhashtable_params ht_parms = { .nelem_hint = GFS2_GL_HASH_SIZE * 3 / 4, .key_len = offsetofend(struct lm_lockname, ln_type), .key_offset = offsetof(struct gfs2_glock, gl_name), @@ -80,6 +81,49 @@ static struct rhashtable_params ht_parms = { static struct rhashtable gl_hash_table; +#define GLOCK_WAIT_TABLE_BITS 12 +#define GLOCK_WAIT_TABLE_SIZE (1 << GLOCK_WAIT_TABLE_BITS) +static wait_queue_head_t glock_wait_table[GLOCK_WAIT_TABLE_SIZE] __cacheline_aligned; + +struct wait_glock_queue { + struct lm_lockname *name; + wait_queue_entry_t wait; +}; + +static int glock_wake_function(wait_queue_entry_t *wait, unsigned int mode, + int sync, void *key) +{ + struct wait_glock_queue *wait_glock = + container_of(wait, struct wait_glock_queue, wait); + struct lm_lockname *wait_name = wait_glock->name; + struct lm_lockname *wake_name = key; + + if (wake_name->ln_sbd != wait_name->ln_sbd || + wake_name->ln_number != wait_name->ln_number || + wake_name->ln_type != wait_name->ln_type) + return 0; + return autoremove_wake_function(wait, mode, sync, key); +} + +static wait_queue_head_t *glock_waitqueue(struct lm_lockname *name) +{ + u32 hash = jhash2((u32 *)name, sizeof(*name) / 4, 0); + + return glock_wait_table + hash_32(hash, GLOCK_WAIT_TABLE_BITS); +} + +/** + * wake_up_glock - Wake up waiters on a glock + * @gl: the glock + */ +static void wake_up_glock(struct gfs2_glock *gl) +{ + wait_queue_head_t *wq = glock_waitqueue(&gl->gl_name); + + if (waitqueue_active(wq)) + __wake_up(wq, TASK_NORMAL, 1, &gl->gl_name); +} + static void gfs2_glock_dealloc(struct rcu_head *rcu) { struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu); @@ -96,6 +140,9 @@ void gfs2_glock_free(struct gfs2_glock *gl) { struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + rhashtable_remove_fast(&gl_hash_table, &gl->gl_node, ht_parms); + smp_mb(); + wake_up_glock(gl); call_rcu(&gl->gl_rcu, gfs2_glock_dealloc); if (atomic_dec_and_test(&sdp->sd_glock_disposal)) wake_up(&sdp->sd_glock_wait); @@ -107,7 +154,7 @@ void gfs2_glock_free(struct gfs2_glock *gl) * */ -static void gfs2_glock_hold(struct gfs2_glock *gl) +void gfs2_glock_hold(struct gfs2_glock *gl) { GLOCK_BUG_ON(gl, __lockref_is_dead(&gl->gl_lockref)); lockref_get(&gl->gl_lockref); @@ -150,6 +197,9 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl) static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) { + if (!(gl->gl_ops->go_flags & GLOF_LRU)) + return; + spin_lock(&lru_lock); if (!list_empty(&gl->gl_lru)) { list_del_init(&gl->gl_lru); @@ -191,13 +241,20 @@ static void __gfs2_glock_put(struct gfs2_glock *gl) gfs2_glock_remove_from_lru(gl); spin_unlock(&gl->gl_lockref.lock); - rhashtable_remove_fast(&gl_hash_table, &gl->gl_node, ht_parms); GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); GLOCK_BUG_ON(gl, mapping && mapping->nrpages); trace_gfs2_glock_put(gl); sdp->sd_lockstruct.ls_ops->lm_put_lock(gl); } +/* + * Cause the glock to be put in work queue context. + */ +void gfs2_glock_queue_put(struct gfs2_glock *gl) +{ + gfs2_glock_queue_work(gl, 0); +} + /** * gfs2_glock_put() - Decrement reference count on glock * @gl: The glock to put @@ -676,6 +733,40 @@ static void glock_work_func(struct work_struct *work) spin_unlock(&gl->gl_lockref.lock); } +static struct gfs2_glock *find_insert_glock(struct lm_lockname *name, + struct gfs2_glock *new) +{ + struct wait_glock_queue wait; + wait_queue_head_t *wq = glock_waitqueue(name); + struct gfs2_glock *gl; + + wait.name = name; + init_wait(&wait.wait); + wait.wait.func = glock_wake_function; + +again: + prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); + rcu_read_lock(); + if (new) { + gl = rhashtable_lookup_get_insert_fast(&gl_hash_table, + &new->gl_node, ht_parms); + if (IS_ERR(gl)) + goto out; + } else { + gl = rhashtable_lookup_fast(&gl_hash_table, + name, ht_parms); + } + if (gl && !lockref_get_not_dead(&gl->gl_lockref)) { + rcu_read_unlock(); + schedule(); + goto again; + } +out: + rcu_read_unlock(); + finish_wait(wq, &wait.wait); + return gl; +} + /** * gfs2_glock_get() - Get a glock, or create one if one doesn't exist * @sdp: The GFS2 superblock @@ -702,15 +793,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, struct kmem_cache *cachep; int ret = 0; - rcu_read_lock(); - gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms); - if (gl && !lockref_get_not_dead(&gl->gl_lockref)) - gl = NULL; - rcu_read_unlock(); - - *glp = gl; - if (gl) + gl = find_insert_glock(&name, NULL); + if (gl) { + *glp = gl; return 0; + } if (!create) return -ENOENT; @@ -764,10 +851,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, mapping->writeback_index = 0; } -again: - rcu_read_lock(); - tmp = rhashtable_lookup_get_insert_fast(&gl_hash_table, &gl->gl_node, - ht_parms); + tmp = find_insert_glock(&name, gl); if (!tmp) { *glp = gl; goto out; @@ -776,13 +860,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, ret = PTR_ERR(tmp); goto out_free; } - if (lockref_get_not_dead(&tmp->gl_lockref)) { - *glp = tmp; - goto out_free; - } - rcu_read_unlock(); - cond_resched(); - goto again; + *glp = tmp; out_free: kfree(gl->gl_lksb.sb_lvbptr); @@ -790,7 +868,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, atomic_dec(&sdp->sd_glock_disposal); out: - rcu_read_unlock(); return ret; } @@ -1473,14 +1550,15 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp) do { gl = ERR_PTR(rhashtable_walk_start(&iter)); - if (gl) - continue; + if (IS_ERR(gl)) + goto walk_stop; while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl)) - if ((gl->gl_name.ln_sbd == sdp) && + if (gl->gl_name.ln_sbd == sdp && lockref_get_not_dead(&gl->gl_lockref)) examiner(gl); +walk_stop: rhashtable_walk_stop(&iter); } while (cond_resched(), gl == ERR_PTR(-EAGAIN)); @@ -1803,7 +1881,7 @@ static int gfs2_sbstats_seq_show(struct seq_file *seq, void *iter_ptr) int __init gfs2_glock_init(void) { - int ret; + int i, ret; ret = rhashtable_init(&gl_hash_table, &ht_parms); if (ret < 0) @@ -1832,6 +1910,9 @@ int __init gfs2_glock_init(void) return ret; } + for (i = 0; i < GLOCK_WAIT_TABLE_SIZE; i++) + init_waitqueue_head(glock_wait_table + i); + return 0; } @@ -1860,16 +1941,13 @@ static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi) } static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(RCU) { struct gfs2_glock_iter *gi = seq->private; loff_t n = *pos; - int ret; - if (gi->last_pos <= *pos) - n = (*pos - gi->last_pos); - - ret = rhashtable_walk_start(&gi->hti); - if (ret) + rhashtable_walk_enter(&gl_hash_table, &gi->hti); + if (rhashtable_walk_start(&gi->hti) != 0) return NULL; do { @@ -1877,6 +1955,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) } while (gi->gl && n--); gi->last_pos = *pos; + return gi->gl; } @@ -1888,15 +1967,18 @@ static void *gfs2_glock_seq_next(struct seq_file *seq, void *iter_ptr, (*pos)++; gi->last_pos = *pos; gfs2_glock_iter_next(gi); + return gi->gl; } static void gfs2_glock_seq_stop(struct seq_file *seq, void *iter_ptr) + __releases(RCU) { struct gfs2_glock_iter *gi = seq->private; gi->gl = NULL; rhashtable_walk_stop(&gi->hti); + rhashtable_walk_exit(&gi->hti); } static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr) @@ -1959,12 +2041,10 @@ static int __gfs2_glocks_open(struct inode *inode, struct file *file, struct gfs2_glock_iter *gi = seq->private; gi->sdp = inode->i_private; - gi->last_pos = 0; seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); if (seq->buf) seq->size = GFS2_SEQ_GOODSIZE; gi->gl = NULL; - rhashtable_walk_enter(&gl_hash_table, &gi->hti); } return ret; } @@ -1980,7 +2060,6 @@ static int gfs2_glocks_release(struct inode *inode, struct file *file) struct gfs2_glock_iter *gi = seq->private; gi->gl = NULL; - rhashtable_walk_exit(&gi->hti); return seq_release_private(inode, file); } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 9ad4a6ac6c84ce90052792efb1d65b991c8ed9bf..5e12220cc0c241100337723719e2bf14f026f836 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -13,6 +13,7 @@ #include #include #include "incore.h" +#include "util.h" /* Options for hostdata parser */ @@ -181,7 +182,9 @@ static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl) extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, const struct gfs2_glock_operations *glops, int create, struct gfs2_glock **glp); +extern void gfs2_glock_hold(struct gfs2_glock *gl); extern void gfs2_glock_put(struct gfs2_glock *gl); +extern void gfs2_glock_queue_put(struct gfs2_glock *gl); extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags, struct gfs2_holder *gh); extern void gfs2_holder_reinit(unsigned int state, u16 flags, @@ -257,11 +260,44 @@ static inline bool gfs2_holder_initialized(struct gfs2_holder *gh) return gh->gh_gl; } +/** + * glock_set_object - set the gl_object field of a glock + * @gl: the glock + * @object: the object + */ static inline void glock_set_object(struct gfs2_glock *gl, void *object) { spin_lock(&gl->gl_lockref.lock); + if (gfs2_assert_warn(gl->gl_name.ln_sbd, gl->gl_object == NULL)) + gfs2_dump_glock(NULL, gl); gl->gl_object = object; spin_unlock(&gl->gl_lockref.lock); } +/** + * glock_clear_object - clear the gl_object field of a glock + * @gl: the glock + * @object: the object + * + * I'd love to similarly add this: + * else if (gfs2_assert_warn(gl->gl_sbd, gl->gl_object == object)) + * gfs2_dump_glock(NULL, gl); + * Unfortunately, that's not possible because as soon as gfs2_delete_inode + * frees the block in the rgrp, another process can reassign it for an I_NEW + * inode in gfs2_create_inode because that calls new_inode, not gfs2_iget. + * That means gfs2_delete_inode may subsequently try to call this function + * for a glock that's already pointing to a brand new inode. If we clear the + * new inode's gl_object, we'll introduce metadata corruption. Function + * gfs2_delete_inode calls clear_inode which calls gfs2_clear_inode which also + * tries to clear gl_object, so it's more than just gfs2_delete_inode. + * + */ +static inline void glock_clear_object(struct gfs2_glock *gl, void *object) +{ + spin_lock(&gl->gl_lockref.lock); + if (gl->gl_object == object) + gl->gl_object = NULL; + spin_unlock(&gl->gl_lockref.lock); +} + #endif /* __GLOCK_DOT_H__ */ diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 5e69636d4dd3cfd968fa5617f9d93fb1b5f62ada..cdd1c5f06f452f70d6704c86ed87d4548ab7d315 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -329,32 +329,6 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl) return 1; } -/** - * gfs2_set_nlink - Set the inode's link count based on on-disk info - * @inode: The inode in question - * @nlink: The link count - * - * If the link count has hit zero, it must never be raised, whatever the - * on-disk inode might say. When new struct inodes are created the link - * count is set to 1, so that we can safely use this test even when reading - * in on disk information for the first time. - */ - -static void gfs2_set_nlink(struct inode *inode, u32 nlink) -{ - /* - * We will need to review setting the nlink count here in the - * light of the forthcoming ro bind mount work. This is a reminder - * to do that. - */ - if ((inode->i_nlink != nlink) && (inode->i_nlink != 0)) { - if (nlink == 0) - clear_nlink(inode); - else - set_nlink(inode, nlink); - } -} - static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) { const struct gfs2_dinode *str = buf; @@ -376,7 +350,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); - gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); + set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); atime.tv_sec = be64_to_cpu(str->di_atime); @@ -470,7 +444,7 @@ static int inode_go_lock(struct gfs2_holder *gh) (gh->gh_state == LM_ST_EXCLUSIVE)) { spin_lock(&sdp->sd_trunc_lock); if (list_empty(&ip->i_trunc_list)) - list_add(&sdp->sd_trunc_list, &ip->i_trunc_list); + list_add(&ip->i_trunc_list, &sdp->sd_trunc_list); spin_unlock(&sdp->sd_trunc_lock); wake_up(&sdp->sd_quota_wait); return 1; @@ -580,7 +554,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) struct gfs2_inode *ip = gl->gl_object; struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; - if (!remote || (sdp->sd_vfs->s_flags & MS_RDONLY)) + if (!remote || sb_rdonly(sdp->sd_vfs)) return; if (gl->gl_demote_state == LM_ST_UNLOCKED && diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 73fce76e67ee84b49495389c44449738008a4312..6e18e9793ec46d72742edc701f28e52065995029 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -606,6 +606,7 @@ enum { SDF_NOJOURNALID = 6, SDF_RORECOVERY = 7, /* read only recovery */ SDF_SKIP_DLM_UNLOCK = 8, + SDF_FORCE_AIL_FLUSH = 9, }; enum gfs2_freeze_state { @@ -816,6 +817,7 @@ struct gfs2_sbd { atomic_t sd_log_in_flight; struct bio *sd_log_bio; wait_queue_head_t sd_log_flush_wait; + int sd_log_error; atomic_t sd_reserving_log; wait_queue_head_t sd_reserving_log_wait; @@ -831,7 +833,7 @@ struct gfs2_sbd { atomic_t sd_freeze_state; struct mutex sd_freeze_mutex; - char sd_fsname[GFS2_FSNAME_LEN]; + char sd_fsname[GFS2_FSNAME_LEN + 3 * sizeof(int) + 2]; char sd_table_name[GFS2_FSNAME_LEN]; char sd_proto_name[GFS2_FSNAME_LEN]; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index acca501f811045cd37980c490e9a1d2e674dcae8..863749e29bf90607238a6b8a09c28dc1abd1ce8a 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -109,7 +109,7 @@ static void gfs2_set_iop(struct inode *inode) * @no_addr: The inode number * @no_formal_ino: The inode generation number * @blktype: Requested block type (GFS2_BLKST_DINODE or GFS2_BLKST_UNLINKED; - * GFS2_BLKST_FREE do indicate not to verify) + * GFS2_BLKST_FREE to indicate not to verify) * * If @type is DT_UNKNOWN, the inode type is fetched from disk. * @@ -145,7 +145,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, if (unlikely(error)) goto fail; flush_delayed_work(&ip->i_gl->gl_work); - glock_set_object(ip->i_gl, ip); error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); if (unlikely(error)) @@ -170,11 +169,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, } } + glock_set_object(ip->i_gl, ip); set_bit(GIF_INVALID, &ip->i_flags); error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); if (unlikely(error)) goto fail_put; - flush_delayed_work(&ip->i_iopen_gh.gh_gl->gl_work); glock_set_object(ip->i_iopen_gh.gh_gl, ip); gfs2_glock_put(io_gl); io_gl = NULL; @@ -202,14 +201,14 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, fail_refresh: ip->i_iopen_gh.gh_flags |= GL_NOCACHE; - glock_set_object(ip->i_iopen_gh.gh_gl, NULL); + glock_clear_object(ip->i_iopen_gh.gh_gl, ip); gfs2_glock_dq_uninit(&ip->i_iopen_gh); fail_put: if (io_gl) gfs2_glock_put(io_gl); + glock_clear_object(ip->i_gl, ip); if (gfs2_holder_initialized(&i_gh)) gfs2_glock_dq_uninit(&i_gh); - glock_set_object(ip->i_gl, NULL); fail: iget_failed(inode); return ERR_PTR(error); @@ -706,8 +705,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); if (error) goto fail_free_inode; - + flush_delayed_work(&ip->i_gl->gl_work); glock_set_object(ip->i_gl, ip); + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); if (error) goto fail_free_inode; @@ -775,14 +775,17 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, return error; fail_gunlock3: + glock_clear_object(io_gl, ip); gfs2_glock_dq_uninit(&ip->i_iopen_gh); gfs2_glock_put(io_gl); fail_gunlock2: if (io_gl) clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); fail_free_inode: - if (ip->i_gl) + if (ip->i_gl) { + glock_clear_object(ip->i_gl, ip); gfs2_glock_put(ip->i_gl); + } gfs2_rsqa_delete(ip, NULL); fail_free_acls: if (default_acl) diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 0515f0a686375fa07cdb1c6bfe51f76516f8bec0..65f33a0ac190572fae58e7087431f3c2005824d5 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -23,8 +23,6 @@ #include "sys.h" #include "trace_gfs2.h" -extern struct workqueue_struct *gfs2_control_wq; - /** * gfs2_update_stats - Update time based stats * @mv: Pointer to mean/variance structure to update @@ -1059,6 +1057,7 @@ static void free_recover_size(struct lm_lockstruct *ls) ls->ls_recover_submit = NULL; ls->ls_recover_result = NULL; ls->ls_recover_size = 0; + ls->ls_lvb_bits = NULL; } /* dlm calls before it does lock recovery */ @@ -1175,7 +1174,7 @@ static void gdlm_recovery_result(struct gfs2_sbd *sdp, unsigned int jid, spin_unlock(&ls->ls_recover_spin); } -const struct dlm_lockspace_ops gdlm_lockspace_ops = { +static const struct dlm_lockspace_ops gdlm_lockspace_ops = { .recover_prep = gdlm_recover_prep, .recover_slot = gdlm_recover_slot, .recover_done = gdlm_recover_done, diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 9a624f6944002af70b75c32c93fc6da1924986f7..f72c442314062c4835ecaa3e0b92b538522f759a 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -898,6 +898,10 @@ static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) { unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); + + if (test_and_clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags)) + return 1; + return used_blocks + atomic_read(&sdp->sd_log_blks_needed) >= atomic_read(&sdp->sd_log_thresh2); } @@ -919,6 +923,15 @@ int gfs2_logd(void *data) while (!kthread_should_stop()) { + /* Check for errors writing to the journal */ + if (sdp->sd_log_error) { + gfs2_lm_withdraw(sdp, + "GFS2: fsid=%s: error %d: " + "withdrawing the file system to " + "prevent further damage.\n", + sdp->sd_fsname, sdp->sd_log_error); + } + did_flush = false; if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { gfs2_ail1_empty(sdp); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 3010f9edd177dffeb3e270515a15e643e37bdd22..c8ff7b7954f05d4b82160804ac1bed811bbb8b48 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -207,8 +207,11 @@ static void gfs2_end_log_write(struct bio *bio) struct page *page; int i; - if (bio->bi_status) - fs_err(sdp, "Error %d writing to log\n", bio->bi_status); + if (bio->bi_status) { + fs_err(sdp, "Error %d writing to journal, jid=%u\n", + bio->bi_status, sdp->sd_jdesc->jd_jid); + wake_up(&sdp->sd_logd_waitq); + } bio_for_each_segment_all(bvec, bio, i) { page = bvec->bv_page; @@ -265,7 +268,7 @@ static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno) bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES); bio->bi_iter.bi_sector = blkno * (sb->s_blocksize >> 9); - bio->bi_bdev = sb->s_bdev; + bio_set_dev(bio, sb->s_bdev); bio->bi_end_io = gfs2_end_log_write; bio->bi_private = sdp; diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index fabe1614f879525827290d05eb79ca53ad76a57e..52de1036d9f92fbd4b544dfb5495d71159fa3ca3 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -221,7 +221,7 @@ static void gfs2_submit_bhs(int op, int op_flags, struct buffer_head *bhs[], bio = bio_alloc(GFP_NOIO, num); bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); - bio->bi_bdev = bh->b_bdev; + bio_set_dev(bio, bh->b_bdev); while (num > 0) { bh = *bhs; if (!bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh))) { @@ -419,8 +419,9 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { brelse(bh); ret = -EIO; + } else { + *bhp = bh; } - *bhp = bh; return ret; } @@ -452,7 +453,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) if (buffer_uptodate(first_bh)) goto out; if (!buffer_locked(first_bh)) - ll_rw_block(REQ_OP_READ, REQ_META, 1, &first_bh); + ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, &first_bh); dblock++; extlen--; @@ -461,7 +462,9 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) bh = gfs2_getbuf(gl, dblock, CREATE); if (!buffer_uptodate(bh) && !buffer_locked(bh)) - ll_rw_block(REQ_OP_READ, REQ_RAHEAD | REQ_META, 1, &bh); + ll_rw_block(REQ_OP_READ, + REQ_RAHEAD | REQ_META | REQ_PRIO, + 1, &bh); brelse(bh); dblock++; extlen--; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index e76058d34b7468b3762a6955f401af822c7a8e9a..a3711f543405218ddc6f88c45d60505955f11740 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -242,7 +242,7 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent) bio = bio_alloc(GFP_NOFS, 1); bio->bi_iter.bi_sector = sector * (sb->s_blocksize >> 9); - bio->bi_bdev = sb->s_bdev; + bio_set_dev(bio, sb->s_bdev); bio_add_page(bio, page, PAGE_SIZE, 0); bio->bi_end_io = end_bio_io_page; @@ -1037,7 +1037,7 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp) char ro[20]; char spectator[20]; char *envp[] = { ro, spectator, NULL }; - sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0); + sprintf(ro, "RDONLY=%d", sb_rdonly(sb)); sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp); } @@ -1113,7 +1113,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent return error; } - snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s", sdp->sd_table_name); + snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s", sdp->sd_table_name); error = gfs2_sys_fs_add(sdp); /* @@ -1159,10 +1159,10 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent } if (sdp->sd_args.ar_spectator) - snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.s", + snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s.s", sdp->sd_table_name); else - snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.%u", + snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s.%u", sdp->sd_table_name, sdp->sd_lockstruct.ls_jid); error = init_inodes(sdp, DO); @@ -1179,7 +1179,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent goto fail_per_node; } - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { error = gfs2_make_fs_rw(sdp); if (error) { fs_err(sdp, "can't make FS RW: %d\n", error); @@ -1388,7 +1388,6 @@ static void gfs2_kill_sb(struct super_block *sb) sdp->sd_root_dir = NULL; sdp->sd_master_dir = NULL; shrink_dcache_sb(sb); - gfs2_delete_debugfs_file(sdp); free_percpu(sdp->sd_lkstats); kill_block_super(sb); } diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c2ca9566b7647e21adcf224af55172eb709221f5..e700fb16266474e4a39708244ddecb26ebb23367 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -452,7 +452,7 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) *qdp = NULL; - if (sdp->sd_vfs->s_flags & MS_RDONLY) + if (sb_rdonly(sdp->sd_vfs)) return 0; spin_lock(&qd_lock); @@ -730,7 +730,7 @@ static int gfs2_write_buf_to_page(struct gfs2_inode *ip, unsigned long index, if (PageUptodate(page)) set_buffer_uptodate(bh); if (!buffer_uptodate(bh)) { - ll_rw_block(REQ_OP_READ, REQ_META, 1, &bh); + ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, &bh); wait_on_buffer(bh); if (!buffer_uptodate(bh)) goto unlock_out; @@ -1474,8 +1474,11 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error) { if (error == 0 || error == -EROFS) return; - if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error); + sdp->sd_log_error = error; + wake_up(&sdp->sd_logd_waitq); + } } static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg, diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 113b6095a58dd000e2d2c23e71435a1d065fbfb9..9395a3db1a601461e525ad116e8cfb58805965bd 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -522,7 +522,7 @@ void gfs2_recover_func(struct work_struct *work) if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) ro = 1; } else { - if (sdp->sd_vfs->s_flags & MS_RDONLY) { + if (sb_rdonly(sdp->sd_vfs)) { /* check if device itself is read-only */ ro = bdev_read_only(sdp->sd_vfs->s_bdev); if (!ro) { diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 836e38ba5d0af328523b5760ae8f6578256e2a4f..95b2a57ded3300a5c2d8b4d351bdfebc04aa151c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -705,8 +705,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) rb_erase(n, &sdp->sd_rindex_tree); if (gl) { - glock_set_object(gl, NULL); - gfs2_glock_add_to_lru(gl); + glock_clear_object(gl, rgd); gfs2_glock_put(gl); } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index fdedec379b78bcfdb067e9bfeaa6b63cdc939cea..8e54f2e3a3040e19052a14cfd593644f3309c1e0 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -893,7 +893,7 @@ static void gfs2_put_super(struct super_block *sb) } spin_unlock(&sdp->sd_jindex_spin); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { error = gfs2_make_fs_ro(sdp); if (error) gfs2_io_error(sdp); @@ -924,6 +924,7 @@ static void gfs2_put_super(struct super_block *sb) gfs2_jindex_free(sdp); /* Take apart glock structures and buffer lists */ gfs2_gl_hash_clear(sdp); + gfs2_delete_debugfs_file(sdp); /* Unmount the locking protocol */ gfs2_lm_unmount(sdp); @@ -943,9 +944,9 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) struct gfs2_sbd *sdp = sb->s_fs_info; gfs2_quota_sync(sb, -1); - if (wait && sdp) + if (wait) gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); - return 0; + return sdp->sd_log_error; } void gfs2_freeze_func(struct work_struct *work) @@ -1295,7 +1296,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) * gfs2_drop_inode - Drop an inode (test for remote unlink) * @inode: The inode to drop * - * If we've received a callback on an iopen lock then its because a + * If we've received a callback on an iopen lock then it's because a * remote node tried to deallocate the inode but failed due to this node * still having the inode open. Here we mark the link count zero * since we know that it must have reached zero if the GLF_DEMOTE flag @@ -1317,6 +1318,23 @@ static int gfs2_drop_inode(struct inode *inode) if (test_bit(GLF_DEMOTE, &gl->gl_flags)) clear_nlink(inode); } + + /* + * When under memory pressure when an inode's link count has dropped to + * zero, defer deleting the inode to the delete workqueue. This avoids + * calling into DLM under memory pressure, which can deadlock. + */ + if (!inode->i_nlink && + unlikely(current->flags & PF_MEMALLOC) && + gfs2_holder_initialized(&ip->i_iopen_gh)) { + struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; + + gfs2_glock_hold(gl); + if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) + gfs2_glock_queue_put(gl); + return false; + } + return generic_drop_inode(inode); } @@ -1500,6 +1518,22 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip) return error; } +/** + * gfs2_glock_put_eventually + * @gl: The glock to put + * + * When under memory pressure, trigger a deferred glock put to make sure we + * won't call into DLM and deadlock. Otherwise, put the glock directly. + */ + +static void gfs2_glock_put_eventually(struct gfs2_glock *gl) +{ + if (current->flags & PF_MEMALLOC) + gfs2_glock_queue_put(gl); + else + gfs2_glock_put(gl); +} + /** * gfs2_evict_inode - Remove an inode from cache * @inode: The inode to evict @@ -1535,7 +1569,7 @@ static void gfs2_evict_inode(struct inode *inode) return; } - if (inode->i_nlink || (sb->s_flags & MS_RDONLY)) + if (inode->i_nlink || sb_rdonly(sb)) goto out; if (test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) { @@ -1544,9 +1578,14 @@ static void gfs2_evict_inode(struct inode *inode) goto alloc_failed; } + /* Deletes should never happen under memory pressure anymore. */ + if (WARN_ON_ONCE(current->flags & PF_MEMALLOC)) + goto out; + /* Must not read inode block until block type has been verified */ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); if (unlikely(error)) { + glock_clear_object(ip->i_iopen_gh.gh_gl, ip); ip->i_iopen_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&ip->i_iopen_gh); goto out; @@ -1562,6 +1601,12 @@ static void gfs2_evict_inode(struct inode *inode) goto out_truncate; } + /* + * The inode may have been recreated in the meantime. + */ + if (inode->i_nlink) + goto out_truncate; + alloc_failed: if (gfs2_holder_initialized(&ip->i_iopen_gh) && test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { @@ -1595,6 +1640,11 @@ static void gfs2_evict_inode(struct inode *inode) goto out_unlock; } + /* We're about to clear the bitmap for the dinode, but as soon as we + do, gfs2_create_inode can create another inode at the same block + location and try to set gl_object again. We clear gl_object here so + that subsequent inode creates don't see an old gl_object. */ + glock_clear_object(ip->i_gl, ip); error = gfs2_dinode_dealloc(ip); goto out_unlock; @@ -1623,14 +1673,17 @@ static void gfs2_evict_inode(struct inode *inode) gfs2_rs_deltree(&ip->i_res); if (gfs2_holder_initialized(&ip->i_iopen_gh)) { + glock_clear_object(ip->i_iopen_gh.gh_gl, ip); if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { ip->i_iopen_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq(&ip->i_iopen_gh); } gfs2_holder_uninit(&ip->i_iopen_gh); } - if (gfs2_holder_initialized(&gh)) + if (gfs2_holder_initialized(&gh)) { + glock_clear_object(ip->i_gl, ip); gfs2_glock_dq_uninit(&gh); + } if (error && error != GLR_TRYFAILED && error != -EROFS) fs_warn(sdp, "gfs2_evict_inode: %d\n", error); out: @@ -1640,15 +1693,19 @@ static void gfs2_evict_inode(struct inode *inode) gfs2_ordered_del_inode(ip); clear_inode(inode); gfs2_dir_hash_inval(ip); - glock_set_object(ip->i_gl, NULL); + glock_clear_object(ip->i_gl, ip); wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE); gfs2_glock_add_to_lru(ip->i_gl); - gfs2_glock_put(ip->i_gl); + gfs2_glock_put_eventually(ip->i_gl); ip->i_gl = NULL; if (gfs2_holder_initialized(&ip->i_iopen_gh)) { - glock_set_object(ip->i_iopen_gh.gh_gl, NULL); + struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; + + glock_clear_object(gl, ip); ip->i_iopen_gh.gh_flags |= GL_NOCACHE; + gfs2_glock_hold(gl); gfs2_glock_dq_uninit(&ip->i_iopen_gh); + gfs2_glock_put_eventually(gl); } } diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index ca1f97ff898c951f495b555cf067203d3365ff43..9eb9d0a1abd98bd914cf71dbbd9296c690417ebc 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -645,7 +645,7 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) char *envp[] = { ro, spectator, NULL }; int sysfs_frees_sdp = 0; - sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0); + sprintf(ro, "RDONLY=%d", sb_rdonly(sb)); sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); sdp->sd_kobj.kset = gfs2_kset; diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index c81295f407f653aa0dc66bc5b0f609588d6cdd07..3926f95a6eb7070484131bb01117249f2f94094a 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h @@ -151,6 +151,7 @@ extern struct kmem_cache *gfs2_rgrpd_cachep; extern struct kmem_cache *gfs2_quotad_cachep; extern struct kmem_cache *gfs2_qadata_cachep; extern mempool_t *gfs2_page_pool; +extern struct workqueue_struct *gfs2_control_wq; static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, unsigned int *p) diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 54179554c7d28b3800c95f4f9bb298650c387054..ea09e41dbb49c2079bedd285bdccc3e38101edaa 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -25,6 +25,7 @@ #include "meta_io.h" #include "quota.h" #include "rgrp.h" +#include "super.h" #include "trans.h" #include "util.h" @@ -1209,8 +1210,12 @@ int __gfs2_xattr_set(struct inode *inode, const char *name, if (namel > GFS2_EA_MAX_NAME_LEN) return -ERANGE; - if (value == NULL) - return gfs2_xattr_remove(ip, type, name); + if (value == NULL) { + error = gfs2_xattr_remove(ip, type, name); + if (error == -ENODATA && !(flags & XATTR_REPLACE)) + error = 0; + return error; + } if (ea_check_size(sdp, namel, size)) return -ERANGE; diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index bfbba799430f1575d6e80b21f2159fe0fbe5968a..2538b49cc349e969e0695b3373f7e22849528264 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -656,7 +656,7 @@ static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end, struct super_block * sb; int ret, err; - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(filp, start, end); if (ret) return ret; inode_lock(inode); diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 482081bcdf70c86da21f22ca1c443373b7327180..894994d2c88501cfb27fc1f46561fcc21e4e0d1e 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c @@ -210,7 +210,7 @@ int hfs_mdb_get(struct super_block *sb) pr_warn("filesystem is marked locked, mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { /* Mark the volume uncleanly unmounted in case we crash */ attrib &= cpu_to_be16(~HFS_SB_ATTRIB_UNMNT); attrib |= cpu_to_be16(HFS_SB_ATTRIB_INCNSTNT); @@ -259,7 +259,7 @@ void hfs_mdb_commit(struct super_block *sb) { struct hfs_mdb *mdb = HFS_SB(sb)->mdb; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; lock_buffer(HFS_SB(sb)->mdb_bh); @@ -334,7 +334,7 @@ void hfs_mdb_commit(struct super_block *sb) void hfs_mdb_close(struct super_block *sb) { /* update volume attributes */ - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; HFS_SB(sb)->mdb->drAtrb |= cpu_to_be16(HFS_SB_ATTRIB_UNMNT); HFS_SB(sb)->mdb->drAtrb &= cpu_to_be16(~HFS_SB_ATTRIB_INCNSTNT); diff --git a/fs/hfs/super.c b/fs/hfs/super.c index bf6304a350a6b58351947b8a96998623e380aad1..7e0d65e9586c7dae01d929bfe2e5b6ba373d20c5 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -71,7 +71,7 @@ void hfs_mark_mdb_dirty(struct super_block *sb) struct hfs_sb_info *sbi = HFS_SB(sb); unsigned long delay; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; spin_lock(&sbi->work_lock); @@ -115,7 +115,7 @@ static int hfs_remount(struct super_block *sb, int *flags, char *data) { sync_filesystem(sb); *flags |= MS_NODIRATIME; - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) return 0; if (!(*flags & MS_RDONLY)) { if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) { diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index e8638d528195196232cc858f77d664e4fe79044e..4f26b687713052286ad5baa98c7c7ca4cb61edc3 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -283,7 +283,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); int error = 0, error2; - error = filemap_write_and_wait_range(inode->i_mapping, start, end); + error = file_write_and_wait_range(file, start, end); if (error) return error; inode_lock(inode); diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 67aedf4c2e7c5b6a82f1caf4ef861549b31b5581..e5bb2de2262ae68c64a061673f93220ae8872383 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -264,7 +264,7 @@ void hfsplus_mark_mdb_dirty(struct super_block *sb) struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); unsigned long delay; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; spin_lock(&sbi->work_lock); @@ -284,7 +284,7 @@ static void hfsplus_put_super(struct super_block *sb) cancel_delayed_work_sync(&sbi->sync_work); - if (!(sb->s_flags & MS_RDONLY) && sbi->s_vhdr) { + if (!sb_rdonly(sb) && sbi->s_vhdr) { struct hfsplus_vh *vhdr = sbi->s_vhdr; vhdr->modify_date = hfsp_now2mt(); @@ -329,7 +329,7 @@ static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf) static int hfsplus_remount(struct super_block *sb, int *flags, char *data) { sync_filesystem(sb); - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) return 0; if (!(*flags & MS_RDONLY)) { struct hfsplus_vh *vhdr = HFSPLUS_SB(sb)->s_vhdr; @@ -462,7 +462,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) pr_warn("Filesystem is marked locked, mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && - !(sb->s_flags & MS_RDONLY)) { + !sb_rdonly(sb)) { pr_warn("write access to a journaled filesystem is not supported, use the force option at your own risk, mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } @@ -535,7 +535,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) } else hfs_find_exit(&fd); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { /* * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused * all three are registered with Apple for our use diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index e254fa0f069710aae74e88f41484de4d39ef7d0a..10032b919a85c21be47678d7117d61f49fcc81b2 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -65,7 +65,7 @@ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, bio = bio_alloc(GFP_NOIO, 1); bio->bi_iter.bi_sector = sector; - bio->bi_bdev = sb->s_bdev; + bio_set_dev(bio, sb->s_bdev); bio_set_op_attrs(bio, op, op_flags); if (op != WRITE && data) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e61261a7417e57cc49a784c5a54b8a15f92bd352..c148e7f4f45197181f0e4a8b4763ed1beae090c3 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -374,7 +374,7 @@ static int hostfs_fsync(struct file *file, loff_t start, loff_t end, struct inode *inode = file->f_mapping->host; int ret; - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(file, start, end); if (ret) return ret; diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c index d6a4b55d2ab0512aa34221564f7cff421be0e152..098bf0f4f386613c8502c7503ae9a237f28579b1 100644 --- a/fs/hpfs/alloc.c +++ b/fs/hpfs/alloc.c @@ -538,7 +538,7 @@ int hpfs_trim_fs(struct super_block *s, u64 start, u64 end, u64 minlen, unsigned return 0; if (start < sbi->sb_dirband_start + sbi->sb_dirband_size && end > sbi->sb_dirband_start) { hpfs_lock(s); - if (s->s_flags & MS_RDONLY) { + if (sb_rdonly(s)) { err = -EROFS; goto unlock_1; } @@ -559,7 +559,7 @@ int hpfs_trim_fs(struct super_block *s, u64 start, u64 end, u64 minlen, unsigned end_bmp = (end + 0x3fff) >> 14; while (start_bmp < end_bmp && !err) { hpfs_lock(s); - if (s->s_flags & MS_RDONLY) { + if (sb_rdonly(s)) { err = -EROFS; goto unlock_2; } diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 7b9150c2e75c4c4a2d9de1fc8c3d05637791bcf3..fa6bbb4f509f43bd8ec51c27c34f3f349d40013b 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c @@ -264,7 +264,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in hpfs_result = hpfs_i(result); if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino; - if (de->has_acl || de->has_xtd_perm) if (!(dir->i_sb->s_flags & MS_RDONLY)) { + if (de->has_acl || de->has_xtd_perm) if (!sb_rdonly(dir->i_sb)) { hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures"); goto bail1; } diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index b3be1b5a62e213f0d8def5b5f4dd51d399567199..f26138425b16edec599f27df730b82b00fd8589c 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -24,7 +24,7 @@ int hpfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct inode *inode = file->f_mapping->host; int ret; - ret = filemap_write_and_wait_range(file->f_mapping, start, end); + ret = file_write_and_wait_range(file, start, end); if (ret) return ret; return sync_blockdev(inode->i_sb->s_bdev); diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 82067ca22f2b909609162c7dc413a93c68aebaa0..1516fb4e28f409d045e00685b4a2c55732c088f0 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -21,7 +21,7 @@ static void mark_dirty(struct super_block *s, int remount) { - if (hpfs_sb(s)->sb_chkdsk && (remount || !(s->s_flags & MS_RDONLY))) { + if (hpfs_sb(s)->sb_chkdsk && (remount || !sb_rdonly(s))) { struct buffer_head *bh; struct hpfs_spare_block *sb; if ((sb = hpfs_map_sector(s, 17, &bh, 0))) { @@ -41,7 +41,7 @@ static void unmark_dirty(struct super_block *s) { struct buffer_head *bh; struct hpfs_spare_block *sb; - if (s->s_flags & MS_RDONLY) return; + if (sb_rdonly(s)) return; sync_blockdev(s->s_bdev); if ((sb = hpfs_map_sector(s, 17, &bh, 0))) { sb->dirty = hpfs_sb(s)->sb_chkdsk > 1 - hpfs_sb(s)->sb_was_error; @@ -73,14 +73,14 @@ void hpfs_error(struct super_block *s, const char *fmt, ...) mark_dirty(s, 0); panic("HPFS panic"); } else if (hpfs_sb(s)->sb_err == 1) { - if (s->s_flags & MS_RDONLY) + if (sb_rdonly(s)) pr_cont("; already mounted read-only\n"); else { pr_cont("; remounting read-only\n"); mark_dirty(s, 0); s->s_flags |= MS_RDONLY; } - } else if (s->s_flags & MS_RDONLY) + } else if (sb_rdonly(s)) pr_cont("; going on - but anything won't be destroyed because it's read-only\n"); else pr_cont("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n"); @@ -607,8 +607,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) } /* Check version */ - if (!(s->s_flags & MS_RDONLY) && - superblock->funcversion != 2 && superblock->funcversion != 3) { + if (!sb_rdonly(s) && superblock->funcversion != 2 && superblock->funcversion != 3) { pr_err("Bad version %d,%d. Mount readonly to go around\n", (int)superblock->version, (int)superblock->funcversion); pr_err("please try recent version of HPFS driver at http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi and if it still can't understand this format, contact author - mikulas@artax.karlin.mff.cuni.cz\n"); @@ -666,7 +665,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) hpfs_error(s, "improperly stopped"); } - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { spareblock->dirty = 1; spareblock->old_wrote = 0; mark_buffer_dirty(bh2); diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 28d2753be09498769282facb66593c95b91f498a..59073e9f01a410f29150a3abf0087ac28409ad5b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -334,7 +334,7 @@ static void remove_huge_page(struct page *page) } static void -hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end) +hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end) { struct vm_area_struct *vma; @@ -401,9 +401,8 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, const pgoff_t end = lend >> huge_page_shift(h); struct vm_area_struct pseudo_vma; struct pagevec pvec; - pgoff_t next; + pgoff_t next, index; int i, freed = 0; - long lookup_nr = PAGEVEC_SIZE; bool truncate_op = (lend == LLONG_MAX); memset(&pseudo_vma, 0, sizeof(struct vm_area_struct)); @@ -411,34 +410,20 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, pagevec_init(&pvec, 0); next = start; while (next < end) { - /* - * Don't grab more pages than the number left in the range. - */ - if (end - next < lookup_nr) - lookup_nr = end - next; - /* * When no more pages are found, we are done. */ - if (!pagevec_lookup(&pvec, mapping, next, lookup_nr)) + if (!pagevec_lookup_range(&pvec, mapping, &next, end - 1)) break; for (i = 0; i < pagevec_count(&pvec); ++i) { struct page *page = pvec.pages[i]; u32 hash; - /* - * The page (index) could be beyond end. This is - * only possible in the punch hole case as end is - * max page offset in the truncate case. - */ - next = page->index; - if (next >= end) - break; - + index = page->index; hash = hugetlb_fault_mutex_hash(h, current->mm, &pseudo_vma, - mapping, next, 0); + mapping, index, 0); mutex_lock(&hugetlb_fault_mutex_table[hash]); /* @@ -455,8 +440,8 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, i_mmap_lock_write(mapping); hugetlb_vmdelete_list(&mapping->i_mmap, - next * pages_per_huge_page(h), - (next + 1) * pages_per_huge_page(h)); + index * pages_per_huge_page(h), + (index + 1) * pages_per_huge_page(h)); i_mmap_unlock_write(mapping); } @@ -475,14 +460,13 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, freed++; if (!truncate_op) { if (unlikely(hugetlb_unreserve_pages(inode, - next, next + 1, 1))) + index, index + 1, 1))) hugetlb_fix_reserve_counts(inode); } unlock_page(page); mutex_unlock(&hugetlb_fault_mutex_table[hash]); } - ++next; huge_pagevec_release(&pvec); cond_resched(); } @@ -514,7 +498,7 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset) i_size_write(inode, offset); i_mmap_lock_write(mapping); - if (!RB_EMPTY_ROOT(&mapping->i_mmap)) + if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root)) hugetlb_vmdelete_list(&mapping->i_mmap, pgoff, 0); i_mmap_unlock_write(mapping); remove_inode_hugepages(inode, offset, LLONG_MAX); @@ -539,7 +523,7 @@ static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) inode_lock(inode); i_mmap_lock_write(mapping); - if (!RB_EMPTY_ROOT(&mapping->i_mmap)) + if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root)) hugetlb_vmdelete_list(&mapping->i_mmap, hole_start >> PAGE_SHIFT, hole_end >> PAGE_SHIFT); @@ -846,7 +830,10 @@ static int hugetlbfs_migrate_page(struct address_space *mapping, rc = migrate_huge_page_move_mapping(mapping, newpage, page); if (rc != MIGRATEPAGE_SUCCESS) return rc; - migrate_page_copy(newpage, page); + if (mode != MIGRATE_SYNC_NO_COPY) + migrate_page_copy(newpage, page); + else + migrate_page_states(newpage, page); return MIGRATEPAGE_SUCCESS; } diff --git a/fs/inode.c b/fs/inode.c index 50370599e37104708b95ede3a627052cc0d910d3..d1e35b53bb23b80db7077500f63eeec9bce6bb28 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -353,7 +353,7 @@ void address_space_init_once(struct address_space *mapping) init_rwsem(&mapping->i_mmap_rwsem); INIT_LIST_HEAD(&mapping->private_list); spin_lock_init(&mapping->private_lock); - mapping->i_mmap = RB_ROOT; + mapping->i_mmap = RB_ROOT_CACHED; } EXPORT_SYMBOL(address_space_init_once); @@ -637,6 +637,7 @@ void evict_inodes(struct super_block *sb) dispose_list(&dispose); } +EXPORT_SYMBOL_GPL(evict_inodes); /** * invalidate_inodes - attempt to free all inodes on a superblock @@ -1569,11 +1570,24 @@ EXPORT_SYMBOL(bmap); static void update_ovl_inode_times(struct dentry *dentry, struct inode *inode, bool rcu) { - if (!rcu) { - struct inode *realinode = d_real_inode(dentry); + struct dentry *upperdentry; - if (unlikely(inode != realinode) && - (!timespec_equal(&inode->i_mtime, &realinode->i_mtime) || + /* + * Nothing to do if in rcu or if non-overlayfs + */ + if (rcu || likely(!(dentry->d_flags & DCACHE_OP_REAL))) + return; + + upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER); + + /* + * If file is on lower then we can't update atime, so no worries about + * stale mtime/ctime. + */ + if (upperdentry) { + struct inode *realinode = d_inode(upperdentry); + + if ((!timespec_equal(&inode->i_mtime, &realinode->i_mtime) || !timespec_equal(&inode->i_ctime, &realinode->i_ctime))) { inode->i_mtime = realinode->i_mtime; inode->i_ctime = realinode->i_ctime; diff --git a/fs/internal.h b/fs/internal.h index 9676fe11c093538d284ec5c2c59e9a2a9e37c1f6..48cee21b4f146f5da86b3e485a1f9c155c33a5fe 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -71,8 +71,10 @@ extern void __init mnt_init(void); extern int __mnt_want_write(struct vfsmount *); extern int __mnt_want_write_file(struct file *); +extern int mnt_want_write_file_path(struct file *); extern void __mnt_drop_write(struct vfsmount *); extern void __mnt_drop_write_file(struct file *); +extern void mnt_drop_write_file_path(struct file *); /* * fs_struct.c @@ -132,7 +134,6 @@ static inline bool atime_needs_update_rcu(const struct path *path, extern void inode_io_list_del(struct inode *inode); extern long get_nr_dirty_inodes(void); -extern void evict_inodes(struct super_block *); extern int invalidate_inodes(struct super_block *, bool); /* diff --git a/fs/iomap.c b/fs/iomap.c index 039266128b7ff0b09ed2a55e621a9a0dc9e38720..be61cf742b5ed1d0d201ff415e9355fa2684508c 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -278,7 +278,7 @@ iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data, unsigned long bytes; /* Bytes to write to page */ offset = (pos & (PAGE_SIZE - 1)); - bytes = min_t(unsigned long, PAGE_SIZE - offset, length); + bytes = min_t(loff_t, PAGE_SIZE - offset, length); rpage = __iomap_read_page(inode, pos); if (IS_ERR(rpage)) @@ -373,7 +373,7 @@ iomap_zero_range_actor(struct inode *inode, loff_t pos, loff_t count, unsigned offset, bytes; offset = pos & (PAGE_SIZE - 1); /* Within page */ - bytes = min_t(unsigned, PAGE_SIZE - offset, count); + bytes = min_t(loff_t, PAGE_SIZE - offset, count); if (IS_DAX(inode)) status = iomap_dax_zero(pos, offset, bytes, iomap); @@ -477,10 +477,10 @@ int iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops) set_page_dirty(page); wait_for_stable_page(page); - return 0; + return VM_FAULT_LOCKED; out_unlock: unlock_page(page); - return ret; + return block_page_mkwrite_return(ret); } EXPORT_SYMBOL_GPL(iomap_page_mkwrite); @@ -713,8 +713,24 @@ struct iomap_dio { static ssize_t iomap_dio_complete(struct iomap_dio *dio) { struct kiocb *iocb = dio->iocb; + struct inode *inode = file_inode(iocb->ki_filp); ssize_t ret; + /* + * Try again to invalidate clean pages which might have been cached by + * non-direct readahead, or faulted in by get_user_pages() if the source + * of the write was an mmap'ed region of the file we're writing. Either + * one is a pretty crazy thing to do, so we don't support it 100%. If + * this invalidation fails, tough, the write still worked... + */ + if (!dio->error && + (dio->flags & IOMAP_DIO_WRITE) && inode->i_mapping->nrpages) { + ret = invalidate_inode_pages2_range(inode->i_mapping, + iocb->ki_pos >> PAGE_SHIFT, + (iocb->ki_pos + dio->size - 1) >> PAGE_SHIFT); + WARN_ON_ONCE(ret); + } + if (dio->end_io) { ret = dio->end_io(iocb, dio->error ? dio->error : dio->size, @@ -805,7 +821,7 @@ iomap_dio_zero(struct iomap_dio *dio, struct iomap *iomap, loff_t pos, struct bio *bio; bio = bio_alloc(GFP_KERNEL, 1); - bio->bi_bdev = iomap->bdev; + bio_set_dev(bio, iomap->bdev); bio->bi_iter.bi_sector = iomap->blkno + ((pos - iomap->offset) >> 9); bio->bi_private = dio; @@ -884,7 +900,7 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length, return 0; bio = bio_alloc(GFP_KERNEL, nr_pages); - bio->bi_bdev = iomap->bdev; + bio_set_dev(bio, iomap->bdev); bio->bi_iter.bi_sector = iomap->blkno + ((pos - iomap->offset) >> 9); bio->bi_write_hint = dio->iocb->ki_hint; @@ -993,6 +1009,13 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, WARN_ON_ONCE(ret); ret = 0; + if (iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) && + !inode->i_sb->s_dio_done_wq) { + ret = sb_init_dio_done_wq(inode->i_sb); + if (ret < 0) + goto out_free_dio; + } + inode_dio_begin(inode); blk_start_plug(&plug); @@ -1015,13 +1038,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, if (ret < 0) iomap_dio_set_error(dio, ret); - if (ret >= 0 && iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) && - !inode->i_sb->s_dio_done_wq) { - ret = sb_init_dio_done_wq(inode->i_sb); - if (ret < 0) - iomap_dio_set_error(dio, ret); - } - if (!atomic_dec_and_test(&dio->ref)) { if (!is_sync_kiocb(iocb)) return -EIOCBQUEUED; @@ -1042,19 +1058,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, ret = iomap_dio_complete(dio); - /* - * Try again to invalidate clean pages which might have been cached by - * non-direct readahead, or faulted in by get_user_pages() if the source - * of the write was an mmap'ed region of the file we're writing. Either - * one is a pretty crazy thing to do, so we don't support it 100%. If - * this invalidation fails, tough, the write still worked... - */ - if (iov_iter_rw(iter) == WRITE) { - int err = invalidate_inode_pages2_range(mapping, - start >> PAGE_SHIFT, end >> PAGE_SHIFT); - WARN_ON_ONCE(err); - } - return ret; out_free_dio: diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 217a5e7815da6a896daeddb53d8200dcba56a303..447a24d77b894ef733412ba201cadcaa9a226f7e 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -96,7 +96,7 @@ static int __init init_inodecache(void) 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD|SLAB_ACCOUNT), init_once); - if (isofs_inode_cachep == NULL) + if (!isofs_inode_cachep) return -ENOMEM; return 0; } @@ -514,9 +514,11 @@ static int isofs_show_options(struct seq_file *m, struct dentry *root) if (sbi->s_fmode != ISOFS_INVALID_MODE) seq_printf(m, ",fmode=%o", sbi->s_fmode); +#ifdef CONFIG_JOLIET if (sbi->s_nls_iocharset && strcmp(sbi->s_nls_iocharset->charset, CONFIG_NLS_DEFAULT) != 0) seq_printf(m, ",iocharset=%s", sbi->s_nls_iocharset->charset); +#endif return 0; } @@ -678,7 +680,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) if (isonum_711(vdp->type) == ISO_VD_END) break; if (isonum_711(vdp->type) == ISO_VD_PRIMARY) { - if (pri == NULL) { + if (!pri) { pri = (struct iso_primary_descriptor *)vdp; /* Save the buffer in case we need it ... */ pri_bh = bh; @@ -737,12 +739,12 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) root_found: /* We don't support read-write mounts */ - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { error = -EACCES; goto out_freebh; } - if (joliet_level && (pri == NULL || !opt.rock)) { + if (joliet_level && (!pri || !opt.rock)) { /* This is the case of Joliet with the norock mount flag. * A disc with both Joliet and Rock Ridge is handled later */ @@ -1298,7 +1300,7 @@ static int isofs_read_inode(struct inode *inode, int relocated) unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); unsigned long block; int high_sierra = sbi->s_high_sierra; - struct buffer_head *bh = NULL; + struct buffer_head *bh; struct iso_directory_record *de; struct iso_directory_record *tmpde = NULL; unsigned int de_len; @@ -1320,8 +1322,7 @@ static int isofs_read_inode(struct inode *inode, int relocated) int frag1 = bufsize - offset; tmpde = kmalloc(de_len, GFP_KERNEL); - if (tmpde == NULL) { - printk(KERN_INFO "%s: out of memory\n", __func__); + if (!tmpde) { ret = -ENOMEM; goto fail; } diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index c12476e309c67c26883d5d2ae95166595359d5ab..bd0428bebe9b7787089135ddc4094800f86882a0 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -35,7 +35,7 @@ int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync) struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); int ret; - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + ret = file_write_and_wait_range(filp, start, end); if (ret) return ret; diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 76fa814df3d1bfcacb3caea51cbaa9711854e120..e96c6b05e43e786ae2dc61bd2cea74fc88631887 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -395,14 +395,14 @@ int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data) { struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); - if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY)) + if (c->flags & JFFS2_SB_FLAG_RO && !sb_rdonly(sb)) return -EROFS; /* We stop if it was running, then restart if it needs to. This also catches the case where it was stopped and this is just a remount to restart it. Flush the writebuffer, if neccecary, else we loose it */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { jffs2_stop_garbage_collect_thread(c); mutex_lock(&c->alloc_sem); jffs2_flush_wbuf_pad(c); @@ -590,7 +590,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) sb->s_blocksize = PAGE_SIZE; sb->s_blocksize_bits = PAGE_SHIFT; sb->s_magic = JFFS2_SUPER_MAGIC; - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) jffs2_start_garbage_collect_thread(c); return 0; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 5ef21f4c4c77d12aa401eea175235cc85e0d6aa6..153f1c6eb16932a9b87fc9a3ecd2e06b5955c245 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -342,7 +342,7 @@ static void jffs2_put_super (struct super_block *sb) static void jffs2_kill_sb(struct super_block *sb) { struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) jffs2_stop_garbage_collect_thread(c); kill_mtd_super(sb); kfree(c); diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index b25d28a21212d25fa1674e0ebc56d2dceda4ec34..2cfe487708e08f268c166053927eafec9c68eac6 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -1162,7 +1162,7 @@ static void delayed_wbuf_sync(struct work_struct *work) struct jffs2_sb_info *c = work_to_sb(work); struct super_block *sb = OFNI_BS_2SFFJ(c); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { jffs2_dbg(1, "%s()\n", __func__); jffs2_flush_wbuf_gc(c, 0); } @@ -1173,7 +1173,7 @@ void jffs2_dirty_trigger(struct jffs2_sb_info *c) struct super_block *sb = OFNI_BS_2SFFJ(c); unsigned long delay; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; delay = msecs_to_jiffies(dirty_writeback_interval * 10); diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 739492c7a3fd9b79b356053e778d9859694ae7fe..36665fd37095ede8da84292e245d4265cf52aabc 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -34,7 +34,7 @@ int jfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct inode *inode = file->f_mapping->host; int rc = 0; - rc = filemap_write_and_wait_range(inode->i_mapping, start, end); + rc = file_write_and_wait_range(file, start, end); if (rc) return rc; diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index a21f0e9eecd45ef34765a4ae567cd4e3df498dbf..0e5d412c0b01a45cdc67a164f471e8b8b4a193c9 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1995,7 +1995,7 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) bio = bio_alloc(GFP_NOFS, 1); bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9); - bio->bi_bdev = log->bdev; + bio_set_dev(bio, log->bdev); bio_add_page(bio, bp->l_page, LOGPSIZE, bp->l_offset); BUG_ON(bio->bi_iter.bi_size != LOGPSIZE); @@ -2139,7 +2139,7 @@ static void lbmStartIO(struct lbuf * bp) bio = bio_alloc(GFP_NOFS, 1); bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9); - bio->bi_bdev = log->bdev; + bio_set_dev(bio, log->bdev); bio_add_page(bio, bp->l_page, LOGPSIZE, bp->l_offset); BUG_ON(bio->bi_iter.bi_size != LOGPSIZE); diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 65120a4717290ae3ec109cb116172e7f091f9f79..1c4b9ad4d7ab66446dae9241f44abe69429d33fb 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -430,7 +430,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) len = min(xlen, (int)JFS_SBI(inode->i_sb)->nbperpage); bio = bio_alloc(GFP_NOFS, 1); - bio->bi_bdev = inode->i_sb->s_bdev; + bio_set_dev(bio, inode->i_sb->s_bdev); bio->bi_iter.bi_sector = pblock << (inode->i_blkbits - 9); bio->bi_end_io = metapage_write_end_io; bio->bi_private = page; @@ -510,7 +510,7 @@ static int metapage_readpage(struct file *fp, struct page *page) submit_bio(bio); bio = bio_alloc(GFP_NOFS, 1); - bio->bi_bdev = inode->i_sb->s_bdev; + bio_set_dev(bio, inode->i_sb->s_bdev); bio->bi_iter.bi_sector = pblock << (inode->i_blkbits - 9); bio->bi_end_io = metapage_read_end_io; diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index 9895595fd2f24c5e3128c0138c554430a73e48d8..d8658607bf46855bf338179551da155d71bccb44 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c @@ -362,7 +362,7 @@ static int chkSuper(struct super_block *sb) /* validate fs state */ if (j_sb->s_state != cpu_to_le32(FM_CLEAN) && - !(sb->s_flags & MS_RDONLY)) { + !sb_rdonly(sb)) { jfs_err("jfs_mount: Mount Failure: File System Dirty."); rc = -EINVAL; goto out; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 78b41e1d5c67151744fb1c98bf1af54560593457..2f14677169c374b7b0dfaedf6e4027464d42916d 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -76,7 +76,7 @@ static void jfs_handle_error(struct super_block *sb) { struct jfs_sb_info *sbi = JFS_SBI(sb); - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; updateSuper(sb, FM_DIRTY); @@ -468,7 +468,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) return -EINVAL; if (newLVSize) { - if (sb->s_flags & MS_RDONLY) { + if (sb_rdonly(sb)) { pr_err("JFS: resize requires volume to be mounted read-write\n"); return -EROFS; } @@ -477,7 +477,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) return rc; } - if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { + if (sb_rdonly(sb) && !(*flags & MS_RDONLY)) { /* * Invalidate any previously read metadata. fsck may have * changed the on-disk data since we mounted r/o @@ -493,7 +493,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) dquot_resume(sb, -1); return ret; } - if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { + if (!sb_rdonly(sb) && (*flags & MS_RDONLY)) { rc = dquot_suspend(sb, -1); if (rc < 0) return rc; @@ -502,7 +502,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) return rc; } if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY)) - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { rc = jfs_umount_rw(sb); if (rc) return rc; @@ -592,7 +592,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) jfs_err("jfs_mount failed w/return code = %d", rc); goto out_mount_failed; } - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) sbi->log = NULL; else { rc = jfs_mount_rw(sb, 0); @@ -619,16 +619,10 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) if (!sb->s_root) goto out_no_root; - /* logical blocks are represented by 40 bits in pxd_t, etc. */ - sb->s_maxbytes = ((u64) sb->s_blocksize) << 40; -#if BITS_PER_LONG == 32 - /* - * Page cache is indexed by long. - * I would use MAX_LFS_FILESIZE, but it's only half as big + /* logical blocks are represented by 40 bits in pxd_t, etc. + * and page cache is indexed by long */ - sb->s_maxbytes = min(((u64) PAGE_SIZE << 32) - 1, - (u64)sb->s_maxbytes); -#endif + sb->s_maxbytes = min(((loff_t)sb->s_blocksize) << 40, MAX_LFS_FILESIZE); sb->s_time_gran = 1; return 0; @@ -658,7 +652,7 @@ static int jfs_freeze(struct super_block *sb) struct jfs_log *log = sbi->log; int rc = 0; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { txQuiesce(sb); rc = lmLogShutdown(log); if (rc) { @@ -688,7 +682,7 @@ static int jfs_unfreeze(struct super_block *sb) struct jfs_log *log = sbi->log; int rc = 0; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { rc = updateSuper(sb, FM_MOUNT); if (rc) { jfs_error(sb, "updateSuper failed\n"); diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index db5900aaa55a47c7d804ac8a51072a577298f517..89d1dc19340b09d4d9cd9db44ae3dfc9413bea98 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -21,6 +21,7 @@ DEFINE_MUTEX(kernfs_mutex); static DEFINE_SPINLOCK(kernfs_rename_lock); /* kn->parent and ->name */ static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by rename_lock */ +static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) @@ -507,6 +508,10 @@ void kernfs_put(struct kernfs_node *kn) struct kernfs_node *parent; struct kernfs_root *root; + /* + * kernfs_node is freed with ->count 0, kernfs_find_and_get_node_by_ino + * depends on this to filter reused stale node + */ if (!kn || !atomic_dec_and_test(&kn->count)) return; root = kernfs_root(kn); @@ -533,7 +538,9 @@ void kernfs_put(struct kernfs_node *kn) simple_xattrs_free(&kn->iattr->xattrs); } kfree(kn->iattr); - ida_simple_remove(&root->ino_ida, kn->ino); + spin_lock(&kernfs_idr_lock); + idr_remove(&root->ino_idr, kn->id.ino); + spin_unlock(&kernfs_idr_lock); kmem_cache_free(kernfs_node_cache, kn); kn = parent; @@ -542,7 +549,7 @@ void kernfs_put(struct kernfs_node *kn) goto repeat; } else { /* just released the root kn, free @root too */ - ida_destroy(&root->ino_ida); + idr_destroy(&root->ino_idr); kfree(root); } } @@ -559,7 +566,7 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) if (d_really_is_negative(dentry)) goto out_bad_unlocked; - kn = dentry->d_fsdata; + kn = kernfs_dentry_node(dentry); mutex_lock(&kernfs_mutex); /* The kernfs node has been deactivated */ @@ -567,7 +574,7 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) goto out_bad; /* The kernfs node has been moved? */ - if (dentry->d_parent->d_fsdata != kn->parent) + if (kernfs_dentry_node(dentry->d_parent) != kn->parent) goto out_bad; /* The kernfs node has been renamed */ @@ -587,14 +594,8 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) return 0; } -static void kernfs_dop_release(struct dentry *dentry) -{ - kernfs_put(dentry->d_fsdata); -} - const struct dentry_operations kernfs_dops = { .d_revalidate = kernfs_dop_revalidate, - .d_release = kernfs_dop_release, }; /** @@ -610,8 +611,9 @@ const struct dentry_operations kernfs_dops = { */ struct kernfs_node *kernfs_node_from_dentry(struct dentry *dentry) { - if (dentry->d_sb->s_op == &kernfs_sops) - return dentry->d_fsdata; + if (dentry->d_sb->s_op == &kernfs_sops && + !d_really_is_negative(dentry)) + return kernfs_dentry_node(dentry); return NULL; } @@ -620,6 +622,8 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, unsigned flags) { struct kernfs_node *kn; + u32 gen; + int cursor; int ret; name = kstrdup_const(name, GFP_KERNEL); @@ -630,11 +634,25 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, if (!kn) goto err_out1; - ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); + idr_preload(GFP_KERNEL); + spin_lock(&kernfs_idr_lock); + cursor = idr_get_cursor(&root->ino_idr); + ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC); + if (ret >= 0 && ret < cursor) + root->next_generation++; + gen = root->next_generation; + spin_unlock(&kernfs_idr_lock); + idr_preload_end(); if (ret < 0) goto err_out2; - kn->ino = ret; + kn->id.ino = ret; + kn->id.generation = gen; + /* + * set ino first. This barrier is paired with atomic_inc_not_zero in + * kernfs_find_and_get_node_by_ino + */ + smp_mb__before_atomic(); atomic_set(&kn->count, 1); atomic_set(&kn->active, KN_DEACTIVATED_BIAS); RB_CLEAR_NODE(&kn->rb); @@ -666,6 +684,54 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, return kn; } +/* + * kernfs_find_and_get_node_by_ino - get kernfs_node from inode number + * @root: the kernfs root + * @ino: inode number + * + * RETURNS: + * NULL on failure. Return a kernfs node with reference counter incremented + */ +struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root, + unsigned int ino) +{ + struct kernfs_node *kn; + + rcu_read_lock(); + kn = idr_find(&root->ino_idr, ino); + if (!kn) + goto out; + + /* + * Since kernfs_node is freed in RCU, it's possible an old node for ino + * is freed, but reused before RCU grace period. But a freed node (see + * kernfs_put) or an incompletedly initialized node (see + * __kernfs_new_node) should have 'count' 0. We can use this fact to + * filter out such node. + */ + if (!atomic_inc_not_zero(&kn->count)) { + kn = NULL; + goto out; + } + + /* + * The node could be a new node or a reused node. If it's a new node, + * we are ok. If it's reused because of RCU (because of + * SLAB_TYPESAFE_BY_RCU), the __kernfs_new_node always sets its 'ino' + * before 'count'. So if 'count' is uptodate, 'ino' should be uptodate, + * hence we can use 'ino' to filter stale node. + */ + if (kn->id.ino != ino) + goto out; + rcu_read_unlock(); + + return kn; +out: + rcu_read_unlock(); + kernfs_put(kn); + return NULL; +} + /** * kernfs_add_one - add kernfs_node to parent without warning * @kn: kernfs_node to be added @@ -875,13 +941,14 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, if (!root) return ERR_PTR(-ENOMEM); - ida_init(&root->ino_ida); + idr_init(&root->ino_idr); INIT_LIST_HEAD(&root->supers); + root->next_generation = 1; kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, KERNFS_DIR); if (!kn) { - ida_destroy(&root->ino_ida); + idr_destroy(&root->ino_idr); kfree(root); return ERR_PTR(-ENOMEM); } @@ -984,7 +1051,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, unsigned int flags) { struct dentry *ret; - struct kernfs_node *parent = dentry->d_parent->d_fsdata; + struct kernfs_node *parent = dir->i_private; struct kernfs_node *kn; struct inode *inode; const void *ns = NULL; @@ -1001,8 +1068,6 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, ret = NULL; goto out_unlock; } - kernfs_get(kn); - dentry->d_fsdata = kn; /* attach dentry and inode */ inode = kernfs_get_inode(dir->i_sb, kn); @@ -1039,7 +1104,7 @@ static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry, static int kernfs_iop_rmdir(struct inode *dir, struct dentry *dentry) { - struct kernfs_node *kn = dentry->d_fsdata; + struct kernfs_node *kn = kernfs_dentry_node(dentry); struct kernfs_syscall_ops *scops = kernfs_root(kn)->syscall_ops; int ret; @@ -1059,7 +1124,7 @@ static int kernfs_iop_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { - struct kernfs_node *kn = old_dentry->d_fsdata; + struct kernfs_node *kn = kernfs_dentry_node(old_dentry); struct kernfs_node *new_parent = new_dir->i_private; struct kernfs_syscall_ops *scops = kernfs_root(kn)->syscall_ops; int ret; @@ -1572,7 +1637,7 @@ static struct kernfs_node *kernfs_dir_next_pos(const void *ns, static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) { struct dentry *dentry = file->f_path.dentry; - struct kernfs_node *parent = dentry->d_fsdata; + struct kernfs_node *parent = kernfs_dentry_node(dentry); struct kernfs_node *pos = file->private_data; const void *ns = NULL; @@ -1589,7 +1654,7 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) const char *name = pos->name; unsigned int type = dt_type(pos); int len = strlen(name); - ino_t ino = pos->ino; + ino_t ino = pos->id.ino; ctx->pos = pos->hash; file->private_data = pos; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index ac2dfe0c5a9c8520aa8b40c4bab97b710799cc78..9698e51656b10b52c7aafccb4a1d5d545eb9acba 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -616,7 +616,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn, static int kernfs_fop_open(struct inode *inode, struct file *file) { - struct kernfs_node *kn = file->f_path.dentry->d_fsdata; + struct kernfs_node *kn = inode->i_private; struct kernfs_root *root = kernfs_root(kn); const struct kernfs_ops *ops; struct kernfs_open_file *of; @@ -768,7 +768,7 @@ static void kernfs_release_file(struct kernfs_node *kn, static int kernfs_fop_release(struct inode *inode, struct file *filp) { - struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; + struct kernfs_node *kn = inode->i_private; struct kernfs_open_file *of = kernfs_of(filp); if (kn->flags & KERNFS_HAS_RELEASE) { @@ -835,7 +835,7 @@ void kernfs_drain_open_files(struct kernfs_node *kn) static unsigned int kernfs_fop_poll(struct file *filp, poll_table *wait) { struct kernfs_open_file *of = kernfs_of(filp); - struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; + struct kernfs_node *kn = kernfs_dentry_node(filp->f_path.dentry); struct kernfs_open_node *on = kn->attr.open; if (!kernfs_get_active(kn)) @@ -895,7 +895,7 @@ static void kernfs_notify_workfn(struct work_struct *work) * have the matching @file available. Look up the inodes * and generate the events manually. */ - inode = ilookup(info->sb, kn->ino); + inode = ilookup(info->sb, kn->id.ino); if (!inode) continue; @@ -903,7 +903,7 @@ static void kernfs_notify_workfn(struct work_struct *work) if (parent) { struct inode *p_inode; - p_inode = ilookup(info->sb, parent->ino); + p_inode = ilookup(info->sb, parent->id.ino); if (p_inode) { fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD, inode, FSNOTIFY_EVENT_INODE, kn->name, 0); @@ -997,7 +997,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, #ifdef CONFIG_DEBUG_LOCK_ALLOC if (key) { - lockdep_init_map(&kn->dep_map, "s_active", key, 0); + lockdep_init_map(&kn->dep_map, "kn->count", key, 0); kn->flags |= KERNFS_LOCKDEP; } #endif diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index fb4b4a79a0d6b4bb329f43ca4ace01ed35cbe74c..a34303981deb2cac6d39996e767b9e738d3c81df 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -112,7 +112,7 @@ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr) { struct inode *inode = d_inode(dentry); - struct kernfs_node *kn = dentry->d_fsdata; + struct kernfs_node *kn = inode->i_private; int error; if (!kn) @@ -154,7 +154,7 @@ static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata, ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) { - struct kernfs_node *kn = dentry->d_fsdata; + struct kernfs_node *kn = kernfs_dentry_node(dentry); struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); @@ -203,8 +203,8 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) int kernfs_iop_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { - struct kernfs_node *kn = path->dentry->d_fsdata; struct inode *inode = d_inode(path->dentry); + struct kernfs_node *kn = inode->i_private; mutex_lock(&kernfs_mutex); kernfs_refresh_inode(kn, inode); @@ -220,6 +220,7 @@ static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode) inode->i_private = kn; inode->i_mapping->a_ops = &kernfs_aops; inode->i_op = &kernfs_iops; + inode->i_generation = kn->id.generation; set_default_inode_attr(inode, kn->mode); kernfs_refresh_inode(kn, inode); @@ -265,7 +266,7 @@ struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn) { struct inode *inode; - inode = iget_locked(sb, kn->ino); + inode = iget_locked(sb, kn->id.ino); if (inode && (inode->i_state & I_NEW)) kernfs_init_inode(kn, inode); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 2d5144ab4251595c4c1f3a99db1fb9ca7f3b4bc8..0f260dcca1770427e7f292fe8ac1d2abc410e029 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -70,6 +70,13 @@ struct kernfs_super_info { }; #define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) +static inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry) +{ + if (d_really_is_negative(dentry)) + return NULL; + return d_inode(dentry)->i_private; +} + extern const struct super_operations kernfs_sops; extern struct kmem_cache *kernfs_node_cache; @@ -98,6 +105,8 @@ int kernfs_add_one(struct kernfs_node *kn); struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, const char *name, umode_t mode, unsigned flags); +struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root, + unsigned int ino); /* * file.c diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index d5b149a45be14940ed60210a6ccb42a993126a2f..95a7c88baed9d32284c073c46e248d670abca1b5 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "kernfs-internal.h" @@ -33,7 +34,7 @@ static int kernfs_sop_remount_fs(struct super_block *sb, int *flags, char *data) static int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry) { - struct kernfs_root *root = kernfs_root(dentry->d_fsdata); + struct kernfs_root *root = kernfs_root(kernfs_dentry_node(dentry)); struct kernfs_syscall_ops *scops = root->syscall_ops; if (scops && scops->show_options) @@ -43,7 +44,7 @@ static int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry) static int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry) { - struct kernfs_node *node = dentry->d_fsdata; + struct kernfs_node *node = kernfs_dentry_node(dentry); struct kernfs_root *root = kernfs_root(node); struct kernfs_syscall_ops *scops = root->syscall_ops; @@ -64,6 +65,78 @@ const struct super_operations kernfs_sops = { .show_path = kernfs_sop_show_path, }; +/* + * Similar to kernfs_fh_get_inode, this one gets kernfs node from inode + * number and generation + */ +struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root, + const union kernfs_node_id *id) +{ + struct kernfs_node *kn; + + kn = kernfs_find_and_get_node_by_ino(root, id->ino); + if (!kn) + return NULL; + if (kn->id.generation != id->generation) { + kernfs_put(kn); + return NULL; + } + return kn; +} + +static struct inode *kernfs_fh_get_inode(struct super_block *sb, + u64 ino, u32 generation) +{ + struct kernfs_super_info *info = kernfs_info(sb); + struct inode *inode; + struct kernfs_node *kn; + + if (ino == 0) + return ERR_PTR(-ESTALE); + + kn = kernfs_find_and_get_node_by_ino(info->root, ino); + if (!kn) + return ERR_PTR(-ESTALE); + inode = kernfs_get_inode(sb, kn); + kernfs_put(kn); + if (!inode) + return ERR_PTR(-ESTALE); + + if (generation && inode->i_generation != generation) { + /* we didn't find the right inode.. */ + iput(inode); + return ERR_PTR(-ESTALE); + } + return inode; +} + +static struct dentry *kernfs_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + return generic_fh_to_dentry(sb, fid, fh_len, fh_type, + kernfs_fh_get_inode); +} + +static struct dentry *kernfs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + return generic_fh_to_parent(sb, fid, fh_len, fh_type, + kernfs_fh_get_inode); +} + +static struct dentry *kernfs_get_parent_dentry(struct dentry *child) +{ + struct kernfs_node *kn = kernfs_dentry_node(child); + + return d_obtain_alias(kernfs_get_inode(child->d_sb, kn->parent)); +} + +static const struct export_operations kernfs_export_ops = { + .fh_to_dentry = kernfs_fh_to_dentry, + .fh_to_parent = kernfs_fh_to_parent, + .get_parent = kernfs_get_parent_dentry, +}; + /** * kernfs_root_from_sb - determine kernfs_root associated with a super_block * @sb: the super_block in question @@ -159,6 +232,8 @@ static int kernfs_fill_super(struct super_block *sb, unsigned long magic) sb->s_magic = magic; sb->s_op = &kernfs_sops; sb->s_xattr = kernfs_xattr_handlers; + if (info->root->flags & KERNFS_ROOT_SUPPORT_EXPORTOP) + sb->s_export_op = &kernfs_export_ops; sb->s_time_gran = 1; /* get root inode, initialize and unlock it */ @@ -176,8 +251,6 @@ static int kernfs_fill_super(struct super_block *sb, unsigned long magic) pr_debug("%s: could not get root dentry!\n", __func__); return -ENOMEM; } - kernfs_get(info->root->kn); - root->d_fsdata = info->root->kn; sb->s_root = root; sb->s_d_op = &kernfs_dops; return 0; @@ -283,7 +356,6 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, void kernfs_kill_sb(struct super_block *sb) { struct kernfs_super_info *info = kernfs_info(sb); - struct kernfs_node *root_kn = sb->s_root->d_fsdata; mutex_lock(&kernfs_mutex); list_del(&info->node); @@ -295,7 +367,6 @@ void kernfs_kill_sb(struct super_block *sb) */ kill_anon_super(sb); kfree(info); - kernfs_put(root_kn); } /** @@ -330,7 +401,16 @@ struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns) void __init kernfs_init(void) { + + /* + * the slab is freed in RCU context, so kernfs_find_and_get_node_by_ino + * can access the slab lock free. This could introduce stale nodes, + * please see how kernfs_find_and_get_node_by_ino filters out stale + * nodes. + */ kernfs_node_cache = kmem_cache_create("kernfs_node_cache", sizeof(struct kernfs_node), - 0, SLAB_PANIC, NULL); + 0, + SLAB_PANIC | SLAB_TYPESAFE_BY_RCU, + NULL); } diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 1684af4a8b9b4eaf752dfffc063b3a2cc622d472..08ccabd7047f390151b8ab31f72baa21efeefb6f 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -98,9 +98,9 @@ static int kernfs_get_target_path(struct kernfs_node *parent, return 0; } -static int kernfs_getlink(struct dentry *dentry, char *path) +static int kernfs_getlink(struct inode *inode, char *path) { - struct kernfs_node *kn = dentry->d_fsdata; + struct kernfs_node *kn = inode->i_private; struct kernfs_node *parent = kn->parent; struct kernfs_node *target = kn->symlink.target_kn; int error; @@ -124,7 +124,7 @@ static const char *kernfs_iop_get_link(struct dentry *dentry, body = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!body) return ERR_PTR(-ENOMEM); - error = kernfs_getlink(dentry, body); + error = kernfs_getlink(inode, body); if (unlikely(error < 0)) { kfree(body); return ERR_PTR(error); diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 27d577dbe51a48f21950a63758e76783fed67eca..96c1d14c18f12fd6d61e74344c6d28d3e6cf2730 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -235,12 +235,8 @@ reclaimer(void *ptr) struct net *net = host->net; req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) { - printk(KERN_ERR "lockd: reclaimer unable to alloc memory." - " Locks for %s won't be reclaimed!\n", - host->h_name); + if (!req) return 0; - } allow_signal(SIGKILL); diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 726b6cecf430d8d9cd522338436562df71efe6dc..b995bdc139768492fcc9faf4696aefb7850b63de 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -396,7 +396,7 @@ static int lockd_start_svc(struct svc_serv *serv) return error; } -static struct svc_serv_ops lockd_sv_ops = { +static const struct svc_serv_ops lockd_sv_ops = { .svo_shutdown = svc_rpcb_cleanup, .svo_enqueue_xprt = svc_xprt_do_enqueue, }; diff --git a/fs/locks.c b/fs/locks.c index afefeb4ad6ded4229d7ba69517c512a59177b3a1..1bd71c4d663a8c0356c457905293b5e9e35f2c9a 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -137,6 +137,7 @@ #define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) #define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) #define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) +#define IS_REMOTELCK(fl) (fl->fl_pid <= 0) static inline bool is_remote_lock(struct file *filp) { @@ -270,6 +271,22 @@ locks_check_ctx_lists(struct inode *inode) } } +static void +locks_check_ctx_file_list(struct file *filp, struct list_head *list, + char *list_type) +{ + struct file_lock *fl; + struct inode *inode = locks_inode(filp); + + list_for_each_entry(fl, list, fl_list) + if (fl->fl_file == filp) + pr_warn("Leaked %s lock on dev=0x%x:0x%x ino=0x%lx " + " fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n", + list_type, MAJOR(inode->i_sb->s_dev), + MINOR(inode->i_sb->s_dev), inode->i_ino, + fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid); +} + void locks_free_lock_context(struct inode *inode) { @@ -733,7 +750,6 @@ static void locks_wake_up_blocks(struct file_lock *blocker) static void locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) { - fl->fl_nspid = get_pid(task_tgid(current)); list_add_tail(&fl->fl_list, before); locks_insert_global_locks(fl); } @@ -743,10 +759,6 @@ locks_unlink_lock_ctx(struct file_lock *fl) { locks_delete_global_locks(fl); list_del_init(&fl->fl_list); - if (fl->fl_nspid) { - put_pid(fl->fl_nspid); - fl->fl_nspid = NULL; - } locks_wake_up_blocks(fl); } @@ -823,8 +835,6 @@ posix_test_lock(struct file *filp, struct file_lock *fl) list_for_each_entry(cfl, &ctx->flc_posix, fl_list) { if (posix_locks_conflict(fl, cfl)) { locks_copy_conflock(fl, cfl); - if (cfl->fl_nspid) - fl->fl_pid = pid_vnr(cfl->fl_nspid); goto out; } } @@ -2048,9 +2058,33 @@ int vfs_test_lock(struct file *filp, struct file_lock *fl) } EXPORT_SYMBOL_GPL(vfs_test_lock); +/** + * locks_translate_pid - translate a file_lock's fl_pid number into a namespace + * @fl: The file_lock who's fl_pid should be translated + * @ns: The namespace into which the pid should be translated + * + * Used to tranlate a fl_pid into a namespace virtual pid number + */ +static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns) +{ + pid_t vnr; + struct pid *pid; + + if (IS_OFDLCK(fl)) + return -1; + if (IS_REMOTELCK(fl)) + return fl->fl_pid; + + rcu_read_lock(); + pid = find_pid_ns(fl->fl_pid, &init_pid_ns); + vnr = pid_nr_ns(pid, ns); + rcu_read_unlock(); + return vnr; +} + static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) { - flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid; + flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); #if BITS_PER_LONG == 32 /* * Make sure we can represent the posix lock via @@ -2072,7 +2106,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) #if BITS_PER_LONG == 32 static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) { - flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid; + flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); flock->l_start = fl->fl_start; flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1; @@ -2086,14 +2120,17 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) */ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) { - struct file_lock file_lock; + struct file_lock *fl; int error; + fl = locks_alloc_lock(); + if (fl == NULL) + return -ENOMEM; error = -EINVAL; if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) goto out; - error = flock_to_posix_lock(filp, &file_lock, flock); + error = flock_to_posix_lock(filp, fl, flock); if (error) goto out; @@ -2103,23 +2140,22 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) goto out; cmd = F_GETLK; - file_lock.fl_flags |= FL_OFDLCK; - file_lock.fl_owner = filp; + fl->fl_flags |= FL_OFDLCK; + fl->fl_owner = filp; } - error = vfs_test_lock(filp, &file_lock); + error = vfs_test_lock(filp, fl); if (error) goto out; - flock->l_type = file_lock.fl_type; - if (file_lock.fl_type != F_UNLCK) { - error = posix_lock_to_flock(flock, &file_lock); + flock->l_type = fl->fl_type; + if (fl->fl_type != F_UNLCK) { + error = posix_lock_to_flock(flock, fl); if (error) - goto rel_priv; + goto out; } -rel_priv: - locks_release_private(&file_lock); out: + locks_free_lock(fl); return error; } @@ -2298,14 +2334,18 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, */ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) { - struct file_lock file_lock; + struct file_lock *fl; int error; + fl = locks_alloc_lock(); + if (fl == NULL) + return -ENOMEM; + error = -EINVAL; if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) goto out; - error = flock64_to_posix_lock(filp, &file_lock, flock); + error = flock64_to_posix_lock(filp, fl, flock); if (error) goto out; @@ -2315,20 +2355,20 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) goto out; cmd = F_GETLK64; - file_lock.fl_flags |= FL_OFDLCK; - file_lock.fl_owner = filp; + fl->fl_flags |= FL_OFDLCK; + fl->fl_owner = filp; } - error = vfs_test_lock(filp, &file_lock); + error = vfs_test_lock(filp, fl); if (error) goto out; - flock->l_type = file_lock.fl_type; - if (file_lock.fl_type != F_UNLCK) - posix_lock_to_flock64(flock, &file_lock); + flock->l_type = fl->fl_type; + if (fl->fl_type != F_UNLCK) + posix_lock_to_flock64(flock, fl); - locks_release_private(&file_lock); out: + locks_free_lock(fl); return error; } @@ -2525,6 +2565,12 @@ void locks_remove_file(struct file *filp) /* remove any leases */ locks_remove_lease(filp, ctx); + + spin_lock(&ctx->flc_lock); + locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX"); + locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK"); + locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE"); + spin_unlock(&ctx->flc_lock); } /** @@ -2578,22 +2624,16 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, { struct inode *inode = NULL; unsigned int fl_pid; + struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; - if (fl->fl_nspid) { - struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; - - /* Don't let fl_pid change based on who is reading the file */ - fl_pid = pid_nr_ns(fl->fl_nspid, proc_pidns); - - /* - * If there isn't a fl_pid don't display who is waiting on - * the lock if we are called from locks_show, or if we are - * called from __show_fd_info - skip lock entirely - */ - if (fl_pid == 0) - return; - } else - fl_pid = fl->fl_pid; + fl_pid = locks_translate_pid(fl, proc_pidns); + /* + * If there isn't a fl_pid don't display who is waiting on + * the lock if we are called from locks_show, or if we are + * called from __show_fd_info - skip lock entirely + */ + if (fl_pid == 0) + return; if (fl->fl_file != NULL) inode = locks_inode(fl->fl_file); @@ -2668,7 +2708,7 @@ static int locks_show(struct seq_file *f, void *v) fl = hlist_entry(v, struct file_lock, fl_link); - if (fl->fl_nspid && !pid_nr_ns(fl->fl_nspid, proc_pidns)) + if (locks_translate_pid(fl, proc_pidns) == 0) return 0; lock_get_status(f, fl, iter->li_pos, ""); diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 6ac76b0434e93727d99ad583688adf6a27d1f6ec..b6829d67964324783f182be42be939753f07a7d0 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -42,7 +42,7 @@ static void minix_put_super(struct super_block *sb) int i; struct minix_sb_info *sbi = minix_sb(sb); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ sbi->s_ms->s_state = sbi->s_mount_state; mark_buffer_dirty(sbi->s_sbh); @@ -125,7 +125,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data) sync_filesystem(sb); ms = sbi->s_ms; - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) return 0; if (*flags & MS_RDONLY) { if (ms->s_state & MINIX_VALID_FS || @@ -293,7 +293,7 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) if (!s->s_root) goto out_no_root; - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ ms->s_state &= ~MINIX_VALID_FS; mark_buffer_dirty(bh); diff --git a/fs/mpage.c b/fs/mpage.c index 2e4c41ccb5c91a4824465678215d190e228134e6..37bb77c1302c354adf0386a32e3b678fdc93f54c 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -83,7 +83,7 @@ mpage_alloc(struct block_device *bdev, } if (bio) { - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector = first_sector; } return bio; diff --git a/fs/namei.c b/fs/namei.c index ddb6a7c2b3d4aee1c3512e064350822533968dc5..c75ea03ca147ec81977f67929b7f4489b90cf42e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -447,8 +447,7 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) umode_t mode = inode->i_mode; /* Nobody gets write access to a read-only fs. */ - if ((sb->s_flags & MS_RDONLY) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) + if (sb_rdonly(sb) && (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) return -EROFS; } return 0; @@ -1129,9 +1128,18 @@ static int follow_automount(struct path *path, struct nameidata *nd, * of the daemon to instantiate them before they can be used. */ if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY | - LOOKUP_OPEN | LOOKUP_CREATE | LOOKUP_AUTOMOUNT)) && - path->dentry->d_inode) - return -EISDIR; + LOOKUP_OPEN | LOOKUP_CREATE | + LOOKUP_AUTOMOUNT))) { + /* Positive dentry that isn't meant to trigger an + * automount, EISDIR will allow it to be used, + * otherwise there's no mount here "now" so return + * ENOENT. + */ + if (path->dentry->d_inode) + return -EISDIR; + else + return -ENOENT; + } if (path->dentry->d_sb->s_user_ns != &init_user_ns) return -EACCES; diff --git a/fs/namespace.c b/fs/namespace.c index f8893dc6a989dc6c9b0f4e8daba2e985a64976e6..3b601f115b6cb72a9f02a82f5e8a41c458729b4b 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -275,7 +275,7 @@ int __mnt_is_readonly(struct vfsmount *mnt) { if (mnt->mnt_flags & MNT_READONLY) return 1; - if (mnt->mnt_sb->s_flags & MS_RDONLY) + if (sb_rdonly(mnt->mnt_sb)) return 1; return 0; } @@ -431,13 +431,18 @@ int __mnt_want_write_file(struct file *file) } /** - * mnt_want_write_file - get write access to a file's mount + * mnt_want_write_file_path - get write access to a file's mount * @file: the file who's mount on which to take a write * * This is like mnt_want_write, but it takes a file and can * do some optimisations if the file is open for write already + * + * Called by the vfs for cases when we have an open file at hand, but will do an + * inode operation on it (important distinction for files opened on overlayfs, + * since the file operations will come from the real underlying file, while + * inode operations come from the overlay). */ -int mnt_want_write_file(struct file *file) +int mnt_want_write_file_path(struct file *file) { int ret; @@ -447,6 +452,55 @@ int mnt_want_write_file(struct file *file) sb_end_write(file->f_path.mnt->mnt_sb); return ret; } + +static inline int may_write_real(struct file *file) +{ + struct dentry *dentry = file->f_path.dentry; + struct dentry *upperdentry; + + /* Writable file? */ + if (file->f_mode & FMODE_WRITER) + return 0; + + /* Not overlayfs? */ + if (likely(!(dentry->d_flags & DCACHE_OP_REAL))) + return 0; + + /* File refers to upper, writable layer? */ + upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER); + if (upperdentry && + (file_inode(file) == d_inode(upperdentry) || + file_inode(file) == d_inode(dentry))) + return 0; + + /* Lower layer: can't write to real file, sorry... */ + return -EPERM; +} + +/** + * mnt_want_write_file - get write access to a file's mount + * @file: the file who's mount on which to take a write + * + * This is like mnt_want_write, but it takes a file and can + * do some optimisations if the file is open for write already + * + * Mostly called by filesystems from their ioctl operation before performing + * modification. On overlayfs this needs to check if the file is on a read-only + * lower layer and deny access in that case. + */ +int mnt_want_write_file(struct file *file) +{ + int ret; + + ret = may_write_real(file); + if (!ret) { + sb_start_write(file_inode(file)->i_sb); + ret = __mnt_want_write_file(file); + if (ret) + sb_end_write(file_inode(file)->i_sb); + } + return ret; +} EXPORT_SYMBOL_GPL(mnt_want_write_file); /** @@ -484,10 +538,16 @@ void __mnt_drop_write_file(struct file *file) __mnt_drop_write(file->f_path.mnt); } -void mnt_drop_write_file(struct file *file) +void mnt_drop_write_file_path(struct file *file) { mnt_drop_write(file->f_path.mnt); } + +void mnt_drop_write_file(struct file *file) +{ + __mnt_drop_write(file->f_path.mnt); + sb_end_write(file_inode(file)->i_sb); +} EXPORT_SYMBOL(mnt_drop_write_file); static int mnt_make_readonly(struct mount *mnt) @@ -971,7 +1031,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void if (!mnt) return ERR_PTR(-ENOMEM); - if (flags & MS_KERNMOUNT) + if (flags & SB_KERNMOUNT) mnt->mnt.mnt_flags = MNT_INTERNAL; root = mount_fs(type, flags, name, data); @@ -1003,7 +1063,7 @@ vfs_submount(const struct dentry *mountpoint, struct file_system_type *type, if (mountpoint->d_sb->s_user_ns != &init_user_ns) return ERR_PTR(-EPERM); - return vfs_kern_mount(type, MS_SUBMOUNT, name, data); + return vfs_kern_mount(type, SB_SUBMOUNT, name, data); } EXPORT_SYMBOL_GPL(vfs_submount); @@ -1124,12 +1184,10 @@ static LLIST_HEAD(delayed_mntput_list); static void delayed_mntput(struct work_struct *unused) { struct llist_node *node = llist_del_all(&delayed_mntput_list); - struct llist_node *next; + struct mount *m, *t; - for (; node; node = next) { - next = llist_next(node); - cleanup_mnt(llist_entry(node, struct mount, mnt_llist)); - } + llist_for_each_entry_safe(m, t, node, mnt_llist) + cleanup_mnt(m); } static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput); @@ -1534,8 +1592,8 @@ static int do_umount(struct mount *mnt, int flags) if (!capable(CAP_SYS_ADMIN)) return -EPERM; down_write(&sb->s_umount); - if (!(sb->s_flags & MS_RDONLY)) - retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); + if (!sb_rdonly(sb)) + retval = do_remount_sb(sb, SB_RDONLY, NULL, 0); up_write(&sb->s_umount); return retval; } @@ -2059,7 +2117,7 @@ static void unlock_mount(struct mountpoint *where) static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) { - if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER) + if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER) return -EINVAL; if (d_is_dir(mp->m_dentry) != @@ -2073,9 +2131,9 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) * Sanity check the flags to change_mnt_propagation. */ -static int flags_to_propagation_type(int flags) +static int flags_to_propagation_type(int ms_flags) { - int type = flags & ~(MS_REC | MS_SILENT); + int type = ms_flags & ~(MS_REC | MS_SILENT); /* Fail if any non-propagation flags are set */ if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) @@ -2089,18 +2147,18 @@ static int flags_to_propagation_type(int flags) /* * recursively change the type of the mountpoint. */ -static int do_change_type(struct path *path, int flag) +static int do_change_type(struct path *path, int ms_flags) { struct mount *m; struct mount *mnt = real_mount(path->mnt); - int recurse = flag & MS_REC; + int recurse = ms_flags & MS_REC; int type; int err = 0; if (path->dentry != path->mnt->mnt_root) return -EINVAL; - type = flags_to_propagation_type(flag); + type = flags_to_propagation_type(ms_flags); if (!type) return -EINVAL; @@ -2222,8 +2280,8 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags) * If you've mounted a non-root directory somewhere and want to do remount * on it - tough luck. */ -static int do_remount(struct path *path, int flags, int mnt_flags, - void *data) +static int do_remount(struct path *path, int ms_flags, int sb_flags, + int mnt_flags, void *data) { int err; struct super_block *sb = path->mnt->mnt_sb; @@ -2267,12 +2325,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags, return err; down_write(&sb->s_umount); - if (flags & MS_BIND) - err = change_mount_flags(path->mnt, flags); + if (ms_flags & MS_BIND) + err = change_mount_flags(path->mnt, ms_flags); else if (!capable(CAP_SYS_ADMIN)) err = -EPERM; else - err = do_remount_sb(sb, flags, data, 0); + err = do_remount_sb(sb, sb_flags, data, 0); if (!err) { lock_mount_hash(); mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; @@ -2437,7 +2495,7 @@ static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags); * create a new mount for userspace and request it to be added into the * namespace's tree */ -static int do_new_mount(struct path *path, const char *fstype, int flags, +static int do_new_mount(struct path *path, const char *fstype, int sb_flags, int mnt_flags, const char *name, void *data) { struct file_system_type *type; @@ -2451,7 +2509,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, if (!type) return -ENODEV; - mnt = vfs_kern_mount(type, flags, name, data); + mnt = vfs_kern_mount(type, sb_flags, name, data); if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && !mnt->mnt_sb->s_subtype) mnt = fs_set_subtype(mnt, fstype); @@ -2706,8 +2764,8 @@ long do_mount(const char *dev_name, const char __user *dir_name, const char *type_page, unsigned long flags, void *data_page) { struct path path; + unsigned int mnt_flags = 0, sb_flags; int retval = 0; - int mnt_flags = 0; /* Discard magic */ if ((flags & MS_MGC_MSK) == MS_MGC_VAL) @@ -2717,6 +2775,9 @@ long do_mount(const char *dev_name, const char __user *dir_name, if (data_page) ((char *)data_page)[PAGE_SIZE - 1] = 0; + if (flags & MS_NOUSER) + return -EINVAL; + /* ... and get the mountpoint */ retval = user_path(dir_name, &path); if (retval) @@ -2726,7 +2787,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, type_page, flags, data_page); if (!retval && !may_mount()) retval = -EPERM; - if (!retval && (flags & MS_MANDLOCK) && !may_mandlock()) + if (!retval && (flags & SB_MANDLOCK) && !may_mandlock()) retval = -EPERM; if (retval) goto dput_out; @@ -2748,7 +2809,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, mnt_flags |= MNT_NODIRATIME; if (flags & MS_STRICTATIME) mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME); - if (flags & MS_RDONLY) + if (flags & SB_RDONLY) mnt_flags |= MNT_READONLY; /* The default atime for remount is preservation */ @@ -2759,12 +2820,15 @@ long do_mount(const char *dev_name, const char __user *dir_name, mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK; } - flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | - MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | - MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT); + sb_flags = flags & (SB_RDONLY | + SB_SYNCHRONOUS | + SB_MANDLOCK | + SB_DIRSYNC | + SB_SILENT | + SB_POSIXACL); if (flags & MS_REMOUNT) - retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, + retval = do_remount(&path, flags, sb_flags, mnt_flags, data_page); else if (flags & MS_BIND) retval = do_loopback(&path, dev_name, flags & MS_REC); @@ -2773,7 +2837,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, else if (flags & MS_MOVE) retval = do_move_mount(&path, dev_name); else - retval = do_new_mount(&path, type_page, flags, mnt_flags, + retval = do_new_mount(&path, type_page, sb_flags, mnt_flags, dev_name, data_page); dput_out: path_put(&path); @@ -3223,7 +3287,7 @@ void put_mnt_ns(struct mnt_namespace *ns) struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) { struct vfsmount *mnt; - mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); + mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, data); if (!IS_ERR(mnt)) { /* * it is a longterm mount, don't release mnt until @@ -3300,7 +3364,7 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new, mnt_flags = mnt->mnt.mnt_flags; /* Don't miss readonly hidden in the superblock flags */ - if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY) + if (sb_rdonly(mnt->mnt.mnt_sb)) mnt_flags |= MNT_LOCK_READONLY; /* Verify the mount flags are equal to or more permissive diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 76965e7722643ec63ced2e6071b0e7ec40561818..a06c07619ee660ca7cb8b4044a3b34e58741042b 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -23,7 +23,7 @@ static int ncp_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - return filemap_write_and_wait_range(file->f_mapping, start, end); + return file_write_and_wait_range(file, start, end); } /* diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 69d02cf8cf370678609175d6e5626d0dedf02c3a..5f93cfacb3d14b9befc6ba33a91d79ccde044d89 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -121,6 +121,7 @@ config PNFS_FILE_LAYOUT config PNFS_BLOCK tristate depends on NFS_V4_1 && BLK_DEV_DM + depends on 64BIT || LBDAF default NFS_V4 config PNFS_FLEXFILE_LAYOUT diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index d8863a804b15756632a15dcd3d0076db4a0bf136..995d707537dab942ce9aae0fc1388d114d68699b 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -130,7 +130,7 @@ bl_alloc_init_bio(int npg, struct block_device *bdev, sector_t disk_sector, if (bio) { bio->bi_iter.bi_sector = disk_sector; - bio->bi_bdev = bdev; + bio_set_dev(bio, bdev); bio->bi_end_io = end_io; bio->bi_private = par; } diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 34323877ec132f8b163d2c1118e45ab8c319fe71..2cddf7f437e666e7e486b3d8ec7676c488440635 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -226,26 +226,26 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, return ret; } -static struct svc_serv_ops nfs40_cb_sv_ops = { +static const struct svc_serv_ops nfs40_cb_sv_ops = { .svo_function = nfs4_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, .svo_setup = svc_set_num_threads_sync, .svo_module = THIS_MODULE, }; #if defined(CONFIG_NFS_V4_1) -static struct svc_serv_ops nfs41_cb_sv_ops = { +static const struct svc_serv_ops nfs41_cb_sv_ops = { .svo_function = nfs41_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, .svo_setup = svc_set_num_threads_sync, .svo_module = THIS_MODULE, }; -static struct svc_serv_ops *nfs4_cb_sv_ops[] = { +static const struct svc_serv_ops *nfs4_cb_sv_ops[] = { [0] = &nfs40_cb_sv_ops, [1] = &nfs41_cb_sv_ops, }; #else -static struct svc_serv_ops *nfs4_cb_sv_ops[] = { +static const struct svc_serv_ops *nfs4_cb_sv_ops[] = { [0] = &nfs40_cb_sv_ops, [1] = NULL, }; @@ -254,8 +254,8 @@ static struct svc_serv_ops *nfs4_cb_sv_ops[] = { static struct svc_serv *nfs_callback_create_svc(int minorversion) { struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; + const struct svc_serv_ops *sv_ops; struct svc_serv *serv; - struct svc_serv_ops *sv_ops; /* * Check whether we're already up and running. diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 5427cdf04c5a1611934848c78455b299412dd185..14358de173fb9d851433977a0e70b8dcff9f0ff3 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -51,7 +51,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp, goto out_iput; res->size = i_size_read(inode); res->change_attr = delegation->change_attr; - if (nfsi->nrequests != 0) + if (nfs_have_writebacks(inode)) res->change_attr++; res->ctime = inode->i_ctime; res->mtime = inode->i_mtime; diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index d7df5e67b0c1560ff3ea93cccd6a4b21e066cd88..606dd3871f66b0881c2760af3bbc3839748f9bc2 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -1089,7 +1089,7 @@ bool nfs4_delegation_flush_on_close(const struct inode *inode) delegation = rcu_dereference(nfsi->delegation); if (delegation == NULL || !(delegation->type & FMODE_WRITE)) goto out; - if (nfsi->nrequests < delegation->pagemod_limit) + if (atomic_long_read(&nfsi->nrequests) < delegation->pagemod_limit) ret = false; out: rcu_read_unlock(); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 3522b1249019ce261db090af01baf9525302f10d..5ceaeb1f6fb69d8ce15e932ff278a70837a48a30 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2260,7 +2260,6 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str spin_lock(&inode->i_lock); retry = false; } - res->jiffies = cache->jiffies; res->cred = cache->cred; res->mask = cache->mask; list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru); @@ -2296,7 +2295,6 @@ static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred, goto out; if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS)) goto out; - res->jiffies = cache->jiffies; res->cred = cache->cred; res->mask = cache->mask; err = 0; @@ -2344,7 +2342,6 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) if (cache == NULL) return; RB_CLEAR_NODE(&cache->rb_node); - cache->jiffies = set->jiffies; cache->cred = get_rpccred(set->cred); cache->mask = set->mask; @@ -2432,7 +2429,6 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) cache.mask = NFS_MAY_LOOKUP | NFS_MAY_EXECUTE | NFS_MAY_WRITE | NFS_MAY_READ; cache.cred = cred; - cache.jiffies = jiffies; status = NFS_PROTO(inode)->access(inode, &cache); if (status != 0) { if (status == -ESTALE) { diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 6fb9fad2d1e6cf6909cfe6dfb2e482bff969e7df..d2972d5374695050cdc3598f6488510af87b3379 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -616,13 +616,13 @@ nfs_direct_write_scan_commit_list(struct inode *inode, struct list_head *list, struct nfs_commit_info *cinfo) { - spin_lock(&cinfo->inode->i_lock); + mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); #ifdef CONFIG_NFS_V4_1 if (cinfo->ds != NULL && cinfo->ds->nwritten != 0) NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo); #endif nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0); - spin_unlock(&cinfo->inode->i_lock); + mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); } static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index af330c31f62752f22c6fe1dc6de5c57f0e02a3d3..0214dd1e10602b4b79f7c5c136ea0ad2bc4b832b 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -208,21 +208,19 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap); * fall back to doing a synchronous write. */ static int -nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) +nfs_file_fsync_commit(struct file *file, int datasync) { struct nfs_open_context *ctx = nfs_file_open_context(file); struct inode *inode = file_inode(file); - int have_error, do_resend, status; + int do_resend, status; int ret = 0; dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); nfs_inc_stats(inode, NFSIOS_VFSFSYNC); do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); - have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); status = nfs_commit_inode(inode, FLUSH_SYNC); - have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); - if (have_error) { + if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { ret = xchg(&ctx->error, 0); if (ret) goto out; @@ -247,10 +245,16 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) trace_nfs_fsync_enter(inode); do { + struct nfs_open_context *ctx = nfs_file_open_context(file); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { + int ret2 = xchg(&ctx->error, 0); + if (ret2) + ret = ret2; + } if (ret != 0) break; - ret = nfs_file_fsync_commit(file, start, end, datasync); + ret = nfs_file_fsync_commit(file, datasync); if (!ret) ret = pnfs_sync_inode(inode, !!datasync); /* @@ -631,11 +635,11 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) if (result <= 0) goto out; - result = generic_write_sync(iocb, result); - if (result < 0) - goto out; written = result; iocb->ki_pos += written; + result = generic_write_sync(iocb, written); + if (result < 0) + goto out; /* Return error values */ if (nfs_need_check_write(file, inode)) { @@ -744,15 +748,18 @@ do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) goto out; /* - * Revalidate the cache if the server has time stamps granular - * enough to detect subsecond changes. Otherwise, clear the - * cache to prevent missing any changes. + * Invalidate cache to prevent missing any changes. If + * the file is mapped, clear the page cache as well so + * those mappings will be loaded. * * This makes locking act as a cache coherency point. */ nfs_sync_mapping(filp->f_mapping); - if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) + if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) { nfs_zap_caches(inode); + if (mapping_mapped(filp->f_mapping)) + nfs_revalidate_mapping(inode, filp->f_mapping); + } out: return status; } diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index 6df7a0cf566015378aa3f76c480115675454297d..f32c58bbe55671cb75abdcb9934152d110e3537d 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -32,6 +32,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds) { nfs4_print_deviceid(&mirror_ds->id_node.deviceid); nfs4_pnfs_ds_put(mirror_ds->ds); + kfree(mirror_ds->ds_versions); kfree_rcu(mirror_ds, id_node.rcu); } diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c index 777b055063f68a83e3655bd6cbeac8aabf1fba70..3025fe8584a05ce24df0e5900d213679b12aa33e 100644 --- a/fs/nfs/fscache-index.c +++ b/fs/nfs/fscache-index.c @@ -251,45 +251,6 @@ enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data, return FSCACHE_CHECKAUX_OKAY; } -/* - * Indication from FS-Cache that the cookie is no longer cached - * - This function is called when the backing store currently caching a cookie - * is removed - * - The netfs should use this to clean up any markers indicating cached pages - * - This is mandatory for any object that may have data - */ -static void nfs_fscache_inode_now_uncached(void *cookie_netfs_data) -{ - struct nfs_inode *nfsi = cookie_netfs_data; - struct pagevec pvec; - pgoff_t first; - int loop, nr_pages; - - pagevec_init(&pvec, 0); - first = 0; - - dprintk("NFS: nfs_inode_now_uncached: nfs_inode 0x%p\n", nfsi); - - for (;;) { - /* grab a bunch of pages to unmark */ - nr_pages = pagevec_lookup(&pvec, - nfsi->vfs_inode.i_mapping, - first, - PAGEVEC_SIZE - pagevec_count(&pvec)); - if (!nr_pages) - break; - - for (loop = 0; loop < nr_pages; loop++) - ClearPageFsCache(pvec.pages[loop]); - - first = pvec.pages[nr_pages - 1]->index + 1; - - pvec.nr = nr_pages; - pagevec_release(&pvec); - cond_resched(); - } -} - /* * Get an extra reference on a read context. * - This function can be absent if the completion function doesn't require a @@ -330,7 +291,6 @@ const struct fscache_cookie_def nfs_fscache_inode_object_def = { .get_attr = nfs_fscache_inode_get_attr, .get_aux = nfs_fscache_inode_get_aux, .check_aux = nfs_fscache_inode_check_aux, - .now_uncached = nfs_fscache_inode_now_uncached, .get_context = nfs_fh_get_context, .put_context = nfs_fh_put_context, }; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 109279d6d91bd61421ef572bbcaa1dfe9fa0e9c8..134d9f560240f3ba1183a9ab4173a81ff21f4b63 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1285,7 +1285,6 @@ static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi) static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) { - struct nfs_inode *nfsi = NFS_I(inode); unsigned long ret = 0; if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) @@ -1315,7 +1314,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) && (fattr->valid & NFS_ATTR_FATTR_SIZE) && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) - && nfsi->nrequests == 0) { + && !nfs_have_writebacks(inode)) { i_size_write(inode, nfs_size_to_loff_t(fattr->size)); ret |= NFS_INO_INVALID_ATTR; } @@ -1823,7 +1822,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) if (new_isize != cur_isize) { /* Do we perhaps have any outstanding writes, or has * the file grown beyond our last write? */ - if (nfsi->nrequests == 0 || new_isize > cur_isize) { + if (!nfs_have_writebacks(inode) || new_isize > cur_isize) { i_size_write(inode, new_isize); if (!have_writers) invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; @@ -2012,10 +2011,11 @@ static void init_once(void *foo) INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); INIT_LIST_HEAD(&nfsi->commit_info.list); - nfsi->nrequests = 0; - nfsi->commit_info.ncommit = 0; + atomic_long_set(&nfsi->nrequests, 0); + atomic_long_set(&nfsi->commit_info.ncommit, 0); atomic_set(&nfsi->commit_info.rpcs_out, 0); init_rwsem(&nfsi->rmdir_sem); + mutex_init(&nfsi->commit_mutex); nfs4_init_once(nfsi); } diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index dc456416d2becc960678625da5712a9992595bc4..5bdf952f414b54c04987e1c3ce5c23ac0bf95961 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -251,7 +251,6 @@ int nfs_iocounter_wait(struct nfs_lock_context *l_ctx); extern const struct nfs_pageio_ops nfs_pgio_rw_ops; struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *); void nfs_pgio_header_free(struct nfs_pgio_header *); -void nfs_pgio_data_destroy(struct nfs_pgio_header *); int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *); int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr, struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops, @@ -769,3 +768,10 @@ static inline bool nfs_error_is_fatal(int err) return false; } } + +static inline void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) +{ + ctx->error = error; + smp_wmb(); + set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); +} diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 40bd05f05e743f01228d09b7d9d23d8fbe7bb213..ac4f10b7f6c1beafc5027ad02a53b33e091f32d0 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -303,6 +303,17 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, struct rpc_cred *newcred = NULL; rpc_authflavor_t flavor; + if (sp4_mode == NFS_SP4_MACH_CRED_CLEANUP || + sp4_mode == NFS_SP4_MACH_CRED_PNFS_CLEANUP) { + /* Using machine creds for cleanup operations + * is only relevent if the client credentials + * might expire. So don't bother for + * RPC_AUTH_UNIX. If file was only exported to + * sec=sys, the PUTFH would fail anyway. + */ + if ((*clntp)->cl_auth->au_flavor == RPC_AUTH_UNIX) + return false; + } if (test_bit(sp4_mode, &clp->cl_sp4_flags)) { spin_lock(&clp->cl_lock); if (clp->cl_machine_cred != NULL) diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 50566acb54694ac4f14330f4bbb7ab360ba15f88..e9bea90dc0179770b9fbfa39fe6651c5949f0d62 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -660,9 +660,6 @@ int nfs4_detect_session_trunking(struct nfs_client *clp, if (!nfs4_check_server_scope(clp->cl_serverscope, res->server_scope)) goto out_err; - /* Session trunking passed, add the xprt */ - rpc_clnt_xprt_switch_add_xprt(clp->cl_rpcclient, xprt); - pr_info("NFS: %s: Session trunking succeeded for %s\n", clp->cl_hostname, xprt->address_strings[RPC_DISPLAY_ADDR]); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 18ca6879d8de9ecebf22d0f4f9ba73b66fdeeddc..6c61e2b996351cde05b1c922674cd3a2670913ea 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1659,12 +1659,52 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data) return state; } +static struct inode * +nfs4_opendata_get_inode(struct nfs4_opendata *data) +{ + struct inode *inode; + + switch (data->o_arg.claim) { + case NFS4_OPEN_CLAIM_NULL: + case NFS4_OPEN_CLAIM_DELEGATE_CUR: + case NFS4_OPEN_CLAIM_DELEGATE_PREV: + if (!(data->f_attr.valid & NFS_ATTR_FATTR)) + return ERR_PTR(-EAGAIN); + inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, + &data->f_attr, data->f_label); + break; + default: + inode = d_inode(data->dentry); + ihold(inode); + nfs_refresh_inode(inode, &data->f_attr); + } + return inode; +} + static struct nfs4_state * -_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) +nfs4_opendata_find_nfs4_state(struct nfs4_opendata *data) { + struct nfs4_state *state; struct inode *inode; - struct nfs4_state *state = NULL; - int ret; + + inode = nfs4_opendata_get_inode(data); + if (IS_ERR(inode)) + return ERR_CAST(inode); + if (data->state != NULL && data->state->inode == inode) { + state = data->state; + atomic_inc(&state->count); + } else + state = nfs4_get_open_state(inode, data->owner); + iput(inode); + if (state == NULL) + state = ERR_PTR(-ENOMEM); + return state; +} + +static struct nfs4_state * +_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) +{ + struct nfs4_state *state; if (!data->rpc_done) { state = nfs4_try_open_cached(data); @@ -1672,29 +1712,17 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) goto out; } - ret = -EAGAIN; - if (!(data->f_attr.valid & NFS_ATTR_FATTR)) - goto err; - inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr, data->f_label); - ret = PTR_ERR(inode); - if (IS_ERR(inode)) - goto err; - ret = -ENOMEM; - state = nfs4_get_open_state(inode, data->owner); - if (state == NULL) - goto err_put_inode; + state = nfs4_opendata_find_nfs4_state(data); + if (IS_ERR(state)) + goto out; + if (data->o_res.delegation_type != 0) nfs4_opendata_check_deleg(data, state); update_open_stateid(state, &data->o_res.stateid, NULL, data->o_arg.fmode); - iput(inode); out: nfs_release_seqid(data->o_arg.seqid); return state; -err_put_inode: - iput(inode); -err: - return ERR_PTR(ret); } static struct nfs4_state * @@ -2071,7 +2099,6 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0]; case NFS4_OPEN_CLAIM_FH: task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; - nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); } data->timestamp = jiffies; if (nfs4_setup_sequence(data->o_arg.server->nfs_client, @@ -2258,7 +2285,6 @@ static int nfs4_opendata_access(struct rpc_cred *cred, mask = NFS4_ACCESS_READ; cache.cred = cred; - cache.jiffies = jiffies; nfs_access_set_mask(&cache, opendata->o_res.access_result); nfs_access_add_cache(state->inode, &cache); @@ -2553,9 +2579,8 @@ static int nfs41_check_open_stateid(struct nfs4_state *state) clear_bit(NFS_O_RDWR_STATE, &state->flags); clear_bit(NFS_OPEN_STATE, &state->flags); stateid->type = NFS4_INVALID_STATEID_TYPE; - } - if (status != NFS_OK) return status; + } if (nfs_open_stateid_recover_openmode(state)) return -NFS4ERR_OPENMODE; return NFS_OK; @@ -7319,7 +7344,9 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp, 1 << (OP_DESTROY_SESSION - 32) | 1 << (OP_DESTROY_CLIENTID - 32) }; + unsigned long flags = 0; unsigned int i; + int ret = 0; if (sp->how == SP4_MACH_CRED) { /* Print state protect result */ @@ -7335,7 +7362,8 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp, for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++) { if (sp->enforce.u.words[i] & ~supported_enforce[i]) { dfprintk(MOUNT, "sp4_mach_cred: disabled\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } } @@ -7354,10 +7382,11 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp, test_bit(OP_DESTROY_CLIENTID, sp->enforce.u.longs)) { dfprintk(MOUNT, "sp4_mach_cred:\n"); dfprintk(MOUNT, " minimal mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_MINIMAL, &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_MINIMAL, &flags); } else { dfprintk(MOUNT, "sp4_mach_cred: disabled\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } if (test_bit(OP_CLOSE, sp->allow.u.longs) && @@ -7365,119 +7394,51 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp, test_bit(OP_DELEGRETURN, sp->allow.u.longs) && test_bit(OP_LOCKU, sp->allow.u.longs)) { dfprintk(MOUNT, " cleanup mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_CLEANUP, &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_CLEANUP, &flags); } if (test_bit(OP_LAYOUTRETURN, sp->allow.u.longs)) { dfprintk(MOUNT, " pnfs cleanup mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_PNFS_CLEANUP, - &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_PNFS_CLEANUP, &flags); } if (test_bit(OP_SECINFO, sp->allow.u.longs) && test_bit(OP_SECINFO_NO_NAME, sp->allow.u.longs)) { dfprintk(MOUNT, " secinfo mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_SECINFO, &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_SECINFO, &flags); } if (test_bit(OP_TEST_STATEID, sp->allow.u.longs) && test_bit(OP_FREE_STATEID, sp->allow.u.longs)) { dfprintk(MOUNT, " stateid mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_STATEID, &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_STATEID, &flags); } if (test_bit(OP_WRITE, sp->allow.u.longs)) { dfprintk(MOUNT, " write mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_WRITE, &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_WRITE, &flags); } if (test_bit(OP_COMMIT, sp->allow.u.longs)) { dfprintk(MOUNT, " commit mode enabled\n"); - set_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags); + __set_bit(NFS_SP4_MACH_CRED_COMMIT, &flags); } } - +out: + clp->cl_sp4_flags = flags; return 0; } struct nfs41_exchange_id_data { struct nfs41_exchange_id_res res; struct nfs41_exchange_id_args args; - struct rpc_xprt *xprt; - int rpc_status; }; -static void nfs4_exchange_id_done(struct rpc_task *task, void *data) -{ - struct nfs41_exchange_id_data *cdata = - (struct nfs41_exchange_id_data *)data; - struct nfs_client *clp = cdata->args.client; - int status = task->tk_status; - - trace_nfs4_exchange_id(clp, status); - - if (status == 0) - status = nfs4_check_cl_exchange_flags(cdata->res.flags); - - if (cdata->xprt && status == 0) { - status = nfs4_detect_session_trunking(clp, &cdata->res, - cdata->xprt); - goto out; - } - - if (status == 0) - status = nfs4_sp4_select_mode(clp, &cdata->res.state_protect); - - if (status == 0) { - clp->cl_clientid = cdata->res.clientid; - clp->cl_exchange_flags = cdata->res.flags; - clp->cl_seqid = cdata->res.seqid; - /* Client ID is not confirmed */ - if (!(cdata->res.flags & EXCHGID4_FLAG_CONFIRMED_R)) - clear_bit(NFS4_SESSION_ESTABLISHED, - &clp->cl_session->session_state); - - kfree(clp->cl_serverowner); - clp->cl_serverowner = cdata->res.server_owner; - cdata->res.server_owner = NULL; - - /* use the most recent implementation id */ - kfree(clp->cl_implid); - clp->cl_implid = cdata->res.impl_id; - cdata->res.impl_id = NULL; - - if (clp->cl_serverscope != NULL && - !nfs41_same_server_scope(clp->cl_serverscope, - cdata->res.server_scope)) { - dprintk("%s: server_scope mismatch detected\n", - __func__); - set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state); - kfree(clp->cl_serverscope); - clp->cl_serverscope = NULL; - } - - if (clp->cl_serverscope == NULL) { - clp->cl_serverscope = cdata->res.server_scope; - cdata->res.server_scope = NULL; - } - /* Save the EXCHANGE_ID verifier session trunk tests */ - memcpy(clp->cl_confirm.data, cdata->args.verifier->data, - sizeof(clp->cl_confirm.data)); - } -out: - cdata->rpc_status = status; - return; -} - static void nfs4_exchange_id_release(void *data) { struct nfs41_exchange_id_data *cdata = (struct nfs41_exchange_id_data *)data; - if (cdata->xprt) { - xprt_put(cdata->xprt); - rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient); - } nfs_put_client(cdata->args.client); kfree(cdata->res.impl_id); kfree(cdata->res.server_scope); @@ -7486,7 +7447,6 @@ static void nfs4_exchange_id_release(void *data) } static const struct rpc_call_ops nfs4_exchange_id_call_ops = { - .rpc_call_done = nfs4_exchange_id_done, .rpc_release = nfs4_exchange_id_release, }; @@ -7495,10 +7455,10 @@ static const struct rpc_call_ops nfs4_exchange_id_call_ops = { * * Wrapper for EXCHANGE_ID operation. */ -static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, +static struct rpc_task * +nfs4_run_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, u32 sp4_how, struct rpc_xprt *xprt) { - nfs4_verifier verifier; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID], .rpc_cred = cred, @@ -7507,23 +7467,20 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, .rpc_client = clp->cl_rpcclient, .callback_ops = &nfs4_exchange_id_call_ops, .rpc_message = &msg, - .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT, + .flags = RPC_TASK_TIMEOUT, }; struct nfs41_exchange_id_data *calldata; - struct rpc_task *task; int status; if (!atomic_inc_not_zero(&clp->cl_count)) - return -EIO; + return ERR_PTR(-EIO); + status = -ENOMEM; calldata = kzalloc(sizeof(*calldata), GFP_NOFS); - if (!calldata) { - nfs_put_client(clp); - return -ENOMEM; - } + if (!calldata) + goto out; - if (!xprt) - nfs4_init_boot_verifier(clp, &verifier); + nfs4_init_boot_verifier(clp, &calldata->args.verifier); status = nfs4_init_uniform_client_string(clp); if (status) @@ -7560,41 +7517,22 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, goto out_impl_id; } if (xprt) { - calldata->xprt = xprt; task_setup_data.rpc_xprt = xprt; - task_setup_data.flags = - RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC; - calldata->args.verifier = &clp->cl_confirm; - } else { - calldata->args.verifier = &verifier; + task_setup_data.flags |= RPC_TASK_SOFTCONN; + memcpy(calldata->args.verifier.data, clp->cl_confirm.data, + sizeof(calldata->args.verifier.data)); } calldata->args.client = clp; -#ifdef CONFIG_NFS_V4_1_MIGRATION - calldata->args.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER | - EXCHGID4_FLAG_BIND_PRINC_STATEID | - EXCHGID4_FLAG_SUPP_MOVED_MIGR, -#else calldata->args.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER | - EXCHGID4_FLAG_BIND_PRINC_STATEID, + EXCHGID4_FLAG_BIND_PRINC_STATEID; +#ifdef CONFIG_NFS_V4_1_MIGRATION + calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR; #endif msg.rpc_argp = &calldata->args; msg.rpc_resp = &calldata->res; task_setup_data.callback_data = calldata; - task = rpc_run_task(&task_setup_data); - if (IS_ERR(task)) - return PTR_ERR(task); - - if (!xprt) { - status = rpc_wait_for_completion_task(task); - if (!status) - status = calldata->rpc_status; - } else /* session trunking test */ - status = calldata->rpc_status; - - rpc_put_task(task); -out: - return status; + return rpc_run_task(&task_setup_data); out_impl_id: kfree(calldata->res.impl_id); @@ -7604,8 +7542,69 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, kfree(calldata->res.server_owner); out_calldata: kfree(calldata); +out: nfs_put_client(clp); - goto out; + return ERR_PTR(status); +} + +/* + * _nfs4_proc_exchange_id() + * + * Wrapper for EXCHANGE_ID operation. + */ +static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, + u32 sp4_how) +{ + struct rpc_task *task; + struct nfs41_exchange_id_args *argp; + struct nfs41_exchange_id_res *resp; + int status; + + task = nfs4_run_exchange_id(clp, cred, sp4_how, NULL); + if (IS_ERR(task)) + return PTR_ERR(task); + + argp = task->tk_msg.rpc_argp; + resp = task->tk_msg.rpc_resp; + status = task->tk_status; + if (status != 0) + goto out; + + status = nfs4_check_cl_exchange_flags(resp->flags); + if (status != 0) + goto out; + + status = nfs4_sp4_select_mode(clp, &resp->state_protect); + if (status != 0) + goto out; + + clp->cl_clientid = resp->clientid; + clp->cl_exchange_flags = resp->flags; + clp->cl_seqid = resp->seqid; + /* Client ID is not confirmed */ + if (!(resp->flags & EXCHGID4_FLAG_CONFIRMED_R)) + clear_bit(NFS4_SESSION_ESTABLISHED, + &clp->cl_session->session_state); + + if (clp->cl_serverscope != NULL && + !nfs41_same_server_scope(clp->cl_serverscope, + resp->server_scope)) { + dprintk("%s: server_scope mismatch detected\n", + __func__); + set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state); + } + + swap(clp->cl_serverowner, resp->server_owner); + swap(clp->cl_serverscope, resp->server_scope); + swap(clp->cl_implid, resp->impl_id); + + /* Save the EXCHANGE_ID verifier session trunk tests */ + memcpy(clp->cl_confirm.data, argp->verifier.data, + sizeof(clp->cl_confirm.data)); +out: + trace_nfs4_exchange_id(clp, status); + rpc_put_task(task); + return status; } /* @@ -7628,13 +7627,13 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) /* try SP4_MACH_CRED if krb5i/p */ if (authflavor == RPC_AUTH_GSS_KRB5I || authflavor == RPC_AUTH_GSS_KRB5P) { - status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED, NULL); + status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED); if (!status) return 0; } /* try SP4_NONE */ - return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL); + return _nfs4_proc_exchange_id(clp, cred, SP4_NONE); } /** @@ -7656,6 +7655,9 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, void *data) { struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data; + struct rpc_task *task; + int status; + u32 sp4_how; dprintk("--> %s try %s\n", __func__, @@ -7664,7 +7666,17 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED); /* Test connection for session trunking. Async exchange_id call */ - return _nfs4_proc_exchange_id(adata->clp, adata->cred, sp4_how, xprt); + task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt); + if (IS_ERR(task)) + return PTR_ERR(task); + + status = task->tk_status; + if (status == 0) + status = nfs4_detect_session_trunking(adata->clp, + task->tk_msg.rpc_resp, xprt); + + rpc_put_task(task); + return status; } EXPORT_SYMBOL_GPL(nfs4_test_session_trunk); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fa3eb361d4f863be18072272293dcbdcedfd887f..37c8af00327588d772610cac487fcf0651cf8fbf 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1785,7 +1785,7 @@ static void encode_exchange_id(struct xdr_stream *xdr, int len = 0; encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr); - encode_nfs4_verifier(xdr, args->verifier); + encode_nfs4_verifier(xdr, &args->verifier); encode_string(xdr, strlen(args->client->cl_owner_id), args->client->cl_owner_id); diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 2ca9167bc97d0468d7dddc284efbbae56ebd8bbf..551711042ba466dd0cca8fef872d53b659e8a05d 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h @@ -719,6 +719,254 @@ TRACE_EVENT(nfs_sillyrename_unlink, __get_str(name) ) ); + +TRACE_EVENT(nfs_initiate_read, + TP_PROTO( + const struct inode *inode, + loff_t offset, unsigned long count + ), + + TP_ARGS(inode, offset, count), + + TP_STRUCT__entry( + __field(loff_t, offset) + __field(unsigned long, count) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + ), + + TP_fast_assign( + const struct nfs_inode *nfsi = NFS_I(inode); + + __entry->offset = offset; + __entry->count = count; + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = nfsi->fileid; + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); + ), + + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "offset=%lld count=%lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->offset, __entry->count + ) +); + +TRACE_EVENT(nfs_readpage_done, + TP_PROTO( + const struct inode *inode, + int status, loff_t offset, bool eof + ), + + TP_ARGS(inode, status, offset, eof), + + TP_STRUCT__entry( + __field(int, status) + __field(loff_t, offset) + __field(bool, eof) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + ), + + TP_fast_assign( + const struct nfs_inode *nfsi = NFS_I(inode); + + __entry->status = status; + __entry->offset = offset; + __entry->eof = eof; + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = nfsi->fileid; + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); + ), + + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "offset=%lld status=%d%s", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->offset, __entry->status, + __entry->eof ? " eof" : "" + ) +); + +/* + * XXX: I tried using NFS_UNSTABLE and friends in this table, but they + * all evaluate to 0 for some reason, even if I include linux/nfs.h. + */ +#define nfs_show_stable(stable) \ + __print_symbolic(stable, \ + { 0, " (UNSTABLE)" }, \ + { 1, " (DATA_SYNC)" }, \ + { 2, " (FILE_SYNC)" }) + +TRACE_EVENT(nfs_initiate_write, + TP_PROTO( + const struct inode *inode, + loff_t offset, unsigned long count, + enum nfs3_stable_how stable + ), + + TP_ARGS(inode, offset, count, stable), + + TP_STRUCT__entry( + __field(loff_t, offset) + __field(unsigned long, count) + __field(enum nfs3_stable_how, stable) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + ), + + TP_fast_assign( + const struct nfs_inode *nfsi = NFS_I(inode); + + __entry->offset = offset; + __entry->count = count; + __entry->stable = stable; + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = nfsi->fileid; + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); + ), + + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "offset=%lld count=%lu stable=%d%s", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->offset, __entry->count, + __entry->stable, nfs_show_stable(__entry->stable) + ) +); + +TRACE_EVENT(nfs_writeback_done, + TP_PROTO( + const struct inode *inode, + int status, + loff_t offset, + struct nfs_writeverf *writeverf + ), + + TP_ARGS(inode, status, offset, writeverf), + + TP_STRUCT__entry( + __field(int, status) + __field(loff_t, offset) + __field(enum nfs3_stable_how, stable) + __field(unsigned long long, verifier) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + ), + + TP_fast_assign( + const struct nfs_inode *nfsi = NFS_I(inode); + + __entry->status = status; + __entry->offset = offset; + __entry->stable = writeverf->committed; + memcpy(&__entry->verifier, &writeverf->verifier, + sizeof(__entry->verifier)); + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = nfsi->fileid; + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); + ), + + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "offset=%lld status=%d stable=%d%s " + "verifier 0x%016llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->offset, __entry->status, + __entry->stable, nfs_show_stable(__entry->stable), + __entry->verifier + ) +); + +TRACE_EVENT(nfs_initiate_commit, + TP_PROTO( + const struct nfs_commit_data *data + ), + + TP_ARGS(data), + + TP_STRUCT__entry( + __field(loff_t, offset) + __field(unsigned long, count) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + ), + + TP_fast_assign( + const struct inode *inode = data->inode; + const struct nfs_inode *nfsi = NFS_I(inode); + + __entry->offset = data->args.offset; + __entry->count = data->args.count; + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = nfsi->fileid; + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); + ), + + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "offset=%lld count=%lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->offset, __entry->count + ) +); + +TRACE_EVENT(nfs_commit_done, + TP_PROTO( + const struct nfs_commit_data *data + ), + + TP_ARGS(data), + + TP_STRUCT__entry( + __field(int, status) + __field(loff_t, offset) + __field(unsigned long long, verifier) + __field(dev_t, dev) + __field(u32, fhandle) + __field(u64, fileid) + ), + + TP_fast_assign( + const struct inode *inode = data->inode; + const struct nfs_inode *nfsi = NFS_I(inode); + + __entry->status = data->res.op_status; + __entry->offset = data->args.offset; + memcpy(&__entry->verifier, &data->verf.verifier, + sizeof(__entry->verifier)); + __entry->dev = inode->i_sb->s_dev; + __entry->fileid = nfsi->fileid; + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); + ), + + TP_printk( + "fileid=%02x:%02x:%llu fhandle=0x%08x " + "offset=%lld status=%d verifier 0x%016llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->fileid, + __entry->fhandle, + __entry->offset, __entry->status, + __entry->verifier + ) +); + #endif /* _TRACE_NFS_H */ #undef TRACE_INCLUDE_PATH diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index de9066a92c0d27cb9e397233fb5b92116c8dc127..d0543e19098a3327197dfbfead1a589c7e05cdba 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -134,19 +134,14 @@ EXPORT_SYMBOL_GPL(nfs_async_iocounter_wait); /* * nfs_page_group_lock - lock the head of the page group * @req - request in group that is to be locked - * @nonblock - if true don't block waiting for lock * - * this lock must be held if modifying the page group list + * this lock must be held when traversing or modifying the page + * group list * - * return 0 on success, < 0 on error: -EDELAY if nonblocking or the - * result from wait_on_bit_lock - * - * NOTE: calling with nonblock=false should always have set the - * lock bit (see fs/buffer.c and other uses of wait_on_bit_lock - * with TASK_UNINTERRUPTIBLE), so there is no need to check the result. + * return 0 on success, < 0 on error */ int -nfs_page_group_lock(struct nfs_page *req, bool nonblock) +nfs_page_group_lock(struct nfs_page *req) { struct nfs_page *head = req->wb_head; @@ -155,35 +150,10 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock) if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags)) return 0; - if (!nonblock) { - set_bit(PG_CONTENDED1, &head->wb_flags); - smp_mb__after_atomic(); - return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, - TASK_UNINTERRUPTIBLE); - } - - return -EAGAIN; -} - -/* - * nfs_page_group_lock_wait - wait for the lock to clear, but don't grab it - * @req - a request in the group - * - * This is a blocking call to wait for the group lock to be cleared. - */ -void -nfs_page_group_lock_wait(struct nfs_page *req) -{ - struct nfs_page *head = req->wb_head; - - WARN_ON_ONCE(head != head->wb_head); - - if (!test_bit(PG_HEADLOCK, &head->wb_flags)) - return; set_bit(PG_CONTENDED1, &head->wb_flags); smp_mb__after_atomic(); - wait_on_bit(&head->wb_flags, PG_HEADLOCK, - TASK_UNINTERRUPTIBLE); + return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, + TASK_UNINTERRUPTIBLE); } /* @@ -246,7 +216,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit) { bool ret; - nfs_page_group_lock(req, false); + nfs_page_group_lock(req); ret = nfs_page_group_sync_on_bit_locked(req, bit); nfs_page_group_unlock(req); @@ -288,9 +258,7 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev) inode = page_file_mapping(req->wb_page)->host; set_bit(PG_INODE_REF, &req->wb_flags); kref_get(&req->wb_kref); - spin_lock(&inode->i_lock); - NFS_I(inode)->nrequests++; - spin_unlock(&inode->i_lock); + atomic_long_inc(&NFS_I(inode)->nrequests); } } } @@ -306,14 +274,11 @@ static void nfs_page_group_destroy(struct kref *kref) { struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref); + struct nfs_page *head = req->wb_head; struct nfs_page *tmp, *next; - /* subrequests must release the ref on the head request */ - if (req->wb_head != req) - nfs_release_request(req->wb_head); - if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN)) - return; + goto out; tmp = req; do { @@ -324,6 +289,10 @@ nfs_page_group_destroy(struct kref *kref) nfs_free_request(tmp); tmp = next; } while (tmp != req); +out: + /* subrequests must release the ref on the head request */ + if (head != req) + nfs_release_request(head); } /** @@ -465,6 +434,7 @@ void nfs_release_request(struct nfs_page *req) { kref_put(&req->wb_kref, nfs_page_group_destroy); } +EXPORT_SYMBOL_GPL(nfs_release_request); /** * nfs_wait_on_request - Wait for a request to complete. @@ -483,6 +453,7 @@ nfs_wait_on_request(struct nfs_page *req) return wait_on_bit_io(&req->wb_flags, PG_BUSY, TASK_UNINTERRUPTIBLE); } +EXPORT_SYMBOL_GPL(nfs_wait_on_request); /* * nfs_generic_pg_test - determine if requests can be coalesced @@ -530,16 +501,6 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *ops) } EXPORT_SYMBOL_GPL(nfs_pgio_header_alloc); -/* - * nfs_pgio_header_free - Free a read or write header - * @hdr: The header to free - */ -void nfs_pgio_header_free(struct nfs_pgio_header *hdr) -{ - hdr->rw_ops->rw_free_header(hdr); -} -EXPORT_SYMBOL_GPL(nfs_pgio_header_free); - /** * nfs_pgio_data_destroy - make @hdr suitable for reuse * @@ -548,14 +509,24 @@ EXPORT_SYMBOL_GPL(nfs_pgio_header_free); * * @hdr: A header that has had nfs_generic_pgio called */ -void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr) +static void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr) { if (hdr->args.context) put_nfs_open_context(hdr->args.context); if (hdr->page_array.pagevec != hdr->page_array.page_array) kfree(hdr->page_array.pagevec); } -EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy); + +/* + * nfs_pgio_header_free - Free a read or write header + * @hdr: The header to free + */ +void nfs_pgio_header_free(struct nfs_pgio_header *hdr) +{ + nfs_pgio_data_destroy(hdr); + hdr->rw_ops->rw_free_header(hdr); +} +EXPORT_SYMBOL_GPL(nfs_pgio_header_free); /** * nfs_pgio_rpcsetup - Set up arguments for a pageio call @@ -669,7 +640,6 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio); static void nfs_pgio_error(struct nfs_pgio_header *hdr) { set_bit(NFS_IOHDR_REDO, &hdr->flags); - nfs_pgio_data_destroy(hdr); hdr->completion_ops->completion(hdr); } @@ -680,7 +650,6 @@ static void nfs_pgio_error(struct nfs_pgio_header *hdr) static void nfs_pgio_release(void *calldata) { struct nfs_pgio_header *hdr = calldata; - nfs_pgio_data_destroy(hdr); hdr->completion_ops->completion(hdr); } @@ -711,12 +680,8 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, const struct nfs_pgio_completion_ops *compl_ops, const struct nfs_rw_ops *rw_ops, size_t bsize, - int io_flags, - gfp_t gfp_flags) + int io_flags) { - struct nfs_pgio_mirror *new; - int i; - desc->pg_moreio = 0; desc->pg_inode = inode; desc->pg_ops = pg_ops; @@ -732,23 +697,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, desc->pg_mirror_count = 1; desc->pg_mirror_idx = 0; - if (pg_ops->pg_get_mirror_count) { - /* until we have a request, we don't have an lseg and no - * idea how many mirrors there will be */ - new = kcalloc(NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX, - sizeof(struct nfs_pgio_mirror), gfp_flags); - desc->pg_mirrors_dynamic = new; - desc->pg_mirrors = new; - - for (i = 0; i < NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX; i++) - nfs_pageio_mirror_init(&desc->pg_mirrors[i], bsize); - } else { - desc->pg_mirrors_dynamic = NULL; - desc->pg_mirrors = desc->pg_mirrors_static; - nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize); - } + desc->pg_mirrors_dynamic = NULL; + desc->pg_mirrors = desc->pg_mirrors_static; + nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize); } -EXPORT_SYMBOL_GPL(nfs_pageio_init); /** * nfs_pgio_result - Basic pageio error handling @@ -865,32 +817,52 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) return ret; } +static struct nfs_pgio_mirror * +nfs_pageio_alloc_mirrors(struct nfs_pageio_descriptor *desc, + unsigned int mirror_count) +{ + struct nfs_pgio_mirror *ret; + unsigned int i; + + kfree(desc->pg_mirrors_dynamic); + desc->pg_mirrors_dynamic = NULL; + if (mirror_count == 1) + return desc->pg_mirrors_static; + ret = kmalloc_array(mirror_count, sizeof(*ret), GFP_NOFS); + if (ret != NULL) { + for (i = 0; i < mirror_count; i++) + nfs_pageio_mirror_init(&ret[i], desc->pg_bsize); + desc->pg_mirrors_dynamic = ret; + } + return ret; +} + /* * nfs_pageio_setup_mirroring - determine if mirroring is to be used * by calling the pg_get_mirror_count op */ -static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio, +static void nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) { - int mirror_count = 1; - - if (!pgio->pg_ops->pg_get_mirror_count) - return 0; + unsigned int mirror_count = 1; - mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); - - if (pgio->pg_error < 0) - return pgio->pg_error; - - if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) - return -EINVAL; + if (pgio->pg_ops->pg_get_mirror_count) + mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); + if (mirror_count == pgio->pg_mirror_count || pgio->pg_error < 0) + return; - if (WARN_ON_ONCE(!pgio->pg_mirrors_dynamic)) - return -EINVAL; + if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) { + pgio->pg_error = -EINVAL; + return; + } + pgio->pg_mirrors = nfs_pageio_alloc_mirrors(pgio, mirror_count); + if (pgio->pg_mirrors == NULL) { + pgio->pg_error = -ENOMEM; + pgio->pg_mirrors = pgio->pg_mirrors_static; + mirror_count = 1; + } pgio->pg_mirror_count = mirror_count; - - return 0; } /* @@ -1036,7 +1008,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, unsigned int bytes_left = 0; unsigned int offset, pgbase; - nfs_page_group_lock(req, false); + nfs_page_group_lock(req); subreq = req; bytes_left = subreq->wb_bytes; @@ -1058,7 +1030,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, if (mirror->pg_recoalesce) return 0; /* retry add_request for this subreq */ - nfs_page_group_lock(req, false); + nfs_page_group_lock(req); continue; } @@ -1155,7 +1127,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, for (midx = 0; midx < desc->pg_mirror_count; midx++) { if (midx) { - nfs_page_group_lock(req, false); + nfs_page_group_lock(req); /* find the last request */ for (lastreq = req->wb_head; @@ -1198,8 +1170,8 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, /* remember fatal errors */ if (nfs_error_is_fatal(desc->pg_error)) - mapping_set_error(desc->pg_inode->i_mapping, - desc->pg_error); + nfs_context_set_write_error(req->wb_context, + desc->pg_error); func = desc->pg_completion_ops->error_cleanup; for (midx = 0; midx < desc->pg_mirror_count; midx++) { diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index c383d0913b54c90fb96020a62faaf989a5d946b3..3bcd669a315237158dea7505bde6fd9f9dcfcec6 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -529,47 +529,6 @@ pnfs_put_lseg(struct pnfs_layout_segment *lseg) } EXPORT_SYMBOL_GPL(pnfs_put_lseg); -static void pnfs_free_lseg_async_work(struct work_struct *work) -{ - struct pnfs_layout_segment *lseg; - struct pnfs_layout_hdr *lo; - - lseg = container_of(work, struct pnfs_layout_segment, pls_work); - lo = lseg->pls_layout; - - pnfs_free_lseg(lseg); - pnfs_put_layout_hdr(lo); -} - -static void pnfs_free_lseg_async(struct pnfs_layout_segment *lseg) -{ - INIT_WORK(&lseg->pls_work, pnfs_free_lseg_async_work); - schedule_work(&lseg->pls_work); -} - -void -pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg) -{ - if (!lseg) - return; - - assert_spin_locked(&lseg->pls_layout->plh_inode->i_lock); - - dprintk("%s: lseg %p ref %d valid %d\n", __func__, lseg, - atomic_read(&lseg->pls_refcount), - test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); - if (atomic_dec_and_test(&lseg->pls_refcount)) { - struct pnfs_layout_hdr *lo = lseg->pls_layout; - if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags)) - return; - pnfs_layout_remove_lseg(lo, lseg); - if (!pnfs_cache_lseg_for_layoutreturn(lo, lseg)) { - pnfs_get_layout_hdr(lo); - pnfs_free_lseg_async(lseg); - } - } -} - /* * is l2 fully contained in l1? * start1 end1 @@ -1705,7 +1664,7 @@ pnfs_update_layout(struct inode *ino, .offset = pos, .length = count, }; - unsigned pg_offset, seq; + unsigned pg_offset; struct nfs_server *server = NFS_SERVER(ino); struct nfs_client *clp = server->nfs_client; struct pnfs_layout_hdr *lo = NULL; @@ -1795,10 +1754,14 @@ pnfs_update_layout(struct inode *ino, } first = true; - do { - seq = read_seqbegin(&ctx->state->seqlock); - nfs4_stateid_copy(&stateid, &ctx->state->stateid); - } while (read_seqretry(&ctx->state->seqlock, seq)); + if (nfs4_select_rw_stateid(ctx->state, + iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ, + NULL, &stateid, NULL) != 0) { + trace_pnfs_update_layout(ino, pos, count, + iomode, lo, lseg, + PNFS_UPDATE_LAYOUT_INVALID_OPEN); + goto out_unlock; + } } else { nfs4_stateid_copy(&stateid, &lo->plh_stateid); } @@ -2274,7 +2237,6 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc, nfs_pageio_reset_write_mds(desc); mirror->pg_recoalesce = 1; } - nfs_pgio_data_destroy(hdr); hdr->release(hdr); } @@ -2398,7 +2360,6 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, nfs_pageio_reset_read_mds(desc); mirror->pg_recoalesce = 1; } - nfs_pgio_data_destroy(hdr); hdr->release(hdr); } diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 99731e3e332f3ec32eec26cca47556193dcf68fe..87f144f14d1e0c0c6c3232cc54c6e6b4167d5c24 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -67,7 +67,6 @@ struct pnfs_layout_segment { u32 pls_seq; unsigned long pls_flags; struct pnfs_layout_hdr *pls_layout; - struct work_struct pls_work; }; enum pnfs_try_status { @@ -230,7 +229,6 @@ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync); /* pnfs.c */ void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo); void pnfs_put_lseg(struct pnfs_layout_segment *lseg); -void pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg); void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, struct nfs_fsinfo *); void unset_pnfs_layoutdriver(struct nfs_server *); diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 25f28fa64c575129130d916d566674da792376ae..60da59be83b6128241bf3be4a93e153e0329421a 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -83,33 +83,10 @@ pnfs_generic_clear_request_commit(struct nfs_page *req, } out: nfs_request_remove_commit_list(req, cinfo); - pnfs_put_lseg_locked(freeme); + pnfs_put_lseg(freeme); } EXPORT_SYMBOL_GPL(pnfs_generic_clear_request_commit); -static int -pnfs_generic_transfer_commit_list(struct list_head *src, struct list_head *dst, - struct nfs_commit_info *cinfo, int max) -{ - struct nfs_page *req, *tmp; - int ret = 0; - - list_for_each_entry_safe(req, tmp, src, wb_list) { - if (!nfs_lock_request(req)) - continue; - kref_get(&req->wb_kref); - if (cond_resched_lock(&cinfo->inode->i_lock)) - list_safe_reset_next(req, tmp, wb_list); - nfs_request_remove_commit_list(req, cinfo); - clear_bit(PG_COMMIT_TO_DS, &req->wb_flags); - nfs_list_add_request(req, dst); - ret++; - if ((ret == max) && !cinfo->dreq) - break; - } - return ret; -} - static int pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket, struct nfs_commit_info *cinfo, @@ -119,15 +96,15 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket, struct list_head *dst = &bucket->committing; int ret; - lockdep_assert_held(&cinfo->inode->i_lock); - ret = pnfs_generic_transfer_commit_list(src, dst, cinfo, max); + lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex); + ret = nfs_scan_commit_list(src, dst, cinfo, max); if (ret) { cinfo->ds->nwritten -= ret; cinfo->ds->ncommitting += ret; if (bucket->clseg == NULL) bucket->clseg = pnfs_get_lseg(bucket->wlseg); if (list_empty(src)) { - pnfs_put_lseg_locked(bucket->wlseg); + pnfs_put_lseg(bucket->wlseg); bucket->wlseg = NULL; } } @@ -142,7 +119,7 @@ int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, { int i, rv = 0, cnt; - lockdep_assert_held(&cinfo->inode->i_lock); + lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex); for (i = 0; i < cinfo->ds->nbuckets && max != 0; i++) { cnt = pnfs_generic_scan_ds_commit_list(&cinfo->ds->buckets[i], cinfo, max); @@ -162,11 +139,10 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst, int nwritten; int i; - lockdep_assert_held(&cinfo->inode->i_lock); + lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex); restart: for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) { - nwritten = pnfs_generic_transfer_commit_list(&b->written, - dst, cinfo, 0); + nwritten = nfs_scan_commit_list(&b->written, dst, cinfo, 0); if (!nwritten) continue; cinfo->ds->nwritten -= nwritten; @@ -953,12 +929,12 @@ pnfs_layout_mark_request_commit(struct nfs_page *req, struct list_head *list; struct pnfs_commit_bucket *buckets; - spin_lock(&cinfo->inode->i_lock); + mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); buckets = cinfo->ds->buckets; list = &buckets[ds_commit_idx].written; if (list_empty(list)) { if (!pnfs_is_valid_lseg(lseg)) { - spin_unlock(&cinfo->inode->i_lock); + mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); cinfo->completion_ops->resched_write(cinfo, req); return; } @@ -975,7 +951,7 @@ pnfs_layout_mark_request_commit(struct nfs_page *req, cinfo->ds->nwritten++; nfs_request_add_commit_list_locked(req, list, cinfo); - spin_unlock(&cinfo->inode->i_lock); + mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); nfs_mark_page_unstable(req->wb_page, cinfo); } EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index a8421d9dab6a125c4eb6b7ad9f074d8ce91a5a99..48d7277c60a9793b3684e9587a69d26af410a8fb 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -25,6 +25,7 @@ #include "iostat.h" #include "fscache.h" #include "pnfs.h" +#include "nfstrace.h" #define NFSDBG_FACILITY NFSDBG_PAGECACHE @@ -68,7 +69,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, pg_ops = server->pnfs_curr_ld->pg_read_ops; #endif nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_read_ops, - server->rsize, 0, GFP_KERNEL); + server->rsize, 0); } EXPORT_SYMBOL_GPL(nfs_pageio_init_read); @@ -200,6 +201,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr, task_setup_data->flags |= swap_flags; rpc_ops->read_setup(hdr, msg); + trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes); } static void @@ -232,6 +234,8 @@ static int nfs_readpage_done(struct rpc_task *task, return status; nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count); + trace_nfs_readpage_done(inode, task->tk_status, + hdr->args.offset, hdr->res.eof); if (task->tk_status == -ESTALE) { set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d828ef88e7db63e83b74e34ef918bee0fbe2b362..c9d24bae302514957435350f8a8a560e98c8a961 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -812,7 +812,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root) * Display all mount option settings */ seq_printf(m, "\n\topts:\t"); - seq_puts(m, root->d_sb->s_flags & MS_RDONLY ? "ro" : "rw"); + seq_puts(m, sb_rdonly(root->d_sb) ? "ro" : "rw"); seq_puts(m, root->d_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : ""); seq_puts(m, root->d_sb->s_flags & MS_NOATIME ? ",noatime" : ""); seq_puts(m, root->d_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : ""); @@ -1691,8 +1691,8 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, rpc_authflavor_t *server_authlist, unsigned int count) { rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR; + bool found_auth_null = false; unsigned int i; - int use_auth_null = false; /* * If the sec= mount option is used, the specified flavor or AUTH_NULL @@ -1701,6 +1701,10 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, * AUTH_NULL has a special meaning when it's in the server list - it * means that the server will ignore the rpc creds, so any flavor * can be used but still use the sec= that was specified. + * + * Note also that the MNT procedure in MNTv1 does not return a list + * of supported security flavors. In this case, nfs_mount() fabricates + * a security flavor list containing just AUTH_NULL. */ for (i = 0; i < count; i++) { flavor = server_authlist[i]; @@ -1709,11 +1713,11 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, goto out; if (flavor == RPC_AUTH_NULL) - use_auth_null = true; + found_auth_null = true; } - if (use_auth_null) { - flavor = RPC_AUTH_NULL; + if (found_auth_null) { + flavor = args->auth_info.flavors[0]; goto out; } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b1af5dee5e0a87fdbd370bfdd9277d331aa4c721..babebbccae2a0e11f12cf722a1b8dccdea75a6b8 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -102,10 +102,8 @@ static struct nfs_pgio_header *nfs_writehdr_alloc(void) { struct nfs_pgio_header *p = mempool_alloc(nfs_wdata_mempool, GFP_NOIO); - if (p) { - memset(p, 0, sizeof(*p)); - p->rw_mode = FMODE_WRITE; - } + memset(p, 0, sizeof(*p)); + p->rw_mode = FMODE_WRITE; return p; } @@ -147,11 +145,12 @@ static void nfs_io_completion_put(struct nfs_io_completion *ioc) kref_put(&ioc->refcount, nfs_io_completion_release); } -static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) +static struct nfs_page * +nfs_page_private_request(struct page *page) { - ctx->error = error; - smp_wmb(); - set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); + if (!PagePrivate(page)) + return NULL; + return (struct nfs_page *)page_private(page); } /* @@ -162,21 +161,41 @@ static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) * returns matching head request with reference held, or NULL if not found. */ static struct nfs_page * -nfs_page_find_head_request_locked(struct nfs_inode *nfsi, struct page *page) +nfs_page_find_private_request(struct page *page) { - struct nfs_page *req = NULL; - - if (PagePrivate(page)) - req = (struct nfs_page *)page_private(page); - else if (unlikely(PageSwapCache(page))) - req = nfs_page_search_commits_for_head_request_locked(nfsi, - page); + struct address_space *mapping = page_file_mapping(page); + struct nfs_page *req; + if (!PagePrivate(page)) + return NULL; + spin_lock(&mapping->private_lock); + req = nfs_page_private_request(page); if (req) { WARN_ON_ONCE(req->wb_head != req); kref_get(&req->wb_kref); } + spin_unlock(&mapping->private_lock); + return req; +} +static struct nfs_page * +nfs_page_find_swap_request(struct page *page) +{ + struct inode *inode = page_file_mapping(page)->host; + struct nfs_inode *nfsi = NFS_I(inode); + struct nfs_page *req = NULL; + if (!PageSwapCache(page)) + return NULL; + mutex_lock(&nfsi->commit_mutex); + if (PageSwapCache(page)) { + req = nfs_page_search_commits_for_head_request_locked(nfsi, + page); + if (req) { + WARN_ON_ONCE(req->wb_head != req); + kref_get(&req->wb_kref); + } + } + mutex_unlock(&nfsi->commit_mutex); return req; } @@ -187,12 +206,11 @@ nfs_page_find_head_request_locked(struct nfs_inode *nfsi, struct page *page) */ static struct nfs_page *nfs_page_find_head_request(struct page *page) { - struct inode *inode = page_file_mapping(page)->host; - struct nfs_page *req = NULL; + struct nfs_page *req; - spin_lock(&inode->i_lock); - req = nfs_page_find_head_request_locked(NFS_I(inode), page); - spin_unlock(&inode->i_lock); + req = nfs_page_find_private_request(page); + if (!req) + req = nfs_page_find_swap_request(page); return req; } @@ -241,9 +259,6 @@ nfs_page_group_search_locked(struct nfs_page *head, unsigned int page_offset) { struct nfs_page *req; - WARN_ON_ONCE(head != head->wb_head); - WARN_ON_ONCE(!test_bit(PG_HEADLOCK, &head->wb_head->wb_flags)); - req = head; do { if (page_offset >= req->wb_pgbase && @@ -269,20 +284,17 @@ static bool nfs_page_group_covers_page(struct nfs_page *req) unsigned int pos = 0; unsigned int len = nfs_page_length(req->wb_page); - nfs_page_group_lock(req, false); + nfs_page_group_lock(req); - do { + for (;;) { tmp = nfs_page_group_search_locked(req->wb_head, pos); - if (tmp) { - /* no way this should happen */ - WARN_ON_ONCE(tmp->wb_pgbase != pos); - pos += tmp->wb_bytes - (pos - tmp->wb_pgbase); - } - } while (tmp && pos < len); + if (!tmp) + break; + pos = tmp->wb_pgbase + tmp->wb_bytes; + } nfs_page_group_unlock(req); - WARN_ON_ONCE(pos > len); - return pos == len; + return pos >= len; } /* We can set the PG_uptodate flag if we see that a write request @@ -333,8 +345,11 @@ static void nfs_end_page_writeback(struct nfs_page *req) { struct inode *inode = page_file_mapping(req->wb_page)->host; struct nfs_server *nfss = NFS_SERVER(inode); + bool is_done; - if (!nfs_page_group_sync_on_bit(req, PG_WB_END)) + is_done = nfs_page_group_sync_on_bit(req, PG_WB_END); + nfs_unlock_request(req); + if (!is_done) return; end_page_writeback(req->wb_page); @@ -342,22 +357,6 @@ static void nfs_end_page_writeback(struct nfs_page *req) clear_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC); } - -/* nfs_page_group_clear_bits - * @req - an nfs request - * clears all page group related bits from @req - */ -static void -nfs_page_group_clear_bits(struct nfs_page *req) -{ - clear_bit(PG_TEARDOWN, &req->wb_flags); - clear_bit(PG_UNLOCKPAGE, &req->wb_flags); - clear_bit(PG_UPTODATE, &req->wb_flags); - clear_bit(PG_WB_END, &req->wb_flags); - clear_bit(PG_REMOVE, &req->wb_flags); -} - - /* * nfs_unroll_locks_and_wait - unlock all newly locked reqs and wait on @req * @@ -366,43 +365,24 @@ nfs_page_group_clear_bits(struct nfs_page *req) * @inode - inode associated with request page group, must be holding inode lock * @head - head request of page group, must be holding head lock * @req - request that couldn't lock and needs to wait on the req bit lock - * @nonblock - if true, don't actually wait * - * NOTE: this must be called holding page_group bit lock and inode spin lock - * and BOTH will be released before returning. + * NOTE: this must be called holding page_group bit lock + * which will be released before returning. * * returns 0 on success, < 0 on error. */ -static int -nfs_unroll_locks_and_wait(struct inode *inode, struct nfs_page *head, - struct nfs_page *req, bool nonblock) - __releases(&inode->i_lock) +static void +nfs_unroll_locks(struct inode *inode, struct nfs_page *head, + struct nfs_page *req) { struct nfs_page *tmp; - int ret; /* relinquish all the locks successfully grabbed this run */ - for (tmp = head ; tmp != req; tmp = tmp->wb_this_page) - nfs_unlock_request(tmp); - - WARN_ON_ONCE(test_bit(PG_TEARDOWN, &req->wb_flags)); - - /* grab a ref on the request that will be waited on */ - kref_get(&req->wb_kref); - - nfs_page_group_unlock(head); - spin_unlock(&inode->i_lock); - - /* release ref from nfs_page_find_head_request_locked */ - nfs_release_request(head); - - if (!nonblock) - ret = nfs_wait_on_request(req); - else - ret = -EAGAIN; - nfs_release_request(req); - - return ret; + for (tmp = head->wb_this_page ; tmp != req; tmp = tmp->wb_this_page) { + if (!kref_read(&tmp->wb_kref)) + continue; + nfs_unlock_and_release_request(tmp); + } } /* @@ -417,7 +397,8 @@ nfs_unroll_locks_and_wait(struct inode *inode, struct nfs_page *head, */ static void nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, - struct nfs_page *old_head) + struct nfs_page *old_head, + struct inode *inode) { while (destroy_list) { struct nfs_page *subreq = destroy_list; @@ -428,33 +409,28 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, WARN_ON_ONCE(old_head != subreq->wb_head); /* make sure old group is not used */ - subreq->wb_head = subreq; subreq->wb_this_page = subreq; - /* subreq is now totally disconnected from page group or any - * write / commit lists. last chance to wake any waiters */ - nfs_unlock_request(subreq); + clear_bit(PG_REMOVE, &subreq->wb_flags); - if (!test_bit(PG_TEARDOWN, &subreq->wb_flags)) { - /* release ref on old head request */ - nfs_release_request(old_head); + /* Note: races with nfs_page_group_destroy() */ + if (!kref_read(&subreq->wb_kref)) { + /* Check if we raced with nfs_page_group_destroy() */ + if (test_and_clear_bit(PG_TEARDOWN, &subreq->wb_flags)) + nfs_free_request(subreq); + continue; + } - nfs_page_group_clear_bits(subreq); + subreq->wb_head = subreq; - /* release the PG_INODE_REF reference */ - if (test_and_clear_bit(PG_INODE_REF, &subreq->wb_flags)) - nfs_release_request(subreq); - else - WARN_ON_ONCE(1); - } else { - WARN_ON_ONCE(test_bit(PG_CLEAN, &subreq->wb_flags)); - /* zombie requests have already released the last - * reference and were waiting on the rest of the - * group to complete. Since it's no longer part of a - * group, simply free the request */ - nfs_page_group_clear_bits(subreq); - nfs_free_request(subreq); + if (test_and_clear_bit(PG_INODE_REF, &subreq->wb_flags)) { + nfs_release_request(subreq); + atomic_long_dec(&NFS_I(inode)->nrequests); } + + /* subreq is now totally disconnected from page group or any + * write / commit lists. last chance to wake any waiters */ + nfs_unlock_and_release_request(subreq); } } @@ -464,7 +440,6 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, * operations for this page. * * @page - the page used to lookup the "page group" of nfs_page structures - * @nonblock - if true, don't block waiting for request locks * * This function joins all sub requests to the head request by first * locking all requests in the group, cancelling any pending operations @@ -478,7 +453,7 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, * error was encountered. */ static struct nfs_page * -nfs_lock_and_join_requests(struct page *page, bool nonblock) +nfs_lock_and_join_requests(struct page *page) { struct inode *inode = page_file_mapping(page)->host; struct nfs_page *head, *subreq; @@ -487,43 +462,63 @@ nfs_lock_and_join_requests(struct page *page, bool nonblock) int ret; try_again: - total_bytes = 0; - - WARN_ON_ONCE(destroy_list); - - spin_lock(&inode->i_lock); - /* * A reference is taken only on the head request which acts as a * reference to the whole page group - the group will not be destroyed * until the head reference is released. */ - head = nfs_page_find_head_request_locked(NFS_I(inode), page); - - if (!head) { - spin_unlock(&inode->i_lock); + head = nfs_page_find_head_request(page); + if (!head) return NULL; - } - /* holding inode lock, so always make a non-blocking call to try the - * page group lock */ - ret = nfs_page_group_lock(head, true); - if (ret < 0) { - spin_unlock(&inode->i_lock); + /* lock the page head first in order to avoid an ABBA inefficiency */ + if (!nfs_lock_request(head)) { + ret = nfs_wait_on_request(head); + nfs_release_request(head); + if (ret < 0) + return ERR_PTR(ret); + goto try_again; + } - if (!nonblock && ret == -EAGAIN) { - nfs_page_group_lock_wait(head); - nfs_release_request(head); - goto try_again; - } + /* Ensure that nobody removed the request before we locked it */ + if (head != nfs_page_private_request(page) && !PageSwapCache(page)) { + nfs_unlock_and_release_request(head); + goto try_again; + } - nfs_release_request(head); + ret = nfs_page_group_lock(head); + if (ret < 0) { + nfs_unlock_and_release_request(head); return ERR_PTR(ret); } /* lock each request in the page group */ - subreq = head; - do { + total_bytes = head->wb_bytes; + for (subreq = head->wb_this_page; subreq != head; + subreq = subreq->wb_this_page) { + + if (!kref_get_unless_zero(&subreq->wb_kref)) { + if (subreq->wb_offset == head->wb_offset + total_bytes) + total_bytes += subreq->wb_bytes; + continue; + } + + while (!nfs_lock_request(subreq)) { + /* + * Unlock page to allow nfs_page_group_sync_on_bit() + * to succeed + */ + nfs_page_group_unlock(head); + ret = nfs_wait_on_request(subreq); + if (!ret) + ret = nfs_page_group_lock(head); + if (ret < 0) { + nfs_unroll_locks(inode, head, subreq); + nfs_release_request(subreq); + nfs_unlock_and_release_request(head); + return ERR_PTR(ret); + } + } /* * Subrequests are always contiguous, non overlapping * and in order - but may be repeated (mirrored writes). @@ -535,24 +530,12 @@ nfs_lock_and_join_requests(struct page *page, bool nonblock) ((subreq->wb_offset + subreq->wb_bytes) > (head->wb_offset + total_bytes)))) { nfs_page_group_unlock(head); - spin_unlock(&inode->i_lock); + nfs_unroll_locks(inode, head, subreq); + nfs_unlock_and_release_request(subreq); + nfs_unlock_and_release_request(head); return ERR_PTR(-EIO); } - - if (!nfs_lock_request(subreq)) { - /* releases page group bit lock and - * inode spin lock and all references */ - ret = nfs_unroll_locks_and_wait(inode, head, - subreq, nonblock); - - if (ret == 0) - goto try_again; - - return ERR_PTR(ret); - } - - subreq = subreq->wb_this_page; - } while (subreq != head); + } /* Now that all requests are locked, make sure they aren't on any list. * Commit list removal accounting is done after locks are dropped */ @@ -573,34 +556,30 @@ nfs_lock_and_join_requests(struct page *page, bool nonblock) head->wb_bytes = total_bytes; } - /* - * prepare head request to be added to new pgio descriptor - */ - nfs_page_group_clear_bits(head); - - /* - * some part of the group was still on the inode list - otherwise - * the group wouldn't be involved in async write. - * grab a reference for the head request, iff it needs one. - */ - if (!test_and_set_bit(PG_INODE_REF, &head->wb_flags)) + /* Postpone destruction of this request */ + if (test_and_clear_bit(PG_REMOVE, &head->wb_flags)) { + set_bit(PG_INODE_REF, &head->wb_flags); kref_get(&head->wb_kref); + atomic_long_inc(&NFS_I(inode)->nrequests); + } nfs_page_group_unlock(head); - /* drop lock to clean uprequests on destroy list */ - spin_unlock(&inode->i_lock); + nfs_destroy_unlinked_subrequests(destroy_list, head, inode); - nfs_destroy_unlinked_subrequests(destroy_list, head); + /* Did we lose a race with nfs_inode_remove_request()? */ + if (!(PagePrivate(page) || PageSwapCache(page))) { + nfs_unlock_and_release_request(head); + return NULL; + } - /* still holds ref on head from nfs_page_find_head_request_locked + /* still holds ref on head from nfs_page_find_head_request * and still has lock on head from lock loop */ return head; } static void nfs_write_error_remove_page(struct nfs_page *req) { - nfs_unlock_request(req); nfs_end_page_writeback(req); generic_error_remove_page(page_file_mapping(req->wb_page), req->wb_page); @@ -624,12 +603,12 @@ nfs_error_is_fatal_on_server(int err) * May return an error if the user signalled nfs_wait_on_request(). */ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, - struct page *page, bool nonblock) + struct page *page) { struct nfs_page *req; int ret = 0; - req = nfs_lock_and_join_requests(page, nonblock); + req = nfs_lock_and_join_requests(page); if (!req) goto out; ret = PTR_ERR(req); @@ -672,7 +651,7 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, int ret; nfs_pageio_cond_complete(pgio, page_index(page)); - ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE); + ret = nfs_page_async_flush(pgio, page); if (ret == -EAGAIN) { redirty_page_for_writepage(wbc, page); ret = 0; @@ -759,6 +738,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) */ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) { + struct address_space *mapping = page_file_mapping(req->wb_page); struct nfs_inode *nfsi = NFS_I(inode); WARN_ON_ONCE(req->wb_this_page != req); @@ -766,27 +746,30 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) /* Lock the request! */ nfs_lock_request(req); - spin_lock(&inode->i_lock); - if (!nfsi->nrequests && - NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) - inode->i_version++; /* * Swap-space should not get truncated. Hence no need to plug the race * with invalidate/truncate. */ + spin_lock(&mapping->private_lock); + if (!nfs_have_writebacks(inode) && + NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) { + spin_lock(&inode->i_lock); + inode->i_version++; + spin_unlock(&inode->i_lock); + } if (likely(!PageSwapCache(req->wb_page))) { set_bit(PG_MAPPED, &req->wb_flags); SetPagePrivate(req->wb_page); set_page_private(req->wb_page, (unsigned long)req); } - nfsi->nrequests++; + spin_unlock(&mapping->private_lock); + atomic_long_inc(&nfsi->nrequests); /* this a head request for a page group - mark it as having an * extra reference so sub groups can follow suit. * This flag also informs pgio layer when to bump nrequests when * adding subrequests. */ WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags)); kref_get(&req->wb_kref); - spin_unlock(&inode->i_lock); } /* @@ -794,25 +777,22 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) */ static void nfs_inode_remove_request(struct nfs_page *req) { - struct inode *inode = d_inode(req->wb_context->dentry); + struct address_space *mapping = page_file_mapping(req->wb_page); + struct inode *inode = mapping->host; struct nfs_inode *nfsi = NFS_I(inode); struct nfs_page *head; + atomic_long_dec(&nfsi->nrequests); if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) { head = req->wb_head; - spin_lock(&inode->i_lock); + spin_lock(&mapping->private_lock); if (likely(head->wb_page && !PageSwapCache(head->wb_page))) { set_page_private(head->wb_page, 0); ClearPagePrivate(head->wb_page); clear_bit(PG_MAPPED, &head->wb_flags); } - nfsi->nrequests--; - spin_unlock(&inode->i_lock); - } else { - spin_lock(&inode->i_lock); - nfsi->nrequests--; - spin_unlock(&inode->i_lock); + spin_unlock(&mapping->private_lock); } if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) @@ -868,7 +848,8 @@ nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi, * number of outstanding requests requiring a commit as well as * the MM page stats. * - * The caller must hold cinfo->inode->i_lock, and the nfs_page lock. + * The caller must hold NFS_I(cinfo->inode)->commit_mutex, and the + * nfs_page lock. */ void nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst, @@ -876,7 +857,7 @@ nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst, { set_bit(PG_CLEAN, &req->wb_flags); nfs_list_add_request(req, dst); - cinfo->mds->ncommit++; + atomic_long_inc(&cinfo->mds->ncommit); } EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked); @@ -896,9 +877,9 @@ EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked); void nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo) { - spin_lock(&cinfo->inode->i_lock); + mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo); - spin_unlock(&cinfo->inode->i_lock); + mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); if (req->wb_page) nfs_mark_page_unstable(req->wb_page, cinfo); } @@ -922,7 +903,7 @@ nfs_request_remove_commit_list(struct nfs_page *req, if (!test_and_clear_bit(PG_CLEAN, &(req)->wb_flags)) return; nfs_list_remove_request(req); - cinfo->mds->ncommit--; + atomic_long_dec(&cinfo->mds->ncommit); } EXPORT_SYMBOL_GPL(nfs_request_remove_commit_list); @@ -967,7 +948,7 @@ nfs_clear_page_commit(struct page *page) WB_RECLAIMABLE); } -/* Called holding inode (/cinfo) lock */ +/* Called holding the request lock on @req */ static void nfs_clear_request_commit(struct nfs_page *req) { @@ -976,9 +957,11 @@ nfs_clear_request_commit(struct nfs_page *req) struct nfs_commit_info cinfo; nfs_init_cinfo_from_inode(&cinfo, inode); + mutex_lock(&NFS_I(inode)->commit_mutex); if (!pnfs_clear_request_commit(req, &cinfo)) { nfs_request_remove_commit_list(req, &cinfo); } + mutex_unlock(&NFS_I(inode)->commit_mutex); nfs_clear_page_commit(req->wb_page); } } @@ -1023,7 +1006,6 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr) remove_req: nfs_inode_remove_request(req); next: - nfs_unlock_request(req); nfs_end_page_writeback(req); nfs_release_request(req); } @@ -1035,10 +1017,10 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr) unsigned long nfs_reqs_to_commit(struct nfs_commit_info *cinfo) { - return cinfo->mds->ncommit; + return atomic_long_read(&cinfo->mds->ncommit); } -/* cinfo->inode->i_lock held by caller */ +/* NFS_I(cinfo->inode)->commit_mutex held by caller */ int nfs_scan_commit_list(struct list_head *src, struct list_head *dst, struct nfs_commit_info *cinfo, int max) @@ -1046,20 +1028,37 @@ nfs_scan_commit_list(struct list_head *src, struct list_head *dst, struct nfs_page *req, *tmp; int ret = 0; +restart: list_for_each_entry_safe(req, tmp, src, wb_list) { - if (!nfs_lock_request(req)) - continue; kref_get(&req->wb_kref); - if (cond_resched_lock(&cinfo->inode->i_lock)) - list_safe_reset_next(req, tmp, wb_list); + if (!nfs_lock_request(req)) { + int status; + + /* Prevent deadlock with nfs_lock_and_join_requests */ + if (!list_empty(dst)) { + nfs_release_request(req); + continue; + } + /* Ensure we make progress to prevent livelock */ + mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); + status = nfs_wait_on_request(req); + nfs_release_request(req); + mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); + if (status < 0) + break; + goto restart; + } nfs_request_remove_commit_list(req, cinfo); + clear_bit(PG_COMMIT_TO_DS, &req->wb_flags); nfs_list_add_request(req, dst); ret++; if ((ret == max) && !cinfo->dreq) break; + cond_resched(); } return ret; } +EXPORT_SYMBOL_GPL(nfs_scan_commit_list); /* * nfs_scan_commit - Scan an inode for commit requests @@ -1076,15 +1075,17 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, { int ret = 0; - spin_lock(&cinfo->inode->i_lock); - if (cinfo->mds->ncommit > 0) { + if (!atomic_long_read(&cinfo->mds->ncommit)) + return 0; + mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); + if (atomic_long_read(&cinfo->mds->ncommit) > 0) { const int max = INT_MAX; ret = nfs_scan_commit_list(&cinfo->mds->list, dst, cinfo, max); ret += pnfs_scan_commit_lists(inode, cinfo, max - ret); } - spin_unlock(&cinfo->inode->i_lock); + mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); return ret; } @@ -1105,43 +1106,21 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, unsigned int end; int error; - if (!PagePrivate(page)) - return NULL; - end = offset + bytes; - spin_lock(&inode->i_lock); - - for (;;) { - req = nfs_page_find_head_request_locked(NFS_I(inode), page); - if (req == NULL) - goto out_unlock; - - /* should be handled by nfs_flush_incompatible */ - WARN_ON_ONCE(req->wb_head != req); - WARN_ON_ONCE(req->wb_this_page != req); - - rqend = req->wb_offset + req->wb_bytes; - /* - * Tell the caller to flush out the request if - * the offsets are non-contiguous. - * Note: nfs_flush_incompatible() will already - * have flushed out requests having wrong owners. - */ - if (offset > rqend - || end < req->wb_offset) - goto out_flushme; - if (nfs_lock_request(req)) - break; + req = nfs_lock_and_join_requests(page); + if (IS_ERR_OR_NULL(req)) + return req; - /* The request is locked, so wait and then retry */ - spin_unlock(&inode->i_lock); - error = nfs_wait_on_request(req); - nfs_release_request(req); - if (error != 0) - goto out_err; - spin_lock(&inode->i_lock); - } + rqend = req->wb_offset + req->wb_bytes; + /* + * Tell the caller to flush out the request if + * the offsets are non-contiguous. + * Note: nfs_flush_incompatible() will already + * have flushed out requests having wrong owners. + */ + if (offset > rqend || end < req->wb_offset) + goto out_flushme; /* Okay, the request matches. Update the region */ if (offset < req->wb_offset) { @@ -1152,17 +1131,17 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, req->wb_bytes = end - req->wb_offset; else req->wb_bytes = rqend - req->wb_offset; -out_unlock: - if (req) - nfs_clear_request_commit(req); - spin_unlock(&inode->i_lock); return req; out_flushme: - spin_unlock(&inode->i_lock); - nfs_release_request(req); + /* + * Note: we mark the request dirty here because + * nfs_lock_and_join_requests() cannot preserve + * commit flags, so we have to replay the write. + */ + nfs_mark_request_dirty(req); + nfs_unlock_and_release_request(req); error = nfs_wb_page(inode, page); -out_err: - return ERR_PTR(error); + return (error < 0) ? ERR_PTR(error) : NULL; } /* @@ -1227,8 +1206,6 @@ int nfs_flush_incompatible(struct file *file, struct page *page) l_ctx = req->wb_lock_context; do_flush = req->wb_page != page || !nfs_match_open_context(req->wb_context, ctx); - /* for now, flush if more than 1 request in page_group */ - do_flush |= req->wb_this_page != req; if (l_ctx && flctx && !(list_empty_careful(&flctx->flc_posix) && list_empty_careful(&flctx->flc_flock))) { @@ -1399,6 +1376,8 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr, task_setup_data->priority = priority; rpc_ops->write_setup(hdr, msg); + trace_nfs_initiate_write(hdr->inode, hdr->io_start, hdr->good_bytes, + hdr->args.stable); nfs4_state_protect_write(NFS_SERVER(hdr->inode)->nfs_client, &task_setup_data->rpc_client, msg, hdr); @@ -1412,7 +1391,6 @@ static void nfs_redirty_request(struct nfs_page *req) { nfs_mark_request_dirty(req); set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags); - nfs_unlock_request(req); nfs_end_page_writeback(req); nfs_release_request(req); } @@ -1452,7 +1430,7 @@ void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, pg_ops = server->pnfs_curr_ld->pg_write_ops; #endif nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_write_ops, - server->wsize, ioflags, GFP_NOIO); + server->wsize, ioflags); } EXPORT_SYMBOL_GPL(nfs_pageio_init_write); @@ -1557,7 +1535,10 @@ static int nfs_writeback_done(struct rpc_task *task, status = NFS_PROTO(inode)->write_done(task, hdr); if (status != 0) return status; + nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); + trace_nfs_writeback_done(inode, task->tk_status, + hdr->args.offset, hdr->res.verf); if (hdr->res.verf->committed < hdr->args.stable && task->tk_status >= 0) { @@ -1686,6 +1667,7 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data, }; /* Set up the initial task struct. */ nfs_ops->commit_setup(data, &msg); + trace_nfs_initiate_commit(data); dprintk("NFS: initiated commit call\n"); @@ -1810,6 +1792,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) /* Call the NFS version-specific code */ NFS_PROTO(data->inode)->commit_done(task, data); + trace_nfs_commit_done(data); } static void nfs_commit_release_pages(struct nfs_commit_data *data) @@ -1934,7 +1917,7 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc) int ret = 0; /* no commits means nothing needs to be done */ - if (!nfsi->commit_info.ncommit) + if (!atomic_long_read(&nfsi->commit_info.ncommit)) return ret; if (wbc->sync_mode == WB_SYNC_NONE) { @@ -2015,7 +1998,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) /* blocking call to cancel all requests and join to a single (head) * request */ - req = nfs_lock_and_join_requests(page, false); + req = nfs_lock_and_join_requests(page); if (IS_ERR(req)) { ret = PTR_ERR(req); diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index d27e75ad25e349fb07628f0d7af414e786005709..3c69db7d4905e379487ebdec7f31c2b4670412d6 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -784,6 +784,14 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } + +static void +nfsd4_read_release(union nfsd4_op_u *u) +{ + if (u->read.rd_filp) + fput(u->read.rd_filp); +} + static __be32 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) @@ -912,6 +920,13 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat return nfs_ok; } +static void +nfsd4_secinfo_release(union nfsd4_op_u *u) +{ + if (u->secinfo.si_exp) + exp_put(u->secinfo.si_exp); +} + static __be32 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) @@ -1335,6 +1350,12 @@ nfsd4_getdeviceinfo(struct svc_rqst *rqstp, return nfserr; } +static void +nfsd4_getdeviceinfo_release(union nfsd4_op_u *u) +{ + kfree(u->getdeviceinfo.gd_device); +} + static __be32 nfsd4_layoutget(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) @@ -1415,6 +1436,12 @@ nfsd4_layoutget(struct svc_rqst *rqstp, return nfserr; } +static void +nfsd4_layoutget_release(union nfsd4_op_u *u) +{ + kfree(u->layoutget.lg_content); +} + static __be32 nfsd4_layoutcommit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) @@ -1541,49 +1568,6 @@ static inline void nfsd4_increment_op_stats(u32 opnum) nfsdstats.nfs4_opcount[opnum]++; } -enum nfsd4_op_flags { - ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ - ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ - ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ - /* For rfc 5661 section 2.6.3.1.1: */ - OP_HANDLES_WRONGSEC = 1 << 3, - OP_IS_PUTFH_LIKE = 1 << 4, - /* - * These are the ops whose result size we estimate before - * encoding, to avoid performing an op then not being able to - * respond or cache a response. This includes writes and setattrs - * as well as the operations usually called "nonidempotent": - */ - OP_MODIFIES_SOMETHING = 1 << 5, - /* - * Cache compounds containing these ops in the xid-based drc: - * We use the DRC for compounds containing non-idempotent - * operations, *except* those that are 4.1-specific (since - * sessions provide their own EOS), and except for stateful - * operations other than setclientid and setclientid_confirm - * (since sequence numbers provide EOS for open, lock, etc in - * the v4.0 case). - */ - OP_CACHEME = 1 << 6, - /* - * These are ops which clear current state id. - */ - OP_CLEAR_STATEID = 1 << 7, -}; - -struct nfsd4_operation { - __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, - union nfsd4_op_u *); - u32 op_flags; - char *op_name; - /* Try to get response size before operation */ - u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *); - void (*op_get_currentstateid)(struct nfsd4_compound_state *, - union nfsd4_op_u *); - void (*op_set_currentstateid)(struct nfsd4_compound_state *, - union nfsd4_op_u *); -}; - static const struct nfsd4_operation nfsd4_ops[]; static const char *nfsd4_op_name(unsigned opnum); @@ -1621,7 +1605,7 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) return nfs_ok; } -static inline const struct nfsd4_operation *OPDESC(struct nfsd4_op *op) +const struct nfsd4_operation *OPDESC(struct nfsd4_op *op) { return &nfsd4_ops[op->opnum]; } @@ -1694,7 +1678,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) struct nfsd4_compoundargs *args = rqstp->rq_argp; struct nfsd4_compoundres *resp = rqstp->rq_resp; struct nfsd4_op *op; - const struct nfsd4_operation *opdesc; struct nfsd4_compound_state *cstate = &resp->cstate; struct svc_fh *current_fh = &cstate->current_fh; struct svc_fh *save_fh = &cstate->save_fh; @@ -1747,15 +1730,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) goto encode_op; } - opdesc = OPDESC(op); - if (!current_fh->fh_dentry) { - if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { + if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) { op->status = nfserr_nofilehandle; goto encode_op; } } else if (current_fh->fh_export->ex_fslocs.migrated && - !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { + !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { op->status = nfserr_moved; goto encode_op; } @@ -1763,12 +1744,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) fh_clear_wcc(current_fh); /* If op is non-idempotent */ - if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { + if (op->opdesc->op_flags & OP_MODIFIES_SOMETHING) { /* * Don't execute this op if we couldn't encode a * succesful reply: */ - u32 plen = opdesc->op_rsize_bop(rqstp, op); + u32 plen = op->opdesc->op_rsize_bop(rqstp, op); /* * Plus if there's another operation, make sure * we'll have space to at least encode an error: @@ -1781,9 +1762,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) if (op->status) goto encode_op; - if (opdesc->op_get_currentstateid) - opdesc->op_get_currentstateid(cstate, &op->u); - op->status = opdesc->op_func(rqstp, cstate, &op->u); + if (op->opdesc->op_get_currentstateid) + op->opdesc->op_get_currentstateid(cstate, &op->u); + op->status = op->opdesc->op_func(rqstp, cstate, &op->u); /* Only from SEQUENCE */ if (cstate->status == nfserr_replay_cache) { @@ -1792,10 +1773,10 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) goto out; } if (!op->status) { - if (opdesc->op_set_currentstateid) - opdesc->op_set_currentstateid(cstate, &op->u); + if (op->opdesc->op_set_currentstateid) + op->opdesc->op_set_currentstateid(cstate, &op->u); - if (opdesc->op_flags & OP_CLEAR_STATEID) + if (op->opdesc->op_flags & OP_CLEAR_STATEID) clear_current_stateid(cstate); if (need_wrongsec_check(rqstp)) @@ -2160,13 +2141,15 @@ static const struct nfsd4_operation nfsd4_ops[] = { }, [OP_LOCK] = { .op_func = nfsd4_lock, - .op_flags = OP_MODIFIES_SOMETHING, + .op_flags = OP_MODIFIES_SOMETHING | + OP_NONTRIVIAL_ERROR_ENCODE, .op_name = "OP_LOCK", .op_rsize_bop = nfsd4_lock_rsize, .op_set_currentstateid = nfsd4_set_lockstateid, }, [OP_LOCKT] = { .op_func = nfsd4_lockt, + .op_flags = OP_NONTRIVIAL_ERROR_ENCODE, .op_name = "OP_LOCKT", .op_rsize_bop = nfsd4_lock_rsize, }, @@ -2238,6 +2221,7 @@ static const struct nfsd4_operation nfsd4_ops[] = { }, [OP_READ] = { .op_func = nfsd4_read, + .op_release = nfsd4_read_release, .op_name = "OP_READ", .op_rsize_bop = nfsd4_read_rsize, .op_get_currentstateid = nfsd4_get_readstateid, @@ -2287,6 +2271,7 @@ static const struct nfsd4_operation nfsd4_ops[] = { }, [OP_SECINFO] = { .op_func = nfsd4_secinfo, + .op_release = nfsd4_secinfo_release, .op_flags = OP_HANDLES_WRONGSEC, .op_name = "OP_SECINFO", .op_rsize_bop = nfsd4_secinfo_rsize, @@ -2294,14 +2279,16 @@ static const struct nfsd4_operation nfsd4_ops[] = { [OP_SETATTR] = { .op_func = nfsd4_setattr, .op_name = "OP_SETATTR", - .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, + .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME + | OP_NONTRIVIAL_ERROR_ENCODE, .op_rsize_bop = nfsd4_setattr_rsize, .op_get_currentstateid = nfsd4_get_setattrstateid, }, [OP_SETCLIENTID] = { .op_func = nfsd4_setclientid, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS - | OP_MODIFIES_SOMETHING | OP_CACHEME, + | OP_MODIFIES_SOMETHING | OP_CACHEME + | OP_NONTRIVIAL_ERROR_ENCODE, .op_name = "OP_SETCLIENTID", .op_rsize_bop = nfsd4_setclientid_rsize, }, @@ -2388,6 +2375,7 @@ static const struct nfsd4_operation nfsd4_ops[] = { }, [OP_SECINFO_NO_NAME] = { .op_func = nfsd4_secinfo_no_name, + .op_release = nfsd4_secinfo_release, .op_flags = OP_HANDLES_WRONGSEC, .op_name = "OP_SECINFO_NO_NAME", .op_rsize_bop = nfsd4_secinfo_rsize, @@ -2408,12 +2396,14 @@ static const struct nfsd4_operation nfsd4_ops[] = { #ifdef CONFIG_NFSD_PNFS [OP_GETDEVICEINFO] = { .op_func = nfsd4_getdeviceinfo, + .op_release = nfsd4_getdeviceinfo_release, .op_flags = ALLOWED_WITHOUT_FH, .op_name = "OP_GETDEVICEINFO", .op_rsize_bop = nfsd4_getdeviceinfo_rsize, }, [OP_LAYOUTGET] = { .op_func = nfsd4_layoutget, + .op_release = nfsd4_layoutget_release, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_LAYOUTGET", .op_rsize_bop = nfsd4_layoutget_rsize, diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 20fbcab977531bee75501a9403f4c8f60ee404d4..2c61c6b8ae0976209cbb8a443fb5db1a50d5fdad 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -144,7 +144,7 @@ static void next_decode_page(struct nfsd4_compoundargs *argp) argp->p = page_address(argp->pagelist[0]); argp->pagelist++; if (argp->pagelen < PAGE_SIZE) { - argp->end = argp->p + (argp->pagelen>>2); + argp->end = argp->p + XDR_QUADLEN(argp->pagelen); argp->pagelen = 0; } else { argp->end = argp->p + (PAGE_SIZE>>2); @@ -159,6 +159,25 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) */ unsigned int avail = (char *)argp->end - (char *)argp->p; __be32 *p; + + if (argp->pagelen == 0) { + struct kvec *vec = &argp->rqstp->rq_arg.tail[0]; + + if (!argp->tail) { + argp->tail = true; + avail = vec->iov_len; + argp->p = vec->iov_base; + argp->end = vec->iov_base + avail; + } + + if (avail < nbytes) + return NULL; + + p = argp->p; + argp->p += XDR_QUADLEN(nbytes); + return p; + } + if (avail + argp->pagelen < nbytes) return NULL; if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ @@ -1279,9 +1298,7 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) argp->pagelen -= pages * PAGE_SIZE; len -= pages * PAGE_SIZE; - argp->p = (__be32 *)page_address(argp->pagelist[0]); - argp->pagelist++; - argp->end = argp->p + XDR_QUADLEN(PAGE_SIZE); + next_decode_page(argp); } argp->p += XDR_QUADLEN(len); @@ -1780,7 +1797,7 @@ nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); -static nfsd4_dec nfsd4_dec_ops[] = { +static const nfsd4_dec nfsd4_dec_ops[] = { [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, @@ -1929,6 +1946,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) op->opnum = OP_ILLEGAL; op->status = nfserr_op_illegal; } + op->opdesc = OPDESC(op); /* * We'll try to cache the result in the DRC if any one * op in the compound wants to be cached: @@ -3104,14 +3122,12 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, 8); - if (!p) - return nfserr_resource; - *p++ = cpu_to_be32(access->ac_supported); - *p++ = cpu_to_be32(access->ac_resp_access); - } - return nfserr; + p = xdr_reserve_space(xdr, 8); + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(access->ac_supported); + *p++ = cpu_to_be32(access->ac_resp_access); + return 0; } static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) @@ -3119,17 +3135,15 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8); - if (!p) - return nfserr_resource; - p = xdr_encode_opaque_fixed(p, bcts->sessionid.data, - NFS4_MAX_SESSIONID_LEN); - *p++ = cpu_to_be32(bcts->dir); - /* Upshifting from TCP to RDMA is not supported */ - *p++ = cpu_to_be32(0); - } - return nfserr; + p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8); + if (!p) + return nfserr_resource; + p = xdr_encode_opaque_fixed(p, bcts->sessionid.data, + NFS4_MAX_SESSIONID_LEN); + *p++ = cpu_to_be32(bcts->dir); + /* Upshifting from TCP to RDMA is not supported */ + *p++ = cpu_to_be32(0); + return 0; } static __be32 @@ -3137,10 +3151,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c { struct xdr_stream *xdr = &resp->xdr; - if (!nfserr) - nfserr = nfsd4_encode_stateid(xdr, &close->cl_stateid); - - return nfserr; + return nfsd4_encode_stateid(xdr, &close->cl_stateid); } @@ -3150,14 +3161,12 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); - if (!p) - return nfserr_resource; - p = xdr_encode_opaque_fixed(p, commit->co_verf.data, + p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); + if (!p) + return nfserr_resource; + p = xdr_encode_opaque_fixed(p, commit->co_verf.data, NFS4_VERIFIER_SIZE); - } - return nfserr; + return 0; } static __be32 @@ -3166,15 +3175,13 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, 20); - if (!p) - return nfserr_resource; - encode_cinfo(p, &create->cr_cinfo); - nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0], - create->cr_bmval[1], create->cr_bmval[2]); - } - return nfserr; + p = xdr_reserve_space(xdr, 20); + if (!p) + return nfserr_resource; + encode_cinfo(p, &create->cr_cinfo); + nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0], + create->cr_bmval[1], create->cr_bmval[2]); + return 0; } static __be32 @@ -3183,13 +3190,8 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 struct svc_fh *fhp = getattr->ga_fhp; struct xdr_stream *xdr = &resp->xdr; - if (nfserr) - return nfserr; - - nfserr = nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry, - getattr->ga_bmval, - resp->rqstp, 0); - return nfserr; + return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry, + getattr->ga_bmval, resp->rqstp, 0); } static __be32 @@ -3200,14 +3202,12 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh unsigned int len; __be32 *p; - if (!nfserr) { - len = fhp->fh_handle.fh_size; - p = xdr_reserve_space(xdr, len + 4); - if (!p) - return nfserr_resource; - p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len); - } - return nfserr; + len = fhp->fh_handle.fh_size; + p = xdr_reserve_space(xdr, len + 4); + if (!p) + return nfserr_resource; + p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len); + return 0; } /* @@ -3277,10 +3277,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l { struct xdr_stream *xdr = &resp->xdr; - if (!nfserr) - nfserr = nfsd4_encode_stateid(xdr, &locku->lu_stateid); - - return nfserr; + return nfsd4_encode_stateid(xdr, &locku->lu_stateid); } @@ -3290,13 +3287,11 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, 20); - if (!p) - return nfserr_resource; - p = encode_cinfo(p, &link->li_cinfo); - } - return nfserr; + p = xdr_reserve_space(xdr, 20); + if (!p) + return nfserr_resource; + p = encode_cinfo(p, &link->li_cinfo); + return 0; } @@ -3306,12 +3301,9 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (nfserr) - goto out; - nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid); if (nfserr) - goto out; + return nfserr; p = xdr_reserve_space(xdr, 24); if (!p) return nfserr_resource; @@ -3321,7 +3313,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1], open->op_bmval[2]); if (nfserr) - goto out; + return nfserr; p = xdr_reserve_space(xdr, 4); if (!p) @@ -3394,8 +3386,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op BUG(); } /* XXX save filehandle here */ -out: - return nfserr; + return 0; } static __be32 @@ -3403,10 +3394,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct { struct xdr_stream *xdr = &resp->xdr; - if (!nfserr) - nfserr = nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid); - - return nfserr; + return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid); } static __be32 @@ -3414,10 +3402,7 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc { struct xdr_stream *xdr = &resp->xdr; - if (!nfserr) - nfserr = nfsd4_encode_stateid(xdr, &od->od_stateid); - - return nfserr; + return nfsd4_encode_stateid(xdr, &od->od_stateid); } static __be32 nfsd4_encode_splice_read( @@ -3554,20 +3539,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, struct raparms *ra = NULL; __be32 *p; - if (nfserr) - goto out; - p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */ if (!p) { WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)); - nfserr = nfserr_resource; - goto out; + return nfserr_resource; } if (resp->xdr.buf->page_len && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) { WARN_ON_ONCE(1); - nfserr = nfserr_resource; - goto out; + return nfserr_resource; } xdr_commit_encode(xdr); @@ -3591,9 +3571,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, if (nfserr) xdr_truncate_encode(xdr, starting_len); -out: - if (file) - fput(file); return nfserr; } @@ -3607,9 +3584,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd int length_offset = xdr->buf->len; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, 4); if (!p) return nfserr_resource; @@ -3653,9 +3627,6 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 int starting_len = xdr->buf->len; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); if (!p) return nfserr_resource; @@ -3741,13 +3712,11 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, 20); - if (!p) - return nfserr_resource; - p = encode_cinfo(p, &remove->rm_cinfo); - } - return nfserr; + p = xdr_reserve_space(xdr, 20); + if (!p) + return nfserr_resource; + p = encode_cinfo(p, &remove->rm_cinfo); + return 0; } static __be32 @@ -3756,19 +3725,16 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, 40); - if (!p) - return nfserr_resource; - p = encode_cinfo(p, &rename->rn_sinfo); - p = encode_cinfo(p, &rename->rn_tinfo); - } - return nfserr; + p = xdr_reserve_space(xdr, 40); + if (!p) + return nfserr_resource; + p = encode_cinfo(p, &rename->rn_sinfo); + p = encode_cinfo(p, &rename->rn_tinfo); + return 0; } static __be32 -nfsd4_do_encode_secinfo(struct xdr_stream *xdr, - __be32 nfserr, struct svc_export *exp) +nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp) { u32 i, nflavs, supported; struct exp_flavor_info *flavs; @@ -3776,9 +3742,6 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, __be32 *p, *flavorsp; static bool report = true; - if (nfserr) - goto out; - nfserr = nfserr_resource; if (exp->ex_nflavors) { flavs = exp->ex_flavors; nflavs = exp->ex_nflavors; @@ -3802,7 +3765,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, supported = 0; p = xdr_reserve_space(xdr, 4); if (!p) - goto out; + return nfserr_resource; flavorsp = p++; /* to be backfilled later */ for (i = 0; i < nflavs; i++) { @@ -3814,7 +3777,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, p = xdr_reserve_space(xdr, 4 + 4 + XDR_LEN(info.oid.len) + 4 + 4); if (!p) - goto out; + return nfserr_resource; *p++ = cpu_to_be32(RPC_AUTH_GSS); p = xdr_encode_opaque(p, info.oid.data, info.oid.len); *p++ = cpu_to_be32(info.qop); @@ -3823,7 +3786,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, supported++; p = xdr_reserve_space(xdr, 4); if (!p) - goto out; + return nfserr_resource; *p++ = cpu_to_be32(pf); } else { if (report) @@ -3835,11 +3798,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, if (nflavs != supported) report = false; *flavorsp = htonl(supported); - nfserr = 0; -out: - if (exp) - exp_put(exp); - return nfserr; + return 0; } static __be32 @@ -3848,7 +3807,7 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, { struct xdr_stream *xdr = &resp->xdr; - return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->si_exp); + return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp); } static __be32 @@ -3857,7 +3816,7 @@ nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, { struct xdr_stream *xdr = &resp->xdr; - return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->sin_exp); + return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp); } /* @@ -3918,16 +3877,14 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (!nfserr) { - p = xdr_reserve_space(xdr, 16); - if (!p) - return nfserr_resource; - *p++ = cpu_to_be32(write->wr_bytes_written); - *p++ = cpu_to_be32(write->wr_how_written); - p = xdr_encode_opaque_fixed(p, write->wr_verifier.data, - NFS4_VERIFIER_SIZE); - } - return nfserr; + p = xdr_reserve_space(xdr, 16); + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(write->wr_bytes_written); + *p++ = cpu_to_be32(write->wr_how_written); + p = xdr_encode_opaque_fixed(p, write->wr_verifier.data, + NFS4_VERIFIER_SIZE); + return 0; } static __be32 @@ -3940,12 +3897,8 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, char *server_scope; int major_id_sz; int server_scope_sz; - int status = 0; uint64_t minor_id = 0; - if (nfserr) - return nfserr; - major_id = utsname()->nodename; major_id_sz = strlen(major_id); server_scope = utsname()->nodename; @@ -3970,19 +3923,19 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, break; case SP4_MACH_CRED: /* spo_must_enforce bitmap: */ - status = nfsd4_encode_bitmap(xdr, + nfserr = nfsd4_encode_bitmap(xdr, exid->spo_must_enforce[0], exid->spo_must_enforce[1], exid->spo_must_enforce[2]); - if (status) - goto out; + if (nfserr) + return nfserr; /* spo_must_allow bitmap: */ - status = nfsd4_encode_bitmap(xdr, + nfserr = nfsd4_encode_bitmap(xdr, exid->spo_must_allow[0], exid->spo_must_allow[1], exid->spo_must_allow[2]); - if (status) - goto out; + if (nfserr) + return nfserr; break; default: WARN_ON_ONCE(1); @@ -4009,8 +3962,6 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, /* Implementation id */ *p++ = cpu_to_be32(0); /* zero length nfs_impl_id4 array */ return 0; -out: - return status; } static __be32 @@ -4020,9 +3971,6 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, 24); if (!p) return nfserr_resource; @@ -4076,9 +4024,6 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20); if (!p) return nfserr_resource; @@ -4103,9 +4048,6 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_test_stateid_id *stateid, *next; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids)); if (!p) return nfserr_resource; @@ -4115,7 +4057,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, *p++ = stateid->ts_id_status; } - return nfserr; + return 0; } #ifdef CONFIG_NFSD_PNFS @@ -4128,14 +4070,9 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, u32 starting_len = xdr->buf->len, needed_len; __be32 *p; - dprintk("%s: err %d\n", __func__, be32_to_cpu(nfserr)); - if (nfserr) - goto out; - - nfserr = nfserr_resource; p = xdr_reserve_space(xdr, 4); if (!p) - goto out; + return nfserr_resource; *p++ = cpu_to_be32(gdev->gd_layout_type); @@ -4151,42 +4088,33 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, */ if (xdr->buf->len + 4 > gdev->gd_maxcount) goto toosmall; - goto out; + return nfserr; } } - nfserr = nfserr_resource; if (gdev->gd_notify_types) { p = xdr_reserve_space(xdr, 4 + 4); if (!p) - goto out; + return nfserr_resource; *p++ = cpu_to_be32(1); /* bitmap length */ *p++ = cpu_to_be32(gdev->gd_notify_types); } else { p = xdr_reserve_space(xdr, 4); if (!p) - goto out; + return nfserr_resource; *p++ = 0; } - nfserr = 0; -out: - kfree(gdev->gd_device); - dprintk("%s: done: %d\n", __func__, be32_to_cpu(nfserr)); - return nfserr; - + return 0; toosmall: dprintk("%s: maxcount too small\n", __func__); needed_len = xdr->buf->len + 4 /* notifications */; xdr_truncate_encode(xdr, starting_len); p = xdr_reserve_space(xdr, 4); - if (!p) { - nfserr = nfserr_resource; - } else { - *p++ = cpu_to_be32(needed_len); - nfserr = nfserr_toosmall; - } - goto out; + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(needed_len); + return nfserr_toosmall; } static __be32 @@ -4197,14 +4125,9 @@ nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr, const struct nfsd4_layout_ops *ops; __be32 *p; - dprintk("%s: err %d\n", __func__, nfserr); - if (nfserr) - goto out; - - nfserr = nfserr_resource; p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t)); if (!p) - goto out; + return nfserr_resource; *p++ = cpu_to_be32(1); /* we always set return-on-close */ *p++ = cpu_to_be32(lgp->lg_sid.si_generation); @@ -4218,10 +4141,7 @@ nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr, *p++ = cpu_to_be32(lgp->lg_layout_type); ops = nfsd4_layout_ops[lgp->lg_layout_type]; - nfserr = ops->encode_layoutget(xdr, lgp); -out: - kfree(lgp->lg_content); - return nfserr; + return ops->encode_layoutget(xdr, lgp); } static __be32 @@ -4231,9 +4151,6 @@ nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr, struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, 4); if (!p) return nfserr_resource; @@ -4245,7 +4162,7 @@ nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr, p = xdr_encode_hyper(p, lcp->lc_newsize); } - return nfs_ok; + return 0; } static __be32 @@ -4255,16 +4172,13 @@ nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr, struct xdr_stream *xdr = &resp->xdr; __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(xdr, 4); if (!p) return nfserr_resource; *p++ = cpu_to_be32(lrp->lrs_present); if (lrp->lrs_present) return nfsd4_encode_stateid(xdr, &lrp->lr_sid); - return nfs_ok; + return 0; } #endif /* CONFIG_NFSD_PNFS */ @@ -4291,16 +4205,14 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, { __be32 *p; - if (!nfserr) { - nfserr = nfsd42_encode_write_res(resp, ©->cp_res); - if (nfserr) - return nfserr; + nfserr = nfsd42_encode_write_res(resp, ©->cp_res); + if (nfserr) + return nfserr; - p = xdr_reserve_space(&resp->xdr, 4 + 4); - *p++ = cpu_to_be32(copy->cp_consecutive); - *p++ = cpu_to_be32(copy->cp_synchronous); - } - return nfserr; + p = xdr_reserve_space(&resp->xdr, 4 + 4); + *p++ = cpu_to_be32(copy->cp_consecutive); + *p++ = cpu_to_be32(copy->cp_synchronous); + return 0; } static __be32 @@ -4309,14 +4221,11 @@ nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, { __be32 *p; - if (nfserr) - return nfserr; - p = xdr_reserve_space(&resp->xdr, 4 + 8); *p++ = cpu_to_be32(seek->seek_eof); p = xdr_encode_hyper(p, seek->seek_pos); - return nfserr; + return 0; } static __be32 @@ -4332,7 +4241,7 @@ typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); * since we don't need to filter out obsolete ops as this is * done in the decoding phase. */ -static nfsd4_enc nfsd4_enc_ops[] = { +static const nfsd4_enc nfsd4_enc_ops[] = { [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access, [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close, [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit, @@ -4451,6 +4360,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) struct xdr_stream *xdr = &resp->xdr; struct nfs4_stateowner *so = resp->cstate.replay_owner; struct svc_rqst *rqstp = resp->rqstp; + const struct nfsd4_operation *opdesc = op->opdesc; int post_err_offset; nfsd4_enc encoder; __be32 *p; @@ -4465,10 +4375,15 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) if (op->opnum == OP_ILLEGAL) goto status; + if (op->status && opdesc && + !(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE)) + goto status; BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) || !nfsd4_enc_ops[op->opnum]); encoder = nfsd4_enc_ops[op->opnum]; op->status = encoder(resp, op->status, &op->u); + if (opdesc && opdesc->op_release) + opdesc->op_release(&op->u); xdr_commit_encode(xdr); /* nfsd4_check_resp_size guarantees enough room for error status */ @@ -4575,6 +4490,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p) args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; args->pagelist = rqstp->rq_arg.pages; args->pagelen = rqstp->rq_arg.page_len; + args->tail = false; args->tmpp = NULL; args->to_free = NULL; args->ops = args->iops; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 063ae7de2c12245fdce41a8b72d97003490fa69f..7e3af3ef091778fa4eb0258f77a5f2582555c375 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -475,7 +475,7 @@ static int nfsd_get_default_max_blksize(void) return ret; } -static struct svc_serv_ops nfsd_thread_sv_ops = { +static const struct svc_serv_ops nfsd_thread_sv_ops = { .svo_shutdown = nfsd_last_thread, .svo_function = nfsd, .svo_enqueue_xprt = svc_xprt_do_enqueue, diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 38d0383dc7f9d330859f53df696e97c4eb35df37..bc69d40c4e8b9436c71b2aef5ae2444e35d78833 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -969,7 +969,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, int use_wgather; loff_t pos = offset; unsigned int pflags = current->flags; - int flags = 0; + rwf_t flags = 0; if (test_bit(RQ_LOCAL, &rqstp->rq_flags)) /* diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 72c6ad136107c7213656dcd3fec7b09eebb3bd39..1e4edbf70052bf5f6c8c0af06e0d7bf1812e80a5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -538,6 +538,7 @@ struct nfsd4_seek { struct nfsd4_op { int opnum; + const struct nfsd4_operation * opdesc; __be32 status; union nfsd4_op_u { struct nfsd4_access access; @@ -614,6 +615,7 @@ struct nfsd4_compoundargs { __be32 * end; struct page ** pagelist; int pagelen; + bool tail; __be32 tmp[8]; __be32 * tmpp; struct svcxdr_tmpbuf *to_free; @@ -661,6 +663,7 @@ static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp) return argp->opcnt == resp->opcnt; } +const struct nfsd4_operation *OPDESC(struct nfsd4_op *op); int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op); void warn_on_nonidempotent_op(struct nfsd4_op *op); @@ -748,6 +751,53 @@ extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *, union nfsd4_op_u *); extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr); +enum nfsd4_op_flags { + ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ + ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ + ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ + /* For rfc 5661 section 2.6.3.1.1: */ + OP_HANDLES_WRONGSEC = 1 << 3, + OP_IS_PUTFH_LIKE = 1 << 4, + /* + * These are the ops whose result size we estimate before + * encoding, to avoid performing an op then not being able to + * respond or cache a response. This includes writes and setattrs + * as well as the operations usually called "nonidempotent": + */ + OP_MODIFIES_SOMETHING = 1 << 5, + /* + * Cache compounds containing these ops in the xid-based drc: + * We use the DRC for compounds containing non-idempotent + * operations, *except* those that are 4.1-specific (since + * sessions provide their own EOS), and except for stateful + * operations other than setclientid and setclientid_confirm + * (since sequence numbers provide EOS for open, lock, etc in + * the v4.0 case). + */ + OP_CACHEME = 1 << 6, + /* + * These are ops which clear current state id. + */ + OP_CLEAR_STATEID = 1 << 7, + /* Most ops return only an error on failure; some may do more: */ + OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8, +}; + +struct nfsd4_operation { + __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, + union nfsd4_op_u *); + void (*op_release)(union nfsd4_op_u *); + u32 op_flags; + char *op_name; + /* Try to get response size before operation */ + u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *); + void (*op_get_currentstateid)(struct nfsd4_compound_state *, + union nfsd4_op_u *); + void (*op_set_currentstateid)(struct nfsd4_compound_state *, + union nfsd4_op_u *); +}; + + #endif /* diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 7ffe71a8dfb9b3de3d2d952931fa36f0ac6d90c6..6a612d832e7de41f1273805fd8db2ad0f0433221 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -174,7 +174,7 @@ static int nilfs_writepages(struct address_space *mapping, struct inode *inode = mapping->host; int err = 0; - if (inode->i_sb->s_flags & MS_RDONLY) { + if (sb_rdonly(inode->i_sb)) { nilfs_clear_dirty_pages(mapping, false); return -EROFS; } @@ -191,7 +191,7 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc) struct inode *inode = page->mapping->host; int err; - if (inode->i_sb->s_flags & MS_RDONLY) { + if (sb_rdonly(inode->i_sb)) { /* * It means that filesystem was remounted in read-only * mode because of error or metadata corruption. But we diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 98835ed6bef40c8ccdc81a0707538a6489f8e57e..c6bc1033e7d2ccf3795bde38b18a5787e2644d1d 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c @@ -413,7 +413,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) struct super_block *sb; int err = 0; - if (inode && (inode->i_sb->s_flags & MS_RDONLY)) { + if (inode && sb_rdonly(inode->i_sb)) { /* * It means that filesystem was remounted in read-only * mode because of error or metadata corruption. But we diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index f11a3ad2df0cd56b0cfcc007aa1e10dade6c1a98..8616c46d33da3849673044b46a643af30b958b07 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c @@ -312,10 +312,9 @@ void nilfs_copy_back_pages(struct address_space *dmap, pagevec_init(&pvec, 0); repeat: - n = pagevec_lookup(&pvec, smap, index, PAGEVEC_SIZE); + n = pagevec_lookup(&pvec, smap, &index); if (!n) return; - index = pvec.pages[n - 1]->index + 1; for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i], *dpage; diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index e73c86d9855ccd186b4c3f75f7a56b6e61060e47..6c5009cc4e6f619ab8869097f0b7ea379d6b3423 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c @@ -400,7 +400,7 @@ static struct bio *nilfs_alloc_seg_bio(struct the_nilfs *nilfs, sector_t start, bio = bio_alloc(GFP_NOIO, nr_vecs); } if (likely(bio)) { - bio->bi_bdev = nilfs->ns_bdev; + bio_set_dev(bio, nilfs->ns_bdev); bio->bi_iter.bi_sector = start << (nilfs->ns_blocksize_bits - 9); } diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 926682981d61f0bd1671e9f49c1a0a8b80e72f03..4fc018dfcfae354b598d2a547b96adf1ae1c76c0 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -136,7 +136,7 @@ void __nilfs_error(struct super_block *sb, const char *function, va_end(args); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { nilfs_set_error(sb); if (nilfs_test_opt(nilfs, ERRORS_RO)) { @@ -478,7 +478,7 @@ static void nilfs_put_super(struct super_block *sb) nilfs_detach_log_writer(sb); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { down_write(&nilfs->ns_sem); nilfs_cleanup_super(sb); up_write(&nilfs->ns_sem); @@ -578,7 +578,7 @@ static int nilfs_freeze(struct super_block *sb) struct the_nilfs *nilfs = sb->s_fs_info; int err; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; /* Mark super block clean */ @@ -592,7 +592,7 @@ static int nilfs_unfreeze(struct super_block *sb) { struct the_nilfs *nilfs = sb->s_fs_info; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; down_write(&nilfs->ns_sem); @@ -898,7 +898,7 @@ int nilfs_check_feature_compatibility(struct super_block *sb, } features = le64_to_cpu(sbp->s_feature_compat_ro) & ~NILFS_FEATURE_COMPAT_RO_SUPP; - if (!(sb->s_flags & MS_RDONLY) && features) { + if (!sb_rdonly(sb) && features) { nilfs_msg(sb, KERN_ERR, "couldn't mount RDWR because of unsupported optional features (%llx)", (unsigned long long)features); @@ -1083,7 +1083,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent) goto failed_unload; } - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { err = nilfs_attach_log_writer(sb, fsroot); if (err) goto failed_checkpoint; @@ -1095,7 +1095,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent) nilfs_put_root(fsroot); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { down_write(&nilfs->ns_sem); nilfs_setup_super(sb, true); up_write(&nilfs->ns_sem); @@ -1144,7 +1144,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) goto out; if (*flags & MS_RDONLY) { /* Shutting down log writer */ @@ -1338,8 +1338,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, if ((flags ^ s->s_flags) & MS_RDONLY) { nilfs_msg(s, KERN_ERR, "the device already has a %s mount.", - (s->s_flags & MS_RDONLY) ? - "read-only" : "read/write"); + sb_rdonly(s) ? "read-only" : "read/write"); err = -EBUSY; goto failed_super; } diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 2430a0415995d9e8d056b2c24eda8b749a79998f..cba32831592952b750ebea310b002c7a27b5cb6e 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -133,7 +133,7 @@ static void dnotify_free_mark(struct fsnotify_mark *fsn_mark) kmem_cache_free(dnotify_mark_cache, dn_mark); } -static struct fsnotify_ops dnotify_fsnotify_ops = { +static const struct fsnotify_ops dnotify_fsnotify_ops = { .handle_event = dnotify_handle_event, .free_mark = dnotify_free_mark, }; diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 0ee19ecc982d4e4ef8137836ba4d753559eb7612..1a24be9e8405d98a355de0bd5a7445ea4210c50e 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c @@ -1506,7 +1506,7 @@ static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end, ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); - err = filemap_write_and_wait_range(vi->i_mapping, start, end); + err = file_write_and_wait_range(filp, start, end); if (err) return err; inode_lock(vi); diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index c4f68c338735b909c163abb11b9d5c90df9fb71f..331910fa84422cc77fc14eaadfef5cb058c22cc7 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -1989,7 +1989,7 @@ static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end, ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); - err = filemap_write_and_wait_range(vi->i_mapping, start, end); + err = file_write_and_wait_range(filp, start, end); if (err) return err; inode_lock(vi); diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index ecb49870a680cd594e276b10a59ff679f5e681e7..3f70f041dbe9d7e0f79b5970da1d7b5d14ca584e 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -487,7 +487,7 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) * When remounting read-only, mark the volume clean if no volume errors * have occurred. */ - if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { + if (sb_rdonly(sb) && !(*flags & MS_RDONLY)) { static const char *es = ". Cannot remount read-write."; /* Remounting read-write. */ @@ -548,7 +548,7 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) NVolSetErrors(vol); return -EROFS; } - } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { + } else if (!sb_rdonly(sb) && (*flags & MS_RDONLY)) { /* Remounting read-only. */ if (!NVolErrors(vol)) { if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY)) @@ -732,7 +732,7 @@ static struct buffer_head *read_ntfs_boot_sector(struct super_block *sb, * on a large sector device contains the whole boot loader or * just the first 512 bytes). */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { ntfs_warning(sb, "Hot-fix: Recovering invalid primary " "boot sector from backup copy."); memcpy(bh_primary->b_data, bh_backup->b_data, @@ -1789,7 +1789,7 @@ static bool load_system_files(ntfs_volume *vol) static const char *es3 = ". Run ntfsfix and/or chkdsk."; /* If a read-write mount, convert it to a read-only mount. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | ON_ERRORS_CONTINUE))) { ntfs_error(sb, "%s and neither on_errors=" @@ -1928,7 +1928,7 @@ static bool load_system_files(ntfs_volume *vol) (unsigned)le16_to_cpu(vol->vol_flags)); } /* If a read-write mount, convert it to a read-only mount. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | ON_ERRORS_CONTINUE))) { ntfs_error(sb, "%s and neither on_errors=" @@ -1961,7 +1961,7 @@ static bool load_system_files(ntfs_volume *vol) es1 = !vol->logfile_ino ? es1a : es1b; /* If a read-write mount, convert it to a read-only mount. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | ON_ERRORS_CONTINUE))) { ntfs_error(sb, "%s and neither on_errors=" @@ -2010,7 +2010,7 @@ static bool load_system_files(ntfs_volume *vol) es1 = err < 0 ? es1a : es1b; /* If a read-write mount, convert it to a read-only mount. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | ON_ERRORS_CONTINUE))) { ntfs_error(sb, "%s and neither on_errors=" @@ -2028,8 +2028,7 @@ static bool load_system_files(ntfs_volume *vol) NVolSetErrors(vol); } /* If (still) a read-write mount, mark the volume dirty. */ - if (!(sb->s_flags & MS_RDONLY) && - ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { + if (!sb_rdonly(sb) && ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { static const char *es1 = "Failed to set dirty bit in volume " "information flags"; static const char *es2 = ". Run chkdsk."; @@ -2075,8 +2074,7 @@ static bool load_system_files(ntfs_volume *vol) } #endif /* If (still) a read-write mount, empty the logfile. */ - if (!(sb->s_flags & MS_RDONLY) && - !ntfs_empty_logfile(vol->logfile_ino)) { + if (!sb_rdonly(sb) && !ntfs_empty_logfile(vol->logfile_ino)) { static const char *es1 = "Failed to empty $LogFile"; static const char *es2 = ". Mount in Windows."; @@ -2121,7 +2119,7 @@ static bool load_system_files(ntfs_volume *vol) static const char *es2 = ". Run chkdsk."; /* If a read-write mount, convert it to a read-only mount. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | ON_ERRORS_CONTINUE))) { ntfs_error(sb, "%s and neither on_errors=" @@ -2139,8 +2137,7 @@ static bool load_system_files(ntfs_volume *vol) NVolSetErrors(vol); } /* If (still) a read-write mount, mark the quotas out of date. */ - if (!(sb->s_flags & MS_RDONLY) && - !ntfs_mark_quotas_out_of_date(vol)) { + if (!sb_rdonly(sb) && !ntfs_mark_quotas_out_of_date(vol)) { static const char *es1 = "Failed to mark quotas out of date"; static const char *es2 = ". Run chkdsk."; @@ -2165,7 +2162,7 @@ static bool load_system_files(ntfs_volume *vol) static const char *es2 = ". Run chkdsk."; /* If a read-write mount, convert it to a read-only mount. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | ON_ERRORS_CONTINUE))) { ntfs_error(sb, "%s and neither on_errors=" @@ -2183,7 +2180,7 @@ static bool load_system_files(ntfs_volume *vol) NVolSetErrors(vol); } /* If (still) a read-write mount, stamp the transaction log. */ - if (!(sb->s_flags & MS_RDONLY) && !ntfs_stamp_usnjrnl(vol)) { + if (!sb_rdonly(sb) && !ntfs_stamp_usnjrnl(vol)) { static const char *es1 = "Failed to stamp transaction log " "($UsnJrnl)"; static const char *es2 = ". Run chkdsk."; @@ -2314,7 +2311,7 @@ static void ntfs_put_super(struct super_block *sb) * If a read-write mount and no volume errors have occurred, mark the * volume clean. Also, re-commit all affected inodes. */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!NVolErrors(vol)) { if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY)) ntfs_warning(sb, "Failed to clear dirty bit " diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index dc22ba8c710ff10de13526d52712ec4ef16cbb96..40b5cc97f7b0f709154402bfdbdbd0cc26004c24 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -221,7 +221,7 @@ static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh, /* * Set the access or default ACL of an inode. */ -int ocfs2_set_acl(handle_t *handle, +static int ocfs2_set_acl(handle_t *handle, struct inode *inode, struct buffer_head *di_bh, int type, @@ -240,18 +240,6 @@ int ocfs2_set_acl(handle_t *handle, switch (type) { case ACL_TYPE_ACCESS: name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - umode_t mode; - - ret = posix_acl_update_mode(inode, &mode, &acl); - if (ret) - return ret; - - ret = ocfs2_acl_set_mode(inode, di_bh, - handle, mode); - if (ret) - return ret; - } break; case ACL_TYPE_DEFAULT: name_index = OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT; @@ -289,7 +277,19 @@ int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type) had_lock = ocfs2_inode_lock_tracker(inode, &bh, 1, &oh); if (had_lock < 0) return had_lock; + if (type == ACL_TYPE_ACCESS && acl) { + umode_t mode; + + status = posix_acl_update_mode(inode, &mode, &acl); + if (status) + goto unlock; + + status = ocfs2_acl_set_mode(inode, bh, NULL, mode); + if (status) + goto unlock; + } status = ocfs2_set_acl(NULL, inode, bh, type, acl, NULL, NULL); +unlock: ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock); brelse(bh); return status; diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h index 2783a75b3999e3c6a548bc44c4645ac882048ae6..7be0bb756286d83576c68472fc9ae267d4c2d1c6 100644 --- a/fs/ocfs2/acl.h +++ b/fs/ocfs2/acl.h @@ -28,13 +28,6 @@ struct ocfs2_acl_entry { struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type); int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type); -int ocfs2_set_acl(handle_t *handle, - struct inode *inode, - struct buffer_head *di_bh, - int type, - struct posix_acl *acl, - struct ocfs2_alloc_context *meta_ac, - struct ocfs2_alloc_context *data_ac); extern int ocfs2_acl_chmod(struct inode *, struct buffer_head *); extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, struct buffer_head *, struct buffer_head *, diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index fb15a96df0b6063bfb7c36e08ddb449a60331857..a177eae3aa1ad593adc62349d6e734cc026717b4 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -955,8 +955,7 @@ int ocfs2_read_extent_block(struct ocfs2_caching_info *ci, u64 eb_blkno, /* * How many free extents have we got before we need more meta data? */ -int ocfs2_num_free_extents(struct ocfs2_super *osb, - struct ocfs2_extent_tree *et) +int ocfs2_num_free_extents(struct ocfs2_extent_tree *et) { int retval; struct ocfs2_extent_list *el = NULL; @@ -1933,14 +1932,12 @@ int ocfs2_find_leaf(struct ocfs2_caching_info *ci, * the new changes. * * left_rec: the record on the left. - * left_child_el: is the child list pointed to by left_rec * right_rec: the record to the right of left_rec * right_child_el: is the child list pointed to by right_rec * * By definition, this only works on interior nodes. */ static void ocfs2_adjust_adjacent_records(struct ocfs2_extent_rec *left_rec, - struct ocfs2_extent_list *left_child_el, struct ocfs2_extent_rec *right_rec, struct ocfs2_extent_list *right_child_el) { @@ -2003,7 +2000,7 @@ static void ocfs2_adjust_root_records(struct ocfs2_extent_list *root_el, */ BUG_ON(i >= (le16_to_cpu(root_el->l_next_free_rec) - 1)); - ocfs2_adjust_adjacent_records(&root_el->l_recs[i], left_el, + ocfs2_adjust_adjacent_records(&root_el->l_recs[i], &root_el->l_recs[i + 1], right_el); } @@ -2060,8 +2057,7 @@ static void ocfs2_complete_edge_insert(handle_t *handle, el = right_path->p_node[i].el; right_rec = &el->l_recs[0]; - ocfs2_adjust_adjacent_records(left_rec, left_el, right_rec, - right_el); + ocfs2_adjust_adjacent_records(left_rec, right_rec, right_el); ocfs2_journal_dirty(handle, left_path->p_node[i].bh); ocfs2_journal_dirty(handle, right_path->p_node[i].bh); @@ -2509,7 +2505,7 @@ static int ocfs2_rotate_tree_right(handle_t *handle, static int ocfs2_update_edge_lengths(handle_t *handle, struct ocfs2_extent_tree *et, - int subtree_index, struct ocfs2_path *path) + struct ocfs2_path *path) { int i, idx, ret; struct ocfs2_extent_rec *rec; @@ -2755,8 +2751,7 @@ static int ocfs2_rotate_subtree_left(handle_t *handle, if (del_right_subtree) { ocfs2_unlink_subtree(handle, et, left_path, right_path, subtree_index, dealloc); - ret = ocfs2_update_edge_lengths(handle, et, subtree_index, - left_path); + ret = ocfs2_update_edge_lengths(handle, et, left_path); if (ret) { mlog_errno(ret); goto out; @@ -3060,8 +3055,7 @@ static int ocfs2_remove_rightmost_path(handle_t *handle, ocfs2_unlink_subtree(handle, et, left_path, path, subtree_index, dealloc); - ret = ocfs2_update_edge_lengths(handle, et, subtree_index, - left_path); + ret = ocfs2_update_edge_lengths(handle, et, left_path); if (ret) { mlog_errno(ret); goto out; @@ -4790,7 +4784,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, if (mark_unwritten) flags = OCFS2_EXT_UNWRITTEN; - free_extents = ocfs2_num_free_extents(osb, et); + free_extents = ocfs2_num_free_extents(et); if (free_extents < 0) { status = free_extents; mlog_errno(status); @@ -5668,7 +5662,7 @@ static int ocfs2_reserve_blocks_for_rec_trunc(struct inode *inode, *ac = NULL; - num_free_extents = ocfs2_num_free_extents(osb, et); + num_free_extents = ocfs2_num_free_extents(et); if (num_free_extents < 0) { ret = num_free_extents; mlog_errno(ret); diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 4a5152ec88a3323a82b73104b3e416b7bf00af3d..27b75cf32cfadda5054b9005230e4fa7f5378fef 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -144,8 +144,7 @@ int ocfs2_remove_btree_range(struct inode *inode, struct ocfs2_cached_dealloc_ctxt *dealloc, u64 refcount_loc, bool refcount_tree_locked); -int ocfs2_num_free_extents(struct ocfs2_super *osb, - struct ocfs2_extent_tree *et); +int ocfs2_num_free_extents(struct ocfs2_extent_tree *et); /* * how many new metadata chunks would an allocation need at maximum? diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index ffe003982d95622decb1ff65ddaa22605cedea58..d0206042d068becfc2164a0f70033f5631b65f25 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -505,8 +505,7 @@ static inline void o2hb_bio_wait_dec(struct o2hb_bio_wait_ctxt *wc, } } -static void o2hb_wait_on_io(struct o2hb_region *reg, - struct o2hb_bio_wait_ctxt *wc) +static void o2hb_wait_on_io(struct o2hb_bio_wait_ctxt *wc) { o2hb_bio_wait_dec(wc, 1); wait_for_completion(&wc->wc_io_complete); @@ -554,7 +553,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg, /* Must put everything in 512 byte sectors for the bio... */ bio->bi_iter.bi_sector = (reg->hr_start_block + cs) << (bits - 9); - bio->bi_bdev = reg->hr_bdev; + bio_set_dev(bio, reg->hr_bdev); bio->bi_private = wc; bio->bi_end_io = o2hb_bio_end_io; bio_set_op_attrs(bio, op, op_flags); @@ -608,7 +607,7 @@ static int o2hb_read_slots(struct o2hb_region *reg, status = 0; bail_and_wait: - o2hb_wait_on_io(reg, &wc); + o2hb_wait_on_io(&wc); if (wc.wc_error && !status) status = wc.wc_error; @@ -1162,7 +1161,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) * before we can go to steady state. This ensures that * people we find in our steady state have seen us. */ - o2hb_wait_on_io(reg, &write_wc); + o2hb_wait_on_io(&write_wc); if (write_wc.wc_error) { /* Do not re-arm the write timeout on I/O error - we * can't be sure that the new block ever made it to @@ -1275,7 +1274,7 @@ static int o2hb_thread(void *data) o2hb_prepare_block(reg, 0); ret = o2hb_issue_node_write(reg, &write_wc); if (ret == 0) - o2hb_wait_on_io(reg, &write_wc); + o2hb_wait_on_io(&write_wc); else mlog_errno(ret); } @@ -2576,22 +2575,6 @@ void o2hb_unregister_callback(const char *region_uuid, } EXPORT_SYMBOL_GPL(o2hb_unregister_callback); -int o2hb_check_node_heartbeating(u8 node_num) -{ - unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; - - o2hb_fill_node_map(testing_map, sizeof(testing_map)); - if (!test_bit(node_num, testing_map)) { - mlog(ML_HEARTBEAT, - "node (%u) does not have heartbeating enabled.\n", - node_num); - return 0; - } - - return 1; -} -EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating); - int o2hb_check_node_heartbeating_no_sem(u8 node_num) { unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; @@ -2626,23 +2609,6 @@ int o2hb_check_node_heartbeating_from_callback(u8 node_num) } EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating_from_callback); -/* Makes sure our local node is configured with a node number, and is - * heartbeating. */ -int o2hb_check_local_node_heartbeating(void) -{ - u8 node_num; - - /* if this node was set then we have networking */ - node_num = o2nm_this_node(); - if (node_num == O2NM_MAX_NODES) { - mlog(ML_HEARTBEAT, "this node has not been configured.\n"); - return 0; - } - - return o2hb_check_node_heartbeating(node_num); -} -EXPORT_SYMBOL_GPL(o2hb_check_local_node_heartbeating); - /* * this is just a hack until we get the plumbing which flips file systems * read only and drops the hb ref instead of killing the node dead. diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 3ecb9f337b7d318868ad1c1ebaaf7ea331aeb623..febe6312ceff8d566e8471003f00966f2fe1898e 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -3249,7 +3249,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, spin_unlock(&OCFS2_I(dir)->ip_lock); ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(dir), parent_fe_bh); - num_free_extents = ocfs2_num_free_extents(osb, &et); + num_free_extents = ocfs2_num_free_extents(&et); if (num_free_extents < 0) { status = num_free_extents; mlog_errno(status); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index bfeb647459d95e6425edd63c3179b848e027c848..6e41fc8fabbe78d1a69b437181bb99eb715ecd28 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -196,7 +196,7 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) return -EROFS; - err = filemap_write_and_wait_range(inode->i_mapping, start, end); + err = file_write_and_wait_range(file, start, end); if (err) return err; @@ -713,13 +713,6 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, return status; } -int ocfs2_extend_allocation(struct inode *inode, u32 logical_start, - u32 clusters_to_add, int mark_unwritten) -{ - return __ocfs2_extend_allocation(inode, logical_start, - clusters_to_add, mark_unwritten); -} - /* * While a write will already be ordering the data, a truncate will not. * Thus, we need to explicitly order the zeroed pages. diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index d5e5fa7f07436f4be241d9fc1746b34dbaf48a64..36304434eacf2f9917ed21002403f2bd63d1fe3e 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1348,7 +1348,6 @@ void ocfs2_complete_mount_recovery(struct ocfs2_super *osb) ocfs2_schedule_truncate_log_flush(osb, 0); osb->local_alloc_copy = NULL; - osb->dirty = 0; /* queue to recover orphan slots for all offline slots */ ocfs2_replay_map_set_state(osb, REPLAY_NEEDED); diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index e52a2852d50dba45a36209e65e327911a89f1449..7eb3b0a6347ef74990589ac47f5b4823441c8135 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -175,7 +175,7 @@ static int ocfs2_lock_allocators_move_extents(struct inode *inode, unsigned int max_recs_needed = 2 * extents_to_split + clusters_to_move; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - num_free_extents = ocfs2_num_free_extents(osb, et); + num_free_extents = ocfs2_num_free_extents(et); if (num_free_extents < 0) { ret = num_free_extents; mlog_errno(ret); diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 0c39d71c67a1802ae401cc1607334b86949f3d64..9a50f222ac97fc800edb5ab196c2f7f41c4f1382 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -320,7 +320,6 @@ struct ocfs2_super u64 system_dir_blkno; u64 bitmap_blkno; u32 bitmap_cpg; - u8 *uuid; char *uuid_str; u32 uuid_hash; u8 *vol_label; @@ -388,9 +387,8 @@ struct ocfs2_super unsigned int osb_resv_level; unsigned int osb_dir_resv_level; - /* Next three fields are for local node slot recovery during + /* Next two fields are for local node slot recovery during * mount. */ - int dirty; struct ocfs2_dinode *local_alloc_copy; struct ocfs2_quota_recovery *quota_rec; diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index cec495a921e32cbbd4ff5bd5d2944bbf5c93f09b..c94b6baaa55128b7cf9bec5961f6aecee446fa38 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -33,7 +33,7 @@ * Locking of quotas with OCFS2 is rather complex. Here are rules that * should be obeyed by all the functions: * - any write of quota structure (either to local or global file) is protected - * by dqio_mutex or dquot->dq_lock. + * by dqio_sem or dquot->dq_lock. * - any modification of global quota file holds inode cluster lock, i_mutex, * and ip_alloc_sem of the global quota file (achieved by * ocfs2_lock_global_qf). It also has to hold qinfo_lock. @@ -42,9 +42,9 @@ * * A rough sketch of locking dependencies (lf = local file, gf = global file): * Normal filesystem operation: - * start_trans -> dqio_mutex -> write to lf + * start_trans -> dqio_sem -> write to lf * Syncing of local and global file: - * ocfs2_lock_global_qf -> start_trans -> dqio_mutex -> qinfo_lock -> + * ocfs2_lock_global_qf -> start_trans -> dqio_sem -> qinfo_lock -> * write to gf * -> write to lf * Acquire dquot for the first time: @@ -60,7 +60,7 @@ * Recovery: * inode cluster lock of recovered lf * -> read bitmaps -> ip_alloc_sem of lf - * -> ocfs2_lock_global_qf -> start_trans -> dqio_mutex -> qinfo_lock -> + * -> ocfs2_lock_global_qf -> start_trans -> dqio_sem -> qinfo_lock -> * write to gf */ @@ -443,13 +443,17 @@ static int __ocfs2_global_write_info(struct super_block *sb, int type) int ocfs2_global_write_info(struct super_block *sb, int type) { int err; - struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; + struct quota_info *dqopt = sb_dqopt(sb); + struct ocfs2_mem_dqinfo *info = dqopt->info[type].dqi_priv; + down_write(&dqopt->dqio_sem); err = ocfs2_qinfo_lock(info, 1); if (err < 0) - return err; + goto out_sem; err = __ocfs2_global_write_info(sb, type); ocfs2_qinfo_unlock(info, 1); +out_sem: + up_write(&dqopt->dqio_sem); return err; } @@ -500,7 +504,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) /* Update space and inode usage. Get also other information from * global quota file so that we don't overwrite any changes there. * We are */ - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); spacechange = dquot->dq_dqb.dqb_curspace - OCFS2_DQUOT(dquot)->dq_origspace; inodechange = dquot->dq_dqb.dqb_curinodes - @@ -556,7 +560,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) __clear_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes; - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); err = ocfs2_qinfo_lock(info, freeing); if (err < 0) { mlog(ML_ERROR, "Failed to lock quota info, losing quota write" @@ -611,7 +615,7 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) mlog_errno(status); goto out_ilock; } - mutex_lock(&sb_dqopt(sb)->dqio_mutex); + down_write(&sb_dqopt(sb)->dqio_sem); status = ocfs2_sync_dquot(dquot); if (status < 0) mlog_errno(status); @@ -619,7 +623,7 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) status = ocfs2_local_write_dquot(dquot); if (status < 0) mlog_errno(status); - mutex_unlock(&sb_dqopt(sb)->dqio_mutex); + up_write(&sb_dqopt(sb)->dqio_sem); ocfs2_commit_trans(osb, handle); out_ilock: ocfs2_unlock_global_qf(oinfo, 1); @@ -666,9 +670,9 @@ static int ocfs2_write_dquot(struct dquot *dquot) mlog_errno(status); goto out; } - mutex_lock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); + down_write(&sb_dqopt(dquot->dq_sb)->dqio_sem); status = ocfs2_local_write_dquot(dquot); - mutex_unlock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); + up_write(&sb_dqopt(dquot->dq_sb)->dqio_sem); ocfs2_commit_trans(osb, handle); out: return status; @@ -920,10 +924,10 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) /* In case user set some limits, sync dquot immediately to global * quota file so that information propagates quicker */ - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); if (dquot->dq_flags & mask) sync = 1; - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); /* This is a slight hack but we can't afford getting global quota * lock if we already have a transaction started. */ if (!sync || journal_current_handle()) { @@ -939,7 +943,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) mlog_errno(status); goto out_ilock; } - mutex_lock(&sb_dqopt(sb)->dqio_mutex); + down_write(&sb_dqopt(sb)->dqio_sem); status = ocfs2_sync_dquot(dquot); if (status < 0) { mlog_errno(status); @@ -948,7 +952,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) /* Now write updated local dquot structure */ status = ocfs2_local_write_dquot(dquot); out_dlock: - mutex_unlock(&sb_dqopt(sb)->dqio_mutex); + up_write(&sb_dqopt(sb)->dqio_sem); ocfs2_commit_trans(osb, handle); out_ilock: ocfs2_unlock_global_qf(oinfo, 1); diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 32c5a40c1257ecda129944a1abf4cdac83a2e8a1..aa700fd10610baf8b022fc17581cd200e13c22ec 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -520,8 +520,8 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, mlog_errno(status); goto out_drop_lock; } - mutex_lock(&sb_dqopt(sb)->dqio_mutex); - spin_lock(&dq_data_lock); + down_write(&sb_dqopt(sb)->dqio_sem); + spin_lock(&dquot->dq_dqb_lock); /* Add usage from quota entry into quota changes * of our node. Auxiliary variables are important * due to signedness */ @@ -529,7 +529,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, inodechange = le64_to_cpu(dqblk->dqb_inodemod); dquot->dq_dqb.dqb_curspace += spacechange; dquot->dq_dqb.dqb_curinodes += inodechange; - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); /* We want to drop reference held by the crashed * node. Since we have our own reference we know * global structure actually won't be freed. */ @@ -553,7 +553,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, unlock_buffer(qbh); ocfs2_journal_dirty(handle, qbh); out_commit: - mutex_unlock(&sb_dqopt(sb)->dqio_mutex); + up_write(&sb_dqopt(sb)->dqio_sem); ocfs2_commit_trans(OCFS2_SB(sb), handle); out_drop_lock: ocfs2_unlock_global_qf(oinfo, 1); @@ -691,9 +691,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) struct ocfs2_quota_recovery *rec; int locked = 0; - /* We don't need the lock and we have to acquire quota file locks - * which will later depend on this lock */ - mutex_unlock(&sb_dqopt(sb)->dqio_mutex); info->dqi_max_spc_limit = 0x7fffffffffffffffLL; info->dqi_max_ino_limit = 0x7fffffffffffffffLL; oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS); @@ -772,7 +769,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) goto out_err; } - mutex_lock(&sb_dqopt(sb)->dqio_mutex); return 0; out_err: if (oinfo) { @@ -786,7 +782,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) kfree(oinfo); } brelse(bh); - mutex_lock(&sb_dqopt(sb)->dqio_mutex); return -1; } @@ -882,12 +877,12 @@ static void olq_set_dquot(struct buffer_head *bh, void *private) dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns, od->dq_dquot.dq_id)); - spin_lock(&dq_data_lock); + spin_lock(&od->dq_dquot.dq_dqb_lock); dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace - od->dq_origspace); dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes - od->dq_originodes); - spin_unlock(&dq_data_lock); + spin_unlock(&od->dq_dquot.dq_dqb_lock); trace_olq_set_dquot( (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod), (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod), diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index f8933cb53d682aaf4c7e22efb75a43d4c1c688ac..ab156e35ec00c462d69a4566ba3475cd39d5d176 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -2851,7 +2851,7 @@ static int ocfs2_lock_refcount_allocators(struct super_block *sb, int *credits) { int ret = 0, meta_add = 0; - int num_free_extents = ocfs2_num_free_extents(OCFS2_SB(sb), et); + int num_free_extents = ocfs2_num_free_extents(et); if (num_free_extents < 0) { ret = num_free_extents; diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 6ad3533940ba5e9fa32bfe83d3c1acc19b14513a..71f22c8fbffd49305fa147c4fafae30ddac31c13 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -2700,7 +2700,7 @@ int ocfs2_lock_allocators(struct inode *inode, BUG_ON(clusters_to_add != 0 && data_ac == NULL); - num_free_extents = ocfs2_num_free_extents(osb, et); + num_free_extents = ocfs2_num_free_extents(et); if (num_free_extents < 0) { ret = num_free_extents; mlog_errno(ret); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 83005f486451eaaa211614f22247fb885f24d229..80733496b22af96f2c323f408fc5e1cfd45cdf7e 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -675,7 +675,7 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) } /* We're going to/from readonly mode. */ - if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) { + if ((bool)(*flags & MS_RDONLY) != sb_rdonly(sb)) { /* Disable quota accounting before remounting RO */ if (*flags & MS_RDONLY) { ret = ocfs2_susp_quotas(osb, 0); @@ -1063,7 +1063,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) /* Hard readonly mode only if: bdev_read_only, MS_RDONLY, * heartbeat=none */ if (bdev_read_only(sb->s_bdev)) { - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { status = -EACCES; mlog(ML_ERROR, "Readonly device detected but readonly " "mount was not specified.\n"); @@ -1098,7 +1098,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) } if (!ocfs2_is_hard_readonly(osb)) { - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) ocfs2_set_ro_flag(osb, 0); } @@ -1179,7 +1179,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) /* Now we can initialize quotas because we can afford to wait * for cluster locks recovery now. That also means that truncation * log recovery can happen but that waits for proper quota setup */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { status = ocfs2_enable_quotas(osb); if (status < 0) { /* We have to err-out specially here because @@ -2180,8 +2180,7 @@ static int ocfs2_initialize_super(struct super_block *sb, status = -EINVAL; goto bail; } - if (!(osb->sb->s_flags & MS_RDONLY) && - (i = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_RO_COMPAT_SUPP))) { + if (!sb_rdonly(osb->sb) && (i = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_RO_COMPAT_SUPP))) { mlog(ML_ERROR, "couldn't mount RDWR because of " "unsupported optional features (%x).\n", i); status = -EINVAL; @@ -2486,7 +2485,6 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) if (dirty) { /* Recovery will be completed after we've mounted the * rest of the volume. */ - osb->dirty = 1; osb->local_alloc_copy = local_alloc; local_alloc = NULL; } @@ -2568,9 +2566,7 @@ static int ocfs2_handle_error(struct super_block *sb) rv = -EIO; } else { /* default option */ rv = -EROFS; - if (sb->s_flags & MS_RDONLY && - (ocfs2_is_soft_readonly(osb) || - ocfs2_is_hard_readonly(osb))) + if (sb_rdonly(sb) && (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb))) return rv; pr_crit("OCFS2: File system is now read-only.\n"); diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index f70c3778d600c6be63996572bee6fd46ac03440c..5fdf269ba82e393c1bff315b260ec45b7a1787b2 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -6800,7 +6800,7 @@ static int ocfs2_lock_reflink_xattr_rec_allocators( *credits += 1; /* count in the xattr tree change. */ - num_free_extents = ocfs2_num_free_extents(osb, xt_et); + num_free_extents = ocfs2_num_free_extents(xt_et); if (num_free_extents < 0) { ret = num_free_extents; mlog_errno(ret); diff --git a/fs/open.c b/fs/open.c index 35bb784763a4fde35558b10d8538cb9617a7c728..7ea118471dce59996ae3d3d9b9e3b9d156baffba 100644 --- a/fs/open.c +++ b/fs/open.c @@ -96,7 +96,7 @@ long vfs_truncate(const struct path *path, loff_t length) * write access on the upper inode, not on the overlay inode. For * non-overlay filesystems d_real() is an identity function. */ - upperdentry = d_real(path->dentry, NULL, O_WRONLY); + upperdentry = d_real(path->dentry, NULL, O_WRONLY, 0); error = PTR_ERR(upperdentry); if (IS_ERR(upperdentry)) goto mnt_drop_write_and_out; @@ -670,12 +670,12 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) if (!f.file) goto out; - error = mnt_want_write_file(f.file); + error = mnt_want_write_file_path(f.file); if (error) goto out_fput; audit_file(f.file); error = chown_common(&f.file->f_path, user, group); - mnt_drop_write_file(f.file); + mnt_drop_write_file_path(f.file); out_fput: fdput(f); out: @@ -857,7 +857,7 @@ EXPORT_SYMBOL(file_path); int vfs_open(const struct path *path, struct file *file, const struct cred *cred) { - struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags); + struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags, 0); if (IS_ERR(dentry)) return PTR_ERR(dentry); diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c index 7a3754488312c650b3003f5cb23a06bb17a53aeb..9108ef433e6d7b09721360a4dc3c1e7f4f2caf3b 100644 --- a/fs/orangefs/acl.c +++ b/fs/orangefs/acl.c @@ -35,7 +35,7 @@ struct posix_acl *orangefs_get_acl(struct inode *inode, int type) * I don't do that for now. */ value = kmalloc(ORANGEFS_MAX_XATTR_VALUELEN, GFP_KERNEL); - if (value == NULL) + if (!value) return ERR_PTR(-ENOMEM); gossip_debug(GOSSIP_ACL_DEBUG, @@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struct inode *inode, int type) return acl; } -int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, + int type) { - struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); int error = 0; void *value = NULL; size_t size = 0; @@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) switch (type) { case ACL_TYPE_ACCESS: name = XATTR_NAME_POSIX_ACL_ACCESS; - if (acl) { - umode_t mode; - - error = posix_acl_update_mode(inode, &mode, &acl); - if (error) { - gossip_err("%s: posix_acl_update_mode err: %d\n", - __func__, - error); - return error; - } - - if (inode->i_mode != mode) - SetModeFlag(orangefs_inode); - inode->i_mode = mode; - mark_inode_dirty_sync(inode); - } break; case ACL_TYPE_DEFAULT: name = XATTR_NAME_POSIX_ACL_DEFAULT; @@ -132,6 +116,42 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) return error; } +int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + int error; + struct iattr iattr; + int rc; + + if (type == ACL_TYPE_ACCESS && acl) { + /* + * posix_acl_update_mode checks to see if the permissions + * described by the ACL can be encoded into the + * object's mode. If so, it sets "acl" to NULL + * and "mode" to the new desired value. It is up to + * us to propagate the new mode back to the server... + */ + error = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); + if (error) { + gossip_err("%s: posix_acl_update_mode err: %d\n", + __func__, + error); + return error; + } + + if (acl) { + rc = __orangefs_set_acl(inode, acl, type); + } else { + iattr.ia_valid = ATTR_MODE; + rc = orangefs_inode_setattr(inode, &iattr); + } + + return rc; + + } else { + return -EINVAL; + } +} + int orangefs_init_acl(struct inode *inode, struct inode *dir) { struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); @@ -146,13 +166,14 @@ int orangefs_init_acl(struct inode *inode, struct inode *dir) return error; if (default_acl) { - error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); + error = __orangefs_set_acl(inode, default_acl, + ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } if (acl) { if (!error) - error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); + error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); } diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index c19f0787c9c65bddfc8b82ca7fad2f88549f2f91..2826859bdc2cb12149c1eed219ec65a1f01ad5d9 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -461,13 +461,10 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, if (op->downcall.type != ORANGEFS_VFS_OP_READDIR) goto wakeup; - op->downcall.trailer_buf = - vmalloc(op->downcall.trailer_size); - if (op->downcall.trailer_buf == NULL) { - gossip_err("%s: failed trailer vmalloc.\n", - __func__); + op->downcall.trailer_buf = vmalloc(op->downcall.trailer_size); + if (!op->downcall.trailer_buf) goto Enomem; - } + memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size); if (!copy_from_iter_full(op->downcall.trailer_buf, op->downcall.trailer_size, iter)) { diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 28f38d813ad23f69f24900a4e8bd6ee75e57659f..336ecbf8c2683a80b5a8a7b96a7fabe1e6a012b5 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -646,14 +646,11 @@ static int orangefs_fsync(struct file *file, loff_t end, int datasync) { - int ret = -EINVAL; + int ret; struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(file_inode(file)); struct orangefs_kernel_op_s *new_op = NULL; - /* required call */ - filemap_write_and_wait_range(file->f_mapping, start, end); - new_op = op_alloc(ORANGEFS_VFS_OP_FSYNC); if (!new_op) return -ENOMEM; diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index 038d67545d9f07c2a7a60db70eac368660f24f72..7ef473f3d64286d8d9e32ddf636bc955bee27b31 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -244,20 +244,14 @@ orangefs_bufmap_alloc(struct ORANGEFS_dev_map_desc *user_desc) bufmap->buffer_index_array = kzalloc(DIV_ROUND_UP(bufmap->desc_count, BITS_PER_LONG), GFP_KERNEL); - if (!bufmap->buffer_index_array) { - gossip_err("orangefs: could not allocate %d buffer indices\n", - bufmap->desc_count); + if (!bufmap->buffer_index_array) goto out_free_bufmap; - } bufmap->desc_array = kcalloc(bufmap->desc_count, sizeof(struct orangefs_bufmap_desc), GFP_KERNEL); - if (!bufmap->desc_array) { - gossip_err("orangefs: could not allocate %d descriptors\n", - bufmap->desc_count); + if (!bufmap->desc_array) goto out_free_index_array; - } bufmap->page_count = bufmap->total_size / PAGE_SIZE; diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index 716ed337f1663ddfaf0729c5d8275b0366308f19..5f59917fd631ca8ed3952bd02ac86d4b2a0de8fb 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -571,11 +571,8 @@ static int orangefs_prepare_cdm_array(char *debug_array_string) goto out; } - cdm_array = - kzalloc(cdm_element_count * sizeof(struct client_debug_mask), - GFP_KERNEL); + cdm_array = kcalloc(cdm_element_count, sizeof(*cdm_array), GFP_KERNEL); if (!cdm_array) { - pr_info("malloc failed for cdm_array!\n"); rc = -ENOMEM; goto out; } diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index c1b5174cb5a9fd5fa0963c22478f1457503e6657..85ef87245a872e51de68a6ae84df88a1416ef3a3 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -98,7 +98,6 @@ static int __init orangefs_init(void) orangefs_htable_ops_in_progress = kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL); if (!orangefs_htable_ops_in_progress) { - gossip_err("Failed to initialize op hashtable"); ret = -ENOMEM; goto cleanup_inode; } diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 5a1bed6c8c6ae5b19eea666343347422b3f0dbbb..47f3fb9cbec405855289679272405a8302575919 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -107,10 +107,8 @@ static struct inode *orangefs_alloc_inode(struct super_block *sb) struct orangefs_inode_s *orangefs_inode; orangefs_inode = kmem_cache_alloc(orangefs_inode_cache, GFP_KERNEL); - if (orangefs_inode == NULL) { - gossip_err("Failed to allocate orangefs_inode\n"); + if (!orangefs_inode) return NULL; - } /* * We want to clear everything except for rw_semaphore and the diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index 237c9c04dc3b49ffcaae3de63a752dbb4891fd0c..81ac88bb91ff9fc6d0d77dc555b8142c86a8040d 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -76,7 +76,7 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; - if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN) + if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) return -EINVAL; fsuid = from_kuid(&init_user_ns, current_fsuid()); @@ -169,7 +169,7 @@ static int orangefs_inode_removexattr(struct inode *inode, const char *name, struct orangefs_kernel_op_s *new_op = NULL; int ret = -ENOMEM; - if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN) + if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) return -EINVAL; down_write(&orangefs_inode->xattr_sem); @@ -233,13 +233,13 @@ int orangefs_inode_setxattr(struct inode *inode, const char *name, if (size > ORANGEFS_MAX_XATTR_VALUELEN) return -EINVAL; - if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN) + if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) return -EINVAL; internal_flag = convert_to_internal_xattr_flags(flags); /* This is equivalent to a removexattr */ - if (size == 0 && value == NULL) { + if (size == 0 && !value) { gossip_debug(GOSSIP_XATTR_DEBUG, "removing xattr (%s)\n", name); @@ -311,7 +311,7 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) int i = 0; int returned_count = 0; - if (size > 0 && buffer == NULL) { + if (size > 0 && !buffer) { gossip_err("%s: bogus NULL pointers\n", __func__); return -EINVAL; } @@ -442,7 +442,7 @@ static int orangefs_xattr_get_default(const struct xattr_handler *handler, } -static struct xattr_handler orangefs_xattr_default_handler = { +static const struct xattr_handler orangefs_xattr_default_handler = { .prefix = "", /* match any name => handlers called with full name */ .get = orangefs_xattr_get_default, .set = orangefs_xattr_set_default, diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index acb6f97deb97ccd25c7a3b785f1ae1280858d6c4..c441f9387a1ba0f2ddf1f1426a114a5533fb6e30 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -241,7 +241,7 @@ struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper) int buflen = MAX_HANDLE_SZ; uuid_t *uuid = &lower->d_sb->s_uuid; - buf = kmalloc(buflen, GFP_TEMPORARY); + buf = kmalloc(buflen, GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM); @@ -561,10 +561,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) c->tmpfile = true; err = ovl_copy_up_locked(c); } else { - err = -EIO; - if (lock_rename(c->workdir, c->destdir) != NULL) { - pr_err("overlayfs: failed to lock workdir+upperdir\n"); - } else { + err = ovl_lock_rename_workdir(c->workdir, c->destdir); + if (!err) { err = ovl_copy_up_locked(c); unlock_rename(c->workdir, c->destdir); } diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 48b70e6490f32e9c7f9c34f8dcb20735279b3946..cc961a3bd3bdec34fcace34553f9e8cfb319db25 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -155,7 +155,7 @@ static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) static void ovl_instantiate(struct dentry *dentry, struct inode *inode, struct dentry *newdentry, bool hardlink) { - ovl_dentry_version_inc(dentry->d_parent); + ovl_dentry_version_inc(dentry->d_parent, false); ovl_dentry_set_upper_alias(dentry); if (!hardlink) { ovl_inode_update(inode, newdentry); @@ -216,26 +216,6 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, return err; } -static int ovl_lock_rename_workdir(struct dentry *workdir, - struct dentry *upperdir) -{ - /* Workdir should not be the same as upperdir */ - if (workdir == upperdir) - goto err; - - /* Workdir should not be subdir of upperdir and vice versa */ - if (lock_rename(workdir, upperdir) != NULL) - goto err_unlock; - - return 0; - -err_unlock: - unlock_rename(workdir, upperdir); -err: - pr_err("overlayfs: failed to lock workdir+upperdir\n"); - return -EIO; -} - static struct dentry *ovl_clear_empty(struct dentry *dentry, struct list_head *list) { @@ -692,7 +672,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) if (flags) ovl_cleanup(wdir, upper); - ovl_dentry_version_inc(dentry->d_parent); + ovl_dentry_version_inc(dentry->d_parent, true); out_d_drop: d_drop(dentry); dput(whiteout); @@ -742,7 +722,7 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir) err = vfs_rmdir(dir, upper); else err = vfs_unlink(dir, upper, NULL); - ovl_dentry_version_inc(dentry->d_parent); + ovl_dentry_version_inc(dentry->d_parent, ovl_type_origin(dentry)); /* * Keeping this dentry hashed would mean having to release @@ -833,7 +813,7 @@ static char *ovl_get_redirect(struct dentry *dentry, bool samedir) goto out; } - buf = ret = kmalloc(buflen, GFP_TEMPORARY); + buf = ret = kmalloc(buflen, GFP_KERNEL); if (!buf) goto out; @@ -1089,8 +1069,9 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, drop_nlink(d_inode(new)); } - ovl_dentry_version_inc(old->d_parent); - ovl_dentry_version_inc(new->d_parent); + ovl_dentry_version_inc(old->d_parent, + !overwrite && ovl_type_origin(new)); + ovl_dentry_version_inc(new->d_parent, ovl_type_origin(old)); out_dput: dput(newdentry); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 5bc71642b22605367ee319abdf8e45a0ec9adcde..a619addecafcf05713b3a41e7e05a9e0866847a1 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -498,6 +498,9 @@ static int ovl_set_nlink_common(struct dentry *dentry, len = snprintf(buf, sizeof(buf), format, (int) (inode->i_nlink - realinode->i_nlink)); + if (WARN_ON(len >= sizeof(buf))) + return -EIO; + return ovl_do_setxattr(ovl_dentry_upper(dentry), OVL_XATTR_NLINK, buf, len, 0); } @@ -576,10 +579,13 @@ static int ovl_inode_set(struct inode *inode, void *data) static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry, struct dentry *upperdentry) { - struct inode *lowerinode = lowerdentry ? d_inode(lowerdentry) : NULL; - - /* Lower (origin) inode must match, even if NULL */ - if (ovl_inode_lower(inode) != lowerinode) + /* + * Allow non-NULL lower inode in ovl_inode even if lowerdentry is NULL. + * This happens when finding a copied up overlay inode for a renamed + * or hardlinked overlay dentry and lower dentry cannot be followed + * by origin because lower fs does not support file handles. + */ + if (lowerdentry && ovl_inode_lower(inode) != d_inode(lowerdentry)) return false; /* diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 8aef2b304b2d2bd2ad0c26942765e4bca0362835..654bea1a5ac9f38c587919d1fac6d53fd6867ee0 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -38,7 +38,7 @@ static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d, return 0; goto fail; } - buf = kzalloc(prelen + res + strlen(post) + 1, GFP_TEMPORARY); + buf = kzalloc(prelen + res + strlen(post) + 1, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -103,7 +103,7 @@ static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry) if (res == 0) return NULL; - fh = kzalloc(res, GFP_TEMPORARY); + fh = kzalloc(res, GFP_KERNEL); if (!fh) return ERR_PTR(-ENOMEM); @@ -309,7 +309,7 @@ static int ovl_check_origin(struct dentry *upperdentry, BUG_ON(*ctrp); if (!*stackp) - *stackp = kmalloc(sizeof(struct path), GFP_TEMPORARY); + *stackp = kmalloc(sizeof(struct path), GFP_KERNEL); if (!*stackp) { dput(origin); return -ENOMEM; @@ -418,7 +418,7 @@ int ovl_verify_index(struct dentry *index, struct path *lowerstack, err = -ENOMEM; len = index->d_name.len / 2; - fh = kzalloc(len, GFP_TEMPORARY); + fh = kzalloc(len, GFP_KERNEL); if (!fh) goto fail; @@ -478,7 +478,7 @@ int ovl_get_index_name(struct dentry *origin, struct qstr *name) return PTR_ERR(fh); err = -ENOMEM; - n = kzalloc(fh->len * 2, GFP_TEMPORARY); + n = kzalloc(fh->len * 2, GFP_KERNEL); if (n) { s = bin2hex(n, fh, fh->len); *name = (struct qstr) QSTR_INIT(n, s - n); @@ -506,6 +506,7 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry, index = lookup_one_len_unlocked(name.name, ofs->indexdir, name.len); if (IS_ERR(index)) { + err = PTR_ERR(index); pr_warn_ratelimited("overlayfs: failed inode index lookup (ino=%lu, key=%*s, err=%i);\n" "overlayfs: mount with '-o index=off' to disable inodes index.\n", d_inode(origin)->i_ino, name.len, name.name, @@ -646,7 +647,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, if (!d.stop && poe->numlower) { err = -ENOMEM; stack = kcalloc(ofs->numlower, sizeof(struct path), - GFP_TEMPORARY); + GFP_KERNEL); if (!stack) goto out_put_upper; } diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index e927a62c97ae3c92070dbb440712c819cc8e827f..c706a6f999288136b567d75777f5f6742682a9a2 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -204,8 +204,8 @@ struct dentry *ovl_i_dentry_upper(struct inode *inode); struct inode *ovl_inode_upper(struct inode *inode); struct inode *ovl_inode_lower(struct inode *inode); struct inode *ovl_inode_real(struct inode *inode); -struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); -void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache); +struct ovl_dir_cache *ovl_dir_cache(struct inode *inode); +void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache); bool ovl_dentry_is_opaque(struct dentry *dentry); bool ovl_dentry_is_whiteout(struct dentry *dentry); void ovl_dentry_set_opaque(struct dentry *dentry); @@ -217,7 +217,7 @@ void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect); void ovl_inode_init(struct inode *inode, struct dentry *upperdentry, struct dentry *lowerdentry); void ovl_inode_update(struct inode *inode, struct dentry *upperdentry); -void ovl_dentry_version_inc(struct dentry *dentry); +void ovl_dentry_version_inc(struct dentry *dentry, bool impurity); u64 ovl_dentry_version_get(struct dentry *dentry); bool ovl_is_whiteout(struct dentry *dentry); struct file *ovl_path_open(struct path *path, int flags); @@ -229,11 +229,13 @@ int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, int xerr); int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry); void ovl_set_flag(unsigned long flag, struct inode *inode); +void ovl_clear_flag(unsigned long flag, struct inode *inode); bool ovl_test_flag(unsigned long flag, struct inode *inode); bool ovl_inuse_trylock(struct dentry *dentry); void ovl_inuse_unlock(struct dentry *dentry); int ovl_nlink_start(struct dentry *dentry, bool *locked); void ovl_nlink_end(struct dentry *dentry, bool locked); +int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir); static inline bool ovl_is_impuredir(struct dentry *dentry) { @@ -256,6 +258,7 @@ extern const struct file_operations ovl_dir_operations; int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list); void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list); void ovl_cache_free(struct list_head *list); +void ovl_dir_cache_free(struct inode *inode); int ovl_check_d_type_supported(struct path *realpath); void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, struct dentry *dentry, int level); diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index 878a750986dd799ad17d9acfc3818e93dcf288fa..25d9b5adcd429071537c5edf3185b58a6ab9cd60 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -37,6 +37,9 @@ struct ovl_fs { bool noxattr; /* sb common to all layers */ struct super_block *same_sb; + /* Did we take the inuse lock? */ + bool upperdir_locked; + bool workdir_locked; }; /* private information held for every overlayfs dentry */ diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 3d424a51cabbf7f1739f154c4d8a7b5616262029..0f85ee9c3268adb320dcc6c4d37e88ae3ea92013 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -15,11 +15,13 @@ #include #include #include +#include #include "overlayfs.h" struct ovl_cache_entry { unsigned int len; unsigned int type; + u64 real_ino; u64 ino; struct list_head l_node; struct rb_node node; @@ -32,18 +34,20 @@ struct ovl_dir_cache { long refcount; u64 version; struct list_head entries; + struct rb_root root; }; struct ovl_readdir_data { struct dir_context ctx; struct dentry *dentry; bool is_lowest; - struct rb_root root; + struct rb_root *root; struct list_head *list; struct list_head middle; struct ovl_cache_entry *first_maybe_whiteout; int count; int err; + bool is_upper; bool d_type_supported; }; @@ -58,7 +62,33 @@ struct ovl_dir_file { static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n) { - return container_of(n, struct ovl_cache_entry, node); + return rb_entry(n, struct ovl_cache_entry, node); +} + +static bool ovl_cache_entry_find_link(const char *name, int len, + struct rb_node ***link, + struct rb_node **parent) +{ + bool found = false; + struct rb_node **newp = *link; + + while (!found && *newp) { + int cmp; + struct ovl_cache_entry *tmp; + + *parent = *newp; + tmp = ovl_cache_entry_from_node(*newp); + cmp = strncmp(name, tmp->name, len); + if (cmp > 0) + newp = &tmp->node.rb_right; + else if (cmp < 0 || len < tmp->len) + newp = &tmp->node.rb_left; + else + found = true; + } + *link = newp; + + return found; } static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root, @@ -82,6 +112,32 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root, return NULL; } +static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd, + struct ovl_cache_entry *p) +{ + /* Don't care if not doing ovl_iter() */ + if (!rdd->dentry) + return false; + + /* Always recalc d_ino for parent */ + if (strcmp(p->name, "..") == 0) + return true; + + /* If this is lower, then native d_ino will do */ + if (!rdd->is_upper) + return false; + + /* + * Recalc d_ino for '.' and for all entries if dir is impure (contains + * copied up entries) + */ + if ((p->name[0] == '.' && p->len == 1) || + ovl_test_flag(OVL_IMPURE, d_inode(rdd->dentry))) + return true; + + return false; +} + static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd, const char *name, int len, u64 ino, unsigned int d_type) @@ -97,7 +153,11 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd, p->name[len] = '\0'; p->len = len; p->type = d_type; + p->real_ino = ino; p->ino = ino; + /* Defer setting d_ino for upper entry to ovl_iterate() */ + if (ovl_calc_d_ino(rdd, p)) + p->ino = 0; p->is_whiteout = false; if (d_type == DT_CHR) { @@ -111,32 +171,22 @@ static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd, const char *name, int len, u64 ino, unsigned int d_type) { - struct rb_node **newp = &rdd->root.rb_node; + struct rb_node **newp = &rdd->root->rb_node; struct rb_node *parent = NULL; struct ovl_cache_entry *p; - while (*newp) { - int cmp; - struct ovl_cache_entry *tmp; - - parent = *newp; - tmp = ovl_cache_entry_from_node(*newp); - cmp = strncmp(name, tmp->name, len); - if (cmp > 0) - newp = &tmp->node.rb_right; - else if (cmp < 0 || len < tmp->len) - newp = &tmp->node.rb_left; - else - return 0; - } + if (ovl_cache_entry_find_link(name, len, &newp, &parent)) + return 0; p = ovl_cache_entry_new(rdd, name, len, ino, d_type); - if (p == NULL) + if (p == NULL) { + rdd->err = -ENOMEM; return -ENOMEM; + } list_add_tail(&p->l_node, rdd->list); rb_link_node(&p->node, parent, newp); - rb_insert_color(&p->node, &rdd->root); + rb_insert_color(&p->node, rdd->root); return 0; } @@ -147,7 +197,7 @@ static int ovl_fill_lowest(struct ovl_readdir_data *rdd, { struct ovl_cache_entry *p; - p = ovl_cache_entry_find(&rdd->root, name, namelen); + p = ovl_cache_entry_find(rdd->root, name, namelen); if (p) { list_move_tail(&p->l_node, &rdd->middle); } else { @@ -172,6 +222,16 @@ void ovl_cache_free(struct list_head *list) INIT_LIST_HEAD(list); } +void ovl_dir_cache_free(struct inode *inode) +{ + struct ovl_dir_cache *cache = ovl_dir_cache(inode); + + if (cache) { + ovl_cache_free(&cache->entries); + kfree(cache); + } +} + static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry) { struct ovl_dir_cache *cache = od->cache; @@ -179,8 +239,8 @@ static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry) WARN_ON(cache->refcount <= 0); cache->refcount--; if (!cache->refcount) { - if (ovl_dir_cache(dentry) == cache) - ovl_set_dir_cache(dentry, NULL); + if (ovl_dir_cache(d_inode(dentry)) == cache) + ovl_set_dir_cache(d_inode(dentry), NULL); ovl_cache_free(&cache->entries); kfree(cache); @@ -273,7 +333,8 @@ static void ovl_dir_reset(struct file *file) od->is_real = false; } -static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list) +static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list, + struct rb_root *root) { int err; struct path realpath; @@ -281,13 +342,14 @@ static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list) .ctx.actor = ovl_fill_merge, .dentry = dentry, .list = list, - .root = RB_ROOT, + .root = root, .is_lowest = false, }; int idx, next; for (idx = 0; idx != -1; idx = next) { next = ovl_path_next(idx, dentry, &realpath); + rdd.is_upper = ovl_dentry_upper(dentry) == realpath.dentry; if (next != -1) { err = ovl_dir_read(&realpath, &rdd); @@ -326,12 +388,13 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) int res; struct ovl_dir_cache *cache; - cache = ovl_dir_cache(dentry); + cache = ovl_dir_cache(d_inode(dentry)); if (cache && ovl_dentry_version_get(dentry) == cache->version) { + WARN_ON(!cache->refcount); cache->refcount++; return cache; } - ovl_set_dir_cache(dentry, NULL); + ovl_set_dir_cache(d_inode(dentry), NULL); cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL); if (!cache) @@ -339,8 +402,9 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) cache->refcount = 1; INIT_LIST_HEAD(&cache->entries); + cache->root = RB_ROOT; - res = ovl_dir_read_merged(dentry, &cache->entries); + res = ovl_dir_read_merged(dentry, &cache->entries, &cache->root); if (res) { ovl_cache_free(&cache->entries); kfree(cache); @@ -348,22 +412,266 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) } cache->version = ovl_dentry_version_get(dentry); - ovl_set_dir_cache(dentry, cache); + ovl_set_dir_cache(d_inode(dentry), cache); return cache; } +/* + * Set d_ino for upper entries. Non-upper entries should always report + * the uppermost real inode ino and should not call this function. + * + * When not all layer are on same fs, report real ino also for upper. + * + * When all layers are on the same fs, and upper has a reference to + * copy up origin, call vfs_getattr() on the overlay entry to make + * sure that d_ino will be consistent with st_ino from stat(2). + */ +static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p) + +{ + struct dentry *dir = path->dentry; + struct dentry *this = NULL; + enum ovl_path_type type; + u64 ino = p->real_ino; + int err = 0; + + if (!ovl_same_sb(dir->d_sb)) + goto out; + + if (p->name[0] == '.') { + if (p->len == 1) { + this = dget(dir); + goto get; + } + if (p->len == 2 && p->name[1] == '.') { + /* we shall not be moved */ + this = dget(dir->d_parent); + goto get; + } + } + this = lookup_one_len(p->name, dir, p->len); + if (IS_ERR_OR_NULL(this) || !this->d_inode) { + if (IS_ERR(this)) { + err = PTR_ERR(this); + this = NULL; + goto fail; + } + goto out; + } + +get: + type = ovl_path_type(this); + if (OVL_TYPE_ORIGIN(type)) { + struct kstat stat; + struct path statpath = *path; + + statpath.dentry = this; + err = vfs_getattr(&statpath, &stat, STATX_INO, 0); + if (err) + goto fail; + + WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev); + ino = stat.ino; + } + +out: + p->ino = ino; + dput(this); + return err; + +fail: + pr_warn_ratelimited("overlay: failed to look up (%s) for ino (%i)\n", + p->name, err); + goto out; +} + +static int ovl_fill_plain(struct dir_context *ctx, const char *name, + int namelen, loff_t offset, u64 ino, + unsigned int d_type) +{ + struct ovl_cache_entry *p; + struct ovl_readdir_data *rdd = + container_of(ctx, struct ovl_readdir_data, ctx); + + rdd->count++; + p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type); + if (p == NULL) { + rdd->err = -ENOMEM; + return -ENOMEM; + } + list_add_tail(&p->l_node, rdd->list); + + return 0; +} + +static int ovl_dir_read_impure(struct path *path, struct list_head *list, + struct rb_root *root) +{ + int err; + struct path realpath; + struct ovl_cache_entry *p, *n; + struct ovl_readdir_data rdd = { + .ctx.actor = ovl_fill_plain, + .list = list, + .root = root, + }; + + INIT_LIST_HEAD(list); + *root = RB_ROOT; + ovl_path_upper(path->dentry, &realpath); + + err = ovl_dir_read(&realpath, &rdd); + if (err) + return err; + + list_for_each_entry_safe(p, n, list, l_node) { + if (strcmp(p->name, ".") != 0 && + strcmp(p->name, "..") != 0) { + err = ovl_cache_update_ino(path, p); + if (err) + return err; + } + if (p->ino == p->real_ino) { + list_del(&p->l_node); + kfree(p); + } else { + struct rb_node **newp = &root->rb_node; + struct rb_node *parent = NULL; + + if (WARN_ON(ovl_cache_entry_find_link(p->name, p->len, + &newp, &parent))) + return -EIO; + + rb_link_node(&p->node, parent, newp); + rb_insert_color(&p->node, root); + } + } + return 0; +} + +static struct ovl_dir_cache *ovl_cache_get_impure(struct path *path) +{ + int res; + struct dentry *dentry = path->dentry; + struct ovl_dir_cache *cache; + + cache = ovl_dir_cache(d_inode(dentry)); + if (cache && ovl_dentry_version_get(dentry) == cache->version) + return cache; + + /* Impure cache is not refcounted, free it here */ + ovl_dir_cache_free(d_inode(dentry)); + ovl_set_dir_cache(d_inode(dentry), NULL); + + cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL); + if (!cache) + return ERR_PTR(-ENOMEM); + + res = ovl_dir_read_impure(path, &cache->entries, &cache->root); + if (res) { + ovl_cache_free(&cache->entries); + kfree(cache); + return ERR_PTR(res); + } + if (list_empty(&cache->entries)) { + /* Good oportunity to get rid of an unnecessary "impure" flag */ + ovl_do_removexattr(ovl_dentry_upper(dentry), OVL_XATTR_IMPURE); + ovl_clear_flag(OVL_IMPURE, d_inode(dentry)); + kfree(cache); + return NULL; + } + + cache->version = ovl_dentry_version_get(dentry); + ovl_set_dir_cache(d_inode(dentry), cache); + + return cache; +} + +struct ovl_readdir_translate { + struct dir_context *orig_ctx; + struct ovl_dir_cache *cache; + struct dir_context ctx; + u64 parent_ino; +}; + +static int ovl_fill_real(struct dir_context *ctx, const char *name, + int namelen, loff_t offset, u64 ino, + unsigned int d_type) +{ + struct ovl_readdir_translate *rdt = + container_of(ctx, struct ovl_readdir_translate, ctx); + struct dir_context *orig_ctx = rdt->orig_ctx; + + if (rdt->parent_ino && strcmp(name, "..") == 0) + ino = rdt->parent_ino; + else if (rdt->cache) { + struct ovl_cache_entry *p; + + p = ovl_cache_entry_find(&rdt->cache->root, name, namelen); + if (p) + ino = p->ino; + } + + return orig_ctx->actor(orig_ctx, name, namelen, offset, ino, d_type); +} + +static int ovl_iterate_real(struct file *file, struct dir_context *ctx) +{ + int err; + struct ovl_dir_file *od = file->private_data; + struct dentry *dir = file->f_path.dentry; + struct ovl_readdir_translate rdt = { + .ctx.actor = ovl_fill_real, + .orig_ctx = ctx, + }; + + if (OVL_TYPE_MERGE(ovl_path_type(dir->d_parent))) { + struct kstat stat; + struct path statpath = file->f_path; + + statpath.dentry = dir->d_parent; + err = vfs_getattr(&statpath, &stat, STATX_INO, 0); + if (err) + return err; + + WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev); + rdt.parent_ino = stat.ino; + } + + if (ovl_test_flag(OVL_IMPURE, d_inode(dir))) { + rdt.cache = ovl_cache_get_impure(&file->f_path); + if (IS_ERR(rdt.cache)) + return PTR_ERR(rdt.cache); + } + + return iterate_dir(od->realfile, &rdt.ctx); +} + + static int ovl_iterate(struct file *file, struct dir_context *ctx) { struct ovl_dir_file *od = file->private_data; struct dentry *dentry = file->f_path.dentry; struct ovl_cache_entry *p; + int err; if (!ctx->pos) ovl_dir_reset(file); - if (od->is_real) + if (od->is_real) { + /* + * If parent is merge, then need to adjust d_ino for '..', if + * dir is impure then need to adjust d_ino for copied up + * entries. + */ + if (ovl_same_sb(dentry->d_sb) && + (ovl_test_flag(OVL_IMPURE, d_inode(dentry)) || + OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent)))) { + return ovl_iterate_real(file, ctx); + } return iterate_dir(od->realfile, ctx); + } if (!od->cache) { struct ovl_dir_cache *cache; @@ -378,9 +686,15 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) while (od->cursor != &od->cache->entries) { p = list_entry(od->cursor, struct ovl_cache_entry, l_node); - if (!p->is_whiteout) + if (!p->is_whiteout) { + if (!p->ino) { + err = ovl_cache_update_ino(&file->f_path, p); + if (err) + return err; + } if (!dir_emit(ctx, p->name, p->len, p->ino, p->type)) break; + } od->cursor = p->l_node.next; ctx->pos++; } @@ -446,14 +760,14 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, ovl_path_upper(dentry, &upperpath); realfile = ovl_path_open(&upperpath, O_RDONLY); - smp_mb__before_spinlock(); + inode_lock(inode); if (!od->upperfile) { if (IS_ERR(realfile)) { inode_unlock(inode); return PTR_ERR(realfile); } - od->upperfile = realfile; + smp_store_release(&od->upperfile, realfile); } else { /* somebody has beaten us to it */ if (!IS_ERR(realfile)) @@ -522,8 +836,9 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) { int err; struct ovl_cache_entry *p; + struct rb_root root = RB_ROOT; - err = ovl_dir_read_merged(dentry, list); + err = ovl_dir_read_merged(dentry, list, &root); if (err) return err; @@ -612,12 +927,13 @@ static void ovl_workdir_cleanup_recurse(struct path *path, int level) int err; struct inode *dir = path->dentry->d_inode; LIST_HEAD(list); + struct rb_root root = RB_ROOT; struct ovl_cache_entry *p; struct ovl_readdir_data rdd = { .ctx.actor = ovl_fill_merge, .dentry = NULL, .list = &list, - .root = RB_ROOT, + .root = &root, .is_lowest = false, }; @@ -672,15 +988,17 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt, struct path *lowerstack, unsigned int numlower) { int err; + struct dentry *index = NULL; struct inode *dir = dentry->d_inode; struct path path = { .mnt = mnt, .dentry = dentry }; LIST_HEAD(list); + struct rb_root root = RB_ROOT; struct ovl_cache_entry *p; struct ovl_readdir_data rdd = { .ctx.actor = ovl_fill_merge, .dentry = NULL, .list = &list, - .root = RB_ROOT, + .root = &root, .is_lowest = false, }; @@ -690,8 +1008,6 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt, inode_lock_nested(dir, I_MUTEX_PARENT); list_for_each_entry(p, &list, l_node) { - struct dentry *index; - if (p->name[0] == '.') { if (p->len == 1) continue; @@ -701,6 +1017,7 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt, index = lookup_one_len(p->name, dentry, p->len); if (IS_ERR(index)) { err = PTR_ERR(index); + index = NULL; break; } err = ovl_verify_index(index, lowerstack, numlower); @@ -712,7 +1029,9 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt, break; } dput(index); + index = NULL; } + dput(index); inode_unlock(dir); out: ovl_cache_free(&list); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index d86e89f972016b4046b20a7a45c2f3f436c50f02..092d150643c12061407be0ecab554a38fe88d9fc 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -70,20 +70,20 @@ static int ovl_check_append_only(struct inode *inode, int flag) static struct dentry *ovl_d_real(struct dentry *dentry, const struct inode *inode, - unsigned int open_flags) + unsigned int open_flags, unsigned int flags) { struct dentry *real; int err; + if (flags & D_REAL_UPPER) + return ovl_dentry_upper(dentry); + if (!d_is_reg(dentry)) { if (!inode || inode == d_inode(dentry)) return dentry; goto bug; } - if (d_is_negative(dentry)) - return dentry; - if (open_flags) { err = ovl_open_maybe_copy_up(dentry, open_flags); if (err) @@ -105,7 +105,7 @@ static struct dentry *ovl_d_real(struct dentry *dentry, goto bug; /* Handle recursion */ - real = d_real(real, inode, open_flags); + real = d_real(real, inode, open_flags, 0); if (!inode || inode == d_inode(real)) return real; @@ -198,6 +198,7 @@ static void ovl_destroy_inode(struct inode *inode) dput(oi->__upperdentry); kfree(oi->redirect); + ovl_dir_cache_free(inode); mutex_destroy(&oi->lock); call_rcu(&inode->i_rcu, ovl_i_callback); @@ -210,9 +211,10 @@ static void ovl_put_super(struct super_block *sb) dput(ufs->indexdir); dput(ufs->workdir); - ovl_inuse_unlock(ufs->workbasedir); + if (ufs->workdir_locked) + ovl_inuse_unlock(ufs->workbasedir); dput(ufs->workbasedir); - if (ufs->upper_mnt) + if (ufs->upper_mnt && ufs->upperdir_locked) ovl_inuse_unlock(ufs->upper_mnt->mnt_root); mntput(ufs->upper_mnt); for (i = 0; i < ufs->numlower; i++) @@ -869,7 +871,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) goto out_free_config; /* Upper fs should not be r/o */ - if (upperpath.mnt->mnt_sb->s_flags & MS_RDONLY) { + if (sb_rdonly(upperpath.mnt->mnt_sb)) { pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n"); err = -EINVAL; goto out_put_upperpath; @@ -880,9 +882,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) goto out_put_upperpath; err = -EBUSY; - if (!ovl_inuse_trylock(upperpath.dentry)) { - pr_err("overlayfs: upperdir is in-use by another mount\n"); + if (ovl_inuse_trylock(upperpath.dentry)) { + ufs->upperdir_locked = true; + } else if (ufs->config.index) { + pr_err("overlayfs: upperdir is in-use by another mount, mount with '-o index=off' to override exclusive upperdir protection.\n"); goto out_put_upperpath; + } else { + pr_warn("overlayfs: upperdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); } err = ovl_mount_dir(ufs->config.workdir, &workpath); @@ -900,9 +906,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) } err = -EBUSY; - if (!ovl_inuse_trylock(workpath.dentry)) { - pr_err("overlayfs: workdir is in-use by another mount\n"); + if (ovl_inuse_trylock(workpath.dentry)) { + ufs->workdir_locked = true; + } else if (ufs->config.index) { + pr_err("overlayfs: workdir is in-use by another mount, mount with '-o index=off' to override exclusive workdir protection.\n"); goto out_put_workpath; + } else { + pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n"); } ufs->workbasedir = workpath.dentry; @@ -1155,11 +1165,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) out_free_lowertmp: kfree(lowertmp); out_unlock_workdentry: - ovl_inuse_unlock(workpath.dentry); + if (ufs->workdir_locked) + ovl_inuse_unlock(workpath.dentry); out_put_workpath: path_put(&workpath); out_unlock_upperdentry: - ovl_inuse_unlock(upperpath.dentry); + if (ufs->upperdir_locked) + ovl_inuse_unlock(upperpath.dentry); out_put_upperpath: path_put(&upperpath); out_free_config: diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index f46ad75dc96af187ea22990a09e63d051aa4bbca..b9b239fa5cfd28d18b120696d05e817330e44241 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -180,14 +180,14 @@ struct inode *ovl_inode_real(struct inode *inode) } -struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry) +struct ovl_dir_cache *ovl_dir_cache(struct inode *inode) { - return OVL_I(d_inode(dentry))->cache; + return OVL_I(inode)->cache; } -void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache) +void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache) { - OVL_I(d_inode(dentry))->cache = cache; + OVL_I(inode)->cache = cache; } bool ovl_dentry_is_opaque(struct dentry *dentry) @@ -275,12 +275,19 @@ void ovl_inode_update(struct inode *inode, struct dentry *upperdentry) } } -void ovl_dentry_version_inc(struct dentry *dentry) +void ovl_dentry_version_inc(struct dentry *dentry, bool impurity) { struct inode *inode = d_inode(dentry); WARN_ON(!inode_is_locked(inode)); - OVL_I(inode)->version++; + /* + * Version is used by readdir code to keep cache consistent. For merge + * dirs all changes need to be noted. For non-merge dirs, cache only + * contains impure (ones which have been copied up and have origins) + * entries, so only need to note changes to impure entries. + */ + if (OVL_TYPE_MERGE(ovl_path_type(dentry)) || impurity) + OVL_I(inode)->version++; } u64 ovl_dentry_version_get(struct dentry *dentry) @@ -382,6 +389,11 @@ void ovl_set_flag(unsigned long flag, struct inode *inode) set_bit(flag, &OVL_I(inode)->flags); } +void ovl_clear_flag(unsigned long flag, struct inode *inode) +{ + clear_bit(flag, &OVL_I(inode)->flags); +} + bool ovl_test_flag(unsigned long flag, struct inode *inode) { return test_bit(flag, &OVL_I(inode)->flags); @@ -418,7 +430,7 @@ void ovl_inuse_unlock(struct dentry *dentry) } } -/* Called must hold OVL_I(inode)->oi_lock */ +/* Caller must hold OVL_I(inode)->lock */ static void ovl_cleanup_index(struct dentry *dentry) { struct inode *dir = ovl_indexdir(dentry->d_sb)->d_inode; @@ -457,6 +469,9 @@ static void ovl_cleanup_index(struct dentry *dentry) err = PTR_ERR(index); if (!IS_ERR(index)) err = ovl_cleanup(dir, index); + else + index = NULL; + inode_unlock(dir); if (err) goto fail; @@ -545,3 +560,22 @@ void ovl_nlink_end(struct dentry *dentry, bool locked) mutex_unlock(&OVL_I(d_inode(dentry))->lock); } } + +int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir) +{ + /* Workdir should not be the same as upperdir */ + if (workdir == upperdir) + goto err; + + /* Workdir should not be subdir of upperdir and vice versa */ + if (lock_rename(workdir, upperdir) != NULL) + goto err_unlock; + + return 0; + +err_unlock: + unlock_rename(workdir, upperdir); +err: + pr_err("overlayfs: failed to lock workdir+upperdir\n"); + return -EIO; +} diff --git a/fs/proc/array.c b/fs/proc/array.c index 88c355574aa0afe3b1a62b371b048af8d948070e..77a8eacbe032f22d5bd9514738341a55dcc46b34 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -118,30 +119,25 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) * simple bit tests. */ static const char * const task_state_array[] = { - "R (running)", /* 0 */ - "S (sleeping)", /* 1 */ - "D (disk sleep)", /* 2 */ - "T (stopped)", /* 4 */ - "t (tracing stop)", /* 8 */ - "X (dead)", /* 16 */ - "Z (zombie)", /* 32 */ + + /* states in TASK_REPORT: */ + "R (running)", /* 0x00 */ + "S (sleeping)", /* 0x01 */ + "D (disk sleep)", /* 0x02 */ + "T (stopped)", /* 0x04 */ + "t (tracing stop)", /* 0x08 */ + "X (dead)", /* 0x10 */ + "Z (zombie)", /* 0x20 */ + "P (parked)", /* 0x40 */ + + /* states beyond TASK_REPORT: */ + "I (idle)", /* 0x80 */ }; static inline const char *get_task_state(struct task_struct *tsk) { - unsigned int state = (tsk->state | tsk->exit_state) & TASK_REPORT; - - /* - * Parked tasks do not run; they sit in __kthread_parkme(). - * Without this check, we would report them as running, which is - * clearly wrong, so we report them as sleeping instead. - */ - if (tsk->state == TASK_PARKED) - state = TASK_INTERRUPTIBLE; - - BUILD_BUG_ON(1 + ilog2(TASK_REPORT) != ARRAY_SIZE(task_state_array)-1); - - return task_state_array[fls(state)]; + BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array)); + return task_state_array[__get_task_state(tsk)]; } static inline int get_task_umask(struct task_struct *tsk) @@ -421,7 +417,15 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, * esp and eip are intentionally zeroed out. There is no * non-racy way to read them without freezing the task. * Programs that need reliable values can use ptrace(2). + * + * The only exception is if the task is core dumping because + * a program is not able to use ptrace(2) in that case. It is + * safe because the task has stopped executing permanently. */ + if (permitted && (task->flags & PF_DUMPCORE)) { + eip = KSTK_EIP(task); + esp = KSTK_ESP(task); + } } get_task_comm(tcomm, task); diff --git a/fs/proc/base.c b/fs/proc/base.c index 719c2e943ea1028f22cd2e400b7b6f9289ca6791..ad3b0762cc3e952bf7c8c7bd717d186d93c21376 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -232,7 +232,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, goto out_mmput; } - page = (char *)__get_free_page(GFP_TEMPORARY); + page = (char *)__get_free_page(GFP_KERNEL); if (!page) { rv = -ENOMEM; goto out_mmput; @@ -813,7 +813,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf, if (!mm) return 0; - page = (char *)__get_free_page(GFP_TEMPORARY); + page = (char *)__get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; @@ -918,7 +918,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, if (!mm || !mm->env_end) return 0; - page = (char *)__get_free_page(GFP_TEMPORARY); + page = (char *)__get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; @@ -1408,12 +1408,13 @@ static const struct file_operations proc_fail_nth_operations = { static int sched_show(struct seq_file *m, void *v) { struct inode *inode = m->private; + struct pid_namespace *ns = inode->i_sb->s_fs_info; struct task_struct *p; p = get_proc_task(inode); if (!p) return -ESRCH; - proc_sched_show_task(p, m); + proc_sched_show_task(p, ns, m); put_task_struct(p); @@ -1629,7 +1630,7 @@ static const char *proc_pid_get_link(struct dentry *dentry, static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) { - char *tmp = (char*)__get_free_page(GFP_TEMPORARY); + char *tmp = (char *)__get_free_page(GFP_KERNEL); char *pathname; int len; @@ -2930,6 +2931,7 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_PROC_PAGE_MONITOR REG("clear_refs", S_IWUSR, proc_clear_refs_operations), REG("smaps", S_IRUGO, proc_pid_smaps_operations), + REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations), REG("pagemap", S_IRUSR, proc_pagemap_operations), #endif #ifdef CONFIG_SECURITY @@ -3323,6 +3325,7 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_PROC_PAGE_MONITOR REG("clear_refs", S_IWUSR, proc_clear_refs_operations), REG("smaps", S_IRUGO, proc_tid_smaps_operations), + REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations), REG("pagemap", S_IRUSR, proc_pagemap_operations), #endif #ifdef CONFIG_SECURITY diff --git a/fs/proc/devices.c b/fs/proc/devices.c index 50493edc30e56e157a6f37407cce84ff60a05de2..e5709343feb7fb63a22c3bb6897c9d8d02f2aee6 100644 --- a/fs/proc/devices.c +++ b/fs/proc/devices.c @@ -7,14 +7,14 @@ static int devinfo_show(struct seq_file *f, void *v) { int i = *(loff_t *) v; - if (i < CHRDEV_MAJOR_HASH_SIZE) { + if (i < CHRDEV_MAJOR_MAX) { if (i == 0) seq_puts(f, "Character devices:\n"); chrdev_show(f, i); } #ifdef CONFIG_BLOCK else { - i -= CHRDEV_MAJOR_HASH_SIZE; + i -= CHRDEV_MAJOR_MAX; if (i == 0) seq_puts(f, "\nBlock devices:\n"); blkdev_show(f, i); @@ -25,7 +25,7 @@ static int devinfo_show(struct seq_file *f, void *v) static void *devinfo_start(struct seq_file *f, loff_t *pos) { - if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) + if (*pos < (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX)) return pos; return NULL; } @@ -33,7 +33,7 @@ static void *devinfo_start(struct seq_file *f, loff_t *pos) static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) { (*pos)++; - if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) + if (*pos >= (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX)) return NULL; return pos; } diff --git a/fs/proc/generic.c b/fs/proc/generic.c index e3cda0b5968fa32ddceee4bf5388e8ec6d772937..793a6757466860e6b8c34f2559f8186c0756239e 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -40,8 +40,8 @@ static int proc_match(unsigned int len, const char *name, struct proc_dir_entry static struct proc_dir_entry *pde_subdir_first(struct proc_dir_entry *dir) { - return rb_entry_safe(rb_first(&dir->subdir), struct proc_dir_entry, - subdir_node); + return rb_entry_safe(rb_first_cached(&dir->subdir), + struct proc_dir_entry, subdir_node); } static struct proc_dir_entry *pde_subdir_next(struct proc_dir_entry *dir) @@ -54,7 +54,7 @@ static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir, const char *name, unsigned int len) { - struct rb_node *node = dir->subdir.rb_node; + struct rb_node *node = dir->subdir.rb_root.rb_node; while (node) { struct proc_dir_entry *de = rb_entry(node, @@ -75,8 +75,9 @@ static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir, static bool pde_subdir_insert(struct proc_dir_entry *dir, struct proc_dir_entry *de) { - struct rb_root *root = &dir->subdir; - struct rb_node **new = &root->rb_node, *parent = NULL; + struct rb_root_cached *root = &dir->subdir; + struct rb_node **new = &root->rb_root.rb_node, *parent = NULL; + bool leftmost = true; /* Figure out where to put new node */ while (*new) { @@ -88,15 +89,16 @@ static bool pde_subdir_insert(struct proc_dir_entry *dir, parent = *new; if (result < 0) new = &(*new)->rb_left; - else if (result > 0) + else if (result > 0) { new = &(*new)->rb_right; - else + leftmost = false; + } else return false; } /* Add new node and rebalance tree. */ rb_link_node(&de->subdir_node, parent, new); - rb_insert_color(&de->subdir_node, root); + rb_insert_color_cached(&de->subdir_node, root, leftmost); return true; } @@ -369,7 +371,7 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, ent->namelen = qstr.len; ent->mode = mode; ent->nlink = nlink; - ent->subdir = RB_ROOT; + ent->subdir = RB_ROOT_CACHED; atomic_set(&ent->count, 1); spin_lock_init(&ent->pde_unload_lock); INIT_LIST_HEAD(&ent->pde_openers); @@ -499,6 +501,14 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, } EXPORT_SYMBOL(proc_create_data); +struct proc_dir_entry *proc_create(const char *name, umode_t mode, + struct proc_dir_entry *parent, + const struct file_operations *proc_fops) +{ + return proc_create_data(name, mode, parent, proc_fops, NULL); +} +EXPORT_SYMBOL(proc_create); + void proc_set_size(struct proc_dir_entry *de, loff_t size) { de->size = size; @@ -545,7 +555,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) de = pde_subdir_find(parent, fn, len); if (de) - rb_erase(&de->subdir_node, &parent->subdir); + rb_erase_cached(&de->subdir_node, &parent->subdir); write_unlock(&proc_subdir_lock); if (!de) { WARN(1, "name '%s'\n", name); @@ -582,13 +592,13 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) write_unlock(&proc_subdir_lock); return -ENOENT; } - rb_erase(&root->subdir_node, &parent->subdir); + rb_erase_cached(&root->subdir_node, &parent->subdir); de = root; while (1) { next = pde_subdir_first(de); if (next) { - rb_erase(&next->subdir_node, &de->subdir); + rb_erase_cached(&next->subdir_node, &de->subdir); de = next; continue; } diff --git a/fs/proc/internal.h b/fs/proc/internal.h index aa2b8907163086daf83034a3dcf54b011d794fe9..a34195e92b206c9f2cd44ee4a627f53efedc3fd8 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -40,7 +40,7 @@ struct proc_dir_entry { const struct inode_operations *proc_iops; const struct file_operations *proc_fops; struct proc_dir_entry *parent; - struct rb_root subdir; + struct rb_root_cached subdir; struct rb_node subdir_node; void *data; atomic_t count; /* use count */ @@ -269,10 +269,12 @@ extern int proc_remount(struct super_block *, int *, char *); /* * task_[no]mmu.c */ +struct mem_size_stats; struct proc_maps_private { struct inode *inode; struct task_struct *task; struct mm_struct *mm; + struct mem_size_stats *rollup; #ifdef CONFIG_MMU struct vm_area_struct *tail_vma; #endif @@ -288,6 +290,7 @@ extern const struct file_operations proc_tid_maps_operations; extern const struct file_operations proc_pid_numa_maps_operations; extern const struct file_operations proc_tid_numa_maps_operations; extern const struct file_operations proc_pid_smaps_operations; +extern const struct file_operations proc_pid_smaps_rollup_operations; extern const struct file_operations proc_tid_smaps_operations; extern const struct file_operations proc_clear_refs_operations; extern const struct file_operations proc_pagemap_operations; diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 8a428498d6b21f08c8c26ef184ff9f4332b5cdd0..cdd979724c7412387f00cf2123965d8998d62c3e 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -80,7 +80,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) show_val_kb(m, "Active(file): ", pages[LRU_ACTIVE_FILE]); show_val_kb(m, "Inactive(file): ", pages[LRU_INACTIVE_FILE]); show_val_kb(m, "Unevictable: ", pages[LRU_UNEVICTABLE]); - show_val_kb(m, "Mlocked: ", global_page_state(NR_MLOCK)); + show_val_kb(m, "Mlocked: ", global_zone_page_state(NR_MLOCK)); #ifdef CONFIG_HIGHMEM show_val_kb(m, "HighTotal: ", i.totalhigh); @@ -106,17 +106,17 @@ static int meminfo_proc_show(struct seq_file *m, void *v) global_node_page_state(NR_FILE_MAPPED)); show_val_kb(m, "Shmem: ", i.sharedram); show_val_kb(m, "Slab: ", - global_page_state(NR_SLAB_RECLAIMABLE) + - global_page_state(NR_SLAB_UNRECLAIMABLE)); + global_node_page_state(NR_SLAB_RECLAIMABLE) + + global_node_page_state(NR_SLAB_UNRECLAIMABLE)); show_val_kb(m, "SReclaimable: ", - global_page_state(NR_SLAB_RECLAIMABLE)); + global_node_page_state(NR_SLAB_RECLAIMABLE)); show_val_kb(m, "SUnreclaim: ", - global_page_state(NR_SLAB_UNRECLAIMABLE)); + global_node_page_state(NR_SLAB_UNRECLAIMABLE)); seq_printf(m, "KernelStack: %8lu kB\n", - global_page_state(NR_KERNEL_STACK_KB)); + global_zone_page_state(NR_KERNEL_STACK_KB)); show_val_kb(m, "PageTables: ", - global_page_state(NR_PAGETABLE)); + global_zone_page_state(NR_PAGETABLE)); #ifdef CONFIG_QUICKLIST show_val_kb(m, "Quicklists: ", quicklist_total_size()); #endif @@ -124,7 +124,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) show_val_kb(m, "NFS_Unstable: ", global_node_page_state(NR_UNSTABLE_NFS)); show_val_kb(m, "Bounce: ", - global_page_state(NR_BOUNCE)); + global_zone_page_state(NR_BOUNCE)); show_val_kb(m, "WritebackTmp: ", global_node_page_state(NR_WRITEBACK_TEMP)); show_val_kb(m, "CommitLimit: ", vm_commit_limit()); @@ -151,7 +151,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) #ifdef CONFIG_CMA show_val_kb(m, "CmaTotal: ", totalcma_pages); show_val_kb(m, "CmaFree: ", - global_page_state(NR_FREE_CMA_PAGES)); + global_zone_page_state(NR_FREE_CMA_PAGES)); #endif hugetlb_report_meminfo(m); diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index d72fc40241d9c6897df7656a95402d0a39511bfd..a2bf369c923dcf1c3b788fcd16320bbc425fc1fd 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -196,7 +196,7 @@ static __net_init int proc_net_ns_init(struct net *net) if (!netd) goto out; - netd->subdir = RB_ROOT; + netd->subdir = RB_ROOT_CACHED; netd->data = net; netd->nlink = 2; netd->namelen = 3; diff --git a/fs/proc/root.c b/fs/proc/root.c index deecb397daa30d769f6750f11dcc7cbbfec805fb..926fb27f4ca26cb27c17c2a3d9eed9b9e32fc639 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -210,7 +210,7 @@ struct proc_dir_entry proc_root = { .proc_iops = &proc_root_inode_operations, .proc_fops = &proc_root_operations, .parent = &proc_root, - .subdir = RB_ROOT, + .subdir = RB_ROOT_CACHED, .name = "/proc", }; diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index b836fd61ed878a38d25d5ffe44bb86e30066955c..5589b4bd4b858fa5369728f0a0a2b90b4a3052ae 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -16,9 +16,10 @@ #include #include #include +#include #include -#include +#include #include #include "internal.h" @@ -252,6 +253,7 @@ static int proc_map_release(struct inode *inode, struct file *file) if (priv->mm) mmdrop(priv->mm); + kfree(priv->rollup); return seq_release_private(inode, file); } @@ -266,8 +268,7 @@ static int do_maps_open(struct inode *inode, struct file *file, * Indicate if the VMA is a stack for the given task; for * /proc/PID/maps that is the stack of the main task. */ -static int is_stack(struct proc_maps_private *priv, - struct vm_area_struct *vma) +static int is_stack(struct vm_area_struct *vma) { /* * We make no effort to guess what a given thread considers to be @@ -278,12 +279,28 @@ static int is_stack(struct proc_maps_private *priv, vma->vm_end >= vma->vm_mm->start_stack; } +static void show_vma_header_prefix(struct seq_file *m, + unsigned long start, unsigned long end, + vm_flags_t flags, unsigned long long pgoff, + dev_t dev, unsigned long ino) +{ + seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); + seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ", + start, + end, + flags & VM_READ ? 'r' : '-', + flags & VM_WRITE ? 'w' : '-', + flags & VM_EXEC ? 'x' : '-', + flags & VM_MAYSHARE ? 's' : 'p', + pgoff, + MAJOR(dev), MINOR(dev), ino); +} + static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) { struct mm_struct *mm = vma->vm_mm; struct file *file = vma->vm_file; - struct proc_maps_private *priv = m->private; vm_flags_t flags = vma->vm_flags; unsigned long ino = 0; unsigned long long pgoff = 0; @@ -300,17 +317,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) start = vma->vm_start; end = vma->vm_end; - - seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); - seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ", - start, - end, - flags & VM_READ ? 'r' : '-', - flags & VM_WRITE ? 'w' : '-', - flags & VM_EXEC ? 'x' : '-', - flags & VM_MAYSHARE ? 's' : 'p', - pgoff, - MAJOR(dev), MINOR(dev), ino); + show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino); /* * Print the dentry name for named mappings, and a @@ -341,7 +348,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) goto done; } - if (is_stack(priv, vma)) + if (is_stack(vma)) name = "[stack]"; } @@ -429,6 +436,7 @@ const struct file_operations proc_tid_maps_operations = { #ifdef CONFIG_PROC_PAGE_MONITOR struct mem_size_stats { + bool first; unsigned long resident; unsigned long shared_clean; unsigned long shared_dirty; @@ -442,7 +450,9 @@ struct mem_size_stats { unsigned long swap; unsigned long shared_hugetlb; unsigned long private_hugetlb; + unsigned long first_vma_start; u64 pss; + u64 pss_locked; u64 swap_pss; bool check_shmem_swap; }; @@ -537,6 +547,8 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, } } else if (is_migration_entry(swpent)) page = migration_entry_to_page(swpent); + else if (is_device_private_entry(swpent)) + page = device_private_entry_to_page(swpent); } else if (unlikely(IS_ENABLED(CONFIG_SHMEM) && mss->check_shmem_swap && pte_none(*pte))) { page = find_get_entry(vma->vm_file->f_mapping, @@ -596,13 +608,14 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, ptl = pmd_trans_huge_lock(pmd, vma); if (ptl) { - smaps_pmd_entry(pmd, addr, walk); + if (pmd_present(*pmd)) + smaps_pmd_entry(pmd, addr, walk); spin_unlock(ptl); - return 0; + goto out; } if (pmd_trans_unstable(pmd)) - return 0; + goto out; /* * The mmap_sem held all the way back in m_start() is what * keeps khugepaged out of here and from collapsing things @@ -612,6 +625,7 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, for (; addr != end; pte++, addr += PAGE_SIZE) smaps_pte_entry(pte, addr, walk); pte_unmap_unlock(pte - 1, ptl); +out: cond_resched(); return 0; } @@ -651,6 +665,7 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) [ilog2(VM_NORESERVE)] = "nr", [ilog2(VM_HUGETLB)] = "ht", [ilog2(VM_ARCH_1)] = "ar", + [ilog2(VM_WIPEONFORK)] = "wf", [ilog2(VM_DONTDUMP)] = "dd", #ifdef CONFIG_MEM_SOFT_DIRTY [ilog2(VM_SOFTDIRTY)] = "sd", @@ -699,6 +714,8 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask, if (is_migration_entry(swpent)) page = migration_entry_to_page(swpent); + else if (is_device_private_entry(swpent)) + page = device_private_entry_to_page(swpent); } if (page) { int mapcount = page_mapcount(page); @@ -718,18 +735,36 @@ void __weak arch_show_smap(struct seq_file *m, struct vm_area_struct *vma) static int show_smap(struct seq_file *m, void *v, int is_pid) { + struct proc_maps_private *priv = m->private; struct vm_area_struct *vma = v; - struct mem_size_stats mss; + struct mem_size_stats mss_stack; + struct mem_size_stats *mss; struct mm_walk smaps_walk = { .pmd_entry = smaps_pte_range, #ifdef CONFIG_HUGETLB_PAGE .hugetlb_entry = smaps_hugetlb_range, #endif .mm = vma->vm_mm, - .private = &mss, }; + int ret = 0; + bool rollup_mode; + bool last_vma; + + if (priv->rollup) { + rollup_mode = true; + mss = priv->rollup; + if (mss->first) { + mss->first_vma_start = vma->vm_start; + mss->first = false; + } + last_vma = !m_next_vma(priv, vma); + } else { + rollup_mode = false; + memset(&mss_stack, 0, sizeof(mss_stack)); + mss = &mss_stack; + } - memset(&mss, 0, sizeof mss); + smaps_walk.private = mss; #ifdef CONFIG_SHMEM if (vma->vm_file && shmem_mapping(vma->vm_file->f_mapping)) { @@ -747,9 +782,9 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) if (!shmem_swapped || (vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_WRITE)) { - mss.swap = shmem_swapped; + mss->swap = shmem_swapped; } else { - mss.check_shmem_swap = true; + mss->check_shmem_swap = true; smaps_walk.pte_hole = smaps_pte_hole; } } @@ -757,54 +792,71 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) /* mmap_sem is held in m_start */ walk_page_vma(vma, &smaps_walk); + if (vma->vm_flags & VM_LOCKED) + mss->pss_locked += mss->pss; + + if (!rollup_mode) { + show_map_vma(m, vma, is_pid); + } else if (last_vma) { + show_vma_header_prefix( + m, mss->first_vma_start, vma->vm_end, 0, 0, 0, 0); + seq_pad(m, ' '); + seq_puts(m, "[rollup]\n"); + } else { + ret = SEQ_SKIP; + } - show_map_vma(m, vma, is_pid); - - seq_printf(m, - "Size: %8lu kB\n" - "Rss: %8lu kB\n" - "Pss: %8lu kB\n" - "Shared_Clean: %8lu kB\n" - "Shared_Dirty: %8lu kB\n" - "Private_Clean: %8lu kB\n" - "Private_Dirty: %8lu kB\n" - "Referenced: %8lu kB\n" - "Anonymous: %8lu kB\n" - "LazyFree: %8lu kB\n" - "AnonHugePages: %8lu kB\n" - "ShmemPmdMapped: %8lu kB\n" - "Shared_Hugetlb: %8lu kB\n" - "Private_Hugetlb: %7lu kB\n" - "Swap: %8lu kB\n" - "SwapPss: %8lu kB\n" - "KernelPageSize: %8lu kB\n" - "MMUPageSize: %8lu kB\n" - "Locked: %8lu kB\n", - (vma->vm_end - vma->vm_start) >> 10, - mss.resident >> 10, - (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), - mss.shared_clean >> 10, - mss.shared_dirty >> 10, - mss.private_clean >> 10, - mss.private_dirty >> 10, - mss.referenced >> 10, - mss.anonymous >> 10, - mss.lazyfree >> 10, - mss.anonymous_thp >> 10, - mss.shmem_thp >> 10, - mss.shared_hugetlb >> 10, - mss.private_hugetlb >> 10, - mss.swap >> 10, - (unsigned long)(mss.swap_pss >> (10 + PSS_SHIFT)), - vma_kernel_pagesize(vma) >> 10, - vma_mmu_pagesize(vma) >> 10, - (vma->vm_flags & VM_LOCKED) ? - (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0); - - arch_show_smap(m, vma); - show_smap_vma_flags(m, vma); + if (!rollup_mode) + seq_printf(m, + "Size: %8lu kB\n" + "KernelPageSize: %8lu kB\n" + "MMUPageSize: %8lu kB\n", + (vma->vm_end - vma->vm_start) >> 10, + vma_kernel_pagesize(vma) >> 10, + vma_mmu_pagesize(vma) >> 10); + + + if (!rollup_mode || last_vma) + seq_printf(m, + "Rss: %8lu kB\n" + "Pss: %8lu kB\n" + "Shared_Clean: %8lu kB\n" + "Shared_Dirty: %8lu kB\n" + "Private_Clean: %8lu kB\n" + "Private_Dirty: %8lu kB\n" + "Referenced: %8lu kB\n" + "Anonymous: %8lu kB\n" + "LazyFree: %8lu kB\n" + "AnonHugePages: %8lu kB\n" + "ShmemPmdMapped: %8lu kB\n" + "Shared_Hugetlb: %8lu kB\n" + "Private_Hugetlb: %7lu kB\n" + "Swap: %8lu kB\n" + "SwapPss: %8lu kB\n" + "Locked: %8lu kB\n", + mss->resident >> 10, + (unsigned long)(mss->pss >> (10 + PSS_SHIFT)), + mss->shared_clean >> 10, + mss->shared_dirty >> 10, + mss->private_clean >> 10, + mss->private_dirty >> 10, + mss->referenced >> 10, + mss->anonymous >> 10, + mss->lazyfree >> 10, + mss->anonymous_thp >> 10, + mss->shmem_thp >> 10, + mss->shared_hugetlb >> 10, + mss->private_hugetlb >> 10, + mss->swap >> 10, + (unsigned long)(mss->swap_pss >> (10 + PSS_SHIFT)), + (unsigned long)(mss->pss >> (10 + PSS_SHIFT))); + + if (!rollup_mode) { + arch_show_smap(m, vma); + show_smap_vma_flags(m, vma); + } m_cache_vma(m, vma); - return 0; + return ret; } static int show_pid_smap(struct seq_file *m, void *v) @@ -836,6 +888,25 @@ static int pid_smaps_open(struct inode *inode, struct file *file) return do_maps_open(inode, file, &proc_pid_smaps_op); } +static int pid_smaps_rollup_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + struct proc_maps_private *priv; + int ret = do_maps_open(inode, file, &proc_pid_smaps_op); + + if (ret < 0) + return ret; + seq = file->private_data; + priv = seq->private; + priv->rollup = kzalloc(sizeof(*priv->rollup), GFP_KERNEL); + if (!priv->rollup) { + proc_map_release(inode, file); + return -ENOMEM; + } + priv->rollup->first = true; + return 0; +} + static int tid_smaps_open(struct inode *inode, struct file *file) { return do_maps_open(inode, file, &proc_tid_smaps_op); @@ -848,6 +919,13 @@ const struct file_operations proc_pid_smaps_operations = { .release = proc_map_release, }; +const struct file_operations proc_pid_smaps_rollup_operations = { + .open = pid_smaps_rollup_open, + .read = seq_read, + .llseek = seq_lseek, + .release = proc_map_release, +}; + const struct file_operations proc_tid_smaps_operations = { .open = tid_smaps_open, .read = seq_read, @@ -903,17 +981,22 @@ static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, { pmd_t pmd = *pmdp; - /* See comment in change_huge_pmd() */ - pmdp_invalidate(vma, addr, pmdp); - if (pmd_dirty(*pmdp)) - pmd = pmd_mkdirty(pmd); - if (pmd_young(*pmdp)) - pmd = pmd_mkyoung(pmd); - - pmd = pmd_wrprotect(pmd); - pmd = pmd_clear_soft_dirty(pmd); - - set_pmd_at(vma->vm_mm, addr, pmdp, pmd); + if (pmd_present(pmd)) { + /* See comment in change_huge_pmd() */ + pmdp_invalidate(vma, addr, pmdp); + if (pmd_dirty(*pmdp)) + pmd = pmd_mkdirty(pmd); + if (pmd_young(*pmdp)) + pmd = pmd_mkyoung(pmd); + + pmd = pmd_wrprotect(pmd); + pmd = pmd_clear_soft_dirty(pmd); + + set_pmd_at(vma->vm_mm, addr, pmdp, pmd); + } else if (is_migration_entry(pmd_to_swp_entry(pmd))) { + pmd = pmd_swp_clear_soft_dirty(pmd); + set_pmd_at(vma->vm_mm, addr, pmdp, pmd); + } } #else static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, @@ -938,6 +1021,9 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, goto out; } + if (!pmd_present(*pmd)) + goto out; + page = pmd_page(*pmd); /* Clear accessed and referenced bits. */ @@ -1008,6 +1094,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, struct mm_struct *mm; struct vm_area_struct *vma; enum clear_refs_types type; + struct mmu_gather tlb; int itype; int rv; @@ -1054,6 +1141,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, } down_read(&mm->mmap_sem); + tlb_gather_mmu(&tlb, mm, 0, -1); if (type == CLEAR_REFS_SOFT_DIRTY) { for (vma = mm->mmap; vma; vma = vma->vm_next) { if (!(vma->vm_flags & VM_SOFTDIRTY)) @@ -1075,7 +1163,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, walk_page_range(0, mm->highest_vm_end, &clear_refs_walk); if (type == CLEAR_REFS_SOFT_DIRTY) mmu_notifier_invalidate_range_end(mm, 0, -1); - flush_tlb_mm(mm); + tlb_finish_mmu(&tlb, 0, -1); up_read(&mm->mmap_sem); out_mm: mmput(mm); @@ -1178,7 +1266,7 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, if (pm->show_pfn) frame = pte_pfn(pte); flags |= PM_PRESENT; - page = vm_normal_page(vma, addr, pte); + page = _vm_normal_page(vma, addr, pte, true); if (pte_soft_dirty(pte)) flags |= PM_SOFT_DIRTY; } else if (is_swap_pte(pte)) { @@ -1191,6 +1279,9 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, flags |= PM_SWAP; if (is_migration_entry(entry)) page = migration_entry_to_page(entry); + + if (is_device_private_entry(entry)) + page = device_private_entry_to_page(entry); } if (page && !PageAnon(page)) @@ -1217,27 +1308,33 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, if (ptl) { u64 flags = 0, frame = 0; pmd_t pmd = *pmdp; + struct page *page = NULL; if ((vma->vm_flags & VM_SOFTDIRTY) || pmd_soft_dirty(pmd)) flags |= PM_SOFT_DIRTY; - /* - * Currently pmd for thp is always present because thp - * can not be swapped-out, migrated, or HWPOISONed - * (split in such cases instead.) - * This if-check is just to prepare for future implementation. - */ if (pmd_present(pmd)) { - struct page *page = pmd_page(pmd); - - if (page_mapcount(page) == 1) - flags |= PM_MMAP_EXCLUSIVE; + page = pmd_page(pmd); flags |= PM_PRESENT; if (pm->show_pfn) frame = pmd_pfn(pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT); } +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + else if (is_swap_pmd(pmd)) { + swp_entry_t entry = pmd_to_swp_entry(pmd); + + frame = swp_type(entry) | + (swp_offset(entry) << MAX_SWAPFILES_SHIFT); + flags |= PM_SWAP; + VM_BUG_ON(!is_pmd_migration_entry(pmd)); + page = migration_entry_to_page(entry); + } +#endif + + if (page && page_mapcount(page) == 1) + flags |= PM_MMAP_EXCLUSIVE; for (; addr != end; addr += PAGE_SIZE) { pagemap_entry_t pme = make_pme(frame, flags); @@ -1377,7 +1474,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, pm.show_pfn = file_ns_capable(file, &init_user_ns, CAP_SYS_ADMIN); pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); - pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY); + pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_KERNEL); ret = -ENOMEM; if (!pm.buffer) goto out_mm; @@ -1670,7 +1767,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) seq_file_path(m, file, "\n\t= "); } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { seq_puts(m, " heap"); - } else if (is_stack(proc_priv, vma)) { + } else if (is_stack(vma)) { seq_puts(m, " stack"); } diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 23266694db117155f6e23284fecbf69800cecb09..b00b766098fa388d56d19502b11b358da19a0865 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -125,8 +125,7 @@ unsigned long task_statm(struct mm_struct *mm, return size; } -static int is_stack(struct proc_maps_private *priv, - struct vm_area_struct *vma) +static int is_stack(struct vm_area_struct *vma) { struct mm_struct *mm = vma->vm_mm; @@ -146,7 +145,6 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, int is_pid) { struct mm_struct *mm = vma->vm_mm; - struct proc_maps_private *priv = m->private; unsigned long ino = 0; struct file *file; dev_t dev = 0; @@ -178,7 +176,7 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, if (file) { seq_pad(m, ' '); seq_file_path(m, file, ""); - } else if (mm && is_stack(priv, vma)) { + } else if (mm && is_stack(vma)) { seq_pad(m, ' '); seq_printf(m, "[stack]"); } diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index b5713fefb4c1b518d931cb26ffd6c917ad269f57..99dff222fe67a1173d753b63f8badec4c71b55d1 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c @@ -178,7 +178,7 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) } else { mangle(m, r->mnt_devname ? r->mnt_devname : "none"); } - seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); + seq_puts(m, sb_rdonly(sb) ? " ro" : " rw"); err = show_sb_opts(m, sb); if (err) goto out; diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index fefd22611cf60b1c25b7842b63da5957876a444f..d814723fb27dcdfc80168bf97a5c10ab20fcc0c2 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "internal.h" @@ -132,18 +131,6 @@ static const struct seq_operations pstore_ftrace_seq_ops = { .show = pstore_ftrace_seq_show, }; -static int pstore_check_syslog_permissions(struct pstore_private *ps) -{ - switch (ps->record->type) { - case PSTORE_TYPE_DMESG: - case PSTORE_TYPE_CONSOLE: - return check_syslog_permissions(SYSLOG_ACTION_READ_ALL, - SYSLOG_FROM_READER); - default: - return 0; - } -} - static ssize_t pstore_file_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -163,10 +150,6 @@ static int pstore_file_open(struct inode *inode, struct file *file) int err; const struct seq_operations *sops = NULL; - err = pstore_check_syslog_permissions(ps); - if (err) - return err; - if (ps->record->type == PSTORE_TYPE_FTRACE) sops = &pstore_ftrace_seq_ops; @@ -204,11 +187,6 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) { struct pstore_private *p = d_inode(dentry)->i_private; struct pstore_record *record = p->record; - int err; - - err = pstore_check_syslog_permissions(p); - if (err) - return err; if (!record->psi->erase) return -EPERM; @@ -471,7 +449,7 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent) inode = pstore_get_inode(sb); if (inode) { - inode->i_mode = S_IFDIR | 0755; + inode->i_mode = S_IFDIR | 0750; inode->i_op = &pstore_dir_inode_operations; inode->i_fop = &simple_dir_operations; inc_nlink(inode); diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 53a17496c5c536a9410cba73c16d70c5efdbba88..50b0556a124f2508531ce9e6fc61721aeb179cc8 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -82,16 +82,19 @@ #include /* - * There are three quota SMP locks. dq_list_lock protects all lists with quotas - * and quota formats. - * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and - * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. - * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly - * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects - * modifications of quota state (on quotaon and quotaoff) and readers who care - * about latest values take it as well. + * There are five quota SMP locks: + * * dq_list_lock protects all lists with quotas and quota formats. + * * dquot->dq_dqb_lock protects data from dq_dqb + * * inode->i_lock protects inode->i_blocks, i_bytes and also guards + * consistency of dquot->dq_dqb with inode->i_blocks, i_bytes so that + * dquot_transfer() can stabilize amount it transfers + * * dq_data_lock protects mem_dqinfo structures and modifications of dquot + * pointers in the inode + * * dq_state_lock protects modifications of quota state (on quotaon and + * quotaoff) and readers who care about latest values take it as well. * - * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, + * The spinlock ordering is hence: + * dq_data_lock > dq_list_lock > i_lock > dquot->dq_dqb_lock, * dq_list_lock > dq_state_lock * * Note that some things (eg. sb pointer, type, id) doesn't change during @@ -110,17 +113,14 @@ * sure they cannot race with quotaon which first sets S_NOQUOTA flag and * then drops all pointers to dquots from an inode. * - * Each dquot has its dq_lock mutex. Locked dquots might not be referenced - * from inodes (dquot_alloc_space() and such don't check the dq_lock). - * Currently dquot is locked only when it is being read to memory (or space for - * it is being allocated) on the first dqget() and when it is being released on - * the last dqput(). The allocation and release oparations are serialized by - * the dq_lock and by checking the use count in dquot_release(). Write - * operations on dquots don't hold dq_lock as they copy data under dq_data_lock - * spinlock to internal buffers before writing. + * Each dquot has its dq_lock mutex. Dquot is locked when it is being read to + * memory (or space for it is being allocated) on the first dqget(), when it is + * being written out, and when it is being released on the last dqput(). The + * allocation and release operations are serialized by the dq_lock and by + * checking the use count in dquot_release(). * * Lock ordering (including related VFS locks) is the following: - * s_umount > i_mutex > journal_lock > dquot->dq_lock > dqio_mutex + * s_umount > i_mutex > journal_lock > dquot->dq_lock > dqio_sem */ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); @@ -129,6 +129,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); EXPORT_SYMBOL(dq_data_lock); DEFINE_STATIC_SRCU(dquot_srcu); +static DECLARE_WAIT_QUEUE_HEAD(dquot_ref_wq); + void __quota_error(struct super_block *sb, const char *func, const char *fmt, ...) { @@ -247,6 +249,7 @@ struct dqstats dqstats; EXPORT_SYMBOL(dqstats); static qsize_t inode_get_rsv_space(struct inode *inode); +static qsize_t __inode_get_rsv_space(struct inode *inode); static int __dquot_initialize(struct inode *inode, int type); static inline unsigned int @@ -342,6 +345,12 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) { int ret = 1; + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + return 0; + + if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY) + return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags); + /* If quota is dirty already, we don't have to acquire dq_list_lock */ if (test_bit(DQ_MOD_B, &dquot->dq_flags)) return 1; @@ -381,18 +390,26 @@ static inline void dqput_all(struct dquot **dquot) dqput(dquot[cnt]); } -/* This function needs dq_list_lock */ static inline int clear_dquot_dirty(struct dquot *dquot) { - if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags)) + if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY) + return test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags); + + spin_lock(&dq_list_lock); + if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags)) { + spin_unlock(&dq_list_lock); return 0; + } list_del_init(&dquot->dq_dirty); + spin_unlock(&dq_list_lock); return 1; } void mark_info_dirty(struct super_block *sb, int type) { - set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags); + spin_lock(&dq_data_lock); + sb_dqopt(sb)->info[type].dqi_flags |= DQF_INFO_DIRTY; + spin_unlock(&dq_data_lock); } EXPORT_SYMBOL(mark_info_dirty); @@ -406,7 +423,6 @@ int dquot_acquire(struct dquot *dquot) struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); mutex_lock(&dquot->dq_lock); - mutex_lock(&dqopt->dqio_mutex); if (!test_bit(DQ_READ_B, &dquot->dq_flags)) ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot); if (ret < 0) @@ -436,7 +452,6 @@ int dquot_acquire(struct dquot *dquot) smp_mb__before_atomic(); set_bit(DQ_ACTIVE_B, &dquot->dq_flags); out_iolock: - mutex_unlock(&dqopt->dqio_mutex); mutex_unlock(&dquot->dq_lock); return ret; } @@ -450,21 +465,17 @@ int dquot_commit(struct dquot *dquot) int ret = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); - mutex_lock(&dqopt->dqio_mutex); - spin_lock(&dq_list_lock); - if (!clear_dquot_dirty(dquot)) { - spin_unlock(&dq_list_lock); - goto out_sem; - } - spin_unlock(&dq_list_lock); + mutex_lock(&dquot->dq_lock); + if (!clear_dquot_dirty(dquot)) + goto out_lock; /* Inactive dquot can be only if there was error during read/init * => we have better not writing it */ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); else ret = -EIO; -out_sem: - mutex_unlock(&dqopt->dqio_mutex); +out_lock: + mutex_unlock(&dquot->dq_lock); return ret; } EXPORT_SYMBOL(dquot_commit); @@ -481,7 +492,6 @@ int dquot_release(struct dquot *dquot) /* Check whether we are not racing with some other dqget() */ if (atomic_read(&dquot->dq_count) > 1) goto out_dqlock; - mutex_lock(&dqopt->dqio_mutex); if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); /* Write the info */ @@ -493,7 +503,6 @@ int dquot_release(struct dquot *dquot) ret = ret2; } clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); - mutex_unlock(&dqopt->dqio_mutex); out_dqlock: mutex_unlock(&dquot->dq_lock); return ret; @@ -530,22 +539,18 @@ static void invalidate_dquots(struct super_block *sb, int type) continue; /* Wait for dquot users */ if (atomic_read(&dquot->dq_count)) { - DEFINE_WAIT(wait); - dqgrab(dquot); - prepare_to_wait(&dquot->dq_wait_unused, &wait, - TASK_UNINTERRUPTIBLE); spin_unlock(&dq_list_lock); - /* Once dqput() wakes us up, we know it's time to free + /* + * Once dqput() wakes us up, we know it's time to free * the dquot. * IMPORTANT: we rely on the fact that there is always * at most one process waiting for dquot to free. * Otherwise dq_count would be > 1 and we would never * wake up. */ - if (atomic_read(&dquot->dq_count) > 1) - schedule(); - finish_wait(&dquot->dq_wait_unused, &wait); + wait_event(dquot_ref_wq, + atomic_read(&dquot->dq_count) == 1); dqput(dquot); /* At this moment dquot() need not exist (it could be * reclaimed by prune_dqcache(). Hence we must @@ -629,11 +634,9 @@ int dquot_writeback_dquots(struct super_block *sb, int type) while (!list_empty(dirty)) { dquot = list_first_entry(dirty, struct dquot, dq_dirty); - /* Dirty and inactive can be only bad dquot... */ - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { - clear_dquot_dirty(dquot); - continue; - } + + WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)); + /* Now we have active dquot from which someone is * holding reference so we can safely just increase * use count */ @@ -759,12 +762,12 @@ void dqput(struct dquot *dquot) /* Releasing dquot during quotaoff phase? */ if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) && atomic_read(&dquot->dq_count) == 1) - wake_up(&dquot->dq_wait_unused); + wake_up(&dquot_ref_wq); spin_unlock(&dq_list_lock); return; } /* Need to release dquot? */ - if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) { + if (dquot_dirty(dquot)) { spin_unlock(&dq_list_lock); /* Commit dquot before releasing */ ret = dquot->dq_sb->dq_op->write_dquot(dquot); @@ -776,14 +779,10 @@ void dqput(struct dquot *dquot) * We clear dirty bit anyway, so that we avoid * infinite loop here */ - spin_lock(&dq_list_lock); clear_dquot_dirty(dquot); - spin_unlock(&dq_list_lock); } goto we_slept; } - /* Clear flag in case dquot was inactive (something bad happened) */ - clear_dquot_dirty(dquot); if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { spin_unlock(&dq_list_lock); dquot->dq_sb->dq_op->release_dquot(dquot); @@ -818,10 +817,10 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) INIT_LIST_HEAD(&dquot->dq_inuse); INIT_HLIST_NODE(&dquot->dq_hash); INIT_LIST_HEAD(&dquot->dq_dirty); - init_waitqueue_head(&dquot->dq_wait_unused); dquot->dq_sb = sb; dquot->dq_id = make_kqid_invalid(type); atomic_set(&dquot->dq_count, 1); + spin_lock_init(&dquot->dq_dqb_lock); return dquot; } @@ -1079,42 +1078,6 @@ static void drop_dquot_ref(struct super_block *sb, int type) } } -static inline void dquot_incr_inodes(struct dquot *dquot, qsize_t number) -{ - dquot->dq_dqb.dqb_curinodes += number; -} - -static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) -{ - dquot->dq_dqb.dqb_curspace += number; -} - -static inline void dquot_resv_space(struct dquot *dquot, qsize_t number) -{ - dquot->dq_dqb.dqb_rsvspace += number; -} - -/* - * Claim reserved quota space - */ -static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number) -{ - if (dquot->dq_dqb.dqb_rsvspace < number) { - WARN_ON_ONCE(1); - number = dquot->dq_dqb.dqb_rsvspace; - } - dquot->dq_dqb.dqb_curspace += number; - dquot->dq_dqb.dqb_rsvspace -= number; -} - -static void dquot_reclaim_reserved_space(struct dquot *dquot, qsize_t number) -{ - if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number)) - number = dquot->dq_dqb.dqb_curspace; - dquot->dq_dqb.dqb_rsvspace += number; - dquot->dq_dqb.dqb_curspace -= number; -} - static inline void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) { @@ -1124,6 +1087,10 @@ void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) WARN_ON_ONCE(1); dquot->dq_dqb.dqb_rsvspace = 0; } + if (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace <= + dquot->dq_dqb.dqb_bsoftlimit) + dquot->dq_dqb.dqb_btime = (time64_t) 0; + clear_bit(DQ_BLKS_B, &dquot->dq_flags); } static void dquot_decr_inodes(struct dquot *dquot, qsize_t number) @@ -1145,7 +1112,8 @@ static void dquot_decr_space(struct dquot *dquot, qsize_t number) dquot->dq_dqb.dqb_curspace -= number; else dquot->dq_dqb.dqb_curspace = 0; - if (dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit) + if (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace <= + dquot->dq_dqb.dqb_bsoftlimit) dquot->dq_dqb.dqb_btime = (time64_t) 0; clear_bit(DQ_BLKS_B, &dquot->dq_flags); } @@ -1273,21 +1241,24 @@ static int ignore_hardlimit(struct dquot *dquot) !(info->dqi_flags & DQF_ROOT_SQUASH)); } -/* needs dq_data_lock */ -static int check_idq(struct dquot *dquot, qsize_t inodes, - struct dquot_warn *warn) +static int dquot_add_inodes(struct dquot *dquot, qsize_t inodes, + struct dquot_warn *warn) { - qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; + qsize_t newinodes; + int ret = 0; + spin_lock(&dquot->dq_dqb_lock); + newinodes = dquot->dq_dqb.dqb_curinodes + inodes; if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) || test_bit(DQ_FAKE_B, &dquot->dq_flags)) - return 0; + goto add; if (dquot->dq_dqb.dqb_ihardlimit && newinodes > dquot->dq_dqb.dqb_ihardlimit && !ignore_hardlimit(dquot)) { prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN); - return -EDQUOT; + ret = -EDQUOT; + goto out; } if (dquot->dq_dqb.dqb_isoftlimit && @@ -1296,7 +1267,8 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, ktime_get_real_seconds() >= dquot->dq_dqb.dqb_itime && !ignore_hardlimit(dquot)) { prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN); - return -EDQUOT; + ret = -EDQUOT; + goto out; } if (dquot->dq_dqb.dqb_isoftlimit && @@ -1306,30 +1278,40 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, dquot->dq_dqb.dqb_itime = ktime_get_real_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace; } +add: + dquot->dq_dqb.dqb_curinodes = newinodes; - return 0; +out: + spin_unlock(&dquot->dq_dqb_lock); + return ret; } -/* needs dq_data_lock */ -static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, - struct dquot_warn *warn) +static int dquot_add_space(struct dquot *dquot, qsize_t space, + qsize_t rsv_space, unsigned int flags, + struct dquot_warn *warn) { qsize_t tspace; struct super_block *sb = dquot->dq_sb; + int ret = 0; + spin_lock(&dquot->dq_dqb_lock); if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) || test_bit(DQ_FAKE_B, &dquot->dq_flags)) - return 0; + goto add; tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace - + space; + + space + rsv_space; + + if (flags & DQUOT_SPACE_NOFAIL) + goto add; if (dquot->dq_dqb.dqb_bhardlimit && tspace > dquot->dq_dqb.dqb_bhardlimit && !ignore_hardlimit(dquot)) { - if (!prealloc) + if (flags & DQUOT_SPACE_WARN) prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN); - return -EDQUOT; + ret = -EDQUOT; + goto out; } if (dquot->dq_dqb.dqb_bsoftlimit && @@ -1337,28 +1319,34 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, dquot->dq_dqb.dqb_btime && ktime_get_real_seconds() >= dquot->dq_dqb.dqb_btime && !ignore_hardlimit(dquot)) { - if (!prealloc) + if (flags & DQUOT_SPACE_WARN) prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN); - return -EDQUOT; + ret = -EDQUOT; + goto out; } if (dquot->dq_dqb.dqb_bsoftlimit && tspace > dquot->dq_dqb.dqb_bsoftlimit && dquot->dq_dqb.dqb_btime == 0) { - if (!prealloc) { + if (flags & DQUOT_SPACE_WARN) { prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); dquot->dq_dqb.dqb_btime = ktime_get_real_seconds() + sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace; - } - else + } else { /* * We don't allow preallocation to exceed softlimit so exceeding will * be always printed */ - return -EDQUOT; + ret = -EDQUOT; + goto out; + } } - - return 0; +add: + dquot->dq_dqb.dqb_rsvspace += rsv_space; + dquot->dq_dqb.dqb_curspace += space; +out: + spin_unlock(&dquot->dq_dqb_lock); + return ret; } static int info_idq_free(struct dquot *dquot, qsize_t inodes) @@ -1381,14 +1369,18 @@ static int info_idq_free(struct dquot *dquot, qsize_t inodes) static int info_bdq_free(struct dquot *dquot, qsize_t space) { + qsize_t tspace; + + tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace; + if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || - dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit) + tspace <= dquot->dq_dqb.dqb_bsoftlimit) return QUOTA_NL_NOWARN; - if (dquot->dq_dqb.dqb_curspace - space <= dquot->dq_dqb.dqb_bsoftlimit) + if (tspace - space <= dquot->dq_dqb.dqb_bsoftlimit) return QUOTA_NL_BSOFTBELOW; - if (dquot->dq_dqb.dqb_curspace >= dquot->dq_dqb.dqb_bhardlimit && - dquot->dq_dqb.dqb_curspace - space < dquot->dq_dqb.dqb_bhardlimit) + if (tspace >= dquot->dq_dqb.dqb_bhardlimit && + tspace - space < dquot->dq_dqb.dqb_bhardlimit) return QUOTA_NL_BHARDBELOW; return QUOTA_NL_NOWARN; } @@ -1493,8 +1485,15 @@ static int __dquot_initialize(struct inode *inode, int type) * did a write before quota was turned on */ rsv = inode_get_rsv_space(inode); - if (unlikely(rsv)) - dquot_resv_space(dquots[cnt], rsv); + if (unlikely(rsv)) { + spin_lock(&inode->i_lock); + /* Get reservation again under proper lock */ + rsv = __inode_get_rsv_space(inode); + spin_lock(&dquots[cnt]->dq_dqb_lock); + dquots[cnt]->dq_dqb.dqb_rsvspace += rsv; + spin_unlock(&dquots[cnt]->dq_dqb_lock); + spin_unlock(&inode->i_lock); + } } } out_lock: @@ -1589,39 +1588,12 @@ static qsize_t *inode_reserved_space(struct inode * inode) return inode->i_sb->dq_op->get_reserved_space(inode); } -void inode_add_rsv_space(struct inode *inode, qsize_t number) -{ - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) += number; - spin_unlock(&inode->i_lock); -} -EXPORT_SYMBOL(inode_add_rsv_space); - -void inode_claim_rsv_space(struct inode *inode, qsize_t number) +static qsize_t __inode_get_rsv_space(struct inode *inode) { - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; - __inode_add_bytes(inode, number); - spin_unlock(&inode->i_lock); -} -EXPORT_SYMBOL(inode_claim_rsv_space); - -void inode_reclaim_rsv_space(struct inode *inode, qsize_t number) -{ - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) += number; - __inode_sub_bytes(inode, number); - spin_unlock(&inode->i_lock); -} -EXPORT_SYMBOL(inode_reclaim_rsv_space); - -void inode_sub_rsv_space(struct inode *inode, qsize_t number) -{ - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; - spin_unlock(&inode->i_lock); + if (!inode->i_sb->dq_op->get_reserved_space) + return 0; + return *inode_reserved_space(inode); } -EXPORT_SYMBOL(inode_sub_rsv_space); static qsize_t inode_get_rsv_space(struct inode *inode) { @@ -1630,28 +1602,11 @@ static qsize_t inode_get_rsv_space(struct inode *inode) if (!inode->i_sb->dq_op->get_reserved_space) return 0; spin_lock(&inode->i_lock); - ret = *inode_reserved_space(inode); + ret = __inode_get_rsv_space(inode); spin_unlock(&inode->i_lock); return ret; } -static void inode_incr_space(struct inode *inode, qsize_t number, - int reserve) -{ - if (reserve) - inode_add_rsv_space(inode, number); - else - inode_add_bytes(inode, number); -} - -static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) -{ - if (reserve) - inode_sub_rsv_space(inode, number); - else - inode_sub_bytes(inode, number); -} - /* * This functions updates i_blocks+i_bytes fields and quota information * (together with appropriate checks). @@ -1673,7 +1628,13 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) struct dquot **dquots; if (!dquot_active(inode)) { - inode_incr_space(inode, number, reserve); + if (reserve) { + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) += number; + spin_unlock(&inode->i_lock); + } else { + inode_add_bytes(inode, number); + } goto out; } @@ -1682,27 +1643,41 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); - spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (!dquots[cnt]) continue; - ret = check_bdq(dquots[cnt], number, - !(flags & DQUOT_SPACE_WARN), &warn[cnt]); - if (ret && !(flags & DQUOT_SPACE_NOFAIL)) { - spin_unlock(&dq_data_lock); + if (flags & DQUOT_SPACE_RESERVE) { + ret = dquot_add_space(dquots[cnt], 0, number, flags, + &warn[cnt]); + } else { + ret = dquot_add_space(dquots[cnt], number, 0, flags, + &warn[cnt]); + } + if (ret) { + /* Back out changes we already did */ + for (cnt--; cnt >= 0; cnt--) { + if (!dquots[cnt]) + continue; + spin_lock(&dquots[cnt]->dq_dqb_lock); + if (flags & DQUOT_SPACE_RESERVE) { + dquots[cnt]->dq_dqb.dqb_rsvspace -= + number; + } else { + dquots[cnt]->dq_dqb.dqb_curspace -= + number; + } + spin_unlock(&dquots[cnt]->dq_dqb_lock); + } + spin_unlock(&inode->i_lock); goto out_flush_warn; } } - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!dquots[cnt]) - continue; - if (reserve) - dquot_resv_space(dquots[cnt], number); - else - dquot_incr_space(dquots[cnt], number); - } - inode_incr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); + if (reserve) + *inode_reserved_space(inode) += number; + else + __inode_add_bytes(inode, number); + spin_unlock(&inode->i_lock); if (reserve) goto out_flush_warn; @@ -1731,23 +1706,26 @@ int dquot_alloc_inode(struct inode *inode) dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); - spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (!dquots[cnt]) continue; - ret = check_idq(dquots[cnt], 1, &warn[cnt]); - if (ret) + ret = dquot_add_inodes(dquots[cnt], 1, &warn[cnt]); + if (ret) { + for (cnt--; cnt >= 0; cnt--) { + if (!dquots[cnt]) + continue; + /* Back out changes we already did */ + spin_lock(&dquots[cnt]->dq_dqb_lock); + dquots[cnt]->dq_dqb.dqb_curinodes--; + spin_unlock(&dquots[cnt]->dq_dqb_lock); + } goto warn_put_all; - } - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!dquots[cnt]) - continue; - dquot_incr_inodes(dquots[cnt], 1); + } } warn_put_all: - spin_unlock(&dq_data_lock); + spin_unlock(&inode->i_lock); if (ret == 0) mark_all_dquot_dirty(dquots); srcu_read_unlock(&dquot_srcu, index); @@ -1765,21 +1743,33 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) int cnt, index; if (!dquot_active(inode)) { - inode_claim_rsv_space(inode, number); + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) -= number; + __inode_add_bytes(inode, number); + spin_unlock(&inode->i_lock); return 0; } dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); - spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); /* Claim reserved quotas to allocated quotas */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (dquots[cnt]) - dquot_claim_reserved_space(dquots[cnt], number); + if (dquots[cnt]) { + struct dquot *dquot = dquots[cnt]; + + spin_lock(&dquot->dq_dqb_lock); + if (WARN_ON_ONCE(dquot->dq_dqb.dqb_rsvspace < number)) + number = dquot->dq_dqb.dqb_rsvspace; + dquot->dq_dqb.dqb_curspace += number; + dquot->dq_dqb.dqb_rsvspace -= number; + spin_unlock(&dquot->dq_dqb_lock); + } } /* Update inode bytes */ - inode_claim_rsv_space(inode, number); - spin_unlock(&dq_data_lock); + *inode_reserved_space(inode) -= number; + __inode_add_bytes(inode, number); + spin_unlock(&inode->i_lock); mark_all_dquot_dirty(dquots); srcu_read_unlock(&dquot_srcu, index); return 0; @@ -1795,21 +1785,33 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) int cnt, index; if (!dquot_active(inode)) { - inode_reclaim_rsv_space(inode, number); + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) += number; + __inode_sub_bytes(inode, number); + spin_unlock(&inode->i_lock); return; } dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); - spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); /* Claim reserved quotas to allocated quotas */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (dquots[cnt]) - dquot_reclaim_reserved_space(dquots[cnt], number); + if (dquots[cnt]) { + struct dquot *dquot = dquots[cnt]; + + spin_lock(&dquot->dq_dqb_lock); + if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number)) + number = dquot->dq_dqb.dqb_curspace; + dquot->dq_dqb.dqb_rsvspace += number; + dquot->dq_dqb.dqb_curspace -= number; + spin_unlock(&dquot->dq_dqb_lock); + } } /* Update inode bytes */ - inode_reclaim_rsv_space(inode, number); - spin_unlock(&dq_data_lock); + *inode_reserved_space(inode) += number; + __inode_sub_bytes(inode, number); + spin_unlock(&inode->i_lock); mark_all_dquot_dirty(dquots); srcu_read_unlock(&dquot_srcu, index); return; @@ -1827,19 +1829,26 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) int reserve = flags & DQUOT_SPACE_RESERVE, index; if (!dquot_active(inode)) { - inode_decr_space(inode, number, reserve); + if (reserve) { + spin_lock(&inode->i_lock); + *inode_reserved_space(inode) -= number; + spin_unlock(&inode->i_lock); + } else { + inode_sub_bytes(inode, number); + } return; } dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); - spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { int wtype; warn[cnt].w_type = QUOTA_NL_NOWARN; if (!dquots[cnt]) continue; + spin_lock(&dquots[cnt]->dq_dqb_lock); wtype = info_bdq_free(dquots[cnt], number); if (wtype != QUOTA_NL_NOWARN) prepare_warning(&warn[cnt], dquots[cnt], wtype); @@ -1847,9 +1856,13 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) dquot_free_reserved_space(dquots[cnt], number); else dquot_decr_space(dquots[cnt], number); + spin_unlock(&dquots[cnt]->dq_dqb_lock); } - inode_decr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); + if (reserve) + *inode_reserved_space(inode) -= number; + else + __inode_sub_bytes(inode, number); + spin_unlock(&inode->i_lock); if (reserve) goto out_unlock; @@ -1875,19 +1888,21 @@ void dquot_free_inode(struct inode *inode) dquots = i_dquot(inode); index = srcu_read_lock(&dquot_srcu); - spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { int wtype; warn[cnt].w_type = QUOTA_NL_NOWARN; if (!dquots[cnt]) continue; + spin_lock(&dquots[cnt]->dq_dqb_lock); wtype = info_idq_free(dquots[cnt], 1); if (wtype != QUOTA_NL_NOWARN) prepare_warning(&warn[cnt], dquots[cnt], wtype); dquot_decr_inodes(dquots[cnt], 1); + spin_unlock(&dquots[cnt]->dq_dqb_lock); } - spin_unlock(&dq_data_lock); + spin_unlock(&inode->i_lock); mark_all_dquot_dirty(dquots); srcu_read_unlock(&dquot_srcu, index); flush_warnings(warn); @@ -1908,7 +1923,7 @@ EXPORT_SYMBOL(dquot_free_inode); */ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) { - qsize_t space, cur_space; + qsize_t cur_space; qsize_t rsv_space = 0; qsize_t inode_usage = 1; struct dquot *transfer_from[MAXQUOTAS] = {}; @@ -1935,14 +1950,18 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) } spin_lock(&dq_data_lock); + spin_lock(&inode->i_lock); if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ + spin_unlock(&inode->i_lock); spin_unlock(&dq_data_lock); return 0; } - cur_space = inode_get_bytes(inode); - rsv_space = inode_get_rsv_space(inode); - space = cur_space + rsv_space; - /* Build the transfer_from list and check the limits */ + cur_space = __inode_get_bytes(inode); + rsv_space = __inode_get_rsv_space(inode); + /* + * Build the transfer_from list, check limits, and update usage in + * the target structures. + */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { /* * Skip changes for same uid or gid or for turned off quota-type. @@ -1954,28 +1973,35 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) continue; is_valid[cnt] = 1; transfer_from[cnt] = i_dquot(inode)[cnt]; - ret = check_idq(transfer_to[cnt], inode_usage, &warn_to[cnt]); + ret = dquot_add_inodes(transfer_to[cnt], inode_usage, + &warn_to[cnt]); if (ret) goto over_quota; - ret = check_bdq(transfer_to[cnt], space, 0, &warn_to[cnt]); - if (ret) + ret = dquot_add_space(transfer_to[cnt], cur_space, rsv_space, 0, + &warn_to[cnt]); + if (ret) { + spin_lock(&transfer_to[cnt]->dq_dqb_lock); + dquot_decr_inodes(transfer_to[cnt], inode_usage); + spin_unlock(&transfer_to[cnt]->dq_dqb_lock); goto over_quota; + } } - /* - * Finally perform the needed transfer from transfer_from to transfer_to - */ + /* Decrease usage for source structures and update quota pointers */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (!is_valid[cnt]) continue; /* Due to IO error we might not have transfer_from[] structure */ if (transfer_from[cnt]) { int wtype; + + spin_lock(&transfer_from[cnt]->dq_dqb_lock); wtype = info_idq_free(transfer_from[cnt], inode_usage); if (wtype != QUOTA_NL_NOWARN) prepare_warning(&warn_from_inodes[cnt], transfer_from[cnt], wtype); - wtype = info_bdq_free(transfer_from[cnt], space); + wtype = info_bdq_free(transfer_from[cnt], + cur_space + rsv_space); if (wtype != QUOTA_NL_NOWARN) prepare_warning(&warn_from_space[cnt], transfer_from[cnt], wtype); @@ -1983,14 +2009,11 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) dquot_decr_space(transfer_from[cnt], cur_space); dquot_free_reserved_space(transfer_from[cnt], rsv_space); + spin_unlock(&transfer_from[cnt]->dq_dqb_lock); } - - dquot_incr_inodes(transfer_to[cnt], inode_usage); - dquot_incr_space(transfer_to[cnt], cur_space); - dquot_resv_space(transfer_to[cnt], rsv_space); - i_dquot(inode)[cnt] = transfer_to[cnt]; } + spin_unlock(&inode->i_lock); spin_unlock(&dq_data_lock); mark_all_dquot_dirty(transfer_from); @@ -2004,6 +2027,17 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) transfer_to[cnt] = transfer_from[cnt]; return 0; over_quota: + /* Back out changes we already did */ + for (cnt--; cnt >= 0; cnt--) { + if (!is_valid[cnt]) + continue; + spin_lock(&transfer_to[cnt]->dq_dqb_lock); + dquot_decr_inodes(transfer_to[cnt], inode_usage); + dquot_decr_space(transfer_to[cnt], cur_space); + dquot_free_reserved_space(transfer_to[cnt], rsv_space); + spin_unlock(&transfer_to[cnt]->dq_dqb_lock); + } + spin_unlock(&inode->i_lock); spin_unlock(&dq_data_lock); flush_warnings(warn_to); return ret; @@ -2057,29 +2091,21 @@ EXPORT_SYMBOL(dquot_transfer); */ int dquot_commit_info(struct super_block *sb, int type) { - int ret; struct quota_info *dqopt = sb_dqopt(sb); - mutex_lock(&dqopt->dqio_mutex); - ret = dqopt->ops[type]->write_file_info(sb, type); - mutex_unlock(&dqopt->dqio_mutex); - return ret; + return dqopt->ops[type]->write_file_info(sb, type); } EXPORT_SYMBOL(dquot_commit_info); int dquot_get_next_id(struct super_block *sb, struct kqid *qid) { struct quota_info *dqopt = sb_dqopt(sb); - int err; if (!sb_has_quota_active(sb, qid->type)) return -ESRCH; if (!dqopt->ops[qid->type]->get_next_id) return -ENOSYS; - mutex_lock(&dqopt->dqio_mutex); - err = dqopt->ops[qid->type]->get_next_id(sb, qid); - mutex_unlock(&dqopt->dqio_mutex); - return err; + return dqopt->ops[qid->type]->get_next_id(sb, qid); } EXPORT_SYMBOL(dquot_get_next_id); @@ -2328,15 +2354,14 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, dqopt->info[type].dqi_format = fmt; dqopt->info[type].dqi_fmt_id = format_id; INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); - mutex_lock(&dqopt->dqio_mutex); error = dqopt->ops[type]->read_file_info(sb, type); - if (error < 0) { - mutex_unlock(&dqopt->dqio_mutex); + if (error < 0) goto out_file_init; - } - if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) + if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) { + spin_lock(&dq_data_lock); dqopt->info[type].dqi_flags |= DQF_SYS_FILE; - mutex_unlock(&dqopt->dqio_mutex); + spin_unlock(&dq_data_lock); + } spin_lock(&dq_state_lock); dqopt->flags |= dquot_state_flag(flags, type); spin_unlock(&dq_state_lock); @@ -2563,7 +2588,7 @@ static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di) struct mem_dqblk *dm = &dquot->dq_dqb; memset(di, 0, sizeof(*di)); - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); di->d_spc_hardlimit = dm->dqb_bhardlimit; di->d_spc_softlimit = dm->dqb_bsoftlimit; di->d_ino_hardlimit = dm->dqb_ihardlimit; @@ -2572,7 +2597,7 @@ static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di) di->d_ino_count = dm->dqb_curinodes; di->d_spc_timer = dm->dqb_btime; di->d_ino_timer = dm->dqb_itime; - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); } int dquot_get_dqblk(struct super_block *sb, struct kqid qid, @@ -2636,7 +2661,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) (di->d_ino_hardlimit > dqi->dqi_max_ino_limit))) return -ERANGE; - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); if (di->d_fieldmask & QC_SPACE) { dm->dqb_curspace = di->d_space - dm->dqb_rsvspace; check_blim = 1; @@ -2681,7 +2706,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) if (check_blim) { if (!dm->dqb_bsoftlimit || - dm->dqb_curspace < dm->dqb_bsoftlimit) { + dm->dqb_curspace + dm->dqb_rsvspace < dm->dqb_bsoftlimit) { dm->dqb_btime = 0; clear_bit(DQ_BLKS_B, &dquot->dq_flags); } else if (!(di->d_fieldmask & QC_SPC_TIMER)) @@ -2702,7 +2727,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) clear_bit(DQ_FAKE_B, &dquot->dq_flags); else set_bit(DQ_FAKE_B, &dquot->dq_flags); - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); mark_dquot_dirty(dquot); return 0; diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 07e08c7d05cae23d92ab891cb384e5dda90509df..a9c5dfe6b83e5ef6f17f6adeb3662e65a97f1b2b 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -753,7 +753,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_XGETNEXTQUOTA: return quota_getnextxquota(sb, type, id, addr); case Q_XQUOTASYNC: - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; /* XFS quotas are fully coherent now, making this call a noop */ return 0; diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index 0738972e8d3f01c6469ea2f5c0917e89ba26e81a..bb3f59bcfcf5b1ee07c2d154fa8b906e4f4c9302 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c @@ -379,7 +379,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) if (!ddquot) return -ENOMEM; - /* dq_off is guarded by dqio_mutex */ + /* dq_off is guarded by dqio_sem */ if (!dquot->dq_off) { ret = dq_insert_tree(info, dquot); if (ret < 0) { @@ -389,9 +389,9 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) return ret; } } - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); info->dqi_ops->mem2disk_dqblk(ddquot, dquot); - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, dquot->dq_off); if (ret != info->dqi_entry_size) { @@ -649,14 +649,14 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) kfree(ddquot); goto out; } - spin_lock(&dq_data_lock); + spin_lock(&dquot->dq_dqb_lock); info->dqi_ops->disk2mem_dqblk(dquot, ddquot); if (!dquot->dq_dqb.dqb_bhardlimit && !dquot->dq_dqb.dqb_bsoftlimit && !dquot->dq_dqb.dqb_ihardlimit && !dquot->dq_dqb.dqb_isoftlimit) set_bit(DQ_FAKE_B, &dquot->dq_flags); - spin_unlock(&dq_data_lock); + spin_unlock(&dquot->dq_dqb_lock); kfree(ddquot); out: dqstats_inc(DQST_READS); diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c index 8fe79beced5cc05c77ad0d536fe017beeb4a2f9e..7ac5298aba70bc7d48c96d85fae88759a7680eb8 100644 --- a/fs/quota/quota_v1.c +++ b/fs/quota/quota_v1.c @@ -56,8 +56,9 @@ static int v1_read_dqblk(struct dquot *dquot) { int type = dquot->dq_id.type; struct v1_disk_dqblk dqblk; + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); - if (!sb_dqopt(dquot->dq_sb)->files[type]) + if (!dqopt->files[type]) return -EINVAL; /* Set structure to 0s in case read fails/is after end of file */ @@ -160,6 +161,7 @@ static int v1_read_file_info(struct super_block *sb, int type) struct v1_disk_dqblk dqblk; int ret; + down_read(&dqopt->dqio_sem); ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret != sizeof(struct v1_disk_dqblk)) { @@ -176,6 +178,7 @@ static int v1_read_file_info(struct super_block *sb, int type) dqopt->info[type].dqi_bgrace = dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; out: + up_read(&dqopt->dqio_sem); return ret; } @@ -185,7 +188,7 @@ static int v1_write_file_info(struct super_block *sb, int type) struct v1_disk_dqblk dqblk; int ret; - dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; + down_write(&dqopt->dqio_sem); ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret != sizeof(struct v1_disk_dqblk)) { @@ -193,8 +196,11 @@ static int v1_write_file_info(struct super_block *sb, int type) ret = -EIO; goto out; } + spin_lock(&dq_data_lock); + dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; dqblk.dqb_itime = dqopt->info[type].dqi_igrace; dqblk.dqb_btime = dqopt->info[type].dqi_bgrace; + spin_unlock(&dq_data_lock); ret = sb->s_op->quota_write(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret == sizeof(struct v1_disk_dqblk)) @@ -202,6 +208,7 @@ static int v1_write_file_info(struct super_block *sb, int type) else if (ret > 0) ret = -EIO; out: + up_write(&dqopt->dqio_sem); return ret; } diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index ca71bf881ad1e33d11c1fdd10b71070c5079358d..a73e5b34db4181272bc943c4e0ea406797ff0311 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -65,9 +65,11 @@ static int v2_read_header(struct super_block *sb, int type, if (size != sizeof(struct v2_disk_dqheader)) { quota_error(sb, "Failed header read: expected=%zd got=%zd", sizeof(struct v2_disk_dqheader), size); - return 0; + if (size < 0) + return size; + return -EIO; } - return 1; + return 0; } /* Check whether given file is really vfsv0 quotafile */ @@ -77,7 +79,7 @@ static int v2_check_quota_file(struct super_block *sb, int type) static const uint quota_magics[] = V2_INITQMAGICS; static const uint quota_versions[] = V2_INITQVERSIONS; - if (!v2_read_header(sb, type, &dqhead)) + if (v2_read_header(sb, type, &dqhead)) return 0; if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] || le32_to_cpu(dqhead.dqh_version) > quota_versions[type]) @@ -90,29 +92,38 @@ static int v2_read_file_info(struct super_block *sb, int type) { struct v2_disk_dqinfo dinfo; struct v2_disk_dqheader dqhead; - struct mem_dqinfo *info = sb_dqinfo(sb, type); + struct quota_info *dqopt = sb_dqopt(sb); + struct mem_dqinfo *info = &dqopt->info[type]; struct qtree_mem_dqinfo *qinfo; ssize_t size; unsigned int version; + int ret; - if (!v2_read_header(sb, type, &dqhead)) - return -1; + down_read(&dqopt->dqio_sem); + ret = v2_read_header(sb, type, &dqhead); + if (ret < 0) + goto out; version = le32_to_cpu(dqhead.dqh_version); if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) || - (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) - return -1; + (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) { + ret = -EINVAL; + goto out; + } size = sb->s_op->quota_read(sb, type, (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); if (size != sizeof(struct v2_disk_dqinfo)) { quota_error(sb, "Can't read info structure"); - return -1; + if (size < 0) + ret = size; + else + ret = -EIO; + goto out; } info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS); if (!info->dqi_priv) { - printk(KERN_WARNING - "Not enough memory for quota information structure.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto out; } qinfo = info->dqi_priv; if (version == 0) { @@ -147,17 +158,22 @@ static int v2_read_file_info(struct super_block *sb, int type) qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk); qinfo->dqi_ops = &v2r1_qtree_ops; } - return 0; + ret = 0; +out: + up_read(&dqopt->dqio_sem); + return ret; } /* Write information header to quota file */ static int v2_write_file_info(struct super_block *sb, int type) { struct v2_disk_dqinfo dinfo; - struct mem_dqinfo *info = sb_dqinfo(sb, type); + struct quota_info *dqopt = sb_dqopt(sb); + struct mem_dqinfo *info = &dqopt->info[type]; struct qtree_mem_dqinfo *qinfo = info->dqi_priv; ssize_t size; + down_write(&dqopt->dqio_sem); spin_lock(&dq_data_lock); info->dqi_flags &= ~DQF_INFO_DIRTY; dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); @@ -170,6 +186,7 @@ static int v2_write_file_info(struct super_block *sb, int type) dinfo.dqi_free_entry = cpu_to_le32(qinfo->dqi_free_entry); size = sb->s_op->quota_write(sb, type, (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); + up_write(&dqopt->dqio_sem); if (size != sizeof(struct v2_disk_dqinfo)) { quota_error(sb, "Can't write info structure"); return -1; @@ -285,17 +302,55 @@ static int v2r1_is_id(void *dp, struct dquot *dquot) static int v2_read_dquot(struct dquot *dquot) { - return qtree_read_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + int ret; + + down_read(&dqopt->dqio_sem); + ret = qtree_read_dquot( + sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, + dquot); + up_read(&dqopt->dqio_sem); + return ret; } static int v2_write_dquot(struct dquot *dquot) { - return qtree_write_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + int ret; + bool alloc = false; + + /* + * If space for dquot is already allocated, we don't need any + * protection as we'll only overwrite the place of dquot. We are + * still protected by concurrent writes of the same dquot by + * dquot->dq_lock. + */ + if (!dquot->dq_off) { + alloc = true; + down_write(&dqopt->dqio_sem); + } else { + down_read(&dqopt->dqio_sem); + } + ret = qtree_write_dquot( + sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, + dquot); + if (alloc) + up_write(&dqopt->dqio_sem); + else + up_read(&dqopt->dqio_sem); + return ret; } static int v2_release_dquot(struct dquot *dquot) { - return qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + int ret; + + down_write(&dqopt->dqio_sem); + ret = qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); + up_write(&dqopt->dqio_sem); + + return ret; } static int v2_free_file_info(struct super_block *sb, int type) @@ -306,7 +361,13 @@ static int v2_free_file_info(struct super_block *sb, int type) static int v2_get_next_id(struct super_block *sb, struct kqid *qid) { - return qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid); + struct quota_info *dqopt = sb_dqopt(sb); + int ret; + + down_read(&dqopt->dqio_sem); + ret = qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid); + up_read(&dqopt->dqio_sem); + return ret; } static const struct quota_format_ops v2_format_ops = { diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 2ef7ce75c0629baf3dbdd7c9e513e80fa2fd52eb..3ac1f23870837a8d5ab0b98338c997aabf4523a1 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -228,7 +228,7 @@ static unsigned long ramfs_nommu_get_unmapped_area(struct file *file, if (!pages) goto out_free; - nr = find_get_pages(inode->i_mapping, pgoff, lpages, pages); + nr = find_get_pages(inode->i_mapping, &pgoff, lpages, pages); if (nr != lpages) goto out_free_pages; /* leave if some pages were missing */ diff --git a/fs/read_write.c b/fs/read_write.c index 0cc7033aa413527973b92eb1a6bedda8e92da470..f0d4b16873e89aa23522c9ece34b8f1900638176 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -33,7 +33,7 @@ const struct file_operations generic_ro_fops = { EXPORT_SYMBOL(generic_ro_fops); -static inline int unsigned_offsets(struct file *file) +static inline bool unsigned_offsets(struct file *file) { return file->f_mode & FMODE_UNSIGNED_OFFSET; } @@ -112,7 +112,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence, * In the generic case the entire file is data, so as long as * offset isn't at the end of the file then the offset is data. */ - if (offset >= eof) + if ((unsigned long long)offset >= eof) return -ENXIO; break; case SEEK_HOLE: @@ -120,7 +120,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence, * There is a virtual hole at the end of the file, so as long as * offset isn't i_size or larger, return i_size. */ - if (offset >= eof) + if ((unsigned long long)offset >= eof) return -ENXIO; offset = eof; break; @@ -413,7 +413,20 @@ ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, else return -EINVAL; } -EXPORT_SYMBOL(__vfs_read); + +ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) +{ + mm_segment_t old_fs; + ssize_t result; + + old_fs = get_fs(); + set_fs(get_ds()); + /* The cast to a user pointer is valid due to the set_fs() */ + result = vfs_read(file, (void __user *)buf, count, pos); + set_fs(old_fs); + return result; +} +EXPORT_SYMBOL(kernel_read); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { @@ -441,8 +454,6 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) return ret; } -EXPORT_SYMBOL(vfs_read); - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; @@ -471,9 +482,8 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, else return -EINVAL; } -EXPORT_SYMBOL(__vfs_write); -ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) +ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) { mm_segment_t old_fs; const char __user *p; @@ -496,9 +506,24 @@ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t inc_syscw(current); return ret; } - EXPORT_SYMBOL(__kernel_write); +ssize_t kernel_write(struct file *file, const void *buf, size_t count, + loff_t *pos) +{ + mm_segment_t old_fs; + ssize_t res; + + old_fs = get_fs(); + set_fs(get_ds()); + /* The cast to a user pointer is valid due to the set_fs() */ + res = vfs_write(file, (__force const char __user *)buf, count, pos); + set_fs(old_fs); + + return res; +} +EXPORT_SYMBOL(kernel_write); + ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; @@ -527,8 +552,6 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ return ret; } -EXPORT_SYMBOL(vfs_write); - static inline loff_t file_pos_read(struct file *file) { return file->f_pos; @@ -633,7 +656,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) EXPORT_SYMBOL(iov_shorten); static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, - loff_t *ppos, int type, int flags) + loff_t *ppos, int type, rwf_t flags) { struct kiocb kiocb; ssize_t ret; @@ -655,7 +678,7 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, /* Do it by hand, with file-ops */ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, - loff_t *ppos, int type, int flags) + loff_t *ppos, int type, rwf_t flags) { ssize_t ret = 0; @@ -871,7 +894,7 @@ ssize_t compat_rw_copy_check_uvector(int type, #endif static ssize_t do_iter_read(struct file *file, struct iov_iter *iter, - loff_t *pos, int flags) + loff_t *pos, rwf_t flags) { size_t tot_len; ssize_t ret = 0; @@ -899,7 +922,7 @@ static ssize_t do_iter_read(struct file *file, struct iov_iter *iter, } ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos, - int flags) + rwf_t flags) { if (!file->f_op->read_iter) return -EINVAL; @@ -908,7 +931,7 @@ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos, EXPORT_SYMBOL(vfs_iter_read); static ssize_t do_iter_write(struct file *file, struct iov_iter *iter, - loff_t *pos, int flags) + loff_t *pos, rwf_t flags) { size_t tot_len; ssize_t ret = 0; @@ -935,7 +958,7 @@ static ssize_t do_iter_write(struct file *file, struct iov_iter *iter, } ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos, - int flags) + rwf_t flags) { if (!file->f_op->write_iter) return -EINVAL; @@ -944,7 +967,7 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos, EXPORT_SYMBOL(vfs_iter_write); ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, - unsigned long vlen, loff_t *pos, int flags) + unsigned long vlen, loff_t *pos, rwf_t flags) { struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; @@ -959,10 +982,9 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, return ret; } -EXPORT_SYMBOL(vfs_readv); -ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, - unsigned long vlen, loff_t *pos, int flags) +static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, + unsigned long vlen, loff_t *pos, rwf_t flags) { struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; @@ -978,10 +1000,9 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, } return ret; } -EXPORT_SYMBOL(vfs_writev); static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec, - unsigned long vlen, int flags) + unsigned long vlen, rwf_t flags) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; @@ -1001,7 +1022,7 @@ static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec, } static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec, - unsigned long vlen, int flags) + unsigned long vlen, rwf_t flags) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; @@ -1027,7 +1048,7 @@ static inline loff_t pos_from_hilo(unsigned long high, unsigned long low) } static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec, - unsigned long vlen, loff_t pos, int flags) + unsigned long vlen, loff_t pos, rwf_t flags) { struct fd f; ssize_t ret = -EBADF; @@ -1050,7 +1071,7 @@ static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec, } static ssize_t do_pwritev(unsigned long fd, const struct iovec __user *vec, - unsigned long vlen, loff_t pos, int flags) + unsigned long vlen, loff_t pos, rwf_t flags) { struct fd f; ssize_t ret = -EBADF; @@ -1094,7 +1115,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec, unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h, - int, flags) + rwf_t, flags) { loff_t pos = pos_from_hilo(pos_h, pos_l); @@ -1114,7 +1135,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec, unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h, - int, flags) + rwf_t, flags) { loff_t pos = pos_from_hilo(pos_h, pos_l); @@ -1127,7 +1148,7 @@ SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec, #ifdef CONFIG_COMPAT static size_t compat_readv(struct file *file, const struct compat_iovec __user *vec, - unsigned long vlen, loff_t *pos, int flags) + unsigned long vlen, loff_t *pos, rwf_t flags) { struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; @@ -1147,7 +1168,7 @@ static size_t compat_readv(struct file *file, static size_t do_compat_readv(compat_ulong_t fd, const struct compat_iovec __user *vec, - compat_ulong_t vlen, int flags) + compat_ulong_t vlen, rwf_t flags) { struct fd f = fdget_pos(fd); ssize_t ret; @@ -1173,7 +1194,7 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, static long do_compat_preadv64(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos, int flags) + unsigned long vlen, loff_t pos, rwf_t flags) { struct fd f; ssize_t ret; @@ -1211,7 +1232,7 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2 COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd, const struct compat_iovec __user *,vec, - unsigned long, vlen, loff_t, pos, int, flags) + unsigned long, vlen, loff_t, pos, rwf_t, flags) { return do_compat_preadv64(fd, vec, vlen, pos, flags); } @@ -1220,7 +1241,7 @@ COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd, COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd, const struct compat_iovec __user *,vec, compat_ulong_t, vlen, u32, pos_low, u32, pos_high, - int, flags) + rwf_t, flags) { loff_t pos = ((loff_t)pos_high << 32) | pos_low; @@ -1232,7 +1253,7 @@ COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd, static size_t compat_writev(struct file *file, const struct compat_iovec __user *vec, - unsigned long vlen, loff_t *pos, int flags) + unsigned long vlen, loff_t *pos, rwf_t flags) { struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; @@ -1254,7 +1275,7 @@ static size_t compat_writev(struct file *file, static size_t do_compat_writev(compat_ulong_t fd, const struct compat_iovec __user* vec, - compat_ulong_t vlen, int flags) + compat_ulong_t vlen, rwf_t flags) { struct fd f = fdget_pos(fd); ssize_t ret; @@ -1279,7 +1300,7 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, static long do_compat_pwritev64(unsigned long fd, const struct compat_iovec __user *vec, - unsigned long vlen, loff_t pos, int flags) + unsigned long vlen, loff_t pos, rwf_t flags) { struct fd f; ssize_t ret; @@ -1317,7 +1338,7 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd, const struct compat_iovec __user *,vec, - unsigned long, vlen, loff_t, pos, int, flags) + unsigned long, vlen, loff_t, pos, rwf_t, flags) { return do_compat_pwritev64(fd, vec, vlen, pos, flags); } @@ -1325,7 +1346,7 @@ COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd, COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd, const struct compat_iovec __user *,vec, - compat_ulong_t, vlen, u32, pos_low, u32, pos_high, int, flags) + compat_ulong_t, vlen, u32, pos_low, u32, pos_high, rwf_t, flags) { loff_t pos = ((loff_t)pos_high << 32) | pos_low; diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 45aa05e2232f9ad6e7a752e794b404377a8822d3..5b50689d853964dd40a71997c1968f9d4357070d 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -34,7 +34,7 @@ static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end, struct inode *inode = filp->f_mapping->host; int err; - err = filemap_write_and_wait_range(inode->i_mapping, start, end); + err = file_write_and_wait_range(filp, start, end); if (err) return err; diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index b396eb09f288864ae27ce6a65108fa1e6f819820..843aadcc123c2a12e04259e90dcc8dff2e779b03 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -154,7 +154,7 @@ static int reiserfs_sync_file(struct file *filp, loff_t start, loff_t end, int err; int barrier_done; - err = filemap_write_and_wait_range(inode->i_mapping, start, end); + err = file_write_and_wait_range(filp, start, end); if (err) return err; diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 873fc04e9403aa7d6ca9c2d13a7d045dd963fe75..11a48affa882415376e279aabe0e0df7b81c49fd 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1776,7 +1776,7 @@ int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc) struct reiserfs_transaction_handle th; int jbegin_count = 1; - if (inode->i_sb->s_flags & MS_RDONLY) + if (sb_rdonly(inode->i_sb)) return -EROFS; /* * memory pressure can sometimes initiate write_inode calls with diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index a11d773e5ff32a21a7b2ec4fb0102acec01a8dfe..f59c667df15b4cf357e20080833d5da0b19f6851 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1481,7 +1481,7 @@ static int flush_journal_list(struct super_block *s, if ((!was_jwait) && !buffer_locked(saved_bh)) { reiserfs_warning(s, "journal-813", "BAD! buffer %llu %cdirty %cjwait, " - "not in a newer tranasction", + "not in a newer transaction", (unsigned long long)saved_bh-> b_blocknr, was_dirty ? ' ' : '!', was_jwait ? ' ' : '!'); @@ -1918,7 +1918,7 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, * we only want to flush out transactions if we were * called with error == 0 */ - if (!error && !(sb->s_flags & MS_RDONLY)) { + if (!error && !sb_rdonly(sb)) { /* end the current trans */ BUG_ON(!th->t_trans_id); do_journal_end(th, FLUSH_ALL); diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index 4f3f928076f3c237c3c582e5f764b8a6ca3d1aea..64f49cafbc5bff7b7c34786e56851408f4f20b55 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c @@ -386,7 +386,7 @@ void __reiserfs_error(struct super_block *sb, const char *id, printk(KERN_CRIT "REISERFS error (device %s): %s: %s\n", sb->s_id, function, error_buf); - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return; reiserfs_info(sb, "Remounting filesystem read-only\n"); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 306e4e9d172d4579206dd4367612a89059ea3c41..5464ec517702f1bb18e0d3323ef57564ef271b53 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -121,7 +121,7 @@ void reiserfs_schedule_old_flush(struct super_block *s) * Avoid scheduling flush when sb is being shut down. It can race * with journal shutdown and free still queued delayed work. */ - if (s->s_flags & MS_RDONLY || !(s->s_flags & MS_ACTIVE)) + if (sb_rdonly(s) || !(s->s_flags & MS_ACTIVE)) return; spin_lock(&sbi->old_work_lock); @@ -151,7 +151,7 @@ static int reiserfs_freeze(struct super_block *s) reiserfs_cancel_old_flush(s); reiserfs_write_lock(s); - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { int err = journal_begin(&th, s, 1); if (err) { reiserfs_block_writes(&th); @@ -599,7 +599,7 @@ static void reiserfs_put_super(struct super_block *s) * change file system state to current state if it was mounted * with read-write permissions */ - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { if (!journal_begin(&th, s, 10)) { reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -700,7 +700,7 @@ static void reiserfs_dirty_inode(struct inode *inode, int flags) int err = 0; - if (inode->i_sb->s_flags & MS_RDONLY) { + if (sb_rdonly(inode->i_sb)) { reiserfs_warning(inode->i_sb, "clm-6006", "writing inode %lu on readonly FS", inode->i_ino); @@ -1525,7 +1525,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) reiserfs_write_unlock(s); reiserfs_xattr_init(s, *mount_flags); /* remount read-only */ - if (s->s_flags & MS_RDONLY) + if (sb_rdonly(s)) /* it is read-only already */ goto out_ok_unlocked; @@ -1551,7 +1551,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) journal_mark_dirty(&th, SB_BUFFER_WITH_SB(s)); } else { /* remount read-write */ - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { reiserfs_write_unlock(s); reiserfs_xattr_init(s, *mount_flags); goto out_ok_unlocked; /* We are read-write already */ @@ -1855,7 +1855,7 @@ static int what_hash(struct super_block *s) * the super */ if (code != UNSET_HASH && - !(s->s_flags & MS_RDONLY) && + !sb_rdonly(s) && code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) { set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code); } @@ -2052,7 +2052,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) if (replay_only(s)) goto error_unlocked; - if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) { + if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) { SWARN(silent, s, "clm-7000", "Detected readonly device, marking FS readonly"); s->s_flags |= MS_RDONLY; @@ -2101,7 +2101,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) else set_bit(REISERFS_3_6, &sbi->s_properties); - if (!(s->s_flags & MS_RDONLY)) { + if (!sb_rdonly(s)) { errval = journal_begin(&th, s, 1); if (errval) { diff --git a/fs/select.c b/fs/select.c index 9d5f15ed87fe7999eaaad22497899e696ad34147..c6362e38ae92dcfafd76f2b10541cb9e4464e230 100644 --- a/fs/select.c +++ b/fs/select.c @@ -1164,11 +1164,7 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, if (ufdset) { return compat_get_bitmap(fdset, ufdset, nr); } else { - /* Tricky, must clear full unsigned long in the - * kernel fdset at the end, ALIGN makes sure that - * actually happens. - */ - memset(fdset, 0, ALIGN(nr, BITS_PER_LONG)); + zero_fd_set(nr, fdset); return 0; } } diff --git a/fs/signalfd.c b/fs/signalfd.c index 593b022ac11b873c67b03f7dcd4ebd5686fe9d2d..d2c434112f4265fec495a1b622c04e59be1e8b58 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -95,23 +95,23 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, */ err |= __put_user(kinfo->si_signo, &uinfo->ssi_signo); err |= __put_user(kinfo->si_errno, &uinfo->ssi_errno); - err |= __put_user((short) kinfo->si_code, &uinfo->ssi_code); - switch (kinfo->si_code & __SI_MASK) { - case __SI_KILL: + err |= __put_user(kinfo->si_code, &uinfo->ssi_code); + switch (siginfo_layout(kinfo->si_signo, kinfo->si_code)) { + case SIL_KILL: err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); break; - case __SI_TIMER: + case SIL_TIMER: err |= __put_user(kinfo->si_tid, &uinfo->ssi_tid); err |= __put_user(kinfo->si_overrun, &uinfo->ssi_overrun); err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); err |= __put_user(kinfo->si_int, &uinfo->ssi_int); break; - case __SI_POLL: + case SIL_POLL: err |= __put_user(kinfo->si_band, &uinfo->ssi_band); err |= __put_user(kinfo->si_fd, &uinfo->ssi_fd); break; - case __SI_FAULT: + case SIL_FAULT: err |= __put_user((long) kinfo->si_addr, &uinfo->ssi_addr); #ifdef __ARCH_SI_TRAPNO err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno); @@ -128,20 +128,14 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, &uinfo->ssi_addr_lsb); #endif break; - case __SI_CHLD: + case SIL_CHLD: err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); err |= __put_user(kinfo->si_status, &uinfo->ssi_status); err |= __put_user(kinfo->si_utime, &uinfo->ssi_utime); err |= __put_user(kinfo->si_stime, &uinfo->ssi_stime); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: /* But this is */ - err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); - err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); - err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); - err |= __put_user(kinfo->si_int, &uinfo->ssi_int); - break; + case SIL_RT: default: /* * This case catches also the signals queued by sigqueue(). diff --git a/fs/splice.c b/fs/splice.c index ae41201d032581a7c03f00a5cc86287782e000d4..f3084cce0ea6be94ad047a1bf07cdcf1cb3cf0f4 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -364,22 +364,6 @@ static ssize_t kernel_readv(struct file *file, const struct kvec *vec, return res; } -ssize_t kernel_write(struct file *file, const char *buf, size_t count, - loff_t pos) -{ - mm_segment_t old_fs; - ssize_t res; - - old_fs = get_fs(); - set_fs(get_ds()); - /* The cast to a user pointer is valid due to the set_fs() */ - res = vfs_write(file, (__force const char __user *)buf, count, &pos); - set_fs(old_fs); - - return res; -} -EXPORT_SYMBOL(kernel_write); - static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags) diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig index ffb093e72b6ca89a0f8d339dfad3f04da0c97e8e..1adb3346b9d6aa659cf5aaf5f82afe1d81a8118f 100644 --- a/fs/squashfs/Kconfig +++ b/fs/squashfs/Kconfig @@ -165,6 +165,20 @@ config SQUASHFS_XZ If unsure, say N. +config SQUASHFS_ZSTD + bool "Include support for ZSTD compressed file systems" + depends on SQUASHFS + select ZSTD_DECOMPRESS + help + Saying Y here includes support for reading Squashfs file systems + compressed with ZSTD compression. ZSTD gives better compression than + the default ZLIB compression, while using less CPU. + + ZSTD is not the standard compression used in Squashfs and so most + file systems will be readable without selecting this option. + + If unsure, say N. + config SQUASHFS_4K_DEVBLK_SIZE bool "Use 4K device block size?" depends on SQUASHFS diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile index 246a6f329d8957df4b3bf48129b3f0e415be2611..6655631c53ae78573c3f88d14d6f60d134ed1639 100644 --- a/fs/squashfs/Makefile +++ b/fs/squashfs/Makefile @@ -15,3 +15,4 @@ squashfs-$(CONFIG_SQUASHFS_LZ4) += lz4_wrapper.o squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o +squashfs-$(CONFIG_SQUASHFS_ZSTD) += zstd_wrapper.o diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c index d2bc13636f7927a7485bb153c4d0883a7b2ea1e2..836639810ea01720982176ddd1aeb22d7e40835a 100644 --- a/fs/squashfs/decompressor.c +++ b/fs/squashfs/decompressor.c @@ -65,6 +65,12 @@ static const struct squashfs_decompressor squashfs_zlib_comp_ops = { }; #endif +#ifndef CONFIG_SQUASHFS_ZSTD +static const struct squashfs_decompressor squashfs_zstd_comp_ops = { + NULL, NULL, NULL, NULL, ZSTD_COMPRESSION, "zstd", 0 +}; +#endif + static const struct squashfs_decompressor squashfs_unknown_comp_ops = { NULL, NULL, NULL, NULL, 0, "unknown", 0 }; @@ -75,6 +81,7 @@ static const struct squashfs_decompressor *decompressor[] = { &squashfs_lzo_comp_ops, &squashfs_xz_comp_ops, &squashfs_lzma_unsupported_comp_ops, + &squashfs_zstd_comp_ops, &squashfs_unknown_comp_ops }; diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h index a25713c031a51213edc9dd5a32de73f64f75c44f..0f5a8e4e58dae999fae44f95e232738cf0bebe7c 100644 --- a/fs/squashfs/decompressor.h +++ b/fs/squashfs/decompressor.h @@ -58,4 +58,8 @@ extern const struct squashfs_decompressor squashfs_lzo_comp_ops; extern const struct squashfs_decompressor squashfs_zlib_comp_ops; #endif +#ifdef CONFIG_SQUASHFS_ZSTD +extern const struct squashfs_decompressor squashfs_zstd_comp_ops; +#endif + #endif diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h index 506f4ba5b98309b9041cc99103312837b2724e58..24d12fd1417767689778302abf77b21f1efd6350 100644 --- a/fs/squashfs/squashfs_fs.h +++ b/fs/squashfs/squashfs_fs.h @@ -241,6 +241,7 @@ struct meta_index { #define LZO_COMPRESSION 3 #define XZ_COMPRESSION 4 #define LZ4_COMPRESSION 5 +#define ZSTD_COMPRESSION 6 struct squashfs_super_block { __le32 s_magic; diff --git a/fs/squashfs/zstd_wrapper.c b/fs/squashfs/zstd_wrapper.c new file mode 100644 index 0000000000000000000000000000000000000000..eeaabf8811591d1980ed507a307732c69afe2dd0 --- /dev/null +++ b/fs/squashfs/zstd_wrapper.c @@ -0,0 +1,151 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * zstd_wrapper.c + */ + +#include +#include +#include +#include +#include + +#include "squashfs_fs.h" +#include "squashfs_fs_sb.h" +#include "squashfs.h" +#include "decompressor.h" +#include "page_actor.h" + +struct workspace { + void *mem; + size_t mem_size; + size_t window_size; +}; + +static void *zstd_init(struct squashfs_sb_info *msblk, void *buff) +{ + struct workspace *wksp = kmalloc(sizeof(*wksp), GFP_KERNEL); + + if (wksp == NULL) + goto failed; + wksp->window_size = max_t(size_t, + msblk->block_size, SQUASHFS_METADATA_SIZE); + wksp->mem_size = ZSTD_DStreamWorkspaceBound(wksp->window_size); + wksp->mem = vmalloc(wksp->mem_size); + if (wksp->mem == NULL) + goto failed; + + return wksp; + +failed: + ERROR("Failed to allocate zstd workspace\n"); + kfree(wksp); + return ERR_PTR(-ENOMEM); +} + + +static void zstd_free(void *strm) +{ + struct workspace *wksp = strm; + + if (wksp) + vfree(wksp->mem); + kfree(wksp); +} + + +static int zstd_uncompress(struct squashfs_sb_info *msblk, void *strm, + struct buffer_head **bh, int b, int offset, int length, + struct squashfs_page_actor *output) +{ + struct workspace *wksp = strm; + ZSTD_DStream *stream; + size_t total_out = 0; + size_t zstd_err; + int k = 0; + ZSTD_inBuffer in_buf = { NULL, 0, 0 }; + ZSTD_outBuffer out_buf = { NULL, 0, 0 }; + + stream = ZSTD_initDStream(wksp->window_size, wksp->mem, wksp->mem_size); + + if (!stream) { + ERROR("Failed to initialize zstd decompressor\n"); + goto out; + } + + out_buf.size = PAGE_SIZE; + out_buf.dst = squashfs_first_page(output); + + do { + if (in_buf.pos == in_buf.size && k < b) { + int avail = min(length, msblk->devblksize - offset); + + length -= avail; + in_buf.src = bh[k]->b_data + offset; + in_buf.size = avail; + in_buf.pos = 0; + offset = 0; + } + + if (out_buf.pos == out_buf.size) { + out_buf.dst = squashfs_next_page(output); + if (out_buf.dst == NULL) { + /* Shouldn't run out of pages + * before stream is done. + */ + squashfs_finish_page(output); + goto out; + } + out_buf.pos = 0; + out_buf.size = PAGE_SIZE; + } + + total_out -= out_buf.pos; + zstd_err = ZSTD_decompressStream(stream, &out_buf, &in_buf); + total_out += out_buf.pos; /* add the additional data produced */ + + if (in_buf.pos == in_buf.size && k < b) + put_bh(bh[k++]); + } while (zstd_err != 0 && !ZSTD_isError(zstd_err)); + + squashfs_finish_page(output); + + if (ZSTD_isError(zstd_err)) { + ERROR("zstd decompression error: %d\n", + (int)ZSTD_getErrorCode(zstd_err)); + goto out; + } + + if (k < b) + goto out; + + return (int)total_out; + +out: + for (; k < b; k++) + put_bh(bh[k]); + + return -EIO; +} + +const struct squashfs_decompressor squashfs_zstd_comp_ops = { + .init = zstd_init, + .free = zstd_free, + .decompress = zstd_uncompress, + .id = ZSTD_COMPRESSION, + .name = "zstd", + .supported = 1 +}; diff --git a/fs/stat.c b/fs/stat.c index c35610845ab19f8c17e4ef96e851cddc2205bba9..8a6aa8caf8917fea570ff861c1247ac5f8a519e3 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -710,7 +710,7 @@ loff_t inode_get_bytes(struct inode *inode) loff_t ret; spin_lock(&inode->i_lock); - ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; + ret = __inode_get_bytes(inode); spin_unlock(&inode->i_lock); return ret; } diff --git a/fs/super.c b/fs/super.c index 6bc3352adcf39fc5ed6cad77b5df5c9d7db3f9cc..166c4ee0d0ed02a00591c9b00cdb69eb8759ca61 100644 --- a/fs/super.c +++ b/fs/super.c @@ -242,7 +242,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, atomic_set(&s->s_active, 1); mutex_init(&s->s_vfs_rename_mutex); lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); - mutex_init(&s->s_dquot.dqio_mutex); + init_rwsem(&s->s_dquot.dqio_sem); s->s_maxbytes = MAX_NON_LFS; s->s_op = &default_op; s->s_time_gran = 1000000000; @@ -360,7 +360,7 @@ static int grab_super(struct super_block *s) __releases(sb_lock) s->s_count++; spin_unlock(&sb_lock); down_write(&s->s_umount); - if ((s->s_flags & MS_BORN) && atomic_inc_not_zero(&s->s_active)) { + if ((s->s_flags & SB_BORN) && atomic_inc_not_zero(&s->s_active)) { put_super(s); return 1; } @@ -390,7 +390,7 @@ bool trylock_super(struct super_block *sb) { if (down_read_trylock(&sb->s_umount)) { if (!hlist_unhashed(&sb->s_instances) && - sb->s_root && (sb->s_flags & MS_BORN)) + sb->s_root && (sb->s_flags & SB_BORN)) return true; up_read(&sb->s_umount); } @@ -419,7 +419,7 @@ void generic_shutdown_super(struct super_block *sb) if (sb->s_root) { shrink_dcache_for_umount(sb); sync_filesystem(sb); - sb->s_flags &= ~MS_ACTIVE; + sb->s_flags &= ~SB_ACTIVE; fsnotify_unmount_inodes(sb); cgroup_writeback_umount(); @@ -472,7 +472,7 @@ struct super_block *sget_userns(struct file_system_type *type, struct super_block *old; int err; - if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) && + if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) && !(type->fs_flags & FS_USERNS_MOUNT) && !capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); @@ -502,7 +502,7 @@ struct super_block *sget_userns(struct file_system_type *type, } if (!s) { spin_unlock(&sb_lock); - s = alloc_super(type, (flags & ~MS_SUBMOUNT), user_ns); + s = alloc_super(type, (flags & ~SB_SUBMOUNT), user_ns); if (!s) return ERR_PTR(-ENOMEM); goto retry; @@ -547,11 +547,11 @@ struct super_block *sget(struct file_system_type *type, * mount through to here so always use &init_user_ns * until that changes. */ - if (flags & MS_SUBMOUNT) + if (flags & SB_SUBMOUNT) user_ns = &init_user_ns; /* Ensure the requestor has permissions over the target filesystem */ - if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN)) + if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); return sget_userns(type, test, set, flags, user_ns, data); @@ -594,7 +594,7 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg) spin_unlock(&sb_lock); down_read(&sb->s_umount); - if (sb->s_root && (sb->s_flags & MS_BORN)) + if (sb->s_root && (sb->s_flags & SB_BORN)) f(sb, arg); up_read(&sb->s_umount); @@ -628,7 +628,7 @@ void iterate_supers_type(struct file_system_type *type, spin_unlock(&sb_lock); down_read(&sb->s_umount); - if (sb->s_root && (sb->s_flags & MS_BORN)) + if (sb->s_root && (sb->s_flags & SB_BORN)) f(sb, arg); up_read(&sb->s_umount); @@ -664,7 +664,7 @@ static struct super_block *__get_super(struct block_device *bdev, bool excl) else down_write(&sb->s_umount); /* still alive? */ - if (sb->s_root && (sb->s_flags & MS_BORN)) + if (sb->s_root && (sb->s_flags & SB_BORN)) return sb; if (!excl) up_read(&sb->s_umount); @@ -785,7 +785,7 @@ struct super_block *user_get_super(dev_t dev) spin_unlock(&sb_lock); down_read(&sb->s_umount); /* still alive? */ - if (sb->s_root && (sb->s_flags & MS_BORN)) + if (sb->s_root && (sb->s_flags & SB_BORN)) return sb; up_read(&sb->s_umount); /* nope, got unmounted */ @@ -801,13 +801,13 @@ struct super_block *user_get_super(dev_t dev) /** * do_remount_sb - asks filesystem to change mount options. * @sb: superblock in question - * @flags: numeric part of options + * @sb_flags: revised superblock flags * @data: the rest of options * @force: whether or not to force the change * * Alters the mount options of a mounted file system. */ -int do_remount_sb(struct super_block *sb, int flags, void *data, int force) +int do_remount_sb(struct super_block *sb, int sb_flags, void *data, int force) { int retval; int remount_ro; @@ -816,11 +816,11 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) return -EBUSY; #ifdef CONFIG_BLOCK - if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) + if (!(sb_flags & SB_RDONLY) && bdev_read_only(sb->s_bdev)) return -EACCES; #endif - remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); + remount_ro = (sb_flags & SB_RDONLY) && !sb_rdonly(sb); if (remount_ro) { if (!hlist_empty(&sb->s_pins)) { @@ -831,7 +831,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) return 0; if (sb->s_writers.frozen != SB_UNFROZEN) return -EBUSY; - remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); + remount_ro = (sb_flags & SB_RDONLY) && !sb_rdonly(sb); } } shrink_dcache_sb(sb); @@ -850,7 +850,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) } if (sb->s_op->remount_fs) { - retval = sb->s_op->remount_fs(sb, &flags, data); + retval = sb->s_op->remount_fs(sb, &sb_flags, data); if (retval) { if (!force) goto cancel_readonly; @@ -859,7 +859,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) sb->s_type->name, retval); } } - sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); + sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (sb_flags & MS_RMT_MASK); /* Needs to be ordered wrt mnt_is_readonly() */ smp_wmb(); sb->s_readonly_remount = 0; @@ -892,12 +892,12 @@ static void do_emergency_remount(struct work_struct *work) sb->s_count++; spin_unlock(&sb_lock); down_write(&sb->s_umount); - if (sb->s_root && sb->s_bdev && (sb->s_flags & MS_BORN) && - !(sb->s_flags & MS_RDONLY)) { + if (sb->s_root && sb->s_bdev && (sb->s_flags & SB_BORN) && + !sb_rdonly(sb)) { /* * What lock protects sb->s_flags?? */ - do_remount_sb(sb, MS_RDONLY, NULL, 1); + do_remount_sb(sb, SB_RDONLY, NULL, 1); } up_write(&sb->s_umount); spin_lock(&sb_lock); @@ -1023,7 +1023,7 @@ struct dentry *mount_ns(struct file_system_type *fs_type, /* Don't allow mounting unless the caller has CAP_SYS_ADMIN * over the namespace. */ - if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN)) + if (!(flags & SB_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags, @@ -1033,13 +1033,13 @@ struct dentry *mount_ns(struct file_system_type *fs_type, if (!sb->s_root) { int err; - err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); + err = fill_super(sb, data, flags & SB_SILENT ? 1 : 0); if (err) { deactivate_locked_super(sb); return ERR_PTR(err); } - sb->s_flags |= MS_ACTIVE; + sb->s_flags |= SB_ACTIVE; } return dget(sb->s_root); @@ -1071,7 +1071,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, fmode_t mode = FMODE_READ | FMODE_EXCL; int error = 0; - if (!(flags & MS_RDONLY)) + if (!(flags & SB_RDONLY)) mode |= FMODE_WRITE; bdev = blkdev_get_by_path(dev_name, mode, fs_type); @@ -1089,14 +1089,14 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, error = -EBUSY; goto error_bdev; } - s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC, + s = sget(fs_type, test_bdev_super, set_bdev_super, flags | SB_NOSEC, bdev); mutex_unlock(&bdev->bd_fsfreeze_mutex); if (IS_ERR(s)) goto error_s; if (s->s_root) { - if ((flags ^ s->s_flags) & MS_RDONLY) { + if ((flags ^ s->s_flags) & SB_RDONLY) { deactivate_locked_super(s); error = -EBUSY; goto error_bdev; @@ -1116,13 +1116,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, s->s_mode = mode; snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); sb_set_blocksize(s, block_size(bdev)); - error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); + error = fill_super(s, data, flags & SB_SILENT ? 1 : 0); if (error) { deactivate_locked_super(s); goto error; } - s->s_flags |= MS_ACTIVE; + s->s_flags |= SB_ACTIVE; bdev->bd_super = s; } @@ -1162,12 +1162,12 @@ struct dentry *mount_nodev(struct file_system_type *fs_type, if (IS_ERR(s)) return ERR_CAST(s); - error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); + error = fill_super(s, data, flags & SB_SILENT ? 1 : 0); if (error) { deactivate_locked_super(s); return ERR_PTR(error); } - s->s_flags |= MS_ACTIVE; + s->s_flags |= SB_ACTIVE; return dget(s->s_root); } EXPORT_SYMBOL(mount_nodev); @@ -1188,12 +1188,12 @@ struct dentry *mount_single(struct file_system_type *fs_type, if (IS_ERR(s)) return ERR_CAST(s); if (!s->s_root) { - error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); + error = fill_super(s, data, flags & SB_SILENT ? 1 : 0); if (error) { deactivate_locked_super(s); return ERR_PTR(error); } - s->s_flags |= MS_ACTIVE; + s->s_flags |= SB_ACTIVE; } else { do_remount_sb(s, flags, data, 0); } @@ -1227,7 +1227,7 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data) sb = root->d_sb; BUG_ON(!sb); WARN_ON(!sb->s_bdi); - sb->s_flags |= MS_BORN; + sb->s_flags |= SB_BORN; error = security_sb_kern_mount(sb, flags, secdata); if (error) @@ -1434,12 +1434,12 @@ int freeze_super(struct super_block *sb) return -EBUSY; } - if (!(sb->s_flags & MS_BORN)) { + if (!(sb->s_flags & SB_BORN)) { up_write(&sb->s_umount); return 0; /* sic - it's "nothing to do" */ } - if (sb->s_flags & MS_RDONLY) { + if (sb_rdonly(sb)) { /* Nothing to do really... */ sb->s_writers.frozen = SB_FREEZE_COMPLETE; up_write(&sb->s_umount); @@ -1502,7 +1502,7 @@ int thaw_super(struct super_block *sb) return -EINVAL; } - if (sb->s_flags & MS_RDONLY) { + if (sb_rdonly(sb)) { sb->s_writers.frozen = SB_UNFROZEN; goto out; } diff --git a/fs/sync.c b/fs/sync.c index 2a54c1f2203595823df1bd97680b9a1fb163e400..a576aa2e6b0902662814476fa20d9551e432d930 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -57,7 +57,7 @@ int sync_filesystem(struct super_block *sb) /* * No point in syncing out anything if the filesystem is read-only. */ - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return 0; ret = __sync_filesystem(sb, 0); @@ -69,13 +69,13 @@ EXPORT_SYMBOL(sync_filesystem); static void sync_inodes_one_sb(struct super_block *sb, void *arg) { - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) sync_inodes_sb(sb); } static void sync_fs_one_sb(struct super_block *sb, void *arg) { - if (!(sb->s_flags & MS_RDONLY) && sb->s_op->sync_fs) + if (!sb_rdonly(sb) && sb->s_op->sync_fs) sb->s_op->sync_fs(sb, *(int *)arg); } @@ -335,14 +335,9 @@ SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, goto out_put; mapping = f.file->f_mapping; - if (!mapping) { - ret = -EINVAL; - goto out_put; - } - ret = 0; if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) { - ret = filemap_fdatawait_range(mapping, offset, endbyte); + ret = file_fdatawait_range(f.file, offset, endbyte); if (ret < 0) goto out_put; } @@ -355,7 +350,7 @@ SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, } if (flags & SYNC_FILE_RANGE_WAIT_AFTER) - ret = filemap_fdatawait_range(mapping, offset, endbyte); + ret = file_fdatawait_range(f.file, offset, endbyte); out_put: fdput(f); diff --git a/fs/sysv/balloc.c b/fs/sysv/balloc.c index 921c053fc052e4f53617c6fc79491dd9d086ab8c..862c1f74a5834d687e3acdd4a93df0825082784c 100644 --- a/fs/sysv/balloc.c +++ b/fs/sysv/balloc.c @@ -231,7 +231,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb) Ecount: printk("sysv_count_free_blocks: free block count was %d, " "correcting to %d\n", sb_count, count); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { *sbi->s_free_blocks = cpu_to_fs32(sbi, count); dirty_sb(sb); } diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index 53f1b78996dd476a9ca37e3d24428303ff905179..eb963fbb7903cd2a477c877363ccb0b9d9820633 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c @@ -220,7 +220,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb) printk("sysv_count_free_inodes: " "free inode count was %d, correcting to %d\n", sb_count, count); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { *sbi->s_sb_total_free_inodes = cpu_to_fs16(SYSV_SB(sb), count); dirty_sb(sb); } diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 858fb72f9e0fa76a7b2214bb518537733bc1dea4..1c8bf9453a71f0c8b802ef61785ec12cba27e53d 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -70,7 +70,7 @@ static void sysv_put_super(struct super_block *sb) { struct sysv_sb_info *sbi = SYSV_SB(sb); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { /* XXX ext2 also updates the state here */ mark_buffer_dirty(sbi->s_bh1); if (sbi->s_bh1 != sbi->s_bh2) diff --git a/fs/sysv/super.c b/fs/sysv/super.c index eda10959714f2acad6ce5d9be82fffbe9426513b..0d56e486b39225c597fa7f2dd86f8ec54d5e25d7 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c @@ -216,7 +216,7 @@ static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh) if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) { sbi->s_type = FSTYPE_AFS; sbi->s_forced_ro = 1; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { printk("SysV FS: SCO EAFS on %s detected, " "forcing read-only mode.\n", sb->s_id); diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 8cad0b19b404cc20be28835a6c99919fa2ef9aae..a02aa59d1e245124dcead693b15cd128fa2b1f4e 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1337,7 +1337,7 @@ int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) */ return 0; - err = filemap_write_and_wait_range(inode->i_mapping, start, end); + err = file_write_and_wait_range(file, start, end); if (err) return err; inode_lock(inode); @@ -1490,7 +1490,10 @@ static int ubifs_migrate_page(struct address_space *mapping, SetPagePrivate(newpage); } - migrate_page_copy(newpage, page); + if (mode != MIGRATE_SYNC_NO_COPY) + migrate_page_copy(newpage, page); + else + migrate_page_states(newpage, page); return MIGRATEPAGE_SUCCESS; } #endif diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index bffadbb67e4753edbe10a5b67e58af9afb1da521..5496b17b959c702408c933c3a98c460042e00543 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1159,7 +1159,7 @@ static int mount_ubifs(struct ubifs_info *c) long long x, y; size_t sz; - c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY); + c->ro_mount = !!sb_rdonly(c->vfs_sb); /* Suppress error messages while probing if MS_SILENT is set */ c->probing = !!(c->vfs_sb->s_flags & MS_SILENT); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 18fdb9d90812a2849376de612ac2a52bc487324e..8dacf4f574149038909fc12abe02580bd2eab71e 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -114,7 +114,7 @@ static void udf_update_extent_cache(struct inode *inode, loff_t estart, __udf_clear_extent_cache(inode); if (pos->bh) get_bh(pos->bh); - memcpy(&iinfo->cached_extent.epos, pos, sizeof(struct extent_position)); + memcpy(&iinfo->cached_extent.epos, pos, sizeof(*pos)); iinfo->cached_extent.lstart = estart; switch (iinfo->i_alloc_type) { case ICBTAG_FLAG_AD_SHORT: @@ -1572,13 +1572,8 @@ static int udf_alloc_i_data(struct inode *inode, size_t size) { struct udf_inode_info *iinfo = UDF_I(inode); iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL); - - if (!iinfo->i_ext.i_data) { - udf_err(inode->i_sb, "(ino %ld) no free memory\n", - inode->i_ino); + if (!iinfo->i_ext.i_data) return -ENOMEM; - } - return 0; } @@ -1703,7 +1698,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) dsea->impUseLength = cpu_to_le32(sizeof(struct regid)); } eid = (struct regid *)dsea->impUse; - memset(eid, 0, sizeof(struct regid)); + memset(eid, 0, sizeof(*eid)); strcpy(eid->ident, UDF_ID_DEVELOPER); eid->identSuffix[0] = UDF_OS_CLASS_UNIX; eid->identSuffix[1] = UDF_OS_ID_LINUX; @@ -1754,7 +1749,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime); udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime); - memset(&(efe->impIdent), 0, sizeof(struct regid)); + memset(&(efe->impIdent), 0, sizeof(efe->impIdent)); strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 385ee89d58242d9ffc920b9d2cb6db55999d073b..885198dfd9f8ea8fa923edfcfccb3254802a3086 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -1184,7 +1184,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, */ ncfi.fileVersionNum = ocfi.fileVersionNum; ncfi.fileCharacteristics = ocfi.fileCharacteristics; - memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(struct long_ad)); + memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(ocfi.icb)); udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL); /* The old fid may have moved - find it again */ diff --git a/fs/udf/super.c b/fs/udf/super.c index 462ac2e9258c9e94bd79bdf87e06151667b72ce8..99cb81d0077f940a2492e8ec109d5531adfcc7e6 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -266,11 +266,8 @@ static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count) { struct udf_sb_info *sbi = UDF_SB(sb); - sbi->s_partmaps = kcalloc(count, sizeof(struct udf_part_map), - GFP_KERNEL); + sbi->s_partmaps = kcalloc(count, sizeof(*sbi->s_partmaps), GFP_KERNEL); if (!sbi->s_partmaps) { - udf_err(sb, "Unable to allocate space for %d partition maps\n", - count); sbi->s_partitions = 0; return -ENOMEM; } @@ -324,7 +321,8 @@ static void udf_sb_free_partitions(struct super_block *sb) { struct udf_sb_info *sbi = UDF_SB(sb); int i; - if (sbi->s_partmaps == NULL) + + if (!sbi->s_partmaps) return; for (i = 0; i < sbi->s_partitions; i++) udf_free_partition(&sbi->s_partmaps[i]); @@ -675,7 +673,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) sbi->s_dmode = uopt.dmode; write_unlock(&sbi->s_cred_lock); - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb)) goto out_unlock; if (*flags & MS_RDONLY) @@ -1019,7 +1017,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition, fe = udf_iget_special(sb, &addr); if (IS_ERR(fe)) { - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only\n"); else { udf_err(sb, "bitmap inode efe not found and attempted read-write mount\n"); @@ -1071,7 +1069,7 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) else bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ - if (bitmap == NULL) + if (!bitmap) return NULL; bitmap->s_nr_groups = nr_groups; @@ -1343,7 +1341,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) * writing to it (we overwrite blocks instead of relocating * them). */ - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { ret = -EACCES; goto out_bh; } @@ -2099,7 +2097,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) uopt.fmode = UDF_INVALID_MODE; uopt.dmode = UDF_INVALID_MODE; - sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); + sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) return -ENOMEM; @@ -2207,7 +2205,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) ret = -EINVAL; goto error_out; } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION && - !(sb->s_flags & MS_RDONLY)) { + !sb_rdonly(sb)) { ret = -EACCES; goto error_out; } @@ -2228,7 +2226,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) if (sbi->s_partmaps[sbi->s_partition].s_partition_flags & UDF_PART_FLAG_READ_ONLY && - !(sb->s_flags & MS_RDONLY)) { + !sb_rdonly(sb)) { ret = -EACCES; goto error_out; } @@ -2247,7 +2245,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) le16_to_cpu(ts.year), ts.month, ts.day, ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone)); } - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { udf_open_lvid(sb); lvid_open = true; } @@ -2334,7 +2332,7 @@ static void udf_put_super(struct super_block *sb) if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) unload_nls(sbi->s_nls_map); #endif - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) udf_close_lvid(sb); brelse(sbi->s_lvid_bh); udf_sb_free_partitions(sb); diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 0a4f58a5073cb63feb94c2174c56d9889d2a37a4..6440003f8ddc62ea689512f4dc25525334d2a42a 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -278,7 +278,7 @@ void ufs_error (struct super_block * sb, const char * function, uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first(uspi); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { usb1->fs_clean = UFS_FSBAD; ubh_mark_buffer_dirty(USPI_UBH(uspi)); ufs_mark_sb_dirty(sb); @@ -312,7 +312,7 @@ void ufs_panic (struct super_block * sb, const char * function, uspi = UFS_SB(sb)->s_uspi; usb1 = ubh_get_usb_first(uspi); - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { usb1->fs_clean = UFS_FSBAD; ubh_mark_buffer_dirty(USPI_UBH(uspi)); ufs_mark_sb_dirty(sb); @@ -742,7 +742,7 @@ static void ufs_put_super(struct super_block *sb) UFSD("ENTER\n"); - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) ufs_put_super_internal(sb); cancel_delayed_work_sync(&sbi->sync_work); @@ -793,7 +793,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) UFSD("ENTER\n"); #ifndef CONFIG_UFS_FS_WRITE - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n"); return -EROFS; } @@ -805,7 +805,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) sb->s_fs_info = sbi; sbi->sb = sb; - UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); + UFSD("flag %u\n", (int)(sb_rdonly(sb))); mutex_init(&sbi->s_lock); spin_lock_init(&sbi->work_lock); @@ -902,7 +902,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_sbsize = super_block_size = 2048; uspi->s_sbbase = 0; flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!silent) pr_info("ufstype=old is supported read-only\n"); sb->s_flags |= MS_RDONLY; @@ -918,7 +918,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_sbbase = 0; uspi->s_dirblksize = 1024; flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!silent) pr_info("ufstype=nextstep is supported read-only\n"); sb->s_flags |= MS_RDONLY; @@ -934,7 +934,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_sbbase = 0; uspi->s_dirblksize = 1024; flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!silent) pr_info("ufstype=nextstep-cd is supported read-only\n"); sb->s_flags |= MS_RDONLY; @@ -950,7 +950,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_sbbase = 0; uspi->s_dirblksize = 1024; flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!silent) pr_info("ufstype=openstep is supported read-only\n"); sb->s_flags |= MS_RDONLY; @@ -965,7 +965,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_sbsize = super_block_size = 2048; uspi->s_sbbase = 0; flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD; - if (!(sb->s_flags & MS_RDONLY)) { + if (!sb_rdonly(sb)) { if (!silent) pr_info("ufstype=hp is supported read-only\n"); sb->s_flags |= MS_RDONLY; @@ -1273,7 +1273,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) /* * Read cylinder group structures */ - if (!(sb->s_flags & MS_RDONLY)) + if (!sb_rdonly(sb)) if (!ufs_read_cylinder_structures(sb)) goto failed; @@ -1328,7 +1328,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) return -EINVAL; } - if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + if ((bool)(*mount_flags & MS_RDONLY) == sb_rdonly(sb)) { UFS_SB(sb)->s_mount_opt = new_mount_opt; mutex_unlock(&UFS_SB(sb)->s_lock); return 0; diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index cadcd12a3d35f6ba5deb54df94c995b19d3d34a8..1c713fd5b3e67966c3d998979d2c30eb8e14ba07 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -109,27 +109,24 @@ static int userfaultfd_wake_function(wait_queue_entry_t *wq, unsigned mode, goto out; WRITE_ONCE(uwq->waken, true); /* - * The implicit smp_mb__before_spinlock in try_to_wake_up() - * renders uwq->waken visible to other CPUs before the task is - * waken. + * The Program-Order guarantees provided by the scheduler + * ensure uwq->waken is visible before the task is woken. */ ret = wake_up_state(wq->private, mode); - if (ret) + if (ret) { /* * Wake only once, autoremove behavior. * - * After the effect of list_del_init is visible to the - * other CPUs, the waitqueue may disappear from under - * us, see the !list_empty_careful() in - * handle_userfault(). try_to_wake_up() has an - * implicit smp_mb__before_spinlock, and the - * wq->private is read before calling the extern - * function "wake_up_state" (which in turns calls - * try_to_wake_up). While the spin_lock;spin_unlock; - * wouldn't be enough, the smp_mb__before_spinlock is - * enough to avoid an explicit smp_mb() here. + * After the effect of list_del_init is visible to the other + * CPUs, the waitqueue may disappear from under us, see the + * !list_empty_careful() in handle_userfault(). + * + * try_to_wake_up() has an implicit smp_mb(), and the + * wq->private is read before calling the extern function + * "wake_up_state" (which in turns calls try_to_wake_up). */ list_del_init(&wq->entry); + } out: return ret; } @@ -181,7 +178,8 @@ static inline void msg_init(struct uffd_msg *msg) static inline struct uffd_msg userfault_msg(unsigned long address, unsigned int flags, - unsigned long reason) + unsigned long reason, + unsigned int features) { struct uffd_msg msg; msg_init(&msg); @@ -205,6 +203,8 @@ static inline struct uffd_msg userfault_msg(unsigned long address, * write protect fault. */ msg.arg.pagefault.flags |= UFFD_PAGEFAULT_FLAG_WP; + if (features & UFFD_FEATURE_THREAD_ID) + msg.arg.pagefault.feat.ptid = task_pid_vnr(current); return msg; } @@ -373,13 +373,34 @@ int handle_userfault(struct vm_fault *vmf, unsigned long reason) VM_BUG_ON(reason & ~(VM_UFFD_MISSING|VM_UFFD_WP)); VM_BUG_ON(!(reason & VM_UFFD_MISSING) ^ !!(reason & VM_UFFD_WP)); + if (ctx->features & UFFD_FEATURE_SIGBUS) + goto out; + /* * If it's already released don't get it. This avoids to loop * in __get_user_pages if userfaultfd_release waits on the * caller of handle_userfault to release the mmap_sem. */ - if (unlikely(ACCESS_ONCE(ctx->released))) + if (unlikely(ACCESS_ONCE(ctx->released))) { + /* + * Don't return VM_FAULT_SIGBUS in this case, so a non + * cooperative manager can close the uffd after the + * last UFFDIO_COPY, without risking to trigger an + * involuntary SIGBUS if the process was starting the + * userfaultfd while the userfaultfd was still armed + * (but after the last UFFDIO_COPY). If the uffd + * wasn't already closed when the userfault reached + * this point, that would normally be solved by + * userfaultfd_must_wait returning 'false'. + * + * If we were to return VM_FAULT_SIGBUS here, the non + * cooperative manager would be instead forced to + * always call UFFDIO_UNREGISTER before it can safely + * close the uffd. + */ + ret = VM_FAULT_NOPAGE; goto out; + } /* * Check that we can return VM_FAULT_RETRY. @@ -422,7 +443,8 @@ int handle_userfault(struct vm_fault *vmf, unsigned long reason) init_waitqueue_func_entry(&uwq.wq, userfaultfd_wake_function); uwq.wq.private = current; - uwq.msg = userfault_msg(vmf->address, vmf->flags, reason); + uwq.msg = userfault_msg(vmf->address, vmf->flags, reason, + ctx->features); uwq.ctx = ctx; uwq.waken = false; @@ -566,6 +588,12 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, break; if (ACCESS_ONCE(ctx->released) || fatal_signal_pending(current)) { + /* + * &ewq->wq may be queued in fork_event, but + * __remove_wait_queue ignores the head + * parameter. It would be a problem if it + * didn't. + */ __remove_wait_queue(&ctx->event_wqh, &ewq->wq); if (ewq->msg.event == UFFD_EVENT_FORK) { struct userfaultfd_ctx *new; @@ -854,6 +882,9 @@ static int userfaultfd_release(struct inode *inode, struct file *file) __wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, &range); spin_unlock(&ctx->fault_pending_wqh.lock); + /* Flush pending events that may still wait on event_wqh */ + wake_up_all(&ctx->event_wqh); + wake_up_poll(&ctx->fd_wqh, POLLHUP); userfaultfd_ctx_put(ctx); return 0; @@ -1036,6 +1067,12 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait, (unsigned long) uwq->msg.arg.reserved.reserved1; list_move(&uwq->wq.entry, &fork_event); + /* + * fork_nctx can be freed as soon as + * we drop the lock, unless we take a + * reference on it. + */ + userfaultfd_ctx_get(fork_nctx); spin_unlock(&ctx->event_wqh.lock); ret = 0; break; @@ -1066,19 +1103,53 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait, if (!ret && msg->event == UFFD_EVENT_FORK) { ret = resolve_userfault_fork(ctx, fork_nctx, msg); + spin_lock(&ctx->event_wqh.lock); + if (!list_empty(&fork_event)) { + /* + * The fork thread didn't abort, so we can + * drop the temporary refcount. + */ + userfaultfd_ctx_put(fork_nctx); - if (!ret) { - spin_lock(&ctx->event_wqh.lock); - if (!list_empty(&fork_event)) { - uwq = list_first_entry(&fork_event, - typeof(*uwq), - wq.entry); - list_del(&uwq->wq.entry); - __add_wait_queue(&ctx->event_wqh, &uwq->wq); + uwq = list_first_entry(&fork_event, + typeof(*uwq), + wq.entry); + /* + * If fork_event list wasn't empty and in turn + * the event wasn't already released by fork + * (the event is allocated on fork kernel + * stack), put the event back to its place in + * the event_wq. fork_event head will be freed + * as soon as we return so the event cannot + * stay queued there no matter the current + * "ret" value. + */ + list_del(&uwq->wq.entry); + __add_wait_queue(&ctx->event_wqh, &uwq->wq); + + /* + * Leave the event in the waitqueue and report + * error to userland if we failed to resolve + * the userfault fork. + */ + if (likely(!ret)) userfaultfd_event_complete(ctx, uwq); - } - spin_unlock(&ctx->event_wqh.lock); + } else { + /* + * Here the fork thread aborted and the + * refcount from the fork thread on fork_nctx + * has already been released. We still hold + * the reference we took before releasing the + * lock above. If resolve_userfault_fork + * failed we've to drop it because the + * fork_nctx has to be freed in such case. If + * it succeeded we'll hold it because the new + * uffd references it. + */ + if (ret) + userfaultfd_ctx_put(fork_nctx); } + spin_unlock(&ctx->event_wqh.lock); } return ret; @@ -1194,7 +1265,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, struct uffdio_register __user *user_uffdio_register; unsigned long vm_flags, new_flags; bool found; - bool non_anon_pages; + bool basic_ioctls; unsigned long start, end, vma_end; user_uffdio_register = (struct uffdio_register __user *) arg; @@ -1260,7 +1331,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, * Search for not compatible vmas. */ found = false; - non_anon_pages = false; + basic_ioctls = false; for (cur = vma; cur && cur->vm_start < end; cur = cur->vm_next) { cond_resched(); @@ -1299,8 +1370,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, /* * Note vmas containing huge pages */ - if (is_vm_hugetlb_page(cur) || vma_is_shmem(cur)) - non_anon_pages = true; + if (is_vm_hugetlb_page(cur)) + basic_ioctls = true; found = true; } @@ -1371,7 +1442,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, * userland which ioctls methods are guaranteed to * succeed on this range. */ - if (put_user(non_anon_pages ? UFFD_API_RANGE_IOCTLS_BASIC : + if (put_user(basic_ioctls ? UFFD_API_RANGE_IOCTLS_BASIC : UFFD_API_RANGE_IOCTLS, &user_uffdio_register->ioctls)) ret = -EFAULT; @@ -1597,7 +1668,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx, uffdio_copy.len); mmput(ctx->mm); } else { - return -ENOSPC; + return -ESRCH; } if (unlikely(put_user(ret, &user_uffdio_copy->copy))) return -EFAULT; @@ -1643,6 +1714,8 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx, ret = mfill_zeropage(ctx->mm, uffdio_zeropage.range.start, uffdio_zeropage.range.len); mmput(ctx->mm); + } else { + return -ESRCH; } if (unlikely(put_user(ret, &user_uffdio_zeropage->zeropage))) return -EFAULT; diff --git a/fs/utimes.c b/fs/utimes.c index 6571d8c848a04054e7517f7ad29b55d5b9022232..51edb9f9507c409269dd8722a6c49303ef926f84 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -22,7 +22,7 @@ */ SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times) { - struct timespec tv[2]; + struct timespec64 tv[2]; if (times) { if (get_user(tv[0].tv_sec, ×->actime) || @@ -44,7 +44,7 @@ static bool nsec_valid(long nsec) return nsec >= 0 && nsec <= 999999999; } -static int utimes_common(const struct path *path, struct timespec *times) +static int utimes_common(const struct path *path, struct timespec64 *times) { int error; struct iattr newattrs; @@ -115,7 +115,7 @@ static int utimes_common(const struct path *path, struct timespec *times) * must be owner or have write permission. * Else, update from *times, must be owner or super user. */ -long do_utimes(int dfd, const char __user *filename, struct timespec *times, +long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags) { int error = -EINVAL; @@ -167,10 +167,11 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times, SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename, struct timespec __user *, utimes, int, flags) { - struct timespec tstimes[2]; + struct timespec64 tstimes[2]; if (utimes) { - if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) + if ((get_timespec64(&tstimes[0], &utimes[0]) || + get_timespec64(&tstimes[1], &utimes[1]))) return -EFAULT; /* Nothing to do, we must not even check the path. */ @@ -186,7 +187,7 @@ SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, struct timeval __user *, utimes) { struct timeval times[2]; - struct timespec tstimes[2]; + struct timespec64 tstimes[2]; if (utimes) { if (copy_from_user(×, utimes, sizeof(times))) @@ -224,7 +225,7 @@ SYSCALL_DEFINE2(utimes, char __user *, filename, COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename, struct compat_utimbuf __user *, t) { - struct timespec tv[2]; + struct timespec64 tv[2]; if (t) { if (get_user(tv[0].tv_sec, &t->actime) || @@ -238,11 +239,11 @@ COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename, COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags) { - struct timespec tv[2]; + struct timespec64 tv[2]; if (t) { - if (compat_get_timespec(&tv[0], &t[0]) || - compat_get_timespec(&tv[1], &t[1])) + if (compat_get_timespec64(&tv[0], &t[0]) || + compat_get_timespec64(&tv[1], &t[1])) return -EFAULT; if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) @@ -253,7 +254,7 @@ COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filena COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t) { - struct timespec tv[2]; + struct timespec64 tv[2]; if (t) { if (get_user(tv[0].tv_sec, &t[0].tv_sec) || diff --git a/fs/xattr.c b/fs/xattr.c index 464c94bf65f9e55339ec9d4bc515ec990691deb7..61cd28ba25f364df5af103277924befb6d4a39a0 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -23,6 +23,7 @@ #include #include +#include "internal.h" static const char * strcmp_prefix(const char *a, const char *a_prefix) @@ -249,7 +250,7 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value, } memcpy(value, buffer, len); out: - security_release_secctx(buffer, len); + kfree(buffer); out_noalloc: return len; } @@ -441,6 +442,12 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) posix_acl_fix_xattr_from_user(kvalue, size); + else if (strcmp(kname, XATTR_NAME_CAPS) == 0) { + error = cap_convert_nscap(d, &kvalue, size); + if (error < 0) + goto out; + size = error; + } } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -496,10 +503,10 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, if (!f.file) return error; audit_file(f.file); - error = mnt_want_write_file(f.file); + error = mnt_want_write_file_path(f.file); if (!error) { error = setxattr(f.file->f_path.dentry, name, value, size, flags); - mnt_drop_write_file(f.file); + mnt_drop_write_file_path(f.file); } fdput(f); return error; @@ -728,10 +735,10 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) if (!f.file) return error; audit_file(f.file); - error = mnt_want_write_file(f.file); + error = mnt_want_write_file_path(f.file); if (!error) { error = removexattr(f.file->f_path.dentry, name); - mnt_drop_write_file(f.file); + mnt_drop_write_file_path(f.file); } fdput(f); return error; diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index b008ff3250eba4f3884e18841c4c316b7e7cbf50..df3e600835e8de81e69ac295b06fae6fecefd7a4 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -156,7 +156,8 @@ __xfs_ag_resv_free( trace_xfs_ag_resv_free(pag, type, 0); resv = xfs_perag_resv(pag, type); - pag->pag_mount->m_ag_max_usable += resv->ar_asked; + if (pag->pag_agno == 0) + pag->pag_mount->m_ag_max_usable += resv->ar_asked; /* * AGFL blocks are always considered "free", so whatever * was reserved at mount time must be given back at umount. @@ -216,7 +217,14 @@ __xfs_ag_resv_init( return error; } - mp->m_ag_max_usable -= ask; + /* + * Reduce the maximum per-AG allocation length by however much we're + * trying to reserve for an AG. Since this is a filesystem-wide + * counter, we only make the adjustment for AG 0. This assumes that + * there aren't any AGs hungrier for per-AG reservation than AG 0. + */ + if (pag->pag_agno == 0) + mp->m_ag_max_usable -= ask; resv = xfs_perag_resv(pag, type); resv->ar_asked = ask; diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index de7b9bd30becc560195de8010261691750896549..6249c92671debe20a45e3cb0577360552e36d523 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -328,20 +328,19 @@ xfs_attr_set( */ xfs_defer_init(args.dfops, args.firstblock); error = xfs_attr_shortform_to_leaf(&args); - if (!error) - error = xfs_defer_finish(&args.trans, args.dfops, dp); - if (error) { - args.trans = NULL; - xfs_defer_cancel(&dfops); - goto out; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args.dfops, dp); + error = xfs_defer_finish(&args.trans, args.dfops); + if (error) + goto out_defer_cancel; /* * Commit the leaf transformation. We'll need another (linked) * transaction to add the new attribute to the leaf. */ - error = xfs_trans_roll(&args.trans, dp); + error = xfs_trans_roll_inode(&args.trans, dp); if (error) goto out; @@ -373,6 +372,9 @@ xfs_attr_set( return error; +out_defer_cancel: + xfs_defer_cancel(&dfops); + args.trans = NULL; out: if (args.trans) xfs_trans_cancel(args.trans); @@ -593,19 +595,18 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) */ xfs_defer_init(args->dfops, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) - error = xfs_defer_finish(&args->trans, args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - return error; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; /* * Commit the current trans (including the inode) and start * a new one. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) return error; @@ -620,7 +621,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * Commit the transaction that added the attr name so that * later routines can manage their own transactions. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) return error; @@ -684,20 +685,18 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) xfs_defer_init(args->dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) - error = xfs_defer_finish(&args->trans, - args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - return error; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; } /* * Commit the remove and start the next trans in series. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); } else if (args->rmtblkno > 0) { /* @@ -706,6 +705,10 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) error = xfs_attr3_leaf_clearflag(args); } return error; +out_defer_cancel: + xfs_defer_cancel(args->dfops); + args->trans = NULL; + return error; } /* @@ -747,15 +750,18 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) xfs_defer_init(args->dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) - error = xfs_defer_finish(&args->trans, args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - return error; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; } return 0; +out_defer_cancel: + xfs_defer_cancel(args->dfops); + args->trans = NULL; + return error; } /* @@ -872,20 +878,18 @@ xfs_attr_node_addname(xfs_da_args_t *args) state = NULL; xfs_defer_init(args->dfops, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) - error = xfs_defer_finish(&args->trans, - args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - goto out; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; /* * Commit the node conversion and start the next * trans in the chain. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) goto out; @@ -900,13 +904,12 @@ xfs_attr_node_addname(xfs_da_args_t *args) */ xfs_defer_init(args->dfops, args->firstblock); error = xfs_da3_split(state); - if (!error) - error = xfs_defer_finish(&args->trans, args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - goto out; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; } else { /* * Addition succeeded, update Btree hashvals. @@ -925,7 +928,7 @@ xfs_attr_node_addname(xfs_da_args_t *args) * Commit the leaf addition or btree split and start the next * trans in the chain. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) goto out; @@ -999,20 +1002,18 @@ xfs_attr_node_addname(xfs_da_args_t *args) if (retval && (state->path.active > 1)) { xfs_defer_init(args->dfops, args->firstblock); error = xfs_da3_join(state); - if (!error) - error = xfs_defer_finish(&args->trans, - args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - goto out; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; } /* * Commit and start the next trans in the chain. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) goto out; @@ -1032,6 +1033,10 @@ xfs_attr_node_addname(xfs_da_args_t *args) if (error) return error; return retval; +out_defer_cancel: + xfs_defer_cancel(args->dfops); + args->trans = NULL; + goto out; } /* @@ -1122,17 +1127,16 @@ xfs_attr_node_removename(xfs_da_args_t *args) if (retval && (state->path.active > 1)) { xfs_defer_init(args->dfops, args->firstblock); error = xfs_da3_join(state); - if (!error) - error = xfs_defer_finish(&args->trans, args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - goto out; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; /* * Commit the Btree join operation and start a new trans. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) goto out; } @@ -1156,14 +1160,12 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_defer_init(args->dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) - error = xfs_defer_finish(&args->trans, - args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - goto out; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; } else xfs_trans_brelse(args->trans, bp); } @@ -1172,6 +1174,10 @@ xfs_attr_node_removename(xfs_da_args_t *args) out: xfs_da_state_free(state); return error; +out_defer_cancel: + xfs_defer_cancel(args->dfops); + args->trans = NULL; + goto out; } /* diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index c6c15e5717e42a2afd20710d12e021e87136985b..5c16db86b38ffbcbb2c7e400cd04a4e84230a34e 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -2608,7 +2608,7 @@ xfs_attr3_leaf_clearflag( /* * Commit the flag value change and start the next trans in series. */ - return xfs_trans_roll(&args->trans, args->dp); + return xfs_trans_roll_inode(&args->trans, args->dp); } /* @@ -2659,7 +2659,7 @@ xfs_attr3_leaf_setflag( /* * Commit the flag value change and start the next trans in series. */ - return xfs_trans_roll(&args->trans, args->dp); + return xfs_trans_roll_inode(&args->trans, args->dp); } /* @@ -2777,7 +2777,7 @@ xfs_attr3_leaf_flipflags( /* * Commit the flag value change and start the next trans in series. */ - error = xfs_trans_roll(&args->trans, args->dp); + error = xfs_trans_roll_inode(&args->trans, args->dp); return error; } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 5236d8e451463c7140d6527adb8439d9c3f4c05c..d56caf037ca0e7948035f5e987caff7a1a0d8e07 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -467,13 +467,12 @@ xfs_attr_rmtval_set( error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, args->total, &map, &nmap, args->dfops); - if (!error) - error = xfs_defer_finish(&args->trans, args->dfops, dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - return error; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && @@ -484,7 +483,7 @@ xfs_attr_rmtval_set( /* * Start the next trans in the chain. */ - error = xfs_trans_roll(&args->trans, dp); + error = xfs_trans_roll_inode(&args->trans, dp); if (error) return error; } @@ -539,6 +538,10 @@ xfs_attr_rmtval_set( } ASSERT(valuelen == 0); return 0; +out_defer_cancel: + xfs_defer_cancel(args->dfops); + args->trans = NULL; + return error; } /* @@ -609,21 +612,23 @@ xfs_attr_rmtval_remove( error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, args->firstblock, args->dfops, &done); - if (!error) - error = xfs_defer_finish(&args->trans, args->dfops, - args->dp); - if (error) { - args->trans = NULL; - xfs_defer_cancel(args->dfops); - return error; - } + if (error) + goto out_defer_cancel; + xfs_defer_ijoin(args->dfops, args->dp); + error = xfs_defer_finish(&args->trans, args->dfops); + if (error) + goto out_defer_cancel; /* * Close out trans and start the next one in the chain. */ - error = xfs_trans_roll(&args->trans, args->dp); + error = xfs_trans_roll_inode(&args->trans, args->dp); if (error) return error; } return 0; +out_defer_cancel: + xfs_defer_cancel(args->dfops); + args->trans = NULL; + return error; } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index c09c16b1ad3b8b1f883e2ee93b9fcc275c7ed63c..044a363119bead470113a35227a8ee6923ebab65 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -49,7 +49,6 @@ #include "xfs_rmap.h" #include "xfs_ag_resv.h" #include "xfs_refcount.h" -#include "xfs_rmap_btree.h" #include "xfs_icache.h" @@ -192,12 +191,8 @@ xfs_bmap_worst_indlen( int maxrecs; /* maximum record count at this level */ xfs_mount_t *mp; /* mount structure */ xfs_filblks_t rval; /* return value */ - xfs_filblks_t orig_len; mp = ip->i_mount; - - /* Calculate the worst-case size of the bmbt. */ - orig_len = len; maxrecs = mp->m_bmap_dmxr[0]; for (level = 0, rval = 0; level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); @@ -205,20 +200,12 @@ xfs_bmap_worst_indlen( len += maxrecs - 1; do_div(len, maxrecs); rval += len; - if (len == 1) { - rval += XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - + if (len == 1) + return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - level - 1; - break; - } if (level == 0) maxrecs = mp->m_bmap_dmxr[1]; } - - /* Calculate the worst-case size of the rmapbt. */ - if (xfs_sb_version_hasrmapbt(&mp->m_sb)) - rval += 1 + xfs_rmapbt_calc_size(mp, orig_len) + - mp->m_rmap_maxlevels; - return rval; } @@ -579,7 +566,7 @@ xfs_bmap_validate_ret( #else #define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0) -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do { } while (0) #endif /* DEBUG */ /* @@ -880,7 +867,7 @@ xfs_bmap_local_to_extents( xfs_ifork_t *ifp; /* inode fork pointer */ xfs_alloc_arg_t args; /* allocation arguments */ xfs_buf_t *bp; /* buffer for extent block */ - xfs_bmbt_rec_host_t *ep; /* extent record pointer */ + struct xfs_bmbt_irec rec; /* * We don't want to deal with the case of keeping inode data inline yet. @@ -943,9 +930,12 @@ xfs_bmap_local_to_extents( xfs_bmap_local_to_extents_empty(ip, whichfork); flags |= XFS_ILOG_CORE; - xfs_iext_add(ifp, 0, 1); - ep = xfs_iext_get_ext(ifp, 0); - xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); + rec.br_startoff = 0; + rec.br_startblock = args.fsbno; + rec.br_blockcount = 1; + rec.br_state = XFS_EXT_NORM; + xfs_iext_insert(ip, 0, 1, &rec, 0); + trace_xfs_bmap_post_update(ip, 0, whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0, _THIS_IP_); @@ -1196,7 +1186,7 @@ xfs_bmap_add_attrfork( xfs_log_sb(tp); } - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto bmap_cancel; error = xfs_trans_commit(tp); @@ -1356,7 +1346,6 @@ xfs_bmap_first_unused( xfs_fileoff_t lastaddr; /* last block number seen */ xfs_fileoff_t lowest; /* lowest useful block */ xfs_fileoff_t max; /* starting useful block */ - xfs_fileoff_t off; /* offset for this block */ xfs_extnum_t nextents; /* number of extent entries */ ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || @@ -1373,16 +1362,19 @@ xfs_bmap_first_unused( lowest = *first_unused; nextents = xfs_iext_count(ifp); for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { - xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); - off = xfs_bmbt_get_startoff(ep); + struct xfs_bmbt_irec got; + + xfs_iext_get_extent(ifp, idx, &got); + /* * See if the hole before this extent will work. */ - if (off >= lowest + len && off - max >= len) { + if (got.br_startoff >= lowest + len && + got.br_startoff - max >= len) { *first_unused = max; return 0; } - lastaddr = off + xfs_bmbt_get_blockcount(ep); + lastaddr = got.br_startoff + got.br_blockcount; max = XFS_FILEOFF_MAX(lastaddr, lowest); } *first_unused = max; @@ -4918,7 +4910,7 @@ xfs_bmap_del_extent_delay( da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, got->br_blockcount), da_old); got->br_startblock = nullstartblock((int)da_new); - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got); + xfs_iext_update_extent(ifp, *idx, got); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); break; case BMAP_RIGHT_CONTIG: @@ -4930,7 +4922,7 @@ xfs_bmap_del_extent_delay( da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, got->br_blockcount), da_old); got->br_startblock = nullstartblock((int)da_new); - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got); + xfs_iext_update_extent(ifp, *idx, got); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); break; case 0: @@ -4956,7 +4948,7 @@ xfs_bmap_del_extent_delay( del->br_blockcount); got->br_startblock = nullstartblock((int)got_indlen); - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got); + xfs_iext_update_extent(ifp, *idx, got); trace_xfs_bmap_post_update(ip, *idx, 0, _THIS_IP_); new.br_startoff = del_endoff; @@ -5026,7 +5018,7 @@ xfs_bmap_del_extent_cow( got->br_startoff = del_endoff; got->br_blockcount -= del->br_blockcount; got->br_startblock = del->br_startblock + del->br_blockcount; - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got); + xfs_iext_update_extent(ifp, *idx, got); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); break; case BMAP_RIGHT_CONTIG: @@ -5035,7 +5027,7 @@ xfs_bmap_del_extent_cow( */ trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); got->br_blockcount -= del->br_blockcount; - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got); + xfs_iext_update_extent(ifp, *idx, got); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); break; case 0: @@ -5044,7 +5036,7 @@ xfs_bmap_del_extent_cow( */ trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); got->br_blockcount = del->br_startoff - got->br_startoff; - xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got); + xfs_iext_update_extent(ifp, *idx, got); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); new.br_startoff = del_endoff; @@ -5876,32 +5868,26 @@ xfs_bmse_merge( int whichfork, xfs_fileoff_t shift, /* shift fsb */ int current_ext, /* idx of gotp */ - struct xfs_bmbt_rec_host *gotp, /* extent to shift */ - struct xfs_bmbt_rec_host *leftp, /* preceding extent */ + struct xfs_bmbt_irec *got, /* extent to shift */ + struct xfs_bmbt_irec *left, /* preceding extent */ struct xfs_btree_cur *cur, - int *logflags) /* output */ + int *logflags, /* output */ + struct xfs_defer_ops *dfops) { - struct xfs_bmbt_irec got; - struct xfs_bmbt_irec left; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + struct xfs_bmbt_irec new; xfs_filblks_t blockcount; int error, i; struct xfs_mount *mp = ip->i_mount; - xfs_bmbt_get_all(gotp, &got); - xfs_bmbt_get_all(leftp, &left); - blockcount = left.br_blockcount + got.br_blockcount; + blockcount = left->br_blockcount + got->br_blockcount; ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ASSERT(xfs_bmse_can_merge(&left, &got, shift)); + ASSERT(xfs_bmse_can_merge(left, got, shift)); - /* - * Merge the in-core extents. Note that the host record pointers and - * current_ext index are invalid once the extent has been removed via - * xfs_iext_remove(). - */ - xfs_bmbt_set_blockcount(leftp, blockcount); - xfs_iext_remove(ip, current_ext, 1, 0); + new = *left; + new.br_blockcount = blockcount; /* * Update the on-disk extent count, the btree if necessary and log the @@ -5912,12 +5898,12 @@ xfs_bmse_merge( *logflags |= XFS_ILOG_CORE; if (!cur) { *logflags |= XFS_ILOG_DEXT; - return 0; + goto done; } /* lookup and remove the extent to merge */ - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, - got.br_blockcount, &i); + error = xfs_bmbt_lookup_eq(cur, got->br_startoff, got->br_startblock, + got->br_blockcount, &i); if (error) return error; XFS_WANT_CORRUPTED_RETURN(mp, i == 1); @@ -5928,16 +5914,28 @@ xfs_bmse_merge( XFS_WANT_CORRUPTED_RETURN(mp, i == 1); /* lookup and update size of the previous extent */ - error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, - left.br_blockcount, &i); + error = xfs_bmbt_lookup_eq(cur, left->br_startoff, left->br_startblock, + left->br_blockcount, &i); if (error) return error; XFS_WANT_CORRUPTED_RETURN(mp, i == 1); - left.br_blockcount = blockcount; + error = xfs_bmbt_update(cur, new.br_startoff, new.br_startblock, + new.br_blockcount, new.br_state); + if (error) + return error; + +done: + xfs_iext_update_extent(ifp, current_ext - 1, &new); + xfs_iext_remove(ip, current_ext, 1, 0); - return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, - left.br_blockcount, left.br_state); + /* update reverse mapping. rmap functions merge the rmaps for us */ + error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got); + if (error) + return error; + memcpy(&new, got, sizeof(new)); + new.br_startoff = left->br_startoff + left->br_blockcount; + return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new); } /* @@ -5949,7 +5947,7 @@ xfs_bmse_shift_one( int whichfork, xfs_fileoff_t offset_shift_fsb, int *current_ext, - struct xfs_bmbt_rec_host *gotp, + struct xfs_bmbt_irec *got, struct xfs_btree_cur *cur, int *logflags, enum shift_direction direction, @@ -5958,9 +5956,7 @@ xfs_bmse_shift_one( struct xfs_ifork *ifp; struct xfs_mount *mp; xfs_fileoff_t startoff; - struct xfs_bmbt_rec_host *adj_irecp; - struct xfs_bmbt_irec got; - struct xfs_bmbt_irec adj_irec; + struct xfs_bmbt_irec adj_irec, new; int error; int i; int total_extents; @@ -5969,13 +5965,11 @@ xfs_bmse_shift_one( ifp = XFS_IFORK_PTR(ip, whichfork); total_extents = xfs_iext_count(ifp); - xfs_bmbt_get_all(gotp, &got); - /* delalloc extents should be prevented by caller */ - XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock)); + XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got->br_startblock)); if (direction == SHIFT_LEFT) { - startoff = got.br_startoff - offset_shift_fsb; + startoff = got->br_startoff - offset_shift_fsb; /* * Check for merge if we've got an extent to the left, @@ -5983,46 +5977,39 @@ xfs_bmse_shift_one( * of the file for the shift. */ if (!*current_ext) { - if (got.br_startoff < offset_shift_fsb) + if (got->br_startoff < offset_shift_fsb) return -EINVAL; goto update_current_ext; } + /* - * grab the left extent and check for a large - * enough hole. + * grab the left extent and check for a large enough hole. */ - adj_irecp = xfs_iext_get_ext(ifp, *current_ext - 1); - xfs_bmbt_get_all(adj_irecp, &adj_irec); - - if (startoff < - adj_irec.br_startoff + adj_irec.br_blockcount) + xfs_iext_get_extent(ifp, *current_ext - 1, &adj_irec); + if (startoff < adj_irec.br_startoff + adj_irec.br_blockcount) return -EINVAL; /* check whether to merge the extent or shift it down */ - if (xfs_bmse_can_merge(&adj_irec, &got, - offset_shift_fsb)) { - error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb, - *current_ext, gotp, adj_irecp, - cur, logflags); - if (error) - return error; - adj_irec = got; - goto update_rmap; + if (xfs_bmse_can_merge(&adj_irec, got, offset_shift_fsb)) { + return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, + *current_ext, got, &adj_irec, + cur, logflags, dfops); } } else { - startoff = got.br_startoff + offset_shift_fsb; + startoff = got->br_startoff + offset_shift_fsb; /* nothing to move if this is the last extent */ if (*current_ext >= (total_extents - 1)) goto update_current_ext; + /* * If this is not the last extent in the file, make sure there * is enough room between current extent and next extent for * accommodating the shift. */ - adj_irecp = xfs_iext_get_ext(ifp, *current_ext + 1); - xfs_bmbt_get_all(adj_irecp, &adj_irec); - if (startoff + got.br_blockcount > adj_irec.br_startoff) + xfs_iext_get_extent(ifp, *current_ext + 1, &adj_irec); + if (startoff + got->br_blockcount > adj_irec.br_startoff) return -EINVAL; + /* * Unlike a left shift (which involves a hole punch), * a right shift does not modify extent neighbors @@ -6030,45 +6017,48 @@ xfs_bmse_shift_one( * in this scenario. Check anyways and warn if we * encounter two extents that could be one. */ - if (xfs_bmse_can_merge(&got, &adj_irec, offset_shift_fsb)) + if (xfs_bmse_can_merge(got, &adj_irec, offset_shift_fsb)) WARN_ON_ONCE(1); } + /* * Increment the extent index for the next iteration, update the start * offset of the in-core extent and update the btree if applicable. */ update_current_ext: - if (direction == SHIFT_LEFT) - (*current_ext)++; - else - (*current_ext)--; - xfs_bmbt_set_startoff(gotp, startoff); *logflags |= XFS_ILOG_CORE; - adj_irec = got; - if (!cur) { + + new = *got; + new.br_startoff = startoff; + + if (cur) { + error = xfs_bmbt_lookup_eq(cur, got->br_startoff, + got->br_startblock, got->br_blockcount, &i); + if (error) + return error; + XFS_WANT_CORRUPTED_RETURN(mp, i == 1); + + error = xfs_bmbt_update(cur, new.br_startoff, + new.br_startblock, new.br_blockcount, + new.br_state); + if (error) + return error; + } else { *logflags |= XFS_ILOG_DEXT; - goto update_rmap; } - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, - got.br_blockcount, &i); - if (error) - return error; - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); + xfs_iext_update_extent(ifp, *current_ext, &new); - got.br_startoff = startoff; - error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, - got.br_blockcount, got.br_state); - if (error) - return error; + if (direction == SHIFT_LEFT) + (*current_ext)++; + else + (*current_ext)--; -update_rmap: /* update reverse mapping */ - error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, &adj_irec); + error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got); if (error) return error; - adj_irec.br_startoff = startoff; - return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &adj_irec); + return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new); } /* @@ -6095,7 +6085,6 @@ xfs_bmap_shift_extents( int num_exts) { struct xfs_btree_cur *cur = NULL; - struct xfs_bmbt_rec_host *gotp; struct xfs_bmbt_irec got; struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; @@ -6122,7 +6111,6 @@ xfs_bmap_shift_extents( ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(direction == SHIFT_LEFT || direction == SHIFT_RIGHT); - ASSERT(*next_fsb != NULLFSBLOCK || direction == SHIFT_RIGHT); ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS)) { @@ -6154,10 +6142,26 @@ xfs_bmap_shift_extents( * In case of first right shift, we need to initialize next_fsb */ if (*next_fsb == NULLFSBLOCK) { - gotp = xfs_iext_get_ext(ifp, total_extents - 1); - xfs_bmbt_get_all(gotp, &got); + ASSERT(direction == SHIFT_RIGHT); + + current_ext = total_extents - 1; + xfs_iext_get_extent(ifp, current_ext, &got); + if (stop_fsb > got.br_startoff) { + *done = 1; + goto del_cursor; + } *next_fsb = got.br_startoff; - if (stop_fsb > *next_fsb) { + } else { + /* + * Look up the extent index for the fsb where we start shifting. We can + * henceforth iterate with current_ext as extent list changes are locked + * out via ilock. + * + * If next_fsb lies in a hole beyond which there are no extents we are + * done. + */ + if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, ¤t_ext, + &got)) { *done = 1; goto del_cursor; } @@ -6165,37 +6169,26 @@ xfs_bmap_shift_extents( /* Lookup the extent index at which we have to stop */ if (direction == SHIFT_RIGHT) { - gotp = xfs_iext_bno_to_ext(ifp, stop_fsb, &stop_extent); + struct xfs_bmbt_irec s; + + xfs_iext_lookup_extent(ip, ifp, stop_fsb, &stop_extent, &s); /* Make stop_extent exclusive of shift range */ stop_extent--; - } else + if (current_ext <= stop_extent) { + error = -EIO; + goto del_cursor; + } + } else { stop_extent = total_extents; - - /* - * Look up the extent index for the fsb where we start shifting. We can - * henceforth iterate with current_ext as extent list changes are locked - * out via ilock. - * - * gotp can be null in 2 cases: 1) if there are no extents or 2) - * *next_fsb lies in a hole beyond which there are no extents. Either - * way, we are done. - */ - gotp = xfs_iext_bno_to_ext(ifp, *next_fsb, ¤t_ext); - if (!gotp) { - *done = 1; - goto del_cursor; - } - - /* some sanity checking before we finally start shifting extents */ - if ((direction == SHIFT_LEFT && current_ext >= stop_extent) || - (direction == SHIFT_RIGHT && current_ext <= stop_extent)) { - error = -EIO; - goto del_cursor; + if (current_ext >= stop_extent) { + error = -EIO; + goto del_cursor; + } } while (nexts++ < num_exts) { error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, - ¤t_ext, gotp, cur, &logflags, + ¤t_ext, &got, cur, &logflags, direction, dfops); if (error) goto del_cursor; @@ -6213,13 +6206,11 @@ xfs_bmap_shift_extents( *next_fsb = NULLFSBLOCK; break; } - gotp = xfs_iext_get_ext(ifp, current_ext); + xfs_iext_get_extent(ifp, current_ext, &got); } - if (!*done) { - xfs_bmbt_get_all(gotp, &got); + if (!*done) *next_fsb = got.br_startoff; - } del_cursor: if (cur) @@ -6248,7 +6239,6 @@ xfs_bmap_split_extent_at( { int whichfork = XFS_DATA_FORK; struct xfs_btree_cur *cur = NULL; - struct xfs_bmbt_rec_host *gotp; struct xfs_bmbt_irec got; struct xfs_bmbt_irec new; /* split extent */ struct xfs_mount *mp = ip->i_mount; @@ -6280,21 +6270,10 @@ xfs_bmap_split_extent_at( } /* - * gotp can be null in 2 cases: 1) if there are no extents - * or 2) split_fsb lies in a hole beyond which there are - * no extents. Either way, we are done. - */ - gotp = xfs_iext_bno_to_ext(ifp, split_fsb, ¤t_ext); - if (!gotp) - return 0; - - xfs_bmbt_get_all(gotp, &got); - - /* - * Check split_fsb lies in a hole or the start boundary offset - * of the extent. + * If there are not extents, or split_fsb lies in a hole we are done. */ - if (got.br_startoff >= split_fsb) + if (!xfs_iext_lookup_extent(ip, ifp, split_fsb, ¤t_ext, &got) || + got.br_startoff >= split_fsb) return 0; gotblkcnt = split_fsb - got.br_startoff; @@ -6317,8 +6296,8 @@ xfs_bmap_split_extent_at( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); } - xfs_bmbt_set_blockcount(gotp, gotblkcnt); got.br_blockcount = gotblkcnt; + xfs_iext_update_extent(ifp, current_ext, &got); logflags = XFS_ILOG_CORE; if (cur) { @@ -6402,7 +6381,7 @@ xfs_bmap_split_extent( if (error) goto out; - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out; @@ -6452,7 +6431,7 @@ __xfs_bmap_add( bi->bi_whichfork = whichfork; bi->bi_bmap = *bmap; - error = xfs_defer_join(dfops, bi->bi_owner); + error = xfs_defer_ijoin(dfops, bi->bi_owner); if (error) { kmem_free(bi); return error; diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 85de2251301457244181bec3a6f2993010a6dccd..a6331ffa51e3e69f04a789de7f335da99ab856dd 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -858,6 +858,7 @@ xfs_bmbt_change_owner( cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); if (!cur) return -ENOMEM; + cur->bc_private.b.flags |= XFS_BTCUR_BPRV_INVALID_OWNER; error = xfs_btree_change_owner(cur, new_owner, buffer_list); xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index e0bcc4a59efdac646947f917f8c5d2a7713997fb..5bfb88261c7e9542a0ba2fca0463c264a36be629 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -1791,6 +1791,7 @@ xfs_btree_lookup_get_block( /* Check the inode owner since the verifiers don't. */ if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) && + !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_INVALID_OWNER) && (cur->bc_flags & XFS_BTREE_LONG_PTRS) && be64_to_cpu((*blkp)->bb_u.l.bb_owner) != cur->bc_private.b.ip->i_ino) @@ -4451,10 +4452,15 @@ xfs_btree_block_change_owner( /* modify the owner */ block = xfs_btree_get_block(cur, level, &bp); - if (cur->bc_flags & XFS_BTREE_LONG_PTRS) + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { + if (block->bb_u.l.bb_owner == cpu_to_be64(bbcoi->new_owner)) + return 0; block->bb_u.l.bb_owner = cpu_to_be64(bbcoi->new_owner); - else + } else { + if (block->bb_u.s.bb_owner == cpu_to_be32(bbcoi->new_owner)) + return 0; block->bb_u.s.bb_owner = cpu_to_be32(bbcoi->new_owner); + } /* * If the block is a root block hosted in an inode, we might not have a @@ -4463,16 +4469,19 @@ xfs_btree_block_change_owner( * block is formatted into the on-disk inode fork. We still change it, * though, so everything is consistent in memory. */ - if (bp) { - if (cur->bc_tp) { - xfs_trans_ordered_buf(cur->bc_tp, bp); + if (!bp) { + ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); + ASSERT(level == cur->bc_nlevels - 1); + return 0; + } + + if (cur->bc_tp) { + if (!xfs_trans_ordered_buf(cur->bc_tp, bp)) { xfs_btree_log_block(cur, bp, XFS_BB_OWNER); - } else { - xfs_buf_delwri_queue(bp, bbcoi->buffer_list); + return -EAGAIN; } } else { - ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); - ASSERT(level == cur->bc_nlevels - 1); + xfs_buf_delwri_queue(bp, bbcoi->buffer_list); } return 0; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 9c95e965cfe53e3c61edbab6a0e6f0a076f82a4f..f2a88c3b11595222d5290781ce91005cd150cdd8 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -233,7 +233,8 @@ typedef struct xfs_btree_cur short forksize; /* fork's inode space */ char whichfork; /* data or attr fork */ char flags; /* flags */ -#define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ +#define XFS_BTCUR_BPRV_WASDEL (1<<0) /* was delayed */ +#define XFS_BTCUR_BPRV_INVALID_OWNER (1<<1) /* for ext swap */ } b; } bc_private; /* per-btree type data */ } xfs_btree_cur_t; diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 5c2929f94bd3bf27411f860b57697b9d899312d1..072ebfe1d6aeb3e00e306a06d71a1b478382f3ad 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -240,23 +240,19 @@ xfs_defer_trans_abort( STATIC int xfs_defer_trans_roll( struct xfs_trans **tp, - struct xfs_defer_ops *dop, - struct xfs_inode *ip) + struct xfs_defer_ops *dop) { int i; int error; - /* Log all the joined inodes except the one we passed in. */ - for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) { - if (dop->dop_inodes[i] == ip) - continue; + /* Log all the joined inodes. */ + for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); - } trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); /* Roll the transaction. */ - error = xfs_trans_roll(tp, ip); + error = xfs_trans_roll(tp); if (error) { trace_xfs_defer_trans_roll_error((*tp)->t_mountp, dop, error); xfs_defer_trans_abort(*tp, dop, error); @@ -264,12 +260,9 @@ xfs_defer_trans_roll( } dop->dop_committed = true; - /* Rejoin the joined inodes except the one we passed in. */ - for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) { - if (dop->dop_inodes[i] == ip) - continue; + /* Rejoin the joined inodes. */ + for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); - } return error; } @@ -284,11 +277,10 @@ xfs_defer_has_unfinished_work( /* * Add this inode to the deferred op. Each joined inode is relogged - * each time we roll the transaction, in addition to any inode passed - * to xfs_defer_finish(). + * each time we roll the transaction. */ int -xfs_defer_join( +xfs_defer_ijoin( struct xfs_defer_ops *dop, struct xfs_inode *ip) { @@ -317,8 +309,7 @@ xfs_defer_join( int xfs_defer_finish( struct xfs_trans **tp, - struct xfs_defer_ops *dop, - struct xfs_inode *ip) + struct xfs_defer_ops *dop) { struct xfs_defer_pending *dfp; struct list_head *li; @@ -337,7 +328,7 @@ xfs_defer_finish( xfs_defer_intake_work(*tp, dop); /* Roll the transaction. */ - error = xfs_defer_trans_roll(tp, dop, ip); + error = xfs_defer_trans_roll(tp, dop); if (error) goto out; diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index f6e93ef0bffe8a4620a136b1e7f523bb1343a941..d4f046dd44bd4ae434d8104991d0327f2d2b9fc7 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -72,12 +72,11 @@ struct xfs_defer_ops { void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); -int xfs_defer_finish(struct xfs_trans **tp, struct xfs_defer_ops *dop, - struct xfs_inode *ip); +int xfs_defer_finish(struct xfs_trans **tp, struct xfs_defer_ops *dop); void xfs_defer_cancel(struct xfs_defer_ops *dop); void xfs_defer_init(struct xfs_defer_ops *dop, xfs_fsblock_t *fbp); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); -int xfs_defer_join(struct xfs_defer_ops *dop, struct xfs_inode *ip); +int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); /* Description of a deferred type. */ struct xfs_defer_op_type { diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index ffd5a15d1bb6d0955633d4e1f61f6a84aa79f3f7..988bb3f3144664216bdf6880fd79838785a7b8db 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -378,8 +378,6 @@ xfs_ialloc_inode_init( * transaction and pin the log appropriately. */ xfs_trans_ordered_buf(tp, fbuf); - xfs_trans_log_buf(tp, fbuf, 0, - BBTOB(fbuf->b_length) - 1); } } else { fbuf->b_flags |= XBF_DONE; @@ -1133,6 +1131,7 @@ xfs_dialloc_ag_inobt( int error; int offset; int i, j; + int searchdistance = 10; pag = xfs_perag_get(mp, agno); @@ -1159,7 +1158,6 @@ xfs_dialloc_ag_inobt( if (pagno == agno) { int doneleft; /* done, to the left */ int doneright; /* done, to the right */ - int searchdistance = 10; error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); if (error) @@ -1220,21 +1218,9 @@ xfs_dialloc_ag_inobt( /* * Loop until we find an inode chunk with a free inode. */ - while (!doneleft || !doneright) { + while (--searchdistance > 0 && (!doneleft || !doneright)) { int useleft; /* using left inode chunk this time */ - if (!--searchdistance) { - /* - * Not in range - save last search - * location and allocate a new inode - */ - xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); - pag->pagl_leftrec = trec.ir_startino; - pag->pagl_rightrec = rec.ir_startino; - pag->pagl_pagino = pagino; - goto newino; - } - /* figure out the closer block if both are valid. */ if (!doneleft && !doneright) { useleft = pagino - @@ -1246,13 +1232,13 @@ xfs_dialloc_ag_inobt( /* free inodes to the left? */ if (useleft && trec.ir_freecount) { - rec = trec; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); cur = tcur; pag->pagl_leftrec = trec.ir_startino; pag->pagl_rightrec = rec.ir_startino; pag->pagl_pagino = pagino; + rec = trec; goto alloc_inode; } @@ -1278,26 +1264,37 @@ xfs_dialloc_ag_inobt( goto error1; } - /* - * We've reached the end of the btree. because - * we are only searching a small chunk of the - * btree each search, there is obviously free - * inodes closer to the parent inode than we - * are now. restart the search again. - */ - pag->pagl_pagino = NULLAGINO; - pag->pagl_leftrec = NULLAGINO; - pag->pagl_rightrec = NULLAGINO; - xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); - goto restart_pagno; + if (searchdistance <= 0) { + /* + * Not in range - save last search + * location and allocate a new inode + */ + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + pag->pagl_leftrec = trec.ir_startino; + pag->pagl_rightrec = rec.ir_startino; + pag->pagl_pagino = pagino; + + } else { + /* + * We've reached the end of the btree. because + * we are only searching a small chunk of the + * btree each search, there is obviously free + * inodes closer to the parent inode than we + * are now. restart the search again. + */ + pag->pagl_pagino = NULLAGINO; + pag->pagl_leftrec = NULLAGINO; + pag->pagl_rightrec = NULLAGINO; + xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + goto restart_pagno; + } } /* * In a different AG from the parent. * See if the most recently allocated block has any free. */ -newino: if (agi->agi_newino != cpu_to_be32(NULLAGINO)) { error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino), XFS_LOOKUP_EQ, &i); diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0e80f34fe97c509cef3eef61ff7237c20a19bdd4..31840ca24018e6fa2ea2fa3cf66209270dc1ed16 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -1499,14 +1499,11 @@ xfs_iext_realloc_indirect( xfs_ifork_t *ifp, /* inode fork pointer */ int new_size) /* new indirection array size */ { - int nlists; /* number of irec's (ex lists) */ - int size; /* current indirection array size */ - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - size = nlists * sizeof(xfs_ext_irec_t); ASSERT(ifp->if_real_bytes); - ASSERT((new_size >= 0) && (new_size != size)); + ASSERT((new_size >= 0) && + (new_size != ((ifp->if_real_bytes / XFS_IEXT_BUFSZ) * + sizeof(xfs_ext_irec_t)))); if (new_size == 0) { xfs_iext_destroy(ifp); } else { @@ -2023,3 +2020,15 @@ xfs_iext_get_extent( xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), gotp); return true; } + +void +xfs_iext_update_extent( + struct xfs_ifork *ifp, + xfs_extnum_t idx, + struct xfs_bmbt_irec *gotp) +{ + ASSERT(idx >= 0); + ASSERT(idx < xfs_iext_count(ifp)); + + xfs_bmbt_set_all(xfs_iext_get_ext(ifp, idx), gotp); +} diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 7fb8365326d1a745583c4f133bc5a63668316b33..11af705219f6d7dacace149dd8d6b00f2a794ef3 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -187,6 +187,8 @@ bool xfs_iext_lookup_extent(struct xfs_inode *ip, xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp); bool xfs_iext_get_extent(struct xfs_ifork *ifp, xfs_extnum_t idx, struct xfs_bmbt_irec *gotp); +void xfs_iext_update_extent(struct xfs_ifork *ifp, xfs_extnum_t idx, + struct xfs_bmbt_irec *gotp); extern struct kmem_zone *xfs_ifork_zone; diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 45b1c3b4e047b1682ded2e0aca55f7160163986e..9d5406b4f66343391fd55bc580f27afc03bdf779 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1679,7 +1679,7 @@ xfs_refcount_recover_cow_leftovers( xfs_bmap_add_free(mp, &dfops, fsb, rr->rr_rrec.rc_blockcount, NULL); - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_defer; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 6bf120bb1a17da7f3b571964ee58719c9315fae3..f18e5932aec4bfe5f1e1b3fb0d69d1b32c540b16 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -80,16 +80,29 @@ xfs_find_bdev_for_inode( return mp->m_ddev_targp->bt_bdev; } +struct dax_device * +xfs_find_daxdev_for_inode( + struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; + + if (XFS_IS_REALTIME_INODE(ip)) + return mp->m_rtdev_targp->bt_daxdev; + else + return mp->m_ddev_targp->bt_daxdev; +} + /* * We're now finished for good with this page. Update the page state via the * associated buffer_heads, paying attention to the start and end offsets that * we need to process on the page. * - * Landmine Warning: bh->b_end_io() will call end_page_writeback() on the last - * buffer in the IO. Once it does this, it is unsafe to access the bufferhead or - * the page at all, as we may be racing with memory reclaim and it can free both - * the bufferhead chain and the page as it will see the page as clean and - * unused. + * Note that we open code the action in end_buffer_async_write here so that we + * only have to iterate over the buffers attached to the page once. This is not + * only more efficient, but also ensures that we only calls end_page_writeback + * at the end of the iteration, and thus avoids the pitfall of having the page + * and buffers potentially freed after every call to end_buffer_async_write. */ static void xfs_finish_page_writeback( @@ -97,29 +110,44 @@ xfs_finish_page_writeback( struct bio_vec *bvec, int error) { - unsigned int end = bvec->bv_offset + bvec->bv_len - 1; - struct buffer_head *head, *bh, *next; + struct buffer_head *head = page_buffers(bvec->bv_page), *bh = head; + bool busy = false; unsigned int off = 0; - unsigned int bsize; + unsigned long flags; ASSERT(bvec->bv_offset < PAGE_SIZE); ASSERT((bvec->bv_offset & (i_blocksize(inode) - 1)) == 0); - ASSERT(end < PAGE_SIZE); + ASSERT(bvec->bv_offset + bvec->bv_len <= PAGE_SIZE); ASSERT((bvec->bv_len & (i_blocksize(inode) - 1)) == 0); - bh = head = page_buffers(bvec->bv_page); - - bsize = bh->b_size; + local_irq_save(flags); + bit_spin_lock(BH_Uptodate_Lock, &head->b_state); do { - if (off > end) - break; - next = bh->b_this_page; - if (off < bvec->bv_offset) - goto next_bh; - bh->b_end_io(bh, !error); -next_bh: - off += bsize; - } while ((bh = next) != head); + if (off >= bvec->bv_offset && + off < bvec->bv_offset + bvec->bv_len) { + ASSERT(buffer_async_write(bh)); + ASSERT(bh->b_end_io == NULL); + + if (error) { + mark_buffer_write_io_error(bh); + clear_buffer_uptodate(bh); + SetPageError(bvec->bv_page); + } else { + set_buffer_uptodate(bh); + } + clear_buffer_async_write(bh); + unlock_buffer(bh); + } else if (buffer_async_write(bh)) { + ASSERT(buffer_locked(bh)); + busy = true; + } + off += bh->b_size; + } while ((bh = bh->b_this_page) != head); + bit_spin_unlock(BH_Uptodate_Lock, &head->b_state); + local_irq_restore(flags); + + if (!busy) + end_page_writeback(bvec->bv_page); } /* @@ -133,8 +161,10 @@ xfs_destroy_ioend( int error) { struct inode *inode = ioend->io_inode; - struct bio *last = ioend->io_bio; - struct bio *bio, *next; + struct bio *bio = &ioend->io_inline_bio; + struct bio *last = ioend->io_bio, *next; + u64 start = bio->bi_iter.bi_sector; + bool quiet = bio_flagged(bio, BIO_QUIET); for (bio = &ioend->io_inline_bio; bio; bio = next) { struct bio_vec *bvec; @@ -155,6 +185,11 @@ xfs_destroy_ioend( bio_put(bio); } + + if (unlikely(error && !quiet)) { + xfs_err_ratelimited(XFS_I(inode)->i_mount, + "writeback error on sector %llu", start); + } } /* @@ -308,7 +343,8 @@ xfs_end_io( error = xfs_reflink_end_cow(ip, offset, size); break; case XFS_IO_UNWRITTEN: - error = xfs_iomap_write_unwritten(ip, offset, size); + /* writeback should never update isize */ + error = xfs_iomap_write_unwritten(ip, offset, size, false); break; default: ASSERT(!xfs_ioend_is_append(ioend) || ioend->io_append_trans); @@ -423,7 +459,8 @@ xfs_start_buffer_writeback( ASSERT(!buffer_delay(bh)); ASSERT(!buffer_unwritten(bh)); - mark_buffer_async_write(bh); + bh->b_end_io = NULL; + set_buffer_async_write(bh); set_buffer_uptodate(bh); clear_buffer_dirty(bh); } @@ -517,7 +554,7 @@ xfs_init_bio_from_bh( struct buffer_head *bh) { bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); - bio->bi_bdev = bh->b_bdev; + bio_set_dev(bio, bh->b_bdev); } static struct xfs_ioend * diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index cc174ec6c2fd088198b7db6b904e4ff185e2ab52..88c85ea63da030ce8d02629ad6aa1fe0bb3971ad 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size); extern void xfs_count_page_state(struct page *, int *, int *); extern struct block_device *xfs_find_bdev_for_inode(struct inode *); +extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *); #endif /* __XFS_AOPS_H__ */ diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index be0b79d8900f0f4fb9cb29fff6c2ccb2cca38f55..ebd66b19fbfc365982500e67aa654c3838b57886 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -97,7 +97,7 @@ xfs_attr3_leaf_freextent( /* * Roll to next transaction. */ - error = xfs_trans_roll(trans, dp); + error = xfs_trans_roll_inode(trans, dp); if (error) return error; } @@ -308,7 +308,7 @@ xfs_attr3_node_inactive( /* * Atomically commit the whole invalidate stuff. */ - error = xfs_trans_roll(trans, dp); + error = xfs_trans_roll_inode(trans, dp); if (error) return error; } @@ -375,7 +375,7 @@ xfs_attr3_root_inactive( /* * Commit the invalidate and start the next transaction. */ - error = xfs_trans_roll(trans, dp); + error = xfs_trans_roll_inode(trans, dp); return error; } diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index 88073910fa5d41c70c96c61dcdb08883cb94d05b..dd136f7275e4a2efede5a7612de243ddd1349abf 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -502,7 +502,7 @@ xfs_bui_recover( } /* Finish transaction, free inodes. */ - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto err_dfops; diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 93e955262d07e1467cba2013c90013f9e452ddf9..e9db7fc95b70bb4a2ba531af65d8718f73b61721 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -222,22 +222,21 @@ xfs_bmap_eof( * Count leaf blocks given a range of extent records. Delayed allocation * extents are not counted towards the totals. */ -STATIC void +xfs_extnum_t xfs_bmap_count_leaves( struct xfs_ifork *ifp, - xfs_extnum_t *numrecs, xfs_filblks_t *count) { - xfs_extnum_t i; - xfs_extnum_t nr_exts = xfs_iext_count(ifp); - - for (i = 0; i < nr_exts; i++) { - xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, i); - if (!isnullstartblock(xfs_bmbt_get_startblock(frp))) { - (*numrecs)++; - *count += xfs_bmbt_get_blockcount(frp); + struct xfs_bmbt_irec got; + xfs_extnum_t numrecs = 0, i = 0; + + while (xfs_iext_get_extent(ifp, i++, &got)) { + if (!isnullstartblock(got.br_startblock)) { + *count += got.br_blockcount; + numrecs++; } } + return numrecs; } /* @@ -370,7 +369,7 @@ xfs_bmap_count_blocks( switch (XFS_IFORK_FORMAT(ip, whichfork)) { case XFS_DINODE_FMT_EXTENTS: - xfs_bmap_count_leaves(ifp, nextents, count); + *nextents = xfs_bmap_count_leaves(ifp, count); return 0; case XFS_DINODE_FMT_BTREE: if (!(ifp->if_flags & XFS_IFEXTENTS)) { @@ -1136,7 +1135,7 @@ xfs_alloc_file_space( /* * Complete the transaction */ - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto error0; @@ -1202,7 +1201,8 @@ xfs_unmap_extent( if (error) goto out_bmap_cancel; - error = xfs_defer_finish(&tp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -1459,7 +1459,19 @@ xfs_shift_file_space( return error; /* - * The extent shiting code works on extent granularity. So, if + * Clean out anything hanging around in the cow fork now that + * we've flushed all the dirty data out to disk to avoid having + * CoW extents at the wrong offsets. + */ + if (xfs_is_reflink_inode(ip)) { + error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF, + true); + if (error) + return error; + } + + /* + * The extent shifting code works on extent granularity. So, if * stop_fsb is not the starting block of extent, we need to split * the extent at stop_fsb. */ @@ -1496,7 +1508,7 @@ xfs_shift_file_space( if (error) goto out_bmap_cancel; - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -1777,7 +1789,8 @@ xfs_swap_extent_rmap( if (error) goto out_defer; - error = xfs_defer_finish(tpp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(tpp, &dfops); if (error) goto out_defer; @@ -1840,29 +1853,18 @@ xfs_swap_extent_forks( } /* - * Before we've swapped the forks, lets set the owners of the forks - * appropriately. We have to do this as we are demand paging the btree - * buffers, and so the validation done on read will expect the owner - * field to be correctly set. Once we change the owners, we can swap the - * inode forks. + * Btree format (v3) inodes have the inode number stamped in the bmbt + * block headers. We can't start changing the bmbt blocks until the + * inode owner change is logged so recovery does the right thing in the + * event of a crash. Set the owner change log flags now and leave the + * bmbt scan as the last step. */ if (ip->i_d.di_version == 3 && - ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { + ip->i_d.di_format == XFS_DINODE_FMT_BTREE) (*target_log_flags) |= XFS_ILOG_DOWNER; - error = xfs_bmbt_change_owner(tp, ip, XFS_DATA_FORK, - tip->i_ino, NULL); - if (error) - return error; - } - if (tip->i_d.di_version == 3 && - tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { + tip->i_d.di_format == XFS_DINODE_FMT_BTREE) (*src_log_flags) |= XFS_ILOG_DOWNER; - error = xfs_bmbt_change_owner(tp, tip, XFS_DATA_FORK, - ip->i_ino, NULL); - if (error) - return error; - } /* * Swap the data forks of the inodes @@ -1940,6 +1942,48 @@ xfs_swap_extent_forks( return 0; } +/* + * Fix up the owners of the bmbt blocks to refer to the current inode. The + * change owner scan attempts to order all modified buffers in the current + * transaction. In the event of ordered buffer failure, the offending buffer is + * physically logged as a fallback and the scan returns -EAGAIN. We must roll + * the transaction in this case to replenish the fallback log reservation and + * restart the scan. This process repeats until the scan completes. + */ +static int +xfs_swap_change_owner( + struct xfs_trans **tpp, + struct xfs_inode *ip, + struct xfs_inode *tmpip) +{ + int error; + struct xfs_trans *tp = *tpp; + + do { + error = xfs_bmbt_change_owner(tp, ip, XFS_DATA_FORK, ip->i_ino, + NULL); + /* success or fatal error */ + if (error != -EAGAIN) + break; + + error = xfs_trans_roll(tpp); + if (error) + break; + tp = *tpp; + + /* + * Redirty both inodes so they can relog and keep the log tail + * moving forward. + */ + xfs_trans_ijoin(tp, ip, 0); + xfs_trans_ijoin(tp, tmpip, 0); + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + xfs_trans_log_inode(tp, tmpip, XFS_ILOG_CORE); + } while (true); + + return error; +} + int xfs_swap_extents( struct xfs_inode *ip, /* target inode */ @@ -1954,7 +1998,7 @@ xfs_swap_extents( int lock_flags; struct xfs_ifork *cowfp; uint64_t f; - int resblks; + int resblks = 0; /* * Lock the inodes against other IO, page faults and truncate to @@ -2002,11 +2046,8 @@ xfs_swap_extents( XFS_SWAP_RMAP_SPACE_RES(mp, XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK), XFS_DATA_FORK); - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, - 0, 0, &tp); - } else - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, - 0, 0, &tp); + } + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp); if (error) goto out_unlock; @@ -2081,16 +2122,53 @@ xfs_swap_extents( ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK; + } + + /* Swap the cow forks. */ + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + xfs_extnum_t extnum; + + ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); + ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); + + extnum = ip->i_cnextents; + ip->i_cnextents = tip->i_cnextents; + tip->i_cnextents = extnum; + cowfp = ip->i_cowfp; ip->i_cowfp = tip->i_cowfp; tip->i_cowfp = cowfp; - xfs_inode_set_cowblocks_tag(ip); - xfs_inode_set_cowblocks_tag(tip); + + if (ip->i_cowfp && ip->i_cnextents) + xfs_inode_set_cowblocks_tag(ip); + else + xfs_inode_clear_cowblocks_tag(ip); + if (tip->i_cowfp && tip->i_cnextents) + xfs_inode_set_cowblocks_tag(tip); + else + xfs_inode_clear_cowblocks_tag(tip); } xfs_trans_log_inode(tp, ip, src_log_flags); xfs_trans_log_inode(tp, tip, target_log_flags); + /* + * The extent forks have been swapped, but crc=1,rmapbt=0 filesystems + * have inode number owner values in the bmbt blocks that still refer to + * the old inode. Scan each bmbt to fix up the owner values with the + * inode number of the current inode. + */ + if (src_log_flags & XFS_ILOG_DOWNER) { + error = xfs_swap_change_owner(&tp, ip, tip); + if (error) + goto out_trans_cancel; + } + if (target_log_flags & XFS_ILOG_DOWNER) { + error = xfs_swap_change_owner(&tp, tip, ip); + if (error) + goto out_trans_cancel; + } + /* * If this is a synchronous mount, make sure that the * transaction goes to disk before returning to the user. diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index 0cede104357170425e1864d63cc934596977a166..0eaa81dc49be674137cda51a3364b54721c10d58 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h @@ -70,6 +70,7 @@ int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb); +xfs_extnum_t xfs_bmap_count_leaves(struct xfs_ifork *ifp, xfs_filblks_t *count); int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, xfs_extnum_t *nextents, xfs_filblks_t *count); diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 72f038492ba8cdb2bd609fd19949d96b95c8ede0..2f97c12ca75e4d5554b94b7a195b4dca53f90174 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1258,8 +1258,6 @@ xfs_buf_ioapply_map( int size; int offset; - total_nr_pages = bp->b_page_count; - /* skip the pages in the buffer before the start offset */ page_index = 0; offset = *buf_offset; @@ -1281,7 +1279,7 @@ xfs_buf_ioapply_map( nr_pages = min(total_nr_pages, BIO_MAX_PAGES); bio = bio_alloc(GFP_NOIO, nr_pages); - bio->bi_bdev = bp->b_target->bt_bdev; + bio_set_dev(bio, bp->b_target->bt_bdev); bio->bi_iter.bi_sector = sector; bio->bi_end_io = xfs_buf_bio_end_io; bio->bi_private = bp; @@ -1802,7 +1800,8 @@ xfs_setsize_buftarg_early( xfs_buftarg_t * xfs_alloc_buftarg( struct xfs_mount *mp, - struct block_device *bdev) + struct block_device *bdev, + struct dax_device *dax_dev) { xfs_buftarg_t *btp; @@ -1811,6 +1810,7 @@ xfs_alloc_buftarg( btp->bt_mount = mp; btp->bt_dev = bdev->bd_dev; btp->bt_bdev = bdev; + btp->bt_daxdev = dax_dev; if (xfs_setsize_buftarg_early(btp, bdev)) goto error; diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 20721261dae5ee4b7dff4c8a70d82439b8982920..bf71507ddb1659ec6991d5ba0c721ee01da7b210 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t; typedef struct xfs_buftarg { dev_t bt_dev; struct block_device *bt_bdev; + struct dax_device *bt_daxdev; struct xfs_mount *bt_mount; unsigned int bt_meta_sectorsize; size_t bt_meta_sectormask; @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset) * Handling of buftargs. */ extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *, - struct block_device *); + struct block_device *, struct dax_device *); extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); extern void xfs_wait_buftarg(xfs_buftarg_t *); extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int); diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index f6a8422e9562cd476537869eebc4abf59a3f9bdb..e0a0af0946f23bd84944256141967526044b2468 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -29,6 +29,7 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_log.h" +#include "xfs_inode.h" kmem_zone_t *xfs_buf_item_zone; @@ -322,6 +323,8 @@ xfs_buf_item_format( ASSERT((bip->bli_flags & XFS_BLI_STALE) || (xfs_blft_from_flags(&bip->__bli_format) > XFS_BLFT_UNKNOWN_BUF && xfs_blft_from_flags(&bip->__bli_format) < XFS_BLFT_MAX_BUF)); + ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED) || + (bip->bli_flags & XFS_BLI_STALE)); /* @@ -346,16 +349,6 @@ xfs_buf_item_format( bip->bli_flags &= ~XFS_BLI_INODE_BUF; } - if ((bip->bli_flags & (XFS_BLI_ORDERED|XFS_BLI_STALE)) == - XFS_BLI_ORDERED) { - /* - * The buffer has been logged just to order it. It is not being - * included in the transaction commit, so don't format it. - */ - trace_xfs_buf_item_format_ordered(bip); - return; - } - for (i = 0; i < bip->bli_format_count; i++) { xfs_buf_item_format_segment(bip, lv, &vecp, offset, &bip->bli_formats[i]); @@ -574,26 +567,20 @@ xfs_buf_item_unlock( { struct xfs_buf_log_item *bip = BUF_ITEM(lip); struct xfs_buf *bp = bip->bli_buf; - bool clean; - bool aborted; - int flags; + bool aborted = !!(lip->li_flags & XFS_LI_ABORTED); + bool hold = !!(bip->bli_flags & XFS_BLI_HOLD); + bool dirty = !!(bip->bli_flags & XFS_BLI_DIRTY); +#if defined(DEBUG) || defined(XFS_WARN) + bool ordered = !!(bip->bli_flags & XFS_BLI_ORDERED); +#endif /* Clear the buffer's association with this transaction. */ bp->b_transp = NULL; /* - * If this is a transaction abort, don't return early. Instead, allow - * the brelse to happen. Normally it would be done for stale - * (cancelled) buffers at unpin time, but we'll never go through the - * pin/unpin cycle if we abort inside commit. + * The per-transaction state has been copied above so clear it from the + * bli. */ - aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false; - /* - * Before possibly freeing the buf item, copy the per-transaction state - * so we can reference it safely later after clearing it from the - * buffer log item. - */ - flags = bip->bli_flags; bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD | XFS_BLI_ORDERED); /* @@ -601,7 +588,7 @@ xfs_buf_item_unlock( * unlock the buffer and free the buf item when the buffer is unpinned * for the last time. */ - if (flags & XFS_BLI_STALE) { + if (bip->bli_flags & XFS_BLI_STALE) { trace_xfs_buf_item_unlock_stale(bip); ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL); if (!aborted) { @@ -619,20 +606,11 @@ xfs_buf_item_unlock( * regardless of whether it is dirty or not. A dirty abort implies a * shutdown, anyway. * - * Ordered buffers are dirty but may have no recorded changes, so ensure - * we only release clean items here. + * The bli dirty state should match whether the blf has logged segments + * except for ordered buffers, where only the bli should be dirty. */ - clean = (flags & XFS_BLI_DIRTY) ? false : true; - if (clean) { - int i; - for (i = 0; i < bip->bli_format_count; i++) { - if (!xfs_bitmap_empty(bip->bli_formats[i].blf_data_map, - bip->bli_formats[i].blf_map_size)) { - clean = false; - break; - } - } - } + ASSERT((!ordered && dirty == xfs_buf_item_dirty_format(bip)) || + (ordered && dirty && !xfs_buf_item_dirty_format(bip))); /* * Clean buffers, by definition, cannot be in the AIL. However, aborted @@ -651,11 +629,11 @@ xfs_buf_item_unlock( ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); xfs_trans_ail_remove(lip, SHUTDOWN_LOG_IO_ERROR); xfs_buf_item_relse(bp); - } else if (clean) + } else if (!dirty) xfs_buf_item_relse(bp); } - if (!(flags & XFS_BLI_HOLD)) + if (!hold) xfs_buf_relse(bp); } @@ -945,14 +923,22 @@ xfs_buf_item_log( /* - * Return 1 if the buffer has been logged or ordered in a transaction (at any - * point, not just the current transaction) and 0 if not. + * Return true if the buffer has any ranges logged/dirtied by a transaction, + * false otherwise. */ -uint -xfs_buf_item_dirty( - xfs_buf_log_item_t *bip) +bool +xfs_buf_item_dirty_format( + struct xfs_buf_log_item *bip) { - return (bip->bli_flags & XFS_BLI_DIRTY); + int i; + + for (i = 0; i < bip->bli_format_count; i++) { + if (!xfs_bitmap_empty(bip->bli_formats[i].blf_data_map, + bip->bli_formats[i].blf_map_size)) + return true; + } + + return false; } STATIC void @@ -1054,6 +1040,31 @@ xfs_buf_do_callbacks( } } +/* + * Invoke the error state callback for each log item affected by the failed I/O. + * + * If a metadata buffer write fails with a non-permanent error, the buffer is + * eventually resubmitted and so the completion callbacks are not run. The error + * state may need to be propagated to the log items attached to the buffer, + * however, so the next AIL push of the item knows hot to handle it correctly. + */ +STATIC void +xfs_buf_do_callbacks_fail( + struct xfs_buf *bp) +{ + struct xfs_log_item *next; + struct xfs_log_item *lip = bp->b_fspriv; + struct xfs_ail *ailp = lip->li_ailp; + + spin_lock(&ailp->xa_lock); + for (; lip; lip = next) { + next = lip->li_bio_list; + if (lip->li_ops->iop_error) + lip->li_ops->iop_error(lip, bp); + } + spin_unlock(&ailp->xa_lock); +} + static bool xfs_buf_iodone_callback_error( struct xfs_buf *bp) @@ -1123,7 +1134,11 @@ xfs_buf_iodone_callback_error( if ((mp->m_flags & XFS_MOUNT_UNMOUNTING) && mp->m_fail_unmount) goto permanent_error; - /* still a transient error, higher layers will retry */ + /* + * Still a transient error, run IO completion failure callbacks and let + * the higher layers retry the buffer. + */ + xfs_buf_do_callbacks_fail(bp); xfs_buf_ioerror(bp, 0); xfs_buf_relse(bp); return true; @@ -1204,3 +1219,31 @@ xfs_buf_iodone( xfs_trans_ail_delete(ailp, lip, SHUTDOWN_CORRUPT_INCORE); xfs_buf_item_free(BUF_ITEM(lip)); } + +/* + * Requeue a failed buffer for writeback + * + * Return true if the buffer has been re-queued properly, false otherwise + */ +bool +xfs_buf_resubmit_failed_buffers( + struct xfs_buf *bp, + struct xfs_log_item *lip, + struct list_head *buffer_list) +{ + struct xfs_log_item *next; + + /* + * Clear XFS_LI_FAILED flag from all items before resubmit + * + * XFS_LI_FAILED set/clear is protected by xa_lock, caller this + * function already have it acquired + */ + for (; lip; lip = next) { + next = lip->li_bio_list; + xfs_clear_li_failed(lip); + } + + /* Add this buffer back to the delayed write list */ + return xfs_buf_delwri_queue(bp, buffer_list); +} diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index f7eba99d19dde9404c1517633fd8f34f16a36599..9690ce62c9a7f63bbc2a4b485617199cc14253c0 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h @@ -64,12 +64,15 @@ typedef struct xfs_buf_log_item { int xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); void xfs_buf_item_relse(struct xfs_buf *); void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint); -uint xfs_buf_item_dirty(xfs_buf_log_item_t *); +bool xfs_buf_item_dirty_format(struct xfs_buf_log_item *); void xfs_buf_attach_iodone(struct xfs_buf *, void(*)(struct xfs_buf *, xfs_log_item_t *), xfs_log_item_t *); void xfs_buf_iodone_callbacks(struct xfs_buf *); void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *); +bool xfs_buf_resubmit_failed_buffers(struct xfs_buf *, + struct xfs_log_item *, + struct list_head *); extern kmem_zone_t *xfs_buf_item_zone; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index fd2ef8c2c9a74baf955e579fb3a3ff25be386be7..cd82429d8df76d572838e7363e2ff28208fd7adf 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -383,7 +383,7 @@ xfs_qm_dqalloc( xfs_trans_bhold(tp, bp); - error = xfs_defer_finish(tpp, &dfops, NULL); + error = xfs_defer_finish(tpp, &dfops); if (error) goto error1; diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 2f4feb959bfb46812678b65e262270b2fc55842a..eaf86f55b7f2156c351aa26fd0190871ef1772bd 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -57,6 +57,7 @@ static unsigned int xfs_errortag_random_default[] = { XFS_RANDOM_AG_RESV_CRITICAL, XFS_RANDOM_DROP_WRITES, XFS_RANDOM_LOG_BAD_CRC, + XFS_RANDOM_LOG_ITEM_PIN, }; struct xfs_errortag_attr { @@ -161,6 +162,7 @@ XFS_ERRORTAG_ATTR_RW(bmap_finish_one, XFS_ERRTAG_BMAP_FINISH_ONE); XFS_ERRORTAG_ATTR_RW(ag_resv_critical, XFS_ERRTAG_AG_RESV_CRITICAL); XFS_ERRORTAG_ATTR_RW(drop_writes, XFS_ERRTAG_DROP_WRITES); XFS_ERRORTAG_ATTR_RW(log_bad_crc, XFS_ERRTAG_LOG_BAD_CRC); +XFS_ERRORTAG_ATTR_RW(log_item_pin, XFS_ERRTAG_LOG_ITEM_PIN); static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(noerror), @@ -193,6 +195,7 @@ static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(ag_resv_critical), XFS_ERRORTAG_ATTR_LIST(drop_writes), XFS_ERRORTAG_ATTR_LIST(log_bad_crc), + XFS_ERRORTAG_ATTR_LIST(log_item_pin), NULL, }; @@ -344,7 +347,7 @@ xfs_verifier_error( { struct xfs_mount *mp = bp->b_target->bt_mount; - xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", + xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx", bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", __return_address, bp->b_ops->name, bp->b_bn); diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index 7577be5f09bc04fa6522baaccf8de6af879efd77..7c4bef3bddb7504d0c06dd27479fc5b6dfa9f1c5 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h @@ -106,7 +106,8 @@ extern void xfs_verifier_error(struct xfs_buf *bp); */ #define XFS_ERRTAG_DROP_WRITES 28 #define XFS_ERRTAG_LOG_BAD_CRC 29 -#define XFS_ERRTAG_MAX 30 +#define XFS_ERRTAG_LOG_ITEM_PIN 30 +#define XFS_ERRTAG_MAX 31 /* * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. @@ -141,6 +142,7 @@ extern void xfs_verifier_error(struct xfs_buf *bp); #define XFS_RANDOM_AG_RESV_CRITICAL 4 #define XFS_RANDOM_DROP_WRITES 1 #define XFS_RANDOM_LOG_BAD_CRC 1 +#define XFS_RANDOM_LOG_ITEM_PIN 1 #ifdef DEBUG extern int xfs_errortag_init(struct xfs_mount *mp); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index c4893e226fd8e7ddebf8ee22aed420d5d122d473..309e26c9dddb49715e81cb38b3aed00e33214463 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -58,7 +58,7 @@ xfs_zero_range( xfs_off_t count, bool *did_zero) { - return iomap_zero_range(VFS_I(ip), pos, count, NULL, &xfs_iomap_ops); + return iomap_zero_range(VFS_I(ip), pos, count, did_zero, &xfs_iomap_ops); } int @@ -259,7 +259,11 @@ xfs_file_buffered_aio_read( trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos); - xfs_ilock(ip, XFS_IOLOCK_SHARED); + if (!xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED)) { + if (iocb->ki_flags & IOCB_NOWAIT) + return -EAGAIN; + xfs_ilock(ip, XFS_IOLOCK_SHARED); + } ret = generic_file_read_iter(iocb, to); xfs_iunlock(ip, XFS_IOLOCK_SHARED); @@ -373,8 +377,6 @@ xfs_file_aio_write_checks( */ spin_lock(&ip->i_flags_lock); if (iocb->ki_pos > i_size_read(inode)) { - bool zero = false; - spin_unlock(&ip->i_flags_lock); if (!drained_dio) { if (*iolock == XFS_IOLOCK_SHARED) { @@ -395,7 +397,7 @@ xfs_file_aio_write_checks( drained_dio = true; goto restart; } - error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero); + error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), NULL); if (error) return error; } else @@ -432,7 +434,6 @@ xfs_dio_write_end_io( struct inode *inode = file_inode(iocb->ki_filp); struct xfs_inode *ip = XFS_I(inode); loff_t offset = iocb->ki_pos; - bool update_size = false; int error = 0; trace_xfs_end_io_direct_write(ip, offset, size); @@ -443,6 +444,21 @@ xfs_dio_write_end_io( if (size <= 0) return size; + if (flags & IOMAP_DIO_COW) { + error = xfs_reflink_end_cow(ip, offset, size); + if (error) + return error; + } + + /* + * Unwritten conversion updates the in-core isize after extent + * conversion but before updating the on-disk size. Updating isize any + * earlier allows a racing dio read to find unwritten extents before + * they are converted. + */ + if (flags & IOMAP_DIO_UNWRITTEN) + return xfs_iomap_write_unwritten(ip, offset, size, true); + /* * We need to update the in-core inode size here so that we don't end up * with the on-disk inode size being outside the in-core inode size. We @@ -457,20 +473,11 @@ xfs_dio_write_end_io( spin_lock(&ip->i_flags_lock); if (offset + size > i_size_read(inode)) { i_size_write(inode, offset + size); - update_size = true; - } - spin_unlock(&ip->i_flags_lock); - - if (flags & IOMAP_DIO_COW) { - error = xfs_reflink_end_cow(ip, offset, size); - if (error) - return error; - } - - if (flags & IOMAP_DIO_UNWRITTEN) - error = xfs_iomap_write_unwritten(ip, offset, size); - else if (update_size) + spin_unlock(&ip->i_flags_lock); error = xfs_setfilesize(ip, offset, size); + } else { + spin_unlock(&ip->i_flags_lock); + } return error; } @@ -636,6 +643,9 @@ xfs_file_buffered_aio_write( int enospc = 0; int iolock; + if (iocb->ki_flags & IOCB_NOWAIT) + return -EOPNOTSUPP; + write_retry: iolock = XFS_IOLOCK_EXCL; xfs_ilock(ip, iolock); @@ -912,7 +922,7 @@ xfs_file_open( return -EFBIG; if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb))) return -EIO; - file->f_mode |= FMODE_AIO_NOWAIT; + file->f_mode |= FMODE_NOWAIT; return 0; } @@ -1011,96 +1021,67 @@ xfs_file_llseek( * page_lock (MM) * i_lock (XFS - extent map serialisation) */ - -/* - * mmap()d file has taken write protection fault and is being made writable. We - * can set the page state up correctly for a writable page, which means we can - * do correct delalloc accounting (ENOSPC checking!) and unwritten extent - * mapping. - */ -STATIC int -xfs_filemap_page_mkwrite( - struct vm_fault *vmf) +static int +__xfs_filemap_fault( + struct vm_fault *vmf, + enum page_entry_size pe_size, + bool write_fault) { struct inode *inode = file_inode(vmf->vma->vm_file); + struct xfs_inode *ip = XFS_I(inode); int ret; - trace_xfs_filemap_page_mkwrite(XFS_I(inode)); + trace_xfs_filemap_fault(ip, pe_size, write_fault); - sb_start_pagefault(inode->i_sb); - file_update_time(vmf->vma->vm_file); - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); + if (write_fault) { + sb_start_pagefault(inode->i_sb); + file_update_time(vmf->vma->vm_file); + } + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = dax_iomap_fault(vmf, PE_SIZE_PTE, &xfs_iomap_ops); + ret = dax_iomap_fault(vmf, pe_size, &xfs_iomap_ops); } else { - ret = iomap_page_mkwrite(vmf, &xfs_iomap_ops); - ret = block_page_mkwrite_return(ret); + if (write_fault) + ret = iomap_page_mkwrite(vmf, &xfs_iomap_ops); + else + ret = filemap_fault(vmf); } - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - sb_end_pagefault(inode->i_sb); + if (write_fault) + sb_end_pagefault(inode->i_sb); return ret; } -STATIC int +static int xfs_filemap_fault( struct vm_fault *vmf) { - struct inode *inode = file_inode(vmf->vma->vm_file); - int ret; - - trace_xfs_filemap_fault(XFS_I(inode)); - /* DAX can shortcut the normal fault path on write faults! */ - if ((vmf->flags & FAULT_FLAG_WRITE) && IS_DAX(inode)) - return xfs_filemap_page_mkwrite(vmf); - - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - if (IS_DAX(inode)) - ret = dax_iomap_fault(vmf, PE_SIZE_PTE, &xfs_iomap_ops); - else - ret = filemap_fault(vmf); - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - - return ret; + return __xfs_filemap_fault(vmf, PE_SIZE_PTE, + IS_DAX(file_inode(vmf->vma->vm_file)) && + (vmf->flags & FAULT_FLAG_WRITE)); } -/* - * Similar to xfs_filemap_fault(), the DAX fault path can call into here on - * both read and write faults. Hence we need to handle both cases. There is no - * ->huge_mkwrite callout for huge pages, so we have a single function here to - * handle both cases here. @flags carries the information on the type of fault - * occuring. - */ -STATIC int +static int xfs_filemap_huge_fault( struct vm_fault *vmf, enum page_entry_size pe_size) { - struct inode *inode = file_inode(vmf->vma->vm_file); - struct xfs_inode *ip = XFS_I(inode); - int ret; - - if (!IS_DAX(inode)) + if (!IS_DAX(file_inode(vmf->vma->vm_file))) return VM_FAULT_FALLBACK; - trace_xfs_filemap_huge_fault(ip); - - if (vmf->flags & FAULT_FLAG_WRITE) { - sb_start_pagefault(inode->i_sb); - file_update_time(vmf->vma->vm_file); - } - - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - ret = dax_iomap_fault(vmf, pe_size, &xfs_iomap_ops); - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - - if (vmf->flags & FAULT_FLAG_WRITE) - sb_end_pagefault(inode->i_sb); + /* DAX can shortcut the normal fault path on write faults! */ + return __xfs_filemap_fault(vmf, pe_size, + (vmf->flags & FAULT_FLAG_WRITE)); +} - return ret; +static int +xfs_filemap_page_mkwrite( + struct vm_fault *vmf) +{ + return __xfs_filemap_fault(vmf, PE_SIZE_PTE, true); } /* @@ -1130,7 +1111,7 @@ xfs_filemap_pfn_mkwrite( if (vmf->pgoff >= size) ret = VM_FAULT_SIGBUS; else if (IS_DAX(inode)) - ret = dax_pfn_mkwrite(vmf); + ret = dax_iomap_fault(vmf, PE_SIZE_PTE, &xfs_iomap_ops); xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); return ret; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0a9e6985a0d092ff8493347c597b1b509c9048ef..34227115a5d6e7c22ee05ce8c90a70bec1701762 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1124,11 +1124,11 @@ xfs_reclaim_inode( * Because we use RCU freeing we need to ensure the inode always appears * to be reclaimed with an invalid inode number when in the free state. * We do this as early as possible under the ILOCK so that - * xfs_iflush_cluster() can be guaranteed to detect races with us here. - * By doing this, we guarantee that once xfs_iflush_cluster has locked - * XFS_ILOCK that it will see either a valid, flushable inode that will - * serialise correctly, or it will see a clean (and invalid) inode that - * it can skip. + * xfs_iflush_cluster() and xfs_ifree_cluster() can be guaranteed to + * detect races with us here. By doing this, we guarantee that once + * xfs_iflush_cluster() or xfs_ifree_cluster() has locked XFS_ILOCK that + * it will see either a valid inode that will serialise correctly, or it + * will see an invalid inode that it can skip. */ spin_lock(&ip->i_flags_lock); ip->i_flags = XFS_IRECLAIM; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ceef77c0416ad5833c2b513006496c8d57a4c62f..4ec5b7f4540137622856883ab5dafb73d95f89ab 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -874,7 +874,6 @@ xfs_ialloc( case S_IFREG: case S_IFDIR: if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { - uint64_t di_flags2 = 0; uint di_flags = 0; if (S_ISDIR(mode)) { @@ -911,20 +910,23 @@ xfs_ialloc( di_flags |= XFS_DIFLAG_NODEFRAG; if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM) di_flags |= XFS_DIFLAG_FILESTREAM; - if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX) - di_flags2 |= XFS_DIFLAG2_DAX; ip->i_d.di_flags |= di_flags; - ip->i_d.di_flags2 |= di_flags2; } if (pip && (pip->i_d.di_flags2 & XFS_DIFLAG2_ANY) && pip->i_d.di_version == 3 && ip->i_d.di_version == 3) { + uint64_t di_flags2 = 0; + if (pip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE) { - ip->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; + di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; ip->i_d.di_cowextsize = pip->i_d.di_cowextsize; } + if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX) + di_flags2 |= XFS_DIFLAG2_DAX; + + ip->i_d.di_flags2 |= di_flags2; } /* FALLTHROUGH */ case S_IFLNK: @@ -1053,7 +1055,7 @@ xfs_dir_ialloc( tp->t_flags &= ~(XFS_TRANS_DQ_DIRTY); } - code = xfs_trans_roll(&tp, NULL); + code = xfs_trans_roll(&tp); if (committed != NULL) *committed = 1; @@ -1283,7 +1285,7 @@ xfs_create( */ xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -1511,7 +1513,7 @@ xfs_link( if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) { xfs_defer_cancel(&dfops); goto error_return; @@ -1605,11 +1607,12 @@ xfs_itruncate_extents( * Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ - error = xfs_defer_finish(&tp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; - error = xfs_trans_roll(&tp, ip); + error = xfs_trans_roll_inode(&tp, ip); if (error) goto out; } @@ -1621,10 +1624,12 @@ xfs_itruncate_extents( goto out; /* - * Clear the reflink flag if we truncated everything. + * Clear the reflink flag if there are no data fork blocks and + * there are no extents staged in the cow fork. */ - if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) { - ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) { + if (ip->i_d.di_nblocks == 0) + ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; xfs_inode_clear_cowblocks_tag(ip); } @@ -1853,7 +1858,7 @@ xfs_inactive_ifree( * Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) { xfs_notice(mp, "%s: xfs_defer_finish returned error %d", __func__, error); @@ -2357,11 +2362,24 @@ xfs_ifree_cluster( * already marked stale. If we can't lock it, back off * and retry. */ - if (ip != free_ip && - !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { - rcu_read_unlock(); - delay(1); - goto retry; + if (ip != free_ip) { + if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { + rcu_read_unlock(); + delay(1); + goto retry; + } + + /* + * Check the inode number again in case we're + * racing with freeing in xfs_reclaim_inode(). + * See the comments in that function for more + * information as to why the initial check is + * not sufficient. + */ + if (ip->i_ino != inum + i) { + xfs_iunlock(ip, XFS_ILOCK_EXCL); + continue; + } } rcu_read_unlock(); @@ -2635,7 +2653,7 @@ xfs_remove( if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -2721,7 +2739,7 @@ xfs_finish_rename( if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_defer_finish(&tp, dfops, NULL); + error = xfs_defer_finish(&tp, dfops); if (error) { xfs_defer_cancel(dfops); xfs_trans_cancel(tp); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 013cc78d7daf46ce69427dd05830be65182d71da..a705f34b58fad089659a019dcdd1caecffd01aa3 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -27,6 +27,7 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_trans_priv.h" +#include "xfs_buf_item.h" #include "xfs_log.h" @@ -475,6 +476,23 @@ xfs_inode_item_unpin( wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT); } +/* + * Callback used to mark a buffer with XFS_LI_FAILED when items in the buffer + * have been failed during writeback + * + * This informs the AIL that the inode is already flush locked on the next push, + * and acquires a hold on the buffer to ensure that it isn't reclaimed before + * dirty data makes it to disk. + */ +STATIC void +xfs_inode_item_error( + struct xfs_log_item *lip, + struct xfs_buf *bp) +{ + ASSERT(xfs_isiflocked(INODE_ITEM(lip)->ili_inode)); + xfs_set_li_failed(lip, bp); +} + STATIC uint xfs_inode_item_push( struct xfs_log_item *lip, @@ -484,13 +502,28 @@ xfs_inode_item_push( { struct xfs_inode_log_item *iip = INODE_ITEM(lip); struct xfs_inode *ip = iip->ili_inode; - struct xfs_buf *bp = NULL; + struct xfs_buf *bp = lip->li_buf; uint rval = XFS_ITEM_SUCCESS; int error; if (xfs_ipincount(ip) > 0) return XFS_ITEM_PINNED; + /* + * The buffer containing this item failed to be written back + * previously. Resubmit the buffer for IO. + */ + if (lip->li_flags & XFS_LI_FAILED) { + if (!xfs_buf_trylock(bp)) + return XFS_ITEM_LOCKED; + + if (!xfs_buf_resubmit_failed_buffers(bp, lip, buffer_list)) + rval = XFS_ITEM_FLUSHING; + + xfs_buf_unlock(bp); + return rval; + } + if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) return XFS_ITEM_LOCKED; @@ -622,7 +655,8 @@ static const struct xfs_item_ops xfs_inode_item_ops = { .iop_unlock = xfs_inode_item_unlock, .iop_committed = xfs_inode_item_committed, .iop_push = xfs_inode_item_push, - .iop_committing = xfs_inode_item_committing + .iop_committing = xfs_inode_item_committing, + .iop_error = xfs_inode_item_error }; @@ -710,7 +744,8 @@ xfs_iflush_done( * the AIL lock. */ iip = INODE_ITEM(blip); - if (iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) + if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) || + (blip->li_flags & XFS_LI_FAILED)) need_ail++; blip = next; @@ -718,7 +753,8 @@ xfs_iflush_done( /* make sure we capture the state of the initial inode. */ iip = INODE_ITEM(lip); - if (iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn) + if ((iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn) || + lip->li_flags & XFS_LI_FAILED) need_ail++; /* @@ -739,6 +775,9 @@ xfs_iflush_done( if (INODE_ITEM(blip)->ili_logged && blip->li_lsn == INODE_ITEM(blip)->ili_flush_lsn) mlip_changed |= xfs_ail_delete_one(ailp, blip); + else { + xfs_clear_li_failed(blip); + } } if (mlip_changed) { diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 9c0c7a920304edf68f82c6407abc43f4bd5ee8c7..aa75389be8cfa81d06695f80701c2093b65289b0 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -931,16 +931,15 @@ xfs_ioc_fsgetxattr( return 0; } -STATIC void -xfs_set_diflags( +STATIC uint16_t +xfs_flags2diflags( struct xfs_inode *ip, unsigned int xflags) { - unsigned int di_flags; - uint64_t di_flags2; - /* can't set PREALLOC this way, just preserve it */ - di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); + uint16_t di_flags = + (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); + if (xflags & FS_XFLAG_IMMUTABLE) di_flags |= XFS_DIFLAG_IMMUTABLE; if (xflags & FS_XFLAG_APPEND) @@ -970,19 +969,24 @@ xfs_set_diflags( if (xflags & FS_XFLAG_EXTSIZE) di_flags |= XFS_DIFLAG_EXTSIZE; } - ip->i_d.di_flags = di_flags; - /* diflags2 only valid for v3 inodes. */ - if (ip->i_d.di_version < 3) - return; + return di_flags; +} + +STATIC uint64_t +xfs_flags2diflags2( + struct xfs_inode *ip, + unsigned int xflags) +{ + uint64_t di_flags2 = + (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK); - di_flags2 = (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK); if (xflags & FS_XFLAG_DAX) di_flags2 |= XFS_DIFLAG2_DAX; if (xflags & FS_XFLAG_COWEXTSIZE) di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; - ip->i_d.di_flags2 = di_flags2; + return di_flags2; } STATIC void @@ -1008,11 +1012,12 @@ xfs_diflags_to_linux( inode->i_flags |= S_NOATIME; else inode->i_flags &= ~S_NOATIME; +#if 0 /* disabled until the flag switching races are sorted out */ if (xflags & FS_XFLAG_DAX) inode->i_flags |= S_DAX; else inode->i_flags &= ~S_DAX; - +#endif } static int @@ -1022,6 +1027,7 @@ xfs_ioctl_setattr_xflags( struct fsxattr *fa) { struct xfs_mount *mp = ip->i_mount; + uint64_t di_flags2; /* Can't change realtime flag if any extents are allocated. */ if ((ip->i_d.di_nextents || ip->i_delayed_blks) && @@ -1052,7 +1058,14 @@ xfs_ioctl_setattr_xflags( !capable(CAP_LINUX_IMMUTABLE)) return -EPERM; - xfs_set_diflags(ip, fa->fsx_xflags); + /* diflags2 only valid for v3 inodes. */ + di_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags); + if (di_flags2 && ip->i_d.di_version < 3) + return -EINVAL; + + ip->i_d.di_flags = xfs_flags2diflags(ip, fa->fsx_xflags); + ip->i_d.di_flags2 = di_flags2; + xfs_diflags_to_linux(ip); xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); @@ -1075,6 +1088,7 @@ xfs_ioctl_setattr_dax_invalidate( int *join_flags) { struct inode *inode = VFS_I(ip); + struct super_block *sb = inode->i_sb; int error; *join_flags = 0; @@ -1087,7 +1101,7 @@ xfs_ioctl_setattr_dax_invalidate( if (fa->fsx_xflags & FS_XFLAG_DAX) { if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) return -EINVAL; - if (ip->i_mount->m_sb.sb_blocksize != PAGE_SIZE) + if (bdev_dax_supported(sb, sb->s_blocksize) < 0) return -EINVAL; } diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 813394c62849727ddd4a5f97c5aa9041b6bc6987..f179bdf1644dc346b2f7f064543eca0c3f808c6a 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap( iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff); iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount); iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip)); + iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip)); } xfs_extlen_t @@ -274,7 +275,7 @@ xfs_iomap_write_direct( /* * Complete the transaction */ - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -520,7 +521,6 @@ xfs_file_iomap_begin_delay( struct inode *inode, loff_t offset, loff_t count, - unsigned flags, struct iomap *iomap) { struct xfs_inode *ip = XFS_I(inode); @@ -784,7 +784,7 @@ xfs_iomap_write_allocate( if (error) goto trans_cancel; - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto trans_cancel; @@ -829,7 +829,8 @@ int xfs_iomap_write_unwritten( xfs_inode_t *ip, xfs_off_t offset, - xfs_off_t count) + xfs_off_t count, + bool update_isize) { xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb; @@ -840,6 +841,7 @@ xfs_iomap_write_unwritten( xfs_trans_t *tp; xfs_bmbt_irec_t imap; struct xfs_defer_ops dfops; + struct inode *inode = VFS_I(ip); xfs_fsize_t i_size; uint resblks; int error; @@ -899,14 +901,15 @@ xfs_iomap_write_unwritten( i_size = XFS_FSB_TO_B(mp, offset_fsb + count_fsb); if (i_size > offset + count) i_size = offset + count; - + if (update_isize && i_size > i_size_read(inode)) + i_size_write(inode, i_size); i_size = xfs_new_eof(ip, i_size); if (i_size) { ip->i_d.di_size = i_size; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto error_on_bmapi_transaction; @@ -976,7 +979,6 @@ xfs_file_iomap_begin( int nimaps = 1, error = 0; bool shared = false, trimmed = false; unsigned lockmode; - struct block_device *bdev; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; @@ -984,8 +986,7 @@ xfs_file_iomap_begin( if (((flags & (IOMAP_WRITE | IOMAP_DIRECT)) == IOMAP_WRITE) && !IS_DAX(inode) && !xfs_get_extsz_hint(ip)) { /* Reserve delalloc blocks for regular writeback. */ - return xfs_file_iomap_begin_delay(inode, offset, length, flags, - iomap); + return xfs_file_iomap_begin_delay(inode, offset, length, iomap); } if (need_excl_ilock(ip, flags)) { @@ -1087,13 +1088,6 @@ xfs_file_iomap_begin( xfs_bmbt_to_iomap(ip, iomap, &imap); - /* optionally associate a dax device with the iomap bdev */ - bdev = iomap->bdev; - if (blk_queue_dax(bdev->bd_queue)) - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name); - else - iomap->dax_dev = NULL; - if (shared) iomap->flags |= IOMAP_F_SHARED; return 0; @@ -1171,7 +1165,6 @@ xfs_file_iomap_end( unsigned flags, struct iomap *iomap) { - fs_put_dax(iomap->dax_dev); if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC) return xfs_file_iomap_end_delalloc(XFS_I(inode), offset, length, written, iomap); diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 00db3ecea0840c2587f6c0de2f2828bcaaab6fbe..ee535065c5d0e3795158e9cf1ce7dafad5f3a729 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -27,7 +27,7 @@ int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, struct xfs_bmbt_irec *, int); int xfs_iomap_write_allocate(struct xfs_inode *, int, xfs_off_t, struct xfs_bmbt_irec *); -int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t); +int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool); void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, struct xfs_bmbt_irec *); diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 469c9fa4c178d98d06445b2456d82edc86d17f63..17081c77ef86ede1447fcf80565a718b136db40c 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -817,7 +817,7 @@ xfs_vn_setattr_nonsize( * Caution: The caller of this function is responsible for calling * setattr_prepare() or otherwise verifying the change is fine. */ -int +STATIC int xfs_setattr_size( struct xfs_inode *ip, struct iattr *iattr) diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 9301c5a6060b68ee63d04cab873b4c4ab26c80c5..dcd1292664b3404b25bd93b9d40e58ab81d72376 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -270,7 +270,14 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y) #endif /* DEBUG */ #ifdef CONFIG_XFS_RT -#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) + +/* + * make sure we ignore the inode flag if the filesystem doesn't have a + * configured realtime device. + */ +#define XFS_IS_REALTIME_INODE(ip) \ + (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) && \ + (ip)->i_mount->m_rtdev_targp) #else #define XFS_IS_REALTIME_INODE(ip) (0) #endif diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 0053bcf2b10a1de59c459de8c74a8cd1d0269d3b..c5107c7bc4bf8cfaad37050babd60e9a4f17e109 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -743,15 +743,45 @@ xfs_log_mount_finish( struct xfs_mount *mp) { int error = 0; + bool readonly = (mp->m_flags & XFS_MOUNT_RDONLY); if (mp->m_flags & XFS_MOUNT_NORECOVERY) { ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); return 0; + } else if (readonly) { + /* Allow unlinked processing to proceed */ + mp->m_flags &= ~XFS_MOUNT_RDONLY; } + /* + * During the second phase of log recovery, we need iget and + * iput to behave like they do for an active filesystem. + * xfs_fs_drop_inode needs to be able to prevent the deletion + * of inodes before we're done replaying log items on those + * inodes. Turn it off immediately after recovery finishes + * so that we don't leak the quota inodes if subsequent mount + * activities fail. + * + * We let all inodes involved in redo item processing end up on + * the LRU instead of being evicted immediately so that if we do + * something to an unlinked inode, the irele won't cause + * premature truncation and freeing of the inode, which results + * in log recovery failure. We have to evict the unreferenced + * lru inodes after clearing MS_ACTIVE because we don't + * otherwise clean up the lru if there's a subsequent failure in + * xfs_mountfs, which leads to us leaking the inodes if nothing + * else (e.g. quotacheck) references the inodes before the + * mount failure occurs. + */ + mp->m_super->s_flags |= MS_ACTIVE; error = xlog_recover_finish(mp->m_log); if (!error) xfs_log_work_queue(mp); + mp->m_super->s_flags &= ~MS_ACTIVE; + evict_inodes(mp->m_super); + + if (readonly) + mp->m_flags |= XFS_MOUNT_RDONLY; return error; } @@ -801,11 +831,14 @@ xfs_log_unmount_write(xfs_mount_t *mp) int error; /* - * Don't write out unmount record on read-only mounts. + * Don't write out unmount record on norecovery mounts or ro devices. * Or, if we are doing a forced umount (typically because of IO errors). */ - if (mp->m_flags & XFS_MOUNT_RDONLY) + if (mp->m_flags & XFS_MOUNT_NORECOVERY || + xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) { + ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); return 0; + } error = _xfs_log_force(mp, XFS_LOG_SYNC, NULL); ASSERT(error || !(XLOG_FORCED_SHUTDOWN(log))); @@ -3342,8 +3375,6 @@ _xfs_log_force( */ if (iclog->ic_state & XLOG_STATE_IOERROR) return -EIO; - if (log_flushed) - *log_flushed = 1; } else { no_sleep: @@ -3447,8 +3478,6 @@ _xfs_log_force_lsn( xlog_wait(&iclog->ic_prev->ic_write_wait, &log->l_icloglock); - if (log_flushed) - *log_flushed = 1; already_slept = 1; goto try_again; } @@ -3482,9 +3511,6 @@ _xfs_log_force_lsn( */ if (iclog->ic_state & XLOG_STATE_IOERROR) return -EIO; - - if (log_flushed) - *log_flushed = 1; } else { /* just return */ spin_unlock(&log->l_icloglock); } diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index fbe72b134bef219e80420063bfe2db2abc594e49..43aa42a3a5d319fffff98417bff98055083f1a75 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -539,6 +539,7 @@ xlog_discard_endio( INIT_WORK(&ctx->discard_endio_work, xlog_discard_endio_work); queue_work(xfs_discard_wq, &ctx->discard_endio_work); + bio_put(bio); } static void diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 9549188f5a36daa37957707695357dd91aa36ca6..ee34899396b263eaf88938cca95a8588221f0ede 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1029,61 +1029,106 @@ xlog_seek_logrec_hdr( } /* - * Check the log tail for torn writes. This is required when torn writes are - * detected at the head and the head had to be walked back to a previous record. - * The tail of the previous record must now be verified to ensure the torn - * writes didn't corrupt the previous tail. + * Calculate distance from head to tail (i.e., unused space in the log). + */ +static inline int +xlog_tail_distance( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk) +{ + if (head_blk < tail_blk) + return tail_blk - head_blk; + + return tail_blk + (log->l_logBBsize - head_blk); +} + +/* + * Verify the log tail. This is particularly important when torn or incomplete + * writes have been detected near the front of the log and the head has been + * walked back accordingly. + * + * We also have to handle the case where the tail was pinned and the head + * blocked behind the tail right before a crash. If the tail had been pushed + * immediately prior to the crash and the subsequent checkpoint was only + * partially written, it's possible it overwrote the last referenced tail in the + * log with garbage. This is not a coherency problem because the tail must have + * been pushed before it can be overwritten, but appears as log corruption to + * recovery because we have no way to know the tail was updated if the + * subsequent checkpoint didn't write successfully. * - * Return an error if CRC verification fails as recovery cannot proceed. + * Therefore, CRC check the log from tail to head. If a failure occurs and the + * offending record is within max iclog bufs from the head, walk the tail + * forward and retry until a valid tail is found or corruption is detected out + * of the range of a possible overwrite. */ STATIC int xlog_verify_tail( struct xlog *log, xfs_daddr_t head_blk, - xfs_daddr_t tail_blk) + xfs_daddr_t *tail_blk, + int hsize) { struct xlog_rec_header *thead; struct xfs_buf *bp; xfs_daddr_t first_bad; - int count; int error = 0; bool wrapped; - xfs_daddr_t tmp_head; + xfs_daddr_t tmp_tail; + xfs_daddr_t orig_tail = *tail_blk; bp = xlog_get_bp(log, 1); if (!bp) return -ENOMEM; /* - * Seek XLOG_MAX_ICLOGS + 1 records past the current tail record to get - * a temporary head block that points after the last possible - * concurrently written record of the tail. + * Make sure the tail points to a record (returns positive count on + * success). */ - count = xlog_seek_logrec_hdr(log, head_blk, tail_blk, - XLOG_MAX_ICLOGS + 1, bp, &tmp_head, &thead, - &wrapped); - if (count < 0) { - error = count; + error = xlog_seek_logrec_hdr(log, head_blk, *tail_blk, 1, bp, + &tmp_tail, &thead, &wrapped); + if (error < 0) goto out; - } - - /* - * If the call above didn't find XLOG_MAX_ICLOGS + 1 records, we ran - * into the actual log head. tmp_head points to the start of the record - * so update it to the actual head block. - */ - if (count < XLOG_MAX_ICLOGS + 1) - tmp_head = head_blk; + if (*tail_blk != tmp_tail) + *tail_blk = tmp_tail; /* - * We now have a tail and temporary head block that covers at least - * XLOG_MAX_ICLOGS records from the tail. We need to verify that these - * records were completely written. Run a CRC verification pass from - * tail to head and return the result. + * Run a CRC check from the tail to the head. We can't just check + * MAX_ICLOGS records past the tail because the tail may point to stale + * blocks cleared during the search for the head/tail. These blocks are + * overwritten with zero-length records and thus record count is not a + * reliable indicator of the iclog state before a crash. */ - error = xlog_do_recovery_pass(log, tmp_head, tail_blk, + first_bad = 0; + error = xlog_do_recovery_pass(log, head_blk, *tail_blk, XLOG_RECOVER_CRCPASS, &first_bad); + while ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) { + int tail_distance; + + /* + * Is corruption within range of the head? If so, retry from + * the next record. Otherwise return an error. + */ + tail_distance = xlog_tail_distance(log, head_blk, first_bad); + if (tail_distance > BTOBB(XLOG_MAX_ICLOGS * hsize)) + break; + /* skip to the next record; returns positive count on success */ + error = xlog_seek_logrec_hdr(log, head_blk, first_bad, 2, bp, + &tmp_tail, &thead, &wrapped); + if (error < 0) + goto out; + + *tail_blk = tmp_tail; + first_bad = 0; + error = xlog_do_recovery_pass(log, head_blk, *tail_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + } + + if (!error && *tail_blk != orig_tail) + xfs_warn(log->l_mp, + "Tail block (0x%llx) overwrite detected. Updated to 0x%llx", + orig_tail, *tail_blk); out: xlog_put_bp(bp); return error; @@ -1143,7 +1188,7 @@ xlog_verify_head( */ error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, XLOG_RECOVER_CRCPASS, &first_bad); - if (error == -EFSBADCRC) { + if ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) { /* * We've hit a potential torn write. Reset the error and warn * about it. @@ -1183,31 +1228,12 @@ xlog_verify_head( ASSERT(0); return 0; } - - /* - * Now verify the tail based on the updated head. This is - * required because the torn writes trimmed from the head could - * have been written over the tail of a previous record. Return - * any errors since recovery cannot proceed if the tail is - * corrupt. - * - * XXX: This leaves a gap in truly robust protection from torn - * writes in the log. If the head is behind the tail, the tail - * pushes forward to create some space and then a crash occurs - * causing the writes into the previous record's tail region to - * tear, log recovery isn't able to recover. - * - * How likely is this to occur? If possible, can we do something - * more intelligent here? Is it safe to push the tail forward if - * we can determine that the tail is within the range of the - * torn write (e.g., the kernel can only overwrite the tail if - * it has actually been pushed forward)? Alternatively, could we - * somehow prevent this condition at runtime? - */ - error = xlog_verify_tail(log, *head_blk, *tail_blk); } + if (error) + return error; - return error; + return xlog_verify_tail(log, *head_blk, tail_blk, + be32_to_cpu((*rhead)->h_size)); } /* @@ -4801,12 +4827,16 @@ xlog_recover_process_intents( int error = 0; struct xfs_ail_cursor cur; struct xfs_ail *ailp; +#if defined(DEBUG) || defined(XFS_WARN) xfs_lsn_t last_lsn; +#endif ailp = log->l_ailp; spin_lock(&ailp->xa_lock); lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); +#if defined(DEBUG) || defined(XFS_WARN) last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block); +#endif while (lip != NULL) { /* * We're done when we see something other than an intent. @@ -5218,7 +5248,7 @@ xlog_do_recovery_pass( xfs_daddr_t *first_bad) /* out: first bad log rec */ { xlog_rec_header_t *rhead; - xfs_daddr_t blk_no; + xfs_daddr_t blk_no, rblk_no; xfs_daddr_t rhead_blk; char *offset; xfs_buf_t *hbp, *dbp; @@ -5231,7 +5261,7 @@ xlog_do_recovery_pass( LIST_HEAD (buffer_list); ASSERT(head_blk != tail_blk); - rhead_blk = 0; + blk_no = rhead_blk = tail_blk; for (i = 0; i < XLOG_RHASH_SIZE; i++) INIT_HLIST_HEAD(&rhash[i]); @@ -5309,7 +5339,6 @@ xlog_do_recovery_pass( } memset(rhash, 0, sizeof(rhash)); - blk_no = rhead_blk = tail_blk; if (tail_blk > head_blk) { /* * Perform recovery around the end of the physical log. @@ -5371,9 +5400,19 @@ xlog_do_recovery_pass( bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); blk_no += hblks; - /* Read in data for log record */ - if (blk_no + bblks <= log->l_logBBsize) { - error = xlog_bread(log, blk_no, bblks, dbp, + /* + * Read the log record data in multiple reads if it + * wraps around the end of the log. Note that if the + * header already wrapped, blk_no could point past the + * end of the log. The record data is contiguous in + * that case. + */ + if (blk_no + bblks <= log->l_logBBsize || + blk_no >= log->l_logBBsize) { + /* mod blk_no in case the header wrapped and + * pushed it beyond the end of the log */ + rblk_no = do_mod(blk_no, log->l_logBBsize); + error = xlog_bread(log, rblk_no, bblks, dbp, &offset); if (error) goto bread_err2; @@ -5563,6 +5602,8 @@ xlog_do_recover( xfs_buf_t *bp; xfs_sb_t *sbp; + trace_xfs_log_recover(log, head_blk, tail_blk); + /* * First replay the images in the log. */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 40d4e8b4e193b41a123903735736248568bf26b9..ea7d4b4e50d0ca3eedee85ffd840542e0bb105db 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -944,15 +944,6 @@ xfs_mountfs( } } - /* - * During the second phase of log recovery, we need iget and - * iput to behave like they do for an active filesystem. - * xfs_fs_drop_inode needs to be able to prevent the deletion - * of inodes before we're done replaying log items on those - * inodes. - */ - mp->m_super->s_flags |= MS_ACTIVE; - /* * Finish recovering the file system. This part needed to be delayed * until after the root and real-time bitmap inodes were consistently @@ -1028,12 +1019,13 @@ xfs_mountfs( out_quota: xfs_qm_unmount_quotas(mp); out_rtunmount: - mp->m_super->s_flags &= ~MS_ACTIVE; xfs_rtunmount_inodes(mp); out_rele_rip: IRELE(rip); cancel_delayed_work_sync(&mp->m_reclaim_work); xfs_reclaim_inodes(mp, SYNC_WAIT); + /* Clean out dquots that might be in memory after quotacheck. */ + xfs_qm_unmount(mp); out_log_dealloc: mp->m_flags |= XFS_MOUNT_UNMOUNTING; xfs_log_mount_cancel(mp); diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index 2f2dc3c09ad008a75fa0ffba6fd5d7aed392c162..4246876df7b759cdd63ddd43b5eb4612af0b0c93 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c @@ -274,7 +274,7 @@ xfs_fs_commit_blocks( (end - 1) >> PAGE_SHIFT); WARN_ON_ONCE(error); - error = xfs_iomap_write_unwritten(ip, start, length); + error = xfs_iomap_write_unwritten(ip, start, length, false); if (error) goto out_drop_iolock; } diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 15751dc2a27df04a4608754ff8250de6ae8bd77f..010a13a201aad78382ae69fdcc8e3b8d5c451c1d 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -31,6 +31,7 @@ #include "xfs_error.h" #include "xfs_bmap.h" #include "xfs_bmap_btree.h" +#include "xfs_bmap_util.h" #include "xfs_trans.h" #include "xfs_trans_space.h" #include "xfs_qm.h" @@ -1120,31 +1121,6 @@ xfs_qm_quotacheck_dqadjust( return 0; } -STATIC int -xfs_qm_get_rtblks( - xfs_inode_t *ip, - xfs_qcnt_t *O_rtblks) -{ - xfs_filblks_t rtblks; /* total rt blks */ - xfs_extnum_t idx; /* extent record index */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_extnum_t nextents; /* number of extent entries */ - int error; - - ASSERT(XFS_IS_REALTIME_INODE(ip)); - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); - if (!(ifp->if_flags & XFS_IFEXTENTS)) { - if ((error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK))) - return error; - } - rtblks = 0; - nextents = xfs_iext_count(ifp); - for (idx = 0; idx < nextents; idx++) - rtblks += xfs_bmbt_get_blockcount(xfs_iext_get_ext(ifp, idx)); - *O_rtblks = (xfs_qcnt_t)rtblks; - return 0; -} - /* * callback routine supplied to bulkstat(). Given an inumber, find its * dquots and update them to account for resources taken by that inode. @@ -1160,7 +1136,8 @@ xfs_qm_dqusage_adjust( int *res) /* result code value */ { xfs_inode_t *ip; - xfs_qcnt_t nblks, rtblks = 0; + xfs_qcnt_t nblks; + xfs_filblks_t rtblks = 0; /* total rt blks */ int error; ASSERT(XFS_IS_QUOTA_RUNNING(mp)); @@ -1190,12 +1167,15 @@ xfs_qm_dqusage_adjust( ASSERT(ip->i_delayed_blks == 0); if (XFS_IS_REALTIME_INODE(ip)) { - /* - * Walk thru the extent list and count the realtime blocks. - */ - error = xfs_qm_get_rtblks(ip, &rtblks); - if (error) - goto error0; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + + if (!(ifp->if_flags & XFS_IFEXTENTS)) { + error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); + if (error) + goto error0; + } + + xfs_bmap_count_leaves(ifp, &rtblks); } nblks = (xfs_qcnt_t)ip->i_d.di_nblocks - rtblks; diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index de9493253edfb99df4c2027866b5d3a36e693f1d..a65108594a070dcade75db6d55869049b875b247 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -125,7 +125,7 @@ xfs_fs_set_info( struct xfs_mount *mp = XFS_M(sb); struct qc_dqblk newlim; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; if (!XFS_IS_QUOTA_RUNNING(mp)) return -ENOSYS; @@ -175,7 +175,7 @@ xfs_quota_enable( { struct xfs_mount *mp = XFS_M(sb); - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; if (!XFS_IS_QUOTA_RUNNING(mp)) return -ENOSYS; @@ -190,7 +190,7 @@ xfs_quota_disable( { struct xfs_mount *mp = XFS_M(sb); - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; if (!XFS_IS_QUOTA_RUNNING(mp)) return -ENOSYS; @@ -208,7 +208,7 @@ xfs_fs_rm_xquota( struct xfs_mount *mp = XFS_M(sb); unsigned int flags = 0; - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; if (XFS_IS_QUOTA_ON(mp)) @@ -279,7 +279,7 @@ xfs_fs_set_dqblk( { struct xfs_mount *mp = XFS_M(sb); - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) return -EROFS; if (!XFS_IS_QUOTA_RUNNING(mp)) return -ENOSYS; diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 96fe209b5eb61fb5b45fcc46f6733c6b46f29308..8f2e2fac4255d63fc1dab2d268433e099aaf5aa8 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -525,7 +525,7 @@ xfs_cui_recover( } xfs_refcount_finish_one_cleanup(tp, rcur, error); - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto abort_defer; set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index f45fbf0db9bbea2cfb9578afd76de61b44bc7285..37e603bf159137dfd38a1210b5d0bb31e5f4829f 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -464,7 +464,7 @@ xfs_reflink_allocate_cow( goto out_bmap_cancel; /* Finish up. */ - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -602,7 +602,8 @@ xfs_reflink_cancel_cow_blocks( -(long)del.br_blockcount); /* Roll the transaction */ - error = xfs_defer_finish(tpp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(tpp, &dfops); if (error) { xfs_defer_cancel(&dfops); break; @@ -735,7 +736,13 @@ xfs_reflink_end_cow( /* If there is a hole at end_fsb - 1 go to the previous extent */ if (!xfs_iext_lookup_extent(ip, ifp, end_fsb - 1, &idx, &got) || got.br_startoff > end_fsb) { - ASSERT(idx > 0); + /* + * In case of racing, overlapping AIO writes no COW extents + * might be left by the time I/O completes for the loser of + * the race. In that case we are done. + */ + if (idx <= 0) + goto out_cancel; xfs_iext_get_extent(ifp, --idx, &got); } @@ -791,7 +798,8 @@ xfs_reflink_end_cow( /* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow(ip, &idx, &got, &del); - error = xfs_defer_finish(&tp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_defer; next_extent: @@ -807,6 +815,7 @@ xfs_reflink_end_cow( out_defer: xfs_defer_cancel(&dfops); +out_cancel: xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); out: @@ -1152,7 +1161,8 @@ xfs_reflink_remap_extent( next_extent: /* Process all the deferred stuff. */ - error = xfs_defer_finish(&tp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_defer; } diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 91472193643b15420e312074f2ccce5b36a5bf6e..488719d43ca82a434e2ee8afdd94b2ec9cfcddad 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -810,7 +810,7 @@ xfs_growfs_rt_alloc( /* * Free any blocks freed up in the transaction, then commit. */ - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; error = xfs_trans_commit(tp); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 38aaacdbb8b3363f32652daa495b659d5e287826..584cf2d573babe6b8331b856e617c4e6f08b5a53 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -210,7 +210,7 @@ xfs_parseargs( /* * Copy binary VFS mount flags we are interested in. */ - if (sb->s_flags & MS_RDONLY) + if (sb_rdonly(sb)) mp->m_flags |= XFS_MOUNT_RDONLY; if (sb->s_flags & MS_DIRSYNC) mp->m_flags |= XFS_MOUNT_DIRSYNC; @@ -714,17 +714,26 @@ STATIC void xfs_close_devices( struct xfs_mount *mp) { + struct dax_device *dax_ddev = mp->m_ddev_targp->bt_daxdev; + if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { struct block_device *logdev = mp->m_logdev_targp->bt_bdev; + struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev; + xfs_free_buftarg(mp, mp->m_logdev_targp); xfs_blkdev_put(logdev); + fs_put_dax(dax_logdev); } if (mp->m_rtdev_targp) { struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; + struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev; + xfs_free_buftarg(mp, mp->m_rtdev_targp); xfs_blkdev_put(rtdev); + fs_put_dax(dax_rtdev); } xfs_free_buftarg(mp, mp->m_ddev_targp); + fs_put_dax(dax_ddev); } /* @@ -742,6 +751,8 @@ xfs_open_devices( struct xfs_mount *mp) { struct block_device *ddev = mp->m_super->s_bdev; + struct dax_device *dax_ddev = fs_dax_get_by_bdev(ddev); + struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL; struct block_device *logdev = NULL, *rtdev = NULL; int error; @@ -752,6 +763,7 @@ xfs_open_devices( error = xfs_blkdev_get(mp, mp->m_logname, &logdev); if (error) goto out; + dax_logdev = fs_dax_get_by_bdev(logdev); } if (mp->m_rtname) { @@ -765,24 +777,25 @@ xfs_open_devices( error = -EINVAL; goto out_close_rtdev; } + dax_rtdev = fs_dax_get_by_bdev(rtdev); } /* * Setup xfs_mount buffer target pointers */ error = -ENOMEM; - mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev); + mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev); if (!mp->m_ddev_targp) goto out_close_rtdev; if (rtdev) { - mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev); + mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev); if (!mp->m_rtdev_targp) goto out_free_ddev_targ; } if (logdev && logdev != ddev) { - mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev); + mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev); if (!mp->m_logdev_targp) goto out_free_rtdev_targ; } else { @@ -798,10 +811,14 @@ xfs_open_devices( xfs_free_buftarg(mp, mp->m_ddev_targp); out_close_rtdev: xfs_blkdev_put(rtdev); + fs_put_dax(dax_rtdev); out_close_logdev: - if (logdev && logdev != ddev) + if (logdev && logdev != ddev) { xfs_blkdev_put(logdev); + fs_put_dax(dax_logdev); + } out: + fs_put_dax(dax_ddev); return error; } @@ -1220,7 +1237,7 @@ xfs_test_remount_options( tmp_mp->m_super = sb; error = xfs_parseargs(tmp_mp, options); xfs_free_fsname(tmp_mp); - kfree(tmp_mp); + kmem_free(tmp_mp); return error; } @@ -1637,6 +1654,16 @@ xfs_fs_fill_super( "DAX and reflink have not been tested together!"); } + if (mp->m_flags & XFS_MOUNT_DISCARD) { + struct request_queue *q = bdev_get_queue(sb->s_bdev); + + if (!blk_queue_discard(q)) { + xfs_warn(mp, "mounting with \"discard\" option, but " + "the device does not support discard"); + mp->m_flags &= ~XFS_MOUNT_DISCARD; + } + } + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { if (mp->m_sb.sb_rblocks) { xfs_alert(mp, diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 23a50d7aa46a738fb3f4e73c343d2d39f363aa55..68d3ca2c4968054646345dab2bd3a76f97490fb8 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -378,7 +378,7 @@ xfs_symlink( xfs_trans_set_sync(tp); } - error = xfs_defer_finish(&tp, &dfops, NULL); + error = xfs_defer_finish(&tp, &dfops); if (error) goto out_bmap_cancel; @@ -497,7 +497,8 @@ xfs_inactive_symlink_rmt( /* * Commit the first transaction. This logs the EFI and the inode. */ - error = xfs_defer_finish(&tp, &dfops, ip); + xfs_defer_ijoin(&dfops, ip); + error = xfs_defer_finish(&tp, &dfops); if (error) goto error_bmap_cancel; /* diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index bcc3cdf8e1c5da7797463bf6023171860268f3d6..bb5514688d470b046e0f125b2832ba2d30b3d34d 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -517,7 +517,6 @@ DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size_ordered); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size_stale); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format); -DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format_ordered); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format_stale); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_ordered); DEFINE_BUF_ITEM_EVENT(xfs_buf_item_pin); @@ -689,11 +688,34 @@ DEFINE_INODE_EVENT(xfs_inode_set_cowblocks_tag); DEFINE_INODE_EVENT(xfs_inode_clear_cowblocks_tag); DEFINE_INODE_EVENT(xfs_inode_free_cowblocks_invalid); -DEFINE_INODE_EVENT(xfs_filemap_fault); -DEFINE_INODE_EVENT(xfs_filemap_huge_fault); -DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite); DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite); +TRACE_EVENT(xfs_filemap_fault, + TP_PROTO(struct xfs_inode *ip, enum page_entry_size pe_size, + bool write_fault), + TP_ARGS(ip, pe_size, write_fault), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(enum page_entry_size, pe_size) + __field(bool, write_fault) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->pe_size = pe_size; + __entry->write_fault = write_fault; + ), + TP_printk("dev %d:%d ino 0x%llx %s write_fault %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_symbolic(__entry->pe_size, + { PE_SIZE_PTE, "PTE" }, + { PE_SIZE_PMD, "PMD" }, + { PE_SIZE_PUD, "PUD" }), + __entry->write_fault) +) + DECLARE_EVENT_CLASS(xfs_iref_class, TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), TP_ARGS(ip, caller_ip), @@ -1963,6 +1985,24 @@ DEFINE_EVENT(xfs_swap_extent_class, name, \ DEFINE_SWAPEXT_EVENT(xfs_swap_extent_before); DEFINE_SWAPEXT_EVENT(xfs_swap_extent_after); +TRACE_EVENT(xfs_log_recover, + TP_PROTO(struct xlog *log, xfs_daddr_t headblk, xfs_daddr_t tailblk), + TP_ARGS(log, headblk, tailblk), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_daddr_t, headblk) + __field(xfs_daddr_t, tailblk) + ), + TP_fast_assign( + __entry->dev = log->l_mp->m_super->s_dev; + __entry->headblk = headblk; + __entry->tailblk = tailblk; + ), + TP_printk("dev %d:%d headblk 0x%llx tailblk 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->headblk, + __entry->tailblk) +) + TRACE_EVENT(xfs_log_recover_record, TP_PROTO(struct xlog *log, struct xlog_rec_header *rhead, int pass), TP_ARGS(log, rhead, pass), diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 2011620008de8a4d422643bc20dbc2313873c16e..a87f657f59c96dbf32241f30335b9b1b2a4f1538 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1035,25 +1035,18 @@ xfs_trans_cancel( */ int xfs_trans_roll( - struct xfs_trans **tpp, - struct xfs_inode *dp) + struct xfs_trans **tpp) { - struct xfs_trans *trans; + struct xfs_trans *trans = *tpp; struct xfs_trans_res tres; int error; - /* - * Ensure that the inode is always logged. - */ - trans = *tpp; - if (dp) - xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); - /* * Copy the critical parameters from one trans to the next. */ tres.tr_logres = trans->t_log_res; tres.tr_logcount = trans->t_log_count; + *tpp = xfs_trans_dup(trans); /* @@ -1067,10 +1060,8 @@ xfs_trans_roll( if (error) return error; - trans = *tpp; - /* - * Reserve space in the log for th next transaction. + * Reserve space in the log for the next transaction. * This also pushes items in the "AIL", the list of logged items, * out to disk if they are taking up space at the tail of the log * that we want to use. This requires that either nothing be locked @@ -1078,14 +1069,5 @@ xfs_trans_roll( * the prior and the next transactions. */ tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; - error = xfs_trans_reserve(trans, &tres, 0, 0); - /* - * Ensure that the inode is in the new transaction and locked. - */ - if (error) - return error; - - if (dp) - xfs_trans_ijoin(trans, dp, 0); - return 0; + return xfs_trans_reserve(*tpp, &tres, 0, 0); } diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 6bdad6f5893453d534b147caa1ba52fd2fb6ec4c..815b53d20e262770c21d6cf8609511a50f851bae 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -49,6 +49,7 @@ typedef struct xfs_log_item { struct xfs_ail *li_ailp; /* ptr to AIL */ uint li_type; /* item type */ uint li_flags; /* misc flags */ + struct xfs_buf *li_buf; /* real buffer pointer */ struct xfs_log_item *li_bio_list; /* buffer item list */ void (*li_cb)(struct xfs_buf *, struct xfs_log_item *); @@ -64,11 +65,13 @@ typedef struct xfs_log_item { } xfs_log_item_t; #define XFS_LI_IN_AIL 0x1 -#define XFS_LI_ABORTED 0x2 +#define XFS_LI_ABORTED 0x2 +#define XFS_LI_FAILED 0x4 #define XFS_LI_FLAGS \ { XFS_LI_IN_AIL, "IN_AIL" }, \ - { XFS_LI_ABORTED, "ABORTED" } + { XFS_LI_ABORTED, "ABORTED" }, \ + { XFS_LI_FAILED, "FAILED" } struct xfs_item_ops { void (*iop_size)(xfs_log_item_t *, int *, int *); @@ -79,6 +82,7 @@ struct xfs_item_ops { void (*iop_unlock)(xfs_log_item_t *); xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); + void (*iop_error)(xfs_log_item_t *, xfs_buf_t *); }; void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, @@ -208,12 +212,14 @@ void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); -void xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *); +bool xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *); void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); -void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); +void xfs_trans_log_buf(struct xfs_trans *, struct xfs_buf *, uint, + uint); +void xfs_trans_dirty_buf(struct xfs_trans *, struct xfs_buf *); void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); void xfs_extent_free_init_defer_op(void); @@ -224,7 +230,8 @@ int xfs_trans_free_extent(struct xfs_trans *, struct xfs_efd_log_item *, xfs_fsblock_t, xfs_extlen_t, struct xfs_owner_info *); int xfs_trans_commit(struct xfs_trans *); -int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); +int xfs_trans_roll(struct xfs_trans **); +int xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *); void xfs_trans_cancel(xfs_trans_t *); int xfs_trans_ail_init(struct xfs_mount *); void xfs_trans_ail_destroy(struct xfs_mount *); diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 9056c0f34a3c42d40a6acaba8a189a55bbf0cc97..354368a906e593c9e1e3a268c38919bbb5a20ab7 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -325,6 +325,21 @@ xfs_ail_delete( xfs_trans_ail_cursor_clear(ailp, lip); } +static inline uint +xfsaild_push_item( + struct xfs_ail *ailp, + struct xfs_log_item *lip) +{ + /* + * If log item pinning is enabled, skip the push and track the item as + * pinned. This can help induce head-behind-tail conditions. + */ + if (XFS_TEST_ERROR(false, ailp->xa_mount, XFS_ERRTAG_LOG_ITEM_PIN)) + return XFS_ITEM_PINNED; + + return lip->li_ops->iop_push(lip, &ailp->xa_buf_list); +} + static long xfsaild_push( struct xfs_ail *ailp) @@ -382,7 +397,7 @@ xfsaild_push( * rely on the AIL cursor implementation to be able to deal with * the dropped lock. */ - lock_result = lip->li_ops->iop_push(lip, &ailp->xa_buf_list); + lock_result = xfsaild_push_item(ailp, lip); switch (lock_result) { case XFS_ITEM_SUCCESS: XFS_STATS_INC(mp, xs_push_ail_success); @@ -687,12 +702,13 @@ xfs_trans_ail_update_bulk( bool xfs_ail_delete_one( struct xfs_ail *ailp, - struct xfs_log_item *lip) + struct xfs_log_item *lip) { struct xfs_log_item *mlip = xfs_ail_min(ailp); trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn); xfs_ail_delete(ailp, lip); + xfs_clear_li_failed(lip); lip->li_flags &= ~XFS_LI_IN_AIL; lip->li_lsn = 0; diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 86987d823d764415e938ac0fad77e90a4e97bfb3..3ba7a96a8abdb3c00f1f2c614a24c6063e2d89fc 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -435,7 +435,7 @@ xfs_trans_brelse(xfs_trans_t *tp, if (XFS_FORCED_SHUTDOWN(tp->t_mountp) && freed) { xfs_trans_ail_remove(&bip->bli_item, SHUTDOWN_LOG_IO_ERROR); xfs_buf_item_relse(bp); - } else if (!xfs_buf_item_dirty(bip)) { + } else if (!(bip->bli_flags & XFS_BLI_DIRTY)) { /*** ASSERT(bp->b_pincount == 0); ***/ @@ -493,25 +493,17 @@ xfs_trans_bhold_release(xfs_trans_t *tp, } /* - * This is called to mark bytes first through last inclusive of the given - * buffer as needing to be logged when the transaction is committed. - * The buffer must already be associated with the given transaction. - * - * First and last are numbers relative to the beginning of this buffer, - * so the first byte in the buffer is numbered 0 regardless of the - * value of b_blkno. + * Mark a buffer dirty in the transaction. */ void -xfs_trans_log_buf(xfs_trans_t *tp, - xfs_buf_t *bp, - uint first, - uint last) +xfs_trans_dirty_buf( + struct xfs_trans *tp, + struct xfs_buf *bp) { - xfs_buf_log_item_t *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_fspriv; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); - ASSERT(first <= last && last < BBTOB(bp->b_length)); ASSERT(bp->b_iodone == NULL || bp->b_iodone == xfs_buf_iodone_callbacks); @@ -531,8 +523,6 @@ xfs_trans_log_buf(xfs_trans_t *tp, bp->b_iodone = xfs_buf_iodone_callbacks; bip->bli_item.li_cb = xfs_buf_iodone; - trace_xfs_trans_log_buf(bip); - /* * If we invalidated the buffer within this transaction, then * cancel the invalidation now that we're dirtying the buffer @@ -545,17 +535,37 @@ xfs_trans_log_buf(xfs_trans_t *tp, bp->b_flags &= ~XBF_STALE; bip->__bli_format.blf_flags &= ~XFS_BLF_CANCEL; } + bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED; tp->t_flags |= XFS_TRANS_DIRTY; bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; +} - /* - * If we have an ordered buffer we are not logging any dirty range but - * it still needs to be marked dirty and that it has been logged. - */ - bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED; - if (!(bip->bli_flags & XFS_BLI_ORDERED)) - xfs_buf_item_log(bip, first, last); +/* + * This is called to mark bytes first through last inclusive of the given + * buffer as needing to be logged when the transaction is committed. + * The buffer must already be associated with the given transaction. + * + * First and last are numbers relative to the beginning of this buffer, + * so the first byte in the buffer is numbered 0 regardless of the + * value of b_blkno. + */ +void +xfs_trans_log_buf( + struct xfs_trans *tp, + struct xfs_buf *bp, + uint first, + uint last) +{ + struct xfs_buf_log_item *bip = bp->b_fspriv; + + ASSERT(first <= last && last < BBTOB(bp->b_length)); + ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED)); + + xfs_trans_dirty_buf(tp, bp); + + trace_xfs_trans_log_buf(bip); + xfs_buf_item_log(bip, first, last); } @@ -708,14 +718,13 @@ xfs_trans_inode_alloc_buf( } /* - * Mark the buffer as ordered for this transaction. This means - * that the contents of the buffer are not recorded in the transaction - * but it is tracked in the AIL as though it was. This allows us - * to record logical changes in transactions rather than the physical - * changes we make to the buffer without changing writeback ordering - * constraints of metadata buffers. + * Mark the buffer as ordered for this transaction. This means that the contents + * of the buffer are not recorded in the transaction but it is tracked in the + * AIL as though it was. This allows us to record logical changes in + * transactions rather than the physical changes we make to the buffer without + * changing writeback ordering constraints of metadata buffers. */ -void +bool xfs_trans_ordered_buf( struct xfs_trans *tp, struct xfs_buf *bp) @@ -726,8 +735,18 @@ xfs_trans_ordered_buf( ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); + if (xfs_buf_item_dirty_format(bip)) + return false; + bip->bli_flags |= XFS_BLI_ORDERED; trace_xfs_buf_item_ordered(bip); + + /* + * We don't log a dirty range of an ordered buffer but it still needs + * to be marked dirty and that it has been logged. + */ + xfs_trans_dirty_buf(tp, bp); + return true; } /* diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index dab8daa676f943c5a26737211a336a4f9889d35a..daa7615497f98b279e6c55398a788b1680d9a7b2 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -134,3 +134,17 @@ xfs_trans_log_inode( flags |= ip->i_itemp->ili_last_fields; ip->i_itemp->ili_fields |= flags; } + +int +xfs_trans_roll_inode( + struct xfs_trans **tpp, + struct xfs_inode *ip) +{ + int error; + + xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); + error = xfs_trans_roll(tpp); + if (!error) + xfs_trans_ijoin(*tpp, ip, 0); + return error; +} diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index d91706c56c633a1eb4ed243cf182d2891200e24d..b317a3644c006817d7c6a2ccc3b0e08cc59e2a3f 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -164,4 +164,35 @@ xfs_trans_ail_copy_lsn( *dst = *src; } #endif + +static inline void +xfs_clear_li_failed( + struct xfs_log_item *lip) +{ + struct xfs_buf *bp = lip->li_buf; + + ASSERT(lip->li_flags & XFS_LI_IN_AIL); + lockdep_assert_held(&lip->li_ailp->xa_lock); + + if (lip->li_flags & XFS_LI_FAILED) { + lip->li_flags &= ~XFS_LI_FAILED; + lip->li_buf = NULL; + xfs_buf_rele(bp); + } +} + +static inline void +xfs_set_li_failed( + struct xfs_log_item *lip, + struct xfs_buf *bp) +{ + lockdep_assert_held(&lip->li_ailp->xa_lock); + + if (!(lip->li_flags & XFS_LI_FAILED)) { + xfs_buf_hold(bp); + lip->li_flags |= XFS_LI_FAILED; + lip->li_buf = bp; + } +} + #endif /* __XFS_TRANS_PRIV_H__ */ diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index b421584033a51dcfdce6918c62bdd6b0273c77e4..d8dd3bf51ca735613d02da030116d0b079f288b0 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -54,6 +54,7 @@ #define METHOD_NAME__CLS "_CLS" #define METHOD_NAME__CRS "_CRS" #define METHOD_NAME__DDN "_DDN" +#define METHOD_NAME__DMA "_DMA" #define METHOD_NAME__HID "_HID" #define METHOD_NAME__INI "_INI" #define METHOD_NAME__PLD "_PLD" diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index ca036620703c6be8c726dd1b77c3e7fc89d9de2a..0887d7cbb7e1428e08e7c9b130ccbd354eb8be78 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h @@ -58,10 +58,10 @@ #include /* ACPICA data types and structures */ #include /* ACPICA exceptions */ #include /* ACPI table definitions */ -#include /* Error output and Debug macros */ #include /* Resource Descriptor structs */ +#include /* Extra environment-specific items */ +#include /* Error output and Debug macros */ #include /* OSL interfaces (ACPICA-to-OS) */ #include /* ACPI core subsystem external interfaces */ -#include /* Extra environment-specific items */ #endif /* __ACPI_H__ */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 68bc6be447fd6d97c4a90d78ed65aa89dead82be..fa1505292f6cda4c4b2434d264d4116bcefe640c 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -316,7 +316,6 @@ struct acpi_device_perf { struct acpi_device_wakeup_flags { u8 valid:1; /* Can successfully enable wakeup? */ u8 notifier_present:1; /* Wake-up notify handler has been installed */ - u8 enabled:1; /* Enabled for wakeup */ }; struct acpi_device_wakeup_context { @@ -333,6 +332,7 @@ struct acpi_device_wakeup { struct acpi_device_wakeup_context context; struct wakeup_source *ws; int prepare_count; + int enable_count; }; struct acpi_device_physical_node { @@ -395,35 +395,45 @@ struct acpi_data_node { struct completion kobj_done; }; -static inline bool is_acpi_node(struct fwnode_handle *fwnode) -{ - return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI - || fwnode->type == FWNODE_ACPI_DATA); -} +extern const struct fwnode_operations acpi_device_fwnode_ops; +extern const struct fwnode_operations acpi_data_fwnode_ops; +extern const struct fwnode_operations acpi_static_fwnode_ops; -static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) -{ - return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI; -} +bool is_acpi_device_node(const struct fwnode_handle *fwnode); +bool is_acpi_data_node(const struct fwnode_handle *fwnode); -static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) +static inline bool is_acpi_node(const struct fwnode_handle *fwnode) { - return is_acpi_device_node(fwnode) ? - container_of(fwnode, struct acpi_device, fwnode) : NULL; + return (is_acpi_device_node(fwnode) || is_acpi_data_node(fwnode)); } -static inline bool is_acpi_data_node(struct fwnode_handle *fwnode) +#define to_acpi_device_node(__fwnode) \ + ({ \ + typeof(__fwnode) __to_acpi_device_node_fwnode = __fwnode; \ + \ + is_acpi_device_node(__to_acpi_device_node_fwnode) ? \ + container_of(__to_acpi_device_node_fwnode, \ + struct acpi_device, fwnode) : \ + NULL; \ + }) + +#define to_acpi_data_node(__fwnode) \ + ({ \ + typeof(__fwnode) __to_acpi_data_node_fwnode = __fwnode; \ + \ + is_acpi_data_node(__to_acpi_data_node_fwnode) ? \ + container_of(__to_acpi_data_node_fwnode, \ + struct acpi_data_node, fwnode) : \ + NULL; \ + }) + +static inline bool is_acpi_static_node(const struct fwnode_handle *fwnode) { - return fwnode && fwnode->type == FWNODE_ACPI_DATA; + return !IS_ERR_OR_NULL(fwnode) && + fwnode->ops == &acpi_static_fwnode_ops; } -static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode) -{ - return is_acpi_data_node(fwnode) ? - container_of(fwnode, struct acpi_data_node, fwnode) : NULL; -} - -static inline bool acpi_data_node_match(struct fwnode_handle *fwnode, +static inline bool acpi_data_node_match(const struct fwnode_handle *fwnode, const char *name) { return is_acpi_data_node(fwnode) ? @@ -578,6 +588,8 @@ struct acpi_pci_root { bool acpi_dma_supported(struct acpi_device *adev); enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev); +int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset, + u64 *size); int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr); void acpi_dma_deconfigure(struct device *dev); @@ -606,6 +618,7 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev); bool acpi_pm_device_can_wakeup(struct device *dev); int acpi_pm_device_sleep_state(struct device *, int *, int); int acpi_pm_set_device_wakeup(struct device *dev, bool enable); +int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable); #else static inline void acpi_pm_wakeup_event(struct device *dev) { @@ -636,6 +649,10 @@ static inline int acpi_pm_set_device_wakeup(struct device *dev, bool enable) { return -ENODEV; } +static inline int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable) +{ + return -ENODEV; +} #endif #ifdef CONFIG_ACPI_SLEEP diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index a59c44c3edd88c397c87f506fd4ffaf448ad1fbf..53c5e2f7bcecd82f824d021de2d31d67e9206c71 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -46,7 +46,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20170531 +#define ACPI_CA_VERSION 0x20170728 #include #include @@ -160,13 +160,14 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE); /* - * Whether or not to verify the table checksum before installation. Set - * this to TRUE to verify the table checksum before install it to the table - * manager. Note that enabling this option causes errors to happen in some - * OSPMs during early initialization stages. Default behavior is to do such - * verification. + * Whether or not to validate (map) an entire table to verify + * checksum/duplication in early stage before install. Set this to TRUE to + * allow early table validation before install it to the table manager. + * Note that enabling this option causes errors to happen in some OSPMs + * during early initialization stages. Default behavior is to allow such + * validation. */ -ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_table_validation, TRUE); /* * Optionally enable output from the AML Debug Object. diff --git a/include/acpi/acrestyp.h b/include/acpi/acrestyp.h index 4f7f39a02820b98ef4cf5bc408fee8593bbc9707..343dbdcef20c66b6a1833d03f23028a625a7bb67 100644 --- a/include/acpi/acrestyp.h +++ b/include/acpi/acrestyp.h @@ -377,13 +377,6 @@ struct acpi_resource_generic_register { u64 address; }; -/* Generic Address Space Access Sizes */ -#define ACPI_ACCESS_SIZE_UNDEFINED 0 -#define ACPI_ACCESS_SIZE_BYTE 1 -#define ACPI_ACCESS_SIZE_WORD 2 -#define ACPI_ACCESS_SIZE_DWORD 3 -#define ACPI_ACCESS_SIZE_QWORD 4 - struct acpi_resource_gpio { u8 revision_id; u8 connection_type; diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index bdc55c0da19cd06c65e589d9071f65c2eb5c2332..89509b86cb54bd04351bdd7cd0da2251dc2f4214 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -394,6 +394,7 @@ struct acpi_table_desc { #define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */ #define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2) /* Virtual address, internallly allocated */ #define ACPI_TABLE_ORIGIN_MASK (3) +#define ACPI_TABLE_IS_VERIFIED (4) #define ACPI_TABLE_IS_LOADED (8) /* diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index 707dda74c272625fe0dc43e4e3d7f85a25484c33..686b6f8c09dc7fd013853c8991cd08a0ee744069 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -76,6 +76,7 @@ #define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */ #define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */ #define ACPI_SIG_MTMR "MTMR" /* MID Timer table */ +#define ACPI_SIG_SDEI "SDEI" /* Software Delegated Exception Interface Table */ #define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ #define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ #define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ @@ -664,7 +665,7 @@ struct acpi_ibft_target { * IORT - IO Remapping Table * * Conforms to "IO Remapping Table System Software on ARM Platforms", - * Document number: ARM DEN 0049B, October 2015 + * Document number: ARM DEN 0049C, May 2017 * ******************************************************************************/ @@ -779,6 +780,8 @@ struct acpi_iort_smmu { #define ACPI_IORT_SMMU_V2 0x00000001 /* Generic SMMUv2 */ #define ACPI_IORT_SMMU_CORELINK_MMU400 0x00000002 /* ARM Corelink MMU-400 */ #define ACPI_IORT_SMMU_CORELINK_MMU500 0x00000003 /* ARM Corelink MMU-500 */ +#define ACPI_IORT_SMMU_CORELINK_MMU401 0x00000004 /* ARM Corelink MMU-401 */ +#define ACPI_IORT_SMMU_CAVIUM_THUNDERX 0x00000005 /* Cavium thunder_x SMMUv2 */ /* Masks for Flags field above */ @@ -799,17 +802,27 @@ struct acpi_iort_smmu_v3 { u32 flags; u32 reserved; u64 vatos_address; - u32 model; /* O: generic SMMUv3 */ + u32 model; u32 event_gsiv; u32 pri_gsiv; u32 gerr_gsiv; u32 sync_gsiv; + u8 pxm; + u8 reserved1; + u16 reserved2; }; +/* Values for Model field above */ + +#define ACPI_IORT_SMMU_V3_GENERIC 0x00000000 /* Generic SMMUv3 */ +#define ACPI_IORT_SMMU_V3_HISILICON_HI161X 0x00000001 /* hi_silicon Hi161x SMMUv3 */ +#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX 0x00000002 /* Cavium CN99xx SMMUv3 */ + /* Masks for Flags field above */ #define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE (1) #define ACPI_IORT_SMMU_V3_HTTU_OVERRIDE (1<<1) +#define ACPI_IORT_SMMU_V3_PXM_VALID (1<<3) /******************************************************************************* * @@ -1120,6 +1133,19 @@ struct acpi_mtmr_entry { u32 irq; }; +/******************************************************************************* + * + * SDEI - Software Delegated Exception Interface Descriptor Table + * + * Conforms to "Software Delegated Exception Interface (SDEI)" ARM DEN0054A, + * May 8th, 2017. Copyright 2017 ARM Ltd. + * + ******************************************************************************/ + +struct acpi_table_sdei { + struct acpi_table_header header; /* Common ACPI table header */ +}; + /******************************************************************************* * * SLIC - Software Licensing Description Table diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 2fcbaec8b3687a6319b80b16e27a886262d6eb0b..4f077edb9b81b8086153609d6b4b22b4a22b96e0 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -166,6 +166,7 @@ typedef u64 acpi_physical_address; #define ACPI_SIZE_MAX ACPI_UINT64_MAX #define ACPI_USE_NATIVE_DIVIDE /* Has native 64-bit integer support */ +#define ACPI_USE_NATIVE_MATH64 /* Has native 64-bit integer support */ /* * In the case of the Itanium Processor Family (IPF), the hardware does not @@ -554,6 +555,13 @@ typedef u64 acpi_integer; #define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8)) #define ACPI_MAKE_RSDP_SIG(dest) (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8)) +/* + * Algorithm to obtain access bit width. + * Can be used with access_width of struct acpi_generic_address and access_size of + * struct acpi_resource_generic_register. + */ +#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + 2)) + /******************************************************************************* * * Miscellaneous constants @@ -775,7 +783,7 @@ typedef u32 acpi_event_status; * | | | | +-- Type of dispatch:to method, handler, notify, or none * | | | +----- Interrupt type: edge or level triggered * | | +------- Is a Wake GPE - * | +--------- Is GPE masked by the software GPE masking mechanism + * | +--------- Has been enabled automatically at init time * +------------ */ #define ACPI_GPE_DISPATCH_NONE (u8) 0x00 @@ -791,6 +799,7 @@ typedef u32 acpi_event_status; #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x08 #define ACPI_GPE_CAN_WAKE (u8) 0x10 +#define ACPI_GPE_AUTO_ENABLED (u8) 0x20 /* * Flags for GPE and Lock interfaces diff --git a/include/acpi/apei.h b/include/acpi/apei.h index 76284bb560a6cd36e7a09253aa67e7363a74be6b..c46694abea28846509f222a613e3e20d8eb799c2 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h @@ -16,7 +16,13 @@ #ifdef __KERNEL__ -extern bool hest_disable; +enum hest_status { + HEST_ENABLED, + HEST_DISABLED, + HEST_NOT_FOUND, +}; + +extern int hest_disable; extern int erst_disable; #ifdef CONFIG_ACPI_APEI_GHES extern bool ghes_disable; diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h index 9f26e01186aea6ccd37d1c7771de3978d9111bb5..9061c5c743b386cb05e065d1158a9fd1ca771dae 100644 --- a/include/acpi/ghes.h +++ b/include/acpi/ghes.h @@ -113,6 +113,11 @@ static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata) return (void *)(gdata) + acpi_hest_get_record_size(gdata); } +#define apei_estatus_for_each_section(estatus, section) \ + for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ + (void *)section - (void *)(estatus + 1) < estatus->data_length; \ + section = acpi_hest_get_next(section)) + int ghes_notify_sea(void); #endif /* GHES_H */ diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 912563c66948e48568e90f618bf1b8872e3342f6..043fd559de6ed6fe16b0eef8feacec40e637a8c6 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -288,6 +288,11 @@ #define ACPI_INLINE #endif +/* Use ordered initialization if compiler doesn't support designated. */ +#ifndef ACPI_STRUCT_INIT +#define ACPI_STRUCT_INIT(field, value) value +#endif + /* * Configurable calling conventions: * @@ -382,8 +387,4 @@ #define ACPI_INIT_FUNCTION #endif -#ifndef ACPI_STRUCT_INIT -#define ACPI_STRUCT_INIT(field, value) value -#endif - #endif /* __ACENV_H__ */ diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 97a7e21cfbe0001795490e40eef05945d455a03f..9c8f8b79644edd44ae5d78281f476d9a1d5fe428 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h @@ -84,4 +84,8 @@ typedef __builtin_va_list va_list; #define COMPILER_VA_MACRO 1 +/* GCC supports native multiply/shift on 32-bit platforms */ + +#define ACPI_USE_NATIVE_MATH64 + #endif /* __ACGCC_H__ */ diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 047f13865608e246bad8dea81f45a4826f05357d..1b473efd9eb6062f342be027403e9735c90b9d29 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -128,6 +128,7 @@ /* Host-dependent types and defines for in-kernel ACPICA */ #define ACPI_MACHINE_WIDTH BITS_PER_LONG +#define ACPI_USE_NATIVE_MATH64 #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); #define strtoul simple_strtoul @@ -178,6 +179,9 @@ #define ACPI_MSG_BIOS_ERROR KERN_ERR "ACPI BIOS Error (bug): " #define ACPI_MSG_BIOS_WARNING KERN_WARNING "ACPI BIOS Warning (bug): " +/* + * Linux wants to use designated initializers for function pointer structs. + */ #define ACPI_STRUCT_INIT(field, value) .field = value #else /* !__KERNEL__ */ @@ -213,6 +217,7 @@ #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long #define ACPI_USE_NATIVE_DIVIDE +#define ACPI_USE_NATIVE_MATH64 #endif #ifndef __cdecl diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h index dad68bf46c77012e144857898093b99dabea1cd7..8d28eb010d0d11a2f35f769f7ef51cd753a42a94 100644 --- a/include/asm-generic/atomic64.h +++ b/include/asm-generic/atomic64.h @@ -21,6 +21,8 @@ typedef struct { extern long long atomic64_read(const atomic64_t *v); extern void atomic64_set(atomic64_t *v, long long i); +#define atomic64_set_release(v, i) atomic64_set((v), (i)) + #define ATOMIC64_OP(op) \ extern void atomic64_##op(long long a, atomic64_t *v); diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h index 734ad4db388c6d922fb812391f913cbdda710f12..2edef8d7fa6b8a1fe65bacb8e0d110f55b5e803f 100644 --- a/include/asm-generic/early_ioremap.h +++ b/include/asm-generic/early_ioremap.h @@ -13,6 +13,8 @@ extern void *early_memremap(resource_size_t phys_addr, unsigned long size); extern void *early_memremap_ro(resource_size_t phys_addr, unsigned long size); +extern void *early_memremap_prot(resource_size_t phys_addr, + unsigned long size, unsigned long prot_val); extern void early_iounmap(void __iomem *addr, unsigned long size); extern void early_memunmap(void *addr, unsigned long size); diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h index bf2d34c9d804334cd0c634bf4d8ed921c08cfd7a..f0d8b1c51343c813761416d147255aeac9e74140 100644 --- a/include/asm-generic/futex.h +++ b/include/asm-generic/futex.h @@ -13,7 +13,7 @@ */ /** - * futex_atomic_op_inuser() - Atomic arithmetic operation with constant + * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant * argument and comparison of the previous * futex value with another constant. * @@ -25,18 +25,11 @@ * <0 - On error */ static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval, ret; u32 tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - preempt_disable(); pagefault_disable(); @@ -74,17 +67,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); preempt_enable(); - if (ret == 0) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (ret == 0) + *oval = oldval; + return ret; } @@ -126,18 +111,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #else static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -153,17 +129,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 7ef015eb3403fb150511351049395480fe631da6..b4531e3b212092e37032a68c14eba2dcff76f504 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -915,6 +915,9 @@ extern void ioport_unmap(void __iomem *p); #endif /* CONFIG_GENERIC_IOMAP */ #endif /* CONFIG_HAS_IOPORT_MAP */ +/* + * Convert a virtual cached pointer to an uncached pointer + */ #ifndef xlate_dev_kmem_ptr #define xlate_dev_kmem_ptr xlate_dev_kmem_ptr static inline void *xlate_dev_kmem_ptr(void *addr) @@ -954,6 +957,14 @@ static inline void *bus_to_virt(unsigned long address) #ifndef memset_io #define memset_io memset_io +/** + * memset_io Set a range of I/O memory to a constant value + * @addr: The beginning of the I/O-memory range to set + * @val: The value to set the memory to + * @count: The number of bytes to set + * + * Set a range of I/O memory to a given value. + */ static inline void memset_io(volatile void __iomem *addr, int value, size_t size) { @@ -963,6 +974,14 @@ static inline void memset_io(volatile void __iomem *addr, int value, #ifndef memcpy_fromio #define memcpy_fromio memcpy_fromio +/** + * memcpy_fromio Copy a block of data from I/O memory + * @dst: The (RAM) destination for the copy + * @src: The (I/O memory) source for the data + * @count: The number of bytes to copy + * + * Copy a block of data from I/O memory. + */ static inline void memcpy_fromio(void *buffer, const volatile void __iomem *addr, size_t size) @@ -973,6 +992,14 @@ static inline void memcpy_fromio(void *buffer, #ifndef memcpy_toio #define memcpy_toio memcpy_toio +/** + * memcpy_toio Copy a block of data into I/O memory + * @dst: The (I/O memory) destination for the copy + * @src: The (RAM) source for the data + * @count: The number of bytes to copy + * + * Copy a block of data to I/O memory. + */ static inline void memcpy_toio(volatile void __iomem *addr, const void *buffer, size_t size) { diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 0504ef8f3aa31d5e7a9f0d86d1cb3fc130fee9e0..976f8ac26665b3f4f03cbbfe5222277d9827d847 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -115,15 +115,35 @@ do { \ (__ret); \ }) -#define this_cpu_generic_read(pcp) \ +#define __this_cpu_generic_read_nopreempt(pcp) \ ({ \ typeof(pcp) __ret; \ preempt_disable_notrace(); \ - __ret = raw_cpu_generic_read(pcp); \ + __ret = READ_ONCE(*raw_cpu_ptr(&(pcp))); \ preempt_enable_notrace(); \ __ret; \ }) +#define __this_cpu_generic_read_noirq(pcp) \ +({ \ + typeof(pcp) __ret; \ + unsigned long __flags; \ + raw_local_irq_save(__flags); \ + __ret = raw_cpu_generic_read(pcp); \ + raw_local_irq_restore(__flags); \ + __ret; \ +}) + +#define this_cpu_generic_read(pcp) \ +({ \ + typeof(pcp) __ret; \ + if (__native_word(pcp)) \ + __ret = __this_cpu_generic_read_nopreempt(pcp); \ + else \ + __ret = __this_cpu_generic_read_noirq(pcp); \ + __ret; \ +}) + #define this_cpu_generic_to_op(pcp, val, op) \ do { \ unsigned long __flags; \ diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 7dfa767dc68012ac52ac81d48e92b3ec79c97311..8e02430365640e2e026c1a244eef70dadab6e080 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -582,6 +582,18 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, #endif /* __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION */ #endif /* CONFIG_MMU */ +/* + * No-op macros that just return the current protection value. Defined here + * because these macros can be used used even if CONFIG_MMU is not defined. + */ +#ifndef pgprot_encrypted +#define pgprot_encrypted(prot) (prot) +#endif + +#ifndef pgprot_decrypted +#define pgprot_decrypted(prot) (prot) +#endif + /* * A facility to provide lazy MMU batching. This allows PTE updates and * page invalidations to be delayed until a call to leave lazy MMU mode @@ -618,7 +630,24 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, #define arch_start_context_switch(prev) do {} while (0) #endif -#ifndef CONFIG_HAVE_ARCH_SOFT_DIRTY +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY +#ifndef CONFIG_ARCH_ENABLE_THP_MIGRATION +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) +{ + return pmd; +} + +static inline int pmd_swp_soft_dirty(pmd_t pmd) +{ + return 0; +} + +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) +{ + return pmd; +} +#endif +#else /* !CONFIG_HAVE_ARCH_SOFT_DIRTY */ static inline int pte_soft_dirty(pte_t pte) { return 0; @@ -663,6 +692,21 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) { return pte; } + +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) +{ + return pmd; +} + +static inline int pmd_swp_soft_dirty(pmd_t pmd) +{ + return 0; +} + +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) +{ + return pmd; +} #endif #ifndef __HAVE_PFNMAP_TRACKING @@ -834,7 +878,23 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd) #ifdef CONFIG_TRANSPARENT_HUGEPAGE barrier(); #endif - if (pmd_none(pmdval) || pmd_trans_huge(pmdval)) + /* + * !pmd_present() checks for pmd migration entries + * + * The complete check uses is_pmd_migration_entry() in linux/swapops.h + * But using that requires moving current function and pmd_trans_unstable() + * to linux/swapops.h to resovle dependency, which is too much code move. + * + * !pmd_present() is equivalent to is_pmd_migration_entry() currently, + * because !pmd_present() pages can only be under migration not swapped + * out. + * + * pmd_none() is preseved for future condition checks on pmd migration + * entries and not confusing with this function name, although it is + * redundant with !pmd_present(). + */ + if (pmd_none(pmdval) || pmd_trans_huge(pmdval) || + (IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION) && !pmd_present(pmdval))) return 1; if (unlikely(pmd_bad(pmdval))) { pmd_clear_bad(pmd); diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h index 9f0681bf1e87d6ec0b2a224168fccc944286f29e..66260777d64470a2ce016b4bb94ed660ab5fa6a0 100644 --- a/include/asm-generic/qspinlock.h +++ b/include/asm-generic/qspinlock.h @@ -21,17 +21,6 @@ #include -/** - * queued_spin_unlock_wait - wait until the _current_ lock holder releases the lock - * @lock : Pointer to queued spinlock structure - * - * There is a very slight possibility of live-lock if the lockers keep coming - * and the waiter is just unfortunate enough to not see any unlock state. - */ -#ifndef queued_spin_unlock_wait -extern void queued_spin_unlock_wait(struct qspinlock *lock); -#endif - /** * queued_spin_is_locked - is the spinlock locked? * @lock: Pointer to queued spinlock structure @@ -41,8 +30,6 @@ extern void queued_spin_unlock_wait(struct qspinlock *lock); static __always_inline int queued_spin_is_locked(struct qspinlock *lock) { /* - * See queued_spin_unlock_wait(). - * * Any !0 state indicates it is locked, even if _Q_LOCKED_VAL * isn't immediately observable. */ @@ -135,6 +122,5 @@ static __always_inline bool virt_spin_lock(struct qspinlock *lock) #define arch_spin_trylock(l) queued_spin_trylock(l) #define arch_spin_unlock(l) queued_spin_unlock(l) #define arch_spin_lock_flags(l, f) queued_spin_lock(l) -#define arch_spin_unlock_wait(l) queued_spin_unlock_wait(l) #endif /* __ASM_GENERIC_QSPINLOCK_H */ diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 532372c6cf15c8084f4910072e96fd0360bad2cd..e5da44eddd2f3ca7ccaa9f3d78c11eb1775d3b94 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -27,6 +27,8 @@ * __kprobes_text_start, __kprobes_text_end * __entry_text_start, __entry_text_end * __ctors_start, __ctors_end + * __irqentry_text_start, __irqentry_text_end + * __softirqentry_text_start, __softirqentry_text_end */ extern char _text[], _stext[], _etext[]; extern char _data[], _sdata[], _edata[]; @@ -39,6 +41,8 @@ extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[]; extern char __kprobes_text_start[], __kprobes_text_end[]; extern char __entry_text_start[], __entry_text_end[]; extern char __start_rodata[], __end_rodata[]; +extern char __irqentry_text_start[], __irqentry_text_end[]; +extern char __softirqentry_text_start[], __softirqentry_text_end[]; /* Start and end of .ctors section - used for constructor calls. */ extern char __ctors_start[], __ctors_end[]; diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index 8afa4335e5b2bfd0c42c00e1b1506d4e1f7377ac..faddde44de8c902e6884e64eeb8b22bd0d11b75a 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -112,10 +112,11 @@ struct mmu_gather { #define HAVE_GENERIC_MMU_GATHER -void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end); +void arch_tlb_gather_mmu(struct mmu_gather *tlb, + struct mm_struct *mm, unsigned long start, unsigned long end); void tlb_flush_mmu(struct mmu_gather *tlb); -void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, - unsigned long end); +void arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force); extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_size); diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h index fc824e2828f3cacad21cd7d3d9d98261cf1d78fb..5d2add1a6c964870b212f848879338f7b9b3ba18 100644 --- a/include/asm-generic/topology.h +++ b/include/asm-generic/topology.h @@ -48,7 +48,11 @@ #define parent_node(node) ((void)(node),0) #endif #ifndef cpumask_of_node -#define cpumask_of_node(node) ((void)node, cpu_online_mask) + #ifdef CONFIG_NEED_MULTIPLE_NODES + #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask) + #else + #define cpumask_of_node(node) ((void)node, cpu_online_mask) + #endif #endif #ifndef pcibus_to_node #define pcibus_to_node(bus) ((void)(bus), -1) diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index 723e81a6c162052e82849864d37794541ac82f38..2e51f6e7b3c26d4f6102db05211b5e7a88306dda 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -75,10 +75,10 @@ static inline int __access_ok(unsigned long addr, unsigned long size) #define put_user(x, ptr) \ ({ \ - void *__p = (ptr); \ + void __user *__p = (ptr); \ might_fault(); \ access_ok(VERIFY_WRITE, __p, sizeof(*ptr)) ? \ - __put_user((x), ((__typeof__(*(ptr)) *)__p)) : \ + __put_user((x), ((__typeof__(*(ptr)) __user *)__p)) : \ -EFAULT; \ }) @@ -137,10 +137,10 @@ extern int __put_user_bad(void) __attribute__((noreturn)); #define get_user(x, ptr) \ ({ \ - const void *__p = (ptr); \ + const void __user *__p = (ptr); \ might_fault(); \ access_ok(VERIFY_READ, __p, sizeof(*ptr)) ? \ - __get_user((x), (__typeof__(*(ptr)) *)__p) : \ + __get_user((x), (__typeof__(*(ptr)) __user *)__p) :\ ((x) = (__typeof__(*(ptr)))0,-EFAULT); \ }) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index da0be9a8d1de4c239e53aec01a5e8b9cd87e3bdd..8acfc1e099e11079cde2ed23d028bd6d5fb79bc6 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -59,6 +59,22 @@ /* Align . to a 8 byte boundary equals to maximum function alignment. */ #define ALIGN_FUNCTION() . = ALIGN(8) +/* + * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections, which + * generates .data.identifier sections, which need to be pulled in with + * .data. We don't want to pull in .data..other sections, which Linux + * has defined. Same for text and bss. + */ +#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION +#define TEXT_MAIN .text .text.[0-9a-zA-Z_]* +#define DATA_MAIN .data .data.[0-9a-zA-Z_]* +#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* +#else +#define TEXT_MAIN .text +#define DATA_MAIN .data +#define BSS_MAIN .bss +#endif + /* * Align to a 32 byte boundary equal to the * alignment gcc 4.5 uses for a struct @@ -198,12 +214,10 @@ /* * .data section - * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections generates - * .data.identifier which needs to be pulled in with .data, but don't want to - * pull in .data..stuff which has its own requirements. Same for bss. */ #define DATA_DATA \ - *(.data .data.[0-9a-zA-Z_]*) \ + *(.xiptext) \ + *(DATA_MAIN) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ MEM_KEEP(init.data) \ @@ -434,16 +448,17 @@ VMLINUX_SYMBOL(__security_initcall_end) = .; \ } -/* .text section. Map to function alignment to avoid address changes +/* + * .text section. Map to function alignment to avoid address changes * during second ld run in second ld pass when generating System.map - * LD_DEAD_CODE_DATA_ELIMINATION option enables -ffunction-sections generates - * .text.identifier which needs to be pulled in with .text , but some - * architectures define .text.foo which is not intended to be pulled in here. - * Those enabling LD_DEAD_CODE_DATA_ELIMINATION must ensure they don't have - * conflicting section names, and must pull in .text.[0-9a-zA-Z_]* */ + * + * TEXT_MAIN here will match .text.fixup and .text.unlikely if dead + * code elimination is enabled, so these sections should be converted + * to use ".." first. + */ #define TEXT_TEXT \ ALIGN_FUNCTION(); \ - *(.text.hot .text .text.fixup .text.unlikely) \ + *(.text.hot TEXT_MAIN .text.fixup .text.unlikely) \ *(.ref.text) \ MEM_KEEP(init.text) \ MEM_KEEP(exit.text) \ @@ -483,25 +498,17 @@ *(.entry.text) \ VMLINUX_SYMBOL(__entry_text_end) = .; -#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) #define IRQENTRY_TEXT \ ALIGN_FUNCTION(); \ VMLINUX_SYMBOL(__irqentry_text_start) = .; \ *(.irqentry.text) \ VMLINUX_SYMBOL(__irqentry_text_end) = .; -#else -#define IRQENTRY_TEXT -#endif -#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) #define SOFTIRQENTRY_TEXT \ ALIGN_FUNCTION(); \ VMLINUX_SYMBOL(__softirqentry_text_start) = .; \ *(.softirqentry.text) \ VMLINUX_SYMBOL(__softirqentry_text_end) = .; -#else -#define SOFTIRQENTRY_TEXT -#endif /* Section used for early init (in .S files) */ #define HEAD_TEXT *(.head.text) @@ -613,7 +620,7 @@ BSS_FIRST_SECTIONS \ *(.bss..page_aligned) \ *(.dynbss) \ - *(.bss .bss.[0-9a-zA-Z_]*) \ + *(BSS_MAIN) \ *(COMMON) \ } @@ -680,6 +687,31 @@ #define BUG_TABLE #endif +#ifdef CONFIG_ORC_UNWINDER +#define ORC_UNWIND_TABLE \ + . = ALIGN(4); \ + .orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_orc_unwind_ip) = .; \ + KEEP(*(.orc_unwind_ip)) \ + VMLINUX_SYMBOL(__stop_orc_unwind_ip) = .; \ + } \ + . = ALIGN(6); \ + .orc_unwind : AT(ADDR(.orc_unwind) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_orc_unwind) = .; \ + KEEP(*(.orc_unwind)) \ + VMLINUX_SYMBOL(__stop_orc_unwind) = .; \ + } \ + . = ALIGN(4); \ + .orc_lookup : AT(ADDR(.orc_lookup) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(orc_lookup) = .; \ + . += (((SIZEOF(.text) + LOOKUP_BLOCK_SIZE - 1) / \ + LOOKUP_BLOCK_SIZE) + 1) * 4; \ + VMLINUX_SYMBOL(orc_lookup_end) = .; \ + } +#else +#define ORC_UNWIND_TABLE +#endif + #ifdef CONFIG_PM_TRACE #define TRACEDATA \ . = ALIGN(4); \ @@ -866,7 +898,7 @@ DATA_DATA \ CONSTRUCTORS \ } \ - BUG_TABLE + BUG_TABLE \ #define INIT_TEXT_SECTION(inittext_align) \ . = ALIGN(inittext_align); \ diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 436c4c2683c7dc81921cb029178967bf0e665abd..e3cebf640c00070e7fcc436e59cb1c59c2d57379 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -192,7 +192,7 @@ static inline unsigned int crypto_queue_len(struct crypto_queue *queue) } void crypto_inc(u8 *a, unsigned int size); -void __crypto_xor(u8 *dst, const u8 *src, unsigned int size); +void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int size); static inline void crypto_xor(u8 *dst, const u8 *src, unsigned int size) { @@ -207,7 +207,26 @@ static inline void crypto_xor(u8 *dst, const u8 *src, unsigned int size) size -= sizeof(unsigned long); } } else { - __crypto_xor(dst, src, size); + __crypto_xor(dst, dst, src, size); + } +} + +static inline void crypto_xor_cpy(u8 *dst, const u8 *src1, const u8 *src2, + unsigned int size) +{ + if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && + __builtin_constant_p(size) && + (size % sizeof(unsigned long)) == 0) { + unsigned long *d = (unsigned long *)dst; + unsigned long *s1 = (unsigned long *)src1; + unsigned long *s2 = (unsigned long *)src2; + + while (size > 0) { + *d++ = *s1++ ^ *s2++; + size -= sizeof(unsigned long); + } + } else { + __crypto_xor(dst, src1, src2, size); } } diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index e2b9c6fe271496e45dca5abb94d814dd8a9c3c04..75ec9c662268bc6d0fcd1226116b4faa7469c0e5 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -20,6 +20,9 @@ #include #include +#include +#include + #define ALG_MAX_PAGES 16 struct crypto_async_request; @@ -68,6 +71,99 @@ struct af_alg_sgl { unsigned int npages; }; +/* TX SGL entry */ +struct af_alg_tsgl { + struct list_head list; + unsigned int cur; /* Last processed SG entry */ + struct scatterlist sg[0]; /* Array of SGs forming the SGL */ +}; + +#define MAX_SGL_ENTS ((4096 - sizeof(struct af_alg_tsgl)) / \ + sizeof(struct scatterlist) - 1) + +/* RX SGL entry */ +struct af_alg_rsgl { + struct af_alg_sgl sgl; + struct list_head list; + size_t sg_num_bytes; /* Bytes of data in that SGL */ +}; + +/** + * struct af_alg_async_req - definition of crypto request + * @iocb: IOCB for AIO operations + * @sk: Socket the request is associated with + * @first_rsgl: First RX SG + * @last_rsgl: Pointer to last RX SG + * @rsgl_list: Track RX SGs + * @tsgl: Private, per request TX SGL of buffers to process + * @tsgl_entries: Number of entries in priv. TX SGL + * @outlen: Number of output bytes generated by crypto op + * @areqlen: Length of this data structure + * @cra_u: Cipher request + */ +struct af_alg_async_req { + struct kiocb *iocb; + struct sock *sk; + + struct af_alg_rsgl first_rsgl; + struct af_alg_rsgl *last_rsgl; + struct list_head rsgl_list; + + struct scatterlist *tsgl; + unsigned int tsgl_entries; + + unsigned int outlen; + unsigned int areqlen; + + union { + struct aead_request aead_req; + struct skcipher_request skcipher_req; + } cra_u; + + /* req ctx trails this struct */ +}; + +/** + * struct af_alg_ctx - definition of the crypto context + * + * The crypto context tracks the input data during the lifetime of an AF_ALG + * socket. + * + * @tsgl_list: Link to TX SGL + * @iv: IV for cipher operation + * @aead_assoclen: Length of AAD for AEAD cipher operations + * @completion: Work queue for synchronous operation + * @used: TX bytes sent to kernel. This variable is used to + * ensure that user space cannot cause the kernel + * to allocate too much memory in sendmsg operation. + * @rcvused: Total RX bytes to be filled by kernel. This variable + * is used to ensure user space cannot cause the kernel + * to allocate too much memory in a recvmsg operation. + * @more: More data to be expected from user space? + * @merge: Shall new data from user space be merged into existing + * SG? + * @enc: Cryptographic operation to be performed when + * recvmsg is invoked. + * @len: Length of memory allocated for this data structure. + */ +struct af_alg_ctx { + struct list_head tsgl_list; + + void *iv; + size_t aead_assoclen; + + struct af_alg_completion completion; + + size_t used; + size_t rcvused; + + bool more; + bool merge; + bool enc; + + unsigned int len; +}; + int af_alg_register_type(const struct af_alg_type *type); int af_alg_unregister_type(const struct af_alg_type *type); @@ -94,4 +190,78 @@ static inline void af_alg_init_completion(struct af_alg_completion *completion) init_completion(&completion->completion); } +/** + * Size of available buffer for sending data from user space to kernel. + * + * @sk socket of connection to user space + * @return number of bytes still available + */ +static inline int af_alg_sndbuf(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct af_alg_ctx *ctx = ask->private; + + return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - + ctx->used, 0); +} + +/** + * Can the send buffer still be written to? + * + * @sk socket of connection to user space + * @return true => writable, false => not writable + */ +static inline bool af_alg_writable(struct sock *sk) +{ + return PAGE_SIZE <= af_alg_sndbuf(sk); +} + +/** + * Size of available buffer used by kernel for the RX user space operation. + * + * @sk socket of connection to user space + * @return number of bytes still available + */ +static inline int af_alg_rcvbuf(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct af_alg_ctx *ctx = ask->private; + + return max_t(int, max_t(int, sk->sk_rcvbuf & PAGE_MASK, PAGE_SIZE) - + ctx->rcvused, 0); +} + +/** + * Can the RX buffer still be written to? + * + * @sk socket of connection to user space + * @return true => writable, false => not writable + */ +static inline bool af_alg_readable(struct sock *sk) +{ + return PAGE_SIZE <= af_alg_rcvbuf(sk); +} + +int af_alg_alloc_tsgl(struct sock *sk); +unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset); +void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, + size_t dst_offset); +void af_alg_free_areq_sgls(struct af_alg_async_req *areq); +int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags); +void af_alg_wmem_wakeup(struct sock *sk); +int af_alg_wait_for_data(struct sock *sk, unsigned flags); +void af_alg_data_wakeup(struct sock *sk); +int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, + unsigned int ivsize); +ssize_t af_alg_sendpage(struct socket *sock, struct page *page, + int offset, size_t size, int flags); +void af_alg_async_cb(struct crypto_async_request *_req, int err); +unsigned int af_alg_poll(struct file *file, struct socket *sock, + poll_table *wait); +struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, + unsigned int areqlen); +int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, + struct af_alg_async_req *areq, size_t maxsize, + size_t *outlen); + #endif /* _CRYPTO_IF_ALG_H */ diff --git a/include/crypto/internal/akcipher.h b/include/crypto/internal/akcipher.h index 479a0078f0f701b4d988e1651476e05e1210d761..805686ba2be47969213cf1f6a1547bbfcab77186 100644 --- a/include/crypto/internal/akcipher.h +++ b/include/crypto/internal/akcipher.h @@ -38,6 +38,12 @@ static inline void *akcipher_request_ctx(struct akcipher_request *req) return req->__ctx; } +static inline void akcipher_set_reqsize(struct crypto_akcipher *akcipher, + unsigned int reqsize) +{ + crypto_akcipher_alg(akcipher)->reqsize = reqsize; +} + static inline void *akcipher_tfm_ctx(struct crypto_akcipher *tfm) { return tfm->base.__crt_ctx; diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index f6d9af3efa45a6cc8eb448a71f5d43d72d8fcbd1..f0b44c16e88f241721a4296019475abae6b7a3b0 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -76,6 +76,8 @@ static inline int crypto_ahash_walk_last(struct crypto_hash_walk *walk) int crypto_register_ahash(struct ahash_alg *alg); int crypto_unregister_ahash(struct ahash_alg *alg); +int crypto_register_ahashes(struct ahash_alg *algs, int count); +void crypto_unregister_ahashes(struct ahash_alg *algs, int count); int ahash_register_instance(struct crypto_template *tmpl, struct ahash_instance *inst); void ahash_free_instance(struct crypto_instance *inst); diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h index 2133d17b7156eb3340b45ba037bc1ca399f32e2e..1bde0a6514fa682deafb3141376f57949504c1e6 100644 --- a/include/crypto/kpp.h +++ b/include/crypto/kpp.h @@ -145,6 +145,16 @@ static inline struct crypto_kpp *crypto_kpp_reqtfm(struct kpp_request *req) return __crypto_kpp_tfm(req->base.tfm); } +static inline u32 crypto_kpp_get_flags(struct crypto_kpp *tfm) +{ + return crypto_tfm_get_flags(crypto_kpp_tfm(tfm)); +} + +static inline void crypto_kpp_set_flags(struct crypto_kpp *tfm, u32 flags) +{ + crypto_tfm_set_flags(crypto_kpp_tfm(tfm), flags); +} + /** * crypto_free_kpp() - free KPP tfm handle * diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h new file mode 100644 index 0000000000000000000000000000000000000000..9b30fec302c8cd84e0621b20e4c0ccc92cf24165 --- /dev/null +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) STMicroelectronics SA 2017 + * + * Authors: Philippe Cornu + * Yannick Fertre + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef __DW_MIPI_DSI__ +#define __DW_MIPI_DSI__ + +struct dw_mipi_dsi_phy_ops { + int (*init)(void *priv_data); + int (*get_lane_mbps)(void *priv_data, struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format, + unsigned int *lane_mbps); +}; + +struct dw_mipi_dsi_plat_data { + void __iomem *base; + unsigned int max_data_lanes; + + enum drm_mode_status (*mode_valid)(void *priv_data, + const struct drm_display_mode *mode); + + const struct dw_mipi_dsi_phy_ops *phy_ops; + + void *priv_data; +}; + +int dw_mipi_dsi_probe(struct platform_device *pdev, + const struct dw_mipi_dsi_plat_data *plat_data); +void dw_mipi_dsi_remove(struct platform_device *pdev); +int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder, + const struct dw_mipi_dsi_plat_data *plat_data); +void dw_mipi_dsi_unbind(struct device *dev); + +#endif /* __DW_MIPI_DSI__ */ diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 39df16af7a4a41e1082c6403e3bd3bc47d168fec..7277783a4ff00c1db7c3816c73547f4e0defd96b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -82,19 +82,10 @@ #include #include #include - +#include struct module; -struct drm_device; -struct drm_agp_head; -struct drm_local_map; -struct drm_device_dma; -struct drm_gem_object; -struct drm_master; -struct drm_vblank_crtc; -struct drm_vma_offset_manager; - struct device_node; struct videomode; struct reservation_object; @@ -305,143 +296,6 @@ struct pci_controller; #define DRM_IF_VERSION(maj, min) (maj << 16 | min) -/** - * DRM device structure. This structure represent a complete card that - * may contain multiple heads. - */ -struct drm_device { - struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */ - int if_version; /**< Highest interface version set */ - - /** \name Lifetime Management */ - /*@{ */ - struct kref ref; /**< Object ref-count */ - struct device *dev; /**< Device structure of bus-device */ - struct drm_driver *driver; /**< DRM driver managing the device */ - void *dev_private; /**< DRM driver private data */ - struct drm_minor *control; /**< Control node */ - struct drm_minor *primary; /**< Primary node */ - struct drm_minor *render; /**< Render node */ - bool registered; - - /* currently active master for this device. Protected by master_mutex */ - struct drm_master *master; - - atomic_t unplugged; /**< Flag whether dev is dead */ - struct inode *anon_inode; /**< inode for private address-space */ - char *unique; /**< unique name of the device */ - /*@} */ - - /** \name Locks */ - /*@{ */ - struct mutex struct_mutex; /**< For others */ - struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ - /*@} */ - - /** \name Usage Counters */ - /*@{ */ - int open_count; /**< Outstanding files open, protected by drm_global_mutex. */ - spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */ - int buf_use; /**< Buffers in use -- cannot alloc */ - atomic_t buf_alloc; /**< Buffer allocation in progress */ - /*@} */ - - struct mutex filelist_mutex; - struct list_head filelist; - - /** \name Memory management */ - /*@{ */ - struct list_head maplist; /**< Linked list of regions */ - struct drm_open_hash map_hash; /**< User token hash table for maps */ - - /** \name Context handle management */ - /*@{ */ - struct list_head ctxlist; /**< Linked list of context handles */ - struct mutex ctxlist_mutex; /**< For ctxlist */ - - struct idr ctx_idr; - - struct list_head vmalist; /**< List of vmas (for debugging) */ - - /*@} */ - - /** \name DMA support */ - /*@{ */ - struct drm_device_dma *dma; /**< Optional pointer for DMA support */ - /*@} */ - - /** \name Context support */ - /*@{ */ - - __volatile__ long context_flag; /**< Context swapping flag */ - int last_context; /**< Last current context */ - /*@} */ - - /** - * @irq_enabled: - * - * Indicates that interrupt handling is enabled, specifically vblank - * handling. Drivers which don't use drm_irq_install() need to set this - * to true manually. - */ - bool irq_enabled; - int irq; - - /* - * If true, vblank interrupt will be disabled immediately when the - * refcount drops to zero, as opposed to via the vblank disable - * timer. - * This can be set to true it the hardware has a working vblank - * counter and the driver uses drm_vblank_on() and drm_vblank_off() - * appropriately. - */ - bool vblank_disable_immediate; - - /* array of size num_crtcs */ - struct drm_vblank_crtc *vblank; - - spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ - spinlock_t vbl_lock; - - u32 max_vblank_count; /**< size of vblank counter register */ - - /** - * List of events - */ - struct list_head vblank_event_list; - spinlock_t event_lock; - - /*@} */ - - struct drm_agp_head *agp; /**< AGP data */ - - struct pci_dev *pdev; /**< PCI device structure */ -#ifdef __alpha__ - struct pci_controller *hose; -#endif - - struct drm_sg_mem *sg; /**< Scatter gather memory */ - unsigned int num_crtcs; /**< Number of CRTCs on this device */ - - struct { - int context; - struct drm_hw_lock *lock; - } sigdata; - - struct drm_local_map *agp_buffer_map; - unsigned int agp_buffer_token; - - struct drm_mode_config mode_config; /**< Current mode config */ - - /** \name GEM information */ - /*@{ */ - struct mutex object_name_lock; - struct idr object_name_idr; - struct drm_vma_offset_manager *vma_offset_manager; - /*@} */ - int switch_power_state; -}; - /** * drm_drv_uses_atomic_modeset - check if the driver implements * atomic_commit() @@ -466,19 +320,6 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, return ((dev->driver->driver_features & feature) ? 1 : 0); } -static inline void drm_device_set_unplugged(struct drm_device *dev) -{ - smp_wmb(); - atomic_set(&dev->unplugged, 1); -} - -static inline int drm_device_is_unplugged(struct drm_device *dev) -{ - int ret = atomic_read(&dev->unplugged); - smp_rmb(); - return ret; -} - /******************************************************************/ /** \name Internal function definitions */ /*@{*/ diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 0196f264a418a1d0885cd5cb4ebbf3ab56f3c91e..8a5808eb562876cd35f2d3f098db5c9156757f3b 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -154,6 +154,9 @@ struct __drm_connnectors_state { struct drm_connector_state *state, *old_state, *new_state; }; +struct drm_private_obj; +struct drm_private_state; + /** * struct drm_private_state_funcs - atomic state functions for private objects * @@ -166,7 +169,7 @@ struct __drm_connnectors_state { */ struct drm_private_state_funcs { /** - * @duplicate_state: + * @atomic_duplicate_state: * * Duplicate the current state of the private object and return it. It * is an error to call this before obj->state has been initialized. @@ -176,29 +179,30 @@ struct drm_private_state_funcs { * Duplicated atomic state or NULL when obj->state is not * initialized or allocation failed. */ - void *(*duplicate_state)(struct drm_atomic_state *state, void *obj); + struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj); /** - * @swap_state: + * @atomic_destroy_state: * - * This function swaps the existing state of a private object @obj with - * it's newly created state, the pointer to which is passed as - * @obj_state_ptr. + * Frees the private object state created with @atomic_duplicate_state. */ - void (*swap_state)(void *obj, void **obj_state_ptr); + void (*atomic_destroy_state)(struct drm_private_obj *obj, + struct drm_private_state *state); +}; - /** - * @destroy_state: - * - * Frees the private object state created with @duplicate_state. - */ - void (*destroy_state)(void *obj_state); +struct drm_private_obj { + struct drm_private_state *state; + + const struct drm_private_state_funcs *funcs; +}; + +struct drm_private_state { + struct drm_atomic_state *state; }; struct __drm_private_objs_state { - void *obj; - void *obj_state; - const struct drm_private_state_funcs *funcs; + struct drm_private_obj *ptr; + struct drm_private_state *state, *old_state, *new_state; }; /** @@ -207,6 +211,7 @@ struct __drm_private_objs_state { * @dev: parent DRM device * @allow_modeset: allow full modeset * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics + * @async_update: hint for asynchronous plane update * @planes: pointer to array of structures with per-plane data * @crtcs: pointer to array of CRTC pointers * @num_connector: size of the @connectors and @connector_states arrays @@ -221,6 +226,7 @@ struct drm_atomic_state { struct drm_device *dev; bool allow_modeset : 1; bool legacy_cursor_update : 1; + bool async_update : 1; struct __drm_planes_state *planes; struct __drm_crtcs_state *crtcs; int num_connector; @@ -309,20 +315,18 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, struct drm_plane_state * __must_check drm_atomic_get_plane_state(struct drm_atomic_state *state, struct drm_plane *plane); -int drm_atomic_plane_set_property(struct drm_plane *plane, - struct drm_plane_state *state, struct drm_property *property, - uint64_t val); struct drm_connector_state * __must_check drm_atomic_get_connector_state(struct drm_atomic_state *state, struct drm_connector *connector); -int drm_atomic_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, struct drm_property *property, - uint64_t val); -void * __must_check +void drm_atomic_private_obj_init(struct drm_private_obj *obj, + struct drm_private_state *state, + const struct drm_private_state_funcs *funcs); +void drm_atomic_private_obj_fini(struct drm_private_obj *obj); + +struct drm_private_state * __must_check drm_atomic_get_private_obj_state(struct drm_atomic_state *state, - void *obj, - const struct drm_private_state_funcs *funcs); + struct drm_private_obj *obj); /** * drm_atomic_get_existing_crtc_state - get crtc state, if it exists @@ -541,8 +545,6 @@ int __must_check drm_atomic_add_affected_planes(struct drm_atomic_state *state, struct drm_crtc *crtc); -void drm_atomic_legacy_backoff(struct drm_atomic_state *state); - void drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret); @@ -809,43 +811,63 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); for_each_if (plane) /** - * __for_each_private_obj - iterate over all private objects + * for_each_oldnew_private_obj_in_state - iterate over all private objects in an atomic update * @__state: &struct drm_atomic_state pointer - * @obj: private object iteration cursor - * @obj_state: private object state iteration cursor + * @obj: &struct drm_private_obj iteration cursor + * @old_obj_state: &struct drm_private_state iteration cursor for the old state + * @new_obj_state: &struct drm_private_state iteration cursor for the new state * @__i: int iteration cursor, for macro-internal use - * @__funcs: &struct drm_private_state_funcs iteration cursor * - * This macro iterates over the array containing private object data in atomic - * state + * This iterates over all private objects in an atomic update, tracking both + * old and new state. This is useful in places where the state delta needs + * to be considered, for example in atomic check functions. */ -#define __for_each_private_obj(__state, obj, obj_state, __i, __funcs) \ - for ((__i) = 0; \ - (__i) < (__state)->num_private_objs && \ - ((obj) = (__state)->private_objs[__i].obj, \ - (__funcs) = (__state)->private_objs[__i].funcs, \ - (obj_state) = (__state)->private_objs[__i].obj_state, \ - 1); \ - (__i)++) \ +#define for_each_oldnew_private_obj_in_state(__state, obj, old_obj_state, new_obj_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->num_private_objs && \ + ((obj) = (__state)->private_objs[__i].ptr, \ + (old_obj_state) = (__state)->private_objs[__i].old_state, \ + (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ + (__i)++) \ + for_each_if (obj) /** - * for_each_private_obj - iterate over a specify type of private object + * for_each_old_private_obj_in_state - iterate over all private objects in an atomic update * @__state: &struct drm_atomic_state pointer - * @obj_funcs: &struct drm_private_state_funcs function table to filter - * private objects - * @obj: private object iteration cursor - * @obj_state: private object state iteration cursor + * @obj: &struct drm_private_obj iteration cursor + * @old_obj_state: &struct drm_private_state iteration cursor for the old state * @__i: int iteration cursor, for macro-internal use - * @__funcs: &struct drm_private_state_funcs iteration cursor * - * This macro iterates over the private objects state array while filtering the - * objects based on the vfunc table that is passed as @obj_funcs. New macros - * can be created by passing in the vfunc table associated with a specific - * private object. + * This iterates over all private objects in an atomic update, tracking only + * the old state. This is useful in disable functions, where we need the old + * state the hardware is still in. + */ +#define for_each_old_private_obj_in_state(__state, obj, old_obj_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->num_private_objs && \ + ((obj) = (__state)->private_objs[__i].ptr, \ + (old_obj_state) = (__state)->private_objs[__i].old_state, 1); \ + (__i)++) \ + for_each_if (obj) + +/** + * for_each_new_private_obj_in_state - iterate over all private objects in an atomic update + * @__state: &struct drm_atomic_state pointer + * @obj: &struct drm_private_obj iteration cursor + * @new_obj_state: &struct drm_private_state iteration cursor for the new state + * @__i: int iteration cursor, for macro-internal use + * + * This iterates over all private objects in an atomic update, tracking only + * the new state. This is useful in enable functions, where we need the new state the + * hardware should be in when the atomic commit operation has completed. */ -#define for_each_private_obj(__state, obj_funcs, obj, obj_state, __i, __funcs) \ - __for_each_private_obj(__state, obj, obj_state, __i, __funcs) \ - for_each_if (__funcs == obj_funcs) +#define for_each_new_private_obj_in_state(__state, obj, new_obj_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->num_private_objs && \ + ((obj) = (__state)->private_objs[__i].ptr, \ + (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ + (__i)++) \ + for_each_if (obj) /** * drm_atomic_crtc_needs_modeset - compute combined modeset need @@ -853,7 +875,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); * * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track * whether the state CRTC changed enough to need a full modeset cycle: - * planes_changed, mode_changed and active_changed. This helper simply + * mode_changed, active_changed and connectors_changed. This helper simply * combines these three to compute the overall need for a modeset for @state. * * The atomic helper code sets these booleans, but drivers can and should diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index f0a8678ae98e542c8632262437c3f5568ecf2398..d2b56cc657e933593c8c8298c931876061f46e34 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -33,6 +33,8 @@ #include struct drm_atomic_state; +struct drm_private_obj; +struct drm_private_state; int drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state); @@ -41,9 +43,14 @@ int drm_atomic_helper_check_planes(struct drm_device *dev, int drm_atomic_helper_check(struct drm_device *dev, struct drm_atomic_state *state); void drm_atomic_helper_commit_tail(struct drm_atomic_state *state); +void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *state); int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock); +int drm_atomic_helper_async_check(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_async_commit(struct drm_device *dev, + struct drm_atomic_state *state); int drm_atomic_helper_wait_for_fences(struct drm_device *dev, struct drm_atomic_state *state, @@ -52,6 +59,9 @@ int drm_atomic_helper_wait_for_fences(struct drm_device *dev, void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *old_state); +void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, + struct drm_atomic_state *old_state); + void drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, struct drm_atomic_state *old_state); @@ -77,8 +87,8 @@ void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state, bool atomic); -void drm_atomic_helper_swap_state(struct drm_atomic_state *state, - bool stall); +int __must_check drm_atomic_helper_swap_state(struct drm_atomic_state *state, + bool stall); /* nonblocking commit helpers */ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, @@ -114,15 +124,6 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, int drm_atomic_helper_resume(struct drm_device *dev, struct drm_atomic_state *state); -int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc, - struct drm_property *property, - uint64_t val); -int drm_atomic_helper_plane_set_property(struct drm_plane *plane, - struct drm_property *property, - uint64_t val); -int drm_atomic_helper_connector_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val); int drm_atomic_helper_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, @@ -135,8 +136,6 @@ int drm_atomic_helper_page_flip_target( uint32_t flags, uint32_t target, struct drm_modeset_acquire_ctx *ctx); -int drm_atomic_helper_connector_dpms(struct drm_connector *connector, - int mode); struct drm_encoder * drm_atomic_helper_best_encoder(struct drm_connector *connector); @@ -178,6 +177,8 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, uint32_t size, struct drm_modeset_acquire_ctx *ctx); +void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, + struct drm_private_state *state); /** * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 1dc94d5392e27d6abd6f0f7b4ad2fd8b5ecad975..6522d4cbc9d9d7426728198024ce44aa622f2b32 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -268,6 +268,9 @@ void drm_bridge_enable(struct drm_bridge *bridge); struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel, u32 connector_type); void drm_panel_bridge_remove(struct drm_bridge *bridge); +struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, + struct drm_panel *panel, + u32 connector_type); #endif #endif diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index ae5b7dc316c8ac586f6f72e9d3cb26f5fbec2557..ea8da401c93c14248374ffaabb1675c2e1bf45d4 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -135,6 +135,28 @@ struct drm_scdc { struct drm_hdmi_info { /** @scdc: sink's scdc support and capabilities */ struct drm_scdc scdc; + + /** + * @y420_vdb_modes: bitmap of modes which can support ycbcr420 + * output only (not normal RGB/YCBCR444/422 outputs). There are total + * 107 VICs defined by CEA-861-F spec, so the size is 128 bits to map + * upto 128 VICs; + */ + unsigned long y420_vdb_modes[BITS_TO_LONGS(128)]; + + /** + * @y420_cmdb_modes: bitmap of modes which can support ycbcr420 + * output also, along with normal HDMI outputs. There are total 107 + * VICs defined by CEA-861-F spec, so the size is 128 bits to map upto + * 128 VICs; + */ + unsigned long y420_cmdb_modes[BITS_TO_LONGS(128)]; + + /** @y420_cmdb_map: bitmap of SVD index, to extraxt vcb modes */ + u64 y420_cmdb_map; + + /** @y420_dc_modes: bitmap of deep color support index */ + u8 y420_dc_modes; }; /** @@ -198,6 +220,7 @@ struct drm_display_info { #define DRM_COLOR_FORMAT_RGB444 (1<<0) #define DRM_COLOR_FORMAT_YCRCB444 (1<<1) #define DRM_COLOR_FORMAT_YCRCB422 (1<<2) +#define DRM_COLOR_FORMAT_YCRCB420 (1<<3) /** * @color_formats: HDMI Color formats, selects between RGB and YCrCb @@ -359,8 +382,8 @@ struct drm_connector_funcs { * implement the 4 level DPMS support on the connector any more, but * instead only have an on/off "ACTIVE" property on the CRTC object. * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_connector_dpms() to implement this hook. + * This hook is not used by atomic drivers, remapping of the legacy DPMS + * property is entirely handled in the DRM core. * * RETURNS: * @@ -457,11 +480,9 @@ struct drm_connector_funcs { * This is the legacy entry point to update a property attached to the * connector. * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_connector_set_property() to implement this hook. - * * This callback is optional if the driver does not support any legacy - * driver-private properties. + * driver-private properties. For atomic drivers it is not used because + * property handling is done entirely in the DRM core. * * RETURNS: * @@ -726,6 +747,15 @@ struct drm_connector { bool interlace_allowed; bool doublescan_allowed; bool stereo_allowed; + + /** + * @ycbcr_420_allowed : This bool indicates if this connector is + * capable of handling YCBCR 420 output. While parsing the EDID + * blocks, its very helpful to know, if the source is capable of + * handling YCBCR 420 outputs. + */ + bool ycbcr_420_allowed; + /** * @registered: Is this connector exposed (registered) with userspace? * Protected by @mutex. diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 629a5fe075b3f7fc3d915e8204a279af1211dc5e..1a642020e306778e55ee65e8a535c0746eb07372 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -358,14 +358,6 @@ struct drm_crtc_funcs { * drm_crtc_enable_color_mgmt(), which then supports the legacy gamma * interface through the drm_atomic_helper_legacy_gamma_set() * compatibility implementation. - * - * NOTE: - * - * Drivers that support gamma tables and also fbdev emulation through - * the provided helper library need to take care to fill out the gamma - * hooks for both. Currently there's a bit an unfortunate duplication - * going on, which should eventually be unified to just one set of - * hooks. */ int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t size, @@ -481,11 +473,9 @@ struct drm_crtc_funcs { * This is the legacy entry point to update a property attached to the * CRTC. * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_crtc_set_property() to implement this hook. - * * This callback is optional if the driver does not support any legacy - * driver-private properties. + * driver-private properties. For atomic drivers it is not used because + * property handling is done entirely in the DRM core. * * RETURNS: * @@ -685,6 +675,9 @@ struct drm_crtc_funcs { * drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or * enabling a CRTC. * + * See also &drm_device.vblank_disable_immediate and + * &drm_device.max_vblank_count. + * * Returns: * * Raw vblank counter value. diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h new file mode 100644 index 0000000000000000000000000000000000000000..e21af87a2f3c61a8d69c96ae40d2f9839df99d03 --- /dev/null +++ b/include/drm/drm_device.h @@ -0,0 +1,190 @@ +#ifndef _DRM_DEVICE_H_ +#define _DRM_DEVICE_H_ + +#include +#include +#include +#include + +#include +#include + +struct drm_driver; +struct drm_minor; +struct drm_master; +struct drm_device_dma; +struct drm_vblank_crtc; +struct drm_sg_mem; +struct drm_local_map; +struct drm_vma_offset_manager; + +struct inode; + +struct pci_dev; +struct pci_controller; + +/** + * DRM device structure. This structure represent a complete card that + * may contain multiple heads. + */ +struct drm_device { + struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */ + int if_version; /**< Highest interface version set */ + + /** \name Lifetime Management */ + /*@{ */ + struct kref ref; /**< Object ref-count */ + struct device *dev; /**< Device structure of bus-device */ + struct drm_driver *driver; /**< DRM driver managing the device */ + void *dev_private; /**< DRM driver private data */ + struct drm_minor *control; /**< Control node */ + struct drm_minor *primary; /**< Primary node */ + struct drm_minor *render; /**< Render node */ + bool registered; + + /* currently active master for this device. Protected by master_mutex */ + struct drm_master *master; + + atomic_t unplugged; /**< Flag whether dev is dead */ + struct inode *anon_inode; /**< inode for private address-space */ + char *unique; /**< unique name of the device */ + /*@} */ + + /** \name Locks */ + /*@{ */ + struct mutex struct_mutex; /**< For others */ + struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ + /*@} */ + + /** \name Usage Counters */ + /*@{ */ + int open_count; /**< Outstanding files open, protected by drm_global_mutex. */ + spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */ + int buf_use; /**< Buffers in use -- cannot alloc */ + atomic_t buf_alloc; /**< Buffer allocation in progress */ + /*@} */ + + struct mutex filelist_mutex; + struct list_head filelist; + + /** \name Memory management */ + /*@{ */ + struct list_head maplist; /**< Linked list of regions */ + struct drm_open_hash map_hash; /**< User token hash table for maps */ + + /** \name Context handle management */ + /*@{ */ + struct list_head ctxlist; /**< Linked list of context handles */ + struct mutex ctxlist_mutex; /**< For ctxlist */ + + struct idr ctx_idr; + + struct list_head vmalist; /**< List of vmas (for debugging) */ + + /*@} */ + + /** \name DMA support */ + /*@{ */ + struct drm_device_dma *dma; /**< Optional pointer for DMA support */ + /*@} */ + + /** \name Context support */ + /*@{ */ + + __volatile__ long context_flag; /**< Context swapping flag */ + int last_context; /**< Last current context */ + /*@} */ + + /** + * @irq_enabled: + * + * Indicates that interrupt handling is enabled, specifically vblank + * handling. Drivers which don't use drm_irq_install() need to set this + * to true manually. + */ + bool irq_enabled; + int irq; + + /** + * @vblank_disable_immediate: + * + * If true, vblank interrupt will be disabled immediately when the + * refcount drops to zero, as opposed to via the vblank disable + * timer. + * + * This can be set to true it the hardware has a working vblank counter + * with high-precision timestamping (otherwise there are races) and the + * driver uses drm_crtc_vblank_on() and drm_crtc_vblank_off() + * appropriately. See also @max_vblank_count and + * &drm_crtc_funcs.get_vblank_counter. + */ + bool vblank_disable_immediate; + + /** + * @vblank: + * + * Array of vblank tracking structures, one per &struct drm_crtc. For + * historical reasons (vblank support predates kernel modesetting) this + * is free-standing and not part of &struct drm_crtc itself. It must be + * initialized explicitly by calling drm_vblank_init(). + */ + struct drm_vblank_crtc *vblank; + + spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ + spinlock_t vbl_lock; + + /** + * @max_vblank_count: + * + * Maximum value of the vblank registers. This value +1 will result in a + * wrap-around of the vblank register. It is used by the vblank core to + * handle wrap-arounds. + * + * If set to zero the vblank core will try to guess the elapsed vblanks + * between times when the vblank interrupt is disabled through + * high-precision timestamps. That approach is suffering from small + * races and imprecision over longer time periods, hence exposing a + * hardware vblank counter is always recommended. + * + * If non-zeor, &drm_crtc_funcs.get_vblank_counter must be set. + */ + u32 max_vblank_count; /**< size of vblank counter register */ + + /** + * List of events + */ + struct list_head vblank_event_list; + spinlock_t event_lock; + + /*@} */ + + struct drm_agp_head *agp; /**< AGP data */ + + struct pci_dev *pdev; /**< PCI device structure */ +#ifdef __alpha__ + struct pci_controller *hose; +#endif + + struct drm_sg_mem *sg; /**< Scatter gather memory */ + unsigned int num_crtcs; /**< Number of CRTCs on this device */ + + struct { + int context; + struct drm_hw_lock *lock; + } sigdata; + + struct drm_local_map *agp_buffer_map; + unsigned int agp_buffer_token; + + struct drm_mode_config mode_config; /**< Current mode config */ + + /** \name GEM information */ + /*@{ */ + struct mutex object_name_lock; + struct idr object_name_idr; + struct drm_vma_offset_manager *vma_offset_manager; + /*@} */ + int switch_power_state; +}; + +#endif diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 177ab6f868554c23169c654b7c97545ecf77de14..d55abb75f29ae1f998a8cc3f0124bacfceb10170 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -404,12 +404,17 @@ struct drm_dp_payload { int vcpi; }; +#define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base) + struct drm_dp_mst_topology_state { + struct drm_private_state base; int avail_slots; struct drm_atomic_state *state; struct drm_dp_mst_topology_mgr *mgr; }; +#define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base) + /** * struct drm_dp_mst_topology_mgr - DisplayPort MST manager * @@ -418,6 +423,11 @@ struct drm_dp_mst_topology_state { * on the GPU. */ struct drm_dp_mst_topology_mgr { + /** + * @base: Base private object for atomic + */ + struct drm_private_obj base; + /** * @dev: device pointer for adding i2c devices etc. */ diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d855f9ae41a80e4c77b396e7210609cbee91798e..71bbaaec836d29f491fc78c74c5fa4801873fa9b 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -30,7 +30,8 @@ #include #include -struct drm_device; +#include + struct drm_file; struct drm_gem_object; struct drm_master; @@ -173,8 +174,6 @@ struct drm_driver { */ void (*release) (struct drm_device *); - int (*set_busid)(struct drm_device *dev, struct drm_master *master); - /** * @get_vblank_counter: * @@ -392,6 +391,11 @@ struct drm_driver { */ void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv); + /** + * @debugfs_init: + * + * Allows drivers to create driver-specific debugfs files. + */ int (*debugfs_init)(struct drm_minor *minor); /** @@ -410,7 +414,18 @@ struct drm_driver { */ void (*gem_free_object_unlocked) (struct drm_gem_object *obj); + /** + * @gem_open_object: + * + * Driver hook called upon gem handle creation + */ int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); + + /** + * @gem_close_object: + * + * Driver hook called upon gem handle release + */ void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); /** @@ -423,19 +438,34 @@ struct drm_driver { size_t size); /* prime: */ - /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */ + /** + * @prime_handle_to_fd: + * + * export handle -> fd (see drm_gem_prime_handle_to_fd() helper) + */ int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); - /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */ + /** + * @prime_fd_to_handle: + * + * import fd -> handle (see drm_gem_prime_fd_to_handle() helper) + */ int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle); - /* export GEM -> dmabuf */ + /** + * @gem_prime_export: + * + * export GEM -> dmabuf + */ struct dma_buf * (*gem_prime_export)(struct drm_device *dev, struct drm_gem_object *obj, int flags); - /* import dmabuf -> GEM */ + /** + * @gem_prime_import: + * + * import dmabuf -> GEM + */ struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, struct dma_buf *dma_buf); - /* low-level interface used by drm_gem_prime_{import,export} */ int (*gem_prime_pin)(struct drm_gem_object *obj); void (*gem_prime_unpin)(struct drm_gem_object *obj); struct reservation_object * (*gem_prime_res_obj)( @@ -507,19 +537,46 @@ struct drm_driver { struct drm_device *dev, uint32_t handle); - /* Driver private ops for this object */ + /** + * @gem_vm_ops: Driver private ops for this object + */ const struct vm_operations_struct *gem_vm_ops; + /** @major: driver major number */ int major; + /** @minor: driver minor number */ int minor; + /** @patchlevel: driver patch level */ int patchlevel; + /** @name: driver name */ char *name; + /** @desc: driver description */ char *desc; + /** @date: driver date */ char *date; + /** @driver_features: driver features */ u32 driver_features; + + /** + * @ioctls: + * + * Array of driver-private IOCTL description entries. See the chapter on + * :ref:`IOCTL support in the userland interfaces + * chapter` for the full details. + */ + const struct drm_ioctl_desc *ioctls; + /** @num_ioctls: Number of entries in @ioctls. */ int num_ioctls; + + /** + * @fops: + * + * File operations for the DRM device node. See the discussion in + * :ref:`file operations` for in-depth coverage and + * some examples. + */ const struct file_operations *fops; /* Everything below here is for legacy driver, never use! */ @@ -557,7 +614,24 @@ void drm_dev_unregister(struct drm_device *dev); void drm_dev_ref(struct drm_device *dev); void drm_dev_unref(struct drm_device *dev); void drm_put_dev(struct drm_device *dev); -void drm_unplug_dev(struct drm_device *dev); +void drm_dev_unplug(struct drm_device *dev); + +/** + * drm_dev_is_unplugged - is a DRM device unplugged + * @dev: DRM device + * + * This function can be called to check whether a hotpluggable is unplugged. + * Unplugging itself is singalled through drm_dev_unplug(). If a device is + * unplugged, these two functions guarantee that any store before calling + * drm_dev_unplug() is visible to callers of this function after it completes + */ +static inline int drm_dev_is_unplugged(struct drm_device *dev) +{ + int ret = atomic_read(&dev->unplugged); + smp_rmb(); + return ret; +} + int drm_dev_set_unique(struct drm_device *dev, const char *name); diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 7b9f48b62e07cda87f74b5d6df617c2dc54734ef..1e1908a6b1d66eddede740c60ccc5084e2f49deb 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -213,6 +213,14 @@ struct detailed_timing { #define DRM_EDID_HDMI_DC_30 (1 << 4) #define DRM_EDID_HDMI_DC_Y444 (1 << 3) +/* YCBCR 420 deep color modes */ +#define DRM_EDID_YCBCR420_DC_48 (1 << 6) +#define DRM_EDID_YCBCR420_DC_36 (1 << 5) +#define DRM_EDID_YCBCR420_DC_30 (1 << 4) +#define DRM_EDID_YCBCR420_DC_MASK (DRM_EDID_YCBCR420_DC_48 | \ + DRM_EDID_YCBCR420_DC_36 | \ + DRM_EDID_YCBCR420_DC_30) + /* ELD Header Block */ #define DRM_ELD_HEADER_BLOCK_SIZE 4 @@ -343,7 +351,8 @@ drm_load_edid_firmware(struct drm_connector *connector) int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, - const struct drm_display_mode *mode); + const struct drm_display_mode *mode, + bool is_hdmi2_sink); int drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, const struct drm_display_mode *mode); diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h index 199a63f48659a8956bfe6350b1778e35c589a95b..a323781afc3f3a73a6c0bdbdd7ac1dfc5b10e9a0 100644 --- a/include/drm/drm_fb_cma_helper.h +++ b/include/drm/drm_fb_cma_helper.h @@ -24,9 +24,9 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma); void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); -void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state); +void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, bool state); void drm_fbdev_cma_set_suspend_unlocked(struct drm_fbdev_cma *fbdev_cma, - int state); + bool state); void drm_fb_cma_destroy(struct drm_framebuffer *fb); int drm_fb_cma_create_handle(struct drm_framebuffer *fb, diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 119e5e4609c7cef6fe6b099bc640495d7c314050..33fe959277428baa28922c8d35c44a854474117c 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -84,38 +84,6 @@ struct drm_fb_helper_surface_size { * Driver callbacks used by the fbdev emulation helper library. */ struct drm_fb_helper_funcs { - /** - * @gamma_set: - * - * Set the given gamma LUT register on the given CRTC. - * - * This callback is optional. - * - * FIXME: - * - * This callback is functionally redundant with the core gamma table - * support and simply exists because the fbdev hasn't yet been - * refactored to use the core gamma table interfaces. - */ - void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno); - /** - * @gamma_get: - * - * Read the given gamma LUT register on the given CRTC, used to save the - * current LUT when force-restoring the fbdev for e.g. kdbg. - * - * This callback is optional. - * - * FIXME: - * - * This callback is functionally redundant with the core gamma table - * support and simply exists because the fbdev hasn't yet been - * refactored to use the core gamma table interfaces. - */ - void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno); - /** * @fb_probe: * @@ -169,7 +137,6 @@ struct drm_fb_helper_connector { * @crtc_info: per-CRTC helper state (mode, x/y offset, etc) * @connector_count: number of connected connectors * @connector_info_alloc_count: size of connector_info - * @connector_info: array of per-connector information * @funcs: driver callbacks for fb helper * @fbdev: emulated fbdev device info struct * @pseudo_palette: fake palette of 16 colors @@ -191,6 +158,12 @@ struct drm_fb_helper { struct drm_fb_helper_crtc *crtc_info; int connector_count; int connector_info_alloc_count; + /** + * @connector_info: + * + * Array of per-connector information. Do not iterate directly, but use + * drm_fb_helper_for_each_connector. + */ struct drm_fb_helper_connector **connector_info; const struct drm_fb_helper_funcs *funcs; struct fb_info *fbdev; @@ -200,6 +173,18 @@ struct drm_fb_helper { struct work_struct dirty_work; struct work_struct resume_work; + /** + * @lock: + * + * Top-level FBDEV helper lock. This protects all internal data + * structures and lists, such as @connector_info and @crtc_info. + * + * FIXME: fbdev emulation locking is a mess and long term we want to + * protect all helper internal state with this lock as well as reduce + * core KMS locking as much as possible. + */ + struct mutex lock; + /** * @kernel_fb_list: * @@ -215,6 +200,29 @@ struct drm_fb_helper { * needs to be reprobe when fbdev is in control again. */ bool delayed_hotplug; + + /** + * @deferred_setup: + * + * If no outputs are connected (disconnected or unknown) the FB helper + * code will defer setup until at least one of the outputs shows up. + * This field keeps track of the status so that setup can be retried + * at every hotplug event until it succeeds eventually. + * + * Protected by @lock. + */ + bool deferred_setup; + + /** + * @preferred_bpp: + * + * Temporary storage for the driver's preferred BPP setting passed to + * FB helper initialization. This needs to be tracked so that deferred + * FB helper setup can pass this on. + * + * See also: @deferred_setup + */ + int preferred_bpp; }; /** diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index 5244f059d23a06f6ad58fb6388451acf76cb8081..b6996ddb19d6e8831d74aac16d6be98d6c72bdff 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h @@ -190,6 +190,13 @@ struct drm_framebuffer { * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock. */ struct list_head filp_head; + /** + * @obj: GEM objects backing the framebuffer, one per plane (optional). + * + * This is used by the GEM framebuffer helpers, see e.g. + * drm_gem_fb_create(). + */ + struct drm_gem_object *obj[4]; }; #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 663d803580578b9ee198ff9f4402dfa8c86cd05c..9c55c2acaa2b366dc5b93f068f66575aa3177a64 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -130,21 +130,6 @@ struct drm_gem_object { */ uint32_t write_domain; - /** - * @pending_read_domains: - * - * While validating an exec operation, the - * new read/write domain values are computed here. - * They will be transferred to the above values - * at the point that any cache flushing occurs - */ - uint32_t pending_read_domains; - - /** - * @pending_write_domain: Write domain similar to @pending_read_domains. - */ - uint32_t pending_write_domain; - /** * @dma_buf: * @@ -317,6 +302,8 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, bool dirty, bool accessed); struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle); +int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, + u32 handle, u64 *offset); int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, uint32_t handle); diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index b42529e0fae0c68d96fb8d947f53bc383236b351..58a739bf15f1fd5d5cfb112dfa9b425fc07f5856 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -73,11 +73,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm, struct drm_mode_create_dumb *args); -/* map memory region for DRM framebuffer to user space */ -int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *drm, u32 handle, - u64 *offset); - /* set vm_flags and we can change the VM attribute to other one at here */ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); diff --git a/include/drm/drm_gem_framebuffer_helper.h b/include/drm/drm_gem_framebuffer_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..db9cfa07235edaaba88f610cfd93bfd03b33b7ae --- /dev/null +++ b/include/drm/drm_gem_framebuffer_helper.h @@ -0,0 +1,37 @@ +#ifndef __DRM_GEM_FB_HELPER_H__ +#define __DRM_GEM_FB_HELPER_H__ + +struct drm_device; +struct drm_file; +struct drm_fb_helper_surface_size; +struct drm_framebuffer; +struct drm_framebuffer_funcs; +struct drm_gem_object; +struct drm_mode_fb_cmd2; +struct drm_plane; +struct drm_plane_state; + +struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb, + unsigned int plane); +void drm_gem_fb_destroy(struct drm_framebuffer *fb); +int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file, + unsigned int *handle); + +struct drm_framebuffer * +drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd, + const struct drm_framebuffer_funcs *funcs); +struct drm_framebuffer * +drm_gem_fb_create(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd); + +int drm_gem_fb_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *state); + +struct drm_framebuffer * +drm_gem_fbdev_fb_create(struct drm_device *dev, + struct drm_fb_helper_surface_size *sizes, + unsigned int pitch_align, struct drm_gem_object *obj, + const struct drm_framebuffer_funcs *funcs); + +#endif diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 49b292e98fecf1da98e38c005eaf3137478626ef..8d10fc97801cee91bdb35682eee1e7759e4177b5 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -172,7 +172,7 @@ struct drm_mm { * according to the (increasing) start address of the memory node. */ struct drm_mm_node head_node; /* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */ - struct rb_root interval_tree; + struct rb_root_cached interval_tree; struct rb_root holes_size; struct rb_root holes_addr; diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 42981711189bda6d93d282ede8d5607f88b1d434..1b37368416c8561f63aea14205f537056be98525 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -757,6 +757,12 @@ struct drm_mode_config { */ bool allow_fb_modifiers; + /** + * @modifiers: Plane property to list support modifier/format + * combination. + */ + struct drm_property *modifiers_property; + /* cursor size */ uint32_t cursor_width, cursor_height; diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 94ac771fe460b1aea79918d55ecdfac3f318a23a..9f3421c8efcd870a410eb3a2ba1d97d66e8035ad 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -80,6 +80,7 @@ struct videomode; * @MODE_ONE_SIZE: only one resolution is supported * @MODE_NO_REDUCED: monitor doesn't accept reduced blanking * @MODE_NO_STEREO: stereo modes not supported + * @MODE_NO_420: ycbcr 420 modes not supported * @MODE_STALE: mode has become stale * @MODE_BAD: unspecified reason * @MODE_ERROR: error condition @@ -124,6 +125,7 @@ enum drm_mode_status { MODE_ONE_SIZE, MODE_NO_REDUCED, MODE_NO_STEREO, + MODE_NO_420, MODE_STALE = -3, MODE_BAD = -2, MODE_ERROR = -1 @@ -450,6 +452,12 @@ int drm_mode_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); void drm_mode_debug_printmodeline(const struct drm_display_mode *mode); +bool drm_mode_is_420_only(const struct drm_display_info *display, + const struct drm_display_mode *mode); +bool drm_mode_is_420_also(const struct drm_display_info *display, + const struct drm_display_mode *mode); +bool drm_mode_is_420(const struct drm_display_info *display, + const struct drm_display_mode *mode); struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, @@ -496,6 +504,9 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode); enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode, int maxX, int maxY); +enum drm_mode_status +drm_mode_validate_ycbcr420(const struct drm_display_mode *mode, + struct drm_connector *connector); void drm_mode_prune_invalid(struct drm_device *dev, struct list_head *mode_list, bool verbose); void drm_mode_sort(struct list_head *mode_list); diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 85984b2082182b510479c806f3efae6301c1cd7a..c55cf3ff68477b8b6e0009a8c54e5b33238df9d5 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -71,7 +71,7 @@ struct drm_crtc_helper_funcs { * This callback is used by the legacy CRTC helpers. Atomic helpers * also support using this hook for enabling and disabling a CRTC to * facilitate transitions to atomic, but it is deprecated. Instead - * @enable and @disable should be used. + * @atomic_enable and @atomic_disable should be used. */ void (*dpms)(struct drm_crtc *crtc, int mode); @@ -85,8 +85,8 @@ struct drm_crtc_helper_funcs { * * This callback is used by the legacy CRTC helpers. Atomic helpers * also support using this hook for disabling a CRTC to facilitate - * transitions to atomic, but it is deprecated. Instead @disable should - * be used. + * transitions to atomic, but it is deprecated. Instead @atomic_disable + * should be used. */ void (*prepare)(struct drm_crtc *crtc); @@ -100,8 +100,8 @@ struct drm_crtc_helper_funcs { * * This callback is used by the legacy CRTC helpers. Atomic helpers * also support using this hook for enabling a CRTC to facilitate - * transitions to atomic, but it is deprecated. Instead @enable should - * be used. + * transitions to atomic, but it is deprecated. Instead @atomic_enable + * should be used. */ void (*commit)(struct drm_crtc *crtc); @@ -222,7 +222,7 @@ struct drm_crtc_helper_funcs { * pipeline is suspended using either DPMS or the new "ACTIVE" property. * Which means register values set in this callback might get reset when * the CRTC is suspended, but not restored. Such drivers should instead - * move all their CRTC setup into the @enable callback. + * move all their CRTC setup into the @atomic_enable callback. * * This callback is optional. */ @@ -266,22 +266,6 @@ struct drm_crtc_helper_funcs { struct drm_framebuffer *fb, int x, int y, enum mode_set_atomic); - /** - * @load_lut: - * - * Load a LUT prepared with the &drm_fb_helper_funcs.gamma_set vfunc. - * - * This callback is optional and is only used by the fbdev emulation - * helpers. - * - * FIXME: - * - * This callback is functionally redundant with the core gamma table - * support and simply exists because the fbdev hasn't yet been - * refactored to use the core gamma table interfaces. - */ - void (*load_lut)(struct drm_crtc *crtc); - /** * @disable: * @@ -297,7 +281,7 @@ struct drm_crtc_helper_funcs { * Atomic drivers don't need to implement it if there's no need to * disable anything at the CRTC level. To ensure that runtime PM * handling (using either DPMS or the new "ACTIVE" property) works - * @disable must be the inverse of @enable for atomic drivers. + * @disable must be the inverse of @atomic_enable for atomic drivers. * Atomic drivers should consider to use @atomic_disable instead of * this one. * @@ -315,24 +299,6 @@ struct drm_crtc_helper_funcs { */ void (*disable)(struct drm_crtc *crtc); - /** - * @enable: - * - * This callback should be used to enable the CRTC. With the atomic - * drivers it is called before all encoders connected to this CRTC are - * enabled through the encoder's own &drm_encoder_helper_funcs.enable - * hook. If that sequence is too simple drivers can just add their own - * hooks and call it from this CRTC callback here by looping over all - * encoders connected to it using for_each_encoder_on_crtc(). - * - * This hook is used only by atomic helpers, for symmetry with @disable. - * Atomic drivers don't need to implement it if there's no need to - * enable anything at the CRTC level. To ensure that runtime PM handling - * (using either DPMS or the new "ACTIVE" property) works - * @enable must be the inverse of @disable for atomic drivers. - */ - void (*enable)(struct drm_crtc *crtc); - /** * @atomic_check: * @@ -432,6 +398,30 @@ struct drm_crtc_helper_funcs { void (*atomic_flush)(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + /** + * @atomic_enable: + * + * This callback should be used to enable the CRTC. With the atomic + * drivers it is called before all encoders connected to this CRTC are + * enabled through the encoder's own &drm_encoder_helper_funcs.enable + * hook. If that sequence is too simple drivers can just add their own + * hooks and call it from this CRTC callback here by looping over all + * encoders connected to it using for_each_encoder_on_crtc(). + * + * This hook is used only by atomic helpers, for symmetry with + * @atomic_disable. Atomic drivers don't need to implement it if there's + * no need to enable anything at the CRTC level. To ensure that runtime + * PM handling (using either DPMS or the new "ACTIVE" property) works + * @atomic_enable must be the inverse of @atomic_disable for atomic + * drivers. + * + * Drivers can use the @old_crtc_state input parameter if the operations + * needed to enable the CRTC don't depend solely on the new state but + * also on the transition between the old state and the new state. + */ + void (*atomic_enable)(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state); + /** * @atomic_disable: * @@ -1129,6 +1119,56 @@ struct drm_plane_helper_funcs { */ void (*atomic_disable)(struct drm_plane *plane, struct drm_plane_state *old_state); + + /** + * @atomic_async_check: + * + * Drivers should set this function pointer to check if the plane state + * can be updated in a async fashion. Here async means "not vblank + * synchronized". + * + * This hook is called by drm_atomic_async_check() to establish if a + * given update can be committed asynchronously, that is, if it can + * jump ahead of the state currently queued for update. + * + * RETURNS: + * + * Return 0 on success and any error returned indicates that the update + * can not be applied in asynchronous manner. + */ + int (*atomic_async_check)(struct drm_plane *plane, + struct drm_plane_state *state); + + /** + * @atomic_async_update: + * + * Drivers should set this function pointer to perform asynchronous + * updates of planes, that is, jump ahead of the currently queued + * state and update the plane. Here async means "not vblank + * synchronized". + * + * This hook is called by drm_atomic_helper_async_commit(). + * + * An async update will happen on legacy cursor updates. An async + * update won't happen if there is an outstanding commit modifying + * the same plane. + * + * Note that unlike &drm_plane_helper_funcs.atomic_update this hook + * takes the new &drm_plane_state as parameter. When doing async_update + * drivers shouldn't replace the &drm_plane_state but update the + * current one with the new plane configurations in the new + * plane_state. + * + * FIXME: + * - It only works for single plane updates + * - Async Pageflips are not supported yet + * - Some hw might still scan out the old buffer until the next + * vblank, however we let go of the fb references as soon as + * we run this hook. For now drivers must implement their own workers + * for deferring if needed, until a common solution is created. + */ + void (*atomic_async_update)(struct drm_plane *plane, + struct drm_plane_state *new_state); }; /** @@ -1169,7 +1209,8 @@ struct drm_mode_config_helper_funcs { * After the atomic update is committed to the hardware this hook needs * to call drm_atomic_helper_commit_hw_done(). Then wait for the upate * to be executed by the hardware, for example using - * drm_atomic_helper_wait_for_vblanks(), and then clean up the old + * drm_atomic_helper_wait_for_vblanks() or + * drm_atomic_helper_wait_for_flip_done(), and then clean up the old * framebuffers using drm_atomic_helper_cleanup_planes(). * * When disabling a CRTC this hook _must_ stall for the commit to diff --git a/include/drm/drm_pci.h b/include/drm/drm_pci.h index 4579fac1080c665b49b9fb3572768072f17228cd..674599025d7d3b15fb08e5a7337475f8f9d588a8 100644 --- a/include/drm/drm_pci.h +++ b/include/drm/drm_pci.h @@ -43,13 +43,12 @@ struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size, size_t align); void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah); -int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); -void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); +int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); +void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); #ifdef CONFIG_PCI int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); -int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master); #else static inline int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, @@ -57,12 +56,6 @@ static inline int drm_get_pci_dev(struct pci_dev *pdev, { return -ENOSYS; } - -static inline int drm_pci_set_busid(struct drm_device *dev, - struct drm_master *master) -{ - return -ENOSYS; -} #endif #define DRM_PCIE_SPEED_25 1 diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 9ab3e70448127902aad5414f7fe1e109ed298e21..73f90f9d057f984a34ff541c3f110e7d61403726 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -233,11 +233,9 @@ struct drm_plane_funcs { * This is the legacy entry point to update a property attached to the * plane. * - * Drivers implementing atomic modeset should use - * drm_atomic_helper_plane_set_property() to implement this hook. - * * This callback is optional if the driver does not support any legacy - * driver-private properties. + * driver-private properties. For atomic drivers it is not used because + * property handling is done entirely in the DRM core. * * RETURNS: * @@ -392,6 +390,22 @@ struct drm_plane_funcs { */ void (*atomic_print_state)(struct drm_printer *p, const struct drm_plane_state *state); + + /** + * @format_mod_supported: + * + * This optional hook is used for the DRM to determine if the given + * format/modifier combination is valid for the plane. This allows the + * DRM to generate the correct format bitmask (which formats apply to + * which modifier). + * + * Returns: + * + * True if the given modifier is valid for that format on the plane. + * False otherwise. + */ + bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format, + uint64_t modifier); }; /** @@ -487,6 +501,9 @@ struct drm_plane { unsigned int format_count; bool format_default; + uint64_t *modifiers; + unsigned int modifier_count; + struct drm_crtc *crtc; struct drm_framebuffer *fb; @@ -527,13 +544,14 @@ struct drm_plane { #define obj_to_plane(x) container_of(x, struct drm_plane, base) -__printf(8, 9) +__printf(9, 10) int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, const struct drm_plane_funcs *funcs, const uint32_t *formats, unsigned int format_count, + const uint64_t *format_modifiers, enum drm_plane_type type, const char *name, ...); int drm_plane_init(struct drm_device *dev, diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h index 619868dc08d8c13cb235b4063eb7013948aefe9c..37355c623e6c32888b2f7b2defabc8f023e7bcc4 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -273,6 +273,8 @@ int drm_property_replace_global_blob(struct drm_device *dev, const void *data, struct drm_mode_object *obj_holds_id, struct drm_property *prop_holds_id); +bool drm_property_replace_blob(struct drm_property_blob **blob, + struct drm_property_blob *new_blob); struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob); void drm_property_blob_put(struct drm_property_blob *blob); diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h index c25122bb490a345528f0228b0ef11ff542c5bc50..f92eb2094d6b1915630e299fbde67858ff34cd5a 100644 --- a/include/drm/drm_scdc_helper.h +++ b/include/drm/drm_scdc_helper.h @@ -131,31 +131,6 @@ static inline int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset, bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter); -/** - * drm_scdc_set_scrambling - enable scrambling - * @adapter: I2C adapter for DDC channel - * @enable: bool to indicate if scrambling is to be enabled/disabled - * - * Writes the TMDS config register over SCDC channel, and: - * enables scrambling when enable = 1 - * disables scrambling when enable = 0 - * - * Returns: - * True if scrambling is set/reset successfully, false otherwise. - */ bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable); - -/** - * drm_scdc_set_high_tmds_clock_ratio - set TMDS clock ratio - * @adapter: I2C adapter for DDC channel - * @set: ret or reset the high clock ratio - * - * Writes to the TMDS config register over SCDC channel, and: - * sets TMDS clock ratio to 1/40 when set = 1 - * sets TMDS clock ratio to 1/10 when set = 0 - * - * Returns: - * True if write is successful, false otherwise. - */ bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set); #endif diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index 2d36538e4a17ebdabe7fa9e20de25fb8cf952dbe..6d9adbb46293310cb09780ec509f048b94642a41 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -122,6 +122,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev, struct drm_simple_display_pipe *pipe, const struct drm_simple_display_pipe_funcs *funcs, const uint32_t *formats, unsigned int format_count, + const uint64_t *format_modifiers, struct drm_connector *connector); #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 89976da542b1b723b073bb1dc6facc818ca54286..c00fee5398224735311fa7581bfe62481cf4ffea 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -28,6 +28,8 @@ #include "linux/dma-fence.h" +struct drm_syncobj_cb; + /** * struct drm_syncobj - sync object. * @@ -43,8 +45,21 @@ struct drm_syncobj { /** * @fence: * NULL or a pointer to the fence bound to this object. + * + * This field should not be used directly. Use drm_syncobj_fence_get + * and drm_syncobj_replace_fence instead. */ struct dma_fence *fence; + /** + * @cb_list: + * List of callbacks to call when the fence gets replaced + */ + struct list_head cb_list; + /** + * @lock: + * locks cb_list and write-locks fence. + */ + spinlock_t lock; /** * @file: * a file backing for this syncobj. @@ -52,6 +67,25 @@ struct drm_syncobj { struct file *file; }; +typedef void (*drm_syncobj_func_t)(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb); + +/** + * struct drm_syncobj_cb - callback for drm_syncobj_add_callback + * @node: used by drm_syncob_add_callback to append this struct to + * syncobj::cb_list + * @func: drm_syncobj_func_t to call + * + * This struct will be initialized by drm_syncobj_add_callback, additional + * data can be passed along by embedding drm_syncobj_cb in another struct. + * The callback will get called the next time drm_syncobj_replace_fence is + * called. + */ +struct drm_syncobj_cb { + struct list_head node; + drm_syncobj_func_t func; +}; + void drm_syncobj_free(struct kref *kref); /** @@ -77,13 +111,30 @@ drm_syncobj_put(struct drm_syncobj *obj) kref_put(&obj->refcount, drm_syncobj_free); } +static inline struct dma_fence * +drm_syncobj_fence_get(struct drm_syncobj *syncobj) +{ + struct dma_fence *fence; + + rcu_read_lock(); + fence = dma_fence_get_rcu_safe(&syncobj->fence); + rcu_read_unlock(); + + return fence; +} + struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, u32 handle); +void drm_syncobj_add_callback(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb, + drm_syncobj_func_t func); +void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, + struct drm_syncobj_cb *cb); void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence); -int drm_syncobj_fence_get(struct drm_file *file_private, - u32 handle, - struct dma_fence **fence); +int drm_syncobj_find_fence(struct drm_file *file_private, + u32 handle, + struct dma_fence **fence); void drm_syncobj_free(struct kref *kref); #endif diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index 4cde47332dfad6163c6a113b89823655061b09f3..7fba9efe495165097a08930b5d1e769f1626902b 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -168,8 +168,7 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); void drm_crtc_vblank_off(struct drm_crtc *crtc); void drm_crtc_vblank_reset(struct drm_crtc *crtc); void drm_crtc_vblank_on(struct drm_crtc *crtc); -void drm_vblank_cleanup(struct drm_device *dev); -u32 drm_accurate_vblank_count(struct drm_crtc *crtc); +u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h index d137b16ee8734ee2a0ec648509e1e83890dbcf43..83346ddb9dba5bcd0101b0e7a86fadab6a699f62 100644 --- a/include/drm/tinydrm/mipi-dbi.h +++ b/include/drm/tinydrm/mipi-dbi.h @@ -62,11 +62,7 @@ mipi_dbi_from_tinydrm(struct tinydrm_device *tdev) } int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi, - struct gpio_desc *dc, - const struct drm_simple_display_pipe_funcs *pipe_funcs, - struct drm_driver *driver, - const struct drm_display_mode *mode, - unsigned int rotation); + struct gpio_desc *dc); int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, const struct drm_simple_display_pipe_funcs *pipe_funcs, struct drm_driver *driver, diff --git a/include/drm/tinydrm/tinydrm-helpers.h b/include/drm/tinydrm/tinydrm-helpers.h index 9b9b6cfe3ba526b1c9e0d49adb28813a201a9764..d554ded60ee989a087fe16b6cef5b636d18e9174 100644 --- a/include/drm/tinydrm/tinydrm-helpers.h +++ b/include/drm/tinydrm/tinydrm-helpers.h @@ -43,6 +43,8 @@ void tinydrm_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_clip_rect *clip, bool swap); +void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_clip_rect *clip); struct backlight_device *tinydrm_of_find_backlight(struct device *dev); int tinydrm_enable_backlight(struct backlight_device *backlight); diff --git a/include/drm/tinydrm/tinydrm.h b/include/drm/tinydrm/tinydrm.h index 00b800df4d1b2b6c6cbe69a3646c8fc577b524db..4774fe3d427393ef7e1809b1512d7b8c3ada6870 100644 --- a/include/drm/tinydrm/tinydrm.h +++ b/include/drm/tinydrm/tinydrm.h @@ -56,9 +56,7 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe) .gem_prime_vmap = drm_gem_cma_prime_vmap, \ .gem_prime_vunmap = drm_gem_cma_prime_vunmap, \ .gem_prime_mmap = drm_gem_cma_prime_mmap, \ - .dumb_create = drm_gem_cma_dumb_create, \ - .dumb_map_offset = drm_gem_cma_dumb_map_offset, \ - .dumb_destroy = drm_gem_dumb_destroy + .dumb_create = drm_gem_cma_dumb_create /** * TINYDRM_MODE - tinydrm display mode diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 990d529f823c6e751c0fdb60130fe1b924b83416..5f821a9b3a1fa8110186c964a706805714a33966 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -229,13 +229,14 @@ struct ttm_mem_type_manager_func { * struct ttm_mem_type_manager member debug * * @man: Pointer to a memory type manager. - * @prefix: Prefix to be used in printout to identify the caller. + * @printer: Prefix to be used in printout to identify the caller. * * This function is called to print out the state of the memory * type manager to aid debugging of out-of-memory conditions. * It may not be called from within atomic context. */ - void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); + void (*debug)(struct ttm_mem_type_manager *man, + struct drm_printer *printer); }; /** @@ -472,6 +473,23 @@ struct ttm_bo_driver { */ unsigned long (*io_mem_pfn)(struct ttm_buffer_object *bo, unsigned long page_offset); + + /** + * Read/write memory buffers for ptrace access + * + * @bo: the BO to access + * @offset: the offset from the start of the BO + * @buf: pointer to source/destination buffer + * @len: number of bytes to copy + * @write: whether to read (0) from or write (non-0) to BO + * + * If successful, this function should return the number of + * bytes copied, -EIO otherwise. If the number of bytes + * returned is < len, the function may be called again with + * the remainder of the buffer to copy. + */ + int (*access_memory)(struct ttm_buffer_object *bo, unsigned long offset, + void *buf, int len, int write); }; /** diff --git a/include/dt-bindings/clock/gxbb-aoclkc.h b/include/dt-bindings/clock/gxbb-aoclkc.h index 31751482d13cb498fb4989a41cb336e8c7e92e13..9d15e2221fdb7fd5f732eaa5a800f7b66112f8a5 100644 --- a/include/dt-bindings/clock/gxbb-aoclkc.h +++ b/include/dt-bindings/clock/gxbb-aoclkc.h @@ -62,5 +62,6 @@ #define CLKID_AO_UART1 3 #define CLKID_AO_UART2 4 #define CLKID_AO_IR_BLASTER 5 +#define CLKID_AO_CEC_32K 6 #endif diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h index e3e9f7919c318baed4063fc7199def1a6d684018..c04a76d8facff42319d708830c985bf342427627 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h @@ -5,37 +5,96 @@ #ifndef __GXBB_CLKC_H #define __GXBB_CLKC_H +#define CLKID_SYS_PLL 0 #define CLKID_HDMI_PLL 2 +#define CLKID_FIXED_PLL 3 #define CLKID_FCLK_DIV2 4 #define CLKID_FCLK_DIV3 5 #define CLKID_FCLK_DIV4 6 +#define CLKID_FCLK_DIV5 7 +#define CLKID_FCLK_DIV7 8 #define CLKID_GP0_PLL 9 #define CLKID_CLK81 12 +#define CLKID_MPLL0 13 +#define CLKID_MPLL1 14 #define CLKID_MPLL2 15 +#define CLKID_DDR 16 +#define CLKID_DOS 17 +#define CLKID_ISA 18 +#define CLKID_PL301 19 +#define CLKID_PERIPHS 20 #define CLKID_SPICC 21 #define CLKID_I2C 22 #define CLKID_SAR_ADC 23 +#define CLKID_SMART_CARD 24 #define CLKID_RNG0 25 #define CLKID_UART0 26 +#define CLKID_SDHC 27 +#define CLKID_STREAM 28 +#define CLKID_ASYNC_FIFO 29 +#define CLKID_SDIO 30 +#define CLKID_ABUF 31 +#define CLKID_HIU_IFACE 32 +#define CLKID_ASSIST_MISC 33 #define CLKID_SPI 34 #define CLKID_ETH 36 +#define CLKID_I2S_SPDIF 35 +#define CLKID_DEMUX 37 #define CLKID_AIU_GLUE 38 #define CLKID_IEC958 39 #define CLKID_I2S_OUT 40 +#define CLKID_AMCLK 41 +#define CLKID_AIFIFO2 42 +#define CLKID_MIXER 43 #define CLKID_MIXER_IFACE 44 +#define CLKID_ADC 45 +#define CLKID_BLKMV 46 #define CLKID_AIU 47 #define CLKID_UART1 48 +#define CLKID_G2D 49 #define CLKID_USB0 50 #define CLKID_USB1 51 +#define CLKID_RESET 52 +#define CLKID_NAND 53 +#define CLKID_DOS_PARSER 54 #define CLKID_USB 55 +#define CLKID_VDIN1 56 +#define CLKID_AHB_ARB0 57 +#define CLKID_EFUSE 58 +#define CLKID_BOOT_ROM 59 +#define CLKID_AHB_DATA_BUS 60 +#define CLKID_AHB_CTRL_BUS 61 +#define CLKID_HDMI_INTR_SYNC 62 #define CLKID_HDMI_PCLK 63 #define CLKID_USB1_DDR_BRIDGE 64 #define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_MMC_PCLK 66 +#define CLKID_DVIN 67 #define CLKID_UART2 68 #define CLKID_SANA 69 +#define CLKID_VPU_INTR 70 +#define CLKID_SEC_AHB_AHB3_BRIDGE 71 +#define CLKID_CLK81_A53 72 +#define CLKID_VCLK2_VENCI0 73 +#define CLKID_VCLK2_VENCI1 74 +#define CLKID_VCLK2_VENCP0 75 +#define CLKID_VCLK2_VENCP1 76 #define CLKID_GCLK_VENCI_INT0 77 +#define CLKID_GCLK_VENCI_INT 78 +#define CLKID_DAC_CLK 79 #define CLKID_AOCLK_GATE 80 #define CLKID_IEC958_GATE 81 +#define CLKID_ENC480P 82 +#define CLKID_RNG1 83 +#define CLKID_GCLK_VENCI_INT1 84 +#define CLKID_VCLK2_VENCLMCC 85 +#define CLKID_VCLK2_VENCL 86 +#define CLKID_VCLK_OTHER 87 +#define CLKID_EDP 88 +#define CLKID_AO_MEDIA_CPU 89 +#define CLKID_AO_AHB_SRAM 90 +#define CLKID_AO_AHB_BUS 91 +#define CLKID_AO_IFACE 92 #define CLKID_AO_I2C 93 #define CLKID_SD_EMMC_A 94 #define CLKID_SD_EMMC_B 95 @@ -50,5 +109,9 @@ #define CLKID_CTS_AMCLK 107 #define CLKID_CTS_MCLK_I958 110 #define CLKID_CTS_I958 113 +#define CLKID_32K_CLK 114 +#define CLKID_SD_EMMC_A_CLK0 119 +#define CLKID_SD_EMMC_B_CLK0 122 +#define CLKID_SD_EMMC_C_CLK0 125 #endif /* __GXBB_CLKC_H */ diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h index e29227fb52a18c66b6aba5773f38fc0c872ea97d..a9c0306330b6a78e910fb5b1fb9fd3dfd107b01e 100644 --- a/include/dt-bindings/clock/meson8b-clkc.h +++ b/include/dt-bindings/clock/meson8b-clkc.h @@ -21,15 +21,85 @@ #define CLKID_ZERO 13 #define CLKID_MPEG_SEL 14 #define CLKID_MPEG_DIV 15 +#define CLKID_DDR 16 +#define CLKID_DOS 17 +#define CLKID_ISA 18 +#define CLKID_PL301 19 +#define CLKID_PERIPHS 20 +#define CLKID_SPICC 21 +#define CLKID_I2C 22 #define CLKID_SAR_ADC 23 +#define CLKID_SMART_CARD 24 #define CLKID_RNG0 25 +#define CLKID_UART0 26 +#define CLKID_SDHC 27 +#define CLKID_STREAM 28 +#define CLKID_ASYNC_FIFO 29 #define CLKID_SDIO 30 +#define CLKID_ABUF 31 +#define CLKID_HIU_IFACE 32 +#define CLKID_ASSIST_MISC 33 +#define CLKID_SPI 34 +#define CLKID_I2S_SPDIF 35 #define CLKID_ETH 36 +#define CLKID_DEMUX 37 +#define CLKID_AIU_GLUE 38 +#define CLKID_IEC958 39 +#define CLKID_I2S_OUT 40 +#define CLKID_AMCLK 41 +#define CLKID_AIFIFO2 42 +#define CLKID_MIXER 43 +#define CLKID_MIXER_IFACE 44 +#define CLKID_ADC 45 +#define CLKID_BLKMV 46 +#define CLKID_AIU 47 +#define CLKID_UART1 48 +#define CLKID_G2D 49 #define CLKID_USB0 50 #define CLKID_USB1 51 +#define CLKID_RESET 52 +#define CLKID_NAND 53 +#define CLKID_DOS_PARSER 54 #define CLKID_USB 55 +#define CLKID_VDIN1 56 +#define CLKID_AHB_ARB0 57 +#define CLKID_EFUSE 58 +#define CLKID_BOOT_ROM 59 +#define CLKID_AHB_DATA_BUS 60 +#define CLKID_AHB_CTRL_BUS 61 +#define CLKID_HDMI_INTR_SYNC 62 +#define CLKID_HDMI_PCLK 63 #define CLKID_USB1_DDR_BRIDGE 64 #define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_MMC_PCLK 66 +#define CLKID_DVIN 67 +#define CLKID_UART2 68 #define CLKID_SANA 69 +#define CLKID_VPU_INTR 70 +#define CLKID_SEC_AHB_AHB3_BRIDGE 71 +#define CLKID_CLK81_A9 72 +#define CLKID_VCLK2_VENCI0 73 +#define CLKID_VCLK2_VENCI1 74 +#define CLKID_VCLK2_VENCP0 75 +#define CLKID_VCLK2_VENCP1 76 +#define CLKID_GCLK_VENCI_INT 77 +#define CLKID_GCLK_VENCP_INT 78 +#define CLKID_DAC_CLK 79 +#define CLKID_AOCLK_GATE 80 +#define CLKID_IEC958_GATE 81 +#define CLKID_ENC480P 82 +#define CLKID_RNG1 83 +#define CLKID_GCLK_VENCL_INT 84 +#define CLKID_VCLK2_VENCLMCC 85 +#define CLKID_VCLK2_VENCL 86 +#define CLKID_VCLK2_OTHER 87 +#define CLKID_EDP 88 +#define CLKID_AO_MEDIA_CPU 89 +#define CLKID_AO_AHB_SRAM 90 +#define CLKID_AO_AHB_BUS 91 +#define CLKID_AO_IFACE 92 +#define CLKID_MPLL0 93 +#define CLKID_MPLL1 94 +#define CLKID_MPLL2 95 #endif /* __MESON8B_CLKC_H */ diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index 1f5c42254798e34ac6d6ea56a049f3e0a13dfc49..75b07cf5eed0f9a2941f0367af601b77c0bd1599 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h @@ -233,6 +233,8 @@ #define GCC_PCIE_CLKREF_CLK 216 #define GCC_RX2_USB2_CLKREF_CLK 217 #define GCC_RX1_USB2_CLKREF_CLK 218 +#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 219 +#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 220 #define GCC_SYSTEM_NOC_BCR 0 #define GCC_CONFIG_NOC_BCR 1 diff --git a/include/dt-bindings/clock/r8a77995-cpg-mssr.h b/include/dt-bindings/clock/r8a77995-cpg-mssr.h new file mode 100644 index 0000000000000000000000000000000000000000..4e8ae3dee5901b01374e6fd609e7e988d4107676 --- /dev/null +++ b/include/dt-bindings/clock/r8a77995-cpg-mssr.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ + +#include + +/* r8a77995 CPG Core Clocks */ +#define R8A77995_CLK_Z2 0 +#define R8A77995_CLK_ZG 1 +#define R8A77995_CLK_ZTR 2 +#define R8A77995_CLK_ZT 3 +#define R8A77995_CLK_ZX 4 +#define R8A77995_CLK_S0D1 5 +#define R8A77995_CLK_S1D1 6 +#define R8A77995_CLK_S1D2 7 +#define R8A77995_CLK_S1D4 8 +#define R8A77995_CLK_S2D1 9 +#define R8A77995_CLK_S2D2 10 +#define R8A77995_CLK_S2D4 11 +#define R8A77995_CLK_S3D1 12 +#define R8A77995_CLK_S3D2 13 +#define R8A77995_CLK_S3D4 14 +#define R8A77995_CLK_S1D4C 15 +#define R8A77995_CLK_S3D1C 16 +#define R8A77995_CLK_S3D2C 17 +#define R8A77995_CLK_S3D4C 18 +#define R8A77995_CLK_LB 19 +#define R8A77995_CLK_CL 20 +#define R8A77995_CLK_ZB3 21 +#define R8A77995_CLK_ZB3D2 22 +#define R8A77995_CLK_CR 23 +#define R8A77995_CLK_CRD2 24 +#define R8A77995_CLK_SD0H 25 +#define R8A77995_CLK_SD0 26 +#define R8A77995_CLK_SSP2 27 +#define R8A77995_CLK_SSP1 28 +#define R8A77995_CLK_RPC 29 +#define R8A77995_CLK_RPCD2 30 +#define R8A77995_CLK_ZA2 31 +#define R8A77995_CLK_ZA8 32 +#define R8A77995_CLK_Z2D 33 +#define R8A77995_CLK_CANFD 34 +#define R8A77995_CLK_MSO 35 +#define R8A77995_CLK_R 36 +#define R8A77995_CLK_OSC 37 +#define R8A77995_CLK_LV0 38 +#define R8A77995_CLK_LV1 39 +#define R8A77995_CLK_CP 40 + +#endif /* __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ */ diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index 56f841c22801a7b5c349cb99f5732b3274986ce3..55655ab0a4c47a2c538f7e866409a5361be285f8 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -49,6 +49,7 @@ #define SCLK_EMMC_DRV 117 #define SCLK_SDMMC_SAMPLE 118 #define SCLK_SDIO_SAMPLE 119 +#define SCLK_SDIO_SRC 120 #define SCLK_EMMC_SAMPLE 121 #define SCLK_VOP 122 #define SCLK_HDMI_HDCP 123 diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h index ae26f81059142867a009197e1c37c8e00d3dbd21..d8d0e0456dc24dc1d5d788b378103807d2dd8faa 100644 --- a/include/dt-bindings/clock/rv1108-cru.h +++ b/include/dt-bindings/clock/rv1108-cru.h @@ -43,12 +43,74 @@ #define SCLK_SDMMC_SAMPLE 84 #define SCLK_SDIO_SAMPLE 85 #define SCLK_EMMC_SAMPLE 86 +#define SCLK_VENC_CORE 87 +#define SCLK_HEVC_CORE 88 +#define SCLK_HEVC_CABAC 89 +#define SCLK_PWM0_PMU 90 +#define SCLK_I2C0_PMU 91 +#define SCLK_WIFI 92 +#define SCLK_CIFOUT 93 +#define SCLK_MIPI_CSI_OUT 94 +#define SCLK_CIF0 95 +#define SCLK_CIF1 96 +#define SCLK_CIF2 97 +#define SCLK_CIF3 98 +#define SCLK_DSP 99 +#define SCLK_DSP_IOP 100 +#define SCLK_DSP_EPP 101 +#define SCLK_DSP_EDP 102 +#define SCLK_DSP_EDAP 103 +#define SCLK_CVBS_HOST 104 +#define SCLK_HDMI_SFR 105 +#define SCLK_HDMI_CEC 106 +#define SCLK_CRYPTO 107 +#define SCLK_SPI 108 +#define SCLK_SARADC 109 +#define SCLK_TSADC 110 +#define SCLK_MAC_PRE 111 +#define SCLK_MAC 112 +#define SCLK_MAC_RX 113 +#define SCLK_MAC_REF 114 +#define SCLK_MAC_REFOUT 115 +#define SCLK_DSP_PFM 116 +#define SCLK_RGA 117 +#define SCLK_I2C1 118 +#define SCLK_I2C2 119 +#define SCLK_I2C3 120 +#define SCLK_PWM 121 +#define SCLK_ISP 122 +#define SCLK_USBPHY 123 +#define SCLK_I2S0_SRC 124 +#define SCLK_I2S1_SRC 125 +#define SCLK_I2S2_SRC 126 +#define SCLK_UART0_SRC 127 +#define SCLK_UART1_SRC 128 +#define SCLK_UART2_SRC 129 + +#define DCLK_VOP_SRC 185 +#define DCLK_HDMIPHY 186 +#define DCLK_VOP 187 /* aclk gates */ #define ACLK_DMAC 192 #define ACLK_PRE 193 #define ACLK_CORE 194 #define ACLK_ENMCORE 195 +#define ACLK_RKVENC 196 +#define ACLK_RKVDEC 197 +#define ACLK_VPU 198 +#define ACLK_CIF0 199 +#define ACLK_VIO0 200 +#define ACLK_VIO1 201 +#define ACLK_VOP 202 +#define ACLK_IEP 203 +#define ACLK_RGA 204 +#define ACLK_ISP 205 +#define ACLK_CIF1 206 +#define ACLK_CIF2 207 +#define ACLK_CIF3 208 +#define ACLK_PERI 209 +#define ACLK_GMAC 210 /* pclk gates */ #define PCLK_GPIO1 256 @@ -67,10 +129,24 @@ #define PCLK_PWM 269 #define PCLK_TIMER 270 #define PCLK_PERI 271 +#define PCLK_GPIO0_PMU 272 +#define PCLK_I2C0_PMU 273 +#define PCLK_PWM0_PMU 274 +#define PCLK_ISP 275 +#define PCLK_VIO 276 +#define PCLK_MIPI_DSI 277 +#define PCLK_HDMI_CTRL 278 +#define PCLK_SARADC 279 +#define PCLK_DSP_CFG 280 +#define PCLK_BUS 281 +#define PCLK_EFUSE0 282 +#define PCLK_EFUSE1 283 +#define PCLK_WDT 284 +#define PCLK_GMAC 285 /* hclk gates */ #define HCLK_I2S0_8CH 320 -#define HCLK_I2S1_8CH 321 +#define HCLK_I2S1_2CH 321 #define HCLK_I2S2_2CH 322 #define HCLK_NANDC 323 #define HCLK_SDMMC 324 @@ -78,20 +154,37 @@ #define HCLK_EMMC 326 #define HCLK_PERI 327 #define HCLK_SFC 328 +#define HCLK_RKVENC 329 +#define HCLK_RKVDEC 330 +#define HCLK_CIF0 331 +#define HCLK_VIO 332 +#define HCLK_VOP 333 +#define HCLK_IEP 334 +#define HCLK_RGA 335 +#define HCLK_ISP 336 +#define HCLK_CRYPTO_MST 337 +#define HCLK_CRYPTO_SLV 338 +#define HCLK_HOST0 339 +#define HCLK_OTG 340 +#define HCLK_CIF1 341 +#define HCLK_CIF2 342 +#define HCLK_CIF3 343 +#define HCLK_BUS 344 +#define HCLK_VPU 345 -#define CLK_NR_CLKS (HCLK_SFC + 1) +#define CLK_NR_CLKS (HCLK_VPU + 1) /* reset id */ -#define SRST_CORE_PO_AD 0 +#define SRST_CORE_PO_AD 0 #define SRST_CORE_AD 1 #define SRST_L2_AD 2 -#define SRST_CPU_NIU_AD 3 +#define SRST_CPU_NIU_AD 3 #define SRST_CORE_PO 4 #define SRST_CORE 5 -#define SRST_L2 6 +#define SRST_L2 6 #define SRST_CORE_DBG 8 #define PRST_DBG 9 -#define RST_DAP 10 +#define RST_DAP 10 #define PRST_DBG_NIU 11 #define ARST_STRC_SYS_AD 15 @@ -158,9 +251,9 @@ #define HRST_SYSBUS 75 #define PRST_USBGRF 76 -#define ARST_PERIPH_NIU 80 -#define HRST_PERIPH_NIU 81 -#define PRST_PERIPH_NIU 82 +#define ARST_PERIPH_NIU 80 +#define HRST_PERIPH_NIU 81 +#define PRST_PERIPH_NIU 82 #define HRST_PERIPH 83 #define HRST_SDMMC 84 #define HRST_SDIO 85 @@ -178,7 +271,7 @@ #define HRST_HOST0_AUX 96 #define HRST_HOST0_ARB 97 #define SRST_HOST0_EHCIPHY 98 -#define SRST_HOST0_UTMI 99 +#define SRST_HOST0_UTMI 99 #define SRST_USBPOR 100 #define SRST_UTMI0 101 #define SRST_UTMI1 102 @@ -225,21 +318,21 @@ #define HRST_VPU_NIU 141 #define ARST_VPU 142 #define HRST_VPU 143 -#define ARST_RKVDEC_NIU 144 -#define HRST_RKVDEC_NIU 145 +#define ARST_RKVDEC_NIU 144 +#define HRST_RKVDEC_NIU 145 #define ARST_RKVDEC 146 #define HRST_RKVDEC 147 #define SRST_RKVDEC_CABAC 148 #define SRST_RKVDEC_CORE 149 -#define ARST_RKVENC_NIU 150 -#define HRST_RKVENC_NIU 151 +#define ARST_RKVENC_NIU 150 +#define HRST_RKVENC_NIU 151 #define ARST_RKVENC 152 #define HRST_RKVENC 153 #define SRST_RKVENC_CORE 154 #define SRST_DSP_CORE 156 #define SRST_DSP_SYS 157 -#define SRST_DSP_GLOBAL 158 +#define SRST_DSP_GLOBAL 158 #define SRST_DSP_OECM 159 #define PRST_DSP_IOP_NIU 160 #define ARST_DSP_EPP_NIU 161 @@ -257,7 +350,7 @@ #define SRST_PMU_I2C0 173 #define PRST_PMU_I2C0 174 #define PRST_PMU_GPIO0 175 -#define PRST_PMU_INTMEM 176 +#define PRST_PMU_INTMEM 176 #define PRST_PMU_PWM0 177 #define SRST_PMU_PWM0 178 #define PRST_PMU_GRF 179 diff --git a/include/dt-bindings/clock/stm32h7-clks.h b/include/dt-bindings/clock/stm32h7-clks.h new file mode 100644 index 0000000000000000000000000000000000000000..6637272b324244f96497817756aa1e25102c1ba0 --- /dev/null +++ b/include/dt-bindings/clock/stm32h7-clks.h @@ -0,0 +1,165 @@ +/* SYS, CORE AND BUS CLOCKS */ +#define SYS_D1CPRE 0 +#define HCLK 1 +#define PCLK1 2 +#define PCLK2 3 +#define PCLK3 4 +#define PCLK4 5 +#define HSI_DIV 6 +#define HSE_1M 7 +#define I2S_CKIN 8 +#define CK_DSI_PHY 9 +#define HSE_CK 10 +#define LSE_CK 11 +#define CSI_KER_DIV122 12 +#define RTC_CK 13 +#define CPU_SYSTICK 14 + +/* OSCILLATOR BANK */ +#define OSC_BANK 18 +#define HSI_CK 18 +#define HSI_KER_CK 19 +#define CSI_CK 20 +#define CSI_KER_CK 21 +#define RC48_CK 22 +#define LSI_CK 23 + +/* MCLOCK BANK */ +#define MCLK_BANK 28 +#define PER_CK 28 +#define PLLSRC 29 +#define SYS_CK 30 +#define TRACEIN_CK 31 + +/* ODF BANK */ +#define ODF_BANK 32 +#define PLL1_P 32 +#define PLL1_Q 33 +#define PLL1_R 34 +#define PLL2_P 35 +#define PLL2_Q 36 +#define PLL2_R 37 +#define PLL3_P 38 +#define PLL3_Q 39 +#define PLL3_R 40 + +/* MCO BANK */ +#define MCO_BANK 41 +#define MCO1 41 +#define MCO2 42 + +/* PERIF BANK */ +#define PERIF_BANK 50 +#define D1SRAM1_CK 50 +#define ITCM_CK 51 +#define DTCM2_CK 52 +#define DTCM1_CK 53 +#define FLITF_CK 54 +#define JPGDEC_CK 55 +#define DMA2D_CK 56 +#define MDMA_CK 57 +#define USB2ULPI_CK 58 +#define USB1ULPI_CK 59 +#define ETH1RX_CK 60 +#define ETH1TX_CK 61 +#define ETH1MAC_CK 62 +#define ART_CK 63 +#define DMA2_CK 64 +#define DMA1_CK 65 +#define D2SRAM3_CK 66 +#define D2SRAM2_CK 67 +#define D2SRAM1_CK 68 +#define HASH_CK 69 +#define CRYPT_CK 70 +#define CAMITF_CK 71 +#define BKPRAM_CK 72 +#define HSEM_CK 73 +#define BDMA_CK 74 +#define CRC_CK 75 +#define GPIOK_CK 76 +#define GPIOJ_CK 77 +#define GPIOI_CK 78 +#define GPIOH_CK 79 +#define GPIOG_CK 80 +#define GPIOF_CK 81 +#define GPIOE_CK 82 +#define GPIOD_CK 83 +#define GPIOC_CK 84 +#define GPIOB_CK 85 +#define GPIOA_CK 86 +#define WWDG1_CK 87 +#define DAC12_CK 88 +#define WWDG2_CK 89 +#define TIM14_CK 90 +#define TIM13_CK 91 +#define TIM12_CK 92 +#define TIM7_CK 93 +#define TIM6_CK 94 +#define TIM5_CK 95 +#define TIM4_CK 96 +#define TIM3_CK 97 +#define TIM2_CK 98 +#define MDIOS_CK 99 +#define OPAMP_CK 100 +#define CRS_CK 101 +#define TIM17_CK 102 +#define TIM16_CK 103 +#define TIM15_CK 104 +#define TIM8_CK 105 +#define TIM1_CK 106 +#define TMPSENS_CK 107 +#define RTCAPB_CK 108 +#define VREF_CK 109 +#define COMP12_CK 110 +#define SYSCFG_CK 111 + +/* KERNEL BANK */ +#define KERN_BANK 120 +#define SDMMC1_CK 120 +#define QUADSPI_CK 121 +#define FMC_CK 122 +#define USB2OTG_CK 123 +#define USB1OTG_CK 124 +#define ADC12_CK 125 +#define SDMMC2_CK 126 +#define RNG_CK 127 +#define ADC3_CK 128 +#define DSI_CK 129 +#define LTDC_CK 130 +#define USART8_CK 131 +#define USART7_CK 132 +#define HDMICEC_CK 133 +#define I2C3_CK 134 +#define I2C2_CK 135 +#define I2C1_CK 136 +#define UART5_CK 137 +#define UART4_CK 138 +#define USART3_CK 139 +#define USART2_CK 140 +#define SPDIFRX_CK 141 +#define SPI3_CK 142 +#define SPI2_CK 143 +#define LPTIM1_CK 144 +#define FDCAN_CK 145 +#define SWP_CK 146 +#define HRTIM_CK 147 +#define DFSDM1_CK 148 +#define SAI3_CK 149 +#define SAI2_CK 150 +#define SAI1_CK 151 +#define SPI5_CK 152 +#define SPI4_CK 153 +#define SPI1_CK 154 +#define USART6_CK 155 +#define USART1_CK 156 +#define SAI4B_CK 157 +#define SAI4A_CK 158 +#define LPTIM5_CK 159 +#define LPTIM4_CK 160 +#define LPTIM3_CK 161 +#define LPTIM2_CK 162 +#define I2C4_CK 163 +#define SPI6_CK 164 +#define LPUART1_CK 165 + +#define STM32H7_MAX_CLKS 166 diff --git a/include/dt-bindings/clock/sun4i-a10-ccu.h b/include/dt-bindings/clock/sun4i-a10-ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..c5a53f38d654048e2c9c8bc2bd3f2f850316bb7c --- /dev/null +++ b/include/dt-bindings/clock/sun4i-a10-ccu.h @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2017 Priit Laes + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLK_SUN4I_A10_H_ +#define _DT_BINDINGS_CLK_SUN4I_A10_H_ + +#define CLK_HOSC 1 +#define CLK_CPU 20 + +/* AHB Gates */ +#define CLK_AHB_OTG 26 +#define CLK_AHB_EHCI0 27 +#define CLK_AHB_OHCI0 28 +#define CLK_AHB_EHCI1 29 +#define CLK_AHB_OHCI1 30 +#define CLK_AHB_SS 31 +#define CLK_AHB_DMA 32 +#define CLK_AHB_BIST 33 +#define CLK_AHB_MMC0 34 +#define CLK_AHB_MMC1 35 +#define CLK_AHB_MMC2 36 +#define CLK_AHB_MMC3 37 +#define CLK_AHB_MS 38 +#define CLK_AHB_NAND 39 +#define CLK_AHB_SDRAM 40 +#define CLK_AHB_ACE 41 +#define CLK_AHB_EMAC 42 +#define CLK_AHB_TS 43 +#define CLK_AHB_SPI0 44 +#define CLK_AHB_SPI1 45 +#define CLK_AHB_SPI2 46 +#define CLK_AHB_SPI3 47 +#define CLK_AHB_PATA 48 +#define CLK_AHB_SATA 49 +#define CLK_AHB_GPS 50 +#define CLK_AHB_HSTIMER 51 +#define CLK_AHB_VE 52 +#define CLK_AHB_TVD 53 +#define CLK_AHB_TVE0 54 +#define CLK_AHB_TVE1 55 +#define CLK_AHB_LCD0 56 +#define CLK_AHB_LCD1 57 +#define CLK_AHB_CSI0 58 +#define CLK_AHB_CSI1 59 +#define CLK_AHB_HDMI0 60 +#define CLK_AHB_HDMI1 61 +#define CLK_AHB_DE_BE0 62 +#define CLK_AHB_DE_BE1 63 +#define CLK_AHB_DE_FE0 64 +#define CLK_AHB_DE_FE1 65 +#define CLK_AHB_GMAC 66 +#define CLK_AHB_MP 67 +#define CLK_AHB_GPU 68 + +/* APB0 Gates */ +#define CLK_APB0_CODEC 69 +#define CLK_APB0_SPDIF 70 +#define CLK_APB0_I2S0 71 +#define CLK_APB0_AC97 72 +#define CLK_APB0_I2S1 73 +#define CLK_APB0_PIO 74 +#define CLK_APB0_IR0 75 +#define CLK_APB0_IR1 76 +#define CLK_APB0_I2S2 77 +#define CLK_APB0_KEYPAD 78 + +/* APB1 Gates */ +#define CLK_APB1_I2C0 79 +#define CLK_APB1_I2C1 80 +#define CLK_APB1_I2C2 81 +#define CLK_APB1_I2C3 82 +#define CLK_APB1_CAN 83 +#define CLK_APB1_SCR 84 +#define CLK_APB1_PS20 85 +#define CLK_APB1_PS21 86 +#define CLK_APB1_I2C4 87 +#define CLK_APB1_UART0 88 +#define CLK_APB1_UART1 89 +#define CLK_APB1_UART2 90 +#define CLK_APB1_UART3 91 +#define CLK_APB1_UART4 92 +#define CLK_APB1_UART5 93 +#define CLK_APB1_UART6 94 +#define CLK_APB1_UART7 95 + +/* IP clocks */ +#define CLK_NAND 96 +#define CLK_MS 97 +#define CLK_MMC0 98 +#define CLK_MMC0_OUTPUT 99 +#define CLK_MMC0_SAMPLE 100 +#define CLK_MMC1 101 +#define CLK_MMC1_OUTPUT 102 +#define CLK_MMC1_SAMPLE 103 +#define CLK_MMC2 104 +#define CLK_MMC2_OUTPUT 105 +#define CLK_MMC2_SAMPLE 106 +#define CLK_MMC3 107 +#define CLK_MMC3_OUTPUT 108 +#define CLK_MMC3_SAMPLE 109 +#define CLK_TS 110 +#define CLK_SS 111 +#define CLK_SPI0 112 +#define CLK_SPI1 113 +#define CLK_SPI2 114 +#define CLK_PATA 115 +#define CLK_IR0 116 +#define CLK_IR1 117 +#define CLK_I2S0 118 +#define CLK_AC97 119 +#define CLK_SPDIF 120 +#define CLK_KEYPAD 121 +#define CLK_SATA 122 +#define CLK_USB_OHCI0 123 +#define CLK_USB_OHCI1 124 +#define CLK_USB_PHY 125 +#define CLK_GPS 126 +#define CLK_SPI3 127 +#define CLK_I2S1 128 +#define CLK_I2S2 129 + +/* DRAM Gates */ +#define CLK_DRAM_VE 130 +#define CLK_DRAM_CSI0 131 +#define CLK_DRAM_CSI1 132 +#define CLK_DRAM_TS 133 +#define CLK_DRAM_TVD 134 +#define CLK_DRAM_TVE0 135 +#define CLK_DRAM_TVE1 136 +#define CLK_DRAM_OUT 137 +#define CLK_DRAM_DE_FE1 138 +#define CLK_DRAM_DE_FE0 139 +#define CLK_DRAM_DE_BE0 140 +#define CLK_DRAM_DE_BE1 141 +#define CLK_DRAM_MP 142 +#define CLK_DRAM_ACE 143 + +/* Display Engine Clocks */ +#define CLK_DE_BE0 144 +#define CLK_DE_BE1 145 +#define CLK_DE_FE0 146 +#define CLK_DE_FE1 147 +#define CLK_DE_MP 148 +#define CLK_TCON0_CH0 149 +#define CLK_TCON1_CH0 150 +#define CLK_CSI_SCLK 151 +#define CLK_TVD_SCLK2 152 +#define CLK_TVD 153 +#define CLK_TCON0_CH1_SCLK2 154 +#define CLK_TCON0_CH1 155 +#define CLK_TCON1_CH1_SCLK2 156 +#define CLK_TCON1_CH1 157 +#define CLK_CSI0 158 +#define CLK_CSI1 159 +#define CLK_CODEC 160 +#define CLK_VE 161 +#define CLK_AVS 162 +#define CLK_ACE 163 +#define CLK_HDMI 164 +#define CLK_GPU 165 + +#endif /* _DT_BINDINGS_CLK_SUN4I_A10_H_ */ diff --git a/include/dt-bindings/clock/sun7i-a20-ccu.h b/include/dt-bindings/clock/sun7i-a20-ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..045a5178da0c618d3ea5cf6f6fa56eda8baf370e --- /dev/null +++ b/include/dt-bindings/clock/sun7i-a20-ccu.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 Priit Laes + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLK_SUN7I_A20_H_ +#define _DT_BINDINGS_CLK_SUN7I_A20_H_ + +#include + +#define CLK_MBUS 166 +#define CLK_HDMI1_SLOW 167 +#define CLK_HDMI1 168 +#define CLK_OUT_A 169 +#define CLK_OUT_B 170 + +#endif /* _DT_BINDINGS_CLK_SUN7I_A20_H_ */ diff --git a/include/dt-bindings/clock/sun8i-r40-ccu.h b/include/dt-bindings/clock/sun8i-r40-ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..4fa5f69fc297cbed6c2b7868759a6bec6345a793 --- /dev/null +++ b/include/dt-bindings/clock/sun8i-r40-ccu.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2017 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_ +#define _DT_BINDINGS_CLK_SUN8I_R40_H_ + +#define CLK_CPU 24 + +#define CLK_BUS_MIPI_DSI 29 +#define CLK_BUS_CE 30 +#define CLK_BUS_DMA 31 +#define CLK_BUS_MMC0 32 +#define CLK_BUS_MMC1 33 +#define CLK_BUS_MMC2 34 +#define CLK_BUS_MMC3 35 +#define CLK_BUS_NAND 36 +#define CLK_BUS_DRAM 37 +#define CLK_BUS_EMAC 38 +#define CLK_BUS_TS 39 +#define CLK_BUS_HSTIMER 40 +#define CLK_BUS_SPI0 41 +#define CLK_BUS_SPI1 42 +#define CLK_BUS_SPI2 43 +#define CLK_BUS_SPI3 44 +#define CLK_BUS_SATA 45 +#define CLK_BUS_OTG 46 +#define CLK_BUS_EHCI0 47 +#define CLK_BUS_EHCI1 48 +#define CLK_BUS_EHCI2 49 +#define CLK_BUS_OHCI0 50 +#define CLK_BUS_OHCI1 51 +#define CLK_BUS_OHCI2 52 +#define CLK_BUS_VE 53 +#define CLK_BUS_MP 54 +#define CLK_BUS_DEINTERLACE 55 +#define CLK_BUS_CSI0 56 +#define CLK_BUS_CSI1 57 +#define CLK_BUS_HDMI1 58 +#define CLK_BUS_HDMI0 59 +#define CLK_BUS_DE 60 +#define CLK_BUS_TVE0 61 +#define CLK_BUS_TVE1 62 +#define CLK_BUS_TVE_TOP 63 +#define CLK_BUS_GMAC 64 +#define CLK_BUS_GPU 65 +#define CLK_BUS_TVD0 66 +#define CLK_BUS_TVD1 67 +#define CLK_BUS_TVD2 68 +#define CLK_BUS_TVD3 69 +#define CLK_BUS_TVD_TOP 70 +#define CLK_BUS_TCON_LCD0 71 +#define CLK_BUS_TCON_LCD1 72 +#define CLK_BUS_TCON_TV0 73 +#define CLK_BUS_TCON_TV1 74 +#define CLK_BUS_TCON_TOP 75 +#define CLK_BUS_CODEC 76 +#define CLK_BUS_SPDIF 77 +#define CLK_BUS_AC97 78 +#define CLK_BUS_PIO 79 +#define CLK_BUS_IR0 80 +#define CLK_BUS_IR1 81 +#define CLK_BUS_THS 82 +#define CLK_BUS_KEYPAD 83 +#define CLK_BUS_I2S0 84 +#define CLK_BUS_I2S1 85 +#define CLK_BUS_I2S2 86 +#define CLK_BUS_I2C0 87 +#define CLK_BUS_I2C1 88 +#define CLK_BUS_I2C2 89 +#define CLK_BUS_I2C3 90 +#define CLK_BUS_CAN 91 +#define CLK_BUS_SCR 92 +#define CLK_BUS_PS20 93 +#define CLK_BUS_PS21 94 +#define CLK_BUS_I2C4 95 +#define CLK_BUS_UART0 96 +#define CLK_BUS_UART1 97 +#define CLK_BUS_UART2 98 +#define CLK_BUS_UART3 99 +#define CLK_BUS_UART4 100 +#define CLK_BUS_UART5 101 +#define CLK_BUS_UART6 102 +#define CLK_BUS_UART7 103 +#define CLK_BUS_DBG 104 + +#define CLK_THS 105 +#define CLK_NAND 106 +#define CLK_MMC0 107 +#define CLK_MMC1 108 +#define CLK_MMC2 109 +#define CLK_MMC3 110 +#define CLK_TS 111 +#define CLK_CE 112 +#define CLK_SPI0 113 +#define CLK_SPI1 114 +#define CLK_SPI2 115 +#define CLK_SPI3 116 +#define CLK_I2S0 117 +#define CLK_I2S1 118 +#define CLK_I2S2 119 +#define CLK_AC97 120 +#define CLK_SPDIF 121 +#define CLK_KEYPAD 122 +#define CLK_SATA 123 +#define CLK_USB_PHY0 124 +#define CLK_USB_PHY1 125 +#define CLK_USB_PHY2 126 +#define CLK_USB_OHCI0 127 +#define CLK_USB_OHCI1 128 +#define CLK_USB_OHCI2 129 +#define CLK_IR0 130 +#define CLK_IR1 131 + +#define CLK_DRAM_VE 133 +#define CLK_DRAM_CSI0 134 +#define CLK_DRAM_CSI1 135 +#define CLK_DRAM_TS 136 +#define CLK_DRAM_TVD 137 +#define CLK_DRAM_MP 138 +#define CLK_DRAM_DEINTERLACE 139 +#define CLK_DE 140 +#define CLK_MP 141 +#define CLK_TCON_LCD0 142 +#define CLK_TCON_LCD1 143 +#define CLK_TCON_TV0 144 +#define CLK_TCON_TV1 145 +#define CLK_DEINTERLACE 146 +#define CLK_CSI1_MCLK 147 +#define CLK_CSI_SCLK 148 +#define CLK_CSI0_MCLK 149 +#define CLK_VE 150 +#define CLK_CODEC 151 +#define CLK_AVS 152 +#define CLK_HDMI 153 +#define CLK_HDMI_SLOW 154 + +#define CLK_DSI_DPHY 156 +#define CLK_TVE0 157 +#define CLK_TVE1 158 +#define CLK_TVD0 159 +#define CLK_TVD1 160 +#define CLK_TVD2 161 +#define CLK_TVD3 162 +#define CLK_GPU 163 +#define CLK_OUTA 164 +#define CLK_OUTB 165 + +#endif /* _DT_BINDINGS_CLK_SUN8I_R40_H_ */ diff --git a/include/dt-bindings/genpd/k2g.h b/include/dt-bindings/genpd/k2g.h deleted file mode 100644 index 1f31f17e19ebca5e528ad9498047ec9bd973d3c4..0000000000000000000000000000000000000000 --- a/include/dt-bindings/genpd/k2g.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * TI K2G SoC Device definitions - * - * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _DT_BINDINGS_GENPD_K2G_H -#define _DT_BINDINGS_GENPD_K2G_H - -/* Documented in http://processors.wiki.ti.com/index.php/TISCI */ - -#define K2G_DEV_PMMC0 0x0000 -#define K2G_DEV_MLB0 0x0001 -#define K2G_DEV_DSS0 0x0002 -#define K2G_DEV_MCBSP0 0x0003 -#define K2G_DEV_MCASP0 0x0004 -#define K2G_DEV_MCASP1 0x0005 -#define K2G_DEV_MCASP2 0x0006 -#define K2G_DEV_DCAN0 0x0008 -#define K2G_DEV_DCAN1 0x0009 -#define K2G_DEV_EMIF0 0x000a -#define K2G_DEV_MMCHS0 0x000b -#define K2G_DEV_MMCHS1 0x000c -#define K2G_DEV_GPMC0 0x000d -#define K2G_DEV_ELM0 0x000e -#define K2G_DEV_SPI0 0x0010 -#define K2G_DEV_SPI1 0x0011 -#define K2G_DEV_SPI2 0x0012 -#define K2G_DEV_SPI3 0x0013 -#define K2G_DEV_ICSS0 0x0014 -#define K2G_DEV_ICSS1 0x0015 -#define K2G_DEV_USB0 0x0016 -#define K2G_DEV_USB1 0x0017 -#define K2G_DEV_NSS0 0x0018 -#define K2G_DEV_PCIE0 0x0019 -#define K2G_DEV_GPIO0 0x001b -#define K2G_DEV_GPIO1 0x001c -#define K2G_DEV_TIMER64_0 0x001d -#define K2G_DEV_TIMER64_1 0x001e -#define K2G_DEV_TIMER64_2 0x001f -#define K2G_DEV_TIMER64_3 0x0020 -#define K2G_DEV_TIMER64_4 0x0021 -#define K2G_DEV_TIMER64_5 0x0022 -#define K2G_DEV_TIMER64_6 0x0023 -#define K2G_DEV_MSGMGR0 0x0025 -#define K2G_DEV_BOOTCFG0 0x0026 -#define K2G_DEV_ARM_BOOTROM0 0x0027 -#define K2G_DEV_DSP_BOOTROM0 0x0029 -#define K2G_DEV_DEBUGSS0 0x002b -#define K2G_DEV_UART0 0x002c -#define K2G_DEV_UART1 0x002d -#define K2G_DEV_UART2 0x002e -#define K2G_DEV_EHRPWM0 0x002f -#define K2G_DEV_EHRPWM1 0x0030 -#define K2G_DEV_EHRPWM2 0x0031 -#define K2G_DEV_EHRPWM3 0x0032 -#define K2G_DEV_EHRPWM4 0x0033 -#define K2G_DEV_EHRPWM5 0x0034 -#define K2G_DEV_EQEP0 0x0035 -#define K2G_DEV_EQEP1 0x0036 -#define K2G_DEV_EQEP2 0x0037 -#define K2G_DEV_ECAP0 0x0038 -#define K2G_DEV_ECAP1 0x0039 -#define K2G_DEV_I2C0 0x003a -#define K2G_DEV_I2C1 0x003b -#define K2G_DEV_I2C2 0x003c -#define K2G_DEV_EDMA0 0x003f -#define K2G_DEV_SEMAPHORE0 0x0040 -#define K2G_DEV_INTC0 0x0041 -#define K2G_DEV_GIC0 0x0042 -#define K2G_DEV_QSPI0 0x0043 -#define K2G_DEV_ARM_64B_COUNTER0 0x0044 -#define K2G_DEV_TETRIS0 0x0045 -#define K2G_DEV_CGEM0 0x0046 -#define K2G_DEV_MSMC0 0x0047 -#define K2G_DEV_CBASS0 0x0049 -#define K2G_DEV_BOARD0 0x004c -#define K2G_DEV_EDMA1 0x004f - -#endif diff --git a/include/dt-bindings/leds/leds-pca955x.h b/include/dt-bindings/leds/leds-pca955x.h new file mode 100644 index 0000000000000000000000000000000000000000..78cb7e979de7b13968c538c9bc4b9b0ea33e92c8 --- /dev/null +++ b/include/dt-bindings/leds/leds-pca955x.h @@ -0,0 +1,16 @@ +/* + * This header provides constants for pca955x LED bindings. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef _DT_BINDINGS_LEDS_PCA955X_H +#define _DT_BINDINGS_LEDS_PCA955X_H + +#define PCA955X_TYPE_NONE 0 +#define PCA955X_TYPE_LED 1 +#define PCA955X_TYPE_GPIO 2 + +#endif /* _DT_BINDINGS_LEDS_PCA955X_H */ diff --git a/include/dt-bindings/memory/mt8173-larb-port.h b/include/dt-bindings/memory/mt8173-larb-port.h index 5fef5d1f8f820de5fc78102e5f996ae3181e0e53..111b4b0ec85a1660ea11f94c8438cf19adab1571 100644 --- a/include/dt-bindings/memory/mt8173-larb-port.h +++ b/include/dt-bindings/memory/mt8173-larb-port.h @@ -15,10 +15,6 @@ #define __DTS_IOMMU_PORT_MT8173_H #define MTK_M4U_ID(larb, port) (((larb) << 5) | (port)) -/* Local arbiter ID */ -#define MTK_M4U_TO_LARB(id) (((id) >> 5) & 0x7) -/* PortID within the local arbiter */ -#define MTK_M4U_TO_PORT(id) ((id) & 0x1f) #define M4U_LARB0_ID 0 #define M4U_LARB1_ID 1 diff --git a/include/dt-bindings/mfd/stm32h7-rcc.h b/include/dt-bindings/mfd/stm32h7-rcc.h new file mode 100644 index 0000000000000000000000000000000000000000..461a8e04453a2b432400b7e5fc669b518362b3fe --- /dev/null +++ b/include/dt-bindings/mfd/stm32h7-rcc.h @@ -0,0 +1,136 @@ +/* + * This header provides constants for the STM32H7 RCC IP + */ + +#ifndef _DT_BINDINGS_MFD_STM32H7_RCC_H +#define _DT_BINDINGS_MFD_STM32H7_RCC_H + +/* AHB3 */ +#define STM32H7_RCC_AHB3_MDMA 0 +#define STM32H7_RCC_AHB3_DMA2D 4 +#define STM32H7_RCC_AHB3_JPGDEC 5 +#define STM32H7_RCC_AHB3_FMC 12 +#define STM32H7_RCC_AHB3_QUADSPI 14 +#define STM32H7_RCC_AHB3_SDMMC1 16 +#define STM32H7_RCC_AHB3_CPU 31 + +#define STM32H7_AHB3_RESET(bit) (STM32H7_RCC_AHB3_##bit + (0x7C * 8)) + +/* AHB1 */ +#define STM32H7_RCC_AHB1_DMA1 0 +#define STM32H7_RCC_AHB1_DMA2 1 +#define STM32H7_RCC_AHB1_ADC12 5 +#define STM32H7_RCC_AHB1_ART 14 +#define STM32H7_RCC_AHB1_ETH1MAC 15 +#define STM32H7_RCC_AHB1_USB1OTG 25 +#define STM32H7_RCC_AHB1_USB2OTG 27 + +#define STM32H7_AHB1_RESET(bit) (STM32H7_RCC_AHB1_##bit + (0x80 * 8)) + +/* AHB2 */ +#define STM32H7_RCC_AHB2_CAMITF 0 +#define STM32H7_RCC_AHB2_CRYPT 4 +#define STM32H7_RCC_AHB2_HASH 5 +#define STM32H7_RCC_AHB2_RNG 6 +#define STM32H7_RCC_AHB2_SDMMC2 9 + +#define STM32H7_AHB2_RESET(bit) (STM32H7_RCC_AHB2_##bit + (0x84 * 8)) + +/* AHB4 */ +#define STM32H7_RCC_AHB4_GPIOA 0 +#define STM32H7_RCC_AHB4_GPIOB 1 +#define STM32H7_RCC_AHB4_GPIOC 2 +#define STM32H7_RCC_AHB4_GPIOD 3 +#define STM32H7_RCC_AHB4_GPIOE 4 +#define STM32H7_RCC_AHB4_GPIOF 5 +#define STM32H7_RCC_AHB4_GPIOG 6 +#define STM32H7_RCC_AHB4_GPIOH 7 +#define STM32H7_RCC_AHB4_GPIOI 8 +#define STM32H7_RCC_AHB4_GPIOJ 9 +#define STM32H7_RCC_AHB4_GPIOK 10 +#define STM32H7_RCC_AHB4_CRC 19 +#define STM32H7_RCC_AHB4_BDMA 21 +#define STM32H7_RCC_AHB4_ADC3 24 +#define STM32H7_RCC_AHB4_HSEM 25 + +#define STM32H7_AHB4_RESET(bit) (STM32H7_RCC_AHB4_##bit + (0x88 * 8)) + +/* APB3 */ +#define STM32H7_RCC_APB3_LTDC 3 +#define STM32H7_RCC_APB3_DSI 4 + +#define STM32H7_APB3_RESET(bit) (STM32H7_RCC_APB3_##bit + (0x8C * 8)) + +/* APB1L */ +#define STM32H7_RCC_APB1L_TIM2 0 +#define STM32H7_RCC_APB1L_TIM3 1 +#define STM32H7_RCC_APB1L_TIM4 2 +#define STM32H7_RCC_APB1L_TIM5 3 +#define STM32H7_RCC_APB1L_TIM6 4 +#define STM32H7_RCC_APB1L_TIM7 5 +#define STM32H7_RCC_APB1L_TIM12 6 +#define STM32H7_RCC_APB1L_TIM13 7 +#define STM32H7_RCC_APB1L_TIM14 8 +#define STM32H7_RCC_APB1L_LPTIM1 9 +#define STM32H7_RCC_APB1L_SPI2 14 +#define STM32H7_RCC_APB1L_SPI3 15 +#define STM32H7_RCC_APB1L_SPDIF_RX 16 +#define STM32H7_RCC_APB1L_USART2 17 +#define STM32H7_RCC_APB1L_USART3 18 +#define STM32H7_RCC_APB1L_UART4 19 +#define STM32H7_RCC_APB1L_UART5 20 +#define STM32H7_RCC_APB1L_I2C1 21 +#define STM32H7_RCC_APB1L_I2C2 22 +#define STM32H7_RCC_APB1L_I2C3 23 +#define STM32H7_RCC_APB1L_HDMICEC 27 +#define STM32H7_RCC_APB1L_DAC12 29 +#define STM32H7_RCC_APB1L_USART7 30 +#define STM32H7_RCC_APB1L_USART8 31 + +#define STM32H7_APB1L_RESET(bit) (STM32H7_RCC_APB1L_##bit + (0x90 * 8)) + +/* APB1H */ +#define STM32H7_RCC_APB1H_CRS 1 +#define STM32H7_RCC_APB1H_SWP 2 +#define STM32H7_RCC_APB1H_OPAMP 4 +#define STM32H7_RCC_APB1H_MDIOS 5 +#define STM32H7_RCC_APB1H_FDCAN 8 + +#define STM32H7_APB1H_RESET(bit) (STM32H7_RCC_APB1H_##bit + (0x94 * 8)) + +/* APB2 */ +#define STM32H7_RCC_APB2_TIM1 0 +#define STM32H7_RCC_APB2_TIM8 1 +#define STM32H7_RCC_APB2_USART1 4 +#define STM32H7_RCC_APB2_USART6 5 +#define STM32H7_RCC_APB2_SPI1 12 +#define STM32H7_RCC_APB2_SPI4 13 +#define STM32H7_RCC_APB2_TIM15 16 +#define STM32H7_RCC_APB2_TIM16 17 +#define STM32H7_RCC_APB2_TIM17 18 +#define STM32H7_RCC_APB2_SPI5 20 +#define STM32H7_RCC_APB2_SAI1 22 +#define STM32H7_RCC_APB2_SAI2 23 +#define STM32H7_RCC_APB2_SAI3 24 +#define STM32H7_RCC_APB2_DFSDM1 28 +#define STM32H7_RCC_APB2_HRTIM 29 + +#define STM32H7_APB2_RESET(bit) (STM32H7_RCC_APB2_##bit + (0x98 * 8)) + +/* APB4 */ +#define STM32H7_RCC_APB4_SYSCFG 1 +#define STM32H7_RCC_APB4_LPUART1 3 +#define STM32H7_RCC_APB4_SPI6 5 +#define STM32H7_RCC_APB4_I2C4 7 +#define STM32H7_RCC_APB4_LPTIM2 9 +#define STM32H7_RCC_APB4_LPTIM3 10 +#define STM32H7_RCC_APB4_LPTIM4 11 +#define STM32H7_RCC_APB4_LPTIM5 12 +#define STM32H7_RCC_APB4_COMP12 14 +#define STM32H7_RCC_APB4_VREF 15 +#define STM32H7_RCC_APB4_SAI4 21 +#define STM32H7_RCC_APB4_TMPSENS 26 + +#define STM32H7_APB4_RESET(bit) (STM32H7_RCC_APB4_##bit + (0x9C * 8)) + +#endif /* _DT_BINDINGS_MFD_STM32H7_RCC_H */ diff --git a/include/dt-bindings/mips/lantiq_rcu_gphy.h b/include/dt-bindings/mips/lantiq_rcu_gphy.h new file mode 100644 index 0000000000000000000000000000000000000000..fa1a6377334294be8466f451102e9ddfa97a86f6 --- /dev/null +++ b/include/dt-bindings/mips/lantiq_rcu_gphy.h @@ -0,0 +1,15 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Copyright (C) 2016 Martin Blumenstingl + * Copyright (C) 2017 Hauke Mehrtens + */ +#ifndef _DT_BINDINGS_MIPS_LANTIQ_RCU_GPHY_H +#define _DT_BINDINGS_MIPS_LANTIQ_RCU_GPHY_H + +#define GPHY_MODE_GE 1 +#define GPHY_MODE_FE 2 + +#endif /* _DT_BINDINGS_MIPS_LANTIQ_RCU_GPHY_H */ diff --git a/include/dt-bindings/pinctrl/dra.h b/include/dt-bindings/pinctrl/dra.h index 5c75e80915fcdc5b4411984cd57b8308eb388bfb..18ec5df5a5812a9f037247b6c95de1d15fba2546 100644 --- a/include/dt-bindings/pinctrl/dra.h +++ b/include/dt-bindings/pinctrl/dra.h @@ -73,5 +73,8 @@ */ #define DRA7XX_CORE_IOPAD(pa, val) (((pa) & 0xffff) - 0x3400) (val) +/* DRA7 IODELAY configuration parameters */ +#define A_DELAY_PS(val) ((val) & 0xffff) +#define G_DELAY_PS(val) ((val) & 0xffff) #endif diff --git a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h index d33f17c8a515d17a64a5062d2eb526844c2ac35f..b8ff8824e21b77be263f362b3d3b1d9163d80482 100644 --- a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h +++ b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h @@ -98,6 +98,8 @@ #define PMIC_GPIO_FUNC_PAIRED "paired" #define PMIC_GPIO_FUNC_FUNC1 "func1" #define PMIC_GPIO_FUNC_FUNC2 "func2" +#define PMIC_GPIO_FUNC_FUNC3 "func3" +#define PMIC_GPIO_FUNC_FUNC4 "func4" #define PMIC_GPIO_FUNC_DTEST1 "dtest1" #define PMIC_GPIO_FUNC_DTEST2 "dtest2" #define PMIC_GPIO_FUNC_DTEST3 "dtest3" diff --git a/include/dt-bindings/pinctrl/samsung.h b/include/dt-bindings/pinctrl/samsung.h index b7aa3646208b1c5c83a8f4656eef6767a350fb38..ceb672305f597f05ba69510143c7ecc5acfc40ce 100644 --- a/include/dt-bindings/pinctrl/samsung.h +++ b/include/dt-bindings/pinctrl/samsung.h @@ -66,7 +66,8 @@ #define EXYNOS_PIN_FUNC_4 4 #define EXYNOS_PIN_FUNC_5 5 #define EXYNOS_PIN_FUNC_6 6 -#define EXYNOS_PIN_FUNC_F 0xf +#define EXYNOS_PIN_FUNC_EINT 0xf +#define EXYNOS_PIN_FUNC_F EXYNOS_PIN_FUNC_EINT /* Drive strengths for Exynos7 FSYS1 block */ #define EXYNOS7_FSYS1_PIN_DRV_LV1 0 diff --git a/include/dt-bindings/power/mt7622-power.h b/include/dt-bindings/power/mt7622-power.h new file mode 100644 index 0000000000000000000000000000000000000000..1b639269790c70e3f0890198f5be3fffbb77472a --- /dev/null +++ b/include/dt-bindings/power/mt7622-power.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See http://www.gnu.org/licenses/gpl-2.0.html for more details. + */ + +#ifndef _DT_BINDINGS_POWER_MT7622_POWER_H +#define _DT_BINDINGS_POWER_MT7622_POWER_H + +#define MT7622_POWER_DOMAIN_ETHSYS 0 +#define MT7622_POWER_DOMAIN_HIF0 1 +#define MT7622_POWER_DOMAIN_HIF1 2 +#define MT7622_POWER_DOMAIN_WB 3 + +#endif /* _DT_BINDINGS_POWER_MT7622_POWER_H */ diff --git a/include/dt-bindings/power/r8a77995-sysc.h b/include/dt-bindings/power/r8a77995-sysc.h new file mode 100644 index 0000000000000000000000000000000000000000..09d0ed575b738aeafb2f2418dfc1a0af11b1d6f5 --- /dev/null +++ b/include/dt-bindings/power/r8a77995-sysc.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2017 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ +#ifndef __DT_BINDINGS_POWER_R8A77995_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A77995_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A77995_PD_CA53_CPU0 5 +#define R8A77995_PD_CA53_SCU 21 + +/* Always-on power area */ +#define R8A77995_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_R8A77995_SYSC_H__ */ diff --git a/include/dt-bindings/power/rk3366-power.h b/include/dt-bindings/power/rk3366-power.h new file mode 100644 index 0000000000000000000000000000000000000000..223a3dce049a1d7d04929ae1f86befbc30d9135c --- /dev/null +++ b/include/dt-bindings/power/rk3366-power.h @@ -0,0 +1,24 @@ +#ifndef __DT_BINDINGS_POWER_RK3366_POWER_H__ +#define __DT_BINDINGS_POWER_RK3366_POWER_H__ + +/* VD_CORE */ +#define RK3366_PD_A53_0 0 +#define RK3366_PD_A53_1 1 +#define RK3366_PD_A53_2 2 +#define RK3366_PD_A53_3 3 + +/* VD_LOGIC */ +#define RK3366_PD_BUS 4 +#define RK3366_PD_PERI 5 +#define RK3366_PD_VIO 6 +#define RK3366_PD_VIDEO 7 +#define RK3366_PD_RKVDEC 8 +#define RK3366_PD_WIFIBT 9 +#define RK3366_PD_VPU 10 +#define RK3366_PD_GPU 11 +#define RK3366_PD_ALIVE 12 + +/* VD_PMU */ +#define RK3366_PD_PMU 13 + +#endif diff --git a/include/dt-bindings/reset/amlogic,meson8b-clkc-reset.h b/include/dt-bindings/reset/amlogic,meson8b-clkc-reset.h new file mode 100644 index 0000000000000000000000000000000000000000..1f1b56e57346e3b939a4597b9242d2aacbcbc33d --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson8b-clkc-reset.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 Martin Blumenstingl . + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +#ifndef _DT_BINDINGS_AMLOGIC_MESON8B_CLKC_RESET_H +#define _DT_BINDINGS_AMLOGIC_MESON8B_CLKC_RESET_H + +#define CLKC_RESET_L2_CACHE_SOFT_RESET 0 +#define CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET 1 +#define CLKC_RESET_SCU_SOFT_RESET 2 +#define CLKC_RESET_CPU0_SOFT_RESET 3 +#define CLKC_RESET_CPU1_SOFT_RESET 4 +#define CLKC_RESET_CPU2_SOFT_RESET 5 +#define CLKC_RESET_CPU3_SOFT_RESET 6 +#define CLKC_RESET_A5_GLOBAL_RESET 7 +#define CLKC_RESET_A5_AXI_SOFT_RESET 8 +#define CLKC_RESET_A5_ABP_SOFT_RESET 9 +#define CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET 10 +#define CLKC_RESET_VID_CLK_CNTL_SOFT_RESET 11 +#define CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST 12 +#define CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE 13 +#define CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST 14 +#define CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE 15 + +#endif /* _DT_BINDINGS_AMLOGIC_MESON8B_CLKC_RESET_H */ diff --git a/include/dt-bindings/reset/snps,hsdk-reset.h b/include/dt-bindings/reset/snps,hsdk-reset.h new file mode 100644 index 0000000000000000000000000000000000000000..e1a643e4bc9152ac397552e5548dfffbaad702b4 --- /dev/null +++ b/include/dt-bindings/reset/snps,hsdk-reset.h @@ -0,0 +1,17 @@ +/** + * This header provides index for the HSDK reset controller. + */ +#ifndef _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK +#define _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK + +#define HSDK_APB_RESET 0 +#define HSDK_AXI_RESET 1 +#define HSDK_ETH_RESET 2 +#define HSDK_USB_RESET 3 +#define HSDK_SDIO_RESET 4 +#define HSDK_HDMI_RESET 5 +#define HSDK_GFX_RESET 6 +#define HSDK_DMAC_RESET 7 +#define HSDK_EBI_RESET 8 + +#endif /*_DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK*/ diff --git a/include/dt-bindings/reset/sun4i-a10-ccu.h b/include/dt-bindings/reset/sun4i-a10-ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..5f4480bedc8a201d5370c80b1b0a7d6a213a2f3e --- /dev/null +++ b/include/dt-bindings/reset/sun4i-a10-ccu.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017 Priit Laes + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_RST_SUN4I_A10_H +#define _DT_BINDINGS_RST_SUN4I_A10_H + +#define RST_USB_PHY0 1 +#define RST_USB_PHY1 2 +#define RST_USB_PHY2 3 +#define RST_GPS 4 +#define RST_DE_BE0 5 +#define RST_DE_BE1 6 +#define RST_DE_FE0 7 +#define RST_DE_FE1 8 +#define RST_DE_MP 9 +#define RST_TVE0 10 +#define RST_TCON0 11 +#define RST_TVE1 12 +#define RST_TCON1 13 +#define RST_CSI0 14 +#define RST_CSI1 15 +#define RST_VE 16 +#define RST_ACE 17 +#define RST_LVDS 18 +#define RST_GPU 19 +#define RST_HDMI_H 20 +#define RST_HDMI_SYS 21 +#define RST_HDMI_AUDIO_DMA 22 + +#endif /* DT_BINDINGS_RST_SUN4I_A10_H */ diff --git a/include/dt-bindings/reset/sun8i-r40-ccu.h b/include/dt-bindings/reset/sun8i-r40-ccu.h new file mode 100644 index 0000000000000000000000000000000000000000..c5ebcf6672e44c620c25873bd6a35962245bf2ee --- /dev/null +++ b/include/dt-bindings/reset/sun8i-r40-ccu.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_RST_SUN8I_R40_H_ +#define _DT_BINDINGS_RST_SUN8I_R40_H_ + +#define RST_USB_PHY0 0 +#define RST_USB_PHY1 1 +#define RST_USB_PHY2 2 + +#define RST_DRAM 3 +#define RST_MBUS 4 + +#define RST_BUS_MIPI_DSI 5 +#define RST_BUS_CE 6 +#define RST_BUS_DMA 7 +#define RST_BUS_MMC0 8 +#define RST_BUS_MMC1 9 +#define RST_BUS_MMC2 10 +#define RST_BUS_MMC3 11 +#define RST_BUS_NAND 12 +#define RST_BUS_DRAM 13 +#define RST_BUS_EMAC 14 +#define RST_BUS_TS 15 +#define RST_BUS_HSTIMER 16 +#define RST_BUS_SPI0 17 +#define RST_BUS_SPI1 18 +#define RST_BUS_SPI2 19 +#define RST_BUS_SPI3 20 +#define RST_BUS_SATA 21 +#define RST_BUS_OTG 22 +#define RST_BUS_EHCI0 23 +#define RST_BUS_EHCI1 24 +#define RST_BUS_EHCI2 25 +#define RST_BUS_OHCI0 26 +#define RST_BUS_OHCI1 27 +#define RST_BUS_OHCI2 28 +#define RST_BUS_VE 29 +#define RST_BUS_MP 30 +#define RST_BUS_DEINTERLACE 31 +#define RST_BUS_CSI0 32 +#define RST_BUS_CSI1 33 +#define RST_BUS_HDMI0 34 +#define RST_BUS_HDMI1 35 +#define RST_BUS_DE 36 +#define RST_BUS_TVE0 37 +#define RST_BUS_TVE1 38 +#define RST_BUS_TVE_TOP 39 +#define RST_BUS_GMAC 40 +#define RST_BUS_GPU 41 +#define RST_BUS_TVD0 42 +#define RST_BUS_TVD1 43 +#define RST_BUS_TVD2 44 +#define RST_BUS_TVD3 45 +#define RST_BUS_TVD_TOP 46 +#define RST_BUS_TCON_LCD0 47 +#define RST_BUS_TCON_LCD1 48 +#define RST_BUS_TCON_TV0 49 +#define RST_BUS_TCON_TV1 50 +#define RST_BUS_TCON_TOP 51 +#define RST_BUS_DBG 52 +#define RST_BUS_LVDS 53 +#define RST_BUS_CODEC 54 +#define RST_BUS_SPDIF 55 +#define RST_BUS_AC97 56 +#define RST_BUS_IR0 57 +#define RST_BUS_IR1 58 +#define RST_BUS_THS 59 +#define RST_BUS_KEYPAD 60 +#define RST_BUS_I2S0 61 +#define RST_BUS_I2S1 62 +#define RST_BUS_I2S2 63 +#define RST_BUS_I2C0 64 +#define RST_BUS_I2C1 65 +#define RST_BUS_I2C2 66 +#define RST_BUS_I2C3 67 +#define RST_BUS_CAN 68 +#define RST_BUS_SCR 69 +#define RST_BUS_PS20 70 +#define RST_BUS_PS21 71 +#define RST_BUS_I2C4 72 +#define RST_BUS_UART0 73 +#define RST_BUS_UART1 74 +#define RST_BUS_UART2 75 +#define RST_BUS_UART3 76 +#define RST_BUS_UART4 77 +#define RST_BUS_UART5 78 +#define RST_BUS_UART6 79 +#define RST_BUS_UART7 80 + +#endif /* _DT_BINDINGS_RST_SUN8I_R40_H_ */ diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h index 5de0673f333b7ca86df00a3f930d5d7005560e53..8cf829dbf20ecac6e5fb5d683cbd4c88b8331b13 100644 --- a/include/keys/rxrpc-type.h +++ b/include/keys/rxrpc-type.h @@ -127,4 +127,27 @@ struct rxrpc_key_data_v1 { #define AFSTOKEN_K5_ADDRESSES_MAX 16 /* max K5 addresses */ #define AFSTOKEN_K5_AUTHDATA_MAX 16 /* max K5 pieces of auth data */ +/* + * Truncate a time64_t to the range from 1970 to 2106 as in the network + * protocol. + */ +static inline u32 rxrpc_time64_to_u32(time64_t time) +{ + if (time < 0) + return 0; + + if (time > UINT_MAX) + return UINT_MAX; + + return (u32)time; +} + +/* + * Extend u32 back to time64_t using the same 1970-2106 range. + */ +static inline time64_t rxrpc_u32_to_time64(u32 time) +{ + return (time64_t)time; +} + #endif /* _KEYS_RXRPC_TYPE_H */ diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index f6e030617467f4d98d0727d480ea3d5d1ac7a0bc..f87fe20fcb052eeb63e4879a03478ad9b5bf8e7b 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -48,7 +48,6 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu); void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu); void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val); -void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu); bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu); @@ -86,7 +85,6 @@ static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {} static inline void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) {} static inline void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val) {} static inline void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val) {} -static inline void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val) {} static inline void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu) {} static inline void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) {} static inline bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index c749eef1daa1557910ec81c5f296dc907f5ccab2..502af53ec0124e1c878ffa297f188c67a79c8d0e 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -57,9 +57,6 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) acpi_fwnode_handle(adev) : NULL) #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) - -extern const struct fwnode_operations acpi_fwnode_ops; - static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) { struct fwnode_handle *fwnode; @@ -68,15 +65,14 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) if (!fwnode) return NULL; - fwnode->type = FWNODE_ACPI_STATIC; - fwnode->ops = &acpi_fwnode_ops; + fwnode->ops = &acpi_static_fwnode_ops; return fwnode; } static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode) { - if (WARN_ON(!fwnode || fwnode->type != FWNODE_ACPI_STATIC)) + if (WARN_ON(!is_acpi_static_node(fwnode))) return; kfree(fwnode); @@ -228,8 +224,8 @@ struct acpi_subtable_proc { int count; }; -char * __acpi_map_table (unsigned long phys_addr, unsigned long size); -void __acpi_unmap_table(char *map, unsigned long size); +void __iomem *__acpi_map_table(unsigned long phys, unsigned long size); +void __acpi_unmap_table(void __iomem *map, unsigned long size); int early_acpi_boot_init(void); int acpi_boot_init (void); void acpi_boot_table_init (void); @@ -427,6 +423,8 @@ void acpi_dev_free_resource_list(struct list_head *list); int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, int (*preproc)(struct acpi_resource *, void *), void *preproc_data); +int acpi_dev_get_dma_resources(struct acpi_device *adev, + struct list_head *list); int acpi_dev_filter_resource_type(struct acpi_resource *ares, unsigned long types); @@ -556,6 +554,25 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, #define ACPI_OST_SC_DRIVER_LOAD_FAILURE 0x81 #define ACPI_OST_SC_INSERT_NOT_SUPPORTED 0x82 +enum acpi_predicate { + all_versions, + less_than_or_equal, + equal, + greater_than_or_equal, +}; + +/* Table must be terminted by a NULL entry */ +struct acpi_platform_list { + char oem_id[ACPI_OEM_ID_SIZE+1]; + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE+1]; + u32 oem_revision; + char *table; + enum acpi_predicate pred; + char *reason; + u32 data; +}; +int acpi_match_platform_list(const struct acpi_platform_list *plat); + extern void acpi_early_init(void); extern void acpi_subsystem_init(void); @@ -774,6 +791,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev) return DEV_DMA_NOT_SUPPORTED; } +static inline int acpi_dma_get_range(struct device *dev, u64 *dma_addr, + u64 *offset, u64 *size) +{ + return -ENODEV; +} + static inline int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr) { @@ -1007,13 +1030,14 @@ struct acpi_reference_args { }; #ifdef CONFIG_ACPI -int acpi_dev_get_property(struct acpi_device *adev, const char *name, +int acpi_dev_get_property(const struct acpi_device *adev, const char *name, acpi_object_type type, const union acpi_object **obj); -int __acpi_node_get_property_reference(struct fwnode_handle *fwnode, +int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, const char *name, size_t index, size_t num_args, struct acpi_reference_args *args); -static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, +static inline int acpi_node_get_property_reference( + const struct fwnode_handle *fwnode, const char *name, size_t index, struct acpi_reference_args *args) { @@ -1021,22 +1045,25 @@ static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, MAX_ACPI_REFERENCE_ARGS, args); } -int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, +int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname, void **valptr); -int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, - enum dev_prop_type proptype, void *val); -int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, - enum dev_prop_type proptype, void *val, size_t nval); -int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, +int acpi_dev_prop_read_single(struct acpi_device *adev, + const char *propname, enum dev_prop_type proptype, + void *val); +int acpi_node_prop_read(const struct fwnode_handle *fwnode, + const char *propname, enum dev_prop_type proptype, + void *val, size_t nval); +int acpi_dev_prop_read(const struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val, size_t nval); -struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode, +struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, struct fwnode_handle *child); -struct fwnode_handle *acpi_node_get_parent(struct fwnode_handle *fwnode); +struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode); -struct fwnode_handle *acpi_graph_get_next_endpoint(struct fwnode_handle *fwnode, - struct fwnode_handle *prev); -int acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode, +struct fwnode_handle * +acpi_graph_get_next_endpoint(const struct fwnode_handle *fwnode, + struct fwnode_handle *prev); +int acpi_graph_get_remote_endpoint(const struct fwnode_handle *fwnode, struct fwnode_handle **remote, struct fwnode_handle **port, struct fwnode_handle **endpoint); @@ -1104,35 +1131,36 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, } static inline int -__acpi_node_get_property_reference(struct fwnode_handle *fwnode, +__acpi_node_get_property_reference(const struct fwnode_handle *fwnode, const char *name, size_t index, size_t num_args, struct acpi_reference_args *args) { return -ENXIO; } -static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, - const char *name, size_t index, - struct acpi_reference_args *args) +static inline int +acpi_node_get_property_reference(const struct fwnode_handle *fwnode, + const char *name, size_t index, + struct acpi_reference_args *args) { return -ENXIO; } -static inline int acpi_node_prop_get(struct fwnode_handle *fwnode, +static inline int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname, void **valptr) { return -ENXIO; } -static inline int acpi_dev_prop_get(struct acpi_device *adev, +static inline int acpi_dev_prop_get(const struct acpi_device *adev, const char *propname, void **valptr) { return -ENXIO; } -static inline int acpi_dev_prop_read_single(struct acpi_device *adev, +static inline int acpi_dev_prop_read_single(const struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val) @@ -1140,7 +1168,7 @@ static inline int acpi_dev_prop_read_single(struct acpi_device *adev, return -ENXIO; } -static inline int acpi_node_prop_read(struct fwnode_handle *fwnode, +static inline int acpi_node_prop_read(const struct fwnode_handle *fwnode, const char *propname, enum dev_prop_type proptype, void *val, size_t nval) @@ -1148,7 +1176,7 @@ static inline int acpi_node_prop_read(struct fwnode_handle *fwnode, return -ENXIO; } -static inline int acpi_dev_prop_read(struct acpi_device *adev, +static inline int acpi_dev_prop_read(const struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val, size_t nval) @@ -1157,26 +1185,27 @@ static inline int acpi_dev_prop_read(struct acpi_device *adev, } static inline struct fwnode_handle * -acpi_get_next_subnode(struct fwnode_handle *fwnode, struct fwnode_handle *child) +acpi_get_next_subnode(const struct fwnode_handle *fwnode, + struct fwnode_handle *child) { return NULL; } static inline struct fwnode_handle * -acpi_node_get_parent(struct fwnode_handle *fwnode) +acpi_node_get_parent(const struct fwnode_handle *fwnode) { return NULL; } static inline struct fwnode_handle * -acpi_graph_get_next_endpoint(struct fwnode_handle *fwnode, +acpi_graph_get_next_endpoint(const struct fwnode_handle *fwnode, struct fwnode_handle *prev) { return ERR_PTR(-ENXIO); } static inline int -acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode, +acpi_graph_get_remote_endpoint(const struct fwnode_handle *fwnode, struct fwnode_handle **remote, struct fwnode_handle **port, struct fwnode_handle **endpoint) @@ -1209,6 +1238,7 @@ static inline bool acpi_has_watchdog(void) { return false; } #endif #ifdef CONFIG_ACPI_SPCR_TABLE +extern bool qdf2400_e44_present; int parse_spcr(bool earlycon); #else static inline int parse_spcr(bool earlycon) { return 0; } diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h index 8379d406ad2e7c20493852739456434cd456c094..8d3f0bf80379a1ee3fcb84d56c8dffaea62b4811 100644 --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -36,7 +36,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id); void acpi_configure_pmsi_domain(struct device *dev); int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); /* IOMMU interface */ -void iort_set_dma_mask(struct device *dev); +void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size); const struct iommu_ops *iort_iommu_configure(struct device *dev); #else static inline void acpi_iort_init(void) { } @@ -47,7 +47,8 @@ static inline struct irq_domain *iort_get_device_domain(struct device *dev, { return NULL; } static inline void acpi_configure_pmsi_domain(struct device *dev) { } /* IOMMU interface */ -static inline void iort_set_dma_mask(struct device *dev) { } +static inline void iort_dma_setup(struct device *dev, u64 *dma_addr, + u64 *size) { } static inline const struct iommu_ops *iort_iommu_configure(struct device *dev) { return NULL; } diff --git a/include/linux/aer.h b/include/linux/aer.h index 04602cbe85dcf324bd433a7b93a1e8c6e1f91cbe..43799bd17a0257dce95d79287e3a30ecbf525399 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -39,7 +39,7 @@ struct aer_capability_regs { }; #if defined(CONFIG_PCIEAER) -/* pci-e port driver needs this function to enable aer */ +/* PCIe port driver needs this function to enable AER */ int pci_enable_pcie_error_reporting(struct pci_dev *dev); int pci_disable_pcie_error_reporting(struct pci_dev *dev); int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); @@ -67,7 +67,6 @@ void cper_print_aer(struct pci_dev *dev, int aer_severity, struct aer_capability_regs *aer); int cper_severity_to_aer(int cper_severity); void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity, - struct aer_capability_regs *aer_regs); + int severity, struct aer_capability_regs *aer_regs); #endif //_AER_H_ diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index a270f25ee7c7c49890e2b902ceaccd80a5a05aa2..1b0a17b22cd3c8e224a7d3dd1fdaa155830ac49a 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -36,6 +36,8 @@ int ahci_platform_init_host(struct platform_device *pdev, const struct ata_port_info *pi_template, struct scsi_host_template *sht); +void ahci_platform_shutdown(struct platform_device *pdev); + int ahci_platform_suspend_host(struct device *dev); int ahci_platform_resume_host(struct device *dev); int ahci_platform_suspend(struct device *dev); diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h index 9af3c174c03aa543dd3ced0905cc6cdb3b662c92..716ce587247e0b2b503969ee1ca2f1c090942eaa 100644 --- a/include/linux/arch_topology.h +++ b/include/linux/arch_topology.h @@ -4,10 +4,12 @@ #ifndef _LINUX_ARCH_TOPOLOGY_H_ #define _LINUX_ARCH_TOPOLOGY_H_ +#include + void topology_normalize_cpu_scale(void); struct device_node; -int topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu); +bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu); struct sched_domain; unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu); diff --git a/include/linux/ata.h b/include/linux/ata.h index e65ae4b2ed485a67a26d7c45d542a76d70ab9d97..c7a353825450a950a2f53f93774ef4c5bce934a0 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -60,7 +60,8 @@ enum { ATA_ID_FW_REV = 23, ATA_ID_PROD = 27, ATA_ID_MAX_MULTSECT = 47, - ATA_ID_DWORD_IO = 48, + ATA_ID_DWORD_IO = 48, /* before ATA-8 */ + ATA_ID_TRUSTED = 48, /* ATA-8 and later */ ATA_ID_CAPABILITY = 49, ATA_ID_OLD_PIO_MODES = 51, ATA_ID_OLD_DMA_MODES = 52, @@ -889,6 +890,13 @@ static inline bool ata_id_has_dword_io(const u16 *id) return id[ATA_ID_DWORD_IO] & (1 << 0); } +static inline bool ata_id_has_trusted(const u16 *id) +{ + if (ata_id_major_version(id) <= 7) + return false; + return id[ATA_ID_TRUSTED] & (1 << 0); +} + static inline bool ata_id_has_unload(const u16 *id) { if (ata_id_major_version(id) >= 7 && diff --git a/include/linux/atomic.h b/include/linux/atomic.h index c56be74101305f74524bc816d9c8fdb67ccb895d..40d6bfec0e0d0fb8ef40de6a6bb37a9d1905cf93 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -38,6 +38,9 @@ * Besides, if an arch has a special barrier for acquire/release, it could * implement its own __atomic_op_* and use the same framework for building * variants + * + * If an architecture overrides __atomic_op_acquire() it will probably want + * to define smp_mb__after_spinlock(). */ #ifndef __atomic_op_acquire #define __atomic_op_acquire(op, args...) \ diff --git a/include/linux/audit.h b/include/linux/audit.h index 2150bdccfbab2953c33cd56d6d64eb798ca180ea..cb708eb8accc59d3dafee57c7c696647e80be471 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -314,11 +314,7 @@ void audit_core_dumps(long signr); static inline void audit_seccomp(unsigned long syscall, long signr, int code) { - if (!audit_enabled) - return; - - /* Force a record to be reported if a signal was delivered. */ - if (signr || unlikely(!audit_dummy_context())) + if (audit_enabled && unlikely(!audit_dummy_context())) __audit_seccomp(syscall, signr, code); } @@ -351,7 +347,7 @@ extern int __audit_socketcall(int nargs, unsigned long *args); extern int __audit_sockaddr(int len, void *addr); extern void __audit_fd_pair(int fd1, int fd2); extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr); -extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); +extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout); extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification); extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, @@ -412,7 +408,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr) if (unlikely(!audit_dummy_context())) __audit_mq_open(oflag, mode, attr); } -static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout) +static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout) { if (unlikely(!audit_dummy_context())) __audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout); @@ -549,7 +545,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr) { } static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, - const struct timespec *abs_timeout) + const struct timespec64 *abs_timeout) { } static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification) diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h index c893b9520a67b559fd32e0aa2df7d7c9965e841a..2b038442c352adc1b716b3634c683f2b71e9fbb7 100644 --- a/include/linux/avf/virtchnl.h +++ b/include/linux/avf/virtchnl.h @@ -133,6 +133,8 @@ enum virtchnl_ops { VIRTCHNL_OP_CONFIG_RSS_LUT = 24, VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25, VIRTCHNL_OP_SET_RSS_HENA = 26, + VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27, + VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28, }; /* This macro is used to generate a compilation error if a structure @@ -223,7 +225,7 @@ struct virtchnl_vsi_resource { VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource); -/* VF offload flags +/* VF capability flags * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including * TX/RX Checksum offloading and TSO for non-tunnelled packets. */ @@ -251,7 +253,7 @@ struct virtchnl_vf_resource { u16 max_vectors; u16 max_mtu; - u32 vf_offload_flags; + u32 vf_cap_flags; u32 rss_key_size; u32 rss_lut_size; @@ -686,6 +688,9 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, case VIRTCHNL_OP_SET_RSS_HENA: valid_len = sizeof(struct virtchnl_rss_hena); break; + case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: + case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING: + break; /* These are always errors coming from the VF. */ case VIRTCHNL_OP_EVENT: case VIRTCHNL_OP_UNKNOWN: diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 3ae9013eeaaa4367bb160aef88b36ab549b0446d..18d05b5491f3442a886630439b4e2ca592898c76 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -25,11 +25,25 @@ struct linux_binprm { struct mm_struct *mm; unsigned long p; /* current top of mem */ unsigned int - cred_prepared:1,/* true if creds already prepared (multiple - * preps happen for interpreters) */ - cap_effective:1;/* true if has elevated effective capabilities, - * false if not; except for init which inherits - * its parent's caps anyway */ + /* + * True after the bprm_set_creds hook has been called once + * (multiple calls can be made via prepare_binprm() for + * binfmt_script/misc). + */ + called_set_creds:1, + /* + * True if most recent call to the commoncaps bprm_set_creds + * hook (due to multiple prepare_binprm() calls from the + * binfmt_script/misc handlers) resulted in elevated + * privileges. + */ + cap_elevated:1, + /* + * Set by bprm_set_creds hook to indicate a privilege-gaining + * exec has happened. Used to sanitize execution environment + * and to set AT_SECURE auxv for glibc. + */ + secureexec:1; #ifdef __alpha__ unsigned int taso:1; #endif @@ -117,7 +131,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm, int executable_stack); extern int transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *sp_location); -extern int bprm_change_interp(char *interp, struct linux_binprm *bprm); +extern int bprm_change_interp(const char *interp, struct linux_binprm *bprm); extern int copy_strings_kernel(int argc, const char *const *argv, struct linux_binprm *bprm); extern int prepare_bprm_creds(struct linux_binprm *bprm); diff --git a/include/linux/bio.h b/include/linux/bio.h index 7b1cf4ba090291af59e904dc1c59d8196ab88d3d..275c91c9951633282980cb3510c700322ff1e657 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -38,7 +38,15 @@ #define BIO_BUG_ON #endif +#ifdef CONFIG_THP_SWAP +#if HPAGE_PMD_NR > 256 +#define BIO_MAX_PAGES HPAGE_PMD_NR +#else #define BIO_MAX_PAGES 256 +#endif +#else +#define BIO_MAX_PAGES 256 +#endif #define bio_prio(bio) (bio)->bi_ioprio #define bio_set_prio(bio, prio) ((bio)->bi_ioprio = prio) @@ -463,10 +471,11 @@ extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int, extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); -void generic_start_io_acct(int rw, unsigned long sectors, - struct hd_struct *part); -void generic_end_io_acct(int rw, struct hd_struct *part, - unsigned long start_time); +void generic_start_io_acct(struct request_queue *q, int rw, + unsigned long sectors, struct hd_struct *part); +void generic_end_io_acct(struct request_queue *q, int rw, + struct hd_struct *part, + unsigned long start_time); #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE # error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform" @@ -493,6 +502,24 @@ extern struct bio_vec *bvec_alloc(gfp_t, int, unsigned long *, mempool_t *); extern void bvec_free(mempool_t *, struct bio_vec *, unsigned int); extern unsigned int bvec_nr_vecs(unsigned short idx); +#define bio_set_dev(bio, bdev) \ +do { \ + (bio)->bi_disk = (bdev)->bd_disk; \ + (bio)->bi_partno = (bdev)->bd_partno; \ +} while (0) + +#define bio_copy_dev(dst, src) \ +do { \ + (dst)->bi_disk = (src)->bi_disk; \ + (dst)->bi_partno = (src)->bi_partno; \ +} while (0) + +#define bio_dev(bio) \ + disk_devt((bio)->bi_disk) + +#define bio_devname(bio, buf) \ + __bdevname(bio_dev(bio), (buf)) + #ifdef CONFIG_BLK_CGROUP int bio_associate_blkcg(struct bio *bio, struct cgroup_subsys_state *blkcg_css); int bio_associate_current(struct bio *bio); diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 8b9d6fff002db113cb2233a2d80b3186ff041ef0..f2deb71958b2dbee591c4c9bf95ee6f1e70f41c4 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -92,7 +92,7 @@ /** * FIELD_GET() - extract a bitfield element * @_mask: shifted mask defining the field's length and position - * @_reg: 32bit value of entire bitfield + * @_reg: value of entire bitfield * * FIELD_GET() extracts the field specified by @_mask from the * bitfield passed in as @_reg by masking and shifting it down. diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 5797ca6fdfe2e658bbfeb225e05b0b8cbe45d40d..700cf5f67118504d85def31a2be37c7c7b117ce3 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -360,6 +360,38 @@ static inline int bitmap_parse(const char *buf, unsigned int buflen, return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits); } +/* + * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap. + * + * Linux bitmaps are internally arrays of unsigned longs, i.e. 32-bit + * integers in 32-bit environment, and 64-bit integers in 64-bit one. + * + * There are four combinations of endianness and length of the word in linux + * ABIs: LE64, BE64, LE32 and BE32. + * + * On 64-bit kernels 64-bit LE and BE numbers are naturally ordered in + * bitmaps and therefore don't require any special handling. + * + * On 32-bit kernels 32-bit LE ABI orders lo word of 64-bit number in memory + * prior to hi, and 32-bit BE orders hi word prior to lo. The bitmap on the + * other hand is represented as an array of 32-bit words and the position of + * bit N may therefore be calculated as: word #(N/32) and bit #(N%32) in that + * word. For example, bit #42 is located at 10th position of 2nd word. + * It matches 32-bit LE ABI, and we can simply let the compiler store 64-bit + * values in memory as it usually does. But for BE we need to swap hi and lo + * words manually. + * + * With all that, the macro BITMAP_FROM_U64() does explicit reordering of hi and + * lo parts of u64. For LE32 it does nothing, and for BE environment it swaps + * hi and lo words, as is expected by bitmap. + */ +#if __BITS_PER_LONG == 64 +#define BITMAP_FROM_U64(n) (n) +#else +#define BITMAP_FROM_U64(n) ((unsigned long) ((u64)(n) & ULONG_MAX)), \ + ((unsigned long) ((u64)(n) >> 32)) +#endif + /* * bitmap_from_u64 - Check and swap words within u64. * @mask: source bitmap diff --git a/include/linux/bitops.h b/include/linux/bitops.h index a83c822c35c2424095b512dd04f95609cadfdaa0..8fbe259b197c987a56190328997aa8ded227c067 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -19,10 +19,11 @@ * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ #define GENMASK(h, l) \ - (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) #define GENMASK_ULL(h, l) \ - (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + (((~0ULL) - (1ULL << (l)) + 1) & \ + (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) extern unsigned int __sw_hweight8(unsigned int w); extern unsigned int __sw_hweight16(unsigned int w); diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h index fb790b8449c1ffba36c740f3001777fa973a11d4..b97be27e5a85c9901724a20daef32aa8da4c73be 100644 --- a/include/linux/bitrev.h +++ b/include/linux/bitrev.h @@ -29,6 +29,8 @@ static inline u32 __bitrev32(u32 x) #endif /* CONFIG_HAVE_ARCH_BITREVERSE */ +#define __bitrev8x4(x) (__bitrev32(swab32(x))) + #define __constant_bitrev32(x) \ ({ \ u32 __x = x; \ @@ -50,6 +52,15 @@ static inline u32 __bitrev32(u32 x) __x; \ }) +#define __constant_bitrev8x4(x) \ +({ \ + u32 __x = x; \ + __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \ + __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \ + __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \ + __x; \ +}) + #define __constant_bitrev8(x) \ ({ \ u8 __x = x; \ @@ -75,6 +86,14 @@ static inline u32 __bitrev32(u32 x) __bitrev16(__x); \ }) +#define bitrev8x4(x) \ +({ \ + u32 __x = x; \ + __builtin_constant_p(__x) ? \ + __constant_bitrev8x4(__x) : \ + __bitrev8x4(__x); \ + }) + #define bitrev8(x) \ ({ \ u8 __x = x; \ diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h index 7104bea8dab1c9895ccc916c5d90912fb41db77e..9d92153dd856f49eb927271e493a4416a2ea15a7 100644 --- a/include/linux/blk-cgroup.h +++ b/include/linux/blk-cgroup.h @@ -691,6 +691,9 @@ static inline bool blkcg_bio_issue_check(struct request_queue *q, rcu_read_lock(); blkcg = bio_blkcg(bio); + /* associate blkcg if bio hasn't attached one */ + bio_associate_blkcg(bio, &blkcg->css); + blkg = blkg_lookup(blkcg, q); if (unlikely(!blkg)) { spin_lock_irq(q->queue_lock); diff --git a/include/linux/blk-mq-rdma.h b/include/linux/blk-mq-rdma.h new file mode 100644 index 0000000000000000000000000000000000000000..b4ade198007db59713b989cf180fb69041be0999 --- /dev/null +++ b/include/linux/blk-mq-rdma.h @@ -0,0 +1,10 @@ +#ifndef _LINUX_BLK_MQ_RDMA_H +#define _LINUX_BLK_MQ_RDMA_H + +struct blk_mq_tag_set; +struct ib_device; + +int blk_mq_rdma_map_queues(struct blk_mq_tag_set *set, + struct ib_device *dev, int first_vec); + +#endif /* _LINUX_BLK_MQ_RDMA_H */ diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 14542308d25bd90dd2c1ac5d7a6c283a86bbd0ba..50c6485cb04f5d4f306ef794758e280113b5756a 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -97,7 +97,6 @@ typedef int (init_request_fn)(struct blk_mq_tag_set *set, struct request *, unsigned int, unsigned int); typedef void (exit_request_fn)(struct blk_mq_tag_set *set, struct request *, unsigned int); -typedef int (reinit_request_fn)(void *, struct request *); typedef void (busy_iter_fn)(struct blk_mq_hw_ctx *, struct request *, void *, bool); @@ -143,7 +142,6 @@ struct blk_mq_ops { */ init_request_fn *init_request; exit_request_fn *exit_request; - reinit_request_fn *reinit_request; /* Called from inside blk_get_request() */ void (*initialize_rq_fn)(struct request *rq); @@ -261,7 +259,8 @@ void blk_freeze_queue_start(struct request_queue *q); void blk_mq_freeze_queue_wait(struct request_queue *q); int blk_mq_freeze_queue_wait_timeout(struct request_queue *q, unsigned long timeout); -int blk_mq_reinit_tagset(struct blk_mq_tag_set *set); +int blk_mq_reinit_tagset(struct blk_mq_tag_set *set, + int (reinit_request)(void *, struct request *)); int blk_mq_map_queues(struct blk_mq_tag_set *set); void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues); diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index d2eb87c84d82b7eb737d9f8a4e052d687a2dca2e..a2d2aa709cef4afc0bb5c3875df3073b81b368fa 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -48,7 +48,8 @@ struct blk_issue_stat { */ struct bio { struct bio *bi_next; /* request queue link */ - struct block_device *bi_bdev; + struct gendisk *bi_disk; + u8 bi_partno; blk_status_t bi_status; unsigned int bi_opf; /* bottom bits req flags, * top bits REQ_OP. Use diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 25f6a0cb27d3e9644c1ef42e7f1ff2b5d817293d..02fa42d24b52f5632500e2dd530a3b16be1f38d8 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -134,7 +134,7 @@ typedef __u32 __bitwise req_flags_t; struct request { struct list_head queuelist; union { - struct call_single_data csd; + call_single_data_t csd; u64 fifo_time; }; @@ -551,6 +551,7 @@ struct request_queue { int node; #ifdef CONFIG_BLK_DEV_IO_TRACE struct blk_trace *blk_trace; + struct mutex blk_trace_mutex; #endif /* * for flush operations @@ -568,7 +569,6 @@ struct request_queue { #if defined(CONFIG_BLK_DEV_BSG) bsg_job_fn *bsg_job_fn; - int bsg_job_size; struct bsg_class_device bsg_dev; #endif @@ -601,38 +601,36 @@ struct request_queue { u64 write_hints[BLK_MAX_WRITE_HINTS]; }; -#define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ -#define QUEUE_FLAG_STOPPED 2 /* queue is stopped */ -#define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ -#define QUEUE_FLAG_ASYNCFULL 4 /* write queue has been filled */ -#define QUEUE_FLAG_DYING 5 /* queue being torn down */ -#define QUEUE_FLAG_BYPASS 6 /* act as dumb FIFO queue */ -#define QUEUE_FLAG_BIDI 7 /* queue supports bidi requests */ -#define QUEUE_FLAG_NOMERGES 8 /* disable merge attempts */ -#define QUEUE_FLAG_SAME_COMP 9 /* complete on same CPU-group */ -#define QUEUE_FLAG_FAIL_IO 10 /* fake timeout */ -#define QUEUE_FLAG_STACKABLE 11 /* supports request stacking */ -#define QUEUE_FLAG_NONROT 12 /* non-rotational device (SSD) */ +#define QUEUE_FLAG_QUEUED 0 /* uses generic tag queueing */ +#define QUEUE_FLAG_STOPPED 1 /* queue is stopped */ +#define QUEUE_FLAG_DYING 2 /* queue being torn down */ +#define QUEUE_FLAG_BYPASS 3 /* act as dumb FIFO queue */ +#define QUEUE_FLAG_BIDI 4 /* queue supports bidi requests */ +#define QUEUE_FLAG_NOMERGES 5 /* disable merge attempts */ +#define QUEUE_FLAG_SAME_COMP 6 /* complete on same CPU-group */ +#define QUEUE_FLAG_FAIL_IO 7 /* fake timeout */ +#define QUEUE_FLAG_STACKABLE 8 /* supports request stacking */ +#define QUEUE_FLAG_NONROT 9 /* non-rotational device (SSD) */ #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ -#define QUEUE_FLAG_IO_STAT 13 /* do IO stats */ -#define QUEUE_FLAG_DISCARD 14 /* supports DISCARD */ -#define QUEUE_FLAG_NOXMERGES 15 /* No extended merges */ -#define QUEUE_FLAG_ADD_RANDOM 16 /* Contributes to random pool */ -#define QUEUE_FLAG_SECERASE 17 /* supports secure erase */ -#define QUEUE_FLAG_SAME_FORCE 18 /* force complete on same CPU */ -#define QUEUE_FLAG_DEAD 19 /* queue tear-down finished */ -#define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ -#define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ -#define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */ -#define QUEUE_FLAG_WC 23 /* Write back caching */ -#define QUEUE_FLAG_FUA 24 /* device supports FUA writes */ -#define QUEUE_FLAG_FLUSH_NQ 25 /* flush not queueuable */ -#define QUEUE_FLAG_DAX 26 /* device supports DAX */ -#define QUEUE_FLAG_STATS 27 /* track rq completion times */ -#define QUEUE_FLAG_POLL_STATS 28 /* collecting stats for hybrid polling */ -#define QUEUE_FLAG_REGISTERED 29 /* queue has been registered to a disk */ -#define QUEUE_FLAG_SCSI_PASSTHROUGH 30 /* queue supports SCSI commands */ -#define QUEUE_FLAG_QUIESCED 31 /* queue has been quiesced */ +#define QUEUE_FLAG_IO_STAT 10 /* do IO stats */ +#define QUEUE_FLAG_DISCARD 11 /* supports DISCARD */ +#define QUEUE_FLAG_NOXMERGES 12 /* No extended merges */ +#define QUEUE_FLAG_ADD_RANDOM 13 /* Contributes to random pool */ +#define QUEUE_FLAG_SECERASE 14 /* supports secure erase */ +#define QUEUE_FLAG_SAME_FORCE 15 /* force complete on same CPU */ +#define QUEUE_FLAG_DEAD 16 /* queue tear-down finished */ +#define QUEUE_FLAG_INIT_DONE 17 /* queue is initialized */ +#define QUEUE_FLAG_NO_SG_MERGE 18 /* don't attempt to merge SG segments*/ +#define QUEUE_FLAG_POLL 19 /* IO polling enabled if set */ +#define QUEUE_FLAG_WC 20 /* Write back caching */ +#define QUEUE_FLAG_FUA 21 /* device supports FUA writes */ +#define QUEUE_FLAG_FLUSH_NQ 22 /* flush not queueuable */ +#define QUEUE_FLAG_DAX 23 /* device supports DAX */ +#define QUEUE_FLAG_STATS 24 /* track rq completion times */ +#define QUEUE_FLAG_POLL_STATS 25 /* collecting stats for hybrid polling */ +#define QUEUE_FLAG_REGISTERED 26 /* queue has been registered to a disk */ +#define QUEUE_FLAG_SCSI_PASSTHROUGH 27 /* queue supports SCSI commands */ +#define QUEUE_FLAG_QUIESCED 28 /* queue has been quiesced */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_STACKABLE) | \ diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index d2e908586e3d50322025806a61816d1ec1b56ece..67b4d4dfc19c5e6f1e958ca73fc8f463d2a4991c 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -28,10 +28,12 @@ struct blk_trace { atomic_t dropped; }; +struct blkcg; + extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); extern void blk_trace_shutdown(struct request_queue *); -extern __printf(2, 3) -void __trace_note_message(struct blk_trace *, const char *fmt, ...); +extern __printf(3, 4) +void __trace_note_message(struct blk_trace *, struct blkcg *blkcg, const char *fmt, ...); /** * blk_add_trace_msg - Add a (simple) message to the blktrace stream @@ -46,12 +48,14 @@ void __trace_note_message(struct blk_trace *, const char *fmt, ...); * NOTE: Can not use 'static inline' due to presence of var args... * **/ -#define blk_add_trace_msg(q, fmt, ...) \ +#define blk_add_cgroup_trace_msg(q, cg, fmt, ...) \ do { \ struct blk_trace *bt = (q)->blk_trace; \ if (unlikely(bt)) \ - __trace_note_message(bt, fmt, ##__VA_ARGS__); \ + __trace_note_message(bt, cg, fmt, ##__VA_ARGS__);\ } while (0) +#define blk_add_trace_msg(q, fmt, ...) \ + blk_add_cgroup_trace_msg(q, NULL, fmt, ##__VA_ARGS__) #define BLK_TN_MAX_MSG 128 static inline bool blk_trace_note_message_enabled(struct request_queue *q) @@ -82,6 +86,7 @@ extern struct attribute_group blk_trace_attr_group; # define blk_trace_startstop(q, start) (-ENOTTY) # define blk_trace_remove(q) (-ENOTTY) # define blk_add_trace_msg(q, fmt, ...) do { } while (0) +# define blk_add_cgroup_trace_msg(q, cg, fmt, ...) do { } while (0) # define blk_trace_remove_sysfs(dev) do { } while (0) # define blk_trace_note_message_enabled(q) (false) static inline int blk_trace_init_sysfs(struct device *dev) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index b69e7a5869ffb33fcf70ba4486bfe9001d720fd8..8390859e79e70b9a07f0948e1efaa5adbfb0c99c 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -14,8 +14,10 @@ #include #include #include +#include struct perf_event; +struct bpf_prog; struct bpf_map; /* map is generic key/value storage optionally accesible by eBPF programs */ @@ -48,6 +50,7 @@ struct bpf_map { u32 map_flags; u32 pages; u32 id; + int numa_node; struct user_struct *user; const struct bpf_map_ops *ops; struct work_struct work; @@ -117,39 +120,27 @@ enum bpf_access_type { }; /* types of values stored in eBPF registers */ +/* Pointer types represent: + * pointer + * pointer + imm + * pointer + (u16) var + * pointer + (u16) var + imm + * if (range > 0) then [ptr, ptr + range - off) is safe to access + * if (id > 0) means that some 'var' was added + * if (off > 0) means that 'imm' was added + */ enum bpf_reg_type { NOT_INIT = 0, /* nothing was written into register */ - UNKNOWN_VALUE, /* reg doesn't contain a valid pointer */ + SCALAR_VALUE, /* reg doesn't contain a valid pointer */ PTR_TO_CTX, /* reg points to bpf_context */ CONST_PTR_TO_MAP, /* reg points to struct bpf_map */ PTR_TO_MAP_VALUE, /* reg points to map element value */ PTR_TO_MAP_VALUE_OR_NULL,/* points to map elem value or NULL */ - FRAME_PTR, /* reg == frame_pointer */ - PTR_TO_STACK, /* reg == frame_pointer + imm */ - CONST_IMM, /* constant integer value */ - - /* PTR_TO_PACKET represents: - * skb->data - * skb->data + imm - * skb->data + (u16) var - * skb->data + (u16) var + imm - * if (range > 0) then [ptr, ptr + range - off) is safe to access - * if (id > 0) means that some 'var' was added - * if (off > 0) menas that 'imm' was added - */ - PTR_TO_PACKET, + PTR_TO_STACK, /* reg == frame_pointer + offset */ + PTR_TO_PACKET, /* reg points to skb->data */ PTR_TO_PACKET_END, /* skb->data + headlen */ - - /* PTR_TO_MAP_VALUE_ADJ is used for doing pointer math inside of a map - * elem value. We only allow this if we can statically verify that - * access from this register are going to fall within the size of the - * map element. - */ - PTR_TO_MAP_VALUE_ADJ, }; -struct bpf_prog; - /* The information passed from prog-specific *_is_valid_access * back to the verifier. */ @@ -262,6 +253,7 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type); struct bpf_prog * __must_check bpf_prog_add(struct bpf_prog *prog, int i); void bpf_prog_sub(struct bpf_prog *prog, int i); struct bpf_prog * __must_check bpf_prog_inc(struct bpf_prog *prog); +struct bpf_prog * __must_check bpf_prog_inc_not_zero(struct bpf_prog *prog); void bpf_prog_put(struct bpf_prog *prog); int __bpf_prog_charge(struct user_struct *user, u32 pages); void __bpf_prog_uncharge(struct user_struct *user, u32 pages); @@ -272,7 +264,7 @@ struct bpf_map * __must_check bpf_map_inc(struct bpf_map *map, bool uref); void bpf_map_put_with_uref(struct bpf_map *map); void bpf_map_put(struct bpf_map *map); int bpf_map_precharge_memlock(u32 pages); -void *bpf_map_area_alloc(size_t size); +void *bpf_map_area_alloc(size_t size, int numa_node); void bpf_map_area_free(void *base); extern int sysctl_unprivileged_bpf_disabled; @@ -318,6 +310,19 @@ static inline void bpf_long_memcpy(void *dst, const void *src, u32 size) /* verify correctness of eBPF program */ int bpf_check(struct bpf_prog **fp, union bpf_attr *attr); + +/* Map specifics */ +struct net_device *__dev_map_lookup_elem(struct bpf_map *map, u32 key); +void __dev_map_insert_ctx(struct bpf_map *map, u32 index); +void __dev_map_flush(struct bpf_map *map); + +/* Return map's numa specified by userspace */ +static inline int bpf_map_attr_numa_node(const union bpf_attr *attr) +{ + return (attr->map_flags & BPF_F_NUMA_NODE) ? + attr->numa_node : NUMA_NO_NODE; +} + #else static inline struct bpf_prog *bpf_prog_get(u32 ufd) { @@ -348,6 +353,12 @@ static inline struct bpf_prog * __must_check bpf_prog_inc(struct bpf_prog *prog) return ERR_PTR(-EOPNOTSUPP); } +static inline struct bpf_prog *__must_check +bpf_prog_inc_not_zero(struct bpf_prog *prog) +{ + return ERR_PTR(-EOPNOTSUPP); +} + static inline int __bpf_prog_charge(struct user_struct *user, u32 pages) { return 0; @@ -356,8 +367,39 @@ static inline int __bpf_prog_charge(struct user_struct *user, u32 pages) static inline void __bpf_prog_uncharge(struct user_struct *user, u32 pages) { } + +static inline struct net_device *__dev_map_lookup_elem(struct bpf_map *map, + u32 key) +{ + return NULL; +} + +static inline void __dev_map_insert_ctx(struct bpf_map *map, u32 index) +{ +} + +static inline void __dev_map_flush(struct bpf_map *map) +{ +} #endif /* CONFIG_BPF_SYSCALL */ +#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) +struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); +int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); +#else +static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) +{ + return NULL; +} + +static inline int sock_map_prog(struct bpf_map *map, + struct bpf_prog *prog, + u32 type) +{ + return -EOPNOTSUPP; +} +#endif + /* verifier prototypes for helper functions called from eBPF programs */ extern const struct bpf_func_proto bpf_map_lookup_elem_proto; extern const struct bpf_func_proto bpf_map_update_elem_proto; @@ -374,6 +416,7 @@ extern const struct bpf_func_proto bpf_get_current_comm_proto; extern const struct bpf_func_proto bpf_skb_vlan_push_proto; extern const struct bpf_func_proto bpf_skb_vlan_pop_proto; extern const struct bpf_func_proto bpf_get_stackid_proto; +extern const struct bpf_func_proto bpf_sock_map_update_proto; /* Shared helpers among cBPF and eBPF. */ void bpf_user_rnd_init_once(void); diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h index 3d137c33d664a7d2ca3843c0ce8ab8f190e87ebb..6f1a567667b8ba8a2999cb867b61eb7b8e7c2f2f 100644 --- a/include/linux/bpf_types.h +++ b/include/linux/bpf_types.h @@ -11,6 +11,7 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_IN, lwt_inout_prog_ops) BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_OUT, lwt_inout_prog_ops) BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_XMIT, lwt_xmit_prog_ops) BPF_PROG_TYPE(BPF_PROG_TYPE_SOCK_OPS, sock_ops_prog_ops) +BPF_PROG_TYPE(BPF_PROG_TYPE_SK_SKB, sk_skb_prog_ops) #endif #ifdef CONFIG_BPF_EVENTS BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe_prog_ops) @@ -35,3 +36,9 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_STACK_TRACE, stack_map_ops) #endif BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops) +#ifdef CONFIG_NET +BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops) +#ifdef CONFIG_STREAM_PARSER +BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKMAP, sock_map_ops) +#endif +#endif diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 8e5d31f6faefd361cee145be654a968123ae5e6a..b8d200f60a4090882cf125ea28294430dd320242 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -9,41 +9,75 @@ #include /* for enum bpf_reg_type */ #include /* for MAX_BPF_STACK */ +#include - /* Just some arbitrary values so we can safely do math without overflowing and - * are obviously wrong for any sort of memory access. - */ -#define BPF_REGISTER_MAX_RANGE (1024 * 1024 * 1024) -#define BPF_REGISTER_MIN_RANGE -1 +/* Maximum variable offset umax_value permitted when resolving memory accesses. + * In practice this is far bigger than any realistic pointer offset; this limit + * ensures that umax_value + (int)off + (int)size cannot overflow a u64. + */ +#define BPF_MAX_VAR_OFF (1ULL << 31) +/* Maximum variable size permitted for ARG_CONST_SIZE[_OR_ZERO]. This ensures + * that converting umax_value to int cannot overflow. + */ +#define BPF_MAX_VAR_SIZ INT_MAX + +/* Liveness marks, used for registers and spilled-regs (in stack slots). + * Read marks propagate upwards until they find a write mark; they record that + * "one of this state's descendants read this reg" (and therefore the reg is + * relevant for states_equal() checks). + * Write marks collect downwards and do not propagate; they record that "the + * straight-line code that reached this state (from its parent) wrote this reg" + * (and therefore that reads propagated from this state or its descendants + * should not propagate to its parent). + * A state with a write mark can receive read marks; it just won't propagate + * them to its parent, since the write mark is a property, not of the state, + * but of the link between it and its parent. See mark_reg_read() and + * mark_stack_slot_read() in kernel/bpf/verifier.c. + */ +enum bpf_reg_liveness { + REG_LIVE_NONE = 0, /* reg hasn't been read or written this branch */ + REG_LIVE_READ, /* reg was read, so we're sensitive to initial value */ + REG_LIVE_WRITTEN, /* reg was written first, screening off later reads */ +}; struct bpf_reg_state { enum bpf_reg_type type; union { - /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE */ - s64 imm; - - /* valid when type == PTR_TO_PACKET* */ - struct { - u16 off; - u16 range; - }; + /* valid when type == PTR_TO_PACKET */ + u16 range; /* valid when type == CONST_PTR_TO_MAP | PTR_TO_MAP_VALUE | * PTR_TO_MAP_VALUE_OR_NULL */ struct bpf_map *map_ptr; }; + /* Fixed part of pointer offset, pointer types only */ + s32 off; + /* For PTR_TO_PACKET, used to find other pointers with the same variable + * offset, so they can share range knowledge. + * For PTR_TO_MAP_VALUE_OR_NULL this is used to share which map value we + * came from, when one is tested for != NULL. + */ u32 id; + /* Ordering of fields matters. See states_equal() */ + /* For scalar types (SCALAR_VALUE), this represents our knowledge of + * the actual value. + * For pointer types, this represents the variable part of the offset + * from the pointed-to object, and is shared with all bpf_reg_states + * with the same id as us. + */ + struct tnum var_off; /* Used to determine if any memory access using this register will - * result in a bad access. These two fields must be last. - * See states_equal() + * result in a bad access. + * These refer to the same value as var_off, not necessarily the actual + * contents of the register. */ - s64 min_value; - u64 max_value; - u32 min_align; - u32 aux_off; - u32 aux_off_align; - bool value_from_signed; + s64 smin_value; /* minimum possible (s64)value */ + s64 smax_value; /* maximum possible (s64)value */ + u64 umin_value; /* minimum possible (u64)value */ + u64 umax_value; /* maximum possible (u64)value */ + /* This field must be last, for states_equal() reasons. */ + enum bpf_reg_liveness live; }; enum bpf_stack_slot_type { @@ -61,6 +95,7 @@ struct bpf_verifier_state { struct bpf_reg_state regs[MAX_BPF_REG]; u8 stack_slot_type[MAX_BPF_STACK]; struct bpf_reg_state spilled_regs[MAX_BPF_STACK / BPF_REG_SIZE]; + struct bpf_verifier_state *parent; }; /* linked list of verifier states used to prune search */ @@ -103,7 +138,6 @@ struct bpf_verifier_env { u32 id_gen; /* used to generate unique reg IDs */ bool allow_ptr_leaks; bool seen_direct_write; - bool varlen_map_value_access; struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ }; diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h index e34dde2da0ef57c3692ce7001fa66fe37c4dc578..b1be0233ce353d93241bf1d1776d901637e9b95a 100644 --- a/include/linux/bsg-lib.h +++ b/include/linux/bsg-lib.h @@ -24,6 +24,7 @@ #define _BLK_BSG_ #include +#include struct request; struct device; @@ -37,6 +38,7 @@ struct bsg_buffer { }; struct bsg_job { + struct scsi_request sreq; struct device *dev; struct request *req; @@ -66,8 +68,9 @@ struct bsg_job { void bsg_job_done(struct bsg_job *job, int result, unsigned int reply_payload_rcv_len); -struct request_queue *bsg_setup_queue(struct device *dev, char *name, - bsg_job_fn *job_fn, int dd_job_size); +struct request_queue *bsg_setup_queue(struct device *dev, const char *name, + bsg_job_fn *job_fn, int dd_job_size, + void (*release)(struct device *)); void bsg_job_put(struct bsg_job *job); int __must_check bsg_job_get(struct bsg_job *job); diff --git a/include/linux/byteorder/big_endian.h b/include/linux/byteorder/big_endian.h index 392041475c720148c4332b38ea81cd3d1460f425..ffd215988392d96db0739118382bc3e4257efb29 100644 --- a/include/linux/byteorder/big_endian.h +++ b/include/linux/byteorder/big_endian.h @@ -3,5 +3,9 @@ #include +#ifndef CONFIG_CPU_BIG_ENDIAN +#warning inconsistent configuration, needs CONFIG_CPU_BIG_ENDIAN +#endif + #include #endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */ diff --git a/include/linux/byteorder/little_endian.h b/include/linux/byteorder/little_endian.h index 08057377aa23299d59c281ff09030c091392f844..ba910bb9aad0c75b83be099bf98b844505f72688 100644 --- a/include/linux/byteorder/little_endian.h +++ b/include/linux/byteorder/little_endian.h @@ -3,5 +3,9 @@ #include +#ifdef CONFIG_CPU_BIG_ENDIAN +#warning inconsistent configuration, CONFIG_CPU_BIG_ENDIAN is set +#endif + #include #endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */ diff --git a/include/linux/capability.h b/include/linux/capability.h index 6ffb67e10c060afbb24ea34d0dbb38ac36043d3c..b52e278e474471909e31070a4e3d2ad7a49fe9b0 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -248,4 +248,6 @@ extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns); /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); +extern int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size); + #endif /* !_LINUX_CAPABILITY_H */ diff --git a/include/linux/ccp.h b/include/linux/ccp.h index 3285c944194adcccdde5ae31745c939471260da6..7e9c991c95e03fc1df55553461d95f9153d37cd7 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -1,7 +1,7 @@ /* * AMD Cryptographic Coprocessor (CCP) driver * - * Copyright (C) 2013,2016 Advanced Micro Devices, Inc. + * Copyright (C) 2013,2017 Advanced Micro Devices, Inc. * * Author: Tom Lendacky * Author: Gary R Hook @@ -20,12 +20,10 @@ #include #include - struct ccp_device; struct ccp_cmd; -#if defined(CONFIG_CRYPTO_DEV_CCP_DD) || \ - defined(CONFIG_CRYPTO_DEV_CCP_DD_MODULE) +#if defined(CONFIG_CRYPTO_DEV_SP_CCP) /** * ccp_present - check if a CCP device is present @@ -71,7 +69,7 @@ unsigned int ccp_version(void); */ int ccp_enqueue_cmd(struct ccp_cmd *cmd); -#else /* CONFIG_CRYPTO_DEV_CCP_DD is not enabled */ +#else /* CONFIG_CRYPTO_DEV_CCP_SP_DEV is not enabled */ static inline int ccp_present(void) { @@ -88,7 +86,7 @@ static inline int ccp_enqueue_cmd(struct ccp_cmd *cmd) return -ENODEV; } -#endif /* CONFIG_CRYPTO_DEV_CCP_DD */ +#endif /* CONFIG_CRYPTO_DEV_SP_CCP */ /***** AES engine *****/ @@ -231,6 +229,7 @@ enum ccp_xts_aes_unit_size { * AES operation the new IV overwrites the old IV. */ struct ccp_xts_aes_engine { + enum ccp_aes_type type; enum ccp_aes_action action; enum ccp_xts_aes_unit_size unit_size; diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index edf5b04b918a2bb3b6cad3f438733e06b9d3d35e..b422170b791abeabb83d15463d05ba6401828b3c 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h @@ -167,6 +167,8 @@ struct ceph_mon_request_header { struct ceph_mon_statfs { struct ceph_mon_request_header monhdr; struct ceph_fsid fsid; + __u8 contains_data_pool; + __le64 data_pool; } __attribute__ ((packed)); struct ceph_statfs { @@ -669,7 +671,9 @@ enum { extern const char *ceph_cap_op_name(int op); /* flags field in client cap messages (version >= 10) */ -#define CEPH_CLIENT_CAPS_SYNC (0x1) +#define CEPH_CLIENT_CAPS_SYNC (1<<0) +#define CEPH_CLIENT_CAPS_NO_CAPSNAP (1<<1) +#define CEPH_CLIENT_CAPS_PENDING_CAPSNAP (1<<2); /* * caps message, used for capability callbacks, acks, requests, etc. diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 8a79587e1317e6d1a6a31b6fe64cedf8bc429484..4c846aabd9f646fed049130653934560fb2bba0b 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -84,17 +84,6 @@ struct ceph_options { #define CEPH_AUTH_NAME_DEFAULT "guest" -/* - * Delay telling the MDS we no longer want caps, in case we reopen - * the file. Delay a minimum amount of time, even if we send a cap - * message for some other reason. Otherwise, take the oppotunity to - * update the mds to avoid sending another message later. - */ -#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT 5 /* cap release delay */ -#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT 60 /* cap release delay */ - -#define CEPH_CAP_RELEASE_SAFETY_DEFAULT (CEPH_CAPS_PER_RELEASE * 4) - /* mount state */ enum { CEPH_MOUNT_MOUNTING, diff --git a/include/linux/ceph/mon_client.h b/include/linux/ceph/mon_client.h index d5a3ecea578d3e5f34eb1efba9d027811cc68557..0fa990bf867a1ca047e5ae71190afe908061f458 100644 --- a/include/linux/ceph/mon_client.h +++ b/include/linux/ceph/mon_client.h @@ -133,8 +133,8 @@ void ceph_monc_renew_subs(struct ceph_mon_client *monc); extern int ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch, unsigned long timeout); -extern int ceph_monc_do_statfs(struct ceph_mon_client *monc, - struct ceph_statfs *buf); +int ceph_monc_do_statfs(struct ceph_mon_client *monc, u64 data_pool, + struct ceph_statfs *buf); int ceph_monc_get_version(struct ceph_mon_client *monc, const char *what, u64 *newest); diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index c6d96a5f46fd6127c712d1cea79e4e47075a24e7..adf670ecaf94688449f92f240dd3f0bde3b87500 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -148,6 +148,7 @@ struct ceph_osd_request_target { int size; int min_size; bool sort_bitwise; + bool recovery_deletes; unsigned int flags; /* CEPH_OSD_FLAG_* */ bool paused; diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h index a0996cb9faeddfff86a9837676aa3a79da1f01bf..af3444a5bfdd1a0e45493d9603596fd38c042a24 100644 --- a/include/linux/ceph/osdmap.h +++ b/include/linux/ceph/osdmap.h @@ -272,6 +272,8 @@ bool ceph_is_new_interval(const struct ceph_osds *old_acting, u32 new_pg_num, bool old_sort_bitwise, bool new_sort_bitwise, + bool old_recovery_deletes, + bool new_recovery_deletes, const struct ceph_pg *pgid); bool ceph_osds_changed(const struct ceph_osds *old_acting, const struct ceph_osds *new_acting, diff --git a/include/linux/ceph/rados.h b/include/linux/ceph/rados.h index 385db08bb8b2d0a16b6fdc0188e7c5701fa9ef50..01408841c9c4d179bdb72daccad4cf594f5ae5e3 100644 --- a/include/linux/ceph/rados.h +++ b/include/linux/ceph/rados.h @@ -158,6 +158,10 @@ extern const char *ceph_osd_state_name(int s); #define CEPH_OSDMAP_NOTIERAGENT (1<<13) /* disable tiering agent */ #define CEPH_OSDMAP_NOREBALANCE (1<<14) /* block osd backfill unless pg is degraded */ #define CEPH_OSDMAP_SORTBITWISE (1<<15) /* use bitwise hobject_t sort */ +#define CEPH_OSDMAP_REQUIRE_JEWEL (1<<16) /* require jewel for booting osds */ +#define CEPH_OSDMAP_REQUIRE_KRAKEN (1<<17) /* require kraken for booting osds */ +#define CEPH_OSDMAP_REQUIRE_LUMINOUS (1<<18) /* require l for booting osds */ +#define CEPH_OSDMAP_RECOVERY_DELETES (1<<19) /* deletes performed during recovery instead of peering */ /* * The error code to return when an OSD can't handle a write @@ -226,7 +230,6 @@ extern const char *ceph_osd_state_name(int s); \ /* fancy write */ \ f(APPEND, __CEPH_OSD_OP(WR, DATA, 6), "append") \ - f(STARTSYNC, __CEPH_OSD_OP(WR, DATA, 7), "startsync") \ f(SETTRUNC, __CEPH_OSD_OP(WR, DATA, 8), "settrunc") \ f(TRIMTRUNC, __CEPH_OSD_OP(WR, DATA, 9), "trimtrunc") \ \ diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 09f4c7df1478e6c6b8fea1cfc4912ed66219bd34..ade4a78a54c2454cbd40646547f40388cf4b85d3 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -74,6 +74,11 @@ enum { * aren't writeable from inside the namespace. */ CGRP_ROOT_NS_DELEGATE = (1 << 3), + + /* + * Enable cpuset controller in v1 cgroup to use v2 behavior. + */ + CGRP_ROOT_CPUSET_V2_MODE = (1 << 4), }; /* cftype->flags */ @@ -172,6 +177,14 @@ struct css_set { /* reference count */ refcount_t refcount; + /* + * For a domain cgroup, the following points to self. If threaded, + * to the matching cset of the nearest domain ancestor. The + * dom_cset provides access to the domain cgroup and its csses to + * which domain level resource consumptions should be charged. + */ + struct css_set *dom_cset; + /* the default cgroup associated with this css_set */ struct cgroup *dfl_cgrp; @@ -200,6 +213,10 @@ struct css_set { */ struct list_head e_cset_node[CGROUP_SUBSYS_COUNT]; + /* all threaded csets whose ->dom_cset points to this cset */ + struct list_head threaded_csets; + struct list_head threaded_csets_node; + /* * List running through all cgroup groups in the same hash * slot. Protected by css_set_lock @@ -261,13 +278,35 @@ struct cgroup { */ int level; + /* Maximum allowed descent tree depth */ + int max_depth; + + /* + * Keep track of total numbers of visible and dying descent cgroups. + * Dying cgroups are cgroups which were deleted by a user, + * but are still existing because someone else is holding a reference. + * max_descendants is a maximum allowed number of descent cgroups. + */ + int nr_descendants; + int nr_dying_descendants; + int max_descendants; + /* * Each non-empty css_set associated with this cgroup contributes - * one to populated_cnt. All children with non-zero popuplated_cnt - * of their own contribute one. The count is zero iff there's no - * task in this cgroup or its subtree. + * one to nr_populated_csets. The counter is zero iff this cgroup + * doesn't have any tasks. + * + * All children which have non-zero nr_populated_csets and/or + * nr_populated_children of their own contribute one to either + * nr_populated_domain_children or nr_populated_threaded_children + * depending on their type. Each counter is zero iff all cgroups + * of the type in the subtree proper don't have any tasks. */ - int populated_cnt; + int nr_populated_csets; + int nr_populated_domain_children; + int nr_populated_threaded_children; + + int nr_threaded_children; /* # of live threaded child cgroups */ struct kernfs_node *kn; /* cgroup kernfs entry */ struct cgroup_file procs_file; /* handle for "cgroup.procs" */ @@ -305,6 +344,15 @@ struct cgroup { */ struct list_head e_csets[CGROUP_SUBSYS_COUNT]; + /* + * If !threaded, self. If threaded, it points to the nearest + * domain ancestor. Inside a threaded subtree, cgroups are exempt + * from process granularity and no-internal-task constraint. + * Domain level resource consumptions which aren't tied to a + * specific task are charged to the dom_cgrp. + */ + struct cgroup *dom_cgrp; + /* * list of pidlists, up to two for each namespace (one for procs, one * for tasks); created on demand. @@ -491,6 +539,18 @@ struct cgroup_subsys { */ bool implicit_on_dfl:1; + /* + * If %true, the controller, supports threaded mode on the default + * hierarchy. In a threaded subtree, both process granularity and + * no-internal-process constraint are ignored and a threaded + * controllers should be able to handle that. + * + * Note that as an implicit controller is automatically enabled on + * all cgroups on the default hierarchy, it should also be + * threaded. implicit && !threaded is not supported. + */ + bool threaded:1; + /* * If %false, this subsystem is properly hierarchical - * configuration, resource accounting and restriction on a parent diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 710a005c6b7a652bb9c32b5457dbd64196f6f4a0..d023ac5e377f4bd21b0a6fdc5ae33a100990e32f 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -36,18 +36,28 @@ #define CGROUP_WEIGHT_DFL 100 #define CGROUP_WEIGHT_MAX 10000 +/* walk only threadgroup leaders */ +#define CSS_TASK_ITER_PROCS (1U << 0) +/* walk all threaded css_sets in the domain */ +#define CSS_TASK_ITER_THREADED (1U << 1) + /* a css_task_iter should be treated as an opaque object */ struct css_task_iter { struct cgroup_subsys *ss; + unsigned int flags; struct list_head *cset_pos; struct list_head *cset_head; + struct list_head *tcset_pos; + struct list_head *tcset_head; + struct list_head *task_pos; struct list_head *tasks_head; struct list_head *mg_tasks_head; struct css_set *cur_cset; + struct css_set *cur_dcset; struct task_struct *cur_task; struct list_head iters_node; /* css_set->task_iters */ }; @@ -129,7 +139,7 @@ struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset, struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset, struct cgroup_subsys_state **dst_cssp); -void css_task_iter_start(struct cgroup_subsys_state *css, +void css_task_iter_start(struct cgroup_subsys_state *css, unsigned int flags, struct css_task_iter *it); struct task_struct *css_task_iter_next(struct css_task_iter *it); void css_task_iter_end(struct css_task_iter *it); @@ -388,6 +398,16 @@ static inline void css_put_many(struct cgroup_subsys_state *css, unsigned int n) percpu_ref_put_many(&css->refcnt, n); } +static inline void cgroup_get(struct cgroup *cgrp) +{ + css_get(&cgrp->self); +} + +static inline bool cgroup_tryget(struct cgroup *cgrp) +{ + return css_tryget(&cgrp->self); +} + static inline void cgroup_put(struct cgroup *cgrp) { css_put(&cgrp->self); @@ -500,6 +520,20 @@ static inline struct cgroup *task_cgroup(struct task_struct *task, return task_css(task, subsys_id)->cgroup; } +static inline struct cgroup *task_dfl_cgroup(struct task_struct *task) +{ + return task_css_set(task)->dfl_cgrp; +} + +static inline struct cgroup *cgroup_parent(struct cgroup *cgrp) +{ + struct cgroup_subsys_state *parent_css = cgrp->self.parent; + + if (parent_css) + return container_of(parent_css, struct cgroup, self); + return NULL; +} + /** * cgroup_is_descendant - test ancestry * @cgrp: the cgroup to be tested @@ -537,13 +571,14 @@ static inline bool task_under_cgroup_hierarchy(struct task_struct *task, /* no synchronization, the result can only be used as a hint */ static inline bool cgroup_is_populated(struct cgroup *cgrp) { - return cgrp->populated_cnt; + return cgrp->nr_populated_csets + cgrp->nr_populated_domain_children + + cgrp->nr_populated_threaded_children; } /* returns ino associated with a cgroup */ static inline ino_t cgroup_ino(struct cgroup *cgrp) { - return cgrp->kn->ino; + return cgrp->kn->id.ino; } /* cft/css accessors for cftype->write() operation */ @@ -609,6 +644,13 @@ static inline void cgroup_kthread_ready(void) current->no_cgroup_migration = 0; } +static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp) +{ + return &cgrp->kn->id; +} + +void cgroup_path_from_kernfs_id(const union kernfs_node_id *id, + char *buf, size_t buflen); #else /* !CONFIG_CGROUPS */ struct cgroup_subsys_state; @@ -631,12 +673,19 @@ static inline int cgroup_init_early(void) { return 0; } static inline int cgroup_init(void) { return 0; } static inline void cgroup_init_kthreadd(void) {} static inline void cgroup_kthread_ready(void) {} +static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp) +{ + return NULL; +} static inline bool task_under_cgroup_hierarchy(struct task_struct *task, struct cgroup *ancestor) { return true; } + +static inline void cgroup_path_from_kernfs_id(const union kernfs_node_id *id, + char *buf, size_t buflen) {} #endif /* !CONFIG_CGROUPS */ /* diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c59c62571e4fe6a8c3ec5a9f48759b84c67e6a4a..5100ec1b5d559f93b93a12b320feefe148f23b30 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -343,6 +343,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, u8 clk_gate_flags, spinlock_t *lock); void clk_unregister_gate(struct clk *clk); void clk_hw_unregister_gate(struct clk_hw *hw); +int clk_gate_is_enabled(struct clk_hw *hw); struct clk_div_table { unsigned int val; @@ -565,6 +566,9 @@ struct clk_fractional_divider { u8 nwidth; u32 nmask; u8 flags; + void (*approximation)(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate, + unsigned long *m, unsigned long *n); spinlock_t *lock; }; diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 17f413bbbedf4aa9f0b3b4bdd1a0449e6dd19657..6aca5ce8a99a5fb52dc5b8a89cc51d8573f771db 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h @@ -185,4 +185,29 @@ #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ +#define AT91_PMC_AUDIO_PLL0 0x14c +#define AT91_PMC_AUDIO_PLL_PLLEN (1 << 0) +#define AT91_PMC_AUDIO_PLL_PADEN (1 << 1) +#define AT91_PMC_AUDIO_PLL_PMCEN (1 << 2) +#define AT91_PMC_AUDIO_PLL_RESETN (1 << 3) +#define AT91_PMC_AUDIO_PLL_ND_OFFSET 8 +#define AT91_PMC_AUDIO_PLL_ND_MASK (0x7f << AT91_PMC_AUDIO_PLL_ND_OFFSET) +#define AT91_PMC_AUDIO_PLL_ND(n) ((n) << AT91_PMC_AUDIO_PLL_ND_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPMC_OFFSET 16 +#define AT91_PMC_AUDIO_PLL_QDPMC_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPMC(n) ((n) << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) + +#define AT91_PMC_AUDIO_PLL1 0x150 +#define AT91_PMC_AUDIO_PLL_FRACR_MASK 0x3fffff +#define AT91_PMC_AUDIO_PLL_QDPAD_OFFSET 24 +#define AT91_PMC_AUDIO_PLL_QDPAD_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPAD(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET AT91_PMC_AUDIO_PLL_QDPAD_OFFSET +#define AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK (0x3 << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPAD_DIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET 26 +#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX 0x1f +#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK (AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET) +#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET) + #endif diff --git a/include/linux/clk/sunxi-ng.h b/include/linux/clk/sunxi-ng.h new file mode 100644 index 0000000000000000000000000000000000000000..990f760f70e54e70d906e7a66702ac8ae0414675 --- /dev/null +++ b/include/linux/clk/sunxi-ng.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_CLK_SUNXI_NG_H_ +#define _LINUX_CLK_SUNXI_NG_H_ + +#include + +#ifdef CONFIG_SUNXI_CCU +int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode); +int sunxi_ccu_get_mmc_timing_mode(struct clk *clk); +#else +static inline int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, + bool new_mode) +{ + return -ENOTSUPP; +} + +static inline int sunxi_ccu_get_mmc_timing_mode(struct clk *clk) +{ + return -ENOTSUPP; +} +#endif + +#endif diff --git a/include/linux/compat.h b/include/linux/compat.h index 5a6a109b4a508b544882e358def3d11820bce250..a5619de3437d9b1691b0e707bb2577b075592822 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -27,7 +27,7 @@ #endif #ifndef __SC_DELOUSE -#define __SC_DELOUSE(t,v) ((t)(unsigned long)(v)) +#define __SC_DELOUSE(t,v) ((__force t)(unsigned long)(v)) #endif #define COMPAT_SYSCALL_DEFINE0(name) \ @@ -171,15 +171,6 @@ extern int get_compat_itimerspec64(struct itimerspec64 *its, extern int put_compat_itimerspec64(const struct itimerspec64 *its, struct compat_itimerspec __user *uits); -/* - * This function convert a timespec if necessary and returns a *user - * space* pointer. If no conversion is necessary, it returns the - * initial pointer. NULL is a legitimate argument and will always - * output NULL. - */ -extern int compat_convert_timespec(struct timespec __user **, - const void __user *); - struct compat_iovec { compat_uptr_t iov_base; compat_size_t iov_len; @@ -365,10 +356,10 @@ asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, compat_ulong_t vlen, u32 pos_low, u32 pos_high); asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd, const struct compat_iovec __user *vec, - compat_ulong_t vlen, u32 pos_low, u32 pos_high, int flags); + compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd, const struct compat_iovec __user *vec, - compat_ulong_t vlen, u32 pos_low, u32 pos_high, int flags); + compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 asmlinkage long compat_sys_preadv64(unsigned long fd, @@ -382,6 +373,18 @@ asmlinkage long compat_sys_pwritev64(unsigned long fd, unsigned long vlen, loff_t pos); #endif +#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2 +asmlinkage long compat_sys_readv64v2(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos, rwf_t flags); +#endif + +#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 +asmlinkage long compat_sys_pwritev64v2(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos, rwf_t flags); +#endif + asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index bdb80c4aef6e13631075b2ad06b39d2788c8eba5..16d41de92ee3a7799c873d479f3f2770bf87ba4c 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -166,6 +166,8 @@ #if GCC_VERSION >= 40100 # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) + +#define __nostackprotector __attribute__((__optimize__("no-stack-protector"))) #endif #if GCC_VERSION >= 40300 @@ -201,17 +203,6 @@ #endif #endif -#ifdef CONFIG_STACK_VALIDATION -#define annotate_unreachable() ({ \ - asm("%c0:\t\n" \ - ".pushsection .discard.unreachable\t\n" \ - ".long %c0b - .\t\n" \ - ".popsection\t\n" : : "i" (__LINE__)); \ -}) -#else -#define annotate_unreachable() -#endif - /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b054db4657d5e562b3904120b042e..e95a2631e54561d8981a9e849802ba9f9f65f998 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -185,8 +185,34 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, #endif /* Unreachable code */ +#ifdef CONFIG_STACK_VALIDATION +#define annotate_reachable() ({ \ + asm("%c0:\n\t" \ + ".pushsection .discard.reachable\n\t" \ + ".long %c0b - .\n\t" \ + ".popsection\n\t" : : "i" (__LINE__)); \ +}) +#define annotate_unreachable() ({ \ + asm("%c0:\n\t" \ + ".pushsection .discard.unreachable\n\t" \ + ".long %c0b - .\n\t" \ + ".popsection\n\t" : : "i" (__LINE__)); \ +}) +#define ASM_UNREACHABLE \ + "999:\n\t" \ + ".pushsection .discard.unreachable\n\t" \ + ".long 999b - .\n\t" \ + ".popsection\n\t" +#else +#define annotate_reachable() +#define annotate_unreachable() +#endif + +#ifndef ASM_UNREACHABLE +# define ASM_UNREACHABLE +#endif #ifndef unreachable -# define unreachable() do { } while (1) +# define unreachable() do { annotate_reachable(); do { } while (1); } while (0) #endif /* @@ -475,6 +501,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s #define __visible #endif +#ifndef __nostackprotector +# define __nostackprotector +#endif + /* * Assume alignment of return value. */ @@ -517,7 +547,8 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __compiletime_error_fallback(condition) do { } while (0) #endif -#define __compiletime_assert(condition, msg, prefix, suffix) \ +#ifdef __OPTIMIZE__ +# define __compiletime_assert(condition, msg, prefix, suffix) \ do { \ bool __cond = !(condition); \ extern void prefix ## suffix(void) __compiletime_error(msg); \ @@ -525,6 +556,9 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s prefix ## suffix(); \ __compiletime_error_fallback(__cond); \ } while (0) +#else +# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) +#endif #define _compiletime_assert(condition, msg, prefix, suffix) \ __compiletime_assert(condition, msg, prefix, suffix) diff --git a/include/linux/completion.h b/include/linux/completion.h index 5d5aaae3af433ff62b6e03f107c7dfe88a06b522..cae5400022a3535df8d95190162f62211db9c6b7 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h @@ -9,6 +9,9 @@ */ #include +#ifdef CONFIG_LOCKDEP_COMPLETIONS +#include +#endif /* * struct completion - structure used to maintain state for a "completion" @@ -25,13 +28,53 @@ struct completion { unsigned int done; wait_queue_head_t wait; +#ifdef CONFIG_LOCKDEP_COMPLETIONS + struct lockdep_map_cross map; +#endif }; +#ifdef CONFIG_LOCKDEP_COMPLETIONS +static inline void complete_acquire(struct completion *x) +{ + lock_acquire_exclusive((struct lockdep_map *)&x->map, 0, 0, NULL, _RET_IP_); +} + +static inline void complete_release(struct completion *x) +{ + lock_release((struct lockdep_map *)&x->map, 0, _RET_IP_); +} + +static inline void complete_release_commit(struct completion *x) +{ + lock_commit_crosslock((struct lockdep_map *)&x->map); +} + +#define init_completion(x) \ +do { \ + static struct lock_class_key __key; \ + lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \ + "(complete)" #x, \ + &__key, 0); \ + __init_completion(x); \ +} while (0) +#else +#define init_completion(x) __init_completion(x) +static inline void complete_acquire(struct completion *x) {} +static inline void complete_release(struct completion *x) {} +static inline void complete_release_commit(struct completion *x) {} +#endif + +#ifdef CONFIG_LOCKDEP_COMPLETIONS +#define COMPLETION_INITIALIZER(work) \ + { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait), \ + STATIC_CROSS_LOCKDEP_MAP_INIT("(complete)" #work, &(work)) } +#else #define COMPLETION_INITIALIZER(work) \ { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } +#endif #define COMPLETION_INITIALIZER_ONSTACK(work) \ - ({ init_completion(&work); work; }) + (*({ init_completion(&work); &work; })) /** * DECLARE_COMPLETION - declare and initialize a completion structure @@ -70,7 +113,7 @@ struct completion { * This inline function will initialize a dynamically created completion * structure. */ -static inline void init_completion(struct completion *x) +static inline void __init_completion(struct completion *x) { x->done = 0; init_waitqueue_head(&x->wait); diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h index 7d410260661bf0794fb9d9e9b9cb5df8b63bf51e..edfeaba954295a76c1c842253004404365436208 100644 --- a/include/linux/coresight-pmu.h +++ b/include/linux/coresight-pmu.h @@ -24,6 +24,12 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 + +/* ETMv4 CONFIGR programming bits for the ETM OPTs */ +#define ETM4_CFG_BIT_CYCACC 4 +#define ETM4_CFG_BIT_TS 11 +#define ETM4_CFG_BIT_RETSTK 12 static inline int coresight_get_trace_id(int cpu) { diff --git a/include/linux/cper.h b/include/linux/cper.h index 4c671fc2081ef6dd60e0194fb3445f8f627c2c24..723e952fde0def5467a07566a79845dd91e3bb0d 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -74,36 +74,36 @@ enum { * Corrected Machine Check */ #define CPER_NOTIFY_CMC \ - UUID_LE(0x2DCE8BB1, 0xBDD7, 0x450e, 0xB9, 0xAD, 0x9C, 0xF4, \ - 0xEB, 0xD4, 0xF8, 0x90) + GUID_INIT(0x2DCE8BB1, 0xBDD7, 0x450e, 0xB9, 0xAD, 0x9C, 0xF4, \ + 0xEB, 0xD4, 0xF8, 0x90) /* Corrected Platform Error */ #define CPER_NOTIFY_CPE \ - UUID_LE(0x4E292F96, 0xD843, 0x4a55, 0xA8, 0xC2, 0xD4, 0x81, \ - 0xF2, 0x7E, 0xBE, 0xEE) + GUID_INIT(0x4E292F96, 0xD843, 0x4a55, 0xA8, 0xC2, 0xD4, 0x81, \ + 0xF2, 0x7E, 0xBE, 0xEE) /* Machine Check Exception */ #define CPER_NOTIFY_MCE \ - UUID_LE(0xE8F56FFE, 0x919C, 0x4cc5, 0xBA, 0x88, 0x65, 0xAB, \ - 0xE1, 0x49, 0x13, 0xBB) + GUID_INIT(0xE8F56FFE, 0x919C, 0x4cc5, 0xBA, 0x88, 0x65, 0xAB, \ + 0xE1, 0x49, 0x13, 0xBB) /* PCI Express Error */ #define CPER_NOTIFY_PCIE \ - UUID_LE(0xCF93C01F, 0x1A16, 0x4dfc, 0xB8, 0xBC, 0x9C, 0x4D, \ - 0xAF, 0x67, 0xC1, 0x04) + GUID_INIT(0xCF93C01F, 0x1A16, 0x4dfc, 0xB8, 0xBC, 0x9C, 0x4D, \ + 0xAF, 0x67, 0xC1, 0x04) /* INIT Record (for IPF) */ #define CPER_NOTIFY_INIT \ - UUID_LE(0xCC5263E8, 0x9308, 0x454a, 0x89, 0xD0, 0x34, 0x0B, \ - 0xD3, 0x9B, 0xC9, 0x8E) + GUID_INIT(0xCC5263E8, 0x9308, 0x454a, 0x89, 0xD0, 0x34, 0x0B, \ + 0xD3, 0x9B, 0xC9, 0x8E) /* Non-Maskable Interrupt */ #define CPER_NOTIFY_NMI \ - UUID_LE(0x5BAD89FF, 0xB7E6, 0x42c9, 0x81, 0x4A, 0xCF, 0x24, \ - 0x85, 0xD6, 0xE9, 0x8A) + GUID_INIT(0x5BAD89FF, 0xB7E6, 0x42c9, 0x81, 0x4A, 0xCF, 0x24, \ + 0x85, 0xD6, 0xE9, 0x8A) /* BOOT Error Record */ #define CPER_NOTIFY_BOOT \ - UUID_LE(0x3D61A466, 0xAB40, 0x409a, 0xA6, 0x98, 0xF3, 0x62, \ - 0xD4, 0x64, 0xB3, 0x8F) + GUID_INIT(0x3D61A466, 0xAB40, 0x409a, 0xA6, 0x98, 0xF3, 0x62, \ + 0xD4, 0x64, 0xB3, 0x8F) /* DMA Remapping Error */ #define CPER_NOTIFY_DMAR \ - UUID_LE(0x667DD791, 0xC6B3, 0x4c27, 0x8A, 0x6B, 0x0F, 0x8E, \ - 0x72, 0x2D, 0xEB, 0x41) + GUID_INIT(0x667DD791, 0xC6B3, 0x4c27, 0x8A, 0x6B, 0x0F, 0x8E, \ + 0x72, 0x2D, 0xEB, 0x41) /* * Flags bits definitions for flags in struct cper_record_header @@ -170,50 +170,50 @@ enum { * Processor Generic */ #define CPER_SEC_PROC_GENERIC \ - UUID_LE(0x9876CCAD, 0x47B4, 0x4bdb, 0xB6, 0x5E, 0x16, 0xF1, \ - 0x93, 0xC4, 0xF3, 0xDB) + GUID_INIT(0x9876CCAD, 0x47B4, 0x4bdb, 0xB6, 0x5E, 0x16, 0xF1, \ + 0x93, 0xC4, 0xF3, 0xDB) /* Processor Specific: X86/X86_64 */ #define CPER_SEC_PROC_IA \ - UUID_LE(0xDC3EA0B0, 0xA144, 0x4797, 0xB9, 0x5B, 0x53, 0xFA, \ - 0x24, 0x2B, 0x6E, 0x1D) + GUID_INIT(0xDC3EA0B0, 0xA144, 0x4797, 0xB9, 0x5B, 0x53, 0xFA, \ + 0x24, 0x2B, 0x6E, 0x1D) /* Processor Specific: IA64 */ #define CPER_SEC_PROC_IPF \ - UUID_LE(0xE429FAF1, 0x3CB7, 0x11D4, 0x0B, 0xCA, 0x07, 0x00, \ - 0x80, 0xC7, 0x3C, 0x88, 0x81) + GUID_INIT(0xE429FAF1, 0x3CB7, 0x11D4, 0x0B, 0xCA, 0x07, 0x00, \ + 0x80, 0xC7, 0x3C, 0x88, 0x81) /* Processor Specific: ARM */ #define CPER_SEC_PROC_ARM \ - UUID_LE(0xE19E3D16, 0xBC11, 0x11E4, 0x9C, 0xAA, 0xC2, 0x05, \ - 0x1D, 0x5D, 0x46, 0xB0) + GUID_INIT(0xE19E3D16, 0xBC11, 0x11E4, 0x9C, 0xAA, 0xC2, 0x05, \ + 0x1D, 0x5D, 0x46, 0xB0) /* Platform Memory */ #define CPER_SEC_PLATFORM_MEM \ - UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \ - 0xED, 0x7C, 0x83, 0xB1) + GUID_INIT(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \ + 0xED, 0x7C, 0x83, 0xB1) #define CPER_SEC_PCIE \ - UUID_LE(0xD995E954, 0xBBC1, 0x430F, 0xAD, 0x91, 0xB4, 0x4D, \ - 0xCB, 0x3C, 0x6F, 0x35) + GUID_INIT(0xD995E954, 0xBBC1, 0x430F, 0xAD, 0x91, 0xB4, 0x4D, \ + 0xCB, 0x3C, 0x6F, 0x35) /* Firmware Error Record Reference */ #define CPER_SEC_FW_ERR_REC_REF \ - UUID_LE(0x81212A96, 0x09ED, 0x4996, 0x94, 0x71, 0x8D, 0x72, \ - 0x9C, 0x8E, 0x69, 0xED) + GUID_INIT(0x81212A96, 0x09ED, 0x4996, 0x94, 0x71, 0x8D, 0x72, \ + 0x9C, 0x8E, 0x69, 0xED) /* PCI/PCI-X Bus */ #define CPER_SEC_PCI_X_BUS \ - UUID_LE(0xC5753963, 0x3B84, 0x4095, 0xBF, 0x78, 0xED, 0xDA, \ - 0xD3, 0xF9, 0xC9, 0xDD) + GUID_INIT(0xC5753963, 0x3B84, 0x4095, 0xBF, 0x78, 0xED, 0xDA, \ + 0xD3, 0xF9, 0xC9, 0xDD) /* PCI Component/Device */ #define CPER_SEC_PCI_DEV \ - UUID_LE(0xEB5E4685, 0xCA66, 0x4769, 0xB6, 0xA2, 0x26, 0x06, \ - 0x8B, 0x00, 0x13, 0x26) + GUID_INIT(0xEB5E4685, 0xCA66, 0x4769, 0xB6, 0xA2, 0x26, 0x06, \ + 0x8B, 0x00, 0x13, 0x26) #define CPER_SEC_DMAR_GENERIC \ - UUID_LE(0x5B51FEF7, 0xC79D, 0x4434, 0x8F, 0x1B, 0xAA, 0x62, \ - 0xDE, 0x3E, 0x2C, 0x64) + GUID_INIT(0x5B51FEF7, 0xC79D, 0x4434, 0x8F, 0x1B, 0xAA, 0x62, \ + 0xDE, 0x3E, 0x2C, 0x64) /* Intel VT for Directed I/O specific DMAr */ #define CPER_SEC_DMAR_VT \ - UUID_LE(0x71761D37, 0x32B2, 0x45cd, 0xA7, 0xD0, 0xB0, 0xFE, \ - 0xDD, 0x93, 0xE8, 0xCF) + GUID_INIT(0x71761D37, 0x32B2, 0x45cd, 0xA7, 0xD0, 0xB0, 0xFE, \ + 0xDD, 0x93, 0xE8, 0xCF) /* IOMMU specific DMAr */ #define CPER_SEC_DMAR_IOMMU \ - UUID_LE(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F, \ - 0xDF, 0xAA, 0x84, 0xEC) + GUID_INIT(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F, \ + 0xDF, 0xAA, 0x84, 0xEC) #define CPER_PROC_VALID_TYPE 0x0001 #define CPER_PROC_VALID_ISA 0x0002 @@ -290,10 +290,10 @@ struct cper_record_header { __u32 validation_bits; __u32 record_length; __u64 timestamp; - uuid_le platform_id; - uuid_le partition_id; - uuid_le creator_id; - uuid_le notification_type; + guid_t platform_id; + guid_t partition_id; + guid_t creator_id; + guid_t notification_type; __u64 record_id; __u32 flags; __u64 persistence_information; @@ -309,8 +309,8 @@ struct cper_section_descriptor { __u8 validation_bits; __u8 reserved; /* must be zero */ __u32 flags; - uuid_le section_type; - uuid_le fru_id; + guid_t section_type; + guid_t fru_id; __u32 section_severity; __u8 fru_text[20]; }; @@ -343,7 +343,7 @@ struct cper_sec_proc_ia { /* IA32/X64 Processor Error Information Structure */ struct cper_ia_err_info { - uuid_le err_type; + guid_t err_type; __u64 validation_bits; __u64 check_info; __u64 target_id; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index f10a9b3761cdbef777c38a131cc1cb1e4aec0c1e..537ff842ff733290252c795b2a8261b82944fd94 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -127,6 +127,15 @@ struct cpufreq_policy { */ unsigned int transition_delay_us; + /* + * Remote DVFS flag (Not added to the driver structure as we don't want + * to access another structure from scheduler hotpath). + * + * Should be set if CPUs can do DVFS on behalf of other CPUs from + * different cpufreq policies. + */ + bool dvfs_possible_from_any_cpu; + /* Cached frequency lookup from cpufreq_driver_resolve_freq. */ unsigned int cached_target_freq; int cached_resolved_idx; @@ -370,6 +379,12 @@ struct cpufreq_driver { */ #define CPUFREQ_NEED_INITIAL_FREQ_CHECK (1 << 5) +/* + * Set by drivers to disallow use of governors with "dynamic_switching" flag + * set. + */ +#define CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING (1 << 6) + int cpufreq_register_driver(struct cpufreq_driver *driver_data); int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); @@ -487,14 +502,8 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, * polling frequency is 1000 times the transition latency of the processor. The * ondemand governor will work on any processor with transition latency <= 10ms, * using appropriate sampling rate. - * - * For CPUs with transition latency > 10ms (mostly drivers with CPUFREQ_ETERNAL) - * the ondemand governor will not work. All times here are in us (microseconds). */ -#define MIN_SAMPLING_RATE_RATIO (2) #define LATENCY_MULTIPLIER (1000) -#define MIN_LATENCY_MULTIPLIER (20) -#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; @@ -507,9 +516,8 @@ struct cpufreq_governor { char *buf); int (*store_setspeed) (struct cpufreq_policy *policy, unsigned int freq); - unsigned int max_transition_latency; /* HW must be able to switch to - next freq faster than this value in nano secs or we - will fallback to performance governor */ + /* For governors which change frequency dynamically by themselves */ + bool dynamic_switching; struct list_head governor_list; struct module *owner; }; @@ -525,6 +533,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int relation); unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, unsigned int target_freq); +unsigned int cpufreq_policy_transition_delay_us(struct cpufreq_policy *policy); int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); @@ -562,6 +571,17 @@ struct governor_attr { size_t count); }; +static inline bool cpufreq_can_do_remote_dvfs(struct cpufreq_policy *policy) +{ + /* + * Allow remote callbacks if: + * - dvfs_possible_from_any_cpu flag is set + * - the local and remote CPUs share cpufreq policy + */ + return policy->dvfs_possible_from_any_cpu || + cpumask_test_cpu(smp_processor_id(), policy->cpus); +} + /********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index b56573bf440db4b85f8f11f678edb9e28d4e6cd8..6d508767e14455d52470fe806f5f923637561edc 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -3,8 +3,27 @@ #include +/* + * CPU-up CPU-down + * + * BP AP BP AP + * + * OFFLINE OFFLINE + * | ^ + * v | + * BRINGUP_CPU->AP_OFFLINE BRINGUP_CPU <- AP_IDLE_DEAD (idle thread/play_dead) + * | AP_OFFLINE + * v (IRQ-off) ,---------------^ + * AP_ONLNE | (stop_machine) + * | TEARDOWN_CPU <- AP_ONLINE_IDLE + * | ^ + * v | + * AP_ACTIVE AP_ACTIVE + */ + enum cpuhp_state { - CPUHP_OFFLINE, + CPUHP_INVALID = -1, + CPUHP_OFFLINE = 0, CPUHP_CREATE_THREADS, CPUHP_PERF_PREPARE, CPUHP_PERF_X86_PREPARE, @@ -39,8 +58,6 @@ enum cpuhp_state { CPUHP_PCI_XGENE_DEAD, CPUHP_IOMMU_INTEL_DEAD, CPUHP_LUSTRE_CFS_DEAD, - CPUHP_SCSI_BNX2FC_DEAD, - CPUHP_SCSI_BNX2I_DEAD, CPUHP_WORKQUEUE_PREP, CPUHP_POWER_NUMA_PREPARE, CPUHP_HRTIMERS_PREPARE, @@ -139,6 +156,9 @@ enum cpuhp_state { CPUHP_AP_PERF_ARM_L2X0_ONLINE, CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE, CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE, + CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE, + CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE, + CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE, CPUHP_AP_WORKQUEUE_ONLINE, CPUHP_AP_RCUTREE_ONLINE, CPUHP_AP_ONLINE_DYN, diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index fc1e5d7fc1c7bf9d9749145597312440c1b63fe8..8f7788d23b5732a3fb5c2b1d704b05d370d41954 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -52,17 +52,18 @@ struct cpuidle_state { int (*enter_dead) (struct cpuidle_device *dev, int index); /* - * CPUs execute ->enter_freeze with the local tick or entire timekeeping + * CPUs execute ->enter_s2idle with the local tick or entire timekeeping * suspended, so it must not re-enable interrupts at any point (even * temporarily) or attempt to change states of clock event devices. */ - void (*enter_freeze) (struct cpuidle_device *dev, + void (*enter_s2idle) (struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); }; /* Idle State Flags */ #define CPUIDLE_FLAG_NONE (0x00) +#define CPUIDLE_FLAG_POLLING (0x01) /* polling state */ #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ #define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */ @@ -197,14 +198,14 @@ static inline struct cpuidle_device *cpuidle_get_device(void) {return NULL; } #ifdef CONFIG_CPU_IDLE extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv, struct cpuidle_device *dev); -extern int cpuidle_enter_freeze(struct cpuidle_driver *drv, +extern int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev); extern void cpuidle_use_deepest_state(bool enable); #else static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv, struct cpuidle_device *dev) {return -ENODEV; } -static inline int cpuidle_enter_freeze(struct cpuidle_driver *drv, +static inline int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev) {return -ENODEV; } static inline void cpuidle_use_deepest_state(bool enable) @@ -224,6 +225,12 @@ static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, } #endif +#ifdef CONFIG_ARCH_HAS_CPU_RELAX +void cpuidle_poll_state_init(struct cpuidle_driver *drv); +#else +static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {} +#endif + /****************************** * CPUIDLE GOVERNOR INTERFACE * ******************************/ @@ -250,12 +257,6 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov) {return 0;} #endif -#ifdef CONFIG_ARCH_HAS_CPU_RELAX -#define CPUIDLE_DRIVER_STATE_START 1 -#else -#define CPUIDLE_DRIVER_STATE_START 0 -#endif - #define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \ ({ \ int __ret; \ diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 4bf4479a3a800c435ccec039f7e5da4089910f87..cd415b733c2a0595ca8c58c22f23ffb5b5126bc4 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -32,15 +32,15 @@ typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; #define cpumask_pr_args(maskp) nr_cpu_ids, cpumask_bits(maskp) #if NR_CPUS == 1 -#define nr_cpu_ids 1 +#define nr_cpu_ids 1U #else -extern int nr_cpu_ids; +extern unsigned int nr_cpu_ids; #endif #ifdef CONFIG_CPUMASK_OFFSTACK /* Assuming NR_CPUS is huge, a runtime limit is more efficient. Also, * not all bits may be allocated. */ -#define nr_cpumask_bits ((unsigned int)nr_cpu_ids) +#define nr_cpumask_bits nr_cpu_ids #else #define nr_cpumask_bits ((unsigned int)NR_CPUS) #endif @@ -178,20 +178,7 @@ static inline unsigned int cpumask_first(const struct cpumask *srcp) return find_first_bit(cpumask_bits(srcp), nr_cpumask_bits); } -/** - * cpumask_next - get the next cpu in a cpumask - * @n: the cpu prior to the place to search (ie. return will be > @n) - * @srcp: the cpumask pointer - * - * Returns >= nr_cpu_ids if no further cpus set. - */ -static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) -{ - /* -1 is a legal arg here. */ - if (n != -1) - cpumask_check(n); - return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1); -} +unsigned int cpumask_next(int n, const struct cpumask *srcp); /** * cpumask_next_zero - get the next unset cpu in a cpumask diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 119a3f9604b0d90b499bdbd6627d30fbc936469b..a1e6a33a4b039cf879ca5e70cd6f14a8bd9a18b8 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -18,31 +18,42 @@ #ifdef CONFIG_CPUSETS +/* + * Static branch rewrites can happen in an arbitrary order for a given + * key. In code paths where we need to loop with read_mems_allowed_begin() and + * read_mems_allowed_retry() to get a consistent view of mems_allowed, we need + * to ensure that begin() always gets rewritten before retry() in the + * disabled -> enabled transition. If not, then if local irqs are disabled + * around the loop, we can deadlock since retry() would always be + * comparing the latest value of the mems_allowed seqcount against 0 as + * begin() still would see cpusets_enabled() as false. The enabled -> disabled + * transition should happen in reverse order for the same reasons (want to stop + * looking at real value of mems_allowed.sequence in retry() first). + */ +extern struct static_key_false cpusets_pre_enable_key; extern struct static_key_false cpusets_enabled_key; static inline bool cpusets_enabled(void) { return static_branch_unlikely(&cpusets_enabled_key); } -static inline int nr_cpusets(void) -{ - /* jump label reference count + the top-level cpuset */ - return static_key_count(&cpusets_enabled_key.key) + 1; -} - static inline void cpuset_inc(void) { + static_branch_inc(&cpusets_pre_enable_key); static_branch_inc(&cpusets_enabled_key); } static inline void cpuset_dec(void) { static_branch_dec(&cpusets_enabled_key); + static_branch_dec(&cpusets_pre_enable_key); } extern int cpuset_init(void); extern void cpuset_init_smp(void); +extern void cpuset_force_rebuild(void); extern void cpuset_update_active_cpus(void); +extern void cpuset_wait_for_hotplug(void); extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); extern void cpuset_cpus_allowed_fallback(struct task_struct *p); extern nodemask_t cpuset_mems_allowed(struct task_struct *p); @@ -115,7 +126,7 @@ extern void cpuset_print_current_mems_allowed(void); */ static inline unsigned int read_mems_allowed_begin(void) { - if (!cpusets_enabled()) + if (!static_branch_unlikely(&cpusets_pre_enable_key)) return 0; return read_seqcount_begin(¤t->mems_allowed_seq); @@ -129,7 +140,7 @@ static inline unsigned int read_mems_allowed_begin(void) */ static inline bool read_mems_allowed_retry(unsigned int seq) { - if (!cpusets_enabled()) + if (!static_branch_unlikely(&cpusets_enabled_key)) return false; return read_seqcount_retry(¤t->mems_allowed_seq, seq); @@ -155,11 +166,15 @@ static inline bool cpusets_enabled(void) { return false; } static inline int cpuset_init(void) { return 0; } static inline void cpuset_init_smp(void) {} +static inline void cpuset_force_rebuild(void) { } + static inline void cpuset_update_active_cpus(void) { partition_sched_domains(1, NULL, NULL); } +static inline void cpuset_wait_for_hotplug(void) { } + static inline void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask) { diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h index 92e165d417a6119d200ce1dbf2972c7297d6da1a..07eed95e10c7d67b8a2c0543c152672bc6019203 100644 --- a/include/linux/crush/crush.h +++ b/include/linux/crush/crush.h @@ -193,7 +193,7 @@ struct crush_choose_arg { struct crush_choose_arg_map { #ifdef __KERNEL__ struct rb_node node; - u64 choose_args_index; + s64 choose_args_index; #endif struct crush_choose_arg *args; /*!< replacement for each bucket in the crushmap */ diff --git a/include/linux/dax.h b/include/linux/dax.h index df97b7af7e2c7263c4ae9fb1608b19aad1ae02ba..122197124b9def0e148482c40df7def28ec6ce99 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -19,8 +19,6 @@ struct dax_operations { /* copy_from_iter: required operation for fs-dax direct-i/o */ size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t, struct iov_iter *); - /* flush: optional driver-specific cache management after writes */ - void (*flush)(struct dax_device *, pgoff_t, void *, size_t); }; extern struct attribute_group dax_attribute_group; @@ -57,6 +55,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev) put_dax(dax_dev); } +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev); #else static inline int bdev_dax_supported(struct super_block *sb, int blocksize) { @@ -71,6 +70,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host) static inline void fs_put_dax(struct dax_device *dax_dev) { } + +static inline struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev) +{ + return NULL; +} #endif int dax_read_lock(void); @@ -84,39 +88,10 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages, void **kaddr, pfn_t *pfn); size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i); -void dax_flush(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, - size_t size); +void dax_flush(struct dax_device *dax_dev, void *addr, size_t size); void dax_write_cache(struct dax_device *dax_dev, bool wc); bool dax_write_cache_enabled(struct dax_device *dax_dev); -/* - * We use lowest available bit in exceptional entry for locking, one bit for - * the entry size (PMD) and two more to tell us if the entry is a huge zero - * page (HZP) or an empty entry that is just used for locking. In total four - * special bits. - * - * If the PMD bit isn't set the entry has size PAGE_SIZE, and if the HZP and - * EMPTY bits aren't set the entry is a normal DAX entry with a filesystem - * block allocation. - */ -#define RADIX_DAX_SHIFT (RADIX_TREE_EXCEPTIONAL_SHIFT + 4) -#define RADIX_DAX_ENTRY_LOCK (1 << RADIX_TREE_EXCEPTIONAL_SHIFT) -#define RADIX_DAX_PMD (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 1)) -#define RADIX_DAX_HZP (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 2)) -#define RADIX_DAX_EMPTY (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 3)) - -static inline unsigned long dax_radix_sector(void *entry) -{ - return (unsigned long)entry >> RADIX_DAX_SHIFT; -} - -static inline void *dax_radix_locked_entry(sector_t sector, unsigned long flags) -{ - return (void *)(RADIX_TREE_EXCEPTIONAL_ENTRY | flags | - ((unsigned long)sector << RADIX_DAX_SHIFT) | - RADIX_DAX_ENTRY_LOCK); -} - ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, const struct iomap_ops *ops); int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, @@ -124,8 +99,6 @@ int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index); int dax_invalidate_mapping_entry_sync(struct address_space *mapping, pgoff_t index); -void dax_wake_mapping_entry_waiter(struct address_space *mapping, - pgoff_t index, void *entry, bool wake_all); #ifdef CONFIG_FS_DAX int __dax_zero_page_range(struct block_device *bdev, @@ -140,21 +113,6 @@ static inline int __dax_zero_page_range(struct block_device *bdev, } #endif -#ifdef CONFIG_FS_DAX_PMD -static inline unsigned int dax_radix_order(void *entry) -{ - if ((unsigned long)entry & RADIX_DAX_PMD) - return PMD_SHIFT - PAGE_SHIFT; - return 0; -} -#else -static inline unsigned int dax_radix_order(void *entry) -{ - return 0; -} -#endif -int dax_pfn_mkwrite(struct vm_fault *vmf); - static inline bool dax_mapping(struct address_space *mapping) { return mapping->host && IS_DAX(mapping->host); diff --git a/include/linux/dcache.h b/include/linux/dcache.h index aae1cdb76851308dd825e1558cf007a3722dad73..ed1a7cf6923af31a3c08a591ca74444b6771e71d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -147,7 +147,7 @@ struct dentry_operations { struct vfsmount *(*d_automount)(struct path *); int (*d_manage)(const struct path *, bool); struct dentry *(*d_real)(struct dentry *, const struct inode *, - unsigned int); + unsigned int, unsigned int); } ____cacheline_aligned; /* @@ -562,11 +562,15 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper) return upper; } +/* d_real() flags */ +#define D_REAL_UPPER 0x2 /* return upper dentry or NULL if non-upper */ + /** * d_real - Return the real dentry * @dentry: the dentry to query * @inode: inode to select the dentry from multiple layers (can be NULL) - * @flags: open flags to control copy-up behavior + * @open_flags: open flags to control copy-up behavior + * @flags: flags to control what is returned by this function * * If dentry is on a union/overlay, then return the underlying, real dentry. * Otherwise return the dentry itself. @@ -575,10 +579,10 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper) */ static inline struct dentry *d_real(struct dentry *dentry, const struct inode *inode, - unsigned int flags) + unsigned int open_flags, unsigned int flags) { if (unlikely(dentry->d_flags & DCACHE_OP_REAL)) - return dentry->d_op->d_real(dentry, inode, flags); + return dentry->d_op->d_real(dentry, inode, open_flags, flags); else return dentry; } @@ -593,7 +597,7 @@ static inline struct dentry *d_real(struct dentry *dentry, static inline struct inode *d_real_inode(const struct dentry *dentry) { /* This usage of d_real() results in const dentry */ - return d_backing_inode(d_real((struct dentry *) dentry, NULL, 0)); + return d_backing_inode(d_real((struct dentry *) dentry, NULL, 0, 0)); } struct name_snapshot { diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index aa86e6d8c1aa2ac2df84ef4fa909192ce4312935..b93efc8feecd1f67e9b79fdc62abc96b30e13b1b 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -196,6 +196,14 @@ static inline struct dentry *debugfs_create_file(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } +static inline struct dentry *debugfs_create_file_unsafe(const char *name, + umode_t mode, struct dentry *parent, + void *data, + const struct file_operations *fops) +{ + return ERR_PTR(-ENODEV); +} + static inline struct dentry *debugfs_create_file_size(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops, @@ -289,6 +297,14 @@ static inline struct dentry *debugfs_create_u64(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } +static inline struct dentry *debugfs_create_ulong(const char *name, + umode_t mode, + struct dentry *parent, + unsigned long *value) +{ + return ERR_PTR(-ENODEV); +} + static inline struct dentry *debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value) diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 6c220e4ebb6b9d8441a811b822a10333fee21498..597294e0cc409cf0bbfeb13aefeb13dccc08d3ea 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -214,19 +214,6 @@ extern void devm_devfreq_unregister_notifier(struct device *dev, extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index); -/** - * devfreq_update_stats() - update the last_status pointer in struct devfreq - * @df: the devfreq instance whose status needs updating - * - * Governors are recommended to use this function along with last_status, - * which allows other entities to reuse the last_status without affecting - * the values fetched later by governors. - */ -static inline int devfreq_update_stats(struct devfreq *df) -{ - return df->profile->get_dev_status(df->dev.parent, &df->last_status); -} - #if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) /** * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 1473455d0341bed5b157cab1cd95d8a08980e711..a5538433c927abebad75ec6763a3e6ab8f1cc0e2 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -134,8 +134,6 @@ typedef long (*dm_dax_direct_access_fn) (struct dm_target *ti, pgoff_t pgoff, long nr_pages, void **kaddr, pfn_t *pfn); typedef size_t (*dm_dax_copy_from_iter_fn)(struct dm_target *ti, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i); -typedef void (*dm_dax_flush_fn)(struct dm_target *ti, pgoff_t pgoff, void *addr, - size_t size); #define PAGE_SECTORS (PAGE_SIZE / 512) void dm_error(const char *message); @@ -186,7 +184,6 @@ struct target_type { dm_io_hints_fn io_hints; dm_dax_direct_access_fn direct_access; dm_dax_copy_from_iter_fn dax_copy_from_iter; - dm_dax_flush_fn dax_flush; /* For internal device-mapper use. */ struct list_head list; @@ -387,7 +384,7 @@ struct dm_arg { * Validate the next argument, either returning it as *value or, if invalid, * returning -EINVAL and setting *error. */ -int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, +int dm_read_arg(const struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error); /* @@ -395,7 +392,7 @@ int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, * arg->min and arg->max further arguments. Either return the size as * *num_args or, if invalid, return -EINVAL and set *error. */ -int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, +int dm_read_arg_group(const struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *num_args, char **error); /* @@ -549,46 +546,29 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); *---------------------------------------------------------------*/ #define DM_NAME "device-mapper" -#ifdef CONFIG_PRINTK -extern struct ratelimit_state dm_ratelimit_state; - -#define dm_ratelimit() __ratelimit(&dm_ratelimit_state) -#else -#define dm_ratelimit() 0 -#endif +#define DM_RATELIMIT(pr_func, fmt, ...) \ +do { \ + static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + \ + if (__ratelimit(&rs)) \ + pr_func(DM_FMT(fmt), ##__VA_ARGS__); \ +} while (0) #define DM_FMT(fmt) DM_NAME ": " DM_MSG_PREFIX ": " fmt "\n" #define DMCRIT(fmt, ...) pr_crit(DM_FMT(fmt), ##__VA_ARGS__) #define DMERR(fmt, ...) pr_err(DM_FMT(fmt), ##__VA_ARGS__) -#define DMERR_LIMIT(fmt, ...) \ -do { \ - if (dm_ratelimit()) \ - DMERR(fmt, ##__VA_ARGS__); \ -} while (0) - +#define DMERR_LIMIT(fmt, ...) DM_RATELIMIT(pr_err, fmt, ##__VA_ARGS__) #define DMWARN(fmt, ...) pr_warn(DM_FMT(fmt), ##__VA_ARGS__) -#define DMWARN_LIMIT(fmt, ...) \ -do { \ - if (dm_ratelimit()) \ - DMWARN(fmt, ##__VA_ARGS__); \ -} while (0) - +#define DMWARN_LIMIT(fmt, ...) DM_RATELIMIT(pr_warn, fmt, ##__VA_ARGS__) #define DMINFO(fmt, ...) pr_info(DM_FMT(fmt), ##__VA_ARGS__) -#define DMINFO_LIMIT(fmt, ...) \ -do { \ - if (dm_ratelimit()) \ - DMINFO(fmt, ##__VA_ARGS__); \ -} while (0) +#define DMINFO_LIMIT(fmt, ...) DM_RATELIMIT(pr_info, fmt, ##__VA_ARGS__) #ifdef CONFIG_DM_DEBUG #define DMDEBUG(fmt, ...) printk(KERN_DEBUG DM_FMT(fmt), ##__VA_ARGS__) -#define DMDEBUG_LIMIT(fmt, ...) \ -do { \ - if (dm_ratelimit()) \ - DMDEBUG(fmt, ##__VA_ARGS__); \ -} while (0) +#define DMDEBUG_LIMIT(fmt, ...) DM_RATELIMIT(pr_debug, fmt, ##__VA_ARGS__) #else #define DMDEBUG(fmt, ...) no_printk(fmt, ##__VA_ARGS__) #define DMDEBUG_LIMIT(fmt, ...) no_printk(fmt, ##__VA_ARGS__) diff --git a/include/linux/device.h b/include/linux/device.h index 723cd54b94da84f95cd18934d14198b6d21040dd..66fe271c2544d5cf861e1e5c58e23a0793ba1ed6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -307,8 +307,6 @@ struct driver_attribute { size_t count); }; -#define DRIVER_ATTR(_name, _mode, _show, _store) \ - struct driver_attribute driver_attr_##_name = __ATTR(_name, _mode, _show, _store) #define DRIVER_ATTR_RW(_name) \ struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) #define DRIVER_ATTR_RO(_name) \ @@ -375,7 +373,7 @@ int subsys_virtual_register(struct bus_type *subsys, * @suspend: Used to put the device to sleep mode, usually to a low power * state. * @resume: Used to bring the device from the sleep mode. - * @shutdown: Called at shut-down time to quiesce the device. + * @shutdown_pre: Called at shut-down time before driver shutdown. * @ns_type: Callbacks so sysfs can detemine namespaces. * @namespace: Namespace of the device belongs to this class. * @pm: The default device power management operations of this class. @@ -404,7 +402,7 @@ struct class { int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); - int (*shutdown)(struct device *dev); + int (*shutdown_pre)(struct device *dev); const struct kobj_ns_type_operations *ns_type; const void *(*namespace)(struct device *dev); @@ -838,15 +836,16 @@ struct dev_links_info { * @driver_data: Private pointer for driver specific info. * @links: Links to suppliers and consumers of this device. * @power: For device power management. - * See Documentation/power/admin-guide/devices.rst for details. + * See Documentation/driver-api/pm/devices.rst for details. * @pm_domain: Provide callbacks that are executed during system suspend, * hibernation, system resume and during runtime PM transitions * along with subsystem-level and driver-level callbacks. * @pins: For device pin management. - * See Documentation/pinctrl.txt for details. + * See Documentation/driver-api/pinctl.rst for details. * @msi_list: Hosts MSI descriptors * @msi_domain: The generic MSI domain this device is using. * @numa_node: NUMA node this device is close to. + * @dma_ops: DMA mapping operations for this device. * @dma_mask: Dma mask (if dma'ble device). * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all * hardware supports 64-bit addresses for consistent allocations @@ -1200,6 +1199,36 @@ struct device *device_create_with_groups(struct class *cls, const char *fmt, ...); extern void device_destroy(struct class *cls, dev_t devt); +extern int __must_check device_add_groups(struct device *dev, + const struct attribute_group **groups); +extern void device_remove_groups(struct device *dev, + const struct attribute_group **groups); + +static inline int __must_check device_add_group(struct device *dev, + const struct attribute_group *grp) +{ + const struct attribute_group *groups[] = { grp, NULL }; + + return device_add_groups(dev, groups); +} + +static inline void device_remove_group(struct device *dev, + const struct attribute_group *grp) +{ + const struct attribute_group *groups[] = { grp, NULL }; + + return device_remove_groups(dev, groups); +} + +extern int __must_check devm_device_add_groups(struct device *dev, + const struct attribute_group **groups); +extern void devm_device_remove_groups(struct device *dev, + const struct attribute_group **groups); +extern int __must_check devm_device_add_group(struct device *dev, + const struct attribute_group *grp); +extern void devm_device_remove_group(struct device *dev, + const struct attribute_group *grp); + /* * Platform "fixup" functions - allow the platform to have their say * about devices and actions that the general device layer doesn't diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 277ab9af9ac29a95773ce2201809f7c7613391a1..100cb43437630114127bfecc3d29ad4454c03446 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -19,6 +19,7 @@ struct pts_fs_info; +struct vfsmount *devpts_mntget(struct file *, struct pts_fs_info *); struct pts_fs_info *devpts_acquire(struct file *); void devpts_release(struct pts_fs_info *); @@ -32,6 +33,15 @@ void *devpts_get_priv(struct dentry *); /* unlink */ void devpts_pty_kill(struct dentry *); +/* in pty.c */ +int ptm_open_peer(struct file *master, struct tty_struct *tty, int flags); + +#else +static inline int +ptm_open_peer(struct file *master, struct tty_struct *tty, int flags) +{ + return -EIO; +} #endif diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index 0a186c4f3981c8738dec34ed558a10f47f9fc026..171895072435bd7efa0303e401a3f907d12cdc7d 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -337,6 +337,19 @@ dma_fence_is_signaled(struct dma_fence *fence) return false; } +/** + * __dma_fence_is_later - return if f1 is chronologically later than f2 + * @f1: [in] the first fence's seqno + * @f2: [in] the second fence's seqno from the same context + * + * Returns true if f1 is chronologically later than f2. Both fences must be + * from the same context, since a seqno is not common across contexts. + */ +static inline bool __dma_fence_is_later(u32 f1, u32 f2) +{ + return (int)(f1 - f2) > 0; +} + /** * dma_fence_is_later - return if f1 is chronologically later than f2 * @f1: [in] the first fence from the same context @@ -351,7 +364,7 @@ static inline bool dma_fence_is_later(struct dma_fence *f1, if (WARN_ON(f1->context != f2->context)) return false; - return (int)(f1->seqno - f2->seqno) > 0; + return __dma_fence_is_later(f1->seqno, f2->seqno); } /** @@ -418,8 +431,8 @@ int dma_fence_get_status(struct dma_fence *fence); static inline void dma_fence_set_error(struct dma_fence *fence, int error) { - BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)); - BUG_ON(error >= 0 || error < -MAX_ERRNO); + WARN_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)); + WARN_ON(error >= 0 || error < -MAX_ERRNO); fence->error = error; } diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 03c0196a6f2474ea4e34e9840638ff80a45370ec..29ce9815da87fcf436405fff2c1bdfddd6847e4b 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -10,6 +10,7 @@ #include #include #include +#include /** * List of possible attributes associated with a DMA mapping. The semantics @@ -549,27 +550,20 @@ static inline void dma_free_coherent(struct device *dev, size_t size, return dma_free_attrs(dev, size, cpu_addr, dma_handle, 0); } -static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return dma_alloc_attrs(dev, size, dma_handle, gfp, - DMA_ATTR_NON_CONSISTENT); -} + const struct dma_map_ops *ops = get_dma_ops(dev); -static inline void dma_free_noncoherent(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle) -{ - dma_free_attrs(dev, size, cpu_addr, dma_handle, - DMA_ATTR_NON_CONSISTENT); + debug_dma_mapping_error(dev, dma_addr); + if (ops->mapping_error) + return ops->mapping_error(dev, dma_addr); + return 0; } -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static inline void dma_check_mask(struct device *dev, u64 mask) { - debug_dma_mapping_error(dev, dma_addr); - - if (get_dma_ops(dev)->mapping_error) - return get_dma_ops(dev)->mapping_error(dev, dma_addr); - return 0; + if (sme_active() && (mask < (((u64)sme_get_me_mask() << 1) - 1))) + dev_warn(dev, "SME is active, device will require DMA bounce buffers\n"); } static inline int dma_supported(struct device *dev, u64 mask) @@ -588,6 +582,9 @@ static inline int dma_set_mask(struct device *dev, u64 mask) { if (!dev->dma_mask || !dma_supported(dev, mask)) return -EIO; + + dma_check_mask(dev, mask); + *dev->dma_mask = mask; return 0; } @@ -607,6 +604,9 @@ static inline int dma_set_coherent_mask(struct device *dev, u64 mask) { if (!dma_supported(dev, mask)) return -EIO; + + dma_check_mask(dev, mask); + dev->coherent_dma_mask = mask; return 0; } @@ -707,10 +707,7 @@ static inline int dma_get_cache_alignment(void) #endif /* flags for the coherent memory api */ -#define DMA_MEMORY_MAP 0x01 -#define DMA_MEMORY_IO 0x02 -#define DMA_MEMORY_INCLUDES_CHILDREN 0x04 -#define DMA_MEMORY_EXCLUSIVE 0x08 +#define DMA_MEMORY_EXCLUSIVE 0x01 #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, @@ -723,7 +720,7 @@ static inline int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, dma_addr_t device_addr, size_t size, int flags) { - return 0; + return -ENOSYS; } static inline void diff --git a/include/linux/dma/qcom_bam_dma.h b/include/linux/dma/qcom_bam_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..077d43a358e5e14d92062d6c0d112b10e7999396 --- /dev/null +++ b/include/linux/dma/qcom_bam_dma.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _QCOM_BAM_DMA_H +#define _QCOM_BAM_DMA_H + +#include + +/* + * This data type corresponds to the native Command Element + * supported by BAM DMA Engine. + * + * @cmd_and_addr - upper 8 bits command and lower 24 bits register address. + * @data - for write command: content to be written into peripheral register. + * for read command: dest addr to write peripheral register value. + * @mask - register mask. + * @reserved - for future usage. + * + */ +struct bam_cmd_element { + __le32 cmd_and_addr; + __le32 data; + __le32 mask; + __le32 reserved; +}; + +/* + * This enum indicates the command type in a command element + */ +enum bam_command_type { + BAM_WRITE_COMMAND = 0, + BAM_READ_COMMAND, +}; + +/* + * prep_bam_ce_le32 - Wrapper function to prepare a single BAM command + * element with the data already in le32 format. + * + * @bam_ce: bam command element + * @addr: target address + * @cmd: BAM command + * @data: actual data for write and dest addr for read in le32 + */ +static inline void +bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr, + enum bam_command_type cmd, __le32 data) +{ + bam_ce->cmd_and_addr = + cpu_to_le32((addr & 0xffffff) | ((cmd & 0xff) << 24)); + bam_ce->data = data; + bam_ce->mask = cpu_to_le32(0xffffffff); +} + +/* + * bam_prep_ce - Wrapper function to prepare a single BAM command element + * with the data. + * + * @bam_ce: BAM command element + * @addr: target address + * @cmd: BAM command + * @data: actual data for write and dest addr for read + */ +static inline void +bam_prep_ce(struct bam_cmd_element *bam_ce, u32 addr, + enum bam_command_type cmd, u32 data) +{ + bam_prep_ce_le32(bam_ce, addr, cmd, cpu_to_le32(data)); +} +#endif diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 533680860865a2f6b64d0f73d3fb9040e097657b..8319101170fcc85e7f69c64bd6e56d8e4deeae89 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -68,7 +68,6 @@ enum dma_transaction_type { DMA_MEMSET, DMA_MEMSET_SG, DMA_INTERRUPT, - DMA_SG, DMA_PRIVATE, DMA_ASYNC_TX, DMA_SLAVE, @@ -186,6 +185,9 @@ struct dma_interleaved_template { * on the result of this operation * @DMA_CTRL_REUSE: client can reuse the descriptor and submit again till * cleared or freed + * @DMA_PREP_CMD: tell the driver that the data passed to DMA API is command + * data and the descriptor should be in different format from normal + * data descriptors. */ enum dma_ctrl_flags { DMA_PREP_INTERRUPT = (1 << 0), @@ -195,6 +197,7 @@ enum dma_ctrl_flags { DMA_PREP_CONTINUE = (1 << 4), DMA_PREP_FENCE = (1 << 5), DMA_CTRL_REUSE = (1 << 6), + DMA_PREP_CMD = (1 << 7), }; /** @@ -771,11 +774,6 @@ struct dma_device { unsigned int nents, int value, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( struct dma_chan *chan, unsigned long flags); - struct dma_async_tx_descriptor *(*device_prep_dma_sg)( - struct dma_chan *chan, - struct scatterlist *dst_sg, unsigned int dst_nents, - struct scatterlist *src_sg, unsigned int src_nents, - unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_slave_sg)( struct dma_chan *chan, struct scatterlist *sgl, @@ -905,19 +903,6 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_memcpy( len, flags); } -static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg( - struct dma_chan *chan, - struct scatterlist *dst_sg, unsigned int dst_nents, - struct scatterlist *src_sg, unsigned int src_nents, - unsigned long flags) -{ - if (!chan || !chan->device || !chan->device->device_prep_dma_sg) - return NULL; - - return chan->device->device_prep_dma_sg(chan, dst_sg, dst_nents, - src_sg, src_nents, flags); -} - /** * dmaengine_terminate_all() - Terminate all active DMA transfers * @chan: The channel for which to terminate the transfers diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 002611c85318f53365f6a606b4d37e445e40f9b6..2d0259327721444b587e6ec6bd8388a01afc82db 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -51,7 +51,7 @@ #endif extern const char *drbd_buildtag(void); -#define REL_VERSION "8.4.7" +#define REL_VERSION "8.4.10" #define API_VERSION 1 #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 101 diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index 2896f93808ae3a8ed962cf1958e72ff2e5f8da3a..4e6d4d4c705662fa5c60cf5bc36c4421472f42e6 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h @@ -132,7 +132,8 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf, __flg_field_def(18, DRBD_GENLA_F_MANDATORY, disk_drain, DRBD_DISK_DRAIN_DEF) __flg_field_def(19, DRBD_GENLA_F_MANDATORY, md_flushes, DRBD_MD_FLUSHES_DEF) __flg_field_def(23, 0 /* OPTIONAL */, al_updates, DRBD_AL_UPDATES_DEF) - __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED) + __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF) + __flg_field_def(26, 0 /* OPTIONAL */, disable_write_same, DRBD_DISABLE_WRITE_SAME_DEF) ) GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index ddac68422a9648efbadba86a4b3a5fa9dd01b8ef..24ae1b9b76c7d3b70025814f07e1a7989d3e902f 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h @@ -209,12 +209,18 @@ #define DRBD_MD_FLUSHES_DEF 1 #define DRBD_TCP_CORK_DEF 1 #define DRBD_AL_UPDATES_DEF 1 + /* We used to ignore the discard_zeroes_data setting. * To not change established (and expected) behaviour, * by default assume that, for discard_zeroes_data=0, * we can make that an effective discard_zeroes_data=1, * if we only explicitly zero-out unaligned partial chunks. */ -#define DRBD_DISCARD_ZEROES_IF_ALIGNED 1 +#define DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF 1 + +/* Some backends pretend to support WRITE SAME, + * but fail such requests when they are actually submitted. + * This is to tell DRBD to not even try. */ +#define DRBD_DISABLE_WRITE_SAME_DEF 0 #define DRBD_ALLOW_TWO_PRIMARIES_DEF 0 #define DRBD_ALWAYS_ASBP_DEF 0 diff --git a/include/linux/edac.h b/include/linux/edac.h index 8ae0f45fafd650f57b10b9db50cef9d91578506c..cd75c173fd00bf6945a8bfe17b280354b8e3308c 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -619,7 +619,6 @@ struct mem_ctl_info { */ struct device *pdev; const char *mod_name; - const char *mod_ver; const char *ctl_name; const char *dev_name; void *pvt_info; diff --git a/include/linux/eeprom_93xx46.h b/include/linux/eeprom_93xx46.h index 885f587a35550cb1e4318beaeced8633fe4321e0..915898759280288f553df6369afe83dc8aec2c81 100644 --- a/include/linux/eeprom_93xx46.h +++ b/include/linux/eeprom_93xx46.h @@ -2,8 +2,7 @@ * Module: eeprom_93xx46 * platform description for 93xx46 EEPROMs. */ - -struct gpio_desc; +#include struct eeprom_93xx46_platform_data { unsigned char flags; diff --git a/include/linux/efi.h b/include/linux/efi.h index 8269bcb8ccf7961bd01f52e39fc4d34d370f25d3..66f4a4e79f4b2ea1894e5b91fce00eb05528e843 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -47,10 +47,10 @@ typedef u16 efi_char16_t; /* UNICODE character */ typedef u64 efi_physical_addr_t; typedef void *efi_handle_t; -typedef uuid_le efi_guid_t; +typedef guid_t efi_guid_t; #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ - UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) + GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) /* * Generic EFI table header @@ -985,7 +985,7 @@ static inline void efi_esrt_init(void) { } extern int efi_config_parse_tables(void *config_tables, int count, int sz, efi_config_table_type_t *arch_tables); extern u64 efi_get_iobase (void); -extern u32 efi_mem_type (unsigned long phys_addr); +extern int efi_mem_type(unsigned long phys_addr); extern u64 efi_mem_attributes (unsigned long phys_addr); extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); extern int __init efi_uart_console_only (void); @@ -1020,6 +1020,28 @@ extern int efi_memattr_init(void); extern int efi_memattr_apply_permissions(struct mm_struct *mm, efi_memattr_perm_setter fn); +/* + * efi_early_memdesc_ptr - get the n-th EFI memmap descriptor + * @map: the start of efi memmap + * @desc_size: the size of space for each EFI memmap descriptor + * @n: the index of efi memmap descriptor + * + * EFI boot service provides the GetMemoryMap() function to get a copy of the + * current memory map which is an array of memory descriptors, each of + * which describes a contiguous block of memory. It also gets the size of the + * map, and the size of each descriptor, etc. + * + * Note that per section 6.2 of UEFI Spec 2.6 Errata A, the returned size of + * each descriptor might not be equal to sizeof(efi_memory_memdesc_t), + * since efi_memory_memdesc_t may be extended in the future. Thus the OS + * MUST use the returned size of the descriptor to find the start of each + * efi_memory_memdesc_t in the memory map array. This should only be used + * during bootup since for_each_efi_memory_desc_xxx() is available after the + * kernel initializes the EFI subsystem to set up struct efi_memory_map. + */ +#define efi_early_memdesc_ptr(map, desc_size, n) \ + (efi_memory_desc_t *)((void *)(map) + ((n) * (desc_size))) + /* Iterate through an efi_memory_map */ #define for_each_efi_memory_desc_in_map(m, md) \ for ((md) = (m)->map; \ @@ -1091,6 +1113,8 @@ static inline bool efi_enabled(int feature) return test_bit(feature, &efi.flags) != 0; } extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused); + +extern bool efi_is_table_address(unsigned long phys_addr); #else static inline bool efi_enabled(int feature) { @@ -1104,6 +1128,11 @@ efi_capsule_pending(int *reset_type) { return false; } + +static inline bool efi_is_table_address(unsigned long phys_addr) +{ + return false; +} #endif extern int efi_status_to_err(efi_status_t status); @@ -1497,6 +1526,13 @@ enum efi_secureboot_mode { }; enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table); +#ifdef CONFIG_RESET_ATTACK_MITIGATION +void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg); +#else +static inline void +efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { } +#endif + /* * Arch code can implement the following three template macros, avoiding * reptition for the void/non-void return cases of {__,}efi_call_virt(): @@ -1557,6 +1593,8 @@ efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table, void *priv, efi_exit_boot_map_processing priv_func); +#define EFI_RANDOM_SEED_SIZE 64U + struct linux_efi_random_seed { u32 size; u8 bits[]; diff --git a/include/linux/errseq.h b/include/linux/errseq.h index 9e0d444ac88df162c51eef8b74aa0d98091d9d95..f746bd8fe4d0873ba7eddf78f0ac45fc152014f3 100644 --- a/include/linux/errseq.h +++ b/include/linux/errseq.h @@ -1,18 +1,12 @@ +/* + * See Documentation/errseq.rst and lib/errseq.c + */ #ifndef _LINUX_ERRSEQ_H #define _LINUX_ERRSEQ_H -/* See lib/errseq.c for more info */ - typedef u32 errseq_t; -errseq_t __errseq_set(errseq_t *eseq, int err); -static inline void errseq_set(errseq_t *eseq, int err) -{ - /* Optimize for the common case of no error */ - if (unlikely(err)) - __errseq_set(eseq, err); -} - +errseq_t errseq_set(errseq_t *eseq, int err); errseq_t errseq_sample(errseq_t *eseq); int errseq_check(errseq_t *eseq, errseq_t since); int errseq_check_and_advance(errseq_t *eseq, errseq_t *since); diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 83cc9863444b078765255b9010b015578768be09..4587a4c369232589fbbc77200ca3257440f850de 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -136,6 +136,17 @@ struct ethtool_link_ksettings { #define ethtool_link_ksettings_add_link_mode(ptr, name, mode) \ __set_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name) +/** + * ethtool_link_ksettings_del_link_mode - clear bit in link_ksettings + * link mode mask + * @ptr : pointer to struct ethtool_link_ksettings + * @name : one of supported/advertising/lp_advertising + * @mode : one of the ETHTOOL_LINK_MODE_*_BIT + * (not atomic, no bound checking) + */ +#define ethtool_link_ksettings_del_link_mode(ptr, name, mode) \ + __clear_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name) + /** * ethtool_link_ksettings_test_link_mode - test bit in ksettings link mode mask * @ptr : pointer to struct ethtool_link_ksettings @@ -374,5 +385,9 @@ struct ethtool_ops { struct ethtool_link_ksettings *); int (*set_link_ksettings)(struct net_device *, const struct ethtool_link_ksettings *); + int (*get_fecparam)(struct net_device *, + struct ethtool_fecparam *); + int (*set_fecparam)(struct net_device *, + struct ethtool_fecparam *); }; #endif /* _LINUX_ETHTOOL_H */ diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 7e206a9f88db81d2feb152ef4a98a9f0119af09e..744d60ca80c3209d811ab217930425f0bc37cc67 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h @@ -1,5 +1,5 @@ /* - * External connector (extcon) class driver + * External Connector (extcon) framework * * Copyright (C) 2015 Samsung Electronics * Author: Chanwoo Choi @@ -20,8 +20,7 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * -*/ + */ #ifndef __LINUX_EXTCON_H__ #define __LINUX_EXTCON_H__ @@ -93,7 +92,7 @@ #define EXTCON_NUM 63 /* - * Define the property of supported external connectors. + * Define the properties of supported external connectors. * * When adding the new extcon property, they *must* have * the type/value/default information. Also, you *have to* @@ -176,44 +175,42 @@ struct extcon_dev; #if IS_ENABLED(CONFIG_EXTCON) -/* - * Following APIs are for notifiers or configurations. - * Notifiers are the external port and connection devices. - */ +/* Following APIs register/unregister the extcon device. */ extern int extcon_dev_register(struct extcon_dev *edev); extern void extcon_dev_unregister(struct extcon_dev *edev); extern int devm_extcon_dev_register(struct device *dev, - struct extcon_dev *edev); + struct extcon_dev *edev); extern void devm_extcon_dev_unregister(struct device *dev, - struct extcon_dev *edev); -extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); + struct extcon_dev *edev); -/* - * Following APIs control the memory of extcon device. - */ +/* Following APIs allocate/free the memory of the extcon device. */ extern struct extcon_dev *extcon_dev_allocate(const unsigned int *cable); extern void extcon_dev_free(struct extcon_dev *edev); extern struct extcon_dev *devm_extcon_dev_allocate(struct device *dev, - const unsigned int *cable); + const unsigned int *cable); extern void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev); +/* Synchronize the state and property value for each external connector. */ +extern int extcon_sync(struct extcon_dev *edev, unsigned int id); + /* - * get/set_state access each bit of the 32b encoded state value. - * They are used to access the status of each cable based on the cable id. + * Following APIs get/set the connected state of each external connector. + * The 'id' argument indicates the defined external connector. */ extern int extcon_get_state(struct extcon_dev *edev, unsigned int id); extern int extcon_set_state(struct extcon_dev *edev, unsigned int id, - bool cable_state); + bool state); extern int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, - bool cable_state); -/* - * Synchronize the state and property data for a specific external connector. - */ -extern int extcon_sync(struct extcon_dev *edev, unsigned int id); + bool state); /* - * get/set_property access the property value of each external connector. - * They are used to access the property of each cable based on the property id. + * Following APIs get/set the property of each external connector. + * The 'id' argument indicates the defined external connector + * and the 'prop' indicates the extcon property. + * + * And extcon_get/set_property_capability() set the capability of the property + * for each external connector. They are used to set the capability of the + * property of each external connector based on the id and property. */ extern int extcon_get_property(struct extcon_dev *edev, unsigned int id, unsigned int prop, @@ -224,28 +221,24 @@ extern int extcon_set_property(struct extcon_dev *edev, unsigned int id, extern int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id, unsigned int prop, union extcon_property_value prop_val); - -/* - * get/set_property_capability set the capability of the property for each - * external connector. They are used to set the capability of the property - * of each external connector based on the id and property. - */ extern int extcon_get_property_capability(struct extcon_dev *edev, unsigned int id, unsigned int prop); extern int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id, unsigned int prop); /* - * Following APIs are to monitor the status change of the external connectors. + * Following APIs register the notifier block in order to detect + * the change of both state and property value for each external connector. + * * extcon_register_notifier(*edev, id, *nb) : Register a notifier block * for specific external connector of the extcon. * extcon_register_notifier_all(*edev, *nb) : Register a notifier block * for all supported external connectors of the extcon. */ extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, - struct notifier_block *nb); + struct notifier_block *nb); extern int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id, - struct notifier_block *nb); + struct notifier_block *nb); extern int devm_extcon_register_notifier(struct device *dev, struct extcon_dev *edev, unsigned int id, struct notifier_block *nb); @@ -265,16 +258,15 @@ extern void devm_extcon_unregister_notifier_all(struct device *dev, struct notifier_block *nb); /* - * Following API get the extcon device from devicetree. - * This function use phandle of devicetree to get extcon device directly. + * Following APIs get the extcon_dev from devicetree or by through extcon name. */ +extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index); -/* Following API to get information of extcon device */ +/* Following API get the name of extcon device. */ extern const char *extcon_get_edev_name(struct extcon_dev *edev); - #else /* CONFIG_EXTCON */ static inline int extcon_dev_register(struct extcon_dev *edev) { @@ -284,13 +276,13 @@ static inline int extcon_dev_register(struct extcon_dev *edev) static inline void extcon_dev_unregister(struct extcon_dev *edev) { } static inline int devm_extcon_dev_register(struct device *dev, - struct extcon_dev *edev) + struct extcon_dev *edev) { return -EINVAL; } static inline void devm_extcon_dev_unregister(struct device *dev, - struct extcon_dev *edev) { } + struct extcon_dev *edev) { } static inline struct extcon_dev *extcon_dev_allocate(const unsigned int *cable) { @@ -300,7 +292,7 @@ static inline struct extcon_dev *extcon_dev_allocate(const unsigned int *cable) static inline void extcon_dev_free(struct extcon_dev *edev) { } static inline struct extcon_dev *devm_extcon_dev_allocate(struct device *dev, - const unsigned int *cable) + const unsigned int *cable) { return ERR_PTR(-ENOSYS); } @@ -314,13 +306,13 @@ static inline int extcon_get_state(struct extcon_dev *edev, unsigned int id) } static inline int extcon_set_state(struct extcon_dev *edev, unsigned int id, - bool cable_state) + bool state) { return 0; } static inline int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, - bool cable_state) + bool state) { return 0; } @@ -331,52 +323,45 @@ static inline int extcon_sync(struct extcon_dev *edev, unsigned int id) } static inline int extcon_get_property(struct extcon_dev *edev, unsigned int id, - unsigned int prop, - union extcon_property_value *prop_val) + unsigned int prop, + union extcon_property_value *prop_val) { return 0; } static inline int extcon_set_property(struct extcon_dev *edev, unsigned int id, - unsigned int prop, - union extcon_property_value prop_val) + unsigned int prop, + union extcon_property_value prop_val) { return 0; } static inline int extcon_set_property_sync(struct extcon_dev *edev, - unsigned int id, unsigned int prop, - union extcon_property_value prop_val) + unsigned int id, unsigned int prop, + union extcon_property_value prop_val) { return 0; } static inline int extcon_get_property_capability(struct extcon_dev *edev, - unsigned int id, unsigned int prop) + unsigned int id, unsigned int prop) { return 0; } static inline int extcon_set_property_capability(struct extcon_dev *edev, - unsigned int id, unsigned int prop) + unsigned int id, unsigned int prop) { return 0; } -static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) -{ - return NULL; -} - static inline int extcon_register_notifier(struct extcon_dev *edev, - unsigned int id, - struct notifier_block *nb) + unsigned int id, struct notifier_block *nb) { return 0; } static inline int extcon_unregister_notifier(struct extcon_dev *edev, - unsigned int id, - struct notifier_block *nb) + unsigned int id, struct notifier_block *nb) { return 0; } @@ -392,8 +377,13 @@ static inline void devm_extcon_unregister_notifier(struct device *dev, struct extcon_dev *edev, unsigned int id, struct notifier_block *nb) { } +static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) +{ + return ERR_PTR(-ENODEV); +} + static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, - int index) + int index) { return ERR_PTR(-ENODEV); } @@ -411,26 +401,14 @@ struct extcon_specific_cable_nb { }; static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj, - const char *extcon_name, const char *cable_name, - struct notifier_block *nb) + const char *extcon_name, const char *cable_name, + struct notifier_block *nb) { return -EINVAL; } -static inline int extcon_unregister_interest(struct extcon_specific_cable_nb - *obj) +static inline int extcon_unregister_interest(struct extcon_specific_cable_nb *obj) { return -EINVAL; } - -static inline int extcon_get_cable_state_(struct extcon_dev *edev, unsigned int id) -{ - return extcon_get_state(edev, id); -} - -static inline int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id, - bool cable_state) -{ - return extcon_set_state_sync(edev, id, cable_state); -} #endif /* __LINUX_EXTCON_H__ */ diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index b6feed6547ce92862acaf3153c5859d3eb132ccb..2a0c453d72354ef6394cf06d2831326ff6bf7aaf 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -186,6 +186,8 @@ struct f2fs_extent { #define F2FS_NAME_LEN 255 #define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs */ #define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ +#define CUR_ADDRS_PER_INODE(inode) (DEF_ADDRS_PER_INODE - \ + get_extra_isize(inode)) #define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */ #define ADDRS_PER_INODE(inode) addrs_per_inode(inode) #define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ @@ -205,9 +207,7 @@ struct f2fs_extent { #define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */ #define F2FS_DATA_EXIST 0x08 /* file inline data exist flag */ #define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */ - -#define MAX_INLINE_DATA (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \ - F2FS_INLINE_XATTR_ADDRS - 1)) +#define F2FS_EXTRA_ATTR 0x20 /* file having extra attribute */ struct f2fs_inode { __le16 i_mode; /* file mode */ @@ -235,8 +235,16 @@ struct f2fs_inode { struct f2fs_extent i_ext; /* caching a largest extent */ - __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */ - + union { + struct { + __le16 i_extra_isize; /* extra inode attribute size */ + __le16 i_padding; /* padding */ + __le32 i_projid; /* project id */ + __le32 i_inode_checksum;/* inode meta checksum */ + __le32 i_extra_end[0]; /* for attribute size calculation */ + }; + __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */ + }; __le32 i_nid[DEF_NIDS_PER_INODE]; /* direct(2), indirect(2), double_indirect(1) node id */ } __packed; @@ -465,7 +473,7 @@ typedef __le32 f2fs_hash_t; #define MAX_DIR_BUCKETS (1 << ((MAX_DIR_HASH_DEPTH / 2) - 1)) /* - * space utilization of regular dentry and inline dentry + * space utilization of regular dentry and inline dentry (w/o extra reservation) * regular dentry inline dentry * bitmap 1 * 27 = 27 1 * 23 = 23 * reserved 1 * 3 = 3 1 * 7 = 7 @@ -501,24 +509,6 @@ struct f2fs_dentry_block { __u8 filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; } __packed; -/* for inline dir */ -#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \ - ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ - BITS_PER_BYTE + 1)) -#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + \ - BITS_PER_BYTE - 1) / BITS_PER_BYTE) -#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \ - ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ - NR_INLINE_DENTRY + INLINE_DENTRY_BITMAP_SIZE)) - -/* inline directory entry structure */ -struct f2fs_inline_dentry { - __u8 dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE]; - __u8 reserved[INLINE_RESERVED_SIZE]; - struct f2fs_dir_entry dentry[NR_INLINE_DENTRY]; - __u8 filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN]; -} __packed; - /* file types used in inode_info->flags */ enum { F2FS_FT_UNKNOWN, @@ -534,4 +524,6 @@ enum { #define S_SHIFT 12 +#define F2FS_DEF_PROJID 0 /* default project ID */ + #endif /* _LINUX_F2FS_FS_H */ diff --git a/include/linux/filter.h b/include/linux/filter.h index bfef1e5734f8a8da5b06c3ad44d36bda7af3a06d..d29e58fde364f01168c059f85faac389622a3fc3 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -711,7 +711,24 @@ bool bpf_helper_changes_pkt_data(void *func); struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, const struct bpf_insn *patch, u32 len); + +/* The pair of xdp_do_redirect and xdp_do_flush_map MUST be called in the + * same cpu context. Further for best results no more than a single map + * for the do_redirect/do_flush pair should be used. This limitation is + * because we only track one map and force a flush when the map changes. + * This does not appear to be a real limitation for existing software. + */ +int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb, + struct bpf_prog *prog); +int xdp_do_redirect(struct net_device *dev, + struct xdp_buff *xdp, + struct bpf_prog *prog); +void xdp_do_flush_map(void); + void bpf_warn_invalid_xdp_action(u32 act); +void bpf_warn_invalid_xdp_redirect(u32 ifindex); + +struct sock *do_sk_redirect_map(void); #ifdef CONFIG_BPF_JIT extern int bpf_jit_enable; diff --git a/include/linux/fmc.h b/include/linux/fmc.h index a5f0aa5c2a8d9da55769f280de4ac6c0970ff944..3dc8a1b2db7beb59a2715e77ef17cce14c990fd4 100644 --- a/include/linux/fmc.h +++ b/include/linux/fmc.h @@ -132,6 +132,8 @@ struct fmc_operations { uint32_t (*read32)(struct fmc_device *fmc, int offset); void (*write32)(struct fmc_device *fmc, uint32_t value, int offset); int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv); + int (*reprogram_raw)(struct fmc_device *f, struct fmc_driver *d, + void *gw, unsigned long len); int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw); int (*irq_request)(struct fmc_device *fmc, irq_handler_t h, char *name, int flags); @@ -144,6 +146,8 @@ struct fmc_operations { }; /* Prefer this helper rather than calling of fmc->reprogram directly */ +int fmc_reprogram_raw(struct fmc_device *fmc, struct fmc_driver *d, + void *gw, unsigned long len, int sdb_entry); extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw, int sdb_entry); @@ -180,6 +184,9 @@ struct fmc_device { uint32_t device_id; /* Filled by the device */ char *mezzanine_name; /* Defaults to ``fmc'' */ void *mezzanine_data; + + struct dentry *dbg_dir; + struct dentry *dbg_sdb_dump; }; #define to_fmc_device(x) container_of((x), struct fmc_device, dev) @@ -217,14 +224,23 @@ static inline void fmc_set_drvdata(struct fmc_device *fmc, void *data) dev_set_drvdata(&fmc->dev, data); } -/* The 4 access points */ +struct fmc_gateware { + void *bitstream; + unsigned long len; +}; + +/* The 5 access points */ extern int fmc_driver_register(struct fmc_driver *drv); extern void fmc_driver_unregister(struct fmc_driver *drv); extern int fmc_device_register(struct fmc_device *tdev); +extern int fmc_device_register_gw(struct fmc_device *tdev, + struct fmc_gateware *gw); extern void fmc_device_unregister(struct fmc_device *tdev); -/* Two more for device sets, all driven by the same FPGA */ +/* Three more for device sets, all driven by the same FPGA */ extern int fmc_device_register_n(struct fmc_device **devs, int n); +extern int fmc_device_register_n_gw(struct fmc_device **devs, int n, + struct fmc_gateware *gw); extern void fmc_device_unregister_n(struct fmc_device **devs, int n); /* Internal cross-calls between files; not exported to other modules */ @@ -232,6 +248,23 @@ extern int fmc_match(struct device *dev, struct device_driver *drv); extern int fmc_fill_id_info(struct fmc_device *fmc); extern void fmc_free_id_info(struct fmc_device *fmc); extern void fmc_dump_eeprom(const struct fmc_device *fmc); -extern void fmc_dump_sdb(const struct fmc_device *fmc); + +/* helpers for FMC operations */ +extern int fmc_irq_request(struct fmc_device *fmc, irq_handler_t h, + char *name, int flags); +extern void fmc_irq_free(struct fmc_device *fmc); +extern void fmc_irq_ack(struct fmc_device *fmc); +extern int fmc_validate(struct fmc_device *fmc, struct fmc_driver *drv); +extern int fmc_gpio_config(struct fmc_device *fmc, struct fmc_gpio *gpio, + int ngpio); +extern int fmc_read_ee(struct fmc_device *fmc, int pos, void *d, int l); +extern int fmc_write_ee(struct fmc_device *fmc, int pos, const void *d, int l); + +/* helpers for FMC operations */ +extern int fmc_irq_request(struct fmc_device *fmc, irq_handler_t h, + char *name, int flags); +extern void fmc_irq_free(struct fmc_device *fmc); +extern void fmc_irq_ack(struct fmc_device *fmc); +extern int fmc_validate(struct fmc_device *fmc, struct fmc_driver *drv); #endif /* __LINUX_FMC_H__ */ diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index b4ac24c4411d0fae1a77aa40024f7b9a5285ad5c..bfa14bc023fbc65014bc7e6010a7a10a181e0d2d 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h @@ -67,10 +67,14 @@ enum fpga_mgr_states { * FPGA Manager flags * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting + * FPGA_MGR_BITSTREAM_LSB_FIRST: SPI bitstream bit order is LSB first + * FPGA_MGR_COMPRESSED_BITSTREAM: FPGA bitstream is compressed */ #define FPGA_MGR_PARTIAL_RECONFIG BIT(0) #define FPGA_MGR_EXTERNAL_CONFIG BIT(1) #define FPGA_MGR_ENCRYPTED_BITSTREAM BIT(2) +#define FPGA_MGR_BITSTREAM_LSB_FIRST BIT(3) +#define FPGA_MGR_COMPRESSED_BITSTREAM BIT(4) /** * struct fpga_image_info - information specific to a FPGA image diff --git a/include/linux/fs.h b/include/linux/fs.h index 6e1fd5d2124877c16bbbfab4487a772c8f7e37ee..13dab191a23e61654d29a4bff297919105bb20a6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -72,6 +72,8 @@ extern int leases_enable, lease_break_time; extern int sysctl_protected_symlinks; extern int sysctl_protected_hardlinks; +typedef __kernel_rwf_t rwf_t; + struct buffer_head; typedef int (get_block_t)(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create); @@ -146,8 +148,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, /* File was opened by fanotify and shouldn't generate fanotify events */ #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) -/* File is capable of returning -EAGAIN if AIO will block */ -#define FMODE_AIO_NOWAIT ((__force fmode_t)0x8000000) +/* File is capable of returning -EAGAIN if I/O will block */ +#define FMODE_NOWAIT ((__force fmode_t)0x8000000) /* * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector @@ -390,7 +392,7 @@ struct address_space { struct radix_tree_root page_tree; /* radix tree of all pages */ spinlock_t tree_lock; /* and lock protecting it */ atomic_t i_mmap_writable;/* count VM_SHARED mappings */ - struct rb_root i_mmap; /* tree of private and shared mappings */ + struct rb_root_cached i_mmap; /* tree of private and shared mappings */ struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */ /* Protected by tree_lock together with the radix tree */ unsigned long nrpages; /* number of total pages */ @@ -401,7 +403,7 @@ struct address_space { unsigned long flags; /* error bits */ spinlock_t private_lock; /* for use by the address_space */ gfp_t gfp_mask; /* implicit gfp mask for allocations */ - struct list_head private_list; /* ditto */ + struct list_head private_list; /* for use by the address_space */ void *private_data; /* ditto */ errseq_t wb_err; } __attribute__((aligned(sizeof(long)))) __randomize_layout; @@ -427,6 +429,7 @@ struct block_device { #endif struct block_device * bd_contains; unsigned bd_block_size; + u8 bd_partno; struct hd_struct * bd_part; /* number of times partitions within this device have been opened. */ unsigned bd_part_count; @@ -484,7 +487,7 @@ static inline void i_mmap_unlock_read(struct address_space *mapping) */ static inline int mapping_mapped(struct address_space *mapping) { - return !RB_EMPTY_ROOT(&mapping->i_mmap); + return !RB_EMPTY_ROOT(&mapping->i_mmap.rb_root); } /* @@ -907,9 +910,9 @@ static inline struct file *get_file(struct file *f) /* Page cache limit. The filesystems should put that into their s_maxbytes limits, otherwise bad things can happen in VM. */ #if BITS_PER_LONG==32 -#define MAX_LFS_FILESIZE (((loff_t)PAGE_SIZE << (BITS_PER_LONG-1))-1) +#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT) #elif BITS_PER_LONG==64 -#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL) +#define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX) #endif #define FL_POSIX 1 @@ -1000,7 +1003,6 @@ struct file_lock { unsigned char fl_type; unsigned int fl_pid; int fl_link_cpu; /* what cpu's list is this on? */ - struct pid *fl_nspid; wait_queue_head_t fl_wait; struct file *fl_file; loff_t fl_start; @@ -1233,7 +1235,7 @@ static inline struct inode *file_inode(const struct file *f) static inline struct dentry *file_dentry(const struct file *file) { - return d_real(file->f_path.dentry, file_inode(file), 0); + return d_real(file->f_path.dentry, file_inode(file), 0, 0); } static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) @@ -1268,7 +1270,32 @@ extern void f_delown(struct file *filp); extern pid_t f_getown(struct file *filp); extern int send_sigurg(struct fown_struct *fown); -struct mm_struct; +/* + * sb->s_flags. Note that these mirror the equivalent MS_* flags where + * represented in both. + */ +#define SB_RDONLY 1 /* Mount read-only */ +#define SB_NOSUID 2 /* Ignore suid and sgid bits */ +#define SB_NODEV 4 /* Disallow access to device special files */ +#define SB_NOEXEC 8 /* Disallow program execution */ +#define SB_SYNCHRONOUS 16 /* Writes are synced at once */ +#define SB_MANDLOCK 64 /* Allow mandatory locks on an FS */ +#define SB_DIRSYNC 128 /* Directory modifications are synchronous */ +#define SB_NOATIME 1024 /* Do not update access times. */ +#define SB_NODIRATIME 2048 /* Do not update directory access times */ +#define SB_SILENT 32768 +#define SB_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define SB_KERNMOUNT (1<<22) /* this is a kern_mount call */ +#define SB_I_VERSION (1<<23) /* Update inode I_version field */ +#define SB_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ + +/* These sb flags are internal to the kernel */ +#define SB_SUBMOUNT (1<<26) +#define SB_NOREMOTELOCK (1<<27) +#define SB_NOSEC (1<<28) +#define SB_BORN (1<<29) +#define SB_ACTIVE (1<<30) +#define SB_NOUSER (1<<31) /* * Umount options @@ -1754,13 +1781,10 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, struct iovec **ret_pointer); extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); -extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_readv(struct file *, const struct iovec __user *, - unsigned long, loff_t *, int); -extern ssize_t vfs_writev(struct file *, const struct iovec __user *, - unsigned long, loff_t *, int); + unsigned long, loff_t *, rwf_t); extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, loff_t, size_t, unsigned int); extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, @@ -1836,7 +1860,7 @@ struct super_operations { * possible to override it selectively if you really wanted to with some * ioctl() that is not currently implemented. * - * Exception: MS_RDONLY is always applied to the entire file system. + * Exception: SB_RDONLY is always applied to the entire file system. * * Unfortunately, it is possible to change a filesystems flags with it mounted * with files in use. This means that all of the inodes will not have their @@ -1845,19 +1869,20 @@ struct super_operations { */ #define __IS_FLG(inode, flg) ((inode)->i_sb->s_flags & (flg)) -#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY) -#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \ +static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags & MS_RDONLY; } +#define IS_RDONLY(inode) sb_rdonly((inode)->i_sb) +#define IS_SYNC(inode) (__IS_FLG(inode, SB_SYNCHRONOUS) || \ ((inode)->i_flags & S_SYNC)) -#define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \ +#define IS_DIRSYNC(inode) (__IS_FLG(inode, SB_SYNCHRONOUS|SB_DIRSYNC) || \ ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) -#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) -#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) -#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) +#define IS_MANDLOCK(inode) __IS_FLG(inode, SB_MANDLOCK) +#define IS_NOATIME(inode) __IS_FLG(inode, SB_RDONLY|SB_NOATIME) +#define IS_I_VERSION(inode) __IS_FLG(inode, SB_I_VERSION) #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) -#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#define IS_POSIXACL(inode) __IS_FLG(inode, SB_POSIXACL) #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) @@ -2178,7 +2203,7 @@ static inline int __mandatory_lock(struct inode *ino) } /* - * ... and these candidates should be on MS_MANDLOCK mounted fs, + * ... and these candidates should be on SB_MANDLOCK mounted fs, * otherwise these will be advisory locks */ @@ -2471,9 +2496,13 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev, #endif /* fs/char_dev.c */ -#define CHRDEV_MAJOR_HASH_SIZE 255 +#define CHRDEV_MAJOR_MAX 512 /* Marks the bottom of the first segment of free char majors */ #define CHRDEV_MAJOR_DYN_END 234 +/* Marks the top and bottom of the second segment of free char majors */ +#define CHRDEV_MAJOR_DYN_EXT_START 511 +#define CHRDEV_MAJOR_DYN_EXT_END 384 + extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); extern int register_chrdev_region(dev_t, unsigned, const char *); extern int __register_chrdev(unsigned int major, unsigned int baseminor, @@ -2500,14 +2529,14 @@ static inline void unregister_chrdev(unsigned int major, const char *name) #define BDEVT_SIZE 10 /* Largest string for MAJ:MIN for blkdev */ #ifdef CONFIG_BLOCK -#define BLKDEV_MAJOR_HASH_SIZE 255 +#define BLKDEV_MAJOR_MAX 512 extern const char *__bdevname(dev_t, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer); extern struct block_device *lookup_bdev(const char *); extern void blkdev_show(struct seq_file *,off_t); #else -#define BLKDEV_MAJOR_HASH_SIZE 0 +#define BLKDEV_MAJOR_MAX 0 #endif extern void init_special_inode(struct inode *, umode_t, dev_t); @@ -2539,12 +2568,19 @@ extern int invalidate_inode_pages2_range(struct address_space *mapping, extern int write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); extern int filemap_flush(struct address_space *); -extern int filemap_fdatawait(struct address_space *); extern int filemap_fdatawait_keep_errors(struct address_space *mapping); extern int filemap_fdatawait_range(struct address_space *, loff_t lstart, loff_t lend); + +static inline int filemap_fdatawait(struct address_space *mapping) +{ + return filemap_fdatawait_range(mapping, 0, LLONG_MAX); +} + extern bool filemap_range_has_page(struct address_space *, loff_t lstart, loff_t lend); +extern int __must_check file_fdatawait_range(struct file *file, loff_t lstart, + loff_t lend); extern int filemap_write_and_wait(struct address_space *mapping); extern int filemap_write_and_wait_range(struct address_space *mapping, loff_t lstart, loff_t lend); @@ -2553,12 +2589,19 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping, extern int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end); extern int filemap_check_errors(struct address_space *mapping); - extern void __filemap_set_wb_err(struct address_space *mapping, int err); + +extern int __must_check file_fdatawait_range(struct file *file, loff_t lstart, + loff_t lend); extern int __must_check file_check_and_advance_wb_err(struct file *file); extern int __must_check file_write_and_wait_range(struct file *file, loff_t start, loff_t end); +static inline int file_write_and_wait(struct file *file) +{ + return file_write_and_wait_range(file, 0, LLONG_MAX); +} + /** * filemap_set_wb_err - set a writeback error on an address_space * @mapping: mapping in which to set writeback error @@ -2572,8 +2615,6 @@ extern int __must_check file_write_and_wait_range(struct file *file, * When a writeback error occurs, most filesystems will want to call * filemap_set_wb_err to record the error in the mapping so that it will be * automatically reported whenever fsync is called on the file. - * - * FIXME: mention FS_* flag here? */ static inline void filemap_set_wb_err(struct address_space *mapping, int err) { @@ -2772,15 +2813,15 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id) return kernel_read_file_str[id]; } -extern int kernel_read(struct file *, loff_t, char *, unsigned long); extern int kernel_read_file(struct file *, void **, loff_t *, loff_t, enum kernel_read_file_id); -extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t, +extern int kernel_read_file_from_path(const char *, void **, loff_t *, loff_t, enum kernel_read_file_id); extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t, enum kernel_read_file_id); -extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t); -extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); +extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *); +extern ssize_t kernel_write(struct file *, const void *, size_t, loff_t *); +extern ssize_t __kernel_write(struct file *, const void *, size_t, loff_t *); extern struct file * open_exec(const char *); /* fs/dcache.c -- generic fs support functions */ @@ -2831,6 +2872,7 @@ static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { }; #endif extern void unlock_new_inode(struct inode *); extern unsigned int get_next_ino(void); +extern void evict_inodes(struct super_block *sb); extern void __iget(struct inode * inode); extern void iget_failed(struct inode *); @@ -2874,9 +2916,9 @@ extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *); extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos, - int flags); + rwf_t flags); ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos, - int flags); + rwf_t flags); /* fs/block_dev.c */ extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to); @@ -2998,6 +3040,10 @@ void __inode_add_bytes(struct inode *inode, loff_t bytes); void inode_add_bytes(struct inode *inode, loff_t bytes); void __inode_sub_bytes(struct inode *inode, loff_t bytes); void inode_sub_bytes(struct inode *inode, loff_t bytes); +static inline loff_t __inode_get_bytes(struct inode *inode) +{ + return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; +} loff_t inode_get_bytes(struct inode *inode); void inode_set_bytes(struct inode *inode, loff_t bytes); const char *simple_get_link(struct dentry *, struct inode *, @@ -3022,8 +3068,7 @@ static inline int vfs_lstat(const char __user *name, struct kstat *stat) static inline int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int flags) { - return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT, - stat, STATX_BASIC_STATS); + return vfs_statx(dfd, filename, flags, stat, STATX_BASIC_STATS); } static inline int vfs_fstat(int fd, struct kstat *stat) { @@ -3143,13 +3188,13 @@ static inline int iocb_flags(struct file *file) return res; } -static inline int kiocb_set_rw_flags(struct kiocb *ki, int flags) +static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags) { if (unlikely(flags & ~RWF_SUPPORTED)) return -EOPNOTSUPP; if (flags & RWF_NOWAIT) { - if (!(ki->ki_filp->f_mode & FMODE_AIO_NOWAIT)) + if (!(ki->ki_filp->f_mode & FMODE_NOWAIT)) return -EOPNOTSUPP; ki->ki_flags |= IOCB_NOWAIT; } @@ -3274,7 +3319,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode) static inline void inode_has_no_xattr(struct inode *inode) { - if (!is_sxid(inode->i_mode) && (inode->i_sb->s_flags & MS_NOSEC)) + if (!is_sxid(inode->i_mode) && (inode->i_sb->s_flags & SB_NOSEC)) inode->i_flags |= S_NOSEC; } diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 115bb81912ccc8759a54d206487cc8936e2a90c7..f4ff47d4a893a7bd0ef7f4baeef6c29dbee2a9f2 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -143,15 +143,6 @@ struct fscache_cookie_def { void (*mark_page_cached)(void *cookie_netfs_data, struct address_space *mapping, struct page *page); - - /* indicate the cookie is no longer cached - * - this function is called when the backing store currently caching - * a cookie is removed - * - the netfs should use this to clean up any markers indicating - * cached pages - * - this is mandatory for any object that may have data - */ - void (*now_uncached)(void *cookie_netfs_data); }; /* diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 6383115e9d2c5c6459973a1d2d74609aeb438b9f..2e028854bac779c1282b5c7201904ef7194f89a0 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -307,7 +307,7 @@ DECLARE_PER_CPU(int, disable_stack_tracer); static inline void stack_tracer_disable(void) { /* Preemption or interupts must be disabled */ - if (IS_ENABLED(CONFIG_PREEMPT_DEBUG)) + if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)) WARN_ON_ONCE(!preempt_count() || !irqs_disabled()); this_cpu_inc(disable_stack_tracer); } @@ -320,7 +320,7 @@ static inline void stack_tracer_disable(void) */ static inline void stack_tracer_enable(void) { - if (IS_ENABLED(CONFIG_PREEMPT_DEBUG)) + if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)) WARN_ON_ONCE(!preempt_count() || !irqs_disabled()); this_cpu_dec(disable_stack_tracer); } diff --git a/include/linux/futex.h b/include/linux/futex.h index 7c5b694864cd9a52d3c5cd4496e834c4e8c5e7aa..f36bfd26f998a7daccdb4f271c7c3300f567b2a9 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -54,7 +54,6 @@ union futex_key { #ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); -extern void exit_pi_state_list(struct task_struct *curr); #ifdef CONFIG_HAVE_FUTEX_CMPXCHG #define futex_cmpxchg_enabled 1 #else @@ -64,8 +63,14 @@ extern int futex_cmpxchg_enabled; static inline void exit_robust_list(struct task_struct *curr) { } +#endif + +#ifdef CONFIG_FUTEX_PI +extern void exit_pi_state_list(struct task_struct *curr); +#else static inline void exit_pi_state_list(struct task_struct *curr) { } #endif + #endif diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 50893a1646cf3b4cfeeab523caabed50aa119311..0c35b6caf0f6abd5be4eed4fe19266efb7b1254b 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -14,20 +14,9 @@ #include -enum fwnode_type { - FWNODE_INVALID = 0, - FWNODE_OF, - FWNODE_ACPI, - FWNODE_ACPI_DATA, - FWNODE_ACPI_STATIC, - FWNODE_PDATA, - FWNODE_IRQCHIP -}; - struct fwnode_operations; struct fwnode_handle { - enum fwnode_type type; struct fwnode_handle *secondary; const struct fwnode_operations *ops; }; @@ -44,6 +33,20 @@ struct fwnode_endpoint { const struct fwnode_handle *local_fwnode; }; +#define NR_FWNODE_REFERENCE_ARGS 8 + +/** + * struct fwnode_reference_args - Fwnode reference with additional arguments + * @fwnode:- A reference to the base fwnode + * @nargs: Number of elements in @args array + * @args: Integer arguments on the fwnode + */ +struct fwnode_reference_args { + struct fwnode_handle *fwnode; + unsigned int nargs; + unsigned int args[NR_FWNODE_REFERENCE_ARGS]; +}; + /** * struct fwnode_operations - Operations for fwnode interface * @get: Get a reference to an fwnode. @@ -57,6 +60,7 @@ struct fwnode_endpoint { * @get_parent: Return the parent of an fwnode. * @get_next_child_node: Return the next child node in an iteration. * @get_named_child_node: Return a child node with a given name. + * @get_reference_args: Return a reference pointed to by a property, with args * @graph_get_next_endpoint: Return an endpoint node in an iteration. * @graph_get_remote_endpoint: Return the remote endpoint node of a local * endpoint node. @@ -66,30 +70,36 @@ struct fwnode_endpoint { struct fwnode_operations { void (*get)(struct fwnode_handle *fwnode); void (*put)(struct fwnode_handle *fwnode); - bool (*device_is_available)(struct fwnode_handle *fwnode); - bool (*property_present)(struct fwnode_handle *fwnode, + bool (*device_is_available)(const struct fwnode_handle *fwnode); + bool (*property_present)(const struct fwnode_handle *fwnode, const char *propname); - int (*property_read_int_array)(struct fwnode_handle *fwnode, + int (*property_read_int_array)(const struct fwnode_handle *fwnode, const char *propname, unsigned int elem_size, void *val, size_t nval); - int (*property_read_string_array)(struct fwnode_handle *fwnode_handle, - const char *propname, - const char **val, size_t nval); - struct fwnode_handle *(*get_parent)(struct fwnode_handle *fwnode); + int + (*property_read_string_array)(const struct fwnode_handle *fwnode_handle, + const char *propname, const char **val, + size_t nval); + struct fwnode_handle *(*get_parent)(const struct fwnode_handle *fwnode); struct fwnode_handle * - (*get_next_child_node)(struct fwnode_handle *fwnode, + (*get_next_child_node)(const struct fwnode_handle *fwnode, struct fwnode_handle *child); struct fwnode_handle * - (*get_named_child_node)(struct fwnode_handle *fwnode, const char *name); + (*get_named_child_node)(const struct fwnode_handle *fwnode, + const char *name); + int (*get_reference_args)(const struct fwnode_handle *fwnode, + const char *prop, const char *nargs_prop, + unsigned int nargs, unsigned int index, + struct fwnode_reference_args *args); struct fwnode_handle * - (*graph_get_next_endpoint)(struct fwnode_handle *fwnode, + (*graph_get_next_endpoint)(const struct fwnode_handle *fwnode, struct fwnode_handle *prev); struct fwnode_handle * - (*graph_get_remote_endpoint)(struct fwnode_handle *fwnode); + (*graph_get_remote_endpoint)(const struct fwnode_handle *fwnode); struct fwnode_handle * (*graph_get_port_parent)(struct fwnode_handle *fwnode); - int (*graph_parse_endpoint)(struct fwnode_handle *fwnode, + int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint); }; diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 29d4385903d456c274e56d258741fa51002881ce..6dfec4d638df3e7b10811191aba871e421c8d724 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -38,12 +38,13 @@ struct device_node; struct gen_pool; /** - * Allocation callback function type definition + * typedef genpool_algo_t: Allocation callback function type definition * @map: Pointer to bitmap * @size: The bitmap size in bits * @start: The bitnumber to start searching at * @nr: The number of zeroed bits we're looking for - * @data: optional additional data used by @genpool_algo_t + * @data: optional additional data used by the callback + * @pool: the pool being allocated from */ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size, diff --git a/include/linux/genhd.h b/include/linux/genhd.h index e619fae2f0375e073e5f3216fd764676ae1340b8..ea652bfcd6756ff382e54a7f209043d9217e3608 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -362,24 +362,12 @@ static inline void free_part_stats(struct hd_struct *part) #define part_stat_sub(cpu, gendiskp, field, subnd) \ part_stat_add(cpu, gendiskp, field, -subnd) -static inline void part_inc_in_flight(struct hd_struct *part, int rw) -{ - atomic_inc(&part->in_flight[rw]); - if (part->partno) - atomic_inc(&part_to_disk(part)->part0.in_flight[rw]); -} - -static inline void part_dec_in_flight(struct hd_struct *part, int rw) -{ - atomic_dec(&part->in_flight[rw]); - if (part->partno) - atomic_dec(&part_to_disk(part)->part0.in_flight[rw]); -} - -static inline int part_in_flight(struct hd_struct *part) -{ - return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]); -} +void part_in_flight(struct request_queue *q, struct hd_struct *part, + unsigned int inflight[2]); +void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, + int rw); +void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, + int rw); static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk) { @@ -395,7 +383,7 @@ static inline void free_part_info(struct hd_struct *part) } /* block/blk-core.c */ -extern void part_round_stats(int cpu, struct hd_struct *part); +extern void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part); /* block/genhd.c */ extern void device_add_disk(struct device *parent, struct gendisk *disk); diff --git a/include/linux/gfp.h b/include/linux/gfp.h index bcfb9f7c46f5dc3d1d8f6d8f2f454e09243a610d..f780718b7391d40999962bed20621c2b8b0cca21 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -288,8 +288,6 @@ struct vm_area_struct; #define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) #define GFP_NOIO (__GFP_RECLAIM) #define GFP_NOFS (__GFP_RECLAIM | __GFP_IO) -#define GFP_TEMPORARY (__GFP_RECLAIM | __GFP_IO | __GFP_FS | \ - __GFP_RECLAIMABLE) #define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL) #define GFP_DMA __GFP_DMA #define GFP_DMA32 __GFP_DMA32 diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index af20369ec8e7b573dec63dcf77346ddd75e4e332..c97f8325e8bf5c2f4d309b1e8e82b69d62e68bfc 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -180,8 +180,27 @@ struct gpio_chip { * If CONFIG_OF is enabled, then all GPIO controllers described in the * device tree automatically may have an OF translation */ + + /** + * @of_node: + * + * Pointer to a device tree node representing this GPIO controller. + */ struct device_node *of_node; - int of_gpio_n_cells; + + /** + * @of_gpio_n_cells: + * + * Number of cells used to form the GPIO specifier. + */ + unsigned int of_gpio_n_cells; + + /** + * @of_xlate: + * + * Callback to translate a device tree GPIO specifier into a chip- + * relative GPIO number and flags. + */ int (*of_xlate)(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); #endif @@ -327,11 +346,10 @@ int gpiochip_generic_config(struct gpio_chip *chip, unsigned offset, /** * struct gpio_pin_range - pin range controlled by a gpio chip - * @head: list for maintaining set of pin ranges, used internally + * @node: list for maintaining set of pin ranges, used internally * @pctldev: pinctrl device which handles corresponding pins * @range: actual range of pins controlled by a gpio controller */ - struct gpio_pin_range { struct list_head node; struct pinctrl_dev *pctldev; diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index 6e76b16fcadeb15bf78e92f3ff5b57c5cf397ec3..ba4ccfd900f91cafe1721a6a633c30b967bf9475 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -60,11 +60,14 @@ struct gpiod_lookup_table { #ifdef CONFIG_GPIOLIB void gpiod_add_lookup_table(struct gpiod_lookup_table *table); +void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n); void gpiod_remove_lookup_table(struct gpiod_lookup_table *table); #else static inline void gpiod_add_lookup_table(struct gpiod_lookup_table *table) {} static inline +void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n) {} +static inline void gpiod_remove_lookup_table(struct gpiod_lookup_table *table) {} #endif diff --git a/include/linux/hid.h b/include/linux/hid.h index 5006f9b5d83701a77529988644cd9b018485bf7b..ab05a86269dc1770181340b8b21c460d83412cb9 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -173,6 +173,7 @@ struct hid_item { #define HID_UP_LOGIVENDOR3 0xff430000 #define HID_UP_LNVENDOR 0xffa00000 #define HID_UP_SENSOR 0x00200000 +#define HID_UP_ASUSVENDOR 0xff310000 #define HID_USAGE 0x0000ffff @@ -292,6 +293,7 @@ struct hid_item { #define HID_DG_BARRELSWITCH2 0x000d005a #define HID_DG_TOOLSERIALNUMBER 0x000d005b +#define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 /* * HID report types --- Ouch! HID spec says 1 2 3! */ @@ -362,6 +364,12 @@ struct hid_item { #define HID_GROUP_WACOM 0x0101 #define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102 +/* + * HID protocol status + */ +#define HID_REPORT_PROTOCOL 1 +#define HID_BOOT_PROTOCOL 0 + /* * This is the global environment of the parser. This information is * persistent for main-items. The global environment can be saved and @@ -526,7 +534,6 @@ struct hid_device { /* device report descriptor */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; struct work_struct led_work; /* delayed LED worker */ - struct semaphore driver_lock; /* protects the current driver, except during input */ struct semaphore driver_input_lock; /* protects the current driver */ struct device dev; /* device */ struct hid_driver *driver; @@ -542,16 +549,18 @@ struct hid_device { /* device report descriptor */ * battery is non-NULL. */ struct power_supply *battery; + __s32 battery_capacity; __s32 battery_min; __s32 battery_max; __s32 battery_report_type; __s32 battery_report_id; + bool battery_reported; #endif unsigned int status; /* see STAT flags above */ unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned quirks; /* Various quirks the device can pull on us */ - bool io_started; /* Protected by driver_lock. If IO has started */ + bool io_started; /* If IO has started */ struct list_head inputs; /* The list of inputs */ void *hiddev; /* The hiddev structure */ @@ -777,6 +786,17 @@ struct hid_ll_driver { int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); }; +extern struct hid_ll_driver i2c_hid_ll_driver; +extern struct hid_ll_driver hidp_hid_driver; +extern struct hid_ll_driver uhid_hid_driver; +extern struct hid_ll_driver usb_hid_driver; + +static inline bool hid_is_using_ll_driver(struct hid_device *hdev, + struct hid_ll_driver *driver) +{ + return hdev->ll_driver == driver; +} + #define PM_HINT_FULLON 1<<5 #define PM_HINT_NORMAL 1<<1 diff --git a/include/linux/hmm.h b/include/linux/hmm.h new file mode 100644 index 0000000000000000000000000000000000000000..96e69979f84d7b7fe1edb6568097bf32cec97a92 --- /dev/null +++ b/include/linux/hmm.h @@ -0,0 +1,520 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: Jérôme Glisse + */ +/* + * Heterogeneous Memory Management (HMM) + * + * See Documentation/vm/hmm.txt for reasons and overview of what HMM is and it + * is for. Here we focus on the HMM API description, with some explanation of + * the underlying implementation. + * + * Short description: HMM provides a set of helpers to share a virtual address + * space between CPU and a device, so that the device can access any valid + * address of the process (while still obeying memory protection). HMM also + * provides helpers to migrate process memory to device memory, and back. Each + * set of functionality (address space mirroring, and migration to and from + * device memory) can be used independently of the other. + * + * + * HMM address space mirroring API: + * + * Use HMM address space mirroring if you want to mirror range of the CPU page + * table of a process into a device page table. Here, "mirror" means "keep + * synchronized". Prerequisites: the device must provide the ability to write- + * protect its page tables (at PAGE_SIZE granularity), and must be able to + * recover from the resulting potential page faults. + * + * HMM guarantees that at any point in time, a given virtual address points to + * either the same memory in both CPU and device page tables (that is: CPU and + * device page tables each point to the same pages), or that one page table (CPU + * or device) points to no entry, while the other still points to the old page + * for the address. The latter case happens when the CPU page table update + * happens first, and then the update is mirrored over to the device page table. + * This does not cause any issue, because the CPU page table cannot start + * pointing to a new page until the device page table is invalidated. + * + * HMM uses mmu_notifiers to monitor the CPU page tables, and forwards any + * updates to each device driver that has registered a mirror. It also provides + * some API calls to help with taking a snapshot of the CPU page table, and to + * synchronize with any updates that might happen concurrently. + * + * + * HMM migration to and from device memory: + * + * HMM provides a set of helpers to hotplug device memory as ZONE_DEVICE, with + * a new MEMORY_DEVICE_PRIVATE type. This provides a struct page for each page + * of the device memory, and allows the device driver to manage its memory + * using those struct pages. Having struct pages for device memory makes + * migration easier. Because that memory is not addressable by the CPU it must + * never be pinned to the device; in other words, any CPU page fault can always + * cause the device memory to be migrated (copied/moved) back to regular memory. + * + * A new migrate helper (migrate_vma()) has been added (see mm/migrate.c) that + * allows use of a device DMA engine to perform the copy operation between + * regular system memory and device memory. + */ +#ifndef LINUX_HMM_H +#define LINUX_HMM_H + +#include + +#if IS_ENABLED(CONFIG_HMM) + +#include +#include +#include +#include + +struct hmm; + +/* + * hmm_pfn_t - HMM uses its own pfn type to keep several flags per page + * + * Flags: + * HMM_PFN_VALID: pfn is valid + * HMM_PFN_READ: CPU page table has read permission set + * HMM_PFN_WRITE: CPU page table has write permission set + * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned memory + * HMM_PFN_EMPTY: corresponding CPU page table entry is pte_none() + * HMM_PFN_SPECIAL: corresponding CPU page table entry is special; i.e., the + * result of vm_insert_pfn() or vm_insert_page(). Therefore, it should not + * be mirrored by a device, because the entry will never have HMM_PFN_VALID + * set and the pfn value is undefined. + * HMM_PFN_DEVICE_UNADDRESSABLE: unaddressable device memory (ZONE_DEVICE) + */ +typedef unsigned long hmm_pfn_t; + +#define HMM_PFN_VALID (1 << 0) +#define HMM_PFN_READ (1 << 1) +#define HMM_PFN_WRITE (1 << 2) +#define HMM_PFN_ERROR (1 << 3) +#define HMM_PFN_EMPTY (1 << 4) +#define HMM_PFN_SPECIAL (1 << 5) +#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 6) +#define HMM_PFN_SHIFT 7 + +/* + * hmm_pfn_t_to_page() - return struct page pointed to by a valid hmm_pfn_t + * @pfn: hmm_pfn_t to convert to struct page + * Returns: struct page pointer if pfn is a valid hmm_pfn_t, NULL otherwise + * + * If the hmm_pfn_t is valid (ie valid flag set) then return the struct page + * matching the pfn value stored in the hmm_pfn_t. Otherwise return NULL. + */ +static inline struct page *hmm_pfn_t_to_page(hmm_pfn_t pfn) +{ + if (!(pfn & HMM_PFN_VALID)) + return NULL; + return pfn_to_page(pfn >> HMM_PFN_SHIFT); +} + +/* + * hmm_pfn_t_to_pfn() - return pfn value store in a hmm_pfn_t + * @pfn: hmm_pfn_t to extract pfn from + * Returns: pfn value if hmm_pfn_t is valid, -1UL otherwise + */ +static inline unsigned long hmm_pfn_t_to_pfn(hmm_pfn_t pfn) +{ + if (!(pfn & HMM_PFN_VALID)) + return -1UL; + return (pfn >> HMM_PFN_SHIFT); +} + +/* + * hmm_pfn_t_from_page() - create a valid hmm_pfn_t value from struct page + * @page: struct page pointer for which to create the hmm_pfn_t + * Returns: valid hmm_pfn_t for the page + */ +static inline hmm_pfn_t hmm_pfn_t_from_page(struct page *page) +{ + return (page_to_pfn(page) << HMM_PFN_SHIFT) | HMM_PFN_VALID; +} + +/* + * hmm_pfn_t_from_pfn() - create a valid hmm_pfn_t value from pfn + * @pfn: pfn value for which to create the hmm_pfn_t + * Returns: valid hmm_pfn_t for the pfn + */ +static inline hmm_pfn_t hmm_pfn_t_from_pfn(unsigned long pfn) +{ + return (pfn << HMM_PFN_SHIFT) | HMM_PFN_VALID; +} + + +#if IS_ENABLED(CONFIG_HMM_MIRROR) +/* + * Mirroring: how to synchronize device page table with CPU page table. + * + * A device driver that is participating in HMM mirroring must always + * synchronize with CPU page table updates. For this, device drivers can either + * directly use mmu_notifier APIs or they can use the hmm_mirror API. Device + * drivers can decide to register one mirror per device per process, or just + * one mirror per process for a group of devices. The pattern is: + * + * int device_bind_address_space(..., struct mm_struct *mm, ...) + * { + * struct device_address_space *das; + * + * // Device driver specific initialization, and allocation of das + * // which contains an hmm_mirror struct as one of its fields. + * ... + * + * ret = hmm_mirror_register(&das->mirror, mm, &device_mirror_ops); + * if (ret) { + * // Cleanup on error + * return ret; + * } + * + * // Other device driver specific initialization + * ... + * } + * + * Once an hmm_mirror is registered for an address space, the device driver + * will get callbacks through sync_cpu_device_pagetables() operation (see + * hmm_mirror_ops struct). + * + * Device driver must not free the struct containing the hmm_mirror struct + * before calling hmm_mirror_unregister(). The expected usage is to do that when + * the device driver is unbinding from an address space. + * + * + * void device_unbind_address_space(struct device_address_space *das) + * { + * // Device driver specific cleanup + * ... + * + * hmm_mirror_unregister(&das->mirror); + * + * // Other device driver specific cleanup, and now das can be freed + * ... + * } + */ + +struct hmm_mirror; + +/* + * enum hmm_update_type - type of update + * @HMM_UPDATE_INVALIDATE: invalidate range (no indication as to why) + */ +enum hmm_update_type { + HMM_UPDATE_INVALIDATE, +}; + +/* + * struct hmm_mirror_ops - HMM mirror device operations callback + * + * @update: callback to update range on a device + */ +struct hmm_mirror_ops { + /* sync_cpu_device_pagetables() - synchronize page tables + * + * @mirror: pointer to struct hmm_mirror + * @update_type: type of update that occurred to the CPU page table + * @start: virtual start address of the range to update + * @end: virtual end address of the range to update + * + * This callback ultimately originates from mmu_notifiers when the CPU + * page table is updated. The device driver must update its page table + * in response to this callback. The update argument tells what action + * to perform. + * + * The device driver must not return from this callback until the device + * page tables are completely updated (TLBs flushed, etc); this is a + * synchronous call. + */ + void (*sync_cpu_device_pagetables)(struct hmm_mirror *mirror, + enum hmm_update_type update_type, + unsigned long start, + unsigned long end); +}; + +/* + * struct hmm_mirror - mirror struct for a device driver + * + * @hmm: pointer to struct hmm (which is unique per mm_struct) + * @ops: device driver callback for HMM mirror operations + * @list: for list of mirrors of a given mm + * + * Each address space (mm_struct) being mirrored by a device must register one + * instance of an hmm_mirror struct with HMM. HMM will track the list of all + * mirrors for each mm_struct. + */ +struct hmm_mirror { + struct hmm *hmm; + const struct hmm_mirror_ops *ops; + struct list_head list; +}; + +int hmm_mirror_register(struct hmm_mirror *mirror, struct mm_struct *mm); +void hmm_mirror_unregister(struct hmm_mirror *mirror); + + +/* + * struct hmm_range - track invalidation lock on virtual address range + * + * @list: all range lock are on a list + * @start: range virtual start address (inclusive) + * @end: range virtual end address (exclusive) + * @pfns: array of pfns (big enough for the range) + * @valid: pfns array did not change since it has been fill by an HMM function + */ +struct hmm_range { + struct list_head list; + unsigned long start; + unsigned long end; + hmm_pfn_t *pfns; + bool valid; +}; + +/* + * To snapshot the CPU page table, call hmm_vma_get_pfns(), then take a device + * driver lock that serializes device page table updates, then call + * hmm_vma_range_done(), to check if the snapshot is still valid. The same + * device driver page table update lock must also be used in the + * hmm_mirror_ops.sync_cpu_device_pagetables() callback, so that CPU page + * table invalidation serializes on it. + * + * YOU MUST CALL hmm_vma_range_done() ONCE AND ONLY ONCE EACH TIME YOU CALL + * hmm_vma_get_pfns() WITHOUT ERROR ! + * + * IF YOU DO NOT FOLLOW THE ABOVE RULE THE SNAPSHOT CONTENT MIGHT BE INVALID ! + */ +int hmm_vma_get_pfns(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns); +bool hmm_vma_range_done(struct vm_area_struct *vma, struct hmm_range *range); + + +/* + * Fault memory on behalf of device driver. Unlike handle_mm_fault(), this will + * not migrate any device memory back to system memory. The hmm_pfn_t array will + * be updated with the fault result and current snapshot of the CPU page table + * for the range. + * + * The mmap_sem must be taken in read mode before entering and it might be + * dropped by the function if the block argument is false. In that case, the + * function returns -EAGAIN. + * + * Return value does not reflect if the fault was successful for every single + * address or not. Therefore, the caller must to inspect the hmm_pfn_t array to + * determine fault status for each address. + * + * Trying to fault inside an invalid vma will result in -EINVAL. + * + * See the function description in mm/hmm.c for further documentation. + */ +int hmm_vma_fault(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns, + bool write, + bool block); +#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ + + +#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC) +struct hmm_devmem; + +struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma, + unsigned long addr); + +/* + * struct hmm_devmem_ops - callback for ZONE_DEVICE memory events + * + * @free: call when refcount on page reach 1 and thus is no longer use + * @fault: call when there is a page fault to unaddressable memory + * + * Both callback happens from page_free() and page_fault() callback of struct + * dev_pagemap respectively. See include/linux/memremap.h for more details on + * those. + * + * The hmm_devmem_ops callback are just here to provide a coherent and + * uniq API to device driver and device driver should not register their + * own page_free() or page_fault() but rely on the hmm_devmem_ops call- + * back. + */ +struct hmm_devmem_ops { + /* + * free() - free a device page + * @devmem: device memory structure (see struct hmm_devmem) + * @page: pointer to struct page being freed + * + * Call back occurs whenever a device page refcount reach 1 which + * means that no one is holding any reference on the page anymore + * (ZONE_DEVICE page have an elevated refcount of 1 as default so + * that they are not release to the general page allocator). + * + * Note that callback has exclusive ownership of the page (as no + * one is holding any reference). + */ + void (*free)(struct hmm_devmem *devmem, struct page *page); + /* + * fault() - CPU page fault or get user page (GUP) + * @devmem: device memory structure (see struct hmm_devmem) + * @vma: virtual memory area containing the virtual address + * @addr: virtual address that faulted or for which there is a GUP + * @page: pointer to struct page backing virtual address (unreliable) + * @flags: FAULT_FLAG_* (see include/linux/mm.h) + * @pmdp: page middle directory + * Returns: VM_FAULT_MINOR/MAJOR on success or one of VM_FAULT_ERROR + * on error + * + * The callback occurs whenever there is a CPU page fault or GUP on a + * virtual address. This means that the device driver must migrate the + * page back to regular memory (CPU accessible). + * + * The device driver is free to migrate more than one page from the + * fault() callback as an optimization. However if device decide to + * migrate more than one page it must always priotirize the faulting + * address over the others. + * + * The struct page pointer is only given as an hint to allow quick + * lookup of internal device driver data. A concurrent migration + * might have already free that page and the virtual address might + * not longer be back by it. So it should not be modified by the + * callback. + * + * Note that mmap semaphore is held in read mode at least when this + * callback occurs, hence the vma is valid upon callback entry. + */ + int (*fault)(struct hmm_devmem *devmem, + struct vm_area_struct *vma, + unsigned long addr, + const struct page *page, + unsigned int flags, + pmd_t *pmdp); +}; + +/* + * struct hmm_devmem - track device memory + * + * @completion: completion object for device memory + * @pfn_first: first pfn for this resource (set by hmm_devmem_add()) + * @pfn_last: last pfn for this resource (set by hmm_devmem_add()) + * @resource: IO resource reserved for this chunk of memory + * @pagemap: device page map for that chunk + * @device: device to bind resource to + * @ops: memory operations callback + * @ref: per CPU refcount + * + * This an helper structure for device drivers that do not wish to implement + * the gory details related to hotplugging new memoy and allocating struct + * pages. + * + * Device drivers can directly use ZONE_DEVICE memory on their own if they + * wish to do so. + */ +struct hmm_devmem { + struct completion completion; + unsigned long pfn_first; + unsigned long pfn_last; + struct resource *resource; + struct device *device; + struct dev_pagemap pagemap; + const struct hmm_devmem_ops *ops; + struct percpu_ref ref; +}; + +/* + * To add (hotplug) device memory, HMM assumes that there is no real resource + * that reserves a range in the physical address space (this is intended to be + * use by unaddressable device memory). It will reserve a physical range big + * enough and allocate struct page for it. + * + * The device driver can wrap the hmm_devmem struct inside a private device + * driver struct. The device driver must call hmm_devmem_remove() before the + * device goes away and before freeing the hmm_devmem struct memory. + */ +struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, + struct device *device, + unsigned long size); +struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops, + struct device *device, + struct resource *res); +void hmm_devmem_remove(struct hmm_devmem *devmem); + +/* + * hmm_devmem_page_set_drvdata - set per-page driver data field + * + * @page: pointer to struct page + * @data: driver data value to set + * + * Because page can not be on lru we have an unsigned long that driver can use + * to store a per page field. This just a simple helper to do that. + */ +static inline void hmm_devmem_page_set_drvdata(struct page *page, + unsigned long data) +{ + unsigned long *drvdata = (unsigned long *)&page->pgmap; + + drvdata[1] = data; +} + +/* + * hmm_devmem_page_get_drvdata - get per page driver data field + * + * @page: pointer to struct page + * Return: driver data value + */ +static inline unsigned long hmm_devmem_page_get_drvdata(struct page *page) +{ + unsigned long *drvdata = (unsigned long *)&page->pgmap; + + return drvdata[1]; +} + + +/* + * struct hmm_device - fake device to hang device memory onto + * + * @device: device struct + * @minor: device minor number + */ +struct hmm_device { + struct device device; + unsigned int minor; +}; + +/* + * A device driver that wants to handle multiple devices memory through a + * single fake device can use hmm_device to do so. This is purely a helper and + * it is not strictly needed, in order to make use of any HMM functionality. + */ +struct hmm_device *hmm_device_new(void *drvdata); +void hmm_device_put(struct hmm_device *hmm_device); +#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ +#endif /* IS_ENABLED(CONFIG_HMM) */ + +/* Below are for HMM internal use only! Not to be used by device driver! */ +#if IS_ENABLED(CONFIG_HMM_MIRROR) +void hmm_mm_destroy(struct mm_struct *mm); + +static inline void hmm_mm_init(struct mm_struct *mm) +{ + mm->hmm = NULL; +} +#else /* IS_ENABLED(CONFIG_HMM_MIRROR) */ +static inline void hmm_mm_destroy(struct mm_struct *mm) {} +static inline void hmm_mm_init(struct mm_struct *mm) {} +#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ + + +#else /* IS_ENABLED(CONFIG_HMM) */ +static inline void hmm_mm_destroy(struct mm_struct *mm) {} +static inline void hmm_mm_init(struct mm_struct *mm) {} +#endif /* LINUX_HMM_H */ diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index ee696347f928ffc7b0aac51e3c6e1180c11265c9..14bc21c2ee7ff8d9c7956b9c317d4a39b36cc0c0 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -147,7 +147,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, #define split_huge_pmd(__vma, __pmd, __address) \ do { \ pmd_t *____pmd = (__pmd); \ - if (pmd_trans_huge(*____pmd) \ + if (is_swap_pmd(*____pmd) || pmd_trans_huge(*____pmd) \ || pmd_devmap(*____pmd)) \ __split_huge_pmd(__vma, __pmd, __address, \ false, NULL); \ @@ -178,12 +178,18 @@ extern spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma); extern spinlock_t *__pud_trans_huge_lock(pud_t *pud, struct vm_area_struct *vma); + +static inline int is_swap_pmd(pmd_t pmd) +{ + return !pmd_none(pmd) && !pmd_present(pmd); +} + /* mmap_sem must be held on entry */ static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma) { VM_BUG_ON_VMA(!rwsem_is_locked(&vma->vm_mm->mmap_sem), vma); - if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) + if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) return __pmd_trans_huge_lock(pmd, vma); else return NULL; @@ -233,6 +239,11 @@ void mm_put_huge_zero_page(struct mm_struct *mm); #define mk_huge_pmd(page, prot) pmd_mkhuge(mk_pmd(page, prot)) +static inline bool thp_migration_supported(void) +{ + return IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION); +} + #else /* CONFIG_TRANSPARENT_HUGEPAGE */ #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; }) #define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; }) @@ -294,6 +305,10 @@ static inline void vma_adjust_trans_huge(struct vm_area_struct *vma, long adjust_next) { } +static inline int is_swap_pmd(pmd_t pmd) +{ + return 0; +} static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma) { @@ -336,6 +351,11 @@ static inline struct page *follow_devmap_pud(struct vm_area_struct *vma, { return NULL; } + +static inline bool thp_migration_supported(void) +{ + return false; +} #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif /* _LINUX_HUGE_MM_H */ diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 0ed8e41aaf1173d3722a058f3be7c01828ca9284..8bbbd37ab10508571f634203469680090dd435b8 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -358,6 +358,7 @@ int huge_add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t idx); /* arch callback */ +int __init __alloc_bootmem_huge_page(struct hstate *h); int __init alloc_bootmem_huge_page(struct hstate *h); void __init hugetlb_bad_size(void); diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b7d7bbec74e044a56b10b49eff12d380206dcd32..c458d7b7ad197688469772fb0c842180c668864c 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -124,10 +124,7 @@ struct hv_ring_buffer_info { spinlock_t ring_lock; u32 ring_datasize; /* < ring_size */ - u32 ring_data_startoffset; - u32 priv_write_index; u32 priv_read_index; - u32 cached_read_index; }; /* @@ -180,19 +177,6 @@ static inline u32 hv_get_bytes_to_write(const struct hv_ring_buffer_info *rbi) return write; } -static inline u32 hv_get_cached_bytes_to_write( - const struct hv_ring_buffer_info *rbi) -{ - u32 read_loc, write_loc, dsize, write; - - dsize = rbi->ring_datasize; - read_loc = rbi->cached_read_index; - write_loc = rbi->ring_buffer->write_index; - - write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : - read_loc - write_loc; - return write; -} /* * VMBUS version is 32 bit entity broken up into * two 16 bit quantities: major_number. minor_number. @@ -677,18 +661,6 @@ union hv_connection_id { } u; }; -/* Definition of the hv_signal_event hypercall input structure. */ -struct hv_input_signal_event { - union hv_connection_id connectionid; - u16 flag_number; - u16 rsvdz; -}; - -struct hv_input_signal_event_buffer { - u64 align8; - struct hv_input_signal_event event; -}; - enum hv_numa_policy { HV_BALANCED = 0, HV_LOCALIZED, @@ -770,8 +742,7 @@ struct vmbus_channel { } callback_mode; bool is_dedicated_interrupt; - struct hv_input_signal_event_buffer sig_buf; - struct hv_input_signal_event *sig_event; + u64 sig_event; /* * Starting with win8, this field will be used to specify @@ -895,6 +866,8 @@ struct vmbus_channel { */ enum hv_numa_policy affinity_policy; + bool probe_done; + }; static inline bool is_hvsock_channel(const struct vmbus_channel *c) @@ -1030,13 +1003,6 @@ extern int vmbus_sendpacket(struct vmbus_channel *channel, enum vmbus_packet_type type, u32 flags); -extern int vmbus_sendpacket_ctl(struct vmbus_channel *channel, - void *buffer, - u32 bufferLen, - u64 requestid, - enum vmbus_packet_type type, - u32 flags); - extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, struct hv_page_buffer pagebuffers[], u32 pagecount, @@ -1044,20 +1010,6 @@ extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, u32 bufferlen, u64 requestid); -extern int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, - struct hv_page_buffer pagebuffers[], - u32 pagecount, - void *buffer, - u32 bufferlen, - u64 requestid, - u32 flags); - -extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, - struct hv_multipage_buffer *mpb, - void *buffer, - u32 bufferlen, - u64 requestid); - extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, struct vmbus_packet_mpb_array *mpb, u32 desc_size, @@ -1186,8 +1138,6 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, resource_size_t size, resource_size_t align, bool fb_overlap_ok); void vmbus_free_mmio(resource_size_t start, resource_size_t size); -int vmbus_cpu_number_to_vp_number(int cpu_number); -u64 hv_do_hypercall(u64 control, void *input, void *output); /* * GUID definitions of various offer types - services offered to the guest. @@ -1473,55 +1423,6 @@ hv_get_ring_buffer(const struct hv_ring_buffer_info *ring_info) return ring_info->ring_buffer->buffer; } -/* - * To optimize the flow management on the send-side, - * when the sender is blocked because of lack of - * sufficient space in the ring buffer, potential the - * consumer of the ring buffer can signal the producer. - * This is controlled by the following parameters: - * - * 1. pending_send_sz: This is the size in bytes that the - * producer is trying to send. - * 2. The feature bit feat_pending_send_sz set to indicate if - * the consumer of the ring will signal when the ring - * state transitions from being full to a state where - * there is room for the producer to send the pending packet. - */ - -static inline void hv_signal_on_read(struct vmbus_channel *channel) -{ - u32 cur_write_sz, cached_write_sz; - u32 pending_sz; - struct hv_ring_buffer_info *rbi = &channel->inbound; - - /* - * Issue a full memory barrier before making the signaling decision. - * Here is the reason for having this barrier: - * If the reading of the pend_sz (in this function) - * were to be reordered and read before we commit the new read - * index (in the calling function) we could - * have a problem. If the host were to set the pending_sz after we - * have sampled pending_sz and go to sleep before we commit the - * read index, we could miss sending the interrupt. Issue a full - * memory barrier to address this. - */ - virt_mb(); - - pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz); - /* If the other end is not blocked on write don't bother. */ - if (pending_sz == 0) - return; - - cur_write_sz = hv_get_bytes_to_write(rbi); - - if (cur_write_sz < pending_sz) - return; - - cached_write_sz = hv_get_cached_bytes_to_write(rbi); - if (cached_write_sz < pending_sz) - vmbus_setevent(channel); -} - /* * Mask off host interrupt callback notifications */ diff --git a/include/linux/i2c-mux-pinctrl.h b/include/linux/i2c-mux-pinctrl.h deleted file mode 100644 index a65c86429e845bb2f971d0b142cddf54a24f6334..0000000000000000000000000000000000000000 --- a/include/linux/i2c-mux-pinctrl.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * i2c-mux-pinctrl platform data - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _LINUX_I2C_MUX_PINCTRL_H -#define _LINUX_I2C_MUX_PINCTRL_H - -/** - * struct i2c_mux_pinctrl_platform_data - Platform data for i2c-mux-pinctrl - * @parent_bus_num: Parent I2C bus number - * @base_bus_num: Base I2C bus number for the child busses. 0 for dynamic. - * @bus_count: Number of child busses. Also the number of elements in - * @pinctrl_states - * @pinctrl_states: The names of the pinctrl state to select for each child bus - * @pinctrl_state_idle: The pinctrl state to select when no child bus is being - * accessed. If NULL, the most recently used pinctrl state will be left - * selected. - */ -struct i2c_mux_pinctrl_platform_data { - int parent_bus_num; - int base_bus_num; - int bus_count; - const char **pinctrl_states; - const char *pinctrl_state_idle; -}; - -#endif diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 00ca5b86a753f8023cad87ce02cbe90748255383..d501d3956f13f041864dc25f0d7e8724ea2b5210 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -689,7 +689,8 @@ i2c_unlock_adapter(struct i2c_adapter *adapter) #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ #define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ #define I2C_CLASS_SPD (1<<7) /* Memory modules */ -#define I2C_CLASS_DEPRECATED (1<<8) /* Warn users that adapter will stop using classes */ +/* Warn users that the adapter doesn't support classes anymore */ +#define I2C_CLASS_DEPRECATED (1<<8) /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU diff --git a/include/linux/i2c/bfin_twi.h b/include/linux/i2c/bfin_twi.h deleted file mode 100644 index 135a4e0876aeba09080c4546214e286a48173bdd..0000000000000000000000000000000000000000 --- a/include/linux/i2c/bfin_twi.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * i2c-bfin-twi.h - interface to ADI TWI controller - * - * Copyright 2005-2014 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __I2C_BFIN_TWI_H__ -#define __I2C_BFIN_TWI_H__ - -#include -#include - -/* - * ADI twi registers layout - */ -struct bfin_twi_regs { - u16 clkdiv; - u16 dummy1; - u16 control; - u16 dummy2; - u16 slave_ctl; - u16 dummy3; - u16 slave_stat; - u16 dummy4; - u16 slave_addr; - u16 dummy5; - u16 master_ctl; - u16 dummy6; - u16 master_stat; - u16 dummy7; - u16 master_addr; - u16 dummy8; - u16 int_stat; - u16 dummy9; - u16 int_mask; - u16 dummy10; - u16 fifo_ctl; - u16 dummy11; - u16 fifo_stat; - u16 dummy12; - u32 __pad[20]; - u16 xmt_data8; - u16 dummy13; - u16 xmt_data16; - u16 dummy14; - u16 rcv_data8; - u16 dummy15; - u16 rcv_data16; - u16 dummy16; -}; - -struct bfin_twi_iface { - int irq; - spinlock_t lock; - char read_write; - u8 command; - u8 *transPtr; - int readNum; - int writeNum; - int cur_mode; - int manual_stop; - int result; - struct i2c_adapter adap; - struct completion complete; - struct i2c_msg *pmsg; - int msg_num; - int cur_msg; - u16 saved_clkdiv; - u16 saved_control; - struct bfin_twi_regs __iomem *regs_base; -}; - -/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ********************/ -/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ -#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ - -/* TWI_PRESCALE Masks */ -#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ -#define TWI_ENA 0x0080 /* TWI Enable */ -#define SCCB 0x0200 /* SCCB Compatibility Enable */ - -/* TWI_SLAVE_CTL Masks */ -#define SEN 0x0001 /* Slave Enable */ -#define SADD_LEN 0x0002 /* Slave Address Length */ -#define STDVAL 0x0004 /* Slave Transmit Data Valid */ -#define NAK 0x0008 /* NAK Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Address Matching Enabled */ - -/* TWI_SLAVE_STAT Masks */ -#define SDIR 0x0001 /* Slave Transfer Direction (RX/TX*) */ -#define GCALL 0x0002 /* General Call Indicator */ - -/* TWI_MASTER_CTL Masks */ -#define MEN 0x0001 /* Master Mode Enable */ -#define MADD_LEN 0x0002 /* Master Address Length */ -#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ -#define FAST 0x0008 /* Use Fast Mode Timing Specs */ -#define STOP 0x0010 /* Issue Stop Condition */ -#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ -#define DCNT 0x3FC0 /* Data Bytes To Transfer */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* TWI_MASTER_STAT Masks */ -#define MPROG 0x0001 /* Master Transfer In Progress */ -#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ -#define ANAK 0x0004 /* Address Not Acknowledged */ -#define DNAK 0x0008 /* Data Not Acknowledged */ -#define BUFRDERR 0x0010 /* Buffer Read Error */ -#define BUFWRERR 0x0020 /* Buffer Write Error */ -#define SDASEN 0x0040 /* Serial Data Sense */ -#define SCLSEN 0x0080 /* Serial Clock Sense */ -#define BUSBUSY 0x0100 /* Bus Busy Indicator */ - -/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ -#define SINIT 0x0001 /* Slave Transfer Initiated */ -#define SCOMP 0x0002 /* Slave Transfer Complete */ -#define SERR 0x0004 /* Slave Transfer Error */ -#define SOVF 0x0008 /* Slave Overflow */ -#define MCOMP 0x0010 /* Master Transfer Complete */ -#define MERR 0x0020 /* Master Transfer Error */ -#define XMTSERV 0x0040 /* Transmit FIFO Service */ -#define RCVSERV 0x0080 /* Receive FIFO Service */ - -/* TWI_FIFO_CTRL Masks */ -#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ -#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ - -/* TWI_FIFO_STAT Masks */ -#define XMTSTAT 0x0003 /* Transmit FIFO Status */ -#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ -#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ -#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ - -#define RCVSTAT 0x000C /* Receive FIFO Status */ -#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ -#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ -#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ - -#endif diff --git a/include/linux/idr.h b/include/linux/idr.h index bf70b3ef0a073bbcb301ddf0141d90e8ac6fa018..7c3a365f7e127ac29cfedc6b5debe81eb87abe74 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -80,19 +80,75 @@ static inline void idr_set_cursor(struct idr *idr, unsigned int val) */ void idr_preload(gfp_t gfp_mask); -int idr_alloc(struct idr *, void *entry, int start, int end, gfp_t); + +int idr_alloc_cmn(struct idr *idr, void *ptr, unsigned long *index, + unsigned long start, unsigned long end, gfp_t gfp, + bool ext); + +/** + * idr_alloc - allocate an id + * @idr: idr handle + * @ptr: pointer to be associated with the new id + * @start: the minimum id (inclusive) + * @end: the maximum id (exclusive) + * @gfp: memory allocation flags + * + * Allocates an unused ID in the range [start, end). Returns -ENOSPC + * if there are no unused IDs in that range. + * + * Note that @end is treated as max when <= 0. This is to always allow + * using @start + N as @end as long as N is inside integer range. + * + * Simultaneous modifications to the @idr are not allowed and should be + * prevented by the user, usually with a lock. idr_alloc() may be called + * concurrently with read-only accesses to the @idr, such as idr_find() and + * idr_for_each_entry(). + */ +static inline int idr_alloc(struct idr *idr, void *ptr, + int start, int end, gfp_t gfp) +{ + unsigned long id; + int ret; + + if (WARN_ON_ONCE(start < 0)) + return -EINVAL; + + ret = idr_alloc_cmn(idr, ptr, &id, start, end, gfp, false); + + if (ret) + return ret; + + return id; +} + +static inline int idr_alloc_ext(struct idr *idr, void *ptr, + unsigned long *index, + unsigned long start, + unsigned long end, + gfp_t gfp) +{ + return idr_alloc_cmn(idr, ptr, index, start, end, gfp, true); +} + int idr_alloc_cyclic(struct idr *, void *entry, int start, int end, gfp_t); int idr_for_each(const struct idr *, int (*fn)(int id, void *p, void *data), void *data); void *idr_get_next(struct idr *, int *nextid); +void *idr_get_next_ext(struct idr *idr, unsigned long *nextid); void *idr_replace(struct idr *, void *, int id); +void *idr_replace_ext(struct idr *idr, void *ptr, unsigned long id); void idr_destroy(struct idr *); -static inline void *idr_remove(struct idr *idr, int id) +static inline void *idr_remove_ext(struct idr *idr, unsigned long id) { return radix_tree_delete_item(&idr->idr_rt, id, NULL); } +static inline void *idr_remove(struct idr *idr, int id) +{ + return idr_remove_ext(idr, id); +} + static inline void idr_init(struct idr *idr) { INIT_RADIX_TREE(&idr->idr_rt, IDR_RT_MARKER); @@ -128,11 +184,16 @@ static inline void idr_preload_end(void) * This function can be called under rcu_read_lock(), given that the leaf * pointers lifetimes are correctly managed. */ -static inline void *idr_find(const struct idr *idr, int id) +static inline void *idr_find_ext(const struct idr *idr, unsigned long id) { return radix_tree_lookup(&idr->idr_rt, id); } +static inline void *idr_find(const struct idr *idr, int id) +{ + return idr_find_ext(idr, id); +} + /** * idr_for_each_entry - iterate over an idr's elements of a given type * @idr: idr handle @@ -145,6 +206,8 @@ static inline void *idr_find(const struct idr *idr, int id) */ #define idr_for_each_entry(idr, entry, id) \ for (id = 0; ((entry) = idr_get_next(idr, &(id))) != NULL; ++id) +#define idr_for_each_entry_ext(idr, entry, id) \ + for (id = 0; ((entry) = idr_get_next_ext(idr, &(id))) != NULL; ++id) /** * idr_for_each_entry_continue - continue iteration over an idr's elements of a given type diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 97caf1821de8ceebe6016b134ae291d802fcb78d..f8231854b5d60316310fc5d8e57eea8625fe3078 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -118,7 +118,8 @@ extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, struct ip_msfilter __user *optval, int __user *optlen); extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, struct group_filter __user *optval, int __user *optlen); -extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt, int dif); +extern int ip_mc_sf_allow(struct sock *sk, __be32 local, __be32 rmt, + int dif, int sdif); extern void ip_mc_init_dev(struct in_device *); extern void ip_mc_destroy_dev(struct in_device *); extern void ip_mc_up(struct in_device *); diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 5ba430cc9a87352c305b7e6319f3a53ec4a94cc6..1fc7abd28b0b064b54a73e9c5717c2954e25e1cb 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -111,6 +111,9 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, unsigned int size, unsigned int *val); +int ad_sd_reset(struct ad_sigma_delta *sigma_delta, + unsigned int reset_length); + int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, int *val); int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 497f2b3a5a62c8da6f87107de16519b176cc9f1f..7b0fa8b5c120d42a7b85e58f6d02f27018f3ee6f 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -105,6 +105,11 @@ struct st_sensor_fullscale { struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX]; }; +struct st_sensor_sim { + u8 addr; + u8 value; +}; + /** * struct st_sensor_bdu - ST sensor device block data update * @addr: address of the register. @@ -197,6 +202,7 @@ struct st_sensor_transfer_function { * @bdu: Block data update register. * @das: Data Alignment Selection register. * @drdy_irq: Data ready register of the sensor. + * @sim: SPI serial interface mode register of the sensor. * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read. * @bootime: samples to discard when sensor passing from power-down to power-up. */ @@ -213,6 +219,7 @@ struct st_sensor_settings { struct st_sensor_bdu bdu; struct st_sensor_das das; struct st_sensor_data_ready_irq drdy_irq; + struct st_sensor_sim sim; bool multi_read_bit; unsigned int bootime; }; @@ -325,4 +332,16 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, ssize_t st_sensors_sysfs_scale_avail(struct device *dev, struct device_attribute *attr, char *buf); +#ifdef CONFIG_OF +void st_sensors_of_name_probe(struct device *dev, + const struct of_device_id *match, + char *name, int len); +#else +static inline void st_sensors_of_name_probe(struct device *dev, + const struct of_device_id *match, + char *name, int len) +{ +} +#endif + #endif /* ST_SENSORS_H */ diff --git a/include/linux/iio/common/st_sensors_i2c.h b/include/linux/iio/common/st_sensors_i2c.h index 254de3c7dde8aa348139e4783ce9376251213688..0a2c25e06d1f95001a9f56bd2c7b3aad607a17f3 100644 --- a/include/linux/iio/common/st_sensors_i2c.h +++ b/include/linux/iio/common/st_sensors_i2c.h @@ -18,16 +18,6 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev, struct i2c_client *client, struct st_sensor_data *sdata); -#ifdef CONFIG_OF -void st_sensors_of_i2c_probe(struct i2c_client *client, - const struct of_device_id *match); -#else -static inline void st_sensors_of_i2c_probe(struct i2c_client *client, - const struct of_device_id *match) -{ -} -#endif - #ifdef CONFIG_ACPI int st_sensors_match_acpi_device(struct device *dev); #else diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index d68bec297a45ee5e212ca253d903bf382d0ccfd9..c380daa40c0e3e6594b79a81128fc64326ee8a99 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -535,7 +535,7 @@ struct iio_buffer_setup_ops { * @scan_timestamp: [INTERN] set if any buffers have requested timestamp * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @trig: [INTERN] current device trigger (buffer modes) - * @trig_readonly [INTERN] mark the current trigger immutable + * @trig_readonly: [INTERN] mark the current trigger immutable * @pollfunc: [DRIVER] function run on trigger being received * @pollfunc_event: [DRIVER] function run on events trigger being received * @channels: [DRIVER] channel specification structure table diff --git a/include/linux/iio/timer/stm32-lptim-trigger.h b/include/linux/iio/timer/stm32-lptim-trigger.h new file mode 100644 index 0000000000000000000000000000000000000000..34d59bfdce2d2b12b0f6d7b61c601bfc0e2cb518 --- /dev/null +++ b/include/linux/iio/timer/stm32-lptim-trigger.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) STMicroelectronics 2017 + * + * Author: Fabrice Gasnier + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef _STM32_LPTIM_TRIGGER_H_ +#define _STM32_LPTIM_TRIGGER_H_ + +#include +#include + +#define LPTIM1_OUT "lptim1_out" +#define LPTIM2_OUT "lptim2_out" +#define LPTIM3_OUT "lptim3_out" + +#if IS_ENABLED(CONFIG_IIO_STM32_LPTIMER_TRIGGER) +bool is_stm32_lptim_trigger(struct iio_trigger *trig); +#else +static inline bool is_stm32_lptim_trigger(struct iio_trigger *trig) +{ + return false; +} +#endif +#endif diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h index fa7d786ed99ef1ccde759b6cbc02ff7490067b84..d68add80ab86d4f4f85a0aee569a09f4007f0478 100644 --- a/include/linux/iio/timer/stm32-timer-trigger.h +++ b/include/linux/iio/timer/stm32-timer-trigger.h @@ -55,10 +55,24 @@ #define TIM9_CH1 "tim9_ch1" #define TIM9_CH2 "tim9_ch2" +#define TIM10_OC1 "tim10_oc1" + +#define TIM11_OC1 "tim11_oc1" + #define TIM12_TRGO "tim12_trgo" #define TIM12_CH1 "tim12_ch1" #define TIM12_CH2 "tim12_ch2" +#define TIM13_OC1 "tim13_oc1" + +#define TIM14_OC1 "tim14_oc1" + +#define TIM15_TRGO "tim15_trgo" + +#define TIM16_OC1 "tim16_oc1" + +#define TIM17_OC1 "tim17_oc1" + bool is_stm32_timer_trigger(struct iio_trigger *trig); #endif diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index ea08302f2d7b27967fb1f0947dcede46411f396c..7142d8d6e470e13257ee12035f045bdabe1b4d7e 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -144,8 +144,8 @@ void devm_iio_trigger_unregister(struct device *dev, /** * iio_trigger_set_immutable() - set an immutable trigger on destination * - * @indio_dev - IIO device structure containing the device - * @trig - trigger to assign to device + * @indio_dev: IIO device structure containing the device + * @trig: trigger to assign to device * **/ int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig); diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 65da430e260f89e904cd56f5de901b3595dcd16c..ee251c585854ca09978bba226dca23fd31534b9e 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -25,6 +25,13 @@ struct inet_diag_handler { struct inet_diag_msg *r, void *info); + int (*idiag_get_aux)(struct sock *sk, + bool net_admin, + struct sk_buff *skb); + + size_t (*idiag_get_aux_size)(struct sock *sk, + bool net_admin); + int (*destroy)(struct sk_buff *in_skb, const struct inet_diag_req_v2 *req); diff --git a/include/linux/init_task.h b/include/linux/init_task.h index a2f6707e9fc054a95213d4a42e01ecf55b9a0730..3c07ace5b431094f3603438f9c27550007012101 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -125,18 +125,12 @@ extern struct group_info init_groups; #define INIT_IDS #endif -#ifdef CONFIG_PREEMPT_RCU -#define INIT_TASK_RCU_TREE_PREEMPT() \ - .rcu_blocked_node = NULL, -#else -#define INIT_TASK_RCU_TREE_PREEMPT(tsk) -#endif #ifdef CONFIG_PREEMPT_RCU #define INIT_TASK_RCU_PREEMPT(tsk) \ .rcu_read_lock_nesting = 0, \ .rcu_read_unlock_special.s = 0, \ .rcu_node_entry = LIST_HEAD_INIT(tsk.rcu_node_entry), \ - INIT_TASK_RCU_TREE_PREEMPT() + .rcu_blocked_node = NULL, #else #define INIT_TASK_RCU_PREEMPT(tsk) #endif @@ -181,9 +175,8 @@ extern struct cred init_cred; #ifdef CONFIG_RT_MUTEXES # define INIT_RT_MUTEXES(tsk) \ - .pi_waiters = RB_ROOT, \ - .pi_top_task = NULL, \ - .pi_waiters_leftmost = NULL, + .pi_waiters = RB_ROOT_CACHED, \ + .pi_top_task = NULL, #else # define INIT_RT_MUTEXES(tsk) #endif diff --git a/include/linux/input.h b/include/linux/input.h index a65e3b24fb1838e43cffc24e2ecdc8a8f92eba12..fb5e23c7ed98894e2833f2143e35cd5f703a9b09 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -529,6 +529,7 @@ int input_ff_event(struct input_dev *dev, unsigned int type, unsigned int code, int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file); int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file); +int input_ff_flush(struct input_dev *dev, struct file *file); int input_ff_create_memless(struct input_dev *dev, void *data, int (*play_effect)(struct input_dev *, void *, struct ff_effect *)); diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index a2fddddb0d601ec1e7cc2633643284cfebc7ef9c..59ba11661b6e69988a97e75996239b7ec0dea817 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -18,6 +18,7 @@ #include #include #include +#include /* * These correspond to the IORESOURCE_IRQ_* defines in @@ -726,7 +727,6 @@ extern int early_irq_init(void); extern int arch_probe_nr_irqs(void); extern int arch_early_irq_init(void); -#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) /* * We want to know which function is an entrypoint of a hardirq or a softirq. */ @@ -734,16 +734,4 @@ extern int arch_early_irq_init(void); #define __softirq_entry \ __attribute__((__section__(".softirqentry.text"))) -/* Limits of hardirq entrypoints */ -extern char __irqentry_text_start[]; -extern char __irqentry_text_end[]; -/* Limits of softirq entrypoints */ -extern char __softirqentry_text_start[]; -extern char __softirqentry_text_end[]; - -#else -#define __irq_entry -#define __softirq_entry -#endif - #endif diff --git a/include/linux/interval_tree.h b/include/linux/interval_tree.h index 724556aa3c957f66f39f2487149c2242471a9f1f..202ee1283f4bd59d984a1066bda5881380a4268e 100644 --- a/include/linux/interval_tree.h +++ b/include/linux/interval_tree.h @@ -11,13 +11,15 @@ struct interval_tree_node { }; extern void -interval_tree_insert(struct interval_tree_node *node, struct rb_root *root); +interval_tree_insert(struct interval_tree_node *node, + struct rb_root_cached *root); extern void -interval_tree_remove(struct interval_tree_node *node, struct rb_root *root); +interval_tree_remove(struct interval_tree_node *node, + struct rb_root_cached *root); extern struct interval_tree_node * -interval_tree_iter_first(struct rb_root *root, +interval_tree_iter_first(struct rb_root_cached *root, unsigned long start, unsigned long last); extern struct interval_tree_node * diff --git a/include/linux/interval_tree_generic.h b/include/linux/interval_tree_generic.h index 58370e1862ad6bbddb8ea3e452ad65a5404b9220..1f97ce26cccc1297caa110b9859b4c3ee8efcb9c 100644 --- a/include/linux/interval_tree_generic.h +++ b/include/linux/interval_tree_generic.h @@ -33,7 +33,7 @@ * ITSTATIC: 'static' or empty * ITPREFIX: prefix to use for the inline tree definitions * - * Note - before using this, please consider if non-generic version + * Note - before using this, please consider if generic version * (interval_tree.h) would work for you... */ @@ -65,11 +65,13 @@ RB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB, \ \ /* Insert / remove interval nodes from the tree */ \ \ -ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root) \ +ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, \ + struct rb_root_cached *root) \ { \ - struct rb_node **link = &root->rb_node, *rb_parent = NULL; \ + struct rb_node **link = &root->rb_root.rb_node, *rb_parent = NULL; \ ITTYPE start = ITSTART(node), last = ITLAST(node); \ ITSTRUCT *parent; \ + bool leftmost = true; \ \ while (*link) { \ rb_parent = *link; \ @@ -78,18 +80,22 @@ ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root) \ parent->ITSUBTREE = last; \ if (start < ITSTART(parent)) \ link = &parent->ITRB.rb_left; \ - else \ + else { \ link = &parent->ITRB.rb_right; \ + leftmost = false; \ + } \ } \ \ node->ITSUBTREE = last; \ rb_link_node(&node->ITRB, rb_parent, link); \ - rb_insert_augmented(&node->ITRB, root, &ITPREFIX ## _augment); \ + rb_insert_augmented_cached(&node->ITRB, root, \ + leftmost, &ITPREFIX ## _augment); \ } \ \ -ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, struct rb_root *root) \ +ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, \ + struct rb_root_cached *root) \ { \ - rb_erase_augmented(&node->ITRB, root, &ITPREFIX ## _augment); \ + rb_erase_augmented_cached(&node->ITRB, root, &ITPREFIX ## _augment); \ } \ \ /* \ @@ -140,15 +146,35 @@ ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) \ } \ \ ITSTATIC ITSTRUCT * \ -ITPREFIX ## _iter_first(struct rb_root *root, ITTYPE start, ITTYPE last) \ +ITPREFIX ## _iter_first(struct rb_root_cached *root, \ + ITTYPE start, ITTYPE last) \ { \ - ITSTRUCT *node; \ + ITSTRUCT *node, *leftmost; \ \ - if (!root->rb_node) \ + if (!root->rb_root.rb_node) \ return NULL; \ - node = rb_entry(root->rb_node, ITSTRUCT, ITRB); \ + \ + /* \ + * Fastpath range intersection/overlap between A: [a0, a1] and \ + * B: [b0, b1] is given by: \ + * \ + * a0 <= b1 && b0 <= a1 \ + * \ + * ... where A holds the lock range and B holds the smallest \ + * 'start' and largest 'last' in the tree. For the later, we \ + * rely on the root node, which by augmented interval tree \ + * property, holds the largest value in its last-in-subtree. \ + * This allows mitigating some of the tree walk overhead for \ + * for non-intersecting ranges, maintained and consulted in O(1). \ + */ \ + node = rb_entry(root->rb_root.rb_node, ITSTRUCT, ITRB); \ if (node->ITSUBTREE < start) \ return NULL; \ + \ + leftmost = rb_entry(root->rb_leftmost, ITSTRUCT, ITRB); \ + if (ITSTART(leftmost) > last) \ + return NULL; \ + \ return ITPREFIX ## _subtree_search(node, start, last); \ } \ \ diff --git a/include/linux/io.h b/include/linux/io.h index 2195d9ea4aaae0c054f04aab2da7cff851d2b997..32e30e8fb9db92cf1472c6188ff3310a610b3c5f 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -157,6 +157,8 @@ enum { MEMREMAP_WB = 1 << 0, MEMREMAP_WT = 1 << 1, MEMREMAP_WC = 1 << 2, + MEMREMAP_ENC = 1 << 3, + MEMREMAP_DEC = 1 << 4, }; void *memremap(resource_size_t offset, size_t size, unsigned long flags); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 2cb54adc4a334aa3f3a1732c35eaf9749d64b9e8..41b8c575785916f7691a7686a5c5d4e7d99003fa 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -167,7 +167,11 @@ struct iommu_resv_region { * @map: map a physically contiguous memory region to an iommu domain * @unmap: unmap a physically contiguous memory region from an iommu domain * @map_sg: map a scatter-gather list of physically contiguous memory chunks - * to an iommu domain + * to an iommu domain + * @flush_tlb_all: Synchronously flush all hardware TLBs for this domain + * @tlb_range_add: Add a given iova range to the flush queue for this domain + * @tlb_sync: Flush all queued ranges from the hardware TLBs and empty flush + * queue * @iova_to_phys: translate iova to physical address * @add_device: add device to iommu grouping * @remove_device: remove device from iommu grouping @@ -199,6 +203,10 @@ struct iommu_ops { size_t size); size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot); + void (*flush_iotlb_all)(struct iommu_domain *domain); + void (*iotlb_range_add)(struct iommu_domain *domain, + unsigned long iova, size_t size); + void (*iotlb_sync)(struct iommu_domain *domain); phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); int (*add_device)(struct device *dev); void (*remove_device)(struct device *dev); @@ -225,6 +233,7 @@ struct iommu_ops { u32 (*domain_get_windows)(struct iommu_domain *domain); int (*of_xlate)(struct device *dev, struct of_phandle_args *args); + bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev); unsigned long pgsize_bitmap; }; @@ -240,7 +249,7 @@ struct iommu_device { struct list_head list; const struct iommu_ops *ops; struct fwnode_handle *fwnode; - struct device dev; + struct device *dev; }; int iommu_device_register(struct iommu_device *iommu); @@ -265,6 +274,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu, iommu->fwnode = fwnode; } +static inline struct iommu_device *dev_to_iommu_device(struct device *dev) +{ + return (struct iommu_device *)dev_get_drvdata(dev); +} + #define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */ #define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */ #define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3 /* Pre Driver bind */ @@ -286,7 +300,9 @@ extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot); extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, - size_t size); + size_t size); +extern size_t iommu_unmap_fast(struct iommu_domain *domain, + unsigned long iova, size_t size); extern size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg,unsigned int nents, int prot); @@ -343,6 +359,25 @@ extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr) extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags); +static inline void iommu_flush_tlb_all(struct iommu_domain *domain) +{ + if (domain->ops->flush_iotlb_all) + domain->ops->flush_iotlb_all(domain); +} + +static inline void iommu_tlb_range_add(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ + if (domain->ops->iotlb_range_add) + domain->ops->iotlb_range_add(domain, iova, size); +} + +static inline void iommu_tlb_sync(struct iommu_domain *domain) +{ + if (domain->ops->iotlb_sync) + domain->ops->iotlb_sync(domain); +} + static inline size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot) @@ -425,13 +460,19 @@ static inline struct iommu_domain *iommu_get_domain_for_dev(struct device *dev) } static inline int iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, int gfp_order, int prot) + phys_addr_t paddr, size_t size, int prot) { return -ENODEV; } static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova, - int gfp_order) + size_t size) +{ + return -ENODEV; +} + +static inline int iommu_unmap_fast(struct iommu_domain *domain, unsigned long iova, + int gfp_order) { return -ENODEV; } @@ -443,6 +484,19 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, return -ENODEV; } +static inline void iommu_flush_tlb_all(struct iommu_domain *domain) +{ +} + +static inline void iommu_tlb_range_add(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ +} + +static inline void iommu_tlb_sync(struct iommu_domain *domain) +{ +} + static inline int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, phys_addr_t paddr, u64 size, int prot) @@ -589,6 +643,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu, { } +static inline struct iommu_device *dev_to_iommu_device(struct device *dev) +{ + return NULL; +} + static inline void iommu_device_unregister(struct iommu_device *iommu) { } diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 6230064d7f95d072d61e2bc0eedd341463880d32..f5cf32e800411ecafd0aef552d7ae675dceefeb7 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -130,6 +130,8 @@ enum { IORES_DESC_ACPI_NV_STORAGE = 3, IORES_DESC_PERSISTENT_MEMORY = 4, IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5, + IORES_DESC_DEVICE_PRIVATE_MEMORY = 6, + IORES_DESC_DEVICE_PUBLIC_MEMORY = 7, }; /* helpers to define resources */ diff --git a/include/linux/iova.h b/include/linux/iova.h index e0a892ae45c0834a82d42e06a6bfab65b424c899..d179b9bf7814767462dbbf592ca75cb78fa0d9fc 100644 --- a/include/linux/iova.h +++ b/include/linux/iova.h @@ -14,6 +14,7 @@ #include #include #include +#include #include /* iova structure */ @@ -36,6 +37,35 @@ struct iova_rcache { struct iova_cpu_rcache __percpu *cpu_rcaches; }; +struct iova_domain; + +/* Call-Back from IOVA code into IOMMU drivers */ +typedef void (* iova_flush_cb)(struct iova_domain *domain); + +/* Destructor for per-entry data */ +typedef void (* iova_entry_dtor)(unsigned long data); + +/* Number of entries per Flush Queue */ +#define IOVA_FQ_SIZE 256 + +/* Timeout (in ms) after which entries are flushed from the Flush-Queue */ +#define IOVA_FQ_TIMEOUT 10 + +/* Flush Queue entry for defered flushing */ +struct iova_fq_entry { + unsigned long iova_pfn; + unsigned long pages; + unsigned long data; + u64 counter; /* Flush counter when this entrie was added */ +}; + +/* Per-CPU Flush Queue structure */ +struct iova_fq { + struct iova_fq_entry entries[IOVA_FQ_SIZE]; + unsigned head, tail; + spinlock_t lock; +}; + /* holds all the iova translations for a domain */ struct iova_domain { spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ @@ -45,6 +75,25 @@ struct iova_domain { unsigned long start_pfn; /* Lower limit for this domain */ unsigned long dma_32bit_pfn; struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE]; /* IOVA range caches */ + + iova_flush_cb flush_cb; /* Call-Back function to flush IOMMU + TLBs */ + + iova_entry_dtor entry_dtor; /* IOMMU driver specific destructor for + iova entry */ + + struct iova_fq __percpu *fq; /* Flush Queue */ + + atomic64_t fq_flush_start_cnt; /* Number of TLB flushes that + have been started */ + + atomic64_t fq_flush_finish_cnt; /* Number of TLB flushes that + have been finished */ + + struct timer_list fq_timer; /* Timer to regularily empty the + flush-queues */ + atomic_t fq_timer_on; /* 1 when timer is active, 0 + when not */ }; static inline unsigned long iova_size(struct iova *iova) @@ -95,6 +144,9 @@ struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size, bool size_aligned); void free_iova_fast(struct iova_domain *iovad, unsigned long pfn, unsigned long size); +void queue_iova(struct iova_domain *iovad, + unsigned long pfn, unsigned long pages, + unsigned long data); unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size, unsigned long limit_pfn); struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, @@ -102,6 +154,8 @@ struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); void init_iova_domain(struct iova_domain *iovad, unsigned long granule, unsigned long start_pfn, unsigned long pfn_32bit); +int init_iova_flush_queue(struct iova_domain *iovad, + iova_flush_cb flush_cb, iova_entry_dtor entry_dtor); struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); void put_iova_domain(struct iova_domain *iovad); struct iova *split_and_remove_iova(struct iova_domain *iovad, @@ -148,6 +202,12 @@ static inline void free_iova_fast(struct iova_domain *iovad, { } +static inline void queue_iova(struct iova_domain *iovad, + unsigned long pfn, unsigned long pages, + unsigned long data) +{ +} + static inline unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size, unsigned long limit_pfn) @@ -174,6 +234,13 @@ static inline void init_iova_domain(struct iova_domain *iovad, { } +static inline int init_iova_flush_queue(struct iova_domain *iovad, + iova_flush_cb flush_cb, + iova_entry_dtor entry_dtor) +{ + return -ENODEV; +} + static inline struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn) { diff --git a/include/linux/ipc.h b/include/linux/ipc.h index fadd579d577dc8aafd7c100ea51fe2bf630c76a0..92a2ccff80c5cf287e2447c75dc505b24bcd62d8 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ @@ -21,8 +23,10 @@ struct kern_ipc_perm { unsigned long seq; void *security; + struct rhash_head khtnode; + struct rcu_head rcu; - atomic_t refcount; + refcount_t refcount; } ____cacheline_aligned_in_smp __randomize_layout; #endif /* _LINUX_IPC_H */ diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index 65327ee0936b314fe38fffee3ffb5f882d8883ac..83f0bf7a587d55c5e7f7d46d4e239b36c1b3c289 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h @@ -7,19 +7,23 @@ #include #include #include +#include +#include struct user_namespace; struct ipc_ids { int in_use; unsigned short seq; + bool tables_initialized; struct rw_semaphore rwsem; struct idr ipcs_idr; int next_id; + struct rhashtable key_ht; }; struct ipc_namespace { - atomic_t count; + refcount_t count; struct ipc_ids ids[3]; int sem_ctls[4]; @@ -118,7 +122,7 @@ extern struct ipc_namespace *copy_ipcs(unsigned long flags, static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns) { if (ns) - atomic_inc(&ns->count); + refcount_inc(&ns->count); return ns; } diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index e1b442996f810529a755533270b6d21c350fbd5a..ac2da4e11d5e84c5dfbdefa5cc3a427ee84777ce 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -128,6 +128,7 @@ struct inet6_skb_parm { #define IP6SKB_FRAGMENTED 16 #define IP6SKB_HOPBYHOP 32 #define IP6SKB_L3SLAVE 64 +#define IP6SKB_JUMBOGRAM 128 }; #if defined(CONFIG_NET_L3_MASTER_DEV) @@ -152,6 +153,21 @@ static inline int inet6_iif(const struct sk_buff *skb) return l3_slave ? skb->skb_iif : IP6CB(skb)->iif; } +static inline bool inet6_is_jumbogram(const struct sk_buff *skb) +{ + return !!(IP6CB(skb)->flags & IP6SKB_JUMBOGRAM); +} + +/* can not be used in TCP layer after tcp_v6_fill_cb */ +static inline int inet6_sdif(const struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) + if (skb && ipv6_l3mdev_skb(IP6CB(skb)->flags)) + return IP6CB(skb)->iif; +#endif + return 0; +} + /* can not be used in TCP layer after tcp_v6_fill_cb */ static inline bool inet6_exact_dif_match(struct net *net, struct sk_buff *skb) { diff --git a/include/linux/irq.h b/include/linux/irq.h index d2d543794093f1272aa62551cfb9867195b490cc..d4728bf6a537c802073592fcd6e440ccc628509e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -568,6 +568,8 @@ extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); extern int irq_chip_pm_get(struct irq_data *data); extern int irq_chip_pm_put(struct irq_data *data); #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +extern void handle_fasteoi_ack_irq(struct irq_desc *desc); +extern void handle_fasteoi_mask_irq(struct irq_desc *desc); extern void irq_chip_enable_parent(struct irq_data *data); extern void irq_chip_disable_parent(struct irq_data *data); extern void irq_chip_ack_parent(struct irq_data *data); diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h new file mode 100644 index 0000000000000000000000000000000000000000..0380d899b9556c6a3331639f0439fba3c1429c15 --- /dev/null +++ b/include/linux/irq_sim.h @@ -0,0 +1,44 @@ +#ifndef _LINUX_IRQ_SIM_H +#define _LINUX_IRQ_SIM_H +/* + * Copyright (C) 2017 Bartosz Golaszewski + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +/* + * Provides a framework for allocating simulated interrupts which can be + * requested like normal irqs and enqueued from process context. + */ + +struct irq_sim_work_ctx { + struct irq_work work; + int irq; +}; + +struct irq_sim_irq_ctx { + int irqnum; + bool enabled; +}; + +struct irq_sim { + struct irq_sim_work_ctx work_ctx; + int irq_base; + unsigned int irq_count; + struct irq_sim_irq_ctx *irqs; +}; + +int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs); +int devm_irq_sim_init(struct device *dev, struct irq_sim *sim, + unsigned int num_irqs); +void irq_sim_fini(struct irq_sim *sim); +void irq_sim_fire(struct irq_sim *sim, unsigned int offset); +int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset); + +#endif /* _LINUX_IRQ_SIM_H */ diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h index c647b0547bcd8a7c303a4e0ab153654ca335053e..0a83b4379f34627f2ae3d0deb927b82210fdb215 100644 --- a/include/linux/irqchip/arm-gic-common.h +++ b/include/linux/irqchip/arm-gic-common.h @@ -27,6 +27,8 @@ struct gic_kvm_info { unsigned int maint_irq; /* Virtual control interface */ struct resource vctrl; + /* vlpi support */ + bool has_v4; }; const struct gic_kvm_info *gic_get_kvm_info(void); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 6a1f87ff94e2bf632d8568e3d9ce613dd111e372..1ea576c8126f8b8c467f1ea3ab2623826efde0af 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -204,6 +204,7 @@ #define GICR_TYPER_PLPIS (1U << 0) #define GICR_TYPER_VLPIS (1U << 1) +#define GICR_TYPER_DirectLPIS (1U << 3) #define GICR_TYPER_LAST (1U << 4) #define GIC_V3_REDIST_SIZE 0x20000 @@ -211,6 +212,69 @@ #define LPI_PROP_GROUP1 (1 << 1) #define LPI_PROP_ENABLED (1 << 0) +/* + * Re-Distributor registers, offsets from VLPI_base + */ +#define GICR_VPROPBASER 0x0070 + +#define GICR_VPROPBASER_IDBITS_MASK 0x1f + +#define GICR_VPROPBASER_SHAREABILITY_SHIFT (10) +#define GICR_VPROPBASER_INNER_CACHEABILITY_SHIFT (7) +#define GICR_VPROPBASER_OUTER_CACHEABILITY_SHIFT (56) + +#define GICR_VPROPBASER_SHAREABILITY_MASK \ + GIC_BASER_SHAREABILITY(GICR_VPROPBASER, SHAREABILITY_MASK) +#define GICR_VPROPBASER_INNER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, MASK) +#define GICR_VPROPBASER_OUTER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_VPROPBASER, OUTER, MASK) +#define GICR_VPROPBASER_CACHEABILITY_MASK \ + GICR_VPROPBASER_INNER_CACHEABILITY_MASK + +#define GICR_VPROPBASER_InnerShareable \ + GIC_BASER_SHAREABILITY(GICR_VPROPBASER, InnerShareable) + +#define GICR_VPROPBASER_nCnB GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nCnB) +#define GICR_VPROPBASER_nC GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nC) +#define GICR_VPROPBASER_RaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt) +#define GICR_VPROPBASER_RaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt) +#define GICR_VPROPBASER_WaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWt) +#define GICR_VPROPBASER_WaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWb) +#define GICR_VPROPBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWt) +#define GICR_VPROPBASER_RaWaWb GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWb) + +#define GICR_VPENDBASER 0x0078 + +#define GICR_VPENDBASER_SHAREABILITY_SHIFT (10) +#define GICR_VPENDBASER_INNER_CACHEABILITY_SHIFT (7) +#define GICR_VPENDBASER_OUTER_CACHEABILITY_SHIFT (56) +#define GICR_VPENDBASER_SHAREABILITY_MASK \ + GIC_BASER_SHAREABILITY(GICR_VPENDBASER, SHAREABILITY_MASK) +#define GICR_VPENDBASER_INNER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, MASK) +#define GICR_VPENDBASER_OUTER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_VPENDBASER, OUTER, MASK) +#define GICR_VPENDBASER_CACHEABILITY_MASK \ + GICR_VPENDBASER_INNER_CACHEABILITY_MASK + +#define GICR_VPENDBASER_NonShareable \ + GIC_BASER_SHAREABILITY(GICR_VPENDBASER, NonShareable) + +#define GICR_VPENDBASER_nCnB GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nCnB) +#define GICR_VPENDBASER_nC GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nC) +#define GICR_VPENDBASER_RaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt) +#define GICR_VPENDBASER_RaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt) +#define GICR_VPENDBASER_WaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWt) +#define GICR_VPENDBASER_WaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWb) +#define GICR_VPENDBASER_RaWaWt GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWt) +#define GICR_VPENDBASER_RaWaWb GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWb) + +#define GICR_VPENDBASER_Dirty (1ULL << 60) +#define GICR_VPENDBASER_PendingLast (1ULL << 61) +#define GICR_VPENDBASER_IDAI (1ULL << 62) +#define GICR_VPENDBASER_Valid (1ULL << 63) + /* * ITS registers, offsets from ITS_base */ @@ -234,15 +298,21 @@ #define GITS_TRANSLATER 0x10040 #define GITS_CTLR_ENABLE (1U << 0) +#define GITS_CTLR_ImDe (1U << 1) +#define GITS_CTLR_ITS_NUMBER_SHIFT 4 +#define GITS_CTLR_ITS_NUMBER (0xFU << GITS_CTLR_ITS_NUMBER_SHIFT) #define GITS_CTLR_QUIESCENT (1U << 31) #define GITS_TYPER_PLPIS (1UL << 0) +#define GITS_TYPER_VLPIS (1UL << 1) #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 +#define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0x1f) + 1) #define GITS_TYPER_IDBITS_SHIFT 8 #define GITS_TYPER_DEVBITS_SHIFT 13 #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) #define GITS_TYPER_PTA (1UL << 19) #define GITS_TYPER_HWCOLLCNT_SHIFT 24 +#define GITS_TYPER_VMOVP (1ULL << 37) #define GITS_IIDR_REV_SHIFT 12 #define GITS_IIDR_REV_MASK (0xf << GITS_IIDR_REV_SHIFT) @@ -341,6 +411,18 @@ #define GITS_CMD_CLEAR 0x04 #define GITS_CMD_SYNC 0x05 +/* + * GICv4 ITS specific commands + */ +#define GITS_CMD_GICv4(x) ((x) | 0x20) +#define GITS_CMD_VINVALL GITS_CMD_GICv4(GITS_CMD_INVALL) +#define GITS_CMD_VMAPP GITS_CMD_GICv4(GITS_CMD_MAPC) +#define GITS_CMD_VMAPTI GITS_CMD_GICv4(GITS_CMD_MAPTI) +#define GITS_CMD_VMOVI GITS_CMD_GICv4(GITS_CMD_MOVI) +#define GITS_CMD_VSYNC GITS_CMD_GICv4(GITS_CMD_SYNC) +/* VMOVP is the odd one, as it doesn't have a physical counterpart */ +#define GITS_CMD_VMOVP GITS_CMD_GICv4(2) + /* * ITS error numbers */ @@ -487,6 +569,8 @@ struct rdists { struct page *prop_page; int id_bits; u64 flags; + bool has_vlpis; + bool has_direct_lpi; }; struct irq_domain; diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h new file mode 100644 index 0000000000000000000000000000000000000000..58a4d89aa82c022644ac371bdfa64ecedcd5ee26 --- /dev/null +++ b/include/linux/irqchip/arm-gic-v4.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016,2017 ARM Limited, All Rights Reserved. + * Author: Marc Zyngier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H +#define __LINUX_IRQCHIP_ARM_GIC_V4_H + +struct its_vpe; + +/* Embedded in kvm.arch */ +struct its_vm { + struct fwnode_handle *fwnode; + struct irq_domain *domain; + struct page *vprop_page; + struct its_vpe **vpes; + int nr_vpes; + irq_hw_number_t db_lpi_base; + unsigned long *db_bitmap; + int nr_db_lpis; +}; + +/* Embedded in kvm_vcpu.arch */ +struct its_vpe { + struct page *vpt_page; + struct its_vm *its_vm; + /* Doorbell interrupt */ + int irq; + irq_hw_number_t vpe_db_lpi; + /* VPE proxy mapping */ + int vpe_proxy_event; + /* + * This collection ID is used to indirect the target + * redistributor for this VPE. The ID itself isn't involved in + * programming of the ITS. + */ + u16 col_idx; + /* Unique (system-wide) VPE identifier */ + u16 vpe_id; + /* Implementation Defined Area Invalid */ + bool idai; + /* Pending VLPIs on schedule out? */ + bool pending_last; +}; + +/* + * struct its_vlpi_map: structure describing the mapping of a + * VLPI. Only to be interpreted in the context of a physical interrupt + * it complements. To be used as the vcpu_info passed to + * irq_set_vcpu_affinity(). + * + * @vm: Pointer to the GICv4 notion of a VM + * @vpe: Pointer to the GICv4 notion of a virtual CPU (VPE) + * @vintid: Virtual LPI number + * @db_enabled: Is the VPE doorbell to be generated? + */ +struct its_vlpi_map { + struct its_vm *vm; + struct its_vpe *vpe; + u32 vintid; + bool db_enabled; +}; + +enum its_vcpu_info_cmd_type { + MAP_VLPI, + GET_VLPI, + PROP_UPDATE_VLPI, + PROP_UPDATE_AND_INV_VLPI, + SCHEDULE_VPE, + DESCHEDULE_VPE, + INVALL_VPE, +}; + +struct its_cmd_info { + enum its_vcpu_info_cmd_type cmd_type; + union { + struct its_vlpi_map *map; + u8 config; + }; +}; + +int its_alloc_vcpu_irqs(struct its_vm *vm); +void its_free_vcpu_irqs(struct its_vm *vm); +int its_schedule_vpe(struct its_vpe *vpe, bool on); +int its_invall_vpe(struct its_vpe *vpe); +int its_map_vlpi(int irq, struct its_vlpi_map *map); +int its_get_vlpi(int irq, struct its_vlpi_map *map); +int its_unmap_vlpi(int irq); +int its_prop_update_vlpi(int irq, u8 config, bool inv); + +int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops); + +#endif diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h deleted file mode 100644 index 2b0e56619e5377064e9dfe7e701c09b36c200bf2..0000000000000000000000000000000000000000 --- a/include/linux/irqchip/mips-gic.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000, 07 MIPS Technologies, Inc. - */ -#ifndef __LINUX_IRQCHIP_MIPS_GIC_H -#define __LINUX_IRQCHIP_MIPS_GIC_H - -#include -#include - -#define GIC_MAX_INTRS 256 - -/* Constants */ -#define GIC_POL_POS 1 -#define GIC_POL_NEG 0 -#define GIC_TRIG_EDGE 1 -#define GIC_TRIG_LEVEL 0 -#define GIC_TRIG_DUAL_ENABLE 1 -#define GIC_TRIG_DUAL_DISABLE 0 - -#define MSK(n) ((1 << (n)) - 1) - -/* Accessors */ -#define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS) - -/* GIC Address Space */ -#define SHARED_SECTION_OFS 0x0000 -#define SHARED_SECTION_SIZE 0x8000 -#define VPE_LOCAL_SECTION_OFS 0x8000 -#define VPE_LOCAL_SECTION_SIZE 0x4000 -#define VPE_OTHER_SECTION_OFS 0xc000 -#define VPE_OTHER_SECTION_SIZE 0x4000 -#define USM_VISIBLE_SECTION_OFS 0x10000 -#define USM_VISIBLE_SECTION_SIZE 0x10000 - -/* Register Map for Shared Section */ - -#define GIC_SH_CONFIG_OFS 0x0000 - -/* Shared Global Counter */ -#define GIC_SH_COUNTER_31_00_OFS 0x0010 -/* 64-bit counter register for CM3 */ -#define GIC_SH_COUNTER_OFS GIC_SH_COUNTER_31_00_OFS -#define GIC_SH_COUNTER_63_32_OFS 0x0014 -#define GIC_SH_REVISIONID_OFS 0x0020 - -/* Convert an interrupt number to a byte offset/bit for multi-word registers */ -#define GIC_INTR_OFS(intr) ({ \ - unsigned bits = mips_cm_is64 ? 64 : 32; \ - unsigned reg_idx = (intr) / bits; \ - unsigned reg_width = bits / 8; \ - \ - reg_idx * reg_width; \ -}) -#define GIC_INTR_BIT(intr) ((intr) % (mips_cm_is64 ? 64 : 32)) - -/* Polarity : Reset Value is always 0 */ -#define GIC_SH_SET_POLARITY_OFS 0x0100 - -/* Triggering : Reset Value is always 0 */ -#define GIC_SH_SET_TRIGGER_OFS 0x0180 - -/* Dual edge triggering : Reset Value is always 0 */ -#define GIC_SH_SET_DUAL_OFS 0x0200 - -/* Set/Clear corresponding bit in Edge Detect Register */ -#define GIC_SH_WEDGE_OFS 0x0280 - -/* Mask manipulation */ -#define GIC_SH_RMASK_OFS 0x0300 -#define GIC_SH_SMASK_OFS 0x0380 - -/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ -#define GIC_SH_MASK_OFS 0x0400 - -/* Pending Global Interrupts (RO) */ -#define GIC_SH_PEND_OFS 0x0480 - -/* Maps Interrupt X to a Pin */ -#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 -#define GIC_SH_MAP_TO_PIN(intr) (4 * (intr)) - -/* Maps Interrupt X to a VPE */ -#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 -#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ - ((32 * (intr)) + (((vpe) / 32) * 4)) -#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) - -/* Register Map for Local Section */ -#define GIC_VPE_CTL_OFS 0x0000 -#define GIC_VPE_PEND_OFS 0x0004 -#define GIC_VPE_MASK_OFS 0x0008 -#define GIC_VPE_RMASK_OFS 0x000c -#define GIC_VPE_SMASK_OFS 0x0010 -#define GIC_VPE_WD_MAP_OFS 0x0040 -#define GIC_VPE_COMPARE_MAP_OFS 0x0044 -#define GIC_VPE_TIMER_MAP_OFS 0x0048 -#define GIC_VPE_FDC_MAP_OFS 0x004c -#define GIC_VPE_PERFCTR_MAP_OFS 0x0050 -#define GIC_VPE_SWINT0_MAP_OFS 0x0054 -#define GIC_VPE_SWINT1_MAP_OFS 0x0058 -#define GIC_VPE_OTHER_ADDR_OFS 0x0080 -#define GIC_VP_IDENT_OFS 0x0088 -#define GIC_VPE_WD_CONFIG0_OFS 0x0090 -#define GIC_VPE_WD_COUNT0_OFS 0x0094 -#define GIC_VPE_WD_INITIAL0_OFS 0x0098 -#define GIC_VPE_COMPARE_LO_OFS 0x00a0 -/* 64-bit Compare register on CM3 */ -#define GIC_VPE_COMPARE_OFS GIC_VPE_COMPARE_LO_OFS -#define GIC_VPE_COMPARE_HI_OFS 0x00a4 - -#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100 -#define GIC_VPE_EIC_SS(intr) (4 * (intr)) - -#define GIC_VPE_EIC_VEC_BASE_OFS 0x0800 -#define GIC_VPE_EIC_VEC(intr) (4 * (intr)) - -#define GIC_VPE_TENABLE_NMI_OFS 0x1000 -#define GIC_VPE_TENABLE_YQ_OFS 0x1004 -#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 -#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 - -/* User Mode Visible Section Register Map */ -#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 -#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 - -/* Masks */ -#define GIC_SH_CONFIG_COUNTSTOP_SHF 28 -#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) - -#define GIC_SH_CONFIG_COUNTBITS_SHF 24 -#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF) - -#define GIC_SH_CONFIG_NUMINTRS_SHF 16 -#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF) - -#define GIC_SH_CONFIG_NUMVPES_SHF 0 -#define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) - -#define GIC_SH_WEDGE_SET(intr) ((intr) | (0x1 << 31)) -#define GIC_SH_WEDGE_CLR(intr) ((intr) & ~(0x1 << 31)) - -#define GIC_MAP_TO_PIN_SHF 31 -#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) -#define GIC_MAP_TO_NMI_SHF 30 -#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF) -#define GIC_MAP_TO_YQ_SHF 29 -#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF) -#define GIC_MAP_SHF 0 -#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) - -/* GIC_VPE_CTL Masks */ -#define GIC_VPE_CTL_FDC_RTBL_SHF 4 -#define GIC_VPE_CTL_FDC_RTBL_MSK (MSK(1) << GIC_VPE_CTL_FDC_RTBL_SHF) -#define GIC_VPE_CTL_SWINT_RTBL_SHF 3 -#define GIC_VPE_CTL_SWINT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_SWINT_RTBL_SHF) -#define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 -#define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) -#define GIC_VPE_CTL_TIMER_RTBL_SHF 1 -#define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF) -#define GIC_VPE_CTL_EIC_MODE_SHF 0 -#define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF) - -/* GIC_VPE_PEND Masks */ -#define GIC_VPE_PEND_WD_SHF 0 -#define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF) -#define GIC_VPE_PEND_CMP_SHF 1 -#define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF) -#define GIC_VPE_PEND_TIMER_SHF 2 -#define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF) -#define GIC_VPE_PEND_PERFCOUNT_SHF 3 -#define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF) -#define GIC_VPE_PEND_SWINT0_SHF 4 -#define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF) -#define GIC_VPE_PEND_SWINT1_SHF 5 -#define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF) -#define GIC_VPE_PEND_FDC_SHF 6 -#define GIC_VPE_PEND_FDC_MSK (MSK(1) << GIC_VPE_PEND_FDC_SHF) - -/* GIC_VPE_RMASK Masks */ -#define GIC_VPE_RMASK_WD_SHF 0 -#define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF) -#define GIC_VPE_RMASK_CMP_SHF 1 -#define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF) -#define GIC_VPE_RMASK_TIMER_SHF 2 -#define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF) -#define GIC_VPE_RMASK_PERFCNT_SHF 3 -#define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF) -#define GIC_VPE_RMASK_SWINT0_SHF 4 -#define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF) -#define GIC_VPE_RMASK_SWINT1_SHF 5 -#define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF) -#define GIC_VPE_RMASK_FDC_SHF 6 -#define GIC_VPE_RMASK_FDC_MSK (MSK(1) << GIC_VPE_RMASK_FDC_SHF) - -/* GIC_VPE_SMASK Masks */ -#define GIC_VPE_SMASK_WD_SHF 0 -#define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF) -#define GIC_VPE_SMASK_CMP_SHF 1 -#define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF) -#define GIC_VPE_SMASK_TIMER_SHF 2 -#define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF) -#define GIC_VPE_SMASK_PERFCNT_SHF 3 -#define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF) -#define GIC_VPE_SMASK_SWINT0_SHF 4 -#define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF) -#define GIC_VPE_SMASK_SWINT1_SHF 5 -#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) -#define GIC_VPE_SMASK_FDC_SHF 6 -#define GIC_VPE_SMASK_FDC_MSK (MSK(1) << GIC_VPE_SMASK_FDC_SHF) - -/* GIC_VP_IDENT fields */ -#define GIC_VP_IDENT_VCNUM_SHF 0 -#define GIC_VP_IDENT_VCNUM_MSK (MSK(6) << GIC_VP_IDENT_VCNUM_SHF) - -/* GIC nomenclature for Core Interrupt Pins. */ -#define GIC_CPU_INT0 0 /* Core Interrupt 2 */ -#define GIC_CPU_INT1 1 /* . */ -#define GIC_CPU_INT2 2 /* . */ -#define GIC_CPU_INT3 3 /* . */ -#define GIC_CPU_INT4 4 /* . */ -#define GIC_CPU_INT5 5 /* Core Interrupt 7 */ - -/* Add 2 to convert GIC CPU pin to core interrupt */ -#define GIC_CPU_PIN_OFFSET 2 - -/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ -#define GIC_CPU_TO_VEC_OFFSET 2 - -/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ -#define GIC_PIN_TO_VEC_OFFSET 1 - -/* Local GIC interrupts. */ -#define GIC_LOCAL_INT_WD 0 /* GIC watchdog */ -#define GIC_LOCAL_INT_COMPARE 1 /* GIC count and compare timer */ -#define GIC_LOCAL_INT_TIMER 2 /* CPU timer interrupt */ -#define GIC_LOCAL_INT_PERFCTR 3 /* CPU performance counter */ -#define GIC_LOCAL_INT_SWINT0 4 /* CPU software interrupt 0 */ -#define GIC_LOCAL_INT_SWINT1 5 /* CPU software interrupt 1 */ -#define GIC_LOCAL_INT_FDC 6 /* CPU fast debug channel */ -#define GIC_NUM_LOCAL_INTRS 7 - -/* Convert between local/shared IRQ number and GIC HW IRQ number. */ -#define GIC_LOCAL_HWIRQ_BASE 0 -#define GIC_LOCAL_TO_HWIRQ(x) (GIC_LOCAL_HWIRQ_BASE + (x)) -#define GIC_HWIRQ_TO_LOCAL(x) ((x) - GIC_LOCAL_HWIRQ_BASE) -#define GIC_SHARED_HWIRQ_BASE GIC_NUM_LOCAL_INTRS -#define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x)) -#define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) - -#ifdef CONFIG_MIPS_GIC - -extern unsigned int gic_present; - -extern void gic_init(unsigned long gic_base_addr, - unsigned long gic_addrspace_size, unsigned int cpu_vec, - unsigned int irqbase); -extern u64 gic_read_count(void); -extern unsigned int gic_get_count_width(void); -extern u64 gic_read_compare(void); -extern void gic_write_compare(u64 cnt); -extern void gic_write_cpu_compare(u64 cnt, int cpu); -extern void gic_start_count(void); -extern void gic_stop_count(void); -extern int gic_get_c0_compare_int(void); -extern int gic_get_c0_perfcount_int(void); -extern int gic_get_c0_fdc_int(void); -extern int gic_get_usm_range(struct resource *gic_usm_res); - -#else /* CONFIG_MIPS_GIC */ - -#define gic_present 0 - -static inline int gic_get_usm_range(struct resource *gic_usm_res) -{ - /* Shouldn't be called. */ - return -1; -} - -#endif /* CONFIG_MIPS_GIC */ - -/** - * gic_read_local_vp_id() - read the local VPs VCNUM - * - * Read the VCNUM of the local VP from the GIC_VP_IDENT register and - * return it to the caller. This ID should be used to refer to the VP - * via the GICs VP-other region, or when calculating an offset to a - * bit representing the VP in interrupt masks. - * - * Return: The VCNUM value for the local VP. - */ -extern unsigned gic_read_local_vp_id(void); - -#endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index cac77a5c555544af38d206c7f5b9eecd525394e2..81e4889ca6dd2c3e571c3ca292e0d8db55780da4 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -265,9 +265,11 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node) return node ? &node->fwnode : NULL; } +extern const struct fwnode_operations irqchip_fwnode_ops; + static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode) { - return fwnode && fwnode->type == FWNODE_IRQCHIP; + return fwnode && fwnode->ops == &irqchip_fwnode_ops; } extern void irq_domain_update_bus_token(struct irq_domain *domain, @@ -460,6 +462,9 @@ extern void irq_domain_free_irqs_common(struct irq_domain *domain, extern void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs); +extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg); +extern int irq_domain_pop_irq(struct irq_domain *domain, int virq); + extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain, unsigned int irq_base, unsigned int nr_irqs, void *arg); diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 5dd1272d1ab2ecb283f588eb95ba1ebd81369dd9..5fdd93bb93009ccb3bb70404a59f9fd31939bcb4 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -23,10 +23,26 @@ # define trace_softirq_context(p) ((p)->softirq_context) # define trace_hardirqs_enabled(p) ((p)->hardirqs_enabled) # define trace_softirqs_enabled(p) ((p)->softirqs_enabled) -# define trace_hardirq_enter() do { current->hardirq_context++; } while (0) -# define trace_hardirq_exit() do { current->hardirq_context--; } while (0) -# define lockdep_softirq_enter() do { current->softirq_context++; } while (0) -# define lockdep_softirq_exit() do { current->softirq_context--; } while (0) +# define trace_hardirq_enter() \ +do { \ + current->hardirq_context++; \ + crossrelease_hist_start(XHLOCK_HARD); \ +} while (0) +# define trace_hardirq_exit() \ +do { \ + current->hardirq_context--; \ + crossrelease_hist_end(XHLOCK_HARD); \ +} while (0) +# define lockdep_softirq_enter() \ +do { \ + current->softirq_context++; \ + crossrelease_hist_start(XHLOCK_SOFT); \ +} while (0) +# define lockdep_softirq_exit() \ +do { \ + current->softirq_context--; \ + crossrelease_hist_end(XHLOCK_SOFT); \ +} while (0) # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, #else # define trace_hardirqs_on() do { } while (0) diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 2afd74b9d844095375be39342e78b5a6749e2a52..cd5861651b17eeb28e66ecb82f5b4ba99ce3cf39 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -163,6 +163,8 @@ extern void jump_label_apply_nops(struct module *mod); extern int static_key_count(struct static_key *key); extern void static_key_enable(struct static_key *key); extern void static_key_disable(struct static_key *key); +extern void static_key_enable_cpuslocked(struct static_key *key); +extern void static_key_disable_cpuslocked(struct static_key *key); /* * We should be using ATOMIC_INIT() for initializing .enabled, but @@ -234,24 +236,29 @@ static inline int jump_label_apply_nops(struct module *mod) static inline void static_key_enable(struct static_key *key) { - int count = static_key_count(key); - - WARN_ON_ONCE(count < 0 || count > 1); + STATIC_KEY_CHECK_USE(); - if (!count) - static_key_slow_inc(key); + if (atomic_read(&key->enabled) != 0) { + WARN_ON_ONCE(atomic_read(&key->enabled) != 1); + return; + } + atomic_set(&key->enabled, 1); } static inline void static_key_disable(struct static_key *key) { - int count = static_key_count(key); - - WARN_ON_ONCE(count < 0 || count > 1); + STATIC_KEY_CHECK_USE(); - if (count) - static_key_slow_dec(key); + if (atomic_read(&key->enabled) != 1) { + WARN_ON_ONCE(atomic_read(&key->enabled) != 0); + return; + } + atomic_set(&key->enabled, 0); } +#define static_key_enable_cpuslocked(k) static_key_enable((k)) +#define static_key_disable_cpuslocked(k) static_key_disable((k)) + #define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) } #define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) } @@ -413,8 +420,10 @@ extern bool ____wrong_branch_error(void); * Normal usage; boolean enable/disable. */ -#define static_branch_enable(x) static_key_enable(&(x)->key) -#define static_branch_disable(x) static_key_disable(&(x)->key) +#define static_branch_enable(x) static_key_enable(&(x)->key) +#define static_branch_disable(x) static_key_disable(&(x)->key) +#define static_branch_enable_cpuslocked(x) static_key_enable_cpuslocked(&(x)->key) +#define static_branch_disable_cpuslocked(x) static_key_disable_cpuslocked(&(x)->key) #endif /* __ASSEMBLY__ */ diff --git a/include/linux/kasan-checks.h b/include/linux/kasan-checks.h index b7f8aced787075710487d370b202c399f2af086a..41960fecf7838d7160a2fa5a17e4a78eb0e55a33 100644 --- a/include/linux/kasan-checks.h +++ b/include/linux/kasan-checks.h @@ -2,11 +2,13 @@ #define _LINUX_KASAN_CHECKS_H #ifdef CONFIG_KASAN -void kasan_check_read(const void *p, unsigned int size); -void kasan_check_write(const void *p, unsigned int size); +void kasan_check_read(const volatile void *p, unsigned int size); +void kasan_check_write(const volatile void *p, unsigned int size); #else -static inline void kasan_check_read(const void *p, unsigned int size) { } -static inline void kasan_check_write(const void *p, unsigned int size) { } +static inline void kasan_check_read(const volatile void *p, unsigned int size) +{ } +static inline void kasan_check_write(const volatile void *p, unsigned int size) +{ } #endif #endif diff --git a/include/linux/kernel.h b/include/linux/kernel.h index bd6d96cf80b17cae9b4e15cb1e05e2a455ffd88a..0ad4c3044cf9333fa9664c2be0850e9596ab2206 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -78,8 +78,11 @@ #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP -#define DIV_ROUND_UP_ULL(ll,d) \ - ({ unsigned long long _tmp = (ll)+(d)-1; do_div(_tmp, d); _tmp; }) + +#define DIV_ROUND_DOWN_ULL(ll, d) \ + ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) + +#define DIV_ROUND_UP_ULL(ll, d) DIV_ROUND_DOWN_ULL((ll) + (d) - 1, (d)) #if BITS_PER_LONG == 32 # define DIV_ROUND_UP_SECTOR_T(ll,d) DIV_ROUND_UP_ULL(ll, d) @@ -277,6 +280,13 @@ extern int oops_may_print(void); void do_exit(long error_code) __noreturn; void complete_and_exit(struct completion *, long) __noreturn; +#ifdef CONFIG_ARCH_HAS_REFCOUNT +void refcount_error_report(struct pt_regs *regs, const char *err); +#else +static inline void refcount_error_report(struct pt_regs *regs, const char *err) +{ } +#endif + /* Internal, do not use. */ int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res); int __must_check _kstrtol(const char *s, unsigned int base, long *res); diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index a9b11b8d06f2ebcee9ecc40f143c1468d182236a..ab25c8b6d9e33d84bbaca9410af75339fa94385b 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -69,6 +69,12 @@ enum kernfs_root_flag { * following flag enables that behavior. */ KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK = 0x0002, + + /* + * The filesystem supports exportfs operation, so userspace can use + * fhandle to access nodes of the fs. + */ + KERNFS_ROOT_SUPPORT_EXPORTOP = 0x0004, }; /* type-specific structures for kernfs_node union members */ @@ -95,6 +101,21 @@ struct kernfs_elem_attr { struct kernfs_node *notify_next; /* for kernfs_notify() */ }; +/* represent a kernfs node */ +union kernfs_node_id { + struct { + /* + * blktrace will export this struct as a simplified 'struct + * fid' (which is a big data struction), so userspace can use + * it to find kernfs node. The layout must match the first two + * fields of 'struct fid' exactly. + */ + u32 ino; + u32 generation; + }; + u64 id; +}; + /* * kernfs_node - the building block of kernfs hierarchy. Each and every * kernfs node is represented by single kernfs_node. Most fields are @@ -131,9 +152,9 @@ struct kernfs_node { void *priv; + union kernfs_node_id id; unsigned short flags; umode_t mode; - unsigned int ino; struct kernfs_iattrs *iattr; }; @@ -163,7 +184,8 @@ struct kernfs_root { unsigned int flags; /* KERNFS_ROOT_* flags */ /* private fields, do not use outside kernfs proper */ - struct ida ino_ida; + struct idr ino_idr; + u32 next_generation; struct kernfs_syscall_ops *syscall_ops; /* list of kernfs_super_info of this root, protected by kernfs_mutex */ @@ -336,6 +358,8 @@ struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns); void kernfs_init(void); +struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root, + const union kernfs_node_id *id); #else /* CONFIG_KERNFS */ static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index dd056fab9e35c958c7aee14156e1df5640fb2556..2b7590f5483a1fc4474fbecddd099977222531cb 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -327,6 +327,14 @@ static inline void *boot_phys_to_virt(unsigned long entry) return phys_to_virt(boot_phys_to_phys(entry)); } +#ifndef arch_kexec_post_alloc_pages +static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp) { return 0; } +#endif + +#ifndef arch_kexec_pre_free_pages +static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { } +#endif + #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; diff --git a/include/linux/key.h b/include/linux/key.h index 044114185120633b8ca5c678b22570c3c2f8e264..e315e16b6ff8a0aaade2552ee404d35e27da5570 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -187,6 +187,7 @@ struct key { #define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */ #define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ #define KEY_FLAG_KEEP 10 /* set if key should not be removed */ +#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */ /* the key type and key description string * - the desc is used to match a key against search criteria @@ -243,6 +244,7 @@ extern struct key *key_alloc(struct key_type *type, #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ #define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */ #define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */ +#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */ extern void key_revoke(struct key *key); extern void key_invalidate(struct key *key); diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 655082c88fd93b5057fc641d196aae66d805850b..40c89ad4bea6adf829eeb54f34d2328a577c4b1e 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -19,6 +19,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include @@ -44,63 +45,4 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS; #define try_then_request_module(x, mod...) (x) #endif - -struct cred; -struct file; - -#define UMH_NO_WAIT 0 /* don't wait at all */ -#define UMH_WAIT_EXEC 1 /* wait for the exec, but not the process */ -#define UMH_WAIT_PROC 2 /* wait for the process to complete */ -#define UMH_KILLABLE 4 /* wait for EXEC/PROC killable */ - -struct subprocess_info { - struct work_struct work; - struct completion *complete; - const char *path; - char **argv; - char **envp; - int wait; - int retval; - int (*init)(struct subprocess_info *info, struct cred *new); - void (*cleanup)(struct subprocess_info *info); - void *data; -} __randomize_layout; - -extern int -call_usermodehelper(const char *path, char **argv, char **envp, int wait); - -extern struct subprocess_info * -call_usermodehelper_setup(const char *path, char **argv, char **envp, - gfp_t gfp_mask, - int (*init)(struct subprocess_info *info, struct cred *new), - void (*cleanup)(struct subprocess_info *), void *data); - -extern int -call_usermodehelper_exec(struct subprocess_info *info, int wait); - -extern struct ctl_table usermodehelper_table[]; - -enum umh_disable_depth { - UMH_ENABLED = 0, - UMH_FREEZING, - UMH_DISABLED, -}; - -extern int __usermodehelper_disable(enum umh_disable_depth depth); -extern void __usermodehelper_set_disable_depth(enum umh_disable_depth depth); - -static inline int usermodehelper_disable(void) -{ - return __usermodehelper_disable(UMH_DISABLED); -} - -static inline void usermodehelper_enable(void) -{ - __usermodehelper_set_disable_depth(UMH_ENABLED); -} - -extern int usermodehelper_read_trylock(void); -extern long usermodehelper_read_lock_wait(long timeout); -extern void usermodehelper_read_unlock(void); - #endif /* __LINUX_KMOD_H__ */ diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 4d800c79475a29fca0cf87c6936174c4ffd509d2..e0a6205caa71ad2fd78853c3eafb2b06e227e58e 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -57,6 +57,8 @@ enum kobject_action { KOBJ_MOVE, KOBJ_ONLINE, KOBJ_OFFLINE, + KOBJ_BIND, + KOBJ_UNBIND, KOBJ_MAX }; diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 4fec8b7758951cf9395613b072659efdce33e1d1..82e197eeac91f2bff8b62df9a58c75b5645b1ca2 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -15,7 +15,7 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), * @threadfn: the function to run in the thread * @data: data pointer for @threadfn() * @namefmt: printf-style format string for the thread name - * @...: arguments for @namefmt. + * @arg...: arguments for @namefmt. * * This macro will create a kthread on the current node, leaving it in * the stopped state. This is just a helper for kthread_create_on_node(); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 890b706d194348c99517ddf23266de860a395f2e..6882538eda329fb4a59c4bb1b2957003f6fdb9e9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -477,7 +477,8 @@ struct kvm { static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) { return srcu_dereference_check(kvm->buses[idx], &kvm->srcu, - lockdep_is_held(&kvm->slots_lock)); + lockdep_is_held(&kvm->slots_lock) || + !refcount_read(&kvm->users_count)); } static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) @@ -570,7 +571,8 @@ void kvm_put_kvm(struct kvm *kvm); static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) { return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu, - lockdep_is_held(&kvm->slots_lock)); + lockdep_is_held(&kvm->slots_lock) || + !refcount_read(&kvm->users_count)); } static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm) @@ -718,7 +720,7 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu); bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu); void kvm_vcpu_kick(struct kvm_vcpu *vcpu); int kvm_vcpu_yield_to(struct kvm_vcpu *target); -void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu); +void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu, bool usermode_vcpu_not_eligible); void kvm_load_guest_fpu(struct kvm_vcpu *vcpu); void kvm_put_guest_fpu(struct kvm_vcpu *vcpu); @@ -798,6 +800,7 @@ int kvm_arch_hardware_setup(void); void kvm_arch_hardware_unsetup(void); void kvm_arch_check_processor_compat(void *rtn); int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); #ifndef __KVM_HAVE_ARCH_VM_ALLOC @@ -983,6 +986,12 @@ static inline hpa_t pfn_to_hpa(kvm_pfn_t pfn) return (hpa_t)pfn << PAGE_SHIFT; } +static inline struct page *kvm_vcpu_gpa_to_page(struct kvm_vcpu *vcpu, + gpa_t gpa) +{ + return kvm_vcpu_gfn_to_page(vcpu, gpa_to_gfn(gpa)); +} + static inline bool kvm_is_error_gpa(struct kvm *kvm, gpa_t gpa) { unsigned long hva = gfn_to_hva(kvm, gpa_to_gfn(gpa)); diff --git a/include/linux/leds.h b/include/linux/leds.h index 64c56d454f7df9f864a5242ce4212df586f66886..bf6db4fe895bcd67e04ee65e8f76ea104af6299f 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -49,6 +49,7 @@ struct led_classdev { #define LED_HW_PLUGGABLE (1 << 19) #define LED_PANIC_INDICATOR (1 << 20) #define LED_BRIGHT_HW_CHANGED (1 << 21) +#define LED_RETAIN_AT_SHUTDOWN (1 << 22) /* set_brightness_work / blink_timer flags, atomic, private. */ unsigned long work_flags; @@ -392,6 +393,7 @@ struct gpio_led { unsigned retain_state_suspended : 1; unsigned panic_indicator : 1; unsigned default_state : 2; + unsigned retain_state_shutdown : 1; /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ struct gpio_desc *gpiod; }; diff --git a/include/linux/lguest.h b/include/linux/lguest.h deleted file mode 100644 index 6db19f35f7c51e9d3206d8d839724bcfb6256a5d..0000000000000000000000000000000000000000 --- a/include/linux/lguest.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Things the lguest guest needs to know. Note: like all lguest interfaces, - * this is subject to wild and random change between versions. - */ -#ifndef _LINUX_LGUEST_H -#define _LINUX_LGUEST_H - -#ifndef __ASSEMBLY__ -#include -#include -#include - -#define LG_CLOCK_MIN_DELTA 100UL -#define LG_CLOCK_MAX_DELTA ULONG_MAX - -/*G:031 - * The second method of communicating with the Host is to via "struct - * lguest_data". Once the Guest's initialization hypercall tells the Host where - * this is, the Guest and Host both publish information in it. -:*/ -struct lguest_data { - /* - * 512 == enabled (same as eflags in normal hardware). The Guest - * changes interrupts so often that a hypercall is too slow. - */ - unsigned int irq_enabled; - /* Fine-grained interrupt disabling by the Guest */ - DECLARE_BITMAP(blocked_interrupts, LGUEST_IRQS); - - /* - * The Host writes the virtual address of the last page fault here, - * which saves the Guest a hypercall. CR2 is the native register where - * this address would normally be found. - */ - unsigned long cr2; - - /* Wallclock time set by the Host. */ - struct timespec time; - - /* - * Interrupt pending set by the Host. The Guest should do a hypercall - * if it re-enables interrupts and sees this set (to X86_EFLAGS_IF). - */ - int irq_pending; - - /* - * Async hypercall ring. Instead of directly making hypercalls, we can - * place them in here for processing the next time the Host wants. - * This batching can be quite efficient. - */ - - /* 0xFF == done (set by Host), 0 == pending (set by Guest). */ - u8 hcall_status[LHCALL_RING_SIZE]; - /* The actual registers for the hypercalls. */ - struct hcall_args hcalls[LHCALL_RING_SIZE]; - -/* Fields initialized by the Host at boot: */ - /* Memory not to try to access */ - unsigned long reserve_mem; - /* KHz for the TSC clock. */ - u32 tsc_khz; - -/* Fields initialized by the Guest at boot: */ - /* Instruction to suppress interrupts even if enabled */ - unsigned long noirq_iret; - /* Address above which page tables are all identical. */ - unsigned long kernel_address; - /* The vector to try to use for system calls (0x40 or 0x80). */ - unsigned int syscall_vec; -}; -extern struct lguest_data lguest_data; -#endif /* __ASSEMBLY__ */ -#endif /* _LINUX_LGUEST_H */ diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h deleted file mode 100644 index acd5b12565cc2725724ed8a65692df9142634fae..0000000000000000000000000000000000000000 --- a/include/linux/lguest_launcher.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _LINUX_LGUEST_LAUNCHER -#define _LINUX_LGUEST_LAUNCHER -/* Everything the "lguest" userspace program needs to know. */ -#include - -/*D:010 - * Drivers - * - * The Guest needs devices to do anything useful. Since we don't let it touch - * real devices (think of the damage it could do!) we provide virtual devices. - * We emulate a PCI bus with virtio devices on it; we used to have our own - * lguest bus which was far simpler, but this tests the virtio 1.0 standard. - * - * Virtio devices are also used by kvm, so we can simply reuse their optimized - * device drivers. And one day when everyone uses virtio, my plan will be - * complete. Bwahahahah! - */ - -/* Write command first word is a request. */ -enum lguest_req -{ - LHREQ_INITIALIZE, /* + base, pfnlimit, start */ - LHREQ_GETDMA, /* No longer used */ - LHREQ_IRQ, /* + irq */ - LHREQ_BREAK, /* No longer used */ - LHREQ_EVENTFD, /* No longer used. */ - LHREQ_GETREG, /* + offset within struct pt_regs (then read value). */ - LHREQ_SETREG, /* + offset within struct pt_regs, value. */ - LHREQ_TRAP, /* + trap number to deliver to guest. */ -}; - -/* - * This is what read() of the lguest fd populates. trap == - * LGUEST_TRAP_ENTRY for an LHCALL_NOTIFY (addr is the - * argument), 14 for a page fault in the MMIO region (addr is - * the trap address, insn is the instruction), or 13 for a GPF - * (insn is the instruction). - */ -struct lguest_pending { - __u8 trap; - __u8 insn[7]; - __u32 addr; -}; -#endif /* _LINUX_LGUEST_LAUNCHER */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 55de3da58b1c4f5582f95e09a868f6ffb1de852a..931c32f1f18d38835425eb21a4c952e1195e4f10 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -435,7 +435,7 @@ enum { ATA_HORKAGE_NOLPM = (1 << 20), /* don't use LPM */ ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21), /* some WDs have broken LPM */ ATA_HORKAGE_ZERO_AFTER_TRIM = (1 << 22),/* guarantees zero after trim */ - ATA_HORKAGE_NO_NCQ_LOG = (1 << 23), /* don't use NCQ for log read */ + ATA_HORKAGE_NO_DMA_LOG = (1 << 23), /* don't use DMA for log read */ ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */ ATA_HORKAGE_MAX_SEC_1024 = (1 << 25), /* Limit max sects to 1024 */ diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index f3d3e6af8838d9949426a9448e744bbb20cde770..3eaad2fbf284ea81688316a6a623f062adeadb4c 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -87,6 +87,7 @@ struct nd_mapping_desc { struct nvdimm *nvdimm; u64 start; u64 size; + int position; }; struct nd_region_desc { @@ -173,4 +174,19 @@ u64 nd_fletcher64(void *addr, size_t len, bool le); void nvdimm_flush(struct nd_region *nd_region); int nvdimm_has_flush(struct nd_region *nd_region); int nvdimm_has_cache(struct nd_region *nd_region); + +#ifdef CONFIG_ARCH_HAS_PMEM_API +#define ARCH_MEMREMAP_PMEM MEMREMAP_WB +void arch_wb_cache_pmem(void *addr, size_t size); +void arch_invalidate_pmem(void *addr, size_t size); +#else +#define ARCH_MEMREMAP_PMEM MEMREMAP_WT +static inline void arch_wb_cache_pmem(void *addr, size_t size) +{ +} +static inline void arch_invalidate_pmem(void *addr, size_t size) +{ +} +#endif + #endif /* __LIBNVDIMM_H__ */ diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index fffe49f188e6d22dfb53ad86e7c53da44a287974..bfa8e0b0d6f1b26442fbe1f36be54b749dffb7bc 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -18,6 +18,8 @@ extern int lock_stat; #define MAX_LOCKDEP_SUBCLASSES 8UL +#include + #ifdef CONFIG_LOCKDEP #include @@ -29,7 +31,7 @@ extern int lock_stat; * We'd rather not expose kernel/lockdep_states.h this wide, but we do need * the total number of states... :-( */ -#define XXX_LOCK_USAGE_STATES (1+3*4) +#define XXX_LOCK_USAGE_STATES (1+2*4) /* * NR_LOCKDEP_CACHING_CLASSES ... Number of classes @@ -155,6 +157,12 @@ struct lockdep_map { int cpu; unsigned long ip; #endif +#ifdef CONFIG_LOCKDEP_CROSSRELEASE + /* + * Whether it's a crosslock. + */ + int cross; +#endif }; static inline void lockdep_copy_map(struct lockdep_map *to, @@ -258,8 +266,95 @@ struct held_lock { unsigned int hardirqs_off:1; unsigned int references:12; /* 32 bits */ unsigned int pin_count; +#ifdef CONFIG_LOCKDEP_CROSSRELEASE + /* + * Generation id. + * + * A value of cross_gen_id will be stored when holding this, + * which is globally increased whenever each crosslock is held. + */ + unsigned int gen_id; +#endif +}; + +#ifdef CONFIG_LOCKDEP_CROSSRELEASE +#define MAX_XHLOCK_TRACE_ENTRIES 5 + +/* + * This is for keeping locks waiting for commit so that true dependencies + * can be added at commit step. + */ +struct hist_lock { + /* + * Id for each entry in the ring buffer. This is used to + * decide whether the ring buffer was overwritten or not. + * + * For example, + * + * |<----------- hist_lock ring buffer size ------->| + * pppppppppppppppppppppiiiiiiiiiiiiiiiiiiiiiiiiiiiii + * wrapped > iiiiiiiiiiiiiiiiiiiiiiiiiii....................... + * + * where 'p' represents an acquisition in process + * context, 'i' represents an acquisition in irq + * context. + * + * In this example, the ring buffer was overwritten by + * acquisitions in irq context, that should be detected on + * rollback or commit. + */ + unsigned int hist_id; + + /* + * Seperate stack_trace data. This will be used at commit step. + */ + struct stack_trace trace; + unsigned long trace_entries[MAX_XHLOCK_TRACE_ENTRIES]; + + /* + * Seperate hlock instance. This will be used at commit step. + * + * TODO: Use a smaller data structure containing only necessary + * data. However, we should make lockdep code able to handle the + * smaller one first. + */ + struct held_lock hlock; +}; + +/* + * To initialize a lock as crosslock, lockdep_init_map_crosslock() should + * be called instead of lockdep_init_map(). + */ +struct cross_lock { + /* + * When more than one acquisition of crosslocks are overlapped, + * we have to perform commit for them based on cross_gen_id of + * the first acquisition, which allows us to add more true + * dependencies. + * + * Moreover, when no acquisition of a crosslock is in progress, + * we should not perform commit because the lock might not exist + * any more, which might cause incorrect memory access. So we + * have to track the number of acquisitions of a crosslock. + */ + int nr_acquire; + + /* + * Seperate hlock instance. This will be used at commit step. + * + * TODO: Use a smaller data structure containing only necessary + * data. However, we should make lockdep code able to handle the + * smaller one first. + */ + struct held_lock hlock; }; +struct lockdep_map_cross { + struct lockdep_map map; + struct cross_lock xlock; +}; +#endif + /* * Initialization, self-test and debugging-output methods: */ @@ -281,13 +376,6 @@ extern void lockdep_on(void); extern void lockdep_init_map(struct lockdep_map *lock, const char *name, struct lock_class_key *key, int subclass); -/* - * To initialize a lockdep_map statically use this macro. - * Note that _name must not be NULL. - */ -#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ - { .name = (_name), .key = (void *)(_key), } - /* * Reinitialize a lock key - for cases where there is special locking or * special initialization of locks so that the validator gets the scope @@ -363,10 +451,6 @@ static inline void lock_set_subclass(struct lockdep_map *lock, extern void lock_downgrade(struct lockdep_map *lock, unsigned long ip); -extern void lockdep_set_current_reclaim_state(gfp_t gfp_mask); -extern void lockdep_clear_current_reclaim_state(void); -extern void lockdep_trace_alloc(gfp_t mask); - struct pin_cookie { unsigned int val; }; #define NIL_COOKIE (struct pin_cookie){ .val = 0U, } @@ -375,7 +459,7 @@ extern struct pin_cookie lock_pin_lock(struct lockdep_map *lock); extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); -# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, +# define INIT_LOCKDEP .lockdep_recursion = 0, #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) @@ -416,9 +500,6 @@ static inline void lockdep_on(void) # define lock_downgrade(l, i) do { } while (0) # define lock_set_class(l, n, k, s, i) do { } while (0) # define lock_set_subclass(l, s, i) do { } while (0) -# define lockdep_set_current_reclaim_state(g) do { } while (0) -# define lockdep_clear_current_reclaim_state() do { } while (0) -# define lockdep_trace_alloc(g) do { } while (0) # define lockdep_info() do { } while (0) # define lockdep_init_map(lock, name, key, sub) \ do { (void)(name); (void)(key); } while (0) @@ -467,6 +548,58 @@ struct pin_cookie { }; #endif /* !LOCKDEP */ +enum xhlock_context_t { + XHLOCK_HARD, + XHLOCK_SOFT, + XHLOCK_CTX_NR, +}; + +#ifdef CONFIG_LOCKDEP_CROSSRELEASE +extern void lockdep_init_map_crosslock(struct lockdep_map *lock, + const char *name, + struct lock_class_key *key, + int subclass); +extern void lock_commit_crosslock(struct lockdep_map *lock); + +/* + * What we essencially have to initialize is 'nr_acquire'. Other members + * will be initialized in add_xlock(). + */ +#define STATIC_CROSS_LOCK_INIT() \ + { .nr_acquire = 0,} + +#define STATIC_CROSS_LOCKDEP_MAP_INIT(_name, _key) \ + { .map.name = (_name), .map.key = (void *)(_key), \ + .map.cross = 1, .xlock = STATIC_CROSS_LOCK_INIT(), } + +/* + * To initialize a lockdep_map statically use this macro. + * Note that _name must not be NULL. + */ +#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ + { .name = (_name), .key = (void *)(_key), .cross = 0, } + +extern void crossrelease_hist_start(enum xhlock_context_t c); +extern void crossrelease_hist_end(enum xhlock_context_t c); +extern void lockdep_invariant_state(bool force); +extern void lockdep_init_task(struct task_struct *task); +extern void lockdep_free_task(struct task_struct *task); +#else /* !CROSSRELEASE */ +#define lockdep_init_map_crosslock(m, n, k, s) do {} while (0) +/* + * To initialize a lockdep_map statically use this macro. + * Note that _name must not be NULL. + */ +#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ + { .name = (_name), .key = (void *)(_key), } + +static inline void crossrelease_hist_start(enum xhlock_context_t c) {} +static inline void crossrelease_hist_end(enum xhlock_context_t c) {} +static inline void lockdep_invariant_state(bool force) {} +static inline void lockdep_init_task(struct task_struct *task) {} +static inline void lockdep_free_task(struct task_struct *task) {} +#endif /* CROSSRELEASE */ + #ifdef CONFIG_LOCK_STAT extern void lock_contended(struct lockdep_map *lock, unsigned long ip); diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index 22b5d4e687ce0f3a3c2f226845390e5ca91b7385..d1c2901f15420dd331ac70a004b699ae7f76c455 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h @@ -4,7 +4,7 @@ * * Author : Etienne BASSET * - * All credits to : Stephen Smalley, + * All credits to : Stephen Smalley, * All BUGS to : Etienne BASSET */ #ifndef _LSM_COMMON_LOGGING_ diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 3a90febadbe20e6756819dcd04e235a05fb7d99e..c9258124e41757187cdb8b2f83c5901966345902 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -43,7 +43,11 @@ * interpreters. The hook can tell whether it has already been called by * checking to see if @bprm->security is non-NULL. If so, then the hook * may decide either to retain the security information saved earlier or - * to replace it. + * to replace it. The hook must set @bprm->secureexec to 1 if a "secure + * exec" has happened as a result of this hook call. The flag is used to + * indicate the need for a sanitized execution environment, and is also + * passed in the ELF auxiliary table on the initial stack to indicate + * whether libc should enable secure mode. * @bprm contains the linux_binprm structure. * Return 0 if the hook is successful and permission is granted. * @bprm_check_security: @@ -71,12 +75,6 @@ * linux_binprm structure. This hook is a good place to perform state * changes on the process such as clearing out non-inheritable signal * state. This is called immediately after commit_creds(). - * @bprm_secureexec: - * Return a boolean value (0 or 1) indicating whether a "secure exec" - * is required. The flag is passed in the auxiliary table - * on the initial stack to the ELF interpreter to indicate whether libc - * should enable secure mode. - * @bprm contains the linux_binprm structure. * * Security hooks for filesystem operations. * @@ -530,11 +528,6 @@ * * Security hooks for task operations. * - * @task_create: - * Check permission before creating a child process. See the clone(2) - * manual page for definitions of the @clone_flags. - * @clone_flags contains the flags indicating what should be shared. - * Return 0 if permission is granted. * @task_alloc: * @task task being allocated. * @clone_flags contains the flags indicating what should be shared. @@ -1388,7 +1381,6 @@ union security_list_options { int (*bprm_set_creds)(struct linux_binprm *bprm); int (*bprm_check_security)(struct linux_binprm *bprm); - int (*bprm_secureexec)(struct linux_binprm *bprm); void (*bprm_committing_creds)(struct linux_binprm *bprm); void (*bprm_committed_creds)(struct linux_binprm *bprm); @@ -1508,7 +1500,6 @@ union security_list_options { int (*file_receive)(struct file *file); int (*file_open)(struct file *file, const struct cred *cred); - int (*task_create)(unsigned long clone_flags); int (*task_alloc)(struct task_struct *task, unsigned long clone_flags); void (*task_free)(struct task_struct *task); int (*cred_alloc_blank)(struct cred *cred, gfp_t gfp); @@ -1710,7 +1701,6 @@ struct security_hook_heads { struct list_head vm_enough_memory; struct list_head bprm_set_creds; struct list_head bprm_check_security; - struct list_head bprm_secureexec; struct list_head bprm_committing_creds; struct list_head bprm_committed_creds; struct list_head sb_alloc_security; @@ -1783,7 +1773,6 @@ struct security_hook_heads { struct list_head file_send_sigiotask; struct list_head file_receive; struct list_head file_open; - struct list_head task_create; struct list_head task_alloc; struct list_head task_free; struct list_head cred_alloc_blank; diff --git a/include/linux/mcb.h b/include/linux/mcb.h index 4097ac9ea13accda06500a7605a4ca8a3632112f..b1a0ad9d23b3070ffb3fd5a8adc07d6330e96739 100644 --- a/include/linux/mcb.h +++ b/include/linux/mcb.h @@ -136,5 +136,7 @@ extern struct resource *mcb_request_mem(struct mcb_device *dev, const char *name); extern void mcb_release_mem(struct resource *mem); extern int mcb_get_irq(struct mcb_device *dev); +extern struct resource *mcb_get_resource(struct mcb_device *dev, + unsigned int type); #endif /* _LINUX_MCB_H */ diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h index 61f5b21b31c7782318c9cf6be916d96e91012747..a5d58f22193967d19d947b368fe3ae810079e0b5 100644 --- a/include/linux/mdio-mux.h +++ b/include/linux/mdio-mux.h @@ -12,7 +12,16 @@ #include #include +/* mdio_mux_init() - Initialize a MDIO mux + * @dev The device owning the MDIO mux + * @mux_node The device node of the MDIO mux + * @switch_fn The function called for switching target MDIO child + * mux_handle A pointer to a (void *) used internaly by mdio-mux + * @data Private data used by switch_fn() + * @mux_bus An optional parent bus (Other case are to use parent_bus property) + */ int mdio_mux_init(struct device *dev, + struct device_node *mux_node, int (*switch_fn) (int cur, int desired, void *data), void **mux_handle, void *data, diff --git a/include/linux/mem_encrypt.h b/include/linux/mem_encrypt.h new file mode 100644 index 0000000000000000000000000000000000000000..265a9cd21cb418e4aae78bf6bc476ec463933670 --- /dev/null +++ b/include/linux/mem_encrypt.h @@ -0,0 +1,53 @@ +/* + * AMD Memory Encryption Support + * + * Copyright (C) 2016 Advanced Micro Devices, Inc. + * + * Author: Tom Lendacky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MEM_ENCRYPT_H__ +#define __MEM_ENCRYPT_H__ + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_ARCH_HAS_MEM_ENCRYPT + +#include + +#else /* !CONFIG_ARCH_HAS_MEM_ENCRYPT */ + +#define sme_me_mask 0ULL + +#endif /* CONFIG_ARCH_HAS_MEM_ENCRYPT */ + +static inline bool sme_active(void) +{ + return !!sme_me_mask; +} + +static inline u64 sme_get_me_mask(void) +{ + return sme_me_mask; +} + +#ifdef CONFIG_AMD_MEM_ENCRYPT +/* + * The __sme_set() and __sme_clr() macros are useful for adding or removing + * the encryption mask from a value (e.g. when dealing with pagetable + * entries). + */ +#define __sme_set(x) ((x) | sme_me_mask) +#define __sme_clr(x) ((x) & ~sme_me_mask) +#else +#define __sme_set(x) (x) +#define __sme_clr(x) (x) +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __MEM_ENCRYPT_H__ */ diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 77d427974f575699d181265a9eb4c8d1cdd4dad5..bae11c7e7bf31920fcf0b928b31dc29ad70f6f8b 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -61,6 +61,7 @@ extern int memblock_debug; #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK #define __init_memblock __meminit #define __initdata_memblock __meminitdata +void memblock_discard(void); #else #define __init_memblock #define __initdata_memblock @@ -74,8 +75,6 @@ phys_addr_t memblock_find_in_range_node(phys_addr_t size, phys_addr_t align, int nid, ulong flags); phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end, phys_addr_t size, phys_addr_t align); -phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr); -phys_addr_t get_allocated_memblock_memory_regions_info(phys_addr_t *addr); void memblock_allow_resize(void); int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid); int memblock_add(phys_addr_t base, phys_addr_t size); @@ -110,6 +109,9 @@ void __next_mem_range_rev(u64 *idx, int nid, ulong flags, void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start, phys_addr_t *out_end); +void __memblock_free_early(phys_addr_t base, phys_addr_t size); +void __memblock_free_late(phys_addr_t base, phys_addr_t size); + /** * for_each_mem_range - iterate through memblock areas from type_a and not * included in type_b. Or just type_a if type_b is NULL. diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 3914e3dd61680a9bc8814d9b9a386c59611eca81..69966c461d1c1164c155f3c5ff2ee9d4c7220911 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -484,11 +484,13 @@ bool mem_cgroup_oom_synchronize(bool wait); extern int do_swap_account; #endif -void lock_page_memcg(struct page *page); +struct mem_cgroup *lock_page_memcg(struct page *page); +void __unlock_page_memcg(struct mem_cgroup *memcg); void unlock_page_memcg(struct page *page); +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx) + int idx) { long val = 0; int cpu; @@ -502,15 +504,17 @@ static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, return val; } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void __mod_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx, int val) + int idx, int val) { if (!mem_cgroup_disabled()) __this_cpu_add(memcg->stat->count[idx], val); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void mod_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx, int val) + int idx, int val) { if (!mem_cgroup_disabled()) this_cpu_add(memcg->stat->count[idx], val); @@ -534,14 +538,14 @@ static inline void mod_memcg_state(struct mem_cgroup *memcg, * Kernel pages are an exception to this, since they'll never move. */ static inline void __mod_memcg_page_state(struct page *page, - enum memcg_stat_item idx, int val) + int idx, int val) { if (page->mem_cgroup) __mod_memcg_state(page->mem_cgroup, idx, val); } static inline void mod_memcg_page_state(struct page *page, - enum memcg_stat_item idx, int val) + int idx, int val) { if (page->mem_cgroup) mod_memcg_state(page->mem_cgroup, idx, val); @@ -631,8 +635,9 @@ static inline void count_memcg_events(struct mem_cgroup *memcg, this_cpu_add(memcg->stat->events[idx], count); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void count_memcg_page_event(struct page *page, - enum memcg_stat_item idx) + int idx) { if (page->mem_cgroup) count_memcg_events(page->mem_cgroup, idx, 1); @@ -809,7 +814,12 @@ mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) { } -static inline void lock_page_memcg(struct page *page) +static inline struct mem_cgroup *lock_page_memcg(struct page *page) +{ + return NULL; +} + +static inline void __unlock_page_memcg(struct mem_cgroup *memcg) { } @@ -840,31 +850,31 @@ static inline bool mem_cgroup_oom_synchronize(bool wait) } static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx) + int idx) { return 0; } static inline void __mod_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx, + int idx, int nr) { } static inline void mod_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx, + int idx, int nr) { } static inline void __mod_memcg_page_state(struct page *page, - enum memcg_stat_item idx, + int idx, int nr) { } static inline void mod_memcg_page_state(struct page *page, - enum memcg_stat_item idx, + int idx, int nr) { } @@ -918,7 +928,7 @@ static inline void count_memcg_events(struct mem_cgroup *memcg, } static inline void count_memcg_page_event(struct page *page, - enum memcg_stat_item idx) + int idx) { } @@ -928,26 +938,30 @@ void count_memcg_event_mm(struct mm_struct *mm, enum vm_event_item idx) } #endif /* CONFIG_MEMCG */ +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void __inc_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx) + int idx) { __mod_memcg_state(memcg, idx, 1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void __dec_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx) + int idx) { __mod_memcg_state(memcg, idx, -1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void __inc_memcg_page_state(struct page *page, - enum memcg_stat_item idx) + int idx) { __mod_memcg_page_state(page, idx, 1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void __dec_memcg_page_state(struct page *page, - enum memcg_stat_item idx) + int idx) { __mod_memcg_page_state(page, idx, -1); } @@ -976,26 +990,30 @@ static inline void __dec_lruvec_page_state(struct page *page, __mod_lruvec_page_state(page, idx, -1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void inc_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx) + int idx) { mod_memcg_state(memcg, idx, 1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void dec_memcg_state(struct mem_cgroup *memcg, - enum memcg_stat_item idx) + int idx) { mod_memcg_state(memcg, idx, -1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void inc_memcg_page_state(struct page *page, - enum memcg_stat_item idx) + int idx) { mod_memcg_page_state(page, idx, 1); } +/* idx can be of type enum memcg_stat_item or node_stat_item */ static inline void dec_memcg_page_state(struct page *page, - enum memcg_stat_item idx) + int idx) { mod_memcg_page_state(page, idx, -1); } diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index c8a5056a5ae0ec05bf327e54a81ed659ba71143a..0995e1a2b4583138953d395e3d10b389b0cb0609 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -133,6 +133,17 @@ extern int __remove_pages(struct zone *zone, unsigned long start_pfn, extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, bool want_memblock); +#ifndef CONFIG_ARCH_HAS_ADD_PAGES +static inline int add_pages(int nid, unsigned long start_pfn, + unsigned long nr_pages, bool want_memblock) +{ + return __add_pages(nid, start_pfn, nr_pages, want_memblock); +} +#else /* ARCH_HAS_ADD_PAGES */ +int add_pages(int nid, unsigned long start_pfn, + unsigned long nr_pages, bool want_memblock); +#endif /* ARCH_HAS_ADD_PAGES */ + #ifdef CONFIG_NUMA extern int memory_add_physaddr_to_nid(u64 start); #else @@ -319,6 +330,6 @@ extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pnum); extern bool allow_online_pfn_range(int nid, unsigned long pfn, unsigned long nr_pages, int online_type); -extern struct zone *default_zone_for_pfn(int nid, unsigned long pfn, +extern struct zone *zone_for_pfn_range(int online_type, int nid, unsigned start_pfn, unsigned long nr_pages); #endif /* __LINUX_MEMORY_HOTPLUG_H */ diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 93416196ba64f6b4747ad9f37aaf5a913ff3ac29..79f8ba7c38940953182d05a59df970d06acc13fc 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -4,6 +4,8 @@ #include #include +#include + struct resource; struct device; @@ -35,24 +37,107 @@ static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start) } #endif +/* + * Specialize ZONE_DEVICE memory into multiple types each having differents + * usage. + * + * MEMORY_DEVICE_HOST: + * Persistent device memory (pmem): struct page might be allocated in different + * memory and architecture might want to perform special actions. It is similar + * to regular memory, in that the CPU can access it transparently. However, + * it is likely to have different bandwidth and latency than regular memory. + * See Documentation/nvdimm/nvdimm.txt for more information. + * + * MEMORY_DEVICE_PRIVATE: + * Device memory that is not directly addressable by the CPU: CPU can neither + * read nor write private memory. In this case, we do still have struct pages + * backing the device memory. Doing so simplifies the implementation, but it is + * important to remember that there are certain points at which the struct page + * must be treated as an opaque object, rather than a "normal" struct page. + * + * A more complete discussion of unaddressable memory may be found in + * include/linux/hmm.h and Documentation/vm/hmm.txt. + * + * MEMORY_DEVICE_PUBLIC: + * Device memory that is cache coherent from device and CPU point of view. This + * is use on platform that have an advance system bus (like CAPI or CCIX). A + * driver can hotplug the device memory using ZONE_DEVICE and with that memory + * type. Any page of a process can be migrated to such memory. However no one + * should be allow to pin such memory so that it can always be evicted. + */ +enum memory_type { + MEMORY_DEVICE_HOST = 0, + MEMORY_DEVICE_PRIVATE, + MEMORY_DEVICE_PUBLIC, +}; + +/* + * For MEMORY_DEVICE_PRIVATE we use ZONE_DEVICE and extend it with two + * callbacks: + * page_fault() + * page_free() + * + * Additional notes about MEMORY_DEVICE_PRIVATE may be found in + * include/linux/hmm.h and Documentation/vm/hmm.txt. There is also a brief + * explanation in include/linux/memory_hotplug.h. + * + * The page_fault() callback must migrate page back, from device memory to + * system memory, so that the CPU can access it. This might fail for various + * reasons (device issues, device have been unplugged, ...). When such error + * conditions happen, the page_fault() callback must return VM_FAULT_SIGBUS and + * set the CPU page table entry to "poisoned". + * + * Note that because memory cgroup charges are transferred to the device memory, + * this should never fail due to memory restrictions. However, allocation + * of a regular system page might still fail because we are out of memory. If + * that happens, the page_fault() callback must return VM_FAULT_OOM. + * + * The page_fault() callback can also try to migrate back multiple pages in one + * chunk, as an optimization. It must, however, prioritize the faulting address + * over all the others. + * + * + * The page_free() callback is called once the page refcount reaches 1 + * (ZONE_DEVICE pages never reach 0 refcount unless there is a refcount bug. + * This allows the device driver to implement its own memory management.) + * + * For MEMORY_DEVICE_PUBLIC only the page_free() callback matter. + */ +typedef int (*dev_page_fault_t)(struct vm_area_struct *vma, + unsigned long addr, + const struct page *page, + unsigned int flags, + pmd_t *pmdp); +typedef void (*dev_page_free_t)(struct page *page, void *data); + /** * struct dev_pagemap - metadata for ZONE_DEVICE mappings + * @page_fault: callback when CPU fault on an unaddressable device page + * @page_free: free page callback when page refcount reaches 1 * @altmap: pre-allocated/reserved memory for vmemmap allocations * @res: physical address range covered by @ref * @ref: reference count that pins the devm_memremap_pages() mapping * @dev: host device of the mapping for debug + * @data: private data pointer for page_free() + * @type: memory type: see MEMORY_* in memory_hotplug.h */ struct dev_pagemap { + dev_page_fault_t page_fault; + dev_page_free_t page_free; struct vmem_altmap *altmap; const struct resource *res; struct percpu_ref *ref; struct device *dev; + void *data; + enum memory_type type; }; #ifdef CONFIG_ZONE_DEVICE void *devm_memremap_pages(struct device *dev, struct resource *res, struct percpu_ref *ref, struct vmem_altmap *altmap); struct dev_pagemap *find_dev_pagemap(resource_size_t phys); + +static inline bool is_zone_device_page(const struct page *page); #else static inline void *devm_memremap_pages(struct device *dev, struct resource *res, struct percpu_ref *ref, @@ -73,6 +158,20 @@ static inline struct dev_pagemap *find_dev_pagemap(resource_size_t phys) } #endif +#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC) +static inline bool is_device_private_page(const struct page *page) +{ + return is_zone_device_page(page) && + page->pgmap->type == MEMORY_DEVICE_PRIVATE; +} + +static inline bool is_device_public_page(const struct page *page) +{ + return is_zone_device_page(page) && + page->pgmap->type == MEMORY_DEVICE_PUBLIC; +} +#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ + /** * get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn * @pfn: page frame number to lookup page_map diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index 965b027e31b3de2275c79a981d1f3bac19165b7d..e9c908c4fba8a22418f6884081af5661b9144a56 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -23,6 +23,7 @@ enum axp20x_variants { AXP803_ID, AXP806_ID, AXP809_ID, + AXP813_ID, NR_AXP20X_VARIANTS, }; @@ -387,6 +388,34 @@ enum { AXP803_REG_ID_MAX, }; +enum { + AXP813_DCDC1 = 0, + AXP813_DCDC2, + AXP813_DCDC3, + AXP813_DCDC4, + AXP813_DCDC5, + AXP813_DCDC6, + AXP813_DCDC7, + AXP813_ALDO1, + AXP813_ALDO2, + AXP813_ALDO3, + AXP813_DLDO1, + AXP813_DLDO2, + AXP813_DLDO3, + AXP813_DLDO4, + AXP813_ELDO1, + AXP813_ELDO2, + AXP813_ELDO3, + AXP813_FLDO1, + AXP813_FLDO2, + AXP813_FLDO3, + AXP813_RTC_LDO, + AXP813_LDO_IO0, + AXP813_LDO_IO1, + AXP813_SW, + AXP813_REG_ID_MAX, +}; + /* IRQs */ enum { AXP152_IRQ_LDO0IN_CONNECT = 1, diff --git a/include/linux/mfd/bd9571mwv.h b/include/linux/mfd/bd9571mwv.h new file mode 100644 index 0000000000000000000000000000000000000000..f0708ba4cbbae2dccf68d0f17abae362a9c7ff66 --- /dev/null +++ b/include/linux/mfd/bd9571mwv.h @@ -0,0 +1,115 @@ +/* + * ROHM BD9571MWV-M driver + * + * Copyright (C) 2017 Marek Vasut + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + * + * Based on the TPS65086 driver + */ + +#ifndef __LINUX_MFD_BD9571MWV_H +#define __LINUX_MFD_BD9571MWV_H + +#include +#include + +/* List of registers for BD9571MWV */ +#define BD9571MWV_VENDOR_CODE 0x00 +#define BD9571MWV_VENDOR_CODE_VAL 0xdb +#define BD9571MWV_PRODUCT_CODE 0x01 +#define BD9571MWV_PRODUCT_CODE_VAL 0x60 +#define BD9571MWV_PRODUCT_REVISION 0x02 + +#define BD9571MWV_I2C_FUSA_MODE 0x10 +#define BD9571MWV_I2C_MD2_E1_BIT_1 0x11 +#define BD9571MWV_I2C_MD2_E1_BIT_2 0x12 + +#define BD9571MWV_BKUP_MODE_CNT 0x20 +#define BD9571MWV_BKUP_MODE_STATUS 0x21 +#define BD9571MWV_BKUP_RECOVERY_CNT 0x22 +#define BD9571MWV_BKUP_CTRL_TIM_CNT 0x23 +#define BD9571MWV_WAITBKUP_WDT_CNT 0x24 +#define BD9571MWV_128H_TIM_CNT 0x26 +#define BD9571MWV_QLLM_CNT 0x27 + +#define BD9571MWV_AVS_SET_MONI 0x31 +#define BD9571MWV_AVS_SET_MONI_MASK 0x3 +#define BD9571MWV_AVS_VD09_VID(n) (0x32 + (n)) +#define BD9571MWV_AVS_DVFS_VID(n) (0x36 + (n)) + +#define BD9571MWV_VD18_VID 0x42 +#define BD9571MWV_VD25_VID 0x43 +#define BD9571MWV_VD33_VID 0x44 + +#define BD9571MWV_DVFS_VINIT 0x50 +#define BD9571MWV_DVFS_SETVMAX 0x52 +#define BD9571MWV_DVFS_BOOSTVID 0x53 +#define BD9571MWV_DVFS_SETVID 0x54 +#define BD9571MWV_DVFS_MONIVDAC 0x55 +#define BD9571MWV_DVFS_PGD_CNT 0x56 + +#define BD9571MWV_GPIO_DIR 0x60 +#define BD9571MWV_GPIO_OUT 0x61 +#define BD9571MWV_GPIO_IN 0x62 +#define BD9571MWV_GPIO_DEB 0x63 +#define BD9571MWV_GPIO_INT_SET 0x64 +#define BD9571MWV_GPIO_INT 0x65 +#define BD9571MWV_GPIO_INTMASK 0x66 + +#define BD9571MWV_REG_KEEP(n) (0x70 + (n)) + +#define BD9571MWV_PMIC_INTERNAL_STATUS 0x80 +#define BD9571MWV_PROT_ERROR_STATUS0 0x81 +#define BD9571MWV_PROT_ERROR_STATUS1 0x82 +#define BD9571MWV_PROT_ERROR_STATUS2 0x83 +#define BD9571MWV_PROT_ERROR_STATUS3 0x84 +#define BD9571MWV_PROT_ERROR_STATUS4 0x85 + +#define BD9571MWV_INT_INTREQ 0x90 +#define BD9571MWV_INT_INTREQ_MD1_INT BIT(0) +#define BD9571MWV_INT_INTREQ_MD2_E1_INT BIT(1) +#define BD9571MWV_INT_INTREQ_MD2_E2_INT BIT(2) +#define BD9571MWV_INT_INTREQ_PROT_ERR_INT BIT(3) +#define BD9571MWV_INT_INTREQ_GP_INT BIT(4) +#define BD9571MWV_INT_INTREQ_128H_OF_INT BIT(5) +#define BD9571MWV_INT_INTREQ_WDT_OF_INT BIT(6) +#define BD9571MWV_INT_INTREQ_BKUP_TRG_INT BIT(7) +#define BD9571MWV_INT_INTMASK 0x91 + +#define BD9571MWV_ACCESS_KEY 0xff + +/* Define the BD9571MWV IRQ numbers */ +enum bd9571mwv_irqs { + BD9571MWV_IRQ_MD1, + BD9571MWV_IRQ_MD2_E1, + BD9571MWV_IRQ_MD2_E2, + BD9571MWV_IRQ_PROT_ERR, + BD9571MWV_IRQ_GP, + BD9571MWV_IRQ_128H_OF, + BD9571MWV_IRQ_WDT_OF, + BD9571MWV_IRQ_BKUP_TRG, +}; + +/** + * struct bd9571mwv - state holder for the bd9571mwv driver + * + * Device data may be used to access the BD9571MWV chip + */ +struct bd9571mwv { + struct device *dev; + struct regmap *regmap; + + /* IRQ Data */ + int irq; + struct regmap_irq_chip_data *irq_data; +}; + +#endif /* __LINUX_MFD_BD9571MWV_H */ diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index 190c8f4afa026706a3befa71734c572760f6f6e9..2b16e95b9bb8566d99a51ca175a904300449ce01 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -285,6 +285,11 @@ enum host_event_code { EC_HOST_EVENT_HANG_DETECT = 20, /* Hang detect logic detected a hang and warm rebooted the AP */ EC_HOST_EVENT_HANG_REBOOT = 21, + /* PD MCU triggering host event */ + EC_HOST_EVENT_PD_MCU = 22, + + /* EC desires to change state of host-controlled USB mux */ + EC_HOST_EVENT_USB_MUX = 28, /* * The high bit of the event mask is not used as a host event code. If @@ -2905,6 +2910,76 @@ struct ec_params_usb_pd_control { uint8_t mux; } __packed; +#define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */ +#define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */ +#define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */ + +struct ec_response_usb_pd_control_v1 { + uint8_t enabled; + uint8_t role; + uint8_t polarity; + char state[32]; +} __packed; + +#define EC_CMD_USB_PD_PORTS 0x102 + +struct ec_response_usb_pd_ports { + uint8_t num_ports; +} __packed; + +#define EC_CMD_USB_PD_POWER_INFO 0x103 + +#define PD_POWER_CHARGING_PORT 0xff +struct ec_params_usb_pd_power_info { + uint8_t port; +} __packed; + +enum usb_chg_type { + USB_CHG_TYPE_NONE, + USB_CHG_TYPE_PD, + USB_CHG_TYPE_C, + USB_CHG_TYPE_PROPRIETARY, + USB_CHG_TYPE_BC12_DCP, + USB_CHG_TYPE_BC12_CDP, + USB_CHG_TYPE_BC12_SDP, + USB_CHG_TYPE_OTHER, + USB_CHG_TYPE_VBUS, + USB_CHG_TYPE_UNKNOWN, +}; + +struct usb_chg_measures { + uint16_t voltage_max; + uint16_t voltage_now; + uint16_t current_max; + uint16_t current_lim; +} __packed; + +struct ec_response_usb_pd_power_info { + uint8_t role; + uint8_t type; + uint8_t dualrole; + uint8_t reserved1; + struct usb_chg_measures meas; + uint32_t max_power; +} __packed; + +/* Get info about USB-C SS muxes */ +#define EC_CMD_USB_PD_MUX_INFO 0x11a + +struct ec_params_usb_pd_mux_info { + uint8_t port; /* USB-C port number */ +} __packed; + +/* Flags representing mux state */ +#define USB_PD_MUX_USB_ENABLED (1 << 0) +#define USB_PD_MUX_DP_ENABLED (1 << 1) +#define USB_PD_MUX_POLARITY_INVERTED (1 << 2) +#define USB_PD_MUX_HPD_IRQ (1 << 3) + +struct ec_response_usb_pd_mux_info { + uint8_t flags; /* USB_PD_MUX_*-encoded USB mux state */ +} __packed; + /*****************************************************************************/ /* * Passthru commands diff --git a/include/linux/mfd/da9052/da9052.h b/include/linux/mfd/da9052/da9052.h index ce9230af09c20c0498e1111fdf148b8f6406b30e..ae5b663836d09bcac7bf86643bf2666282a8b072 100644 --- a/include/linux/mfd/da9052/da9052.h +++ b/include/linux/mfd/da9052/da9052.h @@ -45,6 +45,12 @@ #define DA9052_ADC_TJUNC 8 #define DA9052_ADC_VBBAT 9 +/* TSI channel has its own 4 channel mux */ +#define DA9052_ADC_TSI_XP 70 +#define DA9052_ADC_TSI_XN 71 +#define DA9052_ADC_TSI_YP 72 +#define DA9052_ADC_TSI_YN 73 + #define DA9052_IRQ_DCIN 0 #define DA9052_IRQ_VBUS 1 #define DA9052_IRQ_DCINREM 2 diff --git a/include/linux/mfd/da9052/reg.h b/include/linux/mfd/da9052/reg.h index 5010f978725c50c210128b50ba6b6934ec33f244..76780ea8849c91911b8e8fa332593a6d711631ea 100644 --- a/include/linux/mfd/da9052/reg.h +++ b/include/linux/mfd/da9052/reg.h @@ -690,7 +690,10 @@ /* TSI CONTROL REGISTER B BITS */ #define DA9052_TSICONTB_ADCREF 0X80 #define DA9052_TSICONTB_TSIMAN 0X40 -#define DA9052_TSICONTB_TSIMUX 0X30 +#define DA9052_TSICONTB_TSIMUX_XP 0X00 +#define DA9052_TSICONTB_TSIMUX_YP 0X10 +#define DA9052_TSICONTB_TSIMUX_XN 0X20 +#define DA9052_TSICONTB_TSIMUX_YN 0X30 #define DA9052_TSICONTB_TSISEL3 0X08 #define DA9052_TSICONTB_TSISEL2 0X04 #define DA9052_TSICONTB_TSISEL1 0X02 @@ -705,8 +708,14 @@ /* TSI CO-ORDINATE LSB RESULT REGISTER BITS */ #define DA9052_TSILSB_PENDOWN 0X40 #define DA9052_TSILSB_TSIZL 0X30 +#define DA9052_TSILSB_TSIZL_SHIFT 4 +#define DA9052_TSILSB_TSIZL_BITS 2 #define DA9052_TSILSB_TSIYL 0X0C +#define DA9052_TSILSB_TSIYL_SHIFT 2 +#define DA9052_TSILSB_TSIYL_BITS 2 #define DA9052_TSILSB_TSIXL 0X03 +#define DA9052_TSILSB_TSIXL_SHIFT 0 +#define DA9052_TSILSB_TSIXL_BITS 2 /* TSI Z MEASUREMENT MSB RESULT REGISTER BIT */ #define DA9052_TSIZMSB_TSIZM 0XFF diff --git a/include/linux/i2c/dm355evm_msp.h b/include/linux/mfd/dm355evm_msp.h similarity index 100% rename from include/linux/i2c/dm355evm_msp.h rename to include/linux/mfd/dm355evm_msp.h diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h index 38a372a0e2854fed3f06b790f4f591ca052661c7..2227c6a75d84953f5e93122d76ea13d123670863 100644 --- a/include/linux/mfd/ds1wm.h +++ b/include/linux/mfd/ds1wm.h @@ -1,13 +1,28 @@ -/* MFD cell driver data for the DS1WM driver */ +/* MFD cell driver data for the DS1WM driver + * + * to be defined in the MFD device that is + * using this driver for one of his sub devices + */ struct ds1wm_driver_data { int active_high; int clock_rate; - /* in milliseconds, the amount of time to */ - /* sleep following a reset pulse. Zero */ - /* should work if your bus devices recover*/ - /* time respects the 1-wire spec since the*/ - /* ds1wm implements the precise timings of*/ - /* a reset pulse/presence detect sequence.*/ + /* in milliseconds, the amount of time to + * sleep following a reset pulse. Zero + * should work if your bus devices recover + * time respects the 1-wire spec since the + * ds1wm implements the precise timings of + * a reset pulse/presence detect sequence. + */ unsigned int reset_recover_delay; + + /* Say 1 here for big endian Hardware + * (only relevant with bus-shift > 0 + */ + bool is_hw_big_endian; + + /* left shift of register number to get register address offsett. + * Only 0,1,2 allowed for 8,16 or 32 bit bus width respectively + */ + unsigned int bus_shift; }; diff --git a/include/linux/mfd/hi6421-pmic.h b/include/linux/mfd/hi6421-pmic.h index 587273e35acf08a26d2c5909bdfc0109f4e1c81b..2580c08db7b11fccec23a208231dfb65037ec292 100644 --- a/include/linux/mfd/hi6421-pmic.h +++ b/include/linux/mfd/hi6421-pmic.h @@ -38,4 +38,9 @@ struct hi6421_pmic { struct regmap *regmap; }; +enum hi6421_type { + HI6421 = 0, + HI6421_V530, +}; + #endif /* __HI6421_PMIC_H */ diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index 83701ef7d3c7bfbb1dc59f6e92a6f0664a7c48c5..d3156594674c2c1f166d1e9b83fe200c199d2361 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -206,6 +206,97 @@ enum rk818_reg { #define RK818_USB_ILMIN_2000MA 0x7 #define RK818_USB_CHG_SD_VSEL_MASK 0x70 +/* RK805 */ +enum rk805_reg { + RK805_ID_DCDC1, + RK805_ID_DCDC2, + RK805_ID_DCDC3, + RK805_ID_DCDC4, + RK805_ID_LDO1, + RK805_ID_LDO2, + RK805_ID_LDO3, +}; + +/* CONFIG REGISTER */ +#define RK805_VB_MON_REG 0x21 +#define RK805_THERMAL_REG 0x22 + +/* POWER CHANNELS ENABLE REGISTER */ +#define RK805_DCDC_EN_REG 0x23 +#define RK805_SLP_DCDC_EN_REG 0x25 +#define RK805_SLP_LDO_EN_REG 0x26 +#define RK805_LDO_EN_REG 0x27 + +/* BUCK AND LDO CONFIG REGISTER */ +#define RK805_BUCK_LDO_SLP_LP_EN_REG 0x2A +#define RK805_BUCK1_CONFIG_REG 0x2E +#define RK805_BUCK1_ON_VSEL_REG 0x2F +#define RK805_BUCK1_SLP_VSEL_REG 0x30 +#define RK805_BUCK2_CONFIG_REG 0x32 +#define RK805_BUCK2_ON_VSEL_REG 0x33 +#define RK805_BUCK2_SLP_VSEL_REG 0x34 +#define RK805_BUCK3_CONFIG_REG 0x36 +#define RK805_BUCK4_CONFIG_REG 0x37 +#define RK805_BUCK4_ON_VSEL_REG 0x38 +#define RK805_BUCK4_SLP_VSEL_REG 0x39 +#define RK805_LDO1_ON_VSEL_REG 0x3B +#define RK805_LDO1_SLP_VSEL_REG 0x3C +#define RK805_LDO2_ON_VSEL_REG 0x3D +#define RK805_LDO2_SLP_VSEL_REG 0x3E +#define RK805_LDO3_ON_VSEL_REG 0x3F +#define RK805_LDO3_SLP_VSEL_REG 0x40 + +/* INTERRUPT REGISTER */ +#define RK805_PWRON_LP_INT_TIME_REG 0x47 +#define RK805_PWRON_DB_REG 0x48 +#define RK805_DEV_CTRL_REG 0x4B +#define RK805_INT_STS_REG 0x4C +#define RK805_INT_STS_MSK_REG 0x4D +#define RK805_GPIO_IO_POL_REG 0x50 +#define RK805_OUT_REG 0x52 +#define RK805_ON_SOURCE_REG 0xAE +#define RK805_OFF_SOURCE_REG 0xAF + +#define RK805_NUM_REGULATORS 7 + +#define RK805_PWRON_FALL_RISE_INT_EN 0x0 +#define RK805_PWRON_FALL_RISE_INT_MSK 0x81 + +/* RK805 IRQ Definitions */ +#define RK805_IRQ_PWRON_RISE 0 +#define RK805_IRQ_VB_LOW 1 +#define RK805_IRQ_PWRON 2 +#define RK805_IRQ_PWRON_LP 3 +#define RK805_IRQ_HOTDIE 4 +#define RK805_IRQ_RTC_ALARM 5 +#define RK805_IRQ_RTC_PERIOD 6 +#define RK805_IRQ_PWRON_FALL 7 + +#define RK805_IRQ_PWRON_RISE_MSK BIT(0) +#define RK805_IRQ_VB_LOW_MSK BIT(1) +#define RK805_IRQ_PWRON_MSK BIT(2) +#define RK805_IRQ_PWRON_LP_MSK BIT(3) +#define RK805_IRQ_HOTDIE_MSK BIT(4) +#define RK805_IRQ_RTC_ALARM_MSK BIT(5) +#define RK805_IRQ_RTC_PERIOD_MSK BIT(6) +#define RK805_IRQ_PWRON_FALL_MSK BIT(7) + +#define RK805_PWR_RISE_INT_STATUS BIT(0) +#define RK805_VB_LOW_INT_STATUS BIT(1) +#define RK805_PWRON_INT_STATUS BIT(2) +#define RK805_PWRON_LP_INT_STATUS BIT(3) +#define RK805_HOTDIE_INT_STATUS BIT(4) +#define RK805_ALARM_INT_STATUS BIT(5) +#define RK805_PERIOD_INT_STATUS BIT(6) +#define RK805_PWR_FALL_INT_STATUS BIT(7) + +#define RK805_BUCK1_2_ILMAX_MASK (3 << 6) +#define RK805_BUCK3_4_ILMAX_MASK (3 << 3) +#define RK805_RTC_PERIOD_INT_MASK (1 << 6) +#define RK805_RTC_ALARM_INT_MASK (1 << 5) +#define RK805_INT_ALARM_EN (1 << 3) +#define RK805_INT_TIMER_EN (1 << 2) + /* RK808 IRQ Definitions */ #define RK808_IRQ_VOUT_LO 0 #define RK808_IRQ_VB_LO 1 @@ -298,6 +389,14 @@ enum rk818_reg { #define VOUT_LO_INT BIT(0) #define CLK32KOUT2_EN BIT(0) +#define TEMP115C 0x0c +#define TEMP_HOTDIE_MSK 0x0c +#define SLP_SD_MSK (0x3 << 2) +#define SHUTDOWN_FUN (0x2 << 2) +#define SLEEP_FUN (0x1 << 2) +#define RK8XX_ID_MSK 0xfff0 +#define FPWM_MODE BIT(7) + enum { BUCK_ILMIN_50MA, BUCK_ILMIN_100MA, @@ -321,6 +420,28 @@ enum { }; enum { + RK805_BUCK1_2_ILMAX_2500MA, + RK805_BUCK1_2_ILMAX_3000MA, + RK805_BUCK1_2_ILMAX_3500MA, + RK805_BUCK1_2_ILMAX_4000MA, +}; + +enum { + RK805_BUCK3_ILMAX_1500MA, + RK805_BUCK3_ILMAX_2000MA, + RK805_BUCK3_ILMAX_2500MA, + RK805_BUCK3_ILMAX_3000MA, +}; + +enum { + RK805_BUCK4_ILMAX_2000MA, + RK805_BUCK4_ILMAX_2500MA, + RK805_BUCK4_ILMAX_3000MA, + RK805_BUCK4_ILMAX_3500MA, +}; + +enum { + RK805_ID = 0x8050, RK808_ID = 0x0000, RK818_ID = 0x8181, }; diff --git a/include/linux/mfd/rn5t618.h b/include/linux/mfd/rn5t618.h index e5a6cdeb77dbcc5e8603199bb6021bdc17f8516c..d61bc58aba8a46d841322cd83b4e342931d719c5 100644 --- a/include/linux/mfd/rn5t618.h +++ b/include/linux/mfd/rn5t618.h @@ -226,11 +226,17 @@ enum { RN5T618_DCDC2, RN5T618_DCDC3, RN5T618_DCDC4, + RN5T618_DCDC5, RN5T618_LDO1, RN5T618_LDO2, RN5T618_LDO3, RN5T618_LDO4, RN5T618_LDO5, + RN5T618_LDO6, + RN5T618_LDO7, + RN5T618_LDO8, + RN5T618_LDO9, + RN5T618_LDO10, RN5T618_LDORTC1, RN5T618_LDORTC2, RN5T618_REG_NUM, diff --git a/include/linux/mfd/stm32-lptimer.h b/include/linux/mfd/stm32-lptimer.h new file mode 100644 index 0000000000000000000000000000000000000000..77c7cf40d9b46deec2ad802136a53eda43cde019 --- /dev/null +++ b/include/linux/mfd/stm32-lptimer.h @@ -0,0 +1,62 @@ +/* + * STM32 Low-Power Timer parent driver. + * + * Copyright (C) STMicroelectronics 2017 + * + * Author: Fabrice Gasnier + * + * Inspired by Benjamin Gaignard's stm32-timers driver + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef _LINUX_STM32_LPTIMER_H_ +#define _LINUX_STM32_LPTIMER_H_ + +#include +#include + +#define STM32_LPTIM_ISR 0x00 /* Interrupt and Status Reg */ +#define STM32_LPTIM_ICR 0x04 /* Interrupt Clear Reg */ +#define STM32_LPTIM_IER 0x08 /* Interrupt Enable Reg */ +#define STM32_LPTIM_CFGR 0x0C /* Configuration Reg */ +#define STM32_LPTIM_CR 0x10 /* Control Reg */ +#define STM32_LPTIM_CMP 0x14 /* Compare Reg */ +#define STM32_LPTIM_ARR 0x18 /* Autoreload Reg */ +#define STM32_LPTIM_CNT 0x1C /* Counter Reg */ + +/* STM32_LPTIM_ISR - bit fields */ +#define STM32_LPTIM_CMPOK_ARROK GENMASK(4, 3) +#define STM32_LPTIM_ARROK BIT(4) +#define STM32_LPTIM_CMPOK BIT(3) + +/* STM32_LPTIM_ICR - bit fields */ +#define STM32_LPTIM_CMPOKCF_ARROKCF GENMASK(4, 3) + +/* STM32_LPTIM_CR - bit fields */ +#define STM32_LPTIM_CNTSTRT BIT(2) +#define STM32_LPTIM_ENABLE BIT(0) + +/* STM32_LPTIM_CFGR - bit fields */ +#define STM32_LPTIM_ENC BIT(24) +#define STM32_LPTIM_COUNTMODE BIT(23) +#define STM32_LPTIM_WAVPOL BIT(21) +#define STM32_LPTIM_PRESC GENMASK(11, 9) +#define STM32_LPTIM_CKPOL GENMASK(2, 1) + +/* STM32_LPTIM_ARR */ +#define STM32_LPTIM_MAX_ARR 0xFFFF + +/** + * struct stm32_lptimer - STM32 Low-Power Timer data assigned by parent device + * @clk: clock reference for this instance + * @regmap: register map reference for this instance + * @has_encoder: indicates this Low-Power Timer supports encoder mode + */ +struct stm32_lptimer { + struct clk *clk; + struct regmap *regmap; + bool has_encoder; +}; + +#endif diff --git a/include/linux/mfd/syscon/atmel-smc.h b/include/linux/mfd/syscon/atmel-smc.h index afa2661698004fed5792374ac68d8d8dd9bb0c1f..7a367f34b66ae6995e84d54b3b13a1b28cb22788 100644 --- a/include/linux/mfd/syscon/atmel-smc.h +++ b/include/linux/mfd/syscon/atmel-smc.h @@ -15,21 +15,26 @@ #define _LINUX_MFD_SYSCON_ATMEL_SMC_H_ #include +#include #include #define ATMEL_SMC_SETUP(cs) (((cs) * 0x10)) -#define ATMEL_HSMC_SETUP(cs) (0x600 + ((cs) * 0x14)) +#define ATMEL_HSMC_SETUP(layout, cs) \ + ((layout)->timing_regs_offset + ((cs) * 0x14)) #define ATMEL_SMC_PULSE(cs) (((cs) * 0x10) + 0x4) -#define ATMEL_HSMC_PULSE(cs) (0x600 + ((cs) * 0x14) + 0x4) +#define ATMEL_HSMC_PULSE(layout, cs) \ + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0x4) #define ATMEL_SMC_CYCLE(cs) (((cs) * 0x10) + 0x8) -#define ATMEL_HSMC_CYCLE(cs) (0x600 + ((cs) * 0x14) + 0x8) +#define ATMEL_HSMC_CYCLE(layout, cs) \ + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0x8) #define ATMEL_SMC_NWE_SHIFT 0 #define ATMEL_SMC_NCS_WR_SHIFT 8 #define ATMEL_SMC_NRD_SHIFT 16 #define ATMEL_SMC_NCS_RD_SHIFT 24 #define ATMEL_SMC_MODE(cs) (((cs) * 0x10) + 0xc) -#define ATMEL_HSMC_MODE(cs) (0x600 + ((cs) * 0x14) + 0x10) +#define ATMEL_HSMC_MODE(layout, cs) \ + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0x10) #define ATMEL_SMC_MODE_READMODE_MASK BIT(0) #define ATMEL_SMC_MODE_READMODE_NCS (0 << 0) #define ATMEL_SMC_MODE_READMODE_NRD (1 << 0) @@ -59,7 +64,8 @@ #define ATMEL_SMC_MODE_PS_16 (2 << 28) #define ATMEL_SMC_MODE_PS_32 (3 << 28) -#define ATMEL_HSMC_TIMINGS(cs) (0x600 + ((cs) * 0x14) + 0xc) +#define ATMEL_HSMC_TIMINGS(layout, cs) \ + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0xc) #define ATMEL_HSMC_TIMINGS_OCMS BIT(12) #define ATMEL_HSMC_TIMINGS_RBNSEL(x) ((x) << 28) #define ATMEL_HSMC_TIMINGS_NFSEL BIT(31) @@ -69,6 +75,10 @@ #define ATMEL_HSMC_TIMINGS_TRR_SHIFT 16 #define ATMEL_HSMC_TIMINGS_TWB_SHIFT 24 +struct atmel_hsmc_reg_layout { + unsigned int timing_regs_offset; +}; + /** * struct atmel_smc_cs_conf - SMC CS config as described in the datasheet. * @setup: NCS/NWE/NRD setup timings (not applicable to at91rm9200) @@ -98,11 +108,15 @@ int atmel_smc_cs_conf_set_cycle(struct atmel_smc_cs_conf *conf, unsigned int shift, unsigned int ncycles); void atmel_smc_cs_conf_apply(struct regmap *regmap, int cs, const struct atmel_smc_cs_conf *conf); -void atmel_hsmc_cs_conf_apply(struct regmap *regmap, int cs, - const struct atmel_smc_cs_conf *conf); +void atmel_hsmc_cs_conf_apply(struct regmap *regmap, + const struct atmel_hsmc_reg_layout *reglayout, + int cs, const struct atmel_smc_cs_conf *conf); void atmel_smc_cs_conf_get(struct regmap *regmap, int cs, struct atmel_smc_cs_conf *conf); -void atmel_hsmc_cs_conf_get(struct regmap *regmap, int cs, - struct atmel_smc_cs_conf *conf); +void atmel_hsmc_cs_conf_get(struct regmap *regmap, + const struct atmel_hsmc_reg_layout *reglayout, + int cs, struct atmel_smc_cs_conf *conf); +const struct atmel_hsmc_reg_layout * +atmel_hsmc_get_reg_layout(struct device_node *np); #endif /* _LINUX_MFD_SYSCON_ATMEL_SMC_H_ */ diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 26e8f8c0a6db6d445c3440ba9223e808698ab88b..15646740e2a8ce38654a87371bf19522b340d974 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -107,6 +107,9 @@ */ #define TMIO_MMC_CLK_ACTUAL BIT(10) +/* Some controllers have a CBSY bit */ +#define TMIO_MMC_HAVE_CBSY BIT(11) + int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base); int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base); void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state); @@ -128,6 +131,8 @@ struct tmio_mmc_data { unsigned int cd_gpio; int alignment_shift; dma_addr_t dma_rx_offset; + unsigned int max_blk_count; + unsigned short max_segs; void (*set_pwr)(struct platform_device *host, int state); void (*set_clk_div)(struct platform_device *host, int state); }; @@ -139,6 +144,7 @@ struct tmio_nand_data { struct nand_bbt_descr *badblock_pattern; struct mtd_partition *partition; unsigned int num_partitions; + const char *const *part_parsers; }; #define FBIO_TMIO_ACC_WRITE 0x7C639300 diff --git a/include/linux/i2c/tps65010.h b/include/linux/mfd/tps65010.h similarity index 99% rename from include/linux/i2c/tps65010.h rename to include/linux/mfd/tps65010.h index 08aa92278d71cdd6b388c24d8fdb083c719e291b..a1fb9bc5311de43d24efea019c014f255a24b375 100644 --- a/include/linux/i2c/tps65010.h +++ b/include/linux/mfd/tps65010.h @@ -1,4 +1,4 @@ -/* linux/i2c/tps65010.h +/* linux/mfd/tps65010.h * * Functions to access TPS65010 power management device. * diff --git a/include/linux/mfd/tps68470.h b/include/linux/mfd/tps68470.h new file mode 100644 index 0000000000000000000000000000000000000000..44f9d9f647ed1b1c15a1d4b3226ed841be37d1c3 --- /dev/null +++ b/include/linux/mfd/tps68470.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * Functions to access TPS68470 power management chip. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LINUX_MFD_TPS68470_H +#define __LINUX_MFD_TPS68470_H + +/* Register addresses */ +#define TPS68470_REG_POSTDIV2 0x06 +#define TPS68470_REG_BOOSTDIV 0x07 +#define TPS68470_REG_BUCKDIV 0x08 +#define TPS68470_REG_PLLSWR 0x09 +#define TPS68470_REG_XTALDIV 0x0A +#define TPS68470_REG_PLLDIV 0x0B +#define TPS68470_REG_POSTDIV 0x0C +#define TPS68470_REG_PLLCTL 0x0D +#define TPS68470_REG_PLLCTL2 0x0E +#define TPS68470_REG_CLKCFG1 0x0F +#define TPS68470_REG_CLKCFG2 0x10 +#define TPS68470_REG_GPCTL0A 0x14 +#define TPS68470_REG_GPCTL0B 0x15 +#define TPS68470_REG_GPCTL1A 0x16 +#define TPS68470_REG_GPCTL1B 0x17 +#define TPS68470_REG_GPCTL2A 0x18 +#define TPS68470_REG_GPCTL2B 0x19 +#define TPS68470_REG_GPCTL3A 0x1A +#define TPS68470_REG_GPCTL3B 0x1B +#define TPS68470_REG_GPCTL4A 0x1C +#define TPS68470_REG_GPCTL4B 0x1D +#define TPS68470_REG_GPCTL5A 0x1E +#define TPS68470_REG_GPCTL5B 0x1F +#define TPS68470_REG_GPCTL6A 0x20 +#define TPS68470_REG_GPCTL6B 0x21 +#define TPS68470_REG_SGPO 0x22 +#define TPS68470_REG_GPDI 0x26 +#define TPS68470_REG_GPDO 0x27 +#define TPS68470_REG_VCMVAL 0x3C +#define TPS68470_REG_VAUX1VAL 0x3D +#define TPS68470_REG_VAUX2VAL 0x3E +#define TPS68470_REG_VIOVAL 0x3F +#define TPS68470_REG_VSIOVAL 0x40 +#define TPS68470_REG_VAVAL 0x41 +#define TPS68470_REG_VDVAL 0x42 +#define TPS68470_REG_S_I2C_CTL 0x43 +#define TPS68470_REG_VCMCTL 0x44 +#define TPS68470_REG_VAUX1CTL 0x45 +#define TPS68470_REG_VAUX2CTL 0x46 +#define TPS68470_REG_VACTL 0x47 +#define TPS68470_REG_VDCTL 0x48 +#define TPS68470_REG_RESET 0x50 +#define TPS68470_REG_REVID 0xFF + +#define TPS68470_REG_MAX TPS68470_REG_REVID + +/* Register field definitions */ + +#define TPS68470_REG_RESET_MASK GENMASK(7, 0) +#define TPS68470_VAVAL_AVOLT_MASK GENMASK(6, 0) + +#define TPS68470_VDVAL_DVOLT_MASK GENMASK(5, 0) +#define TPS68470_VCMVAL_VCVOLT_MASK GENMASK(6, 0) +#define TPS68470_VIOVAL_IOVOLT_MASK GENMASK(6, 0) +#define TPS68470_VSIOVAL_IOVOLT_MASK GENMASK(6, 0) +#define TPS68470_VAUX1VAL_AUX1VOLT_MASK GENMASK(6, 0) +#define TPS68470_VAUX2VAL_AUX2VOLT_MASK GENMASK(6, 0) + +#define TPS68470_VACTL_EN_MASK GENMASK(0, 0) +#define TPS68470_VDCTL_EN_MASK GENMASK(0, 0) +#define TPS68470_VCMCTL_EN_MASK GENMASK(0, 0) +#define TPS68470_S_I2C_CTL_EN_MASK GENMASK(1, 0) +#define TPS68470_VAUX1CTL_EN_MASK GENMASK(0, 0) +#define TPS68470_VAUX2CTL_EN_MASK GENMASK(0, 0) +#define TPS68470_PLL_EN_MASK GENMASK(0, 0) + +#define TPS68470_CLKCFG1_MODE_A_MASK GENMASK(1, 0) +#define TPS68470_CLKCFG1_MODE_B_MASK GENMASK(3, 2) + +#define TPS68470_GPIO_CTL_REG_A(x) (TPS68470_REG_GPCTL0A + (x) * 2) +#define TPS68470_GPIO_CTL_REG_B(x) (TPS68470_REG_GPCTL0B + (x) * 2) +#define TPS68470_GPIO_MODE_MASK GENMASK(1, 0) +#define TPS68470_GPIO_MODE_IN 0 +#define TPS68470_GPIO_MODE_IN_PULLUP 1 +#define TPS68470_GPIO_MODE_OUT_CMOS 2 +#define TPS68470_GPIO_MODE_OUT_ODRAIN 3 + +#endif /* __LINUX_MFD_TPS68470_H */ diff --git a/include/linux/i2c/twl.h b/include/linux/mfd/twl.h similarity index 100% rename from include/linux/i2c/twl.h rename to include/linux/mfd/twl.h diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 3e0d405dc842d5dd65b28cb710b4ce38008ca64b..643c7ae7d7b4d8dfad5fa20faf255334f133176f 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -35,15 +35,28 @@ static inline struct page *new_page_nodemask(struct page *page, int preferred_nid, nodemask_t *nodemask) { gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL; + unsigned int order = 0; + struct page *new_page = NULL; if (PageHuge(page)) return alloc_huge_page_nodemask(page_hstate(compound_head(page)), preferred_nid, nodemask); + if (thp_migration_supported() && PageTransHuge(page)) { + order = HPAGE_PMD_ORDER; + gfp_mask |= GFP_TRANSHUGE; + } + if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) gfp_mask |= __GFP_HIGHMEM; - return __alloc_pages_nodemask(gfp_mask, 0, preferred_nid, nodemask); + new_page = __alloc_pages_nodemask(gfp_mask, order, + preferred_nid, nodemask); + + if (new_page && PageTransHuge(page)) + prep_transhuge_page(new_page); + + return new_page; } #ifdef CONFIG_MIGRATION @@ -59,6 +72,7 @@ extern void putback_movable_page(struct page *page); extern int migrate_prep(void); extern int migrate_prep_local(void); +extern void migrate_page_states(struct page *newpage, struct page *page); extern void migrate_page_copy(struct page *newpage, struct page *page); extern int migrate_huge_page_move_mapping(struct address_space *mapping, struct page *newpage, struct page *page); @@ -79,6 +93,10 @@ static inline int isolate_movable_page(struct page *page, isolate_mode_t mode) static inline int migrate_prep(void) { return -ENOSYS; } static inline int migrate_prep_local(void) { return -ENOSYS; } +static inline void migrate_page_states(struct page *newpage, struct page *page) +{ +} + static inline void migrate_page_copy(struct page *newpage, struct page *page) {} @@ -138,4 +156,136 @@ static inline int migrate_misplaced_transhuge_page(struct mm_struct *mm, } #endif /* CONFIG_NUMA_BALANCING && CONFIG_TRANSPARENT_HUGEPAGE*/ + +#ifdef CONFIG_MIGRATION + +/* + * Watch out for PAE architecture, which has an unsigned long, and might not + * have enough bits to store all physical address and flags. So far we have + * enough room for all our flags. + */ +#define MIGRATE_PFN_VALID (1UL << 0) +#define MIGRATE_PFN_MIGRATE (1UL << 1) +#define MIGRATE_PFN_LOCKED (1UL << 2) +#define MIGRATE_PFN_WRITE (1UL << 3) +#define MIGRATE_PFN_DEVICE (1UL << 4) +#define MIGRATE_PFN_ERROR (1UL << 5) +#define MIGRATE_PFN_SHIFT 6 + +static inline struct page *migrate_pfn_to_page(unsigned long mpfn) +{ + if (!(mpfn & MIGRATE_PFN_VALID)) + return NULL; + return pfn_to_page(mpfn >> MIGRATE_PFN_SHIFT); +} + +static inline unsigned long migrate_pfn(unsigned long pfn) +{ + return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID; +} + +/* + * struct migrate_vma_ops - migrate operation callback + * + * @alloc_and_copy: alloc destination memory and copy source memory to it + * @finalize_and_map: allow caller to map the successfully migrated pages + * + * + * The alloc_and_copy() callback happens once all source pages have been locked, + * unmapped and checked (checked whether pinned or not). All pages that can be + * migrated will have an entry in the src array set with the pfn value of the + * page and with the MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE flag set (other + * flags might be set but should be ignored by the callback). + * + * The alloc_and_copy() callback can then allocate destination memory and copy + * source memory to it for all those entries (ie with MIGRATE_PFN_VALID and + * MIGRATE_PFN_MIGRATE flag set). Once these are allocated and copied, the + * callback must update each corresponding entry in the dst array with the pfn + * value of the destination page and with the MIGRATE_PFN_VALID and + * MIGRATE_PFN_LOCKED flags set (destination pages must have their struct pages + * locked, via lock_page()). + * + * At this point the alloc_and_copy() callback is done and returns. + * + * Note that the callback does not have to migrate all the pages that are + * marked with MIGRATE_PFN_MIGRATE flag in src array unless this is a migration + * from device memory to system memory (ie the MIGRATE_PFN_DEVICE flag is also + * set in the src array entry). If the device driver cannot migrate a device + * page back to system memory, then it must set the corresponding dst array + * entry to MIGRATE_PFN_ERROR. This will trigger a SIGBUS if CPU tries to + * access any of the virtual addresses originally backed by this page. Because + * a SIGBUS is such a severe result for the userspace process, the device + * driver should avoid setting MIGRATE_PFN_ERROR unless it is really in an + * unrecoverable state. + * + * For empty entry inside CPU page table (pte_none() or pmd_none() is true) we + * do set MIGRATE_PFN_MIGRATE flag inside the corresponding source array thus + * allowing device driver to allocate device memory for those unback virtual + * address. For this the device driver simply have to allocate device memory + * and properly set the destination entry like for regular migration. Note that + * this can still fails and thus inside the device driver must check if the + * migration was successful for those entry inside the finalize_and_map() + * callback just like for regular migration. + * + * THE alloc_and_copy() CALLBACK MUST NOT CHANGE ANY OF THE SRC ARRAY ENTRIES + * OR BAD THINGS WILL HAPPEN ! + * + * + * The finalize_and_map() callback happens after struct page migration from + * source to destination (destination struct pages are the struct pages for the + * memory allocated by the alloc_and_copy() callback). Migration can fail, and + * thus the finalize_and_map() allows the driver to inspect which pages were + * successfully migrated, and which were not. Successfully migrated pages will + * have the MIGRATE_PFN_MIGRATE flag set for their src array entry. + * + * It is safe to update device page table from within the finalize_and_map() + * callback because both destination and source page are still locked, and the + * mmap_sem is held in read mode (hence no one can unmap the range being + * migrated). + * + * Once callback is done cleaning up things and updating its page table (if it + * chose to do so, this is not an obligation) then it returns. At this point, + * the HMM core will finish up the final steps, and the migration is complete. + * + * THE finalize_and_map() CALLBACK MUST NOT CHANGE ANY OF THE SRC OR DST ARRAY + * ENTRIES OR BAD THINGS WILL HAPPEN ! + */ +struct migrate_vma_ops { + void (*alloc_and_copy)(struct vm_area_struct *vma, + const unsigned long *src, + unsigned long *dst, + unsigned long start, + unsigned long end, + void *private); + void (*finalize_and_map)(struct vm_area_struct *vma, + const unsigned long *src, + const unsigned long *dst, + unsigned long start, + unsigned long end, + void *private); +}; + +#if defined(CONFIG_MIGRATE_VMA_HELPER) +int migrate_vma(const struct migrate_vma_ops *ops, + struct vm_area_struct *vma, + unsigned long start, + unsigned long end, + unsigned long *src, + unsigned long *dst, + void *private); +#else +static inline int migrate_vma(const struct migrate_vma_ops *ops, + struct vm_area_struct *vma, + unsigned long start, + unsigned long end, + unsigned long *src, + unsigned long *dst, + void *private) +{ + return -EINVAL; +} +#endif /* IS_ENABLED(CONFIG_MIGRATE_VMA_HELPER) */ + +#endif /* CONFIG_MIGRATION */ + #endif /* _LINUX_MIGRATE_H */ diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h index ebf3d89a3919405ccd9a887178c65764a931a291..bdf66af9b937a51a661a15c7f0feda67847efe90 100644 --- a/include/linux/migrate_mode.h +++ b/include/linux/migrate_mode.h @@ -6,11 +6,16 @@ * on most operations but not ->writepage as the potential stall time * is too significant * MIGRATE_SYNC will block when migrating pages + * MIGRATE_SYNC_NO_COPY will block when migrating pages but will not copy pages + * with the CPU. Instead, page copy happens outside the migratepage() + * callback and is likely using a DMA engine. See migrate_vma() and HMM + * (mm/hmm.c) for users of this mode. */ enum migrate_mode { MIGRATE_ASYNC, MIGRATE_SYNC_LIGHT, MIGRATE_SYNC, + MIGRATE_SYNC_NO_COPY, }; #endif /* MIGRATE_MODE_H_INCLUDED */ diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index aad5d81dfb444aeb0dcb4b92aef475023aa897c1..b0a57e043fa398b9133b3a9c207e0d72273348f3 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -224,6 +224,7 @@ enum { MLX4_DEV_CAP_FLAG2_DIAG_PER_PORT = 1ULL << 35, MLX4_DEV_CAP_FLAG2_SVLAN_BY_QP = 1ULL << 36, MLX4_DEV_CAP_FLAG2_SL_TO_VL_CHANGE_EVENT = 1ULL << 37, + MLX4_DEV_CAP_FLAG2_USER_MAC_EN = 1ULL << 38, }; enum { @@ -428,6 +429,12 @@ enum mlx4_steer_type { MLX4_NUM_STEERS }; +enum mlx4_resource_usage { + MLX4_RES_USAGE_NONE, + MLX4_RES_USAGE_DRIVER, + MLX4_RES_USAGE_USER_VERBS, +}; + enum { MLX4_NUM_FEXCH = 64 * 1024, }; @@ -518,6 +525,14 @@ struct mlx4_phys_caps { u32 base_tunnel_sqpn; }; +struct mlx4_spec_qps { + u32 qp0_qkey; + u32 qp0_proxy; + u32 qp0_tunnel; + u32 qp1_proxy; + u32 qp1_tunnel; +}; + struct mlx4_caps { u64 fw_ver; u32 function; @@ -547,11 +562,7 @@ struct mlx4_caps { int max_qp_init_rdma; int max_qp_dest_rdma; int max_tc_eth; - u32 *qp0_qkey; - u32 *qp0_proxy; - u32 *qp1_proxy; - u32 *qp0_tunnel; - u32 *qp1_tunnel; + struct mlx4_spec_qps *spec_qps; int num_srqs; int max_srq_wqes; int max_srq_sge; @@ -620,6 +631,7 @@ struct mlx4_caps { u32 dmfs_high_rate_qpn_base; u32 dmfs_high_rate_qpn_range; u32 vf_caps; + bool wol_port[MLX4_MAX_PORTS + 1]; struct mlx4_rate_limit_caps rl_caps; }; @@ -748,6 +760,7 @@ struct mlx4_cq { } tasklet_ctx; int reset_notify_added; struct list_head reset_notify; + u8 usage; }; struct mlx4_qp { @@ -757,6 +770,7 @@ struct mlx4_qp { atomic_t refcount; struct completion free; + u8 usage; }; struct mlx4_srq { @@ -1120,7 +1134,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, unsigned vector, int collapsed, int timestamp_en); void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq); int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, - int *base, u8 flags); + int *base, u8 flags, u8 usage); void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt); int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp); @@ -1372,6 +1386,7 @@ int mlx4_get_base_qpn(struct mlx4_dev *dev, u8 port); int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac); int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx); +int mlx4_SET_PORT_user_mac(struct mlx4_dev *dev, u8 port, u8 *user_mac); int mlx4_SET_PORT_user_mtu(struct mlx4_dev *dev, u8 port, u16 user_mtu); int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, u8 promisc); @@ -1417,7 +1432,7 @@ int mlx4_get_phys_port_id(struct mlx4_dev *dev); int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port); int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port); -int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx); +int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx, u8 usage); void mlx4_counter_free(struct mlx4_dev *dev, u32 idx); int mlx4_get_default_counter_index(struct mlx4_dev *dev, int port); diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index f31a0b5377e1d469050163cf87537c759229696e..e32dbc4934dbbf7e743bd33dd1b3ed8a4c9cee88 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -48,7 +48,7 @@ /* helper macros */ #define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0) #define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld) -#define __mlx5_bit_off(typ, fld) ((unsigned)(unsigned long)(&(__mlx5_nullp(typ)->fld))) +#define __mlx5_bit_off(typ, fld) (offsetof(struct mlx5_ifc_##typ##_bits, fld)) #define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32) #define __mlx5_64_off(typ, fld) (__mlx5_bit_off(typ, fld) / 64) #define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0x1f)) @@ -290,6 +290,7 @@ enum mlx5_event { MLX5_EVENT_TYPE_GPIO_EVENT = 0x15, MLX5_EVENT_TYPE_PORT_MODULE_EVENT = 0x16, MLX5_EVENT_TYPE_REMOTE_CONFIG = 0x19, + MLX5_EVENT_TYPE_GENERAL_EVENT = 0x22, MLX5_EVENT_TYPE_PPS_EVENT = 0x25, MLX5_EVENT_TYPE_DB_BF_CONGESTION = 0x1a, @@ -304,6 +305,10 @@ enum mlx5_event { MLX5_EVENT_TYPE_FPGA_ERROR = 0x20, }; +enum { + MLX5_GENERAL_SUBTYPE_DELAY_DROP_TIMEOUT = 0x1, +}; + enum { MLX5_PORT_CHANGE_SUBTYPE_DOWN = 1, MLX5_PORT_CHANGE_SUBTYPE_ACTIVE = 4, @@ -709,7 +714,7 @@ static inline int mlx5_get_cqe_format(struct mlx5_cqe64 *cqe) return (cqe->op_own >> 2) & 0x3; } -static inline int get_cqe_lro_tcppsh(struct mlx5_cqe64 *cqe) +static inline u8 get_cqe_lro_tcppsh(struct mlx5_cqe64 *cqe) { return (cqe->lro_tcppsh_abort_dupack >> 6) & 1; } @@ -968,14 +973,13 @@ enum mlx5_cap_type { MLX5_CAP_ATOMIC, MLX5_CAP_ROCE, MLX5_CAP_IPOIB_OFFLOADS, - MLX5_CAP_EOIB_OFFLOADS, + MLX5_CAP_IPOIB_ENHANCED_OFFLOADS, MLX5_CAP_FLOW_TABLE, MLX5_CAP_ESWITCH_FLOW_TABLE, MLX5_CAP_ESWITCH, MLX5_CAP_RESERVED, MLX5_CAP_VECTOR_CALC, MLX5_CAP_QOS, - MLX5_CAP_FPGA, /* NUM OF CAP Types */ MLX5_CAP_NUM }; @@ -1011,6 +1015,10 @@ enum mlx5_mcam_feature_groups { MLX5_GET(per_protocol_networking_offload_caps,\ mdev->caps.hca_max[MLX5_CAP_ETHERNET_OFFLOADS], cap) +#define MLX5_CAP_IPOIB_ENHANCED(mdev, cap) \ + MLX5_GET(per_protocol_networking_offload_caps,\ + mdev->caps.hca_cur[MLX5_CAP_IPOIB_ENHANCED_OFFLOADS], cap) + #define MLX5_CAP_ROCE(mdev, cap) \ MLX5_GET(roce_cap, mdev->caps.hca_cur[MLX5_CAP_ROCE], cap) @@ -1101,10 +1109,10 @@ enum mlx5_mcam_feature_groups { MLX5_GET(mcam_reg, (mdev)->caps.mcam, mng_feature_cap_mask.enhanced_features.fld) #define MLX5_CAP_FPGA(mdev, cap) \ - MLX5_GET(fpga_cap, (mdev)->caps.hca_cur[MLX5_CAP_FPGA], cap) + MLX5_GET(fpga_cap, (mdev)->caps.fpga, cap) #define MLX5_CAP64_FPGA(mdev, cap) \ - MLX5_GET64(fpga_cap, (mdev)->caps.hca_cur[MLX5_CAP_FPGA], cap) + MLX5_GET64(fpga_cap, (mdev)->caps.fpga, cap) enum { MLX5_CMD_STAT_OK = 0x0, diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index df6ce59a1f954257cdef95a7733736e42c8b9491..401c8972cc3a869d77bcf1245dfc5095bcb6bbaf 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -162,6 +162,13 @@ enum dbg_rsc_type { MLX5_DBG_RSC_CQ, }; +enum port_state_policy { + MLX5_POLICY_DOWN = 0, + MLX5_POLICY_UP = 1, + MLX5_POLICY_FOLLOW = 2, + MLX5_POLICY_INVALID = 0xffffffff +}; + struct mlx5_field_desc { struct dentry *dent; int i; @@ -185,6 +192,7 @@ enum mlx5_dev_event { MLX5_DEV_EVENT_GUID_CHANGE, MLX5_DEV_EVENT_CLIENT_REREG, MLX5_DEV_EVENT_PPS, + MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT, }; enum mlx5_port_status { @@ -291,7 +299,7 @@ struct mlx5_cmd { struct semaphore pages_sem; int mode; struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS]; - struct pci_pool *pool; + struct dma_pool *pool; struct mlx5_cmd_debug dbg; struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES]; int checksum_disabled; @@ -410,6 +418,7 @@ enum mlx5_res_type { MLX5_RES_SQ = MLX5_EVENT_QUEUE_TYPE_SQ, MLX5_RES_SRQ = 3, MLX5_RES_XSRQ = 4, + MLX5_RES_XRQ = 5, }; struct mlx5_core_rsc_common { @@ -525,6 +534,9 @@ struct mlx5_mkey_table { struct mlx5_vf_context { int enabled; + u64 port_guid; + u64 node_guid; + enum port_state_policy policy; }; struct mlx5_core_sriov { @@ -534,7 +546,6 @@ struct mlx5_core_sriov { }; struct mlx5_irq_info { - cpumask_var_t mask; char name[MLX5_MAX_IRQ_NAME]; }; @@ -550,6 +561,7 @@ struct mlx5_fc_stats { unsigned long sampling_interval; /* jiffies */ }; +struct mlx5_mpfs; struct mlx5_eswitch; struct mlx5_lag; struct mlx5_pagefault; @@ -597,7 +609,6 @@ struct mlx5_port_module_event_stats { struct mlx5_priv { char name[MLX5_MAX_NAME_LEN]; struct mlx5_eq_table eq_table; - struct msix_entry *msix_arr; struct mlx5_irq_info *irq_info; /* pages stuff */ @@ -646,7 +657,11 @@ struct mlx5_priv { struct list_head ctx_list; spinlock_t ctx_lock; + struct list_head waiting_events_list; + bool is_accum_events; + struct mlx5_flow_steering *steering; + struct mlx5_mpfs *mpfs; struct mlx5_eswitch *eswitch; struct mlx5_core_sriov sriov; struct mlx5_lag *lag; @@ -673,9 +688,7 @@ enum mlx5_device_state { }; enum mlx5_interface_state { - MLX5_INTERFACE_STATE_DOWN = BIT(0), - MLX5_INTERFACE_STATE_UP = BIT(1), - MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2), + MLX5_INTERFACE_STATE_UP = BIT(0), }; enum mlx5_pci_status { @@ -761,6 +774,7 @@ struct mlx5_core_dev { u32 hca_max[MLX5_CAP_NUM][MLX5_UN_SZ_DW(hca_cap_union)]; u32 pcam[MLX5_ST_SZ_DW(pcam_reg)]; u32 mcam[MLX5_ST_SZ_DW(mcam_reg)]; + u32 fpga[MLX5_ST_SZ_DW(fpga_cap)]; } caps; phys_addr_t iseg_base; struct mlx5_init_seg __iomem *iseg; @@ -842,13 +856,6 @@ struct mlx5_pas { u8 log_sz; }; -enum port_state_policy { - MLX5_POLICY_DOWN = 0, - MLX5_POLICY_UP = 1, - MLX5_POLICY_FOLLOW = 2, - MLX5_POLICY_INVALID = 0xffffffff -}; - enum phy_port_state { MLX5_AAA_111 }; @@ -885,8 +892,6 @@ static inline void *mlx5_buf_offset(struct mlx5_buf *buf, int offset) return buf->direct.buf + offset; } -extern struct workqueue_struct *mlx5_core_wq; - #define STRUCT_FIELD(header, field) \ .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \ .struct_size_bytes = sizeof((struct ib_unpacked_ ## header *)0)->field @@ -1091,7 +1096,7 @@ enum { }; enum { - MAX_UMR_CACHE_ENTRY = 20, + MR_CACHE_LAST_STD_ENTRY = 20, MLX5_IMR_MTT_CACHE_ENTRY, MLX5_IMR_KSM_CACHE_ENTRY, MAX_MR_CACHE_ENTRIES @@ -1185,4 +1190,10 @@ enum { MLX5_TRIGGERED_CMD_COMP = (u64)1 << 32, }; +static inline const struct cpumask * +mlx5_get_vector_affinity(struct mlx5_core_dev *dev, int vector) +{ + return pci_irq_get_affinity(dev->pdev, MLX5_EQ_VEC_COMP_BASE + vector); +} + #endif /* MLX5_DRIVER_H */ diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 87869c04849ad6681cb3604320c8c39a5745e995..69772347f866680d1a19c08d4e5e5e48b5c233f8 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -200,6 +200,7 @@ enum { MLX5_CMD_OP_QUERY_SQ = 0x907, MLX5_CMD_OP_CREATE_RQ = 0x908, MLX5_CMD_OP_MODIFY_RQ = 0x909, + MLX5_CMD_OP_SET_DELAY_DROP_PARAMS = 0x910, MLX5_CMD_OP_DESTROY_RQ = 0x90a, MLX5_CMD_OP_QUERY_RQ = 0x90b, MLX5_CMD_OP_CREATE_RMP = 0x90c, @@ -294,8 +295,10 @@ struct mlx5_ifc_flow_table_fields_supported_bits { u8 inner_tcp_dport[0x1]; u8 inner_tcp_flags[0x1]; u8 reserved_at_37[0x9]; + u8 reserved_at_40[0x1a]; + u8 bth_dst_qp[0x1]; - u8 reserved_at_40[0x40]; + u8 reserved_at_5b[0x25]; }; struct mlx5_ifc_flow_table_prop_layout_bits { @@ -324,7 +327,8 @@ struct mlx5_ifc_flow_table_prop_layout_bits { u8 reserved_at_80[0x18]; u8 log_max_destination[0x8]; - u8 reserved_at_a0[0x18]; + u8 log_max_flow_counter[0x8]; + u8 reserved_at_a8[0x10]; u8 log_max_flow[0x8]; u8 reserved_at_c0[0x40]; @@ -431,7 +435,9 @@ struct mlx5_ifc_fte_match_set_misc_bits { u8 reserved_at_100[0xc]; u8 inner_ipv6_flow_label[0x14]; - u8 reserved_at_120[0xe0]; + u8 reserved_at_120[0x28]; + u8 bth_dst_qp[0x18]; + u8 reserved_at_160[0xa0]; }; struct mlx5_ifc_cmd_pas_bits { @@ -599,10 +605,10 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits { u8 rss_ind_tbl_cap[0x4]; u8 reg_umr_sq[0x1]; u8 scatter_fcs[0x1]; - u8 reserved_at_1a[0x1]; + u8 enhanced_multi_pkt_send_wqe[0x1]; u8 tunnel_lso_const_out_ip_id[0x1]; u8 reserved_at_1c[0x2]; - u8 tunnel_statless_gre[0x1]; + u8 tunnel_stateless_gre[0x1]; u8 tunnel_stateless_vxlan[0x1]; u8 swp[0x1]; @@ -840,7 +846,7 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 retransmission_q_counters[0x1]; u8 reserved_at_183[0x1]; u8 modify_rq_counter_set_id[0x1]; - u8 reserved_at_185[0x1]; + u8 rq_delay_drop[0x1]; u8 max_qp_cnt[0xa]; u8 pkey_table_size[0x10]; @@ -857,7 +863,7 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 pcam_reg[0x1]; u8 local_ca_ack_delay[0x5]; u8 port_module_event[0x1]; - u8 reserved_at_1b1[0x1]; + u8 enhanced_error_q_counters[0x1]; u8 ports_check[0x1]; u8 reserved_at_1b3[0x1]; u8 disable_link_up[0x1]; @@ -873,7 +879,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 max_tc[0x4]; u8 reserved_at_1d0[0x1]; u8 dcbx[0x1]; - u8 reserved_at_1d2[0x3]; + u8 general_notification_event[0x1]; + u8 reserved_at_1d3[0x2]; u8 fpga[0x1]; u8 rol_s[0x1]; u8 rol_g[0x1]; @@ -963,7 +970,7 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_2a0[0x10]; u8 max_wqe_sz_rq[0x10]; - u8 reserved_at_2c0[0x10]; + u8 max_flow_counter_31_16[0x10]; u8 max_wqe_sz_sq_dc[0x10]; u8 reserved_at_2e0[0x7]; @@ -981,7 +988,7 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_340[0x8]; u8 log_max_flow_counter_bulk[0x8]; - u8 max_flow_counter[0x10]; + u8 max_flow_counter_15_0[0x10]; u8 reserved_at_360[0x3]; @@ -1016,7 +1023,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 log_max_wq_sz[0x5]; u8 nic_vport_change_event[0x1]; - u8 reserved_at_3e1[0xa]; + u8 disable_local_lb[0x1]; + u8 reserved_at_3e2[0x9]; u8 log_max_vlan_list[0x5]; u8 reserved_at_3f0[0x3]; u8 log_max_current_mc_list[0x5]; @@ -1071,9 +1079,7 @@ struct mlx5_ifc_dest_format_struct_bits { }; struct mlx5_ifc_flow_counter_list_bits { - u8 clear[0x1]; - u8 num_of_counters[0xf]; - u8 flow_counter_id[0x10]; + u8 flow_counter_id[0x20]; u8 reserved_at_20[0x20]; }; @@ -1187,7 +1193,8 @@ struct mlx5_ifc_cong_control_r_roce_ecn_np_bits { u8 reserved_at_c0[0x12]; u8 cnp_dscp[0x6]; - u8 reserved_at_d8[0x5]; + u8 reserved_at_d8[0x4]; + u8 cnp_prio_mode[0x1]; u8 cnp_802p_prio[0x3]; u8 reserved_at_e0[0x720]; @@ -1540,7 +1547,17 @@ struct mlx5_ifc_eth_extended_cntrs_grp_data_layout_bits { u8 port_transmit_wait_low[0x20]; - u8 reserved_at_40[0x780]; + u8 reserved_at_40[0x100]; + + u8 rx_buffer_almost_full_high[0x20]; + + u8 rx_buffer_almost_full_low[0x20]; + + u8 rx_buffer_full_high[0x20]; + + u8 rx_buffer_full_low[0x20]; + + u8 reserved_at_1c0[0x600]; }; struct mlx5_ifc_eth_3635_cntrs_grp_data_layout_bits { @@ -1856,7 +1873,19 @@ struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits { u8 crc_error_tlp[0x20]; - u8 reserved_at_140[0x680]; + u8 tx_overflow_buffer_pkt_high[0x20]; + + u8 tx_overflow_buffer_pkt_low[0x20]; + + u8 outbound_stalled_reads[0x20]; + + u8 outbound_stalled_writes[0x20]; + + u8 outbound_stalled_reads_events[0x20]; + + u8 outbound_stalled_writes_events[0x20]; + + u8 reserved_at_200[0x5c0]; }; struct mlx5_ifc_cmd_inter_comp_event_bits { @@ -2014,6 +2043,10 @@ enum { MLX5_QPC_PM_STATE_MIGRATED = 0x3, }; +enum { + MLX5_QPC_OFFLOAD_TYPE_RNDV = 0x1, +}; + enum { MLX5_QPC_END_PADDING_MODE_SCATTER_AS_IS = 0x0, MLX5_QPC_END_PADDING_MODE_PAD_TO_CACHE_LINE_ALIGNMENT = 0x1, @@ -2057,7 +2090,8 @@ struct mlx5_ifc_qpc_bits { u8 st[0x8]; u8 reserved_at_10[0x3]; u8 pm_state[0x2]; - u8 reserved_at_15[0x7]; + u8 reserved_at_15[0x3]; + u8 offload_type[0x4]; u8 end_padding_mode[0x2]; u8 reserved_at_1e[0x2]; @@ -2437,7 +2471,7 @@ struct mlx5_ifc_sqc_bits { u8 cd_master[0x1]; u8 fre[0x1]; u8 flush_in_error_en[0x1]; - u8 reserved_at_4[0x1]; + u8 allow_multi_pkt_send_wqe[0x1]; u8 min_wqe_inline_mode[0x3]; u8 state[0x4]; u8 reg_umr[0x1]; @@ -2515,7 +2549,7 @@ enum { struct mlx5_ifc_rqc_bits { u8 rlky[0x1]; - u8 reserved_at_1[0x1]; + u8 delay_drop_en[0x1]; u8 scatter_fcs[0x1]; u8 vsd[0x1]; u8 mem_rq_type[0x4]; @@ -2562,7 +2596,9 @@ struct mlx5_ifc_rmpc_bits { struct mlx5_ifc_nic_vport_context_bits { u8 reserved_at_0[0x5]; u8 min_wqe_inline_mode[0x3]; - u8 reserved_at_8[0x17]; + u8 reserved_at_8[0x15]; + u8 disable_mc_local_lb[0x1]; + u8 disable_uc_local_lb[0x1]; u8 roce_en[0x1]; u8 arm_change_event[0x1]; @@ -3000,7 +3036,7 @@ struct mlx5_ifc_xrqc_bits { struct mlx5_ifc_tag_matching_topology_context_bits tag_matching_topology_context; - u8 reserved_at_180[0x880]; + u8 reserved_at_180[0x280]; struct mlx5_ifc_wq_bits wq; }; @@ -3947,7 +3983,47 @@ struct mlx5_ifc_query_q_counter_out_bits { u8 local_ack_timeout_err[0x20]; - u8 reserved_at_320[0x4e0]; + u8 reserved_at_320[0xa0]; + + u8 resp_local_length_error[0x20]; + + u8 req_local_length_error[0x20]; + + u8 resp_local_qp_error[0x20]; + + u8 local_operation_error[0x20]; + + u8 resp_local_protection[0x20]; + + u8 req_local_protection[0x20]; + + u8 resp_cqe_error[0x20]; + + u8 req_cqe_error[0x20]; + + u8 req_mw_binding[0x20]; + + u8 req_bad_response[0x20]; + + u8 req_remote_invalid_request[0x20]; + + u8 resp_remote_invalid_request[0x20]; + + u8 req_remote_access_errors[0x20]; + + u8 resp_remote_access_errors[0x20]; + + u8 req_remote_operation_errors[0x20]; + + u8 req_transport_retries_exceeded[0x20]; + + u8 cq_overflow[0x20]; + + u8 resp_cqe_flush_error[0x20]; + + u8 req_cqe_flush_error[0x20]; + + u8 reserved_at_620[0x1e0]; }; struct mlx5_ifc_query_q_counter_in_bits { @@ -4403,8 +4479,7 @@ struct mlx5_ifc_query_flow_counter_in_bits { u8 reserved_at_c1[0xf]; u8 num_of_counters[0x10]; - u8 reserved_at_e0[0x10]; - u8 flow_counter_id[0x10]; + u8 flow_counter_id[0x20]; }; struct mlx5_ifc_query_esw_vport_context_out_bits { @@ -5229,7 +5304,9 @@ struct mlx5_ifc_modify_nic_vport_context_out_bits { }; struct mlx5_ifc_modify_nic_vport_field_select_bits { - u8 reserved_at_0[0x16]; + u8 reserved_at_0[0x14]; + u8 disable_uc_local_lb[0x1]; + u8 disable_mc_local_lb[0x1]; u8 node_guid[0x1]; u8 port_guid[0x1]; u8 min_inline[0x1]; @@ -5847,6 +5924,28 @@ struct mlx5_ifc_destroy_rq_in_bits { u8 reserved_at_60[0x20]; }; +struct mlx5_ifc_set_delay_drop_params_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + + u8 reserved_at_40[0x20]; + + u8 reserved_at_60[0x10]; + u8 delay_drop_timeout[0x10]; +}; + +struct mlx5_ifc_set_delay_drop_params_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + + u8 syndrome[0x20]; + + u8 reserved_at_40[0x40]; +}; + struct mlx5_ifc_destroy_rmp_out_bits { u8 status[0x8]; u8 reserved_at_8[0x18]; @@ -6272,8 +6371,7 @@ struct mlx5_ifc_dealloc_flow_counter_in_bits { u8 reserved_at_20[0x10]; u8 op_mod[0x10]; - u8 reserved_at_40[0x10]; - u8 flow_counter_id[0x10]; + u8 flow_counter_id[0x20]; u8 reserved_at_60[0x20]; }; @@ -7098,8 +7196,7 @@ struct mlx5_ifc_alloc_flow_counter_out_bits { u8 syndrome[0x20]; - u8 reserved_at_40[0x10]; - u8 flow_counter_id[0x10]; + u8 flow_counter_id[0x20]; u8 reserved_at_60[0x20]; }; @@ -7718,8 +7815,9 @@ struct mlx5_ifc_peir_reg_bits { }; struct mlx5_ifc_pcam_enhanced_features_bits { - u8 reserved_at_0[0x7c]; + u8 reserved_at_0[0x7b]; + u8 rx_buffer_fullness_counters[0x1]; u8 ptys_connector_type[0x1]; u8 reserved_at_7d[0x1]; u8 ppcnt_discard_group[0x1]; @@ -7749,8 +7847,11 @@ struct mlx5_ifc_pcam_reg_bits { }; struct mlx5_ifc_mcam_enhanced_features_bits { - u8 reserved_at_0[0x7f]; - + u8 reserved_at_0[0x7b]; + u8 pcie_outbound_stalled[0x1]; + u8 tx_overflow_buffer_pkt[0x1]; + u8 mtpps_enh_out_per_adj[0x1]; + u8 mtpps_fs[0x1]; u8 pcie_performance_group[0x1]; }; @@ -8159,7 +8260,8 @@ struct mlx5_ifc_mtpps_reg_bits { u8 reserved_at_78[0x4]; u8 cap_pin_4_mode[0x4]; - u8 reserved_at_80[0x80]; + u8 field_select[0x20]; + u8 reserved_at_a0[0x60]; u8 enable[0x1]; u8 reserved_at_101[0xb]; @@ -8174,8 +8276,9 @@ struct mlx5_ifc_mtpps_reg_bits { u8 out_pulse_duration[0x10]; u8 out_periodic_adjustment[0x10]; + u8 enhanced_out_periodic_adjustment[0x20]; - u8 reserved_at_1a0[0x60]; + u8 reserved_at_1c0[0x20]; }; struct mlx5_ifc_mtppse_reg_bits { diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h index 6f41270d80c03128bdeb60e5c6fc1b6ca2b5fe54..66d19b611fe4fe6f6e3906ce262f5c67513065b0 100644 --- a/include/linux/mlx5/qp.h +++ b/include/linux/mlx5/qp.h @@ -212,7 +212,6 @@ struct mlx5_wqe_ctrl_seg { #define MLX5_WQE_CTRL_OPCODE_MASK 0xff #define MLX5_WQE_CTRL_WQE_INDEX_MASK 0x00ffff00 #define MLX5_WQE_CTRL_WQE_INDEX_SHIFT 8 -#define MLX5_WQE_AV_EXT 0x80000000 enum { MLX5_ETH_WQE_L3_INNER_CSUM = 1 << 4, @@ -561,6 +560,9 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev, int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp, u32 *out, int outlen); +int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev, + u32 timeout_usec); + int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn); int mlx5_core_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn); void mlx5_init_qp_table(struct mlx5_core_dev *dev); diff --git a/include/linux/mlx5/srq.h b/include/linux/mlx5/srq.h index 1cde0fd53f90e026645a3d171e79653e3477980a..24ff23e27c8ab117f23d7d00c93d16535ef0a663 100644 --- a/include/linux/mlx5/srq.h +++ b/include/linux/mlx5/srq.h @@ -38,6 +38,7 @@ enum { MLX5_SRQ_FLAG_ERR = (1 << 0), MLX5_SRQ_FLAG_WQ_SIG = (1 << 1), + MLX5_SRQ_FLAG_RNDV = (1 << 2), }; struct mlx5_srq_attr { @@ -56,6 +57,10 @@ struct mlx5_srq_attr { u32 user_index; u64 db_record; __be64 *pas; + u32 tm_log_list_size; + u32 tm_next_tag; + u32 tm_hw_phase_cnt; + u32 tm_sw_phase_cnt; }; struct mlx5_core_dev; diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index 656c70b65dd270a137f43106d993f1113fef73ab..aaa0bb9e7655c454877d283222312422a6a30c3f 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h @@ -114,5 +114,6 @@ int mlx5_core_modify_hca_vport_context(struct mlx5_core_dev *dev, u8 other_vport, u8 port_num, int vf, struct mlx5_hca_vport_context *req); - +int mlx5_nic_vport_update_local_lb(struct mlx5_core_dev *mdev, bool enable); +int mlx5_nic_vport_query_local_lb(struct mlx5_core_dev *mdev, bool *status); #endif /* __MLX5_VPORT_H__ */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 46b9ac5e856923ec77125cf5c468585167bf0ff6..065d99deb847e17fd54193035d0f0512b45df79d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -23,6 +23,7 @@ #include #include #include +#include struct mempolicy; struct anon_vma; @@ -189,7 +190,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */ #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_ARCH_1 0x01000000 /* Architecture-specific flag */ -#define VM_ARCH_2 0x02000000 +#define VM_WIPEONFORK 0x02000000 /* Wipe VMA contents in child. */ #define VM_DONTDUMP 0x04000000 /* Do not include in the core dump */ #ifdef CONFIG_MEM_SOFT_DIRTY @@ -208,10 +209,12 @@ extern unsigned int kobjsize(const void *objp); #define VM_HIGH_ARCH_BIT_1 33 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_2 34 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_3 35 /* bit only usable on 64-bit architectures */ +#define VM_HIGH_ARCH_BIT_4 36 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_0 BIT(VM_HIGH_ARCH_BIT_0) #define VM_HIGH_ARCH_1 BIT(VM_HIGH_ARCH_BIT_1) #define VM_HIGH_ARCH_2 BIT(VM_HIGH_ARCH_BIT_2) #define VM_HIGH_ARCH_3 BIT(VM_HIGH_ARCH_BIT_3) +#define VM_HIGH_ARCH_4 BIT(VM_HIGH_ARCH_BIT_4) #endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */ #if defined(CONFIG_X86) @@ -235,9 +238,11 @@ extern unsigned int kobjsize(const void *objp); # define VM_MAPPED_COPY VM_ARCH_1 /* T if mapped copy of data (nommu mmap) */ #endif -#if defined(CONFIG_X86) +#if defined(CONFIG_X86_INTEL_MPX) /* MPX specific bounds table or bounds directory */ -# define VM_MPX VM_ARCH_2 +# define VM_MPX VM_HIGH_ARCH_4 +#else +# define VM_MPX VM_NONE #endif #ifndef VM_GROWSUP @@ -795,6 +800,28 @@ static inline bool is_zone_device_page(const struct page *page) } #endif +#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC) +void put_zone_device_private_or_public_page(struct page *page); +DECLARE_STATIC_KEY_FALSE(device_private_key); +#define IS_HMM_ENABLED static_branch_unlikely(&device_private_key) +static inline bool is_device_private_page(const struct page *page); +static inline bool is_device_public_page(const struct page *page); +#else /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ +static inline void put_zone_device_private_or_public_page(struct page *page) +{ +} +#define IS_HMM_ENABLED 0 +static inline bool is_device_private_page(const struct page *page) +{ + return false; +} +static inline bool is_device_public_page(const struct page *page) +{ + return false; +} +#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ + + static inline void get_page(struct page *page) { page = compound_head(page); @@ -810,6 +837,18 @@ static inline void put_page(struct page *page) { page = compound_head(page); + /* + * For private device pages we need to catch refcount transition from + * 2 to 1, when refcount reach one it means the private device page is + * free and we need to inform the device driver through callback. See + * include/linux/memremap.h and HMM for details. + */ + if (IS_HMM_ENABLED && unlikely(is_device_private_page(page) || + unlikely(is_device_public_page(page)))) { + put_zone_device_private_or_public_page(page); + return; + } + if (put_page_testzero(page)) __put_page(page); } @@ -1195,8 +1234,10 @@ struct zap_details { pgoff_t last_index; /* Highest page->index to unmap */ }; -struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, - pte_t pte); +struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr, + pte_t pte, bool with_public_device); +#define vm_normal_page(vma, addr, pte) _vm_normal_page(vma, addr, pte, false) + struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t pmd); @@ -1260,6 +1301,7 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, void unmap_mapping_range(struct address_space *mapping, loff_t const holebegin, loff_t const holelen, int even_cows); int follow_pte_pmd(struct mm_struct *mm, unsigned long address, + unsigned long *start, unsigned long *end, pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); int follow_pfn(struct vm_area_struct *vma, unsigned long address, unsigned long *pfn); @@ -1992,13 +2034,13 @@ extern int nommu_shrink_inode_mappings(struct inode *, size_t, size_t); /* interval_tree.c */ void vma_interval_tree_insert(struct vm_area_struct *node, - struct rb_root *root); + struct rb_root_cached *root); void vma_interval_tree_insert_after(struct vm_area_struct *node, struct vm_area_struct *prev, - struct rb_root *root); + struct rb_root_cached *root); void vma_interval_tree_remove(struct vm_area_struct *node, - struct rb_root *root); -struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root *root, + struct rb_root_cached *root); +struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root_cached *root, unsigned long start, unsigned long last); struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node, unsigned long start, unsigned long last); @@ -2008,11 +2050,12 @@ struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node, vma; vma = vma_interval_tree_iter_next(vma, start, last)) void anon_vma_interval_tree_insert(struct anon_vma_chain *node, - struct rb_root *root); + struct rb_root_cached *root); void anon_vma_interval_tree_remove(struct anon_vma_chain *node, - struct rb_root *root); -struct anon_vma_chain *anon_vma_interval_tree_iter_first( - struct rb_root *root, unsigned long start, unsigned long last); + struct rb_root_cached *root); +struct anon_vma_chain * +anon_vma_interval_tree_iter_first(struct rb_root_cached *root, + unsigned long start, unsigned long last); struct anon_vma_chain *anon_vma_interval_tree_iter_next( struct anon_vma_chain *node, unsigned long start, unsigned long last); #ifdef CONFIG_DEBUG_VM_RB @@ -2293,6 +2336,8 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, pgprot_t pgprot); int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, pfn_t pfn); +int vm_insert_mixed_mkwrite(struct vm_area_struct *vma, unsigned long addr, + pfn_t pfn); int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); @@ -2505,7 +2550,7 @@ enum mf_action_page_type { #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) extern void clear_huge_page(struct page *page, - unsigned long addr, + unsigned long addr_hint, unsigned int pages_per_huge_page); extern void copy_user_huge_page(struct page *dst, struct page *src, unsigned long addr, struct vm_area_struct *vma, diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index e030a68ead7e211fcd1e19277fd3708e665bf78b..25438b2b6f223fb29989c41e1ce8ff854c425d10 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -126,4 +126,10 @@ static __always_inline enum lru_list page_lru(struct page *page) #define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) +#ifdef arch_unmap_kpfn +extern void arch_unmap_kpfn(unsigned long pfn); +#else +static __always_inline void arch_unmap_kpfn(unsigned long pfn) { } +#endif + #endif diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index ff151814a02d98b613237d1602839fd18358e115..46f4ecf5479adbb2829c26e63d5e56b20e779312 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -23,6 +23,7 @@ struct address_space; struct mem_cgroup; +struct hmm; /* * Each physical page in the system has a struct page associated with @@ -335,6 +336,7 @@ struct vm_area_struct { struct file * vm_file; /* File we map to (can be NULL). */ void * vm_private_data; /* was vm_pte (shared mem) */ + atomic_long_t swap_readahead_info; #ifndef CONFIG_MMU struct vm_region *vm_region; /* NOMMU mapping region */ #endif @@ -487,19 +489,26 @@ struct mm_struct { /* numa_scan_seq prevents two threads setting pte_numa */ int numa_scan_seq; #endif -#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION) /* * An operation with batched TLB flushing is going on. Anything that * can move process memory needs to flush the TLB when moving a * PROT_NONE or PROT_NUMA mapped page. */ - bool tlb_flush_pending; + atomic_t tlb_flush_pending; +#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH + /* See flush_tlb_batched_pending() */ + bool tlb_flush_batched; #endif struct uprobes_state uprobes_state; #ifdef CONFIG_HUGETLB_PAGE atomic_long_t hugetlb_usage; #endif struct work_struct async_put_work; + +#if IS_ENABLED(CONFIG_HMM) + /* HMM needs to track a few things per mm */ + struct hmm *hmm; +#endif } __randomize_layout; extern struct mm_struct init_mm; @@ -518,46 +527,95 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm) return mm->cpu_vm_mask_var; } -#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION) -/* - * Memory barriers to keep this state in sync are graciously provided by - * the page table locks, outside of which no page table modifications happen. - * The barriers below prevent the compiler from re-ordering the instructions - * around the memory barriers that are already present in the code. - */ -static inline bool mm_tlb_flush_pending(struct mm_struct *mm) +struct mmu_gather; +extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end); +extern void tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end); + +static inline void init_tlb_flush_pending(struct mm_struct *mm) { - barrier(); - return mm->tlb_flush_pending; + atomic_set(&mm->tlb_flush_pending, 0); } -static inline void set_tlb_flush_pending(struct mm_struct *mm) -{ - mm->tlb_flush_pending = true; +static inline void inc_tlb_flush_pending(struct mm_struct *mm) +{ + atomic_inc(&mm->tlb_flush_pending); /* - * Guarantee that the tlb_flush_pending store does not leak into the - * critical section updating the page tables + * The only time this value is relevant is when there are indeed pages + * to flush. And we'll only flush pages after changing them, which + * requires the PTL. + * + * So the ordering here is: + * + * atomic_inc(&mm->tlb_flush_pending); + * spin_lock(&ptl); + * ... + * set_pte_at(); + * spin_unlock(&ptl); + * + * spin_lock(&ptl) + * mm_tlb_flush_pending(); + * .... + * spin_unlock(&ptl); + * + * flush_tlb_range(); + * atomic_dec(&mm->tlb_flush_pending); + * + * Where the increment if constrained by the PTL unlock, it thus + * ensures that the increment is visible if the PTE modification is + * visible. After all, if there is no PTE modification, nobody cares + * about TLB flushes either. + * + * This very much relies on users (mm_tlb_flush_pending() and + * mm_tlb_flush_nested()) only caring about _specific_ PTEs (and + * therefore specific PTLs), because with SPLIT_PTE_PTLOCKS and RCpc + * locks (PPC) the unlock of one doesn't order against the lock of + * another PTL. + * + * The decrement is ordered by the flush_tlb_range(), such that + * mm_tlb_flush_pending() will not return false unless all flushes have + * completed. */ - smp_mb__before_spinlock(); } -/* Clearing is done after a TLB flush, which also provides a barrier. */ -static inline void clear_tlb_flush_pending(struct mm_struct *mm) + +static inline void dec_tlb_flush_pending(struct mm_struct *mm) { - barrier(); - mm->tlb_flush_pending = false; + /* + * See inc_tlb_flush_pending(). + * + * This cannot be smp_mb__before_atomic() because smp_mb() simply does + * not order against TLB invalidate completion, which is what we need. + * + * Therefore we must rely on tlb_flush_*() to guarantee order. + */ + atomic_dec(&mm->tlb_flush_pending); } -#else + static inline bool mm_tlb_flush_pending(struct mm_struct *mm) { - return false; -} -static inline void set_tlb_flush_pending(struct mm_struct *mm) -{ + /* + * Must be called after having acquired the PTL; orders against that + * PTLs release and therefore ensures that if we observe the modified + * PTE we must also observe the increment from inc_tlb_flush_pending(). + * + * That is, it only guarantees to return true if there is a flush + * pending for _this_ PTL. + */ + return atomic_read(&mm->tlb_flush_pending); } -static inline void clear_tlb_flush_pending(struct mm_struct *mm) + +static inline bool mm_tlb_flush_nested(struct mm_struct *mm) { + /* + * Similar to mm_tlb_flush_pending(), we must have acquired the PTL + * for which there is a TLB flush pending in order to guarantee + * we've seen both that PTE modification and the increment. + * + * (no requirement on actually still holding the PTL, that is irrelevant) + */ + return atomic_read(&mm->tlb_flush_pending) > 1; } -#endif struct vm_fault; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 46c73e97e61f08a41d9753079345f5965caebbc5..279b39008a33bb68745d9ea55ea5dd7ed522fd1c 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -29,8 +29,8 @@ struct mmc_csd { unsigned char structure; unsigned char mmca_vsn; unsigned short cmdclass; - unsigned short tacc_clks; - unsigned int tacc_ns; + unsigned short taac_clks; + unsigned int taac_ns; unsigned int c_size; unsigned int r2w_factor; unsigned int max_dtr; diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index a0c63ea28796662160b117c14418fe2d867e536e..927519385482e4ab919a9e0dffd5181de450f5a4 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -122,11 +122,18 @@ struct mmc_data { unsigned int timeout_clks; /* data timeout (in clocks) */ unsigned int blksz; /* data block size */ unsigned int blocks; /* number of blocks */ + unsigned int blk_addr; /* block address */ int error; /* data error */ unsigned int flags; -#define MMC_DATA_WRITE (1 << 8) -#define MMC_DATA_READ (1 << 9) +#define MMC_DATA_WRITE BIT(8) +#define MMC_DATA_READ BIT(9) +/* Extra flags used by CQE */ +#define MMC_DATA_QBR BIT(10) /* CQE queue barrier*/ +#define MMC_DATA_PRIO BIT(11) /* CQE high priority */ +#define MMC_DATA_REL_WR BIT(12) /* Reliable write */ +#define MMC_DATA_DAT_TAG BIT(13) /* Tag request */ +#define MMC_DATA_FORCED_PRG BIT(14) /* Forced programming */ unsigned int bytes_xfered; @@ -149,18 +156,22 @@ struct mmc_request { struct completion completion; struct completion cmd_completion; void (*done)(struct mmc_request *);/* completion function */ + /* + * Notify uppers layers (e.g. mmc block driver) that recovery is needed + * due to an error associated with the mmc_request. Currently used only + * by CQE. + */ + void (*recovery_notifier)(struct mmc_request *); struct mmc_host *host; /* Allow other commands during this ongoing data transfer or busy wait */ bool cap_cmd_during_tfr; + + int tag; }; struct mmc_card; -struct mmc_async_req; -struct mmc_async_req *mmc_start_areq(struct mmc_host *host, - struct mmc_async_req *areq, - enum mmc_blk_status *ret_stat); void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq); int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ebd1cebbef0c9a1732e0b36542c3053f7d32c7d5..9a43763a68adb3e998ec942300688f99e065489b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -162,6 +162,50 @@ struct mmc_host_ops { unsigned int direction, int blk_size); }; +struct mmc_cqe_ops { + /* Allocate resources, and make the CQE operational */ + int (*cqe_enable)(struct mmc_host *host, struct mmc_card *card); + /* Free resources, and make the CQE non-operational */ + void (*cqe_disable)(struct mmc_host *host); + /* + * Issue a read, write or DCMD request to the CQE. Also deal with the + * effect of ->cqe_off(). + */ + int (*cqe_request)(struct mmc_host *host, struct mmc_request *mrq); + /* Free resources (e.g. DMA mapping) associated with the request */ + void (*cqe_post_req)(struct mmc_host *host, struct mmc_request *mrq); + /* + * Prepare the CQE and host controller to accept non-CQ commands. There + * is no corresponding ->cqe_on(), instead ->cqe_request() is required + * to deal with that. + */ + void (*cqe_off)(struct mmc_host *host); + /* + * Wait for all CQE tasks to complete. Return an error if recovery + * becomes necessary. + */ + int (*cqe_wait_for_idle)(struct mmc_host *host); + /* + * Notify CQE that a request has timed out. Return false if the request + * completed or true if a timeout happened in which case indicate if + * recovery is needed. + */ + bool (*cqe_timeout)(struct mmc_host *host, struct mmc_request *mrq, + bool *recovery_needed); + /* + * Stop all CQE activity and prepare the CQE and host controller to + * accept recovery commands. + */ + void (*cqe_recovery_start)(struct mmc_host *host); + /* + * Clear the queue and call mmc_cqe_request_done() on all requests. + * Requests that errored will have the error set on the mmc_request + * (data->error or cmd->error for DCMD). Requests that did not error + * will have zero data bytes transferred. + */ + void (*cqe_recovery_finish)(struct mmc_host *host); +}; + struct mmc_async_req { /* active mmc request */ struct mmc_request *mrq; @@ -272,7 +316,7 @@ struct mmc_host { #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ -#define MMC_CAP_NO_BOUNCE_BUFF (1 << 21) /* Disable bounce buffers on host */ +/* (1 << 21) is free for reuse */ #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ @@ -291,10 +335,6 @@ struct mmc_host { MMC_CAP2_HS200_1_2V_SDR) #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ -#define MMC_CAP2_PACKED_RD (1 << 12) /* Allow packed read */ -#define MMC_CAP2_PACKED_WR (1 << 13) /* Allow packed write */ -#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ - MMC_CAP2_PACKED_WR) #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ #define MMC_CAP2_HS400_1_8V (1 << 15) /* Can support HS400 1.8V */ #define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */ @@ -307,6 +347,8 @@ struct mmc_host { #define MMC_CAP2_HS400_ES (1 << 20) /* Host supports enhanced strobe */ #define MMC_CAP2_NO_SD (1 << 21) /* Do not send SD commands during initialization */ #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ +#define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ +#define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -328,9 +370,6 @@ struct mmc_host { unsigned int use_spi_crc:1; unsigned int claimed:1; /* host exclusively claimed */ unsigned int bus_dead:1; /* bus has been released */ -#ifdef CONFIG_MMC_DEBUG - unsigned int removed:1; /* host is being removed */ -#endif unsigned int can_retune:1; /* re-tuning can be used */ unsigned int doing_retune:1; /* re-tuning in progress */ unsigned int retune_now:1; /* do re-tuning at next req */ @@ -393,6 +432,13 @@ struct mmc_host { int dsr_req; /* DSR value is valid */ u32 dsr; /* optional driver stage (DSR) value */ + /* Command Queue Engine (CQE) support */ + const struct mmc_cqe_ops *cqe_ops; + void *cqe_private; + int cqe_qdepth; + bool cqe_enabled; + bool cqe_on; + unsigned long private[0] ____cacheline_aligned; }; diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index b733eb404ffce75cdf68a950c189265c454ca529..abacd5484bc0bfc0fd128519e75150baafbc9010 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -39,6 +39,7 @@ #define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 #define SDIO_DEVICE_ID_BROADCOM_4356 0x4356 +#define SDIO_DEVICE_ID_CYPRESS_4373 0x4373 #define SDIO_VENDOR_ID_INTEL 0x0089 #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index c91b3bcd158f8fa8b2dbc3d4738ade5fdcc600cb..6866e8126982e3ebc328725f4a84699f010ff001 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -94,17 +94,6 @@ struct mmu_notifier_ops { unsigned long address, pte_t pte); - /* - * Before this is invoked any secondary MMU is still ok to - * read/write to the page previously pointed to by the Linux - * pte because the page hasn't been freed yet and it won't be - * freed until this returns. If required set_page_dirty has to - * be called internally to this method. - */ - void (*invalidate_page)(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long address); - /* * invalidate_range_start() and invalidate_range_end() must be * paired and are called only when the mmap_sem and/or the @@ -220,8 +209,6 @@ extern int __mmu_notifier_test_young(struct mm_struct *mm, unsigned long address); extern void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, pte_t pte); -extern void __mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address); extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end); extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, @@ -268,13 +255,6 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm, __mmu_notifier_change_pte(mm, address, pte); } -static inline void mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address) -{ - if (mm_has_notifiers(mm)) - __mmu_notifier_invalidate_page(mm, address); -} - static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end) { @@ -420,6 +400,11 @@ extern void mmu_notifier_synchronize(void); #else /* CONFIG_MMU_NOTIFIER */ +static inline int mm_has_notifiers(struct mm_struct *mm) +{ + return 0; +} + static inline void mmu_notifier_release(struct mm_struct *mm) { } @@ -442,11 +427,6 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm, { } -static inline void mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address) -{ -} - static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end) { diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index fc14b8b3f6ce8a7cdd2a70ef89906c22d52f3b55..c8f89417740bb5819bc9cb2b81549e31a4af4fc0 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -114,6 +114,20 @@ struct zone_padding { #define ZONE_PADDING(name) #endif +#ifdef CONFIG_NUMA +enum numa_stat_item { + NUMA_HIT, /* allocated in intended node */ + NUMA_MISS, /* allocated in non intended node */ + NUMA_FOREIGN, /* was intended here, hit elsewhere */ + NUMA_INTERLEAVE_HIT, /* interleaver preferred this zone */ + NUMA_LOCAL, /* allocation from local node */ + NUMA_OTHER, /* allocation from other node */ + NR_VM_NUMA_STAT_ITEMS +}; +#else +#define NR_VM_NUMA_STAT_ITEMS 0 +#endif + enum zone_stat_item { /* First 128 byte cacheline (assuming 64 bit words) */ NR_FREE_PAGES, @@ -131,14 +145,6 @@ enum zone_stat_item { NR_BOUNCE, #if IS_ENABLED(CONFIG_ZSMALLOC) NR_ZSPAGES, /* allocated in zsmalloc */ -#endif -#ifdef CONFIG_NUMA - NUMA_HIT, /* allocated in intended node */ - NUMA_MISS, /* allocated in non intended node */ - NUMA_FOREIGN, /* was intended here, hit elsewhere */ - NUMA_INTERLEAVE_HIT, /* interleaver preferred this zone */ - NUMA_LOCAL, /* allocation from local node */ - NUMA_OTHER, /* allocation from other node */ #endif NR_FREE_CMA_PAGES, NR_VM_ZONE_STAT_ITEMS }; @@ -276,6 +282,7 @@ struct per_cpu_pageset { struct per_cpu_pages pcp; #ifdef CONFIG_NUMA s8 expire; + u16 vm_numa_stat_diff[NR_VM_NUMA_STAT_ITEMS]; #endif #ifdef CONFIG_SMP s8 stat_threshold; @@ -496,6 +503,7 @@ struct zone { ZONE_PADDING(_pad3_) /* Zone statistics */ atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; + atomic_long_t vm_numa_stat[NR_VM_NUMA_STAT_ITEMS]; } ____cacheline_internodealigned_in_smp; enum pgdat_flags { @@ -770,8 +778,7 @@ static inline bool is_dev_zone(const struct zone *zone) #include -extern struct mutex zonelists_mutex; -void build_all_zonelists(pg_data_t *pgdat, struct zone *zone); +void build_all_zonelists(pg_data_t *pgdat); void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx); bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark, int classzone_idx, unsigned int alloc_flags, @@ -896,7 +903,7 @@ int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *, int, extern int numa_zonelist_order_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); extern char numa_zonelist_order[]; -#define NUMA_ZONELIST_ORDER_LEN 16 /* string buffer size */ +#define NUMA_ZONELIST_ORDER_LEN 16 #ifndef CONFIG_NEED_MULTIPLE_NODES @@ -1087,8 +1094,14 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn) #error Allocator MAX_ORDER exceeds SECTION_SIZE #endif -#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT) -#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT) +static inline unsigned long pfn_to_section_nr(unsigned long pfn) +{ + return pfn >> PFN_SECTION_SHIFT; +} +static inline unsigned long section_nr_to_pfn(unsigned long sec) +{ + return sec << PFN_SECTION_SHIFT; +} #define SECTION_ALIGN_UP(pfn) (((pfn) + PAGES_PER_SECTION - 1) & PAGE_SECTION_MASK) #define SECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SECTION_MASK) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 3f74ef2281e8afac1e4667b4fbf4abcc5f89ff17..694cebb50f72c7d1cb404e26416e5400545c114c 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -674,8 +674,6 @@ struct ulpi_device_id { * struct fsl_mc_device_id - MC object device identifier * @vendor: vendor ID * @obj_type: MC object type - * @ver_major: MC object version major number - * @ver_minor: MC object version minor number * * Type of entries in the "device Id" table for MC object devices supported by * a MC object device driver. The last entry of the table has vendor set to 0x0 diff --git a/include/linux/module.h b/include/linux/module.h index e7bdd549e527bde19eeb565f8e5735d80f589d92..fe5aa3736707294a5a4b6f20ea83be79d91dc9c0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -209,7 +209,7 @@ extern void cleanup_module(void); #ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ -extern const typeof(name) __mod_##type##__##name##_device_table \ +extern typeof(name) __mod_##type##__##name##_device_table \ __attribute__ ((unused, alias(__stringify(name)))) #else /* !MODULE */ #define MODULE_DEVICE_TABLE(type, name) diff --git a/include/linux/msg.h b/include/linux/msg.h index a001305f5a79959a5e4f816320f3c4276e308e12..81263fe3f9dc9dee1d3341fa5c7eda322df415c0 100644 --- a/include/linux/msg.h +++ b/include/linux/msg.h @@ -2,6 +2,7 @@ #define _LINUX_MSG_H #include +#include #include /* one msg_msg structure for each message */ @@ -17,9 +18,9 @@ struct msg_msg { /* one msq_queue structure for each present queue on the system */ struct msg_queue { struct kern_ipc_perm q_perm; - time_t q_stime; /* last msgsnd time */ - time_t q_rtime; /* last msgrcv time */ - time_t q_ctime; /* last change time */ + time64_t q_stime; /* last msgsnd time */ + time64_t q_rtime; /* last msgrcv time */ + time64_t q_ctime; /* last change time */ unsigned long q_cbytes; /* current number of bytes on queue */ unsigned long q_qnum; /* number of messages in queue */ unsigned long q_qbytes; /* max number of bytes on queue */ @@ -31,12 +32,4 @@ struct msg_queue { struct list_head q_senders; } __randomize_layout; -/* Helper routines for sys_msgsnd and sys_msgrcv */ -extern long do_msgsnd(int msqid, long mtype, void __user *mtext, - size_t msgsz, int msgflg); -extern long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, - int msgflg, - long (*msg_fill)(void __user *, struct msg_msg *, - size_t)); - #endif /* _LINUX_MSG_H */ diff --git a/include/linux/msi.h b/include/linux/msi.h index df6d59201d31d9c7dd8e6e00a5fb113973d893f1..80e3b562bef6c9cb5f3e966b397ec61ef711940d 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -66,6 +66,7 @@ struct fsl_mc_msi_desc { * @mask_pos: [PCI MSI] Mask register position * @mask_base: [PCI MSI-X] Mask register base address * @platform: [platform] Platform device specific msi descriptor data + * @fsl_mc: [fsl-mc] FSL MC device specific msi descriptor data */ struct msi_desc { /* Shared device/bus type independent data */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f8a2ef239c60adf6ce49f5ebcdbf576db0bd434d..6cd0f6b7658b38c73be72e3a085d93a6362d2588 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -206,6 +206,15 @@ struct mtd_pairing_scheme { struct module; /* only needed for owner field in mtd_info */ +/** + * struct mtd_debug_info - debugging information for an MTD device. + * + * @dfs_dir: direntry object of the MTD device debugfs directory + */ +struct mtd_debug_info { + struct dentry *dfs_dir; +}; + struct mtd_info { u_char type; uint32_t flags; @@ -346,6 +355,7 @@ struct mtd_info { struct module *owner; struct device dev; int usecount; + struct mtd_debug_info dbg; }; int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, diff --git a/include/linux/mtd/nand-gpio.h b/include/linux/mtd/nand-gpio.h index 51534e50f7fc0c47c5da3e199f7ac17226e45caf..be4f45d89be26c0b73ea50bd00d07b6f9e5753b1 100644 --- a/include/linux/mtd/nand-gpio.h +++ b/include/linux/mtd/nand-gpio.h @@ -1,7 +1,7 @@ #ifndef __LINUX_MTD_NAND_GPIO_H #define __LINUX_MTD_NAND_GPIO_H -#include +#include struct gpio_nand_platdata { int gpio_nce; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/rawnand.h similarity index 98% rename from include/linux/mtd/nand.h rename to include/linux/mtd/rawnand.h index 892148c448cce2c9c9e9e59b2d44941283635cbd..2b05f4273babda7bde2247c07bf90f9363a73e7e 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/rawnand.h @@ -1,6 +1,4 @@ /* - * linux/include/linux/mtd/nand.h - * * Copyright © 2000-2010 David Woodhouse * Steven J. Hill * Thomas Gleixner @@ -15,8 +13,8 @@ * Changelog: * See git changelog. */ -#ifndef __LINUX_MTD_NAND_H -#define __LINUX_MTD_NAND_H +#ifndef __LINUX_MTD_RAWNAND_H +#define __LINUX_MTD_RAWNAND_H #include #include @@ -44,12 +42,6 @@ void nand_release(struct mtd_info *mtd); /* Internal helper for board drivers which need to override command function */ void nand_wait_ready(struct mtd_info *mtd); -/* locks all blocks present in the device */ -int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); - -/* unlocks specified locked blocks */ -int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); - /* The maximum number of NAND chips in an array */ #define NAND_MAX_CHIPS 8 @@ -89,10 +81,6 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); #define NAND_CMD_SET_FEATURES 0xef #define NAND_CMD_RESET 0xff -#define NAND_CMD_LOCK 0x2a -#define NAND_CMD_UNLOCK1 0x23 -#define NAND_CMD_UNLOCK2 0x24 - /* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30 #define NAND_CMD_RNDOUTSTART 0xE0 @@ -449,14 +437,16 @@ struct nand_jedec_params { __le16 crc; } __packed; +/* The maximum expected count of bytes in the NAND ID sequence */ +#define NAND_MAX_ID_LEN 8 + /** * struct nand_id - NAND id structure - * @data: buffer containing the id bytes. Currently 8 bytes large, but can - * be extended if required. + * @data: buffer containing the id bytes. * @len: ID length. */ struct nand_id { - u8 data[8]; + u8 data[NAND_MAX_ID_LEN]; int len; }; @@ -681,10 +671,10 @@ struct nand_buffers { * @tWW_min: WP# transition to WE# low */ struct nand_sdr_timings { - u32 tBERS_max; + u64 tBERS_max; u32 tCCS_min; - u32 tPROG_max; - u32 tR_max; + u64 tPROG_max; + u64 tR_max; u32 tALH_min; u32 tADL_min; u32 tALS_min; @@ -1028,8 +1018,6 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip) #define NAND_MFR_ATO 0x9b #define NAND_MFR_WINBOND 0xef -/* The maximum expected count of bytes in the NAND ID sequence */ -#define NAND_MAX_ID_LEN 8 /* * A helper for defining older NAND chips where the second ID byte fully @@ -1246,6 +1234,8 @@ int onfi_init_data_interface(struct nand_chip *chip, */ static inline bool nand_is_slc(struct nand_chip *chip) { + WARN(chip->bits_per_cell == 0, + "chip->bits_per_cell is used uninitialized\n"); return chip->bits_per_cell == 1; } @@ -1328,4 +1318,4 @@ void nand_cleanup(struct nand_chip *chip); /* Default extended ID decoding function */ void nand_decode_ext_id(struct nand_chip *chip); -#endif /* __LINUX_MTD_NAND_H */ +#endif /* __LINUX_MTD_RAWNAND_H */ diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 2251add65fa7e4fec83ebd6ec7b4347e5fc7863f..c759d403cbc06fba6626de302ca583800176de94 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/include/linux/mtd/sharpsl.h b/include/linux/mtd/sharpsl.h index 65e91d0fa9817b8d66d126754ccec5ec3f3b40c0..e1845fc4afbd00a0538e14bae74ea663fbf1ed05 100644 --- a/include/linux/mtd/sharpsl.h +++ b/include/linux/mtd/sharpsl.h @@ -8,7 +8,7 @@ * published by the Free Software Foundation. */ -#include +#include #include #include @@ -17,4 +17,5 @@ struct sharpsl_nand_platform_data { const struct mtd_ooblayout_ops *ecc_layout; struct mtd_partition *partitions; unsigned int nr_partitions; + const char *const *part_parsers; }; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 55faa2f07ccaf29ccef6a6bf46a66872e83d7a39..1f0a7fc7772feba68fbc99dc3fd25ea5df9028da 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -41,6 +41,8 @@ #define SPINOR_OP_WREN 0x06 /* Write enable */ #define SPINOR_OP_RDSR 0x05 /* Read status register */ #define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ +#define SPINOR_OP_RDSR2 0x3f /* Read status register 2 */ +#define SPINOR_OP_WRSR2 0x3e /* Write status register 2 */ #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ #define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */ @@ -56,6 +58,7 @@ #define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */ #define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */ #define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ +#define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ @@ -102,6 +105,7 @@ /* Used for Spansion flashes only. */ #define SPINOR_OP_BRWR 0x17 /* Bank register write */ +#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ /* Used for Micron flashes only. */ #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ @@ -116,6 +120,9 @@ #define SR_BP2 BIT(4) /* Block protect 2 */ #define SR_TB BIT(5) /* Top/Bottom protect */ #define SR_SRWD BIT(7) /* SR write protect */ +/* Spansion/Cypress specific status bits */ +#define SR_E_ERR BIT(5) +#define SR_P_ERR BIT(6) #define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ @@ -128,6 +135,9 @@ /* Configuration Register bits. */ #define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */ +/* Status Register 2 bits. */ +#define SR2_QUAD_EN_BIT7 BIT(7) + /* Supported SPI protocols */ #define SNOR_PROTO_INST_MASK GENMASK(23, 16) #define SNOR_PROTO_INST_SHIFT 16 @@ -218,6 +228,7 @@ enum spi_nor_option_flags { SNOR_F_NO_OP_CHIP_ERASE = BIT(2), SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), SNOR_F_READY_XSR_RDY = BIT(4), + SNOR_F_USE_CLSR = BIT(5), }; /** diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h index abed4dec5c2f672c4db8e8a60c81fed2df5f7bea..e373690cce0a4fc467caf04b66032c88c98c559d 100644 --- a/include/linux/mtd/xip.h +++ b/include/linux/mtd/xip.h @@ -30,7 +30,9 @@ * obviously not be running from flash. The __xipram is therefore marking * those functions so they get relocated to ram. */ -#define __xipram noinline __attribute__ ((__section__ (".data"))) +#ifdef CONFIG_XIP_KERNEL +#define __xipram noinline __attribute__ ((__section__ (".xiptext"))) +#endif /* * Each architecture has to provide the following macros. They must access @@ -90,10 +92,10 @@ #define xip_cpu_idle() do { } while (0) #endif -#else +#endif /* CONFIG_MTD_XIP */ +#ifndef __xipram #define __xipram - -#endif /* CONFIG_MTD_XIP */ +#endif #endif /* __LINUX_MTD_XIP_H__ */ diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h index 5577e1b773c4ae7c6ecb87ee528409fecf934432..ea96d4c82be7db6c74be886005c3f1f86d96a612 100644 --- a/include/linux/mux/consumer.h +++ b/include/linux/mux/consumer.h @@ -13,6 +13,8 @@ #ifndef _LINUX_MUX_CONSUMER_H #define _LINUX_MUX_CONSUMER_H +#include + struct device; struct mux_control; diff --git a/include/linux/net.h b/include/linux/net.h index dda2cc939a531dab67441c6ddf4b7869c6a06159..d97d80d7fdf8a9c97714d1349b5534ef5509e902 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -37,7 +37,7 @@ struct net; /* Historically, SOCKWQ_ASYNC_NOSPACE & SOCKWQ_ASYNC_WAITDATA were located * in sock->flags, but moved into sk->sk_wq->flags to be RCU protected. - * Eventually all flags will be in sk->sk_wq_flags. + * Eventually all flags will be in sk->sk_wq->flags. */ #define SOCKWQ_ASYNC_NOSPACE 0 #define SOCKWQ_ASYNC_WAITDATA 1 @@ -190,8 +190,16 @@ struct proto_ops { struct pipe_inode_info *pipe, size_t len, unsigned int flags); int (*set_peek_off)(struct sock *sk, int val); int (*peek_len)(struct socket *sock); + + /* The following functions are called internally by kernel with + * sock lock already held. + */ int (*read_sock)(struct sock *sk, read_descriptor_t *desc, sk_read_actor_t recv_actor); + int (*sendpage_locked)(struct sock *sk, struct page *page, + int offset, size_t size, int flags); + int (*sendmsg_locked)(struct sock *sk, struct msghdr *msg, + size_t size); }; #define DECLARE_SOCKADDR(type, dst, src) \ @@ -279,6 +287,8 @@ do { \ int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t len); +int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg, + struct kvec *vec, size_t num, size_t len); int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t len, int flags); @@ -297,6 +307,8 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, char *optval, unsigned int optlen); int kernel_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); +int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset, + size_t size, int flags); int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg); int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how); diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index 1d4737cffc7116c898b42787680b2e9b0dd46812..dc8b4896b77b090e8329bdee9766033a6a3b95fb 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -36,7 +36,6 @@ enum { /**/NETIF_F_GSO_SHIFT, /* keep the order of SKB_GSO_* bits */ NETIF_F_TSO_BIT /* ... TCPv4 segmentation */ = NETIF_F_GSO_SHIFT, - NETIF_F_UFO_BIT, /* ... UDPv4 fragmentation */ NETIF_F_GSO_ROBUST_BIT, /* ... ->SKB_GSO_DODGY */ NETIF_F_TSO_ECN_BIT, /* ... TCP ECN support */ NETIF_F_TSO_MANGLEID_BIT, /* ... IPV4 ID mangling allowed */ @@ -76,6 +75,7 @@ enum { NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */ NETIF_F_HW_ESP_BIT, /* Hardware ESP transformation offload */ NETIF_F_HW_ESP_TX_CSUM_BIT, /* ESP with TX checksum offload */ + NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */ /* * Add your fresh new feature above and remember to update @@ -118,7 +118,6 @@ enum { #define NETIF_F_TSO6 __NETIF_F(TSO6) #define NETIF_F_TSO_ECN __NETIF_F(TSO_ECN) #define NETIF_F_TSO __NETIF_F(TSO) -#define NETIF_F_UFO __NETIF_F(UFO) #define NETIF_F_VLAN_CHALLENGED __NETIF_F(VLAN_CHALLENGED) #define NETIF_F_RXFCS __NETIF_F(RXFCS) #define NETIF_F_RXALL __NETIF_F(RXALL) @@ -140,6 +139,7 @@ enum { #define NETIF_F_HW_TC __NETIF_F(HW_TC) #define NETIF_F_HW_ESP __NETIF_F(HW_ESP) #define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM) +#define NETIF_F_RX_UDP_TUNNEL_PORT __NETIF_F(RX_UDP_TUNNEL_PORT) #define for_each_netdev_feature(mask_addr, bit) \ for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) @@ -172,7 +172,7 @@ enum { NETIF_F_FSO) /* List of features with software fallbacks. */ -#define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_UFO | \ +#define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | \ NETIF_F_GSO_SCTP) /* diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 779b235955968353a926709436483bc3ea63dde9..f535779d9dc1dfe36934c2abba4e43d053ac5d6f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -35,7 +35,6 @@ #include #include -#include #include #include @@ -66,6 +65,7 @@ struct mpls_dev; /* UDP Tunnel offloads */ struct udp_tunnel_info; struct bpf_prog; +struct xdp_buff; void netdev_set_default_ethtool_ops(struct net_device *dev, const struct ethtool_ops *ops); @@ -693,10 +693,9 @@ struct netdev_rx_queue { */ struct rx_queue_attribute { struct attribute attr; - ssize_t (*show)(struct netdev_rx_queue *queue, - struct rx_queue_attribute *attr, char *buf); + ssize_t (*show)(struct netdev_rx_queue *queue, char *buf); ssize_t (*store)(struct netdev_rx_queue *queue, - struct rx_queue_attribute *attr, const char *buf, size_t len); + const char *buf, size_t len); }; #ifdef CONFIG_XPS @@ -770,31 +769,14 @@ static inline bool netdev_phys_item_id_same(struct netdev_phys_item_id *a, typedef u16 (*select_queue_fallback_t)(struct net_device *dev, struct sk_buff *skb); -/* These structures hold the attributes of qdisc and classifiers - * that are being passed to the netdevice through the setup_tc op. - */ -enum { +enum tc_setup_type { TC_SETUP_MQPRIO, TC_SETUP_CLSU32, TC_SETUP_CLSFLOWER, - TC_SETUP_MATCHALL, + TC_SETUP_CLSMATCHALL, TC_SETUP_CLSBPF, }; -struct tc_cls_u32_offload; - -struct tc_to_netdev { - unsigned int type; - union { - struct tc_cls_u32_offload *cls_u32; - struct tc_cls_flower_offload *cls_flower; - struct tc_cls_matchall_offload *cls_mall; - struct tc_cls_bpf_offload *cls_bpf; - struct tc_mqprio_qopt *mqprio; - }; - bool egress_dev; -}; - /* These structures hold the attributes of xdp state that are being passed * to the netdevice through the xdp op. */ @@ -977,8 +959,8 @@ struct xfrmdev_ops { * with PF and querying it may introduce a theoretical security risk. * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting); * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); - * int (*ndo_setup_tc)(struct net_device *dev, u32 handle, u32 chain_index, - * __be16 protocol, struct tc_to_netdev *tc); + * int (*ndo_setup_tc)(struct net_device *dev, enum tc_setup_type type, + * void *type_data); * Called to setup any 'tc' scheduler, classifier or action on @dev. * This is always called from the stack with the rtnl lock held and netif * tx queues stopped. This allows the netdevice to perform queue @@ -1138,7 +1120,12 @@ struct xfrmdev_ops { * int (*ndo_xdp)(struct net_device *dev, struct netdev_xdp *xdp); * This function is used to set or query state related to XDP on the * netdevice. See definition of enum xdp_netdev_command for details. - * + * int (*ndo_xdp_xmit)(struct net_device *dev, struct xdp_buff *xdp); + * This function is used to submit a XDP packet for transmit on a + * netdevice. + * void (*ndo_xdp_flush)(struct net_device *dev); + * This function is used to inform the driver to flush a particular + * xdp tx queue. Must be called on same CPU as xdp_xmit. */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -1221,9 +1208,8 @@ struct net_device_ops { struct net_device *dev, int vf, bool setting); int (*ndo_setup_tc)(struct net_device *dev, - u32 handle, u32 chain_index, - __be16 protocol, - struct tc_to_netdev *tc); + enum tc_setup_type type, + void *type_data); #if IS_ENABLED(CONFIG_FCOE) int (*ndo_fcoe_enable)(struct net_device *dev); int (*ndo_fcoe_disable)(struct net_device *dev); @@ -1323,6 +1309,9 @@ struct net_device_ops { int needed_headroom); int (*ndo_xdp)(struct net_device *dev, struct netdev_xdp *xdp); + int (*ndo_xdp_xmit)(struct net_device *dev, + struct xdp_buff *xdp); + void (*ndo_xdp_flush)(struct net_device *dev); }; /** @@ -1802,7 +1791,7 @@ struct net_device { #endif struct netdev_queue __rcu *ingress_queue; #ifdef CONFIG_NETFILTER_INGRESS - struct nf_hook_entry __rcu *nf_hooks_ingress; + struct nf_hook_entries __rcu *nf_hooks_ingress; #endif unsigned char broadcast[MAX_ADDR_LEN]; @@ -2308,6 +2297,7 @@ struct netdev_lag_lower_state_info { #define NETDEV_PRECHANGEUPPER 0x001A #define NETDEV_CHANGELOWERSTATE 0x001B #define NETDEV_UDP_TUNNEL_PUSH_INFO 0x001C +#define NETDEV_UDP_TUNNEL_DROP_INFO 0x001D #define NETDEV_CHANGE_TX_QUEUE_LEN 0x001E int register_netdevice_notifier(struct notifier_block *nb); @@ -2423,8 +2413,8 @@ struct net_device *dev_get_by_name_rcu(struct net *net, const char *name); struct net_device *__dev_get_by_name(struct net *net, const char *name); int dev_alloc_name(struct net_device *dev, const char *name); int dev_open(struct net_device *dev); -int dev_close(struct net_device *dev); -int dev_close_many(struct list_head *head, bool unlink); +void dev_close(struct net_device *dev); +void dev_close_many(struct list_head *head, bool unlink); void dev_disable_lro(struct net_device *dev); int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *newskb); int dev_queue_xmit(struct sk_buff *skb); @@ -2774,7 +2764,7 @@ struct softnet_data { unsigned int input_queue_head ____cacheline_aligned_in_smp; /* Elements below can be accessed between CPUs for RPS/RFS */ - struct call_single_data csd ____cacheline_aligned_in_smp; + call_single_data_t csd ____cacheline_aligned_in_smp; struct softnet_data *rps_ipi_next; unsigned int cpu; unsigned int input_queue_tail; @@ -3251,6 +3241,8 @@ static inline void dev_consume_skb_any(struct sk_buff *skb) __dev_kfree_skb_any(skb, SKB_REASON_CONSUMED); } +void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog); +int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb); int netif_rx(struct sk_buff *skb); int netif_rx_ni(struct sk_buff *skb); int netif_receive_skb(struct sk_buff *skb); @@ -3866,6 +3858,8 @@ int netdev_walk_all_upper_dev_rcu(struct net_device *dev, bool netdev_has_upper_dev_all_rcu(struct net_device *dev, struct net_device *upper_dev); +bool netdev_has_any_upper_dev(struct net_device *dev); + void *netdev_lower_get_next_private(struct net_device *dev, struct list_head **iter); void *netdev_lower_get_next_private_rcu(struct net_device *dev, @@ -4019,22 +4013,22 @@ static inline netdev_tx_t netdev_start_xmit(struct sk_buff *skb, struct net_devi return rc; } -int netdev_class_create_file_ns(struct class_attribute *class_attr, +int netdev_class_create_file_ns(const struct class_attribute *class_attr, const void *ns); -void netdev_class_remove_file_ns(struct class_attribute *class_attr, +void netdev_class_remove_file_ns(const struct class_attribute *class_attr, const void *ns); -static inline int netdev_class_create_file(struct class_attribute *class_attr) +static inline int netdev_class_create_file(const struct class_attribute *class_attr) { return netdev_class_create_file_ns(class_attr, NULL); } -static inline void netdev_class_remove_file(struct class_attribute *class_attr) +static inline void netdev_class_remove_file(const struct class_attribute *class_attr) { netdev_class_remove_file_ns(class_attr, NULL); } -extern struct kobj_ns_type_operations net_ns_type_operations; +extern const struct kobj_ns_type_operations net_ns_type_operations; const char *netdev_drivername(const struct net_device *dev); @@ -4089,7 +4083,6 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type) /* check flags correspondence */ BUILD_BUG_ON(SKB_GSO_TCPV4 != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT)); - BUILD_BUG_ON(SKB_GSO_UDP != (NETIF_F_UFO >> NETIF_F_GSO_SHIFT)); BUILD_BUG_ON(SKB_GSO_DODGY != (NETIF_F_GSO_ROBUST >> NETIF_F_GSO_SHIFT)); BUILD_BUG_ON(SKB_GSO_TCP_ECN != (NETIF_F_TSO_ECN >> NETIF_F_GSO_SHIFT)); BUILD_BUG_ON(SKB_GSO_TCP_FIXEDID != (NETIF_F_TSO_MANGLEID >> NETIF_F_GSO_SHIFT)); diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 22f081065d4966dbbd3c09bc2b3eea5ecd8c8cf9..f84bca1703cdc865eabfe1f0290b882f4baee99f 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -72,25 +72,32 @@ struct nf_hook_ops { }; struct nf_hook_entry { - struct nf_hook_entry __rcu *next; nf_hookfn *hook; void *priv; - const struct nf_hook_ops *orig_ops; }; -static inline void -nf_hook_entry_init(struct nf_hook_entry *entry, const struct nf_hook_ops *ops) -{ - entry->next = NULL; - entry->hook = ops->hook; - entry->priv = ops->priv; - entry->orig_ops = ops; -} +struct nf_hook_entries { + u16 num_hook_entries; + /* padding */ + struct nf_hook_entry hooks[]; + + /* trailer: pointers to original orig_ops of each hook. + * + * This is not part of struct nf_hook_entry since its only + * needed in slow path (hook register/unregister). + * + * const struct nf_hook_ops *orig_ops[] + */ +}; -static inline int -nf_hook_entry_priority(const struct nf_hook_entry *entry) +static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e) { - return entry->orig_ops->priority; + unsigned int n = e->num_hook_entries; + const void *hook_end; + + hook_end = &e->hooks[n]; /* this is *past* ->hooks[]! */ + + return (struct nf_hook_ops **)hook_end; } static inline int @@ -100,12 +107,6 @@ nf_hook_entry_hookfn(const struct nf_hook_entry *entry, struct sk_buff *skb, return entry->hook(entry->priv, skb, state); } -static inline const struct nf_hook_ops * -nf_hook_entry_ops(const struct nf_hook_entry *entry) -{ - return entry->orig_ops; -} - static inline void nf_hook_state_init(struct nf_hook_state *p, unsigned int hook, u_int8_t pf, @@ -168,7 +169,7 @@ extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; #endif int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, - struct nf_hook_entry *entry); + const struct nf_hook_entries *e, unsigned int i); /** * nf_hook - call a netfilter hook @@ -182,7 +183,7 @@ static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct net *, struct sock *, struct sk_buff *)) { - struct nf_hook_entry *hook_head; + struct nf_hook_entries *hook_head; int ret = 1; #ifdef HAVE_JUMP_LABEL @@ -200,7 +201,7 @@ static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net, nf_hook_state_init(&state, hook, pf, indev, outdev, sk, net, okfn); - ret = nf_hook_slow(skb, &state, hook_head); + ret = nf_hook_slow(skb, &state, hook_head, 0); } rcu_read_unlock(); diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h index 074790c0cf74e78b542e0eaaf0aaca907e6c2d54..0fc458bde80b3f8413a988c10a4ce603a2e1bf72 100644 --- a/include/linux/netfilter/xt_hashlimit.h +++ b/include/linux/netfilter/xt_hashlimit.h @@ -5,5 +5,6 @@ #define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \ - XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES) + XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES |\ + XT_HASHLIMIT_RATE_MATCH) #endif /*_XT_HASHLIMIT_H*/ diff --git a/include/linux/netfilter_ingress.h b/include/linux/netfilter_ingress.h index 59476061de868d686e59cc77a936624f85329e2e..8d5dae1e2ff85185fe64fa2874a9d5abdc0d0717 100644 --- a/include/linux/netfilter_ingress.h +++ b/include/linux/netfilter_ingress.h @@ -17,7 +17,7 @@ static inline bool nf_hook_ingress_active(const struct sk_buff *skb) /* caller must hold rcu_read_lock */ static inline int nf_hook_ingress(struct sk_buff *skb) { - struct nf_hook_entry *e = rcu_dereference(skb->dev->nf_hooks_ingress); + struct nf_hook_entries *e = rcu_dereference(skb->dev->nf_hooks_ingress); struct nf_hook_state state; int ret; @@ -30,7 +30,7 @@ static inline int nf_hook_ingress(struct sk_buff *skb) nf_hook_state_init(&state, NF_NETDEV_INGRESS, NFPROTO_NETDEV, skb->dev, NULL, NULL, dev_net(skb->dev), NULL); - ret = nf_hook_slow(skb, &state, e); + ret = nf_hook_slow(skb, &state, e, 0); if (ret == 0) return -1; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 5cc91d6381a35ce73d64fbf40743a21ef2876d68..a0282ceaa48b7a2ac71cf3c5942169096289c7a6 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -49,7 +49,6 @@ struct nfs_access_entry { struct rb_node rb_node; struct list_head lru; - unsigned long jiffies; struct rpc_cred * cred; __u32 mask; struct rcu_head rcu_head; @@ -154,7 +153,7 @@ struct nfs_inode { */ __be32 cookieverf[2]; - unsigned long nrequests; + atomic_long_t nrequests; struct nfs_mds_commit_info commit_info; /* Open contexts for shared mmap writes */ @@ -163,6 +162,7 @@ struct nfs_inode { /* Readers: in-flight sillydelete RPC calls */ /* Writers: rmdir */ struct rw_semaphore rmdir_sem; + struct mutex commit_mutex; #if IS_ENABLED(CONFIG_NFS_V4) struct nfs4_cached_acl *nfs4_acl; @@ -510,7 +510,7 @@ extern void nfs_commit_free(struct nfs_commit_data *data); static inline int nfs_have_writebacks(struct inode *inode) { - return NFS_I(inode)->nrequests != 0; + return atomic_long_read(&NFS_I(inode)->nrequests) != 0; } /* diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index d67b67ae6c8bfba9ccfdbdbdd1d132e203f22b55..d117120c9b6e06ed5f3f02651cc18be9575b7c76 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -125,8 +125,7 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc, const struct nfs_pgio_completion_ops *compl_ops, const struct nfs_rw_ops *rw_ops, size_t bsize, - int how, - gfp_t gfp_flags); + int how); extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *, struct nfs_page *); extern int nfs_pageio_resend(struct nfs_pageio_descriptor *, @@ -139,8 +138,7 @@ extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, extern int nfs_wait_on_request(struct nfs_page *); extern void nfs_unlock_request(struct nfs_page *req); extern void nfs_unlock_and_release_request(struct nfs_page *); -extern int nfs_page_group_lock(struct nfs_page *, bool); -extern void nfs_page_group_lock_wait(struct nfs_page *); +extern int nfs_page_group_lock(struct nfs_page *); extern void nfs_page_group_unlock(struct nfs_page *); extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index ca3bcc4ed4e55563ecd505fada0cc0dc1f5dbb8d..164d5359d4ab0099772cfc21f5c257f2a9d6211d 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1235,7 +1235,7 @@ struct nfs41_state_protection { struct nfs41_exchange_id_args { struct nfs_client *client; - nfs4_verifier *verifier; + nfs4_verifier verifier; u32 flags; struct nfs41_state_protection state_protect; }; @@ -1476,7 +1476,7 @@ struct nfs_pgio_header { struct nfs_mds_commit_info { atomic_t rpcs_out; - unsigned long ncommit; + atomic_long_t ncommit; struct list_head list; }; diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 8aa01fd859fb84e5f64e9d7ffb0c20957afdfd2d..27e249ed7c5c8dfcbd969e347ff844a56899edc7 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -12,11 +12,31 @@ #ifdef CONFIG_LOCKUP_DETECTOR void lockup_detector_init(void); +void lockup_detector_soft_poweroff(void); +void lockup_detector_cleanup(void); +bool is_hardlockup(void); + +extern int watchdog_user_enabled; +extern int nmi_watchdog_user_enabled; +extern int soft_watchdog_user_enabled; +extern int watchdog_thresh; +extern unsigned long watchdog_enabled; + +extern struct cpumask watchdog_cpumask; +extern unsigned long *watchdog_cpumask_bits; +#ifdef CONFIG_SMP +extern int sysctl_softlockup_all_cpu_backtrace; +extern int sysctl_hardlockup_all_cpu_backtrace; #else -static inline void lockup_detector_init(void) -{ -} -#endif +#define sysctl_softlockup_all_cpu_backtrace 0 +#define sysctl_hardlockup_all_cpu_backtrace 0 +#endif /* !CONFIG_SMP */ + +#else /* CONFIG_LOCKUP_DETECTOR */ +static inline void lockup_detector_init(void) { } +static inline void lockup_detector_soft_poweroff(void) { } +static inline void lockup_detector_cleanup(void) { } +#endif /* !CONFIG_LOCKUP_DETECTOR */ #ifdef CONFIG_SOFTLOCKUP_DETECTOR extern void touch_softlockup_watchdog_sched(void); @@ -24,29 +44,17 @@ extern void touch_softlockup_watchdog(void); extern void touch_softlockup_watchdog_sync(void); extern void touch_all_softlockup_watchdogs(void); extern unsigned int softlockup_panic; -extern int soft_watchdog_enabled; -extern atomic_t watchdog_park_in_progress; #else -static inline void touch_softlockup_watchdog_sched(void) -{ -} -static inline void touch_softlockup_watchdog(void) -{ -} -static inline void touch_softlockup_watchdog_sync(void) -{ -} -static inline void touch_all_softlockup_watchdogs(void) -{ -} +static inline void touch_softlockup_watchdog_sched(void) { } +static inline void touch_softlockup_watchdog(void) { } +static inline void touch_softlockup_watchdog_sync(void) { } +static inline void touch_all_softlockup_watchdogs(void) { } #endif #ifdef CONFIG_DETECT_HUNG_TASK void reset_hung_task_detector(void); #else -static inline void reset_hung_task_detector(void) -{ -} +static inline void reset_hung_task_detector(void) { } #endif /* @@ -54,12 +62,12 @@ static inline void reset_hung_task_detector(void) * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. * - * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled' - * are variables that are only used as an 'interface' between the parameters - * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The - * 'watchdog_thresh' variable is handled differently because its value is not - * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh' - * is equal zero. + * 'watchdog_user_enabled', 'nmi_watchdog_user_enabled' and + * 'soft_watchdog_user_enabled' are variables that are only used as an + * 'interface' between the parameters in /proc/sys/kernel and the internal + * state bits in 'watchdog_enabled'. The 'watchdog_thresh' variable is + * handled differently because its value is not boolean, and the lockup + * detectors are 'suspended' while 'watchdog_thresh' is equal zero. */ #define NMI_WATCHDOG_ENABLED_BIT 0 #define SOFT_WATCHDOG_ENABLED_BIT 1 @@ -73,17 +81,41 @@ extern unsigned int hardlockup_panic; static inline void hardlockup_detector_disable(void) {} #endif +#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR) +# define NMI_WATCHDOG_SYSCTL_PERM 0644 +#else +# define NMI_WATCHDOG_SYSCTL_PERM 0444 +#endif + #if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) extern void arch_touch_nmi_watchdog(void); +extern void hardlockup_detector_perf_stop(void); +extern void hardlockup_detector_perf_restart(void); +extern void hardlockup_detector_perf_disable(void); +extern void hardlockup_detector_perf_enable(void); +extern void hardlockup_detector_perf_cleanup(void); +extern int hardlockup_detector_perf_init(void); #else -#if !defined(CONFIG_HAVE_NMI_WATCHDOG) +static inline void hardlockup_detector_perf_stop(void) { } +static inline void hardlockup_detector_perf_restart(void) { } +static inline void hardlockup_detector_perf_disable(void) { } +static inline void hardlockup_detector_perf_enable(void) { } +static inline void hardlockup_detector_perf_cleanup(void) { } +# if !defined(CONFIG_HAVE_NMI_WATCHDOG) +static inline int hardlockup_detector_perf_init(void) { return -ENODEV; } static inline void arch_touch_nmi_watchdog(void) {} -#endif +# else +static inline int hardlockup_detector_perf_init(void) { return 0; } +# endif #endif +void watchdog_nmi_stop(void); +void watchdog_nmi_start(void); +int watchdog_nmi_probe(void); + /** * touch_nmi_watchdog - restart NMI watchdog timeout. - * + * * If the architecture supports the NMI watchdog, touch_nmi_watchdog() * may be used to reset the timeout - for code which intentionally * disables interrupts for a long time. This call is stateless. @@ -153,22 +185,13 @@ static inline bool trigger_single_cpu_backtrace(int cpu) u64 hw_nmi_get_sample_period(int watchdog_thresh); #endif -#ifdef CONFIG_LOCKUP_DETECTOR -extern int nmi_watchdog_enabled; -extern int watchdog_user_enabled; -extern int watchdog_thresh; -extern unsigned long watchdog_enabled; -extern struct cpumask watchdog_cpumask; -extern unsigned long *watchdog_cpumask_bits; -extern int __read_mostly watchdog_suspended; -#ifdef CONFIG_SMP -extern int sysctl_softlockup_all_cpu_backtrace; -extern int sysctl_hardlockup_all_cpu_backtrace; +#if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ + defined(CONFIG_HARDLOCKUP_DETECTOR) +void watchdog_update_hrtimer_threshold(u64 period); #else -#define sysctl_softlockup_all_cpu_backtrace 0 -#define sysctl_hardlockup_all_cpu_backtrace 0 +static inline void watchdog_update_hrtimer_threshold(u64 period) { } #endif -extern bool is_hardlockup(void); + struct ctl_table; extern int proc_watchdog(struct ctl_table *, int , void __user *, size_t *, loff_t *); @@ -180,18 +203,6 @@ extern int proc_watchdog_thresh(struct ctl_table *, int , void __user *, size_t *, loff_t *); extern int proc_watchdog_cpumask(struct ctl_table *, int, void __user *, size_t *, loff_t *); -extern int lockup_detector_suspend(void); -extern void lockup_detector_resume(void); -#else -static inline int lockup_detector_suspend(void) -{ - return 0; -} - -static inline void lockup_detector_resume(void) -{ -} -#endif #ifdef CONFIG_HAVE_ACPI_APEI_NMI #include diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h index 6c8c5d8041b72ec01097d1c0563b793ea7449f1f..a726f96010d59d9d99eda4e6d5d5ea9776ebdd18 100644 --- a/include/linux/nvme-fc-driver.h +++ b/include/linux/nvme-fc-driver.h @@ -619,7 +619,7 @@ struct nvmefc_tgt_fcp_req { u32 timeout; u32 transfer_length; struct fc_ba_rjt ba_rjt; - struct scatterlist sg[NVME_FC_MAX_SEGMENTS]; + struct scatterlist *sg; int sg_cnt; void *rspaddr; dma_addr_t rspdma; @@ -801,11 +801,19 @@ struct nvmet_fc_target_port { * outstanding operation (if there was one) to complete, then will * call the fcp_req_release() callback to return the command's * exchange context back to the LLDD. + * Entrypoint is Mandatory. * * @fcp_req_release: Called by the transport to return a nvmefc_tgt_fcp_req * to the LLDD after all operations on the fcp operation are complete. * This may be due to the command completing or upon completion of * abort cleanup. + * Entrypoint is Mandatory. + * + * @defer_rcv: Called by the transport to signal the LLLD that it has + * begun processing of a previously received NVME CMD IU. The LLDD + * is now free to re-use the rcv buffer associated with the + * nvmefc_tgt_fcp_req. + * Entrypoint is Optional. * * @max_hw_queues: indicates the maximum number of hw queues the LLDD * supports for cpu affinitization. @@ -846,6 +854,8 @@ struct nvmet_fc_target_template { struct nvmefc_tgt_fcp_req *fcpreq); void (*fcp_req_release)(struct nvmet_fc_target_port *tgtport, struct nvmefc_tgt_fcp_req *fcpreq); + void (*defer_rcv)(struct nvmet_fc_target_port *tgtport, + struct nvmefc_tgt_fcp_req *fcpreq); u32 max_hw_queues; u16 max_sgl_segments; diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 25d8225dbd046d4dcac62e8261d1e49981b72df9..9310ce77d8e1f3b324e8c046ba414084530826e9 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -32,6 +32,8 @@ #define NVME_RDMA_IP_PORT 4420 +#define NVME_NSID_ALL 0xffffffff + enum nvme_subsys_type { NVME_NQN_DISC = 1, /* Discovery type target subsystem */ NVME_NQN_NVME = 2, /* NVME type target subsystem */ @@ -133,19 +135,26 @@ enum { enum { NVME_CC_ENABLE = 1 << 0, NVME_CC_CSS_NVM = 0 << 4, + NVME_CC_EN_SHIFT = 0, + NVME_CC_CSS_SHIFT = 4, NVME_CC_MPS_SHIFT = 7, - NVME_CC_ARB_RR = 0 << 11, - NVME_CC_ARB_WRRU = 1 << 11, - NVME_CC_ARB_VS = 7 << 11, - NVME_CC_SHN_NONE = 0 << 14, - NVME_CC_SHN_NORMAL = 1 << 14, - NVME_CC_SHN_ABRUPT = 2 << 14, - NVME_CC_SHN_MASK = 3 << 14, - NVME_CC_IOSQES = NVME_NVM_IOSQES << 16, - NVME_CC_IOCQES = NVME_NVM_IOCQES << 20, + NVME_CC_AMS_SHIFT = 11, + NVME_CC_SHN_SHIFT = 14, + NVME_CC_IOSQES_SHIFT = 16, + NVME_CC_IOCQES_SHIFT = 20, + NVME_CC_AMS_RR = 0 << NVME_CC_AMS_SHIFT, + NVME_CC_AMS_WRRU = 1 << NVME_CC_AMS_SHIFT, + NVME_CC_AMS_VS = 7 << NVME_CC_AMS_SHIFT, + NVME_CC_SHN_NONE = 0 << NVME_CC_SHN_SHIFT, + NVME_CC_SHN_NORMAL = 1 << NVME_CC_SHN_SHIFT, + NVME_CC_SHN_ABRUPT = 2 << NVME_CC_SHN_SHIFT, + NVME_CC_SHN_MASK = 3 << NVME_CC_SHN_SHIFT, + NVME_CC_IOSQES = NVME_NVM_IOSQES << NVME_CC_IOSQES_SHIFT, + NVME_CC_IOCQES = NVME_NVM_IOCQES << NVME_CC_IOCQES_SHIFT, NVME_CSTS_RDY = 1 << 0, NVME_CSTS_CFS = 1 << 1, NVME_CSTS_NSSRO = 1 << 4, + NVME_CSTS_PP = 1 << 5, NVME_CSTS_SHST_NORMAL = 0 << 2, NVME_CSTS_SHST_OCCUR = 1 << 2, NVME_CSTS_SHST_CMPLT = 2 << 2, @@ -217,7 +226,9 @@ struct nvme_id_ctrl { __le16 mntmt; __le16 mxtmt; __le32 sanicap; - __u8 rsvd332[180]; + __le32 hmminds; + __le16 hmmaxd; + __u8 rsvd338[174]; __u8 sqes; __u8 cqes; __le16 maxcmd; @@ -251,10 +262,11 @@ enum { NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1, NVME_CTRL_ONCS_DSM = 1 << 2, NVME_CTRL_ONCS_WRITE_ZEROES = 1 << 3, + NVME_CTRL_ONCS_TIMESTAMP = 1 << 6, NVME_CTRL_VWC_PRESENT = 1 << 0, NVME_CTRL_OACS_SEC_SUPP = 1 << 0, NVME_CTRL_OACS_DIRECTIVES = 1 << 5, - NVME_CTRL_OACS_DBBUF_SUPP = 1 << 7, + NVME_CTRL_OACS_DBBUF_SUPP = 1 << 8, }; struct nvme_lbaf { @@ -376,6 +388,13 @@ struct nvme_smart_log { __u8 rsvd216[296]; }; +struct nvme_fw_slot_info_log { + __u8 afi; + __u8 rsvd1[7]; + __le64 frs[7]; + __u8 rsvd64[448]; +}; + enum { NVME_SMART_CRIT_SPARE = 1 << 0, NVME_SMART_CRIT_TEMPERATURE = 1 << 1, @@ -386,6 +405,7 @@ enum { enum { NVME_AER_NOTICE_NS_CHANGED = 0x0002, + NVME_AER_NOTICE_FW_ACT_STARTING = 0x0102, }; struct nvme_lba_range_type { @@ -451,12 +471,14 @@ enum nvme_opcode { * * @NVME_SGL_FMT_ADDRESS: absolute address of the data block * @NVME_SGL_FMT_OFFSET: relative offset of the in-capsule data block + * @NVME_SGL_FMT_TRANSPORT_A: transport defined format, value 0xA * @NVME_SGL_FMT_INVALIDATE: RDMA transport specific remote invalidation * request subtype */ enum { NVME_SGL_FMT_ADDRESS = 0x00, NVME_SGL_FMT_OFFSET = 0x01, + NVME_SGL_FMT_TRANSPORT_A = 0x0A, NVME_SGL_FMT_INVALIDATE = 0x0f, }; @@ -470,12 +492,16 @@ enum { * * For struct nvme_keyed_sgl_desc: * @NVME_KEY_SGL_FMT_DATA_DESC: keyed data block descriptor + * + * Transport-specific SGL types: + * @NVME_TRANSPORT_SGL_DATA_DESC: Transport SGL data dlock descriptor */ enum { NVME_SGL_FMT_DATA_DESC = 0x00, NVME_SGL_FMT_SEG_DESC = 0x02, NVME_SGL_FMT_LAST_SEG_DESC = 0x03, NVME_KEY_SGL_FMT_DATA_DESC = 0x04, + NVME_TRANSPORT_SGL_DATA_DESC = 0x05, }; struct nvme_sgl_desc { @@ -677,6 +703,7 @@ enum { NVME_FEAT_ASYNC_EVENT = 0x0b, NVME_FEAT_AUTO_PST = 0x0c, NVME_FEAT_HOST_MEM_BUF = 0x0d, + NVME_FEAT_TIMESTAMP = 0x0e, NVME_FEAT_KATO = 0x0f, NVME_FEAT_SW_PROGRESS = 0x80, NVME_FEAT_HOST_ID = 0x81, @@ -1106,19 +1133,6 @@ enum { NVME_SC_UNWRITTEN_BLOCK = 0x287, NVME_SC_DNR = 0x4000, - - - /* - * FC Transport-specific error status values for NVME commands - * - * Transport-specific status code values must be in the range 0xB0..0xBF - */ - - /* Generic FC failure - catchall */ - NVME_SC_FC_TRANSPORT_ERROR = 0x00B0, - - /* I/O failure due to FC ABTS'd */ - NVME_SC_FC_TRANSPORT_ABORTED = 0x00B1, }; struct nvme_completion { diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h index c2256d74654333b9103fab444c4e318e2c7d422a..4e85447f78602754f56b988f576beb8ab8ab71bf 100644 --- a/include/linux/nvmem-consumer.h +++ b/include/linux/nvmem-consumer.h @@ -12,6 +12,9 @@ #ifndef _LINUX_NVMEM_CONSUMER_H #define _LINUX_NVMEM_CONSUMER_H +#include +#include + struct device; struct device_node; /* consumer cookie */ @@ -35,6 +38,7 @@ void nvmem_cell_put(struct nvmem_cell *cell); void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell); void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len); int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len); +int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val); /* direct nvmem device read/write interface */ struct nvmem_device *nvmem_device_get(struct device *dev, const char *name); @@ -85,6 +89,12 @@ static inline int nvmem_cell_write(struct nvmem_cell *cell, return -ENOSYS; } +static inline int nvmem_cell_read_u32(struct device *dev, + const char *cell_id, u32 *val) +{ + return -ENOSYS; +} + static inline struct nvmem_device *nvmem_device_get(struct device *dev, const char *name) { diff --git a/include/linux/of.h b/include/linux/of.h index 4a8a70916237ec1f9d1583d6cd69bf86f48102cc..cfc34117fc9203eefc2702a87271a95f761a2a3a 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -104,7 +104,6 @@ extern const struct fwnode_operations of_fwnode_ops; static inline void of_node_init(struct device_node *node) { kobject_init(&node->kobj, &of_node_ktype); - node->fwnode.type = FWNODE_OF; node->fwnode.ops = &of_fwnode_ops; } @@ -152,7 +151,7 @@ void of_core_init(void); static inline bool is_of_node(const struct fwnode_handle *fwnode) { - return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_OF; + return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &of_fwnode_ops; } #define to_of_node(__fwnode) \ diff --git a/include/linux/of_device.h b/include/linux/of_device.h index b4ad8b4f85065dae43ab10be81ac27851b4802e7..611502524425c8d7a57753efe693b3317c0a9726 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -50,7 +50,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu) struct device *cpu_dev; cpu_dev = get_cpu_device(cpu); if (!cpu_dev) - return NULL; + return of_get_cpu_node(cpu, NULL); return of_node_get(cpu_dev->of_node); } diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index e0d1946270f38e5238ddf0a3bb25cf03c3f3ebe4..fb908e598348097712981459b969f45fed4a8d09 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -57,7 +57,14 @@ extern const struct of_device_id of_default_bus_match_table[]; extern struct platform_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); +#ifdef CONFIG_OF extern struct platform_device *of_find_device_by_node(struct device_node *np); +#else +static inline struct platform_device *of_find_device_by_node(struct device_node *np) +{ + return NULL; +} +#endif /* Platform devices and busses creation */ extern struct platform_device *of_platform_device_create(struct device_node *np, diff --git a/include/linux/oom.h b/include/linux/oom.h index 8a266e2be5a63a29a2de38ff76f0bdc2e4fac08e..76aac4ce39bcf59e2e5eeb38053cf05f0c9d05ae 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -6,6 +6,8 @@ #include #include #include +#include /* MMF_* */ +#include /* VM_FAULT* */ struct zonelist; struct notifier_block; @@ -63,6 +65,26 @@ static inline bool tsk_is_oom_victim(struct task_struct * tsk) return tsk->signal->oom_mm; } +/* + * Checks whether a page fault on the given mm is still reliable. + * This is no longer true if the oom reaper started to reap the + * address space which is reflected by MMF_UNSTABLE flag set in + * the mm. At that moment any !shared mapping would lose the content + * and could cause a memory corruption (zero pages instead of the + * original content). + * + * User should call this before establishing a page table entry for + * a !shared mapping and under the proper page table lock. + * + * Return 0 when the PF is safe VM_FAULT_SIGBUS otherwise. + */ +static inline int check_stable_address_space(struct mm_struct *mm) +{ + if (unlikely(test_bit(MMF_UNSTABLE, &mm->flags))) + return VM_FAULT_SIGBUS; + return 0; +} + extern unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, const nodemask_t *nodemask, unsigned long totalpages); diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index d33e3280c8adc3b73a5426ec3bfdb6d0729d62ff..ba2d470d2d0a325e9e9d19d39bc675cc311b6a83 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -303,8 +303,8 @@ PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY) * Only test-and-set exist for PG_writeback. The unconditional operators are * risky: they bypass page accounting. */ -TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND) - TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND) +TESTPAGEFLAG(Writeback, writeback, PF_NO_TAIL) + TESTSCFLAG(Writeback, writeback, PF_NO_TAIL) PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_TAIL) /* PG_readahead is only used for reads; PG_reclaim is only for writes */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index baa9344dcd10deb9aaf418a76afa901d2a7f1558..5bbd6780f205103066bbf8b7d0d96959d5cbaed3 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -163,8 +163,6 @@ void release_pages(struct page **pages, int nr, bool cold); */ static inline int page_cache_get_speculative(struct page *page) { - VM_BUG_ON(in_interrupt()); - #ifdef CONFIG_TINY_RCU # ifdef CONFIG_PREEMPT_COUNT VM_BUG_ON(!in_atomic() && !irqs_disabled()); @@ -355,8 +353,16 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset); unsigned find_get_entries(struct address_space *mapping, pgoff_t start, unsigned int nr_entries, struct page **entries, pgoff_t *indices); -unsigned find_get_pages(struct address_space *mapping, pgoff_t start, - unsigned int nr_pages, struct page **pages); +unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start, + pgoff_t end, unsigned int nr_pages, + struct page **pages); +static inline unsigned find_get_pages(struct address_space *mapping, + pgoff_t *start, unsigned int nr_pages, + struct page **pages) +{ + return find_get_pages_range(mapping, start, (pgoff_t)-1, nr_pages, + pages); +} unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, unsigned int nr_pages, struct page **pages); unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index b45d391b454053c5af635db7992c1e12532f0a8e..4dcd5506f1ed02768a2b5d1654767e8f1293d4f9 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -27,8 +27,16 @@ unsigned pagevec_lookup_entries(struct pagevec *pvec, pgoff_t start, unsigned nr_entries, pgoff_t *indices); void pagevec_remove_exceptionals(struct pagevec *pvec); -unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, - pgoff_t start, unsigned nr_pages); +unsigned pagevec_lookup_range(struct pagevec *pvec, + struct address_space *mapping, + pgoff_t *start, pgoff_t end); +static inline unsigned pagevec_lookup(struct pagevec *pvec, + struct address_space *mapping, + pgoff_t *start) +{ + return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1); +} + unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping, pgoff_t *index, int tag, unsigned nr_pages); diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index af5edbf3eea3c2d1767bfaf660634ec63729b54f..f7a04e1af11212df4b5c265e66788442462b1a27 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -62,11 +62,13 @@ struct pci_epc_ops { * @size: the size of the PCI address space * @bitmap: bitmap to manage the PCI address space * @pages: number of bits representing the address region + * @page_size: size of each page */ struct pci_epc_mem { phys_addr_t phys_base; size_t size; unsigned long *bitmap; + size_t page_size; int pages; }; @@ -98,6 +100,9 @@ struct pci_epc { #define devm_pci_epc_create(dev, ops) \ __devm_pci_epc_create((dev), (ops), THIS_MODULE) +#define pci_epc_mem_init(epc, phys_addr, size) \ + __pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE) + static inline void epc_set_drvdata(struct pci_epc *epc, void *data) { dev_set_drvdata(&epc->dev, data); @@ -135,7 +140,8 @@ void pci_epc_stop(struct pci_epc *epc); struct pci_epc *pci_epc_get(const char *epc_name); void pci_epc_put(struct pci_epc *epc); -int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size); +int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size, + size_t page_size); void pci_epc_mem_exit(struct pci_epc *epc); void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, phys_addr_t *phys_addr, size_t size); diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index 0d529cb9014398df67893a72efb7f2f171111345..60d551a9a1baa0920b6c59b6d890e900bd6f6b07 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -14,17 +14,10 @@ #include #include +#include struct pci_epf; -enum pci_interrupt_pin { - PCI_INTERRUPT_UNKNOWN, - PCI_INTERRUPT_INTA, - PCI_INTERRUPT_INTB, - PCI_INTERRUPT_INTC, - PCI_INTERRUPT_INTD, -}; - enum pci_barno { BAR_0, BAR_1, @@ -149,6 +142,8 @@ static inline void *epf_get_drvdata(struct pci_epf *epf) return dev_get_drvdata(&epf->dev); } +const struct pci_epf_device_id * +pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf); struct pci_epf *pci_epf_create(const char *name); void pci_epf_destroy(struct pci_epf *epf); int __pci_epf_register_driver(struct pci_epf_driver *driver, diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66dd659a6bc8fe4ad90df2ed9d3ff98ccac..f4f8ee5a7362e982c0084d619c8ed1996a38f770 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -102,6 +102,28 @@ enum { DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, }; +/** + * enum pci_interrupt_pin - PCI INTx interrupt values + * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt + * @PCI_INTERRUPT_INTA: PCI INTA pin + * @PCI_INTERRUPT_INTB: PCI INTB pin + * @PCI_INTERRUPT_INTC: PCI INTC pin + * @PCI_INTERRUPT_INTD: PCI INTD pin + * + * Corresponds to values for legacy PCI INTx interrupts, as can be found in the + * PCI_INTERRUPT_PIN register. + */ +enum pci_interrupt_pin { + PCI_INTERRUPT_UNKNOWN, + PCI_INTERRUPT_INTA, + PCI_INTERRUPT_INTB, + PCI_INTERRUPT_INTC, + PCI_INTERRUPT_INTD, +}; + +/* The number of legacy PCI INTx interrupts */ +#define PCI_NUM_INTX 4 + /* * pci_power_t values must match the bits in the Capabilities PME_Support * and Control/Status PowerState fields in the Power Management capability. @@ -188,6 +210,8 @@ enum pci_dev_flags { * the direct_complete optimization. */ PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11), + /* Don't use Relaxed Ordering for TLPs directed at this device */ + PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 12), }; enum pci_irq_reroute_variant { @@ -451,6 +475,7 @@ struct pci_host_bridge { void *release_data; struct msi_controller *msi; unsigned int ignore_reset_delay:1; /* for entire hierarchy */ + unsigned int no_ext_tags:1; /* no Extended Tags */ /* Resource alignment requirements */ resource_size_t (*align_resource)(struct pci_dev *dev, const struct resource *res, @@ -729,6 +754,7 @@ struct pci_driver { void (*shutdown) (struct pci_dev *dev); int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */ const struct pci_error_handlers *err_handler; + const struct attribute_group **groups; struct device_driver driver; struct pci_dynids dynids; }; @@ -844,7 +870,6 @@ char *pcibios_setup(char *str); resource_size_t pcibios_align_resource(void *, const struct resource *, resource_size_t, resource_size_t); -void pcibios_update_irq(struct pci_dev *, int irq); /* Weak but can be overriden by arch */ void pci_fixup_cardbus(struct pci_bus *); @@ -1067,6 +1092,7 @@ void pcie_flr(struct pci_dev *dev); int __pci_reset_function(struct pci_dev *dev); int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev); +int pci_reset_function_locked(struct pci_dev *dev); int pci_try_reset_function(struct pci_dev *dev); int pci_probe_reset_slot(struct pci_slot *slot); int pci_reset_slot(struct pci_slot *slot); @@ -1125,6 +1151,7 @@ bool pci_check_pme_status(struct pci_dev *dev); void pci_pme_wakeup_bus(struct pci_bus *bus); void pci_d3cold_enable(struct pci_dev *dev); void pci_d3cold_disable(struct pci_dev *dev); +bool pcie_relaxed_ordering_enabled(struct pci_dev *dev); /* PCI Virtual Channel */ int pci_save_vc_state(struct pci_dev *dev); @@ -1160,8 +1187,6 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus); void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus); void pdev_enable_device(struct pci_dev *); int pci_enable_resources(struct pci_dev *, int mask); -void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), - int (*)(const struct pci_dev *, u8, u8)); void pci_assign_irq(struct pci_dev *dev); struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res); #define HAVE_PCI_REQ_REGIONS 2 @@ -1394,6 +1419,38 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, NULL); } +/** + * pci_irqd_intx_xlate() - Translate PCI INTx value to an IRQ domain hwirq + * @d: the INTx IRQ domain + * @node: the DT node for the device whose interrupt we're translating + * @intspec: the interrupt specifier data from the DT + * @intsize: the number of entries in @intspec + * @out_hwirq: pointer at which to write the hwirq number + * @out_type: pointer at which to write the interrupt type + * + * Translate a PCI INTx interrupt number from device tree in the range 1-4, as + * stored in the standard PCI_INTERRUPT_PIN register, to a value in the range + * 0-3 suitable for use in a 4 entry IRQ domain. That is, subtract one from the + * INTx value to obtain the hwirq number. + * + * Returns 0 on success, or -EINVAL if the interrupt specifier is out of range. + */ +static inline int pci_irqd_intx_xlate(struct irq_domain *d, + struct device_node *node, + const u32 *intspec, + unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + const u32 intx = intspec[0]; + + if (intx < PCI_INTERRUPT_INTA || intx > PCI_INTERRUPT_INTD) + return -EINVAL; + + *out_hwirq = intx - PCI_INTERRUPT_INTA; + return 0; +} + #ifdef CONFIG_PCIEPORTBUS extern bool pcie_ports_disabled; extern bool pcie_ports_auto; @@ -1628,6 +1685,8 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } #define dev_is_pci(d) (false) #define dev_is_pf(d) (false) +static inline bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags) +{ return false; } #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ @@ -2059,7 +2118,7 @@ static inline u16 pci_vpd_lrdt_tag(const u8 *lrdt) /** * pci_vpd_srdt_size - Extracts the Small Resource Data Type length - * @lrdt: Pointer to the beginning of the Small Resource Data Type tag + * @srdt: Pointer to the beginning of the Small Resource Data Type tag * * Returns the extracted Small Resource Data Type length. */ @@ -2070,7 +2129,7 @@ static inline u8 pci_vpd_srdt_size(const u8 *srdt) /** * pci_vpd_srdt_tag - Extracts the Small Resource Data Type Tag Item - * @lrdt: Pointer to the beginning of the Small Resource Data Type tag + * @srdt: Pointer to the beginning of the Small Resource Data Type tag * * Returns the extracted Small Resource Data Type Tag Item. */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c71e532da4589df0ee73fd0a8c2bb586c5f9f0ca..4adf6161ec77d9accd1015f51099c5db2857e4d6 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -576,6 +576,7 @@ #define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095 #define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096 #define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 +#define PCI_DEVICE_ID_AMD_CS5536_DEV_IDE 0x2092 #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082 diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index afcd130ab3a914c6a8af4736ae8cdc6cac11b703..e8f3f74792241fb314b0fbb6614cb87e1b2dbd9d 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h @@ -38,7 +38,7 @@ static inline void set_service_data(struct pcie_device *dev, void *data) dev->priv_data = data; } -static inline void* get_service_data(struct pcie_device *dev) +static inline void *get_service_data(struct pcie_device *dev) { return dev->priv_data; } @@ -50,8 +50,8 @@ struct pcie_port_service_driver { int (*suspend) (struct pcie_device *dev); int (*resume) (struct pcie_device *dev); - /* Service Error Recovery Handler */ - const struct pci_error_handlers *err_handler; + /* Device driver may resume normal operations */ + void (*error_resume)(struct pci_dev *dev); /* Link Reset Capability - AER service driver specific */ pci_ers_result_t (*reset_link) (struct pci_dev *dev); diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 491b3f5a5f8a86ee9347affdb1b08013757235e9..6a5fb939d3e5fd6cea40532402389d02f0835566 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -21,6 +21,25 @@ /* minimum unit size, also is the maximum supported allocation size */ #define PCPU_MIN_UNIT_SIZE PFN_ALIGN(32 << 10) +/* minimum allocation size and shift in bytes */ +#define PCPU_MIN_ALLOC_SHIFT 2 +#define PCPU_MIN_ALLOC_SIZE (1 << PCPU_MIN_ALLOC_SHIFT) + +/* number of bits per page, used to trigger a scan if blocks are > PAGE_SIZE */ +#define PCPU_BITS_PER_PAGE (PAGE_SIZE >> PCPU_MIN_ALLOC_SHIFT) + +/* + * This determines the size of each metadata block. There are several subtle + * constraints around this constant. The reserved region must be a multiple of + * PCPU_BITMAP_BLOCK_SIZE. Additionally, PCPU_BITMAP_BLOCK_SIZE must be a + * multiple of PAGE_SIZE or PAGE_SIZE must be a multiple of + * PCPU_BITMAP_BLOCK_SIZE to align with the populated page map. The unit_size + * also has to be a multiple of PCPU_BITMAP_BLOCK_SIZE to ensure full blocks. + */ +#define PCPU_BITMAP_BLOCK_SIZE PAGE_SIZE +#define PCPU_BITMAP_BLOCK_BITS (PCPU_BITMAP_BLOCK_SIZE >> \ + PCPU_MIN_ALLOC_SHIFT) + /* * Percpu allocator can serve percpu allocations before slab is * initialized which allows slab to depend on the percpu allocator. @@ -116,7 +135,6 @@ extern bool is_kernel_percpu_address(unsigned long addr); #if !defined(CONFIG_SMP) || !defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) extern void __init setup_per_cpu_areas(void); #endif -extern void __init percpu_init_late(void); extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp); extern void __percpu *__alloc_percpu(size_t size, size_t align); diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index a3b873fc59e41745c78bc31a70f0c71d7e4374c3..8e22f24ded6a3ad0e2accd96fe781be16c1987e4 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -139,17 +139,6 @@ struct hw_perf_event { /* for tp_event->class */ struct list_head tp_list; }; - struct { /* intel_cqm */ - int cqm_state; - u32 cqm_rmid; - int is_group_event; - struct list_head cqm_events_entry; - struct list_head cqm_groups_entry; - struct list_head cqm_group_entry; - }; - struct { /* itrace */ - int itrace_started; - }; struct { /* amd_power */ u64 pwr_acc; u64 ptsc; @@ -310,8 +299,8 @@ struct pmu { * Notification that the event was mapped or unmapped. Called * in the context of the mapping task. */ - void (*event_mapped) (struct perf_event *event); /*optional*/ - void (*event_unmapped) (struct perf_event *event); /*optional*/ + void (*event_mapped) (struct perf_event *event, struct mm_struct *mm); /* optional */ + void (*event_unmapped) (struct perf_event *event, struct mm_struct *mm); /* optional */ /* * Flags for ->add()/->del()/ ->start()/->stop(). There are @@ -416,11 +405,6 @@ struct pmu { size_t task_ctx_size; - /* - * Return the count value for a counter. - */ - u64 (*count) (struct perf_event *event); /*optional*/ - /* * Set up pmu-private data structures for an AUX area */ @@ -541,6 +525,7 @@ struct swevent_hlist { #define PERF_ATTACH_GROUP 0x02 #define PERF_ATTACH_TASK 0x04 #define PERF_ATTACH_TASK_DATA 0x08 +#define PERF_ATTACH_ITRACE 0x10 struct perf_cgroup; struct ring_buffer; @@ -864,6 +849,7 @@ extern int perf_aux_output_skip(struct perf_output_handle *handle, unsigned long size); extern void *perf_get_aux(struct perf_output_handle *handle); extern void perf_aux_output_flag(struct perf_output_handle *handle, u64 flags); +extern void perf_event_itrace_started(struct perf_event *event); extern int perf_pmu_register(struct pmu *pmu, const char *name, int type); extern void perf_pmu_unregister(struct pmu *pmu); @@ -944,6 +930,8 @@ struct perf_sample_data { struct perf_regs regs_intr; u64 stack_user_size; + + u64 phys_addr; } ____cacheline_aligned; /* default value for data source */ @@ -1111,11 +1099,6 @@ static inline void perf_event_task_sched_out(struct task_struct *prev, __perf_event_task_sched_out(prev, next); } -static inline u64 __perf_event_count(struct perf_event *event) -{ - return local64_read(&event->count) + atomic64_read(&event->child_count); -} - extern void perf_event_mmap(struct vm_area_struct *vma); extern struct perf_guest_info_callbacks *perf_guest_cbs; extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); @@ -1201,7 +1184,7 @@ extern void perf_event_init(void); extern void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, struct pt_regs *regs, struct hlist_head *head, int rctx, - struct task_struct *task); + struct task_struct *task, struct perf_event *event); extern void perf_bp_event(struct perf_event *event, void *data); #ifndef perf_misc_flags diff --git a/include/linux/phy.h b/include/linux/phy.h index 2a9567bb818636ddf979d8a2d6708991ee06d1a5..d78cd01ea5131018717d28d692b1af7abc3cff77 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -182,6 +182,7 @@ static inline const char *phy_modes(phy_interface_t interface) #define MII_ADDR_C45 (1<<30) struct device; +struct phylink; struct sk_buff; /* @@ -469,11 +470,13 @@ struct phy_device { struct mutex lock; + struct phylink *phylink; struct net_device *attached_dev; u8 mdix; u8 mdix_ctrl; + void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier); void (*adjust_link)(struct net_device *dev); }; #define to_phy_device(d) container_of(to_mdio_device(d), \ @@ -667,6 +670,24 @@ struct phy_fixup { int (*run)(struct phy_device *phydev); }; +const char *phy_speed_to_str(int speed); +const char *phy_duplex_to_str(unsigned int duplex); + +/* A structure for mapping a particular speed and duplex + * combination to a particular SUPPORTED and ADVERTISED value + */ +struct phy_setting { + u32 speed; + u8 duplex; + u8 bit; +}; + +const struct phy_setting * +phy_lookup_setting(int speed, int duplex, const unsigned long *mask, + size_t maxbit, bool exact); +size_t phy_speeds(unsigned int *speeds, size_t size, + unsigned long *mask, size_t maxbit); + /** * phy_read_mmd - Convenience function for reading a register * from an MMD on a given PHY. @@ -830,7 +851,7 @@ static inline int phy_read_status(struct phy_device *phydev) dev_err(&_phydev->mdio.dev, format, ##args) #define phydev_dbg(_phydev, format, args...) \ - dev_dbg(&_phydev->mdio.dev, format, ##args); + dev_dbg(&_phydev->mdio.dev, format, ##args) static inline const char *phydev_name(const struct phy_device *phydev) { diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 78bb0d7f6b11ac0a78e02eb35d12c9cbc0545a53..e694d4008c4a9121cbf1c8b6b0731f890b3570b3 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -27,6 +27,8 @@ enum phy_mode { PHY_MODE_USB_HOST, PHY_MODE_USB_DEVICE, PHY_MODE_USB_OTG, + PHY_MODE_SGMII, + PHY_MODE_10GKR, }; /** diff --git a/include/linux/phylink.h b/include/linux/phylink.h new file mode 100644 index 0000000000000000000000000000000000000000..af67edd4ae38067055443d105222249ed2dce709 --- /dev/null +++ b/include/linux/phylink.h @@ -0,0 +1,148 @@ +#ifndef NETDEV_PCS_H +#define NETDEV_PCS_H + +#include +#include +#include + +struct device_node; +struct ethtool_cmd; +struct net_device; + +enum { + MLO_PAUSE_NONE, + MLO_PAUSE_ASYM = BIT(0), + MLO_PAUSE_SYM = BIT(1), + MLO_PAUSE_RX = BIT(2), + MLO_PAUSE_TX = BIT(3), + MLO_PAUSE_TXRX_MASK = MLO_PAUSE_TX | MLO_PAUSE_RX, + MLO_PAUSE_AN = BIT(4), + + MLO_AN_PHY = 0, /* Conventional PHY */ + MLO_AN_FIXED, /* Fixed-link mode */ + MLO_AN_SGMII, /* Cisco SGMII protocol */ + MLO_AN_8023Z, /* 1000base-X protocol */ +}; + +static inline bool phylink_autoneg_inband(unsigned int mode) +{ + return mode == MLO_AN_SGMII || mode == MLO_AN_8023Z; +} + +struct phylink_link_state { + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); + __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising); + phy_interface_t interface; /* PHY_INTERFACE_xxx */ + int speed; + int duplex; + int pause; + unsigned int link:1; + unsigned int an_enabled:1; + unsigned int an_complete:1; +}; + +struct phylink_mac_ops { + /** + * validate: validate and update the link configuration + * @ndev: net_device structure associated with MAC + * @config: configuration to validate + * + * Update the %config->supported and %config->advertised masks + * clearing bits that can not be supported. + * + * Note: the PHY may be able to transform from one connection + * technology to another, so, eg, don't clear 1000BaseX just + * because the MAC is unable to support it. This is more about + * clearing unsupported speeds and duplex settings. + * + * If the %config->interface mode is %PHY_INTERFACE_MODE_1000BASEX + * or %PHY_INTERFACE_MODE_2500BASEX, select the appropriate mode + * based on %config->advertised and/or %config->speed. + */ + void (*validate)(struct net_device *ndev, unsigned long *supported, + struct phylink_link_state *state); + + /* Read the current link state from the hardware */ + int (*mac_link_state)(struct net_device *, struct phylink_link_state *); + + /* Configure the MAC */ + /** + * mac_config: configure the MAC for the selected mode and state + * @ndev: net_device structure for the MAC + * @mode: one of MLO_AN_FIXED, MLO_AN_PHY, MLO_AN_8023Z, MLO_AN_SGMII + * @state: state structure + * + * The action performed depends on the currently selected mode: + * + * %MLO_AN_FIXED, %MLO_AN_PHY: + * set the specified speed, duplex, pause mode, and phy interface + * mode in the provided @state. + * %MLO_AN_8023Z: + * place the link in 1000base-X mode, advertising the parameters + * given in advertising in @state. + * %MLO_AN_SGMII: + * place the link in Cisco SGMII mode - there is no advertisment + * to make as the PHY communicates the speed and duplex to the + * MAC over the in-band control word. Configuration of the pause + * mode is as per MLO_AN_PHY since this is not included. + */ + void (*mac_config)(struct net_device *ndev, unsigned int mode, + const struct phylink_link_state *state); + + /** + * mac_an_restart: restart 802.3z BaseX autonegotiation + * @ndev: net_device structure for the MAC + */ + void (*mac_an_restart)(struct net_device *ndev); + + void (*mac_link_down)(struct net_device *, unsigned int mode); + void (*mac_link_up)(struct net_device *, unsigned int mode, + struct phy_device *); +}; + +struct phylink *phylink_create(struct net_device *, struct device_node *, + phy_interface_t iface, const struct phylink_mac_ops *ops); +void phylink_destroy(struct phylink *); + +int phylink_connect_phy(struct phylink *, struct phy_device *); +int phylink_of_phy_connect(struct phylink *, struct device_node *); +void phylink_disconnect_phy(struct phylink *); + +void phylink_mac_change(struct phylink *, bool up); + +void phylink_start(struct phylink *); +void phylink_stop(struct phylink *); + +void phylink_ethtool_get_wol(struct phylink *, struct ethtool_wolinfo *); +int phylink_ethtool_set_wol(struct phylink *, struct ethtool_wolinfo *); + +int phylink_ethtool_ksettings_get(struct phylink *, + struct ethtool_link_ksettings *); +int phylink_ethtool_ksettings_set(struct phylink *, + const struct ethtool_link_ksettings *); +int phylink_ethtool_nway_reset(struct phylink *); +void phylink_ethtool_get_pauseparam(struct phylink *, + struct ethtool_pauseparam *); +int phylink_ethtool_set_pauseparam(struct phylink *, + struct ethtool_pauseparam *); +int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *); +int phylink_ethtool_get_module_eeprom(struct phylink *, + struct ethtool_eeprom *, u8 *); +int phylink_init_eee(struct phylink *, bool); +int phylink_get_eee_err(struct phylink *); +int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *); +int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *); +int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); + +#define phylink_zero(bm) \ + bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS) +#define __phylink_do_bit(op, bm, mode) \ + op(ETHTOOL_LINK_MODE_ ## mode ## _BIT, bm) + +#define phylink_set(bm, mode) __phylink_do_bit(__set_bit, bm, mode) +#define phylink_clear(bm, mode) __phylink_do_bit(__clear_bit, bm, mode) +#define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode) + +void phylink_set_port_modes(unsigned long *bits); + +#endif diff --git a/include/linux/pid.h b/include/linux/pid.h index 4d179316e43108f3a14ef48659a1d3a94ac320fb..719582744a2e873a978dbf9a925e143ec29243da 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -8,7 +8,9 @@ enum pid_type PIDTYPE_PID, PIDTYPE_PGID, PIDTYPE_SID, - PIDTYPE_MAX + PIDTYPE_MAX, + /* only valid to __task_pid_nr_ns() */ + __PIDTYPE_TGID }; /* diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index e5b1716f98cc5c6ebba26ead768ed36223c004bc..7fa5d87190c21f7e65cb3b32adde7bab928f5c09 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -152,12 +152,12 @@ struct pinctrl_map { #ifdef CONFIG_PINCTRL -extern int pinctrl_register_mappings(struct pinctrl_map const *map, +extern int pinctrl_register_mappings(const struct pinctrl_map *map, unsigned num_maps); extern void pinctrl_provide_dummies(void); #else -static inline int pinctrl_register_mappings(struct pinctrl_map const *map, +static inline int pinctrl_register_mappings(const struct pinctrl_map *map, unsigned num_maps) { return 0; diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 231d3075815adfa63d462a236e66f214c3216117..5d8bc7f21c2a07658bf25a4e60c6711478eb2be8 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -81,11 +81,12 @@ * it. * @PIN_CONFIG_OUTPUT: this will configure the pin as an output and drive a * value on the line. Use argument 1 to indicate high level, argument 0 to - * indicate low level. (Please see Documentation/pinctrl.txt, section - * "GPIO mode pitfalls" for a discussion around this parameter.) + * indicate low level. (Please see Documentation/driver-api/pinctl.rst, + * section "GPIO mode pitfalls" for a discussion around this parameter.) * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power * supplies, the argument to this parameter (on a custom format) tells * the driver which alternative power source to use. + * @PIN_CONFIG_SLEEP_HARDWARE_STATE: indicate this is sleep related state. * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to * this parameter (on a custom format) tells the driver which alternative * slew rate to use. @@ -114,6 +115,7 @@ enum pin_config_param { PIN_CONFIG_OUTPUT_ENABLE, PIN_CONFIG_OUTPUT, PIN_CONFIG_POWER_SOURCE, + PIN_CONFIG_SLEEP_HARDWARE_STATE, PIN_CONFIG_SLEW_RATE, PIN_CONFIG_END = 0x7F, PIN_CONFIG_MAX = 0xFF, diff --git a/include/linux/platform_data/gpio_backlight.h b/include/linux/platform_data/gpio_backlight.h index 5ae0d9c80d4df17aacd0246e876d83c2337e6ff2..683d90453c419fcef22b77cb3da550147d350b2b 100644 --- a/include/linux/platform_data/gpio_backlight.h +++ b/include/linux/platform_data/gpio_backlight.h @@ -14,7 +14,6 @@ struct gpio_backlight_platform_data { struct device *fbdev; int gpio; int def_value; - bool active_low; const char *name; }; diff --git a/include/linux/platform_data/hsmmc-omap.h b/include/linux/platform_data/hsmmc-omap.h index 0ff1e0dba7201b146a561369ddb3deedfe4d7d67..73d9098ada2d816b9d24bb81674549a51804c6c2 100644 --- a/include/linux/platform_data/hsmmc-omap.h +++ b/include/linux/platform_data/hsmmc-omap.h @@ -67,6 +67,9 @@ struct omap_hsmmc_platform_data { #define HSMMC_HAS_HSPE_SUPPORT (1 << 2) unsigned features; + /* string specifying a particular variant of hardware */ + char *version; + int gpio_cd; /* gpio (card detect) */ int gpio_cod; /* gpio (cover detect) */ int gpio_wp; /* gpio (write protect) */ diff --git a/include/linux/platform_data/mdio-bcm-unimac.h b/include/linux/platform_data/mdio-bcm-unimac.h new file mode 100644 index 0000000000000000000000000000000000000000..8a5f9f0b2c52039e3ff688a417f9ea045def88d4 --- /dev/null +++ b/include/linux/platform_data/mdio-bcm-unimac.h @@ -0,0 +1,13 @@ +#ifndef __MDIO_BCM_UNIMAC_PDATA_H +#define __MDIO_BCM_UNIMAC_PDATA_H + +struct unimac_mdio_pdata { + u32 phy_mask; + int (*wait_func)(void *data); + void *wait_func_data; + const char *bus_name; +}; + +#define UNIMAC_MDIO_DRV_NAME "unimac-mdio" + +#endif /* __MDIO_BCM_UNIMAC_PDATA_H */ diff --git a/include/linux/platform_data/mtd-davinci.h b/include/linux/platform_data/mtd-davinci.h index 1cf555aef896c39342bd7306c09cfa1358451fe6..f1a2cf655bdb5895c5b8ea1a66efbe5724b76629 100644 --- a/include/linux/platform_data/mtd-davinci.h +++ b/include/linux/platform_data/mtd-davinci.h @@ -28,7 +28,7 @@ #ifndef __ARCH_ARM_DAVINCI_NAND_H #define __ARCH_ARM_DAVINCI_NAND_H -#include +#include #define NANDFCR_OFFSET 0x60 #define NANDFSR_OFFSET 0x64 diff --git a/include/linux/platform_data/mtd-nand-s3c2410.h b/include/linux/platform_data/mtd-nand-s3c2410.h index f01659026b2681e7c141899097cedc582a58c447..f8c553f926558c6b83bffe995b33d7a2ddb2b106 100644 --- a/include/linux/platform_data/mtd-nand-s3c2410.h +++ b/include/linux/platform_data/mtd-nand-s3c2410.h @@ -12,7 +12,7 @@ #ifndef __MTD_NAND_S3C2410_H #define __MTD_NAND_S3C2410_H -#include +#include /** * struct s3c2410_nand_set - define a set of one or more nand chips diff --git a/include/linux/platform_data/omap_drm.h b/include/linux/platform_data/omap_drm.h deleted file mode 100644 index f4e4a237ebd2626afffd955768083029eff02d45..0000000000000000000000000000000000000000 --- a/include/linux/platform_data/omap_drm.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * DRM/KMS platform data for TI OMAP platforms - * - * Copyright (C) 2012 Texas Instruments - * Author: Rob Clark - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#ifndef __PLATFORM_DATA_OMAP_DRM_H__ -#define __PLATFORM_DATA_OMAP_DRM_H__ - -/* - * Optional platform data to configure the default configuration of which - * pipes/overlays/CRTCs are used.. if this is not provided, then instead the - * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to - * one manager, with priority given to managers that are connected to - * detected devices. Remaining overlays are used as video planes. This - * should be a good default behavior for most cases, but yet there still - * might be times when you wish to do something different. - */ -struct omap_kms_platform_data { - /* overlays to use as CRTCs: */ - int ovl_cnt; - const int *ovl_ids; - - /* overlays to use as video planes: */ - int pln_cnt; - const int *pln_ids; - - int mgr_cnt; - const int *mgr_ids; - - int dev_cnt; - const char **dev_names; -}; - -struct omap_drm_platform_data { - uint32_t omaprev; - struct omap_kms_platform_data *kms_pdata; -}; - -#endif /* __PLATFORM_DATA_OMAP_DRM_H__ */ diff --git a/include/linux/i2c/pca954x.h b/include/linux/platform_data/pca954x.h similarity index 100% rename from include/linux/i2c/pca954x.h rename to include/linux/platform_data/pca954x.h diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h index 79b0e4cdb8141a10e73affb9a837d5bcc5f00a2a..f8274b0c68880ccbd02de1a85ece46a3cab2053f 100644 --- a/include/linux/platform_data/st_sensors_pdata.h +++ b/include/linux/platform_data/st_sensors_pdata.h @@ -17,10 +17,12 @@ * Available only for accelerometer and pressure sensors. * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). * @open_drain: set the interrupt line to be open drain if possible. + * @spi_3wire: enable spi-3wire mode. */ struct st_sensors_platform_data { u8 drdy_int_pin; bool open_drain; + bool spi_3wire; }; #endif /* ST_SENSORS_PDATA_H */ diff --git a/include/linux/i2c/tc35876x.h b/include/linux/platform_data/tc35876x.h similarity index 100% rename from include/linux/i2c/tc35876x.h rename to include/linux/platform_data/tc35876x.h diff --git a/include/linux/platform_data/x86/apple.h b/include/linux/platform_data/x86/apple.h new file mode 100644 index 0000000000000000000000000000000000000000..079e816c3c219eb19819fda04c729a91578a890e --- /dev/null +++ b/include/linux/platform_data/x86/apple.h @@ -0,0 +1,13 @@ +#ifndef PLATFORM_DATA_X86_APPLE_H +#define PLATFORM_DATA_X86_APPLE_H + +#ifdef CONFIG_X86 +/** + * x86_apple_machine - whether the machine is an x86 Apple Macintosh + */ +extern bool x86_apple_machine; +#else +#define x86_apple_machine false +#endif + +#endif diff --git a/include/linux/i2c/mlxcpld.h b/include/linux/platform_data/x86/mlxcpld.h similarity index 100% rename from include/linux/i2c/mlxcpld.h rename to include/linux/platform_data/x86/mlxcpld.h diff --git a/include/linux/pm.h b/include/linux/pm.h index b8b4df09fd8f5ed3eb3ce5c0f47e4068ba702ca2..47ded8aa8a5d5a0b9ec83e0d362c037a26b03b1d 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -689,6 +689,8 @@ struct dev_pm_domain { extern void device_pm_lock(void); extern void dpm_resume_start(pm_message_t state); extern void dpm_resume_end(pm_message_t state); +extern void dpm_noirq_resume_devices(pm_message_t state); +extern void dpm_noirq_end(void); extern void dpm_resume_noirq(pm_message_t state); extern void dpm_resume_early(pm_message_t state); extern void dpm_resume(pm_message_t state); @@ -697,6 +699,8 @@ extern void dpm_complete(pm_message_t state); extern void device_pm_unlock(void); extern int dpm_suspend_end(pm_message_t state); extern int dpm_suspend_start(pm_message_t state); +extern void dpm_noirq_begin(void); +extern int dpm_noirq_suspend_devices(pm_message_t state); extern int dpm_suspend_noirq(pm_message_t state); extern int dpm_suspend_late(pm_message_t state); extern int dpm_suspend(pm_message_t state); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 41004d97cefae2d9c0565b343a85743788c5e9d3..84f423d5633ee996e7eb5dd87ed8d3024f41b886 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -43,6 +43,7 @@ struct genpd_power_state { s64 power_on_latency_ns; s64 residency_ns; struct fwnode_handle *fwnode; + ktime_t idle_time; }; struct genpd_lock_ops; @@ -78,6 +79,8 @@ struct generic_pm_domain { unsigned int state_count; /* number of states */ unsigned int state_idx; /* state that genpd will go to when off */ void *free; /* Free the state that was allocated for default */ + ktime_t on_time; + ktime_t accounting_time; const struct genpd_lock_ops *lock_ops; union { struct mutex mlock; diff --git a/include/linux/power/bq24190_charger.h b/include/linux/power/bq24190_charger.h new file mode 100644 index 0000000000000000000000000000000000000000..45ce7f116a91b83e05a70c066cc756ff23e8b044 --- /dev/null +++ b/include/linux/power/bq24190_charger.h @@ -0,0 +1,18 @@ +/* + * Platform data for the TI bq24190 battery charger driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _BQ24190_CHARGER_H_ +#define _BQ24190_CHARGER_H_ + +#include + +struct bq24190_platform_data { + const struct regulator_init_data *regulator_init_data; +}; + +#endif diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index 11e11685dd1d5c665028091445656c0b1492ea81..43194e02c1ee12f9df7d9b6d2e3f9992cf8ca893 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -6,6 +6,7 @@ enum bq27xxx_chip { BQ27010, /* bq27010, bq27210 */ BQ2750X, /* bq27500 deprecated alias */ BQ2751X, /* bq27510, bq27520 deprecated alias */ + BQ2752X, BQ27500, /* bq27500/1 */ BQ27510G1, /* bq27510G1 */ BQ27510G2, /* bq27510G2 */ @@ -15,26 +16,16 @@ enum bq27xxx_chip { BQ27520G3, /* bq27520G3 */ BQ27520G4, /* bq27520G4 */ BQ27530, /* bq27530, bq27531 */ + BQ27531, BQ27541, /* bq27541, bq27542, bq27546, bq27742 */ + BQ27542, + BQ27546, + BQ27742, BQ27545, /* bq27545 */ BQ27421, /* bq27421, bq27425, bq27441, bq27621 */ -}; - -/** - * struct bq27xxx_plaform_data - Platform data for bq27xxx devices - * @name: Name of the battery. - * @chip: Chip class number of this device. - * @read: HDQ read callback. - * This function should provide access to the HDQ bus the battery is - * connected to. - * The first parameter is a pointer to the battery device, the second the - * register to be read. The return value should either be the content of - * the passed register or an error value. - */ -struct bq27xxx_platform_data { - const char *name; - enum bq27xxx_chip chip; - int (*read)(struct device *dev, unsigned int); + BQ27425, + BQ27441, + BQ27621, }; struct bq27xxx_device_info; @@ -63,7 +54,7 @@ struct bq27xxx_device_info { struct device *dev; int id; enum bq27xxx_chip chip; - bool ram_chip; + u32 opts; const char *name; struct bq27xxx_dm_reg *dm_regs; u32 unseal_key; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index de89066b72b14c1f11aec42a4afc2eefffa817f7..79e90b3d32888fe6fd5e3abff958a346738d4ab2 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -332,6 +332,8 @@ extern int power_supply_get_battery_info(struct power_supply *psy, struct power_supply_battery_info *info); extern void power_supply_changed(struct power_supply *psy); extern int power_supply_am_i_supplied(struct power_supply *psy); +extern int power_supply_set_input_current_limit_from_supplier( + struct power_supply *psy); extern int power_supply_set_battery_charged(struct power_supply *psy); #ifdef CONFIG_POWER_SUPPLY diff --git a/include/linux/pps-gpio.h b/include/linux/pps-gpio.h index 0035abe41b9a4547f70a65c94f2477b11c320f30..56f35dd3d01d382820c18283500f4a6f725c854f 100644 --- a/include/linux/pps-gpio.h +++ b/include/linux/pps-gpio.h @@ -29,4 +29,4 @@ struct pps_gpio_platform_data { const char *gpio_label; }; -#endif +#endif /* _PPS_GPIO_H */ diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index 35ac903956c7c0c282a9b0cfd74004212c8eb10d..80a980cc8d95f174a120fbd1aece4bdf7e55315b 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h @@ -22,7 +22,6 @@ #define LINUX_PPS_KERNEL_H #include - #include #include #include @@ -35,9 +34,9 @@ struct pps_device; /* The specific PPS source info */ struct pps_source_info { - char name[PPS_MAX_NAME_LEN]; /* simbolic name */ + char name[PPS_MAX_NAME_LEN]; /* symbolic name */ char path[PPS_MAX_NAME_LEN]; /* path of connected device */ - int mode; /* PPS's allowed mode */ + int mode; /* PPS allowed mode */ void (*echo)(struct pps_device *pps, int event, void *data); /* PPS echo function */ @@ -57,10 +56,10 @@ struct pps_event_time { struct pps_device { struct pps_source_info info; /* PSS source info */ - struct pps_kparams params; /* PPS's current params */ + struct pps_kparams params; /* PPS current params */ - __u32 assert_sequence; /* PPS' assert event seq # */ - __u32 clear_sequence; /* PPS' clear event seq # */ + __u32 assert_sequence; /* PPS assert event seq # */ + __u32 clear_sequence; /* PPS clear event seq # */ struct pps_ktime assert_tu; struct pps_ktime clear_tu; int current_mode; /* PPS mode at event time */ @@ -69,7 +68,7 @@ struct pps_device { wait_queue_head_t queue; /* PPS event queue */ unsigned int id; /* PPS source unique ID */ - void const *lookup_cookie; /* pps_lookup_dev only */ + void const *lookup_cookie; /* For pps_lookup_dev() only */ struct cdev cdev; struct device *dev; struct fasync_struct *async_queue; /* fasync method */ @@ -101,7 +100,7 @@ extern struct pps_device *pps_register_source( extern void pps_unregister_source(struct pps_device *pps); extern void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, void *data); -/* Look up a pps device by magic cookie */ +/* Look up a pps_device by magic cookie */ struct pps_device *pps_lookup_dev(void const *cookie); static inline void timespec_to_pps_ktime(struct pps_ktime *kt, @@ -132,4 +131,3 @@ static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec64 delta } #endif /* LINUX_PPS_KERNEL_H */ - diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 2d2bf592d9db216f31093cdc01c0ef418d663af9..76124dd4e36d64e87d3bf9f816b6979a8c35e5c4 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -28,13 +28,7 @@ extern struct proc_dir_entry *proc_create_data(const char *, umode_t, const struct file_operations *, void *); -static inline struct proc_dir_entry *proc_create( - const char *name, umode_t mode, struct proc_dir_entry *parent, - const struct file_operations *proc_fops) -{ - return proc_create_data(name, mode, parent, proc_fops, NULL); -} - +struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops); extern void proc_set_size(struct proc_dir_entry *, loff_t); extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t); extern void *PDE_DATA(const struct inode *); diff --git a/include/linux/property.h b/include/linux/property.h index 7e77039e6b81814357493bf02f5a47b47a6f7e8e..6bebee13c5e0a944d8e473b05953bd15ed292149 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -51,46 +51,52 @@ int device_property_read_string(struct device *dev, const char *propname, int device_property_match_string(struct device *dev, const char *propname, const char *string); -bool fwnode_device_is_available(struct fwnode_handle *fwnode); -bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); -int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, +bool fwnode_device_is_available(const struct fwnode_handle *fwnode); +bool fwnode_property_present(const struct fwnode_handle *fwnode, + const char *propname); +int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode, const char *propname, u8 *val, size_t nval); -int fwnode_property_read_u16_array(struct fwnode_handle *fwnode, +int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode, const char *propname, u16 *val, size_t nval); -int fwnode_property_read_u32_array(struct fwnode_handle *fwnode, +int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode, const char *propname, u32 *val, size_t nval); -int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, +int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode, const char *propname, u64 *val, size_t nval); -int fwnode_property_read_string_array(struct fwnode_handle *fwnode, +int fwnode_property_read_string_array(const struct fwnode_handle *fwnode, const char *propname, const char **val, size_t nval); -int fwnode_property_read_string(struct fwnode_handle *fwnode, +int fwnode_property_read_string(const struct fwnode_handle *fwnode, const char *propname, const char **val); -int fwnode_property_match_string(struct fwnode_handle *fwnode, +int fwnode_property_match_string(const struct fwnode_handle *fwnode, const char *propname, const char *string); +int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, + const char *prop, const char *nargs_prop, + unsigned int nargs, unsigned int index, + struct fwnode_reference_args *args); -struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode); -struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode); -struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode, - struct fwnode_handle *child); +struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode); +struct fwnode_handle *fwnode_get_next_parent( + struct fwnode_handle *fwnode); +struct fwnode_handle *fwnode_get_next_child_node( + const struct fwnode_handle *fwnode, struct fwnode_handle *child); #define fwnode_for_each_child_node(fwnode, child) \ for (child = fwnode_get_next_child_node(fwnode, NULL); child; \ child = fwnode_get_next_child_node(fwnode, child)) -struct fwnode_handle *device_get_next_child_node(struct device *dev, - struct fwnode_handle *child); +struct fwnode_handle *device_get_next_child_node( + struct device *dev, struct fwnode_handle *child); #define device_for_each_child_node(dev, child) \ for (child = device_get_next_child_node(dev, NULL); child; \ child = device_get_next_child_node(dev, child)) -struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode, - const char *childname); +struct fwnode_handle *fwnode_get_named_child_node( + const struct fwnode_handle *fwnode, const char *childname); struct fwnode_handle *device_get_named_child_node(struct device *dev, const char *childname); @@ -129,31 +135,31 @@ static inline int device_property_read_u64(struct device *dev, return device_property_read_u64_array(dev, propname, val, 1); } -static inline bool fwnode_property_read_bool(struct fwnode_handle *fwnode, +static inline bool fwnode_property_read_bool(const struct fwnode_handle *fwnode, const char *propname) { return fwnode_property_present(fwnode, propname); } -static inline int fwnode_property_read_u8(struct fwnode_handle *fwnode, +static inline int fwnode_property_read_u8(const struct fwnode_handle *fwnode, const char *propname, u8 *val) { return fwnode_property_read_u8_array(fwnode, propname, val, 1); } -static inline int fwnode_property_read_u16(struct fwnode_handle *fwnode, +static inline int fwnode_property_read_u16(const struct fwnode_handle *fwnode, const char *propname, u16 *val) { return fwnode_property_read_u16_array(fwnode, propname, val, 1); } -static inline int fwnode_property_read_u32(struct fwnode_handle *fwnode, +static inline int fwnode_property_read_u32(const struct fwnode_handle *fwnode, const char *propname, u32 *val) { return fwnode_property_read_u32_array(fwnode, propname, val, 1); } -static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode, +static inline int fwnode_property_read_u64(const struct fwnode_handle *fwnode, const char *propname, u64 *val) { return fwnode_property_read_u64_array(fwnode, propname, val, 1); @@ -274,19 +280,20 @@ int device_get_phy_mode(struct device *dev); void *device_get_mac_address(struct device *dev, char *addr, int alen); struct fwnode_handle *fwnode_graph_get_next_endpoint( - struct fwnode_handle *fwnode, struct fwnode_handle *prev); + const struct fwnode_handle *fwnode, struct fwnode_handle *prev); struct fwnode_handle * -fwnode_graph_get_port_parent(struct fwnode_handle *fwnode); +fwnode_graph_get_port_parent(const struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_port_parent( - struct fwnode_handle *fwnode); + const struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_port( - struct fwnode_handle *fwnode); + const struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_endpoint( - struct fwnode_handle *fwnode); -struct fwnode_handle *fwnode_graph_get_remote_node(struct fwnode_handle *fwnode, - u32 port, u32 endpoint); + const struct fwnode_handle *fwnode); +struct fwnode_handle * +fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port, + u32 endpoint); -int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode, +int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint); #endif /* _LINUX_PROPERTY_H_ */ diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index a026bfd089db81191b5a322979d4bf58c2777dc5..51349d124ee5d47ded05a433028d765858c61f00 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -99,6 +99,11 @@ struct system_device_crosststamp; * parameter func: the desired function to use. * parameter chan: the function channel index to use. * + * @do_work: Request driver to perform auxiliary (periodic) operations + * Driver should return delay of the next auxiliary work scheduling + * time (>=0) or negative value in case further scheduling + * is not required. + * * Drivers should embed their ptp_clock_info within a private * structure, obtaining a reference to it using container_of(). * @@ -126,6 +131,7 @@ struct ptp_clock_info { struct ptp_clock_request *request, int on); int (*verify)(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan); + long (*do_aux_work)(struct ptp_clock_info *ptp); }; struct ptp_clock; @@ -211,6 +217,16 @@ extern int ptp_clock_index(struct ptp_clock *ptp); int ptp_find_pin(struct ptp_clock *ptp, enum ptp_pin_function func, unsigned int chan); +/** + * ptp_schedule_worker() - schedule ptp auxiliary work + * + * @ptp: The clock obtained from ptp_clock_register(). + * @delay: number of jiffies to wait before queuing + * See kthread_queue_delayed_work() for more info. + */ + +int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay); + #else static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent) @@ -225,6 +241,10 @@ static inline int ptp_clock_index(struct ptp_clock *ptp) static inline int ptp_find_pin(struct ptp_clock *ptp, enum ptp_pin_function func, unsigned int chan) { return -1; } +static inline int ptp_schedule_worker(struct ptp_clock *ptp, + unsigned long delay) +{ return -EOPNOTSUPP; } + #endif #endif diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h index d8c97ec8a8e66d865f516f708a5b3f8fe567da29..37b4bb2545b32dc82633df6b76e629b9999f900b 100644 --- a/include/linux/ptr_ring.h +++ b/include/linux/ptr_ring.h @@ -436,9 +436,9 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r, __PTR_RING_PEEK_CALL_v; \ }) -static inline void **__ptr_ring_init_queue_alloc(int size, gfp_t gfp) +static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp) { - return kzalloc(ALIGN(size * sizeof(void *), SMP_CACHE_BYTES), gfp); + return kcalloc(size, sizeof(void *), gfp); } static inline void __ptr_ring_set_size(struct ptr_ring *r, int size) @@ -582,7 +582,8 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp, * In particular if you consume ring in interrupt or BH context, you must * disable interrupts/BH when doing so. */ -static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings, +static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, + unsigned int nrings, int size, gfp_t gfp, void (*destroy)(void *)) { @@ -590,7 +591,7 @@ static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings, void ***queues; int i; - queues = kmalloc(nrings * sizeof *queues, gfp); + queues = kmalloc_array(nrings, sizeof(*queues), gfp); if (!queues) goto noqueues; diff --git a/include/linux/qed/qed_eth_if.h b/include/linux/qed/qed_eth_if.h index 0eef0a2b1901e6ba672a63a37c9242d4d6ee8b44..d60de4a39810650709d37d5b1404831ad5f730d7 100644 --- a/include/linux/qed/qed_eth_if.h +++ b/include/linux/qed/qed_eth_if.h @@ -323,6 +323,7 @@ struct qed_eth_ops { int (*configure_arfs_searcher)(struct qed_dev *cdev, bool en_searcher); + int (*get_coalesce)(struct qed_dev *cdev, u16 *coal, void *handle); }; const struct qed_eth_ops *qed_get_eth_ops(void); diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index ef39c7f40ae6f67ea54ce0f735d20c3ed7790d55..cc646ca979747e51d13d6992b40be572b61743ba 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -161,6 +161,18 @@ enum qed_nvm_images { QED_NVM_IMAGE_FCOE_CFG, }; +struct qed_link_eee_params { + u32 tx_lpi_timer; +#define QED_EEE_1G_ADV BIT(0) +#define QED_EEE_10G_ADV BIT(1) + + /* Capabilities are represented using QED_EEE_*_ADV values */ + u8 adv_caps; + u8 lp_adv_caps; + bool enable; + bool tx_lpi_enable; +}; + enum qed_led_mode { QED_LED_MODE_OFF, QED_LED_MODE_ON, @@ -172,8 +184,9 @@ enum qed_led_mode { #define DIRECT_REG_RD(reg_addr) readl((void __iomem *)(reg_addr)) -#define QED_COALESCE_MAX 0xFF +#define QED_COALESCE_MAX 0x1FF #define QED_DEFAULT_RX_USECS 12 +#define QED_DEFAULT_TX_USECS 48 /* forward */ struct qed_dev; @@ -408,6 +421,7 @@ struct qed_link_params { #define QED_LINK_OVERRIDE_SPEED_FORCED_SPEED BIT(2) #define QED_LINK_OVERRIDE_PAUSE_CONFIG BIT(3) #define QED_LINK_OVERRIDE_LOOPBACK_MODE BIT(4) +#define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5) u32 override_flags; bool autoneg; u32 adv_speeds; @@ -422,6 +436,7 @@ struct qed_link_params { #define QED_LINK_LOOPBACK_EXT BIT(3) #define QED_LINK_LOOPBACK_MAC BIT(4) u32 loopback_mode; + struct qed_link_eee_params eee; }; struct qed_link_output { @@ -437,6 +452,12 @@ struct qed_link_output { u8 port; /* In PORT defs */ bool autoneg; u32 pause_config; + + /* EEE - capability & param */ + bool eee_supported; + bool eee_active; + u8 sup_caps; + struct qed_link_eee_params eee; }; struct qed_probe_params { @@ -653,16 +674,6 @@ struct qed_common_ops { int (*nvm_get_image)(struct qed_dev *cdev, enum qed_nvm_images type, u8 *buf, u16 len); -/** - * @brief get_coalesce - Get coalesce parameters in usec - * - * @param cdev - * @param rx_coal - Rx coalesce value in usec - * @param tx_coal - Tx coalesce value in usec - * - */ - void (*get_coalesce)(struct qed_dev *cdev, u16 *rx_coal, u16 *tx_coal); - /** * @brief set_coalesce - Configure Rx coalesce value in usec * @@ -674,8 +685,8 @@ struct qed_common_ops { * * @return 0 on success, error otherwise. */ - int (*set_coalesce)(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal, - u16 qid, u16 sb_id); + int (*set_coalesce)(struct qed_dev *cdev, + u16 rx_coal, u16 tx_coal, void *handle); /** * @brief set_led - Configure LED mode diff --git a/include/linux/quota.h b/include/linux/quota.h index bfd077ca6ac3d642026267fa73ce2432126f8aef..5ac9de4fcd6fcad1ea0baae2a9979e4de264560f 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -223,12 +223,12 @@ struct mem_dqinfo { struct quota_format_type *dqi_format; int dqi_fmt_id; /* Id of the dqi_format - used when turning * quotas on after remount RW */ - struct list_head dqi_dirty_list; /* List of dirty dquots */ - unsigned long dqi_flags; - unsigned int dqi_bgrace; - unsigned int dqi_igrace; - qsize_t dqi_max_spc_limit; - qsize_t dqi_max_ino_limit; + struct list_head dqi_dirty_list; /* List of dirty dquots [dq_list_lock] */ + unsigned long dqi_flags; /* DFQ_ flags [dq_data_lock] */ + unsigned int dqi_bgrace; /* Space grace time [dq_data_lock] */ + unsigned int dqi_igrace; /* Inode grace time [dq_data_lock] */ + qsize_t dqi_max_spc_limit; /* Maximum space limit [static] */ + qsize_t dqi_max_ino_limit; /* Maximum inode limit [static] */ void *dqi_priv; }; @@ -293,18 +293,18 @@ static inline void dqstats_dec(unsigned int type) * clear them when it sees fit. */ struct dquot { - struct hlist_node dq_hash; /* Hash list in memory */ - struct list_head dq_inuse; /* List of all quotas */ - struct list_head dq_free; /* Free list element */ - struct list_head dq_dirty; /* List of dirty dquots */ + struct hlist_node dq_hash; /* Hash list in memory [dq_list_lock] */ + struct list_head dq_inuse; /* List of all quotas [dq_list_lock] */ + struct list_head dq_free; /* Free list element [dq_list_lock] */ + struct list_head dq_dirty; /* List of dirty dquots [dq_list_lock] */ struct mutex dq_lock; /* dquot IO lock */ + spinlock_t dq_dqb_lock; /* Lock protecting dq_dqb changes */ atomic_t dq_count; /* Use count */ - wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ struct super_block *dq_sb; /* superblock this applies to */ struct kqid dq_id; /* ID this applies to (uid, gid, projid) */ - loff_t dq_off; /* Offset of dquot on disk */ + loff_t dq_off; /* Offset of dquot on disk [dq_lock, stable once set] */ unsigned long dq_flags; /* See DQ_* */ - struct mem_dqblk dq_dqb; /* Diskquota usage */ + struct mem_dqblk dq_dqb; /* Diskquota usage [dq_dqb_lock] */ }; /* Operations which must be implemented by each quota format */ @@ -491,6 +491,9 @@ enum { */ #define DQUOT_NEGATIVE_USAGE (1 << (DQUOT_STATE_LAST + 1)) /* Allow negative quota usage */ +/* Do not track dirty dquots in a list */ +#define DQUOT_NOLIST_DIRTY (1 << (DQUOT_STATE_LAST + 2)) + static inline unsigned int dquot_state_flag(unsigned int flags, int type) { return flags << type; @@ -521,7 +524,7 @@ static inline void quota_send_warning(struct kqid qid, dev_t dev, struct quota_info { unsigned int flags; /* Flags for diskquotas on this device */ - struct mutex dqio_mutex; /* lock device while I/O in progress */ + struct rw_semaphore dqio_sem; /* Lock quota file while I/O in progress */ struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index dda22f45fc1b2361b9b7c79d5fa39a98f09952be..0ce6fc49962e1bed7dd50ed8b3e10b7dd74207b8 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -38,11 +38,6 @@ void __quota_error(struct super_block *sb, const char *func, /* * declaration of quota_function calls in kernel. */ -void inode_add_rsv_space(struct inode *inode, qsize_t number); -void inode_claim_rsv_space(struct inode *inode, qsize_t number); -void inode_sub_rsv_space(struct inode *inode, qsize_t number); -void inode_reclaim_rsv_space(struct inode *inode, qsize_t number); - int dquot_initialize(struct inode *inode); bool dquot_initialize_needed(struct inode *inode); void dquot_drop(struct inode *inode); diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 3e5735064b7166837e7eae615a4cde2d3a9cd727..567ebb5eaab01f767f7e091a019a85ffd5d2fe73 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -357,8 +357,25 @@ int radix_tree_split(struct radix_tree_root *, unsigned long index, unsigned new_order); int radix_tree_join(struct radix_tree_root *, unsigned long index, unsigned new_order, void *); -void __rcu **idr_get_free(struct radix_tree_root *, struct radix_tree_iter *, - gfp_t, int end); + +void __rcu **idr_get_free_cmn(struct radix_tree_root *root, + struct radix_tree_iter *iter, gfp_t gfp, + unsigned long max); +static inline void __rcu **idr_get_free(struct radix_tree_root *root, + struct radix_tree_iter *iter, + gfp_t gfp, + int end) +{ + return idr_get_free_cmn(root, iter, gfp, end > 0 ? end - 1 : INT_MAX); +} + +static inline void __rcu **idr_get_free_ext(struct radix_tree_root *root, + struct radix_tree_iter *iter, + gfp_t gfp, + unsigned long end) +{ + return idr_get_free_cmn(root, iter, gfp, end - 1); +} enum { RADIX_TREE_ITER_TAG_MASK = 0x0f, /* tag index in lower nybble */ diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h index 30f945329818b53e41b890ba3e8f5452e2b89094..583cdd3d49ca8f01657fbec641a4b7984eac0e11 100644 --- a/include/linux/raid/pq.h +++ b/include/linux/raid/pq.h @@ -121,6 +121,7 @@ extern const struct raid6_recov_calls raid6_recov_ssse3; extern const struct raid6_recov_calls raid6_recov_avx2; extern const struct raid6_recov_calls raid6_recov_avx512; extern const struct raid6_recov_calls raid6_recov_s390xc; +extern const struct raid6_recov_calls raid6_recov_neon; extern const struct raid6_calls raid6_neonx1; extern const struct raid6_calls raid6_neonx2; diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index e585018498d594f7c12abe6d3935f321009b3cd8..d574361943ea832532cf93177e97a8c62d6c3430 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -44,10 +44,25 @@ struct rb_root { struct rb_node *rb_node; }; +/* + * Leftmost-cached rbtrees. + * + * We do not cache the rightmost node based on footprint + * size vs number of potential users that could benefit + * from O(1) rb_last(). Just not worth it, users that want + * this feature can always implement the logic explicitly. + * Furthermore, users that want to cache both pointers may + * find it a bit asymmetric, but that's ok. + */ +struct rb_root_cached { + struct rb_root rb_root; + struct rb_node *rb_leftmost; +}; #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) #define RB_ROOT (struct rb_root) { NULL, } +#define RB_ROOT_CACHED (struct rb_root_cached) { {NULL, }, NULL } #define rb_entry(ptr, type, member) container_of(ptr, type, member) #define RB_EMPTY_ROOT(root) (READ_ONCE((root)->rb_node) == NULL) @@ -69,6 +84,12 @@ extern struct rb_node *rb_prev(const struct rb_node *); extern struct rb_node *rb_first(const struct rb_root *); extern struct rb_node *rb_last(const struct rb_root *); +extern void rb_insert_color_cached(struct rb_node *, + struct rb_root_cached *, bool); +extern void rb_erase_cached(struct rb_node *node, struct rb_root_cached *); +/* Same as rb_first(), but O(1) */ +#define rb_first_cached(root) (root)->rb_leftmost + /* Postorder iteration - always visit the parent after its children */ extern struct rb_node *rb_first_postorder(const struct rb_root *); extern struct rb_node *rb_next_postorder(const struct rb_node *); diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index 9702b6e183bc6ab2432573170e1b43db4ff19288..6bfd2b581f75a464e13d3d749ebe5d639a32551f 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h @@ -41,7 +41,9 @@ struct rb_augment_callbacks { void (*rotate)(struct rb_node *old, struct rb_node *new); }; -extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, +extern void __rb_insert_augmented(struct rb_node *node, + struct rb_root *root, + bool newleft, struct rb_node **leftmost, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); /* * Fixup the rbtree and update the augmented information when rebalancing. @@ -57,7 +59,16 @@ static inline void rb_insert_augmented(struct rb_node *node, struct rb_root *root, const struct rb_augment_callbacks *augment) { - __rb_insert_augmented(node, root, augment->rotate); + __rb_insert_augmented(node, root, false, NULL, augment->rotate); +} + +static inline void +rb_insert_augmented_cached(struct rb_node *node, + struct rb_root_cached *root, bool newleft, + const struct rb_augment_callbacks *augment) +{ + __rb_insert_augmented(node, &root->rb_root, + newleft, &root->rb_leftmost, augment->rotate); } #define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \ @@ -150,6 +161,7 @@ extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, static __always_inline struct rb_node * __rb_erase_augmented(struct rb_node *node, struct rb_root *root, + struct rb_node **leftmost, const struct rb_augment_callbacks *augment) { struct rb_node *child = node->rb_right; @@ -157,6 +169,9 @@ __rb_erase_augmented(struct rb_node *node, struct rb_root *root, struct rb_node *parent, *rebalance; unsigned long pc; + if (leftmost && node == *leftmost) + *leftmost = rb_next(node); + if (!tmp) { /* * Case 1: node to erase has no more than 1 child (easy!) @@ -256,9 +271,21 @@ static __always_inline void rb_erase_augmented(struct rb_node *node, struct rb_root *root, const struct rb_augment_callbacks *augment) { - struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); + struct rb_node *rebalance = __rb_erase_augmented(node, root, + NULL, augment); if (rebalance) __rb_erase_color(rebalance, root, augment->rotate); } +static __always_inline void +rb_erase_augmented_cached(struct rb_node *node, struct rb_root_cached *root, + const struct rb_augment_callbacks *augment) +{ + struct rb_node *rebalance = __rb_erase_augmented(node, &root->rb_root, + &root->rb_leftmost, + augment); + if (rebalance) + __rb_erase_color(rebalance, &root->rb_root, augment->rotate); +} + #endif /* _LINUX_RBTREE_AUGMENTED_H */ diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index f816fc72b51eeda73bf55f7d7176b25cdb27f110..de50d8a4cf414121a9f83e50df7738a5f530494a 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -58,8 +58,6 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func); void call_rcu_bh(struct rcu_head *head, rcu_callback_t func); void call_rcu_sched(struct rcu_head *head, rcu_callback_t func); void synchronize_sched(void); -void call_rcu_tasks(struct rcu_head *head, rcu_callback_t func); -void synchronize_rcu_tasks(void); void rcu_barrier_tasks(void); #ifdef CONFIG_PREEMPT_RCU @@ -105,11 +103,13 @@ static inline int rcu_preempt_depth(void) /* Internal to kernel */ void rcu_init(void); +extern int rcu_scheduler_active __read_mostly; void rcu_sched_qs(void); void rcu_bh_qs(void); void rcu_check_callbacks(int user); void rcu_report_dead(unsigned int cpu); void rcu_cpu_starting(unsigned int cpu); +void rcutree_migrate_callbacks(int cpu); #ifdef CONFIG_RCU_STALL_COMMON void rcu_sysrq_start(void); @@ -164,8 +164,6 @@ static inline void rcu_init_nohz(void) { } * macro rather than an inline function to avoid #include hell. */ #ifdef CONFIG_TASKS_RCU -#define TASKS_RCU(x) x -extern struct srcu_struct tasks_rcu_exit_srcu; #define rcu_note_voluntary_context_switch_lite(t) \ do { \ if (READ_ONCE((t)->rcu_tasks_holdout)) \ @@ -176,10 +174,17 @@ extern struct srcu_struct tasks_rcu_exit_srcu; rcu_all_qs(); \ rcu_note_voluntary_context_switch_lite(t); \ } while (0) +void call_rcu_tasks(struct rcu_head *head, rcu_callback_t func); +void synchronize_rcu_tasks(void); +void exit_tasks_rcu_start(void); +void exit_tasks_rcu_finish(void); #else /* #ifdef CONFIG_TASKS_RCU */ -#define TASKS_RCU(x) do { } while (0) #define rcu_note_voluntary_context_switch_lite(t) do { } while (0) #define rcu_note_voluntary_context_switch(t) rcu_all_qs() +#define call_rcu_tasks call_rcu_sched +#define synchronize_rcu_tasks synchronize_sched +static inline void exit_tasks_rcu_start(void) { } +static inline void exit_tasks_rcu_finish(void) { } #endif /* #else #ifdef CONFIG_TASKS_RCU */ /** @@ -407,6 +412,22 @@ static inline void rcu_preempt_sleep_check(void) { } _r_a_p__v; \ }) +/** + * rcu_swap_protected() - swap an RCU and a regular pointer + * @rcu_ptr: RCU pointer + * @ptr: regular pointer + * @c: the conditions under which the dereference will take place + * + * Perform swap(@rcu_ptr, @ptr) where @rcu_ptr is an RCU-annotated pointer and + * @c is the argument that is passed to the rcu_dereference_protected() call + * used to read that pointer. + */ +#define rcu_swap_protected(rcu_ptr, ptr, c) do { \ + typeof(ptr) __tmp = rcu_dereference_protected((rcu_ptr), (c)); \ + rcu_assign_pointer((rcu_ptr), (ptr)); \ + (ptr) = __tmp; \ +} while (0) + /** * rcu_access_pointer() - fetch RCU pointer with no dereferencing * @p: The pointer to read diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index 5becbbccb998076e94d353485b1c6239140846f5..b3dbf9502fd0fa54ff39d4dcba0a74cc46724538 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h @@ -116,13 +116,11 @@ static inline void rcu_irq_exit_irqson(void) { } static inline void rcu_irq_enter_irqson(void) { } static inline void rcu_irq_exit(void) { } static inline void exit_rcu(void) { } - -#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) -extern int rcu_scheduler_active __read_mostly; +#ifdef CONFIG_SRCU void rcu_scheduler_starting(void); -#else /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) */ +#else /* #ifndef CONFIG_SRCU */ static inline void rcu_scheduler_starting(void) { } -#endif /* #else #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) */ +#endif /* #else #ifndef CONFIG_SRCU */ static inline void rcu_end_inkernel_boot(void) { } static inline bool rcu_is_watching(void) { return true; } diff --git a/include/linux/refcount.h b/include/linux/refcount.h index 591792c8e5b0cc12be5806aa349d6a373f41cde4..48b7c9c68c4dee8a523d12f3b76edf34e554a0a8 100644 --- a/include/linux/refcount.h +++ b/include/linux/refcount.h @@ -53,6 +53,9 @@ extern __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r); extern __must_check bool refcount_dec_and_test(refcount_t *r); extern void refcount_dec(refcount_t *r); #else +# ifdef CONFIG_ARCH_HAS_REFCOUNT +# include +# else static inline __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r) { return atomic_add_unless(&r->refs, i, 0); @@ -87,6 +90,7 @@ static inline void refcount_dec(refcount_t *r) { atomic_dec(&r->refs); } +# endif /* !CONFIG_ARCH_HAS_REFCOUNT */ #endif /* CONFIG_REFCOUNT_FULL */ extern __must_check bool refcount_dec_if_one(refcount_t *r); diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/include/linux/regulator/mt6380-regulator.h similarity index 52% rename from arch/arm/boot/dts/mt7623-evb.dts rename to include/linux/regulator/mt6380-regulator.h index b60b41cad592e66655b9ee5127f4e0174a86aa65..465182da6315fda0bdbf6930c3a56d79757656ae 100644 --- a/arch/arm/boot/dts/mt7623-evb.dts +++ b/include/linux/regulator/mt6380-regulator.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016 MediaTek Inc. - * Author: John Crispin + * Copyright (c) 2017 MediaTek Inc. + * Author: Chenglin Xu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,22 +12,21 @@ * GNU General Public License for more details. */ -/dts-v1/; -#include "mt7623.dtsi" +#ifndef __LINUX_REGULATOR_mt6380_H +#define __LINUX_REGULATOR_mt6380_H -/ { - model = "MediaTek MT7623 evaluation board"; - compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; - - chosen { - stdout-path = &uart2; - }; - - memory { - reg = <0 0x80000000 0 0x40000000>; - }; +enum { + MT6380_ID_VCPU = 0, + MT6380_ID_VCORE, + MT6380_ID_VRF, + MT6380_ID_VMLDO, + MT6380_ID_VALDO, + MT6380_ID_VPHYLDO, + MT6380_ID_VDDRLDO, + MT6380_ID_VTLDO, + MT6380_ID_RG_MAX, }; -&uart2 { - status = "okay"; -}; +#define MT6380_MAX_REGULATOR MT6380_ID_RG_MAX + +#endif /* __LINUX_REGULATOR_mt6380_H */ diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 81da49564ff4236b86618187b0f0be5d2f81bea9..44e630eb3d9443c94f8d215ca47ceb77a5b04054 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -510,6 +510,8 @@ struct rproc_vdev { }; struct rproc *rproc_get_by_phandle(phandle phandle); +struct rproc *rproc_get_by_child(struct device *dev); + struct rproc *rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops, const char *firmware, int len); diff --git a/include/linux/remoteproc/qcom_rproc.h b/include/linux/remoteproc/qcom_rproc.h new file mode 100644 index 0000000000000000000000000000000000000000..fa8e38681b4b773a037905dc05224c56f80676c2 --- /dev/null +++ b/include/linux/remoteproc/qcom_rproc.h @@ -0,0 +1,22 @@ +#ifndef __QCOM_RPROC_H__ +#define __QCOM_RPROC_H__ + +struct notifier_block; + +#if IS_ENABLED(CONFIG_QCOM_RPROC_COMMON) + +int qcom_register_ssr_notifier(struct notifier_block *nb); +void qcom_unregister_ssr_notifier(struct notifier_block *nb); + +#else + +static inline int qcom_register_ssr_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline void qcom_unregister_ssr_notifier(struct notifier_block *nb) {} + +#endif + +#endif diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 156cfd330b6675c79780418e53cd0057410556ec..21fc84d82d41572db2216c4baf07b32c45044ff8 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -254,6 +254,9 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, unsigned *pshared_count, struct dma_fence ***pshared); +int reservation_object_copy_fences(struct reservation_object *dst, + struct reservation_object *src); + long reservation_object_wait_timeout_rcu(struct reservation_object *obj, bool wait_all, bool intr, unsigned long timeout); diff --git a/include/linux/reset.h b/include/linux/reset.h index 13d8681210d545ab2dcedb472fa127b408446eae..56463f37f3e67ec03e0f594a331bf62eb2d70722 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -25,6 +25,11 @@ struct reset_control *__devm_reset_control_get(struct device *dev, int __must_check device_reset(struct device *dev); +struct reset_control *devm_reset_control_array_get(struct device *dev, + bool shared, bool optional); +struct reset_control *of_reset_control_array_get(struct device_node *np, + bool shared, bool optional); + static inline int device_reset_optional(struct device *dev) { return device_reset(dev); @@ -89,6 +94,18 @@ static inline struct reset_control *__devm_reset_control_get( return optional ? NULL : ERR_PTR(-ENOTSUPP); } +static inline struct reset_control * +devm_reset_control_array_get(struct device *dev, bool shared, bool optional) +{ + return optional ? NULL : ERR_PTR(-ENOTSUPP); +} + +static inline struct reset_control * +of_reset_control_array_get(struct device_node *np, bool shared, bool optional) +{ + return optional ? NULL : ERR_PTR(-ENOTSUPP); +} + #endif /* CONFIG_RESET_CONTROLLER */ /** @@ -374,4 +391,55 @@ static inline struct reset_control *devm_reset_control_get_by_index( { return devm_reset_control_get_exclusive_by_index(dev, index); } + +/* + * APIs to manage a list of reset controllers + */ +static inline struct reset_control * +devm_reset_control_array_get_exclusive(struct device *dev) +{ + return devm_reset_control_array_get(dev, false, false); +} + +static inline struct reset_control * +devm_reset_control_array_get_shared(struct device *dev) +{ + return devm_reset_control_array_get(dev, true, false); +} + +static inline struct reset_control * +devm_reset_control_array_get_optional_exclusive(struct device *dev) +{ + return devm_reset_control_array_get(dev, false, true); +} + +static inline struct reset_control * +devm_reset_control_array_get_optional_shared(struct device *dev) +{ + return devm_reset_control_array_get(dev, true, true); +} + +static inline struct reset_control * +of_reset_control_array_get_exclusive(struct device_node *node) +{ + return of_reset_control_array_get(node, false, false); +} + +static inline struct reset_control * +of_reset_control_array_get_shared(struct device_node *node) +{ + return of_reset_control_array_get(node, true, false); +} + +static inline struct reset_control * +of_reset_control_array_get_optional_exclusive(struct device_node *node) +{ + return of_reset_control_array_get(node, false, true); +} + +static inline struct reset_control * +of_reset_control_array_get_optional_shared(struct device_node *node) +{ + return of_reset_control_array_get(node, true, true); +} #endif diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 7d56a7ea2b2e8cdcf471da6aaa6ac0be3c51acaa..361c08e35dbc388f0acd2891706d4df8f33026b6 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -127,7 +127,7 @@ struct rhashtable; * @head_offset: Offset of rhash_head in struct to be hashed * @max_size: Maximum size while expanding * @min_size: Minimum size while shrinking - * @locks_mul: Number of bucket locks to allocate per cpu (default: 128) + * @locks_mul: Number of bucket locks to allocate per cpu (default: 32) * @automatic_shrinking: Enable automatic shrinking of tables * @nulls_base: Base value to generate nulls marker * @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash) diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 43ef2c30cb0f59f83c05d23eea4a8aad87edefd1..733d3d8181e22fc2a7effe78add0f22acc3c147c 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -55,7 +55,9 @@ struct anon_vma { * is serialized by a system wide lock only visible to * mm_take_all_locks() (mm_all_locks_mutex). */ - struct rb_root rb_root; /* Interval tree of private "related" vmas */ + + /* Interval tree of private "related" vmas */ + struct rb_root_cached rb_root; }; /* @@ -93,8 +95,9 @@ enum ttu_flags { TTU_BATCH_FLUSH = 0x40, /* Batch TLB flushes where possible * and caller guarantees they will * do a final flush if necessary */ - TTU_RMAP_LOCKED = 0x80 /* do not grab rmap lock: + TTU_RMAP_LOCKED = 0x80, /* do not grab rmap lock: * caller holds it */ + TTU_SPLIT_FREEZE = 0x100, /* freeze pte under splitting thp */ }; #ifdef CONFIG_MMU diff --git a/include/linux/rpmsg/qcom_glink.h b/include/linux/rpmsg/qcom_glink.h new file mode 100644 index 0000000000000000000000000000000000000000..a622f029836ea0d1a9ed6fc3982df95324af8986 --- /dev/null +++ b/include/linux/rpmsg/qcom_glink.h @@ -0,0 +1,27 @@ +#ifndef _LINUX_RPMSG_QCOM_GLINK_H +#define _LINUX_RPMSG_QCOM_GLINK_H + +#include + +struct qcom_glink; + +#if IS_ENABLED(CONFIG_RPMSG_QCOM_GLINK_SMEM) + +struct qcom_glink *qcom_glink_smem_register(struct device *parent, + struct device_node *node); +void qcom_glink_smem_unregister(struct qcom_glink *glink); + +#else + +static inline struct qcom_glink * +qcom_glink_smem_register(struct device *parent, + struct device_node *node) +{ + return NULL; +} + +static inline void qcom_glink_smem_unregister(struct qcom_glink *glink) {} + +#endif + +#endif diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 0a0f0d14a5fba5582ab8c86ba1dc3a726b9881a0..e6d0f9c1cafd818285e691e40fc156cedb51639a 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -72,8 +72,6 @@ extern struct class *rtc_class; * issued through ioctl() ... */ struct rtc_class_ops { - int (*open)(struct device *); - void (*release)(struct device *); int (*ioctl)(struct device *, unsigned int, unsigned long); int (*read_time)(struct device *, struct rtc_time *); int (*set_time)(struct device *, struct rtc_time *); diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index 44fd002f7cd54472176c9a920ce43645c8ff641c..53fcbe9de7fd11bd18b9cdd8ce406588f3297410 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -22,18 +22,17 @@ extern int max_lock_depth; /* for sysctl */ * The rt_mutex structure * * @wait_lock: spinlock to protect the structure - * @waiters: rbtree root to enqueue waiters in priority order - * @waiters_leftmost: top waiter + * @waiters: rbtree root to enqueue waiters in priority order; + * caches top-waiter (leftmost node). * @owner: the mutex owner */ struct rt_mutex { raw_spinlock_t wait_lock; - struct rb_root waiters; - struct rb_node *waiters_leftmost; + struct rb_root_cached waiters; struct task_struct *owner; #ifdef CONFIG_DEBUG_RT_MUTEXES int save_state; - const char *name, *file; + const char *name, *file; int line; void *magic; #endif @@ -84,7 +83,7 @@ do { \ #define __RT_MUTEX_INITIALIZER(mutexname) \ { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .waiters = RB_ROOT \ + , .waiters = RB_ROOT_CACHED \ , .owner = NULL \ __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \ __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)} diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h index ae0528b834cd33acf5c22559778581b4f4f9b37b..e784761a4443b68430052d70832972ce2c002be5 100644 --- a/include/linux/rwsem-spinlock.h +++ b/include/linux/rwsem-spinlock.h @@ -32,6 +32,7 @@ struct rw_semaphore { #define RWSEM_UNLOCKED_VALUE 0x00000000 extern void __down_read(struct rw_semaphore *sem); +extern int __must_check __down_read_killable(struct rw_semaphore *sem); extern int __down_read_trylock(struct rw_semaphore *sem); extern void __down_write(struct rw_semaphore *sem); extern int __must_check __down_write_killable(struct rw_semaphore *sem); diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index dd1d142503404da2775808630bda2021a597229e..0ad7318ff2994a316a9a6a1a0ac1f1daf6152fb0 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -44,6 +44,7 @@ struct rw_semaphore { }; extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); +extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_down_write_failed_killable(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *); diff --git a/include/linux/sched.h b/include/linux/sched.h index 8337e2db0bb2e71473f94c283c5e51639ddd8dc8..26a7df4e558c249c40b979ead73425989f8e8c7f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -65,25 +65,23 @@ struct task_group; */ /* Used in tsk->state: */ -#define TASK_RUNNING 0 -#define TASK_INTERRUPTIBLE 1 -#define TASK_UNINTERRUPTIBLE 2 -#define __TASK_STOPPED 4 -#define __TASK_TRACED 8 +#define TASK_RUNNING 0x0000 +#define TASK_INTERRUPTIBLE 0x0001 +#define TASK_UNINTERRUPTIBLE 0x0002 +#define __TASK_STOPPED 0x0004 +#define __TASK_TRACED 0x0008 /* Used in tsk->exit_state: */ -#define EXIT_DEAD 16 -#define EXIT_ZOMBIE 32 +#define EXIT_DEAD 0x0010 +#define EXIT_ZOMBIE 0x0020 #define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD) /* Used in tsk->state again: */ -#define TASK_DEAD 64 -#define TASK_WAKEKILL 128 -#define TASK_WAKING 256 -#define TASK_PARKED 512 -#define TASK_NOLOAD 1024 -#define TASK_NEW 2048 -#define TASK_STATE_MAX 4096 - -#define TASK_STATE_TO_CHAR_STR "RSDTtXZxKWPNn" +#define TASK_PARKED 0x0040 +#define TASK_DEAD 0x0080 +#define TASK_WAKEKILL 0x0100 +#define TASK_WAKING 0x0200 +#define TASK_NOLOAD 0x0400 +#define TASK_NEW 0x0800 +#define TASK_STATE_MAX 0x1000 /* Convenience macros for the sake of set_current_state: */ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) @@ -99,7 +97,8 @@ struct task_group; /* get_task_state(): */ #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ - __TASK_TRACED | EXIT_ZOMBIE | EXIT_DEAD) + __TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \ + TASK_PARKED) #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) @@ -589,9 +588,10 @@ struct task_struct { #ifdef CONFIG_TASKS_RCU unsigned long rcu_tasks_nvcsw; - bool rcu_tasks_holdout; - struct list_head rcu_tasks_holdout_list; + u8 rcu_tasks_holdout; + u8 rcu_tasks_idx; int rcu_tasks_idle_cpu; + struct list_head rcu_tasks_holdout_list; #endif /* #ifdef CONFIG_TASKS_RCU */ struct sched_info sched_info; @@ -811,8 +811,7 @@ struct task_struct { #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task: */ - struct rb_root pi_waiters; - struct rb_node *pi_waiters_leftmost; + struct rb_root_cached pi_waiters; /* Updated under owner's pi_lock and rq lock */ struct task_struct *pi_top_task; /* Deadlock detection and priority inheritance handling: */ @@ -846,7 +845,17 @@ struct task_struct { int lockdep_depth; unsigned int lockdep_recursion; struct held_lock held_locks[MAX_LOCK_DEPTH]; - gfp_t lockdep_reclaim_gfp; +#endif + +#ifdef CONFIG_LOCKDEP_CROSSRELEASE +#define MAX_XHLOCKS_NR 64UL + struct hist_lock *xhlocks; /* Crossrelease history locks */ + unsigned int xhlock_idx; + /* For restoring at history boundaries */ + unsigned int xhlock_idx_hist[XHLOCK_CTX_NR]; + unsigned int hist_id; + /* For overwrite check at each context exit */ + unsigned int hist_id_save[XHLOCK_CTX_NR]; #endif #ifdef CONFIG_UBSAN @@ -898,8 +907,9 @@ struct task_struct { /* cg_list protected by css_set_lock and tsk->alloc_lock: */ struct list_head cg_list; #endif -#ifdef CONFIG_INTEL_RDT_A - int closid; +#ifdef CONFIG_INTEL_RDT + u32 closid; + u32 rmid; #endif #ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list; @@ -1163,13 +1173,6 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) return tsk->tgid; } -extern pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - -static inline pid_t task_tgid_vnr(struct task_struct *tsk) -{ - return pid_vnr(task_tgid(tsk)); -} - /** * pid_alive - check that a task structure is not stale * @p: Task structure to be checked. @@ -1185,6 +1188,37 @@ static inline int pid_alive(const struct task_struct *p) return p->pids[PIDTYPE_PID].pid != NULL; } +static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +{ + return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns); +} + +static inline pid_t task_pgrp_vnr(struct task_struct *tsk) +{ + return __task_pid_nr_ns(tsk, PIDTYPE_PGID, NULL); +} + + +static inline pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +{ + return __task_pid_nr_ns(tsk, PIDTYPE_SID, ns); +} + +static inline pid_t task_session_vnr(struct task_struct *tsk) +{ + return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); +} + +static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +{ + return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns); +} + +static inline pid_t task_tgid_vnr(struct task_struct *tsk) +{ + return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL); +} + static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) { pid_t pid = 0; @@ -1202,31 +1236,40 @@ static inline pid_t task_ppid_nr(const struct task_struct *tsk) return task_ppid_nr_ns(tsk, &init_pid_ns); } -static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +/* Obsolete, do not use: */ +static inline pid_t task_pgrp_nr(struct task_struct *tsk) { - return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns); + return task_pgrp_nr_ns(tsk, &init_pid_ns); } -static inline pid_t task_pgrp_vnr(struct task_struct *tsk) +#define TASK_REPORT_IDLE (TASK_REPORT + 1) +#define TASK_REPORT_MAX (TASK_REPORT_IDLE << 1) + +static inline unsigned int __get_task_state(struct task_struct *tsk) { - return __task_pid_nr_ns(tsk, PIDTYPE_PGID, NULL); -} + unsigned int tsk_state = READ_ONCE(tsk->state); + unsigned int state = (tsk_state | tsk->exit_state) & TASK_REPORT; + BUILD_BUG_ON_NOT_POWER_OF_2(TASK_REPORT_MAX); -static inline pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return __task_pid_nr_ns(tsk, PIDTYPE_SID, ns); + if (tsk_state == TASK_IDLE) + state = TASK_REPORT_IDLE; + + return fls(state); } -static inline pid_t task_session_vnr(struct task_struct *tsk) +static inline char __task_state_to_char(unsigned int state) { - return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); + static const char state_char[] = "RSDTtXZPI"; + + BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != sizeof(state_char) - 1); + + return state_char[state]; } -/* Obsolete, do not use: */ -static inline pid_t task_pgrp_nr(struct task_struct *tsk) +static inline char task_state_to_char(struct task_struct *tsk) { - return task_pgrp_nr_ns(tsk, &init_pid_ns); + return __task_state_to_char(__get_task_state(tsk)); } /** diff --git a/include/linux/sched/debug.h b/include/linux/sched/debug.h index e0eaee54c5a4c45347fe198aff578277a1d3bd12..5d58d49e9f87634fa6c14db44a4eb62eb1552fc4 100644 --- a/include/linux/sched/debug.h +++ b/include/linux/sched/debug.h @@ -6,6 +6,7 @@ */ struct task_struct; +struct pid_namespace; extern void dump_cpu_task(int cpu); @@ -34,7 +35,8 @@ extern void sched_show_task(struct task_struct *p); #ifdef CONFIG_SCHED_DEBUG struct seq_file; -extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); +extern void proc_sched_show_task(struct task_struct *p, + struct pid_namespace *ns, struct seq_file *m); extern void proc_sched_set_task(struct task_struct *p); #endif diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 2b24a6974847664165bb323aa00c8fae6f3506b0..ae53e413fb1311ddc1a9c826e1634fa86f083599 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -88,7 +88,7 @@ extern void mmput(struct mm_struct *); /* same as above but performs the slow path from the async context. Can * be called from the atomic context as well */ -extern void mmput_async(struct mm_struct *); +void mmput_async(struct mm_struct *); #endif /* Grab a reference to a task's mm, if it is not already going away */ @@ -167,6 +167,14 @@ static inline gfp_t current_gfp_context(gfp_t flags) return flags; } +#ifdef CONFIG_LOCKDEP +extern void fs_reclaim_acquire(gfp_t gfp_mask); +extern void fs_reclaim_release(gfp_t gfp_mask); +#else +static inline void fs_reclaim_acquire(gfp_t gfp_mask) { } +static inline void fs_reclaim_release(gfp_t gfp_mask) { } +#endif + static inline unsigned int memalloc_noio_save(void) { unsigned int flags = current->flags & PF_MEMALLOC_NOIO; diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index c97e5f09692768d0cf2a3770c45aacf2fdc8baf1..79a2a744648dd704b024cab1b37d85e4b2949ca0 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -30,7 +30,6 @@ extern int lockdep_tasklist_lock_is_held(void); extern asmlinkage void schedule_tail(struct task_struct *prev); extern void init_idle(struct task_struct *idle, int cpu); -extern void init_idle_bootup_task(struct task_struct *idle); extern int sched_fork(unsigned long clone_flags, struct task_struct *p); extern void sched_dead(struct task_struct *p); diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index 7d065abc7a470d7b7efdadb634788c695d809af5..d7b6dab956ec4a130cd835d255b3a93bab764e54 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -71,6 +71,14 @@ struct sched_domain_shared { atomic_t ref; atomic_t nr_busy_cpus; int has_idle_cores; + + /* + * Some variables from the most recent sd_lb_stats for this domain, + * used by wake_affine(). + */ + unsigned long nr_running; + unsigned long load; + unsigned long capacity; }; struct sched_domain { diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h index 5d5415e129d43649f9af0840b3d3f5a2687605fa..3c07e4135127915b75f916fa12e99f077889a141 100644 --- a/include/linux/sched/user.h +++ b/include/linux/sched/user.h @@ -36,7 +36,8 @@ struct user_struct { struct hlist_node uidhash_node; kuid_t uid; -#if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_BPF_SYSCALL) +#if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_BPF_SYSCALL) || \ + defined(CONFIG_NET) atomic_long_t locked_vm; #endif }; diff --git a/include/linux/sctp.h b/include/linux/sctp.h index 99e866487e2f5cea6311b1617afe115c94da00f5..82b171e1aa0b8e0f074b0300f630c909a91d6a16 100644 --- a/include/linux/sctp.h +++ b/include/linux/sctp.h @@ -273,87 +273,85 @@ struct sctp_init_chunk { /* Section 3.3.2.1. IPv4 Address Parameter (5) */ -typedef struct sctp_ipv4addr_param { +struct sctp_ipv4addr_param { struct sctp_paramhdr param_hdr; - struct in_addr addr; -} sctp_ipv4addr_param_t; + struct in_addr addr; +}; /* Section 3.3.2.1. IPv6 Address Parameter (6) */ -typedef struct sctp_ipv6addr_param { +struct sctp_ipv6addr_param { struct sctp_paramhdr param_hdr; struct in6_addr addr; -} sctp_ipv6addr_param_t; +}; /* Section 3.3.2.1 Cookie Preservative (9) */ -typedef struct sctp_cookie_preserve_param { +struct sctp_cookie_preserve_param { struct sctp_paramhdr param_hdr; - __be32 lifespan_increment; -} sctp_cookie_preserve_param_t; + __be32 lifespan_increment; +}; /* Section 3.3.2.1 Host Name Address (11) */ -typedef struct sctp_hostname_param { +struct sctp_hostname_param { struct sctp_paramhdr param_hdr; uint8_t hostname[0]; -} sctp_hostname_param_t; +}; /* Section 3.3.2.1 Supported Address Types (12) */ -typedef struct sctp_supported_addrs_param { +struct sctp_supported_addrs_param { struct sctp_paramhdr param_hdr; __be16 types[0]; -} sctp_supported_addrs_param_t; - -/* Appendix A. ECN Capable (32768) */ -typedef struct sctp_ecn_capable_param { - struct sctp_paramhdr param_hdr; -} sctp_ecn_capable_param_t; +}; /* ADDIP Section 3.2.6 Adaptation Layer Indication */ -typedef struct sctp_adaptation_ind_param { +struct sctp_adaptation_ind_param { struct sctp_paramhdr param_hdr; __be32 adaptation_ind; -} sctp_adaptation_ind_param_t; +}; /* ADDIP Section 4.2.7 Supported Extensions Parameter */ -typedef struct sctp_supported_ext_param { +struct sctp_supported_ext_param { struct sctp_paramhdr param_hdr; __u8 chunks[0]; -} sctp_supported_ext_param_t; +}; /* AUTH Section 3.1 Random */ -typedef struct sctp_random_param { +struct sctp_random_param { struct sctp_paramhdr param_hdr; __u8 random_val[0]; -} sctp_random_param_t; +}; /* AUTH Section 3.2 Chunk List */ -typedef struct sctp_chunks_param { +struct sctp_chunks_param { struct sctp_paramhdr param_hdr; __u8 chunks[0]; -} sctp_chunks_param_t; +}; /* AUTH Section 3.3 HMAC Algorithm */ -typedef struct sctp_hmac_algo_param { +struct sctp_hmac_algo_param { struct sctp_paramhdr param_hdr; __be16 hmac_ids[0]; -} sctp_hmac_algo_param_t; +}; /* RFC 2960. Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2): * The INIT ACK chunk is used to acknowledge the initiation of an SCTP * association. */ -typedef struct sctp_init_chunk sctp_initack_chunk_t; +struct sctp_initack_chunk { + struct sctp_chunkhdr chunk_hdr; + struct sctp_inithdr init_hdr; +}; /* Section 3.3.3.1 State Cookie (7) */ -typedef struct sctp_cookie_param { +struct sctp_cookie_param { struct sctp_paramhdr p; __u8 body[0]; -} sctp_cookie_param_t; +}; /* Section 3.3.3.1 Unrecognized Parameters (8) */ -typedef struct sctp_unrecognized_param { +struct sctp_unrecognized_param { struct sctp_paramhdr param_hdr; struct sctp_paramhdr unrecognized; -} sctp_unrecognized_param_t; +}; @@ -365,30 +363,28 @@ typedef struct sctp_unrecognized_param { * subsequences of DATA chunks as represented by their TSNs. */ -typedef struct sctp_gap_ack_block { +struct sctp_gap_ack_block { __be16 start; __be16 end; -} sctp_gap_ack_block_t; - -typedef __be32 sctp_dup_tsn_t; +}; -typedef union { - sctp_gap_ack_block_t gab; - sctp_dup_tsn_t dup; -} sctp_sack_variable_t; +union sctp_sack_variable { + struct sctp_gap_ack_block gab; + __be32 dup; +}; -typedef struct sctp_sackhdr { +struct sctp_sackhdr { __be32 cum_tsn_ack; __be32 a_rwnd; __be16 num_gap_ack_blocks; __be16 num_dup_tsns; - sctp_sack_variable_t variable[0]; -} sctp_sackhdr_t; + union sctp_sack_variable variable[0]; +}; -typedef struct sctp_sack_chunk { +struct sctp_sack_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_sackhdr_t sack_hdr; -} sctp_sack_chunk_t; + struct sctp_sackhdr sack_hdr; +}; /* RFC 2960. Section 3.3.5 Heartbeat Request (HEARTBEAT) (4): @@ -398,49 +394,49 @@ typedef struct sctp_sack_chunk { * the present association. */ -typedef struct sctp_heartbeathdr { +struct sctp_heartbeathdr { struct sctp_paramhdr info; -} sctp_heartbeathdr_t; +}; -typedef struct sctp_heartbeat_chunk { +struct sctp_heartbeat_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_heartbeathdr_t hb_hdr; -} sctp_heartbeat_chunk_t; + struct sctp_heartbeathdr hb_hdr; +}; /* For the abort and shutdown ACK we must carry the init tag in the * common header. Just the common header is all that is needed with a * chunk descriptor. */ -typedef struct sctp_abort_chunk { +struct sctp_abort_chunk { struct sctp_chunkhdr uh; -} sctp_abort_chunk_t; +}; /* For the graceful shutdown we must carry the tag (in common header) * and the highest consecutive acking value. */ -typedef struct sctp_shutdownhdr { +struct sctp_shutdownhdr { __be32 cum_tsn_ack; -} sctp_shutdownhdr_t; +}; -struct sctp_shutdown_chunk_t { +struct sctp_shutdown_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_shutdownhdr_t shutdown_hdr; + struct sctp_shutdownhdr shutdown_hdr; }; /* RFC 2960. Section 3.3.10 Operation Error (ERROR) (9) */ -typedef struct sctp_errhdr { +struct sctp_errhdr { __be16 cause; __be16 length; __u8 variable[0]; -} sctp_errhdr_t; +}; -typedef struct sctp_operr_chunk { +struct sctp_operr_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_errhdr_t err_hdr; -} sctp_operr_chunk_t; + struct sctp_errhdr err_hdr; +}; /* RFC 2960 3.3.10 - Operation Error * @@ -461,7 +457,7 @@ typedef struct sctp_operr_chunk { * 9 No User Data * 10 Cookie Received While Shutting Down */ -typedef enum { +enum sctp_error { SCTP_ERROR_NO_ERROR = cpu_to_be16(0x00), SCTP_ERROR_INV_STRM = cpu_to_be16(0x01), @@ -516,33 +512,28 @@ typedef enum { * 0x0105 Unsupported HMAC Identifier */ SCTP_ERROR_UNSUP_HMAC = cpu_to_be16(0x0105) -} sctp_error_t; +}; /* RFC 2960. Appendix A. Explicit Congestion Notification. * Explicit Congestion Notification Echo (ECNE) (12) */ -typedef struct sctp_ecnehdr { +struct sctp_ecnehdr { __be32 lowest_tsn; -} sctp_ecnehdr_t; +}; -typedef struct sctp_ecne_chunk { +struct sctp_ecne_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_ecnehdr_t ence_hdr; -} sctp_ecne_chunk_t; + struct sctp_ecnehdr ence_hdr; +}; /* RFC 2960. Appendix A. Explicit Congestion Notification. * Congestion Window Reduced (CWR) (13) */ -typedef struct sctp_cwrhdr { +struct sctp_cwrhdr { __be32 lowest_tsn; -} sctp_cwrhdr_t; - -typedef struct sctp_cwr_chunk { - struct sctp_chunkhdr chunk_hdr; - sctp_cwrhdr_t cwr_hdr; -} sctp_cwr_chunk_t; +}; /* PR-SCTP * 3.2 Forward Cumulative TSN Chunk Definition (FORWARD TSN) @@ -638,20 +629,20 @@ struct sctp_fwdtsn_chunk { * The ASCONF Parameter Response is used in the ASCONF-ACK to * report status of ASCONF processing. */ -typedef struct sctp_addip_param { - struct sctp_paramhdr param_hdr; - __be32 crr_id; -} sctp_addip_param_t; +struct sctp_addip_param { + struct sctp_paramhdr param_hdr; + __be32 crr_id; +}; -typedef struct sctp_addiphdr { +struct sctp_addiphdr { __be32 serial; __u8 params[0]; -} sctp_addiphdr_t; +}; -typedef struct sctp_addip_chunk { +struct sctp_addip_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_addiphdr_t addip_hdr; -} sctp_addip_chunk_t; + struct sctp_addiphdr addip_hdr; +}; /* AUTH * Section 4.1 Authentication Chunk (AUTH) @@ -702,16 +693,16 @@ typedef struct sctp_addip_chunk { * HMAC: n bytes (unsigned integer) This hold the result of the HMAC * calculation. */ -typedef struct sctp_authhdr { +struct sctp_authhdr { __be16 shkey_id; __be16 hmac_id; __u8 hmac[0]; -} sctp_authhdr_t; +}; -typedef struct sctp_auth_chunk { +struct sctp_auth_chunk { struct sctp_chunkhdr chunk_hdr; - sctp_authhdr_t auth_hdr; -} sctp_auth_chunk_t; + struct sctp_authhdr auth_hdr; +}; struct sctp_infox { struct sctp_info *sctpinfo; diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index ecc296c137cd2e3e926821dc357e5c00563bedd4..c8bef436b61df236f5b600622ef54da883e1d7a7 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -3,7 +3,8 @@ #include -#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC) +#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \ + SECCOMP_FILTER_FLAG_LOG) #ifdef CONFIG_SECCOMP diff --git a/include/linux/security.h b/include/linux/security.h index b6ea1dc9cc9d2b9e4f1342d6268da1bdb9301be8..ce6265960d6c430a90e1ad3c3749d0a438ecaca9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -85,12 +85,13 @@ extern int cap_capset(struct cred *new, const struct cred *old, const kernel_cap_t *inheritable, const kernel_cap_t *permitted); extern int cap_bprm_set_creds(struct linux_binprm *bprm); -extern int cap_bprm_secureexec(struct linux_binprm *bprm); extern int cap_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); extern int cap_inode_removexattr(struct dentry *dentry, const char *name); extern int cap_inode_need_killpriv(struct dentry *dentry); extern int cap_inode_killpriv(struct dentry *dentry); +extern int cap_inode_getsecurity(struct inode *inode, const char *name, + void **buffer, bool alloc); extern int cap_mmap_addr(unsigned long addr); extern int cap_mmap_file(struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags); @@ -232,7 +233,6 @@ int security_bprm_set_creds(struct linux_binprm *bprm); int security_bprm_check(struct linux_binprm *bprm); void security_bprm_committing_creds(struct linux_binprm *bprm); void security_bprm_committed_creds(struct linux_binprm *bprm); -int security_bprm_secureexec(struct linux_binprm *bprm); int security_sb_alloc(struct super_block *sb); void security_sb_free(struct super_block *sb); int security_sb_copy_data(char *orig, char *copy); @@ -318,7 +318,6 @@ int security_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int sig); int security_file_receive(struct file *file); int security_file_open(struct file *file, const struct cred *cred); -int security_task_create(unsigned long clone_flags); int security_task_alloc(struct task_struct *task, unsigned long clone_flags); void security_task_free(struct task_struct *task); int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); @@ -541,11 +540,6 @@ static inline void security_bprm_committed_creds(struct linux_binprm *bprm) { } -static inline int security_bprm_secureexec(struct linux_binprm *bprm) -{ - return cap_bprm_secureexec(bprm); -} - static inline int security_sb_alloc(struct super_block *sb) { return 0; @@ -885,11 +879,6 @@ static inline int security_file_open(struct file *file, return 0; } -static inline int security_task_create(unsigned long clone_flags) -{ - return 0; -} - static inline int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { diff --git a/include/linux/seg6_local.h b/include/linux/seg6_local.h new file mode 100644 index 0000000000000000000000000000000000000000..ee63e76fe0c76e9347f1ca73cfd4c9cb0f0d53c4 --- /dev/null +++ b/include/linux/seg6_local.h @@ -0,0 +1,6 @@ +#ifndef _LINUX_SEG6_LOCAL_H +#define _LINUX_SEG6_LOCAL_H + +#include + +#endif diff --git a/include/linux/sem.h b/include/linux/sem.h index de2deb8676bd6c39c55a439b5df98715915eb9c9..0083128318f6da53dc1d29cecb3145096bd22a9a 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h @@ -4,6 +4,7 @@ #include #include #include +#include #include struct task_struct; @@ -30,7 +31,7 @@ struct sem { /* One sem_array data structure for each set of semaphores in the system. */ struct sem_array { struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */ - time_t sem_ctime; /* create/last semctl() time */ + time64_t sem_ctime; /* create/last semctl() time */ struct list_head pending_alter; /* pending operations */ /* that alter the array */ struct list_head pending_const; /* pending complex operations */ diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 61fbb440449ca00d9e422966257ebbe5d9cbf434..a27ef5f56431783f516e039944b8cf4d75c898e3 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -80,9 +80,10 @@ struct uart_8250_ops { }; struct uart_8250_em485 { - struct timer_list start_tx_timer; /* "rs485 start tx" timer */ - struct timer_list stop_tx_timer; /* "rs485 stop tx" timer */ - struct timer_list *active_timer; /* pointer to active timer */ + struct hrtimer start_tx_timer; /* "rs485 start tx" timer */ + struct hrtimer stop_tx_timer; /* "rs485 stop tx" timer */ + struct hrtimer *active_timer; /* pointer to active timer */ + struct uart_8250_port *port; /* for hrtimer callbacks */ }; /* diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 1775500294bb3bab35087cca19def9fc9df2a717..5553e04e59c9fb932c6d91ff71e0e9ddbe0bb640 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -20,7 +20,7 @@ #ifndef LINUX_SERIAL_CORE_H #define LINUX_SERIAL_CORE_H - +#include #include #include #include @@ -144,7 +144,7 @@ struct uart_port { unsigned char x_char; /* xon/xoff char */ unsigned char regshift; /* reg offset shift */ unsigned char iotype; /* io access style */ - unsigned char unused1; + unsigned char quirks; /* internal quirks */ #define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */ #define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */ @@ -155,6 +155,9 @@ struct uart_port { #define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */ #define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */ + /* quirks must be updated while holding port mutex */ +#define UPQ_NO_TXEN_TEST BIT(0) + unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ struct uart_state *state; /* pointer to parent state */ @@ -175,7 +178,6 @@ struct uart_port { * [for bit definitions in the UPF_CHANGE_MASK] * * Bits [0..UPF_LAST_USER] are userspace defined/visible/changeable - * except bit 15 (UPF_NO_TXEN_TEST) which is masked off. * The remaining bits are serial-core specific and not modifiable by * userspace. */ @@ -192,7 +194,6 @@ struct uart_port { #define UPF_SPD_SHI ((__force upf_t) ASYNC_SPD_SHI /* 12 */ ) #define UPF_LOW_LATENCY ((__force upf_t) ASYNC_LOW_LATENCY /* 13 */ ) #define UPF_BUGGY_UART ((__force upf_t) ASYNC_BUGGY_UART /* 14 */ ) -#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) #define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ ) #define UPF_NO_THRE_TEST ((__force upf_t) (1 << 19)) @@ -246,7 +247,6 @@ struct uart_port { struct device *dev; /* parent device */ unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; - unsigned char irq_wake; unsigned char unused[2]; const char *name; /* port name */ struct attribute_group *attr_group; /* port specific attributes */ diff --git a/include/linux/sfp.h b/include/linux/sfp.h new file mode 100644 index 0000000000000000000000000000000000000000..4a906f560817147127e11da728fd8bed3153241c --- /dev/null +++ b/include/linux/sfp.h @@ -0,0 +1,434 @@ +#ifndef LINUX_SFP_H +#define LINUX_SFP_H + +#include + +struct __packed sfp_eeprom_base { + u8 phys_id; + u8 phys_ext_id; + u8 connector; +#if defined __BIG_ENDIAN_BITFIELD + u8 e10g_base_er:1; + u8 e10g_base_lrm:1; + u8 e10g_base_lr:1; + u8 e10g_base_sr:1; + u8 if_1x_sx:1; + u8 if_1x_lx:1; + u8 if_1x_copper_active:1; + u8 if_1x_copper_passive:1; + + u8 escon_mmf_1310_led:1; + u8 escon_smf_1310_laser:1; + u8 sonet_oc192_short_reach:1; + u8 sonet_reach_bit1:1; + u8 sonet_reach_bit2:1; + u8 sonet_oc48_long_reach:1; + u8 sonet_oc48_intermediate_reach:1; + u8 sonet_oc48_short_reach:1; + + u8 unallocated_5_7:1; + u8 sonet_oc12_smf_long_reach:1; + u8 sonet_oc12_smf_intermediate_reach:1; + u8 sonet_oc12_short_reach:1; + u8 unallocated_5_3:1; + u8 sonet_oc3_smf_long_reach:1; + u8 sonet_oc3_smf_intermediate_reach:1; + u8 sonet_oc3_short_reach:1; + + u8 e_base_px:1; + u8 e_base_bx10:1; + u8 e100_base_fx:1; + u8 e100_base_lx:1; + u8 e1000_base_t:1; + u8 e1000_base_cx:1; + u8 e1000_base_lx:1; + u8 e1000_base_sx:1; + + u8 fc_ll_v:1; + u8 fc_ll_s:1; + u8 fc_ll_i:1; + u8 fc_ll_l:1; + u8 fc_ll_m:1; + u8 fc_tech_sa:1; + u8 fc_tech_lc:1; + u8 fc_tech_electrical_inter_enclosure:1; + + u8 fc_tech_electrical_intra_enclosure:1; + u8 fc_tech_sn:1; + u8 fc_tech_sl:1; + u8 fc_tech_ll:1; + u8 sfp_ct_active:1; + u8 sfp_ct_passive:1; + u8 unallocated_8_1:1; + u8 unallocated_8_0:1; + + u8 fc_media_tw:1; + u8 fc_media_tp:1; + u8 fc_media_mi:1; + u8 fc_media_tv:1; + u8 fc_media_m6:1; + u8 fc_media_m5:1; + u8 unallocated_9_1:1; + u8 fc_media_sm:1; + + u8 fc_speed_1200:1; + u8 fc_speed_800:1; + u8 fc_speed_1600:1; + u8 fc_speed_400:1; + u8 fc_speed_3200:1; + u8 fc_speed_200:1; + u8 unallocated_10_1:1; + u8 fc_speed_100:1; +#elif defined __LITTLE_ENDIAN_BITFIELD + u8 if_1x_copper_passive:1; + u8 if_1x_copper_active:1; + u8 if_1x_lx:1; + u8 if_1x_sx:1; + u8 e10g_base_sr:1; + u8 e10g_base_lr:1; + u8 e10g_base_lrm:1; + u8 e10g_base_er:1; + + u8 sonet_oc3_short_reach:1; + u8 sonet_oc3_smf_intermediate_reach:1; + u8 sonet_oc3_smf_long_reach:1; + u8 unallocated_5_3:1; + u8 sonet_oc12_short_reach:1; + u8 sonet_oc12_smf_intermediate_reach:1; + u8 sonet_oc12_smf_long_reach:1; + u8 unallocated_5_7:1; + + u8 sonet_oc48_short_reach:1; + u8 sonet_oc48_intermediate_reach:1; + u8 sonet_oc48_long_reach:1; + u8 sonet_reach_bit2:1; + u8 sonet_reach_bit1:1; + u8 sonet_oc192_short_reach:1; + u8 escon_smf_1310_laser:1; + u8 escon_mmf_1310_led:1; + + u8 e1000_base_sx:1; + u8 e1000_base_lx:1; + u8 e1000_base_cx:1; + u8 e1000_base_t:1; + u8 e100_base_lx:1; + u8 e100_base_fx:1; + u8 e_base_bx10:1; + u8 e_base_px:1; + + u8 fc_tech_electrical_inter_enclosure:1; + u8 fc_tech_lc:1; + u8 fc_tech_sa:1; + u8 fc_ll_m:1; + u8 fc_ll_l:1; + u8 fc_ll_i:1; + u8 fc_ll_s:1; + u8 fc_ll_v:1; + + u8 unallocated_8_0:1; + u8 unallocated_8_1:1; + u8 sfp_ct_passive:1; + u8 sfp_ct_active:1; + u8 fc_tech_ll:1; + u8 fc_tech_sl:1; + u8 fc_tech_sn:1; + u8 fc_tech_electrical_intra_enclosure:1; + + u8 fc_media_sm:1; + u8 unallocated_9_1:1; + u8 fc_media_m5:1; + u8 fc_media_m6:1; + u8 fc_media_tv:1; + u8 fc_media_mi:1; + u8 fc_media_tp:1; + u8 fc_media_tw:1; + + u8 fc_speed_100:1; + u8 unallocated_10_1:1; + u8 fc_speed_200:1; + u8 fc_speed_3200:1; + u8 fc_speed_400:1; + u8 fc_speed_1600:1; + u8 fc_speed_800:1; + u8 fc_speed_1200:1; +#else +#error Unknown Endian +#endif + u8 encoding; + u8 br_nominal; + u8 rate_id; + u8 link_len[6]; + char vendor_name[16]; + u8 extended_cc; + char vendor_oui[3]; + char vendor_pn[16]; + char vendor_rev[4]; + union { + __be16 optical_wavelength; + u8 cable_spec; + }; + u8 reserved62; + u8 cc_base; +}; + +struct __packed sfp_eeprom_ext { + __be16 options; + u8 br_max; + u8 br_min; + char vendor_sn[16]; + char datecode[8]; + u8 diagmon; + u8 enhopts; + u8 sff8472_compliance; + u8 cc_ext; +}; + +struct __packed sfp_eeprom_id { + struct sfp_eeprom_base base; + struct sfp_eeprom_ext ext; +}; + +/* SFP EEPROM registers */ +enum { + SFP_PHYS_ID = 0x00, + SFP_PHYS_EXT_ID = 0x01, + SFP_CONNECTOR = 0x02, + SFP_COMPLIANCE = 0x03, + SFP_ENCODING = 0x0b, + SFP_BR_NOMINAL = 0x0c, + SFP_RATE_ID = 0x0d, + SFP_LINK_LEN_SM_KM = 0x0e, + SFP_LINK_LEN_SM_100M = 0x0f, + SFP_LINK_LEN_50UM_OM2_10M = 0x10, + SFP_LINK_LEN_62_5UM_OM1_10M = 0x11, + SFP_LINK_LEN_COPPER_1M = 0x12, + SFP_LINK_LEN_50UM_OM4_10M = 0x12, + SFP_LINK_LEN_50UM_OM3_10M = 0x13, + SFP_VENDOR_NAME = 0x14, + SFP_VENDOR_OUI = 0x25, + SFP_VENDOR_PN = 0x28, + SFP_VENDOR_REV = 0x38, + SFP_OPTICAL_WAVELENGTH_MSB = 0x3c, + SFP_OPTICAL_WAVELENGTH_LSB = 0x3d, + SFP_CABLE_SPEC = 0x3c, + SFP_CC_BASE = 0x3f, + SFP_OPTIONS = 0x40, /* 2 bytes, MSB, LSB */ + SFP_BR_MAX = 0x42, + SFP_BR_MIN = 0x43, + SFP_VENDOR_SN = 0x44, + SFP_DATECODE = 0x54, + SFP_DIAGMON = 0x5c, + SFP_ENHOPTS = 0x5d, + SFP_SFF8472_COMPLIANCE = 0x5e, + SFP_CC_EXT = 0x5f, + + SFP_PHYS_ID_SFP = 0x03, + SFP_PHYS_EXT_ID_SFP = 0x04, + SFP_CONNECTOR_UNSPEC = 0x00, + /* codes 01-05 not supportable on SFP, but some modules have single SC */ + SFP_CONNECTOR_SC = 0x01, + SFP_CONNECTOR_FIBERJACK = 0x06, + SFP_CONNECTOR_LC = 0x07, + SFP_CONNECTOR_MT_RJ = 0x08, + SFP_CONNECTOR_MU = 0x09, + SFP_CONNECTOR_SG = 0x0a, + SFP_CONNECTOR_OPTICAL_PIGTAIL = 0x0b, + SFP_CONNECTOR_MPO_1X12 = 0x0c, + SFP_CONNECTOR_MPO_2X16 = 0x0d, + SFP_CONNECTOR_HSSDC_II = 0x20, + SFP_CONNECTOR_COPPER_PIGTAIL = 0x21, + SFP_CONNECTOR_RJ45 = 0x22, + SFP_CONNECTOR_NOSEPARATE = 0x23, + SFP_CONNECTOR_MXC_2X16 = 0x24, + SFP_ENCODING_UNSPEC = 0x00, + SFP_ENCODING_8B10B = 0x01, + SFP_ENCODING_4B5B = 0x02, + SFP_ENCODING_NRZ = 0x03, + SFP_ENCODING_8472_MANCHESTER = 0x04, + SFP_ENCODING_8472_SONET = 0x05, + SFP_ENCODING_8472_64B66B = 0x06, + SFP_ENCODING_256B257B = 0x07, + SFP_ENCODING_PAM4 = 0x08, + SFP_OPTIONS_HIGH_POWER_LEVEL = BIT(13), + SFP_OPTIONS_PAGING_A2 = BIT(12), + SFP_OPTIONS_RETIMER = BIT(11), + SFP_OPTIONS_COOLED_XCVR = BIT(10), + SFP_OPTIONS_POWER_DECL = BIT(9), + SFP_OPTIONS_RX_LINEAR_OUT = BIT(8), + SFP_OPTIONS_RX_DECISION_THRESH = BIT(7), + SFP_OPTIONS_TUNABLE_TX = BIT(6), + SFP_OPTIONS_RATE_SELECT = BIT(5), + SFP_OPTIONS_TX_DISABLE = BIT(4), + SFP_OPTIONS_TX_FAULT = BIT(3), + SFP_OPTIONS_LOS_INVERTED = BIT(2), + SFP_OPTIONS_LOS_NORMAL = BIT(1), + SFP_DIAGMON_DDM = BIT(6), + SFP_DIAGMON_INT_CAL = BIT(5), + SFP_DIAGMON_EXT_CAL = BIT(4), + SFP_DIAGMON_RXPWR_AVG = BIT(3), + SFP_DIAGMON_ADDRMODE = BIT(2), + SFP_ENHOPTS_ALARMWARN = BIT(7), + SFP_ENHOPTS_SOFT_TX_DISABLE = BIT(6), + SFP_ENHOPTS_SOFT_TX_FAULT = BIT(5), + SFP_ENHOPTS_SOFT_RX_LOS = BIT(4), + SFP_ENHOPTS_SOFT_RATE_SELECT = BIT(3), + SFP_ENHOPTS_APP_SELECT_SFF8079 = BIT(2), + SFP_ENHOPTS_SOFT_RATE_SFF8431 = BIT(1), + SFP_SFF8472_COMPLIANCE_NONE = 0x00, + SFP_SFF8472_COMPLIANCE_REV9_3 = 0x01, + SFP_SFF8472_COMPLIANCE_REV9_5 = 0x02, + SFP_SFF8472_COMPLIANCE_REV10_2 = 0x03, + SFP_SFF8472_COMPLIANCE_REV10_4 = 0x04, + SFP_SFF8472_COMPLIANCE_REV11_0 = 0x05, + SFP_SFF8472_COMPLIANCE_REV11_3 = 0x06, + SFP_SFF8472_COMPLIANCE_REV11_4 = 0x07, + SFP_SFF8472_COMPLIANCE_REV12_0 = 0x08, +}; + +/* SFP Diagnostics */ +enum { + /* Alarm and warnings stored MSB at lower address then LSB */ + SFP_TEMP_HIGH_ALARM = 0x00, + SFP_TEMP_LOW_ALARM = 0x02, + SFP_TEMP_HIGH_WARN = 0x04, + SFP_TEMP_LOW_WARN = 0x06, + SFP_VOLT_HIGH_ALARM = 0x08, + SFP_VOLT_LOW_ALARM = 0x0a, + SFP_VOLT_HIGH_WARN = 0x0c, + SFP_VOLT_LOW_WARN = 0x0e, + SFP_BIAS_HIGH_ALARM = 0x10, + SFP_BIAS_LOW_ALARM = 0x12, + SFP_BIAS_HIGH_WARN = 0x14, + SFP_BIAS_LOW_WARN = 0x16, + SFP_TXPWR_HIGH_ALARM = 0x18, + SFP_TXPWR_LOW_ALARM = 0x1a, + SFP_TXPWR_HIGH_WARN = 0x1c, + SFP_TXPWR_LOW_WARN = 0x1e, + SFP_RXPWR_HIGH_ALARM = 0x20, + SFP_RXPWR_LOW_ALARM = 0x22, + SFP_RXPWR_HIGH_WARN = 0x24, + SFP_RXPWR_LOW_WARN = 0x26, + SFP_LASER_TEMP_HIGH_ALARM = 0x28, + SFP_LASER_TEMP_LOW_ALARM = 0x2a, + SFP_LASER_TEMP_HIGH_WARN = 0x2c, + SFP_LASER_TEMP_LOW_WARN = 0x2e, + SFP_TEC_CUR_HIGH_ALARM = 0x30, + SFP_TEC_CUR_LOW_ALARM = 0x32, + SFP_TEC_CUR_HIGH_WARN = 0x34, + SFP_TEC_CUR_LOW_WARN = 0x36, + SFP_CAL_RXPWR4 = 0x38, + SFP_CAL_RXPWR3 = 0x3c, + SFP_CAL_RXPWR2 = 0x40, + SFP_CAL_RXPWR1 = 0x44, + SFP_CAL_RXPWR0 = 0x48, + SFP_CAL_TXI_SLOPE = 0x4c, + SFP_CAL_TXI_OFFSET = 0x4e, + SFP_CAL_TXPWR_SLOPE = 0x50, + SFP_CAL_TXPWR_OFFSET = 0x52, + SFP_CAL_T_SLOPE = 0x54, + SFP_CAL_T_OFFSET = 0x56, + SFP_CAL_V_SLOPE = 0x58, + SFP_CAL_V_OFFSET = 0x5a, + SFP_CHKSUM = 0x5f, + + SFP_TEMP = 0x60, + SFP_VCC = 0x62, + SFP_TX_BIAS = 0x64, + SFP_TX_POWER = 0x66, + SFP_RX_POWER = 0x68, + SFP_LASER_TEMP = 0x6a, + SFP_TEC_CUR = 0x6c, + + SFP_STATUS = 0x6e, + SFP_ALARM = 0x70, + + SFP_EXT_STATUS = 0x76, + SFP_VSL = 0x78, + SFP_PAGE = 0x7f, +}; + +struct device_node; +struct ethtool_eeprom; +struct ethtool_modinfo; +struct net_device; +struct sfp_bus; + +struct sfp_upstream_ops { + int (*module_insert)(void *, const struct sfp_eeprom_id *id); + void (*module_remove)(void *); + void (*link_down)(void *); + void (*link_up)(void *); + int (*connect_phy)(void *, struct phy_device *); + void (*disconnect_phy)(void *); +}; + +#if IS_ENABLED(CONFIG_SFP) +int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id, + unsigned long *support); +phy_interface_t sfp_parse_interface(struct sfp_bus *bus, + const struct sfp_eeprom_id *id); +void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, + unsigned long *support); + +int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo); +int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee, + u8 *data); +void sfp_upstream_start(struct sfp_bus *bus); +void sfp_upstream_stop(struct sfp_bus *bus); +struct sfp_bus *sfp_register_upstream(struct device_node *np, + struct net_device *ndev, void *upstream, + const struct sfp_upstream_ops *ops); +void sfp_unregister_upstream(struct sfp_bus *bus); +#else +static inline int sfp_parse_port(struct sfp_bus *bus, + const struct sfp_eeprom_id *id, + unsigned long *support) +{ + return PORT_OTHER; +} + +static inline phy_interface_t sfp_parse_interface(struct sfp_bus *bus, + const struct sfp_eeprom_id *id) +{ + return PHY_INTERFACE_MODE_NA; +} + +static inline void sfp_parse_support(struct sfp_bus *bus, + const struct sfp_eeprom_id *id, + unsigned long *support) +{ +} + +static inline int sfp_get_module_info(struct sfp_bus *bus, + struct ethtool_modinfo *modinfo) +{ + return -EOPNOTSUPP; +} + +static inline int sfp_get_module_eeprom(struct sfp_bus *bus, + struct ethtool_eeprom *ee, u8 *data) +{ + return -EOPNOTSUPP; +} + +static inline void sfp_upstream_start(struct sfp_bus *bus) +{ +} + +static inline void sfp_upstream_stop(struct sfp_bus *bus) +{ +} + +static inline struct sfp_bus *sfp_register_upstream(struct device_node *np, + struct net_device *ndev, void *upstream, + const struct sfp_upstream_ops *ops) +{ + return (struct sfp_bus *)-1; +} + +static inline void sfp_unregister_upstream(struct sfp_bus *bus) +{ +} +#endif + +#endif diff --git a/include/linux/shm.h b/include/linux/shm.h index 0fb7061ec54c13d29e36ba5b6f09628f4f2ba676..74a4b3b64352ec29e9e613b8d8bc41a1ad54a491 100644 --- a/include/linux/shm.h +++ b/include/linux/shm.h @@ -12,9 +12,9 @@ struct shmid_kernel /* private to the kernel */ struct file *shm_file; unsigned long shm_nattch; unsigned long shm_segsz; - time_t shm_atim; - time_t shm_dtim; - time_t shm_ctim; + time64_t shm_atim; + time64_t shm_dtim; + time64_t shm_ctim; pid_t shm_cprid; pid_t shm_lprid; struct user_struct *mlock_user; @@ -27,23 +27,6 @@ struct shmid_kernel /* private to the kernel */ /* shm_mode upper byte flags */ #define SHM_DEST 01000 /* segment will be destroyed on last detach */ #define SHM_LOCKED 02000 /* segment will not be swapped */ -#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */ -#define SHM_NORESERVE 010000 /* don't check for reservations */ - -/* Bits [26:31] are reserved */ - -/* - * When SHM_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define SHM_HUGE_SHIFT 26 -#define SHM_HUGE_MASK 0x3f -#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT) -#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT) #ifdef CONFIG_SYSVIPC struct sysv_shm { diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index a7d6bd2a918f73a71abcc2daf92fb412c22ac342..b6c3540e07bc31a5aafbf43c61b469f4eeb4fa96 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -137,9 +137,15 @@ extern int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd, unsigned long dst_addr, unsigned long src_addr, struct page **pagep); +extern int shmem_mfill_zeropage_pte(struct mm_struct *dst_mm, + pmd_t *dst_pmd, + struct vm_area_struct *dst_vma, + unsigned long dst_addr); #else #define shmem_mcopy_atomic_pte(dst_mm, dst_pte, dst_vma, dst_addr, \ src_addr, pagep) ({ BUG(); 0; }) +#define shmem_mfill_zeropage_pte(dst_mm, dst_pmd, dst_vma, \ + dst_addr) ({ BUG(); 0; }) #endif #endif diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index 4fcacd915d45adaf914c770f7d04f8b12b2a504a..51d189615bdaac321e32a6966ad689b7c37b78ce 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -18,6 +18,13 @@ struct shrink_control { */ unsigned long nr_to_scan; + /* + * How many objects did scan_objects process? + * This defaults to nr_to_scan before every call, but the callee + * should track its actual progress. + */ + unsigned long nr_scanned; + /* current node being shrunk (for NUMA aware shrinkers) */ int nid; diff --git a/include/linux/signal.h b/include/linux/signal.h index e2678b5dbb213f6751283ecc890be2aad304008a..38564e3e54c70cda7531423bdf9b7e3e1576c2d2 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -21,6 +21,20 @@ static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); +enum siginfo_layout { + SIL_KILL, + SIL_TIMER, + SIL_POLL, + SIL_FAULT, + SIL_CHLD, + SIL_RT, +#ifdef __ARCH_SIGSYS + SIL_SYS, +#endif +}; + +enum siginfo_layout siginfo_layout(int sig, int si_code); + /* * Define some primitives to manipulate sigset_t. */ @@ -380,10 +394,18 @@ int unhandled_signal(struct task_struct *tsk, int sig); rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \ rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) ) +#define SIG_SPECIFIC_SICODES_MASK (\ + rt_sigmask(SIGILL) | rt_sigmask(SIGFPE) | \ + rt_sigmask(SIGSEGV) | rt_sigmask(SIGBUS) | \ + rt_sigmask(SIGTRAP) | rt_sigmask(SIGCHLD) | \ + rt_sigmask(SIGPOLL) | rt_sigmask(SIGSYS) | \ + SIGEMT_MASK ) + #define sig_kernel_only(sig) siginmask(sig, SIG_KERNEL_ONLY_MASK) #define sig_kernel_coredump(sig) siginmask(sig, SIG_KERNEL_COREDUMP_MASK) #define sig_kernel_ignore(sig) siginmask(sig, SIG_KERNEL_IGNORE_MASK) #define sig_kernel_stop(sig) siginmask(sig, SIG_KERNEL_STOP_MASK) +#define sig_specific_sicodes(sig) siginmask(sig, SIG_SPECIFIC_SICODES_MASK) #define sig_fatal(t, signr) \ (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ diff --git a/include/linux/skb_array.h b/include/linux/skb_array.h index 35226cd4efb0f32afcf38cc4a97441e9524424f0..8621ffdeecbf0542e57c2d7fee12f53546af7774 100644 --- a/include/linux/skb_array.h +++ b/include/linux/skb_array.h @@ -193,7 +193,8 @@ static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp) } static inline int skb_array_resize_multiple(struct skb_array **rings, - int nrings, int size, gfp_t gfp) + int nrings, unsigned int size, + gfp_t gfp) { BUILD_BUG_ON(offsetof(struct skb_array, ring)); return ptr_ring_resize_multiple((struct ptr_ring **)rings, diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index dbe29b6c9bd6097b4a7e5763ad39d26921780270..72299ef00061db1ce70d34b96ae1639ecde08837 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -345,6 +346,42 @@ static inline void skb_frag_size_sub(skb_frag_t *frag, int delta) frag->size -= delta; } +static inline bool skb_frag_must_loop(struct page *p) +{ +#if defined(CONFIG_HIGHMEM) + if (PageHighMem(p)) + return true; +#endif + return false; +} + +/** + * skb_frag_foreach_page - loop over pages in a fragment + * + * @f: skb frag to operate on + * @f_off: offset from start of f->page.p + * @f_len: length from f_off to loop over + * @p: (temp var) current page + * @p_off: (temp var) offset from start of current page, + * non-zero only on first page. + * @p_len: (temp var) length in current page, + * < PAGE_SIZE only on first and last page. + * @copied: (temp var) length so far, excluding current p_len. + * + * A fragment can hold a compound page, in which case per-page + * operations, notably kmap_atomic, must be called for each + * regular page. + */ +#define skb_frag_foreach_page(f, f_off, f_len, p, p_off, p_len, copied) \ + for (p = skb_frag_page(f) + ((f_off) >> PAGE_SHIFT), \ + p_off = (f_off) & (PAGE_SIZE - 1), \ + p_len = skb_frag_must_loop(p) ? \ + min_t(u32, f_len, PAGE_SIZE - p_off) : f_len, \ + copied = 0; \ + copied < f_len; \ + copied += p_len, p++, p_off = 0, \ + p_len = min_t(u32, f_len - copied, PAGE_SIZE)) \ + #define HAVE_HW_TIME_STAMP /** @@ -393,6 +430,7 @@ enum { SKBTX_SCHED_TSTAMP = 1 << 6, }; +#define SKBTX_ZEROCOPY_FRAG (SKBTX_DEV_ZEROCOPY | SKBTX_SHARED_FRAG) #define SKBTX_ANY_SW_TSTAMP (SKBTX_SW_TSTAMP | \ SKBTX_SCHED_TSTAMP) #define SKBTX_ANY_TSTAMP (SKBTX_HW_TSTAMP | SKBTX_ANY_SW_TSTAMP) @@ -407,10 +445,46 @@ enum { */ struct ubuf_info { void (*callback)(struct ubuf_info *, bool zerocopy_success); - void *ctx; - unsigned long desc; + union { + struct { + unsigned long desc; + void *ctx; + }; + struct { + u32 id; + u16 len; + u16 zerocopy:1; + u32 bytelen; + }; + }; + refcount_t refcnt; + + struct mmpin { + struct user_struct *user; + unsigned int num_pg; + } mmp; }; +#define skb_uarg(SKB) ((struct ubuf_info *)(skb_shinfo(SKB)->destructor_arg)) + +struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size); +struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size, + struct ubuf_info *uarg); + +static inline void sock_zerocopy_get(struct ubuf_info *uarg) +{ + refcount_inc(&uarg->refcnt); +} + +void sock_zerocopy_put(struct ubuf_info *uarg); +void sock_zerocopy_put_abort(struct ubuf_info *uarg); + +void sock_zerocopy_callback(struct ubuf_info *uarg, bool success); + +int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb, + struct msghdr *msg, int len, + struct ubuf_info *uarg); + /* This data is invariant across clones and lives at * the end of the header data, ie. at skb->end. */ @@ -463,39 +537,38 @@ enum { enum { SKB_GSO_TCPV4 = 1 << 0, - SKB_GSO_UDP = 1 << 1, /* This indicates the skb is from an untrusted source. */ - SKB_GSO_DODGY = 1 << 2, + SKB_GSO_DODGY = 1 << 1, /* This indicates the tcp segment has CWR set. */ - SKB_GSO_TCP_ECN = 1 << 3, + SKB_GSO_TCP_ECN = 1 << 2, - SKB_GSO_TCP_FIXEDID = 1 << 4, + SKB_GSO_TCP_FIXEDID = 1 << 3, - SKB_GSO_TCPV6 = 1 << 5, + SKB_GSO_TCPV6 = 1 << 4, - SKB_GSO_FCOE = 1 << 6, + SKB_GSO_FCOE = 1 << 5, - SKB_GSO_GRE = 1 << 7, + SKB_GSO_GRE = 1 << 6, - SKB_GSO_GRE_CSUM = 1 << 8, + SKB_GSO_GRE_CSUM = 1 << 7, - SKB_GSO_IPXIP4 = 1 << 9, + SKB_GSO_IPXIP4 = 1 << 8, - SKB_GSO_IPXIP6 = 1 << 10, + SKB_GSO_IPXIP6 = 1 << 9, - SKB_GSO_UDP_TUNNEL = 1 << 11, + SKB_GSO_UDP_TUNNEL = 1 << 10, - SKB_GSO_UDP_TUNNEL_CSUM = 1 << 12, + SKB_GSO_UDP_TUNNEL_CSUM = 1 << 11, - SKB_GSO_PARTIAL = 1 << 13, + SKB_GSO_PARTIAL = 1 << 12, - SKB_GSO_TUNNEL_REMCSUM = 1 << 14, + SKB_GSO_TUNNEL_REMCSUM = 1 << 13, - SKB_GSO_SCTP = 1 << 15, + SKB_GSO_SCTP = 1 << 14, - SKB_GSO_ESP = 1 << 16, + SKB_GSO_ESP = 1 << 15, }; #if BITS_PER_LONG > 32 @@ -885,7 +958,7 @@ void kfree_skb(struct sk_buff *skb); void kfree_skb_list(struct sk_buff *segs); void skb_tx_error(struct sk_buff *skb); void consume_skb(struct sk_buff *skb); -void consume_stateless_skb(struct sk_buff *skb); +void __consume_stateless_skb(struct sk_buff *skb); void __kfree_skb(struct sk_buff *skb); extern struct kmem_cache *skbuff_head_cache; @@ -945,12 +1018,6 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE); } -struct sk_buff *__alloc_skb_head(gfp_t priority, int node); -static inline struct sk_buff *alloc_skb_head(gfp_t priority) -{ - return __alloc_skb_head(priority, -1); -} - struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask); struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t priority); @@ -973,7 +1040,23 @@ int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); -int skb_pad(struct sk_buff *skb, int pad); +int __skb_pad(struct sk_buff *skb, int pad, bool free_on_error); + +/** + * skb_pad - zero pad the tail of an skb + * @skb: buffer to pad + * @pad: space to pad + * + * Ensure that a buffer is followed by a padding area that is zero + * filled. Used by network drivers which may DMA or transfer data + * beyond the buffer end onto the wire. + * + * May return error in out of memory cases. The skb is freed on error. + */ +static inline int skb_pad(struct sk_buff *skb, int pad) +{ + return __skb_pad(skb, pad, true); +} #define dev_kfree_skb(a) consume_skb(a) int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, @@ -1129,8 +1212,6 @@ static inline __u32 skb_get_hash(struct sk_buff *skb) return skb->hash; } -__u32 __skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 *fl6); - static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 *fl6) { if (!skb->l4_hash && !skb->sw_hash) { @@ -1143,20 +1224,6 @@ static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 return skb->hash; } -__u32 __skb_get_hash_flowi4(struct sk_buff *skb, const struct flowi4 *fl); - -static inline __u32 skb_get_hash_flowi4(struct sk_buff *skb, const struct flowi4 *fl4) -{ - if (!skb->l4_hash && !skb->sw_hash) { - struct flow_keys keys; - __u32 hash = __get_hash_from_flowi4(fl4, &keys); - - __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys)); - } - - return skb->hash; -} - __u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb); static inline __u32 skb_get_hash_raw(const struct sk_buff *skb) @@ -1201,6 +1268,50 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) return &skb_shinfo(skb)->hwtstamps; } +static inline struct ubuf_info *skb_zcopy(struct sk_buff *skb) +{ + bool is_zcopy = skb && skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY; + + return is_zcopy ? skb_uarg(skb) : NULL; +} + +static inline void skb_zcopy_set(struct sk_buff *skb, struct ubuf_info *uarg) +{ + if (skb && uarg && !skb_zcopy(skb)) { + sock_zerocopy_get(uarg); + skb_shinfo(skb)->destructor_arg = uarg; + skb_shinfo(skb)->tx_flags |= SKBTX_ZEROCOPY_FRAG; + } +} + +/* Release a reference on a zerocopy structure */ +static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy) +{ + struct ubuf_info *uarg = skb_zcopy(skb); + + if (uarg) { + if (uarg->callback == sock_zerocopy_callback) { + uarg->zerocopy = uarg->zerocopy && zerocopy; + sock_zerocopy_put(uarg); + } else { + uarg->callback(uarg, zerocopy); + } + + skb_shinfo(skb)->tx_flags &= ~SKBTX_ZEROCOPY_FRAG; + } +} + +/* Abort a zerocopy operation and revert zckey on error in send syscall */ +static inline void skb_zcopy_abort(struct sk_buff *skb) +{ + struct ubuf_info *uarg = skb_zcopy(skb); + + if (uarg) { + sock_zerocopy_put_abort(uarg); + skb_shinfo(skb)->tx_flags &= ~SKBTX_ZEROCOPY_FRAG; + } +} + /** * skb_queue_empty - check if a queue is empty * @list: queue head @@ -1783,13 +1894,18 @@ static inline unsigned int skb_headlen(const struct sk_buff *skb) return skb->len - skb->data_len; } -static inline unsigned int skb_pagelen(const struct sk_buff *skb) +static inline unsigned int __skb_pagelen(const struct sk_buff *skb) { unsigned int i, len = 0; for (i = skb_shinfo(skb)->nr_frags - 1; (int)i >= 0; i--) len += skb_frag_size(&skb_shinfo(skb)->frags[i]); - return len + skb_headlen(skb); + return len; +} + +static inline unsigned int skb_pagelen(const struct sk_buff *skb) +{ + return skb_headlen(skb) + __skb_pagelen(skb); } /** @@ -2434,7 +2550,17 @@ static inline void skb_orphan(struct sk_buff *skb) */ static inline int skb_orphan_frags(struct sk_buff *skb, gfp_t gfp_mask) { - if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY))) + if (likely(!skb_zcopy(skb))) + return 0; + if (skb_uarg(skb)->callback == sock_zerocopy_callback) + return 0; + return skb_copy_ubufs(skb, gfp_mask); +} + +/* Frags must be orphaned, even if refcounted, if skb might loop to rx path */ +static inline int skb_orphan_frags_rx(struct sk_buff *skb, gfp_t gfp_mask) +{ + if (likely(!skb_zcopy(skb))) return 0; return skb_copy_ubufs(skb, gfp_mask); } @@ -2825,25 +2951,42 @@ static inline int skb_padto(struct sk_buff *skb, unsigned int len) * skb_put_padto - increase size and pad an skbuff up to a minimal size * @skb: buffer to pad * @len: minimal length + * @free_on_error: free buffer on error * * Pads up a buffer to ensure the trailing bytes exist and are * blanked. If the buffer already contains sufficient data it * is untouched. Otherwise it is extended. Returns zero on - * success. The skb is freed on error. + * success. The skb is freed on error if @free_on_error is true. */ -static inline int skb_put_padto(struct sk_buff *skb, unsigned int len) +static inline int __skb_put_padto(struct sk_buff *skb, unsigned int len, + bool free_on_error) { unsigned int size = skb->len; if (unlikely(size < len)) { len -= size; - if (skb_pad(skb, len)) + if (__skb_pad(skb, len, free_on_error)) return -ENOMEM; __skb_put(skb, len); } return 0; } +/** + * skb_put_padto - increase size and pad an skbuff up to a minimal size + * @skb: buffer to pad + * @len: minimal length + * + * Pads up a buffer to ensure the trailing bytes exist and are + * blanked. If the buffer already contains sufficient data it + * is untouched. Otherwise it is extended. Returns zero on + * success. The skb is freed on error. + */ +static inline int skb_put_padto(struct sk_buff *skb, unsigned int len) +{ + return __skb_put_padto(skb, len, true); +} + static inline int skb_add_data(struct sk_buff *skb, struct iov_iter *from, int copy) { @@ -2866,6 +3009,8 @@ static inline int skb_add_data(struct sk_buff *skb, static inline bool skb_can_coalesce(struct sk_buff *skb, int i, const struct page *page, int off) { + if (skb_zcopy(skb)) + return false; if (i) { const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; @@ -3120,6 +3265,9 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset, struct pipe_inode_info *pipe, unsigned int len, unsigned int flags); +int skb_send_sock_locked(struct sock *sk, struct sk_buff *skb, int offset, + int len); +int skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset, int len); void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to); unsigned int skb_zerocopy_headlen(const struct sk_buff *from); int skb_zerocopy(struct sk_buff *to, struct sk_buff *from, diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index cc0faf3a90bee30cdf1d482cf76e2c4edf47fd89..0783b622311e1ce96acbb0d2ed85658e1a377cfa 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -115,6 +115,10 @@ struct kmem_cache { #endif #endif +#ifdef CONFIG_SLAB_FREELIST_HARDENED + unsigned long random; +#endif + #ifdef CONFIG_NUMA /* * Defragmentation by allocating from a remote node. diff --git a/include/linux/smp.h b/include/linux/smp.h index 68123c1fe54918c051292eb5ba3427df09f31c2f..98b1fe027fc9c653e2d9c55fc890f19be3973cb3 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -14,13 +14,17 @@ #include typedef void (*smp_call_func_t)(void *info); -struct call_single_data { +struct __call_single_data { struct llist_node llist; smp_call_func_t func; void *info; unsigned int flags; }; +/* Use __aligned() to avoid to use 2 cache lines for 1 csd */ +typedef struct __call_single_data call_single_data_t + __aligned(sizeof(struct __call_single_data)); + /* total number of cpus in this system (may exceed NR_CPUS) */ extern unsigned int total_cpus; @@ -48,7 +52,7 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), smp_call_func_t func, void *info, bool wait, gfp_t gfp_flags); -int smp_call_function_single_async(int cpu, struct call_single_data *csd); +int smp_call_function_single_async(int cpu, call_single_data_t *csd); #ifdef CONFIG_SMP diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h index 12910cf19869c7db32d1ca34ddda0931e80570d1..c149aa7bedf306c8a04d9fd61cb8930af12d416f 100644 --- a/include/linux/smpboot.h +++ b/include/linux/smpboot.h @@ -55,7 +55,7 @@ smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread) } void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread); -int smpboot_update_cpumask_percpu_thread(struct smp_hotplug_thread *plug_thread, - const struct cpumask *); +void smpboot_update_cpumask_percpu_thread(struct smp_hotplug_thread *plug_thread, + const struct cpumask *); #endif diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h index a5714e93fb34189820342e23a93000f7f2265956..a0182ec2a621c2044208b8a780847e58bb066ad5 100644 --- a/include/linux/soc/mediatek/infracfg.h +++ b/include/linux/soc/mediatek/infracfg.h @@ -20,6 +20,13 @@ #define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22) #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) +#define MT7622_TOP_AXI_PROT_EN_ETHSYS (BIT(3) | BIT(17)) +#define MT7622_TOP_AXI_PROT_EN_HIF0 (BIT(24) | BIT(25)) +#define MT7622_TOP_AXI_PROT_EN_HIF1 (BIT(26) | BIT(27) | \ + BIT(28)) +#define MT7622_TOP_AXI_PROT_EN_WB (BIT(2) | BIT(6) | \ + BIT(7) | BIT(8)) + int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask); int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask); diff --git a/include/linux/soc/ti/knav_dma.h b/include/linux/soc/ti/knav_dma.h index 2b7882666ef6950d4b2c24033849722a7839e943..66693bc4c6ad6b9b096b1b3364d7b2b580525d97 100644 --- a/include/linux/soc/ti/knav_dma.h +++ b/include/linux/soc/ti/knav_dma.h @@ -17,6 +17,8 @@ #ifndef __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__ #define __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__ +#include + /* * PKTDMA descriptor manipulation macros for host packet descriptor */ diff --git a/include/linux/socket.h b/include/linux/socket.h index 8b13db5163cc5d511d930b96869c9a7e16e68e05..8ad963cdc88c50114759a343dd13a7a87c76abab 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -287,6 +287,7 @@ struct ucred { #define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */ #define MSG_EOF MSG_FIN +#define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ #define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file descriptor received through diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index d9510e8522d4d33d11bc7e1f9e699f9c353a28ef..69e079c5ff985bdc49d8b933ea688159f448e2f1 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -118,24 +118,41 @@ do { \ #endif /* - * Despite its name it doesn't necessarily has to be a full barrier. - * It should only guarantee that a STORE before the critical section - * can not be reordered with LOADs and STOREs inside this section. - * spin_lock() is the one-way barrier, this LOAD can not escape out - * of the region. So the default implementation simply ensures that - * a STORE can not move into the critical section, smp_wmb() should - * serialize it with another STORE done by spin_lock(). + * This barrier must provide two things: + * + * - it must guarantee a STORE before the spin_lock() is ordered against a + * LOAD after it, see the comments at its two usage sites. + * + * - it must ensure the critical section is RCsc. + * + * The latter is important for cases where we observe values written by other + * CPUs in spin-loops, without barriers, while being subject to scheduling. + * + * CPU0 CPU1 CPU2 + * + * for (;;) { + * if (READ_ONCE(X)) + * break; + * } + * X=1 + * + * + * r = X; + * + * without transitivity it could be that CPU1 observes X!=0 breaks the loop, + * we get migrated and CPU2 sees X==0. + * + * Since most load-store architectures implement ACQUIRE with an smp_mb() after + * the LL/SC loop, they need no further barriers. Similarly all our TSO + * architectures imply an smp_mb() for each atomic instruction and equally don't + * need more. + * + * Architectures that can implement ACQUIRE better need to take care. */ -#ifndef smp_mb__before_spinlock -#define smp_mb__before_spinlock() smp_wmb() +#ifndef smp_mb__after_spinlock +#define smp_mb__after_spinlock() do { } while (0) #endif -/** - * raw_spin_unlock_wait - wait until the spinlock gets unlocked - * @lock: the spinlock in question. - */ -#define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) - #ifdef CONFIG_DEBUG_SPINLOCK extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); #define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock) @@ -369,31 +386,6 @@ static __always_inline int spin_trylock_irq(spinlock_t *lock) raw_spin_trylock_irqsave(spinlock_check(lock), flags); \ }) -/** - * spin_unlock_wait - Interpose between successive critical sections - * @lock: the spinlock whose critical sections are to be interposed. - * - * Semantically this is equivalent to a spin_lock() immediately - * followed by a spin_unlock(). However, most architectures have - * more efficient implementations in which the spin_unlock_wait() - * cannot block concurrent lock acquisition, and in some cases - * where spin_unlock_wait() does not write to the lock variable. - * Nevertheless, spin_unlock_wait() can have high overhead, so if - * you feel the need to use it, please check to see if there is - * a better way to get your job done. - * - * The ordering guarantees provided by spin_unlock_wait() are: - * - * 1. All accesses preceding the spin_unlock_wait() happen before - * any accesses in later critical sections for this same lock. - * 2. All accesses following the spin_unlock_wait() happen after - * any accesses in earlier critical sections for this same lock. - */ -static __always_inline void spin_unlock_wait(spinlock_t *lock) -{ - raw_spin_unlock_wait(&lock->rlock); -} - static __always_inline int spin_is_locked(spinlock_t *lock) { return raw_spin_is_locked(&lock->rlock); diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index 0d9848de677d96eb186f71c578dd6031f6c47611..612fb530af41b40f2e164cfe5f302a3cc48a3cf7 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -26,11 +26,6 @@ #ifdef CONFIG_DEBUG_SPINLOCK #define arch_spin_is_locked(x) ((x)->slock == 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, VAL); -} - static inline void arch_spin_lock(arch_spinlock_t *lock) { lock->slock = 0; @@ -73,7 +68,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) #else /* DEBUG_SPINLOCK */ #define arch_spin_is_locked(lock) ((void)(lock), 0) -#define arch_spin_unlock_wait(lock) do { barrier(); (void)(lock); } while (0) /* for sched/core.c and kernel_lock.c: */ # define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0) # define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0) diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h index cfbfc540cafcb44ed564b03c5b37b127b08db10b..261471f407a55cd8e0adf4b078b1ee62269e7c41 100644 --- a/include/linux/srcutiny.h +++ b/include/linux/srcutiny.h @@ -87,4 +87,17 @@ static inline void srcu_barrier(struct srcu_struct *sp) synchronize_srcu(sp); } +/* Defined here to avoid size increase for non-torture kernels. */ +static inline void srcu_torture_stats_print(struct srcu_struct *sp, + char *tt, char *tf) +{ + int idx; + + idx = READ_ONCE(sp->srcu_idx) & 0x1; + pr_alert("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n", + tt, tf, idx, + READ_ONCE(sp->srcu_lock_nesting[!idx]), + READ_ONCE(sp->srcu_lock_nesting[idx])); +} + #endif diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index 42973f787e7ee23e8f23d89cb9894471ac3b7498..a949f4f9e4d769f37579e8d6e90c8fb636f6029b 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -104,8 +104,6 @@ struct srcu_struct { #define SRCU_STATE_SCAN1 1 #define SRCU_STATE_SCAN2 2 -void process_srcu(struct work_struct *work); - #define __SRCU_STRUCT_INIT(name) \ { \ .sda = &name##_srcu_data, \ @@ -141,5 +139,6 @@ void process_srcu(struct work_struct *work); void synchronize_srcu_expedited(struct srcu_struct *sp); void srcu_barrier(struct srcu_struct *sp); +void srcu_torture_stats_print(struct srcu_struct *sp, char *tt, char *tf); #endif diff --git a/include/linux/string.h b/include/linux/string.h index a467e617eeb08cde480b7e5e2b65ffa208d2243c..54d21783e18dd12dd7e2ad563c2debc9e046143d 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -99,6 +99,36 @@ extern __kernel_size_t strcspn(const char *,const char *); #ifndef __HAVE_ARCH_MEMSET extern void * memset(void *,int,__kernel_size_t); #endif + +#ifndef __HAVE_ARCH_MEMSET16 +extern void *memset16(uint16_t *, uint16_t, __kernel_size_t); +#endif + +#ifndef __HAVE_ARCH_MEMSET32 +extern void *memset32(uint32_t *, uint32_t, __kernel_size_t); +#endif + +#ifndef __HAVE_ARCH_MEMSET64 +extern void *memset64(uint64_t *, uint64_t, __kernel_size_t); +#endif + +static inline void *memset_l(unsigned long *p, unsigned long v, + __kernel_size_t n) +{ + if (BITS_PER_LONG == 32) + return memset32((uint32_t *)p, v, n); + else + return memset64((uint64_t *)p, v, n); +} + +static inline void *memset_p(void **p, void *v, __kernel_size_t n) +{ + if (BITS_PER_LONG == 32) + return memset32((uint32_t *)p, (uintptr_t)v, n); + else + return memset64((uint64_t *)p, (uintptr_t)v, n); +} + #ifndef __HAVE_ARCH_MEMCPY extern void * memcpy(void *,const void *,__kernel_size_t); #endif @@ -200,6 +230,7 @@ static inline const char *kbasename(const char *path) void fortify_panic(const char *name) __noreturn __cold; void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter"); void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter"); +void __read_overflow3(void) __compiletime_error("detected read beyond size of object passed as 3rd parameter"); void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter"); #if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE) @@ -395,4 +426,22 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q) #endif +/** + * memcpy_and_pad - Copy one buffer to another with padding + * @dest: Where to copy to + * @dest_len: The destination buffer size + * @src: Where to copy from + * @count: The number of bytes to copy + * @pad: Character to use for padding if space is left in destination. + */ +static inline void memcpy_and_pad(void *dest, size_t dest_len, + const void *src, size_t count, int pad) +{ + if (dest_len > count) { + memcpy(dest, src, count); + memset(dest + count, pad, dest_len - count); + } else + memcpy(dest, src, dest_len); +} + #endif /* _LINUX_STRING_H_ */ diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 50a99a117da7fc860bf2ab7c389e3214656a2a83..c1768f9d993bf25346dcd67215897278172e7b05 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -139,6 +139,8 @@ struct rpc_task_setup { #define RPC_TASK_RUNNING 0 #define RPC_TASK_QUEUED 1 #define RPC_TASK_ACTIVE 2 +#define RPC_TASK_MSG_RECV 3 +#define RPC_TASK_MSG_RECV_WAIT 4 #define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) #define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index a3f8af9bd543e4c117f95178662f971363df16e3..38f561b2dda3ccd8f2b4e20ea13f2d8d04d12496 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -99,7 +99,7 @@ struct svc_serv { unsigned int sv_nrpools; /* number of thread pools */ struct svc_pool * sv_pools; /* array of thread pools */ - struct svc_serv_ops *sv_ops; /* server operations */ + const struct svc_serv_ops *sv_ops; /* server operations */ #if defined(CONFIG_SUNRPC_BACKCHANNEL) struct list_head sv_cb_list; /* queue for callback requests * that arrive over the same @@ -465,7 +465,7 @@ int svc_rpcb_setup(struct svc_serv *serv, struct net *net); void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); int svc_bind(struct svc_serv *serv, struct net *net); struct svc_serv *svc_create(struct svc_program *, unsigned int, - struct svc_serv_ops *); + const struct svc_serv_ops *); struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node); struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, @@ -475,7 +475,7 @@ void svc_exit_thread(struct svc_rqst *); unsigned int svc_pool_map_get(void); void svc_pool_map_put(void); struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, - struct svc_serv_ops *); + const struct svc_serv_ops *); int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); int svc_set_num_threads_sync(struct svc_serv *, struct svc_pool *, int); int svc_pool_stats_open(struct svc_serv *serv, struct file *file); diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index ddb7f94a9d06ecc48828b7b00230662b85768d64..6a2ad38f545896352ea91edb10f66ca9d44e7b93 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -31,7 +31,7 @@ struct svc_xprt_ops { struct svc_xprt_class { const char *xcl_name; struct module *xcl_owner; - struct svc_xprt_ops *xcl_ops; + const struct svc_xprt_ops *xcl_ops; struct list_head xcl_list; u32 xcl_max_payload; int xcl_ident; @@ -49,7 +49,7 @@ struct svc_xpt_user { struct svc_xprt { struct svc_xprt_class *xpt_class; - struct svc_xprt_ops *xpt_ops; + const struct svc_xprt_ops *xpt_ops; struct kref xpt_ref; struct list_head xpt_list; struct list_head xpt_ready; diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 261b48a2701d2ac01ada6bff67d4059a2633a817..86b59e3525a516d4eb0b7c80b9324ed50597c642 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -239,6 +239,19 @@ extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len); extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len); extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data); +/** + * xdr_stream_remaining - Return the number of bytes remaining in the stream + * @xdr: pointer to struct xdr_stream + * + * Return value: + * Number of bytes remaining in @xdr before xdr->end + */ +static inline size_t +xdr_stream_remaining(const struct xdr_stream *xdr) +{ + return xdr->nwords << 2; +} + ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str, size_t maxlen, gfp_t gfp_flags); /** diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index eab1c749e192b5ba37b050d5fb5592e825d61682..5a7bff41f6b70b3e60908a98f3049ec92ff5a390 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -174,7 +174,7 @@ enum xprt_transports { struct rpc_xprt { struct kref kref; /* Reference count */ - struct rpc_xprt_ops * ops; /* transport methods */ + const struct rpc_xprt_ops *ops; /* transport methods */ const struct rpc_timeout *timeout; /* timeout parms */ struct sockaddr_storage addr; /* server address */ @@ -232,6 +232,7 @@ struct rpc_xprt { */ spinlock_t transport_lock; /* lock transport info */ spinlock_t reserve_lock; /* lock slot table */ + spinlock_t recv_lock; /* lock receive list */ u32 xid; /* Next XID value to use */ struct rpc_task * snd_task; /* Task blocked in send */ struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ @@ -372,6 +373,8 @@ void xprt_write_space(struct rpc_xprt *xprt); void xprt_adjust_cwnd(struct rpc_xprt *xprt, struct rpc_task *task, int result); struct rpc_rqst * xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid); void xprt_complete_rqst(struct rpc_task *task, int copied); +void xprt_pin_rqst(struct rpc_rqst *req); +void xprt_unpin_rqst(struct rpc_rqst *req); void xprt_release_rqst_cong(struct rpc_task *task); void xprt_disconnect_done(struct rpc_xprt *xprt); void xprt_force_disconnect(struct rpc_xprt *xprt); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 0b1cf32edfd7ba1c456252124e23c68450d5bcc3..d10b7980799d5216efdb08566d01d70c1780a5fc 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -33,10 +33,10 @@ static inline void pm_restore_console(void) typedef int __bitwise suspend_state_t; #define PM_SUSPEND_ON ((__force suspend_state_t) 0) -#define PM_SUSPEND_FREEZE ((__force suspend_state_t) 1) +#define PM_SUSPEND_TO_IDLE ((__force suspend_state_t) 1) #define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2) #define PM_SUSPEND_MEM ((__force suspend_state_t) 3) -#define PM_SUSPEND_MIN PM_SUSPEND_FREEZE +#define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) enum suspend_stat_step { @@ -186,7 +186,7 @@ struct platform_suspend_ops { void (*recover)(void); }; -struct platform_freeze_ops { +struct platform_s2idle_ops { int (*begin)(void); int (*prepare)(void); void (*wake)(void); @@ -196,6 +196,9 @@ struct platform_freeze_ops { }; #ifdef CONFIG_SUSPEND +extern suspend_state_t mem_sleep_current; +extern suspend_state_t mem_sleep_default; + /** * suspend_set_ops - set platform dependent suspend operations * @ops: The new suspend operations to set. @@ -234,22 +237,22 @@ static inline bool pm_resume_via_firmware(void) } /* Suspend-to-idle state machnine. */ -enum freeze_state { - FREEZE_STATE_NONE, /* Not suspended/suspending. */ - FREEZE_STATE_ENTER, /* Enter suspend-to-idle. */ - FREEZE_STATE_WAKE, /* Wake up from suspend-to-idle. */ +enum s2idle_states { + S2IDLE_STATE_NONE, /* Not suspended/suspending. */ + S2IDLE_STATE_ENTER, /* Enter suspend-to-idle. */ + S2IDLE_STATE_WAKE, /* Wake up from suspend-to-idle. */ }; -extern enum freeze_state __read_mostly suspend_freeze_state; +extern enum s2idle_states __read_mostly s2idle_state; -static inline bool idle_should_freeze(void) +static inline bool idle_should_enter_s2idle(void) { - return unlikely(suspend_freeze_state == FREEZE_STATE_ENTER); + return unlikely(s2idle_state == S2IDLE_STATE_ENTER); } extern void __init pm_states_init(void); -extern void freeze_set_ops(const struct platform_freeze_ops *ops); -extern void freeze_wake(void); +extern void s2idle_set_ops(const struct platform_s2idle_ops *ops); +extern void s2idle_wake(void); /** * arch_suspend_disable_irqs - disable IRQs for suspend @@ -281,10 +284,10 @@ static inline bool pm_resume_via_firmware(void) { return false; } static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {} static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } -static inline bool idle_should_freeze(void) { return false; } +static inline bool idle_should_enter_s2idle(void) { return false; } static inline void __init pm_states_init(void) {} -static inline void freeze_set_ops(const struct platform_freeze_ops *ops) {} -static inline void freeze_wake(void) {} +static inline void s2idle_set_ops(const struct platform_s2idle_ops *ops) {} +static inline void s2idle_wake(void) {} #endif /* !CONFIG_SUSPEND */ /* struct pbe is used for creating lists of pages that should be restored @@ -427,6 +430,7 @@ extern int unregister_pm_notifier(struct notifier_block *nb); /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; extern unsigned int pm_wakeup_irq; +extern suspend_state_t pm_suspend_target_state; extern bool pm_wakeup_pending(void); extern void pm_system_wakeup(void); @@ -491,10 +495,24 @@ static inline void unlock_system_sleep(void) {} #ifdef CONFIG_PM_SLEEP_DEBUG extern bool pm_print_times_enabled; +extern bool pm_debug_messages_on; +extern __printf(2, 3) void __pm_pr_dbg(bool defer, const char *fmt, ...); #else #define pm_print_times_enabled (false) +#define pm_debug_messages_on (false) + +#include + +#define __pm_pr_dbg(defer, fmt, ...) \ + no_printk(KERN_DEBUG fmt, ##__VA_ARGS__) #endif +#define pm_pr_dbg(fmt, ...) \ + __pm_pr_dbg(false, fmt, ##__VA_ARGS__) + +#define pm_deferred_pr_dbg(fmt, ...) \ + __pm_pr_dbg(true, fmt, ##__VA_ARGS__) + #ifdef CONFIG_PM_AUTOSLEEP /* kernel/power/autosleep.c */ diff --git a/include/linux/swait.h b/include/linux/swait.h index c1f9c62a8a507d1b4bfde42c0201cefabdef7675..73e97a08d3d0a9be1e5467b11d1b0a0ad235b063 100644 --- a/include/linux/swait.h +++ b/include/linux/swait.h @@ -79,9 +79,63 @@ extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name DECLARE_SWAIT_QUEUE_HEAD(name) #endif -static inline int swait_active(struct swait_queue_head *q) +/** + * swait_active -- locklessly test for waiters on the queue + * @wq: the waitqueue to test for waiters + * + * returns true if the wait list is not empty + * + * NOTE: this function is lockless and requires care, incorrect usage _will_ + * lead to sporadic and non-obvious failure. + * + * NOTE2: this function has the same above implications as regular waitqueues. + * + * Use either while holding swait_queue_head::lock or when used for wakeups + * with an extra smp_mb() like: + * + * CPU0 - waker CPU1 - waiter + * + * for (;;) { + * @cond = true; prepare_to_swait(&wq_head, &wait, state); + * smp_mb(); // smp_mb() from set_current_state() + * if (swait_active(wq_head)) if (@cond) + * wake_up(wq_head); break; + * schedule(); + * } + * finish_swait(&wq_head, &wait); + * + * Because without the explicit smp_mb() it's possible for the + * swait_active() load to get hoisted over the @cond store such that we'll + * observe an empty wait list while the waiter might not observe @cond. + * This, in turn, can trigger missing wakeups. + * + * Also note that this 'optimization' trades a spin_lock() for an smp_mb(), + * which (when the lock is uncontended) are of roughly equal cost. + */ +static inline int swait_active(struct swait_queue_head *wq) { - return !list_empty(&q->task_list); + return !list_empty(&wq->task_list); +} + +/** + * swq_has_sleeper - check if there are any waiting processes + * @wq: the waitqueue to test for waiters + * + * Returns true if @wq has waiting processes + * + * Please refer to the comment for swait_active. + */ +static inline bool swq_has_sleeper(struct swait_queue_head *wq) +{ + /* + * We need to be sure we are in sync with the list_add() + * modifications to the wait queue (task_list). + * + * This memory barrier should be paired with one on the + * waiting side. + */ + smp_mb(); + return swait_active(wq); } extern void swake_up(struct swait_queue_head *q); @@ -169,4 +223,59 @@ do { \ __ret; \ }) +#define __swait_event_idle(wq, condition) \ + (void)___swait_event(wq, condition, TASK_IDLE, 0, schedule()) + +/** + * swait_event_idle - wait without system load contribution + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * + * The process is put to sleep (TASK_IDLE) until the @condition evaluates to + * true. The @condition is checked each time the waitqueue @wq is woken up. + * + * This function is mostly used when a kthread or workqueue waits for some + * condition and doesn't want to contribute to system load. Signals are + * ignored. + */ +#define swait_event_idle(wq, condition) \ +do { \ + if (condition) \ + break; \ + __swait_event_idle(wq, condition); \ +} while (0) + +#define __swait_event_idle_timeout(wq, condition, timeout) \ + ___swait_event(wq, ___wait_cond_timeout(condition), \ + TASK_IDLE, timeout, \ + __ret = schedule_timeout(__ret)) + +/** + * swait_event_idle_timeout - wait up to timeout without load contribution + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * @timeout: timeout at which we'll give up in jiffies + * + * The process is put to sleep (TASK_IDLE) until the @condition evaluates to + * true. The @condition is checked each time the waitqueue @wq is woken up. + * + * This function is mostly used when a kthread or workqueue waits for some + * condition and doesn't want to contribute to system load. Signals are + * ignored. + * + * Returns: + * 0 if the @condition evaluated to %false after the @timeout elapsed, + * 1 if the @condition evaluated to %true after the @timeout elapsed, + * or the remaining jiffies (at least 1) if the @condition evaluated + * to %true before the @timeout elapsed. + */ +#define swait_event_idle_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!___wait_cond_timeout(condition)) \ + __ret = __swait_event_idle_timeout(wq, \ + condition, timeout); \ + __ret; \ +}) + #endif /* _LINUX_SWAIT_H */ diff --git a/include/linux/swap.h b/include/linux/swap.h index d83d28e53e6231a8d5421d055a1b2b6548d07ea3..8a807292037f9ff956980260ba61c0c4c22dd07f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -50,6 +50,23 @@ static inline int current_is_kswapd(void) * actions on faults. */ +/* + * Unaddressable device memory support. See include/linux/hmm.h and + * Documentation/vm/hmm.txt. Short description is we need struct pages for + * device memory that is unaddressable (inaccessible) by CPU, so that we can + * migrate part of a process memory to device memory. + * + * When a page is migrated from CPU to device, we set the CPU page table entry + * to a special SWP_DEVICE_* entry. + */ +#ifdef CONFIG_DEVICE_PRIVATE +#define SWP_DEVICE_NUM 2 +#define SWP_DEVICE_WRITE (MAX_SWAPFILES+SWP_HWPOISON_NUM+SWP_MIGRATION_NUM) +#define SWP_DEVICE_READ (MAX_SWAPFILES+SWP_HWPOISON_NUM+SWP_MIGRATION_NUM+1) +#else +#define SWP_DEVICE_NUM 0 +#endif + /* * NUMA node memory migration support */ @@ -72,7 +89,8 @@ static inline int current_is_kswapd(void) #endif #define MAX_SWAPFILES \ - ((1 << MAX_SWAPFILES_SHIFT) - SWP_MIGRATION_NUM - SWP_HWPOISON_NUM) + ((1 << MAX_SWAPFILES_SHIFT) - SWP_DEVICE_NUM - \ + SWP_MIGRATION_NUM - SWP_HWPOISON_NUM) /* * Magic header for a swap area. The first part of the union is @@ -188,6 +206,7 @@ struct swap_cluster_info { }; #define CLUSTER_FLAG_FREE 1 /* This cluster is free */ #define CLUSTER_FLAG_NEXT_NULL 2 /* This cluster has no next cluster */ +#define CLUSTER_FLAG_HUGE 4 /* This cluster is backing a transparent huge page */ /* * We assign a cluster to each CPU, so each CPU can allocate swap entry from @@ -211,7 +230,7 @@ struct swap_info_struct { unsigned long flags; /* SWP_USED etc: see above */ signed short prio; /* swap priority of this type */ struct plist_node list; /* entry in swap_active_head */ - struct plist_node avail_list; /* entry in swap_avail_head */ + struct plist_node avail_lists[MAX_NUMNODES];/* entry in swap_avail_heads */ signed char type; /* strange name for an index */ unsigned int max; /* extent of the swap_map */ unsigned char *swap_map; /* vmalloc'ed array of usage counts */ @@ -250,6 +269,25 @@ struct swap_info_struct { struct swap_cluster_list discard_clusters; /* discard clusters list */ }; +#ifdef CONFIG_64BIT +#define SWAP_RA_ORDER_CEILING 5 +#else +/* Avoid stack overflow, because we need to save part of page table */ +#define SWAP_RA_ORDER_CEILING 3 +#define SWAP_RA_PTE_CACHE_SIZE (1 << SWAP_RA_ORDER_CEILING) +#endif + +struct vma_swap_readahead { + unsigned short win; + unsigned short offset; + unsigned short nr_pte; +#ifdef CONFIG_64BIT + pte_t *ptes; +#else + pte_t ptes[SWAP_RA_PTE_CACHE_SIZE]; +#endif +}; + /* linux/mm/workingset.c */ void *workingset_eviction(struct address_space *mapping, struct page *page); bool workingset_refault(void *shadow); @@ -262,8 +300,8 @@ extern unsigned long totalreserve_pages; extern unsigned long nr_free_buffer_pages(void); extern unsigned long nr_free_pagecache_pages(void); -/* Definition of global_page_state not available yet */ -#define nr_free_pages() global_page_state(NR_FREE_PAGES) +/* Definition of global_zone_page_state not available yet */ +#define nr_free_pages() global_zone_page_state(NR_FREE_PAGES) /* linux/mm/swap.c */ @@ -349,6 +387,7 @@ int generic_swapfile_activate(struct swap_info_struct *, struct file *, #define SWAP_ADDRESS_SPACE_SHIFT 14 #define SWAP_ADDRESS_SPACE_PAGES (1 << SWAP_ADDRESS_SPACE_SHIFT) extern struct address_space *swapper_spaces[]; +extern bool swap_vma_readahead; #define swap_address_space(entry) \ (&swapper_spaces[swp_type(entry)][swp_offset(entry) \ >> SWAP_ADDRESS_SPACE_SHIFT]) @@ -361,7 +400,9 @@ extern void __delete_from_swap_cache(struct page *); extern void delete_from_swap_cache(struct page *); extern void free_page_and_swap_cache(struct page *); extern void free_pages_and_swap_cache(struct page **, int); -extern struct page *lookup_swap_cache(swp_entry_t); +extern struct page *lookup_swap_cache(swp_entry_t entry, + struct vm_area_struct *vma, + unsigned long addr); extern struct page *read_swap_cache_async(swp_entry_t, gfp_t, struct vm_area_struct *vma, unsigned long addr, bool do_poll); @@ -371,11 +412,23 @@ extern struct page *__read_swap_cache_async(swp_entry_t, gfp_t, extern struct page *swapin_readahead(swp_entry_t, gfp_t, struct vm_area_struct *vma, unsigned long addr); +extern struct page *swap_readahead_detect(struct vm_fault *vmf, + struct vma_swap_readahead *swap_ra); +extern struct page *do_swap_page_readahead(swp_entry_t fentry, gfp_t gfp_mask, + struct vm_fault *vmf, + struct vma_swap_readahead *swap_ra); + /* linux/mm/swapfile.c */ extern atomic_long_t nr_swap_pages; extern long total_swap_pages; +extern atomic_t nr_rotate_swap; extern bool has_usable_swap(void); +static inline bool swap_use_vma_readahead(void) +{ + return READ_ONCE(swap_vma_readahead) && !atomic_read(&nr_rotate_swap); +} + /* Swap 50% full? Release swapcache more aggressively.. */ static inline bool vm_swap_full(void) { @@ -434,8 +487,8 @@ static inline void show_swap_cache_info(void) { } -#define free_swap_and_cache(swp) is_migration_entry(swp) -#define swapcache_prepare(swp) is_migration_entry(swp) +#define free_swap_and_cache(e) ({(is_migration_entry(e) || is_device_private_entry(e));}) +#define swapcache_prepare(e) ({(is_migration_entry(e) || is_device_private_entry(e));}) static inline int add_swap_count_continuation(swp_entry_t swp, gfp_t gfp_mask) { @@ -465,12 +518,32 @@ static inline struct page *swapin_readahead(swp_entry_t swp, gfp_t gfp_mask, return NULL; } +static inline bool swap_use_vma_readahead(void) +{ + return false; +} + +static inline struct page *swap_readahead_detect( + struct vm_fault *vmf, struct vma_swap_readahead *swap_ra) +{ + return NULL; +} + +static inline struct page *do_swap_page_readahead( + swp_entry_t fentry, gfp_t gfp_mask, + struct vm_fault *vmf, struct vma_swap_readahead *swap_ra) +{ + return NULL; +} + static inline int swap_writepage(struct page *p, struct writeback_control *wbc) { return 0; } -static inline struct page *lookup_swap_cache(swp_entry_t swp) +static inline struct page *lookup_swap_cache(swp_entry_t swp, + struct vm_area_struct *vma, + unsigned long addr) { return NULL; } @@ -509,8 +582,8 @@ static inline int swp_swapcount(swp_entry_t entry) return 0; } -#define reuse_swap_page(page, total_mapcount) \ - (page_trans_huge_mapcount(page, total_mapcount) == 1) +#define reuse_swap_page(page, total_map_swapcount) \ + (page_trans_huge_mapcount(page, total_map_swapcount) == 1) static inline int try_to_free_swap(struct page *page) { @@ -526,6 +599,15 @@ static inline swp_entry_t get_swap_page(struct page *page) #endif /* CONFIG_SWAP */ +#ifdef CONFIG_THP_SWAP +extern int split_swap_cluster(swp_entry_t entry); +#else +static inline int split_swap_cluster(swp_entry_t entry) +{ + return 0; +} +#endif + #ifdef CONFIG_MEMCG static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg) { diff --git a/include/linux/swapops.h b/include/linux/swapops.h index c5ff7b217ee6e1ba8d011e301e742fdce9bb0a32..291c4b53465819293aaa9c25bbed1b932f449f1f 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -100,10 +100,79 @@ static inline void *swp_to_radix_entry(swp_entry_t entry) return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY); } +#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) +static inline swp_entry_t make_device_private_entry(struct page *page, bool write) +{ + return swp_entry(write ? SWP_DEVICE_WRITE : SWP_DEVICE_READ, + page_to_pfn(page)); +} + +static inline bool is_device_private_entry(swp_entry_t entry) +{ + int type = swp_type(entry); + return type == SWP_DEVICE_READ || type == SWP_DEVICE_WRITE; +} + +static inline void make_device_private_entry_read(swp_entry_t *entry) +{ + *entry = swp_entry(SWP_DEVICE_READ, swp_offset(*entry)); +} + +static inline bool is_write_device_private_entry(swp_entry_t entry) +{ + return unlikely(swp_type(entry) == SWP_DEVICE_WRITE); +} + +static inline struct page *device_private_entry_to_page(swp_entry_t entry) +{ + return pfn_to_page(swp_offset(entry)); +} + +int device_private_entry_fault(struct vm_area_struct *vma, + unsigned long addr, + swp_entry_t entry, + unsigned int flags, + pmd_t *pmdp); +#else /* CONFIG_DEVICE_PRIVATE */ +static inline swp_entry_t make_device_private_entry(struct page *page, bool write) +{ + return swp_entry(0, 0); +} + +static inline void make_device_private_entry_read(swp_entry_t *entry) +{ +} + +static inline bool is_device_private_entry(swp_entry_t entry) +{ + return false; +} + +static inline bool is_write_device_private_entry(swp_entry_t entry) +{ + return false; +} + +static inline struct page *device_private_entry_to_page(swp_entry_t entry) +{ + return NULL; +} + +static inline int device_private_entry_fault(struct vm_area_struct *vma, + unsigned long addr, + swp_entry_t entry, + unsigned int flags, + pmd_t *pmdp) +{ + return VM_FAULT_SIGBUS; +} +#endif /* CONFIG_DEVICE_PRIVATE */ + #ifdef CONFIG_MIGRATION static inline swp_entry_t make_migration_entry(struct page *page, int write) { - BUG_ON(!PageLocked(page)); + BUG_ON(!PageLocked(compound_head(page))); + return swp_entry(write ? SWP_MIGRATION_WRITE : SWP_MIGRATION_READ, page_to_pfn(page)); } @@ -126,7 +195,7 @@ static inline struct page *migration_entry_to_page(swp_entry_t entry) * Any use of migration entries may only occur while the * corresponding page is locked */ - BUG_ON(!PageLocked(p)); + BUG_ON(!PageLocked(compound_head(p))); return p; } @@ -148,7 +217,11 @@ static inline int is_migration_entry(swp_entry_t swp) { return 0; } -#define migration_entry_to_page(swp) NULL +static inline struct page *migration_entry_to_page(swp_entry_t entry) +{ + return NULL; +} + static inline void make_migration_entry_read(swp_entry_t *entryp) { } static inline void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, spinlock_t *ptl) { } @@ -163,6 +236,70 @@ static inline int is_write_migration_entry(swp_entry_t entry) #endif +struct page_vma_mapped_walk; + +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +extern void set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, + struct page *page); + +extern void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, + struct page *new); + +extern void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd); + +static inline swp_entry_t pmd_to_swp_entry(pmd_t pmd) +{ + swp_entry_t arch_entry; + + if (pmd_swp_soft_dirty(pmd)) + pmd = pmd_swp_clear_soft_dirty(pmd); + arch_entry = __pmd_to_swp_entry(pmd); + return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry)); +} + +static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) +{ + swp_entry_t arch_entry; + + arch_entry = __swp_entry(swp_type(entry), swp_offset(entry)); + return __swp_entry_to_pmd(arch_entry); +} + +static inline int is_pmd_migration_entry(pmd_t pmd) +{ + return !pmd_present(pmd) && is_migration_entry(pmd_to_swp_entry(pmd)); +} +#else +static inline void set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, + struct page *page) +{ + BUILD_BUG(); +} + +static inline void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, + struct page *new) +{ + BUILD_BUG(); +} + +static inline void pmd_migration_entry_wait(struct mm_struct *m, pmd_t *p) { } + +static inline swp_entry_t pmd_to_swp_entry(pmd_t pmd) +{ + return swp_entry(0, 0); +} + +static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) +{ + return __pmd(0); +} + +static inline int is_pmd_migration_entry(pmd_t pmd) +{ + return 0; +} +#endif + #ifdef CONFIG_MEMORY_FAILURE extern atomic_long_t num_poisoned_pages __read_mostly; diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 4ee479f2f355b1fa2658b1c2aabbdfc376125651..15e7160751a85a4be938f860257d05595b03105d 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -35,6 +35,7 @@ int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); extern unsigned long swiotlb_nr_tbl(void); unsigned long swiotlb_size_or_default(void); extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); +extern void __init swiotlb_update_mem_attributes(void); /* * Enumeration for sync targets diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h index 5726107963b2d9930d61c3cf5c486abfe244c18a..0ad87c434ae6a344984837e8dd053fe7705d21f1 100644 --- a/include/linux/sync_file.h +++ b/include/linux/sync_file.h @@ -43,12 +43,13 @@ struct sync_file { #endif wait_queue_head_t wq; + unsigned long flags; struct dma_fence *fence; struct dma_fence_cb cb; }; -#define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS +#define POLL_ENABLED 0 struct sync_file *sync_file_create(struct dma_fence *fence); struct dma_fence *sync_file_get_fence(int fd); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 3cb15ea48aeea8414beed8cdd11d1ece13f71d0d..a78186d826d7963d99f168908f4a5ec386de04e1 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -100,11 +100,12 @@ union bpf_attr; #define __MAP(n,...) __MAP##n(__VA_ARGS__) #define __SC_DECL(t, a) t a -#define __TYPE_IS_L(t) (__same_type((t)0, 0L)) -#define __TYPE_IS_UL(t) (__same_type((t)0, 0UL)) -#define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL)) +#define __TYPE_AS(t, v) __same_type((__force t)0, v) +#define __TYPE_IS_L(t) (__TYPE_AS(t, 0L)) +#define __TYPE_IS_UL(t) (__TYPE_AS(t, 0UL)) +#define __TYPE_IS_LL(t) (__TYPE_AS(t, 0LL) || __TYPE_AS(t, 0ULL)) #define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a -#define __SC_CAST(t, a) (t) a +#define __SC_CAST(t, a) (__force t) a #define __SC_ARGS(t, a) a #define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long)) @@ -172,8 +173,20 @@ extern struct trace_event_functions exit_syscall_print_funcs; static struct syscall_metadata __used \ __attribute__((section("__syscalls_metadata"))) \ *__p_syscall_meta_##sname = &__syscall_meta_##sname; + +static inline int is_syscall_trace_event(struct trace_event_call *tp_event) +{ + return tp_event->class == &event_class_syscall_enter || + tp_event->class == &event_class_syscall_exit; +} + #else #define SYSCALL_METADATA(sname, nb, ...) + +static inline int is_syscall_trace_event(struct trace_event_call *tp_event) +{ + return 0; +} #endif #define SYSCALL_DEFINE0(sname) \ @@ -187,6 +200,8 @@ extern struct trace_event_functions exit_syscall_print_funcs; #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE_MAXARGS 6 + #define SYSCALL_DEFINEx(x, sname, ...) \ SYSCALL_METADATA(sname, x, __VA_ARGS__) \ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) @@ -206,6 +221,26 @@ extern struct trace_event_functions exit_syscall_print_funcs; } \ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) +/* + * Called before coming back to user-mode. Returning to user-mode with an + * address limit different than USER_DS can allow to overwrite kernel memory. + */ +static inline void addr_limit_user_check(void) +{ +#ifdef TIF_FSCHECK + if (!test_thread_flag(TIF_FSCHECK)) + return; +#endif + + if (CHECK_DATA_CORRUPTION(!segment_eq(get_fs(), USER_DS), + "Invalid address limit on user-mode return")) + force_sig(SIGKILL, current); + +#ifdef TIF_FSCHECK + clear_thread_flag(TIF_FSCHECK); +#endif +} + asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, qid_t id, void __user *addr); asmlinkage long sys_time(time_t __user *tloc); @@ -578,12 +613,12 @@ asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h); asmlinkage long sys_preadv2(unsigned long fd, const struct iovec __user *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h, - int flags); + rwf_t flags); asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h); asmlinkage long sys_pwritev2(unsigned long fd, const struct iovec __user *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h, - int flags); + rwf_t flags); asmlinkage long sys_getcwd(char __user *buf, unsigned long size); asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode); asmlinkage long sys_chdir(const char __user *filename); diff --git a/include/linux/syslog.h b/include/linux/syslog.h index c3a7f0cc3a275f711a0a41660825b00b2ae535f8..e1c3632f4e81929bfde11b0f5f699482dc757d94 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h @@ -49,13 +49,4 @@ int do_syslog(int type, char __user *buf, int count, int source); -#ifdef CONFIG_PRINTK -int check_syslog_permissions(int type, int source); -#else -static inline int check_syslog_permissions(int type, int source) -{ - return 0; -} -#endif - #endif /* _LINUX_SYSLOG_H */ diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 542ca1ae02c4f64833b287c0fd744283ee518909..4aa40ef02d32cf2719513ca77c38f45a5e646b82 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -192,15 +192,6 @@ struct tcp_sock { struct list_head tsq_node; /* anchor in tsq_tasklet.head list */ - /* Data for direct copy to user */ - struct { - struct sk_buff_head prequeue; - struct task_struct *task; - struct msghdr *msg; - int memory; - int len; - } ucopy; - u32 snd_wl1; /* Sequence for window update */ u32 snd_wnd; /* The window we expect to receive */ u32 max_window; /* Maximal window ever seen from peer */ @@ -273,7 +264,7 @@ struct tcp_sock { u32 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */ u32 snd_cwnd_used; u32 snd_cwnd_stamp; - u32 prior_cwnd; /* Congestion window at start of Recovery. */ + u32 prior_cwnd; /* cwnd right before starting loss recovery */ u32 prr_delivered; /* Number of newly delivered packets to * receiver in Recovery. */ u32 prr_out; /* Total number of pkts sent during Recovery. */ diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 0f175b8f6456c1d5ad14538deb66b9c3a9f3c5c7..cb889afe576b34db3c4293fa431c1eab28dcc4de 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -28,6 +28,7 @@ #define TEE_SHM_MAPPED 0x1 /* Memory mapped by the kernel */ #define TEE_SHM_DMA_BUF 0x2 /* Memory with dma-buf handle */ +struct device; struct tee_device; struct tee_shm; struct tee_shm_pool; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index dab11f97e1c6377cd9bf4af142a5bcd5b64c024e..fd5b959c753c5340f3eaa58da5b752fea2908e84 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -102,6 +102,7 @@ enum thermal_notify_event { THERMAL_DEVICE_DOWN, /* Thermal device is down */ THERMAL_DEVICE_UP, /* Thermal device is up after a down event */ THERMAL_DEVICE_POWER_CAPABILITY_CHANGED, /* power capability changed */ + THERMAL_TABLE_CHANGED, /* Thermal table(s) changed */ }; struct thermal_zone_device_ops { diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 250a27614328471e4a805884a952881116a14c3e..905d769d8ddcfdbf9657371dda29744bcedb53f5 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -38,6 +38,10 @@ enum { #ifdef __KERNEL__ +#ifndef THREAD_ALIGN +#define THREAD_ALIGN THREAD_SIZE +#endif + #ifdef CONFIG_DEBUG_STACK_USAGE # define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \ __GFP_ZERO) diff --git a/include/linux/time.h b/include/linux/time.h index 4abb32d4c6b853fa3030703d9458689b875e713c..9bc1f945777cdefb2ce787eacf59abc1dd42e796 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -178,7 +178,7 @@ extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue); extern int do_getitimer(int which, struct itimerval *value); -extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); +extern long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags); /* * Similar to the struct tm in userspace , but it needs to be here so @@ -285,4 +285,19 @@ static inline bool itimerspec64_valid(const struct itimerspec64 *its) return true; } +/** + * time_after32 - compare two 32-bit relative times + * @a: the time which may be after @b + * @b: the time which may be before @a + * + * time_after32(a, b) returns true if the time @a is after time @b. + * time_before32(b, a) returns true if the time @b is before time @a. + * + * Similar to time_after(), compare two 32-bit timestamps for relative + * times. This is useful for comparing 32-bit seconds values that can't + * be converted to 64-bit values (e.g. due to disk format or wire protocol + * issues) when it is known that the times are less than 68 years apart. + */ +#define time_after32(a, b) ((s32)((u32)(b) - (u32)(a)) < 0) +#define time_before32(b, a) time_after32(a, b) #endif diff --git a/include/linux/timer.h b/include/linux/timer.h index e6789b8757d5021439c332751e52726bde83bec1..6383c528b1484fed5731b3074e1d1accf414ff31 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -168,6 +168,20 @@ static inline void init_timer_on_stack_key(struct timer_list *timer, #define setup_pinned_deferrable_timer_on_stack(timer, fn, data) \ __setup_timer_on_stack((timer), (fn), (data), TIMER_DEFERRABLE | TIMER_PINNED) +#define TIMER_DATA_TYPE unsigned long +#define TIMER_FUNC_TYPE void (*)(TIMER_DATA_TYPE) + +static inline void timer_setup(struct timer_list *timer, + void (*callback)(struct timer_list *), + unsigned int flags) +{ + __setup_timer(timer, (TIMER_FUNC_TYPE)callback, + (TIMER_DATA_TYPE)timer, flags); +} + +#define from_timer(var, callback_timer, timer_fieldname) \ + container_of(callback_timer, typeof(*var), timer_fieldname) + /** * timer_pending - is a timer pending? * @timer: the timer in question diff --git a/include/linux/tnum.h b/include/linux/tnum.h new file mode 100644 index 0000000000000000000000000000000000000000..0d2d3da461397017753231edf208438d6f18b482 --- /dev/null +++ b/include/linux/tnum.h @@ -0,0 +1,81 @@ +/* tnum: tracked (or tristate) numbers + * + * A tnum tracks knowledge about the bits of a value. Each bit can be either + * known (0 or 1), or unknown (x). Arithmetic operations on tnums will + * propagate the unknown bits such that the tnum result represents all the + * possible results for possible values of the operands. + */ +#include + +struct tnum { + u64 value; + u64 mask; +}; + +/* Constructors */ +/* Represent a known constant as a tnum. */ +struct tnum tnum_const(u64 value); +/* A completely unknown value */ +extern const struct tnum tnum_unknown; +/* A value that's unknown except that @min <= value <= @max */ +struct tnum tnum_range(u64 min, u64 max); + +/* Arithmetic and logical ops */ +/* Shift a tnum left (by a fixed shift) */ +struct tnum tnum_lshift(struct tnum a, u8 shift); +/* Shift a tnum right (by a fixed shift) */ +struct tnum tnum_rshift(struct tnum a, u8 shift); +/* Add two tnums, return @a + @b */ +struct tnum tnum_add(struct tnum a, struct tnum b); +/* Subtract two tnums, return @a - @b */ +struct tnum tnum_sub(struct tnum a, struct tnum b); +/* Bitwise-AND, return @a & @b */ +struct tnum tnum_and(struct tnum a, struct tnum b); +/* Bitwise-OR, return @a | @b */ +struct tnum tnum_or(struct tnum a, struct tnum b); +/* Bitwise-XOR, return @a ^ @b */ +struct tnum tnum_xor(struct tnum a, struct tnum b); +/* Multiply two tnums, return @a * @b */ +struct tnum tnum_mul(struct tnum a, struct tnum b); + +/* Return a tnum representing numbers satisfying both @a and @b */ +struct tnum tnum_intersect(struct tnum a, struct tnum b); + +/* Return @a with all but the lowest @size bytes cleared */ +struct tnum tnum_cast(struct tnum a, u8 size); + +/* Returns true if @a is a known constant */ +static inline bool tnum_is_const(struct tnum a) +{ + return !a.mask; +} + +/* Returns true if @a == tnum_const(@b) */ +static inline bool tnum_equals_const(struct tnum a, u64 b) +{ + return tnum_is_const(a) && a.value == b; +} + +/* Returns true if @a is completely unknown */ +static inline bool tnum_is_unknown(struct tnum a) +{ + return !~a.mask; +} + +/* Returns true if @a is known to be a multiple of @size. + * @size must be a power of two. + */ +bool tnum_is_aligned(struct tnum a, u64 size); + +/* Returns true if @b represents a subset of @a. */ +bool tnum_in(struct tnum a, struct tnum b); + +/* Formatting functions. These have snprintf-like semantics: they will write + * up to @size bytes (including the terminating NUL byte), and return the number + * of bytes (excluding the terminating NUL) which would have been written had + * sufficient space been available. (Thus tnum_sbin always returns 64.) + */ +/* Format a tnum as a pair of hex numbers (value; mask) */ +int tnum_strn(char *str, size_t size, struct tnum a); +/* Format a tnum as tristate binary expansion */ +int tnum_sbin(char *str, size_t size, struct tnum a); diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 536c80ff7ad96680ddcca0a7880cd7df81c57f17..2e0f22298fe952748edbc68b35d5e3435335e53a 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -217,7 +217,6 @@ enum { TRACE_EVENT_FL_CAP_ANY_BIT, TRACE_EVENT_FL_NO_SET_FILTER_BIT, TRACE_EVENT_FL_IGNORE_ENABLE_BIT, - TRACE_EVENT_FL_WAS_ENABLED_BIT, TRACE_EVENT_FL_TRACEPOINT_BIT, TRACE_EVENT_FL_KPROBE_BIT, TRACE_EVENT_FL_UPROBE_BIT, @@ -229,9 +228,6 @@ enum { * CAP_ANY - Any user can enable for perf * NO_SET_FILTER - Set when filter has error and is to be ignored * IGNORE_ENABLE - For trace internal events, do not enable with debugfs file - * WAS_ENABLED - Set and stays set when an event was ever enabled - * (used for module unloading, if a module event is enabled, - * it is best to clear the buffers that used it). * TRACEPOINT - Event is a tracepoint * KPROBE - Event is a kprobe * UPROBE - Event is a uprobe @@ -241,7 +237,6 @@ enum { TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), - TRACE_EVENT_FL_WAS_ENABLED = (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT), TRACE_EVENT_FL_TRACEPOINT = (1 << TRACE_EVENT_FL_TRACEPOINT_BIT), TRACE_EVENT_FL_KPROBE = (1 << TRACE_EVENT_FL_KPROBE_BIT), TRACE_EVENT_FL_UPROBE = (1 << TRACE_EVENT_FL_UPROBE_BIT), @@ -277,6 +272,7 @@ struct trace_event_call { int perf_refcount; struct hlist_head __percpu *perf_events; struct bpf_prog *prog; + struct perf_event *bpf_prog_owner; int (*perf_perm)(struct trace_event_call *, struct perf_event *); @@ -306,6 +302,7 @@ enum { EVENT_FILE_FL_TRIGGER_MODE_BIT, EVENT_FILE_FL_TRIGGER_COND_BIT, EVENT_FILE_FL_PID_FILTER_BIT, + EVENT_FILE_FL_WAS_ENABLED_BIT, }; /* @@ -321,6 +318,7 @@ enum { * TRIGGER_MODE - When set, invoke the triggers associated with the event * TRIGGER_COND - When set, one or more triggers has an associated filter * PID_FILTER - When set, the event is filtered based on pid + * WAS_ENABLED - Set when enabled to know to clear trace on module removal */ enum { EVENT_FILE_FL_ENABLED = (1 << EVENT_FILE_FL_ENABLED_BIT), @@ -333,6 +331,7 @@ enum { EVENT_FILE_FL_TRIGGER_MODE = (1 << EVENT_FILE_FL_TRIGGER_MODE_BIT), EVENT_FILE_FL_TRIGGER_COND = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT), EVENT_FILE_FL_PID_FILTER = (1 << EVENT_FILE_FL_PID_FILTER_BIT), + EVENT_FILE_FL_WAS_ENABLED = (1 << EVENT_FILE_FL_WAS_ENABLED_BIT), }; struct trace_event_file { @@ -508,9 +507,9 @@ void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx, static inline void perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type, u64 count, struct pt_regs *regs, void *head, - struct task_struct *task) + struct task_struct *task, struct perf_event *event) { - perf_tp_event(type, count, raw_data, size, regs, head, rctx, task); + perf_tp_event(type, count, raw_data, size, regs, head, rctx, task, event); } #endif diff --git a/include/linux/tty.h b/include/linux/tty.h index 79c30daf46a92160d7560bcc44acdb785b672631..cf53eb539f6e4f88fd8da8800ef0cf28840cf5af 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -261,6 +261,8 @@ struct tty_port { */ #define TTY_PORT_CTS_FLOW 3 /* h/w flow control enabled */ #define TTY_PORT_CHECK_CD 4 /* carrier detect enabled */ +#define TTY_PORT_KOPENED 5 /* device exclusively opened by + kernel */ /* * Where all of the state associated with a tty is kept while the tty @@ -399,8 +401,8 @@ extern struct tty_struct *get_current_tty(void); /* tty_io.c */ extern int __init tty_init(void); extern const char *tty_name(const struct tty_struct *tty); -extern struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, - struct file *filp); +extern struct tty_struct *tty_kopen(dev_t device); +extern void tty_kclose(struct tty_struct *tty); extern int tty_dev_name_to_number(const char *name, dev_t *number); #else static inline void tty_kref_put(struct tty_struct *tty) @@ -422,9 +424,10 @@ static inline int __init tty_init(void) { return 0; } static inline const char *tty_name(const struct tty_struct *tty) { return "(none)"; } -static inline struct tty_struct *tty_open_by_driver(dev_t device, - struct inode *inode, struct file *filp) -{ return NULL; } +static inline struct tty_struct *tty_kopen(dev_t device) +{ return ERR_PTR(-ENODEV); } +static inline void tty_kclose(struct tty_struct *tty) +{ } static inline int tty_dev_name_to_number(const char *name, dev_t *number) { return -ENOTSUPP; } #endif @@ -652,6 +655,19 @@ static inline void tty_port_set_initialized(struct tty_port *port, bool val) clear_bit(TTY_PORT_INITIALIZED, &port->iflags); } +static inline bool tty_port_kopened(struct tty_port *port) +{ + return test_bit(TTY_PORT_KOPENED, &port->iflags); +} + +static inline void tty_port_set_kopened(struct tty_port *port, bool val) +{ + if (val) + set_bit(TTY_PORT_KOPENED, &port->iflags); + else + clear_bit(TTY_PORT_KOPENED, &port->iflags); +} + extern struct tty_struct *tty_port_tty_get(struct tty_port *port); extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); extern int tty_port_carrier_raised(struct tty_port *port); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 00b2213f6a35564974d5be7ac7ba909c464d3e01..fcdc0f5d90988f8d3073eeb91d17857f86b25a62 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -243,6 +243,7 @@ #include #include #include +#include struct tty_struct; struct tty_driver; @@ -285,6 +286,7 @@ struct tty_operations { int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); + void (*show_fdinfo)(struct tty_struct *tty, struct seq_file *m); #ifdef CONFIG_CONSOLE_POLL int (*poll_init)(struct tty_driver *driver, int line, char *options); int (*poll_get_char)(struct tty_driver *driver, int line); diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index c28dd523f96e655fcd89dd4bcb4ab200255cbb54..d43837f2ce3ae6ae530473d8f6be6ba5c5d1ff9b 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, size_t size); extern void tty_flip_buffer_push(struct tty_port *port); void tty_schedule_flip(struct tty_port *port); +int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag); static inline int tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) @@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(struct tty_port *port, *char_buf_ptr(tb, tb->used++) = ch; return 1; } - return tty_insert_flip_string_flags(port, &ch, &flag, 1); + return __tty_insert_flip_char(port, ch, flag); } static inline int tty_insert_flip_string(struct tty_port *port, diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index acdd6f915a8d3d1185d8a13e587824313a5dd14f..20ef8e6ec2db93fc2c160f8697ef810385c5bcf2 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -156,7 +156,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n) } #ifdef CONFIG_COMPAT static __always_inline unsigned long __must_check -copy_in_user(void __user *to, const void *from, unsigned long n) +copy_in_user(void __user *to, const void __user *from, unsigned long n) { might_fault(); if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n)) diff --git a/include/linux/umh.h b/include/linux/umh.h new file mode 100644 index 0000000000000000000000000000000000000000..244aff6382208824e64c6387a38bb60e967f0548 --- /dev/null +++ b/include/linux/umh.h @@ -0,0 +1,69 @@ +#ifndef __LINUX_UMH_H__ +#define __LINUX_UMH_H__ + +#include +#include +#include +#include +#include +#include + +struct cred; +struct file; + +#define UMH_NO_WAIT 0 /* don't wait at all */ +#define UMH_WAIT_EXEC 1 /* wait for the exec, but not the process */ +#define UMH_WAIT_PROC 2 /* wait for the process to complete */ +#define UMH_KILLABLE 4 /* wait for EXEC/PROC killable */ + +struct subprocess_info { + struct work_struct work; + struct completion *complete; + const char *path; + char **argv; + char **envp; + int wait; + int retval; + int (*init)(struct subprocess_info *info, struct cred *new); + void (*cleanup)(struct subprocess_info *info); + void *data; +} __randomize_layout; + +extern int +call_usermodehelper(const char *path, char **argv, char **envp, int wait); + +extern struct subprocess_info * +call_usermodehelper_setup(const char *path, char **argv, char **envp, + gfp_t gfp_mask, + int (*init)(struct subprocess_info *info, struct cred *new), + void (*cleanup)(struct subprocess_info *), void *data); + +extern int +call_usermodehelper_exec(struct subprocess_info *info, int wait); + +extern struct ctl_table usermodehelper_table[]; + +enum umh_disable_depth { + UMH_ENABLED = 0, + UMH_FREEZING, + UMH_DISABLED, +}; + +extern int __usermodehelper_disable(enum umh_disable_depth depth); +extern void __usermodehelper_set_disable_depth(enum umh_disable_depth depth); + +static inline int usermodehelper_disable(void) +{ + return __usermodehelper_disable(UMH_DISABLED); +} + +static inline void usermodehelper_enable(void) +{ + __usermodehelper_set_disable_depth(UMH_ENABLED); +} + +extern int usermodehelper_read_trylock(void); +extern long usermodehelper_read_lock_wait(long timeout); +extern void usermodehelper_read_unlock(void); + +#endif /* __LINUX_UMH_H__ */ diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index c5fdfcf998285202cca159fef5b91a4c6d1a10b0..d725cff7268de388f3e65fed41381255b2cf43e4 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -58,6 +58,7 @@ struct ci_hdrc_platform_data { #define CI_HDRC_OVERRIDE_TX_BURST BIT(10) #define CI_HDRC_OVERRIDE_RX_BURST BIT(11) #define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */ +#define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13) enum usb_dr_mode dr_mode; #define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 1a4a4bacfae629a5559c5af5546c925601a835cc..21468a722c4a77ef2802890edad26ce55a232bdf 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -48,6 +48,7 @@ struct usb_ep; * by adding a zero length packet as needed; * @short_not_ok: When reading data, makes short packets be * treated as errors (queue stops advancing till cleanup). + * @dma_mapped: Indicates if request has been mapped to DMA (internal) * @complete: Function called when request completes, so this request and * its buffer may be re-used. The function will always be called with * interrupts disabled, and it must not sleep. @@ -103,6 +104,7 @@ struct usb_request { unsigned no_interrupt:1; unsigned zero:1; unsigned short_not_ok:1; + unsigned dma_mapped:1; void (*complete)(struct usb_ep *ep, struct usb_request *req); diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 299245105610f271aa68399508a0486aca595db7..8c6914873a16a735b3ac26a6a1f69499ded12c73 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -12,6 +12,7 @@ #include #include #include +#include enum usb_phy_interface { USBPHY_INTERFACE_MODE_UNKNOWN, @@ -72,6 +73,17 @@ struct usb_phy_io_ops { int (*write)(struct usb_phy *x, u32 val, u32 reg); }; +struct usb_charger_current { + unsigned int sdp_min; + unsigned int sdp_max; + unsigned int dcp_min; + unsigned int dcp_max; + unsigned int cdp_min; + unsigned int cdp_max; + unsigned int aca_min; + unsigned int aca_max; +}; + struct usb_phy { struct device *dev; const char *label; @@ -91,6 +103,13 @@ struct usb_phy { struct extcon_dev *id_edev; struct notifier_block vbus_nb; struct notifier_block id_nb; + struct notifier_block type_nb; + + /* Support USB charger */ + enum usb_charger_type chg_type; + enum usb_charger_state chg_state; + struct usb_charger_current chg_cur; + struct work_struct chg_work; /* for notification of usb_phy_events */ struct atomic_notifier_head notifier; @@ -129,6 +148,12 @@ struct usb_phy { enum usb_device_speed speed); int (*notify_disconnect)(struct usb_phy *x, enum usb_device_speed speed); + + /* + * Charger detection method can be implemented if you need to + * manually detect the charger type. + */ + enum usb_charger_type (*charger_detect)(struct usb_phy *x); }; /** @@ -219,6 +244,12 @@ extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); extern int usb_bind_phy(const char *dev_name, u8 index, const char *phy_dev_name); extern void usb_phy_set_event(struct usb_phy *x, unsigned long event); +extern void usb_phy_set_charger_current(struct usb_phy *usb_phy, + unsigned int mA); +extern void usb_phy_get_charger_current(struct usb_phy *usb_phy, + unsigned int *min, unsigned int *max); +extern void usb_phy_set_charger_state(struct usb_phy *usb_phy, + enum usb_charger_state state); #else static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) { @@ -270,12 +301,33 @@ static inline int usb_bind_phy(const char *dev_name, u8 index, static inline void usb_phy_set_event(struct usb_phy *x, unsigned long event) { } + +static inline void usb_phy_set_charger_current(struct usb_phy *usb_phy, + unsigned int mA) +{ +} + +static inline void usb_phy_get_charger_current(struct usb_phy *usb_phy, + unsigned int *min, + unsigned int *max) +{ +} + +static inline void usb_phy_set_charger_state(struct usb_phy *usb_phy, + enum usb_charger_state state) +{ +} #endif static inline int usb_phy_set_power(struct usb_phy *x, unsigned mA) { - if (x && x->set_power) + if (!x) + return 0; + + usb_phy_set_charger_current(x, mA); + + if (x->set_power) return x->set_power(x, mA); return 0; } diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index b3575ce291483284847ccc7eef5fea679fade38b..c18e0125234628f4ad6810eb8f6a19cf356a7f46 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -112,8 +112,9 @@ extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *); extern int proc_setgroups_show(struct seq_file *m, void *v); extern bool userns_may_setgroups(const struct user_namespace *ns); +extern bool in_userns(const struct user_namespace *ancestor, + const struct user_namespace *child); extern bool current_in_userns(const struct user_namespace *target_ns); - struct ns_common *ns_get_owner(struct ns_common *ns); #else @@ -144,6 +145,12 @@ static inline bool userns_may_setgroups(const struct user_namespace *ns) return true; } +static inline bool in_userns(const struct user_namespace *ancestor, + const struct user_namespace *child) +{ + return true; +} + static inline bool current_in_userns(const struct user_namespace *target_ns) { return true; diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 586809abb273498705be4d75a0e2571caa81ec7a..a47b985341d12cb685a525c9a5d7179d376cb6a9 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -152,7 +152,7 @@ extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, size_t *data_size); struct pci_dev; -#ifdef CONFIG_EEH +#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, @@ -173,7 +173,7 @@ static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, { return -ENOTTY; } -#endif /* CONFIG_EEH */ +#endif /* CONFIG_VFIO_SPAPR_EEH */ /* * IRQfd - generic diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 5209b5ed2a6476dfa5fe6b779f433a795f084ed7..32fb046f2173347ad0b72628e84b575e8899f7b9 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -18,9 +18,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, case VIRTIO_NET_HDR_GSO_TCPV6: gso_type = SKB_GSO_TCPV6; break; - case VIRTIO_NET_HDR_GSO_UDP: - gso_type = SKB_GSO_UDP; - break; default: return -EINVAL; } @@ -73,8 +70,6 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb, hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (sinfo->gso_type & SKB_GSO_TCPV6) hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (sinfo->gso_type & SKB_GSO_UDP) - hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; else return -EINVAL; if (sinfo->gso_type & SKB_GSO_TCP_ECN) diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 37e8d31a4632dbbdcb22b492153cb36897057687..d77bc35278b0e9ced64374475aa084290d988e1c 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -85,6 +85,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, #endif THP_ZERO_PAGE_ALLOC, THP_ZERO_PAGE_ALLOC_FAILED, + THP_SWPOUT, + THP_SWPOUT_FALLBACK, #endif #ifdef CONFIG_MEMORY_BALLOON BALLOON_INFLATE, @@ -103,6 +105,10 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, VMACACHE_FIND_CALLS, VMACACHE_FIND_HITS, VMACACHE_FULL_FLUSHES, +#endif +#ifdef CONFIG_SWAP + SWAP_RA, + SWAP_RA_HIT, #endif NR_VM_EVENT_ITEMS }; diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index b3d85f30d42485756a79c831a519b6288000ee48..ade7cb5f1359915f0d5036ae7884d99adc20e021 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -107,8 +107,37 @@ static inline void vm_events_fold_cpu(int cpu) * Zone and node-based page accounting with per cpu differentials. */ extern atomic_long_t vm_zone_stat[NR_VM_ZONE_STAT_ITEMS]; +extern atomic_long_t vm_numa_stat[NR_VM_NUMA_STAT_ITEMS]; extern atomic_long_t vm_node_stat[NR_VM_NODE_STAT_ITEMS]; +#ifdef CONFIG_NUMA +static inline void zone_numa_state_add(long x, struct zone *zone, + enum numa_stat_item item) +{ + atomic_long_add(x, &zone->vm_numa_stat[item]); + atomic_long_add(x, &vm_numa_stat[item]); +} + +static inline unsigned long global_numa_state(enum numa_stat_item item) +{ + long x = atomic_long_read(&vm_numa_stat[item]); + + return x; +} + +static inline unsigned long zone_numa_state_snapshot(struct zone *zone, + enum numa_stat_item item) +{ + long x = atomic_long_read(&zone->vm_numa_stat[item]); + int cpu; + + for_each_online_cpu(cpu) + x += per_cpu_ptr(zone->pageset, cpu)->vm_numa_stat_diff[item]; + + return x; +} +#endif /* CONFIG_NUMA */ + static inline void zone_page_state_add(long x, struct zone *zone, enum zone_stat_item item) { @@ -123,7 +152,7 @@ static inline void node_page_state_add(long x, struct pglist_data *pgdat, atomic_long_add(x, &vm_node_stat[item]); } -static inline unsigned long global_page_state(enum zone_stat_item item) +static inline unsigned long global_zone_page_state(enum zone_stat_item item) { long x = atomic_long_read(&vm_zone_stat[item]); #ifdef CONFIG_SMP @@ -194,12 +223,14 @@ static inline unsigned long node_page_state_snapshot(pg_data_t *pgdat, #ifdef CONFIG_NUMA +extern void __inc_numa_state(struct zone *zone, enum numa_stat_item item); extern unsigned long sum_zone_node_page_state(int node, - enum zone_stat_item item); + enum zone_stat_item item); +extern unsigned long sum_zone_numa_state(int node, enum numa_stat_item item); extern unsigned long node_page_state(struct pglist_data *pgdat, enum node_stat_item item); #else -#define sum_zone_node_page_state(node, item) global_page_state(item) +#define sum_zone_node_page_state(node, item) global_zone_page_state(item) #define node_page_state(node, item) global_node_page_state(item) #endif /* CONFIG_NUMA */ diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index f38c10ba3ff5ea01821ed375d25be2a403365e94..30b6e0d2a942600e234c8195551a008e4d23c039 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -13,6 +13,7 @@ #ifndef _LINUX_VT_BUFFER_H_ #define _LINUX_VT_BUFFER_H_ +#include #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) #include @@ -26,24 +27,33 @@ #ifndef VT_BUF_HAVE_MEMSETW static inline void scr_memsetw(u16 *s, u16 c, unsigned int count) { +#ifdef VT_BUF_HAVE_RW count /= 2; while (count--) scr_writew(c, s++); +#else + memset16(s, c, count / 2); +#endif } #endif #ifndef VT_BUF_HAVE_MEMCPYW static inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count) { +#ifdef VT_BUF_HAVE_RW count /= 2; while (count--) scr_writew(scr_readw(s++), d++); +#else + memcpy(d, s, count); +#endif } #endif #ifndef VT_BUF_HAVE_MEMMOVEW static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count) { +#ifdef VT_BUF_HAVE_RW if (d < s) scr_memcpyw(d, s, count); else { @@ -53,6 +63,9 @@ static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count) while (count--) scr_writew(scr_readw(--s), --d); } +#else + memmove(d, s, count); +#endif } #endif diff --git a/include/linux/w1.h b/include/linux/w1.h index 90cbe7e65059f6b604a87c6bf39cd9bbeae7684c..5b2972946dda5f9ad415f1eaeaab67743a5cc0f0 100644 --- a/include/linux/w1.h +++ b/include/linux/w1.h @@ -68,6 +68,7 @@ struct w1_reg_num { * @family: module for device family type * @family_data: pointer for use by the family module * @dev: kernel device identifier + * @hwmon: pointer to hwmon device * */ struct w1_slave { @@ -83,6 +84,7 @@ struct w1_slave { struct w1_family *family; void *family_data; struct device dev; + struct device *hwmon; }; typedef void (*w1_slave_found_callback)(struct w1_master *, u64); @@ -250,11 +252,13 @@ void w1_remove_master_device(struct w1_bus_master *master); * @add_slave: add_slave * @remove_slave: remove_slave * @groups: sysfs group + * @chip_info: pointer to struct hwmon_chip_info */ struct w1_family_ops { int (*add_slave)(struct w1_slave *sl); void (*remove_slave)(struct w1_slave *sl); const struct attribute_group **groups; + const struct hwmon_chip_info *chip_info; }; /** diff --git a/include/linux/wait.h b/include/linux/wait.h index 5b74e36c0ca896481acd04bbea92be002ad4ba64..87c4641023fbec675fd785a2dd721dbf3e5ed251 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -18,6 +18,7 @@ int default_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int /* wait_queue_entry::flags */ #define WQ_FLAG_EXCLUSIVE 0x01 #define WQ_FLAG_WOKEN 0x02 +#define WQ_FLAG_BOOKMARK 0x04 /* * A single wait-queue entry structure: @@ -184,6 +185,8 @@ __remove_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq void __wake_up(struct wait_queue_head *wq_head, unsigned int mode, int nr, void *key); void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); +void __wake_up_locked_key_bookmark(struct wait_queue_head *wq_head, + unsigned int mode, void *key, wait_queue_entry_t *bookmark); void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, int nr, void *key); void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr); void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode, int nr); @@ -757,6 +760,43 @@ extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_entry_t *); __ret; \ }) +#define __wait_event_killable_timeout(wq_head, condition, timeout) \ + ___wait_event(wq_head, ___wait_cond_timeout(condition), \ + TASK_KILLABLE, 0, timeout, \ + __ret = schedule_timeout(__ret)) + +/** + * wait_event_killable_timeout - sleep until a condition gets true or a timeout elapses + * @wq_head: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * @timeout: timeout, in jiffies + * + * The process is put to sleep (TASK_KILLABLE) until the + * @condition evaluates to true or a kill signal is received. + * The @condition is checked each time the waitqueue @wq_head is woken up. + * + * wake_up() has to be called after changing any variable that could + * change the result of the wait condition. + * + * Returns: + * 0 if the @condition evaluated to %false after the @timeout elapsed, + * 1 if the @condition evaluated to %true after the @timeout elapsed, + * the remaining jiffies (at least 1) if the @condition evaluated + * to %true before the @timeout elapsed, or -%ERESTARTSYS if it was + * interrupted by a kill signal. + * + * Only kill signals interrupt this process. + */ +#define wait_event_killable_timeout(wq_head, condition, timeout) \ +({ \ + long __ret = timeout; \ + might_sleep(); \ + if (!___wait_cond_timeout(condition)) \ + __ret = __wait_event_killable_timeout(wq_head, \ + condition, timeout); \ + __ret; \ +}) + #define __wait_event_lock_irq(wq_head, condition, lock, cmd) \ (void)___wait_event(wq_head, condition, TASK_UNINTERRUPTIBLE, 0, 0, \ diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index c102ef65cb64a94269b950ff09c47d90bbc2d315..1c49431f31213fcaef9a57dbaaa4d79325c6cb47 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -324,6 +324,7 @@ enum { __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */ __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */ __WQ_LEGACY = 1 << 18, /* internal: create*_workqueue() */ + __WQ_ORDERED_EXPLICIT = 1 << 19, /* internal: alloc_ordered_workqueue() */ WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ @@ -422,7 +423,8 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active, * Pointer to the allocated workqueue on success, %NULL on failure. */ #define alloc_ordered_workqueue(fmt, flags, args...) \ - alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args) + alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | \ + __WQ_ORDERED_EXPLICIT | (flags), 1, ##args) #define create_workqueue(name) \ alloc_workqueue("%s", __WQ_LEGACY | WQ_MEM_RECLAIM, 1, (name)) diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h new file mode 100644 index 0000000000000000000000000000000000000000..9e1f42cb57e9e98fb4300c3361b5e8d7eb593a4b --- /dev/null +++ b/include/linux/xxhash.h @@ -0,0 +1,236 @@ +/* + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at: + * - xxHash homepage: http://cyan4973.github.io/xxHash/ + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ + +/* + * Notice extracted from xxHash homepage: + * + * xxHash is an extremely fast Hash algorithm, running at RAM speed limits. + * It also successfully passes all tests from the SMHasher suite. + * + * Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 + * Duo @3GHz) + * + * Name Speed Q.Score Author + * xxHash 5.4 GB/s 10 + * CrapWow 3.2 GB/s 2 Andrew + * MumurHash 3a 2.7 GB/s 10 Austin Appleby + * SpookyHash 2.0 GB/s 10 Bob Jenkins + * SBox 1.4 GB/s 9 Bret Mulvey + * Lookup3 1.2 GB/s 9 Bob Jenkins + * SuperFastHash 1.2 GB/s 1 Paul Hsieh + * CityHash64 1.05 GB/s 10 Pike & Alakuijala + * FNV 0.55 GB/s 5 Fowler, Noll, Vo + * CRC32 0.43 GB/s 9 + * MD5-32 0.33 GB/s 10 Ronald L. Rivest + * SHA1-32 0.28 GB/s 10 + * + * Q.Score is a measure of quality of the hash function. + * It depends on successfully passing SMHasher test set. + * 10 is a perfect score. + * + * A 64-bits version, named xxh64 offers much better speed, + * but for 64-bits applications only. + * Name Speed on 64 bits Speed on 32 bits + * xxh64 13.8 GB/s 1.9 GB/s + * xxh32 6.8 GB/s 6.0 GB/s + */ + +#ifndef XXHASH_H +#define XXHASH_H + +#include + +/*-**************************** + * Simple Hash Functions + *****************************/ + +/** + * xxh32() - calculate the 32-bit hash of the input with a given seed. + * + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s + * + * Return: The 32-bit hash of the data. + */ +uint32_t xxh32(const void *input, size_t length, uint32_t seed); + +/** + * xxh64() - calculate the 64-bit hash of the input with a given seed. + * + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * This function runs 2x faster on 64-bit systems, but slower on 32-bit systems. + * + * Return: The 64-bit hash of the data. + */ +uint64_t xxh64(const void *input, size_t length, uint64_t seed); + +/*-**************************** + * Streaming Hash Functions + *****************************/ + +/* + * These definitions are only meant to allow allocation of XXH state + * statically, on stack, or in a struct for example. + * Do not use members directly. + */ + +/** + * struct xxh32_state - private xxh32 state, do not use members directly + */ +struct xxh32_state { + uint32_t total_len_32; + uint32_t large_len; + uint32_t v1; + uint32_t v2; + uint32_t v3; + uint32_t v4; + uint32_t mem32[4]; + uint32_t memsize; +}; + +/** + * struct xxh32_state - private xxh64 state, do not use members directly + */ +struct xxh64_state { + uint64_t total_len; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t v4; + uint64_t mem64[4]; + uint32_t memsize; +}; + +/** + * xxh32_reset() - reset the xxh32 state to start a new hashing operation + * + * @state: The xxh32 state to reset. + * @seed: Initialize the hash state with this seed. + * + * Call this function on any xxh32_state to prepare for a new hashing operation. + */ +void xxh32_reset(struct xxh32_state *state, uint32_t seed); + +/** + * xxh32_update() - hash the data given and update the xxh32 state + * + * @state: The xxh32 state to update. + * @input: The data to hash. + * @length: The length of the data to hash. + * + * After calling xxh32_reset() call xxh32_update() as many times as necessary. + * + * Return: Zero on success, otherwise an error code. + */ +int xxh32_update(struct xxh32_state *state, const void *input, size_t length); + +/** + * xxh32_digest() - produce the current xxh32 hash + * + * @state: Produce the current xxh32 hash of this state. + * + * A hash value can be produced at any time. It is still possible to continue + * inserting input into the hash state after a call to xxh32_digest(), and + * generate new hashes later on, by calling xxh32_digest() again. + * + * Return: The xxh32 hash stored in the state. + */ +uint32_t xxh32_digest(const struct xxh32_state *state); + +/** + * xxh64_reset() - reset the xxh64 state to start a new hashing operation + * + * @state: The xxh64 state to reset. + * @seed: Initialize the hash state with this seed. + */ +void xxh64_reset(struct xxh64_state *state, uint64_t seed); + +/** + * xxh64_update() - hash the data given and update the xxh64 state + * @state: The xxh64 state to update. + * @input: The data to hash. + * @length: The length of the data to hash. + * + * After calling xxh64_reset() call xxh64_update() as many times as necessary. + * + * Return: Zero on success, otherwise an error code. + */ +int xxh64_update(struct xxh64_state *state, const void *input, size_t length); + +/** + * xxh64_digest() - produce the current xxh64 hash + * + * @state: Produce the current xxh64 hash of this state. + * + * A hash value can be produced at any time. It is still possible to continue + * inserting input into the hash state after a call to xxh64_digest(), and + * generate new hashes later on, by calling xxh64_digest() again. + * + * Return: The xxh64 hash stored in the state. + */ +uint64_t xxh64_digest(const struct xxh64_state *state); + +/*-************************** + * Utils + ***************************/ + +/** + * xxh32_copy_state() - copy the source state into the destination state + * + * @src: The source xxh32 state. + * @dst: The destination xxh32 state. + */ +void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src); + +/** + * xxh64_copy_state() - copy the source state into the destination state + * + * @src: The source xxh64 state. + * @dst: The destination xxh64 state. + */ +void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src); + +#endif /* XXHASH_H */ diff --git a/include/linux/zstd.h b/include/linux/zstd.h new file mode 100644 index 0000000000000000000000000000000000000000..249575e2485f3ce071f90aa692be0701493ac9f3 --- /dev/null +++ b/include/linux/zstd.h @@ -0,0 +1,1157 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +#ifndef ZSTD_H +#define ZSTD_H + +/* ====== Dependency ======*/ +#include /* size_t */ + + +/*-***************************************************************************** + * Introduction + * + * zstd, short for Zstandard, is a fast lossless compression algorithm, + * targeting real-time compression scenarios at zlib-level and better + * compression ratios. The zstd compression library provides in-memory + * compression and decompression functions. The library supports compression + * levels from 1 up to ZSTD_maxCLevel() which is 22. Levels >= 20, labeled + * ultra, should be used with caution, as they require more memory. + * Compression can be done in: + * - a single step, reusing a context (described as Explicit memory management) + * - unbounded multiple steps (described as Streaming compression) + * The compression ratio achievable on small data can be highly improved using + * compression with a dictionary in: + * - a single step (described as Simple dictionary API) + * - a single step, reusing a dictionary (described as Fast dictionary API) + ******************************************************************************/ + +/*====== Helper functions ======*/ + +/** + * enum ZSTD_ErrorCode - zstd error codes + * + * Functions that return size_t can be checked for errors using ZSTD_isError() + * and the ZSTD_ErrorCode can be extracted using ZSTD_getErrorCode(). + */ +typedef enum { + ZSTD_error_no_error, + ZSTD_error_GENERIC, + ZSTD_error_prefix_unknown, + ZSTD_error_version_unsupported, + ZSTD_error_parameter_unknown, + ZSTD_error_frameParameter_unsupported, + ZSTD_error_frameParameter_unsupportedBy32bits, + ZSTD_error_frameParameter_windowTooLarge, + ZSTD_error_compressionParameter_unsupported, + ZSTD_error_init_missing, + ZSTD_error_memory_allocation, + ZSTD_error_stage_wrong, + ZSTD_error_dstSize_tooSmall, + ZSTD_error_srcSize_wrong, + ZSTD_error_corruption_detected, + ZSTD_error_checksum_wrong, + ZSTD_error_tableLog_tooLarge, + ZSTD_error_maxSymbolValue_tooLarge, + ZSTD_error_maxSymbolValue_tooSmall, + ZSTD_error_dictionary_corrupted, + ZSTD_error_dictionary_wrong, + ZSTD_error_dictionaryCreation_failed, + ZSTD_error_maxCode +} ZSTD_ErrorCode; + +/** + * ZSTD_maxCLevel() - maximum compression level available + * + * Return: Maximum compression level available. + */ +int ZSTD_maxCLevel(void); +/** + * ZSTD_compressBound() - maximum compressed size in worst case scenario + * @srcSize: The size of the data to compress. + * + * Return: The maximum compressed size in the worst case scenario. + */ +size_t ZSTD_compressBound(size_t srcSize); +/** + * ZSTD_isError() - tells if a size_t function result is an error code + * @code: The function result to check for error. + * + * Return: Non-zero iff the code is an error. + */ +static __attribute__((unused)) unsigned int ZSTD_isError(size_t code) +{ + return code > (size_t)-ZSTD_error_maxCode; +} +/** + * ZSTD_getErrorCode() - translates an error function result to a ZSTD_ErrorCode + * @functionResult: The result of a function for which ZSTD_isError() is true. + * + * Return: The ZSTD_ErrorCode corresponding to the functionResult or 0 + * if the functionResult isn't an error. + */ +static __attribute__((unused)) ZSTD_ErrorCode ZSTD_getErrorCode( + size_t functionResult) +{ + if (!ZSTD_isError(functionResult)) + return (ZSTD_ErrorCode)0; + return (ZSTD_ErrorCode)(0 - functionResult); +} + +/** + * enum ZSTD_strategy - zstd compression search strategy + * + * From faster to stronger. + */ +typedef enum { + ZSTD_fast, + ZSTD_dfast, + ZSTD_greedy, + ZSTD_lazy, + ZSTD_lazy2, + ZSTD_btlazy2, + ZSTD_btopt, + ZSTD_btopt2 +} ZSTD_strategy; + +/** + * struct ZSTD_compressionParameters - zstd compression parameters + * @windowLog: Log of the largest match distance. Larger means more + * compression, and more memory needed during decompression. + * @chainLog: Fully searched segment. Larger means more compression, slower, + * and more memory (useless for fast). + * @hashLog: Dispatch table. Larger means more compression, + * slower, and more memory. + * @searchLog: Number of searches. Larger means more compression and slower. + * @searchLength: Match length searched. Larger means faster decompression, + * sometimes less compression. + * @targetLength: Acceptable match size for optimal parser (only). Larger means + * more compression, and slower. + * @strategy: The zstd compression strategy. + */ +typedef struct { + unsigned int windowLog; + unsigned int chainLog; + unsigned int hashLog; + unsigned int searchLog; + unsigned int searchLength; + unsigned int targetLength; + ZSTD_strategy strategy; +} ZSTD_compressionParameters; + +/** + * struct ZSTD_frameParameters - zstd frame parameters + * @contentSizeFlag: Controls whether content size will be present in the frame + * header (when known). + * @checksumFlag: Controls whether a 32-bit checksum is generated at the end + * of the frame for error detection. + * @noDictIDFlag: Controls whether dictID will be saved into the frame header + * when using dictionary compression. + * + * The default value is all fields set to 0. + */ +typedef struct { + unsigned int contentSizeFlag; + unsigned int checksumFlag; + unsigned int noDictIDFlag; +} ZSTD_frameParameters; + +/** + * struct ZSTD_parameters - zstd parameters + * @cParams: The compression parameters. + * @fParams: The frame parameters. + */ +typedef struct { + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; +} ZSTD_parameters; + +/** + * ZSTD_getCParams() - returns ZSTD_compressionParameters for selected level + * @compressionLevel: The compression level from 1 to ZSTD_maxCLevel(). + * @estimatedSrcSize: The estimated source size to compress or 0 if unknown. + * @dictSize: The dictionary size or 0 if a dictionary isn't being used. + * + * Return: The selected ZSTD_compressionParameters. + */ +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, + unsigned long long estimatedSrcSize, size_t dictSize); + +/** + * ZSTD_getParams() - returns ZSTD_parameters for selected level + * @compressionLevel: The compression level from 1 to ZSTD_maxCLevel(). + * @estimatedSrcSize: The estimated source size to compress or 0 if unknown. + * @dictSize: The dictionary size or 0 if a dictionary isn't being used. + * + * The same as ZSTD_getCParams() except also selects the default frame + * parameters (all zero). + * + * Return: The selected ZSTD_parameters. + */ +ZSTD_parameters ZSTD_getParams(int compressionLevel, + unsigned long long estimatedSrcSize, size_t dictSize); + +/*-************************************* + * Explicit memory management + **************************************/ + +/** + * ZSTD_CCtxWorkspaceBound() - amount of memory needed to initialize a ZSTD_CCtx + * @cParams: The compression parameters to be used for compression. + * + * If multiple compression parameters might be used, the caller must call + * ZSTD_CCtxWorkspaceBound() for each set of parameters and use the maximum + * size. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initCCtx(). + */ +size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters cParams); + +/** + * struct ZSTD_CCtx - the zstd compression context + * + * When compressing many times it is recommended to allocate a context just once + * and reuse it for each successive compression operation. + */ +typedef struct ZSTD_CCtx_s ZSTD_CCtx; +/** + * ZSTD_initCCtx() - initialize a zstd compression context + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. Use ZSTD_CCtxWorkspaceBound() to + * determine how large the workspace must be. + * + * Return: A compression context emplaced into workspace. + */ +ZSTD_CCtx *ZSTD_initCCtx(void *workspace, size_t workspaceSize); + +/** + * ZSTD_compressCCtx() - compress src into dst + * @ctx: The context. Must have been initialized with a workspace at + * least as large as ZSTD_CCtxWorkspaceBound(params.cParams). + * @dst: The buffer to compress src into. + * @dstCapacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @srcSize: The size of the data to compress. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * + * Return: The compressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compressCCtx(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, ZSTD_parameters params); + +/** + * ZSTD_DCtxWorkspaceBound() - amount of memory needed to initialize a ZSTD_DCtx + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initDCtx(). + */ +size_t ZSTD_DCtxWorkspaceBound(void); + +/** + * struct ZSTD_DCtx - the zstd decompression context + * + * When decompressing many times it is recommended to allocate a context just + * once and reuse it for each successive decompression operation. + */ +typedef struct ZSTD_DCtx_s ZSTD_DCtx; +/** + * ZSTD_initDCtx() - initialize a zstd decompression context + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. Use ZSTD_DCtxWorkspaceBound() to + * determine how large the workspace must be. + * + * Return: A decompression context emplaced into workspace. + */ +ZSTD_DCtx *ZSTD_initDCtx(void *workspace, size_t workspaceSize); + +/** + * ZSTD_decompressDCtx() - decompress zstd compressed src into dst + * @ctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dstCapacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @srcSize: The exact size of the data to decompress. + * + * Return: The decompressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_decompressDCtx(ZSTD_DCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); + +/*-************************ + * Simple dictionary API + **************************/ + +/** + * ZSTD_compress_usingDict() - compress src into dst using a dictionary + * @ctx: The context. Must have been initialized with a workspace at + * least as large as ZSTD_CCtxWorkspaceBound(params.cParams). + * @dst: The buffer to compress src into. + * @dstCapacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @srcSize: The size of the data to compress. + * @dict: The dictionary to use for compression. + * @dictSize: The size of the dictionary. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * + * Compression using a predefined dictionary. The same dictionary must be used + * during decompression. + * + * Return: The compressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compress_usingDict(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, const void *dict, size_t dictSize, + ZSTD_parameters params); + +/** + * ZSTD_decompress_usingDict() - decompress src into dst using a dictionary + * @ctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dstCapacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @srcSize: The exact size of the data to decompress. + * @dict: The dictionary to use for decompression. The same dictionary + * must've been used to compress the data. + * @dictSize: The size of the dictionary. + * + * Return: The decompressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_decompress_usingDict(ZSTD_DCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, const void *dict, size_t dictSize); + +/*-************************** + * Fast dictionary API + ***************************/ + +/** + * ZSTD_CDictWorkspaceBound() - memory needed to initialize a ZSTD_CDict + * @cParams: The compression parameters to be used for compression. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initCDict(). + */ +size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams); + +/** + * struct ZSTD_CDict - a digested dictionary to be used for compression + */ +typedef struct ZSTD_CDict_s ZSTD_CDict; + +/** + * ZSTD_initCDict() - initialize a digested dictionary for compression + * @dictBuffer: The dictionary to digest. The buffer is referenced by the + * ZSTD_CDict so it must outlive the returned ZSTD_CDict. + * @dictSize: The size of the dictionary. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * @workspace: The workspace. It must outlive the returned ZSTD_CDict. + * @workspaceSize: The workspace size. Must be at least + * ZSTD_CDictWorkspaceBound(params.cParams). + * + * When compressing multiple messages / blocks with the same dictionary it is + * recommended to load it just once. The ZSTD_CDict merely references the + * dictBuffer, so it must outlive the returned ZSTD_CDict. + * + * Return: The digested dictionary emplaced into workspace. + */ +ZSTD_CDict *ZSTD_initCDict(const void *dictBuffer, size_t dictSize, + ZSTD_parameters params, void *workspace, size_t workspaceSize); + +/** + * ZSTD_compress_usingCDict() - compress src into dst using a ZSTD_CDict + * @ctx: The context. Must have been initialized with a workspace at + * least as large as ZSTD_CCtxWorkspaceBound(cParams) where + * cParams are the compression parameters used to initialize the + * cdict. + * @dst: The buffer to compress src into. + * @dstCapacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @srcSize: The size of the data to compress. + * @cdict: The digested dictionary to use for compression. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * + * Compression using a digested dictionary. The same dictionary must be used + * during decompression. + * + * Return: The compressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, const ZSTD_CDict *cdict); + + +/** + * ZSTD_DDictWorkspaceBound() - memory needed to initialize a ZSTD_DDict + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initDDict(). + */ +size_t ZSTD_DDictWorkspaceBound(void); + +/** + * struct ZSTD_DDict - a digested dictionary to be used for decompression + */ +typedef struct ZSTD_DDict_s ZSTD_DDict; + +/** + * ZSTD_initDDict() - initialize a digested dictionary for decompression + * @dictBuffer: The dictionary to digest. The buffer is referenced by the + * ZSTD_DDict so it must outlive the returned ZSTD_DDict. + * @dictSize: The size of the dictionary. + * @workspace: The workspace. It must outlive the returned ZSTD_DDict. + * @workspaceSize: The workspace size. Must be at least + * ZSTD_DDictWorkspaceBound(). + * + * When decompressing multiple messages / blocks with the same dictionary it is + * recommended to load it just once. The ZSTD_DDict merely references the + * dictBuffer, so it must outlive the returned ZSTD_DDict. + * + * Return: The digested dictionary emplaced into workspace. + */ +ZSTD_DDict *ZSTD_initDDict(const void *dictBuffer, size_t dictSize, + void *workspace, size_t workspaceSize); + +/** + * ZSTD_decompress_usingDDict() - decompress src into dst using a ZSTD_DDict + * @ctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dstCapacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @srcSize: The exact size of the data to decompress. + * @ddict: The digested dictionary to use for decompression. The same + * dictionary must've been used to compress the data. + * + * Return: The decompressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst, + size_t dstCapacity, const void *src, size_t srcSize, + const ZSTD_DDict *ddict); + + +/*-************************** + * Streaming + ***************************/ + +/** + * struct ZSTD_inBuffer - input buffer for streaming + * @src: Start of the input buffer. + * @size: Size of the input buffer. + * @pos: Position where reading stopped. Will be updated. + * Necessarily 0 <= pos <= size. + */ +typedef struct ZSTD_inBuffer_s { + const void *src; + size_t size; + size_t pos; +} ZSTD_inBuffer; + +/** + * struct ZSTD_outBuffer - output buffer for streaming + * @dst: Start of the output buffer. + * @size: Size of the output buffer. + * @pos: Position where writing stopped. Will be updated. + * Necessarily 0 <= pos <= size. + */ +typedef struct ZSTD_outBuffer_s { + void *dst; + size_t size; + size_t pos; +} ZSTD_outBuffer; + + + +/*-***************************************************************************** + * Streaming compression - HowTo + * + * A ZSTD_CStream object is required to track streaming operation. + * Use ZSTD_initCStream() to initialize a ZSTD_CStream object. + * ZSTD_CStream objects can be reused multiple times on consecutive compression + * operations. It is recommended to re-use ZSTD_CStream in situations where many + * streaming operations will be achieved consecutively. Use one separate + * ZSTD_CStream per thread for parallel execution. + * + * Use ZSTD_compressStream() repetitively to consume input stream. + * The function will automatically update both `pos` fields. + * Note that it may not consume the entire input, in which case `pos < size`, + * and it's up to the caller to present again remaining data. + * It returns a hint for the preferred number of bytes to use as an input for + * the next function call. + * + * At any moment, it's possible to flush whatever data remains within internal + * buffer, using ZSTD_flushStream(). `output->pos` will be updated. There might + * still be some content left within the internal buffer if `output->size` is + * too small. It returns the number of bytes left in the internal buffer and + * must be called until it returns 0. + * + * ZSTD_endStream() instructs to finish a frame. It will perform a flush and + * write frame epilogue. The epilogue is required for decoders to consider a + * frame completed. Similar to ZSTD_flushStream(), it may not be able to flush + * the full content if `output->size` is too small. In which case, call again + * ZSTD_endStream() to complete the flush. It returns the number of bytes left + * in the internal buffer and must be called until it returns 0. + ******************************************************************************/ + +/** + * ZSTD_CStreamWorkspaceBound() - memory needed to initialize a ZSTD_CStream + * @cParams: The compression parameters to be used for compression. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initCStream() and ZSTD_initCStream_usingCDict(). + */ +size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams); + +/** + * struct ZSTD_CStream - the zstd streaming compression context + */ +typedef struct ZSTD_CStream_s ZSTD_CStream; + +/*===== ZSTD_CStream management functions =====*/ +/** + * ZSTD_initCStream() - initialize a zstd streaming compression context + * @params: The zstd compression parameters. + * @pledgedSrcSize: If params.fParams.contentSizeFlag == 1 then the caller must + * pass the source size (zero means empty source). Otherwise, + * the caller may optionally pass the source size, or zero if + * unknown. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use ZSTD_CStreamWorkspaceBound(params.cParams) to determine + * how large the workspace must be. + * + * Return: The zstd streaming compression context. + */ +ZSTD_CStream *ZSTD_initCStream(ZSTD_parameters params, + unsigned long long pledgedSrcSize, void *workspace, + size_t workspaceSize); + +/** + * ZSTD_initCStream_usingCDict() - initialize a streaming compression context + * @cdict: The digested dictionary to use for compression. + * @pledgedSrcSize: Optionally the source size, or zero if unknown. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. Call ZSTD_CStreamWorkspaceBound() + * with the cParams used to initialize the cdict to determine + * how large the workspace must be. + * + * Return: The zstd streaming compression context. + */ +ZSTD_CStream *ZSTD_initCStream_usingCDict(const ZSTD_CDict *cdict, + unsigned long long pledgedSrcSize, void *workspace, + size_t workspaceSize); + +/*===== Streaming compression functions =====*/ +/** + * ZSTD_resetCStream() - reset the context using parameters from creation + * @zcs: The zstd streaming compression context to reset. + * @pledgedSrcSize: Optionally the source size, or zero if unknown. + * + * Resets the context using the parameters from creation. Skips dictionary + * loading, since it can be reused. If `pledgedSrcSize` is non-zero the frame + * content size is always written into the frame header. + * + * Return: Zero or an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_resetCStream(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize); +/** + * ZSTD_compressStream() - streaming compress some of input into output + * @zcs: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * @input: Source buffer. `input->pos` is updated to indicate how much data was + * read. Note that it may not consume the entire input, in which case + * `input->pos < input->size`, and it's up to the caller to present + * remaining data again. + * + * The `input` and `output` buffers may be any size. Guaranteed to make some + * forward progress if `input` and `output` are not empty. + * + * Return: A hint for the number of bytes to use as the input for the next + * function call or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, + ZSTD_inBuffer *input); +/** + * ZSTD_flushStream() - flush internal buffers into output + * @zcs: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * + * ZSTD_flushStream() must be called until it returns 0, meaning all the data + * has been flushed. Since ZSTD_flushStream() causes a block to be ended, + * calling it too often will degrade the compression ratio. + * + * Return: The number of bytes still present within internal buffers or an + * error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_flushStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output); +/** + * ZSTD_endStream() - flush internal buffers into output and end the frame + * @zcs: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * + * ZSTD_endStream() must be called until it returns 0, meaning all the data has + * been flushed and the frame epilogue has been written. + * + * Return: The number of bytes still present within internal buffers or an + * error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output); + +/** + * ZSTD_CStreamInSize() - recommended size for the input buffer + * + * Return: The recommended size for the input buffer. + */ +size_t ZSTD_CStreamInSize(void); +/** + * ZSTD_CStreamOutSize() - recommended size for the output buffer + * + * When the output buffer is at least this large, it is guaranteed to be large + * enough to flush at least one complete compressed block. + * + * Return: The recommended size for the output buffer. + */ +size_t ZSTD_CStreamOutSize(void); + + + +/*-***************************************************************************** + * Streaming decompression - HowTo + * + * A ZSTD_DStream object is required to track streaming operations. + * Use ZSTD_initDStream() to initialize a ZSTD_DStream object. + * ZSTD_DStream objects can be re-used multiple times. + * + * Use ZSTD_decompressStream() repetitively to consume your input. + * The function will update both `pos` fields. + * If `input->pos < input->size`, some input has not been consumed. + * It's up to the caller to present again remaining data. + * If `output->pos < output->size`, decoder has flushed everything it could. + * Returns 0 iff a frame is completely decoded and fully flushed. + * Otherwise it returns a suggested next input size that will never load more + * than the current frame. + ******************************************************************************/ + +/** + * ZSTD_DStreamWorkspaceBound() - memory needed to initialize a ZSTD_DStream + * @maxWindowSize: The maximum window size allowed for compressed frames. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initDStream() and ZSTD_initDStream_usingDDict(). + */ +size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize); + +/** + * struct ZSTD_DStream - the zstd streaming decompression context + */ +typedef struct ZSTD_DStream_s ZSTD_DStream; +/*===== ZSTD_DStream management functions =====*/ +/** + * ZSTD_initDStream() - initialize a zstd streaming decompression context + * @maxWindowSize: The maximum window size allowed for compressed frames. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use ZSTD_DStreamWorkspaceBound(maxWindowSize) to determine + * how large the workspace must be. + * + * Return: The zstd streaming decompression context. + */ +ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace, + size_t workspaceSize); +/** + * ZSTD_initDStream_usingDDict() - initialize streaming decompression context + * @maxWindowSize: The maximum window size allowed for compressed frames. + * @ddict: The digested dictionary to use for decompression. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use ZSTD_DStreamWorkspaceBound(maxWindowSize) to determine + * how large the workspace must be. + * + * Return: The zstd streaming decompression context. + */ +ZSTD_DStream *ZSTD_initDStream_usingDDict(size_t maxWindowSize, + const ZSTD_DDict *ddict, void *workspace, size_t workspaceSize); + +/*===== Streaming decompression functions =====*/ +/** + * ZSTD_resetDStream() - reset the context using parameters from creation + * @zds: The zstd streaming decompression context to reset. + * + * Resets the context using the parameters from creation. Skips dictionary + * loading, since it can be reused. + * + * Return: Zero or an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_resetDStream(ZSTD_DStream *zds); +/** + * ZSTD_decompressStream() - streaming decompress some of input into output + * @zds: The zstd streaming decompression context. + * @output: Destination buffer. `output.pos` is updated to indicate how much + * decompressed data was written. + * @input: Source buffer. `input.pos` is updated to indicate how much data was + * read. Note that it may not consume the entire input, in which case + * `input.pos < input.size`, and it's up to the caller to present + * remaining data again. + * + * The `input` and `output` buffers may be any size. Guaranteed to make some + * forward progress if `input` and `output` are not empty. + * ZSTD_decompressStream() will not consume the last byte of the frame until + * the entire frame is flushed. + * + * Return: Returns 0 iff a frame is completely decoded and fully flushed. + * Otherwise returns a hint for the number of bytes to use as the input + * for the next function call or an error, which can be checked using + * ZSTD_isError(). The size hint will never load more than the frame. + */ +size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, + ZSTD_inBuffer *input); + +/** + * ZSTD_DStreamInSize() - recommended size for the input buffer + * + * Return: The recommended size for the input buffer. + */ +size_t ZSTD_DStreamInSize(void); +/** + * ZSTD_DStreamOutSize() - recommended size for the output buffer + * + * When the output buffer is at least this large, it is guaranteed to be large + * enough to flush at least one complete decompressed block. + * + * Return: The recommended size for the output buffer. + */ +size_t ZSTD_DStreamOutSize(void); + + +/* --- Constants ---*/ +#define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */ +#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U + +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) + +#define ZSTD_WINDOWLOG_MAX_32 27 +#define ZSTD_WINDOWLOG_MAX_64 27 +#define ZSTD_WINDOWLOG_MAX \ + ((unsigned int)(sizeof(size_t) == 4 \ + ? ZSTD_WINDOWLOG_MAX_32 \ + : ZSTD_WINDOWLOG_MAX_64)) +#define ZSTD_WINDOWLOG_MIN 10 +#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX +#define ZSTD_HASHLOG_MIN 6 +#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1) +#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN +#define ZSTD_HASHLOG3_MAX 17 +#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1) +#define ZSTD_SEARCHLOG_MIN 1 +/* only for ZSTD_fast, other strategies are limited to 6 */ +#define ZSTD_SEARCHLENGTH_MAX 7 +/* only for ZSTD_btopt, other strategies are limited to 4 */ +#define ZSTD_SEARCHLENGTH_MIN 3 +#define ZSTD_TARGETLENGTH_MIN 4 +#define ZSTD_TARGETLENGTH_MAX 999 + +/* for static allocation */ +#define ZSTD_FRAMEHEADERSIZE_MAX 18 +#define ZSTD_FRAMEHEADERSIZE_MIN 6 +static const size_t ZSTD_frameHeaderSize_prefix = 5; +static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN; +static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX; +/* magic number + skippable frame length */ +static const size_t ZSTD_skippableHeaderSize = 8; + + +/*-************************************* + * Compressed size functions + **************************************/ + +/** + * ZSTD_findFrameCompressedSize() - returns the size of a compressed frame + * @src: Source buffer. It should point to the start of a zstd encoded frame + * or a skippable frame. + * @srcSize: The size of the source buffer. It must be at least as large as the + * size of the frame. + * + * Return: The compressed size of the frame pointed to by `src` or an error, + * which can be check with ZSTD_isError(). + * Suitable to pass to ZSTD_decompress() or similar functions. + */ +size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize); + +/*-************************************* + * Decompressed size functions + **************************************/ +/** + * ZSTD_getFrameContentSize() - returns the content size in a zstd frame header + * @src: It should point to the start of a zstd encoded frame. + * @srcSize: The size of the source buffer. It must be at least as large as the + * frame header. `ZSTD_frameHeaderSize_max` is always large enough. + * + * Return: The frame content size stored in the frame header if known. + * `ZSTD_CONTENTSIZE_UNKNOWN` if the content size isn't stored in the + * frame header. `ZSTD_CONTENTSIZE_ERROR` on invalid input. + */ +unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); + +/** + * ZSTD_findDecompressedSize() - returns decompressed size of a series of frames + * @src: It should point to the start of a series of zstd encoded and/or + * skippable frames. + * @srcSize: The exact size of the series of frames. + * + * If any zstd encoded frame in the series doesn't have the frame content size + * set, `ZSTD_CONTENTSIZE_UNKNOWN` is returned. But frame content size is always + * set when using ZSTD_compress(). The decompressed size can be very large. + * If the source is untrusted, the decompressed size could be wrong or + * intentionally modified. Always ensure the result fits within the + * application's authorized limits. ZSTD_findDecompressedSize() handles multiple + * frames, and so it must traverse the input to read each frame header. This is + * efficient as most of the data is skipped, however it does mean that all frame + * data must be present and valid. + * + * Return: Decompressed size of all the data contained in the frames if known. + * `ZSTD_CONTENTSIZE_UNKNOWN` if the decompressed size is unknown. + * `ZSTD_CONTENTSIZE_ERROR` if an error occurred. + */ +unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize); + +/*-************************************* + * Advanced compression functions + **************************************/ +/** + * ZSTD_checkCParams() - ensure parameter values remain within authorized range + * @cParams: The zstd compression parameters. + * + * Return: Zero or an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams); + +/** + * ZSTD_adjustCParams() - optimize parameters for a given srcSize and dictSize + * @srcSize: Optionally the estimated source size, or zero if unknown. + * @dictSize: Optionally the estimated dictionary size, or zero if unknown. + * + * Return: The optimized parameters. + */ +ZSTD_compressionParameters ZSTD_adjustCParams( + ZSTD_compressionParameters cParams, unsigned long long srcSize, + size_t dictSize); + +/*--- Advanced decompression functions ---*/ + +/** + * ZSTD_isFrame() - returns true iff the buffer starts with a valid frame + * @buffer: The source buffer to check. + * @size: The size of the source buffer, must be at least 4 bytes. + * + * Return: True iff the buffer starts with a zstd or skippable frame identifier. + */ +unsigned int ZSTD_isFrame(const void *buffer, size_t size); + +/** + * ZSTD_getDictID_fromDict() - returns the dictionary id stored in a dictionary + * @dict: The dictionary buffer. + * @dictSize: The size of the dictionary buffer. + * + * Return: The dictionary id stored within the dictionary or 0 if the + * dictionary is not a zstd dictionary. If it returns 0 the + * dictionary can still be loaded as a content-only dictionary. + */ +unsigned int ZSTD_getDictID_fromDict(const void *dict, size_t dictSize); + +/** + * ZSTD_getDictID_fromDDict() - returns the dictionary id stored in a ZSTD_DDict + * @ddict: The ddict to find the id of. + * + * Return: The dictionary id stored within `ddict` or 0 if the dictionary is not + * a zstd dictionary. If it returns 0 `ddict` will be loaded as a + * content-only dictionary. + */ +unsigned int ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict); + +/** + * ZSTD_getDictID_fromFrame() - returns the dictionary id stored in a zstd frame + * @src: Source buffer. It must be a zstd encoded frame. + * @srcSize: The size of the source buffer. It must be at least as large as the + * frame header. `ZSTD_frameHeaderSize_max` is always large enough. + * + * Return: The dictionary id required to decompress the frame stored within + * `src` or 0 if the dictionary id could not be decoded. It can return + * 0 if the frame does not require a dictionary, the dictionary id + * wasn't stored in the frame, `src` is not a zstd frame, or `srcSize` + * is too small. + */ +unsigned int ZSTD_getDictID_fromFrame(const void *src, size_t srcSize); + +/** + * struct ZSTD_frameParams - zstd frame parameters stored in the frame header + * @frameContentSize: The frame content size, or 0 if not present. + * @windowSize: The window size, or 0 if the frame is a skippable frame. + * @dictID: The dictionary id, or 0 if not present. + * @checksumFlag: Whether a checksum was used. + */ +typedef struct { + unsigned long long frameContentSize; + unsigned int windowSize; + unsigned int dictID; + unsigned int checksumFlag; +} ZSTD_frameParams; + +/** + * ZSTD_getFrameParams() - extracts parameters from a zstd or skippable frame + * @fparamsPtr: On success the frame parameters are written here. + * @src: The source buffer. It must point to a zstd or skippable frame. + * @srcSize: The size of the source buffer. `ZSTD_frameHeaderSize_max` is + * always large enough to succeed. + * + * Return: 0 on success. If more data is required it returns how many bytes + * must be provided to make forward progress. Otherwise it returns + * an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_getFrameParams(ZSTD_frameParams *fparamsPtr, const void *src, + size_t srcSize); + +/*-***************************************************************************** + * Buffer-less and synchronous inner streaming functions + * + * This is an advanced API, giving full control over buffer management, for + * users which need direct control over memory. + * But it's also a complex one, with many restrictions (documented below). + * Prefer using normal streaming API for an easier experience + ******************************************************************************/ + +/*-***************************************************************************** + * Buffer-less streaming compression (synchronous mode) + * + * A ZSTD_CCtx object is required to track streaming operations. + * Use ZSTD_initCCtx() to initialize a context. + * ZSTD_CCtx object can be re-used multiple times within successive compression + * operations. + * + * Start by initializing a context. + * Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary + * compression, + * or ZSTD_compressBegin_advanced(), for finer parameter control. + * It's also possible to duplicate a reference context which has already been + * initialized, using ZSTD_copyCCtx() + * + * Then, consume your input using ZSTD_compressContinue(). + * There are some important considerations to keep in mind when using this + * advanced function : + * - ZSTD_compressContinue() has no internal buffer. It uses externally provided + * buffer only. + * - Interface is synchronous : input is consumed entirely and produce 1+ + * (or more) compressed blocks. + * - Caller must ensure there is enough space in `dst` to store compressed data + * under worst case scenario. Worst case evaluation is provided by + * ZSTD_compressBound(). + * ZSTD_compressContinue() doesn't guarantee recover after a failed + * compression. + * - ZSTD_compressContinue() presumes prior input ***is still accessible and + * unmodified*** (up to maximum distance size, see WindowLog). + * It remembers all previous contiguous blocks, plus one separated memory + * segment (which can itself consists of multiple contiguous blocks) + * - ZSTD_compressContinue() detects that prior input has been overwritten when + * `src` buffer overlaps. In which case, it will "discard" the relevant memory + * section from its history. + * + * Finish a frame with ZSTD_compressEnd(), which will write the last block(s) + * and optional checksum. It's possible to use srcSize==0, in which case, it + * will write a final empty block to end the frame. Without last block mark, + * frames will be considered unfinished (corrupted) by decoders. + * + * `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress some new + * frame. + ******************************************************************************/ + +/*===== Buffer-less streaming compression functions =====*/ +size_t ZSTD_compressBegin(ZSTD_CCtx *cctx, int compressionLevel); +size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx *cctx, const void *dict, + size_t dictSize, int compressionLevel); +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx *cctx, const void *dict, + size_t dictSize, ZSTD_parameters params, + unsigned long long pledgedSrcSize); +size_t ZSTD_copyCCtx(ZSTD_CCtx *cctx, const ZSTD_CCtx *preparedCCtx, + unsigned long long pledgedSrcSize); +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, + unsigned long long pledgedSrcSize); +size_t ZSTD_compressContinue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +size_t ZSTD_compressEnd(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); + + + +/*-***************************************************************************** + * Buffer-less streaming decompression (synchronous mode) + * + * A ZSTD_DCtx object is required to track streaming operations. + * Use ZSTD_initDCtx() to initialize a context. + * A ZSTD_DCtx object can be re-used multiple times. + * + * First typical operation is to retrieve frame parameters, using + * ZSTD_getFrameParams(). It fills a ZSTD_frameParams structure which provide + * important information to correctly decode the frame, such as the minimum + * rolling buffer size to allocate to decompress data (`windowSize`), and the + * dictionary ID used. + * Note: content size is optional, it may not be present. 0 means unknown. + * Note that these values could be wrong, either because of data malformation, + * or because an attacker is spoofing deliberate false information. As a + * consequence, check that values remain within valid application range, + * especially `windowSize`, before allocation. Each application can set its own + * limit, depending on local restrictions. For extended interoperability, it is + * recommended to support at least 8 MB. + * Frame parameters are extracted from the beginning of the compressed frame. + * Data fragment must be large enough to ensure successful decoding, typically + * `ZSTD_frameHeaderSize_max` bytes. + * Result: 0: successful decoding, the `ZSTD_frameParams` structure is filled. + * >0: `srcSize` is too small, provide at least this many bytes. + * errorCode, which can be tested using ZSTD_isError(). + * + * Start decompression, with ZSTD_decompressBegin() or + * ZSTD_decompressBegin_usingDict(). Alternatively, you can copy a prepared + * context, using ZSTD_copyDCtx(). + * + * Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() + * alternatively. + * ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' + * to ZSTD_decompressContinue(). + * ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will + * fail. + * + * The result of ZSTD_decompressContinue() is the number of bytes regenerated + * within 'dst' (necessarily <= dstCapacity). It can be zero, which is not an + * error; it just means ZSTD_decompressContinue() has decoded some metadata + * item. It can also be an error code, which can be tested with ZSTD_isError(). + * + * ZSTD_decompressContinue() needs previous data blocks during decompression, up + * to `windowSize`. They should preferably be located contiguously, prior to + * current block. Alternatively, a round buffer of sufficient size is also + * possible. Sufficient size is determined by frame parameters. + * ZSTD_decompressContinue() is very sensitive to contiguity, if 2 blocks don't + * follow each other, make sure that either the compressor breaks contiguity at + * the same place, or that previous contiguous segment is large enough to + * properly handle maximum back-reference. + * + * A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. + * Context can then be reset to start a new decompression. + * + * Note: it's possible to know if next input to present is a header or a block, + * using ZSTD_nextInputType(). This information is not required to properly + * decode a frame. + * + * == Special case: skippable frames == + * + * Skippable frames allow integration of user-defined data into a flow of + * concatenated frames. Skippable frames will be ignored (skipped) by a + * decompressor. The format of skippable frames is as follows: + * a) Skippable frame ID - 4 Bytes, Little endian format, any value from + * 0x184D2A50 to 0x184D2A5F + * b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits + * c) Frame Content - any content (User Data) of length equal to Frame Size + * For skippable frames ZSTD_decompressContinue() always returns 0. + * For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 + * what means that a frame is skippable. + * Note: If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might + * actually be a zstd encoded frame with no content. For purposes of + * decompression, it is valid in both cases to skip the frame using + * ZSTD_findFrameCompressedSize() to find its size in bytes. + * It also returns frame size as fparamsPtr->frameContentSize. + ******************************************************************************/ + +/*===== Buffer-less streaming decompression functions =====*/ +size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx); +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict, + size_t dictSize); +void ZSTD_copyDCtx(ZSTD_DCtx *dctx, const ZSTD_DCtx *preparedDCtx); +size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx); +size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +typedef enum { + ZSTDnit_frameHeader, + ZSTDnit_blockHeader, + ZSTDnit_block, + ZSTDnit_lastBlock, + ZSTDnit_checksum, + ZSTDnit_skippableFrame +} ZSTD_nextInputType_e; +ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx); + +/*-***************************************************************************** + * Block functions + * + * Block functions produce and decode raw zstd blocks, without frame metadata. + * Frame metadata cost is typically ~18 bytes, which can be non-negligible for + * very small blocks (< 100 bytes). User will have to take in charge required + * information to regenerate data, such as compressed and content sizes. + * + * A few rules to respect: + * - Compressing and decompressing require a context structure + * + Use ZSTD_initCCtx() and ZSTD_initDCtx() + * - It is necessary to init context before starting + * + compression : ZSTD_compressBegin() + * + decompression : ZSTD_decompressBegin() + * + variants _usingDict() are also allowed + * + copyCCtx() and copyDCtx() work too + * - Block size is limited, it must be <= ZSTD_getBlockSizeMax() + * + If you need to compress more, cut data into multiple blocks + * + Consider using the regular ZSTD_compress() instead, as frame metadata + * costs become negligible when source size is large. + * - When a block is considered not compressible enough, ZSTD_compressBlock() + * result will be zero. In which case, nothing is produced into `dst`. + * + User must test for such outcome and deal directly with uncompressed data + * + ZSTD_decompressBlock() doesn't accept uncompressed data as input!!! + * + In case of multiple successive blocks, decoder must be informed of + * uncompressed block existence to follow proper history. Use + * ZSTD_insertBlock() in such a case. + ******************************************************************************/ + +/* Define for static allocation */ +#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) +/*===== Raw zstd block functions =====*/ +size_t ZSTD_getBlockSizeMax(ZSTD_CCtx *cctx); +size_t ZSTD_compressBlock(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart, + size_t blockSize); + +#endif /* ZSTD_H */ diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index 298f996969df632ba41b6c68f3d815678c89e079..57ec319a7f44ffedd047300b432513f09c53f30e 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h @@ -57,6 +57,7 @@ void cec_notifier_put(struct cec_notifier *n); * @pa: the CEC physical address * * Set a new CEC physical address. + * Does nothing if @n == NULL. */ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa); @@ -66,6 +67,7 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa); * @edid: the struct edid pointer * * Parses the EDID to obtain the new CEC physical address and set it. + * Does nothing if @n == NULL. */ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, const struct edid *edid); @@ -86,6 +88,14 @@ void cec_notifier_register(struct cec_notifier *n, */ void cec_notifier_unregister(struct cec_notifier *n); +/** + * cec_register_cec_notifier - register the notifier with the cec adapter. + * @adap: the CEC adapter + * @notifier: the CEC notifier + */ +void cec_register_cec_notifier(struct cec_adapter *adap, + struct cec_notifier *notifier); + #else static inline struct cec_notifier *cec_notifier_get(struct device *dev) { @@ -116,6 +126,23 @@ static inline void cec_notifier_unregister(struct cec_notifier *n) { } +static inline void cec_register_cec_notifier(struct cec_adapter *adap, + struct cec_notifier *notifier) +{ +} #endif +/** + * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID + * + * @n: the CEC notifier + * + * This is a simple helper function to invalidate the physical + * address. Does nothing if @n == NULL. + */ +static inline void cec_notifier_phys_addr_invalidate(struct cec_notifier *n) +{ + cec_notifier_set_phys_addr(n, CEC_PHYS_ADDR_INVALID); +} + #endif diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h new file mode 100644 index 0000000000000000000000000000000000000000..f09cc9579d53d19259419930b3d7d4c6a2a4e5a0 --- /dev/null +++ b/include/media/cec-pin.h @@ -0,0 +1,186 @@ +/* + * cec-pin.h - low-level CEC pin control + * + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef LINUX_CEC_PIN_H +#define LINUX_CEC_PIN_H + +#include +#include +#include + +enum cec_pin_state { + /* CEC is off */ + CEC_ST_OFF, + /* CEC is idle, waiting for Rx or Tx */ + CEC_ST_IDLE, + + /* Tx states */ + + /* Pending Tx, waiting for Signal Free Time to expire */ + CEC_ST_TX_WAIT, + /* Low-drive was detected, wait for bus to go high */ + CEC_ST_TX_WAIT_FOR_HIGH, + /* Drive CEC low for the start bit */ + CEC_ST_TX_START_BIT_LOW, + /* Drive CEC high for the start bit */ + CEC_ST_TX_START_BIT_HIGH, + /* Drive CEC low for the 0 bit */ + CEC_ST_TX_DATA_BIT_0_LOW, + /* Drive CEC high for the 0 bit */ + CEC_ST_TX_DATA_BIT_0_HIGH, + /* Drive CEC low for the 1 bit */ + CEC_ST_TX_DATA_BIT_1_LOW, + /* Drive CEC high for the 1 bit */ + CEC_ST_TX_DATA_BIT_1_HIGH, + /* + * Wait for start of sample time to check for Ack bit or first + * four initiator bits to check for Arbitration Lost. + */ + CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE, + /* Wait for end of bit period after sampling */ + CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE, + + /* Rx states */ + + /* Start bit low detected */ + CEC_ST_RX_START_BIT_LOW, + /* Start bit high detected */ + CEC_ST_RX_START_BIT_HIGH, + /* Wait for bit sample time */ + CEC_ST_RX_DATA_SAMPLE, + /* Wait for earliest end of bit period after sampling */ + CEC_ST_RX_DATA_POST_SAMPLE, + /* Wait for CEC to go high (i.e. end of bit period */ + CEC_ST_RX_DATA_HIGH, + /* Drive CEC low to send 0 Ack bit */ + CEC_ST_RX_ACK_LOW, + /* End of 0 Ack time, wait for earliest end of bit period */ + CEC_ST_RX_ACK_LOW_POST, + /* Wait for CEC to go high (i.e. end of bit period */ + CEC_ST_RX_ACK_HIGH_POST, + /* Wait for earliest end of bit period and end of message */ + CEC_ST_RX_ACK_FINISH, + + /* Start low drive */ + CEC_ST_LOW_DRIVE, + /* Monitor pin using interrupts */ + CEC_ST_RX_IRQ, + + /* Total number of pin states */ + CEC_PIN_STATES +}; + +/** + * struct cec_pin_ops - low-level CEC pin operations + * @read: read the CEC pin. Return true if high, false if low. + * @low: drive the CEC pin low. + * @high: stop driving the CEC pin. The pull-up will drive the pin + * high, unless someone else is driving the pin low. + * @enable_irq: optional, enable the interrupt to detect pin voltage changes. + * @disable_irq: optional, disable the interrupt. + * @free: optional. Free any allocated resources. Called when the + * adapter is deleted. + * @status: optional, log status information. + * + * These operations are used by the cec pin framework to manipulate + * the CEC pin. + */ +struct cec_pin_ops { + bool (*read)(struct cec_adapter *adap); + void (*low)(struct cec_adapter *adap); + void (*high)(struct cec_adapter *adap); + bool (*enable_irq)(struct cec_adapter *adap); + void (*disable_irq)(struct cec_adapter *adap); + void (*free)(struct cec_adapter *adap); + void (*status)(struct cec_adapter *adap, struct seq_file *file); +}; + +#define CEC_NUM_PIN_EVENTS 128 + +#define CEC_PIN_IRQ_UNCHANGED 0 +#define CEC_PIN_IRQ_DISABLE 1 +#define CEC_PIN_IRQ_ENABLE 2 + +struct cec_pin { + struct cec_adapter *adap; + const struct cec_pin_ops *ops; + struct task_struct *kthread; + wait_queue_head_t kthread_waitq; + struct hrtimer timer; + ktime_t ts; + unsigned int wait_usecs; + u16 la_mask; + bool enabled; + bool monitor_all; + bool rx_eom; + bool enable_irq_failed; + enum cec_pin_state state; + struct cec_msg tx_msg; + u32 tx_bit; + bool tx_nacked; + u32 tx_signal_free_time; + struct cec_msg rx_msg; + u32 rx_bit; + + struct cec_msg work_rx_msg; + u8 work_tx_status; + ktime_t work_tx_ts; + atomic_t work_irq_change; + atomic_t work_pin_events; + unsigned int work_pin_events_wr; + unsigned int work_pin_events_rd; + ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS]; + bool work_pin_is_high[CEC_NUM_PIN_EVENTS]; + ktime_t timer_ts; + u32 timer_cnt; + u32 timer_100ms_overruns; + u32 timer_300ms_overruns; + u32 timer_max_overrun; + u32 timer_sum_overrun; +}; + +/** + * cec_pin_changed() - update pin state from interrupt + * + * @adap: pointer to the cec adapter + * @value: when true the pin is high, otherwise it is low + * + * If changes of the CEC voltage are detected via an interrupt, then + * cec_pin_changed is called from the interrupt with the new value. + */ +void cec_pin_changed(struct cec_adapter *adap, bool value); + +/** + * cec_pin_allocate_adapter() - allocate a pin-based cec adapter + * + * @pin_ops: low-level pin operations + * @priv: will be stored in adap->priv and can be used by the adapter ops. + * Use cec_get_drvdata(adap) to get the priv pointer. + * @name: the name of the CEC adapter. Note: this name will be copied. + * @caps: capabilities of the CEC adapter. This will be ORed with + * CEC_CAP_MONITOR_ALL and CEC_CAP_MONITOR_PIN. + * + * Allocate a cec adapter using the cec pin framework. + * + * Return: a pointer to the cec adapter or an error pointer + */ +struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, + void *priv, const char *name, u32 caps); + +#endif diff --git a/include/media/cec.h b/include/media/cec.h index 56643b27e4b8f8c6c07a2c62b4c623e66f66fe99..df6b3bd3128493faf154834b421ab42345d6430c 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -31,6 +31,9 @@ #include #include +#define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \ + CEC_CAP_PASSTHROUGH | CEC_CAP_RC) + /** * struct cec_devnode - cec device node * @dev: cec device @@ -61,6 +64,7 @@ struct cec_devnode { struct cec_adapter; struct cec_data; +struct cec_pin; struct cec_data { struct list_head list; @@ -81,7 +85,13 @@ struct cec_msg_entry { struct cec_msg msg; }; -#define CEC_NUM_EVENTS CEC_EVENT_LOST_MSGS +struct cec_event_entry { + struct list_head list; + struct cec_event ev; +}; + +#define CEC_NUM_CORE_EVENTS 2 +#define CEC_NUM_EVENTS CEC_EVENT_PIN_CEC_HIGH struct cec_fh { struct list_head list; @@ -92,9 +102,11 @@ struct cec_fh { /* Events */ wait_queue_head_t wait; - unsigned int pending_events; - struct cec_event events[CEC_NUM_EVENTS]; struct mutex lock; + struct list_head events[CEC_NUM_EVENTS]; /* queued events */ + u8 queued_events[CEC_NUM_EVENTS]; + unsigned int total_queued_events; + struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS]; struct list_head msgs; /* queued messages */ unsigned int queued_msgs; }; @@ -114,6 +126,7 @@ struct cec_adap_ops { int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + void (*adap_free)(struct cec_adapter *adap); /* High-level CEC message callback */ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); @@ -167,16 +180,28 @@ struct cec_adapter { bool needs_hpd; bool is_configuring; bool is_configured; + bool cec_pin_is_high; u32 monitor_all_cnt; + u32 monitor_pin_cnt; u32 follower_cnt; struct cec_fh *cec_follower; struct cec_fh *cec_initiator; bool passthrough; struct cec_log_addrs log_addrs; + u32 tx_timeouts; + +#ifdef CONFIG_MEDIA_CEC_RC + bool rc_repeating; + int rc_last_scancode; + u64 rc_last_keypress; +#endif #ifdef CONFIG_CEC_NOTIFIER struct cec_notifier *notifier; #endif +#ifdef CONFIG_CEC_PIN + struct cec_pin *pin; +#endif struct dentry *cec_dir; struct dentry *status_file; @@ -184,7 +209,7 @@ struct cec_adapter { u16 phys_addrs[15]; u32 sequence; - char input_name[32]; + char device_name[32]; char input_phys[32]; char input_drv[32]; }; @@ -226,15 +251,50 @@ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, bool block); /* Called by the adapter */ -void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, - u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); +void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, + u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt, + u8 error_cnt, ktime_t ts); + +static inline void cec_transmit_done(struct cec_adapter *adap, u8 status, + u8 arb_lost_cnt, u8 nack_cnt, + u8 low_drive_cnt, u8 error_cnt) +{ + cec_transmit_done_ts(adap, status, arb_lost_cnt, nack_cnt, + low_drive_cnt, error_cnt, ktime_get()); +} /* * Simplified version of cec_transmit_done for hardware that doesn't retry * failed transmits. So this is always just one attempt in which case * the status is sufficient. */ -void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); -void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); +void cec_transmit_attempt_done_ts(struct cec_adapter *adap, + u8 status, ktime_t ts); + +static inline void cec_transmit_attempt_done(struct cec_adapter *adap, + u8 status) +{ + cec_transmit_attempt_done_ts(adap, status, ktime_get()); +} + +void cec_received_msg_ts(struct cec_adapter *adap, + struct cec_msg *msg, ktime_t ts); + +static inline void cec_received_msg(struct cec_adapter *adap, + struct cec_msg *msg) +{ + cec_received_msg_ts(adap, msg, ktime_get()); +} + +/** + * cec_queue_pin_cec_event() - queue a CEC pin event with a given timestamp. + * + * @adap: pointer to the cec adapter + * @is_high: when true the CEC pin is high, otherwise it is low + * @ts: the timestamp for this event + * + */ +void cec_queue_pin_cec_event(struct cec_adapter *adap, + bool is_high, ktime_t ts); /** * cec_get_edid_phys_addr() - find and return the physical address @@ -311,11 +371,6 @@ u16 cec_phys_addr_for_input(u16 phys_addr, u8 input); */ int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port); -#ifdef CONFIG_CEC_NOTIFIER -void cec_register_cec_notifier(struct cec_adapter *adap, - struct cec_notifier *notifier); -#endif - #else static inline int cec_register_adapter(struct cec_adapter *adap, diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h index 7c909da29d435759970b0523cc5ce98ae6493955..6ea2ce2418511255c3c7ec63ced3c2eeb34a18ff 100644 --- a/include/media/davinci/dm644x_ccdc.h +++ b/include/media/davinci/dm644x_ccdc.h @@ -103,16 +103,6 @@ struct ccdc_black_compensation { char gb; }; -/* structure for fault pixel correction */ -struct ccdc_fault_pixel { - /* Enable or Disable fault pixel correction */ - unsigned char enable; - /* Number of fault pixel */ - unsigned short fp_num; - /* Address of fault pixel table */ - unsigned long fpc_table_addr; -}; - /* Structure for CCDC configuration parameters for raw capture mode passed * by application */ @@ -125,8 +115,6 @@ struct ccdc_config_params_raw { struct ccdc_black_clamp blk_clamp; /* Structure for Black Compensation */ struct ccdc_black_compensation blk_comp; - /* Structure for Fault Pixel Module Configuration */ - struct ccdc_fault_pixel fault_pxl; }; diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h index 8e1a4d88daa024cc2b5df4e687d1d96f3925ae61..f003533602d0ff14e5393bc8f2d42941a658c2b2 100644 --- a/include/media/davinci/vpfe_capture.h +++ b/include/media/davinci/vpfe_capture.h @@ -183,14 +183,4 @@ struct vpfe_config_params { }; #endif /* End of __KERNEL__ */ -/** - * VPFE_CMD_S_CCDC_RAW_PARAMS - EXPERIMENTAL IOCTL to set raw capture params - * This can be used to configure modules such as defect pixel correction, - * color space conversion, culling etc. This is an experimental ioctl that - * will change in future kernels. So use this ioctl with care ! - * TODO: This is to be split into multiple ioctls and also explore the - * possibility of extending the v4l2 api to include this - **/ -#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 1, \ - void *) #endif /* _DAVINCI_VPFE_H */ diff --git a/include/media/drv-intf/saa7146.h b/include/media/drv-intf/saa7146.h index 96058a5a4acc3870f63298469e5b22e30601bc25..45294328614dc0f3fa938f5e4d796457cc62bcf3 100644 --- a/include/media/drv-intf/saa7146.h +++ b/include/media/drv-intf/saa7146.h @@ -96,7 +96,7 @@ struct saa7146_extension supported devices, last entry 0xffff, 0xfff */ struct module *module; struct pci_driver driver; - struct pci_device_id *pci_tbl; + const struct pci_device_id *pci_tbl; /* extension functions */ int (*probe)(struct saa7146_dev *); diff --git a/include/media/i2c/ir-kbd-i2c.h b/include/media/i2c/ir-kbd-i2c.h index d8564354debb4391a0193997280653a2cd288bc7..ac8c55617a79902122882e4b0c2856b9e63f9148 100644 --- a/include/media/i2c/ir-kbd-i2c.h +++ b/include/media/i2c/ir-kbd-i2c.h @@ -20,7 +20,8 @@ struct IR_i2c { struct delayed_work work; char name[32]; char phys[32]; - int (*get_key)(struct IR_i2c *ir, enum rc_type *protocol, + int (*get_key)(struct IR_i2c *ir, + enum rc_proto *protocol, u32 *scancode, u8 *toggle); }; @@ -38,14 +39,15 @@ enum ir_kbd_get_key_fn { struct IR_i2c_init_data { char *ir_codes; const char *name; - u64 type; /* RC_BIT_RC5, etc */ + u64 type; /* RC_PROTO_BIT_RC5, etc */ u32 polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */ /* * Specify either a function pointer or a value indicating one of * ir_kbd_i2c's internal get_key functions */ - int (*get_key)(struct IR_i2c *ir, enum rc_type *protocol, + int (*get_key)(struct IR_i2c *ir, + enum rc_proto *protocol, u32 *scancode, u8 *toggle); enum ir_kbd_get_key_fn internal_get_key_func; diff --git a/include/media/media-device.h b/include/media/media-device.h index 6896266031b9905ff6ba61eb0706e5550e85f616..bcc6ec434f1ff515df90d724efd71c22be724425 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -68,7 +68,6 @@ struct media_device_ops { * @serial: Device serial number (optional) * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision - * @driver_version: Device driver version * @topology_version: Monotonic counter for storing the version of the graph * topology. Should be incremented each time the topology changes. * @id: Unique ID used on the last registered graph object @@ -134,7 +133,6 @@ struct media_device { char serial[40]; char bus_info[32]; u32 hw_revision; - u32 driver_version; u64 topology_version; @@ -249,11 +247,6 @@ void media_device_cleanup(struct media_device *mdev); * driver-specific format. When possible the revision should be formatted * with the KERNEL_VERSION() macro. * - * - &media_entity.driver_version is formatted with the KERNEL_VERSION() - * macro. The version minor must be incremented when new features are added - * to the userspace API without breaking binary compatibility. The version - * major must be incremented when binary compatibility is broken. - * * .. note:: * * #) Upon successful registration a character device named media[0-9]+ is created. The device major and minor numbers are dynamic. The model name is exported as a sysfs attribute. diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 754182d296689675f0254c30c7de2adb00c8d0a1..222d379960b7a21c59d1a5597c4be3cdf5974389 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -805,7 +805,7 @@ struct media_link *media_entity_find_link(struct media_pad *source, * Return: returns a pointer to the pad at the remote end of the first found * enabled link, or %NULL if no enabled link has been found. */ -struct media_pad *media_entity_remote_pad(struct media_pad *pad); +struct media_pad *media_entity_remote_pad(const struct media_pad *pad); /** * media_entity_get - Get a reference to the parent module diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 78dea39a9b39040523231dda53db39f942fcedfe..314a1edb6189bf47c722723511cf5ede6d7c9233 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -72,7 +72,7 @@ enum rc_filter_type { * @dev: driver model's view of this device * @managed_alloc: devm_rc_allocate_device was used to create rc_dev * @sysfs_groups: sysfs attribute groups - * @input_name: name of the input child device + * @device_name: name of the rc child device * @input_phys: physical path to the input child device * @input_id: id of the input child device (struct input_id) * @driver_name: name of the hardware driver which registered this device @@ -87,11 +87,12 @@ enum rc_filter_type { * @idle: used to keep track of RX state * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed * wakeup protocols is the set of all raw encoders - * @allowed_protocols: bitmask with the supported RC_BIT_* protocols - * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols - * @allowed_wakeup_protocols: bitmask with the supported RC_BIT_* wakeup protocols - * @wakeup_protocol: the enabled RC_TYPE_* wakeup protocol or - * RC_TYPE_UNKNOWN if disabled. + * @allowed_protocols: bitmask with the supported RC_PROTO_BIT_* protocols + * @enabled_protocols: bitmask with the enabled RC_PROTO_BIT_* protocols + * @allowed_wakeup_protocols: bitmask with the supported RC_PROTO_BIT_* wakeup + * protocols + * @wakeup_protocol: the enabled RC_PROTO_* wakeup protocol or + * RC_PROTO_UNKNOWN if disabled. * @scancode_filter: scancode filter * @scancode_wakeup_filter: scancode wakeup filters * @scancode_mask: some hardware decoders are not capable of providing the full @@ -138,10 +139,10 @@ struct rc_dev { struct device dev; bool managed_alloc; const struct attribute_group *sysfs_groups[5]; - const char *input_name; + const char *device_name; const char *input_phys; struct input_id input_id; - char *driver_name; + const char *driver_name; const char *map_name; struct rc_map rc_map; struct mutex lock; @@ -154,7 +155,7 @@ struct rc_dev { u64 allowed_protocols; u64 enabled_protocols; u64 allowed_wakeup_protocols; - enum rc_type wakeup_protocol; + enum rc_proto wakeup_protocol; struct rc_scancode_filter scancode_filter; struct rc_scancode_filter scancode_wakeup_filter; u32 scancode_mask; @@ -165,7 +166,7 @@ struct rc_dev { unsigned long keyup_jiffies; struct timer_list timer_keyup; u32 last_keycode; - enum rc_type last_protocol; + enum rc_proto last_protocol; u32 last_scancode; u8 last_toggle; u32 timeout; @@ -173,7 +174,7 @@ struct rc_dev { u32 max_timeout; u32 rx_resolution; u32 tx_resolution; - int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto); int (*open)(struct rc_dev *dev); void (*close)(struct rc_dev *dev); int (*s_tx_mask)(struct rc_dev *dev, u32 mask); @@ -262,8 +263,10 @@ int rc_open(struct rc_dev *rdev); void rc_close(struct rc_dev *rdev); void rc_repeat(struct rc_dev *dev); -void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle); -void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle); +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, + u8 toggle); +void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol, + u32 scancode, u8 toggle); void rc_keyup(struct rc_dev *dev); u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode); @@ -272,14 +275,6 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode); * The Raw interface is specific to InfraRed. It may be a good idea to * split it later into a separate header. */ - -enum raw_event_type { - IR_SPACE = (1 << 0), - IR_PULSE = (1 << 1), - IR_START_EVENT = (1 << 2), - IR_STOP_EVENT = (1 << 3), -}; - struct ir_raw_event { union { u32 duration; @@ -308,11 +303,11 @@ static inline void init_ir_raw_event(struct ir_raw_event *ev) void ir_raw_event_handle(struct rc_dev *dev); int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); -int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type); +int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse); int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev); void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); -int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode, +int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max); static inline void ir_raw_event_reset(struct rc_dev *dev) @@ -340,4 +335,35 @@ static inline u32 ir_extract_bits(u32 data, u32 mask) return value; } +/* Get NEC scancode and protocol type from address and command bytes */ +static inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address, + u8 command, u8 not_command, + enum rc_proto *protocol) +{ + u32 scancode; + + if ((command ^ not_command) != 0xff) { + /* NEC transport, but modified protocol, used by at + * least Apple and TiVo remotes + */ + scancode = not_address << 24 | + address << 16 | + not_command << 8 | + command; + *protocol = RC_PROTO_NEC32; + } else if ((address ^ not_address) != 0xff) { + /* Extended NEC */ + scancode = address << 16 | + not_address << 8 | + command; + *protocol = RC_PROTO_NECX; + } else { + /* Normal NEC */ + scancode = address << 8 | command; + *protocol = RC_PROTO_NEC; + } + + return scancode; +} + #endif /* _RC_CORE */ diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 1a815a572fa184a22cdf5c3240bea59f0514de4d..2a160e6e823c46dd96781478e6483d9542e64aa1 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -12,113 +12,122 @@ #include /** - * enum rc_type - type of the Remote Controller protocol + * enum rc_proto - the Remote Controller protocol * - * @RC_TYPE_UNKNOWN: Protocol not known - * @RC_TYPE_OTHER: Protocol known but proprietary - * @RC_TYPE_RC5: Philips RC5 protocol - * @RC_TYPE_RC5X_20: Philips RC5x 20 bit protocol - * @RC_TYPE_RC5_SZ: StreamZap variant of RC5 - * @RC_TYPE_JVC: JVC protocol - * @RC_TYPE_SONY12: Sony 12 bit protocol - * @RC_TYPE_SONY15: Sony 15 bit protocol - * @RC_TYPE_SONY20: Sony 20 bit protocol - * @RC_TYPE_NEC: NEC protocol - * @RC_TYPE_NECX: Extended NEC protocol - * @RC_TYPE_NEC32: NEC 32 bit protocol - * @RC_TYPE_SANYO: Sanyo protocol - * @RC_TYPE_MCIR2_KBD: RC6-ish MCE keyboard - * @RC_TYPE_MCIR2_MSE: RC6-ish MCE mouse - * @RC_TYPE_RC6_0: Philips RC6-0-16 protocol - * @RC_TYPE_RC6_6A_20: Philips RC6-6A-20 protocol - * @RC_TYPE_RC6_6A_24: Philips RC6-6A-24 protocol - * @RC_TYPE_RC6_6A_32: Philips RC6-6A-32 protocol - * @RC_TYPE_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol - * @RC_TYPE_SHARP: Sharp protocol - * @RC_TYPE_XMP: XMP protocol - * @RC_TYPE_CEC: CEC protocol + * @RC_PROTO_UNKNOWN: Protocol not known + * @RC_PROTO_OTHER: Protocol known but proprietary + * @RC_PROTO_RC5: Philips RC5 protocol + * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol + * @RC_PROTO_RC5_SZ: StreamZap variant of RC5 + * @RC_PROTO_JVC: JVC protocol + * @RC_PROTO_SONY12: Sony 12 bit protocol + * @RC_PROTO_SONY15: Sony 15 bit protocol + * @RC_PROTO_SONY20: Sony 20 bit protocol + * @RC_PROTO_NEC: NEC protocol + * @RC_PROTO_NECX: Extended NEC protocol + * @RC_PROTO_NEC32: NEC 32 bit protocol + * @RC_PROTO_SANYO: Sanyo protocol + * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard + * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse + * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol + * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol + * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol + * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol + * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol + * @RC_PROTO_SHARP: Sharp protocol + * @RC_PROTO_XMP: XMP protocol + * @RC_PROTO_CEC: CEC protocol */ -enum rc_type { - RC_TYPE_UNKNOWN = 0, - RC_TYPE_OTHER = 1, - RC_TYPE_RC5 = 2, - RC_TYPE_RC5X_20 = 3, - RC_TYPE_RC5_SZ = 4, - RC_TYPE_JVC = 5, - RC_TYPE_SONY12 = 6, - RC_TYPE_SONY15 = 7, - RC_TYPE_SONY20 = 8, - RC_TYPE_NEC = 9, - RC_TYPE_NECX = 10, - RC_TYPE_NEC32 = 11, - RC_TYPE_SANYO = 12, - RC_TYPE_MCIR2_KBD = 13, - RC_TYPE_MCIR2_MSE = 14, - RC_TYPE_RC6_0 = 15, - RC_TYPE_RC6_6A_20 = 16, - RC_TYPE_RC6_6A_24 = 17, - RC_TYPE_RC6_6A_32 = 18, - RC_TYPE_RC6_MCE = 19, - RC_TYPE_SHARP = 20, - RC_TYPE_XMP = 21, - RC_TYPE_CEC = 22, +enum rc_proto { + RC_PROTO_UNKNOWN = 0, + RC_PROTO_OTHER = 1, + RC_PROTO_RC5 = 2, + RC_PROTO_RC5X_20 = 3, + RC_PROTO_RC5_SZ = 4, + RC_PROTO_JVC = 5, + RC_PROTO_SONY12 = 6, + RC_PROTO_SONY15 = 7, + RC_PROTO_SONY20 = 8, + RC_PROTO_NEC = 9, + RC_PROTO_NECX = 10, + RC_PROTO_NEC32 = 11, + RC_PROTO_SANYO = 12, + RC_PROTO_MCIR2_KBD = 13, + RC_PROTO_MCIR2_MSE = 14, + RC_PROTO_RC6_0 = 15, + RC_PROTO_RC6_6A_20 = 16, + RC_PROTO_RC6_6A_24 = 17, + RC_PROTO_RC6_6A_32 = 18, + RC_PROTO_RC6_MCE = 19, + RC_PROTO_SHARP = 20, + RC_PROTO_XMP = 21, + RC_PROTO_CEC = 22, }; -#define RC_BIT_NONE 0ULL -#define RC_BIT_UNKNOWN BIT_ULL(RC_TYPE_UNKNOWN) -#define RC_BIT_OTHER BIT_ULL(RC_TYPE_OTHER) -#define RC_BIT_RC5 BIT_ULL(RC_TYPE_RC5) -#define RC_BIT_RC5X_20 BIT_ULL(RC_TYPE_RC5X_20) -#define RC_BIT_RC5_SZ BIT_ULL(RC_TYPE_RC5_SZ) -#define RC_BIT_JVC BIT_ULL(RC_TYPE_JVC) -#define RC_BIT_SONY12 BIT_ULL(RC_TYPE_SONY12) -#define RC_BIT_SONY15 BIT_ULL(RC_TYPE_SONY15) -#define RC_BIT_SONY20 BIT_ULL(RC_TYPE_SONY20) -#define RC_BIT_NEC BIT_ULL(RC_TYPE_NEC) -#define RC_BIT_NECX BIT_ULL(RC_TYPE_NECX) -#define RC_BIT_NEC32 BIT_ULL(RC_TYPE_NEC32) -#define RC_BIT_SANYO BIT_ULL(RC_TYPE_SANYO) -#define RC_BIT_MCIR2_KBD BIT_ULL(RC_TYPE_MCIR2_KBD) -#define RC_BIT_MCIR2_MSE BIT_ULL(RC_TYPE_MCIR2_MSE) -#define RC_BIT_RC6_0 BIT_ULL(RC_TYPE_RC6_0) -#define RC_BIT_RC6_6A_20 BIT_ULL(RC_TYPE_RC6_6A_20) -#define RC_BIT_RC6_6A_24 BIT_ULL(RC_TYPE_RC6_6A_24) -#define RC_BIT_RC6_6A_32 BIT_ULL(RC_TYPE_RC6_6A_32) -#define RC_BIT_RC6_MCE BIT_ULL(RC_TYPE_RC6_MCE) -#define RC_BIT_SHARP BIT_ULL(RC_TYPE_SHARP) -#define RC_BIT_XMP BIT_ULL(RC_TYPE_XMP) -#define RC_BIT_CEC BIT_ULL(RC_TYPE_CEC) +#define RC_PROTO_BIT_NONE 0ULL +#define RC_PROTO_BIT_UNKNOWN BIT_ULL(RC_PROTO_UNKNOWN) +#define RC_PROTO_BIT_OTHER BIT_ULL(RC_PROTO_OTHER) +#define RC_PROTO_BIT_RC5 BIT_ULL(RC_PROTO_RC5) +#define RC_PROTO_BIT_RC5X_20 BIT_ULL(RC_PROTO_RC5X_20) +#define RC_PROTO_BIT_RC5_SZ BIT_ULL(RC_PROTO_RC5_SZ) +#define RC_PROTO_BIT_JVC BIT_ULL(RC_PROTO_JVC) +#define RC_PROTO_BIT_SONY12 BIT_ULL(RC_PROTO_SONY12) +#define RC_PROTO_BIT_SONY15 BIT_ULL(RC_PROTO_SONY15) +#define RC_PROTO_BIT_SONY20 BIT_ULL(RC_PROTO_SONY20) +#define RC_PROTO_BIT_NEC BIT_ULL(RC_PROTO_NEC) +#define RC_PROTO_BIT_NECX BIT_ULL(RC_PROTO_NECX) +#define RC_PROTO_BIT_NEC32 BIT_ULL(RC_PROTO_NEC32) +#define RC_PROTO_BIT_SANYO BIT_ULL(RC_PROTO_SANYO) +#define RC_PROTO_BIT_MCIR2_KBD BIT_ULL(RC_PROTO_MCIR2_KBD) +#define RC_PROTO_BIT_MCIR2_MSE BIT_ULL(RC_PROTO_MCIR2_MSE) +#define RC_PROTO_BIT_RC6_0 BIT_ULL(RC_PROTO_RC6_0) +#define RC_PROTO_BIT_RC6_6A_20 BIT_ULL(RC_PROTO_RC6_6A_20) +#define RC_PROTO_BIT_RC6_6A_24 BIT_ULL(RC_PROTO_RC6_6A_24) +#define RC_PROTO_BIT_RC6_6A_32 BIT_ULL(RC_PROTO_RC6_6A_32) +#define RC_PROTO_BIT_RC6_MCE BIT_ULL(RC_PROTO_RC6_MCE) +#define RC_PROTO_BIT_SHARP BIT_ULL(RC_PROTO_SHARP) +#define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP) +#define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) -#define RC_BIT_ALL (RC_BIT_UNKNOWN | RC_BIT_OTHER | \ - RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ - RC_BIT_JVC | \ - RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ - RC_BIT_SANYO | \ - RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ - RC_BIT_XMP | RC_BIT_CEC) +#define RC_PROTO_BIT_ALL \ + (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ + RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ + RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \ + RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \ + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \ + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \ + RC_PROTO_BIT_SANYO | \ + RC_PROTO_BIT_MCIR2_KBD | RC_PROTO_BIT_MCIR2_MSE | \ + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ + RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ + RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC) /* All rc protocols for which we have decoders */ -#define RC_BIT_ALL_IR_DECODER \ - (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ - RC_BIT_JVC | \ - RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ - RC_BIT_SANYO | RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ - RC_BIT_XMP) +#define RC_PROTO_BIT_ALL_IR_DECODER \ + (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ + RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \ + RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \ + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \ + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \ + RC_PROTO_BIT_SANYO | RC_PROTO_BIT_MCIR2_KBD | \ + RC_PROTO_BIT_MCIR2_MSE | \ + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ + RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ + RC_PROTO_BIT_XMP) -#define RC_BIT_ALL_IR_ENCODER \ - (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ - RC_BIT_JVC | \ - RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ - RC_BIT_SANYO | RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | \ - RC_BIT_SHARP) +#define RC_PROTO_BIT_ALL_IR_ENCODER \ + (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ + RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \ + RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \ + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \ + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \ + RC_PROTO_BIT_SANYO | RC_PROTO_BIT_MCIR2_KBD | \ + RC_PROTO_BIT_MCIR2_MSE | \ + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ + RC_PROTO_BIT_RC6_6A_24 | \ + RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ + RC_PROTO_BIT_SHARP) #define RC_SCANCODE_UNKNOWN(x) (x) #define RC_SCANCODE_OTHER(x) (x) @@ -148,8 +157,8 @@ struct rc_map_table { * @size: Max number of entries * @len: Number of entries that are in use * @alloc: size of \*scan, in bytes - * @rc_type: type of the remote controller protocol, as defined at - * enum &rc_type + * @rc_proto: type of the remote controller protocol, as defined at + * enum &rc_proto * @name: name of the key map table * @lock: lock to protect access to this structure */ @@ -158,7 +167,7 @@ struct rc_map { unsigned int size; unsigned int len; unsigned int alloc; - enum rc_type rc_type; + enum rc_proto rc_proto; const char *name; spinlock_t lock; }; @@ -313,6 +322,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_WINFAST "rc-winfast" #define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe" #define RC_MAP_SU3000 "rc-su3000" +#define RC_MAP_ZX_IRDEC "rc-zx-irdec" /* * Please, do not just append newer Remote Controller names at the end. diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h index 2b94662d005c4991094096751a635220bdbb15f4..7ec857f805a6c724fbd06d3c1708fb1c6be8fabc 100644 --- a/include/media/v4l2-clk.h +++ b/include/media/v4l2-clk.h @@ -70,7 +70,7 @@ static inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id, #define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \ "%d-%04x", adap, client) -#define v4l2_clk_name_of(name, size, of_full_name) snprintf(name, size, \ - "of-%s", of_full_name) +#define v4l2_clk_name_of(name, size, node) snprintf(name, size, \ + "of-%pOF", node) #endif diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 2d2aed56922fb43a7988531b37a1bdfe16310b6b..dacfe54057f8f1f185bc49c1fe25fea8ea07d59f 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -340,17 +340,17 @@ struct v4l2_ctrl_config { * v4l2_ctrl_fill - Fill in the control fields based on the control ID. * * @id: ID of the control - * @name: name of the control - * @type: type of the control - * @min: minimum value for the control - * @max: maximum value for the control - * @step: control step - * @def: default value for the control - * @flags: flags to be used on the control + * @name: pointer to be filled with a string with the name of the control + * @type: pointer for storing the type of the control + * @min: pointer for storing the minimum value for the control + * @max: pointer for storing the maximum value for the control + * @step: pointer for storing the control step + * @def: pointer for storing the default value for the control + * @flags: pointer for storing the flags to be used on the control * * This works for all standard V4L2 controls. * For non-standard controls it will only fill in the given arguments - * and @name will be %NULL. + * and @name content will be set to %NULL. * * This function will overwrite the contents of @name, @type and @flags. * The contents of @min, @max, @step and @def may be modified depending on diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h index f9dcd54c17458f0d19dffb46cc29fbb550a1c22f..5c1d50f78e1295e6d589bf13557b7c24e7c0c94c 100644 --- a/include/media/v4l2-flash-led-class.h +++ b/include/media/v4l2-flash-led-class.h @@ -56,8 +56,7 @@ struct v4l2_flash_ops { * struct v4l2_flash_config - V4L2 Flash sub-device initialization data * @dev_name: the name of the media entity, * unique in the system - * @torch_intensity: constraints for the LED in torch mode - * @indicator_intensity: constraints for the indicator LED + * @intensity: non-flash strobe constraints for the LED * @flash_faults: bitmask of flash faults that the LED flash class * device can report; corresponding LED_FAULT* bit * definitions are available in the header file @@ -66,8 +65,7 @@ struct v4l2_flash_ops { */ struct v4l2_flash_config { char dev_name[32]; - struct led_flash_setting torch_intensity; - struct led_flash_setting indicator_intensity; + struct led_flash_setting intensity; u32 flash_faults; unsigned int has_external_strobe:1; }; @@ -85,7 +83,7 @@ struct v4l2_flash_config { */ struct v4l2_flash { struct led_classdev_flash *fled_cdev; - struct led_classdev_flash *iled_cdev; + struct led_classdev *iled_cdev; const struct v4l2_flash_ops *ops; struct v4l2_subdev sd; @@ -110,12 +108,13 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c) * @dev: flash device, e.g. an I2C device * @fwn: fwnode_handle of the LED, may be NULL if the same as device's * @fled_cdev: LED flash class device to wrap - * @iled_cdev: LED flash class device representing indicator LED associated - * with fled_cdev, may be NULL * @ops: V4L2 Flash device ops * @config: initialization data for V4L2 Flash sub-device * * Create V4L2 Flash sub-device wrapping given LED subsystem device. + * The ops pointer is stored by the V4L2 flash framework. No + * references are held to config nor its contents once this function + * has returned. * * Returns: A valid pointer, or, when an error occurs, the return * value is encoded using ERR_PTR(). Use IS_ERR() to check and @@ -124,9 +123,27 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c) struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev_flash *iled_cdev, - const struct v4l2_flash_ops *ops, - struct v4l2_flash_config *config); + const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config); + +/** + * v4l2_flash_indicator_init - initialize V4L2 indicator sub-device + * @dev: flash device, e.g. an I2C device + * @fwn: fwnode_handle of the LED, may be NULL if the same as device's + * @iled_cdev: LED flash class device representing the indicator LED + * @config: initialization data for V4L2 Flash sub-device + * + * Create V4L2 Flash sub-device wrapping given LED subsystem device. + * The ops pointer is stored by the V4L2 flash framework. No + * references are held to config nor its contents once this function + * has returned. + * + * Returns: A valid pointer, or, when an error occurs, the return + * value is encoded using ERR_PTR(). Use IS_ERR() to check and + * PTR_ERR() to obtain the numeric return value. + */ +struct v4l2_flash *v4l2_flash_indicator_init( + struct device *dev, struct fwnode_handle *fwn, + struct led_classdev *iled_cdev, struct v4l2_flash_config *config); /** * v4l2_flash_release - release V4L2 Flash sub-device @@ -140,9 +157,14 @@ void v4l2_flash_release(struct v4l2_flash *v4l2_flash); static inline struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev_flash *iled_cdev, - const struct v4l2_flash_ops *ops, - struct v4l2_flash_config *config) + const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config) +{ + return NULL; +} + +static inline struct v4l2_flash *v4l2_flash_indicator_init( + struct device *dev, struct fwnode_handle *fwn, + struct led_classdev *iled_cdev, struct v4l2_flash_config *config) { return NULL; } diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index ecc1233a873efc71e0be6734d8e6e4044ee0e3b5..7adec9851d9e9124187a845c0ce2fae264b53e8a 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -26,6 +26,8 @@ struct fwnode_handle; +#define V4L2_FWNODE_CSI2_MAX_DATA_LANES 4 + /** * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure * @flags: media bus (V4L2_MBUS_*) flags @@ -37,10 +39,10 @@ struct fwnode_handle; */ struct v4l2_fwnode_bus_mipi_csi2 { unsigned int flags; - unsigned char data_lanes[4]; + unsigned char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES]; unsigned char clock_lane; unsigned short num_data_lanes; - bool lane_polarities[5]; + bool lane_polarities[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES]; }; /** @@ -55,6 +57,24 @@ struct v4l2_fwnode_bus_parallel { unsigned char data_shift; }; +/** + * struct v4l2_fwnode_bus_mipi_csi1 - CSI-1/CCP2 data bus structure + * @clock_inv: polarity of clock/strobe signal + * false - not inverted, true - inverted + * @strobe: false - data/clock, true - data/strobe + * @lane_polarity: the polarities of the clock (index 0) and data lanes + * index (1) + * @data_lane: the number of the data lane + * @clock_lane: the number of the clock lane + */ +struct v4l2_fwnode_bus_mipi_csi1 { + bool clock_inv; + bool strobe; + bool lane_polarity[2]; + unsigned char data_lane; + unsigned char clock_lane; +}; + /** * struct v4l2_fwnode_endpoint - the endpoint data structure * @base: fwnode endpoint of the v4l2_fwnode @@ -72,6 +92,7 @@ struct v4l2_fwnode_endpoint { enum v4l2_mbus_type bus_type; union { struct v4l2_fwnode_bus_parallel parallel; + struct v4l2_fwnode_bus_mipi_csi1 mipi_csi1; struct v4l2_fwnode_bus_mipi_csi2 mipi_csi2; } bus; u64 *link_frequencies; diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 34cc99e093ef79780fb92f2793a08b044f8713cf..93f8afcb7a22056faa2c2f3d52ca2f495f27f1fd 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -69,11 +69,15 @@ * @V4L2_MBUS_PARALLEL: parallel interface with hsync and vsync * @V4L2_MBUS_BT656: parallel interface with embedded synchronisation, can * also be used for BT.1120 + * @V4L2_MBUS_CSI1: MIPI CSI-1 serial interface + * @V4L2_MBUS_CCP2: CCP2 (Compact Camera Port 2) * @V4L2_MBUS_CSI2: MIPI CSI-2 serial interface */ enum v4l2_mbus_type { V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, + V4L2_MBUS_CSI1, + V4L2_MBUS_CCP2, V4L2_MBUS_CSI2, }; @@ -113,4 +117,30 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, mbus_fmt->code = code; } +static inline void v4l2_fill_pix_format_mplane( + struct v4l2_pix_format_mplane *pix_mp_fmt, + const struct v4l2_mbus_framefmt *mbus_fmt) +{ + pix_mp_fmt->width = mbus_fmt->width; + pix_mp_fmt->height = mbus_fmt->height; + pix_mp_fmt->field = mbus_fmt->field; + pix_mp_fmt->colorspace = mbus_fmt->colorspace; + pix_mp_fmt->ycbcr_enc = mbus_fmt->ycbcr_enc; + pix_mp_fmt->quantization = mbus_fmt->quantization; + pix_mp_fmt->xfer_func = mbus_fmt->xfer_func; +} + +static inline void v4l2_fill_mbus_format_mplane( + struct v4l2_mbus_framefmt *mbus_fmt, + const struct v4l2_pix_format_mplane *pix_mp_fmt) +{ + mbus_fmt->width = pix_mp_fmt->width; + mbus_fmt->height = pix_mp_fmt->height; + mbus_fmt->field = pix_mp_fmt->field; + mbus_fmt->colorspace = pix_mp_fmt->colorspace; + mbus_fmt->ycbcr_enc = pix_mp_fmt->ycbcr_enc; + mbus_fmt->quantization = pix_mp_fmt->quantization; + mbus_fmt->xfer_func = pix_mp_fmt->xfer_func; +} + #endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 0f92ebd2d7101acf66ff8cc5e83f8524e573332a..e83872078376a9874f68ae1362478e1a881b83ae 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -982,8 +982,16 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, * Example: err = v4l2_subdev_call(sd, video, s_std, norm); */ #define v4l2_subdev_call(sd, o, f, args...) \ - (!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \ - (sd)->ops->o->f((sd), ##args) : -ENOIOCTLCMD)) + ({ \ + int __result; \ + if (!(sd)) \ + __result = -ENODEV; \ + else if (!((sd)->ops->o && (sd)->ops->o->f)) \ + __result = -ENOIOCTLCMD; \ + else \ + __result = (sd)->ops->o->f((sd), ##args); \ + __result; \ + }) #define v4l2_subdev_has_op(sd, o, f) \ ((sd)->ops->o && (sd)->ops->o->f) diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index cb97c224be730f5e3fd7076fd681e66b56df64e5..ef9b64398c8c9586f741867f13e20e7a157fd16c 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -427,6 +427,16 @@ struct vb2_buf_ops { * @dev: device to use for the default allocation context if the driver * doesn't fill in the @alloc_devs array. * @dma_attrs: DMA attributes to use for the DMA. + * @bidirectional: when this flag is set the DMA direction for the buffers of + * this queue will be overridden with DMA_BIDIRECTIONAL direction. + * This is useful in cases where the hardware (firmware) writes to + * a buffer which is mapped as read (DMA_TO_DEVICE), or reads from + * buffer which is mapped for write (DMA_FROM_DEVICE) in order + * to satisfy some internal hardware restrictions or adds a padding + * needed by the processing algorithm. In case the DMA mapping is + * not bidirectional but the hardware (firmware) trying to access + * the buffer (in the opposite direction) this could lead to an + * IOMMU protection faults. * @fileio_read_once: report EOF after reading the first buffer * @fileio_write_immediately: queue buffer after each write() call * @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver @@ -465,6 +475,7 @@ struct vb2_buf_ops { * Private elements (won't appear at the uAPI book): * @mmap_lock: private mutex used when buffers are allocated/freed/mmapped * @memory: current memory type used + * @dma_dir: DMA mapping direction. * @bufs: videobuf buffer structures * @num_buffers: number of allocated/used buffers * @queued_list: list of buffers currently queued from userspace @@ -495,6 +506,7 @@ struct vb2_queue { unsigned int io_modes; struct device *dev; unsigned long dma_attrs; + unsigned bidirectional:1; unsigned fileio_read_once:1; unsigned fileio_write_immediately:1; unsigned allow_zero_bytesused:1; @@ -516,6 +528,7 @@ struct vb2_queue { /* private: internal use only */ struct mutex mmap_lock; unsigned int memory; + enum dma_data_direction dma_dir; struct vb2_buffer *bufs[VB2_MAX_FRAME]; unsigned int num_buffers; diff --git a/include/media/vsp1.h b/include/media/vsp1.h index c837383b201393b20de47aa2d7561725323aaedf..68a8abe4fac5a35620dc2fa0a2f5bd6ce02e01ed 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -34,11 +34,12 @@ struct vsp1_du_lif_config { unsigned int width; unsigned int height; - void (*callback)(void *); + void (*callback)(void *, bool); void *callback_data; }; -int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg); +int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, + const struct vsp1_du_lif_config *cfg); struct vsp1_du_atomic_config { u32 pixelformat; @@ -50,10 +51,11 @@ struct vsp1_du_atomic_config { unsigned int zpos; }; -void vsp1_du_atomic_begin(struct device *dev); -int vsp1_du_atomic_update(struct device *dev, unsigned int rpf, +void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index); +int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, + unsigned int rpf, const struct vsp1_du_atomic_config *cfg); -void vsp1_du_atomic_flush(struct device *dev); +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index); int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt); void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt); diff --git a/include/net/act_api.h b/include/net/act_api.h index 26ffd8333f50fc6406e42c3536646a34df428f56..b944e0eb93be367944673939a943b05c3473f2e9 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -10,12 +10,9 @@ #include #include - -struct tcf_hashinfo { - struct hlist_head *htab; - unsigned int hmask; - spinlock_t lock; - u32 index; +struct tcf_idrinfo { + spinlock_t lock; + struct idr action_idr; }; struct tc_action_ops; @@ -25,9 +22,8 @@ struct tc_action { __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ __u32 order; struct list_head list; - struct tcf_hashinfo *hinfo; + struct tcf_idrinfo *idrinfo; - struct hlist_node tcfa_head; u32 tcfa_index; int tcfa_refcnt; int tcfa_bindcnt; @@ -38,13 +34,11 @@ struct tc_action { struct gnet_stats_queue tcfa_qstats; struct net_rate_estimator __rcu *tcfa_rate_est; spinlock_t tcfa_lock; - struct rcu_head tcfa_rcu; struct gnet_stats_basic_cpu __percpu *cpu_bstats; struct gnet_stats_queue __percpu *cpu_qstats; struct tc_cookie *act_cookie; struct tcf_chain *goto_chain; }; -#define tcf_head common.tcfa_head #define tcf_index common.tcfa_index #define tcf_refcnt common.tcfa_refcnt #define tcf_bindcnt common.tcfa_bindcnt @@ -55,28 +49,6 @@ struct tc_action { #define tcf_qstats common.tcfa_qstats #define tcf_rate_est common.tcfa_rate_est #define tcf_lock common.tcfa_lock -#define tcf_rcu common.tcfa_rcu - -static inline unsigned int tcf_hash(u32 index, unsigned int hmask) -{ - return index & hmask; -} - -static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask) -{ - int i; - - spin_lock_init(&hf->lock); - hf->index = 0; - hf->hmask = mask; - hf->htab = kzalloc((mask + 1) * sizeof(struct hlist_head), - GFP_KERNEL); - if (!hf->htab) - return -ENOMEM; - for (i = 0; i < mask + 1; i++) - INIT_HLIST_HEAD(&hf->htab[i]); - return 0; -} /* Update lastuse only if needed, to avoid dirtying a cache line. * We use a temp variable to avoid fetching jiffies twice. @@ -126,53 +98,51 @@ struct tc_action_ops { }; struct tc_action_net { - struct tcf_hashinfo *hinfo; + struct tcf_idrinfo *idrinfo; const struct tc_action_ops *ops; }; static inline int tc_action_net_init(struct tc_action_net *tn, - const struct tc_action_ops *ops, unsigned int mask) + const struct tc_action_ops *ops) { int err = 0; - tn->hinfo = kmalloc(sizeof(*tn->hinfo), GFP_KERNEL); - if (!tn->hinfo) + tn->idrinfo = kmalloc(sizeof(*tn->idrinfo), GFP_KERNEL); + if (!tn->idrinfo) return -ENOMEM; tn->ops = ops; - err = tcf_hashinfo_init(tn->hinfo, mask); - if (err) - kfree(tn->hinfo); + spin_lock_init(&tn->idrinfo->lock); + idr_init(&tn->idrinfo->action_idr); return err; } -void tcf_hashinfo_destroy(const struct tc_action_ops *ops, - struct tcf_hashinfo *hinfo); +void tcf_idrinfo_destroy(const struct tc_action_ops *ops, + struct tcf_idrinfo *idrinfo); static inline void tc_action_net_exit(struct tc_action_net *tn) { - tcf_hashinfo_destroy(tn->ops, tn->hinfo); - kfree(tn->hinfo); + tcf_idrinfo_destroy(tn->ops, tn->idrinfo); + kfree(tn->idrinfo); } int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops); -int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index); -u32 tcf_hash_new_index(struct tc_action_net *tn); -bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a, +int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index); +bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a, int bind); -int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, - struct tc_action **a, const struct tc_action_ops *ops, int bind, - bool cpustats); -void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est); -void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a); +int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, + struct tc_action **a, const struct tc_action_ops *ops, + int bind, bool cpustats); +void tcf_idr_cleanup(struct tc_action *a, struct nlattr *est); +void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a); -int __tcf_hash_release(struct tc_action *a, bool bind, bool strict); +int __tcf_idr_release(struct tc_action *a, bool bind, bool strict); -static inline int tcf_hash_release(struct tc_action *a, bool bind) +static inline int tcf_idr_release(struct tc_action *a, bool bind) { - return __tcf_hash_release(a, bind, false); + return __tcf_idr_release(a, bind, false); } int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops); diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 6df79e96a780b3bf0c141fee5b43eded5276775c..f44ff2476758e27ad9f9cc20d96d96f16e5ee98c 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -336,6 +336,16 @@ static inline void in6_dev_put(struct inet6_dev *idev) in6_dev_finish_destroy(idev); } +static inline void in6_dev_put_clear(struct inet6_dev **pidev) +{ + struct inet6_dev *idev = *pidev; + + if (idev) { + in6_dev_put(idev); + *pidev = NULL; + } +} + static inline void __in6_dev_put(struct inet6_dev *idev) { refcount_dec(&idev->refcnt); diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h index c172709787af316efaee4cfa94cc185ca989b5fb..3ac79150291f288351f38ba22cfb85013375ae69 100644 --- a/include/net/af_rxrpc.h +++ b/include/net/af_rxrpc.h @@ -19,8 +19,22 @@ struct sock; struct socket; struct rxrpc_call; +/* + * Call completion condition (state == RXRPC_CALL_COMPLETE). + */ +enum rxrpc_call_completion { + RXRPC_CALL_SUCCEEDED, /* - Normal termination */ + RXRPC_CALL_REMOTELY_ABORTED, /* - call aborted by peer */ + RXRPC_CALL_LOCALLY_ABORTED, /* - call aborted locally on error or close */ + RXRPC_CALL_LOCAL_ERROR, /* - call failed due to local error */ + RXRPC_CALL_NETWORK_ERROR, /* - call terminated by network error */ + NR__RXRPC_CALL_COMPLETIONS +}; + typedef void (*rxrpc_notify_rx_t)(struct sock *, struct rxrpc_call *, unsigned long); +typedef void (*rxrpc_notify_end_tx_t)(struct sock *, struct rxrpc_call *, + unsigned long); typedef void (*rxrpc_notify_new_call_t)(struct sock *, struct rxrpc_call *, unsigned long); typedef void (*rxrpc_discard_new_call_t)(struct rxrpc_call *, unsigned long); @@ -37,7 +51,8 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *, gfp_t, rxrpc_notify_rx_t); int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *, - struct msghdr *, size_t); + struct msghdr *, size_t, + rxrpc_notify_end_tx_t); int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *, void *, size_t, size_t *, bool, u32 *); bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *, @@ -48,5 +63,9 @@ void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *, int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t, rxrpc_user_attach_call_t, unsigned long, gfp_t); void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64); +int rxrpc_kernel_retry_call(struct socket *, struct rxrpc_call *, + struct sockaddr_rxrpc *, struct key *); +int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *, + enum rxrpc_call_completion *, u32 *); #endif /* _NET_RXRPC_H */ diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 53b1a2cca42129f69a5e4925421a3f0cb3fb2ca9..afb37f83544983c2fe54236f2a3806ecc9b43f53 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -58,7 +58,6 @@ struct unix_sock { struct list_head link; atomic_long_t inflight; spinlock_t lock; - unsigned char recursion_level; unsigned long gc_flags; #define UNIX_GC_CANDIDATE 0 #define UNIX_GC_MAYBE_CYCLE 1 diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 01487192f628af6200f9187cb4aa462a05df2093..020142bb9735b80d884bffb4d5f50a7be4826974 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -233,7 +233,7 @@ static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src) memcpy(dst, src, sizeof(bdaddr_t)); } -void baswap(bdaddr_t *dst, bdaddr_t *src); +void baswap(bdaddr_t *dst, const bdaddr_t *src); /* Common socket structures and functions */ diff --git a/include/net/bonding.h b/include/net/bonding.h index b00508d22e0a6adc37ee4e69187377fea3bc102d..b2e68657a2162cd55b957c9230779f5d066fe6f3 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -277,6 +277,11 @@ static inline bool bond_is_lb(const struct bonding *bond) BOND_MODE(bond) == BOND_MODE_ALB; } +static inline bool bond_needs_speed_duplex(const struct bonding *bond) +{ + return BOND_MODE(bond) == BOND_MODE_8023AD || bond_is_lb(bond); +} + static inline bool bond_is_nondyn_tlb(const struct bonding *bond) { return (BOND_MODE(bond) == BOND_MODE_TLB) && diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h index 8ffd434676b7a270af73534f3dbcc26f370fe215..71c72a939bf8b21c5102994ea68796dc89c4f097 100644 --- a/include/net/busy_poll.h +++ b/include/net/busy_poll.h @@ -29,18 +29,18 @@ #include #include -#ifdef CONFIG_NET_RX_BUSY_POLL - -struct napi_struct; -extern unsigned int sysctl_net_busy_read __read_mostly; -extern unsigned int sysctl_net_busy_poll __read_mostly; - /* 0 - Reserved to indicate value not set * 1..NR_CPUS - Reserved for sender_cpu * NR_CPUS+1..~0 - Region available for NAPI IDs */ #define MIN_NAPI_ID ((unsigned int)(NR_CPUS + 1)) +#ifdef CONFIG_NET_RX_BUSY_POLL + +struct napi_struct; +extern unsigned int sysctl_net_busy_read __read_mostly; +extern unsigned int sysctl_net_busy_poll __read_mostly; + static inline bool net_busy_loop_on(void) { return sysctl_net_busy_poll; diff --git a/include/net/devlink.h b/include/net/devlink.h index ed7687bbf5d08f1bb5327f3f8c9e3e543e98e7c2..b9654e133599383fad6ada59a19378e4515be90c 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -178,7 +178,6 @@ struct devlink_dpipe_table_ops; * struct devlink_dpipe_table - table object * @priv: private * @name: table name - * @size: maximum number of entries * @counters_enabled: indicates if counters are active * @counter_control_extern: indicates if counter control is in dpipe or * external tool @@ -189,7 +188,6 @@ struct devlink_dpipe_table { void *priv; struct list_head list; const char *name; - u64 size; bool counters_enabled; bool counter_control_extern; struct devlink_dpipe_table_ops *table_ops; @@ -204,6 +202,7 @@ struct devlink_dpipe_table { * @counters_set_update - when changing the counter status hardware sync * maybe needed to allocate/free counter related * resources + * @size_get - get size */ struct devlink_dpipe_table_ops { int (*actions_dump)(void *priv, struct sk_buff *skb); @@ -211,6 +210,7 @@ struct devlink_dpipe_table_ops { int (*entries_dump)(void *priv, bool counters_enabled, struct devlink_dpipe_dump_ctx *dump_ctx); int (*counters_set_update)(void *priv, bool enable); + u64 (*size_get)(void *priv); }; /** @@ -311,8 +311,7 @@ void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index); int devlink_dpipe_table_register(struct devlink *devlink, const char *table_name, struct devlink_dpipe_table_ops *table_ops, - void *priv, u64 size, - bool counter_control_extern); + void *priv, bool counter_control_extern); void devlink_dpipe_table_unregister(struct devlink *devlink, const char *table_name); int devlink_dpipe_headers_register(struct devlink *devlink, @@ -324,10 +323,14 @@ int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx); int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, struct devlink_dpipe_entry *entry); int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx); +void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry); int devlink_dpipe_action_put(struct sk_buff *skb, struct devlink_dpipe_action *action); int devlink_dpipe_match_put(struct sk_buff *skb, struct devlink_dpipe_match *match); +extern struct devlink_dpipe_header devlink_dpipe_header_ethernet; +extern struct devlink_dpipe_header devlink_dpipe_header_ipv4; +extern struct devlink_dpipe_header devlink_dpipe_header_ipv6; #else @@ -400,8 +403,7 @@ static inline int devlink_dpipe_table_register(struct devlink *devlink, const char *table_name, struct devlink_dpipe_table_ops *table_ops, - void *priv, u64 size, - bool counter_control_extern) + void *priv, bool counter_control_extern) { return 0; } @@ -447,6 +449,11 @@ devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) return 0; } +static inline void +devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry) +{ +} + static inline int devlink_dpipe_action_put(struct sk_buff *skb, struct devlink_dpipe_action *action) diff --git a/include/net/dsa.h b/include/net/dsa.h index 58969b9a090cc8f0e0e9e1ede7b5484ab4b959bd..dd44d6ce10976fa4d14a9b6086104c782cf5f40b 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -101,6 +101,14 @@ struct dsa_platform_data { struct packet_type; +struct dsa_device_ops { + struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); + struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt); + int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto, + int *offset); +}; + struct dsa_switch_tree { struct list_head list; @@ -125,8 +133,7 @@ struct dsa_switch_tree { /* Copy of tag_ops->rcv for faster access in hot path */ struct sk_buff * (*rcv)(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev); + struct packet_type *pt); /* * The switch port to which the CPU is attached. @@ -236,6 +243,9 @@ struct dsa_switch { /* devlink used to represent this switch device */ struct devlink *devlink; + /* Number of switch port queues */ + unsigned int num_tx_queues; + /* Dynamically allocated ports, keep last */ size_t num_ports; struct dsa_port ports[]; @@ -256,11 +266,6 @@ static inline bool dsa_is_normal_port(struct dsa_switch *ds, int p) return !dsa_is_cpu_port(ds, p) && !dsa_is_dsa_port(ds, p); } -static inline bool dsa_is_port_initialized(struct dsa_switch *ds, int p) -{ - return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev; -} - static inline u8 dsa_upstream_port(struct dsa_switch *ds) { struct dsa_switch_tree *dst = ds->dst; @@ -277,6 +282,8 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds) return ds->rtable[dst->cpu_dp->ds->index]; } +typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, + bool is_static, void *data); struct dsa_switch_ops { /* * Legacy probing. @@ -337,13 +344,12 @@ struct dsa_switch_ops { struct phy_device *phy); /* - * EEE setttings + * Port's MAC EEE settings */ - int (*set_eee)(struct dsa_switch *ds, int port, - struct phy_device *phydev, - struct ethtool_eee *e); - int (*get_eee)(struct dsa_switch *ds, int port, - struct ethtool_eee *e); + int (*set_mac_eee)(struct dsa_switch *ds, int port, + struct ethtool_eee *e); + int (*get_mac_eee)(struct dsa_switch *ds, int port, + struct ethtool_eee *e); /* EEPROM access */ int (*get_eeprom_len)(struct dsa_switch *ds); @@ -384,24 +390,15 @@ struct dsa_switch_ops { struct switchdev_trans *trans); int (*port_vlan_del)(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan); - int (*port_vlan_dump)(struct dsa_switch *ds, int port, - struct switchdev_obj_port_vlan *vlan, - switchdev_obj_dump_cb_t *cb); - /* * Forwarding database */ - int (*port_fdb_prepare)(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans); - void (*port_fdb_add)(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans); + int (*port_fdb_add)(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid); int (*port_fdb_del)(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_fdb *fdb); + const unsigned char *addr, u16 vid); int (*port_fdb_dump)(struct dsa_switch *ds, int port, - struct switchdev_obj_port_fdb *fdb, - switchdev_obj_dump_cb_t *cb); + dsa_fdb_dump_cb_t *cb, void *data); /* * Multicast database @@ -414,10 +411,6 @@ struct dsa_switch_ops { struct switchdev_trans *trans); int (*port_mdb_del)(struct dsa_switch *ds, int port, const struct switchdev_obj_port_mdb *mdb); - int (*port_mdb_dump)(struct dsa_switch *ds, int port, - struct switchdev_obj_port_mdb *mdb, - switchdev_obj_dump_cb_t *cb); - /* * RXNFC */ diff --git a/include/net/dst.h b/include/net/dst.h index f73611ec401754d4f52b5310a24da53566dafce6..06a6765da074449e6f1fe42ee05e711e898ad372 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -107,7 +108,7 @@ struct dst_entry { struct dst_metrics { u32 metrics[RTAX_MAX]; - atomic_t refcnt; + refcount_t refcnt; }; extern const struct dst_metrics dst_default_metrics; @@ -270,7 +271,7 @@ static inline void dst_use_noref(struct dst_entry *dst, unsigned long time) static inline struct dst_entry *dst_clone(struct dst_entry *dst) { if (dst) - atomic_inc(&dst->__refcnt); + dst_hold(dst); return dst; } @@ -310,21 +311,6 @@ static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb __skb_dst_copy(nskb, oskb->_skb_refdst); } -/** - * skb_dst_force - makes sure skb dst is refcounted - * @skb: buffer - * - * If dst is not yet refcounted, let's do it - */ -static inline void skb_dst_force(struct sk_buff *skb) -{ - if (skb_dst_is_noref(skb)) { - WARN_ON(!rcu_read_lock_held()); - skb->_skb_refdst &= ~SKB_DST_NOREF; - dst_clone(skb_dst(skb)); - } -} - /** * dst_hold_safe - Take a reference on a dst if possible * @dst: pointer to dst entry @@ -338,16 +324,17 @@ static inline bool dst_hold_safe(struct dst_entry *dst) } /** - * skb_dst_force_safe - makes sure skb dst is refcounted + * skb_dst_force - makes sure skb dst is refcounted * @skb: buffer * * If dst is not yet refcounted and not destroyed, grab a ref on it. */ -static inline void skb_dst_force_safe(struct sk_buff *skb) +static inline void skb_dst_force(struct sk_buff *skb) { if (skb_dst_is_noref(skb)) { struct dst_entry *dst = skb_dst(skb); + WARN_ON(!rcu_read_lock_held()); if (!dst_hold_safe(dst)) dst = NULL; diff --git a/include/net/erspan.h b/include/net/erspan.h new file mode 100644 index 0000000000000000000000000000000000000000..ca94fc86865ecb95206e84372db16792df747fde --- /dev/null +++ b/include/net/erspan.h @@ -0,0 +1,61 @@ +#ifndef __LINUX_ERSPAN_H +#define __LINUX_ERSPAN_H + +/* + * GRE header for ERSPAN encapsulation (8 octets [34:41]) -- 8 bytes + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0|0|0|1|0|00000|000000000|00000| Protocol Type for ERSPAN | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number (increments per packet per session) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Note that in the above GRE header [RFC1701] out of the C, R, K, S, + * s, Recur, Flags, Version fields only S (bit 03) is set to 1. The + * other fields are set to zero, so only a sequence number follows. + * + * ERSPAN Type II header (8 octets [42:49]) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Ver | VLAN | COS | En|T| Session ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Index | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * GRE proto ERSPAN type II = 0x88BE, type III = 0x22EB + */ + +#define ERSPAN_VERSION 0x1 + +#define VER_MASK 0xf000 +#define VLAN_MASK 0x0fff +#define COS_MASK 0xe000 +#define EN_MASK 0x1800 +#define T_MASK 0x0400 +#define ID_MASK 0x03ff +#define INDEX_MASK 0xfffff + +enum erspan_encap_type { + ERSPAN_ENCAP_NOVLAN = 0x0, /* originally without VLAN tag */ + ERSPAN_ENCAP_ISL = 0x1, /* originally ISL encapsulated */ + ERSPAN_ENCAP_8021Q = 0x2, /* originally 802.1Q encapsulated */ + ERSPAN_ENCAP_INFRAME = 0x3, /* VLAN tag perserved in frame */ +}; + +struct erspan_metadata { + __be32 index; /* type II */ +}; + +struct erspanhdr { + __be16 ver_vlan; +#define VER_OFFSET 12 + __be16 session_id; +#define COS_OFFSET 13 +#define EN_OFFSET 11 +#define T_OFFSET 10 + struct erspan_metadata md; +}; + +#endif diff --git a/include/net/fib_notifier.h b/include/net/fib_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..669b9716dc7a67c8c9048d70a97229546d8fc29b --- /dev/null +++ b/include/net/fib_notifier.h @@ -0,0 +1,46 @@ +#ifndef __NET_FIB_NOTIFIER_H +#define __NET_FIB_NOTIFIER_H + +#include +#include +#include +#include + +struct fib_notifier_info { + struct net *net; + int family; +}; + +enum fib_event_type { + FIB_EVENT_ENTRY_REPLACE, + FIB_EVENT_ENTRY_APPEND, + FIB_EVENT_ENTRY_ADD, + FIB_EVENT_ENTRY_DEL, + FIB_EVENT_RULE_ADD, + FIB_EVENT_RULE_DEL, + FIB_EVENT_NH_ADD, + FIB_EVENT_NH_DEL, +}; + +struct fib_notifier_ops { + int family; + struct list_head list; + unsigned int (*fib_seq_read)(struct net *net); + int (*fib_dump)(struct net *net, struct notifier_block *nb); + struct module *owner; + struct rcu_head rcu; +}; + +int call_fib_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct fib_notifier_info *info); +int call_fib_notifiers(struct net *net, enum fib_event_type event_type, + struct fib_notifier_info *info); +int register_fib_notifier(struct notifier_block *nb, + void (*cb)(struct notifier_block *nb)); +int unregister_fib_notifier(struct notifier_block *nb); +struct fib_notifier_ops * +fib_notifier_ops_register(const struct fib_notifier_ops *tmpl, struct net *net); +void fib_notifier_ops_unregister(struct fib_notifier_ops *ops); + +#endif diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index c487bfa2f47907c8c2f059f3162e33c1d9f43b79..3d7f1cefc6f582b328612a7085def93815e288ed 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -8,6 +8,7 @@ #include #include #include +#include struct fib_kuid_range { kuid_t start; @@ -57,6 +58,7 @@ struct fib_rules_ops { int addr_size; int unresolved_rules; int nr_goto_rules; + unsigned int fib_rules_seq; int (*action)(struct fib_rule *, struct flowi *, int, @@ -89,6 +91,11 @@ struct fib_rules_ops { struct rcu_head rcu; }; +struct fib_rule_notifier_info { + struct fib_notifier_info info; /* must be first */ + struct fib_rule *rule; +}; + #define FRA_GENERIC_POLICY \ [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ @@ -143,6 +150,8 @@ int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags, int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table, u32 flags); bool fib_rule_matchall(const struct fib_rule *rule); +int fib_rules_dump(struct net *net, struct notifier_block *nb, int family); +unsigned int fib_rules_seq_read(struct net *net, int family); int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack); diff --git a/include/net/flow.h b/include/net/flow.h index bae198b3039e6e66829c2717c1baf2baebbec6a2..eb60cee30b44ae25b7e1c6e044ea67d9a9b1e361 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -149,6 +149,7 @@ struct flowi6 { #define fl6_ipsec_spi uli.spi #define fl6_mh_type uli.mht.type #define fl6_gre_key uli.gre_key + __u32 mp_hash; } __attribute__((__aligned__(BITS_PER_LONG/8))); struct flowidn { @@ -218,40 +219,6 @@ static inline unsigned int flow_key_size(u16 family) return 0; } -#define FLOW_DIR_IN 0 -#define FLOW_DIR_OUT 1 -#define FLOW_DIR_FWD 2 - -struct net; -struct sock; -struct flow_cache_ops; - -struct flow_cache_object { - const struct flow_cache_ops *ops; -}; - -struct flow_cache_ops { - struct flow_cache_object *(*get)(struct flow_cache_object *); - int (*check)(struct flow_cache_object *); - void (*delete)(struct flow_cache_object *); -}; - -typedef struct flow_cache_object *(*flow_resolve_t)( - struct net *net, const struct flowi *key, u16 family, - u8 dir, struct flow_cache_object *oldobj, void *ctx); - -struct flow_cache_object *flow_cache_lookup(struct net *net, - const struct flowi *key, u16 family, - u8 dir, flow_resolve_t resolver, - void *ctx); -int flow_cache_init(struct net *net); -void flow_cache_fini(struct net *net); -void flow_cache_hp_init(void); - -void flow_cache_flush(struct net *net); -void flow_cache_flush_deferred(struct net *net); -extern atomic_t flow_cache_genid; - __u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys); static inline __u32 get_hash_from_flowi6(const struct flowi6 *fl6) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index e2663e900b0a4bcc827888927c4b3f8e3bb68179..fc3dce730a6bb245718640066b903cb412299eb0 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -19,6 +19,14 @@ struct flow_dissector_key_control { #define FLOW_DIS_FIRST_FRAG BIT(1) #define FLOW_DIS_ENCAPSULATION BIT(2) +enum flow_dissect_ret { + FLOW_DISSECT_RET_OUT_GOOD, + FLOW_DISSECT_RET_OUT_BAD, + FLOW_DISSECT_RET_PROTO_AGAIN, + FLOW_DISSECT_RET_IPPROTO_AGAIN, + FLOW_DISSECT_RET_CONTINUE, +}; + /** * struct flow_dissector_key_basic: * @thoff: Transport header offset diff --git a/include/net/flowcache.h b/include/net/flowcache.h deleted file mode 100644 index 51eb971e897378e25329b06f80678f522eec2ea6..0000000000000000000000000000000000000000 --- a/include/net/flowcache.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _NET_FLOWCACHE_H -#define _NET_FLOWCACHE_H - -#include -#include -#include -#include - -struct flow_cache_percpu { - struct hlist_head *hash_table; - unsigned int hash_count; - u32 hash_rnd; - int hash_rnd_recalc; - struct tasklet_struct flush_tasklet; -}; - -struct flow_cache { - u32 hash_shift; - struct flow_cache_percpu __percpu *percpu; - struct hlist_node node; - unsigned int low_watermark; - unsigned int high_watermark; - struct timer_list rnd_timer; -}; -#endif /* _NET_FLOWCACHE_H */ diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index b87becacd9d347d9a7dac23fb9e08133615a9d11..6e91e38a31da4cf53719d2ba270cf29c9dd98715 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -49,7 +49,8 @@ struct sock *__inet6_lookup_established(struct net *net, const struct in6_addr *saddr, const __be16 sport, const struct in6_addr *daddr, - const u16 hnum, const int dif); + const u16 hnum, const int dif, + const int sdif); struct sock *inet6_lookup_listener(struct net *net, struct inet_hashinfo *hashinfo, @@ -57,7 +58,8 @@ struct sock *inet6_lookup_listener(struct net *net, const struct in6_addr *saddr, const __be16 sport, const struct in6_addr *daddr, - const unsigned short hnum, const int dif); + const unsigned short hnum, + const int dif, const int sdif); static inline struct sock *__inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo, @@ -66,24 +68,25 @@ static inline struct sock *__inet6_lookup(struct net *net, const __be16 sport, const struct in6_addr *daddr, const u16 hnum, - const int dif, + const int dif, const int sdif, bool *refcounted) { struct sock *sk = __inet6_lookup_established(net, hashinfo, saddr, - sport, daddr, hnum, dif); + sport, daddr, hnum, + dif, sdif); *refcounted = true; if (sk) return sk; *refcounted = false; return inet6_lookup_listener(net, hashinfo, skb, doff, saddr, sport, - daddr, hnum, dif); + daddr, hnum, dif, sdif); } static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, struct sk_buff *skb, int doff, const __be16 sport, const __be16 dport, - int iif, + int iif, int sdif, bool *refcounted) { struct sock *sk = skb_steal_sock(skb); @@ -95,7 +98,7 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, doff, &ipv6_hdr(skb)->saddr, sport, &ipv6_hdr(skb)->daddr, ntohs(dport), - iif, refcounted); + iif, sdif, refcounted); } struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo, @@ -107,13 +110,14 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo, int inet6_hash(struct sock *sk); #endif /* IS_ENABLED(CONFIG_IPV6) */ -#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ +#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \ (((__sk)->sk_portpair == (__ports)) && \ ((__sk)->sk_family == AF_INET6) && \ ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \ ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \ (!(__sk)->sk_bound_dev_if || \ - ((__sk)->sk_bound_dev_if == (__dif))) && \ + ((__sk)->sk_bound_dev_if == (__dif)) || \ + ((__sk)->sk_bound_dev_if == (__sdif))) && \ net_eq(sock_net(__sk), (__net))) #endif /* _INET6_HASHTABLES_H */ diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 6fdcd242777651aa75bb55ecfcb9fce53708fd53..fc59e0775e001fd826e4fc76d82e492cec19d0c3 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -1,14 +1,9 @@ #ifndef __NET_FRAG_H__ #define __NET_FRAG_H__ -#include - struct netns_frags { - /* The percpu_counter "mem" need to be cacheline aligned. - * mem.count must not share cacheline with other writers - */ - struct percpu_counter mem ____cacheline_aligned_in_smp; - + /* Keep atomic mem on separate cachelines in structs that include it */ + atomic_t mem ____cacheline_aligned_in_smp; /* sysctls */ int timeout; int high_thresh; @@ -108,15 +103,10 @@ struct inet_frags { int inet_frags_init(struct inet_frags *); void inet_frags_fini(struct inet_frags *); -static inline int inet_frags_init_net(struct netns_frags *nf) -{ - return percpu_counter_init(&nf->mem, 0, GFP_KERNEL); -} -static inline void inet_frags_uninit_net(struct netns_frags *nf) +static inline void inet_frags_init_net(struct netns_frags *nf) { - percpu_counter_destroy(&nf->mem); + atomic_set(&nf->mem, 0); } - void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f); void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); @@ -140,31 +130,24 @@ static inline bool inet_frag_evicting(struct inet_frag_queue *q) /* Memory Tracking Functions. */ -/* The default percpu_counter batch size is not big enough to scale to - * fragmentation mem acct sizes. - * The mem size of a 64K fragment is approx: - * (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes - */ -static unsigned int frag_percpu_counter_batch = 130000; - static inline int frag_mem_limit(struct netns_frags *nf) { - return percpu_counter_read(&nf->mem); + return atomic_read(&nf->mem); } static inline void sub_frag_mem_limit(struct netns_frags *nf, int i) { - percpu_counter_add_batch(&nf->mem, -i, frag_percpu_counter_batch); + atomic_sub(i, &nf->mem); } static inline void add_frag_mem_limit(struct netns_frags *nf, int i) { - percpu_counter_add_batch(&nf->mem, i, frag_percpu_counter_batch); + atomic_add(i, &nf->mem); } -static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf) +static inline int sum_frag_mem_limit(struct netns_frags *nf) { - return percpu_counter_sum_positive(&nf->mem); + return atomic_read(&nf->mem); } /* RFC 3168 support : diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 5026b1f08bb87bf7b9be9df84d70fedf2bd8707f..2dbbbff5e1e3aa58434bbafa691d44005b3e2450 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -221,16 +221,16 @@ struct sock *__inet_lookup_listener(struct net *net, const __be32 saddr, const __be16 sport, const __be32 daddr, const unsigned short hnum, - const int dif); + const int dif, const int sdif); static inline struct sock *inet_lookup_listener(struct net *net, struct inet_hashinfo *hashinfo, struct sk_buff *skb, int doff, __be32 saddr, __be16 sport, - __be32 daddr, __be16 dport, int dif) + __be32 daddr, __be16 dport, int dif, int sdif) { return __inet_lookup_listener(net, hashinfo, skb, doff, saddr, sport, - daddr, ntohs(dport), dif); + daddr, ntohs(dport), dif, sdif); } /* Socket demux engine toys. */ @@ -262,22 +262,24 @@ static inline struct sock *inet_lookup_listener(struct net *net, (((__force __u64)(__be32)(__daddr)) << 32) | \ ((__force __u64)(__be32)(__saddr))) #endif /* __BIG_ENDIAN */ -#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ +#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \ (((__sk)->sk_portpair == (__ports)) && \ ((__sk)->sk_addrpair == (__cookie)) && \ (!(__sk)->sk_bound_dev_if || \ - ((__sk)->sk_bound_dev_if == (__dif))) && \ + ((__sk)->sk_bound_dev_if == (__dif)) || \ + ((__sk)->sk_bound_dev_if == (__sdif))) && \ net_eq(sock_net(__sk), (__net))) #else /* 32-bit arch */ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ const int __name __deprecated __attribute__((unused)) -#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ +#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \ (((__sk)->sk_portpair == (__ports)) && \ ((__sk)->sk_daddr == (__saddr)) && \ ((__sk)->sk_rcv_saddr == (__daddr)) && \ (!(__sk)->sk_bound_dev_if || \ - ((__sk)->sk_bound_dev_if == (__dif))) && \ + ((__sk)->sk_bound_dev_if == (__dif)) || \ + ((__sk)->sk_bound_dev_if == (__sdif))) && \ net_eq(sock_net(__sk), (__net))) #endif /* 64-bit arch */ @@ -288,7 +290,7 @@ struct sock *__inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, const __be32 saddr, const __be16 sport, const __be32 daddr, const u16 hnum, - const int dif); + const int dif, const int sdif); static inline struct sock * inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, @@ -297,7 +299,7 @@ static inline struct sock * const int dif) { return __inet_lookup_established(net, hashinfo, saddr, sport, daddr, - ntohs(dport), dif); + ntohs(dport), dif, 0); } static inline struct sock *__inet_lookup(struct net *net, @@ -305,20 +307,20 @@ static inline struct sock *__inet_lookup(struct net *net, struct sk_buff *skb, int doff, const __be32 saddr, const __be16 sport, const __be32 daddr, const __be16 dport, - const int dif, + const int dif, const int sdif, bool *refcounted) { u16 hnum = ntohs(dport); struct sock *sk; sk = __inet_lookup_established(net, hashinfo, saddr, sport, - daddr, hnum, dif); + daddr, hnum, dif, sdif); *refcounted = true; if (sk) return sk; *refcounted = false; return __inet_lookup_listener(net, hashinfo, skb, doff, saddr, - sport, daddr, hnum, dif); + sport, daddr, hnum, dif, sdif); } static inline struct sock *inet_lookup(struct net *net, @@ -332,7 +334,7 @@ static inline struct sock *inet_lookup(struct net *net, bool refcounted; sk = __inet_lookup(net, hashinfo, skb, doff, saddr, sport, daddr, - dport, dif, &refcounted); + dport, dif, 0, &refcounted); if (sk && !refcounted && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; @@ -344,6 +346,7 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, int doff, const __be16 sport, const __be16 dport, + const int sdif, bool *refcounted) { struct sock *sk = skb_steal_sock(skb); @@ -355,7 +358,7 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, doff, iph->saddr, sport, - iph->daddr, dport, inet_iif(skb), + iph->daddr, dport, inet_iif(skb), sdif, refcounted); } diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index f2a215fc78e4686f597c4041796663a7a463e73f..950ed182f62f6f2e359b8ead28d903b4c6dc877f 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -33,18 +33,12 @@ struct inetpeer_addr { }; struct inet_peer { - /* group together avl_left,avl_right,v4daddr to speedup lookups */ - struct inet_peer __rcu *avl_left, *avl_right; + struct rb_node rb_node; struct inetpeer_addr daddr; - __u32 avl_height; u32 metrics[RTAX_MAX]; u32 rate_tokens; /* rate limiting for ICMP */ unsigned long rate_last; - union { - struct list_head gc_list; - struct rcu_head gc_rcu; - }; /* * Once inet_peer is queued for deletion (refcnt == 0), following field * is not available: rid @@ -55,7 +49,6 @@ struct inet_peer { atomic_t rid; /* Frag reception counter */ }; struct rcu_head rcu; - struct inet_peer *gc_next; }; /* following fields might be frequently dirtied */ @@ -64,7 +57,7 @@ struct inet_peer { }; struct inet_peer_base { - struct inet_peer __rcu *root; + struct rb_root rb_root; seqlock_t lock; int total; }; diff --git a/include/net/ip.h b/include/net/ip.h index 821cedcc8e73b68af72d1918242c25d757c63d24..9896f46cbbf11235395d75a5ec18a14736ee099d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -78,6 +78,16 @@ struct ipcm_cookie { #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb)) +/* return enslaved device index if relevant */ +static inline int inet_sdif(struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) + if (skb && ipv4_l3mdev_skb(IPCB(skb)->flags)) + return IPCB(skb)->iif; +#endif + return 0; +} + struct ip_ra_chain { struct ip_ra_chain __rcu *next; struct sock *sk; @@ -352,7 +362,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, !forwarding) return dst_mtu(dst); - return min(dst->dev->mtu, IP_MAX_MTU); + return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU); } static inline unsigned int ip_skb_dst_mtu(struct sock *sk, @@ -364,7 +374,7 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk, return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); } - return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU); + return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU); } u32 ip_idents_reserve(u32 hash, int segs); @@ -567,11 +577,12 @@ int ip_forward(struct sk_buff *skb); void ip_options_build(struct sk_buff *skb, struct ip_options *opt, __be32 daddr, struct rtable *rt, int is_frag); -int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, - const struct ip_options *sopt); -static inline int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb) +int __ip_options_echo(struct net *net, struct ip_options *dopt, + struct sk_buff *skb, const struct ip_options *sopt); +static inline int ip_options_echo(struct net *net, struct ip_options *dopt, + struct sk_buff *skb) { - return __ip_options_echo(dopt, skb, &IPCB(skb)->opt); + return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt); } void ip_options_fragment(struct sk_buff *skb); diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 1a88008cc6f5e14a788491f62ae3c15e47b62c16..d060d711a6245b63a662c5ecdf839a0d4afe1af8 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -16,10 +16,12 @@ #include #include #include +#include #include #include #include #include +#include #ifdef CONFIG_IPV6_MULTIPLE_TABLES #define FIB6_TABLE_HASHSZ 256 @@ -70,6 +72,7 @@ struct fib6_node { __u16 fn_flags; int fn_sernum; struct rt6_info *rr_ptr; + struct rcu_head rcu; }; #ifndef CONFIG_IPV6_SUBTREES @@ -104,7 +107,7 @@ struct rt6_info { * the same cache line. */ struct fib6_table *rt6i_table; - struct fib6_node *rt6i_node; + struct fib6_node __rcu *rt6i_node; struct in6_addr rt6i_gateway; @@ -118,6 +121,8 @@ struct rt6_info { atomic_t rt6i_ref; + unsigned int rt6i_nh_flags; + /* These are in a separate cache line. */ struct rt6key rt6i_dst ____cacheline_aligned_in_smp; u32 rt6i_flags; @@ -167,13 +172,40 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) rt0->rt6i_flags |= RTF_EXPIRES; } +/* Function to safely get fn->sernum for passed in rt + * and store result in passed in cookie. + * Return true if we can get cookie safely + * Return false if not + */ +static inline bool rt6_get_cookie_safe(const struct rt6_info *rt, + u32 *cookie) +{ + struct fib6_node *fn; + bool status = false; + + rcu_read_lock(); + fn = rcu_dereference(rt->rt6i_node); + + if (fn) { + *cookie = fn->fn_sernum; + status = true; + } + + rcu_read_unlock(); + return status; +} + static inline u32 rt6_get_cookie(const struct rt6_info *rt) { + u32 cookie = 0; + if (rt->rt6i_flags & RTF_PCPU || (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from)) rt = (struct rt6_info *)(rt->dst.from); - return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; + rt6_get_cookie_safe(rt, &cookie); + + return cookie; } static inline void ip6_rt_put(struct rt6_info *rt) @@ -185,6 +217,22 @@ static inline void ip6_rt_put(struct rt6_info *rt) dst_release(&rt->dst); } +void rt6_free_pcpu(struct rt6_info *non_pcpu_rt); + +static inline void rt6_hold(struct rt6_info *rt) +{ + atomic_inc(&rt->rt6i_ref); +} + +static inline void rt6_release(struct rt6_info *rt) +{ + if (atomic_dec_and_test(&rt->rt6i_ref)) { + rt6_free_pcpu(rt); + dst_dev_put(&rt->dst); + dst_release(&rt->dst); + } +} + enum fib6_walk_state { #ifdef CONFIG_IPV6_SUBTREES FWS_S, @@ -233,6 +281,7 @@ struct fib6_table { struct fib6_node tb6_root; struct inet_peer_base tb6_peers; unsigned int flags; + unsigned int fib_seq; #define RT6_TABLE_HAS_DFLT_ROUTER BIT(0) }; @@ -256,6 +305,11 @@ typedef struct rt6_info *(*pol_lookup_t)(struct net *, struct fib6_table *, struct flowi6 *, int); +struct fib6_entry_notifier_info { + struct fib_notifier_info info; /* must be first */ + struct rt6_info *rt; +}; + /* * exported functions */ @@ -292,9 +346,24 @@ int fib6_init(void); int ipv6_route_open(struct inode *inode, struct file *file); +int call_fib6_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct fib_notifier_info *info); +int call_fib6_notifiers(struct net *net, enum fib_event_type event_type, + struct fib_notifier_info *info); + +int __net_init fib6_notifier_init(struct net *net); +void __net_exit fib6_notifier_exit(struct net *net); + +unsigned int fib6_tables_seq_read(struct net *net); +int fib6_tables_dump(struct net *net, struct notifier_block *nb); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES int fib6_rules_init(void); void fib6_rules_cleanup(void); +bool fib6_rule_default(const struct fib_rule *rule); +int fib6_rules_dump(struct net *net, struct notifier_block *nb); +unsigned int fib6_rules_seq_read(struct net *net); #else static inline int fib6_rules_init(void) { @@ -304,5 +373,17 @@ static inline void fib6_rules_cleanup(void) { return ; } +static inline bool fib6_rule_default(const struct fib_rule *rule) +{ + return true; +} +static inline int fib6_rules_dump(struct net *net, struct notifier_block *nb) +{ + return 0; +} +static inline unsigned int fib6_rules_seq_read(struct net *net) +{ + return 0; +} #endif #endif diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 199056933dcbf44cf25c00619cf4af8db66997da..ee96f402cb75ac9b35b7a7180f56367d88d49e47 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -115,6 +115,7 @@ static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt, struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, const struct in6_addr *saddr, int oif, int flags); +u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb); struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6); @@ -163,6 +164,16 @@ void rt6_mtu_change(struct net_device *dev, unsigned int mtu); void rt6_remove_prefsrc(struct inet6_ifaddr *ifp); void rt6_clean_tohost(struct net *net, struct in6_addr *gateway); +static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) +{ + const struct dst_entry *dst = skb_dst(skb); + const struct rt6_info *rt6 = NULL; + + if (dst) + rt6 = container_of(dst, struct rt6_info, dst); + + return rt6; +} /* * Store a destination cache entry in a socket @@ -194,7 +205,7 @@ static inline bool ipv6_anycast_destination(const struct dst_entry *dst, struct rt6_info *rt = (struct rt6_info *)dst; return rt->rt6i_flags & RTF_ANYCAST || - (rt->rt6i_dst.plen != 128 && + (rt->rt6i_dst.plen < 127 && ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)); } diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 41d580c6185ffd7041ef236a06701f6776a3633c..1a7f7e4243202181be87cd0b58b0243693b2dafc 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -124,7 +125,6 @@ struct fib_info { #ifdef CONFIG_IP_ROUTE_MULTIPATH int fib_weight; #endif - unsigned int fib_offload_cnt; struct rcu_head rcu; struct fib_nh fib_nh[0]; #define fib_dev fib_nh[0].nh_dev @@ -177,18 +177,6 @@ struct fib_result_nl { __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh); -static inline void fib_info_offload_inc(struct fib_info *fi) -{ - fi->fib_offload_cnt++; - fi->fib_flags |= RTNH_F_OFFLOAD; -} - -static inline void fib_info_offload_dec(struct fib_info *fi) -{ - if (--fi->fib_offload_cnt == 0) - fi->fib_flags &= ~RTNH_F_OFFLOAD; -} - #define FIB_RES_SADDR(net, res) \ ((FIB_RES_NH(res).nh_saddr_genid == \ atomic_read(&(net)->ipv4.dev_addr_genid)) ? \ @@ -201,10 +189,6 @@ static inline void fib_info_offload_dec(struct fib_info *fi) #define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \ FIB_RES_SADDR(net, res)) -struct fib_notifier_info { - struct net *net; -}; - struct fib_entry_notifier_info { struct fib_notifier_info info; /* must be first */ u32 dst; @@ -215,44 +199,21 @@ struct fib_entry_notifier_info { u32 tb_id; }; -struct fib_rule_notifier_info { - struct fib_notifier_info info; /* must be first */ - struct fib_rule *rule; -}; - struct fib_nh_notifier_info { struct fib_notifier_info info; /* must be first */ struct fib_nh *fib_nh; }; -enum fib_event_type { - FIB_EVENT_ENTRY_REPLACE, - FIB_EVENT_ENTRY_APPEND, - FIB_EVENT_ENTRY_ADD, - FIB_EVENT_ENTRY_DEL, - FIB_EVENT_RULE_ADD, - FIB_EVENT_RULE_DEL, - FIB_EVENT_NH_ADD, - FIB_EVENT_NH_DEL, -}; - -int register_fib_notifier(struct notifier_block *nb, - void (*cb)(struct notifier_block *nb)); -int unregister_fib_notifier(struct notifier_block *nb); -int call_fib_notifier(struct notifier_block *nb, struct net *net, - enum fib_event_type event_type, - struct fib_notifier_info *info); -int call_fib_notifiers(struct net *net, enum fib_event_type event_type, +int call_fib4_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, struct fib_notifier_info *info); +int call_fib4_notifiers(struct net *net, enum fib_event_type event_type, + struct fib_notifier_info *info); + +int __net_init fib4_notifier_init(struct net *net); +void __net_exit fib4_notifier_exit(struct net *net); void fib_notify(struct net *net, struct notifier_block *nb); -#ifdef CONFIG_IP_MULTIPLE_TABLES -void fib_rules_notify(struct net *net, struct notifier_block *nb); -#else -static inline void fib_rules_notify(struct net *net, struct notifier_block *nb) -{ -} -#endif struct fib_table { struct hlist_node tb_hlist; @@ -325,6 +286,16 @@ static inline bool fib4_rule_default(const struct fib_rule *rule) return true; } +static inline int fib4_rules_dump(struct net *net, struct notifier_block *nb) +{ + return 0; +} + +static inline unsigned int fib4_rules_seq_read(struct net *net) +{ + return 0; +} + #else /* CONFIG_IP_MULTIPLE_TABLES */ int __net_init fib4_rules_init(struct net *net); void __net_exit fib4_rules_exit(struct net *net); @@ -370,6 +341,8 @@ static inline int fib_lookup(struct net *net, struct flowi4 *flp, } bool fib4_rule_default(const struct fib_rule *rule); +int fib4_rules_dump(struct net *net, struct notifier_block *nb); +unsigned int fib4_rules_seq_read(struct net *net); #endif /* CONFIG_IP_MULTIPLE_TABLES */ diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 520809912f0392e84b12cc8ce99d82e3e27f5d78..992652856fe8c7c1032e0f5f92ce7ee5aa0119da 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -115,6 +115,9 @@ struct ip_tunnel { u32 o_seqno; /* The last output seqno */ int tun_hlen; /* Precalculated header length */ + /* This field used only by ERSPAN */ + u32 index; /* ERSPAN type II index */ + struct dst_cache dst_cache; struct ip_tunnel_parm parms; @@ -151,8 +154,10 @@ struct ip_tunnel { #define TUNNEL_GENEVE_OPT __cpu_to_be16(0x0800) #define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000) #define TUNNEL_NOCACHE __cpu_to_be16(0x2000) +#define TUNNEL_ERSPAN_OPT __cpu_to_be16(0x4000) -#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT) +#define TUNNEL_OPTIONS_PRESENT \ + (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT) struct tnl_ptk_info { __be16 flags; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b2b5419467cc123b4a2b70c2d926b4576651248d..885690fa39c8d8f4a48f2fa25447646d3d0a7856 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -919,21 +919,10 @@ struct ieee80211_tx_info { unsigned long jiffies; }; /* NB: vif can be NULL for injected frames */ - union { - /* NB: vif can be NULL for injected frames */ - struct ieee80211_vif *vif; - - /* When packets are enqueued on txq it's easy - * to re-construct the vif pointer. There's no - * more space in tx_info so it can be used to - * store the necessary enqueue time for packet - * sojourn time computation. - */ - codel_time_t enqueue_time; - }; + struct ieee80211_vif *vif; struct ieee80211_key_conf *hw_key; u32 flags; - /* 4 bytes free */ + codel_time_t enqueue_time; } control; struct { u64 cookie; @@ -5499,6 +5488,21 @@ static inline void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, ieee80211_manage_rx_ba_offl(vif, addr, tid + IEEE80211_NUM_TIDS); } +/** + * ieee80211_rx_ba_timer_expired - stop a Rx BA session due to timeout + * + * Some device drivers do not offload AddBa/DelBa negotiation, but handle rx + * buffer reording internally, and therefore also handle the session timer. + * + * Trigger the timeout flow, which sends a DelBa. + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback + * @addr: station mac address + * @tid: the rx tid + */ +void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif, + const u8 *addr, unsigned int tid); + /* Rate control API */ /** diff --git a/include/net/ncsi.h b/include/net/ncsi.h index 68680baac0fd87a66759a30adfde823afd544e0e..fdc60ff2511d7ac54f04dae0370c171c4c0a51d1 100644 --- a/include/net/ncsi.h +++ b/include/net/ncsi.h @@ -28,12 +28,24 @@ struct ncsi_dev { }; #ifdef CONFIG_NET_NCSI +int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid); +int ncsi_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid); struct ncsi_dev *ncsi_register_dev(struct net_device *dev, void (*notifier)(struct ncsi_dev *nd)); int ncsi_start_dev(struct ncsi_dev *nd); void ncsi_stop_dev(struct ncsi_dev *nd); void ncsi_unregister_dev(struct ncsi_dev *nd); #else /* !CONFIG_NET_NCSI */ +static inline int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + return -EINVAL; +} + +static inline int ncsi_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + return -EINVAL; +} + static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev, void (*notifier)(struct ncsi_dev *nd)) { diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 1c401bd4c2e0b78d77a6e94507a9525be716c6d4..57faa375eab9c063b98c75d440d10da96d217df8 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -88,6 +88,7 @@ struct net { /* core fib_rules */ struct list_head rules_ops; + struct list_head fib_notifier_ops; /* protected by net_mutex */ struct net_device *loopback_dev; /* The loopback */ struct netns_core core; diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 48407569585da8b44db8ee089e96fdf53c7469de..8f3bd30511def05c91870b2f73bba03e4dc1b04a 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -44,12 +43,6 @@ union nf_conntrack_expect_proto { #include #include -#ifdef CONFIG_NETFILTER_DEBUG -#define NF_CT_ASSERT(x) WARN_ON(!(x)) -#else -#define NF_CT_ASSERT(x) -#endif - #include #include @@ -83,7 +76,7 @@ struct nf_conn { possible_net_t ct_net; #if IS_ENABLED(CONFIG_NF_NAT) - struct rhlist_head nat_bysource; + struct hlist_node nat_bysource; #endif /* all members below initialized via memset */ u8 __nfct_init_offset[0]; @@ -159,7 +152,7 @@ nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) /* decrement reference count on a conntrack */ static inline void nf_ct_put(struct nf_conn *ct) { - NF_CT_ASSERT(ct); + WARN_ON(!ct); nf_conntrack_put(&ct->ct_general); } @@ -224,6 +217,9 @@ extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct, enum ip_conntrack_dir dir, u32 seq); +/* Set all unconfirmed conntrack as dying */ +void nf_ct_unconfirmed_destroy(struct net *); + /* Iterate over all conntracks: if iter returns true, it's deleted. */ void nf_ct_iterate_cleanup_net(struct net *net, int (*iter)(struct nf_conn *i, void *data), diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 2ba54feaccd8d4a6ebccc84fd5e21f45bff665ca..818def0111101cf9d82f9f3ea54b1bb73545f488 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -107,6 +107,11 @@ void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); bool nf_ct_remove_expect(struct nf_conntrack_expect *exp); +void nf_ct_expect_iterate_destroy(bool (*iter)(struct nf_conntrack_expect *e, void *data), void *data); +void nf_ct_expect_iterate_net(struct net *net, + bool (*iter)(struct nf_conntrack_expect *e, void *data), + void *data, u32 portid, int report); + /* Allocate space for an expectation: this is mandatory before calling nf_ct_expect_related. You will have to call put afterwards. */ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me); diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 6d14b36e3a49084a58333ceff5db0b1957aff387..6269deecbee775d8ca47c1e6beb70504487f3d34 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -20,8 +20,8 @@ struct nf_conntrack_l3proto { /* L3 Protocol Family number. ex) PF_INET */ u_int16_t l3proto; - /* Protocol name */ - const char *name; + /* size of tuple nlattr, fills a hole */ + u16 nla_size; /* * Try to fill in the third arg: nhoff is offset of l3 proto @@ -37,10 +37,6 @@ struct nf_conntrack_l3proto { bool (*invert_tuple)(struct nf_conntrack_tuple *inverse, const struct nf_conntrack_tuple *orig); - /* Print out the per-protocol part of the tuple. */ - void (*print_tuple)(struct seq_file *s, - const struct nf_conntrack_tuple *); - /* * Called before tracking. * *dataoff: offset of protocol header (TCP, UDP,...) in skb @@ -49,23 +45,17 @@ struct nf_conntrack_l3proto { int (*get_l4proto)(const struct sk_buff *skb, unsigned int nhoff, unsigned int *dataoff, u_int8_t *protonum); +#if IS_ENABLED(CONFIG_NF_CT_NETLINK) int (*tuple_to_nlattr)(struct sk_buff *skb, const struct nf_conntrack_tuple *t); - - /* Called when netns wants to use connection tracking */ - int (*net_ns_get)(struct net *); - void (*net_ns_put)(struct net *); - - /* - * Calculate size of tuple nlattr - */ - int (*nlattr_tuple_size)(void); - int (*nlattr_to_tuple)(struct nlattr *tb[], struct nf_conntrack_tuple *t); const struct nla_policy *nla_policy; +#endif - size_t nla_size; + /* Called when netns wants to use connection tracking */ + int (*net_ns_get)(struct net *); + void (*net_ns_put)(struct net *); /* Module (if any) which this is connected to. */ struct module *me; @@ -73,26 +63,11 @@ struct nf_conntrack_l3proto { extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[NFPROTO_NUMPROTO]; -#ifdef CONFIG_SYSCTL -/* Protocol pernet registration. */ -int nf_ct_l3proto_pernet_register(struct net *net, - struct nf_conntrack_l3proto *proto); -#else -static inline int nf_ct_l3proto_pernet_register(struct net *n, - struct nf_conntrack_l3proto *p) -{ - return 0; -} -#endif - -void nf_ct_l3proto_pernet_unregister(struct net *net, - struct nf_conntrack_l3proto *proto); - /* Protocol global registration. */ -int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto); -void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto); +int nf_ct_l3proto_register(const struct nf_conntrack_l3proto *proto); +void nf_ct_l3proto_unregister(const struct nf_conntrack_l3proto *proto); -struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); +const struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto); /* Existing built-in protocols */ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic; diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 7032e044bbe2a364ae0cfdb629f2e0c20ac81e8a..738a0307a96bcbc556980e8b28900196e8f72f48 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -43,7 +43,6 @@ struct nf_conntrack_l4proto { unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts); /* Called when a new connection for this protocol found; @@ -61,13 +60,6 @@ struct nf_conntrack_l4proto { /* called by gc worker if table is full */ bool (*can_early_drop)(const struct nf_conn *ct); - /* Print out the per-protocol part of the tuple. Return like seq_* */ - void (*print_tuple)(struct seq_file *s, - const struct nf_conntrack_tuple *); - - /* Print out the private part of the conntrack. */ - void (*print_conntrack)(struct seq_file *s, struct nf_conn *); - /* Return the array of timeouts for this protocol. */ unsigned int *(*get_timeouts)(struct net *net); @@ -92,14 +84,18 @@ struct nf_conntrack_l4proto { #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) struct { - size_t obj_size; int (*nlattr_to_obj)(struct nlattr *tb[], struct net *net, void *data); int (*obj_to_nlattr)(struct sk_buff *skb, const void *data); - unsigned int nlattr_max; + u16 obj_size; + u16 nlattr_max; const struct nla_policy *nla_policy; } ctnl_timeout; +#endif +#ifdef CONFIG_NF_CONNTRACK_PROCFS + /* Print out the private part of the conntrack. */ + void (*print_conntrack)(struct seq_file *s, struct nf_conn *); #endif unsigned int *net_id; /* Init l4proto pernet data */ @@ -108,9 +104,6 @@ struct nf_conntrack_l4proto { /* Return the per-net protocol part. */ struct nf_proto_net *(*get_net_proto)(struct net *net); - /* Protocol name */ - const char *name; - /* Module (if any) which this is connected to. */ struct module *me; }; @@ -120,28 +113,28 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic; #define MAX_NF_CT_PROTO 256 -struct nf_conntrack_l4proto *__nf_ct_l4proto_find(u_int16_t l3proto, +const struct nf_conntrack_l4proto *__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto); -struct nf_conntrack_l4proto *nf_ct_l4proto_find_get(u_int16_t l3proto, +const struct nf_conntrack_l4proto *nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto); -void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p); +void nf_ct_l4proto_put(const struct nf_conntrack_l4proto *p); /* Protocol pernet registration. */ int nf_ct_l4proto_pernet_register_one(struct net *net, - struct nf_conntrack_l4proto *proto); + const struct nf_conntrack_l4proto *proto); void nf_ct_l4proto_pernet_unregister_one(struct net *net, - struct nf_conntrack_l4proto *proto); + const struct nf_conntrack_l4proto *proto); int nf_ct_l4proto_pernet_register(struct net *net, - struct nf_conntrack_l4proto *proto[], + struct nf_conntrack_l4proto *const proto[], unsigned int num_proto); void nf_ct_l4proto_pernet_unregister(struct net *net, - struct nf_conntrack_l4proto *proto[], - unsigned int num_proto); + struct nf_conntrack_l4proto *const proto[], + unsigned int num_proto); /* Protocol global registration. */ int nf_ct_l4proto_register_one(struct nf_conntrack_l4proto *proto); -void nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *proto); +void nf_ct_l4proto_unregister_one(const struct nf_conntrack_l4proto *proto); int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto[], unsigned int num_proto); void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto[], diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h index d40b89355fdd345617cf21593922753613190a11..483d104fa2541996f03cf587b22d9b5bbcffe424 100644 --- a/include/net/netfilter/nf_conntrack_timeout.h +++ b/include/net/netfilter/nf_conntrack_timeout.h @@ -16,7 +16,7 @@ struct ctnl_timeout { refcount_t refcnt; char name[CTNL_TIMEOUT_NAME_MAX]; __u16 l3num; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; char data[0]; }; @@ -68,7 +68,7 @@ struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct, static inline unsigned int * nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l4proto *l4proto) { #ifdef CONFIG_NF_CONNTRACK_TIMEOUT struct nf_conn_timeout *timeout_ext; diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h index 05c82a1a42679cf336c4ecc2addc30bdaceecbbe..b71701302e6176720a0ac8faf52b48e23bdb2fa9 100644 --- a/include/net/netfilter/nf_nat.h +++ b/include/net/netfilter/nf_nat.h @@ -1,6 +1,5 @@ #ifndef _NF_NAT_H #define _NF_NAT_H -#include #include #include #include diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h index 4454719ff849fde065f64eba042d7f58cd971078..39468720fc19226dea5839bf21f5ebb95d689ca6 100644 --- a/include/net/netfilter/nf_queue.h +++ b/include/net/netfilter/nf_queue.h @@ -10,9 +10,9 @@ struct nf_queue_entry { struct list_head list; struct sk_buff *skb; unsigned int id; + unsigned int hook_index; /* index in hook_entries->hook[] */ struct nf_hook_state state; - struct nf_hook_entry *hook; u16 size; /* sizeof(entry) + saved route keys */ /* extra space to store route keys */ diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index bd5be0d691d51dfe7453db5a9fa6adf225b361dc..0f5b12a4ad09f0dd79ceb231e6de037ab830b039 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -396,7 +396,7 @@ void nft_unregister_set(struct nft_set_type *type); struct nft_set { struct list_head list; struct list_head bindings; - char name[NFT_SET_MAXNAMELEN]; + char *name; u32 ktype; u32 dtype; u32 objtype; @@ -859,7 +859,7 @@ struct nft_chain { u16 level; u8 flags:6, genmask:2; - char name[NFT_CHAIN_MAXNAMELEN]; + char *name; }; enum nft_chain_type { @@ -957,7 +957,7 @@ struct nft_table { u32 use; u16 flags:14, genmask:2; - char name[NFT_TABLE_MAXNAMELEN]; + char *name; }; enum nft_af_flags { @@ -1007,21 +1007,21 @@ int nft_verdict_dump(struct sk_buff *skb, int type, * * @list: table stateful object list node * @table: table this object belongs to - * @type: pointer to object type - * @data: pointer to object data * @name: name of this stateful object * @genmask: generation mask * @use: number of references to this stateful object * @data: object data, layout depends on type + * @ops: object operations + * @data: pointer to object data */ struct nft_object { struct list_head list; - char name[NFT_OBJ_MAXNAMELEN]; + char *name; struct nft_table *table; u32 genmask:2, use:30; /* runtime data below here */ - const struct nft_object_type *type ____cacheline_aligned; + const struct nft_object_ops *ops ____cacheline_aligned; unsigned char data[] __attribute__((aligned(__alignof__(u64)))); }; @@ -1044,27 +1044,39 @@ void nft_obj_notify(struct net *net, struct nft_table *table, /** * struct nft_object_type - stateful object type * - * @eval: stateful object evaluation function + * @select_ops: function to select nft_object_ops + * @ops: default ops, used when no select_ops functions is present * @list: list node in list of object types * @type: stateful object numeric type - * @size: stateful object size * @owner: module owner * @maxattr: maximum netlink attribute * @policy: netlink attribute policy + */ +struct nft_object_type { + const struct nft_object_ops *(*select_ops)(const struct nft_ctx *, + const struct nlattr * const tb[]); + const struct nft_object_ops *ops; + struct list_head list; + u32 type; + unsigned int maxattr; + struct module *owner; + const struct nla_policy *policy; +}; + +/** + * struct nft_object_ops - stateful object operations + * + * @eval: stateful object evaluation function + * @size: stateful object size * @init: initialize object from netlink attributes * @destroy: release existing stateful object * @dump: netlink dump stateful object */ -struct nft_object_type { +struct nft_object_ops { void (*eval)(struct nft_object *obj, struct nft_regs *regs, const struct nft_pktinfo *pkt); - struct list_head list; - u32 type; unsigned int size; - unsigned int maxattr; - struct module *owner; - const struct nla_policy *policy; int (*init)(const struct nft_ctx *ctx, const struct nlattr *const tb[], struct nft_object *obj); @@ -1072,6 +1084,7 @@ struct nft_object_type { int (*dump)(struct sk_buff *skb, struct nft_object *obj, bool reset); + const struct nft_object_type *type; }; int nft_register_obj(struct nft_object_type *obj_type); @@ -1272,7 +1285,7 @@ struct nft_trans_set { struct nft_trans_chain { bool update; - char name[NFT_CHAIN_MAXNAMELEN]; + char *name; struct nft_stats __percpu *stats; u8 policy; }; diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h index 8f690effec373565fe0bb15862957ab8afd65e75..424684c337719683e71213e70ef9f823fb8ece6b 100644 --- a/include/net/netfilter/nf_tables_core.h +++ b/include/net/netfilter/nf_tables_core.h @@ -49,6 +49,8 @@ struct nft_payload_set { }; extern const struct nft_expr_ops nft_payload_fast_ops; + +extern struct static_key_false nft_counters_enabled; extern struct static_key_false nft_trace_enabled; #endif /* _NET_NF_TABLES_CORE_H */ diff --git a/include/net/netlink.h b/include/net/netlink.h index ef8e6c3a80a63f6c41f92e82405a5a77c1264ed6..14c289393071945821880c39b6100dbe57df08ac 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -178,6 +178,7 @@ enum { NLA_S16, NLA_S32, NLA_S64, + NLA_BITFIELD32, __NLA_TYPE_MAX, }; @@ -206,6 +207,7 @@ enum { * NLA_MSECS Leaving the length field zero will verify the * given type fits, using it verifies minimum length * just like "All other" + * NLA_BITFIELD32 A 32-bit bitmap/bitselector attribute * All other Minimum length of attribute payload * * Example: @@ -213,11 +215,13 @@ enum { * [ATTR_FOO] = { .type = NLA_U16 }, * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, + * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags }, * }; */ struct nla_policy { u16 type; u16 len; + void *validation_data; }; /** @@ -247,6 +251,7 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, int nla_policy_len(const struct nla_policy *, int); struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype); size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize); +char *nla_strdup(const struct nlattr *nla, gfp_t flags); int nla_memcpy(void *dest, const struct nlattr *src, int count); int nla_memcmp(const struct nlattr *nla, const void *data, size_t size); int nla_strcmp(const struct nlattr *nla, const char *str); @@ -768,7 +773,10 @@ static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, */ static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value) { - return nla_put(skb, attrtype, sizeof(u8), &value); + /* temporary variables to work around GCC PR81715 with asan-stack=1 */ + u8 tmp = value; + + return nla_put(skb, attrtype, sizeof(u8), &tmp); } /** @@ -779,7 +787,9 @@ static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value) */ static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) { - return nla_put(skb, attrtype, sizeof(u16), &value); + u16 tmp = value; + + return nla_put(skb, attrtype, sizeof(u16), &tmp); } /** @@ -790,7 +800,9 @@ static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value) */ static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value) { - return nla_put(skb, attrtype, sizeof(__be16), &value); + __be16 tmp = value; + + return nla_put(skb, attrtype, sizeof(__be16), &tmp); } /** @@ -801,7 +813,9 @@ static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value) */ static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value) { - return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, value); + __be16 tmp = value; + + return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, tmp); } /** @@ -812,7 +826,9 @@ static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value) */ static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value) { - return nla_put(skb, attrtype, sizeof(__le16), &value); + __le16 tmp = value; + + return nla_put(skb, attrtype, sizeof(__le16), &tmp); } /** @@ -823,7 +839,9 @@ static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value) */ static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) { - return nla_put(skb, attrtype, sizeof(u32), &value); + u32 tmp = value; + + return nla_put(skb, attrtype, sizeof(u32), &tmp); } /** @@ -834,7 +852,9 @@ static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value) */ static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value) { - return nla_put(skb, attrtype, sizeof(__be32), &value); + __be32 tmp = value; + + return nla_put(skb, attrtype, sizeof(__be32), &tmp); } /** @@ -845,7 +865,9 @@ static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value) */ static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value) { - return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, value); + __be32 tmp = value; + + return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, tmp); } /** @@ -856,7 +878,9 @@ static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value) */ static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value) { - return nla_put(skb, attrtype, sizeof(__le32), &value); + __le32 tmp = value; + + return nla_put(skb, attrtype, sizeof(__le32), &tmp); } /** @@ -869,7 +893,9 @@ static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value) static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype, u64 value, int padattr) { - return nla_put_64bit(skb, attrtype, sizeof(u64), &value, padattr); + u64 tmp = value; + + return nla_put_64bit(skb, attrtype, sizeof(u64), &tmp, padattr); } /** @@ -882,7 +908,9 @@ static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype, static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value, int padattr) { - return nla_put_64bit(skb, attrtype, sizeof(__be64), &value, padattr); + __be64 tmp = value; + + return nla_put_64bit(skb, attrtype, sizeof(__be64), &tmp, padattr); } /** @@ -895,7 +923,9 @@ static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value, static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value, int padattr) { - return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, value, + __be64 tmp = value; + + return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, tmp, padattr); } @@ -909,7 +939,9 @@ static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value, static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value, int padattr) { - return nla_put_64bit(skb, attrtype, sizeof(__le64), &value, padattr); + __le64 tmp = value; + + return nla_put_64bit(skb, attrtype, sizeof(__le64), &tmp, padattr); } /** @@ -920,7 +952,9 @@ static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value, */ static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value) { - return nla_put(skb, attrtype, sizeof(s8), &value); + s8 tmp = value; + + return nla_put(skb, attrtype, sizeof(s8), &tmp); } /** @@ -931,7 +965,9 @@ static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value) */ static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value) { - return nla_put(skb, attrtype, sizeof(s16), &value); + s16 tmp = value; + + return nla_put(skb, attrtype, sizeof(s16), &tmp); } /** @@ -942,7 +978,9 @@ static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value) */ static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value) { - return nla_put(skb, attrtype, sizeof(s32), &value); + s32 tmp = value; + + return nla_put(skb, attrtype, sizeof(s32), &tmp); } /** @@ -955,7 +993,9 @@ static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value) static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value, int padattr) { - return nla_put_64bit(skb, attrtype, sizeof(s64), &value, padattr); + s64 tmp = value; + + return nla_put_64bit(skb, attrtype, sizeof(s64), &tmp, padattr); } /** @@ -1005,7 +1045,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, static inline int nla_put_in_addr(struct sk_buff *skb, int attrtype, __be32 addr) { - return nla_put_be32(skb, attrtype, addr); + __be32 tmp = addr; + + return nla_put_be32(skb, attrtype, tmp); } /** @@ -1202,6 +1244,18 @@ static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla) return tmp; } +/** + * nla_get_bitfield32 - return payload of 32 bitfield attribute + * @nla: nla_bitfield32 attribute + */ +static inline struct nla_bitfield32 nla_get_bitfield32(const struct nlattr *nla) +{ + struct nla_bitfield32 tmp; + + nla_memcpy(&tmp, nla, sizeof(tmp)); + return tmp; +} + /** * nla_memdup - duplicate attribute memory (kmemdup) * @src: netlink attribute to duplicate from diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 9a14a0850b0e3601194479b4e1a433dc817e088e..20d061c805e31d7df32a258907f8a33eea01c048 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -159,6 +159,7 @@ struct netns_ipv4 { int sysctl_fib_multipath_hash_policy; #endif + struct fib_notifier_ops *notifier_ops; unsigned int fib_seq; /* protected by rtnl_mutex */ atomic_t rt_genid; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index de7745e2edcc63e65c1ab224a6835367d55c54c4..2544f9760a4263b7f1b8d622331ca63038586137 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -36,6 +36,7 @@ struct netns_sysctl_ipv6 { int idgen_retries; int idgen_delay; int flowlabel_state_ranges; + int flowlabel_reflect; }; struct netns_ipv6 { @@ -65,6 +66,7 @@ struct netns_ipv6 { unsigned int ip6_rt_gc_expire; unsigned long ip6_rt_last_gc; #ifdef CONFIG_IPV6_MULTIPLE_TABLES + bool fib6_has_custom_rules; struct rt6_info *ip6_prohibit_entry; struct rt6_info *ip6_blk_hole_entry; struct fib6_table *fib6_local_tbl; @@ -86,6 +88,7 @@ struct netns_ipv6 { atomic_t dev_addr_genid; atomic_t fib6_sernum; struct seg6_pernet_data *seg6_data; + struct fib_notifier_ops *notifier_ops; }; #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h index cea396b53a60d9a2e9cc849d55103c5c19d7cb37..72d66c8763d0378395b160e2887b1d978020f0e0 100644 --- a/include/net/netns/netfilter.h +++ b/include/net/netns/netfilter.h @@ -16,7 +16,7 @@ struct netns_nf { #ifdef CONFIG_SYSCTL struct ctl_table_header *nf_log_dir_header; #endif - struct nf_hook_entry __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; + struct nf_hook_entries __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) bool defrag_ipv4; #endif diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 27bb9633c69d4ec49ae800aef88c91b5882620a2..611521646dd4daf6eca8843b15dfc1dc38f3888c 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -6,7 +6,6 @@ #include #include #include -#include struct ctl_table_header; @@ -73,16 +72,6 @@ struct netns_xfrm { spinlock_t xfrm_state_lock; spinlock_t xfrm_policy_lock; struct mutex xfrm_cfg_mutex; - - /* flow cache part */ - struct flow_cache flow_cache_global; - atomic_t flow_cache_genid; - struct list_head flow_cache_gc_list; - atomic_t flow_cache_gc_count; - spinlock_t flow_cache_gc_lock; - struct work_struct flow_cache_gc_work; - struct work_struct flow_cache_flush_work; - struct mutex flow_flush_sem; }; #endif diff --git a/include/net/nsh.h b/include/net/nsh.h new file mode 100644 index 0000000000000000000000000000000000000000..a1eaea20be966bc30cd4aa778b905fef7a9dac1a --- /dev/null +++ b/include/net/nsh.h @@ -0,0 +1,307 @@ +#ifndef __NET_NSH_H +#define __NET_NSH_H 1 + +#include + +/* + * Network Service Header: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Ver|O|U| TTL | Length |U|U|U|U|MD Type| Next Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Service Path Identifier (SPI) | Service Index | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * ~ Mandatory/Optional Context Headers ~ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Version: The version field is used to ensure backward compatibility + * going forward with future NSH specification updates. It MUST be set + * to 0x0 by the sender, in this first revision of NSH. Given the + * widespread implementation of existing hardware that uses the first + * nibble after an MPLS label stack for ECMP decision processing, this + * document reserves version 01b and this value MUST NOT be used in + * future versions of the protocol. Please see [RFC7325] for further + * discussion of MPLS-related forwarding requirements. + * + * O bit: Setting this bit indicates an Operations, Administration, and + * Maintenance (OAM) packet. The actual format and processing of SFC + * OAM packets is outside the scope of this specification (see for + * example [I-D.ietf-sfc-oam-framework] for one approach). + * + * The O bit MUST be set for OAM packets and MUST NOT be set for non-OAM + * packets. The O bit MUST NOT be modified along the SFP. + * + * SF/SFF/SFC Proxy/Classifier implementations that do not support SFC + * OAM procedures SHOULD discard packets with O bit set, but MAY support + * a configurable parameter to enable forwarding received SFC OAM + * packets unmodified to the next element in the chain. Forwarding OAM + * packets unmodified by SFC elements that do not support SFC OAM + * procedures may be acceptable for a subset of OAM functions, but can + * result in unexpected outcomes for others, thus it is recommended to + * analyze the impact of forwarding an OAM packet for all OAM functions + * prior to enabling this behavior. The configurable parameter MUST be + * disabled by default. + * + * TTL: Indicates the maximum SFF hops for an SFP. This field is used + * for service plane loop detection. The initial TTL value SHOULD be + * configurable via the control plane; the configured initial value can + * be specific to one or more SFPs. If no initial value is explicitly + * provided, the default initial TTL value of 63 MUST be used. Each SFF + * involved in forwarding an NSH packet MUST decrement the TTL value by + * 1 prior to NSH forwarding lookup. Decrementing by 1 from an incoming + * value of 0 shall result in a TTL value of 63. The packet MUST NOT be + * forwarded if TTL is, after decrement, 0. + * + * All other flag fields, marked U, are unassigned and available for + * future use, see Section 11.2.1. Unassigned bits MUST be set to zero + * upon origination, and MUST be ignored and preserved unmodified by + * other NSH supporting elements. Elements which do not understand the + * meaning of any of these bits MUST NOT modify their actions based on + * those unknown bits. + * + * Length: The total length, in 4-byte words, of NSH including the Base + * Header, the Service Path Header, the Fixed Length Context Header or + * Variable Length Context Header(s). The length MUST be 0x6 for MD + * Type equal to 0x1, and MUST be 0x2 or greater for MD Type equal to + * 0x2. The length of the NSH header MUST be an integer multiple of 4 + * bytes, thus variable length metadata is always padded out to a + * multiple of 4 bytes. + * + * MD Type: Indicates the format of NSH beyond the mandatory Base Header + * and the Service Path Header. MD Type defines the format of the + * metadata being carried. + * + * 0x0 - This is a reserved value. Implementations SHOULD silently + * discard packets with MD Type 0x0. + * + * 0x1 - This indicates that the format of the header includes a fixed + * length Context Header (see Figure 4 below). + * + * 0x2 - This does not mandate any headers beyond the Base Header and + * Service Path Header, but may contain optional variable length Context + * Header(s). The semantics of the variable length Context Header(s) + * are not defined in this document. The format of the optional + * variable length Context Headers is provided in Section 2.5.1. + * + * 0xF - This value is reserved for experimentation and testing, as per + * [RFC3692]. Implementations not explicitly configured to be part of + * an experiment SHOULD silently discard packets with MD Type 0xF. + * + * Next Protocol: indicates the protocol type of the encapsulated data. + * NSH does not alter the inner payload, and the semantics on the inner + * protocol remain unchanged due to NSH service function chaining. + * Please see the IANA Considerations section below, Section 11.2.5. + * + * This document defines the following Next Protocol values: + * + * 0x1: IPv4 + * 0x2: IPv6 + * 0x3: Ethernet + * 0x4: NSH + * 0x5: MPLS + * 0xFE: Experiment 1 + * 0xFF: Experiment 2 + * + * Packets with Next Protocol values not supported SHOULD be silently + * dropped by default, although an implementation MAY provide a + * configuration parameter to forward them. Additionally, an + * implementation not explicitly configured for a specific experiment + * [RFC3692] SHOULD silently drop packets with Next Protocol values 0xFE + * and 0xFF. + * + * Service Path Identifier (SPI): Identifies a service path. + * Participating nodes MUST use this identifier for Service Function + * Path selection. The initial classifier MUST set the appropriate SPI + * for a given classification result. + * + * Service Index (SI): Provides location within the SFP. The initial + * classifier for a given SFP SHOULD set the SI to 255, however the + * control plane MAY configure the initial value of SI as appropriate + * (i.e., taking into account the length of the service function path). + * The Service Index MUST be decremented by a value of 1 by Service + * Functions or by SFC Proxy nodes after performing required services + * and the new decremented SI value MUST be used in the egress packet's + * NSH. The initial Classifier MUST send the packet to the first SFF in + * the identified SFP for forwarding along an SFP. If re-classification + * occurs, and that re-classification results in a new SPI, the + * (re)classifier is, in effect, the initial classifier for the + * resultant SPI. + * + * The SI is used in conjunction the with Service Path Identifier for + * Service Function Path Selection and for determining the next SFF/SF + * in the path. The SI is also valuable when troubleshooting or + * reporting service paths. Additionally, while the TTL field is the + * main mechanism for service plane loop detection, the SI can also be + * used for detecting service plane loops. + * + * When the Base Header specifies MD Type = 0x1, a Fixed Length Context + * Header (16-bytes) MUST be present immediately following the Service + * Path Header. The value of a Fixed Length Context + * Header that carries no metadata MUST be set to zero. + * + * When the base header specifies MD Type = 0x2, zero or more Variable + * Length Context Headers MAY be added, immediately following the + * Service Path Header (see Figure 5). Therefore, Length = 0x2, + * indicates that only the Base Header followed by the Service Path + * Header are present. The optional Variable Length Context Headers + * MUST be of an integer number of 4-bytes. The base header Length + * field MUST be used to determine the offset to locate the original + * packet or frame for SFC nodes that require access to that + * information. + * + * The format of the optional variable length Context Headers + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Metadata Class | Type |U| Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Variable Metadata | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Metadata Class (MD Class): Defines the scope of the 'Type' field to + * provide a hierarchical namespace. The IANA Considerations + * Section 11.2.4 defines how the MD Class values can be allocated to + * standards bodies, vendors, and others. + * + * Type: Indicates the explicit type of metadata being carried. The + * definition of the Type is the responsibility of the MD Class owner. + * + * Unassigned bit: One unassigned bit is available for future use. This + * bit MUST NOT be set, and MUST be ignored on receipt. + * + * Length: Indicates the length of the variable metadata, in bytes. In + * case the metadata length is not an integer number of 4-byte words, + * the sender MUST add pad bytes immediately following the last metadata + * byte to extend the metadata to an integer number of 4-byte words. + * The receiver MUST round up the length field to the nearest 4-byte + * word boundary, to locate and process the next field in the packet. + * The receiver MUST access only those bytes in the metadata indicated + * by the length field (i.e., actual number of bytes) and MUST ignore + * the remaining bytes up to the nearest 4-byte word boundary. The + * Length may be 0 or greater. + * + * A value of 0 denotes a Context Header without a Variable Metadata + * field. + * + * [0] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/ + */ + +/** + * struct nsh_md1_ctx - Keeps track of NSH context data + * @nshc<1-4>: NSH Contexts. + */ +struct nsh_md1_ctx { + __be32 context[4]; +}; + +struct nsh_md2_tlv { + __be16 md_class; + u8 type; + u8 length; + u8 md_value[]; +}; + +struct nshhdr { + __be16 ver_flags_ttl_len; + u8 mdtype; + u8 np; + __be32 path_hdr; + union { + struct nsh_md1_ctx md1; + struct nsh_md2_tlv md2; + }; +}; + +/* Masking NSH header fields. */ +#define NSH_VER_MASK 0xc000 +#define NSH_VER_SHIFT 14 +#define NSH_FLAGS_MASK 0x3000 +#define NSH_FLAGS_SHIFT 12 +#define NSH_TTL_MASK 0x0fc0 +#define NSH_TTL_SHIFT 6 +#define NSH_LEN_MASK 0x003f +#define NSH_LEN_SHIFT 0 + +#define NSH_MDTYPE_MASK 0x0f +#define NSH_MDTYPE_SHIFT 0 + +#define NSH_SPI_MASK 0xffffff00 +#define NSH_SPI_SHIFT 8 +#define NSH_SI_MASK 0x000000ff +#define NSH_SI_SHIFT 0 + +/* MD Type Registry. */ +#define NSH_M_TYPE1 0x01 +#define NSH_M_TYPE2 0x02 +#define NSH_M_EXP1 0xFE +#define NSH_M_EXP2 0xFF + +/* NSH Base Header Length */ +#define NSH_BASE_HDR_LEN 8 + +/* NSH MD Type 1 header Length. */ +#define NSH_M_TYPE1_LEN 24 + +/* NSH header maximum Length. */ +#define NSH_HDR_MAX_LEN 256 + +/* NSH context headers maximum Length. */ +#define NSH_CTX_HDRS_MAX_LEN 248 + +static inline struct nshhdr *nsh_hdr(struct sk_buff *skb) +{ + return (struct nshhdr *)skb_network_header(skb); +} + +static inline u16 nsh_hdr_len(const struct nshhdr *nsh) +{ + return ((ntohs(nsh->ver_flags_ttl_len) & NSH_LEN_MASK) + >> NSH_LEN_SHIFT) << 2; +} + +static inline u8 nsh_get_ver(const struct nshhdr *nsh) +{ + return (ntohs(nsh->ver_flags_ttl_len) & NSH_VER_MASK) + >> NSH_VER_SHIFT; +} + +static inline u8 nsh_get_flags(const struct nshhdr *nsh) +{ + return (ntohs(nsh->ver_flags_ttl_len) & NSH_FLAGS_MASK) + >> NSH_FLAGS_SHIFT; +} + +static inline u8 nsh_get_ttl(const struct nshhdr *nsh) +{ + return (ntohs(nsh->ver_flags_ttl_len) & NSH_TTL_MASK) + >> NSH_TTL_SHIFT; +} + +static inline void __nsh_set_xflag(struct nshhdr *nsh, u16 xflag, u16 xmask) +{ + nsh->ver_flags_ttl_len + = (nsh->ver_flags_ttl_len & ~htons(xmask)) | htons(xflag); +} + +static inline void nsh_set_flags_and_ttl(struct nshhdr *nsh, u8 flags, u8 ttl) +{ + __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) | + ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK), + NSH_FLAGS_MASK | NSH_TTL_MASK); +} + +static inline void nsh_set_flags_ttl_len(struct nshhdr *nsh, u8 flags, + u8 ttl, u8 len) +{ + len = len >> 2; + __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) | + ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK) | + ((len << NSH_LEN_SHIFT) & NSH_LEN_MASK), + NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK); +} + +#endif /* __NET_NSH_H */ diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 537d0a0ad4c4615449414ffdb9fbea8110e2c008..e80edd8879efc70f96dc0fbe91714c48714edc54 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -11,7 +11,7 @@ struct tcf_walker { int stop; int skip; int count; - int (*fn)(struct tcf_proto *, unsigned long node, struct tcf_walker *); + int (*fn)(struct tcf_proto *, void *node, struct tcf_walker *); }; int register_tcf_proto_ops(struct tcf_proto_ops *ops); @@ -113,36 +113,6 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police) return 0; } -/** - * tcf_exts_is_predicative - check if a predicative extension is present - * @exts: tc filter extensions handle - * - * Returns 1 if a predicative extension is present, i.e. an extension which - * might cause further actions and thus overrule the regular tcf_result. - */ -static inline int -tcf_exts_is_predicative(struct tcf_exts *exts) -{ -#ifdef CONFIG_NET_CLS_ACT - return exts->nr_actions; -#else - return 0; -#endif -} - -/** - * tcf_exts_is_available - check if at least one extension is present - * @exts: tc filter extensions handle - * - * Returns 1 if at least one extension is present. - */ -static inline int -tcf_exts_is_available(struct tcf_exts *exts) -{ - /* All non-predicative extensions must be added here. */ - return tcf_exts_is_predicative(exts); -} - static inline void tcf_exts_to_list(const struct tcf_exts *exts, struct list_head *actions) { @@ -176,47 +146,62 @@ tcf_exts_stats_update(const struct tcf_exts *exts, #endif } +/** + * tcf_exts_has_actions - check if at least one action is present + * @exts: tc filter extensions handle + * + * Returns true if at least one action is present. + */ +static inline bool tcf_exts_has_actions(struct tcf_exts *exts) +{ +#ifdef CONFIG_NET_CLS_ACT + return exts->nr_actions; +#else + return false; +#endif +} + +/** + * tcf_exts_has_one_action - check if exactly one action is present + * @exts: tc filter extensions handle + * + * Returns true if exactly one action is present. + */ +static inline bool tcf_exts_has_one_action(struct tcf_exts *exts) +{ +#ifdef CONFIG_NET_CLS_ACT + return exts->nr_actions == 1; +#else + return false; +#endif +} + /** * tcf_exts_exec - execute tc filter extensions * @skb: socket buffer * @exts: tc filter extensions handle * @res: desired result * - * Executes all configured extensions. Returns 0 on a normal execution, + * Executes all configured extensions. Returns TC_ACT_OK on a normal execution, * a negative number if the filter must be considered unmatched or * a positive action code (TC_ACT_*) which must be returned to the * underlying layer. */ static inline int tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts, - struct tcf_result *res) + struct tcf_result *res) { #ifdef CONFIG_NET_CLS_ACT - if (exts->nr_actions) - return tcf_action_exec(skb, exts->actions, exts->nr_actions, - res); + return tcf_action_exec(skb, exts->actions, exts->nr_actions, res); #endif - return 0; + return TC_ACT_OK; } -#ifdef CONFIG_NET_CLS_ACT - -#define tc_no_actions(_exts) ((_exts)->nr_actions == 0) -#define tc_single_action(_exts) ((_exts)->nr_actions == 1) - -#else /* CONFIG_NET_CLS_ACT */ - -#define tc_no_actions(_exts) true -#define tc_single_action(_exts) false - -#endif /* CONFIG_NET_CLS_ACT */ - int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr); void tcf_exts_destroy(struct tcf_exts *exts); -void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst, - struct tcf_exts *src); +void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src); int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts); int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts); int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts, @@ -332,26 +317,6 @@ int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int); int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *, struct tcf_pkt_info *); -/** - * tcf_em_tree_change - replace ematch tree of a running classifier - * - * @tp: classifier kind handle - * @dst: destination ematch tree variable - * @src: source ematch tree (temporary tree from tcf_em_tree_validate) - * - * This functions replaces the ematch tree in @dst with the ematch - * tree in @src. The classifier in charge of the ematch tree may be - * running. - */ -static inline void tcf_em_tree_change(struct tcf_proto *tp, - struct tcf_ematch_tree *dst, - struct tcf_ematch_tree *src) -{ - tcf_tree_lock(tp); - memcpy(dst, src, sizeof(*dst)); - tcf_tree_unlock(tp); -} - /** * tcf_em_tree_match - evaulate an ematch tree * @@ -386,7 +351,6 @@ struct tcf_ematch_tree { #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0) #define tcf_em_tree_destroy(t) do { (void)(t); } while(0) #define tcf_em_tree_dump(skb, t, tlv) (0) -#define tcf_em_tree_change(tp, dst, src) do { } while(0) #define tcf_em_tree_match(skb, t, info) ((void)(info), 1) #endif /* CONFIG_NET_EMATCH */ @@ -441,6 +405,23 @@ tcf_match_indev(struct sk_buff *skb, int ifindex) } #endif /* CONFIG_NET_CLS_IND */ +struct tc_cls_common_offload { + u32 chain_index; + __be16 protocol; + u32 prio; + u32 classid; +}; + +static inline void +tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common, + const struct tcf_proto *tp) +{ + cls_common->chain_index = tp->chain->index; + cls_common->protocol = tp->protocol; + cls_common->prio = tp->prio; + cls_common->classid = tp->classid; +} + struct tc_cls_u32_knode { struct tcf_exts *exts; struct tc_u32_sel *sel; @@ -467,6 +448,7 @@ enum tc_clsu32_command { }; struct tc_cls_u32_offload { + struct tc_cls_common_offload common; /* knode values */ enum tc_clsu32_command command; union { @@ -475,19 +457,12 @@ struct tc_cls_u32_offload { }; }; -static inline bool tc_can_offload(const struct net_device *dev, - const struct tcf_proto *tp) +static inline bool tc_can_offload(const struct net_device *dev) { - const struct Qdisc *sch = tp->q; - const struct Qdisc_class_ops *cops = sch->ops->cl_ops; - if (!(dev->features & NETIF_F_HW_TC)) return false; if (!dev->netdev_ops->ndo_setup_tc) return false; - if (cops && cops->tcf_cl_offload) - return cops->tcf_cl_offload(tp->classid); - return true; } @@ -496,12 +471,11 @@ static inline bool tc_skip_hw(u32 flags) return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false; } -static inline bool tc_should_offload(const struct net_device *dev, - const struct tcf_proto *tp, u32 flags) +static inline bool tc_should_offload(const struct net_device *dev, u32 flags) { if (tc_skip_hw(flags)) return false; - return tc_can_offload(dev, tp); + return tc_can_offload(dev); } static inline bool tc_skip_sw(u32 flags) @@ -533,13 +507,14 @@ enum tc_fl_command { }; struct tc_cls_flower_offload { + struct tc_cls_common_offload common; enum tc_fl_command command; - u32 prio; unsigned long cookie; struct flow_dissector *dissector; struct fl_flow_key *mask; struct fl_flow_key *key; struct tcf_exts *exts; + bool egress_dev; }; enum tc_matchall_command { @@ -548,6 +523,7 @@ enum tc_matchall_command { }; struct tc_cls_matchall_offload { + struct tc_cls_common_offload common; enum tc_matchall_command command; struct tcf_exts *exts; unsigned long cookie; @@ -561,6 +537,7 @@ enum tc_clsbpf_command { }; struct tc_cls_bpf_offload { + struct tc_cls_common_offload common; enum tc_clsbpf_command command; struct tcf_exts *exts; struct bpf_prog *prog; diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 2579c209ea51bdcab524c6f9070584d1a88e2bd2..259bc191ba5942bcb01b5033ef866c22c7608ad8 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -5,6 +5,7 @@ #include #include #include +#include #define DEFAULT_TX_QUEUE_LEN 1000 @@ -132,4 +133,17 @@ static inline unsigned int psched_mtu(const struct net_device *dev) return dev->mtu + dev->hard_header_len; } +static inline bool is_classid_clsact_ingress(u32 classid) +{ + /* This also returns true for ingress qdisc */ + return TC_H_MAJ(classid) == TC_H_MAJ(TC_H_CLSACT) && + TC_H_MIN(classid) != TC_H_MIN(TC_H_MIN_EGRESS); +} + +static inline bool is_classid_clsact_egress(u32 classid) +{ + return TC_H_MAJ(classid) == TC_H_MAJ(TC_H_CLSACT) && + TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS); +} + #endif diff --git a/include/net/protocol.h b/include/net/protocol.h index 65ba335b0e7e66bb7f1b4bd279d31e616e0dd31e..4fc75f7ae23beb47674b04df27ac6ef4594679fe 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -39,8 +39,8 @@ /* This is used to register protocols. */ struct net_protocol { - void (*early_demux)(struct sk_buff *skb); - void (*early_demux_handler)(struct sk_buff *skb); + int (*early_demux)(struct sk_buff *skb); + int (*early_demux_handler)(struct sk_buff *skb); int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); unsigned int no_policy:1, diff --git a/include/net/raw.h b/include/net/raw.h index 57c33dd22ec4dcb3955f3a6297631f9fab7e7237..99d26d0c4a1938632279df0e6677c8f0a0cad1ee 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -26,7 +26,7 @@ extern struct proto raw_prot; extern struct raw_hashinfo raw_v4_hashinfo; struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, unsigned short num, __be32 raddr, - __be32 laddr, int dif); + __be32 laddr, int dif, int sdif); int raw_abort(struct sock *sk, int err); void raw_icmp_error(struct sk_buff *, int, u32); diff --git a/include/net/rawv6.h b/include/net/rawv6.h index cbe4e9de1894674ea194239fd21d6f85435d5078..4addc5c988e02b6edff192a8b039831ddc5aa47d 100644 --- a/include/net/rawv6.h +++ b/include/net/rawv6.h @@ -6,7 +6,7 @@ extern struct raw_hashinfo raw_v6_hashinfo; struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, unsigned short num, const struct in6_addr *loc_addr, - const struct in6_addr *rmt_addr, int dif); + const struct in6_addr *rmt_addr, int dif, int sdif); int raw_abort(struct sock *sk, int err); diff --git a/include/net/route.h b/include/net/route.h index cb0a76d9dde17bc77d1b1db853b32d69bfa5f5c5..d538e6db1afef1e7ab50d8b491949e8ccdeca4a8 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -175,7 +175,9 @@ static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 fl4->fl4_gre_key = gre_key; return ip_route_output_key(net, fl4); } - +int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, + u8 tos, struct net_device *dev, + struct in_device *in_dev, u32 *itag); int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin); int ip_route_input_rcu(struct sk_buff *skb, __be32 dst, __be32 src, @@ -189,10 +191,11 @@ static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, rcu_read_lock(); err = ip_route_input_noref(skb, dst, src, tos, devin); - if (!err) - skb_dst_force_safe(skb); - if (!skb_dst(skb)) - err = -EINVAL; + if (!err) { + skb_dst_force(skb); + if (!skb_dst(skb)) + err = -EINVAL; + } rcu_read_unlock(); return err; diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index abe6b733d473cbd84657bc80c184b51dc2e167ac..21837ca68ecc11f1f6d82a9d08878c335c93975b 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -7,12 +7,15 @@ typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, struct netlink_ext_ack *); typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *); -typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *); + +enum rtnl_link_flags { + RTNL_FLAG_DOIT_UNLOCKED = 1, +}; int __rtnl_register(int protocol, int msgtype, - rtnl_doit_func, rtnl_dumpit_func, rtnl_calcit_func); + rtnl_doit_func, rtnl_dumpit_func, unsigned int flags); void rtnl_register(int protocol, int msgtype, - rtnl_doit_func, rtnl_dumpit_func, rtnl_calcit_func); + rtnl_doit_func, rtnl_dumpit_func, unsigned int flags); int rtnl_unregister(int protocol, int msgtype); void rtnl_unregister_all(int protocol); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 1c123e2b2415797e7d32a0248df817cb9fbcb0c9..135f5a2dd93122dd905557028068a31aeea37cb0 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -75,7 +75,6 @@ struct Qdisc { struct hlist_node hash; u32 handle; u32 parent; - void *u32_node; struct netdev_queue *dev_queue; @@ -101,6 +100,13 @@ struct Qdisc { spinlock_t busylock ____cacheline_aligned_in_smp; }; +static inline void qdisc_refcount_inc(struct Qdisc *qdisc) +{ + if (qdisc->flags & TCQ_F_BUILTIN) + return; + refcount_inc(&qdisc->refcnt); +} + static inline bool qdisc_is_running(const struct Qdisc *qdisc) { return (raw_read_seqcount(&qdisc->running) & 1) ? true : false; @@ -147,8 +153,7 @@ struct Qdisc_class_ops { void (*qlen_notify)(struct Qdisc *, unsigned long); /* Class manipulation routines */ - unsigned long (*get)(struct Qdisc *, u32 classid); - void (*put)(struct Qdisc *, unsigned long); + unsigned long (*find)(struct Qdisc *, u32 classid); int (*change)(struct Qdisc *, u32, u32, struct nlattr **, unsigned long *); int (*delete)(struct Qdisc *, unsigned long); @@ -156,7 +161,6 @@ struct Qdisc_class_ops { /* Filter manipulation */ struct tcf_block * (*tcf_block)(struct Qdisc *, unsigned long); - bool (*tcf_cl_offload)(u32 classid); unsigned long (*bind_tcf)(struct Qdisc *, unsigned long, u32 classid); void (*unbind_tcf)(struct Qdisc *, unsigned long); @@ -213,16 +217,17 @@ struct tcf_proto_ops { int (*init)(struct tcf_proto*); void (*destroy)(struct tcf_proto*); - unsigned long (*get)(struct tcf_proto*, u32 handle); + void* (*get)(struct tcf_proto*, u32 handle); int (*change)(struct net *net, struct sk_buff *, struct tcf_proto*, unsigned long, u32 handle, struct nlattr **, - unsigned long *, bool); - int (*delete)(struct tcf_proto*, unsigned long, bool*); + void **, bool); + int (*delete)(struct tcf_proto*, void *, bool*); void (*walk)(struct tcf_proto*, struct tcf_walker *arg); + void (*bind_class)(void *, u32, unsigned long); /* rtnetlink specific */ - int (*dump)(struct net*, struct tcf_proto*, unsigned long, + int (*dump)(struct net*, struct tcf_proto*, void *, struct sk_buff *skb, struct tcmsg*); struct module *owner; @@ -394,6 +399,9 @@ qdisc_class_find(const struct Qdisc_class_hash *hash, u32 id) struct Qdisc_class_common *cl; unsigned int h; + if (!id) + return NULL; + h = qdisc_class_hash(id, hash->hashmask); hlist_for_each_entry(cl, &hash->hash[h], hnode) { if (cl->classid == id) @@ -806,8 +814,11 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new, old = *pold; *pold = new; if (old != NULL) { - qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog); + unsigned int qlen = old->q.qlen; + unsigned int backlog = old->qstats.backlog; + qdisc_reset(old); + qdisc_tree_reduce_backlog(old, qlen, backlog); } sch_tree_unlock(sch); diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index d4679e7a5ed580d2735e90b1e5089e9ee1f3b1d1..b55c6a48a20696328e918155d310132160f87f64 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -40,7 +40,7 @@ #include -typedef enum { +enum sctp_verb { SCTP_CMD_NOP = 0, /* Do nothing. */ SCTP_CMD_NEW_ASOC, /* Register a new association. */ SCTP_CMD_DELETE_TCB, /* Delete the current association. */ @@ -108,16 +108,16 @@ typedef enum { SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ SCTP_CMD_SET_ASOC, /* Restore association context */ SCTP_CMD_LAST -} sctp_verb_t; +}; -/* How many commands can you put in an sctp_cmd_seq_t? +/* How many commands can you put in an struct sctp_cmd_seq? * This is a rather arbitrary number, ideally derived from a careful * analysis of the state functions, but in reality just taken from * thin air in the hopes othat we don't trigger a kernel panic. */ #define SCTP_MAX_NUM_COMMANDS 20 -typedef union { +union sctp_arg { void *zero_all; /* Set to NULL to clear the entire union */ __s32 i32; __u32 u32; @@ -126,8 +126,8 @@ typedef union { __u8 u8; int error; __be16 err; - sctp_state_t state; - sctp_event_timeout_t to; + enum sctp_state state; + enum sctp_event_timeout to; struct sctp_chunk *chunk; struct sctp_association *asoc; struct sctp_transport *transport; @@ -135,26 +135,26 @@ typedef union { struct sctp_init_chunk *init; struct sctp_ulpevent *ulpevent; struct sctp_packet *packet; - sctp_sackhdr_t *sackh; + struct sctp_sackhdr *sackh; struct sctp_datamsg *msg; -} sctp_arg_t; +}; /* We are simulating ML type constructors here. * * SCTP_ARG_CONSTRUCTOR(NAME, TYPE, ELT) builds a function called * SCTP_NAME() which takes an argument of type TYPE and returns an - * sctp_arg_t. It does this by inserting the sole argument into the - * ELT union element of a local sctp_arg_t. + * union sctp_arg. It does this by inserting the sole argument into + * the ELT union element of a local union sctp_arg. * * E.g., SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) builds SCTP_I32(arg), - * which takes an __s32 and returns a sctp_arg_t containing the + * which takes an __s32 and returns a union sctp_arg containing the * __s32. So, after foo = SCTP_I32(arg), foo.i32 == arg. */ #define SCTP_ARG_CONSTRUCTOR(name, type, elt) \ -static inline sctp_arg_t \ +static inline union sctp_arg \ SCTP_## name (type arg) \ -{ sctp_arg_t retval;\ +{ union sctp_arg retval;\ retval.zero_all = NULL;\ retval.elt = arg;\ return retval;\ @@ -167,8 +167,8 @@ SCTP_ARG_CONSTRUCTOR(U16, __u16, u16) SCTP_ARG_CONSTRUCTOR(U8, __u8, u8) SCTP_ARG_CONSTRUCTOR(ERROR, int, error) SCTP_ARG_CONSTRUCTOR(PERR, __be16, err) /* protocol error */ -SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state) -SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to) +SCTP_ARG_CONSTRUCTOR(STATE, enum sctp_state, state) +SCTP_ARG_CONSTRUCTOR(TO, enum sctp_event_timeout, to) SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk) SCTP_ARG_CONSTRUCTOR(ASOC, struct sctp_association *, asoc) SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport) @@ -176,42 +176,42 @@ SCTP_ARG_CONSTRUCTOR(BA, struct sctp_bind_addr *, bp) SCTP_ARG_CONSTRUCTOR(PEER_INIT, struct sctp_init_chunk *, init) SCTP_ARG_CONSTRUCTOR(ULPEVENT, struct sctp_ulpevent *, ulpevent) SCTP_ARG_CONSTRUCTOR(PACKET, struct sctp_packet *, packet) -SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh) +SCTP_ARG_CONSTRUCTOR(SACKH, struct sctp_sackhdr *, sackh) SCTP_ARG_CONSTRUCTOR(DATAMSG, struct sctp_datamsg *, msg) -static inline sctp_arg_t SCTP_FORCE(void) +static inline union sctp_arg SCTP_FORCE(void) { return SCTP_I32(1); } -static inline sctp_arg_t SCTP_NOFORCE(void) +static inline union sctp_arg SCTP_NOFORCE(void) { return SCTP_I32(0); } -static inline sctp_arg_t SCTP_NULL(void) +static inline union sctp_arg SCTP_NULL(void) { - sctp_arg_t retval; + union sctp_arg retval; retval.zero_all = NULL; return retval; } -typedef struct { - sctp_arg_t obj; - sctp_verb_t verb; -} sctp_cmd_t; +struct sctp_cmd { + union sctp_arg obj; + enum sctp_verb verb; +}; -typedef struct { - sctp_cmd_t cmds[SCTP_MAX_NUM_COMMANDS]; - sctp_cmd_t *last_used_slot; - sctp_cmd_t *next_cmd; -} sctp_cmd_seq_t; +struct sctp_cmd_seq { + struct sctp_cmd cmds[SCTP_MAX_NUM_COMMANDS]; + struct sctp_cmd *last_used_slot; + struct sctp_cmd *next_cmd; +}; /* Initialize a block of memory as a command sequence. * Return 0 if the initialization fails. */ -static inline int sctp_init_cmd_seq(sctp_cmd_seq_t *seq) +static inline int sctp_init_cmd_seq(struct sctp_cmd_seq *seq) { /* cmds[] is filled backwards to simplify the overflow BUG() check */ seq->last_used_slot = seq->cmds + SCTP_MAX_NUM_COMMANDS; @@ -220,15 +220,15 @@ static inline int sctp_init_cmd_seq(sctp_cmd_seq_t *seq) } -/* Add a command to an sctp_cmd_seq_t. +/* Add a command to an struct sctp_cmd_seq. * * Use the SCTP_* constructors defined by SCTP_ARG_CONSTRUCTOR() above * to wrap data which goes in the obj argument. */ -static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, - sctp_arg_t obj) +static inline void sctp_add_cmd_sf(struct sctp_cmd_seq *seq, + enum sctp_verb verb, union sctp_arg obj) { - sctp_cmd_t *cmd = seq->last_used_slot - 1; + struct sctp_cmd *cmd = seq->last_used_slot - 1; BUG_ON(cmd < seq->cmds); @@ -240,7 +240,7 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, /* Return the next command structure in an sctp_cmd_seq. * Return NULL at the end of the sequence. */ -static inline sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq) +static inline struct sctp_cmd *sctp_next_cmd(struct sctp_cmd_seq *seq) { if (seq->next_cmd <= seq->last_used_slot) return NULL; diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 9b18044c551eb6b81e21d7cb3f72068ad0cff67a..deaafa9b09cbea18a438070c0579ababf73dcfba 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -42,7 +42,7 @@ #include #include /* For ipv6hdr. */ -#include /* For TCP states used in sctp_sock_state_t */ +#include /* For TCP states used in enum sctp_sock_state */ /* Value used for stream negotiation. */ enum { SCTP_MAX_STREAM = 0xffff }; @@ -71,20 +71,18 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM }; SCTP_NUM_AUTH_CHUNK_TYPES) /* These are the different flavours of event. */ -typedef enum { - +enum sctp_event { SCTP_EVENT_T_CHUNK = 1, SCTP_EVENT_T_TIMEOUT, SCTP_EVENT_T_OTHER, SCTP_EVENT_T_PRIMITIVE - -} sctp_event_t; +}; /* As a convenience for the state machine, we append SCTP_EVENT_* and * SCTP_ULP_* to the list of possible chunks. */ -typedef enum { +enum sctp_event_timeout { SCTP_EVENT_TIMEOUT_NONE = 0, SCTP_EVENT_TIMEOUT_T1_COOKIE, SCTP_EVENT_TIMEOUT_T1_INIT, @@ -96,21 +94,21 @@ typedef enum { SCTP_EVENT_TIMEOUT_RECONF, SCTP_EVENT_TIMEOUT_SACK, SCTP_EVENT_TIMEOUT_AUTOCLOSE, -} sctp_event_timeout_t; +}; #define SCTP_EVENT_TIMEOUT_MAX SCTP_EVENT_TIMEOUT_AUTOCLOSE #define SCTP_NUM_TIMEOUT_TYPES (SCTP_EVENT_TIMEOUT_MAX + 1) -typedef enum { +enum sctp_event_other { SCTP_EVENT_NO_PENDING_TSN = 0, SCTP_EVENT_ICMP_PROTO_UNREACH, -} sctp_event_other_t; +}; #define SCTP_EVENT_OTHER_MAX SCTP_EVENT_ICMP_PROTO_UNREACH #define SCTP_NUM_OTHER_TYPES (SCTP_EVENT_OTHER_MAX + 1) /* These are primitive requests from the ULP. */ -typedef enum { +enum sctp_event_primitive { SCTP_PRIMITIVE_ASSOCIATE = 0, SCTP_PRIMITIVE_SHUTDOWN, SCTP_PRIMITIVE_ABORT, @@ -118,7 +116,7 @@ typedef enum { SCTP_PRIMITIVE_REQUESTHEARTBEAT, SCTP_PRIMITIVE_ASCONF, SCTP_PRIMITIVE_RECONF, -} sctp_event_primitive_t; +}; #define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_RECONF #define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1) @@ -126,25 +124,25 @@ typedef enum { /* We define here a utility type for manipulating subtypes. * The subtype constructors all work like this: * - * sctp_subtype_t foo = SCTP_ST_CHUNK(SCTP_CID_INIT); + * union sctp_subtype foo = SCTP_ST_CHUNK(SCTP_CID_INIT); */ -typedef union { +union sctp_subtype { enum sctp_cid chunk; - sctp_event_timeout_t timeout; - sctp_event_other_t other; - sctp_event_primitive_t primitive; -} sctp_subtype_t; + enum sctp_event_timeout timeout; + enum sctp_event_other other; + enum sctp_event_primitive primitive; +}; #define SCTP_SUBTYPE_CONSTRUCTOR(_name, _type, _elt) \ -static inline sctp_subtype_t \ +static inline union sctp_subtype \ SCTP_ST_## _name (_type _arg) \ -{ sctp_subtype_t _retval; _retval._elt = _arg; return _retval; } +{ union sctp_subtype _retval; _retval._elt = _arg; return _retval; } SCTP_SUBTYPE_CONSTRUCTOR(CHUNK, enum sctp_cid, chunk) -SCTP_SUBTYPE_CONSTRUCTOR(TIMEOUT, sctp_event_timeout_t, timeout) -SCTP_SUBTYPE_CONSTRUCTOR(OTHER, sctp_event_other_t, other) -SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive) +SCTP_SUBTYPE_CONSTRUCTOR(TIMEOUT, enum sctp_event_timeout, timeout) +SCTP_SUBTYPE_CONSTRUCTOR(OTHER, enum sctp_event_other, other) +SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, enum sctp_event_primitive, primitive) #define sctp_chunk_is_data(a) (a->chunk_hdr->type == SCTP_CID_DATA) @@ -155,8 +153,7 @@ SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive) - sizeof(struct sctp_data_chunk))) /* Internal error codes */ -typedef enum { - +enum sctp_ierror { SCTP_IERROR_NO_ERROR = 0, SCTP_IERROR_BASE = 1000, SCTP_IERROR_NO_COOKIE, @@ -177,12 +174,12 @@ typedef enum { SCTP_IERROR_PROTO_VIOLATION, SCTP_IERROR_ERROR, SCTP_IERROR_ABORT, -} sctp_ierror_t; +}; /* SCTP state defines for internal state machine */ -typedef enum { +enum sctp_state { SCTP_STATE_CLOSED = 0, SCTP_STATE_COOKIE_WAIT = 1, @@ -193,7 +190,7 @@ typedef enum { SCTP_STATE_SHUTDOWN_RECEIVED = 6, SCTP_STATE_SHUTDOWN_ACK_SENT = 7, -} sctp_state_t; +}; #define SCTP_STATE_MAX SCTP_STATE_SHUTDOWN_ACK_SENT #define SCTP_STATE_NUM_STATES (SCTP_STATE_MAX + 1) @@ -214,19 +211,19 @@ typedef enum { * - A socket in SCTP_SS_ESTABLISHED state indicates that it has a single * association. */ -typedef enum { +enum sctp_sock_state { SCTP_SS_CLOSED = TCP_CLOSE, SCTP_SS_LISTENING = TCP_LISTEN, SCTP_SS_ESTABLISHING = TCP_SYN_SENT, SCTP_SS_ESTABLISHED = TCP_ESTABLISHED, SCTP_SS_CLOSING = TCP_CLOSE_WAIT, -} sctp_sock_state_t; +}; /* These functions map various type to printable names. */ -const char *sctp_cname(const sctp_subtype_t); /* chunk types */ -const char *sctp_oname(const sctp_subtype_t); /* other events */ -const char *sctp_tname(const sctp_subtype_t); /* timeouts */ -const char *sctp_pname(const sctp_subtype_t); /* primitives */ +const char *sctp_cname(const union sctp_subtype id); /* chunk types */ +const char *sctp_oname(const union sctp_subtype id); /* other events */ +const char *sctp_tname(const union sctp_subtype id); /* timeouts */ +const char *sctp_pname(const union sctp_subtype id); /* primitives */ /* This is a table of printable names of sctp_state_t's. */ extern const char *const sctp_state_tbl[]; @@ -312,19 +309,19 @@ enum { SCTP_MAX_GABS = 16 }; /* These return values describe the success or failure of a number of * routines which form the lower interface to SCTP_outqueue. */ -typedef enum { +enum sctp_xmit { SCTP_XMIT_OK, SCTP_XMIT_PMTU_FULL, SCTP_XMIT_RWND_FULL, SCTP_XMIT_DELAY, -} sctp_xmit_t; +}; /* These are the commands for manipulating transports. */ -typedef enum { +enum sctp_transport_cmd { SCTP_TRANSPORT_UP, SCTP_TRANSPORT_DOWN, SCTP_TRANSPORT_PF, -} sctp_transport_cmd_t; +}; /* These are the address scopes defined mainly for IPv4 addresses * based on draft of SCTP IPv4 scoping . @@ -333,20 +330,22 @@ typedef enum { * At this point, the IPv6 scopes will be mapped to these internal scopes * as much as possible. */ -typedef enum { +enum sctp_scope { SCTP_SCOPE_GLOBAL, /* IPv4 global addresses */ SCTP_SCOPE_PRIVATE, /* IPv4 private addresses */ SCTP_SCOPE_LINK, /* IPv4 link local address */ SCTP_SCOPE_LOOPBACK, /* IPv4 loopback address */ SCTP_SCOPE_UNUSABLE, /* IPv4 unusable addresses */ -} sctp_scope_t; +}; -typedef enum { +enum { SCTP_SCOPE_POLICY_DISABLE, /* Disable IPv4 address scoping */ SCTP_SCOPE_POLICY_ENABLE, /* Enable IPv4 address scoping */ SCTP_SCOPE_POLICY_PRIVATE, /* Follow draft but allow IPv4 private addresses */ SCTP_SCOPE_POLICY_LINK, /* Follow draft but allow IPv4 link local addresses */ -} sctp_scope_policy_t; +}; + +#define SCTP_SCOPE_POLICY_MAX SCTP_SCOPE_POLICY_LINK /* Based on IPv4 scoping , * SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 198.18.0.0/24, @@ -370,20 +369,20 @@ typedef enum { peer */ /* Reasons to retransmit. */ -typedef enum { +enum sctp_retransmit_reason { SCTP_RTXR_T3_RTX, SCTP_RTXR_FAST_RTX, SCTP_RTXR_PMTUD, SCTP_RTXR_T1_RTX, -} sctp_retransmit_reason_t; +}; /* Reasons to lower cwnd. */ -typedef enum { +enum sctp_lower_cwnd { SCTP_LOWER_CWND_T3_RTX, SCTP_LOWER_CWND_FAST_RTX, SCTP_LOWER_CWND_ECNE, SCTP_LOWER_CWND_INACTIVE, -} sctp_lower_cwnd_t; +}; /* SCTP-AUTH Necessary constants */ diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 980807d7506fe3ae6f5c316da091e126e619ed69..d7d8cba014697602832fe20e414b632104c9f239 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -94,8 +94,8 @@ /* * sctp/protocol.c */ -int sctp_copy_local_addr_list(struct net *, struct sctp_bind_addr *, - sctp_scope_t, gfp_t gfp, int flags); +int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *addr, + enum sctp_scope, gfp_t gfp, int flags); struct sctp_pf *sctp_get_pf_specific(sa_family_t family); int sctp_register_pf(struct sctp_pf *, sa_family_t); void sctp_addr_wq_mgmt(struct net *, struct sctp_sockaddr_entry *, int); @@ -127,7 +127,8 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *), const union sctp_addr *laddr, const union sctp_addr *paddr, void *p); int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *), - struct net *net, int pos, void *p); + int (*cb_done)(struct sctp_transport *, void *), + struct net *net, int *pos, void *p); int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p); int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc, struct sctp_info *info); @@ -469,7 +470,7 @@ _sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member) #define _sctp_walk_params(pos, chunk, end, member)\ for (pos.v = chunk->member;\ - (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <\ + (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <=\ (void *)chunk + end) &&\ pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\ ntohs(pos.p->length) >= sizeof(struct sctp_paramhdr);\ @@ -479,13 +480,13 @@ for (pos.v = chunk->member;\ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length)) #define _sctp_walk_errors(err, chunk_hdr, end)\ -for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \ +for (err = (struct sctp_errhdr *)((void *)chunk_hdr + \ sizeof(struct sctp_chunkhdr));\ - ((void *)err + offsetof(sctp_errhdr_t, length) + sizeof(err->length) <\ + ((void *)err + offsetof(struct sctp_errhdr, length) + sizeof(err->length) <=\ (void *)chunk_hdr + end) &&\ (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\ - ntohs(err->length) >= sizeof(sctp_errhdr_t); \ - err = (sctp_errhdr_t *)((void *)err + SCTP_PAD4(ntohs(err->length)))) + ntohs(err->length) >= sizeof(struct sctp_errhdr); \ + err = (struct sctp_errhdr *)((void *)err + SCTP_PAD4(ntohs(err->length)))) #define sctp_walk_fwdtsn(pos, chunk)\ _sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk)) @@ -550,7 +551,8 @@ static inline int sctp_ep_hashfn(struct net *net, __u16 lport) /* Is a socket of this style? */ #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) -static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style) +static inline int __sctp_style(const struct sock *sk, + enum sctp_socket_type style) { return sctp_sk(sk)->type == style; } @@ -558,14 +560,15 @@ static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style) /* Is the association in this state? */ #define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state)) static inline int __sctp_state(const struct sctp_association *asoc, - sctp_state_t state) + enum sctp_state state) { return asoc->state == state; } /* Is the socket in this state? */ #define sctp_sstate(sk, state) __sctp_sstate((sk), (SCTP_SS_##state)) -static inline int __sctp_sstate(const struct sock *sk, sctp_sock_state_t state) +static inline int __sctp_sstate(const struct sock *sk, + enum sctp_sock_state state) { return sk->sk_state == state; } diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 860f378333b577b5f26357c512e34893a837cfe3..2db3d3a9ce1d2cd053954bff3d66d06a9246e5c1 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -53,7 +53,7 @@ /* * Possible values for the disposition are: */ -typedef enum { +enum sctp_disposition { SCTP_DISPOSITION_DISCARD, /* No further processing. */ SCTP_DISPOSITION_CONSUME, /* Process return values normally. */ SCTP_DISPOSITION_NOMEM, /* We ran out of memory--recover. */ @@ -63,24 +63,20 @@ typedef enum { SCTP_DISPOSITION_NOT_IMPL, /* This entry is not implemented. */ SCTP_DISPOSITION_ERROR, /* This is plain old user error. */ SCTP_DISPOSITION_BUG, /* This is a bug. */ -} sctp_disposition_t; - -typedef struct { - int name; - int action; -} sctp_sm_command_t; - -typedef sctp_disposition_t (sctp_state_fn_t) (struct net *, - const struct sctp_endpoint *, - const struct sctp_association *, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *); +}; + +typedef enum sctp_disposition (sctp_state_fn_t) ( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands); typedef void (sctp_timer_event_t) (unsigned long); -typedef struct { +struct sctp_sm_table_entry { sctp_state_fn_t *fn; const char *name; -} sctp_sm_table_entry_t; +}; /* A naming convention of "sctp_sf_xxx" applies to all the state functions * currently in use. @@ -175,10 +171,11 @@ sctp_state_fn_t sctp_sf_autoclose_timer_expire; /* Prototypes for utility support functions. */ __u8 sctp_get_chunk_type(struct sctp_chunk *chunk); -const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *, - sctp_event_t, - sctp_state_t, - sctp_subtype_t); +const struct sctp_sm_table_entry *sctp_sm_lookup_event( + struct net *net, + enum sctp_event event_type, + enum sctp_state state, + union sctp_subtype event_subtype); int sctp_chunk_iif(const struct sctp_chunk *); struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *, struct sctp_chunk *, @@ -187,68 +184,69 @@ __u32 sctp_generate_verification_tag(void); void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag); /* Prototypes for chunk-building functions. */ -struct sctp_chunk *sctp_make_init(const struct sctp_association *, - const struct sctp_bind_addr *, - gfp_t gfp, int vparam_len); -struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *, - const struct sctp_chunk *, - const gfp_t gfp, - const int unkparam_len); -struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *, - const struct sctp_chunk *); -struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *, - const struct sctp_chunk *); -struct sctp_chunk *sctp_make_cwr(const struct sctp_association *, +struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, + const struct sctp_bind_addr *bp, + gfp_t gfp, int vparam_len); +struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + const gfp_t gfp, const int unkparam_len); +struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc, + const struct sctp_chunk *chunk); +struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc, + const struct sctp_chunk *chunk); +struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc, const __u32 lowest_tsn, - const struct sctp_chunk *); -struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *, - const struct sctp_sndrcvinfo *sinfo, - int len, const __u8 flags, - __u16 ssn, gfp_t gfp); -struct sctp_chunk *sctp_make_ecne(const struct sctp_association *, - const __u32); -struct sctp_chunk *sctp_make_sack(const struct sctp_association *); + const struct sctp_chunk *chunk); +struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc, + const struct sctp_sndrcvinfo *sinfo, + int len, const __u8 flags, + __u16 ssn, gfp_t gfp); +struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc, + const __u32 lowest_tsn); +struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc); struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc, const struct sctp_chunk *chunk); struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, - const struct sctp_chunk *); -struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *, - const struct sctp_chunk *); -void sctp_init_cause(struct sctp_chunk *, __be16 cause, size_t); -struct sctp_chunk *sctp_make_abort(const struct sctp_association *, - const struct sctp_chunk *, - const size_t hint); -struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *, - const struct sctp_chunk *, - __u32 tsn); -struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, - struct msghdr *, size_t msg_len); -struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, - const struct sctp_chunk *, - const __u8 *, - const size_t ); -struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *, - const struct sctp_chunk *, - struct sctp_paramhdr *); -struct sctp_chunk *sctp_make_violation_max_retrans(const struct sctp_association *, - const struct sctp_chunk *); -struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *, - const struct sctp_transport *); -struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *, - const struct sctp_chunk *, - const void *payload, - const size_t paylen); -struct sctp_chunk *sctp_make_op_error(const struct sctp_association *, - const struct sctp_chunk *chunk, - __be16 cause_code, - const void *payload, - size_t paylen, - size_t reserve_tail); - -struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, - union sctp_addr *, - struct sockaddr *, - int, __be16); + const struct sctp_chunk *chunk); +struct sctp_chunk *sctp_make_shutdown_complete( + const struct sctp_association *asoc, + const struct sctp_chunk *chunk); +void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause, size_t paylen); +struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + const size_t hint); +struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + __u32 tsn); +struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, + struct msghdr *msg, size_t msg_len); +struct sctp_chunk *sctp_make_abort_violation( + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + const __u8 *payload, + const size_t paylen); +struct sctp_chunk *sctp_make_violation_paramlen( + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + struct sctp_paramhdr *param); +struct sctp_chunk *sctp_make_violation_max_retrans( + const struct sctp_association *asoc, + const struct sctp_chunk *chunk); +struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, + const struct sctp_transport *transport); +struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + const void *payload, + const size_t paylen); +struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + __be16 cause_code, const void *payload, + size_t paylen, size_t reserve_tail); + +struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc, + union sctp_addr *laddr, + struct sockaddr *addrs, + int addrcnt, __be16 flags); struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, union sctp_addr *addr); bool sctp_verify_asconf(const struct sctp_association *asoc, @@ -262,27 +260,25 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, __u32 new_cum_tsn, size_t nstreams, struct sctp_fwdtsn_skip *skiplist); struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc); -struct sctp_chunk *sctp_make_strreset_req( - const struct sctp_association *asoc, - __u16 stream_num, __u16 *stream_list, - bool out, bool in); +struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc, + __u16 stream_num, __u16 *stream_list, + bool out, bool in); struct sctp_chunk *sctp_make_strreset_tsnreq( - const struct sctp_association *asoc); + const struct sctp_association *asoc); struct sctp_chunk *sctp_make_strreset_addstrm( - const struct sctp_association *asoc, - __u16 out, __u16 in); -struct sctp_chunk *sctp_make_strreset_resp( - const struct sctp_association *asoc, - __u32 result, __u32 sn); -struct sctp_chunk *sctp_make_strreset_tsnresp( - struct sctp_association *asoc, - __u32 result, __u32 sn, - __u32 sender_tsn, __u32 receiver_tsn); + const struct sctp_association *asoc, + __u16 out, __u16 in); +struct sctp_chunk *sctp_make_strreset_resp(const struct sctp_association *asoc, + __u32 result, __u32 sn); +struct sctp_chunk *sctp_make_strreset_tsnresp(struct sctp_association *asoc, + __u32 result, __u32 sn, + __u32 sender_tsn, + __u32 receiver_tsn); bool sctp_verify_reconf(const struct sctp_association *asoc, struct sctp_chunk *chunk, struct sctp_paramhdr **errp); -void sctp_chunk_assign_tsn(struct sctp_chunk *); -void sctp_chunk_assign_ssn(struct sctp_chunk *); +void sctp_chunk_assign_tsn(struct sctp_chunk *chunk); +void sctp_chunk_assign_ssn(struct sctp_chunk *chunk); /* Prototypes for stream-processing functions. */ struct sctp_chunk *sctp_process_strreset_outreq( @@ -312,12 +308,10 @@ struct sctp_chunk *sctp_process_strreset_resp( /* Prototypes for statetable processing. */ -int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype, - sctp_state_t state, - struct sctp_endpoint *, - struct sctp_association *asoc, - void *event_arg, - gfp_t gfp); +int sctp_do_sm(struct net *net, enum sctp_event event_type, + union sctp_subtype subtype, enum sctp_state state, + struct sctp_endpoint *ep, struct sctp_association *asoc, + void *event_arg, gfp_t gfp); /* 2nd level prototypes */ void sctp_generate_t3_rtx_event(unsigned long peer); @@ -327,11 +321,12 @@ void sctp_generate_proto_unreach_event(unsigned long peer); void sctp_ootb_pkt_free(struct sctp_packet *packet); -struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - struct sctp_chunk *chunk, - gfp_t gfp, int *err, - struct sctp_chunk **err_chk_p); +struct sctp_association *sctp_unpack_cookie( + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + struct sctp_chunk *chunk, + gfp_t gfp, int *err, + struct sctp_chunk **err_chk_p); /* 3rd level prototypes */ __u32 sctp_generate_tag(const struct sctp_endpoint *ep); diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 5ab29af8ca8acbdb80c94e4a07c23fac64a22526..0477945de1a3cf5c27348e99d9a30e02c491d1de 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -150,18 +150,18 @@ extern struct sctp_globals { #define sctp_checksum_disable (sctp_globals.checksum_disable) /* SCTP Socket type: UDP or TCP style. */ -typedef enum { +enum sctp_socket_type { SCTP_SOCKET_UDP = 0, SCTP_SOCKET_UDP_HIGH_BANDWIDTH, SCTP_SOCKET_TCP -} sctp_socket_type_t; +}; /* Per socket SCTP information. */ struct sctp_sock { /* inet_sock has to be the first member of sctp_sock */ struct inet_sock inet; /* What kind of a socket is this? */ - sctp_socket_type_t type; + enum sctp_socket_type type; /* PF_ family specific functions. */ struct sctp_pf *pf; @@ -371,12 +371,12 @@ union sctp_params { * chunk is sent and the destination transport address to which this * HEARTBEAT is sent (see Section 8.3). */ -typedef struct sctp_sender_hb_info { +struct sctp_sender_hb_info { struct sctp_paramhdr param_hdr; union sctp_addr daddr; unsigned long sent_at; __u64 hb_nonce; -} sctp_sender_hb_info_t; +}; int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, gfp_t gfp); @@ -449,7 +449,7 @@ struct sctp_af { int (*addr_valid) (union sctp_addr *, struct sctp_sock *, const struct sk_buff *); - sctp_scope_t (*scope) (union sctp_addr *); + enum sctp_scope (*scope)(union sctp_addr *); void (*inaddr_any) (union sctp_addr *, __be16); int (*is_any) (const union sctp_addr *); int (*available) (union sctp_addr *, @@ -657,8 +657,6 @@ struct sctp_sockaddr_entry { #define SCTP_ADDRESS_TICK_DELAY 500 -typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); - /* This structure holds lists of chunks as we are assembling for * transmission. */ @@ -697,10 +695,11 @@ struct sctp_packet { void sctp_packet_init(struct sctp_packet *, struct sctp_transport *, __u16 sport, __u16 dport); void sctp_packet_config(struct sctp_packet *, __u32 vtag, int); -sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, - struct sctp_chunk *, int, gfp_t); -sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, - struct sctp_chunk *); +enum sctp_xmit sctp_packet_transmit_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk, + int one_packet, gfp_t gfp); +enum sctp_xmit sctp_packet_append_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk); int sctp_packet_transmit(struct sctp_packet *, gfp_t); void sctp_packet_free(struct sctp_packet *); @@ -950,7 +949,8 @@ int sctp_transport_hold(struct sctp_transport *); void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); -void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); +void sctp_transport_lower_cwnd(struct sctp_transport *t, + enum sctp_lower_cwnd reason); void sctp_transport_burst_limited(struct sctp_transport *); void sctp_transport_burst_reset(struct sctp_transport *); unsigned long sctp_transport_timeout(struct sctp_transport *); @@ -1053,8 +1053,8 @@ int sctp_outq_sack(struct sctp_outq *, struct sctp_chunk *); int sctp_outq_is_empty(const struct sctp_outq *); void sctp_outq_restart(struct sctp_outq *); -void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, - sctp_retransmit_reason_t); +void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, + enum sctp_retransmit_reason reason); void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8); void sctp_outq_uncork(struct sctp_outq *, gfp_t gfp); void sctp_prsctp_prune(struct sctp_association *asoc, @@ -1110,7 +1110,7 @@ void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port); void sctp_bind_addr_free(struct sctp_bind_addr *); int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, - sctp_scope_t scope, gfp_t gfp, + enum sctp_scope scope, gfp_t gfp, int flags); int sctp_bind_addr_dup(struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, @@ -1134,17 +1134,18 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp, int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len, __u16 port, gfp_t gfp); -sctp_scope_t sctp_scope(const union sctp_addr *); -int sctp_in_scope(struct net *net, const union sctp_addr *addr, const sctp_scope_t scope); +enum sctp_scope sctp_scope(const union sctp_addr *addr); +int sctp_in_scope(struct net *net, const union sctp_addr *addr, + const enum sctp_scope scope); int sctp_is_any(struct sock *sk, const union sctp_addr *addr); int sctp_is_ep_boundall(struct sock *sk); /* What type of endpoint? */ -typedef enum { +enum sctp_endpoint_type { SCTP_EP_TYPE_SOCKET, SCTP_EP_TYPE_ASSOCIATION, -} sctp_endpoint_type_t; +}; /* * A common base class to bridge the implmentation view of a @@ -1168,7 +1169,7 @@ struct sctp_ep_common { int hashent; /* Runtime type information. What kind of endpoint is this? */ - sctp_endpoint_type_t type; + enum sctp_endpoint_type type; /* Some fields to help us manage this object. * refcnt - Reference count access to this object. @@ -1556,9 +1557,9 @@ struct sctp_association { * and authenticated chunk list. All that is part of the * cookie and these are just pointers to those locations */ - sctp_random_param_t *peer_random; - sctp_chunks_param_t *peer_chunks; - sctp_hmac_algo_param_t *peer_hmacs; + struct sctp_random_param *peer_random; + struct sctp_chunks_param *peer_chunks; + struct sctp_hmac_algo_param *peer_hmacs; } peer; /* State : A state variable indicating what state the @@ -1574,7 +1575,7 @@ struct sctp_association { * * State takes values from SCTP_STATE_*. */ - sctp_state_t state; + enum sctp_state state; /* Overall : The overall association error count. * Error Count : [Clear this any time I get something.] @@ -1924,8 +1925,8 @@ static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base) struct sctp_association * -sctp_association_new(const struct sctp_endpoint *, const struct sock *, - sctp_scope_t scope, gfp_t gfp); +sctp_association_new(const struct sctp_endpoint *ep, const struct sock *sk, + enum sctp_scope scope, gfp_t gfp); void sctp_association_free(struct sctp_association *); void sctp_association_put(struct sctp_association *); void sctp_association_hold(struct sctp_association *); @@ -1945,9 +1946,10 @@ void sctp_assoc_del_peer(struct sctp_association *asoc, const union sctp_addr *addr); void sctp_assoc_rm_peer(struct sctp_association *asoc, struct sctp_transport *peer); -void sctp_assoc_control_transport(struct sctp_association *, - struct sctp_transport *, - sctp_transport_cmd_t, sctp_sn_error_t); +void sctp_assoc_control_transport(struct sctp_association *asoc, + struct sctp_transport *transport, + enum sctp_transport_cmd command, + sctp_sn_error_t error); struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *, __u32); struct sctp_transport *sctp_assoc_is_match(struct sctp_association *, struct net *, @@ -1966,8 +1968,8 @@ void sctp_assoc_set_primary(struct sctp_association *, struct sctp_transport *); void sctp_assoc_del_nonprimary_peers(struct sctp_association *, struct sctp_transport *); -int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, - sctp_scope_t, gfp_t); +int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, + enum sctp_scope scope, gfp_t gfp); int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, struct sctp_cookie*, gfp_t gfp); @@ -1983,16 +1985,16 @@ int sctp_cmp_addr_exact(const union sctp_addr *ss1, struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); /* A convenience structure to parse out SCTP specific CMSGs. */ -typedef struct sctp_cmsgs { +struct sctp_cmsgs { struct sctp_initmsg *init; struct sctp_sndrcvinfo *srinfo; struct sctp_sndinfo *sinfo; -} sctp_cmsgs_t; +}; /* Structure for tracking memory objects */ -typedef struct { +struct sctp_dbg_objcnt_entry { char *label; atomic_t *counter; -} sctp_dbg_objcnt_entry_t; +}; #endif /* __sctp_structs_h__ */ diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h index 1060494ac230b80caca57f6963dca2692ae10b9d..b8c86ec1a8f5a4b3f025de849b8a6da5772b7427 100644 --- a/include/net/sctp/ulpevent.h +++ b/include/net/sctp/ulpevent.h @@ -153,8 +153,12 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event); static inline int sctp_ulpevent_type_enabled(__u16 sn_type, struct sctp_event_subscribe *mask) { + int offset = sn_type - SCTP_SN_TYPE_BASE; char *amask = (char *) mask; - return amask[sn_type - SCTP_SN_TYPE_BASE]; + + if (offset >= sizeof(struct sctp_event_subscribe)) + return 0; + return amask[offset]; } /* Given an event subscription, is this event enabled? */ diff --git a/include/net/seg6.h b/include/net/seg6.h index 4e0357517d796692540a66485c5608793ffea966..099bad59dc90150457f02e64d87b1354140ef0f3 100644 --- a/include/net/seg6.h +++ b/include/net/seg6.h @@ -56,7 +56,12 @@ extern int seg6_init(void); extern void seg6_exit(void); extern int seg6_iptunnel_init(void); extern void seg6_iptunnel_exit(void); +extern int seg6_local_init(void); +extern void seg6_local_exit(void); extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len); +extern int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, + int proto); +extern int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh); #endif diff --git a/include/net/sock.h b/include/net/sock.h index 7c0632c7e87043ca18fe5d32d7d55792f75ca6e8..a6b9a8d1a6df3f72df8f1aac0f577257fa6452d0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -294,6 +294,7 @@ struct sock_common { * @sk_stamp: time stamp of last packet received * @sk_tsflags: SO_TIMESTAMPING socket options * @sk_tskey: counter to disambiguate concurrent tstamp requests + * @sk_zckey: counter to order MSG_ZEROCOPY notifications * @sk_socket: Identd and reporting IO signals * @sk_user_data: RPC layer private data * @sk_frag: cached page frag @@ -462,6 +463,7 @@ struct sock { u16 sk_tsflags; u8 sk_shutdown; u32 sk_tskey; + atomic_t sk_zckey; struct socket *sk_socket; void *sk_user_data; #ifdef CONFIG_SECURITY @@ -507,9 +509,7 @@ int sk_set_peek_off(struct sock *sk, int val); static inline int sk_peek_offset(struct sock *sk, int flags) { if (unlikely(flags & MSG_PEEK)) { - s32 off = READ_ONCE(sk->sk_peek_off); - if (off >= 0) - return off; + return READ_ONCE(sk->sk_peek_off); } return 0; @@ -856,7 +856,7 @@ void sk_stream_write_space(struct sock *sk); static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) { /* dont let skb dst not refcounted, we are going to leave rcu lock */ - skb_dst_force_safe(skb); + skb_dst_force(skb); if (!sk->sk_backlog.tail) sk->sk_backlog.head = skb; @@ -1531,6 +1531,8 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, gfp_t priority); void __sock_wfree(struct sk_buff *skb); void sock_wfree(struct sk_buff *skb); +struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size, + gfp_t priority); void skb_orphan_partial(struct sk_buff *skb); void sock_rfree(struct sk_buff *skb); void sock_efree(struct sk_buff *skb); @@ -1582,11 +1584,14 @@ int sock_no_shutdown(struct socket *, int); int sock_no_getsockopt(struct socket *, int , int, char __user *, int __user *); int sock_no_setsockopt(struct socket *, int, int, char __user *, unsigned int); int sock_no_sendmsg(struct socket *, struct msghdr *, size_t); +int sock_no_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len); int sock_no_recvmsg(struct socket *, struct msghdr *, size_t, int); int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma); ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); +ssize_t sock_no_sendpage_locked(struct sock *sk, struct page *page, + int offset, size_t size, int flags); /* * Functions to fill in entries in struct proto_ops when a protocol @@ -2363,6 +2368,16 @@ bool sk_net_capable(const struct sock *sk, int cap); void sk_get_meminfo(const struct sock *sk, u32 *meminfo); +/* Take into consideration the size of the struct sk_buff overhead in the + * determination of these values, since that is non-constant across + * platforms. This makes socket queueing behavior and performance + * not depend upon such differences. + */ +#define _SK_MEM_PACKETS 256 +#define _SK_MEM_OVERHEAD SKB_TRUESIZE(256) +#define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) +#define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) + extern __u32 sysctl_wmem_max; extern __u32 sysctl_rmem_max; diff --git a/include/net/strparser.h b/include/net/strparser.h index 0c28ad97c52f17509bc0e825ca5c7d5dfbb82a69..7dc131d62ad5c3a5a8cb67c91d1f3d86e7207410 100644 --- a/include/net/strparser.h +++ b/include/net/strparser.h @@ -18,26 +18,26 @@ #define STRP_STATS_INCR(stat) ((stat)++) struct strp_stats { - unsigned long long rx_msgs; - unsigned long long rx_bytes; - unsigned int rx_mem_fail; - unsigned int rx_need_more_hdr; - unsigned int rx_msg_too_big; - unsigned int rx_msg_timeouts; - unsigned int rx_bad_hdr_len; + unsigned long long msgs; + unsigned long long bytes; + unsigned int mem_fail; + unsigned int need_more_hdr; + unsigned int msg_too_big; + unsigned int msg_timeouts; + unsigned int bad_hdr_len; }; struct strp_aggr_stats { - unsigned long long rx_msgs; - unsigned long long rx_bytes; - unsigned int rx_mem_fail; - unsigned int rx_need_more_hdr; - unsigned int rx_msg_too_big; - unsigned int rx_msg_timeouts; - unsigned int rx_bad_hdr_len; - unsigned int rx_aborts; - unsigned int rx_interrupted; - unsigned int rx_unrecov_intr; + unsigned long long msgs; + unsigned long long bytes; + unsigned int mem_fail; + unsigned int need_more_hdr; + unsigned int msg_too_big; + unsigned int msg_timeouts; + unsigned int bad_hdr_len; + unsigned int aborts; + unsigned int interrupted; + unsigned int unrecov_intr; }; struct strparser; @@ -48,16 +48,18 @@ struct strp_callbacks { void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); int (*read_sock_done)(struct strparser *strp, int err); void (*abort_parser)(struct strparser *strp, int err); + void (*lock)(struct strparser *strp); + void (*unlock)(struct strparser *strp); }; -struct strp_rx_msg { +struct strp_msg { int full_len; int offset; }; -static inline struct strp_rx_msg *strp_rx_msg(struct sk_buff *skb) +static inline struct strp_msg *strp_msg(struct sk_buff *skb) { - return (struct strp_rx_msg *)((void *)skb->cb + + return (struct strp_msg *)((void *)skb->cb + offsetof(struct qdisc_skb_cb, data)); } @@ -65,18 +67,18 @@ static inline struct strp_rx_msg *strp_rx_msg(struct sk_buff *skb) struct strparser { struct sock *sk; - u32 rx_stopped : 1; - u32 rx_paused : 1; - u32 rx_aborted : 1; - u32 rx_interrupted : 1; - u32 rx_unrecov_intr : 1; - - struct sk_buff **rx_skb_nextp; - struct timer_list rx_msg_timer; - struct sk_buff *rx_skb_head; - unsigned int rx_need_bytes; - struct delayed_work rx_delayed_work; - struct work_struct rx_work; + u32 stopped : 1; + u32 paused : 1; + u32 aborted : 1; + u32 interrupted : 1; + u32 unrecov_intr : 1; + + struct sk_buff **skb_nextp; + struct timer_list msg_timer; + struct sk_buff *skb_head; + unsigned int need_bytes; + struct delayed_work delayed_work; + struct work_struct work; struct strp_stats stats; struct strp_callbacks cb; }; @@ -84,7 +86,7 @@ struct strparser { /* Must be called with lock held for attached socket */ static inline void strp_pause(struct strparser *strp) { - strp->rx_paused = 1; + strp->paused = 1; } /* May be called without holding lock for attached socket */ @@ -97,37 +99,37 @@ static inline void save_strp_stats(struct strparser *strp, #define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += \ strp->stats._stat) - SAVE_PSOCK_STATS(rx_msgs); - SAVE_PSOCK_STATS(rx_bytes); - SAVE_PSOCK_STATS(rx_mem_fail); - SAVE_PSOCK_STATS(rx_need_more_hdr); - SAVE_PSOCK_STATS(rx_msg_too_big); - SAVE_PSOCK_STATS(rx_msg_timeouts); - SAVE_PSOCK_STATS(rx_bad_hdr_len); + SAVE_PSOCK_STATS(msgs); + SAVE_PSOCK_STATS(bytes); + SAVE_PSOCK_STATS(mem_fail); + SAVE_PSOCK_STATS(need_more_hdr); + SAVE_PSOCK_STATS(msg_too_big); + SAVE_PSOCK_STATS(msg_timeouts); + SAVE_PSOCK_STATS(bad_hdr_len); #undef SAVE_PSOCK_STATS - if (strp->rx_aborted) - agg_stats->rx_aborts++; - if (strp->rx_interrupted) - agg_stats->rx_interrupted++; - if (strp->rx_unrecov_intr) - agg_stats->rx_unrecov_intr++; + if (strp->aborted) + agg_stats->aborts++; + if (strp->interrupted) + agg_stats->interrupted++; + if (strp->unrecov_intr) + agg_stats->unrecov_intr++; } static inline void aggregate_strp_stats(struct strp_aggr_stats *stats, struct strp_aggr_stats *agg_stats) { #define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += stats->_stat) - SAVE_PSOCK_STATS(rx_msgs); - SAVE_PSOCK_STATS(rx_bytes); - SAVE_PSOCK_STATS(rx_mem_fail); - SAVE_PSOCK_STATS(rx_need_more_hdr); - SAVE_PSOCK_STATS(rx_msg_too_big); - SAVE_PSOCK_STATS(rx_msg_timeouts); - SAVE_PSOCK_STATS(rx_bad_hdr_len); - SAVE_PSOCK_STATS(rx_aborts); - SAVE_PSOCK_STATS(rx_interrupted); - SAVE_PSOCK_STATS(rx_unrecov_intr); + SAVE_PSOCK_STATS(msgs); + SAVE_PSOCK_STATS(bytes); + SAVE_PSOCK_STATS(mem_fail); + SAVE_PSOCK_STATS(need_more_hdr); + SAVE_PSOCK_STATS(msg_too_big); + SAVE_PSOCK_STATS(msg_timeouts); + SAVE_PSOCK_STATS(bad_hdr_len); + SAVE_PSOCK_STATS(aborts); + SAVE_PSOCK_STATS(interrupted); + SAVE_PSOCK_STATS(unrecov_intr); #undef SAVE_PSOCK_STATS } @@ -135,8 +137,11 @@ static inline void aggregate_strp_stats(struct strp_aggr_stats *stats, void strp_done(struct strparser *strp); void strp_stop(struct strparser *strp); void strp_check_rcv(struct strparser *strp); -int strp_init(struct strparser *strp, struct sock *csk, - struct strp_callbacks *cb); +int strp_init(struct strparser *strp, struct sock *sk, + const struct strp_callbacks *cb); void strp_data_ready(struct strparser *strp); +int strp_process(struct strparser *strp, struct sk_buff *orig_skb, + unsigned int orig_offset, size_t orig_len, + size_t max_msg_size, long timeo); #endif /* __NET_STRPARSER_H_ */ diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 8ae9e3b6392e3c74ce93a5cf089fea1749f81619..d767b799188717b7b2175466950762dcd08380a3 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -74,7 +74,6 @@ struct switchdev_attr { enum switchdev_obj_id { SWITCHDEV_OBJ_ID_UNDEFINED, SWITCHDEV_OBJ_ID_PORT_VLAN, - SWITCHDEV_OBJ_ID_PORT_FDB, SWITCHDEV_OBJ_ID_PORT_MDB, }; @@ -97,17 +96,6 @@ struct switchdev_obj_port_vlan { #define SWITCHDEV_OBJ_PORT_VLAN(obj) \ container_of(obj, struct switchdev_obj_port_vlan, obj) -/* SWITCHDEV_OBJ_ID_PORT_FDB */ -struct switchdev_obj_port_fdb { - struct switchdev_obj obj; - unsigned char addr[ETH_ALEN]; - u16 vid; - u16 ndm_state; -}; - -#define SWITCHDEV_OBJ_PORT_FDB(obj) \ - container_of(obj, struct switchdev_obj_port_fdb, obj) - /* SWITCHDEV_OBJ_ID_PORT_MDB */ struct switchdev_obj_port_mdb { struct switchdev_obj obj; @@ -135,8 +123,6 @@ typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj); * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*). * * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*). - * - * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*). */ struct switchdev_ops { int (*switchdev_port_attr_get)(struct net_device *dev, @@ -149,9 +135,6 @@ struct switchdev_ops { struct switchdev_trans *trans); int (*switchdev_port_obj_del)(struct net_device *dev, const struct switchdev_obj *obj); - int (*switchdev_port_obj_dump)(struct net_device *dev, - struct switchdev_obj *obj, - switchdev_obj_dump_cb_t *cb); }; enum switchdev_notifier_type { @@ -189,28 +172,10 @@ int switchdev_port_obj_add(struct net_device *dev, const struct switchdev_obj *obj); int switchdev_port_obj_del(struct net_device *dev, const struct switchdev_obj *obj); -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, - switchdev_obj_dump_cb_t *cb); int register_switchdev_notifier(struct notifier_block *nb); int unregister_switchdev_notifier(struct notifier_block *nb); int call_switchdev_notifiers(unsigned long val, struct net_device *dev, struct switchdev_notifier_info *info); -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, - struct net_device *dev, u32 filter_mask, - int nlflags); -int switchdev_port_bridge_setlink(struct net_device *dev, - struct nlmsghdr *nlh, u16 flags); -int switchdev_port_bridge_dellink(struct net_device *dev, - struct nlmsghdr *nlh, u16 flags); -int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, const unsigned char *addr, - u16 vid, u16 nlm_flags); -int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, const unsigned char *addr, - u16 vid); -int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct net_device *dev, - struct net_device *filter_dev, int *idx); void switchdev_port_fwd_mark_set(struct net_device *dev, struct net_device *group_dev, bool joining); @@ -249,13 +214,6 @@ static inline int switchdev_port_obj_del(struct net_device *dev, return -EOPNOTSUPP; } -static inline int switchdev_port_obj_dump(struct net_device *dev, - const struct switchdev_obj *obj, - switchdev_obj_dump_cb_t *cb) -{ - return -EOPNOTSUPP; -} - static inline int register_switchdev_notifier(struct notifier_block *nb) { return 0; @@ -273,51 +231,6 @@ static inline int call_switchdev_notifiers(unsigned long val, return NOTIFY_DONE; } -static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, - u32 seq, struct net_device *dev, - u32 filter_mask, int nlflags) -{ - return -EOPNOTSUPP; -} - -static inline int switchdev_port_bridge_setlink(struct net_device *dev, - struct nlmsghdr *nlh, - u16 flags) -{ - return -EOPNOTSUPP; -} - -static inline int switchdev_port_bridge_dellink(struct net_device *dev, - struct nlmsghdr *nlh, - u16 flags) -{ - return -EOPNOTSUPP; -} - -static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr, - u16 vid, u16 nlm_flags) -{ - return -EOPNOTSUPP; -} - -static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, - const unsigned char *addr, u16 vid) -{ - return -EOPNOTSUPP; -} - -static inline int switchdev_port_fdb_dump(struct sk_buff *skb, - struct netlink_callback *cb, - struct net_device *dev, - struct net_device *filter_dev, - int *idx) -{ - return *idx; -} - static inline bool switchdev_port_same_parent_id(struct net_device *a, struct net_device *b) { diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h index d576374c4d6fb5a3bf3b52cb85c8ae717d7cb8fb..41afe1ce7b16f9b5841c6010c519470f775e9f35 100644 --- a/include/net/tc_act/tc_gact.h +++ b/include/net/tc_act/tc_gact.h @@ -15,7 +15,8 @@ struct tcf_gact { }; #define to_gact(a) ((struct tcf_gact *)a) -static inline bool __is_tcf_gact_act(const struct tc_action *a, int act) +static inline bool __is_tcf_gact_act(const struct tc_action *a, int act, + bool is_ext) { #ifdef CONFIG_NET_CLS_ACT struct tcf_gact *gact; @@ -24,7 +25,8 @@ static inline bool __is_tcf_gact_act(const struct tc_action *a, int act) return false; gact = to_gact(a); - if (gact->tcf_action == act) + if ((!is_ext && gact->tcf_action == act) || + (is_ext && TC_ACT_EXT_CMP(gact->tcf_action, act))) return true; #endif @@ -33,12 +35,22 @@ static inline bool __is_tcf_gact_act(const struct tc_action *a, int act) static inline bool is_tcf_gact_shot(const struct tc_action *a) { - return __is_tcf_gact_act(a, TC_ACT_SHOT); + return __is_tcf_gact_act(a, TC_ACT_SHOT, false); } static inline bool is_tcf_gact_trap(const struct tc_action *a) { - return __is_tcf_gact_act(a, TC_ACT_TRAP); + return __is_tcf_gact_act(a, TC_ACT_TRAP, false); +} + +static inline bool is_tcf_gact_goto_chain(const struct tc_action *a) +{ + return __is_tcf_gact_act(a, TC_ACT_GOTO_CHAIN, true); +} + +static inline u32 tcf_gact_goto_chain_index(const struct tc_action *a) +{ + return a->goto_chain->index; } #endif /* __NET_TC_GACT_H */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 70483296157f87acdf5acd5e96eaa910119ba220..89974c5286d8ae4db63def6822ae5b0dc93cddf9 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -139,6 +139,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #endif #define TCP_RTO_MAX ((unsigned)(120*HZ)) #define TCP_RTO_MIN ((unsigned)(HZ/5)) +#define TCP_TIMEOUT_MIN (2U) /* Min timeout for TCP timers in jiffies */ #define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC6298 2.1 initial RTO value */ #define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now * used as a fallback RTO for the @@ -150,8 +151,6 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes * for local resources. */ -#define TCP_REO_TIMEOUT_MIN (2000) /* Min RACK reordering timeout in usec */ - #define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ #define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ #define TCP_KEEPALIVE_INTVL (75*HZ) @@ -257,7 +256,6 @@ extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; extern int sysctl_tcp_adv_win_scale; extern int sysctl_tcp_frto; -extern int sysctl_tcp_low_latency; extern int sysctl_tcp_nometrics_save; extern int sysctl_tcp_moderate_rcvbuf; extern int sysctl_tcp_tso_win_divisor; @@ -347,13 +345,16 @@ void tcp_v4_err(struct sk_buff *skb, u32); void tcp_shutdown(struct sock *sk, int how); -void tcp_v4_early_demux(struct sk_buff *skb); +int tcp_v4_early_demux(struct sk_buff *skb); int tcp_v4_rcv(struct sk_buff *skb); int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw); int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size); +int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size); int tcp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags); +int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, + size_t size, int flags); ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, size_t size, int flags); void tcp_release_cb(struct sock *sk); @@ -363,7 +364,7 @@ void tcp_delack_timer_handler(struct sock *sk); int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb); void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, - const struct tcphdr *th, unsigned int len); + const struct tcphdr *th); void tcp_rcv_space_adjust(struct sock *sk); int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp); void tcp_twsk_destructor(struct sock *sk); @@ -543,7 +544,6 @@ u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now, int min_tso_segs); void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, int nonagle); -bool tcp_may_send_now(struct sock *sk); int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs); int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs); void tcp_retransmit_timer(struct sock *sk); @@ -796,6 +796,12 @@ struct tcp_skb_cb { u16 tcp_gso_segs; u16 tcp_gso_size; }; + + /* Used to stash the receive timestamp while this skb is in the + * out of order queue, as skb->tstamp is overwritten by the + * rbnode. + */ + ktime_t swtstamp; }; __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ @@ -812,7 +818,8 @@ struct tcp_skb_cb { __u8 ip_dsfield; /* IPv4 tos or IPv6 dsfield */ __u8 txstamp_ack:1, /* Record TX timestamp for ack? */ eor:1, /* Is skb MSG_EOR marked? */ - unused:6; + has_rxtstamp:1, /* SKB has a RX timestamp */ + unused:5; __u32 ack_seq; /* Sequence number ACK'd */ union { struct { @@ -849,6 +856,16 @@ static inline int tcp_v6_iif(const struct sk_buff *skb) return l3_slave ? skb->skb_iif : TCP_SKB_CB(skb)->header.h6.iif; } + +/* TCP_SKB_CB reference means this can not be used from early demux */ +static inline int tcp_v6_sdif(const struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) + if (skb && ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags)) + return TCP_SKB_CB(skb)->header.h6.iif; +#endif + return 0; +} #endif /* TCP_SKB_CB reference means this can not be used from early demux */ @@ -862,6 +879,16 @@ static inline bool inet_exact_dif_match(struct net *net, struct sk_buff *skb) return false; } +/* TCP_SKB_CB reference means this can not be used from early demux */ +static inline int tcp_v4_sdif(struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) + if (skb && ipv4_l3mdev_skb(TCP_SKB_CB(skb)->header.h4.flags)) + return TCP_SKB_CB(skb)->header.h4.iif; +#endif + return 0; +} + /* Due to TSO, an SKB can be composed of multiple actual * packets. To keep these tracked properly, we use this. */ @@ -1004,9 +1031,7 @@ void tcp_get_default_congestion_control(char *name); void tcp_get_available_congestion_control(char *buf, size_t len); void tcp_get_allowed_congestion_control(char *buf, size_t len); int tcp_set_allowed_congestion_control(char *allowed); -int tcp_set_congestion_control(struct sock *sk, const char *name, bool load); -void tcp_reinit_congestion_control(struct sock *sk, - const struct tcp_congestion_ops *ca); +int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, bool reinit); u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); @@ -1245,17 +1270,6 @@ static inline bool tcp_checksum_complete(struct sk_buff *skb) __tcp_checksum_complete(skb); } -/* Prequeue for VJ style copy to user, combined with checksumming. */ - -static inline void tcp_prequeue_init(struct tcp_sock *tp) -{ - tp->ucopy.task = NULL; - tp->ucopy.len = 0; - tp->ucopy.memory = 0; - skb_queue_head_init(&tp->ucopy.prequeue); -} - -bool tcp_prequeue(struct sock *sk, struct sk_buff *skb); bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb); int tcp_filter(struct sock *sk, struct sk_buff *skb); @@ -1547,8 +1561,7 @@ int tcp_fastopen_reset_cipher(void *key, unsigned int len); void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb); struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, struct request_sock *req, - struct tcp_fastopen_cookie *foc, - struct dst_entry *dst); + struct tcp_fastopen_cookie *foc); void tcp_fastopen_init_key_once(bool publish); bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, struct tcp_fastopen_cookie *cookie); @@ -1916,10 +1929,21 @@ extern void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq, u64 xmit_time); extern void tcp_rack_reo_timeout(struct sock *sk); +/* At how many usecs into the future should the RTO fire? */ +static inline s64 tcp_rto_delta_us(const struct sock *sk) +{ + const struct sk_buff *skb = tcp_write_queue_head(sk); + u32 rto = inet_csk(sk)->icsk_rto; + u64 rto_time_stamp_us = skb->skb_mstamp + jiffies_to_usecs(rto); + + return rto_time_stamp_us - tcp_sk(sk)->tcp_mstamp; +} + /* * Save and compile IPv4 options, return a pointer to it */ -static inline struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) +static inline struct ip_options_rcu *tcp_v4_save_options(struct net *net, + struct sk_buff *skb) { const struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; struct ip_options_rcu *dopt = NULL; @@ -1928,7 +1952,7 @@ static inline struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) int opt_size = sizeof(*dopt) + opt->optlen; dopt = kmalloc(opt_size, GFP_ATOMIC); - if (dopt && __ip_options_echo(&dopt->opt, skb, opt)) { + if (dopt && __ip_options_echo(net, &dopt->opt, skb, opt)) { kfree(dopt); dopt = NULL; } diff --git a/include/net/tso.h b/include/net/tso.h index b7be852bfe9d5719aa86df7d788224a64fbce775..9a56c39e6d0a4b3f5315026970af025bd7069888 100644 --- a/include/net/tso.h +++ b/include/net/tso.h @@ -3,6 +3,8 @@ #include +#define TSO_HEADER_SIZE 128 + struct tso_t { int next_frag_idx; void *data; diff --git a/include/net/tun_proto.h b/include/net/tun_proto.h new file mode 100644 index 0000000000000000000000000000000000000000..2ea3deba4c99ce7fe5dece97c5d1e7972f5d1de1 --- /dev/null +++ b/include/net/tun_proto.h @@ -0,0 +1,49 @@ +#ifndef __NET_TUN_PROTO_H +#define __NET_TUN_PROTO_H + +#include + +/* One byte protocol values as defined by VXLAN-GPE and NSH. These will + * hopefully get a shared IANA registry. + */ +#define TUN_P_IPV4 0x01 +#define TUN_P_IPV6 0x02 +#define TUN_P_ETHERNET 0x03 +#define TUN_P_NSH 0x04 +#define TUN_P_MPLS_UC 0x05 + +static inline __be16 tun_p_to_eth_p(u8 proto) +{ + switch (proto) { + case TUN_P_IPV4: + return htons(ETH_P_IP); + case TUN_P_IPV6: + return htons(ETH_P_IPV6); + case TUN_P_ETHERNET: + return htons(ETH_P_TEB); + case TUN_P_NSH: + return htons(ETH_P_NSH); + case TUN_P_MPLS_UC: + return htons(ETH_P_MPLS_UC); + } + return 0; +} + +static inline u8 tun_p_from_eth_p(__be16 proto) +{ + switch (proto) { + case htons(ETH_P_IP): + return TUN_P_IPV4; + case htons(ETH_P_IPV6): + return TUN_P_IPV6; + case htons(ETH_P_TEB): + return TUN_P_ETHERNET; + case htons(ETH_P_NSH): + return TUN_P_NSH; + case htons(ETH_P_MPLS_UC): + return TUN_P_MPLS_UC; + } + return 0; +} + +#endif diff --git a/include/net/udp.h b/include/net/udp.h index 972ce4baab6b2a4b0539624d1a671c632d77514c..6c759c8594e25c7f9f79dc6bf76325c39e705f94 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -259,7 +259,8 @@ static inline struct sk_buff *skb_recv_udp(struct sock *sk, unsigned int flags, return __skb_recv_udp(sk, flags, noblock, &peeked, &off, err); } -void udp_v4_early_demux(struct sk_buff *skb); +int udp_v4_early_demux(struct sk_buff *skb); +bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst); int udp_get_port(struct sock *sk, unsigned short snum, int (*saddr_cmp)(const struct sock *, const struct sock *)); @@ -286,7 +287,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, __be32 daddr, __be16 dport, int dif); struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, - __be32 daddr, __be16 dport, int dif, + __be32 daddr, __be16 dport, int dif, int sdif, struct udp_table *tbl, struct sk_buff *skb); struct sock *udp4_lib_lookup_skb(struct sk_buff *skb, __be16 sport, __be16 dport); @@ -297,7 +298,7 @@ struct sock *udp6_lib_lookup(struct net *net, struct sock *__udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, const struct in6_addr *daddr, __be16 dport, - int dif, struct udp_table *tbl, + int dif, int sdif, struct udp_table *tbl, struct sk_buff *skb); struct sock *udp6_lib_lookup_skb(struct sk_buff *skb, __be16 sport, __be16 dport); @@ -305,33 +306,44 @@ struct sock *udp6_lib_lookup_skb(struct sk_buff *skb, /* UDP uses skb->dev_scratch to cache as much information as possible and avoid * possibly multiple cache miss on dequeue() */ -#if BITS_PER_LONG == 64 - -/* truesize, len and the bit needed to compute skb_csum_unnecessary will be on - * cold cache lines at recvmsg time. - * skb->len can be stored on 16 bits since the udp header has been already - * validated and pulled. - */ struct udp_dev_scratch { - u32 truesize; + /* skb->truesize and the stateless bit are embedded in a single field; + * do not use a bitfield since the compiler emits better/smaller code + * this way + */ + u32 _tsize_state; + +#if BITS_PER_LONG == 64 + /* len and the bit needed to compute skb_csum_unnecessary + * will be on cold cache lines at recvmsg time. + * skb->len can be stored on 16 bits since the udp header has been + * already validated and pulled. + */ u16 len; bool is_linear; bool csum_unnecessary; +#endif }; +static inline struct udp_dev_scratch *udp_skb_scratch(struct sk_buff *skb) +{ + return (struct udp_dev_scratch *)&skb->dev_scratch; +} + +#if BITS_PER_LONG == 64 static inline unsigned int udp_skb_len(struct sk_buff *skb) { - return ((struct udp_dev_scratch *)&skb->dev_scratch)->len; + return udp_skb_scratch(skb)->len; } static inline bool udp_skb_csum_unnecessary(struct sk_buff *skb) { - return ((struct udp_dev_scratch *)&skb->dev_scratch)->csum_unnecessary; + return udp_skb_scratch(skb)->csum_unnecessary; } static inline bool udp_skb_is_linear(struct sk_buff *skb) { - return ((struct udp_dev_scratch *)&skb->dev_scratch)->is_linear; + return udp_skb_scratch(skb)->is_linear; } #else @@ -354,12 +366,13 @@ static inline bool udp_skb_is_linear(struct sk_buff *skb) static inline int copy_linear_skb(struct sk_buff *skb, int len, int off, struct iov_iter *to) { - int n, copy = len - off; + int n; - n = copy_to_iter(skb->data + off, copy, to); - if (n == copy) + n = copy_to_iter(skb->data + off, len, to); + if (n == len) return 0; + iov_iter_revert(to, n); return -EFAULT; } diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h index 02c5be0374517da8d6912e2a727606a0e2b8b27d..10cce0dd4450353410e55d2b96ffeab6921b1759 100644 --- a/include/net/udp_tunnel.h +++ b/include/net/udp_tunnel.h @@ -115,6 +115,8 @@ struct udp_tunnel_info { /* Notify network devices of offloadable types */ void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock, unsigned short type); +void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock, + unsigned short type); void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type); void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type); @@ -124,6 +126,12 @@ static inline void udp_tunnel_get_rx_info(struct net_device *dev) call_netdevice_notifiers(NETDEV_UDP_TUNNEL_PUSH_INFO, dev); } +static inline void udp_tunnel_drop_rx_info(struct net_device *dev) +{ + ASSERT_RTNL(); + call_netdevice_notifiers(NETDEV_UDP_TUNNEL_DROP_INFO, dev); +} + /* Transmit the skb using UDP encapsulation. */ void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, __u8 ttl, diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 3f430e38ab820b11503104eac8cebe96387fa2a2..4e3876dde295c8dbb48d8c6483624765037acfa4 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -168,12 +168,6 @@ reserved_flags2:2; #define VXLAN_GPE_USED_BITS (VXLAN_HF_VER | VXLAN_HF_NP | VXLAN_HF_OAM | \ cpu_to_be32(0xff)) -/* VXLAN-GPE header Next Protocol. */ -#define VXLAN_GPE_NP_IPV4 0x01 -#define VXLAN_GPE_NP_IPV6 0x02 -#define VXLAN_GPE_NP_ETHERNET 0x03 -#define VXLAN_GPE_NP_NSH 0x04 - struct vxlan_metadata { u32 gbp; }; diff --git a/include/net/xfrm.h b/include/net/xfrm.h index c0916ab18d3288033500e7a4953ef481176adaa0..f002a2c5e33c2c6f5bc8998c73280023e856a51d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -43,6 +43,8 @@ MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap)) #define MODULE_ALIAS_XFRM_TYPE(family, proto) \ MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto)) +#define MODULE_ALIAS_XFRM_OFFLOAD_TYPE(family, proto) \ + MODULE_ALIAS("xfrm-offload-" __stringify(family) "-" __stringify(proto)) #ifdef CONFIG_XFRM_STATISTICS #define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field) @@ -163,6 +165,7 @@ struct xfrm_state { int header_len; int trailer_len; u32 extra_flags; + u32 output_mark; } props; struct xfrm_lifetime_cfg lft; @@ -296,10 +299,12 @@ struct xfrm_policy_afinfo { struct dst_entry *(*dst_lookup)(struct net *net, int tos, int oif, const xfrm_address_t *saddr, - const xfrm_address_t *daddr); + const xfrm_address_t *daddr, + u32 mark); int (*get_saddr)(struct net *net, int oif, xfrm_address_t *saddr, - xfrm_address_t *daddr); + xfrm_address_t *daddr, + u32 mark); void (*decode_session)(struct sk_buff *skb, struct flowi *fl, int reverse); @@ -317,6 +322,7 @@ int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int fam void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo); void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c); +void xfrm_policy_cache_flush(void); void km_state_notify(struct xfrm_state *x, const struct km_event *c); struct xfrm_tmpl; @@ -563,7 +569,6 @@ struct xfrm_policy { refcount_t refcnt; struct timer_list timer; - struct flow_cache_object flo; atomic_t genid; u32 priority; u32 index; @@ -978,7 +983,6 @@ struct xfrm_dst { struct rt6_info rt6; } u; struct dst_entry *route; - struct flow_cache_object flo; struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; int num_pols, num_xfrms; u32 xfrm_genid; @@ -1015,6 +1019,7 @@ struct xfrm_offload { #define CRYPTO_FALLBACK 8 #define XFRM_GSO_SEGMENT 16 #define XFRM_GRO 32 +#define XFRM_ESP_NO_TRAILER 64 __u32 status; #define CRYPTO_SUCCESS 1 @@ -1226,9 +1231,6 @@ static inline void xfrm_sk_free_policy(struct sock *sk) } } -void xfrm_garbage_collect(struct net *net); -void xfrm_garbage_collect_deferred(struct net *net); - #else static inline void xfrm_sk_free_policy(struct sock *sk) {} @@ -1263,9 +1265,6 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir, { return 1; } -static inline void xfrm_garbage_collect(struct net *net) -{ -} #endif static __inline__ @@ -1565,7 +1564,7 @@ void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq); int xfrm_init_replay(struct xfrm_state *x); int xfrm_state_mtu(struct xfrm_state *x, int mtu); -int __xfrm_init_state(struct xfrm_state *x, bool init_replay); +int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload); int xfrm_init_state(struct xfrm_state *x); int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb); int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type); @@ -1645,7 +1644,7 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif, const xfrm_address_t *saddr, const xfrm_address_t *daddr, - int family); + int family, u32 mark); struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp); @@ -1863,6 +1862,20 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo); bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); +static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) +{ + struct xfrm_state *x = dst->xfrm; + + if (!x || !x->type_offload) + return false; + + if (x->xso.offload_handle && (x->xso.dev == dst->path->dev) && + !dst->child->xfrm) + return true; + + return false; +} + static inline void xfrm_dev_state_delete(struct xfrm_state *x) { struct xfrm_state_offload *xso = &x->xso; @@ -1905,6 +1918,11 @@ static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x { return false; } + +static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) +{ + return false; +} #endif static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m) diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index b73a14edc85e3570e2394fbad23234f689f3a956..ec5008cf5d51d20c2a8813565da2adf4e2feb118 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -172,7 +172,8 @@ static inline int rdma_ip2gid(struct sockaddr *addr, union ib_gid *gid) (struct in6_addr *)gid); break; case AF_INET6: - memcpy(gid->raw, &((struct sockaddr_in6 *)addr)->sin6_addr, 16); + *(struct in6_addr *)&gid->raw = + ((struct sockaddr_in6 *)addr)->sin6_addr; break; default: return -EINVAL; @@ -304,7 +305,13 @@ static inline void rdma_get_ll_mac(struct in6_addr *addr, u8 *mac) static inline int rdma_is_multicast_addr(struct in6_addr *addr) { - return addr->s6_addr[0] == 0xff; + u32 ipv4_addr; + + if (addr->s6_addr[0] == 0xff) + return 1; + + memcpy(&ipv4_addr, addr->s6_addr + 12, 4); + return (ipv6_addr_v4mapped(addr) && ipv4_is_multicast(ipv4_addr)); } static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac) diff --git a/include/rdma/ib_hdrs.h b/include/rdma/ib_hdrs.h index 5519f31f043a45b086e098407c4a15a2a7d02ca4..c124d515f7d545951dfc105d95ba1794a987e2bf 100644 --- a/include/rdma/ib_hdrs.h +++ b/include/rdma/ib_hdrs.h @@ -193,8 +193,12 @@ static inline void put_ib_ateth_compare(u64 val, struct ib_atomic_eth *ateth) #define IB_LNH_MASK 3 #define IB_SC_MASK 0xf #define IB_SC_SHIFT 12 +#define IB_SC5_MASK 0x10 #define IB_SL_MASK 0xf #define IB_SL_SHIFT 4 +#define IB_SL_SHIFT 4 +#define IB_LVER_MASK 0xf +#define IB_LVER_SHIFT 8 static inline u8 ib_get_lnh(struct ib_header *hdr) { @@ -206,6 +210,11 @@ static inline u8 ib_get_sc(struct ib_header *hdr) return ((be16_to_cpu(hdr->lrh[0]) >> IB_SC_SHIFT) & IB_SC_MASK); } +static inline bool ib_is_sc5(u16 sc5) +{ + return !!(sc5 & IB_SC5_MASK); +} + static inline u8 ib_get_sl(struct ib_header *hdr) { return ((be16_to_cpu(hdr->lrh[0]) >> IB_SL_SHIFT) & IB_SL_MASK); @@ -221,6 +230,27 @@ static inline u16 ib_get_slid(struct ib_header *hdr) return (be16_to_cpu(hdr->lrh[3])); } +static inline u8 ib_get_lver(struct ib_header *hdr) +{ + return (u8)((be16_to_cpu(hdr->lrh[0]) >> IB_LVER_SHIFT) & + IB_LVER_MASK); +} + +static inline u16 ib_get_len(struct ib_header *hdr) +{ + return (u16)(be16_to_cpu(hdr->lrh[2])); +} + +static inline u32 ib_get_qkey(struct ib_other_headers *ohdr) +{ + return be32_to_cpu(ohdr->u.ud.deth[0]); +} + +static inline u32 ib_get_sqpn(struct ib_other_headers *ohdr) +{ + return ((be32_to_cpu(ohdr->u.ud.deth[1])) & IB_QPN_MASK); +} + /* * BTH */ @@ -229,6 +259,14 @@ static inline u16 ib_get_slid(struct ib_header *hdr) #define IB_BTH_PAD_MASK 3 #define IB_BTH_PKEY_MASK 0xffff #define IB_BTH_PAD_SHIFT 20 +#define IB_BTH_A_MASK 1 +#define IB_BTH_A_SHIFT 31 +#define IB_BTH_M_MASK 1 +#define IB_BTH_M_SHIFT 22 +#define IB_BTH_SE_MASK 1 +#define IB_BTH_SE_SHIFT 23 +#define IB_BTH_TVER_MASK 0xf +#define IB_BTH_TVER_SHIFT 16 static inline u8 ib_bth_get_pad(struct ib_other_headers *ohdr) { @@ -247,4 +285,50 @@ static inline u8 ib_bth_get_opcode(struct ib_other_headers *ohdr) IB_BTH_OPCODE_MASK); } +static inline u8 ib_bth_get_ackreq(struct ib_other_headers *ohdr) +{ + return (u8)((be32_to_cpu(ohdr->bth[2]) >> IB_BTH_A_SHIFT) & + IB_BTH_A_MASK); +} + +static inline u8 ib_bth_get_migreq(struct ib_other_headers *ohdr) +{ + return (u8)((be32_to_cpu(ohdr->bth[0]) >> IB_BTH_M_SHIFT) & + IB_BTH_M_MASK); +} + +static inline u8 ib_bth_get_se(struct ib_other_headers *ohdr) +{ + return (u8)((be32_to_cpu(ohdr->bth[0]) >> IB_BTH_SE_SHIFT) & + IB_BTH_SE_MASK); +} + +static inline u32 ib_bth_get_psn(struct ib_other_headers *ohdr) +{ + return (u32)(be32_to_cpu(ohdr->bth[2])); +} + +static inline u32 ib_bth_get_qpn(struct ib_other_headers *ohdr) +{ + return (u32)((be32_to_cpu(ohdr->bth[1])) & IB_QPN_MASK); +} + +static inline u8 ib_bth_get_becn(struct ib_other_headers *ohdr) +{ + return (u8)((be32_to_cpu(ohdr->bth[1]) >> IB_BECN_SHIFT) & + IB_BECN_MASK); +} + +static inline u8 ib_bth_get_fecn(struct ib_other_headers *ohdr) +{ + return (u8)((be32_to_cpu(ohdr->bth[1]) >> IB_FECN_SHIFT) & + IB_FECN_MASK); +} + +static inline u8 ib_bth_get_tver(struct ib_other_headers *ohdr) +{ + return (u8)((be32_to_cpu(ohdr->bth[0]) >> IB_BTH_TVER_SHIFT) & + IB_BTH_TVER_MASK); +} + #endif /* IB_HDRS_H */ diff --git a/include/rdma/ib_marshall.h b/include/rdma/ib_marshall.h index 68cef3bd50fb97730df5112d4dc88a8c9923f46d..8ebf84ae9ed161a73d061515a80b1f7d198ba48a 100644 --- a/include/rdma/ib_marshall.h +++ b/include/rdma/ib_marshall.h @@ -38,10 +38,12 @@ #include #include -void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst, +void ib_copy_qp_attr_to_user(struct ib_device *device, + struct ib_uverbs_qp_attr *dst, struct ib_qp_attr *src); -void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst, +void ib_copy_ah_attr_to_user(struct ib_device *device, + struct ib_uverbs_ah_attr *dst, struct rdma_ah_attr *src); void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, diff --git a/include/rdma/ib_umem_odp.h b/include/rdma/ib_umem_odp.h index fb67554aabd6e0f80c34f8966b035cbb4efba029..5eb7f5bc82485458ceccb4540597433b7a15a6fb 100644 --- a/include/rdma/ib_umem_odp.h +++ b/include/rdma/ib_umem_odp.h @@ -111,22 +111,25 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 start_offset, u64 bcnt, void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 start_offset, u64 bound); -void rbt_ib_umem_insert(struct umem_odp_node *node, struct rb_root *root); -void rbt_ib_umem_remove(struct umem_odp_node *node, struct rb_root *root); +void rbt_ib_umem_insert(struct umem_odp_node *node, + struct rb_root_cached *root); +void rbt_ib_umem_remove(struct umem_odp_node *node, + struct rb_root_cached *root); typedef int (*umem_call_back)(struct ib_umem *item, u64 start, u64 end, void *cookie); /* * Call the callback on each ib_umem in the range. Returns the logical or of * the return values of the functions called. */ -int rbt_ib_umem_for_each_in_range(struct rb_root *root, u64 start, u64 end, +int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root, + u64 start, u64 end, umem_call_back cb, void *cookie); /* * Find first region intersecting with address range. * Return NULL if not found */ -struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root *root, +struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root_cached *root, u64 addr, u64 length); static inline int ib_umem_mmu_notifier_retry(struct ib_umem *item, diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index b5732432bb297dbf6067ae34b16c00073cb2949d..e8608b2dc844fb27c0e7e5ceb359fe357ecf6553 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -64,6 +64,8 @@ #include #include +#define IB_FW_VERSION_NAME_MAX ETHTOOL_FWVERS_LEN + extern struct workqueue_struct *ib_wq; extern struct workqueue_struct *ib_comp_wq; @@ -168,7 +170,7 @@ enum ib_device_cap_flags { IB_DEVICE_UD_AV_PORT_ENFORCE = (1 << 6), IB_DEVICE_CURR_QP_STATE_MOD = (1 << 7), IB_DEVICE_SHUTDOWN_PORT = (1 << 8), - IB_DEVICE_INIT_TYPE = (1 << 9), + /* Not in use, former INIT_TYPE = (1 << 9),*/ IB_DEVICE_PORT_ACTIVE_EVENT = (1 << 10), IB_DEVICE_SYS_IMAGE_GUID = (1 << 11), IB_DEVICE_RC_RNR_NAK_GEN = (1 << 12), @@ -183,7 +185,7 @@ enum ib_device_cap_flags { * which will always contain a usable lkey. */ IB_DEVICE_LOCAL_DMA_LKEY = (1 << 15), - IB_DEVICE_RESERVED /* old SEND_W_INV */ = (1 << 16), + /* Reserved, old SEND_W_INV = (1 << 16),*/ IB_DEVICE_MEM_WINDOW = (1 << 17), /* * Devices should set IB_DEVICE_UD_IP_SUM if they support @@ -218,7 +220,7 @@ enum ib_device_cap_flags { * of I/O operations with single completion queue managed * by hardware. */ - IB_DEVICE_CROSS_CHANNEL = (1 << 27), + IB_DEVICE_CROSS_CHANNEL = (1 << 27), IB_DEVICE_MANAGED_FLOW_STEERING = (1 << 29), IB_DEVICE_SIGNATURE_HANDOVER = (1 << 30), IB_DEVICE_ON_DEMAND_PAGING = (1ULL << 31), @@ -278,6 +280,24 @@ struct ib_rss_caps { u32 max_rwq_indirection_table_size; }; +enum ib_tm_cap_flags { + /* Support tag matching on RC transport */ + IB_TM_CAP_RC = 1 << 0, +}; + +struct ib_tm_caps { + /* Max size of RNDV header */ + u32 max_rndv_hdr_size; + /* Max number of entries in tag matching list */ + u32 max_num_tags; + /* From enum ib_tm_cap_flags */ + u32 flags; + /* Max number of outstanding list operations */ + u32 max_ops; + /* Max number of SGE in tag matching entry */ + u32 max_sge; +}; + enum ib_cq_creation_flags { IB_CQ_FLAGS_TIMESTAMP_COMPLETION = 1 << 0, IB_CQ_FLAGS_IGNORE_OVERRUN = 1 << 1, @@ -338,6 +358,7 @@ struct ib_device_attr { struct ib_rss_caps rss_caps; u32 max_wq_type_rq; u32 raw_packet_caps; /* Use ib_raw_packet_caps enum */ + struct ib_tm_caps tm_caps; }; enum ib_mtu { @@ -549,8 +570,8 @@ struct ib_port_attr { u32 bad_pkey_cntr; u32 qkey_viol_cntr; u16 pkey_tbl_len; - u16 lid; - u16 sm_lid; + u32 sm_lid; + u32 lid; u8 lmc; u8 max_vl_num; u8 sm_sl; @@ -577,7 +598,8 @@ struct ib_device_modify { enum ib_port_modify_flags { IB_PORT_SHUTDOWN = 1, IB_PORT_INIT_TYPE = (1<<2), - IB_PORT_RESET_QKEY_CNTR = (1<<3) + IB_PORT_RESET_QKEY_CNTR = (1<<3), + IB_PORT_OPA_MASK_CHG = (1<<4) }; struct ib_port_modify { @@ -664,6 +686,8 @@ union rdma_network_hdr { }; }; +#define IB_QPN_MASK 0xFFFFFF + enum { IB_MULTICAST_QPN = 0xffffff }; @@ -859,6 +883,7 @@ struct roce_ah_attr { struct opa_ah_attr { u32 dlid; u8 src_path_bits; + bool make_grd; }; struct rdma_ah_attr { @@ -948,7 +973,7 @@ struct ib_wc { u32 src_qp; int wc_flags; u16 pkey_index; - u16 slid; + u32 slid; u8 sl; u8 dlid_path_bits; u8 port_num; /* valid only for DR SMPs on switches */ @@ -966,9 +991,16 @@ enum ib_cq_notify_flags { enum ib_srq_type { IB_SRQT_BASIC, - IB_SRQT_XRC + IB_SRQT_XRC, + IB_SRQT_TM, }; +static inline bool ib_srq_has_cq(enum ib_srq_type srq_type) +{ + return srq_type == IB_SRQT_XRC || + srq_type == IB_SRQT_TM; +} + enum ib_srq_attr_mask { IB_SRQ_MAX_WR = 1 << 0, IB_SRQ_LIMIT = 1 << 1, @@ -986,11 +1018,17 @@ struct ib_srq_init_attr { struct ib_srq_attr attr; enum ib_srq_type srq_type; - union { - struct { - struct ib_xrcd *xrcd; - struct ib_cq *cq; - } xrc; + struct { + struct ib_cq *cq; + union { + struct { + struct ib_xrcd *xrcd; + } xrc; + + struct { + u32 max_num_tags; + } tag_matching; + }; } ext; }; @@ -1059,6 +1097,7 @@ enum ib_qp_create_flags { /* FREE = 1 << 7, */ IB_QP_CREATE_SCATTER_FCS = 1 << 8, IB_QP_CREATE_CVLAN_STRIPPING = 1 << 9, + IB_QP_CREATE_SOURCE_QPN = 1 << 10, /* reserve bits 26-31 for low level drivers' internal use */ IB_QP_CREATE_RESERVED_START = 1 << 26, IB_QP_CREATE_RESERVED_END = 1 << 31, @@ -1086,6 +1125,7 @@ struct ib_qp_init_attr { */ u8 port_num; struct ib_rwq_ind_table *rwq_ind_tbl; + u32 source_qpn; }; struct ib_qp_open_attr { @@ -1417,7 +1457,7 @@ struct ib_ucontext { struct pid *tgid; #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING - struct rb_root umem_tree; + struct rb_root_cached umem_tree; /* * Protects .umem_rbroot and tree, as well as odp_mrs_count and * mmu notifiers registration. @@ -1527,12 +1567,14 @@ struct ib_srq { enum ib_srq_type srq_type; atomic_t usecnt; - union { - struct { - struct ib_xrcd *xrcd; - struct ib_cq *cq; - u32 srq_num; - } xrc; + struct { + struct ib_cq *cq; + union { + struct { + struct ib_xrcd *xrcd; + u32 srq_num; + } xrc; + }; } ext; }; @@ -1546,6 +1588,10 @@ enum ib_raw_packet_caps { IB_RAW_PACKET_CAP_SCATTER_FCS = (1 << 1), /* Checksum offloads are supported (for both send and receive). */ IB_RAW_PACKET_CAP_IP_CSUM = (1 << 2), + /* When a packet is received for an RQ with no receive WQEs, the + * packet processing is delayed. + */ + IB_RAW_PACKET_CAP_DELAY_DROP = (1 << 3), }; enum ib_wq_type { @@ -1574,6 +1620,7 @@ struct ib_wq { enum ib_wq_flags { IB_WQ_FLAGS_CVLAN_STRIPPING = 1 << 0, IB_WQ_FLAGS_SCATTER_FCS = 1 << 1, + IB_WQ_FLAGS_DELAY_DROP = 1 << 2, }; struct ib_wq_init_attr { @@ -1683,6 +1730,7 @@ struct ib_qp { enum ib_qp_type qp_type; struct ib_rwq_ind_table *rwq_ind_tbl; struct ib_qp_security *qp_sec; + u8 port; }; struct ib_mr { @@ -1691,7 +1739,7 @@ struct ib_mr { u32 lkey; u32 rkey; u64 iova; - u32 length; + u64 length; unsigned int page_size; bool need_inval; union { @@ -2288,6 +2336,8 @@ struct ib_device { struct rdmacg_device cg_device; #endif + u32 index; + /** * The following mandatory functions are used only at device * registration. Keep functions such as these at the end of this @@ -2295,7 +2345,11 @@ struct ib_device { * in fast paths. */ int (*get_port_immutable)(struct ib_device *, u8, struct ib_port_immutable *); - void (*get_dev_fw_str)(struct ib_device *, char *str, size_t str_len); + void (*get_dev_fw_str)(struct ib_device *, char *str); + const struct cpumask *(*get_vector_affinity)(struct ib_device *ibdev, + int comp_vector); + + struct uverbs_root_spec *specs_root; }; struct ib_client { @@ -2331,7 +2385,7 @@ struct ib_client { struct ib_device *ib_alloc_device(size_t size); void ib_dealloc_device(struct ib_device *device); -void ib_get_device_fw_str(struct ib_device *device, char *str, size_t str_len); +void ib_get_device_fw_str(struct ib_device *device, char *str); int ib_register_device(struct ib_device *device, int (*port_callback)(struct ib_device *, @@ -2395,8 +2449,8 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, enum ib_qp_type type, enum ib_qp_attr_mask mask, enum rdma_link_layer ll); -int ib_register_event_handler (struct ib_event_handler *event_handler); -int ib_unregister_event_handler(struct ib_event_handler *event_handler); +void ib_register_event_handler(struct ib_event_handler *event_handler); +void ib_unregister_event_handler(struct ib_event_handler *event_handler); void ib_dispatch_event(struct ib_event *event); int ib_query_port(struct ib_device *device, @@ -3555,6 +3609,7 @@ void ib_drain_qp(struct ib_qp *qp); int ib_resolve_eth_dmac(struct ib_device *device, struct rdma_ah_attr *ah_attr); +int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u8 *speed, u8 *width); static inline u8 *rdma_ah_retrieve_dmac(struct rdma_ah_attr *attr) { @@ -3608,6 +3663,20 @@ static inline u8 rdma_ah_get_path_bits(const struct rdma_ah_attr *attr) return 0; } +static inline void rdma_ah_set_make_grd(struct rdma_ah_attr *attr, + bool make_grd) +{ + if (attr->type == RDMA_AH_ATTR_TYPE_OPA) + attr->opa.make_grd = make_grd; +} + +static inline bool rdma_ah_get_make_grd(const struct rdma_ah_attr *attr) +{ + if (attr->type == RDMA_AH_ATTR_TYPE_OPA) + return attr->opa.make_grd; + return false; +} + static inline void rdma_ah_set_port_num(struct rdma_ah_attr *attr, u8 port_num) { attr->port_num = port_num; @@ -3706,4 +3775,52 @@ static inline enum rdma_ah_attr_type rdma_ah_find_type(struct ib_device *dev, else return RDMA_AH_ATTR_TYPE_IB; } + +/** + * ib_lid_cpu16 - Return lid in 16bit CPU encoding. + * In the current implementation the only way to get + * get the 32bit lid is from other sources for OPA. + * For IB, lids will always be 16bits so cast the + * value accordingly. + * + * @lid: A 32bit LID + */ +static inline u16 ib_lid_cpu16(u32 lid) +{ + WARN_ON_ONCE(lid & 0xFFFF0000); + return (u16)lid; +} + +/** + * ib_lid_be16 - Return lid in 16bit BE encoding. + * + * @lid: A 32bit LID + */ +static inline __be16 ib_lid_be16(u32 lid) +{ + WARN_ON_ONCE(lid & 0xFFFF0000); + return cpu_to_be16((u16)lid); +} + +/** + * ib_get_vector_affinity - Get the affinity mappings of a given completion + * vector + * @device: the rdma device + * @comp_vector: index of completion vector + * + * Returns NULL on failure, otherwise a corresponding cpu map of the + * completion vector (returns all-cpus map if the device driver doesn't + * implement get_vector_affinity). + */ +static inline const struct cpumask * +ib_get_vector_affinity(struct ib_device *device, int comp_vector) +{ + if (comp_vector < 0 || comp_vector >= device->num_comp_vectors || + !device->get_vector_affinity) + return NULL; + + return device->get_vector_affinity(device, comp_vector); + +} + #endif /* IB_VERBS_H */ diff --git a/include/rdma/opa_addr.h b/include/rdma/opa_addr.h index eace28f1555d958a896677977232b814c4642568..e6e90f18e6d5b6887fccb2b78d8f0c920cdb1edb 100644 --- a/include/rdma/opa_addr.h +++ b/include/rdma/opa_addr.h @@ -48,8 +48,21 @@ #ifndef OPA_ADDR_H #define OPA_ADDR_H +#include + #define OPA_SPECIAL_OUI (0x00066AULL) #define OPA_MAKE_ID(x) (cpu_to_be64(OPA_SPECIAL_OUI << 40 | (x))) +#define OPA_TO_IB_UCAST_LID(x) (((x) >= be16_to_cpu(IB_MULTICAST_LID_BASE)) \ + ? 0 : x) +#define OPA_GID_INDEX 0x1 +/** + * 0xF8 - 4 bits of multicast range and 1 bit for collective range + * Example: For 24 bit LID space, + * Multicast range: 0xF00000 to 0xF7FFFF + * Collective range: 0xF80000 to 0xFFFFFE + */ +#define OPA_MCAST_NR 0x4 /* Number of top bits set */ +#define OPA_COLLECTIVE_NR 0x1 /* Number of bits after MCAST_NR */ /** * ib_is_opa_gid: Returns true if the top 24 bits of the gid @@ -59,7 +72,7 @@ * * @gid: The Global identifier */ -static inline bool ib_is_opa_gid(union ib_gid *gid) +static inline bool ib_is_opa_gid(const union ib_gid *gid) { return ((be64_to_cpu(gid->global.interface_id) >> 40) == OPA_SPECIAL_OUI); @@ -72,8 +85,33 @@ static inline bool ib_is_opa_gid(union ib_gid *gid) * * @gid: The Global identifier */ -static inline u32 opa_get_lid_from_gid(union ib_gid *gid) +static inline u32 opa_get_lid_from_gid(const union ib_gid *gid) { return be64_to_cpu(gid->global.interface_id) & 0xFFFFFFFF; } + +/** + * opa_is_extended_lid: Returns true if dlid or slid are + * extended. + * + * @dlid: The DLID + * @slid: The SLID + */ +static inline bool opa_is_extended_lid(u32 dlid, u32 slid) +{ + if ((be32_to_cpu(dlid) >= + be16_to_cpu(IB_MULTICAST_LID_BASE)) || + (be32_to_cpu(slid) >= + be16_to_cpu(IB_MULTICAST_LID_BASE))) + return true; + else + return false; +} + +/* Get multicast lid base */ +static inline u32 opa_get_mcast_base(u32 nr_top_bits) +{ + return (be32_to_cpu(OPA_LID_PERMISSIVE) << (32 - nr_top_bits)); +} + #endif /* OPA_ADDR_H */ diff --git a/include/rdma/opa_vnic.h b/include/rdma/opa_vnic.h index 39d6890616a6bf8c93ff98242c0cbabd532845ef..0c07a70bd7f61d707e1e897434c54baf53b93be6 100644 --- a/include/rdma/opa_vnic.h +++ b/include/rdma/opa_vnic.h @@ -54,9 +54,6 @@ #include -/* VNIC uses 16B header format */ -#define OPA_VNIC_L2_TYPE 0x2 - /* 16 header bytes + 2 reserved bytes */ #define OPA_VNIC_L2_HDR_LEN (16 + 2) diff --git a/include/rdma/rdma_netlink.h b/include/rdma/rdma_netlink.h index 348c102cb5f6afdbe9f90a7c788431bac0219226..2d878596b1e07a41f0e7d75b17b269e88646b9fd 100644 --- a/include/rdma/rdma_netlink.h +++ b/include/rdma/rdma_netlink.h @@ -5,29 +5,43 @@ #include #include -struct ibnl_client_cbs { +struct rdma_nl_cbs { + int (*doit)(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack); int (*dump)(struct sk_buff *skb, struct netlink_callback *nlcb); - struct module *module; + u8 flags; }; +enum rdma_nl_flags { + /* Require CAP_NET_ADMIN */ + RDMA_NL_ADMIN_PERM = 1 << 0, +}; + +/* Define this module as providing netlink services for NETLINK_RDMA, with + * index _index. Since the client indexes were setup in a uapi header as an + * enum and we do no want to change that, the user must supply the expanded + * constant as well and the compiler checks they are the same. + */ +#define MODULE_ALIAS_RDMA_NETLINK(_index, _val) \ + static inline void __chk_##_index(void) \ + { \ + BUILD_BUG_ON(_index != _val); \ + } \ + MODULE_ALIAS("rdma-netlink-subsys-" __stringify(_val)) + /** - * Add a a client to the list of IB netlink exporters. + * Register client in RDMA netlink. * @index: Index of the added client - * @nops: Number of supported ops by the added client. * @cb_table: A table for op->callback - * - * Returns 0 on success or a negative error code. */ -int ibnl_add_client(int index, int nops, - const struct ibnl_client_cbs cb_table[]); +void rdma_nl_register(unsigned int index, + const struct rdma_nl_cbs cb_table[]); /** * Remove a client from IB netlink. * @index: Index of the removed IB client. - * - * Returns 0 on success or a negative error code. */ -int ibnl_remove_client(int index); +void rdma_nl_unregister(unsigned int index); /** * Put a new message in a supplied skb. @@ -56,22 +70,32 @@ int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh, /** * Send the supplied skb to a specific userspace PID. * @skb: The netlink skb - * @nlh: Header of the netlink message to send * @pid: Userspace netlink process ID * Returns 0 on success or a negative error code. */ -int ibnl_unicast(struct sk_buff *skb, struct nlmsghdr *nlh, - __u32 pid); +int rdma_nl_unicast(struct sk_buff *skb, u32 pid); + +/** + * Send, with wait/1 retry, the supplied skb to a specific userspace PID. + * @skb: The netlink skb + * @pid: Userspace netlink process ID + * Returns 0 on success or a negative error code. + */ +int rdma_nl_unicast_wait(struct sk_buff *skb, __u32 pid); /** * Send the supplied skb to a netlink group. * @skb: The netlink skb - * @nlh: Header of the netlink message to send * @group: Netlink group ID * @flags: allocation flags * Returns 0 on success or a negative error code. */ -int ibnl_multicast(struct sk_buff *skb, struct nlmsghdr *nlh, - unsigned int group, gfp_t flags); +int rdma_nl_multicast(struct sk_buff *skb, unsigned int group, gfp_t flags); +/** + * Check if there are any listeners to the netlink group + * @group: the netlink group ID + * Returns 0 on success or a negative for no listeners. + */ +int rdma_nl_chk_listeners(unsigned int group); #endif /* _RDMA_NETLINK_H */ diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h index 55af692710539d6555c072a0c2a290aca7bfba42..1ba84a78f1c5435f4e049313acdf581820667ecc 100644 --- a/include/rdma/rdma_vt.h +++ b/include/rdma/rdma_vt.h @@ -57,11 +57,21 @@ #include #include #include +#include #include #include #define RVT_MAX_PKEY_VALUES 16 +#define RVT_MAX_TRAP_LEN 100 /* Limit pending trap list */ +#define RVT_MAX_TRAP_LISTS 5 /*((IB_NOTICE_TYPE_INFO & 0x0F) + 1)*/ +#define RVT_TRAP_TIMEOUT 4096 /* 4.096 usec */ + +struct trap_list { + u32 list_len; + struct list_head list; +}; + struct rvt_ibport { struct rvt_qp __rcu *qp[2]; struct ib_mad_agent *send_agent; /* agent for SMI (traps) */ @@ -75,12 +85,13 @@ struct rvt_ibport { __be64 mkey; u64 tid; u32 port_cap_flags; + u16 port_cap3_flags; u32 pma_sample_start; u32 pma_sample_interval; __be16 pma_counter_select[5]; u16 pma_tag; u16 mkey_lease_period; - u16 sm_lid; + u32 sm_lid; u8 sm_sl; u8 mkeyprot; u8 subnet_timeout; @@ -127,6 +138,13 @@ struct rvt_ibport { u16 *pkey_table; struct rvt_ah *sm_ah; + + /* + * Keep a list of traps that have not been repressed. They will be + * resent based on trap_timer. + */ + struct trap_list trap_lists[RVT_MAX_TRAP_LISTS]; + struct timer_list trap_timer; }; #define RVT_CQN_MAX 16 /* maximum length of cq name */ @@ -514,7 +532,8 @@ int rvt_invalidate_rkey(struct rvt_qp *qp, u32 rkey); int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge, u32 len, u64 vaddr, u32 rkey, int acc); int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd, - struct rvt_sge *isge, struct ib_sge *sge, int acc); + struct rvt_sge *isge, struct rvt_sge *last_sge, + struct ib_sge *sge, int acc); struct rvt_mcast *rvt_mcast_find(struct rvt_ibport *ibp, union ib_gid *mgid, u16 lid); diff --git a/include/rdma/rdmavt_mr.h b/include/rdma/rdmavt_mr.h index f418bd5571a56e60023cce3b432042a52a5dd7dc..72a3856d4057f5ac72e0c0c5e3a5ecb41dfd8af1 100644 --- a/include/rdma/rdmavt_mr.h +++ b/include/rdma/rdmavt_mr.h @@ -191,4 +191,7 @@ static inline void rvt_skip_sge(struct rvt_sge_state *ss, u32 length, } } +bool rvt_ss_has_lkey(struct rvt_sge_state *ss, u32 lkey); +bool rvt_mr_has_lkey(struct rvt_mregion *mr, u32 lkey); + #endif /* DEF_RDMAVT_INCMRH */ diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h index d664d2e762808321d7b2aece6d3146b713b51631..0eed3d8752fa0b10ca4ec9ad2ac8d96201f67b12 100644 --- a/include/rdma/rdmavt_qp.h +++ b/include/rdma/rdmavt_qp.h @@ -277,7 +277,6 @@ struct rvt_qp { unsigned long timeout_jiffies; /* computed from timeout */ - enum ib_mtu path_mtu; int srate_mbps; /* s_srate (below) converted to Mbit/s */ pid_t pid; /* pid for user mode QPs */ u32 remote_qpn; @@ -396,7 +395,7 @@ struct rvt_srq { #define RVT_QPNMAP_ENTRIES (RVT_QPN_MAX / PAGE_SIZE / BITS_PER_BYTE) #define RVT_BITS_PER_PAGE (PAGE_SIZE * BITS_PER_BYTE) #define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE - 1) -#define RVT_QPN_MASK 0xFFFFFF +#define RVT_QPN_MASK IB_QPN_MASK /* * QPN-map pages start out as NULL, they get allocated upon @@ -674,4 +673,34 @@ void rvt_del_timers_sync(struct rvt_qp *qp); void rvt_stop_rc_timers(struct rvt_qp *qp); void rvt_add_retry_timer(struct rvt_qp *qp); +/** + * struct rvt_qp_iter - the iterator for QPs + * @qp - the current QP + * + * This structure defines the current iterator + * state for sequenced access to all QPs relative + * to an rvt_dev_info. + */ +struct rvt_qp_iter { + struct rvt_qp *qp; + /* private: backpointer */ + struct rvt_dev_info *rdi; + /* private: callback routine */ + void (*cb)(struct rvt_qp *qp, u64 v); + /* private: for arg to callback routine */ + u64 v; + /* private: number of SMI,GSI QPs for device */ + int specials; + /* private: current iterator index */ + int n; +}; + +struct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi, + u64 v, + void (*cb)(struct rvt_qp *qp, u64 v)); +int rvt_qp_iter_next(struct rvt_qp_iter *iter); +void rvt_qp_iter(struct rvt_dev_info *rdi, + u64 v, + void (*cb)(struct rvt_qp *qp, u64 v)); +void rvt_qp_mr_clean(struct rvt_qp *qp, u32 lkey); #endif /* DEF_RDMAVT_INCQP_H */ diff --git a/include/rdma/rw.h b/include/rdma/rw.h index 377d865e506dcbba1daec08715aa07c68222a176..a3cbbc7b641766955918db345fdcec16130eb8ac 100644 --- a/include/rdma/rw.h +++ b/include/rdma/rw.h @@ -81,6 +81,8 @@ struct ib_send_wr *rdma_rw_ctx_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp, int rdma_rw_ctx_post(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, struct ib_cqe *cqe, struct ib_send_wr *chain_wr); +unsigned int rdma_rw_mr_factor(struct ib_device *device, u8 port_num, + unsigned int maxpages); void rdma_rw_init_qp(struct ib_device *dev, struct ib_qp_init_attr *attr); int rdma_rw_init_mrs(struct ib_qp *qp, struct ib_qp_init_attr *attr); void rdma_rw_cleanup_mrs(struct ib_qp *qp); diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h new file mode 100644 index 0000000000000000000000000000000000000000..6da44079aa58961cccde88f8366944f2c96166c0 --- /dev/null +++ b/include/rdma/uverbs_ioctl.h @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _UVERBS_IOCTL_ +#define _UVERBS_IOCTL_ + +#include +#include +#include +#include + +/* + * ======================================= + * Verbs action specifications + * ======================================= + */ + +enum uverbs_attr_type { + UVERBS_ATTR_TYPE_NA, + UVERBS_ATTR_TYPE_PTR_IN, + UVERBS_ATTR_TYPE_PTR_OUT, + UVERBS_ATTR_TYPE_IDR, + UVERBS_ATTR_TYPE_FD, +}; + +enum uverbs_obj_access { + UVERBS_ACCESS_READ, + UVERBS_ACCESS_WRITE, + UVERBS_ACCESS_NEW, + UVERBS_ACCESS_DESTROY +}; + +enum { + UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0, + /* Support extending attributes by length */ + UVERBS_ATTR_SPEC_F_MIN_SZ = 1U << 1, +}; + +struct uverbs_attr_spec { + enum uverbs_attr_type type; + union { + u16 len; + struct { + /* + * higher bits mean the namespace and lower bits mean + * the type id within the namespace. + */ + u16 obj_type; + u8 access; + } obj; + }; + /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ + u8 flags; +}; + +struct uverbs_attr_spec_hash { + size_t num_attrs; + unsigned long *mandatory_attrs_bitmask; + struct uverbs_attr_spec attrs[0]; +}; + +struct uverbs_attr_bundle; +struct ib_uverbs_file; + +enum { + /* + * Action marked with this flag creates a context (or root for all + * objects). + */ + UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0, +}; + +struct uverbs_method_spec { + /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ + u32 flags; + size_t num_buckets; + size_t num_child_attrs; + int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, + struct uverbs_attr_bundle *ctx); + struct uverbs_attr_spec_hash *attr_buckets[0]; +}; + +struct uverbs_method_spec_hash { + size_t num_methods; + struct uverbs_method_spec *methods[0]; +}; + +struct uverbs_object_spec { + const struct uverbs_obj_type *type_attrs; + size_t num_buckets; + struct uverbs_method_spec_hash *method_buckets[0]; +}; + +struct uverbs_object_spec_hash { + size_t num_objects; + struct uverbs_object_spec *objects[0]; +}; + +struct uverbs_root_spec { + size_t num_buckets; + struct uverbs_object_spec_hash *object_buckets[0]; +}; + +/* + * ======================================= + * Verbs definitions + * ======================================= + */ + +struct uverbs_attr_def { + u16 id; + struct uverbs_attr_spec attr; +}; + +struct uverbs_method_def { + u16 id; + /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ + u32 flags; + size_t num_attrs; + const struct uverbs_attr_def * const (*attrs)[]; + int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, + struct uverbs_attr_bundle *ctx); +}; + +struct uverbs_object_def { + u16 id; + const struct uverbs_obj_type *type_attrs; + size_t num_methods; + const struct uverbs_method_def * const (*methods)[]; +}; + +struct uverbs_object_tree_def { + size_t num_objects; + const struct uverbs_object_def * const (*objects)[]; +}; + +#define UA_FLAGS(_flags) .flags = _flags +#define __UVERBS_ATTR0(_id, _len, _type, ...) \ + ((const struct uverbs_attr_def) \ + {.id = _id, .attr = {.type = _type, {.len = _len}, .flags = 0, } }) +#define __UVERBS_ATTR1(_id, _len, _type, _flags) \ + ((const struct uverbs_attr_def) \ + {.id = _id, .attr = {.type = _type, {.len = _len}, _flags, } }) +#define __UVERBS_ATTR(_id, _len, _type, _flags, _n, ...) \ + __UVERBS_ATTR##_n(_id, _len, _type, _flags) +/* + * In new compiler, UVERBS_ATTR could be simplified by declaring it as + * [_id] = {.type = _type, .len = _len, ##__VA_ARGS__} + * But since we support older compilers too, we need the more complex code. + */ +#define UVERBS_ATTR(_id, _len, _type, ...) \ + __UVERBS_ATTR(_id, _len, _type, ##__VA_ARGS__, 1, 0) +#define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \ + UVERBS_ATTR(_id, _len, UVERBS_ATTR_TYPE_PTR_IN, ##__VA_ARGS__) +/* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */ +#define UVERBS_ATTR_PTR_IN(_id, _type, ...) \ + UVERBS_ATTR_PTR_IN_SZ(_id, sizeof(_type), ##__VA_ARGS__) +#define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \ + UVERBS_ATTR(_id, _len, UVERBS_ATTR_TYPE_PTR_OUT, ##__VA_ARGS__) +#define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \ + UVERBS_ATTR_PTR_OUT_SZ(_id, sizeof(_type), ##__VA_ARGS__) + +/* + * In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring + * it as + * {.id = _id, \ + * .attr {.type = __obj_class, \ + * .obj = {.obj_type = _idr_type, \ + * .access = _access \ + * }, ##__VA_ARGS__ } } + * But since we support older compilers too, we need the more complex code. + */ +#define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\ + ((const struct uverbs_attr_def) \ + {.id = _id, \ + .attr = {.type = _obj_class, \ + {.obj = {.obj_type = _obj_type, .access = _access } },\ + .flags = 0} }) +#define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\ + ((const struct uverbs_attr_def) \ + {.id = _id, \ + .attr = {.type = _obj_class, \ + {.obj = {.obj_type = _obj_type, .access = _access} }, \ + _flags} }) +#define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \ + _n, ...) \ + ___UVERBS_ATTR_OBJ##_n(_id, _obj_class, _obj_type, _access, _flags) +#define __UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, ...) \ + ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, \ + ##__VA_ARGS__, 1, 0) +#define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \ + __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\ + ##__VA_ARGS__) +#define UVERBS_ATTR_FD(_id, _fd_type, _access, ...) \ + __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_FD, _fd_type, \ + (_access) + BUILD_BUG_ON_ZERO( \ + (_access) != UVERBS_ACCESS_NEW && \ + (_access) != UVERBS_ACCESS_READ), \ + ##__VA_ARGS__) +#define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \ + const struct uverbs_attr_def _name = __VA_ARGS__ + +#define _UVERBS_METHOD_ATTRS_SZ(...) \ + (sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\ + sizeof(const struct uverbs_attr_def *)) +#define _UVERBS_METHOD(_id, _handler, _flags, ...) \ + ((const struct uverbs_method_def) { \ + .id = _id, \ + .flags = _flags, \ + .handler = _handler, \ + .num_attrs = _UVERBS_METHOD_ATTRS_SZ(__VA_ARGS__), \ + .attrs = &(const struct uverbs_attr_def * const []){__VA_ARGS__} }) +#define DECLARE_UVERBS_METHOD(_name, _id, _handler, ...) \ + const struct uverbs_method_def _name = \ + _UVERBS_METHOD(_id, _handler, 0, ##__VA_ARGS__) +#define DECLARE_UVERBS_CTX_METHOD(_name, _id, _handler, _flags, ...) \ + const struct uverbs_method_def _name = \ + _UVERBS_METHOD(_id, _handler, \ + UVERBS_ACTION_FLAG_CREATE_ROOT, \ + ##__VA_ARGS__) +#define _UVERBS_OBJECT_METHODS_SZ(...) \ + (sizeof((const struct uverbs_method_def * const []){__VA_ARGS__}) / \ + sizeof(const struct uverbs_method_def *)) +#define _UVERBS_OBJECT(_id, _type_attrs, ...) \ + ((const struct uverbs_object_def) { \ + .id = _id, \ + .type_attrs = _type_attrs, \ + .num_methods = _UVERBS_OBJECT_METHODS_SZ(__VA_ARGS__), \ + .methods = &(const struct uverbs_method_def * const []){__VA_ARGS__} }) +#define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \ + const struct uverbs_object_def _name = \ + _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__) +#define _UVERBS_TREE_OBJECTS_SZ(...) \ + (sizeof((const struct uverbs_object_def * const []){__VA_ARGS__}) / \ + sizeof(const struct uverbs_object_def *)) +#define _UVERBS_OBJECT_TREE(...) \ + ((const struct uverbs_object_tree_def) { \ + .num_objects = _UVERBS_TREE_OBJECTS_SZ(__VA_ARGS__), \ + .objects = &(const struct uverbs_object_def * const []){__VA_ARGS__} }) +#define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \ + const struct uverbs_object_tree_def _name = \ + _UVERBS_OBJECT_TREE(__VA_ARGS__) + +/* ================================================= + * Parsing infrastructure + * ================================================= + */ + +struct uverbs_ptr_attr { + union { + u64 data; + void __user *ptr; + }; + u16 len; + /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ + u16 flags; +}; + +struct uverbs_obj_attr { + /* pointer to the kernel descriptor -> type, access, etc */ + const struct uverbs_obj_type *type; + struct ib_uobject *uobject; + /* fd or id in idr of this object */ + int id; +}; + +struct uverbs_attr { + /* + * pointer to the user-space given attribute, in order to write the + * new uobject's id or update flags. + */ + struct ib_uverbs_attr __user *uattr; + union { + struct uverbs_ptr_attr ptr_attr; + struct uverbs_obj_attr obj_attr; + }; +}; + +struct uverbs_attr_bundle_hash { + /* if bit i is set, it means attrs[i] contains valid information */ + unsigned long *valid_bitmap; + size_t num_attrs; + /* + * arrays of attributes, each element corresponds to the specification + * of the attribute in the same index. + */ + struct uverbs_attr *attrs; +}; + +struct uverbs_attr_bundle { + size_t num_buckets; + struct uverbs_attr_bundle_hash hash[]; +}; + +static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash, + unsigned int idx) +{ + return test_bit(idx, attrs_hash->valid_bitmap); +} + +static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle, + unsigned int idx) +{ + u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; + + if (attrs_bundle->num_buckets <= idx_bucket) + return false; + + return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket], + idx & ~UVERBS_ID_NS_MASK); +} + +static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle, + u16 idx) +{ + u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; + + if (!uverbs_attr_is_valid(attrs_bundle, idx)) + return ERR_PTR(-ENOENT); + + return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK]; +} + +static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, + size_t idx, const void *from) +{ + const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); + u16 flags; + + if (IS_ERR(attr)) + return PTR_ERR(attr); + + flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT; + return (!copy_to_user(attr->ptr_attr.ptr, from, attr->ptr_attr.len) && + !put_user(flags, &attr->uattr->flags)) ? 0 : -EFAULT; +} + +static inline int _uverbs_copy_from(void *to, size_t to_size, + const struct uverbs_attr_bundle *attrs_bundle, + size_t idx) +{ + const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); + + if (IS_ERR(attr)) + return PTR_ERR(attr); + + if (to_size <= sizeof(((struct ib_uverbs_attr *)0)->data)) + memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len); + else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len)) + return -EFAULT; + + return 0; +} + +#define uverbs_copy_from(to, attrs_bundle, idx) \ + _uverbs_copy_from(to, sizeof(*(to)), attrs_bundle, idx) + +/* ================================================= + * Definitions -> Specs infrastructure + * ================================================= + */ + +/* + * uverbs_alloc_spec_tree - Merges different common and driver specific feature + * into one parsing tree that every uverbs command will be parsed upon. + * + * @num_trees: Number of trees in the array @trees. + * @trees: Array of pointers to tree root definitions to merge. Each such tree + * possibly contains objects, methods and attributes definitions. + * + * Returns: + * uverbs_root_spec *: The root of the merged parsing tree. + * On error, we return an error code. Error is checked via IS_ERR. + * + * The following merges could take place: + * a. Two trees representing the same method with different handler + * -> We take the handler of the tree that its handler != NULL + * and its index in the trees array is greater. The incentive for that + * is that developers are expected to first merge common trees and then + * merge trees that gives specialized the behaviour. + * b. Two trees representing the same object with different + * type_attrs (struct uverbs_obj_type): + * -> We take the type_attrs of the tree that its type_attr != NULL + * and its index in the trees array is greater. This could be used + * in order to override the free function, allocation size, etc. + * c. Two trees representing the same method attribute (same id but possibly + * different attributes): + * -> ERROR (-ENOENT), we believe that's not the programmer's intent. + * + * An object without any methods is considered invalid and will abort the + * function with -ENOENT error. + */ +#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) +struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, + const struct uverbs_object_tree_def **trees); +void uverbs_free_spec_tree(struct uverbs_root_spec *root); +#else +static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, + const struct uverbs_object_tree_def **trees) +{ + return NULL; +} + +static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root) +{ +} +#endif + +#endif diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h index 7771ce9669521912ddfcc611bf01dad5381dc58c..5f8e20bbd67ceb06a5d51e94de3c17c557c9559a 100644 --- a/include/rdma/uverbs_std_types.h +++ b/include/rdma/uverbs_std_types.h @@ -34,19 +34,35 @@ #define _UVERBS_STD_TYPES__ #include - -extern const struct uverbs_obj_fd_type uverbs_type_attrs_comp_channel; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_cq; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_qp; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_rwq_ind_table; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_wq; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_srq; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_ah; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_flow; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_mr; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_mw; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_pd; -extern const struct uverbs_obj_idr_type uverbs_type_attrs_xrcd; +#include +#include + +#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) +extern const struct uverbs_object_def uverbs_object_comp_channel; +extern const struct uverbs_object_def uverbs_object_cq; +extern const struct uverbs_object_def uverbs_object_qp; +extern const struct uverbs_object_def uverbs_object_rwq_ind_table; +extern const struct uverbs_object_def uverbs_object_wq; +extern const struct uverbs_object_def uverbs_object_srq; +extern const struct uverbs_object_def uverbs_object_ah; +extern const struct uverbs_object_def uverbs_object_flow; +extern const struct uverbs_object_def uverbs_object_mr; +extern const struct uverbs_object_def uverbs_object_mw; +extern const struct uverbs_object_def uverbs_object_pd; +extern const struct uverbs_object_def uverbs_object_xrcd; +extern const struct uverbs_object_def uverbs_object_device; + +extern const struct uverbs_object_tree_def uverbs_default_objects; +static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void) +{ + return &uverbs_default_objects; +} +#else +static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void) +{ + return NULL; +} +#endif static inline struct ib_uobject *__uobj_get(const struct uverbs_obj_type *type, bool write, @@ -56,22 +72,22 @@ static inline struct ib_uobject *__uobj_get(const struct uverbs_obj_type *type, return rdma_lookup_get_uobject(type, ucontext, id, write); } -#define uobj_get_type(_type) uverbs_type_attrs_##_type.type +#define uobj_get_type(_object) uverbs_object_##_object.type_attrs #define uobj_get_read(_type, _id, _ucontext) \ - __uobj_get(&(_type), false, _ucontext, _id) + __uobj_get(_type, false, _ucontext, _id) -#define uobj_get_obj_read(_type, _id, _ucontext) \ +#define uobj_get_obj_read(_object, _id, _ucontext) \ ({ \ - struct ib_uobject *uobj = \ - __uobj_get(&uobj_get_type(_type), \ + struct ib_uobject *__uobj = \ + __uobj_get(uverbs_object_##_object.type_attrs, \ false, _ucontext, _id); \ \ - (struct ib_##_type *)(IS_ERR(uobj) ? NULL : uobj->object); \ + (struct ib_##_object *)(IS_ERR(__uobj) ? NULL : __uobj->object);\ }) #define uobj_get_write(_type, _id, _ucontext) \ - __uobj_get(&(_type), true, _ucontext, _id) + __uobj_get(_type, true, _ucontext, _id) static inline void uobj_put_read(struct ib_uobject *uobj) { @@ -108,7 +124,7 @@ static inline struct ib_uobject *__uobj_alloc(const struct uverbs_obj_type *type } #define uobj_alloc(_type, ucontext) \ - __uobj_alloc(&(_type), ucontext) + __uobj_alloc(_type, ucontext) #endif diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h index 351ea185df44fee1af734ae6cad770f1a5ba6c6d..cc04ec65588daa9bc07903dd8831c8cda3d4bc85 100644 --- a/include/rdma/uverbs_types.h +++ b/include/rdma/uverbs_types.h @@ -129,6 +129,7 @@ struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type, void rdma_alloc_abort_uobject(struct ib_uobject *uobj); int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj); int rdma_alloc_commit_uobject(struct ib_uobject *uobj); +int rdma_explicit_destroy(struct ib_uobject *uobject); struct uverbs_obj_fd_type { /* @@ -151,22 +152,30 @@ extern const struct uverbs_obj_type_class uverbs_fd_class; #define UVERBS_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - \ sizeof(char)) -#define UVERBS_TYPE_ALLOC_FD(_size, _order) \ - { \ - .destroy_order = _order, \ - .type_class = &uverbs_fd_class, \ - .obj_size = (_size) + \ - UVERBS_BUILD_BUG_ON((_size) < \ - sizeof(struct ib_uobject_file)),\ - } -#define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _order) \ - { \ +#define UVERBS_TYPE_ALLOC_FD(_order, _obj_size, _context_closed, _fops, _name, _flags)\ + ((&((const struct uverbs_obj_fd_type) \ + {.type = { \ + .destroy_order = _order, \ + .type_class = &uverbs_fd_class, \ + .obj_size = (_obj_size) + \ + UVERBS_BUILD_BUG_ON((_obj_size) < sizeof(struct ib_uobject_file)), \ + }, \ + .context_closed = _context_closed, \ + .fops = _fops, \ + .name = _name, \ + .flags = _flags}))->type) +#define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _order, _destroy_object) \ + ((&((const struct uverbs_obj_idr_type) \ + {.type = { \ .destroy_order = _order, \ .type_class = &uverbs_idr_class, \ .obj_size = (_size) + \ - UVERBS_BUILD_BUG_ON((_size) < \ - sizeof(struct ib_uobject)), \ - } -#define UVERBS_TYPE_ALLOC_IDR(_order) \ - UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), _order) + UVERBS_BUILD_BUG_ON((_size) < \ + sizeof(struct ib_uobject)) \ + }, \ + .destroy_object = _destroy_object,}))->type) +#define UVERBS_TYPE_ALLOC_IDR(_order, _destroy_object) \ + UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), _order, \ + _destroy_object) + #endif diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index cfaeed256ab23789dac204674b030b5e175bc647..6c0dc6155ee757b5e066b075316dc899f6dddddc 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -714,16 +714,13 @@ void sas_init_dev(struct domain_device *); void sas_task_abort(struct sas_task *); int sas_eh_abort_handler(struct scsi_cmnd *cmd); int sas_eh_device_reset_handler(struct scsi_cmnd *cmd); -int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd); +int sas_eh_target_reset_handler(struct scsi_cmnd *cmd); extern void sas_target_destroy(struct scsi_target *); extern int sas_slave_alloc(struct scsi_device *); extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); extern int sas_drain_work(struct sas_ha_struct *ha); -extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, - struct request *req); - extern void sas_ssp_task_response(struct device *dev, struct sas_task *task, struct ssp_response_iu *iu); struct sas_phy *sas_get_local_phy(struct domain_device *dev); diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a1266d318c855dec12dbb41a6bb1ab9e4dc27f08..3d3f8b342e05d14e76d912251a36d6111ab4da88 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -57,6 +57,10 @@ struct scsi_pointer { /* for scmd->flags */ #define SCMD_TAGGED (1 << 0) #define SCMD_UNCHECKED_ISA_DMA (1 << 1) +#define SCMD_ZONE_WRITE_LOCK (1 << 2) +#define SCMD_INITIALIZED (1 << 3) +/* flags preserved across unprep / reprep */ +#define SCMD_PRESERVED_FLAGS (SCMD_UNCHECKED_ISA_DMA | SCMD_INITIALIZED) struct scsi_cmnd { struct scsi_request req; @@ -158,7 +162,6 @@ static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) return *(struct scsi_driver **)cmd->request->rq_disk->private_data; } -extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); extern void scsi_finish_command(struct scsi_cmnd *cmd); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 0979a5f3b69a30ce384db82728fb28ad6a136a6d..67c5a9f223f77aa19d6f5c8b7badba1ecf138299 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -80,6 +80,18 @@ struct scsi_event { */ }; +/** + * struct scsi_vpd - SCSI Vital Product Data + * @rcu: For kfree_rcu(). + * @len: Length in bytes of @data. + * @data: VPD data as defined in various T10 SCSI standard documents. + */ +struct scsi_vpd { + struct rcu_head rcu; + int len; + unsigned char data[]; +}; + struct scsi_device { struct Scsi_Host *host; struct request_queue *request_queue; @@ -111,7 +123,7 @@ struct scsi_device { unsigned sector_size; /* size in bytes */ void *hostdata; /* available to low-level driver */ - char type; + unsigned char type; char scsi_level; char inq_periph_qual; /* PQ from INQUIRY data */ struct mutex inquiry_mutex; @@ -122,10 +134,8 @@ struct scsi_device { const char * rev; /* ... "nullnullnullnull" before scan */ #define SCSI_VPD_PG_LEN 255 - int vpd_pg83_len; - unsigned char __rcu *vpd_pg83; - int vpd_pg80_len; - unsigned char __rcu *vpd_pg80; + struct scsi_vpd __rcu *vpd_pg83; + struct scsi_vpd __rcu *vpd_pg80; unsigned char current_tag; /* current tag */ struct scsi_target *sdev_target; /* used only for single_lun */ @@ -182,6 +192,7 @@ struct scsi_device { unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ unsigned broken_fua:1; /* Don't set FUA bit */ unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */ + unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */ atomic_t disk_events_disable_depth; /* disable depth for disk events */ diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index 9592570e092a3bba93065d6e66a21665f8bd52ae..36b03013d6291cf9fda3c99eec690d3841f0ca5e 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -29,5 +29,6 @@ #define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */ #define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */ #define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */ +#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */ #endif diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index afb04811b7b9c578f24d8360ace4f85efa07632c..0a804b1a47267d5195deff92dba1f637d9de5bef 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -691,12 +691,6 @@ struct Scsi_Host { unsigned int prot_capabilities; unsigned char prot_guard_type; - /* - * q used for scsi_tgt msgs, async events or any other requests that - * need to be processed in userspace - */ - struct request_queue *uspace_req_q; - /* legacy crap */ unsigned long base; unsigned long io_port; diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index 4416b1026189c182bb75fbc5f677f587007522a7..5b416debf101c091874fcd4c94a1ef21433d4abf 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h @@ -39,7 +39,7 @@ static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, if (!req) return NULL; - return req->special; + return blk_mq_rq_to_pdu(req); } #endif /* CONFIG_BLOCK */ diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index e308cd59e5561944ed12b9f5a94b90957377b285..e8644eea9fe56441d16ba78a8ea50f5b35d86f07 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -804,6 +804,7 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel, struct fc_vport_identifiers *); int fc_vport_terminate(struct fc_vport *vport); +int fc_block_rport(struct fc_rport *rport); int fc_block_scsi_eh(struct scsi_cmnd *cmnd); enum blk_eh_timer_return fc_eh_timed_out(struct scsi_cmnd *scmd); diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 6183d20a01fbe8f94bff514c8c8caa7585185b62..b266d2a3bcb1d099ed4a16237a8f06ab820714d5 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -434,7 +434,6 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, unsigned int target_id); extern void iscsi_remove_session(struct iscsi_cls_session *session); extern void iscsi_free_session(struct iscsi_cls_session *session); -extern int iscsi_destroy_session(struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, int dd_size, uint32_t cid); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 73d870918939e082295a90bd9a092814dd97131b..a23304b7fb2e6837003a0d51297f4ebc9b3f0e52 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -5,6 +5,7 @@ #include #include #include +#include struct scsi_transport_template; struct sas_rphy; @@ -176,7 +177,8 @@ struct sas_function_template { int (*phy_setup)(struct sas_phy *); void (*phy_release)(struct sas_phy *); int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); - int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); + void (*smp_handler)(struct bsg_job *, struct Scsi_Host *, + struct sas_rphy *); }; diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h index dd096330734e3656829776f05ab20d02ba9a8d73..56ae198acc7378cffe6e8e1cb1c5019ee91c47c1 100644 --- a/include/scsi/scsi_transport_srp.h +++ b/include/scsi/scsi_transport_srp.h @@ -111,7 +111,7 @@ extern struct srp_rport *srp_rport_add(struct Scsi_Host *, struct srp_rport_identifiers *); extern void srp_rport_del(struct srp_rport *); extern int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo, - int dev_loss_tmo); + long dev_loss_tmo); int srp_parse_tmo(int *tmo, const char *buf); extern int srp_reconnect_rport(struct srp_rport *rport); extern void srp_start_tl_fail_timers(struct srp_rport *rport); diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h index 8893c5eacd07e1ed5169bba2cff3ebf5ab6dc562..5201e9022c86fa90a580735d886dddfa7e9144dd 100644 --- a/include/soc/mediatek/smi.h +++ b/include/soc/mediatek/smi.h @@ -19,7 +19,7 @@ #ifdef CONFIG_MTK_SMI -#define MTK_LARB_NR_MAX 8 +#define MTK_LARB_NR_MAX 16 #define MTK_SMI_MMU_EN(port) BIT(port) diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index b4c9219e7f95659b803d1c7cd3f042ef7aa61022..9b6ea0c7211780182c4cce20735ade7ef673695d 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h @@ -65,6 +65,8 @@ int tegra_fuse_readl(unsigned long offset, u32 *value); extern struct tegra_sku_info tegra_sku_info; +struct device *tegra_soc_device_register(void); + #endif /* __ASSEMBLY__ */ #endif /* __SOC_TEGRA_FUSE_H__ */ diff --git a/include/sound/atmel-abdac.h b/include/sound/atmel-abdac.h deleted file mode 100644 index a8f735d677fa5b29f49c7f64efffdf67e4c38c09..0000000000000000000000000000000000000000 --- a/include/sound/atmel-abdac.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Driver for the Atmel Audio Bitstream DAC (ABDAC) - * - * Copyright (C) 2009 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ -#ifndef __INCLUDE_SOUND_ATMEL_ABDAC_H -#define __INCLUDE_SOUND_ATMEL_ABDAC_H - -#include - -/** - * struct atmel_abdac_pdata - board specific ABDAC configuration - * @dws: DMA slave interface to use for sound playback. - */ -struct atmel_abdac_pdata { - struct dw_dma_slave dws; -}; - -#endif /* __INCLUDE_SOUND_ATMEL_ABDAC_H */ diff --git a/include/sound/atmel-ac97c.h b/include/sound/atmel-ac97c.h deleted file mode 100644 index f2a1cdc3766116d9f8ac4899e3b42c1392983e30..0000000000000000000000000000000000000000 --- a/include/sound/atmel-ac97c.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Driver for the Atmel AC97C controller - * - * Copyright (C) 2005-2009 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ -#ifndef __INCLUDE_SOUND_ATMEL_AC97C_H -#define __INCLUDE_SOUND_ATMEL_AC97C_H - -#include - -#define AC97C_CAPTURE 0x01 -#define AC97C_PLAYBACK 0x02 -#define AC97C_BOTH (AC97C_CAPTURE | AC97C_PLAYBACK) - -/** - * struct atmel_ac97c_pdata - board specific AC97C configuration - * @rx_dws: DMA slave interface to use for sound capture. - * @tx_dws: DMA slave interface to use for sound playback. - * @reset_pin: GPIO pin wired to the reset input on the external AC97 codec, - * optional to use, set to -ENODEV if not in use. AC97 layer will - * try to do a software reset of the external codec anyway. - * - * If the user do not want to use a DMA channel for playback or capture, i.e. - * only one feature is required on the board. The slave for playback or capture - * can be set to NULL. The AC97C driver will take use of this when setting up - * the sound streams. - */ -struct ac97c_platform_data { - struct dw_dma_slave rx_dws; - struct dw_dma_slave tx_dws; - int reset_pin; -}; - -#endif /* __INCLUDE_SOUND_ATMEL_AC97C_H */ diff --git a/include/sound/core.h b/include/sound/core.h index 55385588eefa082e28811f6b61a1c3da56f32b0f..4104a9d1001fcb0f14709c0ad029561e6b03eefe 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -118,8 +118,6 @@ struct snd_card { int user_ctl_count; /* count of all user controls */ struct list_head controls; /* all controls for this card */ struct list_head ctl_files; /* active control files */ - struct mutex user_ctl_lock; /* protects user controls against - concurrent access */ struct snd_info_entry *proc_root; /* root for soundcard specific files */ struct snd_info_entry *proc_id; /* the card id */ @@ -138,7 +136,6 @@ struct snd_card { #ifdef CONFIG_PM unsigned int power_state; /* power state */ - struct mutex power_lock; /* power lock */ wait_queue_head_t power_sleep; #endif @@ -151,16 +148,6 @@ struct snd_card { #define dev_to_snd_card(p) container_of(p, struct snd_card, card_dev) #ifdef CONFIG_PM -static inline void snd_power_lock(struct snd_card *card) -{ - mutex_lock(&card->power_lock); -} - -static inline void snd_power_unlock(struct snd_card *card) -{ - mutex_unlock(&card->power_lock); -} - static inline unsigned int snd_power_get_state(struct snd_card *card) { return card->power_state; @@ -177,8 +164,6 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state); #else /* ! CONFIG_PM */ -#define snd_power_lock(card) do { (void)(card); } while (0) -#define snd_power_unlock(card) do { (void)(card); } while (0) static inline int snd_power_wait(struct snd_card *card, unsigned int state) { return 0; } #define snd_power_get_state(card) ({ (void)(card); SNDRV_CTL_POWER_D0; }) #define snd_power_change_state(card, state) do { (void)(card); } while (0) diff --git a/include/sound/hda_verbs.h b/include/sound/hda_verbs.h index d0509db6d0ec56b8034388dcf1d3492c2dd7955e..f89cd5ee1c7aae51f6975d31b5e43007fc4499e0 100644 --- a/include/sound/hda_verbs.h +++ b/include/sound/hda_verbs.h @@ -95,6 +95,7 @@ enum { #define AC_VERB_SET_EAPD_BTLENABLE 0x70c #define AC_VERB_SET_DIGI_CONVERT_1 0x70d #define AC_VERB_SET_DIGI_CONVERT_2 0x70e +#define AC_VERB_SET_DIGI_CONVERT_3 0x73e #define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f #define AC_VERB_SET_GPIO_DATA 0x715 #define AC_VERB_SET_GPIO_MASK 0x716 diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h index 1df2ff61a4dd95dda25c5962a6335cc6fb9ca44f..0e495ed8872ee14750c6647edf169ccc2946144b 100644 --- a/include/sound/omap-hdmi-audio.h +++ b/include/sound/omap-hdmi-audio.h @@ -39,7 +39,7 @@ struct omap_hdmi_audio_ops { /* HDMI audio initalization data */ struct omap_hdmi_audio_pdata { struct device *dev; - enum omapdss_version dss_version; + unsigned int version; phys_addr_t audio_dma_addr; const struct omap_hdmi_audio_ops *ops; diff --git a/include/sound/rt5663.h b/include/sound/rt5663.h new file mode 100644 index 0000000000000000000000000000000000000000..7d00e58497063d35daa35be5448f5a8b96e26d5c --- /dev/null +++ b/include/sound/rt5663.h @@ -0,0 +1,22 @@ +/* + * linux/sound/rt5663.h -- Platform data for RT5663 + * + * Copyright 2017 Realtek Semiconductor Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_SND_RT5663_H +#define __LINUX_SND_RT5663_H + +struct rt5663_platform_data { + unsigned int dc_offset_l_manual; + unsigned int dc_offset_r_manual; + unsigned int dc_offset_l_manual_mic; + unsigned int dc_offset_r_manual_mic; +}; + +#endif + diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h deleted file mode 100644 index a6207043ac3c7f80f1def8b4fb2025f0dd1a05ca..0000000000000000000000000000000000000000 --- a/include/sound/rt5677.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/sound/rt5677.h -- Platform data for RT5677 - * - * Copyright 2013 Realtek Semiconductor Corp. - * Author: Oder Chiou - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __LINUX_SND_RT5677_H -#define __LINUX_SND_RT5677_H - -enum rt5677_dmic2_clk { - RT5677_DMIC_CLK1 = 0, - RT5677_DMIC_CLK2 = 1, -}; - - -struct rt5677_platform_data { - /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ - bool in1_diff; - bool in2_diff; - bool lout1_diff; - bool lout2_diff; - bool lout3_diff; - /* DMIC2 clock source selection */ - enum rt5677_dmic2_clk dmic2_clk_pin; - - /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ - u8 gpio_config[6]; - - /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */ - unsigned int jd1_gpio; - /* jd2 and jd3 can select 0 ~ 3 as - OFF, GPIO4, GPIO5 and GPIO6 respectively */ - unsigned int jd2_gpio; - unsigned int jd3_gpio; - - /* Set MICBIAS1 VDD 1v8 or 3v3 */ - bool micbias1_vdd_3v3; -}; - -#endif diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 42c6a6ac3ce60d6ab81fc4e726e6dfe0129804ff..7e25afce6566fe315496979c9da9f6176d3fae20 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -15,6 +15,7 @@ struct asoc_simple_dai { const char *name; unsigned int sysclk; + int clk_direction; int slots; int slot_width; unsigned int tx_slot_mask; diff --git a/include/sound/soc.h b/include/sound/soc.h index 9c94b97c17f8ebc830f9ccac9e00c9a0b0e1d463..d22de9712c451d67a9ee068ab8001589f55901bd 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -469,10 +469,10 @@ int snd_soc_register_codec(struct device *dev, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_codec(struct device *dev); int snd_soc_register_component(struct device *dev, - const struct snd_soc_component_driver *cmpnt_drv, + const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai); int devm_snd_soc_register_component(struct device *dev, - const struct snd_soc_component_driver *cmpnt_drv, + const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_component(struct device *dev); int snd_soc_cache_init(struct snd_soc_codec *codec); @@ -795,9 +795,13 @@ struct snd_soc_component_driver { int (*suspend)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *); - /* pcm creation and destruction */ - int (*pcm_new)(struct snd_soc_pcm_runtime *); - void (*pcm_free)(struct snd_pcm *); + /* component wide operations */ + int (*set_sysclk)(struct snd_soc_component *component, + int clk_id, int source, unsigned int freq, int dir); + int (*set_pll)(struct snd_soc_component *component, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out); + int (*set_jack)(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data); /* DT */ int (*of_xlate_dai_name)(struct snd_soc_component *component, @@ -862,20 +866,19 @@ struct snd_soc_component { /* Don't use these, use snd_soc_component_get_dapm() */ struct snd_soc_dapm_context dapm; - const struct snd_kcontrol_new *controls; - unsigned int num_controls; - const struct snd_soc_dapm_widget *dapm_widgets; - unsigned int num_dapm_widgets; - const struct snd_soc_dapm_route *dapm_routes; - unsigned int num_dapm_routes; struct snd_soc_codec *codec; int (*probe)(struct snd_soc_component *); void (*remove)(struct snd_soc_component *); int (*suspend)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *); - int (*pcm_new)(struct snd_soc_pcm_runtime *); - void (*pcm_free)(struct snd_pcm *); + + int (*set_sysclk)(struct snd_soc_component *component, + int clk_id, int source, unsigned int freq, int dir); + int (*set_pll)(struct snd_soc_component *component, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out); + int (*set_jack)(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data); /* machine specific init */ int (*init)(struct snd_soc_component *component); @@ -886,6 +889,18 @@ struct snd_soc_component { #endif }; +struct snd_soc_rtdcom_list { + struct snd_soc_component *component; + struct list_head list; /* rtd::component_list */ +}; +struct snd_soc_component* +snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, + const char *driver_name); +#define for_each_rtdcom(rtd, rtdcom) \ + list_for_each_entry(rtdcom, &(rtd)->component_list, list) +#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \ + list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list) + /* SoC Audio Codec device */ struct snd_soc_codec { struct device *dev; @@ -894,7 +909,6 @@ struct snd_soc_codec { struct list_head list; /* runtime */ - unsigned int cache_bypass:1; /* Suppress access to the cache */ unsigned int cache_init:1; /* codec cache has been initialized */ /* codec IO */ @@ -904,10 +918,6 @@ struct snd_soc_codec { /* component */ struct snd_soc_component component; - -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs_reg; -#endif }; /* codec driver */ @@ -1230,7 +1240,7 @@ struct snd_soc_pcm_runtime { struct snd_pcm *pcm; struct snd_compr *compr; struct snd_soc_codec *codec; - struct snd_soc_platform *platform; + struct snd_soc_platform *platform; /* will be removed */ struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; @@ -1240,11 +1250,11 @@ struct snd_soc_pcm_runtime { struct delayed_work delayed_work; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dpcm_root; - struct dentry *debugfs_dpcm_state; #endif unsigned int num; /* 0-based and monotonic increasing */ struct list_head list; /* rtd list of the soc card */ + struct list_head component_list; /* list of connected components */ /* bit field */ unsigned int dev_registered:1; @@ -1471,6 +1481,13 @@ void snd_soc_component_async_complete(struct snd_soc_component *component); int snd_soc_component_test_bits(struct snd_soc_component *component, unsigned int reg, unsigned int mask, unsigned int value); +/* component wide operations */ +int snd_soc_component_set_sysclk(struct snd_soc_component *component, + int clk_id, int source, unsigned int freq, int dir); +int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, + int source, unsigned int freq_in, + unsigned int freq_out); + #ifdef CONFIG_REGMAP void snd_soc_component_init_regmap(struct snd_soc_component *component, diff --git a/include/sound/tlv320aic32x4.h b/include/sound/tlv320aic32x4.h index 24e5d991f148be2d8b16cc309e1af7dca5f5f14b..22305c0ab31a9cfabeee28596bac9317af377c0f 100644 --- a/include/sound/tlv320aic32x4.h +++ b/include/sound/tlv320aic32x4.h @@ -22,7 +22,30 @@ #define AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K 0x00000001 #define AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K 0x00000002 +/* GPIO API */ +#define AIC32X4_MFPX_DEFAULT_VALUE 0xff + +#define AIC32X4_MFP1_DIN_DISABLED 0 +#define AIC32X4_MFP1_DIN_ENABLED 0x2 +#define AIC32X4_MFP1_GPIO_IN 0x4 + +#define AIC32X4_MFP2_GPIO_OUT_LOW 0x0 +#define AIC32X4_MFP2_GPIO_OUT_HIGH 0x1 + +#define AIC32X4_MFP_GPIO_ENABLED 0x4 + +#define AIC32X4_MFP5_GPIO_DISABLED 0x0 +#define AIC32X4_MFP5_GPIO_INPUT 0x8 +#define AIC32X4_MFP5_GPIO_OUTPUT 0xc +#define AIC32X4_MFP5_GPIO_OUT_LOW 0x0 +#define AIC32X4_MFP5_GPIO_OUT_HIGH 0x1 + +struct aic32x4_setup_data { + unsigned int gpio_func[5]; +}; + struct aic32x4_pdata { + struct aic32x4_setup_data *setup; u32 power_cfg; u32 micpga_routing; bool swapdacs; diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 0ca1fb08805b254fa8ffda73f4decd4c48ac2211..fb87d32f5e513de3c2a1b7c6f402b5f48e401c45 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -786,6 +786,7 @@ struct iscsi_np { int np_sock_type; enum np_thread_state_table np_thread_state; bool enabled; + atomic_t np_reset_count; enum iscsi_timer_flags_table np_login_timer_flags; u32 np_exports; enum np_flags_table np_flags; diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h index df3e9ae5ad8d2b4e2aace80bd8c189fd09098c28..daf749138ff80c9fb6c12b1940168fa2f33cea7f 100644 --- a/include/trace/events/bcache.h +++ b/include/trace/events/bcache.h @@ -21,7 +21,7 @@ DECLARE_EVENT_CLASS(bcache_request, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->orig_major = d->disk->major; __entry->orig_minor = d->disk->first_minor; __entry->sector = bio->bi_iter.bi_sector; @@ -98,7 +98,7 @@ DECLARE_EVENT_CLASS(bcache_bio, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio->bi_iter.bi_size >> 9; blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); @@ -133,7 +133,7 @@ TRACE_EVENT(bcache_read, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio->bi_iter.bi_size >> 9; blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); diff --git a/include/trace/events/block.h b/include/trace/events/block.h index d0dbe60d8a6dd5ccbb89029796fcabd23d970ceb..1fd7ff1a46f792d3a69a006e2406f86d87100cf3 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h @@ -236,8 +236,7 @@ TRACE_EVENT(block_bio_bounce, ), TP_fast_assign( - __entry->dev = bio->bi_bdev ? - bio->bi_bdev->bd_dev : 0; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio_sectors(bio); blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); @@ -274,7 +273,7 @@ TRACE_EVENT(block_bio_complete, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio_sectors(bio); __entry->error = error; @@ -302,7 +301,7 @@ DECLARE_EVENT_CLASS(block_bio_merge, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio_sectors(bio); blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); @@ -369,7 +368,7 @@ TRACE_EVENT(block_bio_queue, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio_sectors(bio); blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); @@ -397,7 +396,7 @@ DECLARE_EVENT_CLASS(block_get_rq, ), TP_fast_assign( - __entry->dev = bio ? bio->bi_bdev->bd_dev : 0; + __entry->dev = bio ? bio_dev(bio) : 0; __entry->sector = bio ? bio->bi_iter.bi_sector : 0; __entry->nr_sector = bio ? bio_sectors(bio) : 0; blk_fill_rwbs(__entry->rwbs, @@ -414,7 +413,7 @@ DECLARE_EVENT_CLASS(block_get_rq, /** * block_getrq - get a free request entry in queue for block IO operations * @q: queue for operations - * @bio: pending block IO operation + * @bio: pending block IO operation (can be %NULL) * @rw: low bit indicates a read (%0) or a write (%1) * * A request struct for queue @q has been allocated to handle the @@ -430,7 +429,7 @@ DEFINE_EVENT(block_get_rq, block_getrq, /** * block_sleeprq - waiting to get a free request entry in queue for block IO operation * @q: queue for operation - * @bio: pending block IO operation + * @bio: pending block IO operation (can be %NULL) * @rw: low bit indicates a read (%0) or a write (%1) * * In the case where a request struct cannot be provided for queue @q @@ -532,7 +531,7 @@ TRACE_EVENT(block_split, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->new_sector = new_sector; blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); @@ -573,7 +572,7 @@ TRACE_EVENT(block_bio_remap, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio_dev(bio); __entry->sector = bio->bi_iter.bi_sector; __entry->nr_sector = bio_sectors(bio); __entry->old_dev = dev; diff --git a/include/trace/events/bridge.h b/include/trace/events/bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..1bee3e7fdf32cd9028f765ffbe24b4e8218cd12a --- /dev/null +++ b/include/trace/events/bridge.h @@ -0,0 +1,129 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM bridge + +#if !defined(_TRACE_BRIDGE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_BRIDGE_H + +#include +#include + +#include "../../../net/bridge/br_private.h" + +TRACE_EVENT(br_fdb_add, + + TP_PROTO(struct ndmsg *ndm, struct net_device *dev, + const unsigned char *addr, u16 vid, u16 nlh_flags), + + TP_ARGS(ndm, dev, addr, vid, nlh_flags), + + TP_STRUCT__entry( + __field(u8, ndm_flags) + __string(dev, dev->name) + __array(unsigned char, addr, ETH_ALEN) + __field(u16, vid) + __field(u16, nlh_flags) + ), + + TP_fast_assign( + __assign_str(dev, dev->name); + memcpy(__entry->addr, addr, ETH_ALEN); + __entry->vid = vid; + __entry->nlh_flags = nlh_flags; + __entry->ndm_flags = ndm->ndm_flags; + ), + + TP_printk("dev %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u nlh_flags %04x ndm_flags %02x", + __get_str(dev), __entry->addr[0], __entry->addr[1], + __entry->addr[2], __entry->addr[3], __entry->addr[4], + __entry->addr[5], __entry->vid, + __entry->nlh_flags, __entry->ndm_flags) +); + +TRACE_EVENT(br_fdb_external_learn_add, + + TP_PROTO(struct net_bridge *br, struct net_bridge_port *p, + const unsigned char *addr, u16 vid), + + TP_ARGS(br, p, addr, vid), + + TP_STRUCT__entry( + __string(br_dev, br->dev->name) + __string(dev, p ? p->dev->name : "null") + __array(unsigned char, addr, ETH_ALEN) + __field(u16, vid) + ), + + TP_fast_assign( + __assign_str(br_dev, br->dev->name); + __assign_str(dev, p ? p->dev->name : "null"); + memcpy(__entry->addr, addr, ETH_ALEN); + __entry->vid = vid; + ), + + TP_printk("br_dev %s port %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u", + __get_str(br_dev), __get_str(dev), __entry->addr[0], + __entry->addr[1], __entry->addr[2], __entry->addr[3], + __entry->addr[4], __entry->addr[5], __entry->vid) +); + +TRACE_EVENT(fdb_delete, + + TP_PROTO(struct net_bridge *br, struct net_bridge_fdb_entry *f), + + TP_ARGS(br, f), + + TP_STRUCT__entry( + __string(br_dev, br->dev->name) + __string(dev, f->dst ? f->dst->dev->name : "null") + __array(unsigned char, addr, ETH_ALEN) + __field(u16, vid) + ), + + TP_fast_assign( + __assign_str(br_dev, br->dev->name); + __assign_str(dev, f->dst ? f->dst->dev->name : "null"); + memcpy(__entry->addr, f->addr.addr, ETH_ALEN); + __entry->vid = f->vlan_id; + ), + + TP_printk("br_dev %s dev %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u", + __get_str(br_dev), __get_str(dev), __entry->addr[0], + __entry->addr[1], __entry->addr[2], __entry->addr[3], + __entry->addr[4], __entry->addr[5], __entry->vid) +); + +TRACE_EVENT(br_fdb_update, + + TP_PROTO(struct net_bridge *br, struct net_bridge_port *source, + const unsigned char *addr, u16 vid, bool added_by_user), + + TP_ARGS(br, source, addr, vid, added_by_user), + + TP_STRUCT__entry( + __string(br_dev, br->dev->name) + __string(dev, source->dev->name) + __array(unsigned char, addr, ETH_ALEN) + __field(u16, vid) + __field(bool, added_by_user) + ), + + TP_fast_assign( + __assign_str(br_dev, br->dev->name); + __assign_str(dev, source->dev->name); + memcpy(__entry->addr, addr, ETH_ALEN); + __entry->vid = vid; + __entry->added_by_user = added_by_user; + ), + + TP_printk("br_dev %s source %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u added_by_user %d", + __get_str(br_dev), __get_str(dev), __entry->addr[0], + __entry->addr[1], __entry->addr[2], __entry->addr[3], + __entry->addr[4], __entry->addr[5], __entry->vid, + __entry->added_by_user) +); + + +#endif /* _TRACE_BRIDGE_H */ + +/* This part must be outside protection */ +#include diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index cd99a3658156bc8229a54a15a56917f19f74502c..dc1d0df91e0b0ee193f6c0b58184fb1272cf1c70 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -26,6 +26,7 @@ struct btrfs_work; struct __btrfs_workqueue; struct btrfs_qgroup_extent_record; struct btrfs_qgroup; +struct prelim_ref; #define show_ref_type(type) \ __print_symbolic(type, \ @@ -73,11 +74,11 @@ struct btrfs_qgroup; { BTRFS_BLOCK_GROUP_RAID5, "RAID5"}, \ { BTRFS_BLOCK_GROUP_RAID6, "RAID6"} -#define BTRFS_UUID_SIZE 16 -#define TP_STRUCT__entry_fsid __array(u8, fsid, BTRFS_UUID_SIZE) +#define BTRFS_FSID_SIZE 16 +#define TP_STRUCT__entry_fsid __array(u8, fsid, BTRFS_FSID_SIZE) #define TP_fast_assign_fsid(fs_info) \ - memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE) + memcpy(__entry->fsid, fs_info->fsid, BTRFS_FSID_SIZE) #define TP_STRUCT__entry_btrfs(args...) \ TP_STRUCT__entry( \ @@ -92,7 +93,7 @@ struct btrfs_qgroup; TRACE_EVENT(btrfs_transaction_commit, - TP_PROTO(struct btrfs_root *root), + TP_PROTO(const struct btrfs_root *root), TP_ARGS(root), @@ -113,7 +114,7 @@ TRACE_EVENT(btrfs_transaction_commit, DECLARE_EVENT_CLASS(btrfs__inode, - TP_PROTO(struct inode *inode), + TP_PROTO(const struct inode *inode), TP_ARGS(inode), @@ -151,21 +152,21 @@ DECLARE_EVENT_CLASS(btrfs__inode, DEFINE_EVENT(btrfs__inode, btrfs_inode_new, - TP_PROTO(struct inode *inode), + TP_PROTO(const struct inode *inode), TP_ARGS(inode) ); DEFINE_EVENT(btrfs__inode, btrfs_inode_request, - TP_PROTO(struct inode *inode), + TP_PROTO(const struct inode *inode), TP_ARGS(inode) ); DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, - TP_PROTO(struct inode *inode), + TP_PROTO(const struct inode *inode), TP_ARGS(inode) ); @@ -192,8 +193,8 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, TRACE_EVENT_CONDITION(btrfs_get_extent, - TP_PROTO(struct btrfs_root *root, struct btrfs_inode *inode, - struct extent_map *map), + TP_PROTO(const struct btrfs_root *root, const struct btrfs_inode *inode, + const struct extent_map *map), TP_ARGS(root, inode, map), @@ -388,7 +389,8 @@ DEFINE_EVENT( DECLARE_EVENT_CLASS(btrfs__ordered_extent, - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), + TP_PROTO(const struct inode *inode, + const struct btrfs_ordered_extent *ordered), TP_ARGS(inode, ordered), @@ -440,36 +442,40 @@ DECLARE_EVENT_CLASS(btrfs__ordered_extent, DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_add, - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), + TP_PROTO(const struct inode *inode, + const struct btrfs_ordered_extent *ordered), TP_ARGS(inode, ordered) ); DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_remove, - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), + TP_PROTO(const struct inode *inode, + const struct btrfs_ordered_extent *ordered), TP_ARGS(inode, ordered) ); DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_start, - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), + TP_PROTO(const struct inode *inode, + const struct btrfs_ordered_extent *ordered), TP_ARGS(inode, ordered) ); DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_put, - TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered), + TP_PROTO(const struct inode *inode, + const struct btrfs_ordered_extent *ordered), TP_ARGS(inode, ordered) ); DECLARE_EVENT_CLASS(btrfs__writepage, - TP_PROTO(struct page *page, struct inode *inode, - struct writeback_control *wbc), + TP_PROTO(const struct page *page, const struct inode *inode, + const struct writeback_control *wbc), TP_ARGS(page, inode, wbc), @@ -517,15 +523,15 @@ DECLARE_EVENT_CLASS(btrfs__writepage, DEFINE_EVENT(btrfs__writepage, __extent_writepage, - TP_PROTO(struct page *page, struct inode *inode, - struct writeback_control *wbc), + TP_PROTO(const struct page *page, const struct inode *inode, + const struct writeback_control *wbc), TP_ARGS(page, inode, wbc) ); TRACE_EVENT(btrfs_writepage_end_io_hook, - TP_PROTO(struct page *page, u64 start, u64 end, int uptodate), + TP_PROTO(const struct page *page, u64 start, u64 end, int uptodate), TP_ARGS(page, start, end, uptodate), @@ -558,7 +564,7 @@ TRACE_EVENT(btrfs_writepage_end_io_hook, TRACE_EVENT(btrfs_sync_file, - TP_PROTO(struct file *file, int datasync), + TP_PROTO(const struct file *file, int datasync), TP_ARGS(file, datasync), @@ -570,8 +576,8 @@ TRACE_EVENT(btrfs_sync_file, ), TP_fast_assign( - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = d_inode(dentry); + const struct dentry *dentry = file->f_path.dentry; + const struct inode *inode = d_inode(dentry); TP_fast_assign_fsid(btrfs_sb(file->f_path.dentry->d_sb)); __entry->ino = inode->i_ino; @@ -589,7 +595,7 @@ TRACE_EVENT(btrfs_sync_file, TRACE_EVENT(btrfs_sync_fs, - TP_PROTO(struct btrfs_fs_info *fs_info, int wait), + TP_PROTO(const struct btrfs_fs_info *fs_info, int wait), TP_ARGS(fs_info, wait), @@ -606,13 +612,13 @@ TRACE_EVENT(btrfs_sync_fs, TRACE_EVENT(btrfs_add_block_group, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_block_group_cache *block_group, int create), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_block_group_cache *block_group, int create), TP_ARGS(fs_info, block_group, create), TP_STRUCT__entry( - __array( u8, fsid, BTRFS_UUID_SIZE ) + __array( u8, fsid, BTRFS_FSID_SIZE ) __field( u64, offset ) __field( u64, size ) __field( u64, flags ) @@ -622,7 +628,7 @@ TRACE_EVENT(btrfs_add_block_group, ), TP_fast_assign( - memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE); + memcpy(__entry->fsid, fs_info->fsid, BTRFS_FSID_SIZE); __entry->offset = block_group->key.objectid; __entry->size = block_group->key.offset; __entry->flags = block_group->flags; @@ -654,9 +660,9 @@ TRACE_EVENT(btrfs_add_block_group, DECLARE_EVENT_CLASS(btrfs_delayed_tree_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_tree_ref *full_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_tree_ref *full_ref, int action), TP_ARGS(fs_info, ref, full_ref, action), @@ -697,9 +703,9 @@ DECLARE_EVENT_CLASS(btrfs_delayed_tree_ref, DEFINE_EVENT(btrfs_delayed_tree_ref, add_delayed_tree_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_tree_ref *full_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_tree_ref *full_ref, int action), TP_ARGS(fs_info, ref, full_ref, action) @@ -707,9 +713,9 @@ DEFINE_EVENT(btrfs_delayed_tree_ref, add_delayed_tree_ref, DEFINE_EVENT(btrfs_delayed_tree_ref, run_delayed_tree_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_tree_ref *full_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_tree_ref *full_ref, int action), TP_ARGS(fs_info, ref, full_ref, action) @@ -717,9 +723,9 @@ DEFINE_EVENT(btrfs_delayed_tree_ref, run_delayed_tree_ref, DECLARE_EVENT_CLASS(btrfs_delayed_data_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_data_ref *full_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_data_ref *full_ref, int action), TP_ARGS(fs_info, ref, full_ref, action), @@ -764,9 +770,9 @@ DECLARE_EVENT_CLASS(btrfs_delayed_data_ref, DEFINE_EVENT(btrfs_delayed_data_ref, add_delayed_data_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_data_ref *full_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_data_ref *full_ref, int action), TP_ARGS(fs_info, ref, full_ref, action) @@ -774,9 +780,9 @@ DEFINE_EVENT(btrfs_delayed_data_ref, add_delayed_data_ref, DEFINE_EVENT(btrfs_delayed_data_ref, run_delayed_data_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_data_ref *full_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_data_ref *full_ref, int action), TP_ARGS(fs_info, ref, full_ref, action) @@ -784,9 +790,9 @@ DEFINE_EVENT(btrfs_delayed_data_ref, run_delayed_data_ref, DECLARE_EVENT_CLASS(btrfs_delayed_ref_head, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_ref_head *head_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_ref_head *head_ref, int action), TP_ARGS(fs_info, ref, head_ref, action), @@ -814,9 +820,9 @@ DECLARE_EVENT_CLASS(btrfs_delayed_ref_head, DEFINE_EVENT(btrfs_delayed_ref_head, add_delayed_ref_head, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_ref_head *head_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_ref_head *head_ref, int action), TP_ARGS(fs_info, ref, head_ref, action) @@ -824,9 +830,9 @@ DEFINE_EVENT(btrfs_delayed_ref_head, add_delayed_ref_head, DEFINE_EVENT(btrfs_delayed_ref_head, run_delayed_ref_head, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_delayed_ref_node *ref, - struct btrfs_delayed_ref_head *head_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_delayed_ref_node *ref, + const struct btrfs_delayed_ref_head *head_ref, int action), TP_ARGS(fs_info, ref, head_ref, action) @@ -846,8 +852,8 @@ DEFINE_EVENT(btrfs_delayed_ref_head, run_delayed_ref_head, DECLARE_EVENT_CLASS(btrfs__chunk, - TP_PROTO(struct btrfs_fs_info *fs_info, struct map_lookup *map, - u64 offset, u64 size), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct map_lookup *map, u64 offset, u64 size), TP_ARGS(fs_info, map, offset, size), @@ -880,24 +886,24 @@ DECLARE_EVENT_CLASS(btrfs__chunk, DEFINE_EVENT(btrfs__chunk, btrfs_chunk_alloc, - TP_PROTO(struct btrfs_fs_info *fs_info, struct map_lookup *map, - u64 offset, u64 size), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct map_lookup *map, u64 offset, u64 size), TP_ARGS(fs_info, map, offset, size) ); DEFINE_EVENT(btrfs__chunk, btrfs_chunk_free, - TP_PROTO(struct btrfs_fs_info *fs_info, struct map_lookup *map, - u64 offset, u64 size), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct map_lookup *map, u64 offset, u64 size), TP_ARGS(fs_info, map, offset, size) ); TRACE_EVENT(btrfs_cow_block, - TP_PROTO(struct btrfs_root *root, struct extent_buffer *buf, - struct extent_buffer *cow), + TP_PROTO(const struct btrfs_root *root, const struct extent_buffer *buf, + const struct extent_buffer *cow), TP_ARGS(root, buf, cow), @@ -931,7 +937,7 @@ TRACE_EVENT(btrfs_cow_block, TRACE_EVENT(btrfs_space_reservation, - TP_PROTO(struct btrfs_fs_info *fs_info, char *type, u64 val, + TP_PROTO(const struct btrfs_fs_info *fs_info, char *type, u64 val, u64 bytes, int reserve), TP_ARGS(fs_info, type, val, bytes, reserve), @@ -963,13 +969,13 @@ TRACE_EVENT(btrfs_space_reservation, TRACE_EVENT(btrfs_trigger_flush, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 flags, u64 bytes, + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 flags, u64 bytes, int flush, char *reason), TP_ARGS(fs_info, flags, bytes, flush, reason), TP_STRUCT__entry( - __array( u8, fsid, BTRFS_UUID_SIZE ) + __array( u8, fsid, BTRFS_FSID_SIZE ) __field( u64, flags ) __field( u64, bytes ) __field( int, flush ) @@ -977,7 +983,7 @@ TRACE_EVENT(btrfs_trigger_flush, ), TP_fast_assign( - memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE); + memcpy(__entry->fsid, fs_info->fsid, BTRFS_FSID_SIZE); __entry->flags = flags; __entry->bytes = bytes; __entry->flush = flush; @@ -1004,42 +1010,39 @@ TRACE_EVENT(btrfs_trigger_flush, TRACE_EVENT(btrfs_flush_space, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 flags, u64 num_bytes, - u64 orig_bytes, int state, int ret), + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 flags, u64 num_bytes, + int state, int ret), - TP_ARGS(fs_info, flags, num_bytes, orig_bytes, state, ret), + TP_ARGS(fs_info, flags, num_bytes, state, ret), TP_STRUCT__entry( - __array( u8, fsid, BTRFS_UUID_SIZE ) + __array( u8, fsid, BTRFS_FSID_SIZE ) __field( u64, flags ) __field( u64, num_bytes ) - __field( u64, orig_bytes ) __field( int, state ) __field( int, ret ) ), TP_fast_assign( - memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE); + memcpy(__entry->fsid, fs_info->fsid, BTRFS_FSID_SIZE); __entry->flags = flags; __entry->num_bytes = num_bytes; - __entry->orig_bytes = orig_bytes; __entry->state = state; __entry->ret = ret; ), - TP_printk("%pU: state=%d(%s) flags=%llu(%s) num_bytes=%llu " - "orig_bytes=%llu ret=%d", __entry->fsid, __entry->state, + TP_printk("%pU: state=%d(%s) flags=%llu(%s) num_bytes=%llu ret=%d", + __entry->fsid, __entry->state, show_flush_state(__entry->state), (unsigned long long)__entry->flags, __print_flags((unsigned long)__entry->flags, "|", BTRFS_GROUP_FLAGS), - (unsigned long long)__entry->num_bytes, - (unsigned long long)__entry->orig_bytes, __entry->ret) + (unsigned long long)__entry->num_bytes, __entry->ret) ); DECLARE_EVENT_CLASS(btrfs__reserved_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 start, u64 len), + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 start, u64 len), TP_ARGS(fs_info, start, len), @@ -1061,22 +1064,22 @@ DECLARE_EVENT_CLASS(btrfs__reserved_extent, DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_alloc, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 start, u64 len), + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 start, u64 len), TP_ARGS(fs_info, start, len) ); DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_free, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 start, u64 len), + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 start, u64 len), TP_ARGS(fs_info, start, len) ); TRACE_EVENT(find_free_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 num_bytes, u64 empty_size, - u64 data), + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 num_bytes, + u64 empty_size, u64 data), TP_ARGS(fs_info, num_bytes, empty_size, data), @@ -1101,8 +1104,8 @@ TRACE_EVENT(find_free_extent, DECLARE_EVENT_CLASS(btrfs__reserve_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_block_group_cache *block_group, u64 start, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_block_group_cache *block_group, u64 start, u64 len), TP_ARGS(fs_info, block_group, start, len), @@ -1132,8 +1135,8 @@ DECLARE_EVENT_CLASS(btrfs__reserve_extent, DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_block_group_cache *block_group, u64 start, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_block_group_cache *block_group, u64 start, u64 len), TP_ARGS(fs_info, block_group, start, len) @@ -1141,8 +1144,8 @@ DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent, DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent_cluster, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_block_group_cache *block_group, u64 start, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_block_group_cache *block_group, u64 start, u64 len), TP_ARGS(fs_info, block_group, start, len) @@ -1150,7 +1153,7 @@ DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent_cluster, TRACE_EVENT(btrfs_find_cluster, - TP_PROTO(struct btrfs_block_group_cache *block_group, u64 start, + TP_PROTO(const struct btrfs_block_group_cache *block_group, u64 start, u64 bytes, u64 empty_size, u64 min_bytes), TP_ARGS(block_group, start, bytes, empty_size, min_bytes), @@ -1183,7 +1186,7 @@ TRACE_EVENT(btrfs_find_cluster, TRACE_EVENT(btrfs_failed_cluster_setup, - TP_PROTO(struct btrfs_block_group_cache *block_group), + TP_PROTO(const struct btrfs_block_group_cache *block_group), TP_ARGS(block_group), @@ -1200,8 +1203,9 @@ TRACE_EVENT(btrfs_failed_cluster_setup, TRACE_EVENT(btrfs_setup_cluster, - TP_PROTO(struct btrfs_block_group_cache *block_group, - struct btrfs_free_cluster *cluster, u64 size, int bitmap), + TP_PROTO(const struct btrfs_block_group_cache *block_group, + const struct btrfs_free_cluster *cluster, + u64 size, int bitmap), TP_ARGS(block_group, cluster, size, bitmap), @@ -1235,12 +1239,13 @@ TRACE_EVENT(btrfs_setup_cluster, struct extent_state; TRACE_EVENT(alloc_extent_state, - TP_PROTO(struct extent_state *state, gfp_t mask, unsigned long IP), + TP_PROTO(const struct extent_state *state, + gfp_t mask, unsigned long IP), TP_ARGS(state, mask, IP), TP_STRUCT__entry( - __field(struct extent_state *, state) + __field(const struct extent_state *, state) __field(gfp_t, mask) __field(unsigned long, ip) ), @@ -1252,17 +1257,17 @@ TRACE_EVENT(alloc_extent_state, ), TP_printk("state=%p mask=%s caller=%pS", __entry->state, - show_gfp_flags(__entry->mask), (void *)__entry->ip) + show_gfp_flags(__entry->mask), (const void *)__entry->ip) ); TRACE_EVENT(free_extent_state, - TP_PROTO(struct extent_state *state, unsigned long IP), + TP_PROTO(const struct extent_state *state, unsigned long IP), TP_ARGS(state, IP), TP_STRUCT__entry( - __field(struct extent_state *, state) + __field(const struct extent_state *, state) __field(unsigned long, ip) ), @@ -1272,22 +1277,22 @@ TRACE_EVENT(free_extent_state, ), TP_printk("state=%p caller=%pS", __entry->state, - (void *)__entry->ip) + (const void *)__entry->ip) ); DECLARE_EVENT_CLASS(btrfs__work, - TP_PROTO(struct btrfs_work *work), + TP_PROTO(const struct btrfs_work *work), TP_ARGS(work), TP_STRUCT__entry_btrfs( - __field( void *, work ) - __field( void *, wq ) - __field( void *, func ) - __field( void *, ordered_func ) - __field( void *, ordered_free ) - __field( void *, normal_work ) + __field( const void *, work ) + __field( const void *, wq ) + __field( const void *, func ) + __field( const void *, ordered_func ) + __field( const void *, ordered_free ) + __field( const void *, normal_work ) ), TP_fast_assign_btrfs(btrfs_work_owner(work), @@ -1312,12 +1317,12 @@ DECLARE_EVENT_CLASS(btrfs__work, */ DECLARE_EVENT_CLASS(btrfs__work__done, - TP_PROTO(struct btrfs_fs_info *fs_info, void *wtag), + TP_PROTO(const struct btrfs_fs_info *fs_info, const void *wtag), TP_ARGS(fs_info, wtag), TP_STRUCT__entry_btrfs( - __field( void *, wtag ) + __field( const void *, wtag ) ), TP_fast_assign_btrfs(fs_info, @@ -1329,40 +1334,41 @@ DECLARE_EVENT_CLASS(btrfs__work__done, DEFINE_EVENT(btrfs__work, btrfs_work_queued, - TP_PROTO(struct btrfs_work *work), + TP_PROTO(const struct btrfs_work *work), TP_ARGS(work) ); DEFINE_EVENT(btrfs__work, btrfs_work_sched, - TP_PROTO(struct btrfs_work *work), + TP_PROTO(const struct btrfs_work *work), TP_ARGS(work) ); DEFINE_EVENT(btrfs__work__done, btrfs_all_work_done, - TP_PROTO(struct btrfs_fs_info *fs_info, void *wtag), + TP_PROTO(const struct btrfs_fs_info *fs_info, const void *wtag), TP_ARGS(fs_info, wtag) ); DEFINE_EVENT(btrfs__work, btrfs_ordered_sched, - TP_PROTO(struct btrfs_work *work), + TP_PROTO(const struct btrfs_work *work), TP_ARGS(work) ); DECLARE_EVENT_CLASS(btrfs__workqueue, - TP_PROTO(struct __btrfs_workqueue *wq, const char *name, int high), + TP_PROTO(const struct __btrfs_workqueue *wq, + const char *name, int high), TP_ARGS(wq, name, high), TP_STRUCT__entry_btrfs( - __field( void *, wq ) + __field( const void *, wq ) __string( name, name ) __field( int , high ) ), @@ -1381,19 +1387,20 @@ DECLARE_EVENT_CLASS(btrfs__workqueue, DEFINE_EVENT(btrfs__workqueue, btrfs_workqueue_alloc, - TP_PROTO(struct __btrfs_workqueue *wq, const char *name, int high), + TP_PROTO(const struct __btrfs_workqueue *wq, + const char *name, int high), TP_ARGS(wq, name, high) ); DECLARE_EVENT_CLASS(btrfs__workqueue_done, - TP_PROTO(struct __btrfs_workqueue *wq), + TP_PROTO(const struct __btrfs_workqueue *wq), TP_ARGS(wq), TP_STRUCT__entry_btrfs( - __field( void *, wq ) + __field( const void *, wq ) ), TP_fast_assign_btrfs(btrfs_workqueue_owner(wq), @@ -1405,7 +1412,7 @@ DECLARE_EVENT_CLASS(btrfs__workqueue_done, DEFINE_EVENT(btrfs__workqueue_done, btrfs_workqueue_destroy, - TP_PROTO(struct __btrfs_workqueue *wq), + TP_PROTO(const struct __btrfs_workqueue *wq), TP_ARGS(wq) ); @@ -1417,7 +1424,8 @@ DEFINE_EVENT(btrfs__workqueue_done, btrfs_workqueue_destroy, DECLARE_EVENT_CLASS(btrfs__qgroup_rsv_data, - TP_PROTO(struct inode *inode, u64 start, u64 len, u64 reserved, int op), + TP_PROTO(const struct inode *inode, u64 start, u64 len, + u64 reserved, int op), TP_ARGS(inode, start, len, reserved, op), @@ -1449,21 +1457,24 @@ DECLARE_EVENT_CLASS(btrfs__qgroup_rsv_data, DEFINE_EVENT(btrfs__qgroup_rsv_data, btrfs_qgroup_reserve_data, - TP_PROTO(struct inode *inode, u64 start, u64 len, u64 reserved, int op), + TP_PROTO(const struct inode *inode, u64 start, u64 len, + u64 reserved, int op), TP_ARGS(inode, start, len, reserved, op) ); DEFINE_EVENT(btrfs__qgroup_rsv_data, btrfs_qgroup_release_data, - TP_PROTO(struct inode *inode, u64 start, u64 len, u64 reserved, int op), + TP_PROTO(const struct inode *inode, u64 start, u64 len, + u64 reserved, int op), TP_ARGS(inode, start, len, reserved, op) ); DECLARE_EVENT_CLASS(btrfs__qgroup_delayed_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 ref_root, u64 reserved), + TP_PROTO(const struct btrfs_fs_info *fs_info, + u64 ref_root, u64 reserved), TP_ARGS(fs_info, ref_root, reserved), @@ -1483,14 +1494,15 @@ DECLARE_EVENT_CLASS(btrfs__qgroup_delayed_ref, DEFINE_EVENT(btrfs__qgroup_delayed_ref, btrfs_qgroup_free_delayed_ref, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 ref_root, u64 reserved), + TP_PROTO(const struct btrfs_fs_info *fs_info, + u64 ref_root, u64 reserved), TP_ARGS(fs_info, ref_root, reserved) ); DECLARE_EVENT_CLASS(btrfs_qgroup_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_qgroup_extent_record *rec), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_qgroup_extent_record *rec), TP_ARGS(fs_info, rec), @@ -1511,23 +1523,23 @@ DECLARE_EVENT_CLASS(btrfs_qgroup_extent, DEFINE_EVENT(btrfs_qgroup_extent, btrfs_qgroup_account_extents, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_qgroup_extent_record *rec), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_qgroup_extent_record *rec), TP_ARGS(fs_info, rec) ); DEFINE_EVENT(btrfs_qgroup_extent, btrfs_qgroup_trace_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, - struct btrfs_qgroup_extent_record *rec), + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct btrfs_qgroup_extent_record *rec), TP_ARGS(fs_info, rec) ); TRACE_EVENT(btrfs_qgroup_account_extent, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 bytenr, + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes, u64 nr_old_roots, u64 nr_new_roots), TP_ARGS(fs_info, bytenr, num_bytes, nr_old_roots, nr_new_roots), @@ -1556,7 +1568,7 @@ TRACE_EVENT(btrfs_qgroup_account_extent, TRACE_EVENT(qgroup_update_counters, - TP_PROTO(struct btrfs_fs_info *fs_info, u64 qgid, + TP_PROTO(const struct btrfs_fs_info *fs_info, u64 qgid, u64 cur_old_count, u64 cur_new_count), TP_ARGS(fs_info, qgid, cur_old_count, cur_new_count), @@ -1622,6 +1634,63 @@ TRACE_EVENT(qgroup_meta_reserve, show_root_type(__entry->refroot), __entry->diff) ); +DECLARE_EVENT_CLASS(btrfs__prelim_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct prelim_ref *oldref, + const struct prelim_ref *newref, u64 tree_size), + TP_ARGS(fs_info, newref, oldref, tree_size), + + TP_STRUCT__entry_btrfs( + __field( u64, root_id ) + __field( u64, objectid ) + __field( u8, type ) + __field( u64, offset ) + __field( int, level ) + __field( int, old_count ) + __field( u64, parent ) + __field( u64, bytenr ) + __field( int, mod_count ) + __field( u64, tree_size ) + ), + + TP_fast_assign_btrfs(fs_info, + __entry->root_id = oldref->root_id; + __entry->objectid = oldref->key_for_search.objectid; + __entry->type = oldref->key_for_search.type; + __entry->offset = oldref->key_for_search.offset; + __entry->level = oldref->level; + __entry->old_count = oldref->count; + __entry->parent = oldref->parent; + __entry->bytenr = oldref->wanted_disk_byte; + __entry->mod_count = newref ? newref->count : 0; + __entry->tree_size = tree_size; + ), + + TP_printk_btrfs("root_id=%llu key=[%llu,%u,%llu] level=%d count=[%d+%d=%d] parent=%llu wanted_disk_byte=%llu nodes=%llu", + (unsigned long long)__entry->root_id, + (unsigned long long)__entry->objectid, __entry->type, + (unsigned long long)__entry->offset, __entry->level, + __entry->old_count, __entry->mod_count, + __entry->old_count + __entry->mod_count, + (unsigned long long)__entry->parent, + (unsigned long long)__entry->bytenr, + (unsigned long long)__entry->tree_size) +); + +DEFINE_EVENT(btrfs__prelim_ref, btrfs_prelim_ref_merge, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct prelim_ref *oldref, + const struct prelim_ref *newref, u64 tree_size), + TP_ARGS(fs_info, oldref, newref, tree_size) +); + +DEFINE_EVENT(btrfs__prelim_ref, btrfs_prelim_ref_insert, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct prelim_ref *oldref, + const struct prelim_ref *newref, u64 tree_size), + TP_ARGS(fs_info, oldref, newref, tree_size) +); + #endif /* _TRACE_BTRFS_H */ /* This part must be outside protection */ diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index dfae175ddebc2340c68e9145d588f57f2f45ebce..9c3bc3883d2fac1fbd4683d9eb4efbd74282f5c6 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -937,21 +937,19 @@ TRACE_EVENT(ext4_alloc_da_blocks, TP_STRUCT__entry( __field( dev_t, dev ) __field( ino_t, ino ) - __field( unsigned int, data_blocks ) - __field( unsigned int, meta_blocks ) + __field( unsigned int, data_blocks ) ), TP_fast_assign( __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; __entry->data_blocks = EXT4_I(inode)->i_reserved_data_blocks; - __entry->meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks; ), - TP_printk("dev %d,%d ino %lu data_blocks %u meta_blocks %u", + TP_printk("dev %d,%d ino %lu reserved_data_blocks %u", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->data_blocks, __entry->meta_blocks) + __entry->data_blocks) ); TRACE_EVENT(ext4_mballoc_alloc, @@ -1153,8 +1151,6 @@ TRACE_EVENT(ext4_da_update_reserve_space, __field( __u64, i_blocks ) __field( int, used_blocks ) __field( int, reserved_data_blocks ) - __field( int, reserved_meta_blocks ) - __field( int, allocated_meta_blocks ) __field( int, quota_claim ) __field( __u16, mode ) ), @@ -1166,22 +1162,16 @@ TRACE_EVENT(ext4_da_update_reserve_space, __entry->used_blocks = used_blocks; __entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks; - __entry->reserved_meta_blocks = - EXT4_I(inode)->i_reserved_meta_blocks; - __entry->allocated_meta_blocks = - EXT4_I(inode)->i_allocated_meta_blocks; __entry->quota_claim = quota_claim; __entry->mode = inode->i_mode; ), TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu used_blocks %d " - "reserved_data_blocks %d reserved_meta_blocks %d " - "allocated_meta_blocks %d quota_claim %d", + "reserved_data_blocks %d quota_claim %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->mode, __entry->i_blocks, __entry->used_blocks, __entry->reserved_data_blocks, - __entry->reserved_meta_blocks, __entry->allocated_meta_blocks, __entry->quota_claim) ); @@ -1195,7 +1185,6 @@ TRACE_EVENT(ext4_da_reserve_space, __field( ino_t, ino ) __field( __u64, i_blocks ) __field( int, reserved_data_blocks ) - __field( int, reserved_meta_blocks ) __field( __u16, mode ) ), @@ -1204,17 +1193,15 @@ TRACE_EVENT(ext4_da_reserve_space, __entry->ino = inode->i_ino; __entry->i_blocks = inode->i_blocks; __entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks; - __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks; __entry->mode = inode->i_mode; ), TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu " - "reserved_data_blocks %d reserved_meta_blocks %d", + "reserved_data_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->mode, __entry->i_blocks, - __entry->reserved_data_blocks, - __entry->reserved_meta_blocks) + __entry->reserved_data_blocks) ); TRACE_EVENT(ext4_da_release_space, @@ -1228,8 +1215,6 @@ TRACE_EVENT(ext4_da_release_space, __field( __u64, i_blocks ) __field( int, freed_blocks ) __field( int, reserved_data_blocks ) - __field( int, reserved_meta_blocks ) - __field( int, allocated_meta_blocks ) __field( __u16, mode ) ), @@ -1239,19 +1224,15 @@ TRACE_EVENT(ext4_da_release_space, __entry->i_blocks = inode->i_blocks; __entry->freed_blocks = freed_blocks; __entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks; - __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks; - __entry->allocated_meta_blocks = EXT4_I(inode)->i_allocated_meta_blocks; __entry->mode = inode->i_mode; ), TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu freed_blocks %d " - "reserved_data_blocks %d reserved_meta_blocks %d " - "allocated_meta_blocks %d", + "reserved_data_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->mode, __entry->i_blocks, - __entry->freed_blocks, __entry->reserved_data_blocks, - __entry->reserved_meta_blocks, __entry->allocated_meta_blocks) + __entry->freed_blocks, __entry->reserved_data_blocks) ); DECLARE_EVENT_CLASS(ext4__bitmap_load, diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 6f77a2755abbfa89b4ab93467d69d36364650693..5d216f7fb05ae05337dde54bfcb8a4e2dcd2983b 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -543,14 +543,14 @@ TRACE_EVENT(f2fs_map_blocks, TRACE_EVENT(f2fs_background_gc, - TP_PROTO(struct super_block *sb, long wait_ms, + TP_PROTO(struct super_block *sb, unsigned int wait_ms, unsigned int prefree, unsigned int free), TP_ARGS(sb, wait_ms, prefree, free), TP_STRUCT__entry( __field(dev_t, dev) - __field(long, wait_ms) + __field(unsigned int, wait_ms) __field(unsigned int, prefree) __field(unsigned int, free) ), @@ -562,13 +562,120 @@ TRACE_EVENT(f2fs_background_gc, __entry->free = free; ), - TP_printk("dev = (%d,%d), wait_ms = %ld, prefree = %u, free = %u", + TP_printk("dev = (%d,%d), wait_ms = %u, prefree = %u, free = %u", show_dev(__entry->dev), __entry->wait_ms, __entry->prefree, __entry->free) ); +TRACE_EVENT(f2fs_gc_begin, + + TP_PROTO(struct super_block *sb, bool sync, bool background, + long long dirty_nodes, long long dirty_dents, + long long dirty_imeta, unsigned int free_sec, + unsigned int free_seg, int reserved_seg, + unsigned int prefree_seg), + + TP_ARGS(sb, sync, background, dirty_nodes, dirty_dents, dirty_imeta, + free_sec, free_seg, reserved_seg, prefree_seg), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(bool, sync) + __field(bool, background) + __field(long long, dirty_nodes) + __field(long long, dirty_dents) + __field(long long, dirty_imeta) + __field(unsigned int, free_sec) + __field(unsigned int, free_seg) + __field(int, reserved_seg) + __field(unsigned int, prefree_seg) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->sync = sync; + __entry->background = background; + __entry->dirty_nodes = dirty_nodes; + __entry->dirty_dents = dirty_dents; + __entry->dirty_imeta = dirty_imeta; + __entry->free_sec = free_sec; + __entry->free_seg = free_seg; + __entry->reserved_seg = reserved_seg; + __entry->prefree_seg = prefree_seg; + ), + + TP_printk("dev = (%d,%d), sync = %d, background = %d, nodes = %lld, " + "dents = %lld, imeta = %lld, free_sec:%u, free_seg:%u, " + "rsv_seg:%d, prefree_seg:%u", + show_dev(__entry->dev), + __entry->sync, + __entry->background, + __entry->dirty_nodes, + __entry->dirty_dents, + __entry->dirty_imeta, + __entry->free_sec, + __entry->free_seg, + __entry->reserved_seg, + __entry->prefree_seg) +); + +TRACE_EVENT(f2fs_gc_end, + + TP_PROTO(struct super_block *sb, int ret, int seg_freed, + int sec_freed, long long dirty_nodes, + long long dirty_dents, long long dirty_imeta, + unsigned int free_sec, unsigned int free_seg, + int reserved_seg, unsigned int prefree_seg), + + TP_ARGS(sb, ret, seg_freed, sec_freed, dirty_nodes, dirty_dents, + dirty_imeta, free_sec, free_seg, reserved_seg, prefree_seg), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(int, ret) + __field(int, seg_freed) + __field(int, sec_freed) + __field(long long, dirty_nodes) + __field(long long, dirty_dents) + __field(long long, dirty_imeta) + __field(unsigned int, free_sec) + __field(unsigned int, free_seg) + __field(int, reserved_seg) + __field(unsigned int, prefree_seg) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->ret = ret; + __entry->seg_freed = seg_freed; + __entry->sec_freed = sec_freed; + __entry->dirty_nodes = dirty_nodes; + __entry->dirty_dents = dirty_dents; + __entry->dirty_imeta = dirty_imeta; + __entry->free_sec = free_sec; + __entry->free_seg = free_seg; + __entry->reserved_seg = reserved_seg; + __entry->prefree_seg = prefree_seg; + ), + + TP_printk("dev = (%d,%d), ret = %d, seg_freed = %d, sec_freed = %d, " + "nodes = %lld, dents = %lld, imeta = %lld, free_sec:%u, " + "free_seg:%u, rsv_seg:%d, prefree_seg:%u", + show_dev(__entry->dev), + __entry->ret, + __entry->seg_freed, + __entry->sec_freed, + __entry->dirty_nodes, + __entry->dirty_dents, + __entry->dirty_imeta, + __entry->free_sec, + __entry->free_seg, + __entry->reserved_seg, + __entry->prefree_seg) +); + TRACE_EVENT(f2fs_get_victim, TP_PROTO(struct super_block *sb, int type, int gc_type, @@ -829,7 +936,7 @@ DECLARE_EVENT_CLASS(f2fs__bio, TP_fast_assign( __entry->dev = sb->s_dev; - __entry->target = bio->bi_bdev->bd_dev; + __entry->target = bio_dev(bio); __entry->op = bio_op(bio); __entry->op_flags = bio->bi_opf; __entry->type = type; diff --git a/include/trace/events/fs_dax.h b/include/trace/events/fs_dax.h index 08bb3ed18dcc213dbbdcfad0832a83a8fbb2ed4e..fbc4a06f7310a0d04fdfbd702d94663edcc04b56 100644 --- a/include/trace/events/fs_dax.h +++ b/include/trace/events/fs_dax.h @@ -190,8 +190,6 @@ DEFINE_EVENT(dax_pte_fault_class, name, \ DEFINE_PTE_FAULT_EVENT(dax_pte_fault); DEFINE_PTE_FAULT_EVENT(dax_pte_fault_done); -DEFINE_PTE_FAULT_EVENT(dax_pfn_mkwrite_no_entry); -DEFINE_PTE_FAULT_EVENT(dax_pfn_mkwrite); DEFINE_PTE_FAULT_EVENT(dax_load_hole); TRACE_EVENT(dax_insert_mapping, diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 8ade3eb6c640e0725e2c1fe0d930e6309cd0801f..dcffedfac43109ae4c898bb57b3c161b49405e57 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -14,7 +14,9 @@ ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR), \ ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\ ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI), ERSN(PAPR_HCALL), \ - ERSN(S390_UCONTROL), ERSN(WATCHDOG), ERSN(S390_TSCH) + ERSN(S390_UCONTROL), ERSN(WATCHDOG), ERSN(S390_TSCH), ERSN(EPR),\ + ERSN(SYSTEM_EVENT), ERSN(S390_STSI), ERSN(IOAPIC_EOI), \ + ERSN(HYPERV) TRACE_EVENT(kvm_userspace_exit, TP_PROTO(__u32 reason, int errno), diff --git a/include/trace/events/mmc.h b/include/trace/events/mmc.h index a72f9b94c80bda751117b417b07790941bb179f2..f30a99ac65b6a764da1a6b46f0dec2e82b174a64 100644 --- a/include/trace/events/mmc.h +++ b/include/trace/events/mmc.h @@ -29,8 +29,10 @@ TRACE_EVENT(mmc_request_start, __field(unsigned int, sbc_flags) __field(unsigned int, sbc_retries) __field(unsigned int, blocks) + __field(unsigned int, blk_addr) __field(unsigned int, blksz) __field(unsigned int, data_flags) + __field(int, tag) __field(unsigned int, can_retune) __field(unsigned int, doing_retune) __field(unsigned int, retune_now) @@ -42,10 +44,10 @@ TRACE_EVENT(mmc_request_start, ), TP_fast_assign( - __entry->cmd_opcode = mrq->cmd->opcode; - __entry->cmd_arg = mrq->cmd->arg; - __entry->cmd_flags = mrq->cmd->flags; - __entry->cmd_retries = mrq->cmd->retries; + __entry->cmd_opcode = mrq->cmd ? mrq->cmd->opcode : 0; + __entry->cmd_arg = mrq->cmd ? mrq->cmd->arg : 0; + __entry->cmd_flags = mrq->cmd ? mrq->cmd->flags : 0; + __entry->cmd_retries = mrq->cmd ? mrq->cmd->retries : 0; __entry->stop_opcode = mrq->stop ? mrq->stop->opcode : 0; __entry->stop_arg = mrq->stop ? mrq->stop->arg : 0; __entry->stop_flags = mrq->stop ? mrq->stop->flags : 0; @@ -56,7 +58,9 @@ TRACE_EVENT(mmc_request_start, __entry->sbc_retries = mrq->sbc ? mrq->sbc->retries : 0; __entry->blksz = mrq->data ? mrq->data->blksz : 0; __entry->blocks = mrq->data ? mrq->data->blocks : 0; + __entry->blk_addr = mrq->data ? mrq->data->blk_addr : 0; __entry->data_flags = mrq->data ? mrq->data->flags : 0; + __entry->tag = mrq->tag; __entry->can_retune = host->can_retune; __entry->doing_retune = host->doing_retune; __entry->retune_now = host->retune_now; @@ -71,8 +75,8 @@ TRACE_EVENT(mmc_request_start, "cmd_opcode=%u cmd_arg=0x%x cmd_flags=0x%x cmd_retries=%u " "stop_opcode=%u stop_arg=0x%x stop_flags=0x%x stop_retries=%u " "sbc_opcode=%u sbc_arg=0x%x sbc_flags=0x%x sbc_retires=%u " - "blocks=%u block_size=%u data_flags=0x%x " - "can_retune=%u doing_retune=%u retune_now=%u " + "blocks=%u block_size=%u blk_addr=%u data_flags=0x%x " + "tag=%d can_retune=%u doing_retune=%u retune_now=%u " "need_retune=%d hold_retune=%d retune_period=%u", __get_str(name), __entry->mrq, __entry->cmd_opcode, __entry->cmd_arg, @@ -81,7 +85,8 @@ TRACE_EVENT(mmc_request_start, __entry->stop_flags, __entry->stop_retries, __entry->sbc_opcode, __entry->sbc_arg, __entry->sbc_flags, __entry->sbc_retries, - __entry->blocks, __entry->blksz, __entry->data_flags, + __entry->blocks, __entry->blk_addr, + __entry->blksz, __entry->data_flags, __entry->tag, __entry->can_retune, __entry->doing_retune, __entry->retune_now, __entry->need_retune, __entry->hold_retune, __entry->retune_period) @@ -108,6 +113,7 @@ TRACE_EVENT(mmc_request_done, __field(unsigned int, sbc_retries) __field(unsigned int, bytes_xfered) __field(int, data_err) + __field(int, tag) __field(unsigned int, can_retune) __field(unsigned int, doing_retune) __field(unsigned int, retune_now) @@ -119,10 +125,13 @@ TRACE_EVENT(mmc_request_done, ), TP_fast_assign( - __entry->cmd_opcode = mrq->cmd->opcode; - __entry->cmd_err = mrq->cmd->error; - memcpy(__entry->cmd_resp, mrq->cmd->resp, 4); - __entry->cmd_retries = mrq->cmd->retries; + __entry->cmd_opcode = mrq->cmd ? mrq->cmd->opcode : 0; + __entry->cmd_err = mrq->cmd ? mrq->cmd->error : 0; + __entry->cmd_resp[0] = mrq->cmd ? mrq->cmd->resp[0] : 0; + __entry->cmd_resp[1] = mrq->cmd ? mrq->cmd->resp[1] : 0; + __entry->cmd_resp[2] = mrq->cmd ? mrq->cmd->resp[2] : 0; + __entry->cmd_resp[3] = mrq->cmd ? mrq->cmd->resp[3] : 0; + __entry->cmd_retries = mrq->cmd ? mrq->cmd->retries : 0; __entry->stop_opcode = mrq->stop ? mrq->stop->opcode : 0; __entry->stop_err = mrq->stop ? mrq->stop->error : 0; __entry->stop_resp[0] = mrq->stop ? mrq->stop->resp[0] : 0; @@ -139,6 +148,7 @@ TRACE_EVENT(mmc_request_done, __entry->sbc_retries = mrq->sbc ? mrq->sbc->retries : 0; __entry->bytes_xfered = mrq->data ? mrq->data->bytes_xfered : 0; __entry->data_err = mrq->data ? mrq->data->error : 0; + __entry->tag = mrq->tag; __entry->can_retune = host->can_retune; __entry->doing_retune = host->doing_retune; __entry->retune_now = host->retune_now; @@ -154,7 +164,7 @@ TRACE_EVENT(mmc_request_done, "cmd_retries=%u stop_opcode=%u stop_err=%d " "stop_resp=0x%x 0x%x 0x%x 0x%x stop_retries=%u " "sbc_opcode=%u sbc_err=%d sbc_resp=0x%x 0x%x 0x%x 0x%x " - "sbc_retries=%u bytes_xfered=%u data_err=%d " + "sbc_retries=%u bytes_xfered=%u data_err=%d tag=%d " "can_retune=%u doing_retune=%u retune_now=%u need_retune=%d " "hold_retune=%d retune_period=%u", __get_str(name), __entry->mrq, @@ -170,7 +180,7 @@ TRACE_EVENT(mmc_request_done, __entry->sbc_resp[0], __entry->sbc_resp[1], __entry->sbc_resp[2], __entry->sbc_resp[3], __entry->sbc_retries, - __entry->bytes_xfered, __entry->data_err, + __entry->bytes_xfered, __entry->data_err, __entry->tag, __entry->can_retune, __entry->doing_retune, __entry->retune_now, __entry->need_retune, __entry->hold_retune, __entry->retune_period) diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index 8e50d01c645fc7522dc0d6f74e80098c3c36f3dc..fec6291a67036fb6d9b118f53850612e81ab3d54 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -18,7 +18,6 @@ {(unsigned long)GFP_HIGHUSER_MOVABLE, "GFP_HIGHUSER_MOVABLE"},\ {(unsigned long)GFP_HIGHUSER, "GFP_HIGHUSER"}, \ {(unsigned long)GFP_USER, "GFP_USER"}, \ - {(unsigned long)GFP_TEMPORARY, "GFP_TEMPORARY"}, \ {(unsigned long)GFP_KERNEL_ACCOUNT, "GFP_KERNEL_ACCOUNT"}, \ {(unsigned long)GFP_KERNEL, "GFP_KERNEL"}, \ {(unsigned long)GFP_NOFS, "GFP_NOFS"}, \ @@ -125,12 +124,6 @@ IF_HAVE_PG_IDLE(PG_idle, "idle" ) #define __VM_ARCH_SPECIFIC_1 {VM_ARCH_1, "arch_1" } #endif -#if defined(CONFIG_X86) -#define __VM_ARCH_SPECIFIC_2 {VM_MPX, "mpx" } -#else -#define __VM_ARCH_SPECIFIC_2 {VM_ARCH_2, "arch_2" } -#endif - #ifdef CONFIG_MEM_SOFT_DIRTY #define IF_HAVE_VM_SOFTDIRTY(flag,name) {flag, name }, #else @@ -162,7 +155,7 @@ IF_HAVE_PG_IDLE(PG_idle, "idle" ) {VM_NORESERVE, "noreserve" }, \ {VM_HUGETLB, "hugetlb" }, \ __VM_ARCH_SPECIFIC_1 , \ - __VM_ARCH_SPECIFIC_2 , \ + {VM_WIPEONFORK, "wipeonfork" }, \ {VM_DONTDUMP, "dontdump" }, \ IF_HAVE_VM_SOFTDIRTY(VM_SOFTDIRTY, "softdirty" ) \ {VM_MIXEDMAP, "mixedmap" }, \ diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h new file mode 100644 index 0000000000000000000000000000000000000000..60d0d8bd336d08705f98468a87b9a31696c83941 --- /dev/null +++ b/include/trace/events/qdisc.h @@ -0,0 +1,50 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM qdisc + +#if !defined(_TRACE_QDISC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_QDISC_H_ + +#include +#include +#include +#include + +TRACE_EVENT(qdisc_dequeue, + + TP_PROTO(struct Qdisc *qdisc, const struct netdev_queue *txq, + int packets, struct sk_buff *skb), + + TP_ARGS(qdisc, txq, packets, skb), + + TP_STRUCT__entry( + __field( struct Qdisc *, qdisc ) + __field(const struct netdev_queue *, txq ) + __field( int, packets ) + __field( void *, skbaddr ) + __field( int, ifindex ) + __field( u32, handle ) + __field( u32, parent ) + __field( unsigned long, txq_state) + ), + + /* skb==NULL indicate packets dequeued was 0, even when packets==1 */ + TP_fast_assign( + __entry->qdisc = qdisc; + __entry->txq = txq; + __entry->packets = skb ? packets : 0; + __entry->skbaddr = skb; + __entry->ifindex = txq->dev ? txq->dev->ifindex : 0; + __entry->handle = qdisc->handle; + __entry->parent = qdisc->parent; + __entry->txq_state = txq->state; + ), + + TP_printk("dequeue ifindex=%d qdisc handle=0x%X parent=0x%X txq_state=0x%lX packets=%d skbaddr=%p", + __entry->ifindex, __entry->handle, __entry->parent, + __entry->txq_state, __entry->packets, __entry->skbaddr ) +); + +#endif /* _TRACE_QDISC_H_ */ + +/* This part must be outside protection */ +#include diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 91dc089d65b7e3abfd9d22bf4ac5e4bc593237cc..e91ae1f2290de4288aa0f70336f8596a4b68f711 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h @@ -703,6 +703,7 @@ TRACE_EVENT(rcu_batch_end, * at the beginning and end of the read, respectively. Note that the * callback address can be NULL. */ +#define RCUTORTURENAME_LEN 8 TRACE_EVENT(rcu_torture_read, TP_PROTO(const char *rcutorturename, struct rcu_head *rhp, @@ -711,7 +712,7 @@ TRACE_EVENT(rcu_torture_read, TP_ARGS(rcutorturename, rhp, secs, c_old, c), TP_STRUCT__entry( - __field(const char *, rcutorturename) + __field(char, rcutorturename[RCUTORTURENAME_LEN]) __field(struct rcu_head *, rhp) __field(unsigned long, secs) __field(unsigned long, c_old) @@ -719,7 +720,9 @@ TRACE_EVENT(rcu_torture_read, ), TP_fast_assign( - __entry->rcutorturename = rcutorturename; + strncpy(__entry->rcutorturename, rcutorturename, + RCUTORTURENAME_LEN); + __entry->rcutorturename[RCUTORTURENAME_LEN - 1] = 0; __entry->rhp = rhp; __entry->secs = secs; __entry->c_old = c_old; diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index ae1409ffe99a00817f02a2cc51771840712fc1c3..3c8b7f6256701b6c6eeb05b2bae9387fa95df692 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h @@ -114,7 +114,10 @@ static inline long __trace_sched_switch_state(bool preempt, struct task_struct * * Preemption ignores task state, therefore preempted tasks are always * RUNNING (we will not have dequeued if state != RUNNING). */ - return preempt ? TASK_RUNNING | TASK_STATE_MAX : p->state; + if (preempt) + return TASK_STATE_MAX; + + return __get_task_state(p); } #endif /* CREATE_TRACE_POINTS */ @@ -152,12 +155,14 @@ TRACE_EVENT(sched_switch, TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, - __entry->prev_state & (TASK_STATE_MAX-1) ? - __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|", - { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, - { 16, "Z" }, { 32, "X" }, { 64, "x" }, - { 128, "K" }, { 256, "W" }, { 512, "P" }, - { 1024, "N" }) : "R", + + (__entry->prev_state & (TASK_REPORT_MAX - 1)) ? + __print_flags(__entry->prev_state & (TASK_REPORT_MAX - 1), "|", + { 0x01, "S" }, { 0x02, "D" }, { 0x04, "T" }, + { 0x08, "t" }, { 0x10, "X" }, { 0x20, "Z" }, + { 0x40, "P" }, { 0x80, "I" }) : + "R", + __entry->prev_state & TASK_STATE_MAX ? "+" : "", __entry->next_comm, __entry->next_pid, __entry->next_prio) ); diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 7bd8783a590ff99aed51310d4e4e4f05f2f7cb38..9b57f014d79d033336d7dc63a00972e5e9535230 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h @@ -136,7 +136,7 @@ DEFINE_EVENT(writeback_dirty_inode_template, writeback_dirty_inode, static inline unsigned int __trace_wb_assign_cgroup(struct bdi_writeback *wb) { - return wb->memcg_css->cgroup->kn->ino; + return wb->memcg_css->cgroup->kn->id.ino; } static inline unsigned int __trace_wbc_assign_cgroup(struct writeback_control *wbc) diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h index 1b61357d3f575ab8b3c5debd487714cb1430b2b5..4e16c43fba10ab7ce958582b0b6771473dbe926a 100644 --- a/include/trace/events/xdp.h +++ b/include/trace/events/xdp.h @@ -12,7 +12,8 @@ FN(ABORTED) \ FN(DROP) \ FN(PASS) \ - FN(TX) + FN(TX) \ + FN(REDIRECT) #define __XDP_ACT_TP_FN(x) \ TRACE_DEFINE_ENUM(XDP_##x); @@ -30,24 +31,119 @@ TRACE_EVENT(xdp_exception, TP_ARGS(dev, xdp, act), TP_STRUCT__entry( - __string(name, dev->name) - __array(u8, prog_tag, 8) + __field(int, prog_id) __field(u32, act) + __field(int, ifindex) ), TP_fast_assign( - BUILD_BUG_ON(sizeof(__entry->prog_tag) != sizeof(xdp->tag)); - memcpy(__entry->prog_tag, xdp->tag, sizeof(xdp->tag)); - __assign_str(name, dev->name); - __entry->act = act; + __entry->prog_id = xdp->aux->id; + __entry->act = act; + __entry->ifindex = dev->ifindex; ), - TP_printk("prog=%s device=%s action=%s", - __print_hex_str(__entry->prog_tag, 8), - __get_str(name), - __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB)) + TP_printk("prog_id=%d action=%s ifindex=%d", + __entry->prog_id, + __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB), + __entry->ifindex) ); +DECLARE_EVENT_CLASS(xdp_redirect_template, + + TP_PROTO(const struct net_device *dev, + const struct bpf_prog *xdp, + int to_ifindex, int err, + const struct bpf_map *map, u32 map_index), + + TP_ARGS(dev, xdp, to_ifindex, err, map, map_index), + + TP_STRUCT__entry( + __field(int, prog_id) + __field(u32, act) + __field(int, ifindex) + __field(int, err) + __field(int, to_ifindex) + __field(u32, map_id) + __field(int, map_index) + ), + + TP_fast_assign( + __entry->prog_id = xdp->aux->id; + __entry->act = XDP_REDIRECT; + __entry->ifindex = dev->ifindex; + __entry->err = err; + __entry->to_ifindex = to_ifindex; + __entry->map_id = map ? map->id : 0; + __entry->map_index = map_index; + ), + + TP_printk("prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d", + __entry->prog_id, + __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB), + __entry->ifindex, __entry->to_ifindex, + __entry->err) +); + +DEFINE_EVENT(xdp_redirect_template, xdp_redirect, + TP_PROTO(const struct net_device *dev, + const struct bpf_prog *xdp, + int to_ifindex, int err, + const struct bpf_map *map, u32 map_index), + TP_ARGS(dev, xdp, to_ifindex, err, map, map_index) +); + +DEFINE_EVENT(xdp_redirect_template, xdp_redirect_err, + TP_PROTO(const struct net_device *dev, + const struct bpf_prog *xdp, + int to_ifindex, int err, + const struct bpf_map *map, u32 map_index), + TP_ARGS(dev, xdp, to_ifindex, err, map, map_index) +); + +#define _trace_xdp_redirect(dev, xdp, to) \ + trace_xdp_redirect(dev, xdp, to, 0, NULL, 0); + +#define _trace_xdp_redirect_err(dev, xdp, to, err) \ + trace_xdp_redirect_err(dev, xdp, to, err, NULL, 0); + +DEFINE_EVENT_PRINT(xdp_redirect_template, xdp_redirect_map, + TP_PROTO(const struct net_device *dev, + const struct bpf_prog *xdp, + int to_ifindex, int err, + const struct bpf_map *map, u32 map_index), + TP_ARGS(dev, xdp, to_ifindex, err, map, map_index), + TP_printk("prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d" + " map_id=%d map_index=%d", + __entry->prog_id, + __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB), + __entry->ifindex, __entry->to_ifindex, + __entry->err, + __entry->map_id, __entry->map_index) +); + +DEFINE_EVENT_PRINT(xdp_redirect_template, xdp_redirect_map_err, + TP_PROTO(const struct net_device *dev, + const struct bpf_prog *xdp, + int to_ifindex, int err, + const struct bpf_map *map, u32 map_index), + TP_ARGS(dev, xdp, to_ifindex, err, map, map_index), + TP_printk("prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d" + " map_id=%d map_index=%d", + __entry->prog_id, + __print_symbolic(__entry->act, __XDP_ACT_SYM_TAB), + __entry->ifindex, __entry->to_ifindex, + __entry->err, + __entry->map_id, __entry->map_index) +); + +#define _trace_xdp_redirect_map(dev, xdp, fwd, map, idx) \ + trace_xdp_redirect_map(dev, xdp, fwd ? fwd->ifindex : 0, \ + 0, map, idx) + +#define _trace_xdp_redirect_map_err(dev, xdp, fwd, map, idx, err) \ + trace_xdp_redirect_map_err(dev, xdp, fwd ? fwd->ifindex : 0, \ + err, map, idx) + #endif /* _TRACE_XDP_H */ #include diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h index b70a38b7fa84b85f13967d1c4be83d18a1b416c1..1b4fed72f573800c0839eedc4aaa1ca642a2ada0 100644 --- a/include/trace/events/xen.h +++ b/include/trace/events/xen.h @@ -149,24 +149,6 @@ DECLARE_EVENT_CLASS(xen_mmu__set_pte, DEFINE_XEN_MMU_SET_PTE(xen_mmu_set_pte); DEFINE_XEN_MMU_SET_PTE(xen_mmu_set_pte_atomic); -TRACE_EVENT(xen_mmu_set_domain_pte, - TP_PROTO(pte_t *ptep, pte_t pteval, unsigned domid), - TP_ARGS(ptep, pteval, domid), - TP_STRUCT__entry( - __field(pte_t *, ptep) - __field(pteval_t, pteval) - __field(unsigned, domid) - ), - TP_fast_assign(__entry->ptep = ptep; - __entry->pteval = pteval.pte; - __entry->domid = domid), - TP_printk("ptep %p pteval %0*llx (raw %0*llx) domid %u", - __entry->ptep, - (int)sizeof(pteval_t) * 2, (unsigned long long)pte_val(native_make_pte(__entry->pteval)), - (int)sizeof(pteval_t) * 2, (unsigned long long)__entry->pteval, - __entry->domid) - ); - TRACE_EVENT(xen_mmu_set_pte_at, TP_PROTO(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval), @@ -266,16 +248,6 @@ TRACE_EVENT(xen_mmu_set_p4d, (int)sizeof(p4dval_t) * 2, (unsigned long long)pgd_val(native_make_pgd(__entry->p4dval)), (int)sizeof(p4dval_t) * 2, (unsigned long long)__entry->p4dval) ); - -TRACE_EVENT(xen_mmu_pud_clear, - TP_PROTO(pud_t *pudp), - TP_ARGS(pudp), - TP_STRUCT__entry( - __field(pud_t *, pudp) - ), - TP_fast_assign(__entry->pudp = pudp), - TP_printk("pudp %p", __entry->pudp) - ); #else TRACE_EVENT(xen_mmu_set_pud, @@ -295,16 +267,6 @@ TRACE_EVENT(xen_mmu_set_pud, #endif -TRACE_EVENT(xen_mmu_pgd_clear, - TP_PROTO(pgd_t *pgdp), - TP_ARGS(pgdp), - TP_STRUCT__entry( - __field(pgd_t *, pgdp) - ), - TP_fast_assign(__entry->pgdp = pgdp), - TP_printk("pgdp %p", __entry->pgdp) - ); - DECLARE_EVENT_CLASS(xen_mmu_ptep_modify_prot, TP_PROTO(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval), diff --git a/include/uapi/asm-generic/hugetlb_encode.h b/include/uapi/asm-generic/hugetlb_encode.h new file mode 100644 index 0000000000000000000000000000000000000000..e4732d3c2998264857772faac64409c69ff8e43d --- /dev/null +++ b/include/uapi/asm-generic/hugetlb_encode.h @@ -0,0 +1,34 @@ +#ifndef _ASM_GENERIC_HUGETLB_ENCODE_H_ +#define _ASM_GENERIC_HUGETLB_ENCODE_H_ + +/* + * Several system calls take a flag to request "hugetlb" huge pages. + * Without further specification, these system calls will use the + * system's default huge page size. If a system supports multiple + * huge page sizes, the desired huge page size can be specified in + * bits [26:31] of the flag arguments. The value in these 6 bits + * will encode the log2 of the huge page size. + * + * The following definitions are associated with this huge page size + * encoding in flag arguments. System call specific header files + * that use this encoding should include this file. They can then + * provide definitions based on these with their own specific prefix. + * for example: + * #define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT + */ + +#define HUGETLB_FLAG_ENCODE_SHIFT 26 +#define HUGETLB_FLAG_ENCODE_MASK 0x3f + +#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT) + +#endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */ diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h index 8c27db0c5c08ce84fc7299bd9bff2cee571b9397..203268f9231e155d72307995989feab4857defe7 100644 --- a/include/uapi/asm-generic/mman-common.h +++ b/include/uapi/asm-generic/mman-common.h @@ -58,20 +58,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h index 9c4eca6b374a6c86c83e33a73f2d6800cedf7215..e5aa6794cea465a69d09b0bae663673365b67909 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -151,29 +151,6 @@ typedef struct siginfo { #define si_arch _sifields._sigsys._arch #endif -#ifdef __KERNEL__ -#define __SI_MASK 0xffff0000u -#define __SI_KILL (0 << 16) -#define __SI_TIMER (1 << 16) -#define __SI_POLL (2 << 16) -#define __SI_FAULT (3 << 16) -#define __SI_CHLD (4 << 16) -#define __SI_RT (5 << 16) -#define __SI_MESGQ (6 << 16) -#define __SI_SYS (7 << 16) -#define __SI_CODE(T,N) ((T) | ((N) & 0xffff)) -#else /* __KERNEL__ */ -#define __SI_KILL 0 -#define __SI_TIMER 0 -#define __SI_POLL 0 -#define __SI_FAULT 0 -#define __SI_CHLD 0 -#define __SI_RT 0 -#define __SI_MESGQ 0 -#define __SI_SYS 0 -#define __SI_CODE(T,N) (N) -#endif /* __KERNEL__ */ - /* * si_code values * Digital reserves positive values for kernel-generated signals. @@ -181,8 +158,8 @@ typedef struct siginfo { #define SI_USER 0 /* sent by kill, sigsend, raise */ #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */ #define SI_QUEUE -1 /* sent by sigqueue */ -#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */ -#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */ +#define SI_TIMER -2 /* sent by timer expiration */ +#define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ #define SI_TKILL -6 /* sent by tkill system call */ @@ -194,86 +171,86 @@ typedef struct siginfo { /* * SIGILL si_codes */ -#define ILL_ILLOPC (__SI_FAULT|1) /* illegal opcode */ -#define ILL_ILLOPN (__SI_FAULT|2) /* illegal operand */ -#define ILL_ILLADR (__SI_FAULT|3) /* illegal addressing mode */ -#define ILL_ILLTRP (__SI_FAULT|4) /* illegal trap */ -#define ILL_PRVOPC (__SI_FAULT|5) /* privileged opcode */ -#define ILL_PRVREG (__SI_FAULT|6) /* privileged register */ -#define ILL_COPROC (__SI_FAULT|7) /* coprocessor error */ -#define ILL_BADSTK (__SI_FAULT|8) /* internal stack error */ +#define ILL_ILLOPC 1 /* illegal opcode */ +#define ILL_ILLOPN 2 /* illegal operand */ +#define ILL_ILLADR 3 /* illegal addressing mode */ +#define ILL_ILLTRP 4 /* illegal trap */ +#define ILL_PRVOPC 5 /* privileged opcode */ +#define ILL_PRVREG 6 /* privileged register */ +#define ILL_COPROC 7 /* coprocessor error */ +#define ILL_BADSTK 8 /* internal stack error */ #define NSIGILL 8 /* * SIGFPE si_codes */ -#define FPE_INTDIV (__SI_FAULT|1) /* integer divide by zero */ -#define FPE_INTOVF (__SI_FAULT|2) /* integer overflow */ -#define FPE_FLTDIV (__SI_FAULT|3) /* floating point divide by zero */ -#define FPE_FLTOVF (__SI_FAULT|4) /* floating point overflow */ -#define FPE_FLTUND (__SI_FAULT|5) /* floating point underflow */ -#define FPE_FLTRES (__SI_FAULT|6) /* floating point inexact result */ -#define FPE_FLTINV (__SI_FAULT|7) /* floating point invalid operation */ -#define FPE_FLTSUB (__SI_FAULT|8) /* subscript out of range */ +#define FPE_INTDIV 1 /* integer divide by zero */ +#define FPE_INTOVF 2 /* integer overflow */ +#define FPE_FLTDIV 3 /* floating point divide by zero */ +#define FPE_FLTOVF 4 /* floating point overflow */ +#define FPE_FLTUND 5 /* floating point underflow */ +#define FPE_FLTRES 6 /* floating point inexact result */ +#define FPE_FLTINV 7 /* floating point invalid operation */ +#define FPE_FLTSUB 8 /* subscript out of range */ #define NSIGFPE 8 /* * SIGSEGV si_codes */ -#define SEGV_MAPERR (__SI_FAULT|1) /* address not mapped to object */ -#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */ -#define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */ -#define SEGV_PKUERR (__SI_FAULT|4) /* failed protection key checks */ +#define SEGV_MAPERR 1 /* address not mapped to object */ +#define SEGV_ACCERR 2 /* invalid permissions for mapped object */ +#define SEGV_BNDERR 3 /* failed address bound checks */ +#define SEGV_PKUERR 4 /* failed protection key checks */ #define NSIGSEGV 4 /* * SIGBUS si_codes */ -#define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */ -#define BUS_ADRERR (__SI_FAULT|2) /* non-existent physical address */ -#define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */ +#define BUS_ADRALN 1 /* invalid address alignment */ +#define BUS_ADRERR 2 /* non-existent physical address */ +#define BUS_OBJERR 3 /* object specific hardware error */ /* hardware memory error consumed on a machine check: action required */ -#define BUS_MCEERR_AR (__SI_FAULT|4) +#define BUS_MCEERR_AR 4 /* hardware memory error detected in process but not consumed: action optional*/ -#define BUS_MCEERR_AO (__SI_FAULT|5) +#define BUS_MCEERR_AO 5 #define NSIGBUS 5 /* * SIGTRAP si_codes */ -#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */ -#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */ -#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */ -#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */ +#define TRAP_BRKPT 1 /* process breakpoint */ +#define TRAP_TRACE 2 /* process trace trap */ +#define TRAP_BRANCH 3 /* process taken branch trap */ +#define TRAP_HWBKPT 4 /* hardware breakpoint/watchpoint */ #define NSIGTRAP 4 /* * SIGCHLD si_codes */ -#define CLD_EXITED (__SI_CHLD|1) /* child has exited */ -#define CLD_KILLED (__SI_CHLD|2) /* child was killed */ -#define CLD_DUMPED (__SI_CHLD|3) /* child terminated abnormally */ -#define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */ -#define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */ -#define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */ +#define CLD_EXITED 1 /* child has exited */ +#define CLD_KILLED 2 /* child was killed */ +#define CLD_DUMPED 3 /* child terminated abnormally */ +#define CLD_TRAPPED 4 /* traced child has trapped */ +#define CLD_STOPPED 5 /* child has stopped */ +#define CLD_CONTINUED 6 /* stopped child has continued */ #define NSIGCHLD 6 /* - * SIGPOLL si_codes + * SIGPOLL (or any other signal without signal specific si_codes) si_codes */ -#define POLL_IN (__SI_POLL|1) /* data input available */ -#define POLL_OUT (__SI_POLL|2) /* output buffers available */ -#define POLL_MSG (__SI_POLL|3) /* input message available */ -#define POLL_ERR (__SI_POLL|4) /* i/o error */ -#define POLL_PRI (__SI_POLL|5) /* high priority input available */ -#define POLL_HUP (__SI_POLL|6) /* device disconnected */ +#define POLL_IN 1 /* data input available */ +#define POLL_OUT 2 /* output buffers available */ +#define POLL_MSG 3 /* input message available */ +#define POLL_ERR 4 /* i/o error */ +#define POLL_PRI 5 /* high priority input available */ +#define POLL_HUP 6 /* device disconnected */ #define NSIGPOLL 6 /* * SIGSYS si_codes */ -#define SYS_SECCOMP (__SI_SYS|1) /* seccomp triggered */ -#define NSIGSYS 1 +#define SYS_SECCOMP 1 /* seccomp triggered */ +#define NSIGSYS 1 /* * sigevent definitions diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 9861be8da65e09e7a66ee9d5a543067b677af59e..e47c9e4362216e96482bde07acb12c9db4703e58 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -104,4 +104,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* __ASM_GENERIC_SOCKET_H */ diff --git a/include/uapi/drm/armada_drm.h b/include/uapi/drm/armada_drm.h index 72e326f9c7defd73eab70d139dde8d867e3bd776..0cb932416cfea4ac5f24e319bd883cace23ea08b 100644 --- a/include/uapi/drm/armada_drm.h +++ b/include/uapi/drm/armada_drm.h @@ -23,27 +23,27 @@ extern "C" { DRM_##dir(DRM_COMMAND_BASE + DRM_ARMADA_##name, struct drm_armada_##str) struct drm_armada_gem_create { - uint32_t handle; - uint32_t size; + __u32 handle; + __u32 size; }; #define DRM_IOCTL_ARMADA_GEM_CREATE \ ARMADA_IOCTL(IOWR, GEM_CREATE, gem_create) struct drm_armada_gem_mmap { - uint32_t handle; - uint32_t pad; - uint64_t offset; - uint64_t size; - uint64_t addr; + __u32 handle; + __u32 pad; + __u64 offset; + __u64 size; + __u64 addr; }; #define DRM_IOCTL_ARMADA_GEM_MMAP \ ARMADA_IOCTL(IOWR, GEM_MMAP, gem_mmap) struct drm_armada_gem_pwrite { - uint64_t ptr; - uint32_t handle; - uint32_t offset; - uint32_t size; + __u64 ptr; + __u32 handle; + __u32 offset; + __u32 size; }; #define DRM_IOCTL_ARMADA_GEM_PWRITE \ ARMADA_IOCTL(IOW, GEM_PWRITE, gem_pwrite) diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 101593ab10ac795808db33848092eb62ac542560..97677cd6964db099689f96f11b9731c748bebcfa 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -700,6 +700,7 @@ struct drm_prime_handle { struct drm_syncobj_create { __u32 handle; +#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) __u32 flags; }; @@ -718,6 +719,24 @@ struct drm_syncobj_handle { __u32 pad; }; +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) +struct drm_syncobj_wait { + __u64 handles; + /* absolute timeout */ + __s64 timeout_nsec; + __u32 count_handles; + __u32 flags; + __u32 first_signaled; /* only valid when not waiting all */ + __u32 pad; +}; + +struct drm_syncobj_array { + __u64 handles; + __u32 count_handles; + __u32 pad; +}; + #if defined(__cplusplus) } #endif @@ -840,6 +859,9 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) #define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) #define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) +#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait) +#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) +#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) /** * Device specific ioctls should only be in their respective headers diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 7586c46f68bf22f48a1536c0f27eed0d8d06eb92..3ad838d3f93f323b5a456dbd0f305687a5c786ab 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -185,6 +185,8 @@ extern "C" { #define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 /* add more to the end as needed */ +#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) + #define fourcc_mod_code(vendor, val) \ ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) @@ -196,6 +198,15 @@ extern "C" { * authoritative source for all of these. */ +/* + * Invalid Modifier + * + * This modifier can be used as a sentinel to terminate the format modifiers + * list, or to initialize a variable with an invalid modifier. It might also be + * used to report an error back to userspace for certain APIs. + */ +#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) + /* * Linear Layout * @@ -252,6 +263,26 @@ extern "C" { */ #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) +/* + * Intel color control surface (CCS) for render compression + * + * The framebuffer format must be one of the 8:8:8:8 RGB formats. + * The main surface will be plane index 0 and must be Y/Yf-tiled, + * the CCS will be plane index 1. + * + * Each CCS tile matches a 1024x512 pixel area of the main surface. + * To match certain aspects of the 3D hardware the CCS is + * considered to be made up of normal 128Bx32 Y tiles, Thus + * the CCS pitch must be specified in multiples of 128 bytes. + * + * In reality the CCS tile appears to be a 64Bx64 Y tile, composed + * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks. + * But that fact is not relevant unless the memory is accessed + * directly. + */ +#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4) +#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5) + /* * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks * diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 403339f98a925edb15d25974a5ac227216211800..54fc38c3c3f1dbd4cd65f188e5ce8f0d29cc194a 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -712,6 +712,56 @@ struct drm_mode_atomic { __u64 user_data; }; +struct drm_format_modifier_blob { +#define FORMAT_BLOB_CURRENT 1 + /* Version of this blob format */ + __u32 version; + + /* Flags */ + __u32 flags; + + /* Number of fourcc formats supported */ + __u32 count_formats; + + /* Where in this blob the formats exist (in bytes) */ + __u32 formats_offset; + + /* Number of drm_format_modifiers */ + __u32 count_modifiers; + + /* Where in this blob the modifiers exist (in bytes) */ + __u32 modifiers_offset; + + /* __u32 formats[] */ + /* struct drm_format_modifier modifiers[] */ +}; + +struct drm_format_modifier { + /* Bitmask of formats in get_plane format list this info applies to. The + * offset allows a sliding window of which 64 formats (bits). + * + * Some examples: + * In today's world with < 65 formats, and formats 0, and 2 are + * supported + * 0x0000000000000005 + * ^-offset = 0, formats = 5 + * + * If the number formats grew to 128, and formats 98-102 are + * supported with the modifier: + * + * 0x0000003c00000000 0000000000000000 + * ^ + * |__offset = 64, formats = 0x3c00000000 + * + */ + __u64 formats; + __u32 offset; + __u32 pad; + + /* The modifier that applies to the >get_plane format list bitmask. */ + __u64 modifier; +}; + /** * Create a new 'blob' data property, copying length bytes from data pointer, * and returning new blob ID. diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 7ccbd6a2bbe07b387b43bb8b4ac5eba0f52d1cd0..6598fb76d2c27741d2c916f914b70c5f472911f9 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -260,6 +260,8 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 #define DRM_I915_PERF_OPEN 0x36 +#define DRM_I915_PERF_ADD_CONFIG 0x37 +#define DRM_I915_PERF_REMOVE_CONFIG 0x38 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -315,6 +317,8 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) #define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) +#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config) +#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -431,6 +435,11 @@ typedef struct drm_i915_irq_wait { */ #define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of + * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY. + */ +#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 + typedef struct drm_i915_getparam { __s32 param; /* @@ -812,6 +821,17 @@ struct drm_i915_gem_exec_object2 { __u64 rsvd2; }; +struct drm_i915_gem_exec_fence { + /** + * User's handle for a drm_syncobj to wait on or signal. + */ + __u32 handle; + +#define I915_EXEC_FENCE_WAIT (1<<0) +#define I915_EXEC_FENCE_SIGNAL (1<<1) + __u32 flags; +}; + struct drm_i915_gem_execbuffer2 { /** * List of gem_exec_object2 structs @@ -826,7 +846,11 @@ struct drm_i915_gem_execbuffer2 { __u32 DR1; __u32 DR4; __u32 num_cliprects; - /** This is a struct drm_clip_rect *cliprects */ + /** + * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY + * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a + * struct drm_i915_gem_exec_fence *fences. + */ __u64 cliprects_ptr; #define I915_EXEC_RING_MASK (7<<0) #define I915_EXEC_DEFAULT (0<<0) @@ -927,7 +951,14 @@ struct drm_i915_gem_execbuffer2 { * element). */ #define I915_EXEC_BATCH_FIRST (1<<18) -#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_BATCH_FIRST<<1)) + +/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr + * define an array of i915_gem_exec_fence structures which specify a set of + * dma fences to wait upon or signal. + */ +#define I915_EXEC_FENCE_ARRAY (1<<19) + +#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1)) #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) #define i915_execbuffer2_set_context_id(eb2, context) \ @@ -1467,6 +1498,22 @@ enum drm_i915_perf_record_type { DRM_I915_PERF_RECORD_MAX /* non-ABI */ }; +/** + * Structure to upload perf dynamic configuration into the kernel. + */ +struct drm_i915_perf_oa_config { + /** String formatted like "%08x-%04x-%04x-%04x-%012x" */ + char uuid[36]; + + __u32 n_mux_regs; + __u32 n_boolean_regs; + __u32 n_flex_regs; + + __u64 __user mux_regs_ptr; + __u64 __user boolean_regs_ptr; + __u64 __user flex_regs_ptr; +}; + #if defined(__cplusplus) } #endif diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 26c54f6d595d4070c7708ef22daf7533468404a2..ad4eb2863e70ee195f9abc68e6b8c3c3020f27bc 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -171,7 +171,7 @@ struct drm_msm_gem_submit_cmd { __u32 size; /* in, cmdstream size */ __u32 pad; __u32 nr_relocs; /* in, number of submit_reloc's */ - __u64 __user relocs; /* in, ptr to array of submit_reloc's */ + __u64 relocs; /* in, ptr to array of submit_reloc's */ }; /* Each buffer referenced elsewhere in the cmdstream submit (ie. the @@ -215,8 +215,8 @@ struct drm_msm_gem_submit { __u32 fence; /* out */ __u32 nr_bos; /* in, number of submit_bo's */ __u32 nr_cmds; /* in, number of submit_cmd's */ - __u64 __user bos; /* in, ptr to array of submit_bo's */ - __u64 __user cmds; /* in, ptr to array of submit_cmd's */ + __u64 bos; /* in, ptr to array of submit_bo's */ + __u64 cmds; /* in, ptr to array of submit_cmd's */ __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ }; diff --git a/include/uapi/drm/qxl_drm.h b/include/uapi/drm/qxl_drm.h index 7eef42213051b4e80197c7983e12ed1cd79b4f20..880999d2d8630dd1408807342d0f127a4185e2be 100644 --- a/include/uapi/drm/qxl_drm.h +++ b/include/uapi/drm/qxl_drm.h @@ -80,8 +80,8 @@ struct drm_qxl_reloc { }; struct drm_qxl_command { - __u64 __user command; /* void* */ - __u64 __user relocs; /* struct drm_qxl_reloc* */ + __u64 command; /* void* */ + __u64 relocs; /* struct drm_qxl_reloc* */ __u32 type; __u32 command_size; __u32 relocs_num; @@ -91,7 +91,7 @@ struct drm_qxl_command { struct drm_qxl_execbuffer { __u32 flags; /* for future use */ __u32 commands_num; - __u64 __user commands; /* struct drm_qxl_command* */ + __u64 commands; /* struct drm_qxl_command* */ }; struct drm_qxl_update_area { diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h index 6ac4c5c014cb9b98343f25721f74b727a88f2bb5..afae870049636e9c5db9a10a03d40dc3beb4c6ee 100644 --- a/include/uapi/drm/vc4_drm.h +++ b/include/uapi/drm/vc4_drm.h @@ -40,6 +40,7 @@ extern "C" { #define DRM_VC4_GET_PARAM 0x07 #define DRM_VC4_SET_TILING 0x08 #define DRM_VC4_GET_TILING 0x09 +#define DRM_VC4_LABEL_BO 0x0a #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) @@ -51,6 +52,7 @@ extern "C" { #define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param) #define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling) #define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling) +#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo) struct drm_vc4_submit_rcl_surface { __u32 hindex; /* Handle index, or ~0 if not present. */ @@ -153,6 +155,16 @@ struct drm_vc4_submit_cl { __u32 pad:24; #define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) +/* By default, the kernel gets to choose the order that the tiles are + * rendered in. If this is set, then the tiles will be rendered in a + * raster order, with the right-to-left vs left-to-right and + * top-to-bottom vs bottom-to-top dictated by + * VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*. This allows overlapping + * blits to be implemented using the 3D engine. + */ +#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1) +#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2) +#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3) __u32 flags; /* Returned value of the seqno of this render job (for the @@ -292,6 +304,7 @@ struct drm_vc4_get_hang_state { #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3 #define DRM_VC4_PARAM_SUPPORTS_ETC1 4 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5 +#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6 struct drm_vc4_get_param { __u32 param; @@ -311,6 +324,15 @@ struct drm_vc4_set_tiling { __u64 modifier; }; +/** + * struct drm_vc4_label_bo - Attach a name to a BO for debug purposes. + */ +struct drm_vc4_label_bo { + __u32 handle; + __u32 len; + __u64 name; +}; + #if defined(__cplusplus) } #endif diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index d9dfde9aa757aad51dff8d264b7d43b1170028c5..0bc784f5e0dbe15bc8d1f92c7941ff57b5008072 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -297,13 +297,17 @@ union drm_vmw_surface_reference_arg { * @version: Allows expanding the execbuf ioctl parameters without breaking * backwards compatibility, since user-space will always tell the kernel * which version it uses. - * @flags: Execbuf flags. None currently. + * @flags: Execbuf flags. + * @imported_fence_fd: FD for a fence imported from another device * * Argument to the DRM_VMW_EXECBUF Ioctl. */ #define DRM_VMW_EXECBUF_VERSION 2 +#define DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD (1 << 0) +#define DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD (1 << 1) + struct drm_vmw_execbuf_arg { __u64 commands; __u32 command_size; @@ -312,7 +316,7 @@ struct drm_vmw_execbuf_arg { __u32 version; __u32 flags; __u32 context_handle; - __u32 pad64; + __s32 imported_fence_fd; }; /** @@ -328,6 +332,7 @@ struct drm_vmw_execbuf_arg { * @passed_seqno: The highest seqno number processed by the hardware * so far. This can be used to mark user-space fence objects as signaled, and * to determine whether a fence seqno might be stale. + * @fd: FD associated with the fence, -1 if not exported * @error: This member should've been set to -EFAULT on submission. * The following actions should be take on completion: * error == -EFAULT: Fence communication failed. The host is synchronized. @@ -345,7 +350,7 @@ struct drm_vmw_fence_rep { __u32 mask; __u32 seqno; __u32 passed_seqno; - __u32 pad64; + __s32 fd; __s32 error; }; diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h index a2d4a8ac94ca8c1c83717cab0148fe359752743b..a04adbc70ddfb2a0a46efb8906c10dd49e26ec90 100644 --- a/include/uapi/linux/aio_abi.h +++ b/include/uapi/linux/aio_abi.h @@ -28,6 +28,7 @@ #define __LINUX__AIO_ABI_H #include +#include #include typedef __kernel_ulong_t aio_context_t; @@ -62,14 +63,6 @@ struct io_event { __s64 res2; /* secondary result */ }; -#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) -#define PADDED(x,y) x, y -#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) -#define PADDED(x,y) y, x -#else -#error edit for your odd byteorder. -#endif - /* * we always use a 64bit off_t when communicating * with userland. its up to libraries to do the @@ -79,8 +72,16 @@ struct io_event { struct iocb { /* these are internal to the kernel/libc. */ __u64 aio_data; /* data to be returned in event's data */ - __u32 PADDED(aio_key, aio_rw_flags); - /* the kernel sets aio_key to the req # */ + +#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) + __u32 aio_key; /* the kernel sets aio_key to the req # */ + __kernel_rwf_t aio_rw_flags; /* RWF_* flags */ +#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) + __kernel_rwf_t aio_rw_flags; /* RWF_* flags */ + __u32 aio_key; /* the kernel sets aio_key to the req # */ +#else +#error edit for your odd byteorder. +#endif /* common fields */ __u16 aio_lio_opcode; /* see IOCB_CMD_ above */ diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h index 51f891fb1b18ad9b14713fe3a4f2a541c9ca5442..84a9a0944e13501e3db7de994a2124e92d88f492 100644 --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -132,6 +132,7 @@ enum { /* struct binder_fd_array_object - object describing an array of fds in a buffer * @hdr: common header structure + * @pad: padding to ensure correct alignment * @num_fds: number of file descriptors in the buffer * @parent: index in offset array to buffer holding the fd array * @parent_offset: start offset of fd array in the buffer @@ -152,6 +153,7 @@ enum { */ struct binder_fd_array_object { struct binder_object_header hdr; + __u32 pad; binder_size_t num_fds; binder_size_t parent; binder_size_t parent_offset; @@ -184,6 +186,19 @@ struct binder_version { #define BINDER_CURRENT_PROTOCOL_VERSION 8 #endif +/* + * Use with BINDER_GET_NODE_DEBUG_INFO, driver reads ptr, writes to all fields. + * Set ptr to NULL for the first call to get the info for the first node, and + * then repeat the call passing the previously returned value to get the next + * nodes. ptr will be 0 when there are no more nodes. + */ +struct binder_node_debug_info { + binder_uintptr_t ptr; + binder_uintptr_t cookie; + __u32 has_strong_ref; + __u32 has_weak_ref; +}; + #define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) #define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32) @@ -191,6 +206,7 @@ struct binder_version { #define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32) #define BINDER_THREAD_EXIT _IOW('b', 8, __s32) #define BINDER_VERSION _IOWR('b', 9, struct binder_version) +#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info) /* * NOTE: Two special error codes you should check for when calling diff --git a/include/uapi/linux/auto_dev-ioctl.h b/include/uapi/linux/auto_dev-ioctl.h index 744b3d0609687b82bb198ed76c158417c22f09f9..5558db8e6646bc4abb46471b129331e8d1862b90 100644 --- a/include/uapi/linux/auto_dev-ioctl.h +++ b/include/uapi/linux/auto_dev-ioctl.h @@ -16,7 +16,7 @@ #define AUTOFS_DEVICE_NAME "autofs" #define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1 -#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0 +#define AUTOFS_DEV_IOCTL_VERSION_MINOR 1 #define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) diff --git a/include/uapi/linux/auto_fs4.h b/include/uapi/linux/auto_fs4.h index 7c6da423d54ee6f3298cdf479d91a900cb5b2c4c..9453e9a07c9d124fd31baf1868473fbb8fe218c2 100644 --- a/include/uapi/linux/auto_fs4.h +++ b/include/uapi/linux/auto_fs4.h @@ -155,8 +155,6 @@ enum { }; #define AUTOFS_IOC_EXPIRE_MULTI _IOW(AUTOFS_IOCTL, AUTOFS_IOC_EXPIRE_MULTI_CMD, int) -#define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI -#define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI #define AUTOFS_IOC_PROTOSUBVER _IOR(AUTOFS_IOCTL, AUTOFS_IOC_PROTOSUBVER_CMD, int) #define AUTOFS_IOC_ASKUMOUNT _IOR(AUTOFS_IOCTL, AUTOFS_IOC_ASKUMOUNT_CMD, int) diff --git a/include/uapi/linux/blktrace_api.h b/include/uapi/linux/blktrace_api.h index c590ca6bfbd9e05c1e828747859419a731be2730..9cdaedeadb84b96f627b7c4d2721a4551a23c6ca 100644 --- a/include/uapi/linux/blktrace_api.h +++ b/include/uapi/linux/blktrace_api.h @@ -52,6 +52,7 @@ enum blktrace_act { __BLK_TA_REMAP, /* bio was remapped */ __BLK_TA_ABORT, /* request aborted */ __BLK_TA_DRV_DATA, /* driver-specific binary data */ + __BLK_TA_CGROUP = 1 << 8, /* from a cgroup*/ }; /* @@ -61,6 +62,7 @@ enum blktrace_notify { __BLK_TN_PROCESS = 0, /* establish pid/name mapping */ __BLK_TN_TIMESTAMP, /* include system clock */ __BLK_TN_MESSAGE, /* Character string message */ + __BLK_TN_CGROUP = __BLK_TA_CGROUP, /* from a cgroup */ }; @@ -107,6 +109,7 @@ struct blk_io_trace { __u32 cpu; /* on what cpu did it happen */ __u16 error; /* completion error */ __u16 pdu_len; /* length of data after this trace */ + /* cgroup id will be stored here if exists */ }; /* diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index e99e3e6f8b3741829404c5bdce8c92af70a110f6..f90860d1f8979e03b10063a04179bed44c137e5a 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -30,9 +30,14 @@ #define BPF_FROM_LE BPF_TO_LE #define BPF_FROM_BE BPF_TO_BE +/* jmp encodings */ #define BPF_JNE 0x50 /* jump != */ +#define BPF_JLT 0xa0 /* LT is unsigned, '<' */ +#define BPF_JLE 0xb0 /* LE is unsigned, '<=' */ #define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ #define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ +#define BPF_JSLT 0xc0 /* SLT is signed, '<' */ +#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */ #define BPF_CALL 0x80 /* function call */ #define BPF_EXIT 0x90 /* function return */ @@ -104,6 +109,8 @@ enum bpf_map_type { BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_ARRAY_OF_MAPS, BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, }; enum bpf_prog_type { @@ -121,6 +128,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_LWT_OUT, BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, }; enum bpf_attach_type { @@ -128,6 +136,8 @@ enum bpf_attach_type { BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, + BPF_SK_SKB_STREAM_PARSER, + BPF_SK_SKB_STREAM_VERDICT, __MAX_BPF_ATTACH_TYPE }; @@ -153,6 +163,7 @@ enum bpf_attach_type { #define BPF_NOEXIST 1 /* create new element if it didn't exist */ #define BPF_EXIST 2 /* update existing element */ +/* flags for BPF_MAP_CREATE command */ #define BPF_F_NO_PREALLOC (1U << 0) /* Instead of having one common LRU list in the * BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list @@ -161,6 +172,8 @@ enum bpf_attach_type { * across different LRU lists. */ #define BPF_F_NO_COMMON_LRU (1U << 1) +/* Specify numa node during map creation */ +#define BPF_F_NUMA_NODE (1U << 2) union bpf_attr { struct { /* anonymous struct used by BPF_MAP_CREATE command */ @@ -168,8 +181,13 @@ union bpf_attr { __u32 key_size; /* size of key in bytes */ __u32 value_size; /* size of value in bytes */ __u32 max_entries; /* max number of entries in a map */ - __u32 map_flags; /* prealloc or not */ + __u32 map_flags; /* BPF_MAP_CREATE related + * flags defined above. + */ __u32 inner_map_fd; /* fd pointing to the inner map */ + __u32 numa_node; /* numa node (effective only if + * BPF_F_NUMA_NODE is set). + */ }; struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ @@ -294,7 +312,7 @@ union bpf_attr { * jump into another BPF program * @ctx: context pointer passed to next program * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY - * @index: index inside array that selects specific program to run + * @index: 32-bit index inside array that selects specific program to run * Return: 0 on success or negative error * * int bpf_clone_redirect(skb, ifindex, flags) @@ -344,9 +362,20 @@ union bpf_attr { * int bpf_redirect(ifindex, flags) * redirect to another netdev * @ifindex: ifindex of the net device - * @flags: bit 0 - if set, redirect to ingress instead of egress - * other bits - reserved - * Return: TC_ACT_REDIRECT + * @flags: + * cls_bpf: + * bit 0 - if set, redirect to ingress instead of egress + * other bits - reserved + * xdp_bpf: + * all bits - reserved + * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error + * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error + * int bpf_redirect_map(map, key, flags) + * redirect to endpoint in map + * @map: pointer to dev map + * @key: index in map to lookup + * @flags: -- + * Return: XDP_REDIRECT on success or XDP_ABORT on error * * u32 bpf_get_route_realm(skb) * retrieve a dst's tclassid @@ -539,6 +568,20 @@ union bpf_attr { * @mode: operation mode (enum bpf_adj_room_mode) * @flags: reserved for future use * Return: 0 on success or negative error code + * + * int bpf_sk_redirect_map(map, key, flags) + * Redirect skb to a sock in map using key as a lookup key for the + * sock in map. + * @map: pointer to sockmap + * @key: key to lookup sock in map + * @flags: reserved for future use + * Return: SK_REDIRECT + * + * int bpf_sock_map_update(skops, map, key, flags) + * @skops: pointer to bpf_sock_ops + * @map: pointer to sockmap to update + * @key: key to insert/update sock in map + * @flags: same flags as map update elem */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -591,7 +634,10 @@ union bpf_attr { FN(get_socket_uid), \ FN(set_hash), \ FN(setsockopt), \ - FN(skb_adjust_room), + FN(skb_adjust_room), \ + FN(redirect_map), \ + FN(sk_redirect_map), \ + FN(sock_map_update), \ /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call @@ -668,6 +714,15 @@ struct __sk_buff { __u32 data; __u32 data_end; __u32 napi_id; + + /* accessed by BPF_PROG_TYPE_sk_skb types */ + __u32 family; + __u32 remote_ip4; /* Stored in network byte order */ + __u32 local_ip4; /* Stored in network byte order */ + __u32 remote_ip6[4]; /* Stored in network byte order */ + __u32 local_ip6[4]; /* Stored in network byte order */ + __u32 remote_port; /* Stored in network byte order */ + __u32 local_port; /* stored in host byte order */ }; struct bpf_tunnel_key { @@ -703,20 +758,23 @@ struct bpf_sock { __u32 family; __u32 type; __u32 protocol; + __u32 mark; + __u32 priority; }; #define XDP_PACKET_HEADROOM 256 /* User return codes for XDP prog type. * A valid XDP program must return one of these defined values. All other - * return codes are reserved for future use. Unknown return codes will result - * in packet drop. + * return codes are reserved for future use. Unknown return codes will + * result in packet drops and a warning via bpf_warn_invalid_xdp_action(). */ enum xdp_action { XDP_ABORTED = 0, XDP_DROP, XDP_PASS, XDP_TX, + XDP_REDIRECT, }; /* user accessible metadata for XDP packet hook @@ -727,6 +785,12 @@ struct xdp_md { __u32 data_end; }; +enum sk_action { + SK_ABORTED = 0, + SK_DROP, + SK_REDIRECT, +}; + #define BPF_TAG_SIZE 8 struct bpf_prog_info { diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 9aa74f317747c7c37f2a7e8e725e766adde5d584..378230c163d5ecdf87a1d5062c8a431a7c9c5c45 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -255,13 +255,7 @@ struct btrfs_ioctl_fs_info_args { #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2) #define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3) -/* - * some patches floated around with a second compression method - * lets save that incompat here for when they do get in - * Note we don't actually support it, we're just reserving the - * number - */ -#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2 (1ULL << 4) +#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD (1ULL << 4) /* * older kernels tried to do bigger metadata blocks, but the diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h index 6fe14d001f68f77b98991d8650df0fcc8a6f3988..230e05d35191dafe5aa7dfdbc33a247e7e6bd51d 100644 --- a/include/uapi/linux/capability.h +++ b/include/uapi/linux/capability.h @@ -60,9 +60,13 @@ typedef struct __user_cap_data_struct { #define VFS_CAP_U32_2 2 #define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2)) -#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2 -#define VFS_CAP_U32 VFS_CAP_U32_2 -#define VFS_CAP_REVISION VFS_CAP_REVISION_2 +#define VFS_CAP_REVISION_3 0x03000000 +#define VFS_CAP_U32_3 2 +#define XATTR_CAPS_SZ_3 (sizeof(__le32)*(2 + 2*VFS_CAP_U32_3)) + +#define XATTR_CAPS_SZ XATTR_CAPS_SZ_3 +#define VFS_CAP_U32 VFS_CAP_U32_3 +#define VFS_CAP_REVISION VFS_CAP_REVISION_3 struct vfs_cap_data { __le32 magic_etc; /* Little endian */ @@ -72,6 +76,18 @@ struct vfs_cap_data { } data[VFS_CAP_U32]; }; +/* + * same as vfs_cap_data but with a rootid at the end + */ +struct vfs_ns_cap_data { + __le32 magic_etc; + struct { + __le32 permitted; /* Little endian */ + __le32 inheritable; /* Little endian */ + } data[VFS_CAP_U32]; + __le32 rootid; +}; + #ifndef __KERNEL__ /* diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h index c451eec42a83101a6eea0219788165600d128e49..270b251a3d9b5edf4f74fbc518a7e10756899116 100644 --- a/include/uapi/linux/cec-funcs.h +++ b/include/uapi/linux/cec-funcs.h @@ -895,6 +895,7 @@ static inline void cec_ops_report_features(const struct cec_msg *msg, *cec_version = msg->msg[2]; *all_device_types = msg->msg[3]; *rc_profile = p; + *dev_features = NULL; while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT)) p++; if (!(*p & CEC_OP_FEAT_EXT)) { diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index 44579a24f95d637836d528d803a05c2c27323234..4351c3481aea19720c2c96130f3a642bb5bfb44d 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -318,6 +318,7 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) #define CEC_MODE_FOLLOWER (0x1 << 4) #define CEC_MODE_EXCL_FOLLOWER (0x2 << 4) #define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4) +#define CEC_MODE_MONITOR_PIN (0xd << 4) #define CEC_MODE_MONITOR (0xe << 4) #define CEC_MODE_MONITOR_ALL (0xf << 4) #define CEC_MODE_FOLLOWER_MSK 0xf0 @@ -338,6 +339,8 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) #define CEC_CAP_MONITOR_ALL (1 << 5) /* Hardware can use CEC only if the HDMI HPD pin is high. */ #define CEC_CAP_NEEDS_HPD (1 << 6) +/* Hardware can monitor CEC pin transitions */ +#define CEC_CAP_MONITOR_PIN (1 << 7) /** * struct cec_caps - CEC capabilities structure. @@ -405,8 +408,11 @@ struct cec_log_addrs { * didn't empty the message queue in time */ #define CEC_EVENT_LOST_MSGS 2 +#define CEC_EVENT_PIN_CEC_LOW 3 +#define CEC_EVENT_PIN_CEC_HIGH 4 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0) +#define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1) /** * struct cec_event_state_change - used when the CEC adapter changes state. @@ -419,7 +425,7 @@ struct cec_event_state_change { }; /** - * struct cec_event_lost_msgs - tells you how many messages were lost due. + * struct cec_event_lost_msgs - tells you how many messages were lost. * @lost_msgs: how many messages were lost. */ struct cec_event_lost_msgs { diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index b0e807ac53bbfd3b088533381ecbf25a689633b0..0cbca96c66b9447cac9c69d6f5b72d4c27d739dd 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -226,4 +226,22 @@ enum devlink_dpipe_action_type { DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY, }; +enum devlink_dpipe_field_ethernet_id { + DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, +}; + +enum devlink_dpipe_field_ipv4_id { + DEVLINK_DPIPE_FIELD_IPV4_DST_IP, +}; + +enum devlink_dpipe_field_ipv6_id { + DEVLINK_DPIPE_FIELD_IPV6_DST_IP, +}; + +enum devlink_dpipe_header_id { + DEVLINK_DPIPE_HEADER_ETHERNET, + DEVLINK_DPIPE_HEADER_IPV4, + DEVLINK_DPIPE_HEADER_IPV6, +}; + #endif /* _UAPI_LINUX_DEVLINK_H_ */ diff --git a/include/uapi/linux/dlm_netlink.h b/include/uapi/linux/dlm_netlink.h index 647c8ef2722795bdc8bd4f4074799ab80e0a02b2..ef1e2e08769a0ad35ee7072b4d7866858794ba80 100644 --- a/include/uapi/linux/dlm_netlink.h +++ b/include/uapi/linux/dlm_netlink.h @@ -10,6 +10,7 @@ #define _DLM_NETLINK_H #include +#include enum { DLM_STATUS_WAITING = 1, diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h index 412c06a624c83674e02f1d6669c4201d2a6c6e1b..ccaea525340b9d857a9f4fe8a5834def9c9367be 100644 --- a/include/uapi/linux/dm-ioctl.h +++ b/include/uapi/linux/dm-ioctl.h @@ -269,9 +269,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 36 +#define DM_VERSION_MINOR 37 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2017-06-09)" +#define DM_VERSION_EXTRA "-ioctl (2017-09-20)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ diff --git a/include/uapi/linux/dvb/ca.h b/include/uapi/linux/dvb/ca.h index c18537f3e449bb219a1b48f1b9e46c1c3aa00820..cb150029fdffab2ece722f7a888ab286a0c310fd 100644 --- a/include/uapi/linux/dvb/ca.h +++ b/include/uapi/linux/dvb/ca.h @@ -24,67 +24,131 @@ #ifndef _DVBCA_H_ #define _DVBCA_H_ -/* slot interface types and info */ - -typedef struct ca_slot_info { - int num; /* slot number */ +/** + * struct ca_slot_info - CA slot interface types and info. + * + * @num: slot number. + * @type: slot type. + * @flags: flags applicable to the slot. + * + * This struct stores the CA slot information. + * + * @type can be: + * + * - %CA_CI - CI high level interface; + * - %CA_CI_LINK - CI link layer level interface; + * - %CA_CI_PHYS - CI physical layer level interface; + * - %CA_DESCR - built-in descrambler; + * - %CA_SC -simple smart card interface. + * + * @flags can be: + * + * - %CA_CI_MODULE_PRESENT - module (or card) inserted; + * - %CA_CI_MODULE_READY - module is ready for usage. + */ - int type; /* CA interface this slot supports */ -#define CA_CI 1 /* CI high level interface */ -#define CA_CI_LINK 2 /* CI link layer level interface */ -#define CA_CI_PHYS 4 /* CI physical layer level interface */ -#define CA_DESCR 8 /* built-in descrambler */ -#define CA_SC 128 /* simple smart card interface */ +struct ca_slot_info { + int num; + int type; +#define CA_CI 1 +#define CA_CI_LINK 2 +#define CA_CI_PHYS 4 +#define CA_DESCR 8 +#define CA_SC 128 unsigned int flags; -#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ +#define CA_CI_MODULE_PRESENT 1 #define CA_CI_MODULE_READY 2 -} ca_slot_info_t; - +}; -/* descrambler types and info */ -typedef struct ca_descr_info { - unsigned int num; /* number of available descramblers (keys) */ - unsigned int type; /* type of supported scrambling system */ +/** + * struct ca_descr_info - descrambler types and info. + * + * @num: number of available descramblers (keys). + * @type: type of supported scrambling system. + * + * Identifies the number of descramblers and their type. + * + * @type can be: + * + * - %CA_ECD - European Common Descrambler (ECD) hardware; + * - %CA_NDS - Videoguard (NDS) hardware; + * - %CA_DSS - Distributed Sample Scrambling (DSS) hardware. + */ +struct ca_descr_info { + unsigned int num; + unsigned int type; #define CA_ECD 1 #define CA_NDS 2 #define CA_DSS 4 -} ca_descr_info_t; +}; -typedef struct ca_caps { - unsigned int slot_num; /* total number of CA card and module slots */ - unsigned int slot_type; /* OR of all supported types */ - unsigned int descr_num; /* total number of descrambler slots (keys) */ - unsigned int descr_type; /* OR of all supported types */ -} ca_caps_t; +/** + * struct ca_caps - CA slot interface capabilities. + * + * @slot_num: total number of CA card and module slots. + * @slot_type: bitmap with all supported types as defined at + * &struct ca_slot_info (e. g. %CA_CI, %CA_CI_LINK, etc). + * @descr_num: total number of descrambler slots (keys) + * @descr_type: bitmap with all supported types as defined at + * &struct ca_descr_info (e. g. %CA_ECD, %CA_NDS, etc). + */ +struct ca_caps { + unsigned int slot_num; + unsigned int slot_type; + unsigned int descr_num; + unsigned int descr_type; +}; -/* a message to/from a CI-CAM */ -typedef struct ca_msg { +/** + * struct ca_msg - a message to/from a CI-CAM + * + * @index: unused + * @type: unused + * @length: length of the message + * @msg: message + * + * This struct carries a message to be send/received from a CI CA module. + */ +struct ca_msg { unsigned int index; unsigned int type; unsigned int length; unsigned char msg[256]; -} ca_msg_t; +}; -typedef struct ca_descr { +/** + * struct ca_descr - CA descrambler control words info + * + * @index: CA Descrambler slot + * @parity: control words parity, where 0 means even and 1 means odd + * @cw: CA Descrambler control words + */ +struct ca_descr { unsigned int index; - unsigned int parity; /* 0 == even, 1 == odd */ + unsigned int parity; unsigned char cw[8]; -} ca_descr_t; - -typedef struct ca_pid { - unsigned int pid; - int index; /* -1 == disable*/ -} ca_pid_t; +}; #define CA_RESET _IO('o', 128) -#define CA_GET_CAP _IOR('o', 129, ca_caps_t) -#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t) -#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) -#define CA_GET_MSG _IOR('o', 132, ca_msg_t) -#define CA_SEND_MSG _IOW('o', 133, ca_msg_t) -#define CA_SET_DESCR _IOW('o', 134, ca_descr_t) -#define CA_SET_PID _IOW('o', 135, ca_pid_t) +#define CA_GET_CAP _IOR('o', 129, struct ca_caps) +#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info) +#define CA_GET_DESCR_INFO _IOR('o', 131, struct ca_descr_info) +#define CA_GET_MSG _IOR('o', 132, struct ca_msg) +#define CA_SEND_MSG _IOW('o', 133, struct ca_msg) +#define CA_SET_DESCR _IOW('o', 134, struct ca_descr) + +#if !defined(__KERNEL__) + +/* This is needed for legacy userspace support */ +typedef struct ca_slot_info ca_slot_info_t; +typedef struct ca_descr_info ca_descr_info_t; +typedef struct ca_caps ca_caps_t; +typedef struct ca_msg ca_msg_t; +typedef struct ca_descr ca_descr_t; + +#endif + #endif diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h index 427e4899ed69acd1ab31722b7723ad15db290a04..4aa5f6a1815aa9729193651a4e32a6028261eb45 100644 --- a/include/uapi/linux/dvb/dmx.h +++ b/include/uapi/linux/dvb/dmx.h @@ -32,28 +32,74 @@ #define DMX_FILTER_SIZE 16 -enum dmx_output -{ - DMX_OUT_DECODER, /* Streaming directly to decoder. */ - DMX_OUT_TAP, /* Output going to a memory buffer */ - /* (to be retrieved via the read command).*/ - DMX_OUT_TS_TAP, /* Output multiplexed into a new TS */ - /* (to be retrieved by reading from the */ - /* logical DVR device). */ - DMX_OUT_TSDEMUX_TAP /* Like TS_TAP but retrieved from the DMX device */ +/** + * enum dmx_output - Output for the demux. + * + * @DMX_OUT_DECODER: + * Streaming directly to decoder. + * @DMX_OUT_TAP: + * Output going to a memory buffer (to be retrieved via the read command). + * Delivers the stream output to the demux device on which the ioctl + * is called. + * @DMX_OUT_TS_TAP: + * Output multiplexed into a new TS (to be retrieved by reading from the + * logical DVR device). Routes output to the logical DVR device + * ``/dev/dvb/adapter?/dvr?``, which delivers a TS multiplexed from all + * filters for which @DMX_OUT_TS_TAP was specified. + * @DMX_OUT_TSDEMUX_TAP: + * Like @DMX_OUT_TS_TAP but retrieved from the DMX device. + */ +enum dmx_output { + DMX_OUT_DECODER, + DMX_OUT_TAP, + DMX_OUT_TS_TAP, + DMX_OUT_TSDEMUX_TAP }; -typedef enum dmx_output dmx_output_t; -typedef enum dmx_input -{ - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ -} dmx_input_t; +/** + * enum dmx_input - Input from the demux. + * + * @DMX_IN_FRONTEND: Input from a front-end device. + * @DMX_IN_DVR: Input from the logical DVR device. + */ +enum dmx_input { + DMX_IN_FRONTEND, + DMX_IN_DVR +}; +/** + * enum dmx_ts_pes - type of the PES filter. + * + * @DMX_PES_AUDIO0: first audio PID. Also referred as @DMX_PES_AUDIO. + * @DMX_PES_VIDEO0: first video PID. Also referred as @DMX_PES_VIDEO. + * @DMX_PES_TELETEXT0: first teletext PID. Also referred as @DMX_PES_TELETEXT. + * @DMX_PES_SUBTITLE0: first subtitle PID. Also referred as @DMX_PES_SUBTITLE. + * @DMX_PES_PCR0: first Program Clock Reference PID. + * Also referred as @DMX_PES_PCR. + * + * @DMX_PES_AUDIO1: second audio PID. + * @DMX_PES_VIDEO1: second video PID. + * @DMX_PES_TELETEXT1: second teletext PID. + * @DMX_PES_SUBTITLE1: second subtitle PID. + * @DMX_PES_PCR1: second Program Clock Reference PID. + * + * @DMX_PES_AUDIO2: third audio PID. + * @DMX_PES_VIDEO2: third video PID. + * @DMX_PES_TELETEXT2: third teletext PID. + * @DMX_PES_SUBTITLE2: third subtitle PID. + * @DMX_PES_PCR2: third Program Clock Reference PID. + * + * @DMX_PES_AUDIO3: fourth audio PID. + * @DMX_PES_VIDEO3: fourth video PID. + * @DMX_PES_TELETEXT3: fourth teletext PID. + * @DMX_PES_SUBTITLE3: fourth subtitle PID. + * @DMX_PES_PCR3: fourth Program Clock Reference PID. + * + * @DMX_PES_OTHER: any other PID. + */ -typedef enum dmx_ts_pes -{ +enum dmx_ts_pes { DMX_PES_AUDIO0, DMX_PES_VIDEO0, DMX_PES_TELETEXT0, @@ -79,7 +125,7 @@ typedef enum dmx_ts_pes DMX_PES_PCR3, DMX_PES_OTHER -} dmx_pes_type_t; +}; #define DMX_PES_AUDIO DMX_PES_AUDIO0 #define DMX_PES_VIDEO DMX_PES_VIDEO0 @@ -88,56 +134,80 @@ typedef enum dmx_ts_pes #define DMX_PES_PCR DMX_PES_PCR0 -typedef struct dmx_filter -{ + +/** + * struct dmx_filter - Specifies a section header filter. + * + * @filter: bit array with bits to be matched at the section header. + * @mask: bits that are valid at the filter bit array. + * @mode: mode of match: if bit is zero, it will match if equal (positive + * match); if bit is one, it will match if the bit is negated. + * + * Note: All arrays in this struct have a size of DMX_FILTER_SIZE (16 bytes). + */ +struct dmx_filter { __u8 filter[DMX_FILTER_SIZE]; __u8 mask[DMX_FILTER_SIZE]; __u8 mode[DMX_FILTER_SIZE]; -} dmx_filter_t; - +}; -struct dmx_sct_filter_params -{ - __u16 pid; - dmx_filter_t filter; - __u32 timeout; - __u32 flags; +/** + * struct dmx_sct_filter_params - Specifies a section filter. + * + * @pid: PID to be filtered. + * @filter: section header filter, as defined by &struct dmx_filter. + * @timeout: maximum time to filter, in milliseconds. + * @flags: extra flags for the section filter. + * + * Carries the configuration for a MPEG-TS section filter. + * + * The @flags can be: + * + * - %DMX_CHECK_CRC - only deliver sections where the CRC check succeeded; + * - %DMX_ONESHOT - disable the section filter after one section + * has been delivered; + * - %DMX_IMMEDIATE_START - Start filter immediately without requiring a + * :ref:`DMX_START`. + */ +struct dmx_sct_filter_params { + __u16 pid; + struct dmx_filter filter; + __u32 timeout; + __u32 flags; #define DMX_CHECK_CRC 1 #define DMX_ONESHOT 2 #define DMX_IMMEDIATE_START 4 -#define DMX_KERNEL_CLIENT 0x8000 }; - -struct dmx_pes_filter_params -{ - __u16 pid; - dmx_input_t input; - dmx_output_t output; - dmx_pes_type_t pes_type; - __u32 flags; +/** + * struct dmx_pes_filter_params - Specifies Packetized Elementary Stream (PES) + * filter parameters. + * + * @pid: PID to be filtered. + * @input: Demux input, as specified by &enum dmx_input. + * @output: Demux output, as specified by &enum dmx_output. + * @pes_type: Type of the pes filter, as specified by &enum dmx_pes_type. + * @flags: Demux PES flags. + */ +struct dmx_pes_filter_params { + __u16 pid; + enum dmx_input input; + enum dmx_output output; + enum dmx_ts_pes pes_type; + __u32 flags; }; -typedef struct dmx_caps { - __u32 caps; - int num_decoders; -} dmx_caps_t; - -typedef enum dmx_source { - DMX_SOURCE_FRONT0 = 0, - DMX_SOURCE_FRONT1, - DMX_SOURCE_FRONT2, - DMX_SOURCE_FRONT3, - DMX_SOURCE_DVR0 = 16, - DMX_SOURCE_DVR1, - DMX_SOURCE_DVR2, - DMX_SOURCE_DVR3 -} dmx_source_t; - +/** + * struct dmx_stc - Stores System Time Counter (STC) information. + * + * @num: input data: number of the STC, from 0 to N. + * @base: output: divisor for STC to get 90 kHz clock. + * @stc: output: stc in @base * 90 kHz units. + */ struct dmx_stc { - unsigned int num; /* input : which STC? 0..N */ - unsigned int base; /* output: divisor for stc to get 90 kHz clock */ - __u64 stc; /* output: stc in 'base'*90 kHz units */ + unsigned int num; + unsigned int base; + __u64 stc; }; #define DMX_START _IO('o', 41) @@ -146,10 +216,18 @@ struct dmx_stc { #define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params) #define DMX_SET_BUFFER_SIZE _IO('o', 45) #define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5]) -#define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t) -#define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t) #define DMX_GET_STC _IOWR('o', 50, struct dmx_stc) #define DMX_ADD_PID _IOW('o', 51, __u16) #define DMX_REMOVE_PID _IOW('o', 52, __u16) +#if !defined(__KERNEL__) + +/* This is needed for legacy userspace support */ +typedef enum dmx_output dmx_output_t; +typedef enum dmx_input dmx_input_t; +typedef enum dmx_ts_pes dmx_pes_type_t; +typedef struct dmx_filter dmx_filter_t; + +#endif + #endif /* _UAPI_DVBDMX_H_ */ diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 00a20cd21ee230dabd55954d58209d1e59025d24..861cacd5711fe2dd8f3a63e1e9b44cd4a2f88edb 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -28,13 +28,46 @@ #include -enum fe_type { - FE_QPSK, - FE_QAM, - FE_OFDM, - FE_ATSC -}; - +/** + * enum fe_caps - Frontend capabilities + * + * @FE_IS_STUPID: There's something wrong at the + * frontend, and it can't report its + * capabilities. + * @FE_CAN_INVERSION_AUTO: Can auto-detect frequency spectral + * band inversion + * @FE_CAN_FEC_1_2: Supports FEC 1/2 + * @FE_CAN_FEC_2_3: Supports FEC 2/3 + * @FE_CAN_FEC_3_4: Supports FEC 3/4 + * @FE_CAN_FEC_4_5: Supports FEC 4/5 + * @FE_CAN_FEC_5_6: Supports FEC 5/6 + * @FE_CAN_FEC_6_7: Supports FEC 6/7 + * @FE_CAN_FEC_7_8: Supports FEC 7/8 + * @FE_CAN_FEC_8_9: Supports FEC 8/9 + * @FE_CAN_FEC_AUTO: Can auto-detect FEC + * @FE_CAN_QPSK: Supports QPSK modulation + * @FE_CAN_QAM_16: Supports 16-QAM modulation + * @FE_CAN_QAM_32: Supports 32-QAM modulation + * @FE_CAN_QAM_64: Supports 64-QAM modulation + * @FE_CAN_QAM_128: Supports 128-QAM modulation + * @FE_CAN_QAM_256: Supports 256-QAM modulation + * @FE_CAN_QAM_AUTO: Can auto-detect QAM modulation + * @FE_CAN_TRANSMISSION_MODE_AUTO: Can auto-detect transmission mode + * @FE_CAN_BANDWIDTH_AUTO: Can auto-detect bandwidth + * @FE_CAN_GUARD_INTERVAL_AUTO: Can auto-detect guard interval + * @FE_CAN_HIERARCHY_AUTO: Can auto-detect hierarchy + * @FE_CAN_8VSB: Supports 8-VSB modulation + * @FE_CAN_16VSB: Supporta 16-VSB modulation + * @FE_HAS_EXTENDED_CAPS: Unused + * @FE_CAN_MULTISTREAM: Supports multistream filtering + * @FE_CAN_TURBO_FEC: Supports "turbo FEC" modulation + * @FE_CAN_2G_MODULATION: Supports "2nd generation" modulation, + * e. g. DVB-S2, DVB-T2, DVB-C2 + * @FE_NEEDS_BENDING: Unused + * @FE_CAN_RECOVER: Can recover from a cable unplug + * automatically + * @FE_CAN_MUTE_TS: Can stop spurious TS data output + */ enum fe_caps { FE_IS_STUPID = 0, FE_CAN_INVERSION_AUTO = 0x1, @@ -60,15 +93,55 @@ enum fe_caps { FE_CAN_HIERARCHY_AUTO = 0x100000, FE_CAN_8VSB = 0x200000, FE_CAN_16VSB = 0x400000, - FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */ - FE_CAN_MULTISTREAM = 0x4000000, /* frontend supports multistream filtering */ - FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */ - FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */ - FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */ - FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */ - FE_CAN_MUTE_TS = 0x80000000 /* frontend can stop spurious TS data output */ + FE_HAS_EXTENDED_CAPS = 0x800000, + FE_CAN_MULTISTREAM = 0x4000000, + FE_CAN_TURBO_FEC = 0x8000000, + FE_CAN_2G_MODULATION = 0x10000000, + FE_NEEDS_BENDING = 0x20000000, + FE_CAN_RECOVER = 0x40000000, + FE_CAN_MUTE_TS = 0x80000000 +}; + +/* + * DEPRECATED: Should be kept just due to backward compatibility. + */ +enum fe_type { + FE_QPSK, + FE_QAM, + FE_OFDM, + FE_ATSC }; +/** + * struct dvb_frontend_info - Frontend properties and capabilities + * + * @name: Name of the frontend + * @type: **DEPRECATED**. + * Should not be used on modern programs, + * as a frontend may have more than one type. + * In order to get the support types of a given + * frontend, use :c:type:`DTV_ENUM_DELSYS` + * instead. + * @frequency_min: Minimal frequency supported by the frontend. + * @frequency_max: Minimal frequency supported by the frontend. + * @frequency_stepsize: All frequencies are multiple of this value. + * @frequency_tolerance: Frequency tolerance. + * @symbol_rate_min: Minimal symbol rate, in bauds + * (for Cable/Satellite systems). + * @symbol_rate_max: Maximal symbol rate, in bauds + * (for Cable/Satellite systems). + * @symbol_rate_tolerance: Maximal symbol rate tolerance, in ppm + * (for Cable/Satellite systems). + * @notifier_delay: **DEPRECATED**. Not used by any driver. + * @caps: Capabilities supported by the frontend, + * as specified in &enum fe_caps. + * + * .. note: + * + * #. The frequencies are specified in Hz for Terrestrial and Cable + * systems. + * #. The frequencies are specified in kHz for Satellite systems. + */ struct dvb_frontend_info { char name[128]; enum fe_type type; /* DEPRECATED. Use DTV_ENUM_DELSYS instead */ @@ -78,55 +151,105 @@ struct dvb_frontend_info { __u32 frequency_tolerance; __u32 symbol_rate_min; __u32 symbol_rate_max; - __u32 symbol_rate_tolerance; /* ppm */ + __u32 symbol_rate_tolerance; __u32 notifier_delay; /* DEPRECATED */ enum fe_caps caps; }; - /** - * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for - * the meaning of this struct... + * struct dvb_diseqc_master_cmd - DiSEqC master command + * + * @msg: + * DiSEqC message to be sent. It contains a 3 bytes header with: + * framing + address + command, and an optional argument + * of up to 3 bytes of data. + * @msg_len: + * Length of the DiSEqC message. Valid values are 3 to 6. + * + * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for + * the possible messages that can be used. */ struct dvb_diseqc_master_cmd { - __u8 msg [6]; /* { framing, address, command, data [3] } */ - __u8 msg_len; /* valid values are 3...6 */ + __u8 msg[6]; + __u8 msg_len; }; +/** + * struct dvb_diseqc_slave_reply - DiSEqC received data + * + * @msg: + * DiSEqC message buffer to store a message received via DiSEqC. + * It contains one byte header with: framing and + * an optional argument of up to 3 bytes of data. + * @msg_len: + * Length of the DiSEqC message. Valid values are 0 to 4, + * where 0 means no message. + * @timeout: + * Return from ioctl after timeout ms with errorcode when + * no message was received. + * + * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for + * the possible messages that can be used. + */ struct dvb_diseqc_slave_reply { - __u8 msg [4]; /* { framing, data [3] } */ - __u8 msg_len; /* valid values are 0...4, 0 means no msg */ - int timeout; /* return from ioctl after timeout ms with */ -}; /* errorcode when no message was received */ + __u8 msg[4]; + __u8 msg_len; + int timeout; +}; +/** + * enum fe_sec_voltage - DC Voltage used to feed the LNBf + * + * @SEC_VOLTAGE_13: Output 13V to the LNBf + * @SEC_VOLTAGE_18: Output 18V to the LNBf + * @SEC_VOLTAGE_OFF: Don't feed the LNBf with a DC voltage + */ enum fe_sec_voltage { SEC_VOLTAGE_13, SEC_VOLTAGE_18, SEC_VOLTAGE_OFF }; +/** + * enum fe_sec_tone_mode - Type of tone to be send to the LNBf. + * @SEC_TONE_ON: Sends a 22kHz tone burst to the antenna. + * @SEC_TONE_OFF: Don't send a 22kHz tone to the antenna (except + * if the ``FE_DISEQC_*`` ioctls are called). + */ enum fe_sec_tone_mode { SEC_TONE_ON, SEC_TONE_OFF }; +/** + * enum fe_sec_mini_cmd - Type of mini burst to be sent + * + * @SEC_MINI_A: Sends a mini-DiSEqC 22kHz '0' Tone Burst to select + * satellite-A + * @SEC_MINI_B: Sends a mini-DiSEqC 22kHz '1' Data Burst to select + * satellite-B + */ enum fe_sec_mini_cmd { SEC_MINI_A, SEC_MINI_B }; /** - * enum fe_status - enumerates the possible frontend status - * @FE_HAS_SIGNAL: found something above the noise level - * @FE_HAS_CARRIER: found a DVB signal - * @FE_HAS_VITERBI: FEC is stable - * @FE_HAS_SYNC: found sync bytes - * @FE_HAS_LOCK: everything's working - * @FE_TIMEDOUT: no lock within the last ~2 seconds - * @FE_REINIT: frontend was reinitialized, application is recommended - * to reset DiSEqC, tone and parameters + * enum fe_status - Enumerates the possible frontend status. + * @FE_NONE: The frontend doesn't have any kind of lock. + * That's the initial frontend status + * @FE_HAS_SIGNAL: Has found something above the noise level. + * @FE_HAS_CARRIER: Has found a signal. + * @FE_HAS_VITERBI: FEC inner coding (Viterbi, LDPC or other inner code). + * is stable. + * @FE_HAS_SYNC: Synchronization bytes was found. + * @FE_HAS_LOCK: Digital TV were locked and everything is working. + * @FE_TIMEDOUT: Fo lock within the last about 2 seconds. + * @FE_REINIT: Frontend was reinitialized, application is recommended + * to reset DiSEqC, tone and parameters. */ enum fe_status { + FE_NONE = 0x00, FE_HAS_SIGNAL = 0x01, FE_HAS_CARRIER = 0x02, FE_HAS_VITERBI = 0x04, @@ -136,12 +259,45 @@ enum fe_status { FE_REINIT = 0x40, }; +/** + * enum fe_spectral_inversion - Type of inversion band + * + * @INVERSION_OFF: Don't do spectral band inversion. + * @INVERSION_ON: Do spectral band inversion. + * @INVERSION_AUTO: Autodetect spectral band inversion. + * + * This parameter indicates if spectral inversion should be presumed or + * not. In the automatic setting (``INVERSION_AUTO``) the hardware will try + * to figure out the correct setting by itself. If the hardware doesn't + * support, the %dvb_frontend will try to lock at the carrier first with + * inversion off. If it fails, it will try to enable inversion. + */ enum fe_spectral_inversion { INVERSION_OFF, INVERSION_ON, INVERSION_AUTO }; +/** + * enum fe_code_rate - Type of Forward Error Correction (FEC) + * + * + * @FEC_NONE: No Forward Error Correction Code + * @FEC_1_2: Forward Error Correction Code 1/2 + * @FEC_2_3: Forward Error Correction Code 2/3 + * @FEC_3_4: Forward Error Correction Code 3/4 + * @FEC_4_5: Forward Error Correction Code 4/5 + * @FEC_5_6: Forward Error Correction Code 5/6 + * @FEC_6_7: Forward Error Correction Code 6/7 + * @FEC_7_8: Forward Error Correction Code 7/8 + * @FEC_8_9: Forward Error Correction Code 8/9 + * @FEC_AUTO: Autodetect Error Correction Code + * @FEC_3_5: Forward Error Correction Code 3/5 + * @FEC_9_10: Forward Error Correction Code 9/10 + * @FEC_2_5: Forward Error Correction Code 2/5 + * + * Please note that not all FEC types are supported by a given standard. + */ enum fe_code_rate { FEC_NONE = 0, FEC_1_2, @@ -158,6 +314,26 @@ enum fe_code_rate { FEC_2_5, }; +/** + * enum fe_modulation - Type of modulation/constellation + * @QPSK: QPSK modulation + * @QAM_16: 16-QAM modulation + * @QAM_32: 32-QAM modulation + * @QAM_64: 64-QAM modulation + * @QAM_128: 128-QAM modulation + * @QAM_256: 256-QAM modulation + * @QAM_AUTO: Autodetect QAM modulation + * @VSB_8: 8-VSB modulation + * @VSB_16: 16-VSB modulation + * @PSK_8: 8-PSK modulation + * @APSK_16: 16-APSK modulation + * @APSK_32: 32-APSK modulation + * @DQPSK: DQPSK modulation + * @QAM_4_NR: 4-QAM-NR modulation + * + * Please note that not all modulations are supported by a given standard. + * + */ enum fe_modulation { QPSK, QAM_16, @@ -175,6 +351,32 @@ enum fe_modulation { QAM_4_NR, }; +/** + * enum fe_transmit_mode - Transmission mode + * + * @TRANSMISSION_MODE_AUTO: + * Autodetect transmission mode. The hardware will try to find the + * correct FFT-size (if capable) to fill in the missing parameters. + * @TRANSMISSION_MODE_1K: + * Transmission mode 1K + * @TRANSMISSION_MODE_2K: + * Transmission mode 2K + * @TRANSMISSION_MODE_8K: + * Transmission mode 8K + * @TRANSMISSION_MODE_4K: + * Transmission mode 4K + * @TRANSMISSION_MODE_16K: + * Transmission mode 16K + * @TRANSMISSION_MODE_32K: + * Transmission mode 32K + * @TRANSMISSION_MODE_C1: + * Single Carrier (C=1) transmission mode (DTMB only) + * @TRANSMISSION_MODE_C3780: + * Multi Carrier (C=3780) transmission mode (DTMB only) + * + * Please note that not all transmission modes are supported by a given + * standard. + */ enum fe_transmit_mode { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, @@ -187,6 +389,23 @@ enum fe_transmit_mode { TRANSMISSION_MODE_C3780, }; +/** + * enum fe_guard_interval - Guard interval + * + * @GUARD_INTERVAL_AUTO: Autodetect the guard interval + * @GUARD_INTERVAL_1_128: Guard interval 1/128 + * @GUARD_INTERVAL_1_32: Guard interval 1/32 + * @GUARD_INTERVAL_1_16: Guard interval 1/16 + * @GUARD_INTERVAL_1_8: Guard interval 1/8 + * @GUARD_INTERVAL_1_4: Guard interval 1/4 + * @GUARD_INTERVAL_19_128: Guard interval 19/128 + * @GUARD_INTERVAL_19_256: Guard interval 19/256 + * @GUARD_INTERVAL_PN420: PN length 420 (1/4) + * @GUARD_INTERVAL_PN595: PN length 595 (1/6) + * @GUARD_INTERVAL_PN945: PN length 945 (1/9) + * + * Please note that not all guard intervals are supported by a given standard. + */ enum fe_guard_interval { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, @@ -201,6 +420,16 @@ enum fe_guard_interval { GUARD_INTERVAL_PN945, }; +/** + * enum fe_hierarchy - Hierarchy + * @HIERARCHY_NONE: No hierarchy + * @HIERARCHY_AUTO: Autodetect hierarchy (if supported) + * @HIERARCHY_1: Hierarchy 1 + * @HIERARCHY_2: Hierarchy 2 + * @HIERARCHY_4: Hierarchy 4 + * + * Please note that not all hierarchy types are supported by a given standard. + */ enum fe_hierarchy { HIERARCHY_NONE, HIERARCHY_1, @@ -209,6 +438,15 @@ enum fe_hierarchy { HIERARCHY_AUTO }; +/** + * enum fe_interleaving - Interleaving + * @INTERLEAVING_NONE: No interleaving. + * @INTERLEAVING_AUTO: Auto-detect interleaving. + * @INTERLEAVING_240: Interleaving of 240 symbols. + * @INTERLEAVING_720: Interleaving of 720 symbols. + * + * Please note that, currently, only DTMB uses it. + */ enum fe_interleaving { INTERLEAVING_NONE, INTERLEAVING_AUTO, @@ -216,7 +454,8 @@ enum fe_interleaving { INTERLEAVING_720, }; -/* S2API Commands */ +/* DVBv5 property Commands */ + #define DTV_UNDEFINED 0 #define DTV_TUNE 1 #define DTV_CLEAR 2 @@ -309,19 +548,79 @@ enum fe_interleaving { #define DTV_MAX_COMMAND DTV_STAT_TOTAL_BLOCK_COUNT +/** + * enum fe_pilot - Type of pilot tone + * + * @PILOT_ON: Pilot tones enabled + * @PILOT_OFF: Pilot tones disabled + * @PILOT_AUTO: Autodetect pilot tones + */ enum fe_pilot { PILOT_ON, PILOT_OFF, PILOT_AUTO, }; +/** + * enum fe_rolloff - Rolloff factor + * @ROLLOFF_35: Roloff factor: α=35% + * @ROLLOFF_20: Roloff factor: α=20% + * @ROLLOFF_25: Roloff factor: α=25% + * @ROLLOFF_AUTO: Auto-detect the roloff factor. + * + * .. note: + * + * Roloff factor of 35% is implied on DVB-S. On DVB-S2, it is default. + */ enum fe_rolloff { - ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */ + ROLLOFF_35, ROLLOFF_20, ROLLOFF_25, ROLLOFF_AUTO, }; +/** + * enum fe_delivery_system - Type of the delivery system + * + * @SYS_UNDEFINED: + * Undefined standard. Generally, indicates an error + * @SYS_DVBC_ANNEX_A: + * Cable TV: DVB-C following ITU-T J.83 Annex A spec + * @SYS_DVBC_ANNEX_B: + * Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM) + * @SYS_DVBC_ANNEX_C: + * Cable TV: DVB-C following ITU-T J.83 Annex C spec + * @SYS_ISDBC: + * Cable TV: ISDB-C (no drivers yet) + * @SYS_DVBT: + * Terrestrial TV: DVB-T + * @SYS_DVBT2: + * Terrestrial TV: DVB-T2 + * @SYS_ISDBT: + * Terrestrial TV: ISDB-T + * @SYS_ATSC: + * Terrestrial TV: ATSC + * @SYS_ATSCMH: + * Terrestrial TV (mobile): ATSC-M/H + * @SYS_DTMB: + * Terrestrial TV: DTMB + * @SYS_DVBS: + * Satellite TV: DVB-S + * @SYS_DVBS2: + * Satellite TV: DVB-S2 + * @SYS_TURBO: + * Satellite TV: DVB-S Turbo + * @SYS_ISDBS: + * Satellite TV: ISDB-S + * @SYS_DAB: + * Digital audio: DAB (not fully supported) + * @SYS_DSS: + * Satellite TV: DSS (not fully supported) + * @SYS_CMMB: + * Terrestrial TV (mobile): CMMB (not fully supported) + * @SYS_DVBH: + * Terrestrial TV (mobile): DVB-H (standard deprecated) + */ enum fe_delivery_system { SYS_UNDEFINED, SYS_DVBC_ANNEX_A, @@ -344,35 +643,85 @@ enum fe_delivery_system { SYS_DVBC_ANNEX_C, }; -/* backward compatibility */ +/* backward compatibility definitions for delivery systems */ #define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A -#define SYS_DMBTH SYS_DTMB /* DMB-TH is legacy name, use DTMB instead */ +#define SYS_DMBTH SYS_DTMB /* DMB-TH is legacy name, use DTMB */ -/* ATSC-MH */ +/* ATSC-MH specific parameters */ +/** + * enum atscmh_sccc_block_mode - Type of Series Concatenated Convolutional + * Code Block Mode. + * + * @ATSCMH_SCCC_BLK_SEP: + * Separate SCCC: the SCCC outer code mode shall be set independently + * for each Group Region (A, B, C, D) + * @ATSCMH_SCCC_BLK_COMB: + * Combined SCCC: all four Regions shall have the same SCCC outer + * code mode. + * @ATSCMH_SCCC_BLK_RES: + * Reserved. Shouldn't be used. + */ enum atscmh_sccc_block_mode { ATSCMH_SCCC_BLK_SEP = 0, ATSCMH_SCCC_BLK_COMB = 1, ATSCMH_SCCC_BLK_RES = 2, }; +/** + * enum atscmh_sccc_code_mode - Type of Series Concatenated Convolutional + * Code Rate. + * + * @ATSCMH_SCCC_CODE_HLF: + * The outer code rate of a SCCC Block is 1/2 rate. + * @ATSCMH_SCCC_CODE_QTR: + * The outer code rate of a SCCC Block is 1/4 rate. + * @ATSCMH_SCCC_CODE_RES: + * Reserved. Should not be used. + */ enum atscmh_sccc_code_mode { ATSCMH_SCCC_CODE_HLF = 0, ATSCMH_SCCC_CODE_QTR = 1, ATSCMH_SCCC_CODE_RES = 2, }; +/** + * enum atscmh_rs_frame_ensemble - Reed Solomon(RS) frame ensemble. + * + * @ATSCMH_RSFRAME_ENS_PRI: Primary Ensemble. + * @ATSCMH_RSFRAME_ENS_SEC: Secondary Ensemble. + */ enum atscmh_rs_frame_ensemble { ATSCMH_RSFRAME_ENS_PRI = 0, ATSCMH_RSFRAME_ENS_SEC = 1, }; +/** + * enum atscmh_rs_frame_mode - Reed Solomon (RS) frame mode. + * + * @ATSCMH_RSFRAME_PRI_ONLY: + * Single Frame: There is only a primary RS Frame for all Group + * Regions. + * @ATSCMH_RSFRAME_PRI_SEC: + * Dual Frame: There are two separate RS Frames: Primary RS Frame for + * Group Region A and B and Secondary RS Frame for Group Region C and + * D. + * @ATSCMH_RSFRAME_RES: + * Reserved. Shouldn't be used. + */ enum atscmh_rs_frame_mode { ATSCMH_RSFRAME_PRI_ONLY = 0, ATSCMH_RSFRAME_PRI_SEC = 1, ATSCMH_RSFRAME_RES = 2, }; +/** + * enum atscmh_rs_code_mode + * @ATSCMH_RSCODE_211_187: Reed Solomon code (211,187). + * @ATSCMH_RSCODE_223_187: Reed Solomon code (223,187). + * @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187). + * @ATSCMH_RSCODE_RES: Reserved. Shouldn't be used. + */ enum atscmh_rs_code_mode { ATSCMH_RSCODE_211_187 = 0, ATSCMH_RSCODE_223_187 = 1, @@ -383,28 +732,18 @@ enum atscmh_rs_code_mode { #define NO_STREAM_ID_FILTER (~0U) #define LNA_AUTO (~0U) -struct dtv_cmds_h { - char *name; /* A display name for debugging purposes */ - - __u32 cmd; /* A unique ID */ - - /* Flags */ - __u32 set:1; /* Either a set or get property */ - __u32 buffer:1; /* Does this property use the buffer? */ - __u32 reserved:30; /* Align */ -}; - /** - * Scale types for the quality parameters. + * enum fecap_scale_params - scale types for the quality parameters. + * * @FE_SCALE_NOT_AVAILABLE: That QoS measure is not available. That * could indicate a temporary or a permanent * condition. * @FE_SCALE_DECIBEL: The scale is measured in 0.001 dB steps, typically - * used on signal measures. + * used on signal measures. * @FE_SCALE_RELATIVE: The scale is a relative percentual measure, - * ranging from 0 (0%) to 0xffff (100%). + * ranging from 0 (0%) to 0xffff (100%). * @FE_SCALE_COUNTER: The scale counts the occurrence of an event, like - * bit error, block error, lapsed time. + * bit error, block error, lapsed time. */ enum fecap_scale_params { FE_SCALE_NOT_AVAILABLE = 0, @@ -416,24 +755,38 @@ enum fecap_scale_params { /** * struct dtv_stats - Used for reading a DTV status property * - * @value: value of the measure. Should range from 0 to 0xffff; * @scale: Filled with enum fecap_scale_params - the scale * in usage for that parameter * + * The ``{unnamed_union}`` may have either one of the values below: + * + * %svalue + * integer value of the measure, for %FE_SCALE_DECIBEL, + * used for dB measures. The unit is 0.001 dB. + * + * %uvalue + * unsigned integer value of the measure, used when @scale is + * either %FE_SCALE_RELATIVE or %FE_SCALE_COUNTER. + * * For most delivery systems, this will return a single value for each * parameter. + * * It should be noticed, however, that new OFDM delivery systems like * ISDB can use different modulation types for each group of carriers. * On such standards, up to 8 groups of statistics can be provided, one * for each carrier group (called "layer" on ISDB). + * * In order to be consistent with other delivery systems, the first * value refers to the entire set of carriers ("global"). - * dtv_status:scale should use the value FE_SCALE_NOT_AVAILABLE when + * + * @scale should use the value %FE_SCALE_NOT_AVAILABLE when * the value for the entire group of carriers or from one specific layer * is not provided by the hardware. - * st.len should be filled with the latest filled status + 1. * - * In other words, for ISDB, those values should be filled like: + * @len should be filled with the latest filled status + 1. + * + * In other words, for ISDB, those values should be filled like:: + * * u.st.stat.svalue[0] = global statistics; * u.st.stat.scale[0] = FE_SCALE_DECIBEL; * u.st.stat.value[1] = layer A statistics; @@ -455,11 +808,39 @@ struct dtv_stats { #define MAX_DTV_STATS 4 +/** + * struct dtv_fe_stats - store Digital TV frontend statistics + * + * @len: length of the statistics - if zero, stats is disabled. + * @stat: array with digital TV statistics. + * + * On most standards, @len can either be 0 or 1. However, for ISDB, each + * layer is modulated in separate. So, each layer may have its own set + * of statistics. If so, stat[0] carries on a global value for the property. + * Indexes 1 to 3 means layer A to B. + */ struct dtv_fe_stats { __u8 len; struct dtv_stats stat[MAX_DTV_STATS]; } __attribute__ ((packed)); +/** + * struct dtv_property - store one of frontend command and its value + * + * @cmd: Digital TV command. + * @reserved: Not used. + * @u: Union with the values for the command. + * @result: Result of the command set (currently unused). + * + * The @u union may have either one of the values below: + * + * %data + * an unsigned 32-bits number. + * %st + * a &struct dtv_fe_stats array of statistics. + * %buffer + * a buffer of up to 32 characters (currently unused). + */ struct dtv_property { __u32 cmd; __u32 reserved[3]; @@ -479,17 +860,70 @@ struct dtv_property { /* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ #define DTV_IOCTL_MAX_MSGS 64 +/** + * struct dtv_properties - a set of command/value pairs. + * + * @num: amount of commands stored at the struct. + * @props: a pointer to &struct dtv_property. + */ struct dtv_properties { __u32 num; struct dtv_property *props; }; -#if defined(__DVB_CORE__) || !defined (__KERNEL__) +/* + * When set, this flag will disable any zigzagging or other "normal" tuning + * behavior. Additionally, there will be no automatic monitoring of the lock + * status, and hence no frontend events will be generated. If a frontend device + * is closed, this flag will be automatically turned off when the device is + * reopened read-write. + */ +#define FE_TUNE_MODE_ONESHOT 0x01 + +/* Digital TV Frontend API calls */ + +#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info) + +#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62) +#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd) +#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply) +#define FE_DISEQC_SEND_BURST _IO('o', 65) /* fe_sec_mini_cmd_t */ + +#define FE_SET_TONE _IO('o', 66) /* fe_sec_tone_mode_t */ +#define FE_SET_VOLTAGE _IO('o', 67) /* fe_sec_voltage_t */ +#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */ + +#define FE_READ_STATUS _IOR('o', 69, fe_status_t) +#define FE_READ_BER _IOR('o', 70, __u32) +#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16) +#define FE_READ_SNR _IOR('o', 72, __u16) +#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32) + +#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */ +#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) + +#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ + +#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) +#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) + +#if defined(__DVB_CORE__) || !defined(__KERNEL__) + +/* + * DEPRECATED: Everything below is deprecated in favor of DVBv5 API + * + * The DVBv3 only ioctls, structs and enums should not be used on + * newer programs, as it doesn't support the second generation of + * digital TV standards, nor supports newer delivery systems. + * They also don't support modern frontends with usually support multiple + * delivery systems. + * + * Drivers shouldn't use them. + * + * New applications should use DVBv5 delivery system instead + */ /* - * DEPRECATED: The DVBv3 ioctls, structs and enums should not be used on - * newer programs, as it doesn't support the second generation of digital - * TV standards, nor supports newer delivery systems. */ enum fe_bandwidth { @@ -502,7 +936,7 @@ enum fe_bandwidth { BANDWIDTH_1_712_MHZ, }; -/* This is needed for legacy userspace support */ +/* This is kept for legacy userspace support */ typedef enum fe_sec_voltage fe_sec_voltage_t; typedef enum fe_caps fe_caps_t; typedef enum fe_type fe_type_t; @@ -520,6 +954,8 @@ typedef enum fe_pilot fe_pilot_t; typedef enum fe_rolloff fe_rolloff_t; typedef enum fe_delivery_system fe_delivery_system_t; +/* DVBv3 structs */ + struct dvb_qpsk_parameters { __u32 symbol_rate; /* symbol rate in Symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ @@ -546,8 +982,8 @@ struct dvb_ofdm_parameters { }; struct dvb_frontend_parameters { - __u32 frequency; /* (absolute) frequency in Hz for DVB-C/DVB-T/ATSC */ - /* intermediate frequency in kHz for DVB-S */ + __u32 frequency; /* (absolute) frequency in Hz for DVB-C/DVB-T/ATSC */ + /* intermediate frequency in kHz for DVB-S */ fe_spectral_inversion_t inversion; union { struct dvb_qpsk_parameters qpsk; /* DVB-S */ @@ -561,42 +997,12 @@ struct dvb_frontend_event { fe_status_t status; struct dvb_frontend_parameters parameters; }; -#endif -#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) -#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) - -/** - * When set, this flag will disable any zigzagging or other "normal" tuning - * behaviour. Additionally, there will be no automatic monitoring of the lock - * status, and hence no frontend events will be generated. If a frontend device - * is closed, this flag will be automatically turned off when the device is - * reopened read-write. - */ -#define FE_TUNE_MODE_ONESHOT 0x01 - -#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info) - -#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62) -#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd) -#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply) -#define FE_DISEQC_SEND_BURST _IO('o', 65) /* fe_sec_mini_cmd_t */ - -#define FE_SET_TONE _IO('o', 66) /* fe_sec_tone_mode_t */ -#define FE_SET_VOLTAGE _IO('o', 67) /* fe_sec_voltage_t */ -#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */ - -#define FE_READ_STATUS _IOR('o', 69, fe_status_t) -#define FE_READ_BER _IOR('o', 70, __u32) -#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16) -#define FE_READ_SNR _IOR('o', 72, __u16) -#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32) +/* DVBv3 API calls */ #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) -#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */ -#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) -#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ +#endif #endif /*_DVBFRONTEND_H_*/ diff --git a/include/uapi/linux/dvb/net.h b/include/uapi/linux/dvb/net.h index f451e7eb0b0bd9c393dca78cea873c4f91e1dede..89d805f9a5a6af24ffc2b29800891f631c3e2dec 100644 --- a/include/uapi/linux/dvb/net.h +++ b/include/uapi/linux/dvb/net.h @@ -26,6 +26,21 @@ #include +/** + * struct dvb_net_if - describes a DVB network interface + * + * @pid: Packet ID (PID) of the MPEG-TS that contains data + * @if_num: number of the Digital TV interface. + * @feedtype: Encapsulation type of the feed. + * + * A MPEG-TS stream may contain packet IDs with IP packages on it. + * This struct describes it, and the type of encoding. + * + * @feedtype can be: + * + * - %DVB_NET_FEEDTYPE_MPE for MPE encoding + * - %DVB_NET_FEEDTYPE_ULE for ULE encoding. + */ struct dvb_net_if { __u16 pid; __u16 if_num; diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h index 07bdce1f444aa892c1c36abe10c87ab9d6003daa..78fdf52d6b2fcbfad3a8e928807b9b8f86629851 100644 --- a/include/uapi/linux/errqueue.h +++ b/include/uapi/linux/errqueue.h @@ -18,10 +18,13 @@ struct sock_extended_err { #define SO_EE_ORIGIN_ICMP 2 #define SO_EE_ORIGIN_ICMP6 3 #define SO_EE_ORIGIN_TXSTATUS 4 +#define SO_EE_ORIGIN_ZEROCOPY 5 #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS #define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) +#define SO_EE_CODE_ZEROCOPY_COPIED 1 + /** * struct scm_timestamping - timestamps exposed through cmsg * diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 7d4a594d5d58147e3cf4b56eb992268a619badf3..5bd1b1de4ea0670caf18ffb28e36ba9e35592605 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1238,6 +1238,47 @@ struct ethtool_per_queue_op { char data[]; }; +/** + * struct ethtool_fecparam - Ethernet forward error correction(fec) parameters + * @cmd: Command number = %ETHTOOL_GFECPARAM or %ETHTOOL_SFECPARAM + * @active_fec: FEC mode which is active on porte + * @fec: Bitmask of supported/configured FEC modes + * @rsvd: Reserved for future extensions. i.e FEC bypass feature. + * + * Drivers should reject a non-zero setting of @autoneg when + * autoneogotiation is disabled (or not supported) for the link. + * + */ +struct ethtool_fecparam { + __u32 cmd; + /* bitmask of FEC modes */ + __u32 active_fec; + __u32 fec; + __u32 reserved; +}; + +/** + * enum ethtool_fec_config_bits - flags definition of ethtool_fec_configuration + * @ETHTOOL_FEC_NONE: FEC mode configuration is not supported + * @ETHTOOL_FEC_AUTO: Default/Best FEC mode provided by driver + * @ETHTOOL_FEC_OFF: No FEC Mode + * @ETHTOOL_FEC_RS: Reed-Solomon Forward Error Detection mode + * @ETHTOOL_FEC_BASER: Base-R/Reed-Solomon Forward Error Detection mode + */ +enum ethtool_fec_config_bits { + ETHTOOL_FEC_NONE_BIT, + ETHTOOL_FEC_AUTO_BIT, + ETHTOOL_FEC_OFF_BIT, + ETHTOOL_FEC_RS_BIT, + ETHTOOL_FEC_BASER_BIT, +}; + +#define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT) +#define ETHTOOL_FEC_AUTO (1 << ETHTOOL_FEC_AUTO_BIT) +#define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT) +#define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT) +#define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT) + /* CMDs currently supported */ #define ETHTOOL_GSET 0x00000001 /* DEPRECATED, Get settings. * Please use ETHTOOL_GLINKSETTINGS @@ -1330,6 +1371,8 @@ struct ethtool_per_queue_op { #define ETHTOOL_SLINKSETTINGS 0x0000004d /* Set ethtool_link_settings */ #define ETHTOOL_PHY_GTUNABLE 0x0000004e /* Get PHY tunable configuration */ #define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */ +#define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */ +#define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET @@ -1387,6 +1430,9 @@ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47, ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48, + ETHTOOL_LINK_MODE_FEC_NONE_BIT = 49, + ETHTOOL_LINK_MODE_FEC_RS_BIT = 50, + ETHTOOL_LINK_MODE_FEC_BASER_BIT = 51, /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_* @@ -1395,7 +1441,7 @@ enum ethtool_link_mode_bit_indices { */ __ETHTOOL_LINK_MODE_LAST - = ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + = ETHTOOL_LINK_MODE_FEC_BASER_BIT, }; #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \ @@ -1707,6 +1753,8 @@ enum ethtool_reset_flags { * %ethtool_link_mode_bit_indices for the link modes, and other * link features that the link partner advertised through * autonegotiation; 0 if unknown or not applicable. Read-only. + * @transceiver: Used to distinguish different possible PHY types, + * reported consistently by PHYLIB. Read-only. * * If autonegotiation is disabled, the speed and @duplex represent the * fixed link mode and are writable if the driver supports multiple @@ -1758,7 +1806,9 @@ struct ethtool_link_settings { __u8 eth_tp_mdix; __u8 eth_tp_mdix_ctrl; __s8 link_mode_masks_nwords; - __u32 reserved[8]; + __u8 transceiver; + __u8 reserved1[3]; + __u32 reserved[7]; __u32 link_mode_masks[0]; /* layout of link_mode_masks fields: * __u32 map_supported[link_mode_masks_nwords]; diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index b7495d05e8de8db54f97fef83fbca0402329f11a..56235dddea7d8674033f71fb85f3468234859d1a 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -358,13 +358,25 @@ struct fscrypt_key { #define SYNC_FILE_RANGE_WRITE 2 #define SYNC_FILE_RANGE_WAIT_AFTER 4 -/* flags for preadv2/pwritev2: */ -#define RWF_HIPRI 0x00000001 /* high priority request, poll if possible */ -#define RWF_DSYNC 0x00000002 /* per-IO O_DSYNC */ -#define RWF_SYNC 0x00000004 /* per-IO O_SYNC */ -#define RWF_NOWAIT 0x00000008 /* per-IO, return -EAGAIN if operation would block */ - -#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC |\ - RWF_NOWAIT) +/* + * Flags for preadv2/pwritev2: + */ + +typedef int __bitwise __kernel_rwf_t; + +/* high priority request, poll if possible */ +#define RWF_HIPRI ((__force __kernel_rwf_t)0x00000001) + +/* per-IO O_DSYNC */ +#define RWF_DSYNC ((__force __kernel_rwf_t)0x00000002) + +/* per-IO O_SYNC */ +#define RWF_SYNC ((__force __kernel_rwf_t)0x00000004) + +/* per-IO, return -EAGAIN if operation would block */ +#define RWF_NOWAIT ((__force __kernel_rwf_t)0x00000008) + +/* mask of flags supported by the kernel */ +#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT) #endif /* _UAPI_LINUX_FS_H */ diff --git a/include/uapi/linux/fsmap.h b/include/uapi/linux/fsmap.h index 7e8e5f0bd6d263c7a9e583a255810f5b85f96441..e5213c3e38b2104b28e3f6ea621dbdf757e8efa8 100644 --- a/include/uapi/linux/fsmap.h +++ b/include/uapi/linux/fsmap.h @@ -96,7 +96,7 @@ fsmap_advance( #define FMR_OF_EXTENT_MAP 0x4 /* segment = extent map */ #define FMR_OF_SHARED 0x8 /* segment = shared with another file */ #define FMR_OF_SPECIAL_OWNER 0x10 /* owner is a special value */ -#define FMR_OF_LAST 0x20 /* segment is the last in the FS */ +#define FMR_OF_LAST 0x20 /* segment is the last in the dataset */ /* Each FS gets to define its own special owner codes. */ #define FMR_OWNER(type, code) (((__u64)type << 32) | \ diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h index cf73510b923864fd1b0c20bd3de47ba874a9b855..a2a63562060050ba4041a86905407f19e3ebd3a8 100644 --- a/include/uapi/linux/if_arp.h +++ b/include/uapi/linux/if_arp.h @@ -59,6 +59,7 @@ #define ARPHRD_LAPB 516 /* LAPB */ #define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */ #define ARPHRD_RAWHDLC 518 /* Raw HDLC */ +#define ARPHRD_RAWIP 519 /* Raw IP */ #define ARPHRD_TUNNEL 768 /* IPIP tunnel */ #define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */ diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 5bc9bfd816b7b72185b9a3ee149563a5ebf74a80..9037065e23d0d08f191ac378fb60cceb819afaed 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -66,6 +66,7 @@ #define ETH_P_ATALK 0x809B /* Appletalk DDP */ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define ETH_P_ERSPAN 0x88BE /* ERSPAN type II */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ #define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */ @@ -98,11 +99,13 @@ #define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ #define ETH_P_80221 0x8917 /* IEEE 802.21 Media Independent Handover Protocol */ #define ETH_P_HSR 0x892F /* IEC 62439-3 HSRv1 */ +#define ETH_P_NSH 0x894F /* Network Service Header */ #define ETH_P_LOOPBACK 0x9000 /* Ethernet loopback packet, per IEEE 802.3 */ #define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ +#define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */ #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */ #define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value @@ -137,6 +140,9 @@ #define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ #define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */ #define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */ +#define ETH_P_MAP 0x00F9 /* Qualcomm multiplexing and + * aggregation protocol + */ /* * This is an Ethernet frame header. diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 6792d1967d3145f3f2092d3b1bf052bf13ce04fb..2e520883c054ce474272471655cea5d119de0be0 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h @@ -134,6 +134,7 @@ enum { IFLA_GRE_COLLECT_METADATA, IFLA_GRE_IGNORE_DF, IFLA_GRE_FWMARK, + IFLA_GRE_ERSPAN_INDEX, __IFLA_GRE_MAX, }; diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h index bbe201047df6c8cd5e56d8e783d3934163c10d0b..f52ff62bfabe766c262b1ab2f3943f590f69946d 100644 --- a/include/uapi/linux/inet_diag.h +++ b/include/uapi/linux/inet_diag.h @@ -142,6 +142,8 @@ enum { INET_DIAG_PAD, INET_DIAG_MARK, INET_DIAG_BBRINFO, + INET_DIAG_CLASS_ID, + INET_DIAG_MD5SIG, __INET_DIAG_MAX, }; diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index d6833426fdef15479a0c2f3fe6145a6d5b8b2e15..26283fefdf5fd5f86719fb954c02ae3b2492cd30 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -23,15 +23,15 @@ #ifndef KFD_IOCTL_H_INCLUDED #define KFD_IOCTL_H_INCLUDED -#include +#include #include #define KFD_IOCTL_MAJOR_VERSION 1 #define KFD_IOCTL_MINOR_VERSION 1 struct kfd_ioctl_get_version_args { - uint32_t major_version; /* from KFD */ - uint32_t minor_version; /* from KFD */ + __u32 major_version; /* from KFD */ + __u32 minor_version; /* from KFD */ }; /* For kfd_ioctl_create_queue_args.queue_type. */ @@ -43,36 +43,36 @@ struct kfd_ioctl_get_version_args { #define KFD_MAX_QUEUE_PRIORITY 15 struct kfd_ioctl_create_queue_args { - uint64_t ring_base_address; /* to KFD */ - uint64_t write_pointer_address; /* from KFD */ - uint64_t read_pointer_address; /* from KFD */ - uint64_t doorbell_offset; /* from KFD */ - - uint32_t ring_size; /* to KFD */ - uint32_t gpu_id; /* to KFD */ - uint32_t queue_type; /* to KFD */ - uint32_t queue_percentage; /* to KFD */ - uint32_t queue_priority; /* to KFD */ - uint32_t queue_id; /* from KFD */ - - uint64_t eop_buffer_address; /* to KFD */ - uint64_t eop_buffer_size; /* to KFD */ - uint64_t ctx_save_restore_address; /* to KFD */ - uint64_t ctx_save_restore_size; /* to KFD */ + __u64 ring_base_address; /* to KFD */ + __u64 write_pointer_address; /* from KFD */ + __u64 read_pointer_address; /* from KFD */ + __u64 doorbell_offset; /* from KFD */ + + __u32 ring_size; /* to KFD */ + __u32 gpu_id; /* to KFD */ + __u32 queue_type; /* to KFD */ + __u32 queue_percentage; /* to KFD */ + __u32 queue_priority; /* to KFD */ + __u32 queue_id; /* from KFD */ + + __u64 eop_buffer_address; /* to KFD */ + __u64 eop_buffer_size; /* to KFD */ + __u64 ctx_save_restore_address; /* to KFD */ + __u64 ctx_save_restore_size; /* to KFD */ }; struct kfd_ioctl_destroy_queue_args { - uint32_t queue_id; /* to KFD */ - uint32_t pad; + __u32 queue_id; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_update_queue_args { - uint64_t ring_base_address; /* to KFD */ + __u64 ring_base_address; /* to KFD */ - uint32_t queue_id; /* to KFD */ - uint32_t ring_size; /* to KFD */ - uint32_t queue_percentage; /* to KFD */ - uint32_t queue_priority; /* to KFD */ + __u32 queue_id; /* to KFD */ + __u32 ring_size; /* to KFD */ + __u32 queue_percentage; /* to KFD */ + __u32 queue_priority; /* to KFD */ }; /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */ @@ -80,13 +80,13 @@ struct kfd_ioctl_update_queue_args { #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1 struct kfd_ioctl_set_memory_policy_args { - uint64_t alternate_aperture_base; /* to KFD */ - uint64_t alternate_aperture_size; /* to KFD */ + __u64 alternate_aperture_base; /* to KFD */ + __u64 alternate_aperture_size; /* to KFD */ - uint32_t gpu_id; /* to KFD */ - uint32_t default_policy; /* to KFD */ - uint32_t alternate_policy; /* to KFD */ - uint32_t pad; + __u32 gpu_id; /* to KFD */ + __u32 default_policy; /* to KFD */ + __u32 alternate_policy; /* to KFD */ + __u32 pad; }; /* @@ -97,26 +97,26 @@ struct kfd_ioctl_set_memory_policy_args { */ struct kfd_ioctl_get_clock_counters_args { - uint64_t gpu_clock_counter; /* from KFD */ - uint64_t cpu_clock_counter; /* from KFD */ - uint64_t system_clock_counter; /* from KFD */ - uint64_t system_clock_freq; /* from KFD */ + __u64 gpu_clock_counter; /* from KFD */ + __u64 cpu_clock_counter; /* from KFD */ + __u64 system_clock_counter; /* from KFD */ + __u64 system_clock_freq; /* from KFD */ - uint32_t gpu_id; /* to KFD */ - uint32_t pad; + __u32 gpu_id; /* to KFD */ + __u32 pad; }; #define NUM_OF_SUPPORTED_GPUS 7 struct kfd_process_device_apertures { - uint64_t lds_base; /* from KFD */ - uint64_t lds_limit; /* from KFD */ - uint64_t scratch_base; /* from KFD */ - uint64_t scratch_limit; /* from KFD */ - uint64_t gpuvm_base; /* from KFD */ - uint64_t gpuvm_limit; /* from KFD */ - uint32_t gpu_id; /* from KFD */ - uint32_t pad; + __u64 lds_base; /* from KFD */ + __u64 lds_limit; /* from KFD */ + __u64 scratch_base; /* from KFD */ + __u64 scratch_limit; /* from KFD */ + __u64 gpuvm_base; /* from KFD */ + __u64 gpuvm_limit; /* from KFD */ + __u32 gpu_id; /* from KFD */ + __u32 pad; }; struct kfd_ioctl_get_process_apertures_args { @@ -124,8 +124,8 @@ struct kfd_ioctl_get_process_apertures_args { process_apertures[NUM_OF_SUPPORTED_GPUS];/* from KFD */ /* from KFD, should be in the range [1 - NUM_OF_SUPPORTED_GPUS] */ - uint32_t num_of_nodes; - uint32_t pad; + __u32 num_of_nodes; + __u32 pad; }; #define MAX_ALLOWED_NUM_POINTS 100 @@ -133,25 +133,25 @@ struct kfd_ioctl_get_process_apertures_args { #define MAX_ALLOWED_WAC_BUFF_SIZE 128 struct kfd_ioctl_dbg_register_args { - uint32_t gpu_id; /* to KFD */ - uint32_t pad; + __u32 gpu_id; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_dbg_unregister_args { - uint32_t gpu_id; /* to KFD */ - uint32_t pad; + __u32 gpu_id; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_dbg_address_watch_args { - uint64_t content_ptr; /* a pointer to the actual content */ - uint32_t gpu_id; /* to KFD */ - uint32_t buf_size_in_bytes; /*including gpu_id and buf_size */ + __u64 content_ptr; /* a pointer to the actual content */ + __u32 gpu_id; /* to KFD */ + __u32 buf_size_in_bytes; /*including gpu_id and buf_size */ }; struct kfd_ioctl_dbg_wave_control_args { - uint64_t content_ptr; /* a pointer to the actual content */ - uint32_t gpu_id; /* to KFD */ - uint32_t buf_size_in_bytes; /*including gpu_id and buf_size */ + __u64 content_ptr; /* a pointer to the actual content */ + __u32 gpu_id; /* to KFD */ + __u32 buf_size_in_bytes; /*including gpu_id and buf_size */ }; /* Matching HSA_EVENTTYPE */ @@ -172,44 +172,44 @@ struct kfd_ioctl_dbg_wave_control_args { #define KFD_SIGNAL_EVENT_LIMIT 256 struct kfd_ioctl_create_event_args { - uint64_t event_page_offset; /* from KFD */ - uint32_t event_trigger_data; /* from KFD - signal events only */ - uint32_t event_type; /* to KFD */ - uint32_t auto_reset; /* to KFD */ - uint32_t node_id; /* to KFD - only valid for certain + __u64 event_page_offset; /* from KFD */ + __u32 event_trigger_data; /* from KFD - signal events only */ + __u32 event_type; /* to KFD */ + __u32 auto_reset; /* to KFD */ + __u32 node_id; /* to KFD - only valid for certain event types */ - uint32_t event_id; /* from KFD */ - uint32_t event_slot_index; /* from KFD */ + __u32 event_id; /* from KFD */ + __u32 event_slot_index; /* from KFD */ }; struct kfd_ioctl_destroy_event_args { - uint32_t event_id; /* to KFD */ - uint32_t pad; + __u32 event_id; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_set_event_args { - uint32_t event_id; /* to KFD */ - uint32_t pad; + __u32 event_id; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_reset_event_args { - uint32_t event_id; /* to KFD */ - uint32_t pad; + __u32 event_id; /* to KFD */ + __u32 pad; }; struct kfd_memory_exception_failure { - uint32_t NotPresent; /* Page not present or supervisor privilege */ - uint32_t ReadOnly; /* Write access to a read-only page */ - uint32_t NoExecute; /* Execute access to a page marked NX */ - uint32_t pad; + __u32 NotPresent; /* Page not present or supervisor privilege */ + __u32 ReadOnly; /* Write access to a read-only page */ + __u32 NoExecute; /* Execute access to a page marked NX */ + __u32 pad; }; /* memory exception data*/ struct kfd_hsa_memory_exception_data { struct kfd_memory_exception_failure failure; - uint64_t va; - uint32_t gpu_id; - uint32_t pad; + __u64 va; + __u32 gpu_id; + __u32 pad; }; /* Event data*/ @@ -217,19 +217,48 @@ struct kfd_event_data { union { struct kfd_hsa_memory_exception_data memory_exception_data; }; /* From KFD */ - uint64_t kfd_event_data_ext; /* pointer to an extension structure + __u64 kfd_event_data_ext; /* pointer to an extension structure for future exception types */ - uint32_t event_id; /* to KFD */ - uint32_t pad; + __u32 event_id; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_wait_events_args { - uint64_t events_ptr; /* pointed to struct + __u64 events_ptr; /* pointed to struct kfd_event_data array, to KFD */ - uint32_t num_events; /* to KFD */ - uint32_t wait_for_all; /* to KFD */ - uint32_t timeout; /* to KFD */ - uint32_t wait_result; /* from KFD */ + __u32 num_events; /* to KFD */ + __u32 wait_for_all; /* to KFD */ + __u32 timeout; /* to KFD */ + __u32 wait_result; /* from KFD */ +}; + +struct kfd_ioctl_set_scratch_backing_va_args { + uint64_t va_addr; /* to KFD */ + uint32_t gpu_id; /* to KFD */ + uint32_t pad; +}; + +struct kfd_ioctl_get_tile_config_args { + /* to KFD: pointer to tile array */ + uint64_t tile_config_ptr; + /* to KFD: pointer to macro tile array */ + uint64_t macro_tile_config_ptr; + /* to KFD: array size allocated by user mode + * from KFD: array size filled by kernel + */ + uint32_t num_tile_configs; + /* to KFD: array size allocated by user mode + * from KFD: array size filled by kernel + */ + uint32_t num_macro_tile_configs; + + uint32_t gpu_id; /* to KFD */ + uint32_t gb_addr_config; /* from KFD */ + uint32_t num_banks; /* from KFD */ + uint32_t num_ranks; /* from KFD */ + /* struct size can be extended later if needed + * without breaking ABI compatibility + */ }; #define AMDKFD_IOCTL_BASE 'K' @@ -286,7 +315,13 @@ struct kfd_ioctl_wait_events_args { #define AMDKFD_IOC_DBG_WAVE_CONTROL \ AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args) +#define AMDKFD_IOC_SET_SCRATCH_BACKING_VA \ + AMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args) + +#define AMDKFD_IOC_GET_TILE_CONFIG \ + AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args) + #define AMDKFD_COMMAND_START 0x01 -#define AMDKFD_COMMAND_END 0x11 +#define AMDKFD_COMMAND_END 0x13 #endif diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 6cd63c18708ae1d23dbc280ed49aed55f817a2f5..83888758741184f969f3b8fd1738e38bdc24da78 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -711,7 +711,8 @@ struct kvm_ppc_one_seg_page_size { struct kvm_ppc_smmu_info { __u64 flags; __u32 slb_size; - __u32 pad; + __u16 data_keys; /* # storage keys supported for data */ + __u16 instr_keys; /* # storage keys supported for instructions */ struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; }; diff --git a/include/uapi/linux/loop.h b/include/uapi/linux/loop.h index a3960f98679c13567c3db4ecb7919cd14a70cfb0..23158dbe242483c7d4c35570794dadc2c332bcc0 100644 --- a/include/uapi/linux/loop.h +++ b/include/uapi/linux/loop.h @@ -22,7 +22,6 @@ enum { LO_FLAGS_AUTOCLEAR = 4, LO_FLAGS_PARTSCAN = 8, LO_FLAGS_DIRECT_IO = 16, - LO_FLAGS_BLOCKSIZE = 32, }; #include /* for __kernel_old_dev_t */ @@ -60,8 +59,6 @@ struct loop_info64 { __u64 lo_init[2]; }; -#define LO_INFO_BLOCKSIZE(l) (l)->lo_init[0] - /* * Loop filter types */ @@ -91,6 +88,7 @@ struct loop_info64 { #define LOOP_CHANGE_FD 0x4C06 #define LOOP_SET_CAPACITY 0x4C07 #define LOOP_SET_DIRECT_IO 0x4C08 +#define LOOP_SET_BLOCK_SIZE 0x4C09 /* /dev/loop-control interface */ #define LOOP_CTL_ADD 0x4C80 diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h index 92724cba1eba07c9035febba046d1687cd0ce96a..7fdd19ca75111809ac4e9078d092d9e194785109 100644 --- a/include/uapi/linux/lwtunnel.h +++ b/include/uapi/linux/lwtunnel.h @@ -11,6 +11,7 @@ enum lwtunnel_encap_types { LWTUNNEL_ENCAP_IP6, LWTUNNEL_ENCAP_SEG6, LWTUNNEL_ENCAP_BPF, + LWTUNNEL_ENCAP_SEG6_LOCAL, __LWTUNNEL_ENCAP_MAX, }; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index fac96c64fe513b3e17dff640cfa516683e91e553..4865f1e713398b63f41fca7a84fae1637fc44385 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -30,8 +30,6 @@ #include #include -#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) - struct media_device_info { char driver[16]; char model[32]; @@ -187,6 +185,9 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER #define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER + +/* Obsolete symbol for media_version, no longer used in the kernel */ +#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) #endif /* Entity flags */ diff --git a/include/uapi/linux/membarrier.h b/include/uapi/linux/membarrier.h index e0b108bd2624de3765538fe61f5c2852ca766593..6d47b3249d8ad84a2fcf2b38585338ccbf05a99f 100644 --- a/include/uapi/linux/membarrier.h +++ b/include/uapi/linux/membarrier.h @@ -40,14 +40,33 @@ * (non-running threads are de facto in such a * state). This covers threads from all processes * running on the system. This command returns 0. + * @MEMBARRIER_CMD_PRIVATE_EXPEDITED: + * Execute a memory barrier on each running + * thread belonging to the same process as the current + * thread. Upon return from system call, the + * caller thread is ensured that all its running + * threads siblings have passed through a state + * where all memory accesses to user-space + * addresses match program order between entry + * to and return from the system call + * (non-running threads are de facto in such a + * state). This only covers threads from the + * same processes as the caller thread. This + * command returns 0. The "expedited" commands + * complete faster than the non-expedited ones, + * they never block, but have the downside of + * causing extra overhead. * * Command to be passed to the membarrier system call. The commands need to * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to * the value 0. */ enum membarrier_cmd { - MEMBARRIER_CMD_QUERY = 0, - MEMBARRIER_CMD_SHARED = (1 << 0), + MEMBARRIER_CMD_QUERY = 0, + MEMBARRIER_CMD_SHARED = (1 << 0), + /* reserved for MEMBARRIER_CMD_SHARED_EXPEDITED (1 << 1) */ + /* reserved for MEMBARRIER_CMD_PRIVATE (1 << 2) */ + MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3), }; #endif /* _UAPI_LINUX_MEMBARRIER_H */ diff --git a/include/uapi/linux/memfd.h b/include/uapi/linux/memfd.h index 534e364bda92b05a3067234f8b9d285c06bebbd9..7f3a722dbd722b8c515d3dd9176ce1d646a0caac 100644 --- a/include/uapi/linux/memfd.h +++ b/include/uapi/linux/memfd.h @@ -1,8 +1,32 @@ #ifndef _UAPI_LINUX_MEMFD_H #define _UAPI_LINUX_MEMFD_H +#include + /* flags for memfd_create(2) (unsigned int) */ #define MFD_CLOEXEC 0x0001U #define MFD_ALLOW_SEALING 0x0002U +#define MFD_HUGETLB 0x0004U + +/* + * Huge page size encoding when MFD_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +#define MFD_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT +#define MFD_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK + +#define MFD_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB +#define MFD_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB +#define MFD_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB +#define MFD_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB +#define MFD_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB +#define MFD_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB +#define MFD_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB +#define MFD_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB +#define MFD_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB +#define MFD_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB #endif /* _UAPI_LINUX_MEMFD_H */ diff --git a/include/uapi/linux/mman.h b/include/uapi/linux/mman.h index ade4acd3a90cd498d4409abe263681d590a7de96..a937480d7cd345f4e1b12c2e409f58c0489e8a4e 100644 --- a/include/uapi/linux/mman.h +++ b/include/uapi/linux/mman.h @@ -2,6 +2,7 @@ #define _UAPI_LINUX_MMAN_H #include +#include #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 @@ -10,4 +11,25 @@ #define OVERCOMMIT_ALWAYS 1 #define OVERCOMMIT_NEVER 2 +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT +#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK + +#define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB +#define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB +#define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB +#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB +#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB +#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB +#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB +#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB +#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB +#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB + #endif /* _UAPI_LINUX_MMAN_H */ diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h index 6d3c54264d8e46f662e3a0caa416538042727fb3..3f03567631cb092dc8f51aae740dd2a3472730e9 100644 --- a/include/uapi/linux/ndctl.h +++ b/include/uapi/linux/ndctl.h @@ -145,43 +145,6 @@ struct nd_cmd_clear_error { __u64 cleared; } __packed; -struct nd_cmd_trans_spa { - __u64 spa; - __u32 status; - __u8 flags; - __u8 _reserved[3]; - __u64 trans_length; - __u32 num_nvdimms; - struct nd_nvdimm_device { - __u32 nfit_device_handle; - __u32 _reserved; - __u64 dpa; - } __packed devices[0]; - -} __packed; - -struct nd_cmd_ars_err_inj { - __u64 err_inj_spa_range_base; - __u64 err_inj_spa_range_length; - __u8 err_inj_options; - __u32 status; -} __packed; - -struct nd_cmd_ars_err_inj_clr { - __u64 err_inj_clr_spa_range_base; - __u64 err_inj_clr_spa_range_length; - __u32 status; -} __packed; - -struct nd_cmd_ars_err_inj_stat { - __u32 status; - __u32 inj_err_rec_count; - struct nd_error_stat_query_record { - __u64 err_inj_stat_spa_range_base; - __u64 err_inj_stat_spa_range_length; - } __packed record[0]; -} __packed; - enum { ND_CMD_IMPLEMENTED = 0, diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 683f6f88fcacefa0898e3898cd75f31422fc0f9a..871afa4871bf386ba08cf15f9bdae55f2ec6a68d 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -1,10 +1,11 @@ #ifndef _LINUX_NF_TABLES_H #define _LINUX_NF_TABLES_H -#define NFT_TABLE_MAXNAMELEN 32 -#define NFT_CHAIN_MAXNAMELEN 32 -#define NFT_SET_MAXNAMELEN 32 -#define NFT_OBJ_MAXNAMELEN 32 +#define NFT_NAME_MAXLEN 256 +#define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN +#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN +#define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN +#define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN #define NFT_USERDATA_MAXLEN 256 /** @@ -731,7 +732,8 @@ enum nft_exthdr_op { * @NFTA_EXTHDR_OFFSET: extension header offset (NLA_U32) * @NFTA_EXTHDR_LEN: extension header length (NLA_U32) * @NFTA_EXTHDR_FLAGS: extension header flags (NLA_U32) - * @NFTA_EXTHDR_OP: option match type (NLA_U8) + * @NFTA_EXTHDR_OP: option match type (NLA_U32) + * @NFTA_EXTHDR_SREG: option match type (NLA_U32) */ enum nft_exthdr_attributes { NFTA_EXTHDR_UNSPEC, @@ -741,6 +743,7 @@ enum nft_exthdr_attributes { NFTA_EXTHDR_LEN, NFTA_EXTHDR_FLAGS, NFTA_EXTHDR_OP, + NFTA_EXTHDR_SREG, __NFTA_EXTHDR_MAX }; #define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1) @@ -808,11 +811,13 @@ enum nft_meta_keys { * @NFT_RT_CLASSID: realm value of packet's route (skb->dst->tclassid) * @NFT_RT_NEXTHOP4: routing nexthop for IPv4 * @NFT_RT_NEXTHOP6: routing nexthop for IPv6 + * @NFT_RT_TCPMSS: fetch current path tcp mss */ enum nft_rt_keys { NFT_RT_CLASSID, NFT_RT_NEXTHOP4, NFT_RT_NEXTHOP6, + NFT_RT_TCPMSS, }; /** @@ -1221,6 +1226,8 @@ enum nft_objref_attributes { enum nft_gen_attributes { NFTA_GEN_UNSPEC, NFTA_GEN_ID, + NFTA_GEN_PROC_PID, + NFTA_GEN_PROC_NAME, __NFTA_GEN_MAX }; #define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1) @@ -1275,7 +1282,8 @@ enum nft_ct_helper_attributes { #define NFT_OBJECT_COUNTER 1 #define NFT_OBJECT_QUOTA 2 #define NFT_OBJECT_CT_HELPER 3 -#define __NFT_OBJECT_MAX 4 +#define NFT_OBJECT_LIMIT 4 +#define __NFT_OBJECT_MAX 5 #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) /** diff --git a/include/uapi/linux/netfilter/xt_hashlimit.h b/include/uapi/linux/netfilter/xt_hashlimit.h index 79da349f10605be2aa890e10b563008082cfd9ff..aa98573248b1d0fdfda8794e4dc332c87311d5f8 100644 --- a/include/uapi/linux/netfilter/xt_hashlimit.h +++ b/include/uapi/linux/netfilter/xt_hashlimit.h @@ -19,12 +19,13 @@ struct xt_hashlimit_htable; enum { - XT_HASHLIMIT_HASH_DIP = 1 << 0, - XT_HASHLIMIT_HASH_DPT = 1 << 1, - XT_HASHLIMIT_HASH_SIP = 1 << 2, - XT_HASHLIMIT_HASH_SPT = 1 << 3, - XT_HASHLIMIT_INVERT = 1 << 4, - XT_HASHLIMIT_BYTES = 1 << 5, + XT_HASHLIMIT_HASH_DIP = 1 << 0, + XT_HASHLIMIT_HASH_DPT = 1 << 1, + XT_HASHLIMIT_HASH_SIP = 1 << 2, + XT_HASHLIMIT_HASH_SPT = 1 << 3, + XT_HASHLIMIT_INVERT = 1 << 4, + XT_HASHLIMIT_BYTES = 1 << 5, + XT_HASHLIMIT_RATE_MATCH = 1 << 6, }; struct hashlimit_cfg { @@ -79,6 +80,21 @@ struct hashlimit_cfg2 { __u8 srcmask, dstmask; }; +struct hashlimit_cfg3 { + __u64 avg; /* Average secs between packets * scale */ + __u64 burst; /* Period multiplier for upper limit. */ + __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */ + + /* user specified */ + __u32 size; /* how many buckets */ + __u32 max; /* max number of entries */ + __u32 gc_interval; /* gc interval */ + __u32 expire; /* when do entries expire? */ + + __u32 interval; + __u8 srcmask, dstmask; +}; + struct xt_hashlimit_mtinfo1 { char name[IFNAMSIZ]; struct hashlimit_cfg1 cfg; @@ -95,4 +111,12 @@ struct xt_hashlimit_mtinfo2 { struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); }; +struct xt_hashlimit_mtinfo3 { + char name[NAME_MAX]; + struct hashlimit_cfg3 cfg; + + /* Used internally by the kernel */ + struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); +}; + #endif /* _UAPI_XT_HASHLIMIT_H */ diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h index f86127a46cfc80697df711c847d6a07b5a722347..e8af60a7c56dce757ba5557898e1b5ca2ebaf14c 100644 --- a/include/uapi/linux/netlink.h +++ b/include/uapi/linux/netlink.h @@ -69,6 +69,9 @@ struct nlmsghdr { #define NLM_F_CREATE 0x400 /* Create, if it does not exist */ #define NLM_F_APPEND 0x800 /* Add to end of list */ +/* Modifiers to DELETE request */ +#define NLM_F_NONREC 0x100 /* Do not delete recursively */ + /* Flags for ACK message */ #define NLM_F_CAPPED 0x100 /* request was capped */ #define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */ @@ -226,5 +229,22 @@ struct nlattr { #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) +/* Generic 32 bitflags attribute content sent to the kernel. + * + * The value is a bitmap that defines the values being set + * The selector is a bitmask that defines which value is legit + * + * Examples: + * value = 0x0, and selector = 0x1 + * implies we are selecting bit 1 and we want to set its value to 0. + * + * value = 0x2, and selector = 0x2 + * implies we are selecting bit 2 and we want to set its value to 1. + * + */ +struct nla_bitfield32 { + __u32 value; + __u32 selector; +}; #endif /* _UAPI__LINUX_NETLINK_H */ diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index c22d3ebaca20aedf12aa9cab30b0c8cc50b99bf5..f8d58045926ff11d23cd8e575e550badd78e3237 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -513,6 +513,7 @@ #define PCI_EXP_DEVSTA_URD 0x0008 /* Unsupported Request Detected */ #define PCI_EXP_DEVSTA_AUXPD 0x0010 /* AUX Power Detected */ #define PCI_EXP_DEVSTA_TRPND 0x0020 /* Transactions Pending */ +#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V1 12 /* v1 endpoints without link end here */ #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ @@ -556,7 +557,7 @@ #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ #define PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ #define PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ -#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20 /* v1 endpoints end here */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20 /* v1 endpoints with link end here */ #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ #define PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */ #define PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */ @@ -639,7 +640,7 @@ #define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000 /* Enable OBFF Message type B */ #define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ #define PCI_EXP_DEVSTA2 42 /* Device Status 2 */ -#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints end here */ +#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints without link end here */ #define PCI_EXP_LNKCAP2 44 /* Link Capabilities 2 */ #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5.0GT/s */ @@ -647,6 +648,7 @@ #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100 /* Crosslink supported */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */ #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ #define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */ @@ -733,23 +735,17 @@ #define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ #define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ #define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ -/* Correctable Err Reporting Enable */ -#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 -/* Non-fatal Err Reporting Enable */ -#define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002 -/* Fatal Err Reporting Enable */ -#define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004 +#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 /* Correctable Err Reporting Enable */ +#define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002 /* Non-Fatal Err Reporting Enable */ +#define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004 /* Fatal Err Reporting Enable */ #define PCI_ERR_ROOT_STATUS 48 -#define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ -/* Multi ERR_COR Received */ -#define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 -/* ERR_FATAL/NONFATAL Received */ -#define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 -/* Multi ERR_FATAL/NONFATAL Received */ -#define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 -#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ -#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ -#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ +#define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ +#define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 /* Multiple ERR_COR */ +#define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 /* ERR_FATAL/NONFATAL */ +#define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 /* Multiple FATAL/NONFATAL */ +#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First UNC is Fatal */ +#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ +#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ #define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */ /* Virtual Channel */ @@ -967,6 +963,7 @@ #define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */ #define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */ #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */ +#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00 /* RP PIO log size */ #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */ #define PCI_EXP_DPC_CTL 6 /* DPC control */ @@ -980,6 +977,15 @@ #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ +#define PCI_EXP_DPC_RP_PIO_STATUS 0x0C /* RP PIO Status */ +#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO MASK */ +#define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14 /* RP PIO Severity */ +#define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18 /* RP PIO SysError */ +#define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C /* RP PIO Exception */ +#define PCI_EXP_DPC_RP_PIO_HEADER_LOG 0x20 /* RP PIO Header Log */ +#define PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG 0x30 /* RP PIO ImpSpec Log */ +#define PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG 0x34 /* RP PIO TLP Prefix Log */ + /* Precision Time Measurement */ #define PCI_PTM_CAP 0x04 /* PTM Capability */ #define PCI_PTM_CAP_REQ 0x00000001 /* Requester capable */ diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index b1c0b187acfe57da3ece7e91325536edcc9cff0c..140ae638cfd618b931ec1d298a80d1dffa4c1680 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -139,8 +139,9 @@ enum perf_event_sample_format { PERF_SAMPLE_IDENTIFIER = 1U << 16, PERF_SAMPLE_TRANSACTION = 1U << 17, PERF_SAMPLE_REGS_INTR = 1U << 18, + PERF_SAMPLE_PHYS_ADDR = 1U << 19, - PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */ }; /* @@ -174,6 +175,8 @@ enum perf_branch_sample_type_shift { PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14, /* no flags */ PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15, /* no cycles */ + PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16, /* save branch type */ + PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */ }; @@ -198,9 +201,30 @@ enum perf_branch_sample_type { PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT, PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT, + PERF_SAMPLE_BRANCH_TYPE_SAVE = + 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT, + PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT, }; +/* + * Common flow change classification + */ +enum { + PERF_BR_UNKNOWN = 0, /* unknown */ + PERF_BR_COND = 1, /* conditional */ + PERF_BR_UNCOND = 2, /* unconditional */ + PERF_BR_IND = 3, /* indirect */ + PERF_BR_CALL = 4, /* function call */ + PERF_BR_IND_CALL = 5, /* indirect function call */ + PERF_BR_RET = 6, /* function return */ + PERF_BR_SYSCALL = 7, /* syscall */ + PERF_BR_SYSRET = 8, /* syscall return */ + PERF_BR_COND_CALL = 9, /* conditional function call */ + PERF_BR_COND_RET = 10, /* conditional function return */ + PERF_BR_MAX, +}; + #define PERF_SAMPLE_BRANCH_PLM_ALL \ (PERF_SAMPLE_BRANCH_USER|\ PERF_SAMPLE_BRANCH_KERNEL|\ @@ -791,6 +815,7 @@ enum perf_event_type { * { u64 transaction; } && PERF_SAMPLE_TRANSACTION * { u64 abi; # enum perf_sample_regs_abi * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR + * { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR * }; */ PERF_RECORD_SAMPLE = 9, @@ -931,14 +956,20 @@ union perf_mem_data_src { mem_snoop:5, /* snoop mode */ mem_lock:2, /* lock instr */ mem_dtlb:7, /* tlb access */ - mem_rsvd:31; + mem_lvl_num:4, /* memory hierarchy level number */ + mem_remote:1, /* remote */ + mem_snoopx:2, /* snoop mode, ext */ + mem_rsvd:24; }; }; #elif defined(__BIG_ENDIAN_BITFIELD) union perf_mem_data_src { __u64 val; struct { - __u64 mem_rsvd:31, + __u64 mem_rsvd:24, + mem_snoopx:2, /* snoop mode, ext */ + mem_remote:1, /* remote */ + mem_lvl_num:4, /* memory hierarchy level number */ mem_dtlb:7, /* tlb access */ mem_lock:2, /* lock instr */ mem_snoop:5, /* snoop mode */ @@ -975,6 +1006,22 @@ union perf_mem_data_src { #define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */ #define PERF_MEM_LVL_SHIFT 5 +#define PERF_MEM_REMOTE_REMOTE 0x01 /* Remote */ +#define PERF_MEM_REMOTE_SHIFT 37 + +#define PERF_MEM_LVLNUM_L1 0x01 /* L1 */ +#define PERF_MEM_LVLNUM_L2 0x02 /* L2 */ +#define PERF_MEM_LVLNUM_L3 0x03 /* L3 */ +#define PERF_MEM_LVLNUM_L4 0x04 /* L4 */ +/* 5-0xa available */ +#define PERF_MEM_LVLNUM_ANY_CACHE 0x0b /* Any cache */ +#define PERF_MEM_LVLNUM_LFB 0x0c /* LFB */ +#define PERF_MEM_LVLNUM_RAM 0x0d /* RAM */ +#define PERF_MEM_LVLNUM_PMEM 0x0e /* PMEM */ +#define PERF_MEM_LVLNUM_NA 0x0f /* N/A */ + +#define PERF_MEM_LVLNUM_SHIFT 33 + /* snoop mode */ #define PERF_MEM_SNOOP_NA 0x01 /* not available */ #define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */ @@ -983,6 +1030,10 @@ union perf_mem_data_src { #define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */ #define PERF_MEM_SNOOP_SHIFT 19 +#define PERF_MEM_SNOOPX_FWD 0x01 /* forward */ +/* 1 free */ +#define PERF_MEM_SNOOPX_SHIFT 37 + /* locked instruction */ #define PERF_MEM_LOCK_NA 0x01 /* not available */ #define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */ @@ -1015,6 +1066,7 @@ union perf_mem_data_src { * in_tx: running in a hardware transaction * abort: aborting a hardware transaction * cycles: cycles from last branch (or 0 if not supported) + * type: branch type */ struct perf_branch_entry { __u64 from; @@ -1024,7 +1076,8 @@ struct perf_branch_entry { in_tx:1, /* in transaction */ abort:1, /* transaction abort */ cycles:16, /* cycle count to last branch */ - reserved:44; + type:4, /* branch type */ + reserved:40; }; #endif /* _UAPI_LINUX_PERF_EVENT_H */ diff --git a/include/uapi/linux/pps.h b/include/uapi/linux/pps.h index c1cb3825a8bc805e804f88c4e759e77716c6efef..c29d6b791c0816e35b0e025b80ed8d9f0eb0400a 100644 --- a/include/uapi/linux/pps.h +++ b/include/uapi/linux/pps.h @@ -95,8 +95,8 @@ struct pps_kparams { #define PPS_CAPTURECLEAR 0x02 /* capture clear events */ #define PPS_CAPTUREBOTH 0x03 /* capture assert and clear events */ -#define PPS_OFFSETASSERT 0x10 /* apply compensation for assert ev. */ -#define PPS_OFFSETCLEAR 0x20 /* apply compensation for clear ev. */ +#define PPS_OFFSETASSERT 0x10 /* apply compensation for assert event */ +#define PPS_OFFSETCLEAR 0x20 /* apply compensation for clear event */ #define PPS_CANWAIT 0x100 /* can we wait for an event? */ #define PPS_CANPOLL 0x200 /* bit reserved for future use */ diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h index 4d2489ef6f1065a2303f05a1450da5e06c50ee67..f17c9636a859330e067ffd8f1917f521ad4ba3d3 100644 --- a/include/uapi/linux/quota.h +++ b/include/uapi/linux/quota.h @@ -33,7 +33,6 @@ #ifndef _UAPI_LINUX_QUOTA_ #define _UAPI_LINUX_QUOTA_ -#include #include #define __DQUOT_VERSION__ "dquot_6.6.0" diff --git a/include/uapi/linux/raid/md_p.h b/include/uapi/linux/raid/md_p.h index d500bd224979d923f15732bd19a5bcde11c8f91f..b9197976b660b41c7e728c361dec5890feee8864 100644 --- a/include/uapi/linux/raid/md_p.h +++ b/include/uapi/linux/raid/md_p.h @@ -324,9 +324,10 @@ struct mdp_superblock_1 { #define MD_FEATURE_RECOVERY_BITMAP 128 /* recovery that is happening * is guided by bitmap. */ -#define MD_FEATURE_CLUSTERED 256 /* clustered MD */ +#define MD_FEATURE_CLUSTERED 256 /* clustered MD */ #define MD_FEATURE_JOURNAL 512 /* support write cache */ #define MD_FEATURE_PPL 1024 /* support PPL */ +#define MD_FEATURE_MULTIPLE_PPLS 2048 /* support for multiple PPLs */ #define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ |MD_FEATURE_RECOVERY_OFFSET \ |MD_FEATURE_RESHAPE_ACTIVE \ @@ -338,6 +339,7 @@ struct mdp_superblock_1 { |MD_FEATURE_CLUSTERED \ |MD_FEATURE_JOURNAL \ |MD_FEATURE_PPL \ + |MD_FEATURE_MULTIPLE_PPLS \ ) struct r5l_payload_header { diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index d148505010a7e8ae1b544ce479bde2597a3a4595..dab7dad9e01af4b32cdc587f8a9c149eeae98ec4 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -683,10 +683,29 @@ struct tcamsg { unsigned char tca__pad1; unsigned short tca__pad2; }; + +enum { + TCA_ROOT_UNSPEC, + TCA_ROOT_TAB, +#define TCA_ACT_TAB TCA_ROOT_TAB +#define TCAA_MAX TCA_ROOT_TAB + TCA_ROOT_FLAGS, + TCA_ROOT_COUNT, + TCA_ROOT_TIME_DELTA, /* in msecs */ + __TCA_ROOT_MAX, +#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1) +}; + #define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg)))) #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg)) -#define TCA_ACT_TAB 1 /* attr type must be >=1 */ -#define TCAA_MAX 1 +/* tcamsg flags stored in attribute TCA_ROOT_FLAGS + * + * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO + * actions in a dump. All dump responses will contain the number of actions + * being dumped stored in for user app's consumption in TCA_ROOT_COUNT + * + */ +#define TCA_FLAG_LARGE_DUMP_ON (1 << 0) /* New extended info filters for IFLA_EXT_MASK */ #define RTEXT_FILTER_VF (1 << 0) diff --git a/include/linux/rxrpc.h b/include/uapi/linux/rxrpc.h similarity index 54% rename from include/linux/rxrpc.h rename to include/uapi/linux/rxrpc.h index 7343f71783dce943d5d884e158efecf1f11f9d87..9656aad8f8f7b37e44052d35189eab2aac28cee3 100644 --- a/include/linux/rxrpc.h +++ b/include/uapi/linux/rxrpc.h @@ -1,17 +1,18 @@ -/* AF_RXRPC parameters +/* Types and definitions for AF_RXRPC. * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License + * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * 2 of the Licence, or (at your option) any later version. */ -#ifndef _LINUX_RXRPC_H -#define _LINUX_RXRPC_H +#ifndef _UAPI_LINUX_RXRPC_H +#define _UAPI_LINUX_RXRPC_H +#include #include #include @@ -76,4 +77,48 @@ enum rxrpc_cmsg_type { #define RXRPC_SECURITY_RXGK 4 /* gssapi-based */ #define RXRPC_SECURITY_RXK5 5 /* kerberos 5 */ -#endif /* _LINUX_RXRPC_H */ +/* + * RxRPC-level abort codes + */ +#define RX_CALL_DEAD -1 /* call/conn has been inactive and is shut down */ +#define RX_INVALID_OPERATION -2 /* invalid operation requested / attempted */ +#define RX_CALL_TIMEOUT -3 /* call timeout exceeded */ +#define RX_EOF -4 /* unexpected end of data on read op */ +#define RX_PROTOCOL_ERROR -5 /* low-level protocol error */ +#define RX_USER_ABORT -6 /* generic user abort */ +#define RX_ADDRINUSE -7 /* UDP port in use */ +#define RX_DEBUGI_BADTYPE -8 /* bad debugging packet type */ + +/* + * (un)marshalling abort codes (rxgen) + */ +#define RXGEN_CC_MARSHAL -450 +#define RXGEN_CC_UNMARSHAL -451 +#define RXGEN_SS_MARSHAL -452 +#define RXGEN_SS_UNMARSHAL -453 +#define RXGEN_DECODE -454 +#define RXGEN_OPCODE -455 +#define RXGEN_SS_XDRFREE -456 +#define RXGEN_CC_XDRFREE -457 + +/* + * Rx kerberos security abort codes + * - unfortunately we have no generalised security abort codes to say things + * like "unsupported security", so we have to use these instead and hope the + * other side understands + */ +#define RXKADINCONSISTENCY 19270400 /* security module structure inconsistent */ +#define RXKADPACKETSHORT 19270401 /* packet too short for security challenge */ +#define RXKADLEVELFAIL 19270402 /* security level negotiation failed */ +#define RXKADTICKETLEN 19270403 /* ticket length too short or too long */ +#define RXKADOUTOFSEQUENCE 19270404 /* packet had bad sequence number */ +#define RXKADNOAUTH 19270405 /* caller not authorised */ +#define RXKADBADKEY 19270406 /* illegal key: bad parity or weak */ +#define RXKADBADTICKET 19270407 /* security object was passed a bad ticket */ +#define RXKADUNKNOWNKEY 19270408 /* ticket contained unknown key version number */ +#define RXKADEXPIRED 19270409 /* authentication expired */ +#define RXKADSEALEDINCON 19270410 /* sealed data inconsistent */ +#define RXKADDATALEN 19270411 /* user data too long */ +#define RXKADILLEGALLEVEL 19270412 /* caller not authorised to use encrypted conns */ + +#endif /* _UAPI_LINUX_RXRPC_H */ diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h index 0f238a43ff1e7e5ebd8bd746a055fa910c10b51d..f6bc1dea32479f080de8f0d380b4cfaf2a547aae 100644 --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h @@ -11,27 +11,34 @@ #define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ /* Valid operations for seccomp syscall. */ -#define SECCOMP_SET_MODE_STRICT 0 -#define SECCOMP_SET_MODE_FILTER 1 +#define SECCOMP_SET_MODE_STRICT 0 +#define SECCOMP_SET_MODE_FILTER 1 +#define SECCOMP_GET_ACTION_AVAIL 2 /* Valid flags for SECCOMP_SET_MODE_FILTER */ #define SECCOMP_FILTER_FLAG_TSYNC 1 +#define SECCOMP_FILTER_FLAG_LOG 2 /* * All BPF programs must return a 32-bit value. * The bottom 16-bits are for optional return data. - * The upper 16-bits are ordered from least permissive values to most. + * The upper 16-bits are ordered from least permissive values to most, + * as a signed value (so 0x8000000 is negative). * * The ordering ensures that a min_t() over composed return values always * selects the least permissive choice. */ -#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ -#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ -#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ -#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ -#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ +#define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */ +#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */ +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD +#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ +#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ +#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ +#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */ +#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ /* Masks for the return value sections. */ +#define SECCOMP_RET_ACTION_FULL 0xffff0000U #define SECCOMP_RET_ACTION 0x7fff0000U #define SECCOMP_RET_DATA 0x0000ffffU diff --git a/include/uapi/linux/seg6_iptunnel.h b/include/uapi/linux/seg6_iptunnel.h index b6e5a0a1afd7a180938ba75250c7858c65868dc5..b23df9f58354e6e2d0174ddf356494c89a1dbc9b 100644 --- a/include/uapi/linux/seg6_iptunnel.h +++ b/include/uapi/linux/seg6_iptunnel.h @@ -33,16 +33,26 @@ struct seg6_iptunnel_encap { enum { SEG6_IPTUN_MODE_INLINE, SEG6_IPTUN_MODE_ENCAP, + SEG6_IPTUN_MODE_L2ENCAP, }; #ifdef __KERNEL__ static inline size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo) { - int encap = (tuninfo->mode == SEG6_IPTUN_MODE_ENCAP); - - return ((tuninfo->srh->hdrlen + 1) << 3) + - (encap * sizeof(struct ipv6hdr)); + int head = 0; + + switch (tuninfo->mode) { + case SEG6_IPTUN_MODE_INLINE: + break; + case SEG6_IPTUN_MODE_ENCAP: + head = sizeof(struct ipv6hdr); + break; + case SEG6_IPTUN_MODE_L2ENCAP: + return 0; + } + + return ((tuninfo->srh->hdrlen + 1) << 3) + head; } #endif diff --git a/include/uapi/linux/seg6_local.h b/include/uapi/linux/seg6_local.h new file mode 100644 index 0000000000000000000000000000000000000000..ef2d8c3e76c144368d1de59be7906599e562e1d1 --- /dev/null +++ b/include/uapi/linux/seg6_local.h @@ -0,0 +1,68 @@ +/* + * SR-IPv6 implementation + * + * Author: + * David Lebrun + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _UAPI_LINUX_SEG6_LOCAL_H +#define _UAPI_LINUX_SEG6_LOCAL_H + +#include + +enum { + SEG6_LOCAL_UNSPEC, + SEG6_LOCAL_ACTION, + SEG6_LOCAL_SRH, + SEG6_LOCAL_TABLE, + SEG6_LOCAL_NH4, + SEG6_LOCAL_NH6, + SEG6_LOCAL_IIF, + SEG6_LOCAL_OIF, + __SEG6_LOCAL_MAX, +}; +#define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1) + +enum { + SEG6_LOCAL_ACTION_UNSPEC = 0, + /* node segment */ + SEG6_LOCAL_ACTION_END = 1, + /* adjacency segment (IPv6 cross-connect) */ + SEG6_LOCAL_ACTION_END_X = 2, + /* lookup of next seg NH in table */ + SEG6_LOCAL_ACTION_END_T = 3, + /* decap and L2 cross-connect */ + SEG6_LOCAL_ACTION_END_DX2 = 4, + /* decap and IPv6 cross-connect */ + SEG6_LOCAL_ACTION_END_DX6 = 5, + /* decap and IPv4 cross-connect */ + SEG6_LOCAL_ACTION_END_DX4 = 6, + /* decap and lookup of DA in v6 table */ + SEG6_LOCAL_ACTION_END_DT6 = 7, + /* decap and lookup of DA in v4 table */ + SEG6_LOCAL_ACTION_END_DT4 = 8, + /* binding segment with insertion */ + SEG6_LOCAL_ACTION_END_B6 = 9, + /* binding segment with encapsulation */ + SEG6_LOCAL_ACTION_END_B6_ENCAP = 10, + /* binding segment with MPLS encap */ + SEG6_LOCAL_ACTION_END_BM = 11, + /* lookup last seg in table */ + SEG6_LOCAL_ACTION_END_S = 12, + /* forward to SR-unaware VNF with static proxy */ + SEG6_LOCAL_ACTION_END_AS = 13, + /* forward to SR-unaware VNF with masquerading */ + SEG6_LOCAL_ACTION_END_AM = 14, + + __SEG6_LOCAL_ACTION_MAX, +}; + +#define SEG6_LOCAL_ACTION_MAX (__SEG6_LOCAL_ACTION_MAX - 1) + +#endif diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index c34a2a3eeff568307d4fc8bb92ac2dc036fa7991..50d71c436323918f2ca2a20dd3d7c1d8016392eb 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -56,8 +56,6 @@ #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ -#define PORT_DA830 31 /* TI DA8xx/66AK2x */ -#define PORT_MAX_8250 31 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed @@ -70,12 +68,17 @@ #define PORT_CLPS711X 33 #define PORT_SA1100 34 #define PORT_UART00 35 +#define PORT_OWL 36 #define PORT_21285 37 /* Sparc type numbers. */ #define PORT_SUNZILOG 38 #define PORT_SUNSAB 39 +/* Intel EG20 */ +#define PORT_PCH_8LINE 44 +#define PORT_PCH_2LINE 45 + /* DEC */ #define PORT_DZ 46 #define PORT_ZS 47 @@ -205,8 +208,8 @@ /* MAX310X */ #define PORT_MAX310X 94 -/* High Speed UART for Medfield */ -#define PORT_MFD 95 +/* TI DA8xx/66AK2x */ +#define PORT_DA830 95 /* TI OMAP-UART */ #define PORT_OMAP 96 @@ -271,4 +274,7 @@ /* MPS2 UART */ #define PORT_MPS2UART 116 +/* MediaTek BTIF */ +#define PORT_MTK_BTIF 117 + #endif /* _UAPILINUX_SERIAL_CORE_H */ diff --git a/include/uapi/linux/shm.h b/include/uapi/linux/shm.h index 1fbf24ea37fdcf63f1da6ccfc5944ac6f21e299f..cf23c873719d7d703d8107ef994f19ea8f16b7c5 100644 --- a/include/uapi/linux/shm.h +++ b/include/uapi/linux/shm.h @@ -3,6 +3,7 @@ #include #include +#include #ifndef __KERNEL__ #include #endif @@ -40,11 +41,37 @@ struct shmid_ds { /* Include the definition of shmid64_ds and shminfo64 */ #include -/* permission flag for shmget */ +/* + * shmget() shmflg values. + */ +/* The bottom nine bits are the same as open(2) mode flags */ #define SHM_R 0400 /* or S_IRUGO from */ #define SHM_W 0200 /* or S_IWUGO from */ +/* Bits 9 & 10 are IPC_CREAT and IPC_EXCL */ +#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */ +#define SHM_NORESERVE 010000 /* don't check for reservations */ + +/* + * Huge page size encoding when SHM_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h + */ +#define SHM_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT +#define SHM_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK + +#define SHM_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB +#define SHM_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB +#define SHM_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB +#define SHM_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB +#define SHM_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB +#define SHM_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB +#define SHM_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB +#define SHM_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB +#define SHM_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB +#define SHM_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB -/* mode for attach */ +/* + * shmat() shmflg values + */ #define SHM_RDONLY 010000 /* read-only access */ #define SHM_RND 020000 /* round attach address to SHMLBA boundary */ #define SHM_REMAP 040000 /* take-over region on attach */ diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h index d8569329579816213255169d0c183f4400835f7b..758f12b585410b2de6936459c8e296902f7cd1a1 100644 --- a/include/uapi/linux/snmp.h +++ b/include/uapi/linux/snmp.h @@ -184,12 +184,7 @@ enum LINUX_MIB_DELAYEDACKLOST, /* DelayedACKLost */ LINUX_MIB_LISTENOVERFLOWS, /* ListenOverflows */ LINUX_MIB_LISTENDROPS, /* ListenDrops */ - LINUX_MIB_TCPPREQUEUED, /* TCPPrequeued */ - LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG, /* TCPDirectCopyFromBacklog */ - LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, /* TCPDirectCopyFromPrequeue */ - LINUX_MIB_TCPPREQUEUEDROPPED, /* TCPPrequeueDropped */ LINUX_MIB_TCPHPHITS, /* TCPHPHits */ - LINUX_MIB_TCPHPHITSTOUSER, /* TCPHPHitsToUser */ LINUX_MIB_TCPPUREACKS, /* TCPPureAcks */ LINUX_MIB_TCPHPACKS, /* TCPHPAcks */ LINUX_MIB_TCPRENORECOVERY, /* TCPRenoRecovery */ @@ -208,14 +203,12 @@ enum LINUX_MIB_TCPSACKFAILURES, /* TCPSackFailures */ LINUX_MIB_TCPLOSSFAILURES, /* TCPLossFailures */ LINUX_MIB_TCPFASTRETRANS, /* TCPFastRetrans */ - LINUX_MIB_TCPFORWARDRETRANS, /* TCPForwardRetrans */ LINUX_MIB_TCPSLOWSTARTRETRANS, /* TCPSlowStartRetrans */ LINUX_MIB_TCPTIMEOUTS, /* TCPTimeouts */ LINUX_MIB_TCPLOSSPROBES, /* TCPLossProbes */ LINUX_MIB_TCPLOSSPROBERECOVERY, /* TCPLossProbeRecovery */ LINUX_MIB_TCPRENORECOVERYFAIL, /* TCPRenoRecoveryFail */ LINUX_MIB_TCPSACKRECOVERYFAIL, /* TCPSackRecoveryFail */ - LINUX_MIB_TCPSCHEDULERFAILED, /* TCPSchedulerFailed */ LINUX_MIB_TCPRCVCOLLAPSED, /* TCPRcvCollapsed */ LINUX_MIB_TCPDSACKOLDSENT, /* TCPDSACKOldSent */ LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */ diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index a5507c97749718ccdd74433129f0c12fc9645fb5..15c25eccab2b3beab080c6cb6c6e1f1ffd15d0c1 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h @@ -231,6 +231,14 @@ enum { TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer */ TCP_NLA_DATA_SEGS_OUT, /* Data pkts sent including retransmission */ TCP_NLA_TOTAL_RETRANS, /* Data pkts retransmitted */ + TCP_NLA_PACING_RATE, /* Pacing rate in bytes per second */ + TCP_NLA_DELIVERY_RATE, /* Delivery rate in bytes per second */ + TCP_NLA_SND_CWND, /* Sending congestion window */ + TCP_NLA_REORDERING, /* Reordering metric */ + TCP_NLA_MIN_RTT, /* minimum RTT */ + TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt */ + TCP_NLA_DELIVERY_RATE_APP_LMT, /* delivery rate application limited ? */ + }; /* for TCP_MD5SIG socket option */ @@ -248,4 +256,13 @@ struct tcp_md5sig { __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ }; +/* INET_DIAG_MD5SIG */ +struct tcp_diag_md5sig { + __u8 tcpm_family; + __u8 tcpm_prefixlen; + __u16 tcpm_keylen; + __be32 tcpm_addr[4]; + __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; +}; + #endif /* _UAPI_LINUX_TCP_H */ diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 370d8845ab2173a733ccbf7091f9ce560024bb0e..688782e901407cb7baf5238b2281f8a38bdf2016 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -49,6 +49,7 @@ #define TEE_MAX_ARG_SIZE 1024 #define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ +#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */ /* * TEE Implementation ID diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index ce1169af39d72c58663e08f4ff7e0c175f467507..2a5d63040a0b0c7a713b9dcffa8dfd3cc7ac382f 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h @@ -780,6 +780,7 @@ struct usb_interface_assoc_descriptor { __u8 iFunction; } __attribute__ ((packed)); +#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8 /*-------------------------------------------------------------------------*/ diff --git a/include/uapi/linux/usb/charger.h b/include/uapi/linux/usb/charger.h new file mode 100644 index 0000000000000000000000000000000000000000..5f72af35b3ed768fd3bc1e2d8ca3f4f6ecaea47f --- /dev/null +++ b/include/uapi/linux/usb/charger.h @@ -0,0 +1,31 @@ +/* + * This file defines the USB charger type and state that are needed for + * USB device APIs. + */ + +#ifndef _UAPI__LINUX_USB_CHARGER_H +#define _UAPI__LINUX_USB_CHARGER_H + +/* + * USB charger type: + * SDP (Standard Downstream Port) + * DCP (Dedicated Charging Port) + * CDP (Charging Downstream Port) + * ACA (Accessory Charger Adapters) + */ +enum usb_charger_type { + UNKNOWN_TYPE, + SDP_TYPE, + DCP_TYPE, + CDP_TYPE, + ACA_TYPE, +}; + +/* USB charger state */ +enum usb_charger_state { + USB_CHARGER_DEFAULT, + USB_CHARGER_PRESENT, + USB_CHARGER_ABSENT, +}; + +#endif /* _UAPI__LINUX_USB_CHARGER_H */ diff --git a/include/uapi/linux/userfaultfd.h b/include/uapi/linux/userfaultfd.h index 3b059530dac95fa6e5dcf736e95a84fe80eb5f35..d6d1f65cb3c37c7b76738f544e6b625ebff39edb 100644 --- a/include/uapi/linux/userfaultfd.h +++ b/include/uapi/linux/userfaultfd.h @@ -23,7 +23,9 @@ UFFD_FEATURE_EVENT_REMOVE | \ UFFD_FEATURE_EVENT_UNMAP | \ UFFD_FEATURE_MISSING_HUGETLBFS | \ - UFFD_FEATURE_MISSING_SHMEM) + UFFD_FEATURE_MISSING_SHMEM | \ + UFFD_FEATURE_SIGBUS | \ + UFFD_FEATURE_THREAD_ID) #define UFFD_API_IOCTLS \ ((__u64)1 << _UFFDIO_REGISTER | \ (__u64)1 << _UFFDIO_UNREGISTER | \ @@ -78,6 +80,9 @@ struct uffd_msg { struct { __u64 flags; __u64 address; + union { + __u32 ptid; + } feat; } pagefault; struct { @@ -153,6 +158,13 @@ struct uffdio_api { * UFFD_FEATURE_MISSING_SHMEM works the same as * UFFD_FEATURE_MISSING_HUGETLBFS, but it applies to shmem * (i.e. tmpfs and other shmem based APIs). + * + * UFFD_FEATURE_SIGBUS feature means no page-fault + * (UFFD_EVENT_PAGEFAULT) event will be delivered, instead + * a SIGBUS signal will be sent to the faulting process. + * + * UFFD_FEATURE_THREAD_ID pid of the page faulted task_struct will + * be returned, if feature is not requested 0 will be returned. */ #define UFFD_FEATURE_PAGEFAULT_FLAG_WP (1<<0) #define UFFD_FEATURE_EVENT_FORK (1<<1) @@ -161,6 +173,8 @@ struct uffdio_api { #define UFFD_FEATURE_MISSING_HUGETLBFS (1<<4) #define UFFD_FEATURE_MISSING_SHMEM (1<<5) #define UFFD_FEATURE_EVENT_UNMAP (1<<6) +#define UFFD_FEATURE_SIGBUS (1<<7) +#define UFFD_FEATURE_THREAD_ID (1<<8) __u64 features; __u64 ioctls; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 45cf7359822cd276dd1485cd015418303afb87a0..185d6a0acc062a956e670e6d241c0f25edafc500 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -603,6 +603,11 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ + /* 12bit raw bayer packed, 6 bytes for every 4 pixels */ +#define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C') +#define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') +#define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') +#define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16 GRGR.. BGBG.. */ diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h index c07295969b7e134ec85bf58b72b100949a6462fa..6d5d5faa989b9247cba12e1e27ac26683dc2efca 100644 --- a/include/uapi/linux/virtio_ring.h +++ b/include/uapi/linux/virtio_ring.h @@ -1,7 +1,7 @@ #ifndef _UAPI_LINUX_VIRTIO_RING_H #define _UAPI_LINUX_VIRTIO_RING_H -/* An interface for efficient virtio implementation, currently for use by KVM - * and lguest, but hopefully others soon. Do NOT change this since it will +/* An interface for efficient virtio implementation, currently for use by KVM, + * but hopefully others soon. Do NOT change this since it will * break existing servers and clients. * * This header is BSD licensed so anyone can use the definitions to implement diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h index 2b384ff09fa05411bdffdaa53472591554aa2be6..5fe7370a2bef498f00083d2fd9d740403f15b6e5 100644 --- a/include/uapi/linux/xfrm.h +++ b/include/uapi/linux/xfrm.h @@ -304,6 +304,7 @@ enum xfrm_attr_type_t { XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */ XFRMA_PAD, XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */ + XFRMA_OUTPUT_MARK, /* __u32 */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h new file mode 100644 index 0000000000000000000000000000000000000000..842792eae38314bf055bb11e4b09b92dec0f4faf --- /dev/null +++ b/include/uapi/rdma/ib_user_ioctl_verbs.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef IB_USER_IOCTL_VERBS_H +#define IB_USER_IOCTL_VERBS_H + +#include + +#define UVERBS_UDATA_DRIVER_DATA_NS 1 +#define UVERBS_UDATA_DRIVER_DATA_FLAG (1UL << UVERBS_ID_NS_SHIFT) + +enum uverbs_default_objects { + UVERBS_OBJECT_DEVICE, /* No instances of DEVICE are allowed */ + UVERBS_OBJECT_PD, + UVERBS_OBJECT_COMP_CHANNEL, + UVERBS_OBJECT_CQ, + UVERBS_OBJECT_QP, + UVERBS_OBJECT_SRQ, + UVERBS_OBJECT_AH, + UVERBS_OBJECT_MR, + UVERBS_OBJECT_MW, + UVERBS_OBJECT_FLOW, + UVERBS_OBJECT_XRCD, + UVERBS_OBJECT_RWQ_IND_TBL, + UVERBS_OBJECT_WQ, + UVERBS_OBJECT_LAST, +}; + +enum { + UVERBS_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG, + UVERBS_UHW_OUT, +}; + +enum uverbs_create_cq_cmd_attr_ids { + CREATE_CQ_HANDLE, + CREATE_CQ_CQE, + CREATE_CQ_USER_HANDLE, + CREATE_CQ_COMP_CHANNEL, + CREATE_CQ_COMP_VECTOR, + CREATE_CQ_FLAGS, + CREATE_CQ_RESP_CQE, +}; + +enum uverbs_destroy_cq_cmd_attr_ids { + DESTROY_CQ_HANDLE, + DESTROY_CQ_RESP, +}; + +enum uverbs_actions_cq_ops { + UVERBS_CQ_CREATE, + UVERBS_CQ_DESTROY, +}; + +#endif + diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index 270c350bedc6c4911ff0763275fc034e90b2a018..d4e0b53bfc75ccdf03585c7b402389a21aba4dca 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h @@ -236,6 +236,20 @@ struct ib_uverbs_rss_caps { __u32 reserved; }; +struct ib_uverbs_tm_caps { + /* Max size of rendezvous request message */ + __u32 max_rndv_hdr_size; + /* Max number of entries in tag matching list */ + __u32 max_num_tags; + /* TM flags */ + __u32 flags; + /* Max number of outstanding list operations */ + __u32 max_ops; + /* Max number of SGE in tag matching entry */ + __u32 max_sge; + __u32 reserved; +}; + struct ib_uverbs_ex_query_device_resp { struct ib_uverbs_query_device_resp base; __u32 comp_mask; @@ -247,6 +261,7 @@ struct ib_uverbs_ex_query_device_resp { struct ib_uverbs_rss_caps rss_caps; __u32 max_wq_type_rq; __u32 raw_packet_caps; + struct ib_uverbs_tm_caps tm_caps; }; struct ib_uverbs_query_port { @@ -578,7 +593,7 @@ struct ib_uverbs_ex_create_qp { __u32 comp_mask; __u32 create_flags; __u32 rwq_ind_tbl_handle; - __u32 reserved1; + __u32 source_qpn; }; struct ib_uverbs_open_qp { @@ -1024,7 +1039,7 @@ struct ib_uverbs_create_xsrq { __u32 max_wr; __u32 max_sge; __u32 srq_limit; - __u32 reserved; + __u32 max_num_tags; __u32 xrcd_handle; __u32 cq_handle; __u64 driver_data[0]; diff --git a/include/uapi/rdma/mlx4-abi.h b/include/uapi/rdma/mlx4-abi.h index af431752655c576fe9bc5cf180e32a84dea0c69a..c55f60e05f867953a9ed2d134a7e4e67445bb5ca 100644 --- a/include/uapi/rdma/mlx4-abi.h +++ b/include/uapi/rdma/mlx4-abi.h @@ -95,13 +95,63 @@ struct mlx4_ib_create_srq_resp { __u32 reserved; }; +struct mlx4_ib_create_qp_rss { + __u64 rx_hash_fields_mask; + __u8 rx_hash_function; + __u8 reserved[7]; + __u8 rx_hash_key[40]; + __u32 comp_mask; + __u32 reserved1; +}; + struct mlx4_ib_create_qp { __u64 buf_addr; __u64 db_addr; __u8 log_sq_bb_count; __u8 log_sq_stride; __u8 sq_no_prefetch; - __u8 reserved[5]; + __u8 reserved; + __u32 inl_recv_sz; +}; + +struct mlx4_ib_create_wq { + __u64 buf_addr; + __u64 db_addr; + __u8 log_range_size; + __u8 reserved[3]; + __u32 comp_mask; +}; + +struct mlx4_ib_modify_wq { + __u32 comp_mask; + __u32 reserved; +}; + +struct mlx4_ib_create_rwq_ind_tbl_resp { + __u32 response_length; + __u32 reserved; +}; + +/* RX Hash function flags */ +enum mlx4_ib_rx_hash_function_flags { + MLX4_IB_RX_HASH_FUNC_TOEPLITZ = 1 << 0, +}; + +/* + * RX Hash flags, these flags allows to set which incoming packet's field should + * participates in RX Hash. Each flag represent certain packet's field, + * when the flag is set the field that is represented by the flag will + * participate in RX Hash calculation. + */ +enum mlx4_ib_rx_hash_fields { + MLX4_IB_RX_HASH_SRC_IPV4 = 1 << 0, + MLX4_IB_RX_HASH_DST_IPV4 = 1 << 1, + MLX4_IB_RX_HASH_SRC_IPV6 = 1 << 2, + MLX4_IB_RX_HASH_DST_IPV6 = 1 << 3, + MLX4_IB_RX_HASH_SRC_PORT_TCP = 1 << 4, + MLX4_IB_RX_HASH_DST_PORT_TCP = 1 << 5, + MLX4_IB_RX_HASH_SRC_PORT_UDP = 1 << 6, + MLX4_IB_RX_HASH_DST_PORT_UDP = 1 << 7 }; #endif /* MLX4_ABI_USER_H */ diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h index 0b3d30837a9f6456aabe028f5f9931b3593d778c..1791bf123ba96453564ec65fda99c27af062c052 100644 --- a/include/uapi/rdma/mlx5-abi.h +++ b/include/uapi/rdma/mlx5-abi.h @@ -168,6 +168,28 @@ struct mlx5_packet_pacing_caps { __u32 reserved; }; +enum mlx5_ib_mpw_caps { + MPW_RESERVED = 1 << 0, + MLX5_IB_ALLOW_MPW = 1 << 1, + MLX5_IB_SUPPORT_EMPW = 1 << 2, +}; + +enum mlx5_ib_sw_parsing_offloads { + MLX5_IB_SW_PARSING = 1 << 0, + MLX5_IB_SW_PARSING_CSUM = 1 << 1, + MLX5_IB_SW_PARSING_LSO = 1 << 2, +}; + +struct mlx5_ib_sw_parsing_caps { + __u32 sw_parsing_offloads; /* enum mlx5_ib_sw_parsing_offloads */ + + /* Corresponding bit will be set if qp type from + * 'enum ib_qp_type' is supported, e.g. + * supported_qpts |= 1 << IB_QPT_RAW_PACKET + */ + __u32 supported_qpts; +}; + struct mlx5_ib_query_device_resp { __u32 comp_mask; __u32 response_length; @@ -177,6 +199,7 @@ struct mlx5_ib_query_device_resp { struct mlx5_packet_pacing_caps packet_pacing_caps; __u32 mlx5_ib_support_multi_pkt_send_wqes; __u32 reserved; + struct mlx5_ib_sw_parsing_caps sw_parsing_caps; }; struct mlx5_ib_create_cq { diff --git a/include/uapi/rdma/qedr-abi.h b/include/uapi/rdma/qedr-abi.h index 75c270d839c8d5097757baf8644a0426db4fb16f..54b64357ab245e97151efeccecd2dde1c83960aa 100644 --- a/include/uapi/rdma/qedr-abi.h +++ b/include/uapi/rdma/qedr-abi.h @@ -49,6 +49,9 @@ struct qedr_alloc_ucontext_resp { __u32 sges_per_recv_wr; __u32 sges_per_srq_wr; __u32 max_cqes; + __u8 dpm_enabled; + __u8 wids_enabled; + __u16 wid_count; }; struct qedr_alloc_pd_ureq { diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h index 02fe8390c18f6dd6d857a8eac2a855b2174f2cd2..861440a87e7c50c29b87c94c5ddd6a5691b10be1 100644 --- a/include/uapi/rdma/rdma_netlink.h +++ b/include/uapi/rdma/rdma_netlink.h @@ -8,7 +8,7 @@ enum { RDMA_NL_IWCM, RDMA_NL_RSVD, RDMA_NL_LS, /* RDMA Local Services */ - RDMA_NL_I40IW, + RDMA_NL_NLDEV, /* RDMA device interface */ RDMA_NL_NUM_CLIENTS }; @@ -222,4 +222,86 @@ struct rdma_nla_ls_gid { __u8 gid[16]; }; +enum rdma_nldev_command { + RDMA_NLDEV_CMD_UNSPEC, + + RDMA_NLDEV_CMD_GET, /* can dump */ + RDMA_NLDEV_CMD_SET, + RDMA_NLDEV_CMD_NEW, + RDMA_NLDEV_CMD_DEL, + + RDMA_NLDEV_CMD_PORT_GET, /* can dump */ + RDMA_NLDEV_CMD_PORT_SET, + RDMA_NLDEV_CMD_PORT_NEW, + RDMA_NLDEV_CMD_PORT_DEL, + + RDMA_NLDEV_NUM_OPS +}; + +enum rdma_nldev_attr { + /* don't change the order or add anything between, this is ABI! */ + RDMA_NLDEV_ATTR_UNSPEC, + + /* Identifier for ib_device */ + RDMA_NLDEV_ATTR_DEV_INDEX, /* u32 */ + + RDMA_NLDEV_ATTR_DEV_NAME, /* string */ + /* + * Device index together with port index are identifiers + * for port/link properties. + * + * For RDMA_NLDEV_CMD_GET commamnd, port index will return number + * of available ports in ib_device, while for port specific operations, + * it will be real port index as it appears in sysfs. Port index follows + * sysfs notation and starts from 1 for the first port. + */ + RDMA_NLDEV_ATTR_PORT_INDEX, /* u32 */ + + /* + * Device and port capabilities + */ + RDMA_NLDEV_ATTR_CAP_FLAGS, /* u64 */ + + /* + * FW version + */ + RDMA_NLDEV_ATTR_FW_VERSION, /* string */ + + /* + * Node GUID (in host byte order) associated with the RDMA device. + */ + RDMA_NLDEV_ATTR_NODE_GUID, /* u64 */ + + /* + * System image GUID (in host byte order) associated with + * this RDMA device and other devices which are part of a + * single system. + */ + RDMA_NLDEV_ATTR_SYS_IMAGE_GUID, /* u64 */ + + /* + * Subnet prefix (in host byte order) + */ + RDMA_NLDEV_ATTR_SUBNET_PREFIX, /* u64 */ + + /* + * Local Identifier (LID), + * According to IB specification, It is 16-bit address assigned + * by the Subnet Manager. Extended to be 32-bit for OmniPath users. + */ + RDMA_NLDEV_ATTR_LID, /* u32 */ + RDMA_NLDEV_ATTR_SM_LID, /* u32 */ + + /* + * LID mask control (LMC) + */ + RDMA_NLDEV_ATTR_LMC, /* u8 */ + + RDMA_NLDEV_ATTR_PORT_STATE, /* u8 */ + RDMA_NLDEV_ATTR_PORT_PHYS_STATE, /* u8 */ + + RDMA_NLDEV_ATTR_DEV_NODE_TYPE, /* u8 */ + + RDMA_NLDEV_ATTR_MAX +}; #endif /* _UAPI_RDMA_NETLINK_H */ diff --git a/include/uapi/rdma/rdma_user_ioctl.h b/include/uapi/rdma/rdma_user_ioctl.h index 9388125ad51ba01eea5b7caffd0b5ee00582810d..165a27e969d58d96eb88020e72b5491eb8a8bb37 100644 --- a/include/uapi/rdma/rdma_user_ioctl.h +++ b/include/uapi/rdma/rdma_user_ioctl.h @@ -43,6 +43,39 @@ /* Legacy name, for user space application which already use it */ #define IB_IOCTL_MAGIC RDMA_IOCTL_MAGIC +#define RDMA_VERBS_IOCTL \ + _IOWR(RDMA_IOCTL_MAGIC, 1, struct ib_uverbs_ioctl_hdr) + +#define UVERBS_ID_NS_MASK 0xF000 +#define UVERBS_ID_NS_SHIFT 12 + +enum { + /* User input */ + UVERBS_ATTR_F_MANDATORY = 1U << 0, + /* + * Valid output bit should be ignored and considered set in + * mandatory fields. This bit is kernel output. + */ + UVERBS_ATTR_F_VALID_OUTPUT = 1U << 1, +}; + +struct ib_uverbs_attr { + __u16 attr_id; /* command specific type attribute */ + __u16 len; /* only for pointers */ + __u16 flags; /* combination of UVERBS_ATTR_F_XXXX */ + __u16 reserved; + __u64 data; /* ptr to command, inline data or idr/fd */ +}; + +struct ib_uverbs_ioctl_hdr { + __u16 length; + __u16 object_id; + __u16 method_id; + __u16 num_attrs; + __u64 reserved; + struct ib_uverbs_attr attrs[0]; +}; + /* * General blocks assignments * It is closed on purpose do not expose it it user space diff --git a/include/uapi/rdma/vmw_pvrdma-abi.h b/include/uapi/rdma/vmw_pvrdma-abi.h index c8c1d2d6df4d52ad84315727ec69849b9daa32ee..c6569b0032ecb2d06612b76d9e5dab09389f38fc 100644 --- a/include/uapi/rdma/vmw_pvrdma-abi.h +++ b/include/uapi/rdma/vmw_pvrdma-abi.h @@ -125,7 +125,8 @@ enum pvrdma_wc_flags { PVRDMA_WC_IP_CSUM_OK = 1 << 3, PVRDMA_WC_WITH_SMAC = 1 << 4, PVRDMA_WC_WITH_VLAN = 1 << 5, - PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_VLAN, + PVRDMA_WC_WITH_NETWORK_HDR_TYPE = 1 << 6, + PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_NETWORK_HDR_TYPE, }; struct pvrdma_alloc_ucontext_resp { @@ -283,7 +284,8 @@ struct pvrdma_cqe { __u8 dlid_path_bits; __u8 port_num; __u8 smac[6]; - __u8 reserved2[7]; /* Pad to next power of 2 (64). */ + __u8 network_hdr_type; + __u8 reserved2[6]; /* Pad to next power of 2 (64). */ }; #endif /* __VMW_PVRDMA_ABI_H__ */ diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h index dedb2056160d03a76ca2b1238652ad3afa64926e..f691e421f5e8730ccb4f1c5a9a04f779d4c972e5 100644 --- a/include/uapi/sound/snd_sst_tokens.h +++ b/include/uapi/sound/snd_sst_tokens.h @@ -163,8 +163,71 @@ * * %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec * + * %SKL_TKN_U32_PIPE_DIR: Specifies pipe direction. Can be + * playback/capture. + * + * %SKL_TKN_U32_NUM_CONFIGS: Number of pipe configs + * + * %SKL_TKN_U32_PATH_MEM_PGS: Size of memory (in pages) required for pipeline + * and its data + * + * %SKL_TKN_U32_PIPE_CONFIG_ID: Config id for the modules in the pipe + * and PCM params supported by that pipe + * config. This is used as index to fill + * up the pipe config and module config + * structure. + * + * %SKL_TKN_U32_CFG_FREQ: + * %SKL_TKN_U8_CFG_CHAN: + * %SKL_TKN_U8_CFG_BPS: PCM params (freq, channels, bits per sample) + * supported for each of the pipe configs. + * + * %SKL_TKN_CFG_MOD_RES_ID: Module's resource index for each of the + * pipe config + * + * %SKL_TKN_CFG_MOD_FMT_ID: Module's interface index for each of the + * pipe config + * + * %SKL_TKN_U8_NUM_MOD: Number of modules in the manifest + * + * %SKL_TKN_MM_U8_MOD_IDX: Current index of the module in the manifest + * + * %SKL_TKN_MM_U8_NUM_RES: Number of resources for the module + * + * %SKL_TKN_MM_U8_NUM_INTF: Number of interfaces for the module + * + * %SKL_TKN_MM_U32_RES_ID: Resource index for the resource info to + * be filled into. + * A module can support multiple resource + * configuration and is represnted as a + * resource table. This index is used to + * fill information into appropriate index. + * + * %SKL_TKN_MM_U32_CPS: DSP cycles per second + * + * %SKL_TKN_MM_U32_DMA_SIZE: Allocated buffer size for gateway DMA + * + * %SKL_TKN_MM_U32_CPC: DSP cycles allocated per frame + * + * %SKL_TKN_MM_U32_RES_PIN_ID: Resource pin index in the module + * + * %SKL_TKN_MM_U32_INTF_PIN_ID: Interface index in the module + * + * %SKL_TKN_MM_U32_PIN_BUF: Buffer size of the module pin + * + * %SKL_TKN_MM_U32_FMT_ID: Format index for each of the interface/ + * format information to be filled into. + * + * %SKL_TKN_MM_U32_NUM_IN_FMT: Number of input formats + * %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats + * * module_id and loadable flags dont have tokens as these values will be * read from the DSP FW manifest + * + * Tokens defined can be used either in the manifest or widget private data. + * + * SKL_TKN_MM is used as a suffix for all tokens that represent + * module data in the manifest. */ enum SKL_TKNS { SKL_TKN_UUID = 1, @@ -218,7 +281,34 @@ enum SKL_TKNS { SKL_TKL_U32_D0I3_CAPS, /* Typo added at v4.10 */ SKL_TKN_U32_D0I3_CAPS = SKL_TKL_U32_D0I3_CAPS, SKL_TKN_U32_DMA_BUF_SIZE, - SKL_TKN_MAX = SKL_TKN_U32_DMA_BUF_SIZE, + + SKL_TKN_U32_PIPE_DIRECTION, + SKL_TKN_U32_PIPE_CONFIG_ID, + SKL_TKN_U32_NUM_CONFIGS, + SKL_TKN_U32_PATH_MEM_PGS, + + SKL_TKN_U32_CFG_FREQ, + SKL_TKN_U8_CFG_CHAN, + SKL_TKN_U8_CFG_BPS, + SKL_TKN_CFG_MOD_RES_ID, + SKL_TKN_CFG_MOD_FMT_ID, + SKL_TKN_U8_NUM_MOD, + + SKL_TKN_MM_U8_MOD_IDX, + SKL_TKN_MM_U8_NUM_RES, + SKL_TKN_MM_U8_NUM_INTF, + SKL_TKN_MM_U32_RES_ID, + SKL_TKN_MM_U32_CPS, + SKL_TKN_MM_U32_DMA_SIZE, + SKL_TKN_MM_U32_CPC, + SKL_TKN_MM_U32_RES_PIN_ID, + SKL_TKN_MM_U32_INTF_PIN_ID, + SKL_TKN_MM_U32_PIN_BUF, + SKL_TKN_MM_U32_FMT_ID, + SKL_TKN_MM_U32_NUM_IN_FMT, + SKL_TKN_MM_U32_NUM_OUT_FMT, + + SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT, }; #endif diff --git a/include/xen/arm/page.h b/include/xen/arm/page.h index 415dbc6e43fd7ac6c256e2b30b704567ab5966d2..6adc2a955340627c590e1e06e8ab146b3c058f12 100644 --- a/include/xen/arm/page.h +++ b/include/xen/arm/page.h @@ -84,16 +84,6 @@ static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr) BUG(); } -/* TODO: this shouldn't be here but it is because the frontend drivers - * are using it (its rolled in headers) even though we won't hit the code path. - * So for right now just punt with this. - */ -static inline pte_t *lookup_address(unsigned long address, unsigned int *level) -{ - BUG(); - return NULL; -} - extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, struct gnttab_map_grant_ref *kmap_ops, struct page **pages, unsigned int count); diff --git a/include/xen/interface/io/pvcalls.h b/include/xen/interface/io/pvcalls.h new file mode 100644 index 0000000000000000000000000000000000000000..ccf97b817e72a18dfed209de5460df2cd21857cb --- /dev/null +++ b/include/xen/interface/io/pvcalls.h @@ -0,0 +1,121 @@ +#ifndef __XEN_PUBLIC_IO_XEN_PVCALLS_H__ +#define __XEN_PUBLIC_IO_XEN_PVCALLS_H__ + +#include +#include +#include + +/* "1" means socket, connect, release, bind, listen, accept and poll */ +#define XENBUS_FUNCTIONS_CALLS "1" + +/* + * See docs/misc/pvcalls.markdown in xen.git for the full specification: + * https://xenbits.xen.org/docs/unstable/misc/pvcalls.html + */ +struct pvcalls_data_intf { + RING_IDX in_cons, in_prod, in_error; + + uint8_t pad1[52]; + + RING_IDX out_cons, out_prod, out_error; + + uint8_t pad2[52]; + + RING_IDX ring_order; + grant_ref_t ref[]; +}; +DEFINE_XEN_FLEX_RING(pvcalls); + +#define PVCALLS_SOCKET 0 +#define PVCALLS_CONNECT 1 +#define PVCALLS_RELEASE 2 +#define PVCALLS_BIND 3 +#define PVCALLS_LISTEN 4 +#define PVCALLS_ACCEPT 5 +#define PVCALLS_POLL 6 + +struct xen_pvcalls_request { + uint32_t req_id; /* private to guest, echoed in response */ + uint32_t cmd; /* command to execute */ + union { + struct xen_pvcalls_socket { + uint64_t id; + uint32_t domain; + uint32_t type; + uint32_t protocol; + } socket; + struct xen_pvcalls_connect { + uint64_t id; + uint8_t addr[28]; + uint32_t len; + uint32_t flags; + grant_ref_t ref; + uint32_t evtchn; + } connect; + struct xen_pvcalls_release { + uint64_t id; + uint8_t reuse; + } release; + struct xen_pvcalls_bind { + uint64_t id; + uint8_t addr[28]; + uint32_t len; + } bind; + struct xen_pvcalls_listen { + uint64_t id; + uint32_t backlog; + } listen; + struct xen_pvcalls_accept { + uint64_t id; + uint64_t id_new; + grant_ref_t ref; + uint32_t evtchn; + } accept; + struct xen_pvcalls_poll { + uint64_t id; + } poll; + /* dummy member to force sizeof(struct xen_pvcalls_request) + * to match across archs */ + struct xen_pvcalls_dummy { + uint8_t dummy[56]; + } dummy; + } u; +}; + +struct xen_pvcalls_response { + uint32_t req_id; + uint32_t cmd; + int32_t ret; + uint32_t pad; + union { + struct _xen_pvcalls_socket { + uint64_t id; + } socket; + struct _xen_pvcalls_connect { + uint64_t id; + } connect; + struct _xen_pvcalls_release { + uint64_t id; + } release; + struct _xen_pvcalls_bind { + uint64_t id; + } bind; + struct _xen_pvcalls_listen { + uint64_t id; + } listen; + struct _xen_pvcalls_accept { + uint64_t id; + } accept; + struct _xen_pvcalls_poll { + uint64_t id; + } poll; + struct _xen_pvcalls_dummy { + uint8_t dummy[8]; + } dummy; + } u; +}; + +DEFINE_RING_TYPES(xen_pvcalls, struct xen_pvcalls_request, + struct xen_pvcalls_response); + +#endif diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index c794568555391518466d8d7d11a08a4b38ef3eaf..e547088ceb0e589b64cb58dff7dcf517b8c6ab82 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h @@ -9,6 +9,8 @@ #ifndef __XEN_PUBLIC_IO_RING_H__ #define __XEN_PUBLIC_IO_RING_H__ +#include + typedef unsigned int RING_IDX; /* Round a 32-bit unsigned constant down to the nearest power of two. */ diff --git a/include/xen/xen.h b/include/xen/xen.h index 6e8b7fc798017e4c13188339cf83b1e68fcd16e4..28c59ca529d74e09b4100201633c4e8b830de459 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -13,11 +13,16 @@ extern enum xen_domain_type xen_domain_type; #define xen_domain_type XEN_NATIVE #endif +#ifdef CONFIG_XEN_PVH +extern bool xen_pvh; +#else +#define xen_pvh 0 +#endif + #define xen_domain() (xen_domain_type != XEN_NATIVE) -#define xen_pv_domain() (xen_domain() && \ - xen_domain_type == XEN_PV_DOMAIN) -#define xen_hvm_domain() (xen_domain() && \ - xen_domain_type == XEN_HVM_DOMAIN) +#define xen_pv_domain() (xen_domain_type == XEN_PV_DOMAIN) +#define xen_hvm_domain() (xen_domain_type == XEN_HVM_DOMAIN) +#define xen_pvh_domain() (xen_pvh) #ifdef CONFIG_XEN_DOM0 #include @@ -29,11 +34,4 @@ extern enum xen_domain_type xen_domain_type; #define xen_initial_domain() (0) #endif /* CONFIG_XEN_DOM0 */ -#ifdef CONFIG_XEN_PVH -extern bool xen_pvh; -#define xen_pvh_domain() (xen_hvm_domain() && xen_pvh) -#else -#define xen_pvh_domain() (0) -#endif - #endif /* _XEN_XEN_H */ diff --git a/init/Kconfig b/init/Kconfig index 8514b25db21c6bb6928a6944cc6867ae9414321c..78cb2461012ef530f2755a0a6a8458428ed19043 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1275,12 +1275,17 @@ config BASE_FULL config FUTEX bool "Enable futex support" if EXPERT default y - select RT_MUTEXES + imply RT_MUTEXES help Disabling this option will cause the kernel to be built without support for "fast userspace mutexes". The resulting kernel may not run glibc-based applications correctly. +config FUTEX_PI + bool + depends on FUTEX && RT_MUTEXES + default y + config HAVE_FUTEX_CMPXCHG bool depends on FUTEX @@ -1571,6 +1576,15 @@ config SLAB_FREELIST_RANDOM security feature reduces the predictability of the kernel slab allocator against heap overflows. +config SLAB_FREELIST_HARDENED + bool "Harden slab freelist metadata" + depends on SLUB + help + Many kernel heap attacks try to target slab cache metadata and + other infrastructure. This options makes minor performance + sacrifies to harden the kernel slab allocator against common + freelist exploit methods. + config SLUB_CPU_PARTIAL default y depends on SLUB && SMP diff --git a/init/do_mounts.c b/init/do_mounts.c index c2de5104aad2d64c51dfc480c7f5fa3e84daa1b4..f6d4dd764a52483f0fed18593f7c38e4d1cfc30a 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -373,7 +373,7 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) printk(KERN_INFO "VFS: Mounted root (%s filesystem)%s on device %u:%u.\n", s->s_type->name, - s->s_flags & MS_RDONLY ? " readonly" : "", + sb_rdonly(s) ? " readonly" : "", MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); return 0; } @@ -420,8 +420,8 @@ void __init mount_block_root(char *name, int flags) #endif panic("VFS: Unable to mount root fs on %s", b); } - if (!(flags & MS_RDONLY)) { - flags |= MS_RDONLY; + if (!(flags & SB_RDONLY)) { + flags |= SB_RDONLY; goto retry; } diff --git a/init/initramfs.c b/init/initramfs.c index 8a532050043f5f804f06ddbf980e54965c9055de..e64bf7b4c1ca470d0eec8cd2003d14d2df4ed075 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -110,7 +110,7 @@ static void __init free_hash(void) static long __init do_utime(char *filename, time_t mtime) { - struct timespec t[2]; + struct timespec64 t[2]; t[0].tv_sec = mtime; t[0].tv_nsec = 0; diff --git a/init/main.c b/init/main.c index 052481fbe3633f64b420c5bbd6deea3be261e6a9..0ee9c6866ada1d9877c6afd50e23237eab6dfb4c 100644 --- a/init/main.c +++ b/init/main.c @@ -430,7 +430,6 @@ static noinline void __ref rest_init(void) * The boot idle thread must execute schedule() * at least once to get things moving: */ - init_idle_bootup_task(current); schedule_preempt_disabled(); /* Call into cpu_idle with preempt disabled */ cpu_startup_entry(CPUHP_ONLINE); @@ -488,6 +487,8 @@ void __init __weak thread_stack_cache_init(void) } #endif +void __init __weak mem_encrypt_init(void) { } + /* * Set up kernel memory allocators */ @@ -500,7 +501,6 @@ static void __init mm_init(void) page_ext_init_flatmem(); mem_init(); kmem_cache_init(); - percpu_init_late(); pgtable_init(); vmalloc_init(); ioremap_huge_init(); @@ -515,12 +515,6 @@ asmlinkage __visible void __init start_kernel(void) smp_setup_processor_id(); debug_objects_early_init(); - /* - * Set up the initial canary ASAP: - */ - add_latent_entropy(); - boot_init_stack_canary(); - cgroup_init_early(); local_irq_disable(); @@ -534,6 +528,13 @@ asmlinkage __visible void __init start_kernel(void) page_address_init(); pr_notice("%s", linux_banner); setup_arch(&command_line); + /* + * Set up the the initial canary and entropy after arch + * and after adding latent and command line entropy. + */ + add_latent_entropy(); + add_device_randomness(command_line, strlen(command_line)); + boot_init_stack_canary(); mm_init_cpumask(&init_mm); setup_command_line(command_line); setup_nr_cpu_ids(); @@ -541,7 +542,7 @@ asmlinkage __visible void __init start_kernel(void) boot_cpu_state_init(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ - build_all_zonelists(NULL, NULL); + build_all_zonelists(NULL); page_alloc_init(); pr_notice("Kernel command line: %s\n", boot_command_line); @@ -641,6 +642,14 @@ asmlinkage __visible void __init start_kernel(void) */ locking_selftest(); + /* + * This needs to be called before any devices perform DMA + * operations that might use the SWIOTLB bounce buffers. It will + * mark the bounce buffers as decrypted so that their usage will + * not cause "plain-text" data to be decrypted when accessed. + */ + mem_encrypt_init(); + #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { @@ -651,8 +660,8 @@ asmlinkage __visible void __init start_kernel(void) } #endif page_ext_init(); - debug_objects_mem_init(); kmemleak_init(); + debug_objects_mem_init(); setup_per_cpu_pageset(); numa_policy_init(); if (late_time_init) diff --git a/ipc/compat.c b/ipc/compat.c index 9b3c85f8a53825330b99015e34af9d2117393f06..b17bf93d7b49a0a4eff445ab3977041b7221c168 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -34,724 +34,48 @@ #include "util.h" -struct compat_msgbuf { - compat_long_t mtype; - char mtext[1]; -}; - -struct compat_ipc_perm { - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; -}; - -struct compat_semid_ds { - struct compat_ipc_perm sem_perm; - compat_time_t sem_otime; - compat_time_t sem_ctime; - compat_uptr_t sem_base; - compat_uptr_t sem_pending; - compat_uptr_t sem_pending_last; - compat_uptr_t undo; - unsigned short sem_nsems; -}; - -struct compat_msqid_ds { - struct compat_ipc_perm msg_perm; - compat_uptr_t msg_first; - compat_uptr_t msg_last; - compat_time_t msg_stime; - compat_time_t msg_rtime; - compat_time_t msg_ctime; - compat_ulong_t msg_lcbytes; - compat_ulong_t msg_lqbytes; - unsigned short msg_cbytes; - unsigned short msg_qnum; - unsigned short msg_qbytes; - compat_ipc_pid_t msg_lspid; - compat_ipc_pid_t msg_lrpid; -}; - -struct compat_shmid_ds { - struct compat_ipc_perm shm_perm; - int shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_ipc_pid_t shm_cpid; - compat_ipc_pid_t shm_lpid; - unsigned short shm_nattch; - unsigned short shm_unused; - compat_uptr_t shm_unused2; - compat_uptr_t shm_unused3; -}; - -struct compat_ipc_kludge { - compat_uptr_t msgp; - compat_long_t msgtyp; -}; - -struct compat_shminfo64 { - compat_ulong_t shmmax; - compat_ulong_t shmmin; - compat_ulong_t shmmni; - compat_ulong_t shmseg; - compat_ulong_t shmall; - compat_ulong_t __unused1; - compat_ulong_t __unused2; - compat_ulong_t __unused3; - compat_ulong_t __unused4; -}; - -struct compat_shm_info { - compat_int_t used_ids; - compat_ulong_t shm_tot, shm_rss, shm_swp; - compat_ulong_t swap_attempts, swap_successes; -}; - -static inline int compat_ipc_parse_version(int *cmd) -{ -#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION - int version = *cmd & IPC_64; - - /* this is tricky: architectures that have support for the old - * ipc structures in 64 bit binaries need to have IPC_64 set - * in cmd, the others need to have it cleared */ -#ifndef ipc_parse_version - *cmd |= IPC_64; -#else - *cmd &= ~IPC_64; -#endif - return version; -#else - /* With the asm-generic APIs, we always use the 64-bit versions. */ - return IPC_64; -#endif -} - -static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64, - struct compat_ipc64_perm __user *up64) -{ - int err; - - err = __get_user(p64->uid, &up64->uid); - err |= __get_user(p64->gid, &up64->gid); - err |= __get_user(p64->mode, &up64->mode); - return err; -} - -static inline int __get_compat_ipc_perm(struct ipc64_perm *p, - struct compat_ipc_perm __user *up) -{ - int err; - - err = __get_user(p->uid, &up->uid); - err |= __get_user(p->gid, &up->gid); - err |= __get_user(p->mode, &up->mode); - return err; -} - -static inline int __put_compat_ipc64_perm(struct ipc64_perm *p64, - struct compat_ipc64_perm __user *up64) +int get_compat_ipc64_perm(struct ipc64_perm *to, + struct compat_ipc64_perm __user *from) { - int err; - - err = __put_user(p64->key, &up64->key); - err |= __put_user(p64->uid, &up64->uid); - err |= __put_user(p64->gid, &up64->gid); - err |= __put_user(p64->cuid, &up64->cuid); - err |= __put_user(p64->cgid, &up64->cgid); - err |= __put_user(p64->mode, &up64->mode); - err |= __put_user(p64->seq, &up64->seq); - return err; -} - -static inline int __put_compat_ipc_perm(struct ipc64_perm *p, - struct compat_ipc_perm __user *uip) -{ - int err; - __compat_uid_t u; - __compat_gid_t g; - - err = __put_user(p->key, &uip->key); - SET_UID(u, p->uid); - err |= __put_user(u, &uip->uid); - SET_GID(g, p->gid); - err |= __put_user(g, &uip->gid); - SET_UID(u, p->cuid); - err |= __put_user(u, &uip->cuid); - SET_GID(g, p->cgid); - err |= __put_user(g, &uip->cgid); - err |= __put_user(p->mode, &uip->mode); - err |= __put_user(p->seq, &uip->seq); - return err; -} - -static inline int get_compat_semid64_ds(struct semid64_ds *sem64, - struct compat_semid64_ds __user *up64) -{ - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) - return -EFAULT; - return __get_compat_ipc64_perm(&sem64->sem_perm, &up64->sem_perm); -} - -static inline int get_compat_semid_ds(struct semid64_ds *s, - struct compat_semid_ds __user *up) -{ - if (!access_ok(VERIFY_READ, up, sizeof(*up))) + struct compat_ipc64_perm v; + if (copy_from_user(&v, from, sizeof(v))) return -EFAULT; - return __get_compat_ipc_perm(&s->sem_perm, &up->sem_perm); + to->uid = v.uid; + to->gid = v.gid; + to->mode = v.mode; + return 0; } -static inline int put_compat_semid64_ds(struct semid64_ds *sem64, - struct compat_semid64_ds __user *up64) +int get_compat_ipc_perm(struct ipc64_perm *to, + struct compat_ipc_perm __user *from) { - int err; - - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) + struct compat_ipc_perm v; + if (copy_from_user(&v, from, sizeof(v))) return -EFAULT; - err = __put_compat_ipc64_perm(&sem64->sem_perm, &up64->sem_perm); - err |= __put_user(sem64->sem_otime, &up64->sem_otime); - err |= __put_user(sem64->sem_ctime, &up64->sem_ctime); - err |= __put_user(sem64->sem_nsems, &up64->sem_nsems); - return err; + to->uid = v.uid; + to->gid = v.gid; + to->mode = v.mode; + return 0; } -static inline int put_compat_semid_ds(struct semid64_ds *s, - struct compat_semid_ds __user *up) +void to_compat_ipc64_perm(struct compat_ipc64_perm *to, struct ipc64_perm *from) { - int err; - - if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) - return -EFAULT; - err = __put_compat_ipc_perm(&s->sem_perm, &up->sem_perm); - err |= __put_user(s->sem_otime, &up->sem_otime); - err |= __put_user(s->sem_ctime, &up->sem_ctime); - err |= __put_user(s->sem_nsems, &up->sem_nsems); - return err; + to->key = from->key; + to->uid = from->uid; + to->gid = from->gid; + to->cuid = from->cuid; + to->cgid = from->cgid; + to->mode = from->mode; + to->seq = from->seq; } -static long do_compat_semctl(int first, int second, int third, u32 pad) +void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from) { - unsigned long fourth; - int err, err2; - struct semid64_ds sem64; - struct semid64_ds __user *up64; - int version = compat_ipc_parse_version(&third); - - memset(&sem64, 0, sizeof(sem64)); - - if ((third & (~IPC_64)) == SETVAL) -#ifdef __BIG_ENDIAN - fourth = (unsigned long)pad << 32; -#else - fourth = pad; -#endif - else - fourth = (unsigned long)compat_ptr(pad); - switch (third & (~IPC_64)) { - case IPC_INFO: - case IPC_RMID: - case SEM_INFO: - case GETVAL: - case GETPID: - case GETNCNT: - case GETZCNT: - case GETALL: - case SETVAL: - case SETALL: - err = sys_semctl(first, second, third, fourth); - break; - - case IPC_STAT: - case SEM_STAT: - up64 = compat_alloc_user_space(sizeof(sem64)); - fourth = (unsigned long)up64; - err = sys_semctl(first, second, third, fourth); - if (err < 0) - break; - if (copy_from_user(&sem64, up64, sizeof(sem64))) - err2 = -EFAULT; - else if (version == IPC_64) - err2 = put_compat_semid64_ds(&sem64, compat_ptr(pad)); - else - err2 = put_compat_semid_ds(&sem64, compat_ptr(pad)); - if (err2) - err = -EFAULT; - break; - - case IPC_SET: - if (version == IPC_64) - err = get_compat_semid64_ds(&sem64, compat_ptr(pad)); - else - err = get_compat_semid_ds(&sem64, compat_ptr(pad)); - - up64 = compat_alloc_user_space(sizeof(sem64)); - if (copy_to_user(up64, &sem64, sizeof(sem64))) - err = -EFAULT; - if (err) - break; - - fourth = (unsigned long)up64; - err = sys_semctl(first, second, third, fourth); - break; - - default: - err = -EINVAL; - break; - } - return err; -} - -static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) -{ - struct compat_msgbuf __user *msgp = dest; - size_t msgsz; - - if (put_user(msg->m_type, &msgp->mtype)) - return -EFAULT; - - msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz; - if (store_msg(msgp->mtext, msg, msgsz)) - return -EFAULT; - return msgsz; -} - -#ifndef COMPAT_SHMLBA -#define COMPAT_SHMLBA SHMLBA -#endif - -#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC -COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, - u32, third, compat_uptr_t, ptr, u32, fifth) -{ - int version; - u32 pad; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - /* struct sembuf is the same on 32 and 64bit :)) */ - return sys_semtimedop(first, compat_ptr(ptr), second, NULL); - case SEMTIMEDOP: - return compat_sys_semtimedop(first, compat_ptr(ptr), second, - compat_ptr(fifth)); - case SEMGET: - return sys_semget(first, second, third); - case SEMCTL: - if (!ptr) - return -EINVAL; - if (get_user(pad, (u32 __user *) compat_ptr(ptr))) - return -EFAULT; - return do_compat_semctl(first, second, third, pad); - - case MSGSND: { - struct compat_msgbuf __user *up = compat_ptr(ptr); - compat_long_t type; - - if (first < 0 || second < 0) - return -EINVAL; - - if (get_user(type, &up->mtype)) - return -EFAULT; - - return do_msgsnd(first, type, up->mtext, second, third); - } - case MSGRCV: { - void __user *uptr = compat_ptr(ptr); - - if (first < 0 || second < 0) - return -EINVAL; - - if (!version) { - struct compat_ipc_kludge ipck; - if (!uptr) - return -EINVAL; - if (copy_from_user(&ipck, uptr, sizeof(ipck))) - return -EFAULT; - uptr = compat_ptr(ipck.msgp); - fifth = ipck.msgtyp; - } - return do_msgrcv(first, uptr, second, (s32)fifth, third, - compat_do_msg_fill); - } - case MSGGET: - return sys_msgget(first, second); - case MSGCTL: - return compat_sys_msgctl(first, second, compat_ptr(ptr)); - - case SHMAT: { - int err; - unsigned long raddr; - - if (version == 1) - return -EINVAL; - err = do_shmat(first, compat_ptr(ptr), second, &raddr, - COMPAT_SHMLBA); - if (err < 0) - return err; - return put_user(raddr, (compat_ulong_t *)compat_ptr(third)); - } - case SHMDT: - return sys_shmdt(compat_ptr(ptr)); - case SHMGET: - return sys_shmget(first, (unsigned)second, third); - case SHMCTL: - return compat_sys_shmctl(first, second, compat_ptr(ptr)); - } - - return -ENOSYS; -} -#endif - -COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) -{ - return do_compat_semctl(semid, semnum, cmd, arg); -} - -COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, - compat_ssize_t, msgsz, int, msgflg) -{ - struct compat_msgbuf __user *up = compat_ptr(msgp); - compat_long_t mtype; - - if (get_user(mtype, &up->mtype)) - return -EFAULT; - return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg); -} - -COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, - compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg) -{ - return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, - msgflg, compat_do_msg_fill); -} - -static inline int get_compat_msqid64(struct msqid64_ds *m64, - struct compat_msqid64_ds __user *up64) -{ - int err; - - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) - return -EFAULT; - err = __get_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm); - err |= __get_user(m64->msg_qbytes, &up64->msg_qbytes); - return err; -} - -static inline int get_compat_msqid(struct msqid64_ds *m, - struct compat_msqid_ds __user *up) -{ - int err; - - if (!access_ok(VERIFY_READ, up, sizeof(*up))) - return -EFAULT; - err = __get_compat_ipc_perm(&m->msg_perm, &up->msg_perm); - err |= __get_user(m->msg_qbytes, &up->msg_qbytes); - return err; -} - -static inline int put_compat_msqid64_ds(struct msqid64_ds *m64, - struct compat_msqid64_ds __user *up64) -{ - int err; - - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) - return -EFAULT; - err = __put_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm); - err |= __put_user(m64->msg_stime, &up64->msg_stime); - err |= __put_user(m64->msg_rtime, &up64->msg_rtime); - err |= __put_user(m64->msg_ctime, &up64->msg_ctime); - err |= __put_user(m64->msg_cbytes, &up64->msg_cbytes); - err |= __put_user(m64->msg_qnum, &up64->msg_qnum); - err |= __put_user(m64->msg_qbytes, &up64->msg_qbytes); - err |= __put_user(m64->msg_lspid, &up64->msg_lspid); - err |= __put_user(m64->msg_lrpid, &up64->msg_lrpid); - return err; -} - -static inline int put_compat_msqid_ds(struct msqid64_ds *m, - struct compat_msqid_ds __user *up) -{ - int err; - - if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) - return -EFAULT; - err = __put_compat_ipc_perm(&m->msg_perm, &up->msg_perm); - err |= __put_user(m->msg_stime, &up->msg_stime); - err |= __put_user(m->msg_rtime, &up->msg_rtime); - err |= __put_user(m->msg_ctime, &up->msg_ctime); - err |= __put_user(m->msg_cbytes, &up->msg_cbytes); - err |= __put_user(m->msg_qnum, &up->msg_qnum); - err |= __put_user(m->msg_qbytes, &up->msg_qbytes); - err |= __put_user(m->msg_lspid, &up->msg_lspid); - err |= __put_user(m->msg_lrpid, &up->msg_lrpid); - return err; -} - -COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr) -{ - int err, err2; - struct msqid64_ds m64; - int version = compat_ipc_parse_version(&second); - void __user *p; - - memset(&m64, 0, sizeof(m64)); - - switch (second & (~IPC_64)) { - case IPC_INFO: - case IPC_RMID: - case MSG_INFO: - err = sys_msgctl(first, second, uptr); - break; - - case IPC_SET: - if (version == IPC_64) - err = get_compat_msqid64(&m64, uptr); - else - err = get_compat_msqid(&m64, uptr); - - if (err) - break; - p = compat_alloc_user_space(sizeof(m64)); - if (copy_to_user(p, &m64, sizeof(m64))) - err = -EFAULT; - else - err = sys_msgctl(first, second, p); - break; - - case IPC_STAT: - case MSG_STAT: - p = compat_alloc_user_space(sizeof(m64)); - err = sys_msgctl(first, second, p); - if (err < 0) - break; - if (copy_from_user(&m64, p, sizeof(m64))) - err2 = -EFAULT; - else if (version == IPC_64) - err2 = put_compat_msqid64_ds(&m64, uptr); - else - err2 = put_compat_msqid_ds(&m64, uptr); - if (err2) - err = -EFAULT; - break; - - default: - err = -EINVAL; - break; - } - return err; -} - -COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) -{ - unsigned long ret; - long err; - - err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA); - if (err) - return err; - force_successful_syscall_return(); - return (long)ret; -} - -static inline int get_compat_shmid64_ds(struct shmid64_ds *sem64, - struct compat_shmid64_ds __user *up64) -{ - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) - return -EFAULT; - return __get_compat_ipc64_perm(&sem64->shm_perm, &up64->shm_perm); -} - -static inline int get_compat_shmid_ds(struct shmid64_ds *s, - struct compat_shmid_ds __user *up) -{ - if (!access_ok(VERIFY_READ, up, sizeof(*up))) - return -EFAULT; - return __get_compat_ipc_perm(&s->shm_perm, &up->shm_perm); -} - -static inline int put_compat_shmid64_ds(struct shmid64_ds *sem64, - struct compat_shmid64_ds __user *up64) -{ - int err; - - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) - return -EFAULT; - err = __put_compat_ipc64_perm(&sem64->shm_perm, &up64->shm_perm); - err |= __put_user(sem64->shm_atime, &up64->shm_atime); - err |= __put_user(sem64->shm_dtime, &up64->shm_dtime); - err |= __put_user(sem64->shm_ctime, &up64->shm_ctime); - err |= __put_user(sem64->shm_segsz, &up64->shm_segsz); - err |= __put_user(sem64->shm_nattch, &up64->shm_nattch); - err |= __put_user(sem64->shm_cpid, &up64->shm_cpid); - err |= __put_user(sem64->shm_lpid, &up64->shm_lpid); - return err; -} - -static inline int put_compat_shmid_ds(struct shmid64_ds *s, - struct compat_shmid_ds __user *up) -{ - int err; - - if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) - return -EFAULT; - err = __put_compat_ipc_perm(&s->shm_perm, &up->shm_perm); - err |= __put_user(s->shm_atime, &up->shm_atime); - err |= __put_user(s->shm_dtime, &up->shm_dtime); - err |= __put_user(s->shm_ctime, &up->shm_ctime); - err |= __put_user(s->shm_segsz, &up->shm_segsz); - err |= __put_user(s->shm_nattch, &up->shm_nattch); - err |= __put_user(s->shm_cpid, &up->shm_cpid); - err |= __put_user(s->shm_lpid, &up->shm_lpid); - return err; -} - -static inline int put_compat_shminfo64(struct shminfo64 *smi, - struct compat_shminfo64 __user *up64) -{ - int err; - - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) - return -EFAULT; - if (smi->shmmax > INT_MAX) - smi->shmmax = INT_MAX; - err = __put_user(smi->shmmax, &up64->shmmax); - err |= __put_user(smi->shmmin, &up64->shmmin); - err |= __put_user(smi->shmmni, &up64->shmmni); - err |= __put_user(smi->shmseg, &up64->shmseg); - err |= __put_user(smi->shmall, &up64->shmall); - return err; -} - -static inline int put_compat_shminfo(struct shminfo64 *smi, - struct shminfo __user *up) -{ - int err; - - if (!access_ok(VERIFY_WRITE, up, sizeof(*up))) - return -EFAULT; - if (smi->shmmax > INT_MAX) - smi->shmmax = INT_MAX; - err = __put_user(smi->shmmax, &up->shmmax); - err |= __put_user(smi->shmmin, &up->shmmin); - err |= __put_user(smi->shmmni, &up->shmmni); - err |= __put_user(smi->shmseg, &up->shmseg); - err |= __put_user(smi->shmall, &up->shmall); - return err; -} - -static inline int put_compat_shm_info(struct shm_info __user *ip, - struct compat_shm_info __user *uip) -{ - int err; - struct shm_info si; - - if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip)) || - copy_from_user(&si, ip, sizeof(si))) - return -EFAULT; - err = __put_user(si.used_ids, &uip->used_ids); - err |= __put_user(si.shm_tot, &uip->shm_tot); - err |= __put_user(si.shm_rss, &uip->shm_rss); - err |= __put_user(si.shm_swp, &uip->shm_swp); - err |= __put_user(si.swap_attempts, &uip->swap_attempts); - err |= __put_user(si.swap_successes, &uip->swap_successes); - return err; -} - -COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr) -{ - void __user *p; - struct shmid64_ds sem64; - struct shminfo64 smi; - int err, err2; - int version = compat_ipc_parse_version(&second); - - memset(&sem64, 0, sizeof(sem64)); - - switch (second & (~IPC_64)) { - case IPC_RMID: - case SHM_LOCK: - case SHM_UNLOCK: - err = sys_shmctl(first, second, uptr); - break; - - case IPC_INFO: - p = compat_alloc_user_space(sizeof(smi)); - err = sys_shmctl(first, second, p); - if (err < 0) - break; - if (copy_from_user(&smi, p, sizeof(smi))) - err2 = -EFAULT; - else if (version == IPC_64) - err2 = put_compat_shminfo64(&smi, uptr); - else - err2 = put_compat_shminfo(&smi, uptr); - if (err2) - err = -EFAULT; - break; - - - case IPC_SET: - if (version == IPC_64) - err = get_compat_shmid64_ds(&sem64, uptr); - else - err = get_compat_shmid_ds(&sem64, uptr); - - if (err) - break; - p = compat_alloc_user_space(sizeof(sem64)); - if (copy_to_user(p, &sem64, sizeof(sem64))) - err = -EFAULT; - else - err = sys_shmctl(first, second, p); - break; - - case IPC_STAT: - case SHM_STAT: - p = compat_alloc_user_space(sizeof(sem64)); - err = sys_shmctl(first, second, p); - if (err < 0) - break; - if (copy_from_user(&sem64, p, sizeof(sem64))) - err2 = -EFAULT; - else if (version == IPC_64) - err2 = put_compat_shmid64_ds(&sem64, uptr); - else - err2 = put_compat_shmid_ds(&sem64, uptr); - if (err2) - err = -EFAULT; - break; - - case SHM_INFO: - p = compat_alloc_user_space(sizeof(struct shm_info)); - err = sys_shmctl(first, second, p); - if (err < 0) - break; - err2 = put_compat_shm_info(p, uptr); - if (err2) - err = -EFAULT; - break; - - default: - err = -EINVAL; - break; - } - return err; -} - -COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, - unsigned, nsops, - const struct compat_timespec __user *, timeout) -{ - struct timespec __user *ts64; - if (compat_convert_timespec(&ts64, timeout)) - return -EFAULT; - return sys_semtimedop(semid, tsems, nsops, ts64); + to->key = from->key; + SET_UID(to->uid, from->uid); + SET_GID(to->gid, from->gid); + SET_UID(to->cuid, from->cuid); + SET_GID(to->cgid, from->cgid); + to->mode = from->mode; + to->seq = from->seq; } diff --git a/ipc/mqueue.c b/ipc/mqueue.c index eb1391b52c6f84fe75dec4e8366d858341ac665a..d240256263103f89972ab5e62201549a7074a829 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -668,11 +668,11 @@ static void __do_notify(struct mqueue_inode_info *info) } static int prepare_timeout(const struct timespec __user *u_abs_timeout, - struct timespec *ts) + struct timespec64 *ts) { - if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec))) + if (get_timespec64(ts, u_abs_timeout)) return -EFAULT; - if (!timespec_valid(ts)) + if (!timespec64_valid(ts)) return -EINVAL; return 0; } @@ -962,7 +962,7 @@ static inline void pipelined_receive(struct wake_q_head *wake_q, static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, size_t msg_len, unsigned int msg_prio, - struct timespec *ts) + struct timespec64 *ts) { struct fd f; struct inode *inode; @@ -979,7 +979,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, return -EINVAL; if (ts) { - expires = timespec_to_ktime(*ts); + expires = timespec64_to_ktime(*ts); timeout = &expires; } @@ -1080,7 +1080,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, size_t msg_len, unsigned int __user *u_msg_prio, - struct timespec *ts) + struct timespec64 *ts) { ssize_t ret; struct msg_msg *msg_ptr; @@ -1092,7 +1092,7 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, struct posix_msg_tree_node *new_leaf = NULL; if (ts) { - expires = timespec_to_ktime(*ts); + expires = timespec64_to_ktime(*ts); timeout = &expires; } @@ -1184,7 +1184,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, size_t, msg_len, unsigned int, msg_prio, const struct timespec __user *, u_abs_timeout) { - struct timespec ts, *p = NULL; + struct timespec64 ts, *p = NULL; if (u_abs_timeout) { int res = prepare_timeout(u_abs_timeout, &ts); if (res) @@ -1198,7 +1198,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, size_t, msg_len, unsigned int __user *, u_msg_prio, const struct timespec __user *, u_abs_timeout) { - struct timespec ts, *p = NULL; + struct timespec64 ts, *p = NULL; if (u_abs_timeout) { int res = prepare_timeout(u_abs_timeout, &ts); if (res) @@ -1475,11 +1475,11 @@ COMPAT_SYSCALL_DEFINE4(mq_open, const char __user *, u_name, } static int compat_prepare_timeout(const struct compat_timespec __user *p, - struct timespec *ts) + struct timespec64 *ts) { - if (compat_get_timespec(ts, p)) + if (compat_get_timespec64(ts, p)) return -EFAULT; - if (!timespec_valid(ts)) + if (!timespec64_valid(ts)) return -EINVAL; return 0; } @@ -1489,7 +1489,7 @@ COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, compat_size_t, msg_len, unsigned int, msg_prio, const struct compat_timespec __user *, u_abs_timeout) { - struct timespec ts, *p = NULL; + struct timespec64 ts, *p = NULL; if (u_abs_timeout) { int res = compat_prepare_timeout(u_abs_timeout, &ts); if (res) @@ -1504,7 +1504,7 @@ COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, compat_size_t, msg_len, unsigned int __user *, u_msg_prio, const struct compat_timespec __user *, u_abs_timeout) { - struct timespec ts, *p = NULL; + struct timespec64 ts, *p = NULL; if (u_abs_timeout) { int res = compat_prepare_timeout(u_abs_timeout, &ts); if (res) diff --git a/ipc/msg.c b/ipc/msg.c index 5b25e0755656a6a2b85a7f647bf77cd87db77a5a..06be5a9adfa41c39fd155f4ebc13ada0142b1bca 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -133,7 +133,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) } msq->q_stime = msq->q_rtime = 0; - msq->q_ctime = get_seconds(); + msq->q_ctime = ktime_get_real_seconds(); msq->q_cbytes = msq->q_qnum = 0; msq->q_qbytes = ns->msg_ctlmnb; msq->q_lspid = msq->q_lrpid = 0; @@ -361,23 +361,17 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) * NOTE: no locks must be held, the rwsem is taken inside this function. */ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, - struct msqid_ds __user *buf, int version) + struct msqid64_ds *msqid64) { struct kern_ipc_perm *ipcp; - struct msqid64_ds uninitialized_var(msqid64); struct msg_queue *msq; int err; - if (cmd == IPC_SET) { - if (copy_msqid_from_user(&msqid64, buf, version)) - return -EFAULT; - } - down_write(&msg_ids(ns).rwsem); rcu_read_lock(); ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, - &msqid64.msg_perm, msqid64.msg_qbytes); + &msqid64->msg_perm, msqid64->msg_qbytes); if (IS_ERR(ipcp)) { err = PTR_ERR(ipcp); goto out_unlock1; @@ -399,20 +393,20 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, { DEFINE_WAKE_Q(wake_q); - if (msqid64.msg_qbytes > ns->msg_ctlmnb && + if (msqid64->msg_qbytes > ns->msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) { err = -EPERM; goto out_unlock1; } ipc_lock_object(&msq->q_perm); - err = ipc_update_perm(&msqid64.msg_perm, ipcp); + err = ipc_update_perm(&msqid64->msg_perm, ipcp); if (err) goto out_unlock0; - msq->q_qbytes = msqid64.msg_qbytes; + msq->q_qbytes = msqid64->msg_qbytes; - msq->q_ctime = get_seconds(); + msq->q_ctime = ktime_get_real_seconds(); /* * Sleeping receivers might be excluded by * stricter permissions. @@ -442,111 +436,89 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, return err; } -static int msgctl_nolock(struct ipc_namespace *ns, int msqid, - int cmd, int version, void __user *buf) +static int msgctl_info(struct ipc_namespace *ns, int msqid, + int cmd, struct msginfo *msginfo) { int err; - struct msg_queue *msq; - - switch (cmd) { - case IPC_INFO: - case MSG_INFO: - { - struct msginfo msginfo; - int max_id; - - if (!buf) - return -EFAULT; - - /* - * We must not return kernel stack data. - * due to padding, it's not enough - * to set all member fields. - */ - err = security_msg_queue_msgctl(NULL, cmd); - if (err) - return err; + int max_id; - memset(&msginfo, 0, sizeof(msginfo)); - msginfo.msgmni = ns->msg_ctlmni; - msginfo.msgmax = ns->msg_ctlmax; - msginfo.msgmnb = ns->msg_ctlmnb; - msginfo.msgssz = MSGSSZ; - msginfo.msgseg = MSGSEG; - down_read(&msg_ids(ns).rwsem); - if (cmd == MSG_INFO) { - msginfo.msgpool = msg_ids(ns).in_use; - msginfo.msgmap = atomic_read(&ns->msg_hdrs); - msginfo.msgtql = atomic_read(&ns->msg_bytes); - } else { - msginfo.msgmap = MSGMAP; - msginfo.msgpool = MSGPOOL; - msginfo.msgtql = MSGTQL; - } - max_id = ipc_get_maxid(&msg_ids(ns)); - up_read(&msg_ids(ns).rwsem); - if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) - return -EFAULT; - return (max_id < 0) ? 0 : max_id; + /* + * We must not return kernel stack data. + * due to padding, it's not enough + * to set all member fields. + */ + err = security_msg_queue_msgctl(NULL, cmd); + if (err) + return err; + + memset(msginfo, 0, sizeof(*msginfo)); + msginfo->msgmni = ns->msg_ctlmni; + msginfo->msgmax = ns->msg_ctlmax; + msginfo->msgmnb = ns->msg_ctlmnb; + msginfo->msgssz = MSGSSZ; + msginfo->msgseg = MSGSEG; + down_read(&msg_ids(ns).rwsem); + if (cmd == MSG_INFO) { + msginfo->msgpool = msg_ids(ns).in_use; + msginfo->msgmap = atomic_read(&ns->msg_hdrs); + msginfo->msgtql = atomic_read(&ns->msg_bytes); + } else { + msginfo->msgmap = MSGMAP; + msginfo->msgpool = MSGPOOL; + msginfo->msgtql = MSGTQL; } + max_id = ipc_get_maxid(&msg_ids(ns)); + up_read(&msg_ids(ns).rwsem); + return (max_id < 0) ? 0 : max_id; +} - case MSG_STAT: - case IPC_STAT: - { - struct msqid64_ds tbuf; - int success_return; - - if (!buf) - return -EFAULT; +static int msgctl_stat(struct ipc_namespace *ns, int msqid, + int cmd, struct msqid64_ds *p) +{ + int err; + struct msg_queue *msq; + int success_return; - memset(&tbuf, 0, sizeof(tbuf)); + memset(p, 0, sizeof(*p)); - rcu_read_lock(); - if (cmd == MSG_STAT) { - msq = msq_obtain_object(ns, msqid); - if (IS_ERR(msq)) { - err = PTR_ERR(msq); - goto out_unlock; - } - success_return = msq->q_perm.id; - } else { - msq = msq_obtain_object_check(ns, msqid); - if (IS_ERR(msq)) { - err = PTR_ERR(msq); - goto out_unlock; - } - success_return = 0; - } - - err = -EACCES; - if (ipcperms(ns, &msq->q_perm, S_IRUGO)) + rcu_read_lock(); + if (cmd == MSG_STAT) { + msq = msq_obtain_object(ns, msqid); + if (IS_ERR(msq)) { + err = PTR_ERR(msq); goto out_unlock; - - err = security_msg_queue_msgctl(msq, cmd); - if (err) + } + success_return = msq->q_perm.id; + } else { + msq = msq_obtain_object_check(ns, msqid); + if (IS_ERR(msq)) { + err = PTR_ERR(msq); goto out_unlock; + } + success_return = 0; + } - kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); - tbuf.msg_stime = msq->q_stime; - tbuf.msg_rtime = msq->q_rtime; - tbuf.msg_ctime = msq->q_ctime; - tbuf.msg_cbytes = msq->q_cbytes; - tbuf.msg_qnum = msq->q_qnum; - tbuf.msg_qbytes = msq->q_qbytes; - tbuf.msg_lspid = msq->q_lspid; - tbuf.msg_lrpid = msq->q_lrpid; - rcu_read_unlock(); + err = -EACCES; + if (ipcperms(ns, &msq->q_perm, S_IRUGO)) + goto out_unlock; - if (copy_msqid_to_user(buf, &tbuf, version)) - return -EFAULT; - return success_return; - } + err = security_msg_queue_msgctl(msq, cmd); + if (err) + goto out_unlock; + + kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm); + p->msg_stime = msq->q_stime; + p->msg_rtime = msq->q_rtime; + p->msg_ctime = msq->q_ctime; + p->msg_cbytes = msq->q_cbytes; + p->msg_qnum = msq->q_qnum; + p->msg_qbytes = msq->q_qbytes; + p->msg_lspid = msq->q_lspid; + p->msg_lrpid = msq->q_lrpid; + rcu_read_unlock(); - default: - return -EINVAL; - } + return success_return; - return err; out_unlock: rcu_read_unlock(); return err; @@ -556,6 +528,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) { int version; struct ipc_namespace *ns; + struct msqid64_ds msqid64; + int err; if (msqid < 0 || cmd < 0) return -EINVAL; @@ -565,18 +539,147 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) switch (cmd) { case IPC_INFO: - case MSG_INFO: + case MSG_INFO: { + struct msginfo msginfo; + err = msgctl_info(ns, msqid, cmd, &msginfo); + if (err < 0) + return err; + if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) + err = -EFAULT; + return err; + } case MSG_STAT: /* msqid is an index rather than a msg queue id */ case IPC_STAT: - return msgctl_nolock(ns, msqid, cmd, version, buf); + err = msgctl_stat(ns, msqid, cmd, &msqid64); + if (err < 0) + return err; + if (copy_msqid_to_user(buf, &msqid64, version)) + err = -EFAULT; + return err; case IPC_SET: + if (copy_msqid_from_user(&msqid64, buf, version)) + return -EFAULT; + /* fallthru */ case IPC_RMID: - return msgctl_down(ns, msqid, cmd, buf, version); + return msgctl_down(ns, msqid, cmd, &msqid64); default: return -EINVAL; } } +#ifdef CONFIG_COMPAT + +struct compat_msqid_ds { + struct compat_ipc_perm msg_perm; + compat_uptr_t msg_first; + compat_uptr_t msg_last; + compat_time_t msg_stime; + compat_time_t msg_rtime; + compat_time_t msg_ctime; + compat_ulong_t msg_lcbytes; + compat_ulong_t msg_lqbytes; + unsigned short msg_cbytes; + unsigned short msg_qnum; + unsigned short msg_qbytes; + compat_ipc_pid_t msg_lspid; + compat_ipc_pid_t msg_lrpid; +}; + +static int copy_compat_msqid_from_user(struct msqid64_ds *out, void __user *buf, + int version) +{ + memset(out, 0, sizeof(*out)); + if (version == IPC_64) { + struct compat_msqid64_ds *p = buf; + if (get_compat_ipc64_perm(&out->msg_perm, &p->msg_perm)) + return -EFAULT; + if (get_user(out->msg_qbytes, &p->msg_qbytes)) + return -EFAULT; + } else { + struct compat_msqid_ds *p = buf; + if (get_compat_ipc_perm(&out->msg_perm, &p->msg_perm)) + return -EFAULT; + if (get_user(out->msg_qbytes, &p->msg_qbytes)) + return -EFAULT; + } + return 0; +} + +static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in, + int version) +{ + if (version == IPC_64) { + struct compat_msqid64_ds v; + memset(&v, 0, sizeof(v)); + to_compat_ipc64_perm(&v.msg_perm, &in->msg_perm); + v.msg_stime = in->msg_stime; + v.msg_rtime = in->msg_rtime; + v.msg_ctime = in->msg_ctime; + v.msg_cbytes = in->msg_cbytes; + v.msg_qnum = in->msg_qnum; + v.msg_qbytes = in->msg_qbytes; + v.msg_lspid = in->msg_lspid; + v.msg_lrpid = in->msg_lrpid; + return copy_to_user(buf, &v, sizeof(v)); + } else { + struct compat_msqid_ds v; + memset(&v, 0, sizeof(v)); + to_compat_ipc_perm(&v.msg_perm, &in->msg_perm); + v.msg_stime = in->msg_stime; + v.msg_rtime = in->msg_rtime; + v.msg_ctime = in->msg_ctime; + v.msg_cbytes = in->msg_cbytes; + v.msg_qnum = in->msg_qnum; + v.msg_qbytes = in->msg_qbytes; + v.msg_lspid = in->msg_lspid; + v.msg_lrpid = in->msg_lrpid; + return copy_to_user(buf, &v, sizeof(v)); + } +} + +COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) +{ + struct ipc_namespace *ns; + int err; + struct msqid64_ds msqid64; + int version = compat_ipc_parse_version(&cmd); + + ns = current->nsproxy->ipc_ns; + + if (msqid < 0 || cmd < 0) + return -EINVAL; + + switch (cmd & (~IPC_64)) { + case IPC_INFO: + case MSG_INFO: { + struct msginfo msginfo; + err = msgctl_info(ns, msqid, cmd, &msginfo); + if (err < 0) + return err; + if (copy_to_user(uptr, &msginfo, sizeof(struct msginfo))) + err = -EFAULT; + return err; + } + case IPC_STAT: + case MSG_STAT: + err = msgctl_stat(ns, msqid, cmd, &msqid64); + if (err < 0) + return err; + if (copy_compat_msqid_to_user(uptr, &msqid64, version)) + err = -EFAULT; + return err; + case IPC_SET: + if (copy_compat_msqid_from_user(&msqid64, uptr, version)) + return -EFAULT; + /* fallthru */ + case IPC_RMID: + return msgctl_down(ns, msqid, cmd, &msqid64); + default: + return -EINVAL; + } +} +#endif + static int testmsg(struct msg_msg *msg, long type, int mode) { switch (mode) { @@ -627,7 +730,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, return 0; } -long do_msgsnd(int msqid, long mtype, void __user *mtext, +static long do_msgsnd(int msqid, long mtype, void __user *mtext, size_t msgsz, int msgflg) { struct msg_queue *msq; @@ -750,6 +853,25 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); } +#ifdef CONFIG_COMPAT + +struct compat_msgbuf { + compat_long_t mtype; + char mtext[1]; +}; + +COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, + compat_ssize_t, msgsz, int, msgflg) +{ + struct compat_msgbuf __user *up = compat_ptr(msgp); + compat_long_t mtype; + + if (get_user(mtype, &up->mtype)) + return -EFAULT; + return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg); +} +#endif + static inline int convert_mode(long *msgtyp, int msgflg) { if (msgflg & MSG_COPY) @@ -846,7 +968,7 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode) return found ?: ERR_PTR(-EAGAIN); } -long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, +static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, long (*msg_handler)(void __user *, struct msg_msg *, size_t)) { int mode; @@ -1010,8 +1132,30 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); } +#ifdef CONFIG_COMPAT +static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) +{ + struct compat_msgbuf __user *msgp = dest; + size_t msgsz; + + if (put_user(msg->m_type, &msgp->mtype)) + return -EFAULT; + + msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz; + if (store_msg(msgp->mtext, msg, msgsz)) + return -EFAULT; + return msgsz; +} + +COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, + compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg) +{ + return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, + msgflg, compat_do_msg_fill); +} +#endif -void msg_init_ns(struct ipc_namespace *ns) +int msg_init_ns(struct ipc_namespace *ns) { ns->msg_ctlmax = MSGMAX; ns->msg_ctlmnb = MSGMNB; @@ -1019,7 +1163,7 @@ void msg_init_ns(struct ipc_namespace *ns) atomic_set(&ns->msg_bytes, 0); atomic_set(&ns->msg_hdrs, 0); - ipc_init_ids(&ns->ids[IPC_MSG_IDS]); + return ipc_init_ids(&ns->ids[IPC_MSG_IDS]); } #ifdef CONFIG_IPC_NS @@ -1027,6 +1171,7 @@ void msg_exit_ns(struct ipc_namespace *ns) { free_ipcs(ns, &msg_ids(ns), freeque); idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr); + rhashtable_destroy(&ns->ids[IPC_MSG_IDS].key_ht); } #endif @@ -1034,10 +1179,11 @@ void msg_exit_ns(struct ipc_namespace *ns) static int sysvipc_msg_proc_show(struct seq_file *s, void *it) { struct user_namespace *user_ns = seq_user_ns(s); - struct msg_queue *msq = it; + struct kern_ipc_perm *ipcp = it; + struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); seq_printf(s, - "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", + "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10llu %10llu %10llu\n", msq->q_perm.key, msq->q_perm.id, msq->q_perm.mode, @@ -1057,11 +1203,12 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) } #endif -void __init msg_init(void) +int __init msg_init(void) { - msg_init_ns(&init_ipc_ns); + const int err = msg_init_ns(&init_ipc_ns); ipc_init_proc_interface("sysvipc/msg", " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", IPC_MSG_IDS, sysvipc_msg_proc_show); + return err; } diff --git a/ipc/msgutil.c b/ipc/msgutil.c index bf74eaa5c39f208ea5f1ee41db38e57349512e7d..84598025a6ade1faaf412d3ae67e5c2bda32e294 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -29,7 +29,7 @@ DEFINE_SPINLOCK(mq_lock); * and not CONFIG_IPC_NS. */ struct ipc_namespace init_ipc_ns = { - .count = ATOMIC_INIT(1), + .count = REFCOUNT_INIT(1), .user_ns = &init_user_ns, .ns.inum = PROC_IPC_INIT_INO, #ifdef CONFIG_IPC_NS diff --git a/ipc/namespace.c b/ipc/namespace.c index b4d80f9f7246732e7ca749db7a1f2e33e105531a..fc850c526698428fad7e7538e3ba673486553358 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -50,20 +50,32 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, goto fail_free; ns->ns.ops = &ipcns_operations; - atomic_set(&ns->count, 1); + refcount_set(&ns->count, 1); ns->user_ns = get_user_ns(user_ns); ns->ucounts = ucounts; - err = mq_init_ns(ns); + err = sem_init_ns(ns); if (err) goto fail_put; + err = msg_init_ns(ns); + if (err) + goto fail_destroy_sem; + err = shm_init_ns(ns); + if (err) + goto fail_destroy_msg; - sem_init_ns(ns); - msg_init_ns(ns); - shm_init_ns(ns); + err = mq_init_ns(ns); + if (err) + goto fail_destroy_shm; return ns; +fail_destroy_shm: + shm_exit_ns(ns); +fail_destroy_msg: + msg_exit_ns(ns); +fail_destroy_sem: + sem_exit_ns(ns); fail_put: put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); @@ -144,7 +156,7 @@ static void free_ipc_ns(struct ipc_namespace *ns) */ void put_ipc_ns(struct ipc_namespace *ns) { - if (atomic_dec_and_lock(&ns->count, &mq_lock)) { + if (refcount_dec_and_lock(&ns->count, &mq_lock)) { mq_clear_sbinfo(ns); spin_unlock(&mq_lock); mq_put_mnt(ns); diff --git a/ipc/sem.c b/ipc/sem.c index 9e70cd7a17da7e74e915ce7f4061aa99aea66b89..f7385bce5fd3bd00a9d3a42b7b61c7e96f5184f3 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -122,7 +122,7 @@ struct sem_undo { * that may be shared among all a CLONE_SYSVSEM task group. */ struct sem_undo_list { - atomic_t refcnt; + refcount_t refcnt; spinlock_t lock; struct list_head list_proc; }; @@ -130,8 +130,6 @@ struct sem_undo_list { #define sem_ids(ns) ((ns)->ids[IPC_SEM_IDS]) -#define sem_checkid(sma, semid) ipc_checkid(&sma->sem_perm, semid) - static int newary(struct ipc_namespace *, struct ipc_params *); static void freeary(struct ipc_namespace *, struct kern_ipc_perm *); #ifdef CONFIG_PROC_FS @@ -185,14 +183,14 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it); #define sc_semopm sem_ctls[2] #define sc_semmni sem_ctls[3] -void sem_init_ns(struct ipc_namespace *ns) +int sem_init_ns(struct ipc_namespace *ns) { ns->sc_semmsl = SEMMSL; ns->sc_semmns = SEMMNS; ns->sc_semopm = SEMOPM; ns->sc_semmni = SEMMNI; ns->used_sems = 0; - ipc_init_ids(&ns->ids[IPC_SEM_IDS]); + return ipc_init_ids(&ns->ids[IPC_SEM_IDS]); } #ifdef CONFIG_IPC_NS @@ -200,15 +198,18 @@ void sem_exit_ns(struct ipc_namespace *ns) { free_ipcs(ns, &sem_ids(ns), freeary); idr_destroy(&ns->ids[IPC_SEM_IDS].ipcs_idr); + rhashtable_destroy(&ns->ids[IPC_SEM_IDS].key_ht); } #endif -void __init sem_init(void) +int __init sem_init(void) { - sem_init_ns(&init_ipc_ns); + const int err = sem_init_ns(&init_ipc_ns); + ipc_init_proc_interface("sysvipc/sem", " key semid perms nsems uid gid cuid cgid otime ctime\n", IPC_SEM_IDS, sysvipc_sem_proc_show); + return err; } /** @@ -511,7 +512,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) INIT_LIST_HEAD(&sma->pending_const); INIT_LIST_HEAD(&sma->list_id); sma->sem_nsems = nsems; - sma->sem_ctime = get_seconds(); + sma->sem_ctime = ktime_get_real_seconds(); retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); if (retval < 0) { @@ -1162,14 +1163,14 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, } } -static time_t get_semotime(struct sem_array *sma) +static time64_t get_semotime(struct sem_array *sma) { int i; - time_t res; + time64_t res; res = sma->sems[0].sem_otime; for (i = 1; i < sma->sem_nsems; i++) { - time_t to = sma->sems[i].sem_otime; + time64_t to = sma->sems[i].sem_otime; if (to > res) res = to; @@ -1177,112 +1178,95 @@ static time_t get_semotime(struct sem_array *sma) return res; } -static int semctl_nolock(struct ipc_namespace *ns, int semid, - int cmd, int version, void __user *p) +static int semctl_stat(struct ipc_namespace *ns, int semid, + int cmd, struct semid64_ds *semid64) { - int err; struct sem_array *sma; + int id = 0; + int err; - switch (cmd) { - case IPC_INFO: - case SEM_INFO: - { - struct seminfo seminfo; - int max_id; - - err = security_sem_semctl(NULL, cmd); - if (err) - return err; + memset(semid64, 0, sizeof(*semid64)); - memset(&seminfo, 0, sizeof(seminfo)); - seminfo.semmni = ns->sc_semmni; - seminfo.semmns = ns->sc_semmns; - seminfo.semmsl = ns->sc_semmsl; - seminfo.semopm = ns->sc_semopm; - seminfo.semvmx = SEMVMX; - seminfo.semmnu = SEMMNU; - seminfo.semmap = SEMMAP; - seminfo.semume = SEMUME; - down_read(&sem_ids(ns).rwsem); - if (cmd == SEM_INFO) { - seminfo.semusz = sem_ids(ns).in_use; - seminfo.semaem = ns->used_sems; - } else { - seminfo.semusz = SEMUSZ; - seminfo.semaem = SEMAEM; + rcu_read_lock(); + if (cmd == SEM_STAT) { + sma = sem_obtain_object(ns, semid); + if (IS_ERR(sma)) { + err = PTR_ERR(sma); + goto out_unlock; + } + id = sma->sem_perm.id; + } else { + sma = sem_obtain_object_check(ns, semid); + if (IS_ERR(sma)) { + err = PTR_ERR(sma); + goto out_unlock; } - max_id = ipc_get_maxid(&sem_ids(ns)); - up_read(&sem_ids(ns).rwsem); - if (copy_to_user(p, &seminfo, sizeof(struct seminfo))) - return -EFAULT; - return (max_id < 0) ? 0 : max_id; } - case IPC_STAT: - case SEM_STAT: - { - struct semid64_ds tbuf; - int id = 0; - - memset(&tbuf, 0, sizeof(tbuf)); - rcu_read_lock(); - if (cmd == SEM_STAT) { - sma = sem_obtain_object(ns, semid); - if (IS_ERR(sma)) { - err = PTR_ERR(sma); - goto out_unlock; - } - id = sma->sem_perm.id; - } else { - sma = sem_obtain_object_check(ns, semid); - if (IS_ERR(sma)) { - err = PTR_ERR(sma); - goto out_unlock; - } - } + err = -EACCES; + if (ipcperms(ns, &sma->sem_perm, S_IRUGO)) + goto out_unlock; - err = -EACCES; - if (ipcperms(ns, &sma->sem_perm, S_IRUGO)) - goto out_unlock; + err = security_sem_semctl(sma, cmd); + if (err) + goto out_unlock; - err = security_sem_semctl(sma, cmd); - if (err) - goto out_unlock; + kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm); + semid64->sem_otime = get_semotime(sma); + semid64->sem_ctime = sma->sem_ctime; + semid64->sem_nsems = sma->sem_nsems; + rcu_read_unlock(); + return id; - kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); - tbuf.sem_otime = get_semotime(sma); - tbuf.sem_ctime = sma->sem_ctime; - tbuf.sem_nsems = sma->sem_nsems; - rcu_read_unlock(); - if (copy_semid_to_user(p, &tbuf, version)) - return -EFAULT; - return id; - } - default: - return -EINVAL; - } out_unlock: rcu_read_unlock(); return err; } +static int semctl_info(struct ipc_namespace *ns, int semid, + int cmd, void __user *p) +{ + struct seminfo seminfo; + int max_id; + int err; + + err = security_sem_semctl(NULL, cmd); + if (err) + return err; + + memset(&seminfo, 0, sizeof(seminfo)); + seminfo.semmni = ns->sc_semmni; + seminfo.semmns = ns->sc_semmns; + seminfo.semmsl = ns->sc_semmsl; + seminfo.semopm = ns->sc_semopm; + seminfo.semvmx = SEMVMX; + seminfo.semmnu = SEMMNU; + seminfo.semmap = SEMMAP; + seminfo.semume = SEMUME; + down_read(&sem_ids(ns).rwsem); + if (cmd == SEM_INFO) { + seminfo.semusz = sem_ids(ns).in_use; + seminfo.semaem = ns->used_sems; + } else { + seminfo.semusz = SEMUSZ; + seminfo.semaem = SEMAEM; + } + max_id = ipc_get_maxid(&sem_ids(ns)); + up_read(&sem_ids(ns).rwsem); + if (copy_to_user(p, &seminfo, sizeof(struct seminfo))) + return -EFAULT; + return (max_id < 0) ? 0 : max_id; +} + static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum, - unsigned long arg) + int val) { struct sem_undo *un; struct sem_array *sma; struct sem *curr; - int err, val; + int err; DEFINE_WAKE_Q(wake_q); -#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN) - /* big-endian 64bit */ - val = arg >> 32; -#else - /* 32bit or little-endian 64bit */ - val = arg; -#endif - if (val > SEMVMX || val < 0) return -ERANGE; @@ -1326,7 +1310,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum, curr->semval = val; curr->sempid = task_tgid_vnr(current); - sma->sem_ctime = get_seconds(); + sma->sem_ctime = ktime_get_real_seconds(); /* maybe some queued-up processes were waiting for this */ do_smart_update(sma, NULL, 0, 0, &wake_q); sem_unlock(sma, -1); @@ -1454,7 +1438,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, for (i = 0; i < nsems; i++) un->semadj[i] = 0; } - sma->sem_ctime = get_seconds(); + sma->sem_ctime = ktime_get_real_seconds(); /* maybe some queued-up processes were waiting for this */ do_smart_update(sma, NULL, 0, 0, &wake_q); err = 0; @@ -1531,23 +1515,17 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version) * NOTE: no locks must be held, the rwsem is taken inside this function. */ static int semctl_down(struct ipc_namespace *ns, int semid, - int cmd, int version, void __user *p) + int cmd, struct semid64_ds *semid64) { struct sem_array *sma; int err; - struct semid64_ds semid64; struct kern_ipc_perm *ipcp; - if (cmd == IPC_SET) { - if (copy_semid_from_user(&semid64, p, version)) - return -EFAULT; - } - down_write(&sem_ids(ns).rwsem); rcu_read_lock(); ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd, - &semid64.sem_perm, 0); + &semid64->sem_perm, 0); if (IS_ERR(ipcp)) { err = PTR_ERR(ipcp); goto out_unlock1; @@ -1567,10 +1545,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid, goto out_up; case IPC_SET: sem_lock(sma, NULL, -1); - err = ipc_update_perm(&semid64.sem_perm, ipcp); + err = ipc_update_perm(&semid64->sem_perm, ipcp); if (err) goto out_unlock0; - sma->sem_ctime = get_seconds(); + sma->sem_ctime = ktime_get_real_seconds(); break; default: err = -EINVAL; @@ -1591,6 +1569,8 @@ SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg) int version; struct ipc_namespace *ns; void __user *p = (void __user *)arg; + struct semid64_ds semid64; + int err; if (semid < 0) return -EINVAL; @@ -1601,25 +1581,136 @@ SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg) switch (cmd) { case IPC_INFO: case SEM_INFO: + return semctl_info(ns, semid, cmd, p); case IPC_STAT: case SEM_STAT: - return semctl_nolock(ns, semid, cmd, version, p); + err = semctl_stat(ns, semid, cmd, &semid64); + if (err < 0) + return err; + if (copy_semid_to_user(p, &semid64, version)) + err = -EFAULT; + return err; case GETALL: case GETVAL: case GETPID: case GETNCNT: case GETZCNT: + case SETALL: + return semctl_main(ns, semid, semnum, cmd, p); + case SETVAL: { + int val; +#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN) + /* big-endian 64bit */ + val = arg >> 32; +#else + /* 32bit or little-endian 64bit */ + val = arg; +#endif + return semctl_setval(ns, semid, semnum, val); + } + case IPC_SET: + if (copy_semid_from_user(&semid64, p, version)) + return -EFAULT; + case IPC_RMID: + return semctl_down(ns, semid, cmd, &semid64); + default: + return -EINVAL; + } +} + +#ifdef CONFIG_COMPAT + +struct compat_semid_ds { + struct compat_ipc_perm sem_perm; + compat_time_t sem_otime; + compat_time_t sem_ctime; + compat_uptr_t sem_base; + compat_uptr_t sem_pending; + compat_uptr_t sem_pending_last; + compat_uptr_t undo; + unsigned short sem_nsems; +}; + +static int copy_compat_semid_from_user(struct semid64_ds *out, void __user *buf, + int version) +{ + memset(out, 0, sizeof(*out)); + if (version == IPC_64) { + struct compat_semid64_ds *p = buf; + return get_compat_ipc64_perm(&out->sem_perm, &p->sem_perm); + } else { + struct compat_semid_ds *p = buf; + return get_compat_ipc_perm(&out->sem_perm, &p->sem_perm); + } +} + +static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in, + int version) +{ + if (version == IPC_64) { + struct compat_semid64_ds v; + memset(&v, 0, sizeof(v)); + to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm); + v.sem_otime = in->sem_otime; + v.sem_ctime = in->sem_ctime; + v.sem_nsems = in->sem_nsems; + return copy_to_user(buf, &v, sizeof(v)); + } else { + struct compat_semid_ds v; + memset(&v, 0, sizeof(v)); + to_compat_ipc_perm(&v.sem_perm, &in->sem_perm); + v.sem_otime = in->sem_otime; + v.sem_ctime = in->sem_ctime; + v.sem_nsems = in->sem_nsems; + return copy_to_user(buf, &v, sizeof(v)); + } +} + +COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) +{ + void __user *p = compat_ptr(arg); + struct ipc_namespace *ns; + struct semid64_ds semid64; + int version = compat_ipc_parse_version(&cmd); + int err; + + ns = current->nsproxy->ipc_ns; + + if (semid < 0) + return -EINVAL; + + switch (cmd & (~IPC_64)) { + case IPC_INFO: + case SEM_INFO: + return semctl_info(ns, semid, cmd, p); + case IPC_STAT: + case SEM_STAT: + err = semctl_stat(ns, semid, cmd, &semid64); + if (err < 0) + return err; + if (copy_compat_semid_to_user(p, &semid64, version)) + err = -EFAULT; + return err; + case GETVAL: + case GETPID: + case GETNCNT: + case GETZCNT: + case GETALL: case SETALL: return semctl_main(ns, semid, semnum, cmd, p); case SETVAL: return semctl_setval(ns, semid, semnum, arg); - case IPC_RMID: case IPC_SET: - return semctl_down(ns, semid, cmd, version, p); + if (copy_compat_semid_from_user(&semid64, p, version)) + return -EFAULT; + /* fallthru */ + case IPC_RMID: + return semctl_down(ns, semid, cmd, &semid64); default: return -EINVAL; } } +#endif /* If the task doesn't already have a undo_list, then allocate one * here. We guarantee there is only one thread using this undo list, @@ -1642,7 +1733,7 @@ static inline int get_undo_list(struct sem_undo_list **undo_listp) if (undo_list == NULL) return -ENOMEM; spin_lock_init(&undo_list->lock); - atomic_set(&undo_list->refcnt, 1); + refcount_set(&undo_list->refcnt, 1); INIT_LIST_HEAD(&undo_list->list_proc); current->sysvsem.undo_list = undo_list; @@ -1765,8 +1856,8 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid) return un; } -SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, - unsigned, nsops, const struct timespec __user *, timeout) +static long do_semtimedop(int semid, struct sembuf __user *tsops, + unsigned nsops, const struct timespec64 *timeout) { int error = -EINVAL; struct sem_array *sma; @@ -1786,7 +1877,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, if (nsops > ns->sc_semopm) return -E2BIG; if (nsops > SEMOPM_FAST) { - sops = kmalloc(sizeof(*sops)*nsops, GFP_KERNEL); + sops = kvmalloc(sizeof(*sops)*nsops, GFP_KERNEL); if (sops == NULL) return -ENOMEM; } @@ -1797,17 +1888,12 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, } if (timeout) { - struct timespec _timeout; - if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) { - error = -EFAULT; - goto out_free; - } - if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 || - _timeout.tv_nsec >= 1000000000L) { + if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 || + timeout->tv_nsec >= 1000000000L) { error = -EINVAL; goto out_free; } - jiffies_left = timespec_to_jiffies(&_timeout); + jiffies_left = timespec64_to_jiffies(timeout); } max = 0; @@ -2018,14 +2104,41 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, rcu_read_unlock(); out_free: if (sops != fast_sops) - kfree(sops); + kvfree(sops); return error; } +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, + unsigned, nsops, const struct timespec __user *, timeout) +{ + if (timeout) { + struct timespec64 ts; + if (get_timespec64(&ts, timeout)) + return -EFAULT; + return do_semtimedop(semid, tsops, nsops, &ts); + } + return do_semtimedop(semid, tsops, nsops, NULL); +} + +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems, + unsigned, nsops, + const struct compat_timespec __user *, timeout) +{ + if (timeout) { + struct timespec64 ts; + if (compat_get_timespec64(&ts, timeout)) + return -EFAULT; + return do_semtimedop(semid, tsems, nsops, &ts); + } + return do_semtimedop(semid, tsems, nsops, NULL); +} +#endif + SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, unsigned, nsops) { - return sys_semtimedop(semid, tsops, nsops, NULL); + return do_semtimedop(semid, tsops, nsops, NULL); } /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between @@ -2041,7 +2154,7 @@ int copy_semundo(unsigned long clone_flags, struct task_struct *tsk) error = get_undo_list(&undo_list); if (error) return error; - atomic_inc(&undo_list->refcnt); + refcount_inc(&undo_list->refcnt); tsk->sysvsem.undo_list = undo_list; } else tsk->sysvsem.undo_list = NULL; @@ -2070,7 +2183,7 @@ void exit_sem(struct task_struct *tsk) return; tsk->sysvsem.undo_list = NULL; - if (!atomic_dec_and_test(&ulp->refcnt)) + if (!refcount_dec_and_test(&ulp->refcnt)) return; for (;;) { @@ -2091,7 +2204,8 @@ void exit_sem(struct task_struct *tsk) * possibility where we exit while freeary() didn't * finish unlocking sem_undo_list. */ - spin_unlock_wait(&ulp->lock); + spin_lock(&ulp->lock); + spin_unlock(&ulp->lock); rcu_read_unlock(); break; } @@ -2179,8 +2293,9 @@ void exit_sem(struct task_struct *tsk) static int sysvipc_sem_proc_show(struct seq_file *s, void *it) { struct user_namespace *user_ns = seq_user_ns(s); - struct sem_array *sma = it; - time_t sem_otime; + struct kern_ipc_perm *ipcp = it; + struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm); + time64_t sem_otime; /* * The proc interface isn't aware of sem_lock(), it calls @@ -2193,7 +2308,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it) sem_otime = get_semotime(sma); seq_printf(s, - "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", + "%10d %10d %4o %10u %5u %5u %5u %5u %10llu %10llu\n", sma->sem_perm.key, sma->sem_perm.id, sma->sem_perm.mode, diff --git a/ipc/shm.c b/ipc/shm.c index 28a444861a8f489fa46edca81878eedf0f55da7a..badac463e2c8ea7a035c73acd385d4d58211e6ac 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -72,14 +72,14 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp); static int sysvipc_shm_proc_show(struct seq_file *s, void *it); #endif -void shm_init_ns(struct ipc_namespace *ns) +int shm_init_ns(struct ipc_namespace *ns) { ns->shm_ctlmax = SHMMAX; ns->shm_ctlall = SHMALL; ns->shm_ctlmni = SHMMNI; ns->shm_rmid_forced = 0; ns->shm_tot = 0; - ipc_init_ids(&shm_ids(ns)); + return ipc_init_ids(&shm_ids(ns)); } /* @@ -95,7 +95,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) if (shp->shm_nattch) { shp->shm_perm.mode |= SHM_DEST; /* Do not find it any more */ - shp->shm_perm.key = IPC_PRIVATE; + ipc_set_key_private(&shm_ids(ns), &shp->shm_perm); shm_unlock(shp); } else shm_destroy(ns, shp); @@ -106,13 +106,15 @@ void shm_exit_ns(struct ipc_namespace *ns) { free_ipcs(ns, &shm_ids(ns), do_shm_rmid); idr_destroy(&ns->ids[IPC_SHM_IDS].ipcs_idr); + rhashtable_destroy(&ns->ids[IPC_SHM_IDS].key_ht); } #endif static int __init ipc_ns_init(void) { - shm_init_ns(&init_ipc_ns); - return 0; + const int err = shm_init_ns(&init_ipc_ns); + WARN(err, "ipc: sysv shm_init_ns failed: %d\n", err); + return err; } pure_initcall(ipc_ns_init); @@ -200,7 +202,7 @@ static int __shm_open(struct vm_area_struct *vma) if (IS_ERR(shp)) return PTR_ERR(shp); - shp->shm_atim = get_seconds(); + shp->shm_atim = ktime_get_real_seconds(); shp->shm_lprid = task_tgid_vnr(current); shp->shm_nattch++; shm_unlock(shp); @@ -287,7 +289,7 @@ static void shm_close(struct vm_area_struct *vma) goto done; /* no-op */ shp->shm_lprid = task_tgid_vnr(current); - shp->shm_dtim = get_seconds(); + shp->shm_dtim = ktime_get_real_seconds(); shp->shm_nattch--; if (shm_may_destroy(ns, shp)) shm_destroy(ns, shp); @@ -592,7 +594,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) shp->shm_cprid = task_tgid_vnr(current); shp->shm_lprid = 0; shp->shm_atim = shp->shm_dtim = 0; - shp->shm_ctim = get_seconds(); + shp->shm_ctim = ktime_get_real_seconds(); shp->shm_segsz = size; shp->shm_nattch = 0; shp->shm_file = file; @@ -813,23 +815,17 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, * NOTE: no locks must be held, the rwsem is taken inside this function. */ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, - struct shmid_ds __user *buf, int version) + struct shmid64_ds *shmid64) { struct kern_ipc_perm *ipcp; - struct shmid64_ds shmid64; struct shmid_kernel *shp; int err; - if (cmd == IPC_SET) { - if (copy_shmid_from_user(&shmid64, buf, version)) - return -EFAULT; - } - down_write(&shm_ids(ns).rwsem); rcu_read_lock(); ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd, - &shmid64.shm_perm, 0); + &shmid64->shm_perm, 0); if (IS_ERR(ipcp)) { err = PTR_ERR(ipcp); goto out_unlock1; @@ -849,10 +845,10 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, goto out_up; case IPC_SET: ipc_lock_object(&shp->shm_perm); - err = ipc_update_perm(&shmid64.shm_perm, ipcp); + err = ipc_update_perm(&shmid64->shm_perm, ipcp); if (err) goto out_unlock0; - shp->shm_ctim = get_seconds(); + shp->shm_ctim = ktime_get_real_seconds(); break; default: err = -EINVAL; @@ -868,125 +864,175 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, return err; } -static int shmctl_nolock(struct ipc_namespace *ns, int shmid, - int cmd, int version, void __user *buf) +static int shmctl_ipc_info(struct ipc_namespace *ns, + struct shminfo64 *shminfo) { - int err; - struct shmid_kernel *shp; - - /* preliminary security checks for *_INFO */ - if (cmd == IPC_INFO || cmd == SHM_INFO) { - err = security_shm_shmctl(NULL, cmd); - if (err) - return err; - } - - switch (cmd) { - case IPC_INFO: - { - struct shminfo64 shminfo; - - memset(&shminfo, 0, sizeof(shminfo)); - shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; - shminfo.shmmax = ns->shm_ctlmax; - shminfo.shmall = ns->shm_ctlall; - - shminfo.shmmin = SHMMIN; - if (copy_shminfo_to_user(buf, &shminfo, version)) - return -EFAULT; - + int err = security_shm_shmctl(NULL, IPC_INFO); + if (!err) { + memset(shminfo, 0, sizeof(*shminfo)); + shminfo->shmmni = shminfo->shmseg = ns->shm_ctlmni; + shminfo->shmmax = ns->shm_ctlmax; + shminfo->shmall = ns->shm_ctlall; + shminfo->shmmin = SHMMIN; down_read(&shm_ids(ns).rwsem); err = ipc_get_maxid(&shm_ids(ns)); up_read(&shm_ids(ns).rwsem); - if (err < 0) err = 0; - goto out; } - case SHM_INFO: - { - struct shm_info shm_info; + return err; +} - memset(&shm_info, 0, sizeof(shm_info)); +static int shmctl_shm_info(struct ipc_namespace *ns, + struct shm_info *shm_info) +{ + int err = security_shm_shmctl(NULL, SHM_INFO); + if (!err) { + memset(shm_info, 0, sizeof(*shm_info)); down_read(&shm_ids(ns).rwsem); - shm_info.used_ids = shm_ids(ns).in_use; - shm_get_stat(ns, &shm_info.shm_rss, &shm_info.shm_swp); - shm_info.shm_tot = ns->shm_tot; - shm_info.swap_attempts = 0; - shm_info.swap_successes = 0; + shm_info->used_ids = shm_ids(ns).in_use; + shm_get_stat(ns, &shm_info->shm_rss, &shm_info->shm_swp); + shm_info->shm_tot = ns->shm_tot; + shm_info->swap_attempts = 0; + shm_info->swap_successes = 0; err = ipc_get_maxid(&shm_ids(ns)); up_read(&shm_ids(ns).rwsem); - if (copy_to_user(buf, &shm_info, sizeof(shm_info))) { - err = -EFAULT; - goto out; + if (err < 0) + err = 0; + } + return err; +} + +static int shmctl_stat(struct ipc_namespace *ns, int shmid, + int cmd, struct shmid64_ds *tbuf) +{ + struct shmid_kernel *shp; + int result; + int err; + + rcu_read_lock(); + if (cmd == SHM_STAT) { + shp = shm_obtain_object(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); + goto out_unlock; + } + result = shp->shm_perm.id; + } else { + shp = shm_obtain_object_check(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); + goto out_unlock; } + result = 0; + } - err = err < 0 ? 0 : err; - goto out; + err = -EACCES; + if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) + goto out_unlock; + + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock; + + memset(tbuf, 0, sizeof(*tbuf)); + kernel_to_ipc64_perm(&shp->shm_perm, &tbuf->shm_perm); + tbuf->shm_segsz = shp->shm_segsz; + tbuf->shm_atime = shp->shm_atim; + tbuf->shm_dtime = shp->shm_dtim; + tbuf->shm_ctime = shp->shm_ctim; + tbuf->shm_cpid = shp->shm_cprid; + tbuf->shm_lpid = shp->shm_lprid; + tbuf->shm_nattch = shp->shm_nattch; + rcu_read_unlock(); + return result; + +out_unlock: + rcu_read_unlock(); + return err; +} + +static int shmctl_do_lock(struct ipc_namespace *ns, int shmid, int cmd) +{ + struct shmid_kernel *shp; + struct file *shm_file; + int err; + + rcu_read_lock(); + shp = shm_obtain_object_check(ns, shmid); + if (IS_ERR(shp)) { + err = PTR_ERR(shp); + goto out_unlock1; } - case SHM_STAT: - case IPC_STAT: - { - struct shmid64_ds tbuf; - int result; - - rcu_read_lock(); - if (cmd == SHM_STAT) { - shp = shm_obtain_object(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); - goto out_unlock; - } - result = shp->shm_perm.id; - } else { - shp = shm_obtain_object_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); - goto out_unlock; - } - result = 0; - } - err = -EACCES; - if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) - goto out_unlock; + audit_ipc_obj(&(shp->shm_perm)); + err = security_shm_shmctl(shp, cmd); + if (err) + goto out_unlock1; - err = security_shm_shmctl(shp, cmd); - if (err) - goto out_unlock; + ipc_lock_object(&shp->shm_perm); - memset(&tbuf, 0, sizeof(tbuf)); - kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); - tbuf.shm_segsz = shp->shm_segsz; - tbuf.shm_atime = shp->shm_atim; - tbuf.shm_dtime = shp->shm_dtim; - tbuf.shm_ctime = shp->shm_ctim; - tbuf.shm_cpid = shp->shm_cprid; - tbuf.shm_lpid = shp->shm_lprid; - tbuf.shm_nattch = shp->shm_nattch; - rcu_read_unlock(); - - if (copy_shmid_to_user(buf, &tbuf, version)) - err = -EFAULT; - else - err = result; - goto out; + /* check if shm_destroy() is tearing down shp */ + if (!ipc_valid_object(&shp->shm_perm)) { + err = -EIDRM; + goto out_unlock0; } - default: - return -EINVAL; + + if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { + kuid_t euid = current_euid(); + + if (!uid_eq(euid, shp->shm_perm.uid) && + !uid_eq(euid, shp->shm_perm.cuid)) { + err = -EPERM; + goto out_unlock0; + } + if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) { + err = -EPERM; + goto out_unlock0; + } } -out_unlock: + shm_file = shp->shm_file; + if (is_file_hugepages(shm_file)) + goto out_unlock0; + + if (cmd == SHM_LOCK) { + struct user_struct *user = current_user(); + + err = shmem_lock(shm_file, 1, user); + if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) { + shp->shm_perm.mode |= SHM_LOCKED; + shp->mlock_user = user; + } + goto out_unlock0; + } + + /* SHM_UNLOCK */ + if (!(shp->shm_perm.mode & SHM_LOCKED)) + goto out_unlock0; + shmem_lock(shm_file, 0, shp->mlock_user); + shp->shm_perm.mode &= ~SHM_LOCKED; + shp->mlock_user = NULL; + get_file(shm_file); + ipc_unlock_object(&shp->shm_perm); + rcu_read_unlock(); + shmem_unlock_mapping(shm_file->f_mapping); + + fput(shm_file); + return err; + +out_unlock0: + ipc_unlock_object(&shp->shm_perm); +out_unlock1: rcu_read_unlock(); -out: return err; } SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) { - struct shmid_kernel *shp; int err, version; struct ipc_namespace *ns; + struct shmid64_ds sem64; if (cmd < 0 || shmid < 0) return -EINVAL; @@ -995,92 +1041,222 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) ns = current->nsproxy->ipc_ns; switch (cmd) { - case IPC_INFO: - case SHM_INFO: + case IPC_INFO: { + struct shminfo64 shminfo; + err = shmctl_ipc_info(ns, &shminfo); + if (err < 0) + return err; + if (copy_shminfo_to_user(buf, &shminfo, version)) + err = -EFAULT; + return err; + } + case SHM_INFO: { + struct shm_info shm_info; + err = shmctl_shm_info(ns, &shm_info); + if (err < 0) + return err; + if (copy_to_user(buf, &shm_info, sizeof(shm_info))) + err = -EFAULT; + return err; + } case SHM_STAT: - case IPC_STAT: - return shmctl_nolock(ns, shmid, cmd, version, buf); - case IPC_RMID: + case IPC_STAT: { + err = shmctl_stat(ns, shmid, cmd, &sem64); + if (err < 0) + return err; + if (copy_shmid_to_user(buf, &sem64, version)) + err = -EFAULT; + return err; + } case IPC_SET: - return shmctl_down(ns, shmid, cmd, buf, version); + if (copy_shmid_from_user(&sem64, buf, version)) + return -EFAULT; + /* fallthru */ + case IPC_RMID: + return shmctl_down(ns, shmid, cmd, &sem64); case SHM_LOCK: case SHM_UNLOCK: - { - struct file *shm_file; + return shmctl_do_lock(ns, shmid, cmd); + default: + return -EINVAL; + } +} - rcu_read_lock(); - shp = shm_obtain_object_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); - goto out_unlock1; - } +#ifdef CONFIG_COMPAT + +struct compat_shmid_ds { + struct compat_ipc_perm shm_perm; + int shm_segsz; + compat_time_t shm_atime; + compat_time_t shm_dtime; + compat_time_t shm_ctime; + compat_ipc_pid_t shm_cpid; + compat_ipc_pid_t shm_lpid; + unsigned short shm_nattch; + unsigned short shm_unused; + compat_uptr_t shm_unused2; + compat_uptr_t shm_unused3; +}; - audit_ipc_obj(&(shp->shm_perm)); - err = security_shm_shmctl(shp, cmd); - if (err) - goto out_unlock1; +struct compat_shminfo64 { + compat_ulong_t shmmax; + compat_ulong_t shmmin; + compat_ulong_t shmmni; + compat_ulong_t shmseg; + compat_ulong_t shmall; + compat_ulong_t __unused1; + compat_ulong_t __unused2; + compat_ulong_t __unused3; + compat_ulong_t __unused4; +}; - ipc_lock_object(&shp->shm_perm); +struct compat_shm_info { + compat_int_t used_ids; + compat_ulong_t shm_tot, shm_rss, shm_swp; + compat_ulong_t swap_attempts, swap_successes; +}; - /* check if shm_destroy() is tearing down shp */ - if (!ipc_valid_object(&shp->shm_perm)) { - err = -EIDRM; - goto out_unlock0; - } +static int copy_compat_shminfo_to_user(void __user *buf, struct shminfo64 *in, + int version) +{ + if (in->shmmax > INT_MAX) + in->shmmax = INT_MAX; + if (version == IPC_64) { + struct compat_shminfo64 info; + memset(&info, 0, sizeof(info)); + info.shmmax = in->shmmax; + info.shmmin = in->shmmin; + info.shmmni = in->shmmni; + info.shmseg = in->shmseg; + info.shmall = in->shmall; + return copy_to_user(buf, &info, sizeof(info)); + } else { + struct shminfo info; + memset(&info, 0, sizeof(info)); + info.shmmax = in->shmmax; + info.shmmin = in->shmmin; + info.shmmni = in->shmmni; + info.shmseg = in->shmseg; + info.shmall = in->shmall; + return copy_to_user(buf, &info, sizeof(info)); + } +} - if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { - kuid_t euid = current_euid(); - - if (!uid_eq(euid, shp->shm_perm.uid) && - !uid_eq(euid, shp->shm_perm.cuid)) { - err = -EPERM; - goto out_unlock0; - } - if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) { - err = -EPERM; - goto out_unlock0; - } - } +static int put_compat_shm_info(struct shm_info *ip, + struct compat_shm_info __user *uip) +{ + struct compat_shm_info info; + + memset(&info, 0, sizeof(info)); + info.used_ids = ip->used_ids; + info.shm_tot = ip->shm_tot; + info.shm_rss = ip->shm_rss; + info.shm_swp = ip->shm_swp; + info.swap_attempts = ip->swap_attempts; + info.swap_successes = ip->swap_successes; + return copy_to_user(uip, &info, sizeof(info)); +} - shm_file = shp->shm_file; - if (is_file_hugepages(shm_file)) - goto out_unlock0; +static int copy_compat_shmid_to_user(void __user *buf, struct shmid64_ds *in, + int version) +{ + if (version == IPC_64) { + struct compat_shmid64_ds v; + memset(&v, 0, sizeof(v)); + to_compat_ipc64_perm(&v.shm_perm, &in->shm_perm); + v.shm_atime = in->shm_atime; + v.shm_dtime = in->shm_dtime; + v.shm_ctime = in->shm_ctime; + v.shm_segsz = in->shm_segsz; + v.shm_nattch = in->shm_nattch; + v.shm_cpid = in->shm_cpid; + v.shm_lpid = in->shm_lpid; + return copy_to_user(buf, &v, sizeof(v)); + } else { + struct compat_shmid_ds v; + memset(&v, 0, sizeof(v)); + to_compat_ipc_perm(&v.shm_perm, &in->shm_perm); + v.shm_perm.key = in->shm_perm.key; + v.shm_atime = in->shm_atime; + v.shm_dtime = in->shm_dtime; + v.shm_ctime = in->shm_ctime; + v.shm_segsz = in->shm_segsz; + v.shm_nattch = in->shm_nattch; + v.shm_cpid = in->shm_cpid; + v.shm_lpid = in->shm_lpid; + return copy_to_user(buf, &v, sizeof(v)); + } +} - if (cmd == SHM_LOCK) { - struct user_struct *user = current_user(); +static int copy_compat_shmid_from_user(struct shmid64_ds *out, void __user *buf, + int version) +{ + memset(out, 0, sizeof(*out)); + if (version == IPC_64) { + struct compat_shmid64_ds *p = buf; + return get_compat_ipc64_perm(&out->shm_perm, &p->shm_perm); + } else { + struct compat_shmid_ds *p = buf; + return get_compat_ipc_perm(&out->shm_perm, &p->shm_perm); + } +} - err = shmem_lock(shm_file, 1, user); - if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) { - shp->shm_perm.mode |= SHM_LOCKED; - shp->mlock_user = user; - } - goto out_unlock0; - } +COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr) +{ + struct ipc_namespace *ns; + struct shmid64_ds sem64; + int version = compat_ipc_parse_version(&cmd); + int err; - /* SHM_UNLOCK */ - if (!(shp->shm_perm.mode & SHM_LOCKED)) - goto out_unlock0; - shmem_lock(shm_file, 0, shp->mlock_user); - shp->shm_perm.mode &= ~SHM_LOCKED; - shp->mlock_user = NULL; - get_file(shm_file); - ipc_unlock_object(&shp->shm_perm); - rcu_read_unlock(); - shmem_unlock_mapping(shm_file->f_mapping); + ns = current->nsproxy->ipc_ns; - fput(shm_file); + if (cmd < 0 || shmid < 0) + return -EINVAL; + + switch (cmd) { + case IPC_INFO: { + struct shminfo64 shminfo; + err = shmctl_ipc_info(ns, &shminfo); + if (err < 0) + return err; + if (copy_compat_shminfo_to_user(uptr, &shminfo, version)) + err = -EFAULT; + return err; + } + case SHM_INFO: { + struct shm_info shm_info; + err = shmctl_shm_info(ns, &shm_info); + if (err < 0) + return err; + if (put_compat_shm_info(&shm_info, uptr)) + err = -EFAULT; return err; } + case IPC_STAT: + case SHM_STAT: + err = shmctl_stat(ns, shmid, cmd, &sem64); + if (err < 0) + return err; + if (copy_compat_shmid_to_user(uptr, &sem64, version)) + err = -EFAULT; + return err; + + case IPC_SET: + if (copy_compat_shmid_from_user(&sem64, uptr, version)) + return -EFAULT; + /* fallthru */ + case IPC_RMID: + return shmctl_down(ns, shmid, cmd, &sem64); + case SHM_LOCK: + case SHM_UNLOCK: + return shmctl_do_lock(ns, shmid, cmd); + break; default: return -EINVAL; } - -out_unlock0: - ipc_unlock_object(&shp->shm_perm); -out_unlock1: - rcu_read_unlock(); return err; } +#endif /* * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists. @@ -1265,6 +1441,25 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) return (long)ret; } +#ifdef CONFIG_COMPAT + +#ifndef COMPAT_SHMLBA +#define COMPAT_SHMLBA SHMLBA +#endif + +COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) +{ + unsigned long ret; + long err; + + err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA); + if (err) + return err; + force_successful_syscall_return(); + return (long)ret; +} +#endif + /* * detach and kill segment if marked destroyed. * The work is done in shm_close. @@ -1380,9 +1575,11 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) static int sysvipc_shm_proc_show(struct seq_file *s, void *it) { struct user_namespace *user_ns = seq_user_ns(s); - struct shmid_kernel *shp = it; + struct kern_ipc_perm *ipcp = it; + struct shmid_kernel *shp; unsigned long rss = 0, swp = 0; + shp = container_of(ipcp, struct shmid_kernel, shm_perm); shm_add_rss_swap(shp, &rss, &swp); #if BITS_PER_LONG <= 32 @@ -1393,7 +1590,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) seq_printf(s, "%10d %10d %4o " SIZE_SPEC " %5u %5u " - "%5lu %5u %5u %5u %5u %10lu %10lu %10lu " + "%5lu %5u %5u %5u %5u %10llu %10llu %10llu " SIZE_SPEC " " SIZE_SPEC "\n", shp->shm_perm.key, shp->shm_perm.id, diff --git a/ipc/syscall.c b/ipc/syscall.c index 52429489cde0070ab9398648ca326592e824a2a7..667022746ca56914e77fcb0b9a1c23ff4b02d3d6 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -5,12 +5,12 @@ * the individual syscalls instead. */ #include +#include #ifdef __ARCH_WANT_SYS_IPC #include #include #include -#include #include SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, @@ -97,3 +97,91 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, } } #endif + +#ifdef CONFIG_COMPAT +#include + +#ifndef COMPAT_SHMLBA +#define COMPAT_SHMLBA SHMLBA +#endif + +struct compat_ipc_kludge { + compat_uptr_t msgp; + compat_long_t msgtyp; +}; + +#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC +COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, + u32, third, compat_uptr_t, ptr, u32, fifth) +{ + int version; + u32 pad; + + version = call >> 16; /* hack for backward compatibility */ + call &= 0xffff; + + switch (call) { + case SEMOP: + /* struct sembuf is the same on 32 and 64bit :)) */ + return sys_semtimedop(first, compat_ptr(ptr), second, NULL); + case SEMTIMEDOP: + return compat_sys_semtimedop(first, compat_ptr(ptr), second, + compat_ptr(fifth)); + case SEMGET: + return sys_semget(first, second, third); + case SEMCTL: + if (!ptr) + return -EINVAL; + if (get_user(pad, (u32 __user *) compat_ptr(ptr))) + return -EFAULT; + return compat_sys_semctl(first, second, third, pad); + + case MSGSND: + return compat_sys_msgsnd(first, ptr, second, third); + + case MSGRCV: { + void __user *uptr = compat_ptr(ptr); + + if (first < 0 || second < 0) + return -EINVAL; + + if (!version) { + struct compat_ipc_kludge ipck; + if (!uptr) + return -EINVAL; + if (copy_from_user(&ipck, uptr, sizeof(ipck))) + return -EFAULT; + return compat_sys_msgrcv(first, ipck.msgp, second, + ipck.msgtyp, third); + } + return compat_sys_msgrcv(first, ptr, second, fifth, third); + } + case MSGGET: + return sys_msgget(first, second); + case MSGCTL: + return compat_sys_msgctl(first, second, compat_ptr(ptr)); + + case SHMAT: { + int err; + unsigned long raddr; + + if (version == 1) + return -EINVAL; + err = do_shmat(first, compat_ptr(ptr), second, &raddr, + COMPAT_SHMLBA); + if (err < 0) + return err; + return put_user(raddr, (compat_ulong_t *)compat_ptr(third)); + } + case SHMDT: + return sys_shmdt(compat_ptr(ptr)); + case SHMGET: + return sys_shmget(first, (unsigned)second, third); + case SHMCTL: + return compat_sys_shmctl(first, second, compat_ptr(ptr)); + } + + return -ENOSYS; +} +#endif +#endif diff --git a/ipc/util.c b/ipc/util.c index 1a2cb02467ab5f33f309a4542620cbec8d18361a..78755873cc5b9e2dfe28f85e44933c282aa7d91e 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -83,27 +83,46 @@ struct ipc_proc_iface { */ static int __init ipc_init(void) { - sem_init(); - msg_init(); + int err_sem, err_msg; + + err_sem = sem_init(); + WARN(err_sem, "ipc: sysv sem_init failed: %d\n", err_sem); + err_msg = msg_init(); + WARN(err_msg, "ipc: sysv msg_init failed: %d\n", err_msg); shm_init(); - return 0; + + return err_msg ? err_msg : err_sem; } device_initcall(ipc_init); +static const struct rhashtable_params ipc_kht_params = { + .head_offset = offsetof(struct kern_ipc_perm, khtnode), + .key_offset = offsetof(struct kern_ipc_perm, key), + .key_len = FIELD_SIZEOF(struct kern_ipc_perm, key), + .locks_mul = 1, + .automatic_shrinking = true, +}; + /** * ipc_init_ids - initialise ipc identifiers * @ids: ipc identifier set * * Set up the sequence range to use for the ipc identifier range (limited - * below IPCMNI) then initialise the ids idr. + * below IPCMNI) then initialise the keys hashtable and ids idr. */ -void ipc_init_ids(struct ipc_ids *ids) +int ipc_init_ids(struct ipc_ids *ids) { + int err; ids->in_use = 0; ids->seq = 0; ids->next_id = -1; init_rwsem(&ids->rwsem); + err = rhashtable_init(&ids->key_ht, &ipc_kht_params); + if (err) + return err; idr_init(&ids->ipcs_idr); + ids->tables_initialized = true; + return 0; } #ifdef CONFIG_PROC_FS @@ -147,28 +166,20 @@ void __init ipc_init_proc_interface(const char *path, const char *header, * Returns the locked pointer to the ipc structure if found or NULL * otherwise. If key is found ipc points to the owning ipc structure * - * Called with ipc_ids.rwsem held. + * Called with writer ipc_ids.rwsem held. */ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) { - struct kern_ipc_perm *ipc; - int next_id; - int total; - - for (total = 0, next_id = 0; total < ids->in_use; next_id++) { - ipc = idr_find(&ids->ipcs_idr, next_id); - - if (ipc == NULL) - continue; + struct kern_ipc_perm *ipcp = NULL; - if (ipc->key != key) { - total++; - continue; - } + if (likely(ids->tables_initialized)) + ipcp = rhashtable_lookup_fast(&ids->key_ht, &key, + ipc_kht_params); + if (ipcp) { rcu_read_lock(); - ipc_lock_object(ipc); - return ipc; + ipc_lock_object(ipcp); + return ipcp; } return NULL; @@ -221,18 +232,18 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) { kuid_t euid; kgid_t egid; - int id; + int id, err; int next_id = ids->next_id; if (size > IPCMNI) size = IPCMNI; - if (ids->in_use >= size) + if (!ids->tables_initialized || ids->in_use >= size) return -ENOSPC; idr_preload(GFP_KERNEL); - atomic_set(&new->refcount, 1); + refcount_set(&new->refcount, 1); spin_lock_init(&new->lock); new->deleted = false; rcu_read_lock(); @@ -246,6 +257,15 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, GFP_NOWAIT); idr_preload_end(); + + if (id >= 0 && new->key != IPC_PRIVATE) { + err = rhashtable_insert_fast(&ids->key_ht, &new->khtnode, + ipc_kht_params); + if (err < 0) { + idr_remove(&ids->ipcs_idr, id); + id = err; + } + } if (id < 0) { spin_unlock(&new->lock); rcu_read_unlock(); @@ -377,6 +397,20 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, return err; } +/** + * ipc_kht_remove - remove an ipc from the key hashtable + * @ids: ipc identifier set + * @ipcp: ipc perm structure containing the key to remove + * + * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held + * before this function is called, and remain locked on the exit. + */ +static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) +{ + if (ipcp->key != IPC_PRIVATE) + rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, + ipc_kht_params); +} /** * ipc_rmid - remove an ipc identifier @@ -391,19 +425,34 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) int lid = ipcid_to_idx(ipcp->id); idr_remove(&ids->ipcs_idr, lid); + ipc_kht_remove(ids, ipcp); ids->in_use--; ipcp->deleted = true; } +/** + * ipc_set_key_private - switch the key of an existing ipc to IPC_PRIVATE + * @ids: ipc identifier set + * @ipcp: ipc perm structure containing the key to modify + * + * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held + * before this function is called, and remain locked on the exit. + */ +void ipc_set_key_private(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) +{ + ipc_kht_remove(ids, ipcp); + ipcp->key = IPC_PRIVATE; +} + int ipc_rcu_getref(struct kern_ipc_perm *ptr) { - return atomic_inc_not_zero(&ptr->refcount); + return refcount_inc_not_zero(&ptr->refcount); } void ipc_rcu_putref(struct kern_ipc_perm *ptr, void (*func)(struct rcu_head *head)) { - if (!atomic_dec_and_test(&ptr->refcount)) + if (!refcount_dec_and_test(&ptr->refcount)) return; call_rcu(&ptr->rcu, func); @@ -485,7 +534,7 @@ void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out) } /** - * ipc_obtain_object + * ipc_obtain_object_idr * @ids: ipc identifier set * @id: ipc id to look for * @@ -499,6 +548,9 @@ struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id) struct kern_ipc_perm *out; int lid = ipcid_to_idx(id); + if (unlikely(!ids->tables_initialized)) + return ERR_PTR(-EINVAL); + out = idr_find(&ids->ipcs_idr, lid); if (!out) return ERR_PTR(-EINVAL); diff --git a/ipc/util.h b/ipc/util.h index c692010e6f0a394d1d796e33fda3b6b5e46ca16f..b21297bc11ebfe4bd65317e59a401a2fcd49e566 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -15,8 +15,8 @@ #define SEQ_MULTIPLIER (IPCMNI) -void sem_init(void); -void msg_init(void); +int sem_init(void); +int msg_init(void); void shm_init(void); struct ipc_namespace; @@ -30,17 +30,17 @@ static inline void mq_put_mnt(struct ipc_namespace *ns) { } #endif #ifdef CONFIG_SYSVIPC -void sem_init_ns(struct ipc_namespace *ns); -void msg_init_ns(struct ipc_namespace *ns); -void shm_init_ns(struct ipc_namespace *ns); +int sem_init_ns(struct ipc_namespace *ns); +int msg_init_ns(struct ipc_namespace *ns); +int shm_init_ns(struct ipc_namespace *ns); void sem_exit_ns(struct ipc_namespace *ns); void msg_exit_ns(struct ipc_namespace *ns); void shm_exit_ns(struct ipc_namespace *ns); #else -static inline void sem_init_ns(struct ipc_namespace *ns) { } -static inline void msg_init_ns(struct ipc_namespace *ns) { } -static inline void shm_init_ns(struct ipc_namespace *ns) { } +static inline int sem_init_ns(struct ipc_namespace *ns) { return 0; } +static inline int msg_init_ns(struct ipc_namespace *ns) { return 0; } +static inline int shm_init_ns(struct ipc_namespace *ns) { return 0; } static inline void sem_exit_ns(struct ipc_namespace *ns) { } static inline void msg_exit_ns(struct ipc_namespace *ns) { } @@ -79,7 +79,7 @@ struct ipc_ops { struct seq_file; struct ipc_ids; -void ipc_init_ids(struct ipc_ids *); +int ipc_init_ids(struct ipc_ids *); #ifdef CONFIG_PROC_FS void __init ipc_init_proc_interface(const char *path, const char *header, int ids, int (*show)(struct seq_file *, void *)); @@ -104,6 +104,9 @@ int ipc_get_maxid(struct ipc_ids *); /* must be called with both locks acquired. */ void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *); +/* must be called with both locks acquired. */ +void ipc_set_key_private(struct ipc_ids *, struct kern_ipc_perm *); + /* must be called with ipcp locked */ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg); @@ -191,4 +194,34 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, const struct ipc_ops *ops, struct ipc_params *params); void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, void (*free)(struct ipc_namespace *, struct kern_ipc_perm *)); + +#ifdef CONFIG_COMPAT +#include +struct compat_ipc_perm { + key_t key; + __compat_uid_t uid; + __compat_gid_t gid; + __compat_uid_t cuid; + __compat_gid_t cgid; + compat_mode_t mode; + unsigned short seq; +}; + +void to_compat_ipc_perm(struct compat_ipc_perm *, struct ipc64_perm *); +void to_compat_ipc64_perm(struct compat_ipc64_perm *, struct ipc64_perm *); +int get_compat_ipc_perm(struct ipc64_perm *, struct compat_ipc_perm __user *); +int get_compat_ipc64_perm(struct ipc64_perm *, + struct compat_ipc64_perm __user *); + +static inline int compat_ipc_parse_version(int *cmd) +{ +#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION + int version = *cmd & IPC_64; + *cmd &= ~IPC_64; + return version; +#else + return IPC_64; +#endif +} +#endif #endif diff --git a/kernel/Makefile b/kernel/Makefile index 4cb8e8b23c6ecbcfbf12fda4980a0e9957b94346..ed470aac53da1e3b47bd98517cb67deefd853588 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -5,12 +5,13 @@ obj-y = fork.o exec_domain.o panic.o \ cpu.o exit.o softirq.o resource.o \ sysctl.o sysctl_binary.o capability.o ptrace.o user.o \ - signal.o sys.o kmod.o workqueue.o pid.o task_work.o \ + signal.o sys.o umh.o workqueue.o pid.o task_work.o \ extable.o params.o \ kthread.o sys_ni.o nsproxy.o \ notifier.o ksysfs.o cred.o reboot.o \ async.o range.o smpboot.o ucount.o +obj-$(CONFIG_MODULES) += kmod.o obj-$(CONFIG_MULTIUSER) += groups.o ifdef CONFIG_FUNCTION_TRACER @@ -108,7 +109,6 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o obj-$(CONFIG_TORTURE_TEST) += torture.o -obj-$(CONFIG_MEMBARRIER) += membarrier.o obj-$(CONFIG_HAS_IOMEM) += memremap.o diff --git a/kernel/acct.c b/kernel/acct.c index 5b1284370367aa71bdb5a56fd5c6855d7130fb4e..5e72af29ab738c7134dcc1932ea11c297b027d44 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -516,7 +516,7 @@ static void do_acct_process(struct bsd_acct_struct *acct) if (file_start_write_trylock(file)) { /* it's been opened O_APPEND, so position is irrelevant */ loff_t pos = 0; - __kernel_write(file, (char *)&ac, sizeof(acct_t), &pos); + __kernel_write(file, &ac, sizeof(acct_t), &pos); file_end_write(file); } out: diff --git a/kernel/audit.c b/kernel/audit.c index 6dd5569317393889d2f90814dc7b15a840f7e0eb..be1c28fd4d575d824606f10860f766fc09f8a0c1 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1662,7 +1662,7 @@ static inline void audit_get_stamp(struct audit_context *ctx, struct timespec64 *t, unsigned int *serial) { if (!ctx || !auditsc_get_stamp(ctx, t, serial)) { - ktime_get_real_ts64(t); + *t = current_kernel_time64(); *serial = audit_serial(); } } @@ -1833,7 +1833,7 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) } /** - * audit_log_hex - convert a buffer to hex and append it to the audit skb + * audit_log_n_hex - convert a buffer to hex and append it to the audit skb * @ab: the audit_buffer * @buf: buffer to convert to hex * @len: length of @buf to be converted diff --git a/kernel/audit.h b/kernel/audit.h index b331d9b83f6344c9194462bf31dc1e55e7e7c0d8..9b110ae17ee3fe744592fdb1127d1dc868577af2 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -182,7 +182,7 @@ struct audit_context { mqd_t mqdes; size_t msg_len; unsigned int msg_prio; - struct timespec abs_timeout; + struct timespec64 abs_timeout; } mq_sendrecv; struct { int oflag; diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 62d686d965813aeb4b8ef34877e886e08bd71912..9eb8b3511636e96e0607be2484119823b1034fb5 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -66,7 +66,7 @@ static struct fsnotify_group *audit_watch_group; /* fsnotify events we care about. */ #define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\ - FS_MOVE_SELF | FS_EVENT_ON_CHILD) + FS_MOVE_SELF | FS_EVENT_ON_CHILD | FS_UNMOUNT) static void audit_free_parent(struct audit_parent *parent) { @@ -457,13 +457,15 @@ void audit_remove_watch_rule(struct audit_krule *krule) list_del(&krule->rlist); if (list_empty(&watch->rules)) { + /* + * audit_remove_watch() drops our reference to 'parent' which + * can get freed. Grab our own reference to be safe. + */ + audit_get_parent(parent); audit_remove_watch(watch); - - if (list_empty(&parent->watches)) { - audit_get_parent(parent); + if (list_empty(&parent->watches)) fsnotify_destroy_mark(&parent->mark, audit_watch_group); - audit_put_parent(parent); - } + audit_put_parent(parent); } } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3260ba2312a95e4e500513d5277426e0582b868f..ecc23e25c9eb2b3aedf5db585905d7b044d6b276 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1235,11 +1235,11 @@ static void show_special(struct audit_context *context, int *call_panic) case AUDIT_MQ_SENDRECV: audit_log_format(ab, "mqdes=%d msg_len=%zd msg_prio=%u " - "abs_timeout_sec=%ld abs_timeout_nsec=%ld", + "abs_timeout_sec=%lld abs_timeout_nsec=%ld", context->mq_sendrecv.mqdes, context->mq_sendrecv.msg_len, context->mq_sendrecv.msg_prio, - context->mq_sendrecv.abs_timeout.tv_sec, + (long long) context->mq_sendrecv.abs_timeout.tv_sec, context->mq_sendrecv.abs_timeout.tv_nsec); break; case AUDIT_MQ_NOTIFY: @@ -1462,7 +1462,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts } /** - * audit_free - free a per-task audit context + * __audit_free - free a per-task audit context * @tsk: task whose audit context block to free * * Called from copy_process and do_exit @@ -1489,7 +1489,7 @@ void __audit_free(struct task_struct *tsk) } /** - * audit_syscall_entry - fill in an audit record at syscall entry + * __audit_syscall_entry - fill in an audit record at syscall entry * @major: major syscall type (function) * @a1: additional syscall register 1 * @a2: additional syscall register 2 @@ -1536,14 +1536,14 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2, return; context->serial = 0; - ktime_get_real_ts64(&context->ctime); + context->ctime = current_kernel_time64(); context->in_syscall = 1; context->current_state = state; context->ppid = 0; } /** - * audit_syscall_exit - deallocate audit context after a system call + * __audit_syscall_exit - deallocate audit context after a system call * @success: success value of the syscall * @return_code: return value of the syscall * @@ -1705,7 +1705,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context, } /** - * audit_reusename - fill out filename with info from existing entry + * __audit_reusename - fill out filename with info from existing entry * @uptr: userland ptr to pathname * * Search the audit_names list for the current audit context. If there is an @@ -1730,7 +1730,7 @@ __audit_reusename(const __user char *uptr) } /** - * audit_getname - add a name to the list + * __audit_getname - add a name to the list * @name: name to add * * Add a name to the list of audit names for this context. @@ -2083,15 +2083,15 @@ void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr) * */ void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, - const struct timespec *abs_timeout) + const struct timespec64 *abs_timeout) { struct audit_context *context = current->audit_context; - struct timespec *p = &context->mq_sendrecv.abs_timeout; + struct timespec64 *p = &context->mq_sendrecv.abs_timeout; if (abs_timeout) - memcpy(p, abs_timeout, sizeof(struct timespec)); + memcpy(p, abs_timeout, sizeof(*p)); else - memset(p, 0, sizeof(struct timespec)); + memset(p, 0, sizeof(*p)); context->mq_sendrecv.mqdes = mqdes; context->mq_sendrecv.msg_len = msg_len; @@ -2135,7 +2135,7 @@ void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) } /** - * audit_ipc_obj - record audit data for ipc object + * __audit_ipc_obj - record audit data for ipc object * @ipcp: ipc permissions * */ @@ -2151,7 +2151,7 @@ void __audit_ipc_obj(struct kern_ipc_perm *ipcp) } /** - * audit_ipc_set_perm - record audit data for new ipc permissions + * __audit_ipc_set_perm - record audit data for new ipc permissions * @qbytes: msgq bytes * @uid: msgq user id * @gid: msgq group id @@ -2180,7 +2180,7 @@ void __audit_bprm(struct linux_binprm *bprm) /** - * audit_socketcall - record audit data for sys_socketcall + * __audit_socketcall - record audit data for sys_socketcall * @nargs: number of args, which should not be more than AUDITSC_ARGS. * @args: args array * @@ -2211,7 +2211,7 @@ void __audit_fd_pair(int fd1, int fd2) } /** - * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto + * __audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto * @len: data length in user space * @a: data address in kernel space * diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index e1e5e658f2dbf887be70fbfc9492d4365aef5064..897daa005b239d403fd4e3be9d817834dbe4d40a 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -1,7 +1,13 @@ obj-y := core.o -obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o +obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o +ifeq ($(CONFIG_NET),y) +obj-$(CONFIG_BPF_SYSCALL) += devmap.o +ifeq ($(CONFIG_STREAM_PARSER),y) +obj-$(CONFIG_BPF_SYSCALL) += sockmap.o +endif +endif ifeq ($(CONFIG_PERF_EVENTS),y) obj-$(CONFIG_BPF_SYSCALL) += stackmap.o endif diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index d771a38725006379315cc22782efedb3775b4569..98c0f00c3f5e05007287de1a1636c4e6722beed7 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -49,13 +49,15 @@ static int bpf_array_alloc_percpu(struct bpf_array *array) static struct bpf_map *array_map_alloc(union bpf_attr *attr) { bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; + int numa_node = bpf_map_attr_numa_node(attr); struct bpf_array *array; u64 array_size; u32 elem_size; /* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 4 || - attr->value_size == 0 || attr->map_flags) + attr->value_size == 0 || attr->map_flags & ~BPF_F_NUMA_NODE || + (percpu && numa_node != NUMA_NO_NODE)) return ERR_PTR(-EINVAL); if (attr->value_size > KMALLOC_MAX_SIZE) @@ -77,7 +79,7 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) return ERR_PTR(-ENOMEM); /* allocate all map elements and zero-initialize them */ - array = bpf_map_area_alloc(array_size); + array = bpf_map_area_alloc(array_size, numa_node); if (!array) return ERR_PTR(-ENOMEM); @@ -87,6 +89,7 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) array->map.value_size = attr->value_size; array->map.max_entries = attr->max_entries; array->map.map_flags = attr->map_flags; + array->map.numa_node = numa_node; array->elem_size = elem_size; if (!percpu) @@ -603,6 +606,31 @@ static void *array_of_map_lookup_elem(struct bpf_map *map, void *key) return READ_ONCE(*inner_map); } +static u32 array_of_map_gen_lookup(struct bpf_map *map, + struct bpf_insn *insn_buf) +{ + u32 elem_size = round_up(map->value_size, 8); + struct bpf_insn *insn = insn_buf; + const int ret = BPF_REG_0; + const int map_ptr = BPF_REG_1; + const int index = BPF_REG_2; + + *insn++ = BPF_ALU64_IMM(BPF_ADD, map_ptr, offsetof(struct bpf_array, value)); + *insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0); + *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5); + if (is_power_of_2(elem_size)) + *insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(elem_size)); + else + *insn++ = BPF_ALU64_IMM(BPF_MUL, ret, elem_size); + *insn++ = BPF_ALU64_REG(BPF_ADD, ret, map_ptr); + *insn++ = BPF_LDX_MEM(BPF_DW, ret, ret, 0); + *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 1); + *insn++ = BPF_JMP_IMM(BPF_JA, 0, 0, 1); + *insn++ = BPF_MOV64_IMM(ret, 0); + + return insn - insn_buf; +} + const struct bpf_map_ops array_of_maps_map_ops = { .map_alloc = array_of_map_alloc, .map_free = array_of_map_free, @@ -612,4 +640,5 @@ const struct bpf_map_ops array_of_maps_map_ops = { .map_fd_get_ptr = bpf_map_fd_get_ptr, .map_fd_put_ptr = bpf_map_fd_put_ptr, .map_fd_sys_lookup_elem = bpf_map_fd_sys_lookup_elem, + .map_gen_lookup = array_of_map_gen_lookup, }; diff --git a/kernel/bpf/bpf_lru_list.h b/kernel/bpf/bpf_lru_list.h index 5c35a98d02bf281d0d9527248c37aca0b9876fb1..7d4f89b7cb84167f9ca94b154ae32b3df77cf9f4 100644 --- a/kernel/bpf/bpf_lru_list.h +++ b/kernel/bpf/bpf_lru_list.h @@ -69,7 +69,8 @@ static inline void bpf_lru_node_set_ref(struct bpf_lru_node *node) /* ref is an approximation on access frequency. It does not * have to be very accurate. Hence, no protection is used. */ - node->ref = 1; + if (!node->ref) + node->ref = 1; } int bpf_lru_init(struct bpf_lru *lru, bool percpu, u32 hash_offset, diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index ad5f55922a136f19af951992e5a973dfa5de9bb6..7b62df86be1d7e56044f947985b6c67ee5746c0d 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -595,9 +595,13 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from, case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: case BPF_JMP | BPF_JSET | BPF_K: /* Accommodate for extra offset in case of a backjump. */ off = from->off; @@ -833,12 +837,20 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, [BPF_JMP | BPF_JNE | BPF_K] = &&JMP_JNE_K, [BPF_JMP | BPF_JGT | BPF_X] = &&JMP_JGT_X, [BPF_JMP | BPF_JGT | BPF_K] = &&JMP_JGT_K, + [BPF_JMP | BPF_JLT | BPF_X] = &&JMP_JLT_X, + [BPF_JMP | BPF_JLT | BPF_K] = &&JMP_JLT_K, [BPF_JMP | BPF_JGE | BPF_X] = &&JMP_JGE_X, [BPF_JMP | BPF_JGE | BPF_K] = &&JMP_JGE_K, + [BPF_JMP | BPF_JLE | BPF_X] = &&JMP_JLE_X, + [BPF_JMP | BPF_JLE | BPF_K] = &&JMP_JLE_K, [BPF_JMP | BPF_JSGT | BPF_X] = &&JMP_JSGT_X, [BPF_JMP | BPF_JSGT | BPF_K] = &&JMP_JSGT_K, + [BPF_JMP | BPF_JSLT | BPF_X] = &&JMP_JSLT_X, + [BPF_JMP | BPF_JSLT | BPF_K] = &&JMP_JSLT_K, [BPF_JMP | BPF_JSGE | BPF_X] = &&JMP_JSGE_X, [BPF_JMP | BPF_JSGE | BPF_K] = &&JMP_JSGE_K, + [BPF_JMP | BPF_JSLE | BPF_X] = &&JMP_JSLE_X, + [BPF_JMP | BPF_JSLE | BPF_K] = &&JMP_JSLE_K, [BPF_JMP | BPF_JSET | BPF_X] = &&JMP_JSET_X, [BPF_JMP | BPF_JSET | BPF_K] = &&JMP_JSET_K, /* Program return */ @@ -1010,7 +1022,7 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, struct bpf_map *map = (struct bpf_map *) (unsigned long) BPF_R2; struct bpf_array *array = container_of(map, struct bpf_array, map); struct bpf_prog *prog; - u64 index = BPF_R3; + u32 index = BPF_R3; if (unlikely(index >= array->map.max_entries)) goto out; @@ -1073,6 +1085,18 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, CONT_JMP; } CONT; + JMP_JLT_X: + if (DST < SRC) { + insn += insn->off; + CONT_JMP; + } + CONT; + JMP_JLT_K: + if (DST < IMM) { + insn += insn->off; + CONT_JMP; + } + CONT; JMP_JGE_X: if (DST >= SRC) { insn += insn->off; @@ -1085,6 +1109,18 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, CONT_JMP; } CONT; + JMP_JLE_X: + if (DST <= SRC) { + insn += insn->off; + CONT_JMP; + } + CONT; + JMP_JLE_K: + if (DST <= IMM) { + insn += insn->off; + CONT_JMP; + } + CONT; JMP_JSGT_X: if (((s64) DST) > ((s64) SRC)) { insn += insn->off; @@ -1097,6 +1133,18 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, CONT_JMP; } CONT; + JMP_JSLT_X: + if (((s64) DST) < ((s64) SRC)) { + insn += insn->off; + CONT_JMP; + } + CONT; + JMP_JSLT_K: + if (((s64) DST) < ((s64) IMM)) { + insn += insn->off; + CONT_JMP; + } + CONT; JMP_JSGE_X: if (((s64) DST) >= ((s64) SRC)) { insn += insn->off; @@ -1109,6 +1157,18 @@ static unsigned int ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, CONT_JMP; } CONT; + JMP_JSLE_X: + if (((s64) DST) <= ((s64) SRC)) { + insn += insn->off; + CONT_JMP; + } + CONT; + JMP_JSLE_K: + if (((s64) DST) <= ((s64) IMM)) { + insn += insn->off; + CONT_JMP; + } + CONT; JMP_JSET_X: if (DST & SRC) { insn += insn->off; @@ -1378,6 +1438,7 @@ const struct bpf_func_proto bpf_ktime_get_ns_proto __weak; const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak; const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak; const struct bpf_func_proto bpf_get_current_comm_proto __weak; +const struct bpf_func_proto bpf_sock_map_update_proto __weak; const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void) { diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c new file mode 100644 index 0000000000000000000000000000000000000000..e093d9a2c4dd3fb5f02503bf0c741f2af9cc7c48 --- /dev/null +++ b/kernel/bpf/devmap.c @@ -0,0 +1,411 @@ +/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +/* Devmaps primary use is as a backend map for XDP BPF helper call + * bpf_redirect_map(). Because XDP is mostly concerned with performance we + * spent some effort to ensure the datapath with redirect maps does not use + * any locking. This is a quick note on the details. + * + * We have three possible paths to get into the devmap control plane bpf + * syscalls, bpf programs, and driver side xmit/flush operations. A bpf syscall + * will invoke an update, delete, or lookup operation. To ensure updates and + * deletes appear atomic from the datapath side xchg() is used to modify the + * netdev_map array. Then because the datapath does a lookup into the netdev_map + * array (read-only) from an RCU critical section we use call_rcu() to wait for + * an rcu grace period before free'ing the old data structures. This ensures the + * datapath always has a valid copy. However, the datapath does a "flush" + * operation that pushes any pending packets in the driver outside the RCU + * critical section. Each bpf_dtab_netdev tracks these pending operations using + * an atomic per-cpu bitmap. The bpf_dtab_netdev object will not be destroyed + * until all bits are cleared indicating outstanding flush operations have + * completed. + * + * BPF syscalls may race with BPF program calls on any of the update, delete + * or lookup operations. As noted above the xchg() operation also keep the + * netdev_map consistent in this case. From the devmap side BPF programs + * calling into these operations are the same as multiple user space threads + * making system calls. + * + * Finally, any of the above may race with a netdev_unregister notifier. The + * unregister notifier must search for net devices in the map structure that + * contain a reference to the net device and remove them. This is a two step + * process (a) dereference the bpf_dtab_netdev object in netdev_map and (b) + * check to see if the ifindex is the same as the net_device being removed. + * When removing the dev a cmpxchg() is used to ensure the correct dev is + * removed, in the case of a concurrent update or delete operation it is + * possible that the initially referenced dev is no longer in the map. As the + * notifier hook walks the map we know that new dev references can not be + * added by the user because core infrastructure ensures dev_get_by_index() + * calls will fail at this point. + */ +#include +#include + +struct bpf_dtab_netdev { + struct net_device *dev; + struct bpf_dtab *dtab; + unsigned int bit; + struct rcu_head rcu; +}; + +struct bpf_dtab { + struct bpf_map map; + struct bpf_dtab_netdev **netdev_map; + unsigned long __percpu *flush_needed; + struct list_head list; +}; + +static DEFINE_SPINLOCK(dev_map_lock); +static LIST_HEAD(dev_map_list); + +static u64 dev_map_bitmap_size(const union bpf_attr *attr) +{ + return BITS_TO_LONGS(attr->max_entries) * sizeof(unsigned long); +} + +static struct bpf_map *dev_map_alloc(union bpf_attr *attr) +{ + struct bpf_dtab *dtab; + int err = -EINVAL; + u64 cost; + + /* check sanity of attributes */ + if (attr->max_entries == 0 || attr->key_size != 4 || + attr->value_size != 4 || attr->map_flags & ~BPF_F_NUMA_NODE) + return ERR_PTR(-EINVAL); + + dtab = kzalloc(sizeof(*dtab), GFP_USER); + if (!dtab) + return ERR_PTR(-ENOMEM); + + /* mandatory map attributes */ + dtab->map.map_type = attr->map_type; + dtab->map.key_size = attr->key_size; + dtab->map.value_size = attr->value_size; + dtab->map.max_entries = attr->max_entries; + dtab->map.map_flags = attr->map_flags; + dtab->map.numa_node = bpf_map_attr_numa_node(attr); + + /* make sure page count doesn't overflow */ + cost = (u64) dtab->map.max_entries * sizeof(struct bpf_dtab_netdev *); + cost += dev_map_bitmap_size(attr) * num_possible_cpus(); + if (cost >= U32_MAX - PAGE_SIZE) + goto free_dtab; + + dtab->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; + + /* if map size is larger than memlock limit, reject it early */ + err = bpf_map_precharge_memlock(dtab->map.pages); + if (err) + goto free_dtab; + + err = -ENOMEM; + + /* A per cpu bitfield with a bit per possible net device */ + dtab->flush_needed = __alloc_percpu(dev_map_bitmap_size(attr), + __alignof__(unsigned long)); + if (!dtab->flush_needed) + goto free_dtab; + + dtab->netdev_map = bpf_map_area_alloc(dtab->map.max_entries * + sizeof(struct bpf_dtab_netdev *), + dtab->map.numa_node); + if (!dtab->netdev_map) + goto free_dtab; + + spin_lock(&dev_map_lock); + list_add_tail_rcu(&dtab->list, &dev_map_list); + spin_unlock(&dev_map_lock); + + return &dtab->map; +free_dtab: + free_percpu(dtab->flush_needed); + kfree(dtab); + return ERR_PTR(err); +} + +static void dev_map_free(struct bpf_map *map) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + int i, cpu; + + /* At this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0, + * so the programs (can be more than one that used this map) were + * disconnected from events. Wait for outstanding critical sections in + * these programs to complete. The rcu critical section only guarantees + * no further reads against netdev_map. It does __not__ ensure pending + * flush operations (if any) are complete. + */ + + spin_lock(&dev_map_lock); + list_del_rcu(&dtab->list); + spin_unlock(&dev_map_lock); + + synchronize_rcu(); + + /* To ensure all pending flush operations have completed wait for flush + * bitmap to indicate all flush_needed bits to be zero on _all_ cpus. + * Because the above synchronize_rcu() ensures the map is disconnected + * from the program we can assume no new bits will be set. + */ + for_each_online_cpu(cpu) { + unsigned long *bitmap = per_cpu_ptr(dtab->flush_needed, cpu); + + while (!bitmap_empty(bitmap, dtab->map.max_entries)) + cond_resched(); + } + + for (i = 0; i < dtab->map.max_entries; i++) { + struct bpf_dtab_netdev *dev; + + dev = dtab->netdev_map[i]; + if (!dev) + continue; + + dev_put(dev->dev); + kfree(dev); + } + + free_percpu(dtab->flush_needed); + bpf_map_area_free(dtab->netdev_map); + kfree(dtab); +} + +static int dev_map_get_next_key(struct bpf_map *map, void *key, void *next_key) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + u32 index = key ? *(u32 *)key : U32_MAX; + u32 *next = next_key; + + if (index >= dtab->map.max_entries) { + *next = 0; + return 0; + } + + if (index == dtab->map.max_entries - 1) + return -ENOENT; + *next = index + 1; + return 0; +} + +void __dev_map_insert_ctx(struct bpf_map *map, u32 bit) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + unsigned long *bitmap = this_cpu_ptr(dtab->flush_needed); + + __set_bit(bit, bitmap); +} + +/* __dev_map_flush is called from xdp_do_flush_map() which _must_ be signaled + * from the driver before returning from its napi->poll() routine. The poll() + * routine is called either from busy_poll context or net_rx_action signaled + * from NET_RX_SOFTIRQ. Either way the poll routine must complete before the + * net device can be torn down. On devmap tear down we ensure the ctx bitmap + * is zeroed before completing to ensure all flush operations have completed. + */ +void __dev_map_flush(struct bpf_map *map) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + unsigned long *bitmap = this_cpu_ptr(dtab->flush_needed); + u32 bit; + + for_each_set_bit(bit, bitmap, map->max_entries) { + struct bpf_dtab_netdev *dev = READ_ONCE(dtab->netdev_map[bit]); + struct net_device *netdev; + + /* This is possible if the dev entry is removed by user space + * between xdp redirect and flush op. + */ + if (unlikely(!dev)) + continue; + + __clear_bit(bit, bitmap); + netdev = dev->dev; + if (likely(netdev->netdev_ops->ndo_xdp_flush)) + netdev->netdev_ops->ndo_xdp_flush(netdev); + } +} + +/* rcu_read_lock (from syscall and BPF contexts) ensures that if a delete and/or + * update happens in parallel here a dev_put wont happen until after reading the + * ifindex. + */ +struct net_device *__dev_map_lookup_elem(struct bpf_map *map, u32 key) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + struct bpf_dtab_netdev *dev; + + if (key >= map->max_entries) + return NULL; + + dev = READ_ONCE(dtab->netdev_map[key]); + return dev ? dev->dev : NULL; +} + +static void *dev_map_lookup_elem(struct bpf_map *map, void *key) +{ + struct net_device *dev = __dev_map_lookup_elem(map, *(u32 *)key); + + return dev ? &dev->ifindex : NULL; +} + +static void dev_map_flush_old(struct bpf_dtab_netdev *dev) +{ + if (dev->dev->netdev_ops->ndo_xdp_flush) { + struct net_device *fl = dev->dev; + unsigned long *bitmap; + int cpu; + + for_each_online_cpu(cpu) { + bitmap = per_cpu_ptr(dev->dtab->flush_needed, cpu); + __clear_bit(dev->bit, bitmap); + + fl->netdev_ops->ndo_xdp_flush(dev->dev); + } + } +} + +static void __dev_map_entry_free(struct rcu_head *rcu) +{ + struct bpf_dtab_netdev *dev; + + dev = container_of(rcu, struct bpf_dtab_netdev, rcu); + dev_map_flush_old(dev); + dev_put(dev->dev); + kfree(dev); +} + +static int dev_map_delete_elem(struct bpf_map *map, void *key) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + struct bpf_dtab_netdev *old_dev; + int k = *(u32 *)key; + + if (k >= map->max_entries) + return -EINVAL; + + /* Use call_rcu() here to ensure any rcu critical sections have + * completed, but this does not guarantee a flush has happened + * yet. Because driver side rcu_read_lock/unlock only protects the + * running XDP program. However, for pending flush operations the + * dev and ctx are stored in another per cpu map. And additionally, + * the driver tear down ensures all soft irqs are complete before + * removing the net device in the case of dev_put equals zero. + */ + old_dev = xchg(&dtab->netdev_map[k], NULL); + if (old_dev) + call_rcu(&old_dev->rcu, __dev_map_entry_free); + return 0; +} + +static int dev_map_update_elem(struct bpf_map *map, void *key, void *value, + u64 map_flags) +{ + struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map); + struct net *net = current->nsproxy->net_ns; + struct bpf_dtab_netdev *dev, *old_dev; + u32 i = *(u32 *)key; + u32 ifindex = *(u32 *)value; + + if (unlikely(map_flags > BPF_EXIST)) + return -EINVAL; + if (unlikely(i >= dtab->map.max_entries)) + return -E2BIG; + if (unlikely(map_flags == BPF_NOEXIST)) + return -EEXIST; + + if (!ifindex) { + dev = NULL; + } else { + dev = kmalloc_node(sizeof(*dev), GFP_ATOMIC | __GFP_NOWARN, + map->numa_node); + if (!dev) + return -ENOMEM; + + dev->dev = dev_get_by_index(net, ifindex); + if (!dev->dev) { + kfree(dev); + return -EINVAL; + } + + dev->bit = i; + dev->dtab = dtab; + } + + /* Use call_rcu() here to ensure rcu critical sections have completed + * Remembering the driver side flush operation will happen before the + * net device is removed. + */ + old_dev = xchg(&dtab->netdev_map[i], dev); + if (old_dev) + call_rcu(&old_dev->rcu, __dev_map_entry_free); + + return 0; +} + +const struct bpf_map_ops dev_map_ops = { + .map_alloc = dev_map_alloc, + .map_free = dev_map_free, + .map_get_next_key = dev_map_get_next_key, + .map_lookup_elem = dev_map_lookup_elem, + .map_update_elem = dev_map_update_elem, + .map_delete_elem = dev_map_delete_elem, +}; + +static int dev_map_notification(struct notifier_block *notifier, + ulong event, void *ptr) +{ + struct net_device *netdev = netdev_notifier_info_to_dev(ptr); + struct bpf_dtab *dtab; + int i; + + switch (event) { + case NETDEV_UNREGISTER: + /* This rcu_read_lock/unlock pair is needed because + * dev_map_list is an RCU list AND to ensure a delete + * operation does not free a netdev_map entry while we + * are comparing it against the netdev being unregistered. + */ + rcu_read_lock(); + list_for_each_entry_rcu(dtab, &dev_map_list, list) { + for (i = 0; i < dtab->map.max_entries; i++) { + struct bpf_dtab_netdev *dev, *odev; + + dev = READ_ONCE(dtab->netdev_map[i]); + if (!dev || + dev->dev->ifindex != netdev->ifindex) + continue; + odev = cmpxchg(&dtab->netdev_map[i], dev, NULL); + if (dev == odev) + call_rcu(&dev->rcu, + __dev_map_entry_free); + } + } + rcu_read_unlock(); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block dev_map_notifier = { + .notifier_call = dev_map_notification, +}; + +static int __init dev_map_init(void) +{ + register_netdevice_notifier(&dev_map_notifier); + return 0; +} + +subsys_initcall(dev_map_init); diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 4fb463172aa88e81d9caaaee271d8d8c8a9db978..431126f31ea3c90648366295e2b77fd3bb79b6e7 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -18,6 +18,9 @@ #include "bpf_lru_list.h" #include "map_in_map.h" +#define HTAB_CREATE_FLAG_MASK \ + (BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU | BPF_F_NUMA_NODE) + struct bucket { struct hlist_nulls_head head; raw_spinlock_t lock; @@ -138,7 +141,8 @@ static int prealloc_init(struct bpf_htab *htab) if (!htab_is_percpu(htab) && !htab_is_lru(htab)) num_entries += num_possible_cpus(); - htab->elems = bpf_map_area_alloc(htab->elem_size * num_entries); + htab->elems = bpf_map_area_alloc(htab->elem_size * num_entries, + htab->map.numa_node); if (!htab->elems) return -ENOMEM; @@ -233,6 +237,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) */ bool percpu_lru = (attr->map_flags & BPF_F_NO_COMMON_LRU); bool prealloc = !(attr->map_flags & BPF_F_NO_PREALLOC); + int numa_node = bpf_map_attr_numa_node(attr); struct bpf_htab *htab; int err, i; u64 cost; @@ -248,7 +253,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) */ return ERR_PTR(-EPERM); - if (attr->map_flags & ~(BPF_F_NO_PREALLOC | BPF_F_NO_COMMON_LRU)) + if (attr->map_flags & ~HTAB_CREATE_FLAG_MASK) /* reserved bits should not be used */ return ERR_PTR(-EINVAL); @@ -258,6 +263,9 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) if (lru && !prealloc) return ERR_PTR(-ENOTSUPP); + if (numa_node != NUMA_NO_NODE && (percpu || percpu_lru)) + return ERR_PTR(-EINVAL); + htab = kzalloc(sizeof(*htab), GFP_USER); if (!htab) return ERR_PTR(-ENOMEM); @@ -268,6 +276,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) htab->map.value_size = attr->value_size; htab->map.max_entries = attr->max_entries; htab->map.map_flags = attr->map_flags; + htab->map.numa_node = numa_node; /* check sanity of attributes. * value_size == 0 may be allowed in the future to use map as a set @@ -346,7 +355,8 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) err = -ENOMEM; htab->buckets = bpf_map_area_alloc(htab->n_buckets * - sizeof(struct bucket)); + sizeof(struct bucket), + htab->map.numa_node); if (!htab->buckets) goto free_htab; @@ -504,6 +514,29 @@ static void *htab_lru_map_lookup_elem(struct bpf_map *map, void *key) return NULL; } +static u32 htab_lru_map_gen_lookup(struct bpf_map *map, + struct bpf_insn *insn_buf) +{ + struct bpf_insn *insn = insn_buf; + const int ret = BPF_REG_0; + const int ref_reg = BPF_REG_1; + + *insn++ = BPF_EMIT_CALL((u64 (*)(u64, u64, u64, u64, u64))__htab_map_lookup_elem); + *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 4); + *insn++ = BPF_LDX_MEM(BPF_B, ref_reg, ret, + offsetof(struct htab_elem, lru_node) + + offsetof(struct bpf_lru_node, ref)); + *insn++ = BPF_JMP_IMM(BPF_JNE, ref_reg, 0, 1); + *insn++ = BPF_ST_MEM(BPF_B, ret, + offsetof(struct htab_elem, lru_node) + + offsetof(struct bpf_lru_node, ref), + 1); + *insn++ = BPF_ALU64_IMM(BPF_ADD, ret, + offsetof(struct htab_elem, key) + + round_up(map->key_size, 8)); + return insn - insn_buf; +} + /* It is called from the bpf_lru_list when the LRU needs to delete * older elements from the htab. */ @@ -652,12 +685,27 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, } } +static bool fd_htab_map_needs_adjust(const struct bpf_htab *htab) +{ + return htab->map.map_type == BPF_MAP_TYPE_HASH_OF_MAPS && + BITS_PER_LONG == 64; +} + +static u32 htab_size_value(const struct bpf_htab *htab, bool percpu) +{ + u32 size = htab->map.value_size; + + if (percpu || fd_htab_map_needs_adjust(htab)) + size = round_up(size, 8); + return size; +} + static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, void *value, u32 key_size, u32 hash, bool percpu, bool onallcpus, struct htab_elem *old_elem) { - u32 size = htab->map.value_size; + u32 size = htab_size_value(htab, percpu); bool prealloc = htab_is_prealloc(htab); struct htab_elem *l_new, **pl_new; void __percpu *pptr; @@ -689,16 +737,14 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, atomic_dec(&htab->count); return ERR_PTR(-E2BIG); } - l_new = kmalloc(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN); + l_new = kmalloc_node(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN, + htab->map.numa_node); if (!l_new) return ERR_PTR(-ENOMEM); } memcpy(l_new->key, key, key_size); if (percpu) { - /* round up value_size to 8 bytes */ - size = round_up(size, 8); - if (prealloc) { pptr = htab_elem_get_ptr(l_new, key_size); } else { @@ -1114,6 +1160,7 @@ const struct bpf_map_ops htab_lru_map_ops = { .map_lookup_elem = htab_lru_map_lookup_elem, .map_update_elem = htab_lru_map_update_elem, .map_delete_elem = htab_lru_map_delete_elem, + .map_gen_lookup = htab_lru_map_gen_lookup, }; /* Called from eBPF program */ @@ -1209,17 +1256,9 @@ const struct bpf_map_ops htab_lru_percpu_map_ops = { static struct bpf_map *fd_htab_map_alloc(union bpf_attr *attr) { - struct bpf_map *map; - if (attr->value_size != sizeof(u32)) return ERR_PTR(-EINVAL); - - /* pointer is stored internally */ - attr->value_size = sizeof(void *); - map = htab_map_alloc(attr); - attr->value_size = sizeof(u32); - - return map; + return htab_map_alloc(attr); } static void fd_htab_map_free(struct bpf_map *map) @@ -1311,6 +1350,22 @@ static void *htab_of_map_lookup_elem(struct bpf_map *map, void *key) return READ_ONCE(*inner_map); } +static u32 htab_of_map_gen_lookup(struct bpf_map *map, + struct bpf_insn *insn_buf) +{ + struct bpf_insn *insn = insn_buf; + const int ret = BPF_REG_0; + + *insn++ = BPF_EMIT_CALL((u64 (*)(u64, u64, u64, u64, u64))__htab_map_lookup_elem); + *insn++ = BPF_JMP_IMM(BPF_JEQ, ret, 0, 2); + *insn++ = BPF_ALU64_IMM(BPF_ADD, ret, + offsetof(struct htab_elem, key) + + round_up(map->key_size, 8)); + *insn++ = BPF_LDX_MEM(BPF_DW, ret, ret, 0); + + return insn - insn_buf; +} + static void htab_of_map_free(struct bpf_map *map) { bpf_map_meta_free(map->inner_map_meta); @@ -1326,4 +1381,5 @@ const struct bpf_map_ops htab_of_maps_map_ops = { .map_fd_get_ptr = bpf_map_fd_get_ptr, .map_fd_put_ptr = bpf_map_fd_put_ptr, .map_fd_sys_lookup_elem = bpf_map_fd_sys_lookup_elem, + .map_gen_lookup = htab_of_map_gen_lookup, }; diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c index b09185f0f17d3428ac445de2ed52756004ca5368..1b767844a76ff54b1e99c0c191964269a34c85a7 100644 --- a/kernel/bpf/lpm_trie.c +++ b/kernel/bpf/lpm_trie.c @@ -244,7 +244,8 @@ static struct lpm_trie_node *lpm_trie_node_alloc(const struct lpm_trie *trie, if (value) size += trie->map.value_size; - node = kmalloc(size, GFP_ATOMIC | __GFP_NOWARN); + node = kmalloc_node(size, GFP_ATOMIC | __GFP_NOWARN, + trie->map.numa_node); if (!node) return NULL; @@ -405,6 +406,8 @@ static int trie_delete_elem(struct bpf_map *map, void *key) #define LPM_KEY_SIZE_MAX LPM_KEY_SIZE(LPM_DATA_SIZE_MAX) #define LPM_KEY_SIZE_MIN LPM_KEY_SIZE(LPM_DATA_SIZE_MIN) +#define LPM_CREATE_FLAG_MASK (BPF_F_NO_PREALLOC | BPF_F_NUMA_NODE) + static struct bpf_map *trie_alloc(union bpf_attr *attr) { struct lpm_trie *trie; @@ -416,7 +419,8 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr) /* check sanity of attributes */ if (attr->max_entries == 0 || - attr->map_flags != BPF_F_NO_PREALLOC || + !(attr->map_flags & BPF_F_NO_PREALLOC) || + attr->map_flags & ~LPM_CREATE_FLAG_MASK || attr->key_size < LPM_KEY_SIZE_MIN || attr->key_size > LPM_KEY_SIZE_MAX || attr->value_size < LPM_VAL_SIZE_MIN || @@ -433,6 +437,7 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr) trie->map.value_size = attr->value_size; trie->map.max_entries = attr->max_entries; trie->map.map_flags = attr->map_flags; + trie->map.numa_node = bpf_map_attr_numa_node(attr); trie->data_size = attr->key_size - offsetof(struct bpf_lpm_trie_key, data); trie->max_prefixlen = trie->data_size * 8; diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c new file mode 100644 index 0000000000000000000000000000000000000000..6424ce0e49698abee1da6242a0a8494d8ba0f03f --- /dev/null +++ b/kernel/bpf/sockmap.c @@ -0,0 +1,873 @@ +/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +/* A BPF sock_map is used to store sock objects. This is primarly used + * for doing socket redirect with BPF helper routines. + * + * A sock map may have BPF programs attached to it, currently a program + * used to parse packets and a program to provide a verdict and redirect + * decision on the packet are supported. Any programs attached to a sock + * map are inherited by sock objects when they are added to the map. If + * no BPF programs are attached the sock object may only be used for sock + * redirect. + * + * A sock object may be in multiple maps, but can only inherit a single + * parse or verdict program. If adding a sock object to a map would result + * in having multiple parsing programs the update will return an EBUSY error. + * + * For reference this program is similar to devmap used in XDP context + * reviewing these together may be useful. For an example please review + * ./samples/bpf/sockmap/. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct bpf_stab { + struct bpf_map map; + struct sock **sock_map; + struct bpf_prog *bpf_parse; + struct bpf_prog *bpf_verdict; +}; + +enum smap_psock_state { + SMAP_TX_RUNNING, +}; + +struct smap_psock_map_entry { + struct list_head list; + struct sock **entry; +}; + +struct smap_psock { + struct rcu_head rcu; + /* refcnt is used inside sk_callback_lock */ + u32 refcnt; + + /* datapath variables */ + struct sk_buff_head rxqueue; + bool strp_enabled; + + /* datapath error path cache across tx work invocations */ + int save_rem; + int save_off; + struct sk_buff *save_skb; + + struct strparser strp; + struct bpf_prog *bpf_parse; + struct bpf_prog *bpf_verdict; + struct list_head maps; + + /* Back reference used when sock callback trigger sockmap operations */ + struct sock *sock; + unsigned long state; + + struct work_struct tx_work; + struct work_struct gc_work; + + void (*save_data_ready)(struct sock *sk); + void (*save_write_space)(struct sock *sk); + void (*save_state_change)(struct sock *sk); +}; + +static inline struct smap_psock *smap_psock_sk(const struct sock *sk) +{ + return rcu_dereference_sk_user_data(sk); +} + +static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb) +{ + struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict); + int rc; + + if (unlikely(!prog)) + return SK_DROP; + + skb_orphan(skb); + skb->sk = psock->sock; + bpf_compute_data_end(skb); + rc = (*prog->bpf_func)(skb, prog->insnsi); + skb->sk = NULL; + + return rc; +} + +static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb) +{ + struct sock *sk; + int rc; + + /* Because we use per cpu values to feed input from sock redirect + * in BPF program to do_sk_redirect_map() call we need to ensure we + * are not preempted. RCU read lock is not sufficient in this case + * with CONFIG_PREEMPT_RCU enabled so we must be explicit here. + */ + preempt_disable(); + rc = smap_verdict_func(psock, skb); + switch (rc) { + case SK_REDIRECT: + sk = do_sk_redirect_map(); + preempt_enable(); + if (likely(sk)) { + struct smap_psock *peer = smap_psock_sk(sk); + + if (likely(peer && + test_bit(SMAP_TX_RUNNING, &peer->state) && + !sock_flag(sk, SOCK_DEAD) && + sock_writeable(sk))) { + skb_set_owner_w(skb, sk); + skb_queue_tail(&peer->rxqueue, skb); + schedule_work(&peer->tx_work); + break; + } + } + /* Fall through and free skb otherwise */ + case SK_DROP: + default: + if (rc != SK_REDIRECT) + preempt_enable(); + kfree_skb(skb); + } +} + +static void smap_report_sk_error(struct smap_psock *psock, int err) +{ + struct sock *sk = psock->sock; + + sk->sk_err = err; + sk->sk_error_report(sk); +} + +static void smap_release_sock(struct smap_psock *psock, struct sock *sock); + +/* Called with lock_sock(sk) held */ +static void smap_state_change(struct sock *sk) +{ + struct smap_psock_map_entry *e, *tmp; + struct smap_psock *psock; + struct socket_wq *wq; + struct sock *osk; + + rcu_read_lock(); + + /* Allowing transitions into an established syn_recv states allows + * for early binding sockets to a smap object before the connection + * is established. + */ + switch (sk->sk_state) { + case TCP_SYN_SENT: + case TCP_SYN_RECV: + case TCP_ESTABLISHED: + break; + case TCP_CLOSE_WAIT: + case TCP_CLOSING: + case TCP_LAST_ACK: + case TCP_FIN_WAIT1: + case TCP_FIN_WAIT2: + case TCP_LISTEN: + break; + case TCP_CLOSE: + /* Only release if the map entry is in fact the sock in + * question. There is a case where the operator deletes + * the sock from the map, but the TCP sock is closed before + * the psock is detached. Use cmpxchg to verify correct + * sock is removed. + */ + psock = smap_psock_sk(sk); + if (unlikely(!psock)) + break; + write_lock_bh(&sk->sk_callback_lock); + list_for_each_entry_safe(e, tmp, &psock->maps, list) { + osk = cmpxchg(e->entry, sk, NULL); + if (osk == sk) { + list_del(&e->list); + smap_release_sock(psock, sk); + } + } + write_unlock_bh(&sk->sk_callback_lock); + break; + default: + psock = smap_psock_sk(sk); + if (unlikely(!psock)) + break; + smap_report_sk_error(psock, EPIPE); + break; + } + + wq = rcu_dereference(sk->sk_wq); + if (skwq_has_sleeper(wq)) + wake_up_interruptible_all(&wq->wait); + rcu_read_unlock(); +} + +static void smap_read_sock_strparser(struct strparser *strp, + struct sk_buff *skb) +{ + struct smap_psock *psock; + + rcu_read_lock(); + psock = container_of(strp, struct smap_psock, strp); + smap_do_verdict(psock, skb); + rcu_read_unlock(); +} + +/* Called with lock held on socket */ +static void smap_data_ready(struct sock *sk) +{ + struct smap_psock *psock; + + rcu_read_lock(); + psock = smap_psock_sk(sk); + if (likely(psock)) { + write_lock_bh(&sk->sk_callback_lock); + strp_data_ready(&psock->strp); + write_unlock_bh(&sk->sk_callback_lock); + } + rcu_read_unlock(); +} + +static void smap_tx_work(struct work_struct *w) +{ + struct smap_psock *psock; + struct sk_buff *skb; + int rem, off, n; + + psock = container_of(w, struct smap_psock, tx_work); + + /* lock sock to avoid losing sk_socket at some point during loop */ + lock_sock(psock->sock); + if (psock->save_skb) { + skb = psock->save_skb; + rem = psock->save_rem; + off = psock->save_off; + psock->save_skb = NULL; + goto start; + } + + while ((skb = skb_dequeue(&psock->rxqueue))) { + rem = skb->len; + off = 0; +start: + do { + if (likely(psock->sock->sk_socket)) + n = skb_send_sock_locked(psock->sock, + skb, off, rem); + else + n = -EINVAL; + if (n <= 0) { + if (n == -EAGAIN) { + /* Retry when space is available */ + psock->save_skb = skb; + psock->save_rem = rem; + psock->save_off = off; + goto out; + } + /* Hard errors break pipe and stop xmit */ + smap_report_sk_error(psock, n ? -n : EPIPE); + clear_bit(SMAP_TX_RUNNING, &psock->state); + kfree_skb(skb); + goto out; + } + rem -= n; + off += n; + } while (rem); + kfree_skb(skb); + } +out: + release_sock(psock->sock); +} + +static void smap_write_space(struct sock *sk) +{ + struct smap_psock *psock; + + rcu_read_lock(); + psock = smap_psock_sk(sk); + if (likely(psock && test_bit(SMAP_TX_RUNNING, &psock->state))) + schedule_work(&psock->tx_work); + rcu_read_unlock(); +} + +static void smap_stop_sock(struct smap_psock *psock, struct sock *sk) +{ + if (!psock->strp_enabled) + return; + sk->sk_data_ready = psock->save_data_ready; + sk->sk_write_space = psock->save_write_space; + sk->sk_state_change = psock->save_state_change; + psock->save_data_ready = NULL; + psock->save_write_space = NULL; + psock->save_state_change = NULL; + strp_stop(&psock->strp); + psock->strp_enabled = false; +} + +static void smap_destroy_psock(struct rcu_head *rcu) +{ + struct smap_psock *psock = container_of(rcu, + struct smap_psock, rcu); + + /* Now that a grace period has passed there is no longer + * any reference to this sock in the sockmap so we can + * destroy the psock, strparser, and bpf programs. But, + * because we use workqueue sync operations we can not + * do it in rcu context + */ + schedule_work(&psock->gc_work); +} + +static void smap_release_sock(struct smap_psock *psock, struct sock *sock) +{ + psock->refcnt--; + if (psock->refcnt) + return; + + smap_stop_sock(psock, sock); + clear_bit(SMAP_TX_RUNNING, &psock->state); + rcu_assign_sk_user_data(sock, NULL); + call_rcu_sched(&psock->rcu, smap_destroy_psock); +} + +static int smap_parse_func_strparser(struct strparser *strp, + struct sk_buff *skb) +{ + struct smap_psock *psock; + struct bpf_prog *prog; + int rc; + + rcu_read_lock(); + psock = container_of(strp, struct smap_psock, strp); + prog = READ_ONCE(psock->bpf_parse); + + if (unlikely(!prog)) { + rcu_read_unlock(); + return skb->len; + } + + /* Attach socket for bpf program to use if needed we can do this + * because strparser clones the skb before handing it to a upper + * layer, meaning skb_orphan has been called. We NULL sk on the + * way out to ensure we don't trigger a BUG_ON in skb/sk operations + * later and because we are not charging the memory of this skb to + * any socket yet. + */ + skb->sk = psock->sock; + bpf_compute_data_end(skb); + rc = (*prog->bpf_func)(skb, prog->insnsi); + skb->sk = NULL; + rcu_read_unlock(); + return rc; +} + + +static int smap_read_sock_done(struct strparser *strp, int err) +{ + return err; +} + +static int smap_init_sock(struct smap_psock *psock, + struct sock *sk) +{ + static const struct strp_callbacks cb = { + .rcv_msg = smap_read_sock_strparser, + .parse_msg = smap_parse_func_strparser, + .read_sock_done = smap_read_sock_done, + }; + + return strp_init(&psock->strp, sk, &cb); +} + +static void smap_init_progs(struct smap_psock *psock, + struct bpf_stab *stab, + struct bpf_prog *verdict, + struct bpf_prog *parse) +{ + struct bpf_prog *orig_parse, *orig_verdict; + + orig_parse = xchg(&psock->bpf_parse, parse); + orig_verdict = xchg(&psock->bpf_verdict, verdict); + + if (orig_verdict) + bpf_prog_put(orig_verdict); + if (orig_parse) + bpf_prog_put(orig_parse); +} + +static void smap_start_sock(struct smap_psock *psock, struct sock *sk) +{ + if (sk->sk_data_ready == smap_data_ready) + return; + psock->save_data_ready = sk->sk_data_ready; + psock->save_write_space = sk->sk_write_space; + psock->save_state_change = sk->sk_state_change; + sk->sk_data_ready = smap_data_ready; + sk->sk_write_space = smap_write_space; + sk->sk_state_change = smap_state_change; + psock->strp_enabled = true; +} + +static void sock_map_remove_complete(struct bpf_stab *stab) +{ + bpf_map_area_free(stab->sock_map); + kfree(stab); +} + +static void smap_gc_work(struct work_struct *w) +{ + struct smap_psock_map_entry *e, *tmp; + struct smap_psock *psock; + + psock = container_of(w, struct smap_psock, gc_work); + + /* no callback lock needed because we already detached sockmap ops */ + if (psock->strp_enabled) + strp_done(&psock->strp); + + cancel_work_sync(&psock->tx_work); + __skb_queue_purge(&psock->rxqueue); + + /* At this point all strparser and xmit work must be complete */ + if (psock->bpf_parse) + bpf_prog_put(psock->bpf_parse); + if (psock->bpf_verdict) + bpf_prog_put(psock->bpf_verdict); + + list_for_each_entry_safe(e, tmp, &psock->maps, list) { + list_del(&e->list); + kfree(e); + } + + sock_put(psock->sock); + kfree(psock); +} + +static struct smap_psock *smap_init_psock(struct sock *sock, + struct bpf_stab *stab) +{ + struct smap_psock *psock; + + psock = kzalloc_node(sizeof(struct smap_psock), + GFP_ATOMIC | __GFP_NOWARN, + stab->map.numa_node); + if (!psock) + return ERR_PTR(-ENOMEM); + + psock->sock = sock; + skb_queue_head_init(&psock->rxqueue); + INIT_WORK(&psock->tx_work, smap_tx_work); + INIT_WORK(&psock->gc_work, smap_gc_work); + INIT_LIST_HEAD(&psock->maps); + psock->refcnt = 1; + + rcu_assign_sk_user_data(sock, psock); + sock_hold(sock); + return psock; +} + +static struct bpf_map *sock_map_alloc(union bpf_attr *attr) +{ + struct bpf_stab *stab; + int err = -EINVAL; + u64 cost; + + /* check sanity of attributes */ + if (attr->max_entries == 0 || attr->key_size != 4 || + attr->value_size != 4 || attr->map_flags & ~BPF_F_NUMA_NODE) + return ERR_PTR(-EINVAL); + + if (attr->value_size > KMALLOC_MAX_SIZE) + return ERR_PTR(-E2BIG); + + stab = kzalloc(sizeof(*stab), GFP_USER); + if (!stab) + return ERR_PTR(-ENOMEM); + + /* mandatory map attributes */ + stab->map.map_type = attr->map_type; + stab->map.key_size = attr->key_size; + stab->map.value_size = attr->value_size; + stab->map.max_entries = attr->max_entries; + stab->map.map_flags = attr->map_flags; + stab->map.numa_node = bpf_map_attr_numa_node(attr); + + /* make sure page count doesn't overflow */ + cost = (u64) stab->map.max_entries * sizeof(struct sock *); + if (cost >= U32_MAX - PAGE_SIZE) + goto free_stab; + + stab->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; + + /* if map size is larger than memlock limit, reject it early */ + err = bpf_map_precharge_memlock(stab->map.pages); + if (err) + goto free_stab; + + err = -ENOMEM; + stab->sock_map = bpf_map_area_alloc(stab->map.max_entries * + sizeof(struct sock *), + stab->map.numa_node); + if (!stab->sock_map) + goto free_stab; + + return &stab->map; +free_stab: + kfree(stab); + return ERR_PTR(err); +} + +static void smap_list_remove(struct smap_psock *psock, struct sock **entry) +{ + struct smap_psock_map_entry *e, *tmp; + + list_for_each_entry_safe(e, tmp, &psock->maps, list) { + if (e->entry == entry) { + list_del(&e->list); + break; + } + } +} + +static void sock_map_free(struct bpf_map *map) +{ + struct bpf_stab *stab = container_of(map, struct bpf_stab, map); + int i; + + synchronize_rcu(); + + /* At this point no update, lookup or delete operations can happen. + * However, be aware we can still get a socket state event updates, + * and data ready callabacks that reference the psock from sk_user_data + * Also psock worker threads are still in-flight. So smap_release_sock + * will only free the psock after cancel_sync on the worker threads + * and a grace period expire to ensure psock is really safe to remove. + */ + rcu_read_lock(); + for (i = 0; i < stab->map.max_entries; i++) { + struct smap_psock *psock; + struct sock *sock; + + sock = xchg(&stab->sock_map[i], NULL); + if (!sock) + continue; + + write_lock_bh(&sock->sk_callback_lock); + psock = smap_psock_sk(sock); + smap_list_remove(psock, &stab->sock_map[i]); + smap_release_sock(psock, sock); + write_unlock_bh(&sock->sk_callback_lock); + } + rcu_read_unlock(); + + if (stab->bpf_verdict) + bpf_prog_put(stab->bpf_verdict); + if (stab->bpf_parse) + bpf_prog_put(stab->bpf_parse); + + sock_map_remove_complete(stab); +} + +static int sock_map_get_next_key(struct bpf_map *map, void *key, void *next_key) +{ + struct bpf_stab *stab = container_of(map, struct bpf_stab, map); + u32 i = key ? *(u32 *)key : U32_MAX; + u32 *next = (u32 *)next_key; + + if (i >= stab->map.max_entries) { + *next = 0; + return 0; + } + + if (i == stab->map.max_entries - 1) + return -ENOENT; + + *next = i + 1; + return 0; +} + +struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) +{ + struct bpf_stab *stab = container_of(map, struct bpf_stab, map); + + if (key >= map->max_entries) + return NULL; + + return READ_ONCE(stab->sock_map[key]); +} + +static int sock_map_delete_elem(struct bpf_map *map, void *key) +{ + struct bpf_stab *stab = container_of(map, struct bpf_stab, map); + struct smap_psock *psock; + int k = *(u32 *)key; + struct sock *sock; + + if (k >= map->max_entries) + return -EINVAL; + + sock = xchg(&stab->sock_map[k], NULL); + if (!sock) + return -EINVAL; + + write_lock_bh(&sock->sk_callback_lock); + psock = smap_psock_sk(sock); + if (!psock) + goto out; + + if (psock->bpf_parse) + smap_stop_sock(psock, sock); + smap_list_remove(psock, &stab->sock_map[k]); + smap_release_sock(psock, sock); +out: + write_unlock_bh(&sock->sk_callback_lock); + return 0; +} + +/* Locking notes: Concurrent updates, deletes, and lookups are allowed and are + * done inside rcu critical sections. This ensures on updates that the psock + * will not be released via smap_release_sock() until concurrent updates/deletes + * complete. All operations operate on sock_map using cmpxchg and xchg + * operations to ensure we do not get stale references. Any reads into the + * map must be done with READ_ONCE() because of this. + * + * A psock is destroyed via call_rcu and after any worker threads are cancelled + * and syncd so we are certain all references from the update/lookup/delete + * operations as well as references in the data path are no longer in use. + * + * Psocks may exist in multiple maps, but only a single set of parse/verdict + * programs may be inherited from the maps it belongs to. A reference count + * is kept with the total number of references to the psock from all maps. The + * psock will not be released until this reaches zero. The psock and sock + * user data data use the sk_callback_lock to protect critical data structures + * from concurrent access. This allows us to avoid two updates from modifying + * the user data in sock and the lock is required anyways for modifying + * callbacks, we simply increase its scope slightly. + * + * Rules to follow, + * - psock must always be read inside RCU critical section + * - sk_user_data must only be modified inside sk_callback_lock and read + * inside RCU critical section. + * - psock->maps list must only be read & modified inside sk_callback_lock + * - sock_map must use READ_ONCE and (cmp)xchg operations + * - BPF verdict/parse programs must use READ_ONCE and xchg operations + */ +static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops, + struct bpf_map *map, + void *key, u64 flags) +{ + struct bpf_stab *stab = container_of(map, struct bpf_stab, map); + struct smap_psock_map_entry *e = NULL; + struct bpf_prog *verdict, *parse; + struct sock *osock, *sock; + struct smap_psock *psock; + u32 i = *(u32 *)key; + int err; + + if (unlikely(flags > BPF_EXIST)) + return -EINVAL; + + if (unlikely(i >= stab->map.max_entries)) + return -E2BIG; + + sock = READ_ONCE(stab->sock_map[i]); + if (flags == BPF_EXIST && !sock) + return -ENOENT; + else if (flags == BPF_NOEXIST && sock) + return -EEXIST; + + sock = skops->sk; + + /* 1. If sock map has BPF programs those will be inherited by the + * sock being added. If the sock is already attached to BPF programs + * this results in an error. + */ + verdict = READ_ONCE(stab->bpf_verdict); + parse = READ_ONCE(stab->bpf_parse); + + if (parse && verdict) { + /* bpf prog refcnt may be zero if a concurrent attach operation + * removes the program after the above READ_ONCE() but before + * we increment the refcnt. If this is the case abort with an + * error. + */ + verdict = bpf_prog_inc_not_zero(stab->bpf_verdict); + if (IS_ERR(verdict)) + return PTR_ERR(verdict); + + parse = bpf_prog_inc_not_zero(stab->bpf_parse); + if (IS_ERR(parse)) { + bpf_prog_put(verdict); + return PTR_ERR(parse); + } + } + + write_lock_bh(&sock->sk_callback_lock); + psock = smap_psock_sk(sock); + + /* 2. Do not allow inheriting programs if psock exists and has + * already inherited programs. This would create confusion on + * which parser/verdict program is running. If no psock exists + * create one. Inside sk_callback_lock to ensure concurrent create + * doesn't update user data. + */ + if (psock) { + if (READ_ONCE(psock->bpf_parse) && parse) { + err = -EBUSY; + goto out_progs; + } + psock->refcnt++; + } else { + psock = smap_init_psock(sock, stab); + if (IS_ERR(psock)) { + err = PTR_ERR(psock); + goto out_progs; + } + + set_bit(SMAP_TX_RUNNING, &psock->state); + } + + e = kzalloc(sizeof(*e), GFP_ATOMIC | __GFP_NOWARN); + if (!e) { + err = -ENOMEM; + goto out_progs; + } + e->entry = &stab->sock_map[i]; + + /* 3. At this point we have a reference to a valid psock that is + * running. Attach any BPF programs needed. + */ + if (parse && verdict && !psock->strp_enabled) { + err = smap_init_sock(psock, sock); + if (err) + goto out_free; + smap_init_progs(psock, stab, verdict, parse); + smap_start_sock(psock, sock); + } + + /* 4. Place psock in sockmap for use and stop any programs on + * the old sock assuming its not the same sock we are replacing + * it with. Because we can only have a single set of programs if + * old_sock has a strp we can stop it. + */ + list_add_tail(&e->list, &psock->maps); + write_unlock_bh(&sock->sk_callback_lock); + + osock = xchg(&stab->sock_map[i], sock); + if (osock) { + struct smap_psock *opsock = smap_psock_sk(osock); + + write_lock_bh(&osock->sk_callback_lock); + if (osock != sock && parse) + smap_stop_sock(opsock, osock); + smap_list_remove(opsock, &stab->sock_map[i]); + smap_release_sock(opsock, osock); + write_unlock_bh(&osock->sk_callback_lock); + } + return 0; +out_free: + smap_release_sock(psock, sock); +out_progs: + if (verdict) + bpf_prog_put(verdict); + if (parse) + bpf_prog_put(parse); + write_unlock_bh(&sock->sk_callback_lock); + kfree(e); + return err; +} + +int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) +{ + struct bpf_stab *stab = container_of(map, struct bpf_stab, map); + struct bpf_prog *orig; + + if (unlikely(map->map_type != BPF_MAP_TYPE_SOCKMAP)) + return -EINVAL; + + switch (type) { + case BPF_SK_SKB_STREAM_PARSER: + orig = xchg(&stab->bpf_parse, prog); + break; + case BPF_SK_SKB_STREAM_VERDICT: + orig = xchg(&stab->bpf_verdict, prog); + break; + default: + return -EOPNOTSUPP; + } + + if (orig) + bpf_prog_put(orig); + + return 0; +} + +static void *sock_map_lookup(struct bpf_map *map, void *key) +{ + return NULL; +} + +static int sock_map_update_elem(struct bpf_map *map, + void *key, void *value, u64 flags) +{ + struct bpf_sock_ops_kern skops; + u32 fd = *(u32 *)value; + struct socket *socket; + int err; + + socket = sockfd_lookup(fd, &err); + if (!socket) + return err; + + skops.sk = socket->sk; + if (!skops.sk) { + fput(socket->file); + return -EINVAL; + } + + err = sock_map_ctx_update_elem(&skops, map, key, flags); + fput(socket->file); + return err; +} + +const struct bpf_map_ops sock_map_ops = { + .map_alloc = sock_map_alloc, + .map_free = sock_map_free, + .map_lookup_elem = sock_map_lookup, + .map_get_next_key = sock_map_get_next_key, + .map_update_elem = sock_map_update_elem, + .map_delete_elem = sock_map_delete_elem, +}; + +BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, + struct bpf_map *, map, void *, key, u64, flags) +{ + WARN_ON_ONCE(!rcu_read_lock_held()); + return sock_map_ctx_update_elem(bpf_sock, map, key, flags); +} + +const struct bpf_func_proto bpf_sock_map_update_proto = { + .func = bpf_sock_map_update, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_CONST_MAP_PTR, + .arg3_type = ARG_PTR_TO_MAP_KEY, + .arg4_type = ARG_ANYTHING, +}; diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index 31147d730abf532cc8f10efc9a871b5dd498928d..135be433e9a0fb9a3c18e96db336cf1817be1c1c 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -31,7 +31,8 @@ static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; int err; - smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries); + smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, + smap->map.numa_node); if (!smap->elems) return -ENOMEM; @@ -59,7 +60,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) if (!capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); - if (attr->map_flags) + if (attr->map_flags & ~BPF_F_NUMA_NODE) return ERR_PTR(-EINVAL); /* check sanity of attributes */ @@ -75,7 +76,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) if (cost >= U32_MAX - PAGE_SIZE) return ERR_PTR(-E2BIG); - smap = bpf_map_area_alloc(cost); + smap = bpf_map_area_alloc(cost, bpf_map_attr_numa_node(attr)); if (!smap) return ERR_PTR(-ENOMEM); @@ -91,6 +92,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) smap->map.map_flags = attr->map_flags; smap->n_buckets = n_buckets; smap->map.pages = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; + smap->map.numa_node = bpf_map_attr_numa_node(attr); err = bpf_map_precharge_memlock(smap->map.pages); if (err) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 045646da97cc5dc55a5063301a2e76e4178a8ea3..25d074920a009ff682d97bf88e68f466c79bd564 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -48,6 +48,47 @@ static const struct bpf_map_ops * const bpf_map_types[] = { #undef BPF_MAP_TYPE }; +/* + * If we're handed a bigger struct than we know of, ensure all the unknown bits + * are 0 - i.e. new user-space does not rely on any kernel feature extensions + * we don't know about yet. + * + * There is a ToCToU between this function call and the following + * copy_from_user() call. However, this is not a concern since this function is + * meant to be a future-proofing of bits. + */ +static int check_uarg_tail_zero(void __user *uaddr, + size_t expected_size, + size_t actual_size) +{ + unsigned char __user *addr; + unsigned char __user *end; + unsigned char val; + int err; + + if (unlikely(actual_size > PAGE_SIZE)) /* silly large */ + return -E2BIG; + + if (unlikely(!access_ok(VERIFY_READ, uaddr, actual_size))) + return -EFAULT; + + if (actual_size <= expected_size) + return 0; + + addr = uaddr + expected_size; + end = uaddr + actual_size; + + for (; addr < end; addr++) { + err = get_user(val, addr); + if (err) + return err; + if (val) + return -E2BIG; + } + + return 0; +} + static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) { struct bpf_map *map; @@ -64,7 +105,7 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) return map; } -void *bpf_map_area_alloc(size_t size) +void *bpf_map_area_alloc(size_t size, int numa_node) { /* We definitely need __GFP_NORETRY, so OOM killer doesn't * trigger under memory pressure as we really just want to @@ -74,12 +115,13 @@ void *bpf_map_area_alloc(size_t size) void *area; if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { - area = kmalloc(size, GFP_USER | flags); + area = kmalloc_node(size, GFP_USER | flags, numa_node); if (area != NULL) return area; } - return __vmalloc(size, GFP_KERNEL | flags, PAGE_KERNEL); + return __vmalloc_node_flags_caller(size, numa_node, GFP_KERNEL | flags, + __builtin_return_address(0)); } void bpf_map_area_free(void *area) @@ -144,15 +186,17 @@ static int bpf_map_alloc_id(struct bpf_map *map) static void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock) { + unsigned long flags; + if (do_idr_lock) - spin_lock_bh(&map_idr_lock); + spin_lock_irqsave(&map_idr_lock, flags); else __acquire(&map_idr_lock); idr_remove(&map_idr, map->id); if (do_idr_lock) - spin_unlock_bh(&map_idr_lock); + spin_unlock_irqrestore(&map_idr_lock, flags); else __release(&map_idr_lock); } @@ -268,10 +312,11 @@ int bpf_map_new_fd(struct bpf_map *map) offsetof(union bpf_attr, CMD##_LAST_FIELD) - \ sizeof(attr->CMD##_LAST_FIELD)) != NULL -#define BPF_MAP_CREATE_LAST_FIELD inner_map_fd +#define BPF_MAP_CREATE_LAST_FIELD numa_node /* called via syscall */ static int map_create(union bpf_attr *attr) { + int numa_node = bpf_map_attr_numa_node(attr); struct bpf_map *map; int err; @@ -279,6 +324,11 @@ static int map_create(union bpf_attr *attr) if (err) return -EINVAL; + if (numa_node != NUMA_NO_NODE && + ((unsigned int)numa_node >= nr_node_ids || + !node_online(numa_node))) + return -EINVAL; + /* find map type and init map: hashtable vs rbtree vs bloom vs ... */ map = find_and_alloc_map(attr); if (IS_ERR(map)) @@ -870,7 +920,7 @@ struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog) EXPORT_SYMBOL_GPL(bpf_prog_inc); /* prog_idr_lock should have been held */ -static struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog) +struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog) { int refold; @@ -886,6 +936,7 @@ static struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog) return prog; } +EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type) { @@ -1047,6 +1098,40 @@ static int bpf_obj_get(const union bpf_attr *attr) #define BPF_PROG_ATTACH_LAST_FIELD attach_flags +static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach) +{ + struct bpf_prog *prog = NULL; + int ufd = attr->target_fd; + struct bpf_map *map; + struct fd f; + int err; + + f = fdget(ufd); + map = __bpf_map_get(f); + if (IS_ERR(map)) + return PTR_ERR(map); + + if (attach) { + prog = bpf_prog_get_type(attr->attach_bpf_fd, + BPF_PROG_TYPE_SK_SKB); + if (IS_ERR(prog)) { + fdput(f); + return PTR_ERR(prog); + } + } + + err = sock_map_prog(map, prog, attr->attach_type); + if (err) { + fdput(f); + if (prog) + bpf_prog_put(prog); + return err; + } + + fdput(f); + return 0; +} + static int bpf_prog_attach(const union bpf_attr *attr) { enum bpf_prog_type ptype; @@ -1074,6 +1159,9 @@ static int bpf_prog_attach(const union bpf_attr *attr) case BPF_CGROUP_SOCK_OPS: ptype = BPF_PROG_TYPE_SOCK_OPS; break; + case BPF_SK_SKB_STREAM_PARSER: + case BPF_SK_SKB_STREAM_VERDICT: + return sockmap_get_from_fd(attr, true); default: return -EINVAL; } @@ -1122,7 +1210,10 @@ static int bpf_prog_detach(const union bpf_attr *attr) ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false); cgroup_put(cgrp); break; - + case BPF_SK_SKB_STREAM_PARSER: + case BPF_SK_SKB_STREAM_VERDICT: + ret = sockmap_get_from_fd(attr, false); + break; default: return -EINVAL; } @@ -1246,32 +1337,6 @@ static int bpf_map_get_fd_by_id(const union bpf_attr *attr) return fd; } -static int check_uarg_tail_zero(void __user *uaddr, - size_t expected_size, - size_t actual_size) -{ - unsigned char __user *addr; - unsigned char __user *end; - unsigned char val; - int err; - - if (actual_size <= expected_size) - return 0; - - addr = uaddr + expected_size; - end = uaddr + actual_size; - - for (; addr < end; addr++) { - err = get_user(val, addr); - if (err) - return err; - if (val) - return -E2BIG; - } - - return 0; -} - static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, const union bpf_attr *attr, union bpf_attr __user *uattr) @@ -1289,7 +1354,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, info_len = min_t(u32, sizeof(info), info_len); if (copy_from_user(&info, uinfo, info_len)) - return err; + return -EFAULT; info.type = prog->type; info.id = prog->aux->id; @@ -1312,7 +1377,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, } ulen = info.xlated_prog_len; - info.xlated_prog_len = bpf_prog_size(prog->len); + info.xlated_prog_len = bpf_prog_insn_size(prog); if (info.xlated_prog_len && ulen) { uinsns = u64_to_user_ptr(info.xlated_prog_insns); ulen = min_t(u32, info.xlated_prog_len, ulen); @@ -1393,17 +1458,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled) return -EPERM; - if (!access_ok(VERIFY_READ, uattr, 1)) - return -EFAULT; - - if (size > PAGE_SIZE) /* silly large */ - return -E2BIG; - - /* If we're handed a bigger struct than we know of, - * ensure all the unknown bits are 0 - i.e. new - * user-space does not rely on any kernel feature - * extensions we dont know about yet. - */ err = check_uarg_tail_zero(uattr, sizeof(attr), size); if (err) return err; diff --git a/kernel/bpf/tnum.c b/kernel/bpf/tnum.c new file mode 100644 index 0000000000000000000000000000000000000000..1f4bf68c12dbbb88118d32c939616b43cebcf070 --- /dev/null +++ b/kernel/bpf/tnum.c @@ -0,0 +1,180 @@ +/* tnum: tracked (or tristate) numbers + * + * A tnum tracks knowledge about the bits of a value. Each bit can be either + * known (0 or 1), or unknown (x). Arithmetic operations on tnums will + * propagate the unknown bits such that the tnum result represents all the + * possible results for possible values of the operands. + */ +#include +#include + +#define TNUM(_v, _m) (struct tnum){.value = _v, .mask = _m} +/* A completely unknown value */ +const struct tnum tnum_unknown = { .value = 0, .mask = -1 }; + +struct tnum tnum_const(u64 value) +{ + return TNUM(value, 0); +} + +struct tnum tnum_range(u64 min, u64 max) +{ + u64 chi = min ^ max, delta; + u8 bits = fls64(chi); + + /* special case, needed because 1ULL << 64 is undefined */ + if (bits > 63) + return tnum_unknown; + /* e.g. if chi = 4, bits = 3, delta = (1<<3) - 1 = 7. + * if chi = 0, bits = 0, delta = (1<<0) - 1 = 0, so we return + * constant min (since min == max). + */ + delta = (1ULL << bits) - 1; + return TNUM(min & ~delta, delta); +} + +struct tnum tnum_lshift(struct tnum a, u8 shift) +{ + return TNUM(a.value << shift, a.mask << shift); +} + +struct tnum tnum_rshift(struct tnum a, u8 shift) +{ + return TNUM(a.value >> shift, a.mask >> shift); +} + +struct tnum tnum_add(struct tnum a, struct tnum b) +{ + u64 sm, sv, sigma, chi, mu; + + sm = a.mask + b.mask; + sv = a.value + b.value; + sigma = sm + sv; + chi = sigma ^ sv; + mu = chi | a.mask | b.mask; + return TNUM(sv & ~mu, mu); +} + +struct tnum tnum_sub(struct tnum a, struct tnum b) +{ + u64 dv, alpha, beta, chi, mu; + + dv = a.value - b.value; + alpha = dv + a.mask; + beta = dv - b.mask; + chi = alpha ^ beta; + mu = chi | a.mask | b.mask; + return TNUM(dv & ~mu, mu); +} + +struct tnum tnum_and(struct tnum a, struct tnum b) +{ + u64 alpha, beta, v; + + alpha = a.value | a.mask; + beta = b.value | b.mask; + v = a.value & b.value; + return TNUM(v, alpha & beta & ~v); +} + +struct tnum tnum_or(struct tnum a, struct tnum b) +{ + u64 v, mu; + + v = a.value | b.value; + mu = a.mask | b.mask; + return TNUM(v, mu & ~v); +} + +struct tnum tnum_xor(struct tnum a, struct tnum b) +{ + u64 v, mu; + + v = a.value ^ b.value; + mu = a.mask | b.mask; + return TNUM(v & ~mu, mu); +} + +/* half-multiply add: acc += (unknown * mask * value). + * An intermediate step in the multiply algorithm. + */ +static struct tnum hma(struct tnum acc, u64 value, u64 mask) +{ + while (mask) { + if (mask & 1) + acc = tnum_add(acc, TNUM(0, value)); + mask >>= 1; + value <<= 1; + } + return acc; +} + +struct tnum tnum_mul(struct tnum a, struct tnum b) +{ + struct tnum acc; + u64 pi; + + pi = a.value * b.value; + acc = hma(TNUM(pi, 0), a.mask, b.mask | b.value); + return hma(acc, b.mask, a.value); +} + +/* Note that if a and b disagree - i.e. one has a 'known 1' where the other has + * a 'known 0' - this will return a 'known 1' for that bit. + */ +struct tnum tnum_intersect(struct tnum a, struct tnum b) +{ + u64 v, mu; + + v = a.value | b.value; + mu = a.mask & b.mask; + return TNUM(v & ~mu, mu); +} + +struct tnum tnum_cast(struct tnum a, u8 size) +{ + a.value &= (1ULL << (size * 8)) - 1; + a.mask &= (1ULL << (size * 8)) - 1; + return a; +} + +bool tnum_is_aligned(struct tnum a, u64 size) +{ + if (!size) + return true; + return !((a.value | a.mask) & (size - 1)); +} + +bool tnum_in(struct tnum a, struct tnum b) +{ + if (b.mask & ~a.mask) + return false; + b.value &= ~a.mask; + return a.value == b.value; +} + +int tnum_strn(char *str, size_t size, struct tnum a) +{ + return snprintf(str, size, "(%#llx; %#llx)", a.value, a.mask); +} +EXPORT_SYMBOL_GPL(tnum_strn); + +int tnum_sbin(char *str, size_t size, struct tnum a) +{ + size_t n; + + for (n = 64; n; n--) { + if (n < size) { + if (a.mask & 1) + str[n - 1] = 'x'; + else if (a.value & 1) + str[n - 1] = '1'; + else + str[n - 1] = '0'; + } + a.mask >>= 1; + a.value >>= 1; + } + str[min(size - 1, (size_t)64)] = 0; + return 64; +} diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index af9e84a4944e60fdd617c0c69ecbc46d53e230ac..b914fbe1383e83fa9609944bc54358456794f470 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -61,12 +61,12 @@ * (and -20 constant is saved for further stack bounds checking). * Meaning that this reg is a pointer to stack plus known immediate constant. * - * Most of the time the registers have UNKNOWN_VALUE type, which + * Most of the time the registers have SCALAR_VALUE type, which * means the register has some value, but it's not a valid pointer. - * (like pointer plus pointer becomes UNKNOWN_VALUE type) + * (like pointer plus pointer becomes SCALAR_VALUE type) * * When verifier sees load or store instructions the type of base register - * can be: PTR_TO_MAP_VALUE, PTR_TO_CTX, FRAME_PTR. These are three pointer + * can be: PTR_TO_MAP_VALUE, PTR_TO_CTX, PTR_TO_STACK. These are three pointer * types recognized by check_mem_access() function. * * PTR_TO_MAP_VALUE means that this register is pointing to 'map element value' @@ -140,7 +140,7 @@ struct bpf_verifier_stack_elem { struct bpf_verifier_stack_elem *next; }; -#define BPF_COMPLEXITY_LIMIT_INSNS 98304 +#define BPF_COMPLEXITY_LIMIT_INSNS 131072 #define BPF_COMPLEXITY_LIMIT_STACK 1024 #define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA) @@ -180,15 +180,12 @@ static __printf(1, 2) void verbose(const char *fmt, ...) /* string representation of 'enum bpf_reg_type' */ static const char * const reg_type_str[] = { [NOT_INIT] = "?", - [UNKNOWN_VALUE] = "inv", + [SCALAR_VALUE] = "inv", [PTR_TO_CTX] = "ctx", [CONST_PTR_TO_MAP] = "map_ptr", [PTR_TO_MAP_VALUE] = "map_value", [PTR_TO_MAP_VALUE_OR_NULL] = "map_value_or_null", - [PTR_TO_MAP_VALUE_ADJ] = "map_value_adj", - [FRAME_PTR] = "fp", [PTR_TO_STACK] = "fp", - [CONST_IMM] = "imm", [PTR_TO_PACKET] = "pkt", [PTR_TO_PACKET_END] = "pkt_end", }; @@ -221,32 +218,52 @@ static void print_verifier_state(struct bpf_verifier_state *state) if (t == NOT_INIT) continue; verbose(" R%d=%s", i, reg_type_str[t]); - if (t == CONST_IMM || t == PTR_TO_STACK) - verbose("%lld", reg->imm); - else if (t == PTR_TO_PACKET) - verbose("(id=%d,off=%d,r=%d)", - reg->id, reg->off, reg->range); - else if (t == UNKNOWN_VALUE && reg->imm) - verbose("%lld", reg->imm); - else if (t == CONST_PTR_TO_MAP || t == PTR_TO_MAP_VALUE || - t == PTR_TO_MAP_VALUE_OR_NULL || - t == PTR_TO_MAP_VALUE_ADJ) - verbose("(ks=%d,vs=%d,id=%u)", - reg->map_ptr->key_size, - reg->map_ptr->value_size, - reg->id); - if (reg->min_value != BPF_REGISTER_MIN_RANGE) - verbose(",min_value=%lld", - (long long)reg->min_value); - if (reg->max_value != BPF_REGISTER_MAX_RANGE) - verbose(",max_value=%llu", - (unsigned long long)reg->max_value); - if (reg->min_align) - verbose(",min_align=%u", reg->min_align); - if (reg->aux_off) - verbose(",aux_off=%u", reg->aux_off); - if (reg->aux_off_align) - verbose(",aux_off_align=%u", reg->aux_off_align); + if ((t == SCALAR_VALUE || t == PTR_TO_STACK) && + tnum_is_const(reg->var_off)) { + /* reg->off should be 0 for SCALAR_VALUE */ + verbose("%lld", reg->var_off.value + reg->off); + } else { + verbose("(id=%d", reg->id); + if (t != SCALAR_VALUE) + verbose(",off=%d", reg->off); + if (t == PTR_TO_PACKET) + verbose(",r=%d", reg->range); + else if (t == CONST_PTR_TO_MAP || + t == PTR_TO_MAP_VALUE || + t == PTR_TO_MAP_VALUE_OR_NULL) + verbose(",ks=%d,vs=%d", + reg->map_ptr->key_size, + reg->map_ptr->value_size); + if (tnum_is_const(reg->var_off)) { + /* Typically an immediate SCALAR_VALUE, but + * could be a pointer whose offset is too big + * for reg->off + */ + verbose(",imm=%llx", reg->var_off.value); + } else { + if (reg->smin_value != reg->umin_value && + reg->smin_value != S64_MIN) + verbose(",smin_value=%lld", + (long long)reg->smin_value); + if (reg->smax_value != reg->umax_value && + reg->smax_value != S64_MAX) + verbose(",smax_value=%lld", + (long long)reg->smax_value); + if (reg->umin_value != 0) + verbose(",umin_value=%llu", + (unsigned long long)reg->umin_value); + if (reg->umax_value != U64_MAX) + verbose(",umax_value=%llu", + (unsigned long long)reg->umax_value); + if (!tnum_is_unknown(reg->var_off)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); + verbose(",var_off=%s", tn_buf); + } + } + verbose(")"); + } } for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { if (state->stack_slot_type[i] == STACK_SPILL) @@ -295,11 +312,15 @@ static const char *const bpf_jmp_string[16] = { [BPF_JA >> 4] = "jmp", [BPF_JEQ >> 4] = "==", [BPF_JGT >> 4] = ">", + [BPF_JLT >> 4] = "<", [BPF_JGE >> 4] = ">=", + [BPF_JLE >> 4] = "<=", [BPF_JSET >> 4] = "&", [BPF_JNE >> 4] = "!=", [BPF_JSGT >> 4] = "s>", + [BPF_JSLT >> 4] = "s<", [BPF_JSGE >> 4] = "s>=", + [BPF_JSLE >> 4] = "s<=", [BPF_CALL >> 4] = "call", [BPF_EXIT >> 4] = "exit", }; @@ -463,56 +484,163 @@ static const int caller_saved[CALLER_SAVED_REGS] = { BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5 }; -static void mark_reg_not_init(struct bpf_reg_state *regs, u32 regno) +static void __mark_reg_not_init(struct bpf_reg_state *reg); + +/* Mark the unknown part of a register (variable offset or scalar value) as + * known to have the value @imm. + */ +static void __mark_reg_known(struct bpf_reg_state *reg, u64 imm) { - BUG_ON(regno >= MAX_BPF_REG); + reg->id = 0; + reg->var_off = tnum_const(imm); + reg->smin_value = (s64)imm; + reg->smax_value = (s64)imm; + reg->umin_value = imm; + reg->umax_value = imm; +} - memset(®s[regno], 0, sizeof(regs[regno])); - regs[regno].type = NOT_INIT; - regs[regno].min_value = BPF_REGISTER_MIN_RANGE; - regs[regno].max_value = BPF_REGISTER_MAX_RANGE; +/* Mark the 'variable offset' part of a register as zero. This should be + * used only on registers holding a pointer type. + */ +static void __mark_reg_known_zero(struct bpf_reg_state *reg) +{ + __mark_reg_known(reg, 0); } -static void init_reg_state(struct bpf_reg_state *regs) +static void mark_reg_known_zero(struct bpf_reg_state *regs, u32 regno) { - int i; + if (WARN_ON(regno >= MAX_BPF_REG)) { + verbose("mark_reg_known_zero(regs, %u)\n", regno); + /* Something bad happened, let's kill all regs */ + for (regno = 0; regno < MAX_BPF_REG; regno++) + __mark_reg_not_init(regs + regno); + return; + } + __mark_reg_known_zero(regs + regno); +} - for (i = 0; i < MAX_BPF_REG; i++) - mark_reg_not_init(regs, i); +/* Attempts to improve min/max values based on var_off information */ +static void __update_reg_bounds(struct bpf_reg_state *reg) +{ + /* min signed is max(sign bit) | min(other bits) */ + reg->smin_value = max_t(s64, reg->smin_value, + reg->var_off.value | (reg->var_off.mask & S64_MIN)); + /* max signed is min(sign bit) | max(other bits) */ + reg->smax_value = min_t(s64, reg->smax_value, + reg->var_off.value | (reg->var_off.mask & S64_MAX)); + reg->umin_value = max(reg->umin_value, reg->var_off.value); + reg->umax_value = min(reg->umax_value, + reg->var_off.value | reg->var_off.mask); +} - /* frame pointer */ - regs[BPF_REG_FP].type = FRAME_PTR; +/* Uses signed min/max values to inform unsigned, and vice-versa */ +static void __reg_deduce_bounds(struct bpf_reg_state *reg) +{ + /* Learn sign from signed bounds. + * If we cannot cross the sign boundary, then signed and unsigned bounds + * are the same, so combine. This works even in the negative case, e.g. + * -3 s<= x s<= -1 implies 0xf...fd u<= x u<= 0xf...ff. + */ + if (reg->smin_value >= 0 || reg->smax_value < 0) { + reg->smin_value = reg->umin_value = max_t(u64, reg->smin_value, + reg->umin_value); + reg->smax_value = reg->umax_value = min_t(u64, reg->smax_value, + reg->umax_value); + return; + } + /* Learn sign from unsigned bounds. Signed bounds cross the sign + * boundary, so we must be careful. + */ + if ((s64)reg->umax_value >= 0) { + /* Positive. We can't learn anything from the smin, but smax + * is positive, hence safe. + */ + reg->smin_value = reg->umin_value; + reg->smax_value = reg->umax_value = min_t(u64, reg->smax_value, + reg->umax_value); + } else if ((s64)reg->umin_value < 0) { + /* Negative. We can't learn anything from the smax, but smin + * is negative, hence safe. + */ + reg->smin_value = reg->umin_value = max_t(u64, reg->smin_value, + reg->umin_value); + reg->smax_value = reg->umax_value; + } +} - /* 1st arg to a function */ - regs[BPF_REG_1].type = PTR_TO_CTX; +/* Attempts to improve var_off based on unsigned min/max information */ +static void __reg_bound_offset(struct bpf_reg_state *reg) +{ + reg->var_off = tnum_intersect(reg->var_off, + tnum_range(reg->umin_value, + reg->umax_value)); } -static void __mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno) +/* Reset the min/max bounds of a register */ +static void __mark_reg_unbounded(struct bpf_reg_state *reg) { - regs[regno].type = UNKNOWN_VALUE; - regs[regno].id = 0; - regs[regno].imm = 0; + reg->smin_value = S64_MIN; + reg->smax_value = S64_MAX; + reg->umin_value = 0; + reg->umax_value = U64_MAX; } -static void mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno) +/* Mark a register as having a completely unknown (scalar) value. */ +static void __mark_reg_unknown(struct bpf_reg_state *reg) { - BUG_ON(regno >= MAX_BPF_REG); - __mark_reg_unknown_value(regs, regno); + reg->type = SCALAR_VALUE; + reg->id = 0; + reg->off = 0; + reg->var_off = tnum_unknown; + __mark_reg_unbounded(reg); } -static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno) +static void mark_reg_unknown(struct bpf_reg_state *regs, u32 regno) { - regs[regno].min_value = BPF_REGISTER_MIN_RANGE; - regs[regno].max_value = BPF_REGISTER_MAX_RANGE; - regs[regno].value_from_signed = false; - regs[regno].min_align = 0; + if (WARN_ON(regno >= MAX_BPF_REG)) { + verbose("mark_reg_unknown(regs, %u)\n", regno); + /* Something bad happened, let's kill all regs */ + for (regno = 0; regno < MAX_BPF_REG; regno++) + __mark_reg_not_init(regs + regno); + return; + } + __mark_reg_unknown(regs + regno); } -static void mark_reg_unknown_value_and_range(struct bpf_reg_state *regs, - u32 regno) +static void __mark_reg_not_init(struct bpf_reg_state *reg) { - mark_reg_unknown_value(regs, regno); - reset_reg_range_values(regs, regno); + __mark_reg_unknown(reg); + reg->type = NOT_INIT; +} + +static void mark_reg_not_init(struct bpf_reg_state *regs, u32 regno) +{ + if (WARN_ON(regno >= MAX_BPF_REG)) { + verbose("mark_reg_not_init(regs, %u)\n", regno); + /* Something bad happened, let's kill all regs */ + for (regno = 0; regno < MAX_BPF_REG; regno++) + __mark_reg_not_init(regs + regno); + return; + } + __mark_reg_not_init(regs + regno); +} + +static void init_reg_state(struct bpf_reg_state *regs) +{ + int i; + + for (i = 0; i < MAX_BPF_REG; i++) { + mark_reg_not_init(regs, i); + regs[i].live = REG_LIVE_NONE; + } + + /* frame pointer */ + regs[BPF_REG_FP].type = PTR_TO_STACK; + mark_reg_known_zero(regs, BPF_REG_FP); + + /* 1st arg to a function */ + regs[BPF_REG_1].type = PTR_TO_CTX; + mark_reg_known_zero(regs, BPF_REG_1); } enum reg_arg_type { @@ -521,9 +649,26 @@ enum reg_arg_type { DST_OP_NO_MARK /* same as above, check only, don't mark */ }; -static int check_reg_arg(struct bpf_reg_state *regs, u32 regno, +static void mark_reg_read(const struct bpf_verifier_state *state, u32 regno) +{ + struct bpf_verifier_state *parent = state->parent; + + while (parent) { + /* if read wasn't screened by an earlier write ... */ + if (state->regs[regno].live & REG_LIVE_WRITTEN) + break; + /* ... then we depend on parent's value */ + parent->regs[regno].live |= REG_LIVE_READ; + state = parent; + parent = state->parent; + } +} + +static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, enum reg_arg_type t) { + struct bpf_reg_state *regs = env->cur_state.regs; + if (regno >= MAX_BPF_REG) { verbose("R%d is invalid\n", regno); return -EINVAL; @@ -535,14 +680,16 @@ static int check_reg_arg(struct bpf_reg_state *regs, u32 regno, verbose("R%d !read_ok\n", regno); return -EACCES; } + mark_reg_read(&env->cur_state, regno); } else { /* check whether register used as dest operand can be written to */ if (regno == BPF_REG_FP) { verbose("frame pointer is read only\n"); return -EACCES; } + regs[regno].live |= REG_LIVE_WRITTEN; if (t == DST_OP) - mark_reg_unknown_value(regs, regno); + mark_reg_unknown(regs, regno); } return 0; } @@ -552,12 +699,10 @@ static bool is_spillable_regtype(enum bpf_reg_type type) switch (type) { case PTR_TO_MAP_VALUE: case PTR_TO_MAP_VALUE_OR_NULL: - case PTR_TO_MAP_VALUE_ADJ: case PTR_TO_STACK: case PTR_TO_CTX: case PTR_TO_PACKET: case PTR_TO_PACKET_END: - case FRAME_PTR: case CONST_PTR_TO_MAP: return true; default: @@ -571,7 +716,7 @@ static bool is_spillable_regtype(enum bpf_reg_type type) static int check_stack_write(struct bpf_verifier_state *state, int off, int size, int value_regno) { - int i; + int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, * so it's aligned access and [off, off + size) are within stack limits */ @@ -586,15 +731,14 @@ static int check_stack_write(struct bpf_verifier_state *state, int off, } /* save register state */ - state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = - state->regs[value_regno]; + state->spilled_regs[spi] = state->regs[value_regno]; + state->spilled_regs[spi].live |= REG_LIVE_WRITTEN; for (i = 0; i < BPF_REG_SIZE; i++) state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_SPILL; } else { /* regular write of data into stack */ - state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = - (struct bpf_reg_state) {}; + state->spilled_regs[spi] = (struct bpf_reg_state) {}; for (i = 0; i < size; i++) state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_MISC; @@ -602,11 +746,26 @@ static int check_stack_write(struct bpf_verifier_state *state, int off, return 0; } +static void mark_stack_slot_read(const struct bpf_verifier_state *state, int slot) +{ + struct bpf_verifier_state *parent = state->parent; + + while (parent) { + /* if read wasn't screened by an earlier write ... */ + if (state->spilled_regs[slot].live & REG_LIVE_WRITTEN) + break; + /* ... then we depend on parent's value */ + parent->spilled_regs[slot].live |= REG_LIVE_READ; + state = parent; + parent = state->parent; + } +} + static int check_stack_read(struct bpf_verifier_state *state, int off, int size, int value_regno) { u8 *slot_type; - int i; + int i, spi; slot_type = &state->stack_slot_type[MAX_BPF_STACK + off]; @@ -622,10 +781,13 @@ static int check_stack_read(struct bpf_verifier_state *state, int off, int size, } } - if (value_regno >= 0) + spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; + + if (value_regno >= 0) { /* restore register state from stack */ - state->regs[value_regno] = - state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE]; + state->regs[value_regno] = state->spilled_regs[spi]; + mark_stack_slot_read(state, spi); + } return 0; } else { for (i = 0; i < size; i++) { @@ -637,14 +799,13 @@ static int check_stack_read(struct bpf_verifier_state *state, int off, int size, } if (value_regno >= 0) /* have read misc data from the stack */ - mark_reg_unknown_value_and_range(state->regs, - value_regno); + mark_reg_unknown(state->regs, value_regno); return 0; } } /* check read/write into map element returned by bpf_map_lookup_elem() */ -static int check_map_access(struct bpf_verifier_env *env, u32 regno, int off, +static int __check_map_access(struct bpf_verifier_env *env, u32 regno, int off, int size) { struct bpf_map *map = env->cur_state.regs[regno].map_ptr; @@ -657,49 +818,50 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno, int off, return 0; } -/* check read/write into an adjusted map element */ -static int check_map_access_adj(struct bpf_verifier_env *env, u32 regno, +/* check read/write into a map element with possible variable offset */ +static int check_map_access(struct bpf_verifier_env *env, u32 regno, int off, int size) { struct bpf_verifier_state *state = &env->cur_state; struct bpf_reg_state *reg = &state->regs[regno]; int err; - /* We adjusted the register to this map value, so we - * need to change off and size to min_value and max_value - * respectively to make sure our theoretical access will be - * safe. + /* We may have adjusted the register to this map value, so we + * need to try adding each of min_value and max_value to off + * to make sure our theoretical access will be safe. */ if (log_level) print_verifier_state(state); - env->varlen_map_value_access = true; /* The minimum value is only important with signed * comparisons where we can't assume the floor of a * value is 0. If we are using signed variables for our * index'es we need to make sure that whatever we use * will have a set floor within our range. */ - if (reg->min_value < 0) { + if (reg->smin_value < 0) { verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", regno); return -EACCES; } - err = check_map_access(env, regno, reg->min_value + off, size); + err = __check_map_access(env, regno, reg->smin_value + off, size); if (err) { - verbose("R%d min value is outside of the array range\n", - regno); + verbose("R%d min value is outside of the array range\n", regno); return err; } - /* If we haven't set a max value then we need to bail - * since we can't be sure we won't do bad things. + /* If we haven't set a max value then we need to bail since we can't be + * sure we won't do bad things. + * If reg->umax_value + off could overflow, treat that as unbounded too. */ - if (reg->max_value == BPF_REGISTER_MAX_RANGE) { + if (reg->umax_value >= BPF_MAX_VAR_OFF) { verbose("R%d unbounded memory access, make sure to bounds check any array access into a map\n", regno); return -EACCES; } - return check_map_access(env, regno, reg->max_value + off, size); + err = __check_map_access(env, regno, reg->umax_value + off, size); + if (err) + verbose("R%d max value is outside of the array range\n", regno); + return err; } #define MAX_PACKET_OFF 0xffff @@ -719,6 +881,7 @@ static bool may_access_direct_pkt_data(struct bpf_verifier_env *env, case BPF_PROG_TYPE_SCHED_ACT: case BPF_PROG_TYPE_XDP: case BPF_PROG_TYPE_LWT_XMIT: + case BPF_PROG_TYPE_SK_SKB: if (meta) return meta->pkt_access; @@ -729,14 +892,13 @@ static bool may_access_direct_pkt_data(struct bpf_verifier_env *env, } } -static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off, - int size) +static int __check_packet_access(struct bpf_verifier_env *env, u32 regno, + int off, int size) { struct bpf_reg_state *regs = env->cur_state.regs; struct bpf_reg_state *reg = ®s[regno]; - off += reg->off; - if (off < 0 || size <= 0 || off + size > reg->range) { + if (off < 0 || size <= 0 || (u64)off + size > reg->range) { verbose("invalid access to packet, off=%d size=%d, R%d(id=%d,off=%d,r=%d)\n", off, size, regno, reg->id, reg->off, reg->range); return -EACCES; @@ -744,7 +906,35 @@ static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off, return 0; } -/* check access to 'struct bpf_context' fields */ +static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off, + int size) +{ + struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *reg = ®s[regno]; + int err; + + /* We may have added a variable offset to the packet pointer; but any + * reg->range we have comes after that. We are only checking the fixed + * offset. + */ + + /* We don't allow negative numbers, because we aren't tracking enough + * detail to prove they're safe. + */ + if (reg->smin_value < 0) { + verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", + regno); + return -EACCES; + } + err = __check_packet_access(env, regno, off, size); + if (err) { + verbose("R%d offset is outside of the packet\n", regno); + return err; + } + return err; +} + +/* check access to 'struct bpf_context' fields. Supports fixed offsets only */ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off, int size, enum bpf_access_type t, enum bpf_reg_type *reg_type) { @@ -784,13 +974,7 @@ static bool __is_pointer_value(bool allow_ptr_leaks, if (allow_ptr_leaks) return false; - switch (reg->type) { - case UNKNOWN_VALUE: - case CONST_IMM: - return false; - default: - return true; - } + return reg->type != SCALAR_VALUE; } static bool is_pointer_value(struct bpf_verifier_env *env, int regno) @@ -801,23 +985,13 @@ static bool is_pointer_value(struct bpf_verifier_env *env, int regno) static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, int off, int size, bool strict) { + struct tnum reg_off; int ip_align; - int reg_off; /* Byte size accesses are always allowed. */ if (!strict || size == 1) return 0; - reg_off = reg->off; - if (reg->id) { - if (reg->aux_off_align % size) { - verbose("Packet access is only %u byte aligned, %d byte access not allowed\n", - reg->aux_off_align, size); - return -EACCES; - } - reg_off += reg->aux_off; - } - /* For platforms that do not have a Kconfig enabling * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS the value of * NET_IP_ALIGN is universally set to '2'. And on platforms @@ -827,20 +1001,37 @@ static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, * unconditional IP align value of '2'. */ ip_align = 2; - if ((ip_align + reg_off + off) % size != 0) { - verbose("misaligned packet access off %d+%d+%d size %d\n", - ip_align, reg_off, off, size); + + reg_off = tnum_add(reg->var_off, tnum_const(ip_align + reg->off + off)); + if (!tnum_is_aligned(reg_off, size)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); + verbose("misaligned packet access off %d+%s+%d+%d size %d\n", + ip_align, tn_buf, reg->off, off, size); return -EACCES; } return 0; } -static int check_val_ptr_alignment(const struct bpf_reg_state *reg, - int size, bool strict) +static int check_generic_ptr_alignment(const struct bpf_reg_state *reg, + const char *pointer_desc, + int off, int size, bool strict) { - if (strict && size != 1) { - verbose("Unknown alignment. Only byte-sized access allowed in value access.\n"); + struct tnum reg_off; + + /* Byte size accesses are always allowed. */ + if (!strict || size == 1) + return 0; + + reg_off = tnum_add(reg->var_off, tnum_const(reg->off + off)); + if (!tnum_is_aligned(reg_off, size)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); + verbose("misaligned %saccess off %s+%d+%d size %d\n", + pointer_desc, tn_buf, reg->off, off, size); return -EACCES; } @@ -852,21 +1043,25 @@ static int check_ptr_alignment(struct bpf_verifier_env *env, int off, int size) { bool strict = env->strict_alignment; + const char *pointer_desc = ""; switch (reg->type) { case PTR_TO_PACKET: + /* special case, because of NET_IP_ALIGN */ return check_pkt_ptr_alignment(reg, off, size, strict); - case PTR_TO_MAP_VALUE_ADJ: - return check_val_ptr_alignment(reg, size, strict); + case PTR_TO_MAP_VALUE: + pointer_desc = "value "; + break; + case PTR_TO_CTX: + pointer_desc = "context "; + break; + case PTR_TO_STACK: + pointer_desc = "stack "; + break; default: - if (off % size != 0) { - verbose("misaligned access off %d size %d\n", - off, size); - return -EACCES; - } - - return 0; + break; } + return check_generic_ptr_alignment(reg, pointer_desc, off, size, strict); } /* check whether memory at (regno + off) is accessible for t = (read | write) @@ -883,52 +1078,79 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn struct bpf_reg_state *reg = &state->regs[regno]; int size, err = 0; - if (reg->type == PTR_TO_STACK) - off += reg->imm; - size = bpf_size_to_bytes(bpf_size); if (size < 0) return size; + /* alignment checks will add in reg->off themselves */ err = check_ptr_alignment(env, reg, off, size); if (err) return err; - if (reg->type == PTR_TO_MAP_VALUE || - reg->type == PTR_TO_MAP_VALUE_ADJ) { + /* for access checks, reg->off is just part of off */ + off += reg->off; + + if (reg->type == PTR_TO_MAP_VALUE) { if (t == BPF_WRITE && value_regno >= 0 && is_pointer_value(env, value_regno)) { verbose("R%d leaks addr into map\n", value_regno); return -EACCES; } - if (reg->type == PTR_TO_MAP_VALUE_ADJ) - err = check_map_access_adj(env, regno, off, size); - else - err = check_map_access(env, regno, off, size); + err = check_map_access(env, regno, off, size); if (!err && t == BPF_READ && value_regno >= 0) - mark_reg_unknown_value_and_range(state->regs, - value_regno); + mark_reg_unknown(state->regs, value_regno); } else if (reg->type == PTR_TO_CTX) { - enum bpf_reg_type reg_type = UNKNOWN_VALUE; + enum bpf_reg_type reg_type = SCALAR_VALUE; if (t == BPF_WRITE && value_regno >= 0 && is_pointer_value(env, value_regno)) { verbose("R%d leaks addr into ctx\n", value_regno); return -EACCES; } + /* ctx accesses must be at a fixed offset, so that we can + * determine what type of data were returned. + */ + if (!tnum_is_const(reg->var_off)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); + verbose("variable ctx access var_off=%s off=%d size=%d", + tn_buf, off, size); + return -EACCES; + } + off += reg->var_off.value; err = check_ctx_access(env, insn_idx, off, size, t, ®_type); if (!err && t == BPF_READ && value_regno >= 0) { - mark_reg_unknown_value_and_range(state->regs, - value_regno); - /* note that reg.[id|off|range] == 0 */ + /* ctx access returns either a scalar, or a + * PTR_TO_PACKET[_END]. In the latter case, we know + * the offset is zero. + */ + if (reg_type == SCALAR_VALUE) + mark_reg_unknown(state->regs, value_regno); + else + mark_reg_known_zero(state->regs, value_regno); + state->regs[value_regno].id = 0; + state->regs[value_regno].off = 0; + state->regs[value_regno].range = 0; state->regs[value_regno].type = reg_type; - state->regs[value_regno].aux_off = 0; - state->regs[value_regno].aux_off_align = 0; } - } else if (reg->type == FRAME_PTR || reg->type == PTR_TO_STACK) { + } else if (reg->type == PTR_TO_STACK) { + /* stack accesses must be at a fixed offset, so that we can + * determine what type of data were returned. + * See check_stack_read(). + */ + if (!tnum_is_const(reg->var_off)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); + verbose("variable stack access var_off=%s off=%d size=%d", + tn_buf, off, size); + return -EACCES; + } + off += reg->var_off.value; if (off >= 0 || off < -MAX_BPF_STACK) { verbose("invalid stack off=%d size=%d\n", off, size); return -EACCES; @@ -948,7 +1170,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn } else { err = check_stack_read(state, off, size, value_regno); } - } else if (state->regs[regno].type == PTR_TO_PACKET) { + } else if (reg->type == PTR_TO_PACKET) { if (t == BPF_WRITE && !may_access_direct_pkt_data(env, NULL, t)) { verbose("cannot write into packet\n"); return -EACCES; @@ -960,28 +1182,25 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn } err = check_packet_access(env, regno, off, size); if (!err && t == BPF_READ && value_regno >= 0) - mark_reg_unknown_value_and_range(state->regs, - value_regno); + mark_reg_unknown(state->regs, value_regno); } else { verbose("R%d invalid mem access '%s'\n", regno, reg_type_str[reg->type]); return -EACCES; } - if (!err && size <= 2 && value_regno >= 0 && env->allow_ptr_leaks && - state->regs[value_regno].type == UNKNOWN_VALUE) { - /* 1 or 2 byte load zero-extends, determine the number of - * zero upper bits. Not doing it fo 4 byte load, since - * such values cannot be added to ptr_to_packet anyway. - */ - state->regs[value_regno].imm = 64 - size * 8; + if (!err && size < BPF_REG_SIZE && value_regno >= 0 && t == BPF_READ && + state->regs[value_regno].type == SCALAR_VALUE) { + /* b/h/w load zero-extends, mark upper bits as known 0 */ + state->regs[value_regno].var_off = tnum_cast( + state->regs[value_regno].var_off, size); + __update_reg_bounds(&state->regs[value_regno]); } return err; } static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_insn *insn) { - struct bpf_reg_state *regs = env->cur_state.regs; int err; if ((BPF_SIZE(insn->code) != BPF_W && BPF_SIZE(insn->code) != BPF_DW) || @@ -991,12 +1210,12 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins } /* check src1 operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; /* check src2 operand */ - err = check_reg_arg(regs, insn->dst_reg, SRC_OP); + err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; @@ -1016,9 +1235,17 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins BPF_SIZE(insn->code), BPF_WRITE, -1); } +/* Does this register contain a constant zero? */ +static bool register_is_null(struct bpf_reg_state reg) +{ + return reg.type == SCALAR_VALUE && tnum_equals_const(reg.var_off, 0); +} + /* when register 'regno' is passed into function that will read 'access_size' * bytes from that pointer, make sure that it's within stack boundary - * and all elements of stack are initialized + * and all elements of stack are initialized. + * Unlike most pointer bounds-checking functions, this one doesn't take an + * 'off' argument, so it has to add in reg->off itself. */ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, int access_size, bool zero_size_allowed, @@ -1029,9 +1256,9 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, int off, i; if (regs[regno].type != PTR_TO_STACK) { + /* Allow zero-byte read from NULL, regardless of pointer type */ if (zero_size_allowed && access_size == 0 && - regs[regno].type == CONST_IMM && - regs[regno].imm == 0) + register_is_null(regs[regno])) return 0; verbose("R%d type=%s expected=%s\n", regno, @@ -1040,7 +1267,15 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, return -EACCES; } - off = regs[regno].imm; + /* Only allow fixed-offset stack reads */ + if (!tnum_is_const(regs[regno].var_off)) { + char tn_buf[48]; + + tnum_strn(tn_buf, sizeof(tn_buf), regs[regno].var_off); + verbose("invalid variable stack read R%d var_off=%s\n", + regno, tn_buf); + } + off = regs[regno].off + regs[regno].var_off.value; if (off >= 0 || off < -MAX_BPF_STACK || off + access_size > 0 || access_size <= 0) { verbose("invalid stack type R%d off=%d access_size=%d\n", @@ -1071,16 +1306,14 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno, int access_size, bool zero_size_allowed, struct bpf_call_arg_meta *meta) { - struct bpf_reg_state *regs = env->cur_state.regs; + struct bpf_reg_state *regs = env->cur_state.regs, *reg = ®s[regno]; - switch (regs[regno].type) { + switch (reg->type) { case PTR_TO_PACKET: - return check_packet_access(env, regno, 0, access_size); + return check_packet_access(env, regno, reg->off, access_size); case PTR_TO_MAP_VALUE: - return check_map_access(env, regno, 0, access_size); - case PTR_TO_MAP_VALUE_ADJ: - return check_map_access_adj(env, regno, 0, access_size); - default: /* const_imm|ptr_to_stack or invalid ptr */ + return check_map_access(env, regno, reg->off, access_size); + default: /* scalar_value|ptr_to_stack or invalid ptr */ return check_stack_boundary(env, regno, access_size, zero_size_allowed, meta); } @@ -1097,10 +1330,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, if (arg_type == ARG_DONTCARE) return 0; - if (type == NOT_INIT) { - verbose("R%d !read_ok\n", regno); - return -EACCES; - } + err = check_reg_arg(env, regno, SRC_OP); + if (err) + return err; if (arg_type == ARG_ANYTHING) { if (is_pointer_value(env, regno)) { @@ -1123,11 +1355,8 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, goto err_type; } else if (arg_type == ARG_CONST_SIZE || arg_type == ARG_CONST_SIZE_OR_ZERO) { - expected_type = CONST_IMM; - /* One exception. Allow UNKNOWN_VALUE registers when the - * boundaries are known and don't cause unsafe memory accesses - */ - if (type != UNKNOWN_VALUE && type != expected_type) + expected_type = SCALAR_VALUE; + if (type != expected_type) goto err_type; } else if (arg_type == ARG_CONST_MAP_PTR) { expected_type = CONST_PTR_TO_MAP; @@ -1141,13 +1370,13 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, arg_type == ARG_PTR_TO_UNINIT_MEM) { expected_type = PTR_TO_STACK; /* One exception here. In case function allows for NULL to be - * passed in as argument, it's a CONST_IMM type. Final test + * passed in as argument, it's a SCALAR_VALUE type. Final test * happens during stack boundary checking. */ - if (type == CONST_IMM && reg->imm == 0) + if (register_is_null(*reg)) /* final test in check_stack_boundary() */; else if (type != PTR_TO_PACKET && type != PTR_TO_MAP_VALUE && - type != PTR_TO_MAP_VALUE_ADJ && type != expected_type) + type != expected_type) goto err_type; meta->raw_mode = arg_type == ARG_PTR_TO_UNINIT_MEM; } else { @@ -1173,7 +1402,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, return -EACCES; } if (type == PTR_TO_PACKET) - err = check_packet_access(env, regno, 0, + err = check_packet_access(env, regno, reg->off, meta->map_ptr->key_size); else err = check_stack_boundary(env, regno, @@ -1189,7 +1418,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, return -EACCES; } if (type == PTR_TO_PACKET) - err = check_packet_access(env, regno, 0, + err = check_packet_access(env, regno, reg->off, meta->map_ptr->value_size); else err = check_stack_boundary(env, regno, @@ -1209,10 +1438,11 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, return -EACCES; } - /* If the register is UNKNOWN_VALUE, the access check happens - * using its boundaries. Otherwise, just use its imm + /* The register is SCALAR_VALUE; the access check + * happens using its boundaries. */ - if (type == UNKNOWN_VALUE) { + + if (!tnum_is_const(reg->var_off)) /* For unprivileged variable accesses, disable raw * mode so that the program is required to * initialize all the memory that the helper could @@ -1220,35 +1450,28 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno, */ meta = NULL; - if (reg->min_value < 0) { - verbose("R%d min value is negative, either use unsigned or 'var &= const'\n", - regno); - return -EACCES; - } - - if (reg->min_value == 0) { - err = check_helper_mem_access(env, regno - 1, 0, - zero_size_allowed, - meta); - if (err) - return err; - } + if (reg->smin_value < 0) { + verbose("R%d min value is negative, either use unsigned or 'var &= const'\n", + regno); + return -EACCES; + } - if (reg->max_value == BPF_REGISTER_MAX_RANGE) { - verbose("R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n", - regno); - return -EACCES; - } - err = check_helper_mem_access(env, regno - 1, - reg->max_value, - zero_size_allowed, meta); + if (reg->umin_value == 0) { + err = check_helper_mem_access(env, regno - 1, 0, + zero_size_allowed, + meta); if (err) return err; - } else { - /* register is CONST_IMM */ - err = check_helper_mem_access(env, regno - 1, reg->imm, - zero_size_allowed, meta); } + + if (reg->umax_value >= BPF_MAX_VAR_SIZ) { + verbose("R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n", + regno); + return -EACCES; + } + err = check_helper_mem_access(env, regno - 1, + reg->umax_value, + zero_size_allowed, meta); } return err; @@ -1283,10 +1506,25 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id) func_id != BPF_FUNC_current_task_under_cgroup) goto error; break; + /* devmap returns a pointer to a live net_device ifindex that we cannot + * allow to be modified from bpf side. So do not allow lookup elements + * for now. + */ + case BPF_MAP_TYPE_DEVMAP: + if (func_id != BPF_FUNC_redirect_map) + goto error; + break; case BPF_MAP_TYPE_ARRAY_OF_MAPS: case BPF_MAP_TYPE_HASH_OF_MAPS: if (func_id != BPF_FUNC_map_lookup_elem) goto error; + break; + case BPF_MAP_TYPE_SOCKMAP: + if (func_id != BPF_FUNC_sk_redirect_map && + func_id != BPF_FUNC_sock_map_update && + func_id != BPF_FUNC_map_delete_elem) + goto error; + break; default: break; } @@ -1311,6 +1549,18 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id) if (map->map_type != BPF_MAP_TYPE_CGROUP_ARRAY) goto error; break; + case BPF_FUNC_redirect_map: + if (map->map_type != BPF_MAP_TYPE_DEVMAP) + goto error; + break; + case BPF_FUNC_sk_redirect_map: + if (map->map_type != BPF_MAP_TYPE_SOCKMAP) + goto error; + break; + case BPF_FUNC_sock_map_update: + if (map->map_type != BPF_MAP_TYPE_SOCKMAP) + goto error; + break; default: break; } @@ -1340,6 +1590,9 @@ static int check_raw_mode(const struct bpf_func_proto *fn) return count > 1 ? -EINVAL : 0; } +/* Packet data might have moved, any old PTR_TO_PACKET[_END] are now invalid, + * so turn them into unknown SCALAR_VALUE. + */ static void clear_all_pkt_pointers(struct bpf_verifier_env *env) { struct bpf_verifier_state *state = &env->cur_state; @@ -1349,7 +1602,7 @@ static void clear_all_pkt_pointers(struct bpf_verifier_env *env) for (i = 0; i < MAX_BPF_REG; i++) if (regs[i].type == PTR_TO_PACKET || regs[i].type == PTR_TO_PACKET_END) - mark_reg_unknown_value(regs, i); + mark_reg_unknown(regs, i); for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { if (state->stack_slot_type[i] != STACK_SPILL) @@ -1358,8 +1611,7 @@ static void clear_all_pkt_pointers(struct bpf_verifier_env *env) if (reg->type != PTR_TO_PACKET && reg->type != PTR_TO_PACKET_END) continue; - __mark_reg_unknown_value(state->spilled_regs, - i / BPF_REG_SIZE); + __mark_reg_unknown(reg); } } @@ -1434,19 +1686,24 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) } /* reset caller saved regs */ - for (i = 0; i < CALLER_SAVED_REGS; i++) + for (i = 0; i < CALLER_SAVED_REGS; i++) { mark_reg_not_init(regs, caller_saved[i]); + check_reg_arg(env, caller_saved[i], DST_OP_NO_MARK); + } - /* update return register */ + /* update return register (already marked as written above) */ if (fn->ret_type == RET_INTEGER) { - regs[BPF_REG_0].type = UNKNOWN_VALUE; + /* sets type to SCALAR_VALUE */ + mark_reg_unknown(regs, BPF_REG_0); } else if (fn->ret_type == RET_VOID) { regs[BPF_REG_0].type = NOT_INIT; } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) { struct bpf_insn_aux_data *insn_aux; regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; - regs[BPF_REG_0].max_value = regs[BPF_REG_0].min_value = 0; + /* There is no offset yet applied, variable or fixed */ + mark_reg_known_zero(regs, BPF_REG_0); + regs[BPF_REG_0].off = 0; /* remember map_ptr, so that check_map_access() * can check 'value_size' boundary of memory access * to map element returned from bpf_map_lookup_elem() @@ -1477,485 +1734,551 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) return 0; } -static int check_packet_ptr_add(struct bpf_verifier_env *env, - struct bpf_insn *insn) +static void coerce_reg_to_32(struct bpf_reg_state *reg) { - struct bpf_reg_state *regs = env->cur_state.regs; - struct bpf_reg_state *dst_reg = ®s[insn->dst_reg]; - struct bpf_reg_state *src_reg = ®s[insn->src_reg]; - struct bpf_reg_state tmp_reg; - s32 imm; - - if (BPF_SRC(insn->code) == BPF_K) { - /* pkt_ptr += imm */ - imm = insn->imm; - -add_imm: - if (imm < 0) { - verbose("addition of negative constant to packet pointer is not allowed\n"); - return -EACCES; - } - if (imm >= MAX_PACKET_OFF || - imm + dst_reg->off >= MAX_PACKET_OFF) { - verbose("constant %d is too large to add to packet pointer\n", - imm); - return -EACCES; - } - /* a constant was added to pkt_ptr. - * Remember it while keeping the same 'id' - */ - dst_reg->off += imm; - } else { - bool had_id; - - if (src_reg->type == PTR_TO_PACKET) { - /* R6=pkt(id=0,off=0,r=62) R7=imm22; r7 += r6 */ - tmp_reg = *dst_reg; /* save r7 state */ - *dst_reg = *src_reg; /* copy pkt_ptr state r6 into r7 */ - src_reg = &tmp_reg; /* pretend it's src_reg state */ - /* if the checks below reject it, the copy won't matter, - * since we're rejecting the whole program. If all ok, - * then imm22 state will be added to r7 - * and r7 will be pkt(id=0,off=22,r=62) while - * r6 will stay as pkt(id=0,off=0,r=62) - */ - } - - if (src_reg->type == CONST_IMM) { - /* pkt_ptr += reg where reg is known constant */ - imm = src_reg->imm; - goto add_imm; - } - /* disallow pkt_ptr += reg - * if reg is not uknown_value with guaranteed zero upper bits - * otherwise pkt_ptr may overflow and addition will become - * subtraction which is not allowed - */ - if (src_reg->type != UNKNOWN_VALUE) { - verbose("cannot add '%s' to ptr_to_packet\n", - reg_type_str[src_reg->type]); - return -EACCES; - } - if (src_reg->imm < 48) { - verbose("cannot add integer value with %lld upper zero bits to ptr_to_packet\n", - src_reg->imm); - return -EACCES; - } - - had_id = (dst_reg->id != 0); - - /* dst_reg stays as pkt_ptr type and since some positive - * integer value was added to the pointer, increment its 'id' - */ - dst_reg->id = ++env->id_gen; - - /* something was added to pkt_ptr, set range to zero */ - dst_reg->aux_off += dst_reg->off; - dst_reg->off = 0; - dst_reg->range = 0; - if (had_id) - dst_reg->aux_off_align = min(dst_reg->aux_off_align, - src_reg->min_align); - else - dst_reg->aux_off_align = src_reg->min_align; - } - return 0; + /* clear high 32 bits */ + reg->var_off = tnum_cast(reg->var_off, 4); + /* Update bounds */ + __update_reg_bounds(reg); } -static int evaluate_reg_alu(struct bpf_verifier_env *env, struct bpf_insn *insn) +static bool signed_add_overflows(s64 a, s64 b) { - struct bpf_reg_state *regs = env->cur_state.regs; - struct bpf_reg_state *dst_reg = ®s[insn->dst_reg]; - u8 opcode = BPF_OP(insn->code); - s64 imm_log2; - - /* for type == UNKNOWN_VALUE: - * imm > 0 -> number of zero upper bits - * imm == 0 -> don't track which is the same as all bits can be non-zero - */ - - if (BPF_SRC(insn->code) == BPF_X) { - struct bpf_reg_state *src_reg = ®s[insn->src_reg]; - - if (src_reg->type == UNKNOWN_VALUE && src_reg->imm > 0 && - dst_reg->imm && opcode == BPF_ADD) { - /* dreg += sreg - * where both have zero upper bits. Adding them - * can only result making one more bit non-zero - * in the larger value. - * Ex. 0xffff (imm=48) + 1 (imm=63) = 0x10000 (imm=47) - * 0xffff (imm=48) + 0xffff = 0x1fffe (imm=47) - */ - dst_reg->imm = min(dst_reg->imm, src_reg->imm); - dst_reg->imm--; - return 0; - } - if (src_reg->type == CONST_IMM && src_reg->imm > 0 && - dst_reg->imm && opcode == BPF_ADD) { - /* dreg += sreg - * where dreg has zero upper bits and sreg is const. - * Adding them can only result making one more bit - * non-zero in the larger value. - */ - imm_log2 = __ilog2_u64((long long)src_reg->imm); - dst_reg->imm = min(dst_reg->imm, 63 - imm_log2); - dst_reg->imm--; - return 0; - } - /* all other cases non supported yet, just mark dst_reg */ - dst_reg->imm = 0; - return 0; - } - - /* sign extend 32-bit imm into 64-bit to make sure that - * negative values occupy bit 63. Note ilog2() would have - * been incorrect, since sizeof(insn->imm) == 4 - */ - imm_log2 = __ilog2_u64((long long)insn->imm); - - if (dst_reg->imm && opcode == BPF_LSH) { - /* reg <<= imm - * if reg was a result of 2 byte load, then its imm == 48 - * which means that upper 48 bits are zero and shifting this reg - * left by 4 would mean that upper 44 bits are still zero - */ - dst_reg->imm -= insn->imm; - } else if (dst_reg->imm && opcode == BPF_MUL) { - /* reg *= imm - * if multiplying by 14 subtract 4 - * This is conservative calculation of upper zero bits. - * It's not trying to special case insn->imm == 1 or 0 cases - */ - dst_reg->imm -= imm_log2 + 1; - } else if (opcode == BPF_AND) { - /* reg &= imm */ - dst_reg->imm = 63 - imm_log2; - } else if (dst_reg->imm && opcode == BPF_ADD) { - /* reg += imm */ - dst_reg->imm = min(dst_reg->imm, 63 - imm_log2); - dst_reg->imm--; - } else if (opcode == BPF_RSH) { - /* reg >>= imm - * which means that after right shift, upper bits will be zero - * note that verifier already checked that - * 0 <= imm < 64 for shift insn - */ - dst_reg->imm += insn->imm; - if (unlikely(dst_reg->imm > 64)) - /* some dumb code did: - * r2 = *(u32 *)mem; - * r2 >>= 32; - * and all bits are zero now */ - dst_reg->imm = 64; - } else { - /* all other alu ops, means that we don't know what will - * happen to the value, mark it with unknown number of zero bits - */ - dst_reg->imm = 0; - } + /* Do the add in u64, where overflow is well-defined */ + s64 res = (s64)((u64)a + (u64)b); - if (dst_reg->imm < 0) { - /* all 64 bits of the register can contain non-zero bits - * and such value cannot be added to ptr_to_packet, since it - * may overflow, mark it as unknown to avoid further eval - */ - dst_reg->imm = 0; - } - return 0; + if (b < 0) + return res > a; + return res < a; } -static int evaluate_reg_imm_alu_unknown(struct bpf_verifier_env *env, - struct bpf_insn *insn) +static bool signed_sub_overflows(s64 a, s64 b) { - struct bpf_reg_state *regs = env->cur_state.regs; - struct bpf_reg_state *dst_reg = ®s[insn->dst_reg]; - struct bpf_reg_state *src_reg = ®s[insn->src_reg]; - u8 opcode = BPF_OP(insn->code); - s64 imm_log2 = __ilog2_u64((long long)dst_reg->imm); - - /* BPF_X code with src_reg->type UNKNOWN_VALUE here. */ - if (src_reg->imm > 0 && dst_reg->imm) { - switch (opcode) { - case BPF_ADD: - /* dreg += sreg - * where both have zero upper bits. Adding them - * can only result making one more bit non-zero - * in the larger value. - * Ex. 0xffff (imm=48) + 1 (imm=63) = 0x10000 (imm=47) - * 0xffff (imm=48) + 0xffff = 0x1fffe (imm=47) - */ - dst_reg->imm = min(src_reg->imm, 63 - imm_log2); - dst_reg->imm--; - break; - case BPF_AND: - /* dreg &= sreg - * AND can not extend zero bits only shrink - * Ex. 0x00..00ffffff - * & 0x0f..ffffffff - * ---------------- - * 0x00..00ffffff - */ - dst_reg->imm = max(src_reg->imm, 63 - imm_log2); - break; - case BPF_OR: - /* dreg |= sreg - * OR can only extend zero bits - * Ex. 0x00..00ffffff - * | 0x0f..ffffffff - * ---------------- - * 0x0f..00ffffff - */ - dst_reg->imm = min(src_reg->imm, 63 - imm_log2); - break; - case BPF_SUB: - case BPF_MUL: - case BPF_RSH: - case BPF_LSH: - /* These may be flushed out later */ - default: - mark_reg_unknown_value(regs, insn->dst_reg); - } - } else { - mark_reg_unknown_value(regs, insn->dst_reg); - } + /* Do the sub in u64, where overflow is well-defined */ + s64 res = (s64)((u64)a - (u64)b); - dst_reg->type = UNKNOWN_VALUE; - return 0; + if (b < 0) + return res < a; + return res > a; } -static int evaluate_reg_imm_alu(struct bpf_verifier_env *env, - struct bpf_insn *insn) +/* Handles arithmetic on a pointer and a scalar: computes new min/max and var_off. + * Caller should also handle BPF_MOV case separately. + * If we return -EACCES, caller may want to try again treating pointer as a + * scalar. So we only emit a diagnostic if !env->allow_ptr_leaks. + */ +static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + struct bpf_insn *insn, + const struct bpf_reg_state *ptr_reg, + const struct bpf_reg_state *off_reg) { - struct bpf_reg_state *regs = env->cur_state.regs; - struct bpf_reg_state *dst_reg = ®s[insn->dst_reg]; - struct bpf_reg_state *src_reg = ®s[insn->src_reg]; + struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg; + bool known = tnum_is_const(off_reg->var_off); + s64 smin_val = off_reg->smin_value, smax_val = off_reg->smax_value, + smin_ptr = ptr_reg->smin_value, smax_ptr = ptr_reg->smax_value; + u64 umin_val = off_reg->umin_value, umax_val = off_reg->umax_value, + umin_ptr = ptr_reg->umin_value, umax_ptr = ptr_reg->umax_value; u8 opcode = BPF_OP(insn->code); - u64 dst_imm = dst_reg->imm; + u32 dst = insn->dst_reg; - if (BPF_SRC(insn->code) == BPF_X && src_reg->type == UNKNOWN_VALUE) - return evaluate_reg_imm_alu_unknown(env, insn); + dst_reg = ®s[dst]; - /* dst_reg->type == CONST_IMM here. Simulate execution of insns - * containing ALU ops. Don't care about overflow or negative - * values, just add/sub/... them; registers are in u64. - */ - if (opcode == BPF_ADD && BPF_SRC(insn->code) == BPF_K) { - dst_imm += insn->imm; - } else if (opcode == BPF_ADD && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm += src_reg->imm; - } else if (opcode == BPF_SUB && BPF_SRC(insn->code) == BPF_K) { - dst_imm -= insn->imm; - } else if (opcode == BPF_SUB && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm -= src_reg->imm; - } else if (opcode == BPF_MUL && BPF_SRC(insn->code) == BPF_K) { - dst_imm *= insn->imm; - } else if (opcode == BPF_MUL && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm *= src_reg->imm; - } else if (opcode == BPF_OR && BPF_SRC(insn->code) == BPF_K) { - dst_imm |= insn->imm; - } else if (opcode == BPF_OR && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm |= src_reg->imm; - } else if (opcode == BPF_AND && BPF_SRC(insn->code) == BPF_K) { - dst_imm &= insn->imm; - } else if (opcode == BPF_AND && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm &= src_reg->imm; - } else if (opcode == BPF_RSH && BPF_SRC(insn->code) == BPF_K) { - dst_imm >>= insn->imm; - } else if (opcode == BPF_RSH && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm >>= src_reg->imm; - } else if (opcode == BPF_LSH && BPF_SRC(insn->code) == BPF_K) { - dst_imm <<= insn->imm; - } else if (opcode == BPF_LSH && BPF_SRC(insn->code) == BPF_X && - src_reg->type == CONST_IMM) { - dst_imm <<= src_reg->imm; - } else { - mark_reg_unknown_value(regs, insn->dst_reg); - goto out; + if (WARN_ON_ONCE(known && (smin_val != smax_val))) { + print_verifier_state(&env->cur_state); + verbose("verifier internal error: known but bad sbounds\n"); + return -EINVAL; + } + if (WARN_ON_ONCE(known && (umin_val != umax_val))) { + print_verifier_state(&env->cur_state); + verbose("verifier internal error: known but bad ubounds\n"); + return -EINVAL; } - dst_reg->imm = dst_imm; -out: - return 0; -} - -static void check_reg_overflow(struct bpf_reg_state *reg) -{ - if (reg->max_value > BPF_REGISTER_MAX_RANGE) - reg->max_value = BPF_REGISTER_MAX_RANGE; - if (reg->min_value < BPF_REGISTER_MIN_RANGE || - reg->min_value > BPF_REGISTER_MAX_RANGE) - reg->min_value = BPF_REGISTER_MIN_RANGE; -} + if (BPF_CLASS(insn->code) != BPF_ALU64) { + /* 32-bit ALU ops on pointers produce (meaningless) scalars */ + if (!env->allow_ptr_leaks) + verbose("R%d 32-bit pointer arithmetic prohibited\n", + dst); + return -EACCES; + } -static u32 calc_align(u32 imm) -{ - if (!imm) - return 1U << 31; - return imm - ((imm - 1) & imm); -} + if (ptr_reg->type == PTR_TO_MAP_VALUE_OR_NULL) { + if (!env->allow_ptr_leaks) + verbose("R%d pointer arithmetic on PTR_TO_MAP_VALUE_OR_NULL prohibited, null-check it first\n", + dst); + return -EACCES; + } + if (ptr_reg->type == CONST_PTR_TO_MAP) { + if (!env->allow_ptr_leaks) + verbose("R%d pointer arithmetic on CONST_PTR_TO_MAP prohibited\n", + dst); + return -EACCES; + } + if (ptr_reg->type == PTR_TO_PACKET_END) { + if (!env->allow_ptr_leaks) + verbose("R%d pointer arithmetic on PTR_TO_PACKET_END prohibited\n", + dst); + return -EACCES; + } -static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, - struct bpf_insn *insn) -{ - struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg; - s64 min_val = BPF_REGISTER_MIN_RANGE; - u64 max_val = BPF_REGISTER_MAX_RANGE; - u8 opcode = BPF_OP(insn->code); - u32 dst_align, src_align; + /* In case of 'scalar += pointer', dst_reg inherits pointer type and id. + * The id may be overwritten later if we create a new variable offset. + */ + dst_reg->type = ptr_reg->type; + dst_reg->id = ptr_reg->id; - dst_reg = ®s[insn->dst_reg]; - src_align = 0; - if (BPF_SRC(insn->code) == BPF_X) { - check_reg_overflow(®s[insn->src_reg]); - min_val = regs[insn->src_reg].min_value; - max_val = regs[insn->src_reg].max_value; - - /* If the source register is a random pointer then the - * min_value/max_value values represent the range of the known - * accesses into that value, not the actual min/max value of the - * register itself. In this case we have to reset the reg range - * values so we know it is not safe to look at. + switch (opcode) { + case BPF_ADD: + /* We can take a fixed offset as long as it doesn't overflow + * the s32 'off' field + */ + if (known && (ptr_reg->off + smin_val == + (s64)(s32)(ptr_reg->off + smin_val))) { + /* pointer += K. Accumulate it into fixed offset */ + dst_reg->smin_value = smin_ptr; + dst_reg->smax_value = smax_ptr; + dst_reg->umin_value = umin_ptr; + dst_reg->umax_value = umax_ptr; + dst_reg->var_off = ptr_reg->var_off; + dst_reg->off = ptr_reg->off + smin_val; + dst_reg->range = ptr_reg->range; + break; + } + /* A new variable offset is created. Note that off_reg->off + * == 0, since it's a scalar. + * dst_reg gets the pointer type and since some positive + * integer value was added to the pointer, give it a new 'id' + * if it's a PTR_TO_PACKET. + * this creates a new 'base' pointer, off_reg (variable) gets + * added into the variable offset, and we copy the fixed offset + * from ptr_reg. + */ + if (signed_add_overflows(smin_ptr, smin_val) || + signed_add_overflows(smax_ptr, smax_val)) { + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } else { + dst_reg->smin_value = smin_ptr + smin_val; + dst_reg->smax_value = smax_ptr + smax_val; + } + if (umin_ptr + umin_val < umin_ptr || + umax_ptr + umax_val < umax_ptr) { + dst_reg->umin_value = 0; + dst_reg->umax_value = U64_MAX; + } else { + dst_reg->umin_value = umin_ptr + umin_val; + dst_reg->umax_value = umax_ptr + umax_val; + } + dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off); + dst_reg->off = ptr_reg->off; + if (ptr_reg->type == PTR_TO_PACKET) { + dst_reg->id = ++env->id_gen; + /* something was added to pkt_ptr, set range to zero */ + dst_reg->range = 0; + } + break; + case BPF_SUB: + if (dst_reg == off_reg) { + /* scalar -= pointer. Creates an unknown scalar */ + if (!env->allow_ptr_leaks) + verbose("R%d tried to subtract pointer from scalar\n", + dst); + return -EACCES; + } + /* We don't allow subtraction from FP, because (according to + * test_verifier.c test "invalid fp arithmetic", JITs might not + * be able to deal with it. + */ + if (ptr_reg->type == PTR_TO_STACK) { + if (!env->allow_ptr_leaks) + verbose("R%d subtraction from stack pointer prohibited\n", + dst); + return -EACCES; + } + if (known && (ptr_reg->off - smin_val == + (s64)(s32)(ptr_reg->off - smin_val))) { + /* pointer -= K. Subtract it from fixed offset */ + dst_reg->smin_value = smin_ptr; + dst_reg->smax_value = smax_ptr; + dst_reg->umin_value = umin_ptr; + dst_reg->umax_value = umax_ptr; + dst_reg->var_off = ptr_reg->var_off; + dst_reg->id = ptr_reg->id; + dst_reg->off = ptr_reg->off - smin_val; + dst_reg->range = ptr_reg->range; + break; + } + /* A new variable offset is created. If the subtrahend is known + * nonnegative, then any reg->range we had before is still good. + */ + if (signed_sub_overflows(smin_ptr, smax_val) || + signed_sub_overflows(smax_ptr, smin_val)) { + /* Overflow possible, we know nothing */ + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } else { + dst_reg->smin_value = smin_ptr - smax_val; + dst_reg->smax_value = smax_ptr - smin_val; + } + if (umin_ptr < umax_val) { + /* Overflow possible, we know nothing */ + dst_reg->umin_value = 0; + dst_reg->umax_value = U64_MAX; + } else { + /* Cannot overflow (as long as bounds are consistent) */ + dst_reg->umin_value = umin_ptr - umax_val; + dst_reg->umax_value = umax_ptr - umin_val; + } + dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off); + dst_reg->off = ptr_reg->off; + if (ptr_reg->type == PTR_TO_PACKET) { + dst_reg->id = ++env->id_gen; + /* something was added to pkt_ptr, set range to zero */ + if (smin_val < 0) + dst_reg->range = 0; + } + break; + case BPF_AND: + case BPF_OR: + case BPF_XOR: + /* bitwise ops on pointers are troublesome, prohibit for now. + * (However, in principle we could allow some cases, e.g. + * ptr &= ~3 which would reduce min_value by 3.) */ - if (regs[insn->src_reg].type != CONST_IMM && - regs[insn->src_reg].type != UNKNOWN_VALUE) { - min_val = BPF_REGISTER_MIN_RANGE; - max_val = BPF_REGISTER_MAX_RANGE; - src_align = 0; - } else { - src_align = regs[insn->src_reg].min_align; - } - } else if (insn->imm < BPF_REGISTER_MAX_RANGE && - (s64)insn->imm > BPF_REGISTER_MIN_RANGE) { - min_val = max_val = insn->imm; - src_align = calc_align(insn->imm); + if (!env->allow_ptr_leaks) + verbose("R%d bitwise operator %s on pointer prohibited\n", + dst, bpf_alu_string[opcode >> 4]); + return -EACCES; + default: + /* other operators (e.g. MUL,LSH) produce non-pointer results */ + if (!env->allow_ptr_leaks) + verbose("R%d pointer arithmetic with %s operator prohibited\n", + dst, bpf_alu_string[opcode >> 4]); + return -EACCES; } - dst_align = dst_reg->min_align; + __update_reg_bounds(dst_reg); + __reg_deduce_bounds(dst_reg); + __reg_bound_offset(dst_reg); + return 0; +} - /* We don't know anything about what was done to this register, mark it - * as unknown. Also, if both derived bounds came from signed/unsigned - * mixed compares and one side is unbounded, we cannot really do anything - * with them as boundaries cannot be trusted. Thus, arithmetic of two - * regs of such kind will get invalidated bounds on the dst side. - */ - if ((min_val == BPF_REGISTER_MIN_RANGE && - max_val == BPF_REGISTER_MAX_RANGE) || - (BPF_SRC(insn->code) == BPF_X && - ((min_val != BPF_REGISTER_MIN_RANGE && - max_val == BPF_REGISTER_MAX_RANGE) || - (min_val == BPF_REGISTER_MIN_RANGE && - max_val != BPF_REGISTER_MAX_RANGE) || - (dst_reg->min_value != BPF_REGISTER_MIN_RANGE && - dst_reg->max_value == BPF_REGISTER_MAX_RANGE) || - (dst_reg->min_value == BPF_REGISTER_MIN_RANGE && - dst_reg->max_value != BPF_REGISTER_MAX_RANGE)) && - regs[insn->dst_reg].value_from_signed != - regs[insn->src_reg].value_from_signed)) { - reset_reg_range_values(regs, insn->dst_reg); - return; +static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, + struct bpf_insn *insn, + struct bpf_reg_state *dst_reg, + struct bpf_reg_state src_reg) +{ + struct bpf_reg_state *regs = env->cur_state.regs; + u8 opcode = BPF_OP(insn->code); + bool src_known, dst_known; + s64 smin_val, smax_val; + u64 umin_val, umax_val; + + if (BPF_CLASS(insn->code) != BPF_ALU64) { + /* 32-bit ALU ops are (32,32)->64 */ + coerce_reg_to_32(dst_reg); + coerce_reg_to_32(&src_reg); } - - /* If one of our values was at the end of our ranges then we can't just - * do our normal operations to the register, we need to set the values - * to the min/max since they are undefined. - */ - if (min_val == BPF_REGISTER_MIN_RANGE) - dst_reg->min_value = BPF_REGISTER_MIN_RANGE; - if (max_val == BPF_REGISTER_MAX_RANGE) - dst_reg->max_value = BPF_REGISTER_MAX_RANGE; + smin_val = src_reg.smin_value; + smax_val = src_reg.smax_value; + umin_val = src_reg.umin_value; + umax_val = src_reg.umax_value; + src_known = tnum_is_const(src_reg.var_off); + dst_known = tnum_is_const(dst_reg->var_off); switch (opcode) { case BPF_ADD: - if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) - dst_reg->min_value += min_val; - if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) - dst_reg->max_value += max_val; - dst_reg->min_align = min(src_align, dst_align); + if (signed_add_overflows(dst_reg->smin_value, smin_val) || + signed_add_overflows(dst_reg->smax_value, smax_val)) { + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } else { + dst_reg->smin_value += smin_val; + dst_reg->smax_value += smax_val; + } + if (dst_reg->umin_value + umin_val < umin_val || + dst_reg->umax_value + umax_val < umax_val) { + dst_reg->umin_value = 0; + dst_reg->umax_value = U64_MAX; + } else { + dst_reg->umin_value += umin_val; + dst_reg->umax_value += umax_val; + } + dst_reg->var_off = tnum_add(dst_reg->var_off, src_reg.var_off); break; case BPF_SUB: - if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) - dst_reg->min_value -= min_val; - if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) - dst_reg->max_value -= max_val; - dst_reg->min_align = min(src_align, dst_align); + if (signed_sub_overflows(dst_reg->smin_value, smax_val) || + signed_sub_overflows(dst_reg->smax_value, smin_val)) { + /* Overflow possible, we know nothing */ + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } else { + dst_reg->smin_value -= smax_val; + dst_reg->smax_value -= smin_val; + } + if (dst_reg->umin_value < umax_val) { + /* Overflow possible, we know nothing */ + dst_reg->umin_value = 0; + dst_reg->umax_value = U64_MAX; + } else { + /* Cannot overflow (as long as bounds are consistent) */ + dst_reg->umin_value -= umax_val; + dst_reg->umax_value -= umin_val; + } + dst_reg->var_off = tnum_sub(dst_reg->var_off, src_reg.var_off); break; case BPF_MUL: - if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) - dst_reg->min_value *= min_val; - if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) - dst_reg->max_value *= max_val; - dst_reg->min_align = max(src_align, dst_align); + dst_reg->var_off = tnum_mul(dst_reg->var_off, src_reg.var_off); + if (smin_val < 0 || dst_reg->smin_value < 0) { + /* Ain't nobody got time to multiply that sign */ + __mark_reg_unbounded(dst_reg); + __update_reg_bounds(dst_reg); + break; + } + /* Both values are positive, so we can work with unsigned and + * copy the result to signed (unless it exceeds S64_MAX). + */ + if (umax_val > U32_MAX || dst_reg->umax_value > U32_MAX) { + /* Potential overflow, we know nothing */ + __mark_reg_unbounded(dst_reg); + /* (except what we can learn from the var_off) */ + __update_reg_bounds(dst_reg); + break; + } + dst_reg->umin_value *= umin_val; + dst_reg->umax_value *= umax_val; + if (dst_reg->umax_value > S64_MAX) { + /* Overflow possible, we know nothing */ + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } else { + dst_reg->smin_value = dst_reg->umin_value; + dst_reg->smax_value = dst_reg->umax_value; + } break; case BPF_AND: - /* Disallow AND'ing of negative numbers, ain't nobody got time - * for that. Otherwise the minimum is 0 and the max is the max - * value we could AND against. + if (src_known && dst_known) { + __mark_reg_known(dst_reg, dst_reg->var_off.value & + src_reg.var_off.value); + break; + } + /* We get our minimum from the var_off, since that's inherently + * bitwise. Our maximum is the minimum of the operands' maxima. */ - if (min_val < 0) - dst_reg->min_value = BPF_REGISTER_MIN_RANGE; - else - dst_reg->min_value = 0; - dst_reg->max_value = max_val; - dst_reg->min_align = max(src_align, dst_align); + dst_reg->var_off = tnum_and(dst_reg->var_off, src_reg.var_off); + dst_reg->umin_value = dst_reg->var_off.value; + dst_reg->umax_value = min(dst_reg->umax_value, umax_val); + if (dst_reg->smin_value < 0 || smin_val < 0) { + /* Lose signed bounds when ANDing negative numbers, + * ain't nobody got time for that. + */ + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } else { + /* ANDing two positives gives a positive, so safe to + * cast result into s64. + */ + dst_reg->smin_value = dst_reg->umin_value; + dst_reg->smax_value = dst_reg->umax_value; + } + /* We may learn something more from the var_off */ + __update_reg_bounds(dst_reg); break; - case BPF_LSH: - /* Gotta have special overflow logic here, if we're shifting - * more than MAX_RANGE then just assume we have an invalid - * range. + case BPF_OR: + if (src_known && dst_known) { + __mark_reg_known(dst_reg, dst_reg->var_off.value | + src_reg.var_off.value); + break; + } + /* We get our maximum from the var_off, and our minimum is the + * maximum of the operands' minima */ - if (min_val > ilog2(BPF_REGISTER_MAX_RANGE)) { - dst_reg->min_value = BPF_REGISTER_MIN_RANGE; - dst_reg->min_align = 1; + dst_reg->var_off = tnum_or(dst_reg->var_off, src_reg.var_off); + dst_reg->umin_value = max(dst_reg->umin_value, umin_val); + dst_reg->umax_value = dst_reg->var_off.value | + dst_reg->var_off.mask; + if (dst_reg->smin_value < 0 || smin_val < 0) { + /* Lose signed bounds when ORing negative numbers, + * ain't nobody got time for that. + */ + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; } else { - if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) - dst_reg->min_value <<= min_val; - if (!dst_reg->min_align) - dst_reg->min_align = 1; - dst_reg->min_align <<= min_val; - } - if (max_val > ilog2(BPF_REGISTER_MAX_RANGE)) - dst_reg->max_value = BPF_REGISTER_MAX_RANGE; - else if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) - dst_reg->max_value <<= max_val; + /* ORing two positives gives a positive, so safe to + * cast result into s64. + */ + dst_reg->smin_value = dst_reg->umin_value; + dst_reg->smax_value = dst_reg->umax_value; + } + /* We may learn something more from the var_off */ + __update_reg_bounds(dst_reg); break; - case BPF_RSH: - /* RSH by a negative number is undefined, and the BPF_RSH is an - * unsigned shift, so make the appropriate casts. + case BPF_LSH: + if (umax_val > 63) { + /* Shifts greater than 63 are undefined. This includes + * shifts by a negative number. + */ + mark_reg_unknown(regs, insn->dst_reg); + break; + } + /* We lose all sign bit information (except what we can pick + * up from var_off) */ - if (min_val < 0 || dst_reg->min_value < 0) { - dst_reg->min_value = BPF_REGISTER_MIN_RANGE; + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + /* If we might shift our top bit out, then we know nothing */ + if (dst_reg->umax_value > 1ULL << (63 - umax_val)) { + dst_reg->umin_value = 0; + dst_reg->umax_value = U64_MAX; } else { - dst_reg->min_value = - (u64)(dst_reg->min_value) >> min_val; + dst_reg->umin_value <<= umin_val; + dst_reg->umax_value <<= umax_val; + } + if (src_known) + dst_reg->var_off = tnum_lshift(dst_reg->var_off, umin_val); + else + dst_reg->var_off = tnum_lshift(tnum_unknown, umin_val); + /* We may learn something more from the var_off */ + __update_reg_bounds(dst_reg); + break; + case BPF_RSH: + if (umax_val > 63) { + /* Shifts greater than 63 are undefined. This includes + * shifts by a negative number. + */ + mark_reg_unknown(regs, insn->dst_reg); + break; } - if (min_val < 0) { - dst_reg->min_align = 1; + /* BPF_RSH is an unsigned shift, so make the appropriate casts */ + if (dst_reg->smin_value < 0) { + if (umin_val) { + /* Sign bit will be cleared */ + dst_reg->smin_value = 0; + } else { + /* Lost sign bit information */ + dst_reg->smin_value = S64_MIN; + dst_reg->smax_value = S64_MAX; + } } else { - dst_reg->min_align >>= (u64) min_val; - if (!dst_reg->min_align) - dst_reg->min_align = 1; + dst_reg->smin_value = + (u64)(dst_reg->smin_value) >> umax_val; } - if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) - dst_reg->max_value >>= max_val; + if (src_known) + dst_reg->var_off = tnum_rshift(dst_reg->var_off, + umin_val); + else + dst_reg->var_off = tnum_rshift(tnum_unknown, umin_val); + dst_reg->umin_value >>= umax_val; + dst_reg->umax_value >>= umin_val; + /* We may learn something more from the var_off */ + __update_reg_bounds(dst_reg); break; default: - reset_reg_range_values(regs, insn->dst_reg); + mark_reg_unknown(regs, insn->dst_reg); break; } - check_reg_overflow(dst_reg); + __reg_deduce_bounds(dst_reg); + __reg_bound_offset(dst_reg); + return 0; +} + +/* Handles ALU ops other than BPF_END, BPF_NEG and BPF_MOV: computes new min/max + * and var_off. + */ +static int adjust_reg_min_max_vals(struct bpf_verifier_env *env, + struct bpf_insn *insn) +{ + struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg, *src_reg; + struct bpf_reg_state *ptr_reg = NULL, off_reg = {0}; + u8 opcode = BPF_OP(insn->code); + int rc; + + dst_reg = ®s[insn->dst_reg]; + src_reg = NULL; + if (dst_reg->type != SCALAR_VALUE) + ptr_reg = dst_reg; + if (BPF_SRC(insn->code) == BPF_X) { + src_reg = ®s[insn->src_reg]; + if (src_reg->type != SCALAR_VALUE) { + if (dst_reg->type != SCALAR_VALUE) { + /* Combining two pointers by any ALU op yields + * an arbitrary scalar. + */ + if (!env->allow_ptr_leaks) { + verbose("R%d pointer %s pointer prohibited\n", + insn->dst_reg, + bpf_alu_string[opcode >> 4]); + return -EACCES; + } + mark_reg_unknown(regs, insn->dst_reg); + return 0; + } else { + /* scalar += pointer + * This is legal, but we have to reverse our + * src/dest handling in computing the range + */ + rc = adjust_ptr_min_max_vals(env, insn, + src_reg, dst_reg); + if (rc == -EACCES && env->allow_ptr_leaks) { + /* scalar += unknown scalar */ + __mark_reg_unknown(&off_reg); + return adjust_scalar_min_max_vals( + env, insn, + dst_reg, off_reg); + } + return rc; + } + } else if (ptr_reg) { + /* pointer += scalar */ + rc = adjust_ptr_min_max_vals(env, insn, + dst_reg, src_reg); + if (rc == -EACCES && env->allow_ptr_leaks) { + /* unknown scalar += scalar */ + __mark_reg_unknown(dst_reg); + return adjust_scalar_min_max_vals( + env, insn, dst_reg, *src_reg); + } + return rc; + } + } else { + /* Pretend the src is a reg with a known value, since we only + * need to be able to read from this state. + */ + off_reg.type = SCALAR_VALUE; + __mark_reg_known(&off_reg, insn->imm); + src_reg = &off_reg; + if (ptr_reg) { /* pointer += K */ + rc = adjust_ptr_min_max_vals(env, insn, + ptr_reg, src_reg); + if (rc == -EACCES && env->allow_ptr_leaks) { + /* unknown scalar += K */ + __mark_reg_unknown(dst_reg); + return adjust_scalar_min_max_vals( + env, insn, dst_reg, off_reg); + } + return rc; + } + } + + /* Got here implies adding two SCALAR_VALUEs */ + if (WARN_ON_ONCE(ptr_reg)) { + print_verifier_state(&env->cur_state); + verbose("verifier internal error: unexpected ptr_reg\n"); + return -EINVAL; + } + if (WARN_ON(!src_reg)) { + print_verifier_state(&env->cur_state); + verbose("verifier internal error: no src_reg\n"); + return -EINVAL; + } + return adjust_scalar_min_max_vals(env, insn, dst_reg, *src_reg); } /* check validity of 32-bit and 64-bit arithmetic operations */ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) { - struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg; + struct bpf_reg_state *regs = env->cur_state.regs; u8 opcode = BPF_OP(insn->code); int err; @@ -1969,14 +2292,15 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) } } else { if (insn->src_reg != BPF_REG_0 || insn->off != 0 || - (insn->imm != 16 && insn->imm != 32 && insn->imm != 64)) { + (insn->imm != 16 && insn->imm != 32 && insn->imm != 64) || + BPF_CLASS(insn->code) == BPF_ALU64) { verbose("BPF_END uses reserved fields\n"); return -EINVAL; } } /* check src operand */ - err = check_reg_arg(regs, insn->dst_reg, SRC_OP); + err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; @@ -1987,7 +2311,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) } /* check dest operand */ - err = check_reg_arg(regs, insn->dst_reg, DST_OP); + err = check_reg_arg(env, insn->dst_reg, DST_OP); if (err) return err; @@ -2000,7 +2324,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) } /* check src operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; } else { @@ -2011,15 +2335,10 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) } /* check dest operand */ - err = check_reg_arg(regs, insn->dst_reg, DST_OP); + err = check_reg_arg(env, insn->dst_reg, DST_OP); if (err) return err; - /* we are setting our register to something new, we need to - * reset its range values. - */ - reset_reg_range_values(regs, insn->dst_reg); - if (BPF_SRC(insn->code) == BPF_X) { if (BPF_CLASS(insn->code) == BPF_ALU64) { /* case: R1 = R2 @@ -2027,24 +2346,24 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) */ regs[insn->dst_reg] = regs[insn->src_reg]; } else { + /* R1 = (u32) R2 */ if (is_pointer_value(env, insn->src_reg)) { verbose("R%d partial copy of pointer\n", insn->src_reg); return -EACCES; } - mark_reg_unknown_value(regs, insn->dst_reg); + mark_reg_unknown(regs, insn->dst_reg); + /* high 32 bits are known zero. */ + regs[insn->dst_reg].var_off = tnum_cast( + regs[insn->dst_reg].var_off, 4); + __update_reg_bounds(®s[insn->dst_reg]); } } else { /* case: R = imm * remember the value we stored into this reg */ - regs[insn->dst_reg].type = CONST_IMM; - regs[insn->dst_reg].imm = insn->imm; - regs[insn->dst_reg].id = 0; - regs[insn->dst_reg].max_value = insn->imm; - regs[insn->dst_reg].min_value = insn->imm; - regs[insn->dst_reg].min_align = calc_align(insn->imm); - regs[insn->dst_reg].value_from_signed = false; + regs[insn->dst_reg].type = SCALAR_VALUE; + __mark_reg_known(regs + insn->dst_reg, insn->imm); } } else if (opcode > BPF_END) { @@ -2059,7 +2378,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) return -EINVAL; } /* check src1 operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; } else { @@ -2070,7 +2389,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) } /* check src2 operand */ - err = check_reg_arg(regs, insn->dst_reg, SRC_OP); + err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; @@ -2091,72 +2410,11 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) } /* check dest operand */ - err = check_reg_arg(regs, insn->dst_reg, DST_OP_NO_MARK); + err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK); if (err) return err; - dst_reg = ®s[insn->dst_reg]; - - /* first we want to adjust our ranges. */ - adjust_reg_min_max_vals(env, insn); - - /* pattern match 'bpf_add Rx, imm' instruction */ - if (opcode == BPF_ADD && BPF_CLASS(insn->code) == BPF_ALU64 && - dst_reg->type == FRAME_PTR && BPF_SRC(insn->code) == BPF_K) { - dst_reg->type = PTR_TO_STACK; - dst_reg->imm = insn->imm; - return 0; - } else if (opcode == BPF_ADD && - BPF_CLASS(insn->code) == BPF_ALU64 && - dst_reg->type == PTR_TO_STACK && - ((BPF_SRC(insn->code) == BPF_X && - regs[insn->src_reg].type == CONST_IMM) || - BPF_SRC(insn->code) == BPF_K)) { - if (BPF_SRC(insn->code) == BPF_X) - dst_reg->imm += regs[insn->src_reg].imm; - else - dst_reg->imm += insn->imm; - return 0; - } else if (opcode == BPF_ADD && - BPF_CLASS(insn->code) == BPF_ALU64 && - (dst_reg->type == PTR_TO_PACKET || - (BPF_SRC(insn->code) == BPF_X && - regs[insn->src_reg].type == PTR_TO_PACKET))) { - /* ptr_to_packet += K|X */ - return check_packet_ptr_add(env, insn); - } else if (BPF_CLASS(insn->code) == BPF_ALU64 && - dst_reg->type == UNKNOWN_VALUE && - env->allow_ptr_leaks) { - /* unknown += K|X */ - return evaluate_reg_alu(env, insn); - } else if (BPF_CLASS(insn->code) == BPF_ALU64 && - dst_reg->type == CONST_IMM && - env->allow_ptr_leaks) { - /* reg_imm += K|X */ - return evaluate_reg_imm_alu(env, insn); - } else if (is_pointer_value(env, insn->dst_reg)) { - verbose("R%d pointer arithmetic prohibited\n", - insn->dst_reg); - return -EACCES; - } else if (BPF_SRC(insn->code) == BPF_X && - is_pointer_value(env, insn->src_reg)) { - verbose("R%d pointer arithmetic prohibited\n", - insn->src_reg); - return -EACCES; - } - - /* If we did pointer math on a map value then just set it to our - * PTR_TO_MAP_VALUE_ADJ type so we can deal with any stores or - * loads to this register appropriately, otherwise just mark the - * register as unknown. - */ - if (env->allow_ptr_leaks && - BPF_CLASS(insn->code) == BPF_ALU64 && opcode == BPF_ADD && - (dst_reg->type == PTR_TO_MAP_VALUE || - dst_reg->type == PTR_TO_MAP_VALUE_ADJ)) - dst_reg->type = PTR_TO_MAP_VALUE_ADJ; - else - mark_reg_unknown_value(regs, insn->dst_reg); + return adjust_reg_min_max_vals(env, insn); } return 0; @@ -2168,27 +2426,48 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state, struct bpf_reg_state *regs = state->regs, *reg; int i; - /* LLVM can generate two kind of checks: + if (dst_reg->off < 0) + /* This doesn't give us any range */ + return; + + if (dst_reg->umax_value > MAX_PACKET_OFF || + dst_reg->umax_value + dst_reg->off > MAX_PACKET_OFF) + /* Risk of overflow. For instance, ptr + (1<<63) may be less + * than pkt_end, but that's because it's also less than pkt. + */ + return; + + /* LLVM can generate four kind of checks: * - * Type 1: + * Type 1/2: * * r2 = r3; * r2 += 8; * if (r2 > pkt_end) goto * * + * r2 = r3; + * r2 += 8; + * if (r2 < pkt_end) goto + * + * * Where: * r2 == dst_reg, pkt_end == src_reg * r2=pkt(id=n,off=8,r=0) * r3=pkt(id=n,off=0,r=0) * - * Type 2: + * Type 3/4: * * r2 = r3; * r2 += 8; * if (pkt_end >= r2) goto * * + * r2 = r3; + * r2 += 8; + * if (pkt_end <= r2) goto + * + * * Where: * pkt_end == dst_reg, r2 == src_reg * r2=pkt(id=n,off=8,r=0) @@ -2198,193 +2477,247 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state, * so that range of bytes [r3, r3 + 8) is safe to access. */ + /* If our ids match, then we must have the same max_value. And we + * don't care about the other reg's fixed offset, since if it's too big + * the range won't allow anything. + * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16. + */ for (i = 0; i < MAX_BPF_REG; i++) if (regs[i].type == PTR_TO_PACKET && regs[i].id == dst_reg->id) /* keep the maximum range already checked */ - regs[i].range = max(regs[i].range, dst_reg->off); + regs[i].range = max_t(u16, regs[i].range, dst_reg->off); for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { if (state->stack_slot_type[i] != STACK_SPILL) continue; reg = &state->spilled_regs[i / BPF_REG_SIZE]; if (reg->type == PTR_TO_PACKET && reg->id == dst_reg->id) - reg->range = max(reg->range, dst_reg->off); + reg->range = max_t(u16, reg->range, dst_reg->off); } } /* Adjusts the register min/max values in the case that the dst_reg is the * variable register that we are working on, and src_reg is a constant or we're * simply doing a BPF_K check. + * In JEQ/JNE cases we also adjust the var_off values. */ static void reg_set_min_max(struct bpf_reg_state *true_reg, struct bpf_reg_state *false_reg, u64 val, u8 opcode) { - bool value_from_signed = true; - bool is_range = true; + /* If the dst_reg is a pointer, we can't learn anything about its + * variable offset from the compare (unless src_reg were a pointer into + * the same object, but we don't bother with that. + * Since false_reg and true_reg have the same type by construction, we + * only need to check one of them for pointerness. + */ + if (__is_pointer_value(false, false_reg)) + return; switch (opcode) { case BPF_JEQ: /* If this is false then we know nothing Jon Snow, but if it is * true then we know for sure. */ - true_reg->max_value = true_reg->min_value = val; - is_range = false; + __mark_reg_known(true_reg, val); break; case BPF_JNE: /* If this is true we know nothing Jon Snow, but if it is false * we know the value for sure; */ - false_reg->max_value = false_reg->min_value = val; - is_range = false; + __mark_reg_known(false_reg, val); break; case BPF_JGT: - value_from_signed = false; - /* fallthrough */ + false_reg->umax_value = min(false_reg->umax_value, val); + true_reg->umin_value = max(true_reg->umin_value, val + 1); + break; case BPF_JSGT: - if (true_reg->value_from_signed != value_from_signed) - reset_reg_range_values(true_reg, 0); - if (false_reg->value_from_signed != value_from_signed) - reset_reg_range_values(false_reg, 0); - if (opcode == BPF_JGT) { - /* Unsigned comparison, the minimum value is 0. */ - false_reg->min_value = 0; - } - /* If this is false then we know the maximum val is val, - * otherwise we know the min val is val+1. - */ - false_reg->max_value = val; - false_reg->value_from_signed = value_from_signed; - true_reg->min_value = val + 1; - true_reg->value_from_signed = value_from_signed; + false_reg->smax_value = min_t(s64, false_reg->smax_value, val); + true_reg->smin_value = max_t(s64, true_reg->smin_value, val + 1); + break; + case BPF_JLT: + false_reg->umin_value = max(false_reg->umin_value, val); + true_reg->umax_value = min(true_reg->umax_value, val - 1); + break; + case BPF_JSLT: + false_reg->smin_value = max_t(s64, false_reg->smin_value, val); + true_reg->smax_value = min_t(s64, true_reg->smax_value, val - 1); break; case BPF_JGE: - value_from_signed = false; - /* fallthrough */ + false_reg->umax_value = min(false_reg->umax_value, val - 1); + true_reg->umin_value = max(true_reg->umin_value, val); + break; case BPF_JSGE: - if (true_reg->value_from_signed != value_from_signed) - reset_reg_range_values(true_reg, 0); - if (false_reg->value_from_signed != value_from_signed) - reset_reg_range_values(false_reg, 0); - if (opcode == BPF_JGE) { - /* Unsigned comparison, the minimum value is 0. */ - false_reg->min_value = 0; - } - /* If this is false then we know the maximum value is val - 1, - * otherwise we know the mimimum value is val. - */ - false_reg->max_value = val - 1; - false_reg->value_from_signed = value_from_signed; - true_reg->min_value = val; - true_reg->value_from_signed = value_from_signed; + false_reg->smax_value = min_t(s64, false_reg->smax_value, val - 1); + true_reg->smin_value = max_t(s64, true_reg->smin_value, val); + break; + case BPF_JLE: + false_reg->umin_value = max(false_reg->umin_value, val + 1); + true_reg->umax_value = min(true_reg->umax_value, val); + break; + case BPF_JSLE: + false_reg->smin_value = max_t(s64, false_reg->smin_value, val + 1); + true_reg->smax_value = min_t(s64, true_reg->smax_value, val); break; default: break; } - check_reg_overflow(false_reg); - check_reg_overflow(true_reg); - if (is_range) { - if (__is_pointer_value(false, false_reg)) - reset_reg_range_values(false_reg, 0); - if (__is_pointer_value(false, true_reg)) - reset_reg_range_values(true_reg, 0); - } + __reg_deduce_bounds(false_reg); + __reg_deduce_bounds(true_reg); + /* We might have learned some bits from the bounds. */ + __reg_bound_offset(false_reg); + __reg_bound_offset(true_reg); + /* Intersecting with the old var_off might have improved our bounds + * slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), + * then new var_off is (0; 0x7f...fc) which improves our umax. + */ + __update_reg_bounds(false_reg); + __update_reg_bounds(true_reg); } -/* Same as above, but for the case that dst_reg is a CONST_IMM reg and src_reg - * is the variable reg. +/* Same as above, but for the case that dst_reg holds a constant and src_reg is + * the variable reg. */ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg, struct bpf_reg_state *false_reg, u64 val, u8 opcode) { - bool value_from_signed = true; - bool is_range = true; + if (__is_pointer_value(false, false_reg)) + return; switch (opcode) { case BPF_JEQ: /* If this is false then we know nothing Jon Snow, but if it is * true then we know for sure. */ - true_reg->max_value = true_reg->min_value = val; - is_range = false; + __mark_reg_known(true_reg, val); break; case BPF_JNE: /* If this is true we know nothing Jon Snow, but if it is false * we know the value for sure; */ - false_reg->max_value = false_reg->min_value = val; - is_range = false; + __mark_reg_known(false_reg, val); break; case BPF_JGT: - value_from_signed = false; - /* fallthrough */ + true_reg->umax_value = min(true_reg->umax_value, val - 1); + false_reg->umin_value = max(false_reg->umin_value, val); + break; case BPF_JSGT: - if (true_reg->value_from_signed != value_from_signed) - reset_reg_range_values(true_reg, 0); - if (false_reg->value_from_signed != value_from_signed) - reset_reg_range_values(false_reg, 0); - if (opcode == BPF_JGT) { - /* Unsigned comparison, the minimum value is 0. */ - true_reg->min_value = 0; - } - /* - * If this is false, then the val is <= the register, if it is - * true the register <= to the val. - */ - false_reg->min_value = val; - false_reg->value_from_signed = value_from_signed; - true_reg->max_value = val - 1; - true_reg->value_from_signed = value_from_signed; + true_reg->smax_value = min_t(s64, true_reg->smax_value, val - 1); + false_reg->smin_value = max_t(s64, false_reg->smin_value, val); + break; + case BPF_JLT: + true_reg->umin_value = max(true_reg->umin_value, val + 1); + false_reg->umax_value = min(false_reg->umax_value, val); + break; + case BPF_JSLT: + true_reg->smin_value = max_t(s64, true_reg->smin_value, val + 1); + false_reg->smax_value = min_t(s64, false_reg->smax_value, val); break; case BPF_JGE: - value_from_signed = false; - /* fallthrough */ + true_reg->umax_value = min(true_reg->umax_value, val); + false_reg->umin_value = max(false_reg->umin_value, val + 1); + break; case BPF_JSGE: - if (true_reg->value_from_signed != value_from_signed) - reset_reg_range_values(true_reg, 0); - if (false_reg->value_from_signed != value_from_signed) - reset_reg_range_values(false_reg, 0); - if (opcode == BPF_JGE) { - /* Unsigned comparison, the minimum value is 0. */ - true_reg->min_value = 0; - } - /* If this is false then constant < register, if it is true then - * the register < constant. - */ - false_reg->min_value = val + 1; - false_reg->value_from_signed = value_from_signed; - true_reg->max_value = val; - true_reg->value_from_signed = value_from_signed; + true_reg->smax_value = min_t(s64, true_reg->smax_value, val); + false_reg->smin_value = max_t(s64, false_reg->smin_value, val + 1); + break; + case BPF_JLE: + true_reg->umin_value = max(true_reg->umin_value, val); + false_reg->umax_value = min(false_reg->umax_value, val - 1); + break; + case BPF_JSLE: + true_reg->smin_value = max_t(s64, true_reg->smin_value, val); + false_reg->smax_value = min_t(s64, false_reg->smax_value, val - 1); break; default: break; } - check_reg_overflow(false_reg); - check_reg_overflow(true_reg); - if (is_range) { - if (__is_pointer_value(false, false_reg)) - reset_reg_range_values(false_reg, 0); - if (__is_pointer_value(false, true_reg)) - reset_reg_range_values(true_reg, 0); + __reg_deduce_bounds(false_reg); + __reg_deduce_bounds(true_reg); + /* We might have learned some bits from the bounds. */ + __reg_bound_offset(false_reg); + __reg_bound_offset(true_reg); + /* Intersecting with the old var_off might have improved our bounds + * slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), + * then new var_off is (0; 0x7f...fc) which improves our umax. + */ + __update_reg_bounds(false_reg); + __update_reg_bounds(true_reg); +} + +/* Regs are known to be equal, so intersect their min/max/var_off */ +static void __reg_combine_min_max(struct bpf_reg_state *src_reg, + struct bpf_reg_state *dst_reg) +{ + src_reg->umin_value = dst_reg->umin_value = max(src_reg->umin_value, + dst_reg->umin_value); + src_reg->umax_value = dst_reg->umax_value = min(src_reg->umax_value, + dst_reg->umax_value); + src_reg->smin_value = dst_reg->smin_value = max(src_reg->smin_value, + dst_reg->smin_value); + src_reg->smax_value = dst_reg->smax_value = min(src_reg->smax_value, + dst_reg->smax_value); + src_reg->var_off = dst_reg->var_off = tnum_intersect(src_reg->var_off, + dst_reg->var_off); + /* We might have learned new bounds from the var_off. */ + __update_reg_bounds(src_reg); + __update_reg_bounds(dst_reg); + /* We might have learned something about the sign bit. */ + __reg_deduce_bounds(src_reg); + __reg_deduce_bounds(dst_reg); + /* We might have learned some bits from the bounds. */ + __reg_bound_offset(src_reg); + __reg_bound_offset(dst_reg); + /* Intersecting with the old var_off might have improved our bounds + * slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), + * then new var_off is (0; 0x7f...fc) which improves our umax. + */ + __update_reg_bounds(src_reg); + __update_reg_bounds(dst_reg); +} + +static void reg_combine_min_max(struct bpf_reg_state *true_src, + struct bpf_reg_state *true_dst, + struct bpf_reg_state *false_src, + struct bpf_reg_state *false_dst, + u8 opcode) +{ + switch (opcode) { + case BPF_JEQ: + __reg_combine_min_max(true_src, true_dst); + break; + case BPF_JNE: + __reg_combine_min_max(false_src, false_dst); + break; } } static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, - enum bpf_reg_type type) + bool is_null) { struct bpf_reg_state *reg = ®s[regno]; if (reg->type == PTR_TO_MAP_VALUE_OR_NULL && reg->id == id) { - if (type == UNKNOWN_VALUE) { - __mark_reg_unknown_value(regs, regno); + /* Old offset (both fixed and variable parts) should + * have been known-zero, because we don't allow pointer + * arithmetic on pointers that might be NULL. + */ + if (WARN_ON_ONCE(reg->smin_value || reg->smax_value || + !tnum_equals_const(reg->var_off, 0) || + reg->off)) { + __mark_reg_known_zero(reg); + reg->off = 0; + } + if (is_null) { + reg->type = SCALAR_VALUE; } else if (reg->map_ptr->inner_map_meta) { reg->type = CONST_PTR_TO_MAP; reg->map_ptr = reg->map_ptr->inner_map_meta; } else { - reg->type = type; + reg->type = PTR_TO_MAP_VALUE; } /* We don't need id from this point onwards anymore, thus we * should better reset it, so that state pruning has chances @@ -2398,19 +2731,19 @@ static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, * be folded together at some point. */ static void mark_map_regs(struct bpf_verifier_state *state, u32 regno, - enum bpf_reg_type type) + bool is_null) { struct bpf_reg_state *regs = state->regs; u32 id = regs[regno].id; int i; for (i = 0; i < MAX_BPF_REG; i++) - mark_map_reg(regs, i, id, type); + mark_map_reg(regs, i, id, is_null); for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { if (state->stack_slot_type[i] != STACK_SPILL) continue; - mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE, id, type); + mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE, id, is_null); } } @@ -2422,7 +2755,7 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, u8 opcode = BPF_OP(insn->code); int err; - if (opcode > BPF_EXIT) { + if (opcode > BPF_JSLE) { verbose("invalid BPF_JMP opcode %x\n", opcode); return -EINVAL; } @@ -2434,7 +2767,7 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, } /* check src1 operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; @@ -2451,7 +2784,7 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, } /* check src2 operand */ - err = check_reg_arg(regs, insn->dst_reg, SRC_OP); + err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; @@ -2460,7 +2793,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, /* detect if R == 0 where R was initialized to zero earlier */ if (BPF_SRC(insn->code) == BPF_K && (opcode == BPF_JEQ || opcode == BPF_JNE) && - dst_reg->type == CONST_IMM && dst_reg->imm == insn->imm) { + dst_reg->type == SCALAR_VALUE && + tnum_equals_const(dst_reg->var_off, insn->imm)) { if (opcode == BPF_JEQ) { /* if (imm == imm) goto pc+off; * only follow the goto, ignore fall-through @@ -2482,17 +2816,30 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, /* detect if we are comparing against a constant value so we can adjust * our min/max values for our dst register. + * this is only legit if both are scalars (or pointers to the same + * object, I suppose, but we don't support that right now), because + * otherwise the different base pointers mean the offsets aren't + * comparable. */ if (BPF_SRC(insn->code) == BPF_X) { - if (regs[insn->src_reg].type == CONST_IMM) - reg_set_min_max(&other_branch->regs[insn->dst_reg], - dst_reg, regs[insn->src_reg].imm, - opcode); - else if (dst_reg->type == CONST_IMM) - reg_set_min_max_inv(&other_branch->regs[insn->src_reg], - ®s[insn->src_reg], dst_reg->imm, - opcode); - } else { + if (dst_reg->type == SCALAR_VALUE && + regs[insn->src_reg].type == SCALAR_VALUE) { + if (tnum_is_const(regs[insn->src_reg].var_off)) + reg_set_min_max(&other_branch->regs[insn->dst_reg], + dst_reg, regs[insn->src_reg].var_off.value, + opcode); + else if (tnum_is_const(dst_reg->var_off)) + reg_set_min_max_inv(&other_branch->regs[insn->src_reg], + ®s[insn->src_reg], + dst_reg->var_off.value, opcode); + else if (opcode == BPF_JEQ || opcode == BPF_JNE) + /* Comparing for equality, we can combine knowledge */ + reg_combine_min_max(&other_branch->regs[insn->src_reg], + &other_branch->regs[insn->dst_reg], + ®s[insn->src_reg], + ®s[insn->dst_reg], opcode); + } + } else if (dst_reg->type == SCALAR_VALUE) { reg_set_min_max(&other_branch->regs[insn->dst_reg], dst_reg, insn->imm, opcode); } @@ -2504,18 +2851,24 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, /* Mark all identical map registers in each branch as either * safe or unknown depending R == 0 or R != 0 conditional. */ - mark_map_regs(this_branch, insn->dst_reg, - opcode == BPF_JEQ ? PTR_TO_MAP_VALUE : UNKNOWN_VALUE); - mark_map_regs(other_branch, insn->dst_reg, - opcode == BPF_JEQ ? UNKNOWN_VALUE : PTR_TO_MAP_VALUE); + mark_map_regs(this_branch, insn->dst_reg, opcode == BPF_JNE); + mark_map_regs(other_branch, insn->dst_reg, opcode == BPF_JEQ); } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT && dst_reg->type == PTR_TO_PACKET && regs[insn->src_reg].type == PTR_TO_PACKET_END) { find_good_pkt_pointers(this_branch, dst_reg); + } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLT && + dst_reg->type == PTR_TO_PACKET && + regs[insn->src_reg].type == PTR_TO_PACKET_END) { + find_good_pkt_pointers(other_branch, dst_reg); } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGE && dst_reg->type == PTR_TO_PACKET_END && regs[insn->src_reg].type == PTR_TO_PACKET) { find_good_pkt_pointers(other_branch, ®s[insn->src_reg]); + } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLE && + dst_reg->type == PTR_TO_PACKET_END && + regs[insn->src_reg].type == PTR_TO_PACKET) { + find_good_pkt_pointers(this_branch, ®s[insn->src_reg]); } else if (is_pointer_value(env, insn->dst_reg)) { verbose("R%d pointer comparison prohibited\n", insn->dst_reg); return -EACCES; @@ -2548,16 +2901,15 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) return -EINVAL; } - err = check_reg_arg(regs, insn->dst_reg, DST_OP); + err = check_reg_arg(env, insn->dst_reg, DST_OP); if (err) return err; if (insn->src_reg == 0) { u64 imm = ((u64)(insn + 1)->imm << 32) | (u32)insn->imm; - regs[insn->dst_reg].type = CONST_IMM; - regs[insn->dst_reg].imm = imm; - regs[insn->dst_reg].id = 0; + regs[insn->dst_reg].type = SCALAR_VALUE; + __mark_reg_known(®s[insn->dst_reg], imm); return 0; } @@ -2615,7 +2967,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) } /* check whether implicit source operand (register R6) is readable */ - err = check_reg_arg(regs, BPF_REG_6, SRC_OP); + err = check_reg_arg(env, BPF_REG_6, SRC_OP); if (err) return err; @@ -2626,19 +2978,22 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn) if (mode == BPF_IND) { /* check explicit source operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; } /* reset caller saved regs to unreadable */ - for (i = 0; i < CALLER_SAVED_REGS; i++) + for (i = 0; i < CALLER_SAVED_REGS; i++) { mark_reg_not_init(regs, caller_saved[i]); + check_reg_arg(env, caller_saved[i], DST_OP_NO_MARK); + } /* mark destination R0 register as readable, since it contains - * the value fetched from the packet + * the value fetched from the packet. + * Already marked as written above. */ - regs[BPF_REG_0].type = UNKNOWN_VALUE; + mark_reg_unknown(regs, BPF_REG_0); return 0; } @@ -2841,57 +3196,144 @@ static int check_cfg(struct bpf_verifier_env *env) return ret; } -/* the following conditions reduce the number of explored insns - * from ~140k to ~80k for ultra large programs that use a lot of ptr_to_packet +/* check %cur's range satisfies %old's */ +static bool range_within(struct bpf_reg_state *old, + struct bpf_reg_state *cur) +{ + return old->umin_value <= cur->umin_value && + old->umax_value >= cur->umax_value && + old->smin_value <= cur->smin_value && + old->smax_value >= cur->smax_value; +} + +/* Maximum number of register states that can exist at once */ +#define ID_MAP_SIZE (MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) +struct idpair { + u32 old; + u32 cur; +}; + +/* If in the old state two registers had the same id, then they need to have + * the same id in the new state as well. But that id could be different from + * the old state, so we need to track the mapping from old to new ids. + * Once we have seen that, say, a reg with old id 5 had new id 9, any subsequent + * regs with old id 5 must also have new id 9 for the new state to be safe. But + * regs with a different old id could still have new id 9, we don't care about + * that. + * So we look through our idmap to see if this old id has been seen before. If + * so, we require the new id to match; otherwise, we add the id pair to the map. */ -static bool compare_ptrs_to_packet(struct bpf_verifier_env *env, - struct bpf_reg_state *old, - struct bpf_reg_state *cur) +static bool check_ids(u32 old_id, u32 cur_id, struct idpair *idmap) { - if (old->id != cur->id) - return false; + unsigned int i; + + for (i = 0; i < ID_MAP_SIZE; i++) { + if (!idmap[i].old) { + /* Reached an empty slot; haven't seen this id before */ + idmap[i].old = old_id; + idmap[i].cur = cur_id; + return true; + } + if (idmap[i].old == old_id) + return idmap[i].cur == cur_id; + } + /* We ran out of idmap slots, which should be impossible */ + WARN_ON_ONCE(1); + return false; +} - /* old ptr_to_packet is more conservative, since it allows smaller - * range. Ex: - * old(off=0,r=10) is equal to cur(off=0,r=20), because - * old(off=0,r=10) means that with range=10 the verifier proceeded - * further and found no issues with the program. Now we're in the same - * spot with cur(off=0,r=20), so we're safe too, since anything further - * will only be looking at most 10 bytes after this pointer. - */ - if (old->off == cur->off && old->range < cur->range) +/* Returns true if (rold safe implies rcur safe) */ +static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, + struct idpair *idmap) +{ + if (!(rold->live & REG_LIVE_READ)) + /* explored state didn't use this */ return true; - /* old(off=20,r=10) is equal to cur(off=22,re=22 or 5 or 0) - * since both cannot be used for packet access and safe(old) - * pointer has smaller off that could be used for further - * 'if (ptr > data_end)' check - * Ex: - * old(off=20,r=10) and cur(off=22,r=22) and cur(off=22,r=0) mean - * that we cannot access the packet. - * The safe range is: - * [ptr, ptr + range - off) - * so whenever off >=range, it means no safe bytes from this pointer. - * When comparing old->off <= cur->off, it means that older code - * went with smaller offset and that offset was later - * used to figure out the safe range after 'if (ptr > data_end)' check - * Say, 'old' state was explored like: - * ... R3(off=0, r=0) - * R4 = R3 + 20 - * ... now R4(off=20,r=0) <-- here - * if (R4 > data_end) - * ... R4(off=20,r=20), R3(off=0,r=20) and R3 can be used to access. - * ... the code further went all the way to bpf_exit. - * Now the 'cur' state at the mark 'here' has R4(off=30,r=0). - * old_R4(off=20,r=0) equal to cur_R4(off=30,r=0), since if the verifier - * goes further, such cur_R4 will give larger safe packet range after - * 'if (R4 > data_end)' and all further insn were already good with r=20, - * so they will be good with r=30 and we can prune the search. - */ - if (!env->strict_alignment && old->off <= cur->off && - old->off >= old->range && cur->off >= cur->range) + if (memcmp(rold, rcur, offsetof(struct bpf_reg_state, live)) == 0) + return true; + + if (rold->type == NOT_INIT) + /* explored state can't have used this */ return true; + if (rcur->type == NOT_INIT) + return false; + switch (rold->type) { + case SCALAR_VALUE: + if (rcur->type == SCALAR_VALUE) { + /* new val must satisfy old val knowledge */ + return range_within(rold, rcur) && + tnum_in(rold->var_off, rcur->var_off); + } else { + /* if we knew anything about the old value, we're not + * equal, because we can't know anything about the + * scalar value of the pointer in the new value. + */ + return rold->umin_value == 0 && + rold->umax_value == U64_MAX && + rold->smin_value == S64_MIN && + rold->smax_value == S64_MAX && + tnum_is_unknown(rold->var_off); + } + case PTR_TO_MAP_VALUE: + /* If the new min/max/var_off satisfy the old ones and + * everything else matches, we are OK. + * We don't care about the 'id' value, because nothing + * uses it for PTR_TO_MAP_VALUE (only for ..._OR_NULL) + */ + return memcmp(rold, rcur, offsetof(struct bpf_reg_state, id)) == 0 && + range_within(rold, rcur) && + tnum_in(rold->var_off, rcur->var_off); + case PTR_TO_MAP_VALUE_OR_NULL: + /* a PTR_TO_MAP_VALUE could be safe to use as a + * PTR_TO_MAP_VALUE_OR_NULL into the same map. + * However, if the old PTR_TO_MAP_VALUE_OR_NULL then got NULL- + * checked, doing so could have affected others with the same + * id, and we can't check for that because we lost the id when + * we converted to a PTR_TO_MAP_VALUE. + */ + if (rcur->type != PTR_TO_MAP_VALUE_OR_NULL) + return false; + if (memcmp(rold, rcur, offsetof(struct bpf_reg_state, id))) + return false; + /* Check our ids match any regs they're supposed to */ + return check_ids(rold->id, rcur->id, idmap); + case PTR_TO_PACKET: + if (rcur->type != PTR_TO_PACKET) + return false; + /* We must have at least as much range as the old ptr + * did, so that any accesses which were safe before are + * still safe. This is true even if old range < old off, + * since someone could have accessed through (ptr - k), or + * even done ptr -= k in a register, to get a safe access. + */ + if (rold->range > rcur->range) + return false; + /* If the offsets don't match, we can't trust our alignment; + * nor can we be sure that we won't fall out of range. + */ + if (rold->off != rcur->off) + return false; + /* id relations must be preserved */ + if (rold->id && !check_ids(rold->id, rcur->id, idmap)) + return false; + /* new val must satisfy old val knowledge */ + return range_within(rold, rcur) && + tnum_in(rold->var_off, rcur->var_off); + case PTR_TO_CTX: + case CONST_PTR_TO_MAP: + case PTR_TO_STACK: + case PTR_TO_PACKET_END: + /* Only valid matches are exact, which memcmp() above + * would have accepted + */ + default: + /* Don't know what's going on, just say it's not safe */ + return false; + } + /* Shouldn't get here; if we do, say it's not safe */ + WARN_ON_ONCE(1); return false; } @@ -2925,44 +3367,18 @@ static bool states_equal(struct bpf_verifier_env *env, struct bpf_verifier_state *old, struct bpf_verifier_state *cur) { - bool varlen_map_access = env->varlen_map_value_access; - struct bpf_reg_state *rold, *rcur; + struct idpair *idmap; + bool ret = false; int i; - for (i = 0; i < MAX_BPF_REG; i++) { - rold = &old->regs[i]; - rcur = &cur->regs[i]; - - if (memcmp(rold, rcur, sizeof(*rold)) == 0) - continue; - - /* If the ranges were not the same, but everything else was and - * we didn't do a variable access into a map then we are a-ok. - */ - if (!varlen_map_access && - memcmp(rold, rcur, offsetofend(struct bpf_reg_state, id)) == 0) - continue; - - /* If we didn't map access then again we don't care about the - * mismatched range values and it's ok if our old type was - * UNKNOWN and we didn't go to a NOT_INIT'ed reg. - */ - if (rold->type == NOT_INIT || - (!varlen_map_access && rold->type == UNKNOWN_VALUE && - rcur->type != NOT_INIT)) - continue; - - /* Don't care about the reg->id in this case. */ - if (rold->type == PTR_TO_MAP_VALUE_OR_NULL && - rcur->type == PTR_TO_MAP_VALUE_OR_NULL && - rold->map_ptr == rcur->map_ptr) - continue; - - if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET && - compare_ptrs_to_packet(env, rold, rcur)) - continue; - + idmap = kcalloc(ID_MAP_SIZE, sizeof(struct idpair), GFP_KERNEL); + /* If we failed to allocate the idmap, just say it's not safe */ + if (!idmap) return false; + + for (i = 0; i < MAX_BPF_REG; i++) { + if (!regsafe(&old->regs[i], &cur->regs[i], idmap)) + goto out_free; } for (i = 0; i < MAX_BPF_STACK; i++) { @@ -2974,35 +3390,104 @@ static bool states_equal(struct bpf_verifier_env *env, * this verifier states are not equivalent, * return false to continue verification of this path */ - return false; + goto out_free; if (i % BPF_REG_SIZE) continue; if (old->stack_slot_type[i] != STACK_SPILL) continue; - if (memcmp(&old->spilled_regs[i / BPF_REG_SIZE], - &cur->spilled_regs[i / BPF_REG_SIZE], - sizeof(old->spilled_regs[0]))) - /* when explored and current stack slot types are - * the same, check that stored pointers types + if (!regsafe(&old->spilled_regs[i / BPF_REG_SIZE], + &cur->spilled_regs[i / BPF_REG_SIZE], + idmap)) + /* when explored and current stack slot are both storing + * spilled registers, check that stored pointers types * are the same as well. * Ex: explored safe path could have stored - * (bpf_reg_state) {.type = PTR_TO_STACK, .imm = -8} + * (bpf_reg_state) {.type = PTR_TO_STACK, .off = -8} * but current path has stored: - * (bpf_reg_state) {.type = PTR_TO_STACK, .imm = -16} + * (bpf_reg_state) {.type = PTR_TO_STACK, .off = -16} * such verifier states are not equivalent. * return false to continue verification of this path */ - return false; + goto out_free; else continue; } - return true; + ret = true; +out_free: + kfree(idmap); + return ret; +} + +/* A write screens off any subsequent reads; but write marks come from the + * straight-line code between a state and its parent. When we arrive at a + * jump target (in the first iteration of the propagate_liveness() loop), + * we didn't arrive by the straight-line code, so read marks in state must + * propagate to parent regardless of state's write marks. + */ +static bool do_propagate_liveness(const struct bpf_verifier_state *state, + struct bpf_verifier_state *parent) +{ + bool writes = parent == state->parent; /* Observe write marks */ + bool touched = false; /* any changes made? */ + int i; + + if (!parent) + return touched; + /* Propagate read liveness of registers... */ + BUILD_BUG_ON(BPF_REG_FP + 1 != MAX_BPF_REG); + /* We don't need to worry about FP liveness because it's read-only */ + for (i = 0; i < BPF_REG_FP; i++) { + if (parent->regs[i].live & REG_LIVE_READ) + continue; + if (writes && (state->regs[i].live & REG_LIVE_WRITTEN)) + continue; + if (state->regs[i].live & REG_LIVE_READ) { + parent->regs[i].live |= REG_LIVE_READ; + touched = true; + } + } + /* ... and stack slots */ + for (i = 0; i < MAX_BPF_STACK / BPF_REG_SIZE; i++) { + if (parent->stack_slot_type[i * BPF_REG_SIZE] != STACK_SPILL) + continue; + if (state->stack_slot_type[i * BPF_REG_SIZE] != STACK_SPILL) + continue; + if (parent->spilled_regs[i].live & REG_LIVE_READ) + continue; + if (writes && (state->spilled_regs[i].live & REG_LIVE_WRITTEN)) + continue; + if (state->spilled_regs[i].live & REG_LIVE_READ) { + parent->spilled_regs[i].live |= REG_LIVE_READ; + touched = true; + } + } + return touched; +} + +/* "parent" is "a state from which we reach the current state", but initially + * it is not the state->parent (i.e. "the state whose straight-line code leads + * to the current state"), instead it is the state that happened to arrive at + * a (prunable) equivalent of the current state. See comment above + * do_propagate_liveness() for consequences of this. + * This function is just a more efficient way of calling mark_reg_read() or + * mark_stack_slot_read() on each reg in "parent" that is read in "state", + * though it requires that parent != state->parent in the call arguments. + */ +static void propagate_liveness(const struct bpf_verifier_state *state, + struct bpf_verifier_state *parent) +{ + while (do_propagate_liveness(state, parent)) { + /* Something changed, so we need to feed those changes onward */ + state = parent; + parent = state->parent; + } } static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) { struct bpf_verifier_state_list *new_sl; struct bpf_verifier_state_list *sl; + int i; sl = env->explored_states[insn_idx]; if (!sl) @@ -3012,11 +3497,20 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) return 0; while (sl != STATE_LIST_MARK) { - if (states_equal(env, &sl->state, &env->cur_state)) + if (states_equal(env, &sl->state, &env->cur_state)) { /* reached equivalent register/stack state, - * prune the search + * prune the search. + * Registers read by the continuation are read by us. + * If we have any write marks in env->cur_state, they + * will prevent corresponding reads in the continuation + * from reaching our parent (an explored_state). Our + * own state will get the read marks recorded, but + * they'll be immediately forgotten as we're pruning + * this state and will pop a new one. */ + propagate_liveness(&sl->state, &env->cur_state); return 1; + } sl = sl->next; } @@ -3034,6 +3528,19 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) memcpy(&new_sl->state, &env->cur_state, sizeof(env->cur_state)); new_sl->next = env->explored_states[insn_idx]; env->explored_states[insn_idx] = new_sl; + /* connect new state to parentage chain */ + env->cur_state.parent = &new_sl->state; + /* clear write marks in current state: the writes we did are not writes + * our child did, so they don't screen off its reads from us. + * (There are no read marks in current state, because reads always mark + * their parent and current state never has children yet. Only + * explored_states can get read marks.) + */ + for (i = 0; i < BPF_REG_FP; i++) + env->cur_state.regs[i].live = REG_LIVE_NONE; + for (i = 0; i < MAX_BPF_STACK / BPF_REG_SIZE; i++) + if (env->cur_state.stack_slot_type[i * BPF_REG_SIZE] == STACK_SPILL) + env->cur_state.spilled_regs[i].live = REG_LIVE_NONE; return 0; } @@ -3057,8 +3564,8 @@ static int do_check(struct bpf_verifier_env *env) bool do_print_state = false; init_reg_state(regs); + state->parent = NULL; insn_idx = 0; - env->varlen_map_value_access = false; for (;;) { struct bpf_insn *insn; u8 class; @@ -3127,11 +3634,11 @@ static int do_check(struct bpf_verifier_env *env) /* check for reserved fields is already done */ /* check src operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; - err = check_reg_arg(regs, insn->dst_reg, DST_OP_NO_MARK); + err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK); if (err) return err; @@ -3181,11 +3688,11 @@ static int do_check(struct bpf_verifier_env *env) } /* check src1 operand */ - err = check_reg_arg(regs, insn->src_reg, SRC_OP); + err = check_reg_arg(env, insn->src_reg, SRC_OP); if (err) return err; /* check src2 operand */ - err = check_reg_arg(regs, insn->dst_reg, SRC_OP); + err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; @@ -3216,7 +3723,7 @@ static int do_check(struct bpf_verifier_env *env) return -EINVAL; } /* check src operand */ - err = check_reg_arg(regs, insn->dst_reg, SRC_OP); + err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; @@ -3270,7 +3777,7 @@ static int do_check(struct bpf_verifier_env *env) * of bpf_exit, which means that program wrote * something into it earlier */ - err = check_reg_arg(regs, BPF_REG_0, SRC_OP); + err = check_reg_arg(env, BPF_REG_0, SRC_OP); if (err) return err; @@ -3310,7 +3817,6 @@ static int do_check(struct bpf_verifier_env *env) verbose("invalid BPF_LD mode\n"); return -EINVAL; } - reset_reg_range_values(regs, insn->dst_reg); } else { verbose("unknown insn class %d\n", class); return -EINVAL; @@ -3669,7 +4175,11 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) continue; } - if (ebpf_jit_enabled() && insn->imm == BPF_FUNC_map_lookup_elem) { + /* BPF_EMIT_CALL() assumptions in some of the map_gen_lookup + * handlers are currently limited to 64 bit only. + */ + if (ebpf_jit_enabled() && BITS_PER_LONG == 64 && + insn->imm == BPF_FUNC_map_lookup_elem) { map_ptr = env->insn_aux_data[i + delta].map_ptr; if (map_ptr == BPF_MAP_PTR_POISON || !map_ptr->ops->map_gen_lookup) @@ -3694,6 +4204,27 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) continue; } + if (insn->imm == BPF_FUNC_redirect_map) { + /* Note, we cannot use prog directly as imm as subsequent + * rewrites would still change the prog pointer. The only + * stable address we can use is aux, which also works with + * prog clones during blinding. + */ + u64 addr = (unsigned long)prog->aux; + struct bpf_insn r4_ld[] = { + BPF_LD_IMM64(BPF_REG_4, addr), + *insn, + }; + cnt = ARRAY_SIZE(r4_ld); + + new_prog = bpf_patch_insn_data(env, i + delta, r4_ld, cnt); + if (!new_prog) + return -ENOMEM; + + delta += cnt - 1; + env->prog = prog = new_prog; + insn = new_prog->insnsi + i + delta; + } patch_call_imm: fn = prog->aux->ops->get_func_proto(insn->imm); /* all functions that have prototype and verifier allowed diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h index 793565c057426656312ab7b31471f6c523b7ae59..5151ff256c2945ec3a6b274b4eae7c2221d81a98 100644 --- a/kernel/cgroup/cgroup-internal.h +++ b/kernel/cgroup/cgroup-internal.h @@ -33,6 +33,9 @@ struct cgroup_taskset { struct list_head src_csets; struct list_head dst_csets; + /* the number of tasks in the set */ + int nr_tasks; + /* the subsys currently being processed */ int ssid; @@ -153,6 +156,8 @@ static inline void get_css_set(struct css_set *cset) bool cgroup_ssid_enabled(int ssid); bool cgroup_on_dfl(const struct cgroup *cgrp); +bool cgroup_is_thread_root(struct cgroup *cgrp); +bool cgroup_is_threaded(struct cgroup *cgrp); struct cgroup_root *cgroup_root_from_kf(struct kernfs_root *kf_root); struct cgroup *task_cgroup_from_root(struct task_struct *task, @@ -170,7 +175,7 @@ struct dentry *cgroup_do_mount(struct file_system_type *fs_type, int flags, struct cgroup_root *root, unsigned long magic, struct cgroup_namespace *ns); -bool cgroup_may_migrate_to(struct cgroup *dst_cgrp); +int cgroup_migrate_vet_dst(struct cgroup *dst_cgrp); void cgroup_migrate_finish(struct cgroup_mgctx *mgctx); void cgroup_migrate_add_src(struct css_set *src_cset, struct cgroup *dst_cgrp, struct cgroup_mgctx *mgctx); @@ -180,10 +185,10 @@ int cgroup_migrate(struct task_struct *leader, bool threadgroup, int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader, bool threadgroup); -ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, - size_t nbytes, loff_t off, bool threadgroup); -ssize_t cgroup_procs_write(struct kernfs_open_file *of, char *buf, size_t nbytes, - loff_t off); +struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup) + __acquires(&cgroup_threadgroup_rwsem); +void cgroup_procs_write_finish(struct task_struct *task) + __releases(&cgroup_threadgroup_rwsem); void cgroup_lock_and_drain_offline(struct cgroup *cgrp); diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 7bf4b1533f3466411fecaaab4e761f12323a3810..024085daab1aede5958235b0663c19ec667b5836 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -99,8 +99,9 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) if (cgroup_on_dfl(to)) return -EINVAL; - if (!cgroup_may_migrate_to(to)) - return -EBUSY; + ret = cgroup_migrate_vet_dst(to); + if (ret) + return ret; mutex_lock(&cgroup_mutex); @@ -121,7 +122,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) * ->can_attach() fails. */ do { - css_task_iter_start(&from->self, &it); + css_task_iter_start(&from->self, 0, &it); task = css_task_iter_next(&it); if (task) get_task_struct(task); @@ -373,7 +374,7 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type, if (!array) return -ENOMEM; /* now, populate the array */ - css_task_iter_start(&cgrp->self, &it); + css_task_iter_start(&cgrp->self, 0, &it); while ((tsk = css_task_iter_next(&it))) { if (unlikely(n == length)) break; @@ -510,10 +511,58 @@ static int cgroup_pidlist_show(struct seq_file *s, void *v) return 0; } -static ssize_t cgroup_tasks_write(struct kernfs_open_file *of, - char *buf, size_t nbytes, loff_t off) +static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off, + bool threadgroup) { - return __cgroup_procs_write(of, buf, nbytes, off, false); + struct cgroup *cgrp; + struct task_struct *task; + const struct cred *cred, *tcred; + ssize_t ret; + + cgrp = cgroup_kn_lock_live(of->kn, false); + if (!cgrp) + return -ENODEV; + + task = cgroup_procs_write_start(buf, threadgroup); + ret = PTR_ERR_OR_ZERO(task); + if (ret) + goto out_unlock; + + /* + * Even if we're attaching all tasks in the thread group, we only + * need to check permissions on one of them. + */ + cred = current_cred(); + tcred = get_task_cred(task); + if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) && + !uid_eq(cred->euid, tcred->uid) && + !uid_eq(cred->euid, tcred->suid)) + ret = -EACCES; + put_cred(tcred); + if (ret) + goto out_finish; + + ret = cgroup_attach_task(cgrp, task, threadgroup); + +out_finish: + cgroup_procs_write_finish(task); +out_unlock: + cgroup_kn_unlock(of->kn); + + return ret ?: nbytes; +} + +static ssize_t cgroup1_procs_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + return __cgroup1_procs_write(of, buf, nbytes, off, true); +} + +static ssize_t cgroup1_tasks_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + return __cgroup1_procs_write(of, buf, nbytes, off, false); } static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, @@ -592,7 +641,7 @@ struct cftype cgroup1_base_files[] = { .seq_stop = cgroup_pidlist_stop, .seq_show = cgroup_pidlist_show, .private = CGROUP_FILE_PROCS, - .write = cgroup_procs_write, + .write = cgroup1_procs_write, }, { .name = "cgroup.clone_children", @@ -611,7 +660,7 @@ struct cftype cgroup1_base_files[] = { .seq_stop = cgroup_pidlist_stop, .seq_show = cgroup_pidlist_show, .private = CGROUP_FILE_TASKS, - .write = cgroup_tasks_write, + .write = cgroup1_tasks_write, }, { .name = "notify_on_release", @@ -701,7 +750,7 @@ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry) } rcu_read_unlock(); - css_task_iter_start(&cgrp->self, &it); + css_task_iter_start(&cgrp->self, 0, &it); while ((tsk = css_task_iter_next(&it))) { switch (tsk->state) { case TASK_RUNNING: @@ -846,6 +895,8 @@ static int cgroup1_show_options(struct seq_file *seq, struct kernfs_root *kf_roo seq_puts(seq, ",noprefix"); if (root->flags & CGRP_ROOT_XATTR) seq_puts(seq, ",xattr"); + if (root->flags & CGRP_ROOT_CPUSET_V2_MODE) + seq_puts(seq, ",cpuset_v2_mode"); spin_lock(&release_agent_path_lock); if (strlen(root->release_agent_path)) @@ -900,6 +951,10 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) opts->cpuset_clone_children = true; continue; } + if (!strcmp(token, "cpuset_v2_mode")) { + opts->flags |= CGRP_ROOT_CPUSET_V2_MODE; + continue; + } if (!strcmp(token, "xattr")) { opts->flags |= CGRP_ROOT_XATTR; continue; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 620794a20a339c7e10948da829fae5a6818e598b..44857278eb8aa6a2bbf27b7eb12137ef42628170 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -162,6 +162,9 @@ static u16 cgrp_dfl_inhibit_ss_mask; /* some controllers are implicitly enabled on the default hierarchy */ static u16 cgrp_dfl_implicit_ss_mask; +/* some controllers can be threaded on the default hierarchy */ +static u16 cgrp_dfl_threaded_ss_mask; + /* The list of hierarchy roots */ LIST_HEAD(cgroup_roots); static int cgroup_root_count; @@ -316,13 +319,87 @@ static void cgroup_idr_remove(struct idr *idr, int id) spin_unlock_bh(&cgroup_idr_lock); } -static struct cgroup *cgroup_parent(struct cgroup *cgrp) +static bool cgroup_has_tasks(struct cgroup *cgrp) { - struct cgroup_subsys_state *parent_css = cgrp->self.parent; + return cgrp->nr_populated_csets; +} - if (parent_css) - return container_of(parent_css, struct cgroup, self); - return NULL; +bool cgroup_is_threaded(struct cgroup *cgrp) +{ + return cgrp->dom_cgrp != cgrp; +} + +/* can @cgrp host both domain and threaded children? */ +static bool cgroup_is_mixable(struct cgroup *cgrp) +{ + /* + * Root isn't under domain level resource control exempting it from + * the no-internal-process constraint, so it can serve as a thread + * root and a parent of resource domains at the same time. + */ + return !cgroup_parent(cgrp); +} + +/* can @cgrp become a thread root? should always be true for a thread root */ +static bool cgroup_can_be_thread_root(struct cgroup *cgrp) +{ + /* mixables don't care */ + if (cgroup_is_mixable(cgrp)) + return true; + + /* domain roots can't be nested under threaded */ + if (cgroup_is_threaded(cgrp)) + return false; + + /* can only have either domain or threaded children */ + if (cgrp->nr_populated_domain_children) + return false; + + /* and no domain controllers can be enabled */ + if (cgrp->subtree_control & ~cgrp_dfl_threaded_ss_mask) + return false; + + return true; +} + +/* is @cgrp root of a threaded subtree? */ +bool cgroup_is_thread_root(struct cgroup *cgrp) +{ + /* thread root should be a domain */ + if (cgroup_is_threaded(cgrp)) + return false; + + /* a domain w/ threaded children is a thread root */ + if (cgrp->nr_threaded_children) + return true; + + /* + * A domain which has tasks and explicit threaded controllers + * enabled is a thread root. + */ + if (cgroup_has_tasks(cgrp) && + (cgrp->subtree_control & cgrp_dfl_threaded_ss_mask)) + return true; + + return false; +} + +/* a domain which isn't connected to the root w/o brekage can't be used */ +static bool cgroup_is_valid_domain(struct cgroup *cgrp) +{ + /* the cgroup itself can be a thread root */ + if (cgroup_is_threaded(cgrp)) + return false; + + /* but the ancestors can't be unless mixable */ + while ((cgrp = cgroup_parent(cgrp))) { + if (!cgroup_is_mixable(cgrp) && cgroup_is_thread_root(cgrp)) + return false; + if (cgroup_is_threaded(cgrp)) + return false; + } + + return true; } /* subsystems visibly enabled on a cgroup */ @@ -331,8 +408,14 @@ static u16 cgroup_control(struct cgroup *cgrp) struct cgroup *parent = cgroup_parent(cgrp); u16 root_ss_mask = cgrp->root->subsys_mask; - if (parent) - return parent->subtree_control; + if (parent) { + u16 ss_mask = parent->subtree_control; + + /* threaded cgroups can only have threaded controllers */ + if (cgroup_is_threaded(cgrp)) + ss_mask &= cgrp_dfl_threaded_ss_mask; + return ss_mask; + } if (cgroup_on_dfl(cgrp)) root_ss_mask &= ~(cgrp_dfl_inhibit_ss_mask | @@ -345,8 +428,14 @@ static u16 cgroup_ss_mask(struct cgroup *cgrp) { struct cgroup *parent = cgroup_parent(cgrp); - if (parent) - return parent->subtree_ss_mask; + if (parent) { + u16 ss_mask = parent->subtree_ss_mask; + + /* threaded cgroups can only have threaded controllers */ + if (cgroup_is_threaded(cgrp)) + ss_mask &= cgrp_dfl_threaded_ss_mask; + return ss_mask; + } return cgrp->root->subsys_mask; } @@ -436,22 +525,12 @@ struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgrp, return css; } -static void __maybe_unused cgroup_get(struct cgroup *cgrp) -{ - css_get(&cgrp->self); -} - static void cgroup_get_live(struct cgroup *cgrp) { WARN_ON_ONCE(cgroup_is_dead(cgrp)); css_get(&cgrp->self); } -static bool cgroup_tryget(struct cgroup *cgrp) -{ - return css_tryget(&cgrp->self); -} - struct cgroup_subsys_state *of_css(struct kernfs_open_file *of) { struct cgroup *cgrp = of->kn->parent->priv; @@ -560,9 +639,11 @@ EXPORT_SYMBOL_GPL(of_css); */ struct css_set init_css_set = { .refcount = REFCOUNT_INIT(1), + .dom_cset = &init_css_set, .tasks = LIST_HEAD_INIT(init_css_set.tasks), .mg_tasks = LIST_HEAD_INIT(init_css_set.mg_tasks), .task_iters = LIST_HEAD_INIT(init_css_set.task_iters), + .threaded_csets = LIST_HEAD_INIT(init_css_set.threaded_csets), .cgrp_links = LIST_HEAD_INIT(init_css_set.cgrp_links), .mg_preload_node = LIST_HEAD_INIT(init_css_set.mg_preload_node), .mg_node = LIST_HEAD_INIT(init_css_set.mg_node), @@ -570,6 +651,11 @@ struct css_set init_css_set = { static int css_set_count = 1; /* 1 for init_css_set */ +static bool css_set_threaded(struct css_set *cset) +{ + return cset->dom_cset != cset; +} + /** * css_set_populated - does a css_set contain any tasks? * @cset: target css_set @@ -587,39 +673,48 @@ static bool css_set_populated(struct css_set *cset) } /** - * cgroup_update_populated - updated populated count of a cgroup + * cgroup_update_populated - update the populated count of a cgroup * @cgrp: the target cgroup * @populated: inc or dec populated count * * One of the css_sets associated with @cgrp is either getting its first - * task or losing the last. Update @cgrp->populated_cnt accordingly. The - * count is propagated towards root so that a given cgroup's populated_cnt - * is zero iff the cgroup and all its descendants don't contain any tasks. + * task or losing the last. Update @cgrp->nr_populated_* accordingly. The + * count is propagated towards root so that a given cgroup's + * nr_populated_children is zero iff none of its descendants contain any + * tasks. * - * @cgrp's interface file "cgroup.populated" is zero if - * @cgrp->populated_cnt is zero and 1 otherwise. When @cgrp->populated_cnt - * changes from or to zero, userland is notified that the content of the - * interface file has changed. This can be used to detect when @cgrp and - * its descendants become populated or empty. + * @cgrp's interface file "cgroup.populated" is zero if both + * @cgrp->nr_populated_csets and @cgrp->nr_populated_children are zero and + * 1 otherwise. When the sum changes from or to zero, userland is notified + * that the content of the interface file has changed. This can be used to + * detect when @cgrp and its descendants become populated or empty. */ static void cgroup_update_populated(struct cgroup *cgrp, bool populated) { + struct cgroup *child = NULL; + int adj = populated ? 1 : -1; + lockdep_assert_held(&css_set_lock); do { - bool trigger; + bool was_populated = cgroup_is_populated(cgrp); - if (populated) - trigger = !cgrp->populated_cnt++; - else - trigger = !--cgrp->populated_cnt; + if (!child) { + cgrp->nr_populated_csets += adj; + } else { + if (cgroup_is_threaded(child)) + cgrp->nr_populated_threaded_children += adj; + else + cgrp->nr_populated_domain_children += adj; + } - if (!trigger) + if (was_populated == cgroup_is_populated(cgrp)) break; cgroup1_check_for_release(cgrp); cgroup_file_notify(&cgrp->events_file); + child = cgrp; cgrp = cgroup_parent(cgrp); } while (cgrp); } @@ -630,7 +725,7 @@ static void cgroup_update_populated(struct cgroup *cgrp, bool populated) * @populated: whether @cset is populated or depopulated * * @cset is either getting the first task or losing the last. Update the - * ->populated_cnt of all associated cgroups accordingly. + * populated counters of all associated cgroups accordingly. */ static void css_set_update_populated(struct css_set *cset, bool populated) { @@ -653,7 +748,7 @@ static void css_set_update_populated(struct css_set *cset, bool populated) * css_set, @from_cset can be NULL. If @task is being disassociated * instead of moved, @to_cset can be NULL. * - * This function automatically handles populated_cnt updates and + * This function automatically handles populated counter updates and * css_task_iter adjustments but the caller is responsible for managing * @from_cset and @to_cset's reference counts. */ @@ -737,6 +832,8 @@ void put_css_set_locked(struct css_set *cset) if (!refcount_dec_and_test(&cset->refcount)) return; + WARN_ON_ONCE(!list_empty(&cset->threaded_csets)); + /* This css_set is dead. unlink it and release cgroup and css refs */ for_each_subsys(ss, ssid) { list_del(&cset->e_cset_node[ssid]); @@ -753,6 +850,11 @@ void put_css_set_locked(struct css_set *cset) kfree(link); } + if (css_set_threaded(cset)) { + list_del(&cset->threaded_csets_node); + put_css_set_locked(cset->dom_cset); + } + kfree_rcu(cset, rcu_head); } @@ -771,6 +873,7 @@ static bool compare_css_sets(struct css_set *cset, struct cgroup *new_cgrp, struct cgroup_subsys_state *template[]) { + struct cgroup *new_dfl_cgrp; struct list_head *l1, *l2; /* @@ -781,6 +884,16 @@ static bool compare_css_sets(struct css_set *cset, if (memcmp(template, cset->subsys, sizeof(cset->subsys))) return false; + + /* @cset's domain should match the default cgroup's */ + if (cgroup_on_dfl(new_cgrp)) + new_dfl_cgrp = new_cgrp; + else + new_dfl_cgrp = old_cset->dfl_cgrp; + + if (new_dfl_cgrp->dom_cgrp != cset->dom_cset->dfl_cgrp) + return false; + /* * Compare cgroup pointers in order to distinguish between * different cgroups in hierarchies. As different cgroups may @@ -988,9 +1101,11 @@ static struct css_set *find_css_set(struct css_set *old_cset, } refcount_set(&cset->refcount, 1); + cset->dom_cset = cset; INIT_LIST_HEAD(&cset->tasks); INIT_LIST_HEAD(&cset->mg_tasks); INIT_LIST_HEAD(&cset->task_iters); + INIT_LIST_HEAD(&cset->threaded_csets); INIT_HLIST_NODE(&cset->hlist); INIT_LIST_HEAD(&cset->cgrp_links); INIT_LIST_HEAD(&cset->mg_preload_node); @@ -1028,6 +1143,28 @@ static struct css_set *find_css_set(struct css_set *old_cset, spin_unlock_irq(&css_set_lock); + /* + * If @cset should be threaded, look up the matching dom_cset and + * link them up. We first fully initialize @cset then look for the + * dom_cset. It's simpler this way and safe as @cset is guaranteed + * to stay empty until we return. + */ + if (cgroup_is_threaded(cset->dfl_cgrp)) { + struct css_set *dcset; + + dcset = find_css_set(cset, cset->dfl_cgrp->dom_cgrp); + if (!dcset) { + put_css_set(cset); + return NULL; + } + + spin_lock_irq(&css_set_lock); + cset->dom_cset = dcset; + list_add_tail(&cset->threaded_csets_node, + &dcset->threaded_csets); + spin_unlock_irq(&css_set_lock); + } + return cset; } @@ -1155,6 +1292,8 @@ static struct cgroup *cset_cgroup_from_root(struct css_set *cset, if (cset == &init_css_set) { res = &root->cgrp; + } else if (root == &cgrp_dfl_root) { + res = cset->dfl_cgrp; } else { struct cgrp_cset_link *link; @@ -1670,6 +1809,9 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp) mutex_init(&cgrp->pidlist_mutex); cgrp->self.cgroup = cgrp; cgrp->self.flags |= CSS_ONLINE; + cgrp->dom_cgrp = cgrp; + cgrp->max_descendants = INT_MAX; + cgrp->max_depth = INT_MAX; for_each_subsys(ss, ssid) INIT_LIST_HEAD(&cgrp->e_csets[ssid]); @@ -1737,7 +1879,8 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask, int ref_flags) &cgroup_kf_syscall_ops : &cgroup1_kf_syscall_ops; root->kf_root = kernfs_create_root(kf_sops, - KERNFS_ROOT_CREATE_DEACTIVATED, + KERNFS_ROOT_CREATE_DEACTIVATED | + KERNFS_ROOT_SUPPORT_EXPORTOP, root_cgrp); if (IS_ERR(root->kf_root)) { ret = PTR_ERR(root->kf_root); @@ -2006,6 +2149,8 @@ static void cgroup_migrate_add_task(struct task_struct *task, if (!cset->mg_src_cgrp) return; + mgctx->tset.nr_tasks++; + list_move_tail(&task->cg_list, &cset->mg_tasks); if (list_empty(&cset->mg_node)) list_add_tail(&cset->mg_node, @@ -2094,21 +2239,19 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) struct css_set *cset, *tmp_cset; int ssid, failed_ssid, ret; - /* methods shouldn't be called if no task is actually migrating */ - if (list_empty(&tset->src_csets)) - return 0; - /* check that we can legitimately attach to the cgroup */ - do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { - if (ss->can_attach) { - tset->ssid = ssid; - ret = ss->can_attach(tset); - if (ret) { - failed_ssid = ssid; - goto out_cancel_attach; + if (tset->nr_tasks) { + do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { + if (ss->can_attach) { + tset->ssid = ssid; + ret = ss->can_attach(tset); + if (ret) { + failed_ssid = ssid; + goto out_cancel_attach; + } } - } - } while_each_subsys_mask(); + } while_each_subsys_mask(); + } /* * Now that we're guaranteed success, proceed to move all tasks to @@ -2137,25 +2280,29 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) */ tset->csets = &tset->dst_csets; - do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { - if (ss->attach) { - tset->ssid = ssid; - ss->attach(tset); - } - } while_each_subsys_mask(); + if (tset->nr_tasks) { + do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { + if (ss->attach) { + tset->ssid = ssid; + ss->attach(tset); + } + } while_each_subsys_mask(); + } ret = 0; goto out_release_tset; out_cancel_attach: - do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { - if (ssid == failed_ssid) - break; - if (ss->cancel_attach) { - tset->ssid = ssid; - ss->cancel_attach(tset); - } - } while_each_subsys_mask(); + if (tset->nr_tasks) { + do_each_subsys_mask(ss, ssid, mgctx->ss_mask) { + if (ssid == failed_ssid) + break; + if (ss->cancel_attach) { + tset->ssid = ssid; + ss->cancel_attach(tset); + } + } while_each_subsys_mask(); + } out_release_tset: spin_lock_irq(&css_set_lock); list_splice_init(&tset->dst_csets, &tset->src_csets); @@ -2164,21 +2311,52 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) list_del_init(&cset->mg_node); } spin_unlock_irq(&css_set_lock); + + /* + * Re-initialize the cgroup_taskset structure in case it is reused + * again in another cgroup_migrate_add_task()/cgroup_migrate_execute() + * iteration. + */ + tset->nr_tasks = 0; + tset->csets = &tset->src_csets; return ret; } /** - * cgroup_may_migrate_to - verify whether a cgroup can be migration destination + * cgroup_migrate_vet_dst - verify whether a cgroup can be migration destination * @dst_cgrp: destination cgroup to test * - * On the default hierarchy, except for the root, subtree_control must be - * zero for migration destination cgroups with tasks so that child cgroups - * don't compete against tasks. + * On the default hierarchy, except for the mixable, (possible) thread root + * and threaded cgroups, subtree_control must be zero for migration + * destination cgroups with tasks so that child cgroups don't compete + * against tasks. */ -bool cgroup_may_migrate_to(struct cgroup *dst_cgrp) +int cgroup_migrate_vet_dst(struct cgroup *dst_cgrp) { - return !cgroup_on_dfl(dst_cgrp) || !cgroup_parent(dst_cgrp) || - !dst_cgrp->subtree_control; + /* v1 doesn't have any restriction */ + if (!cgroup_on_dfl(dst_cgrp)) + return 0; + + /* verify @dst_cgrp can host resources */ + if (!cgroup_is_valid_domain(dst_cgrp->dom_cgrp)) + return -EOPNOTSUPP; + + /* mixables don't care */ + if (cgroup_is_mixable(dst_cgrp)) + return 0; + + /* + * If @dst_cgrp is already or can become a thread root or is + * threaded, it doesn't matter. + */ + if (cgroup_can_be_thread_root(dst_cgrp) || cgroup_is_threaded(dst_cgrp)) + return 0; + + /* apply no-internal-process constraint */ + if (dst_cgrp->subtree_control) + return -EBUSY; + + return 0; } /** @@ -2383,8 +2561,9 @@ int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader, struct task_struct *task; int ret; - if (!cgroup_may_migrate_to(dst_cgrp)) - return -EBUSY; + ret = cgroup_migrate_vet_dst(dst_cgrp); + if (ret) + return ret; /* look up all src csets */ spin_lock_irq(&css_set_lock); @@ -2411,96 +2590,23 @@ int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader, return ret; } -static int cgroup_procs_write_permission(struct task_struct *task, - struct cgroup *dst_cgrp, - struct kernfs_open_file *of) -{ - struct super_block *sb = of->file->f_path.dentry->d_sb; - struct cgroup_namespace *ns = current->nsproxy->cgroup_ns; - struct cgroup *root_cgrp = ns->root_cset->dfl_cgrp; - struct cgroup *src_cgrp, *com_cgrp; - struct inode *inode; - int ret; - - if (!cgroup_on_dfl(dst_cgrp)) { - const struct cred *cred = current_cred(); - const struct cred *tcred = get_task_cred(task); - - /* - * even if we're attaching all tasks in the thread group, - * we only need to check permissions on one of them. - */ - if (uid_eq(cred->euid, GLOBAL_ROOT_UID) || - uid_eq(cred->euid, tcred->uid) || - uid_eq(cred->euid, tcred->suid)) - ret = 0; - else - ret = -EACCES; - - put_cred(tcred); - return ret; - } - - /* find the source cgroup */ - spin_lock_irq(&css_set_lock); - src_cgrp = task_cgroup_from_root(task, &cgrp_dfl_root); - spin_unlock_irq(&css_set_lock); - - /* and the common ancestor */ - com_cgrp = src_cgrp; - while (!cgroup_is_descendant(dst_cgrp, com_cgrp)) - com_cgrp = cgroup_parent(com_cgrp); - - /* %current should be authorized to migrate to the common ancestor */ - inode = kernfs_get_inode(sb, com_cgrp->procs_file.kn); - if (!inode) - return -ENOMEM; - - ret = inode_permission(inode, MAY_WRITE); - iput(inode); - if (ret) - return ret; - - /* - * If namespaces are delegation boundaries, %current must be able - * to see both source and destination cgroups from its namespace. - */ - if ((cgrp_dfl_root.flags & CGRP_ROOT_NS_DELEGATE) && - (!cgroup_is_descendant(src_cgrp, root_cgrp) || - !cgroup_is_descendant(dst_cgrp, root_cgrp))) - return -ENOENT; - - return 0; -} - -/* - * Find the task_struct of the task to attach by vpid and pass it along to the - * function to attach either it or all tasks in its threadgroup. Will lock - * cgroup_mutex and threadgroup. - */ -ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, - size_t nbytes, loff_t off, bool threadgroup) +struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup) + __acquires(&cgroup_threadgroup_rwsem) { struct task_struct *tsk; - struct cgroup_subsys *ss; - struct cgroup *cgrp; pid_t pid; - int ssid, ret; if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) - return -EINVAL; - - cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENODEV; + return ERR_PTR(-EINVAL); percpu_down_write(&cgroup_threadgroup_rwsem); + rcu_read_lock(); if (pid) { tsk = find_task_by_vpid(pid); if (!tsk) { - ret = -ESRCH; - goto out_unlock_rcu; + tsk = ERR_PTR(-ESRCH); + goto out_unlock_threadgroup; } } else { tsk = current; @@ -2516,35 +2622,33 @@ ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, * cgroup with no rt_runtime allocated. Just say no. */ if (tsk->no_cgroup_migration || (tsk->flags & PF_NO_SETAFFINITY)) { - ret = -EINVAL; - goto out_unlock_rcu; + tsk = ERR_PTR(-EINVAL); + goto out_unlock_threadgroup; } get_task_struct(tsk); + goto out_unlock_rcu; + +out_unlock_threadgroup: + percpu_up_write(&cgroup_threadgroup_rwsem); +out_unlock_rcu: rcu_read_unlock(); + return tsk; +} - ret = cgroup_procs_write_permission(tsk, cgrp, of); - if (!ret) - ret = cgroup_attach_task(cgrp, tsk, threadgroup); +void cgroup_procs_write_finish(struct task_struct *task) + __releases(&cgroup_threadgroup_rwsem) +{ + struct cgroup_subsys *ss; + int ssid; - put_task_struct(tsk); - goto out_unlock_threadgroup; + /* release reference from cgroup_procs_write_start() */ + put_task_struct(task); -out_unlock_rcu: - rcu_read_unlock(); -out_unlock_threadgroup: percpu_up_write(&cgroup_threadgroup_rwsem); for_each_subsys(ss, ssid) if (ss->post_attach) ss->post_attach(); - cgroup_kn_unlock(of->kn); - return ret ?: nbytes; -} - -ssize_t cgroup_procs_write(struct kernfs_open_file *of, char *buf, size_t nbytes, - loff_t off) -{ - return __cgroup_procs_write(of, buf, nbytes, off, true); } static void cgroup_print_ss_mask(struct seq_file *seq, u16 ss_mask) @@ -2887,6 +2991,46 @@ static void cgroup_finalize_control(struct cgroup *cgrp, int ret) cgroup_apply_control_disable(cgrp); } +static int cgroup_vet_subtree_control_enable(struct cgroup *cgrp, u16 enable) +{ + u16 domain_enable = enable & ~cgrp_dfl_threaded_ss_mask; + + /* if nothing is getting enabled, nothing to worry about */ + if (!enable) + return 0; + + /* can @cgrp host any resources? */ + if (!cgroup_is_valid_domain(cgrp->dom_cgrp)) + return -EOPNOTSUPP; + + /* mixables don't care */ + if (cgroup_is_mixable(cgrp)) + return 0; + + if (domain_enable) { + /* can't enable domain controllers inside a thread subtree */ + if (cgroup_is_thread_root(cgrp) || cgroup_is_threaded(cgrp)) + return -EOPNOTSUPP; + } else { + /* + * Threaded controllers can handle internal competitions + * and are always allowed inside a (prospective) thread + * subtree. + */ + if (cgroup_can_be_thread_root(cgrp) || cgroup_is_threaded(cgrp)) + return 0; + } + + /* + * Controllers can't be enabled for a cgroup with tasks to avoid + * child cgroups competing against tasks. + */ + if (cgroup_has_tasks(cgrp)) + return -EBUSY; + + return 0; +} + /* change the enabled child controllers for a cgroup in the default hierarchy */ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, char *buf, size_t nbytes, @@ -2962,33 +3106,9 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, goto out_unlock; } - /* - * Except for the root, subtree_control must be zero for a cgroup - * with tasks so that child cgroups don't compete against tasks. - */ - if (enable && cgroup_parent(cgrp)) { - struct cgrp_cset_link *link; - - /* - * Because namespaces pin csets too, @cgrp->cset_links - * might not be empty even when @cgrp is empty. Walk and - * verify each cset. - */ - spin_lock_irq(&css_set_lock); - - ret = 0; - list_for_each_entry(link, &cgrp->cset_links, cset_link) { - if (css_set_populated(link->cset)) { - ret = -EBUSY; - break; - } - } - - spin_unlock_irq(&css_set_lock); - - if (ret) - goto out_unlock; - } + ret = cgroup_vet_subtree_control_enable(cgrp, enable); + if (ret) + goto out_unlock; /* save and update control masks and prepare csses */ cgroup_save_control(cgrp); @@ -2997,37 +3117,215 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, cgrp->subtree_control &= ~disable; ret = cgroup_apply_control(cgrp); - cgroup_finalize_control(cgrp, ret); + if (ret) + goto out_unlock; kernfs_activate(cgrp->kn); - ret = 0; out_unlock: cgroup_kn_unlock(of->kn); return ret ?: nbytes; } -static int cgroup_events_show(struct seq_file *seq, void *v) +/** + * cgroup_enable_threaded - make @cgrp threaded + * @cgrp: the target cgroup + * + * Called when "threaded" is written to the cgroup.type interface file and + * tries to make @cgrp threaded and join the parent's resource domain. + * This function is never called on the root cgroup as cgroup.type doesn't + * exist on it. + */ +static int cgroup_enable_threaded(struct cgroup *cgrp) { - seq_printf(seq, "populated %d\n", - cgroup_is_populated(seq_css(seq)->cgroup)); - return 0; -} + struct cgroup *parent = cgroup_parent(cgrp); + struct cgroup *dom_cgrp = parent->dom_cgrp; + int ret; -static int cgroup_file_open(struct kernfs_open_file *of) -{ - struct cftype *cft = of->kn->priv; + lockdep_assert_held(&cgroup_mutex); - if (cft->open) - return cft->open(of); - return 0; -} + /* noop if already threaded */ + if (cgroup_is_threaded(cgrp)) + return 0; -static void cgroup_file_release(struct kernfs_open_file *of) -{ - struct cftype *cft = of->kn->priv; + /* we're joining the parent's domain, ensure its validity */ + if (!cgroup_is_valid_domain(dom_cgrp) || + !cgroup_can_be_thread_root(dom_cgrp)) + return -EOPNOTSUPP; - if (cft->release) + /* + * The following shouldn't cause actual migrations and should + * always succeed. + */ + cgroup_save_control(cgrp); + + cgrp->dom_cgrp = dom_cgrp; + ret = cgroup_apply_control(cgrp); + if (!ret) + parent->nr_threaded_children++; + else + cgrp->dom_cgrp = cgrp; + + cgroup_finalize_control(cgrp, ret); + return ret; +} + +static int cgroup_type_show(struct seq_file *seq, void *v) +{ + struct cgroup *cgrp = seq_css(seq)->cgroup; + + if (cgroup_is_threaded(cgrp)) + seq_puts(seq, "threaded\n"); + else if (!cgroup_is_valid_domain(cgrp)) + seq_puts(seq, "domain invalid\n"); + else if (cgroup_is_thread_root(cgrp)) + seq_puts(seq, "domain threaded\n"); + else + seq_puts(seq, "domain\n"); + + return 0; +} + +static ssize_t cgroup_type_write(struct kernfs_open_file *of, char *buf, + size_t nbytes, loff_t off) +{ + struct cgroup *cgrp; + int ret; + + /* only switching to threaded mode is supported */ + if (strcmp(strstrip(buf), "threaded")) + return -EINVAL; + + cgrp = cgroup_kn_lock_live(of->kn, false); + if (!cgrp) + return -ENOENT; + + /* threaded can only be enabled */ + ret = cgroup_enable_threaded(cgrp); + + cgroup_kn_unlock(of->kn); + return ret ?: nbytes; +} + +static int cgroup_max_descendants_show(struct seq_file *seq, void *v) +{ + struct cgroup *cgrp = seq_css(seq)->cgroup; + int descendants = READ_ONCE(cgrp->max_descendants); + + if (descendants == INT_MAX) + seq_puts(seq, "max\n"); + else + seq_printf(seq, "%d\n", descendants); + + return 0; +} + +static ssize_t cgroup_max_descendants_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct cgroup *cgrp; + int descendants; + ssize_t ret; + + buf = strstrip(buf); + if (!strcmp(buf, "max")) { + descendants = INT_MAX; + } else { + ret = kstrtoint(buf, 0, &descendants); + if (ret) + return ret; + } + + if (descendants < 0) + return -ERANGE; + + cgrp = cgroup_kn_lock_live(of->kn, false); + if (!cgrp) + return -ENOENT; + + cgrp->max_descendants = descendants; + + cgroup_kn_unlock(of->kn); + + return nbytes; +} + +static int cgroup_max_depth_show(struct seq_file *seq, void *v) +{ + struct cgroup *cgrp = seq_css(seq)->cgroup; + int depth = READ_ONCE(cgrp->max_depth); + + if (depth == INT_MAX) + seq_puts(seq, "max\n"); + else + seq_printf(seq, "%d\n", depth); + + return 0; +} + +static ssize_t cgroup_max_depth_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct cgroup *cgrp; + ssize_t ret; + int depth; + + buf = strstrip(buf); + if (!strcmp(buf, "max")) { + depth = INT_MAX; + } else { + ret = kstrtoint(buf, 0, &depth); + if (ret) + return ret; + } + + if (depth < 0) + return -ERANGE; + + cgrp = cgroup_kn_lock_live(of->kn, false); + if (!cgrp) + return -ENOENT; + + cgrp->max_depth = depth; + + cgroup_kn_unlock(of->kn); + + return nbytes; +} + +static int cgroup_events_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "populated %d\n", + cgroup_is_populated(seq_css(seq)->cgroup)); + return 0; +} + +static int cgroup_stat_show(struct seq_file *seq, void *v) +{ + struct cgroup *cgroup = seq_css(seq)->cgroup; + + seq_printf(seq, "nr_descendants %d\n", + cgroup->nr_descendants); + seq_printf(seq, "nr_dying_descendants %d\n", + cgroup->nr_dying_descendants); + + return 0; +} + +static int cgroup_file_open(struct kernfs_open_file *of) +{ + struct cftype *cft = of->kn->priv; + + if (cft->open) + return cft->open(of); + return 0; +} + +static void cgroup_file_release(struct kernfs_open_file *of) +{ + struct cftype *cft = of->kn->priv; + + if (cft->release) cft->release(of); } @@ -3230,7 +3528,6 @@ static int cgroup_addrm_files(struct cgroup_subsys_state *css, static int cgroup_apply_cftypes(struct cftype *cfts, bool is_add) { - LIST_HEAD(pending); struct cgroup_subsys *ss = cfts[0].ss; struct cgroup *root = &ss->root->cgrp; struct cgroup_subsys_state *css; @@ -3655,6 +3952,58 @@ bool css_has_online_children(struct cgroup_subsys_state *css) return ret; } +static struct css_set *css_task_iter_next_css_set(struct css_task_iter *it) +{ + struct list_head *l; + struct cgrp_cset_link *link; + struct css_set *cset; + + lockdep_assert_held(&css_set_lock); + + /* find the next threaded cset */ + if (it->tcset_pos) { + l = it->tcset_pos->next; + + if (l != it->tcset_head) { + it->tcset_pos = l; + return container_of(l, struct css_set, + threaded_csets_node); + } + + it->tcset_pos = NULL; + } + + /* find the next cset */ + l = it->cset_pos; + l = l->next; + if (l == it->cset_head) { + it->cset_pos = NULL; + return NULL; + } + + if (it->ss) { + cset = container_of(l, struct css_set, e_cset_node[it->ss->id]); + } else { + link = list_entry(l, struct cgrp_cset_link, cset_link); + cset = link->cset; + } + + it->cset_pos = l; + + /* initialize threaded css_set walking */ + if (it->flags & CSS_TASK_ITER_THREADED) { + if (it->cur_dcset) + put_css_set_locked(it->cur_dcset); + it->cur_dcset = cset; + get_css_set(cset); + + it->tcset_head = &cset->threaded_csets; + it->tcset_pos = &cset->threaded_csets; + } + + return cset; +} + /** * css_task_iter_advance_css_set - advance a task itererator to the next css_set * @it: the iterator to advance @@ -3663,32 +4012,19 @@ bool css_has_online_children(struct cgroup_subsys_state *css) */ static void css_task_iter_advance_css_set(struct css_task_iter *it) { - struct list_head *l = it->cset_pos; - struct cgrp_cset_link *link; struct css_set *cset; lockdep_assert_held(&css_set_lock); /* Advance to the next non-empty css_set */ do { - l = l->next; - if (l == it->cset_head) { - it->cset_pos = NULL; + cset = css_task_iter_next_css_set(it); + if (!cset) { it->task_pos = NULL; return; } - - if (it->ss) { - cset = container_of(l, struct css_set, - e_cset_node[it->ss->id]); - } else { - link = list_entry(l, struct cgrp_cset_link, cset_link); - cset = link->cset; - } } while (!css_set_populated(cset)); - it->cset_pos = l; - if (!list_empty(&cset->tasks)) it->task_pos = cset->tasks.next; else @@ -3728,6 +4064,7 @@ static void css_task_iter_advance(struct css_task_iter *it) lockdep_assert_held(&css_set_lock); WARN_ON_ONCE(!l); +repeat: /* * Advance iterator to find next entry. cset->tasks is consumed * first and then ->mg_tasks. After ->mg_tasks, we move onto the @@ -3742,11 +4079,18 @@ static void css_task_iter_advance(struct css_task_iter *it) css_task_iter_advance_css_set(it); else it->task_pos = l; + + /* if PROCS, skip over tasks which aren't group leaders */ + if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos && + !thread_group_leader(list_entry(it->task_pos, struct task_struct, + cg_list))) + goto repeat; } /** * css_task_iter_start - initiate task iteration * @css: the css to walk tasks of + * @flags: CSS_TASK_ITER_* flags * @it: the task iterator to use * * Initiate iteration through the tasks of @css. The caller can call @@ -3754,7 +4098,7 @@ static void css_task_iter_advance(struct css_task_iter *it) * returns NULL. On completion of iteration, css_task_iter_end() must be * called. */ -void css_task_iter_start(struct cgroup_subsys_state *css, +void css_task_iter_start(struct cgroup_subsys_state *css, unsigned int flags, struct css_task_iter *it) { /* no one should try to iterate before mounting cgroups */ @@ -3765,6 +4109,7 @@ void css_task_iter_start(struct cgroup_subsys_state *css, spin_lock_irq(&css_set_lock); it->ss = css->ss; + it->flags = flags; if (it->ss) it->cset_pos = &css->cgroup->e_csets[css->ss->id]; @@ -3822,6 +4167,9 @@ void css_task_iter_end(struct css_task_iter *it) spin_unlock_irq(&css_set_lock); } + if (it->cur_dcset) + put_css_set(it->cur_dcset); + if (it->cur_task) put_task_struct(it->cur_task); } @@ -3838,16 +4186,12 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos) { struct kernfs_open_file *of = s->private; struct css_task_iter *it = of->priv; - struct task_struct *task; - - do { - task = css_task_iter_next(it); - } while (task && !thread_group_leader(task)); - return task; + return css_task_iter_next(it); } -static void *cgroup_procs_start(struct seq_file *s, loff_t *pos) +static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, + unsigned int iter_flags) { struct kernfs_open_file *of = s->private; struct cgroup *cgrp = seq_css(s)->cgroup; @@ -3865,23 +4209,168 @@ static void *cgroup_procs_start(struct seq_file *s, loff_t *pos) if (!it) return ERR_PTR(-ENOMEM); of->priv = it; - css_task_iter_start(&cgrp->self, it); + css_task_iter_start(&cgrp->self, iter_flags, it); } else if (!(*pos)++) { css_task_iter_end(it); - css_task_iter_start(&cgrp->self, it); + css_task_iter_start(&cgrp->self, iter_flags, it); } return cgroup_procs_next(s, NULL, NULL); } +static void *cgroup_procs_start(struct seq_file *s, loff_t *pos) +{ + struct cgroup *cgrp = seq_css(s)->cgroup; + + /* + * All processes of a threaded subtree belong to the domain cgroup + * of the subtree. Only threads can be distributed across the + * subtree. Reject reads on cgroup.procs in the subtree proper. + * They're always empty anyway. + */ + if (cgroup_is_threaded(cgrp)) + return ERR_PTR(-EOPNOTSUPP); + + return __cgroup_procs_start(s, pos, CSS_TASK_ITER_PROCS | + CSS_TASK_ITER_THREADED); +} + static int cgroup_procs_show(struct seq_file *s, void *v) { - seq_printf(s, "%d\n", task_tgid_vnr(v)); + seq_printf(s, "%d\n", task_pid_vnr(v)); + return 0; +} + +static int cgroup_procs_write_permission(struct cgroup *src_cgrp, + struct cgroup *dst_cgrp, + struct super_block *sb) +{ + struct cgroup_namespace *ns = current->nsproxy->cgroup_ns; + struct cgroup *com_cgrp = src_cgrp; + struct inode *inode; + int ret; + + lockdep_assert_held(&cgroup_mutex); + + /* find the common ancestor */ + while (!cgroup_is_descendant(dst_cgrp, com_cgrp)) + com_cgrp = cgroup_parent(com_cgrp); + + /* %current should be authorized to migrate to the common ancestor */ + inode = kernfs_get_inode(sb, com_cgrp->procs_file.kn); + if (!inode) + return -ENOMEM; + + ret = inode_permission(inode, MAY_WRITE); + iput(inode); + if (ret) + return ret; + + /* + * If namespaces are delegation boundaries, %current must be able + * to see both source and destination cgroups from its namespace. + */ + if ((cgrp_dfl_root.flags & CGRP_ROOT_NS_DELEGATE) && + (!cgroup_is_descendant(src_cgrp, ns->root_cset->dfl_cgrp) || + !cgroup_is_descendant(dst_cgrp, ns->root_cset->dfl_cgrp))) + return -ENOENT; + return 0; } +static ssize_t cgroup_procs_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct cgroup *src_cgrp, *dst_cgrp; + struct task_struct *task; + ssize_t ret; + + dst_cgrp = cgroup_kn_lock_live(of->kn, false); + if (!dst_cgrp) + return -ENODEV; + + task = cgroup_procs_write_start(buf, true); + ret = PTR_ERR_OR_ZERO(task); + if (ret) + goto out_unlock; + + /* find the source cgroup */ + spin_lock_irq(&css_set_lock); + src_cgrp = task_cgroup_from_root(task, &cgrp_dfl_root); + spin_unlock_irq(&css_set_lock); + + ret = cgroup_procs_write_permission(src_cgrp, dst_cgrp, + of->file->f_path.dentry->d_sb); + if (ret) + goto out_finish; + + ret = cgroup_attach_task(dst_cgrp, task, true); + +out_finish: + cgroup_procs_write_finish(task); +out_unlock: + cgroup_kn_unlock(of->kn); + + return ret ?: nbytes; +} + +static void *cgroup_threads_start(struct seq_file *s, loff_t *pos) +{ + return __cgroup_procs_start(s, pos, 0); +} + +static ssize_t cgroup_threads_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct cgroup *src_cgrp, *dst_cgrp; + struct task_struct *task; + ssize_t ret; + + buf = strstrip(buf); + + dst_cgrp = cgroup_kn_lock_live(of->kn, false); + if (!dst_cgrp) + return -ENODEV; + + task = cgroup_procs_write_start(buf, false); + ret = PTR_ERR_OR_ZERO(task); + if (ret) + goto out_unlock; + + /* find the source cgroup */ + spin_lock_irq(&css_set_lock); + src_cgrp = task_cgroup_from_root(task, &cgrp_dfl_root); + spin_unlock_irq(&css_set_lock); + + /* thread migrations follow the cgroup.procs delegation rule */ + ret = cgroup_procs_write_permission(src_cgrp, dst_cgrp, + of->file->f_path.dentry->d_sb); + if (ret) + goto out_finish; + + /* and must be contained in the same domain */ + ret = -EOPNOTSUPP; + if (src_cgrp->dom_cgrp != dst_cgrp->dom_cgrp) + goto out_finish; + + ret = cgroup_attach_task(dst_cgrp, task, false); + +out_finish: + cgroup_procs_write_finish(task); +out_unlock: + cgroup_kn_unlock(of->kn); + + return ret ?: nbytes; +} + /* cgroup core interface files for the default hierarchy */ static struct cftype cgroup_base_files[] = { + { + .name = "cgroup.type", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = cgroup_type_show, + .write = cgroup_type_write, + }, { .name = "cgroup.procs", .flags = CFTYPE_NS_DELEGATABLE, @@ -3892,6 +4381,14 @@ static struct cftype cgroup_base_files[] = { .seq_show = cgroup_procs_show, .write = cgroup_procs_write, }, + { + .name = "cgroup.threads", + .release = cgroup_procs_release, + .seq_start = cgroup_threads_start, + .seq_next = cgroup_procs_next, + .seq_show = cgroup_procs_show, + .write = cgroup_threads_write, + }, { .name = "cgroup.controllers", .seq_show = cgroup_controllers_show, @@ -3908,6 +4405,20 @@ static struct cftype cgroup_base_files[] = { .file_offset = offsetof(struct cgroup, events_file), .seq_show = cgroup_events_show, }, + { + .name = "cgroup.max.descendants", + .seq_show = cgroup_max_descendants_show, + .write = cgroup_max_descendants_write, + }, + { + .name = "cgroup.max.depth", + .seq_show = cgroup_max_depth_show, + .write = cgroup_max_depth_write, + }, + { + .name = "cgroup.stat", + .seq_show = cgroup_stat_show, + }, { } /* terminate */ }; @@ -4007,9 +4518,15 @@ static void css_release_work_fn(struct work_struct *work) if (ss->css_released) ss->css_released(css); } else { + struct cgroup *tcgrp; + /* cgroup release path */ trace_cgroup_release(cgrp); + for (tcgrp = cgroup_parent(cgrp); tcgrp; + tcgrp = cgroup_parent(tcgrp)) + tcgrp->nr_dying_descendants--; + cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id); cgrp->id = -1; @@ -4096,9 +4613,6 @@ static void offline_css(struct cgroup_subsys_state *css) if (!(css->flags & CSS_ONLINE)) return; - if (ss->css_reset) - ss->css_reset(css); - if (ss->css_offline) ss->css_offline(css); @@ -4208,9 +4722,13 @@ static struct cgroup *cgroup_create(struct cgroup *parent) cgrp->root = root; cgrp->level = level; - for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) + for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) { cgrp->ancestor_ids[tcgrp->level] = tcgrp->id; + if (tcgrp != cgrp) + tcgrp->nr_descendants++; + } + if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); @@ -4251,6 +4769,29 @@ static struct cgroup *cgroup_create(struct cgroup *parent) return ERR_PTR(ret); } +static bool cgroup_check_hierarchy_limits(struct cgroup *parent) +{ + struct cgroup *cgroup; + int ret = false; + int level = 1; + + lockdep_assert_held(&cgroup_mutex); + + for (cgroup = parent; cgroup; cgroup = cgroup_parent(cgroup)) { + if (cgroup->nr_descendants >= cgroup->max_descendants) + goto fail; + + if (level > cgroup->max_depth) + goto fail; + + level++; + } + + ret = true; +fail: + return ret; +} + int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode) { struct cgroup *parent, *cgrp; @@ -4265,6 +4806,11 @@ int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode) if (!parent) return -ENODEV; + if (!cgroup_check_hierarchy_limits(parent)) { + ret = -EAGAIN; + goto out_unlock; + } + cgrp = cgroup_create(parent); if (IS_ERR(cgrp)) { ret = PTR_ERR(cgrp); @@ -4416,6 +4962,7 @@ static void kill_css(struct cgroup_subsys_state *css) static int cgroup_destroy_locked(struct cgroup *cgrp) __releases(&cgroup_mutex) __acquires(&cgroup_mutex) { + struct cgroup *tcgrp, *parent = cgroup_parent(cgrp); struct cgroup_subsys_state *css; struct cgrp_cset_link *link; int ssid; @@ -4460,7 +5007,15 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) */ kernfs_remove(cgrp->kn); - cgroup1_check_for_release(cgroup_parent(cgrp)); + if (parent && cgroup_is_threaded(cgrp)) + parent->nr_threaded_children--; + + for (tcgrp = cgroup_parent(cgrp); tcgrp; tcgrp = cgroup_parent(tcgrp)) { + tcgrp->nr_descendants--; + tcgrp->nr_dying_descendants++; + } + + cgroup1_check_for_release(parent); /* put the base reference */ percpu_ref_kill(&cgrp->self.refcnt); @@ -4655,11 +5210,17 @@ int __init cgroup_init(void) cgrp_dfl_root.subsys_mask |= 1 << ss->id; + /* implicit controllers must be threaded too */ + WARN_ON(ss->implicit_on_dfl && !ss->threaded); + if (ss->implicit_on_dfl) cgrp_dfl_implicit_ss_mask |= 1 << ss->id; else if (!ss->dfl_cftypes) cgrp_dfl_inhibit_ss_mask |= 1 << ss->id; + if (ss->threaded) + cgrp_dfl_threaded_ss_mask |= 1 << ss->id; + if (ss->dfl_cftypes == ss->legacy_cftypes) { WARN_ON(cgroup_add_cftypes(ss, ss->dfl_cftypes)); } else { @@ -4669,6 +5230,10 @@ int __init cgroup_init(void) if (ss->bind) ss->bind(init_css_set.subsys[ssid]); + + mutex_lock(&cgroup_mutex); + css_populate_dir(init_css_set.subsys[ssid]); + mutex_unlock(&cgroup_mutex); } /* init_css_set.subsys[] has been updated, re-hash */ @@ -4700,6 +5265,18 @@ static int __init cgroup_wq_init(void) } core_initcall(cgroup_wq_init); +void cgroup_path_from_kernfs_id(const union kernfs_node_id *id, + char *buf, size_t buflen) +{ + struct kernfs_node *kn; + + kn = kernfs_get_node_by_id(cgrp_dfl_root.kf_root, id); + if (!kn) + return; + kernfs_path(kn, buf, buflen); + kernfs_put(kn); +} + /* * proc_cgroup_show() * - Print task's cgroup paths into seq_file, one line for each hierarchy diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index ca8376e5008c7c16ca91175e3ad1021ec69e2777..4657e2924ecb1a72281cc70e3c46f25a2f2ce962 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,7 @@ #include #include +DEFINE_STATIC_KEY_FALSE(cpusets_pre_enable_key); DEFINE_STATIC_KEY_FALSE(cpusets_enabled_key); /* See "Frequency meter" comments, below. */ @@ -298,6 +300,16 @@ static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn); static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); +/* + * Cgroup v2 behavior is used when on default hierarchy or the + * cgroup_v2_mode flag is set. + */ +static inline bool is_in_v2_mode(void) +{ + return cgroup_subsys_on_dfl(cpuset_cgrp_subsys) || + (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); +} + /* * This is ugly, but preserves the userspace API for existing cpuset * users. If someone tries to mount the "cpuset" filesystem, we @@ -488,8 +500,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) /* On legacy hiearchy, we must be a subset of our parent cpuset. */ ret = -EACCES; - if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && - !is_cpuset_subset(trial, par)) + if (!is_in_v2_mode() && !is_cpuset_subset(trial, par)) goto out; /* @@ -576,6 +587,13 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr, rcu_read_unlock(); } +/* Must be called with cpuset_mutex held. */ +static inline int nr_cpusets(void) +{ + /* jump label reference count + the top-level cpuset */ + return static_key_count(&cpusets_enabled_key.key) + 1; +} + /* * generate_sched_domains() * @@ -861,7 +879,7 @@ static void update_tasks_cpumask(struct cpuset *cs) struct css_task_iter it; struct task_struct *task; - css_task_iter_start(&cs->css, &it); + css_task_iter_start(&cs->css, 0, &it); while ((task = css_task_iter_next(&it))) set_cpus_allowed_ptr(task, cs->effective_cpus); css_task_iter_end(&it); @@ -895,8 +913,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) * If it becomes empty, inherit the effective mask of the * parent, which is guaranteed to have some CPUs. */ - if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && - cpumask_empty(new_cpus)) + if (is_in_v2_mode() && cpumask_empty(new_cpus)) cpumask_copy(new_cpus, parent->effective_cpus); /* Skip the whole subtree if the cpumask remains the same. */ @@ -913,7 +930,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) cpumask_copy(cp->effective_cpus, new_cpus); spin_unlock_irq(&callback_lock); - WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && + WARN_ON(!is_in_v2_mode() && !cpumask_equal(cp->cpus_allowed, cp->effective_cpus)); update_tasks_cpumask(cp); @@ -1091,7 +1108,7 @@ static void update_tasks_nodemask(struct cpuset *cs) * It's ok if we rebind the same mm twice; mpol_rebind_mm() * is idempotent. Also migrate pages in each mm to new nodes. */ - css_task_iter_start(&cs->css, &it); + css_task_iter_start(&cs->css, 0, &it); while ((task = css_task_iter_next(&it))) { struct mm_struct *mm; bool migrate; @@ -1149,8 +1166,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) * If it becomes empty, inherit the effective mask of the * parent, which is guaranteed to have some MEMs. */ - if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && - nodes_empty(*new_mems)) + if (is_in_v2_mode() && nodes_empty(*new_mems)) *new_mems = parent->effective_mems; /* Skip the whole subtree if the nodemask remains the same. */ @@ -1167,7 +1183,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) cp->effective_mems = *new_mems; spin_unlock_irq(&callback_lock); - WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && + WARN_ON(!is_in_v2_mode() && !nodes_equal(cp->mems_allowed, cp->effective_mems)); update_tasks_nodemask(cp); @@ -1284,7 +1300,7 @@ static void update_tasks_flags(struct cpuset *cs) struct css_task_iter it; struct task_struct *task; - css_task_iter_start(&cs->css, &it); + css_task_iter_start(&cs->css, 0, &it); while ((task = css_task_iter_next(&it))) cpuset_update_task_spread_flag(cs, task); css_task_iter_end(&it); @@ -1459,7 +1475,7 @@ static int cpuset_can_attach(struct cgroup_taskset *tset) /* allow moving tasks into an empty cpuset if on default hierarchy */ ret = -ENOSPC; - if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && + if (!is_in_v2_mode() && (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) goto out_unlock; @@ -1891,6 +1907,7 @@ static struct cftype files[] = { { .name = "memory_pressure", .read_u64 = cpuset_read_u64, + .private = FILE_MEMORY_PRESSURE, }, { @@ -1977,7 +1994,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) cpuset_inc(); spin_lock_irq(&callback_lock); - if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) { + if (is_in_v2_mode()) { cpumask_copy(cs->effective_cpus, parent->effective_cpus); cs->effective_mems = parent->effective_mems; } @@ -2054,7 +2071,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css) mutex_lock(&cpuset_mutex); spin_lock_irq(&callback_lock); - if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) { + if (is_in_v2_mode()) { cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask); top_cpuset.mems_allowed = node_possible_map; } else { @@ -2248,7 +2265,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs) cpus_updated = !cpumask_equal(&new_cpus, cs->effective_cpus); mems_updated = !nodes_equal(new_mems, cs->effective_mems); - if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) + if (is_in_v2_mode()) hotplug_update_tasks(cs, &new_cpus, &new_mems, cpus_updated, mems_updated); else @@ -2258,6 +2275,13 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs) mutex_unlock(&cpuset_mutex); } +static bool force_rebuild; + +void cpuset_force_rebuild(void) +{ + force_rebuild = true; +} + /** * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset * @@ -2279,7 +2303,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) static cpumask_t new_cpus; static nodemask_t new_mems; bool cpus_updated, mems_updated; - bool on_dfl = cgroup_subsys_on_dfl(cpuset_cgrp_subsys); + bool on_dfl = is_in_v2_mode(); mutex_lock(&cpuset_mutex); @@ -2332,8 +2356,10 @@ static void cpuset_hotplug_workfn(struct work_struct *work) } /* rebuild sched domains if cpus_allowed has changed */ - if (cpus_updated) + if (cpus_updated || force_rebuild) { + force_rebuild = false; rebuild_sched_domains(); + } } void cpuset_update_active_cpus(void) @@ -2342,16 +2368,15 @@ void cpuset_update_active_cpus(void) * We're inside cpu hotplug critical region which usually nests * inside cgroup synchronization. Bounce actual hotplug processing * to a work item to avoid reverse locking order. - * - * We still need to do partition_sched_domains() synchronously; - * otherwise, the scheduler will get confused and put tasks to the - * dead CPU. Fall back to the default single domain. - * cpuset_hotplug_workfn() will rebuild it as necessary. */ - partition_sched_domains(1, NULL, NULL); schedule_work(&cpuset_hotplug_work); } +void cpuset_wait_for_hotplug(void) +{ + flush_work(&cpuset_hotplug_work); +} + /* * Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY]. * Call this routine anytime after node_states[N_MEMORY] changes. @@ -2497,12 +2522,12 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) * If we're in interrupt, yes, we can always allocate. If @node is set in * current's mems_allowed, yes. If it's not a __GFP_HARDWALL request and this * node is set in the nearest hardwalled cpuset ancestor to current's cpuset, - * yes. If current has access to memory reserves due to TIF_MEMDIE, yes. + * yes. If current has access to memory reserves as an oom victim, yes. * Otherwise, no. * * GFP_USER allocations are marked with the __GFP_HARDWALL bit, * and do not allow allocations outside the current tasks cpuset - * unless the task has been OOM killed as is marked TIF_MEMDIE. + * unless the task has been OOM killed. * GFP_KERNEL allocations are not so marked, so can escape to the * nearest enclosing hardwalled ancestor cpuset. * @@ -2525,7 +2550,7 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) * affect that: * in_interrupt - any node ok (current task context irrelevant) * GFP_ATOMIC - any node ok - * TIF_MEMDIE - any node ok + * tsk_is_oom_victim - any node ok * GFP_KERNEL - any node in enclosing hardwalled cpuset ok * GFP_USER - only nodes in current tasks mems allowed ok. */ @@ -2543,7 +2568,7 @@ bool __cpuset_node_allowed(int node, gfp_t gfp_mask) * Allow tasks that have access to memory reserves because they have * been OOM killed to get memory anywhere. */ - if (unlikely(test_thread_flag(TIF_MEMDIE))) + if (unlikely(tsk_is_oom_victim(current))) return true; if (gfp_mask & __GFP_HARDWALL) /* If hardwall request, stop here */ return false; diff --git a/kernel/cgroup/debug.c b/kernel/cgroup/debug.c index dac46af2278285e0abc546abfaacc26a2c52361b..f661b4cc5efde99eb804d5b96f2d9e22e07c91f9 100644 --- a/kernel/cgroup/debug.c +++ b/kernel/cgroup/debug.c @@ -114,27 +114,49 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) { struct cgroup_subsys_state *css = seq_css(seq); struct cgrp_cset_link *link; - int dead_cnt = 0, extra_refs = 0; + int dead_cnt = 0, extra_refs = 0, threaded_csets = 0; spin_lock_irq(&css_set_lock); + list_for_each_entry(link, &css->cgroup->cset_links, cset_link) { struct css_set *cset = link->cset; struct task_struct *task; int count = 0; int refcnt = refcount_read(&cset->refcount); - seq_printf(seq, " %d", refcnt); - if (refcnt - cset->nr_tasks > 0) { - int extra = refcnt - cset->nr_tasks; - - seq_printf(seq, " +%d", extra); - /* - * Take out the one additional reference in - * init_css_set. - */ - if (cset == &init_css_set) - extra--; - extra_refs += extra; + /* + * Print out the proc_cset and threaded_cset relationship + * and highlight difference between refcount and task_count. + */ + seq_printf(seq, "css_set %pK", cset); + if (rcu_dereference_protected(cset->dom_cset, 1) != cset) { + threaded_csets++; + seq_printf(seq, "=>%pK", cset->dom_cset); + } + if (!list_empty(&cset->threaded_csets)) { + struct css_set *tcset; + int idx = 0; + + list_for_each_entry(tcset, &cset->threaded_csets, + threaded_csets_node) { + seq_puts(seq, idx ? "," : "<="); + seq_printf(seq, "%pK", tcset); + idx++; + } + } else { + seq_printf(seq, " %d", refcnt); + if (refcnt - cset->nr_tasks > 0) { + int extra = refcnt - cset->nr_tasks; + + seq_printf(seq, " +%d", extra); + /* + * Take out the one additional reference in + * init_css_set. + */ + if (cset == &init_css_set) + extra--; + extra_refs += extra; + } } seq_puts(seq, "\n"); @@ -163,10 +185,12 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) } spin_unlock_irq(&css_set_lock); - if (!dead_cnt && !extra_refs) + if (!dead_cnt && !extra_refs && !threaded_csets) return 0; seq_puts(seq, "\n"); + if (threaded_csets) + seq_printf(seq, "threaded css_sets = %d\n", threaded_csets); if (extra_refs) seq_printf(seq, "extra references = %d\n", extra_refs); if (dead_cnt) @@ -352,6 +376,7 @@ static int __init enable_cgroup_debug(char *str) { debug_cgrp_subsys.dfl_cftypes = debug_files; debug_cgrp_subsys.implicit_on_dfl = true; + debug_cgrp_subsys.threaded = true; return 1; } __setup("cgroup_debug", enable_cgroup_debug); diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c index 1b72d56edce5e2d9253c2c03f203e81aa76bd16c..08236798d17315622d73540d62a89dcbafdc5c77 100644 --- a/kernel/cgroup/freezer.c +++ b/kernel/cgroup/freezer.c @@ -268,7 +268,7 @@ static void update_if_frozen(struct cgroup_subsys_state *css) rcu_read_unlock(); /* are all tasks frozen? */ - css_task_iter_start(css, &it); + css_task_iter_start(css, 0, &it); while ((task = css_task_iter_next(&it))) { if (freezing(task)) { @@ -320,7 +320,7 @@ static void freeze_cgroup(struct freezer *freezer) struct css_task_iter it; struct task_struct *task; - css_task_iter_start(&freezer->css, &it); + css_task_iter_start(&freezer->css, 0, &it); while ((task = css_task_iter_next(&it))) freeze_task(task); css_task_iter_end(&it); @@ -331,7 +331,7 @@ static void unfreeze_cgroup(struct freezer *freezer) struct css_task_iter it; struct task_struct *task; - css_task_iter_start(&freezer->css, &it); + css_task_iter_start(&freezer->css, 0, &it); while ((task = css_task_iter_next(&it))) __thaw_task(task); css_task_iter_end(&it); diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c index 2237201d66d5dacf1fe952a15d9acc54b1e90b50..9829c67ebc0ae0236af31913b2ce858b0a2c33b2 100644 --- a/kernel/cgroup/pids.c +++ b/kernel/cgroup/pids.c @@ -345,4 +345,5 @@ struct cgroup_subsys pids_cgrp_subsys = { .free = pids_free, .legacy_cftypes = pids_files, .dfl_cftypes = pids_files, + .threaded = true, }; diff --git a/kernel/compat.c b/kernel/compat.c index 6f0a0e723a0622a8876f9bfc81bbe08346db2ffd..772e038d04d9a85ef6e78c2df8924ca5348fce78 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -200,29 +200,6 @@ int compat_put_timespec(const struct timespec *ts, void __user *uts) } EXPORT_SYMBOL_GPL(compat_put_timespec); -int compat_convert_timespec(struct timespec __user **kts, - const void __user *cts) -{ - struct timespec ts; - struct timespec __user *uts; - - if (!cts || COMPAT_USE_64BIT_TIME) { - *kts = (struct timespec __user *)cts; - return 0; - } - - uts = compat_alloc_user_space(sizeof(ts)); - if (!uts) - return -EFAULT; - if (compat_get_timespec(&ts, cts)) - return -EFAULT; - if (copy_to_user(uts, &ts, sizeof(ts))) - return -EFAULT; - - *kts = uts; - return 0; -} - int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i) { struct compat_itimerval v32; diff --git a/kernel/configs/android-base.config b/kernel/configs/android-base.config index d70829033bb7a8fb728c4e5b3ddc8a16436280de..d3fd428f4b92606915c959467eed22e39ed0b9af 100644 --- a/kernel/configs/android-base.config +++ b/kernel/configs/android-base.config @@ -10,6 +10,7 @@ # CONFIG_USELIB is not set CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDER_DEVICES=binder,hwbinder,vndbinder CONFIG_ANDROID_LOW_MEMORY_KILLER=y CONFIG_ARMV8_DEPRECATED=y CONFIG_ASHMEM=y diff --git a/kernel/cpu.c b/kernel/cpu.c index eee0331342628f09a02720ffe34aba2f8fb12f31..d851df22f5c5eef24b9f4e3ead6e986e4b87352f 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -46,11 +47,13 @@ * @bringup: Single callback bringup or teardown selector * @cb_state: The state for a single callback (install/uninstall) * @result: Result of the operation - * @done: Signal completion to the issuer of the task + * @done_up: Signal completion to the issuer of the task for cpu-up + * @done_down: Signal completion to the issuer of the task for cpu-down */ struct cpuhp_cpu_state { enum cpuhp_state state; enum cpuhp_state target; + enum cpuhp_state fail; #ifdef CONFIG_SMP struct task_struct *thread; bool should_run; @@ -58,18 +61,39 @@ struct cpuhp_cpu_state { bool single; bool bringup; struct hlist_node *node; + struct hlist_node *last; enum cpuhp_state cb_state; int result; - struct completion done; + struct completion done_up; + struct completion done_down; #endif }; -static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state); +static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state) = { + .fail = CPUHP_INVALID, +}; #if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP) -static struct lock_class_key cpuhp_state_key; -static struct lockdep_map cpuhp_state_lock_map = - STATIC_LOCKDEP_MAP_INIT("cpuhp_state", &cpuhp_state_key); +static struct lockdep_map cpuhp_state_up_map = + STATIC_LOCKDEP_MAP_INIT("cpuhp_state-up", &cpuhp_state_up_map); +static struct lockdep_map cpuhp_state_down_map = + STATIC_LOCKDEP_MAP_INIT("cpuhp_state-down", &cpuhp_state_down_map); + + +static void inline cpuhp_lock_acquire(bool bringup) +{ + lock_map_acquire(bringup ? &cpuhp_state_up_map : &cpuhp_state_down_map); +} + +static void inline cpuhp_lock_release(bool bringup) +{ + lock_map_release(bringup ? &cpuhp_state_up_map : &cpuhp_state_down_map); +} +#else + +static void inline cpuhp_lock_acquire(bool bringup) { } +static void inline cpuhp_lock_release(bool bringup) { } + #endif /** @@ -123,13 +147,16 @@ static struct cpuhp_step *cpuhp_get_step(enum cpuhp_state state) /** * cpuhp_invoke_callback _ Invoke the callbacks for a given state * @cpu: The cpu for which the callback should be invoked - * @step: The step in the state machine + * @state: The state to do callbacks for * @bringup: True if the bringup callback should be invoked + * @node: For multi-instance, do a single entry callback for install/remove + * @lastp: For multi-instance rollback, remember how far we got * * Called from cpu hotplug and from the state register machinery. */ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, - bool bringup, struct hlist_node *node) + bool bringup, struct hlist_node *node, + struct hlist_node **lastp) { struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); struct cpuhp_step *step = cpuhp_get_step(state); @@ -137,7 +164,17 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, int (*cb)(unsigned int cpu); int ret, cnt; + if (st->fail == state) { + st->fail = CPUHP_INVALID; + + if (!(bringup ? step->startup.single : step->teardown.single)) + return 0; + + return -EAGAIN; + } + if (!step->multi_instance) { + WARN_ON_ONCE(lastp && *lastp); cb = bringup ? step->startup.single : step->teardown.single; if (!cb) return 0; @@ -152,6 +189,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, /* Single invocation for instance add/remove */ if (node) { + WARN_ON_ONCE(lastp && *lastp); trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); ret = cbm(cpu, node); trace_cpuhp_exit(cpu, st->state, state, ret); @@ -161,13 +199,23 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, /* State transition. Invoke on all instances */ cnt = 0; hlist_for_each(node, &step->list) { + if (lastp && node == *lastp) + break; + trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); ret = cbm(cpu, node); trace_cpuhp_exit(cpu, st->state, state, ret); - if (ret) - goto err; + if (ret) { + if (!lastp) + goto err; + + *lastp = node; + return ret; + } cnt++; } + if (lastp) + *lastp = NULL; return 0; err: /* Rollback the instances if one failed */ @@ -178,12 +226,39 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, hlist_for_each(node, &step->list) { if (!cnt--) break; - cbm(cpu, node); + + trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); + ret = cbm(cpu, node); + trace_cpuhp_exit(cpu, st->state, state, ret); + /* + * Rollback must not fail, + */ + WARN_ON_ONCE(ret); } return ret; } #ifdef CONFIG_SMP +static inline void wait_for_ap_thread(struct cpuhp_cpu_state *st, bool bringup) +{ + struct completion *done = bringup ? &st->done_up : &st->done_down; + wait_for_completion(done); +} + +static inline void complete_ap_thread(struct cpuhp_cpu_state *st, bool bringup) +{ + struct completion *done = bringup ? &st->done_up : &st->done_down; + complete(done); +} + +/* + * The former STARTING/DYING states, ran with IRQs disabled and must not fail. + */ +static bool cpuhp_is_atomic_state(enum cpuhp_state state) +{ + return CPUHP_AP_IDLE_DEAD <= state && state < CPUHP_AP_ONLINE; +} + /* Serializes the updates to cpu_online_mask, cpu_present_mask */ static DEFINE_MUTEX(cpu_add_remove_lock); bool cpuhp_tasks_frozen; @@ -271,14 +346,79 @@ void cpu_hotplug_enable(void) EXPORT_SYMBOL_GPL(cpu_hotplug_enable); #endif /* CONFIG_HOTPLUG_CPU */ -static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st); +static inline enum cpuhp_state +cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuhp_state target) +{ + enum cpuhp_state prev_state = st->state; + + st->rollback = false; + st->last = NULL; + + st->target = target; + st->single = false; + st->bringup = st->state < target; + + return prev_state; +} + +static inline void +cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuhp_state prev_state) +{ + st->rollback = true; + + /* + * If we have st->last we need to undo partial multi_instance of this + * state first. Otherwise start undo at the previous state. + */ + if (!st->last) { + if (st->bringup) + st->state--; + else + st->state++; + } + + st->target = prev_state; + st->bringup = !st->bringup; +} + +/* Regular hotplug invocation of the AP hotplug thread */ +static void __cpuhp_kick_ap(struct cpuhp_cpu_state *st) +{ + if (!st->single && st->state == st->target) + return; + + st->result = 0; + /* + * Make sure the above stores are visible before should_run becomes + * true. Paired with the mb() above in cpuhp_thread_fun() + */ + smp_mb(); + st->should_run = true; + wake_up_process(st->thread); + wait_for_ap_thread(st, st->bringup); +} + +static int cpuhp_kick_ap(struct cpuhp_cpu_state *st, enum cpuhp_state target) +{ + enum cpuhp_state prev_state; + int ret; + + prev_state = cpuhp_set_state(st, target); + __cpuhp_kick_ap(st); + if ((ret = st->result)) { + cpuhp_reset_state(st, prev_state); + __cpuhp_kick_ap(st); + } + + return ret; +} static int bringup_wait_for_ap(unsigned int cpu) { struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */ - wait_for_completion(&st->done); + wait_for_ap_thread(st, true); if (WARN_ON_ONCE((!cpu_online(cpu)))) return -ECANCELED; @@ -286,12 +426,10 @@ static int bringup_wait_for_ap(unsigned int cpu) stop_machine_unpark(cpu); kthread_unpark(st->thread); - /* Should we go further up ? */ - if (st->target > CPUHP_AP_ONLINE_IDLE) { - __cpuhp_kick_ap_work(st); - wait_for_completion(&st->done); - } - return st->result; + if (st->target <= CPUHP_AP_ONLINE_IDLE) + return 0; + + return cpuhp_kick_ap(st, st->target); } static int bringup_cpu(unsigned int cpu) @@ -317,32 +455,6 @@ static int bringup_cpu(unsigned int cpu) /* * Hotplug state machine related functions */ -static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st) -{ - for (st->state++; st->state < st->target; st->state++) { - struct cpuhp_step *step = cpuhp_get_step(st->state); - - if (!step->skip_onerr) - cpuhp_invoke_callback(cpu, st->state, true, NULL); - } -} - -static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, - enum cpuhp_state target) -{ - enum cpuhp_state prev_state = st->state; - int ret = 0; - - for (; st->state > target; st->state--) { - ret = cpuhp_invoke_callback(cpu, st->state, false, NULL); - if (ret) { - st->target = prev_state; - undo_cpu_down(cpu, st); - break; - } - } - return ret; -} static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st) { @@ -350,7 +462,7 @@ static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st) struct cpuhp_step *step = cpuhp_get_step(st->state); if (!step->skip_onerr) - cpuhp_invoke_callback(cpu, st->state, false, NULL); + cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); } } @@ -362,7 +474,7 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, while (st->state < target) { st->state++; - ret = cpuhp_invoke_callback(cpu, st->state, true, NULL); + ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); if (ret) { st->target = prev_state; undo_cpu_up(cpu, st); @@ -379,7 +491,8 @@ static void cpuhp_create(unsigned int cpu) { struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); - init_completion(&st->done); + init_completion(&st->done_up); + init_completion(&st->done_down); } static int cpuhp_should_run(unsigned int cpu) @@ -389,69 +502,90 @@ static int cpuhp_should_run(unsigned int cpu) return st->should_run; } -/* Execute the teardown callbacks. Used to be CPU_DOWN_PREPARE */ -static int cpuhp_ap_offline(unsigned int cpu, struct cpuhp_cpu_state *st) -{ - enum cpuhp_state target = max((int)st->target, CPUHP_TEARDOWN_CPU); - - return cpuhp_down_callbacks(cpu, st, target); -} - -/* Execute the online startup callbacks. Used to be CPU_ONLINE */ -static int cpuhp_ap_online(unsigned int cpu, struct cpuhp_cpu_state *st) -{ - return cpuhp_up_callbacks(cpu, st, st->target); -} - /* * Execute teardown/startup callbacks on the plugged cpu. Also used to invoke * callbacks when a state gets [un]installed at runtime. + * + * Each invocation of this function by the smpboot thread does a single AP + * state callback. + * + * It has 3 modes of operation: + * - single: runs st->cb_state + * - up: runs ++st->state, while st->state < st->target + * - down: runs st->state--, while st->state > st->target + * + * When complete or on error, should_run is cleared and the completion is fired. */ static void cpuhp_thread_fun(unsigned int cpu) { struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); - int ret = 0; + bool bringup = st->bringup; + enum cpuhp_state state; /* - * Paired with the mb() in cpuhp_kick_ap_work and - * cpuhp_invoke_ap_callback, so the work set is consistent visible. + * ACQUIRE for the cpuhp_should_run() load of ->should_run. Ensures + * that if we see ->should_run we also see the rest of the state. */ smp_mb(); - if (!st->should_run) + + if (WARN_ON_ONCE(!st->should_run)) return; - st->should_run = false; + cpuhp_lock_acquire(bringup); - lock_map_acquire(&cpuhp_state_lock_map); - /* Single callback invocation for [un]install ? */ if (st->single) { - if (st->cb_state < CPUHP_AP_ONLINE) { - local_irq_disable(); - ret = cpuhp_invoke_callback(cpu, st->cb_state, - st->bringup, st->node); - local_irq_enable(); + state = st->cb_state; + st->should_run = false; + } else { + if (bringup) { + st->state++; + state = st->state; + st->should_run = (st->state < st->target); + WARN_ON_ONCE(st->state > st->target); } else { - ret = cpuhp_invoke_callback(cpu, st->cb_state, - st->bringup, st->node); + state = st->state; + st->state--; + st->should_run = (st->state > st->target); + WARN_ON_ONCE(st->state < st->target); } - } else if (st->rollback) { - BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); + } + + WARN_ON_ONCE(!cpuhp_is_ap_state(state)); + + if (st->rollback) { + struct cpuhp_step *step = cpuhp_get_step(state); + if (step->skip_onerr) + goto next; + } + + if (cpuhp_is_atomic_state(state)) { + local_irq_disable(); + st->result = cpuhp_invoke_callback(cpu, state, bringup, st->node, &st->last); + local_irq_enable(); - undo_cpu_down(cpu, st); - st->rollback = false; + /* + * STARTING/DYING must not fail! + */ + WARN_ON_ONCE(st->result); } else { - /* Cannot happen .... */ - BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); - - /* Regular hotplug work */ - if (st->state < st->target) - ret = cpuhp_ap_online(cpu, st); - else if (st->state > st->target) - ret = cpuhp_ap_offline(cpu, st); + st->result = cpuhp_invoke_callback(cpu, state, bringup, st->node, &st->last); + } + + if (st->result) { + /* + * If we fail on a rollback, we're up a creek without no + * paddle, no way forward, no way back. We loose, thanks for + * playing. + */ + WARN_ON_ONCE(st->rollback); + st->should_run = false; } - lock_map_release(&cpuhp_state_lock_map); - st->result = ret; - complete(&st->done); + +next: + cpuhp_lock_release(bringup); + + if (!st->should_run) + complete_ap_thread(st, bringup); } /* Invoke a single callback on a remote cpu */ @@ -460,62 +594,64 @@ cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state, bool bringup, struct hlist_node *node) { struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); + int ret; if (!cpu_online(cpu)) return 0; - lock_map_acquire(&cpuhp_state_lock_map); - lock_map_release(&cpuhp_state_lock_map); + cpuhp_lock_acquire(false); + cpuhp_lock_release(false); + + cpuhp_lock_acquire(true); + cpuhp_lock_release(true); /* * If we are up and running, use the hotplug thread. For early calls * we invoke the thread function directly. */ if (!st->thread) - return cpuhp_invoke_callback(cpu, state, bringup, node); + return cpuhp_invoke_callback(cpu, state, bringup, node, NULL); + + st->rollback = false; + st->last = NULL; + st->node = node; + st->bringup = bringup; st->cb_state = state; st->single = true; - st->bringup = bringup; - st->node = node; - /* - * Make sure the above stores are visible before should_run becomes - * true. Paired with the mb() above in cpuhp_thread_fun() - */ - smp_mb(); - st->should_run = true; - wake_up_process(st->thread); - wait_for_completion(&st->done); - return st->result; -} + __cpuhp_kick_ap(st); -/* Regular hotplug invocation of the AP hotplug thread */ -static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st) -{ - st->result = 0; - st->single = false; /* - * Make sure the above stores are visible before should_run becomes - * true. Paired with the mb() above in cpuhp_thread_fun() + * If we failed and did a partial, do a rollback. */ - smp_mb(); - st->should_run = true; - wake_up_process(st->thread); + if ((ret = st->result) && st->last) { + st->rollback = true; + st->bringup = !bringup; + + __cpuhp_kick_ap(st); + } + + return ret; } static int cpuhp_kick_ap_work(unsigned int cpu) { struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); - enum cpuhp_state state = st->state; + enum cpuhp_state prev_state = st->state; + int ret; + + cpuhp_lock_acquire(false); + cpuhp_lock_release(false); + + cpuhp_lock_acquire(true); + cpuhp_lock_release(true); + + trace_cpuhp_enter(cpu, st->target, prev_state, cpuhp_kick_ap_work); + ret = cpuhp_kick_ap(st, st->target); + trace_cpuhp_exit(cpu, st->state, prev_state, ret); - trace_cpuhp_enter(cpu, st->target, state, cpuhp_kick_ap_work); - lock_map_acquire(&cpuhp_state_lock_map); - lock_map_release(&cpuhp_state_lock_map); - __cpuhp_kick_ap_work(st); - wait_for_completion(&st->done); - trace_cpuhp_exit(cpu, st->state, state, st->result); - return st->result; + return ret; } static struct smp_hotplug_thread cpuhp_threads = { @@ -581,6 +717,7 @@ static int take_cpu_down(void *_param) struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE); int err, cpu = smp_processor_id(); + int ret; /* Ensure this CPU doesn't handle any more interrupts. */ err = __cpu_disable(); @@ -594,8 +731,13 @@ static int take_cpu_down(void *_param) WARN_ON(st->state != CPUHP_TEARDOWN_CPU); st->state--; /* Invoke the former CPU_DYING callbacks */ - for (; st->state > target; st->state--) - cpuhp_invoke_callback(cpu, st->state, false, NULL); + for (; st->state > target; st->state--) { + ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); + /* + * DYING must not fail! + */ + WARN_ON_ONCE(ret); + } /* Give up timekeeping duties */ tick_handover_do_timer(); @@ -639,7 +781,7 @@ static int takedown_cpu(unsigned int cpu) * * Wait for the stop thread to go away. */ - wait_for_completion(&st->done); + wait_for_ap_thread(st, false); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); /* Interrupts are moved away from the dying cpu, reenable alloc/free */ @@ -650,6 +792,7 @@ static int takedown_cpu(unsigned int cpu) __cpu_die(cpu); tick_cleanup_dead_cpu(cpu); + rcutree_migrate_callbacks(cpu); return 0; } @@ -657,7 +800,7 @@ static void cpuhp_complete_idle_dead(void *arg) { struct cpuhp_cpu_state *st = arg; - complete(&st->done); + complete_ap_thread(st, false); } void cpuhp_report_idle_dead(void) @@ -675,11 +818,32 @@ void cpuhp_report_idle_dead(void) cpuhp_complete_idle_dead, st, 0); } -#else -#define takedown_cpu NULL -#endif +static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st) +{ + for (st->state++; st->state < st->target; st->state++) { + struct cpuhp_step *step = cpuhp_get_step(st->state); -#ifdef CONFIG_HOTPLUG_CPU + if (!step->skip_onerr) + cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); + } +} + +static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, + enum cpuhp_state target) +{ + enum cpuhp_state prev_state = st->state; + int ret = 0; + + for (; st->state > target; st->state--) { + ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); + if (ret) { + st->target = prev_state; + undo_cpu_down(cpu, st); + break; + } + } + return ret; +} /* Requires cpu_add_remove_lock to be held */ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, @@ -698,13 +862,13 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, cpuhp_tasks_frozen = tasks_frozen; - prev_state = st->state; - st->target = target; + prev_state = cpuhp_set_state(st, target); /* * If the current CPU state is in the range of the AP hotplug thread, * then we need to kick the thread. */ if (st->state > CPUHP_TEARDOWN_CPU) { + st->target = max((int)target, CPUHP_TEARDOWN_CPU); ret = cpuhp_kick_ap_work(cpu); /* * The AP side has done the error rollback already. Just @@ -719,6 +883,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, */ if (st->state > CPUHP_TEARDOWN_CPU) goto out; + + st->target = target; } /* * The AP brought itself down to CPUHP_TEARDOWN_CPU. So we need @@ -726,13 +892,17 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, */ ret = cpuhp_down_callbacks(cpu, st, target); if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) { - st->target = prev_state; - st->rollback = true; - cpuhp_kick_ap_work(cpu); + cpuhp_reset_state(st, prev_state); + __cpuhp_kick_ap(st); } out: cpus_write_unlock(); + /* + * Do post unplug cleanup. This is still protected against + * concurrent CPU hotplug via cpu_add_remove_lock. + */ + lockup_detector_cleanup(); return ret; } @@ -753,11 +923,15 @@ static int do_cpu_down(unsigned int cpu, enum cpuhp_state target) cpu_maps_update_done(); return err; } + int cpu_down(unsigned int cpu) { return do_cpu_down(cpu, CPUHP_OFFLINE); } EXPORT_SYMBOL(cpu_down); + +#else +#define takedown_cpu NULL #endif /*CONFIG_HOTPLUG_CPU*/ /** @@ -771,11 +945,16 @@ void notify_cpu_starting(unsigned int cpu) { struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE); + int ret; rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */ while (st->state < target) { st->state++; - cpuhp_invoke_callback(cpu, st->state, true, NULL); + ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); + /* + * STARTING must not fail! + */ + WARN_ON_ONCE(ret); } } @@ -793,7 +972,7 @@ void cpuhp_online_idle(enum cpuhp_state state) return; st->state = CPUHP_AP_ONLINE_IDLE; - complete(&st->done); + complete_ap_thread(st, true); } /* Requires cpu_add_remove_lock to be held */ @@ -828,7 +1007,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target) cpuhp_tasks_frozen = tasks_frozen; - st->target = target; + cpuhp_set_state(st, target); /* * If the current CPU state is in the range of the AP hotplug thread, * then we need to kick the thread once more. @@ -1252,7 +1431,17 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name, struct cpuhp_step *sp; int ret = 0; - if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { + /* + * If name is NULL, then the state gets removed. + * + * CPUHP_AP_ONLINE_DYN and CPUHP_BP_PREPARE_DYN are handed out on + * the first allocation from these dynamic ranges, so the removal + * would trigger a new allocation and clear the wrong (already + * empty) state, leaving the callbacks of the to be cleared state + * dangling, which causes wreckage on the next hotplug operation. + */ + if (name && (state == CPUHP_AP_ONLINE_DYN || + state == CPUHP_BP_PREPARE_DYN)) { ret = cpuhp_reserve_state(state); if (ret < 0) return ret; @@ -1285,6 +1474,10 @@ static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup, struct cpuhp_step *sp = cpuhp_get_step(state); int ret; + /* + * If there's nothing to do, we done. + * Relies on the union for multi_instance. + */ if ((bringup && !sp->startup.single) || (!bringup && !sp->teardown.single)) return 0; @@ -1296,9 +1489,9 @@ static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup, if (cpuhp_is_ap_state(state)) ret = cpuhp_invoke_ap_callback(cpu, state, bringup, node); else - ret = cpuhp_invoke_callback(cpu, state, bringup, node); + ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL); #else - ret = cpuhp_invoke_callback(cpu, state, bringup, node); + ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL); #endif BUG_ON(ret && !bringup); return ret; @@ -1630,9 +1823,55 @@ static ssize_t show_cpuhp_target(struct device *dev, } static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target); + +static ssize_t write_cpuhp_fail(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id); + struct cpuhp_step *sp; + int fail, ret; + + ret = kstrtoint(buf, 10, &fail); + if (ret) + return ret; + + /* + * Cannot fail STARTING/DYING callbacks. + */ + if (cpuhp_is_atomic_state(fail)) + return -EINVAL; + + /* + * Cannot fail anything that doesn't have callbacks. + */ + mutex_lock(&cpuhp_state_mutex); + sp = cpuhp_get_step(fail); + if (!sp->startup.single && !sp->teardown.single) + ret = -EINVAL; + mutex_unlock(&cpuhp_state_mutex); + if (ret) + return ret; + + st->fail = fail; + + return count; +} + +static ssize_t show_cpuhp_fail(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id); + + return sprintf(buf, "%d\n", st->fail); +} + +static DEVICE_ATTR(fail, 0644, show_cpuhp_fail, write_cpuhp_fail); + static struct attribute *cpuhp_cpu_attrs[] = { &dev_attr_state.attr, &dev_attr_target.attr, + &dev_attr_fail.attr, NULL }; diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c index 009cc9a17d95d601e4f6bf38f13d0f810ebbdb34..67b02e138a472da5f908a6eb2156887e058d0704 100644 --- a/kernel/cpu_pm.c +++ b/kernel/cpu_pm.c @@ -22,15 +22,21 @@ #include #include -static DEFINE_RWLOCK(cpu_pm_notifier_lock); -static RAW_NOTIFIER_HEAD(cpu_pm_notifier_chain); +static ATOMIC_NOTIFIER_HEAD(cpu_pm_notifier_chain); static int cpu_pm_notify(enum cpu_pm_event event, int nr_to_call, int *nr_calls) { int ret; - ret = __raw_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL, + /* + * __atomic_notifier_call_chain has a RCU read critical section, which + * could be disfunctional in cpu idle. Copy RCU_NONIDLE code to let + * RCU know this. + */ + rcu_irq_enter_irqson(); + ret = __atomic_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL, nr_to_call, nr_calls); + rcu_irq_exit_irqson(); return notifier_to_errno(ret); } @@ -47,14 +53,7 @@ static int cpu_pm_notify(enum cpu_pm_event event, int nr_to_call, int *nr_calls) */ int cpu_pm_register_notifier(struct notifier_block *nb) { - unsigned long flags; - int ret; - - write_lock_irqsave(&cpu_pm_notifier_lock, flags); - ret = raw_notifier_chain_register(&cpu_pm_notifier_chain, nb); - write_unlock_irqrestore(&cpu_pm_notifier_lock, flags); - - return ret; + return atomic_notifier_chain_register(&cpu_pm_notifier_chain, nb); } EXPORT_SYMBOL_GPL(cpu_pm_register_notifier); @@ -69,14 +68,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_register_notifier); */ int cpu_pm_unregister_notifier(struct notifier_block *nb) { - unsigned long flags; - int ret; - - write_lock_irqsave(&cpu_pm_notifier_lock, flags); - ret = raw_notifier_chain_unregister(&cpu_pm_notifier_chain, nb); - write_unlock_irqrestore(&cpu_pm_notifier_lock, flags); - - return ret; + return atomic_notifier_chain_unregister(&cpu_pm_notifier_chain, nb); } EXPORT_SYMBOL_GPL(cpu_pm_unregister_notifier); @@ -100,7 +92,6 @@ int cpu_pm_enter(void) int nr_calls; int ret = 0; - read_lock(&cpu_pm_notifier_lock); ret = cpu_pm_notify(CPU_PM_ENTER, -1, &nr_calls); if (ret) /* @@ -108,7 +99,6 @@ int cpu_pm_enter(void) * PM entry who are notified earlier to prepare for it. */ cpu_pm_notify(CPU_PM_ENTER_FAILED, nr_calls - 1, NULL); - read_unlock(&cpu_pm_notifier_lock); return ret; } @@ -128,13 +118,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_enter); */ int cpu_pm_exit(void) { - int ret; - - read_lock(&cpu_pm_notifier_lock); - ret = cpu_pm_notify(CPU_PM_EXIT, -1, NULL); - read_unlock(&cpu_pm_notifier_lock); - - return ret; + return cpu_pm_notify(CPU_PM_EXIT, -1, NULL); } EXPORT_SYMBOL_GPL(cpu_pm_exit); @@ -159,7 +143,6 @@ int cpu_cluster_pm_enter(void) int nr_calls; int ret = 0; - read_lock(&cpu_pm_notifier_lock); ret = cpu_pm_notify(CPU_CLUSTER_PM_ENTER, -1, &nr_calls); if (ret) /* @@ -167,7 +150,6 @@ int cpu_cluster_pm_enter(void) * PM entry who are notified earlier to prepare for it. */ cpu_pm_notify(CPU_CLUSTER_PM_ENTER_FAILED, nr_calls - 1, NULL); - read_unlock(&cpu_pm_notifier_lock); return ret; } @@ -190,13 +172,7 @@ EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter); */ int cpu_cluster_pm_exit(void) { - int ret; - - read_lock(&cpu_pm_notifier_lock); - ret = cpu_pm_notify(CPU_CLUSTER_PM_EXIT, -1, NULL); - read_unlock(&cpu_pm_notifier_lock); - - return ret; + return cpu_pm_notify(CPU_CLUSTER_PM_EXIT, -1, NULL); } EXPORT_SYMBOL_GPL(cpu_cluster_pm_exit); diff --git a/kernel/events/core.c b/kernel/events/core.c index 426c2ffba16d4ce1474a798a4c43d78d5abedb1e..6bc21e202ae40d36ceb9fa23d3c78785cad957da 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1249,26 +1249,31 @@ unclone_ctx(struct perf_event_context *ctx) return parent_ctx; } -static u32 perf_event_pid(struct perf_event *event, struct task_struct *p) +static u32 perf_event_pid_type(struct perf_event *event, struct task_struct *p, + enum pid_type type) { + u32 nr; /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; - return task_tgid_nr_ns(p, event->ns); + nr = __task_pid_nr_ns(p, type, event->ns); + /* avoid -1 if it is idle thread or runs in another ns */ + if (!nr && !pid_alive(p)) + nr = -1; + return nr; } -static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) +static u32 perf_event_pid(struct perf_event *event, struct task_struct *p) { - /* - * only top level events have the pid namespace they were created in - */ - if (event->parent) - event = event->parent; + return perf_event_pid_type(event, p, __PIDTYPE_TGID); +} - return task_pid_nr_ns(p, event->ns); +static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) +{ + return perf_event_pid_type(event, p, PIDTYPE_PID); } /* @@ -1570,6 +1575,9 @@ static void __perf_event_header_size(struct perf_event *event, u64 sample_type) if (sample_type & PERF_SAMPLE_TRANSACTION) size += sizeof(data->txn); + if (sample_type & PERF_SAMPLE_PHYS_ADDR) + size += sizeof(data->phys_addr); + event->header_size = size; } @@ -2217,6 +2225,33 @@ static int group_can_go_on(struct perf_event *event, return can_add_hw; } +/* + * Complement to update_event_times(). This computes the tstamp_* values to + * continue 'enabled' state from @now, and effectively discards the time + * between the prior tstamp_stopped and now (as we were in the OFF state, or + * just switched (context) time base). + * + * This further assumes '@event->state == INACTIVE' (we just came from OFF) and + * cannot have been scheduled in yet. And going into INACTIVE state means + * '@event->tstamp_stopped = @now'. + * + * Thus given the rules of update_event_times(): + * + * total_time_enabled = tstamp_stopped - tstamp_enabled + * total_time_running = tstamp_stopped - tstamp_running + * + * We can insert 'tstamp_stopped == now' and reverse them to compute new + * tstamp_* values. + */ +static void __perf_event_enable_time(struct perf_event *event, u64 now) +{ + WARN_ON_ONCE(event->state != PERF_EVENT_STATE_INACTIVE); + + event->tstamp_stopped = now; + event->tstamp_enabled = now - event->total_time_enabled; + event->tstamp_running = now - event->total_time_running; +} + static void add_event_to_ctx(struct perf_event *event, struct perf_event_context *ctx) { @@ -2224,9 +2259,12 @@ static void add_event_to_ctx(struct perf_event *event, list_add_event(event, ctx); perf_group_attach(event); - event->tstamp_enabled = tstamp; - event->tstamp_running = tstamp; - event->tstamp_stopped = tstamp; + /* + * We can be called with event->state == STATE_OFF when we create with + * .disabled = 1. In that case the IOC_ENABLE will call this function. + */ + if (event->state == PERF_EVENT_STATE_INACTIVE) + __perf_event_enable_time(event, tstamp); } static void ctx_sched_out(struct perf_event_context *ctx, @@ -2471,10 +2509,11 @@ static void __perf_event_mark_enabled(struct perf_event *event) u64 tstamp = perf_event_time(event); event->state = PERF_EVENT_STATE_INACTIVE; - event->tstamp_enabled = tstamp - event->total_time_enabled; + __perf_event_enable_time(event, tstamp); list_for_each_entry(sub, &event->sibling_list, group_entry) { + /* XXX should not be > INACTIVE if event isn't */ if (sub->state >= PERF_EVENT_STATE_INACTIVE) - sub->tstamp_enabled = tstamp - sub->total_time_enabled; + __perf_event_enable_time(sub, tstamp); } } @@ -3180,6 +3219,13 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx, return; perf_ctx_lock(cpuctx, ctx); + /* + * We must check ctx->nr_events while holding ctx->lock, such + * that we serialize against perf_install_in_context(). + */ + if (!ctx->nr_events) + goto unlock; + perf_pmu_disable(ctx->pmu); /* * We want to keep the following priority order: @@ -3193,6 +3239,8 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx, cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); perf_event_sched_in(cpuctx, ctx, task); perf_pmu_enable(ctx->pmu); + +unlock: perf_ctx_unlock(cpuctx, ctx); } @@ -3625,10 +3673,7 @@ static void __perf_event_read(void *info) static inline u64 perf_event_count(struct perf_event *event) { - if (event->pmu->count) - return event->pmu->count(event); - - return __perf_event_count(event); + return local64_read(&event->count) + atomic64_read(&event->child_count); } /* @@ -3659,15 +3704,6 @@ int perf_event_read_local(struct perf_event *event, u64 *value) goto out; } - /* - * It must not have a pmu::count method, those are not - * NMI safe. - */ - if (event->pmu->count) { - ret = -EOPNOTSUPP; - goto out; - } - /* If this is a per-task event, it must be for current */ if ((event->attach_state & PERF_ATTACH_TASK) && event->hw.target != current) { @@ -5090,7 +5126,7 @@ static void perf_mmap_open(struct vm_area_struct *vma) atomic_inc(&event->rb->aux_mmap_count); if (event->pmu->event_mapped) - event->pmu->event_mapped(event); + event->pmu->event_mapped(event, vma->vm_mm); } static void perf_pmu_output_stop(struct perf_event *event); @@ -5113,7 +5149,7 @@ static void perf_mmap_close(struct vm_area_struct *vma) unsigned long size = perf_data_size(rb); if (event->pmu->event_unmapped) - event->pmu->event_unmapped(event); + event->pmu->event_unmapped(event, vma->vm_mm); /* * rb->aux_mmap_count will always drop before rb->mmap_count and @@ -5411,7 +5447,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &perf_mmap_vmops; if (event->pmu->event_mapped) - event->pmu->event_mapped(event); + event->pmu->event_mapped(event, vma->vm_mm); return ret; } @@ -5972,6 +6008,9 @@ void perf_output_sample(struct perf_output_handle *handle, } } + if (sample_type & PERF_SAMPLE_PHYS_ADDR) + perf_output_put(handle, data->phys_addr); + if (!event->attr.watermark) { int wakeup_events = event->attr.wakeup_events; @@ -5987,6 +6026,38 @@ void perf_output_sample(struct perf_output_handle *handle, } } +static u64 perf_virt_to_phys(u64 virt) +{ + u64 phys_addr = 0; + struct page *p = NULL; + + if (!virt) + return 0; + + if (virt >= TASK_SIZE) { + /* If it's vmalloc()d memory, leave phys_addr as 0 */ + if (virt_addr_valid((void *)(uintptr_t)virt) && + !(virt >= VMALLOC_START && virt < VMALLOC_END)) + phys_addr = (u64)virt_to_phys((void *)(uintptr_t)virt); + } else { + /* + * Walking the pages tables for user address. + * Interrupts are disabled, so it prevents any tear down + * of the page tables. + * Try IRQ-safe __get_user_pages_fast first. + * If failed, leave phys_addr as 0. + */ + if ((current->mm != NULL) && + (__get_user_pages_fast(virt, 1, 0, &p) == 1)) + phys_addr = page_to_phys(p) + virt % PAGE_SIZE; + + if (p) + put_page(p); + } + + return phys_addr; +} + void perf_prepare_sample(struct perf_event_header *header, struct perf_sample_data *data, struct perf_event *event, @@ -6105,6 +6176,9 @@ void perf_prepare_sample(struct perf_event_header *header, header->size += size; } + + if (sample_type & PERF_SAMPLE_PHYS_ADDR) + data->phys_addr = perf_virt_to_phys(data->addr); } static void __always_inline @@ -7256,6 +7330,11 @@ static void perf_log_throttle(struct perf_event *event, int enable) perf_output_end(&handle); } +void perf_event_itrace_started(struct perf_event *event) +{ + event->attach_state |= PERF_ATTACH_ITRACE; +} + static void perf_log_itrace_start(struct perf_event *event) { struct perf_output_handle handle; @@ -7271,7 +7350,7 @@ static void perf_log_itrace_start(struct perf_event *event) event = event->parent; if (!(event->pmu->capabilities & PERF_PMU_CAP_ITRACE) || - event->hw.itrace_started) + event->attach_state & PERF_ATTACH_ITRACE) return; rec.header.type = PERF_RECORD_ITRACE_START; @@ -7875,16 +7954,15 @@ void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx, } } perf_tp_event(call->event.type, count, raw_data, size, regs, head, - rctx, task); + rctx, task, NULL); } EXPORT_SYMBOL_GPL(perf_trace_run_bpf_submit); void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, struct pt_regs *regs, struct hlist_head *head, int rctx, - struct task_struct *task) + struct task_struct *task, struct perf_event *event) { struct perf_sample_data data; - struct perf_event *event; struct perf_raw_record raw = { .frag = { @@ -7898,9 +7976,15 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, perf_trace_buf_update(record, event_type); - hlist_for_each_entry_rcu(event, head, hlist_entry) { + /* Use the given event instead of the hlist */ + if (event) { if (perf_tp_event_match(event, &data, regs)) perf_swevent_event(event, count, &data, regs); + } else { + hlist_for_each_entry_rcu(event, head, hlist_entry) { + if (perf_tp_event_match(event, &data, regs)) + perf_swevent_event(event, count, &data, regs); + } } /* @@ -8050,7 +8134,7 @@ static void perf_event_free_bpf_handler(struct perf_event *event) static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) { - bool is_kprobe, is_tracepoint; + bool is_kprobe, is_tracepoint, is_syscall_tp; struct bpf_prog *prog; if (event->attr.type != PERF_TYPE_TRACEPOINT) @@ -8061,7 +8145,8 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_UKPROBE; is_tracepoint = event->tp_event->flags & TRACE_EVENT_FL_TRACEPOINT; - if (!is_kprobe && !is_tracepoint) + is_syscall_tp = is_syscall_trace_event(event->tp_event); + if (!is_kprobe && !is_tracepoint && !is_syscall_tp) /* bpf programs can only be attached to u/kprobe or tracepoint */ return -EINVAL; @@ -8070,13 +8155,14 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) return PTR_ERR(prog); if ((is_kprobe && prog->type != BPF_PROG_TYPE_KPROBE) || - (is_tracepoint && prog->type != BPF_PROG_TYPE_TRACEPOINT)) { + (is_tracepoint && prog->type != BPF_PROG_TYPE_TRACEPOINT) || + (is_syscall_tp && prog->type != BPF_PROG_TYPE_TRACEPOINT)) { /* valid fd, but invalid bpf program type */ bpf_prog_put(prog); return -EINVAL; } - if (is_tracepoint) { + if (is_tracepoint || is_syscall_tp) { int off = trace_event_get_offsets(event->tp_event); if (prog->aux->max_ctx_offset > off) { @@ -8085,6 +8171,7 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) } } event->tp_event->prog = prog; + event->tp_event->bpf_prog_owner = event; return 0; } @@ -8099,7 +8186,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event) return; prog = event->tp_event->prog; - if (prog) { + if (prog && event->tp_event->bpf_prog_owner == event) { event->tp_event->prog = NULL; bpf_prog_put(prog); } @@ -9580,6 +9667,8 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, if (ret) return -EFAULT; + attr->size = size; + if (attr->__reserved_1) return -EINVAL; @@ -9852,6 +9941,11 @@ SYSCALL_DEFINE5(perf_event_open, return -EINVAL; } + /* Only privileged users can get physical addresses */ + if ((attr.sample_type & PERF_SAMPLE_PHYS_ADDR) && + perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) + return -EACCES; + if (!attr.sample_max_stack) attr.sample_max_stack = sysctl_perf_event_max_stack; @@ -10001,28 +10095,27 @@ SYSCALL_DEFINE5(perf_event_open, goto err_context; /* - * Do not allow to attach to a group in a different - * task or CPU context: + * Make sure we're both events for the same CPU; + * grouping events for different CPUs is broken; since + * you can never concurrently schedule them anyhow. */ - if (move_group) { - /* - * Make sure we're both on the same task, or both - * per-cpu events. - */ - if (group_leader->ctx->task != ctx->task) - goto err_context; + if (group_leader->cpu != event->cpu) + goto err_context; - /* - * Make sure we're both events for the same CPU; - * grouping events for different CPUs is broken; since - * you can never concurrently schedule them anyhow. - */ - if (group_leader->cpu != event->cpu) - goto err_context; - } else { - if (group_leader->ctx != ctx) - goto err_context; - } + /* + * Make sure we're both on the same task, or both + * per-CPU events. + */ + if (group_leader->ctx->task != ctx->task) + goto err_context; + + /* + * Do not allow to attach to a group in a different task + * or CPU context. If we're moving SW events, we'll fix + * this up later, so allow that. + */ + if (!move_group && group_leader->ctx != ctx) + goto err_context; /* * Only a group leader can be exclusive or pinned @@ -11201,5 +11294,6 @@ struct cgroup_subsys perf_event_cgrp_subsys = { * controller is not mounted on a legacy hierarchy. */ .implicit_on_dfl = true, + .threaded = true, }; #endif /* CONFIG_CGROUP_PERF */ diff --git a/kernel/events/internal.h b/kernel/events/internal.h index 486fd78eb8d5e426dcc88ee6c68e28a10601decf..843e9704733551aa7b2cac2c3db3dd35e7618c6d 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h @@ -38,9 +38,9 @@ struct ring_buffer { struct user_struct *mmap_user; /* AUX area */ - local_t aux_head; + long aux_head; local_t aux_nest; - local_t aux_wakeup; + long aux_wakeup; /* last aux_watermark boundary crossed by aux_head */ unsigned long aux_pgoff; int aux_nr_pages; int aux_overwrite; @@ -208,7 +208,7 @@ static inline int get_recursion_context(int *recursion) { int rctx; - if (in_nmi()) + if (unlikely(in_nmi())) rctx = 3; else if (in_irq()) rctx = 2; diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index ee97196bb1510e4f95cfd6ddc039fa9700cdc828..f684d8e5fa2be2fd10e4d5e2f1e65a5c2afeb629 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -367,7 +367,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, if (WARN_ON_ONCE(local_xchg(&rb->aux_nest, 1))) goto err_put; - aux_head = local_read(&rb->aux_head); + aux_head = rb->aux_head; handle->rb = rb; handle->event = event; @@ -382,7 +382,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, */ if (!rb->aux_overwrite) { aux_tail = ACCESS_ONCE(rb->user_page->aux_tail); - handle->wakeup = local_read(&rb->aux_wakeup) + rb->aux_watermark; + handle->wakeup = rb->aux_wakeup + rb->aux_watermark; if (aux_head - aux_tail < perf_aux_size(rb)) handle->size = CIRC_SPACE(aux_head, aux_tail, perf_aux_size(rb)); @@ -412,6 +412,19 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, return NULL; } +static bool __always_inline rb_need_aux_wakeup(struct ring_buffer *rb) +{ + if (rb->aux_overwrite) + return false; + + if (rb->aux_head - rb->aux_wakeup >= rb->aux_watermark) { + rb->aux_wakeup = rounddown(rb->aux_head, rb->aux_watermark); + return true; + } + + return false; +} + /* * Commit the data written by hardware into the ring buffer by adjusting * aux_head and posting a PERF_RECORD_AUX into the perf buffer. It is the @@ -433,12 +446,12 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size) handle->aux_flags |= PERF_AUX_FLAG_OVERWRITE; aux_head = handle->head; - local_set(&rb->aux_head, aux_head); + rb->aux_head = aux_head; } else { handle->aux_flags &= ~PERF_AUX_FLAG_OVERWRITE; - aux_head = local_read(&rb->aux_head); - local_add(size, &rb->aux_head); + aux_head = rb->aux_head; + rb->aux_head += size; } if (size || handle->aux_flags) { @@ -450,12 +463,9 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size) handle->aux_flags); } - aux_head = rb->user_page->aux_head = local_read(&rb->aux_head); - - if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) { + rb->user_page->aux_head = rb->aux_head; + if (rb_need_aux_wakeup(rb)) wakeup = true; - local_add(rb->aux_watermark, &rb->aux_wakeup); - } if (wakeup) { if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED) @@ -478,22 +488,19 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size) int perf_aux_output_skip(struct perf_output_handle *handle, unsigned long size) { struct ring_buffer *rb = handle->rb; - unsigned long aux_head; if (size > handle->size) return -ENOSPC; - local_add(size, &rb->aux_head); + rb->aux_head += size; - aux_head = rb->user_page->aux_head = local_read(&rb->aux_head); - if (aux_head - local_read(&rb->aux_wakeup) >= rb->aux_watermark) { + rb->user_page->aux_head = rb->aux_head; + if (rb_need_aux_wakeup(rb)) { perf_output_wakeup(handle); - local_add(rb->aux_watermark, &rb->aux_wakeup); - handle->wakeup = local_read(&rb->aux_wakeup) + - rb->aux_watermark; + handle->wakeup = rb->aux_wakeup + rb->aux_watermark; } - handle->head = aux_head; + handle->head = rb->aux_head; handle->size -= size; return 0; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 0e137f98a50c30db936a8deecedc1f84455aca23..267f6ef91d9709e2f53c35e053a792d3fcede64d 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1262,8 +1262,6 @@ void uprobe_end_dup_mmap(void) void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) { - newmm->uprobes_state.xol_area = NULL; - if (test_bit(MMF_HAS_UPROBES, &oldmm->flags)) { set_bit(MMF_HAS_UPROBES, &newmm->flags); /* unconditionally, dup_mmap() skips VM_DONTCOPY vmas */ diff --git a/kernel/exit.c b/kernel/exit.c index c5548faa9f377c5bf01f4a4db8e3020448565469..f2cd53e92147c35c43d773b1eb688098fe4b7db3 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -764,7 +764,6 @@ void __noreturn do_exit(long code) { struct task_struct *tsk = current; int group_dead; - TASKS_RCU(int tasks_rcu_i); profile_task_exit(tsk); kcov_task_exit(tsk); @@ -819,7 +818,8 @@ void __noreturn do_exit(long code) * Ensure that we must observe the pi_state in exit_mm() -> * mm_release() -> exit_pi_state_list(). */ - raw_spin_unlock_wait(&tsk->pi_lock); + raw_spin_lock_irq(&tsk->pi_lock); + raw_spin_unlock_irq(&tsk->pi_lock); if (unlikely(in_atomic())) { pr_info("note: %s[%d] exited with preempt_count %d\n", @@ -881,9 +881,7 @@ void __noreturn do_exit(long code) */ flush_ptrace_hw_breakpoint(tsk); - TASKS_RCU(preempt_disable()); - TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu)); - TASKS_RCU(preempt_enable()); + exit_tasks_rcu_start(); exit_notify(tsk, group_dead); proc_exit_connector(tsk); mpol_put_task_policy(tsk); @@ -918,8 +916,9 @@ void __noreturn do_exit(long code) if (tsk->nr_dirtied) __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied); exit_rcu(); - TASKS_RCU(__srcu_read_unlock(&tasks_rcu_exit_srcu, tasks_rcu_i)); + exit_tasks_rcu_finish(); + lockdep_free_task(tsk); do_task_dead(); } EXPORT_SYMBOL_GPL(do_exit); @@ -1601,12 +1600,10 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, struct waitid_info info = {.status = 0}; long err = kernel_waitid(which, upid, &info, options, ru ? &r : NULL); int signo = 0; + if (err > 0) { signo = SIGCHLD; err = 0; - } - - if (!err) { if (ru && copy_to_user(ru, &r, sizeof(struct rusage))) return -EFAULT; } @@ -1616,7 +1613,7 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, user_access_begin(); unsafe_put_user(signo, &infop->si_signo, Efault); unsafe_put_user(0, &infop->si_errno, Efault); - unsafe_put_user((short)info.cause, &infop->si_code, Efault); + unsafe_put_user(info.cause, &infop->si_code, Efault); unsafe_put_user(info.pid, &infop->si_pid, Efault); unsafe_put_user(info.uid, &infop->si_uid, Efault); unsafe_put_user(info.status, &infop->si_status, Efault); @@ -1724,16 +1721,15 @@ COMPAT_SYSCALL_DEFINE5(waitid, if (err > 0) { signo = SIGCHLD; err = 0; - } - - if (!err && uru) { - /* kernel_waitid() overwrites everything in ru */ - if (COMPAT_USE_64BIT_TIME) - err = copy_to_user(uru, &ru, sizeof(ru)); - else - err = put_compat_rusage(&ru, uru); - if (err) - return -EFAULT; + if (uru) { + /* kernel_waitid() overwrites everything in ru */ + if (COMPAT_USE_64BIT_TIME) + err = copy_to_user(uru, &ru, sizeof(ru)); + else + err = put_compat_rusage(&ru, uru); + if (err) + return -EFAULT; + } } if (!infop) @@ -1742,7 +1738,7 @@ COMPAT_SYSCALL_DEFINE5(waitid, user_access_begin(); unsafe_put_user(signo, &infop->si_signo, Efault); unsafe_put_user(0, &infop->si_errno, Efault); - unsafe_put_user((short)info.cause, &infop->si_code, Efault); + unsafe_put_user(info.cause, &infop->si_code, Efault); unsafe_put_user(info.pid, &infop->si_pid, Efault); unsafe_put_user(info.uid, &infop->si_uid, Efault); unsafe_put_user(info.status, &infop->si_status, Efault); diff --git a/kernel/extable.c b/kernel/extable.c index 38c2412401a1b118d53d3cff92eba24753134aed..9aa1cc41ecf79c8c2cc5fb9dbd3fbd418025c0dd 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -102,15 +102,7 @@ int core_kernel_data(unsigned long addr) int __kernel_text_address(unsigned long addr) { - if (core_kernel_text(addr)) - return 1; - if (is_module_text_address(addr)) - return 1; - if (is_ftrace_trampoline(addr)) - return 1; - if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) - return 1; - if (is_bpf_text_address(addr)) + if (kernel_text_address(addr)) return 1; /* * There might be init symbols in saved stacktraces. @@ -127,17 +119,42 @@ int __kernel_text_address(unsigned long addr) int kernel_text_address(unsigned long addr) { + bool no_rcu; + int ret = 1; + if (core_kernel_text(addr)) return 1; + + /* + * If a stack dump happens while RCU is not watching, then + * RCU needs to be notified that it requires to start + * watching again. This can happen either by tracing that + * triggers a stack trace, or a WARN() that happens during + * coming back from idle, or cpu on or offlining. + * + * is_module_text_address() as well as the kprobe slots + * and is_bpf_text_address() require RCU to be watching. + */ + no_rcu = !rcu_is_watching(); + + /* Treat this like an NMI as it can happen anywhere */ + if (no_rcu) + rcu_nmi_enter(); + if (is_module_text_address(addr)) - return 1; + goto out; if (is_ftrace_trampoline(addr)) - return 1; + goto out; if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) - return 1; + goto out; if (is_bpf_text_address(addr)) - return 1; - return 0; + goto out; + ret = 0; +out: + if (no_rcu) + rcu_nmi_exit(); + + return ret; } /* diff --git a/kernel/fork.c b/kernel/fork.c index 17921b0390b4f91113bcf8c9ccac5c1225751460..e702cb9ffbd85ab7ff388c17654f729614d0b296 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,7 @@ #include #include #include +#include #include #include @@ -217,7 +219,7 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) return s->addr; } - stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE, + stack = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, VMALLOC_START, VMALLOC_END, THREADINFO_GFP, PAGE_KERNEL, @@ -484,6 +486,8 @@ void __init fork_init(void) cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", NULL, free_vm_stack_cache); #endif + + lockdep_init_task(&init_task); } int __weak arch_dup_task_struct(struct task_struct *dst, @@ -654,7 +658,12 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, retval = dup_userfaultfd(tmp, &uf); if (retval) goto fail_nomem_anon_vma_fork; - if (anon_vma_fork(tmp, mpnt)) + if (tmp->vm_flags & VM_WIPEONFORK) { + /* VM_WIPEONFORK gets a clean slate in the child. */ + tmp->anon_vma = NULL; + if (anon_vma_prepare(tmp)) + goto fail_nomem_anon_vma_fork; + } else if (anon_vma_fork(tmp, mpnt)) goto fail_nomem_anon_vma_fork; tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT); tmp->vm_next = tmp->vm_prev = NULL; @@ -698,7 +707,8 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, rb_parent = &tmp->vm_rb; mm->map_count++; - retval = copy_page_range(mm, oldmm, mpnt); + if (!(tmp->vm_flags & VM_WIPEONFORK)) + retval = copy_page_range(mm, oldmm, mpnt); if (tmp->vm_ops && tmp->vm_ops->open) tmp->vm_ops->open(tmp); @@ -785,6 +795,13 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p) #endif } +static void mm_init_uprobes_state(struct mm_struct *mm) +{ +#ifdef CONFIG_UPROBES + mm->uprobes_state.xol_area = NULL; +#endif +} + static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, struct user_namespace *user_ns) { @@ -806,11 +823,14 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, mm_init_cpumask(mm); mm_init_aio(mm); mm_init_owner(mm, p); + RCU_INIT_POINTER(mm->exe_file, NULL); mmu_notifier_mm_init(mm); - clear_tlb_flush_pending(mm); + hmm_mm_init(mm); + init_tlb_flush_pending(mm); #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS mm->pmd_huge_pte = NULL; #endif + mm_init_uprobes_state(mm); if (current->mm) { mm->flags = current->mm->flags & MMF_INIT_MASK; @@ -885,6 +905,7 @@ void __mmdrop(struct mm_struct *mm) BUG_ON(mm == &init_mm); mm_free_pgd(mm); destroy_context(mm); + hmm_mm_destroy(mm); mmu_notifier_mm_destroy(mm); check_mm(mm); put_user_ns(mm->user_ns); @@ -910,7 +931,6 @@ static inline void __mmput(struct mm_struct *mm) } if (mm->binfmt) module_put(mm->binfmt->module); - set_bit(MMF_OOM_SKIP, &mm->flags); mmdrop(mm); } @@ -929,7 +949,9 @@ EXPORT_SYMBOL_GPL(mmput); #ifdef CONFIG_MMU static void mmput_async_fn(struct work_struct *work) { - struct mm_struct *mm = container_of(work, struct mm_struct, async_put_work); + struct mm_struct *mm = container_of(work, struct mm_struct, + async_put_work); + __mmput(mm); } @@ -1458,8 +1480,7 @@ static void rt_mutex_init_task(struct task_struct *p) { raw_spin_lock_init(&p->pi_lock); #ifdef CONFIG_RT_MUTEXES - p->pi_waiters = RB_ROOT; - p->pi_waiters_leftmost = NULL; + p->pi_waiters = RB_ROOT_CACHED; p->pi_top_task = NULL; p->pi_blocked_on = NULL; #endif @@ -1566,10 +1587,6 @@ static __latent_entropy struct task_struct *copy_process( return ERR_PTR(-EINVAL); } - retval = security_task_create(clone_flags); - if (retval) - goto fork_out; - retval = -ENOMEM; p = dup_task_struct(current, node); if (!p) @@ -1691,6 +1708,7 @@ static __latent_entropy struct task_struct *copy_process( p->lockdep_depth = 0; /* no locks held yet */ p->curr_chain_key = 0; p->lockdep_recursion = 0; + lockdep_init_task(p); #endif #ifdef CONFIG_DEBUG_MUTEXES @@ -1949,6 +1967,7 @@ static __latent_entropy struct task_struct *copy_process( bad_fork_cleanup_perf: perf_event_free_task(p); bad_fork_cleanup_policy: + lockdep_free_task(p); #ifdef CONFIG_NUMA mpol_put(p->mempolicy); bad_fork_cleanup_threadgroup_lock: diff --git a/kernel/futex.c b/kernel/futex.c index 16dbe4c938953a70a49faf0a5264af8c19a9491f..0518a0bfc746bab4f257f2fa81ef7361f99ff113 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -670,13 +670,14 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) * this reference was taken by ihold under the page lock * pinning the inode in place so i_lock was unnecessary. The * only way for this check to fail is if the inode was - * truncated in parallel so warn for now if this happens. + * truncated in parallel which is almost certainly an + * application bug. In such a case, just retry. * * We are not calling into get_futex_key_refs() in file-backed * cases, therefore a successful atomic_inc return below will * guarantee that get_futex_key() will still imply smp_mb(); (B). */ - if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) { + if (!atomic_inc_not_zero(&inode->i_count)) { rcu_read_unlock(); put_page(page); @@ -820,8 +821,6 @@ static void get_pi_state(struct futex_pi_state *pi_state) /* * Drops a reference to the pi_state object and frees or caches it * when the last reference is gone. - * - * Must be called with the hb lock held. */ static void put_pi_state(struct futex_pi_state *pi_state) { @@ -836,16 +835,22 @@ static void put_pi_state(struct futex_pi_state *pi_state) * and has cleaned up the pi_state already */ if (pi_state->owner) { - raw_spin_lock_irq(&pi_state->owner->pi_lock); - list_del_init(&pi_state->list); - raw_spin_unlock_irq(&pi_state->owner->pi_lock); + struct task_struct *owner; - rt_mutex_proxy_unlock(&pi_state->pi_mutex, pi_state->owner); + raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + owner = pi_state->owner; + if (owner) { + raw_spin_lock(&owner->pi_lock); + list_del_init(&pi_state->list); + raw_spin_unlock(&owner->pi_lock); + } + rt_mutex_proxy_unlock(&pi_state->pi_mutex, owner); + raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); } - if (current->pi_state_cache) + if (current->pi_state_cache) { kfree(pi_state); - else { + } else { /* * pi_state->list is already empty. * clear pi_state->owner. @@ -875,6 +880,8 @@ static struct task_struct *futex_find_get_task(pid_t pid) return p; } +#ifdef CONFIG_FUTEX_PI + /* * This task is holding PI mutexes at exit time => bad. * Kernel cleans up PI-state, but userspace is likely hosed. @@ -904,13 +911,14 @@ void exit_pi_state_list(struct task_struct *curr) raw_spin_unlock_irq(&curr->pi_lock); spin_lock(&hb->lock); - - raw_spin_lock_irq(&curr->pi_lock); + raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + raw_spin_lock(&curr->pi_lock); /* * We dropped the pi-lock, so re-check whether this * task still owns the PI-state: */ if (head->next != next) { + raw_spin_unlock(&pi_state->pi_mutex.wait_lock); spin_unlock(&hb->lock); continue; } @@ -919,9 +927,10 @@ void exit_pi_state_list(struct task_struct *curr) WARN_ON(list_empty(&pi_state->list)); list_del_init(&pi_state->list); pi_state->owner = NULL; - raw_spin_unlock_irq(&curr->pi_lock); + raw_spin_unlock(&curr->pi_lock); get_pi_state(pi_state); + raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); spin_unlock(&hb->lock); rt_mutex_futex_unlock(&pi_state->pi_mutex); @@ -932,6 +941,8 @@ void exit_pi_state_list(struct task_struct *curr) raw_spin_unlock_irq(&curr->pi_lock); } +#endif + /* * We need to check the following states: * @@ -1203,6 +1214,10 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key, WARN_ON(!list_empty(&pi_state->list)); list_add(&pi_state->list, &p->pi_state_list); + /* + * Assignment without holding pi_state->pi_mutex.wait_lock is safe + * because there is no concurrency as the object is not published yet. + */ pi_state->owner = p; raw_spin_unlock_irq(&p->pi_lock); @@ -1546,6 +1561,45 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) return ret; } +static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) +{ + unsigned int op = (encoded_op & 0x70000000) >> 28; + unsigned int cmp = (encoded_op & 0x0f000000) >> 24; + int oparg = sign_extend32((encoded_op & 0x00fff000) >> 12, 12); + int cmparg = sign_extend32(encoded_op & 0x00000fff, 12); + int oldval, ret; + + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) { + if (oparg < 0 || oparg > 31) + return -EINVAL; + oparg = 1 << oparg; + } + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + + ret = arch_futex_atomic_op_inuser(op, oparg, &oldval, uaddr); + if (ret) + return ret; + + switch (cmp) { + case FUTEX_OP_CMP_EQ: + return oldval == cmparg; + case FUTEX_OP_CMP_NE: + return oldval != cmparg; + case FUTEX_OP_CMP_LT: + return oldval < cmparg; + case FUTEX_OP_CMP_GE: + return oldval >= cmparg; + case FUTEX_OP_CMP_LE: + return oldval <= cmparg; + case FUTEX_OP_CMP_GT: + return oldval > cmparg; + default: + return -ENOSYS; + } +} + /* * Wake up all waiters hashed on the physical page that is mapped * to this virtual address: @@ -1799,6 +1853,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, struct futex_q *this, *next; DEFINE_WAKE_Q(wake_q); + /* + * When PI not supported: return -ENOSYS if requeue_pi is true, + * consequently the compiler knows requeue_pi is always false past + * this point which will optimize away all the conditional code + * further down. + */ + if (!IS_ENABLED(CONFIG_FUTEX_PI) && requeue_pi) + return -ENOSYS; + if (requeue_pi) { /* * Requeue PI only works on two distinct uaddrs. This @@ -2594,6 +2657,9 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, struct futex_q q = futex_q_init; int res, ret; + if (!IS_ENABLED(CONFIG_FUTEX_PI)) + return -ENOSYS; + if (refill_pi_state_cache()) return -ENOMEM; @@ -2773,6 +2839,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) struct futex_q *top_waiter; int ret; + if (!IS_ENABLED(CONFIG_FUTEX_PI)) + return -ENOSYS; + retry: if (get_user(uval, uaddr)) return -EFAULT; @@ -2819,6 +2888,7 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); spin_unlock(&hb->lock); + /* drops pi_state->pi_mutex.wait_lock */ ret = wake_futex_pi(uaddr, uval, pi_state); put_pi_state(pi_state); @@ -2983,6 +3053,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, struct futex_q q = futex_q_init; int res, ret; + if (!IS_ENABLED(CONFIG_FUTEX_PI)) + return -ENOSYS; + if (uaddr == uaddr2) return -EINVAL; diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 27c4e774071ce68ce06bc86c8ed817536e0e795b..a117adf7084b88fd8ad26897623d2a196813538c 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -63,11 +63,20 @@ config GENERIC_IRQ_CHIP config IRQ_DOMAIN bool +# Support for simulated interrupts +config IRQ_SIM + bool + select IRQ_WORK + # Support for hierarchical irq domains config IRQ_DOMAIN_HIERARCHY bool select IRQ_DOMAIN +# Support for hierarchical fasteoi+edge and fasteoi+level handlers +config IRQ_FASTEOI_HIERARCHY_HANDLERS + bool + # Generic IRQ IPI support config GENERIC_IRQ_IPI bool diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile index e4aef7351f2b615bdbf679fa478fc3557387c317..1970cafe8f2ad147e8680006709347a730bc49b7 100644 --- a/kernel/irq/Makefile +++ b/kernel/irq/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_IRQ_TIMINGS) += timings.o obj-$(CONFIG_GENERIC_IRQ_CHIP) += generic-chip.o obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o +obj-$(CONFIG_IRQ_SIM) += irq_sim.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o obj-$(CONFIG_GENERIC_IRQ_MIGRATION) += cpuhotplug.o diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index a3cc37c0c85e2267497f650611b656af90aaf5aa..6fc89fd938248f7e616e1594a786e2ffc4f19a5c 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -202,7 +202,7 @@ __irq_startup_managed(struct irq_desc *desc, struct cpumask *aff, bool force) irqd_clr_managed_shutdown(d); - if (cpumask_any_and(aff, cpu_online_mask) > nr_cpu_ids) { + if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) { /* * Catch code which fiddles with enable_irq() on a managed * and potentially shutdown IRQ. Chained interrupt @@ -1000,7 +1000,7 @@ EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name); void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) { - unsigned long flags; + unsigned long flags, trigger, tmp; struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); if (!desc) @@ -1014,6 +1014,8 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) irq_settings_clr_and_set(desc, clr, set); + trigger = irqd_get_trigger_type(&desc->irq_data); + irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU | IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT); if (irq_settings_has_no_balance_set(desc)) @@ -1025,7 +1027,11 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) if (irq_settings_is_level(desc)) irqd_set(&desc->irq_data, IRQD_LEVEL); - irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc)); + tmp = irq_settings_get_trigger_mask(desc); + if (tmp != IRQ_TYPE_NONE) + trigger = tmp; + + irqd_set(&desc->irq_data, trigger); irq_put_desc_unlock(desc, flags); } @@ -1092,6 +1098,112 @@ void irq_cpu_offline(void) } #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY + +#ifdef CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS +/** + * handle_fasteoi_ack_irq - irq handler for edge hierarchy + * stacked on transparent controllers + * + * @desc: the interrupt description structure for this irq + * + * Like handle_fasteoi_irq(), but for use with hierarchy where + * the irq_chip also needs to have its ->irq_ack() function + * called. + */ +void handle_fasteoi_ack_irq(struct irq_desc *desc) +{ + struct irq_chip *chip = desc->irq_data.chip; + + raw_spin_lock(&desc->lock); + + if (!irq_may_run(desc)) + goto out; + + desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); + + /* + * If its disabled or no action available + * then mask it and get out of here: + */ + if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { + desc->istate |= IRQS_PENDING; + mask_irq(desc); + goto out; + } + + kstat_incr_irqs_this_cpu(desc); + if (desc->istate & IRQS_ONESHOT) + mask_irq(desc); + + /* Start handling the irq */ + desc->irq_data.chip->irq_ack(&desc->irq_data); + + preflow_handler(desc); + handle_irq_event(desc); + + cond_unmask_eoi_irq(desc, chip); + + raw_spin_unlock(&desc->lock); + return; +out: + if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED)) + chip->irq_eoi(&desc->irq_data); + raw_spin_unlock(&desc->lock); +} +EXPORT_SYMBOL_GPL(handle_fasteoi_ack_irq); + +/** + * handle_fasteoi_mask_irq - irq handler for level hierarchy + * stacked on transparent controllers + * + * @desc: the interrupt description structure for this irq + * + * Like handle_fasteoi_irq(), but for use with hierarchy where + * the irq_chip also needs to have its ->irq_mask_ack() function + * called. + */ +void handle_fasteoi_mask_irq(struct irq_desc *desc) +{ + struct irq_chip *chip = desc->irq_data.chip; + + raw_spin_lock(&desc->lock); + mask_ack_irq(desc); + + if (!irq_may_run(desc)) + goto out; + + desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); + + /* + * If its disabled or no action available + * then mask it and get out of here: + */ + if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { + desc->istate |= IRQS_PENDING; + mask_irq(desc); + goto out; + } + + kstat_incr_irqs_this_cpu(desc); + if (desc->istate & IRQS_ONESHOT) + mask_irq(desc); + + preflow_handler(desc); + handle_irq_event(desc); + + cond_unmask_eoi_irq(desc, chip); + + raw_spin_unlock(&desc->lock); + return; +out: + if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED)) + chip->irq_eoi(&desc->irq_data); + raw_spin_unlock(&desc->lock); +} +EXPORT_SYMBOL_GPL(handle_fasteoi_mask_irq); + +#endif /* CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS */ + /** * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if * NULL) @@ -1105,6 +1217,7 @@ void irq_chip_enable_parent(struct irq_data *data) else data->chip->irq_unmask(data); } +EXPORT_SYMBOL_GPL(irq_chip_enable_parent); /** * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if @@ -1119,6 +1232,7 @@ void irq_chip_disable_parent(struct irq_data *data) else data->chip->irq_mask(data); } +EXPORT_SYMBOL_GPL(irq_chip_disable_parent); /** * irq_chip_ack_parent - Acknowledge the parent interrupt @@ -1181,6 +1295,7 @@ int irq_chip_set_affinity_parent(struct irq_data *data, return -ENOSYS; } +EXPORT_SYMBOL_GPL(irq_chip_set_affinity_parent); /** * irq_chip_set_type_parent - Set IRQ type on the parent interrupt diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c index 4d384edc0c64eb1807cf3f8056c2607c58053ab1..c3fdb36dec304956650082efc63bed95f37ff56c 100644 --- a/kernel/irq/debugfs.c +++ b/kernel/irq/debugfs.c @@ -5,6 +5,7 @@ */ #include #include +#include #include "internals.h" @@ -171,8 +172,55 @@ static int irq_debug_open(struct inode *inode, struct file *file) return single_open(file, irq_debug_show, inode->i_private); } +static ssize_t irq_debug_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct irq_desc *desc = file_inode(file)->i_private; + char buf[8] = { 0, }; + size_t size; + + size = min(sizeof(buf) - 1, count); + if (copy_from_user(buf, user_buf, size)) + return -EFAULT; + + if (!strncmp(buf, "trigger", size)) { + unsigned long flags; + int err; + + /* Try the HW interface first */ + err = irq_set_irqchip_state(irq_desc_get_irq(desc), + IRQCHIP_STATE_PENDING, true); + if (!err) + return count; + + /* + * Otherwise, try to inject via the resend interface, + * which may or may not succeed. + */ + chip_bus_lock(desc); + raw_spin_lock_irqsave(&desc->lock, flags); + + if (irq_settings_is_level(desc)) { + /* Can't do level, sorry */ + err = -EINVAL; + } else { + desc->istate |= IRQS_PENDING; + check_irq_resend(desc); + err = 0; + } + + raw_spin_unlock_irqrestore(&desc->lock, flags); + chip_bus_sync_unlock(desc); + + return err ? err : count; + } + + return count; +} + static const struct file_operations dfs_irq_ops = { .open = irq_debug_open, + .write = irq_debug_write, .read = seq_read, .llseek = seq_lseek, .release = single_release, @@ -186,7 +234,7 @@ void irq_add_debugfs_entry(unsigned int irq, struct irq_desc *desc) return; sprintf(name, "%d", irq); - desc->debugfs_file = debugfs_create_file(name, 0444, irq_dir, desc, + desc->debugfs_file = debugfs_create_file(name, 0644, irq_dir, desc, &dfs_irq_ops); } diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index f7086b78ad6e1e1bcb3995537b024d7ed057ef0e..5270a54b9fa4dbf6a4cbdf3e990edc6a0156a915 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -322,7 +322,6 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip, /* Calc pointer to the next generic chip */ tmp += sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); } - d->name = name; return 0; } EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index a2c48058354c871803eb9650db60acc0e7cb4b13..a4aa39009f0d50d5be26e32b768bc2a2ff9c1f27 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -151,7 +151,7 @@ static inline void chip_bus_sync_unlock(struct irq_desc *desc) #define IRQ_GET_DESC_CHECK_PERCPU (_IRQ_DESC_CHECK | _IRQ_DESC_PERCPU) #define for_each_action_of_desc(desc, act) \ - for (act = desc->act; act; act = act->next) + for (act = desc->action; act; act = act->next) struct irq_desc * __irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus, diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index 1a9abc1c8ea0046d6491d1786645f1c1e4e1eee2..259a22aa9934cf9d67eb779e5e3eae22db0a3412 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -165,7 +165,7 @@ irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu) struct irq_data *data = irq_get_irq_data(irq); struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL; - if (!data || !ipimask || cpu > nr_cpu_ids) + if (!data || !ipimask || cpu >= nr_cpu_ids) return INVALID_HWIRQ; if (!cpumask_test_cpu(cpu, ipimask)) @@ -195,7 +195,7 @@ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data, if (!chip->ipi_send_single && !chip->ipi_send_mask) return -EINVAL; - if (cpu > nr_cpu_ids) + if (cpu >= nr_cpu_ids) return -EINVAL; if (dest) { diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c new file mode 100644 index 0000000000000000000000000000000000000000..24caabf1a0f78e809d4d8416d1a408b256b52153 --- /dev/null +++ b/kernel/irq/irq_sim.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2017 Bartosz Golaszewski + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +struct irq_sim_devres { + struct irq_sim *sim; +}; + +static void irq_sim_irqmask(struct irq_data *data) +{ + struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data); + + irq_ctx->enabled = false; +} + +static void irq_sim_irqunmask(struct irq_data *data) +{ + struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data); + + irq_ctx->enabled = true; +} + +static struct irq_chip irq_sim_irqchip = { + .name = "irq_sim", + .irq_mask = irq_sim_irqmask, + .irq_unmask = irq_sim_irqunmask, +}; + +static void irq_sim_handle_irq(struct irq_work *work) +{ + struct irq_sim_work_ctx *work_ctx; + + work_ctx = container_of(work, struct irq_sim_work_ctx, work); + handle_simple_irq(irq_to_desc(work_ctx->irq)); +} + +/** + * irq_sim_init - Initialize the interrupt simulator: allocate a range of + * dummy interrupts. + * + * @sim: The interrupt simulator object to initialize. + * @num_irqs: Number of interrupts to allocate + * + * Returns 0 on success and a negative error number on failure. + */ +int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs) +{ + int i; + + sim->irqs = kmalloc_array(num_irqs, sizeof(*sim->irqs), GFP_KERNEL); + if (!sim->irqs) + return -ENOMEM; + + sim->irq_base = irq_alloc_descs(-1, 0, num_irqs, 0); + if (sim->irq_base < 0) { + kfree(sim->irqs); + return sim->irq_base; + } + + for (i = 0; i < num_irqs; i++) { + sim->irqs[i].irqnum = sim->irq_base + i; + sim->irqs[i].enabled = false; + irq_set_chip(sim->irq_base + i, &irq_sim_irqchip); + irq_set_chip_data(sim->irq_base + i, &sim->irqs[i]); + irq_set_handler(sim->irq_base + i, &handle_simple_irq); + irq_modify_status(sim->irq_base + i, + IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); + } + + init_irq_work(&sim->work_ctx.work, irq_sim_handle_irq); + sim->irq_count = num_irqs; + + return 0; +} +EXPORT_SYMBOL_GPL(irq_sim_init); + +/** + * irq_sim_fini - Deinitialize the interrupt simulator: free the interrupt + * descriptors and allocated memory. + * + * @sim: The interrupt simulator to tear down. + */ +void irq_sim_fini(struct irq_sim *sim) +{ + irq_work_sync(&sim->work_ctx.work); + irq_free_descs(sim->irq_base, sim->irq_count); + kfree(sim->irqs); +} +EXPORT_SYMBOL_GPL(irq_sim_fini); + +static void devm_irq_sim_release(struct device *dev, void *res) +{ + struct irq_sim_devres *this = res; + + irq_sim_fini(this->sim); +} + +/** + * irq_sim_init - Initialize the interrupt simulator for a managed device. + * + * @dev: Device to initialize the simulator object for. + * @sim: The interrupt simulator object to initialize. + * @num_irqs: Number of interrupts to allocate + * + * Returns 0 on success and a negative error number on failure. + */ +int devm_irq_sim_init(struct device *dev, struct irq_sim *sim, + unsigned int num_irqs) +{ + struct irq_sim_devres *dr; + int rv; + + dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + rv = irq_sim_init(sim, num_irqs); + if (rv) { + devres_free(dr); + return rv; + } + + dr->sim = sim; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_irq_sim_init); + +/** + * irq_sim_fire - Enqueue an interrupt. + * + * @sim: The interrupt simulator object. + * @offset: Offset of the simulated interrupt which should be fired. + */ +void irq_sim_fire(struct irq_sim *sim, unsigned int offset) +{ + if (sim->irqs[offset].enabled) { + sim->work_ctx.irq = irq_sim_irqnum(sim, offset); + irq_work_queue(&sim->work_ctx.work); + } +} +EXPORT_SYMBOL_GPL(irq_sim_fire); + +/** + * irq_sim_irqnum - Get the allocated number of a dummy interrupt. + * + * @sim: The interrupt simulator object. + * @offset: Offset of the simulated interrupt for which to retrieve + * the number. + */ +int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset) +{ + return sim->irqs[offset].irqnum; +} +EXPORT_SYMBOL_GPL(irq_sim_irqnum); diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 73be2b3909bd40a373e9c5237575faed5812945f..82afb7ed369f0df70bcd5d6fdc110addda5b842f 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -421,10 +421,8 @@ static void free_desc(unsigned int irq) * The sysfs entry must be serialized against a concurrent * irq_sysfs_init() as well. */ - mutex_lock(&sparse_irq_lock); kobject_del(&desc->kobj); delete_irq_desc(irq); - mutex_unlock(&sparse_irq_lock); /* * We free the descriptor, masks and stat fields via RCU. That @@ -462,20 +460,15 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node, desc = alloc_desc(start + i, node, flags, mask, owner); if (!desc) goto err; - mutex_lock(&sparse_irq_lock); irq_insert_desc(start + i, desc); irq_sysfs_add(start + i, desc); - mutex_unlock(&sparse_irq_lock); } + bitmap_set(allocated_irqs, start, cnt); return start; err: for (i--; i >= 0; i--) free_desc(start + i); - - mutex_lock(&sparse_irq_lock); - bitmap_clear(allocated_irqs, start, cnt); - mutex_unlock(&sparse_irq_lock); return -ENOMEM; } @@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node, desc->owner = owner; } + bitmap_set(allocated_irqs, start, cnt); return start; } @@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, unsigned int cnt) if (from >= nr_irqs || (from + cnt) > nr_irqs) return; + mutex_lock(&sparse_irq_lock); for (i = 0; i < cnt; i++) free_desc(from + i); - mutex_lock(&sparse_irq_lock); bitmap_clear(allocated_irqs, from, cnt); mutex_unlock(&sparse_irq_lock); } @@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, from, cnt, 0); ret = -EEXIST; if (irq >=0 && start != irq) - goto err; + goto unlock; if (start + cnt > nr_irqs) { ret = irq_expand_nr_irqs(start + cnt); if (ret) - goto err; + goto unlock; } - - bitmap_set(allocated_irqs, start, cnt); - mutex_unlock(&sparse_irq_lock); - return alloc_descs(start, cnt, node, affinity, owner); - -err: + ret = alloc_descs(start, cnt, node, affinity, owner); +unlock: mutex_unlock(&sparse_irq_lock); return ret; } diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index f1f251479aa6009eddb81041f69e825ebb8d28b7..ac4644e92b499949b1a11652ddde3e3bccba8072 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -41,6 +41,9 @@ static inline void debugfs_add_domain_dir(struct irq_domain *d) { } static inline void debugfs_remove_domain_dir(struct irq_domain *d) { } #endif +const struct fwnode_operations irqchip_fwnode_ops; +EXPORT_SYMBOL_GPL(irqchip_fwnode_ops); + /** * irq_domain_alloc_fwnode - Allocate a fwnode_handle suitable for * identifying an irq domain @@ -86,7 +89,7 @@ struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id, fwid->type = type; fwid->name = n; fwid->data = data; - fwid->fwnode.type = FWNODE_IRQCHIP; + fwid->fwnode.ops = &irqchip_fwnode_ops; return &fwid->fwnode; } EXPORT_SYMBOL_GPL(__irq_domain_alloc_fwnode); @@ -193,10 +196,8 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, } if (!domain->name) { - if (fwnode) { - pr_err("Invalid fwnode type (%d) for irqdomain\n", - fwnode->type); - } + if (fwnode) + pr_err("Invalid fwnode type for irqdomain\n"); domain->name = kasprintf(GFP_KERNEL, "unknown-%d", atomic_inc_return(&unknown_domains)); if (!domain->name) { @@ -455,6 +456,31 @@ void irq_set_default_host(struct irq_domain *domain) } EXPORT_SYMBOL_GPL(irq_set_default_host); +static void irq_domain_clear_mapping(struct irq_domain *domain, + irq_hw_number_t hwirq) +{ + if (hwirq < domain->revmap_size) { + domain->linear_revmap[hwirq] = 0; + } else { + mutex_lock(&revmap_trees_mutex); + radix_tree_delete(&domain->revmap_tree, hwirq); + mutex_unlock(&revmap_trees_mutex); + } +} + +static void irq_domain_set_mapping(struct irq_domain *domain, + irq_hw_number_t hwirq, + struct irq_data *irq_data) +{ + if (hwirq < domain->revmap_size) { + domain->linear_revmap[hwirq] = irq_data->irq; + } else { + mutex_lock(&revmap_trees_mutex); + radix_tree_insert(&domain->revmap_tree, hwirq, irq_data); + mutex_unlock(&revmap_trees_mutex); + } +} + void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) { struct irq_data *irq_data = irq_get_irq_data(irq); @@ -483,13 +509,7 @@ void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) domain->mapcount--; /* Clear reverse map for this hwirq */ - if (hwirq < domain->revmap_size) { - domain->linear_revmap[hwirq] = 0; - } else { - mutex_lock(&revmap_trees_mutex); - radix_tree_delete(&domain->revmap_tree, hwirq); - mutex_unlock(&revmap_trees_mutex); - } + irq_domain_clear_mapping(domain, hwirq); } int irq_domain_associate(struct irq_domain *domain, unsigned int virq, @@ -533,13 +553,7 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq, } domain->mapcount++; - if (hwirq < domain->revmap_size) { - domain->linear_revmap[hwirq] = virq; - } else { - mutex_lock(&revmap_trees_mutex); - radix_tree_insert(&domain->revmap_tree, hwirq, irq_data); - mutex_unlock(&revmap_trees_mutex); - } + irq_domain_set_mapping(domain, hwirq, irq_data); mutex_unlock(&irq_domain_mutex); irq_clear_status_flags(virq, IRQ_NOREQUEST); @@ -931,7 +945,7 @@ static int virq_debug_show(struct seq_file *m, void *private) struct irq_desc *desc; struct irq_domain *domain; struct radix_tree_iter iter; - void **slot; + void __rcu **slot; int i; seq_printf(m, " %-16s %-6s %-10s %-10s %s\n", @@ -1138,16 +1152,9 @@ static void irq_domain_insert_irq(int virq) for (data = irq_get_irq_data(virq); data; data = data->parent_data) { struct irq_domain *domain = data->domain; - irq_hw_number_t hwirq = data->hwirq; domain->mapcount++; - if (hwirq < domain->revmap_size) { - domain->linear_revmap[hwirq] = virq; - } else { - mutex_lock(&revmap_trees_mutex); - radix_tree_insert(&domain->revmap_tree, hwirq, data); - mutex_unlock(&revmap_trees_mutex); - } + irq_domain_set_mapping(domain, data->hwirq, data); /* If not already assigned, give the domain the chip's name */ if (!domain->name && data->chip) @@ -1171,13 +1178,7 @@ static void irq_domain_remove_irq(int virq) irq_hw_number_t hwirq = data->hwirq; domain->mapcount--; - if (hwirq < domain->revmap_size) { - domain->linear_revmap[hwirq] = 0; - } else { - mutex_lock(&revmap_trees_mutex); - radix_tree_delete(&domain->revmap_tree, hwirq); - mutex_unlock(&revmap_trees_mutex); - } + irq_domain_clear_mapping(domain, hwirq); } } @@ -1362,7 +1363,8 @@ static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain, unsigned int irq_base, unsigned int nr_irqs) { - domain->ops->free(domain, irq_base, nr_irqs); + if (domain->ops->free) + domain->ops->free(domain, irq_base, nr_irqs); } int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, @@ -1448,6 +1450,175 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, return ret; } +/* The irq_data was moved, fix the revmap to refer to the new location */ +static void irq_domain_fix_revmap(struct irq_data *d) +{ + void __rcu **slot; + + if (d->hwirq < d->domain->revmap_size) + return; /* Not using radix tree. */ + + /* Fix up the revmap. */ + mutex_lock(&revmap_trees_mutex); + slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq); + if (slot) + radix_tree_replace_slot(&d->domain->revmap_tree, slot, d); + mutex_unlock(&revmap_trees_mutex); +} + +/** + * irq_domain_push_irq() - Push a domain in to the top of a hierarchy. + * @domain: Domain to push. + * @virq: Irq to push the domain in to. + * @arg: Passed to the irq_domain_ops alloc() function. + * + * For an already existing irqdomain hierarchy, as might be obtained + * via a call to pci_enable_msix(), add an additional domain to the + * head of the processing chain. Must be called before request_irq() + * has been called. + */ +int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg) +{ + struct irq_data *child_irq_data; + struct irq_data *root_irq_data = irq_get_irq_data(virq); + struct irq_desc *desc; + int rv = 0; + + /* + * Check that no action has been set, which indicates the virq + * is in a state where this function doesn't have to deal with + * races between interrupt handling and maintaining the + * hierarchy. This will catch gross misuse. Attempting to + * make the check race free would require holding locks across + * calls to struct irq_domain_ops->alloc(), which could lead + * to deadlock, so we just do a simple check before starting. + */ + desc = irq_to_desc(virq); + if (!desc) + return -EINVAL; + if (WARN_ON(desc->action)) + return -EBUSY; + + if (domain == NULL) + return -EINVAL; + + if (WARN_ON(!irq_domain_is_hierarchy(domain))) + return -EINVAL; + + if (!root_irq_data) + return -EINVAL; + + if (domain->parent != root_irq_data->domain) + return -EINVAL; + + child_irq_data = kzalloc_node(sizeof(*child_irq_data), GFP_KERNEL, + irq_data_get_node(root_irq_data)); + if (!child_irq_data) + return -ENOMEM; + + mutex_lock(&irq_domain_mutex); + + /* Copy the original irq_data. */ + *child_irq_data = *root_irq_data; + + /* + * Overwrite the root_irq_data, which is embedded in struct + * irq_desc, with values for this domain. + */ + root_irq_data->parent_data = child_irq_data; + root_irq_data->domain = domain; + root_irq_data->mask = 0; + root_irq_data->hwirq = 0; + root_irq_data->chip = NULL; + root_irq_data->chip_data = NULL; + + /* May (probably does) set hwirq, chip, etc. */ + rv = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); + if (rv) { + /* Restore the original irq_data. */ + *root_irq_data = *child_irq_data; + goto error; + } + + irq_domain_fix_revmap(child_irq_data); + irq_domain_set_mapping(domain, root_irq_data->hwirq, root_irq_data); + +error: + mutex_unlock(&irq_domain_mutex); + + return rv; +} +EXPORT_SYMBOL_GPL(irq_domain_push_irq); + +/** + * irq_domain_pop_irq() - Remove a domain from the top of a hierarchy. + * @domain: Domain to remove. + * @virq: Irq to remove the domain from. + * + * Undo the effects of a call to irq_domain_push_irq(). Must be + * called either before request_irq() or after free_irq(). + */ +int irq_domain_pop_irq(struct irq_domain *domain, int virq) +{ + struct irq_data *root_irq_data = irq_get_irq_data(virq); + struct irq_data *child_irq_data; + struct irq_data *tmp_irq_data; + struct irq_desc *desc; + + /* + * Check that no action is set, which indicates the virq is in + * a state where this function doesn't have to deal with races + * between interrupt handling and maintaining the hierarchy. + * This will catch gross misuse. Attempting to make the check + * race free would require holding locks across calls to + * struct irq_domain_ops->free(), which could lead to + * deadlock, so we just do a simple check before starting. + */ + desc = irq_to_desc(virq); + if (!desc) + return -EINVAL; + if (WARN_ON(desc->action)) + return -EBUSY; + + if (domain == NULL) + return -EINVAL; + + if (!root_irq_data) + return -EINVAL; + + tmp_irq_data = irq_domain_get_irq_data(domain, virq); + + /* We can only "pop" if this domain is at the top of the list */ + if (WARN_ON(root_irq_data != tmp_irq_data)) + return -EINVAL; + + if (WARN_ON(root_irq_data->domain != domain)) + return -EINVAL; + + child_irq_data = root_irq_data->parent_data; + if (WARN_ON(!child_irq_data)) + return -EINVAL; + + mutex_lock(&irq_domain_mutex); + + root_irq_data->parent_data = NULL; + + irq_domain_clear_mapping(domain, root_irq_data->hwirq); + irq_domain_free_irqs_hierarchy(domain, virq, 1); + + /* Restore the original irq_data. */ + *root_irq_data = *child_irq_data; + + irq_domain_fix_revmap(root_irq_data); + + mutex_unlock(&irq_domain_mutex); + + kfree(child_irq_data); + + return 0; +} +EXPORT_SYMBOL_GPL(irq_domain_pop_irq); + /** * irq_domain_free_irqs - Free IRQ number and associated data structures * @virq: base IRQ number diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 1d1a5b945ab428008ebaa8b31cd1f2a638f6aa97..d00132b5c325b389f6646de064527df64e2d873e 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -400,8 +400,18 @@ int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info) return -EINVAL; data = irq_desc_get_irq_data(desc); - chip = irq_data_get_irq_chip(data); - if (chip && chip->irq_set_vcpu_affinity) + do { + chip = irq_data_get_irq_chip(data); + if (chip && chip->irq_set_vcpu_affinity) + break; +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY + data = data->parent_data; +#else + data = NULL; +#endif + } while (data); + + if (data) ret = chip->irq_set_vcpu_affinity(data, vcpu_info); irq_put_desc_unlock(desc, flags); @@ -1633,6 +1643,10 @@ const void *free_irq(unsigned int irq, void *dev_id) #endif action = __free_irq(irq, dev_id); + + if (!action) + return NULL; + devname = action->name; kfree(action); return devname; diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 48eadf416c24b3c86f540ab94c6e519557b9b036..3fa4bd59f569865703bb9ab189d24401e99bbf38 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -315,11 +315,12 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, ops->set_desc(arg, desc); /* Assumes the domain mutex is held! */ - ret = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); + ret = irq_domain_alloc_irqs_hierarchy(domain, desc->irq, 1, + arg); if (ret) break; - irq_set_msi_desc_off(virq, 0, desc); + irq_set_msi_desc_off(desc->irq, 0, desc); } if (ret) { diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 7f9642a1e2670154002b42e62a77913dcf6366f2..6376b4a598d35247b0c0f95d645e5f319f1d744c 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -61,12 +61,12 @@ static int show_irq_affinity(int type, struct seq_file *m) case EFFECTIVE: case EFFECTIVE_LIST: #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK - mask = desc->irq_common_data.effective_affinity; + mask = irq_data_get_effective_affinity_mask(&desc->irq_data); break; -#else - return -EINVAL; #endif - }; + default: + return -EINVAL; + } switch (type) { case AFFINITY_LIST: diff --git a/kernel/jump_label.c b/kernel/jump_label.c index d11c506a6ac3db63e9475ee45d3c4bd34aa47a73..0bf2e8f5244ae7ffbf7bc7660cca27cd79bb3e50 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c @@ -79,29 +79,7 @@ int static_key_count(struct static_key *key) } EXPORT_SYMBOL_GPL(static_key_count); -void static_key_enable(struct static_key *key) -{ - int count = static_key_count(key); - - WARN_ON_ONCE(count < 0 || count > 1); - - if (!count) - static_key_slow_inc(key); -} -EXPORT_SYMBOL_GPL(static_key_enable); - -void static_key_disable(struct static_key *key) -{ - int count = static_key_count(key); - - WARN_ON_ONCE(count < 0 || count > 1); - - if (count) - static_key_slow_dec(key); -} -EXPORT_SYMBOL_GPL(static_key_disable); - -void static_key_slow_inc(struct static_key *key) +static void static_key_slow_inc_cpuslocked(struct static_key *key) { int v, v1; @@ -125,24 +103,87 @@ void static_key_slow_inc(struct static_key *key) return; } - cpus_read_lock(); jump_label_lock(); if (atomic_read(&key->enabled) == 0) { atomic_set(&key->enabled, -1); jump_label_update(key); - atomic_set(&key->enabled, 1); + /* + * Ensure that if the above cmpxchg loop observes our positive + * value, it must also observe all the text changes. + */ + atomic_set_release(&key->enabled, 1); } else { atomic_inc(&key->enabled); } jump_label_unlock(); +} + +void static_key_slow_inc(struct static_key *key) +{ + cpus_read_lock(); + static_key_slow_inc_cpuslocked(key); cpus_read_unlock(); } EXPORT_SYMBOL_GPL(static_key_slow_inc); -static void __static_key_slow_dec(struct static_key *key, - unsigned long rate_limit, struct delayed_work *work) +void static_key_enable_cpuslocked(struct static_key *key) +{ + STATIC_KEY_CHECK_USE(); + + if (atomic_read(&key->enabled) > 0) { + WARN_ON_ONCE(atomic_read(&key->enabled) != 1); + return; + } + + jump_label_lock(); + if (atomic_read(&key->enabled) == 0) { + atomic_set(&key->enabled, -1); + jump_label_update(key); + /* + * See static_key_slow_inc(). + */ + atomic_set_release(&key->enabled, 1); + } + jump_label_unlock(); +} +EXPORT_SYMBOL_GPL(static_key_enable_cpuslocked); + +void static_key_enable(struct static_key *key) +{ + cpus_read_lock(); + static_key_enable_cpuslocked(key); + cpus_read_unlock(); +} +EXPORT_SYMBOL_GPL(static_key_enable); + +void static_key_disable_cpuslocked(struct static_key *key) +{ + STATIC_KEY_CHECK_USE(); + + if (atomic_read(&key->enabled) != 1) { + WARN_ON_ONCE(atomic_read(&key->enabled) != 0); + return; + } + + jump_label_lock(); + if (atomic_cmpxchg(&key->enabled, 1, 0)) + jump_label_update(key); + jump_label_unlock(); +} +EXPORT_SYMBOL_GPL(static_key_disable_cpuslocked); + +void static_key_disable(struct static_key *key) { cpus_read_lock(); + static_key_disable_cpuslocked(key); + cpus_read_unlock(); +} +EXPORT_SYMBOL_GPL(static_key_disable); + +static void static_key_slow_dec_cpuslocked(struct static_key *key, + unsigned long rate_limit, + struct delayed_work *work) +{ /* * The negative count check is valid even when a negative * key->enabled is in use by static_key_slow_inc(); a @@ -153,7 +194,6 @@ static void __static_key_slow_dec(struct static_key *key, if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) { WARN(atomic_read(&key->enabled) < 0, "jump label: negative count!\n"); - cpus_read_unlock(); return; } @@ -164,6 +204,14 @@ static void __static_key_slow_dec(struct static_key *key, jump_label_update(key); } jump_label_unlock(); +} + +static void __static_key_slow_dec(struct static_key *key, + unsigned long rate_limit, + struct delayed_work *work) +{ + cpus_read_lock(); + static_key_slow_dec_cpuslocked(key, rate_limit, work); cpus_read_unlock(); } diff --git a/kernel/kcmp.c b/kernel/kcmp.c index ea34ed8bb9529c7b7a2a38b0a4e050995b4ba97e..055bb2962a0b656269b1220d7cb4ead7978301e2 100644 --- a/kernel/kcmp.c +++ b/kernel/kcmp.c @@ -131,7 +131,7 @@ static int kcmp_epoll_target(struct task_struct *task1, if (filp_epoll) { filp_tgt = get_epoll_tfile_raw_ptr(filp_epoll, slot.tfd, slot.toff); fput(filp_epoll); - } else + } if (IS_ERR(filp_tgt)) return PTR_ERR(filp_tgt); diff --git a/kernel/kcov.c b/kernel/kcov.c index cd771993f96f4a7ff23592f1abaea22c71444fda..3f693a0f6f3edc9e563b681ad47bf168e73d0dca 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -270,6 +270,7 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) static const struct file_operations kcov_fops = { .open = kcov_open, .unlocked_ioctl = kcov_ioctl, + .compat_ioctl = kcov_ioctl, .mmap = kcov_mmap, .release = kcov_close, }; diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 1ae7c41c33c19c54e4b08d33c0c59da78244efba..20fef1a38602d9d0ed6fdb5d359d5604fbafc3dd 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -301,7 +301,7 @@ static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order) { struct page *pages; - pages = alloc_pages(gfp_mask, order); + pages = alloc_pages(gfp_mask & ~__GFP_ZERO, order); if (pages) { unsigned int count, i; @@ -310,6 +310,13 @@ static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order) count = 1 << order; for (i = 0; i < count; i++) SetPageReserved(pages + i); + + arch_kexec_post_alloc_pages(page_address(pages), count, + gfp_mask); + + if (gfp_mask & __GFP_ZERO) + for (i = 0; i < count; i++) + clear_highpage(pages + i); } return pages; @@ -321,6 +328,9 @@ static void kimage_free_pages(struct page *page) order = page_private(page); count = 1 << order; + + arch_kexec_pre_free_pages(page_address(page), count); + for (i = 0; i < count; i++) ClearPageReserved(page + i); __free_pages(page, order); diff --git a/kernel/kmod.c b/kernel/kmod.c index 6d016c5d97c8390f561e6a9456a4e0c1ca59bffe..bc6addd9152b4db58c57757f1fe0a2911a16e459 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -1,23 +1,6 @@ /* - kmod, the new module loader (replaces kerneld) - Kirk Petersen - - Reorganized not to be a daemon by Adam Richter, with guidance - from Greg Zornetzer. - - Modified to avoid chroot and file sharing problems. - Mikael Pettersson - - Limit the concurrent number of kmod modprobes to catch loops from - "modprobe needs a service that is in a module". - Keith Owens December 1999 - - Unblock all signals when we exec a usermode process. - Shuu Yamaguchi December 2000 - - call_usermodehelper wait flag, and remove exec_usermodehelper. - Rusty Russell Jan 2003 -*/ + * kmod - the kernel module loader + */ #include #include #include @@ -45,15 +28,6 @@ #include -#define CAP_BSET (void *)1 -#define CAP_PI (void *)2 - -static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; -static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; -static DEFINE_SPINLOCK(umh_sysctl_lock); -static DECLARE_RWSEM(umhelper_sem); - -#ifdef CONFIG_MODULES /* * Assuming: * @@ -70,6 +44,18 @@ static DECLARE_RWSEM(umhelper_sem); static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT); static DECLARE_WAIT_QUEUE_HEAD(kmod_wq); +/* + * This is a restriction on having *all* MAX_KMOD_CONCURRENT threads + * running at the same time without returning. When this happens we + * believe you've somehow ended up with a recursive module dependency + * creating a loop. + * + * We have no option but to fail. + * + * Userspace should proactively try to detect and prevent these. + */ +#define MAX_KMOD_ALL_BUSY_TIMEOUT 5 + /* modprobe_path is set via /proc/sys. */ @@ -167,8 +153,17 @@ int __request_module(bool wait, const char *fmt, ...) pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...", atomic_read(&kmod_concurrent_max), MAX_KMOD_CONCURRENT, module_name); - wait_event_interruptible(kmod_wq, - atomic_dec_if_positive(&kmod_concurrent_max) >= 0); + ret = wait_event_killable_timeout(kmod_wq, + atomic_dec_if_positive(&kmod_concurrent_max) >= 0, + MAX_KMOD_ALL_BUSY_TIMEOUT * HZ); + if (!ret) { + pr_warn_ratelimited("request_module: modprobe %s cannot be processed, kmod busy with %d threads for more than %d seconds now", + module_name, MAX_KMOD_CONCURRENT, MAX_KMOD_ALL_BUSY_TIMEOUT); + return -ETIME; + } else if (ret == -ERESTARTSYS) { + pr_warn_ratelimited("request_module: sigkill sent for modprobe %s, giving up", module_name); + return ret; + } } trace_module_request(module_name, wait, _RET_IP_); @@ -181,536 +176,3 @@ int __request_module(bool wait, const char *fmt, ...) return ret; } EXPORT_SYMBOL(__request_module); - -#endif /* CONFIG_MODULES */ - -static void call_usermodehelper_freeinfo(struct subprocess_info *info) -{ - if (info->cleanup) - (*info->cleanup)(info); - kfree(info); -} - -static void umh_complete(struct subprocess_info *sub_info) -{ - struct completion *comp = xchg(&sub_info->complete, NULL); - /* - * See call_usermodehelper_exec(). If xchg() returns NULL - * we own sub_info, the UMH_KILLABLE caller has gone away - * or the caller used UMH_NO_WAIT. - */ - if (comp) - complete(comp); - else - call_usermodehelper_freeinfo(sub_info); -} - -/* - * This is the task which runs the usermode application - */ -static int call_usermodehelper_exec_async(void *data) -{ - struct subprocess_info *sub_info = data; - struct cred *new; - int retval; - - spin_lock_irq(¤t->sighand->siglock); - flush_signal_handlers(current, 1); - spin_unlock_irq(¤t->sighand->siglock); - - /* - * Our parent (unbound workqueue) runs with elevated scheduling - * priority. Avoid propagating that into the userspace child. - */ - set_user_nice(current, 0); - - retval = -ENOMEM; - new = prepare_kernel_cred(current); - if (!new) - goto out; - - spin_lock(&umh_sysctl_lock); - new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset); - new->cap_inheritable = cap_intersect(usermodehelper_inheritable, - new->cap_inheritable); - spin_unlock(&umh_sysctl_lock); - - if (sub_info->init) { - retval = sub_info->init(sub_info, new); - if (retval) { - abort_creds(new); - goto out; - } - } - - commit_creds(new); - - retval = do_execve(getname_kernel(sub_info->path), - (const char __user *const __user *)sub_info->argv, - (const char __user *const __user *)sub_info->envp); -out: - sub_info->retval = retval; - /* - * call_usermodehelper_exec_sync() will call umh_complete - * if UHM_WAIT_PROC. - */ - if (!(sub_info->wait & UMH_WAIT_PROC)) - umh_complete(sub_info); - if (!retval) - return 0; - do_exit(0); -} - -/* Handles UMH_WAIT_PROC. */ -static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info) -{ - pid_t pid; - - /* If SIGCLD is ignored sys_wait4 won't populate the status. */ - kernel_sigaction(SIGCHLD, SIG_DFL); - pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD); - if (pid < 0) { - sub_info->retval = pid; - } else { - int ret = -ECHILD; - /* - * Normally it is bogus to call wait4() from in-kernel because - * wait4() wants to write the exit code to a userspace address. - * But call_usermodehelper_exec_sync() always runs as kernel - * thread (workqueue) and put_user() to a kernel address works - * OK for kernel threads, due to their having an mm_segment_t - * which spans the entire address space. - * - * Thus the __user pointer cast is valid here. - */ - sys_wait4(pid, (int __user *)&ret, 0, NULL); - - /* - * If ret is 0, either call_usermodehelper_exec_async failed and - * the real error code is already in sub_info->retval or - * sub_info->retval is 0 anyway, so don't mess with it then. - */ - if (ret) - sub_info->retval = ret; - } - - /* Restore default kernel sig handler */ - kernel_sigaction(SIGCHLD, SIG_IGN); - - umh_complete(sub_info); -} - -/* - * We need to create the usermodehelper kernel thread from a task that is affine - * to an optimized set of CPUs (or nohz housekeeping ones) such that they - * inherit a widest affinity irrespective of call_usermodehelper() callers with - * possibly reduced affinity (eg: per-cpu workqueues). We don't want - * usermodehelper targets to contend a busy CPU. - * - * Unbound workqueues provide such wide affinity and allow to block on - * UMH_WAIT_PROC requests without blocking pending request (up to some limit). - * - * Besides, workqueues provide the privilege level that caller might not have - * to perform the usermodehelper request. - * - */ -static void call_usermodehelper_exec_work(struct work_struct *work) -{ - struct subprocess_info *sub_info = - container_of(work, struct subprocess_info, work); - - if (sub_info->wait & UMH_WAIT_PROC) { - call_usermodehelper_exec_sync(sub_info); - } else { - pid_t pid; - /* - * Use CLONE_PARENT to reparent it to kthreadd; we do not - * want to pollute current->children, and we need a parent - * that always ignores SIGCHLD to ensure auto-reaping. - */ - pid = kernel_thread(call_usermodehelper_exec_async, sub_info, - CLONE_PARENT | SIGCHLD); - if (pid < 0) { - sub_info->retval = pid; - umh_complete(sub_info); - } - } -} - -/* - * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY - * (used for preventing user land processes from being created after the user - * land has been frozen during a system-wide hibernation or suspend operation). - * Should always be manipulated under umhelper_sem acquired for write. - */ -static enum umh_disable_depth usermodehelper_disabled = UMH_DISABLED; - -/* Number of helpers running */ -static atomic_t running_helpers = ATOMIC_INIT(0); - -/* - * Wait queue head used by usermodehelper_disable() to wait for all running - * helpers to finish. - */ -static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); - -/* - * Used by usermodehelper_read_lock_wait() to wait for usermodehelper_disabled - * to become 'false'. - */ -static DECLARE_WAIT_QUEUE_HEAD(usermodehelper_disabled_waitq); - -/* - * Time to wait for running_helpers to become zero before the setting of - * usermodehelper_disabled in usermodehelper_disable() fails - */ -#define RUNNING_HELPERS_TIMEOUT (5 * HZ) - -int usermodehelper_read_trylock(void) -{ - DEFINE_WAIT(wait); - int ret = 0; - - down_read(&umhelper_sem); - for (;;) { - prepare_to_wait(&usermodehelper_disabled_waitq, &wait, - TASK_INTERRUPTIBLE); - if (!usermodehelper_disabled) - break; - - if (usermodehelper_disabled == UMH_DISABLED) - ret = -EAGAIN; - - up_read(&umhelper_sem); - - if (ret) - break; - - schedule(); - try_to_freeze(); - - down_read(&umhelper_sem); - } - finish_wait(&usermodehelper_disabled_waitq, &wait); - return ret; -} -EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); - -long usermodehelper_read_lock_wait(long timeout) -{ - DEFINE_WAIT(wait); - - if (timeout < 0) - return -EINVAL; - - down_read(&umhelper_sem); - for (;;) { - prepare_to_wait(&usermodehelper_disabled_waitq, &wait, - TASK_UNINTERRUPTIBLE); - if (!usermodehelper_disabled) - break; - - up_read(&umhelper_sem); - - timeout = schedule_timeout(timeout); - if (!timeout) - break; - - down_read(&umhelper_sem); - } - finish_wait(&usermodehelper_disabled_waitq, &wait); - return timeout; -} -EXPORT_SYMBOL_GPL(usermodehelper_read_lock_wait); - -void usermodehelper_read_unlock(void) -{ - up_read(&umhelper_sem); -} -EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); - -/** - * __usermodehelper_set_disable_depth - Modify usermodehelper_disabled. - * @depth: New value to assign to usermodehelper_disabled. - * - * Change the value of usermodehelper_disabled (under umhelper_sem locked for - * writing) and wakeup tasks waiting for it to change. - */ -void __usermodehelper_set_disable_depth(enum umh_disable_depth depth) -{ - down_write(&umhelper_sem); - usermodehelper_disabled = depth; - wake_up(&usermodehelper_disabled_waitq); - up_write(&umhelper_sem); -} - -/** - * __usermodehelper_disable - Prevent new helpers from being started. - * @depth: New value to assign to usermodehelper_disabled. - * - * Set usermodehelper_disabled to @depth and wait for running helpers to exit. - */ -int __usermodehelper_disable(enum umh_disable_depth depth) -{ - long retval; - - if (!depth) - return -EINVAL; - - down_write(&umhelper_sem); - usermodehelper_disabled = depth; - up_write(&umhelper_sem); - - /* - * From now on call_usermodehelper_exec() won't start any new - * helpers, so it is sufficient if running_helpers turns out to - * be zero at one point (it may be increased later, but that - * doesn't matter). - */ - retval = wait_event_timeout(running_helpers_waitq, - atomic_read(&running_helpers) == 0, - RUNNING_HELPERS_TIMEOUT); - if (retval) - return 0; - - __usermodehelper_set_disable_depth(UMH_ENABLED); - return -EAGAIN; -} - -static void helper_lock(void) -{ - atomic_inc(&running_helpers); - smp_mb__after_atomic(); -} - -static void helper_unlock(void) -{ - if (atomic_dec_and_test(&running_helpers)) - wake_up(&running_helpers_waitq); -} - -/** - * call_usermodehelper_setup - prepare to call a usermode helper - * @path: path to usermode executable - * @argv: arg vector for process - * @envp: environment for process - * @gfp_mask: gfp mask for memory allocation - * @cleanup: a cleanup function - * @init: an init function - * @data: arbitrary context sensitive data - * - * Returns either %NULL on allocation failure, or a subprocess_info - * structure. This should be passed to call_usermodehelper_exec to - * exec the process and free the structure. - * - * The init function is used to customize the helper process prior to - * exec. A non-zero return code causes the process to error out, exit, - * and return the failure to the calling process - * - * The cleanup function is just before ethe subprocess_info is about to - * be freed. This can be used for freeing the argv and envp. The - * Function must be runnable in either a process context or the - * context in which call_usermodehelper_exec is called. - */ -struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv, - char **envp, gfp_t gfp_mask, - int (*init)(struct subprocess_info *info, struct cred *new), - void (*cleanup)(struct subprocess_info *info), - void *data) -{ - struct subprocess_info *sub_info; - sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask); - if (!sub_info) - goto out; - - INIT_WORK(&sub_info->work, call_usermodehelper_exec_work); - -#ifdef CONFIG_STATIC_USERMODEHELPER - sub_info->path = CONFIG_STATIC_USERMODEHELPER_PATH; -#else - sub_info->path = path; -#endif - sub_info->argv = argv; - sub_info->envp = envp; - - sub_info->cleanup = cleanup; - sub_info->init = init; - sub_info->data = data; - out: - return sub_info; -} -EXPORT_SYMBOL(call_usermodehelper_setup); - -/** - * call_usermodehelper_exec - start a usermode application - * @sub_info: information about the subprocessa - * @wait: wait for the application to finish and return status. - * when UMH_NO_WAIT don't wait at all, but you get no useful error back - * when the program couldn't be exec'ed. This makes it safe to call - * from interrupt context. - * - * Runs a user-space application. The application is started - * asynchronously if wait is not set, and runs as a child of system workqueues. - * (ie. it runs with full root capabilities and optimized affinity). - */ -int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) -{ - DECLARE_COMPLETION_ONSTACK(done); - int retval = 0; - - if (!sub_info->path) { - call_usermodehelper_freeinfo(sub_info); - return -EINVAL; - } - helper_lock(); - if (usermodehelper_disabled) { - retval = -EBUSY; - goto out; - } - - /* - * If there is no binary for us to call, then just return and get out of - * here. This allows us to set STATIC_USERMODEHELPER_PATH to "" and - * disable all call_usermodehelper() calls. - */ - if (strlen(sub_info->path) == 0) - goto out; - - /* - * Set the completion pointer only if there is a waiter. - * This makes it possible to use umh_complete to free - * the data structure in case of UMH_NO_WAIT. - */ - sub_info->complete = (wait == UMH_NO_WAIT) ? NULL : &done; - sub_info->wait = wait; - - queue_work(system_unbound_wq, &sub_info->work); - if (wait == UMH_NO_WAIT) /* task has freed sub_info */ - goto unlock; - - if (wait & UMH_KILLABLE) { - retval = wait_for_completion_killable(&done); - if (!retval) - goto wait_done; - - /* umh_complete() will see NULL and free sub_info */ - if (xchg(&sub_info->complete, NULL)) - goto unlock; - /* fallthrough, umh_complete() was already called */ - } - - wait_for_completion(&done); -wait_done: - retval = sub_info->retval; -out: - call_usermodehelper_freeinfo(sub_info); -unlock: - helper_unlock(); - return retval; -} -EXPORT_SYMBOL(call_usermodehelper_exec); - -/** - * call_usermodehelper() - prepare and start a usermode application - * @path: path to usermode executable - * @argv: arg vector for process - * @envp: environment for process - * @wait: wait for the application to finish and return status. - * when UMH_NO_WAIT don't wait at all, but you get no useful error back - * when the program couldn't be exec'ed. This makes it safe to call - * from interrupt context. - * - * This function is the equivalent to use call_usermodehelper_setup() and - * call_usermodehelper_exec(). - */ -int call_usermodehelper(const char *path, char **argv, char **envp, int wait) -{ - struct subprocess_info *info; - gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; - - info = call_usermodehelper_setup(path, argv, envp, gfp_mask, - NULL, NULL, NULL); - if (info == NULL) - return -ENOMEM; - - return call_usermodehelper_exec(info, wait); -} -EXPORT_SYMBOL(call_usermodehelper); - -static int proc_cap_handler(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - struct ctl_table t; - unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; - kernel_cap_t new_cap; - int err, i; - - if (write && (!capable(CAP_SETPCAP) || - !capable(CAP_SYS_MODULE))) - return -EPERM; - - /* - * convert from the global kernel_cap_t to the ulong array to print to - * userspace if this is a read. - */ - spin_lock(&umh_sysctl_lock); - for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) { - if (table->data == CAP_BSET) - cap_array[i] = usermodehelper_bset.cap[i]; - else if (table->data == CAP_PI) - cap_array[i] = usermodehelper_inheritable.cap[i]; - else - BUG(); - } - spin_unlock(&umh_sysctl_lock); - - t = *table; - t.data = &cap_array; - - /* - * actually read or write and array of ulongs from userspace. Remember - * these are least significant 32 bits first - */ - err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos); - if (err < 0) - return err; - - /* - * convert from the sysctl array of ulongs to the kernel_cap_t - * internal representation - */ - for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) - new_cap.cap[i] = cap_array[i]; - - /* - * Drop everything not in the new_cap (but don't add things) - */ - spin_lock(&umh_sysctl_lock); - if (write) { - if (table->data == CAP_BSET) - usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); - if (table->data == CAP_PI) - usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); - } - spin_unlock(&umh_sysctl_lock); - - return 0; -} - -struct ctl_table usermodehelper_table[] = { - { - .procname = "bset", - .data = CAP_BSET, - .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), - .mode = 0600, - .proc_handler = proc_cap_handler, - }, - { - .procname = "inheritable", - .data = CAP_PI, - .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), - .mode = 0600, - .proc_handler = proc_cap_handler, - }, - { } -}; diff --git a/kernel/kthread.c b/kernel/kthread.c index 26db528c1d881bf371ea5b53b7ade0815c990bf1..1c19edf824272db47a48730478af5f3b582bbf67 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -637,6 +637,7 @@ int kthread_worker_fn(void *worker_ptr) schedule(); try_to_freeze(); + cond_resched(); goto repeat; } EXPORT_SYMBOL_GPL(kthread_worker_fn); diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 7d2499bec5fe662f6bf1c103e5fb33e1b5c15d70..44c8d0d17170af808ab0f11c4e556d49044a6c78 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -58,6 +58,10 @@ #define CREATE_TRACE_POINTS #include +#ifdef CONFIG_LOCKDEP_CROSSRELEASE +#include +#endif + #ifdef CONFIG_PROVE_LOCKING int prove_locking = 1; module_param(prove_locking, int, 0644); @@ -344,14 +348,12 @@ EXPORT_SYMBOL(lockdep_on); #if VERBOSE # define HARDIRQ_VERBOSE 1 # define SOFTIRQ_VERBOSE 1 -# define RECLAIM_VERBOSE 1 #else # define HARDIRQ_VERBOSE 0 # define SOFTIRQ_VERBOSE 0 -# define RECLAIM_VERBOSE 0 #endif -#if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE || RECLAIM_VERBOSE +#if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE /* * Quick filtering for interesting events: */ @@ -726,6 +728,18 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass) return is_static || static_obj(lock->key) ? NULL : ERR_PTR(-EINVAL); } +#ifdef CONFIG_LOCKDEP_CROSSRELEASE +static void cross_init(struct lockdep_map *lock, int cross); +static int cross_lock(struct lockdep_map *lock); +static int lock_acquire_crosslock(struct held_lock *hlock); +static int lock_release_crosslock(struct lockdep_map *lock); +#else +static inline void cross_init(struct lockdep_map *lock, int cross) {} +static inline int cross_lock(struct lockdep_map *lock) { return 0; } +static inline int lock_acquire_crosslock(struct held_lock *hlock) { return 2; } +static inline int lock_release_crosslock(struct lockdep_map *lock) { return 2; } +#endif + /* * Register a lock's class in the hash-table, if the class is not present * yet. Otherwise we look it up. We cache the result in the lock object @@ -1125,22 +1139,41 @@ print_circular_lock_scenario(struct held_lock *src, printk(KERN_CONT "\n\n"); } - printk(" Possible unsafe locking scenario:\n\n"); - printk(" CPU0 CPU1\n"); - printk(" ---- ----\n"); - printk(" lock("); - __print_lock_name(target); - printk(KERN_CONT ");\n"); - printk(" lock("); - __print_lock_name(parent); - printk(KERN_CONT ");\n"); - printk(" lock("); - __print_lock_name(target); - printk(KERN_CONT ");\n"); - printk(" lock("); - __print_lock_name(source); - printk(KERN_CONT ");\n"); - printk("\n *** DEADLOCK ***\n\n"); + if (cross_lock(tgt->instance)) { + printk(" Possible unsafe locking scenario by crosslock:\n\n"); + printk(" CPU0 CPU1\n"); + printk(" ---- ----\n"); + printk(" lock("); + __print_lock_name(parent); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(target); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(source); + printk(KERN_CONT ");\n"); + printk(" unlock("); + __print_lock_name(target); + printk(KERN_CONT ");\n"); + printk("\n *** DEADLOCK ***\n\n"); + } else { + printk(" Possible unsafe locking scenario:\n\n"); + printk(" CPU0 CPU1\n"); + printk(" ---- ----\n"); + printk(" lock("); + __print_lock_name(target); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(parent); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(target); + printk(KERN_CONT ");\n"); + printk(" lock("); + __print_lock_name(source); + printk(KERN_CONT ");\n"); + printk("\n *** DEADLOCK ***\n\n"); + } } /* @@ -1165,7 +1198,12 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth, pr_warn("%s/%d is trying to acquire lock:\n", curr->comm, task_pid_nr(curr)); print_lock(check_src); - pr_warn("\nbut task is already holding lock:\n"); + + if (cross_lock(check_tgt->instance)) + pr_warn("\nbut now in release context of a crosslock acquired at the following:\n"); + else + pr_warn("\nbut task is already holding lock:\n"); + print_lock(check_tgt); pr_warn("\nwhich lock already depends on the new lock.\n\n"); pr_warn("\nthe existing dependency chain (in reverse order) is:\n"); @@ -1183,7 +1221,8 @@ static inline int class_equal(struct lock_list *entry, void *data) static noinline int print_circular_bug(struct lock_list *this, struct lock_list *target, struct held_lock *check_src, - struct held_lock *check_tgt) + struct held_lock *check_tgt, + struct stack_trace *trace) { struct task_struct *curr = current; struct lock_list *parent; @@ -1193,7 +1232,9 @@ static noinline int print_circular_bug(struct lock_list *this, if (!debug_locks_off_graph_unlock() || debug_locks_silent) return 0; - if (!save_trace(&this->trace)) + if (cross_lock(check_tgt->instance)) + this->trace = *trace; + else if (!save_trace(&this->trace)) return 0; depth = get_lock_depth(target); @@ -1309,6 +1350,19 @@ check_noncircular(struct lock_list *root, struct lock_class *target, return result; } +static noinline int +check_redundant(struct lock_list *root, struct lock_class *target, + struct lock_list **target_entry) +{ + int result; + + debug_atomic_inc(nr_redundant_checks); + + result = __bfs_forwards(root, target, class_equal, target_entry); + + return result; +} + #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) /* * Forwards and backwards subgraph searching, for the purposes of @@ -1784,6 +1838,9 @@ check_deadlock(struct task_struct *curr, struct held_lock *next, if (nest) return 2; + if (cross_lock(prev->instance)) + continue; + return print_deadlock_bug(curr, prev, next); } return 1; @@ -1813,20 +1870,13 @@ check_deadlock(struct task_struct *curr, struct held_lock *next, */ static int check_prev_add(struct task_struct *curr, struct held_lock *prev, - struct held_lock *next, int distance, int *stack_saved) + struct held_lock *next, int distance, struct stack_trace *trace, + int (*save)(struct stack_trace *trace)) { struct lock_list *entry; int ret; struct lock_list this; struct lock_list *uninitialized_var(target_entry); - /* - * Static variable, serialized by the graph_lock(). - * - * We use this static variable to save the stack trace in case - * we call into this function multiple times due to encountering - * trylocks in the held lock stack. - */ - static struct stack_trace trace; /* * Prove that the new -> dependency would not @@ -1841,7 +1891,7 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, this.parent = NULL; ret = check_noncircular(&this, hlock_class(prev), &target_entry); if (unlikely(!ret)) - return print_circular_bug(&this, target_entry, next, prev); + return print_circular_bug(&this, target_entry, next, prev, trace); else if (unlikely(ret < 0)) return print_bfs_bug(ret); @@ -1870,15 +1920,26 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, if (entry->class == hlock_class(next)) { if (distance == 1) entry->distance = 1; - return 2; + return 1; } } - if (!*stack_saved) { - if (!save_trace(&trace)) - return 0; - *stack_saved = 1; + /* + * Is the -> link redundant? + */ + this.class = hlock_class(prev); + this.parent = NULL; + ret = check_redundant(&this, hlock_class(next), &target_entry); + if (!ret) { + debug_atomic_inc(nr_redundant); + return 2; } + if (ret < 0) + return print_bfs_bug(ret); + + + if (save && !save(trace)) + return 0; /* * Ok, all validations passed, add the new lock @@ -1886,14 +1947,14 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, */ ret = add_lock_to_list(hlock_class(next), &hlock_class(prev)->locks_after, - next->acquire_ip, distance, &trace); + next->acquire_ip, distance, trace); if (!ret) return 0; ret = add_lock_to_list(hlock_class(prev), &hlock_class(next)->locks_before, - next->acquire_ip, distance, &trace); + next->acquire_ip, distance, trace); if (!ret) return 0; @@ -1901,8 +1962,6 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, * Debugging printouts: */ if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) { - /* We drop graph lock, so another thread can overwrite trace. */ - *stack_saved = 0; graph_unlock(); printk("\n new dependency: "); print_lock_name(hlock_class(prev)); @@ -1910,9 +1969,10 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, print_lock_name(hlock_class(next)); printk(KERN_CONT "\n"); dump_stack(); - return graph_lock(); + if (!graph_lock()) + return 0; } - return 1; + return 2; } /* @@ -1925,8 +1985,9 @@ static int check_prevs_add(struct task_struct *curr, struct held_lock *next) { int depth = curr->lockdep_depth; - int stack_saved = 0; struct held_lock *hlock; + struct stack_trace trace; + int (*save)(struct stack_trace *trace) = save_trace; /* * Debugging checks. @@ -1947,21 +2008,36 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) int distance = curr->lockdep_depth - depth + 1; hlock = curr->held_locks + depth - 1; /* - * Only non-recursive-read entries get new dependencies - * added: + * Only non-crosslock entries get new dependencies added. + * Crosslock entries will be added by commit later: */ - if (hlock->read != 2 && hlock->check) { - if (!check_prev_add(curr, hlock, next, - distance, &stack_saved)) - return 0; + if (!cross_lock(hlock->instance)) { /* - * Stop after the first non-trylock entry, - * as non-trylock entries have added their - * own direct dependencies already, so this - * lock is connected to them indirectly: + * Only non-recursive-read entries get new dependencies + * added: */ - if (!hlock->trylock) - break; + if (hlock->read != 2 && hlock->check) { + int ret = check_prev_add(curr, hlock, next, + distance, &trace, save); + if (!ret) + return 0; + + /* + * Stop saving stack_trace if save_trace() was + * called at least once: + */ + if (save && ret == 2) + save = NULL; + + /* + * Stop after the first non-trylock entry, + * as non-trylock entries have added their + * own direct dependencies already, so this + * lock is connected to them indirectly: + */ + if (!hlock->trylock) + break; + } } depth--; /* @@ -2126,19 +2202,26 @@ static int check_no_collision(struct task_struct *curr, } /* - * Look up a dependency chain. If the key is not present yet then - * add it and return 1 - in this case the new dependency chain is - * validated. If the key is already hashed, return 0. - * (On return with 1 graph_lock is held.) + * This is for building a chain between just two different classes, + * instead of adding a new hlock upon current, which is done by + * add_chain_cache(). + * + * This can be called in any context with two classes, while + * add_chain_cache() must be done within the lock owener's context + * since it uses hlock which might be racy in another context. */ -static inline int lookup_chain_cache(struct task_struct *curr, - struct held_lock *hlock, - u64 chain_key) +static inline int add_chain_cache_classes(unsigned int prev, + unsigned int next, + unsigned int irq_context, + u64 chain_key) { - struct lock_class *class = hlock_class(hlock); struct hlist_head *hash_head = chainhashentry(chain_key); struct lock_chain *chain; - int i, j; + + /* + * Allocate a new chain entry from the static array, and add + * it to the hash: + */ /* * We might need to take the graph lock, ensure we've got IRQs @@ -2147,43 +2230,76 @@ static inline int lookup_chain_cache(struct task_struct *curr, */ if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) return 0; + + if (unlikely(nr_lock_chains >= MAX_LOCKDEP_CHAINS)) { + if (!debug_locks_off_graph_unlock()) + return 0; + + print_lockdep_off("BUG: MAX_LOCKDEP_CHAINS too low!"); + dump_stack(); + return 0; + } + + chain = lock_chains + nr_lock_chains++; + chain->chain_key = chain_key; + chain->irq_context = irq_context; + chain->depth = 2; + if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { + chain->base = nr_chain_hlocks; + nr_chain_hlocks += chain->depth; + chain_hlocks[chain->base] = prev - 1; + chain_hlocks[chain->base + 1] = next -1; + } +#ifdef CONFIG_DEBUG_LOCKDEP /* - * We can walk it lock-free, because entries only get added - * to the hash: + * Important for check_no_collision(). */ - hlist_for_each_entry_rcu(chain, hash_head, entry) { - if (chain->chain_key == chain_key) { -cache_hit: - debug_atomic_inc(chain_lookup_hits); - if (!check_no_collision(curr, hlock, chain)) - return 0; - - if (very_verbose(class)) - printk("\nhash chain already cached, key: " - "%016Lx tail class: [%p] %s\n", - (unsigned long long)chain_key, - class->key, class->name); + else { + if (!debug_locks_off_graph_unlock()) return 0; - } + + print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); + dump_stack(); + return 0; } - if (very_verbose(class)) - printk("\nnew hash chain, key: %016Lx tail class: [%p] %s\n", - (unsigned long long)chain_key, class->key, class->name); +#endif + + hlist_add_head_rcu(&chain->entry, hash_head); + debug_atomic_inc(chain_lookup_misses); + inc_chains(); + + return 1; +} + +/* + * Adds a dependency chain into chain hashtable. And must be called with + * graph_lock held. + * + * Return 0 if fail, and graph_lock is released. + * Return 1 if succeed, with graph_lock held. + */ +static inline int add_chain_cache(struct task_struct *curr, + struct held_lock *hlock, + u64 chain_key) +{ + struct lock_class *class = hlock_class(hlock); + struct hlist_head *hash_head = chainhashentry(chain_key); + struct lock_chain *chain; + int i, j; + /* * Allocate a new chain entry from the static array, and add * it to the hash: */ - if (!graph_lock()) - return 0; + /* - * We have to walk the chain again locked - to avoid duplicates: + * We might need to take the graph lock, ensure we've got IRQs + * disabled to make this an IRQ-safe lock.. for recursion reasons + * lockdep won't complain about its own locking errors. */ - hlist_for_each_entry(chain, hash_head, entry) { - if (chain->chain_key == chain_key) { - graph_unlock(); - goto cache_hit; - } - } + if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) + return 0; + if (unlikely(nr_lock_chains >= MAX_LOCKDEP_CHAINS)) { if (!debug_locks_off_graph_unlock()) return 0; @@ -2235,6 +2351,78 @@ static inline int lookup_chain_cache(struct task_struct *curr, return 1; } +/* + * Look up a dependency chain. + */ +static inline struct lock_chain *lookup_chain_cache(u64 chain_key) +{ + struct hlist_head *hash_head = chainhashentry(chain_key); + struct lock_chain *chain; + + /* + * We can walk it lock-free, because entries only get added + * to the hash: + */ + hlist_for_each_entry_rcu(chain, hash_head, entry) { + if (chain->chain_key == chain_key) { + debug_atomic_inc(chain_lookup_hits); + return chain; + } + } + return NULL; +} + +/* + * If the key is not present yet in dependency chain cache then + * add it and return 1 - in this case the new dependency chain is + * validated. If the key is already hashed, return 0. + * (On return with 1 graph_lock is held.) + */ +static inline int lookup_chain_cache_add(struct task_struct *curr, + struct held_lock *hlock, + u64 chain_key) +{ + struct lock_class *class = hlock_class(hlock); + struct lock_chain *chain = lookup_chain_cache(chain_key); + + if (chain) { +cache_hit: + if (!check_no_collision(curr, hlock, chain)) + return 0; + + if (very_verbose(class)) { + printk("\nhash chain already cached, key: " + "%016Lx tail class: [%p] %s\n", + (unsigned long long)chain_key, + class->key, class->name); + } + + return 0; + } + + if (very_verbose(class)) { + printk("\nnew hash chain, key: %016Lx tail class: [%p] %s\n", + (unsigned long long)chain_key, class->key, class->name); + } + + if (!graph_lock()) + return 0; + + /* + * We have to walk the chain again locked - to avoid duplicates: + */ + chain = lookup_chain_cache(chain_key); + if (chain) { + graph_unlock(); + goto cache_hit; + } + + if (!add_chain_cache(curr, hlock, chain_key)) + return 0; + + return 1; +} + static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, struct held_lock *hlock, int chain_head, u64 chain_key) { @@ -2245,11 +2433,11 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, * * We look up the chain_key and do the O(N^2) check and update of * the dependencies only if this is a new dependency chain. - * (If lookup_chain_cache() returns with 1 it acquires + * (If lookup_chain_cache_add() return with 1 it acquires * graph_lock for us) */ if (!hlock->trylock && hlock->check && - lookup_chain_cache(curr, hlock, chain_key)) { + lookup_chain_cache_add(curr, hlock, chain_key)) { /* * Check whether last held lock: * @@ -2277,14 +2465,17 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, * Add dependency only if this lock is not the head * of the chain, and if it's not a secondary read-lock: */ - if (!chain_head && ret != 2) + if (!chain_head && ret != 2) { if (!check_prevs_add(curr, hlock)) return 0; + } + graph_unlock(); - } else - /* after lookup_chain_cache(): */ + } else { + /* after lookup_chain_cache_add(): */ if (unlikely(!debug_locks)) return 0; + } return 1; } @@ -2567,14 +2758,6 @@ static int SOFTIRQ_verbose(struct lock_class *class) return 0; } -static int RECLAIM_FS_verbose(struct lock_class *class) -{ -#if RECLAIM_VERBOSE - return class_filter(class); -#endif - return 0; -} - #define STRICT_READ_CHECKS 1 static int (*state_verbose_f[])(struct lock_class *class) = { @@ -2870,57 +3053,6 @@ void trace_softirqs_off(unsigned long ip) debug_atomic_inc(redundant_softirqs_off); } -static void __lockdep_trace_alloc(gfp_t gfp_mask, unsigned long flags) -{ - struct task_struct *curr = current; - - if (unlikely(!debug_locks)) - return; - - gfp_mask = current_gfp_context(gfp_mask); - - /* no reclaim without waiting on it */ - if (!(gfp_mask & __GFP_DIRECT_RECLAIM)) - return; - - /* this guy won't enter reclaim */ - if ((curr->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) - return; - - /* We're only interested __GFP_FS allocations for now */ - if (!(gfp_mask & __GFP_FS) || (curr->flags & PF_MEMALLOC_NOFS)) - return; - - /* - * Oi! Can't be having __GFP_FS allocations with IRQs disabled. - */ - if (DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))) - return; - - /* Disable lockdep if explicitly requested */ - if (gfp_mask & __GFP_NOLOCKDEP) - return; - - mark_held_locks(curr, RECLAIM_FS); -} - -static void check_flags(unsigned long flags); - -void lockdep_trace_alloc(gfp_t gfp_mask) -{ - unsigned long flags; - - if (unlikely(current->lockdep_recursion)) - return; - - raw_local_irq_save(flags); - check_flags(flags); - current->lockdep_recursion = 1; - __lockdep_trace_alloc(gfp_mask, flags); - current->lockdep_recursion = 0; - raw_local_irq_restore(flags); -} - static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) { /* @@ -2966,22 +3098,6 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) } } - /* - * We reuse the irq context infrastructure more broadly as a general - * context checking code. This tests GFP_FS recursion (a lock taken - * during reclaim for a GFP_FS allocation is held over a GFP_FS - * allocation). - */ - if (!hlock->trylock && (curr->lockdep_reclaim_gfp & __GFP_FS)) { - if (hlock->read) { - if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS_READ)) - return 0; - } else { - if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS)) - return 0; - } - } - return 1; } @@ -3040,10 +3156,6 @@ static inline int separate_irq_context(struct task_struct *curr, return 0; } -void lockdep_trace_alloc(gfp_t gfp_mask) -{ -} - #endif /* defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) */ /* @@ -3116,7 +3228,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, /* * Initialize a lock instance's lock-class mapping info: */ -void lockdep_init_map(struct lockdep_map *lock, const char *name, +static void __lockdep_init_map(struct lockdep_map *lock, const char *name, struct lock_class_key *key, int subclass) { int i; @@ -3174,8 +3286,25 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name, raw_local_irq_restore(flags); } } + +void lockdep_init_map(struct lockdep_map *lock, const char *name, + struct lock_class_key *key, int subclass) +{ + cross_init(lock, 0); + __lockdep_init_map(lock, name, key, subclass); +} EXPORT_SYMBOL_GPL(lockdep_init_map); +#ifdef CONFIG_LOCKDEP_CROSSRELEASE +void lockdep_init_map_crosslock(struct lockdep_map *lock, const char *name, + struct lock_class_key *key, int subclass) +{ + cross_init(lock, 1); + __lockdep_init_map(lock, name, key, subclass); +} +EXPORT_SYMBOL_GPL(lockdep_init_map_crosslock); +#endif + struct lock_class_key __lockdep_no_validate__; EXPORT_SYMBOL_GPL(__lockdep_no_validate__); @@ -3231,6 +3360,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, int chain_head = 0; int class_idx; u64 chain_key; + int ret; if (unlikely(!debug_locks)) return 0; @@ -3279,7 +3409,8 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, class_idx = class - lock_classes + 1; - if (depth) { + /* TODO: nest_lock is not implemented for crosslock yet. */ + if (depth && !cross_lock(lock)) { hlock = curr->held_locks + depth - 1; if (hlock->class_idx == class_idx && nest_lock) { if (hlock->references) { @@ -3367,6 +3498,14 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, if (!validate_chain(curr, lock, hlock, chain_head, chain_key)) return 0; + ret = lock_acquire_crosslock(hlock); + /* + * 2 means normal acquire operations are needed. Otherwise, it's + * ok just to return with '0:fail, 1:success'. + */ + if (ret != 2) + return ret; + curr->curr_chain_key = chain_key; curr->lockdep_depth++; check_chain_key(curr); @@ -3604,11 +3743,19 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) struct task_struct *curr = current; struct held_lock *hlock; unsigned int depth; - int i; + int ret, i; if (unlikely(!debug_locks)) return 0; + ret = lock_release_crosslock(lock); + /* + * 2 means normal release operations are needed. Otherwise, it's + * ok just to return with '0:fail, 1:success'. + */ + if (ret != 2) + return ret; + depth = curr->lockdep_depth; /* * So we're all set to release this lock.. wait what lock? We don't @@ -3952,18 +4099,6 @@ void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie) } EXPORT_SYMBOL_GPL(lock_unpin_lock); -void lockdep_set_current_reclaim_state(gfp_t gfp_mask) -{ - current->lockdep_reclaim_gfp = current_gfp_context(gfp_mask); -} -EXPORT_SYMBOL_GPL(lockdep_set_current_reclaim_state); - -void lockdep_clear_current_reclaim_state(void) -{ - current->lockdep_reclaim_gfp = 0; -} -EXPORT_SYMBOL_GPL(lockdep_clear_current_reclaim_state); - #ifdef CONFIG_LOCK_STAT static int print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, @@ -4484,6 +4619,12 @@ asmlinkage __visible void lockdep_sys_exit(void) curr->comm, curr->pid); lockdep_print_held_locks(curr); } + + /* + * The lock history for each syscall should be independent. So wipe the + * slate clean on return to userspace. + */ + lockdep_invariant_state(false); } void lockdep_rcu_suspicious(const char *file, const int line, const char *s) @@ -4532,3 +4673,488 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s) dump_stack(); } EXPORT_SYMBOL_GPL(lockdep_rcu_suspicious); + +#ifdef CONFIG_LOCKDEP_CROSSRELEASE + +/* + * Crossrelease works by recording a lock history for each thread and + * connecting those historic locks that were taken after the + * wait_for_completion() in the complete() context. + * + * Task-A Task-B + * + * mutex_lock(&A); + * mutex_unlock(&A); + * + * wait_for_completion(&C); + * lock_acquire_crosslock(); + * atomic_inc_return(&cross_gen_id); + * | + * | mutex_lock(&B); + * | mutex_unlock(&B); + * | + * | complete(&C); + * `-- lock_commit_crosslock(); + * + * Which will then add a dependency between B and C. + */ + +#define xhlock(i) (current->xhlocks[(i) % MAX_XHLOCKS_NR]) + +/* + * Whenever a crosslock is held, cross_gen_id will be increased. + */ +static atomic_t cross_gen_id; /* Can be wrapped */ + +/* + * Make an entry of the ring buffer invalid. + */ +static inline void invalidate_xhlock(struct hist_lock *xhlock) +{ + /* + * Normally, xhlock->hlock.instance must be !NULL. + */ + xhlock->hlock.instance = NULL; +} + +/* + * Lock history stacks; we have 2 nested lock history stacks: + * + * HARD(IRQ) + * SOFT(IRQ) + * + * The thing is that once we complete a HARD/SOFT IRQ the future task locks + * should not depend on any of the locks observed while running the IRQ. So + * what we do is rewind the history buffer and erase all our knowledge of that + * temporal event. + */ + +void crossrelease_hist_start(enum xhlock_context_t c) +{ + struct task_struct *cur = current; + + if (!cur->xhlocks) + return; + + cur->xhlock_idx_hist[c] = cur->xhlock_idx; + cur->hist_id_save[c] = cur->hist_id; +} + +void crossrelease_hist_end(enum xhlock_context_t c) +{ + struct task_struct *cur = current; + + if (cur->xhlocks) { + unsigned int idx = cur->xhlock_idx_hist[c]; + struct hist_lock *h = &xhlock(idx); + + cur->xhlock_idx = idx; + + /* Check if the ring was overwritten. */ + if (h->hist_id != cur->hist_id_save[c]) + invalidate_xhlock(h); + } +} + +/* + * lockdep_invariant_state() is used to annotate independence inside a task, to + * make one task look like multiple independent 'tasks'. + * + * Take for instance workqueues; each work is independent of the last. The + * completion of a future work does not depend on the completion of a past work + * (in general). Therefore we must not carry that (lock) dependency across + * works. + * + * This is true for many things; pretty much all kthreads fall into this + * pattern, where they have an invariant state and future completions do not + * depend on past completions. Its just that since they all have the 'same' + * form -- the kthread does the same over and over -- it doesn't typically + * matter. + * + * The same is true for system-calls, once a system call is completed (we've + * returned to userspace) the next system call does not depend on the lock + * history of the previous system call. + * + * They key property for independence, this invariant state, is that it must be + * a point where we hold no locks and have no history. Because if we were to + * hold locks, the restore at _end() would not necessarily recover it's history + * entry. Similarly, independence per-definition means it does not depend on + * prior state. + */ +void lockdep_invariant_state(bool force) +{ + /* + * We call this at an invariant point, no current state, no history. + * Verify the former, enforce the latter. + */ + WARN_ON_ONCE(!force && current->lockdep_depth); + invalidate_xhlock(&xhlock(current->xhlock_idx)); +} + +static int cross_lock(struct lockdep_map *lock) +{ + return lock ? lock->cross : 0; +} + +/* + * This is needed to decide the relationship between wrapable variables. + */ +static inline int before(unsigned int a, unsigned int b) +{ + return (int)(a - b) < 0; +} + +static inline struct lock_class *xhlock_class(struct hist_lock *xhlock) +{ + return hlock_class(&xhlock->hlock); +} + +static inline struct lock_class *xlock_class(struct cross_lock *xlock) +{ + return hlock_class(&xlock->hlock); +} + +/* + * Should we check a dependency with previous one? + */ +static inline int depend_before(struct held_lock *hlock) +{ + return hlock->read != 2 && hlock->check && !hlock->trylock; +} + +/* + * Should we check a dependency with next one? + */ +static inline int depend_after(struct held_lock *hlock) +{ + return hlock->read != 2 && hlock->check; +} + +/* + * Check if the xhlock is valid, which would be false if, + * + * 1. Has not used after initializaion yet. + * 2. Got invalidated. + * + * Remind hist_lock is implemented as a ring buffer. + */ +static inline int xhlock_valid(struct hist_lock *xhlock) +{ + /* + * xhlock->hlock.instance must be !NULL. + */ + return !!xhlock->hlock.instance; +} + +/* + * Record a hist_lock entry. + * + * Irq disable is only required. + */ +static void add_xhlock(struct held_lock *hlock) +{ + unsigned int idx = ++current->xhlock_idx; + struct hist_lock *xhlock = &xhlock(idx); + +#ifdef CONFIG_DEBUG_LOCKDEP + /* + * This can be done locklessly because they are all task-local + * state, we must however ensure IRQs are disabled. + */ + WARN_ON_ONCE(!irqs_disabled()); +#endif + + /* Initialize hist_lock's members */ + xhlock->hlock = *hlock; + xhlock->hist_id = ++current->hist_id; + + xhlock->trace.nr_entries = 0; + xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES; + xhlock->trace.entries = xhlock->trace_entries; + xhlock->trace.skip = 3; + save_stack_trace(&xhlock->trace); +} + +static inline int same_context_xhlock(struct hist_lock *xhlock) +{ + return xhlock->hlock.irq_context == task_irq_context(current); +} + +/* + * This should be lockless as far as possible because this would be + * called very frequently. + */ +static void check_add_xhlock(struct held_lock *hlock) +{ + /* + * Record a hist_lock, only in case that acquisitions ahead + * could depend on the held_lock. For example, if the held_lock + * is trylock then acquisitions ahead never depends on that. + * In that case, we don't need to record it. Just return. + */ + if (!current->xhlocks || !depend_before(hlock)) + return; + + add_xhlock(hlock); +} + +/* + * For crosslock. + */ +static int add_xlock(struct held_lock *hlock) +{ + struct cross_lock *xlock; + unsigned int gen_id; + + if (!graph_lock()) + return 0; + + xlock = &((struct lockdep_map_cross *)hlock->instance)->xlock; + + /* + * When acquisitions for a crosslock are overlapped, we use + * nr_acquire to perform commit for them, based on cross_gen_id + * of the first acquisition, which allows to add additional + * dependencies. + * + * Moreover, when no acquisition of a crosslock is in progress, + * we should not perform commit because the lock might not exist + * any more, which might cause incorrect memory access. So we + * have to track the number of acquisitions of a crosslock. + * + * depend_after() is necessary to initialize only the first + * valid xlock so that the xlock can be used on its commit. + */ + if (xlock->nr_acquire++ && depend_after(&xlock->hlock)) + goto unlock; + + gen_id = (unsigned int)atomic_inc_return(&cross_gen_id); + xlock->hlock = *hlock; + xlock->hlock.gen_id = gen_id; +unlock: + graph_unlock(); + return 1; +} + +/* + * Called for both normal and crosslock acquires. Normal locks will be + * pushed on the hist_lock queue. Cross locks will record state and + * stop regular lock_acquire() to avoid being placed on the held_lock + * stack. + * + * Return: 0 - failure; + * 1 - crosslock, done; + * 2 - normal lock, continue to held_lock[] ops. + */ +static int lock_acquire_crosslock(struct held_lock *hlock) +{ + /* + * CONTEXT 1 CONTEXT 2 + * --------- --------- + * lock A (cross) + * X = atomic_inc_return(&cross_gen_id) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Y = atomic_read_acquire(&cross_gen_id) + * lock B + * + * atomic_read_acquire() is for ordering between A and B, + * IOW, A happens before B, when CONTEXT 2 see Y >= X. + * + * Pairs with atomic_inc_return() in add_xlock(). + */ + hlock->gen_id = (unsigned int)atomic_read_acquire(&cross_gen_id); + + if (cross_lock(hlock->instance)) + return add_xlock(hlock); + + check_add_xhlock(hlock); + return 2; +} + +static int copy_trace(struct stack_trace *trace) +{ + unsigned long *buf = stack_trace + nr_stack_trace_entries; + unsigned int max_nr = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries; + unsigned int nr = min(max_nr, trace->nr_entries); + + trace->nr_entries = nr; + memcpy(buf, trace->entries, nr * sizeof(trace->entries[0])); + trace->entries = buf; + nr_stack_trace_entries += nr; + + if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES-1) { + if (!debug_locks_off_graph_unlock()) + return 0; + + print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); + dump_stack(); + + return 0; + } + + return 1; +} + +static int commit_xhlock(struct cross_lock *xlock, struct hist_lock *xhlock) +{ + unsigned int xid, pid; + u64 chain_key; + + xid = xlock_class(xlock) - lock_classes; + chain_key = iterate_chain_key((u64)0, xid); + pid = xhlock_class(xhlock) - lock_classes; + chain_key = iterate_chain_key(chain_key, pid); + + if (lookup_chain_cache(chain_key)) + return 1; + + if (!add_chain_cache_classes(xid, pid, xhlock->hlock.irq_context, + chain_key)) + return 0; + + if (!check_prev_add(current, &xlock->hlock, &xhlock->hlock, 1, + &xhlock->trace, copy_trace)) + return 0; + + return 1; +} + +static void commit_xhlocks(struct cross_lock *xlock) +{ + unsigned int cur = current->xhlock_idx; + unsigned int prev_hist_id = xhlock(cur).hist_id; + unsigned int i; + + if (!graph_lock()) + return; + + if (xlock->nr_acquire) { + for (i = 0; i < MAX_XHLOCKS_NR; i++) { + struct hist_lock *xhlock = &xhlock(cur - i); + + if (!xhlock_valid(xhlock)) + break; + + if (before(xhlock->hlock.gen_id, xlock->hlock.gen_id)) + break; + + if (!same_context_xhlock(xhlock)) + break; + + /* + * Filter out the cases where the ring buffer was + * overwritten and the current entry has a bigger + * hist_id than the previous one, which is impossible + * otherwise: + */ + if (unlikely(before(prev_hist_id, xhlock->hist_id))) + break; + + prev_hist_id = xhlock->hist_id; + + /* + * commit_xhlock() returns 0 with graph_lock already + * released if fail. + */ + if (!commit_xhlock(xlock, xhlock)) + return; + } + } + + graph_unlock(); +} + +void lock_commit_crosslock(struct lockdep_map *lock) +{ + struct cross_lock *xlock; + unsigned long flags; + + if (unlikely(!debug_locks || current->lockdep_recursion)) + return; + + if (!current->xhlocks) + return; + + /* + * Do commit hist_locks with the cross_lock, only in case that + * the cross_lock could depend on acquisitions after that. + * + * For example, if the cross_lock does not have the 'check' flag + * then we don't need to check dependencies and commit for that. + * Just skip it. In that case, of course, the cross_lock does + * not depend on acquisitions ahead, either. + * + * WARNING: Don't do that in add_xlock() in advance. When an + * acquisition context is different from the commit context, + * invalid(skipped) cross_lock might be accessed. + */ + if (!depend_after(&((struct lockdep_map_cross *)lock)->xlock.hlock)) + return; + + raw_local_irq_save(flags); + check_flags(flags); + current->lockdep_recursion = 1; + xlock = &((struct lockdep_map_cross *)lock)->xlock; + commit_xhlocks(xlock); + current->lockdep_recursion = 0; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL_GPL(lock_commit_crosslock); + +/* + * Return: 0 - failure; + * 1 - crosslock, done; + * 2 - normal lock, continue to held_lock[] ops. + */ +static int lock_release_crosslock(struct lockdep_map *lock) +{ + if (cross_lock(lock)) { + if (!graph_lock()) + return 0; + ((struct lockdep_map_cross *)lock)->xlock.nr_acquire--; + graph_unlock(); + return 1; + } + return 2; +} + +static void cross_init(struct lockdep_map *lock, int cross) +{ + if (cross) + ((struct lockdep_map_cross *)lock)->xlock.nr_acquire = 0; + + lock->cross = cross; + + /* + * Crossrelease assumes that the ring buffer size of xhlocks + * is aligned with power of 2. So force it on build. + */ + BUILD_BUG_ON(MAX_XHLOCKS_NR & (MAX_XHLOCKS_NR - 1)); +} + +void lockdep_init_task(struct task_struct *task) +{ + int i; + + task->xhlock_idx = UINT_MAX; + task->hist_id = 0; + + for (i = 0; i < XHLOCK_CTX_NR; i++) { + task->xhlock_idx_hist[i] = UINT_MAX; + task->hist_id_save[i] = 0; + } + + task->xhlocks = kzalloc(sizeof(struct hist_lock) * MAX_XHLOCKS_NR, + GFP_KERNEL); +} + +void lockdep_free_task(struct task_struct *task) +{ + if (task->xhlocks) { + void *tmp = task->xhlocks; + /* Diable crossrelease for current */ + task->xhlocks = NULL; + kfree(tmp); + } +} +#endif diff --git a/kernel/locking/lockdep_internals.h b/kernel/locking/lockdep_internals.h index c08fbd2f5ba9fa2a806f326a3a85f5d021d74027..1da4669d57a7a62c330c8d24ca9d30819a892a2a 100644 --- a/kernel/locking/lockdep_internals.h +++ b/kernel/locking/lockdep_internals.h @@ -143,6 +143,8 @@ struct lockdep_stats { int redundant_softirqs_on; int redundant_softirqs_off; int nr_unused_locks; + int nr_redundant_checks; + int nr_redundant; int nr_cyclic_checks; int nr_cyclic_check_recursions; int nr_find_usage_forwards_checks; diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 6d1fcc786081a0cddb66cb2537cae22e1121b685..68d9e267ccd46df87d88bef89a809a40a05ed9bd 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -201,6 +201,10 @@ static void lockdep_stats_debug_show(struct seq_file *m) debug_atomic_read(chain_lookup_hits)); seq_printf(m, " cyclic checks: %11llu\n", debug_atomic_read(nr_cyclic_checks)); + seq_printf(m, " redundant checks: %11llu\n", + debug_atomic_read(nr_redundant_checks)); + seq_printf(m, " redundant links: %11llu\n", + debug_atomic_read(nr_redundant)); seq_printf(m, " find-mask forwards checks: %11llu\n", debug_atomic_read(nr_find_usage_forwards_checks)); seq_printf(m, " find-mask backwards checks: %11llu\n", diff --git a/kernel/locking/lockdep_states.h b/kernel/locking/lockdep_states.h index 995b0cc2b84c943c4abfd146bcc233311e3b1d18..35ca09f2ed0bbd139dd2a3f00dbcbb2f85371017 100644 --- a/kernel/locking/lockdep_states.h +++ b/kernel/locking/lockdep_states.h @@ -6,4 +6,3 @@ */ LOCKDEP_STATE(HARDIRQ) LOCKDEP_STATE(SOFTIRQ) -LOCKDEP_STATE(RECLAIM_FS) diff --git a/kernel/locking/osq_lock.c b/kernel/locking/osq_lock.c index a3167941093b74657dc1bea02a7febe3343c8e90..a74ee6abd039d0291f136b1b2dd1e5affeba2d06 100644 --- a/kernel/locking/osq_lock.c +++ b/kernel/locking/osq_lock.c @@ -109,6 +109,19 @@ bool osq_lock(struct optimistic_spin_queue *lock) prev = decode_cpu(old); node->prev = prev; + + /* + * osq_lock() unqueue + * + * node->prev = prev osq_wait_next() + * WMB MB + * prev->next = node next->prev = prev // unqueue-C + * + * Here 'node->prev' and 'next->prev' are the same variable and we need + * to ensure these stores happen in-order to avoid corrupting the list. + */ + smp_wmb(); + WRITE_ONCE(prev->next, node); /* diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c index fd24153e8a48db3bcf3c2be46270177a196529da..294294c71ba46a971652470f13507dd3ac231eed 100644 --- a/kernel/locking/qspinlock.c +++ b/kernel/locking/qspinlock.c @@ -268,123 +268,6 @@ static __always_inline u32 __pv_wait_head_or_lock(struct qspinlock *lock, #define queued_spin_lock_slowpath native_queued_spin_lock_slowpath #endif -/* - * Various notes on spin_is_locked() and spin_unlock_wait(), which are - * 'interesting' functions: - * - * PROBLEM: some architectures have an interesting issue with atomic ACQUIRE - * operations in that the ACQUIRE applies to the LOAD _not_ the STORE (ARM64, - * PPC). Also qspinlock has a similar issue per construction, the setting of - * the locked byte can be unordered acquiring the lock proper. - * - * This gets to be 'interesting' in the following cases, where the /should/s - * end up false because of this issue. - * - * - * CASE 1: - * - * So the spin_is_locked() correctness issue comes from something like: - * - * CPU0 CPU1 - * - * global_lock(); local_lock(i) - * spin_lock(&G) spin_lock(&L[i]) - * for (i) if (!spin_is_locked(&G)) { - * spin_unlock_wait(&L[i]); smp_acquire__after_ctrl_dep(); - * return; - * } - * // deal with fail - * - * Where it is important CPU1 sees G locked or CPU0 sees L[i] locked such - * that there is exclusion between the two critical sections. - * - * The load from spin_is_locked(&G) /should/ be constrained by the ACQUIRE from - * spin_lock(&L[i]), and similarly the load(s) from spin_unlock_wait(&L[i]) - * /should/ be constrained by the ACQUIRE from spin_lock(&G). - * - * Similarly, later stuff is constrained by the ACQUIRE from CTRL+RMB. - * - * - * CASE 2: - * - * For spin_unlock_wait() there is a second correctness issue, namely: - * - * CPU0 CPU1 - * - * flag = set; - * smp_mb(); spin_lock(&l) - * spin_unlock_wait(&l); if (!flag) - * // add to lockless list - * spin_unlock(&l); - * // iterate lockless list - * - * Which wants to ensure that CPU1 will stop adding bits to the list and CPU0 - * will observe the last entry on the list (if spin_unlock_wait() had ACQUIRE - * semantics etc..) - * - * Where flag /should/ be ordered against the locked store of l. - */ - -/* - * queued_spin_lock_slowpath() can (load-)ACQUIRE the lock before - * issuing an _unordered_ store to set _Q_LOCKED_VAL. - * - * This means that the store can be delayed, but no later than the - * store-release from the unlock. This means that simply observing - * _Q_LOCKED_VAL is not sufficient to determine if the lock is acquired. - * - * There are two paths that can issue the unordered store: - * - * (1) clear_pending_set_locked(): *,1,0 -> *,0,1 - * - * (2) set_locked(): t,0,0 -> t,0,1 ; t != 0 - * atomic_cmpxchg_relaxed(): t,0,0 -> 0,0,1 - * - * However, in both cases we have other !0 state we've set before to queue - * ourseves: - * - * For (1) we have the atomic_cmpxchg_acquire() that set _Q_PENDING_VAL, our - * load is constrained by that ACQUIRE to not pass before that, and thus must - * observe the store. - * - * For (2) we have a more intersting scenario. We enqueue ourselves using - * xchg_tail(), which ends up being a RELEASE. This in itself is not - * sufficient, however that is followed by an smp_cond_acquire() on the same - * word, giving a RELEASE->ACQUIRE ordering. This again constrains our load and - * guarantees we must observe that store. - * - * Therefore both cases have other !0 state that is observable before the - * unordered locked byte store comes through. This means we can use that to - * wait for the lock store, and then wait for an unlock. - */ -#ifndef queued_spin_unlock_wait -void queued_spin_unlock_wait(struct qspinlock *lock) -{ - u32 val; - - for (;;) { - val = atomic_read(&lock->val); - - if (!val) /* not locked, we're done */ - goto done; - - if (val & _Q_LOCKED_MASK) /* locked, go wait for unlock */ - break; - - /* not locked, but pending, wait until we observe the lock */ - cpu_relax(); - } - - /* any unlock is good */ - while (atomic_read(&lock->val) & _Q_LOCKED_MASK) - cpu_relax(); - -done: - smp_acquire__after_ctrl_dep(); -} -EXPORT_SYMBOL(queued_spin_unlock_wait); -#endif - #endif /* _GEN_PV_LOCK_SLOWPATH */ /** diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h index 4ccfcaae5b89da53ae688893eddbc717c5124317..43555681c40b496dd6494a0f52240f932b7bef38 100644 --- a/kernel/locking/qspinlock_paravirt.h +++ b/kernel/locking/qspinlock_paravirt.h @@ -72,7 +72,7 @@ static inline bool pv_queued_spin_steal_lock(struct qspinlock *lock) struct __qspinlock *l = (void *)lock; if (!(atomic_read(&lock->val) & _Q_LOCKED_PENDING_MASK) && - (cmpxchg(&l->locked, 0, _Q_LOCKED_VAL) == 0)) { + (cmpxchg_acquire(&l->locked, 0, _Q_LOCKED_VAL) == 0)) { qstat_inc(qstat_pv_lock_stealing, true); return true; } @@ -101,16 +101,16 @@ static __always_inline void clear_pending(struct qspinlock *lock) /* * The pending bit check in pv_queued_spin_steal_lock() isn't a memory - * barrier. Therefore, an atomic cmpxchg() is used to acquire the lock - * just to be sure that it will get it. + * barrier. Therefore, an atomic cmpxchg_acquire() is used to acquire the + * lock just to be sure that it will get it. */ static __always_inline int trylock_clear_pending(struct qspinlock *lock) { struct __qspinlock *l = (void *)lock; return !READ_ONCE(l->locked) && - (cmpxchg(&l->locked_pending, _Q_PENDING_VAL, _Q_LOCKED_VAL) - == _Q_PENDING_VAL); + (cmpxchg_acquire(&l->locked_pending, _Q_PENDING_VAL, + _Q_LOCKED_VAL) == _Q_PENDING_VAL); } #else /* _Q_PENDING_BITS == 8 */ static __always_inline void set_pending(struct qspinlock *lock) @@ -138,7 +138,7 @@ static __always_inline int trylock_clear_pending(struct qspinlock *lock) */ old = val; new = (val & ~_Q_PENDING_MASK) | _Q_LOCKED_VAL; - val = atomic_cmpxchg(&lock->val, old, new); + val = atomic_cmpxchg_acquire(&lock->val, old, new); if (val == old) return 1; @@ -362,8 +362,18 @@ static void pv_kick_node(struct qspinlock *lock, struct mcs_spinlock *node) * observe its next->locked value and advance itself. * * Matches with smp_store_mb() and cmpxchg() in pv_wait_node() + * + * The write to next->locked in arch_mcs_spin_unlock_contended() + * must be ordered before the read of pn->state in the cmpxchg() + * below for the code to work correctly. To guarantee full ordering + * irrespective of the success or failure of the cmpxchg(), + * a relaxed version with explicit barrier is used. The control + * dependency will order the reading of pn->state before any + * subsequent writes. */ - if (cmpxchg(&pn->state, vcpu_halted, vcpu_hashed) != vcpu_halted) + smp_mb__before_atomic(); + if (cmpxchg_relaxed(&pn->state, vcpu_halted, vcpu_hashed) + != vcpu_halted) return; /* diff --git a/kernel/locking/rtmutex-debug.c b/kernel/locking/rtmutex-debug.c index ac35e648b0e519ffc0a96a54d85f57fd1c0d2c1d..f4a74e78d4678f767f8d18d801db43dfeb92cece 100644 --- a/kernel/locking/rtmutex-debug.c +++ b/kernel/locking/rtmutex-debug.c @@ -58,7 +58,7 @@ static void printk_lock(struct rt_mutex *lock, int print_owner) void rt_mutex_debug_task_free(struct task_struct *task) { - DEBUG_LOCKS_WARN_ON(!RB_EMPTY_ROOT(&task->pi_waiters)); + DEBUG_LOCKS_WARN_ON(!RB_EMPTY_ROOT(&task->pi_waiters.rb_root)); DEBUG_LOCKS_WARN_ON(task->pi_blocked_on); } diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 649dc9d3951a5fed57930769957552841528f784..6f3dba6e4e9e14332dfb02039dd720f84d0348b0 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -271,10 +271,10 @@ rt_mutex_waiter_equal(struct rt_mutex_waiter *left, static void rt_mutex_enqueue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) { - struct rb_node **link = &lock->waiters.rb_node; + struct rb_node **link = &lock->waiters.rb_root.rb_node; struct rb_node *parent = NULL; struct rt_mutex_waiter *entry; - int leftmost = 1; + bool leftmost = true; while (*link) { parent = *link; @@ -283,15 +283,12 @@ rt_mutex_enqueue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) link = &parent->rb_left; } else { link = &parent->rb_right; - leftmost = 0; + leftmost = false; } } - if (leftmost) - lock->waiters_leftmost = &waiter->tree_entry; - rb_link_node(&waiter->tree_entry, parent, link); - rb_insert_color(&waiter->tree_entry, &lock->waiters); + rb_insert_color_cached(&waiter->tree_entry, &lock->waiters, leftmost); } static void @@ -300,20 +297,17 @@ rt_mutex_dequeue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) if (RB_EMPTY_NODE(&waiter->tree_entry)) return; - if (lock->waiters_leftmost == &waiter->tree_entry) - lock->waiters_leftmost = rb_next(&waiter->tree_entry); - - rb_erase(&waiter->tree_entry, &lock->waiters); + rb_erase_cached(&waiter->tree_entry, &lock->waiters); RB_CLEAR_NODE(&waiter->tree_entry); } static void rt_mutex_enqueue_pi(struct task_struct *task, struct rt_mutex_waiter *waiter) { - struct rb_node **link = &task->pi_waiters.rb_node; + struct rb_node **link = &task->pi_waiters.rb_root.rb_node; struct rb_node *parent = NULL; struct rt_mutex_waiter *entry; - int leftmost = 1; + bool leftmost = true; while (*link) { parent = *link; @@ -322,15 +316,12 @@ rt_mutex_enqueue_pi(struct task_struct *task, struct rt_mutex_waiter *waiter) link = &parent->rb_left; } else { link = &parent->rb_right; - leftmost = 0; + leftmost = false; } } - if (leftmost) - task->pi_waiters_leftmost = &waiter->pi_tree_entry; - rb_link_node(&waiter->pi_tree_entry, parent, link); - rb_insert_color(&waiter->pi_tree_entry, &task->pi_waiters); + rb_insert_color_cached(&waiter->pi_tree_entry, &task->pi_waiters, leftmost); } static void @@ -339,10 +330,7 @@ rt_mutex_dequeue_pi(struct task_struct *task, struct rt_mutex_waiter *waiter) if (RB_EMPTY_NODE(&waiter->pi_tree_entry)) return; - if (task->pi_waiters_leftmost == &waiter->pi_tree_entry) - task->pi_waiters_leftmost = rb_next(&waiter->pi_tree_entry); - - rb_erase(&waiter->pi_tree_entry, &task->pi_waiters); + rb_erase_cached(&waiter->pi_tree_entry, &task->pi_waiters); RB_CLEAR_NODE(&waiter->pi_tree_entry); } @@ -1657,8 +1645,7 @@ void __rt_mutex_init(struct rt_mutex *lock, const char *name, { lock->owner = NULL; raw_spin_lock_init(&lock->wait_lock); - lock->waiters = RB_ROOT; - lock->waiters_leftmost = NULL; + lock->waiters = RB_ROOT_CACHED; if (name && key) debug_rt_mutex_init(lock, name, key); diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h index 72ad45a9a79439c53f73afee4ab87330957a0ff2..7453be0485a5e85738aa6de657c111d85494e08b 100644 --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h @@ -40,9 +40,12 @@ struct rt_mutex_waiter { /* * Various helpers to access the waiters-tree: */ + +#ifdef CONFIG_RT_MUTEXES + static inline int rt_mutex_has_waiters(struct rt_mutex *lock) { - return !RB_EMPTY_ROOT(&lock->waiters); + return !RB_EMPTY_ROOT(&lock->waiters.rb_root); } static inline struct rt_mutex_waiter * @@ -50,8 +53,8 @@ rt_mutex_top_waiter(struct rt_mutex *lock) { struct rt_mutex_waiter *w; - w = rb_entry(lock->waiters_leftmost, struct rt_mutex_waiter, - tree_entry); + w = rb_entry(lock->waiters.rb_leftmost, + struct rt_mutex_waiter, tree_entry); BUG_ON(w->lock != lock); return w; @@ -59,16 +62,42 @@ rt_mutex_top_waiter(struct rt_mutex *lock) static inline int task_has_pi_waiters(struct task_struct *p) { - return !RB_EMPTY_ROOT(&p->pi_waiters); + return !RB_EMPTY_ROOT(&p->pi_waiters.rb_root); +} + +static inline struct rt_mutex_waiter * +task_top_pi_waiter(struct task_struct *p) +{ + return rb_entry(p->pi_waiters.rb_leftmost, + struct rt_mutex_waiter, pi_tree_entry); +} + +#else + +static inline int rt_mutex_has_waiters(struct rt_mutex *lock) +{ + return false; +} + +static inline struct rt_mutex_waiter * +rt_mutex_top_waiter(struct rt_mutex *lock) +{ + return NULL; +} + +static inline int task_has_pi_waiters(struct task_struct *p) +{ + return false; } static inline struct rt_mutex_waiter * task_top_pi_waiter(struct task_struct *p) { - return rb_entry(p->pi_waiters_leftmost, struct rt_mutex_waiter, - pi_tree_entry); + return NULL; } +#endif + /* * lock->owner state tracking: */ diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index 20819df981256c51f94bfdc38a2635132a7c8be6..0848634c5512998ab0fa1d6b495216f4ef305853 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c @@ -126,7 +126,7 @@ __rwsem_wake_one_writer(struct rw_semaphore *sem) /* * get a read lock on the semaphore */ -void __sched __down_read(struct rw_semaphore *sem) +int __sched __down_read_common(struct rw_semaphore *sem, int state) { struct rwsem_waiter waiter; unsigned long flags; @@ -140,8 +140,6 @@ void __sched __down_read(struct rw_semaphore *sem) goto out; } - set_current_state(TASK_UNINTERRUPTIBLE); - /* set up my own style of waitqueue */ waiter.task = current; waiter.type = RWSEM_WAITING_FOR_READ; @@ -149,20 +147,41 @@ void __sched __down_read(struct rw_semaphore *sem) list_add_tail(&waiter.list, &sem->wait_list); - /* we don't need to touch the semaphore struct anymore */ - raw_spin_unlock_irqrestore(&sem->wait_lock, flags); - /* wait to be given the lock */ for (;;) { if (!waiter.task) break; + if (signal_pending_state(state, current)) + goto out_nolock; + set_current_state(state); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); schedule(); - set_current_state(TASK_UNINTERRUPTIBLE); + raw_spin_lock_irqsave(&sem->wait_lock, flags); } - __set_current_state(TASK_RUNNING); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); out: - ; + return 0; + +out_nolock: + /* + * We didn't take the lock, so that there is a writer, which + * is owner or the first waiter of the sem. If it's a waiter, + * it will be woken by current owner. Not need to wake anybody. + */ + list_del(&waiter.list); + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); + return -EINTR; +} + +void __sched __down_read(struct rw_semaphore *sem) +{ + __down_read_common(sem, TASK_UNINTERRUPTIBLE); +} + +int __sched __down_read_killable(struct rw_semaphore *sem) +{ + return __down_read_common(sem, TASK_KILLABLE); } /* diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 34e727f18e4945fb2cce3a3777000329152c0031..1fefe6dcafd7403a9b172e11ebd0f41d35332211 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c @@ -221,8 +221,8 @@ static void __rwsem_mark_wake(struct rw_semaphore *sem, /* * Wait for the read lock to be granted */ -__visible -struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) +static inline struct rw_semaphore __sched * +__rwsem_down_read_failed_common(struct rw_semaphore *sem, int state) { long count, adjustment = -RWSEM_ACTIVE_READ_BIAS; struct rwsem_waiter waiter; @@ -255,17 +255,44 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) /* wait to be given the lock */ while (true) { - set_current_state(TASK_UNINTERRUPTIBLE); + set_current_state(state); if (!waiter.task) break; + if (signal_pending_state(state, current)) { + raw_spin_lock_irq(&sem->wait_lock); + if (waiter.task) + goto out_nolock; + raw_spin_unlock_irq(&sem->wait_lock); + break; + } schedule(); } __set_current_state(TASK_RUNNING); return sem; +out_nolock: + list_del(&waiter.list); + if (list_empty(&sem->wait_list)) + atomic_long_add(-RWSEM_WAITING_BIAS, &sem->count); + raw_spin_unlock_irq(&sem->wait_lock); + __set_current_state(TASK_RUNNING); + return ERR_PTR(-EINTR); +} + +__visible struct rw_semaphore * __sched +rwsem_down_read_failed(struct rw_semaphore *sem) +{ + return __rwsem_down_read_failed_common(sem, TASK_UNINTERRUPTIBLE); } EXPORT_SYMBOL(rwsem_down_read_failed); +__visible struct rw_semaphore * __sched +rwsem_down_read_failed_killable(struct rw_semaphore *sem) +{ + return __rwsem_down_read_failed_common(sem, TASK_KILLABLE); +} +EXPORT_SYMBOL(rwsem_down_read_failed_killable); + /* * This function must be called with the sem->wait_lock held to prevent * race conditions between checking the rwsem wait list and setting the @@ -585,6 +612,33 @@ struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem) unsigned long flags; DEFINE_WAKE_Q(wake_q); + /* + * __rwsem_down_write_failed_common(sem) + * rwsem_optimistic_spin(sem) + * osq_unlock(sem->osq) + * ... + * atomic_long_add_return(&sem->count) + * + * - VS - + * + * __up_write() + * if (atomic_long_sub_return_release(&sem->count) < 0) + * rwsem_wake(sem) + * osq_is_locked(&sem->osq) + * + * And __up_write() must observe !osq_is_locked() when it observes the + * atomic_long_add_return() in order to not miss a wakeup. + * + * This boils down to: + * + * [S.rel] X = 1 [RmW] r0 = (Y += 0) + * MB RMB + * [RmW] Y += 1 [L] r1 = X + * + * exists (r0=1 /\ r1=0) + */ + smp_rmb(); + /* * If a spinner is present, it is not necessary to do the wakeup. * Try to do wakeup only if the trylock succeeds to minimize diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c index 39f56c870051b505611746ff0033cc6a7f6e1a10..0e4cd64ad2c018cf4ad2375004b966d6de49c241 100644 --- a/kernel/locking/test-ww_mutex.c +++ b/kernel/locking/test-ww_mutex.c @@ -362,7 +362,7 @@ static int *get_random_order(int count) int *order; int n, r, tmp; - order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY); + order = kmalloc_array(count, sizeof(*order), GFP_KERNEL); if (!order) return order; diff --git a/kernel/membarrier.c b/kernel/membarrier.c deleted file mode 100644 index 9f9284f37f8d8b6d3149ecc22634c613123e792d..0000000000000000000000000000000000000000 --- a/kernel/membarrier.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010, 2015 Mathieu Desnoyers - * - * membarrier system call - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -/* - * Bitmask made from a "or" of all commands within enum membarrier_cmd, - * except MEMBARRIER_CMD_QUERY. - */ -#define MEMBARRIER_CMD_BITMASK (MEMBARRIER_CMD_SHARED) - -/** - * sys_membarrier - issue memory barriers on a set of threads - * @cmd: Takes command values defined in enum membarrier_cmd. - * @flags: Currently needs to be 0. For future extensions. - * - * If this system call is not implemented, -ENOSYS is returned. If the - * command specified does not exist, or if the command argument is invalid, - * this system call returns -EINVAL. For a given command, with flags argument - * set to 0, this system call is guaranteed to always return the same value - * until reboot. - * - * All memory accesses performed in program order from each targeted thread - * is guaranteed to be ordered with respect to sys_membarrier(). If we use - * the semantic "barrier()" to represent a compiler barrier forcing memory - * accesses to be performed in program order across the barrier, and - * smp_mb() to represent explicit memory barriers forcing full memory - * ordering across the barrier, we have the following ordering table for - * each pair of barrier(), sys_membarrier() and smp_mb(): - * - * The pair ordering is detailed as (O: ordered, X: not ordered): - * - * barrier() smp_mb() sys_membarrier() - * barrier() X X O - * smp_mb() X O O - * sys_membarrier() O O O - */ -SYSCALL_DEFINE2(membarrier, int, cmd, int, flags) -{ - /* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */ - if (tick_nohz_full_enabled()) - return -ENOSYS; - if (unlikely(flags)) - return -EINVAL; - switch (cmd) { - case MEMBARRIER_CMD_QUERY: - return MEMBARRIER_CMD_BITMASK; - case MEMBARRIER_CMD_SHARED: - if (num_online_cpus() > 1) - synchronize_sched(); - return 0; - default: - return -EINVAL; - } -} diff --git a/kernel/memremap.c b/kernel/memremap.c index 124bed776532d3d2e69f4079e3f2d23da193fd2e..403ab9cdb949a0483bd82c811a3383eed77e5246 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c @@ -11,13 +11,14 @@ * General Public License for more details. */ #include -#include #include #include #include #include #include #include +#include +#include #ifndef ioremap_cache /* temporary while we convert existing ioremap_cache users to memremap */ @@ -34,13 +35,24 @@ static void *arch_memremap_wb(resource_size_t offset, unsigned long size) } #endif -static void *try_ram_remap(resource_size_t offset, size_t size) +#ifndef arch_memremap_can_ram_remap +static bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, + unsigned long flags) +{ + return true; +} +#endif + +static void *try_ram_remap(resource_size_t offset, size_t size, + unsigned long flags) { unsigned long pfn = PHYS_PFN(offset); /* In the simple case just return the existing linear address */ - if (pfn_valid(pfn) && !PageHighMem(pfn_to_page(pfn))) + if (pfn_valid(pfn) && !PageHighMem(pfn_to_page(pfn)) && + arch_memremap_can_ram_remap(offset, size, flags)) return __va(offset); + return NULL; /* fallback to arch_memremap_wb */ } @@ -48,7 +60,8 @@ static void *try_ram_remap(resource_size_t offset, size_t size) * memremap() - remap an iomem_resource as cacheable memory * @offset: iomem resource start address * @size: size of remap - * @flags: any of MEMREMAP_WB, MEMREMAP_WT and MEMREMAP_WC + * @flags: any of MEMREMAP_WB, MEMREMAP_WT, MEMREMAP_WC, + * MEMREMAP_ENC, MEMREMAP_DEC * * memremap() is "ioremap" for cases where it is known that the resource * being mapped does not have i/o side effects and the __iomem @@ -95,7 +108,7 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags) * the requested range is potentially in System RAM. */ if (is_ram == REGION_INTERSECTS) - addr = try_ram_remap(offset, size); + addr = try_ram_remap(offset, size, flags); if (!addr) addr = arch_memremap_wb(offset, size); } @@ -182,18 +195,69 @@ struct page_map { struct vmem_altmap altmap; }; -static void pgmap_radix_release(struct resource *res) +static unsigned long order_at(struct resource *res, unsigned long pgoff) { - resource_size_t key, align_start, align_size, align_end; + unsigned long phys_pgoff = PHYS_PFN(res->start) + pgoff; + unsigned long nr_pages, mask; - align_start = res->start & ~(SECTION_SIZE - 1); - align_size = ALIGN(resource_size(res), SECTION_SIZE); - align_end = align_start + align_size - 1; + nr_pages = PHYS_PFN(resource_size(res)); + if (nr_pages == pgoff) + return ULONG_MAX; + + /* + * What is the largest aligned power-of-2 range available from + * this resource pgoff to the end of the resource range, + * considering the alignment of the current pgoff? + */ + mask = phys_pgoff | rounddown_pow_of_two(nr_pages - pgoff); + if (!mask) + return ULONG_MAX; + + return find_first_bit(&mask, BITS_PER_LONG); +} + +#define foreach_order_pgoff(res, order, pgoff) \ + for (pgoff = 0, order = order_at((res), pgoff); order < ULONG_MAX; \ + pgoff += 1UL << order, order = order_at((res), pgoff)) + +#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) +int device_private_entry_fault(struct vm_area_struct *vma, + unsigned long addr, + swp_entry_t entry, + unsigned int flags, + pmd_t *pmdp) +{ + struct page *page = device_private_entry_to_page(entry); + + /* + * The page_fault() callback must migrate page back to system memory + * so that CPU can access it. This might fail for various reasons + * (device issue, device was unsafely unplugged, ...). When such + * error conditions happen, the callback must return VM_FAULT_SIGBUS. + * + * Note that because memory cgroup charges are accounted to the device + * memory, this should never fail because of memory restrictions (but + * allocation of regular system page might still fail because we are + * out of memory). + * + * There is a more in-depth description of what that callback can and + * cannot do, in include/linux/memremap.h + */ + return page->pgmap->page_fault(vma, addr, page, flags, pmdp); +} +EXPORT_SYMBOL(device_private_entry_fault); +#endif /* CONFIG_DEVICE_PRIVATE */ + +static void pgmap_radix_release(struct resource *res) +{ + unsigned long pgoff, order; mutex_lock(&pgmap_lock); - for (key = res->start; key <= res->end; key += SECTION_SIZE) - radix_tree_delete(&pgmap_radix, key >> PA_SECTION_SHIFT); + foreach_order_pgoff(res, order, pgoff) + radix_tree_delete(&pgmap_radix, PHYS_PFN(res->start) + pgoff); mutex_unlock(&pgmap_lock); + + synchronize_rcu(); } static unsigned long pfn_first(struct page_map *page_map) @@ -256,7 +320,7 @@ struct dev_pagemap *find_dev_pagemap(resource_size_t phys) WARN_ON_ONCE(!rcu_read_lock_held()); - page_map = radix_tree_lookup(&pgmap_radix, phys >> PA_SECTION_SHIFT); + page_map = radix_tree_lookup(&pgmap_radix, PHYS_PFN(phys)); return page_map ? &page_map->pgmap : NULL; } @@ -281,12 +345,12 @@ struct dev_pagemap *find_dev_pagemap(resource_size_t phys) void *devm_memremap_pages(struct device *dev, struct resource *res, struct percpu_ref *ref, struct vmem_altmap *altmap) { - resource_size_t key, align_start, align_size, align_end; + resource_size_t align_start, align_size, align_end; + unsigned long pfn, pgoff, order; pgprot_t pgprot = PAGE_KERNEL; struct dev_pagemap *pgmap; struct page_map *page_map; - int error, nid, is_ram; - unsigned long pfn; + int error, nid, is_ram, i = 0; align_start = res->start & ~(SECTION_SIZE - 1); align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE) @@ -321,15 +385,20 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, } pgmap->ref = ref; pgmap->res = &page_map->res; + pgmap->type = MEMORY_DEVICE_HOST; + pgmap->page_fault = NULL; + pgmap->page_free = NULL; + pgmap->data = NULL; mutex_lock(&pgmap_lock); error = 0; align_end = align_start + align_size - 1; - for (key = align_start; key <= align_end; key += SECTION_SIZE) { + + foreach_order_pgoff(res, order, pgoff) { struct dev_pagemap *dup; rcu_read_lock(); - dup = find_dev_pagemap(key); + dup = find_dev_pagemap(res->start + PFN_PHYS(pgoff)); rcu_read_unlock(); if (dup) { dev_err(dev, "%s: %pr collides with mapping for %s\n", @@ -337,8 +406,8 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, error = -EBUSY; break; } - error = radix_tree_insert(&pgmap_radix, key >> PA_SECTION_SHIFT, - page_map); + error = __radix_tree_insert(&pgmap_radix, + PHYS_PFN(res->start) + pgoff, order, page_map); if (error) { dev_err(dev, "%s: failed: %d\n", __func__, error); break; @@ -379,6 +448,8 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, list_del(&page->lru); page->pgmap = pgmap; percpu_ref_get(ref); + if (!(++i % 1024)) + cond_resched(); } devres_add(dev, page_map); return __va(res->start); @@ -430,3 +501,28 @@ struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start) return pgmap ? pgmap->altmap : NULL; } #endif /* CONFIG_ZONE_DEVICE */ + + +#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC) +void put_zone_device_private_or_public_page(struct page *page) +{ + int count = page_ref_dec_return(page); + + /* + * If refcount is 1 then page is freed and refcount is stable as nobody + * holds a reference on the page. + */ + if (count == 1) { + /* Clear Active bit in case of parallel mark_page_accessed */ + __ClearPageActive(page); + __ClearPageWaiters(page); + + page->mapping = NULL; + mem_cgroup_uncharge(page); + + page->pgmap->page_free(page, page->pgmap->data); + } else if (!count) + __put_page(page); +} +EXPORT_SYMBOL(put_zone_device_private_or_public_page); +#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ diff --git a/kernel/module.c b/kernel/module.c index 40f983cbea81d1e3711955dfb2409659d89fd317..de66ec82599289d786063457ef46a3619893bb03 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2707,21 +2707,21 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) } #endif /* CONFIG_KALLSYMS */ -static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num) +static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsigned int num) { if (!debug) return; #ifdef CONFIG_DYNAMIC_DEBUG - if (ddebug_add_module(debug, num, debug->modname)) + if (ddebug_add_module(debug, num, mod->name)) pr_err("dynamic debug error adding module: %s\n", debug->modname); #endif } -static void dynamic_debug_remove(struct _ddebug *debug) +static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug) { if (debug) - ddebug_remove_module(debug->modname); + ddebug_remove_module(mod->name); } void * __weak module_alloc(unsigned long size) @@ -3715,7 +3715,7 @@ static int load_module(struct load_info *info, const char __user *uargs, goto free_arch_cleanup; } - dynamic_debug_setup(info->debug, info->num_debug); + dynamic_debug_setup(mod, info->debug, info->num_debug); /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */ ftrace_module_init(mod); @@ -3779,7 +3779,7 @@ static int load_module(struct load_info *info, const char __user *uargs, module_disable_nx(mod); ddebug_cleanup: - dynamic_debug_remove(info->debug); + dynamic_debug_remove(mod, info->debug); synchronize_sched(); kfree(mod->args); free_arch_cleanup: diff --git a/kernel/panic.c b/kernel/panic.c index a58932b41700a93c3a9fff8121ec716c4a256cac..bdd18afa19a486c759e7cd4b7a2983cfa0097fcb 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -26,6 +26,7 @@ #include #include #include +#include #define PANIC_TIMER_STEP 100 #define PANIC_BLINK_SPD 18 @@ -601,6 +602,17 @@ EXPORT_SYMBOL(__stack_chk_fail); #endif +#ifdef CONFIG_ARCH_HAS_REFCOUNT +void refcount_error_report(struct pt_regs *regs, const char *err) +{ + WARN_RATELIMIT(1, "refcount_t %s at %pB in %s[%d], uid/euid: %u/%u\n", + err, (void *)instruction_pointer(regs), + current->comm, task_pid_nr(current), + from_kuid_munged(&init_user_ns, current_uid()), + from_kuid_munged(&init_user_ns, current_euid())); +} +#endif + core_param(panic, panic_timeout, int, 0644); core_param(pause_on_oops, pause_on_oops, int, 0644); core_param(panic_on_warn, panic_on_warn, int, 0644); diff --git a/kernel/params.c b/kernel/params.c index 60b2d8101355fedcfd8dfee99f8a2fa467ea99d9..cc9108c2a1fde209f5fe8b41e4cfca2e9e4d1310 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -224,7 +224,7 @@ char *parse_args(const char *doing, } \ int param_get_##name(char *buffer, const struct kernel_param *kp) \ { \ - return scnprintf(buffer, PAGE_SIZE, format, \ + return scnprintf(buffer, PAGE_SIZE, format "\n", \ *((type *)kp->arg)); \ } \ const struct kernel_param_ops param_ops_##name = { \ @@ -236,14 +236,14 @@ char *parse_args(const char *doing, EXPORT_SYMBOL(param_ops_##name) -STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", kstrtou8); -STANDARD_PARAM_DEF(short, short, "%hi", kstrtos16); -STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", kstrtou16); -STANDARD_PARAM_DEF(int, int, "%i", kstrtoint); -STANDARD_PARAM_DEF(uint, unsigned int, "%u", kstrtouint); -STANDARD_PARAM_DEF(long, long, "%li", kstrtol); -STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", kstrtoul); -STANDARD_PARAM_DEF(ullong, unsigned long long, "%llu", kstrtoull); +STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", kstrtou8); +STANDARD_PARAM_DEF(short, short, "%hi", kstrtos16); +STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", kstrtou16); +STANDARD_PARAM_DEF(int, int, "%i", kstrtoint); +STANDARD_PARAM_DEF(uint, unsigned int, "%u", kstrtouint); +STANDARD_PARAM_DEF(long, long, "%li", kstrtol); +STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", kstrtoul); +STANDARD_PARAM_DEF(ullong, unsigned long long, "%llu", kstrtoull); int param_set_charp(const char *val, const struct kernel_param *kp) { @@ -270,7 +270,7 @@ EXPORT_SYMBOL(param_set_charp); int param_get_charp(char *buffer, const struct kernel_param *kp) { - return scnprintf(buffer, PAGE_SIZE, "%s", *((char **)kp->arg)); + return scnprintf(buffer, PAGE_SIZE, "%s\n", *((char **)kp->arg)); } EXPORT_SYMBOL(param_get_charp); @@ -301,7 +301,7 @@ EXPORT_SYMBOL(param_set_bool); int param_get_bool(char *buffer, const struct kernel_param *kp) { /* Y and N chosen as being relatively non-coder friendly */ - return sprintf(buffer, "%c", *(bool *)kp->arg ? 'Y' : 'N'); + return sprintf(buffer, "%c\n", *(bool *)kp->arg ? 'Y' : 'N'); } EXPORT_SYMBOL(param_get_bool); @@ -360,7 +360,7 @@ EXPORT_SYMBOL(param_set_invbool); int param_get_invbool(char *buffer, const struct kernel_param *kp) { - return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); + return sprintf(buffer, "%c\n", (*(bool *)kp->arg) ? 'N' : 'Y'); } EXPORT_SYMBOL(param_get_invbool); @@ -460,8 +460,9 @@ static int param_array_get(char *buffer, const struct kernel_param *kp) struct kernel_param p = *kp; for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) { + /* Replace \n with comma */ if (i) - buffer[off++] = ','; + buffer[off - 1] = ','; p.arg = arr->elem + arr->elemsize * i; check_kparam_locked(p.mod); ret = arr->ops->get(buffer + off, &p); @@ -507,7 +508,7 @@ EXPORT_SYMBOL(param_set_copystring); int param_get_string(char *buffer, const struct kernel_param *kp) { const struct kparam_string *kps = kp->str; - return strlcpy(buffer, kps->string, kps->maxlen); + return scnprintf(buffer, PAGE_SIZE, "%s\n", kps->string); } EXPORT_SYMBOL(param_get_string); @@ -549,10 +550,6 @@ static ssize_t param_attr_show(struct module_attribute *mattr, kernel_param_lock(mk->mod); count = attribute->param->ops->get(buf, attribute->param); kernel_param_unlock(mk->mod); - if (count > 0) { - strcat(buf, "\n"); - ++count; - } return count; } @@ -600,7 +597,7 @@ EXPORT_SYMBOL(kernel_param_unlock); /* * add_sysfs_param - add a parameter to sysfs * @mk: struct module_kobject - * @kparam: the actual parameter definition to add to sysfs + * @kp: the actual parameter definition to add to sysfs * @name: name of parameter * * Create a kobject if for a (per-module) parameter if mp NULL, and diff --git a/kernel/pid.c b/kernel/pid.c index 731c4e528f4e3cb2150370b37dc22afe9dc8e5cb..020dedbdf066bccbc370cba20be8dc7dbc914629 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -527,8 +527,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, if (!ns) ns = task_active_pid_ns(current); if (likely(pid_alive(task))) { - if (type != PIDTYPE_PID) + if (type != PIDTYPE_PID) { + if (type == __PIDTYPE_TGID) + type = PIDTYPE_PID; task = task->group_leader; + } nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); } rcu_read_unlock(); @@ -537,12 +540,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, } EXPORT_SYMBOL(__task_pid_nr_ns); -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return pid_nr_ns(task_tgid(tsk), ns); -} -EXPORT_SYMBOL(task_tgid_nr_ns); - struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) { return ns_of_pid(task_pid(tsk)); @@ -575,13 +572,10 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns) */ void __init pidhash_init(void) { - unsigned int pidhash_size; - pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18, HASH_EARLY | HASH_SMALL | HASH_ZERO, &pidhash_shift, NULL, 0, 4096); - pidhash_size = 1U << pidhash_shift; } void __init pidmap_init(void) diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 74a5a7255b4d9cb473cc7708d851c64402cca942..4918314893bc6620ae95660c78588d6d5ac9129c 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -101,6 +101,10 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns int i; int err; + err = -EINVAL; + if (!in_userns(parent_pid_ns->user_ns, user_ns)) + goto out; + err = -ENOSPC; if (level > MAX_PID_NS_LEVEL) goto out; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index e1914c7b85b180e7683eed48738e14443dbadc62..a5c36e9c56a670c59cabe20376f2ce1aedcd5e8a 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -651,7 +651,7 @@ static int load_image_and_restore(void) int error; unsigned int flags; - pr_debug("Loading hibernation image.\n"); + pm_pr_dbg("Loading hibernation image.\n"); lock_device_hotplug(); error = create_basic_memory_bitmaps(); @@ -681,7 +681,7 @@ int hibernate(void) bool snapshot_test = false; if (!hibernation_available()) { - pr_debug("Hibernation not available.\n"); + pm_pr_dbg("Hibernation not available.\n"); return -EPERM; } @@ -692,6 +692,7 @@ int hibernate(void) goto Unlock; } + pr_info("hibernation entry\n"); pm_prepare_console(); error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls); if (error) { @@ -727,7 +728,7 @@ int hibernate(void) else flags |= SF_CRC32_MODE; - pr_debug("Writing image.\n"); + pm_pr_dbg("Writing image.\n"); error = swsusp_write(flags); swsusp_free(); if (!error) { @@ -739,7 +740,7 @@ int hibernate(void) in_suspend = 0; pm_restore_gfp_mask(); } else { - pr_debug("Image restored successfully.\n"); + pm_pr_dbg("Image restored successfully.\n"); } Free_bitmaps: @@ -747,7 +748,7 @@ int hibernate(void) Thaw: unlock_device_hotplug(); if (snapshot_test) { - pr_debug("Checking hibernation image\n"); + pm_pr_dbg("Checking hibernation image\n"); error = swsusp_check(); if (!error) error = load_image_and_restore(); @@ -762,6 +763,8 @@ int hibernate(void) atomic_inc(&snapshot_device_available); Unlock: unlock_system_sleep(); + pr_info("hibernation exit\n"); + return error; } @@ -811,7 +814,7 @@ static int software_resume(void) goto Unlock; } - pr_debug("Checking hibernation image partition %s\n", resume_file); + pm_pr_dbg("Checking hibernation image partition %s\n", resume_file); if (resume_delay) { pr_info("Waiting %dsec before reading resume device ...\n", @@ -853,10 +856,10 @@ static int software_resume(void) } Check_image: - pr_debug("Hibernation image partition %d:%d present\n", + pm_pr_dbg("Hibernation image partition %d:%d present\n", MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); - pr_debug("Looking for hibernation image.\n"); + pm_pr_dbg("Looking for hibernation image.\n"); error = swsusp_check(); if (error) goto Unlock; @@ -868,6 +871,7 @@ static int software_resume(void) goto Unlock; } + pr_info("resume from hibernation\n"); pm_prepare_console(); error = __pm_notifier_call_chain(PM_RESTORE_PREPARE, -1, &nr_calls); if (error) { @@ -875,7 +879,7 @@ static int software_resume(void) goto Close_Finish; } - pr_debug("Preparing processes for restore.\n"); + pm_pr_dbg("Preparing processes for restore.\n"); error = freeze_processes(); if (error) goto Close_Finish; @@ -884,11 +888,12 @@ static int software_resume(void) Finish: __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL); pm_restore_console(); + pr_info("resume from hibernation failed (%d)\n", error); atomic_inc(&snapshot_device_available); /* For success case, the suspend path will release the lock */ Unlock: mutex_unlock(&pm_mutex); - pr_debug("Hibernation image not present or could not be loaded.\n"); + pm_pr_dbg("Hibernation image not present or could not be loaded.\n"); return error; Close_Finish: swsusp_close(FMODE_READ); @@ -1012,8 +1017,8 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, error = -EINVAL; if (!error) - pr_debug("Hibernation mode set to '%s'\n", - hibernation_modes[mode]); + pm_pr_dbg("Hibernation mode set to '%s'\n", + hibernation_modes[mode]); unlock_system_sleep(); return error ? error : n; } diff --git a/kernel/power/main.c b/kernel/power/main.c index 42bd800a6755be14cea9a296aa5c7db57bd7fdea..3a2ca9066583fad36e3b91fe99515058d453a62e 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -150,7 +150,7 @@ static ssize_t mem_sleep_store(struct kobject *kobj, struct kobj_attribute *attr power_attr(mem_sleep); #endif /* CONFIG_SUSPEND */ -#ifdef CONFIG_PM_DEBUG +#ifdef CONFIG_PM_SLEEP_DEBUG int pm_test_level = TEST_NONE; static const char * const pm_tests[__TEST_AFTER_LAST] = { @@ -211,7 +211,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, } power_attr(pm_test); -#endif /* CONFIG_PM_DEBUG */ +#endif /* CONFIG_PM_SLEEP_DEBUG */ #ifdef CONFIG_DEBUG_FS static char *suspend_step_name(enum suspend_stat_step step) @@ -361,6 +361,61 @@ static ssize_t pm_wakeup_irq_show(struct kobject *kobj, power_attr_ro(pm_wakeup_irq); +bool pm_debug_messages_on __read_mostly; + +static ssize_t pm_debug_messages_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", pm_debug_messages_on); +} + +static ssize_t pm_debug_messages_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + unsigned long val; + + if (kstrtoul(buf, 10, &val)) + return -EINVAL; + + if (val > 1) + return -EINVAL; + + pm_debug_messages_on = !!val; + return n; +} + +power_attr(pm_debug_messages); + +/** + * __pm_pr_dbg - Print a suspend debug message to the kernel log. + * @defer: Whether or not to use printk_deferred() to print the message. + * @fmt: Message format. + * + * The message will be emitted if enabled through the pm_debug_messages + * sysfs attribute. + */ +void __pm_pr_dbg(bool defer, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + if (!pm_debug_messages_on) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + if (defer) + printk_deferred(KERN_DEBUG "PM: %pV", &vaf); + else + printk(KERN_DEBUG "PM: %pV", &vaf); + + va_end(args); +} + #else /* !CONFIG_PM_SLEEP_DEBUG */ static inline void pm_print_times_init(void) {} #endif /* CONFIG_PM_SLEEP_DEBUG */ @@ -691,12 +746,11 @@ static struct attribute * g[] = { &wake_lock_attr.attr, &wake_unlock_attr.attr, #endif -#ifdef CONFIG_PM_DEBUG - &pm_test_attr.attr, -#endif #ifdef CONFIG_PM_SLEEP_DEBUG + &pm_test_attr.attr, &pm_print_times_attr.attr, &pm_wakeup_irq_attr.attr, + &pm_debug_messages_attr.attr, #endif #endif #ifdef CONFIG_FREEZER diff --git a/kernel/power/power.h b/kernel/power/power.h index 7fdc40d31b7db455fadbc20569a6b49faa8f01f6..1d2d761e3c25008fbacc139e445cbbc8a325c9d9 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -192,7 +192,6 @@ extern void swsusp_show_speed(ktime_t, ktime_t, unsigned int, char *); extern const char * const pm_labels[]; extern const char *pm_states[]; extern const char *mem_sleep_states[]; -extern suspend_state_t mem_sleep_current; extern int suspend_devices_and_enter(suspend_state_t state); #else /* !CONFIG_SUSPEND */ @@ -245,7 +244,11 @@ enum { #define TEST_FIRST TEST_NONE #define TEST_MAX (__TEST_AFTER_LAST - 1) +#ifdef CONFIG_PM_SLEEP_DEBUG extern int pm_test_level; +#else +#define pm_test_level (TEST_NONE) +#endif #ifdef CONFIG_SUSPEND_FREEZER static inline int suspend_freeze_processes(void) diff --git a/kernel/power/process.c b/kernel/power/process.c index 78672d324a6ef95394ad72a0b0ba29c7d1155d5d..50f25cb370c6e10769b3e7ee359113ea5b4013e2 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -20,8 +20,9 @@ #include #include #include +#include -/* +/* * Timeout for stopping processes */ unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC; @@ -202,6 +203,8 @@ void thaw_processes(void) __usermodehelper_set_disable_depth(UMH_FREEZING); thaw_workqueues(); + cpuset_wait_for_hotplug(); + read_lock(&tasklist_lock); for_each_process_thread(g, p) { /* No other threads should have PF_SUSPEND_TASK set */ diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 222317721c5a09291c6b78fc839e722b2196b177..0972a8e09d082d99c7f197cbe6bd4fdb6475ba33 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -1650,7 +1650,7 @@ static unsigned long minimum_image_size(unsigned long saveable) { unsigned long size; - size = global_page_state(NR_SLAB_RECLAIMABLE) + size = global_node_page_state(NR_SLAB_RECLAIMABLE) + global_node_page_state(NR_ACTIVE_ANON) + global_node_page_state(NR_INACTIVE_ANON) + global_node_page_state(NR_ACTIVE_FILE) diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 3ecf275d7e44ef864bb0bcfa9b03c69f9f050483..ccd2d20e6b067f6a7c3bb83a5848e9c0b333fade 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -8,6 +8,8 @@ * This file is released under the GPLv2. */ +#define pr_fmt(fmt) "PM: " fmt + #include #include #include @@ -33,53 +35,55 @@ #include "power.h" const char * const pm_labels[] = { - [PM_SUSPEND_FREEZE] = "freeze", + [PM_SUSPEND_TO_IDLE] = "freeze", [PM_SUSPEND_STANDBY] = "standby", [PM_SUSPEND_MEM] = "mem", }; const char *pm_states[PM_SUSPEND_MAX]; static const char * const mem_sleep_labels[] = { - [PM_SUSPEND_FREEZE] = "s2idle", + [PM_SUSPEND_TO_IDLE] = "s2idle", [PM_SUSPEND_STANDBY] = "shallow", [PM_SUSPEND_MEM] = "deep", }; const char *mem_sleep_states[PM_SUSPEND_MAX]; -suspend_state_t mem_sleep_current = PM_SUSPEND_FREEZE; -static suspend_state_t mem_sleep_default = PM_SUSPEND_MEM; +suspend_state_t mem_sleep_current = PM_SUSPEND_TO_IDLE; +suspend_state_t mem_sleep_default = PM_SUSPEND_MAX; +suspend_state_t pm_suspend_target_state; +EXPORT_SYMBOL_GPL(pm_suspend_target_state); unsigned int pm_suspend_global_flags; EXPORT_SYMBOL_GPL(pm_suspend_global_flags); static const struct platform_suspend_ops *suspend_ops; -static const struct platform_freeze_ops *freeze_ops; -static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head); +static const struct platform_s2idle_ops *s2idle_ops; +static DECLARE_WAIT_QUEUE_HEAD(s2idle_wait_head); -enum freeze_state __read_mostly suspend_freeze_state; -static DEFINE_SPINLOCK(suspend_freeze_lock); +enum s2idle_states __read_mostly s2idle_state; +static DEFINE_SPINLOCK(s2idle_lock); -void freeze_set_ops(const struct platform_freeze_ops *ops) +void s2idle_set_ops(const struct platform_s2idle_ops *ops) { lock_system_sleep(); - freeze_ops = ops; + s2idle_ops = ops; unlock_system_sleep(); } -static void freeze_begin(void) +static void s2idle_begin(void) { - suspend_freeze_state = FREEZE_STATE_NONE; + s2idle_state = S2IDLE_STATE_NONE; } -static void freeze_enter(void) +static void s2idle_enter(void) { - trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, true); + trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_TO_IDLE, true); - spin_lock_irq(&suspend_freeze_lock); + spin_lock_irq(&s2idle_lock); if (pm_wakeup_pending()) goto out; - suspend_freeze_state = FREEZE_STATE_ENTER; - spin_unlock_irq(&suspend_freeze_lock); + s2idle_state = S2IDLE_STATE_ENTER; + spin_unlock_irq(&s2idle_lock); get_online_cpus(); cpuidle_resume(); @@ -87,56 +91,79 @@ static void freeze_enter(void) /* Push all the CPUs into the idle loop. */ wake_up_all_idle_cpus(); /* Make the current CPU wait so it can enter the idle loop too. */ - wait_event(suspend_freeze_wait_head, - suspend_freeze_state == FREEZE_STATE_WAKE); + wait_event(s2idle_wait_head, + s2idle_state == S2IDLE_STATE_WAKE); cpuidle_pause(); put_online_cpus(); - spin_lock_irq(&suspend_freeze_lock); + spin_lock_irq(&s2idle_lock); out: - suspend_freeze_state = FREEZE_STATE_NONE; - spin_unlock_irq(&suspend_freeze_lock); + s2idle_state = S2IDLE_STATE_NONE; + spin_unlock_irq(&s2idle_lock); - trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, false); + trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_TO_IDLE, false); } static void s2idle_loop(void) { - pr_debug("PM: suspend-to-idle\n"); + pm_pr_dbg("suspend-to-idle\n"); - do { - freeze_enter(); + for (;;) { + int error; + + dpm_noirq_begin(); + + /* + * Suspend-to-idle equals + * frozen processes + suspended devices + idle processors. + * Thus s2idle_enter() should be called right after + * all devices have been suspended. + * + * Wakeups during the noirq suspend of devices may be spurious, + * so prevent them from terminating the loop right away. + */ + error = dpm_noirq_suspend_devices(PMSG_SUSPEND); + if (!error) + s2idle_enter(); + else if (error == -EBUSY && pm_wakeup_pending()) + error = 0; + + if (!error && s2idle_ops && s2idle_ops->wake) + s2idle_ops->wake(); - if (freeze_ops && freeze_ops->wake) - freeze_ops->wake(); + dpm_noirq_resume_devices(PMSG_RESUME); - dpm_resume_noirq(PMSG_RESUME); - if (freeze_ops && freeze_ops->sync) - freeze_ops->sync(); + dpm_noirq_end(); + + if (error) + break; + + if (s2idle_ops && s2idle_ops->sync) + s2idle_ops->sync(); if (pm_wakeup_pending()) break; pm_wakeup_clear(false); - } while (!dpm_suspend_noirq(PMSG_SUSPEND)); + } - pr_debug("PM: resume from suspend-to-idle\n"); + pm_pr_dbg("resume from suspend-to-idle\n"); } -void freeze_wake(void) +void s2idle_wake(void) { unsigned long flags; - spin_lock_irqsave(&suspend_freeze_lock, flags); - if (suspend_freeze_state > FREEZE_STATE_NONE) { - suspend_freeze_state = FREEZE_STATE_WAKE; - wake_up(&suspend_freeze_wait_head); + spin_lock_irqsave(&s2idle_lock, flags); + if (s2idle_state > S2IDLE_STATE_NONE) { + s2idle_state = S2IDLE_STATE_WAKE; + wake_up(&s2idle_wait_head); } - spin_unlock_irqrestore(&suspend_freeze_lock, flags); + spin_unlock_irqrestore(&s2idle_lock, flags); } -EXPORT_SYMBOL_GPL(freeze_wake); +EXPORT_SYMBOL_GPL(s2idle_wake); static bool valid_state(suspend_state_t state) { @@ -152,19 +179,19 @@ void __init pm_states_init(void) { /* "mem" and "freeze" are always present in /sys/power/state. */ pm_states[PM_SUSPEND_MEM] = pm_labels[PM_SUSPEND_MEM]; - pm_states[PM_SUSPEND_FREEZE] = pm_labels[PM_SUSPEND_FREEZE]; + pm_states[PM_SUSPEND_TO_IDLE] = pm_labels[PM_SUSPEND_TO_IDLE]; /* * Suspend-to-idle should be supported even without any suspend_ops, * initialize mem_sleep_states[] accordingly here. */ - mem_sleep_states[PM_SUSPEND_FREEZE] = mem_sleep_labels[PM_SUSPEND_FREEZE]; + mem_sleep_states[PM_SUSPEND_TO_IDLE] = mem_sleep_labels[PM_SUSPEND_TO_IDLE]; } static int __init mem_sleep_default_setup(char *str) { suspend_state_t state; - for (state = PM_SUSPEND_FREEZE; state <= PM_SUSPEND_MEM; state++) + for (state = PM_SUSPEND_TO_IDLE; state <= PM_SUSPEND_MEM; state++) if (mem_sleep_labels[state] && !strcmp(str, mem_sleep_labels[state])) { mem_sleep_default = state; @@ -193,7 +220,7 @@ void suspend_set_ops(const struct platform_suspend_ops *ops) } if (valid_state(PM_SUSPEND_MEM)) { mem_sleep_states[PM_SUSPEND_MEM] = mem_sleep_labels[PM_SUSPEND_MEM]; - if (mem_sleep_default == PM_SUSPEND_MEM) + if (mem_sleep_default >= PM_SUSPEND_MEM) mem_sleep_current = PM_SUSPEND_MEM; } @@ -216,49 +243,49 @@ EXPORT_SYMBOL_GPL(suspend_valid_only_mem); static bool sleep_state_supported(suspend_state_t state) { - return state == PM_SUSPEND_FREEZE || (suspend_ops && suspend_ops->enter); + return state == PM_SUSPEND_TO_IDLE || (suspend_ops && suspend_ops->enter); } static int platform_suspend_prepare(suspend_state_t state) { - return state != PM_SUSPEND_FREEZE && suspend_ops->prepare ? + return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ? suspend_ops->prepare() : 0; } static int platform_suspend_prepare_late(suspend_state_t state) { - return state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->prepare ? - freeze_ops->prepare() : 0; + return state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->prepare ? + s2idle_ops->prepare() : 0; } static int platform_suspend_prepare_noirq(suspend_state_t state) { - return state != PM_SUSPEND_FREEZE && suspend_ops->prepare_late ? + return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare_late ? suspend_ops->prepare_late() : 0; } static void platform_resume_noirq(suspend_state_t state) { - if (state != PM_SUSPEND_FREEZE && suspend_ops->wake) + if (state != PM_SUSPEND_TO_IDLE && suspend_ops->wake) suspend_ops->wake(); } static void platform_resume_early(suspend_state_t state) { - if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->restore) - freeze_ops->restore(); + if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->restore) + s2idle_ops->restore(); } static void platform_resume_finish(suspend_state_t state) { - if (state != PM_SUSPEND_FREEZE && suspend_ops->finish) + if (state != PM_SUSPEND_TO_IDLE && suspend_ops->finish) suspend_ops->finish(); } static int platform_suspend_begin(suspend_state_t state) { - if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) - return freeze_ops->begin(); + if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->begin) + return s2idle_ops->begin(); else if (suspend_ops && suspend_ops->begin) return suspend_ops->begin(state); else @@ -267,21 +294,21 @@ static int platform_suspend_begin(suspend_state_t state) static void platform_resume_end(suspend_state_t state) { - if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end) - freeze_ops->end(); + if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->end) + s2idle_ops->end(); else if (suspend_ops && suspend_ops->end) suspend_ops->end(); } static void platform_recover(suspend_state_t state) { - if (state != PM_SUSPEND_FREEZE && suspend_ops->recover) + if (state != PM_SUSPEND_TO_IDLE && suspend_ops->recover) suspend_ops->recover(); } static bool platform_suspend_again(suspend_state_t state) { - return state != PM_SUSPEND_FREEZE && suspend_ops->suspend_again ? + return state != PM_SUSPEND_TO_IDLE && suspend_ops->suspend_again ? suspend_ops->suspend_again() : false; } @@ -370,16 +397,21 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) error = dpm_suspend_late(PMSG_SUSPEND); if (error) { - pr_err("PM: late suspend of devices failed\n"); + pr_err("late suspend of devices failed\n"); goto Platform_finish; } error = platform_suspend_prepare_late(state); if (error) goto Devices_early_resume; + if (state == PM_SUSPEND_TO_IDLE && pm_test_level != TEST_PLATFORM) { + s2idle_loop(); + goto Platform_early_resume; + } + error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { - pr_err("PM: noirq suspend of devices failed\n"); + pr_err("noirq suspend of devices failed\n"); goto Platform_early_resume; } error = platform_suspend_prepare_noirq(state); @@ -389,17 +421,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) if (suspend_test(TEST_PLATFORM)) goto Platform_wake; - /* - * PM_SUSPEND_FREEZE equals - * frozen processes + suspended devices + idle processors. - * Thus we should invoke freeze_enter() soon after - * all the devices are suspended. - */ - if (state == PM_SUSPEND_FREEZE) { - s2idle_loop(); - goto Platform_early_resume; - } - error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; @@ -456,6 +477,8 @@ int suspend_devices_and_enter(suspend_state_t state) if (!sleep_state_supported(state)) return -ENOSYS; + pm_suspend_target_state = state; + error = platform_suspend_begin(state); if (error) goto Close; @@ -464,7 +487,7 @@ int suspend_devices_and_enter(suspend_state_t state) suspend_test_start(); error = dpm_suspend_start(PMSG_SUSPEND); if (error) { - pr_err("PM: Some devices failed to suspend, or early wake event detected\n"); + pr_err("Some devices failed to suspend, or early wake event detected\n"); goto Recover_platform; } suspend_test_finish("suspend devices"); @@ -485,6 +508,7 @@ int suspend_devices_and_enter(suspend_state_t state) Close: platform_resume_end(state); + pm_suspend_target_state = PM_SUSPEND_ON; return error; Recover_platform: @@ -518,10 +542,10 @@ static int enter_state(suspend_state_t state) int error; trace_suspend_resume(TPS("suspend_enter"), state, true); - if (state == PM_SUSPEND_FREEZE) { + if (state == PM_SUSPEND_TO_IDLE) { #ifdef CONFIG_PM_DEBUG if (pm_test_level != TEST_NONE && pm_test_level <= TEST_CPUS) { - pr_warn("PM: Unsupported test mode for suspend to idle, please choose none/freezer/devices/platform.\n"); + pr_warn("Unsupported test mode for suspend to idle, please choose none/freezer/devices/platform.\n"); return -EAGAIN; } #endif @@ -531,18 +555,18 @@ static int enter_state(suspend_state_t state) if (!mutex_trylock(&pm_mutex)) return -EBUSY; - if (state == PM_SUSPEND_FREEZE) - freeze_begin(); + if (state == PM_SUSPEND_TO_IDLE) + s2idle_begin(); #ifndef CONFIG_SUSPEND_SKIP_SYNC trace_suspend_resume(TPS("sync_filesystems"), 0, true); - pr_info("PM: Syncing filesystems ... "); + pr_info("Syncing filesystems ... "); sys_sync(); pr_cont("done.\n"); trace_suspend_resume(TPS("sync_filesystems"), 0, false); #endif - pr_debug("PM: Preparing system for sleep (%s)\n", pm_states[state]); + pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]); pm_suspend_clear_flags(); error = suspend_prepare(state); if (error) @@ -552,13 +576,13 @@ static int enter_state(suspend_state_t state) goto Finish; trace_suspend_resume(TPS("suspend_enter"), state, false); - pr_debug("PM: Suspending system (%s)\n", pm_states[state]); + pm_pr_dbg("Suspending system (%s)\n", mem_sleep_labels[state]); pm_restrict_gfp_mask(); error = suspend_devices_and_enter(state); pm_restore_gfp_mask(); Finish: - pr_debug("PM: Finishing wakeup.\n"); + pm_pr_dbg("Finishing wakeup.\n"); suspend_finish(); Unlock: mutex_unlock(&pm_mutex); @@ -579,6 +603,7 @@ int pm_suspend(suspend_state_t state) if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) return -EINVAL; + pr_info("suspend entry (%s)\n", mem_sleep_labels[state]); error = enter_state(state); if (error) { suspend_stats.fail++; @@ -586,6 +611,7 @@ int pm_suspend(suspend_state_t state) } else { suspend_stats.success++; } + pr_info("suspend exit\n"); return error; } EXPORT_SYMBOL(pm_suspend); diff --git a/kernel/power/suspend_test.c b/kernel/power/suspend_test.c index 5db217051232de97afcc20208ee504ae3d06a430..6a897e8b2a8886c99f7725d1215ab6fe742caf28 100644 --- a/kernel/power/suspend_test.c +++ b/kernel/power/suspend_test.c @@ -104,9 +104,9 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) printk(info_test, pm_states[state]); status = pm_suspend(state); if (status < 0) - state = PM_SUSPEND_FREEZE; + state = PM_SUSPEND_TO_IDLE; } - if (state == PM_SUSPEND_FREEZE) { + if (state == PM_SUSPEND_TO_IDLE) { printk(info_test, pm_states[state]); status = pm_suspend(state); } diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 57d22571f3068bdecf36a3ac0f8d8566d5f7c455..d7cdc426ee3809bbaafdfd9d5698f83db654e23a 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -242,8 +242,7 @@ static void hib_end_io(struct bio *bio) if (bio->bi_status) { printk(KERN_ALERT "Read-error on swap-device (%u:%u:%Lu)\n", - imajor(bio->bi_bdev->bd_inode), - iminor(bio->bi_bdev->bd_inode), + MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)), (unsigned long long)bio->bi_iter.bi_sector); } @@ -270,7 +269,7 @@ static int hib_submit_io(int op, int op_flags, pgoff_t page_off, void *addr, bio = bio_alloc(__GFP_RECLAIM | __GFP_HIGH, 1); bio->bi_iter.bi_sector = page_off * (PAGE_SIZE >> 9); - bio->bi_bdev = hib_resume_bdev; + bio_set_dev(bio, hib_resume_bdev); bio_set_op_attrs(bio, op, op_flags); if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index fc47863f629cf4b86f7e26298220a2511d1dd1df..512f7c2baedd59bef5300e361c22e92b7a4845a0 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -649,7 +649,7 @@ static int syslog_action_restricted(int type) type != SYSLOG_ACTION_SIZE_BUFFER; } -int check_syslog_permissions(int type, int source) +static int check_syslog_permissions(int type, int source) { /* * If this is from /proc/kmsg and we've already opened it, then we've @@ -677,7 +677,6 @@ int check_syslog_permissions(int type, int source) ok: return security_syslog(type); } -EXPORT_SYMBOL_GPL(check_syslog_permissions); static void append_char(char **pp, char *e, char c) { @@ -1435,7 +1434,7 @@ int do_syslog(int type, char __user *buf, int len, int source) error = check_syslog_permissions(type, source); if (error) - goto out; + return error; switch (type) { case SYSLOG_ACTION_CLOSE: /* Close log */ @@ -1443,20 +1442,16 @@ int do_syslog(int type, char __user *buf, int len, int source) case SYSLOG_ACTION_OPEN: /* Open log */ break; case SYSLOG_ACTION_READ: /* Read from log */ - error = -EINVAL; if (!buf || len < 0) - goto out; - error = 0; + return -EINVAL; if (!len) - goto out; - if (!access_ok(VERIFY_WRITE, buf, len)) { - error = -EFAULT; - goto out; - } + return 0; + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; error = wait_event_interruptible(log_wait, syslog_seq != log_next_seq); if (error) - goto out; + return error; error = syslog_print(buf, len); break; /* Read/clear last kernel messages */ @@ -1465,16 +1460,12 @@ int do_syslog(int type, char __user *buf, int len, int source) /* FALL THRU */ /* Read last kernel messages */ case SYSLOG_ACTION_READ_ALL: - error = -EINVAL; if (!buf || len < 0) - goto out; - error = 0; + return -EINVAL; if (!len) - goto out; - if (!access_ok(VERIFY_WRITE, buf, len)) { - error = -EFAULT; - goto out; - } + return 0; + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; error = syslog_print_all(buf, len, clear); break; /* Clear ring buffer */ @@ -1496,15 +1487,13 @@ int do_syslog(int type, char __user *buf, int len, int source) break; /* Set level of messages printed to console */ case SYSLOG_ACTION_CONSOLE_LEVEL: - error = -EINVAL; if (len < 1 || len > 8) - goto out; + return -EINVAL; if (len < minimum_console_loglevel) len = minimum_console_loglevel; console_loglevel = len; /* Implicitly re-enable logging to console */ saved_console_loglevel = LOGLEVEL_DEFAULT; - error = 0; break; /* Number of chars in the log buffer */ case SYSLOG_ACTION_SIZE_UNREAD: @@ -1526,7 +1515,6 @@ int do_syslog(int type, char __user *buf, int len, int source) u64 seq = syslog_seq; u32 idx = syslog_idx; - error = 0; while (seq < log_next_seq) { struct printk_log *msg = log_from_idx(idx); @@ -1546,7 +1534,7 @@ int do_syslog(int type, char __user *buf, int len, int source) error = -EINVAL; break; } -out: + return error; } @@ -1698,10 +1686,10 @@ asmlinkage int vprintk_emit(int facility, int level, { static char textbuf[LOG_LINE_MAX]; char *text = textbuf; - size_t text_len = 0; + size_t text_len; enum log_flags lflags = 0; unsigned long flags; - int printed_len = 0; + int printed_len; bool in_sched = false; if (level == LOGLEVEL_SCHED) { @@ -1754,7 +1742,7 @@ asmlinkage int vprintk_emit(int facility, int level, if (dict) lflags |= LOG_PREFIX|LOG_NEWLINE; - printed_len += log_output(facility, level, lflags, dict, dictlen, text, text_len); + printed_len = log_output(facility, level, lflags, dict, dictlen, text, text_len); logbuf_unlock_irqrestore(flags); @@ -2650,9 +2638,8 @@ void __init console_init(void) * makes it difficult to diagnose problems that occur during this time. * * To mitigate this problem somewhat, only unregister consoles whose memory - * intersects with the init section. Note that code exists elsewhere to get - * rid of the boot console as soon as the proper console shows up, so there - * won't be side-effects from postponing the removal. + * intersects with the init section. Note that all other boot consoles will + * get unregistred when the real preferred console is registered. */ static int __init printk_late_init(void) { @@ -2660,16 +2647,23 @@ static int __init printk_late_init(void) int ret; for_each_console(con) { - if (!keep_bootcon && con->flags & CON_BOOT) { + if (!(con->flags & CON_BOOT)) + continue; + + /* Check addresses that might be used for enabled consoles. */ + if (init_section_intersects(con, sizeof(*con)) || + init_section_contains(con->write, 0) || + init_section_contains(con->read, 0) || + init_section_contains(con->device, 0) || + init_section_contains(con->unblank, 0) || + init_section_contains(con->data, 0)) { /* - * Make sure to unregister boot consoles whose data - * resides in the init section before the init section - * is discarded. Boot consoles whose data will stick - * around will automatically be unregistered when the - * proper console replaces them. + * Please, consider moving the reported consoles out + * of the init section. */ - if (init_section_intersects(con, sizeof(*con))) - unregister_console(con); + pr_warn("bootconsole [%s%d] uses init memory and must be disabled even before the real one is ready\n", + con->name, con->index); + unregister_console(con); } } ret = cpuhp_setup_state_nocalls(CPUHP_PRINTK_DEAD, "printk:dead", NULL, diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 60f356d91060c8974268cc5bc02d57c75d359afc..84b1367935e410f79770c06efadc20deb51346b3 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -728,8 +728,7 @@ static int ptrace_peek_siginfo(struct task_struct *child, if (unlikely(in_compat_syscall())) { compat_siginfo_t __user *uinfo = compat_ptr(data); - if (copy_siginfo_to_user32(uinfo, &info) || - __put_user(info.si_code, &uinfo->si_code)) { + if (copy_siginfo_to_user32(uinfo, &info)) { ret = -EFAULT; break; } @@ -739,8 +738,7 @@ static int ptrace_peek_siginfo(struct task_struct *child, { siginfo_t __user *uinfo = (siginfo_t __user *) data; - if (copy_siginfo_to_user(uinfo, &info) || - __put_user(info.si_code, &uinfo->si_code)) { + if (copy_siginfo_to_user(uinfo, &info)) { ret = -EFAULT; break; } diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig index be90c945063f46b7ba1368aed5c6fc970e9b6e98..9210379c0353676b79bc92e0c872fb41f1ba5693 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -69,8 +69,7 @@ config TREE_SRCU This option selects the full-fledged version of SRCU. config TASKS_RCU - bool - default n + def_bool PREEMPT select SRCU help This option enables a task-based RCU implementation that uses diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index 808b8c85f626f9647c70081a0f1a98c0df001d6a..e4b43fef89f5e12c5d4e0125d2500aff28bbde5f 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h @@ -356,22 +356,10 @@ do { \ #ifdef CONFIG_TINY_RCU /* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */ -static inline bool rcu_gp_is_normal(void) /* Internal RCU use. */ -{ - return true; -} -static inline bool rcu_gp_is_expedited(void) /* Internal RCU use. */ -{ - return false; -} - -static inline void rcu_expedite_gp(void) -{ -} - -static inline void rcu_unexpedite_gp(void) -{ -} +static inline bool rcu_gp_is_normal(void) { return true; } +static inline bool rcu_gp_is_expedited(void) { return false; } +static inline void rcu_expedite_gp(void) { } +static inline void rcu_unexpedite_gp(void) { } #else /* #ifdef CONFIG_TINY_RCU */ bool rcu_gp_is_normal(void); /* Internal RCU use. */ bool rcu_gp_is_expedited(void); /* Internal RCU use. */ @@ -419,12 +407,8 @@ static inline void rcutorture_get_gp_data(enum rcutorture_type test_type, *gpnum = 0; *completed = 0; } -static inline void rcutorture_record_test_transition(void) -{ -} -static inline void rcutorture_record_progress(unsigned long vernum) -{ -} +static inline void rcutorture_record_test_transition(void) { } +static inline void rcutorture_record_progress(unsigned long vernum) { } #ifdef CONFIG_RCU_TRACE void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp, @@ -460,92 +444,20 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type, #endif #ifdef CONFIG_TINY_RCU - -/* - * Return the number of grace periods started. - */ -static inline unsigned long rcu_batches_started(void) -{ - return 0; -} - -/* - * Return the number of bottom-half grace periods started. - */ -static inline unsigned long rcu_batches_started_bh(void) -{ - return 0; -} - -/* - * Return the number of sched grace periods started. - */ -static inline unsigned long rcu_batches_started_sched(void) -{ - return 0; -} - -/* - * Return the number of grace periods completed. - */ -static inline unsigned long rcu_batches_completed(void) -{ - return 0; -} - -/* - * Return the number of bottom-half grace periods completed. - */ -static inline unsigned long rcu_batches_completed_bh(void) -{ - return 0; -} - -/* - * Return the number of sched grace periods completed. - */ -static inline unsigned long rcu_batches_completed_sched(void) -{ - return 0; -} - -/* - * Return the number of expedited grace periods completed. - */ -static inline unsigned long rcu_exp_batches_completed(void) -{ - return 0; -} - -/* - * Return the number of expedited sched grace periods completed. - */ -static inline unsigned long rcu_exp_batches_completed_sched(void) -{ - return 0; -} - -static inline unsigned long srcu_batches_completed(struct srcu_struct *sp) -{ - return 0; -} - -static inline void rcu_force_quiescent_state(void) -{ -} - -static inline void rcu_bh_force_quiescent_state(void) -{ -} - -static inline void rcu_sched_force_quiescent_state(void) -{ -} - -static inline void show_rcu_gp_kthreads(void) -{ -} - +static inline unsigned long rcu_batches_started(void) { return 0; } +static inline unsigned long rcu_batches_started_bh(void) { return 0; } +static inline unsigned long rcu_batches_started_sched(void) { return 0; } +static inline unsigned long rcu_batches_completed(void) { return 0; } +static inline unsigned long rcu_batches_completed_bh(void) { return 0; } +static inline unsigned long rcu_batches_completed_sched(void) { return 0; } +static inline unsigned long rcu_exp_batches_completed(void) { return 0; } +static inline unsigned long rcu_exp_batches_completed_sched(void) { return 0; } +static inline unsigned long +srcu_batches_completed(struct srcu_struct *sp) { return 0; } +static inline void rcu_force_quiescent_state(void) { } +static inline void rcu_bh_force_quiescent_state(void) { } +static inline void rcu_sched_force_quiescent_state(void) { } +static inline void show_rcu_gp_kthreads(void) { } #else /* #ifdef CONFIG_TINY_RCU */ extern unsigned long rcutorture_testseq; extern unsigned long rcutorture_vernum; diff --git a/kernel/rcu/rcu_segcblist.c b/kernel/rcu/rcu_segcblist.c index 2b62a38b080fa5e04af36635f2d6dcedffe8c21e..7649fcd2c4c7de0504c4113309f2aa8a9757adb3 100644 --- a/kernel/rcu/rcu_segcblist.c +++ b/kernel/rcu/rcu_segcblist.c @@ -35,24 +35,6 @@ void rcu_cblist_init(struct rcu_cblist *rclp) rclp->len_lazy = 0; } -/* - * Debug function to actually count the number of callbacks. - * If the number exceeds the limit specified, return -1. - */ -long rcu_cblist_count_cbs(struct rcu_cblist *rclp, long lim) -{ - int cnt = 0; - struct rcu_head **rhpp = &rclp->head; - - for (;;) { - if (!*rhpp) - return cnt; - if (++cnt > lim) - return -1; - rhpp = &(*rhpp)->next; - } -} - /* * Dequeue the oldest rcu_head structure from the specified callback * list. This function assumes that the callback is non-lazy, but @@ -102,17 +84,6 @@ void rcu_segcblist_disable(struct rcu_segcblist *rsclp) rsclp->tails[RCU_NEXT_TAIL] = NULL; } -/* - * Is the specified segment of the specified rcu_segcblist structure - * empty of callbacks? - */ -bool rcu_segcblist_segempty(struct rcu_segcblist *rsclp, int seg) -{ - if (seg == RCU_DONE_TAIL) - return &rsclp->head == rsclp->tails[RCU_DONE_TAIL]; - return rsclp->tails[seg - 1] == rsclp->tails[seg]; -} - /* * Does the specified rcu_segcblist structure contain callbacks that * are ready to be invoked? @@ -133,50 +104,6 @@ bool rcu_segcblist_pend_cbs(struct rcu_segcblist *rsclp) !rcu_segcblist_restempty(rsclp, RCU_DONE_TAIL); } -/* - * Dequeue and return the first ready-to-invoke callback. If there - * are no ready-to-invoke callbacks, return NULL. Disables interrupts - * to avoid interference. Does not protect from interference from other - * CPUs or tasks. - */ -struct rcu_head *rcu_segcblist_dequeue(struct rcu_segcblist *rsclp) -{ - unsigned long flags; - int i; - struct rcu_head *rhp; - - local_irq_save(flags); - if (!rcu_segcblist_ready_cbs(rsclp)) { - local_irq_restore(flags); - return NULL; - } - rhp = rsclp->head; - BUG_ON(!rhp); - rsclp->head = rhp->next; - for (i = RCU_DONE_TAIL; i < RCU_CBLIST_NSEGS; i++) { - if (rsclp->tails[i] != &rhp->next) - break; - rsclp->tails[i] = &rsclp->head; - } - smp_mb(); /* Dequeue before decrement for rcu_barrier(). */ - WRITE_ONCE(rsclp->len, rsclp->len - 1); - local_irq_restore(flags); - return rhp; -} - -/* - * Account for the fact that a previously dequeued callback turned out - * to be marked as lazy. - */ -void rcu_segcblist_dequeued_lazy(struct rcu_segcblist *rsclp) -{ - unsigned long flags; - - local_irq_save(flags); - rsclp->len_lazy--; - local_irq_restore(flags); -} - /* * Return a pointer to the first callback in the specified rcu_segcblist * structure. This is useful for diagnostics. @@ -202,17 +129,6 @@ struct rcu_head *rcu_segcblist_first_pend_cb(struct rcu_segcblist *rsclp) return NULL; } -/* - * Does the specified rcu_segcblist structure contain callbacks that - * have not yet been processed beyond having been posted, that is, - * does it contain callbacks in its last segment? - */ -bool rcu_segcblist_new_cbs(struct rcu_segcblist *rsclp) -{ - return rcu_segcblist_is_enabled(rsclp) && - !rcu_segcblist_restempty(rsclp, RCU_NEXT_READY_TAIL); -} - /* * Enqueue the specified callback onto the specified rcu_segcblist * structure, updating accounting as needed. Note that the ->len @@ -503,3 +419,27 @@ bool rcu_segcblist_future_gp_needed(struct rcu_segcblist *rsclp, return true; return false; } + +/* + * Merge the source rcu_segcblist structure into the destination + * rcu_segcblist structure, then initialize the source. Any pending + * callbacks from the source get to start over. It is best to + * advance and accelerate both the destination and the source + * before merging. + */ +void rcu_segcblist_merge(struct rcu_segcblist *dst_rsclp, + struct rcu_segcblist *src_rsclp) +{ + struct rcu_cblist donecbs; + struct rcu_cblist pendcbs; + + rcu_cblist_init(&donecbs); + rcu_cblist_init(&pendcbs); + rcu_segcblist_extract_count(src_rsclp, &donecbs); + rcu_segcblist_extract_done_cbs(src_rsclp, &donecbs); + rcu_segcblist_extract_pend_cbs(src_rsclp, &pendcbs); + rcu_segcblist_insert_count(dst_rsclp, &donecbs); + rcu_segcblist_insert_done_cbs(dst_rsclp, &donecbs); + rcu_segcblist_insert_pend_cbs(dst_rsclp, &pendcbs); + rcu_segcblist_init(src_rsclp); +} diff --git a/kernel/rcu/rcu_segcblist.h b/kernel/rcu/rcu_segcblist.h index 6e36e36478cd3f57338260904eb9335d3e0b85a5..581c12b6354434f7a847e7560514aaa58c7a3777 100644 --- a/kernel/rcu/rcu_segcblist.h +++ b/kernel/rcu/rcu_segcblist.h @@ -31,29 +31,7 @@ static inline void rcu_cblist_dequeued_lazy(struct rcu_cblist *rclp) rclp->len_lazy--; } -/* - * Interim function to return rcu_cblist head pointer. Longer term, the - * rcu_cblist will be used more pervasively, removing the need for this - * function. - */ -static inline struct rcu_head *rcu_cblist_head(struct rcu_cblist *rclp) -{ - return rclp->head; -} - -/* - * Interim function to return rcu_cblist head pointer. Longer term, the - * rcu_cblist will be used more pervasively, removing the need for this - * function. - */ -static inline struct rcu_head **rcu_cblist_tail(struct rcu_cblist *rclp) -{ - WARN_ON_ONCE(!rclp->head); - return rclp->tail; -} - void rcu_cblist_init(struct rcu_cblist *rclp); -long rcu_cblist_count_cbs(struct rcu_cblist *rclp, long lim); struct rcu_head *rcu_cblist_dequeue(struct rcu_cblist *rclp); /* @@ -134,14 +112,10 @@ static inline struct rcu_head **rcu_segcblist_tail(struct rcu_segcblist *rsclp) void rcu_segcblist_init(struct rcu_segcblist *rsclp); void rcu_segcblist_disable(struct rcu_segcblist *rsclp); -bool rcu_segcblist_segempty(struct rcu_segcblist *rsclp, int seg); bool rcu_segcblist_ready_cbs(struct rcu_segcblist *rsclp); bool rcu_segcblist_pend_cbs(struct rcu_segcblist *rsclp); -struct rcu_head *rcu_segcblist_dequeue(struct rcu_segcblist *rsclp); -void rcu_segcblist_dequeued_lazy(struct rcu_segcblist *rsclp); struct rcu_head *rcu_segcblist_first_cb(struct rcu_segcblist *rsclp); struct rcu_head *rcu_segcblist_first_pend_cb(struct rcu_segcblist *rsclp); -bool rcu_segcblist_new_cbs(struct rcu_segcblist *rsclp); void rcu_segcblist_enqueue(struct rcu_segcblist *rsclp, struct rcu_head *rhp, bool lazy); bool rcu_segcblist_entrain(struct rcu_segcblist *rsclp, @@ -162,3 +136,5 @@ void rcu_segcblist_advance(struct rcu_segcblist *rsclp, unsigned long seq); bool rcu_segcblist_accelerate(struct rcu_segcblist *rsclp, unsigned long seq); bool rcu_segcblist_future_gp_needed(struct rcu_segcblist *rsclp, unsigned long seq); +void rcu_segcblist_merge(struct rcu_segcblist *dst_rsclp, + struct rcu_segcblist *src_rsclp); diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c index 3cc18110b61213128f5aec484352f3296ffb3e6b..1f87a02c33999087ad0504b9c42c63b2d3fd5d2e 100644 --- a/kernel/rcu/rcuperf.c +++ b/kernel/rcu/rcuperf.c @@ -317,8 +317,6 @@ static struct rcu_perf_ops sched_ops = { .name = "sched" }; -#ifdef CONFIG_TASKS_RCU - /* * Definitions for RCU-tasks perf testing. */ @@ -346,24 +344,11 @@ static struct rcu_perf_ops tasks_ops = { .name = "tasks" }; -#define RCUPERF_TASKS_OPS &tasks_ops, - static bool __maybe_unused torturing_tasks(void) { return cur_ops == &tasks_ops; } -#else /* #ifdef CONFIG_TASKS_RCU */ - -#define RCUPERF_TASKS_OPS - -static bool __maybe_unused torturing_tasks(void) -{ - return false; -} - -#endif /* #else #ifdef CONFIG_TASKS_RCU */ - /* * If performance tests complete, wait for shutdown to commence. */ @@ -658,7 +643,7 @@ rcu_perf_init(void) int firsterr = 0; static struct rcu_perf_ops *perf_ops[] = { &rcu_ops, &rcu_bh_ops, &srcu_ops, &srcud_ops, &sched_ops, - RCUPERF_TASKS_OPS + &tasks_ops, }; if (!torture_init_begin(perf_type, verbose, &perf_runnable)) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index b8f7f8ce8575dda9092cbaa18f1134b0cf1a06c5..45f2ffbc1e78ed587d26d6764cb8d1aba0f6f2d8 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -199,7 +199,8 @@ MODULE_PARM_DESC(torture_runnable, "Start rcutorture at boot"); static u64 notrace rcu_trace_clock_local(void) { u64 ts = trace_clock_local(); - unsigned long __maybe_unused ts_rem = do_div(ts, NSEC_PER_USEC); + + (void)do_div(ts, NSEC_PER_USEC); return ts; } #else /* #ifdef CONFIG_RCU_TRACE */ @@ -496,7 +497,7 @@ static struct rcu_torture_ops rcu_busted_ops = { .fqs = NULL, .stats = NULL, .irq_capable = 1, - .name = "rcu_busted" + .name = "busted" }; /* @@ -522,7 +523,7 @@ static void srcu_read_delay(struct torture_random_state *rrsp) delay = torture_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick); - if (!delay) + if (!delay && in_task()) schedule_timeout_interruptible(longdelay); else rcu_read_delay(rrsp); @@ -561,44 +562,7 @@ static void srcu_torture_barrier(void) static void srcu_torture_stats(void) { - int __maybe_unused cpu; - int idx; - -#ifdef CONFIG_TREE_SRCU - idx = srcu_ctlp->srcu_idx & 0x1; - pr_alert("%s%s Tree SRCU per-CPU(idx=%d):", - torture_type, TORTURE_FLAG, idx); - for_each_possible_cpu(cpu) { - unsigned long l0, l1; - unsigned long u0, u1; - long c0, c1; - struct srcu_data *counts; - - counts = per_cpu_ptr(srcu_ctlp->sda, cpu); - u0 = counts->srcu_unlock_count[!idx]; - u1 = counts->srcu_unlock_count[idx]; - - /* - * Make sure that a lock is always counted if the corresponding - * unlock is counted. - */ - smp_rmb(); - - l0 = counts->srcu_lock_count[!idx]; - l1 = counts->srcu_lock_count[idx]; - - c0 = l0 - u0; - c1 = l1 - u1; - pr_cont(" %d(%ld,%ld)", cpu, c0, c1); - } - pr_cont("\n"); -#elif defined(CONFIG_TINY_SRCU) - idx = READ_ONCE(srcu_ctlp->srcu_idx) & 0x1; - pr_alert("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n", - torture_type, TORTURE_FLAG, idx, - READ_ONCE(srcu_ctlp->srcu_lock_nesting[!idx]), - READ_ONCE(srcu_ctlp->srcu_lock_nesting[idx])); -#endif + srcu_torture_stats_print(srcu_ctlp, torture_type, TORTURE_FLAG); } static void srcu_torture_synchronize_expedited(void) @@ -620,6 +584,7 @@ static struct rcu_torture_ops srcu_ops = { .call = srcu_torture_call, .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, + .irq_capable = 1, .name = "srcu" }; @@ -652,6 +617,7 @@ static struct rcu_torture_ops srcud_ops = { .call = srcu_torture_call, .cb_barrier = srcu_torture_barrier, .stats = srcu_torture_stats, + .irq_capable = 1, .name = "srcud" }; @@ -696,8 +662,6 @@ static struct rcu_torture_ops sched_ops = { .name = "sched" }; -#ifdef CONFIG_TASKS_RCU - /* * Definitions for RCU-tasks torture testing. */ @@ -735,24 +699,11 @@ static struct rcu_torture_ops tasks_ops = { .name = "tasks" }; -#define RCUTORTURE_TASKS_OPS &tasks_ops, - static bool __maybe_unused torturing_tasks(void) { return cur_ops == &tasks_ops; } -#else /* #ifdef CONFIG_TASKS_RCU */ - -#define RCUTORTURE_TASKS_OPS - -static bool __maybe_unused torturing_tasks(void) -{ - return false; -} - -#endif /* #else #ifdef CONFIG_TASKS_RCU */ - /* * RCU torture priority-boost testing. Runs one real-time thread per * CPU for moderate bursts, repeatedly registering RCU callbacks and @@ -1114,6 +1065,11 @@ rcu_torture_fakewriter(void *arg) return 0; } +static void rcu_torture_timer_cb(struct rcu_head *rhp) +{ + kfree(rhp); +} + /* * RCU torture reader from timer handler. Dereferences rcu_torture_current, * incrementing the corresponding element of the pipeline array. The @@ -1176,6 +1132,14 @@ static void rcu_torture_timer(unsigned long unused) __this_cpu_inc(rcu_torture_batch[completed]); preempt_enable(); cur_ops->readunlock(idx); + + /* Test call_rcu() invocation from interrupt handler. */ + if (cur_ops->call) { + struct rcu_head *rhp = kmalloc(sizeof(*rhp), GFP_NOWAIT); + + if (rhp) + cur_ops->call(rhp, rcu_torture_timer_cb); + } } /* @@ -1354,11 +1318,12 @@ rcu_torture_stats_print(void) srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp, &flags, &gpnum, &completed); wtp = READ_ONCE(writer_task); - pr_alert("??? Writer stall state %s(%d) g%lu c%lu f%#x ->state %#lx\n", + pr_alert("??? Writer stall state %s(%d) g%lu c%lu f%#x ->state %#lx cpu %d\n", rcu_torture_writer_state_getname(), rcu_torture_writer_state, gpnum, completed, flags, - wtp == NULL ? ~0UL : wtp->state); + wtp == NULL ? ~0UL : wtp->state, + wtp == NULL ? -1 : (int)task_cpu(wtp)); show_rcu_gp_kthreads(); rcu_ftrace_dump(DUMP_ALL); } @@ -1749,7 +1714,7 @@ rcu_torture_init(void) int firsterr = 0; static struct rcu_torture_ops *torture_ops[] = { &rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &srcud_ops, - &sched_ops, RCUTORTURE_TASKS_OPS + &sched_ops, &tasks_ops, }; if (!torture_init_begin(torture_type, verbose, &torture_runnable)) diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c index 1a1c1047d2edecaba7691d8c6f9fd3851c3c434a..76ac5f50b2c796eb545403d1cb0cd23281957382 100644 --- a/kernel/rcu/srcutiny.c +++ b/kernel/rcu/srcutiny.c @@ -33,6 +33,8 @@ #include "rcu_segcblist.h" #include "rcu.h" +int rcu_scheduler_active __read_mostly; + static int init_srcu_struct_fields(struct srcu_struct *sp) { sp->srcu_lock_nesting[0] = 0; @@ -193,3 +195,9 @@ void synchronize_srcu(struct srcu_struct *sp) destroy_rcu_head_on_stack(&rs.head); } EXPORT_SYMBOL_GPL(synchronize_srcu); + +/* Lockdep diagnostics. */ +void __init rcu_scheduler_starting(void) +{ + rcu_scheduler_active = RCU_SCHEDULER_RUNNING; +} diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index d0ca524bf042f24fa5baed83021d983577a17c45..729a8706751db4230bf3e3275192475fb44f9c3a 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -51,6 +51,7 @@ module_param(counter_wrap_check, ulong, 0444); static void srcu_invoke_callbacks(struct work_struct *work); static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay); +static void process_srcu(struct work_struct *work); /* * Initialize SRCU combining tree. Note that statically allocated @@ -896,6 +897,15 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool do_norm) __call_srcu(sp, &rcu.head, wakeme_after_rcu, do_norm); wait_for_completion(&rcu.completion); destroy_rcu_head_on_stack(&rcu.head); + + /* + * Make sure that later code is ordered after the SRCU grace + * period. This pairs with the raw_spin_lock_irq_rcu_node() + * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed + * because the current CPU might have been totally uninvolved with + * (and thus unordered against) that grace period. + */ + smp_mb(); } /** @@ -1194,7 +1204,7 @@ static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay) /* * This is the work-queue function that handles SRCU grace periods. */ -void process_srcu(struct work_struct *work) +static void process_srcu(struct work_struct *work) { struct srcu_struct *sp; @@ -1203,7 +1213,6 @@ void process_srcu(struct work_struct *work) srcu_advance_state(sp); srcu_reschedule(sp, srcu_get_delay(sp)); } -EXPORT_SYMBOL_GPL(process_srcu); void srcutorture_get_gp_data(enum rcutorture_type test_type, struct srcu_struct *sp, int *flags, @@ -1217,6 +1226,43 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type, } EXPORT_SYMBOL_GPL(srcutorture_get_gp_data); +void srcu_torture_stats_print(struct srcu_struct *sp, char *tt, char *tf) +{ + int cpu; + int idx; + unsigned long s0 = 0, s1 = 0; + + idx = sp->srcu_idx & 0x1; + pr_alert("%s%s Tree SRCU per-CPU(idx=%d):", tt, tf, idx); + for_each_possible_cpu(cpu) { + unsigned long l0, l1; + unsigned long u0, u1; + long c0, c1; + struct srcu_data *counts; + + counts = per_cpu_ptr(sp->sda, cpu); + u0 = counts->srcu_unlock_count[!idx]; + u1 = counts->srcu_unlock_count[idx]; + + /* + * Make sure that a lock is always counted if the corresponding + * unlock is counted. + */ + smp_rmb(); + + l0 = counts->srcu_lock_count[!idx]; + l1 = counts->srcu_lock_count[idx]; + + c0 = l0 - u0; + c1 = l1 - u1; + pr_cont(" %d(%ld,%ld)", cpu, c0, c1); + s0 += c0; + s1 += c1; + } + pr_cont(" T(%ld,%ld)\n", s0, s1); +} +EXPORT_SYMBOL_GPL(srcu_torture_stats_print); + static int __init srcu_bootup_announce(void) { pr_info("Hierarchical SRCU implementation.\n"); diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c index f8488965250f12ce26d40ba31553b8128ef55023..a64eee0db39e3642c33e69c55535619e363c0b55 100644 --- a/kernel/rcu/tiny.c +++ b/kernel/rcu/tiny.c @@ -56,8 +56,6 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk = { .curtail = &rcu_bh_ctrlblk.rcucblist, }; -#include "tiny_plugin.h" - void rcu_barrier_bh(void) { wait_rcu_gp(call_rcu_bh); diff --git a/kernel/rcu/tiny_plugin.h b/kernel/rcu/tiny_plugin.h deleted file mode 100644 index f0a01b2a30623e70cc8e05d112b29c521b0db435..0000000000000000000000000000000000000000 --- a/kernel/rcu/tiny_plugin.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition - * Internal non-public definitions that provide either classic - * or preemptible semantics. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can access it online at - * http://www.gnu.org/licenses/gpl-2.0.html. - * - * Copyright (c) 2010 Linaro - * - * Author: Paul E. McKenney - */ - -#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) -#include - -int rcu_scheduler_active __read_mostly; -EXPORT_SYMBOL_GPL(rcu_scheduler_active); - -/* - * During boot, we forgive RCU lockdep issues. After this function is - * invoked, we start taking RCU lockdep issues seriously. Note that unlike - * Tree RCU, Tiny RCU transitions directly from RCU_SCHEDULER_INACTIVE - * to RCU_SCHEDULER_RUNNING, skipping the RCU_SCHEDULER_INIT stage. - * The reason for this is that Tiny RCU does not need kthreads, so does - * not have to care about the fact that the scheduler is half-initialized - * at a certain phase of the boot process. Unless SRCU is in the mix. - */ -void __init rcu_scheduler_starting(void) -{ - WARN_ON(nr_context_switches() > 0); - rcu_scheduler_active = IS_ENABLED(CONFIG_SRCU) - ? RCU_SCHEDULER_INIT : RCU_SCHEDULER_RUNNING; -} - -#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) */ diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 51d4c3acf32d40dff46610919602909f3372fd27..b0ad62b0e7b8f8028d20694d79e144e4e07ec9c0 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -97,9 +97,6 @@ struct rcu_state sname##_state = { \ .gp_state = RCU_GP_IDLE, \ .gpnum = 0UL - 300UL, \ .completed = 0UL - 300UL, \ - .orphan_lock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.orphan_lock), \ - .orphan_pend = RCU_CBLIST_INITIALIZER(sname##_state.orphan_pend), \ - .orphan_done = RCU_CBLIST_INITIALIZER(sname##_state.orphan_done), \ .barrier_mutex = __MUTEX_INITIALIZER(sname##_state.barrier_mutex), \ .name = RCU_STATE_NAME(sname), \ .abbr = sabbr, \ @@ -843,13 +840,9 @@ static void rcu_eqs_enter(bool user) */ void rcu_idle_enter(void) { - unsigned long flags; - - local_irq_save(flags); + RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_idle_enter() invoked with irqs enabled!!!"); rcu_eqs_enter(false); - local_irq_restore(flags); } -EXPORT_SYMBOL_GPL(rcu_idle_enter); #ifdef CONFIG_NO_HZ_FULL /** @@ -862,7 +855,8 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter); */ void rcu_user_enter(void) { - rcu_eqs_enter(1); + RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_user_enter() invoked with irqs enabled!!!"); + rcu_eqs_enter(true); } #endif /* CONFIG_NO_HZ_FULL */ @@ -888,6 +882,11 @@ void rcu_irq_exit(void) RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); rdtp = this_cpu_ptr(&rcu_dynticks); + + /* Page faults can happen in NMI handlers, so check... */ + if (rdtp->dynticks_nmi_nesting) + return; + WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && rdtp->dynticks_nesting < 1); if (rdtp->dynticks_nesting <= 1) { @@ -955,8 +954,10 @@ static void rcu_eqs_exit(bool user) if (oldval & DYNTICK_TASK_NEST_MASK) { rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE; } else { + __this_cpu_inc(disable_rcu_irq_enter); rdtp->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE; rcu_eqs_exit_common(oldval, user); + __this_cpu_dec(disable_rcu_irq_enter); } } @@ -979,7 +980,6 @@ void rcu_idle_exit(void) rcu_eqs_exit(false); local_irq_restore(flags); } -EXPORT_SYMBOL_GPL(rcu_idle_exit); #ifdef CONFIG_NO_HZ_FULL /** @@ -1020,6 +1020,11 @@ void rcu_irq_enter(void) RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); rdtp = this_cpu_ptr(&rcu_dynticks); + + /* Page faults can happen in NMI handlers, so check... */ + if (rdtp->dynticks_nmi_nesting) + return; + oldval = rdtp->dynticks_nesting; rdtp->dynticks_nesting++; WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && @@ -1358,12 +1363,13 @@ static void rcu_check_gp_kthread_starvation(struct rcu_state *rsp) j = jiffies; gpa = READ_ONCE(rsp->gp_activity); if (j - gpa > 2 * HZ) { - pr_err("%s kthread starved for %ld jiffies! g%lu c%lu f%#x %s(%d) ->state=%#lx\n", + pr_err("%s kthread starved for %ld jiffies! g%lu c%lu f%#x %s(%d) ->state=%#lx ->cpu=%d\n", rsp->name, j - gpa, rsp->gpnum, rsp->completed, rsp->gp_flags, gp_state_getname(rsp->gp_state), rsp->gp_state, - rsp->gp_kthread ? rsp->gp_kthread->state : ~0); + rsp->gp_kthread ? rsp->gp_kthread->state : ~0, + rsp->gp_kthread ? task_cpu(rsp->gp_kthread) : -1); if (rsp->gp_kthread) { sched_show_task(rsp->gp_kthread); wake_up_process(rsp->gp_kthread); @@ -2067,8 +2073,8 @@ static bool rcu_gp_init(struct rcu_state *rsp) } /* - * Helper function for wait_event_interruptible_timeout() wakeup - * at force-quiescent-state time. + * Helper function for swait_event_idle() wakeup at force-quiescent-state + * time. */ static bool rcu_gp_fqs_check_wake(struct rcu_state *rsp, int *gfp) { @@ -2206,9 +2212,8 @@ static int __noreturn rcu_gp_kthread(void *arg) READ_ONCE(rsp->gpnum), TPS("reqwait")); rsp->gp_state = RCU_GP_WAIT_GPS; - swait_event_interruptible(rsp->gp_wq, - READ_ONCE(rsp->gp_flags) & - RCU_GP_FLAG_INIT); + swait_event_idle(rsp->gp_wq, READ_ONCE(rsp->gp_flags) & + RCU_GP_FLAG_INIT); rsp->gp_state = RCU_GP_DONE_GPS; /* Locking provides needed memory barrier. */ if (rcu_gp_init(rsp)) @@ -2239,7 +2244,7 @@ static int __noreturn rcu_gp_kthread(void *arg) READ_ONCE(rsp->gpnum), TPS("fqswait")); rsp->gp_state = RCU_GP_WAIT_FQS; - ret = swait_event_interruptible_timeout(rsp->gp_wq, + ret = swait_event_idle_timeout(rsp->gp_wq, rcu_gp_fqs_check_wake(rsp, &gf), j); rsp->gp_state = RCU_GP_DOING_FQS; /* Locking provides needed memory barriers. */ @@ -2409,6 +2414,8 @@ rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp, return; } WARN_ON_ONCE(oldmask); /* Any child must be all zeroed! */ + WARN_ON_ONCE(rnp->level != rcu_num_lvls - 1 && + rcu_preempt_blocked_readers_cgp(rnp)); rnp->qsmask &= ~mask; trace_rcu_quiescent_state_report(rsp->name, rnp->gpnum, mask, rnp->qsmask, rnp->level, @@ -2562,85 +2569,6 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp) rcu_report_qs_rdp(rdp->cpu, rsp, rdp); } -/* - * Send the specified CPU's RCU callbacks to the orphanage. The - * specified CPU must be offline, and the caller must hold the - * ->orphan_lock. - */ -static void -rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, - struct rcu_node *rnp, struct rcu_data *rdp) -{ - lockdep_assert_held(&rsp->orphan_lock); - - /* No-CBs CPUs do not have orphanable callbacks. */ - if (!IS_ENABLED(CONFIG_HOTPLUG_CPU) || rcu_is_nocb_cpu(rdp->cpu)) - return; - - /* - * Orphan the callbacks. First adjust the counts. This is safe - * because _rcu_barrier() excludes CPU-hotplug operations, so it - * cannot be running now. Thus no memory barrier is required. - */ - rdp->n_cbs_orphaned += rcu_segcblist_n_cbs(&rdp->cblist); - rcu_segcblist_extract_count(&rdp->cblist, &rsp->orphan_done); - - /* - * Next, move those callbacks still needing a grace period to - * the orphanage, where some other CPU will pick them up. - * Some of the callbacks might have gone partway through a grace - * period, but that is too bad. They get to start over because we - * cannot assume that grace periods are synchronized across CPUs. - */ - rcu_segcblist_extract_pend_cbs(&rdp->cblist, &rsp->orphan_pend); - - /* - * Then move the ready-to-invoke callbacks to the orphanage, - * where some other CPU will pick them up. These will not be - * required to pass though another grace period: They are done. - */ - rcu_segcblist_extract_done_cbs(&rdp->cblist, &rsp->orphan_done); - - /* Finally, disallow further callbacks on this CPU. */ - rcu_segcblist_disable(&rdp->cblist); -} - -/* - * Adopt the RCU callbacks from the specified rcu_state structure's - * orphanage. The caller must hold the ->orphan_lock. - */ -static void rcu_adopt_orphan_cbs(struct rcu_state *rsp, unsigned long flags) -{ - struct rcu_data *rdp = raw_cpu_ptr(rsp->rda); - - lockdep_assert_held(&rsp->orphan_lock); - - /* No-CBs CPUs are handled specially. */ - if (!IS_ENABLED(CONFIG_HOTPLUG_CPU) || - rcu_nocb_adopt_orphan_cbs(rsp, rdp, flags)) - return; - - /* Do the accounting first. */ - rdp->n_cbs_adopted += rsp->orphan_done.len; - if (rsp->orphan_done.len_lazy != rsp->orphan_done.len) - rcu_idle_count_callbacks_posted(); - rcu_segcblist_insert_count(&rdp->cblist, &rsp->orphan_done); - - /* - * We do not need a memory barrier here because the only way we - * can get here if there is an rcu_barrier() in flight is if - * we are the task doing the rcu_barrier(). - */ - - /* First adopt the ready-to-invoke callbacks, then the done ones. */ - rcu_segcblist_insert_done_cbs(&rdp->cblist, &rsp->orphan_done); - WARN_ON_ONCE(rsp->orphan_done.head); - rcu_segcblist_insert_pend_cbs(&rdp->cblist, &rsp->orphan_pend); - WARN_ON_ONCE(rsp->orphan_pend.head); - WARN_ON_ONCE(rcu_segcblist_empty(&rdp->cblist) != - !rcu_segcblist_n_cbs(&rdp->cblist)); -} - /* * Trace the fact that this CPU is going offline. */ @@ -2704,14 +2632,12 @@ static void rcu_cleanup_dead_rnp(struct rcu_node *rnp_leaf) /* * The CPU has been completely removed, and some other CPU is reporting - * this fact from process context. Do the remainder of the cleanup, - * including orphaning the outgoing CPU's RCU callbacks, and also - * adopting them. There can only be one CPU hotplug operation at a time, - * so no other CPU can be attempting to update rcu_cpu_kthread_task. + * this fact from process context. Do the remainder of the cleanup. + * There can only be one CPU hotplug operation at a time, so no need for + * explicit locking. */ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) { - unsigned long flags; struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */ @@ -2720,18 +2646,6 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) /* Adjust any no-longer-needed kthreads. */ rcu_boost_kthread_setaffinity(rnp, -1); - - /* Orphan the dead CPU's callbacks, and adopt them if appropriate. */ - raw_spin_lock_irqsave(&rsp->orphan_lock, flags); - rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp); - rcu_adopt_orphan_cbs(rsp, flags); - raw_spin_unlock_irqrestore(&rsp->orphan_lock, flags); - - WARN_ONCE(rcu_segcblist_n_cbs(&rdp->cblist) != 0 || - !rcu_segcblist_empty(&rdp->cblist), - "rcu_cleanup_dead_cpu: Callbacks on offline CPU %d: qlen=%lu, 1stCB=%p\n", - cpu, rcu_segcblist_n_cbs(&rdp->cblist), - rcu_segcblist_first_cb(&rdp->cblist)); } /* @@ -3569,10 +3483,11 @@ static void rcu_barrier_callback(struct rcu_head *rhp) struct rcu_state *rsp = rdp->rsp; if (atomic_dec_and_test(&rsp->barrier_cpu_count)) { - _rcu_barrier_trace(rsp, "LastCB", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("LastCB"), -1, + rsp->barrier_sequence); complete(&rsp->barrier_completion); } else { - _rcu_barrier_trace(rsp, "CB", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("CB"), -1, rsp->barrier_sequence); } } @@ -3584,14 +3499,15 @@ static void rcu_barrier_func(void *type) struct rcu_state *rsp = type; struct rcu_data *rdp = raw_cpu_ptr(rsp->rda); - _rcu_barrier_trace(rsp, "IRQ", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("IRQ"), -1, rsp->barrier_sequence); rdp->barrier_head.func = rcu_barrier_callback; debug_rcu_head_queue(&rdp->barrier_head); if (rcu_segcblist_entrain(&rdp->cblist, &rdp->barrier_head, 0)) { atomic_inc(&rsp->barrier_cpu_count); } else { debug_rcu_head_unqueue(&rdp->barrier_head); - _rcu_barrier_trace(rsp, "IRQNQ", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("IRQNQ"), -1, + rsp->barrier_sequence); } } @@ -3605,14 +3521,15 @@ static void _rcu_barrier(struct rcu_state *rsp) struct rcu_data *rdp; unsigned long s = rcu_seq_snap(&rsp->barrier_sequence); - _rcu_barrier_trace(rsp, "Begin", -1, s); + _rcu_barrier_trace(rsp, TPS("Begin"), -1, s); /* Take mutex to serialize concurrent rcu_barrier() requests. */ mutex_lock(&rsp->barrier_mutex); /* Did someone else do our work for us? */ if (rcu_seq_done(&rsp->barrier_sequence, s)) { - _rcu_barrier_trace(rsp, "EarlyExit", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("EarlyExit"), -1, + rsp->barrier_sequence); smp_mb(); /* caller's subsequent code after above check. */ mutex_unlock(&rsp->barrier_mutex); return; @@ -3620,7 +3537,7 @@ static void _rcu_barrier(struct rcu_state *rsp) /* Mark the start of the barrier operation. */ rcu_seq_start(&rsp->barrier_sequence); - _rcu_barrier_trace(rsp, "Inc1", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("Inc1"), -1, rsp->barrier_sequence); /* * Initialize the count to one rather than to zero in order to @@ -3643,10 +3560,10 @@ static void _rcu_barrier(struct rcu_state *rsp) rdp = per_cpu_ptr(rsp->rda, cpu); if (rcu_is_nocb_cpu(cpu)) { if (!rcu_nocb_cpu_needs_barrier(rsp, cpu)) { - _rcu_barrier_trace(rsp, "OfflineNoCB", cpu, + _rcu_barrier_trace(rsp, TPS("OfflineNoCB"), cpu, rsp->barrier_sequence); } else { - _rcu_barrier_trace(rsp, "OnlineNoCB", cpu, + _rcu_barrier_trace(rsp, TPS("OnlineNoCB"), cpu, rsp->barrier_sequence); smp_mb__before_atomic(); atomic_inc(&rsp->barrier_cpu_count); @@ -3654,11 +3571,11 @@ static void _rcu_barrier(struct rcu_state *rsp) rcu_barrier_callback, rsp, cpu, 0); } } else if (rcu_segcblist_n_cbs(&rdp->cblist)) { - _rcu_barrier_trace(rsp, "OnlineQ", cpu, + _rcu_barrier_trace(rsp, TPS("OnlineQ"), cpu, rsp->barrier_sequence); smp_call_function_single(cpu, rcu_barrier_func, rsp, 1); } else { - _rcu_barrier_trace(rsp, "OnlineNQ", cpu, + _rcu_barrier_trace(rsp, TPS("OnlineNQ"), cpu, rsp->barrier_sequence); } } @@ -3675,7 +3592,7 @@ static void _rcu_barrier(struct rcu_state *rsp) wait_for_completion(&rsp->barrier_completion); /* Mark the end of the barrier operation. */ - _rcu_barrier_trace(rsp, "Inc2", -1, rsp->barrier_sequence); + _rcu_barrier_trace(rsp, TPS("Inc2"), -1, rsp->barrier_sequence); rcu_seq_end(&rsp->barrier_sequence); /* Other rcu_barrier() invocations can now safely proceed. */ @@ -3777,8 +3694,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp) */ rnp = rdp->mynode; raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */ - if (!rdp->beenonline) - WRITE_ONCE(rsp->ncpus, READ_ONCE(rsp->ncpus) + 1); rdp->beenonline = true; /* We have now been online. */ rdp->gpnum = rnp->completed; /* Make CPU later note any new GP. */ rdp->completed = rnp->completed; @@ -3882,6 +3797,8 @@ void rcu_cpu_starting(unsigned int cpu) { unsigned long flags; unsigned long mask; + int nbits; + unsigned long oldmask; struct rcu_data *rdp; struct rcu_node *rnp; struct rcu_state *rsp; @@ -3892,9 +3809,15 @@ void rcu_cpu_starting(unsigned int cpu) mask = rdp->grpmask; raw_spin_lock_irqsave_rcu_node(rnp, flags); rnp->qsmaskinitnext |= mask; + oldmask = rnp->expmaskinitnext; rnp->expmaskinitnext |= mask; + oldmask ^= rnp->expmaskinitnext; + nbits = bitmap_weight(&oldmask, BITS_PER_LONG); + /* Allow lockless access for expedited grace periods. */ + smp_store_release(&rsp->ncpus, rsp->ncpus + nbits); /* ^^^ */ raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } + smp_mb(); /* Ensure RCU read-side usage follows above initialization. */ } #ifdef CONFIG_HOTPLUG_CPU @@ -3937,6 +3860,50 @@ void rcu_report_dead(unsigned int cpu) for_each_rcu_flavor(rsp) rcu_cleanup_dying_idle_cpu(cpu, rsp); } + +/* Migrate the dead CPU's callbacks to the current CPU. */ +static void rcu_migrate_callbacks(int cpu, struct rcu_state *rsp) +{ + unsigned long flags; + struct rcu_data *my_rdp; + struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); + struct rcu_node *rnp_root = rcu_get_root(rdp->rsp); + + if (rcu_is_nocb_cpu(cpu) || rcu_segcblist_empty(&rdp->cblist)) + return; /* No callbacks to migrate. */ + + local_irq_save(flags); + my_rdp = this_cpu_ptr(rsp->rda); + if (rcu_nocb_adopt_orphan_cbs(my_rdp, rdp, flags)) { + local_irq_restore(flags); + return; + } + raw_spin_lock_rcu_node(rnp_root); /* irqs already disabled. */ + rcu_advance_cbs(rsp, rnp_root, rdp); /* Leverage recent GPs. */ + rcu_advance_cbs(rsp, rnp_root, my_rdp); /* Assign GP to pending CBs. */ + rcu_segcblist_merge(&my_rdp->cblist, &rdp->cblist); + WARN_ON_ONCE(rcu_segcblist_empty(&my_rdp->cblist) != + !rcu_segcblist_n_cbs(&my_rdp->cblist)); + raw_spin_unlock_irqrestore_rcu_node(rnp_root, flags); + WARN_ONCE(rcu_segcblist_n_cbs(&rdp->cblist) != 0 || + !rcu_segcblist_empty(&rdp->cblist), + "rcu_cleanup_dead_cpu: Callbacks on offline CPU %d: qlen=%lu, 1stCB=%p\n", + cpu, rcu_segcblist_n_cbs(&rdp->cblist), + rcu_segcblist_first_cb(&rdp->cblist)); +} + +/* + * The outgoing CPU has just passed through the dying-idle state, + * and we are being invoked from the CPU that was IPIed to continue the + * offline operation. We need to migrate the outgoing CPU's callbacks. + */ +void rcutree_migrate_callbacks(int cpu) +{ + struct rcu_state *rsp; + + for_each_rcu_flavor(rsp) + rcu_migrate_callbacks(cpu, rsp); +} #endif /* @@ -4134,7 +4101,7 @@ static void __init rcu_init_geometry(void) if (rcu_fanout_leaf == RCU_FANOUT_LEAF && nr_cpu_ids == NR_CPUS) return; - pr_info("RCU: Adjusting geometry for rcu_fanout_leaf=%d, nr_cpu_ids=%d\n", + pr_info("RCU: Adjusting geometry for rcu_fanout_leaf=%d, nr_cpu_ids=%u\n", rcu_fanout_leaf, nr_cpu_ids); /* diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 9af0f31d6847a0893e1d9070e08096281e806e63..8e1f285f0a70ae53c4436e31df43d166109f6c67 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h @@ -219,8 +219,6 @@ struct rcu_data { /* qlen at last check for QS forcing */ unsigned long n_cbs_invoked; /* count of RCU cbs invoked. */ unsigned long n_nocbs_invoked; /* count of no-CBs RCU cbs invoked. */ - unsigned long n_cbs_orphaned; /* RCU cbs orphaned by dying CPU */ - unsigned long n_cbs_adopted; /* RCU cbs adopted from dying CPU */ unsigned long n_force_qs_snap; /* did other CPU force QS recently? */ long blimit; /* Upper limit on a processed batch */ @@ -268,7 +266,9 @@ struct rcu_data { struct rcu_head **nocb_follower_tail; struct swait_queue_head nocb_wq; /* For nocb kthreads to sleep on. */ struct task_struct *nocb_kthread; + raw_spinlock_t nocb_lock; /* Guard following pair of fields. */ int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */ + struct timer_list nocb_timer; /* Enforce finite deferral. */ /* The following fields are used by the leader, hence own cacheline. */ struct rcu_head *nocb_gp_head ____cacheline_internodealigned_in_smp; @@ -350,15 +350,6 @@ struct rcu_state { /* End of fields guarded by root rcu_node's lock. */ - raw_spinlock_t orphan_lock ____cacheline_internodealigned_in_smp; - /* Protect following fields. */ - struct rcu_cblist orphan_pend; /* Orphaned callbacks that */ - /* need a grace period. */ - struct rcu_cblist orphan_done; /* Orphaned callbacks that */ - /* are ready to invoke. */ - /* (Contains counts.) */ - /* End of fields guarded by orphan_lock. */ - struct mutex barrier_mutex; /* Guards barrier fields. */ atomic_t barrier_cpu_count; /* # CPUs waiting on. */ struct completion barrier_completion; /* Wake at barrier end. */ @@ -495,7 +486,7 @@ static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq); static void rcu_init_one_nocb(struct rcu_node *rnp); static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, bool lazy, unsigned long flags); -static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, +static bool rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp, struct rcu_data *rdp, unsigned long flags); static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp); diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h index dd21ca47e4b493bde21664bdcac526cd22588bd7..46d61b59773187fee241e114b3451823c4757fde 100644 --- a/kernel/rcu/tree_exp.h +++ b/kernel/rcu/tree_exp.h @@ -73,7 +73,7 @@ static void sync_exp_reset_tree_hotplug(struct rcu_state *rsp) unsigned long flags; unsigned long mask; unsigned long oldmask; - int ncpus = READ_ONCE(rsp->ncpus); + int ncpus = smp_load_acquire(&rsp->ncpus); /* Order against locking. */ struct rcu_node *rnp; struct rcu_node *rnp_up; diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index 908b309d60d7bc29e82f3a049d928fbd8140dfd2..e012b9be777e3ba00ccf2fe4d05df78b78abd8f5 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -89,7 +89,7 @@ static void __init rcu_bootup_announce_oddness(void) if (rcu_fanout_leaf != RCU_FANOUT_LEAF) pr_info("\tBoot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf); if (nr_cpu_ids != NR_CPUS) - pr_info("\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids); + pr_info("\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%u.\n", NR_CPUS, nr_cpu_ids); #ifdef CONFIG_RCU_BOOST pr_info("\tRCU priority boosting: priority %d delay %d ms.\n", kthread_prio, CONFIG_RCU_BOOST_DELAY); #endif @@ -180,6 +180,8 @@ static void rcu_preempt_ctxt_queue(struct rcu_node *rnp, struct rcu_data *rdp) struct task_struct *t = current; lockdep_assert_held(&rnp->lock); + WARN_ON_ONCE(rdp->mynode != rnp); + WARN_ON_ONCE(rnp->level != rcu_num_lvls - 1); /* * Decide where to queue the newly blocked task. In theory, @@ -261,6 +263,10 @@ static void rcu_preempt_ctxt_queue(struct rcu_node *rnp, struct rcu_data *rdp) rnp->gp_tasks = &t->rcu_node_entry; if (!rnp->exp_tasks && (blkd_state & RCU_EXP_BLKD)) rnp->exp_tasks = &t->rcu_node_entry; + WARN_ON_ONCE(!(blkd_state & RCU_GP_BLKD) != + !(rnp->qsmask & rdp->grpmask)); + WARN_ON_ONCE(!(blkd_state & RCU_EXP_BLKD) != + !(rnp->expmask & rdp->grpmask)); raw_spin_unlock_rcu_node(rnp); /* interrupts remain disabled. */ /* @@ -482,6 +488,7 @@ void rcu_read_unlock_special(struct task_struct *t) rnp = t->rcu_blocked_node; raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */ WARN_ON_ONCE(rnp != t->rcu_blocked_node); + WARN_ON_ONCE(rnp->level != rcu_num_lvls - 1); empty_norm = !rcu_preempt_blocked_readers_cgp(rnp); empty_exp = sync_rcu_preempt_exp_done(rnp); smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */ @@ -495,10 +502,10 @@ void rcu_read_unlock_special(struct task_struct *t) if (&t->rcu_node_entry == rnp->exp_tasks) rnp->exp_tasks = np; if (IS_ENABLED(CONFIG_RCU_BOOST)) { - if (&t->rcu_node_entry == rnp->boost_tasks) - rnp->boost_tasks = np; /* Snapshot ->boost_mtx ownership w/rnp->lock held. */ drop_boost_mutex = rt_mutex_owner(&rnp->boost_mtx) == t; + if (&t->rcu_node_entry == rnp->boost_tasks) + rnp->boost_tasks = np; } /* @@ -636,10 +643,17 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp) */ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp) { + struct task_struct *t; + RCU_LOCKDEP_WARN(preemptible(), "rcu_preempt_check_blocked_tasks() invoked with preemption enabled!!!\n"); WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp)); - if (rcu_preempt_has_tasks(rnp)) + if (rcu_preempt_has_tasks(rnp)) { rnp->gp_tasks = rnp->blkd_tasks.next; + t = container_of(rnp->gp_tasks, struct task_struct, + rcu_node_entry); + trace_rcu_unlock_preempted_task(TPS("rcu_preempt-GPS"), + rnp->gpnum, t->pid); + } WARN_ON_ONCE(rnp->qsmask); } @@ -1788,22 +1802,61 @@ bool rcu_is_nocb_cpu(int cpu) } /* - * Kick the leader kthread for this NOCB group. + * Kick the leader kthread for this NOCB group. Caller holds ->nocb_lock + * and this function releases it. */ -static void wake_nocb_leader(struct rcu_data *rdp, bool force) +static void __wake_nocb_leader(struct rcu_data *rdp, bool force, + unsigned long flags) + __releases(rdp->nocb_lock) { struct rcu_data *rdp_leader = rdp->nocb_leader; - if (!READ_ONCE(rdp_leader->nocb_kthread)) + lockdep_assert_held(&rdp->nocb_lock); + if (!READ_ONCE(rdp_leader->nocb_kthread)) { + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); return; - if (READ_ONCE(rdp_leader->nocb_leader_sleep) || force) { + } + if (rdp_leader->nocb_leader_sleep || force) { /* Prior smp_mb__after_atomic() orders against prior enqueue. */ WRITE_ONCE(rdp_leader->nocb_leader_sleep, false); + del_timer(&rdp->nocb_timer); + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); smp_mb(); /* ->nocb_leader_sleep before swake_up(). */ swake_up(&rdp_leader->nocb_wq); + } else { + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); } } +/* + * Kick the leader kthread for this NOCB group, but caller has not + * acquired locks. + */ +static void wake_nocb_leader(struct rcu_data *rdp, bool force) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&rdp->nocb_lock, flags); + __wake_nocb_leader(rdp, force, flags); +} + +/* + * Arrange to wake the leader kthread for this NOCB group at some + * future time when it is safe to do so. + */ +static void wake_nocb_leader_defer(struct rcu_data *rdp, int waketype, + const char *reason) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&rdp->nocb_lock, flags); + if (rdp->nocb_defer_wakeup == RCU_NOCB_WAKE_NOT) + mod_timer(&rdp->nocb_timer, jiffies + 1); + WRITE_ONCE(rdp->nocb_defer_wakeup, waketype); + trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, reason); + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); +} + /* * Does the specified CPU need an RCU callback for the specified flavor * of rcu_barrier()? @@ -1891,11 +1944,8 @@ static void __call_rcu_nocb_enqueue(struct rcu_data *rdp, trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeEmpty")); } else { - WRITE_ONCE(rdp->nocb_defer_wakeup, RCU_NOCB_WAKE); - /* Store ->nocb_defer_wakeup before ->rcu_urgent_qs. */ - smp_store_release(this_cpu_ptr(&rcu_dynticks.rcu_urgent_qs), true); - trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, - TPS("WakeEmptyIsDeferred")); + wake_nocb_leader_defer(rdp, RCU_NOCB_WAKE, + TPS("WakeEmptyIsDeferred")); } rdp->qlen_last_fqs_check = 0; } else if (len > rdp->qlen_last_fqs_check + qhimark) { @@ -1905,11 +1955,8 @@ static void __call_rcu_nocb_enqueue(struct rcu_data *rdp, trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeOvf")); } else { - WRITE_ONCE(rdp->nocb_defer_wakeup, RCU_NOCB_WAKE_FORCE); - /* Store ->nocb_defer_wakeup before ->rcu_urgent_qs. */ - smp_store_release(this_cpu_ptr(&rcu_dynticks.rcu_urgent_qs), true); - trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, - TPS("WakeOvfIsDeferred")); + wake_nocb_leader_defer(rdp, RCU_NOCB_WAKE, + TPS("WakeOvfIsDeferred")); } rdp->qlen_last_fqs_check = LONG_MAX / 2; } else { @@ -1961,30 +2008,19 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, * Adopt orphaned callbacks on a no-CBs CPU, or return 0 if this is * not a no-CBs CPU. */ -static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, +static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp, struct rcu_data *rdp, unsigned long flags) { - long ql = rsp->orphan_done.len; - long qll = rsp->orphan_done.len_lazy; - - /* If this is not a no-CBs CPU, tell the caller to do it the old way. */ + RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_nocb_adopt_orphan_cbs() invoked with irqs enabled!!!"); if (!rcu_is_nocb_cpu(smp_processor_id())) - return false; - - /* First, enqueue the donelist, if any. This preserves CB ordering. */ - if (rsp->orphan_done.head) { - __call_rcu_nocb_enqueue(rdp, rcu_cblist_head(&rsp->orphan_done), - rcu_cblist_tail(&rsp->orphan_done), - ql, qll, flags); - } - if (rsp->orphan_pend.head) { - __call_rcu_nocb_enqueue(rdp, rcu_cblist_head(&rsp->orphan_pend), - rcu_cblist_tail(&rsp->orphan_pend), - ql, qll, flags); - } - rcu_cblist_init(&rsp->orphan_done); - rcu_cblist_init(&rsp->orphan_pend); + return false; /* Not NOCBs CPU, caller must migrate CBs. */ + __call_rcu_nocb_enqueue(my_rdp, rcu_segcblist_head(&rdp->cblist), + rcu_segcblist_tail(&rdp->cblist), + rcu_segcblist_n_cbs(&rdp->cblist), + rcu_segcblist_n_lazy_cbs(&rdp->cblist), flags); + rcu_segcblist_init(&rdp->cblist); + rcu_segcblist_disable(&rdp->cblist); return true; } @@ -2031,6 +2067,7 @@ static void rcu_nocb_wait_gp(struct rcu_data *rdp) static void nocb_leader_wait(struct rcu_data *my_rdp) { bool firsttime = true; + unsigned long flags; bool gotcbs; struct rcu_data *rdp; struct rcu_head **tail; @@ -2039,13 +2076,17 @@ static void nocb_leader_wait(struct rcu_data *my_rdp) /* Wait for callbacks to appear. */ if (!rcu_nocb_poll) { - trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, "Sleep"); + trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, TPS("Sleep")); swait_event_interruptible(my_rdp->nocb_wq, !READ_ONCE(my_rdp->nocb_leader_sleep)); - /* Memory barrier handled by smp_mb() calls below and repoll. */ + raw_spin_lock_irqsave(&my_rdp->nocb_lock, flags); + my_rdp->nocb_leader_sleep = true; + WRITE_ONCE(my_rdp->nocb_defer_wakeup, RCU_NOCB_WAKE_NOT); + del_timer(&my_rdp->nocb_timer); + raw_spin_unlock_irqrestore(&my_rdp->nocb_lock, flags); } else if (firsttime) { firsttime = false; /* Don't drown trace log with "Poll"! */ - trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, "Poll"); + trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, TPS("Poll")); } /* @@ -2054,7 +2095,7 @@ static void nocb_leader_wait(struct rcu_data *my_rdp) * nocb_gp_head, where they await a grace period. */ gotcbs = false; - smp_mb(); /* wakeup before ->nocb_head reads. */ + smp_mb(); /* wakeup and _sleep before ->nocb_head reads. */ for (rdp = my_rdp; rdp; rdp = rdp->nocb_next_follower) { rdp->nocb_gp_head = READ_ONCE(rdp->nocb_head); if (!rdp->nocb_gp_head) @@ -2066,56 +2107,41 @@ static void nocb_leader_wait(struct rcu_data *my_rdp) gotcbs = true; } - /* - * If there were no callbacks, sleep a bit, rescan after a - * memory barrier, and go retry. - */ + /* No callbacks? Sleep a bit if polling, and go retry. */ if (unlikely(!gotcbs)) { - if (!rcu_nocb_poll) - trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, - "WokeEmpty"); WARN_ON(signal_pending(current)); - schedule_timeout_interruptible(1); - - /* Rescan in case we were a victim of memory ordering. */ - my_rdp->nocb_leader_sleep = true; - smp_mb(); /* Ensure _sleep true before scan. */ - for (rdp = my_rdp; rdp; rdp = rdp->nocb_next_follower) - if (READ_ONCE(rdp->nocb_head)) { - /* Found CB, so short-circuit next wait. */ - my_rdp->nocb_leader_sleep = false; - break; - } + if (rcu_nocb_poll) { + schedule_timeout_interruptible(1); + } else { + trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, + TPS("WokeEmpty")); + } goto wait_again; } /* Wait for one grace period. */ rcu_nocb_wait_gp(my_rdp); - /* - * We left ->nocb_leader_sleep unset to reduce cache thrashing. - * We set it now, but recheck for new callbacks while - * traversing our follower list. - */ - my_rdp->nocb_leader_sleep = true; - smp_mb(); /* Ensure _sleep true before scan of ->nocb_head. */ - /* Each pass through the following loop wakes a follower, if needed. */ for (rdp = my_rdp; rdp; rdp = rdp->nocb_next_follower) { - if (READ_ONCE(rdp->nocb_head)) + if (!rcu_nocb_poll && + READ_ONCE(rdp->nocb_head) && + READ_ONCE(my_rdp->nocb_leader_sleep)) { + raw_spin_lock_irqsave(&my_rdp->nocb_lock, flags); my_rdp->nocb_leader_sleep = false;/* No need to sleep.*/ + raw_spin_unlock_irqrestore(&my_rdp->nocb_lock, flags); + } if (!rdp->nocb_gp_head) continue; /* No CBs, so no need to wake follower. */ /* Append callbacks to follower's "done" list. */ - tail = xchg(&rdp->nocb_follower_tail, rdp->nocb_gp_tail); + raw_spin_lock_irqsave(&rdp->nocb_lock, flags); + tail = rdp->nocb_follower_tail; + rdp->nocb_follower_tail = rdp->nocb_gp_tail; *tail = rdp->nocb_gp_head; - smp_mb__after_atomic(); /* Store *tail before wakeup. */ + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); if (rdp != my_rdp && tail == &rdp->nocb_follower_head) { - /* - * List was empty, wake up the follower. - * Memory barriers supplied by atomic_long_add(). - */ + /* List was empty, so wake up the follower. */ swake_up(&rdp->nocb_wq); } } @@ -2131,28 +2157,16 @@ static void nocb_leader_wait(struct rcu_data *my_rdp) */ static void nocb_follower_wait(struct rcu_data *rdp) { - bool firsttime = true; - for (;;) { - if (!rcu_nocb_poll) { - trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, - "FollowerSleep"); - swait_event_interruptible(rdp->nocb_wq, - READ_ONCE(rdp->nocb_follower_head)); - } else if (firsttime) { - /* Don't drown trace log with "Poll"! */ - firsttime = false; - trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, "Poll"); - } + trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("FollowerSleep")); + swait_event_interruptible(rdp->nocb_wq, + READ_ONCE(rdp->nocb_follower_head)); if (smp_load_acquire(&rdp->nocb_follower_head)) { /* ^^^ Ensure CB invocation follows _head test. */ return; } - if (!rcu_nocb_poll) - trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, - "WokeEmpty"); WARN_ON(signal_pending(current)); - schedule_timeout_interruptible(1); + trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WokeEmpty")); } } @@ -2165,6 +2179,7 @@ static void nocb_follower_wait(struct rcu_data *rdp) static int rcu_nocb_kthread(void *arg) { int c, cl; + unsigned long flags; struct rcu_head *list; struct rcu_head *next; struct rcu_head **tail; @@ -2179,11 +2194,14 @@ static int rcu_nocb_kthread(void *arg) nocb_follower_wait(rdp); /* Pull the ready-to-invoke callbacks onto local list. */ - list = READ_ONCE(rdp->nocb_follower_head); + raw_spin_lock_irqsave(&rdp->nocb_lock, flags); + list = rdp->nocb_follower_head; + rdp->nocb_follower_head = NULL; + tail = rdp->nocb_follower_tail; + rdp->nocb_follower_tail = &rdp->nocb_follower_head; + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); BUG_ON(!list); - trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, "WokeNonEmpty"); - WRITE_ONCE(rdp->nocb_follower_head, NULL); - tail = xchg(&rdp->nocb_follower_tail, &rdp->nocb_follower_head); + trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WokeNonEmpty")); /* Each pass through the following loop invokes a callback. */ trace_rcu_batch_start(rdp->rsp->name, @@ -2226,18 +2244,39 @@ static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp) } /* Do a deferred wakeup of rcu_nocb_kthread(). */ -static void do_nocb_deferred_wakeup(struct rcu_data *rdp) +static void do_nocb_deferred_wakeup_common(struct rcu_data *rdp) { + unsigned long flags; int ndw; - if (!rcu_nocb_need_deferred_wakeup(rdp)) + raw_spin_lock_irqsave(&rdp->nocb_lock, flags); + if (!rcu_nocb_need_deferred_wakeup(rdp)) { + raw_spin_unlock_irqrestore(&rdp->nocb_lock, flags); return; + } ndw = READ_ONCE(rdp->nocb_defer_wakeup); WRITE_ONCE(rdp->nocb_defer_wakeup, RCU_NOCB_WAKE_NOT); - wake_nocb_leader(rdp, ndw == RCU_NOCB_WAKE_FORCE); + __wake_nocb_leader(rdp, ndw == RCU_NOCB_WAKE_FORCE, flags); trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("DeferredWake")); } +/* Do a deferred wakeup of rcu_nocb_kthread() from a timer handler. */ +static void do_nocb_deferred_wakeup_timer(unsigned long x) +{ + do_nocb_deferred_wakeup_common((struct rcu_data *)x); +} + +/* + * Do a deferred wakeup of rcu_nocb_kthread() from fastpath. + * This means we do an inexact common-case check. Note that if + * we miss, ->nocb_timer will eventually clean things up. + */ +static void do_nocb_deferred_wakeup(struct rcu_data *rdp) +{ + if (rcu_nocb_need_deferred_wakeup(rdp)) + do_nocb_deferred_wakeup_common(rdp); +} + void __init rcu_init_nohz(void) { int cpu; @@ -2287,6 +2326,9 @@ static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp) rdp->nocb_tail = &rdp->nocb_head; init_swait_queue_head(&rdp->nocb_wq); rdp->nocb_follower_tail = &rdp->nocb_follower_head; + raw_spin_lock_init(&rdp->nocb_lock); + setup_timer(&rdp->nocb_timer, do_nocb_deferred_wakeup_timer, + (unsigned long)rdp); } /* @@ -2459,7 +2501,7 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, return false; } -static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, +static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp, struct rcu_data *rdp, unsigned long flags) { diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index 00e77c470017401a812e738b1598ab4887fbf93e..5033b66d27530f30eea3625ac4e529f631aa0a41 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -568,7 +568,7 @@ static DECLARE_WAIT_QUEUE_HEAD(rcu_tasks_cbs_wq); static DEFINE_RAW_SPINLOCK(rcu_tasks_cbs_lock); /* Track exiting tasks in order to allow them to be waited for. */ -DEFINE_SRCU(tasks_rcu_exit_srcu); +DEFINE_STATIC_SRCU(tasks_rcu_exit_srcu); /* Control stall timeouts. Disable with <= 0, otherwise jiffies till stall. */ #define RCU_TASK_STALL_TIMEOUT (HZ * 60 * 10) @@ -875,6 +875,22 @@ static void rcu_spawn_tasks_kthread(void) mutex_unlock(&rcu_tasks_kthread_mutex); } +/* Do the srcu_read_lock() for the above synchronize_srcu(). */ +void exit_tasks_rcu_start(void) +{ + preempt_disable(); + current->rcu_tasks_idx = __srcu_read_lock(&tasks_rcu_exit_srcu); + preempt_enable(); +} + +/* Do the srcu_read_unlock() for the above synchronize_srcu(). */ +void exit_tasks_rcu_finish(void) +{ + preempt_disable(); + __srcu_read_unlock(&tasks_rcu_exit_srcu, current->rcu_tasks_idx); + preempt_enable(); +} + #endif /* #ifdef CONFIG_TASKS_RCU */ #ifndef CONFIG_TINY_RCU diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile index 53f0164ed362dd91b3a218f5db1790420b2a6850..78f54932ea1d09edfab191763583d565df677adf 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_SCHED_DEBUG) += debug.o obj-$(CONFIG_CGROUP_CPUACCT) += cpuacct.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) += cpufreq_schedutil.o +obj-$(CONFIG_MEMBARRIER) += membarrier.o diff --git a/kernel/sched/autogroup.c b/kernel/sched/autogroup.c index da39489d2d80e9b8f6781610e97c23ec0014f45b..de6d7f4dfcb52ce4f7386b052b5ded37a9f30054 100644 --- a/kernel/sched/autogroup.c +++ b/kernel/sched/autogroup.c @@ -71,7 +71,6 @@ static inline struct autogroup *autogroup_create(void) goto out_fail; tg = sched_create_group(&root_task_group); - if (IS_ERR(tg)) goto out_free; @@ -101,7 +100,7 @@ static inline struct autogroup *autogroup_create(void) out_fail: if (printk_ratelimit()) { printk(KERN_WARNING "autogroup_create: %s failure.\n", - ag ? "sched_create_group()" : "kmalloc()"); + ag ? "sched_create_group()" : "kzalloc()"); } return autogroup_kref_get(&autogroup_default); diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c index 13fc5ae9bf2f6c96ee82ad140d89e3231ade1c88..cc873075c3bde5fa8f97403243f1b2754e326675 100644 --- a/kernel/sched/completion.c +++ b/kernel/sched/completion.c @@ -32,6 +32,12 @@ void complete(struct completion *x) unsigned long flags; spin_lock_irqsave(&x->wait.lock, flags); + + /* + * Perform commit of crossrelease here. + */ + complete_release_commit(x); + if (x->done != UINT_MAX) x->done++; __wake_up_locked(&x->wait, TASK_NORMAL, 1); @@ -47,6 +53,13 @@ EXPORT_SYMBOL(complete); * * It may be assumed that this function implies a write memory barrier before * changing the task state if and only if any tasks are woken up. + * + * Since complete_all() sets the completion of @x permanently to done + * to allow multiple waiters to finish, a call to reinit_completion() + * must be used on @x if @x is to be used again. The code must make + * sure that all waiters have woken and finished before reinitializing + * @x. Also note that the function completion_done() can not be used + * to know if there are still waiters after complete_all() has been called. */ void complete_all(struct completion *x) { @@ -92,9 +105,14 @@ __wait_for_common(struct completion *x, { might_sleep(); + complete_acquire(x); + spin_lock_irq(&x->wait.lock); timeout = do_wait_for_common(x, action, timeout, state); spin_unlock_irq(&x->wait.lock); + + complete_release(x); + return timeout; } @@ -297,9 +315,12 @@ EXPORT_SYMBOL(try_wait_for_completion); * Return: 0 if there are waiters (wait_for_completion() in progress) * 1 if there are no waiters. * + * Note, this will always return true if complete_all() was called on @X. */ bool completion_done(struct completion *x) { + unsigned long flags; + if (!READ_ONCE(x->done)) return false; @@ -307,14 +328,9 @@ bool completion_done(struct completion *x) * If ->done, we need to wait for complete() to release ->wait.lock * otherwise we can end up freeing the completion before complete() * is done referencing it. - * - * The RMB pairs with complete()'s RELEASE of ->wait.lock and orders - * the loads of ->done and ->wait.lock such that we cannot observe - * the lock before complete() acquires it while observing the ->done - * after it's acquired the lock. */ - smp_rmb(); - spin_unlock_wait(&x->wait.lock); + spin_lock_irqsave(&x->wait.lock, flags); + spin_unlock_irqrestore(&x->wait.lock, flags); return true; } EXPORT_SYMBOL(completion_done); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 0869b20fba81f6f1a7f5f73bde65fadc483f0fa2..d17c5da523a0bc817a6b32413ee7e0ba3e7a6b2e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -951,8 +951,13 @@ struct migration_arg { static struct rq *__migrate_task(struct rq *rq, struct rq_flags *rf, struct task_struct *p, int dest_cpu) { - if (unlikely(!cpu_active(dest_cpu))) - return rq; + if (p->flags & PF_KTHREAD) { + if (unlikely(!cpu_online(dest_cpu))) + return rq; + } else { + if (unlikely(!cpu_active(dest_cpu))) + return rq; + } /* Affinity changed (again). */ if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed)) @@ -1168,6 +1173,10 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&p->pi_lock) || lockdep_is_held(&task_rq(p)->lock))); #endif + /* + * Clearly, migrating tasks to offline CPUs is a fairly daft thing. + */ + WARN_ON_ONCE(!cpu_online(new_cpu)); #endif trace_sched_migrate_task(p, new_cpu); @@ -1967,8 +1976,8 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) * reordered with p->state check below. This pairs with mb() in * set_current_state() the waiting thread does. */ - smp_mb__before_spinlock(); raw_spin_lock_irqsave(&p->pi_lock, flags); + smp_mb__after_spinlock(); if (!(p->state & state)) goto out; @@ -2635,6 +2644,16 @@ static struct rq *finish_task_switch(struct task_struct *prev) prev_state = prev->state; vtime_task_switch(prev); perf_event_task_sched_in(prev, current); + /* + * The membarrier system call requires a full memory barrier + * after storing to rq->curr, before going back to user-space. + * + * TODO: This smp_mb__after_unlock_lock can go away if PPC end + * up adding a full barrier to switch_mm(), or we should figure + * out if a smp_mb__after_unlock_lock is really the proper API + * to use. + */ + smp_mb__after_unlock_lock(); finish_lock_switch(rq, prev); finish_arch_post_lock_switch(); @@ -3281,8 +3300,8 @@ static void __sched notrace __schedule(bool preempt) * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE) * done by the caller to avoid the race with signal_wake_up(). */ - smp_mb__before_spinlock(); rq_lock(rq, &rf); + smp_mb__after_spinlock(); /* Promote REQ to ACT */ rq->clock_update_flags <<= 1; @@ -3324,6 +3343,21 @@ static void __sched notrace __schedule(bool preempt) if (likely(prev != next)) { rq->nr_switches++; rq->curr = next; + /* + * The membarrier system call requires each architecture + * to have a full memory barrier after updating + * rq->curr, before returning to user-space. For TSO + * (e.g. x86), the architecture must provide its own + * barrier in switch_mm(). For weakly ordered machines + * for which spin_unlock() acts as a full memory + * barrier, finish_lock_switch() in common code takes + * care of this barrier. For weakly ordered machines for + * which spin_unlock() acts as a RELEASE barrier (only + * arm64 and PowerPC), arm64 has a full barrier in + * switch_to(), and PowerPC has + * smp_mb__after_unlock_lock() before + * finish_lock_switch(). + */ ++*switch_count; trace_sched_switch(preempt, prev, next); @@ -3352,8 +3386,8 @@ void __noreturn do_task_dead(void) * To avoid it, we have to wait for releasing tsk->pi_lock which * is held by try_to_wake_up() */ - smp_mb(); - raw_spin_unlock_wait(¤t->pi_lock); + raw_spin_lock_irq(¤t->pi_lock); + raw_spin_unlock_irq(¤t->pi_lock); /* Causes final put_task_struct in finish_task_switch(): */ __set_current_state(TASK_DEAD); @@ -5103,24 +5137,17 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, return retval; } -static const char stat_nam[] = TASK_STATE_TO_CHAR_STR; - void sched_show_task(struct task_struct *p) { unsigned long free = 0; int ppid; - unsigned long state = p->state; - - /* Make sure the string lines up properly with the number of task states: */ - BUILD_BUG_ON(sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1); if (!try_get_task_stack(p)) return; - if (state) - state = __ffs(state) + 1; - printk(KERN_INFO "%-15.15s %c", p->comm, - state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?'); - if (state == TASK_RUNNING) + + printk(KERN_INFO "%-15.15s %c", p->comm, task_state_to_char(p)); + + if (p->state == TASK_RUNNING) printk(KERN_CONT " running task "); #ifdef CONFIG_DEBUG_STACK_USAGE free = stack_not_used(p); @@ -5139,6 +5166,28 @@ void sched_show_task(struct task_struct *p) put_task_stack(p); } +static inline bool +state_filter_match(unsigned long state_filter, struct task_struct *p) +{ + /* no filter, everything matches */ + if (!state_filter) + return true; + + /* filter, but doesn't match */ + if (!(p->state & state_filter)) + return false; + + /* + * When looking for TASK_UNINTERRUPTIBLE skip TASK_IDLE (allows + * TASK_KILLABLE). + */ + if (state_filter == TASK_UNINTERRUPTIBLE && p->state == TASK_IDLE) + return false; + + return true; +} + + void show_state_filter(unsigned long state_filter) { struct task_struct *g, *p; @@ -5161,7 +5210,7 @@ void show_state_filter(unsigned long state_filter) */ touch_nmi_watchdog(); touch_all_softlockup_watchdogs(); - if (!state_filter || (p->state & state_filter)) + if (state_filter_match(state_filter, p)) sched_show_task(p); } @@ -5177,11 +5226,6 @@ void show_state_filter(unsigned long state_filter) debug_show_all_locks(); } -void init_idle_bootup_task(struct task_struct *idle) -{ - idle->sched_class = &idle_sched_class; -} - /** * init_idle - set up an idle thread for a given CPU * @idle: task in question @@ -5438,7 +5482,7 @@ static void migrate_tasks(struct rq *dead_rq, struct rq_flags *rf) */ next = pick_next_task(rq, &fake_task, rf); BUG_ON(!next); - next->sched_class->put_prev_task(rq, next); + put_prev_task(rq, next); /* * Rules for changing task_struct::cpus_allowed are holding @@ -5538,16 +5582,15 @@ static void cpuset_cpu_active(void) * operation in the resume sequence, just build a single sched * domain, ignoring cpusets. */ - num_cpus_frozen--; - if (likely(num_cpus_frozen)) { - partition_sched_domains(1, NULL, NULL); + partition_sched_domains(1, NULL, NULL); + if (--num_cpus_frozen) return; - } /* * This is the last CPU online operation. So fall through and * restore the original sched domains by considering the * cpuset configurations. */ + cpuset_force_rebuild(); } cpuset_update_active_cpus(); } diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c index fba235c7d02679a5881f71971f84d778a4222972..8d9562d890d3041421aaf9d0978563293b322c46 100644 --- a/kernel/sched/cpudeadline.c +++ b/kernel/sched/cpudeadline.c @@ -119,29 +119,29 @@ static inline int cpudl_maximum(struct cpudl *cp) * @p: the task * @later_mask: a mask to fill in with the selected CPUs (or NULL) * - * Returns: int - best CPU (heap maximum if suitable) + * Returns: int - CPUs were found */ int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask) { - int best_cpu = -1; const struct sched_dl_entity *dl_se = &p->dl; if (later_mask && cpumask_and(later_mask, cp->free_cpus, &p->cpus_allowed)) { - best_cpu = cpumask_any(later_mask); - goto out; - } else if (cpumask_test_cpu(cpudl_maximum(cp), &p->cpus_allowed) && - dl_time_before(dl_se->deadline, cp->elements[0].dl)) { - best_cpu = cpudl_maximum(cp); - if (later_mask) - cpumask_set_cpu(best_cpu, later_mask); - } + return 1; + } else { + int best_cpu = cpudl_maximum(cp); + WARN_ON(best_cpu != -1 && !cpu_present(best_cpu)); -out: - WARN_ON(best_cpu != -1 && !cpu_present(best_cpu)); + if (cpumask_test_cpu(best_cpu, &p->cpus_allowed) && + dl_time_before(dl_se->deadline, cp->elements[0].dl)) { + if (later_mask) + cpumask_set_cpu(best_cpu, later_mask); - return best_cpu; + return 1; + } + } + return 0; } /* @@ -246,7 +246,6 @@ int cpudl_init(struct cpudl *cp) { int i; - memset(cp, 0, sizeof(*cp)); raw_spin_lock_init(&cp->lock); cp->size = 0; diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 29a397067ffa0f7c818990f3defe1a4bdd437708..9209d83ecdcf1a52faa9eb3d7d741970b6631faf 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -52,9 +52,11 @@ struct sugov_policy { struct sugov_cpu { struct update_util_data update_util; struct sugov_policy *sg_policy; + unsigned int cpu; - unsigned long iowait_boost; - unsigned long iowait_boost_max; + bool iowait_boost_pending; + unsigned int iowait_boost; + unsigned int iowait_boost_max; u64 last_update; /* The fields below are only needed when sharing a policy. */ @@ -76,6 +78,26 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) { s64 delta_ns; + /* + * Since cpufreq_update_util() is called with rq->lock held for + * the @target_cpu, our per-cpu data is fully serialized. + * + * However, drivers cannot in general deal with cross-cpu + * requests, so while get_next_freq() will work, our + * sugov_update_commit() call may not for the fast switching platforms. + * + * Hence stop here for remote requests if they aren't supported + * by the hardware, as calculating the frequency is pointless if + * we cannot in fact act on it. + * + * For the slow switching platforms, the kthread is always scheduled on + * the right set of CPUs and any CPU can find the next frequency and + * schedule the kthread. + */ + if (sg_policy->policy->fast_switch_enabled && + !cpufreq_can_do_remote_dvfs(sg_policy->policy)) + return false; + if (sg_policy->work_in_progress) return false; @@ -106,7 +128,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, if (policy->fast_switch_enabled) { next_freq = cpufreq_driver_fast_switch(policy, next_freq); - if (next_freq == CPUFREQ_ENTRY_INVALID) + if (!next_freq) return; policy->cur = next_freq; @@ -154,12 +176,12 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, return cpufreq_driver_resolve_freq(policy, freq); } -static void sugov_get_util(unsigned long *util, unsigned long *max) +static void sugov_get_util(unsigned long *util, unsigned long *max, int cpu) { - struct rq *rq = this_rq(); + struct rq *rq = cpu_rq(cpu); unsigned long cfs_max; - cfs_max = arch_scale_cpu_capacity(NULL, smp_processor_id()); + cfs_max = arch_scale_cpu_capacity(NULL, cpu); *util = min(rq->cfs.avg.util_avg, cfs_max); *max = cfs_max; @@ -169,30 +191,54 @@ static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time, unsigned int flags) { if (flags & SCHED_CPUFREQ_IOWAIT) { - sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; + if (sg_cpu->iowait_boost_pending) + return; + + sg_cpu->iowait_boost_pending = true; + + if (sg_cpu->iowait_boost) { + sg_cpu->iowait_boost <<= 1; + if (sg_cpu->iowait_boost > sg_cpu->iowait_boost_max) + sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; + } else { + sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min; + } } else if (sg_cpu->iowait_boost) { s64 delta_ns = time - sg_cpu->last_update; /* Clear iowait_boost if the CPU apprears to have been idle. */ - if (delta_ns > TICK_NSEC) + if (delta_ns > TICK_NSEC) { sg_cpu->iowait_boost = 0; + sg_cpu->iowait_boost_pending = false; + } } } static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, unsigned long *max) { - unsigned long boost_util = sg_cpu->iowait_boost; - unsigned long boost_max = sg_cpu->iowait_boost_max; + unsigned int boost_util, boost_max; - if (!boost_util) + if (!sg_cpu->iowait_boost) return; + if (sg_cpu->iowait_boost_pending) { + sg_cpu->iowait_boost_pending = false; + } else { + sg_cpu->iowait_boost >>= 1; + if (sg_cpu->iowait_boost < sg_cpu->sg_policy->policy->min) { + sg_cpu->iowait_boost = 0; + return; + } + } + + boost_util = sg_cpu->iowait_boost; + boost_max = sg_cpu->iowait_boost_max; + if (*util * boost_max < *max * boost_util) { *util = boost_util; *max = boost_max; } - sg_cpu->iowait_boost >>= 1; } #ifdef CONFIG_NO_HZ_COMMON @@ -229,7 +275,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, if (flags & SCHED_CPUFREQ_RT_DL) { next_f = policy->cpuinfo.max_freq; } else { - sugov_get_util(&util, &max); + sugov_get_util(&util, &max, sg_cpu->cpu); sugov_iowait_boost(sg_cpu, &util, &max); next_f = get_next_freq(sg_policy, util, max); /* @@ -264,6 +310,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time) delta_ns = time - j_sg_cpu->last_update; if (delta_ns > TICK_NSEC) { j_sg_cpu->iowait_boost = 0; + j_sg_cpu->iowait_boost_pending = false; continue; } if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL) @@ -290,7 +337,7 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time, unsigned long util, max; unsigned int next_f; - sugov_get_util(&util, &max); + sugov_get_util(&util, &max, sg_cpu->cpu); raw_spin_lock(&sg_policy->update_lock); @@ -445,7 +492,11 @@ static int sugov_kthread_create(struct sugov_policy *sg_policy) } sg_policy->thread = thread; - kthread_bind_mask(thread, policy->related_cpus); + + /* Kthread is bound to all CPUs by default */ + if (!policy->dvfs_possible_from_any_cpu) + kthread_bind_mask(thread, policy->related_cpus); + init_irq_work(&sg_policy->irq_work, sugov_irq_work); mutex_init(&sg_policy->work_lock); @@ -528,16 +579,7 @@ static int sugov_init(struct cpufreq_policy *policy) goto stop_kthread; } - if (policy->transition_delay_us) { - tunables->rate_limit_us = policy->transition_delay_us; - } else { - unsigned int lat; - - tunables->rate_limit_us = LATENCY_MULTIPLIER; - lat = policy->cpuinfo.transition_latency / NSEC_PER_USEC; - if (lat) - tunables->rate_limit_us *= lat; - } + tunables->rate_limit_us = cpufreq_policy_transition_delay_us(policy); policy->governor_data = sg_policy; sg_policy->tunables = tunables; @@ -655,6 +697,7 @@ static void sugov_limits(struct cpufreq_policy *policy) static struct cpufreq_governor schedutil_gov = { .name = "schedutil", .owner = THIS_MODULE, + .dynamic_switching = true, .init = sugov_init, .exit = sugov_exit, .start = sugov_start, @@ -671,6 +714,11 @@ struct cpufreq_governor *cpufreq_default_governor(void) static int __init sugov_register(void) { + int cpu; + + for_each_possible_cpu(cpu) + per_cpu(sugov_cpu, cpu).cpu = cpu; + return cpufreq_register_governor(&schedutil_gov); } fs_initcall(sugov_register); diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c index 981fcd7dc394eb10dd26113c66815dd0aa8e6a46..2511aba36b89e5e6581d3b9f0c33257a3c09a394 100644 --- a/kernel/sched/cpupri.c +++ b/kernel/sched/cpupri.c @@ -209,8 +209,6 @@ int cpupri_init(struct cpupri *cp) { int i; - memset(cp, 0, sizeof(*cp)); - for (i = 0; i < CPUPRI_NR_PRIORITIES; i++) { struct cpupri_vec *vec = &cp->pri_to_cpu[i]; diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 755bd3f1a1a93a8f1daf713dd36578637ce515c5..0191ec7667c326d603ed058f9a393af0436b7c76 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -296,7 +296,7 @@ static inline int is_leftmost(struct task_struct *p, struct dl_rq *dl_rq) { struct sched_dl_entity *dl_se = &p->dl; - return dl_rq->rb_leftmost == &dl_se->rb_node; + return dl_rq->root.rb_leftmost == &dl_se->rb_node; } void init_dl_bandwidth(struct dl_bandwidth *dl_b, u64 period, u64 runtime) @@ -320,7 +320,7 @@ void init_dl_bw(struct dl_bw *dl_b) void init_dl_rq(struct dl_rq *dl_rq) { - dl_rq->rb_root = RB_ROOT; + dl_rq->root = RB_ROOT_CACHED; #ifdef CONFIG_SMP /* zero means no -deadline tasks */ @@ -328,7 +328,7 @@ void init_dl_rq(struct dl_rq *dl_rq) dl_rq->dl_nr_migratory = 0; dl_rq->overloaded = 0; - dl_rq->pushable_dl_tasks_root = RB_ROOT; + dl_rq->pushable_dl_tasks_root = RB_ROOT_CACHED; #else init_dl_bw(&dl_rq->dl_bw); #endif @@ -410,10 +410,10 @@ static void dec_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) static void enqueue_pushable_dl_task(struct rq *rq, struct task_struct *p) { struct dl_rq *dl_rq = &rq->dl; - struct rb_node **link = &dl_rq->pushable_dl_tasks_root.rb_node; + struct rb_node **link = &dl_rq->pushable_dl_tasks_root.rb_root.rb_node; struct rb_node *parent = NULL; struct task_struct *entry; - int leftmost = 1; + bool leftmost = true; BUG_ON(!RB_EMPTY_NODE(&p->pushable_dl_tasks)); @@ -425,17 +425,16 @@ static void enqueue_pushable_dl_task(struct rq *rq, struct task_struct *p) link = &parent->rb_left; else { link = &parent->rb_right; - leftmost = 0; + leftmost = false; } } - if (leftmost) { - dl_rq->pushable_dl_tasks_leftmost = &p->pushable_dl_tasks; + if (leftmost) dl_rq->earliest_dl.next = p->dl.deadline; - } rb_link_node(&p->pushable_dl_tasks, parent, link); - rb_insert_color(&p->pushable_dl_tasks, &dl_rq->pushable_dl_tasks_root); + rb_insert_color_cached(&p->pushable_dl_tasks, + &dl_rq->pushable_dl_tasks_root, leftmost); } static void dequeue_pushable_dl_task(struct rq *rq, struct task_struct *p) @@ -445,24 +444,23 @@ static void dequeue_pushable_dl_task(struct rq *rq, struct task_struct *p) if (RB_EMPTY_NODE(&p->pushable_dl_tasks)) return; - if (dl_rq->pushable_dl_tasks_leftmost == &p->pushable_dl_tasks) { + if (dl_rq->pushable_dl_tasks_root.rb_leftmost == &p->pushable_dl_tasks) { struct rb_node *next_node; next_node = rb_next(&p->pushable_dl_tasks); - dl_rq->pushable_dl_tasks_leftmost = next_node; if (next_node) { dl_rq->earliest_dl.next = rb_entry(next_node, struct task_struct, pushable_dl_tasks)->dl.deadline; } } - rb_erase(&p->pushable_dl_tasks, &dl_rq->pushable_dl_tasks_root); + rb_erase_cached(&p->pushable_dl_tasks, &dl_rq->pushable_dl_tasks_root); RB_CLEAR_NODE(&p->pushable_dl_tasks); } static inline int has_pushable_dl_tasks(struct rq *rq) { - return !RB_EMPTY_ROOT(&rq->dl.pushable_dl_tasks_root); + return !RB_EMPTY_ROOT(&rq->dl.pushable_dl_tasks_root.rb_root); } static int push_dl_task(struct rq *rq); @@ -1136,7 +1134,7 @@ static void update_curr_dl(struct rq *rq) } /* kick cpufreq (see the comment in kernel/sched/sched.h). */ - cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_DL); + cpufreq_update_util(rq, SCHED_CPUFREQ_DL); schedstat_set(curr->se.statistics.exec_max, max(curr->se.statistics.exec_max, delta_exec)); @@ -1266,7 +1264,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) dl_rq->earliest_dl.next = 0; cpudl_clear(&rq->rd->cpudl, rq->cpu); } else { - struct rb_node *leftmost = dl_rq->rb_leftmost; + struct rb_node *leftmost = dl_rq->root.rb_leftmost; struct sched_dl_entity *entry; entry = rb_entry(leftmost, struct sched_dl_entity, rb_node); @@ -1313,7 +1311,7 @@ void dec_dl_tasks(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) static void __enqueue_dl_entity(struct sched_dl_entity *dl_se) { struct dl_rq *dl_rq = dl_rq_of_se(dl_se); - struct rb_node **link = &dl_rq->rb_root.rb_node; + struct rb_node **link = &dl_rq->root.rb_root.rb_node; struct rb_node *parent = NULL; struct sched_dl_entity *entry; int leftmost = 1; @@ -1331,11 +1329,8 @@ static void __enqueue_dl_entity(struct sched_dl_entity *dl_se) } } - if (leftmost) - dl_rq->rb_leftmost = &dl_se->rb_node; - rb_link_node(&dl_se->rb_node, parent, link); - rb_insert_color(&dl_se->rb_node, &dl_rq->rb_root); + rb_insert_color_cached(&dl_se->rb_node, &dl_rq->root, leftmost); inc_dl_tasks(dl_se, dl_rq); } @@ -1347,14 +1342,7 @@ static void __dequeue_dl_entity(struct sched_dl_entity *dl_se) if (RB_EMPTY_NODE(&dl_se->rb_node)) return; - if (dl_rq->rb_leftmost == &dl_se->rb_node) { - struct rb_node *next_node; - - next_node = rb_next(&dl_se->rb_node); - dl_rq->rb_leftmost = next_node; - } - - rb_erase(&dl_se->rb_node, &dl_rq->rb_root); + rb_erase_cached(&dl_se->rb_node, &dl_rq->root); RB_CLEAR_NODE(&dl_se->rb_node); dec_dl_tasks(dl_se, dl_rq); @@ -1594,7 +1582,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p) * let's hope p can move out. */ if (rq->curr->nr_cpus_allowed == 1 || - cpudl_find(&rq->rd->cpudl, rq->curr, NULL) == -1) + !cpudl_find(&rq->rd->cpudl, rq->curr, NULL)) return; /* @@ -1602,7 +1590,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p) * see if it is pushed or pulled somewhere else. */ if (p->nr_cpus_allowed != 1 && - cpudl_find(&rq->rd->cpudl, p, NULL) != -1) + cpudl_find(&rq->rd->cpudl, p, NULL)) return; resched_curr(rq); @@ -1647,7 +1635,7 @@ static void start_hrtick_dl(struct rq *rq, struct task_struct *p) static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq, struct dl_rq *dl_rq) { - struct rb_node *left = dl_rq->rb_leftmost; + struct rb_node *left = rb_first_cached(&dl_rq->root); if (!left) return NULL; @@ -1655,7 +1643,7 @@ static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq, return rb_entry(left, struct sched_dl_entity, rb_node); } -struct task_struct * +static struct task_struct * pick_next_task_dl(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) { struct sched_dl_entity *dl_se; @@ -1771,7 +1759,7 @@ static int pick_dl_task(struct rq *rq, struct task_struct *p, int cpu) */ static struct task_struct *pick_earliest_pushable_dl_task(struct rq *rq, int cpu) { - struct rb_node *next_node = rq->dl.pushable_dl_tasks_leftmost; + struct rb_node *next_node = rq->dl.pushable_dl_tasks_root.rb_leftmost; struct task_struct *p = NULL; if (!has_pushable_dl_tasks(rq)) @@ -1798,7 +1786,7 @@ static int find_later_rq(struct task_struct *task) struct sched_domain *sd; struct cpumask *later_mask = this_cpu_cpumask_var_ptr(local_cpu_mask_dl); int this_cpu = smp_processor_id(); - int best_cpu, cpu = task_cpu(task); + int cpu = task_cpu(task); /* Make sure the mask is initialized first */ if (unlikely(!later_mask)) @@ -1811,17 +1799,14 @@ static int find_later_rq(struct task_struct *task) * We have to consider system topology and task affinity * first, then we can look for a suitable cpu. */ - best_cpu = cpudl_find(&task_rq(task)->rd->cpudl, - task, later_mask); - if (best_cpu == -1) + if (!cpudl_find(&task_rq(task)->rd->cpudl, task, later_mask)) return -1; /* - * If we are here, some target has been found, - * the most suitable of which is cached in best_cpu. - * This is, among the runqueues where the current tasks - * have later deadlines than the task's one, the rq - * with the latest possible one. + * If we are here, some targets have been found, including + * the most suitable which is, among the runqueues where the + * current tasks have later deadlines than the task's one, the + * rq with the latest possible one. * * Now we check how well this matches with task's * affinity and system topology. @@ -1841,6 +1826,7 @@ static int find_later_rq(struct task_struct *task) rcu_read_lock(); for_each_domain(cpu, sd) { if (sd->flags & SD_WAKE_AFFINE) { + int best_cpu; /* * If possible, preempting this_cpu is @@ -1852,12 +1838,15 @@ static int find_later_rq(struct task_struct *task) return this_cpu; } + best_cpu = cpumask_first_and(later_mask, + sched_domain_span(sd)); /* - * Last chance: if best_cpu is valid and is - * in the mask, that becomes our choice. + * Last chance: if a cpu being in both later_mask + * and current sd span is valid, that becomes our + * choice. Of course, the latest possible cpu is + * already under consideration through later_mask. */ - if (best_cpu < nr_cpu_ids && - cpumask_test_cpu(best_cpu, sched_domain_span(sd))) { + if (best_cpu < nr_cpu_ids) { rcu_read_unlock(); return best_cpu; } @@ -1944,7 +1933,7 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq) if (!has_pushable_dl_tasks(rq)) return NULL; - p = rb_entry(rq->dl.pushable_dl_tasks_leftmost, + p = rb_entry(rq->dl.pushable_dl_tasks_root.rb_leftmost, struct task_struct, pushable_dl_tasks); BUG_ON(rq->cpu != task_cpu(p)); diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 4fa66de52bd6ad8d88ed2c95650a274206e3de1d..2f93e4a2d9f623915d0023f9b3a7d8b7d7b95cf7 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -181,11 +181,16 @@ static const struct file_operations sched_feat_fops = { .release = single_release, }; +__read_mostly bool sched_debug_enabled; + static __init int sched_init_debug(void) { debugfs_create_file("sched_features", 0644, NULL, NULL, &sched_feat_fops); + debugfs_create_bool("sched_debug", 0644, NULL, + &sched_debug_enabled); + return 0; } late_initcall(sched_init_debug); @@ -327,38 +332,78 @@ static struct ctl_table *sd_alloc_ctl_cpu_table(int cpu) return table; } +static cpumask_var_t sd_sysctl_cpus; static struct ctl_table_header *sd_sysctl_header; + void register_sched_domain_sysctl(void) { - int i, cpu_num = num_possible_cpus(); - struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); + static struct ctl_table *cpu_entries; + static struct ctl_table **cpu_idx; char buf[32]; + int i; - WARN_ON(sd_ctl_dir[0].child); - sd_ctl_dir[0].child = entry; + if (!cpu_entries) { + cpu_entries = sd_alloc_ctl_entry(num_possible_cpus() + 1); + if (!cpu_entries) + return; - if (entry == NULL) - return; + WARN_ON(sd_ctl_dir[0].child); + sd_ctl_dir[0].child = cpu_entries; + } - for_each_possible_cpu(i) { - snprintf(buf, 32, "cpu%d", i); - entry->procname = kstrdup(buf, GFP_KERNEL); - entry->mode = 0555; - entry->child = sd_alloc_ctl_cpu_table(i); - entry++; + if (!cpu_idx) { + struct ctl_table *e = cpu_entries; + + cpu_idx = kcalloc(nr_cpu_ids, sizeof(struct ctl_table*), GFP_KERNEL); + if (!cpu_idx) + return; + + /* deal with sparse possible map */ + for_each_possible_cpu(i) { + cpu_idx[i] = e; + e++; + } + } + + if (!cpumask_available(sd_sysctl_cpus)) { + if (!alloc_cpumask_var(&sd_sysctl_cpus, GFP_KERNEL)) + return; + + /* init to possible to not have holes in @cpu_entries */ + cpumask_copy(sd_sysctl_cpus, cpu_possible_mask); + } + + for_each_cpu(i, sd_sysctl_cpus) { + struct ctl_table *e = cpu_idx[i]; + + if (e->child) + sd_free_ctl_entry(&e->child); + + if (!e->procname) { + snprintf(buf, 32, "cpu%d", i); + e->procname = kstrdup(buf, GFP_KERNEL); + } + e->mode = 0555; + e->child = sd_alloc_ctl_cpu_table(i); + + __cpumask_clear_cpu(i, sd_sysctl_cpus); } WARN_ON(sd_sysctl_header); sd_sysctl_header = register_sysctl_table(sd_ctl_root); } +void dirty_sched_domain_sysctl(int cpu) +{ + if (cpumask_available(sd_sysctl_cpus)) + __cpumask_set_cpu(cpu, sd_sysctl_cpus); +} + /* may be called multiple times per register */ void unregister_sched_domain_sysctl(void) { unregister_sysctl_table(sd_sysctl_header); sd_sysctl_header = NULL; - if (sd_ctl_dir[0].child) - sd_free_ctl_entry(&sd_ctl_dir[0].child); } #endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SMP */ @@ -425,9 +470,9 @@ static void print_task(struct seq_file *m, struct rq *rq, struct task_struct *p) { if (rq->curr == p) - SEQ_printf(m, "R"); + SEQ_printf(m, ">R"); else - SEQ_printf(m, " "); + SEQ_printf(m, " %c", task_state_to_char(p)); SEQ_printf(m, "%15s %5d %9Ld.%06ld %9Ld %5d ", p->comm, task_pid_nr(p), @@ -456,9 +501,9 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu) SEQ_printf(m, "\nrunnable tasks:\n" - " task PID tree-key switches prio" + " S task PID tree-key switches prio" " wait-time sum-exec sum-sleep\n" - "------------------------------------------------------" + "-------------------------------------------------------" "----------------------------------------------------\n"); rcu_read_lock(); @@ -488,7 +533,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) SPLIT_NS(cfs_rq->exec_clock)); raw_spin_lock_irqsave(&rq->lock, flags); - if (cfs_rq->rb_leftmost) + if (rb_first_cached(&cfs_rq->tasks_timeline)) MIN_vruntime = (__pick_first_entity(cfs_rq))->vruntime; last = __pick_last_entity(cfs_rq); if (last) @@ -872,11 +917,12 @@ static void sched_show_numa(struct task_struct *p, struct seq_file *m) #endif } -void proc_sched_show_task(struct task_struct *p, struct seq_file *m) +void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns, + struct seq_file *m) { unsigned long nr_switches; - SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, task_pid_nr(p), + SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, task_pid_nr_ns(p, ns), get_nr_threads(p)); SEQ_printf(m, "---------------------------------------------------------" diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c95880e216f6900ed06e92e93ddc355d20e59092..70ba32e08a231858326211b7f64a3ae6a3f4dbd3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -513,6 +513,7 @@ static inline int entity_before(struct sched_entity *a, static void update_min_vruntime(struct cfs_rq *cfs_rq) { struct sched_entity *curr = cfs_rq->curr; + struct rb_node *leftmost = rb_first_cached(&cfs_rq->tasks_timeline); u64 vruntime = cfs_rq->min_vruntime; @@ -523,10 +524,9 @@ static void update_min_vruntime(struct cfs_rq *cfs_rq) curr = NULL; } - if (cfs_rq->rb_leftmost) { - struct sched_entity *se = rb_entry(cfs_rq->rb_leftmost, - struct sched_entity, - run_node); + if (leftmost) { /* non-empty tree */ + struct sched_entity *se; + se = rb_entry(leftmost, struct sched_entity, run_node); if (!curr) vruntime = se->vruntime; @@ -547,10 +547,10 @@ static void update_min_vruntime(struct cfs_rq *cfs_rq) */ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) { - struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; + struct rb_node **link = &cfs_rq->tasks_timeline.rb_root.rb_node; struct rb_node *parent = NULL; struct sched_entity *entry; - int leftmost = 1; + bool leftmost = true; /* * Find the right place in the rbtree: @@ -566,36 +566,23 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) link = &parent->rb_left; } else { link = &parent->rb_right; - leftmost = 0; + leftmost = false; } } - /* - * Maintain a cache of leftmost tree entries (it is frequently - * used): - */ - if (leftmost) - cfs_rq->rb_leftmost = &se->run_node; - rb_link_node(&se->run_node, parent, link); - rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); + rb_insert_color_cached(&se->run_node, + &cfs_rq->tasks_timeline, leftmost); } static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) { - if (cfs_rq->rb_leftmost == &se->run_node) { - struct rb_node *next_node; - - next_node = rb_next(&se->run_node); - cfs_rq->rb_leftmost = next_node; - } - - rb_erase(&se->run_node, &cfs_rq->tasks_timeline); + rb_erase_cached(&se->run_node, &cfs_rq->tasks_timeline); } struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq) { - struct rb_node *left = cfs_rq->rb_leftmost; + struct rb_node *left = rb_first_cached(&cfs_rq->tasks_timeline); if (!left) return NULL; @@ -616,7 +603,7 @@ static struct sched_entity *__pick_next_entity(struct sched_entity *se) #ifdef CONFIG_SCHED_DEBUG struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { - struct rb_node *last = rb_last(&cfs_rq->tasks_timeline); + struct rb_node *last = rb_last(&cfs_rq->tasks_timeline.rb_root); if (!last) return NULL; @@ -806,7 +793,7 @@ void post_init_entity_util_avg(struct sched_entity *se) /* * For !fair tasks do: * - update_cfs_rq_load_avg(now, cfs_rq, false); + update_cfs_rq_load_avg(now, cfs_rq); attach_entity_load_avg(cfs_rq, se); switched_from_fair(rq, p); * @@ -1071,6 +1058,29 @@ unsigned int sysctl_numa_balancing_scan_size = 256; /* Scan @scan_size MB every @scan_period after an initial @scan_delay in ms */ unsigned int sysctl_numa_balancing_scan_delay = 1000; +struct numa_group { + atomic_t refcount; + + spinlock_t lock; /* nr_tasks, tasks */ + int nr_tasks; + pid_t gid; + int active_nodes; + + struct rcu_head rcu; + unsigned long total_faults; + unsigned long max_faults_cpu; + /* + * Faults_cpu is used to decide whether memory should move + * towards the CPU. As a consequence, these stats are weighted + * more by CPU use than by memory faults. + */ + unsigned long *faults_cpu; + unsigned long faults[0]; +}; + +static inline unsigned long group_faults_priv(struct numa_group *ng); +static inline unsigned long group_faults_shared(struct numa_group *ng); + static unsigned int task_nr_scan_windows(struct task_struct *p) { unsigned long rss = 0; @@ -1107,13 +1117,47 @@ static unsigned int task_scan_min(struct task_struct *p) return max_t(unsigned int, floor, scan); } +static unsigned int task_scan_start(struct task_struct *p) +{ + unsigned long smin = task_scan_min(p); + unsigned long period = smin; + + /* Scale the maximum scan period with the amount of shared memory. */ + if (p->numa_group) { + struct numa_group *ng = p->numa_group; + unsigned long shared = group_faults_shared(ng); + unsigned long private = group_faults_priv(ng); + + period *= atomic_read(&ng->refcount); + period *= shared + 1; + period /= private + shared + 1; + } + + return max(smin, period); +} + static unsigned int task_scan_max(struct task_struct *p) { - unsigned int smin = task_scan_min(p); - unsigned int smax; + unsigned long smin = task_scan_min(p); + unsigned long smax; /* Watch for min being lower than max due to floor calculations */ smax = sysctl_numa_balancing_scan_period_max / task_nr_scan_windows(p); + + /* Scale the maximum scan period with the amount of shared memory. */ + if (p->numa_group) { + struct numa_group *ng = p->numa_group; + unsigned long shared = group_faults_shared(ng); + unsigned long private = group_faults_priv(ng); + unsigned long period = smax; + + period *= atomic_read(&ng->refcount); + period *= shared + 1; + period /= private + shared + 1; + + smax = max(smax, period); + } + return max(smin, smax); } @@ -1129,26 +1173,6 @@ static void account_numa_dequeue(struct rq *rq, struct task_struct *p) rq->nr_preferred_running -= (p->numa_preferred_nid == task_node(p)); } -struct numa_group { - atomic_t refcount; - - spinlock_t lock; /* nr_tasks, tasks */ - int nr_tasks; - pid_t gid; - int active_nodes; - - struct rcu_head rcu; - unsigned long total_faults; - unsigned long max_faults_cpu; - /* - * Faults_cpu is used to decide whether memory should move - * towards the CPU. As a consequence, these stats are weighted - * more by CPU use than by memory faults. - */ - unsigned long *faults_cpu; - unsigned long faults[0]; -}; - /* Shared or private faults. */ #define NR_NUMA_HINT_FAULT_TYPES 2 @@ -1198,6 +1222,30 @@ static inline unsigned long group_faults_cpu(struct numa_group *group, int nid) group->faults_cpu[task_faults_idx(NUMA_MEM, nid, 1)]; } +static inline unsigned long group_faults_priv(struct numa_group *ng) +{ + unsigned long faults = 0; + int node; + + for_each_online_node(node) { + faults += ng->faults[task_faults_idx(NUMA_MEM, node, 1)]; + } + + return faults; +} + +static inline unsigned long group_faults_shared(struct numa_group *ng) +{ + unsigned long faults = 0; + int node; + + for_each_online_node(node) { + faults += ng->faults[task_faults_idx(NUMA_MEM, node, 0)]; + } + + return faults; +} + /* * A node triggering more than 1/3 as many NUMA faults as the maximum is * considered part of a numa group's pseudo-interleaving set. Migrations @@ -1378,7 +1426,7 @@ bool should_numa_migrate_memory(struct task_struct *p, struct page * page, group_faults_cpu(ng, src_nid) * group_faults(p, dst_nid) * 4; } -static unsigned long weighted_cpuload(const int cpu); +static unsigned long weighted_cpuload(struct rq *rq); static unsigned long source_load(int cpu, int type); static unsigned long target_load(int cpu, int type); static unsigned long capacity_of(int cpu); @@ -1409,7 +1457,7 @@ static void update_numa_stats(struct numa_stats *ns, int nid) struct rq *rq = cpu_rq(cpu); ns->nr_running += rq->nr_running; - ns->load += weighted_cpuload(cpu); + ns->load += weighted_cpuload(rq); ns->compute_capacity += capacity_of(cpu); cpus++; @@ -1808,7 +1856,7 @@ static int task_numa_migrate(struct task_struct *p) * Reset the scan period if the task is being rescheduled on an * alternative node to recheck if the tasks is now properly placed. */ - p->numa_scan_period = task_scan_min(p); + p->numa_scan_period = task_scan_start(p); if (env.best_task == NULL) { ret = migrate_task_to(p, env.best_cpu); @@ -1892,7 +1940,7 @@ static void update_task_scan_period(struct task_struct *p, unsigned long shared, unsigned long private) { unsigned int period_slot; - int ratio; + int lr_ratio, ps_ratio; int diff; unsigned long remote = p->numa_faults_locality[0]; @@ -1922,25 +1970,36 @@ static void update_task_scan_period(struct task_struct *p, * >= NUMA_PERIOD_THRESHOLD scan period increases (scan slower) */ period_slot = DIV_ROUND_UP(p->numa_scan_period, NUMA_PERIOD_SLOTS); - ratio = (local * NUMA_PERIOD_SLOTS) / (local + remote); - if (ratio >= NUMA_PERIOD_THRESHOLD) { - int slot = ratio - NUMA_PERIOD_THRESHOLD; + lr_ratio = (local * NUMA_PERIOD_SLOTS) / (local + remote); + ps_ratio = (private * NUMA_PERIOD_SLOTS) / (private + shared); + + if (ps_ratio >= NUMA_PERIOD_THRESHOLD) { + /* + * Most memory accesses are local. There is no need to + * do fast NUMA scanning, since memory is already local. + */ + int slot = ps_ratio - NUMA_PERIOD_THRESHOLD; + if (!slot) + slot = 1; + diff = slot * period_slot; + } else if (lr_ratio >= NUMA_PERIOD_THRESHOLD) { + /* + * Most memory accesses are shared with other tasks. + * There is no point in continuing fast NUMA scanning, + * since other tasks may just move the memory elsewhere. + */ + int slot = lr_ratio - NUMA_PERIOD_THRESHOLD; if (!slot) slot = 1; diff = slot * period_slot; } else { - diff = -(NUMA_PERIOD_THRESHOLD - ratio) * period_slot; - /* - * Scale scan rate increases based on sharing. There is an - * inverse relationship between the degree of sharing and - * the adjustment made to the scanning period. Broadly - * speaking the intent is that there is little point - * scanning faster if shared accesses dominate as it may - * simply bounce migrations uselessly + * Private memory faults exceed (SLOTS-THRESHOLD)/SLOTS, + * yet they are not on the local NUMA node. Speed up + * NUMA scanning to get the memory moved over. */ - ratio = DIV_ROUND_UP(private * NUMA_PERIOD_SLOTS, (private + shared + 1)); - diff = (diff * ratio) / NUMA_PERIOD_SLOTS; + int ratio = max(lr_ratio, ps_ratio); + diff = -(NUMA_PERIOD_THRESHOLD - ratio) * period_slot; } p->numa_scan_period = clamp(p->numa_scan_period + diff, @@ -2448,7 +2507,7 @@ void task_numa_work(struct callback_head *work) if (p->numa_scan_period == 0) { p->numa_scan_period_max = task_scan_max(p); - p->numa_scan_period = task_scan_min(p); + p->numa_scan_period = task_scan_start(p); } next_scan = now + msecs_to_jiffies(p->numa_scan_period); @@ -2576,7 +2635,7 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr) if (now > curr->node_stamp + period) { if (!curr->node_stamp) - curr->numa_scan_period = task_scan_min(curr); + curr->numa_scan_period = task_scan_start(curr); curr->node_stamp += period; if (!time_before(jiffies, curr->mm->numa_next_scan)) { @@ -2586,59 +2645,6 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr) } } -/* - * Can a task be moved from prev_cpu to this_cpu without causing a load - * imbalance that would trigger the load balancer? - */ -static inline bool numa_wake_affine(struct sched_domain *sd, - struct task_struct *p, int this_cpu, - int prev_cpu, int sync) -{ - struct numa_stats prev_load, this_load; - s64 this_eff_load, prev_eff_load; - - update_numa_stats(&prev_load, cpu_to_node(prev_cpu)); - update_numa_stats(&this_load, cpu_to_node(this_cpu)); - - /* - * If sync wakeup then subtract the (maximum possible) - * effect of the currently running task from the load - * of the current CPU: - */ - if (sync) { - unsigned long current_load = task_h_load(current); - - if (this_load.load > current_load) - this_load.load -= current_load; - else - this_load.load = 0; - } - - /* - * In low-load situations, where this_cpu's node is idle due to the - * sync cause above having dropped this_load.load to 0, move the task. - * Moving to an idle socket will not create a bad imbalance. - * - * Otherwise check if the nodes are near enough in load to allow this - * task to be woken on this_cpu's node. - */ - if (this_load.load > 0) { - unsigned long task_load = task_h_load(p); - - this_eff_load = 100; - this_eff_load *= prev_load.compute_capacity; - - prev_eff_load = 100 + (sd->imbalance_pct - 100) / 2; - prev_eff_load *= this_load.compute_capacity; - - this_eff_load *= this_load.load + task_load; - prev_eff_load *= prev_load.load - task_load; - - return this_eff_load <= prev_eff_load; - } - - return true; -} #else static void task_tick_numa(struct rq *rq, struct task_struct *curr) { @@ -2652,14 +2658,6 @@ static inline void account_numa_dequeue(struct rq *rq, struct task_struct *p) { } -#ifdef CONFIG_SMP -static inline bool numa_wake_affine(struct sched_domain *sd, - struct task_struct *p, int this_cpu, - int prev_cpu, int sync) -{ - return true; -} -#endif /* !SMP */ #endif /* CONFIG_NUMA_BALANCING */ static void @@ -2790,6 +2788,31 @@ static inline void update_cfs_shares(struct sched_entity *se) } #endif /* CONFIG_FAIR_GROUP_SCHED */ +static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) +{ + struct rq *rq = rq_of(cfs_rq); + + if (&rq->cfs == cfs_rq) { + /* + * There are a few boundary cases this might miss but it should + * get called often enough that that should (hopefully) not be + * a real problem -- added to that it only calls on the local + * CPU, so if we enqueue remotely we'll miss an update, but + * the next tick/schedule should update. + * + * It will not get called when we go idle, because the idle + * thread is a different class (!fair), nor will the utilization + * number include things like RT tasks. + * + * As is, the util number is not freq-invariant (we'd have to + * implement arch_scale_freq_capacity() for that). + * + * See cpu_util(). + */ + cpufreq_update_util(rq, 0); + } +} + #ifdef CONFIG_SMP /* * Approximate: @@ -2967,6 +2990,18 @@ ___update_load_avg(u64 now, int cpu, struct sched_avg *sa, sa->last_update_time += delta << 10; + /* + * running is a subset of runnable (weight) so running can't be set if + * runnable is clear. But there are some corner cases where the current + * se has been already dequeued but cfs_rq->curr still points to it. + * This means that weight will be 0 but not running for a sched_entity + * but also for a cfs_rq if the latter becomes idle. As an example, + * this happens during idle_balance() which calls + * update_blocked_averages() + */ + if (!weight) + running = 0; + /* * Now we know we crossed measurement unit boundaries. The *_avg * accrues by two steps: @@ -3276,29 +3311,6 @@ static inline void set_tg_cfs_propagate(struct cfs_rq *cfs_rq) {} #endif /* CONFIG_FAIR_GROUP_SCHED */ -static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) -{ - if (&this_rq()->cfs == cfs_rq) { - /* - * There are a few boundary cases this might miss but it should - * get called often enough that that should (hopefully) not be - * a real problem -- added to that it only calls on the local - * CPU, so if we enqueue remotely we'll miss an update, but - * the next tick/schedule should update. - * - * It will not get called when we go idle, because the idle - * thread is a different class (!fair), nor will the utilization - * number include things like RT tasks. - * - * As is, the util number is not freq-invariant (we'd have to - * implement arch_scale_freq_capacity() for that). - * - * See cpu_util(). - */ - cpufreq_update_util(rq_of(cfs_rq), 0); - } -} - /* * Unsigned subtract and clamp on underflow. * @@ -3320,7 +3332,6 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) * update_cfs_rq_load_avg - update the cfs_rq's load/util averages * @now: current time, as per cfs_rq_clock_task() * @cfs_rq: cfs_rq to update - * @update_freq: should we call cfs_rq_util_change() or will the call do so * * The cfs_rq avg is the direct sum of all its entities (blocked and runnable) * avg. The immediate corollary is that all (fair) tasks must be attached, see @@ -3334,7 +3345,7 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) * call update_tg_load_avg() when this function returns true. */ static inline int -update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq) +update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) { struct sched_avg *sa = &cfs_rq->avg; int decayed, removed_load = 0, removed_util = 0; @@ -3362,7 +3373,7 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq) cfs_rq->load_last_update_time_copy = sa->last_update_time; #endif - if (update_freq && (decayed || removed_util)) + if (decayed || removed_util) cfs_rq_util_change(cfs_rq); return decayed || removed_load; @@ -3390,7 +3401,7 @@ static inline void update_load_avg(struct sched_entity *se, int flags) if (se->avg.last_update_time && !(flags & SKIP_AGE_LOAD)) __update_load_avg_se(now, cpu, cfs_rq, se); - decayed = update_cfs_rq_load_avg(now, cfs_rq, true); + decayed = update_cfs_rq_load_avg(now, cfs_rq); decayed |= propagate_entity_load_avg(se); if (decayed && (flags & UPDATE_TG)) @@ -3534,7 +3545,7 @@ static int idle_balance(struct rq *this_rq, struct rq_flags *rf); #else /* CONFIG_SMP */ static inline int -update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq) +update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) { return 0; } @@ -3544,7 +3555,7 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq) static inline void update_load_avg(struct sched_entity *se, int not_used1) { - cpufreq_update_util(rq_of(cfs_rq_of(se)), 0); + cfs_rq_util_change(cfs_rq_of(se)); } static inline void @@ -4875,7 +4886,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) * passed. */ if (p->in_iowait) - cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_IOWAIT); + cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT); for_each_sched_entity(se) { if (se->on_rq) @@ -5125,9 +5136,9 @@ static void cpu_load_update(struct rq *this_rq, unsigned long this_load, } /* Used instead of source_load when we know the type == 0 */ -static unsigned long weighted_cpuload(const int cpu) +static unsigned long weighted_cpuload(struct rq *rq) { - return cfs_rq_runnable_load_avg(&cpu_rq(cpu)->cfs); + return cfs_rq_runnable_load_avg(&rq->cfs); } #ifdef CONFIG_NO_HZ_COMMON @@ -5172,7 +5183,7 @@ static void cpu_load_update_idle(struct rq *this_rq) /* * bail if there's load or we're actually up-to-date. */ - if (weighted_cpuload(cpu_of(this_rq))) + if (weighted_cpuload(this_rq)) return; cpu_load_update_nohz(this_rq, READ_ONCE(jiffies), 0); @@ -5193,7 +5204,7 @@ void cpu_load_update_nohz_start(void) * concurrently we'll exit nohz. And cpu_load write can race with * cpu_load_update_idle() but both updater would be writing the same. */ - this_rq->cpu_load[0] = weighted_cpuload(cpu_of(this_rq)); + this_rq->cpu_load[0] = weighted_cpuload(this_rq); } /* @@ -5209,7 +5220,7 @@ void cpu_load_update_nohz_stop(void) if (curr_jiffies == this_rq->last_load_update_tick) return; - load = weighted_cpuload(cpu_of(this_rq)); + load = weighted_cpuload(this_rq); rq_lock(this_rq, &rf); update_rq_clock(this_rq); cpu_load_update_nohz(this_rq, curr_jiffies, load); @@ -5235,7 +5246,7 @@ static void cpu_load_update_periodic(struct rq *this_rq, unsigned long load) */ void cpu_load_update_active(struct rq *this_rq) { - unsigned long load = weighted_cpuload(cpu_of(this_rq)); + unsigned long load = weighted_cpuload(this_rq); if (tick_nohz_tick_stopped()) cpu_load_update_nohz(this_rq, READ_ONCE(jiffies), load); @@ -5253,7 +5264,7 @@ void cpu_load_update_active(struct rq *this_rq) static unsigned long source_load(int cpu, int type) { struct rq *rq = cpu_rq(cpu); - unsigned long total = weighted_cpuload(cpu); + unsigned long total = weighted_cpuload(rq); if (type == 0 || !sched_feat(LB_BIAS)) return total; @@ -5268,7 +5279,7 @@ static unsigned long source_load(int cpu, int type) static unsigned long target_load(int cpu, int type) { struct rq *rq = cpu_rq(cpu); - unsigned long total = weighted_cpuload(cpu); + unsigned long total = weighted_cpuload(rq); if (type == 0 || !sched_feat(LB_BIAS)) return total; @@ -5290,7 +5301,7 @@ static unsigned long cpu_avg_load_per_task(int cpu) { struct rq *rq = cpu_rq(cpu); unsigned long nr_running = READ_ONCE(rq->cfs.h_nr_running); - unsigned long load_avg = weighted_cpuload(cpu); + unsigned long load_avg = weighted_cpuload(rq); if (nr_running) return load_avg / nr_running; @@ -5345,20 +5356,115 @@ static int wake_wide(struct task_struct *p) return 1; } +struct llc_stats { + unsigned long nr_running; + unsigned long load; + unsigned long capacity; + int has_capacity; +}; + +static bool get_llc_stats(struct llc_stats *stats, int cpu) +{ + struct sched_domain_shared *sds = rcu_dereference(per_cpu(sd_llc_shared, cpu)); + + if (!sds) + return false; + + stats->nr_running = READ_ONCE(sds->nr_running); + stats->load = READ_ONCE(sds->load); + stats->capacity = READ_ONCE(sds->capacity); + stats->has_capacity = stats->nr_running < per_cpu(sd_llc_size, cpu); + + return true; +} + +/* + * Can a task be moved from prev_cpu to this_cpu without causing a load + * imbalance that would trigger the load balancer? + * + * Since we're running on 'stale' values, we might in fact create an imbalance + * but recomputing these values is expensive, as that'd mean iteration 2 cache + * domains worth of CPUs. + */ +static bool +wake_affine_llc(struct sched_domain *sd, struct task_struct *p, + int this_cpu, int prev_cpu, int sync) +{ + struct llc_stats prev_stats, this_stats; + s64 this_eff_load, prev_eff_load; + unsigned long task_load; + + if (!get_llc_stats(&prev_stats, prev_cpu) || + !get_llc_stats(&this_stats, this_cpu)) + return false; + + /* + * If sync wakeup then subtract the (maximum possible) + * effect of the currently running task from the load + * of the current LLC. + */ + if (sync) { + unsigned long current_load = task_h_load(current); + + /* in this case load hits 0 and this LLC is considered 'idle' */ + if (current_load > this_stats.load) + return true; + + this_stats.load -= current_load; + } + + /* + * The has_capacity stuff is not SMT aware, but by trying to balance + * the nr_running on both ends we try and fill the domain at equal + * rates, thereby first consuming cores before siblings. + */ + + /* if the old cache has capacity, stay there */ + if (prev_stats.has_capacity && prev_stats.nr_running < this_stats.nr_running+1) + return false; + + /* if this cache has capacity, come here */ + if (this_stats.has_capacity && this_stats.nr_running+1 < prev_stats.nr_running) + return true; + + /* + * Check to see if we can move the load without causing too much + * imbalance. + */ + task_load = task_h_load(p); + + this_eff_load = 100; + this_eff_load *= prev_stats.capacity; + + prev_eff_load = 100 + (sd->imbalance_pct - 100) / 2; + prev_eff_load *= this_stats.capacity; + + this_eff_load *= this_stats.load + task_load; + prev_eff_load *= prev_stats.load - task_load; + + return this_eff_load <= prev_eff_load; +} + static int wake_affine(struct sched_domain *sd, struct task_struct *p, int prev_cpu, int sync) { int this_cpu = smp_processor_id(); - bool affine = false; + bool affine; /* - * Common case: CPUs are in the same socket, and select_idle_sibling() - * will do its thing regardless of what we return: + * Default to no affine wakeups; wake_affine() should not effect a task + * placement the load-balancer feels inclined to undo. The conservative + * option is therefore to not move tasks when they wake up. */ - if (cpus_share_cache(prev_cpu, this_cpu)) - affine = true; - else - affine = numa_wake_affine(sd, p, this_cpu, prev_cpu, sync); + affine = false; + + /* + * If the wakeup is across cache domains, try to evaluate if movement + * makes sense, otherwise rely on select_idle_siblings() to do + * placement inside the cache domain. + */ + if (!cpus_share_cache(prev_cpu, this_cpu)) + affine = wake_affine_llc(sd, p, this_cpu, prev_cpu, sync); schedstat_inc(p->se.statistics.nr_wakeups_affine_attempts); if (affine) { @@ -5550,7 +5656,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) shallowest_idle_cpu = i; } } else if (shallowest_idle_cpu == -1) { - load = weighted_cpuload(i); + load = weighted_cpuload(cpu_rq(i)); if (load < min_load || (load == min_load && i == this_cpu)) { min_load = load; least_loaded_cpu = i; @@ -6187,10 +6293,10 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf int new_tasks; again: -#ifdef CONFIG_FAIR_GROUP_SCHED if (!cfs_rq->nr_running) goto idle; +#ifdef CONFIG_FAIR_GROUP_SCHED if (prev->sched_class != &fair_sched_class) goto simple; @@ -6220,11 +6326,17 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf /* * This call to check_cfs_rq_runtime() will do the * throttle and dequeue its entity in the parent(s). - * Therefore the 'simple' nr_running test will indeed + * Therefore the nr_running test will indeed * be correct. */ - if (unlikely(check_cfs_rq_runtime(cfs_rq))) + if (unlikely(check_cfs_rq_runtime(cfs_rq))) { + cfs_rq = &rq->cfs; + + if (!cfs_rq->nr_running) + goto idle; + goto simple; + } } se = pick_next_entity(cfs_rq, curr); @@ -6264,12 +6376,8 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf return p; simple: - cfs_rq = &rq->cfs; #endif - if (!cfs_rq->nr_running) - goto idle; - put_prev_task(rq, prev); do { @@ -6917,7 +7025,7 @@ static void update_blocked_averages(int cpu) if (throttled_hierarchy(cfs_rq)) continue; - if (update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq, true)) + if (update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq)) update_tg_load_avg(cfs_rq, 0); /* Propagate pending load changes to the parent, if any: */ @@ -6990,7 +7098,7 @@ static inline void update_blocked_averages(int cpu) rq_lock_irqsave(rq, &rf); update_rq_clock(rq); - update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq, true); + update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq); rq_unlock_irqrestore(rq, &rf); } @@ -7036,6 +7144,7 @@ struct sg_lb_stats { struct sd_lb_stats { struct sched_group *busiest; /* Busiest group in this sd */ struct sched_group *local; /* Local group in this sd */ + unsigned long total_running; unsigned long total_load; /* Total load of all groups in sd */ unsigned long total_capacity; /* Total capacity of all groups in sd */ unsigned long avg_load; /* Average load across all groups in sd */ @@ -7055,6 +7164,7 @@ static inline void init_sd_lb_stats(struct sd_lb_stats *sds) *sds = (struct sd_lb_stats){ .busiest = NULL, .local = NULL, + .total_running = 0UL, .total_load = 0UL, .total_capacity = 0UL, .busiest_stat = { @@ -7363,7 +7473,7 @@ static inline void update_sg_lb_stats(struct lb_env *env, sgs->nr_numa_running += rq->nr_numa_running; sgs->nr_preferred_running += rq->nr_preferred_running; #endif - sgs->sum_weighted_load += weighted_cpuload(i); + sgs->sum_weighted_load += weighted_cpuload(rq); /* * No need to call idle_cpu() if nr_running is not 0 */ @@ -7490,6 +7600,7 @@ static inline enum fbq_type fbq_classify_rq(struct rq *rq) */ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sds) { + struct sched_domain_shared *shared = env->sd->shared; struct sched_domain *child = env->sd->child; struct sched_group *sg = env->sd->groups; struct sg_lb_stats *local = &sds->local_stat; @@ -7546,6 +7657,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd next_group: /* Now, start updating sd_lb_stats */ + sds->total_running += sgs->sum_nr_running; sds->total_load += sgs->group_load; sds->total_capacity += sgs->group_capacity; @@ -7561,6 +7673,21 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd env->dst_rq->rd->overload = overload; } + if (!shared) + return; + + /* + * Since these are sums over groups they can contain some CPUs + * multiple times for the NUMA domains. + * + * Currently only wake_affine_llc() and find_busiest_group() + * uses these numbers, only the last is affected by this problem. + * + * XXX fix that. + */ + WRITE_ONCE(shared->nr_running, sds->total_running); + WRITE_ONCE(shared->load, sds->total_load); + WRITE_ONCE(shared->capacity, sds->total_capacity); } /** @@ -7581,7 +7708,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd * number. * * Return: 1 when packing is required and a task should be moved to - * this CPU. The amount of the imbalance is returned in *imbalance. + * this CPU. The amount of the imbalance is returned in env->imbalance. * * @env: The load balancing environment. * @sds: Statistics of the sched_domain which is to be packed @@ -7790,6 +7917,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env) if (!sds.busiest || busiest->sum_nr_running == 0) goto out_balanced; + /* XXX broken for overlapping NUMA groups */ sds.avg_load = (SCHED_CAPACITY_SCALE * sds.total_load) / sds.total_capacity; @@ -7892,7 +8020,7 @@ static struct rq *find_busiest_queue(struct lb_env *env, capacity = capacity_of(i); - wl = weighted_cpuload(i); + wl = weighted_cpuload(rq); /* * When comparing with imbalance, use weighted_cpuload() @@ -8308,6 +8436,12 @@ static int idle_balance(struct rq *this_rq, struct rq_flags *rf) */ this_rq->idle_stamp = rq_clock(this_rq); + /* + * Do not pull tasks towards !active CPUs... + */ + if (!cpu_active(this_cpu)) + return 0; + /* * This is OK, because current is on_cpu, which avoids it being picked * for load-balance and preemption/IRQs are still disabled avoiding @@ -8415,6 +8549,13 @@ static int active_load_balance_cpu_stop(void *data) struct rq_flags rf; rq_lock_irq(busiest_rq, &rf); + /* + * Between queueing the stop-work and running it is a hole in which + * CPUs can become inactive. We should not move tasks from or to + * inactive CPUs. + */ + if (!cpu_active(busiest_cpu) || !cpu_active(target_cpu)) + goto out_unlock; /* make sure the requested cpu hasn't gone down in the meantime */ if (unlikely(busiest_cpu != smp_processor_id() || @@ -9171,7 +9312,7 @@ static void set_curr_task_fair(struct rq *rq) void init_cfs_rq(struct cfs_rq *cfs_rq) { - cfs_rq->tasks_timeline = RB_ROOT; + cfs_rq->tasks_timeline = RB_ROOT_CACHED; cfs_rq->min_vruntime = (u64)(-(1LL << 20)); #ifndef CONFIG_64BIT cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime; diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 6c23e30c0e5cc5addb9f3bf027161bb366686ef6..257f4f0b4532b0428a8ff3c72513b0a54cb0029d 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -158,7 +158,7 @@ static void cpuidle_idle_call(void) } /* - * Suspend-to-idle ("freeze") is a system state in which all user space + * Suspend-to-idle ("s2idle") is a system state in which all user space * has been frozen, all I/O devices have been suspended and the only * activity happens here and in iterrupts (if any). In that case bypass * the cpuidle governor and go stratight for the deepest idle state @@ -167,9 +167,9 @@ static void cpuidle_idle_call(void) * until a proper wakeup interrupt happens. */ - if (idle_should_freeze() || dev->use_deepest_state) { - if (idle_should_freeze()) { - entered_state = cpuidle_enter_freeze(drv, dev); + if (idle_should_enter_s2idle() || dev->use_deepest_state) { + if (idle_should_enter_s2idle()) { + entered_state = cpuidle_enter_s2idle(drv, dev); if (entered_state > 0) { local_irq_enable(); goto exit_idle; diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c new file mode 100644 index 0000000000000000000000000000000000000000..a92fddc227471e05a77d9f8c4c585b84ba8f28dd --- /dev/null +++ b/kernel/sched/membarrier.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2010-2017 Mathieu Desnoyers + * + * membarrier system call + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include "sched.h" /* for cpu_rq(). */ + +/* + * Bitmask made from a "or" of all commands within enum membarrier_cmd, + * except MEMBARRIER_CMD_QUERY. + */ +#define MEMBARRIER_CMD_BITMASK \ + (MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED) + +static void ipi_mb(void *info) +{ + smp_mb(); /* IPIs should be serializing but paranoid. */ +} + +static void membarrier_private_expedited(void) +{ + int cpu; + bool fallback = false; + cpumask_var_t tmpmask; + + if (num_online_cpus() == 1) + return; + + /* + * Matches memory barriers around rq->curr modification in + * scheduler. + */ + smp_mb(); /* system call entry is not a mb. */ + + /* + * Expedited membarrier commands guarantee that they won't + * block, hence the GFP_NOWAIT allocation flag and fallback + * implementation. + */ + if (!zalloc_cpumask_var(&tmpmask, GFP_NOWAIT)) { + /* Fallback for OOM. */ + fallback = true; + } + + cpus_read_lock(); + for_each_online_cpu(cpu) { + struct task_struct *p; + + /* + * Skipping the current CPU is OK even through we can be + * migrated at any point. The current CPU, at the point + * where we read raw_smp_processor_id(), is ensured to + * be in program order with respect to the caller + * thread. Therefore, we can skip this CPU from the + * iteration. + */ + if (cpu == raw_smp_processor_id()) + continue; + rcu_read_lock(); + p = task_rcu_dereference(&cpu_rq(cpu)->curr); + if (p && p->mm == current->mm) { + if (!fallback) + __cpumask_set_cpu(cpu, tmpmask); + else + smp_call_function_single(cpu, ipi_mb, NULL, 1); + } + rcu_read_unlock(); + } + if (!fallback) { + smp_call_function_many(tmpmask, ipi_mb, NULL, 1); + free_cpumask_var(tmpmask); + } + cpus_read_unlock(); + + /* + * Memory barrier on the caller thread _after_ we finished + * waiting for the last IPI. Matches memory barriers around + * rq->curr modification in scheduler. + */ + smp_mb(); /* exit from system call is not a mb */ +} + +/** + * sys_membarrier - issue memory barriers on a set of threads + * @cmd: Takes command values defined in enum membarrier_cmd. + * @flags: Currently needs to be 0. For future extensions. + * + * If this system call is not implemented, -ENOSYS is returned. If the + * command specified does not exist, not available on the running + * kernel, or if the command argument is invalid, this system call + * returns -EINVAL. For a given command, with flags argument set to 0, + * this system call is guaranteed to always return the same value until + * reboot. + * + * All memory accesses performed in program order from each targeted thread + * is guaranteed to be ordered with respect to sys_membarrier(). If we use + * the semantic "barrier()" to represent a compiler barrier forcing memory + * accesses to be performed in program order across the barrier, and + * smp_mb() to represent explicit memory barriers forcing full memory + * ordering across the barrier, we have the following ordering table for + * each pair of barrier(), sys_membarrier() and smp_mb(): + * + * The pair ordering is detailed as (O: ordered, X: not ordered): + * + * barrier() smp_mb() sys_membarrier() + * barrier() X X O + * smp_mb() X O O + * sys_membarrier() O O O + */ +SYSCALL_DEFINE2(membarrier, int, cmd, int, flags) +{ + if (unlikely(flags)) + return -EINVAL; + switch (cmd) { + case MEMBARRIER_CMD_QUERY: + { + int cmd_mask = MEMBARRIER_CMD_BITMASK; + + if (tick_nohz_full_enabled()) + cmd_mask &= ~MEMBARRIER_CMD_SHARED; + return cmd_mask; + } + case MEMBARRIER_CMD_SHARED: + /* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */ + if (tick_nohz_full_enabled()) + return -EINVAL; + if (num_online_cpus() > 1) + synchronize_sched(); + return 0; + case MEMBARRIER_CMD_PRIVATE_EXPEDITED: + membarrier_private_expedited(); + return 0; + default: + return -EINVAL; + } +} diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 45caf937ef90ead71864d4fbb12e7281e4b8ff9b..0af5ca9e3e3f1d3613e69fabba32d909d0a15f3b 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -970,7 +970,7 @@ static void update_curr_rt(struct rq *rq) return; /* Kick cpufreq (see the comment in kernel/sched/sched.h). */ - cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_RT); + cpufreq_update_util(rq, SCHED_CPUFREQ_RT); schedstat_set(curr->se.statistics.exec_max, max(curr->se.statistics.exec_max, delta_exec)); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index eeef1a3086d1e74af034782cd780bbf7e44333b2..14db76cd496ffb68641c3cc68a9be72205524e1b 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -426,8 +426,7 @@ struct cfs_rq { u64 min_vruntime_copy; #endif - struct rb_root tasks_timeline; - struct rb_node *rb_leftmost; + struct rb_root_cached tasks_timeline; /* * 'curr' points to currently running entity on this cfs_rq. @@ -550,8 +549,7 @@ struct rt_rq { /* Deadline class' related fields in a runqueue */ struct dl_rq { /* runqueue is an rbtree, ordered by deadline */ - struct rb_root rb_root; - struct rb_node *rb_leftmost; + struct rb_root_cached root; unsigned long dl_nr_running; @@ -575,8 +573,7 @@ struct dl_rq { * an rb-tree, ordered by tasks' deadlines, with caching * of the leftmost (earliest deadline) element. */ - struct rb_root pushable_dl_tasks_root; - struct rb_node *pushable_dl_tasks_leftmost; + struct rb_root_cached pushable_dl_tasks_root; #else struct dl_bw dl_bw; #endif @@ -769,7 +766,7 @@ struct rq { #ifdef CONFIG_SCHED_HRTICK #ifdef CONFIG_SMP int hrtick_csd_pending; - struct call_single_data hrtick_csd; + call_single_data_t hrtick_csd; #endif struct hrtimer hrtick_timer; #endif @@ -1120,11 +1117,15 @@ extern int group_balance_cpu(struct sched_group *sg); #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL) void register_sched_domain_sysctl(void); +void dirty_sched_domain_sysctl(int cpu); void unregister_sched_domain_sysctl(void); #else static inline void register_sched_domain_sysctl(void) { } +static inline void dirty_sched_domain_sysctl(int cpu) +{ +} static inline void unregister_sched_domain_sysctl(void) { } @@ -1950,6 +1951,8 @@ extern struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq); extern struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq); #ifdef CONFIG_SCHED_DEBUG +extern bool sched_debug_enabled; + extern void print_cfs_stats(struct seq_file *m, int cpu); extern void print_rt_stats(struct seq_file *m, int cpu); extern void print_dl_stats(struct seq_file *m, int cpu); @@ -2070,19 +2073,13 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) { struct update_util_data *data; - data = rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data)); + data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data, + cpu_of(rq))); if (data) data->func(data, rq_clock(rq), flags); } - -static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) -{ - if (cpu_of(rq) == smp_processor_id()) - cpufreq_update_util(rq, flags); -} #else static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {} -static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) {} #endif /* CONFIG_CPU_FREQ */ #ifdef arch_scale_freq_capacity diff --git a/kernel/sched/swait.c b/kernel/sched/swait.c index 3d5610dcce114d458f2edfddc7c47d345e5882a8..2227e183e202652a164307977503bd271fe4ca16 100644 --- a/kernel/sched/swait.c +++ b/kernel/sched/swait.c @@ -33,9 +33,6 @@ void swake_up(struct swait_queue_head *q) { unsigned long flags; - if (!swait_active(q)) - return; - raw_spin_lock_irqsave(&q->lock, flags); swake_up_locked(q); raw_spin_unlock_irqrestore(&q->lock, flags); @@ -51,9 +48,6 @@ void swake_up_all(struct swait_queue_head *q) struct swait_queue *curr; LIST_HEAD(tmp); - if (!swait_active(q)) - return; - raw_spin_lock_irq(&q->lock); list_splice_init(&q->task_list, &tmp); while (!list_empty(&tmp)) { diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 79895aec281eb5ad198fae3e5e8aed31849ed900..f1cf4f306a8285b642c02ebd28e4d0c78e21e9a5 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -14,11 +14,9 @@ cpumask_var_t sched_domains_tmpmask2; #ifdef CONFIG_SCHED_DEBUG -static __read_mostly int sched_debug_enabled; - static int __init sched_debug_setup(char *str) { - sched_debug_enabled = 1; + sched_debug_enabled = true; return 0; } @@ -261,8 +259,6 @@ void rq_attach_root(struct rq *rq, struct root_domain *rd) static int init_rootdomain(struct root_domain *rd) { - memset(rd, 0, sizeof(*rd)); - if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL)) goto out; if (!zalloc_cpumask_var(&rd->online, GFP_KERNEL)) @@ -311,7 +307,7 @@ static struct root_domain *alloc_rootdomain(void) { struct root_domain *rd; - rd = kmalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc(sizeof(*rd), GFP_KERNEL); if (!rd) return NULL; @@ -337,7 +333,8 @@ static void free_sched_groups(struct sched_group *sg, int free_sgc) if (free_sgc && atomic_dec_and_test(&sg->sgc->ref)) kfree(sg->sgc); - kfree(sg); + if (atomic_dec_and_test(&sg->ref)) + kfree(sg); sg = tmp; } while (sg != first); } @@ -345,15 +342,12 @@ static void free_sched_groups(struct sched_group *sg, int free_sgc) static void destroy_sched_domain(struct sched_domain *sd) { /* - * If its an overlapping domain it has private groups, iterate and - * nuke them all. + * A normal sched domain may have multiple group references, an + * overlapping domain, having private groups, only one. Iterate, + * dropping group/capacity references, freeing where none remain. */ - if (sd->flags & SD_OVERLAP) { - free_sched_groups(sd->groups, 1); - } else if (atomic_dec_and_test(&sd->groups->ref)) { - kfree(sd->groups->sgc); - kfree(sd->groups); - } + free_sched_groups(sd->groups, 1); + if (sd->shared && atomic_dec_and_test(&sd->shared->ref)) kfree(sd->shared); kfree(sd); @@ -463,6 +457,7 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu) rq_attach_root(rq, rd); tmp = rq->sd; rcu_assign_pointer(rq->sd, sd); + dirty_sched_domain_sysctl(cpu); destroy_sched_domains(tmp); update_top_cache_domain(cpu); @@ -476,7 +471,7 @@ static int __init isolated_cpu_setup(char *str) alloc_bootmem_cpumask_var(&cpu_isolated_map); ret = cpulist_parse(str, cpu_isolated_map); if (ret) { - pr_err("sched: Error, all isolcpus= values must be between 0 and %d\n", nr_cpu_ids); + pr_err("sched: Error, all isolcpus= values must be between 0 and %u\n", nr_cpu_ids); return 0; } return 1; @@ -670,6 +665,7 @@ build_group_from_child_sched_domain(struct sched_domain *sd, int cpu) else cpumask_copy(sg_span, sched_domain_span(sd)); + atomic_inc(&sg->ref); return sg; } @@ -1595,7 +1591,7 @@ static void __sdt_free(const struct cpumask *cpu_map) } } -struct sched_domain *build_sched_domain(struct sched_domain_topology_level *tl, +static struct sched_domain *build_sched_domain(struct sched_domain_topology_level *tl, const struct cpumask *cpu_map, struct sched_domain_attr *attr, struct sched_domain *child, int cpu) { @@ -1854,7 +1850,17 @@ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[], /* Let the architecture update CPU core mappings: */ new_topology = arch_update_cpu_topology(); - n = doms_new ? ndoms_new : 0; + if (!doms_new) { + WARN_ON_ONCE(dattr_new); + n = 0; + doms_new = alloc_sched_domains(1); + if (doms_new) { + n = 1; + cpumask_andnot(doms_new[0], cpu_active_mask, cpu_isolated_map); + } + } else { + n = ndoms_new; + } /* Destroy deleted domains: */ for (i = 0; i < ndoms_cur; i++) { @@ -1870,11 +1876,10 @@ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[], } n = ndoms_cur; - if (doms_new == NULL) { + if (!doms_new) { n = 0; doms_new = &fallback_doms; cpumask_andnot(doms_new[0], cpu_active_mask, cpu_isolated_map); - WARN_ON_ONCE(dattr_new); } /* Build new domains: */ diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c index 17f11c6b0a9f7a87010c17d3b775739d7e0d93a1..98feab7933c76a0d178cd7da0115376641e7bbad 100644 --- a/kernel/sched/wait.c +++ b/kernel/sched/wait.c @@ -53,6 +53,12 @@ void remove_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry } EXPORT_SYMBOL(remove_wait_queue); +/* + * Scan threshold to break wait queue walk. + * This allows a waker to take a break from holding the + * wait queue lock during the wait queue walk. + */ +#define WAITQUEUE_WALK_BREAK_CNT 64 /* * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just @@ -63,17 +69,67 @@ EXPORT_SYMBOL(remove_wait_queue); * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns * zero in this (rare) case, and we handle it by continuing to scan the queue. */ -static void __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode, - int nr_exclusive, int wake_flags, void *key) +static int __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode, + int nr_exclusive, int wake_flags, void *key, + wait_queue_entry_t *bookmark) { wait_queue_entry_t *curr, *next; + int cnt = 0; + + if (bookmark && (bookmark->flags & WQ_FLAG_BOOKMARK)) { + curr = list_next_entry(bookmark, entry); + + list_del(&bookmark->entry); + bookmark->flags = 0; + } else + curr = list_first_entry(&wq_head->head, wait_queue_entry_t, entry); - list_for_each_entry_safe(curr, next, &wq_head->head, entry) { + if (&curr->entry == &wq_head->head) + return nr_exclusive; + + list_for_each_entry_safe_from(curr, next, &wq_head->head, entry) { unsigned flags = curr->flags; + int ret; + + if (flags & WQ_FLAG_BOOKMARK) + continue; - if (curr->func(curr, mode, wake_flags, key) && - (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) + ret = curr->func(curr, mode, wake_flags, key); + if (ret < 0) break; + if (ret && (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) + break; + + if (bookmark && (++cnt > WAITQUEUE_WALK_BREAK_CNT) && + (&next->entry != &wq_head->head)) { + bookmark->flags = WQ_FLAG_BOOKMARK; + list_add_tail(&bookmark->entry, &next->entry); + break; + } + } + return nr_exclusive; +} + +static void __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int mode, + int nr_exclusive, int wake_flags, void *key) +{ + unsigned long flags; + wait_queue_entry_t bookmark; + + bookmark.flags = 0; + bookmark.private = NULL; + bookmark.func = NULL; + INIT_LIST_HEAD(&bookmark.entry); + + spin_lock_irqsave(&wq_head->lock, flags); + nr_exclusive = __wake_up_common(wq_head, mode, nr_exclusive, wake_flags, key, &bookmark); + spin_unlock_irqrestore(&wq_head->lock, flags); + + while (bookmark.flags & WQ_FLAG_BOOKMARK) { + spin_lock_irqsave(&wq_head->lock, flags); + nr_exclusive = __wake_up_common(wq_head, mode, nr_exclusive, + wake_flags, key, &bookmark); + spin_unlock_irqrestore(&wq_head->lock, flags); } } @@ -90,11 +146,7 @@ static void __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode, void __wake_up(struct wait_queue_head *wq_head, unsigned int mode, int nr_exclusive, void *key) { - unsigned long flags; - - spin_lock_irqsave(&wq_head->lock, flags); - __wake_up_common(wq_head, mode, nr_exclusive, 0, key); - spin_unlock_irqrestore(&wq_head->lock, flags); + __wake_up_common_lock(wq_head, mode, nr_exclusive, 0, key); } EXPORT_SYMBOL(__wake_up); @@ -103,16 +155,23 @@ EXPORT_SYMBOL(__wake_up); */ void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr) { - __wake_up_common(wq_head, mode, nr, 0, NULL); + __wake_up_common(wq_head, mode, nr, 0, NULL, NULL); } EXPORT_SYMBOL_GPL(__wake_up_locked); void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key) { - __wake_up_common(wq_head, mode, 1, 0, key); + __wake_up_common(wq_head, mode, 1, 0, key, NULL); } EXPORT_SYMBOL_GPL(__wake_up_locked_key); +void __wake_up_locked_key_bookmark(struct wait_queue_head *wq_head, + unsigned int mode, void *key, wait_queue_entry_t *bookmark) +{ + __wake_up_common(wq_head, mode, 1, 0, key, bookmark); +} +EXPORT_SYMBOL_GPL(__wake_up_locked_key_bookmark); + /** * __wake_up_sync_key - wake up threads blocked on a waitqueue. * @wq_head: the waitqueue @@ -133,7 +192,6 @@ EXPORT_SYMBOL_GPL(__wake_up_locked_key); void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, int nr_exclusive, void *key) { - unsigned long flags; int wake_flags = 1; /* XXX WF_SYNC */ if (unlikely(!wq_head)) @@ -142,9 +200,7 @@ void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, if (unlikely(nr_exclusive != 1)) wake_flags = 0; - spin_lock_irqsave(&wq_head->lock, flags); - __wake_up_common(wq_head, mode, nr_exclusive, wake_flags, key); - spin_unlock_irqrestore(&wq_head->lock, flags); + __wake_up_common_lock(wq_head, mode, nr_exclusive, wake_flags, key); } EXPORT_SYMBOL_GPL(__wake_up_sync_key); diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 98b59b5db90baae53b091afe807c133e6027d081..bb3a38005b9cc3f3b9f80d49c40bb9428e12a20d 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -17,11 +17,13 @@ #include #include #include +#include #include #include #include #include #include +#include #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER #include @@ -42,6 +44,7 @@ * get/put helpers should be used when accessing an instance * outside of a lifetime-guarded section. In general, this * is only needed for handling filters shared across tasks. + * @log: true if all actions except for SECCOMP_RET_ALLOW should be logged * @prev: points to a previously installed, or inherited, filter * @prog: the BPF program to evaluate * @@ -57,6 +60,7 @@ */ struct seccomp_filter { refcount_t usage; + bool log; struct seccomp_filter *prev; struct bpf_prog *prog; }; @@ -171,10 +175,15 @@ static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen) /** * seccomp_run_filters - evaluates all seccomp filters against @sd * @sd: optional seccomp data to be passed to filters + * @match: stores struct seccomp_filter that resulted in the return value, + * unless filter returned SECCOMP_RET_ALLOW, in which case it will + * be unchanged. * * Returns valid seccomp BPF response codes. */ -static u32 seccomp_run_filters(const struct seccomp_data *sd) +#define ACTION_ONLY(ret) ((s32)((ret) & (SECCOMP_RET_ACTION_FULL))) +static u32 seccomp_run_filters(const struct seccomp_data *sd, + struct seccomp_filter **match) { struct seccomp_data sd_local; u32 ret = SECCOMP_RET_ALLOW; @@ -184,7 +193,7 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd) /* Ensure unexpected behavior doesn't result in failing open. */ if (unlikely(WARN_ON(f == NULL))) - return SECCOMP_RET_KILL; + return SECCOMP_RET_KILL_PROCESS; if (!sd) { populate_seccomp_data(&sd_local); @@ -198,8 +207,10 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd) for (; f; f = f->prev) { u32 cur_ret = BPF_PROG_RUN(f->prog, sd); - if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION)) + if (ACTION_ONLY(cur_ret) < ACTION_ONLY(ret)) { ret = cur_ret; + *match = f; + } } return ret; } @@ -444,6 +455,10 @@ static long seccomp_attach_filter(unsigned int flags, return ret; } + /* Set log flag, if present. */ + if (flags & SECCOMP_FILTER_FLAG_LOG) + filter->log = true; + /* * If there is an existing filter, make it the prev and don't drop its * task reference. @@ -458,14 +473,19 @@ static long seccomp_attach_filter(unsigned int flags, return 0; } +void __get_seccomp_filter(struct seccomp_filter *filter) +{ + /* Reference count is bounded by the number of total processes. */ + refcount_inc(&filter->usage); +} + /* get_seccomp_filter - increments the reference count of the filter on @tsk */ void get_seccomp_filter(struct task_struct *tsk) { struct seccomp_filter *orig = tsk->seccomp.filter; if (!orig) return; - /* Reference count is bounded by the number of total processes. */ - refcount_inc(&orig->usage); + __get_seccomp_filter(orig); } static inline void seccomp_filter_free(struct seccomp_filter *filter) @@ -476,10 +496,8 @@ static inline void seccomp_filter_free(struct seccomp_filter *filter) } } -/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */ -void put_seccomp_filter(struct task_struct *tsk) +static void __put_seccomp_filter(struct seccomp_filter *orig) { - struct seccomp_filter *orig = tsk->seccomp.filter; /* Clean up single-reference branches iteratively. */ while (orig && refcount_dec_and_test(&orig->usage)) { struct seccomp_filter *freeme = orig; @@ -488,6 +506,12 @@ void put_seccomp_filter(struct task_struct *tsk) } } +/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */ +void put_seccomp_filter(struct task_struct *tsk) +{ + __put_seccomp_filter(tsk->seccomp.filter); +} + static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason) { memset(info, 0, sizeof(*info)); @@ -514,6 +538,65 @@ static void seccomp_send_sigsys(int syscall, int reason) } #endif /* CONFIG_SECCOMP_FILTER */ +/* For use with seccomp_actions_logged */ +#define SECCOMP_LOG_KILL_PROCESS (1 << 0) +#define SECCOMP_LOG_KILL_THREAD (1 << 1) +#define SECCOMP_LOG_TRAP (1 << 2) +#define SECCOMP_LOG_ERRNO (1 << 3) +#define SECCOMP_LOG_TRACE (1 << 4) +#define SECCOMP_LOG_LOG (1 << 5) +#define SECCOMP_LOG_ALLOW (1 << 6) + +static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_PROCESS | + SECCOMP_LOG_KILL_THREAD | + SECCOMP_LOG_TRAP | + SECCOMP_LOG_ERRNO | + SECCOMP_LOG_TRACE | + SECCOMP_LOG_LOG; + +static inline void seccomp_log(unsigned long syscall, long signr, u32 action, + bool requested) +{ + bool log = false; + + switch (action) { + case SECCOMP_RET_ALLOW: + break; + case SECCOMP_RET_TRAP: + log = requested && seccomp_actions_logged & SECCOMP_LOG_TRAP; + break; + case SECCOMP_RET_ERRNO: + log = requested && seccomp_actions_logged & SECCOMP_LOG_ERRNO; + break; + case SECCOMP_RET_TRACE: + log = requested && seccomp_actions_logged & SECCOMP_LOG_TRACE; + break; + case SECCOMP_RET_LOG: + log = seccomp_actions_logged & SECCOMP_LOG_LOG; + break; + case SECCOMP_RET_KILL_THREAD: + log = seccomp_actions_logged & SECCOMP_LOG_KILL_THREAD; + break; + case SECCOMP_RET_KILL_PROCESS: + default: + log = seccomp_actions_logged & SECCOMP_LOG_KILL_PROCESS; + } + + /* + * Force an audit message to be emitted when the action is RET_KILL_*, + * RET_LOG, or the FILTER_FLAG_LOG bit was set and the action is + * allowed to be logged by the admin. + */ + if (log) + return __audit_seccomp(syscall, signr, action); + + /* + * Let the audit subsystem decide if the action should be audited based + * on whether the current task itself is being audited. + */ + return audit_seccomp(syscall, signr, action); +} + /* * Secure computing mode 1 allows only read/write/exit/sigreturn. * To be fully secure this must be combined with rlimit @@ -539,7 +622,7 @@ static void __secure_computing_strict(int this_syscall) #ifdef SECCOMP_DEBUG dump_stack(); #endif - audit_seccomp(this_syscall, SIGKILL, SECCOMP_RET_KILL); + seccomp_log(this_syscall, SIGKILL, SECCOMP_RET_KILL_THREAD, true); do_exit(SIGKILL); } @@ -566,6 +649,7 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, const bool recheck_after_trace) { u32 filter_ret, action; + struct seccomp_filter *match = NULL; int data; /* @@ -574,9 +658,9 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, */ rmb(); - filter_ret = seccomp_run_filters(sd); + filter_ret = seccomp_run_filters(sd, &match); data = filter_ret & SECCOMP_RET_DATA; - action = filter_ret & SECCOMP_RET_ACTION; + action = filter_ret & SECCOMP_RET_ACTION_FULL; switch (action) { case SECCOMP_RET_ERRNO: @@ -637,14 +721,25 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, return 0; + case SECCOMP_RET_LOG: + seccomp_log(this_syscall, 0, action, true); + return 0; + case SECCOMP_RET_ALLOW: + /* + * Note that the "match" filter will always be NULL for + * this action since SECCOMP_RET_ALLOW is the starting + * state in seccomp_run_filters(). + */ return 0; - case SECCOMP_RET_KILL: + case SECCOMP_RET_KILL_THREAD: + case SECCOMP_RET_KILL_PROCESS: default: - audit_seccomp(this_syscall, SIGSYS, action); + seccomp_log(this_syscall, SIGSYS, action, true); /* Dump core only if this is the last remaining thread. */ - if (get_nr_threads(current) == 1) { + if (action == SECCOMP_RET_KILL_PROCESS || + get_nr_threads(current) == 1) { siginfo_t info; /* Show the original registers in the dump. */ @@ -653,13 +748,16 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, seccomp_init_siginfo(&info, this_syscall, data); do_coredump(&info); } - do_exit(SIGSYS); + if (action == SECCOMP_RET_KILL_PROCESS) + do_group_exit(SIGSYS); + else + do_exit(SIGSYS); } unreachable(); skip: - audit_seccomp(this_syscall, 0, action); + seccomp_log(this_syscall, 0, action, match ? match->log : false); return -1; } #else @@ -794,6 +892,29 @@ static inline long seccomp_set_mode_filter(unsigned int flags, } #endif +static long seccomp_get_action_avail(const char __user *uaction) +{ + u32 action; + + if (copy_from_user(&action, uaction, sizeof(action))) + return -EFAULT; + + switch (action) { + case SECCOMP_RET_KILL_PROCESS: + case SECCOMP_RET_KILL_THREAD: + case SECCOMP_RET_TRAP: + case SECCOMP_RET_ERRNO: + case SECCOMP_RET_TRACE: + case SECCOMP_RET_LOG: + case SECCOMP_RET_ALLOW: + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + /* Common entry point for both prctl and syscall. */ static long do_seccomp(unsigned int op, unsigned int flags, const char __user *uargs) @@ -805,6 +926,11 @@ static long do_seccomp(unsigned int op, unsigned int flags, return seccomp_set_mode_strict(); case SECCOMP_SET_MODE_FILTER: return seccomp_set_mode_filter(flags, uargs); + case SECCOMP_GET_ACTION_AVAIL: + if (flags != 0) + return -EINVAL; + + return seccomp_get_action_avail(uargs); default: return -EINVAL; } @@ -908,13 +1034,13 @@ long seccomp_get_filter(struct task_struct *task, unsigned long filter_off, if (!data) goto out; - get_seccomp_filter(task); + __get_seccomp_filter(filter); spin_unlock_irq(&task->sighand->siglock); if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog))) ret = -EFAULT; - put_seccomp_filter(task); + __put_seccomp_filter(filter); return ret; out: @@ -922,3 +1048,185 @@ long seccomp_get_filter(struct task_struct *task, unsigned long filter_off, return ret; } #endif + +#ifdef CONFIG_SYSCTL + +/* Human readable action names for friendly sysctl interaction */ +#define SECCOMP_RET_KILL_PROCESS_NAME "kill_process" +#define SECCOMP_RET_KILL_THREAD_NAME "kill_thread" +#define SECCOMP_RET_TRAP_NAME "trap" +#define SECCOMP_RET_ERRNO_NAME "errno" +#define SECCOMP_RET_TRACE_NAME "trace" +#define SECCOMP_RET_LOG_NAME "log" +#define SECCOMP_RET_ALLOW_NAME "allow" + +static const char seccomp_actions_avail[] = + SECCOMP_RET_KILL_PROCESS_NAME " " + SECCOMP_RET_KILL_THREAD_NAME " " + SECCOMP_RET_TRAP_NAME " " + SECCOMP_RET_ERRNO_NAME " " + SECCOMP_RET_TRACE_NAME " " + SECCOMP_RET_LOG_NAME " " + SECCOMP_RET_ALLOW_NAME; + +struct seccomp_log_name { + u32 log; + const char *name; +}; + +static const struct seccomp_log_name seccomp_log_names[] = { + { SECCOMP_LOG_KILL_PROCESS, SECCOMP_RET_KILL_PROCESS_NAME }, + { SECCOMP_LOG_KILL_THREAD, SECCOMP_RET_KILL_THREAD_NAME }, + { SECCOMP_LOG_TRAP, SECCOMP_RET_TRAP_NAME }, + { SECCOMP_LOG_ERRNO, SECCOMP_RET_ERRNO_NAME }, + { SECCOMP_LOG_TRACE, SECCOMP_RET_TRACE_NAME }, + { SECCOMP_LOG_LOG, SECCOMP_RET_LOG_NAME }, + { SECCOMP_LOG_ALLOW, SECCOMP_RET_ALLOW_NAME }, + { } +}; + +static bool seccomp_names_from_actions_logged(char *names, size_t size, + u32 actions_logged) +{ + const struct seccomp_log_name *cur; + bool append_space = false; + + for (cur = seccomp_log_names; cur->name && size; cur++) { + ssize_t ret; + + if (!(actions_logged & cur->log)) + continue; + + if (append_space) { + ret = strscpy(names, " ", size); + if (ret < 0) + return false; + + names += ret; + size -= ret; + } else + append_space = true; + + ret = strscpy(names, cur->name, size); + if (ret < 0) + return false; + + names += ret; + size -= ret; + } + + return true; +} + +static bool seccomp_action_logged_from_name(u32 *action_logged, + const char *name) +{ + const struct seccomp_log_name *cur; + + for (cur = seccomp_log_names; cur->name; cur++) { + if (!strcmp(cur->name, name)) { + *action_logged = cur->log; + return true; + } + } + + return false; +} + +static bool seccomp_actions_logged_from_names(u32 *actions_logged, char *names) +{ + char *name; + + *actions_logged = 0; + while ((name = strsep(&names, " ")) && *name) { + u32 action_logged = 0; + + if (!seccomp_action_logged_from_name(&action_logged, name)) + return false; + + *actions_logged |= action_logged; + } + + return true; +} + +static int seccomp_actions_logged_handler(struct ctl_table *ro_table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + char names[sizeof(seccomp_actions_avail)]; + struct ctl_table table; + int ret; + + if (write && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + memset(names, 0, sizeof(names)); + + if (!write) { + if (!seccomp_names_from_actions_logged(names, sizeof(names), + seccomp_actions_logged)) + return -EINVAL; + } + + table = *ro_table; + table.data = names; + table.maxlen = sizeof(names); + ret = proc_dostring(&table, write, buffer, lenp, ppos); + if (ret) + return ret; + + if (write) { + u32 actions_logged; + + if (!seccomp_actions_logged_from_names(&actions_logged, + table.data)) + return -EINVAL; + + if (actions_logged & SECCOMP_LOG_ALLOW) + return -EINVAL; + + seccomp_actions_logged = actions_logged; + } + + return 0; +} + +static struct ctl_path seccomp_sysctl_path[] = { + { .procname = "kernel", }, + { .procname = "seccomp", }, + { } +}; + +static struct ctl_table seccomp_sysctl_table[] = { + { + .procname = "actions_avail", + .data = (void *) &seccomp_actions_avail, + .maxlen = sizeof(seccomp_actions_avail), + .mode = 0444, + .proc_handler = proc_dostring, + }, + { + .procname = "actions_logged", + .mode = 0644, + .proc_handler = seccomp_actions_logged_handler, + }, + { } +}; + +static int __init seccomp_sysctl_init(void) +{ + struct ctl_table_header *hdr; + + hdr = register_sysctl_paths(seccomp_sysctl_path, seccomp_sysctl_table); + if (!hdr) + pr_warn("seccomp: sysctl registration failed\n"); + else + kmemleak_not_leak(hdr); + + return 0; +} + +device_initcall(seccomp_sysctl_init) + +#endif /* CONFIG_SYSCTL */ diff --git a/kernel/signal.c b/kernel/signal.c index caed9133ae52733aa96baf74cb4ef3c344832125..800a18f77732c14cf49d81bc615b01cd56d11933 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1194,7 +1194,11 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) recalc_sigpending_and_wake(t); } } - if (action->sa.sa_handler == SIG_DFL) + /* + * Don't clear SIGNAL_UNKILLABLE for traced tasks, users won't expect + * debugging to leave init killable. + */ + if (action->sa.sa_handler == SIG_DFL && !t->ptrace) t->signal->flags &= ~SIGNAL_UNKILLABLE; ret = specific_send_sig_info(sig, info, t); spin_unlock_irqrestore(&t->sighand->siglock, flags); @@ -2682,6 +2686,51 @@ COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset, } #endif +enum siginfo_layout siginfo_layout(int sig, int si_code) +{ + enum siginfo_layout layout = SIL_KILL; + if ((si_code > SI_USER) && (si_code < SI_KERNEL)) { + static const struct { + unsigned char limit, layout; + } filter[] = { + [SIGILL] = { NSIGILL, SIL_FAULT }, + [SIGFPE] = { NSIGFPE, SIL_FAULT }, + [SIGSEGV] = { NSIGSEGV, SIL_FAULT }, + [SIGBUS] = { NSIGBUS, SIL_FAULT }, + [SIGTRAP] = { NSIGTRAP, SIL_FAULT }, +#if defined(SIGMET) && defined(NSIGEMT) + [SIGEMT] = { NSIGEMT, SIL_FAULT }, +#endif + [SIGCHLD] = { NSIGCHLD, SIL_CHLD }, + [SIGPOLL] = { NSIGPOLL, SIL_POLL }, +#ifdef __ARCH_SIGSYS + [SIGSYS] = { NSIGSYS, SIL_SYS }, +#endif + }; + if ((sig < ARRAY_SIZE(filter)) && (si_code <= filter[sig].limit)) + layout = filter[sig].layout; + else if (si_code <= NSIGPOLL) + layout = SIL_POLL; + } else { + if (si_code == SI_TIMER) + layout = SIL_TIMER; + else if (si_code == SI_SIGIO) + layout = SIL_POLL; + else if (si_code < 0) + layout = SIL_RT; + /* Tests to support buggy kernel ABIs */ +#ifdef TRAP_FIXME + if ((sig == SIGTRAP) && (si_code == TRAP_FIXME)) + layout = SIL_FAULT; +#endif +#ifdef FPE_FIXME + if ((sig == SIGFPE) && (si_code == FPE_FIXME)) + layout = SIL_FAULT; +#endif + } + return layout; +} + #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from) @@ -2704,22 +2753,20 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from) */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - switch (from->si_code & __SI_MASK) { - case __SI_KILL: + err |= __put_user(from->si_code, &to->si_code); + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_TIMER: - err |= __put_user(from->si_tid, &to->si_tid); - err |= __put_user(from->si_overrun, &to->si_overrun); - err |= __put_user(from->si_ptr, &to->si_ptr); + case SIL_TIMER: + /* Unreached SI_TIMER is negative */ break; - case __SI_POLL: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_FAULT: + case SIL_FAULT: err |= __put_user(from->si_addr, &to->si_addr); #ifdef __ARCH_SI_TRAPNO err |= __put_user(from->si_trapno, &to->si_trapno); @@ -2744,30 +2791,25 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from) err |= __put_user(from->si_pkey, &to->si_pkey); #endif break; - case __SI_CHLD: + case SIL_CHLD: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_status, &to->si_status); err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: /* But this is */ + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_ptr, &to->si_ptr); break; #ifdef __ARCH_SIGSYS - case __SI_SYS: + case SIL_SYS: err |= __put_user(from->si_call_addr, &to->si_call_addr); err |= __put_user(from->si_syscall, &to->si_syscall); err |= __put_user(from->si_arch, &to->si_arch); break; #endif - default: /* this is just in case for now ... */ - err |= __put_user(from->si_pid, &to->si_pid); - err |= __put_user(from->si_uid, &to->si_uid); - break; } return err; } @@ -3303,12 +3345,15 @@ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) #ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set32) { +#ifdef __BIG_ENDIAN sigset_t set; - int err = do_sigpending(&set, sizeof(old_sigset_t)); - if (err == 0) - if (copy_to_user(set32, &set, sizeof(old_sigset_t))) - err = -EFAULT; + int err = do_sigpending(&set, sizeof(set.sig[0])); + if (!err) + err = put_user(set.sig[0], set32); return err; +#else + return sys_rt_sigpending((sigset_t __user *)set32, sizeof(*set32)); +#endif } #endif diff --git a/kernel/smp.c b/kernel/smp.c index 3061483cb3ad3eac437046eda0634f8a152e07f2..c94dd85c8d41798443a7080af55c24fe508815b3 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -28,7 +28,7 @@ enum { }; struct call_function_data { - struct call_single_data __percpu *csd; + call_single_data_t __percpu *csd; cpumask_var_t cpumask; cpumask_var_t cpumask_ipi; }; @@ -51,7 +51,7 @@ int smpcfd_prepare_cpu(unsigned int cpu) free_cpumask_var(cfd->cpumask); return -ENOMEM; } - cfd->csd = alloc_percpu(struct call_single_data); + cfd->csd = alloc_percpu(call_single_data_t); if (!cfd->csd) { free_cpumask_var(cfd->cpumask); free_cpumask_var(cfd->cpumask_ipi); @@ -103,12 +103,12 @@ void __init call_function_init(void) * previous function call. For multi-cpu calls its even more interesting * as we'll have to ensure no other cpu is observing our csd. */ -static __always_inline void csd_lock_wait(struct call_single_data *csd) +static __always_inline void csd_lock_wait(call_single_data_t *csd) { smp_cond_load_acquire(&csd->flags, !(VAL & CSD_FLAG_LOCK)); } -static __always_inline void csd_lock(struct call_single_data *csd) +static __always_inline void csd_lock(call_single_data_t *csd) { csd_lock_wait(csd); csd->flags |= CSD_FLAG_LOCK; @@ -116,12 +116,12 @@ static __always_inline void csd_lock(struct call_single_data *csd) /* * prevent CPU from reordering the above assignment * to ->flags with any subsequent assignments to other - * fields of the specified call_single_data structure: + * fields of the specified call_single_data_t structure: */ smp_wmb(); } -static __always_inline void csd_unlock(struct call_single_data *csd) +static __always_inline void csd_unlock(call_single_data_t *csd) { WARN_ON(!(csd->flags & CSD_FLAG_LOCK)); @@ -131,14 +131,14 @@ static __always_inline void csd_unlock(struct call_single_data *csd) smp_store_release(&csd->flags, 0); } -static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_single_data, csd_data); +static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data); /* - * Insert a previously allocated call_single_data element + * Insert a previously allocated call_single_data_t element * for execution on the given CPU. data must already have * ->func, ->info, and ->flags set. */ -static int generic_exec_single(int cpu, struct call_single_data *csd, +static int generic_exec_single(int cpu, call_single_data_t *csd, smp_call_func_t func, void *info) { if (cpu == smp_processor_id()) { @@ -210,7 +210,7 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) { struct llist_head *head; struct llist_node *entry; - struct call_single_data *csd, *csd_next; + call_single_data_t *csd, *csd_next; static bool warned; WARN_ON(!irqs_disabled()); @@ -268,8 +268,10 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) int smp_call_function_single(int cpu, smp_call_func_t func, void *info, int wait) { - struct call_single_data *csd; - struct call_single_data csd_stack = { .flags = CSD_FLAG_LOCK | CSD_FLAG_SYNCHRONOUS }; + call_single_data_t *csd; + call_single_data_t csd_stack = { + .flags = CSD_FLAG_LOCK | CSD_FLAG_SYNCHRONOUS, + }; int this_cpu; int err; @@ -321,7 +323,7 @@ EXPORT_SYMBOL(smp_call_function_single); * NOTE: Be careful, there is unfortunately no current debugging facility to * validate the correctness of this serialization. */ -int smp_call_function_single_async(int cpu, struct call_single_data *csd) +int smp_call_function_single_async(int cpu, call_single_data_t *csd) { int err = 0; @@ -444,7 +446,7 @@ void smp_call_function_many(const struct cpumask *mask, cpumask_clear(cfd->cpumask_ipi); for_each_cpu(cpu, cfd->cpumask) { - struct call_single_data *csd = per_cpu_ptr(cfd->csd, cpu); + call_single_data_t *csd = per_cpu_ptr(cfd->csd, cpu); csd_lock(csd); if (wait) @@ -460,7 +462,7 @@ void smp_call_function_many(const struct cpumask *mask, if (wait) { for_each_cpu(cpu, cfd->cpumask) { - struct call_single_data *csd; + call_single_data_t *csd; csd = per_cpu_ptr(cfd->csd, cpu); csd_lock_wait(csd); @@ -548,7 +550,7 @@ static int __init maxcpus(char *str) early_param("maxcpus", maxcpus); /* Setup number of possible processor ids */ -int nr_cpu_ids __read_mostly = NR_CPUS; +unsigned int nr_cpu_ids __read_mostly = NR_CPUS; EXPORT_SYMBOL(nr_cpu_ids); /* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */ diff --git a/kernel/smpboot.c b/kernel/smpboot.c index 1d71c051a9515c6acecd4be823465a4760e7cefa..5043e7433f4b15879a6498ed3d1ca6cfa2876f83 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c @@ -344,39 +344,30 @@ EXPORT_SYMBOL_GPL(smpboot_unregister_percpu_thread); * by the client, but only by calling this function. * This function can only be called on a registered smp_hotplug_thread. */ -int smpboot_update_cpumask_percpu_thread(struct smp_hotplug_thread *plug_thread, - const struct cpumask *new) +void smpboot_update_cpumask_percpu_thread(struct smp_hotplug_thread *plug_thread, + const struct cpumask *new) { struct cpumask *old = plug_thread->cpumask; - cpumask_var_t tmp; + static struct cpumask tmp; unsigned int cpu; - if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) - return -ENOMEM; - - get_online_cpus(); + lockdep_assert_cpus_held(); mutex_lock(&smpboot_threads_lock); /* Park threads that were exclusively enabled on the old mask. */ - cpumask_andnot(tmp, old, new); - for_each_cpu_and(cpu, tmp, cpu_online_mask) + cpumask_andnot(&tmp, old, new); + for_each_cpu_and(cpu, &tmp, cpu_online_mask) smpboot_park_thread(plug_thread, cpu); /* Unpark threads that are exclusively enabled on the new mask. */ - cpumask_andnot(tmp, new, old); - for_each_cpu_and(cpu, tmp, cpu_online_mask) + cpumask_andnot(&tmp, new, old); + for_each_cpu_and(cpu, &tmp, cpu_online_mask) smpboot_unpark_thread(plug_thread, cpu); cpumask_copy(old, new); mutex_unlock(&smpboot_threads_lock); - put_online_cpus(); - - free_cpumask_var(tmp); - - return 0; } -EXPORT_SYMBOL_GPL(smpboot_update_cpumask_percpu_thread); static DEFINE_PER_CPU(atomic_t, cpu_hotplug_state) = ATOMIC_INIT(CPU_POST_DEAD); diff --git a/kernel/sys.c b/kernel/sys.c index 2855ee73acd0ef9f62699ff669659e045df84422..9aebc293501330ffdfef0b6ad53df155ae6b31ca 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1896,15 +1896,11 @@ static int validate_prctl_map(struct prctl_mm_map *prctl_map) /* * Finally, make sure the caller has the rights to - * change /proc/pid/exe link: only local root should + * change /proc/pid/exe link: only local sys admin should * be allowed to. */ if (prctl_map->exe_fd != (u32)-1) { - struct user_namespace *ns = current_user_ns(); - const struct cred *cred = current_cred(); - - if (!uid_eq(cred->uid, make_kuid(ns, 0)) || - !gid_eq(cred->gid, make_kgid(ns, 0))) + if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN)) goto out; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 6648fbbb8157fc12703d02fa0fdc9ff85c527ac4..d9c31bc2eaea2c95a7a7be5a5321700b84d8f640 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -367,7 +367,8 @@ static struct ctl_table kern_table[] = { .data = &sysctl_sched_time_avg, .maxlen = sizeof(unsigned int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &one, }, #ifdef CONFIG_SCHEDSTATS { @@ -871,9 +872,9 @@ static struct ctl_table kern_table[] = { #if defined(CONFIG_LOCKUP_DETECTOR) { .procname = "watchdog", - .data = &watchdog_user_enabled, - .maxlen = sizeof (int), - .mode = 0644, + .data = &watchdog_user_enabled, + .maxlen = sizeof(int), + .mode = 0644, .proc_handler = proc_watchdog, .extra1 = &zero, .extra2 = &one, @@ -889,16 +890,12 @@ static struct ctl_table kern_table[] = { }, { .procname = "nmi_watchdog", - .data = &nmi_watchdog_enabled, - .maxlen = sizeof (int), - .mode = 0644, + .data = &nmi_watchdog_user_enabled, + .maxlen = sizeof(int), + .mode = NMI_WATCHDOG_SYSCTL_PERM, .proc_handler = proc_nmi_watchdog, .extra1 = &zero, -#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR) .extra2 = &one, -#else - .extra2 = &zero, -#endif }, { .procname = "watchdog_cpumask", @@ -910,9 +907,9 @@ static struct ctl_table kern_table[] = { #ifdef CONFIG_SOFTLOCKUP_DETECTOR { .procname = "soft_watchdog", - .data = &soft_watchdog_enabled, - .maxlen = sizeof (int), - .mode = 0644, + .data = &soft_watchdog_user_enabled, + .maxlen = sizeof(int), + .mode = 0644, .proc_handler = proc_soft_watchdog, .extra1 = &zero, .extra2 = &one, @@ -2185,8 +2182,6 @@ static int do_proc_douintvec_conv(unsigned long *lvalp, int write, void *data) { if (write) { - if (*lvalp > UINT_MAX) - return -EINVAL; if (*lvalp > UINT_MAX) return -EINVAL; *valp = *lvalp; diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 02e1859f2ca82e086f0ac73b08c4df07766edede..58ea8c03662ef38ac228e60d21e2b21e077b7f94 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -986,8 +986,9 @@ static ssize_t bin_intvec(struct file *file, size_t length = oldlen / sizeof(*vec); char *str, *end; int i; + loff_t pos = 0; - result = kernel_read(file, 0, buffer, BUFSZ - 1); + result = kernel_read(file, buffer, BUFSZ - 1, &pos); if (result < 0) goto out_kfree; @@ -1016,6 +1017,7 @@ static ssize_t bin_intvec(struct file *file, size_t length = newlen / sizeof(*vec); char *str, *end; int i; + loff_t pos = 0; str = buffer; end = str + BUFSZ; @@ -1029,7 +1031,7 @@ static ssize_t bin_intvec(struct file *file, str += scnprintf(str, end - str, "%lu\t", value); } - result = kernel_write(file, buffer, str - buffer, 0); + result = kernel_write(file, buffer, str - buffer, &pos); if (result < 0) goto out_kfree; } @@ -1057,8 +1059,9 @@ static ssize_t bin_ulongvec(struct file *file, size_t length = oldlen / sizeof(*vec); char *str, *end; int i; + loff_t pos = 0; - result = kernel_read(file, 0, buffer, BUFSZ - 1); + result = kernel_read(file, buffer, BUFSZ - 1, &pos); if (result < 0) goto out_kfree; @@ -1087,6 +1090,7 @@ static ssize_t bin_ulongvec(struct file *file, size_t length = newlen / sizeof(*vec); char *str, *end; int i; + loff_t pos = 0; str = buffer; end = str + BUFSZ; @@ -1100,7 +1104,7 @@ static ssize_t bin_ulongvec(struct file *file, str += scnprintf(str, end - str, "%lu\t", value); } - result = kernel_write(file, buffer, str - buffer, 0); + result = kernel_write(file, buffer, str - buffer, &pos); if (result < 0) goto out_kfree; } @@ -1120,8 +1124,9 @@ static ssize_t bin_uuid(struct file *file, if (oldval && oldlen) { char buf[UUID_STRING_LEN + 1]; uuid_t uuid; + loff_t pos = 0; - result = kernel_read(file, 0, buf, sizeof(buf) - 1); + result = kernel_read(file, buf, sizeof(buf) - 1, &pos); if (result < 0) goto out; @@ -1154,8 +1159,9 @@ static ssize_t bin_dn_node_address(struct file *file, char buf[15], *nodep; unsigned long area, node; __le16 dnaddr; + loff_t pos = 0; - result = kernel_read(file, 0, buf, sizeof(buf) - 1); + result = kernel_read(file, buf, sizeof(buf) - 1, &pos); if (result < 0) goto out; @@ -1188,6 +1194,7 @@ static ssize_t bin_dn_node_address(struct file *file, __le16 dnaddr; char buf[15]; int len; + loff_t pos = 0; result = -EINVAL; if (newlen != sizeof(dnaddr)) @@ -1201,7 +1208,7 @@ static ssize_t bin_dn_node_address(struct file *file, le16_to_cpu(dnaddr) >> 10, le16_to_cpu(dnaddr) & 0x3ff); - result = kernel_write(file, buf, len, 0); + result = kernel_write(file, buf, len, &pos); if (result < 0) goto out; } diff --git a/kernel/task_work.c b/kernel/task_work.c index d513051fcca271e560eeb9e181373609cf83a65c..836a72a66fba14ec1b66f941c50f81ea58444b3a 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -96,20 +96,16 @@ void task_work_run(void) * work->func() can do task_work_add(), do not set * work_exited unless the list is empty. */ + raw_spin_lock_irq(&task->pi_lock); do { work = READ_ONCE(task->task_works); head = !work && (task->flags & PF_EXITING) ? &work_exited : NULL; } while (cmpxchg(&task->task_works, work, head) != work); + raw_spin_unlock_irq(&task->pi_lock); if (!work) break; - /* - * Synchronize with task_work_cancel(). It can't remove - * the first entry == work, cmpxchg(task_works) should - * fail, but it can play with *work and other entries. - */ - raw_spin_unlock_wait(&task->pi_lock); do { next = work->next; diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 0b8ff7d257ea290743f2d0ab0194488784bc56ef..ec09ce9a6012b0a0cdf5299fcbad8a813433d1e1 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "posix-timers.h" @@ -56,9 +57,9 @@ static ktime_t freezer_delta; static DEFINE_SPINLOCK(freezer_delta_lock); #endif +#ifdef CONFIG_RTC_CLASS static struct wakeup_source *ws; -#ifdef CONFIG_RTC_CLASS /* rtc timer and device for setting alarm wakeups at suspend */ static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; @@ -89,6 +90,7 @@ static int alarmtimer_rtc_add_device(struct device *dev, { unsigned long flags; struct rtc_device *rtc = to_rtc_device(dev); + struct wakeup_source *__ws; if (rtcdev) return -EBUSY; @@ -98,13 +100,25 @@ static int alarmtimer_rtc_add_device(struct device *dev, if (!device_may_wakeup(rtc->dev.parent)) return -1; + __ws = wakeup_source_register("alarmtimer"); + spin_lock_irqsave(&rtcdev_lock, flags); if (!rtcdev) { + if (!try_module_get(rtc->owner)) { + spin_unlock_irqrestore(&rtcdev_lock, flags); + return -1; + } + rtcdev = rtc; /* hold a reference so it doesn't go away */ get_device(dev); + ws = __ws; + __ws = NULL; } spin_unlock_irqrestore(&rtcdev_lock, flags); + + wakeup_source_unregister(__ws); + return 0; } @@ -860,7 +874,6 @@ static int __init alarmtimer_init(void) error = PTR_ERR(pdev); goto out_drv; } - ws = wakeup_source_register("alarmtimer"); return 0; out_drv: diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index a3bd5dbe0dc4070010ff7ee2b5cb35178c1c555b..8585ad6e472a332f90aeb4343f8235b7b347a6c5 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -799,7 +799,6 @@ static void check_thread_timers(struct task_struct *tsk, struct list_head *firing) { struct list_head *timers = tsk->cpu_timers; - struct signal_struct *const sig = tsk->signal; struct task_cputime *tsk_expires = &tsk->cputime_expires; u64 expires; unsigned long soft; @@ -823,10 +822,9 @@ static void check_thread_timers(struct task_struct *tsk, /* * Check for the special case thread timers. */ - soft = READ_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur); + soft = task_rlimit(tsk, RLIMIT_RTTIME); if (soft != RLIM_INFINITY) { - unsigned long hard = - READ_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max); + unsigned long hard = task_rlimit_max(tsk, RLIMIT_RTTIME); if (hard != RLIM_INFINITY && tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { @@ -847,7 +845,8 @@ static void check_thread_timers(struct task_struct *tsk, */ if (soft < hard) { soft += USEC_PER_SEC; - sig->rlim[RLIMIT_RTTIME].rlim_cur = soft; + tsk->signal->rlim[RLIMIT_RTTIME].rlim_cur = + soft; } if (print_fatal_signals) { pr_info("RT Watchdog Timeout (soft): %s[%d]\n", @@ -938,11 +937,10 @@ static void check_process_timers(struct task_struct *tsk, SIGPROF); check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, SIGVTALRM); - soft = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); + soft = task_rlimit(tsk, RLIMIT_CPU); if (soft != RLIM_INFINITY) { unsigned long psecs = div_u64(ptime, NSEC_PER_SEC); - unsigned long hard = - READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_max); + unsigned long hard = task_rlimit_max(tsk, RLIMIT_CPU); u64 x; if (psecs >= hard) { /* diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index cedafa008de5a1196ff08a4422623893876b98b3..2cafb49aa65e13b5b1d29223e8943d53386a795d 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -637,9 +637,7 @@ static inline void tk_update_ktime_data(struct timekeeper *tk) tk->ktime_sec = seconds; /* Update the monotonic raw base */ - seconds = tk->raw_sec; - nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift); - tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec); + tk->tkr_raw.base = ns_to_ktime(tk->raw_sec * NSEC_PER_SEC); } /* must hold timekeeper_lock */ @@ -2066,7 +2064,7 @@ void update_wall_time(void) goto out; /* Do some additional sanity checking */ - timekeeping_check_update(real_tk, offset); + timekeeping_check_update(tk, offset); /* * With NO_HZ we may have to accumulate many cycle_intervals @@ -2318,7 +2316,7 @@ void hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts) raw_spin_unlock_irqrestore(&timekeeper_lock, flags); } EXPORT_SYMBOL(hardpps); -#endif +#endif /* CONFIG_NTP_PPS */ /** * xtime_update() - advances the timekeeping infrastructure diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c index 38bc4d2208e80bb398f411c2eafb3d2c599f1bc7..0754cadfa9e61b044b6bfcf81f4146c8c45f63c3 100644 --- a/kernel/time/timekeeping_debug.c +++ b/kernel/time/timekeeping_debug.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "timekeeping_internal.h" @@ -75,7 +76,7 @@ void tk_debug_account_sleep_time(struct timespec64 *t) int bin = min(fls(t->tv_sec), NUM_BINS-1); sleep_time_bin[bin]++; - printk_deferred(KERN_INFO "Suspended for %lld.%03lu seconds\n", - (s64)t->tv_sec, t->tv_nsec / NSEC_PER_MSEC); + pm_deferred_pr_dbg("Timekeeping suspended for %lld.%03lu seconds\n", + (s64)t->tv_sec, t->tv_nsec / NSEC_PER_MSEC); } diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 71ce3f4eead34afc12fa2743c69e8e9e77c544ad..f2674a056c268a58e0525194ea225fcd0bd9e1d5 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -203,6 +203,7 @@ struct timer_base { bool migration_enabled; bool nohz_active; bool is_idle; + bool must_forward_clk; DECLARE_BITMAP(pending_map, WHEEL_SIZE); struct hlist_head vectors[WHEEL_SIZE]; } ____cacheline_aligned; @@ -856,13 +857,19 @@ get_target_base(struct timer_base *base, unsigned tflags) static inline void forward_timer_base(struct timer_base *base) { - unsigned long jnow = READ_ONCE(jiffies); + unsigned long jnow; /* - * We only forward the base when it's idle and we have a delta between - * base clock and jiffies. + * We only forward the base when we are idle or have just come out of + * idle (must_forward_clk logic), and have a delta between base clock + * and jiffies. In the common case, run_timers will take care of it. */ - if (!base->is_idle || (long) (jnow - base->clk) < 2) + if (likely(!base->must_forward_clk)) + return; + + jnow = READ_ONCE(jiffies); + base->must_forward_clk = base->is_idle; + if ((long)(jnow - base->clk) < 2) return; /* @@ -938,6 +945,11 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) * same array bucket then just return: */ if (timer_pending(timer)) { + /* + * The downside of this optimization is that it can result in + * larger granularity than you would get from adding a new + * timer with this expiry. + */ if (timer->expires == expires) return 1; @@ -948,6 +960,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) * dequeue/enqueue dance. */ base = lock_timer_base(timer, &flags); + forward_timer_base(base); clk = base->clk; idx = calc_wheel_index(expires, clk); @@ -964,6 +977,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) } } else { base = lock_timer_base(timer, &flags); + forward_timer_base(base); } ret = detach_if_pending(timer, base, false); @@ -991,12 +1005,10 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) raw_spin_lock(&base->lock); WRITE_ONCE(timer->flags, (timer->flags & ~TIMER_BASEMASK) | base->cpu); + forward_timer_base(base); } } - /* Try to forward a stale timer base clock */ - forward_timer_base(base); - timer->expires = expires; /* * If 'idx' was calculated above and the base time did not advance @@ -1112,6 +1124,7 @@ void add_timer_on(struct timer_list *timer, int cpu) WRITE_ONCE(timer->flags, (timer->flags & ~TIMER_BASEMASK) | cpu); } + forward_timer_base(base); debug_activate(timer, timer->expires); internal_add_timer(base, timer); @@ -1495,12 +1508,18 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) base->is_idle = false; } else { if (!is_max_delta) - expires = basem + (nextevt - basej) * TICK_NSEC; + expires = basem + (u64)(nextevt - basej) * TICK_NSEC; /* - * If we expect to sleep more than a tick, mark the base idle: + * If we expect to sleep more than a tick, mark the base idle. + * Also the tick is stopped so any added timer must forward + * the base clk itself to keep granularity small. This idle + * logic is only maintained for the BASE_STD base, deferrable + * timers may still see large granularity skew (by design). */ - if ((expires - basem) > TICK_NSEC) + if ((expires - basem) > TICK_NSEC) { + base->must_forward_clk = true; base->is_idle = true; + } } raw_spin_unlock(&base->lock); @@ -1611,6 +1630,19 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h) { struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); + /* + * must_forward_clk must be cleared before running timers so that any + * timer functions that call mod_timer will not try to forward the + * base. idle trcking / clock forwarding logic is only used with + * BASE_STD timers. + * + * The deferrable base does not do idle tracking at all, so we do + * not forward it. This can result in very large variations in + * granularity for deferrable timers, but they can be deferred for + * long periods due to idle. + */ + base->must_forward_clk = false; + __run_timers(base); if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); diff --git a/kernel/torture.c b/kernel/torture.c index 55de96529287a21fc2683070ad3eeb4298e5c8f8..637e172835d84969829f2215697556ff045fcfe5 100644 --- a/kernel/torture.c +++ b/kernel/torture.c @@ -117,7 +117,7 @@ bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes, torture_type, cpu); (*n_offl_successes)++; delta = jiffies - starttime; - sum_offl += delta; + *sum_offl += delta; if (*min_offl < 0) { *min_offl = delta; *max_offl = delta; diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index bc364f86100aa89f5d7b463d8c5465d1505766ce..45a3928544ce599183c415471f4624be0583ea40 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "../../block/blk.h" @@ -46,10 +47,16 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(running_trace_lock); /* Select an alternative, minimalistic output than the original one */ #define TRACE_BLK_OPT_CLASSIC 0x1 +#define TRACE_BLK_OPT_CGROUP 0x2 +#define TRACE_BLK_OPT_CGNAME 0x4 static struct tracer_opt blk_tracer_opts[] = { /* Default disable the minimalistic output */ { TRACER_OPT(blk_classic, TRACE_BLK_OPT_CLASSIC) }, +#ifdef CONFIG_BLK_CGROUP + { TRACER_OPT(blk_cgroup, TRACE_BLK_OPT_CGROUP) }, + { TRACER_OPT(blk_cgname, TRACE_BLK_OPT_CGNAME) }, +#endif { } }; @@ -68,7 +75,8 @@ static void blk_unregister_tracepoints(void); * Send out a notify message. */ static void trace_note(struct blk_trace *bt, pid_t pid, int action, - const void *data, size_t len) + const void *data, size_t len, + union kernfs_node_id *cgid) { struct blk_io_trace *t; struct ring_buffer_event *event = NULL; @@ -76,12 +84,13 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action, int pc = 0; int cpu = smp_processor_id(); bool blk_tracer = blk_tracer_enabled; + ssize_t cgid_len = cgid ? sizeof(*cgid) : 0; if (blk_tracer) { buffer = blk_tr->trace_buffer.buffer; pc = preempt_count(); event = trace_buffer_lock_reserve(buffer, TRACE_BLK, - sizeof(*t) + len, + sizeof(*t) + len + cgid_len, 0, pc); if (!event) return; @@ -92,17 +101,19 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action, if (!bt->rchan) return; - t = relay_reserve(bt->rchan, sizeof(*t) + len); + t = relay_reserve(bt->rchan, sizeof(*t) + len + cgid_len); if (t) { t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; t->time = ktime_to_ns(ktime_get()); record_it: t->device = bt->dev; - t->action = action; + t->action = action | (cgid ? __BLK_TN_CGROUP : 0); t->pid = pid; t->cpu = cpu; - t->pdu_len = len; - memcpy((void *) t + sizeof(*t), data, len); + t->pdu_len = len + cgid_len; + if (cgid) + memcpy((void *)t + sizeof(*t), cgid, cgid_len); + memcpy((void *) t + sizeof(*t) + cgid_len, data, len); if (blk_tracer) trace_buffer_unlock_commit(blk_tr, buffer, event, 0, pc); @@ -122,7 +133,7 @@ static void trace_note_tsk(struct task_struct *tsk) spin_lock_irqsave(&running_trace_lock, flags); list_for_each_entry(bt, &running_trace_list, running_list) { trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm, - sizeof(tsk->comm)); + sizeof(tsk->comm), NULL); } spin_unlock_irqrestore(&running_trace_lock, flags); } @@ -139,11 +150,12 @@ static void trace_note_time(struct blk_trace *bt) words[1] = now.tv_nsec; local_irq_save(flags); - trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words)); + trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words), NULL); local_irq_restore(flags); } -void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) +void __trace_note_message(struct blk_trace *bt, struct blkcg *blkcg, + const char *fmt, ...) { int n; va_list args; @@ -167,7 +179,14 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args); va_end(args); - trace_note(bt, 0, BLK_TN_MESSAGE, buf, n); + if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CGROUP)) + blkcg = NULL; +#ifdef CONFIG_BLK_CGROUP + trace_note(bt, 0, BLK_TN_MESSAGE, buf, n, + blkcg ? cgroup_get_kernfs_id(blkcg->css.cgroup) : NULL); +#else + trace_note(bt, 0, BLK_TN_MESSAGE, buf, n, NULL); +#endif local_irq_restore(flags); } EXPORT_SYMBOL_GPL(__trace_note_message); @@ -204,7 +223,7 @@ static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ), */ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, int op, int op_flags, u32 what, int error, int pdu_len, - void *pdu_data) + void *pdu_data, union kernfs_node_id *cgid) { struct task_struct *tsk = current; struct ring_buffer_event *event = NULL; @@ -215,6 +234,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, pid_t pid; int cpu, pc = 0; bool blk_tracer = blk_tracer_enabled; + ssize_t cgid_len = cgid ? sizeof(*cgid) : 0; if (unlikely(bt->trace_state != Blktrace_running && !blk_tracer)) return; @@ -229,6 +249,8 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= BLK_TC_ACT(BLK_TC_DISCARD); if (op == REQ_OP_FLUSH) what |= BLK_TC_ACT(BLK_TC_FLUSH); + if (cgid) + what |= __BLK_TA_CGROUP; pid = tsk->pid; if (act_log_check(bt, what, sector, pid)) @@ -241,7 +263,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, buffer = blk_tr->trace_buffer.buffer; pc = preempt_count(); event = trace_buffer_lock_reserve(buffer, TRACE_BLK, - sizeof(*t) + pdu_len, + sizeof(*t) + pdu_len + cgid_len, 0, pc); if (!event) return; @@ -258,7 +280,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, * from coming in and stepping on our toes. */ local_irq_save(flags); - t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len); + t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len + cgid_len); if (t) { sequence = per_cpu_ptr(bt->sequence, cpu); @@ -280,10 +302,12 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, t->action = what; t->device = bt->dev; t->error = error; - t->pdu_len = pdu_len; + t->pdu_len = pdu_len + cgid_len; + if (cgid_len) + memcpy((void *)t + sizeof(*t), cgid, cgid_len); if (pdu_len) - memcpy((void *) t + sizeof(*t), pdu_data, pdu_len); + memcpy((void *)t + sizeof(*t) + cgid_len, pdu_data, pdu_len); if (blk_tracer) { trace_buffer_unlock_commit(blk_tr, buffer, event, 0, pc); @@ -359,7 +383,7 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, return PTR_ERR(msg); bt = filp->private_data; - __trace_note_message(bt, "%s", msg); + __trace_note_message(bt, NULL, "%s", msg); kfree(msg); return count; @@ -624,6 +648,12 @@ int blk_trace_startstop(struct request_queue *q, int start) } EXPORT_SYMBOL_GPL(blk_trace_startstop); +/* + * When reading or writing the blktrace sysfs files, the references to the + * opened sysfs or device files should prevent the underlying block device + * from being removed. So no further delete protection is really needed. + */ + /** * blk_trace_ioctl: - handle the ioctls associated with tracing * @bdev: the block device @@ -641,7 +671,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) if (!q) return -ENXIO; - mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex); switch (cmd) { case BLKTRACESETUP: @@ -667,7 +697,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) break; } - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); return ret; } @@ -684,6 +714,36 @@ void blk_trace_shutdown(struct request_queue *q) } } +#ifdef CONFIG_BLK_CGROUP +static union kernfs_node_id * +blk_trace_bio_get_cgid(struct request_queue *q, struct bio *bio) +{ + struct blk_trace *bt = q->blk_trace; + + if (!bt || !(blk_tracer_flags.val & TRACE_BLK_OPT_CGROUP)) + return NULL; + + if (!bio->bi_css) + return NULL; + return cgroup_get_kernfs_id(bio->bi_css->cgroup); +} +#else +static union kernfs_node_id * +blk_trace_bio_get_cgid(struct request_queue *q, struct bio *bio) +{ + return NULL; +} +#endif + +static union kernfs_node_id * +blk_trace_request_get_cgid(struct request_queue *q, struct request *rq) +{ + if (!rq->bio) + return NULL; + /* Use the first bio */ + return blk_trace_bio_get_cgid(q, rq->bio); +} + /* * blktrace probes */ @@ -694,13 +754,15 @@ void blk_trace_shutdown(struct request_queue *q) * @error: return status to log * @nr_bytes: number of completed bytes * @what: the action + * @cgid: the cgroup info * * Description: * Records an action against a request. Will log the bio offset + size. * **/ static void blk_add_trace_rq(struct request *rq, int error, - unsigned int nr_bytes, u32 what) + unsigned int nr_bytes, u32 what, + union kernfs_node_id *cgid) { struct blk_trace *bt = rq->q->blk_trace; @@ -713,32 +775,36 @@ static void blk_add_trace_rq(struct request *rq, int error, what |= BLK_TC_ACT(BLK_TC_FS); __blk_add_trace(bt, blk_rq_trace_sector(rq), nr_bytes, req_op(rq), - rq->cmd_flags, what, error, 0, NULL); + rq->cmd_flags, what, error, 0, NULL, cgid); } static void blk_add_trace_rq_insert(void *ignore, struct request_queue *q, struct request *rq) { - blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_INSERT); + blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_INSERT, + blk_trace_request_get_cgid(q, rq)); } static void blk_add_trace_rq_issue(void *ignore, struct request_queue *q, struct request *rq) { - blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_ISSUE); + blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_ISSUE, + blk_trace_request_get_cgid(q, rq)); } static void blk_add_trace_rq_requeue(void *ignore, struct request_queue *q, struct request *rq) { - blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_REQUEUE); + blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_REQUEUE, + blk_trace_request_get_cgid(q, rq)); } static void blk_add_trace_rq_complete(void *ignore, struct request *rq, int error, unsigned int nr_bytes) { - blk_add_trace_rq(rq, error, nr_bytes, BLK_TA_COMPLETE); + blk_add_trace_rq(rq, error, nr_bytes, BLK_TA_COMPLETE, + blk_trace_request_get_cgid(rq->q, rq)); } /** @@ -753,7 +819,7 @@ static void blk_add_trace_rq_complete(void *ignore, struct request *rq, * **/ static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, - u32 what, int error) + u32 what, int error, union kernfs_node_id *cgid) { struct blk_trace *bt = q->blk_trace; @@ -761,20 +827,22 @@ static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, return; __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, - bio_op(bio), bio->bi_opf, what, error, 0, NULL); + bio_op(bio), bio->bi_opf, what, error, 0, NULL, cgid); } static void blk_add_trace_bio_bounce(void *ignore, struct request_queue *q, struct bio *bio) { - blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0); + blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0, + blk_trace_bio_get_cgid(q, bio)); } static void blk_add_trace_bio_complete(void *ignore, struct request_queue *q, struct bio *bio, int error) { - blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error); + blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error, + blk_trace_bio_get_cgid(q, bio)); } static void blk_add_trace_bio_backmerge(void *ignore, @@ -782,7 +850,8 @@ static void blk_add_trace_bio_backmerge(void *ignore, struct request *rq, struct bio *bio) { - blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE, 0); + blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE, 0, + blk_trace_bio_get_cgid(q, bio)); } static void blk_add_trace_bio_frontmerge(void *ignore, @@ -790,13 +859,15 @@ static void blk_add_trace_bio_frontmerge(void *ignore, struct request *rq, struct bio *bio) { - blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE, 0); + blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE, 0, + blk_trace_bio_get_cgid(q, bio)); } static void blk_add_trace_bio_queue(void *ignore, struct request_queue *q, struct bio *bio) { - blk_add_trace_bio(q, bio, BLK_TA_QUEUE, 0); + blk_add_trace_bio(q, bio, BLK_TA_QUEUE, 0, + blk_trace_bio_get_cgid(q, bio)); } static void blk_add_trace_getrq(void *ignore, @@ -804,13 +875,14 @@ static void blk_add_trace_getrq(void *ignore, struct bio *bio, int rw) { if (bio) - blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0); + blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0, + blk_trace_bio_get_cgid(q, bio)); else { struct blk_trace *bt = q->blk_trace; if (bt) __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_GETRQ, 0, 0, - NULL); + NULL, NULL); } } @@ -820,13 +892,14 @@ static void blk_add_trace_sleeprq(void *ignore, struct bio *bio, int rw) { if (bio) - blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0); + blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0, + blk_trace_bio_get_cgid(q, bio)); else { struct blk_trace *bt = q->blk_trace; if (bt) __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_SLEEPRQ, - 0, 0, NULL); + 0, 0, NULL, NULL); } } @@ -835,7 +908,7 @@ static void blk_add_trace_plug(void *ignore, struct request_queue *q) struct blk_trace *bt = q->blk_trace; if (bt) - __blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL); + __blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL, NULL); } static void blk_add_trace_unplug(void *ignore, struct request_queue *q, @@ -852,7 +925,7 @@ static void blk_add_trace_unplug(void *ignore, struct request_queue *q, else what = BLK_TA_UNPLUG_TIMER; - __blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu); + __blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu, NULL); } } @@ -868,7 +941,7 @@ static void blk_add_trace_split(void *ignore, __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, bio_op(bio), bio->bi_opf, BLK_TA_SPLIT, bio->bi_status, sizeof(rpdu), - &rpdu); + &rpdu, blk_trace_bio_get_cgid(q, bio)); } } @@ -896,12 +969,12 @@ static void blk_add_trace_bio_remap(void *ignore, return; r.device_from = cpu_to_be32(dev); - r.device_to = cpu_to_be32(bio->bi_bdev->bd_dev); + r.device_to = cpu_to_be32(bio_dev(bio)); r.sector_from = cpu_to_be64(from); __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, bio_op(bio), bio->bi_opf, BLK_TA_REMAP, bio->bi_status, - sizeof(r), &r); + sizeof(r), &r, blk_trace_bio_get_cgid(q, bio)); } /** @@ -934,7 +1007,7 @@ static void blk_add_trace_rq_remap(void *ignore, __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), rq_data_dir(rq), 0, BLK_TA_REMAP, 0, - sizeof(r), &r); + sizeof(r), &r, blk_trace_request_get_cgid(q, rq)); } /** @@ -958,7 +1031,8 @@ void blk_add_driver_data(struct request_queue *q, return; __blk_add_trace(bt, blk_rq_trace_sector(rq), blk_rq_bytes(rq), 0, 0, - BLK_TA_DRV_DATA, 0, len, data); + BLK_TA_DRV_DATA, 0, len, data, + blk_trace_request_get_cgid(q, rq)); } EXPORT_SYMBOL_GPL(blk_add_driver_data); @@ -1031,7 +1105,7 @@ static void fill_rwbs(char *rwbs, const struct blk_io_trace *t) int i = 0; int tc = t->action >> BLK_TC_SHIFT; - if (t->action == BLK_TN_MESSAGE) { + if ((t->action & ~__BLK_TN_CGROUP) == BLK_TN_MESSAGE) { rwbs[i++] = 'N'; goto out; } @@ -1066,9 +1140,21 @@ const struct blk_io_trace *te_blk_io_trace(const struct trace_entry *ent) return (const struct blk_io_trace *)ent; } -static inline const void *pdu_start(const struct trace_entry *ent) +static inline const void *pdu_start(const struct trace_entry *ent, bool has_cg) +{ + return (void *)(te_blk_io_trace(ent) + 1) + + (has_cg ? sizeof(union kernfs_node_id) : 0); +} + +static inline const void *cgid_start(const struct trace_entry *ent) { - return te_blk_io_trace(ent) + 1; + return (void *)(te_blk_io_trace(ent) + 1); +} + +static inline int pdu_real_len(const struct trace_entry *ent, bool has_cg) +{ + return te_blk_io_trace(ent)->pdu_len - + (has_cg ? sizeof(union kernfs_node_id) : 0); } static inline u32 t_action(const struct trace_entry *ent) @@ -1096,16 +1182,16 @@ static inline __u16 t_error(const struct trace_entry *ent) return te_blk_io_trace(ent)->error; } -static __u64 get_pdu_int(const struct trace_entry *ent) +static __u64 get_pdu_int(const struct trace_entry *ent, bool has_cg) { - const __u64 *val = pdu_start(ent); + const __u64 *val = pdu_start(ent, has_cg); return be64_to_cpu(*val); } static void get_pdu_remap(const struct trace_entry *ent, - struct blk_io_trace_remap *r) + struct blk_io_trace_remap *r, bool has_cg) { - const struct blk_io_trace_remap *__r = pdu_start(ent); + const struct blk_io_trace_remap *__r = pdu_start(ent, has_cg); __u64 sector_from = __r->sector_from; r->device_from = be32_to_cpu(__r->device_from); @@ -1113,9 +1199,11 @@ static void get_pdu_remap(const struct trace_entry *ent, r->sector_from = be64_to_cpu(sector_from); } -typedef void (blk_log_action_t) (struct trace_iterator *iter, const char *act); +typedef void (blk_log_action_t) (struct trace_iterator *iter, const char *act, + bool has_cg); -static void blk_log_action_classic(struct trace_iterator *iter, const char *act) +static void blk_log_action_classic(struct trace_iterator *iter, const char *act, + bool has_cg) { char rwbs[RWBS_LEN]; unsigned long long ts = iter->ts; @@ -1131,24 +1219,43 @@ static void blk_log_action_classic(struct trace_iterator *iter, const char *act) secs, nsec_rem, iter->ent->pid, act, rwbs); } -static void blk_log_action(struct trace_iterator *iter, const char *act) +static void blk_log_action(struct trace_iterator *iter, const char *act, + bool has_cg) { char rwbs[RWBS_LEN]; const struct blk_io_trace *t = te_blk_io_trace(iter->ent); fill_rwbs(rwbs, t); - trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ", - MAJOR(t->device), MINOR(t->device), act, rwbs); -} - -static void blk_log_dump_pdu(struct trace_seq *s, const struct trace_entry *ent) + if (has_cg) { + const union kernfs_node_id *id = cgid_start(iter->ent); + + if (blk_tracer_flags.val & TRACE_BLK_OPT_CGNAME) { + char blkcg_name_buf[NAME_MAX + 1] = "<...>"; + + cgroup_path_from_kernfs_id(id, blkcg_name_buf, + sizeof(blkcg_name_buf)); + trace_seq_printf(&iter->seq, "%3d,%-3d %s %2s %3s ", + MAJOR(t->device), MINOR(t->device), + blkcg_name_buf, act, rwbs); + } else + trace_seq_printf(&iter->seq, + "%3d,%-3d %x,%-x %2s %3s ", + MAJOR(t->device), MINOR(t->device), + id->ino, id->generation, act, rwbs); + } else + trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ", + MAJOR(t->device), MINOR(t->device), act, rwbs); +} + +static void blk_log_dump_pdu(struct trace_seq *s, + const struct trace_entry *ent, bool has_cg) { const unsigned char *pdu_buf; int pdu_len; int i, end; - pdu_buf = pdu_start(ent); - pdu_len = te_blk_io_trace(ent)->pdu_len; + pdu_buf = pdu_start(ent, has_cg); + pdu_len = pdu_real_len(ent, has_cg); if (!pdu_len) return; @@ -1179,7 +1286,7 @@ static void blk_log_dump_pdu(struct trace_seq *s, const struct trace_entry *ent) trace_seq_puts(s, ") "); } -static void blk_log_generic(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_generic(struct trace_seq *s, const struct trace_entry *ent, bool has_cg) { char cmd[TASK_COMM_LEN]; @@ -1187,7 +1294,7 @@ static void blk_log_generic(struct trace_seq *s, const struct trace_entry *ent) if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) { trace_seq_printf(s, "%u ", t_bytes(ent)); - blk_log_dump_pdu(s, ent); + blk_log_dump_pdu(s, ent, has_cg); trace_seq_printf(s, "[%s]\n", cmd); } else { if (t_sec(ent)) @@ -1199,10 +1306,10 @@ static void blk_log_generic(struct trace_seq *s, const struct trace_entry *ent) } static void blk_log_with_error(struct trace_seq *s, - const struct trace_entry *ent) + const struct trace_entry *ent, bool has_cg) { if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) { - blk_log_dump_pdu(s, ent); + blk_log_dump_pdu(s, ent, has_cg); trace_seq_printf(s, "[%d]\n", t_error(ent)); } else { if (t_sec(ent)) @@ -1215,18 +1322,18 @@ static void blk_log_with_error(struct trace_seq *s, } } -static void blk_log_remap(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_remap(struct trace_seq *s, const struct trace_entry *ent, bool has_cg) { struct blk_io_trace_remap r = { .device_from = 0, }; - get_pdu_remap(ent, &r); + get_pdu_remap(ent, &r, has_cg); trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n", t_sector(ent), t_sec(ent), MAJOR(r.device_from), MINOR(r.device_from), (unsigned long long)r.sector_from); } -static void blk_log_plug(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_plug(struct trace_seq *s, const struct trace_entry *ent, bool has_cg) { char cmd[TASK_COMM_LEN]; @@ -1235,30 +1342,31 @@ static void blk_log_plug(struct trace_seq *s, const struct trace_entry *ent) trace_seq_printf(s, "[%s]\n", cmd); } -static void blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent, bool has_cg) { char cmd[TASK_COMM_LEN]; trace_find_cmdline(ent->pid, cmd); - trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent)); + trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent, has_cg)); } -static void blk_log_split(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_split(struct trace_seq *s, const struct trace_entry *ent, bool has_cg) { char cmd[TASK_COMM_LEN]; trace_find_cmdline(ent->pid, cmd); trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent), - get_pdu_int(ent), cmd); + get_pdu_int(ent, has_cg), cmd); } -static void blk_log_msg(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_msg(struct trace_seq *s, const struct trace_entry *ent, + bool has_cg) { - const struct blk_io_trace *t = te_blk_io_trace(ent); - trace_seq_putmem(s, t + 1, t->pdu_len); + trace_seq_putmem(s, pdu_start(ent, has_cg), + pdu_real_len(ent, has_cg)); trace_seq_putc(s, '\n'); } @@ -1298,7 +1406,8 @@ static void blk_tracer_reset(struct trace_array *tr) static const struct { const char *act[2]; - void (*print)(struct trace_seq *s, const struct trace_entry *ent); + void (*print)(struct trace_seq *s, const struct trace_entry *ent, + bool has_cg); } what2act[] = { [__BLK_TA_QUEUE] = {{ "Q", "queue" }, blk_log_generic }, [__BLK_TA_BACKMERGE] = {{ "M", "backmerge" }, blk_log_generic }, @@ -1326,23 +1435,25 @@ static enum print_line_t print_one_line(struct trace_iterator *iter, u16 what; bool long_act; blk_log_action_t *log_action; + bool has_cg; t = te_blk_io_trace(iter->ent); - what = t->action & ((1 << BLK_TC_SHIFT) - 1); + what = (t->action & ((1 << BLK_TC_SHIFT) - 1)) & ~__BLK_TA_CGROUP; long_act = !!(tr->trace_flags & TRACE_ITER_VERBOSE); log_action = classic ? &blk_log_action_classic : &blk_log_action; + has_cg = t->action & __BLK_TA_CGROUP; - if (t->action == BLK_TN_MESSAGE) { - log_action(iter, long_act ? "message" : "m"); - blk_log_msg(s, iter->ent); + if ((t->action & ~__BLK_TN_CGROUP) == BLK_TN_MESSAGE) { + log_action(iter, long_act ? "message" : "m", has_cg); + blk_log_msg(s, iter->ent, has_cg); return trace_handle_return(s); } if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) trace_seq_printf(s, "Unknown action %x\n", what); else { - log_action(iter, what2act[what].act[long_act]); - what2act[what].print(s, iter->ent); + log_action(iter, what2act[what].act[long_act], has_cg); + what2act[what].print(s, iter->ent, has_cg); } return trace_handle_return(s); @@ -1622,7 +1733,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, if (q == NULL) goto out_bdput; - mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex); if (attr == &dev_attr_enable) { ret = sprintf(buf, "%u\n", !!q->blk_trace); @@ -1641,7 +1752,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba); out_unlock_bdev: - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); out_bdput: bdput(bdev); out: @@ -1683,7 +1794,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, if (q == NULL) goto out_bdput; - mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex); if (attr == &dev_attr_enable) { if (value) @@ -1709,7 +1820,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, } out_unlock_bdev: - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); out_bdput: bdput(bdev); out: diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 37385193a6084ed1b8fdd794eb0938c2021fcfa4..dc498b605d5dd36137eaba7bd0ee93da72a36c33 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -204,10 +204,36 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, fmt_cnt++; } - return __trace_printk(1/* fake ip will not be printed */, fmt, - mod[0] == 2 ? arg1 : mod[0] == 1 ? (long) arg1 : (u32) arg1, - mod[1] == 2 ? arg2 : mod[1] == 1 ? (long) arg2 : (u32) arg2, - mod[2] == 2 ? arg3 : mod[2] == 1 ? (long) arg3 : (u32) arg3); +/* Horrid workaround for getting va_list handling working with different + * argument type combinations generically for 32 and 64 bit archs. + */ +#define __BPF_TP_EMIT() __BPF_ARG3_TP() +#define __BPF_TP(...) \ + __trace_printk(1 /* Fake ip will not be printed. */, \ + fmt, ##__VA_ARGS__) + +#define __BPF_ARG1_TP(...) \ + ((mod[0] == 2 || (mod[0] == 1 && __BITS_PER_LONG == 64)) \ + ? __BPF_TP(arg1, ##__VA_ARGS__) \ + : ((mod[0] == 1 || (mod[0] == 0 && __BITS_PER_LONG == 32)) \ + ? __BPF_TP((long)arg1, ##__VA_ARGS__) \ + : __BPF_TP((u32)arg1, ##__VA_ARGS__))) + +#define __BPF_ARG2_TP(...) \ + ((mod[1] == 2 || (mod[1] == 1 && __BITS_PER_LONG == 64)) \ + ? __BPF_ARG1_TP(arg2, ##__VA_ARGS__) \ + : ((mod[1] == 1 || (mod[1] == 0 && __BITS_PER_LONG == 32)) \ + ? __BPF_ARG1_TP((long)arg2, ##__VA_ARGS__) \ + : __BPF_ARG1_TP((u32)arg2, ##__VA_ARGS__))) + +#define __BPF_ARG3_TP(...) \ + ((mod[2] == 2 || (mod[2] == 1 && __BITS_PER_LONG == 64)) \ + ? __BPF_ARG2_TP(arg3, ##__VA_ARGS__) \ + : ((mod[2] == 1 || (mod[2] == 0 && __BITS_PER_LONG == 32)) \ + ? __BPF_ARG2_TP((long)arg3, ##__VA_ARGS__) \ + : __BPF_ARG2_TP((u32)arg3, ##__VA_ARGS__))) + + return __BPF_TP_EMIT(); } static const struct bpf_func_proto bpf_trace_printk_proto = { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 02004ae918608f915b28341b6ed1b3b7f551c5a5..8319e09e15b945f14f9046edeb885e173ef26652 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -889,6 +889,10 @@ static int profile_graph_entry(struct ftrace_graph_ent *trace) function_profile_call(trace->func, 0, NULL, NULL); + /* If function graph is shutting down, ret_stack can be NULL */ + if (!current->ret_stack) + return 0; + if (index >= 0 && index < FTRACE_RETFUNC_DEPTH) current->ret_stack[index].subtime = 0; @@ -2824,13 +2828,14 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) if (!command || !ftrace_enabled) { /* - * If these are per_cpu ops, they still need their - * per_cpu field freed. Since, function tracing is + * If these are dynamic or per_cpu ops, they still + * need their data freed. Since, function tracing is * not currently active, we can just free them * without synchronizing all CPUs. */ - if (ops->flags & FTRACE_OPS_FL_PER_CPU) - per_cpu_ops_free(ops); + if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_PER_CPU)) + goto free_ops; + return 0; } @@ -2896,6 +2901,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) if (IS_ENABLED(CONFIG_PREEMPT)) synchronize_rcu_tasks(); + free_ops: arch_ftrace_trampoline_free(ops); if (ops->flags & FTRACE_OPS_FL_PER_CPU) @@ -4948,9 +4954,6 @@ static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; static char ftrace_graph_notrace_buf[FTRACE_FILTER_SIZE] __initdata; static int ftrace_graph_set_hash(struct ftrace_hash *hash, char *buffer); -static unsigned long save_global_trampoline; -static unsigned long save_global_flags; - static int __init set_graph_function(char *str) { strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE); @@ -5686,10 +5689,51 @@ static int referenced_filters(struct dyn_ftrace *rec) return cnt; } +static void +clear_mod_from_hash(struct ftrace_page *pg, struct ftrace_hash *hash) +{ + struct ftrace_func_entry *entry; + struct dyn_ftrace *rec; + int i; + + if (ftrace_hash_empty(hash)) + return; + + for (i = 0; i < pg->index; i++) { + rec = &pg->records[i]; + entry = __ftrace_lookup_ip(hash, rec->ip); + /* + * Do not allow this rec to match again. + * Yeah, it may waste some memory, but will be removed + * if/when the hash is modified again. + */ + if (entry) + entry->ip = 0; + } +} + +/* Clear any records from hashs */ +static void clear_mod_from_hashes(struct ftrace_page *pg) +{ + struct trace_array *tr; + + mutex_lock(&trace_types_lock); + list_for_each_entry(tr, &ftrace_trace_arrays, list) { + if (!tr->ops || !tr->ops->func_hash) + continue; + mutex_lock(&tr->ops->func_hash->regex_lock); + clear_mod_from_hash(pg, tr->ops->func_hash->filter_hash); + clear_mod_from_hash(pg, tr->ops->func_hash->notrace_hash); + mutex_unlock(&tr->ops->func_hash->regex_lock); + } + mutex_unlock(&trace_types_lock); +} + void ftrace_release_mod(struct module *mod) { struct dyn_ftrace *rec; struct ftrace_page **last_pg; + struct ftrace_page *tmp_page = NULL; struct ftrace_page *pg; int order; @@ -5719,14 +5763,25 @@ void ftrace_release_mod(struct module *mod) ftrace_update_tot_cnt -= pg->index; *last_pg = pg->next; - order = get_count_order(pg->size / ENTRIES_PER_PAGE); - free_pages((unsigned long)pg->records, order); - kfree(pg); + + pg->next = tmp_page; + tmp_page = pg; } else last_pg = &pg->next; } out_unlock: mutex_unlock(&ftrace_lock); + + for (pg = tmp_page; pg; pg = tmp_page) { + + /* Needs to be called outside of ftrace_lock */ + clear_mod_from_hashes(pg); + + order = get_count_order(pg->size / ENTRIES_PER_PAGE); + free_pages((unsigned long)pg->records, order); + tmp_page = pg->next; + kfree(pg); + } } void ftrace_module_enable(struct module *mod) @@ -6750,17 +6805,6 @@ void unregister_ftrace_graph(void) unregister_pm_notifier(&ftrace_suspend_notifier); unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); -#ifdef CONFIG_DYNAMIC_FTRACE - /* - * Function graph does not allocate the trampoline, but - * other global_ops do. We need to reset the ALLOC_TRAMP flag - * if one was used. - */ - global_ops.trampoline = save_global_trampoline; - if (save_global_flags & FTRACE_OPS_FL_ALLOC_TRAMP) - global_ops.flags |= FTRACE_OPS_FL_ALLOC_TRAMP; -#endif - out: mutex_unlock(&ftrace_lock); } diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 529cc50d7243d6c1007e517bcdc83a5312f7ae6b..81279c6602ff1753d8c38c8def566c3576578962 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4386,15 +4386,19 @@ EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu); * the page that was allocated, with the read page of the buffer. * * Returns: - * The page allocated, or NULL on error. + * The page allocated, or ERR_PTR */ void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu) { - struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; + struct ring_buffer_per_cpu *cpu_buffer; struct buffer_data_page *bpage = NULL; unsigned long flags; struct page *page; + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return ERR_PTR(-ENODEV); + + cpu_buffer = buffer->buffers[cpu]; local_irq_save(flags); arch_spin_lock(&cpu_buffer->lock); @@ -4412,7 +4416,7 @@ void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu) page = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL | __GFP_NORETRY, 0); if (!page) - return NULL; + return ERR_PTR(-ENOMEM); bpage = page_address(page); @@ -4467,8 +4471,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); * * for example: * rpage = ring_buffer_alloc_read_page(buffer, cpu); - * if (!rpage) - * return error; + * if (IS_ERR(rpage)) + * return PTR_ERR(rpage); * ret = ring_buffer_read_page(buffer, &rpage, len, cpu, 0); * if (ret >= 0) * process_page(rpage, ret); diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c index 9fbcaf56788626335bfd5412dffaf820a9b308bc..68ee79afe31c223218e8fab1ffd829b7be1226d3 100644 --- a/kernel/trace/ring_buffer_benchmark.c +++ b/kernel/trace/ring_buffer_benchmark.c @@ -113,7 +113,7 @@ static enum event_status read_page(int cpu) int i; bpage = ring_buffer_alloc_read_page(buffer, cpu); - if (!bpage) + if (IS_ERR(bpage)) return EVENT_DROPPED; ret = ring_buffer_read_page(buffer, &bpage, PAGE_SIZE, cpu, 1); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 42b9355033d45d5a7c27bf0606799772e70d7421..752e5daf0896fc529876f8801a95e23118713338 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1702,6 +1702,9 @@ void tracing_reset_all_online_cpus(void) struct trace_array *tr; list_for_each_entry(tr, &ftrace_trace_arrays, list) { + if (!tr->clear_trace) + continue; + tr->clear_trace = false; tracing_reset_online_cpus(&tr->trace_buffer); #ifdef CONFIG_TRACER_MAX_TRACE tracing_reset_online_cpus(&tr->max_buffer); @@ -2799,11 +2802,17 @@ static char *get_trace_buf(void) if (!buffer || buffer->nesting >= 4) return NULL; - return &buffer->buffer[buffer->nesting++][0]; + buffer->nesting++; + + /* Interrupts must see nesting incremented before we use the buffer */ + barrier(); + return &buffer->buffer[buffer->nesting][0]; } static void put_trace_buf(void) { + /* Don't let the decrement of nesting leak before this */ + barrier(); this_cpu_dec(trace_percpu_buffer->nesting); } @@ -4011,11 +4020,17 @@ static int tracing_open(struct inode *inode, struct file *file) /* If this file was open for write, then erase contents */ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { int cpu = tracing_get_cpu(inode); + struct trace_buffer *trace_buf = &tr->trace_buffer; + +#ifdef CONFIG_TRACER_MAX_TRACE + if (tr->current_trace->print_max) + trace_buf = &tr->max_buffer; +#endif if (cpu == RING_BUFFER_ALL_CPUS) - tracing_reset_online_cpus(&tr->trace_buffer); + tracing_reset_online_cpus(trace_buf); else - tracing_reset(&tr->trace_buffer, cpu); + tracing_reset(trace_buf, cpu); } if (file->f_mode & FMODE_READ) { @@ -5349,6 +5364,13 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf) if (t == tr->current_trace) goto out; + /* Some tracers won't work on kernel command line */ + if (system_state < SYSTEM_RUNNING && t->noboot) { + pr_warn("Tracer '%s' is not allowed on command line, ignored\n", + t->name); + goto out; + } + /* Some tracers are only allowed for the top level buffer */ if (!trace_ok_for_array(t, tr)) { ret = -EINVAL; @@ -5658,7 +5680,7 @@ static int tracing_wait_pipe(struct file *filp) * * iter->pos will be 0 if we haven't read anything. */ - if (!tracing_is_on() && iter->pos) + if (!tracer_tracing_is_on(iter->tr) && iter->pos) break; mutex_unlock(&iter->mutex); @@ -6220,7 +6242,7 @@ static int tracing_set_clock(struct trace_array *tr, const char *clockstr) tracing_reset_online_cpus(&tr->trace_buffer); #ifdef CONFIG_TRACER_MAX_TRACE - if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) + if (tr->max_buffer.buffer) ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); tracing_reset_online_cpus(&tr->max_buffer); #endif @@ -6598,7 +6620,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, { struct ftrace_buffer_info *info = filp->private_data; struct trace_iterator *iter = &info->iter; - ssize_t ret; + ssize_t ret = 0; ssize_t size; if (!count) @@ -6612,10 +6634,15 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, if (!info->spare) { info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, iter->cpu_file); - info->spare_cpu = iter->cpu_file; + if (IS_ERR(info->spare)) { + ret = PTR_ERR(info->spare); + info->spare = NULL; + } else { + info->spare_cpu = iter->cpu_file; + } } if (!info->spare) - return -ENOMEM; + return ret; /* Do we have previous read data to read? */ if (info->read < PAGE_SIZE) @@ -6790,8 +6817,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, ref->ref = 1; ref->buffer = iter->trace_buffer->buffer; ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); - if (!ref->page) { - ret = -ENOMEM; + if (IS_ERR(ref->page)) { + ret = PTR_ERR(ref->page); + ref->page = NULL; kfree(ref); break; } @@ -8293,6 +8321,7 @@ __init static int tracer_alloc_buffers(void) if (ret < 0) goto out_free_cpumask; /* Used for event triggers */ + ret = -ENOMEM; temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE); if (!temp_buffer) goto out_rm_hp_state; @@ -8407,4 +8436,4 @@ __init static int clear_boot_tracer(void) } fs_initcall(tracer_init_tracefs); -late_initcall(clear_boot_tracer); +late_initcall_sync(clear_boot_tracer); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 490ba229931d7d00243a1be009dec6ab2b3a5864..652c682707cdd4f489a00c3b14df0b97ae8d2425 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -245,6 +245,7 @@ struct trace_array { int stop_count; int clock_id; int nr_topts; + bool clear_trace; struct tracer *current_trace; unsigned int trace_flags; unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE]; @@ -443,6 +444,8 @@ struct tracer { #ifdef CONFIG_TRACER_MAX_TRACE bool use_max_tr; #endif + /* True if tracer cannot be enabled in kernel param */ + bool noboot; }; diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 562fa69df5d3d3168db8a270b23c5b4864b6a79d..13ba2d3f6a91a147c8377041ee387ff457ab21c2 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -306,6 +306,7 @@ static void perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *pt_regs) { + struct perf_event *event; struct ftrace_entry *entry; struct hlist_head *head; struct pt_regs regs; @@ -329,8 +330,9 @@ perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip, entry->ip = ip; entry->parent_ip = parent_ip; + event = container_of(ops, struct perf_event, ftrace_ops); perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, TRACE_FN, - 1, ®s, head, NULL); + 1, ®s, head, NULL, event); #undef ENTRY_SIZE } diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 36132f9280e627ae91fecc7955148178bb076480..87468398b9ed6206722db4126cc6c6318580e357 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -406,7 +406,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, if (file->flags & EVENT_FILE_FL_RECORDED_TGID) { tracing_stop_tgid_record(); - clear_bit(EVENT_FILE_FL_RECORDED_CMD_BIT, &file->flags); + clear_bit(EVENT_FILE_FL_RECORDED_TGID_BIT, &file->flags); } call->class->reg(call, TRACE_REG_UNREGISTER, file); @@ -466,7 +466,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, set_bit(EVENT_FILE_FL_ENABLED_BIT, &file->flags); /* WAS_ENABLED gets set but never cleared. */ - call->flags |= TRACE_EVENT_FL_WAS_ENABLED; + set_bit(EVENT_FILE_FL_WAS_ENABLED_BIT, &file->flags); } break; } @@ -2058,6 +2058,10 @@ static void event_remove(struct trace_event_call *call) do_for_each_event_file(tr, file) { if (file->event_call != call) continue; + + if (file->flags & EVENT_FILE_FL_WAS_ENABLED) + tr->clear_trace = true; + ftrace_event_enable_disable(file, 0); /* * The do_for_each_event_file() is @@ -2396,15 +2400,11 @@ static void trace_module_add_events(struct module *mod) static void trace_module_remove_events(struct module *mod) { struct trace_event_call *call, *p; - bool clear_trace = false; down_write(&trace_event_sem); list_for_each_entry_safe(call, p, &ftrace_events, list) { - if (call->mod == mod) { - if (call->flags & TRACE_EVENT_FL_WAS_ENABLED) - clear_trace = true; + if (call->mod == mod) __trace_remove_event_call(call); - } } up_write(&trace_event_sem); @@ -2416,8 +2416,7 @@ static void trace_module_remove_events(struct module *mod) * over from this module may be passed to the new module events and * unexpected results may occur. */ - if (clear_trace) - tracing_reset_all_online_cpus(); + tracing_reset_all_online_cpus(); } static int trace_module_notify(struct notifier_block *self, diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 59a411ff60c709834121fc70363c74560dfe1ff5..61e7f0678d3359fe77c52beb27e7d47a48865570 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -702,7 +702,7 @@ static void append_filter_err(struct filter_parse_state *ps, int pos = ps->lasterr_pos; char *buf, *pbuf; - buf = (char *)__get_free_page(GFP_TEMPORARY); + buf = (char *)__get_free_page(GFP_KERNEL); if (!buf) return; @@ -1959,6 +1959,10 @@ static int create_filter(struct trace_event_call *call, if (err && set_str) append_filter_err(ps, filter); } + if (err && !set_str) { + free_event_filter(filter); + filter = NULL; + } create_filter_finish(ps); *filterp = filter; diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index d56123cdcc89027ee5841cf6573de474b38ebb39..b8f1f54731af0ab1190783291ffa1ca9aaf33feb 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1543,7 +1543,7 @@ fs_initcall(init_graph_tracefs); static __init int init_graph_trace(void) { - max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1); + max_bytes_for_cpu = snprintf(NULL, 0, "%u", nr_cpu_ids - 1); if (!register_trace_event(&graph_trace_entry_event)) { pr_warn("Warning: could not register graph trace events\n"); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index c9b5aa10fbf9c582b38f21f76de5a83398f6bb4a..8a907e12b6b901cd88c597210231b3fe48c25c8e 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1200,7 +1200,7 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) memset(&entry[1], 0, dsize); store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, - head, NULL); + head, NULL, NULL); } NOKPROBE_SYMBOL(kprobe_perf_func); @@ -1236,7 +1236,7 @@ kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, entry->ret_ip = (unsigned long)ri->ret_addr; store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, - head, NULL); + head, NULL, NULL); } NOKPROBE_SYMBOL(kretprobe_perf_func); #endif /* CONFIG_PERF_EVENTS */ diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index cd7480d0a201e335cd7adc20c9cb0a8dba16f189..dca78fc48439d21a80cd6576269eded8bfe13623 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -282,6 +282,7 @@ static struct tracer mmio_tracer __read_mostly = .close = mmio_close, .read = mmio_read, .print_line = mmio_print_line, + .noboot = true, }; __init static int init_mmio_trace(void) diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index bac629af2285748bbdac64b6b5c632f2fcaed49d..c738e764e2a55cfd3303a3262d748c94a917a86d 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -656,15 +656,6 @@ int trace_print_lat_context(struct trace_iterator *iter) return !trace_seq_has_overflowed(s); } -static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; - -static int task_state_char(unsigned long state) -{ - int bit = state ? __ffs(state) + 1 : 0; - - return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?'; -} - /** * ftrace_find_event - find a registered event * @type: the type of event to look for @@ -930,8 +921,8 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, trace_assign_type(field, iter->ent); - T = task_state_char(field->next_state); - S = task_state_char(field->prev_state); + T = __task_state_to_char(field->next_state); + S = __task_state_to_char(field->prev_state); trace_find_cmdline(field->next_pid, comm); trace_seq_printf(&iter->seq, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", @@ -966,8 +957,8 @@ static int trace_ctxwake_raw(struct trace_iterator *iter, char S) trace_assign_type(field, iter->ent); if (!S) - S = task_state_char(field->prev_state); - T = task_state_char(field->next_state); + S = __task_state_to_char(field->prev_state); + T = __task_state_to_char(field->next_state); trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", field->prev_pid, field->prev_prio, @@ -1002,8 +993,8 @@ static int trace_ctxwake_hex(struct trace_iterator *iter, char S) trace_assign_type(field, iter->ent); if (!S) - S = task_state_char(field->prev_state); - T = task_state_char(field->next_state); + S = __task_state_to_char(field->prev_state); + T = __task_state_to_char(field->next_state); SEQ_PUT_HEX_FIELD(s, field->prev_pid); SEQ_PUT_HEX_FIELD(s, field->prev_prio); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index ddec53b6764617e8fe431d93bf9f970a5015b4be..0c331978b1a636e9f2736f77bd93e97415c1ca10 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -397,10 +397,10 @@ tracing_sched_switch_trace(struct trace_array *tr, entry = ring_buffer_event_data(event); entry->prev_pid = prev->pid; entry->prev_prio = prev->prio; - entry->prev_state = prev->state; + entry->prev_state = __get_task_state(prev); entry->next_pid = next->pid; entry->next_prio = next->prio; - entry->next_state = next->state; + entry->next_state = __get_task_state(next); entry->next_cpu = task_cpu(next); if (!call_filter_check_discard(call, entry, buffer, event)) @@ -425,10 +425,10 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry = ring_buffer_event_data(event); entry->prev_pid = curr->pid; entry->prev_prio = curr->prio; - entry->prev_state = curr->state; + entry->prev_state = __get_task_state(curr); entry->next_pid = wakee->pid; entry->next_prio = wakee->prio; - entry->next_state = wakee->state; + entry->next_state = __get_task_state(wakee); entry->next_cpu = task_cpu(wakee); if (!call_filter_check_discard(call, entry, buffer, event)) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index cb917cebae291bfbf00a86ea67e69d151b626e27..b17ec642793bc327e56f14d433a725dcff330f78 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -273,7 +273,7 @@ static int trace_selftest_ops(struct trace_array *tr, int cnt) goto out_free; if (cnt > 1) { if (trace_selftest_test_global_cnt == 0) - goto out; + goto out_free; } if (trace_selftest_test_dyn_cnt == 0) goto out_free; diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index a4df67cbc711459df2aa8b4a313eb449a472ee45..49cb41412eece8bb7dff9bedf5fd7991ade07b76 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -96,23 +96,9 @@ check_stack(unsigned long ip, unsigned long *stack) if (in_nmi()) return; - /* - * There's a slight chance that we are tracing inside the - * RCU infrastructure, and rcu_irq_enter() will not work - * as expected. - */ - if (unlikely(rcu_irq_enter_disabled())) - return; - local_irq_save(flags); arch_spin_lock(&stack_trace_max_lock); - /* - * RCU may not be watching, make it see us. - * The stack trace code uses rcu_sched. - */ - rcu_irq_enter(); - /* In case another CPU set the tracer_frame on us */ if (unlikely(!frame_size)) this_size -= tracer_frame; @@ -205,7 +191,6 @@ check_stack(unsigned long ip, unsigned long *stack) } out: - rcu_irq_exit(); arch_spin_unlock(&stack_trace_max_lock); local_irq_restore(flags); } diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 5e10395da88ecc0fe213b77510355119ab5f7648..696afe72d3b1445738feaa1031a4d7110363d6dd 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -559,11 +559,29 @@ static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls); static int sys_perf_refcount_enter; static int sys_perf_refcount_exit; +static int perf_call_bpf_enter(struct bpf_prog *prog, struct pt_regs *regs, + struct syscall_metadata *sys_data, + struct syscall_trace_enter *rec) { + struct syscall_tp_t { + unsigned long long regs; + unsigned long syscall_nr; + unsigned long args[SYSCALL_DEFINE_MAXARGS]; + } param; + int i; + + *(struct pt_regs **)¶m = regs; + param.syscall_nr = rec->nr; + for (i = 0; i < sys_data->nb_args; i++) + param.args[i] = rec->args[i]; + return trace_call_bpf(prog, ¶m); +} + static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) { struct syscall_metadata *sys_data; struct syscall_trace_enter *rec; struct hlist_head *head; + struct bpf_prog *prog; int syscall_nr; int rctx; int size; @@ -578,8 +596,9 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) if (!sys_data) return; + prog = READ_ONCE(sys_data->enter_event->prog); head = this_cpu_ptr(sys_data->enter_event->perf_events); - if (hlist_empty(head)) + if (!prog && hlist_empty(head)) return; /* get the size after alignment with the u32 buffer size field */ @@ -594,9 +613,16 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) rec->nr = syscall_nr; syscall_get_arguments(current, regs, 0, sys_data->nb_args, (unsigned long *)&rec->args); + + if ((prog && !perf_call_bpf_enter(prog, regs, sys_data, rec)) || + hlist_empty(head)) { + perf_swevent_put_recursion_context(rctx); + return; + } + perf_trace_buf_submit(rec, size, rctx, sys_data->enter_event->event.type, 1, regs, - head, NULL); + head, NULL, NULL); } static int perf_sysenter_enable(struct trace_event_call *call) @@ -633,11 +659,26 @@ static void perf_sysenter_disable(struct trace_event_call *call) mutex_unlock(&syscall_trace_lock); } +static int perf_call_bpf_exit(struct bpf_prog *prog, struct pt_regs *regs, + struct syscall_trace_exit *rec) { + struct syscall_tp_t { + unsigned long long regs; + unsigned long syscall_nr; + unsigned long ret; + } param; + + *(struct pt_regs **)¶m = regs; + param.syscall_nr = rec->nr; + param.ret = rec->ret; + return trace_call_bpf(prog, ¶m); +} + static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) { struct syscall_metadata *sys_data; struct syscall_trace_exit *rec; struct hlist_head *head; + struct bpf_prog *prog; int syscall_nr; int rctx; int size; @@ -652,8 +693,9 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) if (!sys_data) return; + prog = READ_ONCE(sys_data->exit_event->prog); head = this_cpu_ptr(sys_data->exit_event->perf_events); - if (hlist_empty(head)) + if (!prog && hlist_empty(head)) return; /* We can probably do that at build time */ @@ -666,8 +708,15 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) rec->nr = syscall_nr; rec->ret = syscall_get_return_value(current, regs); + + if ((prog && !perf_call_bpf_exit(prog, regs, rec)) || + hlist_empty(head)) { + perf_swevent_put_recursion_context(rctx); + return; + } + perf_trace_buf_submit(rec, size, rctx, sys_data->exit_event->event.type, - 1, regs, head, NULL); + 1, regs, head, NULL, NULL); } static int perf_sysexit_enable(struct trace_event_call *call) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index a7581fec96818ed5bd67ce36dec28d67f40665f8..4525e0271a5396266d976fe36f043e2dad7a09c4 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -1156,7 +1156,7 @@ static void __uprobe_perf_func(struct trace_uprobe *tu, } perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, - head, NULL); + head, NULL, NULL); out: preempt_enable(); } diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c index 0a689bbb78ef4fe48d9e55cb867e836aea87a726..305039b122fafba242f73b5982289ce4a12a6e20 100644 --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c @@ -221,16 +221,19 @@ void tracing_map_array_free(struct tracing_map_array *a) if (!a) return; - if (!a->pages) { - kfree(a); - return; - } + if (!a->pages) + goto free; for (i = 0; i < a->n_pages; i++) { if (!a->pages[i]) break; free_page((unsigned long)a->pages[i]); } + + kfree(a->pages); + + free: + kfree(a); } struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, diff --git a/kernel/umh.c b/kernel/umh.c new file mode 100644 index 0000000000000000000000000000000000000000..6ff9905250ff0563713c64585a74e888de70f343 --- /dev/null +++ b/kernel/umh.c @@ -0,0 +1,568 @@ +/* + * umh - the kernel usermode helper + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CAP_BSET (void *)1 +#define CAP_PI (void *)2 + +static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; +static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; +static DEFINE_SPINLOCK(umh_sysctl_lock); +static DECLARE_RWSEM(umhelper_sem); + +static void call_usermodehelper_freeinfo(struct subprocess_info *info) +{ + if (info->cleanup) + (*info->cleanup)(info); + kfree(info); +} + +static void umh_complete(struct subprocess_info *sub_info) +{ + struct completion *comp = xchg(&sub_info->complete, NULL); + /* + * See call_usermodehelper_exec(). If xchg() returns NULL + * we own sub_info, the UMH_KILLABLE caller has gone away + * or the caller used UMH_NO_WAIT. + */ + if (comp) + complete(comp); + else + call_usermodehelper_freeinfo(sub_info); +} + +/* + * This is the task which runs the usermode application + */ +static int call_usermodehelper_exec_async(void *data) +{ + struct subprocess_info *sub_info = data; + struct cred *new; + int retval; + + spin_lock_irq(¤t->sighand->siglock); + flush_signal_handlers(current, 1); + spin_unlock_irq(¤t->sighand->siglock); + + /* + * Our parent (unbound workqueue) runs with elevated scheduling + * priority. Avoid propagating that into the userspace child. + */ + set_user_nice(current, 0); + + retval = -ENOMEM; + new = prepare_kernel_cred(current); + if (!new) + goto out; + + spin_lock(&umh_sysctl_lock); + new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset); + new->cap_inheritable = cap_intersect(usermodehelper_inheritable, + new->cap_inheritable); + spin_unlock(&umh_sysctl_lock); + + if (sub_info->init) { + retval = sub_info->init(sub_info, new); + if (retval) { + abort_creds(new); + goto out; + } + } + + commit_creds(new); + + retval = do_execve(getname_kernel(sub_info->path), + (const char __user *const __user *)sub_info->argv, + (const char __user *const __user *)sub_info->envp); +out: + sub_info->retval = retval; + /* + * call_usermodehelper_exec_sync() will call umh_complete + * if UHM_WAIT_PROC. + */ + if (!(sub_info->wait & UMH_WAIT_PROC)) + umh_complete(sub_info); + if (!retval) + return 0; + do_exit(0); +} + +/* Handles UMH_WAIT_PROC. */ +static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info) +{ + pid_t pid; + + /* If SIGCLD is ignored sys_wait4 won't populate the status. */ + kernel_sigaction(SIGCHLD, SIG_DFL); + pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD); + if (pid < 0) { + sub_info->retval = pid; + } else { + int ret = -ECHILD; + /* + * Normally it is bogus to call wait4() from in-kernel because + * wait4() wants to write the exit code to a userspace address. + * But call_usermodehelper_exec_sync() always runs as kernel + * thread (workqueue) and put_user() to a kernel address works + * OK for kernel threads, due to their having an mm_segment_t + * which spans the entire address space. + * + * Thus the __user pointer cast is valid here. + */ + sys_wait4(pid, (int __user *)&ret, 0, NULL); + + /* + * If ret is 0, either call_usermodehelper_exec_async failed and + * the real error code is already in sub_info->retval or + * sub_info->retval is 0 anyway, so don't mess with it then. + */ + if (ret) + sub_info->retval = ret; + } + + /* Restore default kernel sig handler */ + kernel_sigaction(SIGCHLD, SIG_IGN); + + umh_complete(sub_info); +} + +/* + * We need to create the usermodehelper kernel thread from a task that is affine + * to an optimized set of CPUs (or nohz housekeeping ones) such that they + * inherit a widest affinity irrespective of call_usermodehelper() callers with + * possibly reduced affinity (eg: per-cpu workqueues). We don't want + * usermodehelper targets to contend a busy CPU. + * + * Unbound workqueues provide such wide affinity and allow to block on + * UMH_WAIT_PROC requests without blocking pending request (up to some limit). + * + * Besides, workqueues provide the privilege level that caller might not have + * to perform the usermodehelper request. + * + */ +static void call_usermodehelper_exec_work(struct work_struct *work) +{ + struct subprocess_info *sub_info = + container_of(work, struct subprocess_info, work); + + if (sub_info->wait & UMH_WAIT_PROC) { + call_usermodehelper_exec_sync(sub_info); + } else { + pid_t pid; + /* + * Use CLONE_PARENT to reparent it to kthreadd; we do not + * want to pollute current->children, and we need a parent + * that always ignores SIGCHLD to ensure auto-reaping. + */ + pid = kernel_thread(call_usermodehelper_exec_async, sub_info, + CLONE_PARENT | SIGCHLD); + if (pid < 0) { + sub_info->retval = pid; + umh_complete(sub_info); + } + } +} + +/* + * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY + * (used for preventing user land processes from being created after the user + * land has been frozen during a system-wide hibernation or suspend operation). + * Should always be manipulated under umhelper_sem acquired for write. + */ +static enum umh_disable_depth usermodehelper_disabled = UMH_DISABLED; + +/* Number of helpers running */ +static atomic_t running_helpers = ATOMIC_INIT(0); + +/* + * Wait queue head used by usermodehelper_disable() to wait for all running + * helpers to finish. + */ +static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); + +/* + * Used by usermodehelper_read_lock_wait() to wait for usermodehelper_disabled + * to become 'false'. + */ +static DECLARE_WAIT_QUEUE_HEAD(usermodehelper_disabled_waitq); + +/* + * Time to wait for running_helpers to become zero before the setting of + * usermodehelper_disabled in usermodehelper_disable() fails + */ +#define RUNNING_HELPERS_TIMEOUT (5 * HZ) + +int usermodehelper_read_trylock(void) +{ + DEFINE_WAIT(wait); + int ret = 0; + + down_read(&umhelper_sem); + for (;;) { + prepare_to_wait(&usermodehelper_disabled_waitq, &wait, + TASK_INTERRUPTIBLE); + if (!usermodehelper_disabled) + break; + + if (usermodehelper_disabled == UMH_DISABLED) + ret = -EAGAIN; + + up_read(&umhelper_sem); + + if (ret) + break; + + schedule(); + try_to_freeze(); + + down_read(&umhelper_sem); + } + finish_wait(&usermodehelper_disabled_waitq, &wait); + return ret; +} +EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); + +long usermodehelper_read_lock_wait(long timeout) +{ + DEFINE_WAIT(wait); + + if (timeout < 0) + return -EINVAL; + + down_read(&umhelper_sem); + for (;;) { + prepare_to_wait(&usermodehelper_disabled_waitq, &wait, + TASK_UNINTERRUPTIBLE); + if (!usermodehelper_disabled) + break; + + up_read(&umhelper_sem); + + timeout = schedule_timeout(timeout); + if (!timeout) + break; + + down_read(&umhelper_sem); + } + finish_wait(&usermodehelper_disabled_waitq, &wait); + return timeout; +} +EXPORT_SYMBOL_GPL(usermodehelper_read_lock_wait); + +void usermodehelper_read_unlock(void) +{ + up_read(&umhelper_sem); +} +EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); + +/** + * __usermodehelper_set_disable_depth - Modify usermodehelper_disabled. + * @depth: New value to assign to usermodehelper_disabled. + * + * Change the value of usermodehelper_disabled (under umhelper_sem locked for + * writing) and wakeup tasks waiting for it to change. + */ +void __usermodehelper_set_disable_depth(enum umh_disable_depth depth) +{ + down_write(&umhelper_sem); + usermodehelper_disabled = depth; + wake_up(&usermodehelper_disabled_waitq); + up_write(&umhelper_sem); +} + +/** + * __usermodehelper_disable - Prevent new helpers from being started. + * @depth: New value to assign to usermodehelper_disabled. + * + * Set usermodehelper_disabled to @depth and wait for running helpers to exit. + */ +int __usermodehelper_disable(enum umh_disable_depth depth) +{ + long retval; + + if (!depth) + return -EINVAL; + + down_write(&umhelper_sem); + usermodehelper_disabled = depth; + up_write(&umhelper_sem); + + /* + * From now on call_usermodehelper_exec() won't start any new + * helpers, so it is sufficient if running_helpers turns out to + * be zero at one point (it may be increased later, but that + * doesn't matter). + */ + retval = wait_event_timeout(running_helpers_waitq, + atomic_read(&running_helpers) == 0, + RUNNING_HELPERS_TIMEOUT); + if (retval) + return 0; + + __usermodehelper_set_disable_depth(UMH_ENABLED); + return -EAGAIN; +} + +static void helper_lock(void) +{ + atomic_inc(&running_helpers); + smp_mb__after_atomic(); +} + +static void helper_unlock(void) +{ + if (atomic_dec_and_test(&running_helpers)) + wake_up(&running_helpers_waitq); +} + +/** + * call_usermodehelper_setup - prepare to call a usermode helper + * @path: path to usermode executable + * @argv: arg vector for process + * @envp: environment for process + * @gfp_mask: gfp mask for memory allocation + * @cleanup: a cleanup function + * @init: an init function + * @data: arbitrary context sensitive data + * + * Returns either %NULL on allocation failure, or a subprocess_info + * structure. This should be passed to call_usermodehelper_exec to + * exec the process and free the structure. + * + * The init function is used to customize the helper process prior to + * exec. A non-zero return code causes the process to error out, exit, + * and return the failure to the calling process + * + * The cleanup function is just before ethe subprocess_info is about to + * be freed. This can be used for freeing the argv and envp. The + * Function must be runnable in either a process context or the + * context in which call_usermodehelper_exec is called. + */ +struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv, + char **envp, gfp_t gfp_mask, + int (*init)(struct subprocess_info *info, struct cred *new), + void (*cleanup)(struct subprocess_info *info), + void *data) +{ + struct subprocess_info *sub_info; + sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask); + if (!sub_info) + goto out; + + INIT_WORK(&sub_info->work, call_usermodehelper_exec_work); + +#ifdef CONFIG_STATIC_USERMODEHELPER + sub_info->path = CONFIG_STATIC_USERMODEHELPER_PATH; +#else + sub_info->path = path; +#endif + sub_info->argv = argv; + sub_info->envp = envp; + + sub_info->cleanup = cleanup; + sub_info->init = init; + sub_info->data = data; + out: + return sub_info; +} +EXPORT_SYMBOL(call_usermodehelper_setup); + +/** + * call_usermodehelper_exec - start a usermode application + * @sub_info: information about the subprocessa + * @wait: wait for the application to finish and return status. + * when UMH_NO_WAIT don't wait at all, but you get no useful error back + * when the program couldn't be exec'ed. This makes it safe to call + * from interrupt context. + * + * Runs a user-space application. The application is started + * asynchronously if wait is not set, and runs as a child of system workqueues. + * (ie. it runs with full root capabilities and optimized affinity). + */ +int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) +{ + DECLARE_COMPLETION_ONSTACK(done); + int retval = 0; + + if (!sub_info->path) { + call_usermodehelper_freeinfo(sub_info); + return -EINVAL; + } + helper_lock(); + if (usermodehelper_disabled) { + retval = -EBUSY; + goto out; + } + + /* + * If there is no binary for us to call, then just return and get out of + * here. This allows us to set STATIC_USERMODEHELPER_PATH to "" and + * disable all call_usermodehelper() calls. + */ + if (strlen(sub_info->path) == 0) + goto out; + + /* + * Set the completion pointer only if there is a waiter. + * This makes it possible to use umh_complete to free + * the data structure in case of UMH_NO_WAIT. + */ + sub_info->complete = (wait == UMH_NO_WAIT) ? NULL : &done; + sub_info->wait = wait; + + queue_work(system_unbound_wq, &sub_info->work); + if (wait == UMH_NO_WAIT) /* task has freed sub_info */ + goto unlock; + + if (wait & UMH_KILLABLE) { + retval = wait_for_completion_killable(&done); + if (!retval) + goto wait_done; + + /* umh_complete() will see NULL and free sub_info */ + if (xchg(&sub_info->complete, NULL)) + goto unlock; + /* fallthrough, umh_complete() was already called */ + } + + wait_for_completion(&done); +wait_done: + retval = sub_info->retval; +out: + call_usermodehelper_freeinfo(sub_info); +unlock: + helper_unlock(); + return retval; +} +EXPORT_SYMBOL(call_usermodehelper_exec); + +/** + * call_usermodehelper() - prepare and start a usermode application + * @path: path to usermode executable + * @argv: arg vector for process + * @envp: environment for process + * @wait: wait for the application to finish and return status. + * when UMH_NO_WAIT don't wait at all, but you get no useful error back + * when the program couldn't be exec'ed. This makes it safe to call + * from interrupt context. + * + * This function is the equivalent to use call_usermodehelper_setup() and + * call_usermodehelper_exec(). + */ +int call_usermodehelper(const char *path, char **argv, char **envp, int wait) +{ + struct subprocess_info *info; + gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; + + info = call_usermodehelper_setup(path, argv, envp, gfp_mask, + NULL, NULL, NULL); + if (info == NULL) + return -ENOMEM; + + return call_usermodehelper_exec(info, wait); +} +EXPORT_SYMBOL(call_usermodehelper); + +static int proc_cap_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct ctl_table t; + unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; + kernel_cap_t new_cap; + int err, i; + + if (write && (!capable(CAP_SETPCAP) || + !capable(CAP_SYS_MODULE))) + return -EPERM; + + /* + * convert from the global kernel_cap_t to the ulong array to print to + * userspace if this is a read. + */ + spin_lock(&umh_sysctl_lock); + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) { + if (table->data == CAP_BSET) + cap_array[i] = usermodehelper_bset.cap[i]; + else if (table->data == CAP_PI) + cap_array[i] = usermodehelper_inheritable.cap[i]; + else + BUG(); + } + spin_unlock(&umh_sysctl_lock); + + t = *table; + t.data = &cap_array; + + /* + * actually read or write and array of ulongs from userspace. Remember + * these are least significant 32 bits first + */ + err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos); + if (err < 0) + return err; + + /* + * convert from the sysctl array of ulongs to the kernel_cap_t + * internal representation + */ + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) + new_cap.cap[i] = cap_array[i]; + + /* + * Drop everything not in the new_cap (but don't add things) + */ + spin_lock(&umh_sysctl_lock); + if (write) { + if (table->data == CAP_BSET) + usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); + if (table->data == CAP_PI) + usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); + } + spin_unlock(&umh_sysctl_lock); + + return 0; +} + +struct ctl_table usermodehelper_table[] = { + { + .procname = "bset", + .data = CAP_BSET, + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), + .mode = 0600, + .proc_handler = proc_cap_handler, + }, + { + .procname = "inheritable", + .data = CAP_PI, + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), + .mode = 0600, + .proc_handler = proc_cap_handler, + }, + { } +}; diff --git a/kernel/up.c b/kernel/up.c index ee81ac9af4caff801a531a9219efd19637b76688..42c46bf3e0a5ca5b6ece7dc967fc34c72dd581a2 100644 --- a/kernel/up.c +++ b/kernel/up.c @@ -23,7 +23,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, } EXPORT_SYMBOL(smp_call_function_single); -int smp_call_function_single_async(int cpu, struct call_single_data *csd) +int smp_call_function_single_async(int cpu, call_single_data_t *csd) { unsigned long flags; diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 2f735cbe05e8aca3b8ee8a3dcc7de493f9757c05..c490f1e4313b998a60686b98fbdf6b0167753e11 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -986,17 +986,21 @@ bool userns_may_setgroups(const struct user_namespace *ns) } /* - * Returns true if @ns is the same namespace as or a descendant of - * @target_ns. + * Returns true if @child is the same namespace or a descendant of + * @ancestor. */ +bool in_userns(const struct user_namespace *ancestor, + const struct user_namespace *child) +{ + const struct user_namespace *ns; + for (ns = child; ns->level > ancestor->level; ns = ns->parent) + ; + return (ns == ancestor); +} + bool current_in_userns(const struct user_namespace *target_ns) { - struct user_namespace *ns; - for (ns = current_user_ns(); ns; ns = ns->parent) { - if (ns == target_ns) - return true; - } - return false; + return in_userns(target_ns, current_user_ns()); } static inline struct user_namespace *to_user_ns(struct ns_common *ns) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 06d3389bca0df01c8a730f7b270767f6ed35a8a9..6bcb854909c0b6f1563469ae3517fa1f89c43268 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -29,20 +29,29 @@ #include #include -/* Watchdog configuration */ -static DEFINE_MUTEX(watchdog_proc_mutex); - -int __read_mostly nmi_watchdog_enabled; +static DEFINE_MUTEX(watchdog_mutex); #if defined(CONFIG_HARDLOCKUP_DETECTOR) || defined(CONFIG_HAVE_NMI_WATCHDOG) -unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED | - NMI_WATCHDOG_ENABLED; +# define WATCHDOG_DEFAULT (SOFT_WATCHDOG_ENABLED | NMI_WATCHDOG_ENABLED) +# define NMI_WATCHDOG_DEFAULT 1 #else -unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED; +# define WATCHDOG_DEFAULT (SOFT_WATCHDOG_ENABLED) +# define NMI_WATCHDOG_DEFAULT 0 #endif +unsigned long __read_mostly watchdog_enabled; +int __read_mostly watchdog_user_enabled = 1; +int __read_mostly nmi_watchdog_user_enabled = NMI_WATCHDOG_DEFAULT; +int __read_mostly soft_watchdog_user_enabled = 1; +int __read_mostly watchdog_thresh = 10; +int __read_mostly nmi_watchdog_available; + +struct cpumask watchdog_allowed_mask __read_mostly; + +struct cpumask watchdog_cpumask __read_mostly; +unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask); + #ifdef CONFIG_HARDLOCKUP_DETECTOR -/* boot commands */ /* * Should we panic when a soft-lockup or hard-lockup occurs: */ @@ -56,9 +65,9 @@ unsigned int __read_mostly hardlockup_panic = * kernel command line parameters are parsed, because otherwise it is not * possible to override this in hardlockup_panic_setup(). */ -void hardlockup_detector_disable(void) +void __init hardlockup_detector_disable(void) { - watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; + nmi_watchdog_user_enabled = 0; } static int __init hardlockup_panic_setup(char *str) @@ -68,48 +77,24 @@ static int __init hardlockup_panic_setup(char *str) else if (!strncmp(str, "nopanic", 7)) hardlockup_panic = 0; else if (!strncmp(str, "0", 1)) - watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; + nmi_watchdog_user_enabled = 0; else if (!strncmp(str, "1", 1)) - watchdog_enabled |= NMI_WATCHDOG_ENABLED; + nmi_watchdog_user_enabled = 1; return 1; } __setup("nmi_watchdog=", hardlockup_panic_setup); -#endif - -#ifdef CONFIG_SOFTLOCKUP_DETECTOR -int __read_mostly soft_watchdog_enabled; -#endif - -int __read_mostly watchdog_user_enabled; -int __read_mostly watchdog_thresh = 10; - -#ifdef CONFIG_SMP -int __read_mostly sysctl_softlockup_all_cpu_backtrace; +# ifdef CONFIG_SMP int __read_mostly sysctl_hardlockup_all_cpu_backtrace; -#endif -struct cpumask watchdog_cpumask __read_mostly; -unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask); -/* - * The 'watchdog_running' variable is set to 1 when the watchdog threads - * are registered/started and is set to 0 when the watchdog threads are - * unregistered/stopped, so it is an indicator whether the threads exist. - */ -static int __read_mostly watchdog_running; -/* - * If a subsystem has a need to deactivate the watchdog temporarily, it - * can use the suspend/resume interface to achieve this. The content of - * the 'watchdog_suspended' variable reflects this state. Existing threads - * are parked/unparked by the lockup_detector_{suspend|resume} functions - * (see comment blocks pertaining to those functions for further details). - * - * 'watchdog_suspended' also prevents threads from being registered/started - * or unregistered/stopped via parameters in /proc/sys/kernel, so the state - * of 'watchdog_running' cannot change while the watchdog is deactivated - * temporarily (see related code in 'proc' handlers). - */ -int __read_mostly watchdog_suspended; +static int __init hardlockup_all_cpu_backtrace_setup(char *str) +{ + sysctl_hardlockup_all_cpu_backtrace = !!simple_strtol(str, NULL, 0); + return 1; +} +__setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup); +# endif /* CONFIG_SMP */ +#endif /* CONFIG_HARDLOCKUP_DETECTOR */ /* * These functions can be overridden if an architecture implements its @@ -121,36 +106,68 @@ int __read_mostly watchdog_suspended; */ int __weak watchdog_nmi_enable(unsigned int cpu) { + hardlockup_detector_perf_enable(); return 0; } + void __weak watchdog_nmi_disable(unsigned int cpu) { + hardlockup_detector_perf_disable(); } -/* - * watchdog_nmi_reconfigure can be implemented to be notified after any - * watchdog configuration change. The arch hardlockup watchdog should - * respond to the following variables: - * - nmi_watchdog_enabled +/* Return 0, if a NMI watchdog is available. Error code otherwise */ +int __weak __init watchdog_nmi_probe(void) +{ + return hardlockup_detector_perf_init(); +} + +/** + * watchdog_nmi_stop - Stop the watchdog for reconfiguration + * + * The reconfiguration steps are: + * watchdog_nmi_stop(); + * update_variables(); + * watchdog_nmi_start(); + */ +void __weak watchdog_nmi_stop(void) { } + +/** + * watchdog_nmi_start - Start the watchdog after reconfiguration + * + * Counterpart to watchdog_nmi_stop(). + * + * The following variables have been updated in update_variables() and + * contain the currently valid configuration: + * - watchdog_enabled * - watchdog_thresh * - watchdog_cpumask - * - sysctl_hardlockup_all_cpu_backtrace - * - hardlockup_panic - * - watchdog_suspended */ -void __weak watchdog_nmi_reconfigure(void) +void __weak watchdog_nmi_start(void) { } + +/** + * lockup_detector_update_enable - Update the sysctl enable bit + * + * Caller needs to make sure that the NMI/perf watchdogs are off, so this + * can't race with watchdog_nmi_disable(). + */ +static void lockup_detector_update_enable(void) { + watchdog_enabled = 0; + if (!watchdog_user_enabled) + return; + if (nmi_watchdog_available && nmi_watchdog_user_enabled) + watchdog_enabled |= NMI_WATCHDOG_ENABLED; + if (soft_watchdog_user_enabled) + watchdog_enabled |= SOFT_WATCHDOG_ENABLED; } - #ifdef CONFIG_SOFTLOCKUP_DETECTOR -/* Helper for online, unparked cpus. */ -#define for_each_watchdog_cpu(cpu) \ - for_each_cpu_and((cpu), cpu_online_mask, &watchdog_cpumask) - -atomic_t watchdog_park_in_progress = ATOMIC_INIT(0); +/* Global variables, exported for sysctl */ +unsigned int __read_mostly softlockup_panic = + CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; +static bool softlockup_threads_initialized __read_mostly; static u64 __read_mostly sample_period; static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); @@ -164,50 +181,40 @@ static DEFINE_PER_CPU(struct task_struct *, softlockup_task_ptr_saved); static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); static unsigned long soft_lockup_nmi_warn; -unsigned int __read_mostly softlockup_panic = - CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; - static int __init softlockup_panic_setup(char *str) { softlockup_panic = simple_strtoul(str, NULL, 0); - return 1; } __setup("softlockup_panic=", softlockup_panic_setup); static int __init nowatchdog_setup(char *str) { - watchdog_enabled = 0; + watchdog_user_enabled = 0; return 1; } __setup("nowatchdog", nowatchdog_setup); static int __init nosoftlockup_setup(char *str) { - watchdog_enabled &= ~SOFT_WATCHDOG_ENABLED; + soft_watchdog_user_enabled = 0; return 1; } __setup("nosoftlockup", nosoftlockup_setup); #ifdef CONFIG_SMP +int __read_mostly sysctl_softlockup_all_cpu_backtrace; + static int __init softlockup_all_cpu_backtrace_setup(char *str) { - sysctl_softlockup_all_cpu_backtrace = - !!simple_strtol(str, NULL, 0); + sysctl_softlockup_all_cpu_backtrace = !!simple_strtol(str, NULL, 0); return 1; } __setup("softlockup_all_cpu_backtrace=", softlockup_all_cpu_backtrace_setup); -#ifdef CONFIG_HARDLOCKUP_DETECTOR -static int __init hardlockup_all_cpu_backtrace_setup(char *str) -{ - sysctl_hardlockup_all_cpu_backtrace = - !!simple_strtol(str, NULL, 0); - return 1; -} -__setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup); -#endif #endif +static void __lockup_detector_cleanup(void); + /* * Hard-lockup warnings should be triggered after just a few seconds. Soft- * lockups can have false positives under extreme conditions. So we generally @@ -240,6 +247,7 @@ static void set_sample_period(void) * hardlockup detector generates a warning */ sample_period = get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5); + watchdog_update_hrtimer_threshold(sample_period); } /* Commands for resetting the watchdog */ @@ -277,11 +285,15 @@ void touch_all_softlockup_watchdogs(void) int cpu; /* - * this is done lockless - * do we care if a 0 races with a timestamp? - * all it means is the softlock check starts one cycle later + * watchdog_mutex cannpt be taken here, as this might be called + * from (soft)interrupt context, so the access to + * watchdog_allowed_cpumask might race with a concurrent update. + * + * The watchdog time stamp can race against a concurrent real + * update as well, the only side effect might be a cycle delay for + * the softlockup check. */ - for_each_watchdog_cpu(cpu) + for_each_cpu(cpu, &watchdog_allowed_mask) per_cpu(watchdog_touch_ts, cpu) = 0; wq_watchdog_touch(-1); } @@ -321,9 +333,6 @@ static void watchdog_interrupt_count(void) __this_cpu_inc(hrtimer_interrupts); } -static int watchdog_enable_all_cpus(void); -static void watchdog_disable_all_cpus(void); - /* watchdog kicker functions */ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) { @@ -332,7 +341,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) int duration; int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace; - if (atomic_read(&watchdog_park_in_progress) != 0) + if (!watchdog_enabled) return HRTIMER_NORESTART; /* kick the hardlockup detector */ @@ -446,32 +455,38 @@ static void watchdog_set_prio(unsigned int policy, unsigned int prio) static void watchdog_enable(unsigned int cpu) { - struct hrtimer *hrtimer = raw_cpu_ptr(&watchdog_hrtimer); + struct hrtimer *hrtimer = this_cpu_ptr(&watchdog_hrtimer); - /* kick off the timer for the hardlockup detector */ + /* + * Start the timer first to prevent the NMI watchdog triggering + * before the timer has a chance to fire. + */ hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer->function = watchdog_timer_fn; - - /* Enable the perf event */ - watchdog_nmi_enable(cpu); - - /* done here because hrtimer_start can only pin to smp_processor_id() */ hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL_PINNED); - /* initialize timestamp */ - watchdog_set_prio(SCHED_FIFO, MAX_RT_PRIO - 1); + /* Initialize timestamp */ __touch_watchdog(); + /* Enable the perf event */ + if (watchdog_enabled & NMI_WATCHDOG_ENABLED) + watchdog_nmi_enable(cpu); + + watchdog_set_prio(SCHED_FIFO, MAX_RT_PRIO - 1); } static void watchdog_disable(unsigned int cpu) { - struct hrtimer *hrtimer = raw_cpu_ptr(&watchdog_hrtimer); + struct hrtimer *hrtimer = this_cpu_ptr(&watchdog_hrtimer); watchdog_set_prio(SCHED_NORMAL, 0); - hrtimer_cancel(hrtimer); - /* disable the perf event */ + /* + * Disable the perf event first. That prevents that a large delay + * between disabling the timer and disabling the perf event causes + * the perf NMI to detect a false positive. + */ watchdog_nmi_disable(cpu); + hrtimer_cancel(hrtimer); } static void watchdog_cleanup(unsigned int cpu, bool online) @@ -498,21 +513,6 @@ static void watchdog(unsigned int cpu) __this_cpu_write(soft_lockup_hrtimer_cnt, __this_cpu_read(hrtimer_interrupts)); __touch_watchdog(); - - /* - * watchdog_nmi_enable() clears the NMI_WATCHDOG_ENABLED bit in the - * failure path. Check for failures that can occur asynchronously - - * for example, when CPUs are on-lined - and shut down the hardware - * perf event on each CPU accordingly. - * - * The only non-obvious place this bit can be cleared is through - * watchdog_nmi_enable(), so a pr_info() is placed there. Placing a - * pr_info here would be too noisy as it would result in a message - * every few seconds if the hardlockup was disabled but the softlockup - * enabled. - */ - if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) - watchdog_nmi_disable(cpu); } static struct smp_hotplug_thread watchdog_threads = { @@ -526,295 +526,174 @@ static struct smp_hotplug_thread watchdog_threads = { .unpark = watchdog_enable, }; -/* - * park all watchdog threads that are specified in 'watchdog_cpumask' - * - * This function returns an error if kthread_park() of a watchdog thread - * fails. In this situation, the watchdog threads of some CPUs can already - * be parked and the watchdog threads of other CPUs can still be runnable. - * Callers are expected to handle this special condition as appropriate in - * their context. - * - * This function may only be called in a context that is protected against - * races with CPU hotplug - for example, via get_online_cpus(). - */ -static int watchdog_park_threads(void) +static void softlockup_update_smpboot_threads(void) { - int cpu, ret = 0; + lockdep_assert_held(&watchdog_mutex); - atomic_set(&watchdog_park_in_progress, 1); + if (!softlockup_threads_initialized) + return; - for_each_watchdog_cpu(cpu) { - ret = kthread_park(per_cpu(softlockup_watchdog, cpu)); - if (ret) - break; - } - - atomic_set(&watchdog_park_in_progress, 0); - - return ret; + smpboot_update_cpumask_percpu_thread(&watchdog_threads, + &watchdog_allowed_mask); } -/* - * unpark all watchdog threads that are specified in 'watchdog_cpumask' - * - * This function may only be called in a context that is protected against - * races with CPU hotplug - for example, via get_online_cpus(). - */ -static void watchdog_unpark_threads(void) +/* Temporarily park all watchdog threads */ +static void softlockup_park_all_threads(void) { - int cpu; - - for_each_watchdog_cpu(cpu) - kthread_unpark(per_cpu(softlockup_watchdog, cpu)); + cpumask_clear(&watchdog_allowed_mask); + softlockup_update_smpboot_threads(); } -static int update_watchdog_all_cpus(void) +/* Unpark enabled threads */ +static void softlockup_unpark_threads(void) { - int ret; - - ret = watchdog_park_threads(); - if (ret) - return ret; - - watchdog_unpark_threads(); - - return 0; + cpumask_copy(&watchdog_allowed_mask, &watchdog_cpumask); + softlockup_update_smpboot_threads(); } -static int watchdog_enable_all_cpus(void) +static void lockup_detector_reconfigure(void) { - int err = 0; - - if (!watchdog_running) { - err = smpboot_register_percpu_thread_cpumask(&watchdog_threads, - &watchdog_cpumask); - if (err) - pr_err("Failed to create watchdog threads, disabled\n"); - else - watchdog_running = 1; - } else { - /* - * Enable/disable the lockup detectors or - * change the sample period 'on the fly'. - */ - err = update_watchdog_all_cpus(); - - if (err) { - watchdog_disable_all_cpus(); - pr_err("Failed to update lockup detectors, disabled\n"); - } - } - - if (err) - watchdog_enabled = 0; - - return err; + cpus_read_lock(); + watchdog_nmi_stop(); + softlockup_park_all_threads(); + set_sample_period(); + lockup_detector_update_enable(); + if (watchdog_enabled && watchdog_thresh) + softlockup_unpark_threads(); + watchdog_nmi_start(); + cpus_read_unlock(); + /* + * Must be called outside the cpus locked section to prevent + * recursive locking in the perf code. + */ + __lockup_detector_cleanup(); } -static void watchdog_disable_all_cpus(void) +/* + * Create the watchdog thread infrastructure and configure the detector(s). + * + * The threads are not unparked as watchdog_allowed_mask is empty. When + * the threads are sucessfully initialized, take the proper locks and + * unpark the threads in the watchdog_cpumask if the watchdog is enabled. + */ +static __init void lockup_detector_setup(void) { - if (watchdog_running) { - watchdog_running = 0; - smpboot_unregister_percpu_thread(&watchdog_threads); - } -} + int ret; -#ifdef CONFIG_SYSCTL -static int watchdog_update_cpus(void) -{ - return smpboot_update_cpumask_percpu_thread( - &watchdog_threads, &watchdog_cpumask); -} -#endif + /* + * If sysctl is off and watchdog got disabled on the command line, + * nothing to do here. + */ + lockup_detector_update_enable(); -#else /* SOFTLOCKUP */ -static int watchdog_park_threads(void) -{ - return 0; -} + if (!IS_ENABLED(CONFIG_SYSCTL) && + !(watchdog_enabled && watchdog_thresh)) + return; -static void watchdog_unpark_threads(void) -{ -} + ret = smpboot_register_percpu_thread_cpumask(&watchdog_threads, + &watchdog_allowed_mask); + if (ret) { + pr_err("Failed to initialize soft lockup detector threads\n"); + return; + } -static int watchdog_enable_all_cpus(void) -{ - return 0; + mutex_lock(&watchdog_mutex); + softlockup_threads_initialized = true; + lockup_detector_reconfigure(); + mutex_unlock(&watchdog_mutex); } -static void watchdog_disable_all_cpus(void) +#else /* CONFIG_SOFTLOCKUP_DETECTOR */ +static inline int watchdog_park_threads(void) { return 0; } +static inline void watchdog_unpark_threads(void) { } +static inline int watchdog_enable_all_cpus(void) { return 0; } +static inline void watchdog_disable_all_cpus(void) { } +static void lockup_detector_reconfigure(void) { + cpus_read_lock(); + watchdog_nmi_stop(); + lockup_detector_update_enable(); + watchdog_nmi_start(); + cpus_read_unlock(); } - -#ifdef CONFIG_SYSCTL -static int watchdog_update_cpus(void) +static inline void lockup_detector_setup(void) { - return 0; + lockup_detector_reconfigure(); } -#endif +#endif /* !CONFIG_SOFTLOCKUP_DETECTOR */ -static void set_sample_period(void) +static void __lockup_detector_cleanup(void) { + lockdep_assert_held(&watchdog_mutex); + hardlockup_detector_perf_cleanup(); } -#endif /* SOFTLOCKUP */ -/* - * Suspend the hard and soft lockup detector by parking the watchdog threads. +/** + * lockup_detector_cleanup - Cleanup after cpu hotplug or sysctl changes + * + * Caller must not hold the cpu hotplug rwsem. */ -int lockup_detector_suspend(void) +void lockup_detector_cleanup(void) { - int ret = 0; - - get_online_cpus(); - mutex_lock(&watchdog_proc_mutex); - /* - * Multiple suspend requests can be active in parallel (counted by - * the 'watchdog_suspended' variable). If the watchdog threads are - * running, the first caller takes care that they will be parked. - * The state of 'watchdog_running' cannot change while a suspend - * request is active (see related code in 'proc' handlers). - */ - if (watchdog_running && !watchdog_suspended) - ret = watchdog_park_threads(); - - if (ret == 0) - watchdog_suspended++; - else { - watchdog_disable_all_cpus(); - pr_err("Failed to suspend lockup detectors, disabled\n"); - watchdog_enabled = 0; - } - - watchdog_nmi_reconfigure(); - - mutex_unlock(&watchdog_proc_mutex); - - return ret; + mutex_lock(&watchdog_mutex); + __lockup_detector_cleanup(); + mutex_unlock(&watchdog_mutex); } -/* - * Resume the hard and soft lockup detector by unparking the watchdog threads. +/** + * lockup_detector_soft_poweroff - Interface to stop lockup detector(s) + * + * Special interface for parisc. It prevents lockup detector warnings from + * the default pm_poweroff() function which busy loops forever. */ -void lockup_detector_resume(void) +void lockup_detector_soft_poweroff(void) { - mutex_lock(&watchdog_proc_mutex); - - watchdog_suspended--; - /* - * The watchdog threads are unparked if they were previously running - * and if there is no more active suspend request. - */ - if (watchdog_running && !watchdog_suspended) - watchdog_unpark_threads(); - - watchdog_nmi_reconfigure(); - - mutex_unlock(&watchdog_proc_mutex); - put_online_cpus(); + watchdog_enabled = 0; } #ifdef CONFIG_SYSCTL -/* - * Update the run state of the lockup detectors. - */ -static int proc_watchdog_update(void) +/* Propagate any changes to the watchdog threads */ +static void proc_watchdog_update(void) { - int err = 0; - - /* - * Watchdog threads won't be started if they are already active. - * The 'watchdog_running' variable in watchdog_*_all_cpus() takes - * care of this. If those threads are already active, the sample - * period will be updated and the lockup detectors will be enabled - * or disabled 'on the fly'. - */ - if (watchdog_enabled && watchdog_thresh) - err = watchdog_enable_all_cpus(); - else - watchdog_disable_all_cpus(); - - watchdog_nmi_reconfigure(); - - return err; - + /* Remove impossible cpus to keep sysctl output clean. */ + cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask); + lockup_detector_reconfigure(); } /* * common function for watchdog, nmi_watchdog and soft_watchdog parameter * - * caller | table->data points to | 'which' contains the flag(s) - * -------------------|-----------------------|----------------------------- - * proc_watchdog | watchdog_user_enabled | NMI_WATCHDOG_ENABLED or'ed - * | | with SOFT_WATCHDOG_ENABLED - * -------------------|-----------------------|----------------------------- - * proc_nmi_watchdog | nmi_watchdog_enabled | NMI_WATCHDOG_ENABLED - * -------------------|-----------------------|----------------------------- - * proc_soft_watchdog | soft_watchdog_enabled | SOFT_WATCHDOG_ENABLED + * caller | table->data points to | 'which' + * -------------------|----------------------------|-------------------------- + * proc_watchdog | watchdog_user_enabled | NMI_WATCHDOG_ENABLED | + * | | SOFT_WATCHDOG_ENABLED + * -------------------|----------------------------|-------------------------- + * proc_nmi_watchdog | nmi_watchdog_user_enabled | NMI_WATCHDOG_ENABLED + * -------------------|----------------------------|-------------------------- + * proc_soft_watchdog | soft_watchdog_user_enabled | SOFT_WATCHDOG_ENABLED */ static int proc_watchdog_common(int which, struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int err, old, new; - int *watchdog_param = (int *)table->data; + int err, old, *param = table->data; - get_online_cpus(); - mutex_lock(&watchdog_proc_mutex); + mutex_lock(&watchdog_mutex); - if (watchdog_suspended) { - /* no parameter changes allowed while watchdog is suspended */ - err = -EAGAIN; - goto out; - } - - /* - * If the parameter is being read return the state of the corresponding - * bit(s) in 'watchdog_enabled', else update 'watchdog_enabled' and the - * run state of the lockup detectors. - */ if (!write) { - *watchdog_param = (watchdog_enabled & which) != 0; + /* + * On read synchronize the userspace interface. This is a + * racy snapshot. + */ + *param = (watchdog_enabled & which) != 0; err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); } else { + old = READ_ONCE(*param); err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (err) - goto out; - - /* - * There is a race window between fetching the current value - * from 'watchdog_enabled' and storing the new value. During - * this race window, watchdog_nmi_enable() can sneak in and - * clear the NMI_WATCHDOG_ENABLED bit in 'watchdog_enabled'. - * The 'cmpxchg' detects this race and the loop retries. - */ - do { - old = watchdog_enabled; - /* - * If the parameter value is not zero set the - * corresponding bit(s), else clear it(them). - */ - if (*watchdog_param) - new = old | which; - else - new = old & ~which; - } while (cmpxchg(&watchdog_enabled, old, new) != old); - - /* - * Update the run state of the lockup detectors. There is _no_ - * need to check the value returned by proc_watchdog_update() - * and to restore the previous value of 'watchdog_enabled' as - * both lockup detectors are disabled if proc_watchdog_update() - * returns an error. - */ - if (old == new) - goto out; - - err = proc_watchdog_update(); + if (!err && old != READ_ONCE(*param)) + proc_watchdog_update(); } -out: - mutex_unlock(&watchdog_proc_mutex); - put_online_cpus(); + mutex_unlock(&watchdog_mutex); return err; } @@ -834,6 +713,8 @@ int proc_watchdog(struct ctl_table *table, int write, int proc_nmi_watchdog(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { + if (!nmi_watchdog_available && write) + return -ENOTSUPP; return proc_watchdog_common(NMI_WATCHDOG_ENABLED, table, write, buffer, lenp, ppos); } @@ -854,39 +735,17 @@ int proc_soft_watchdog(struct ctl_table *table, int write, int proc_watchdog_thresh(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int err, old, new; - - get_online_cpus(); - mutex_lock(&watchdog_proc_mutex); + int err, old; - if (watchdog_suspended) { - /* no parameter changes allowed while watchdog is suspended */ - err = -EAGAIN; - goto out; - } + mutex_lock(&watchdog_mutex); - old = ACCESS_ONCE(watchdog_thresh); + old = READ_ONCE(watchdog_thresh); err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (err || !write) - goto out; - - /* - * Update the sample period. Restore on failure. - */ - new = ACCESS_ONCE(watchdog_thresh); - if (old == new) - goto out; + if (!err && write && old != READ_ONCE(watchdog_thresh)) + proc_watchdog_update(); - set_sample_period(); - err = proc_watchdog_update(); - if (err) { - watchdog_thresh = old; - set_sample_period(); - } -out: - mutex_unlock(&watchdog_proc_mutex); - put_online_cpus(); + mutex_unlock(&watchdog_mutex); return err; } @@ -901,45 +760,19 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write, { int err; - get_online_cpus(); - mutex_lock(&watchdog_proc_mutex); - - if (watchdog_suspended) { - /* no parameter changes allowed while watchdog is suspended */ - err = -EAGAIN; - goto out; - } + mutex_lock(&watchdog_mutex); err = proc_do_large_bitmap(table, write, buffer, lenp, ppos); - if (!err && write) { - /* Remove impossible cpus to keep sysctl output cleaner. */ - cpumask_and(&watchdog_cpumask, &watchdog_cpumask, - cpu_possible_mask); - - if (watchdog_running) { - /* - * Failure would be due to being unable to allocate - * a temporary cpumask, so we are likely not in a - * position to do much else to make things better. - */ - if (watchdog_update_cpus() != 0) - pr_err("cpumask update failed\n"); - } + if (!err && write) + proc_watchdog_update(); - watchdog_nmi_reconfigure(); - } -out: - mutex_unlock(&watchdog_proc_mutex); - put_online_cpus(); + mutex_unlock(&watchdog_mutex); return err; } - #endif /* CONFIG_SYSCTL */ void __init lockup_detector_init(void) { - set_sample_period(); - #ifdef CONFIG_NO_HZ_FULL if (tick_nohz_full_enabled()) { pr_info("Disabling watchdog on nohz_full cores by default\n"); @@ -950,6 +783,7 @@ void __init lockup_detector_init(void) cpumask_copy(&watchdog_cpumask, cpu_possible_mask); #endif - if (watchdog_enabled) - watchdog_enable_all_cpus(); + if (!watchdog_nmi_probe()) + nmi_watchdog_available = true; + lockup_detector_setup(); } diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c index 295a0d84934cb1d3a9a87abd4a8ac0f1d38656a5..71a62ceacdc883aa77a711e4b1bfba8c3185dceb 100644 --- a/kernel/watchdog_hld.c +++ b/kernel/watchdog_hld.c @@ -21,8 +21,10 @@ static DEFINE_PER_CPU(bool, hard_watchdog_warn); static DEFINE_PER_CPU(bool, watchdog_nmi_touch); static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); +static struct cpumask dead_events_mask; static unsigned long hardlockup_allcpu_dumped; +static unsigned int watchdog_cpus; void arch_touch_nmi_watchdog(void) { @@ -37,6 +39,62 @@ void arch_touch_nmi_watchdog(void) } EXPORT_SYMBOL(arch_touch_nmi_watchdog); +#ifdef CONFIG_HARDLOCKUP_CHECK_TIMESTAMP +static DEFINE_PER_CPU(ktime_t, last_timestamp); +static DEFINE_PER_CPU(unsigned int, nmi_rearmed); +static ktime_t watchdog_hrtimer_sample_threshold __read_mostly; + +void watchdog_update_hrtimer_threshold(u64 period) +{ + /* + * The hrtimer runs with a period of (watchdog_threshold * 2) / 5 + * + * So it runs effectively with 2.5 times the rate of the NMI + * watchdog. That means the hrtimer should fire 2-3 times before + * the NMI watchdog expires. The NMI watchdog on x86 is based on + * unhalted CPU cycles, so if Turbo-Mode is enabled the CPU cycles + * might run way faster than expected and the NMI fires in a + * smaller period than the one deduced from the nominal CPU + * frequency. Depending on the Turbo-Mode factor this might be fast + * enough to get the NMI period smaller than the hrtimer watchdog + * period and trigger false positives. + * + * The sample threshold is used to check in the NMI handler whether + * the minimum time between two NMI samples has elapsed. That + * prevents false positives. + * + * Set this to 4/5 of the actual watchdog threshold period so the + * hrtimer is guaranteed to fire at least once within the real + * watchdog threshold. + */ + watchdog_hrtimer_sample_threshold = period * 2; +} + +static bool watchdog_check_timestamp(void) +{ + ktime_t delta, now = ktime_get_mono_fast_ns(); + + delta = now - __this_cpu_read(last_timestamp); + if (delta < watchdog_hrtimer_sample_threshold) { + /* + * If ktime is jiffies based, a stalled timer would prevent + * jiffies from being incremented and the filter would look + * at a stale timestamp and never trigger. + */ + if (__this_cpu_inc_return(nmi_rearmed) < 10) + return false; + } + __this_cpu_write(nmi_rearmed, 0); + __this_cpu_write(last_timestamp, now); + return true; +} +#else +static inline bool watchdog_check_timestamp(void) +{ + return true; +} +#endif + static struct perf_event_attr wd_hw_attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, @@ -47,20 +105,20 @@ static struct perf_event_attr wd_hw_attr = { /* Callback function for perf event subsystem */ static void watchdog_overflow_callback(struct perf_event *event, - struct perf_sample_data *data, - struct pt_regs *regs) + struct perf_sample_data *data, + struct pt_regs *regs) { /* Ensure the watchdog never gets throttled */ event->hw.interrupts = 0; - if (atomic_read(&watchdog_park_in_progress) != 0) - return; - if (__this_cpu_read(watchdog_nmi_touch) == true) { __this_cpu_write(watchdog_nmi_touch, false); return; } + if (!watchdog_check_timestamp()) + return; + /* check for a hardlockup * This is done by making sure our timer interrupt * is incrementing. The timer interrupt should have @@ -101,104 +159,131 @@ static void watchdog_overflow_callback(struct perf_event *event, return; } -/* - * People like the simple clean cpu node info on boot. - * Reduce the watchdog noise by only printing messages - * that are different from what cpu0 displayed. - */ -static unsigned long firstcpu_err; -static atomic_t watchdog_cpus; - -int watchdog_nmi_enable(unsigned int cpu) +static int hardlockup_detector_event_create(void) { + unsigned int cpu = smp_processor_id(); struct perf_event_attr *wd_attr; - struct perf_event *event = per_cpu(watchdog_ev, cpu); - int firstcpu = 0; - - /* nothing to do if the hard lockup detector is disabled */ - if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) - goto out; - - /* is it already setup and enabled? */ - if (event && event->state > PERF_EVENT_STATE_OFF) - goto out; - - /* it is setup but not enabled */ - if (event != NULL) - goto out_enable; - - if (atomic_inc_return(&watchdog_cpus) == 1) - firstcpu = 1; + struct perf_event *evt; wd_attr = &wd_hw_attr; wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); /* Try to register using hardware perf events */ - event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); + evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL, + watchdog_overflow_callback, NULL); + if (IS_ERR(evt)) { + pr_info("Perf event create on CPU %d failed with %ld\n", cpu, + PTR_ERR(evt)); + return PTR_ERR(evt); + } + this_cpu_write(watchdog_ev, evt); + return 0; +} - /* save the first cpu's error for future comparision */ - if (firstcpu && IS_ERR(event)) - firstcpu_err = PTR_ERR(event); +/** + * hardlockup_detector_perf_enable - Enable the local event + */ +void hardlockup_detector_perf_enable(void) +{ + if (hardlockup_detector_event_create()) + return; - if (!IS_ERR(event)) { - /* only print for the first cpu initialized */ - if (firstcpu || firstcpu_err) - pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n"); - goto out_save; - } + if (!watchdog_cpus++) + pr_info("Enabled. Permanently consumes one hw-PMU counter.\n"); - /* - * Disable the hard lockup detector if _any_ CPU fails to set up - * set up the hardware perf event. The watchdog() function checks - * the NMI_WATCHDOG_ENABLED bit periodically. - * - * The barriers are for syncing up watchdog_enabled across all the - * cpus, as clear_bit() does not use barriers. - */ - smp_mb__before_atomic(); - clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled); - smp_mb__after_atomic(); - - /* skip displaying the same error again */ - if (!firstcpu && (PTR_ERR(event) == firstcpu_err)) - return PTR_ERR(event); - - /* vary the KERN level based on the returned errno */ - if (PTR_ERR(event) == -EOPNOTSUPP) - pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu); - else if (PTR_ERR(event) == -ENOENT) - pr_warn("disabled (cpu%i): hardware events not enabled\n", - cpu); - else - pr_err("disabled (cpu%i): unable to create perf event: %ld\n", - cpu, PTR_ERR(event)); - - pr_info("Shutting down hard lockup detector on all cpus\n"); - - return PTR_ERR(event); - - /* success path */ -out_save: - per_cpu(watchdog_ev, cpu) = event; -out_enable: - perf_event_enable(per_cpu(watchdog_ev, cpu)); -out: - return 0; + perf_event_enable(this_cpu_read(watchdog_ev)); } -void watchdog_nmi_disable(unsigned int cpu) +/** + * hardlockup_detector_perf_disable - Disable the local event + */ +void hardlockup_detector_perf_disable(void) { - struct perf_event *event = per_cpu(watchdog_ev, cpu); + struct perf_event *event = this_cpu_read(watchdog_ev); if (event) { perf_event_disable(event); + cpumask_set_cpu(smp_processor_id(), &dead_events_mask); + watchdog_cpus--; + } +} + +/** + * hardlockup_detector_perf_cleanup - Cleanup disabled events and destroy them + * + * Called from lockup_detector_cleanup(). Serialized by the caller. + */ +void hardlockup_detector_perf_cleanup(void) +{ + int cpu; + + for_each_cpu(cpu, &dead_events_mask) { + struct perf_event *event = per_cpu(watchdog_ev, cpu); + + /* + * Required because for_each_cpu() reports unconditionally + * CPU0 as set on UP kernels. Sigh. + */ + if (event) + perf_event_release_kernel(event); per_cpu(watchdog_ev, cpu) = NULL; + } + cpumask_clear(&dead_events_mask); +} + +/** + * hardlockup_detector_perf_stop - Globally stop watchdog events + * + * Special interface for x86 to handle the perf HT bug. + */ +void __init hardlockup_detector_perf_stop(void) +{ + int cpu; - /* should be in cleanup, but blocks oprofile */ - perf_event_release_kernel(event); + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) { + struct perf_event *event = per_cpu(watchdog_ev, cpu); + + if (event) + perf_event_disable(event); + } +} + +/** + * hardlockup_detector_perf_restart - Globally restart watchdog events + * + * Special interface for x86 to handle the perf HT bug. + */ +void __init hardlockup_detector_perf_restart(void) +{ + int cpu; + + lockdep_assert_cpus_held(); + + if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) + return; + + for_each_online_cpu(cpu) { + struct perf_event *event = per_cpu(watchdog_ev, cpu); + + if (event) + perf_event_enable(event); + } +} + +/** + * hardlockup_detector_perf_init - Probe whether NMI event is available at all + */ +int __init hardlockup_detector_perf_init(void) +{ + int ret = hardlockup_detector_event_create(); - /* watchdog_nmi_enable() expects this to be zero initially. */ - if (atomic_dec_and_test(&watchdog_cpus)) - firstcpu_err = 0; + if (ret) { + pr_info("Perf NMI watchdog permanently disabled\n"); + } else { + perf_event_release_kernel(this_cpu_read(watchdog_ev)); + this_cpu_write(watchdog_ev, NULL); } + return ret; } diff --git a/kernel/workqueue.c b/kernel/workqueue.c index a86688fabc55c4a4ec2bad843f6dc1e0e411f2d1..64d0edf428f850f2e5cfed94970cb74491eb6b61 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -21,7 +21,7 @@ * pools for workqueues which are not bound to any specific CPU - the * number of these backing pools is dynamic. * - * Please read Documentation/workqueue.txt for details. + * Please read Documentation/core-api/workqueue.rst for details. */ #include @@ -2091,8 +2091,30 @@ __acquires(&pool->lock) spin_unlock_irq(&pool->lock); - lock_map_acquire_read(&pwq->wq->lockdep_map); + lock_map_acquire(&pwq->wq->lockdep_map); lock_map_acquire(&lockdep_map); + /* + * Strictly speaking we should mark the invariant state without holding + * any locks, that is, before these two lock_map_acquire()'s. + * + * However, that would result in: + * + * A(W1) + * WFC(C) + * A(W1) + * C(C) + * + * Which would create W1->C->W1 dependencies, even though there is no + * actual deadlock possible. There are two solutions, using a + * read-recursive acquire on the work(queue) 'locks', but this will then + * hit the lockdep limitation on recursive locks, or simply discard + * these locks. + * + * AFAICT there is no possible deadlock scenario between the + * flush_work() and complete() primitives (except for single-threaded + * workqueues), so hiding them isn't a problem. + */ + lockdep_invariant_state(true); trace_workqueue_execute_start(work); worker->current_func(work); /* @@ -2247,7 +2269,7 @@ static int worker_thread(void *__worker) * event. */ worker_enter_idle(worker); - __set_current_state(TASK_INTERRUPTIBLE); + __set_current_state(TASK_IDLE); spin_unlock_irq(&pool->lock); schedule(); goto woke_up; @@ -2289,7 +2311,7 @@ static int rescuer_thread(void *__rescuer) */ rescuer->task->flags |= PF_WQ_WORKER; repeat: - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_IDLE); /* * By the time the rescuer is requested to stop, the workqueue @@ -2474,7 +2496,16 @@ static void insert_wq_barrier(struct pool_workqueue *pwq, */ INIT_WORK_ONSTACK(&barr->work, wq_barrier_func); __set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work)); - init_completion(&barr->done); + + /* + * Explicitly init the crosslock for wq_barrier::done, make its lock + * key a subkey of the corresponding work. As a result we won't + * build a dependency between wq_barrier::done and unrelated work. + */ + lockdep_init_map_crosslock((struct lockdep_map *)&barr->done.map, + "(complete)wq_barr::done", + target->lockdep_map.key, 1); + __init_completion(&barr->done); barr->task = current; /* @@ -2815,16 +2846,18 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr) spin_unlock_irq(&pool->lock); /* - * If @max_active is 1 or rescuer is in use, flushing another work - * item on the same workqueue may lead to deadlock. Make sure the - * flusher is not running on the same workqueue by verifying write - * access. + * Force a lock recursion deadlock when using flush_work() inside a + * single-threaded or rescuer equipped workqueue. + * + * For single threaded workqueues the deadlock happens when the work + * is after the work issuing the flush_work(). For rescuer equipped + * workqueues the deadlock happens when the rescuer stalls, blocking + * forward progress. */ - if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) + if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) { lock_map_acquire(&pwq->wq->lockdep_map); - else - lock_map_acquire_read(&pwq->wq->lockdep_map); - lock_map_release(&pwq->wq->lockdep_map); + lock_map_release(&pwq->wq->lockdep_map); + } return true; already_gone: @@ -3577,6 +3610,13 @@ static bool wq_calc_node_cpumask(const struct workqueue_attrs *attrs, int node, /* yeap, return possible CPUs in @node that @attrs wants */ cpumask_and(cpumask, attrs->cpumask, wq_numa_possible_cpumask[node]); + + if (cpumask_empty(cpumask)) { + pr_warn_once("WARNING: workqueue cpumask: online intersect > " + "possible intersect\n"); + return false; + } + return !cpumask_equal(cpumask, attrs->cpumask); use_dfl: @@ -3744,8 +3784,12 @@ static int apply_workqueue_attrs_locked(struct workqueue_struct *wq, return -EINVAL; /* creating multiple pwqs breaks ordering guarantee */ - if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs))) - return -EINVAL; + if (!list_empty(&wq->pwqs)) { + if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT)) + return -EINVAL; + + wq->flags &= ~__WQ_ORDERED; + } ctx = apply_wqattrs_prepare(wq, attrs); if (!ctx) @@ -3929,6 +3973,16 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, struct workqueue_struct *wq; struct pool_workqueue *pwq; + /* + * Unbound && max_active == 1 used to imply ordered, which is no + * longer the case on NUMA machines due to per-node pools. While + * alloc_ordered_workqueue() is the right way to create an ordered + * workqueue, keep the previous behavior to avoid subtle breakages + * on NUMA. + */ + if ((flags & WQ_UNBOUND) && max_active == 1) + flags |= __WQ_ORDERED; + /* see the comment above the definition of WQ_POWER_EFFICIENT */ if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient) flags |= WQ_UNBOUND; @@ -4119,13 +4173,14 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) struct pool_workqueue *pwq; /* disallow meddling with max_active for ordered workqueues */ - if (WARN_ON(wq->flags & __WQ_ORDERED)) + if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT)) return; max_active = wq_clamp_max_active(max_active, wq->flags, wq->name); mutex_lock(&wq->mutex); + wq->flags &= ~__WQ_ORDERED; wq->saved_max_active = max_active; for_each_pwq(pwq, wq) @@ -5253,7 +5308,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq) * attributes breaks ordering guarantee. Disallow exposing ordered * workqueues. */ - if (WARN_ON(wq->flags & __WQ_ORDERED)) + if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT)) return -EINVAL; wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL); diff --git a/lib/Kconfig b/lib/Kconfig index 6762529ad9e4597f473a07e9300bd0ac8a601c10..b1445b22a6def496d91bde16deb2b13a01a52915 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -192,6 +192,9 @@ config CRC8 when they need to do cyclic redundancy check according CRC8 algorithm. Module will be called crc8. +config XXHASH + tristate + config AUDIT_GENERIC bool depends on AUDIT && !AUDIT_ARCH @@ -246,6 +249,14 @@ config LZ4HC_COMPRESS config LZ4_DECOMPRESS tristate +config ZSTD_COMPRESS + select XXHASH + tristate + +config ZSTD_DECOMPRESS + select XXHASH + tristate + source "lib/xz/Kconfig" # @@ -559,9 +570,6 @@ config ARCH_HAS_PMEM_API config ARCH_HAS_UACCESS_FLUSHCACHE bool -config ARCH_HAS_MMIO_FLUSH - bool - config STACKDEPOT bool select STACKTRACE @@ -575,4 +583,7 @@ config PARMAN config PRIME_NUMBERS tristate +config STRING_SELFTEST + bool "Test string functions" + endmenu diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 98fe715522e8d1834083e608d32a78ed0600deb9..2689b7c50c52992623cc8d7e65df03bffc8798d3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -219,7 +219,8 @@ config FRAME_WARN range 0 8192 default 0 if KASAN default 2048 if GCC_PLUGIN_LATENT_ENTROPY - default 1024 if !64BIT + default 1280 if (!64BIT && PARISC) + default 1024 if (!64BIT && !PARISC) default 2048 if 64BIT help Tell gcc to warn at build time for stack frames larger than this. @@ -374,6 +375,9 @@ config STACK_VALIDATION pointers (if CONFIG_FRAME_POINTER is enabled). This helps ensure that runtime stack traces are more reliable. + This is also a prerequisite for generation of ORC unwind data, which + is needed for CONFIG_ORC_UNWINDER. + For more information, see tools/objtool/Documentation/stack-validation.txt. @@ -797,6 +801,13 @@ config HARDLOCKUP_DETECTOR_PERF bool select SOFTLOCKUP_DETECTOR +# +# Enables a timestamp based low pass filter to compensate for perf based +# hard lockup detection which runs too fast due to turbo modes. +# +config HARDLOCKUP_CHECK_TIMESTAMP + bool + # # arch/ can define HAVE_HARDLOCKUP_DETECTOR_ARCH to provide their own hard # lockup detector rather than the perf based detector. @@ -1081,6 +1092,8 @@ config PROVE_LOCKING select DEBUG_MUTEXES select DEBUG_RT_MUTEXES if RT_MUTEXES select DEBUG_LOCK_ALLOC + select LOCKDEP_CROSSRELEASE + select LOCKDEP_COMPLETIONS select TRACE_IRQFLAGS default n help @@ -1121,7 +1134,7 @@ config LOCKDEP bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE + select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE && !X86 select KALLSYMS select KALLSYMS_ALL @@ -1150,6 +1163,22 @@ config LOCK_STAT CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. (CONFIG_LOCKDEP defines "acquire" and "release" events.) +config LOCKDEP_CROSSRELEASE + bool + help + This makes lockdep work for crosslock which is a lock allowed to + be released in a different context from the acquisition context. + Normally a lock must be released in the context acquiring the lock. + However, relexing this constraint helps synchronization primitives + such as page locks or completions can use the lock correctness + detector, lockdep. + +config LOCKDEP_COMPLETIONS + bool + help + A deadlock caused by wait_for_completion() and complete() can be + detected by lockdep using crossrelease feature. + config DEBUG_LOCKDEP bool "Lock dependency engine debugging" depends on DEBUG_KERNEL && LOCKDEP @@ -1540,7 +1569,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT depends on !X86_64 select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE && !X86 help Provide stacktrace filter for fault-injection capabilities @@ -1549,7 +1578,7 @@ config LATENCYTOP depends on DEBUG_KERNEL depends on STACKTRACE_SUPPORT depends on PROC_FS - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !X86 select KALLSYMS select KALLSYMS_ALL select STACKTRACE @@ -1902,6 +1931,17 @@ config TEST_KMOD If unsure, say N. +config TEST_DEBUG_VIRTUAL + tristate "Test CONFIG_DEBUG_VIRTUAL feature" + depends on DEBUG_VIRTUAL + help + Test the kernel's ability to detect incorrect calls to + virt_to_phys() done against the non-linear part of the + kernel's virtual address map. + + If unsure, say N. + + source "samples/Kconfig" source "lib/Kconfig.kgdb" diff --git a/lib/Makefile b/lib/Makefile index 40c18372b301e5fe429fff598a077996e353966f..dafa79613fb47867fb641a71fa05a8f249c2ccd5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o obj-$(CONFIG_TEST_UUID) += test_uuid.o obj-$(CONFIG_TEST_PARMAN) += test_parman.o obj-$(CONFIG_TEST_KMOD) += test_kmod.o +obj-$(CONFIG_TEST_DEBUG_VIRTUAL) += test_debug_virtual.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG @@ -102,6 +103,7 @@ obj-$(CONFIG_CRC4) += crc4.o obj-$(CONFIG_CRC7) += crc7.o obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_CRC8) += crc8.o +obj-$(CONFIG_XXHASH) += xxhash.o obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o obj-$(CONFIG_842_COMPRESS) += 842/ @@ -115,6 +117,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ obj-$(CONFIG_LZ4_COMPRESS) += lz4/ obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ +obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ +obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ obj-$(CONFIG_XZ_DEC) += xz/ obj-$(CONFIG_RAID6_PQ) += raid6/ diff --git a/lib/assoc_array.c b/lib/assoc_array.c index 59fd7c0b119cbc3e0b61137732f76cc3759fb7c7..155c55d8db5fccb3ded0047d1fb1fcfef7673072 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c @@ -1,6 +1,6 @@ /* Generic associative array implementation. * - * See Documentation/assoc_array.txt for information. + * See Documentation/core-api/assoc_array.rst for information. * * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) diff --git a/lib/bitmap.c b/lib/bitmap.c index 9a532805364b6c039c30467a72a557ba8d532ca0..c82c61b66e166b521ff91d4e6055905d7431e6dc 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -513,7 +513,7 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, int nmaskbits) { unsigned int a, b, old_a, old_b; - unsigned int group_size, used_size; + unsigned int group_size, used_size, off; int c, old_c, totaldigits, ndigits; const char __user __force *ubuf = (const char __user __force *)buf; int at_start, in_range, in_partial_range; @@ -599,6 +599,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, a = old_a; b = old_b; old_a = old_b = 0; + } else { + used_size = group_size = b - a + 1; } /* if no digit is after '-', it's wrong*/ if (at_start && in_range) @@ -608,17 +610,9 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, if (b >= nmaskbits) return -ERANGE; while (a <= b) { - if (in_partial_range) { - static int pos_in_group = 1; - - if (pos_in_group <= used_size) - set_bit(a, maskp); - - if (a == b || ++pos_in_group > group_size) - pos_in_group = 1; - } else - set_bit(a, maskp); - a++; + off = min(b - a + 1, used_size); + bitmap_set(maskp, a, off); + a += group_size; } } while (buflen && c == ','); return 0; diff --git a/lib/cmdline.c b/lib/cmdline.c index 4c0888c4a68d9621717f9012d3ca4cc0b72df20b..171c19b6888e207bd663e9e41a87c7b0fad9a1de 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -244,5 +244,4 @@ char *next_arg(char *args, char **param, char **val) /* Chew up trailing spaces. */ return skip_spaces(next); - //return next; } diff --git a/lib/cpumask.c b/lib/cpumask.c index 4731a0895760e70cab07d59a0cff45c2590da450..8b1a1bd77539386a580dc79347518c76beb97e1d 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -5,6 +5,22 @@ #include #include +/** + * cpumask_next - get the next cpu in a cpumask + * @n: the cpu prior to the place to search (ie. return will be > @n) + * @srcp: the cpumask pointer + * + * Returns >= nr_cpu_ids if no further cpus set. + */ +unsigned int cpumask_next(int n, const struct cpumask *srcp) +{ + /* -1 is a legal arg here. */ + if (n != -1) + cpumask_check(n); + return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n + 1); +} +EXPORT_SYMBOL(cpumask_next); + /** * cpumask_next_and - get the next cpu in *src1p & *src2p * @n: the cpu prior to the place to search (ie. return will be > @n) diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 17afb043016133f880c3c64b696b5093f28dc52e..2f5349c6e81ae01b0cca972570f3b7920aca246e 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -18,6 +18,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -110,6 +111,7 @@ static void fill_pool(void) if (!new) return; + kmemleak_ignore(new); raw_spin_lock_irqsave(&pool_lock, flags); hlist_add_head(&new->node, &obj_pool); debug_objects_allocated++; @@ -1080,6 +1082,7 @@ static int __init debug_objects_replace_static_objects(void) obj = kmem_cache_zalloc(obj_cache, GFP_KERNEL); if (!obj) goto free; + kmemleak_ignore(obj); hlist_add_head(&obj->node, &objects); } diff --git a/lib/errseq.c b/lib/errseq.c index 841fa24e6e00e4fd2036ab9ff32345d0ceba0201..7b900c2a277ad39803db6904d8b8346b08951628 100644 --- a/lib/errseq.c +++ b/lib/errseq.c @@ -41,23 +41,20 @@ #define ERRSEQ_CTR_INC (1 << (ERRSEQ_SHIFT + 1)) /** - * __errseq_set - set a errseq_t for later reporting + * errseq_set - set a errseq_t for later reporting * @eseq: errseq_t field that should be set - * @err: error to set + * @err: error to set (must be between -1 and -MAX_ERRNO) * * This function sets the error in *eseq, and increments the sequence counter * if the last sequence was sampled at some point in the past. * * Any error set will always overwrite an existing error. * - * Most callers will want to use the errseq_set inline wrapper to efficiently - * handle the common case where err is 0. - * - * We do return an errseq_t here, primarily for debugging purposes. The return - * value should not be used as a previously sampled value in later calls as it - * will not have the SEEN flag set. + * We do return the latest value here, primarily for debugging purposes. The + * return value should not be used as a previously sampled value in later calls + * as it will not have the SEEN flag set. */ -errseq_t __errseq_set(errseq_t *eseq, int err) +errseq_t errseq_set(errseq_t *eseq, int err) { errseq_t cur, old; @@ -107,7 +104,7 @@ errseq_t __errseq_set(errseq_t *eseq, int err) } return cur; } -EXPORT_SYMBOL(__errseq_set); +EXPORT_SYMBOL(errseq_set); /** * errseq_sample - grab current errseq_t value diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 7d315fdb9f13d9b17d8a2aa129c75790c7599bdb..cf7b129b0b2b08adcc1aae98f990c384761532dc 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -110,10 +110,12 @@ bool should_fail(struct fault_attr *attr, ssize_t size) if (in_task()) { unsigned int fail_nth = READ_ONCE(current->fail_nth); - if (fail_nth && !WRITE_ONCE(current->fail_nth, fail_nth - 1)) - goto fail; + if (fail_nth) { + if (!WRITE_ONCE(current->fail_nth, fail_nth - 1)) + goto fail; - return false; + return false; + } } /* No need to check any other properties if the probability is 0 */ diff --git a/lib/hexdump.c b/lib/hexdump.c index 992457b1284c186d8e0d7b8c5d7b5fc349c18ef3..81b70ed37209697c083247264c9374b143c1749f 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -42,7 +43,7 @@ EXPORT_SYMBOL(hex_to_bin); * @src: ascii hexadecimal string * @count: result length * - * Return 0 on success, -1 in case of bad input. + * Return 0 on success, -EINVAL in case of bad input. */ int hex2bin(u8 *dst, const char *src, size_t count) { @@ -51,7 +52,7 @@ int hex2bin(u8 *dst, const char *src, size_t count) int lo = hex_to_bin(*src++); if ((hi < 0) || (lo < 0)) - return -1; + return -EINVAL; *dst++ = (hi << 4) | lo; } diff --git a/lib/idr.c b/lib/idr.c index b13682bb0a1c67432092ffb6f3f23071e9cd15dd..edd9b2be1651fa99ae3a6274bda38c1bd7159a64 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -7,45 +7,32 @@ DEFINE_PER_CPU(struct ida_bitmap *, ida_bitmap); static DEFINE_SPINLOCK(simple_ida_lock); -/** - * idr_alloc - allocate an id - * @idr: idr handle - * @ptr: pointer to be associated with the new id - * @start: the minimum id (inclusive) - * @end: the maximum id (exclusive) - * @gfp: memory allocation flags - * - * Allocates an unused ID in the range [start, end). Returns -ENOSPC - * if there are no unused IDs in that range. - * - * Note that @end is treated as max when <= 0. This is to always allow - * using @start + N as @end as long as N is inside integer range. - * - * Simultaneous modifications to the @idr are not allowed and should be - * prevented by the user, usually with a lock. idr_alloc() may be called - * concurrently with read-only accesses to the @idr, such as idr_find() and - * idr_for_each_entry(). - */ -int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp) +int idr_alloc_cmn(struct idr *idr, void *ptr, unsigned long *index, + unsigned long start, unsigned long end, gfp_t gfp, + bool ext) { - void __rcu **slot; struct radix_tree_iter iter; + void __rcu **slot; - if (WARN_ON_ONCE(start < 0)) - return -EINVAL; if (WARN_ON_ONCE(radix_tree_is_internal_node(ptr))) return -EINVAL; radix_tree_iter_init(&iter, start); - slot = idr_get_free(&idr->idr_rt, &iter, gfp, end); + if (ext) + slot = idr_get_free_ext(&idr->idr_rt, &iter, gfp, end); + else + slot = idr_get_free(&idr->idr_rt, &iter, gfp, end); if (IS_ERR(slot)) return PTR_ERR(slot); radix_tree_iter_replace(&idr->idr_rt, &iter, slot, ptr); radix_tree_iter_tag_clear(&idr->idr_rt, &iter, IDR_FREE); - return iter.index; + + if (index) + *index = iter.index; + return 0; } -EXPORT_SYMBOL_GPL(idr_alloc); +EXPORT_SYMBOL_GPL(idr_alloc_cmn); /** * idr_alloc_cyclic - allocate new idr entry in a cyclical fashion @@ -134,6 +121,20 @@ void *idr_get_next(struct idr *idr, int *nextid) } EXPORT_SYMBOL(idr_get_next); +void *idr_get_next_ext(struct idr *idr, unsigned long *nextid) +{ + struct radix_tree_iter iter; + void __rcu **slot; + + slot = radix_tree_iter_find(&idr->idr_rt, &iter, *nextid); + if (!slot) + return NULL; + + *nextid = iter.index; + return rcu_dereference_raw(*slot); +} +EXPORT_SYMBOL(idr_get_next_ext); + /** * idr_replace - replace pointer for given id * @idr: idr handle @@ -145,17 +146,24 @@ EXPORT_SYMBOL(idr_get_next); * idr_alloc() and idr_remove() (as long as the ID being removed is not * the one being replaced!). * - * Returns: 0 on success. %-ENOENT indicates that @id was not found. - * %-EINVAL indicates that @id or @ptr were not valid. + * Returns: the old value on success. %-ENOENT indicates that @id was not + * found. %-EINVAL indicates that @id or @ptr were not valid. */ void *idr_replace(struct idr *idr, void *ptr, int id) +{ + if (id < 0) + return ERR_PTR(-EINVAL); + + return idr_replace_ext(idr, ptr, id); +} +EXPORT_SYMBOL(idr_replace); + +void *idr_replace_ext(struct idr *idr, void *ptr, unsigned long id) { struct radix_tree_node *node; void __rcu **slot = NULL; void *entry; - if (WARN_ON_ONCE(id < 0)) - return ERR_PTR(-EINVAL); if (WARN_ON_ONCE(radix_tree_is_internal_node(ptr))) return ERR_PTR(-EINVAL); @@ -167,7 +175,7 @@ void *idr_replace(struct idr *idr, void *ptr, int id) return entry; } -EXPORT_SYMBOL(idr_replace); +EXPORT_SYMBOL(idr_replace_ext); /** * DOC: IDA description diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c index df495fe814210c1c979b893f8723e9b66fa4498f..0e343fd29570194d775594fb8e5319682c8c3d5c 100644 --- a/lib/interval_tree_test.c +++ b/lib/interval_tree_test.c @@ -19,14 +19,14 @@ __param(bool, search_all, false, "Searches will iterate all nodes in the tree"); __param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint"); -static struct rb_root root = RB_ROOT; +static struct rb_root_cached root = RB_ROOT_CACHED; static struct interval_tree_node *nodes = NULL; static u32 *queries = NULL; static struct rnd_state rnd; static inline unsigned long -search(struct rb_root *root, unsigned long start, unsigned long last) +search(struct rb_root_cached *root, unsigned long start, unsigned long last) { struct interval_tree_node *node; unsigned long results = 0; diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 52c8dd6d8e8290fa8df614e0017542a600b9c536..1c1c06ddc20a8a961d7d9f73e43d65b695636d5d 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -687,8 +687,10 @@ EXPORT_SYMBOL(_copy_from_iter_full_nocache); static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) { - size_t v = n + offset; - if (likely(n <= v && v <= (PAGE_SIZE << compound_order(page)))) + struct page *head = compound_head(page); + size_t v = n + offset + page_address(page) - page_address(head); + + if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head)))) return true; WARN_ON(1); return false; diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 719c155fce2084fc8e817afc007549a06eec92b5..f237a09a58627bfd4df2628c173f57afd89a83de 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -52,6 +52,8 @@ static const char *kobject_actions[] = { [KOBJ_MOVE] = "move", [KOBJ_ONLINE] = "online", [KOBJ_OFFLINE] = "offline", + [KOBJ_BIND] = "bind", + [KOBJ_UNBIND] = "unbind", }; static int kobject_action_type(const char *buf, size_t count, @@ -292,6 +294,26 @@ static void cleanup_uevent_env(struct subprocess_info *info) } #endif +static void zap_modalias_env(struct kobj_uevent_env *env) +{ + static const char modalias_prefix[] = "MODALIAS="; + int i; + + for (i = 0; i < env->envp_idx;) { + if (strncmp(env->envp[i], modalias_prefix, + sizeof(modalias_prefix) - 1)) { + i++; + continue; + } + + if (i != env->envp_idx - 1) + memmove(&env->envp[i], &env->envp[i + 1], + sizeof(env->envp[i]) * env->envp_idx - 1); + + env->envp_idx--; + } +} + /** * kobject_uevent_env - send an uevent with environmental data * @@ -407,16 +429,29 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, } } - /* - * Mark "add" and "remove" events in the object to ensure proper - * events to userspace during automatic cleanup. If the object did - * send an "add" event, "remove" will automatically generated by - * the core, if not already done by the caller. - */ - if (action == KOBJ_ADD) + switch (action) { + case KOBJ_ADD: + /* + * Mark "add" event so we can make sure we deliver "remove" + * event to userspace during automatic cleanup. If + * the object did send an "add" event, "remove" will + * automatically generated by the core, if not already done + * by the caller. + */ kobj->state_add_uevent_sent = 1; - else if (action == KOBJ_REMOVE) + break; + + case KOBJ_REMOVE: kobj->state_remove_uevent_sent = 1; + break; + + case KOBJ_UNBIND: + zap_modalias_env(env); + break; + + default: + break; + } mutex_lock(&uevent_sock_mutex); /* we will send an event, so request a new sequence number */ diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 6f2b135dc5e81996dc2582f56d59b5d1769f5377..cd0b5c964bd041853a74116780c4446c4dc355f9 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -362,6 +362,103 @@ static void rsem_AA3(void) RSL(X2); // this one should fail } +/* + * read_lock(A) + * spin_lock(B) + * spin_lock(B) + * write_lock(A) + */ +static void rlock_ABBA1(void) +{ + RL(X1); + L(Y1); + U(Y1); + RU(X1); + + L(Y1); + WL(X1); + WU(X1); + U(Y1); // should fail +} + +static void rwsem_ABBA1(void) +{ + RSL(X1); + ML(Y1); + MU(Y1); + RSU(X1); + + ML(Y1); + WSL(X1); + WSU(X1); + MU(Y1); // should fail +} + +/* + * read_lock(A) + * spin_lock(B) + * spin_lock(B) + * read_lock(A) + */ +static void rlock_ABBA2(void) +{ + RL(X1); + L(Y1); + U(Y1); + RU(X1); + + L(Y1); + RL(X1); + RU(X1); + U(Y1); // should NOT fail +} + +static void rwsem_ABBA2(void) +{ + RSL(X1); + ML(Y1); + MU(Y1); + RSU(X1); + + ML(Y1); + RSL(X1); + RSU(X1); + MU(Y1); // should fail +} + + +/* + * write_lock(A) + * spin_lock(B) + * spin_lock(B) + * write_lock(A) + */ +static void rlock_ABBA3(void) +{ + WL(X1); + L(Y1); + U(Y1); + WU(X1); + + L(Y1); + WL(X1); + WU(X1); + U(Y1); // should fail +} + +static void rwsem_ABBA3(void) +{ + WSL(X1); + ML(Y1); + MU(Y1); + WSU(X1); + + ML(Y1); + WSL(X1); + WSU(X1); + MU(Y1); // should fail +} + /* * ABBA deadlock: */ @@ -1056,8 +1153,6 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) if (debug_locks != expected) { unexpected_testcase_failures++; pr_cont("FAILED|"); - - dump_stack(); } else { testcase_successes++; pr_cont(" ok |"); @@ -1933,6 +2028,30 @@ void locking_selftest(void) dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); pr_cont("\n"); + print_testname("mixed read-lock/lock-write ABBA"); + pr_cont(" |"); + dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK); + /* + * Lockdep does indeed fail here, but there's nothing we can do about + * that now. Don't kill lockdep for it. + */ + unexpected_testcase_failures--; + + pr_cont(" |"); + dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM); + + print_testname("mixed read-lock/lock-read ABBA"); + pr_cont(" |"); + dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK); + pr_cont(" |"); + dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM); + + print_testname("mixed write-lock/lock-write ABBA"); + pr_cont(" |"); + dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK); + pr_cont(" |"); + dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM); + printk(" --------------------------------------------------------------------------\n"); /* diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c index bd3574312b827c606fe93c8d0a8a8c0ca0c6542d..141734d255e4b941f888e32ee53885c26cfc8fbd 100644 --- a/lib/lz4/lz4_decompress.c +++ b/lib/lz4/lz4_decompress.c @@ -85,8 +85,8 @@ static FORCE_INLINE int LZ4_decompress_generic( const BYTE * const lowLimit = lowPrefix - dictSize; const BYTE * const dictEnd = (const BYTE *)dictStart + dictSize; - const unsigned int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; - const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; + static const unsigned int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; + static const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; const int safeDecode = (endOnInput == endOnInputSize); const int checkOffset = ((safeDecode) && (dictSize < (int)(64 * KB))); diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 93336502af089685ce1f6ccbdb159003f1442d70..57fd45ab7af1a42aaf290866a2c0bbc5da7f8710 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h @@ -176,8 +176,8 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("adds %1, %4, %5\n" \ "adc %0, %2, %3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "%r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ @@ -185,15 +185,15 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subs %1, %4, %5\n" \ "sbc %0, %2, %3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ + : "=r" (sh), \ + "=&r" (sl) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ "rI" ((USItype)(bl))) #if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__ #define umul_ppmm(xh, xl, a, b) \ - __asm__ ("%@ Inlined umul_ppmm\n" \ + __asm__ ("@ Inlined umul_ppmm\n" \ "mov %|r0, %2, lsr #16 @ AAAA\n" \ "mov %|r2, %3, lsr #16 @ BBBB\n" \ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \ @@ -206,19 +206,19 @@ extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype); "addcs %|r2, %|r2, #65536\n" \ "adds %1, %|r1, %|r0, lsl #16\n" \ "adc %0, %|r2, %|r0, lsr #16" \ - : "=&r" ((USItype)(xh)), \ - "=r" ((USItype)(xl)) \ + : "=&r" (xh), \ + "=r" (xl) \ : "r" ((USItype)(a)), \ "r" ((USItype)(b)) \ : "r0", "r1", "r2") #else #define umul_ppmm(xh, xl, a, b) \ - __asm__ ("%@ Inlined umul_ppmm\n" \ - "umull %r1, %r0, %r2, %r3" \ - : "=&r" ((USItype)(xh)), \ - "=&r" ((USItype)(xl)) \ + __asm__ ("@ Inlined umul_ppmm\n" \ + "umull %1, %0, %2, %3" \ + : "=&r" (xh), \ + "=&r" (xl) \ : "r" ((USItype)(a)), \ - "r" ((USItype)(b)) \ + "r" ((USItype)(b)) \ : "r0", "r1") #endif #define UMUL_TIME 20 diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 5a0f75a3bf01c1b259fb125fbe7266c186d83a71..eead4b339466854f51db30a17f17ee0472ebe6d3 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c @@ -364,11 +364,11 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) } miter.consumed = lzeros; - sg_miter_stop(&miter); nbytes -= lzeros; nbits = nbytes * 8; if (nbits > MAX_EXTERN_MPI_BITS) { + sg_miter_stop(&miter); pr_info("MPI: mpi too large (%u bits)\n", nbits); return NULL; } @@ -376,6 +376,8 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) if (nbytes > 0) nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8); + sg_miter_stop(&miter); + nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); val = mpi_alloc(nlimbs); if (!val) diff --git a/lib/nlattr.c b/lib/nlattr.c index fb52435be42dda3a5e7041b3554712bc80b4caad..927c2f19f119e4eb4f21b02987db34e3edc97fa8 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -27,6 +27,30 @@ static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_S64] = sizeof(s64), }; +static int validate_nla_bitfield32(const struct nlattr *nla, + u32 *valid_flags_allowed) +{ + const struct nla_bitfield32 *bf = nla_data(nla); + u32 *valid_flags_mask = valid_flags_allowed; + + if (!valid_flags_allowed) + return -EINVAL; + + /*disallow invalid bit selector */ + if (bf->selector & ~*valid_flags_mask) + return -EINVAL; + + /*disallow invalid bit values */ + if (bf->value & ~*valid_flags_mask) + return -EINVAL; + + /*disallow valid bit values that are not selected*/ + if (bf->value & ~bf->selector) + return -EINVAL; + + return 0; +} + static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy) { @@ -46,6 +70,12 @@ static int validate_nla(const struct nlattr *nla, int maxtype, return -ERANGE; break; + case NLA_BITFIELD32: + if (attrlen != sizeof(struct nla_bitfield32)) + return -ERANGE; + + return validate_nla_bitfield32(nla, pt->validation_data); + case NLA_NUL_STRING: if (pt->len) minlen = min_t(int, attrlen, pt->len + 1); @@ -271,6 +301,30 @@ size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize) } EXPORT_SYMBOL(nla_strlcpy); +/** + * nla_strdup - Copy string attribute payload into a newly allocated buffer + * @nla: attribute to copy the string from + * @flags: the type of memory to allocate (see kmalloc). + * + * Returns a pointer to the allocated buffer or NULL on error. + */ +char *nla_strdup(const struct nlattr *nla, gfp_t flags) +{ + size_t srclen = nla_len(nla); + char *src = nla_data(nla), *dst; + + if (srclen > 0 && src[srclen - 1] == '\0') + srclen--; + + dst = kmalloc(srclen + 1, flags); + if (dst != NULL) { + memcpy(dst, src, srclen); + dst[srclen] = '\0'; + } + return dst; +} +EXPORT_SYMBOL(nla_strdup); + /** * nla_memcpy - Copy a netlink attribute into another memory area * @dest: where to copy to memcpy diff --git a/lib/oid_registry.c b/lib/oid_registry.c index 318f382a010d62f0f6b0c536ee038f41100e57cf..41b9e50711a72af31d7548d3aea5be1177a45a9d 100644 --- a/lib/oid_registry.c +++ b/lib/oid_registry.c @@ -142,9 +142,9 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) } ret += count = snprintf(buffer, bufsize, ".%lu", num); buffer += count; - bufsize -= count; - if (bufsize == 0) + if (bufsize <= count) return -ENOBUFS; + bufsize -= count; } return ret; diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 898e8799841759ff20f1dc3eb25f277ebb3a8119..8b1feca1230a08c4537036f517cfa4369b62dffa 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -463,7 +463,7 @@ radix_tree_node_free(struct radix_tree_node *node) * To make use of this facility, the radix tree must be initialised without * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE(). */ -static int __radix_tree_preload(gfp_t gfp_mask, unsigned nr) +static __must_check int __radix_tree_preload(gfp_t gfp_mask, unsigned nr) { struct radix_tree_preload *rtp; struct radix_tree_node *node; @@ -2022,6 +2022,7 @@ void radix_tree_iter_delete(struct radix_tree_root *root, if (__radix_tree_delete(root, iter->node, slot)) iter->index = iter->next_index; } +EXPORT_SYMBOL(radix_tree_iter_delete); /** * radix_tree_delete_item - delete an item from a radix tree @@ -2103,7 +2104,8 @@ EXPORT_SYMBOL(radix_tree_tagged); */ void idr_preload(gfp_t gfp_mask) { - __radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE); + if (__radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE)) + preempt_disable(); } EXPORT_SYMBOL(idr_preload); @@ -2117,13 +2119,13 @@ EXPORT_SYMBOL(idr_preload); */ int ida_pre_get(struct ida *ida, gfp_t gfp) { - __radix_tree_preload(gfp, IDA_PRELOAD_SIZE); /* * The IDA API has no preload_end() equivalent. Instead, * ida_get_new() can return -EAGAIN, prompting the caller * to return to the ida_pre_get() step. */ - preempt_enable(); + if (!__radix_tree_preload(gfp, IDA_PRELOAD_SIZE)) + preempt_enable(); if (!this_cpu_read(ida_bitmap)) { struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); @@ -2137,13 +2139,13 @@ int ida_pre_get(struct ida *ida, gfp_t gfp) } EXPORT_SYMBOL(ida_pre_get); -void __rcu **idr_get_free(struct radix_tree_root *root, - struct radix_tree_iter *iter, gfp_t gfp, int end) +void __rcu **idr_get_free_cmn(struct radix_tree_root *root, + struct radix_tree_iter *iter, gfp_t gfp, + unsigned long max) { struct radix_tree_node *node = NULL, *child; void __rcu **slot = (void __rcu **)&root->rnode; unsigned long maxindex, start = iter->next_index; - unsigned long max = end > 0 ? end - 1 : INT_MAX; unsigned int shift, offset = 0; grow: diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index 3057011f5599bed39532bbe83e6d84cc4a3f05f8..a93adf6dcfb27114950f3403c7d59962213c2cac 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile @@ -5,7 +5,7 @@ raid6_pq-y += algos.o recov.o tables.o int1.o int2.o int4.o \ raid6_pq-$(CONFIG_X86) += recov_ssse3.o recov_avx2.o mmx.o sse1.o sse2.o avx2.o avx512.o recov_avx512.o raid6_pq-$(CONFIG_ALTIVEC) += altivec1.o altivec2.o altivec4.o altivec8.o -raid6_pq-$(CONFIG_KERNEL_MODE_NEON) += neon.o neon1.o neon2.o neon4.o neon8.o +raid6_pq-$(CONFIG_KERNEL_MODE_NEON) += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o raid6_pq-$(CONFIG_TILEGX) += tilegx8.o raid6_pq-$(CONFIG_S390) += s390vx8.o recov_s390xc.o @@ -26,7 +26,9 @@ NEON_FLAGS := -ffreestanding ifeq ($(ARCH),arm) NEON_FLAGS += -mfloat-abi=softfp -mfpu=neon endif +CFLAGS_recov_neon_inner.o += $(NEON_FLAGS) ifeq ($(ARCH),arm64) +CFLAGS_REMOVE_recov_neon_inner.o += -mgeneral-regs-only CFLAGS_REMOVE_neon1.o += -mgeneral-regs-only CFLAGS_REMOVE_neon2.o += -mgeneral-regs-only CFLAGS_REMOVE_neon4.o += -mgeneral-regs-only diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c index 7857049fd7d3660022e9372fdd5a11adc243099b..4769947232582c9a9074b167c2fe1c0a22143bf3 100644 --- a/lib/raid6/algos.c +++ b/lib/raid6/algos.c @@ -112,6 +112,9 @@ const struct raid6_recov_calls *const raid6_recov_algos[] = { #endif #ifdef CONFIG_S390 &raid6_recov_s390xc, +#endif +#if defined(CONFIG_KERNEL_MODE_NEON) + &raid6_recov_neon, #endif &raid6_recov_intx1, NULL diff --git a/lib/raid6/avx512.c b/lib/raid6/avx512.c index f524a797200652aec220f3c09f0c5e790b234c87..46df7977b9718bdc4b6ca1960792bae62b8442b7 100644 --- a/lib/raid6/avx512.c +++ b/lib/raid6/avx512.c @@ -29,7 +29,7 @@ static const struct raid6_avx512_constants { u64 x1d[8]; -} raid6_avx512_constants __aligned(512) = { +} raid6_avx512_constants __aligned(512/8) = { { 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL, diff --git a/lib/raid6/neon.uc b/lib/raid6/neon.uc index 4fa51b761dd0cb4e0ef6c82fbacff87dfe20383f..d5242f5445511784bc821f3cd64a4487f2673c97 100644 --- a/lib/raid6/neon.uc +++ b/lib/raid6/neon.uc @@ -46,8 +46,12 @@ static inline unative_t SHLBYTE(unative_t v) */ static inline unative_t MASK(unative_t v) { - const uint8x16_t temp = NBYTES(0); - return (unative_t)vcltq_s8((int8x16_t)v, (int8x16_t)temp); + return (unative_t)vshrq_n_s8((int8x16_t)v, 7); +} + +static inline unative_t PMUL(unative_t v, unative_t u) +{ + return (unative_t)vmulq_p8((poly8x16_t)v, (poly8x16_t)u); } void raid6_neon$#_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs) @@ -110,7 +114,30 @@ void raid6_neon$#_xor_syndrome_real(int disks, int start, int stop, wq$$ = veorq_u8(w1$$, wd$$); } /* P/Q left side optimization */ - for ( z = start-1 ; z >= 0 ; z-- ) { + for ( z = start-1 ; z >= 3 ; z -= 4 ) { + w2$$ = vshrq_n_u8(wq$$, 4); + w1$$ = vshlq_n_u8(wq$$, 4); + + w2$$ = PMUL(w2$$, x1d); + wq$$ = veorq_u8(w1$$, w2$$); + } + + switch (z) { + case 2: + w2$$ = vshrq_n_u8(wq$$, 5); + w1$$ = vshlq_n_u8(wq$$, 3); + + w2$$ = PMUL(w2$$, x1d); + wq$$ = veorq_u8(w1$$, w2$$); + break; + case 1: + w2$$ = vshrq_n_u8(wq$$, 6); + w1$$ = vshlq_n_u8(wq$$, 2); + + w2$$ = PMUL(w2$$, x1d); + wq$$ = veorq_u8(w1$$, w2$$); + break; + case 0: w2$$ = MASK(wq$$); w1$$ = SHLBYTE(wq$$); diff --git a/lib/raid6/recov_neon.c b/lib/raid6/recov_neon.c new file mode 100644 index 0000000000000000000000000000000000000000..eeb5c4065b92d70b2ea27fe7e633dfa0ee7ec745 --- /dev/null +++ b/lib/raid6/recov_neon.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include + +#ifdef __KERNEL__ +#include +#else +#define kernel_neon_begin() +#define kernel_neon_end() +#define cpu_has_neon() (1) +#endif + +static int raid6_has_neon(void) +{ + return cpu_has_neon(); +} + +void __raid6_2data_recov_neon(int bytes, uint8_t *p, uint8_t *q, uint8_t *dp, + uint8_t *dq, const uint8_t *pbmul, + const uint8_t *qmul); + +void __raid6_datap_recov_neon(int bytes, uint8_t *p, uint8_t *q, uint8_t *dq, + const uint8_t *qmul); + +static void raid6_2data_recov_neon(int disks, size_t bytes, int faila, + int failb, void **ptrs) +{ + u8 *p, *q, *dp, *dq; + const u8 *pbmul; /* P multiplier table for B data */ + const u8 *qmul; /* Q multiplier table (for both) */ + + p = (u8 *)ptrs[disks - 2]; + q = (u8 *)ptrs[disks - 1]; + + /* + * Compute syndrome with zero for the missing data pages + * Use the dead data pages as temporary storage for + * delta p and delta q + */ + dp = (u8 *)ptrs[faila]; + ptrs[faila] = (void *)raid6_empty_zero_page; + ptrs[disks - 2] = dp; + dq = (u8 *)ptrs[failb]; + ptrs[failb] = (void *)raid6_empty_zero_page; + ptrs[disks - 1] = dq; + + raid6_call.gen_syndrome(disks, bytes, ptrs); + + /* Restore pointer table */ + ptrs[faila] = dp; + ptrs[failb] = dq; + ptrs[disks - 2] = p; + ptrs[disks - 1] = q; + + /* Now, pick the proper data tables */ + pbmul = raid6_vgfmul[raid6_gfexi[failb-faila]]; + qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila] ^ + raid6_gfexp[failb]]]; + + kernel_neon_begin(); + __raid6_2data_recov_neon(bytes, p, q, dp, dq, pbmul, qmul); + kernel_neon_end(); +} + +static void raid6_datap_recov_neon(int disks, size_t bytes, int faila, + void **ptrs) +{ + u8 *p, *q, *dq; + const u8 *qmul; /* Q multiplier table */ + + p = (u8 *)ptrs[disks - 2]; + q = (u8 *)ptrs[disks - 1]; + + /* + * Compute syndrome with zero for the missing data page + * Use the dead data page as temporary storage for delta q + */ + dq = (u8 *)ptrs[faila]; + ptrs[faila] = (void *)raid6_empty_zero_page; + ptrs[disks - 1] = dq; + + raid6_call.gen_syndrome(disks, bytes, ptrs); + + /* Restore pointer table */ + ptrs[faila] = dq; + ptrs[disks - 1] = q; + + /* Now, pick the proper data tables */ + qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila]]]; + + kernel_neon_begin(); + __raid6_datap_recov_neon(bytes, p, q, dq, qmul); + kernel_neon_end(); +} + +const struct raid6_recov_calls raid6_recov_neon = { + .data2 = raid6_2data_recov_neon, + .datap = raid6_datap_recov_neon, + .valid = raid6_has_neon, + .name = "neon", + .priority = 10, +}; diff --git a/lib/raid6/recov_neon_inner.c b/lib/raid6/recov_neon_inner.c new file mode 100644 index 0000000000000000000000000000000000000000..8cd20c9f834a1e8cc90e9a4f783f74a4244a5f7a --- /dev/null +++ b/lib/raid6/recov_neon_inner.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include + +static const uint8x16_t x0f = { + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, +}; + +#ifdef CONFIG_ARM +/* + * AArch32 does not provide this intrinsic natively because it does not + * implement the underlying instruction. AArch32 only provides a 64-bit + * wide vtbl.8 instruction, so use that instead. + */ +static uint8x16_t vqtbl1q_u8(uint8x16_t a, uint8x16_t b) +{ + union { + uint8x16_t val; + uint8x8x2_t pair; + } __a = { a }; + + return vcombine_u8(vtbl2_u8(__a.pair, vget_low_u8(b)), + vtbl2_u8(__a.pair, vget_high_u8(b))); +} +#endif + +void __raid6_2data_recov_neon(int bytes, uint8_t *p, uint8_t *q, uint8_t *dp, + uint8_t *dq, const uint8_t *pbmul, + const uint8_t *qmul) +{ + uint8x16_t pm0 = vld1q_u8(pbmul); + uint8x16_t pm1 = vld1q_u8(pbmul + 16); + uint8x16_t qm0 = vld1q_u8(qmul); + uint8x16_t qm1 = vld1q_u8(qmul + 16); + + /* + * while ( bytes-- ) { + * uint8_t px, qx, db; + * + * px = *p ^ *dp; + * qx = qmul[*q ^ *dq]; + * *dq++ = db = pbmul[px] ^ qx; + * *dp++ = db ^ px; + * p++; q++; + * } + */ + + while (bytes) { + uint8x16_t vx, vy, px, qx, db; + + px = veorq_u8(vld1q_u8(p), vld1q_u8(dp)); + vx = veorq_u8(vld1q_u8(q), vld1q_u8(dq)); + + vy = (uint8x16_t)vshrq_n_s16((int16x8_t)vx, 4); + vx = vqtbl1q_u8(qm0, vandq_u8(vx, x0f)); + vy = vqtbl1q_u8(qm1, vandq_u8(vy, x0f)); + qx = veorq_u8(vx, vy); + + vy = (uint8x16_t)vshrq_n_s16((int16x8_t)px, 4); + vx = vqtbl1q_u8(pm0, vandq_u8(px, x0f)); + vy = vqtbl1q_u8(pm1, vandq_u8(vy, x0f)); + vx = veorq_u8(vx, vy); + db = veorq_u8(vx, qx); + + vst1q_u8(dq, db); + vst1q_u8(dp, veorq_u8(db, px)); + + bytes -= 16; + p += 16; + q += 16; + dp += 16; + dq += 16; + } +} + +void __raid6_datap_recov_neon(int bytes, uint8_t *p, uint8_t *q, uint8_t *dq, + const uint8_t *qmul) +{ + uint8x16_t qm0 = vld1q_u8(qmul); + uint8x16_t qm1 = vld1q_u8(qmul + 16); + + /* + * while (bytes--) { + * *p++ ^= *dq = qmul[*q ^ *dq]; + * q++; dq++; + * } + */ + + while (bytes) { + uint8x16_t vx, vy; + + vx = veorq_u8(vld1q_u8(q), vld1q_u8(dq)); + + vy = (uint8x16_t)vshrq_n_s16((int16x8_t)vx, 4); + vx = vqtbl1q_u8(qm0, vandq_u8(vx, x0f)); + vy = vqtbl1q_u8(qm1, vandq_u8(vy, x0f)); + vx = veorq_u8(vx, vy); + vy = veorq_u8(vx, vld1q_u8(p)); + + vst1q_u8(dq, vx); + vst1q_u8(p, vy); + + bytes -= 16; + p += 16; + q += 16; + dq += 16; + } +} diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 08f8043cac619d4dc59efda9aa2830514ba1c199..d01f4713523904b6c1da5022eb273f227b129095 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -48,7 +48,9 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func) if (time_is_before_jiffies(rs->begin + rs->interval)) { if (rs->missed) { if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { - pr_warn("%s: %d callbacks suppressed\n", func, rs->missed); + printk_deferred(KERN_WARNING + "%s: %d callbacks suppressed\n", + func, rs->missed); rs->missed = 0; } } diff --git a/lib/rbtree.c b/lib/rbtree.c index 4ba2828a67c0401b371b04cce7c52d566b5c0e74..ba4a9d165f1bed3c39651387def0008fc793fbd6 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c @@ -95,22 +95,35 @@ __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, static __always_inline void __rb_insert(struct rb_node *node, struct rb_root *root, + bool newleft, struct rb_node **leftmost, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) { struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; + if (newleft) + *leftmost = node; + while (true) { /* - * Loop invariant: node is red - * - * If there is a black parent, we are done. - * Otherwise, take some corrective action as we don't - * want a red root or two consecutive red nodes. + * Loop invariant: node is red. */ - if (!parent) { + if (unlikely(!parent)) { + /* + * The inserted node is root. Either this is the + * first node, or we recursed at Case 1 below and + * are no longer violating 4). + */ rb_set_parent_color(node, NULL, RB_BLACK); break; - } else if (rb_is_black(parent)) + } + + /* + * If there is a black parent, we are done. + * Otherwise, take some corrective action as, + * per 4), we don't want a red root or two + * consecutive red nodes. + */ + if(rb_is_black(parent)) break; gparent = rb_red_parent(parent); @@ -119,7 +132,7 @@ __rb_insert(struct rb_node *node, struct rb_root *root, if (parent != tmp) { /* parent == gparent->rb_left */ if (tmp && rb_is_red(tmp)) { /* - * Case 1 - color flips + * Case 1 - node's uncle is red (color flips). * * G g * / \ / \ @@ -142,7 +155,8 @@ __rb_insert(struct rb_node *node, struct rb_root *root, tmp = parent->rb_right; if (node == tmp) { /* - * Case 2 - left rotate at parent + * Case 2 - node's uncle is black and node is + * the parent's right child (left rotate at parent). * * G G * / \ / \ @@ -166,7 +180,8 @@ __rb_insert(struct rb_node *node, struct rb_root *root, } /* - * Case 3 - right rotate at gparent + * Case 3 - node's uncle is black and node is + * the parent's left child (right rotate at gparent). * * G P * / \ / \ @@ -434,19 +449,38 @@ static const struct rb_augment_callbacks dummy_callbacks = { void rb_insert_color(struct rb_node *node, struct rb_root *root) { - __rb_insert(node, root, dummy_rotate); + __rb_insert(node, root, false, NULL, dummy_rotate); } EXPORT_SYMBOL(rb_insert_color); void rb_erase(struct rb_node *node, struct rb_root *root) { struct rb_node *rebalance; - rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); + rebalance = __rb_erase_augmented(node, root, + NULL, &dummy_callbacks); if (rebalance) ____rb_erase_color(rebalance, root, dummy_rotate); } EXPORT_SYMBOL(rb_erase); +void rb_insert_color_cached(struct rb_node *node, + struct rb_root_cached *root, bool leftmost) +{ + __rb_insert(node, &root->rb_root, leftmost, + &root->rb_leftmost, dummy_rotate); +} +EXPORT_SYMBOL(rb_insert_color_cached); + +void rb_erase_cached(struct rb_node *node, struct rb_root_cached *root) +{ + struct rb_node *rebalance; + rebalance = __rb_erase_augmented(node, &root->rb_root, + &root->rb_leftmost, &dummy_callbacks); + if (rebalance) + ____rb_erase_color(rebalance, &root->rb_root, dummy_rotate); +} +EXPORT_SYMBOL(rb_erase_cached); + /* * Augmented rbtree manipulation functions. * @@ -455,9 +489,10 @@ EXPORT_SYMBOL(rb_erase); */ void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, + bool newleft, struct rb_node **leftmost, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) { - __rb_insert(node, root, augment_rotate); + __rb_insert(node, root, newleft, leftmost, augment_rotate); } EXPORT_SYMBOL(__rb_insert_augmented); @@ -502,7 +537,7 @@ struct rb_node *rb_next(const struct rb_node *node) * as we can. */ if (node->rb_right) { - node = node->rb_right; + node = node->rb_right; while (node->rb_left) node=node->rb_left; return (struct rb_node *)node; @@ -534,7 +569,7 @@ struct rb_node *rb_prev(const struct rb_node *node) * as we can. */ if (node->rb_left) { - node = node->rb_left; + node = node->rb_left; while (node->rb_right) node=node->rb_right; return (struct rb_node *)node; diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c index 8b3c9dc882628fd9945b5901eba670f67f885adf..191a238e5a9d73e67ee763371cf3f9a4a3865792 100644 --- a/lib/rbtree_test.c +++ b/lib/rbtree_test.c @@ -1,11 +1,18 @@ #include +#include #include #include +#include #include -#define NODES 100 -#define PERF_LOOPS 100000 -#define CHECK_LOOPS 100 +#define __param(type, name, init, msg) \ + static type name = init; \ + module_param(name, type, 0444); \ + MODULE_PARM_DESC(name, msg); + +__param(int, nnodes, 100, "Number of nodes in the rb-tree"); +__param(int, perf_loops, 100000, "Number of iterations modifying the rb-tree"); +__param(int, check_loops, 100, "Number of iterations modifying and verifying the rb-tree"); struct test_node { u32 key; @@ -16,14 +23,14 @@ struct test_node { u32 augmented; }; -static struct rb_root root = RB_ROOT; -static struct test_node nodes[NODES]; +static struct rb_root_cached root = RB_ROOT_CACHED; +static struct test_node *nodes = NULL; static struct rnd_state rnd; -static void insert(struct test_node *node, struct rb_root *root) +static void insert(struct test_node *node, struct rb_root_cached *root) { - struct rb_node **new = &root->rb_node, *parent = NULL; + struct rb_node **new = &root->rb_root.rb_node, *parent = NULL; u32 key = node->key; while (*new) { @@ -35,14 +42,40 @@ static void insert(struct test_node *node, struct rb_root *root) } rb_link_node(&node->rb, parent, new); - rb_insert_color(&node->rb, root); + rb_insert_color(&node->rb, &root->rb_root); +} + +static void insert_cached(struct test_node *node, struct rb_root_cached *root) +{ + struct rb_node **new = &root->rb_root.rb_node, *parent = NULL; + u32 key = node->key; + bool leftmost = true; + + while (*new) { + parent = *new; + if (key < rb_entry(parent, struct test_node, rb)->key) + new = &parent->rb_left; + else { + new = &parent->rb_right; + leftmost = false; + } + } + + rb_link_node(&node->rb, parent, new); + rb_insert_color_cached(&node->rb, root, leftmost); } -static inline void erase(struct test_node *node, struct rb_root *root) +static inline void erase(struct test_node *node, struct rb_root_cached *root) { - rb_erase(&node->rb, root); + rb_erase(&node->rb, &root->rb_root); } +static inline void erase_cached(struct test_node *node, struct rb_root_cached *root) +{ + rb_erase_cached(&node->rb, root); +} + + static inline u32 augment_recompute(struct test_node *node) { u32 max = node->val, child_augmented; @@ -64,9 +97,10 @@ static inline u32 augment_recompute(struct test_node *node) RB_DECLARE_CALLBACKS(static, augment_callbacks, struct test_node, rb, u32, augmented, augment_recompute) -static void insert_augmented(struct test_node *node, struct rb_root *root) +static void insert_augmented(struct test_node *node, + struct rb_root_cached *root) { - struct rb_node **new = &root->rb_node, *rb_parent = NULL; + struct rb_node **new = &root->rb_root.rb_node, *rb_parent = NULL; u32 key = node->key; u32 val = node->val; struct test_node *parent; @@ -84,18 +118,53 @@ static void insert_augmented(struct test_node *node, struct rb_root *root) node->augmented = val; rb_link_node(&node->rb, rb_parent, new); - rb_insert_augmented(&node->rb, root, &augment_callbacks); + rb_insert_augmented(&node->rb, &root->rb_root, &augment_callbacks); +} + +static void insert_augmented_cached(struct test_node *node, + struct rb_root_cached *root) +{ + struct rb_node **new = &root->rb_root.rb_node, *rb_parent = NULL; + u32 key = node->key; + u32 val = node->val; + struct test_node *parent; + bool leftmost = true; + + while (*new) { + rb_parent = *new; + parent = rb_entry(rb_parent, struct test_node, rb); + if (parent->augmented < val) + parent->augmented = val; + if (key < parent->key) + new = &parent->rb.rb_left; + else { + new = &parent->rb.rb_right; + leftmost = false; + } + } + + node->augmented = val; + rb_link_node(&node->rb, rb_parent, new); + rb_insert_augmented_cached(&node->rb, root, + leftmost, &augment_callbacks); +} + + +static void erase_augmented(struct test_node *node, struct rb_root_cached *root) +{ + rb_erase_augmented(&node->rb, &root->rb_root, &augment_callbacks); } -static void erase_augmented(struct test_node *node, struct rb_root *root) +static void erase_augmented_cached(struct test_node *node, + struct rb_root_cached *root) { - rb_erase_augmented(&node->rb, root, &augment_callbacks); + rb_erase_augmented_cached(&node->rb, root, &augment_callbacks); } static void init(void) { int i; - for (i = 0; i < NODES; i++) { + for (i = 0; i < nnodes; i++) { nodes[i].key = prandom_u32_state(&rnd); nodes[i].val = prandom_u32_state(&rnd); } @@ -118,7 +187,7 @@ static void check_postorder_foreach(int nr_nodes) { struct test_node *cur, *n; int count = 0; - rbtree_postorder_for_each_entry_safe(cur, n, &root, rb) + rbtree_postorder_for_each_entry_safe(cur, n, &root.rb_root, rb) count++; WARN_ON_ONCE(count != nr_nodes); @@ -128,7 +197,7 @@ static void check_postorder(int nr_nodes) { struct rb_node *rb; int count = 0; - for (rb = rb_first_postorder(&root); rb; rb = rb_next_postorder(rb)) + for (rb = rb_first_postorder(&root.rb_root); rb; rb = rb_next_postorder(rb)) count++; WARN_ON_ONCE(count != nr_nodes); @@ -140,7 +209,7 @@ static void check(int nr_nodes) int count = 0, blacks = 0; u32 prev_key = 0; - for (rb = rb_first(&root); rb; rb = rb_next(rb)) { + for (rb = rb_first(&root.rb_root); rb; rb = rb_next(rb)) { struct test_node *node = rb_entry(rb, struct test_node, rb); WARN_ON_ONCE(node->key < prev_key); WARN_ON_ONCE(is_red(rb) && @@ -155,7 +224,7 @@ static void check(int nr_nodes) } WARN_ON_ONCE(count != nr_nodes); - WARN_ON_ONCE(count < (1 << black_path_count(rb_last(&root))) - 1); + WARN_ON_ONCE(count < (1 << black_path_count(rb_last(&root.rb_root))) - 1); check_postorder(nr_nodes); check_postorder_foreach(nr_nodes); @@ -166,7 +235,7 @@ static void check_augmented(int nr_nodes) struct rb_node *rb; check(nr_nodes); - for (rb = rb_first(&root); rb; rb = rb_next(rb)) { + for (rb = rb_first(&root.rb_root); rb; rb = rb_next(rb)) { struct test_node *node = rb_entry(rb, struct test_node, rb); WARN_ON_ONCE(node->augmented != augment_recompute(node)); } @@ -176,6 +245,11 @@ static int __init rbtree_test_init(void) { int i, j; cycles_t time1, time2, time; + struct rb_node *node; + + nodes = kmalloc(nnodes * sizeof(*nodes), GFP_KERNEL); + if (!nodes) + return -ENOMEM; printk(KERN_ALERT "rbtree testing"); @@ -184,27 +258,88 @@ static int __init rbtree_test_init(void) time1 = get_cycles(); - for (i = 0; i < PERF_LOOPS; i++) { - for (j = 0; j < NODES; j++) + for (i = 0; i < perf_loops; i++) { + for (j = 0; j < nnodes; j++) insert(nodes + j, &root); - for (j = 0; j < NODES; j++) + for (j = 0; j < nnodes; j++) erase(nodes + j, &root); } time2 = get_cycles(); time = time2 - time1; - time = div_u64(time, PERF_LOOPS); - printk(" -> %llu cycles\n", (unsigned long long)time); + time = div_u64(time, perf_loops); + printk(" -> test 1 (latency of nnodes insert+delete): %llu cycles\n", + (unsigned long long)time); + + time1 = get_cycles(); + + for (i = 0; i < perf_loops; i++) { + for (j = 0; j < nnodes; j++) + insert_cached(nodes + j, &root); + for (j = 0; j < nnodes; j++) + erase_cached(nodes + j, &root); + } + + time2 = get_cycles(); + time = time2 - time1; + + time = div_u64(time, perf_loops); + printk(" -> test 2 (latency of nnodes cached insert+delete): %llu cycles\n", + (unsigned long long)time); + + for (i = 0; i < nnodes; i++) + insert(nodes + i, &root); + + time1 = get_cycles(); + + for (i = 0; i < perf_loops; i++) { + for (node = rb_first(&root.rb_root); node; node = rb_next(node)) + ; + } + + time2 = get_cycles(); + time = time2 - time1; + + time = div_u64(time, perf_loops); + printk(" -> test 3 (latency of inorder traversal): %llu cycles\n", + (unsigned long long)time); + + time1 = get_cycles(); + + for (i = 0; i < perf_loops; i++) + node = rb_first(&root.rb_root); + + time2 = get_cycles(); + time = time2 - time1; + + time = div_u64(time, perf_loops); + printk(" -> test 4 (latency to fetch first node)\n"); + printk(" non-cached: %llu cycles\n", (unsigned long long)time); + + time1 = get_cycles(); + + for (i = 0; i < perf_loops; i++) + node = rb_first_cached(&root); + + time2 = get_cycles(); + time = time2 - time1; + + time = div_u64(time, perf_loops); + printk(" cached: %llu cycles\n", (unsigned long long)time); - for (i = 0; i < CHECK_LOOPS; i++) { + for (i = 0; i < nnodes; i++) + erase(nodes + i, &root); + + /* run checks */ + for (i = 0; i < check_loops; i++) { init(); - for (j = 0; j < NODES; j++) { + for (j = 0; j < nnodes; j++) { check(j); insert(nodes + j, &root); } - for (j = 0; j < NODES; j++) { - check(NODES - j); + for (j = 0; j < nnodes; j++) { + check(nnodes - j); erase(nodes + j, &root); } check(0); @@ -216,32 +351,49 @@ static int __init rbtree_test_init(void) time1 = get_cycles(); - for (i = 0; i < PERF_LOOPS; i++) { - for (j = 0; j < NODES; j++) + for (i = 0; i < perf_loops; i++) { + for (j = 0; j < nnodes; j++) insert_augmented(nodes + j, &root); - for (j = 0; j < NODES; j++) + for (j = 0; j < nnodes; j++) erase_augmented(nodes + j, &root); } time2 = get_cycles(); time = time2 - time1; - time = div_u64(time, PERF_LOOPS); - printk(" -> %llu cycles\n", (unsigned long long)time); + time = div_u64(time, perf_loops); + printk(" -> test 1 (latency of nnodes insert+delete): %llu cycles\n", (unsigned long long)time); + + time1 = get_cycles(); + + for (i = 0; i < perf_loops; i++) { + for (j = 0; j < nnodes; j++) + insert_augmented_cached(nodes + j, &root); + for (j = 0; j < nnodes; j++) + erase_augmented_cached(nodes + j, &root); + } + + time2 = get_cycles(); + time = time2 - time1; + + time = div_u64(time, perf_loops); + printk(" -> test 2 (latency of nnodes cached insert+delete): %llu cycles\n", (unsigned long long)time); - for (i = 0; i < CHECK_LOOPS; i++) { + for (i = 0; i < check_loops; i++) { init(); - for (j = 0; j < NODES; j++) { + for (j = 0; j < nnodes; j++) { check_augmented(j); insert_augmented(nodes + j, &root); } - for (j = 0; j < NODES; j++) { - check_augmented(NODES - j); + for (j = 0; j < nnodes; j++) { + check_augmented(nnodes - j); erase_augmented(nodes + j, &root); } check_augmented(0); } + kfree(nodes); + return -EAGAIN; /* Fail will directly unload the module */ } diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 707ca5d677c676a599442604d918c215d7709138..ddd7dde87c3ca0db910d67a567f2a68c8d8e847e 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -735,9 +735,9 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_exit); * rhashtable_walk_start - Start a hash table walk * @iter: Hash table iterator * - * Start a hash table walk. Note that we take the RCU lock in all - * cases including when we return an error. So you must always call - * rhashtable_walk_stop to clean up. + * Start a hash table walk at the current iterator position. Note that we take + * the RCU lock in all cases including when we return an error. So you must + * always call rhashtable_walk_stop to clean up. * * Returns zero if successful. * @@ -846,7 +846,8 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_next); * rhashtable_walk_stop - Finish a hash table walk * @iter: Hash table iterator * - * Finish a hash table walk. + * Finish a hash table walk. Does not reset the iterator to the start of the + * hash table. */ void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU) diff --git a/lib/string.c b/lib/string.c index ebbb99c775bdab12e6036a85bed06d7521cf94b4..9921dc202db440a0a1b20aa19b85555e634fe3b5 100644 --- a/lib/string.c +++ b/lib/string.c @@ -723,6 +723,72 @@ void memzero_explicit(void *s, size_t count) } EXPORT_SYMBOL(memzero_explicit); +#ifndef __HAVE_ARCH_MEMSET16 +/** + * memset16() - Fill a memory area with a uint16_t + * @s: Pointer to the start of the area. + * @v: The value to fill the area with + * @count: The number of values to store + * + * Differs from memset() in that it fills with a uint16_t instead + * of a byte. Remember that @count is the number of uint16_ts to + * store, not the number of bytes. + */ +void *memset16(uint16_t *s, uint16_t v, size_t count) +{ + uint16_t *xs = s; + + while (count--) + *xs++ = v; + return s; +} +EXPORT_SYMBOL(memset16); +#endif + +#ifndef __HAVE_ARCH_MEMSET32 +/** + * memset32() - Fill a memory area with a uint32_t + * @s: Pointer to the start of the area. + * @v: The value to fill the area with + * @count: The number of values to store + * + * Differs from memset() in that it fills with a uint32_t instead + * of a byte. Remember that @count is the number of uint32_ts to + * store, not the number of bytes. + */ +void *memset32(uint32_t *s, uint32_t v, size_t count) +{ + uint32_t *xs = s; + + while (count--) + *xs++ = v; + return s; +} +EXPORT_SYMBOL(memset32); +#endif + +#ifndef __HAVE_ARCH_MEMSET64 +/** + * memset64() - Fill a memory area with a uint64_t + * @s: Pointer to the start of the area. + * @v: The value to fill the area with + * @count: The number of values to store + * + * Differs from memset() in that it fills with a uint64_t instead + * of a byte. Remember that @count is the number of uint64_ts to + * store, not the number of bytes. + */ +void *memset64(uint64_t *s, uint64_t v, size_t count) +{ + uint64_t *xs = s; + + while (count--) + *xs++ = v; + return s; +} +EXPORT_SYMBOL(memset64); +#endif + #ifndef __HAVE_ARCH_MEMCPY /** * memcpy - Copy one area of memory to another @@ -985,3 +1051,144 @@ void fortify_panic(const char *name) BUG(); } EXPORT_SYMBOL(fortify_panic); + +#ifdef CONFIG_STRING_SELFTEST +#include +#include + +static __init int memset16_selftest(void) +{ + unsigned i, j, k; + u16 v, *p; + + p = kmalloc(256 * 2 * 2, GFP_KERNEL); + if (!p) + return -1; + + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + memset(p, 0xa1, 256 * 2 * sizeof(v)); + memset16(p + i, 0xb1b2, j); + for (k = 0; k < 512; k++) { + v = p[k]; + if (k < i) { + if (v != 0xa1a1) + goto fail; + } else if (k < i + j) { + if (v != 0xb1b2) + goto fail; + } else { + if (v != 0xa1a1) + goto fail; + } + } + } + } + +fail: + kfree(p); + if (i < 256) + return (i << 24) | (j << 16) | k; + return 0; +} + +static __init int memset32_selftest(void) +{ + unsigned i, j, k; + u32 v, *p; + + p = kmalloc(256 * 2 * 4, GFP_KERNEL); + if (!p) + return -1; + + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + memset(p, 0xa1, 256 * 2 * sizeof(v)); + memset32(p + i, 0xb1b2b3b4, j); + for (k = 0; k < 512; k++) { + v = p[k]; + if (k < i) { + if (v != 0xa1a1a1a1) + goto fail; + } else if (k < i + j) { + if (v != 0xb1b2b3b4) + goto fail; + } else { + if (v != 0xa1a1a1a1) + goto fail; + } + } + } + } + +fail: + kfree(p); + if (i < 256) + return (i << 24) | (j << 16) | k; + return 0; +} + +static __init int memset64_selftest(void) +{ + unsigned i, j, k; + u64 v, *p; + + p = kmalloc(256 * 2 * 8, GFP_KERNEL); + if (!p) + return -1; + + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + memset(p, 0xa1, 256 * 2 * sizeof(v)); + memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j); + for (k = 0; k < 512; k++) { + v = p[k]; + if (k < i) { + if (v != 0xa1a1a1a1a1a1a1a1ULL) + goto fail; + } else if (k < i + j) { + if (v != 0xb1b2b3b4b5b6b7b8ULL) + goto fail; + } else { + if (v != 0xa1a1a1a1a1a1a1a1ULL) + goto fail; + } + } + } + } + +fail: + kfree(p); + if (i < 256) + return (i << 24) | (j << 16) | k; + return 0; +} + +static __init int string_selftest_init(void) +{ + int test, subtest; + + test = 1; + subtest = memset16_selftest(); + if (subtest) + goto fail; + + test = 2; + subtest = memset32_selftest(); + if (subtest) + goto fail; + + test = 3; + subtest = memset64_selftest(); + if (subtest) + goto fail; + + pr_info("String selftests succeeded\n"); + return 0; +fail: + pr_crit("String selftest failure %d.%08x\n", test, subtest); + return 0; +} + +module_init(string_selftest_init); +#endif /* CONFIG_STRING_SELFTEST */ diff --git a/lib/string_helpers.c b/lib/string_helpers.c index ecaac2c0526fcaf555fff4d22ecbd172d933e7bd..29c490e5d47858ce18da95d63608a147f9b1ecd7 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -576,7 +576,7 @@ char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp) char *buffer, *quoted; int i, res; - buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY); + buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buffer) return NULL; @@ -612,7 +612,7 @@ char *kstrdup_quotable_file(struct file *file, gfp_t gfp) return kstrdup("", gfp); /* We add 11 spaces for ' (deleted)' to be appended */ - temp = kmalloc(PATH_MAX + 11, GFP_TEMPORARY); + temp = kmalloc(PATH_MAX + 11, GFP_KERNEL); if (!temp) return kstrdup("", gfp); diff --git a/lib/swiotlb.c b/lib/swiotlb.c index a8d74a733a38b54a912f5e292f0a15a2cfff4a95..8c6c83ef57a43336e0a33a52f691e3323eb8f3f4 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,15 @@ unsigned long swiotlb_size_or_default(void) return size ? size : (IO_TLB_DEFAULT_SIZE); } +void __weak swiotlb_set_mem_attributes(void *vaddr, unsigned long size) { } + +/* For swiotlb, clear memory encryption mask from dma addresses */ +static dma_addr_t swiotlb_phys_to_dma(struct device *hwdev, + phys_addr_t address) +{ + return __sme_clr(phys_to_dma(hwdev, address)); +} + /* Note that this doesn't work with highmem page */ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, volatile void *address) @@ -183,6 +193,31 @@ void swiotlb_print_info(void) bytes >> 20, vstart, vend - 1); } +/* + * Early SWIOTLB allocation may be too early to allow an architecture to + * perform the desired operations. This function allows the architecture to + * call SWIOTLB when the operations are possible. It needs to be called + * before the SWIOTLB memory is used. + */ +void __init swiotlb_update_mem_attributes(void) +{ + void *vaddr; + unsigned long bytes; + + if (no_iotlb_memory || late_alloc) + return; + + vaddr = phys_to_virt(io_tlb_start); + bytes = PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT); + swiotlb_set_mem_attributes(vaddr, bytes); + memset(vaddr, 0, bytes); + + vaddr = phys_to_virt(io_tlb_overflow_buffer); + bytes = PAGE_ALIGN(io_tlb_overflow); + swiotlb_set_mem_attributes(vaddr, bytes); + memset(vaddr, 0, bytes); +} + int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) { void *v_overflow_buffer; @@ -320,6 +355,7 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) io_tlb_start = virt_to_phys(tlb); io_tlb_end = io_tlb_start + bytes; + swiotlb_set_mem_attributes(tlb, bytes); memset(tlb, 0, bytes); /* @@ -330,6 +366,8 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) if (!v_overflow_buffer) goto cleanup2; + swiotlb_set_mem_attributes(v_overflow_buffer, io_tlb_overflow); + memset(v_overflow_buffer, 0, io_tlb_overflow); io_tlb_overflow_buffer = virt_to_phys(v_overflow_buffer); /* @@ -469,6 +507,9 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, if (no_iotlb_memory) panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer"); + if (sme_active()) + pr_warn_once("SME is active and system is using DMA bounce buffers\n"); + mask = dma_get_seg_boundary(hwdev); tbl_dma_addr &= mask; @@ -581,7 +622,7 @@ map_single(struct device *hwdev, phys_addr_t phys, size_t size, return SWIOTLB_MAP_ERROR; } - start_dma_addr = phys_to_dma(hwdev, io_tlb_start); + start_dma_addr = swiotlb_phys_to_dma(hwdev, io_tlb_start); return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, dir, attrs); } @@ -702,7 +743,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, goto err_warn; ret = phys_to_virt(paddr); - dev_addr = phys_to_dma(hwdev, paddr); + dev_addr = swiotlb_phys_to_dma(hwdev, paddr); /* Confirm address can be DMA'd by device */ if (dev_addr + size - 1 > dma_mask) { @@ -812,10 +853,10 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, map = map_single(dev, phys, size, dir, attrs); if (map == SWIOTLB_MAP_ERROR) { swiotlb_full(dev, size, dir, 1); - return phys_to_dma(dev, io_tlb_overflow_buffer); + return swiotlb_phys_to_dma(dev, io_tlb_overflow_buffer); } - dev_addr = phys_to_dma(dev, map); + dev_addr = swiotlb_phys_to_dma(dev, map); /* Ensure that the address returned is DMA'ble */ if (dma_capable(dev, dev_addr, size)) @@ -824,7 +865,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, attrs |= DMA_ATTR_SKIP_CPU_SYNC; swiotlb_tbl_unmap_single(dev, map, size, dir, attrs); - return phys_to_dma(dev, io_tlb_overflow_buffer); + return swiotlb_phys_to_dma(dev, io_tlb_overflow_buffer); } EXPORT_SYMBOL_GPL(swiotlb_map_page); @@ -958,7 +999,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, sg_dma_len(sgl) = 0; return 0; } - sg->dma_address = phys_to_dma(hwdev, map); + sg->dma_address = swiotlb_phys_to_dma(hwdev, map); } else sg->dma_address = dev_addr; sg_dma_len(sg) = sg->length; @@ -1026,7 +1067,7 @@ EXPORT_SYMBOL(swiotlb_sync_sg_for_device); int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) { - return (dma_addr == phys_to_dma(hwdev, io_tlb_overflow_buffer)); + return (dma_addr == swiotlb_phys_to_dma(hwdev, io_tlb_overflow_buffer)); } EXPORT_SYMBOL(swiotlb_dma_mapping_error); @@ -1039,6 +1080,6 @@ EXPORT_SYMBOL(swiotlb_dma_mapping_error); int swiotlb_dma_supported(struct device *hwdev, u64 mask) { - return phys_to_dma(hwdev, io_tlb_end - 1) <= mask; + return swiotlb_phys_to_dma(hwdev, io_tlb_end - 1) <= mask; } EXPORT_SYMBOL(swiotlb_dma_supported); diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index 2526a2975c51bc24e329bdd542b3dd2b0ebfbdec..aa1f2669bdd5d83663994ef04ca0d26b634e8e5f 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -165,6 +165,96 @@ static void __init test_zero_fill_copy(void) expect_eq_pbl("128-1023", bmap2, 1024); } +#define PARSE_TIME 0x1 + +struct test_bitmap_parselist{ + const int errno; + const char *in; + const unsigned long *expected; + const int nbits; + const int flags; +}; + +static const unsigned long exp[] __initconst = { + BITMAP_FROM_U64(1), + BITMAP_FROM_U64(2), + BITMAP_FROM_U64(0x0000ffff), + BITMAP_FROM_U64(0xffff0000), + BITMAP_FROM_U64(0x55555555), + BITMAP_FROM_U64(0xaaaaaaaa), + BITMAP_FROM_U64(0x11111111), + BITMAP_FROM_U64(0x22222222), + BITMAP_FROM_U64(0xffffffff), + BITMAP_FROM_U64(0xfffffffe), + BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0xffffffff77777777ULL) +}; + +static const unsigned long exp2[] __initconst = { + BITMAP_FROM_U64(0x3333333311111111ULL), + BITMAP_FROM_U64(0xffffffff77777777ULL) +}; + +static const struct test_bitmap_parselist parselist_tests[] __initconst = { +#define step (sizeof(u64) / sizeof(unsigned long)) + + {0, "0", &exp[0], 8, 0}, + {0, "1", &exp[1 * step], 8, 0}, + {0, "0-15", &exp[2 * step], 32, 0}, + {0, "16-31", &exp[3 * step], 32, 0}, + {0, "0-31:1/2", &exp[4 * step], 32, 0}, + {0, "1-31:1/2", &exp[5 * step], 32, 0}, + {0, "0-31:1/4", &exp[6 * step], 32, 0}, + {0, "1-31:1/4", &exp[7 * step], 32, 0}, + {0, "0-31:4/4", &exp[8 * step], 32, 0}, + {0, "1-31:4/4", &exp[9 * step], 32, 0}, + {0, "0-31:1/4,32-63:2/4", &exp[10 * step], 64, 0}, + {0, "0-31:3/4,32-63:4/4", &exp[11 * step], 64, 0}, + + {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4", exp2, 128, 0}, + + {0, "0-2047:128/256", NULL, 2048, PARSE_TIME}, + + {-EINVAL, "-1", NULL, 8, 0}, + {-EINVAL, "-0", NULL, 8, 0}, + {-EINVAL, "10-1", NULL, 8, 0}, + {-EINVAL, "0-31:10/1", NULL, 8, 0}, +}; + +static void __init test_bitmap_parselist(void) +{ + int i; + int err; + cycles_t cycles; + DECLARE_BITMAP(bmap, 2048); + + for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) { +#define ptest parselist_tests[i] + + cycles = get_cycles(); + err = bitmap_parselist(ptest.in, bmap, ptest.nbits); + cycles = get_cycles() - cycles; + + if (err != ptest.errno) { + pr_err("test %d: input is %s, errno is %d, expected %d\n", + i, ptest.in, err, ptest.errno); + continue; + } + + if (!err && ptest.expected + && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) { + pr_err("test %d: input is %s, result is 0x%lx, expected 0x%lx\n", + i, ptest.in, bmap[0], *ptest.expected); + continue; + } + + if (ptest.flags & PARSE_TIME) + pr_err("test %d: input is '%s' OK, Time: %llu\n", + i, ptest.in, + (unsigned long long)cycles); + } +} + static void __init test_bitmap_u32_array_conversions(void) { DECLARE_BITMAP(bmap1, 1024); @@ -365,6 +455,7 @@ static int __init test_bitmap_init(void) { test_zero_fill_copy(); test_bitmap_u32_array_conversions(); + test_bitmap_parselist(); test_mem_optimisations(); if (failed_tests == 0) diff --git a/lib/test_bpf.c b/lib/test_bpf.c index d9d5a410955c948b4e923d729417bc9dbb91e514..aa8812ae6776ee31712fe88c58da4048ff9c31e4 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -951,6 +951,32 @@ static struct bpf_test tests[] = { { 4, 4, 4, 3, 3 }, { { 2, 0 }, { 3, 1 }, { 4, MAX_K } }, }, + { + "JGE (jt 0), test 1", + .u.insns = { + BPF_STMT(BPF_LDX | BPF_LEN, 0), + BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2), + BPF_JUMP(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET | BPF_K, 1), + BPF_STMT(BPF_RET | BPF_K, MAX_K) + }, + CLASSIC, + { 4, 4, 4, 3, 3 }, + { { 2, 0 }, { 3, 1 }, { 4, 1 } }, + }, + { + "JGE (jt 0), test 2", + .u.insns = { + BPF_STMT(BPF_LDX | BPF_LEN, 0), + BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2), + BPF_JUMP(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET | BPF_K, 1), + BPF_STMT(BPF_RET | BPF_K, MAX_K) + }, + CLASSIC, + { 4, 4, 5, 3, 3 }, + { { 4, 1 }, { 5, 1 }, { 6, MAX_K } }, + }, { "JGE", .u.insns = { @@ -4492,6 +4518,35 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JSLT | BPF_K */ + { + "JMP_JSLT_K: Signed jump: if (-2 < -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 0xfffffffffffffffeLL), + BPF_JMP_IMM(BPF_JSLT, R1, -1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JSLT_K: Signed jump: if (-1 < -1) return 0", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_LD_IMM64(R1, 0xffffffffffffffffLL), + BPF_JMP_IMM(BPF_JSLT, R1, -1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JSGT | BPF_K */ { "JMP_JSGT_K: Signed jump: if (-1 > -2) return 1", @@ -4521,6 +4576,73 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JSLE | BPF_K */ + { + "JMP_JSLE_K: Signed jump: if (-2 <= -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 0xfffffffffffffffeLL), + BPF_JMP_IMM(BPF_JSLE, R1, -1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JSLE_K: Signed jump: if (-1 <= -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 0xffffffffffffffffLL), + BPF_JMP_IMM(BPF_JSLE, R1, -1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JSLE_K: Signed jump: value walk 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 6), + BPF_ALU64_IMM(BPF_SUB, R1, 1), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 4), + BPF_ALU64_IMM(BPF_SUB, R1, 1), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 2), + BPF_ALU64_IMM(BPF_SUB, R1, 1), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 1), + BPF_EXIT_INSN(), /* bad exit */ + BPF_ALU32_IMM(BPF_MOV, R0, 1), /* good exit */ + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JSLE_K: Signed jump: value walk 2", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 4), + BPF_ALU64_IMM(BPF_SUB, R1, 2), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 2), + BPF_ALU64_IMM(BPF_SUB, R1, 2), + BPF_JMP_IMM(BPF_JSLE, R1, 0, 1), + BPF_EXIT_INSN(), /* bad exit */ + BPF_ALU32_IMM(BPF_MOV, R0, 1), /* good exit */ + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JSGE | BPF_K */ { "JMP_JSGE_K: Signed jump: if (-1 >= -2) return 1", @@ -4617,6 +4739,35 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JLT | BPF_K */ + { + "JMP_JLT_K: if (2 < 3) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 2), + BPF_JMP_IMM(BPF_JLT, R1, 3, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JGT_K: Unsigned jump: if (1 < -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 1), + BPF_JMP_IMM(BPF_JLT, R1, -1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JGE | BPF_K */ { "JMP_JGE_K: if (3 >= 2) return 1", @@ -4632,6 +4783,21 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JLE | BPF_K */ + { + "JMP_JLE_K: if (2 <= 3) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 2), + BPF_JMP_IMM(BPF_JLE, R1, 3, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JGT | BPF_K jump backwards */ { "JMP_JGT_K: if (3 > 2) return 1 (jump backwards)", @@ -4662,6 +4828,36 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JLT | BPF_K jump backwards */ + { + "JMP_JGT_K: if (2 < 3) return 1 (jump backwards)", + .u.insns_int = { + BPF_JMP_IMM(BPF_JA, 0, 0, 2), /* goto start */ + BPF_ALU32_IMM(BPF_MOV, R0, 1), /* out: */ + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 0), /* start: */ + BPF_LD_IMM64(R1, 2), /* note: this takes 2 insns */ + BPF_JMP_IMM(BPF_JLT, R1, 3, -6), /* goto out */ + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JLE_K: if (3 <= 3) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_JMP_IMM(BPF_JLE, R1, 3, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JNE | BPF_K */ { "JMP_JNE_K: if (3 != 2) return 1", @@ -4752,6 +4948,37 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JSLT | BPF_X */ + { + "JMP_JSLT_X: Signed jump: if (-2 < -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, -1), + BPF_LD_IMM64(R2, -2), + BPF_JMP_REG(BPF_JSLT, R2, R1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JSLT_X: Signed jump: if (-1 < -1) return 0", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_LD_IMM64(R1, -1), + BPF_LD_IMM64(R2, -1), + BPF_JMP_REG(BPF_JSLT, R1, R2, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JSGE | BPF_X */ { "JMP_JSGE_X: Signed jump: if (-1 >= -2) return 1", @@ -4783,6 +5010,37 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JSLE | BPF_X */ + { + "JMP_JSLE_X: Signed jump: if (-2 <= -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, -1), + BPF_LD_IMM64(R2, -2), + BPF_JMP_REG(BPF_JSLE, R2, R1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JSLE_X: Signed jump: if (-1 <= -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, -1), + BPF_LD_IMM64(R2, -1), + BPF_JMP_REG(BPF_JSLE, R1, R2, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JGT | BPF_X */ { "JMP_JGT_X: if (3 > 2) return 1", @@ -4814,6 +5072,37 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JLT | BPF_X */ + { + "JMP_JLT_X: if (2 < 3) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_LD_IMM64(R2, 2), + BPF_JMP_REG(BPF_JLT, R2, R1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JLT_X: Unsigned jump: if (1 < -1) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, -1), + BPF_LD_IMM64(R2, 1), + BPF_JMP_REG(BPF_JLT, R2, R1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JGE | BPF_X */ { "JMP_JGE_X: if (3 >= 2) return 1", @@ -4845,6 +5134,37 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + /* BPF_JMP | BPF_JLE | BPF_X */ + { + "JMP_JLE_X: if (2 <= 3) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_LD_IMM64(R2, 2), + BPF_JMP_REG(BPF_JLE, R2, R1, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, + { + "JMP_JLE_X: if (3 <= 3) return 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_LD_IMM64(R2, 3), + BPF_JMP_REG(BPF_JLE, R1, R2, 1), + BPF_EXIT_INSN(), + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, { /* Mainly testing JIT + imm64 here. */ "JMP_JGE_X: ldimm64 test 1", @@ -4890,6 +5210,50 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } }, }, + { + "JMP_JLE_X: ldimm64 test 1", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_LD_IMM64(R2, 2), + BPF_JMP_REG(BPF_JLE, R2, R1, 2), + BPF_LD_IMM64(R0, 0xffffffffffffffffULL), + BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeULL), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 0xeeeeeeeeU } }, + }, + { + "JMP_JLE_X: ldimm64 test 2", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 0), + BPF_LD_IMM64(R1, 3), + BPF_LD_IMM64(R2, 2), + BPF_JMP_REG(BPF_JLE, R2, R1, 0), + BPF_LD_IMM64(R0, 0xffffffffffffffffULL), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 0xffffffffU } }, + }, + { + "JMP_JLE_X: ldimm64 test 3", + .u.insns_int = { + BPF_ALU32_IMM(BPF_MOV, R0, 1), + BPF_LD_IMM64(R1, 3), + BPF_LD_IMM64(R2, 2), + BPF_JMP_REG(BPF_JLE, R2, R1, 4), + BPF_LD_IMM64(R0, 0xffffffffffffffffULL), + BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeULL), + BPF_EXIT_INSN(), + }, + INTERNAL, + { }, + { { 0, 1 } }, + }, /* BPF_JMP | BPF_JNE | BPF_X */ { "JMP_JNE_X: if (3 != 2) return 1", diff --git a/lib/test_debug_virtual.c b/lib/test_debug_virtual.c new file mode 100644 index 0000000000000000000000000000000000000000..b9cdeecc19dc303f0167433457f41f5325684f6a --- /dev/null +++ b/lib/test_debug_virtual.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef CONFIG_MIPS +#include +#endif + +struct foo { + unsigned int bar; +}; + +struct foo *foo; + +static int __init test_debug_virtual_init(void) +{ + phys_addr_t pa; + void *va; + + va = (void *)VMALLOC_START; + pa = virt_to_phys(va); + + pr_info("PA: %pa for VA: 0x%lx\n", &pa, (unsigned long)va); + + foo = kzalloc(sizeof(*foo), GFP_KERNEL); + if (!foo) + return -ENOMEM; + + pa = virt_to_phys(foo); + va = foo; + pr_info("PA: %pa for VA: 0x%lx\n", &pa, (unsigned long)va); + + return 0; +} +module_init(test_debug_virtual_init); + +static void __exit test_debug_virtual_exit(void) +{ + kfree(foo); +} +module_exit(test_debug_virtual_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Test module for CONFIG_DEBUG_VIRTUAL"); diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 09371b0a9bafb5443de9664c767d62315bdcdd1b..64a4c76cba2ba8de3b072e89c0e16788ce131894 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -19,10 +19,85 @@ #include #include #include +#include +#include + +#define TEST_FIRMWARE_NAME "test-firmware.bin" +#define TEST_FIRMWARE_NUM_REQS 4 static DEFINE_MUTEX(test_fw_mutex); static const struct firmware *test_firmware; +struct test_batched_req { + u8 idx; + int rc; + bool sent; + const struct firmware *fw; + const char *name; + struct completion completion; + struct task_struct *task; + struct device *dev; +}; + +/** + * test_config - represents configuration for the test for different triggers + * + * @name: the name of the firmware file to look for + * @sync_direct: when the sync trigger is used if this is true + * request_firmware_direct() will be used instead. + * @send_uevent: whether or not to send a uevent for async requests + * @num_requests: number of requests to try per test case. This is trigger + * specific. + * @reqs: stores all requests information + * @read_fw_idx: index of thread from which we want to read firmware results + * from through the read_fw trigger. + * @test_result: a test may use this to collect the result from the call + * of the request_firmware*() calls used in their tests. In order of + * priority we always keep first any setup error. If no setup errors were + * found then we move on to the first error encountered while running the + * API. Note that for async calls this typically will be a successful + * result (0) unless of course you've used bogus parameters, or the system + * is out of memory. In the async case the callback is expected to do a + * bit more homework to figure out what happened, unfortunately the only + * information passed today on error is the fact that no firmware was + * found so we can only assume -ENOENT on async calls if the firmware is + * NULL. + * + * Errors you can expect: + * + * API specific: + * + * 0: success for sync, for async it means request was sent + * -EINVAL: invalid parameters or request + * -ENOENT: files not found + * + * System environment: + * + * -ENOMEM: memory pressure on system + * -ENODEV: out of number of devices to test + * -EINVAL: an unexpected error has occurred + * @req_firmware: if @sync_direct is true this is set to + * request_firmware_direct(), otherwise request_firmware() + */ +struct test_config { + char *name; + bool sync_direct; + bool send_uevent; + u8 num_requests; + u8 read_fw_idx; + + /* + * These below don't belong her but we'll move them once we create + * a struct fw_test_device and stuff the misc_dev under there later. + */ + struct test_batched_req *reqs; + int test_result; + int (*req_firmware)(const struct firmware **fw, const char *name, + struct device *device); +}; + +struct test_config *test_fw_config; + static ssize_t test_fw_misc_read(struct file *f, char __user *buf, size_t size, loff_t *offset) { @@ -42,6 +117,338 @@ static const struct file_operations test_fw_fops = { .read = test_fw_misc_read, }; +static void __test_release_all_firmware(void) +{ + struct test_batched_req *req; + u8 i; + + if (!test_fw_config->reqs) + return; + + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; + if (req->fw) + release_firmware(req->fw); + } + + vfree(test_fw_config->reqs); + test_fw_config->reqs = NULL; +} + +static void test_release_all_firmware(void) +{ + mutex_lock(&test_fw_mutex); + __test_release_all_firmware(); + mutex_unlock(&test_fw_mutex); +} + + +static void __test_firmware_config_free(void) +{ + __test_release_all_firmware(); + kfree_const(test_fw_config->name); + test_fw_config->name = NULL; +} + +/* + * XXX: move to kstrncpy() once merged. + * + * Users should use kfree_const() when freeing these. + */ +static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp) +{ + *dst = kstrndup(name, count, gfp); + if (!*dst) + return -ENOSPC; + return count; +} + +static int __test_firmware_config_init(void) +{ + int ret; + + ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME, + strlen(TEST_FIRMWARE_NAME), GFP_KERNEL); + if (ret < 0) + goto out; + + test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS; + test_fw_config->send_uevent = true; + test_fw_config->sync_direct = false; + test_fw_config->req_firmware = request_firmware; + test_fw_config->test_result = 0; + test_fw_config->reqs = NULL; + + return 0; + +out: + __test_firmware_config_free(); + return ret; +} + +static ssize_t reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + + mutex_lock(&test_fw_mutex); + + __test_firmware_config_free(); + + ret = __test_firmware_config_init(); + if (ret < 0) { + ret = -ENOMEM; + pr_err("could not alloc settings for config trigger: %d\n", + ret); + goto out; + } + + pr_info("reset\n"); + ret = count; + +out: + mutex_unlock(&test_fw_mutex); + + return ret; +} +static DEVICE_ATTR_WO(reset); + +static ssize_t config_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int len = 0; + + mutex_lock(&test_fw_mutex); + + len += snprintf(buf, PAGE_SIZE, + "Custom trigger configuration for: %s\n", + dev_name(dev)); + + if (test_fw_config->name) + len += snprintf(buf+len, PAGE_SIZE, + "name:\t%s\n", + test_fw_config->name); + else + len += snprintf(buf+len, PAGE_SIZE, + "name:\tEMTPY\n"); + + len += snprintf(buf+len, PAGE_SIZE, + "num_requests:\t%u\n", test_fw_config->num_requests); + + len += snprintf(buf+len, PAGE_SIZE, + "send_uevent:\t\t%s\n", + test_fw_config->send_uevent ? + "FW_ACTION_HOTPLUG" : + "FW_ACTION_NOHOTPLUG"); + len += snprintf(buf+len, PAGE_SIZE, + "sync_direct:\t\t%s\n", + test_fw_config->sync_direct ? "true" : "false"); + len += snprintf(buf+len, PAGE_SIZE, + "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx); + + mutex_unlock(&test_fw_mutex); + + return len; +} +static DEVICE_ATTR_RO(config); + +static ssize_t config_name_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + + mutex_lock(&test_fw_mutex); + kfree_const(test_fw_config->name); + ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL); + mutex_unlock(&test_fw_mutex); + + return ret; +} + +/* + * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE. + */ +static ssize_t config_test_show_str(char *dst, + char *src) +{ + int len; + + mutex_lock(&test_fw_mutex); + len = snprintf(dst, PAGE_SIZE, "%s\n", src); + mutex_unlock(&test_fw_mutex); + + return len; +} + +static int test_dev_config_update_bool(const char *buf, size_t size, + bool *cfg) +{ + int ret; + + mutex_lock(&test_fw_mutex); + if (strtobool(buf, cfg) < 0) + ret = -EINVAL; + else + ret = size; + mutex_unlock(&test_fw_mutex); + + return ret; +} + +static ssize_t +test_dev_config_show_bool(char *buf, + bool config) +{ + bool val; + + mutex_lock(&test_fw_mutex); + val = config; + mutex_unlock(&test_fw_mutex); + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t test_dev_config_show_int(char *buf, int cfg) +{ + int val; + + mutex_lock(&test_fw_mutex); + val = cfg; + mutex_unlock(&test_fw_mutex); + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg) +{ + int ret; + long new; + + ret = kstrtol(buf, 10, &new); + if (ret) + return ret; + + if (new > U8_MAX) + return -EINVAL; + + mutex_lock(&test_fw_mutex); + *(u8 *)cfg = new; + mutex_unlock(&test_fw_mutex); + + /* Always return full write size even if we didn't consume all */ + return size; +} + +static ssize_t test_dev_config_show_u8(char *buf, u8 cfg) +{ + u8 val; + + mutex_lock(&test_fw_mutex); + val = cfg; + mutex_unlock(&test_fw_mutex); + + return snprintf(buf, PAGE_SIZE, "%u\n", val); +} + +static ssize_t config_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return config_test_show_str(buf, test_fw_config->name); +} +static DEVICE_ATTR(config_name, 0644, config_name_show, config_name_store); + +static ssize_t config_num_requests_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc; + + mutex_lock(&test_fw_mutex); + if (test_fw_config->reqs) { + pr_err("Must call release_all_firmware prior to changing config\n"); + rc = -EINVAL; + goto out; + } + mutex_unlock(&test_fw_mutex); + + rc = test_dev_config_update_u8(buf, count, + &test_fw_config->num_requests); + +out: + return rc; +} + +static ssize_t config_num_requests_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return test_dev_config_show_u8(buf, test_fw_config->num_requests); +} +static DEVICE_ATTR(config_num_requests, 0644, config_num_requests_show, + config_num_requests_store); + +static ssize_t config_sync_direct_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = test_dev_config_update_bool(buf, count, + &test_fw_config->sync_direct); + + if (rc == count) + test_fw_config->req_firmware = test_fw_config->sync_direct ? + request_firmware_direct : + request_firmware; + return rc; +} + +static ssize_t config_sync_direct_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return test_dev_config_show_bool(buf, test_fw_config->sync_direct); +} +static DEVICE_ATTR(config_sync_direct, 0644, config_sync_direct_show, + config_sync_direct_store); + +static ssize_t config_send_uevent_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return test_dev_config_update_bool(buf, count, + &test_fw_config->send_uevent); +} + +static ssize_t config_send_uevent_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return test_dev_config_show_bool(buf, test_fw_config->send_uevent); +} +static DEVICE_ATTR(config_send_uevent, 0644, config_send_uevent_show, + config_send_uevent_store); + +static ssize_t config_read_fw_idx_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return test_dev_config_update_u8(buf, count, + &test_fw_config->read_fw_idx); +} + +static ssize_t config_read_fw_idx_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx); +} +static DEVICE_ATTR(config_read_fw_idx, 0644, config_read_fw_idx_show, + config_read_fw_idx_store); + + static ssize_t trigger_request_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -170,12 +577,301 @@ static ssize_t trigger_custom_fallback_store(struct device *dev, } static DEVICE_ATTR_WO(trigger_custom_fallback); +static int test_fw_run_batch_request(void *data) +{ + struct test_batched_req *req = data; + + if (!req) { + test_fw_config->test_result = -EINVAL; + return -EINVAL; + } + + req->rc = test_fw_config->req_firmware(&req->fw, req->name, req->dev); + if (req->rc) { + pr_info("#%u: batched sync load failed: %d\n", + req->idx, req->rc); + if (!test_fw_config->test_result) + test_fw_config->test_result = req->rc; + } else if (req->fw) { + req->sent = true; + pr_info("#%u: batched sync loaded %zu\n", + req->idx, req->fw->size); + } + complete(&req->completion); + + req->task = NULL; + + return 0; +} + +/* + * We use a kthread as otherwise the kernel serializes all our sync requests + * and we would not be able to mimic batched requests on a sync call. Batched + * requests on a sync call can for instance happen on a device driver when + * multiple cards are used and firmware loading happens outside of probe. + */ +static ssize_t trigger_batched_requests_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct test_batched_req *req; + int rc; + u8 i; + + mutex_lock(&test_fw_mutex); + + test_fw_config->reqs = vzalloc(sizeof(struct test_batched_req) * + test_fw_config->num_requests * 2); + if (!test_fw_config->reqs) { + rc = -ENOMEM; + goto out_unlock; + } + + pr_info("batched sync firmware loading '%s' %u times\n", + test_fw_config->name, test_fw_config->num_requests); + + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; + if (!req) { + WARN_ON(1); + rc = -ENOMEM; + goto out_bail; + } + req->fw = NULL; + req->idx = i; + req->name = test_fw_config->name; + req->dev = dev; + init_completion(&req->completion); + req->task = kthread_run(test_fw_run_batch_request, req, + "%s-%u", KBUILD_MODNAME, req->idx); + if (!req->task || IS_ERR(req->task)) { + pr_err("Setting up thread %u failed\n", req->idx); + req->task = NULL; + rc = -ENOMEM; + goto out_bail; + } + } + + rc = count; + + /* + * We require an explicit release to enable more time and delay of + * calling release_firmware() to improve our chances of forcing a + * batched request. If we instead called release_firmware() right away + * then we might miss on an opportunity of having a successful firmware + * request pass on the opportunity to be come a batched request. + */ + +out_bail: + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; + if (req->task || req->sent) + wait_for_completion(&req->completion); + } + + /* Override any worker error if we had a general setup error */ + if (rc < 0) + test_fw_config->test_result = rc; + +out_unlock: + mutex_unlock(&test_fw_mutex); + + return rc; +} +static DEVICE_ATTR_WO(trigger_batched_requests); + +/* + * We wait for each callback to return with the lock held, no need to lock here + */ +static void trigger_batched_cb(const struct firmware *fw, void *context) +{ + struct test_batched_req *req = context; + + if (!req) { + test_fw_config->test_result = -EINVAL; + return; + } + + /* forces *some* batched requests to queue up */ + if (!req->idx) + ssleep(2); + + req->fw = fw; + + /* + * Unfortunately the firmware API gives us nothing other than a null FW + * if the firmware was not found on async requests. Best we can do is + * just assume -ENOENT. A better API would pass the actual return + * value to the callback. + */ + if (!fw && !test_fw_config->test_result) + test_fw_config->test_result = -ENOENT; + + complete(&req->completion); +} + +static +ssize_t trigger_batched_requests_async_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct test_batched_req *req; + bool send_uevent; + int rc; + u8 i; + + mutex_lock(&test_fw_mutex); + + test_fw_config->reqs = vzalloc(sizeof(struct test_batched_req) * + test_fw_config->num_requests * 2); + if (!test_fw_config->reqs) { + rc = -ENOMEM; + goto out; + } + + pr_info("batched loading '%s' custom fallback mechanism %u times\n", + test_fw_config->name, test_fw_config->num_requests); + + send_uevent = test_fw_config->send_uevent ? FW_ACTION_HOTPLUG : + FW_ACTION_NOHOTPLUG; + + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; + if (!req) { + WARN_ON(1); + goto out_bail; + } + req->name = test_fw_config->name; + req->fw = NULL; + req->idx = i; + init_completion(&req->completion); + rc = request_firmware_nowait(THIS_MODULE, send_uevent, + req->name, + dev, GFP_KERNEL, req, + trigger_batched_cb); + if (rc) { + pr_info("#%u: batched async load failed setup: %d\n", + i, rc); + req->rc = rc; + goto out_bail; + } else + req->sent = true; + } + + rc = count; + +out_bail: + + /* + * We require an explicit release to enable more time and delay of + * calling release_firmware() to improve our chances of forcing a + * batched request. If we instead called release_firmware() right away + * then we might miss on an opportunity of having a successful firmware + * request pass on the opportunity to be come a batched request. + */ + + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; + if (req->sent) + wait_for_completion(&req->completion); + } + + /* Override any worker error if we had a general setup error */ + if (rc < 0) + test_fw_config->test_result = rc; + +out: + mutex_unlock(&test_fw_mutex); + + return rc; +} +static DEVICE_ATTR_WO(trigger_batched_requests_async); + +static ssize_t test_result_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return test_dev_config_show_int(buf, test_fw_config->test_result); +} +static DEVICE_ATTR_RO(test_result); + +static ssize_t release_all_firmware_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + test_release_all_firmware(); + return count; +} +static DEVICE_ATTR_WO(release_all_firmware); + +static ssize_t read_firmware_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct test_batched_req *req; + u8 idx; + ssize_t rc = 0; + + mutex_lock(&test_fw_mutex); + + idx = test_fw_config->read_fw_idx; + if (idx >= test_fw_config->num_requests) { + rc = -ERANGE; + goto out; + } + + if (!test_fw_config->reqs) { + rc = -EINVAL; + goto out; + } + + req = &test_fw_config->reqs[idx]; + if (!req->fw) { + pr_err("#%u: failed to async load firmware\n", idx); + rc = -ENOENT; + goto out; + } + + pr_info("#%u: loaded %zu\n", idx, req->fw->size); + + if (req->fw->size > PAGE_SIZE) { + pr_err("Testing interface must use PAGE_SIZE firmware for now\n"); + rc = -EINVAL; + } + memcpy(buf, req->fw->data, req->fw->size); + + rc = req->fw->size; +out: + mutex_unlock(&test_fw_mutex); + + return rc; +} +static DEVICE_ATTR_RO(read_firmware); + #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr static struct attribute *test_dev_attrs[] = { + TEST_FW_DEV_ATTR(reset), + + TEST_FW_DEV_ATTR(config), + TEST_FW_DEV_ATTR(config_name), + TEST_FW_DEV_ATTR(config_num_requests), + TEST_FW_DEV_ATTR(config_sync_direct), + TEST_FW_DEV_ATTR(config_send_uevent), + TEST_FW_DEV_ATTR(config_read_fw_idx), + + /* These don't use the config at all - they could be ported! */ TEST_FW_DEV_ATTR(trigger_request), TEST_FW_DEV_ATTR(trigger_async_request), TEST_FW_DEV_ATTR(trigger_custom_fallback), + + /* These use the config and can use the test_result */ + TEST_FW_DEV_ATTR(trigger_batched_requests), + TEST_FW_DEV_ATTR(trigger_batched_requests_async), + + TEST_FW_DEV_ATTR(release_all_firmware), + TEST_FW_DEV_ATTR(test_result), + TEST_FW_DEV_ATTR(read_firmware), NULL, }; @@ -192,8 +888,17 @@ static int __init test_firmware_init(void) { int rc; + test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL); + if (!test_fw_config) + return -ENOMEM; + + rc = __test_firmware_config_init(); + if (rc) + return rc; + rc = misc_register(&test_fw_misc_device); if (rc) { + kfree(test_fw_config); pr_err("could not register misc device: %d\n", rc); return rc; } @@ -207,8 +912,13 @@ module_init(test_firmware_init); static void __exit test_firmware_exit(void) { + mutex_lock(&test_fw_mutex); release_firmware(test_firmware); misc_deregister(&test_fw_misc_device); + __test_firmware_config_free(); + kfree(test_fw_config); + mutex_unlock(&test_fw_mutex); + pr_warn("removed interface\n"); } diff --git a/lib/test_kmod.c b/lib/test_kmod.c index 6c1d678bcf8b00ff7b2d2fc70747045e6c14327a..fba78d25e82569e57845d16b36c271d0848099b0 100644 --- a/lib/test_kmod.c +++ b/lib/test_kmod.c @@ -485,7 +485,7 @@ static ssize_t config_show(struct device *dev, config->test_driver); else len += snprintf(buf+len, PAGE_SIZE - len, - "driver:\tEMTPY\n"); + "driver:\tEMPTY\n"); if (config->test_fs) len += snprintf(buf+len, PAGE_SIZE - len, @@ -493,7 +493,7 @@ static ssize_t config_show(struct device *dev, config->test_fs); else len += snprintf(buf+len, PAGE_SIZE - len, - "fs:\tEMTPY\n"); + "fs:\tEMPTY\n"); mutex_unlock(&test_dev->config_mutex); @@ -746,11 +746,11 @@ static int trigger_config_run_type(struct kmod_test_device *test_dev, strlen(test_str)); break; case TEST_KMOD_FS_TYPE: - break; kfree_const(config->test_fs); config->test_driver = NULL; copied = config_copy_test_fs(config, test_str, strlen(test_str)); + break; default: mutex_unlock(&test_dev->config_mutex); return -EINVAL; @@ -880,10 +880,10 @@ static int test_dev_config_update_uint_sync(struct kmod_test_device *test_dev, int (*test_sync)(struct kmod_test_device *test_dev)) { int ret; - long new; + unsigned long new; unsigned int old_val; - ret = kstrtol(buf, 10, &new); + ret = kstrtoul(buf, 10, &new); if (ret) return ret; @@ -918,13 +918,13 @@ static int test_dev_config_update_uint_range(struct kmod_test_device *test_dev, unsigned int max) { int ret; - long new; + unsigned long new; - ret = kstrtol(buf, 10, &new); + ret = kstrtoul(buf, 10, &new); if (ret) return ret; - if (new < min || new > max || new > UINT_MAX) + if (new < min || new > max) return -EINVAL; mutex_lock(&test_dev->config_mutex); @@ -946,7 +946,7 @@ static int test_dev_config_update_int(struct kmod_test_device *test_dev, if (ret) return ret; - if (new > INT_MAX || new < INT_MIN) + if (new < INT_MIN || new > INT_MAX) return -EINVAL; mutex_lock(&test_dev->config_mutex); @@ -1146,7 +1146,7 @@ static struct kmod_test_device *register_test_dev_kmod(void) struct kmod_test_device *test_dev = NULL; int ret; - mutex_unlock(®_dev_mutex); + mutex_lock(®_dev_mutex); /* int should suffice for number of devices, test for wrap */ if (unlikely(num_test_devs + 1) < 0) { diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 64e899b633371d252deaf057156408a8ea8f4625..0ffca990a83370d13553266be315f9373d6995da 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -56,8 +56,13 @@ static bool enomem_retry = false; module_param(enomem_retry, bool, 0); MODULE_PARM_DESC(enomem_retry, "Retry insert even if -ENOMEM was returned (default: off)"); +struct test_obj_val { + int id; + int tid; +}; + struct test_obj { - int value; + struct test_obj_val value; struct rhash_head node; }; @@ -72,7 +77,7 @@ static struct test_obj array[MAX_ENTRIES]; static struct rhashtable_params test_rht_params = { .head_offset = offsetof(struct test_obj, node), .key_offset = offsetof(struct test_obj, value), - .key_len = sizeof(int), + .key_len = sizeof(struct test_obj_val), .hashfn = jhash, .nulls_base = (3U << RHT_BASE_SHIFT), }; @@ -109,24 +114,26 @@ static int __init test_rht_lookup(struct rhashtable *ht) for (i = 0; i < entries * 2; i++) { struct test_obj *obj; bool expected = !(i % 2); - u32 key = i; + struct test_obj_val key = { + .id = i, + }; - if (array[i / 2].value == TEST_INSERT_FAIL) + if (array[i / 2].value.id == TEST_INSERT_FAIL) expected = false; obj = rhashtable_lookup_fast(ht, &key, test_rht_params); if (expected && !obj) { - pr_warn("Test failed: Could not find key %u\n", key); + pr_warn("Test failed: Could not find key %u\n", key.id); return -ENOENT; } else if (!expected && obj) { pr_warn("Test failed: Unexpected entry found for key %u\n", - key); + key.id); return -EEXIST; } else if (expected && obj) { - if (obj->value != i) { + if (obj->value.id != i) { pr_warn("Test failed: Lookup value mismatch %u!=%u\n", - obj->value, i); + obj->value.id, i); return -EINVAL; } } @@ -195,7 +202,7 @@ static s64 __init test_rhashtable(struct rhashtable *ht) for (i = 0; i < entries; i++) { struct test_obj *obj = &array[i]; - obj->value = i * 2; + obj->value.id = i * 2; err = insert_retry(ht, &obj->node, test_rht_params); if (err > 0) insert_retries += err; @@ -216,9 +223,11 @@ static s64 __init test_rhashtable(struct rhashtable *ht) pr_info(" Deleting %d keys\n", entries); for (i = 0; i < entries; i++) { - u32 key = i * 2; + struct test_obj_val key = { + .id = i * 2, + }; - if (array[i].value != TEST_INSERT_FAIL) { + if (array[i].value.id != TEST_INSERT_FAIL) { obj = rhashtable_lookup_fast(ht, &key, test_rht_params); BUG_ON(!obj); @@ -242,18 +251,21 @@ static int thread_lookup_test(struct thread_data *tdata) for (i = 0; i < entries; i++) { struct test_obj *obj; - int key = (tdata->id << 16) | i; + struct test_obj_val key = { + .id = i, + .tid = tdata->id, + }; obj = rhashtable_lookup_fast(&ht, &key, test_rht_params); - if (obj && (tdata->objs[i].value == TEST_INSERT_FAIL)) { - pr_err(" found unexpected object %d\n", key); + if (obj && (tdata->objs[i].value.id == TEST_INSERT_FAIL)) { + pr_err(" found unexpected object %d-%d\n", key.tid, key.id); err++; - } else if (!obj && (tdata->objs[i].value != TEST_INSERT_FAIL)) { - pr_err(" object %d not found!\n", key); + } else if (!obj && (tdata->objs[i].value.id != TEST_INSERT_FAIL)) { + pr_err(" object %d-%d not found!\n", key.tid, key.id); err++; - } else if (obj && (obj->value != key)) { - pr_err(" wrong object returned (got %d, expected %d)\n", - obj->value, key); + } else if (obj && memcmp(&obj->value, &key, sizeof(key))) { + pr_err(" wrong object returned (got %d-%d, expected %d-%d)\n", + obj->value.tid, obj->value.id, key.tid, key.id); err++; } @@ -272,7 +284,8 @@ static int threadfunc(void *data) pr_err(" thread[%d]: down_interruptible failed\n", tdata->id); for (i = 0; i < entries; i++) { - tdata->objs[i].value = (tdata->id << 16) | i; + tdata->objs[i].value.id = i; + tdata->objs[i].value.tid = tdata->id; err = insert_retry(&ht, &tdata->objs[i].node, test_rht_params); if (err > 0) { insert_retries += err; @@ -295,7 +308,7 @@ static int threadfunc(void *data) for (step = 10; step > 0; step--) { for (i = 0; i < entries; i += step) { - if (tdata->objs[i].value == TEST_INSERT_FAIL) + if (tdata->objs[i].value.id == TEST_INSERT_FAIL) continue; err = rhashtable_remove_fast(&ht, &tdata->objs[i].node, test_rht_params); @@ -304,7 +317,7 @@ static int threadfunc(void *data) tdata->id); goto out; } - tdata->objs[i].value = TEST_INSERT_FAIL; + tdata->objs[i].value.id = TEST_INSERT_FAIL; cond_resched(); } diff --git a/lib/xxhash.c b/lib/xxhash.c new file mode 100644 index 0000000000000000000000000000000000000000..aa61e2a3802f0a69061fcf93f0b2f8523e9b4448 --- /dev/null +++ b/lib/xxhash.c @@ -0,0 +1,500 @@ +/* + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at: + * - xxHash homepage: http://cyan4973.github.io/xxHash/ + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ + +#include +#include +#include +#include +#include +#include +#include + +/*-************************************* + * Macros + **************************************/ +#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r))) +#define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r))) + +#ifdef __LITTLE_ENDIAN +# define XXH_CPU_LITTLE_ENDIAN 1 +#else +# define XXH_CPU_LITTLE_ENDIAN 0 +#endif + +/*-************************************* + * Constants + **************************************/ +static const uint32_t PRIME32_1 = 2654435761U; +static const uint32_t PRIME32_2 = 2246822519U; +static const uint32_t PRIME32_3 = 3266489917U; +static const uint32_t PRIME32_4 = 668265263U; +static const uint32_t PRIME32_5 = 374761393U; + +static const uint64_t PRIME64_1 = 11400714785074694791ULL; +static const uint64_t PRIME64_2 = 14029467366897019727ULL; +static const uint64_t PRIME64_3 = 1609587929392839161ULL; +static const uint64_t PRIME64_4 = 9650029242287828579ULL; +static const uint64_t PRIME64_5 = 2870177450012600261ULL; + +/*-************************** + * Utils + ***************************/ +void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src) +{ + memcpy(dst, src, sizeof(*dst)); +} +EXPORT_SYMBOL(xxh32_copy_state); + +void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src) +{ + memcpy(dst, src, sizeof(*dst)); +} +EXPORT_SYMBOL(xxh64_copy_state); + +/*-*************************** + * Simple Hash Functions + ****************************/ +static uint32_t xxh32_round(uint32_t seed, const uint32_t input) +{ + seed += input * PRIME32_2; + seed = xxh_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + +uint32_t xxh32(const void *input, const size_t len, const uint32_t seed) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *b_end = p + len; + uint32_t h32; + + if (len >= 16) { + const uint8_t *const limit = b_end - 16; + uint32_t v1 = seed + PRIME32_1 + PRIME32_2; + uint32_t v2 = seed + PRIME32_2; + uint32_t v3 = seed + 0; + uint32_t v4 = seed - PRIME32_1; + + do { + v1 = xxh32_round(v1, get_unaligned_le32(p)); + p += 4; + v2 = xxh32_round(v2, get_unaligned_le32(p)); + p += 4; + v3 = xxh32_round(v3, get_unaligned_le32(p)); + p += 4; + v4 = xxh32_round(v4, get_unaligned_le32(p)); + p += 4; + } while (p <= limit); + + h32 = xxh_rotl32(v1, 1) + xxh_rotl32(v2, 7) + + xxh_rotl32(v3, 12) + xxh_rotl32(v4, 18); + } else { + h32 = seed + PRIME32_5; + } + + h32 += (uint32_t)len; + + while (p + 4 <= b_end) { + h32 += get_unaligned_le32(p) * PRIME32_3; + h32 = xxh_rotl32(h32, 17) * PRIME32_4; + p += 4; + } + + while (p < b_end) { + h32 += (*p) * PRIME32_5; + h32 = xxh_rotl32(h32, 11) * PRIME32_1; + p++; + } + + h32 ^= h32 >> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} +EXPORT_SYMBOL(xxh32); + +static uint64_t xxh64_round(uint64_t acc, const uint64_t input) +{ + acc += input * PRIME64_2; + acc = xxh_rotl64(acc, 31); + acc *= PRIME64_1; + return acc; +} + +static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val) +{ + val = xxh64_round(0, val); + acc ^= val; + acc = acc * PRIME64_1 + PRIME64_4; + return acc; +} + +uint64_t xxh64(const void *input, const size_t len, const uint64_t seed) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *const b_end = p + len; + uint64_t h64; + + if (len >= 32) { + const uint8_t *const limit = b_end - 32; + uint64_t v1 = seed + PRIME64_1 + PRIME64_2; + uint64_t v2 = seed + PRIME64_2; + uint64_t v3 = seed + 0; + uint64_t v4 = seed - PRIME64_1; + + do { + v1 = xxh64_round(v1, get_unaligned_le64(p)); + p += 8; + v2 = xxh64_round(v2, get_unaligned_le64(p)); + p += 8; + v3 = xxh64_round(v3, get_unaligned_le64(p)); + p += 8; + v4 = xxh64_round(v4, get_unaligned_le64(p)); + p += 8; + } while (p <= limit); + + h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) + + xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18); + h64 = xxh64_merge_round(h64, v1); + h64 = xxh64_merge_round(h64, v2); + h64 = xxh64_merge_round(h64, v3); + h64 = xxh64_merge_round(h64, v4); + + } else { + h64 = seed + PRIME64_5; + } + + h64 += (uint64_t)len; + + while (p + 8 <= b_end) { + const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p)); + + h64 ^= k1; + h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; + p += 8; + } + + if (p + 4 <= b_end) { + h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1; + h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p += 4; + } + + while (p < b_end) { + h64 ^= (*p) * PRIME64_5; + h64 = xxh_rotl64(h64, 11) * PRIME64_1; + p++; + } + + h64 ^= h64 >> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} +EXPORT_SYMBOL(xxh64); + +/*-************************************************** + * Advanced Hash Functions + ***************************************************/ +void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed) +{ + /* use a local state for memcpy() to avoid strict-aliasing warnings */ + struct xxh32_state state; + + memset(&state, 0, sizeof(state)); + state.v1 = seed + PRIME32_1 + PRIME32_2; + state.v2 = seed + PRIME32_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME32_1; + memcpy(statePtr, &state, sizeof(state)); +} +EXPORT_SYMBOL(xxh32_reset); + +void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed) +{ + /* use a local state for memcpy() to avoid strict-aliasing warnings */ + struct xxh64_state state; + + memset(&state, 0, sizeof(state)); + state.v1 = seed + PRIME64_1 + PRIME64_2; + state.v2 = seed + PRIME64_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME64_1; + memcpy(statePtr, &state, sizeof(state)); +} +EXPORT_SYMBOL(xxh64_reset); + +int xxh32_update(struct xxh32_state *state, const void *input, const size_t len) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *const b_end = p + len; + + if (input == NULL) + return -EINVAL; + + state->total_len_32 += (uint32_t)len; + state->large_len |= (len >= 16) | (state->total_len_32 >= 16); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + memcpy((uint8_t *)(state->mem32) + state->memsize, input, len); + state->memsize += (uint32_t)len; + return 0; + } + + if (state->memsize) { /* some data left from previous update */ + const uint32_t *p32 = state->mem32; + + memcpy((uint8_t *)(state->mem32) + state->memsize, input, + 16 - state->memsize); + + state->v1 = xxh32_round(state->v1, get_unaligned_le32(p32)); + p32++; + state->v2 = xxh32_round(state->v2, get_unaligned_le32(p32)); + p32++; + state->v3 = xxh32_round(state->v3, get_unaligned_le32(p32)); + p32++; + state->v4 = xxh32_round(state->v4, get_unaligned_le32(p32)); + p32++; + + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= b_end - 16) { + const uint8_t *const limit = b_end - 16; + uint32_t v1 = state->v1; + uint32_t v2 = state->v2; + uint32_t v3 = state->v3; + uint32_t v4 = state->v4; + + do { + v1 = xxh32_round(v1, get_unaligned_le32(p)); + p += 4; + v2 = xxh32_round(v2, get_unaligned_le32(p)); + p += 4; + v3 = xxh32_round(v3, get_unaligned_le32(p)); + p += 4; + v4 = xxh32_round(v4, get_unaligned_le32(p)); + p += 4; + } while (p <= limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < b_end) { + memcpy(state->mem32, p, (size_t)(b_end-p)); + state->memsize = (uint32_t)(b_end-p); + } + + return 0; +} +EXPORT_SYMBOL(xxh32_update); + +uint32_t xxh32_digest(const struct xxh32_state *state) +{ + const uint8_t *p = (const uint8_t *)state->mem32; + const uint8_t *const b_end = (const uint8_t *)(state->mem32) + + state->memsize; + uint32_t h32; + + if (state->large_len) { + h32 = xxh_rotl32(state->v1, 1) + xxh_rotl32(state->v2, 7) + + xxh_rotl32(state->v3, 12) + xxh_rotl32(state->v4, 18); + } else { + h32 = state->v3 /* == seed */ + PRIME32_5; + } + + h32 += state->total_len_32; + + while (p + 4 <= b_end) { + h32 += get_unaligned_le32(p) * PRIME32_3; + h32 = xxh_rotl32(h32, 17) * PRIME32_4; + p += 4; + } + + while (p < b_end) { + h32 += (*p) * PRIME32_5; + h32 = xxh_rotl32(h32, 11) * PRIME32_1; + p++; + } + + h32 ^= h32 >> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} +EXPORT_SYMBOL(xxh32_digest); + +int xxh64_update(struct xxh64_state *state, const void *input, const size_t len) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *const b_end = p + len; + + if (input == NULL) + return -EINVAL; + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + memcpy(((uint8_t *)state->mem64) + state->memsize, input, len); + state->memsize += (uint32_t)len; + return 0; + } + + if (state->memsize) { /* tmp buffer is full */ + uint64_t *p64 = state->mem64; + + memcpy(((uint8_t *)p64) + state->memsize, input, + 32 - state->memsize); + + state->v1 = xxh64_round(state->v1, get_unaligned_le64(p64)); + p64++; + state->v2 = xxh64_round(state->v2, get_unaligned_le64(p64)); + p64++; + state->v3 = xxh64_round(state->v3, get_unaligned_le64(p64)); + p64++; + state->v4 = xxh64_round(state->v4, get_unaligned_le64(p64)); + + p += 32 - state->memsize; + state->memsize = 0; + } + + if (p + 32 <= b_end) { + const uint8_t *const limit = b_end - 32; + uint64_t v1 = state->v1; + uint64_t v2 = state->v2; + uint64_t v3 = state->v3; + uint64_t v4 = state->v4; + + do { + v1 = xxh64_round(v1, get_unaligned_le64(p)); + p += 8; + v2 = xxh64_round(v2, get_unaligned_le64(p)); + p += 8; + v3 = xxh64_round(v3, get_unaligned_le64(p)); + p += 8; + v4 = xxh64_round(v4, get_unaligned_le64(p)); + p += 8; + } while (p <= limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < b_end) { + memcpy(state->mem64, p, (size_t)(b_end-p)); + state->memsize = (uint32_t)(b_end - p); + } + + return 0; +} +EXPORT_SYMBOL(xxh64_update); + +uint64_t xxh64_digest(const struct xxh64_state *state) +{ + const uint8_t *p = (const uint8_t *)state->mem64; + const uint8_t *const b_end = (const uint8_t *)state->mem64 + + state->memsize; + uint64_t h64; + + if (state->total_len >= 32) { + const uint64_t v1 = state->v1; + const uint64_t v2 = state->v2; + const uint64_t v3 = state->v3; + const uint64_t v4 = state->v4; + + h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) + + xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18); + h64 = xxh64_merge_round(h64, v1); + h64 = xxh64_merge_round(h64, v2); + h64 = xxh64_merge_round(h64, v3); + h64 = xxh64_merge_round(h64, v4); + } else { + h64 = state->v3 + PRIME64_5; + } + + h64 += (uint64_t)state->total_len; + + while (p + 8 <= b_end) { + const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p)); + + h64 ^= k1; + h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; + p += 8; + } + + if (p + 4 <= b_end) { + h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1; + h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p += 4; + } + + while (p < b_end) { + h64 ^= (*p) * PRIME64_5; + h64 = xxh_rotl64(h64, 11) * PRIME64_1; + p++; + } + + h64 ^= h64 >> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} +EXPORT_SYMBOL(xxh64_digest); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("xxHash"); diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..dd0a359c135b47b77dc98a6c292ffb7c86b21add --- /dev/null +++ b/lib/zstd/Makefile @@ -0,0 +1,18 @@ +obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o +obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o + +ccflags-y += -O3 + +# Object files unique to zstd_compress and zstd_decompress +zstd_compress-y := fse_compress.o huf_compress.o compress.o +zstd_decompress-y := huf_decompress.o decompress.o + +# These object files are shared between the modules. +# Always add them to zstd_compress. +# Unless both zstd_compress and zstd_decompress are built in +# then also add them to zstd_decompress. +zstd_compress-y += entropy_common.o fse_decompress.o zstd_common.o + +ifneq ($(CONFIG_ZSTD_COMPRESS)$(CONFIG_ZSTD_DECOMPRESS),yy) + zstd_decompress-y += entropy_common.o fse_decompress.o zstd_common.o +endif diff --git a/lib/zstd/bitstream.h b/lib/zstd/bitstream.h new file mode 100644 index 0000000000000000000000000000000000000000..a826b99e1d63526d576ffbb818645fe356238af1 --- /dev/null +++ b/lib/zstd/bitstream.h @@ -0,0 +1,374 @@ +/* + * bitstream + * Part of FSE library + * header file (to include) + * Copyright (C) 2013-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +/* +* This API consists of small unitary functions, which must be inlined for best performance. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + +/*-**************************************** +* Dependencies +******************************************/ +#include "error_private.h" /* error codes and messages */ +#include "mem.h" /* unaligned access routines */ + +/*========================================= +* Target specific +=========================================*/ +#define STREAM_ACCUMULATOR_MIN_32 25 +#define STREAM_ACCUMULATOR_MIN_64 57 +#define STREAM_ACCUMULATOR_MIN ((U32)(ZSTD_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + +/*-****************************************** +* bitStream encoding API (write forward) +********************************************/ +/* bitStream can mix input from multiple sources. +* A critical property of these streams is that they encode and decode in **reverse** direction. +* So the first bit sequence you add will be the last to be read, like a LIFO stack. +*/ +typedef struct { + size_t bitContainer; + int bitPos; + char *startPtr; + char *ptr; + char *endPtr; +} BIT_CStream_t; + +ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *dstBuffer, size_t dstCapacity); +ZSTD_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits); +ZSTD_STATIC void BIT_flushBits(BIT_CStream_t *bitC); +ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC); + +/* Start with initCStream, providing the size of buffer to write into. +* bitStream will never write outside of this buffer. +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. +* +* bits are first added to a local register. +* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +* Writing data into memory is an explicit operation, performed by the flushBits function. +* Hence keep track how many bits are potentially stored into local register to avoid register overflow. +* After a flushBits, a maximum of 7 bits might still be stored into local register. +* +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. +* +* Last operation is to close the bitStream. +* The function returns the final size of CStream in bytes. +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) +*/ + +/*-******************************************** +* bitStream decoding API (read backward) +**********************************************/ +typedef struct { + size_t bitContainer; + unsigned bitsConsumed; + const char *ptr; + const char *start; +} BIT_DStream_t; + +typedef enum { + BIT_DStream_unfinished = 0, + BIT_DStream_endOfBuffer = 1, + BIT_DStream_completed = 2, + BIT_DStream_overflow = 3 +} BIT_DStream_status; /* result of BIT_reloadDStream() */ +/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ + +ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize); +ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, unsigned nbBits); +ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD); +ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *bitD); + +/* Start by invoking BIT_initDStream(). +* A chunk of the bitStream is then stored into a local register. +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +* You can then retrieve bitFields stored into the local register, **in reverse order**. +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. +* Otherwise, it can be less than that, so proceed accordingly. +* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). +*/ + +/*-**************************************** +* unsafe API +******************************************/ +ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits); +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ + +ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC); +/* unsafe version; does not check buffer overflow */ + +ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + +/*-************************************************************** +* Internal functions +****************************************************************/ +ZSTD_STATIC unsigned BIT_highbit32(register U32 val) { return 31 - __builtin_clz(val); } + +/*===== Local Constants =====*/ +static const unsigned BIT_mask[] = {0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, + 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF}; /* up to 26 bits */ + +/*-************************************************************** +* bitStream encoding +****************************************************************/ +/*! BIT_initCStream() : + * `dstCapacity` must be > sizeof(void*) + * @return : 0 if success, + otherwise an error code (can be tested using ERR_isError() ) */ +ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *startPtr, size_t dstCapacity) +{ + bitC->bitContainer = 0; + bitC->bitPos = 0; + bitC->startPtr = (char *)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr); + if (dstCapacity <= sizeof(bitC->ptr)) + return ERROR(dstSize_tooSmall); + return 0; +} + +/*! BIT_addBits() : + can add up to 26 bits into `bitC`. + Does not check for register overflow ! */ +ZSTD_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits) +{ + bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_addBitsFast() : + * works only if `value` is _clean_, meaning all high bits above nbBits are 0 */ +ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits) +{ + bitC->bitContainer |= value << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_flushBitsFast() : + * unsafe version; does not check buffer overflow */ +ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + ZSTD_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes * 8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */ +} + +/*! BIT_flushBits() : + * safe version; check for buffer overflow, and prevents it. + * note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */ +ZSTD_STATIC void BIT_flushBits(BIT_CStream_t *bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + ZSTD_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + if (bitC->ptr > bitC->endPtr) + bitC->ptr = bitC->endPtr; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes * 8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */ +} + +/*! BIT_closeCStream() : + * @return : size of CStream, in bytes, + or 0 if it could not fit into dstBuffer */ +ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC) +{ + BIT_addBitsFast(bitC, 1, 1); /* endMark */ + BIT_flushBits(bitC); + + if (bitC->ptr >= bitC->endPtr) + return 0; /* doesn't fit within authorized budget : cancel */ + + return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +} + +/*-******************************************************** +* bitStream decoding +**********************************************************/ +/*! BIT_initDStream() : +* Initialize a BIT_DStream_t. +* `bitD` : a pointer to an already allocated BIT_DStream_t structure. +* `srcSize` must be the *exact* size of the bitStream, in bytes. +* @return : size of stream (== srcSize) or an errorCode if a problem is detected +*/ +ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { + memset(bitD, 0, sizeof(*bitD)); + return ERROR(srcSize_wrong); + } + + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ + bitD->start = (const char *)srcBuffer; + bitD->ptr = (const char *)srcBuffer + srcSize - sizeof(bitD->bitContainer); + bitD->bitContainer = ZSTD_readLEST(bitD->ptr); + { + BYTE const lastByte = ((const BYTE *)srcBuffer)[srcSize - 1]; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ + if (lastByte == 0) + return ERROR(GENERIC); /* endMark not present */ + } + } else { + bitD->start = (const char *)srcBuffer; + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE *)(bitD->start); + switch (srcSize) { + case 7: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[6]) << (sizeof(bitD->bitContainer) * 8 - 16); + case 6: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[5]) << (sizeof(bitD->bitContainer) * 8 - 24); + case 5: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[4]) << (sizeof(bitD->bitContainer) * 8 - 32); + case 4: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[3]) << 24; + case 3: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[2]) << 16; + case 2: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[1]) << 8; + default:; + } + { + BYTE const lastByte = ((const BYTE *)srcBuffer)[srcSize - 1]; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; + if (lastByte == 0) + return ERROR(GENERIC); /* endMark not present */ + } + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize) * 8; + } + + return srcSize; +} + +ZSTD_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) { return bitContainer >> start; } + +ZSTD_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) { return (bitContainer >> start) & BIT_mask[nbBits]; } + +ZSTD_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) { return bitContainer & BIT_mask[nbBits]; } + +/*! BIT_lookBits() : + * Provides next n bits from local register. + * local register is not modified. + * On 32-bits, maxNbBits==24. + * On 64-bits, maxNbBits==56. + * @return : value extracted + */ +ZSTD_STATIC size_t BIT_lookBits(const BIT_DStream_t *bitD, U32 nbBits) +{ + U32 const bitMask = sizeof(bitD->bitContainer) * 8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask - nbBits) & bitMask); +} + +/*! BIT_lookBitsFast() : +* unsafe version; only works only if nbBits >= 1 */ +ZSTD_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t *bitD, U32 nbBits) +{ + U32 const bitMask = sizeof(bitD->bitContainer) * 8 - 1; + return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask + 1) - nbBits) & bitMask); +} + +ZSTD_STATIC void BIT_skipBits(BIT_DStream_t *bitD, U32 nbBits) { bitD->bitsConsumed += nbBits; } + +/*! BIT_readBits() : + * Read (consume) next n bits from local register and update. + * Pay attention to not read more than nbBits contained into local register. + * @return : extracted value. + */ +ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, U32 nbBits) +{ + size_t const value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_readBitsFast() : +* unsafe version; only works only if nbBits >= 1 */ +ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, U32 nbBits) +{ + size_t const value = BIT_lookBitsFast(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_reloadDStream() : +* Refill `bitD` from buffer previously set in BIT_initDStream() . +* This function is safe, it guarantees it will not read beyond src buffer. +* @return : status of `BIT_DStream_t` internal register. + if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ +ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD) +{ + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer) * 8)) /* should not happen => corruption detected */ + return BIT_DStream_overflow; + + if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) { + bitD->ptr -= bitD->bitsConsumed >> 3; + bitD->bitsConsumed &= 7; + bitD->bitContainer = ZSTD_readLEST(bitD->ptr); + return BIT_DStream_unfinished; + } + if (bitD->ptr == bitD->start) { + if (bitD->bitsConsumed < sizeof(bitD->bitContainer) * 8) + return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + { + U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes * 8; + bitD->bitContainer = ZSTD_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */ + return result; + } +} + +/*! BIT_endOfDStream() : +* @return Tells if DStream has exactly reached its end (all bits consumed). +*/ +ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer) * 8)); +} + +#endif /* BITSTREAM_H_MODULE */ diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c new file mode 100644 index 0000000000000000000000000000000000000000..f9166cf4f7a98733384144e18e7989e681992c7d --- /dev/null +++ b/lib/zstd/compress.c @@ -0,0 +1,3484 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/*-************************************* +* Dependencies +***************************************/ +#include "fse.h" +#include "huf.h" +#include "mem.h" +#include "zstd_internal.h" /* includes zstd.h */ +#include +#include +#include /* memset */ + +/*-************************************* +* Constants +***************************************/ +static const U32 g_searchStrength = 8; /* control skip over incompressible data */ +#define HASH_READ_SIZE 8 +typedef enum { ZSTDcs_created = 0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e; + +/*-************************************* +* Helper functions +***************************************/ +size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; } + +/*-************************************* +* Sequence storage +***************************************/ +static void ZSTD_resetSeqStore(seqStore_t *ssPtr) +{ + ssPtr->lit = ssPtr->litStart; + ssPtr->sequences = ssPtr->sequencesStart; + ssPtr->longLengthID = 0; +} + +/*-************************************* +* Context memory management +***************************************/ +struct ZSTD_CCtx_s { + const BYTE *nextSrc; /* next block here to continue on curr prefix */ + const BYTE *base; /* All regular indexes relative to this position */ + const BYTE *dictBase; /* extDict indexes relative to this position */ + U32 dictLimit; /* below that point, need extDict */ + U32 lowLimit; /* below that point, no more data */ + U32 nextToUpdate; /* index from which to continue dictionary update */ + U32 nextToUpdate3; /* index from which to continue dictionary update */ + U32 hashLog3; /* dispatch table : larger == faster, more memory */ + U32 loadedDictEnd; /* index of end of dictionary */ + U32 forceWindow; /* force back-references to respect limit of 1< 3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog); + size_t const h3Size = ((size_t)1) << hashLog3; + size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32); + size_t const optSpace = + ((MaxML + 1) + (MaxLL + 1) + (MaxOff + 1) + (1 << Litbits)) * sizeof(U32) + (ZSTD_OPT_NUM + 1) * (sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t)); + size_t const workspaceSize = tableSpace + (256 * sizeof(U32)) /* huffTable */ + tokenSpace + + (((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btopt2)) ? optSpace : 0); + + return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_CCtx)) + ZSTD_ALIGN(workspaceSize); +} + +static ZSTD_CCtx *ZSTD_createCCtx_advanced(ZSTD_customMem customMem) +{ + ZSTD_CCtx *cctx; + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + cctx = (ZSTD_CCtx *)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem); + if (!cctx) + return NULL; + memset(cctx, 0, sizeof(ZSTD_CCtx)); + cctx->customMem = customMem; + return cctx; +} + +ZSTD_CCtx *ZSTD_initCCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize); + ZSTD_CCtx *cctx = ZSTD_createCCtx_advanced(stackMem); + if (cctx) { + cctx->workSpace = ZSTD_stackAllocAll(cctx->customMem.opaque, &cctx->workSpaceSize); + } + return cctx; +} + +size_t ZSTD_freeCCtx(ZSTD_CCtx *cctx) +{ + if (cctx == NULL) + return 0; /* support free on NULL */ + ZSTD_free(cctx->workSpace, cctx->customMem); + ZSTD_free(cctx, cctx->customMem); + return 0; /* reserved as a potential error code in the future */ +} + +const seqStore_t *ZSTD_getSeqStore(const ZSTD_CCtx *ctx) /* hidden interface */ { return &(ctx->seqStore); } + +static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx *cctx) { return cctx->params; } + +/** ZSTD_checkParams() : + ensure param values remain within authorized range. + @return : 0, or an error code if one value is beyond authorized range */ +size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) +{ +#define CLAMPCHECK(val, min, max) \ + { \ + if ((val < min) | (val > max)) \ + return ERROR(compressionParameter_unsupported); \ + } + CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); + CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); + CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); + CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); + CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); + CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); + if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) + return ERROR(compressionParameter_unsupported); + return 0; +} + +/** ZSTD_cycleLog() : + * condition for correct operation : hashLog > 1 */ +static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) +{ + U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); + return hashLog - btScale; +} + +/** ZSTD_adjustCParams() : + optimize `cPar` for a given input (`srcSize` and `dictSize`). + mostly downsizing to reduce memory consumption and initialization. + Both `srcSize` and `dictSize` are optional (use 0 if unknown), + but if both are 0, no optimization can be done. + Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */ +ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize) +{ + if (srcSize + dictSize == 0) + return cPar; /* no size information available : no adjustment */ + + /* resize params, to use less memory when necessary */ + { + U32 const minSrcSize = (srcSize == 0) ? 500 : 0; + U64 const rSize = srcSize + dictSize + minSrcSize; + if (rSize < ((U64)1 << ZSTD_WINDOWLOG_MAX)) { + U32 const srcLog = MAX(ZSTD_HASHLOG_MIN, ZSTD_highbit32((U32)(rSize)-1) + 1); + if (cPar.windowLog > srcLog) + cPar.windowLog = srcLog; + } + } + if (cPar.hashLog > cPar.windowLog) + cPar.hashLog = cPar.windowLog; + { + U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cycleLog > cPar.windowLog) + cPar.chainLog -= (cycleLog - cPar.windowLog); + } + + if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) + cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ + + return cPar; +} + +static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2) +{ + return (param1.cParams.hashLog == param2.cParams.hashLog) & (param1.cParams.chainLog == param2.cParams.chainLog) & + (param1.cParams.strategy == param2.cParams.strategy) & ((param1.cParams.searchLength == 3) == (param2.cParams.searchLength == 3)); +} + +/*! ZSTD_continueCCtx() : + reuse CCtx without reset (note : requires no dictionary) */ +static size_t ZSTD_continueCCtx(ZSTD_CCtx *cctx, ZSTD_parameters params, U64 frameContentSize) +{ + U32 const end = (U32)(cctx->nextSrc - cctx->base); + cctx->params = params; + cctx->frameContentSize = frameContentSize; + cctx->lowLimit = end; + cctx->dictLimit = end; + cctx->nextToUpdate = end + 1; + cctx->stage = ZSTDcs_init; + cctx->dictID = 0; + cctx->loadedDictEnd = 0; + { + int i; + for (i = 0; i < ZSTD_REP_NUM; i++) + cctx->rep[i] = repStartValue[i]; + } + cctx->seqStore.litLengthSum = 0; /* force reset of btopt stats */ + xxh64_reset(&cctx->xxhState, 0); + return 0; +} + +typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e; + +/*! ZSTD_resetCCtx_advanced() : + note : `params` must be validated */ +static size_t ZSTD_resetCCtx_advanced(ZSTD_CCtx *zc, ZSTD_parameters params, U64 frameContentSize, ZSTD_compResetPolicy_e const crp) +{ + if (crp == ZSTDcrp_continue) + if (ZSTD_equivalentParams(params, zc->params)) { + zc->flagStaticTables = 0; + zc->flagStaticHufTable = HUF_repeat_none; + return ZSTD_continueCCtx(zc, params, frameContentSize); + } + + { + size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog); + U32 const divider = (params.cParams.searchLength == 3) ? 3 : 4; + size_t const maxNbSeq = blockSize / divider; + size_t const tokenSpace = blockSize + 11 * maxNbSeq; + size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog); + size_t const hSize = ((size_t)1) << params.cParams.hashLog; + U32 const hashLog3 = (params.cParams.searchLength > 3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog); + size_t const h3Size = ((size_t)1) << hashLog3; + size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32); + void *ptr; + + /* Check if workSpace is large enough, alloc a new one if needed */ + { + size_t const optSpace = ((MaxML + 1) + (MaxLL + 1) + (MaxOff + 1) + (1 << Litbits)) * sizeof(U32) + + (ZSTD_OPT_NUM + 1) * (sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t)); + size_t const neededSpace = tableSpace + (256 * sizeof(U32)) /* huffTable */ + tokenSpace + + (((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optSpace : 0); + if (zc->workSpaceSize < neededSpace) { + ZSTD_free(zc->workSpace, zc->customMem); + zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem); + if (zc->workSpace == NULL) + return ERROR(memory_allocation); + zc->workSpaceSize = neededSpace; + } + } + + if (crp != ZSTDcrp_noMemset) + memset(zc->workSpace, 0, tableSpace); /* reset tables only */ + xxh64_reset(&zc->xxhState, 0); + zc->hashLog3 = hashLog3; + zc->hashTable = (U32 *)(zc->workSpace); + zc->chainTable = zc->hashTable + hSize; + zc->hashTable3 = zc->chainTable + chainSize; + ptr = zc->hashTable3 + h3Size; + zc->hufTable = (HUF_CElt *)ptr; + zc->flagStaticTables = 0; + zc->flagStaticHufTable = HUF_repeat_none; + ptr = ((U32 *)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */ + + zc->nextToUpdate = 1; + zc->nextSrc = NULL; + zc->base = NULL; + zc->dictBase = NULL; + zc->dictLimit = 0; + zc->lowLimit = 0; + zc->params = params; + zc->blockSize = blockSize; + zc->frameContentSize = frameContentSize; + { + int i; + for (i = 0; i < ZSTD_REP_NUM; i++) + zc->rep[i] = repStartValue[i]; + } + + if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) { + zc->seqStore.litFreq = (U32 *)ptr; + zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1 << Litbits); + zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL + 1); + zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML + 1); + ptr = zc->seqStore.offCodeFreq + (MaxOff + 1); + zc->seqStore.matchTable = (ZSTD_match_t *)ptr; + ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM + 1; + zc->seqStore.priceTable = (ZSTD_optimal_t *)ptr; + ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM + 1; + zc->seqStore.litLengthSum = 0; + } + zc->seqStore.sequencesStart = (seqDef *)ptr; + ptr = zc->seqStore.sequencesStart + maxNbSeq; + zc->seqStore.llCode = (BYTE *)ptr; + zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq; + zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq; + zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq; + + zc->stage = ZSTDcs_init; + zc->dictID = 0; + zc->loadedDictEnd = 0; + + return 0; + } +} + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx *cctx) +{ + int i; + for (i = 0; i < ZSTD_REP_NUM; i++) + cctx->rep[i] = 0; +} + +/*! ZSTD_copyCCtx() : +* Duplicate an existing context `srcCCtx` into another one `dstCCtx`. +* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). +* @return : 0, or an error code */ +size_t ZSTD_copyCCtx(ZSTD_CCtx *dstCCtx, const ZSTD_CCtx *srcCCtx, unsigned long long pledgedSrcSize) +{ + if (srcCCtx->stage != ZSTDcs_init) + return ERROR(stage_wrong); + + memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); + { + ZSTD_parameters params = srcCCtx->params; + params.fParams.contentSizeFlag = (pledgedSrcSize > 0); + ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset); + } + + /* copy tables */ + { + size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog); + size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog; + size_t const h3Size = (size_t)1 << srcCCtx->hashLog3; + size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32); + memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace); + } + + /* copy dictionary offsets */ + dstCCtx->nextToUpdate = srcCCtx->nextToUpdate; + dstCCtx->nextToUpdate3 = srcCCtx->nextToUpdate3; + dstCCtx->nextSrc = srcCCtx->nextSrc; + dstCCtx->base = srcCCtx->base; + dstCCtx->dictBase = srcCCtx->dictBase; + dstCCtx->dictLimit = srcCCtx->dictLimit; + dstCCtx->lowLimit = srcCCtx->lowLimit; + dstCCtx->loadedDictEnd = srcCCtx->loadedDictEnd; + dstCCtx->dictID = srcCCtx->dictID; + + /* copy entropy tables */ + dstCCtx->flagStaticTables = srcCCtx->flagStaticTables; + dstCCtx->flagStaticHufTable = srcCCtx->flagStaticHufTable; + if (srcCCtx->flagStaticTables) { + memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable)); + memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable)); + memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable)); + } + if (srcCCtx->flagStaticHufTable) { + memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256 * 4); + } + + return 0; +} + +/*! ZSTD_reduceTable() : +* reduce table indexes by `reducerValue` */ +static void ZSTD_reduceTable(U32 *const table, U32 const size, U32 const reducerValue) +{ + U32 u; + for (u = 0; u < size; u++) { + if (table[u] < reducerValue) + table[u] = 0; + else + table[u] -= reducerValue; + } +} + +/*! ZSTD_reduceIndex() : +* rescale all indexes to avoid future overflow (indexes are U32) */ +static void ZSTD_reduceIndex(ZSTD_CCtx *zc, const U32 reducerValue) +{ + { + U32 const hSize = 1 << zc->params.cParams.hashLog; + ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); + } + + { + U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog); + ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); + } + + { + U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0; + ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); + } +} + +/*-******************************************************* +* Block entropic compression +*********************************************************/ + +/* See doc/zstd_compression_format.md for detailed format description */ + +size_t ZSTD_noCompressBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + if (srcSize + ZSTD_blockHeaderSize > dstCapacity) + return ERROR(dstSize_tooSmall); + memcpy((BYTE *)dst + ZSTD_blockHeaderSize, src, srcSize); + ZSTD_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw); + return ZSTD_blockHeaderSize + srcSize; +} + +static size_t ZSTD_noCompressLiterals(void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + BYTE *const ostart = (BYTE * const)dst; + U32 const flSize = 1 + (srcSize > 31) + (srcSize > 4095); + + if (srcSize + flSize > dstCapacity) + return ERROR(dstSize_tooSmall); + + switch (flSize) { + case 1: /* 2 - 1 - 5 */ ostart[0] = (BYTE)((U32)set_basic + (srcSize << 3)); break; + case 2: /* 2 - 2 - 12 */ ZSTD_writeLE16(ostart, (U16)((U32)set_basic + (1 << 2) + (srcSize << 4))); break; + default: /*note : should not be necessary : flSize is within {1,2,3} */ + case 3: /* 2 - 2 - 20 */ ZSTD_writeLE32(ostart, (U32)((U32)set_basic + (3 << 2) + (srcSize << 4))); break; + } + + memcpy(ostart + flSize, src, srcSize); + return srcSize + flSize; +} + +static size_t ZSTD_compressRleLiteralsBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + BYTE *const ostart = (BYTE * const)dst; + U32 const flSize = 1 + (srcSize > 31) + (srcSize > 4095); + + (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */ + + switch (flSize) { + case 1: /* 2 - 1 - 5 */ ostart[0] = (BYTE)((U32)set_rle + (srcSize << 3)); break; + case 2: /* 2 - 2 - 12 */ ZSTD_writeLE16(ostart, (U16)((U32)set_rle + (1 << 2) + (srcSize << 4))); break; + default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */ + case 3: /* 2 - 2 - 20 */ ZSTD_writeLE32(ostart, (U32)((U32)set_rle + (3 << 2) + (srcSize << 4))); break; + } + + ostart[flSize] = *(const BYTE *)src; + return flSize + 1; +} + +static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; } + +static size_t ZSTD_compressLiterals(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + size_t const minGain = ZSTD_minGain(srcSize); + size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); + BYTE *const ostart = (BYTE *)dst; + U32 singleStream = srcSize < 256; + symbolEncodingType_e hType = set_compressed; + size_t cLitSize; + +/* small ? don't even attempt compression (speed opt) */ +#define LITERAL_NOENTROPY 63 + { + size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY; + if (srcSize <= minLitSize) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + } + + if (dstCapacity < lhSize + 1) + return ERROR(dstSize_tooSmall); /* not enough space for compression */ + { + HUF_repeat repeat = zc->flagStaticHufTable; + int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0; + if (repeat == HUF_repeat_valid && lhSize == 3) + singleStream = 1; + cLitSize = singleStream ? HUF_compress1X_repeat(ostart + lhSize, dstCapacity - lhSize, src, srcSize, 255, 11, zc->tmpCounters, + sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat) + : HUF_compress4X_repeat(ostart + lhSize, dstCapacity - lhSize, src, srcSize, 255, 11, zc->tmpCounters, + sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat); + if (repeat != HUF_repeat_none) { + hType = set_repeat; + } /* reused the existing table */ + else { + zc->flagStaticHufTable = HUF_repeat_check; + } /* now have a table to reuse */ + } + + if ((cLitSize == 0) | (cLitSize >= srcSize - minGain)) { + zc->flagStaticHufTable = HUF_repeat_none; + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + } + if (cLitSize == 1) { + zc->flagStaticHufTable = HUF_repeat_none; + return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); + } + + /* Build header */ + switch (lhSize) { + case 3: /* 2 - 2 - 10 - 10 */ + { + U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize << 4) + ((U32)cLitSize << 14); + ZSTD_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + { + U32 const lhc = hType + (2 << 2) + ((U32)srcSize << 4) + ((U32)cLitSize << 18); + ZSTD_writeLE32(ostart, lhc); + break; + } + default: /* should not be necessary, lhSize is only {3,4,5} */ + case 5: /* 2 - 2 - 18 - 18 */ + { + U32 const lhc = hType + (3 << 2) + ((U32)srcSize << 4) + ((U32)cLitSize << 22); + ZSTD_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + } + return lhSize + cLitSize; +} + +static const BYTE LL_Code[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, + 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, + 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}; + +static const BYTE ML_Code[128] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, + 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42}; + +void ZSTD_seqToCodes(const seqStore_t *seqStorePtr) +{ + BYTE const LL_deltaCode = 19; + BYTE const ML_deltaCode = 36; + const seqDef *const sequences = seqStorePtr->sequencesStart; + BYTE *const llCodeTable = seqStorePtr->llCode; + BYTE *const ofCodeTable = seqStorePtr->ofCode; + BYTE *const mlCodeTable = seqStorePtr->mlCode; + U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + U32 u; + for (u = 0; u < nbSeq; u++) { + U32 const llv = sequences[u].litLength; + U32 const mlv = sequences[u].matchLength; + llCodeTable[u] = (llv > 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv]; + ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset); + mlCodeTable[u] = (mlv > 127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv]; + } + if (seqStorePtr->longLengthID == 1) + llCodeTable[seqStorePtr->longLengthPos] = MaxLL; + if (seqStorePtr->longLengthID == 2) + mlCodeTable[seqStorePtr->longLengthPos] = MaxML; +} + +ZSTD_STATIC size_t ZSTD_compressSequences_internal(ZSTD_CCtx *zc, void *dst, size_t dstCapacity) +{ + const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN; + const seqStore_t *seqStorePtr = &(zc->seqStore); + FSE_CTable *CTable_LitLength = zc->litlengthCTable; + FSE_CTable *CTable_OffsetBits = zc->offcodeCTable; + FSE_CTable *CTable_MatchLength = zc->matchlengthCTable; + U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */ + const seqDef *const sequences = seqStorePtr->sequencesStart; + const BYTE *const ofCodeTable = seqStorePtr->ofCode; + const BYTE *const llCodeTable = seqStorePtr->llCode; + const BYTE *const mlCodeTable = seqStorePtr->mlCode; + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstCapacity; + BYTE *op = ostart; + size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; + BYTE *seqHead; + + U32 *count; + S16 *norm; + U32 *workspace; + size_t workspaceSize = sizeof(zc->tmpCounters); + { + size_t spaceUsed32 = 0; + count = (U32 *)zc->tmpCounters + spaceUsed32; + spaceUsed32 += MaxSeq + 1; + norm = (S16 *)((U32 *)zc->tmpCounters + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2; + + workspace = (U32 *)zc->tmpCounters + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + } + + /* Compress literals */ + { + const BYTE *const literals = seqStorePtr->litStart; + size_t const litSize = seqStorePtr->lit - literals; + size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize); + if (ZSTD_isError(cSize)) + return cSize; + op += cSize; + } + + /* Sequences Header */ + if ((oend - op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) + return ERROR(dstSize_tooSmall); + if (nbSeq < 0x7F) + *op++ = (BYTE)nbSeq; + else if (nbSeq < LONGNBSEQ) + op[0] = (BYTE)((nbSeq >> 8) + 0x80), op[1] = (BYTE)nbSeq, op += 2; + else + op[0] = 0xFF, ZSTD_writeLE16(op + 1, (U16)(nbSeq - LONGNBSEQ)), op += 3; + if (nbSeq == 0) + return op - ostart; + + /* seqHead : flags for FSE encoding type */ + seqHead = op++; + +#define MIN_SEQ_FOR_DYNAMIC_FSE 64 +#define MAX_SEQ_FOR_STATIC_FSE 1000 + + /* convert length/distances into codes */ + ZSTD_seqToCodes(seqStorePtr); + + /* CTable for Literal Lengths */ + { + U32 max = MaxLL; + size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { + *op++ = llCodeTable[0]; + FSE_buildCTable_rle(CTable_LitLength, (BYTE)max); + LLtype = set_rle; + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + LLtype = set_repeat; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog - 1)))) { + FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, workspace, workspaceSize); + LLtype = set_basic; + } else { + size_t nbSeq_1 = nbSeq; + const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max); + if (count[llCodeTable[nbSeq - 1]] > 1) { + count[llCodeTable[nbSeq - 1]]--; + nbSeq_1--; + } + FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max); + { + size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */ + if (FSE_isError(NCountSize)) + return NCountSize; + op += NCountSize; + } + FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, workspace, workspaceSize); + LLtype = set_compressed; + } + } + + /* CTable for Offsets */ + { + U32 max = MaxOff; + size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { + *op++ = ofCodeTable[0]; + FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max); + Offtype = set_rle; + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + Offtype = set_repeat; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog - 1)))) { + FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, workspace, workspaceSize); + Offtype = set_basic; + } else { + size_t nbSeq_1 = nbSeq; + const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max); + if (count[ofCodeTable[nbSeq - 1]] > 1) { + count[ofCodeTable[nbSeq - 1]]--; + nbSeq_1--; + } + FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max); + { + size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */ + if (FSE_isError(NCountSize)) + return NCountSize; + op += NCountSize; + } + FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, workspace, workspaceSize); + Offtype = set_compressed; + } + } + + /* CTable for MatchLengths */ + { + U32 max = MaxML; + size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { + *op++ = *mlCodeTable; + FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max); + MLtype = set_rle; + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + MLtype = set_repeat; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog - 1)))) { + FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, workspace, workspaceSize); + MLtype = set_basic; + } else { + size_t nbSeq_1 = nbSeq; + const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max); + if (count[mlCodeTable[nbSeq - 1]] > 1) { + count[mlCodeTable[nbSeq - 1]]--; + nbSeq_1--; + } + FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max); + { + size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */ + if (FSE_isError(NCountSize)) + return NCountSize; + op += NCountSize; + } + FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, workspace, workspaceSize); + MLtype = set_compressed; + } + } + + *seqHead = (BYTE)((LLtype << 6) + (Offtype << 4) + (MLtype << 2)); + zc->flagStaticTables = 0; + + /* Encoding Sequences */ + { + BIT_CStream_t blockStream; + FSE_CState_t stateMatchLength; + FSE_CState_t stateOffsetBits; + FSE_CState_t stateLitLength; + + CHECK_E(BIT_initCStream(&blockStream, op, oend - op), dstSize_tooSmall); /* not enough space remaining */ + + /* first symbols */ + FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq - 1]); + FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq - 1]); + FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq - 1]); + BIT_addBits(&blockStream, sequences[nbSeq - 1].litLength, LL_bits[llCodeTable[nbSeq - 1]]); + if (ZSTD_32bits()) + BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[nbSeq - 1].matchLength, ML_bits[mlCodeTable[nbSeq - 1]]); + if (ZSTD_32bits()) + BIT_flushBits(&blockStream); + if (longOffsets) { + U32 const ofBits = ofCodeTable[nbSeq - 1]; + int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN - 1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[nbSeq - 1].offset, extraBits); + BIT_flushBits(&blockStream); + } + BIT_addBits(&blockStream, sequences[nbSeq - 1].offset >> extraBits, ofBits - extraBits); + } else { + BIT_addBits(&blockStream, sequences[nbSeq - 1].offset, ofCodeTable[nbSeq - 1]); + } + BIT_flushBits(&blockStream); + + { + size_t n; + for (n = nbSeq - 2; n < nbSeq; n--) { /* intentional underflow */ + BYTE const llCode = llCodeTable[n]; + BYTE const ofCode = ofCodeTable[n]; + BYTE const mlCode = mlCodeTable[n]; + U32 const llBits = LL_bits[llCode]; + U32 const ofBits = ofCode; /* 32b*/ /* 64b*/ + U32 const mlBits = ML_bits[mlCode]; + /* (7)*/ /* (7)*/ + FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */ + FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */ + if (ZSTD_32bits()) + BIT_flushBits(&blockStream); /* (7)*/ + FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */ + if (ZSTD_32bits() || (ofBits + mlBits + llBits >= 64 - 7 - (LLFSELog + MLFSELog + OffFSELog))) + BIT_flushBits(&blockStream); /* (7)*/ + BIT_addBits(&blockStream, sequences[n].litLength, llBits); + if (ZSTD_32bits() && ((llBits + mlBits) > 24)) + BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[n].matchLength, mlBits); + if (ZSTD_32bits()) + BIT_flushBits(&blockStream); /* (7)*/ + if (longOffsets) { + int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN - 1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[n].offset, extraBits); + BIT_flushBits(&blockStream); /* (7)*/ + } + BIT_addBits(&blockStream, sequences[n].offset >> extraBits, ofBits - extraBits); /* 31 */ + } else { + BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */ + } + BIT_flushBits(&blockStream); /* (7)*/ + } + } + + FSE_flushCState(&blockStream, &stateMatchLength); + FSE_flushCState(&blockStream, &stateOffsetBits); + FSE_flushCState(&blockStream, &stateLitLength); + + { + size_t const streamSize = BIT_closeCStream(&blockStream); + if (streamSize == 0) + return ERROR(dstSize_tooSmall); /* not enough space */ + op += streamSize; + } + } + return op - ostart; +} + +ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, size_t srcSize) +{ + size_t const cSize = ZSTD_compressSequences_internal(zc, dst, dstCapacity); + size_t const minGain = ZSTD_minGain(srcSize); + size_t const maxCSize = srcSize - minGain; + /* If the srcSize <= dstCapacity, then there is enough space to write a + * raw uncompressed block. Since we ran out of space, the block must not + * be compressible, so fall back to a raw uncompressed block. + */ + int const uncompressibleError = cSize == ERROR(dstSize_tooSmall) && srcSize <= dstCapacity; + int i; + + if (ZSTD_isError(cSize) && !uncompressibleError) + return cSize; + if (cSize >= maxCSize || uncompressibleError) { + zc->flagStaticHufTable = HUF_repeat_none; + return 0; + } + /* confirm repcodes */ + for (i = 0; i < ZSTD_REP_NUM; i++) + zc->rep[i] = zc->repToConfirm[i]; + return cSize; +} + +/*! ZSTD_storeSeq() : + Store a sequence (literal length, literals, offset code and match length code) into seqStore_t. + `offsetCode` : distance to match, or 0 == repCode. + `matchCode` : matchLength - MINMATCH +*/ +ZSTD_STATIC void ZSTD_storeSeq(seqStore_t *seqStorePtr, size_t litLength, const void *literals, U32 offsetCode, size_t matchCode) +{ + /* copy Literals */ + ZSTD_wildcopy(seqStorePtr->lit, literals, litLength); + seqStorePtr->lit += litLength; + + /* literal Length */ + if (litLength > 0xFFFF) { + seqStorePtr->longLengthID = 1; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].litLength = (U16)litLength; + + /* match offset */ + seqStorePtr->sequences[0].offset = offsetCode + 1; + + /* match Length */ + if (matchCode > 0xFFFF) { + seqStorePtr->longLengthID = 2; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].matchLength = (U16)matchCode; + + seqStorePtr->sequences++; +} + +/*-************************************* +* Match length counter +***************************************/ +static unsigned ZSTD_NbCommonBytes(register size_t val) +{ + if (ZSTD_isLittleEndian()) { + if (ZSTD_64bits()) { + return (__builtin_ctzll((U64)val) >> 3); + } else { /* 32 bits */ + return (__builtin_ctz((U32)val) >> 3); + } + } else { /* Big Endian CPU */ + if (ZSTD_64bits()) { + return (__builtin_clzll(val) >> 3); + } else { /* 32 bits */ + return (__builtin_clz((U32)val) >> 3); + } + } +} + +static size_t ZSTD_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *const pInLimit) +{ + const BYTE *const pStart = pIn; + const BYTE *const pInLoopLimit = pInLimit - (sizeof(size_t) - 1); + + while (pIn < pInLoopLimit) { + size_t const diff = ZSTD_readST(pMatch) ^ ZSTD_readST(pIn); + if (!diff) { + pIn += sizeof(size_t); + pMatch += sizeof(size_t); + continue; + } + pIn += ZSTD_NbCommonBytes(diff); + return (size_t)(pIn - pStart); + } + if (ZSTD_64bits()) + if ((pIn < (pInLimit - 3)) && (ZSTD_read32(pMatch) == ZSTD_read32(pIn))) { + pIn += 4; + pMatch += 4; + } + if ((pIn < (pInLimit - 1)) && (ZSTD_read16(pMatch) == ZSTD_read16(pIn))) { + pIn += 2; + pMatch += 2; + } + if ((pIn < pInLimit) && (*pMatch == *pIn)) + pIn++; + return (size_t)(pIn - pStart); +} + +/** ZSTD_count_2segments() : +* can count match length with `ip` & `match` in 2 different segments. +* convention : on reaching mEnd, match count continue starting from iStart +*/ +static size_t ZSTD_count_2segments(const BYTE *ip, const BYTE *match, const BYTE *iEnd, const BYTE *mEnd, const BYTE *iStart) +{ + const BYTE *const vEnd = MIN(ip + (mEnd - match), iEnd); + size_t const matchLength = ZSTD_count(ip, match, vEnd); + if (match + matchLength != mEnd) + return matchLength; + return matchLength + ZSTD_count(ip + matchLength, iStart, iEnd); +} + +/*-************************************* +* Hashes +***************************************/ +static const U32 prime3bytes = 506832829U; +static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32 - 24)) * prime3bytes) >> (32 - h); } +ZSTD_STATIC size_t ZSTD_hash3Ptr(const void *ptr, U32 h) { return ZSTD_hash3(ZSTD_readLE32(ptr), h); } /* only in zstd_opt.h */ + +static const U32 prime4bytes = 2654435761U; +static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32 - h); } +static size_t ZSTD_hash4Ptr(const void *ptr, U32 h) { return ZSTD_hash4(ZSTD_read32(ptr), h); } + +static const U64 prime5bytes = 889523592379ULL; +static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64 - 40)) * prime5bytes) >> (64 - h)); } +static size_t ZSTD_hash5Ptr(const void *p, U32 h) { return ZSTD_hash5(ZSTD_readLE64(p), h); } + +static const U64 prime6bytes = 227718039650203ULL; +static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64 - 48)) * prime6bytes) >> (64 - h)); } +static size_t ZSTD_hash6Ptr(const void *p, U32 h) { return ZSTD_hash6(ZSTD_readLE64(p), h); } + +static const U64 prime7bytes = 58295818150454627ULL; +static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64 - 56)) * prime7bytes) >> (64 - h)); } +static size_t ZSTD_hash7Ptr(const void *p, U32 h) { return ZSTD_hash7(ZSTD_readLE64(p), h); } + +static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; +static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u)*prime8bytes) >> (64 - h)); } +static size_t ZSTD_hash8Ptr(const void *p, U32 h) { return ZSTD_hash8(ZSTD_readLE64(p), h); } + +static size_t ZSTD_hashPtr(const void *p, U32 hBits, U32 mls) +{ + switch (mls) { + // case 3: return ZSTD_hash3Ptr(p, hBits); + default: + case 4: return ZSTD_hash4Ptr(p, hBits); + case 5: return ZSTD_hash5Ptr(p, hBits); + case 6: return ZSTD_hash6Ptr(p, hBits); + case 7: return ZSTD_hash7Ptr(p, hBits); + case 8: return ZSTD_hash8Ptr(p, hBits); + } +} + +/*-************************************* +* Fast Scan +***************************************/ +static void ZSTD_fillHashTable(ZSTD_CCtx *zc, const void *end, const U32 mls) +{ + U32 *const hashTable = zc->hashTable; + U32 const hBits = zc->params.cParams.hashLog; + const BYTE *const base = zc->base; + const BYTE *ip = base + zc->nextToUpdate; + const BYTE *const iend = ((const BYTE *)end) - HASH_READ_SIZE; + const size_t fastHashFillStep = 3; + + while (ip <= iend) { + hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base); + ip += fastHashFillStep; + } +} + +FORCE_INLINE +void ZSTD_compressBlock_fast_generic(ZSTD_CCtx *cctx, const void *src, size_t srcSize, const U32 mls) +{ + U32 *const hashTable = cctx->hashTable; + U32 const hBits = cctx->params.cParams.hashLog; + seqStore_t *seqStorePtr = &(cctx->seqStore); + const BYTE *const base = cctx->base; + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const U32 lowestIndex = cctx->dictLimit; + const BYTE *const lowest = base + lowestIndex; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - HASH_READ_SIZE; + U32 offset_1 = cctx->rep[0], offset_2 = cctx->rep[1]; + U32 offsetSaved = 0; + + /* init */ + ip += (ip == lowest); + { + U32 const maxRep = (U32)(ip - lowest); + if (offset_2 > maxRep) + offsetSaved = offset_2, offset_2 = 0; + if (offset_1 > maxRep) + offsetSaved = offset_1, offset_1 = 0; + } + + /* Main Search Loop */ + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ + size_t mLength; + size_t const h = ZSTD_hashPtr(ip, hBits, mls); + U32 const curr = (U32)(ip - base); + U32 const matchIndex = hashTable[h]; + const BYTE *match = base + matchIndex; + hashTable[h] = curr; /* update hash table */ + + if ((offset_1 > 0) & (ZSTD_read32(ip + 1 - offset_1) == ZSTD_read32(ip + 1))) { + mLength = ZSTD_count(ip + 1 + 4, ip + 1 + 4 - offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH); + } else { + U32 offset; + if ((matchIndex <= lowestIndex) || (ZSTD_read32(match) != ZSTD_read32(ip))) { + ip += ((ip - anchor) >> g_searchStrength) + 1; + continue; + } + mLength = ZSTD_count(ip + 4, match + 4, iend) + 4; + offset = (U32)(ip - match); + while (((ip > anchor) & (match > lowest)) && (ip[-1] == match[-1])) { + ip--; + match--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH); + } + + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Fill Table */ + hashTable[ZSTD_hashPtr(base + curr + 2, hBits, mls)] = curr + 2; /* here because curr+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip - 2, hBits, mls)] = (U32)(ip - 2 - base); + /* check immediate repcode */ + while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip + 4, ip + 4 - offset_2, iend) + 4; + { + U32 const tmpOff = offset_2; + offset_2 = offset_1; + offset_1 = tmpOff; + } /* swap offset_2 <=> offset_1 */ + hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength - MINMATCH); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + } + + /* save reps for next block */ + cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved; + cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved; + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +static void ZSTD_compressBlock_fast(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + const U32 mls = ctx->params.cParams.searchLength; + switch (mls) { + default: /* includes case 3 */ + case 4: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return; + case 5: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return; + case 6: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return; + case 7: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return; + } +} + +static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 mls) +{ + U32 *hashTable = ctx->hashTable; + const U32 hBits = ctx->params.cParams.hashLog; + seqStore_t *seqStorePtr = &(ctx->seqStore); + const BYTE *const base = ctx->base; + const BYTE *const dictBase = ctx->dictBase; + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const U32 lowestIndex = ctx->lowLimit; + const BYTE *const dictStart = dictBase + lowestIndex; + const U32 dictLimit = ctx->dictLimit; + const BYTE *const lowPrefixPtr = base + dictLimit; + const BYTE *const dictEnd = dictBase + dictLimit; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - 8; + U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1]; + + /* Search Loop */ + while (ip < ilimit) { /* < instead of <=, because (ip+1) */ + const size_t h = ZSTD_hashPtr(ip, hBits, mls); + const U32 matchIndex = hashTable[h]; + const BYTE *matchBase = matchIndex < dictLimit ? dictBase : base; + const BYTE *match = matchBase + matchIndex; + const U32 curr = (U32)(ip - base); + const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */ + const BYTE *repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *repMatch = repBase + repIndex; + size_t mLength; + hashTable[h] = curr; /* update hash table */ + + if ((((U32)((dictLimit - 1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex)) && + (ZSTD_read32(repMatch) == ZSTD_read32(ip + 1))) { + const BYTE *repMatchEnd = repIndex < dictLimit ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip + 1 + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32; + ip++; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH); + } else { + if ((matchIndex < lowestIndex) || (ZSTD_read32(match) != ZSTD_read32(ip))) { + ip += ((ip - anchor) >> g_searchStrength) + 1; + continue; + } + { + const BYTE *matchEnd = matchIndex < dictLimit ? dictEnd : iend; + const BYTE *lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr; + U32 offset; + mLength = ZSTD_count_2segments(ip + EQUAL_READ32, match + EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32; + while (((ip > anchor) & (match > lowMatchPtr)) && (ip[-1] == match[-1])) { + ip--; + match--; + mLength++; + } /* catch up */ + offset = curr - matchIndex; + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH); + } + } + + /* found a match : store it */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Fill Table */ + hashTable[ZSTD_hashPtr(base + curr + 2, hBits, mls)] = curr + 2; + hashTable[ZSTD_hashPtr(ip - 2, hBits, mls)] = (U32)(ip - 2 - base); + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const curr2 = (U32)(ip - base); + U32 const repIndex2 = curr2 - offset_2; + const BYTE *repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2; + if ((((U32)((dictLimit - 1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */ + && (ZSTD_read32(repMatch2) == ZSTD_read32(ip))) { + const BYTE *const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend; + size_t repLength2 = + ZSTD_count_2segments(ip + EQUAL_READ32, repMatch2 + EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32; + U32 tmpOffset = offset_2; + offset_2 = offset_1; + offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2 - MINMATCH); + hashTable[ZSTD_hashPtr(ip, hBits, mls)] = curr2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } + } + } + + /* save reps for next block */ + ctx->repToConfirm[0] = offset_1; + ctx->repToConfirm[1] = offset_2; + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + U32 const mls = ctx->params.cParams.searchLength; + switch (mls) { + default: /* includes case 3 */ + case 4: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return; + case 5: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return; + case 6: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return; + case 7: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return; + } +} + +/*-************************************* +* Double Fast +***************************************/ +static void ZSTD_fillDoubleHashTable(ZSTD_CCtx *cctx, const void *end, const U32 mls) +{ + U32 *const hashLarge = cctx->hashTable; + U32 const hBitsL = cctx->params.cParams.hashLog; + U32 *const hashSmall = cctx->chainTable; + U32 const hBitsS = cctx->params.cParams.chainLog; + const BYTE *const base = cctx->base; + const BYTE *ip = base + cctx->nextToUpdate; + const BYTE *const iend = ((const BYTE *)end) - HASH_READ_SIZE; + const size_t fastHashFillStep = 3; + + while (ip <= iend) { + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base); + hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base); + ip += fastHashFillStep; + } +} + +FORCE_INLINE +void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx *cctx, const void *src, size_t srcSize, const U32 mls) +{ + U32 *const hashLong = cctx->hashTable; + const U32 hBitsL = cctx->params.cParams.hashLog; + U32 *const hashSmall = cctx->chainTable; + const U32 hBitsS = cctx->params.cParams.chainLog; + seqStore_t *seqStorePtr = &(cctx->seqStore); + const BYTE *const base = cctx->base; + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const U32 lowestIndex = cctx->dictLimit; + const BYTE *const lowest = base + lowestIndex; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - HASH_READ_SIZE; + U32 offset_1 = cctx->rep[0], offset_2 = cctx->rep[1]; + U32 offsetSaved = 0; + + /* init */ + ip += (ip == lowest); + { + U32 const maxRep = (U32)(ip - lowest); + if (offset_2 > maxRep) + offsetSaved = offset_2, offset_2 = 0; + if (offset_1 > maxRep) + offsetSaved = offset_1, offset_1 = 0; + } + + /* Main Search Loop */ + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ + size_t mLength; + size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); + size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); + U32 const curr = (U32)(ip - base); + U32 const matchIndexL = hashLong[h2]; + U32 const matchIndexS = hashSmall[h]; + const BYTE *matchLong = base + matchIndexL; + const BYTE *match = base + matchIndexS; + hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ + + if ((offset_1 > 0) & (ZSTD_read32(ip + 1 - offset_1) == ZSTD_read32(ip + 1))) { /* note : by construction, offset_1 <= curr */ + mLength = ZSTD_count(ip + 1 + 4, ip + 1 + 4 - offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH); + } else { + U32 offset; + if ((matchIndexL > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip))) { + mLength = ZSTD_count(ip + 8, matchLong + 8, iend) + 8; + offset = (U32)(ip - matchLong); + while (((ip > anchor) & (matchLong > lowest)) && (ip[-1] == matchLong[-1])) { + ip--; + matchLong--; + mLength++; + } /* catch up */ + } else if ((matchIndexS > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip))) { + size_t const h3 = ZSTD_hashPtr(ip + 1, hBitsL, 8); + U32 const matchIndex3 = hashLong[h3]; + const BYTE *match3 = base + matchIndex3; + hashLong[h3] = curr + 1; + if ((matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip + 1))) { + mLength = ZSTD_count(ip + 9, match3 + 8, iend) + 8; + ip++; + offset = (U32)(ip - match3); + while (((ip > anchor) & (match3 > lowest)) && (ip[-1] == match3[-1])) { + ip--; + match3--; + mLength++; + } /* catch up */ + } else { + mLength = ZSTD_count(ip + 4, match + 4, iend) + 4; + offset = (U32)(ip - match); + while (((ip > anchor) & (match > lowest)) && (ip[-1] == match[-1])) { + ip--; + match--; + mLength++; + } /* catch up */ + } + } else { + ip += ((ip - anchor) >> g_searchStrength) + 1; + continue; + } + + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH); + } + + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Fill Table */ + hashLong[ZSTD_hashPtr(base + curr + 2, hBitsL, 8)] = hashSmall[ZSTD_hashPtr(base + curr + 2, hBitsS, mls)] = + curr + 2; /* here because curr+2 could be > iend-8 */ + hashLong[ZSTD_hashPtr(ip - 2, hBitsL, 8)] = hashSmall[ZSTD_hashPtr(ip - 2, hBitsS, mls)] = (U32)(ip - 2 - base); + + /* check immediate repcode */ + while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip + 4, ip + 4 - offset_2, iend) + 4; + { + U32 const tmpOff = offset_2; + offset_2 = offset_1; + offset_1 = tmpOff; + } /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength - MINMATCH); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + } + + /* save reps for next block */ + cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved; + cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved; + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + const U32 mls = ctx->params.cParams.searchLength; + switch (mls) { + default: /* includes case 3 */ + case 4: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return; + case 5: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return; + case 6: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return; + case 7: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return; + } +} + +static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 mls) +{ + U32 *const hashLong = ctx->hashTable; + U32 const hBitsL = ctx->params.cParams.hashLog; + U32 *const hashSmall = ctx->chainTable; + U32 const hBitsS = ctx->params.cParams.chainLog; + seqStore_t *seqStorePtr = &(ctx->seqStore); + const BYTE *const base = ctx->base; + const BYTE *const dictBase = ctx->dictBase; + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const U32 lowestIndex = ctx->lowLimit; + const BYTE *const dictStart = dictBase + lowestIndex; + const U32 dictLimit = ctx->dictLimit; + const BYTE *const lowPrefixPtr = base + dictLimit; + const BYTE *const dictEnd = dictBase + dictLimit; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - 8; + U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1]; + + /* Search Loop */ + while (ip < ilimit) { /* < instead of <=, because (ip+1) */ + const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 matchIndex = hashSmall[hSmall]; + const BYTE *matchBase = matchIndex < dictLimit ? dictBase : base; + const BYTE *match = matchBase + matchIndex; + + const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8); + const U32 matchLongIndex = hashLong[hLong]; + const BYTE *matchLongBase = matchLongIndex < dictLimit ? dictBase : base; + const BYTE *matchLong = matchLongBase + matchLongIndex; + + const U32 curr = (U32)(ip - base); + const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */ + const BYTE *repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *repMatch = repBase + repIndex; + size_t mLength; + hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ + + if ((((U32)((dictLimit - 1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex)) && + (ZSTD_read32(repMatch) == ZSTD_read32(ip + 1))) { + const BYTE *repMatchEnd = repIndex < dictLimit ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip + 1 + 4, repMatch + 4, iend, repMatchEnd, lowPrefixPtr) + 4; + ip++; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH); + } else { + if ((matchLongIndex > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip))) { + const BYTE *matchEnd = matchLongIndex < dictLimit ? dictEnd : iend; + const BYTE *lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr; + U32 offset; + mLength = ZSTD_count_2segments(ip + 8, matchLong + 8, iend, matchEnd, lowPrefixPtr) + 8; + offset = curr - matchLongIndex; + while (((ip > anchor) & (matchLong > lowMatchPtr)) && (ip[-1] == matchLong[-1])) { + ip--; + matchLong--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH); + + } else if ((matchIndex > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip))) { + size_t const h3 = ZSTD_hashPtr(ip + 1, hBitsL, 8); + U32 const matchIndex3 = hashLong[h3]; + const BYTE *const match3Base = matchIndex3 < dictLimit ? dictBase : base; + const BYTE *match3 = match3Base + matchIndex3; + U32 offset; + hashLong[h3] = curr + 1; + if ((matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip + 1))) { + const BYTE *matchEnd = matchIndex3 < dictLimit ? dictEnd : iend; + const BYTE *lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr; + mLength = ZSTD_count_2segments(ip + 9, match3 + 8, iend, matchEnd, lowPrefixPtr) + 8; + ip++; + offset = curr + 1 - matchIndex3; + while (((ip > anchor) & (match3 > lowMatchPtr)) && (ip[-1] == match3[-1])) { + ip--; + match3--; + mLength++; + } /* catch up */ + } else { + const BYTE *matchEnd = matchIndex < dictLimit ? dictEnd : iend; + const BYTE *lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr; + mLength = ZSTD_count_2segments(ip + 4, match + 4, iend, matchEnd, lowPrefixPtr) + 4; + offset = curr - matchIndex; + while (((ip > anchor) & (match > lowMatchPtr)) && (ip[-1] == match[-1])) { + ip--; + match--; + mLength++; + } /* catch up */ + } + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH); + + } else { + ip += ((ip - anchor) >> g_searchStrength) + 1; + continue; + } + } + + /* found a match : store it */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Fill Table */ + hashSmall[ZSTD_hashPtr(base + curr + 2, hBitsS, mls)] = curr + 2; + hashLong[ZSTD_hashPtr(base + curr + 2, hBitsL, 8)] = curr + 2; + hashSmall[ZSTD_hashPtr(ip - 2, hBitsS, mls)] = (U32)(ip - 2 - base); + hashLong[ZSTD_hashPtr(ip - 2, hBitsL, 8)] = (U32)(ip - 2 - base); + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const curr2 = (U32)(ip - base); + U32 const repIndex2 = curr2 - offset_2; + const BYTE *repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2; + if ((((U32)((dictLimit - 1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */ + && (ZSTD_read32(repMatch2) == ZSTD_read32(ip))) { + const BYTE *const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend; + size_t const repLength2 = + ZSTD_count_2segments(ip + EQUAL_READ32, repMatch2 + EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32; + U32 tmpOffset = offset_2; + offset_2 = offset_1; + offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2 - MINMATCH); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = curr2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = curr2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } + } + } + + /* save reps for next block */ + ctx->repToConfirm[0] = offset_1; + ctx->repToConfirm[1] = offset_2; + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + U32 const mls = ctx->params.cParams.searchLength; + switch (mls) { + default: /* includes case 3 */ + case 4: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return; + case 5: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return; + case 6: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return; + case 7: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return; + } +} + +/*-************************************* +* Binary Tree search +***************************************/ +/** ZSTD_insertBt1() : add one or multiple positions to tree. +* ip : assumed <= iend-8 . +* @return : nb of positions added */ +static U32 ZSTD_insertBt1(ZSTD_CCtx *zc, const BYTE *const ip, const U32 mls, const BYTE *const iend, U32 nbCompares, U32 extDict) +{ + U32 *const hashTable = zc->hashTable; + U32 const hashLog = zc->params.cParams.hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 *const bt = zc->chainTable; + U32 const btLog = zc->params.cParams.chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 matchIndex = hashTable[h]; + size_t commonLengthSmaller = 0, commonLengthLarger = 0; + const BYTE *const base = zc->base; + const BYTE *const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE *const dictEnd = dictBase + dictLimit; + const BYTE *const prefixStart = base + dictLimit; + const BYTE *match; + const U32 curr = (U32)(ip - base); + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + U32 *smallerPtr = bt + 2 * (curr & btMask); + U32 *largerPtr = smallerPtr + 1; + U32 dummy32; /* to be nullified at the end */ + U32 const windowLow = zc->lowLimit; + U32 matchEndIdx = curr + 8; + size_t bestLength = 8; + + hashTable[h] = curr; /* Update Hash Table */ + + while (nbCompares-- && (matchIndex > windowLow)) { + U32 *const nextPtr = bt + 2 * (matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + + if ((!extDict) || (matchIndex + matchLength >= dictLimit)) { + match = base + matchIndex; + if (match[matchLength] == ip[matchLength]) + matchLength += ZSTD_count(ip + matchLength + 1, match + matchLength + 1, iend) + 1; + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip + matchLength, match + matchLength, iend, dictEnd, prefixStart); + if (matchIndex + matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + bestLength = matchLength; + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + } + + if (ip + matchLength == iend) /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */ + + if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */ + /* match is smaller than curr */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { + smallerPtr = &dummy32; + break; + } /* beyond tree size, stop the search */ + smallerPtr = nextPtr + 1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to curr) */ + } else { + /* match is larger than curr */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { + largerPtr = &dummy32; + break; + } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } + } + + *smallerPtr = *largerPtr = 0; + if (bestLength > 384) + return MIN(192, (U32)(bestLength - 384)); /* speed optimization */ + if (matchEndIdx > curr + 8) + return matchEndIdx - curr - 8; + return 1; +} + +static size_t ZSTD_insertBtAndFindBestMatch(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iend, size_t *offsetPtr, U32 nbCompares, const U32 mls, + U32 extDict) +{ + U32 *const hashTable = zc->hashTable; + U32 const hashLog = zc->params.cParams.hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 *const bt = zc->chainTable; + U32 const btLog = zc->params.cParams.chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 matchIndex = hashTable[h]; + size_t commonLengthSmaller = 0, commonLengthLarger = 0; + const BYTE *const base = zc->base; + const BYTE *const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE *const dictEnd = dictBase + dictLimit; + const BYTE *const prefixStart = base + dictLimit; + const U32 curr = (U32)(ip - base); + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + const U32 windowLow = zc->lowLimit; + U32 *smallerPtr = bt + 2 * (curr & btMask); + U32 *largerPtr = bt + 2 * (curr & btMask) + 1; + U32 matchEndIdx = curr + 8; + U32 dummy32; /* to be nullified at the end */ + size_t bestLength = 0; + + hashTable[h] = curr; /* Update Hash Table */ + + while (nbCompares-- && (matchIndex > windowLow)) { + U32 *const nextPtr = bt + 2 * (matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE *match; + + if ((!extDict) || (matchIndex + matchLength >= dictLimit)) { + match = base + matchIndex; + if (match[matchLength] == ip[matchLength]) + matchLength += ZSTD_count(ip + matchLength + 1, match + matchLength + 1, iend) + 1; + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip + matchLength, match + matchLength, iend, dictEnd, prefixStart); + if (matchIndex + matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + if ((4 * (int)(matchLength - bestLength)) > (int)(ZSTD_highbit32(curr - matchIndex + 1) - ZSTD_highbit32((U32)offsetPtr[0] + 1))) + bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex; + if (ip + matchLength == iend) /* equal : no way to know if inf or sup */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + + if (match[matchLength] < ip[matchLength]) { + /* match is smaller than curr */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { + smallerPtr = &dummy32; + break; + } /* beyond tree size, stop the search */ + smallerPtr = nextPtr + 1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to curr) */ + } else { + /* match is larger than curr */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { + largerPtr = &dummy32; + break; + } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } + } + + *smallerPtr = *largerPtr = 0; + + zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr + 1; + return bestLength; +} + +static void ZSTD_updateTree(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iend, const U32 nbCompares, const U32 mls) +{ + const BYTE *const base = zc->base; + const U32 target = (U32)(ip - base); + U32 idx = zc->nextToUpdate; + + while (idx < target) + idx += ZSTD_insertBt1(zc, base + idx, mls, iend, nbCompares, 0); +} + +/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */ +static size_t ZSTD_BtFindBestMatch(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 mls) +{ + if (ip < zc->base + zc->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls); + return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0); +} + +static size_t ZSTD_BtFindBestMatch_selectMLS(ZSTD_CCtx *zc, /* Index table will be updated */ + const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 matchLengthSearch) +{ + switch (matchLengthSearch) { + default: /* includes case 3 */ + case 4: return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4); + case 5: return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5); + case 7: + case 6: return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6); + } +} + +static void ZSTD_updateTree_extDict(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iend, const U32 nbCompares, const U32 mls) +{ + const BYTE *const base = zc->base; + const U32 target = (U32)(ip - base); + U32 idx = zc->nextToUpdate; + + while (idx < target) + idx += ZSTD_insertBt1(zc, base + idx, mls, iend, nbCompares, 1); +} + +/** Tree updater, providing best match */ +static size_t ZSTD_BtFindBestMatch_extDict(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, + const U32 mls) +{ + if (ip < zc->base + zc->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls); + return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1); +} + +static size_t ZSTD_BtFindBestMatch_selectMLS_extDict(ZSTD_CCtx *zc, /* Index table will be updated */ + const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, + const U32 matchLengthSearch) +{ + switch (matchLengthSearch) { + default: /* includes case 3 */ + case 4: return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4); + case 5: return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5); + case 7: + case 6: return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6); + } +} + +/* ********************************* +* Hash Chain +***********************************/ +#define NEXT_IN_CHAIN(d, mask) chainTable[(d)&mask] + +/* Update chains up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +FORCE_INLINE +U32 ZSTD_insertAndFindFirstIndex(ZSTD_CCtx *zc, const BYTE *ip, U32 mls) +{ + U32 *const hashTable = zc->hashTable; + const U32 hashLog = zc->params.cParams.hashLog; + U32 *const chainTable = zc->chainTable; + const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1; + const BYTE *const base = zc->base; + const U32 target = (U32)(ip - base); + U32 idx = zc->nextToUpdate; + + while (idx < target) { /* catch up */ + size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); + NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; + hashTable[h] = idx; + idx++; + } + + zc->nextToUpdate = target; + return hashTable[ZSTD_hashPtr(ip, hashLog, mls)]; +} + +/* inlining is important to hardwire a hot branch (template emulation) */ +FORCE_INLINE +size_t ZSTD_HcFindBestMatch_generic(ZSTD_CCtx *zc, /* Index table will be updated */ + const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 mls, + const U32 extDict) +{ + U32 *const chainTable = zc->chainTable; + const U32 chainSize = (1 << zc->params.cParams.chainLog); + const U32 chainMask = chainSize - 1; + const BYTE *const base = zc->base; + const BYTE *const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE *const prefixStart = base + dictLimit; + const BYTE *const dictEnd = dictBase + dictLimit; + const U32 lowLimit = zc->lowLimit; + const U32 curr = (U32)(ip - base); + const U32 minChain = curr > chainSize ? curr - chainSize : 0; + int nbAttempts = maxNbAttempts; + size_t ml = EQUAL_READ32 - 1; + + /* HC4 match finder */ + U32 matchIndex = ZSTD_insertAndFindFirstIndex(zc, ip, mls); + + for (; (matchIndex > lowLimit) & (nbAttempts > 0); nbAttempts--) { + const BYTE *match; + size_t currMl = 0; + if ((!extDict) || matchIndex >= dictLimit) { + match = base + matchIndex; + if (match[ml] == ip[ml]) /* potentially better */ + currMl = ZSTD_count(ip, match, iLimit); + } else { + match = dictBase + matchIndex; + if (ZSTD_read32(match) == ZSTD_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currMl = ZSTD_count_2segments(ip + EQUAL_READ32, match + EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32; + } + + /* save best solution */ + if (currMl > ml) { + ml = currMl; + *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE; + if (ip + currMl == iLimit) + break; /* best possible, and avoid read overflow*/ + } + + if (matchIndex <= minChain) + break; + matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); + } + + return ml; +} + +FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS(ZSTD_CCtx *zc, const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, + const U32 matchLengthSearch) +{ + switch (matchLengthSearch) { + default: /* includes case 3 */ + case 4: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0); + case 5: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0); + case 7: + case 6: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0); + } +} + +FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS(ZSTD_CCtx *zc, const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, + const U32 matchLengthSearch) +{ + switch (matchLengthSearch) { + default: /* includes case 3 */ + case 4: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1); + case 5: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1); + case 7: + case 6: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1); + } +} + +/* ******************************* +* Common parser - lazy strategy +*********************************/ +FORCE_INLINE +void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 searchMethod, const U32 depth) +{ + seqStore_t *seqStorePtr = &(ctx->seqStore); + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - 8; + const BYTE *const base = ctx->base + ctx->dictLimit; + + U32 const maxSearches = 1 << ctx->params.cParams.searchLog; + U32 const mls = ctx->params.cParams.searchLength; + + typedef size_t (*searchMax_f)(ZSTD_CCtx * zc, const BYTE *ip, const BYTE *iLimit, size_t *offsetPtr, U32 maxNbAttempts, U32 matchLengthSearch); + searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; + U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset = 0; + + /* init */ + ip += (ip == base); + ctx->nextToUpdate3 = ctx->nextToUpdate; + { + U32 const maxRep = (U32)(ip - base); + if (offset_2 > maxRep) + savedOffset = offset_2, offset_2 = 0; + if (offset_1 > maxRep) + savedOffset = offset_1, offset_1 = 0; + } + + /* Match Loop */ + while (ip < ilimit) { + size_t matchLength = 0; + size_t offset = 0; + const BYTE *start = ip + 1; + + /* check repCode */ + if ((offset_1 > 0) & (ZSTD_read32(ip + 1) == ZSTD_read32(ip + 1 - offset_1))) { + /* repcode : we take it */ + matchLength = ZSTD_count(ip + 1 + EQUAL_READ32, ip + 1 + EQUAL_READ32 - offset_1, iend) + EQUAL_READ32; + if (depth == 0) + goto _storeSequence; + } + + /* first search (depth 0) */ + { + size_t offsetFound = 99999999; + size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offset = offsetFound; + } + + if (matchLength < EQUAL_READ32) { + ip += ((ip - anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + continue; + } + + /* let's try to find a better solution */ + if (depth >= 1) + while (ip < ilimit) { + ip++; + if ((offset) && ((offset_1 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip + EQUAL_READ32, ip + EQUAL_READ32 - offset_1, iend) + EQUAL_READ32; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength * 3 - ZSTD_highbit32((U32)offset + 1) + 1); + if ((mlRep >= EQUAL_READ32) && (gain2 > gain1)) + matchLength = mlRep, offset = 0, start = ip; + } + { + size_t offset2 = 99999999; + size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); + int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */ + int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 4); + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; + continue; /* search a better one */ + } + } + + /* let's find an even better one */ + if ((depth == 2) && (ip < ilimit)) { + ip++; + if ((offset) && ((offset_1 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) { + size_t const ml2 = ZSTD_count(ip + EQUAL_READ32, ip + EQUAL_READ32 - offset_1, iend) + EQUAL_READ32; + int const gain2 = (int)(ml2 * 4); + int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 1); + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) + matchLength = ml2, offset = 0, start = ip; + } + { + size_t offset2 = 99999999; + size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); + int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */ + int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 7); + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; + continue; + } + } + } + break; /* nothing found : store previous solution */ + } + + /* NOTE: + * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior. + * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which + * overflows the pointer, which is undefined behavior. + */ + /* catch up */ + if (offset) { + while ((start > anchor) && (start > base + offset - ZSTD_REP_MOVE) && + (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1])) /* only search for offset within prefix */ + { + start--; + matchLength++; + } + offset_2 = offset_1; + offset_1 = (U32)(offset - ZSTD_REP_MOVE); + } + + /* store sequence */ +_storeSequence: + { + size_t const litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH); + anchor = ip = start + matchLength; + } + + /* check immediate repcode */ + while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) { + /* store sequence */ + matchLength = ZSTD_count(ip + EQUAL_READ32, ip + EQUAL_READ32 - offset_2, iend) + EQUAL_READ32; + offset = offset_2; + offset_2 = offset_1; + offset_1 = (U32)offset; /* swap repcodes */ + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength - MINMATCH); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + + /* Save reps for next block */ + ctx->repToConfirm[0] = offset_1 ? offset_1 : savedOffset; + ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset; + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2); } + +static void ZSTD_compressBlock_lazy2(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2); } + +static void ZSTD_compressBlock_lazy(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1); } + +static void ZSTD_compressBlock_greedy(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0); } + +FORCE_INLINE +void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 searchMethod, const U32 depth) +{ + seqStore_t *seqStorePtr = &(ctx->seqStore); + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - 8; + const BYTE *const base = ctx->base; + const U32 dictLimit = ctx->dictLimit; + const U32 lowestIndex = ctx->lowLimit; + const BYTE *const prefixStart = base + dictLimit; + const BYTE *const dictBase = ctx->dictBase; + const BYTE *const dictEnd = dictBase + dictLimit; + const BYTE *const dictStart = dictBase + ctx->lowLimit; + + const U32 maxSearches = 1 << ctx->params.cParams.searchLog; + const U32 mls = ctx->params.cParams.searchLength; + + typedef size_t (*searchMax_f)(ZSTD_CCtx * zc, const BYTE *ip, const BYTE *iLimit, size_t *offsetPtr, U32 maxNbAttempts, U32 matchLengthSearch); + searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS; + + U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1]; + + /* init */ + ctx->nextToUpdate3 = ctx->nextToUpdate; + ip += (ip == prefixStart); + + /* Match Loop */ + while (ip < ilimit) { + size_t matchLength = 0; + size_t offset = 0; + const BYTE *start = ip + 1; + U32 curr = (U32)(ip - base); + + /* check repCode */ + { + const U32 repIndex = (U32)(curr + 1 - offset_1); + const BYTE *const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *const repMatch = repBase + repIndex; + if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */ + if (ZSTD_read32(ip + 1) == ZSTD_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = + ZSTD_count_2segments(ip + 1 + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; + if (depth == 0) + goto _storeSequence; + } + } + + /* first search (depth 0) */ + { + size_t offsetFound = 99999999; + size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offset = offsetFound; + } + + if (matchLength < EQUAL_READ32) { + ip += ((ip - anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + continue; + } + + /* let's try to find a better solution */ + if (depth >= 1) + while (ip < ilimit) { + ip++; + curr++; + /* check repCode */ + if (offset) { + const U32 repIndex = (U32)(curr - offset_1); + const BYTE *const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *const repMatch = repBase + repIndex; + if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */ + if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) { + /* repcode detected */ + const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = + ZSTD_count_2segments(ip + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repEnd, prefixStart) + + EQUAL_READ32; + int const gain2 = (int)(repLength * 3); + int const gain1 = (int)(matchLength * 3 - ZSTD_highbit32((U32)offset + 1) + 1); + if ((repLength >= EQUAL_READ32) && (gain2 > gain1)) + matchLength = repLength, offset = 0, start = ip; + } + } + + /* search match, depth 1 */ + { + size_t offset2 = 99999999; + size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); + int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */ + int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 4); + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; + continue; /* search a better one */ + } + } + + /* let's find an even better one */ + if ((depth == 2) && (ip < ilimit)) { + ip++; + curr++; + /* check repCode */ + if (offset) { + const U32 repIndex = (U32)(curr - offset_1); + const BYTE *const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *const repMatch = repBase + repIndex; + if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */ + if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) { + /* repcode detected */ + const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t repLength = ZSTD_count_2segments(ip + EQUAL_READ32, repMatch + EQUAL_READ32, iend, + repEnd, prefixStart) + + EQUAL_READ32; + int gain2 = (int)(repLength * 4); + int gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 1); + if ((repLength >= EQUAL_READ32) && (gain2 > gain1)) + matchLength = repLength, offset = 0, start = ip; + } + } + + /* search match, depth 2 */ + { + size_t offset2 = 99999999; + size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); + int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */ + int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 7); + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; + continue; + } + } + } + break; /* nothing found : store previous solution */ + } + + /* catch up */ + if (offset) { + U32 const matchIndex = (U32)((start - base) - (offset - ZSTD_REP_MOVE)); + const BYTE *match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; + const BYTE *const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; + while ((start > anchor) && (match > mStart) && (start[-1] == match[-1])) { + start--; + match--; + matchLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = (U32)(offset - ZSTD_REP_MOVE); + } + + /* store sequence */ + _storeSequence : { + size_t const litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH); + anchor = ip = start + matchLength; + } + + /* check immediate repcode */ + while (ip <= ilimit) { + const U32 repIndex = (U32)((ip - base) - offset_2); + const BYTE *const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *const repMatch = repBase + repIndex; + if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */ + if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = + ZSTD_count_2segments(ip + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; + offset = offset_2; + offset_2 = offset_1; + offset_1 = (U32)offset; /* swap offset history */ + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength - MINMATCH); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + break; + } + } + + /* Save reps for next block */ + ctx->repToConfirm[0] = offset_1; + ctx->repToConfirm[1] = offset_2; + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0); } + +static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1); +} + +static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2); +} + +static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ + ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2); +} + +/* The optimal parser */ +#include "zstd_opt.h" + +static void ZSTD_compressBlock_btopt(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ +#ifdef ZSTD_OPT_H_91842398743 + ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0); +#else + (void)ctx; + (void)src; + (void)srcSize; + return; +#endif +} + +static void ZSTD_compressBlock_btopt2(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ +#ifdef ZSTD_OPT_H_91842398743 + ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1); +#else + (void)ctx; + (void)src; + (void)srcSize; + return; +#endif +} + +static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ +#ifdef ZSTD_OPT_H_91842398743 + ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0); +#else + (void)ctx; + (void)src; + (void)srcSize; + return; +#endif +} + +static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) +{ +#ifdef ZSTD_OPT_H_91842398743 + ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1); +#else + (void)ctx; + (void)src; + (void)srcSize; + return; +#endif +} + +typedef void (*ZSTD_blockCompressor)(ZSTD_CCtx *ctx, const void *src, size_t srcSize); + +static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) +{ + static const ZSTD_blockCompressor blockCompressor[2][8] = { + {ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, + ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2}, + {ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict, + ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict}}; + + return blockCompressor[extDict][(U32)strat]; +} + +static size_t ZSTD_compressBlock_internal(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit); + const BYTE *const base = zc->base; + const BYTE *const istart = (const BYTE *)src; + const U32 curr = (U32)(istart - base); + if (srcSize < MIN_CBLOCK_SIZE + ZSTD_blockHeaderSize + 1) + return 0; /* don't even attempt compression below a certain srcSize */ + ZSTD_resetSeqStore(&(zc->seqStore)); + if (curr > zc->nextToUpdate + 384) + zc->nextToUpdate = curr - MIN(192, (U32)(curr - zc->nextToUpdate - 384)); /* update tree not updated after finding very long rep matches */ + blockCompressor(zc, src, srcSize); + return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize); +} + +/*! ZSTD_compress_generic() : +* Compress a chunk of data into one or multiple blocks. +* All blocks will be terminated, all input will be consumed. +* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content. +* Frame is supposed already started (header already produced) +* @return : compressed size, or an error code +*/ +static size_t ZSTD_compress_generic(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastFrameChunk) +{ + size_t blockSize = cctx->blockSize; + size_t remaining = srcSize; + const BYTE *ip = (const BYTE *)src; + BYTE *const ostart = (BYTE *)dst; + BYTE *op = ostart; + U32 const maxDist = 1 << cctx->params.cParams.windowLog; + + if (cctx->params.fParams.checksumFlag && srcSize) + xxh64_update(&cctx->xxhState, src, srcSize); + + while (remaining) { + U32 const lastBlock = lastFrameChunk & (blockSize >= remaining); + size_t cSize; + + if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) + return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */ + if (remaining < blockSize) + blockSize = remaining; + + /* preemptive overflow correction */ + if (cctx->lowLimit > (3U << 29)) { + U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1; + U32 const curr = (U32)(ip - cctx->base); + U32 const newCurr = (curr & cycleMask) + (1 << cctx->params.cParams.windowLog); + U32 const correction = curr - newCurr; + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30); + ZSTD_reduceIndex(cctx, correction); + cctx->base += correction; + cctx->dictBase += correction; + cctx->lowLimit -= correction; + cctx->dictLimit -= correction; + if (cctx->nextToUpdate < correction) + cctx->nextToUpdate = 0; + else + cctx->nextToUpdate -= correction; + } + + if ((U32)(ip + blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) { + /* enforce maxDist */ + U32 const newLowLimit = (U32)(ip + blockSize - cctx->base) - maxDist; + if (cctx->lowLimit < newLowLimit) + cctx->lowLimit = newLowLimit; + if (cctx->dictLimit < cctx->lowLimit) + cctx->dictLimit = cctx->lowLimit; + } + + cSize = ZSTD_compressBlock_internal(cctx, op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize, ip, blockSize); + if (ZSTD_isError(cSize)) + return cSize; + + if (cSize == 0) { /* block is not compressible */ + U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw) << 1) + (U32)(blockSize << 3); + if (blockSize + ZSTD_blockHeaderSize > dstCapacity) + return ERROR(dstSize_tooSmall); + ZSTD_writeLE32(op, cBlockHeader24); /* no pb, 4th byte will be overwritten */ + memcpy(op + ZSTD_blockHeaderSize, ip, blockSize); + cSize = ZSTD_blockHeaderSize + blockSize; + } else { + U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed) << 1) + (U32)(cSize << 3); + ZSTD_writeLE24(op, cBlockHeader24); + cSize += ZSTD_blockHeaderSize; + } + + remaining -= blockSize; + dstCapacity -= cSize; + ip += blockSize; + op += cSize; + } + + if (lastFrameChunk && (op > ostart)) + cctx->stage = ZSTDcs_ending; + return op - ostart; +} + +static size_t ZSTD_writeFrameHeader(void *dst, size_t dstCapacity, ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID) +{ + BYTE *const op = (BYTE *)dst; + U32 const dictIDSizeCode = (dictID > 0) + (dictID >= 256) + (dictID >= 65536); /* 0-3 */ + U32 const checksumFlag = params.fParams.checksumFlag > 0; + U32 const windowSize = 1U << params.cParams.windowLog; + U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize); + BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3); + U32 const fcsCode = + params.fParams.contentSizeFlag ? (pledgedSrcSize >= 256) + (pledgedSrcSize >= 65536 + 256) + (pledgedSrcSize >= 0xFFFFFFFFU) : 0; /* 0-3 */ + BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag << 2) + (singleSegment << 5) + (fcsCode << 6)); + size_t pos; + + if (dstCapacity < ZSTD_frameHeaderSize_max) + return ERROR(dstSize_tooSmall); + + ZSTD_writeLE32(dst, ZSTD_MAGICNUMBER); + op[4] = frameHeaderDecriptionByte; + pos = 5; + if (!singleSegment) + op[pos++] = windowLogByte; + switch (dictIDSizeCode) { + default: /* impossible */ + case 0: break; + case 1: + op[pos] = (BYTE)(dictID); + pos++; + break; + case 2: + ZSTD_writeLE16(op + pos, (U16)dictID); + pos += 2; + break; + case 3: + ZSTD_writeLE32(op + pos, dictID); + pos += 4; + break; + } + switch (fcsCode) { + default: /* impossible */ + case 0: + if (singleSegment) + op[pos++] = (BYTE)(pledgedSrcSize); + break; + case 1: + ZSTD_writeLE16(op + pos, (U16)(pledgedSrcSize - 256)); + pos += 2; + break; + case 2: + ZSTD_writeLE32(op + pos, (U32)(pledgedSrcSize)); + pos += 4; + break; + case 3: + ZSTD_writeLE64(op + pos, (U64)(pledgedSrcSize)); + pos += 8; + break; + } + return pos; +} + +static size_t ZSTD_compressContinue_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 frame, U32 lastFrameChunk) +{ + const BYTE *const ip = (const BYTE *)src; + size_t fhSize = 0; + + if (cctx->stage == ZSTDcs_created) + return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */ + + if (frame && (cctx->stage == ZSTDcs_init)) { + fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID); + if (ZSTD_isError(fhSize)) + return fhSize; + dstCapacity -= fhSize; + dst = (char *)dst + fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + /* Check if blocks follow each other */ + if (src != cctx->nextSrc) { + /* not contiguous */ + ptrdiff_t const delta = cctx->nextSrc - ip; + cctx->lowLimit = cctx->dictLimit; + cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base); + cctx->dictBase = cctx->base; + cctx->base -= delta; + cctx->nextToUpdate = cctx->dictLimit; + if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) + cctx->lowLimit = cctx->dictLimit; /* too small extDict */ + } + + /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ + if ((ip + srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) { + ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase; + U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx; + cctx->lowLimit = lowLimitMax; + } + + cctx->nextSrc = ip + srcSize; + + if (srcSize) { + size_t const cSize = frame ? ZSTD_compress_generic(cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) + : ZSTD_compressBlock_internal(cctx, dst, dstCapacity, src, srcSize); + if (ZSTD_isError(cSize)) + return cSize; + return cSize + fhSize; + } else + return fhSize; +} + +size_t ZSTD_compressContinue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 0); +} + +size_t ZSTD_getBlockSizeMax(ZSTD_CCtx *cctx) { return MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog); } + +size_t ZSTD_compressBlock(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx); + if (srcSize > blockSizeMax) + return ERROR(srcSize_wrong); + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0); +} + +/*! ZSTD_loadDictionaryContent() : + * @return : 0, or an error code + */ +static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx *zc, const void *src, size_t srcSize) +{ + const BYTE *const ip = (const BYTE *)src; + const BYTE *const iend = ip + srcSize; + + /* input becomes curr prefix */ + zc->lowLimit = zc->dictLimit; + zc->dictLimit = (U32)(zc->nextSrc - zc->base); + zc->dictBase = zc->base; + zc->base += ip - zc->nextSrc; + zc->nextToUpdate = zc->dictLimit; + zc->loadedDictEnd = zc->forceWindow ? 0 : (U32)(iend - zc->base); + + zc->nextSrc = iend; + if (srcSize <= HASH_READ_SIZE) + return 0; + + switch (zc->params.cParams.strategy) { + case ZSTD_fast: ZSTD_fillHashTable(zc, iend, zc->params.cParams.searchLength); break; + + case ZSTD_dfast: ZSTD_fillDoubleHashTable(zc, iend, zc->params.cParams.searchLength); break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + if (srcSize >= HASH_READ_SIZE) + ZSTD_insertAndFindFirstIndex(zc, iend - HASH_READ_SIZE, zc->params.cParams.searchLength); + break; + + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btopt2: + if (srcSize >= HASH_READ_SIZE) + ZSTD_updateTree(zc, iend - HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength); + break; + + default: + return ERROR(GENERIC); /* strategy doesn't exist; impossible */ + } + + zc->nextToUpdate = (U32)(iend - zc->base); + return 0; +} + +/* Dictionaries that assign zero probability to symbols that show up causes problems + when FSE encoding. Refuse dictionaries that assign zero probability to symbols + that we may encounter during compression. + NOTE: This behavior is not standard and could be improved in the future. */ +static size_t ZSTD_checkDictNCount(short *normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) +{ + U32 s; + if (dictMaxSymbolValue < maxSymbolValue) + return ERROR(dictionary_corrupted); + for (s = 0; s <= maxSymbolValue; ++s) { + if (normalizedCounter[s] == 0) + return ERROR(dictionary_corrupted); + } + return 0; +} + +/* Dictionary format : + * See : + * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format + */ +/*! ZSTD_loadZstdDictionary() : + * @return : 0, or an error code + * assumptions : magic number supposed already checked + * dictSize supposed > 8 + */ +static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx *cctx, const void *dict, size_t dictSize) +{ + const BYTE *dictPtr = (const BYTE *)dict; + const BYTE *const dictEnd = dictPtr + dictSize; + short offcodeNCount[MaxOff + 1]; + unsigned offcodeMaxValue = MaxOff; + + dictPtr += 4; /* skip magic number */ + cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 : ZSTD_readLE32(dictPtr); + dictPtr += 4; + + { + size_t const hufHeaderSize = HUF_readCTable_wksp(cctx->hufTable, 255, dictPtr, dictEnd - dictPtr, cctx->tmpCounters, sizeof(cctx->tmpCounters)); + if (HUF_isError(hufHeaderSize)) + return ERROR(dictionary_corrupted); + dictPtr += hufHeaderSize; + } + + { + unsigned offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd - dictPtr); + if (FSE_isError(offcodeHeaderSize)) + return ERROR(dictionary_corrupted); + if (offcodeLog > OffFSELog) + return ERROR(dictionary_corrupted); + /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ + CHECK_E(FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), + dictionary_corrupted); + dictPtr += offcodeHeaderSize; + } + + { + short matchlengthNCount[MaxML + 1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd - dictPtr); + if (FSE_isError(matchlengthHeaderSize)) + return ERROR(dictionary_corrupted); + if (matchlengthLog > MLFSELog) + return ERROR(dictionary_corrupted); + /* Every match length code must have non-zero probability */ + CHECK_F(ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML)); + CHECK_E( + FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), + dictionary_corrupted); + dictPtr += matchlengthHeaderSize; + } + + { + short litlengthNCount[MaxLL + 1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd - dictPtr); + if (FSE_isError(litlengthHeaderSize)) + return ERROR(dictionary_corrupted); + if (litlengthLog > LLFSELog) + return ERROR(dictionary_corrupted); + /* Every literal length code must have non-zero probability */ + CHECK_F(ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL)); + CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), + dictionary_corrupted); + dictPtr += litlengthHeaderSize; + } + + if (dictPtr + 12 > dictEnd) + return ERROR(dictionary_corrupted); + cctx->rep[0] = ZSTD_readLE32(dictPtr + 0); + cctx->rep[1] = ZSTD_readLE32(dictPtr + 4); + cctx->rep[2] = ZSTD_readLE32(dictPtr + 8); + dictPtr += 12; + + { + size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + U32 offcodeMax = MaxOff; + if (dictContentSize <= ((U32)-1) - 128 KB) { + U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */ + offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */ + } + /* All offset values <= dictContentSize + 128 KB must be representable */ + CHECK_F(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff))); + /* All repCodes must be <= dictContentSize and != 0*/ + { + U32 u; + for (u = 0; u < 3; u++) { + if (cctx->rep[u] == 0) + return ERROR(dictionary_corrupted); + if (cctx->rep[u] > dictContentSize) + return ERROR(dictionary_corrupted); + } + } + + cctx->flagStaticTables = 1; + cctx->flagStaticHufTable = HUF_repeat_valid; + return ZSTD_loadDictionaryContent(cctx, dictPtr, dictContentSize); + } +} + +/** ZSTD_compress_insertDictionary() : +* @return : 0, or an error code */ +static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx *cctx, const void *dict, size_t dictSize) +{ + if ((dict == NULL) || (dictSize <= 8)) + return 0; + + /* dict as pure content */ + if ((ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict)) + return ZSTD_loadDictionaryContent(cctx, dict, dictSize); + + /* dict as zstd dictionary */ + return ZSTD_loadZstdDictionary(cctx, dict, dictSize); +} + +/*! ZSTD_compressBegin_internal() : +* @return : 0, or an error code */ +static size_t ZSTD_compressBegin_internal(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_parameters params, U64 pledgedSrcSize) +{ + ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue; + CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp)); + return ZSTD_compress_insertDictionary(cctx, dict, dictSize); +} + +/*! ZSTD_compressBegin_advanced() : +* @return : 0, or an error code */ +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) +{ + /* compression parameters verification and optimization */ + CHECK_F(ZSTD_checkCParams(params.cParams)); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize); +} + +size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, int compressionLevel) +{ + ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0); +} + +size_t ZSTD_compressBegin(ZSTD_CCtx *cctx, int compressionLevel) { return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel); } + +/*! ZSTD_writeEpilogue() : +* Ends a frame. +* @return : nb of bytes written into dst (or an error code) */ +static size_t ZSTD_writeEpilogue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity) +{ + BYTE *const ostart = (BYTE *)dst; + BYTE *op = ostart; + size_t fhSize = 0; + + if (cctx->stage == ZSTDcs_created) + return ERROR(stage_wrong); /* init missing */ + + /* special case : empty frame */ + if (cctx->stage == ZSTDcs_init) { + fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0); + if (ZSTD_isError(fhSize)) + return fhSize; + dstCapacity -= fhSize; + op += fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (cctx->stage != ZSTDcs_ending) { + /* write one last empty block, make it the "last" block */ + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw) << 1) + 0; + if (dstCapacity < 4) + return ERROR(dstSize_tooSmall); + ZSTD_writeLE32(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + } + + if (cctx->params.fParams.checksumFlag) { + U32 const checksum = (U32)xxh64_digest(&cctx->xxhState); + if (dstCapacity < 4) + return ERROR(dstSize_tooSmall); + ZSTD_writeLE32(op, checksum); + op += 4; + } + + cctx->stage = ZSTDcs_created; /* return to "created but no init" status */ + return op - ostart; +} + +size_t ZSTD_compressEnd(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + size_t endResult; + size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 1); + if (ZSTD_isError(cSize)) + return cSize; + endResult = ZSTD_writeEpilogue(cctx, (char *)dst + cSize, dstCapacity - cSize); + if (ZSTD_isError(endResult)) + return endResult; + return cSize + endResult; +} + +static size_t ZSTD_compress_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, + ZSTD_parameters params) +{ + CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize)); + return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_usingDict(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, + ZSTD_parameters params) +{ + return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params); +} + +size_t ZSTD_compressCCtx(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, ZSTD_parameters params) +{ + return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, NULL, 0, params); +} + +/* ===== Dictionary API ===== */ + +struct ZSTD_CDict_s { + void *dictBuffer; + const void *dictContent; + size_t dictContentSize; + ZSTD_CCtx *refContext; +}; /* typedef'd tp ZSTD_CDict within "zstd.h" */ + +size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams) { return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CDict)); } + +static ZSTD_CDict *ZSTD_createCDict_advanced(const void *dictBuffer, size_t dictSize, unsigned byReference, ZSTD_parameters params, ZSTD_customMem customMem) +{ + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + + { + ZSTD_CDict *const cdict = (ZSTD_CDict *)ZSTD_malloc(sizeof(ZSTD_CDict), customMem); + ZSTD_CCtx *const cctx = ZSTD_createCCtx_advanced(customMem); + + if (!cdict || !cctx) { + ZSTD_free(cdict, customMem); + ZSTD_freeCCtx(cctx); + return NULL; + } + + if ((byReference) || (!dictBuffer) || (!dictSize)) { + cdict->dictBuffer = NULL; + cdict->dictContent = dictBuffer; + } else { + void *const internalBuffer = ZSTD_malloc(dictSize, customMem); + if (!internalBuffer) { + ZSTD_free(cctx, customMem); + ZSTD_free(cdict, customMem); + return NULL; + } + memcpy(internalBuffer, dictBuffer, dictSize); + cdict->dictBuffer = internalBuffer; + cdict->dictContent = internalBuffer; + } + + { + size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0); + if (ZSTD_isError(errorCode)) { + ZSTD_free(cdict->dictBuffer, customMem); + ZSTD_free(cdict, customMem); + ZSTD_freeCCtx(cctx); + return NULL; + } + } + + cdict->refContext = cctx; + cdict->dictContentSize = dictSize; + return cdict; + } +} + +ZSTD_CDict *ZSTD_initCDict(const void *dict, size_t dictSize, ZSTD_parameters params, void *workspace, size_t workspaceSize) +{ + ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize); + return ZSTD_createCDict_advanced(dict, dictSize, 1, params, stackMem); +} + +size_t ZSTD_freeCDict(ZSTD_CDict *cdict) +{ + if (cdict == NULL) + return 0; /* support free on NULL */ + { + ZSTD_customMem const cMem = cdict->refContext->customMem; + ZSTD_freeCCtx(cdict->refContext); + ZSTD_free(cdict->dictBuffer, cMem); + ZSTD_free(cdict, cMem); + return 0; + } +} + +static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict *cdict) { return ZSTD_getParamsFromCCtx(cdict->refContext); } + +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, unsigned long long pledgedSrcSize) +{ + if (cdict->dictContentSize) + CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize)) + else { + ZSTD_parameters params = cdict->refContext->params; + params.fParams.contentSizeFlag = (pledgedSrcSize > 0); + CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, params, pledgedSrcSize)); + } + return 0; +} + +/*! ZSTD_compress_usingCDict() : +* Compression using a digested Dictionary. +* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. +* Note that compression level is decided during dictionary creation */ +size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_CDict *cdict) +{ + CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize)); + + if (cdict->refContext->params.fParams.contentSizeFlag == 1) { + cctx->params.fParams.contentSizeFlag = 1; + cctx->frameContentSize = srcSize; + } else { + cctx->params.fParams.contentSizeFlag = 0; + } + + return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); +} + +/* ****************************************************************** +* Streaming +********************************************************************/ + +typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage; + +struct ZSTD_CStream_s { + ZSTD_CCtx *cctx; + ZSTD_CDict *cdictLocal; + const ZSTD_CDict *cdict; + char *inBuff; + size_t inBuffSize; + size_t inToCompress; + size_t inBuffPos; + size_t inBuffTarget; + size_t blockSize; + char *outBuff; + size_t outBuffSize; + size_t outBuffContentSize; + size_t outBuffFlushedSize; + ZSTD_cStreamStage stage; + U32 checksum; + U32 frameEnded; + U64 pledgedSrcSize; + U64 inputProcessed; + ZSTD_parameters params; + ZSTD_customMem customMem; +}; /* typedef'd to ZSTD_CStream within "zstd.h" */ + +size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams) +{ + size_t const inBuffSize = (size_t)1 << cParams.windowLog; + size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, inBuffSize); + size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1; + + return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize); +} + +ZSTD_CStream *ZSTD_createCStream_advanced(ZSTD_customMem customMem) +{ + ZSTD_CStream *zcs; + + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + + zcs = (ZSTD_CStream *)ZSTD_malloc(sizeof(ZSTD_CStream), customMem); + if (zcs == NULL) + return NULL; + memset(zcs, 0, sizeof(ZSTD_CStream)); + memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem)); + zcs->cctx = ZSTD_createCCtx_advanced(customMem); + if (zcs->cctx == NULL) { + ZSTD_freeCStream(zcs); + return NULL; + } + return zcs; +} + +size_t ZSTD_freeCStream(ZSTD_CStream *zcs) +{ + if (zcs == NULL) + return 0; /* support free on NULL */ + { + ZSTD_customMem const cMem = zcs->customMem; + ZSTD_freeCCtx(zcs->cctx); + zcs->cctx = NULL; + ZSTD_freeCDict(zcs->cdictLocal); + zcs->cdictLocal = NULL; + ZSTD_free(zcs->inBuff, cMem); + zcs->inBuff = NULL; + ZSTD_free(zcs->outBuff, cMem); + zcs->outBuff = NULL; + ZSTD_free(zcs, cMem); + return 0; + } +} + +/*====== Initialization ======*/ + +size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; } +size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */; } + +static size_t ZSTD_resetCStream_internal(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize) +{ + if (zcs->inBuffSize == 0) + return ERROR(stage_wrong); /* zcs has not been init at least once => can't reset */ + + if (zcs->cdict) + CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize)) + else + CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize)); + + zcs->inToCompress = 0; + zcs->inBuffPos = 0; + zcs->inBuffTarget = zcs->blockSize; + zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; + zcs->stage = zcss_load; + zcs->frameEnded = 0; + zcs->pledgedSrcSize = pledgedSrcSize; + zcs->inputProcessed = 0; + return 0; /* ready to go */ +} + +size_t ZSTD_resetCStream(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize) +{ + + zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0); + + return ZSTD_resetCStream_internal(zcs, pledgedSrcSize); +} + +static size_t ZSTD_initCStream_advanced(ZSTD_CStream *zcs, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) +{ + /* allocate buffers */ + { + size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog; + if (zcs->inBuffSize < neededInBuffSize) { + zcs->inBuffSize = neededInBuffSize; + ZSTD_free(zcs->inBuff, zcs->customMem); + zcs->inBuff = (char *)ZSTD_malloc(neededInBuffSize, zcs->customMem); + if (zcs->inBuff == NULL) + return ERROR(memory_allocation); + } + zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize); + } + if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize) + 1) { + zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize) + 1; + ZSTD_free(zcs->outBuff, zcs->customMem); + zcs->outBuff = (char *)ZSTD_malloc(zcs->outBuffSize, zcs->customMem); + if (zcs->outBuff == NULL) + return ERROR(memory_allocation); + } + + if (dict && dictSize >= 8) { + ZSTD_freeCDict(zcs->cdictLocal); + zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0, params, zcs->customMem); + if (zcs->cdictLocal == NULL) + return ERROR(memory_allocation); + zcs->cdict = zcs->cdictLocal; + } else + zcs->cdict = NULL; + + zcs->checksum = params.fParams.checksumFlag > 0; + zcs->params = params; + + return ZSTD_resetCStream_internal(zcs, pledgedSrcSize); +} + +ZSTD_CStream *ZSTD_initCStream(ZSTD_parameters params, unsigned long long pledgedSrcSize, void *workspace, size_t workspaceSize) +{ + ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize); + ZSTD_CStream *const zcs = ZSTD_createCStream_advanced(stackMem); + if (zcs) { + size_t const code = ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize); + if (ZSTD_isError(code)) { + return NULL; + } + } + return zcs; +} + +ZSTD_CStream *ZSTD_initCStream_usingCDict(const ZSTD_CDict *cdict, unsigned long long pledgedSrcSize, void *workspace, size_t workspaceSize) +{ + ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict); + ZSTD_CStream *const zcs = ZSTD_initCStream(params, pledgedSrcSize, workspace, workspaceSize); + if (zcs) { + zcs->cdict = cdict; + if (ZSTD_isError(ZSTD_resetCStream_internal(zcs, pledgedSrcSize))) { + return NULL; + } + } + return zcs; +} + +/*====== Compression ======*/ + +typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e; + +ZSTD_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + size_t const length = MIN(dstCapacity, srcSize); + memcpy(dst, src, length); + return length; +} + +static size_t ZSTD_compressStream_generic(ZSTD_CStream *zcs, void *dst, size_t *dstCapacityPtr, const void *src, size_t *srcSizePtr, ZSTD_flush_e const flush) +{ + U32 someMoreWork = 1; + const char *const istart = (const char *)src; + const char *const iend = istart + *srcSizePtr; + const char *ip = istart; + char *const ostart = (char *)dst; + char *const oend = ostart + *dstCapacityPtr; + char *op = ostart; + + while (someMoreWork) { + switch (zcs->stage) { + case zcss_init: + return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */ + + case zcss_load: + /* complete inBuffer */ + { + size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; + size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend - ip); + zcs->inBuffPos += loaded; + ip += loaded; + if ((zcs->inBuffPos == zcs->inToCompress) || (!flush && (toLoad != loaded))) { + someMoreWork = 0; + break; /* not enough input to get a full block : stop there, wait for more */ + } + } + /* compress curr block (note : this stage cannot be stopped in the middle) */ + { + void *cDst; + size_t cSize; + size_t const iSize = zcs->inBuffPos - zcs->inToCompress; + size_t oSize = oend - op; + if (oSize >= ZSTD_compressBound(iSize)) + cDst = op; /* compress directly into output buffer (avoid flush stage) */ + else + cDst = zcs->outBuff, oSize = zcs->outBuffSize; + cSize = (flush == zsf_end) ? ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) + : ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize); + if (ZSTD_isError(cSize)) + return cSize; + if (flush == zsf_end) + zcs->frameEnded = 1; + /* prepare next block */ + zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize; + if (zcs->inBuffTarget > zcs->inBuffSize) + zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; /* note : inBuffSize >= blockSize */ + zcs->inToCompress = zcs->inBuffPos; + if (cDst == op) { + op += cSize; + break; + } /* no need to flush */ + zcs->outBuffContentSize = cSize; + zcs->outBuffFlushedSize = 0; + zcs->stage = zcss_flush; /* pass-through to flush stage */ + } + + case zcss_flush: { + size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; + size_t const flushed = ZSTD_limitCopy(op, oend - op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush); + op += flushed; + zcs->outBuffFlushedSize += flushed; + if (toFlush != flushed) { + someMoreWork = 0; + break; + } /* dst too small to store flushed data : stop there */ + zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; + zcs->stage = zcss_load; + break; + } + + case zcss_final: + someMoreWork = 0; /* do nothing */ + break; + + default: + return ERROR(GENERIC); /* impossible */ + } + } + + *srcSizePtr = ip - istart; + *dstCapacityPtr = op - ostart; + zcs->inputProcessed += *srcSizePtr; + if (zcs->frameEnded) + return 0; + { + size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos; + if (hintInSize == 0) + hintInSize = zcs->blockSize; + return hintInSize; + } +} + +size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, ZSTD_inBuffer *input) +{ + size_t sizeRead = input->size - input->pos; + size_t sizeWritten = output->size - output->pos; + size_t const result = + ZSTD_compressStream_generic(zcs, (char *)(output->dst) + output->pos, &sizeWritten, (const char *)(input->src) + input->pos, &sizeRead, zsf_gather); + input->pos += sizeRead; + output->pos += sizeWritten; + return result; +} + +/*====== Finalize ======*/ + +/*! ZSTD_flushStream() : +* @return : amount of data remaining to flush */ +size_t ZSTD_flushStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output) +{ + size_t srcSize = 0; + size_t sizeWritten = output->size - output->pos; + size_t const result = ZSTD_compressStream_generic(zcs, (char *)(output->dst) + output->pos, &sizeWritten, &srcSize, + &srcSize, /* use a valid src address instead of NULL */ + zsf_flush); + output->pos += sizeWritten; + if (ZSTD_isError(result)) + return result; + return zcs->outBuffContentSize - zcs->outBuffFlushedSize; /* remaining to flush */ +} + +size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output) +{ + BYTE *const ostart = (BYTE *)(output->dst) + output->pos; + BYTE *const oend = (BYTE *)(output->dst) + output->size; + BYTE *op = ostart; + + if ((zcs->pledgedSrcSize) && (zcs->inputProcessed != zcs->pledgedSrcSize)) + return ERROR(srcSize_wrong); /* pledgedSrcSize not respected */ + + if (zcs->stage != zcss_final) { + /* flush whatever remains */ + size_t srcSize = 0; + size_t sizeWritten = output->size - output->pos; + size_t const notEnded = + ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end); /* use a valid src address instead of NULL */ + size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; + op += sizeWritten; + if (remainingToFlush) { + output->pos += sizeWritten; + return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4); + } + /* create epilogue */ + zcs->stage = zcss_final; + zcs->outBuffContentSize = !notEnded ? 0 : ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, + 0); /* write epilogue, including final empty block, into outBuff */ + } + + /* flush epilogue */ + { + size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; + size_t const flushed = ZSTD_limitCopy(op, oend - op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush); + op += flushed; + zcs->outBuffFlushedSize += flushed; + output->pos += op - ostart; + if (toFlush == flushed) + zcs->stage = zcss_init; /* end reached */ + return toFlush - flushed; + } +} + +/*-===== Pre-defined compression levels =====-*/ + +#define ZSTD_DEFAULT_CLEVEL 1 +#define ZSTD_MAX_CLEVEL 22 +int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } + +static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL + 1] = { + { + /* "default" */ + /* W, C, H, S, L, TL, strat */ + {18, 12, 12, 1, 7, 16, ZSTD_fast}, /* level 0 - never used */ + {19, 13, 14, 1, 7, 16, ZSTD_fast}, /* level 1 */ + {19, 15, 16, 1, 6, 16, ZSTD_fast}, /* level 2 */ + {20, 16, 17, 1, 5, 16, ZSTD_dfast}, /* level 3.*/ + {20, 18, 18, 1, 5, 16, ZSTD_dfast}, /* level 4.*/ + {20, 15, 18, 3, 5, 16, ZSTD_greedy}, /* level 5 */ + {21, 16, 19, 2, 5, 16, ZSTD_lazy}, /* level 6 */ + {21, 17, 20, 3, 5, 16, ZSTD_lazy}, /* level 7 */ + {21, 18, 20, 3, 5, 16, ZSTD_lazy2}, /* level 8 */ + {21, 20, 20, 3, 5, 16, ZSTD_lazy2}, /* level 9 */ + {21, 19, 21, 4, 5, 16, ZSTD_lazy2}, /* level 10 */ + {22, 20, 22, 4, 5, 16, ZSTD_lazy2}, /* level 11 */ + {22, 20, 22, 5, 5, 16, ZSTD_lazy2}, /* level 12 */ + {22, 21, 22, 5, 5, 16, ZSTD_lazy2}, /* level 13 */ + {22, 21, 22, 6, 5, 16, ZSTD_lazy2}, /* level 14 */ + {22, 21, 21, 5, 5, 16, ZSTD_btlazy2}, /* level 15 */ + {23, 22, 22, 5, 5, 16, ZSTD_btlazy2}, /* level 16 */ + {23, 21, 22, 4, 5, 24, ZSTD_btopt}, /* level 17 */ + {23, 23, 22, 6, 5, 32, ZSTD_btopt}, /* level 18 */ + {23, 23, 22, 6, 3, 48, ZSTD_btopt}, /* level 19 */ + {25, 25, 23, 7, 3, 64, ZSTD_btopt2}, /* level 20 */ + {26, 26, 23, 7, 3, 256, ZSTD_btopt2}, /* level 21 */ + {27, 27, 25, 9, 3, 512, ZSTD_btopt2}, /* level 22 */ + }, + { + /* for srcSize <= 256 KB */ + /* W, C, H, S, L, T, strat */ + {0, 0, 0, 0, 0, 0, ZSTD_fast}, /* level 0 - not used */ + {18, 13, 14, 1, 6, 8, ZSTD_fast}, /* level 1 */ + {18, 14, 13, 1, 5, 8, ZSTD_dfast}, /* level 2 */ + {18, 16, 15, 1, 5, 8, ZSTD_dfast}, /* level 3 */ + {18, 15, 17, 1, 5, 8, ZSTD_greedy}, /* level 4.*/ + {18, 16, 17, 4, 5, 8, ZSTD_greedy}, /* level 5.*/ + {18, 16, 17, 3, 5, 8, ZSTD_lazy}, /* level 6.*/ + {18, 17, 17, 4, 4, 8, ZSTD_lazy}, /* level 7 */ + {18, 17, 17, 4, 4, 8, ZSTD_lazy2}, /* level 8 */ + {18, 17, 17, 5, 4, 8, ZSTD_lazy2}, /* level 9 */ + {18, 17, 17, 6, 4, 8, ZSTD_lazy2}, /* level 10 */ + {18, 18, 17, 6, 4, 8, ZSTD_lazy2}, /* level 11.*/ + {18, 18, 17, 7, 4, 8, ZSTD_lazy2}, /* level 12.*/ + {18, 19, 17, 6, 4, 8, ZSTD_btlazy2}, /* level 13 */ + {18, 18, 18, 4, 4, 16, ZSTD_btopt}, /* level 14.*/ + {18, 18, 18, 4, 3, 16, ZSTD_btopt}, /* level 15.*/ + {18, 19, 18, 6, 3, 32, ZSTD_btopt}, /* level 16.*/ + {18, 19, 18, 8, 3, 64, ZSTD_btopt}, /* level 17.*/ + {18, 19, 18, 9, 3, 128, ZSTD_btopt}, /* level 18.*/ + {18, 19, 18, 10, 3, 256, ZSTD_btopt}, /* level 19.*/ + {18, 19, 18, 11, 3, 512, ZSTD_btopt2}, /* level 20.*/ + {18, 19, 18, 12, 3, 512, ZSTD_btopt2}, /* level 21.*/ + {18, 19, 18, 13, 3, 512, ZSTD_btopt2}, /* level 22.*/ + }, + { + /* for srcSize <= 128 KB */ + /* W, C, H, S, L, T, strat */ + {17, 12, 12, 1, 7, 8, ZSTD_fast}, /* level 0 - not used */ + {17, 12, 13, 1, 6, 8, ZSTD_fast}, /* level 1 */ + {17, 13, 16, 1, 5, 8, ZSTD_fast}, /* level 2 */ + {17, 16, 16, 2, 5, 8, ZSTD_dfast}, /* level 3 */ + {17, 13, 15, 3, 4, 8, ZSTD_greedy}, /* level 4 */ + {17, 15, 17, 4, 4, 8, ZSTD_greedy}, /* level 5 */ + {17, 16, 17, 3, 4, 8, ZSTD_lazy}, /* level 6 */ + {17, 15, 17, 4, 4, 8, ZSTD_lazy2}, /* level 7 */ + {17, 17, 17, 4, 4, 8, ZSTD_lazy2}, /* level 8 */ + {17, 17, 17, 5, 4, 8, ZSTD_lazy2}, /* level 9 */ + {17, 17, 17, 6, 4, 8, ZSTD_lazy2}, /* level 10 */ + {17, 17, 17, 7, 4, 8, ZSTD_lazy2}, /* level 11 */ + {17, 17, 17, 8, 4, 8, ZSTD_lazy2}, /* level 12 */ + {17, 18, 17, 6, 4, 8, ZSTD_btlazy2}, /* level 13.*/ + {17, 17, 17, 7, 3, 8, ZSTD_btopt}, /* level 14.*/ + {17, 17, 17, 7, 3, 16, ZSTD_btopt}, /* level 15.*/ + {17, 18, 17, 7, 3, 32, ZSTD_btopt}, /* level 16.*/ + {17, 18, 17, 7, 3, 64, ZSTD_btopt}, /* level 17.*/ + {17, 18, 17, 7, 3, 256, ZSTD_btopt}, /* level 18.*/ + {17, 18, 17, 8, 3, 256, ZSTD_btopt}, /* level 19.*/ + {17, 18, 17, 9, 3, 256, ZSTD_btopt2}, /* level 20.*/ + {17, 18, 17, 10, 3, 256, ZSTD_btopt2}, /* level 21.*/ + {17, 18, 17, 11, 3, 512, ZSTD_btopt2}, /* level 22.*/ + }, + { + /* for srcSize <= 16 KB */ + /* W, C, H, S, L, T, strat */ + {14, 12, 12, 1, 7, 6, ZSTD_fast}, /* level 0 - not used */ + {14, 14, 14, 1, 6, 6, ZSTD_fast}, /* level 1 */ + {14, 14, 14, 1, 4, 6, ZSTD_fast}, /* level 2 */ + {14, 14, 14, 1, 4, 6, ZSTD_dfast}, /* level 3.*/ + {14, 14, 14, 4, 4, 6, ZSTD_greedy}, /* level 4.*/ + {14, 14, 14, 3, 4, 6, ZSTD_lazy}, /* level 5.*/ + {14, 14, 14, 4, 4, 6, ZSTD_lazy2}, /* level 6 */ + {14, 14, 14, 5, 4, 6, ZSTD_lazy2}, /* level 7 */ + {14, 14, 14, 6, 4, 6, ZSTD_lazy2}, /* level 8.*/ + {14, 15, 14, 6, 4, 6, ZSTD_btlazy2}, /* level 9.*/ + {14, 15, 14, 3, 3, 6, ZSTD_btopt}, /* level 10.*/ + {14, 15, 14, 6, 3, 8, ZSTD_btopt}, /* level 11.*/ + {14, 15, 14, 6, 3, 16, ZSTD_btopt}, /* level 12.*/ + {14, 15, 14, 6, 3, 24, ZSTD_btopt}, /* level 13.*/ + {14, 15, 15, 6, 3, 48, ZSTD_btopt}, /* level 14.*/ + {14, 15, 15, 6, 3, 64, ZSTD_btopt}, /* level 15.*/ + {14, 15, 15, 6, 3, 96, ZSTD_btopt}, /* level 16.*/ + {14, 15, 15, 6, 3, 128, ZSTD_btopt}, /* level 17.*/ + {14, 15, 15, 6, 3, 256, ZSTD_btopt}, /* level 18.*/ + {14, 15, 15, 7, 3, 256, ZSTD_btopt}, /* level 19.*/ + {14, 15, 15, 8, 3, 256, ZSTD_btopt2}, /* level 20.*/ + {14, 15, 15, 9, 3, 256, ZSTD_btopt2}, /* level 21.*/ + {14, 15, 15, 10, 3, 256, ZSTD_btopt2}, /* level 22.*/ + }, +}; + +/*! ZSTD_getCParams() : +* @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`. +* Size values are optional, provide 0 if not known or unused */ +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) +{ + ZSTD_compressionParameters cp; + size_t const addedSize = srcSize ? 0 : 500; + U64 const rSize = srcSize + dictSize ? srcSize + dictSize + addedSize : (U64)-1; + U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ + if (compressionLevel <= 0) + compressionLevel = ZSTD_DEFAULT_CLEVEL; /* 0 == default; no negative compressionLevel yet */ + if (compressionLevel > ZSTD_MAX_CLEVEL) + compressionLevel = ZSTD_MAX_CLEVEL; + cp = ZSTD_defaultCParameters[tableID][compressionLevel]; + if (ZSTD_32bits()) { /* auto-correction, for 32-bits mode */ + if (cp.windowLog > ZSTD_WINDOWLOG_MAX) + cp.windowLog = ZSTD_WINDOWLOG_MAX; + if (cp.chainLog > ZSTD_CHAINLOG_MAX) + cp.chainLog = ZSTD_CHAINLOG_MAX; + if (cp.hashLog > ZSTD_HASHLOG_MAX) + cp.hashLog = ZSTD_HASHLOG_MAX; + } + cp = ZSTD_adjustCParams(cp, srcSize, dictSize); + return cp; +} + +/*! ZSTD_getParams() : +* same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`). +* All fields of `ZSTD_frameParameters` are set to default (0) */ +ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) +{ + ZSTD_parameters params; + ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize); + memset(¶ms, 0, sizeof(params)); + params.cParams = cParams; + return params; +} + +EXPORT_SYMBOL(ZSTD_maxCLevel); +EXPORT_SYMBOL(ZSTD_compressBound); + +EXPORT_SYMBOL(ZSTD_CCtxWorkspaceBound); +EXPORT_SYMBOL(ZSTD_initCCtx); +EXPORT_SYMBOL(ZSTD_compressCCtx); +EXPORT_SYMBOL(ZSTD_compress_usingDict); + +EXPORT_SYMBOL(ZSTD_CDictWorkspaceBound); +EXPORT_SYMBOL(ZSTD_initCDict); +EXPORT_SYMBOL(ZSTD_compress_usingCDict); + +EXPORT_SYMBOL(ZSTD_CStreamWorkspaceBound); +EXPORT_SYMBOL(ZSTD_initCStream); +EXPORT_SYMBOL(ZSTD_initCStream_usingCDict); +EXPORT_SYMBOL(ZSTD_resetCStream); +EXPORT_SYMBOL(ZSTD_compressStream); +EXPORT_SYMBOL(ZSTD_flushStream); +EXPORT_SYMBOL(ZSTD_endStream); +EXPORT_SYMBOL(ZSTD_CStreamInSize); +EXPORT_SYMBOL(ZSTD_CStreamOutSize); + +EXPORT_SYMBOL(ZSTD_getCParams); +EXPORT_SYMBOL(ZSTD_getParams); +EXPORT_SYMBOL(ZSTD_checkCParams); +EXPORT_SYMBOL(ZSTD_adjustCParams); + +EXPORT_SYMBOL(ZSTD_compressBegin); +EXPORT_SYMBOL(ZSTD_compressBegin_usingDict); +EXPORT_SYMBOL(ZSTD_compressBegin_advanced); +EXPORT_SYMBOL(ZSTD_copyCCtx); +EXPORT_SYMBOL(ZSTD_compressBegin_usingCDict); +EXPORT_SYMBOL(ZSTD_compressContinue); +EXPORT_SYMBOL(ZSTD_compressEnd); + +EXPORT_SYMBOL(ZSTD_getBlockSizeMax); +EXPORT_SYMBOL(ZSTD_compressBlock); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Zstd Compressor"); diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c new file mode 100644 index 0000000000000000000000000000000000000000..b17846725ca00fe0eaeb3f7c53f616dfa890f964 --- /dev/null +++ b/lib/zstd/decompress.c @@ -0,0 +1,2528 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! +* MAXWINDOWSIZE_DEFAULT : +* maximum window size accepted by DStream, by default. +* Frames requiring more memory will be rejected. +*/ +#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT +#define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */ +#endif + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "fse.h" +#include "huf.h" +#include "mem.h" /* low level memory routines */ +#include "zstd_internal.h" +#include +#include +#include /* memcpy, memmove, memset */ + +#define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0) + +/*-************************************* +* Macros +***************************************/ +#define ZSTD_isError ERR_isError /* for inlining */ +#define FSE_isError ERR_isError +#define HUF_isError ERR_isError + +/*_******************************************************* +* Memory operations +**********************************************************/ +static void ZSTD_copy4(void *dst, const void *src) { memcpy(dst, src, 4); } + +/*-************************************************************* +* Context management +***************************************************************/ +typedef enum { + ZSTDds_getFrameHeaderSize, + ZSTDds_decodeFrameHeader, + ZSTDds_decodeBlockHeader, + ZSTDds_decompressBlock, + ZSTDds_decompressLastBlock, + ZSTDds_checkChecksum, + ZSTDds_decodeSkippableHeader, + ZSTDds_skipFrame +} ZSTD_dStage; + +typedef struct { + FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; + FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; + FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; + HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ + U64 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32 / 2]; + U32 rep[ZSTD_REP_NUM]; +} ZSTD_entropyTables_t; + +struct ZSTD_DCtx_s { + const FSE_DTable *LLTptr; + const FSE_DTable *MLTptr; + const FSE_DTable *OFTptr; + const HUF_DTable *HUFptr; + ZSTD_entropyTables_t entropy; + const void *previousDstEnd; /* detect continuity */ + const void *base; /* start of curr segment */ + const void *vBase; /* virtual start of previous segment if it was just before curr one */ + const void *dictEnd; /* end of previous segment */ + size_t expected; + ZSTD_frameParams fParams; + blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */ + ZSTD_dStage stage; + U32 litEntropy; + U32 fseEntropy; + struct xxh64_state xxhState; + size_t headerSize; + U32 dictID; + const BYTE *litPtr; + ZSTD_customMem customMem; + size_t litSize; + size_t rleSize; + BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH]; + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; +}; /* typedef'd to ZSTD_DCtx within "zstd.h" */ + +size_t ZSTD_DCtxWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DCtx)); } + +size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx) +{ + dctx->expected = ZSTD_frameHeaderSize_prefix; + dctx->stage = ZSTDds_getFrameHeaderSize; + dctx->previousDstEnd = NULL; + dctx->base = NULL; + dctx->vBase = NULL; + dctx->dictEnd = NULL; + dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ + dctx->litEntropy = dctx->fseEntropy = 0; + dctx->dictID = 0; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); + memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ + dctx->LLTptr = dctx->entropy.LLTable; + dctx->MLTptr = dctx->entropy.MLTable; + dctx->OFTptr = dctx->entropy.OFTable; + dctx->HUFptr = dctx->entropy.hufTable; + return 0; +} + +ZSTD_DCtx *ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + ZSTD_DCtx *dctx; + + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + + dctx = (ZSTD_DCtx *)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem); + if (!dctx) + return NULL; + memcpy(&dctx->customMem, &customMem, sizeof(customMem)); + ZSTD_decompressBegin(dctx); + return dctx; +} + +ZSTD_DCtx *ZSTD_initDCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize); + return ZSTD_createDCtx_advanced(stackMem); +} + +size_t ZSTD_freeDCtx(ZSTD_DCtx *dctx) +{ + if (dctx == NULL) + return 0; /* support free on NULL */ + ZSTD_free(dctx, dctx->customMem); + return 0; /* reserved as a potential error code in the future */ +} + +void ZSTD_copyDCtx(ZSTD_DCtx *dstDCtx, const ZSTD_DCtx *srcDCtx) +{ + size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max; + memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */ +} + +static void ZSTD_refDDict(ZSTD_DCtx *dstDCtx, const ZSTD_DDict *ddict); + +/*-************************************************************* +* Decompression section +***************************************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void *buffer, size_t size) +{ + if (size < 4) + return 0; + { + U32 const magic = ZSTD_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) + return 1; + if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) + return 1; + } + return 0; +} + +/** ZSTD_frameHeaderSize() : +* srcSize must be >= ZSTD_frameHeaderSize_prefix. +* @return : size of the Frame Header */ +static size_t ZSTD_frameHeaderSize(const void *src, size_t srcSize) +{ + if (srcSize < ZSTD_frameHeaderSize_prefix) + return ERROR(srcSize_wrong); + { + BYTE const fhd = ((const BYTE *)src)[4]; + U32 const dictID = fhd & 3; + U32 const singleSegment = (fhd >> 5) & 1; + U32 const fcsId = fhd >> 6; + return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + (singleSegment && !fcsId); + } +} + +/** ZSTD_getFrameParams() : +* decode Frame Header, or require larger `srcSize`. +* @return : 0, `fparamsPtr` is correctly filled, +* >0, `srcSize` is too small, result is expected `srcSize`, +* or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameParams(ZSTD_frameParams *fparamsPtr, const void *src, size_t srcSize) +{ + const BYTE *ip = (const BYTE *)src; + + if (srcSize < ZSTD_frameHeaderSize_prefix) + return ZSTD_frameHeaderSize_prefix; + if (ZSTD_readLE32(src) != ZSTD_MAGICNUMBER) { + if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + if (srcSize < ZSTD_skippableHeaderSize) + return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */ + memset(fparamsPtr, 0, sizeof(*fparamsPtr)); + fparamsPtr->frameContentSize = ZSTD_readLE32((const char *)src + 4); + fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */ + return 0; + } + return ERROR(prefix_unknown); + } + + /* ensure there is enough `srcSize` to fully read/decode frame header */ + { + size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize); + if (srcSize < fhsize) + return fhsize; + } + + { + BYTE const fhdByte = ip[4]; + size_t pos = 5; + U32 const dictIDSizeCode = fhdByte & 3; + U32 const checksumFlag = (fhdByte >> 2) & 1; + U32 const singleSegment = (fhdByte >> 5) & 1; + U32 const fcsID = fhdByte >> 6; + U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; + U32 windowSize = 0; + U32 dictID = 0; + U64 frameContentSize = 0; + if ((fhdByte & 0x08) != 0) + return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */ + if (!singleSegment) { + BYTE const wlByte = ip[pos++]; + U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; + if (windowLog > ZSTD_WINDOWLOG_MAX) + return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */ + windowSize = (1U << windowLog); + windowSize += (windowSize >> 3) * (wlByte & 7); + } + + switch (dictIDSizeCode) { + default: /* impossible */ + case 0: break; + case 1: + dictID = ip[pos]; + pos++; + break; + case 2: + dictID = ZSTD_readLE16(ip + pos); + pos += 2; + break; + case 3: + dictID = ZSTD_readLE32(ip + pos); + pos += 4; + break; + } + switch (fcsID) { + default: /* impossible */ + case 0: + if (singleSegment) + frameContentSize = ip[pos]; + break; + case 1: frameContentSize = ZSTD_readLE16(ip + pos) + 256; break; + case 2: frameContentSize = ZSTD_readLE32(ip + pos); break; + case 3: frameContentSize = ZSTD_readLE64(ip + pos); break; + } + if (!windowSize) + windowSize = (U32)frameContentSize; + if (windowSize > windowSizeMax) + return ERROR(frameParameter_windowTooLarge); + fparamsPtr->frameContentSize = frameContentSize; + fparamsPtr->windowSize = windowSize; + fparamsPtr->dictID = dictID; + fparamsPtr->checksumFlag = checksumFlag; + } + return 0; +} + +/** ZSTD_getFrameContentSize() : +* compatible with legacy mode +* @return : decompressed size of the single frame pointed to be `src` if known, otherwise +* - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined +* - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */ +unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize) +{ + { + ZSTD_frameParams fParams; + if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0) + return ZSTD_CONTENTSIZE_ERROR; + if (fParams.windowSize == 0) { + /* Either skippable or empty frame, size == 0 either way */ + return 0; + } else if (fParams.frameContentSize != 0) { + return fParams.frameContentSize; + } else { + return ZSTD_CONTENTSIZE_UNKNOWN; + } + } +} + +/** ZSTD_findDecompressedSize() : + * compatible with legacy mode + * `srcSize` must be the exact length of some number of ZSTD compressed and/or + * skippable frames + * @return : decompressed size of the frames contained */ +unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize) +{ + { + unsigned long long totalDstSize = 0; + while (srcSize >= ZSTD_frameHeaderSize_prefix) { + const U32 magicNumber = ZSTD_readLE32(src); + + if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + size_t skippableSize; + if (srcSize < ZSTD_skippableHeaderSize) + return ERROR(srcSize_wrong); + skippableSize = ZSTD_readLE32((const BYTE *)src + 4) + ZSTD_skippableHeaderSize; + if (srcSize < skippableSize) { + return ZSTD_CONTENTSIZE_ERROR; + } + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; + } + + { + unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); + if (ret >= ZSTD_CONTENTSIZE_ERROR) + return ret; + + /* check for overflow */ + if (totalDstSize + ret < totalDstSize) + return ZSTD_CONTENTSIZE_ERROR; + totalDstSize += ret; + } + { + size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); + if (ZSTD_isError(frameSrcSize)) { + return ZSTD_CONTENTSIZE_ERROR; + } + + src = (const BYTE *)src + frameSrcSize; + srcSize -= frameSrcSize; + } + } + + if (srcSize) { + return ZSTD_CONTENTSIZE_ERROR; + } + + return totalDstSize; + } +} + +/** ZSTD_decodeFrameHeader() : +* `headerSize` must be the size provided by ZSTD_frameHeaderSize(). +* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ +static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx *dctx, const void *src, size_t headerSize) +{ + size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize); + if (ZSTD_isError(result)) + return result; /* invalid header */ + if (result > 0) + return ERROR(srcSize_wrong); /* headerSize too small */ + if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) + return ERROR(dictionary_wrong); + if (dctx->fParams.checksumFlag) + xxh64_reset(&dctx->xxhState, 0); + return 0; +} + +typedef struct { + blockType_e blockType; + U32 lastBlock; + U32 origSize; +} blockProperties_t; + +/*! ZSTD_getcBlockSize() : +* Provides the size of compressed block from block header `src` */ +size_t ZSTD_getcBlockSize(const void *src, size_t srcSize, blockProperties_t *bpPtr) +{ + if (srcSize < ZSTD_blockHeaderSize) + return ERROR(srcSize_wrong); + { + U32 const cBlockHeader = ZSTD_readLE24(src); + U32 const cSize = cBlockHeader >> 3; + bpPtr->lastBlock = cBlockHeader & 1; + bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3); + bpPtr->origSize = cSize; /* only useful for RLE */ + if (bpPtr->blockType == bt_rle) + return 1; + if (bpPtr->blockType == bt_reserved) + return ERROR(corruption_detected); + return cSize; + } +} + +static size_t ZSTD_copyRawBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + if (srcSize > dstCapacity) + return ERROR(dstSize_tooSmall); + memcpy(dst, src, srcSize); + return srcSize; +} + +static size_t ZSTD_setRleBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize, size_t regenSize) +{ + if (srcSize != 1) + return ERROR(srcSize_wrong); + if (regenSize > dstCapacity) + return ERROR(dstSize_tooSmall); + memset(dst, *(const BYTE *)src, regenSize); + return regenSize; +} + +/*! ZSTD_decodeLiteralsBlock() : + @return : nb of bytes read from src (< srcSize ) */ +size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t srcSize) /* note : srcSize < BLOCKSIZE */ +{ + if (srcSize < MIN_CBLOCK_SIZE) + return ERROR(corruption_detected); + + { + const BYTE *const istart = (const BYTE *)src; + symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3); + + switch (litEncType) { + case set_repeat: + if (dctx->litEntropy == 0) + return ERROR(dictionary_corrupted); + /* fall-through */ + case set_compressed: + if (srcSize < 5) + return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */ + { + size_t lhSize, litSize, litCSize; + U32 singleStream = 0; + U32 const lhlCode = (istart[0] >> 2) & 3; + U32 const lhc = ZSTD_readLE32(istart); + switch (lhlCode) { + case 0: + case 1: + default: /* note : default is impossible, since lhlCode into [0..3] */ + /* 2 - 2 - 10 - 10 */ + singleStream = !lhlCode; + lhSize = 3; + litSize = (lhc >> 4) & 0x3FF; + litCSize = (lhc >> 14) & 0x3FF; + break; + case 2: + /* 2 - 2 - 14 - 14 */ + lhSize = 4; + litSize = (lhc >> 4) & 0x3FFF; + litCSize = lhc >> 18; + break; + case 3: + /* 2 - 2 - 18 - 18 */ + lhSize = 5; + litSize = (lhc >> 4) & 0x3FFFF; + litCSize = (lhc >> 22) + (istart[4] << 10); + break; + } + if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) + return ERROR(corruption_detected); + if (litCSize + lhSize > srcSize) + return ERROR(corruption_detected); + + if (HUF_isError( + (litEncType == set_repeat) + ? (singleStream ? HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr) + : HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr)) + : (singleStream + ? HUF_decompress1X2_DCtx_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize, + dctx->entropy.workspace, sizeof(dctx->entropy.workspace)) + : HUF_decompress4X_hufOnly_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize, + dctx->entropy.workspace, sizeof(dctx->entropy.workspace))))) + return ERROR(corruption_detected); + + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + dctx->litEntropy = 1; + if (litEncType == set_compressed) + dctx->HUFptr = dctx->entropy.hufTable; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); + return litCSize + lhSize; + } + + case set_basic: { + size_t litSize, lhSize; + U32 const lhlCode = ((istart[0]) >> 2) & 3; + switch (lhlCode) { + case 0: + case 2: + default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = ZSTD_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + litSize = ZSTD_readLE24(istart) >> 4; + break; + } + + if (lhSize + litSize + WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ + if (litSize + lhSize > srcSize) + return ERROR(corruption_detected); + memcpy(dctx->litBuffer, istart + lhSize, litSize); + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); + return lhSize + litSize; + } + /* direct reference into compressed stream */ + dctx->litPtr = istart + lhSize; + dctx->litSize = litSize; + return lhSize + litSize; + } + + case set_rle: { + U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t litSize, lhSize; + switch (lhlCode) { + case 0: + case 2: + default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = ZSTD_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + litSize = ZSTD_readLE24(istart) >> 4; + if (srcSize < 4) + return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */ + break; + } + if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) + return ERROR(corruption_detected); + memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize + 1; + } + default: + return ERROR(corruption_detected); /* impossible */ + } + } +} + +typedef union { + FSE_decode_t realData; + U32 alignedBy4; +} FSE_decode_t4; + +static const FSE_decode_t4 LL_defaultDTable[(1 << LL_DEFAULTNORMLOG) + 1] = { + {{LL_DEFAULTNORMLOG, 1, 1}}, /* header : tableLog, fastMode, fastMode */ + {{0, 0, 4}}, /* 0 : base, symbol, bits */ + {{16, 0, 4}}, + {{32, 1, 5}}, + {{0, 3, 5}}, + {{0, 4, 5}}, + {{0, 6, 5}}, + {{0, 7, 5}}, + {{0, 9, 5}}, + {{0, 10, 5}}, + {{0, 12, 5}}, + {{0, 14, 6}}, + {{0, 16, 5}}, + {{0, 18, 5}}, + {{0, 19, 5}}, + {{0, 21, 5}}, + {{0, 22, 5}}, + {{0, 24, 5}}, + {{32, 25, 5}}, + {{0, 26, 5}}, + {{0, 27, 6}}, + {{0, 29, 6}}, + {{0, 31, 6}}, + {{32, 0, 4}}, + {{0, 1, 4}}, + {{0, 2, 5}}, + {{32, 4, 5}}, + {{0, 5, 5}}, + {{32, 7, 5}}, + {{0, 8, 5}}, + {{32, 10, 5}}, + {{0, 11, 5}}, + {{0, 13, 6}}, + {{32, 16, 5}}, + {{0, 17, 5}}, + {{32, 19, 5}}, + {{0, 20, 5}}, + {{32, 22, 5}}, + {{0, 23, 5}}, + {{0, 25, 4}}, + {{16, 25, 4}}, + {{32, 26, 5}}, + {{0, 28, 6}}, + {{0, 30, 6}}, + {{48, 0, 4}}, + {{16, 1, 4}}, + {{32, 2, 5}}, + {{32, 3, 5}}, + {{32, 5, 5}}, + {{32, 6, 5}}, + {{32, 8, 5}}, + {{32, 9, 5}}, + {{32, 11, 5}}, + {{32, 12, 5}}, + {{0, 15, 6}}, + {{32, 17, 5}}, + {{32, 18, 5}}, + {{32, 20, 5}}, + {{32, 21, 5}}, + {{32, 23, 5}}, + {{32, 24, 5}}, + {{0, 35, 6}}, + {{0, 34, 6}}, + {{0, 33, 6}}, + {{0, 32, 6}}, +}; /* LL_defaultDTable */ + +static const FSE_decode_t4 ML_defaultDTable[(1 << ML_DEFAULTNORMLOG) + 1] = { + {{ML_DEFAULTNORMLOG, 1, 1}}, /* header : tableLog, fastMode, fastMode */ + {{0, 0, 6}}, /* 0 : base, symbol, bits */ + {{0, 1, 4}}, + {{32, 2, 5}}, + {{0, 3, 5}}, + {{0, 5, 5}}, + {{0, 6, 5}}, + {{0, 8, 5}}, + {{0, 10, 6}}, + {{0, 13, 6}}, + {{0, 16, 6}}, + {{0, 19, 6}}, + {{0, 22, 6}}, + {{0, 25, 6}}, + {{0, 28, 6}}, + {{0, 31, 6}}, + {{0, 33, 6}}, + {{0, 35, 6}}, + {{0, 37, 6}}, + {{0, 39, 6}}, + {{0, 41, 6}}, + {{0, 43, 6}}, + {{0, 45, 6}}, + {{16, 1, 4}}, + {{0, 2, 4}}, + {{32, 3, 5}}, + {{0, 4, 5}}, + {{32, 6, 5}}, + {{0, 7, 5}}, + {{0, 9, 6}}, + {{0, 12, 6}}, + {{0, 15, 6}}, + {{0, 18, 6}}, + {{0, 21, 6}}, + {{0, 24, 6}}, + {{0, 27, 6}}, + {{0, 30, 6}}, + {{0, 32, 6}}, + {{0, 34, 6}}, + {{0, 36, 6}}, + {{0, 38, 6}}, + {{0, 40, 6}}, + {{0, 42, 6}}, + {{0, 44, 6}}, + {{32, 1, 4}}, + {{48, 1, 4}}, + {{16, 2, 4}}, + {{32, 4, 5}}, + {{32, 5, 5}}, + {{32, 7, 5}}, + {{32, 8, 5}}, + {{0, 11, 6}}, + {{0, 14, 6}}, + {{0, 17, 6}}, + {{0, 20, 6}}, + {{0, 23, 6}}, + {{0, 26, 6}}, + {{0, 29, 6}}, + {{0, 52, 6}}, + {{0, 51, 6}}, + {{0, 50, 6}}, + {{0, 49, 6}}, + {{0, 48, 6}}, + {{0, 47, 6}}, + {{0, 46, 6}}, +}; /* ML_defaultDTable */ + +static const FSE_decode_t4 OF_defaultDTable[(1 << OF_DEFAULTNORMLOG) + 1] = { + {{OF_DEFAULTNORMLOG, 1, 1}}, /* header : tableLog, fastMode, fastMode */ + {{0, 0, 5}}, /* 0 : base, symbol, bits */ + {{0, 6, 4}}, + {{0, 9, 5}}, + {{0, 15, 5}}, + {{0, 21, 5}}, + {{0, 3, 5}}, + {{0, 7, 4}}, + {{0, 12, 5}}, + {{0, 18, 5}}, + {{0, 23, 5}}, + {{0, 5, 5}}, + {{0, 8, 4}}, + {{0, 14, 5}}, + {{0, 20, 5}}, + {{0, 2, 5}}, + {{16, 7, 4}}, + {{0, 11, 5}}, + {{0, 17, 5}}, + {{0, 22, 5}}, + {{0, 4, 5}}, + {{16, 8, 4}}, + {{0, 13, 5}}, + {{0, 19, 5}}, + {{0, 1, 5}}, + {{16, 6, 4}}, + {{0, 10, 5}}, + {{0, 16, 5}}, + {{0, 28, 5}}, + {{0, 27, 5}}, + {{0, 26, 5}}, + {{0, 25, 5}}, + {{0, 24, 5}}, +}; /* OF_defaultDTable */ + +/*! ZSTD_buildSeqTable() : + @return : nb bytes read from src, + or an error code if it fails, testable with ZSTD_isError() +*/ +static size_t ZSTD_buildSeqTable(FSE_DTable *DTableSpace, const FSE_DTable **DTablePtr, symbolEncodingType_e type, U32 max, U32 maxLog, const void *src, + size_t srcSize, const FSE_decode_t4 *defaultTable, U32 flagRepeatTable, void *workspace, size_t workspaceSize) +{ + const void *const tmpPtr = defaultTable; /* bypass strict aliasing */ + switch (type) { + case set_rle: + if (!srcSize) + return ERROR(srcSize_wrong); + if ((*(const BYTE *)src) > max) + return ERROR(corruption_detected); + FSE_buildDTable_rle(DTableSpace, *(const BYTE *)src); + *DTablePtr = DTableSpace; + return 1; + case set_basic: *DTablePtr = (const FSE_DTable *)tmpPtr; return 0; + case set_repeat: + if (!flagRepeatTable) + return ERROR(corruption_detected); + return 0; + default: /* impossible */ + case set_compressed: { + U32 tableLog; + S16 *norm = (S16 *)workspace; + size_t const spaceUsed32 = ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(GENERIC); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + { + size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); + if (FSE_isError(headerSize)) + return ERROR(corruption_detected); + if (tableLog > maxLog) + return ERROR(corruption_detected); + FSE_buildDTable_wksp(DTableSpace, norm, max, tableLog, workspace, workspaceSize); + *DTablePtr = DTableSpace; + return headerSize; + } + } + } +} + +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx *dctx, int *nbSeqPtr, const void *src, size_t srcSize) +{ + const BYTE *const istart = (const BYTE *const)src; + const BYTE *const iend = istart + srcSize; + const BYTE *ip = istart; + + /* check */ + if (srcSize < MIN_SEQUENCES_SIZE) + return ERROR(srcSize_wrong); + + /* SeqHead */ + { + int nbSeq = *ip++; + if (!nbSeq) { + *nbSeqPtr = 0; + return 1; + } + if (nbSeq > 0x7F) { + if (nbSeq == 0xFF) { + if (ip + 2 > iend) + return ERROR(srcSize_wrong); + nbSeq = ZSTD_readLE16(ip) + LONGNBSEQ, ip += 2; + } else { + if (ip >= iend) + return ERROR(srcSize_wrong); + nbSeq = ((nbSeq - 0x80) << 8) + *ip++; + } + } + *nbSeqPtr = nbSeq; + } + + /* FSE table descriptors */ + if (ip + 4 > iend) + return ERROR(srcSize_wrong); /* minimum possible size */ + { + symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6); + symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3); + symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3); + ip++; + + /* Build DTables */ + { + size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, LLtype, MaxLL, LLFSELog, ip, iend - ip, + LL_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); + if (ZSTD_isError(llhSize)) + return ERROR(corruption_detected); + ip += llhSize; + } + { + size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, OFtype, MaxOff, OffFSELog, ip, iend - ip, + OF_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); + if (ZSTD_isError(ofhSize)) + return ERROR(corruption_detected); + ip += ofhSize; + } + { + size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, MLtype, MaxML, MLFSELog, ip, iend - ip, + ML_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); + if (ZSTD_isError(mlhSize)) + return ERROR(corruption_detected); + ip += mlhSize; + } + } + + return ip - istart; +} + +typedef struct { + size_t litLength; + size_t matchLength; + size_t offset; + const BYTE *match; +} seq_t; + +typedef struct { + BIT_DStream_t DStream; + FSE_DState_t stateLL; + FSE_DState_t stateOffb; + FSE_DState_t stateML; + size_t prevOffset[ZSTD_REP_NUM]; + const BYTE *base; + size_t pos; + uPtrDiff gotoDict; +} seqState_t; + +FORCE_NOINLINE +size_t ZSTD_execSequenceLast7(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base, + const BYTE *const vBase, const BYTE *const dictEnd) +{ + BYTE *const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE *const iLitEnd = *litPtr + sequence.litLength; + const BYTE *match = oLitEnd - sequence.offset; + + /* check */ + if (oMatchEnd > oend) + return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) + return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd <= oend_w) + return ERROR(GENERIC); /* Precondition */ + + /* copy literals */ + if (op < oend_w) { + ZSTD_wildcopy(op, *litPtr, oend_w - op); + *litPtr += oend_w - op; + op = oend_w; + } + while (op < oLitEnd) + *op++ = *(*litPtr)++; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - base)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - vBase)) + return ERROR(corruption_detected); + match = dictEnd - (base - match); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currPrefixSegment */ + { + size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = base; + } + } + while (op < oMatchEnd) + *op++ = *match++; + return sequenceLength; +} + +static seq_t ZSTD_decodeSequence(seqState_t *seqState) +{ + seq_t seq; + + U32 const llCode = FSE_peekSymbol(&seqState->stateLL); + U32 const mlCode = FSE_peekSymbol(&seqState->stateML); + U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ + + U32 const llBits = LL_bits[llCode]; + U32 const mlBits = ML_bits[mlCode]; + U32 const ofBits = ofCode; + U32 const totalBits = llBits + mlBits + ofBits; + + static const U32 LL_base[MaxLL + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, + 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000}; + + static const U32 ML_base[MaxML + 1] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41, + 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003}; + + static const U32 OF_base[MaxOff + 1] = {0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD, + 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, + 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD}; + + /* sequence */ + { + size_t offset; + if (!ofCode) + offset = 0; + else { + offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (ZSTD_32bits()) + BIT_reloadDStream(&seqState->DStream); + } + + if (ofCode <= 1) { + offset += (llCode == 0); + if (offset) { + size_t temp = (offset == 3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { + offset = seqState->prevOffset[0]; + } + } else { + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + seq.offset = offset; + } + + seq.matchLength = ML_base[mlCode] + ((mlCode > 31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + if (ZSTD_32bits() && (mlBits + llBits > 24)) + BIT_reloadDStream(&seqState->DStream); + + seq.litLength = LL_base[llCode] + ((llCode > 15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + if (ZSTD_32bits() || (totalBits > 64 - 7 - (LLFSELog + MLFSELog + OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + + /* ANS state update */ + FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ + FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ + if (ZSTD_32bits()) + BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + + seq.match = NULL; + + return seq; +} + +FORCE_INLINE +size_t ZSTD_execSequence(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base, + const BYTE *const vBase, const BYTE *const dictEnd) +{ + BYTE *const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE *const iLitEnd = *litPtr + sequence.litLength; + const BYTE *match = oLitEnd - sequence.offset; + + /* check */ + if (oMatchEnd > oend) + return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) + return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd > oend_w) + return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); + + /* copy Literals */ + ZSTD_copy8(op, *litPtr); + if (sequence.litLength > 8) + ZSTD_wildcopy(op + 8, (*litPtr) + 8, + sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - base)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - vBase)) + return ERROR(corruption_detected); + match = dictEnd + (match - base); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currPrefixSegment */ + { + size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = base; + if (op > oend_w || sequence.matchLength < MINMATCH) { + U32 i; + for (i = 0; i < sequence.matchLength; ++i) + op[i] = match[i]; + return sequenceLength; + } + } + } + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ + + /* match within prefix */ + if (sequence.offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */ + static const int dec64table[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */ + int const sub2 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op + 4, match); + match -= sub2; + } else { + ZSTD_copy8(op, match); + } + op += 8; + match += 8; + + if (oMatchEnd > oend - (16 - MINMATCH)) { + if (op < oend_w) { + ZSTD_wildcopy(op, match, oend_w - op); + match += oend_w - op; + op = oend_w; + } + while (op < oMatchEnd) + *op++ = *match++; + } else { + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8); /* works even if matchLength < 8 */ + } + return sequenceLength; +} + +static size_t ZSTD_decompressSequences(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize) +{ + const BYTE *ip = (const BYTE *)seqStart; + const BYTE *const iend = ip + seqSize; + BYTE *const ostart = (BYTE * const)dst; + BYTE *const oend = ostart + maxDstSize; + BYTE *op = ostart; + const BYTE *litPtr = dctx->litPtr; + const BYTE *const litEnd = litPtr + dctx->litSize; + const BYTE *const base = (const BYTE *)(dctx->base); + const BYTE *const vBase = (const BYTE *)(dctx->vBase); + const BYTE *const dictEnd = (const BYTE *)(dctx->dictEnd); + int nbSeq; + + /* Build Decoding Tables */ + { + size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); + if (ZSTD_isError(seqHSize)) + return seqHSize; + ip += seqHSize; + } + + /* Regen sequences */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + seqState.prevOffset[i] = dctx->entropy.rep[i]; + } + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend - ip), corruption_detected); + FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq;) { + nbSeq--; + { + seq_t const sequence = ZSTD_decodeSequence(&seqState); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); + if (ZSTD_isError(oneSeqSize)) + return oneSeqSize; + op += oneSeqSize; + } + } + + /* check if reached exact end */ + if (nbSeq) + return ERROR(corruption_detected); + /* save reps for next block */ + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); + } + } + + /* last literal segment */ + { + size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend - op)) + return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op - ostart; +} + +FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t *seqState, int const longOffsets) +{ + seq_t seq; + + U32 const llCode = FSE_peekSymbol(&seqState->stateLL); + U32 const mlCode = FSE_peekSymbol(&seqState->stateML); + U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ + + U32 const llBits = LL_bits[llCode]; + U32 const mlBits = ML_bits[mlCode]; + U32 const ofBits = ofCode; + U32 const totalBits = llBits + mlBits + ofBits; + + static const U32 LL_base[MaxLL + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, + 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000}; + + static const U32 ML_base[MaxML + 1] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41, + 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003}; + + static const U32 OF_base[MaxOff + 1] = {0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD, + 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, + 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD}; + + /* sequence */ + { + size_t offset; + if (!ofCode) + offset = 0; + else { + if (longOffsets) { + int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN); + offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + if (ZSTD_32bits() || extraBits) + BIT_reloadDStream(&seqState->DStream); + if (extraBits) + offset += BIT_readBitsFast(&seqState->DStream, extraBits); + } else { + offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (ZSTD_32bits()) + BIT_reloadDStream(&seqState->DStream); + } + } + + if (ofCode <= 1) { + offset += (llCode == 0); + if (offset) { + size_t temp = (offset == 3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { + offset = seqState->prevOffset[0]; + } + } else { + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + seq.offset = offset; + } + + seq.matchLength = ML_base[mlCode] + ((mlCode > 31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + if (ZSTD_32bits() && (mlBits + llBits > 24)) + BIT_reloadDStream(&seqState->DStream); + + seq.litLength = LL_base[llCode] + ((llCode > 15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + if (ZSTD_32bits() || (totalBits > 64 - 7 - (LLFSELog + MLFSELog + OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + + { + size_t const pos = seqState->pos + seq.litLength; + seq.match = seqState->base + pos - seq.offset; /* single memory segment */ + if (seq.offset > pos) + seq.match += seqState->gotoDict; /* separate memory segment */ + seqState->pos = pos + seq.matchLength; + } + + /* ANS state update */ + FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ + FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ + if (ZSTD_32bits()) + BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + + return seq; +} + +static seq_t ZSTD_decodeSequenceLong(seqState_t *seqState, unsigned const windowSize) +{ + if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) { + return ZSTD_decodeSequenceLong_generic(seqState, 1); + } else { + return ZSTD_decodeSequenceLong_generic(seqState, 0); + } +} + +FORCE_INLINE +size_t ZSTD_execSequenceLong(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base, + const BYTE *const vBase, const BYTE *const dictEnd) +{ + BYTE *const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE *const iLitEnd = *litPtr + sequence.litLength; + const BYTE *match = sequence.match; + + /* check */ + if (oMatchEnd > oend) + return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) + return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd > oend_w) + return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); + + /* copy Literals */ + ZSTD_copy8(op, *litPtr); + if (sequence.litLength > 8) + ZSTD_wildcopy(op + 8, (*litPtr) + 8, + sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - base)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - vBase)) + return ERROR(corruption_detected); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currPrefixSegment */ + { + size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = base; + if (op > oend_w || sequence.matchLength < MINMATCH) { + U32 i; + for (i = 0; i < sequence.matchLength; ++i) + op[i] = match[i]; + return sequenceLength; + } + } + } + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ + + /* match within prefix */ + if (sequence.offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */ + static const int dec64table[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */ + int const sub2 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op + 4, match); + match -= sub2; + } else { + ZSTD_copy8(op, match); + } + op += 8; + match += 8; + + if (oMatchEnd > oend - (16 - MINMATCH)) { + if (op < oend_w) { + ZSTD_wildcopy(op, match, oend_w - op); + match += oend_w - op; + op = oend_w; + } + while (op < oMatchEnd) + *op++ = *match++; + } else { + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8); /* works even if matchLength < 8 */ + } + return sequenceLength; +} + +static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize) +{ + const BYTE *ip = (const BYTE *)seqStart; + const BYTE *const iend = ip + seqSize; + BYTE *const ostart = (BYTE * const)dst; + BYTE *const oend = ostart + maxDstSize; + BYTE *op = ostart; + const BYTE *litPtr = dctx->litPtr; + const BYTE *const litEnd = litPtr + dctx->litSize; + const BYTE *const base = (const BYTE *)(dctx->base); + const BYTE *const vBase = (const BYTE *)(dctx->vBase); + const BYTE *const dictEnd = (const BYTE *)(dctx->dictEnd); + unsigned const windowSize = dctx->fParams.windowSize; + int nbSeq; + + /* Build Decoding Tables */ + { + size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); + if (ZSTD_isError(seqHSize)) + return seqHSize; + ip += seqHSize; + } + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 4 +#define STOSEQ_MASK (STORED_SEQS - 1) +#define ADVANCED_SEQS 4 + seq_t *sequences = (seq_t *)dctx->entropy.workspace; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.workspace) >= sizeof(seq_t) * STORED_SEQS); + dctx->fseEntropy = 1; + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + seqState.prevOffset[i] = dctx->entropy.rep[i]; + } + seqState.base = base; + seqState.pos = (size_t)(op - base); + seqState.gotoDict = (uPtrDiff)dictEnd - (uPtrDiff)base; /* cast to avoid undefined behaviour */ + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend - ip), corruption_detected); + FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb = 0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb < seqAdvance; seqNb++) { + sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, windowSize); + } + if (seqNb < seqAdvance) + return ERROR(corruption_detected); + + /* decode and decompress */ + for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb < nbSeq; seqNb++) { + seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, windowSize); + size_t const oneSeqSize = + ZSTD_execSequenceLong(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd); + if (ZSTD_isError(oneSeqSize)) + return oneSeqSize; + ZSTD_PREFETCH(sequence.match); + sequences[seqNb & STOSEQ_MASK] = sequence; + op += oneSeqSize; + } + if (seqNb < nbSeq) + return ERROR(corruption_detected); + + /* finish queue */ + seqNb -= seqAdvance; + for (; seqNb < nbSeq; seqNb++) { + size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[seqNb & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd); + if (ZSTD_isError(oneSeqSize)) + return oneSeqSize; + op += oneSeqSize; + } + + /* save reps for next block */ + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); + } + } + + /* last literal segment */ + { + size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend - op)) + return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op - ostart; +} + +static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ /* blockType == blockCompressed */ + const BYTE *ip = (const BYTE *)src; + + if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) + return ERROR(srcSize_wrong); + + /* Decode literals section */ + { + size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); + if (ZSTD_isError(litCSize)) + return litCSize; + ip += litCSize; + srcSize -= litCSize; + } + if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */ + /* likely because of register pressure */ + /* if that's the correct cause, then 32-bits ARM should be affected differently */ + /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */ + if (dctx->fParams.windowSize > (1 << 23)) + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize); + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); +} + +static void ZSTD_checkContinuity(ZSTD_DCtx *dctx, const void *dst) +{ + if (dst != dctx->previousDstEnd) { /* not contiguous */ + dctx->dictEnd = dctx->previousDstEnd; + dctx->vBase = (const char *)dst - ((const char *)(dctx->previousDstEnd) - (const char *)(dctx->base)); + dctx->base = dst; + dctx->previousDstEnd = dst; + } +} + +size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + size_t dSize; + ZSTD_checkContinuity(dctx, dst); + dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize); + dctx->previousDstEnd = (char *)dst + dSize; + return dSize; +} + +/** ZSTD_insertBlock() : + insert `src` block into `dctx` history. Useful to track uncompressed blocks. */ +size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart, size_t blockSize) +{ + ZSTD_checkContinuity(dctx, blockStart); + dctx->previousDstEnd = (const char *)blockStart + blockSize; + return blockSize; +} + +size_t ZSTD_generateNxBytes(void *dst, size_t dstCapacity, BYTE byte, size_t length) +{ + if (length > dstCapacity) + return ERROR(dstSize_tooSmall); + memset(dst, byte, length); + return length; +} + +/** ZSTD_findFrameCompressedSize() : + * compatible with legacy mode + * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame + * `srcSize` must be at least as large as the frame contained + * @return : the compressed size of the frame starting at `src` */ +size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) +{ + if (srcSize >= ZSTD_skippableHeaderSize && (ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + return ZSTD_skippableHeaderSize + ZSTD_readLE32((const BYTE *)src + 4); + } else { + const BYTE *ip = (const BYTE *)src; + const BYTE *const ipstart = ip; + size_t remainingSize = srcSize; + ZSTD_frameParams fParams; + + size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize); + if (ZSTD_isError(headerSize)) + return headerSize; + + /* Frame Header */ + { + size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize); + if (ZSTD_isError(ret)) + return ret; + if (ret > 0) + return ERROR(srcSize_wrong); + } + + ip += headerSize; + remainingSize -= headerSize; + + /* Loop on each block */ + while (1) { + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) + return cBlockSize; + + if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) + return ERROR(srcSize_wrong); + + ip += ZSTD_blockHeaderSize + cBlockSize; + remainingSize -= ZSTD_blockHeaderSize + cBlockSize; + + if (blockProperties.lastBlock) + break; + } + + if (fParams.checksumFlag) { /* Frame content checksum */ + if (remainingSize < 4) + return ERROR(srcSize_wrong); + ip += 4; + remainingSize -= 4; + } + + return ip - ipstart; + } +} + +/*! ZSTD_decompressFrame() : +* @dctx must be properly initialized */ +static size_t ZSTD_decompressFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void **srcPtr, size_t *srcSizePtr) +{ + const BYTE *ip = (const BYTE *)(*srcPtr); + BYTE *const ostart = (BYTE * const)dst; + BYTE *const oend = ostart + dstCapacity; + BYTE *op = ostart; + size_t remainingSize = *srcSizePtr; + + /* check */ + if (remainingSize < ZSTD_frameHeaderSize_min + ZSTD_blockHeaderSize) + return ERROR(srcSize_wrong); + + /* Frame Header */ + { + size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix); + if (ZSTD_isError(frameHeaderSize)) + return frameHeaderSize; + if (remainingSize < frameHeaderSize + ZSTD_blockHeaderSize) + return ERROR(srcSize_wrong); + CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize)); + ip += frameHeaderSize; + remainingSize -= frameHeaderSize; + } + + /* Loop on each block */ + while (1) { + size_t decodedSize; + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) + return cBlockSize; + + ip += ZSTD_blockHeaderSize; + remainingSize -= ZSTD_blockHeaderSize; + if (cBlockSize > remainingSize) + return ERROR(srcSize_wrong); + + switch (blockProperties.blockType) { + case bt_compressed: decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend - op, ip, cBlockSize); break; + case bt_raw: decodedSize = ZSTD_copyRawBlock(op, oend - op, ip, cBlockSize); break; + case bt_rle: decodedSize = ZSTD_generateNxBytes(op, oend - op, *ip, blockProperties.origSize); break; + case bt_reserved: + default: return ERROR(corruption_detected); + } + + if (ZSTD_isError(decodedSize)) + return decodedSize; + if (dctx->fParams.checksumFlag) + xxh64_update(&dctx->xxhState, op, decodedSize); + op += decodedSize; + ip += cBlockSize; + remainingSize -= cBlockSize; + if (blockProperties.lastBlock) + break; + } + + if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ + U32 const checkCalc = (U32)xxh64_digest(&dctx->xxhState); + U32 checkRead; + if (remainingSize < 4) + return ERROR(checksum_wrong); + checkRead = ZSTD_readLE32(ip); + if (checkRead != checkCalc) + return ERROR(checksum_wrong); + ip += 4; + remainingSize -= 4; + } + + /* Allow caller to get size read */ + *srcPtr = ip; + *srcSizePtr = remainingSize; + return op - ostart; +} + +static const void *ZSTD_DDictDictContent(const ZSTD_DDict *ddict); +static size_t ZSTD_DDictDictSize(const ZSTD_DDict *ddict); + +static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, + const ZSTD_DDict *ddict) +{ + void *const dststart = dst; + + if (ddict) { + if (dict) { + /* programmer error, these two cases should be mutually exclusive */ + return ERROR(GENERIC); + } + + dict = ZSTD_DDictDictContent(ddict); + dictSize = ZSTD_DDictDictSize(ddict); + } + + while (srcSize >= ZSTD_frameHeaderSize_prefix) { + U32 magicNumber; + + magicNumber = ZSTD_readLE32(src); + if (magicNumber != ZSTD_MAGICNUMBER) { + if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + size_t skippableSize; + if (srcSize < ZSTD_skippableHeaderSize) + return ERROR(srcSize_wrong); + skippableSize = ZSTD_readLE32((const BYTE *)src + 4) + ZSTD_skippableHeaderSize; + if (srcSize < skippableSize) { + return ERROR(srcSize_wrong); + } + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; + } else { + return ERROR(prefix_unknown); + } + } + + if (ddict) { + /* we were called from ZSTD_decompress_usingDDict */ + ZSTD_refDDict(dctx, ddict); + } else { + /* this will initialize correctly with no dict if dict == NULL, so + * use this in all cases but ddict */ + CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize)); + } + ZSTD_checkContinuity(dctx, dst); + + { + const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, &src, &srcSize); + if (ZSTD_isError(res)) + return res; + /* don't need to bounds check this, ZSTD_decompressFrame will have + * already */ + dst = (BYTE *)dst + res; + dstCapacity -= res; + } + } + + if (srcSize) + return ERROR(srcSize_wrong); /* input not entirely consumed */ + + return (BYTE *)dst - (BYTE *)dststart; +} + +size_t ZSTD_decompress_usingDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize) +{ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); +} + +size_t ZSTD_decompressDCtx(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0); +} + +/*-************************************** +* Advanced Streaming Decompression API +* Bufferless and synchronous +****************************************/ +size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx) { return dctx->expected; } + +ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx) +{ + switch (dctx->stage) { + default: /* should not happen */ + case ZSTDds_getFrameHeaderSize: + case ZSTDds_decodeFrameHeader: return ZSTDnit_frameHeader; + case ZSTDds_decodeBlockHeader: return ZSTDnit_blockHeader; + case ZSTDds_decompressBlock: return ZSTDnit_block; + case ZSTDds_decompressLastBlock: return ZSTDnit_lastBlock; + case ZSTDds_checkChecksum: return ZSTDnit_checksum; + case ZSTDds_decodeSkippableHeader: + case ZSTDds_skipFrame: return ZSTDnit_skippableFrame; + } +} + +int ZSTD_isSkipFrame(ZSTD_DCtx *dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */ + +/** ZSTD_decompressContinue() : +* @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity) +* or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + /* Sanity check */ + if (srcSize != dctx->expected) + return ERROR(srcSize_wrong); + if (dstCapacity) + ZSTD_checkContinuity(dctx, dst); + + switch (dctx->stage) { + case ZSTDds_getFrameHeaderSize: + if (srcSize != ZSTD_frameHeaderSize_prefix) + return ERROR(srcSize_wrong); /* impossible */ + if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ + memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix); + dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */ + dctx->stage = ZSTDds_decodeSkippableHeader; + return 0; + } + dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix); + if (ZSTD_isError(dctx->headerSize)) + return dctx->headerSize; + memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix); + if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) { + dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix; + dctx->stage = ZSTDds_decodeFrameHeader; + return 0; + } + dctx->expected = 0; /* not necessary to copy more */ + + case ZSTDds_decodeFrameHeader: + memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected); + CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize)); + dctx->expected = ZSTD_blockHeaderSize; + dctx->stage = ZSTDds_decodeBlockHeader; + return 0; + + case ZSTDds_decodeBlockHeader: { + blockProperties_t bp; + size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp); + if (ZSTD_isError(cBlockSize)) + return cBlockSize; + dctx->expected = cBlockSize; + dctx->bType = bp.blockType; + dctx->rleSize = bp.origSize; + if (cBlockSize) { + dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock; + return 0; + } + /* empty block */ + if (bp.lastBlock) { + if (dctx->fParams.checksumFlag) { + dctx->expected = 4; + dctx->stage = ZSTDds_checkChecksum; + } else { + dctx->expected = 0; /* end of frame */ + dctx->stage = ZSTDds_getFrameHeaderSize; + } + } else { + dctx->expected = 3; /* go directly to next header */ + dctx->stage = ZSTDds_decodeBlockHeader; + } + return 0; + } + case ZSTDds_decompressLastBlock: + case ZSTDds_decompressBlock: { + size_t rSize; + switch (dctx->bType) { + case bt_compressed: rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize); break; + case bt_raw: rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize); break; + case bt_rle: rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize); break; + case bt_reserved: /* should never happen */ + default: return ERROR(corruption_detected); + } + if (ZSTD_isError(rSize)) + return rSize; + if (dctx->fParams.checksumFlag) + xxh64_update(&dctx->xxhState, dst, rSize); + + if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */ + if (dctx->fParams.checksumFlag) { /* another round for frame checksum */ + dctx->expected = 4; + dctx->stage = ZSTDds_checkChecksum; + } else { + dctx->expected = 0; /* ends here */ + dctx->stage = ZSTDds_getFrameHeaderSize; + } + } else { + dctx->stage = ZSTDds_decodeBlockHeader; + dctx->expected = ZSTD_blockHeaderSize; + dctx->previousDstEnd = (char *)dst + rSize; + } + return rSize; + } + case ZSTDds_checkChecksum: { + U32 const h32 = (U32)xxh64_digest(&dctx->xxhState); + U32 const check32 = ZSTD_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */ + if (check32 != h32) + return ERROR(checksum_wrong); + dctx->expected = 0; + dctx->stage = ZSTDds_getFrameHeaderSize; + return 0; + } + case ZSTDds_decodeSkippableHeader: { + memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected); + dctx->expected = ZSTD_readLE32(dctx->headerBuffer + 4); + dctx->stage = ZSTDds_skipFrame; + return 0; + } + case ZSTDds_skipFrame: { + dctx->expected = 0; + dctx->stage = ZSTDds_getFrameHeaderSize; + return 0; + } + default: + return ERROR(GENERIC); /* impossible */ + } +} + +static size_t ZSTD_refDictContent(ZSTD_DCtx *dctx, const void *dict, size_t dictSize) +{ + dctx->dictEnd = dctx->previousDstEnd; + dctx->vBase = (const char *)dict - ((const char *)(dctx->previousDstEnd) - (const char *)(dctx->base)); + dctx->base = dict; + dctx->previousDstEnd = (const char *)dict + dictSize; + return 0; +} + +/* ZSTD_loadEntropy() : + * dict : must point at beginning of a valid zstd dictionary + * @return : size of entropy tables read */ +static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const dict, size_t const dictSize) +{ + const BYTE *dictPtr = (const BYTE *)dict; + const BYTE *const dictEnd = dictPtr + dictSize; + + if (dictSize <= 8) + return ERROR(dictionary_corrupted); + dictPtr += 8; /* skip header = magic + dictID */ + + { + size_t const hSize = HUF_readDTableX4_wksp(entropy->hufTable, dictPtr, dictEnd - dictPtr, entropy->workspace, sizeof(entropy->workspace)); + if (HUF_isError(hSize)) + return ERROR(dictionary_corrupted); + dictPtr += hSize; + } + + { + short offcodeNCount[MaxOff + 1]; + U32 offcodeMaxValue = MaxOff, offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd - dictPtr); + if (FSE_isError(offcodeHeaderSize)) + return ERROR(dictionary_corrupted); + if (offcodeLog > OffFSELog) + return ERROR(dictionary_corrupted); + CHECK_E(FSE_buildDTable_wksp(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); + dictPtr += offcodeHeaderSize; + } + + { + short matchlengthNCount[MaxML + 1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd - dictPtr); + if (FSE_isError(matchlengthHeaderSize)) + return ERROR(dictionary_corrupted); + if (matchlengthLog > MLFSELog) + return ERROR(dictionary_corrupted); + CHECK_E(FSE_buildDTable_wksp(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); + dictPtr += matchlengthHeaderSize; + } + + { + short litlengthNCount[MaxLL + 1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd - dictPtr); + if (FSE_isError(litlengthHeaderSize)) + return ERROR(dictionary_corrupted); + if (litlengthLog > LLFSELog) + return ERROR(dictionary_corrupted); + CHECK_E(FSE_buildDTable_wksp(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); + dictPtr += litlengthHeaderSize; + } + + if (dictPtr + 12 > dictEnd) + return ERROR(dictionary_corrupted); + { + int i; + size_t const dictContentSize = (size_t)(dictEnd - (dictPtr + 12)); + for (i = 0; i < 3; i++) { + U32 const rep = ZSTD_readLE32(dictPtr); + dictPtr += 4; + if (rep == 0 || rep >= dictContentSize) + return ERROR(dictionary_corrupted); + entropy->rep[i] = rep; + } + } + + return dictPtr - (const BYTE *)dict; +} + +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx *dctx, const void *dict, size_t dictSize) +{ + if (dictSize < 8) + return ZSTD_refDictContent(dctx, dict, dictSize); + { + U32 const magic = ZSTD_readLE32(dict); + if (magic != ZSTD_DICT_MAGIC) { + return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ + } + } + dctx->dictID = ZSTD_readLE32((const char *)dict + 4); + + /* load entropy tables */ + { + size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize); + if (ZSTD_isError(eSize)) + return ERROR(dictionary_corrupted); + dict = (const char *)dict + eSize; + dictSize -= eSize; + } + dctx->litEntropy = dctx->fseEntropy = 1; + + /* reference dictionary content */ + return ZSTD_refDictContent(dctx, dict, dictSize); +} + +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict, size_t dictSize) +{ + CHECK_F(ZSTD_decompressBegin(dctx)); + if (dict && dictSize) + CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted); + return 0; +} + +/* ====== ZSTD_DDict ====== */ + +struct ZSTD_DDict_s { + void *dictBuffer; + const void *dictContent; + size_t dictSize; + ZSTD_entropyTables_t entropy; + U32 dictID; + U32 entropyPresent; + ZSTD_customMem cMem; +}; /* typedef'd to ZSTD_DDict within "zstd.h" */ + +size_t ZSTD_DDictWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DDict)); } + +static const void *ZSTD_DDictDictContent(const ZSTD_DDict *ddict) { return ddict->dictContent; } + +static size_t ZSTD_DDictDictSize(const ZSTD_DDict *ddict) { return ddict->dictSize; } + +static void ZSTD_refDDict(ZSTD_DCtx *dstDCtx, const ZSTD_DDict *ddict) +{ + ZSTD_decompressBegin(dstDCtx); /* init */ + if (ddict) { /* support refDDict on NULL */ + dstDCtx->dictID = ddict->dictID; + dstDCtx->base = ddict->dictContent; + dstDCtx->vBase = ddict->dictContent; + dstDCtx->dictEnd = (const BYTE *)ddict->dictContent + ddict->dictSize; + dstDCtx->previousDstEnd = dstDCtx->dictEnd; + if (ddict->entropyPresent) { + dstDCtx->litEntropy = 1; + dstDCtx->fseEntropy = 1; + dstDCtx->LLTptr = ddict->entropy.LLTable; + dstDCtx->MLTptr = ddict->entropy.MLTable; + dstDCtx->OFTptr = ddict->entropy.OFTable; + dstDCtx->HUFptr = ddict->entropy.hufTable; + dstDCtx->entropy.rep[0] = ddict->entropy.rep[0]; + dstDCtx->entropy.rep[1] = ddict->entropy.rep[1]; + dstDCtx->entropy.rep[2] = ddict->entropy.rep[2]; + } else { + dstDCtx->litEntropy = 0; + dstDCtx->fseEntropy = 0; + } + } +} + +static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict *ddict) +{ + ddict->dictID = 0; + ddict->entropyPresent = 0; + if (ddict->dictSize < 8) + return 0; + { + U32 const magic = ZSTD_readLE32(ddict->dictContent); + if (magic != ZSTD_DICT_MAGIC) + return 0; /* pure content mode */ + } + ddict->dictID = ZSTD_readLE32((const char *)ddict->dictContent + 4); + + /* load entropy tables */ + CHECK_E(ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted); + ddict->entropyPresent = 1; + return 0; +} + +static ZSTD_DDict *ZSTD_createDDict_advanced(const void *dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem) +{ + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + + { + ZSTD_DDict *const ddict = (ZSTD_DDict *)ZSTD_malloc(sizeof(ZSTD_DDict), customMem); + if (!ddict) + return NULL; + ddict->cMem = customMem; + + if ((byReference) || (!dict) || (!dictSize)) { + ddict->dictBuffer = NULL; + ddict->dictContent = dict; + } else { + void *const internalBuffer = ZSTD_malloc(dictSize, customMem); + if (!internalBuffer) { + ZSTD_freeDDict(ddict); + return NULL; + } + memcpy(internalBuffer, dict, dictSize); + ddict->dictBuffer = internalBuffer; + ddict->dictContent = internalBuffer; + } + ddict->dictSize = dictSize; + ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ + /* parse dictionary content */ + { + size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict); + if (ZSTD_isError(errorCode)) { + ZSTD_freeDDict(ddict); + return NULL; + } + } + + return ddict; + } +} + +/*! ZSTD_initDDict() : +* Create a digested dictionary, to start decompression without startup delay. +* `dict` content is copied inside DDict. +* Consequently, `dict` can be released after `ZSTD_DDict` creation */ +ZSTD_DDict *ZSTD_initDDict(const void *dict, size_t dictSize, void *workspace, size_t workspaceSize) +{ + ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize); + return ZSTD_createDDict_advanced(dict, dictSize, 1, stackMem); +} + +size_t ZSTD_freeDDict(ZSTD_DDict *ddict) +{ + if (ddict == NULL) + return 0; /* support free on NULL */ + { + ZSTD_customMem const cMem = ddict->cMem; + ZSTD_free(ddict->dictBuffer, cMem); + ZSTD_free(ddict, cMem); + return 0; + } +} + +/*! ZSTD_getDictID_fromDict() : + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +unsigned ZSTD_getDictID_fromDict(const void *dict, size_t dictSize) +{ + if (dictSize < 8) + return 0; + if (ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC) + return 0; + return ZSTD_readLE32((const char *)dict + 4); +} + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict) +{ + if (ddict == NULL) + return 0; + return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize); +} + +/*! ZSTD_getDictID_fromFrame() : + * Provides the dictID required to decompressed the frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary to be decoded (most common case). + * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */ +unsigned ZSTD_getDictID_fromFrame(const void *src, size_t srcSize) +{ + ZSTD_frameParams zfp = {0, 0, 0, 0}; + size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize); + if (ZSTD_isError(hError)) + return 0; + return zfp.dictID; +} + +/*! ZSTD_decompress_usingDDict() : +* Decompression using a pre-digested Dictionary +* Use dictionary without significant overhead. */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_DDict *ddict) +{ + /* pass content and size in case legacy frames are encountered */ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, NULL, 0, ddict); +} + +/*===================================== +* Streaming decompression +*====================================*/ + +typedef enum { zdss_init, zdss_loadHeader, zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; + +/* *** Resource management *** */ +struct ZSTD_DStream_s { + ZSTD_DCtx *dctx; + ZSTD_DDict *ddictLocal; + const ZSTD_DDict *ddict; + ZSTD_frameParams fParams; + ZSTD_dStreamStage stage; + char *inBuff; + size_t inBuffSize; + size_t inPos; + size_t maxWindowSize; + char *outBuff; + size_t outBuffSize; + size_t outStart; + size_t outEnd; + size_t blockSize; + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */ + size_t lhSize; + ZSTD_customMem customMem; + void *legacyContext; + U32 previousLegacyVersion; + U32 legacyVersion; + U32 hostageByte; +}; /* typedef'd to ZSTD_DStream within "zstd.h" */ + +size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize) +{ + size_t const blockSize = MIN(maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); + size_t const inBuffSize = blockSize; + size_t const outBuffSize = maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; + return ZSTD_DCtxWorkspaceBound() + ZSTD_ALIGN(sizeof(ZSTD_DStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize); +} + +static ZSTD_DStream *ZSTD_createDStream_advanced(ZSTD_customMem customMem) +{ + ZSTD_DStream *zds; + + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + + zds = (ZSTD_DStream *)ZSTD_malloc(sizeof(ZSTD_DStream), customMem); + if (zds == NULL) + return NULL; + memset(zds, 0, sizeof(ZSTD_DStream)); + memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem)); + zds->dctx = ZSTD_createDCtx_advanced(customMem); + if (zds->dctx == NULL) { + ZSTD_freeDStream(zds); + return NULL; + } + zds->stage = zdss_init; + zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + return zds; +} + +ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace, size_t workspaceSize) +{ + ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize); + ZSTD_DStream *zds = ZSTD_createDStream_advanced(stackMem); + if (!zds) { + return NULL; + } + + zds->maxWindowSize = maxWindowSize; + zds->stage = zdss_loadHeader; + zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; + ZSTD_freeDDict(zds->ddictLocal); + zds->ddictLocal = NULL; + zds->ddict = zds->ddictLocal; + zds->legacyVersion = 0; + zds->hostageByte = 0; + + { + size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); + size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; + + zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem); + zds->inBuffSize = blockSize; + zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem); + zds->outBuffSize = neededOutSize; + if (zds->inBuff == NULL || zds->outBuff == NULL) { + ZSTD_freeDStream(zds); + return NULL; + } + } + return zds; +} + +ZSTD_DStream *ZSTD_initDStream_usingDDict(size_t maxWindowSize, const ZSTD_DDict *ddict, void *workspace, size_t workspaceSize) +{ + ZSTD_DStream *zds = ZSTD_initDStream(maxWindowSize, workspace, workspaceSize); + if (zds) { + zds->ddict = ddict; + } + return zds; +} + +size_t ZSTD_freeDStream(ZSTD_DStream *zds) +{ + if (zds == NULL) + return 0; /* support free on null */ + { + ZSTD_customMem const cMem = zds->customMem; + ZSTD_freeDCtx(zds->dctx); + zds->dctx = NULL; + ZSTD_freeDDict(zds->ddictLocal); + zds->ddictLocal = NULL; + ZSTD_free(zds->inBuff, cMem); + zds->inBuff = NULL; + ZSTD_free(zds->outBuff, cMem); + zds->outBuff = NULL; + ZSTD_free(zds, cMem); + return 0; + } +} + +/* *** Initialization *** */ + +size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; } +size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; } + +size_t ZSTD_resetDStream(ZSTD_DStream *zds) +{ + zds->stage = zdss_loadHeader; + zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; + zds->legacyVersion = 0; + zds->hostageByte = 0; + return ZSTD_frameHeaderSize_prefix; +} + +/* ***** Decompression ***** */ + +ZSTD_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize) +{ + size_t const length = MIN(dstCapacity, srcSize); + memcpy(dst, src, length); + return length; +} + +size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input) +{ + const char *const istart = (const char *)(input->src) + input->pos; + const char *const iend = (const char *)(input->src) + input->size; + const char *ip = istart; + char *const ostart = (char *)(output->dst) + output->pos; + char *const oend = (char *)(output->dst) + output->size; + char *op = ostart; + U32 someMoreWork = 1; + + while (someMoreWork) { + switch (zds->stage) { + case zdss_init: + ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ + /* fall-through */ + + case zdss_loadHeader: { + size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); + if (ZSTD_isError(hSize)) + return hSize; + if (hSize != 0) { /* need more input */ + size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ + if (toLoad > (size_t)(iend - ip)) { /* not enough input to load full header */ + memcpy(zds->headerBuffer + zds->lhSize, ip, iend - ip); + zds->lhSize += iend - ip; + input->pos = input->size; + return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ + } + memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); + zds->lhSize = hSize; + ip += toLoad; + break; + } + + /* check for single-pass mode opportunity */ + if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */ + && (U64)(size_t)(oend - op) >= zds->fParams.frameContentSize) { + size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend - istart); + if (cSize <= (size_t)(iend - istart)) { + size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend - op, istart, cSize, zds->ddict); + if (ZSTD_isError(decompressedSize)) + return decompressedSize; + ip = istart + cSize; + op += decompressedSize; + zds->dctx->expected = 0; + zds->stage = zdss_init; + someMoreWork = 0; + break; + } + } + + /* Consume header */ + ZSTD_refDDict(zds->dctx, zds->ddict); + { + size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */ + CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size)); + { + size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); + CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer + h1Size, h2Size)); + } + } + + zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); + if (zds->fParams.windowSize > zds->maxWindowSize) + return ERROR(frameParameter_windowTooLarge); + + /* Buffers are preallocated, but double check */ + { + size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); + size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; + if (zds->inBuffSize < blockSize) { + return ERROR(GENERIC); + } + if (zds->outBuffSize < neededOutSize) { + return ERROR(GENERIC); + } + zds->blockSize = blockSize; + } + zds->stage = zdss_read; + } + /* pass-through */ + + case zdss_read: { + size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx); + if (neededInSize == 0) { /* end of frame */ + zds->stage = zdss_init; + someMoreWork = 0; + break; + } + if ((size_t)(iend - ip) >= neededInSize) { /* decode directly from src */ + const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx); + size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, zds->outBuff + zds->outStart, + (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), ip, neededInSize); + if (ZSTD_isError(decodedSize)) + return decodedSize; + ip += neededInSize; + if (!decodedSize && !isSkipFrame) + break; /* this was just a header */ + zds->outEnd = zds->outStart + decodedSize; + zds->stage = zdss_flush; + break; + } + if (ip == iend) { + someMoreWork = 0; + break; + } /* no more input */ + zds->stage = zdss_load; + /* pass-through */ + } + + case zdss_load: { + size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx); + size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */ + size_t loadedSize; + if (toLoad > zds->inBuffSize - zds->inPos) + return ERROR(corruption_detected); /* should never happen */ + loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend - ip); + ip += loadedSize; + zds->inPos += loadedSize; + if (loadedSize < toLoad) { + someMoreWork = 0; + break; + } /* not enough input, wait for more */ + + /* decode loaded input */ + { + const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx); + size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart, + zds->inBuff, neededInSize); + if (ZSTD_isError(decodedSize)) + return decodedSize; + zds->inPos = 0; /* input is consumed */ + if (!decodedSize && !isSkipFrame) { + zds->stage = zdss_read; + break; + } /* this was just a header */ + zds->outEnd = zds->outStart + decodedSize; + zds->stage = zdss_flush; + /* pass-through */ + } + } + + case zdss_flush: { + size_t const toFlushSize = zds->outEnd - zds->outStart; + size_t const flushedSize = ZSTD_limitCopy(op, oend - op, zds->outBuff + zds->outStart, toFlushSize); + op += flushedSize; + zds->outStart += flushedSize; + if (flushedSize == toFlushSize) { /* flush completed */ + zds->stage = zdss_read; + if (zds->outStart + zds->blockSize > zds->outBuffSize) + zds->outStart = zds->outEnd = 0; + break; + } + /* cannot complete flush */ + someMoreWork = 0; + break; + } + default: + return ERROR(GENERIC); /* impossible */ + } + } + + /* result */ + input->pos += (size_t)(ip - istart); + output->pos += (size_t)(op - ostart); + { + size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx); + if (!nextSrcSizeHint) { /* frame fully decoded */ + if (zds->outEnd == zds->outStart) { /* output fully flushed */ + if (zds->hostageByte) { + if (input->pos >= input->size) { + zds->stage = zdss_read; + return 1; + } /* can't release hostage (not present) */ + input->pos++; /* release hostage */ + } + return 0; + } + if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ + input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ + zds->hostageByte = 1; + } + return 1; + } + nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */ + if (zds->inPos > nextSrcSizeHint) + return ERROR(GENERIC); /* should never happen */ + nextSrcSizeHint -= zds->inPos; /* already loaded*/ + return nextSrcSizeHint; + } +} + +EXPORT_SYMBOL(ZSTD_DCtxWorkspaceBound); +EXPORT_SYMBOL(ZSTD_initDCtx); +EXPORT_SYMBOL(ZSTD_decompressDCtx); +EXPORT_SYMBOL(ZSTD_decompress_usingDict); + +EXPORT_SYMBOL(ZSTD_DDictWorkspaceBound); +EXPORT_SYMBOL(ZSTD_initDDict); +EXPORT_SYMBOL(ZSTD_decompress_usingDDict); + +EXPORT_SYMBOL(ZSTD_DStreamWorkspaceBound); +EXPORT_SYMBOL(ZSTD_initDStream); +EXPORT_SYMBOL(ZSTD_initDStream_usingDDict); +EXPORT_SYMBOL(ZSTD_resetDStream); +EXPORT_SYMBOL(ZSTD_decompressStream); +EXPORT_SYMBOL(ZSTD_DStreamInSize); +EXPORT_SYMBOL(ZSTD_DStreamOutSize); + +EXPORT_SYMBOL(ZSTD_findFrameCompressedSize); +EXPORT_SYMBOL(ZSTD_getFrameContentSize); +EXPORT_SYMBOL(ZSTD_findDecompressedSize); + +EXPORT_SYMBOL(ZSTD_isFrame); +EXPORT_SYMBOL(ZSTD_getDictID_fromDict); +EXPORT_SYMBOL(ZSTD_getDictID_fromDDict); +EXPORT_SYMBOL(ZSTD_getDictID_fromFrame); + +EXPORT_SYMBOL(ZSTD_getFrameParams); +EXPORT_SYMBOL(ZSTD_decompressBegin); +EXPORT_SYMBOL(ZSTD_decompressBegin_usingDict); +EXPORT_SYMBOL(ZSTD_copyDCtx); +EXPORT_SYMBOL(ZSTD_nextSrcSizeToDecompress); +EXPORT_SYMBOL(ZSTD_decompressContinue); +EXPORT_SYMBOL(ZSTD_nextInputType); + +EXPORT_SYMBOL(ZSTD_decompressBlock); +EXPORT_SYMBOL(ZSTD_insertBlock); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Zstd Decompressor"); diff --git a/lib/zstd/entropy_common.c b/lib/zstd/entropy_common.c new file mode 100644 index 0000000000000000000000000000000000000000..2b0a643c32c4b2bf24e56a0325d955a59b4f5cdd --- /dev/null +++ b/lib/zstd/entropy_common.c @@ -0,0 +1,243 @@ +/* + * Common functions of New Generation Entropy library + * Copyright (C) 2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ + +/* ************************************* +* Dependencies +***************************************/ +#include "error_private.h" /* ERR_*, ERROR */ +#include "fse.h" +#include "huf.h" +#include "mem.h" + +/*=== Version ===*/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + +/*=== Error Management ===*/ +unsigned FSE_isError(size_t code) { return ERR_isError(code); } + +unsigned HUF_isError(size_t code) { return ERR_isError(code); } + +/*-************************************************************** +* FSE NCount encoding-decoding +****************************************************************/ +size_t FSE_readNCount(short *normalizedCounter, unsigned *maxSVPtr, unsigned *tableLogPtr, const void *headerBuffer, size_t hbSize) +{ + const BYTE *const istart = (const BYTE *)headerBuffer; + const BYTE *const iend = istart + hbSize; + const BYTE *ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + int previous0 = 0; + + if (hbSize < 4) + return ERROR(srcSize_wrong); + bitStream = ZSTD_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) + return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1 << nbBits) + 1; + threshold = 1 << nbBits; + nbBits++; + + while ((remaining > 1) & (charnum <= *maxSVPtr)) { + if (previous0) { + unsigned n0 = charnum; + while ((bitStream & 0xFFFF) == 0xFFFF) { + n0 += 24; + if (ip < iend - 5) { + ip += 2; + bitStream = ZSTD_readLE32(ip) >> bitCount; + } else { + bitStream >>= 16; + bitCount += 16; + } + } + while ((bitStream & 3) == 3) { + n0 += 3; + bitStream >>= 2; + bitCount += 2; + } + n0 += bitStream & 3; + bitCount += 2; + if (n0 > *maxSVPtr) + return ERROR(maxSymbolValue_tooSmall); + while (charnum < n0) + normalizedCounter[charnum++] = 0; + if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4)) { + ip += bitCount >> 3; + bitCount &= 7; + bitStream = ZSTD_readLE32(ip) >> bitCount; + } else { + bitStream >>= 2; + } + } + { + int const max = (2 * threshold - 1) - remaining; + int count; + + if ((bitStream & (threshold - 1)) < (U32)max) { + count = bitStream & (threshold - 1); + bitCount += nbBits - 1; + } else { + count = bitStream & (2 * threshold - 1); + if (count >= threshold) + count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + remaining -= count < 0 ? -count : count; /* -1 means +1 */ + normalizedCounter[charnum++] = (short)count; + previous0 = !count; + while (remaining < threshold) { + nbBits--; + threshold >>= 1; + } + + if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4)) { + ip += bitCount >> 3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + ip = iend - 4; + } + bitStream = ZSTD_readLE32(ip) >> (bitCount & 31); + } + } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ + if (remaining != 1) + return ERROR(corruption_detected); + if (bitCount > 32) + return ERROR(corruption_detected); + *maxSVPtr = charnum - 1; + + ip += (bitCount + 7) >> 3; + return ip - istart; +} + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ +size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ + U32 weightTotal; + const BYTE *ip = (const BYTE *)src; + size_t iSize; + size_t oSize; + + if (!srcSize) + return ERROR(srcSize_wrong); + iSize = ip[0]; + /* memset(huffWeight, 0, hwSize); */ /* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) { /* special header */ + oSize = iSize - 127; + iSize = ((oSize + 1) / 2); + if (iSize + 1 > srcSize) + return ERROR(srcSize_wrong); + if (oSize >= hwSize) + return ERROR(corruption_detected); + ip += 1; + { + U32 n; + for (n = 0; n < oSize; n += 2) { + huffWeight[n] = ip[n / 2] >> 4; + huffWeight[n + 1] = ip[n / 2] & 15; + } + } + } else { /* header compressed with FSE (normal case) */ + if (iSize + 1 > srcSize) + return ERROR(srcSize_wrong); + oSize = FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, 6, workspace, workspaceSize); /* max (hwSize-1) values decoded, as last one is implied */ + if (FSE_isError(oSize)) + return oSize; + } + + /* collect weight stats */ + memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + weightTotal = 0; + { + U32 n; + for (n = 0; n < oSize; n++) { + if (huffWeight[n] >= HUF_TABLELOG_MAX) + return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } + } + if (weightTotal == 0) + return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + { + U32 const tableLog = BIT_highbit32(weightTotal) + 1; + if (tableLog > HUF_TABLELOG_MAX) + return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { + U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << BIT_highbit32(rest); + U32 const lastWeight = BIT_highbit32(rest) + 1; + if (verif != rest) + return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } + } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) + return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize + 1); + return iSize + 1; +} diff --git a/lib/zstd/error_private.h b/lib/zstd/error_private.h new file mode 100644 index 0000000000000000000000000000000000000000..1a60b31f706cb69f8df04608b701d4dfb3f2a085 --- /dev/null +++ b/lib/zstd/error_private.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/* Note : this module is expected to remain private, do not expose it */ + +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +/* **************************************** +* Dependencies +******************************************/ +#include /* size_t */ +#include /* enum list */ + +/* **************************************** +* Compiler-specific +******************************************/ +#define ERR_STATIC static __attribute__((unused)) + +/*-**************************************** +* Customization (error_public.h) +******************************************/ +typedef ZSTD_ErrorCode ERR_enum; +#define PREFIX(name) ZSTD_error_##name + +/*-**************************************** +* Error codes handling +******************************************/ +#define ERROR(name) ((size_t)-PREFIX(name)) + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) +{ + if (!ERR_isError(code)) + return (ERR_enum)0; + return (ERR_enum)(0 - code); +} + +#endif /* ERROR_H_MODULE */ diff --git a/lib/zstd/fse.h b/lib/zstd/fse.h new file mode 100644 index 0000000000000000000000000000000000000000..7460ab04b1916db01f23d243b2eb226b7a694a10 --- /dev/null +++ b/lib/zstd/fse.h @@ -0,0 +1,575 @@ +/* + * FSE : Finite State Entropy codec + * Public Prototypes declaration + * Copyright (C) 2013-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ +#ifndef FSE_H +#define FSE_H + +/*-***************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ + +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#define FSE_PUBLIC_API + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR * 100 * 100 + FSE_VERSION_MINOR * 100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + +/*-***************************************** +* Tool functions +******************************************/ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ + +/* Error Management */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ + +/*-***************************************** +* FSE detailed API +******************************************/ +/*! +FSE_compress() does the following: +1. count symbol occurrence from source[] into table count[] +2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) +3. save normalized counters to memory buffer using writeNCount() +4. build encoding table 'CTable' from normalized counters +5. encode the data stream using encoding table 'CTable' + +FSE_decompress() does the following: +1. read normalized counters with readNCount() +2. build decoding table 'DTable' from normalized counters +3. decode the data stream using decoding table 'DTable' + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and provide normalized distribution using external method. +*/ + +/* *** COMPRESSION *** */ +/*! FSE_optimalTableLog(): + dynamically downsize 'tableLog' when conditions are met. + It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. + @return : recommended tableLog (necessarily <= 'maxTableLog') */ +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_normalizeCount(): + normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) + 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + @return : tableLog, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const unsigned *count, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_NCountWriteBound(): + Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. + Typically useful for allocation purpose. */ +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_writeNCount(): + Compactly save 'normalizedCounter' into 'buffer'. + @return : size of the compressed table, + or an errorCode, which can be tested using FSE_isError(). */ +FSE_PUBLIC_API size_t FSE_writeNCount(void *buffer, size_t bufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! Constructor and Destructor of FSE_CTable. + Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ + +/*! FSE_compress_usingCTable(): + Compress `src` using `ct` into `dst` which must be already allocated. + @return : size of compressed data (<= `dstCapacity`), + or 0 if compressed data could not fit into `dst`, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_compress_usingCTable(void *dst, size_t dstCapacity, const void *src, size_t srcSize, const FSE_CTable *ct); + +/*! +Tutorial : +---------- +The first step is to count all symbols. FSE_count() does this job very fast. +Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. +'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] +maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) +FSE_count() will return the number of occurrence of the most frequent symbol. +This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). + +The next step is to normalize the frequencies. +FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. +It also guarantees a minimum of 1 to any Symbol with frequency >= 1. +You can use 'tableLog'==0 to mean "use default tableLog value". +If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), +which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). + +The result of FSE_normalizeCount() will be saved into a table, +called 'normalizedCounter', which is a table of signed short. +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. +The return value is tableLog if everything proceeded as expected. +It is 0 if there is a single symbol within distribution. +If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). + +'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). +'buffer' must be already allocated. +For guaranteed success, buffer size must be at least FSE_headerBound(). +The result of the function is the number of bytes written into 'buffer'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). + +'normalizedCounter' can then be used to create the compression table 'CTable'. +The space required by 'CTable' must be already allocated, using FSE_createCTable(). +You can then use FSE_buildCTable() to fill 'CTable'. +If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). + +'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). +Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' +The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. +If it returns '0', compressed data could not fit into 'dst'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). +*/ + +/* *** DECOMPRESSION *** */ + +/*! FSE_readNCount(): + Read compactly saved 'normalizedCounter' from 'rBuffer'. + @return : size read from 'rBuffer', + or an errorCode, which can be tested using FSE_isError(). + maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ +FSE_PUBLIC_API size_t FSE_readNCount(short *normalizedCounter, unsigned *maxSymbolValuePtr, unsigned *tableLogPtr, const void *rBuffer, size_t rBuffSize); + +/*! Constructor and Destructor of FSE_DTable. + Note that its size depends on 'tableLog' */ +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ + +/*! FSE_buildDTable(): + Builds 'dt', which must be already allocated, using FSE_createDTable(). + return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize); + +/*! FSE_decompress_usingDTable(): + Decompress compressed source `cSrc` of size `cSrcSize` using `dt` + into `dst` which must be already allocated. + @return : size of regenerated data (necessarily <= `dstCapacity`), + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt); + +/*! +Tutorial : +---------- +(Note : these functions only decompress FSE-compressed blocks. + If block is uncompressed, use memcpy() instead + If block is a single repeated byte, use memset() instead ) + +The first step is to obtain the normalized frequencies of symbols. +This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. +In practice, that means it's necessary to know 'maxSymbolValue' beforehand, +or size the table to handle worst case situations (typically 256). +FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. +The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. +Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. +This is performed by the function FSE_buildDTable(). +The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). +`cSrcSize` must be strictly correct, otherwise decompression will fail. +FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) +*/ + +/* *** Dependency *** */ +#include "bitstream.h" + +/* ***************************************** +* Static allocation +*******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) (size + (size >> 7)) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1 << (maxTableLog - 1)) + ((maxSymbolValue + 1) * 2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1 << maxTableLog)) + +/* ***************************************** +* FSE advanced API +*******************************************/ +/* FSE_count_wksp() : + * Same as FSE_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= `1024` unsigned + */ +size_t FSE_count_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace); + +/* FSE_countFast_wksp() : + * Same as FSE_countFast(), but using an externally provided scratch buffer. + * `workSpace` must be a table of minimum `1024` unsigned + */ +size_t FSE_countFast_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize, unsigned *workSpace); + +/*! FSE_count_simple + * Same as FSE_countFast(), but does not use any additional memory (not even on stack). + * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` (presuming it's also the size of `count`). +*/ +size_t FSE_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize); + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); +/**< same as FSE_optimalTableLog(), which used `minus==2` */ + +size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits); +/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ + +size_t FSE_buildCTable_rle(FSE_CTable *ct, unsigned char symbolValue); +/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` must be >= `(1<= BIT_DStream_completed + +When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. +Checking if DStream has reached its end is performed by : + BIT_endOfDStream(&DStream); +Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. + FSE_endOfDState(&DState); +*/ + +/* ***************************************** +* FSE unsafe API +*******************************************/ +static unsigned char FSE_decodeSymbolFast(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD); +/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ + +/* ***************************************** +* Implementation of inlined functions +*******************************************/ +typedef struct { + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +ZSTD_STATIC void FSE_initCState(FSE_CState_t *statePtr, const FSE_CTable *ct) +{ + const void *ptr = ct; + const U16 *u16ptr = (const U16 *)ptr; + const U32 tableLog = ZSTD_read16(ptr); + statePtr->value = (ptrdiff_t)1 << tableLog; + statePtr->stateTable = u16ptr + 2; + statePtr->symbolTT = ((const U32 *)ct + 1 + (tableLog ? (1 << (tableLog - 1)) : 1)); + statePtr->stateLog = tableLog; +} + +/*! FSE_initCState2() : +* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) +* uses the smallest state value possible, saving the cost of this symbol */ +ZSTD_STATIC void FSE_initCState2(FSE_CState_t *statePtr, const FSE_CTable *ct, U32 symbol) +{ + FSE_initCState(statePtr, ct); + { + const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform *)(statePtr->symbolTT))[symbol]; + const U16 *stateTable = (const U16 *)(statePtr->stateTable); + U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1 << 15)) >> 16); + statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; + } +} + +ZSTD_STATIC void FSE_encodeSymbol(BIT_CStream_t *bitC, FSE_CState_t *statePtr, U32 symbol) +{ + const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform *)(statePtr->symbolTT))[symbol]; + const U16 *const stateTable = (const U16 *)(statePtr->stateTable); + U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); + BIT_addBits(bitC, statePtr->value, nbBitsOut); + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; +} + +ZSTD_STATIC void FSE_flushCState(BIT_CStream_t *bitC, const FSE_CState_t *statePtr) +{ + BIT_addBits(bitC, statePtr->value, statePtr->stateLog); + BIT_flushBits(bitC); +} + +/* ====== Decompression ====== */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct { + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +ZSTD_STATIC void FSE_initDState(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD, const FSE_DTable *dt) +{ + const void *ptr = dt; + const FSE_DTableHeader *const DTableH = (const FSE_DTableHeader *)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +ZSTD_STATIC BYTE FSE_peekSymbol(const FSE_DState_t *DStatePtr) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state]; + return DInfo.symbol; +} + +ZSTD_STATIC void FSE_updateState(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.newState + lowBits; +} + +ZSTD_STATIC BYTE FSE_decodeSymbol(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/*! FSE_decodeSymbolFast() : + unsafe, only works if no symbol has a probability > 50% */ +ZSTD_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t *DStatePtr) { return DStatePtr->state == 0; } + +/* ************************************************************** +* Tuning parameters +****************************************************************/ +/*!MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#ifndef FSE_MAX_MEMORY_USAGE +#define FSE_MAX_MEMORY_USAGE 14 +#endif +#ifndef FSE_DEFAULT_MEMORY_USAGE +#define FSE_DEFAULT_MEMORY_USAGE 13 +#endif + +/*!FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#ifndef FSE_MAX_SYMBOL_VALUE +#define FSE_MAX_SYMBOL_VALUE 255 +#endif + +/* ************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION +#define FSE_DECODE_TYPE FSE_decode_t + +/* *************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE - 2) +#define FSE_MAX_TABLESIZE (1U << FSE_MAX_TABLELOG) +#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE - 1) +#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE - 2) +#define FSE_MIN_TABLELOG 5 + +#define FSE_TABLELOG_ABSOLUTE_MAX 15 +#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX +#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + +#define FSE_TABLESTEP(tableSize) ((tableSize >> 1) + (tableSize >> 3) + 3) + +#endif /* FSE_H */ diff --git a/lib/zstd/fse_compress.c b/lib/zstd/fse_compress.c new file mode 100644 index 0000000000000000000000000000000000000000..ef3d1741d5328247bf912fd11c5737771c3277fc --- /dev/null +++ b/lib/zstd/fse_compress.c @@ -0,0 +1,795 @@ +/* + * FSE : Finite State Entropy encoder + * Copyright (C) 2013-2015, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ + +/* ************************************************************** +* Compiler specifics +****************************************************************/ +#define FORCE_INLINE static __always_inline + +/* ************************************************************** +* Includes +****************************************************************/ +#include "bitstream.h" +#include "fse.h" +#include +#include +#include +#include /* memcpy, memset */ + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_STATIC_ASSERT(c) \ + { \ + enum { FSE_static_assert = 1 / (int)(!!(c)) }; \ + } /* use only *after* variable declarations */ + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +#error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +#error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X, Y) X##Y +#define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y) +#define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y) + +/* Function templates */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * wkspSize should be sized to handle worst case situation, which is `1<> 1 : 1); + FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT); + U32 const step = FSE_TABLESTEP(tableSize); + U32 highThreshold = tableSize - 1; + + U32 *cumul; + FSE_FUNCTION_TYPE *tableSymbol; + size_t spaceUsed32 = 0; + + cumul = (U32 *)workspace + spaceUsed32; + spaceUsed32 += FSE_MAX_SYMBOL_VALUE + 2; + tableSymbol = (FSE_FUNCTION_TYPE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(FSE_FUNCTION_TYPE) * ((size_t)1 << tableLog), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + /* CTable header */ + tableU16[-2] = (U16)tableLog; + tableU16[-1] = (U16)maxSymbolValue; + + /* For explanations on how to distribute symbol values over the table : + * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ + + /* symbol start positions */ + { + U32 u; + cumul[0] = 0; + for (u = 1; u <= maxSymbolValue + 1; u++) { + if (normalizedCounter[u - 1] == -1) { /* Low proba symbol */ + cumul[u] = cumul[u - 1] + 1; + tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u - 1); + } else { + cumul[u] = cumul[u - 1] + normalizedCounter[u - 1]; + } + } + cumul[maxSymbolValue + 1] = tableSize + 1; + } + + /* Spread symbols */ + { + U32 position = 0; + U32 symbol; + for (symbol = 0; symbol <= maxSymbolValue; symbol++) { + int nbOccurences; + for (nbOccurences = 0; nbOccurences < normalizedCounter[symbol]; nbOccurences++) { + tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol; + position = (position + step) & tableMask; + while (position > highThreshold) + position = (position + step) & tableMask; /* Low proba area */ + } + } + + if (position != 0) + return ERROR(GENERIC); /* Must have gone through all positions */ + } + + /* Build table */ + { + U32 u; + for (u = 0; u < tableSize; u++) { + FSE_FUNCTION_TYPE s = tableSymbol[u]; /* note : static analyzer may not understand tableSymbol is properly initialized */ + tableU16[cumul[s]++] = (U16)(tableSize + u); /* TableU16 : sorted by symbol order; gives next state value */ + } + } + + /* Build Symbol Transformation Table */ + { + unsigned total = 0; + unsigned s; + for (s = 0; s <= maxSymbolValue; s++) { + switch (normalizedCounter[s]) { + case 0: break; + + case -1: + case 1: + symbolTT[s].deltaNbBits = (tableLog << 16) - (1 << tableLog); + symbolTT[s].deltaFindState = total - 1; + total++; + break; + default: { + U32 const maxBitsOut = tableLog - BIT_highbit32(normalizedCounter[s] - 1); + U32 const minStatePlus = normalizedCounter[s] << maxBitsOut; + symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; + symbolTT[s].deltaFindState = total - normalizedCounter[s]; + total += normalizedCounter[s]; + } + } + } + } + + return 0; +} + +/*-************************************************************** +* FSE NCount encoding-decoding +****************************************************************/ +size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) +{ + size_t const maxHeaderSize = (((maxSymbolValue + 1) * tableLog) >> 3) + 3; + return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ +} + +static size_t FSE_writeNCount_generic(void *header, size_t headerBufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, + unsigned writeIsSafe) +{ + BYTE *const ostart = (BYTE *)header; + BYTE *out = ostart; + BYTE *const oend = ostart + headerBufferSize; + int nbBits; + const int tableSize = 1 << tableLog; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + int previous0 = 0; + + bitStream = 0; + bitCount = 0; + /* Table Size */ + bitStream += (tableLog - FSE_MIN_TABLELOG) << bitCount; + bitCount += 4; + + /* Init */ + remaining = tableSize + 1; /* +1 for extra accuracy */ + threshold = tableSize; + nbBits = tableLog + 1; + + while (remaining > 1) { /* stops at 1 */ + if (previous0) { + unsigned start = charnum; + while (!normalizedCounter[charnum]) + charnum++; + while (charnum >= start + 24) { + start += 24; + bitStream += 0xFFFFU << bitCount; + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream >> 8); + out += 2; + bitStream >>= 16; + } + while (charnum >= start + 3) { + start += 3; + bitStream += 3 << bitCount; + bitCount += 2; + } + bitStream += (charnum - start) << bitCount; + bitCount += 2; + if (bitCount > 16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream >> 8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } + } + { + int count = normalizedCounter[charnum++]; + int const max = (2 * threshold - 1) - remaining; + remaining -= count < 0 ? -count : count; + count++; /* +1 for extra accuracy */ + if (count >= threshold) + count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ + bitStream += count << bitCount; + bitCount += nbBits; + bitCount -= (count < max); + previous0 = (count == 1); + if (remaining < 1) + return ERROR(GENERIC); + while (remaining < threshold) + nbBits--, threshold >>= 1; + } + if (bitCount > 16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream >> 8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } + } + + /* flush remaining bitStream */ + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream >> 8); + out += (bitCount + 7) / 8; + + if (charnum > maxSymbolValue + 1) + return ERROR(GENERIC); + + return (out - ostart); +} + +size_t FSE_writeNCount(void *buffer, size_t bufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) + return ERROR(tableLog_tooLarge); /* Unsupported */ + if (tableLog < FSE_MIN_TABLELOG) + return ERROR(GENERIC); /* Unsupported */ + + if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); + + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1); +} + +/*-************************************************************** +* Counting histogram +****************************************************************/ +/*! FSE_count_simple + This function counts byte values within `src`, and store the histogram into table `count`. + It doesn't use any additional memory. + But this function is unsafe : it doesn't check that all values within `src` can fit into `count`. + For this reason, prefer using a table `count` with 256 elements. + @return : count of most numerous element +*/ +size_t FSE_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize) +{ + const BYTE *ip = (const BYTE *)src; + const BYTE *const end = ip + srcSize; + unsigned maxSymbolValue = *maxSymbolValuePtr; + unsigned max = 0; + + memset(count, 0, (maxSymbolValue + 1) * sizeof(*count)); + if (srcSize == 0) { + *maxSymbolValuePtr = 0; + return 0; + } + + while (ip < end) + count[*ip++]++; + + while (!count[maxSymbolValue]) + maxSymbolValue--; + *maxSymbolValuePtr = maxSymbolValue; + + { + U32 s; + for (s = 0; s <= maxSymbolValue; s++) + if (count[s] > max) + max = count[s]; + } + + return (size_t)max; +} + +/* FSE_count_parallel_wksp() : + * Same as FSE_count_parallel(), but using an externally provided scratch buffer. + * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */ +static size_t FSE_count_parallel_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned checkMax, + unsigned *const workSpace) +{ + const BYTE *ip = (const BYTE *)source; + const BYTE *const iend = ip + sourceSize; + unsigned maxSymbolValue = *maxSymbolValuePtr; + unsigned max = 0; + U32 *const Counting1 = workSpace; + U32 *const Counting2 = Counting1 + 256; + U32 *const Counting3 = Counting2 + 256; + U32 *const Counting4 = Counting3 + 256; + + memset(Counting1, 0, 4 * 256 * sizeof(unsigned)); + + /* safety checks */ + if (!sourceSize) { + memset(count, 0, maxSymbolValue + 1); + *maxSymbolValuePtr = 0; + return 0; + } + if (!maxSymbolValue) + maxSymbolValue = 255; /* 0 == default */ + + /* by stripes of 16 bytes */ + { + U32 cached = ZSTD_read32(ip); + ip += 4; + while (ip < iend - 15) { + U32 c = cached; + cached = ZSTD_read32(ip); + ip += 4; + Counting1[(BYTE)c]++; + Counting2[(BYTE)(c >> 8)]++; + Counting3[(BYTE)(c >> 16)]++; + Counting4[c >> 24]++; + c = cached; + cached = ZSTD_read32(ip); + ip += 4; + Counting1[(BYTE)c]++; + Counting2[(BYTE)(c >> 8)]++; + Counting3[(BYTE)(c >> 16)]++; + Counting4[c >> 24]++; + c = cached; + cached = ZSTD_read32(ip); + ip += 4; + Counting1[(BYTE)c]++; + Counting2[(BYTE)(c >> 8)]++; + Counting3[(BYTE)(c >> 16)]++; + Counting4[c >> 24]++; + c = cached; + cached = ZSTD_read32(ip); + ip += 4; + Counting1[(BYTE)c]++; + Counting2[(BYTE)(c >> 8)]++; + Counting3[(BYTE)(c >> 16)]++; + Counting4[c >> 24]++; + } + ip -= 4; + } + + /* finish last symbols */ + while (ip < iend) + Counting1[*ip++]++; + + if (checkMax) { /* verify stats will fit into destination table */ + U32 s; + for (s = 255; s > maxSymbolValue; s--) { + Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s]; + if (Counting1[s]) + return ERROR(maxSymbolValue_tooSmall); + } + } + + { + U32 s; + for (s = 0; s <= maxSymbolValue; s++) { + count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s]; + if (count[s] > max) + max = count[s]; + } + } + + while (!count[maxSymbolValue]) + maxSymbolValue--; + *maxSymbolValuePtr = maxSymbolValue; + return (size_t)max; +} + +/* FSE_countFast_wksp() : + * Same as FSE_countFast(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= `1024` unsigned */ +size_t FSE_countFast_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace) +{ + if (sourceSize < 1500) + return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize); + return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace); +} + +/* FSE_count_wksp() : + * Same as FSE_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= `1024` unsigned */ +size_t FSE_count_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace) +{ + if (*maxSymbolValuePtr < 255) + return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace); + *maxSymbolValuePtr = 255; + return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace); +} + +/*-************************************************************** +* FSE Compression Code +****************************************************************/ +/*! FSE_sizeof_CTable() : + FSE_CTable is a variable size structure which contains : + `U16 tableLog;` + `U16 maxSymbolValue;` + `U16 nextStateNumber[1 << tableLog];` // This size is variable + `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];` // This size is variable +Allocation is manual (C standard does not support variable-size structures). +*/ +size_t FSE_sizeof_CTable(unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) + return ERROR(tableLog_tooLarge); + return FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue) * sizeof(U32); +} + +/* provides the minimum logSize to safely represent a distribution */ +static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) +{ + U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1; + U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2; + U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; + return minBits; +} + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) +{ + U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus; + U32 tableLog = maxTableLog; + U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); + if (tableLog == 0) + tableLog = FSE_DEFAULT_TABLELOG; + if (maxBitsSrc < tableLog) + tableLog = maxBitsSrc; /* Accuracy can be reduced */ + if (minBits > tableLog) + tableLog = minBits; /* Need a minimum to safely represent all symbol values */ + if (tableLog < FSE_MIN_TABLELOG) + tableLog = FSE_MIN_TABLELOG; + if (tableLog > FSE_MAX_TABLELOG) + tableLog = FSE_MAX_TABLELOG; + return tableLog; +} + +unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) +{ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); +} + +/* Secondary normalization method. + To be used when primary method fails. */ + +static size_t FSE_normalizeM2(short *norm, U32 tableLog, const unsigned *count, size_t total, U32 maxSymbolValue) +{ + short const NOT_YET_ASSIGNED = -2; + U32 s; + U32 distributed = 0; + U32 ToDistribute; + + /* Init */ + U32 const lowThreshold = (U32)(total >> tableLog); + U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); + + for (s = 0; s <= maxSymbolValue; s++) { + if (count[s] == 0) { + norm[s] = 0; + continue; + } + if (count[s] <= lowThreshold) { + norm[s] = -1; + distributed++; + total -= count[s]; + continue; + } + if (count[s] <= lowOne) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } + + norm[s] = NOT_YET_ASSIGNED; + } + ToDistribute = (1 << tableLog) - distributed; + + if ((total / ToDistribute) > lowOne) { + /* risk of rounding to zero */ + lowOne = (U32)((total * 3) / (ToDistribute * 2)); + for (s = 0; s <= maxSymbolValue; s++) { + if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } + } + ToDistribute = (1 << tableLog) - distributed; + } + + if (distributed == maxSymbolValue + 1) { + /* all values are pretty poor; + probably incompressible data (should have already been detected); + find max, then give all remaining points to max */ + U32 maxV = 0, maxC = 0; + for (s = 0; s <= maxSymbolValue; s++) + if (count[s] > maxC) + maxV = s, maxC = count[s]; + norm[maxV] += (short)ToDistribute; + return 0; + } + + if (total == 0) { + /* all of the symbols were low enough for the lowOne or lowThreshold */ + for (s = 0; ToDistribute > 0; s = (s + 1) % (maxSymbolValue + 1)) + if (norm[s] > 0) + ToDistribute--, norm[s]++; + return 0; + } + + { + U64 const vStepLog = 62 - tableLog; + U64 const mid = (1ULL << (vStepLog - 1)) - 1; + U64 const rStep = div_u64((((U64)1 << vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */ + U64 tmpTotal = mid; + for (s = 0; s <= maxSymbolValue; s++) { + if (norm[s] == NOT_YET_ASSIGNED) { + U64 const end = tmpTotal + (count[s] * rStep); + U32 const sStart = (U32)(tmpTotal >> vStepLog); + U32 const sEnd = (U32)(end >> vStepLog); + U32 const weight = sEnd - sStart; + if (weight < 1) + return ERROR(GENERIC); + norm[s] = (short)weight; + tmpTotal = end; + } + } + } + + return 0; +} + +size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const unsigned *count, size_t total, unsigned maxSymbolValue) +{ + /* Sanity checks */ + if (tableLog == 0) + tableLog = FSE_DEFAULT_TABLELOG; + if (tableLog < FSE_MIN_TABLELOG) + return ERROR(GENERIC); /* Unsupported size */ + if (tableLog > FSE_MAX_TABLELOG) + return ERROR(tableLog_tooLarge); /* Unsupported size */ + if (tableLog < FSE_minTableLog(total, maxSymbolValue)) + return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ + + { + U32 const rtbTable[] = {0, 473195, 504333, 520860, 550000, 700000, 750000, 830000}; + U64 const scale = 62 - tableLog; + U64 const step = div_u64((U64)1 << 62, (U32)total); /* <== here, one division ! */ + U64 const vStep = 1ULL << (scale - 20); + int stillToDistribute = 1 << tableLog; + unsigned s; + unsigned largest = 0; + short largestP = 0; + U32 lowThreshold = (U32)(total >> tableLog); + + for (s = 0; s <= maxSymbolValue; s++) { + if (count[s] == total) + return 0; /* rle special case */ + if (count[s] == 0) { + normalizedCounter[s] = 0; + continue; + } + if (count[s] <= lowThreshold) { + normalizedCounter[s] = -1; + stillToDistribute--; + } else { + short proba = (short)((count[s] * step) >> scale); + if (proba < 8) { + U64 restToBeat = vStep * rtbTable[proba]; + proba += (count[s] * step) - ((U64)proba << scale) > restToBeat; + } + if (proba > largestP) + largestP = proba, largest = s; + normalizedCounter[s] = proba; + stillToDistribute -= proba; + } + } + if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { + /* corner case, need another normalization method */ + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); + if (FSE_isError(errorCode)) + return errorCode; + } else + normalizedCounter[largest] += (short)stillToDistribute; + } + + return tableLog; +} + +/* fake FSE_CTable, for raw (uncompressed) input */ +size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits) +{ + const unsigned tableSize = 1 << nbBits; + const unsigned tableMask = tableSize - 1; + const unsigned maxSymbolValue = tableMask; + void *const ptr = ct; + U16 *const tableU16 = ((U16 *)ptr) + 2; + void *const FSCT = ((U32 *)ptr) + 1 /* header */ + (tableSize >> 1); /* assumption : tableLog >= 1 */ + FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT); + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) + return ERROR(GENERIC); /* min size */ + + /* header */ + tableU16[-2] = (U16)nbBits; + tableU16[-1] = (U16)maxSymbolValue; + + /* Build table */ + for (s = 0; s < tableSize; s++) + tableU16[s] = (U16)(tableSize + s); + + /* Build Symbol Transformation Table */ + { + const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits); + for (s = 0; s <= maxSymbolValue; s++) { + symbolTT[s].deltaNbBits = deltaNbBits; + symbolTT[s].deltaFindState = s - 1; + } + } + + return 0; +} + +/* fake FSE_CTable, for rle input (always same symbol) */ +size_t FSE_buildCTable_rle(FSE_CTable *ct, BYTE symbolValue) +{ + void *ptr = ct; + U16 *tableU16 = ((U16 *)ptr) + 2; + void *FSCTptr = (U32 *)ptr + 2; + FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)FSCTptr; + + /* header */ + tableU16[-2] = (U16)0; + tableU16[-1] = (U16)symbolValue; + + /* Build table */ + tableU16[0] = 0; + tableU16[1] = 0; /* just in case */ + + /* Build Symbol Transformation Table */ + symbolTT[symbolValue].deltaNbBits = 0; + symbolTT[symbolValue].deltaFindState = 0; + + return 0; +} + +static size_t FSE_compress_usingCTable_generic(void *dst, size_t dstSize, const void *src, size_t srcSize, const FSE_CTable *ct, const unsigned fast) +{ + const BYTE *const istart = (const BYTE *)src; + const BYTE *const iend = istart + srcSize; + const BYTE *ip = iend; + + BIT_CStream_t bitC; + FSE_CState_t CState1, CState2; + + /* init */ + if (srcSize <= 2) + return 0; + { + size_t const initError = BIT_initCStream(&bitC, dst, dstSize); + if (FSE_isError(initError)) + return 0; /* not enough space available to write a bitstream */ + } + +#define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s)) + + if (srcSize & 1) { + FSE_initCState2(&CState1, ct, *--ip); + FSE_initCState2(&CState2, ct, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + FSE_FLUSHBITS(&bitC); + } else { + FSE_initCState2(&CState2, ct, *--ip); + FSE_initCState2(&CState1, ct, *--ip); + } + + /* join to mod 4 */ + srcSize -= 2; + if ((sizeof(bitC.bitContainer) * 8 > FSE_MAX_TABLELOG * 4 + 7) && (srcSize & 2)) { /* test bit 2 */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + FSE_FLUSHBITS(&bitC); + } + + /* 2 or 4 encoding per loop */ + while (ip > istart) { + + FSE_encodeSymbol(&bitC, &CState2, *--ip); + + if (sizeof(bitC.bitContainer) * 8 < FSE_MAX_TABLELOG * 2 + 7) /* this test must be static */ + FSE_FLUSHBITS(&bitC); + + FSE_encodeSymbol(&bitC, &CState1, *--ip); + + if (sizeof(bitC.bitContainer) * 8 > FSE_MAX_TABLELOG * 4 + 7) { /* this test must be static */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + } + + FSE_FLUSHBITS(&bitC); + } + + FSE_flushCState(&bitC, &CState2); + FSE_flushCState(&bitC, &CState1); + return BIT_closeCStream(&bitC); +} + +size_t FSE_compress_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const FSE_CTable *ct) +{ + unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); + + if (fast) + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); + else + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); +} + +size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c new file mode 100644 index 0000000000000000000000000000000000000000..a84300e5a0132247d7ce18caeab0bb093b2305a3 --- /dev/null +++ b/lib/zstd/fse_decompress.c @@ -0,0 +1,332 @@ +/* + * FSE : Finite State Entropy decoder + * Copyright (C) 2013-2015, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ + +/* ************************************************************** +* Compiler specifics +****************************************************************/ +#define FORCE_INLINE static __always_inline + +/* ************************************************************** +* Includes +****************************************************************/ +#include "bitstream.h" +#include "fse.h" +#include +#include +#include /* memcpy, memset */ + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError +#define FSE_STATIC_ASSERT(c) \ + { \ + enum { FSE_static_assert = 1 / (int)(!!(c)) }; \ + } /* use only *after* variable declarations */ + +/* check and forward error code */ +#define CHECK_F(f) \ + { \ + size_t const e = f; \ + if (FSE_isError(e)) \ + return e; \ + } + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +#error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +#error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X, Y) X##Y +#define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y) +#define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y) + +/* Function templates */ + +size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize) +{ + void *const tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE *const tableDecode = (FSE_DECODE_TYPE *)(tdPtr); + U16 *symbolNext = (U16 *)workspace; + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize - 1; + + /* Sanity Checks */ + if (workspaceSize < sizeof(U16) * (FSE_MAX_SYMBOL_VALUE + 1)) + return ERROR(tableLog_tooLarge); + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) + return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) + return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + { + FSE_DTableHeader DTableH; + DTableH.tableLog = (U16)tableLog; + DTableH.fastMode = 1; + { + S16 const largeLimit = (S16)(1 << (tableLog - 1)); + U32 s; + for (s = 0; s < maxSV1; s++) { + if (normalizedCounter[s] == -1) { + tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; + symbolNext[s] = 1; + } else { + if (normalizedCounter[s] >= largeLimit) + DTableH.fastMode = 0; + symbolNext[s] = normalizedCounter[s]; + } + } + } + memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + { + U32 const tableMask = tableSize - 1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s = 0; s < maxSV1; s++) { + int i; + for (i = 0; i < normalizedCounter[s]; i++) { + tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s; + position = (position + step) & tableMask; + while (position > highThreshold) + position = (position + step) & tableMask; /* lowprob area */ + } + } + if (position != 0) + return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { + U32 u; + for (u = 0; u < tableSize; u++) { + FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol); + U16 nextState = symbolNext[symbol]++; + tableDecode[u].nbBits = (BYTE)(tableLog - BIT_highbit32((U32)nextState)); + tableDecode[u].newState = (U16)((nextState << tableDecode[u].nbBits) - tableSize); + } + } + + return 0; +} + +/*-******************************************************* +* Decompression (Byte symbols) +*********************************************************/ +size_t FSE_buildDTable_rle(FSE_DTable *dt, BYTE symbolValue) +{ + void *ptr = dt; + FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr; + void *dPtr = dt + 1; + FSE_decode_t *const cell = (FSE_decode_t *)dPtr; + + DTableH->tableLog = 0; + DTableH->fastMode = 0; + + cell->newState = 0; + cell->symbol = symbolValue; + cell->nbBits = 0; + + return 0; +} + +size_t FSE_buildDTable_raw(FSE_DTable *dt, unsigned nbBits) +{ + void *ptr = dt; + FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr; + void *dPtr = dt + 1; + FSE_decode_t *const dinfo = (FSE_decode_t *)dPtr; + const unsigned tableSize = 1 << nbBits; + const unsigned tableMask = tableSize - 1; + const unsigned maxSV1 = tableMask + 1; + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) + return ERROR(GENERIC); /* min size */ + + /* Build Decoding Table */ + DTableH->tableLog = (U16)nbBits; + DTableH->fastMode = 1; + for (s = 0; s < maxSV1; s++) { + dinfo[s].newState = 0; + dinfo[s].symbol = (BYTE)s; + dinfo[s].nbBits = (BYTE)nbBits; + } + + return 0; +} + +FORCE_INLINE size_t FSE_decompress_usingDTable_generic(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt, + const unsigned fast) +{ + BYTE *const ostart = (BYTE *)dst; + BYTE *op = ostart; + BYTE *const omax = op + maxDstSize; + BYTE *const olimit = omax - 3; + + BIT_DStream_t bitD; + FSE_DState_t state1; + FSE_DState_t state2; + + /* Init */ + CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize)); + + FSE_initDState(&state1, &bitD, dt); + FSE_initDState(&state2, &bitD, dt); + +#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) + + /* 4 symbols per loop */ + for (; (BIT_reloadDStream(&bitD) == BIT_DStream_unfinished) & (op < olimit); op += 4) { + op[0] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG * 4 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ + { + if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { + op += 2; + break; + } + } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) { + if (op > (omax - 2)) + return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state1); + if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state2); + break; + } + + if (op > (omax - 2)) + return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state2); + if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state1); + break; + } + } + + return op - ostart; +} + +size_t FSE_decompress_usingDTable(void *dst, size_t originalSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt) +{ + const void *ptr = dt; + const FSE_DTableHeader *DTableH = (const FSE_DTableHeader *)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); +} + +size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize) +{ + const BYTE *const istart = (const BYTE *)cSrc; + const BYTE *ip = istart; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + size_t NCountLength; + + FSE_DTable *dt; + short *counting; + size_t spaceUsed32 = 0; + + FSE_STATIC_ASSERT(sizeof(FSE_DTable) == sizeof(U32)); + + dt = (FSE_DTable *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += FSE_DTABLE_SIZE_U32(maxLog); + counting = (short *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(short) * (FSE_MAX_SYMBOL_VALUE + 1), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + /* normal FSE decoding mode */ + NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(NCountLength)) + return NCountLength; + // if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining + // case : NCountLength==cSrcSize */ + if (tableLog > maxLog) + return ERROR(tableLog_tooLarge); + ip += NCountLength; + cSrcSize -= NCountLength; + + CHECK_F(FSE_buildDTable_wksp(dt, counting, maxSymbolValue, tableLog, workspace, workspaceSize)); + + return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, dt); /* always return, even if it is an error code */ +} diff --git a/lib/zstd/huf.h b/lib/zstd/huf.h new file mode 100644 index 0000000000000000000000000000000000000000..2143da28d952815cd086e6218dcac1bd9328f6c4 --- /dev/null +++ b/lib/zstd/huf.h @@ -0,0 +1,212 @@ +/* + * Huffman coder, part of New Generation Entropy library + * header file + * Copyright (C) 2013-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ +#ifndef HUF_H_298734234 +#define HUF_H_298734234 + +/* *** Dependencies *** */ +#include /* size_t */ + +/* *** Tool functions *** */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ +size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ + +/* Error Management */ +unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ + +/* *** Advanced function *** */ + +/** HUF_compress4X_wksp() : +* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */ +size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, + size_t wkspSize); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ + +/* *** Dependencies *** */ +#include "mem.h" /* U32 */ + +/* *** Constants *** */ +#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ +#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */ +#define HUF_SYMBOLVALUE_MAX 255 + +#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) +#error "HUF_TABLELOG_MAX is too large !" +#endif + +/* **************************************** +* Static allocation +******************************************/ +/* HUF buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size >> 8) + 8) /* only true if incompressible pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of HUF's Compression Table */ +#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ + U32 name##hb[maxSymbolValue + 1]; \ + void *name##hv = &(name##hb); \ + HUF_CElt *name = (HUF_CElt *)(name##hv) /* no final ; */ + +/* static allocation of HUF's DTable */ +typedef U32 HUF_DTable; +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1 << (maxTableLog))) +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = {((U32)((maxTableLog)-1) * 0x01000001)} +#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = {((U32)(maxTableLog)*0x01000001)} + +/* The workspace must have alignment at least 4 and be at least this large */ +#define HUF_COMPRESS_WORKSPACE_SIZE (6 << 10) +#define HUF_COMPRESS_WORKSPACE_SIZE_U32 (HUF_COMPRESS_WORKSPACE_SIZE / sizeof(U32)) + +/* The workspace must have alignment at least 4 and be at least this large */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE (3 << 10) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + +/* **************************************** +* Advanced decompression functions +******************************************/ +size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize); /**< decodes RLE and uncompressed */ +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< single-symbol decoder */ +size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< double-symbols decoder */ + +/* **************************************** +* HUF detailed API +******************************************/ +/*! +HUF_compress() does the following: +1. count symbol occurrence from source[] into table count[] using FSE_count() +2. (optional) refine tableLog using HUF_optimalTableLog() +3. build Huffman table from count using HUF_buildCTable() +4. save Huffman table to memory buffer using HUF_writeCTable_wksp() +5. encode the data stream using HUF_compress4X_usingCTable() + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and regenerate 'CTable' using external methods. +*/ +/* FSE_count() : find it within "fse.h" */ +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); +typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ +size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog, void *workspace, size_t workspaceSize); +size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable); + +typedef enum { + HUF_repeat_none, /**< Cannot use the previous table */ + HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, + 4}X_repeat */ + HUF_repeat_valid /**< Can use the previous table and it is asumed to be valid */ +} HUF_repeat; +/** HUF_compress4X_repeat() : +* Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. +* If it uses hufTable it does not modify hufTable or repeat. +* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. +* If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, + size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, + int preferRepeat); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned. + */ +size_t HUF_buildCTable_wksp(HUF_CElt *tree, const U32 *count, U32 maxSymbolValue, U32 maxNbBits, void *workSpace, size_t wkspSize); + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ +size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, + void *workspace, size_t workspaceSize); + +/** HUF_readCTable() : +* Loading a CTable saved with HUF_writeCTable() */ +size_t HUF_readCTable_wksp(HUF_CElt *CTable, unsigned maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); + +/* +HUF_decompress() does the following: +1. select the decompression algorithm (X2, X4) based on pre-computed heuristics +2. build Huffman table from save, using HUF_readDTableXn() +3. decode 1 or 4 segments in parallel using HUF_decompressSXn_usingDTable +*/ + +/** HUF_selectDecoder() : +* Tells which decoder is likely to decode faster, +* based on a set of pre-determined metrics. +* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 . +* Assumption : 0 < cSrcSize < dstSize <= 128 KB */ +U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize); + +size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); +size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); + +size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); +size_t HUF_decompress4X2_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); +size_t HUF_decompress4X4_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); + +/* single stream variants */ + +size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, + size_t wkspSize); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ +size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable); +/** HUF_compress1X_repeat() : +* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. +* If it uses hufTable it does not modify hufTable or repeat. +* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. +* If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, + size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, + int preferRepeat); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize); +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< single-symbol decoder */ +size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< double-symbols decoder */ + +size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, + const HUF_DTable *DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ +size_t HUF_decompress1X2_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); +size_t HUF_decompress1X4_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); + +#endif /* HUF_H_298734234 */ diff --git a/lib/zstd/huf_compress.c b/lib/zstd/huf_compress.c new file mode 100644 index 0000000000000000000000000000000000000000..40055a7016e669b81345cc10267e77ad4f220248 --- /dev/null +++ b/lib/zstd/huf_compress.c @@ -0,0 +1,770 @@ +/* + * Huffman encoder, part of New Generation Entropy library + * Copyright (C) 2013-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ + +/* ************************************************************** +* Includes +****************************************************************/ +#include "bitstream.h" +#include "fse.h" /* header compression */ +#include "huf.h" +#include +#include /* memcpy, memset */ + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_STATIC_ASSERT(c) \ + { \ + enum { HUF_static_assert = 1 / (int)(!!(c)) }; \ + } /* use only *after* variable declarations */ +#define CHECK_V_F(e, f) \ + size_t const e = f; \ + if (ERR_isError(e)) \ + return f +#define CHECK_F(f) \ + { \ + CHECK_V_F(_var_err__, f); \ + } + +/* ************************************************************** +* Utils +****************************************************************/ +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) +{ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1); +} + +/* ******************************************************* +* HUF : Huffman block compression +*********************************************************/ +/* HUF_compressWeights() : + * Same as FSE_compress(), but dedicated to huff0's weights compression. + * The use case needs much less stack memory. + * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. + */ +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 +size_t HUF_compressWeights_wksp(void *dst, size_t dstSize, const void *weightTable, size_t wtSize, void *workspace, size_t workspaceSize) +{ + BYTE *const ostart = (BYTE *)dst; + BYTE *op = ostart; + BYTE *const oend = ostart + dstSize; + + U32 maxSymbolValue = HUF_TABLELOG_MAX; + U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; + + FSE_CTable *CTable; + U32 *count; + S16 *norm; + size_t spaceUsed32 = 0; + + HUF_STATIC_ASSERT(sizeof(FSE_CTable) == sizeof(U32)); + + CTable = (FSE_CTable *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX); + count = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 1; + norm = (S16 *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(S16) * (HUF_TABLELOG_MAX + 1), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + /* init conditions */ + if (wtSize <= 1) + return 0; /* Not compressible */ + + /* Scan input and build symbol stats */ + { + CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize)); + if (maxCount == wtSize) + return 1; /* only a single symbol in src : rle */ + if (maxCount == 1) + return 0; /* each symbol present maximum once => not compressible */ + } + + tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue); + CHECK_F(FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue)); + + /* Write table description header */ + { + CHECK_V_F(hSize, FSE_writeNCount(op, oend - op, norm, maxSymbolValue, tableLog)); + op += hSize; + } + + /* Compress */ + CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, workspace, workspaceSize)); + { + CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable)); + if (cSize == 0) + return 0; /* not enough space for compressed data */ + op += cSize; + } + + return op - ostart; +} + +struct HUF_CElt_s { + U16 val; + BYTE nbBits; +}; /* typedef'd to HUF_CElt within "huf.h" */ + +/*! HUF_writeCTable_wksp() : + `CTable` : Huffman tree to save, using huf representation. + @return : size of saved CTable */ +size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog, void *workspace, size_t workspaceSize) +{ + BYTE *op = (BYTE *)dst; + U32 n; + + BYTE *bitsToWeight; + BYTE *huffWeight; + size_t spaceUsed32 = 0; + + bitsToWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_TABLELOG_MAX + 1, sizeof(U32)) >> 2; + huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + /* check conditions */ + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(maxSymbolValue_tooLarge); + + /* convert to weight */ + bitsToWeight[0] = 0; + for (n = 1; n < huffLog + 1; n++) + bitsToWeight[n] = (BYTE)(huffLog + 1 - n); + for (n = 0; n < maxSymbolValue; n++) + huffWeight[n] = bitsToWeight[CTable[n].nbBits]; + + /* attempt weights compression by FSE */ + { + CHECK_V_F(hSize, HUF_compressWeights_wksp(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue, workspace, workspaceSize)); + if ((hSize > 1) & (hSize < maxSymbolValue / 2)) { /* FSE compressed */ + op[0] = (BYTE)hSize; + return hSize + 1; + } + } + + /* write raw values as 4-bits (max : 15) */ + if (maxSymbolValue > (256 - 128)) + return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */ + if (((maxSymbolValue + 1) / 2) + 1 > maxDstSize) + return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */ + op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue - 1)); + huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */ + for (n = 0; n < maxSymbolValue; n += 2) + op[(n / 2) + 1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n + 1]); + return ((maxSymbolValue + 1) / 2) + 1; +} + +size_t HUF_readCTable_wksp(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ + U32 *rankVal; + BYTE *huffWeight; + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t readSize; + size_t spaceUsed32 = 0; + + rankVal = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; + huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + /* get symbol weights */ + readSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); + if (ERR_isError(readSize)) + return readSize; + + /* check result */ + if (tableLog > HUF_TABLELOG_MAX) + return ERROR(tableLog_tooLarge); + if (nbSymbols > maxSymbolValue + 1) + return ERROR(maxSymbolValue_tooSmall); + + /* Prepare base value per rank */ + { + U32 n, nextRankStart = 0; + for (n = 1; n <= tableLog; n++) { + U32 curr = nextRankStart; + nextRankStart += (rankVal[n] << (n - 1)); + rankVal[n] = curr; + } + } + + /* fill nbBits */ + { + U32 n; + for (n = 0; n < nbSymbols; n++) { + const U32 w = huffWeight[n]; + CTable[n].nbBits = (BYTE)(tableLog + 1 - w); + } + } + + /* fill val */ + { + U16 nbPerRank[HUF_TABLELOG_MAX + 2] = {0}; /* support w=0=>n=tableLog+1 */ + U16 valPerRank[HUF_TABLELOG_MAX + 2] = {0}; + { + U32 n; + for (n = 0; n < nbSymbols; n++) + nbPerRank[CTable[n].nbBits]++; + } + /* determine stating value per rank */ + valPerRank[tableLog + 1] = 0; /* for w==0 */ + { + U16 min = 0; + U32 n; + for (n = tableLog; n > 0; n--) { /* start at n=tablelog <-> w=1 */ + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } + } + /* assign value within rank, symbol order */ + { + U32 n; + for (n = 0; n <= maxSymbolValue; n++) + CTable[n].val = valPerRank[CTable[n].nbBits]++; + } + } + + return readSize; +} + +typedef struct nodeElt_s { + U32 count; + U16 parent; + BYTE byte; + BYTE nbBits; +} nodeElt; + +static U32 HUF_setMaxHeight(nodeElt *huffNode, U32 lastNonNull, U32 maxNbBits) +{ + const U32 largestBits = huffNode[lastNonNull].nbBits; + if (largestBits <= maxNbBits) + return largestBits; /* early exit : no elt > maxNbBits */ + + /* there are several too large elements (at least >= 2) */ + { + int totalCost = 0; + const U32 baseCost = 1 << (largestBits - maxNbBits); + U32 n = lastNonNull; + + while (huffNode[n].nbBits > maxNbBits) { + totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)); + huffNode[n].nbBits = (BYTE)maxNbBits; + n--; + } /* n stops at huffNode[n].nbBits <= maxNbBits */ + while (huffNode[n].nbBits == maxNbBits) + n--; /* n end at index of smallest symbol using < maxNbBits */ + + /* renorm totalCost */ + totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */ + + /* repay normalized cost */ + { + U32 const noSymbol = 0xF0F0F0F0; + U32 rankLast[HUF_TABLELOG_MAX + 2]; + int pos; + + /* Get pos of last (smallest) symbol per rank */ + memset(rankLast, 0xF0, sizeof(rankLast)); + { + U32 currNbBits = maxNbBits; + for (pos = n; pos >= 0; pos--) { + if (huffNode[pos].nbBits >= currNbBits) + continue; + currNbBits = huffNode[pos].nbBits; /* < maxNbBits */ + rankLast[maxNbBits - currNbBits] = pos; + } + } + + while (totalCost > 0) { + U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1; + for (; nBitsToDecrease > 1; nBitsToDecrease--) { + U32 highPos = rankLast[nBitsToDecrease]; + U32 lowPos = rankLast[nBitsToDecrease - 1]; + if (highPos == noSymbol) + continue; + if (lowPos == noSymbol) + break; + { + U32 const highTotal = huffNode[highPos].count; + U32 const lowTotal = 2 * huffNode[lowPos].count; + if (highTotal <= lowTotal) + break; + } + } + /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */ + /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */ + while ((nBitsToDecrease <= HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) + nBitsToDecrease++; + totalCost -= 1 << (nBitsToDecrease - 1); + if (rankLast[nBitsToDecrease - 1] == noSymbol) + rankLast[nBitsToDecrease - 1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */ + huffNode[rankLast[nBitsToDecrease]].nbBits++; + if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */ + rankLast[nBitsToDecrease] = noSymbol; + else { + rankLast[nBitsToDecrease]--; + if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits - nBitsToDecrease) + rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */ + } + } /* while (totalCost > 0) */ + + while (totalCost < 0) { /* Sometimes, cost correction overshoot */ + if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 + (using maxNbBits) */ + while (huffNode[n].nbBits == maxNbBits) + n--; + huffNode[n + 1].nbBits--; + rankLast[1] = n + 1; + totalCost++; + continue; + } + huffNode[rankLast[1] + 1].nbBits--; + rankLast[1]++; + totalCost++; + } + } + } /* there are several too large elements (at least >= 2) */ + + return maxNbBits; +} + +typedef struct { + U32 base; + U32 curr; +} rankPos; + +static void HUF_sort(nodeElt *huffNode, const U32 *count, U32 maxSymbolValue) +{ + rankPos rank[32]; + U32 n; + + memset(rank, 0, sizeof(rank)); + for (n = 0; n <= maxSymbolValue; n++) { + U32 r = BIT_highbit32(count[n] + 1); + rank[r].base++; + } + for (n = 30; n > 0; n--) + rank[n - 1].base += rank[n].base; + for (n = 0; n < 32; n++) + rank[n].curr = rank[n].base; + for (n = 0; n <= maxSymbolValue; n++) { + U32 const c = count[n]; + U32 const r = BIT_highbit32(c + 1) + 1; + U32 pos = rank[r].curr++; + while ((pos > rank[r].base) && (c > huffNode[pos - 1].count)) + huffNode[pos] = huffNode[pos - 1], pos--; + huffNode[pos].count = c; + huffNode[pos].byte = (BYTE)n; + } +} + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned. + */ +#define STARTNODE (HUF_SYMBOLVALUE_MAX + 1) +typedef nodeElt huffNodeTable[2 * HUF_SYMBOLVALUE_MAX + 1 + 1]; +size_t HUF_buildCTable_wksp(HUF_CElt *tree, const U32 *count, U32 maxSymbolValue, U32 maxNbBits, void *workSpace, size_t wkspSize) +{ + nodeElt *const huffNode0 = (nodeElt *)workSpace; + nodeElt *const huffNode = huffNode0 + 1; + U32 n, nonNullRank; + int lowS, lowN; + U16 nodeNb = STARTNODE; + U32 nodeRoot; + + /* safety checks */ + if (wkspSize < sizeof(huffNodeTable)) + return ERROR(GENERIC); /* workSpace is not large enough */ + if (maxNbBits == 0) + maxNbBits = HUF_TABLELOG_DEFAULT; + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(GENERIC); + memset(huffNode0, 0, sizeof(huffNodeTable)); + + /* sort, decreasing order */ + HUF_sort(huffNode, count, maxSymbolValue); + + /* init for parents */ + nonNullRank = maxSymbolValue; + while (huffNode[nonNullRank].count == 0) + nonNullRank--; + lowS = nonNullRank; + nodeRoot = nodeNb + lowS - 1; + lowN = nodeNb; + huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS - 1].count; + huffNode[lowS].parent = huffNode[lowS - 1].parent = nodeNb; + nodeNb++; + lowS -= 2; + for (n = nodeNb; n <= nodeRoot; n++) + huffNode[n].count = (U32)(1U << 30); + huffNode0[0].count = (U32)(1U << 31); /* fake entry, strong barrier */ + + /* create parents */ + while (nodeNb <= nodeRoot) { + U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count; + huffNode[n1].parent = huffNode[n2].parent = nodeNb; + nodeNb++; + } + + /* distribute weights (unlimited tree height) */ + huffNode[nodeRoot].nbBits = 0; + for (n = nodeRoot - 1; n >= STARTNODE; n--) + huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1; + for (n = 0; n <= nonNullRank; n++) + huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1; + + /* enforce maxTableLog */ + maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits); + + /* fill result into tree (val, nbBits) */ + { + U16 nbPerRank[HUF_TABLELOG_MAX + 1] = {0}; + U16 valPerRank[HUF_TABLELOG_MAX + 1] = {0}; + if (maxNbBits > HUF_TABLELOG_MAX) + return ERROR(GENERIC); /* check fit into table */ + for (n = 0; n <= nonNullRank; n++) + nbPerRank[huffNode[n].nbBits]++; + /* determine stating value per rank */ + { + U16 min = 0; + for (n = maxNbBits; n > 0; n--) { + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } + } + for (n = 0; n <= maxSymbolValue; n++) + tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */ + for (n = 0; n <= maxSymbolValue; n++) + tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */ + } + + return maxNbBits; +} + +static size_t HUF_estimateCompressedSize(HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue) +{ + size_t nbBits = 0; + int s; + for (s = 0; s <= (int)maxSymbolValue; ++s) { + nbBits += CTable[s].nbBits * count[s]; + } + return nbBits >> 3; +} + +static int HUF_validateCTable(const HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue) +{ + int bad = 0; + int s; + for (s = 0; s <= (int)maxSymbolValue; ++s) { + bad |= (count[s] != 0) & (CTable[s].nbBits == 0); + } + return !bad; +} + +static void HUF_encodeSymbol(BIT_CStream_t *bitCPtr, U32 symbol, const HUF_CElt *CTable) +{ + BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits); +} + +size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); } + +#define HUF_FLUSHBITS(s) BIT_flushBits(s) + +#define HUF_FLUSHBITS_1(stream) \ + if (sizeof((stream)->bitContainer) * 8 < HUF_TABLELOG_MAX * 2 + 7) \ + HUF_FLUSHBITS(stream) + +#define HUF_FLUSHBITS_2(stream) \ + if (sizeof((stream)->bitContainer) * 8 < HUF_TABLELOG_MAX * 4 + 7) \ + HUF_FLUSHBITS(stream) + +size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable) +{ + const BYTE *ip = (const BYTE *)src; + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstSize; + BYTE *op = ostart; + size_t n; + BIT_CStream_t bitC; + + /* init */ + if (dstSize < 8) + return 0; /* not enough space to compress */ + { + size_t const initErr = BIT_initCStream(&bitC, op, oend - op); + if (HUF_isError(initErr)) + return 0; + } + + n = srcSize & ~3; /* join to mod 4 */ + switch (srcSize & 3) { + case 3: HUF_encodeSymbol(&bitC, ip[n + 2], CTable); HUF_FLUSHBITS_2(&bitC); + case 2: HUF_encodeSymbol(&bitC, ip[n + 1], CTable); HUF_FLUSHBITS_1(&bitC); + case 1: HUF_encodeSymbol(&bitC, ip[n + 0], CTable); HUF_FLUSHBITS(&bitC); + case 0: + default:; + } + + for (; n > 0; n -= 4) { /* note : n&3==0 at this stage */ + HUF_encodeSymbol(&bitC, ip[n - 1], CTable); + HUF_FLUSHBITS_1(&bitC); + HUF_encodeSymbol(&bitC, ip[n - 2], CTable); + HUF_FLUSHBITS_2(&bitC); + HUF_encodeSymbol(&bitC, ip[n - 3], CTable); + HUF_FLUSHBITS_1(&bitC); + HUF_encodeSymbol(&bitC, ip[n - 4], CTable); + HUF_FLUSHBITS(&bitC); + } + + return BIT_closeCStream(&bitC); +} + +size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable) +{ + size_t const segmentSize = (srcSize + 3) / 4; /* first 3 segments */ + const BYTE *ip = (const BYTE *)src; + const BYTE *const iend = ip + srcSize; + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstSize; + BYTE *op = ostart; + + if (dstSize < 6 + 1 + 1 + 1 + 8) + return 0; /* minimum space to compress successfully */ + if (srcSize < 12) + return 0; /* no saving possible : too small input */ + op += 6; /* jumpTable */ + + { + CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable)); + if (cSize == 0) + return 0; + ZSTD_writeLE16(ostart, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + { + CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable)); + if (cSize == 0) + return 0; + ZSTD_writeLE16(ostart + 2, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + { + CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable)); + if (cSize == 0) + return 0; + ZSTD_writeLE16(ostart + 4, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + { + CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, iend - ip, CTable)); + if (cSize == 0) + return 0; + op += cSize; + } + + return op - ostart; +} + +static size_t HUF_compressCTable_internal(BYTE *const ostart, BYTE *op, BYTE *const oend, const void *src, size_t srcSize, unsigned singleStream, + const HUF_CElt *CTable) +{ + size_t const cSize = + singleStream ? HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) : HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable); + if (HUF_isError(cSize)) { + return cSize; + } + if (cSize == 0) { + return 0; + } /* uncompressible */ + op += cSize; + /* check compressibility */ + if ((size_t)(op - ostart) >= srcSize - 1) { + return 0; + } + return op - ostart; +} + +/* `workSpace` must a table of at least 1024 unsigned */ +static size_t HUF_compress_internal(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, + unsigned singleStream, void *workSpace, size_t wkspSize, HUF_CElt *oldHufTable, HUF_repeat *repeat, int preferRepeat) +{ + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstSize; + BYTE *op = ostart; + + U32 *count; + size_t const countSize = sizeof(U32) * (HUF_SYMBOLVALUE_MAX + 1); + HUF_CElt *CTable; + size_t const CTableSize = sizeof(HUF_CElt) * (HUF_SYMBOLVALUE_MAX + 1); + + /* checks & inits */ + if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) + return ERROR(GENERIC); + if (!srcSize) + return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */ + if (!dstSize) + return 0; /* cannot fit within dst budget */ + if (srcSize > HUF_BLOCKSIZE_MAX) + return ERROR(srcSize_wrong); /* curr block size limit */ + if (huffLog > HUF_TABLELOG_MAX) + return ERROR(tableLog_tooLarge); + if (!maxSymbolValue) + maxSymbolValue = HUF_SYMBOLVALUE_MAX; + if (!huffLog) + huffLog = HUF_TABLELOG_DEFAULT; + + count = (U32 *)workSpace; + workSpace = (BYTE *)workSpace + countSize; + wkspSize -= countSize; + CTable = (HUF_CElt *)workSpace; + workSpace = (BYTE *)workSpace + CTableSize; + wkspSize -= CTableSize; + + /* Heuristic : If we don't need to check the validity of the old table use the old table for small inputs */ + if (preferRepeat && repeat && *repeat == HUF_repeat_valid) { + return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable); + } + + /* Scan input and build symbol stats */ + { + CHECK_V_F(largest, FSE_count_wksp(count, &maxSymbolValue, (const BYTE *)src, srcSize, (U32 *)workSpace)); + if (largest == srcSize) { + *ostart = ((const BYTE *)src)[0]; + return 1; + } /* single symbol, rle */ + if (largest <= (srcSize >> 7) + 1) + return 0; /* Fast heuristic : not compressible enough */ + } + + /* Check validity of previous table */ + if (repeat && *repeat == HUF_repeat_check && !HUF_validateCTable(oldHufTable, count, maxSymbolValue)) { + *repeat = HUF_repeat_none; + } + /* Heuristic : use existing table for small inputs */ + if (preferRepeat && repeat && *repeat != HUF_repeat_none) { + return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable); + } + + /* Build Huffman Tree */ + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue); + { + CHECK_V_F(maxBits, HUF_buildCTable_wksp(CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize)); + huffLog = (U32)maxBits; + /* Zero the unused symbols so we can check it for validity */ + memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt)); + } + + /* Write table description header */ + { + CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, CTable, maxSymbolValue, huffLog, workSpace, wkspSize)); + /* Check if using the previous table will be beneficial */ + if (repeat && *repeat != HUF_repeat_none) { + size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue); + size_t const newSize = HUF_estimateCompressedSize(CTable, count, maxSymbolValue); + if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) { + return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable); + } + } + /* Use the new table */ + if (hSize + 12ul >= srcSize) { + return 0; + } + op += hSize; + if (repeat) { + *repeat = HUF_repeat_none; + } + if (oldHufTable) { + memcpy(oldHufTable, CTable, CTableSize); + } /* Save the new table */ + } + return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, CTable); +} + +size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace, + size_t wkspSize) +{ + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, NULL, NULL, 0); +} + +size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace, + size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int preferRepeat) +{ + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat, + preferRepeat); +} + +size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace, + size_t wkspSize) +{ + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, NULL, NULL, 0); +} + +size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace, + size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int preferRepeat) +{ + return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat, + preferRepeat); +} diff --git a/lib/zstd/huf_decompress.c b/lib/zstd/huf_decompress.c new file mode 100644 index 0000000000000000000000000000000000000000..6526482047dce9b829f48ba71e1956cb62742857 --- /dev/null +++ b/lib/zstd/huf_decompress.c @@ -0,0 +1,960 @@ +/* + * Huffman decoder, part of New Generation Entropy library + * Copyright (C) 2013-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + */ + +/* ************************************************************** +* Compiler specifics +****************************************************************/ +#define FORCE_INLINE static __always_inline + +/* ************************************************************** +* Dependencies +****************************************************************/ +#include "bitstream.h" /* BIT_* */ +#include "fse.h" /* header compression */ +#include "huf.h" +#include +#include +#include /* memcpy, memset */ + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_STATIC_ASSERT(c) \ + { \ + enum { HUF_static_assert = 1 / (int)(!!(c)) }; \ + } /* use only *after* variable declarations */ + +/*-***************************/ +/* generic DTableDesc */ +/*-***************************/ + +typedef struct { + BYTE maxTableLog; + BYTE tableType; + BYTE tableLog; + BYTE reserved; +} DTableDesc; + +static DTableDesc HUF_getDTableDesc(const HUF_DTable *table) +{ + DTableDesc dtd; + memcpy(&dtd, table, sizeof(dtd)); + return dtd; +} + +/*-***************************/ +/* single-symbol decoding */ +/*-***************************/ + +typedef struct { + BYTE byte; + BYTE nbBits; +} HUF_DEltX2; /* single-symbol decoding */ + +size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t iSize; + void *const dtPtr = DTable + 1; + HUF_DEltX2 *const dt = (HUF_DEltX2 *)dtPtr; + + U32 *rankVal; + BYTE *huffWeight; + size_t spaceUsed32 = 0; + + rankVal = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; + huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); + /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); + if (HUF_isError(iSize)) + return iSize; + + /* Table header */ + { + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (tableLog > (U32)(dtd.maxTableLog + 1)) + return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ + dtd.tableType = 0; + dtd.tableLog = (BYTE)tableLog; + memcpy(DTable, &dtd, sizeof(dtd)); + } + + /* Calculate starting value for each rank */ + { + U32 n, nextRankStart = 0; + for (n = 1; n < tableLog + 1; n++) { + U32 const curr = nextRankStart; + nextRankStart += (rankVal[n] << (n - 1)); + rankVal[n] = curr; + } + } + + /* fill DTable */ + { + U32 n; + for (n = 0; n < nbSymbols; n++) { + U32 const w = huffWeight[n]; + U32 const length = (1 << w) >> 1; + U32 u; + HUF_DEltX2 D; + D.byte = (BYTE)n; + D.nbBits = (BYTE)(tableLog + 1 - w); + for (u = rankVal[w]; u < rankVal[w] + length; u++) + dt[u] = D; + rankVal[w] += length; + } + } + + return iSize; +} + +static BYTE HUF_decodeSymbolX2(BIT_DStream_t *Dstream, const HUF_DEltX2 *dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + BYTE const c = dt[val].byte; + BIT_skipBits(Dstream, dt[val].nbBits); + return c; +} + +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \ + HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) + +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + if (ZSTD_64bits()) \ + HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) + +FORCE_INLINE size_t HUF_decodeStreamX2(BYTE *p, BIT_DStream_t *const bitDPtr, BYTE *const pEnd, const HUF_DEltX2 *const dt, const U32 dtLog) +{ + BYTE *const pStart = p; + + /* up to 4 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd - 4)) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + + /* closer to the end */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + /* no more data to retrieve from bitstream, hence no need to reload */ + while (p < pEnd) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + return pEnd - pStart; +} + +static size_t HUF_decompress1X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + BYTE *op = (BYTE *)dst; + BYTE *const oend = op + dstSize; + const void *dtPtr = DTable + 1; + const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr; + BIT_DStream_t bitD; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + { + size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); + if (HUF_isError(errorCode)) + return errorCode; + } + + HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog); + + /* check */ + if (!BIT_endOfDStream(&bitD)) + return ERROR(corruption_detected); + + return dstSize; +} + +size_t HUF_decompress1X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 0) + return ERROR(GENERIC); + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) + return ERROR(srcSize_wrong); + ip += hSize; + cSrcSize -= hSize; + + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx); +} + +static size_t HUF_decompress4X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + /* Check */ + if (cSrcSize < 10) + return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + + { + const BYTE *const istart = (const BYTE *)cSrc; + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstSize; + const void *const dtPtr = DTable + 1; + const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = ZSTD_readLE16(istart); + size_t const length2 = ZSTD_readLE16(istart + 2); + size_t const length3 = ZSTD_readLE16(istart + 4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE *const istart1 = istart + 6; /* jumpTable */ + const BYTE *const istart2 = istart1 + length1; + const BYTE *const istart3 = istart2 + length2; + const BYTE *const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize + 3) / 4; + BYTE *const opStart2 = ostart + segmentSize; + BYTE *const opStart3 = opStart2 + segmentSize; + BYTE *const opStart4 = opStart3 + segmentSize; + BYTE *op1 = ostart; + BYTE *op2 = opStart2; + BYTE *op3 = opStart3; + BYTE *op4 = opStart4; + U32 endSignal; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) + return ERROR(corruption_detected); /* overflow */ + { + size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1); + if (HUF_isError(errorCode)) + return errorCode; + } + { + size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2); + if (HUF_isError(errorCode)) + return errorCode; + } + { + size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3); + if (HUF_isError(errorCode)) + return errorCode; + } + { + size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4); + if (HUF_isError(errorCode)) + return errorCode; + } + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + for (; (endSignal == BIT_DStream_unfinished) && (op4 < (oend - 7));) { + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + } + + /* check corruption */ + if (op1 > opStart2) + return ERROR(corruption_detected); + if (op2 > opStart3) + return ERROR(corruption_detected); + if (op3 > opStart4) + return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); + + /* check */ + endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endSignal) + return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; + } +} + +size_t HUF_decompress4X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 0) + return ERROR(GENERIC); + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + + size_t const hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) + return ERROR(srcSize_wrong); + ip += hSize; + cSrcSize -= hSize; + + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx); +} + +/* *************************/ +/* double-symbols decoding */ +/* *************************/ +typedef struct { + U16 sequence; + BYTE nbBits; + BYTE length; +} HUF_DEltX4; /* double-symbols decoding */ + +typedef struct { + BYTE symbol; + BYTE weight; +} sortedSymbol_t; + +/* HUF_fillDTableX4Level2() : + * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ +static void HUF_fillDTableX4Level2(HUF_DEltX4 *DTable, U32 sizeLog, const U32 consumed, const U32 *rankValOrigin, const int minWeight, + const sortedSymbol_t *sortedSymbols, const U32 sortedListSize, U32 nbBitsBaseline, U16 baseSeq) +{ + HUF_DEltX4 DElt; + U32 rankVal[HUF_TABLELOG_MAX + 1]; + + /* get pre-calculated rankVal */ + memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + + /* fill skipped values */ + if (minWeight > 1) { + U32 i, skipSize = rankVal[minWeight]; + ZSTD_writeLE16(&(DElt.sequence), baseSeq); + DElt.nbBits = (BYTE)(consumed); + DElt.length = 1; + for (i = 0; i < skipSize; i++) + DTable[i] = DElt; + } + + /* fill DTable */ + { + U32 s; + for (s = 0; s < sortedListSize; s++) { /* note : sortedSymbols already skipped */ + const U32 symbol = sortedSymbols[s].symbol; + const U32 weight = sortedSymbols[s].weight; + const U32 nbBits = nbBitsBaseline - weight; + const U32 length = 1 << (sizeLog - nbBits); + const U32 start = rankVal[weight]; + U32 i = start; + const U32 end = start + length; + + ZSTD_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8))); + DElt.nbBits = (BYTE)(nbBits + consumed); + DElt.length = 2; + do { + DTable[i++] = DElt; + } while (i < end); /* since length >= 1 */ + + rankVal[weight] += length; + } + } +} + +typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1]; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; + +static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 sortedListSize, const U32 *rankStart, + rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline) +{ + U32 rankVal[HUF_TABLELOG_MAX + 1]; + const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ + const U32 minBits = nbBitsBaseline - maxWeight; + U32 s; + + memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + + /* fill DTable */ + for (s = 0; s < sortedListSize; s++) { + const U16 symbol = sortedList[s].symbol; + const U32 weight = sortedList[s].weight; + const U32 nbBits = nbBitsBaseline - weight; + const U32 start = rankVal[weight]; + const U32 length = 1 << (targetLog - nbBits); + + if (targetLog - nbBits >= minBits) { /* enough room for a second symbol */ + U32 sortedRank; + int minWeight = nbBits + scaleLog; + if (minWeight < 1) + minWeight = 1; + sortedRank = rankStart[minWeight]; + HUF_fillDTableX4Level2(DTable + start, targetLog - nbBits, nbBits, rankValOrigin[nbBits], minWeight, sortedList + sortedRank, + sortedListSize - sortedRank, nbBitsBaseline, symbol); + } else { + HUF_DEltX4 DElt; + ZSTD_writeLE16(&(DElt.sequence), symbol); + DElt.nbBits = (BYTE)(nbBits); + DElt.length = 1; + { + U32 const end = start + length; + U32 u; + for (u = start; u < end; u++) + DTable[u] = DElt; + } + } + rankVal[weight] += length; + } +} + +size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ + U32 tableLog, maxW, sizeOfSort, nbSymbols; + DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog; + size_t iSize; + void *dtPtr = DTable + 1; /* force compiler to avoid strict-aliasing */ + HUF_DEltX4 *const dt = (HUF_DEltX4 *)dtPtr; + U32 *rankStart; + + rankValCol_t *rankVal; + U32 *rankStats; + U32 *rankStart0; + sortedSymbol_t *sortedSymbol; + BYTE *weightList; + size_t spaceUsed32 = 0; + + HUF_STATIC_ASSERT((sizeof(rankValCol_t) & 3) == 0); + + rankVal = (rankValCol_t *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2; + rankStats = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 1; + rankStart0 = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 2; + sortedSymbol = (sortedSymbol_t *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; + weightList = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + rankStart = rankStart0 + 1; + memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); + + HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ + if (maxTableLog > HUF_TABLELOG_MAX) + return ERROR(tableLog_tooLarge); + /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); + if (HUF_isError(iSize)) + return iSize; + + /* check result */ + if (tableLog > maxTableLog) + return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + + /* find maxWeight */ + for (maxW = tableLog; rankStats[maxW] == 0; maxW--) { + } /* necessarily finds a solution before 0 */ + + /* Get start index of each weight */ + { + U32 w, nextRankStart = 0; + for (w = 1; w < maxW + 1; w++) { + U32 curr = nextRankStart; + nextRankStart += rankStats[w]; + rankStart[w] = curr; + } + rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ + sizeOfSort = nextRankStart; + } + + /* sort symbols by weight */ + { + U32 s; + for (s = 0; s < nbSymbols; s++) { + U32 const w = weightList[s]; + U32 const r = rankStart[w]++; + sortedSymbol[r].symbol = (BYTE)s; + sortedSymbol[r].weight = (BYTE)w; + } + rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */ + } + + /* Build rankVal */ + { + U32 *const rankVal0 = rankVal[0]; + { + int const rescale = (maxTableLog - tableLog) - 1; /* tableLog <= maxTableLog */ + U32 nextRankVal = 0; + U32 w; + for (w = 1; w < maxW + 1; w++) { + U32 curr = nextRankVal; + nextRankVal += rankStats[w] << (w + rescale); + rankVal0[w] = curr; + } + } + { + U32 const minBits = tableLog + 1 - maxW; + U32 consumed; + for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) { + U32 *const rankValPtr = rankVal[consumed]; + U32 w; + for (w = 1; w < maxW + 1; w++) { + rankValPtr[w] = rankVal0[w] >> consumed; + } + } + } + } + + HUF_fillDTableX4(dt, maxTableLog, sortedSymbol, sizeOfSort, rankStart0, rankVal, maxW, tableLog + 1); + + dtd.tableLog = (BYTE)maxTableLog; + dtd.tableType = 1; + memcpy(DTable, &dtd, sizeof(dtd)); + return iSize; +} + +static U32 HUF_decodeSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + memcpy(op, dt + val, 2); + BIT_skipBits(DStream, dt[val].nbBits); + return dt[val].length; +} + +static U32 HUF_decodeLastSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + memcpy(op, dt + val, 1); + if (dt[val].length == 1) + BIT_skipBits(DStream, dt[val].nbBits); + else { + if (DStream->bitsConsumed < (sizeof(DStream->bitContainer) * 8)) { + BIT_skipBits(DStream, dt[val].nbBits); + if (DStream->bitsConsumed > (sizeof(DStream->bitContainer) * 8)) + /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ + DStream->bitsConsumed = (sizeof(DStream->bitContainer) * 8); + } + } + return 1; +} + +#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \ + if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \ + ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \ + if (ZSTD_64bits()) \ + ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) + +FORCE_INLINE size_t HUF_decodeStreamX4(BYTE *p, BIT_DStream_t *bitDPtr, BYTE *const pEnd, const HUF_DEltX4 *const dt, const U32 dtLog) +{ + BYTE *const pStart = p; + + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd - (sizeof(bitDPtr->bitContainer) - 1))) { + HUF_DECODE_SYMBOLX4_2(p, bitDPtr); + HUF_DECODE_SYMBOLX4_1(p, bitDPtr); + HUF_DECODE_SYMBOLX4_2(p, bitDPtr); + HUF_DECODE_SYMBOLX4_0(p, bitDPtr); + } + + /* closer to end : up to 2 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd - 2)) + HUF_DECODE_SYMBOLX4_0(p, bitDPtr); + + while (p <= pEnd - 2) + HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + + if (p < pEnd) + p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog); + + return p - pStart; +} + +static size_t HUF_decompress1X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + BIT_DStream_t bitD; + + /* Init */ + { + size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); + if (HUF_isError(errorCode)) + return errorCode; + } + + /* decode */ + { + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstSize; + const void *const dtPtr = DTable + 1; /* force compiler to not use strict-aliasing */ + const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog); + } + + /* check */ + if (!BIT_endOfDStream(&bitD)) + return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; +} + +size_t HUF_decompress1X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 1) + return ERROR(GENERIC); + return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + +size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + + size_t const hSize = HUF_readDTableX4_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) + return ERROR(srcSize_wrong); + ip += hSize; + cSrcSize -= hSize; + + return HUF_decompress1X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx); +} + +static size_t HUF_decompress4X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + if (cSrcSize < 10) + return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + + { + const BYTE *const istart = (const BYTE *)cSrc; + BYTE *const ostart = (BYTE *)dst; + BYTE *const oend = ostart + dstSize; + const void *const dtPtr = DTable + 1; + const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = ZSTD_readLE16(istart); + size_t const length2 = ZSTD_readLE16(istart + 2); + size_t const length3 = ZSTD_readLE16(istart + 4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE *const istart1 = istart + 6; /* jumpTable */ + const BYTE *const istart2 = istart1 + length1; + const BYTE *const istart3 = istart2 + length2; + const BYTE *const istart4 = istart3 + length3; + size_t const segmentSize = (dstSize + 3) / 4; + BYTE *const opStart2 = ostart + segmentSize; + BYTE *const opStart3 = opStart2 + segmentSize; + BYTE *const opStart4 = opStart3 + segmentSize; + BYTE *op1 = ostart; + BYTE *op2 = opStart2; + BYTE *op3 = opStart3; + BYTE *op4 = opStart4; + U32 endSignal; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) + return ERROR(corruption_detected); /* overflow */ + { + size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1); + if (HUF_isError(errorCode)) + return errorCode; + } + { + size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2); + if (HUF_isError(errorCode)) + return errorCode; + } + { + size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3); + if (HUF_isError(errorCode)) + return errorCode; + } + { + size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4); + if (HUF_isError(errorCode)) + return errorCode; + } + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + for (; (endSignal == BIT_DStream_unfinished) & (op4 < (oend - (sizeof(bitD4.bitContainer) - 1)));) { + HUF_DECODE_SYMBOLX4_2(op1, &bitD1); + HUF_DECODE_SYMBOLX4_2(op2, &bitD2); + HUF_DECODE_SYMBOLX4_2(op3, &bitD3); + HUF_DECODE_SYMBOLX4_2(op4, &bitD4); + HUF_DECODE_SYMBOLX4_1(op1, &bitD1); + HUF_DECODE_SYMBOLX4_1(op2, &bitD2); + HUF_DECODE_SYMBOLX4_1(op3, &bitD3); + HUF_DECODE_SYMBOLX4_1(op4, &bitD4); + HUF_DECODE_SYMBOLX4_2(op1, &bitD1); + HUF_DECODE_SYMBOLX4_2(op2, &bitD2); + HUF_DECODE_SYMBOLX4_2(op3, &bitD3); + HUF_DECODE_SYMBOLX4_2(op4, &bitD4); + HUF_DECODE_SYMBOLX4_0(op1, &bitD1); + HUF_DECODE_SYMBOLX4_0(op2, &bitD2); + HUF_DECODE_SYMBOLX4_0(op3, &bitD3); + HUF_DECODE_SYMBOLX4_0(op4, &bitD4); + + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + } + + /* check corruption */ + if (op1 > opStart2) + return ERROR(corruption_detected); + if (op2 > opStart3) + return ERROR(corruption_detected); + if (op3 > opStart4) + return ERROR(corruption_detected); + /* note : op4 already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { + U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) + return ERROR(corruption_detected); + } + + /* decoded size */ + return dstSize; + } +} + +size_t HUF_decompress4X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 1) + return ERROR(GENERIC); + return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + +size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + + size_t hSize = HUF_readDTableX4_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) + return ERROR(srcSize_wrong); + ip += hSize; + cSrcSize -= hSize; + + return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx); +} + +/* ********************************/ +/* Generic decompression selector */ +/* ********************************/ + +size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); + return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) + : HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable); +} + +size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); + return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) + : HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable); +} + +typedef struct { + U32 tableTime; + U32 decode256Time; +} algo_time_t; +static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = { + /* single, double, quad */ + {{0, 0}, {1, 1}, {2, 2}}, /* Q==0 : impossible */ + {{0, 0}, {1, 1}, {2, 2}}, /* Q==1 : impossible */ + {{38, 130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */ + {{448, 128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */ + {{556, 128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */ + {{714, 128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */ + {{883, 128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */ + {{897, 128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */ + {{926, 128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */ + {{947, 128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */ + {{1107, 128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */ + {{1177, 128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */ + {{1242, 128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */ + {{1349, 128}, {2644, 106}, {5260, 106}}, /* Q ==13 : 81-87% */ + {{1455, 128}, {2422, 124}, {4174, 124}}, /* Q ==14 : 87-93% */ + {{722, 128}, {1891, 145}, {1936, 146}}, /* Q ==15 : 93-99% */ +}; + +/** HUF_selectDecoder() : +* Tells which decoder is likely to decode faster, +* based on a set of pre-determined metrics. +* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 . +* Assumption : 0 < cSrcSize < dstSize <= 128 KB */ +U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize) +{ + /* decoder timing evaluation */ + U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */ + U32 const D256 = (U32)(dstSize >> 8); + U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); + U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); + DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, for cache eviction */ + + return DTime1 < DTime0; +} + +typedef size_t (*decompressionAlgo)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); + +size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + /* validation checks */ + if (dstSize == 0) + return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) + return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { + memcpy(dst, cSrc, dstSize); + return dstSize; + } /* not compressed */ + if (cSrcSize == 1) { + memset(dst, *(const BYTE *)cSrc, dstSize); + return dstSize; + } /* RLE */ + + { + U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) + : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); + } +} + +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + /* validation checks */ + if (dstSize == 0) + return ERROR(dstSize_tooSmall); + if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) + return ERROR(corruption_detected); /* invalid */ + + { + U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) + : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); + } +} + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + /* validation checks */ + if (dstSize == 0) + return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) + return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { + memcpy(dst, cSrc, dstSize); + return dstSize; + } /* not compressed */ + if (cSrcSize == 1) { + memset(dst, *(const BYTE *)cSrc, dstSize); + return dstSize; + } /* RLE */ + + { + U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress1X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) + : HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); + } +} diff --git a/lib/zstd/mem.h b/lib/zstd/mem.h new file mode 100644 index 0000000000000000000000000000000000000000..3a0f34c8706c2907be6634585fc964cf79c56f04 --- /dev/null +++ b/lib/zstd/mem.h @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +/*-**************************************** +* Dependencies +******************************************/ +#include +#include /* memcpy */ +#include /* size_t, ptrdiff_t */ + +/*-**************************************** +* Compiler specifics +******************************************/ +#define ZSTD_STATIC static __inline __attribute__((unused)) + +/*-************************************************************** +* Basic Types +*****************************************************************/ +typedef uint8_t BYTE; +typedef uint16_t U16; +typedef int16_t S16; +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +typedef int64_t S64; +typedef ptrdiff_t iPtrDiff; +typedef uintptr_t uPtrDiff; + +/*-************************************************************** +* Memory I/O +*****************************************************************/ +ZSTD_STATIC unsigned ZSTD_32bits(void) { return sizeof(size_t) == 4; } +ZSTD_STATIC unsigned ZSTD_64bits(void) { return sizeof(size_t) == 8; } + +#if defined(__LITTLE_ENDIAN) +#define ZSTD_LITTLE_ENDIAN 1 +#else +#define ZSTD_LITTLE_ENDIAN 0 +#endif + +ZSTD_STATIC unsigned ZSTD_isLittleEndian(void) { return ZSTD_LITTLE_ENDIAN; } + +ZSTD_STATIC U16 ZSTD_read16(const void *memPtr) { return get_unaligned((const U16 *)memPtr); } + +ZSTD_STATIC U32 ZSTD_read32(const void *memPtr) { return get_unaligned((const U32 *)memPtr); } + +ZSTD_STATIC U64 ZSTD_read64(const void *memPtr) { return get_unaligned((const U64 *)memPtr); } + +ZSTD_STATIC size_t ZSTD_readST(const void *memPtr) { return get_unaligned((const size_t *)memPtr); } + +ZSTD_STATIC void ZSTD_write16(void *memPtr, U16 value) { put_unaligned(value, (U16 *)memPtr); } + +ZSTD_STATIC void ZSTD_write32(void *memPtr, U32 value) { put_unaligned(value, (U32 *)memPtr); } + +ZSTD_STATIC void ZSTD_write64(void *memPtr, U64 value) { put_unaligned(value, (U64 *)memPtr); } + +/*=== Little endian r/w ===*/ + +ZSTD_STATIC U16 ZSTD_readLE16(const void *memPtr) { return get_unaligned_le16(memPtr); } + +ZSTD_STATIC void ZSTD_writeLE16(void *memPtr, U16 val) { put_unaligned_le16(val, memPtr); } + +ZSTD_STATIC U32 ZSTD_readLE24(const void *memPtr) { return ZSTD_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16); } + +ZSTD_STATIC void ZSTD_writeLE24(void *memPtr, U32 val) +{ + ZSTD_writeLE16(memPtr, (U16)val); + ((BYTE *)memPtr)[2] = (BYTE)(val >> 16); +} + +ZSTD_STATIC U32 ZSTD_readLE32(const void *memPtr) { return get_unaligned_le32(memPtr); } + +ZSTD_STATIC void ZSTD_writeLE32(void *memPtr, U32 val32) { put_unaligned_le32(val32, memPtr); } + +ZSTD_STATIC U64 ZSTD_readLE64(const void *memPtr) { return get_unaligned_le64(memPtr); } + +ZSTD_STATIC void ZSTD_writeLE64(void *memPtr, U64 val64) { put_unaligned_le64(val64, memPtr); } + +ZSTD_STATIC size_t ZSTD_readLEST(const void *memPtr) +{ + if (ZSTD_32bits()) + return (size_t)ZSTD_readLE32(memPtr); + else + return (size_t)ZSTD_readLE64(memPtr); +} + +ZSTD_STATIC void ZSTD_writeLEST(void *memPtr, size_t val) +{ + if (ZSTD_32bits()) + ZSTD_writeLE32(memPtr, (U32)val); + else + ZSTD_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +ZSTD_STATIC U32 ZSTD_readBE32(const void *memPtr) { return get_unaligned_be32(memPtr); } + +ZSTD_STATIC void ZSTD_writeBE32(void *memPtr, U32 val32) { put_unaligned_be32(val32, memPtr); } + +ZSTD_STATIC U64 ZSTD_readBE64(const void *memPtr) { return get_unaligned_be64(memPtr); } + +ZSTD_STATIC void ZSTD_writeBE64(void *memPtr, U64 val64) { put_unaligned_be64(val64, memPtr); } + +ZSTD_STATIC size_t ZSTD_readBEST(const void *memPtr) +{ + if (ZSTD_32bits()) + return (size_t)ZSTD_readBE32(memPtr); + else + return (size_t)ZSTD_readBE64(memPtr); +} + +ZSTD_STATIC void ZSTD_writeBEST(void *memPtr, size_t val) +{ + if (ZSTD_32bits()) + ZSTD_writeBE32(memPtr, (U32)val); + else + ZSTD_writeBE64(memPtr, (U64)val); +} + +/* function safe only for comparisons */ +ZSTD_STATIC U32 ZSTD_readMINMATCH(const void *memPtr, U32 length) +{ + switch (length) { + default: + case 4: return ZSTD_read32(memPtr); + case 3: + if (ZSTD_isLittleEndian()) + return ZSTD_read32(memPtr) << 8; + else + return ZSTD_read32(memPtr) >> 8; + } +} + +#endif /* MEM_H_MODULE */ diff --git a/lib/zstd/zstd_common.c b/lib/zstd/zstd_common.c new file mode 100644 index 0000000000000000000000000000000000000000..a282624ee1553c4dddf3e3e1c44ef60594c21709 --- /dev/null +++ b/lib/zstd/zstd_common.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/*-************************************* +* Dependencies +***************************************/ +#include "error_private.h" +#include "zstd_internal.h" /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */ +#include + +/*=************************************************************** +* Custom allocator +****************************************************************/ + +#define stack_push(stack, size) \ + ({ \ + void *const ptr = ZSTD_PTR_ALIGN((stack)->ptr); \ + (stack)->ptr = (char *)ptr + (size); \ + (stack)->ptr <= (stack)->end ? ptr : NULL; \ + }) + +ZSTD_customMem ZSTD_initStack(void *workspace, size_t workspaceSize) +{ + ZSTD_customMem stackMem = {ZSTD_stackAlloc, ZSTD_stackFree, workspace}; + ZSTD_stack *stack = (ZSTD_stack *)workspace; + /* Verify preconditions */ + if (!workspace || workspaceSize < sizeof(ZSTD_stack) || workspace != ZSTD_PTR_ALIGN(workspace)) { + ZSTD_customMem error = {NULL, NULL, NULL}; + return error; + } + /* Initialize the stack */ + stack->ptr = workspace; + stack->end = (char *)workspace + workspaceSize; + stack_push(stack, sizeof(ZSTD_stack)); + return stackMem; +} + +void *ZSTD_stackAllocAll(void *opaque, size_t *size) +{ + ZSTD_stack *stack = (ZSTD_stack *)opaque; + *size = (BYTE const *)stack->end - (BYTE *)ZSTD_PTR_ALIGN(stack->ptr); + return stack_push(stack, *size); +} + +void *ZSTD_stackAlloc(void *opaque, size_t size) +{ + ZSTD_stack *stack = (ZSTD_stack *)opaque; + return stack_push(stack, size); +} +void ZSTD_stackFree(void *opaque, void *address) +{ + (void)opaque; + (void)address; +} + +void *ZSTD_malloc(size_t size, ZSTD_customMem customMem) { return customMem.customAlloc(customMem.opaque, size); } + +void ZSTD_free(void *ptr, ZSTD_customMem customMem) +{ + if (ptr != NULL) + customMem.customFree(customMem.opaque, ptr); +} diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..1a79fab9e13add613828fa9f285c705e08a23066 --- /dev/null +++ b/lib/zstd/zstd_internal.h @@ -0,0 +1,263 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +#ifndef ZSTD_CCOMMON_H_MODULE +#define ZSTD_CCOMMON_H_MODULE + +/*-******************************************************* +* Compiler specifics +*********************************************************/ +#define FORCE_INLINE static __always_inline +#define FORCE_NOINLINE static noinline + +/*-************************************* +* Dependencies +***************************************/ +#include "error_private.h" +#include "mem.h" +#include +#include +#include +#include + +/*-************************************* +* shared macros +***************************************/ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define CHECK_F(f) \ + { \ + size_t const errcod = f; \ + if (ERR_isError(errcod)) \ + return errcod; \ + } /* check and Forward error code */ +#define CHECK_E(f, e) \ + { \ + size_t const errcod = f; \ + if (ERR_isError(errcod)) \ + return ERROR(e); \ + } /* check and send Error code */ +#define ZSTD_STATIC_ASSERT(c) \ + { \ + enum { ZSTD_static_assert = 1 / (int)(!!(c)) }; \ + } + +/*-************************************* +* Common constants +***************************************/ +#define ZSTD_OPT_NUM (1 << 12) +#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */ + +#define ZSTD_REP_NUM 3 /* number of repcodes */ +#define ZSTD_REP_CHECK (ZSTD_REP_NUM) /* number of repcodes to check by the optimal parser */ +#define ZSTD_REP_MOVE (ZSTD_REP_NUM - 1) +#define ZSTD_REP_MOVE_OPT (ZSTD_REP_NUM) +static const U32 repStartValue[ZSTD_REP_NUM] = {1, 4, 8}; + +#define KB *(1 << 10) +#define MB *(1 << 20) +#define GB *(1U << 30) + +#define BIT7 128 +#define BIT6 64 +#define BIT5 32 +#define BIT4 16 +#define BIT1 2 +#define BIT0 1 + +#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 +static const size_t ZSTD_fcs_fieldSize[4] = {0, 2, 4, 8}; +static const size_t ZSTD_did_fieldSize[4] = {0, 1, 2, 4}; + +#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ +static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; +typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; + +#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */ + +#define HufLog 12 +typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e; + +#define LONGNBSEQ 0x7F00 + +#define MINMATCH 3 +#define EQUAL_READ32 4 + +#define Litbits 8 +#define MaxLit ((1 << Litbits) - 1) +#define MaxML 52 +#define MaxLL 35 +#define MaxOff 28 +#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */ +#define MLFSELog 9 +#define LLFSELog 9 +#define OffFSELog 8 + +static const U32 LL_bits[MaxLL + 1] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; +static const S16 LL_defaultNorm[MaxLL + 1] = {4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, -1, -1, -1, -1}; +#define LL_DEFAULTNORMLOG 6 /* for static allocation */ +static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG; + +static const U32 ML_bits[MaxML + 1] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; +static const S16 ML_defaultNorm[MaxML + 1] = {1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1}; +#define ML_DEFAULTNORMLOG 6 /* for static allocation */ +static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG; + +static const S16 OF_defaultNorm[MaxOff + 1] = {1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1}; +#define OF_DEFAULTNORMLOG 5 /* for static allocation */ +static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; + +/*-******************************************* +* Shared functions to include for inlining +*********************************************/ +ZSTD_STATIC void ZSTD_copy8(void *dst, const void *src) { + memcpy(dst, src, 8); +} +/*! ZSTD_wildcopy() : +* custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */ +#define WILDCOPY_OVERLENGTH 8 +ZSTD_STATIC void ZSTD_wildcopy(void *dst, const void *src, ptrdiff_t length) +{ + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + BYTE* const oend = op + length; + /* Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81388. + * Avoid the bad case where the loop only runs once by handling the + * special case separately. This doesn't trigger the bug because it + * doesn't involve pointer/integer overflow. + */ + if (length <= 8) + return ZSTD_copy8(dst, src); + do { + ZSTD_copy8(op, ip); + op += 8; + ip += 8; + } while (op < oend); +} + +/*-******************************************* +* Private interfaces +*********************************************/ +typedef struct ZSTD_stats_s ZSTD_stats_t; + +typedef struct { + U32 off; + U32 len; +} ZSTD_match_t; + +typedef struct { + U32 price; + U32 off; + U32 mlen; + U32 litlen; + U32 rep[ZSTD_REP_NUM]; +} ZSTD_optimal_t; + +typedef struct seqDef_s { + U32 offset; + U16 litLength; + U16 matchLength; +} seqDef; + +typedef struct { + seqDef *sequencesStart; + seqDef *sequences; + BYTE *litStart; + BYTE *lit; + BYTE *llCode; + BYTE *mlCode; + BYTE *ofCode; + U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */ + U32 longLengthPos; + /* opt */ + ZSTD_optimal_t *priceTable; + ZSTD_match_t *matchTable; + U32 *matchLengthFreq; + U32 *litLengthFreq; + U32 *litFreq; + U32 *offCodeFreq; + U32 matchLengthSum; + U32 matchSum; + U32 litLengthSum; + U32 litSum; + U32 offCodeSum; + U32 log2matchLengthSum; + U32 log2matchSum; + U32 log2litLengthSum; + U32 log2litSum; + U32 log2offCodeSum; + U32 factor; + U32 staticPrices; + U32 cachedPrice; + U32 cachedLitLength; + const BYTE *cachedLiterals; +} seqStore_t; + +const seqStore_t *ZSTD_getSeqStore(const ZSTD_CCtx *ctx); +void ZSTD_seqToCodes(const seqStore_t *seqStorePtr); +int ZSTD_isSkipFrame(ZSTD_DCtx *dctx); + +/*= Custom memory allocation functions */ +typedef void *(*ZSTD_allocFunction)(void *opaque, size_t size); +typedef void (*ZSTD_freeFunction)(void *opaque, void *address); +typedef struct { + ZSTD_allocFunction customAlloc; + ZSTD_freeFunction customFree; + void *opaque; +} ZSTD_customMem; + +void *ZSTD_malloc(size_t size, ZSTD_customMem customMem); +void ZSTD_free(void *ptr, ZSTD_customMem customMem); + +/*====== stack allocation ======*/ + +typedef struct { + void *ptr; + const void *end; +} ZSTD_stack; + +#define ZSTD_ALIGN(x) ALIGN(x, sizeof(size_t)) +#define ZSTD_PTR_ALIGN(p) PTR_ALIGN(p, sizeof(size_t)) + +ZSTD_customMem ZSTD_initStack(void *workspace, size_t workspaceSize); + +void *ZSTD_stackAllocAll(void *opaque, size_t *size); +void *ZSTD_stackAlloc(void *opaque, size_t size); +void ZSTD_stackFree(void *opaque, void *address); + +/*====== common function ======*/ + +ZSTD_STATIC U32 ZSTD_highbit32(U32 val) { return 31 - __builtin_clz(val); } + +/* hidden functions */ + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx *cctx); + +size_t ZSTD_freeCCtx(ZSTD_CCtx *cctx); +size_t ZSTD_freeDCtx(ZSTD_DCtx *dctx); +size_t ZSTD_freeCDict(ZSTD_CDict *cdict); +size_t ZSTD_freeDDict(ZSTD_DDict *cdict); +size_t ZSTD_freeCStream(ZSTD_CStream *zcs); +size_t ZSTD_freeDStream(ZSTD_DStream *zds); + +#endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/lib/zstd/zstd_opt.h b/lib/zstd/zstd_opt.h new file mode 100644 index 0000000000000000000000000000000000000000..55e1b4cba8088c59c4c17fb8aaf91a9dc9263819 --- /dev/null +++ b/lib/zstd/zstd_opt.h @@ -0,0 +1,1014 @@ +/** + * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/* Note : this file is intended to be included within zstd_compress.c */ + +#ifndef ZSTD_OPT_H_91842398743 +#define ZSTD_OPT_H_91842398743 + +#define ZSTD_LITFREQ_ADD 2 +#define ZSTD_FREQ_DIV 4 +#define ZSTD_MAX_PRICE (1 << 30) + +/*-************************************* +* Price functions for optimal parser +***************************************/ +FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t *ssPtr) +{ + ssPtr->log2matchLengthSum = ZSTD_highbit32(ssPtr->matchLengthSum + 1); + ssPtr->log2litLengthSum = ZSTD_highbit32(ssPtr->litLengthSum + 1); + ssPtr->log2litSum = ZSTD_highbit32(ssPtr->litSum + 1); + ssPtr->log2offCodeSum = ZSTD_highbit32(ssPtr->offCodeSum + 1); + ssPtr->factor = 1 + ((ssPtr->litSum >> 5) / ssPtr->litLengthSum) + ((ssPtr->litSum << 1) / (ssPtr->litSum + ssPtr->matchSum)); +} + +ZSTD_STATIC void ZSTD_rescaleFreqs(seqStore_t *ssPtr, const BYTE *src, size_t srcSize) +{ + unsigned u; + + ssPtr->cachedLiterals = NULL; + ssPtr->cachedPrice = ssPtr->cachedLitLength = 0; + ssPtr->staticPrices = 0; + + if (ssPtr->litLengthSum == 0) { + if (srcSize <= 1024) + ssPtr->staticPrices = 1; + + for (u = 0; u <= MaxLit; u++) + ssPtr->litFreq[u] = 0; + for (u = 0; u < srcSize; u++) + ssPtr->litFreq[src[u]]++; + + ssPtr->litSum = 0; + ssPtr->litLengthSum = MaxLL + 1; + ssPtr->matchLengthSum = MaxML + 1; + ssPtr->offCodeSum = (MaxOff + 1); + ssPtr->matchSum = (ZSTD_LITFREQ_ADD << Litbits); + + for (u = 0; u <= MaxLit; u++) { + ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u] >> ZSTD_FREQ_DIV); + ssPtr->litSum += ssPtr->litFreq[u]; + } + for (u = 0; u <= MaxLL; u++) + ssPtr->litLengthFreq[u] = 1; + for (u = 0; u <= MaxML; u++) + ssPtr->matchLengthFreq[u] = 1; + for (u = 0; u <= MaxOff; u++) + ssPtr->offCodeFreq[u] = 1; + } else { + ssPtr->matchLengthSum = 0; + ssPtr->litLengthSum = 0; + ssPtr->offCodeSum = 0; + ssPtr->matchSum = 0; + ssPtr->litSum = 0; + + for (u = 0; u <= MaxLit; u++) { + ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u] >> (ZSTD_FREQ_DIV + 1)); + ssPtr->litSum += ssPtr->litFreq[u]; + } + for (u = 0; u <= MaxLL; u++) { + ssPtr->litLengthFreq[u] = 1 + (ssPtr->litLengthFreq[u] >> (ZSTD_FREQ_DIV + 1)); + ssPtr->litLengthSum += ssPtr->litLengthFreq[u]; + } + for (u = 0; u <= MaxML; u++) { + ssPtr->matchLengthFreq[u] = 1 + (ssPtr->matchLengthFreq[u] >> ZSTD_FREQ_DIV); + ssPtr->matchLengthSum += ssPtr->matchLengthFreq[u]; + ssPtr->matchSum += ssPtr->matchLengthFreq[u] * (u + 3); + } + ssPtr->matchSum *= ZSTD_LITFREQ_ADD; + for (u = 0; u <= MaxOff; u++) { + ssPtr->offCodeFreq[u] = 1 + (ssPtr->offCodeFreq[u] >> ZSTD_FREQ_DIV); + ssPtr->offCodeSum += ssPtr->offCodeFreq[u]; + } + } + + ZSTD_setLog2Prices(ssPtr); +} + +FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t *ssPtr, U32 litLength, const BYTE *literals) +{ + U32 price, u; + + if (ssPtr->staticPrices) + return ZSTD_highbit32((U32)litLength + 1) + (litLength * 6); + + if (litLength == 0) + return ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[0] + 1); + + /* literals */ + if (ssPtr->cachedLiterals == literals) { + U32 const additional = litLength - ssPtr->cachedLitLength; + const BYTE *literals2 = ssPtr->cachedLiterals + ssPtr->cachedLitLength; + price = ssPtr->cachedPrice + additional * ssPtr->log2litSum; + for (u = 0; u < additional; u++) + price -= ZSTD_highbit32(ssPtr->litFreq[literals2[u]] + 1); + ssPtr->cachedPrice = price; + ssPtr->cachedLitLength = litLength; + } else { + price = litLength * ssPtr->log2litSum; + for (u = 0; u < litLength; u++) + price -= ZSTD_highbit32(ssPtr->litFreq[literals[u]] + 1); + + if (litLength >= 12) { + ssPtr->cachedLiterals = literals; + ssPtr->cachedPrice = price; + ssPtr->cachedLitLength = litLength; + } + } + + /* literal Length */ + { + const BYTE LL_deltaCode = 19; + const BYTE llCode = (litLength > 63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength]; + price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode] + 1); + } + + return price; +} + +FORCE_INLINE U32 ZSTD_getPrice(seqStore_t *seqStorePtr, U32 litLength, const BYTE *literals, U32 offset, U32 matchLength, const int ultra) +{ + /* offset */ + U32 price; + BYTE const offCode = (BYTE)ZSTD_highbit32(offset + 1); + + if (seqStorePtr->staticPrices) + return ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + ZSTD_highbit32((U32)matchLength + 1) + 16 + offCode; + + price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode] + 1); + if (!ultra && offCode >= 20) + price += (offCode - 19) * 2; + + /* match Length */ + { + const BYTE ML_deltaCode = 36; + const BYTE mlCode = (matchLength > 127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength]; + price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode] + 1); + } + + return price + ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + seqStorePtr->factor; +} + +ZSTD_STATIC void ZSTD_updatePrice(seqStore_t *seqStorePtr, U32 litLength, const BYTE *literals, U32 offset, U32 matchLength) +{ + U32 u; + + /* literals */ + seqStorePtr->litSum += litLength * ZSTD_LITFREQ_ADD; + for (u = 0; u < litLength; u++) + seqStorePtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD; + + /* literal Length */ + { + const BYTE LL_deltaCode = 19; + const BYTE llCode = (litLength > 63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength]; + seqStorePtr->litLengthFreq[llCode]++; + seqStorePtr->litLengthSum++; + } + + /* match offset */ + { + BYTE const offCode = (BYTE)ZSTD_highbit32(offset + 1); + seqStorePtr->offCodeSum++; + seqStorePtr->offCodeFreq[offCode]++; + } + + /* match Length */ + { + const BYTE ML_deltaCode = 36; + const BYTE mlCode = (matchLength > 127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength]; + seqStorePtr->matchLengthFreq[mlCode]++; + seqStorePtr->matchLengthSum++; + } + + ZSTD_setLog2Prices(seqStorePtr); +} + +#define SET_PRICE(pos, mlen_, offset_, litlen_, price_) \ + { \ + while (last_pos < pos) { \ + opt[last_pos + 1].price = ZSTD_MAX_PRICE; \ + last_pos++; \ + } \ + opt[pos].mlen = mlen_; \ + opt[pos].off = offset_; \ + opt[pos].litlen = litlen_; \ + opt[pos].price = price_; \ + } + +/* Update hashTable3 up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +FORCE_INLINE +U32 ZSTD_insertAndFindFirstIndexHash3(ZSTD_CCtx *zc, const BYTE *ip) +{ + U32 *const hashTable3 = zc->hashTable3; + U32 const hashLog3 = zc->hashLog3; + const BYTE *const base = zc->base; + U32 idx = zc->nextToUpdate3; + const U32 target = zc->nextToUpdate3 = (U32)(ip - base); + const size_t hash3 = ZSTD_hash3Ptr(ip, hashLog3); + + while (idx < target) { + hashTable3[ZSTD_hash3Ptr(base + idx, hashLog3)] = idx; + idx++; + } + + return hashTable3[hash3]; +} + +/*-************************************* +* Binary Tree search +***************************************/ +static U32 ZSTD_insertBtAndGetAllMatches(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, U32 nbCompares, const U32 mls, U32 extDict, + ZSTD_match_t *matches, const U32 minMatchLen) +{ + const BYTE *const base = zc->base; + const U32 curr = (U32)(ip - base); + const U32 hashLog = zc->params.cParams.hashLog; + const size_t h = ZSTD_hashPtr(ip, hashLog, mls); + U32 *const hashTable = zc->hashTable; + U32 matchIndex = hashTable[h]; + U32 *const bt = zc->chainTable; + const U32 btLog = zc->params.cParams.chainLog - 1; + const U32 btMask = (1U << btLog) - 1; + size_t commonLengthSmaller = 0, commonLengthLarger = 0; + const BYTE *const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE *const dictEnd = dictBase + dictLimit; + const BYTE *const prefixStart = base + dictLimit; + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + const U32 windowLow = zc->lowLimit; + U32 *smallerPtr = bt + 2 * (curr & btMask); + U32 *largerPtr = bt + 2 * (curr & btMask) + 1; + U32 matchEndIdx = curr + 8; + U32 dummy32; /* to be nullified at the end */ + U32 mnum = 0; + + const U32 minMatch = (mls == 3) ? 3 : 4; + size_t bestLength = minMatchLen - 1; + + if (minMatch == 3) { /* HC3 match finder */ + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(zc, ip); + if (matchIndex3 > windowLow && (curr - matchIndex3 < (1 << 18))) { + const BYTE *match; + size_t currMl = 0; + if ((!extDict) || matchIndex3 >= dictLimit) { + match = base + matchIndex3; + if (match[bestLength] == ip[bestLength]) + currMl = ZSTD_count(ip, match, iLimit); + } else { + match = dictBase + matchIndex3; + if (ZSTD_readMINMATCH(match, MINMATCH) == + ZSTD_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ + currMl = ZSTD_count_2segments(ip + MINMATCH, match + MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; + } + + /* save best solution */ + if (currMl > bestLength) { + bestLength = currMl; + matches[mnum].off = ZSTD_REP_MOVE_OPT + curr - matchIndex3; + matches[mnum].len = (U32)currMl; + mnum++; + if (currMl > ZSTD_OPT_NUM) + goto update; + if (ip + currMl == iLimit) + goto update; /* best possible, and avoid read overflow*/ + } + } + } + + hashTable[h] = curr; /* Update Hash Table */ + + while (nbCompares-- && (matchIndex > windowLow)) { + U32 *nextPtr = bt + 2 * (matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE *match; + + if ((!extDict) || (matchIndex + matchLength >= dictLimit)) { + match = base + matchIndex; + if (match[matchLength] == ip[matchLength]) { + matchLength += ZSTD_count(ip + matchLength + 1, match + matchLength + 1, iLimit) + 1; + } + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip + matchLength, match + matchLength, iLimit, dictEnd, prefixStart); + if (matchIndex + matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = ZSTD_REP_MOVE_OPT + curr - matchIndex; + matches[mnum].len = (U32)matchLength; + mnum++; + if (matchLength > ZSTD_OPT_NUM) + break; + if (ip + matchLength == iLimit) /* equal : no way to know if inf or sup */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + + if (match[matchLength] < ip[matchLength]) { + /* match is smaller than curr */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { + smallerPtr = &dummy32; + break; + } /* beyond tree size, stop the search */ + smallerPtr = nextPtr + 1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to curr) */ + } else { + /* match is larger than curr */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { + largerPtr = &dummy32; + break; + } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } + } + + *smallerPtr = *largerPtr = 0; + +update: + zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr + 1; + return mnum; +} + +/** Tree updater, providing best match */ +static U32 ZSTD_BtGetAllMatches(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, const U32 maxNbAttempts, const U32 mls, ZSTD_match_t *matches, + const U32 minMatchLen) +{ + if (ip < zc->base + zc->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls); + return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches, minMatchLen); +} + +static U32 ZSTD_BtGetAllMatches_selectMLS(ZSTD_CCtx *zc, /* Index table will be updated */ + const BYTE *ip, const BYTE *const iHighLimit, const U32 maxNbAttempts, const U32 matchLengthSearch, + ZSTD_match_t *matches, const U32 minMatchLen) +{ + switch (matchLengthSearch) { + case 3: return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen); + default: + case 4: return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen); + case 5: return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen); + case 7: + case 6: return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen); + } +} + +/** Tree updater, providing best match */ +static U32 ZSTD_BtGetAllMatches_extDict(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, const U32 maxNbAttempts, const U32 mls, + ZSTD_match_t *matches, const U32 minMatchLen) +{ + if (ip < zc->base + zc->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls); + return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 1, matches, minMatchLen); +} + +static U32 ZSTD_BtGetAllMatches_selectMLS_extDict(ZSTD_CCtx *zc, /* Index table will be updated */ + const BYTE *ip, const BYTE *const iHighLimit, const U32 maxNbAttempts, const U32 matchLengthSearch, + ZSTD_match_t *matches, const U32 minMatchLen) +{ + switch (matchLengthSearch) { + case 3: return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen); + default: + case 4: return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen); + case 5: return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen); + case 7: + case 6: return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen); + } +} + +/*-******************************* +* Optimal parser +*********************************/ +FORCE_INLINE +void ZSTD_compressBlock_opt_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const int ultra) +{ + seqStore_t *seqStorePtr = &(ctx->seqStore); + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - 8; + const BYTE *const base = ctx->base; + const BYTE *const prefixStart = base + ctx->dictLimit; + + const U32 maxSearches = 1U << ctx->params.cParams.searchLog; + const U32 sufficient_len = ctx->params.cParams.targetLength; + const U32 mls = ctx->params.cParams.searchLength; + const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4; + + ZSTD_optimal_t *opt = seqStorePtr->priceTable; + ZSTD_match_t *matches = seqStorePtr->matchTable; + const BYTE *inr; + U32 offset, rep[ZSTD_REP_NUM]; + + /* init */ + ctx->nextToUpdate3 = ctx->nextToUpdate; + ZSTD_rescaleFreqs(seqStorePtr, (const BYTE *)src, srcSize); + ip += (ip == prefixStart); + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + rep[i] = ctx->rep[i]; + } + + /* Match Loop */ + while (ip < ilimit) { + U32 cur, match_num, last_pos, litlen, price; + U32 u, mlen, best_mlen, best_off, litLength; + memset(opt, 0, sizeof(ZSTD_optimal_t)); + last_pos = 0; + litlen = (U32)(ip - anchor); + + /* check repCode */ + { + U32 i, last_i = ZSTD_REP_CHECK + (ip == anchor); + for (i = (ip == anchor); i < last_i; i++) { + const S32 repCur = (i == ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : rep[i]; + if ((repCur > 0) && (repCur < (S32)(ip - prefixStart)) && + (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repCur, minMatch))) { + mlen = (U32)ZSTD_count(ip + minMatch, ip + minMatch - repCur, iend) + minMatch; + if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { + best_mlen = mlen; + best_off = i; + cur = 0; + last_pos = 1; + goto _storeSequence; + } + best_off = i - (ip == anchor); + do { + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ + mlen--; + } while (mlen >= minMatch); + } + } + } + + match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch); + + if (!last_pos && !match_num) { + ip++; + continue; + } + + if (match_num && (matches[match_num - 1].len > sufficient_len || matches[match_num - 1].len >= ZSTD_OPT_NUM)) { + best_mlen = matches[match_num - 1].len; + best_off = matches[match_num - 1].off; + cur = 0; + last_pos = 1; + goto _storeSequence; + } + + /* set prices using matches at position = 0 */ + best_mlen = (last_pos) ? last_pos : minMatch; + for (u = 0; u < match_num; u++) { + mlen = (u > 0) ? matches[u - 1].len + 1 : best_mlen; + best_mlen = matches[u].len; + while (mlen <= best_mlen) { + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off - 1, mlen - MINMATCH, ultra); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */ + mlen++; + } + } + + if (last_pos < minMatch) { + ip++; + continue; + } + + /* initialize opt[0] */ + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + opt[0].rep[i] = rep[i]; + } + opt[0].mlen = 1; + opt[0].litlen = litlen; + + /* check further positions */ + for (cur = 1; cur <= last_pos; cur++) { + inr = ip + cur; + + if (opt[cur - 1].mlen == 1) { + litlen = opt[cur - 1].litlen + 1; + if (cur > litlen) { + price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr - litlen); + } else + price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor); + } else { + litlen = 1; + price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr - 1); + } + + if (cur > last_pos || price <= opt[cur].price) + SET_PRICE(cur, 1, 0, litlen, price); + + if (cur == last_pos) + break; + + if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */ + continue; + + mlen = opt[cur].mlen; + if (opt[cur].off > ZSTD_REP_MOVE_OPT) { + opt[cur].rep[2] = opt[cur - mlen].rep[1]; + opt[cur].rep[1] = opt[cur - mlen].rep[0]; + opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT; + } else { + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur - mlen].rep[1] : opt[cur - mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur - mlen].rep[0] : opt[cur - mlen].rep[1]; + opt[cur].rep[0] = + ((opt[cur].off == ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur - mlen].rep[0] - 1) : (opt[cur - mlen].rep[opt[cur].off]); + } + + best_mlen = minMatch; + { + U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1); + for (i = (opt[cur].mlen != 1); i < last_i; i++) { /* check rep */ + const S32 repCur = (i == ZSTD_REP_MOVE_OPT) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i]; + if ((repCur > 0) && (repCur < (S32)(inr - prefixStart)) && + (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) { + mlen = (U32)ZSTD_count(inr + minMatch, inr + minMatch - repCur, iend) + minMatch; + + if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { + best_mlen = mlen; + best_off = i; + last_pos = cur + 1; + goto _storeSequence; + } + + best_off = i - (opt[cur].mlen != 1); + if (mlen > best_mlen) + best_mlen = mlen; + + do { + if (opt[cur].mlen == 1) { + litlen = opt[cur].litlen; + if (cur > litlen) { + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr - litlen, + best_off, mlen - MINMATCH, ultra); + } else + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra); + } else { + litlen = 0; + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra); + } + + if (cur + mlen > last_pos || price <= opt[cur + mlen].price) + SET_PRICE(cur + mlen, mlen, i, litlen, price); + mlen--; + } while (mlen >= minMatch); + } + } + } + + match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen); + + if (match_num > 0 && (matches[match_num - 1].len > sufficient_len || cur + matches[match_num - 1].len >= ZSTD_OPT_NUM)) { + best_mlen = matches[match_num - 1].len; + best_off = matches[match_num - 1].off; + last_pos = cur + 1; + goto _storeSequence; + } + + /* set prices using matches at position = cur */ + for (u = 0; u < match_num; u++) { + mlen = (u > 0) ? matches[u - 1].len + 1 : best_mlen; + best_mlen = matches[u].len; + + while (mlen <= best_mlen) { + if (opt[cur].mlen == 1) { + litlen = opt[cur].litlen; + if (cur > litlen) + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip + cur - litlen, + matches[u].off - 1, mlen - MINMATCH, ultra); + else + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off - 1, mlen - MINMATCH, ultra); + } else { + litlen = 0; + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off - 1, mlen - MINMATCH, ultra); + } + + if (cur + mlen > last_pos || (price < opt[cur + mlen].price)) + SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price); + + mlen++; + } + } + } + + best_mlen = opt[last_pos].mlen; + best_off = opt[last_pos].off; + cur = last_pos - best_mlen; + + /* store sequence */ +_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ + opt[0].mlen = 1; + + while (1) { + mlen = opt[cur].mlen; + offset = opt[cur].off; + opt[cur].mlen = best_mlen; + opt[cur].off = best_off; + best_mlen = mlen; + best_off = offset; + if (mlen > cur) + break; + cur -= mlen; + } + + for (u = 0; u <= last_pos;) { + u += opt[u].mlen; + } + + for (cur = 0; cur < last_pos;) { + mlen = opt[cur].mlen; + if (mlen == 1) { + ip++; + cur++; + continue; + } + offset = opt[cur].off; + cur += mlen; + litLength = (U32)(ip - anchor); + + if (offset > ZSTD_REP_MOVE_OPT) { + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE_OPT; + offset--; + } else { + if (offset != 0) { + best_off = (offset == ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]); + if (offset != 1) + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; + } + if (litLength == 0) + offset--; + } + + ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen - MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen - MINMATCH); + anchor = ip = ip + mlen; + } + } /* for (cur=0; cur < last_pos; ) */ + + /* Save reps for next block */ + { + int i; + for (i = 0; i < ZSTD_REP_NUM; i++) + ctx->repToConfirm[i] = rep[i]; + } + + /* Last Literals */ + { + size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +FORCE_INLINE +void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const int ultra) +{ + seqStore_t *seqStorePtr = &(ctx->seqStore); + const BYTE *const istart = (const BYTE *)src; + const BYTE *ip = istart; + const BYTE *anchor = istart; + const BYTE *const iend = istart + srcSize; + const BYTE *const ilimit = iend - 8; + const BYTE *const base = ctx->base; + const U32 lowestIndex = ctx->lowLimit; + const U32 dictLimit = ctx->dictLimit; + const BYTE *const prefixStart = base + dictLimit; + const BYTE *const dictBase = ctx->dictBase; + const BYTE *const dictEnd = dictBase + dictLimit; + + const U32 maxSearches = 1U << ctx->params.cParams.searchLog; + const U32 sufficient_len = ctx->params.cParams.targetLength; + const U32 mls = ctx->params.cParams.searchLength; + const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4; + + ZSTD_optimal_t *opt = seqStorePtr->priceTable; + ZSTD_match_t *matches = seqStorePtr->matchTable; + const BYTE *inr; + + /* init */ + U32 offset, rep[ZSTD_REP_NUM]; + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + rep[i] = ctx->rep[i]; + } + + ctx->nextToUpdate3 = ctx->nextToUpdate; + ZSTD_rescaleFreqs(seqStorePtr, (const BYTE *)src, srcSize); + ip += (ip == prefixStart); + + /* Match Loop */ + while (ip < ilimit) { + U32 cur, match_num, last_pos, litlen, price; + U32 u, mlen, best_mlen, best_off, litLength; + U32 curr = (U32)(ip - base); + memset(opt, 0, sizeof(ZSTD_optimal_t)); + last_pos = 0; + opt[0].litlen = (U32)(ip - anchor); + + /* check repCode */ + { + U32 i, last_i = ZSTD_REP_CHECK + (ip == anchor); + for (i = (ip == anchor); i < last_i; i++) { + const S32 repCur = (i == ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : rep[i]; + const U32 repIndex = (U32)(curr - repCur); + const BYTE *const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *const repMatch = repBase + repIndex; + if ((repCur > 0 && repCur <= (S32)curr) && + (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */ + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch))) { + /* repcode detected we should take it */ + const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend; + mlen = (U32)ZSTD_count_2segments(ip + minMatch, repMatch + minMatch, iend, repEnd, prefixStart) + minMatch; + + if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { + best_mlen = mlen; + best_off = i; + cur = 0; + last_pos = 1; + goto _storeSequence; + } + + best_off = i - (ip == anchor); + litlen = opt[0].litlen; + do { + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ + mlen--; + } while (mlen >= minMatch); + } + } + } + + match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */ + + if (!last_pos && !match_num) { + ip++; + continue; + } + + { + U32 i; + for (i = 0; i < ZSTD_REP_NUM; i++) + opt[0].rep[i] = rep[i]; + } + opt[0].mlen = 1; + + if (match_num && (matches[match_num - 1].len > sufficient_len || matches[match_num - 1].len >= ZSTD_OPT_NUM)) { + best_mlen = matches[match_num - 1].len; + best_off = matches[match_num - 1].off; + cur = 0; + last_pos = 1; + goto _storeSequence; + } + + best_mlen = (last_pos) ? last_pos : minMatch; + + /* set prices using matches at position = 0 */ + for (u = 0; u < match_num; u++) { + mlen = (u > 0) ? matches[u - 1].len + 1 : best_mlen; + best_mlen = matches[u].len; + litlen = opt[0].litlen; + while (mlen <= best_mlen) { + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off - 1, mlen - MINMATCH, ultra); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, matches[u].off, litlen, price); + mlen++; + } + } + + if (last_pos < minMatch) { + ip++; + continue; + } + + /* check further positions */ + for (cur = 1; cur <= last_pos; cur++) { + inr = ip + cur; + + if (opt[cur - 1].mlen == 1) { + litlen = opt[cur - 1].litlen + 1; + if (cur > litlen) { + price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr - litlen); + } else + price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor); + } else { + litlen = 1; + price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr - 1); + } + + if (cur > last_pos || price <= opt[cur].price) + SET_PRICE(cur, 1, 0, litlen, price); + + if (cur == last_pos) + break; + + if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */ + continue; + + mlen = opt[cur].mlen; + if (opt[cur].off > ZSTD_REP_MOVE_OPT) { + opt[cur].rep[2] = opt[cur - mlen].rep[1]; + opt[cur].rep[1] = opt[cur - mlen].rep[0]; + opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT; + } else { + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur - mlen].rep[1] : opt[cur - mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur - mlen].rep[0] : opt[cur - mlen].rep[1]; + opt[cur].rep[0] = + ((opt[cur].off == ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur - mlen].rep[0] - 1) : (opt[cur - mlen].rep[opt[cur].off]); + } + + best_mlen = minMatch; + { + U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1); + for (i = (mlen != 1); i < last_i; i++) { + const S32 repCur = (i == ZSTD_REP_MOVE_OPT) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i]; + const U32 repIndex = (U32)(curr + cur - repCur); + const BYTE *const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE *const repMatch = repBase + repIndex; + if ((repCur > 0 && repCur <= (S32)(curr + cur)) && + (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */ + && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch))) { + /* repcode detected */ + const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend; + mlen = (U32)ZSTD_count_2segments(inr + minMatch, repMatch + minMatch, iend, repEnd, prefixStart) + minMatch; + + if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { + best_mlen = mlen; + best_off = i; + last_pos = cur + 1; + goto _storeSequence; + } + + best_off = i - (opt[cur].mlen != 1); + if (mlen > best_mlen) + best_mlen = mlen; + + do { + if (opt[cur].mlen == 1) { + litlen = opt[cur].litlen; + if (cur > litlen) { + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr - litlen, + best_off, mlen - MINMATCH, ultra); + } else + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra); + } else { + litlen = 0; + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra); + } + + if (cur + mlen > last_pos || price <= opt[cur + mlen].price) + SET_PRICE(cur + mlen, mlen, i, litlen, price); + mlen--; + } while (mlen >= minMatch); + } + } + } + + match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch); + + if (match_num > 0 && (matches[match_num - 1].len > sufficient_len || cur + matches[match_num - 1].len >= ZSTD_OPT_NUM)) { + best_mlen = matches[match_num - 1].len; + best_off = matches[match_num - 1].off; + last_pos = cur + 1; + goto _storeSequence; + } + + /* set prices using matches at position = cur */ + for (u = 0; u < match_num; u++) { + mlen = (u > 0) ? matches[u - 1].len + 1 : best_mlen; + best_mlen = matches[u].len; + + while (mlen <= best_mlen) { + if (opt[cur].mlen == 1) { + litlen = opt[cur].litlen; + if (cur > litlen) + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip + cur - litlen, + matches[u].off - 1, mlen - MINMATCH, ultra); + else + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off - 1, mlen - MINMATCH, ultra); + } else { + litlen = 0; + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off - 1, mlen - MINMATCH, ultra); + } + + if (cur + mlen > last_pos || (price < opt[cur + mlen].price)) + SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price); + + mlen++; + } + } + } /* for (cur = 1; cur <= last_pos; cur++) */ + + best_mlen = opt[last_pos].mlen; + best_off = opt[last_pos].off; + cur = last_pos - best_mlen; + + /* store sequence */ +_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ + opt[0].mlen = 1; + + while (1) { + mlen = opt[cur].mlen; + offset = opt[cur].off; + opt[cur].mlen = best_mlen; + opt[cur].off = best_off; + best_mlen = mlen; + best_off = offset; + if (mlen > cur) + break; + cur -= mlen; + } + + for (u = 0; u <= last_pos;) { + u += opt[u].mlen; + } + + for (cur = 0; cur < last_pos;) { + mlen = opt[cur].mlen; + if (mlen == 1) { + ip++; + cur++; + continue; + } + offset = opt[cur].off; + cur += mlen; + litLength = (U32)(ip - anchor); + + if (offset > ZSTD_REP_MOVE_OPT) { + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE_OPT; + offset--; + } else { + if (offset != 0) { + best_off = (offset == ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]); + if (offset != 1) + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; + } + + if (litLength == 0) + offset--; + } + + ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen - MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen - MINMATCH); + anchor = ip = ip + mlen; + } + } /* for (cur=0; cur < last_pos; ) */ + + /* Save reps for next block */ + { + int i; + for (i = 0; i < ZSTD_REP_NUM; i++) + ctx->repToConfirm[i] = rep[i]; + } + + /* Last Literals */ + { + size_t lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +#endif /* ZSTD_OPT_H_91842398743 */ diff --git a/mm/Kconfig b/mm/Kconfig index 48b1af447fa749c78c74217f2a09b1b1ade0fd46..9c4bdddd80c2123ac522c7d6c08453cca6c8445f 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -262,6 +262,9 @@ config MIGRATION config ARCH_ENABLE_HUGEPAGE_MIGRATION bool +config ARCH_ENABLE_THP_MIGRATION + bool + config PHYS_ADDR_T_64BIT def_bool 64BIT || ARCH_PHYS_ADDR_T_64BIT @@ -673,11 +676,12 @@ config ARCH_HAS_ZONE_DEVICE bool config ZONE_DEVICE - bool "Device memory (pmem, etc...) hotplug support" + bool "Device memory (pmem, HMM, etc...) hotplug support" depends on MEMORY_HOTPLUG depends on MEMORY_HOTREMOVE depends on SPARSEMEM_VMEMMAP depends on ARCH_HAS_ZONE_DEVICE + select RADIX_TREE_MULTIORDER help Device memory hotplug support allows for establishing pmem, @@ -688,6 +692,55 @@ config ZONE_DEVICE If FS_DAX is enabled, then say Y. +config ARCH_HAS_HMM + bool + default y + depends on (X86_64 || PPC64) + depends on ZONE_DEVICE + depends on MMU && 64BIT + depends on MEMORY_HOTPLUG + depends on MEMORY_HOTREMOVE + depends on SPARSEMEM_VMEMMAP + +config MIGRATE_VMA_HELPER + bool + +config HMM + bool + select MIGRATE_VMA_HELPER + +config HMM_MIRROR + bool "HMM mirror CPU page table into a device page table" + depends on ARCH_HAS_HMM + select MMU_NOTIFIER + select HMM + help + Select HMM_MIRROR if you want to mirror range of the CPU page table of a + process into a device page table. Here, mirror means "keep synchronized". + Prerequisites: the device must provide the ability to write-protect its + page tables (at PAGE_SIZE granularity), and must be able to recover from + the resulting potential page faults. + +config DEVICE_PRIVATE + bool "Unaddressable device memory (GPU memory, ...)" + depends on ARCH_HAS_HMM + select HMM + + help + Allows creation of struct pages to represent unaddressable device + memory; i.e., memory that is only accessible from the device (or + group of devices). You likely also want to select HMM_MIRROR. + +config DEVICE_PUBLIC + bool "Addressable device memory (like GPU memory)" + depends on ARCH_HAS_HMM + select HMM + + help + Allows creation of struct pages to represent addressable device + memory; i.e., memory that is accessible from both the device and + the CPU + config FRAME_VECTOR bool diff --git a/mm/Makefile b/mm/Makefile index 411bd24d4a7c78dabc1f508201feb5795a8c5ad8..e3ac3aeb533badc264dac11579192acb101a693c 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -104,3 +104,4 @@ obj-$(CONFIG_FRAME_VECTOR) += frame_vector.o obj-$(CONFIG_DEBUG_PAGE_REF) += debug_page_ref.o obj-$(CONFIG_HARDENED_USERCOPY) += usercopy.o obj-$(CONFIG_PERCPU_STATS) += percpu-stats.o +obj-$(CONFIG_HMM) += hmm.o diff --git a/mm/backing-dev.c b/mm/backing-dev.c index f028a9a472fd9b2c7098bce8fe622fd58ba2f140..e19606bb41a0b5b48f6cbca8268eb529718da45c 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -569,8 +569,10 @@ static int cgwb_create(struct backing_dev_info *bdi, /* need to create a new one */ wb = kmalloc(sizeof(*wb), gfp); - if (!wb) - return -ENOMEM; + if (!wb) { + ret = -ENOMEM; + goto out_put; + } ret = wb_init(wb, bdi, blkcg_css->id, gfp); if (ret) diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c index 9075aa54e95517cdbb1094f04e72c36357401e52..68d28924ba79d66cec76535f19772de6dc429522 100644 --- a/mm/balloon_compaction.c +++ b/mm/balloon_compaction.c @@ -24,7 +24,7 @@ struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info) { unsigned long flags; struct page *page = alloc_page(balloon_mapping_gfp_mask() | - __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_ZERO); + __GFP_NOMEMALLOC | __GFP_NORETRY); if (!page) return NULL; @@ -139,6 +139,14 @@ int balloon_page_migrate(struct address_space *mapping, { struct balloon_dev_info *balloon = balloon_page_device(page); + /* + * We can not easily support the no copy case here so ignore it as it + * is unlikely to be use with ballon pages. See include/linux/hmm.h for + * user of the MIGRATE_SYNC_NO_COPY mode. + */ + if (mode == MIGRATE_SYNC_NO_COPY) + return -EINVAL; + VM_BUG_ON_PAGE(!PageLocked(page), page); VM_BUG_ON_PAGE(!PageLocked(newpage), newpage); diff --git a/mm/cma_debug.c b/mm/cma_debug.c index 595b757bef72722fb2715afd9ab0cd1536181c9e..c03ccbc405a066038619361cf995f675dc2efaa1 100644 --- a/mm/cma_debug.c +++ b/mm/cma_debug.c @@ -167,7 +167,7 @@ static void cma_debugfs_add_one(struct cma *cma, int idx) char name[16]; int u32s; - sprintf(name, "cma-%s", cma->name); + scnprintf(name, sizeof(name), "cma-%s", cma->name); tmp = debugfs_create_dir(name, cma_debugfs_root); diff --git a/mm/compaction.c b/mm/compaction.c index fb548e4c7bd4b44f426a8e45c5230508c57d36e6..03d31a87534160f23eadb0aefeb48feca89191ab 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1999,17 +1999,14 @@ void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx) if (pgdat->kcompactd_max_order < order) pgdat->kcompactd_max_order = order; - /* - * Pairs with implicit barrier in wait_event_freezable() - * such that wakeups are not missed in the lockless - * waitqueue_active() call. - */ - smp_acquire__after_ctrl_dep(); - if (pgdat->kcompactd_classzone_idx > classzone_idx) pgdat->kcompactd_classzone_idx = classzone_idx; - if (!waitqueue_active(&pgdat->kcompactd_wait)) + /* + * Pairs with implicit barrier in wait_event_freezable() + * such that wakeups are not missed. + */ + if (!wq_has_sleeper(&pgdat->kcompactd_wait)) return; if (!kcompactd_node_suitable(pgdat)) diff --git a/mm/debug.c b/mm/debug.c index db1cd26d8752022b7f8b576cdff78f5412209d39..5715448ab0b53db5d8bd4b64d47706f7deaaf7a6 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -124,9 +124,7 @@ void dump_mm(const struct mm_struct *mm) #ifdef CONFIG_NUMA_BALANCING "numa_next_scan %lu numa_scan_offset %lu numa_scan_seq %d\n" #endif -#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION) "tlb_flush_pending %d\n" -#endif "def_flags: %#lx(%pGv)\n", mm, mm->mmap, mm->vmacache_seqnum, mm->task_size, @@ -158,9 +156,7 @@ void dump_mm(const struct mm_struct *mm) #ifdef CONFIG_NUMA_BALANCING mm->numa_next_scan, mm->numa_scan_offset, mm->numa_scan_seq, #endif -#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION) - mm->tlb_flush_pending, -#endif + atomic_read(&mm->tlb_flush_pending), mm->def_flags, &mm->def_flags ); } diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c index 6d5717bd7197ba0428c32941df27d90da04264b5..b1dd4a948fc0b3afc375964d23ebcb9f69eaafa3 100644 --- a/mm/early_ioremap.c +++ b/mm/early_ioremap.c @@ -30,6 +30,13 @@ early_param("early_ioremap_debug", early_ioremap_debug_setup); static int after_paging_init __initdata; +pgprot_t __init __weak early_memremap_pgprot_adjust(resource_size_t phys_addr, + unsigned long size, + pgprot_t prot) +{ + return prot; +} + void __init __weak early_ioremap_shutdown(void) { } @@ -215,14 +222,29 @@ early_ioremap(resource_size_t phys_addr, unsigned long size) void __init * early_memremap(resource_size_t phys_addr, unsigned long size) { - return (__force void *)__early_ioremap(phys_addr, size, - FIXMAP_PAGE_NORMAL); + pgprot_t prot = early_memremap_pgprot_adjust(phys_addr, size, + FIXMAP_PAGE_NORMAL); + + return (__force void *)__early_ioremap(phys_addr, size, prot); } #ifdef FIXMAP_PAGE_RO void __init * early_memremap_ro(resource_size_t phys_addr, unsigned long size) { - return (__force void *)__early_ioremap(phys_addr, size, FIXMAP_PAGE_RO); + pgprot_t prot = early_memremap_pgprot_adjust(phys_addr, size, + FIXMAP_PAGE_RO); + + return (__force void *)__early_ioremap(phys_addr, size, prot); +} +#endif + +#ifdef CONFIG_ARCH_USE_MEMREMAP_PROT +void __init * +early_memremap_prot(resource_size_t phys_addr, unsigned long size, + unsigned long prot_val) +{ + return (__force void *)__early_ioremap(phys_addr, size, + __pgprot(prot_val)); } #endif diff --git a/mm/fadvise.c b/mm/fadvise.c index a430131125815803ba25a7014917c6118087dd5c..702f239cd6db534b20276bce62ae1d2176bdb664 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c @@ -52,7 +52,9 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) goto out; } - if (IS_DAX(inode)) { + bdi = inode_to_bdi(mapping->host); + + if (IS_DAX(inode) || (bdi == &noop_backing_dev_info)) { switch (advice) { case POSIX_FADV_NORMAL: case POSIX_FADV_RANDOM: @@ -75,8 +77,6 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) else endbyte--; /* inclusive */ - bdi = inode_to_bdi(mapping->host); - switch (advice) { case POSIX_FADV_NORMAL: f.file->f_ra.ra_pages = bdi->ra_pages; diff --git a/mm/filemap.c b/mm/filemap.c index a49702445ce05beeb8d80b46f0ee57c116986be2..594d73fef8b43bae852f4f7ace1e8cfc46b23690 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -130,17 +130,8 @@ static int page_cache_tree_insert(struct address_space *mapping, return -EEXIST; mapping->nrexceptional--; - if (!dax_mapping(mapping)) { - if (shadowp) - *shadowp = p; - } else { - /* DAX can replace empty locked entry with a hole */ - WARN_ON_ONCE(p != - dax_radix_locked_entry(0, RADIX_DAX_EMPTY)); - /* Wakeup waiters for exceptional entry lock */ - dax_wake_mapping_entry_waiter(mapping, page->index, p, - true); - } + if (shadowp) + *shadowp = p; } __radix_tree_replace(&mapping->page_tree, node, slot, page, workingset_update_node, mapping); @@ -402,8 +393,7 @@ bool filemap_range_has_page(struct address_space *mapping, { pgoff_t index = start_byte >> PAGE_SHIFT; pgoff_t end = end_byte >> PAGE_SHIFT; - struct pagevec pvec; - bool ret; + struct page *page; if (end_byte < start_byte) return false; @@ -411,12 +401,10 @@ bool filemap_range_has_page(struct address_space *mapping, if (mapping->nrpages == 0) return false; - pagevec_init(&pvec, 0); - if (!pagevec_lookup(&pvec, mapping, index, 1)) + if (!find_get_pages_range(mapping, &index, end, 1, &page)) return false; - ret = (pvec.pages[0]->index <= end); - pagevec_release(&pvec); - return ret; + put_page(page); + return true; } EXPORT_SYMBOL(filemap_range_has_page); @@ -475,6 +463,29 @@ int filemap_fdatawait_range(struct address_space *mapping, loff_t start_byte, } EXPORT_SYMBOL(filemap_fdatawait_range); +/** + * file_fdatawait_range - wait for writeback to complete + * @file: file pointing to address space structure to wait for + * @start_byte: offset in bytes where the range starts + * @end_byte: offset in bytes where the range ends (inclusive) + * + * Walk the list of under-writeback pages of the address space that file + * refers to, in the given range and wait for all of them. Check error + * status of the address space vs. the file->f_wb_err cursor and return it. + * + * Since the error status of the file is advanced by this function, + * callers are responsible for checking the return value and handling and/or + * reporting the error. + */ +int file_fdatawait_range(struct file *file, loff_t start_byte, loff_t end_byte) +{ + struct address_space *mapping = file->f_mapping; + + __filemap_fdatawait_range(mapping, start_byte, end_byte); + return file_check_and_advance_wb_err(file); +} +EXPORT_SYMBOL(file_fdatawait_range); + /** * filemap_fdatawait_keep_errors - wait for writeback without clearing errors * @mapping: address space structure to wait for @@ -489,45 +500,22 @@ EXPORT_SYMBOL(filemap_fdatawait_range); */ int filemap_fdatawait_keep_errors(struct address_space *mapping) { - loff_t i_size = i_size_read(mapping->host); - - if (i_size == 0) - return 0; - - __filemap_fdatawait_range(mapping, 0, i_size - 1); + __filemap_fdatawait_range(mapping, 0, LLONG_MAX); return filemap_check_and_keep_errors(mapping); } EXPORT_SYMBOL(filemap_fdatawait_keep_errors); -/** - * filemap_fdatawait - wait for all under-writeback pages to complete - * @mapping: address space structure to wait for - * - * Walk the list of under-writeback pages of the given address space - * and wait for all of them. Check error status of the address space - * and return it. - * - * Since the error status of the address space is cleared by this function, - * callers are responsible for checking the return value and handling and/or - * reporting the error. - */ -int filemap_fdatawait(struct address_space *mapping) +static bool mapping_needs_writeback(struct address_space *mapping) { - loff_t i_size = i_size_read(mapping->host); - - if (i_size == 0) - return 0; - - return filemap_fdatawait_range(mapping, 0, i_size - 1); + return (!dax_mapping(mapping) && mapping->nrpages) || + (dax_mapping(mapping) && mapping->nrexceptional); } -EXPORT_SYMBOL(filemap_fdatawait); int filemap_write_and_wait(struct address_space *mapping) { int err = 0; - if ((!dax_mapping(mapping) && mapping->nrpages) || - (dax_mapping(mapping) && mapping->nrexceptional)) { + if (mapping_needs_writeback(mapping)) { err = filemap_fdatawrite(mapping); /* * Even if the above returned error, the pages may be @@ -566,8 +554,7 @@ int filemap_write_and_wait_range(struct address_space *mapping, { int err = 0; - if ((!dax_mapping(mapping) && mapping->nrpages) || - (dax_mapping(mapping) && mapping->nrexceptional)) { + if (mapping_needs_writeback(mapping)) { err = __filemap_fdatawrite_range(mapping, lstart, lend, WB_SYNC_ALL); /* See comment of filemap_write_and_wait() */ @@ -589,7 +576,7 @@ EXPORT_SYMBOL(filemap_write_and_wait_range); void __filemap_set_wb_err(struct address_space *mapping, int err) { - errseq_t eseq = __errseq_set(&mapping->wb_err, err); + errseq_t eseq = errseq_set(&mapping->wb_err, err); trace_filemap_set_wb_err(mapping, eseq); } @@ -633,6 +620,14 @@ int file_check_and_advance_wb_err(struct file *file) trace_file_check_and_advance_wb_err(file, old); spin_unlock(&file->f_lock); } + + /* + * We're mostly using this function as a drop in replacement for + * filemap_check_errors. Clear AS_EIO/AS_ENOSPC to emulate the effect + * that the legacy code would have had on these flags. + */ + clear_bit(AS_EIO, &mapping->flags); + clear_bit(AS_ENOSPC, &mapping->flags); return err; } EXPORT_SYMBOL(file_check_and_advance_wb_err); @@ -656,8 +651,7 @@ int file_write_and_wait_range(struct file *file, loff_t lstart, loff_t lend) int err = 0, err2; struct address_space *mapping = file->f_mapping; - if ((!dax_mapping(mapping) && mapping->nrpages) || - (dax_mapping(mapping) && mapping->nrexceptional)) { + if (mapping_needs_writeback(mapping)) { err = __filemap_fdatawrite_range(mapping, lstart, lend, WB_SYNC_ALL); /* See comment of filemap_write_and_wait() */ @@ -885,6 +879,7 @@ void __init pagecache_init(void) page_writeback_init(); } +/* This has the same layout as wait_bit_key - see fs/cachefiles/rdwr.c */ struct wait_page_key { struct page *page; int bit_nr; @@ -909,8 +904,10 @@ static int wake_page_function(wait_queue_entry_t *wait, unsigned mode, int sync, if (wait_page->bit_nr != key->bit_nr) return 0; + + /* Stop walking if it's locked */ if (test_bit(key->bit_nr, &key->page->flags)) - return 0; + return -1; return autoremove_wake_function(wait, mode, sync, key); } @@ -920,13 +917,33 @@ static void wake_up_page_bit(struct page *page, int bit_nr) wait_queue_head_t *q = page_waitqueue(page); struct wait_page_key key; unsigned long flags; + wait_queue_entry_t bookmark; key.page = page; key.bit_nr = bit_nr; key.page_match = 0; + bookmark.flags = 0; + bookmark.private = NULL; + bookmark.func = NULL; + INIT_LIST_HEAD(&bookmark.entry); + spin_lock_irqsave(&q->lock, flags); - __wake_up_locked_key(q, TASK_NORMAL, &key); + __wake_up_locked_key_bookmark(q, TASK_NORMAL, &key, &bookmark); + + while (bookmark.flags & WQ_FLAG_BOOKMARK) { + /* + * Take a breather from holding the lock, + * allow pages that finish wake up asynchronously + * to acquire the lock and remove themselves + * from wait queue + */ + spin_unlock_irqrestore(&q->lock, flags); + cpu_relax(); + spin_lock_irqsave(&q->lock, flags); + __wake_up_locked_key_bookmark(q, TASK_NORMAL, &key, &bookmark); + } + /* * It is possible for other pages to have collided on the waitqueue * hash, so in that case check for a page match. That prevents a long- @@ -964,6 +981,7 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q, int ret = 0; init_wait(wait); + wait->flags = lock ? WQ_FLAG_EXCLUSIVE : 0; wait->func = wake_page_function; wait_page.page = page; wait_page.bit_nr = bit_nr; @@ -972,10 +990,7 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q, spin_lock_irq(&q->lock); if (likely(list_empty(&wait->entry))) { - if (lock) - __add_wait_queue_entry_tail_exclusive(q, wait); - else - __add_wait_queue(q, wait); + __add_wait_queue_entry_tail(q, wait); SetPageWaiters(page); } @@ -985,10 +1000,6 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q, if (likely(test_bit(bit_nr, &page->flags))) { io_schedule(); - if (unlikely(signal_pending_state(state, current))) { - ret = -EINTR; - break; - } } if (lock) { @@ -998,6 +1009,11 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q, if (!test_bit(bit_nr, &page->flags)) break; } + + if (unlikely(signal_pending_state(state, current))) { + ret = -EINTR; + break; + } } finish_wait(q, wait); @@ -1039,7 +1055,7 @@ void add_page_wait_queue(struct page *page, wait_queue_entry_t *waiter) unsigned long flags; spin_lock_irqsave(&q->lock, flags); - __add_wait_queue(q, waiter); + __add_wait_queue_entry_tail(q, waiter); SetPageWaiters(page); spin_unlock_irqrestore(&q->lock, flags); } @@ -1564,23 +1580,29 @@ unsigned find_get_entries(struct address_space *mapping, } /** - * find_get_pages - gang pagecache lookup + * find_get_pages_range - gang pagecache lookup * @mapping: The address_space to search * @start: The starting page index + * @end: The final page index (inclusive) * @nr_pages: The maximum number of pages * @pages: Where the resulting pages are placed * - * find_get_pages() will search for and return a group of up to - * @nr_pages pages in the mapping. The pages are placed at @pages. - * find_get_pages() takes a reference against the returned pages. + * find_get_pages_range() will search for and return a group of up to @nr_pages + * pages in the mapping starting at index @start and up to index @end + * (inclusive). The pages are placed at @pages. find_get_pages_range() takes + * a reference against the returned pages. * * The search returns a group of mapping-contiguous pages with ascending * indexes. There may be holes in the indices due to not-present pages. + * We also update @start to index the next page for the traversal. * - * find_get_pages() returns the number of pages which were found. + * find_get_pages_range() returns the number of pages which were found. If this + * number is smaller than @nr_pages, the end of specified range has been + * reached. */ -unsigned find_get_pages(struct address_space *mapping, pgoff_t start, - unsigned int nr_pages, struct page **pages) +unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start, + pgoff_t end, unsigned int nr_pages, + struct page **pages) { struct radix_tree_iter iter; void **slot; @@ -1590,8 +1612,11 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, return 0; rcu_read_lock(); - radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { + radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, *start) { struct page *head, *page; + + if (iter.index > end) + break; repeat: page = radix_tree_deref_slot(slot); if (unlikely(!page)) @@ -1627,11 +1652,25 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, } pages[ret] = page; - if (++ret == nr_pages) - break; + if (++ret == nr_pages) { + *start = pages[ret - 1]->index + 1; + goto out; + } } + /* + * We come here when there is no page beyond @end. We take care to not + * overflow the index @start as it confuses some of the callers. This + * breaks the iteration when there is page at index -1 but that is + * already broken anyway. + */ + if (end == (pgoff_t)-1) + *start = (pgoff_t)-1; + else + *start = end + 1; +out: rcu_read_unlock(); + return ret; } @@ -1886,9 +1925,8 @@ static void shrink_readahead_size_eio(struct file *filp, } /** - * do_generic_file_read - generic file read routine - * @filp: the file to read - * @ppos: current file position + * generic_file_buffered_read - generic file read routine + * @iocb: the iocb to read * @iter: data destination * @written: already copied * @@ -1898,12 +1936,14 @@ static void shrink_readahead_size_eio(struct file *filp, * This is really ugly. But the goto's actually try to clarify some * of the logic when it comes to error handling etc. */ -static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, +static ssize_t generic_file_buffered_read(struct kiocb *iocb, struct iov_iter *iter, ssize_t written) { + struct file *filp = iocb->ki_filp; struct address_space *mapping = filp->f_mapping; struct inode *inode = mapping->host; struct file_ra_state *ra = &filp->f_ra; + loff_t *ppos = &iocb->ki_pos; pgoff_t index; pgoff_t last_index; pgoff_t prev_index; @@ -1936,6 +1976,8 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, page = find_get_page(mapping, index); if (!page) { + if (iocb->ki_flags & IOCB_NOWAIT) + goto would_block; page_cache_sync_readahead(mapping, ra, filp, index, last_index - index); @@ -1949,6 +1991,11 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, index, last_index - index); } if (!PageUptodate(page)) { + if (iocb->ki_flags & IOCB_NOWAIT) { + put_page(page); + goto would_block; + } + /* * See comment in do_read_cache_page on why * wait_on_page_locked is used to avoid unnecessarily @@ -2130,6 +2177,8 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, goto readpage; } +would_block: + error = -EAGAIN; out: ra->prev_pos = prev_index; ra->prev_pos <<= PAGE_SHIFT; @@ -2151,14 +2200,14 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, ssize_t generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) { - struct file *file = iocb->ki_filp; - ssize_t retval = 0; size_t count = iov_iter_count(iter); + ssize_t retval = 0; if (!count) goto out; /* skip atime */ if (iocb->ki_flags & IOCB_DIRECT) { + struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; loff_t size; @@ -2199,7 +2248,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) goto out; } - retval = do_generic_file_read(file, &iocb->ki_pos, iter, retval); + retval = generic_file_buffered_read(iocb, iter, retval); out: return retval; } @@ -2885,9 +2934,15 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from) * we're writing. Either one is a pretty crazy thing to do, * so we don't support it 100%. If this invalidation * fails, tough, the write still worked... + * + * Most of the time we do not need this since dio_complete() will do + * the invalidation for us. However there are some file systems that + * do not end up with dio_complete() being called, so let's not break + * them by removing it completely */ - invalidate_inode_pages2_range(mapping, - pos >> PAGE_SHIFT, end); + if (mapping->nrpages) + invalidate_inode_pages2_range(mapping, + pos >> PAGE_SHIFT, end); if (written > 0) { pos += written; diff --git a/mm/gup.c b/mm/gup.c index 23f01c40c88f63cc88ff62548a4d120b0c406a8e..b2b4d4263768d82d61b99d2a2125251345fa778c 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -234,6 +234,16 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma, return page; return no_page_table(vma, flags); } +retry: + if (!pmd_present(*pmd)) { + if (likely(!(flags & FOLL_MIGRATION))) + return no_page_table(vma, flags); + VM_BUG_ON(thp_migration_supported() && + !is_pmd_migration_entry(*pmd)); + if (is_pmd_migration_entry(*pmd)) + pmd_migration_entry_wait(mm, pmd); + goto retry; + } if (pmd_devmap(*pmd)) { ptl = pmd_lock(mm, pmd); page = follow_devmap_pmd(vma, address, pmd, flags); @@ -247,7 +257,15 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma, if ((flags & FOLL_NUMA) && pmd_protnone(*pmd)) return no_page_table(vma, flags); +retry_locked: ptl = pmd_lock(mm, pmd); + if (unlikely(!pmd_present(*pmd))) { + spin_unlock(ptl); + if (likely(!(flags & FOLL_MIGRATION))) + return no_page_table(vma, flags); + pmd_migration_entry_wait(mm, pmd); + goto retry_locked; + } if (unlikely(!pmd_trans_huge(*pmd))) { spin_unlock(ptl); return follow_page_pte(vma, address, pmd, flags); @@ -424,7 +442,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, pud = pud_offset(p4d, address); BUG_ON(pud_none(*pud)); pmd = pmd_offset(pud, address); - if (pmd_none(*pmd)) + if (!pmd_present(*pmd)) return -EFAULT; VM_BUG_ON(pmd_trans_huge(*pmd)); pte = pte_offset_map(pmd, address); @@ -438,6 +456,13 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, if ((gup_flags & FOLL_DUMP) || !is_zero_pfn(pte_pfn(*pte))) goto unmap; *page = pte_page(*pte); + + /* + * This should never happen (a device public page in the gate + * area). + */ + if (is_device_public_page(*page)) + goto unmap; } get_page(*page); out: @@ -1352,7 +1377,7 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, } #endif /* __HAVE_ARCH_PTE_SPECIAL */ -#ifdef __HAVE_ARCH_PTE_DEVMAP +#if defined(__HAVE_ARCH_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE) static int __gup_device_huge(unsigned long pfn, unsigned long addr, unsigned long end, struct page **pages, int *nr) { @@ -1534,7 +1559,7 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, pmd_t pmd = READ_ONCE(*pmdp); next = pmd_addr_end(addr, end); - if (pmd_none(pmd)) + if (!pmd_present(pmd)) return 0; if (unlikely(pmd_trans_huge(pmd) || pmd_huge(pmd))) { diff --git a/mm/hmm.c b/mm/hmm.c new file mode 100644 index 0000000000000000000000000000000000000000..a88a847bccba700a1c0f51d0a819dcf365995ed1 --- /dev/null +++ b/mm/hmm.c @@ -0,0 +1,1257 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: Jérôme Glisse + */ +/* + * Refer to include/linux/hmm.h for information about heterogeneous memory + * management or HMM for short. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PA_SECTION_SIZE (1UL << PA_SECTION_SHIFT) + +#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC) +/* + * Device private memory see HMM (Documentation/vm/hmm.txt) or hmm.h + */ +DEFINE_STATIC_KEY_FALSE(device_private_key); +EXPORT_SYMBOL(device_private_key); +#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ + + +#if IS_ENABLED(CONFIG_HMM_MIRROR) +static const struct mmu_notifier_ops hmm_mmu_notifier_ops; + +/* + * struct hmm - HMM per mm struct + * + * @mm: mm struct this HMM struct is bound to + * @lock: lock protecting ranges list + * @sequence: we track updates to the CPU page table with a sequence number + * @ranges: list of range being snapshotted + * @mirrors: list of mirrors for this mm + * @mmu_notifier: mmu notifier to track updates to CPU page table + * @mirrors_sem: read/write semaphore protecting the mirrors list + */ +struct hmm { + struct mm_struct *mm; + spinlock_t lock; + atomic_t sequence; + struct list_head ranges; + struct list_head mirrors; + struct mmu_notifier mmu_notifier; + struct rw_semaphore mirrors_sem; +}; + +/* + * hmm_register - register HMM against an mm (HMM internal) + * + * @mm: mm struct to attach to + * + * This is not intended to be used directly by device drivers. It allocates an + * HMM struct if mm does not have one, and initializes it. + */ +static struct hmm *hmm_register(struct mm_struct *mm) +{ + struct hmm *hmm = READ_ONCE(mm->hmm); + bool cleanup = false; + + /* + * The hmm struct can only be freed once the mm_struct goes away, + * hence we should always have pre-allocated an new hmm struct + * above. + */ + if (hmm) + return hmm; + + hmm = kmalloc(sizeof(*hmm), GFP_KERNEL); + if (!hmm) + return NULL; + INIT_LIST_HEAD(&hmm->mirrors); + init_rwsem(&hmm->mirrors_sem); + atomic_set(&hmm->sequence, 0); + hmm->mmu_notifier.ops = NULL; + INIT_LIST_HEAD(&hmm->ranges); + spin_lock_init(&hmm->lock); + hmm->mm = mm; + + /* + * We should only get here if hold the mmap_sem in write mode ie on + * registration of first mirror through hmm_mirror_register() + */ + hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops; + if (__mmu_notifier_register(&hmm->mmu_notifier, mm)) { + kfree(hmm); + return NULL; + } + + spin_lock(&mm->page_table_lock); + if (!mm->hmm) + mm->hmm = hmm; + else + cleanup = true; + spin_unlock(&mm->page_table_lock); + + if (cleanup) { + mmu_notifier_unregister(&hmm->mmu_notifier, mm); + kfree(hmm); + } + + return mm->hmm; +} + +void hmm_mm_destroy(struct mm_struct *mm) +{ + kfree(mm->hmm); +} + +static void hmm_invalidate_range(struct hmm *hmm, + enum hmm_update_type action, + unsigned long start, + unsigned long end) +{ + struct hmm_mirror *mirror; + struct hmm_range *range; + + spin_lock(&hmm->lock); + list_for_each_entry(range, &hmm->ranges, list) { + unsigned long addr, idx, npages; + + if (end < range->start || start >= range->end) + continue; + + range->valid = false; + addr = max(start, range->start); + idx = (addr - range->start) >> PAGE_SHIFT; + npages = (min(range->end, end) - addr) >> PAGE_SHIFT; + memset(&range->pfns[idx], 0, sizeof(*range->pfns) * npages); + } + spin_unlock(&hmm->lock); + + down_read(&hmm->mirrors_sem); + list_for_each_entry(mirror, &hmm->mirrors, list) + mirror->ops->sync_cpu_device_pagetables(mirror, action, + start, end); + up_read(&hmm->mirrors_sem); +} + +static void hmm_invalidate_range_start(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + struct hmm *hmm = mm->hmm; + + VM_BUG_ON(!hmm); + + atomic_inc(&hmm->sequence); +} + +static void hmm_invalidate_range_end(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + struct hmm *hmm = mm->hmm; + + VM_BUG_ON(!hmm); + + hmm_invalidate_range(mm->hmm, HMM_UPDATE_INVALIDATE, start, end); +} + +static const struct mmu_notifier_ops hmm_mmu_notifier_ops = { + .invalidate_range_start = hmm_invalidate_range_start, + .invalidate_range_end = hmm_invalidate_range_end, +}; + +/* + * hmm_mirror_register() - register a mirror against an mm + * + * @mirror: new mirror struct to register + * @mm: mm to register against + * + * To start mirroring a process address space, the device driver must register + * an HMM mirror struct. + * + * THE mm->mmap_sem MUST BE HELD IN WRITE MODE ! + */ +int hmm_mirror_register(struct hmm_mirror *mirror, struct mm_struct *mm) +{ + /* Sanity check */ + if (!mm || !mirror || !mirror->ops) + return -EINVAL; + + mirror->hmm = hmm_register(mm); + if (!mirror->hmm) + return -ENOMEM; + + down_write(&mirror->hmm->mirrors_sem); + list_add(&mirror->list, &mirror->hmm->mirrors); + up_write(&mirror->hmm->mirrors_sem); + + return 0; +} +EXPORT_SYMBOL(hmm_mirror_register); + +/* + * hmm_mirror_unregister() - unregister a mirror + * + * @mirror: new mirror struct to register + * + * Stop mirroring a process address space, and cleanup. + */ +void hmm_mirror_unregister(struct hmm_mirror *mirror) +{ + struct hmm *hmm = mirror->hmm; + + down_write(&hmm->mirrors_sem); + list_del(&mirror->list); + up_write(&hmm->mirrors_sem); +} +EXPORT_SYMBOL(hmm_mirror_unregister); + +struct hmm_vma_walk { + struct hmm_range *range; + unsigned long last; + bool fault; + bool block; + bool write; +}; + +static int hmm_vma_do_fault(struct mm_walk *walk, + unsigned long addr, + hmm_pfn_t *pfn) +{ + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_REMOTE; + struct hmm_vma_walk *hmm_vma_walk = walk->private; + struct vm_area_struct *vma = walk->vma; + int r; + + flags |= hmm_vma_walk->block ? 0 : FAULT_FLAG_ALLOW_RETRY; + flags |= hmm_vma_walk->write ? FAULT_FLAG_WRITE : 0; + r = handle_mm_fault(vma, addr, flags); + if (r & VM_FAULT_RETRY) + return -EBUSY; + if (r & VM_FAULT_ERROR) { + *pfn = HMM_PFN_ERROR; + return -EFAULT; + } + + return -EAGAIN; +} + +static void hmm_pfns_special(hmm_pfn_t *pfns, + unsigned long addr, + unsigned long end) +{ + for (; addr < end; addr += PAGE_SIZE, pfns++) + *pfns = HMM_PFN_SPECIAL; +} + +static int hmm_pfns_bad(unsigned long addr, + unsigned long end, + struct mm_walk *walk) +{ + struct hmm_range *range = walk->private; + hmm_pfn_t *pfns = range->pfns; + unsigned long i; + + i = (addr - range->start) >> PAGE_SHIFT; + for (; addr < end; addr += PAGE_SIZE, i++) + pfns[i] = HMM_PFN_ERROR; + + return 0; +} + +static void hmm_pfns_clear(hmm_pfn_t *pfns, + unsigned long addr, + unsigned long end) +{ + for (; addr < end; addr += PAGE_SIZE, pfns++) + *pfns = 0; +} + +static int hmm_vma_walk_hole(unsigned long addr, + unsigned long end, + struct mm_walk *walk) +{ + struct hmm_vma_walk *hmm_vma_walk = walk->private; + struct hmm_range *range = hmm_vma_walk->range; + hmm_pfn_t *pfns = range->pfns; + unsigned long i; + + hmm_vma_walk->last = addr; + i = (addr - range->start) >> PAGE_SHIFT; + for (; addr < end; addr += PAGE_SIZE, i++) { + pfns[i] = HMM_PFN_EMPTY; + if (hmm_vma_walk->fault) { + int ret; + + ret = hmm_vma_do_fault(walk, addr, &pfns[i]); + if (ret != -EAGAIN) + return ret; + } + } + + return hmm_vma_walk->fault ? -EAGAIN : 0; +} + +static int hmm_vma_walk_clear(unsigned long addr, + unsigned long end, + struct mm_walk *walk) +{ + struct hmm_vma_walk *hmm_vma_walk = walk->private; + struct hmm_range *range = hmm_vma_walk->range; + hmm_pfn_t *pfns = range->pfns; + unsigned long i; + + hmm_vma_walk->last = addr; + i = (addr - range->start) >> PAGE_SHIFT; + for (; addr < end; addr += PAGE_SIZE, i++) { + pfns[i] = 0; + if (hmm_vma_walk->fault) { + int ret; + + ret = hmm_vma_do_fault(walk, addr, &pfns[i]); + if (ret != -EAGAIN) + return ret; + } + } + + return hmm_vma_walk->fault ? -EAGAIN : 0; +} + +static int hmm_vma_walk_pmd(pmd_t *pmdp, + unsigned long start, + unsigned long end, + struct mm_walk *walk) +{ + struct hmm_vma_walk *hmm_vma_walk = walk->private; + struct hmm_range *range = hmm_vma_walk->range; + struct vm_area_struct *vma = walk->vma; + hmm_pfn_t *pfns = range->pfns; + unsigned long addr = start, i; + bool write_fault; + hmm_pfn_t flag; + pte_t *ptep; + + i = (addr - range->start) >> PAGE_SHIFT; + flag = vma->vm_flags & VM_READ ? HMM_PFN_READ : 0; + write_fault = hmm_vma_walk->fault & hmm_vma_walk->write; + +again: + if (pmd_none(*pmdp)) + return hmm_vma_walk_hole(start, end, walk); + + if (pmd_huge(*pmdp) && vma->vm_flags & VM_HUGETLB) + return hmm_pfns_bad(start, end, walk); + + if (pmd_devmap(*pmdp) || pmd_trans_huge(*pmdp)) { + unsigned long pfn; + pmd_t pmd; + + /* + * No need to take pmd_lock here, even if some other threads + * is splitting the huge pmd we will get that event through + * mmu_notifier callback. + * + * So just read pmd value and check again its a transparent + * huge or device mapping one and compute corresponding pfn + * values. + */ + pmd = pmd_read_atomic(pmdp); + barrier(); + if (!pmd_devmap(pmd) && !pmd_trans_huge(pmd)) + goto again; + if (pmd_protnone(pmd)) + return hmm_vma_walk_clear(start, end, walk); + + if (write_fault && !pmd_write(pmd)) + return hmm_vma_walk_clear(start, end, walk); + + pfn = pmd_pfn(pmd) + pte_index(addr); + flag |= pmd_write(pmd) ? HMM_PFN_WRITE : 0; + for (; addr < end; addr += PAGE_SIZE, i++, pfn++) + pfns[i] = hmm_pfn_t_from_pfn(pfn) | flag; + return 0; + } + + if (pmd_bad(*pmdp)) + return hmm_pfns_bad(start, end, walk); + + ptep = pte_offset_map(pmdp, addr); + for (; addr < end; addr += PAGE_SIZE, ptep++, i++) { + pte_t pte = *ptep; + + pfns[i] = 0; + + if (pte_none(pte)) { + pfns[i] = HMM_PFN_EMPTY; + if (hmm_vma_walk->fault) + goto fault; + continue; + } + + if (!pte_present(pte)) { + swp_entry_t entry; + + if (!non_swap_entry(entry)) { + if (hmm_vma_walk->fault) + goto fault; + continue; + } + + entry = pte_to_swp_entry(pte); + + /* + * This is a special swap entry, ignore migration, use + * device and report anything else as error. + */ + if (is_device_private_entry(entry)) { + pfns[i] = hmm_pfn_t_from_pfn(swp_offset(entry)); + if (is_write_device_private_entry(entry)) { + pfns[i] |= HMM_PFN_WRITE; + } else if (write_fault) + goto fault; + pfns[i] |= HMM_PFN_DEVICE_UNADDRESSABLE; + pfns[i] |= flag; + } else if (is_migration_entry(entry)) { + if (hmm_vma_walk->fault) { + pte_unmap(ptep); + hmm_vma_walk->last = addr; + migration_entry_wait(vma->vm_mm, + pmdp, addr); + return -EAGAIN; + } + continue; + } else { + /* Report error for everything else */ + pfns[i] = HMM_PFN_ERROR; + } + continue; + } + + if (write_fault && !pte_write(pte)) + goto fault; + + pfns[i] = hmm_pfn_t_from_pfn(pte_pfn(pte)) | flag; + pfns[i] |= pte_write(pte) ? HMM_PFN_WRITE : 0; + continue; + +fault: + pte_unmap(ptep); + /* Fault all pages in range */ + return hmm_vma_walk_clear(start, end, walk); + } + pte_unmap(ptep - 1); + + return 0; +} + +/* + * hmm_vma_get_pfns() - snapshot CPU page table for a range of virtual addresses + * @vma: virtual memory area containing the virtual address range + * @range: used to track snapshot validity + * @start: range virtual start address (inclusive) + * @end: range virtual end address (exclusive) + * @entries: array of hmm_pfn_t: provided by the caller, filled in by function + * Returns: -EINVAL if invalid argument, -ENOMEM out of memory, 0 success + * + * This snapshots the CPU page table for a range of virtual addresses. Snapshot + * validity is tracked by range struct. See hmm_vma_range_done() for further + * information. + * + * The range struct is initialized here. It tracks the CPU page table, but only + * if the function returns success (0), in which case the caller must then call + * hmm_vma_range_done() to stop CPU page table update tracking on this range. + * + * NOT CALLING hmm_vma_range_done() IF FUNCTION RETURNS 0 WILL LEAD TO SERIOUS + * MEMORY CORRUPTION ! YOU HAVE BEEN WARNED ! + */ +int hmm_vma_get_pfns(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns) +{ + struct hmm_vma_walk hmm_vma_walk; + struct mm_walk mm_walk; + struct hmm *hmm; + + /* FIXME support hugetlb fs */ + if (is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_SPECIAL)) { + hmm_pfns_special(pfns, start, end); + return -EINVAL; + } + + /* Sanity check, this really should not happen ! */ + if (start < vma->vm_start || start >= vma->vm_end) + return -EINVAL; + if (end < vma->vm_start || end > vma->vm_end) + return -EINVAL; + + hmm = hmm_register(vma->vm_mm); + if (!hmm) + return -ENOMEM; + /* Caller must have registered a mirror, via hmm_mirror_register() ! */ + if (!hmm->mmu_notifier.ops) + return -EINVAL; + + /* Initialize range to track CPU page table update */ + range->start = start; + range->pfns = pfns; + range->end = end; + spin_lock(&hmm->lock); + range->valid = true; + list_add_rcu(&range->list, &hmm->ranges); + spin_unlock(&hmm->lock); + + hmm_vma_walk.fault = false; + hmm_vma_walk.range = range; + mm_walk.private = &hmm_vma_walk; + + mm_walk.vma = vma; + mm_walk.mm = vma->vm_mm; + mm_walk.pte_entry = NULL; + mm_walk.test_walk = NULL; + mm_walk.hugetlb_entry = NULL; + mm_walk.pmd_entry = hmm_vma_walk_pmd; + mm_walk.pte_hole = hmm_vma_walk_hole; + + walk_page_range(start, end, &mm_walk); + return 0; +} +EXPORT_SYMBOL(hmm_vma_get_pfns); + +/* + * hmm_vma_range_done() - stop tracking change to CPU page table over a range + * @vma: virtual memory area containing the virtual address range + * @range: range being tracked + * Returns: false if range data has been invalidated, true otherwise + * + * Range struct is used to track updates to the CPU page table after a call to + * either hmm_vma_get_pfns() or hmm_vma_fault(). Once the device driver is done + * using the data, or wants to lock updates to the data it got from those + * functions, it must call the hmm_vma_range_done() function, which will then + * stop tracking CPU page table updates. + * + * Note that device driver must still implement general CPU page table update + * tracking either by using hmm_mirror (see hmm_mirror_register()) or by using + * the mmu_notifier API directly. + * + * CPU page table update tracking done through hmm_range is only temporary and + * to be used while trying to duplicate CPU page table contents for a range of + * virtual addresses. + * + * There are two ways to use this : + * again: + * hmm_vma_get_pfns(vma, range, start, end, pfns); or hmm_vma_fault(...); + * trans = device_build_page_table_update_transaction(pfns); + * device_page_table_lock(); + * if (!hmm_vma_range_done(vma, range)) { + * device_page_table_unlock(); + * goto again; + * } + * device_commit_transaction(trans); + * device_page_table_unlock(); + * + * Or: + * hmm_vma_get_pfns(vma, range, start, end, pfns); or hmm_vma_fault(...); + * device_page_table_lock(); + * hmm_vma_range_done(vma, range); + * device_update_page_table(pfns); + * device_page_table_unlock(); + */ +bool hmm_vma_range_done(struct vm_area_struct *vma, struct hmm_range *range) +{ + unsigned long npages = (range->end - range->start) >> PAGE_SHIFT; + struct hmm *hmm; + + if (range->end <= range->start) { + BUG(); + return false; + } + + hmm = hmm_register(vma->vm_mm); + if (!hmm) { + memset(range->pfns, 0, sizeof(*range->pfns) * npages); + return false; + } + + spin_lock(&hmm->lock); + list_del_rcu(&range->list); + spin_unlock(&hmm->lock); + + return range->valid; +} +EXPORT_SYMBOL(hmm_vma_range_done); + +/* + * hmm_vma_fault() - try to fault some address in a virtual address range + * @vma: virtual memory area containing the virtual address range + * @range: use to track pfns array content validity + * @start: fault range virtual start address (inclusive) + * @end: fault range virtual end address (exclusive) + * @pfns: array of hmm_pfn_t, only entry with fault flag set will be faulted + * @write: is it a write fault + * @block: allow blocking on fault (if true it sleeps and do not drop mmap_sem) + * Returns: 0 success, error otherwise (-EAGAIN means mmap_sem have been drop) + * + * This is similar to a regular CPU page fault except that it will not trigger + * any memory migration if the memory being faulted is not accessible by CPUs. + * + * On error, for one virtual address in the range, the function will set the + * hmm_pfn_t error flag for the corresponding pfn entry. + * + * Expected use pattern: + * retry: + * down_read(&mm->mmap_sem); + * // Find vma and address device wants to fault, initialize hmm_pfn_t + * // array accordingly + * ret = hmm_vma_fault(vma, start, end, pfns, allow_retry); + * switch (ret) { + * case -EAGAIN: + * hmm_vma_range_done(vma, range); + * // You might want to rate limit or yield to play nicely, you may + * // also commit any valid pfn in the array assuming that you are + * // getting true from hmm_vma_range_monitor_end() + * goto retry; + * case 0: + * break; + * default: + * // Handle error ! + * up_read(&mm->mmap_sem) + * return; + * } + * // Take device driver lock that serialize device page table update + * driver_lock_device_page_table_update(); + * hmm_vma_range_done(vma, range); + * // Commit pfns we got from hmm_vma_fault() + * driver_unlock_device_page_table_update(); + * up_read(&mm->mmap_sem) + * + * YOU MUST CALL hmm_vma_range_done() AFTER THIS FUNCTION RETURN SUCCESS (0) + * BEFORE FREEING THE range struct OR YOU WILL HAVE SERIOUS MEMORY CORRUPTION ! + * + * YOU HAVE BEEN WARNED ! + */ +int hmm_vma_fault(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns, + bool write, + bool block) +{ + struct hmm_vma_walk hmm_vma_walk; + struct mm_walk mm_walk; + struct hmm *hmm; + int ret; + + /* Sanity check, this really should not happen ! */ + if (start < vma->vm_start || start >= vma->vm_end) + return -EINVAL; + if (end < vma->vm_start || end > vma->vm_end) + return -EINVAL; + + hmm = hmm_register(vma->vm_mm); + if (!hmm) { + hmm_pfns_clear(pfns, start, end); + return -ENOMEM; + } + /* Caller must have registered a mirror using hmm_mirror_register() */ + if (!hmm->mmu_notifier.ops) + return -EINVAL; + + /* Initialize range to track CPU page table update */ + range->start = start; + range->pfns = pfns; + range->end = end; + spin_lock(&hmm->lock); + range->valid = true; + list_add_rcu(&range->list, &hmm->ranges); + spin_unlock(&hmm->lock); + + /* FIXME support hugetlb fs */ + if (is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_SPECIAL)) { + hmm_pfns_special(pfns, start, end); + return 0; + } + + hmm_vma_walk.fault = true; + hmm_vma_walk.write = write; + hmm_vma_walk.block = block; + hmm_vma_walk.range = range; + mm_walk.private = &hmm_vma_walk; + hmm_vma_walk.last = range->start; + + mm_walk.vma = vma; + mm_walk.mm = vma->vm_mm; + mm_walk.pte_entry = NULL; + mm_walk.test_walk = NULL; + mm_walk.hugetlb_entry = NULL; + mm_walk.pmd_entry = hmm_vma_walk_pmd; + mm_walk.pte_hole = hmm_vma_walk_hole; + + do { + ret = walk_page_range(start, end, &mm_walk); + start = hmm_vma_walk.last; + } while (ret == -EAGAIN); + + if (ret) { + unsigned long i; + + i = (hmm_vma_walk.last - range->start) >> PAGE_SHIFT; + hmm_pfns_clear(&pfns[i], hmm_vma_walk.last, end); + hmm_vma_range_done(vma, range); + } + return ret; +} +EXPORT_SYMBOL(hmm_vma_fault); +#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ + + +#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC) +struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma, + unsigned long addr) +{ + struct page *page; + + page = alloc_page_vma(GFP_HIGHUSER, vma, addr); + if (!page) + return NULL; + lock_page(page); + return page; +} +EXPORT_SYMBOL(hmm_vma_alloc_locked_page); + + +static void hmm_devmem_ref_release(struct percpu_ref *ref) +{ + struct hmm_devmem *devmem; + + devmem = container_of(ref, struct hmm_devmem, ref); + complete(&devmem->completion); +} + +static void hmm_devmem_ref_exit(void *data) +{ + struct percpu_ref *ref = data; + struct hmm_devmem *devmem; + + devmem = container_of(ref, struct hmm_devmem, ref); + percpu_ref_exit(ref); + devm_remove_action(devmem->device, &hmm_devmem_ref_exit, data); +} + +static void hmm_devmem_ref_kill(void *data) +{ + struct percpu_ref *ref = data; + struct hmm_devmem *devmem; + + devmem = container_of(ref, struct hmm_devmem, ref); + percpu_ref_kill(ref); + wait_for_completion(&devmem->completion); + devm_remove_action(devmem->device, &hmm_devmem_ref_kill, data); +} + +static int hmm_devmem_fault(struct vm_area_struct *vma, + unsigned long addr, + const struct page *page, + unsigned int flags, + pmd_t *pmdp) +{ + struct hmm_devmem *devmem = page->pgmap->data; + + return devmem->ops->fault(devmem, vma, addr, page, flags, pmdp); +} + +static void hmm_devmem_free(struct page *page, void *data) +{ + struct hmm_devmem *devmem = data; + + devmem->ops->free(devmem, page); +} + +static DEFINE_MUTEX(hmm_devmem_lock); +static RADIX_TREE(hmm_devmem_radix, GFP_KERNEL); + +static void hmm_devmem_radix_release(struct resource *resource) +{ + resource_size_t key, align_start, align_size, align_end; + + align_start = resource->start & ~(PA_SECTION_SIZE - 1); + align_size = ALIGN(resource_size(resource), PA_SECTION_SIZE); + align_end = align_start + align_size - 1; + + mutex_lock(&hmm_devmem_lock); + for (key = resource->start; + key <= resource->end; + key += PA_SECTION_SIZE) + radix_tree_delete(&hmm_devmem_radix, key >> PA_SECTION_SHIFT); + mutex_unlock(&hmm_devmem_lock); +} + +static void hmm_devmem_release(struct device *dev, void *data) +{ + struct hmm_devmem *devmem = data; + struct resource *resource = devmem->resource; + unsigned long start_pfn, npages; + struct zone *zone; + struct page *page; + + if (percpu_ref_tryget_live(&devmem->ref)) { + dev_WARN(dev, "%s: page mapping is still live!\n", __func__); + percpu_ref_put(&devmem->ref); + } + + /* pages are dead and unused, undo the arch mapping */ + start_pfn = (resource->start & ~(PA_SECTION_SIZE - 1)) >> PAGE_SHIFT; + npages = ALIGN(resource_size(resource), PA_SECTION_SIZE) >> PAGE_SHIFT; + + page = pfn_to_page(start_pfn); + zone = page_zone(page); + + mem_hotplug_begin(); + if (resource->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) + __remove_pages(zone, start_pfn, npages); + else + arch_remove_memory(start_pfn << PAGE_SHIFT, + npages << PAGE_SHIFT); + mem_hotplug_done(); + + hmm_devmem_radix_release(resource); +} + +static struct hmm_devmem *hmm_devmem_find(resource_size_t phys) +{ + WARN_ON_ONCE(!rcu_read_lock_held()); + + return radix_tree_lookup(&hmm_devmem_radix, phys >> PA_SECTION_SHIFT); +} + +static int hmm_devmem_pages_create(struct hmm_devmem *devmem) +{ + resource_size_t key, align_start, align_size, align_end; + struct device *device = devmem->device; + int ret, nid, is_ram; + unsigned long pfn; + + align_start = devmem->resource->start & ~(PA_SECTION_SIZE - 1); + align_size = ALIGN(devmem->resource->start + + resource_size(devmem->resource), + PA_SECTION_SIZE) - align_start; + + is_ram = region_intersects(align_start, align_size, + IORESOURCE_SYSTEM_RAM, + IORES_DESC_NONE); + if (is_ram == REGION_MIXED) { + WARN_ONCE(1, "%s attempted on mixed region %pr\n", + __func__, devmem->resource); + return -ENXIO; + } + if (is_ram == REGION_INTERSECTS) + return -ENXIO; + + if (devmem->resource->desc == IORES_DESC_DEVICE_PUBLIC_MEMORY) + devmem->pagemap.type = MEMORY_DEVICE_PUBLIC; + else + devmem->pagemap.type = MEMORY_DEVICE_PRIVATE; + + devmem->pagemap.res = devmem->resource; + devmem->pagemap.page_fault = hmm_devmem_fault; + devmem->pagemap.page_free = hmm_devmem_free; + devmem->pagemap.dev = devmem->device; + devmem->pagemap.ref = &devmem->ref; + devmem->pagemap.data = devmem; + + mutex_lock(&hmm_devmem_lock); + align_end = align_start + align_size - 1; + for (key = align_start; key <= align_end; key += PA_SECTION_SIZE) { + struct hmm_devmem *dup; + + rcu_read_lock(); + dup = hmm_devmem_find(key); + rcu_read_unlock(); + if (dup) { + dev_err(device, "%s: collides with mapping for %s\n", + __func__, dev_name(dup->device)); + mutex_unlock(&hmm_devmem_lock); + ret = -EBUSY; + goto error; + } + ret = radix_tree_insert(&hmm_devmem_radix, + key >> PA_SECTION_SHIFT, + devmem); + if (ret) { + dev_err(device, "%s: failed: %d\n", __func__, ret); + mutex_unlock(&hmm_devmem_lock); + goto error_radix; + } + } + mutex_unlock(&hmm_devmem_lock); + + nid = dev_to_node(device); + if (nid < 0) + nid = numa_mem_id(); + + mem_hotplug_begin(); + /* + * For device private memory we call add_pages() as we only need to + * allocate and initialize struct page for the device memory. More- + * over the device memory is un-accessible thus we do not want to + * create a linear mapping for the memory like arch_add_memory() + * would do. + * + * For device public memory, which is accesible by the CPU, we do + * want the linear mapping and thus use arch_add_memory(). + */ + if (devmem->pagemap.type == MEMORY_DEVICE_PUBLIC) + ret = arch_add_memory(nid, align_start, align_size, false); + else + ret = add_pages(nid, align_start >> PAGE_SHIFT, + align_size >> PAGE_SHIFT, false); + if (ret) { + mem_hotplug_done(); + goto error_add_memory; + } + move_pfn_range_to_zone(&NODE_DATA(nid)->node_zones[ZONE_DEVICE], + align_start >> PAGE_SHIFT, + align_size >> PAGE_SHIFT); + mem_hotplug_done(); + + for (pfn = devmem->pfn_first; pfn < devmem->pfn_last; pfn++) { + struct page *page = pfn_to_page(pfn); + + page->pgmap = &devmem->pagemap; + } + return 0; + +error_add_memory: + untrack_pfn(NULL, PHYS_PFN(align_start), align_size); +error_radix: + hmm_devmem_radix_release(devmem->resource); +error: + return ret; +} + +static int hmm_devmem_match(struct device *dev, void *data, void *match_data) +{ + struct hmm_devmem *devmem = data; + + return devmem->resource == match_data; +} + +static void hmm_devmem_pages_remove(struct hmm_devmem *devmem) +{ + devres_release(devmem->device, &hmm_devmem_release, + &hmm_devmem_match, devmem->resource); +} + +/* + * hmm_devmem_add() - hotplug ZONE_DEVICE memory for device memory + * + * @ops: memory event device driver callback (see struct hmm_devmem_ops) + * @device: device struct to bind the resource too + * @size: size in bytes of the device memory to add + * Returns: pointer to new hmm_devmem struct ERR_PTR otherwise + * + * This function first finds an empty range of physical address big enough to + * contain the new resource, and then hotplugs it as ZONE_DEVICE memory, which + * in turn allocates struct pages. It does not do anything beyond that; all + * events affecting the memory will go through the various callbacks provided + * by hmm_devmem_ops struct. + * + * Device driver should call this function during device initialization and + * is then responsible of memory management. HMM only provides helpers. + */ +struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, + struct device *device, + unsigned long size) +{ + struct hmm_devmem *devmem; + resource_size_t addr; + int ret; + + static_branch_enable(&device_private_key); + + devmem = devres_alloc_node(&hmm_devmem_release, sizeof(*devmem), + GFP_KERNEL, dev_to_node(device)); + if (!devmem) + return ERR_PTR(-ENOMEM); + + init_completion(&devmem->completion); + devmem->pfn_first = -1UL; + devmem->pfn_last = -1UL; + devmem->resource = NULL; + devmem->device = device; + devmem->ops = ops; + + ret = percpu_ref_init(&devmem->ref, &hmm_devmem_ref_release, + 0, GFP_KERNEL); + if (ret) + goto error_percpu_ref; + + ret = devm_add_action(device, hmm_devmem_ref_exit, &devmem->ref); + if (ret) + goto error_devm_add_action; + + size = ALIGN(size, PA_SECTION_SIZE); + addr = min((unsigned long)iomem_resource.end, + (1UL << MAX_PHYSMEM_BITS) - 1); + addr = addr - size + 1UL; + + /* + * FIXME add a new helper to quickly walk resource tree and find free + * range + * + * FIXME what about ioport_resource resource ? + */ + for (; addr > size && addr >= iomem_resource.start; addr -= size) { + ret = region_intersects(addr, size, 0, IORES_DESC_NONE); + if (ret != REGION_DISJOINT) + continue; + + devmem->resource = devm_request_mem_region(device, addr, size, + dev_name(device)); + if (!devmem->resource) { + ret = -ENOMEM; + goto error_no_resource; + } + break; + } + if (!devmem->resource) { + ret = -ERANGE; + goto error_no_resource; + } + + devmem->resource->desc = IORES_DESC_DEVICE_PRIVATE_MEMORY; + devmem->pfn_first = devmem->resource->start >> PAGE_SHIFT; + devmem->pfn_last = devmem->pfn_first + + (resource_size(devmem->resource) >> PAGE_SHIFT); + + ret = hmm_devmem_pages_create(devmem); + if (ret) + goto error_pages; + + devres_add(device, devmem); + + ret = devm_add_action(device, hmm_devmem_ref_kill, &devmem->ref); + if (ret) { + hmm_devmem_remove(devmem); + return ERR_PTR(ret); + } + + return devmem; + +error_pages: + devm_release_mem_region(device, devmem->resource->start, + resource_size(devmem->resource)); +error_no_resource: +error_devm_add_action: + hmm_devmem_ref_kill(&devmem->ref); + hmm_devmem_ref_exit(&devmem->ref); +error_percpu_ref: + devres_free(devmem); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(hmm_devmem_add); + +struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops, + struct device *device, + struct resource *res) +{ + struct hmm_devmem *devmem; + int ret; + + if (res->desc != IORES_DESC_DEVICE_PUBLIC_MEMORY) + return ERR_PTR(-EINVAL); + + static_branch_enable(&device_private_key); + + devmem = devres_alloc_node(&hmm_devmem_release, sizeof(*devmem), + GFP_KERNEL, dev_to_node(device)); + if (!devmem) + return ERR_PTR(-ENOMEM); + + init_completion(&devmem->completion); + devmem->pfn_first = -1UL; + devmem->pfn_last = -1UL; + devmem->resource = res; + devmem->device = device; + devmem->ops = ops; + + ret = percpu_ref_init(&devmem->ref, &hmm_devmem_ref_release, + 0, GFP_KERNEL); + if (ret) + goto error_percpu_ref; + + ret = devm_add_action(device, hmm_devmem_ref_exit, &devmem->ref); + if (ret) + goto error_devm_add_action; + + + devmem->pfn_first = devmem->resource->start >> PAGE_SHIFT; + devmem->pfn_last = devmem->pfn_first + + (resource_size(devmem->resource) >> PAGE_SHIFT); + + ret = hmm_devmem_pages_create(devmem); + if (ret) + goto error_devm_add_action; + + devres_add(device, devmem); + + ret = devm_add_action(device, hmm_devmem_ref_kill, &devmem->ref); + if (ret) { + hmm_devmem_remove(devmem); + return ERR_PTR(ret); + } + + return devmem; + +error_devm_add_action: + hmm_devmem_ref_kill(&devmem->ref); + hmm_devmem_ref_exit(&devmem->ref); +error_percpu_ref: + devres_free(devmem); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(hmm_devmem_add_resource); + +/* + * hmm_devmem_remove() - remove device memory (kill and free ZONE_DEVICE) + * + * @devmem: hmm_devmem struct use to track and manage the ZONE_DEVICE memory + * + * This will hot-unplug memory that was hotplugged by hmm_devmem_add on behalf + * of the device driver. It will free struct page and remove the resource that + * reserved the physical address range for this device memory. + */ +void hmm_devmem_remove(struct hmm_devmem *devmem) +{ + resource_size_t start, size; + struct device *device; + bool cdm = false; + + if (!devmem) + return; + + device = devmem->device; + start = devmem->resource->start; + size = resource_size(devmem->resource); + + cdm = devmem->resource->desc == IORES_DESC_DEVICE_PUBLIC_MEMORY; + hmm_devmem_ref_kill(&devmem->ref); + hmm_devmem_ref_exit(&devmem->ref); + hmm_devmem_pages_remove(devmem); + + if (!cdm) + devm_release_mem_region(device, start, size); +} +EXPORT_SYMBOL(hmm_devmem_remove); + +/* + * A device driver that wants to handle multiple devices memory through a + * single fake device can use hmm_device to do so. This is purely a helper + * and it is not needed to make use of any HMM functionality. + */ +#define HMM_DEVICE_MAX 256 + +static DECLARE_BITMAP(hmm_device_mask, HMM_DEVICE_MAX); +static DEFINE_SPINLOCK(hmm_device_lock); +static struct class *hmm_device_class; +static dev_t hmm_device_devt; + +static void hmm_device_release(struct device *device) +{ + struct hmm_device *hmm_device; + + hmm_device = container_of(device, struct hmm_device, device); + spin_lock(&hmm_device_lock); + clear_bit(hmm_device->minor, hmm_device_mask); + spin_unlock(&hmm_device_lock); + + kfree(hmm_device); +} + +struct hmm_device *hmm_device_new(void *drvdata) +{ + struct hmm_device *hmm_device; + + hmm_device = kzalloc(sizeof(*hmm_device), GFP_KERNEL); + if (!hmm_device) + return ERR_PTR(-ENOMEM); + + spin_lock(&hmm_device_lock); + hmm_device->minor = find_first_zero_bit(hmm_device_mask, HMM_DEVICE_MAX); + if (hmm_device->minor >= HMM_DEVICE_MAX) { + spin_unlock(&hmm_device_lock); + kfree(hmm_device); + return ERR_PTR(-EBUSY); + } + set_bit(hmm_device->minor, hmm_device_mask); + spin_unlock(&hmm_device_lock); + + dev_set_name(&hmm_device->device, "hmm_device%d", hmm_device->minor); + hmm_device->device.devt = MKDEV(MAJOR(hmm_device_devt), + hmm_device->minor); + hmm_device->device.release = hmm_device_release; + dev_set_drvdata(&hmm_device->device, drvdata); + hmm_device->device.class = hmm_device_class; + device_initialize(&hmm_device->device); + + return hmm_device; +} +EXPORT_SYMBOL(hmm_device_new); + +void hmm_device_put(struct hmm_device *hmm_device) +{ + put_device(&hmm_device->device); +} +EXPORT_SYMBOL(hmm_device_put); + +static int __init hmm_init(void) +{ + int ret; + + ret = alloc_chrdev_region(&hmm_device_devt, 0, + HMM_DEVICE_MAX, + "hmm_device"); + if (ret) + return ret; + + hmm_device_class = class_create(THIS_MODULE, "hmm_device"); + if (IS_ERR(hmm_device_class)) { + unregister_chrdev_region(hmm_device_devt, HMM_DEVICE_MAX); + return PTR_ERR(hmm_device_class); + } + return 0; +} + +device_initcall(hmm_init); +#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 86975dec0ba160feadfb8aa0d13b8f2be943638d..269b5df58543e44d6a283c6268036f010aad37c2 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -327,7 +328,7 @@ static struct attribute *hugepage_attr[] = { NULL, }; -static struct attribute_group hugepage_attr_group = { +static const struct attribute_group hugepage_attr_group = { .attrs = hugepage_attr, }; @@ -550,6 +551,7 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page, struct mem_cgroup *memcg; pgtable_t pgtable; unsigned long haddr = vmf->address & HPAGE_PMD_MASK; + int ret = 0; VM_BUG_ON_PAGE(!PageCompound(page), page); @@ -561,12 +563,11 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page, pgtable = pte_alloc_one(vma->vm_mm, haddr); if (unlikely(!pgtable)) { - mem_cgroup_cancel_charge(page, memcg, true); - put_page(page); - return VM_FAULT_OOM; + ret = VM_FAULT_OOM; + goto release; } - clear_huge_page(page, haddr, HPAGE_PMD_NR); + clear_huge_page(page, vmf->address, HPAGE_PMD_NR); /* * The memory barrier inside __SetPageUptodate makes sure that * clear_huge_page writes become visible before the set_pmd_at() @@ -576,13 +577,14 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page, vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); if (unlikely(!pmd_none(*vmf->pmd))) { - spin_unlock(vmf->ptl); - mem_cgroup_cancel_charge(page, memcg, true); - put_page(page); - pte_free(vma->vm_mm, pgtable); + goto unlock_release; } else { pmd_t entry; + ret = check_stable_address_space(vma->vm_mm); + if (ret) + goto unlock_release; + /* Deliver the page fault to userland */ if (userfaultfd_missing(vma)) { int ret; @@ -610,6 +612,15 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page, } return 0; +unlock_release: + spin_unlock(vmf->ptl); +release: + if (pgtable) + pte_free(vma->vm_mm, pgtable); + mem_cgroup_cancel_charge(page, memcg, true); + put_page(page); + return ret; + } /* @@ -688,7 +699,10 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) ret = 0; set = false; if (pmd_none(*vmf->pmd)) { - if (userfaultfd_missing(vma)) { + ret = check_stable_address_space(vma->vm_mm); + if (ret) { + spin_unlock(vmf->ptl); + } else if (userfaultfd_missing(vma)) { spin_unlock(vmf->ptl); ret = handle_userfault(vmf, VM_UFFD_MISSING); VM_BUG_ON(ret & VM_FAULT_FALLBACK); @@ -914,6 +928,25 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm, ret = -EAGAIN; pmd = *src_pmd; + +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + if (unlikely(is_swap_pmd(pmd))) { + swp_entry_t entry = pmd_to_swp_entry(pmd); + + VM_BUG_ON(!is_pmd_migration_entry(pmd)); + if (is_write_migration_entry(entry)) { + make_migration_entry_read(&entry); + pmd = swp_entry_to_pmd(entry); + if (pmd_swp_soft_dirty(*src_pmd)) + pmd = pmd_swp_mksoft_dirty(pmd); + set_pmd_at(src_mm, addr, src_pmd, pmd); + } + set_pmd_at(dst_mm, addr, dst_pmd, pmd); + ret = 0; + goto out_unlock; + } +#endif + if (unlikely(!pmd_trans_huge(pmd))) { pte_free(dst_mm, pgtable); goto out_unlock; @@ -1226,15 +1259,29 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) * We can only reuse the page if nobody else maps the huge page or it's * part. */ - if (page_trans_huge_mapcount(page, NULL) == 1) { + if (!trylock_page(page)) { + get_page(page); + spin_unlock(vmf->ptl); + lock_page(page); + spin_lock(vmf->ptl); + if (unlikely(!pmd_same(*vmf->pmd, orig_pmd))) { + unlock_page(page); + put_page(page); + goto out_unlock; + } + put_page(page); + } + if (reuse_swap_page(page, NULL)) { pmd_t entry; entry = pmd_mkyoung(orig_pmd); entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); if (pmdp_set_access_flags(vma, haddr, vmf->pmd, entry, 1)) update_mmu_cache_pmd(vma, vmf->address, vmf->pmd); ret |= VM_FAULT_WRITE; + unlock_page(page); goto out_unlock; } + unlock_page(page); get_page(page); spin_unlock(vmf->ptl); alloc: @@ -1277,7 +1324,7 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) count_vm_event(THP_FAULT_ALLOC); if (!page) - clear_huge_page(new_page, haddr, HPAGE_PMD_NR); + clear_huge_page(new_page, vmf->address, HPAGE_PMD_NR); else copy_user_huge_page(new_page, page, haddr, vma, HPAGE_PMD_NR); __SetPageUptodate(new_page); @@ -1495,11 +1542,26 @@ int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd) goto clear_pmdnuma; } + /* + * Since we took the NUMA fault, we must have observed the !accessible + * bit. Make sure all other CPUs agree with that, to avoid them + * modifying the page we're about to migrate. + * + * Must be done under PTL such that we'll observe the relevant + * inc_tlb_flush_pending(). + * + * We are not sure a pending tlb flush here is for a huge page + * mapping or not. Hence use the tlb range variant + */ + if (mm_tlb_flush_pending(vma->vm_mm)) + flush_tlb_range(vma, haddr, haddr + HPAGE_PMD_SIZE); + /* * Migrate the THP to the requested node, returns with page unlocked * and access rights restored. */ spin_unlock(vmf->ptl); + migrated = migrate_misplaced_transhuge_page(vma->vm_mm, vma, vmf->pmd, pmd, vmf->address, page, target_nid); if (migrated) { @@ -1556,6 +1618,12 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, if (is_huge_zero_pmd(orig_pmd)) goto out; + if (unlikely(!pmd_present(orig_pmd))) { + VM_BUG_ON(thp_migration_supported() && + !is_pmd_migration_entry(orig_pmd)); + goto out; + } + page = pmd_page(orig_pmd); /* * If other processes are mapping this page, we couldn't discard @@ -1641,10 +1709,24 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, spin_unlock(ptl); tlb_remove_page_size(tlb, pmd_page(orig_pmd), HPAGE_PMD_SIZE); } else { - struct page *page = pmd_page(orig_pmd); - page_remove_rmap(page, true); - VM_BUG_ON_PAGE(page_mapcount(page) < 0, page); - VM_BUG_ON_PAGE(!PageHead(page), page); + struct page *page = NULL; + int flush_needed = 1; + + if (pmd_present(orig_pmd)) { + page = pmd_page(orig_pmd); + page_remove_rmap(page, true); + VM_BUG_ON_PAGE(page_mapcount(page) < 0, page); + VM_BUG_ON_PAGE(!PageHead(page), page); + } else if (thp_migration_supported()) { + swp_entry_t entry; + + VM_BUG_ON(!is_pmd_migration_entry(orig_pmd)); + entry = pmd_to_swp_entry(orig_pmd); + page = pfn_to_page(swp_offset(entry)); + flush_needed = 0; + } else + WARN_ONCE(1, "Non present huge pmd without pmd migration enabled!"); + if (PageAnon(page)) { zap_deposited_table(tlb->mm, pmd); add_mm_counter(tlb->mm, MM_ANONPAGES, -HPAGE_PMD_NR); @@ -1653,8 +1735,10 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, zap_deposited_table(tlb->mm, pmd); add_mm_counter(tlb->mm, MM_FILEPAGES, -HPAGE_PMD_NR); } + spin_unlock(ptl); - tlb_remove_page_size(tlb, page, HPAGE_PMD_SIZE); + if (flush_needed) + tlb_remove_page_size(tlb, page, HPAGE_PMD_SIZE); } return 1; } @@ -1674,6 +1758,17 @@ static inline int pmd_move_must_withdraw(spinlock_t *new_pmd_ptl, } #endif +static pmd_t move_soft_dirty_pmd(pmd_t pmd) +{ +#ifdef CONFIG_MEM_SOFT_DIRTY + if (unlikely(is_pmd_migration_entry(pmd))) + pmd = pmd_swp_mksoft_dirty(pmd); + else if (pmd_present(pmd)) + pmd = pmd_mksoft_dirty(pmd); +#endif + return pmd; +} + bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, unsigned long new_addr, unsigned long old_end, pmd_t *old_pmd, pmd_t *new_pmd, bool *need_flush) @@ -1716,7 +1811,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, pgtable = pgtable_trans_huge_withdraw(mm, old_pmd); pgtable_trans_huge_deposit(mm, new_pmd, pgtable); } - set_pmd_at(mm, new_addr, new_pmd, pmd_mksoft_dirty(pmd)); + pmd = move_soft_dirty_pmd(pmd); + set_pmd_at(mm, new_addr, new_pmd, pmd); if (new_ptl != old_ptl) spin_unlock(new_ptl); if (force_flush) @@ -1751,6 +1847,27 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, preserve_write = prot_numa && pmd_write(*pmd); ret = 1; +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + if (is_swap_pmd(*pmd)) { + swp_entry_t entry = pmd_to_swp_entry(*pmd); + + VM_BUG_ON(!is_pmd_migration_entry(*pmd)); + if (is_write_migration_entry(entry)) { + pmd_t newpmd; + /* + * A protection check is difficult so + * just be safe and disable write + */ + make_migration_entry_read(&entry); + newpmd = swp_entry_to_pmd(entry); + if (pmd_swp_soft_dirty(*pmd)) + newpmd = pmd_swp_mksoft_dirty(newpmd); + set_pmd_at(mm, addr, pmd, newpmd); + } + goto unlock; + } +#endif + /* * Avoid trapping faults against the zero page. The read-only * data is likely to be read-cached on the local CPU and @@ -1816,7 +1933,8 @@ spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma) { spinlock_t *ptl; ptl = pmd_lock(vma->vm_mm, pmd); - if (likely(pmd_trans_huge(*pmd) || pmd_devmap(*pmd))) + if (likely(is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || + pmd_devmap(*pmd))) return ptl; spin_unlock(ptl); return NULL; @@ -1934,14 +2052,15 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, struct page *page; pgtable_t pgtable; pmd_t _pmd; - bool young, write, dirty, soft_dirty; + bool young, write, dirty, soft_dirty, pmd_migration = false; unsigned long addr; int i; VM_BUG_ON(haddr & ~HPAGE_PMD_MASK); VM_BUG_ON_VMA(vma->vm_start > haddr, vma); VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PMD_SIZE, vma); - VM_BUG_ON(!pmd_trans_huge(*pmd) && !pmd_devmap(*pmd)); + VM_BUG_ON(!is_pmd_migration_entry(*pmd) && !pmd_trans_huge(*pmd) + && !pmd_devmap(*pmd)); count_vm_event(THP_SPLIT_PMD); @@ -1966,7 +2085,16 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, return __split_huge_zero_page_pmd(vma, haddr, pmd); } - page = pmd_page(*pmd); +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + pmd_migration = is_pmd_migration_entry(*pmd); + if (pmd_migration) { + swp_entry_t entry; + + entry = pmd_to_swp_entry(*pmd); + page = pfn_to_page(swp_offset(entry)); + } else +#endif + page = pmd_page(*pmd); VM_BUG_ON_PAGE(!page_count(page), page); page_ref_add(page, HPAGE_PMD_NR - 1); write = pmd_write(*pmd); @@ -1985,7 +2113,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, * transferred to avoid any possibility of altering * permissions across VMAs. */ - if (freeze) { + if (freeze || pmd_migration) { swp_entry_t swp_entry; swp_entry = make_migration_entry(page + i, write); entry = swp_entry_to_pte(swp_entry); @@ -2084,7 +2212,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, page = pmd_page(*pmd); if (PageMlocked(page)) clear_page_mlock(page); - } else if (!pmd_devmap(*pmd)) + } else if (!(pmd_devmap(*pmd) || is_pmd_migration_entry(*pmd))) goto out; __split_huge_pmd_locked(vma, pmd, haddr, freeze); out: @@ -2167,7 +2295,7 @@ static void freeze_page(struct page *page) VM_BUG_ON_PAGE(!PageHead(page), page); if (PageAnon(page)) - ttu_flags |= TTU_MIGRATION; + ttu_flags |= TTU_SPLIT_FREEZE; unmap_success = try_to_unmap(page, ttu_flags); VM_BUG_ON_PAGE(!unmap_success, page); @@ -2438,6 +2566,9 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) VM_BUG_ON_PAGE(!PageLocked(page), page); VM_BUG_ON_PAGE(!PageCompound(page), page); + if (PageWriteback(page)) + return -EBUSY; + if (PageAnon(head)) { /* * The caller does not necessarily hold an mmap_sem that would @@ -2515,7 +2646,12 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) __dec_node_page_state(page, NR_SHMEM_THPS); spin_unlock(&pgdata->split_queue_lock); __split_huge_page(page, list, flags); - ret = 0; + if (PageSwapCache(head)) { + swp_entry_t entry = { .val = page_private(head) }; + + ret = split_swap_cluster(entry); + } else + ret = 0; } else { if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) { pr_alert("total_mapcount: %u, page_count(): %u\n", @@ -2694,3 +2830,66 @@ static int __init split_huge_pages_debugfs(void) } late_initcall(split_huge_pages_debugfs); #endif + +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +void set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, + struct page *page) +{ + struct vm_area_struct *vma = pvmw->vma; + struct mm_struct *mm = vma->vm_mm; + unsigned long address = pvmw->address; + pmd_t pmdval; + swp_entry_t entry; + pmd_t pmdswp; + + if (!(pvmw->pmd && !pvmw->pte)) + return; + + mmu_notifier_invalidate_range_start(mm, address, + address + HPAGE_PMD_SIZE); + + flush_cache_range(vma, address, address + HPAGE_PMD_SIZE); + pmdval = *pvmw->pmd; + pmdp_invalidate(vma, address, pvmw->pmd); + if (pmd_dirty(pmdval)) + set_page_dirty(page); + entry = make_migration_entry(page, pmd_write(pmdval)); + pmdswp = swp_entry_to_pmd(entry); + if (pmd_soft_dirty(pmdval)) + pmdswp = pmd_swp_mksoft_dirty(pmdswp); + set_pmd_at(mm, address, pvmw->pmd, pmdswp); + page_remove_rmap(page, true); + put_page(page); + + mmu_notifier_invalidate_range_end(mm, address, + address + HPAGE_PMD_SIZE); +} + +void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new) +{ + struct vm_area_struct *vma = pvmw->vma; + struct mm_struct *mm = vma->vm_mm; + unsigned long address = pvmw->address; + unsigned long mmun_start = address & HPAGE_PMD_MASK; + pmd_t pmde; + swp_entry_t entry; + + if (!(pvmw->pmd && !pvmw->pte)) + return; + + entry = pmd_to_swp_entry(*pvmw->pmd); + get_page(new); + pmde = pmd_mkold(mk_huge_pmd(new, vma->vm_page_prot)); + if (pmd_swp_soft_dirty(*pvmw->pmd)) + pmde = pmd_mksoft_dirty(pmde); + if (is_write_migration_entry(entry)) + pmde = maybe_pmd_mkwrite(pmde, vma); + + flush_cache_range(vma, mmun_start, mmun_start + HPAGE_PMD_SIZE); + page_add_anon_rmap(new, vma, mmun_start, true); + set_pmd_at(mm, mmun_start, pvmw->pmd, pmde); + if (vma->vm_flags & VM_LOCKED) + mlock_vma_page(new); + update_mmu_cache_pmd(vma, address, pvmw->pmd); +} +#endif diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bc48ee783dd9e1e31f03a4b0393ef2902ea00a6e..424b0ef08a60cb616d40e9249e5447287c1705e3 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1066,11 +1066,11 @@ static void free_gigantic_page(struct page *page, unsigned int order) } static int __alloc_gigantic_page(unsigned long start_pfn, - unsigned long nr_pages) + unsigned long nr_pages, gfp_t gfp_mask) { unsigned long end_pfn = start_pfn + nr_pages; return alloc_contig_range(start_pfn, end_pfn, MIGRATE_MOVABLE, - GFP_KERNEL); + gfp_mask); } static bool pfn_range_valid_gigantic(struct zone *z, @@ -1108,19 +1108,24 @@ static bool zone_spans_last_pfn(const struct zone *zone, return zone_spans_pfn(zone, last_pfn); } -static struct page *alloc_gigantic_page(int nid, unsigned int order) +static struct page *alloc_gigantic_page(int nid, struct hstate *h) { + unsigned int order = huge_page_order(h); unsigned long nr_pages = 1 << order; unsigned long ret, pfn, flags; - struct zone *z; + struct zonelist *zonelist; + struct zone *zone; + struct zoneref *z; + gfp_t gfp_mask; - z = NODE_DATA(nid)->node_zones; - for (; z - NODE_DATA(nid)->node_zones < MAX_NR_ZONES; z++) { - spin_lock_irqsave(&z->lock, flags); + gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE; + zonelist = node_zonelist(nid, gfp_mask); + for_each_zone_zonelist_nodemask(zone, z, zonelist, gfp_zone(gfp_mask), NULL) { + spin_lock_irqsave(&zone->lock, flags); - pfn = ALIGN(z->zone_start_pfn, nr_pages); - while (zone_spans_last_pfn(z, pfn, nr_pages)) { - if (pfn_range_valid_gigantic(z, pfn, nr_pages)) { + pfn = ALIGN(zone->zone_start_pfn, nr_pages); + while (zone_spans_last_pfn(zone, pfn, nr_pages)) { + if (pfn_range_valid_gigantic(zone, pfn, nr_pages)) { /* * We release the zone lock here because * alloc_contig_range() will also lock the zone @@ -1128,16 +1133,16 @@ static struct page *alloc_gigantic_page(int nid, unsigned int order) * spinning on this lock, it may win the race * and cause alloc_contig_range() to fail... */ - spin_unlock_irqrestore(&z->lock, flags); - ret = __alloc_gigantic_page(pfn, nr_pages); + spin_unlock_irqrestore(&zone->lock, flags); + ret = __alloc_gigantic_page(pfn, nr_pages, gfp_mask); if (!ret) return pfn_to_page(pfn); - spin_lock_irqsave(&z->lock, flags); + spin_lock_irqsave(&zone->lock, flags); } pfn += nr_pages; } - spin_unlock_irqrestore(&z->lock, flags); + spin_unlock_irqrestore(&zone->lock, flags); } return NULL; @@ -1150,7 +1155,7 @@ static struct page *alloc_fresh_gigantic_page_node(struct hstate *h, int nid) { struct page *page; - page = alloc_gigantic_page(nid, huge_page_order(h)); + page = alloc_gigantic_page(nid, h); if (page) { prep_compound_gigantic_page(page, huge_page_order(h)); prep_new_huge_page(h, page, nid); @@ -2083,7 +2088,9 @@ struct page *alloc_huge_page_noerr(struct vm_area_struct *vma, return page; } -int __weak alloc_bootmem_huge_page(struct hstate *h) +int alloc_bootmem_huge_page(struct hstate *h) + __attribute__ ((weak, alias("__alloc_bootmem_huge_page"))); +int __alloc_bootmem_huge_page(struct hstate *h) { struct huge_bootmem_page *m; int nr_nodes, node; @@ -2569,13 +2576,13 @@ static struct attribute *hstate_attrs[] = { NULL, }; -static struct attribute_group hstate_attr_group = { +static const struct attribute_group hstate_attr_group = { .attrs = hstate_attrs, }; static int hugetlb_sysfs_add_hstate(struct hstate *h, struct kobject *parent, struct kobject **hstate_kobjs, - struct attribute_group *hstate_attr_group) + const struct attribute_group *hstate_attr_group) { int retval; int hi = hstate_index(h); @@ -2633,7 +2640,7 @@ static struct attribute *per_node_hstate_attrs[] = { NULL, }; -static struct attribute_group per_node_hstate_attr_group = { +static const struct attribute_group per_node_hstate_attr_group = { .attrs = per_node_hstate_attrs, }; @@ -4062,9 +4069,9 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm, return ret; out_release_unlock: spin_unlock(ptl); -out_release_nounlock: if (vm_shared) unlock_page(page); +out_release_nounlock: put_page(page); goto out; } @@ -4078,6 +4085,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long vaddr = *position; unsigned long remainder = *nr_pages; struct hstate *h = hstate_vma(vma); + int err = -EFAULT; while (vaddr < vma->vm_end && remainder) { pte_t *pte; @@ -4154,11 +4162,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, } ret = hugetlb_fault(mm, vma, vaddr, fault_flags); if (ret & VM_FAULT_ERROR) { - int err = vm_fault_to_errno(ret, flags); - - if (err) - return err; - + err = vm_fault_to_errno(ret, flags); remainder = 0; break; } @@ -4213,7 +4217,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, */ *position = vaddr; - return i ? i : -EFAULT; + return i ? i : err; } #ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE @@ -4603,6 +4607,15 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, return pte; } +/* + * huge_pte_offset() - Walk the page table to resolve the hugepage + * entry at address @addr + * + * Return: Pointer to page table or swap entry (PUD or PMD) for + * address @addr, or NULL if a p*d_none() entry is encountered and the + * size @sz doesn't match the hugepage size at this level of the page + * table. + */ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz) { @@ -4617,13 +4630,22 @@ pte_t *huge_pte_offset(struct mm_struct *mm, p4d = p4d_offset(pgd, addr); if (!p4d_present(*p4d)) return NULL; + pud = pud_offset(p4d, addr); - if (!pud_present(*pud)) + if (sz != PUD_SIZE && pud_none(*pud)) return NULL; - if (pud_huge(*pud)) + /* hugepage or swap? */ + if (pud_huge(*pud) || !pud_present(*pud)) return (pte_t *)pud; + pmd = pmd_offset(pud, addr); - return (pte_t *) pmd; + if (sz != PMD_SIZE && pmd_none(*pmd)) + return NULL; + /* hugepage or swap? */ + if (pmd_huge(*pmd) || !pmd_present(*pmd)) + return (pte_t *)pmd; + + return NULL; } #endif /* CONFIG_ARCH_WANT_GENERAL_HUGETLB */ diff --git a/mm/internal.h b/mm/internal.h index 24d88f0847059ebc028ce9fc9eabce90caae40b9..1df011f624801ffbdf3379a6d17218d9b32280e1 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -480,6 +480,17 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone, /* Mask to get the watermark bits */ #define ALLOC_WMARK_MASK (ALLOC_NO_WATERMARKS-1) +/* + * Only MMU archs have async oom victim reclaim - aka oom_reaper so we + * cannot assume a reduced access to memory reserves is sufficient for + * !MMU + */ +#ifdef CONFIG_MMU +#define ALLOC_OOM 0x08 +#else +#define ALLOC_OOM ALLOC_NO_WATERMARKS +#endif + #define ALLOC_HARDER 0x10 /* try to alloc harder */ #define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ #define ALLOC_CPUSET 0x40 /* check for correct cpuset */ @@ -498,6 +509,7 @@ extern struct workqueue_struct *mm_percpu_wq; #ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH void try_to_unmap_flush(void); void try_to_unmap_flush_dirty(void); +void flush_tlb_batched_pending(struct mm_struct *mm); #else static inline void try_to_unmap_flush(void) { @@ -505,7 +517,9 @@ static inline void try_to_unmap_flush(void) static inline void try_to_unmap_flush_dirty(void) { } - +static inline void flush_tlb_batched_pending(struct mm_struct *mm) +{ +} #endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */ extern const struct trace_print_flags pageflag_names[]; @@ -522,4 +536,5 @@ static inline bool is_migrate_highatomic_page(struct page *page) return get_pageblock_migratetype(page) == MIGRATE_HIGHATOMIC; } +void setup_zone_pageset(struct zone *zone); #endif /* __MM_INTERNAL_H */ diff --git a/mm/interval_tree.c b/mm/interval_tree.c index f2c2492681bf14ae49456b8353965ca3c73002d1..b476643587966102e90813663b2039461d1dc679 100644 --- a/mm/interval_tree.c +++ b/mm/interval_tree.c @@ -28,7 +28,7 @@ INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.rb, /* Insert node immediately after prev in the interval tree */ void vma_interval_tree_insert_after(struct vm_area_struct *node, struct vm_area_struct *prev, - struct rb_root *root) + struct rb_root_cached *root) { struct rb_node **link; struct vm_area_struct *parent; @@ -55,7 +55,7 @@ void vma_interval_tree_insert_after(struct vm_area_struct *node, node->shared.rb_subtree_last = last; rb_link_node(&node->shared.rb, &parent->shared.rb, link); - rb_insert_augmented(&node->shared.rb, root, + rb_insert_augmented(&node->shared.rb, &root->rb_root, &vma_interval_tree_augment); } @@ -74,7 +74,7 @@ INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, unsigned long, rb_subtree_last, static inline, __anon_vma_interval_tree) void anon_vma_interval_tree_insert(struct anon_vma_chain *node, - struct rb_root *root) + struct rb_root_cached *root) { #ifdef CONFIG_DEBUG_VM_RB node->cached_vma_start = avc_start_pgoff(node); @@ -84,13 +84,13 @@ void anon_vma_interval_tree_insert(struct anon_vma_chain *node, } void anon_vma_interval_tree_remove(struct anon_vma_chain *node, - struct rb_root *root) + struct rb_root_cached *root) { __anon_vma_interval_tree_remove(node, root); } struct anon_vma_chain * -anon_vma_interval_tree_iter_first(struct rb_root *root, +anon_vma_interval_tree_iter_first(struct rb_root_cached *root, unsigned long first, unsigned long last) { return __anon_vma_interval_tree_iter_first(root, first, last); diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c index ca11bc4ce2050ab476a9b25ebf19c7b860921caf..6f319fb817186e4b5c9ef62ff8a715bc28a0e292 100644 --- a/mm/kasan/kasan.c +++ b/mm/kasan/kasan.c @@ -267,13 +267,13 @@ static void check_memory_region(unsigned long addr, check_memory_region_inline(addr, size, write, ret_ip); } -void kasan_check_read(const void *p, unsigned int size) +void kasan_check_read(const volatile void *p, unsigned int size) { check_memory_region((unsigned long)p, size, false, _RET_IP_); } EXPORT_SYMBOL(kasan_check_read); -void kasan_check_write(const void *p, unsigned int size) +void kasan_check_write(const volatile void *p, unsigned int size) { check_memory_region((unsigned long)p, size, true, _RET_IP_); } diff --git a/mm/kasan/report.c b/mm/kasan/report.c index 04bb1d3eb9ece0480182f2c738ed9d827fea3c62..6bcfb01ba0386e5bf2ec49512321e59a1fac0661 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -401,6 +401,7 @@ void kasan_report(unsigned long addr, size_t size, disable_trace_on_warning(); info.access_addr = (void *)addr; + info.first_bad_addr = (void *)addr; info.access_size = size; info.is_write = is_write; info.ip = ip; diff --git a/mm/ksm.c b/mm/ksm.c index 4dc92f138786988c4ef0f9d371ff8a48b2e6e905..6cb60f46cce55761b0ff9d3523be69a706523972 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -1038,7 +1038,8 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, goto out_unlock; if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) || - (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte))) { + (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte)) || + mm_tlb_flush_pending(mm)) { pte_t entry; swapped = PageSwapCache(page); @@ -1989,6 +1990,7 @@ static void stable_tree_append(struct rmap_item *rmap_item, */ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item) { + struct mm_struct *mm = rmap_item->mm; struct rmap_item *tree_rmap_item; struct page *tree_page = NULL; struct stable_node *stable_node; @@ -2061,9 +2063,11 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item) if (ksm_use_zero_pages && (checksum == zero_checksum)) { struct vm_area_struct *vma; - vma = find_mergeable_vma(rmap_item->mm, rmap_item->address); + down_read(&mm->mmap_sem); + vma = find_mergeable_vma(mm, rmap_item->address); err = try_to_merge_one_page(vma, page, ZERO_PAGE(rmap_item->address)); + up_read(&mm->mmap_sem); /* * In case of failure, the page was not really empty, so we * need to continue. Otherwise we're done. @@ -3042,7 +3046,7 @@ static struct attribute *ksm_attrs[] = { NULL, }; -static struct attribute_group ksm_attr_group = { +static const struct attribute_group ksm_attr_group = { .attrs = ksm_attrs, .name = "ksm", }; diff --git a/mm/list_lru.c b/mm/list_lru.c index 7a40fa2be858acbc79cc79d887c1af575a3d2026..f141f0c80ff338f9c2a5a5244afca23440f9bdc3 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -325,12 +325,12 @@ static int memcg_init_list_lru_node(struct list_lru_node *nlru) { int size = memcg_nr_cache_ids; - nlru->memcg_lrus = kmalloc(size * sizeof(void *), GFP_KERNEL); + nlru->memcg_lrus = kvmalloc(size * sizeof(void *), GFP_KERNEL); if (!nlru->memcg_lrus) return -ENOMEM; if (__memcg_init_list_lru_node(nlru->memcg_lrus, 0, size)) { - kfree(nlru->memcg_lrus); + kvfree(nlru->memcg_lrus); return -ENOMEM; } @@ -340,7 +340,7 @@ static int memcg_init_list_lru_node(struct list_lru_node *nlru) static void memcg_destroy_list_lru_node(struct list_lru_node *nlru) { __memcg_destroy_list_lru_node(nlru->memcg_lrus, 0, memcg_nr_cache_ids); - kfree(nlru->memcg_lrus); + kvfree(nlru->memcg_lrus); } static int memcg_update_list_lru_node(struct list_lru_node *nlru, @@ -351,12 +351,12 @@ static int memcg_update_list_lru_node(struct list_lru_node *nlru, BUG_ON(old_size > new_size); old = nlru->memcg_lrus; - new = kmalloc(new_size * sizeof(void *), GFP_KERNEL); + new = kvmalloc(new_size * sizeof(void *), GFP_KERNEL); if (!new) return -ENOMEM; if (__memcg_init_list_lru_node(new, old_size, new_size)) { - kfree(new); + kvfree(new); return -ENOMEM; } @@ -373,7 +373,7 @@ static int memcg_update_list_lru_node(struct list_lru_node *nlru, nlru->memcg_lrus = new; spin_unlock_irq(&nlru->lock); - kfree(old); + kvfree(old); return 0; } diff --git a/mm/madvise.c b/mm/madvise.c index 9976852f1e1cb25c986cf69c1846ba8f17e981fd..25bade36e9caa5702e092348d9b260c79e6477b4 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -80,6 +80,17 @@ static long madvise_behavior(struct vm_area_struct *vma, } new_flags &= ~VM_DONTCOPY; break; + case MADV_WIPEONFORK: + /* MADV_WIPEONFORK is only supported on anonymous memory. */ + if (vma->vm_file || vma->vm_flags & VM_SHARED) { + error = -EINVAL; + goto out; + } + new_flags |= VM_WIPEONFORK; + break; + case MADV_KEEPONFORK: + new_flags &= ~VM_WIPEONFORK; + break; case MADV_DONTDUMP: new_flags |= VM_DONTDUMP; break; @@ -320,6 +331,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr, tlb_remove_check_page_size_change(tlb, PAGE_SIZE); orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl); + flush_tlb_batched_pending(mm); arch_enter_lazy_mmu_mode(); for (; addr != end; pte++, addr += PAGE_SIZE) { ptent = *pte; @@ -343,7 +355,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr, continue; } - page = vm_normal_page(vma, addr, ptent); + page = _vm_normal_page(vma, addr, ptent, true); if (!page) continue; @@ -367,8 +379,8 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr, pte_offset_map_lock(mm, pmd, addr, &ptl); goto out; } - put_page(page); unlock_page(page); + put_page(page); pte = pte_offset_map_lock(mm, pmd, addr, &ptl); pte--; addr -= PAGE_SIZE; @@ -612,18 +624,27 @@ static int madvise_inject_error(int behavior, unsigned long start, unsigned long end) { struct page *page; + struct zone *zone; + unsigned int order; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - for (; start < end; start += PAGE_SIZE << - compound_order(compound_head(page))) { + + for (; start < end; start += PAGE_SIZE << order) { int ret; ret = get_user_pages_fast(start, 1, 0, &page); if (ret != 1) return ret; + /* + * When soft offlining hugepages, after migrating the page + * we dissolve it, therefore in the second loop "page" will + * no longer be a compound page, and order will be 0. + */ + order = compound_order(compound_head(page)); + if (PageHWPoison(page)) { put_page(page); continue; @@ -645,6 +666,11 @@ static int madvise_inject_error(int behavior, if (ret) return ret; } + + /* Ensure that all poisoned pages are removed from per-cpu lists */ + for_each_populated_zone(zone) + drain_all_pages(zone); + return 0; } #endif @@ -689,6 +715,8 @@ madvise_behavior_valid(int behavior) #endif case MADV_DONTDUMP: case MADV_DODUMP: + case MADV_WIPEONFORK: + case MADV_KEEPONFORK: #ifdef CONFIG_MEMORY_FAILURE case MADV_SOFT_OFFLINE: case MADV_HWPOISON: diff --git a/mm/memblock.c b/mm/memblock.c index 2cb25fe4452c279c5ff6ff74cbbfee64128d820e..91205780e6b151f8239574c5f97b8d5ebc89b59f 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -285,31 +285,27 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u } #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK - -phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info( - phys_addr_t *addr) -{ - if (memblock.reserved.regions == memblock_reserved_init_regions) - return 0; - - *addr = __pa(memblock.reserved.regions); - - return PAGE_ALIGN(sizeof(struct memblock_region) * - memblock.reserved.max); -} - -phys_addr_t __init_memblock get_allocated_memblock_memory_regions_info( - phys_addr_t *addr) +/** + * Discard memory and reserved arrays if they were allocated + */ +void __init memblock_discard(void) { - if (memblock.memory.regions == memblock_memory_init_regions) - return 0; + phys_addr_t addr, size; - *addr = __pa(memblock.memory.regions); + if (memblock.reserved.regions != memblock_reserved_init_regions) { + addr = __pa(memblock.reserved.regions); + size = PAGE_ALIGN(sizeof(struct memblock_region) * + memblock.reserved.max); + __memblock_free_late(addr, size); + } - return PAGE_ALIGN(sizeof(struct memblock_region) * - memblock.memory.max); + if (memblock.memory.regions != memblock_memory_init_regions) { + addr = __pa(memblock.memory.regions); + size = PAGE_ALIGN(sizeof(struct memblock_region) * + memblock.memory.max); + __memblock_free_late(addr, size); + } } - #endif /** diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 3df3c04d73ab08e3bbb663f25b2e195b396d2149..d5f3a62887cf958f6b657c0f542f0cf2c3e86e8d 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -119,6 +119,7 @@ static const char *const mem_cgroup_lru_names[] = { struct mem_cgroup_tree_per_node { struct rb_root rb_root; + struct rb_node *rb_rightmost; spinlock_t lock; }; @@ -386,6 +387,7 @@ static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_node *mz, struct rb_node **p = &mctz->rb_root.rb_node; struct rb_node *parent = NULL; struct mem_cgroup_per_node *mz_node; + bool rightmost = true; if (mz->on_tree) return; @@ -397,8 +399,11 @@ static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_node *mz, parent = *p; mz_node = rb_entry(parent, struct mem_cgroup_per_node, tree_node); - if (mz->usage_in_excess < mz_node->usage_in_excess) + if (mz->usage_in_excess < mz_node->usage_in_excess) { p = &(*p)->rb_left; + rightmost = false; + } + /* * We can't avoid mem cgroups that are over their soft * limit by the same amount @@ -406,6 +411,10 @@ static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_node *mz, else if (mz->usage_in_excess >= mz_node->usage_in_excess) p = &(*p)->rb_right; } + + if (rightmost) + mctz->rb_rightmost = &mz->tree_node; + rb_link_node(&mz->tree_node, parent, p); rb_insert_color(&mz->tree_node, &mctz->rb_root); mz->on_tree = true; @@ -416,6 +425,10 @@ static void __mem_cgroup_remove_exceeded(struct mem_cgroup_per_node *mz, { if (!mz->on_tree) return; + + if (&mz->tree_node == mctz->rb_rightmost) + mctz->rb_rightmost = rb_prev(&mz->tree_node); + rb_erase(&mz->tree_node, &mctz->rb_root); mz->on_tree = false; } @@ -496,16 +509,15 @@ static void mem_cgroup_remove_from_trees(struct mem_cgroup *memcg) static struct mem_cgroup_per_node * __mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz) { - struct rb_node *rightmost = NULL; struct mem_cgroup_per_node *mz; retry: mz = NULL; - rightmost = rb_last(&mctz->rb_root); - if (!rightmost) + if (!mctz->rb_rightmost) goto done; /* Nothing to reclaim from */ - mz = rb_entry(rightmost, struct mem_cgroup_per_node, tree_node); + mz = rb_entry(mctz->rb_rightmost, + struct mem_cgroup_per_node, tree_node); /* * Remove the node now but someone else can add it back, * we will to add it back at the end of reclaim to its correct @@ -550,10 +562,12 @@ mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz) * value, and reading all cpu value can be performance bottleneck in some * common workload, threshold and synchronization as vmstat[] should be * implemented. + * + * The parameter idx can be of type enum memcg_event_item or vm_event_item. */ static unsigned long memcg_sum_events(struct mem_cgroup *memcg, - enum memcg_event_item event) + int event) { unsigned long val = 0; int cpu; @@ -917,7 +931,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg, struct css_task_iter it; struct task_struct *task; - css_task_iter_start(&iter->css, &it); + css_task_iter_start(&iter->css, 0, &it); while (!ret && (task = css_task_iter_next(&it))) ret = fn(task, arg); css_task_iter_end(&it); @@ -1611,9 +1625,13 @@ bool mem_cgroup_oom_synchronize(bool handle) * @page: the page * * This function protects unlocked LRU pages from being moved to - * another cgroup and stabilizes their page->mem_cgroup binding. + * another cgroup. + * + * It ensures lifetime of the returned memcg. Caller is responsible + * for the lifetime of the page; __unlock_page_memcg() is available + * when @page might get freed inside the locked section. */ -void lock_page_memcg(struct page *page) +struct mem_cgroup *lock_page_memcg(struct page *page) { struct mem_cgroup *memcg; unsigned long flags; @@ -1622,18 +1640,24 @@ void lock_page_memcg(struct page *page) * The RCU lock is held throughout the transaction. The fast * path can get away without acquiring the memcg->move_lock * because page moving starts with an RCU grace period. - */ + * + * The RCU lock also protects the memcg from being freed when + * the page state that is going to change is the only thing + * preventing the page itself from being freed. E.g. writeback + * doesn't hold a page reference and relies on PG_writeback to + * keep off truncation, migration and so forth. + */ rcu_read_lock(); if (mem_cgroup_disabled()) - return; + return NULL; again: memcg = page->mem_cgroup; if (unlikely(!memcg)) - return; + return NULL; if (atomic_read(&memcg->moving_account) <= 0) - return; + return memcg; spin_lock_irqsave(&memcg->move_lock, flags); if (memcg != page->mem_cgroup) { @@ -1649,18 +1673,18 @@ void lock_page_memcg(struct page *page) memcg->move_lock_task = current; memcg->move_lock_flags = flags; - return; + return memcg; } EXPORT_SYMBOL(lock_page_memcg); /** - * unlock_page_memcg - unlock a page->mem_cgroup binding - * @page: the page + * __unlock_page_memcg - unlock and unpin a memcg + * @memcg: the memcg + * + * Unlock and unpin a memcg returned by lock_page_memcg(). */ -void unlock_page_memcg(struct page *page) +void __unlock_page_memcg(struct mem_cgroup *memcg) { - struct mem_cgroup *memcg = page->mem_cgroup; - if (memcg && memcg->move_lock_task == current) { unsigned long flags = memcg->move_lock_flags; @@ -1672,6 +1696,15 @@ void unlock_page_memcg(struct page *page) rcu_read_unlock(); } + +/** + * unlock_page_memcg - unlock a page->mem_cgroup binding + * @page: the page + */ +void unlock_page_memcg(struct page *page) +{ + __unlock_page_memcg(page->mem_cgroup); +} EXPORT_SYMBOL(unlock_page_memcg); /* @@ -1744,6 +1777,10 @@ static void drain_local_stock(struct work_struct *dummy) struct memcg_stock_pcp *stock; unsigned long flags; + /* + * The only protection from memory hotplug vs. drain_stock races is + * that we always operate on local CPU stock here with IRQ disabled + */ local_irq_save(flags); stock = this_cpu_ptr(&memcg_stock); @@ -1771,6 +1808,9 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) } stock->nr_pages += nr_pages; + if (stock->nr_pages > CHARGE_BATCH) + drain_stock(stock); + local_irq_restore(flags); } @@ -1785,27 +1825,33 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) /* If someone's already draining, avoid adding running more workers. */ if (!mutex_trylock(&percpu_charge_mutex)) return; - /* Notify other cpus that system-wide "drain" is running */ - get_online_cpus(); + /* + * Notify other cpus that system-wide "drain" is running + * We do not care about races with the cpu hotplug because cpu down + * as well as workers from this path always operate on the local + * per-cpu data. CPU up doesn't touch memcg_stock at all. + */ curcpu = get_cpu(); for_each_online_cpu(cpu) { struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); struct mem_cgroup *memcg; memcg = stock->cached; - if (!memcg || !stock->nr_pages) + if (!memcg || !stock->nr_pages || !css_tryget(&memcg->css)) continue; - if (!mem_cgroup_is_descendant(memcg, root_memcg)) + if (!mem_cgroup_is_descendant(memcg, root_memcg)) { + css_put(&memcg->css); continue; + } if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) { if (cpu == curcpu) drain_local_stock(&stock->work); else schedule_work_on(cpu, &stock->work); } + css_put(&memcg->css); } put_cpu(); - put_online_cpus(); mutex_unlock(&percpu_charge_mutex); } @@ -1896,7 +1942,7 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, * bypass the last charges so that they can exit quickly and * free their memory. */ - if (unlikely(test_thread_flag(TIF_MEMDIE) || + if (unlikely(tsk_is_oom_victim(current) || fatal_signal_pending(current) || current->flags & PF_EXITING)) goto force; @@ -4300,6 +4346,8 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css) } spin_unlock(&memcg->event_list_lock); + memcg->low = 0; + memcg_offline_kmem(memcg); wb_memcg_offline(memcg); @@ -4391,12 +4439,13 @@ enum mc_target_type { MC_TARGET_NONE = 0, MC_TARGET_PAGE, MC_TARGET_SWAP, + MC_TARGET_DEVICE, }; static struct page *mc_handle_present_pte(struct vm_area_struct *vma, unsigned long addr, pte_t ptent) { - struct page *page = vm_normal_page(vma, addr, ptent); + struct page *page = _vm_normal_page(vma, addr, ptent, true); if (!page || !page_mapped(page)) return NULL; @@ -4413,7 +4462,7 @@ static struct page *mc_handle_present_pte(struct vm_area_struct *vma, return page; } -#ifdef CONFIG_SWAP +#if defined(CONFIG_SWAP) || defined(CONFIG_DEVICE_PRIVATE) static struct page *mc_handle_swap_pte(struct vm_area_struct *vma, pte_t ptent, swp_entry_t *entry) { @@ -4422,6 +4471,23 @@ static struct page *mc_handle_swap_pte(struct vm_area_struct *vma, if (!(mc.flags & MOVE_ANON) || non_swap_entry(ent)) return NULL; + + /* + * Handle MEMORY_DEVICE_PRIVATE which are ZONE_DEVICE page belonging to + * a device and because they are not accessible by CPU they are store + * as special swap entry in the CPU page table. + */ + if (is_device_private_entry(ent)) { + page = device_private_entry_to_page(ent); + /* + * MEMORY_DEVICE_PRIVATE means ZONE_DEVICE page and which have + * a refcount of 1 when free (unlike normal page) + */ + if (!page_ref_add_unless(page, 1, 1)) + return NULL; + return page; + } + /* * Because lookup_swap_cache() updates some statistics counter, * we call find_get_page() with swapper_space directly. @@ -4582,6 +4648,13 @@ static int mem_cgroup_move_account(struct page *page, * 2(MC_TARGET_SWAP): if the swap entry corresponding to this pte is a * target for charge migration. if @target is not NULL, the entry is stored * in target->ent. + * 3(MC_TARGET_DEVICE): like MC_TARGET_PAGE but page is MEMORY_DEVICE_PUBLIC + * or MEMORY_DEVICE_PRIVATE (so ZONE_DEVICE page and thus not on the lru). + * For now we such page is charge like a regular page would be as for all + * intent and purposes it is just special memory taking the place of a + * regular page. + * + * See Documentations/vm/hmm.txt and include/linux/hmm.h * * Called with pte lock held. */ @@ -4610,14 +4683,20 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma, */ if (page->mem_cgroup == mc.from) { ret = MC_TARGET_PAGE; + if (is_device_private_page(page) || + is_device_public_page(page)) + ret = MC_TARGET_DEVICE; if (target) target->page = page; } if (!ret || !target) put_page(page); } - /* There is a swap entry and a page doesn't exist or isn't charged */ - if (ent.val && !ret && + /* + * There is a swap entry and a page doesn't exist or isn't charged. + * But we cannot move a tail-page in a THP. + */ + if (ent.val && !ret && (!page || !PageTransCompound(page)) && mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) { ret = MC_TARGET_SWAP; if (target) @@ -4628,8 +4707,8 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma, #ifdef CONFIG_TRANSPARENT_HUGEPAGE /* - * We don't consider swapping or file mapped pages because THP does not - * support them for now. + * We don't consider PMD mapped swapping or file mapped pages because THP does + * not support them for now. * Caller should make sure that pmd_trans_huge(pmd) is true. */ static enum mc_target_type get_mctgt_type_thp(struct vm_area_struct *vma, @@ -4638,6 +4717,11 @@ static enum mc_target_type get_mctgt_type_thp(struct vm_area_struct *vma, struct page *page = NULL; enum mc_target_type ret = MC_TARGET_NONE; + if (unlikely(is_swap_pmd(pmd))) { + VM_BUG_ON(thp_migration_supported() && + !is_pmd_migration_entry(pmd)); + return ret; + } page = pmd_page(pmd); VM_BUG_ON_PAGE(!page || !PageHead(page), page); if (!(mc.flags & MOVE_ANON)) @@ -4669,6 +4753,11 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd, ptl = pmd_trans_huge_lock(pmd, vma); if (ptl) { + /* + * Note their can not be MC_TARGET_DEVICE for now as we do not + * support transparent huge page with MEMORY_DEVICE_PUBLIC or + * MEMORY_DEVICE_PRIVATE but this might change. + */ if (get_mctgt_type_thp(vma, addr, *pmd, NULL) == MC_TARGET_PAGE) mc.precharge += HPAGE_PMD_NR; spin_unlock(ptl); @@ -4884,6 +4973,14 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd, putback_lru_page(page); } put_page(page); + } else if (target_type == MC_TARGET_DEVICE) { + page = target.page; + if (!mem_cgroup_move_account(page, true, + mc.from, mc.to)) { + mc.precharge -= HPAGE_PMD_NR; + mc.moved_charge += HPAGE_PMD_NR; + } + put_page(page); } spin_unlock(ptl); return 0; @@ -4895,12 +4992,16 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd, pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); for (; addr != end; addr += PAGE_SIZE) { pte_t ptent = *(pte++); + bool device = false; swp_entry_t ent; if (!mc.precharge) break; switch (get_mctgt_type(vma, addr, ptent, &target)) { + case MC_TARGET_DEVICE: + device = true; + /* fall through */ case MC_TARGET_PAGE: page = target.page; /* @@ -4911,7 +5012,7 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd, */ if (PageTransCompound(page)) goto put; - if (isolate_lru_page(page)) + if (!device && isolate_lru_page(page)) goto put; if (!mem_cgroup_move_account(page, false, mc.from, mc.to)) { @@ -4919,7 +5020,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd, /* we uncharge from mc.from later. */ mc.moved_charge++; } - putback_lru_page(page); + if (!device) + putback_lru_page(page); put: /* get_mctgt_type() gets the page */ put_page(page); break; @@ -5404,7 +5506,7 @@ int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm, * in turn serializes uncharging. */ VM_BUG_ON_PAGE(!PageLocked(page), page); - if (page->mem_cgroup) + if (compound_head(page)->mem_cgroup) goto out; if (do_swap_account) { @@ -5509,48 +5611,103 @@ void mem_cgroup_cancel_charge(struct page *page, struct mem_cgroup *memcg, cancel_charge(memcg, nr_pages); } -static void uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout, - unsigned long nr_anon, unsigned long nr_file, - unsigned long nr_kmem, unsigned long nr_huge, - unsigned long nr_shmem, struct page *dummy_page) +struct uncharge_gather { + struct mem_cgroup *memcg; + unsigned long pgpgout; + unsigned long nr_anon; + unsigned long nr_file; + unsigned long nr_kmem; + unsigned long nr_huge; + unsigned long nr_shmem; + struct page *dummy_page; +}; + +static inline void uncharge_gather_clear(struct uncharge_gather *ug) +{ + memset(ug, 0, sizeof(*ug)); +} + +static void uncharge_batch(const struct uncharge_gather *ug) { - unsigned long nr_pages = nr_anon + nr_file + nr_kmem; + unsigned long nr_pages = ug->nr_anon + ug->nr_file + ug->nr_kmem; unsigned long flags; - if (!mem_cgroup_is_root(memcg)) { - page_counter_uncharge(&memcg->memory, nr_pages); + if (!mem_cgroup_is_root(ug->memcg)) { + page_counter_uncharge(&ug->memcg->memory, nr_pages); if (do_memsw_account()) - page_counter_uncharge(&memcg->memsw, nr_pages); - if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && nr_kmem) - page_counter_uncharge(&memcg->kmem, nr_kmem); - memcg_oom_recover(memcg); + page_counter_uncharge(&ug->memcg->memsw, nr_pages); + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && ug->nr_kmem) + page_counter_uncharge(&ug->memcg->kmem, ug->nr_kmem); + memcg_oom_recover(ug->memcg); } local_irq_save(flags); - __this_cpu_sub(memcg->stat->count[MEMCG_RSS], nr_anon); - __this_cpu_sub(memcg->stat->count[MEMCG_CACHE], nr_file); - __this_cpu_sub(memcg->stat->count[MEMCG_RSS_HUGE], nr_huge); - __this_cpu_sub(memcg->stat->count[NR_SHMEM], nr_shmem); - __this_cpu_add(memcg->stat->events[PGPGOUT], pgpgout); - __this_cpu_add(memcg->stat->nr_page_events, nr_pages); - memcg_check_events(memcg, dummy_page); + __this_cpu_sub(ug->memcg->stat->count[MEMCG_RSS], ug->nr_anon); + __this_cpu_sub(ug->memcg->stat->count[MEMCG_CACHE], ug->nr_file); + __this_cpu_sub(ug->memcg->stat->count[MEMCG_RSS_HUGE], ug->nr_huge); + __this_cpu_sub(ug->memcg->stat->count[NR_SHMEM], ug->nr_shmem); + __this_cpu_add(ug->memcg->stat->events[PGPGOUT], ug->pgpgout); + __this_cpu_add(ug->memcg->stat->nr_page_events, nr_pages); + memcg_check_events(ug->memcg, ug->dummy_page); local_irq_restore(flags); - if (!mem_cgroup_is_root(memcg)) - css_put_many(&memcg->css, nr_pages); + if (!mem_cgroup_is_root(ug->memcg)) + css_put_many(&ug->memcg->css, nr_pages); +} + +static void uncharge_page(struct page *page, struct uncharge_gather *ug) +{ + VM_BUG_ON_PAGE(PageLRU(page), page); + VM_BUG_ON_PAGE(page_count(page) && !is_zone_device_page(page) && + !PageHWPoison(page) , page); + + if (!page->mem_cgroup) + return; + + /* + * Nobody should be changing or seriously looking at + * page->mem_cgroup at this point, we have fully + * exclusive access to the page. + */ + + if (ug->memcg != page->mem_cgroup) { + if (ug->memcg) { + uncharge_batch(ug); + uncharge_gather_clear(ug); + } + ug->memcg = page->mem_cgroup; + } + + if (!PageKmemcg(page)) { + unsigned int nr_pages = 1; + + if (PageTransHuge(page)) { + nr_pages <<= compound_order(page); + ug->nr_huge += nr_pages; + } + if (PageAnon(page)) + ug->nr_anon += nr_pages; + else { + ug->nr_file += nr_pages; + if (PageSwapBacked(page)) + ug->nr_shmem += nr_pages; + } + ug->pgpgout++; + } else { + ug->nr_kmem += 1 << compound_order(page); + __ClearPageKmemcg(page); + } + + ug->dummy_page = page; + page->mem_cgroup = NULL; } static void uncharge_list(struct list_head *page_list) { - struct mem_cgroup *memcg = NULL; - unsigned long nr_shmem = 0; - unsigned long nr_anon = 0; - unsigned long nr_file = 0; - unsigned long nr_huge = 0; - unsigned long nr_kmem = 0; - unsigned long pgpgout = 0; + struct uncharge_gather ug; struct list_head *next; - struct page *page; + + uncharge_gather_clear(&ug); /* * Note that the list can be a single page->lru; hence the @@ -5558,57 +5715,16 @@ static void uncharge_list(struct list_head *page_list) */ next = page_list->next; do { + struct page *page; + page = list_entry(next, struct page, lru); next = page->lru.next; - VM_BUG_ON_PAGE(PageLRU(page), page); - VM_BUG_ON_PAGE(!PageHWPoison(page) && page_count(page), page); - - if (!page->mem_cgroup) - continue; - - /* - * Nobody should be changing or seriously looking at - * page->mem_cgroup at this point, we have fully - * exclusive access to the page. - */ - - if (memcg != page->mem_cgroup) { - if (memcg) { - uncharge_batch(memcg, pgpgout, nr_anon, nr_file, - nr_kmem, nr_huge, nr_shmem, page); - pgpgout = nr_anon = nr_file = nr_kmem = 0; - nr_huge = nr_shmem = 0; - } - memcg = page->mem_cgroup; - } - - if (!PageKmemcg(page)) { - unsigned int nr_pages = 1; - - if (PageTransHuge(page)) { - nr_pages <<= compound_order(page); - nr_huge += nr_pages; - } - if (PageAnon(page)) - nr_anon += nr_pages; - else { - nr_file += nr_pages; - if (PageSwapBacked(page)) - nr_shmem += nr_pages; - } - pgpgout++; - } else { - nr_kmem += 1 << compound_order(page); - __ClearPageKmemcg(page); - } - - page->mem_cgroup = NULL; + uncharge_page(page, &ug); } while (next != page_list); - if (memcg) - uncharge_batch(memcg, pgpgout, nr_anon, nr_file, - nr_kmem, nr_huge, nr_shmem, page); + if (ug.memcg) + uncharge_batch(&ug); } /** @@ -5620,6 +5736,8 @@ static void uncharge_list(struct list_head *page_list) */ void mem_cgroup_uncharge(struct page *page) { + struct uncharge_gather ug; + if (mem_cgroup_disabled()) return; @@ -5627,8 +5745,9 @@ void mem_cgroup_uncharge(struct page *page) if (!page->mem_cgroup) return; - INIT_LIST_HEAD(&page->lru); - uncharge_list(&page->lru); + uncharge_gather_clear(&ug); + uncharge_page(page, &ug); + uncharge_batch(&ug); } /** @@ -5793,8 +5912,7 @@ void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) this_cpu_sub(memcg->stat->count[MEMCG_SOCK], nr_pages); - page_counter_uncharge(&memcg->memory, nr_pages); - css_put_many(&memcg->css, nr_pages); + refill_stock(memcg, nr_pages); } static int __init cgroup_memory(char *s) @@ -5850,6 +5968,7 @@ static int __init mem_cgroup_init(void) node_online(node) ? node : NUMA_NO_NODE); rtpn->rb_root = RB_ROOT; + rtpn->rb_rightmost = NULL; spin_lock_init(&rtpn->lock); soft_limit_tree.rb_tree_per_node[node] = rtpn; } @@ -5887,6 +6006,7 @@ static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) void mem_cgroup_swapout(struct page *page, swp_entry_t entry) { struct mem_cgroup *memcg, *swap_memcg; + unsigned int nr_entries; unsigned short oldid; VM_BUG_ON_PAGE(PageLRU(page), page); @@ -5907,19 +6027,24 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) * ancestor for the swap instead and transfer the memory+swap charge. */ swap_memcg = mem_cgroup_id_get_online(memcg); - oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), 1); + nr_entries = hpage_nr_pages(page); + /* Get references for the tail pages, too */ + if (nr_entries > 1) + mem_cgroup_id_get_many(swap_memcg, nr_entries - 1); + oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), + nr_entries); VM_BUG_ON_PAGE(oldid, page); - mem_cgroup_swap_statistics(swap_memcg, 1); + mem_cgroup_swap_statistics(swap_memcg, nr_entries); page->mem_cgroup = NULL; if (!mem_cgroup_is_root(memcg)) - page_counter_uncharge(&memcg->memory, 1); + page_counter_uncharge(&memcg->memory, nr_entries); if (memcg != swap_memcg) { if (!mem_cgroup_is_root(swap_memcg)) - page_counter_charge(&swap_memcg->memsw, 1); - page_counter_uncharge(&memcg->memsw, 1); + page_counter_charge(&swap_memcg->memsw, nr_entries); + page_counter_uncharge(&memcg->memsw, nr_entries); } /* @@ -5929,7 +6054,8 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) * only synchronisation we have for udpating the per-CPU variables. */ VM_BUG_ON(!irqs_disabled()); - mem_cgroup_charge_statistics(memcg, page, false, -1); + mem_cgroup_charge_statistics(memcg, page, PageTransHuge(page), + -nr_entries); memcg_check_events(memcg, page); if (!mem_cgroup_is_root(memcg)) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 1cd3b3569af8a79285b75bfdb2485b7de7a69aa8..88366626c0b7c790d92514f32cb3cea701dd0ffb 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1146,6 +1146,8 @@ int memory_failure(unsigned long pfn, int trapno, int flags) return 0; } + arch_unmap_kpfn(pfn); + orig_head = hpage = compound_head(p); num_poisoned_pages_inc(); diff --git a/mm/memory.c b/mm/memory.c index 0e517be91a89e162bb868af9835c8641aadfd01b..a728bed16c206902de6498921a1d130d141ff7b7 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ #include #include #include +#include #include #include @@ -215,12 +217,8 @@ static bool tlb_next_batch(struct mmu_gather *tlb) return true; } -/* tlb_gather_mmu - * Called to initialize an (on-stack) mmu_gather structure for page-table - * tear-down from @mm. The @fullmm argument is used when @mm is without - * users and we're going to destroy the full address space (exit/execve). - */ -void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) +void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) { tlb->mm = mm; @@ -275,10 +273,14 @@ void tlb_flush_mmu(struct mmu_gather *tlb) * Called at the end of the shootdown operation to free up any resources * that were required. */ -void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +void arch_tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end, bool force) { struct mmu_gather_batch *batch, *next; + if (force) + __tlb_adjust_range(tlb, start, end - start); + tlb_flush_mmu(tlb); /* keep the page table cache within bounds */ @@ -398,6 +400,34 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) #endif /* CONFIG_HAVE_RCU_TABLE_FREE */ +/* tlb_gather_mmu + * Called to initialize an (on-stack) mmu_gather structure for page-table + * tear-down from @mm. The @fullmm argument is used when @mm is without + * users and we're going to destroy the full address space (exit/execve). + */ +void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + arch_tlb_gather_mmu(tlb, mm, start, end); + inc_tlb_flush_pending(tlb->mm); +} + +void tlb_finish_mmu(struct mmu_gather *tlb, + unsigned long start, unsigned long end) +{ + /* + * If there are parallel threads are doing PTE changes on same range + * under non-exclusive lock(e.g., mmap_sem read-side) but defer TLB + * flush by batching, a thread has stable TLB entry can fail to flush + * the TLB by observing pte_none|!pte_dirty, for example so flush TLB + * forcefully if we detect parallel PTE batching threads. + */ + bool force = mm_tlb_flush_nested(tlb->mm); + + arch_tlb_finish_mmu(tlb, start, end, force); + dec_tlb_flush_pending(tlb->mm); +} + /* * Note: this doesn't free the actual pages themselves. That * has been handled earlier when unmapping all the memory regions. @@ -788,8 +818,8 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr, #else # define HAVE_PTE_SPECIAL 0 #endif -struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, - pte_t pte) +struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr, + pte_t pte, bool with_public_device) { unsigned long pfn = pte_pfn(pte); @@ -800,8 +830,31 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, return vma->vm_ops->find_special_page(vma, addr); if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return NULL; - if (!is_zero_pfn(pfn)) - print_bad_pte(vma, addr, pte, NULL); + if (is_zero_pfn(pfn)) + return NULL; + + /* + * Device public pages are special pages (they are ZONE_DEVICE + * pages but different from persistent memory). They behave + * allmost like normal pages. The difference is that they are + * not on the lru and thus should never be involve with any- + * thing that involve lru manipulation (mlock, numa balancing, + * ...). + * + * This is why we still want to return NULL for such page from + * vm_normal_page() so that we do not have to special case all + * call site of vm_normal_page(). + */ + if (likely(pfn <= highest_memmap_pfn)) { + struct page *page = pfn_to_page(pfn); + + if (is_device_public_page(page)) { + if (with_public_device) + return page; + return NULL; + } + } + print_bad_pte(vma, addr, pte, NULL); return NULL; } @@ -927,6 +980,35 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, pte = pte_swp_mksoft_dirty(pte); set_pte_at(src_mm, addr, src_pte, pte); } + } else if (is_device_private_entry(entry)) { + page = device_private_entry_to_page(entry); + + /* + * Update rss count even for unaddressable pages, as + * they should treated just like normal pages in this + * respect. + * + * We will likely want to have some new rss counters + * for unaddressable pages, at some point. But for now + * keep things as they are. + */ + get_page(page); + rss[mm_counter(page)]++; + page_dup_rmap(page, false); + + /* + * We do not preserve soft-dirty information, because so + * far, checkpoint/restore is the only feature that + * requires that. And checkpoint/restore does not work + * when a device driver is involved (you cannot easily + * save and restore device driver state). + */ + if (is_write_device_private_entry(entry) && + is_cow_mapping(vm_flags)) { + make_device_private_entry_read(&entry); + pte = swp_entry_to_pte(entry); + set_pte_at(src_mm, addr, src_pte, pte); + } } goto out_set_pte; } @@ -953,6 +1035,19 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, get_page(page); page_dup_rmap(page, false); rss[mm_counter(page)]++; + } else if (pte_devmap(pte)) { + page = pte_page(pte); + + /* + * Cache coherent device memory behave like regular page and + * not like persistent memory page. For more informations see + * MEMORY_DEVICE_CACHE_COHERENT in memory_hotplug.h + */ + if (is_device_public_page(page)) { + get_page(page); + page_dup_rmap(page, false); + rss[mm_counter(page)]++; + } } out_set_pte: @@ -1036,7 +1131,8 @@ static inline int copy_pmd_range(struct mm_struct *dst_mm, struct mm_struct *src src_pmd = pmd_offset(src_pud, addr); do { next = pmd_addr_end(addr, end); - if (pmd_trans_huge(*src_pmd) || pmd_devmap(*src_pmd)) { + if (is_swap_pmd(*src_pmd) || pmd_trans_huge(*src_pmd) + || pmd_devmap(*src_pmd)) { int err; VM_BUG_ON_VMA(next-addr != HPAGE_PMD_SIZE, vma); err = copy_huge_pmd(dst_mm, src_mm, @@ -1197,6 +1293,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, init_rss_vec(rss); start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl); pte = start_pte; + flush_tlb_batched_pending(mm); arch_enter_lazy_mmu_mode(); do { pte_t ptent = *pte; @@ -1206,7 +1303,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, if (pte_present(ptent)) { struct page *page; - page = vm_normal_page(vma, addr, ptent); + page = _vm_normal_page(vma, addr, ptent, true); if (unlikely(details) && page) { /* * unmap_shared_mapping_pages() wants to @@ -1243,6 +1340,29 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, } continue; } + + entry = pte_to_swp_entry(ptent); + if (non_swap_entry(entry) && is_device_private_entry(entry)) { + struct page *page = device_private_entry_to_page(entry); + + if (unlikely(details && details->check_mapping)) { + /* + * unmap_shared_mapping_pages() wants to + * invalidate cache without truncating: + * unmap shared but keep private pages. + */ + if (details->check_mapping != + page_rmapping(page)) + continue; + } + + pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); + rss[mm_counter(page)]--; + page_remove_rmap(page, false); + put_page(page); + continue; + } + /* If details->check_mapping, we leave swap entries. */ if (unlikely(details)) continue; @@ -1296,7 +1416,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, pmd = pmd_offset(pud, addr); do { next = pmd_addr_end(addr, end); - if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { + if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { if (next - addr != HPAGE_PMD_SIZE) { VM_BUG_ON_VMA(vma_is_anonymous(vma) && !rwsem_is_locked(&tlb->mm->mmap_sem), vma); @@ -1483,8 +1603,20 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start, tlb_gather_mmu(&tlb, mm, start, end); update_hiwater_rss(mm); mmu_notifier_invalidate_range_start(mm, start, end); - for ( ; vma && vma->vm_start < end; vma = vma->vm_next) + for ( ; vma && vma->vm_start < end; vma = vma->vm_next) { unmap_single_vma(&tlb, vma, start, end, NULL); + + /* + * zap_page_range does not specify whether mmap_sem should be + * held for read or write. That allows parallel zap_page_range + * operations to unmap a PTE and defer a flush meaning that + * this call observes pte_none and fails to flush the TLB. + * Rather than adding a complex API, ensure that no stale + * TLB entries exist when this call returns. + */ + flush_tlb_range(vma, start, end); + } + mmu_notifier_invalidate_range_end(mm, start, end); tlb_finish_mmu(&tlb, start, end); } @@ -1646,7 +1778,7 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, EXPORT_SYMBOL(vm_insert_page); static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, - pfn_t pfn, pgprot_t prot) + pfn_t pfn, pgprot_t prot, bool mkwrite) { struct mm_struct *mm = vma->vm_mm; int retval; @@ -1658,14 +1790,35 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, if (!pte) goto out; retval = -EBUSY; - if (!pte_none(*pte)) - goto out_unlock; + if (!pte_none(*pte)) { + if (mkwrite) { + /* + * For read faults on private mappings the PFN passed + * in may not match the PFN we have mapped if the + * mapped PFN is a writeable COW page. In the mkwrite + * case we are creating a writable PTE for a shared + * mapping and we expect the PFNs to match. + */ + if (WARN_ON_ONCE(pte_pfn(*pte) != pfn_t_to_pfn(pfn))) + goto out_unlock; + entry = *pte; + goto out_mkwrite; + } else + goto out_unlock; + } /* Ok, finally just insert the thing.. */ if (pfn_t_devmap(pfn)) entry = pte_mkdevmap(pfn_t_pte(pfn, prot)); else entry = pte_mkspecial(pfn_t_pte(pfn, prot)); + +out_mkwrite: + if (mkwrite) { + entry = pte_mkyoung(entry); + entry = maybe_mkwrite(pte_mkdirty(entry), vma); + } + set_pte_at(mm, addr, pte, entry); update_mmu_cache(vma, addr, pte); /* XXX: why not for insert_page? */ @@ -1736,14 +1889,15 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, track_pfn_insert(vma, &pgprot, __pfn_to_pfn_t(pfn, PFN_DEV)); - ret = insert_pfn(vma, addr, __pfn_to_pfn_t(pfn, PFN_DEV), pgprot); + ret = insert_pfn(vma, addr, __pfn_to_pfn_t(pfn, PFN_DEV), pgprot, + false); return ret; } EXPORT_SYMBOL(vm_insert_pfn_prot); -int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, - pfn_t pfn) +static int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, + pfn_t pfn, bool mkwrite) { pgprot_t pgprot = vma->vm_page_prot; @@ -1772,10 +1926,24 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, page = pfn_to_page(pfn_t_to_pfn(pfn)); return insert_page(vma, addr, page, pgprot); } - return insert_pfn(vma, addr, pfn, pgprot); + return insert_pfn(vma, addr, pfn, pgprot, mkwrite); +} + +int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, + pfn_t pfn) +{ + return __vm_insert_mixed(vma, addr, pfn, false); + } EXPORT_SYMBOL(vm_insert_mixed); +int vm_insert_mixed_mkwrite(struct vm_area_struct *vma, unsigned long addr, + pfn_t pfn) +{ + return __vm_insert_mixed(vma, addr, pfn, true); +} +EXPORT_SYMBOL(vm_insert_mixed_mkwrite); + /* * maps a range of physical memory into the requested pages. the old * mappings are removed. any references to nonexistent pages results @@ -2541,7 +2709,7 @@ static int do_wp_page(struct vm_fault *vmf) * not dirty accountable. */ if (PageAnon(vmf->page) && !PageKsm(vmf->page)) { - int total_mapcount; + int total_map_swapcount; if (!trylock_page(vmf->page)) { get_page(vmf->page); pte_unmap_unlock(vmf->pte, vmf->ptl); @@ -2556,8 +2724,8 @@ static int do_wp_page(struct vm_fault *vmf) } put_page(vmf->page); } - if (reuse_swap_page(vmf->page, &total_mapcount)) { - if (total_mapcount == 1) { + if (reuse_swap_page(vmf->page, &total_map_swapcount)) { + if (total_map_swapcount == 1) { /* * The page is all ours. Move it to * our anon_vma so the rmap code will @@ -2593,7 +2761,7 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma, zap_page_range_single(vma, start_addr, end_addr - start_addr, details); } -static inline void unmap_mapping_range_tree(struct rb_root *root, +static inline void unmap_mapping_range_tree(struct rb_root_cached *root, struct zap_details *details) { struct vm_area_struct *vma; @@ -2657,7 +2825,7 @@ void unmap_mapping_range(struct address_space *mapping, details.last_index = ULONG_MAX; i_mmap_lock_write(mapping); - if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap))) + if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))) unmap_mapping_range_tree(&mapping->i_mmap, &details); i_mmap_unlock_write(mapping); } @@ -2674,22 +2842,37 @@ EXPORT_SYMBOL(unmap_mapping_range); int do_swap_page(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; - struct page *page, *swapcache; + struct page *page = NULL, *swapcache; struct mem_cgroup *memcg; + struct vma_swap_readahead swap_ra; swp_entry_t entry; pte_t pte; int locked; int exclusive = 0; int ret = 0; + bool vma_readahead = swap_use_vma_readahead(); - if (!pte_unmap_same(vma->vm_mm, vmf->pmd, vmf->pte, vmf->orig_pte)) + if (vma_readahead) + page = swap_readahead_detect(vmf, &swap_ra); + if (!pte_unmap_same(vma->vm_mm, vmf->pmd, vmf->pte, vmf->orig_pte)) { + if (page) + put_page(page); goto out; + } entry = pte_to_swp_entry(vmf->orig_pte); if (unlikely(non_swap_entry(entry))) { if (is_migration_entry(entry)) { migration_entry_wait(vma->vm_mm, vmf->pmd, vmf->address); + } else if (is_device_private_entry(entry)) { + /* + * For un-addressable device memory we call the pgmap + * fault handler callback. The callback must migrate + * the page back to some CPU accessible page. + */ + ret = device_private_entry_fault(vma, vmf->address, entry, + vmf->flags, vmf->pmd); } else if (is_hwpoison_entry(entry)) { ret = VM_FAULT_HWPOISON; } else { @@ -2699,10 +2882,16 @@ int do_swap_page(struct vm_fault *vmf) goto out; } delayacct_set_flag(DELAYACCT_PF_SWAPIN); - page = lookup_swap_cache(entry); + if (!page) + page = lookup_swap_cache(entry, vma_readahead ? vma : NULL, + vmf->address); if (!page) { - page = swapin_readahead(entry, GFP_HIGHUSER_MOVABLE, vma, - vmf->address); + if (vma_readahead) + page = do_swap_page_readahead(entry, + GFP_HIGHUSER_MOVABLE, vmf, &swap_ra); + else + page = swapin_readahead(entry, + GFP_HIGHUSER_MOVABLE, vma, vmf->address); if (!page) { /* * Back out if somebody else faulted in this pte @@ -2864,6 +3053,7 @@ static int do_anonymous_page(struct vm_fault *vmf) struct vm_area_struct *vma = vmf->vma; struct mem_cgroup *memcg; struct page *page; + int ret = 0; pte_t entry; /* File mapping without ->vm_ops ? */ @@ -2896,6 +3086,9 @@ static int do_anonymous_page(struct vm_fault *vmf) vmf->address, &vmf->ptl); if (!pte_none(*vmf->pte)) goto unlock; + ret = check_stable_address_space(vma->vm_mm); + if (ret) + goto unlock; /* Deliver the page fault to userland, check inside PT lock */ if (userfaultfd_missing(vma)) { pte_unmap_unlock(vmf->pte, vmf->ptl); @@ -2930,6 +3123,10 @@ static int do_anonymous_page(struct vm_fault *vmf) if (!pte_none(*vmf->pte)) goto release; + ret = check_stable_address_space(vma->vm_mm); + if (ret) + goto release; + /* Deliver the page fault to userland, check inside PT lock */ if (userfaultfd_missing(vma)) { pte_unmap_unlock(vmf->pte, vmf->ptl); @@ -2949,7 +3146,7 @@ static int do_anonymous_page(struct vm_fault *vmf) update_mmu_cache(vma, vmf->address, vmf->pte); unlock: pte_unmap_unlock(vmf->pte, vmf->ptl); - return 0; + return ret; release: mem_cgroup_cancel_charge(page, memcg, false); put_page(page); @@ -3223,7 +3420,7 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, int finish_fault(struct vm_fault *vmf) { struct page *page; - int ret; + int ret = 0; /* Did we COW the page? */ if ((vmf->flags & FAULT_FLAG_WRITE) && @@ -3231,7 +3428,15 @@ int finish_fault(struct vm_fault *vmf) page = vmf->cow_page; else page = vmf->page; - ret = alloc_set_pte(vmf, vmf->memcg, page); + + /* + * check even for read faults because we might have lost our CoWed + * page + */ + if (!(vmf->vma->vm_flags & VM_SHARED)) + ret = check_stable_address_space(vmf->vma->vm_mm); + if (!ret) + ret = alloc_set_pte(vmf, vmf->memcg, page); if (vmf->pte) pte_unmap_unlock(vmf->pte, vmf->ptl); return ret; @@ -3756,6 +3961,7 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address, .pgoff = linear_page_index(vma, address), .gfp_mask = __get_fault_gfp_mask(vma), }; + unsigned int dirty = flags & FAULT_FLAG_WRITE; struct mm_struct *mm = vma->vm_mm; pgd_t *pgd; p4d_t *p4d; @@ -3778,7 +3984,6 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address, barrier(); if (pud_trans_huge(orig_pud) || pud_devmap(orig_pud)) { - unsigned int dirty = flags & FAULT_FLAG_WRITE; /* NUMA case for anonymous PUDs would go here */ @@ -3804,12 +4009,18 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address, pmd_t orig_pmd = *vmf.pmd; barrier(); + if (unlikely(is_swap_pmd(orig_pmd))) { + VM_BUG_ON(thp_migration_supported() && + !is_pmd_migration_entry(orig_pmd)); + if (is_pmd_migration_entry(orig_pmd)) + pmd_migration_entry_wait(mm, vmf.pmd); + return 0; + } if (pmd_trans_huge(orig_pmd) || pmd_devmap(orig_pmd)) { if (pmd_protnone(orig_pmd) && vma_is_accessible(vma)) return do_huge_pmd_numa_page(&vmf, orig_pmd); - if ((vmf.flags & FAULT_FLAG_WRITE) && - !pmd_write(orig_pmd)) { + if (dirty && !pmd_write(orig_pmd)) { ret = wp_huge_pmd(&vmf, orig_pmd); if (!(ret & VM_FAULT_FALLBACK)) return ret; @@ -3842,6 +4053,11 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, /* do counter updates before entering really critical section. */ check_sync_rss_stat(current); + if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE, + flags & FAULT_FLAG_INSTRUCTION, + flags & FAULT_FLAG_REMOTE)) + return VM_FAULT_SIGSEGV; + /* * Enable the memcg OOM handling for faults triggered in user * space. Kernel faults are handled more gracefully. @@ -3849,11 +4065,6 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, if (flags & FAULT_FLAG_USER) mem_cgroup_oom_enable(); - if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE, - flags & FAULT_FLAG_INSTRUCTION, - flags & FAULT_FLAG_REMOTE)) - return VM_FAULT_SIGSEGV; - if (unlikely(is_vm_hugetlb_page(vma))) ret = hugetlb_fault(vma->vm_mm, vma, address, flags); else @@ -3871,19 +4082,6 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, mem_cgroup_oom_synchronize(false); } - /* - * This mm has been already reaped by the oom reaper and so the - * refault cannot be trusted in general. Anonymous refaults would - * lose data and give a zero page instead e.g. This is especially - * problem for use_mm() because regular tasks will just die and - * the corrupted data will not be visible anywhere while kthread - * will outlive the oom victim and potentially propagate the date - * further. - */ - if (unlikely((current->flags & PF_KTHREAD) && !(ret & VM_FAULT_ERROR) - && test_bit(MMF_UNSTABLE, &vma->vm_mm->flags))) - ret = VM_FAULT_SIGBUS; - return ret; } EXPORT_SYMBOL_GPL(handle_mm_fault); @@ -3975,7 +4173,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) #endif /* __PAGETABLE_PMD_FOLDED */ static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address, - pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) + unsigned long *start, unsigned long *end, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) { pgd_t *pgd; p4d_t *p4d; @@ -4002,17 +4201,29 @@ static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address, if (!pmdpp) goto out; + if (start && end) { + *start = address & PMD_MASK; + *end = *start + PMD_SIZE; + mmu_notifier_invalidate_range_start(mm, *start, *end); + } *ptlp = pmd_lock(mm, pmd); if (pmd_huge(*pmd)) { *pmdpp = pmd; return 0; } spin_unlock(*ptlp); + if (start && end) + mmu_notifier_invalidate_range_end(mm, *start, *end); } if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) goto out; + if (start && end) { + *start = address & PAGE_MASK; + *end = *start + PAGE_SIZE; + mmu_notifier_invalidate_range_start(mm, *start, *end); + } ptep = pte_offset_map_lock(mm, pmd, address, ptlp); if (!pte_present(*ptep)) goto unlock; @@ -4020,6 +4231,8 @@ static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address, return 0; unlock: pte_unmap_unlock(ptep, *ptlp); + if (start && end) + mmu_notifier_invalidate_range_end(mm, *start, *end); out: return -EINVAL; } @@ -4031,20 +4244,21 @@ static inline int follow_pte(struct mm_struct *mm, unsigned long address, /* (void) is needed to make gcc happy */ (void) __cond_lock(*ptlp, - !(res = __follow_pte_pmd(mm, address, ptepp, NULL, - ptlp))); + !(res = __follow_pte_pmd(mm, address, NULL, NULL, + ptepp, NULL, ptlp))); return res; } int follow_pte_pmd(struct mm_struct *mm, unsigned long address, + unsigned long *start, unsigned long *end, pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) { int res; /* (void) is needed to make gcc happy */ (void) __cond_lock(*ptlp, - !(res = __follow_pte_pmd(mm, address, ptepp, pmdpp, - ptlp))); + !(res = __follow_pte_pmd(mm, address, start, end, + ptepp, pmdpp, ptlp))); return res; } EXPORT_SYMBOL(follow_pte_pmd); @@ -4307,19 +4521,53 @@ static void clear_gigantic_page(struct page *page, } } void clear_huge_page(struct page *page, - unsigned long addr, unsigned int pages_per_huge_page) + unsigned long addr_hint, unsigned int pages_per_huge_page) { - int i; + int i, n, base, l; + unsigned long addr = addr_hint & + ~(((unsigned long)pages_per_huge_page << PAGE_SHIFT) - 1); if (unlikely(pages_per_huge_page > MAX_ORDER_NR_PAGES)) { clear_gigantic_page(page, addr, pages_per_huge_page); return; } + /* Clear sub-page to access last to keep its cache lines hot */ might_sleep(); - for (i = 0; i < pages_per_huge_page; i++) { + n = (addr_hint - addr) / PAGE_SIZE; + if (2 * n <= pages_per_huge_page) { + /* If sub-page to access in first half of huge page */ + base = 0; + l = n; + /* Clear sub-pages at the end of huge page */ + for (i = pages_per_huge_page - 1; i >= 2 * n; i--) { + cond_resched(); + clear_user_highpage(page + i, addr + i * PAGE_SIZE); + } + } else { + /* If sub-page to access in second half of huge page */ + base = pages_per_huge_page - 2 * (pages_per_huge_page - n); + l = pages_per_huge_page - n; + /* Clear sub-pages at the begin of huge page */ + for (i = 0; i < base; i++) { + cond_resched(); + clear_user_highpage(page + i, addr + i * PAGE_SIZE); + } + } + /* + * Clear remaining sub-pages in left-right-left-right pattern + * towards the sub-page to access + */ + for (i = 0; i < l; i++) { + int left_idx = base + i; + int right_idx = base + 2 * l - 1 - i; + + cond_resched(); + clear_user_highpage(page + left_idx, + addr + left_idx * PAGE_SIZE); cond_resched(); - clear_user_highpage(page + i, addr + i * PAGE_SIZE); + clear_user_highpage(page + right_idx, + addr + right_idx * PAGE_SIZE); } } diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 8dccc317aac2a568bb7a3014705d894fc4248cd0..d4b5f29906b96465207df76897739d2eba518886 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -99,7 +99,7 @@ void mem_hotplug_done(void) /* add this memory to iomem resource */ static struct resource *register_memory_resource(u64 start, u64 size) { - struct resource *res; + struct resource *res, *conflict; res = kzalloc(sizeof(struct resource), GFP_KERNEL); if (!res) return ERR_PTR(-ENOMEM); @@ -108,7 +108,13 @@ static struct resource *register_memory_resource(u64 start, u64 size) res->start = start; res->end = start + size - 1; res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; - if (request_resource(&iomem_resource, res) < 0) { + conflict = request_resource_conflict(&iomem_resource, res); + if (conflict) { + if (conflict->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) { + pr_debug("Device unaddressable memory block " + "memory hotplug at %#010llx !\n", + (unsigned long long)start); + } pr_debug("System RAM resource %pR cannot be added\n", res); kfree(res); return ERR_PTR(-EEXIST); @@ -322,6 +328,7 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn, if (err && (err != -EEXIST)) break; err = 0; + cond_resched(); } vmemmap_populate_print_last(); out: @@ -331,7 +338,7 @@ EXPORT_SYMBOL_GPL(__add_pages); #ifdef CONFIG_MEMORY_HOTREMOVE /* find the smallest valid pfn in the range [start_pfn, end_pfn) */ -static int find_smallest_section_pfn(int nid, struct zone *zone, +static unsigned long find_smallest_section_pfn(int nid, struct zone *zone, unsigned long start_pfn, unsigned long end_pfn) { @@ -356,7 +363,7 @@ static int find_smallest_section_pfn(int nid, struct zone *zone, } /* find the biggest valid pfn in the range [start_pfn, end_pfn). */ -static int find_biggest_section_pfn(int nid, struct zone *zone, +static unsigned long find_biggest_section_pfn(int nid, struct zone *zone, unsigned long start_pfn, unsigned long end_pfn) { @@ -544,7 +551,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms, return ret; scn_nr = __section_nr(ms); - start_pfn = section_nr_to_pfn(scn_nr); + start_pfn = section_nr_to_pfn((unsigned long)scn_nr); __remove_zone(zone, start_pfn); sparse_remove_one_section(zone, ms, map_offset); @@ -773,31 +780,6 @@ static void node_states_set_node(int node, struct memory_notify *arg) node_set_state(node, N_MEMORY); } -bool allow_online_pfn_range(int nid, unsigned long pfn, unsigned long nr_pages, int online_type) -{ - struct pglist_data *pgdat = NODE_DATA(nid); - struct zone *movable_zone = &pgdat->node_zones[ZONE_MOVABLE]; - struct zone *default_zone = default_zone_for_pfn(nid, pfn, nr_pages); - - /* - * TODO there shouldn't be any inherent reason to have ZONE_NORMAL - * physically before ZONE_MOVABLE. All we need is they do not - * overlap. Historically we didn't allow ZONE_NORMAL after ZONE_MOVABLE - * though so let's stick with it for simplicity for now. - * TODO make sure we do not overlap with ZONE_DEVICE - */ - if (online_type == MMOP_ONLINE_KERNEL) { - if (zone_is_empty(movable_zone)) - return true; - return movable_zone->zone_start_pfn >= pfn + nr_pages; - } else if (online_type == MMOP_ONLINE_MOVABLE) { - return zone_end_pfn(default_zone) <= pfn; - } - - /* MMOP_ONLINE_KEEP will always succeed and inherits the current zone */ - return online_type == MMOP_ONLINE_KEEP; -} - static void __meminit resize_zone_range(struct zone *zone, unsigned long start_pfn, unsigned long nr_pages) { @@ -856,7 +838,7 @@ void __ref move_pfn_range_to_zone(struct zone *zone, * If no kernel zone covers this pfn range it will automatically go * to the ZONE_NORMAL. */ -struct zone *default_zone_for_pfn(int nid, unsigned long start_pfn, +static struct zone *default_kernel_zone_for_pfn(int nid, unsigned long start_pfn, unsigned long nr_pages) { struct pglist_data *pgdat = NODE_DATA(nid); @@ -872,17 +854,40 @@ struct zone *default_zone_for_pfn(int nid, unsigned long start_pfn, return &pgdat->node_zones[ZONE_NORMAL]; } -static inline bool movable_pfn_range(int nid, struct zone *default_zone, - unsigned long start_pfn, unsigned long nr_pages) +static inline struct zone *default_zone_for_pfn(int nid, unsigned long start_pfn, + unsigned long nr_pages) { - if (!allow_online_pfn_range(nid, start_pfn, nr_pages, - MMOP_ONLINE_KERNEL)) - return true; + struct zone *kernel_zone = default_kernel_zone_for_pfn(nid, start_pfn, + nr_pages); + struct zone *movable_zone = &NODE_DATA(nid)->node_zones[ZONE_MOVABLE]; + bool in_kernel = zone_intersects(kernel_zone, start_pfn, nr_pages); + bool in_movable = zone_intersects(movable_zone, start_pfn, nr_pages); - if (!movable_node_is_enabled()) - return false; + /* + * We inherit the existing zone in a simple case where zones do not + * overlap in the given range + */ + if (in_kernel ^ in_movable) + return (in_kernel) ? kernel_zone : movable_zone; - return !zone_intersects(default_zone, start_pfn, nr_pages); + /* + * If the range doesn't belong to any zone or two zones overlap in the + * given range then we use movable zone only if movable_node is + * enabled because we always online to a kernel zone by default. + */ + return movable_node_enabled ? movable_zone : kernel_zone; +} + +struct zone * zone_for_pfn_range(int online_type, int nid, unsigned start_pfn, + unsigned long nr_pages) +{ + if (online_type == MMOP_ONLINE_KERNEL) + return default_kernel_zone_for_pfn(nid, start_pfn, nr_pages); + + if (online_type == MMOP_ONLINE_MOVABLE) + return &NODE_DATA(nid)->node_zones[ZONE_MOVABLE]; + + return default_zone_for_pfn(nid, start_pfn, nr_pages); } /* @@ -892,28 +897,14 @@ static inline bool movable_pfn_range(int nid, struct zone *default_zone, static struct zone * __meminit move_pfn_range(int online_type, int nid, unsigned long start_pfn, unsigned long nr_pages) { - struct pglist_data *pgdat = NODE_DATA(nid); - struct zone *zone = default_zone_for_pfn(nid, start_pfn, nr_pages); - - if (online_type == MMOP_ONLINE_KEEP) { - struct zone *movable_zone = &pgdat->node_zones[ZONE_MOVABLE]; - /* - * MMOP_ONLINE_KEEP defaults to MMOP_ONLINE_KERNEL but use - * movable zone if that is not possible (e.g. we are within - * or past the existing movable zone). movable_node overrides - * this default and defaults to movable zone - */ - if (movable_pfn_range(nid, zone, start_pfn, nr_pages)) - zone = movable_zone; - } else if (online_type == MMOP_ONLINE_MOVABLE) { - zone = &pgdat->node_zones[ZONE_MOVABLE]; - } + struct zone *zone; + zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages); move_pfn_range_to_zone(zone, start_pfn, nr_pages); return zone; } -/* Must be protected by mem_hotplug_begin() */ +/* Must be protected by mem_hotplug_begin() or a device_lock */ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type) { unsigned long flags; @@ -925,9 +916,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ struct memory_notify arg; nid = pfn_to_nid(pfn); - if (!allow_online_pfn_range(nid, pfn, nr_pages, online_type)) - return -EINVAL; - /* associate pfn range with the zone */ zone = move_pfn_range(online_type, nid, pfn, nr_pages); @@ -945,10 +933,9 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ * This means the page allocator ignores this zone. * So, zonelist must be updated after online. */ - mutex_lock(&zonelists_mutex); if (!populated_zone(zone)) { need_zonelists_rebuild = 1; - build_all_zonelists(NULL, zone); + setup_zone_pageset(zone); } ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages, @@ -956,7 +943,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ if (ret) { if (need_zonelists_rebuild) zone_pcp_reset(zone); - mutex_unlock(&zonelists_mutex); goto failed_addition; } @@ -969,13 +955,11 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ if (onlined_pages) { node_states_set_node(nid, &arg); if (need_zonelists_rebuild) - build_all_zonelists(NULL, NULL); + build_all_zonelists(NULL); else zone_pcp_update(zone); } - mutex_unlock(&zonelists_mutex); - init_per_zone_wmark_min(); if (onlined_pages) { @@ -1046,9 +1030,7 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start) * The node we allocated has no zone fallback lists. For avoiding * to access not-initialized zonelist, build here. */ - mutex_lock(&zonelists_mutex); - build_all_zonelists(pgdat, NULL); - mutex_unlock(&zonelists_mutex); + build_all_zonelists(pgdat); /* * zone->managed_pages is set to an approximate value in @@ -1100,13 +1082,6 @@ int try_online_node(int nid) node_set_online(nid); ret = register_one_node(nid); BUG_ON(ret); - - if (pgdat->node_zonelists->_zonerefs->zone == NULL) { - mutex_lock(&zonelists_mutex); - build_all_zonelists(NULL, NULL); - mutex_unlock(&zonelists_mutex); - } - out: mem_hotplug_done(); return ret; @@ -1412,7 +1387,9 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) if (isolate_huge_page(page, &source)) move_pages -= 1 << compound_order(head); continue; - } + } else if (thp_migration_supported() && PageTransHuge(page)) + pfn = page_to_pfn(compound_head(page)) + + hpage_nr_pages(page) - 1; if (!get_page_unless_zero(page)) continue; @@ -1722,9 +1699,7 @@ static int __ref __offline_pages(unsigned long start_pfn, if (!populated_zone(zone)) { zone_pcp_reset(zone); - mutex_lock(&zonelists_mutex); - build_all_zonelists(NULL, NULL); - mutex_unlock(&zonelists_mutex); + build_all_zonelists(NULL); } else zone_pcp_update(zone); @@ -1750,7 +1725,7 @@ static int __ref __offline_pages(unsigned long start_pfn, return ret; } -/* Must be protected by mem_hotplug_begin() */ +/* Must be protected by mem_hotplug_begin() or a device_lock */ int offline_pages(unsigned long start_pfn, unsigned long nr_pages) { return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ); diff --git a/mm/mempolicy.c b/mm/mempolicy.c index d911fa5cb2a73fe464042a59e1c2676c1129239d..006ba625c0b8d4edb6b3ed2b20ce307c254b42be 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -97,6 +97,7 @@ #include #include #include +#include #include #include @@ -411,6 +412,64 @@ struct queue_pages { struct vm_area_struct *prev; }; +/* + * Check if the page's nid is in qp->nmask. + * + * If MPOL_MF_INVERT is set in qp->flags, check if the nid is + * in the invert of qp->nmask. + */ +static inline bool queue_pages_required(struct page *page, + struct queue_pages *qp) +{ + int nid = page_to_nid(page); + unsigned long flags = qp->flags; + + return node_isset(nid, *qp->nmask) == !(flags & MPOL_MF_INVERT); +} + +static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, + unsigned long end, struct mm_walk *walk) +{ + int ret = 0; + struct page *page; + struct queue_pages *qp = walk->private; + unsigned long flags; + + if (unlikely(is_pmd_migration_entry(*pmd))) { + ret = 1; + goto unlock; + } + page = pmd_page(*pmd); + if (is_huge_zero_page(page)) { + spin_unlock(ptl); + __split_huge_pmd(walk->vma, pmd, addr, false, NULL); + goto out; + } + if (!thp_migration_supported()) { + get_page(page); + spin_unlock(ptl); + lock_page(page); + ret = split_huge_page(page); + unlock_page(page); + put_page(page); + goto out; + } + if (!queue_pages_required(page, qp)) { + ret = 1; + goto unlock; + } + + ret = 1; + flags = qp->flags; + /* go to thp migration */ + if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) + migrate_page_add(page, qp->pagelist, flags); +unlock: + spin_unlock(ptl); +out: + return ret; +} + /* * Scan through pages checking if pages follow certain conditions, * and move them to the pagelist if they do. @@ -422,30 +481,15 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, struct page *page; struct queue_pages *qp = walk->private; unsigned long flags = qp->flags; - int nid, ret; + int ret; pte_t *pte; spinlock_t *ptl; - if (pmd_trans_huge(*pmd)) { - ptl = pmd_lock(walk->mm, pmd); - if (pmd_trans_huge(*pmd)) { - page = pmd_page(*pmd); - if (is_huge_zero_page(page)) { - spin_unlock(ptl); - __split_huge_pmd(vma, pmd, addr, false, NULL); - } else { - get_page(page); - spin_unlock(ptl); - lock_page(page); - ret = split_huge_page(page); - unlock_page(page); - put_page(page); - if (ret) - return 0; - } - } else { - spin_unlock(ptl); - } + ptl = pmd_trans_huge_lock(pmd, vma); + if (ptl) { + ret = queue_pages_pmd(pmd, ptl, addr, end, walk); + if (ret) + return 0; } if (pmd_trans_unstable(pmd)) @@ -464,10 +508,9 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, */ if (PageReserved(page)) continue; - nid = page_to_nid(page); - if (node_isset(nid, *qp->nmask) == !!(flags & MPOL_MF_INVERT)) + if (!queue_pages_required(page, qp)) continue; - if (PageTransCompound(page)) { + if (PageTransCompound(page) && !thp_migration_supported()) { get_page(page); pte_unmap_unlock(pte, ptl); lock_page(page); @@ -497,7 +540,6 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long hmask, #ifdef CONFIG_HUGETLB_PAGE struct queue_pages *qp = walk->private; unsigned long flags = qp->flags; - int nid; struct page *page; spinlock_t *ptl; pte_t entry; @@ -507,8 +549,7 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long hmask, if (!pte_present(entry)) goto unlock; page = pte_page(entry); - nid = page_to_nid(page); - if (node_isset(nid, *qp->nmask) == !!(flags & MPOL_MF_INVERT)) + if (!queue_pages_required(page, qp)) goto unlock; /* With MPOL_MF_MOVE, we migrate only unshared hugepage. */ if (flags & (MPOL_MF_MOVE_ALL) || @@ -861,11 +902,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, *policy |= (pol->flags & MPOL_MODE_FLAGS); } - if (vma) { - up_read(¤t->mm->mmap_sem); - vma = NULL; - } - err = 0; if (nmask) { if (mpol_store_user_nodemask(pol)) { @@ -886,19 +922,21 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, #ifdef CONFIG_MIGRATION /* - * page migration + * page migration, thp tail pages can be passed. */ static void migrate_page_add(struct page *page, struct list_head *pagelist, unsigned long flags) { + struct page *head = compound_head(page); /* * Avoid migrating a page that is shared with others. */ - if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1) { - if (!isolate_lru_page(page)) { - list_add_tail(&page->lru, pagelist); - inc_node_page_state(page, NR_ISOLATED_ANON + - page_is_file_cache(page)); + if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(head) == 1) { + if (!isolate_lru_page(head)) { + list_add_tail(&head->lru, pagelist); + mod_node_page_state(page_pgdat(head), + NR_ISOLATED_ANON + page_is_file_cache(head), + hpage_nr_pages(head)); } } } @@ -908,7 +946,17 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x if (PageHuge(page)) return alloc_huge_page_node(page_hstate(compound_head(page)), node); - else + else if (thp_migration_supported() && PageTransHuge(page)) { + struct page *thp; + + thp = alloc_pages_node(node, + (GFP_TRANSHUGE | __GFP_THISNODE), + HPAGE_PMD_ORDER); + if (!thp) + return NULL; + prep_transhuge_page(thp); + return thp; + } else return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0); } @@ -1074,6 +1122,15 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) if (PageHuge(page)) { BUG_ON(!vma); return alloc_huge_page_noerr(vma, address, 1); + } else if (thp_migration_supported() && PageTransHuge(page)) { + struct page *thp; + + thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, + HPAGE_PMD_ORDER); + if (!thp) + return NULL; + prep_transhuge_page(thp); + return thp; } /* * if !vma, alloc_page_vma() will use task or system default policy @@ -1688,8 +1745,7 @@ unsigned int mempolicy_slab_node(void) * node in pol->v.nodes (starting from n=0), wrapping around if n exceeds the * number of present nodes. */ -static unsigned offset_il_node(struct mempolicy *pol, - struct vm_area_struct *vma, unsigned long n) +static unsigned offset_il_node(struct mempolicy *pol, unsigned long n) { unsigned nnodes = nodes_weight(pol->v.nodes); unsigned target; @@ -1722,7 +1778,7 @@ static inline unsigned interleave_nid(struct mempolicy *pol, BUG_ON(shift < PAGE_SHIFT); off = vma->vm_pgoff >> (shift - PAGE_SHIFT); off += (addr - vma->vm_start) >> shift; - return offset_il_node(pol, vma, off); + return offset_il_node(pol, off); } else return interleave_nodes(pol); } @@ -2177,20 +2233,15 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long int polnid = -1; int ret = -1; - BUG_ON(!vma); - pol = get_vma_policy(vma, addr); if (!(pol->flags & MPOL_F_MOF)) goto out; switch (pol->mode) { case MPOL_INTERLEAVE: - BUG_ON(addr >= vma->vm_end); - BUG_ON(addr < vma->vm_start); - pgoff = vma->vm_pgoff; pgoff += (addr - vma->vm_start) >> PAGE_SHIFT; - polnid = offset_il_node(pol, vma, pgoff); + polnid = offset_il_node(pol, pgoff); break; case MPOL_PREFERRED: diff --git a/mm/migrate.c b/mm/migrate.c index 62767155187356d54d1fa7333ad402e76183ca0b..6954c1435833133f910a08a9cd8e0e1516084296 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -36,11 +36,15 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include #include @@ -184,8 +188,8 @@ void putback_movable_pages(struct list_head *l) unlock_page(page); put_page(page); } else { - dec_node_page_state(page, NR_ISOLATED_ANON + - page_is_file_cache(page)); + mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + + page_is_file_cache(page), -hpage_nr_pages(page)); putback_lru_page(page); } } @@ -215,6 +219,15 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma, new = page - pvmw.page->index + linear_page_index(vma, pvmw.address); +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + /* PMD-mapped THP migration entry */ + if (!pvmw.pte) { + VM_BUG_ON_PAGE(PageHuge(page) || !PageTransCompound(page), page); + remove_migration_pmd(&pvmw, new); + continue; + } +#endif + get_page(new); pte = pte_mkold(mk_pte(new, READ_ONCE(vma->vm_page_prot))); if (pte_swp_soft_dirty(*pvmw.pte)) @@ -227,7 +240,17 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma, if (is_write_migration_entry(entry)) pte = maybe_mkwrite(pte, vma); - flush_dcache_page(new); + if (unlikely(is_zone_device_page(new))) { + if (is_device_private_page(new)) { + entry = make_device_private_entry(new, pte_write(pte)); + pte = swp_entry_to_pte(entry); + } else if (is_device_public_page(new)) { + pte = pte_mkdevmap(pte); + flush_dcache_page(new); + } + } else + flush_dcache_page(new); + #ifdef CONFIG_HUGETLB_PAGE if (PageHuge(new)) { pte = pte_mkhuge(pte); @@ -329,6 +352,27 @@ void migration_entry_wait_huge(struct vm_area_struct *vma, __migration_entry_wait(mm, pte, ptl); } +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd) +{ + spinlock_t *ptl; + struct page *page; + + ptl = pmd_lock(mm, pmd); + if (!is_pmd_migration_entry(*pmd)) + goto unlock; + page = migration_entry_to_page(pmd_to_swp_entry(*pmd)); + if (!get_page_unless_zero(page)) + goto unlock; + spin_unlock(ptl); + wait_on_page_locked(page); + put_page(page); + return; +unlock: + spin_unlock(ptl); +} +#endif + #ifdef CONFIG_BLOCK /* Returns true if all buffers are successfully locked */ static bool buffer_migrate_lock_buffers(struct buffer_head *head, @@ -397,6 +441,13 @@ int migrate_page_move_mapping(struct address_space *mapping, int expected_count = 1 + extra_count; void **pslot; + /* + * Device public or private pages have an extra refcount as they are + * ZONE_DEVICE pages. + */ + expected_count += is_device_private_page(page); + expected_count += is_device_public_page(page); + if (!mapping) { /* Anonymous page without mapping */ if (page_count(page) != expected_count) @@ -603,15 +654,10 @@ static void copy_huge_page(struct page *dst, struct page *src) /* * Copy the page to its new location */ -void migrate_page_copy(struct page *newpage, struct page *page) +void migrate_page_states(struct page *newpage, struct page *page) { int cpupid; - if (PageHuge(page) || PageTransHuge(page)) - copy_huge_page(newpage, page); - else - copy_highpage(newpage, page); - if (PageError(page)) SetPageError(newpage); if (PageReferenced(page)) @@ -665,6 +711,17 @@ void migrate_page_copy(struct page *newpage, struct page *page) mem_cgroup_migrate(page, newpage); } +EXPORT_SYMBOL(migrate_page_states); + +void migrate_page_copy(struct page *newpage, struct page *page) +{ + if (PageHuge(page) || PageTransHuge(page)) + copy_huge_page(newpage, page); + else + copy_highpage(newpage, page); + + migrate_page_states(newpage, page); +} EXPORT_SYMBOL(migrate_page_copy); /************************************************************ @@ -690,7 +747,10 @@ int migrate_page(struct address_space *mapping, if (rc != MIGRATEPAGE_SUCCESS) return rc; - migrate_page_copy(newpage, page); + if (mode != MIGRATE_SYNC_NO_COPY) + migrate_page_copy(newpage, page); + else + migrate_page_states(newpage, page); return MIGRATEPAGE_SUCCESS; } EXPORT_SYMBOL(migrate_page); @@ -740,12 +800,15 @@ int buffer_migrate_page(struct address_space *mapping, SetPagePrivate(newpage); - migrate_page_copy(newpage, page); + if (mode != MIGRATE_SYNC_NO_COPY) + migrate_page_copy(newpage, page); + else + migrate_page_states(newpage, page); bh = head; do { unlock_buffer(bh); - put_bh(bh); + put_bh(bh); bh = bh->b_this_page; } while (bh != head); @@ -804,8 +867,13 @@ static int fallback_migrate_page(struct address_space *mapping, { if (PageDirty(page)) { /* Only writeback pages in full synchronous migration */ - if (mode != MIGRATE_SYNC) + switch (mode) { + case MIGRATE_SYNC: + case MIGRATE_SYNC_NO_COPY: + break; + default: return -EBUSY; + } return writeout(mapping, page); } @@ -942,7 +1010,11 @@ static int __unmap_and_move(struct page *page, struct page *newpage, * the retry loop is too short and in the sync-light case, * the overhead of stalling is too much */ - if (mode != MIGRATE_SYNC) { + switch (mode) { + case MIGRATE_SYNC: + case MIGRATE_SYNC_NO_COPY: + break; + default: rc = -EBUSY; goto out_unlock; } @@ -1087,7 +1159,7 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page, goto out; } - if (unlikely(PageTransHuge(page))) { + if (unlikely(PageTransHuge(page) && !PageTransHuge(newpage))) { lock_page(page); rc = split_huge_page(page); unlock_page(page); @@ -1115,8 +1187,8 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page, * as __PageMovable */ if (likely(!__PageMovable(page))) - dec_node_page_state(page, NR_ISOLATED_ANON + - page_is_file_cache(page)); + mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + + page_is_file_cache(page), -hpage_nr_pages(page)); } /* @@ -1212,8 +1284,15 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, return -ENOMEM; if (!trylock_page(hpage)) { - if (!force || mode != MIGRATE_SYNC) + if (!force) + goto out; + switch (mode) { + case MIGRATE_SYNC: + case MIGRATE_SYNC_NO_COPY: + break; + default: goto out; + } lock_page(hpage); } @@ -1390,7 +1469,17 @@ static struct page *new_page_node(struct page *p, unsigned long private, if (PageHuge(p)) return alloc_huge_page_node(page_hstate(compound_head(p)), pm->node); - else + else if (thp_migration_supported() && PageTransHuge(p)) { + struct page *thp; + + thp = alloc_pages_node(pm->node, + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, + HPAGE_PMD_ORDER); + if (!thp) + return NULL; + prep_transhuge_page(thp); + return thp; + } else return __alloc_pages_node(pm->node, GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0); } @@ -1417,6 +1506,8 @@ static int do_move_page_to_node_array(struct mm_struct *mm, for (pp = pm; pp->node != MAX_NUMNODES; pp++) { struct vm_area_struct *vma; struct page *page; + struct page *head; + unsigned int follflags; err = -EFAULT; vma = find_vma(mm, pp->addr); @@ -1424,8 +1515,10 @@ static int do_move_page_to_node_array(struct mm_struct *mm, goto set_status; /* FOLL_DUMP to ignore special (like zero) pages */ - page = follow_page(vma, pp->addr, - FOLL_GET | FOLL_SPLIT | FOLL_DUMP); + follflags = FOLL_GET | FOLL_DUMP; + if (!thp_migration_supported()) + follflags |= FOLL_SPLIT; + page = follow_page(vma, pp->addr, follflags); err = PTR_ERR(page); if (IS_ERR(page)) @@ -1435,7 +1528,6 @@ static int do_move_page_to_node_array(struct mm_struct *mm, if (!page) goto set_status; - pp->page = page; err = page_to_nid(page); if (err == pp->node) @@ -1450,16 +1542,22 @@ static int do_move_page_to_node_array(struct mm_struct *mm, goto put_and_set; if (PageHuge(page)) { - if (PageHead(page)) + if (PageHead(page)) { isolate_huge_page(page, &pagelist); + err = 0; + pp->page = page; + } goto put_and_set; } - err = isolate_lru_page(page); + pp->page = compound_head(page); + head = compound_head(page); + err = isolate_lru_page(head); if (!err) { - list_add_tail(&page->lru, &pagelist); - inc_node_page_state(page, NR_ISOLATED_ANON + - page_is_file_cache(page)); + list_add_tail(&head->lru, &pagelist); + mod_node_page_state(page_pgdat(head), + NR_ISOLATED_ANON + page_is_file_cache(head), + hpage_nr_pages(head)); } put_and_set: /* @@ -1652,7 +1750,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, const int __user *, nodes, int __user *, status, int, flags) { - const struct cred *cred = current_cred(), *tcred; struct task_struct *task; struct mm_struct *mm; int err; @@ -1676,14 +1773,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, /* * Check if this process has the right to modify the specified - * process. The right exists if the process has administrative - * capabilities, superuser privileges or the same - * userid as the target process. + * process. Use the regular "ptrace_may_access()" checks. */ - tcred = __task_cred(task); - if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) && - !uid_eq(cred->uid, tcred->suid) && !uid_eq(cred->uid, tcred->uid) && - !capable(CAP_SYS_NICE)) { + if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) { rcu_read_unlock(); err = -EPERM; goto out; @@ -1937,12 +2029,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, put_page(new_page); goto out_fail; } - /* - * We are not sure a pending tlb flush here is for a huge page - * mapping or not. Hence use the tlb range variant - */ - if (mm_tlb_flush_pending(mm)) - flush_tlb_range(vma, mmun_start, mmun_end); /* Prepare a page as a migration target */ __SetPageLocked(new_page); @@ -2040,3 +2126,859 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, #endif /* CONFIG_NUMA_BALANCING */ #endif /* CONFIG_NUMA */ + +#if defined(CONFIG_MIGRATE_VMA_HELPER) +struct migrate_vma { + struct vm_area_struct *vma; + unsigned long *dst; + unsigned long *src; + unsigned long cpages; + unsigned long npages; + unsigned long start; + unsigned long end; +}; + +static int migrate_vma_collect_hole(unsigned long start, + unsigned long end, + struct mm_walk *walk) +{ + struct migrate_vma *migrate = walk->private; + unsigned long addr; + + for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { + migrate->src[migrate->npages++] = MIGRATE_PFN_MIGRATE; + migrate->dst[migrate->npages] = 0; + migrate->cpages++; + } + + return 0; +} + +static int migrate_vma_collect_skip(unsigned long start, + unsigned long end, + struct mm_walk *walk) +{ + struct migrate_vma *migrate = walk->private; + unsigned long addr; + + for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { + migrate->dst[migrate->npages] = 0; + migrate->src[migrate->npages++] = 0; + } + + return 0; +} + +static int migrate_vma_collect_pmd(pmd_t *pmdp, + unsigned long start, + unsigned long end, + struct mm_walk *walk) +{ + struct migrate_vma *migrate = walk->private; + struct vm_area_struct *vma = walk->vma; + struct mm_struct *mm = vma->vm_mm; + unsigned long addr = start, unmapped = 0; + spinlock_t *ptl; + pte_t *ptep; + +again: + if (pmd_none(*pmdp)) + return migrate_vma_collect_hole(start, end, walk); + + if (pmd_trans_huge(*pmdp)) { + struct page *page; + + ptl = pmd_lock(mm, pmdp); + if (unlikely(!pmd_trans_huge(*pmdp))) { + spin_unlock(ptl); + goto again; + } + + page = pmd_page(*pmdp); + if (is_huge_zero_page(page)) { + spin_unlock(ptl); + split_huge_pmd(vma, pmdp, addr); + if (pmd_trans_unstable(pmdp)) + return migrate_vma_collect_skip(start, end, + walk); + } else { + int ret; + + get_page(page); + spin_unlock(ptl); + if (unlikely(!trylock_page(page))) + return migrate_vma_collect_skip(start, end, + walk); + ret = split_huge_page(page); + unlock_page(page); + put_page(page); + if (ret) + return migrate_vma_collect_skip(start, end, + walk); + if (pmd_none(*pmdp)) + return migrate_vma_collect_hole(start, end, + walk); + } + } + + if (unlikely(pmd_bad(*pmdp))) + return migrate_vma_collect_skip(start, end, walk); + + ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); + arch_enter_lazy_mmu_mode(); + + for (; addr < end; addr += PAGE_SIZE, ptep++) { + unsigned long mpfn, pfn; + struct page *page; + swp_entry_t entry; + pte_t pte; + + pte = *ptep; + pfn = pte_pfn(pte); + + if (pte_none(pte)) { + mpfn = MIGRATE_PFN_MIGRATE; + migrate->cpages++; + pfn = 0; + goto next; + } + + if (!pte_present(pte)) { + mpfn = pfn = 0; + + /* + * Only care about unaddressable device page special + * page table entry. Other special swap entries are not + * migratable, and we ignore regular swapped page. + */ + entry = pte_to_swp_entry(pte); + if (!is_device_private_entry(entry)) + goto next; + + page = device_private_entry_to_page(entry); + mpfn = migrate_pfn(page_to_pfn(page))| + MIGRATE_PFN_DEVICE | MIGRATE_PFN_MIGRATE; + if (is_write_device_private_entry(entry)) + mpfn |= MIGRATE_PFN_WRITE; + } else { + if (is_zero_pfn(pfn)) { + mpfn = MIGRATE_PFN_MIGRATE; + migrate->cpages++; + pfn = 0; + goto next; + } + page = _vm_normal_page(migrate->vma, addr, pte, true); + mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE; + mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0; + } + + /* FIXME support THP */ + if (!page || !page->mapping || PageTransCompound(page)) { + mpfn = pfn = 0; + goto next; + } + pfn = page_to_pfn(page); + + /* + * By getting a reference on the page we pin it and that blocks + * any kind of migration. Side effect is that it "freezes" the + * pte. + * + * We drop this reference after isolating the page from the lru + * for non device page (device page are not on the lru and thus + * can't be dropped from it). + */ + get_page(page); + migrate->cpages++; + + /* + * Optimize for the common case where page is only mapped once + * in one process. If we can lock the page, then we can safely + * set up a special migration page table entry now. + */ + if (trylock_page(page)) { + pte_t swp_pte; + + mpfn |= MIGRATE_PFN_LOCKED; + ptep_get_and_clear(mm, addr, ptep); + + /* Setup special migration page table entry */ + entry = make_migration_entry(page, pte_write(pte)); + swp_pte = swp_entry_to_pte(entry); + if (pte_soft_dirty(pte)) + swp_pte = pte_swp_mksoft_dirty(swp_pte); + set_pte_at(mm, addr, ptep, swp_pte); + + /* + * This is like regular unmap: we remove the rmap and + * drop page refcount. Page won't be freed, as we took + * a reference just above. + */ + page_remove_rmap(page, false); + put_page(page); + + if (pte_present(pte)) + unmapped++; + } + +next: + migrate->dst[migrate->npages] = 0; + migrate->src[migrate->npages++] = mpfn; + } + arch_leave_lazy_mmu_mode(); + pte_unmap_unlock(ptep - 1, ptl); + + /* Only flush the TLB if we actually modified any entries */ + if (unmapped) + flush_tlb_range(walk->vma, start, end); + + return 0; +} + +/* + * migrate_vma_collect() - collect pages over a range of virtual addresses + * @migrate: migrate struct containing all migration information + * + * This will walk the CPU page table. For each virtual address backed by a + * valid page, it updates the src array and takes a reference on the page, in + * order to pin the page until we lock it and unmap it. + */ +static void migrate_vma_collect(struct migrate_vma *migrate) +{ + struct mm_walk mm_walk; + + mm_walk.pmd_entry = migrate_vma_collect_pmd; + mm_walk.pte_entry = NULL; + mm_walk.pte_hole = migrate_vma_collect_hole; + mm_walk.hugetlb_entry = NULL; + mm_walk.test_walk = NULL; + mm_walk.vma = migrate->vma; + mm_walk.mm = migrate->vma->vm_mm; + mm_walk.private = migrate; + + mmu_notifier_invalidate_range_start(mm_walk.mm, + migrate->start, + migrate->end); + walk_page_range(migrate->start, migrate->end, &mm_walk); + mmu_notifier_invalidate_range_end(mm_walk.mm, + migrate->start, + migrate->end); + + migrate->end = migrate->start + (migrate->npages << PAGE_SHIFT); +} + +/* + * migrate_vma_check_page() - check if page is pinned or not + * @page: struct page to check + * + * Pinned pages cannot be migrated. This is the same test as in + * migrate_page_move_mapping(), except that here we allow migration of a + * ZONE_DEVICE page. + */ +static bool migrate_vma_check_page(struct page *page) +{ + /* + * One extra ref because caller holds an extra reference, either from + * isolate_lru_page() for a regular page, or migrate_vma_collect() for + * a device page. + */ + int extra = 1; + + /* + * FIXME support THP (transparent huge page), it is bit more complex to + * check them than regular pages, because they can be mapped with a pmd + * or with a pte (split pte mapping). + */ + if (PageCompound(page)) + return false; + + /* Page from ZONE_DEVICE have one extra reference */ + if (is_zone_device_page(page)) { + /* + * Private page can never be pin as they have no valid pte and + * GUP will fail for those. Yet if there is a pending migration + * a thread might try to wait on the pte migration entry and + * will bump the page reference count. Sadly there is no way to + * differentiate a regular pin from migration wait. Hence to + * avoid 2 racing thread trying to migrate back to CPU to enter + * infinite loop (one stoping migration because the other is + * waiting on pte migration entry). We always return true here. + * + * FIXME proper solution is to rework migration_entry_wait() so + * it does not need to take a reference on page. + */ + if (is_device_private_page(page)) + return true; + + /* + * Only allow device public page to be migrated and account for + * the extra reference count imply by ZONE_DEVICE pages. + */ + if (!is_device_public_page(page)) + return false; + extra++; + } + + /* For file back page */ + if (page_mapping(page)) + extra += 1 + page_has_private(page); + + if ((page_count(page) - extra) > page_mapcount(page)) + return false; + + return true; +} + +/* + * migrate_vma_prepare() - lock pages and isolate them from the lru + * @migrate: migrate struct containing all migration information + * + * This locks pages that have been collected by migrate_vma_collect(). Once each + * page is locked it is isolated from the lru (for non-device pages). Finally, + * the ref taken by migrate_vma_collect() is dropped, as locked pages cannot be + * migrated by concurrent kernel threads. + */ +static void migrate_vma_prepare(struct migrate_vma *migrate) +{ + const unsigned long npages = migrate->npages; + const unsigned long start = migrate->start; + unsigned long addr, i, restore = 0; + bool allow_drain = true; + + lru_add_drain(); + + for (i = 0; (i < npages) && migrate->cpages; i++) { + struct page *page = migrate_pfn_to_page(migrate->src[i]); + bool remap = true; + + if (!page) + continue; + + if (!(migrate->src[i] & MIGRATE_PFN_LOCKED)) { + /* + * Because we are migrating several pages there can be + * a deadlock between 2 concurrent migration where each + * are waiting on each other page lock. + * + * Make migrate_vma() a best effort thing and backoff + * for any page we can not lock right away. + */ + if (!trylock_page(page)) { + migrate->src[i] = 0; + migrate->cpages--; + put_page(page); + continue; + } + remap = false; + migrate->src[i] |= MIGRATE_PFN_LOCKED; + } + + /* ZONE_DEVICE pages are not on LRU */ + if (!is_zone_device_page(page)) { + if (!PageLRU(page) && allow_drain) { + /* Drain CPU's pagevec */ + lru_add_drain_all(); + allow_drain = false; + } + + if (isolate_lru_page(page)) { + if (remap) { + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + migrate->cpages--; + restore++; + } else { + migrate->src[i] = 0; + unlock_page(page); + migrate->cpages--; + put_page(page); + } + continue; + } + + /* Drop the reference we took in collect */ + put_page(page); + } + + if (!migrate_vma_check_page(page)) { + if (remap) { + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + migrate->cpages--; + restore++; + + if (!is_zone_device_page(page)) { + get_page(page); + putback_lru_page(page); + } + } else { + migrate->src[i] = 0; + unlock_page(page); + migrate->cpages--; + + if (!is_zone_device_page(page)) + putback_lru_page(page); + else + put_page(page); + } + } + } + + for (i = 0, addr = start; i < npages && restore; i++, addr += PAGE_SIZE) { + struct page *page = migrate_pfn_to_page(migrate->src[i]); + + if (!page || (migrate->src[i] & MIGRATE_PFN_MIGRATE)) + continue; + + remove_migration_pte(page, migrate->vma, addr, page); + + migrate->src[i] = 0; + unlock_page(page); + put_page(page); + restore--; + } +} + +/* + * migrate_vma_unmap() - replace page mapping with special migration pte entry + * @migrate: migrate struct containing all migration information + * + * Replace page mapping (CPU page table pte) with a special migration pte entry + * and check again if it has been pinned. Pinned pages are restored because we + * cannot migrate them. + * + * This is the last step before we call the device driver callback to allocate + * destination memory and copy contents of original page over to new page. + */ +static void migrate_vma_unmap(struct migrate_vma *migrate) +{ + int flags = TTU_MIGRATION | TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS; + const unsigned long npages = migrate->npages; + const unsigned long start = migrate->start; + unsigned long addr, i, restore = 0; + + for (i = 0; i < npages; i++) { + struct page *page = migrate_pfn_to_page(migrate->src[i]); + + if (!page || !(migrate->src[i] & MIGRATE_PFN_MIGRATE)) + continue; + + if (page_mapped(page)) { + try_to_unmap(page, flags); + if (page_mapped(page)) + goto restore; + } + + if (migrate_vma_check_page(page)) + continue; + +restore: + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + migrate->cpages--; + restore++; + } + + for (addr = start, i = 0; i < npages && restore; addr += PAGE_SIZE, i++) { + struct page *page = migrate_pfn_to_page(migrate->src[i]); + + if (!page || (migrate->src[i] & MIGRATE_PFN_MIGRATE)) + continue; + + remove_migration_ptes(page, page, false); + + migrate->src[i] = 0; + unlock_page(page); + restore--; + + if (is_zone_device_page(page)) + put_page(page); + else + putback_lru_page(page); + } +} + +static void migrate_vma_insert_page(struct migrate_vma *migrate, + unsigned long addr, + struct page *page, + unsigned long *src, + unsigned long *dst) +{ + struct vm_area_struct *vma = migrate->vma; + struct mm_struct *mm = vma->vm_mm; + struct mem_cgroup *memcg; + bool flush = false; + spinlock_t *ptl; + pte_t entry; + pgd_t *pgdp; + p4d_t *p4dp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep; + + /* Only allow populating anonymous memory */ + if (!vma_is_anonymous(vma)) + goto abort; + + pgdp = pgd_offset(mm, addr); + p4dp = p4d_alloc(mm, pgdp, addr); + if (!p4dp) + goto abort; + pudp = pud_alloc(mm, p4dp, addr); + if (!pudp) + goto abort; + pmdp = pmd_alloc(mm, pudp, addr); + if (!pmdp) + goto abort; + + if (pmd_trans_huge(*pmdp) || pmd_devmap(*pmdp)) + goto abort; + + /* + * Use pte_alloc() instead of pte_alloc_map(). We can't run + * pte_offset_map() on pmds where a huge pmd might be created + * from a different thread. + * + * pte_alloc_map() is safe to use under down_write(mmap_sem) or when + * parallel threads are excluded by other means. + * + * Here we only have down_read(mmap_sem). + */ + if (pte_alloc(mm, pmdp, addr)) + goto abort; + + /* See the comment in pte_alloc_one_map() */ + if (unlikely(pmd_trans_unstable(pmdp))) + goto abort; + + if (unlikely(anon_vma_prepare(vma))) + goto abort; + if (mem_cgroup_try_charge(page, vma->vm_mm, GFP_KERNEL, &memcg, false)) + goto abort; + + /* + * The memory barrier inside __SetPageUptodate makes sure that + * preceding stores to the page contents become visible before + * the set_pte_at() write. + */ + __SetPageUptodate(page); + + if (is_zone_device_page(page)) { + if (is_device_private_page(page)) { + swp_entry_t swp_entry; + + swp_entry = make_device_private_entry(page, vma->vm_flags & VM_WRITE); + entry = swp_entry_to_pte(swp_entry); + } else if (is_device_public_page(page)) { + entry = pte_mkold(mk_pte(page, READ_ONCE(vma->vm_page_prot))); + if (vma->vm_flags & VM_WRITE) + entry = pte_mkwrite(pte_mkdirty(entry)); + entry = pte_mkdevmap(entry); + } + } else { + entry = mk_pte(page, vma->vm_page_prot); + if (vma->vm_flags & VM_WRITE) + entry = pte_mkwrite(pte_mkdirty(entry)); + } + + ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); + + if (pte_present(*ptep)) { + unsigned long pfn = pte_pfn(*ptep); + + if (!is_zero_pfn(pfn)) { + pte_unmap_unlock(ptep, ptl); + mem_cgroup_cancel_charge(page, memcg, false); + goto abort; + } + flush = true; + } else if (!pte_none(*ptep)) { + pte_unmap_unlock(ptep, ptl); + mem_cgroup_cancel_charge(page, memcg, false); + goto abort; + } + + /* + * Check for usefaultfd but do not deliver the fault. Instead, + * just back off. + */ + if (userfaultfd_missing(vma)) { + pte_unmap_unlock(ptep, ptl); + mem_cgroup_cancel_charge(page, memcg, false); + goto abort; + } + + inc_mm_counter(mm, MM_ANONPAGES); + page_add_new_anon_rmap(page, vma, addr, false); + mem_cgroup_commit_charge(page, memcg, false, false); + if (!is_zone_device_page(page)) + lru_cache_add_active_or_unevictable(page, vma); + get_page(page); + + if (flush) { + flush_cache_page(vma, addr, pte_pfn(*ptep)); + ptep_clear_flush_notify(vma, addr, ptep); + set_pte_at_notify(mm, addr, ptep, entry); + update_mmu_cache(vma, addr, ptep); + } else { + /* No need to invalidate - it was non-present before */ + set_pte_at(mm, addr, ptep, entry); + update_mmu_cache(vma, addr, ptep); + } + + pte_unmap_unlock(ptep, ptl); + *src = MIGRATE_PFN_MIGRATE; + return; + +abort: + *src &= ~MIGRATE_PFN_MIGRATE; +} + +/* + * migrate_vma_pages() - migrate meta-data from src page to dst page + * @migrate: migrate struct containing all migration information + * + * This migrates struct page meta-data from source struct page to destination + * struct page. This effectively finishes the migration from source page to the + * destination page. + */ +static void migrate_vma_pages(struct migrate_vma *migrate) +{ + const unsigned long npages = migrate->npages; + const unsigned long start = migrate->start; + struct vm_area_struct *vma = migrate->vma; + struct mm_struct *mm = vma->vm_mm; + unsigned long addr, i, mmu_start; + bool notified = false; + + for (i = 0, addr = start; i < npages; addr += PAGE_SIZE, i++) { + struct page *newpage = migrate_pfn_to_page(migrate->dst[i]); + struct page *page = migrate_pfn_to_page(migrate->src[i]); + struct address_space *mapping; + int r; + + if (!newpage) { + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + continue; + } + + if (!page) { + if (!(migrate->src[i] & MIGRATE_PFN_MIGRATE)) { + continue; + } + if (!notified) { + mmu_start = addr; + notified = true; + mmu_notifier_invalidate_range_start(mm, + mmu_start, + migrate->end); + } + migrate_vma_insert_page(migrate, addr, newpage, + &migrate->src[i], + &migrate->dst[i]); + continue; + } + + mapping = page_mapping(page); + + if (is_zone_device_page(newpage)) { + if (is_device_private_page(newpage)) { + /* + * For now only support private anonymous when + * migrating to un-addressable device memory. + */ + if (mapping) { + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + continue; + } + } else if (!is_device_public_page(newpage)) { + /* + * Other types of ZONE_DEVICE page are not + * supported. + */ + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + continue; + } + } + + r = migrate_page(mapping, newpage, page, MIGRATE_SYNC_NO_COPY); + if (r != MIGRATEPAGE_SUCCESS) + migrate->src[i] &= ~MIGRATE_PFN_MIGRATE; + } + + if (notified) + mmu_notifier_invalidate_range_end(mm, mmu_start, + migrate->end); +} + +/* + * migrate_vma_finalize() - restore CPU page table entry + * @migrate: migrate struct containing all migration information + * + * This replaces the special migration pte entry with either a mapping to the + * new page if migration was successful for that page, or to the original page + * otherwise. + * + * This also unlocks the pages and puts them back on the lru, or drops the extra + * refcount, for device pages. + */ +static void migrate_vma_finalize(struct migrate_vma *migrate) +{ + const unsigned long npages = migrate->npages; + unsigned long i; + + for (i = 0; i < npages; i++) { + struct page *newpage = migrate_pfn_to_page(migrate->dst[i]); + struct page *page = migrate_pfn_to_page(migrate->src[i]); + + if (!page) { + if (newpage) { + unlock_page(newpage); + put_page(newpage); + } + continue; + } + + if (!(migrate->src[i] & MIGRATE_PFN_MIGRATE) || !newpage) { + if (newpage) { + unlock_page(newpage); + put_page(newpage); + } + newpage = page; + } + + remove_migration_ptes(page, newpage, false); + unlock_page(page); + migrate->cpages--; + + if (is_zone_device_page(page)) + put_page(page); + else + putback_lru_page(page); + + if (newpage != page) { + unlock_page(newpage); + if (is_zone_device_page(newpage)) + put_page(newpage); + else + putback_lru_page(newpage); + } + } +} + +/* + * migrate_vma() - migrate a range of memory inside vma + * + * @ops: migration callback for allocating destination memory and copying + * @vma: virtual memory area containing the range to be migrated + * @start: start address of the range to migrate (inclusive) + * @end: end address of the range to migrate (exclusive) + * @src: array of hmm_pfn_t containing source pfns + * @dst: array of hmm_pfn_t containing destination pfns + * @private: pointer passed back to each of the callback + * Returns: 0 on success, error code otherwise + * + * This function tries to migrate a range of memory virtual address range, using + * callbacks to allocate and copy memory from source to destination. First it + * collects all the pages backing each virtual address in the range, saving this + * inside the src array. Then it locks those pages and unmaps them. Once the pages + * are locked and unmapped, it checks whether each page is pinned or not. Pages + * that aren't pinned have the MIGRATE_PFN_MIGRATE flag set (by this function) + * in the corresponding src array entry. It then restores any pages that are + * pinned, by remapping and unlocking those pages. + * + * At this point it calls the alloc_and_copy() callback. For documentation on + * what is expected from that callback, see struct migrate_vma_ops comments in + * include/linux/migrate.h + * + * After the alloc_and_copy() callback, this function goes over each entry in + * the src array that has the MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE flag + * set. If the corresponding entry in dst array has MIGRATE_PFN_VALID flag set, + * then the function tries to migrate struct page information from the source + * struct page to the destination struct page. If it fails to migrate the struct + * page information, then it clears the MIGRATE_PFN_MIGRATE flag in the src + * array. + * + * At this point all successfully migrated pages have an entry in the src + * array with MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE flag set and the dst + * array entry with MIGRATE_PFN_VALID flag set. + * + * It then calls the finalize_and_map() callback. See comments for "struct + * migrate_vma_ops", in include/linux/migrate.h for details about + * finalize_and_map() behavior. + * + * After the finalize_and_map() callback, for successfully migrated pages, this + * function updates the CPU page table to point to new pages, otherwise it + * restores the CPU page table to point to the original source pages. + * + * Function returns 0 after the above steps, even if no pages were migrated + * (The function only returns an error if any of the arguments are invalid.) + * + * Both src and dst array must be big enough for (end - start) >> PAGE_SHIFT + * unsigned long entries. + */ +int migrate_vma(const struct migrate_vma_ops *ops, + struct vm_area_struct *vma, + unsigned long start, + unsigned long end, + unsigned long *src, + unsigned long *dst, + void *private) +{ + struct migrate_vma migrate; + + /* Sanity check the arguments */ + start &= PAGE_MASK; + end &= PAGE_MASK; + if (!vma || is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_SPECIAL)) + return -EINVAL; + if (start < vma->vm_start || start >= vma->vm_end) + return -EINVAL; + if (end <= vma->vm_start || end > vma->vm_end) + return -EINVAL; + if (!ops || !src || !dst || start >= end) + return -EINVAL; + + memset(src, 0, sizeof(*src) * ((end - start) >> PAGE_SHIFT)); + migrate.src = src; + migrate.dst = dst; + migrate.start = start; + migrate.npages = 0; + migrate.cpages = 0; + migrate.end = end; + migrate.vma = vma; + + /* Collect, and try to unmap source pages */ + migrate_vma_collect(&migrate); + if (!migrate.cpages) + return 0; + + /* Lock and isolate page */ + migrate_vma_prepare(&migrate); + if (!migrate.cpages) + return 0; + + /* Unmap pages */ + migrate_vma_unmap(&migrate); + if (!migrate.cpages) + return 0; + + /* + * At this point pages are locked and unmapped, and thus they have + * stable content and can safely be copied to destination memory that + * is allocated by the callback. + * + * Note that migration can fail in migrate_vma_struct_page() for each + * individual page. + */ + ops->alloc_and_copy(vma, src, dst, start, end, private); + + /* This does the real migration of struct page */ + migrate_vma_pages(&migrate); + + ops->finalize_and_map(vma, src, dst, start, end, private); + + /* Unlock and remap pages */ + migrate_vma_finalize(&migrate); + + return 0; +} +EXPORT_SYMBOL(migrate_vma); +#endif /* defined(MIGRATE_VMA_HELPER) */ diff --git a/mm/mlock.c b/mm/mlock.c index b562b5523a6544e6c0ae6e4f792943441f6217a3..dfc6f19121768ee85f269a8ddd1d5bc0f7a5b6fe 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -365,8 +365,8 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) * @start + PAGE_SIZE when no page could be added by the pte walk. */ static unsigned long __munlock_pagevec_fill(struct pagevec *pvec, - struct vm_area_struct *vma, int zoneid, unsigned long start, - unsigned long end) + struct vm_area_struct *vma, struct zone *zone, + unsigned long start, unsigned long end) { pte_t *pte; spinlock_t *ptl; @@ -394,7 +394,7 @@ static unsigned long __munlock_pagevec_fill(struct pagevec *pvec, * Break if page could not be obtained or the page's node+zone does not * match */ - if (!page || page_zone_id(page) != zoneid) + if (!page || page_zone(page) != zone) break; /* @@ -446,7 +446,6 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, unsigned long page_increm; struct pagevec pvec; struct zone *zone; - int zoneid; pagevec_init(&pvec, 0); /* @@ -481,7 +480,6 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, */ pagevec_add(&pvec, page); zone = page_zone(page); - zoneid = page_zone_id(page); /* * Try to fill the rest of pagevec using fast @@ -490,7 +488,7 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, * pagevec. */ start = __munlock_pagevec_fill(&pvec, vma, - zoneid, start, end); + zone, start, end); __munlock_pagevec(&pvec, zone); goto next; } diff --git a/mm/mmap.c b/mm/mmap.c index f19efcf7541878093eb3c3323a597cf8d1da5ae2..680506faceae91d9da5347f27f1271a9b542addf 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -684,7 +685,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, struct mm_struct *mm = vma->vm_mm; struct vm_area_struct *next = vma->vm_next, *orig_vma = vma; struct address_space *mapping = NULL; - struct rb_root *root = NULL; + struct rb_root_cached *root = NULL; struct anon_vma *anon_vma = NULL; struct file *file = vma->vm_file; bool start_changed = false, end_changed = false; @@ -2639,13 +2640,6 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, if (vma->vm_start >= end) return 0; - if (uf) { - int error = userfaultfd_unmap_prep(vma, start, end, uf); - - if (error) - return error; - } - /* * If we need to split any vma, do it now to save pain later. * @@ -2679,6 +2673,21 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, } vma = prev ? prev->vm_next : mm->mmap; + if (unlikely(uf)) { + /* + * If userfaultfd_unmap_prep returns an error the vmas + * will remain splitted, but userland will get a + * highly unexpected error anyway. This is no + * different than the case where the first of the two + * __split_vma fails, but we don't undo the first + * split, despite we could. This is unlikely enough + * failure that it's not worth optimizing it for. + */ + int error = userfaultfd_unmap_prep(vma, start, end, uf); + if (error) + return error; + } + /* * unlock any mlock()ed ranges before detaching vmas */ @@ -2993,6 +3002,23 @@ void exit_mmap(struct mm_struct *mm) /* Use -1 here to ensure all VMAs in the mm are unmapped */ unmap_vmas(&tlb, vma, 0, -1); + set_bit(MMF_OOM_SKIP, &mm->flags); + if (unlikely(tsk_is_oom_victim(current))) { + /* + * Wait for oom_reap_task() to stop working on this + * mm. Because MMF_OOM_SKIP is already set before + * calling down_read(), oom_reap_task() will not run + * on this "mm" post up_write(). + * + * tsk_is_oom_victim() cannot be set from under us + * either because current->mm is already set to NULL + * under task_lock before calling mmput and oom_mm is + * set not NULL by the OOM killer only if current->mm + * is found not NULL while holding the task_lock. + */ + down_write(&mm->mmap_sem); + up_write(&mm->mmap_sem); + } free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING); tlb_finish_mmu(&tlb, 0, -1); @@ -3314,7 +3340,7 @@ static DEFINE_MUTEX(mm_all_locks_mutex); static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) { - if (!test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) { + if (!test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_root.rb_node)) { /* * The LSB of head.next can't change from under us * because we hold the mm_all_locks_mutex. @@ -3330,7 +3356,7 @@ static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) * anon_vma->root->rwsem. */ if (__test_and_set_bit(0, (unsigned long *) - &anon_vma->root->rb_root.rb_node)) + &anon_vma->root->rb_root.rb_root.rb_node)) BUG(); } } @@ -3432,7 +3458,7 @@ int mm_take_all_locks(struct mm_struct *mm) static void vm_unlock_anon_vma(struct anon_vma *anon_vma) { - if (test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) { + if (test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_root.rb_node)) { /* * The LSB of head.next can't change to 0 from under * us because we hold the mm_all_locks_mutex. @@ -3446,7 +3472,7 @@ static void vm_unlock_anon_vma(struct anon_vma *anon_vma) * anon_vma->root->rwsem. */ if (!__test_and_clear_bit(0, (unsigned long *) - &anon_vma->root->rb_root.rb_node)) + &anon_vma->root->rb_root.rb_root.rb_node)) BUG(); anon_vma_unlock_write(anon_vma); } @@ -3514,7 +3540,7 @@ static int init_user_reserve(void) { unsigned long free_kbytes; - free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); + free_kbytes = global_zone_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); sysctl_user_reserve_kbytes = min(free_kbytes / 32, 1UL << 17); return 0; @@ -3535,7 +3561,7 @@ static int init_admin_reserve(void) { unsigned long free_kbytes; - free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); + free_kbytes = global_zone_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); sysctl_admin_reserve_kbytes = min(free_kbytes / 32, 1UL << 13); return 0; @@ -3579,7 +3605,7 @@ static int reserve_mem_notifier(struct notifier_block *nb, break; case MEM_OFFLINE: - free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); + free_kbytes = global_zone_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); if (sysctl_user_reserve_kbytes > free_kbytes) { init_user_reserve(); diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 54ca545629286223a16ef931830a3757b29da77d..314285284e6e6a4c764d0f8126dd0fecf8f7f84e 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -174,20 +174,6 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, srcu_read_unlock(&srcu, id); } -void __mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address) -{ - struct mmu_notifier *mn; - int id; - - id = srcu_read_lock(&srcu); - hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { - if (mn->ops->invalidate_page) - mn->ops->invalidate_page(mn, mm, address); - } - srcu_read_unlock(&srcu, id); -} - void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end) { diff --git a/mm/mprotect.c b/mm/mprotect.c index 1a8c9ca83e48ec9a998ea0882e24c58dee0d3dd1..6d3e2f0822901605aa3554234e3e96838997b0ba 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -64,6 +64,7 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, atomic_read(&vma->vm_mm->mm_users) == 1) target_node = numa_node_id(); + flush_tlb_batched_pending(vma->vm_mm); arch_enter_lazy_mmu_mode(); do { oldpte = *pte; @@ -124,6 +125,20 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, pages++; } + + if (is_write_device_private_entry(entry)) { + pte_t newpte; + + /* + * We do not preserve soft-dirtiness. See + * copy_one_pte() for explanation. + */ + make_device_private_entry_read(&entry); + newpte = swp_entry_to_pte(entry); + set_pte_at(mm, addr, pte, newpte); + + pages++; + } } } while (pte++, addr += PAGE_SIZE, addr != end); arch_leave_lazy_mmu_mode(); @@ -148,7 +163,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma, unsigned long this_pages; next = pmd_addr_end(addr, end); - if (!pmd_trans_huge(*pmd) && !pmd_devmap(*pmd) + if (!is_swap_pmd(*pmd) && !pmd_trans_huge(*pmd) && !pmd_devmap(*pmd) && pmd_none_or_clear_bad(pmd)) continue; @@ -158,7 +173,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma, mmu_notifier_invalidate_range_start(mm, mni_start, end); } - if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { + if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { if (next - addr != HPAGE_PMD_SIZE) { __split_huge_pmd(vma, pmd, addr, false, NULL); } else { @@ -243,7 +258,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma, BUG_ON(addr >= end); pgd = pgd_offset(mm, addr); flush_cache_range(vma, addr, end); - set_tlb_flush_pending(mm); + inc_tlb_flush_pending(mm); do { next = pgd_addr_end(addr, end); if (pgd_none_or_clear_bad(pgd)) @@ -255,7 +270,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma, /* Only flush the TLB if we actually modified any entries: */ if (pages) flush_tlb_range(vma, start, end); - clear_tlb_flush_pending(mm); + dec_tlb_flush_pending(mm); return pages; } diff --git a/mm/mremap.c b/mm/mremap.c index cd8a1b199ef9496ef63a50d97f92e648b8eecd58..cfec004c4ff9a95511940039d6975d270bf37996 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -152,6 +152,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, new_ptl = pte_lockptr(mm, new_pmd); if (new_ptl != old_ptl) spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING); + flush_tlb_batched_pending(vma->vm_mm); arch_enter_lazy_mmu_mode(); for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE, @@ -222,7 +223,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma, new_pmd = alloc_new_pmd(vma->vm_mm, vma, new_addr); if (!new_pmd) break; - if (pmd_trans_huge(*old_pmd)) { + if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd)) { if (extent == HPAGE_PMD_SIZE) { bool moved; /* See comment in move_ptes() */ @@ -383,6 +384,19 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr, if (!vma || vma->vm_start > addr) return ERR_PTR(-EFAULT); + /* + * !old_len is a special case where an attempt is made to 'duplicate' + * a mapping. This makes no sense for private mappings as it will + * instead create a fresh/new mapping unrelated to the original. This + * is contrary to the basic idea of mremap which creates new mappings + * based on the original. There are no known use cases for this + * behavior. As a result, fail such attempts. + */ + if (!old_len && !(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) { + pr_warn_once("%s (%d): attempted to duplicate a private mapping with mremap. This is not supported.\n", current->comm, current->pid); + return ERR_PTR(-EINVAL); + } + if (is_vm_hugetlb_page(vma)) return ERR_PTR(-EINVAL); @@ -428,6 +442,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr, static unsigned long mremap_to(unsigned long addr, unsigned long old_len, unsigned long new_addr, unsigned long new_len, bool *locked, struct vm_userfaultfd_ctx *uf, + struct list_head *uf_unmap_early, struct list_head *uf_unmap) { struct mm_struct *mm = current->mm; @@ -446,7 +461,7 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len, if (addr + old_len > new_addr && new_addr + new_len > addr) goto out; - ret = do_munmap(mm, new_addr, new_len, NULL); + ret = do_munmap(mm, new_addr, new_len, uf_unmap_early); if (ret) goto out; @@ -514,6 +529,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long charged = 0; bool locked = false; struct vm_userfaultfd_ctx uf = NULL_VM_UFFD_CTX; + LIST_HEAD(uf_unmap_early); LIST_HEAD(uf_unmap); if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) @@ -541,7 +557,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, if (flags & MREMAP_FIXED) { ret = mremap_to(addr, old_len, new_addr, new_len, - &locked, &uf, &uf_unmap); + &locked, &uf, &uf_unmap_early, &uf_unmap); goto out; } @@ -621,6 +637,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, up_write(¤t->mm->mmap_sem); if (locked && new_len > old_len) mm_populate(new_addr + old_len, new_len - old_len); + userfaultfd_unmap_complete(mm, &uf_unmap_early); mremap_userfaultfd_complete(&uf, addr, new_addr, old_len); userfaultfd_unmap_complete(mm, &uf_unmap); return ret; diff --git a/mm/nobootmem.c b/mm/nobootmem.c index 36454d0f96ee6b91383554c83015a2b47e66f038..3637809a18d04f9c20d1b00d70687ae1eb00b282 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c @@ -146,22 +146,6 @@ static unsigned long __init free_low_memory_core_early(void) NULL) count += __free_memory_core(start, end); -#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK - { - phys_addr_t size; - - /* Free memblock.reserved array if it was allocated */ - size = get_allocated_memblock_reserved_regions_info(&start); - if (size) - count += __free_memory_core(start, start + size); - - /* Free memblock.memory array if it was allocated */ - size = get_allocated_memblock_memory_regions_info(&start); - if (size) - count += __free_memory_core(start, start + size); - } -#endif - return count; } diff --git a/mm/nommu.c b/mm/nommu.c index fc184f597d59d9af942f8dc60229b999173fe22f..17c00d93de2e4973278845e98554ce2040445f65 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1164,17 +1164,12 @@ static int do_mmap_private(struct vm_area_struct *vma, if (vma->vm_file) { /* read the contents of a file into the copy */ - mm_segment_t old_fs; loff_t fpos; fpos = vma->vm_pgoff; fpos <<= PAGE_SHIFT; - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = __vfs_read(vma->vm_file, base, len, &fpos); - set_fs(old_fs); - + ret = kernel_read(vma->vm_file, base, len, &fpos); if (ret < 0) goto error_free; @@ -1962,7 +1957,7 @@ static int __meminit init_user_reserve(void) { unsigned long free_kbytes; - free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); + free_kbytes = global_zone_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); sysctl_user_reserve_kbytes = min(free_kbytes / 32, 1UL << 17); return 0; @@ -1983,7 +1978,7 @@ static int __meminit init_admin_reserve(void) { unsigned long free_kbytes; - free_kbytes = global_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); + free_kbytes = global_zone_page_state(NR_FREE_PAGES) << (PAGE_SHIFT - 10); sysctl_admin_reserve_kbytes = min(free_kbytes / 32, 1UL << 13); return 0; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 9e8b4f030c1c43cb92da706306e1b9390658af7b..dee0f75c301337af62156d2ae46d5c5391cc6127 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "internal.h" @@ -495,11 +496,27 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) } /* - * increase mm_users only after we know we will reap something so - * that the mmput_async is called only when we have reaped something - * and delayed __mmput doesn't matter that much + * If the mm has notifiers then we would need to invalidate them around + * unmap_page_range and that is risky because notifiers can sleep and + * what they do is basically undeterministic. So let's have a short + * sleep to give the oom victim some more time. + * TODO: we really want to get rid of this ugly hack and make sure that + * notifiers cannot block for unbounded amount of time and add + * mmu_notifier_invalidate_range_{start,end} around unmap_page_range */ - if (!mmget_not_zero(mm)) { + if (mm_has_notifiers(mm)) { + up_read(&mm->mmap_sem); + schedule_timeout_idle(HZ); + goto unlock_oom; + } + + /* + * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't + * work on the mm anymore. The check for MMF_OOM_SKIP must run + * under mmap_sem for reading because it serializes against the + * down_write();up_write() cycle in exit_mmap(). + */ + if (test_bit(MMF_OOM_SKIP, &mm->flags)) { up_read(&mm->mmap_sem); trace_skip_task_reaping(tsk->pid); goto unlock_oom; @@ -542,12 +559,6 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) K(get_mm_counter(mm, MM_SHMEMPAGES))); up_read(&mm->mmap_sem); - /* - * Drop our reference but make sure the mmput slow path is called from a - * different context because we shouldn't risk we get stuck there and - * put the oom_reaper out of the way. - */ - mmput_async(mm); trace_finish_task_reaping(tsk->pid); unlock_oom: mutex_unlock(&oom_lock); @@ -824,7 +835,8 @@ static void oom_kill_process(struct oom_control *oc, const char *message) /* * If the task is already exiting, don't alarm the sysadmin or kill - * its children or threads, just set TIF_MEMDIE so it can die quickly + * its children or threads, just give it access to memory reserves + * so it can die quickly */ task_lock(p); if (task_will_free_mem(p)) { @@ -889,9 +901,9 @@ static void oom_kill_process(struct oom_control *oc, const char *message) count_memcg_event_mm(mm, OOM_KILL); /* - * We should send SIGKILL before setting TIF_MEMDIE in order to prevent - * the OOM victim from depleting the memory reserves from the user - * space under its control. + * We should send SIGKILL before granting access to memory reserves + * in order to prevent the OOM victim from depleting the memory + * reserves from the user space under its control. */ do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true); mark_oom_victim(victim); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 96e93b214d317baf4fb4ffbb5fcbe726e110980d..0b9c5cbe8eba086b385e489eefac7d601aed2535 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -363,7 +363,7 @@ static unsigned long global_dirtyable_memory(void) { unsigned long x; - x = global_page_state(NR_FREE_PAGES); + x = global_zone_page_state(NR_FREE_PAGES); /* * Pages reserved for the kernel should not be considered * dirtyable, to prevent a situation where reclaim has to @@ -1405,7 +1405,7 @@ void wb_update_bandwidth(struct bdi_writeback *wb, unsigned long start_time) * will look to see if it needs to start dirty throttling. * * If dirty_poll_interval is too low, big NUMA machines will call the expensive - * global_page_state() too often. So scale it near-sqrt to the safety margin + * global_zone_page_state() too often. So scale it near-sqrt to the safety margin * (the number of pages we may dirty without exceeding the dirty limits). */ static unsigned long dirty_poll_interval(unsigned long dirty, @@ -2724,9 +2724,12 @@ EXPORT_SYMBOL(clear_page_dirty_for_io); int test_clear_page_writeback(struct page *page) { struct address_space *mapping = page_mapping(page); + struct mem_cgroup *memcg; + struct lruvec *lruvec; int ret; - lock_page_memcg(page); + memcg = lock_page_memcg(page); + lruvec = mem_cgroup_page_lruvec(page, page_pgdat(page)); if (mapping && mapping_use_writeback_tags(mapping)) { struct inode *inode = mapping->host; struct backing_dev_info *bdi = inode_to_bdi(inode); @@ -2754,12 +2757,18 @@ int test_clear_page_writeback(struct page *page) } else { ret = TestClearPageWriteback(page); } + /* + * NOTE: Page might be free now! Writeback doesn't hold a page + * reference on its own, it relies on truncation to wait for + * the clearing of PG_writeback. The below can only access + * page state that is static across allocation cycles. + */ if (ret) { - dec_lruvec_page_state(page, NR_WRITEBACK); + dec_lruvec_state(lruvec, NR_WRITEBACK); dec_zone_page_state(page, NR_ZONE_WRITE_PENDING); inc_node_page_state(page, NR_WRITTEN); } - unlock_page_memcg(page); + __unlock_page_memcg(memcg); return ret; } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6d30e914afb6c1b9ecc77b33ee5e01fc7a0ed6b3..77e4d3c5c57b72dcd7e411a03707c26dc85c7c04 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -66,6 +66,8 @@ #include #include #include +#include +#include #include #include @@ -1188,7 +1190,7 @@ static void __meminit __init_single_pfn(unsigned long pfn, unsigned long zone, } #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT -static void init_reserved_page(unsigned long pfn) +static void __meminit init_reserved_page(unsigned long pfn) { pg_data_t *pgdat; int nid, zid; @@ -1584,6 +1586,10 @@ void __init page_alloc_init_late(void) /* Reinit limits that are based on free pages after the kernel is up */ files_maxfiles_init(); #endif +#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK + /* Discard memblock private memory */ + memblock_discard(); +#endif for_each_populated_zone(zone) set_zone_contiguous(zone); @@ -2531,9 +2537,14 @@ void drain_all_pages(struct zone *zone) #ifdef CONFIG_HIBERNATION +/* + * Touch the watchdog for every WD_PAGE_COUNT pages. + */ +#define WD_PAGE_COUNT (128*1024) + void mark_free_pages(struct zone *zone) { - unsigned long pfn, max_zone_pfn; + unsigned long pfn, max_zone_pfn, page_count = WD_PAGE_COUNT; unsigned long flags; unsigned int order, t; struct page *page; @@ -2548,6 +2559,11 @@ void mark_free_pages(struct zone *zone) if (pfn_valid(pfn)) { page = pfn_to_page(pfn); + if (!--page_count) { + touch_nmi_watchdog(); + page_count = WD_PAGE_COUNT; + } + if (page_zone(page) != zone) continue; @@ -2561,8 +2577,13 @@ void mark_free_pages(struct zone *zone) unsigned long i; pfn = page_to_pfn(page); - for (i = 0; i < (1UL << order); i++) + for (i = 0; i < (1UL << order); i++) { + if (!--page_count) { + touch_nmi_watchdog(); + page_count = WD_PAGE_COUNT; + } swsusp_set_page_free(pfn_to_page(pfn + i)); + } } } spin_unlock_irqrestore(&zone->lock, flags); @@ -2720,18 +2741,18 @@ int __isolate_free_page(struct page *page, unsigned int order) static inline void zone_statistics(struct zone *preferred_zone, struct zone *z) { #ifdef CONFIG_NUMA - enum zone_stat_item local_stat = NUMA_LOCAL; + enum numa_stat_item local_stat = NUMA_LOCAL; if (z->node != numa_node_id()) local_stat = NUMA_OTHER; if (z->node == preferred_zone->node) - __inc_zone_state(z, NUMA_HIT); + __inc_numa_state(z, NUMA_HIT); else { - __inc_zone_state(z, NUMA_MISS); - __inc_zone_state(preferred_zone, NUMA_FOREIGN); + __inc_numa_state(z, NUMA_MISS); + __inc_numa_state(preferred_zone, NUMA_FOREIGN); } - __inc_zone_state(z, local_stat); + __inc_numa_state(z, local_stat); #endif } @@ -2930,7 +2951,7 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark, { long min = mark; int o; - const bool alloc_harder = (alloc_flags & ALLOC_HARDER); + const bool alloc_harder = (alloc_flags & (ALLOC_HARDER|ALLOC_OOM)); /* free_pages may go negative - that's OK */ free_pages -= (1 << order) - 1; @@ -2943,10 +2964,21 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark, * the high-atomic reserves. This will over-estimate the size of the * atomic reserve but it avoids a search. */ - if (likely(!alloc_harder)) + if (likely(!alloc_harder)) { free_pages -= z->nr_reserved_highatomic; - else - min -= min / 4; + } else { + /* + * OOM victims can try even harder than normal ALLOC_HARDER + * users on the grounds that it's definitely going to be in + * the exit path shortly and free memory. Any allocation it + * makes during the free path will be small and short-lived. + */ + if (alloc_flags & ALLOC_OOM) + min -= min / 2; + else + min -= min / 4; + } + #ifdef CONFIG_CMA /* If allocation can't use CMA areas don't use free CMA pages */ @@ -3184,7 +3216,7 @@ static void warn_alloc_show_mem(gfp_t gfp_mask, nodemask_t *nodemask) * of allowed nodes. */ if (!(gfp_mask & __GFP_NOMEMALLOC)) - if (test_thread_flag(TIF_MEMDIE) || + if (tsk_is_oom_victim(current) || (current->flags & (PF_MEMALLOC | PF_EXITING))) filter &= ~SHOW_MEM_FILTER_NODES; if (in_interrupt() || !(gfp_mask & __GFP_DIRECT_RECLAIM)) @@ -3271,10 +3303,13 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, /* * Go through the zonelist yet one more time, keep very high watermark * here, this is only to catch a parallel oom killing, we must fail if - * we're still under heavy pressure. + * we're still under heavy pressure. But make sure that this reclaim + * attempt shall not depend on __GFP_DIRECT_RECLAIM && !__GFP_NORETRY + * allocation which will never fail due to oom_lock already held. */ - page = get_page_from_freelist(gfp_mask | __GFP_HARDWALL, order, - ALLOC_WMARK_HIGH|ALLOC_CPUSET, ac); + page = get_page_from_freelist((gfp_mask | __GFP_HARDWALL) & + ~__GFP_DIRECT_RECLAIM, order, + ALLOC_WMARK_HIGH|ALLOC_CPUSET, ac); if (page) goto out; @@ -3490,6 +3525,47 @@ should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_fla } #endif /* CONFIG_COMPACTION */ +#ifdef CONFIG_LOCKDEP +struct lockdep_map __fs_reclaim_map = + STATIC_LOCKDEP_MAP_INIT("fs_reclaim", &__fs_reclaim_map); + +static bool __need_fs_reclaim(gfp_t gfp_mask) +{ + gfp_mask = current_gfp_context(gfp_mask); + + /* no reclaim without waiting on it */ + if (!(gfp_mask & __GFP_DIRECT_RECLAIM)) + return false; + + /* this guy won't enter reclaim */ + if ((current->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) + return false; + + /* We're only interested __GFP_FS allocations for now */ + if (!(gfp_mask & __GFP_FS)) + return false; + + if (gfp_mask & __GFP_NOLOCKDEP) + return false; + + return true; +} + +void fs_reclaim_acquire(gfp_t gfp_mask) +{ + if (__need_fs_reclaim(gfp_mask)) + lock_map_acquire(&__fs_reclaim_map); +} +EXPORT_SYMBOL_GPL(fs_reclaim_acquire); + +void fs_reclaim_release(gfp_t gfp_mask) +{ + if (__need_fs_reclaim(gfp_mask)) + lock_map_release(&__fs_reclaim_map); +} +EXPORT_SYMBOL_GPL(fs_reclaim_release); +#endif + /* Perform direct synchronous page reclaim */ static int __perform_reclaim(gfp_t gfp_mask, unsigned int order, @@ -3504,7 +3580,7 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order, /* We now go into synchronous reclaim */ cpuset_memory_pressure_bump(); noreclaim_flag = memalloc_noreclaim_save(); - lockdep_set_current_reclaim_state(gfp_mask); + fs_reclaim_acquire(gfp_mask); reclaim_state.reclaimed_slab = 0; current->reclaim_state = &reclaim_state; @@ -3512,7 +3588,7 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order, ac->nodemask); current->reclaim_state = NULL; - lockdep_clear_current_reclaim_state(); + fs_reclaim_release(gfp_mask); memalloc_noreclaim_restore(noreclaim_flag); cond_resched(); @@ -3603,21 +3679,46 @@ gfp_to_alloc_flags(gfp_t gfp_mask) return alloc_flags; } -bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) +static bool oom_reserves_allowed(struct task_struct *tsk) { - if (unlikely(gfp_mask & __GFP_NOMEMALLOC)) + if (!tsk_is_oom_victim(tsk)) return false; + /* + * !MMU doesn't have oom reaper so give access to memory reserves + * only to the thread with TIF_MEMDIE set + */ + if (!IS_ENABLED(CONFIG_MMU) && !test_thread_flag(TIF_MEMDIE)) + return false; + + return true; +} + +/* + * Distinguish requests which really need access to full memory + * reserves from oom victims which can live with a portion of it + */ +static inline int __gfp_pfmemalloc_flags(gfp_t gfp_mask) +{ + if (unlikely(gfp_mask & __GFP_NOMEMALLOC)) + return 0; if (gfp_mask & __GFP_MEMALLOC) - return true; + return ALLOC_NO_WATERMARKS; if (in_serving_softirq() && (current->flags & PF_MEMALLOC)) - return true; - if (!in_interrupt() && - ((current->flags & PF_MEMALLOC) || - unlikely(test_thread_flag(TIF_MEMDIE)))) - return true; + return ALLOC_NO_WATERMARKS; + if (!in_interrupt()) { + if (current->flags & PF_MEMALLOC) + return ALLOC_NO_WATERMARKS; + else if (oom_reserves_allowed(current)) + return ALLOC_OOM; + } - return false; + return 0; +} + +bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) +{ + return !!__gfp_pfmemalloc_flags(gfp_mask); } /* @@ -3770,6 +3871,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, unsigned long alloc_start = jiffies; unsigned int stall_timeout = 10 * HZ; unsigned int cpuset_mems_cookie; + int reserve_flags; /* * In the slowpath, we sanity check order to avoid ever trying to @@ -3875,15 +3977,16 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, if (gfp_mask & __GFP_KSWAPD_RECLAIM) wake_all_kswapds(order, ac); - if (gfp_pfmemalloc_allowed(gfp_mask)) - alloc_flags = ALLOC_NO_WATERMARKS; + reserve_flags = __gfp_pfmemalloc_flags(gfp_mask); + if (reserve_flags) + alloc_flags = reserve_flags; /* * Reset the zonelist iterators if memory policies can be ignored. * These allocations are high priority and system rather than user * orientated. */ - if (!(alloc_flags & ALLOC_CPUSET) || (alloc_flags & ALLOC_NO_WATERMARKS)) { + if (!(alloc_flags & ALLOC_CPUSET) || reserve_flags) { ac->zonelist = node_zonelist(numa_node_id(), gfp_mask); ac->preferred_zoneref = first_zones_zonelist(ac->zonelist, ac->high_zoneidx, ac->nodemask); @@ -3960,8 +4063,8 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto got_pg; /* Avoid allocations with no watermarks from looping endlessly */ - if (test_thread_flag(TIF_MEMDIE) && - (alloc_flags == ALLOC_NO_WATERMARKS || + if (tsk_is_oom_victim(current) && + (alloc_flags == ALLOC_OOM || (gfp_mask & __GFP_NOMEMALLOC))) goto nopage; @@ -4041,7 +4144,8 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order, *alloc_flags |= ALLOC_CPUSET; } - lockdep_trace_alloc(gfp_mask); + fs_reclaim_acquire(gfp_mask); + fs_reclaim_release(gfp_mask); might_sleep_if(gfp_mask & __GFP_DIRECT_RECLAIM); @@ -4079,10 +4183,11 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid, { struct page *page; unsigned int alloc_flags = ALLOC_WMARK_LOW; - gfp_t alloc_mask = gfp_mask; /* The gfp_t that was actually used for allocation */ + gfp_t alloc_mask; /* The gfp_t that was actually used for allocation */ struct alloc_context ac = { }; gfp_mask &= gfp_allowed_mask; + alloc_mask = gfp_mask; if (!prepare_alloc_pages(gfp_mask, order, preferred_nid, nodemask, &ac, &alloc_mask, &alloc_flags)) return NULL; @@ -4443,7 +4548,7 @@ long si_mem_available(void) * Estimate the amount of memory available for userspace allocations, * without causing swapping. */ - available = global_page_state(NR_FREE_PAGES) - totalreserve_pages; + available = global_zone_page_state(NR_FREE_PAGES) - totalreserve_pages; /* * Not all the page cache can be freed, otherwise the system will @@ -4458,8 +4563,9 @@ long si_mem_available(void) * Part of the reclaimable slab consists of items that are in use, * and cannot be freed. Cap this estimate at the low watermark. */ - available += global_page_state(NR_SLAB_RECLAIMABLE) - - min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low); + available += global_node_page_state(NR_SLAB_RECLAIMABLE) - + min(global_node_page_state(NR_SLAB_RECLAIMABLE) / 2, + wmark_low); if (available < 0) available = 0; @@ -4471,7 +4577,7 @@ void si_meminfo(struct sysinfo *val) { val->totalram = totalram_pages; val->sharedram = global_node_page_state(NR_SHMEM); - val->freeram = global_page_state(NR_FREE_PAGES); + val->freeram = global_zone_page_state(NR_FREE_PAGES); val->bufferram = nr_blockdev_pages(); val->totalhigh = totalhigh_pages; val->freehigh = nr_free_highpages(); @@ -4602,15 +4708,15 @@ void show_free_areas(unsigned int filter, nodemask_t *nodemask) global_node_page_state(NR_FILE_DIRTY), global_node_page_state(NR_WRITEBACK), global_node_page_state(NR_UNSTABLE_NFS), - global_page_state(NR_SLAB_RECLAIMABLE), - global_page_state(NR_SLAB_UNRECLAIMABLE), + global_node_page_state(NR_SLAB_RECLAIMABLE), + global_node_page_state(NR_SLAB_UNRECLAIMABLE), global_node_page_state(NR_FILE_MAPPED), global_node_page_state(NR_SHMEM), - global_page_state(NR_PAGETABLE), - global_page_state(NR_BOUNCE), - global_page_state(NR_FREE_PAGES), + global_zone_page_state(NR_PAGETABLE), + global_zone_page_state(NR_BOUNCE), + global_zone_page_state(NR_FREE_PAGES), free_pcp, - global_page_state(NR_FREE_CMA_PAGES)); + global_zone_page_state(NR_FREE_CMA_PAGES)); for_each_online_pgdat(pgdat) { if (show_mem_node_skip(filter, pgdat->node_id, nodemask)) @@ -4772,18 +4878,17 @@ static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref) * * Add all populated zones of a node to the zonelist. */ -static int build_zonelists_node(pg_data_t *pgdat, struct zonelist *zonelist, - int nr_zones) +static int build_zonerefs_node(pg_data_t *pgdat, struct zoneref *zonerefs) { struct zone *zone; enum zone_type zone_type = MAX_NR_ZONES; + int nr_zones = 0; do { zone_type--; zone = pgdat->node_zones + zone_type; if (managed_zone(zone)) { - zoneref_set_zone(zone, - &zonelist->_zonerefs[nr_zones++]); + zoneref_set_zone(zone, &zonerefs[nr_zones++]); check_highest_zone(zone_type); } } while (zone_type); @@ -4791,52 +4896,18 @@ static int build_zonelists_node(pg_data_t *pgdat, struct zonelist *zonelist, return nr_zones; } - -/* - * zonelist_order: - * 0 = automatic detection of better ordering. - * 1 = order by ([node] distance, -zonetype) - * 2 = order by (-zonetype, [node] distance) - * - * If not NUMA, ZONELIST_ORDER_ZONE and ZONELIST_ORDER_NODE will create - * the same zonelist. So only NUMA can configure this param. - */ -#define ZONELIST_ORDER_DEFAULT 0 -#define ZONELIST_ORDER_NODE 1 -#define ZONELIST_ORDER_ZONE 2 - -/* zonelist order in the kernel. - * set_zonelist_order() will set this to NODE or ZONE. - */ -static int current_zonelist_order = ZONELIST_ORDER_DEFAULT; -static char zonelist_order_name[3][8] = {"Default", "Node", "Zone"}; - - #ifdef CONFIG_NUMA -/* The value user specified ....changed by config */ -static int user_zonelist_order = ZONELIST_ORDER_DEFAULT; -/* string for sysctl */ -#define NUMA_ZONELIST_ORDER_LEN 16 -char numa_zonelist_order[16] = "default"; - -/* - * interface for configure zonelist ordering. - * command line option "numa_zonelist_order" - * = "[dD]efault - default, automatic configuration. - * = "[nN]ode - order by node locality, then by zone within node - * = "[zZ]one - order by zone, then by locality within zone - */ static int __parse_numa_zonelist_order(char *s) { - if (*s == 'd' || *s == 'D') { - user_zonelist_order = ZONELIST_ORDER_DEFAULT; - } else if (*s == 'n' || *s == 'N') { - user_zonelist_order = ZONELIST_ORDER_NODE; - } else if (*s == 'z' || *s == 'Z') { - user_zonelist_order = ZONELIST_ORDER_ZONE; - } else { - pr_warn("Ignoring invalid numa_zonelist_order value: %s\n", s); + /* + * We used to support different zonlists modes but they turned + * out to be just not useful. Let's keep the warning in place + * if somebody still use the cmd line parameter so that we do + * not fail it silently + */ + if (!(*s == 'd' || *s == 'D' || *s == 'n' || *s == 'N')) { + pr_warn("Ignoring unsupported numa_zonelist_order value: %s\n", s); return -EINVAL; } return 0; @@ -4844,19 +4915,15 @@ static int __parse_numa_zonelist_order(char *s) static __init int setup_numa_zonelist_order(char *s) { - int ret; - if (!s) return 0; - ret = __parse_numa_zonelist_order(s); - if (ret == 0) - strlcpy(numa_zonelist_order, s, NUMA_ZONELIST_ORDER_LEN); - - return ret; + return __parse_numa_zonelist_order(s); } early_param("numa_zonelist_order", setup_numa_zonelist_order); +char numa_zonelist_order[] = "Node"; + /* * sysctl handler for numa_zonelist_order */ @@ -4864,40 +4931,17 @@ int numa_zonelist_order_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { - char saved_string[NUMA_ZONELIST_ORDER_LEN]; + char *str; int ret; - static DEFINE_MUTEX(zl_order_mutex); - mutex_lock(&zl_order_mutex); - if (write) { - if (strlen((char *)table->data) >= NUMA_ZONELIST_ORDER_LEN) { - ret = -EINVAL; - goto out; - } - strcpy(saved_string, (char *)table->data); - } - ret = proc_dostring(table, write, buffer, length, ppos); - if (ret) - goto out; - if (write) { - int oldval = user_zonelist_order; + if (!write) + return proc_dostring(table, write, buffer, length, ppos); + str = memdup_user_nul(buffer, 16); + if (IS_ERR(str)) + return PTR_ERR(str); - ret = __parse_numa_zonelist_order((char *)table->data); - if (ret) { - /* - * bogus value. restore saved string - */ - strncpy((char *)table->data, saved_string, - NUMA_ZONELIST_ORDER_LEN); - user_zonelist_order = oldval; - } else if (oldval != user_zonelist_order) { - mutex_lock(&zonelists_mutex); - build_all_zonelists(NULL, NULL); - mutex_unlock(&zonelists_mutex); - } - } -out: - mutex_unlock(&zl_order_mutex); + ret = __parse_numa_zonelist_order(str); + kfree(str); return ret; } @@ -4971,17 +5015,24 @@ static int find_next_best_node(int node, nodemask_t *used_node_mask) * This results in maximum locality--normal zone overflows into local * DMA zone, if any--but risks exhausting DMA zone. */ -static void build_zonelists_in_node_order(pg_data_t *pgdat, int node) +static void build_zonelists_in_node_order(pg_data_t *pgdat, int *node_order, + unsigned nr_nodes) { - int j; - struct zonelist *zonelist; + struct zoneref *zonerefs; + int i; + + zonerefs = pgdat->node_zonelists[ZONELIST_FALLBACK]._zonerefs; + + for (i = 0; i < nr_nodes; i++) { + int nr_zones; - zonelist = &pgdat->node_zonelists[ZONELIST_FALLBACK]; - for (j = 0; zonelist->_zonerefs[j].zone != NULL; j++) - ; - j = build_zonelists_node(NODE_DATA(node), zonelist, j); - zonelist->_zonerefs[j].zone = NULL; - zonelist->_zonerefs[j].zone_idx = 0; + pg_data_t *node = NODE_DATA(node_order[i]); + + nr_zones = build_zonerefs_node(node, zonerefs); + zonerefs += nr_zones; + } + zonerefs->zone = NULL; + zonerefs->zone_idx = 0; } /* @@ -4989,13 +5040,14 @@ static void build_zonelists_in_node_order(pg_data_t *pgdat, int node) */ static void build_thisnode_zonelists(pg_data_t *pgdat) { - int j; - struct zonelist *zonelist; + struct zoneref *zonerefs; + int nr_zones; - zonelist = &pgdat->node_zonelists[ZONELIST_NOFALLBACK]; - j = build_zonelists_node(pgdat, zonelist, 0); - zonelist->_zonerefs[j].zone = NULL; - zonelist->_zonerefs[j].zone_idx = 0; + zonerefs = pgdat->node_zonelists[ZONELIST_NOFALLBACK]._zonerefs; + nr_zones = build_zonerefs_node(pgdat, zonerefs); + zonerefs += nr_zones; + zonerefs->zone = NULL; + zonerefs->zone_idx = 0; } /* @@ -5004,79 +5056,13 @@ static void build_thisnode_zonelists(pg_data_t *pgdat) * exhausted, but results in overflowing to remote node while memory * may still exist in local DMA zone. */ -static int node_order[MAX_NUMNODES]; - -static void build_zonelists_in_zone_order(pg_data_t *pgdat, int nr_nodes) -{ - int pos, j, node; - int zone_type; /* needs to be signed */ - struct zone *z; - struct zonelist *zonelist; - - zonelist = &pgdat->node_zonelists[ZONELIST_FALLBACK]; - pos = 0; - for (zone_type = MAX_NR_ZONES - 1; zone_type >= 0; zone_type--) { - for (j = 0; j < nr_nodes; j++) { - node = node_order[j]; - z = &NODE_DATA(node)->node_zones[zone_type]; - if (managed_zone(z)) { - zoneref_set_zone(z, - &zonelist->_zonerefs[pos++]); - check_highest_zone(zone_type); - } - } - } - zonelist->_zonerefs[pos].zone = NULL; - zonelist->_zonerefs[pos].zone_idx = 0; -} - -#if defined(CONFIG_64BIT) -/* - * Devices that require DMA32/DMA are relatively rare and do not justify a - * penalty to every machine in case the specialised case applies. Default - * to Node-ordering on 64-bit NUMA machines - */ -static int default_zonelist_order(void) -{ - return ZONELIST_ORDER_NODE; -} -#else -/* - * On 32-bit, the Normal zone needs to be preserved for allocations accessible - * by the kernel. If processes running on node 0 deplete the low memory zone - * then reclaim will occur more frequency increasing stalls and potentially - * be easier to OOM if a large percentage of the zone is under writeback or - * dirty. The problem is significantly worse if CONFIG_HIGHPTE is not set. - * Hence, default to zone ordering on 32-bit. - */ -static int default_zonelist_order(void) -{ - return ZONELIST_ORDER_ZONE; -} -#endif /* CONFIG_64BIT */ - -static void set_zonelist_order(void) -{ - if (user_zonelist_order == ZONELIST_ORDER_DEFAULT) - current_zonelist_order = default_zonelist_order(); - else - current_zonelist_order = user_zonelist_order; -} static void build_zonelists(pg_data_t *pgdat) { - int i, node, load; + static int node_order[MAX_NUMNODES]; + int node, load, nr_nodes = 0; nodemask_t used_mask; int local_node, prev_node; - struct zonelist *zonelist; - unsigned int order = current_zonelist_order; - - /* initialize zonelists */ - for (i = 0; i < MAX_ZONELISTS; i++) { - zonelist = pgdat->node_zonelists + i; - zonelist->_zonerefs[0].zone = NULL; - zonelist->_zonerefs[0].zone_idx = 0; - } /* NUMA-aware ordering of nodes */ local_node = pgdat->node_id; @@ -5085,8 +5071,6 @@ static void build_zonelists(pg_data_t *pgdat) nodes_clear(used_mask); memset(node_order, 0, sizeof(node_order)); - i = 0; - while ((node = find_next_best_node(local_node, &used_mask)) >= 0) { /* * We don't want to pressure a particular node. @@ -5097,19 +5081,12 @@ static void build_zonelists(pg_data_t *pgdat) node_distance(local_node, prev_node)) node_load[node] = load; + node_order[nr_nodes++] = node; prev_node = node; load--; - if (order == ZONELIST_ORDER_NODE) - build_zonelists_in_node_order(pgdat, node); - else - node_order[i++] = node; /* remember order */ - } - - if (order == ZONELIST_ORDER_ZONE) { - /* calculate node order -- i.e., DMA last! */ - build_zonelists_in_zone_order(pgdat, i); } + build_zonelists_in_node_order(pgdat, node_order, nr_nodes); build_thisnode_zonelists(pgdat); } @@ -5135,21 +5112,17 @@ static void setup_min_unmapped_ratio(void); static void setup_min_slab_ratio(void); #else /* CONFIG_NUMA */ -static void set_zonelist_order(void) -{ - current_zonelist_order = ZONELIST_ORDER_ZONE; -} - static void build_zonelists(pg_data_t *pgdat) { int node, local_node; - enum zone_type j; - struct zonelist *zonelist; + struct zoneref *zonerefs; + int nr_zones; local_node = pgdat->node_id; - zonelist = &pgdat->node_zonelists[ZONELIST_FALLBACK]; - j = build_zonelists_node(pgdat, zonelist, 0); + zonerefs = pgdat->node_zonelists[ZONELIST_FALLBACK]._zonerefs; + nr_zones = build_zonerefs_node(pgdat, zonerefs); + zonerefs += nr_zones; /* * Now we build the zonelist so that it contains the zones @@ -5162,16 +5135,18 @@ static void build_zonelists(pg_data_t *pgdat) for (node = local_node + 1; node < MAX_NUMNODES; node++) { if (!node_online(node)) continue; - j = build_zonelists_node(NODE_DATA(node), zonelist, j); + nr_zones = build_zonerefs_node(NODE_DATA(node), zonerefs); + zonerefs += nr_zones; } for (node = 0; node < local_node; node++) { if (!node_online(node)) continue; - j = build_zonelists_node(NODE_DATA(node), zonelist, j); + nr_zones = build_zonerefs_node(NODE_DATA(node), zonerefs); + zonerefs += nr_zones; } - zonelist->_zonerefs[j].zone = NULL; - zonelist->_zonerefs[j].zone_idx = 0; + zonerefs->zone = NULL; + zonerefs->zone_idx = 0; } #endif /* CONFIG_NUMA */ @@ -5194,50 +5169,32 @@ static void build_zonelists(pg_data_t *pgdat) static void setup_pageset(struct per_cpu_pageset *p, unsigned long batch); static DEFINE_PER_CPU(struct per_cpu_pageset, boot_pageset); static DEFINE_PER_CPU(struct per_cpu_nodestat, boot_nodestats); -static void setup_zone_pageset(struct zone *zone); - -/* - * Global mutex to protect against size modification of zonelists - * as well as to serialize pageset setup for the new populated zone. - */ -DEFINE_MUTEX(zonelists_mutex); -/* return values int ....just for stop_machine() */ -static int __build_all_zonelists(void *data) +static void __build_all_zonelists(void *data) { int nid; - int cpu; + int __maybe_unused cpu; pg_data_t *self = data; + static DEFINE_SPINLOCK(lock); + + spin_lock(&lock); #ifdef CONFIG_NUMA memset(node_load, 0, sizeof(node_load)); #endif + /* + * This node is hotadded and no memory is yet present. So just + * building zonelists is fine - no need to touch other nodes. + */ if (self && !node_online(self->node_id)) { build_zonelists(self); - } - - for_each_online_node(nid) { - pg_data_t *pgdat = NODE_DATA(nid); - - build_zonelists(pgdat); - } + } else { + for_each_online_node(nid) { + pg_data_t *pgdat = NODE_DATA(nid); - /* - * Initialize the boot_pagesets that are going to be used - * for bootstrapping processors. The real pagesets for - * each zone will be allocated later when the per cpu - * allocator is available. - * - * boot_pagesets are used also for bootstrapping offline - * cpus if the system is already booted because the pagesets - * are needed to initialize allocators on a specific cpu too. - * F.e. the percpu allocator needs the page allocator which - * needs the percpu allocator in order to allocate its pagesets - * (a chicken-egg dilemma). - */ - for_each_possible_cpu(cpu) { - setup_pageset(&per_cpu(boot_pageset, cpu), 0); + build_zonelists(pgdat); + } #ifdef CONFIG_HAVE_MEMORYLESS_NODES /* @@ -5248,45 +5205,53 @@ static int __build_all_zonelists(void *data) * secondary cpus' numa_mem as they come on-line. During * node/memory hotplug, we'll fixup all on-line cpus. */ - if (cpu_online(cpu)) + for_each_online_cpu(cpu) set_cpu_numa_mem(cpu, local_memory_node(cpu_to_node(cpu))); #endif } - return 0; + spin_unlock(&lock); } static noinline void __init build_all_zonelists_init(void) { + int cpu; + __build_all_zonelists(NULL); + + /* + * Initialize the boot_pagesets that are going to be used + * for bootstrapping processors. The real pagesets for + * each zone will be allocated later when the per cpu + * allocator is available. + * + * boot_pagesets are used also for bootstrapping offline + * cpus if the system is already booted because the pagesets + * are needed to initialize allocators on a specific cpu too. + * F.e. the percpu allocator needs the page allocator which + * needs the percpu allocator in order to allocate its pagesets + * (a chicken-egg dilemma). + */ + for_each_possible_cpu(cpu) + setup_pageset(&per_cpu(boot_pageset, cpu), 0); + mminit_verify_zonelist(); cpuset_init_current_mems_allowed(); } /* - * Called with zonelists_mutex held always * unless system_state == SYSTEM_BOOTING. * - * __ref due to (1) call of __meminit annotated setup_zone_pageset - * [we're only called with non-NULL zone through __meminit paths] and - * (2) call of __init annotated helper build_all_zonelists_init + * __ref due to call of __init annotated helper build_all_zonelists_init * [protected by SYSTEM_BOOTING]. */ -void __ref build_all_zonelists(pg_data_t *pgdat, struct zone *zone) +void __ref build_all_zonelists(pg_data_t *pgdat) { - set_zonelist_order(); - if (system_state == SYSTEM_BOOTING) { build_all_zonelists_init(); } else { -#ifdef CONFIG_MEMORY_HOTPLUG - if (zone) - setup_zone_pageset(zone); -#endif - /* we have to stop all cpus to guarantee there is no user - of zonelist */ - stop_machine_cpuslocked(__build_all_zonelists, pgdat, NULL); + __build_all_zonelists(pgdat); /* cpuset refresh routine should be here */ } vm_total_pages = nr_free_pagecache_pages(); @@ -5302,9 +5267,8 @@ void __ref build_all_zonelists(pg_data_t *pgdat, struct zone *zone) else page_group_by_mobility_disabled = 0; - pr_info("Built %i zonelists in %s order, mobility grouping %s. Total pages: %ld\n", + pr_info("Built %i zonelists, mobility grouping %s. Total pages: %ld\n", nr_online_nodes, - zonelist_order_name[current_zonelist_order], page_group_by_mobility_disabled ? "off" : "on", vm_total_pages); #ifdef CONFIG_NUMA @@ -5403,6 +5367,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, __init_single_page(page, pfn, zone, nid); set_pageblock_migratetype(page, MIGRATE_MOVABLE); + cond_resched(); } else { __init_single_pfn(pfn, zone, nid); } @@ -5558,7 +5523,7 @@ static void __meminit zone_pageset_init(struct zone *zone, int cpu) pageset_set_high_and_batch(zone, pcp); } -static void __meminit setup_zone_pageset(struct zone *zone) +void __meminit setup_zone_pageset(struct zone *zone) { int cpu; zone->pageset = alloc_percpu(struct per_cpu_pageset); @@ -7012,9 +6977,11 @@ static void __setup_per_zone_wmarks(void) */ void setup_per_zone_wmarks(void) { - mutex_lock(&zonelists_mutex); + static DEFINE_SPINLOCK(lock); + + spin_lock(&lock); __setup_per_zone_wmarks(); - mutex_unlock(&zonelists_mutex); + spin_unlock(&lock); } /* @@ -7666,7 +7633,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, /* Make sure the range is really isolated. */ if (test_pages_isolated(outer_start, end, false)) { - pr_info("%s: [%lx, %lx) PFNs busy\n", + pr_info_ratelimited("%s: [%lx, %lx) PFNs busy\n", __func__, outer_start, end); ret = -EBUSY; goto done; diff --git a/mm/page_ext.c b/mm/page_ext.c index 88ccc044b09a41504fb212afdb5ca8a45e842998..32f18911dedabfa7fc0cda117686f582cc44ebe9 100644 --- a/mm/page_ext.c +++ b/mm/page_ext.c @@ -222,10 +222,7 @@ static void *__meminit alloc_page_ext(size_t size, int nid) return addr; } - if (node_state(nid, N_HIGH_MEMORY)) - addr = vzalloc_node(size, nid); - else - addr = vzalloc(size); + addr = vzalloc_node(size, nid); return addr; } @@ -409,6 +406,7 @@ void __init page_ext_init(void) continue; if (init_section_page_ext(pfn, nid)) goto oom; + cond_resched(); } } hotplug_memory_notifier(page_ext_callback, 0); diff --git a/mm/page_idle.c b/mm/page_idle.c index 1b0f48c62316b3ebf1e09cc7b0a16f413db7e9ae..4bd03a8d809e9ab2d4044955525ef6c1d28d2f08 100644 --- a/mm/page_idle.c +++ b/mm/page_idle.c @@ -204,7 +204,7 @@ static struct bin_attribute *page_idle_bin_attrs[] = { NULL, }; -static struct attribute_group page_idle_attr_group = { +static const struct attribute_group page_idle_attr_group = { .bin_attrs = page_idle_bin_attrs, .name = "page_idle", }; diff --git a/mm/page_io.c b/mm/page_io.c index b6c4ac388209c945d744f2541326411314a1cceb..21502d341a67c2322054686d8f8adf2267a6ba34 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -22,21 +22,27 @@ #include #include #include +#include #include static struct bio *get_swap_bio(gfp_t gfp_flags, struct page *page, bio_end_io_t end_io) { + int i, nr = hpage_nr_pages(page); struct bio *bio; - bio = bio_alloc(gfp_flags, 1); + bio = bio_alloc(gfp_flags, nr); if (bio) { - bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev); + struct block_device *bdev; + + bio->bi_iter.bi_sector = map_swap_page(page, &bdev); + bio_set_dev(bio, bdev); bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9; bio->bi_end_io = end_io; - bio_add_page(bio, page, PAGE_SIZE, 0); - BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE); + for (i = 0; i < nr; i++) + bio_add_page(bio, page + i, PAGE_SIZE, 0); + VM_BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE * nr); } return bio; } @@ -57,8 +63,7 @@ void end_swap_bio_write(struct bio *bio) */ set_page_dirty(page); pr_alert("Write-error on swap-device (%u:%u:%llu)\n", - imajor(bio->bi_bdev->bd_inode), - iminor(bio->bi_bdev->bd_inode), + MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)), (unsigned long long)bio->bi_iter.bi_sector); ClearPageReclaim(page); } @@ -123,8 +128,7 @@ static void end_swap_bio_read(struct bio *bio) SetPageError(page); ClearPageUptodate(page); pr_alert("Read-error on swap-device (%u:%u:%llu)\n", - imajor(bio->bi_bdev->bd_inode), - iminor(bio->bi_bdev->bd_inode), + MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)), (unsigned long long)bio->bi_iter.bi_sector); goto out; } @@ -136,6 +140,7 @@ static void end_swap_bio_read(struct bio *bio) WRITE_ONCE(bio->bi_private, NULL); bio_put(bio); wake_up_process(waiter); + put_task_struct(waiter); } int generic_swapfile_activate(struct swap_info_struct *sis, @@ -260,6 +265,15 @@ static sector_t swap_page_sector(struct page *page) return (sector_t)__page_file_index(page) << (PAGE_SHIFT - 9); } +static inline void count_swpout_vm_event(struct page *page) +{ +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + if (unlikely(PageTransHuge(page))) + count_vm_event(THP_SWPOUT); +#endif + count_vm_events(PSWPOUT, hpage_nr_pages(page)); +} + int __swap_writepage(struct page *page, struct writeback_control *wbc, bio_end_io_t end_write_func) { @@ -311,7 +325,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc, ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc); if (!ret) { - count_vm_event(PSWPOUT); + count_swpout_vm_event(page); return 0; } @@ -324,7 +338,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc, goto out; } bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc); - count_vm_event(PSWPOUT); + count_swpout_vm_event(page); set_page_writeback(page); unlock_page(page); submit_bio(bio); @@ -338,7 +352,7 @@ int swap_readpage(struct page *page, bool do_poll) int ret = 0; struct swap_info_struct *sis = page_swap_info(page); blk_qc_t qc; - struct block_device *bdev; + struct gendisk *disk; VM_BUG_ON_PAGE(!PageSwapCache(page), page); VM_BUG_ON_PAGE(!PageLocked(page), page); @@ -377,7 +391,12 @@ int swap_readpage(struct page *page, bool do_poll) ret = -ENOMEM; goto out; } - bdev = bio->bi_bdev; + disk = bio->bi_disk; + /* + * Keep this task valid during swap readpage because the oom killer may + * attempt to access it in the page fault retry time check. + */ + get_task_struct(current); bio->bi_private = current; bio_set_op_attrs(bio, REQ_OP_READ, 0); count_vm_event(PSWPIN); @@ -388,7 +407,7 @@ int swap_readpage(struct page *page, bool do_poll) if (!READ_ONCE(bio->bi_private)) break; - if (!blk_mq_poll(bdev_get_queue(bdev), qc)) + if (!blk_mq_poll(disk->queue, qc)) break; } __set_current_state(TASK_RUNNING); diff --git a/mm/page_owner.c b/mm/page_owner.c index 0fd9dcf2c5dc158789831e0309d1fa66968b9205..57abca62d4dba3e8b4302bc19850980e40f7ebcb 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -30,6 +30,7 @@ DEFINE_STATIC_KEY_FALSE(page_owner_inited); static depot_stack_handle_t dummy_handle; static depot_stack_handle_t failure_handle; +static depot_stack_handle_t early_handle; static void init_early_allocated_pages(void); @@ -53,7 +54,7 @@ static bool need_page_owner(void) return true; } -static noinline void register_dummy_stack(void) +static __always_inline depot_stack_handle_t create_dummy_stack(void) { unsigned long entries[4]; struct stack_trace dummy; @@ -64,21 +65,22 @@ static noinline void register_dummy_stack(void) dummy.skip = 0; save_stack_trace(&dummy); - dummy_handle = depot_save_stack(&dummy, GFP_KERNEL); + return depot_save_stack(&dummy, GFP_KERNEL); } -static noinline void register_failure_stack(void) +static noinline void register_dummy_stack(void) { - unsigned long entries[4]; - struct stack_trace failure; + dummy_handle = create_dummy_stack(); +} - failure.nr_entries = 0; - failure.max_entries = ARRAY_SIZE(entries); - failure.entries = &entries[0]; - failure.skip = 0; +static noinline void register_failure_stack(void) +{ + failure_handle = create_dummy_stack(); +} - save_stack_trace(&failure); - failure_handle = depot_save_stack(&failure, GFP_KERNEL); +static noinline void register_early_stack(void) +{ + early_handle = create_dummy_stack(); } static void init_page_owner(void) @@ -88,6 +90,7 @@ static void init_page_owner(void) register_dummy_stack(); register_failure_stack(); + register_early_stack(); static_branch_enable(&page_owner_inited); init_early_allocated_pages(); } @@ -139,7 +142,7 @@ static noinline depot_stack_handle_t save_stack(gfp_t flags) .nr_entries = 0, .entries = entries, .max_entries = PAGE_OWNER_STACK_DEPTH, - .skip = 0 + .skip = 2 }; depot_stack_handle_t handle; @@ -165,17 +168,13 @@ static noinline depot_stack_handle_t save_stack(gfp_t flags) return handle; } -noinline void __set_page_owner(struct page *page, unsigned int order, - gfp_t gfp_mask) +static inline void __set_page_owner_handle(struct page_ext *page_ext, + depot_stack_handle_t handle, unsigned int order, gfp_t gfp_mask) { - struct page_ext *page_ext = lookup_page_ext(page); struct page_owner *page_owner; - if (unlikely(!page_ext)) - return; - page_owner = get_page_owner(page_ext); - page_owner->handle = save_stack(gfp_mask); + page_owner->handle = handle; page_owner->order = order; page_owner->gfp_mask = gfp_mask; page_owner->last_migrate_reason = -1; @@ -183,6 +182,19 @@ noinline void __set_page_owner(struct page *page, unsigned int order, __set_bit(PAGE_EXT_OWNER, &page_ext->flags); } +noinline void __set_page_owner(struct page *page, unsigned int order, + gfp_t gfp_mask) +{ + struct page_ext *page_ext = lookup_page_ext(page); + depot_stack_handle_t handle; + + if (unlikely(!page_ext)) + return; + + handle = save_stack(gfp_mask); + __set_page_owner_handle(page_ext, handle, order, gfp_mask); +} + void __set_page_owner_migrate_reason(struct page *page, int reason) { struct page_ext *page_ext = lookup_page_ext(page); @@ -550,11 +562,17 @@ static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone) continue; /* - * We are safe to check buddy flag and order, because - * this is init stage and only single thread runs. + * To avoid having to grab zone->lock, be a little + * careful when reading buddy page order. The only + * danger is that we skip too much and potentially miss + * some early allocated pages, which is better than + * heavy lock contention. */ if (PageBuddy(page)) { - pfn += (1UL << page_order(page)) - 1; + unsigned long order = page_order_unsafe(page); + + if (order > 0 && order < MAX_ORDER) + pfn += (1UL << order) - 1; continue; } @@ -565,14 +583,15 @@ static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone) if (unlikely(!page_ext)) continue; - /* Maybe overraping zone */ + /* Maybe overlapping zone */ if (test_bit(PAGE_EXT_OWNER, &page_ext->flags)) continue; /* Found early allocated page */ - set_page_owner(page, 0, 0); + __set_page_owner_handle(page_ext, early_handle, 0, 0); count++; } + cond_resched(); } pr_info("Node %d, zone %8s: page owner found early allocated %lu pages\n", @@ -583,15 +602,12 @@ static void init_zones_in_node(pg_data_t *pgdat) { struct zone *zone; struct zone *node_zones = pgdat->node_zones; - unsigned long flags; for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) { if (!populated_zone(zone)) continue; - spin_lock_irqsave(&zone->lock, flags); init_pages_in_zone(pgdat, zone); - spin_unlock_irqrestore(&zone->lock, flags); } } diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c index 8ec6ba230bb9dabba967489f0ba8f15ca61b8806..6a03946469a99eb535851194f519893a5e8a2d11 100644 --- a/mm/page_vma_mapped.c +++ b/mm/page_vma_mapped.c @@ -48,6 +48,7 @@ static bool check_pte(struct page_vma_mapped_walk *pvmw) if (!is_swap_pte(*pvmw->pte)) return false; entry = pte_to_swp_entry(*pvmw->pte); + if (!is_migration_entry(entry)) return false; if (migration_entry_to_page(entry) - pvmw->page >= @@ -60,6 +61,15 @@ static bool check_pte(struct page_vma_mapped_walk *pvmw) WARN_ON_ONCE(1); #endif } else { + if (is_swap_pte(*pvmw->pte)) { + swp_entry_t entry; + + entry = pte_to_swp_entry(*pvmw->pte); + if (is_device_private_entry(entry) && + device_private_entry_to_page(entry) == pvmw->page) + return true; + } + if (!pte_present(*pvmw->pte)) return false; @@ -138,16 +148,28 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw) if (!pud_present(*pud)) return false; pvmw->pmd = pmd_offset(pud, pvmw->address); - if (pmd_trans_huge(*pvmw->pmd)) { + if (pmd_trans_huge(*pvmw->pmd) || is_pmd_migration_entry(*pvmw->pmd)) { pvmw->ptl = pmd_lock(mm, pvmw->pmd); - if (!pmd_present(*pvmw->pmd)) - return not_found(pvmw); if (likely(pmd_trans_huge(*pvmw->pmd))) { if (pvmw->flags & PVMW_MIGRATION) return not_found(pvmw); if (pmd_page(*pvmw->pmd) != page) return not_found(pvmw); return true; + } else if (!pmd_present(*pvmw->pmd)) { + if (thp_migration_supported()) { + if (!(pvmw->flags & PVMW_MIGRATION)) + return not_found(pvmw); + if (is_migration_entry(pmd_to_swp_entry(*pvmw->pmd))) { + swp_entry_t entry = pmd_to_swp_entry(*pvmw->pmd); + + if (migration_entry_to_page(entry) != page) + return not_found(pvmw); + return true; + } + } else + WARN_ONCE(1, "Non present huge pmd without pmd migration enabled!"); + return not_found(pvmw); } else { /* THP pmd was split under us: handle on pte level */ spin_unlock(pvmw->ptl); diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h index cd2442e13d8f5add724bb6be9de1c3dc2ae8f715..7065faf74b46b20e5f9647cd09d228ad307d711f 100644 --- a/mm/percpu-internal.h +++ b/mm/percpu-internal.h @@ -4,6 +4,22 @@ #include #include +/* + * pcpu_block_md is the metadata block struct. + * Each chunk's bitmap is split into a number of full blocks. + * All units are in terms of bits. + */ +struct pcpu_block_md { + int contig_hint; /* contig hint for block */ + int contig_hint_start; /* block relative starting + position of the contig hint */ + int left_free; /* size of free space along + the left side of the block */ + int right_free; /* size of free space along + the right side of the block */ + int first_free; /* block position of first free */ +}; + struct pcpu_chunk { #ifdef CONFIG_PERCPU_STATS int nr_alloc; /* # of allocations */ @@ -11,24 +27,29 @@ struct pcpu_chunk { #endif struct list_head list; /* linked to pcpu_slot lists */ - int free_size; /* free bytes in the chunk */ - int contig_hint; /* max contiguous size hint */ + int free_bytes; /* free bytes in the chunk */ + int contig_bits; /* max contiguous size hint */ + int contig_bits_start; /* contig_bits starting + offset */ void *base_addr; /* base address of this chunk */ - int map_used; /* # of map entries used before the sentry */ - int map_alloc; /* # of map entries allocated */ - int *map; /* allocation map */ - struct list_head map_extend_list;/* on pcpu_map_extend_chunks */ + unsigned long *alloc_map; /* allocation map */ + unsigned long *bound_map; /* boundary map */ + struct pcpu_block_md *md_blocks; /* metadata blocks */ void *data; /* chunk data */ - int first_free; /* no free below this */ + int first_bit; /* no free below this */ bool immutable; /* no [de]population allowed */ - bool has_reserved; /* Indicates if chunk has reserved space - at the beginning. Reserved chunk will - contain reservation for static chunk. - Dynamic chunk will contain reservation - for static and reserved chunks. */ + int start_offset; /* the overlap with the previous + region to have a page aligned + base_addr */ + int end_offset; /* additional area required to + have the region end page + aligned */ + + int nr_pages; /* # of pages served by this chunk */ int nr_populated; /* # of populated pages */ + int nr_empty_pop_pages; /* # of empty populated pages */ unsigned long populated[]; /* populated bitmap */ }; @@ -36,10 +57,47 @@ extern spinlock_t pcpu_lock; extern struct list_head *pcpu_slot; extern int pcpu_nr_slots; +extern int pcpu_nr_empty_pop_pages; extern struct pcpu_chunk *pcpu_first_chunk; extern struct pcpu_chunk *pcpu_reserved_chunk; +/** + * pcpu_chunk_nr_blocks - converts nr_pages to # of md_blocks + * @chunk: chunk of interest + * + * This conversion is from the number of physical pages that the chunk + * serves to the number of bitmap blocks used. + */ +static inline int pcpu_chunk_nr_blocks(struct pcpu_chunk *chunk) +{ + return chunk->nr_pages * PAGE_SIZE / PCPU_BITMAP_BLOCK_SIZE; +} + +/** + * pcpu_nr_pages_to_map_bits - converts the pages to size of bitmap + * @pages: number of physical pages + * + * This conversion is from physical pages to the number of bits + * required in the bitmap. + */ +static inline int pcpu_nr_pages_to_map_bits(int pages) +{ + return pages * PAGE_SIZE / PCPU_MIN_ALLOC_SIZE; +} + +/** + * pcpu_chunk_map_bits - helper to convert nr_pages to size of bitmap + * @chunk: chunk of interest + * + * This conversion is from the number of physical pages that the chunk + * serves to the number of bits in the bitmap. + */ +static inline int pcpu_chunk_map_bits(struct pcpu_chunk *chunk) +{ + return pcpu_nr_pages_to_map_bits(chunk->nr_pages); +} + #ifdef CONFIG_PERCPU_STATS #include diff --git a/mm/percpu-km.c b/mm/percpu-km.c index eb58aa4c0997540fb3eb912ee6449d2daf7d3ab2..d2a76642c4ae89ecc5489dc430a7cddbce351b5e 100644 --- a/mm/percpu-km.c +++ b/mm/percpu-km.c @@ -69,7 +69,7 @@ static struct pcpu_chunk *pcpu_create_chunk(void) chunk->base_addr = page_address(pages) - pcpu_group_offsets[0]; spin_lock_irq(&pcpu_lock); - pcpu_chunk_populated(chunk, 0, nr_pages); + pcpu_chunk_populated(chunk, 0, nr_pages, false); spin_unlock_irq(&pcpu_lock); pcpu_stats_chunk_alloc(); diff --git a/mm/percpu-stats.c b/mm/percpu-stats.c index 03524a56eefff19c9b093da5343e9196023068bb..7a58460bfd27a303c7ab4d3c4f10abac02c15603 100644 --- a/mm/percpu-stats.c +++ b/mm/percpu-stats.c @@ -18,7 +18,7 @@ #include "percpu-internal.h" #define P(X, Y) \ - seq_printf(m, " %-24s: %8lld\n", X, (long long int)Y) + seq_printf(m, " %-20s: %12lld\n", X, (long long int)Y) struct percpu_stats pcpu_stats; struct pcpu_alloc_info pcpu_stats_ai; @@ -29,64 +29,85 @@ static int cmpint(const void *a, const void *b) } /* - * Iterates over all chunks to find the max # of map entries used. + * Iterates over all chunks to find the max nr_alloc entries. */ -static int find_max_map_used(void) +static int find_max_nr_alloc(void) { struct pcpu_chunk *chunk; - int slot, max_map_used; + int slot, max_nr_alloc; - max_map_used = 0; + max_nr_alloc = 0; for (slot = 0; slot < pcpu_nr_slots; slot++) list_for_each_entry(chunk, &pcpu_slot[slot], list) - max_map_used = max(max_map_used, chunk->map_used); + max_nr_alloc = max(max_nr_alloc, chunk->nr_alloc); - return max_map_used; + return max_nr_alloc; } /* * Prints out chunk state. Fragmentation is considered between * the beginning of the chunk to the last allocation. + * + * All statistics are in bytes unless stated otherwise. */ static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk, - void *buffer) + int *buffer) { - int i, s_index, last_alloc, alloc_sign, as_len; + int i, last_alloc, as_len, start, end; int *alloc_sizes, *p; /* statistics */ int sum_frag = 0, max_frag = 0; int cur_min_alloc = 0, cur_med_alloc = 0, cur_max_alloc = 0; alloc_sizes = buffer; - s_index = chunk->has_reserved ? 1 : 0; - - /* find last allocation */ - last_alloc = -1; - for (i = chunk->map_used - 1; i >= s_index; i--) { - if (chunk->map[i] & 1) { - last_alloc = i; - break; - } - } - /* if the chunk is not empty - ignoring reserve */ - if (last_alloc >= s_index) { - as_len = last_alloc + 1 - s_index; - - /* - * Iterate through chunk map computing size info. - * The first bit is overloaded to be a used flag. - * negative = free space, positive = allocated - */ - for (i = 0, p = chunk->map + s_index; i < as_len; i++, p++) { - alloc_sign = (*p & 1) ? 1 : -1; - alloc_sizes[i] = alloc_sign * - ((p[1] & ~1) - (p[0] & ~1)); + /* + * find_last_bit returns the start value if nothing found. + * Therefore, we must determine if it is a failure of find_last_bit + * and set the appropriate value. + */ + last_alloc = find_last_bit(chunk->alloc_map, + pcpu_chunk_map_bits(chunk) - + chunk->end_offset / PCPU_MIN_ALLOC_SIZE - 1); + last_alloc = test_bit(last_alloc, chunk->alloc_map) ? + last_alloc + 1 : 0; + + as_len = 0; + start = chunk->start_offset / PCPU_MIN_ALLOC_SIZE; + + /* + * If a bit is set in the allocation map, the bound_map identifies + * where the allocation ends. If the allocation is not set, the + * bound_map does not identify free areas as it is only kept accurate + * on allocation, not free. + * + * Positive values are allocations and negative values are free + * fragments. + */ + while (start < last_alloc) { + if (test_bit(start, chunk->alloc_map)) { + end = find_next_bit(chunk->bound_map, last_alloc, + start + 1); + alloc_sizes[as_len] = 1; + } else { + end = find_next_bit(chunk->alloc_map, last_alloc, + start + 1); + alloc_sizes[as_len] = -1; } - sort(alloc_sizes, as_len, sizeof(chunk->map[0]), cmpint, NULL); + alloc_sizes[as_len++] *= (end - start) * PCPU_MIN_ALLOC_SIZE; + + start = end; + } + + /* + * The negative values are free fragments and thus sorting gives the + * free fragments at the beginning in largest first order. + */ + if (as_len > 0) { + sort(alloc_sizes, as_len, sizeof(int), cmpint, NULL); - /* Iterate through the unallocated fragements. */ + /* iterate through the unallocated fragments */ for (i = 0, p = alloc_sizes; *p < 0 && i < as_len; i++, p++) { sum_frag -= *p; max_frag = max(max_frag, -1 * (*p)); @@ -99,8 +120,10 @@ static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk, P("nr_alloc", chunk->nr_alloc); P("max_alloc_size", chunk->max_alloc_size); - P("free_size", chunk->free_size); - P("contig_hint", chunk->contig_hint); + P("empty_pop_pages", chunk->nr_empty_pop_pages); + P("first_bit", chunk->first_bit); + P("free_bytes", chunk->free_bytes); + P("contig_bytes", chunk->contig_bits * PCPU_MIN_ALLOC_SIZE); P("sum_frag", sum_frag); P("max_frag", max_frag); P("cur_min_alloc", cur_min_alloc); @@ -112,29 +135,30 @@ static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk, static int percpu_stats_show(struct seq_file *m, void *v) { struct pcpu_chunk *chunk; - int slot, max_map_used; - void *buffer; + int slot, max_nr_alloc; + int *buffer; alloc_buffer: spin_lock_irq(&pcpu_lock); - max_map_used = find_max_map_used(); + max_nr_alloc = find_max_nr_alloc(); spin_unlock_irq(&pcpu_lock); - buffer = vmalloc(max_map_used * sizeof(pcpu_first_chunk->map[0])); + /* there can be at most this many free and allocated fragments */ + buffer = vmalloc((2 * max_nr_alloc + 1) * sizeof(int)); if (!buffer) return -ENOMEM; spin_lock_irq(&pcpu_lock); /* if the buffer allocated earlier is too small */ - if (max_map_used < find_max_map_used()) { + if (max_nr_alloc < find_max_nr_alloc()) { spin_unlock_irq(&pcpu_lock); vfree(buffer); goto alloc_buffer; } #define PL(X) \ - seq_printf(m, " %-24s: %8lld\n", #X, (long long int)pcpu_stats_ai.X) + seq_printf(m, " %-20s: %12lld\n", #X, (long long int)pcpu_stats_ai.X) seq_printf(m, "Percpu Memory Statistics\n" @@ -151,7 +175,7 @@ static int percpu_stats_show(struct seq_file *m, void *v) #undef PL #define PU(X) \ - seq_printf(m, " %-18s: %14llu\n", #X, (unsigned long long)pcpu_stats.X) + seq_printf(m, " %-20s: %12llu\n", #X, (unsigned long long)pcpu_stats.X) seq_printf(m, "Global Stats:\n" @@ -164,6 +188,7 @@ static int percpu_stats_show(struct seq_file *m, void *v) PU(nr_max_chunks); PU(min_alloc_size); PU(max_alloc_size); + P("empty_pop_pages", pcpu_nr_empty_pop_pages); seq_putc(m, '\n'); #undef PU diff --git a/mm/percpu.c b/mm/percpu.c index bd4130a69bbc9b6b631baf911e66aab31f08b6e0..aa121cef76de338441f3dbcf5e3e0d1de9f0aebf 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -4,44 +4,53 @@ * Copyright (C) 2009 SUSE Linux Products GmbH * Copyright (C) 2009 Tejun Heo * - * This file is released under the GPLv2. + * Copyright (C) 2017 Facebook Inc. + * Copyright (C) 2017 Dennis Zhou * - * This is percpu allocator which can handle both static and dynamic - * areas. Percpu areas are allocated in chunks. Each chunk is - * consisted of boot-time determined number of units and the first - * chunk is used for static percpu variables in the kernel image - * (special boot time alloc/init handling necessary as these areas - * need to be brought up before allocation services are running). - * Unit grows as necessary and all units grow or shrink in unison. - * When a chunk is filled up, another chunk is allocated. + * This file is released under the GPLv2 license. + * + * The percpu allocator handles both static and dynamic areas. Percpu + * areas are allocated in chunks which are divided into units. There is + * a 1-to-1 mapping for units to possible cpus. These units are grouped + * based on NUMA properties of the machine. * * c0 c1 c2 * ------------------- ------------------- ------------ * | u0 | u1 | u2 | u3 | | u0 | u1 | u2 | u3 | | u0 | u1 | u * ------------------- ...... ------------------- .... ------------ * - * Allocation is done in offset-size areas of single unit space. Ie, - * an area of 512 bytes at 6k in c1 occupies 512 bytes at 6k of c1:u0, - * c1:u1, c1:u2 and c1:u3. On UMA, units corresponds directly to - * cpus. On NUMA, the mapping can be non-linear and even sparse. - * Percpu access can be done by configuring percpu base registers - * according to cpu to unit mapping and pcpu_unit_size. - * - * There are usually many small percpu allocations many of them being - * as small as 4 bytes. The allocator organizes chunks into lists - * according to free size and tries to allocate from the fullest one. - * Each chunk keeps the maximum contiguous area size hint which is - * guaranteed to be equal to or larger than the maximum contiguous - * area in the chunk. This helps the allocator not to iterate the - * chunk maps unnecessarily. - * - * Allocation state in each chunk is kept using an array of integers - * on chunk->map. A positive value in the map represents a free - * region and negative allocated. Allocation inside a chunk is done - * by scanning this map sequentially and serving the first matching - * entry. This is mostly copied from the percpu_modalloc() allocator. - * Chunks can be determined from the address using the index field - * in the page struct. The index field contains a pointer to the chunk. + * Allocation is done by offsets into a unit's address space. Ie., an + * area of 512 bytes at 6k in c1 occupies 512 bytes at 6k in c1:u0, + * c1:u1, c1:u2, etc. On NUMA machines, the mapping may be non-linear + * and even sparse. Access is handled by configuring percpu base + * registers according to the cpu to unit mappings and offsetting the + * base address using pcpu_unit_size. + * + * There is special consideration for the first chunk which must handle + * the static percpu variables in the kernel image as allocation services + * are not online yet. In short, the first chunk is structured like so: + * + * + * + * The static data is copied from the original section managed by the + * linker. The reserved section, if non-zero, primarily manages static + * percpu variables from kernel modules. Finally, the dynamic section + * takes care of normal allocations. + * + * The allocator organizes chunks into lists according to free size and + * tries to allocate from the fullest chunk first. Each chunk is managed + * by a bitmap with metadata blocks. The allocation map is updated on + * every allocation and free to reflect the current state while the boundary + * map is only updated on allocation. Each metadata block contains + * information to help mitigate the need to iterate over large portions + * of the bitmap. The reverse mapping from page to chunk is stored in + * the page's index. Lastly, units are lazily backed and grow in unison. + * + * There is a unique conversion that goes on here between bytes and bits. + * Each bit represents a fragment of size PCPU_MIN_ALLOC_SIZE. The chunk + * tracks the number of pages it is responsible for in nr_pages. Helper + * functions are used to convert from between the bytes, bits, and blocks. + * All hints are managed in bits unless explicitly stated. * * To use this allocator, arch code should do the following: * @@ -58,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -81,10 +91,9 @@ #include "percpu-internal.h" -#define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ -#define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ -#define PCPU_ATOMIC_MAP_MARGIN_LOW 32 -#define PCPU_ATOMIC_MAP_MARGIN_HIGH 64 +/* the slots are sorted by free bytes left, 1-31 bytes share the same slot */ +#define PCPU_SLOT_BASE_SHIFT 5 + #define PCPU_EMPTY_POP_PAGES_LOW 2 #define PCPU_EMPTY_POP_PAGES_HIGH 4 @@ -140,13 +149,10 @@ struct pcpu_chunk *pcpu_first_chunk __ro_after_init; /* * Optional reserved chunk. This chunk reserves part of the first - * chunk and serves it for reserved allocations. The amount of - * reserved offset is in pcpu_reserved_chunk_limit. When reserved - * area doesn't exist, the following variables contain NULL and 0 - * respectively. + * chunk and serves it for reserved allocations. When the reserved + * region doesn't exist, the following variable is NULL. */ struct pcpu_chunk *pcpu_reserved_chunk __ro_after_init; -static int pcpu_reserved_chunk_limit __ro_after_init; DEFINE_SPINLOCK(pcpu_lock); /* all internal data structures */ static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext */ @@ -160,7 +166,7 @@ static LIST_HEAD(pcpu_map_extend_chunks); * The number of empty populated pages, protected by pcpu_lock. The * reserved chunk doesn't contribute to the count. */ -static int pcpu_nr_empty_pop_pages; +int pcpu_nr_empty_pop_pages; /* * Balance work is used to populate or destroy chunks asynchronously. We @@ -179,19 +185,26 @@ static void pcpu_schedule_balance_work(void) schedule_work(&pcpu_balance_work); } -static bool pcpu_addr_in_first_chunk(void *addr) +/** + * pcpu_addr_in_chunk - check if the address is served from this chunk + * @chunk: chunk of interest + * @addr: percpu address + * + * RETURNS: + * True if the address is served from this chunk. + */ +static bool pcpu_addr_in_chunk(struct pcpu_chunk *chunk, void *addr) { - void *first_start = pcpu_first_chunk->base_addr; + void *start_addr, *end_addr; - return addr >= first_start && addr < first_start + pcpu_unit_size; -} + if (!chunk) + return false; -static bool pcpu_addr_in_reserved_chunk(void *addr) -{ - void *first_start = pcpu_first_chunk->base_addr; + start_addr = chunk->base_addr + chunk->start_offset; + end_addr = chunk->base_addr + chunk->nr_pages * PAGE_SIZE - + chunk->end_offset; - return addr >= first_start && - addr < first_start + pcpu_reserved_chunk_limit; + return addr >= start_addr && addr < end_addr; } static int __pcpu_size_to_slot(int size) @@ -209,10 +222,10 @@ static int pcpu_size_to_slot(int size) static int pcpu_chunk_slot(const struct pcpu_chunk *chunk) { - if (chunk->free_size < sizeof(int) || chunk->contig_hint < sizeof(int)) + if (chunk->free_bytes < PCPU_MIN_ALLOC_SIZE || chunk->contig_bits == 0) return 0; - return pcpu_size_to_slot(chunk->free_size); + return pcpu_size_to_slot(chunk->free_bytes); } /* set the pointer to a chunk in a page struct */ @@ -232,42 +245,204 @@ static int __maybe_unused pcpu_page_idx(unsigned int cpu, int page_idx) return pcpu_unit_map[cpu] * pcpu_unit_pages + page_idx; } +static unsigned long pcpu_unit_page_offset(unsigned int cpu, int page_idx) +{ + return pcpu_unit_offsets[cpu] + (page_idx << PAGE_SHIFT); +} + static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk, unsigned int cpu, int page_idx) { - return (unsigned long)chunk->base_addr + pcpu_unit_offsets[cpu] + - (page_idx << PAGE_SHIFT); + return (unsigned long)chunk->base_addr + + pcpu_unit_page_offset(cpu, page_idx); } -static void __maybe_unused pcpu_next_unpop(struct pcpu_chunk *chunk, - int *rs, int *re, int end) +static void pcpu_next_unpop(unsigned long *bitmap, int *rs, int *re, int end) { - *rs = find_next_zero_bit(chunk->populated, end, *rs); - *re = find_next_bit(chunk->populated, end, *rs + 1); + *rs = find_next_zero_bit(bitmap, end, *rs); + *re = find_next_bit(bitmap, end, *rs + 1); } -static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk, - int *rs, int *re, int end) +static void pcpu_next_pop(unsigned long *bitmap, int *rs, int *re, int end) { - *rs = find_next_bit(chunk->populated, end, *rs); - *re = find_next_zero_bit(chunk->populated, end, *rs + 1); + *rs = find_next_bit(bitmap, end, *rs); + *re = find_next_zero_bit(bitmap, end, *rs + 1); } /* - * (Un)populated page region iterators. Iterate over (un)populated - * page regions between @start and @end in @chunk. @rs and @re should - * be integer variables and will be set to start and end page index of - * the current region. + * Bitmap region iterators. Iterates over the bitmap between + * [@start, @end) in @chunk. @rs and @re should be integer variables + * and will be set to start and end index of the current free region. + */ +#define pcpu_for_each_unpop_region(bitmap, rs, re, start, end) \ + for ((rs) = (start), pcpu_next_unpop((bitmap), &(rs), &(re), (end)); \ + (rs) < (re); \ + (rs) = (re) + 1, pcpu_next_unpop((bitmap), &(rs), &(re), (end))) + +#define pcpu_for_each_pop_region(bitmap, rs, re, start, end) \ + for ((rs) = (start), pcpu_next_pop((bitmap), &(rs), &(re), (end)); \ + (rs) < (re); \ + (rs) = (re) + 1, pcpu_next_pop((bitmap), &(rs), &(re), (end))) + +/* + * The following are helper functions to help access bitmaps and convert + * between bitmap offsets to address offsets. + */ +static unsigned long *pcpu_index_alloc_map(struct pcpu_chunk *chunk, int index) +{ + return chunk->alloc_map + + (index * PCPU_BITMAP_BLOCK_BITS / BITS_PER_LONG); +} + +static unsigned long pcpu_off_to_block_index(int off) +{ + return off / PCPU_BITMAP_BLOCK_BITS; +} + +static unsigned long pcpu_off_to_block_off(int off) +{ + return off & (PCPU_BITMAP_BLOCK_BITS - 1); +} + +static unsigned long pcpu_block_off_to_off(int index, int off) +{ + return index * PCPU_BITMAP_BLOCK_BITS + off; +} + +/** + * pcpu_next_md_free_region - finds the next hint free area + * @chunk: chunk of interest + * @bit_off: chunk offset + * @bits: size of free area + * + * Helper function for pcpu_for_each_md_free_region. It checks + * block->contig_hint and performs aggregation across blocks to find the + * next hint. It modifies bit_off and bits in-place to be consumed in the + * loop. + */ +static void pcpu_next_md_free_region(struct pcpu_chunk *chunk, int *bit_off, + int *bits) +{ + int i = pcpu_off_to_block_index(*bit_off); + int block_off = pcpu_off_to_block_off(*bit_off); + struct pcpu_block_md *block; + + *bits = 0; + for (block = chunk->md_blocks + i; i < pcpu_chunk_nr_blocks(chunk); + block++, i++) { + /* handles contig area across blocks */ + if (*bits) { + *bits += block->left_free; + if (block->left_free == PCPU_BITMAP_BLOCK_BITS) + continue; + return; + } + + /* + * This checks three things. First is there a contig_hint to + * check. Second, have we checked this hint before by + * comparing the block_off. Third, is this the same as the + * right contig hint. In the last case, it spills over into + * the next block and should be handled by the contig area + * across blocks code. + */ + *bits = block->contig_hint; + if (*bits && block->contig_hint_start >= block_off && + *bits + block->contig_hint_start < PCPU_BITMAP_BLOCK_BITS) { + *bit_off = pcpu_block_off_to_off(i, + block->contig_hint_start); + return; + } + /* reset to satisfy the second predicate above */ + block_off = 0; + + *bits = block->right_free; + *bit_off = (i + 1) * PCPU_BITMAP_BLOCK_BITS - block->right_free; + } +} + +/** + * pcpu_next_fit_region - finds fit areas for a given allocation request + * @chunk: chunk of interest + * @alloc_bits: size of allocation + * @align: alignment of area (max PAGE_SIZE) + * @bit_off: chunk offset + * @bits: size of free area + * + * Finds the next free region that is viable for use with a given size and + * alignment. This only returns if there is a valid area to be used for this + * allocation. block->first_free is returned if the allocation request fits + * within the block to see if the request can be fulfilled prior to the contig + * hint. */ -#define pcpu_for_each_unpop_region(chunk, rs, re, start, end) \ - for ((rs) = (start), pcpu_next_unpop((chunk), &(rs), &(re), (end)); \ - (rs) < (re); \ - (rs) = (re) + 1, pcpu_next_unpop((chunk), &(rs), &(re), (end))) +static void pcpu_next_fit_region(struct pcpu_chunk *chunk, int alloc_bits, + int align, int *bit_off, int *bits) +{ + int i = pcpu_off_to_block_index(*bit_off); + int block_off = pcpu_off_to_block_off(*bit_off); + struct pcpu_block_md *block; + + *bits = 0; + for (block = chunk->md_blocks + i; i < pcpu_chunk_nr_blocks(chunk); + block++, i++) { + /* handles contig area across blocks */ + if (*bits) { + *bits += block->left_free; + if (*bits >= alloc_bits) + return; + if (block->left_free == PCPU_BITMAP_BLOCK_BITS) + continue; + } + + /* check block->contig_hint */ + *bits = ALIGN(block->contig_hint_start, align) - + block->contig_hint_start; + /* + * This uses the block offset to determine if this has been + * checked in the prior iteration. + */ + if (block->contig_hint && + block->contig_hint_start >= block_off && + block->contig_hint >= *bits + alloc_bits) { + *bits += alloc_bits + block->contig_hint_start - + block->first_free; + *bit_off = pcpu_block_off_to_off(i, block->first_free); + return; + } + /* reset to satisfy the second predicate above */ + block_off = 0; + + *bit_off = ALIGN(PCPU_BITMAP_BLOCK_BITS - block->right_free, + align); + *bits = PCPU_BITMAP_BLOCK_BITS - *bit_off; + *bit_off = pcpu_block_off_to_off(i, *bit_off); + if (*bits >= alloc_bits) + return; + } + + /* no valid offsets were found - fail condition */ + *bit_off = pcpu_chunk_map_bits(chunk); +} -#define pcpu_for_each_pop_region(chunk, rs, re, start, end) \ - for ((rs) = (start), pcpu_next_pop((chunk), &(rs), &(re), (end)); \ - (rs) < (re); \ - (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end))) +/* + * Metadata free area iterators. These perform aggregation of free areas + * based on the metadata blocks and return the offset @bit_off and size in + * bits of the free area @bits. pcpu_for_each_fit_region only returns when + * a fit is found for the allocation request. + */ +#define pcpu_for_each_md_free_region(chunk, bit_off, bits) \ + for (pcpu_next_md_free_region((chunk), &(bit_off), &(bits)); \ + (bit_off) < pcpu_chunk_map_bits((chunk)); \ + (bit_off) += (bits) + 1, \ + pcpu_next_md_free_region((chunk), &(bit_off), &(bits))) + +#define pcpu_for_each_fit_region(chunk, alloc_bits, align, bit_off, bits) \ + for (pcpu_next_fit_region((chunk), (alloc_bits), (align), &(bit_off), \ + &(bits)); \ + (bit_off) < pcpu_chunk_map_bits((chunk)); \ + (bit_off) += (bits), \ + pcpu_next_fit_region((chunk), (alloc_bits), (align), &(bit_off), \ + &(bits))) /** * pcpu_mem_zalloc - allocate memory @@ -305,38 +480,6 @@ static void pcpu_mem_free(void *ptr) kvfree(ptr); } -/** - * pcpu_count_occupied_pages - count the number of pages an area occupies - * @chunk: chunk of interest - * @i: index of the area in question - * - * Count the number of pages chunk's @i'th area occupies. When the area's - * start and/or end address isn't aligned to page boundary, the straddled - * page is included in the count iff the rest of the page is free. - */ -static int pcpu_count_occupied_pages(struct pcpu_chunk *chunk, int i) -{ - int off = chunk->map[i] & ~1; - int end = chunk->map[i + 1] & ~1; - - if (!PAGE_ALIGNED(off) && i > 0) { - int prev = chunk->map[i - 1]; - - if (!(prev & 1) && prev <= round_down(off, PAGE_SIZE)) - off = round_down(off, PAGE_SIZE); - } - - if (!PAGE_ALIGNED(end) && i + 1 < chunk->map_used) { - int next = chunk->map[i + 1]; - int nend = chunk->map[i + 2] & ~1; - - if (!(next & 1) && nend >= round_up(end, PAGE_SIZE)) - end = round_up(end, PAGE_SIZE); - } - - return max_t(int, PFN_DOWN(end) - PFN_UP(off), 0); -} - /** * pcpu_chunk_relocate - put chunk in the appropriate chunk slot * @chunk: chunk of interest @@ -363,383 +506,706 @@ static void pcpu_chunk_relocate(struct pcpu_chunk *chunk, int oslot) } /** - * pcpu_need_to_extend - determine whether chunk area map needs to be extended + * pcpu_cnt_pop_pages- counts populated backing pages in range * @chunk: chunk of interest - * @is_atomic: the allocation context + * @bit_off: start offset + * @bits: size of area to check * - * Determine whether area map of @chunk needs to be extended. If - * @is_atomic, only the amount necessary for a new allocation is - * considered; however, async extension is scheduled if the left amount is - * low. If !@is_atomic, it aims for more empty space. Combined, this - * ensures that the map is likely to have enough available space to - * accomodate atomic allocations which can't extend maps directly. - * - * CONTEXT: - * pcpu_lock. + * Calculates the number of populated pages in the region + * [page_start, page_end). This keeps track of how many empty populated + * pages are available and decide if async work should be scheduled. * * RETURNS: - * New target map allocation length if extension is necessary, 0 - * otherwise. + * The nr of populated pages. */ -static int pcpu_need_to_extend(struct pcpu_chunk *chunk, bool is_atomic) +static inline int pcpu_cnt_pop_pages(struct pcpu_chunk *chunk, int bit_off, + int bits) { - int margin, new_alloc; - - lockdep_assert_held(&pcpu_lock); - - if (is_atomic) { - margin = 3; + int page_start = PFN_UP(bit_off * PCPU_MIN_ALLOC_SIZE); + int page_end = PFN_DOWN((bit_off + bits) * PCPU_MIN_ALLOC_SIZE); - if (chunk->map_alloc < - chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW) { - if (list_empty(&chunk->map_extend_list)) { - list_add_tail(&chunk->map_extend_list, - &pcpu_map_extend_chunks); - pcpu_schedule_balance_work(); - } - } - } else { - margin = PCPU_ATOMIC_MAP_MARGIN_HIGH; - } - - if (chunk->map_alloc >= chunk->map_used + margin) + if (page_start >= page_end) return 0; - new_alloc = PCPU_DFL_MAP_ALLOC; - while (new_alloc < chunk->map_used + margin) - new_alloc *= 2; - - return new_alloc; + /* + * bitmap_weight counts the number of bits set in a bitmap up to + * the specified number of bits. This is counting the populated + * pages up to page_end and then subtracting the populated pages + * up to page_start to count the populated pages in + * [page_start, page_end). + */ + return bitmap_weight(chunk->populated, page_end) - + bitmap_weight(chunk->populated, page_start); } /** - * pcpu_extend_area_map - extend area map of a chunk + * pcpu_chunk_update - updates the chunk metadata given a free area * @chunk: chunk of interest - * @new_alloc: new target allocation length of the area map + * @bit_off: chunk offset + * @bits: size of free area * - * Extend area map of @chunk to have @new_alloc entries. + * This updates the chunk's contig hint and starting offset given a free area. + * Choose the best starting offset if the contig hint is equal. + */ +static void pcpu_chunk_update(struct pcpu_chunk *chunk, int bit_off, int bits) +{ + if (bits > chunk->contig_bits) { + chunk->contig_bits_start = bit_off; + chunk->contig_bits = bits; + } else if (bits == chunk->contig_bits && chunk->contig_bits_start && + (!bit_off || + __ffs(bit_off) > __ffs(chunk->contig_bits_start))) { + /* use the start with the best alignment */ + chunk->contig_bits_start = bit_off; + } +} + +/** + * pcpu_chunk_refresh_hint - updates metadata about a chunk + * @chunk: chunk of interest * - * CONTEXT: - * Does GFP_KERNEL allocation. Grabs and releases pcpu_lock. + * Iterates over the metadata blocks to find the largest contig area. + * It also counts the populated pages and uses the delta to update the + * global count. * - * RETURNS: - * 0 on success, -errno on failure. + * Updates: + * chunk->contig_bits + * chunk->contig_bits_start + * nr_empty_pop_pages (chunk and global) */ -static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc) +static void pcpu_chunk_refresh_hint(struct pcpu_chunk *chunk) { - int *old = NULL, *new = NULL; - size_t old_size = 0, new_size = new_alloc * sizeof(new[0]); - unsigned long flags; + int bit_off, bits, nr_empty_pop_pages; - lockdep_assert_held(&pcpu_alloc_mutex); + /* clear metadata */ + chunk->contig_bits = 0; - new = pcpu_mem_zalloc(new_size); - if (!new) - return -ENOMEM; + bit_off = chunk->first_bit; + bits = nr_empty_pop_pages = 0; + pcpu_for_each_md_free_region(chunk, bit_off, bits) { + pcpu_chunk_update(chunk, bit_off, bits); - /* acquire pcpu_lock and switch to new area map */ - spin_lock_irqsave(&pcpu_lock, flags); + nr_empty_pop_pages += pcpu_cnt_pop_pages(chunk, bit_off, bits); + } - if (new_alloc <= chunk->map_alloc) - goto out_unlock; + /* + * Keep track of nr_empty_pop_pages. + * + * The chunk maintains the previous number of free pages it held, + * so the delta is used to update the global counter. The reserved + * chunk is not part of the free page count as they are populated + * at init and are special to serving reserved allocations. + */ + if (chunk != pcpu_reserved_chunk) + pcpu_nr_empty_pop_pages += + (nr_empty_pop_pages - chunk->nr_empty_pop_pages); - old_size = chunk->map_alloc * sizeof(chunk->map[0]); - old = chunk->map; + chunk->nr_empty_pop_pages = nr_empty_pop_pages; +} - memcpy(new, old, old_size); +/** + * pcpu_block_update - updates a block given a free area + * @block: block of interest + * @start: start offset in block + * @end: end offset in block + * + * Updates a block given a known free area. The region [start, end) is + * expected to be the entirety of the free area within a block. Chooses + * the best starting offset if the contig hints are equal. + */ +static void pcpu_block_update(struct pcpu_block_md *block, int start, int end) +{ + int contig = end - start; + + block->first_free = min(block->first_free, start); + if (start == 0) + block->left_free = contig; + + if (end == PCPU_BITMAP_BLOCK_BITS) + block->right_free = contig; + + if (contig > block->contig_hint) { + block->contig_hint_start = start; + block->contig_hint = contig; + } else if (block->contig_hint_start && contig == block->contig_hint && + (!start || __ffs(start) > __ffs(block->contig_hint_start))) { + /* use the start with the best alignment */ + block->contig_hint_start = start; + } +} - chunk->map_alloc = new_alloc; - chunk->map = new; - new = NULL; +/** + * pcpu_block_refresh_hint + * @chunk: chunk of interest + * @index: index of the metadata block + * + * Scans over the block beginning at first_free and updates the block + * metadata accordingly. + */ +static void pcpu_block_refresh_hint(struct pcpu_chunk *chunk, int index) +{ + struct pcpu_block_md *block = chunk->md_blocks + index; + unsigned long *alloc_map = pcpu_index_alloc_map(chunk, index); + int rs, re; /* region start, region end */ + + /* clear hints */ + block->contig_hint = 0; + block->left_free = block->right_free = 0; + + /* iterate over free areas and update the contig hints */ + pcpu_for_each_unpop_region(alloc_map, rs, re, block->first_free, + PCPU_BITMAP_BLOCK_BITS) { + pcpu_block_update(block, rs, re); + } +} -out_unlock: - spin_unlock_irqrestore(&pcpu_lock, flags); +/** + * pcpu_block_update_hint_alloc - update hint on allocation path + * @chunk: chunk of interest + * @bit_off: chunk offset + * @bits: size of request + * + * Updates metadata for the allocation path. The metadata only has to be + * refreshed by a full scan iff the chunk's contig hint is broken. Block level + * scans are required if the block's contig hint is broken. + */ +static void pcpu_block_update_hint_alloc(struct pcpu_chunk *chunk, int bit_off, + int bits) +{ + struct pcpu_block_md *s_block, *e_block, *block; + int s_index, e_index; /* block indexes of the freed allocation */ + int s_off, e_off; /* block offsets of the freed allocation */ /* - * pcpu_mem_free() might end up calling vfree() which uses - * IRQ-unsafe lock and thus can't be called under pcpu_lock. + * Calculate per block offsets. + * The calculation uses an inclusive range, but the resulting offsets + * are [start, end). e_index always points to the last block in the + * range. */ - pcpu_mem_free(old); - pcpu_mem_free(new); + s_index = pcpu_off_to_block_index(bit_off); + e_index = pcpu_off_to_block_index(bit_off + bits - 1); + s_off = pcpu_off_to_block_off(bit_off); + e_off = pcpu_off_to_block_off(bit_off + bits - 1) + 1; - return 0; + s_block = chunk->md_blocks + s_index; + e_block = chunk->md_blocks + e_index; + + /* + * Update s_block. + * block->first_free must be updated if the allocation takes its place. + * If the allocation breaks the contig_hint, a scan is required to + * restore this hint. + */ + if (s_off == s_block->first_free) + s_block->first_free = find_next_zero_bit( + pcpu_index_alloc_map(chunk, s_index), + PCPU_BITMAP_BLOCK_BITS, + s_off + bits); + + if (s_off >= s_block->contig_hint_start && + s_off < s_block->contig_hint_start + s_block->contig_hint) { + /* block contig hint is broken - scan to fix it */ + pcpu_block_refresh_hint(chunk, s_index); + } else { + /* update left and right contig manually */ + s_block->left_free = min(s_block->left_free, s_off); + if (s_index == e_index) + s_block->right_free = min_t(int, s_block->right_free, + PCPU_BITMAP_BLOCK_BITS - e_off); + else + s_block->right_free = 0; + } + + /* + * Update e_block. + */ + if (s_index != e_index) { + /* + * When the allocation is across blocks, the end is along + * the left part of the e_block. + */ + e_block->first_free = find_next_zero_bit( + pcpu_index_alloc_map(chunk, e_index), + PCPU_BITMAP_BLOCK_BITS, e_off); + + if (e_off == PCPU_BITMAP_BLOCK_BITS) { + /* reset the block */ + e_block++; + } else { + if (e_off > e_block->contig_hint_start) { + /* contig hint is broken - scan to fix it */ + pcpu_block_refresh_hint(chunk, e_index); + } else { + e_block->left_free = 0; + e_block->right_free = + min_t(int, e_block->right_free, + PCPU_BITMAP_BLOCK_BITS - e_off); + } + } + + /* update in-between md_blocks */ + for (block = s_block + 1; block < e_block; block++) { + block->contig_hint = 0; + block->left_free = 0; + block->right_free = 0; + } + } + + /* + * The only time a full chunk scan is required is if the chunk + * contig hint is broken. Otherwise, it means a smaller space + * was used and therefore the chunk contig hint is still correct. + */ + if (bit_off >= chunk->contig_bits_start && + bit_off < chunk->contig_bits_start + chunk->contig_bits) + pcpu_chunk_refresh_hint(chunk); } /** - * pcpu_fit_in_area - try to fit the requested allocation in a candidate area - * @chunk: chunk the candidate area belongs to - * @off: the offset to the start of the candidate area - * @this_size: the size of the candidate area - * @size: the size of the target allocation - * @align: the alignment of the target allocation - * @pop_only: only allocate from already populated region - * - * We're trying to allocate @size bytes aligned at @align. @chunk's area - * at @off sized @this_size is a candidate. This function determines - * whether the target allocation fits in the candidate area and returns the - * number of bytes to pad after @off. If the target area doesn't fit, -1 - * is returned. - * - * If @pop_only is %true, this function only considers the already - * populated part of the candidate area. + * pcpu_block_update_hint_free - updates the block hints on the free path + * @chunk: chunk of interest + * @bit_off: chunk offset + * @bits: size of request + * + * Updates metadata for the allocation path. This avoids a blind block + * refresh by making use of the block contig hints. If this fails, it scans + * forward and backward to determine the extent of the free area. This is + * capped at the boundary of blocks. + * + * A chunk update is triggered if a page becomes free, a block becomes free, + * or the free spans across blocks. This tradeoff is to minimize iterating + * over the block metadata to update chunk->contig_bits. chunk->contig_bits + * may be off by up to a page, but it will never be more than the available + * space. If the contig hint is contained in one block, it will be accurate. */ -static int pcpu_fit_in_area(struct pcpu_chunk *chunk, int off, int this_size, - int size, int align, bool pop_only) +static void pcpu_block_update_hint_free(struct pcpu_chunk *chunk, int bit_off, + int bits) { - int cand_off = off; + struct pcpu_block_md *s_block, *e_block, *block; + int s_index, e_index; /* block indexes of the freed allocation */ + int s_off, e_off; /* block offsets of the freed allocation */ + int start, end; /* start and end of the whole free area */ - while (true) { - int head = ALIGN(cand_off, align) - off; - int page_start, page_end, rs, re; - - if (this_size < head + size) - return -1; + /* + * Calculate per block offsets. + * The calculation uses an inclusive range, but the resulting offsets + * are [start, end). e_index always points to the last block in the + * range. + */ + s_index = pcpu_off_to_block_index(bit_off); + e_index = pcpu_off_to_block_index(bit_off + bits - 1); + s_off = pcpu_off_to_block_off(bit_off); + e_off = pcpu_off_to_block_off(bit_off + bits - 1) + 1; - if (!pop_only) - return head; + s_block = chunk->md_blocks + s_index; + e_block = chunk->md_blocks + e_index; + /* + * Check if the freed area aligns with the block->contig_hint. + * If it does, then the scan to find the beginning/end of the + * larger free area can be avoided. + * + * start and end refer to beginning and end of the free area + * within each their respective blocks. This is not necessarily + * the entire free area as it may span blocks past the beginning + * or end of the block. + */ + start = s_off; + if (s_off == s_block->contig_hint + s_block->contig_hint_start) { + start = s_block->contig_hint_start; + } else { /* - * If the first unpopulated page is beyond the end of the - * allocation, the whole allocation is populated; - * otherwise, retry from the end of the unpopulated area. + * Scan backwards to find the extent of the free area. + * find_last_bit returns the starting bit, so if the start bit + * is returned, that means there was no last bit and the + * remainder of the chunk is free. */ - page_start = PFN_DOWN(head + off); - page_end = PFN_UP(head + off + size); - - rs = page_start; - pcpu_next_unpop(chunk, &rs, &re, PFN_UP(off + this_size)); - if (rs >= page_end) - return head; - cand_off = re * PAGE_SIZE; + int l_bit = find_last_bit(pcpu_index_alloc_map(chunk, s_index), + start); + start = (start == l_bit) ? 0 : l_bit + 1; + } + + end = e_off; + if (e_off == e_block->contig_hint_start) + end = e_block->contig_hint_start + e_block->contig_hint; + else + end = find_next_bit(pcpu_index_alloc_map(chunk, e_index), + PCPU_BITMAP_BLOCK_BITS, end); + + /* update s_block */ + e_off = (s_index == e_index) ? end : PCPU_BITMAP_BLOCK_BITS; + pcpu_block_update(s_block, start, e_off); + + /* freeing in the same block */ + if (s_index != e_index) { + /* update e_block */ + pcpu_block_update(e_block, 0, end); + + /* reset md_blocks in the middle */ + for (block = s_block + 1; block < e_block; block++) { + block->first_free = 0; + block->contig_hint_start = 0; + block->contig_hint = PCPU_BITMAP_BLOCK_BITS; + block->left_free = PCPU_BITMAP_BLOCK_BITS; + block->right_free = PCPU_BITMAP_BLOCK_BITS; + } } + + /* + * Refresh chunk metadata when the free makes a page free, a block + * free, or spans across blocks. The contig hint may be off by up to + * a page, but if the hint is contained in a block, it will be accurate + * with the else condition below. + */ + if ((ALIGN_DOWN(end, min(PCPU_BITS_PER_PAGE, PCPU_BITMAP_BLOCK_BITS)) > + ALIGN(start, min(PCPU_BITS_PER_PAGE, PCPU_BITMAP_BLOCK_BITS))) || + s_index != e_index) + pcpu_chunk_refresh_hint(chunk); + else + pcpu_chunk_update(chunk, pcpu_block_off_to_off(s_index, start), + s_block->contig_hint); } /** - * pcpu_alloc_area - allocate area from a pcpu_chunk + * pcpu_is_populated - determines if the region is populated * @chunk: chunk of interest - * @size: wanted size in bytes - * @align: wanted align - * @pop_only: allocate only from the populated area - * @occ_pages_p: out param for the number of pages the area occupies - * - * Try to allocate @size bytes area aligned at @align from @chunk. - * Note that this function only allocates the offset. It doesn't - * populate or map the area. + * @bit_off: chunk offset + * @bits: size of area + * @next_off: return value for the next offset to start searching * - * @chunk->map must have at least two free slots. + * For atomic allocations, check if the backing pages are populated. * - * CONTEXT: - * pcpu_lock. + * RETURNS: + * Bool if the backing pages are populated. + * next_index is to skip over unpopulated blocks in pcpu_find_block_fit. + */ +static bool pcpu_is_populated(struct pcpu_chunk *chunk, int bit_off, int bits, + int *next_off) +{ + int page_start, page_end, rs, re; + + page_start = PFN_DOWN(bit_off * PCPU_MIN_ALLOC_SIZE); + page_end = PFN_UP((bit_off + bits) * PCPU_MIN_ALLOC_SIZE); + + rs = page_start; + pcpu_next_unpop(chunk->populated, &rs, &re, page_end); + if (rs >= page_end) + return true; + + *next_off = re * PAGE_SIZE / PCPU_MIN_ALLOC_SIZE; + return false; +} + +/** + * pcpu_find_block_fit - finds the block index to start searching + * @chunk: chunk of interest + * @alloc_bits: size of request in allocation units + * @align: alignment of area (max PAGE_SIZE bytes) + * @pop_only: use populated regions only + * + * Given a chunk and an allocation spec, find the offset to begin searching + * for a free region. This iterates over the bitmap metadata blocks to + * find an offset that will be guaranteed to fit the requirements. It is + * not quite first fit as if the allocation does not fit in the contig hint + * of a block or chunk, it is skipped. This errs on the side of caution + * to prevent excess iteration. Poor alignment can cause the allocator to + * skip over blocks and chunks that have valid free areas. * * RETURNS: - * Allocated offset in @chunk on success, -1 if no matching area is - * found. + * The offset in the bitmap to begin searching. + * -1 if no offset is found. */ -static int pcpu_alloc_area(struct pcpu_chunk *chunk, int size, int align, - bool pop_only, int *occ_pages_p) +static int pcpu_find_block_fit(struct pcpu_chunk *chunk, int alloc_bits, + size_t align, bool pop_only) { - int oslot = pcpu_chunk_slot(chunk); - int max_contig = 0; - int i, off; - bool seen_free = false; - int *p; - - for (i = chunk->first_free, p = chunk->map + i; i < chunk->map_used; i++, p++) { - int head, tail; - int this_size; - - off = *p; - if (off & 1) - continue; + int bit_off, bits, next_off; - this_size = (p[1] & ~1) - off; + /* + * Check to see if the allocation can fit in the chunk's contig hint. + * This is an optimization to prevent scanning by assuming if it + * cannot fit in the global hint, there is memory pressure and creating + * a new chunk would happen soon. + */ + bit_off = ALIGN(chunk->contig_bits_start, align) - + chunk->contig_bits_start; + if (bit_off + alloc_bits > chunk->contig_bits) + return -1; + + bit_off = chunk->first_bit; + bits = 0; + pcpu_for_each_fit_region(chunk, alloc_bits, align, bit_off, bits) { + if (!pop_only || pcpu_is_populated(chunk, bit_off, bits, + &next_off)) + break; - head = pcpu_fit_in_area(chunk, off, this_size, size, align, - pop_only); - if (head < 0) { - if (!seen_free) { - chunk->first_free = i; - seen_free = true; - } - max_contig = max(this_size, max_contig); - continue; - } + bit_off = next_off; + bits = 0; + } - /* - * If head is small or the previous block is free, - * merge'em. Note that 'small' is defined as smaller - * than sizeof(int), which is very small but isn't too - * uncommon for percpu allocations. - */ - if (head && (head < sizeof(int) || !(p[-1] & 1))) { - *p = off += head; - if (p[-1] & 1) - chunk->free_size -= head; - else - max_contig = max(*p - p[-1], max_contig); - this_size -= head; - head = 0; - } + if (bit_off == pcpu_chunk_map_bits(chunk)) + return -1; - /* if tail is small, just keep it around */ - tail = this_size - head - size; - if (tail < sizeof(int)) { - tail = 0; - size = this_size - head; - } + return bit_off; +} - /* split if warranted */ - if (head || tail) { - int nr_extra = !!head + !!tail; - - /* insert new subblocks */ - memmove(p + nr_extra + 1, p + 1, - sizeof(chunk->map[0]) * (chunk->map_used - i)); - chunk->map_used += nr_extra; - - if (head) { - if (!seen_free) { - chunk->first_free = i; - seen_free = true; - } - *++p = off += head; - ++i; - max_contig = max(head, max_contig); - } - if (tail) { - p[1] = off + size; - max_contig = max(tail, max_contig); - } - } +/** + * pcpu_alloc_area - allocates an area from a pcpu_chunk + * @chunk: chunk of interest + * @alloc_bits: size of request in allocation units + * @align: alignment of area (max PAGE_SIZE) + * @start: bit_off to start searching + * + * This function takes in a @start offset to begin searching to fit an + * allocation of @alloc_bits with alignment @align. It needs to scan + * the allocation map because if it fits within the block's contig hint, + * @start will be block->first_free. This is an attempt to fill the + * allocation prior to breaking the contig hint. The allocation and + * boundary maps are updated accordingly if it confirms a valid + * free area. + * + * RETURNS: + * Allocated addr offset in @chunk on success. + * -1 if no matching area is found. + */ +static int pcpu_alloc_area(struct pcpu_chunk *chunk, int alloc_bits, + size_t align, int start) +{ + size_t align_mask = (align) ? (align - 1) : 0; + int bit_off, end, oslot; - if (!seen_free) - chunk->first_free = i + 1; + lockdep_assert_held(&pcpu_lock); - /* update hint and mark allocated */ - if (i + 1 == chunk->map_used) - chunk->contig_hint = max_contig; /* fully scanned */ - else - chunk->contig_hint = max(chunk->contig_hint, - max_contig); + oslot = pcpu_chunk_slot(chunk); - chunk->free_size -= size; - *p |= 1; + /* + * Search to find a fit. + */ + end = start + alloc_bits + PCPU_BITMAP_BLOCK_BITS; + bit_off = bitmap_find_next_zero_area(chunk->alloc_map, end, start, + alloc_bits, align_mask); + if (bit_off >= end) + return -1; - *occ_pages_p = pcpu_count_occupied_pages(chunk, i); - pcpu_chunk_relocate(chunk, oslot); - return off; - } + /* update alloc map */ + bitmap_set(chunk->alloc_map, bit_off, alloc_bits); + + /* update boundary map */ + set_bit(bit_off, chunk->bound_map); + bitmap_clear(chunk->bound_map, bit_off + 1, alloc_bits - 1); + set_bit(bit_off + alloc_bits, chunk->bound_map); + + chunk->free_bytes -= alloc_bits * PCPU_MIN_ALLOC_SIZE; + + /* update first free bit */ + if (bit_off == chunk->first_bit) + chunk->first_bit = find_next_zero_bit( + chunk->alloc_map, + pcpu_chunk_map_bits(chunk), + bit_off + alloc_bits); + + pcpu_block_update_hint_alloc(chunk, bit_off, alloc_bits); - chunk->contig_hint = max_contig; /* fully scanned */ pcpu_chunk_relocate(chunk, oslot); - /* tell the upper layer that this chunk has no matching area */ - return -1; + return bit_off * PCPU_MIN_ALLOC_SIZE; } /** - * pcpu_free_area - free area to a pcpu_chunk + * pcpu_free_area - frees the corresponding offset * @chunk: chunk of interest - * @freeme: offset of area to free - * @occ_pages_p: out param for the number of pages the area occupies - * - * Free area starting from @freeme to @chunk. Note that this function - * only modifies the allocation map. It doesn't depopulate or unmap - * the area. + * @off: addr offset into chunk * - * CONTEXT: - * pcpu_lock. + * This function determines the size of an allocation to free using + * the boundary bitmap and clears the allocation map. */ -static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme, - int *occ_pages_p) +static void pcpu_free_area(struct pcpu_chunk *chunk, int off) { - int oslot = pcpu_chunk_slot(chunk); - int off = 0; - unsigned i, j; - int to_free = 0; - int *p; + int bit_off, bits, end, oslot; lockdep_assert_held(&pcpu_lock); pcpu_stats_area_dealloc(chunk); - freeme |= 1; /* we are searching for pair */ - - i = 0; - j = chunk->map_used; - while (i != j) { - unsigned k = (i + j) / 2; - off = chunk->map[k]; - if (off < freeme) - i = k + 1; - else if (off > freeme) - j = k; - else - i = j = k; + oslot = pcpu_chunk_slot(chunk); + + bit_off = off / PCPU_MIN_ALLOC_SIZE; + + /* find end index */ + end = find_next_bit(chunk->bound_map, pcpu_chunk_map_bits(chunk), + bit_off + 1); + bits = end - bit_off; + bitmap_clear(chunk->alloc_map, bit_off, bits); + + /* update metadata */ + chunk->free_bytes += bits * PCPU_MIN_ALLOC_SIZE; + + /* update first free bit */ + chunk->first_bit = min(chunk->first_bit, bit_off); + + pcpu_block_update_hint_free(chunk, bit_off, bits); + + pcpu_chunk_relocate(chunk, oslot); +} + +static void pcpu_init_md_blocks(struct pcpu_chunk *chunk) +{ + struct pcpu_block_md *md_block; + + for (md_block = chunk->md_blocks; + md_block != chunk->md_blocks + pcpu_chunk_nr_blocks(chunk); + md_block++) { + md_block->contig_hint = PCPU_BITMAP_BLOCK_BITS; + md_block->left_free = PCPU_BITMAP_BLOCK_BITS; + md_block->right_free = PCPU_BITMAP_BLOCK_BITS; } - BUG_ON(off != freeme); +} + +/** + * pcpu_alloc_first_chunk - creates chunks that serve the first chunk + * @tmp_addr: the start of the region served + * @map_size: size of the region served + * + * This is responsible for creating the chunks that serve the first chunk. The + * base_addr is page aligned down of @tmp_addr while the region end is page + * aligned up. Offsets are kept track of to determine the region served. All + * this is done to appease the bitmap allocator in avoiding partial blocks. + * + * RETURNS: + * Chunk serving the region at @tmp_addr of @map_size. + */ +static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr, + int map_size) +{ + struct pcpu_chunk *chunk; + unsigned long aligned_addr, lcm_align; + int start_offset, offset_bits, region_size, region_bits; - if (i < chunk->first_free) - chunk->first_free = i; + /* region calculations */ + aligned_addr = tmp_addr & PAGE_MASK; - p = chunk->map + i; - *p = off &= ~1; - chunk->free_size += (p[1] & ~1) - off; + start_offset = tmp_addr - aligned_addr; - *occ_pages_p = pcpu_count_occupied_pages(chunk, i); + /* + * Align the end of the region with the LCM of PAGE_SIZE and + * PCPU_BITMAP_BLOCK_SIZE. One of these constants is a multiple of + * the other. + */ + lcm_align = lcm(PAGE_SIZE, PCPU_BITMAP_BLOCK_SIZE); + region_size = ALIGN(start_offset + map_size, lcm_align); - /* merge with next? */ - if (!(p[1] & 1)) - to_free++; - /* merge with previous? */ - if (i > 0 && !(p[-1] & 1)) { - to_free++; - i--; - p--; + /* allocate chunk */ + chunk = memblock_virt_alloc(sizeof(struct pcpu_chunk) + + BITS_TO_LONGS(region_size >> PAGE_SHIFT), + 0); + + INIT_LIST_HEAD(&chunk->list); + + chunk->base_addr = (void *)aligned_addr; + chunk->start_offset = start_offset; + chunk->end_offset = region_size - chunk->start_offset - map_size; + + chunk->nr_pages = region_size >> PAGE_SHIFT; + region_bits = pcpu_chunk_map_bits(chunk); + + chunk->alloc_map = memblock_virt_alloc(BITS_TO_LONGS(region_bits) * + sizeof(chunk->alloc_map[0]), 0); + chunk->bound_map = memblock_virt_alloc(BITS_TO_LONGS(region_bits + 1) * + sizeof(chunk->bound_map[0]), 0); + chunk->md_blocks = memblock_virt_alloc(pcpu_chunk_nr_blocks(chunk) * + sizeof(chunk->md_blocks[0]), 0); + pcpu_init_md_blocks(chunk); + + /* manage populated page bitmap */ + chunk->immutable = true; + bitmap_fill(chunk->populated, chunk->nr_pages); + chunk->nr_populated = chunk->nr_pages; + chunk->nr_empty_pop_pages = + pcpu_cnt_pop_pages(chunk, start_offset / PCPU_MIN_ALLOC_SIZE, + map_size / PCPU_MIN_ALLOC_SIZE); + + chunk->contig_bits = map_size / PCPU_MIN_ALLOC_SIZE; + chunk->free_bytes = map_size; + + if (chunk->start_offset) { + /* hide the beginning of the bitmap */ + offset_bits = chunk->start_offset / PCPU_MIN_ALLOC_SIZE; + bitmap_set(chunk->alloc_map, 0, offset_bits); + set_bit(0, chunk->bound_map); + set_bit(offset_bits, chunk->bound_map); + + chunk->first_bit = offset_bits; + + pcpu_block_update_hint_alloc(chunk, 0, offset_bits); } - if (to_free) { - chunk->map_used -= to_free; - memmove(p + 1, p + 1 + to_free, - (chunk->map_used - i) * sizeof(chunk->map[0])); + + if (chunk->end_offset) { + /* hide the end of the bitmap */ + offset_bits = chunk->end_offset / PCPU_MIN_ALLOC_SIZE; + bitmap_set(chunk->alloc_map, + pcpu_chunk_map_bits(chunk) - offset_bits, + offset_bits); + set_bit((start_offset + map_size) / PCPU_MIN_ALLOC_SIZE, + chunk->bound_map); + set_bit(region_bits, chunk->bound_map); + + pcpu_block_update_hint_alloc(chunk, pcpu_chunk_map_bits(chunk) + - offset_bits, offset_bits); } - chunk->contig_hint = max(chunk->map[i + 1] - chunk->map[i] - 1, chunk->contig_hint); - pcpu_chunk_relocate(chunk, oslot); + return chunk; } static struct pcpu_chunk *pcpu_alloc_chunk(void) { struct pcpu_chunk *chunk; + int region_bits; chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size); if (!chunk) return NULL; - chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC * - sizeof(chunk->map[0])); - if (!chunk->map) { - pcpu_mem_free(chunk); - return NULL; - } + INIT_LIST_HEAD(&chunk->list); + chunk->nr_pages = pcpu_unit_pages; + region_bits = pcpu_chunk_map_bits(chunk); - chunk->map_alloc = PCPU_DFL_MAP_ALLOC; - chunk->map[0] = 0; - chunk->map[1] = pcpu_unit_size | 1; - chunk->map_used = 1; - chunk->has_reserved = false; + chunk->alloc_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits) * + sizeof(chunk->alloc_map[0])); + if (!chunk->alloc_map) + goto alloc_map_fail; - INIT_LIST_HEAD(&chunk->list); - INIT_LIST_HEAD(&chunk->map_extend_list); - chunk->free_size = pcpu_unit_size; - chunk->contig_hint = pcpu_unit_size; + chunk->bound_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits + 1) * + sizeof(chunk->bound_map[0])); + if (!chunk->bound_map) + goto bound_map_fail; + + chunk->md_blocks = pcpu_mem_zalloc(pcpu_chunk_nr_blocks(chunk) * + sizeof(chunk->md_blocks[0])); + if (!chunk->md_blocks) + goto md_blocks_fail; + + pcpu_init_md_blocks(chunk); + + /* init metadata */ + chunk->contig_bits = region_bits; + chunk->free_bytes = chunk->nr_pages * PAGE_SIZE; return chunk; + +md_blocks_fail: + pcpu_mem_free(chunk->bound_map); +bound_map_fail: + pcpu_mem_free(chunk->alloc_map); +alloc_map_fail: + pcpu_mem_free(chunk); + + return NULL; } static void pcpu_free_chunk(struct pcpu_chunk *chunk) { if (!chunk) return; - pcpu_mem_free(chunk->map); + pcpu_mem_free(chunk->bound_map); + pcpu_mem_free(chunk->alloc_map); pcpu_mem_free(chunk); } @@ -748,13 +1214,17 @@ static void pcpu_free_chunk(struct pcpu_chunk *chunk) * @chunk: pcpu_chunk which got populated * @page_start: the start page * @page_end: the end page + * @for_alloc: if this is to populate for allocation * * Pages in [@page_start,@page_end) have been populated to @chunk. Update * the bookkeeping information accordingly. Must be called after each * successful population. + * + * If this is @for_alloc, do not increment pcpu_nr_empty_pop_pages because it + * is to serve an allocation in that area. */ -static void pcpu_chunk_populated(struct pcpu_chunk *chunk, - int page_start, int page_end) +static void pcpu_chunk_populated(struct pcpu_chunk *chunk, int page_start, + int page_end, bool for_alloc) { int nr = page_end - page_start; @@ -762,7 +1232,11 @@ static void pcpu_chunk_populated(struct pcpu_chunk *chunk, bitmap_set(chunk->populated, page_start, nr); chunk->nr_populated += nr; - pcpu_nr_empty_pop_pages += nr; + + if (!for_alloc) { + chunk->nr_empty_pop_pages += nr; + pcpu_nr_empty_pop_pages += nr; + } } /** @@ -784,6 +1258,7 @@ static void pcpu_chunk_depopulated(struct pcpu_chunk *chunk, bitmap_clear(chunk->populated, page_start, nr); chunk->nr_populated -= nr; + chunk->nr_empty_pop_pages -= nr; pcpu_nr_empty_pop_pages -= nr; } @@ -819,18 +1294,21 @@ static int __init pcpu_verify_alloc_info(const struct pcpu_alloc_info *ai); * pcpu_chunk_addr_search - determine chunk containing specified address * @addr: address for which the chunk needs to be determined. * + * This is an internal function that handles all but static allocations. + * Static percpu address values should never be passed into the allocator. + * * RETURNS: * The address of the found chunk. */ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr) { - /* is it in the first chunk? */ - if (pcpu_addr_in_first_chunk(addr)) { - /* is it in the reserved area? */ - if (pcpu_addr_in_reserved_chunk(addr)) - return pcpu_reserved_chunk; + /* is it in the dynamic region (first chunk)? */ + if (pcpu_addr_in_chunk(pcpu_first_chunk, addr)) return pcpu_first_chunk; - } + + /* is it in the reserved region? */ + if (pcpu_addr_in_chunk(pcpu_reserved_chunk, addr)) + return pcpu_reserved_chunk; /* * The address is relative to unit0 which might be unused and @@ -863,19 +1341,23 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, struct pcpu_chunk *chunk; const char *err; bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; - int occ_pages = 0; - int slot, off, new_alloc, cpu, ret; + int slot, off, cpu, ret; unsigned long flags; void __percpu *ptr; + size_t bits, bit_align; /* - * We want the lowest bit of offset available for in-use/free - * indicator, so force >= 16bit alignment and make size even. + * There is now a minimum allocation size of PCPU_MIN_ALLOC_SIZE, + * therefore alignment must be a minimum of that many bytes. + * An allocation may have internal fragmentation from rounding up + * of up to PCPU_MIN_ALLOC_SIZE - 1 bytes. */ - if (unlikely(align < 2)) - align = 2; + if (unlikely(align < PCPU_MIN_ALLOC_SIZE)) + align = PCPU_MIN_ALLOC_SIZE; - size = ALIGN(size, 2); + size = ALIGN(size, PCPU_MIN_ALLOC_SIZE); + bits = size >> PCPU_MIN_ALLOC_SHIFT; + bit_align = align >> PCPU_MIN_ALLOC_SHIFT; if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE || !is_power_of_2(align))) { @@ -893,23 +1375,13 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, if (reserved && pcpu_reserved_chunk) { chunk = pcpu_reserved_chunk; - if (size > chunk->contig_hint) { + off = pcpu_find_block_fit(chunk, bits, bit_align, is_atomic); + if (off < 0) { err = "alloc from reserved chunk failed"; goto fail_unlock; } - while ((new_alloc = pcpu_need_to_extend(chunk, is_atomic))) { - spin_unlock_irqrestore(&pcpu_lock, flags); - if (is_atomic || - pcpu_extend_area_map(chunk, new_alloc) < 0) { - err = "failed to extend area map of reserved chunk"; - goto fail; - } - spin_lock_irqsave(&pcpu_lock, flags); - } - - off = pcpu_alloc_area(chunk, size, align, is_atomic, - &occ_pages); + off = pcpu_alloc_area(chunk, bits, bit_align, off); if (off >= 0) goto area_found; @@ -921,31 +1393,15 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, /* search through normal chunks */ for (slot = pcpu_size_to_slot(size); slot < pcpu_nr_slots; slot++) { list_for_each_entry(chunk, &pcpu_slot[slot], list) { - if (size > chunk->contig_hint) + off = pcpu_find_block_fit(chunk, bits, bit_align, + is_atomic); + if (off < 0) continue; - new_alloc = pcpu_need_to_extend(chunk, is_atomic); - if (new_alloc) { - if (is_atomic) - continue; - spin_unlock_irqrestore(&pcpu_lock, flags); - if (pcpu_extend_area_map(chunk, - new_alloc) < 0) { - err = "failed to extend area map"; - goto fail; - } - spin_lock_irqsave(&pcpu_lock, flags); - /* - * pcpu_lock has been dropped, need to - * restart cpu_slot list walking. - */ - goto restart; - } - - off = pcpu_alloc_area(chunk, size, align, is_atomic, - &occ_pages); + off = pcpu_alloc_area(chunk, bits, bit_align, off); if (off >= 0) goto area_found; + } } @@ -987,30 +1443,25 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, page_start = PFN_DOWN(off); page_end = PFN_UP(off + size); - pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) { + pcpu_for_each_unpop_region(chunk->populated, rs, re, + page_start, page_end) { WARN_ON(chunk->immutable); ret = pcpu_populate_chunk(chunk, rs, re); spin_lock_irqsave(&pcpu_lock, flags); if (ret) { - pcpu_free_area(chunk, off, &occ_pages); + pcpu_free_area(chunk, off); err = "failed to populate"; goto fail_unlock; } - pcpu_chunk_populated(chunk, rs, re); + pcpu_chunk_populated(chunk, rs, re, true); spin_unlock_irqrestore(&pcpu_lock, flags); } mutex_unlock(&pcpu_alloc_mutex); } - if (chunk != pcpu_reserved_chunk) { - spin_lock_irqsave(&pcpu_lock, flags); - pcpu_nr_empty_pop_pages -= occ_pages; - spin_unlock_irqrestore(&pcpu_lock, flags); - } - if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW) pcpu_schedule_balance_work(); @@ -1128,7 +1579,6 @@ static void pcpu_balance_workfn(struct work_struct *work) if (chunk == list_first_entry(free_head, struct pcpu_chunk, list)) continue; - list_del_init(&chunk->map_extend_list); list_move(&chunk->list, &to_free); } @@ -1137,7 +1587,8 @@ static void pcpu_balance_workfn(struct work_struct *work) list_for_each_entry_safe(chunk, next, &to_free, list) { int rs, re; - pcpu_for_each_pop_region(chunk, rs, re, 0, pcpu_unit_pages) { + pcpu_for_each_pop_region(chunk->populated, rs, re, 0, + chunk->nr_pages) { pcpu_depopulate_chunk(chunk, rs, re); spin_lock_irq(&pcpu_lock); pcpu_chunk_depopulated(chunk, rs, re); @@ -1146,25 +1597,6 @@ static void pcpu_balance_workfn(struct work_struct *work) pcpu_destroy_chunk(chunk); } - /* service chunks which requested async area map extension */ - do { - int new_alloc = 0; - - spin_lock_irq(&pcpu_lock); - - chunk = list_first_entry_or_null(&pcpu_map_extend_chunks, - struct pcpu_chunk, map_extend_list); - if (chunk) { - list_del_init(&chunk->map_extend_list); - new_alloc = pcpu_need_to_extend(chunk, false); - } - - spin_unlock_irq(&pcpu_lock); - - if (new_alloc) - pcpu_extend_area_map(chunk, new_alloc); - } while (chunk); - /* * Ensure there are certain number of free populated pages for * atomic allocs. Fill up from the most packed so that atomic @@ -1194,7 +1626,7 @@ static void pcpu_balance_workfn(struct work_struct *work) spin_lock_irq(&pcpu_lock); list_for_each_entry(chunk, &pcpu_slot[slot], list) { - nr_unpop = pcpu_unit_pages - chunk->nr_populated; + nr_unpop = chunk->nr_pages - chunk->nr_populated; if (nr_unpop) break; } @@ -1204,14 +1636,15 @@ static void pcpu_balance_workfn(struct work_struct *work) continue; /* @chunk can't go away while pcpu_alloc_mutex is held */ - pcpu_for_each_unpop_region(chunk, rs, re, 0, pcpu_unit_pages) { + pcpu_for_each_unpop_region(chunk->populated, rs, re, 0, + chunk->nr_pages) { int nr = min(re - rs, nr_to_pop); ret = pcpu_populate_chunk(chunk, rs, rs + nr); if (!ret) { nr_to_pop -= nr; spin_lock_irq(&pcpu_lock); - pcpu_chunk_populated(chunk, rs, rs + nr); + pcpu_chunk_populated(chunk, rs, rs + nr, false); spin_unlock_irq(&pcpu_lock); } else { nr_to_pop = 0; @@ -1250,7 +1683,7 @@ void free_percpu(void __percpu *ptr) void *addr; struct pcpu_chunk *chunk; unsigned long flags; - int off, occ_pages; + int off; if (!ptr) return; @@ -1264,13 +1697,10 @@ void free_percpu(void __percpu *ptr) chunk = pcpu_chunk_addr_search(addr); off = addr - chunk->base_addr; - pcpu_free_area(chunk, off, &occ_pages); - - if (chunk != pcpu_reserved_chunk) - pcpu_nr_empty_pop_pages += occ_pages; + pcpu_free_area(chunk, off); /* if there are more than one fully free chunks, wake up grim reaper */ - if (chunk->free_size == pcpu_unit_size) { + if (chunk->free_bytes == pcpu_unit_size) { struct pcpu_chunk *pos; list_for_each_entry(pos, &pcpu_slot[pcpu_nr_slots - 1], list) @@ -1361,10 +1791,16 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr) * The following test on unit_low/high isn't strictly * necessary but will speed up lookups of addresses which * aren't in the first chunk. + * + * The address check is against full chunk sizes. pcpu_base_addr + * points to the beginning of the first chunk including the + * static region. Assumes good intent as the first chunk may + * not be full (ie. < pcpu_unit_pages in size). */ - first_low = pcpu_chunk_addr(pcpu_first_chunk, pcpu_low_unit_cpu, 0); - first_high = pcpu_chunk_addr(pcpu_first_chunk, pcpu_high_unit_cpu, - pcpu_unit_pages); + first_low = (unsigned long)pcpu_base_addr + + pcpu_unit_page_offset(pcpu_low_unit_cpu, 0); + first_high = (unsigned long)pcpu_base_addr + + pcpu_unit_page_offset(pcpu_high_unit_cpu, pcpu_unit_pages); if ((unsigned long)addr >= first_low && (unsigned long)addr < first_high) { for_each_possible_cpu(cpu) { @@ -1546,12 +1982,13 @@ static void pcpu_dump_alloc_info(const char *lvl, * The caller should have mapped the first chunk at @base_addr and * copied static data to each unit. * - * If the first chunk ends up with both reserved and dynamic areas, it - * is served by two chunks - one to serve the core static and reserved - * areas and the other for the dynamic area. They share the same vm - * and page map but uses different area allocation map to stay away - * from each other. The latter chunk is circulated in the chunk slots - * and available for dynamic allocation like any other chunks. + * The first chunk will always contain a static and a dynamic region. + * However, the static region is not managed by any chunk. If the first + * chunk also contains a reserved region, it is served by two chunks - + * one for the reserved region and one for the dynamic region. They + * share the same vm, but use offset regions in the area allocation map. + * The chunk serving the dynamic region is circulated in the chunk slots + * and available for dynamic allocation like any other chunk. * * RETURNS: * 0 on success, -errno on failure. @@ -1559,17 +1996,17 @@ static void pcpu_dump_alloc_info(const char *lvl, int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, void *base_addr) { - static int smap[PERCPU_DYNAMIC_EARLY_SLOTS] __initdata; - static int dmap[PERCPU_DYNAMIC_EARLY_SLOTS] __initdata; - size_t dyn_size = ai->dyn_size; - size_t size_sum = ai->static_size + ai->reserved_size + dyn_size; - struct pcpu_chunk *schunk, *dchunk = NULL; + size_t size_sum = ai->static_size + ai->reserved_size + ai->dyn_size; + size_t static_size, dyn_size; + struct pcpu_chunk *chunk; unsigned long *group_offsets; size_t *group_sizes; unsigned long *unit_off; unsigned int cpu; int *unit_map; int group, unit, i; + int map_size; + unsigned long tmp_addr; #define PCPU_SETUP_BUG_ON(cond) do { \ if (unlikely(cond)) { \ @@ -1592,7 +2029,12 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, PCPU_SETUP_BUG_ON(ai->unit_size < size_sum); PCPU_SETUP_BUG_ON(offset_in_page(ai->unit_size)); PCPU_SETUP_BUG_ON(ai->unit_size < PCPU_MIN_UNIT_SIZE); + PCPU_SETUP_BUG_ON(!IS_ALIGNED(ai->unit_size, PCPU_BITMAP_BLOCK_SIZE)); PCPU_SETUP_BUG_ON(ai->dyn_size < PERCPU_DYNAMIC_EARLY_SIZE); + PCPU_SETUP_BUG_ON(!ai->dyn_size); + PCPU_SETUP_BUG_ON(!IS_ALIGNED(ai->reserved_size, PCPU_MIN_ALLOC_SIZE)); + PCPU_SETUP_BUG_ON(!(IS_ALIGNED(PCPU_BITMAP_BLOCK_SIZE, PAGE_SIZE) || + IS_ALIGNED(PAGE_SIZE, PCPU_BITMAP_BLOCK_SIZE))); PCPU_SETUP_BUG_ON(pcpu_verify_alloc_info(ai) < 0); /* process group information and build config tables accordingly */ @@ -1671,64 +2113,41 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, INIT_LIST_HEAD(&pcpu_slot[i]); /* - * Initialize static chunk. If reserved_size is zero, the - * static chunk covers static area + dynamic allocation area - * in the first chunk. If reserved_size is not zero, it - * covers static area + reserved area (mostly used for module - * static percpu allocation). + * The end of the static region needs to be aligned with the + * minimum allocation size as this offsets the reserved and + * dynamic region. The first chunk ends page aligned by + * expanding the dynamic region, therefore the dynamic region + * can be shrunk to compensate while still staying above the + * configured sizes. */ - schunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); - INIT_LIST_HEAD(&schunk->list); - INIT_LIST_HEAD(&schunk->map_extend_list); - schunk->base_addr = base_addr; - schunk->map = smap; - schunk->map_alloc = ARRAY_SIZE(smap); - schunk->immutable = true; - bitmap_fill(schunk->populated, pcpu_unit_pages); - schunk->nr_populated = pcpu_unit_pages; + static_size = ALIGN(ai->static_size, PCPU_MIN_ALLOC_SIZE); + dyn_size = ai->dyn_size - (static_size - ai->static_size); - if (ai->reserved_size) { - schunk->free_size = ai->reserved_size; - pcpu_reserved_chunk = schunk; - pcpu_reserved_chunk_limit = ai->static_size + ai->reserved_size; - } else { - schunk->free_size = dyn_size; - dyn_size = 0; /* dynamic area covered */ - } - schunk->contig_hint = schunk->free_size; - - schunk->map[0] = 1; - schunk->map[1] = ai->static_size; - schunk->map_used = 1; - if (schunk->free_size) - schunk->map[++schunk->map_used] = ai->static_size + schunk->free_size; - schunk->map[schunk->map_used] |= 1; - schunk->has_reserved = true; + /* + * Initialize first chunk. + * If the reserved_size is non-zero, this initializes the reserved + * chunk. If the reserved_size is zero, the reserved chunk is NULL + * and the dynamic region is initialized here. The first chunk, + * pcpu_first_chunk, will always point to the chunk that serves + * the dynamic region. + */ + tmp_addr = (unsigned long)base_addr + static_size; + map_size = ai->reserved_size ?: dyn_size; + chunk = pcpu_alloc_first_chunk(tmp_addr, map_size); /* init dynamic chunk if necessary */ - if (dyn_size) { - dchunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); - INIT_LIST_HEAD(&dchunk->list); - INIT_LIST_HEAD(&dchunk->map_extend_list); - dchunk->base_addr = base_addr; - dchunk->map = dmap; - dchunk->map_alloc = ARRAY_SIZE(dmap); - dchunk->immutable = true; - bitmap_fill(dchunk->populated, pcpu_unit_pages); - dchunk->nr_populated = pcpu_unit_pages; - - dchunk->contig_hint = dchunk->free_size = dyn_size; - dchunk->map[0] = 1; - dchunk->map[1] = pcpu_reserved_chunk_limit; - dchunk->map[2] = (pcpu_reserved_chunk_limit + dchunk->free_size) | 1; - dchunk->map_used = 2; - dchunk->has_reserved = true; + if (ai->reserved_size) { + pcpu_reserved_chunk = chunk; + + tmp_addr = (unsigned long)base_addr + static_size + + ai->reserved_size; + map_size = dyn_size; + chunk = pcpu_alloc_first_chunk(tmp_addr, map_size); } /* link the first chunk in */ - pcpu_first_chunk = dchunk ?: schunk; - pcpu_nr_empty_pop_pages += - pcpu_count_occupied_pages(pcpu_first_chunk, 1); + pcpu_first_chunk = chunk; + pcpu_nr_empty_pop_pages = pcpu_first_chunk->nr_empty_pop_pages; pcpu_chunk_relocate(pcpu_first_chunk, -1); pcpu_stats_chunk_alloc(); @@ -1842,6 +2261,7 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( */ min_unit_size = max_t(size_t, size_sum, PCPU_MIN_UNIT_SIZE); + /* determine the maximum # of units that can fit in an allocation */ alloc_size = roundup(min_unit_size, atom_size); upa = alloc_size / min_unit_size; while (alloc_size % upa || (offset_in_page(alloc_size / upa))) @@ -1868,9 +2288,9 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( } /* - * Expand unit size until address space usage goes over 75% - * and then as much as possible without using more address - * space. + * Wasted space is caused by a ratio imbalance of upa to group_cnt. + * Expand the unit_size until we use >= 75% of the units allocated. + * Related to atom_size, which could be much larger than the unit_size. */ last_allocs = INT_MAX; for (upa = max_upa; upa; upa--) { @@ -2298,36 +2718,6 @@ void __init setup_per_cpu_areas(void) #endif /* CONFIG_SMP */ -/* - * First and reserved chunks are initialized with temporary allocation - * map in initdata so that they can be used before slab is online. - * This function is called after slab is brought up and replaces those - * with properly allocated maps. - */ -void __init percpu_init_late(void) -{ - struct pcpu_chunk *target_chunks[] = - { pcpu_first_chunk, pcpu_reserved_chunk, NULL }; - struct pcpu_chunk *chunk; - unsigned long flags; - int i; - - for (i = 0; (chunk = target_chunks[i]); i++) { - int *map; - const size_t size = PERCPU_DYNAMIC_EARLY_SLOTS * sizeof(map[0]); - - BUILD_BUG_ON(size > PAGE_SIZE); - - map = pcpu_mem_zalloc(size); - BUG_ON(!map); - - spin_lock_irqsave(&pcpu_lock, flags); - memcpy(map, chunk->map, size); - chunk->map = map; - spin_unlock_irqrestore(&pcpu_lock, flags); - } -} - /* * Percpu allocator is initialized early during boot when neither slab or * workqueue is available. Plug async management until everything is up diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c index c99d9512a45b8a1599f0d679ec92d9e4511b3d68..1175f6a24fdb09d49af7ab93061b56b527d554a1 100644 --- a/mm/pgtable-generic.c +++ b/mm/pgtable-generic.c @@ -124,7 +124,8 @@ pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address, { pmd_t pmd; VM_BUG_ON(address & ~HPAGE_PMD_MASK); - VM_BUG_ON(!pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp)); + VM_BUG_ON((pmd_present(*pmdp) && !pmd_trans_huge(*pmdp) && + !pmd_devmap(*pmdp)) || !pmd_present(*pmdp)); pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp); flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE); return pmd; diff --git a/mm/rmap.c b/mm/rmap.c index ced14f1af6dc29ac2337eac9806eb6415238536b..b874c4761e8422829610d9a1173c56139db5823b 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -63,6 +63,7 @@ #include #include #include +#include #include @@ -390,7 +391,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma) * Leave empty anon_vmas on the list - we'll need * to free them outside the lock. */ - if (RB_EMPTY_ROOT(&anon_vma->rb_root)) { + if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) { anon_vma->parent->degree--; continue; } @@ -424,7 +425,7 @@ static void anon_vma_ctor(void *data) init_rwsem(&anon_vma->rwsem); atomic_set(&anon_vma->refcount, 0); - anon_vma->rb_root = RB_ROOT; + anon_vma->rb_root = RB_ROOT_CACHED; } void __init anon_vma_init(void) @@ -604,6 +605,13 @@ static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable) arch_tlbbatch_add_mm(&tlb_ubc->arch, mm); tlb_ubc->flush_required = true; + /* + * Ensure compiler does not re-order the setting of tlb_flush_batched + * before the PTE is cleared. + */ + barrier(); + mm->tlb_flush_batched = true; + /* * If the PTE was dirty then it's best to assume it's writable. The * caller must use try_to_unmap_flush_dirty() or try_to_unmap_flush() @@ -631,6 +639,35 @@ static bool should_defer_flush(struct mm_struct *mm, enum ttu_flags flags) return should_defer; } + +/* + * Reclaim unmaps pages under the PTL but do not flush the TLB prior to + * releasing the PTL if TLB flushes are batched. It's possible for a parallel + * operation such as mprotect or munmap to race between reclaim unmapping + * the page and flushing the page. If this race occurs, it potentially allows + * access to data via a stale TLB entry. Tracking all mm's that have TLB + * batching in flight would be expensive during reclaim so instead track + * whether TLB batching occurred in the past and if so then do a flush here + * if required. This will cost one additional flush per reclaim cycle paid + * by the first operation at risk such as mprotect and mumap. + * + * This must be called under the PTL so that an access to tlb_flush_batched + * that is potentially a "reclaim vs mprotect/munmap/etc" race will synchronise + * via the PTL. + */ +void flush_tlb_batched_pending(struct mm_struct *mm) +{ + if (mm->tlb_flush_batched) { + flush_tlb_mm(mm); + + /* + * Do not allow the compiler to re-order the clearing of + * tlb_flush_batched before the tlb is flushed. + */ + barrier(); + mm->tlb_flush_batched = false; + } +} #else static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable) { @@ -851,11 +888,21 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma, .address = address, .flags = PVMW_SYNC, }; + unsigned long start = address, end; int *cleaned = arg; + /* + * We have to assume the worse case ie pmd for invalidation. Note that + * the page can not be free from this function. + */ + end = min(vma->vm_end, start + (PAGE_SIZE << compound_order(page))); + mmu_notifier_invalidate_range_start(vma->vm_mm, start, end); + while (page_vma_mapped_walk(&pvmw)) { + unsigned long cstart, cend; int ret = 0; - address = pvmw.address; + + cstart = address = pvmw.address; if (pvmw.pte) { pte_t entry; pte_t *pte = pvmw.pte; @@ -868,6 +915,7 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma, entry = pte_wrprotect(entry); entry = pte_mkclean(entry); set_pte_at(vma->vm_mm, address, pte, entry); + cend = cstart + PAGE_SIZE; ret = 1; } else { #ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE @@ -882,6 +930,8 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma, entry = pmd_wrprotect(entry); entry = pmd_mkclean(entry); set_pmd_at(vma->vm_mm, address, pmd, entry); + cstart &= PMD_MASK; + cend = cstart + PMD_SIZE; ret = 1; #else /* unexpected pmd-mapped page? */ @@ -890,11 +940,13 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma, } if (ret) { - mmu_notifier_invalidate_page(vma->vm_mm, address); + mmu_notifier_invalidate_range(vma->vm_mm, cstart, cend); (*cleaned)++; } } + mmu_notifier_invalidate_range_end(vma->vm_mm, start, end); + return true; } @@ -1288,18 +1340,44 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, pte_t pteval; struct page *subpage; bool ret = true; + unsigned long start = address, end; enum ttu_flags flags = (enum ttu_flags)arg; /* munlock has nothing to gain from examining un-locked vmas */ if ((flags & TTU_MUNLOCK) && !(vma->vm_flags & VM_LOCKED)) return true; + if (IS_ENABLED(CONFIG_MIGRATION) && (flags & TTU_MIGRATION) && + is_zone_device_page(page) && !is_device_private_page(page)) + return true; + if (flags & TTU_SPLIT_HUGE_PMD) { split_huge_pmd_address(vma, address, - flags & TTU_MIGRATION, page); + flags & TTU_SPLIT_FREEZE, page); } + /* + * We have to assume the worse case ie pmd for invalidation. Note that + * the page can not be free in this function as call of try_to_unmap() + * must hold a reference on the page. + */ + end = min(vma->vm_end, start + (PAGE_SIZE << compound_order(page))); + mmu_notifier_invalidate_range_start(vma->vm_mm, start, end); + while (page_vma_mapped_walk(&pvmw)) { +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION + /* PMD-mapped THP migration entry */ + if (!pvmw.pte && (flags & TTU_MIGRATION)) { + VM_BUG_ON_PAGE(PageHuge(page) || !PageTransCompound(page), page); + + if (!PageAnon(page)) + continue; + + set_pmd_migration_entry(&pvmw, page); + continue; + } +#endif + /* * If the page is mlock()d, we cannot swap it out. * If it's recently referenced (perhaps page_referenced @@ -1330,6 +1408,27 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, address = pvmw.address; + if (IS_ENABLED(CONFIG_MIGRATION) && + (flags & TTU_MIGRATION) && + is_zone_device_page(page)) { + swp_entry_t entry; + pte_t swp_pte; + + pteval = ptep_get_and_clear(mm, pvmw.address, pvmw.pte); + + /* + * Store the pfn of the page in a special migration + * pte. do_swap_page() will wait until the migration + * pte is removed and then restart fault handling. + */ + entry = make_migration_entry(page, 0); + swp_pte = swp_entry_to_pte(entry); + if (pte_soft_dirty(pteval)) + swp_pte = pte_swp_mksoft_dirty(swp_pte); + set_pte_at(mm, pvmw.address, pvmw.pte, swp_pte); + goto discard; + } + if (!(flags & TTU_IGNORE_ACCESS)) { if (ptep_clear_flush_young_notify(vma, address, pvmw.pte)) { @@ -1385,7 +1484,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, */ dec_mm_counter(mm, mm_counter(page)); } else if (IS_ENABLED(CONFIG_MIGRATION) && - (flags & TTU_MIGRATION)) { + (flags & (TTU_MIGRATION|TTU_SPLIT_FREEZE))) { swp_entry_t entry; pte_t swp_pte; /* @@ -1409,6 +1508,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, if (unlikely(PageSwapBacked(page) != PageSwapCache(page))) { WARN_ON_ONCE(1); ret = false; + /* We have to invalidate as we cleared the pte */ page_vma_mapped_walk_done(&pvmw); break; } @@ -1454,8 +1554,12 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, discard: page_remove_rmap(subpage, PageHuge(page)); put_page(page); - mmu_notifier_invalidate_page(mm, address); + mmu_notifier_invalidate_range(mm, address, + address + PAGE_SIZE); } + + mmu_notifier_invalidate_range_end(vma->vm_mm, start, end); + return ret; } @@ -1510,7 +1614,8 @@ bool try_to_unmap(struct page *page, enum ttu_flags flags) * locking requirements of exec(), migration skips * temporary VMAs until after exec() completes. */ - if ((flags & TTU_MIGRATION) && !PageKsm(page) && PageAnon(page)) + if ((flags & (TTU_MIGRATION|TTU_SPLIT_FREEZE)) + && !PageKsm(page) && PageAnon(page)) rwc.invalid_vma = invalid_migration_vma; if (flags & TTU_RMAP_LOCKED) diff --git a/mm/rodata_test.c b/mm/rodata_test.c index 6bb4deb12e78b8e3724c40446069e2cd0731b4a4..d908c8769b48478b6ba738b5053f0e25a70c0732 100644 --- a/mm/rodata_test.c +++ b/mm/rodata_test.c @@ -14,7 +14,7 @@ #include #include -const int rodata_test_data = 0xC3; +static const int rodata_test_data = 0xC3; void rodata_test(void) { diff --git a/mm/shmem.c b/mm/shmem.c index b0aa6075d164df9ae4766876cc823394abaebc6d..07a1d22807beb7cfb5f85c3343a5eacdc28fb523 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -34,6 +34,7 @@ #include #include #include +#include #include /* for arch/microblaze update_mmu_cache() */ @@ -188,6 +189,38 @@ static inline void shmem_unacct_blocks(unsigned long flags, long pages) vm_unacct_memory(pages * VM_ACCT(PAGE_SIZE)); } +static inline bool shmem_inode_acct_block(struct inode *inode, long pages) +{ + struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + + if (shmem_acct_block(info->flags, pages)) + return false; + + if (sbinfo->max_blocks) { + if (percpu_counter_compare(&sbinfo->used_blocks, + sbinfo->max_blocks - pages) > 0) + goto unacct; + percpu_counter_add(&sbinfo->used_blocks, pages); + } + + return true; + +unacct: + shmem_unacct_blocks(info->flags, pages); + return false; +} + +static inline void shmem_inode_unacct_blocks(struct inode *inode, long pages) +{ + struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + + if (sbinfo->max_blocks) + percpu_counter_sub(&sbinfo->used_blocks, pages); + shmem_unacct_blocks(info->flags, pages); +} + static const struct super_operations shmem_ops; static const struct address_space_operations shmem_aops; static const struct file_operations shmem_file_operations; @@ -249,23 +282,20 @@ static void shmem_recalc_inode(struct inode *inode) freed = info->alloced - info->swapped - inode->i_mapping->nrpages; if (freed > 0) { - struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); - if (sbinfo->max_blocks) - percpu_counter_add(&sbinfo->used_blocks, -freed); info->alloced -= freed; inode->i_blocks -= freed * BLOCKS_PER_PAGE; - shmem_unacct_blocks(info->flags, freed); + shmem_inode_unacct_blocks(inode, freed); } } bool shmem_charge(struct inode *inode, long pages) { struct shmem_inode_info *info = SHMEM_I(inode); - struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); unsigned long flags; - if (shmem_acct_block(info->flags, pages)) + if (!shmem_inode_acct_block(inode, pages)) return false; + spin_lock_irqsave(&info->lock, flags); info->alloced += pages; inode->i_blocks += pages * BLOCKS_PER_PAGE; @@ -273,26 +303,12 @@ bool shmem_charge(struct inode *inode, long pages) spin_unlock_irqrestore(&info->lock, flags); inode->i_mapping->nrpages += pages; - if (!sbinfo->max_blocks) - return true; - if (percpu_counter_compare(&sbinfo->used_blocks, - sbinfo->max_blocks - pages) > 0) { - inode->i_mapping->nrpages -= pages; - spin_lock_irqsave(&info->lock, flags); - info->alloced -= pages; - shmem_recalc_inode(inode); - spin_unlock_irqrestore(&info->lock, flags); - shmem_unacct_blocks(info->flags, pages); - return false; - } - percpu_counter_add(&sbinfo->used_blocks, pages); return true; } void shmem_uncharge(struct inode *inode, long pages) { struct shmem_inode_info *info = SHMEM_I(inode); - struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); unsigned long flags; spin_lock_irqsave(&info->lock, flags); @@ -301,9 +317,7 @@ void shmem_uncharge(struct inode *inode, long pages) shmem_recalc_inode(inode); spin_unlock_irqrestore(&info->lock, flags); - if (sbinfo->max_blocks) - percpu_counter_sub(&sbinfo->used_blocks, pages); - shmem_unacct_blocks(info->flags, pages); + shmem_inode_unacct_blocks(inode, pages); } /* @@ -1022,7 +1036,11 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr) */ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE)) { spin_lock(&sbinfo->shrinklist_lock); - if (list_empty(&info->shrinklist)) { + /* + * _careful to defend against unlocked access to + * ->shrink_list in shmem_unused_huge_shrink() + */ + if (list_empty_careful(&info->shrinklist)) { list_add_tail(&info->shrinklist, &sbinfo->shrinklist); sbinfo->shrinklist_len++; @@ -1448,9 +1466,10 @@ static struct page *shmem_alloc_page(gfp_t gfp, } static struct page *shmem_alloc_and_acct_page(gfp_t gfp, - struct shmem_inode_info *info, struct shmem_sb_info *sbinfo, + struct inode *inode, pgoff_t index, bool huge) { + struct shmem_inode_info *info = SHMEM_I(inode); struct page *page; int nr; int err = -ENOSPC; @@ -1459,14 +1478,8 @@ static struct page *shmem_alloc_and_acct_page(gfp_t gfp, huge = false; nr = huge ? HPAGE_PMD_NR : 1; - if (shmem_acct_block(info->flags, nr)) + if (!shmem_inode_acct_block(inode, nr)) goto failed; - if (sbinfo->max_blocks) { - if (percpu_counter_compare(&sbinfo->used_blocks, - sbinfo->max_blocks - nr) > 0) - goto unacct; - percpu_counter_add(&sbinfo->used_blocks, nr); - } if (huge) page = shmem_alloc_hugepage(gfp, info, index); @@ -1479,10 +1492,7 @@ static struct page *shmem_alloc_and_acct_page(gfp_t gfp, } err = -ENOMEM; - if (sbinfo->max_blocks) - percpu_counter_add(&sbinfo->used_blocks, -nr); -unacct: - shmem_unacct_blocks(info->flags, nr); + shmem_inode_unacct_blocks(inode, nr); failed: return ERR_PTR(err); } @@ -1640,7 +1650,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, if (swap.val) { /* Look it up and read it in.. */ - page = lookup_swap_cache(swap); + page = lookup_swap_cache(swap, NULL, 0); if (!page) { /* Or update major stats only when swapin succeeds?? */ if (fault_type) { @@ -1747,10 +1757,9 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, } alloc_huge: - page = shmem_alloc_and_acct_page(gfp, info, sbinfo, - index, true); + page = shmem_alloc_and_acct_page(gfp, inode, index, true); if (IS_ERR(page)) { -alloc_nohuge: page = shmem_alloc_and_acct_page(gfp, info, sbinfo, +alloc_nohuge: page = shmem_alloc_and_acct_page(gfp, inode, index, false); } if (IS_ERR(page)) { @@ -1817,7 +1826,11 @@ alloc_nohuge: page = shmem_alloc_and_acct_page(gfp, info, sbinfo, * to shrink under memory pressure. */ spin_lock(&sbinfo->shrinklist_lock); - if (list_empty(&info->shrinklist)) { + /* + * _careful to defend against unlocked access to + * ->shrink_list in shmem_unused_huge_shrink() + */ + if (list_empty_careful(&info->shrinklist)) { list_add_tail(&info->shrinklist, &sbinfo->shrinklist); sbinfo->shrinklist_len++; @@ -1868,10 +1881,7 @@ alloc_nohuge: page = shmem_alloc_and_acct_page(gfp, info, sbinfo, * Error recovery. */ unacct: - if (sbinfo->max_blocks) - percpu_counter_sub(&sbinfo->used_blocks, - 1 << compound_order(page)); - shmem_unacct_blocks(info->flags, 1 << compound_order(page)); + shmem_inode_unacct_blocks(inode, 1 << compound_order(page)); if (PageTransHuge(page)) { unlock_page(page); @@ -2198,16 +2208,16 @@ bool shmem_mapping(struct address_space *mapping) return mapping->a_ops == &shmem_aops; } -int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, - pmd_t *dst_pmd, - struct vm_area_struct *dst_vma, - unsigned long dst_addr, - unsigned long src_addr, - struct page **pagep) +static int shmem_mfill_atomic_pte(struct mm_struct *dst_mm, + pmd_t *dst_pmd, + struct vm_area_struct *dst_vma, + unsigned long dst_addr, + unsigned long src_addr, + bool zeropage, + struct page **pagep) { struct inode *inode = file_inode(dst_vma->vm_file); struct shmem_inode_info *info = SHMEM_I(inode); - struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); struct address_space *mapping = inode->i_mapping; gfp_t gfp = mapping_gfp_mask(mapping); pgoff_t pgoff = linear_page_index(dst_vma, dst_addr); @@ -2219,33 +2229,30 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, int ret; ret = -ENOMEM; - if (shmem_acct_block(info->flags, 1)) + if (!shmem_inode_acct_block(inode, 1)) goto out; - if (sbinfo->max_blocks) { - if (percpu_counter_compare(&sbinfo->used_blocks, - sbinfo->max_blocks) >= 0) - goto out_unacct_blocks; - percpu_counter_inc(&sbinfo->used_blocks); - } if (!*pagep) { page = shmem_alloc_page(gfp, info, pgoff); if (!page) - goto out_dec_used_blocks; - - page_kaddr = kmap_atomic(page); - ret = copy_from_user(page_kaddr, (const void __user *)src_addr, - PAGE_SIZE); - kunmap_atomic(page_kaddr); - - /* fallback to copy_from_user outside mmap_sem */ - if (unlikely(ret)) { - *pagep = page; - if (sbinfo->max_blocks) - percpu_counter_add(&sbinfo->used_blocks, -1); - shmem_unacct_blocks(info->flags, 1); - /* don't free the page */ - return -EFAULT; + goto out_unacct_blocks; + + if (!zeropage) { /* mcopy_atomic */ + page_kaddr = kmap_atomic(page); + ret = copy_from_user(page_kaddr, + (const void __user *)src_addr, + PAGE_SIZE); + kunmap_atomic(page_kaddr); + + /* fallback to copy_from_user outside mmap_sem */ + if (unlikely(ret)) { + *pagep = page; + shmem_inode_unacct_blocks(inode, 1); + /* don't free the page */ + return -EFAULT; + } + } else { /* mfill_zeropage_atomic */ + clear_highpage(page); } } else { page = *pagep; @@ -2306,14 +2313,33 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, out_release: unlock_page(page); put_page(page); -out_dec_used_blocks: - if (sbinfo->max_blocks) - percpu_counter_add(&sbinfo->used_blocks, -1); out_unacct_blocks: - shmem_unacct_blocks(info->flags, 1); + shmem_inode_unacct_blocks(inode, 1); goto out; } +int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, + pmd_t *dst_pmd, + struct vm_area_struct *dst_vma, + unsigned long dst_addr, + unsigned long src_addr, + struct page **pagep) +{ + return shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, + dst_addr, src_addr, false, pagep); +} + +int shmem_mfill_zeropage_pte(struct mm_struct *dst_mm, + pmd_t *dst_pmd, + struct vm_area_struct *dst_vma, + unsigned long dst_addr) +{ + struct page *page = NULL; + + return shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, + dst_addr, 0, true, &page); +} + #ifdef CONFIG_TMPFS static const struct inode_operations shmem_symlink_inode_operations; static const struct inode_operations shmem_short_symlink_operations; @@ -3627,7 +3653,7 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root) #define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1) #define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN) -#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING) +#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB) SYSCALL_DEFINE2(memfd_create, const char __user *, uname, @@ -3639,8 +3665,18 @@ SYSCALL_DEFINE2(memfd_create, char *name; long len; - if (flags & ~(unsigned int)MFD_ALL_FLAGS) - return -EINVAL; + if (!(flags & MFD_HUGETLB)) { + if (flags & ~(unsigned int)MFD_ALL_FLAGS) + return -EINVAL; + } else { + /* Sealing not supported in hugetlbfs (MFD_HUGETLB) */ + if (flags & MFD_ALLOW_SEALING) + return -EINVAL; + /* Allow huge page size encoding in flags. */ + if (flags & ~(unsigned int)(MFD_ALL_FLAGS | + (MFD_HUGE_MASK << MFD_HUGE_SHIFT))) + return -EINVAL; + } /* length includes terminating zero */ len = strnlen_user(uname, MFD_NAME_MAX_LEN + 1); @@ -3649,7 +3685,7 @@ SYSCALL_DEFINE2(memfd_create, if (len > MFD_NAME_MAX_LEN + 1) return -EINVAL; - name = kmalloc(len + MFD_NAME_PREFIX_LEN, GFP_TEMPORARY); + name = kmalloc(len + MFD_NAME_PREFIX_LEN, GFP_KERNEL); if (!name) return -ENOMEM; @@ -3671,16 +3707,30 @@ SYSCALL_DEFINE2(memfd_create, goto err_name; } - file = shmem_file_setup(name, 0, VM_NORESERVE); + if (flags & MFD_HUGETLB) { + struct user_struct *user = NULL; + + file = hugetlb_file_setup(name, 0, VM_NORESERVE, &user, + HUGETLB_ANONHUGE_INODE, + (flags >> MFD_HUGE_SHIFT) & + MFD_HUGE_MASK); + } else + file = shmem_file_setup(name, 0, VM_NORESERVE); if (IS_ERR(file)) { error = PTR_ERR(file); goto err_fd; } - info = SHMEM_I(file_inode(file)); file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; file->f_flags |= O_RDWR | O_LARGEFILE; - if (flags & MFD_ALLOW_SEALING) + + if (flags & MFD_ALLOW_SEALING) { + /* + * flags check at beginning of function ensures + * this is not a hugetlbfs (MFD_HUGETLB) file. + */ + info = SHMEM_I(file_inode(file)); info->seals &= ~F_SEAL_SEAL; + } fd_install(fd, file); kfree(name); @@ -3959,7 +4009,7 @@ int __init shmem_init(void) } #ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE - if (has_transparent_hugepage() && shmem_huge < SHMEM_HUGE_DENY) + if (has_transparent_hugepage() && shmem_huge > SHMEM_HUGE_DENY) SHMEM_SB(shm_mnt->mnt_sb)->huge = shmem_huge; else shmem_huge = 0; /* just in case it was patched */ @@ -4020,7 +4070,7 @@ static ssize_t shmem_enabled_store(struct kobject *kobj, return -EINVAL; shmem_huge = huge; - if (shmem_huge < SHMEM_HUGE_DENY) + if (shmem_huge > SHMEM_HUGE_DENY) SHMEM_SB(shm_mnt->mnt_sb)->huge = shmem_huge; return count; } diff --git a/mm/slab.h b/mm/slab.h index 6885e1192ec5369d4edf7ee14aeeaf1f69c860bf..073362816acc8dd4914e610e6a56e2fdb3295f2a 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -43,6 +43,7 @@ struct kmem_cache { #include #include #include +#include /* * State of the slab allocator. @@ -412,7 +413,10 @@ static inline struct kmem_cache *slab_pre_alloc_hook(struct kmem_cache *s, gfp_t flags) { flags &= gfp_allowed_mask; - lockdep_trace_alloc(flags); + + fs_reclaim_acquire(flags); + fs_reclaim_release(flags); + might_sleep_if(gfpflags_allow_blocking(flags)); if (should_failslab(s, flags)) diff --git a/mm/slab_common.c b/mm/slab_common.c index 904a83be82de81a24a73adfac8e573db32f7118a..80164599ca5d1921d2c4b8f773f2a7c8b019cce7 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -165,9 +165,9 @@ static int init_memcg_params(struct kmem_cache *s, if (!memcg_nr_cache_ids) return 0; - arr = kzalloc(sizeof(struct memcg_cache_array) + - memcg_nr_cache_ids * sizeof(void *), - GFP_KERNEL); + arr = kvzalloc(sizeof(struct memcg_cache_array) + + memcg_nr_cache_ids * sizeof(void *), + GFP_KERNEL); if (!arr) return -ENOMEM; @@ -178,15 +178,23 @@ static int init_memcg_params(struct kmem_cache *s, static void destroy_memcg_params(struct kmem_cache *s) { if (is_root_cache(s)) - kfree(rcu_access_pointer(s->memcg_params.memcg_caches)); + kvfree(rcu_access_pointer(s->memcg_params.memcg_caches)); +} + +static void free_memcg_params(struct rcu_head *rcu) +{ + struct memcg_cache_array *old; + + old = container_of(rcu, struct memcg_cache_array, rcu); + kvfree(old); } static int update_memcg_params(struct kmem_cache *s, int new_array_size) { struct memcg_cache_array *old, *new; - new = kzalloc(sizeof(struct memcg_cache_array) + - new_array_size * sizeof(void *), GFP_KERNEL); + new = kvzalloc(sizeof(struct memcg_cache_array) + + new_array_size * sizeof(void *), GFP_KERNEL); if (!new) return -ENOMEM; @@ -198,7 +206,7 @@ static int update_memcg_params(struct kmem_cache *s, int new_array_size) rcu_assign_pointer(s->memcg_params.memcg_caches, new); if (old) - kfree_rcu(old, rcu); + call_rcu(&old->rcu, free_memcg_params); return 0; } diff --git a/mm/slob.c b/mm/slob.c index 1bae78d71096ad26bbe4575f631f3fad7b694388..a8bd6fa11a66fae671132d2a17eae201751a5093 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -432,7 +432,8 @@ __do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller) gfp &= gfp_allowed_mask; - lockdep_trace_alloc(gfp); + fs_reclaim_acquire(gfp); + fs_reclaim_release(gfp); if (size < PAGE_SIZE - align) { if (!size) @@ -538,7 +539,8 @@ static void *slob_alloc_node(struct kmem_cache *c, gfp_t flags, int node) flags &= gfp_allowed_mask; - lockdep_trace_alloc(flags); + fs_reclaim_acquire(flags); + fs_reclaim_release(flags); if (c->size < PAGE_SIZE) { b = slob_alloc(c->size, flags, c->align, node); diff --git a/mm/slub.c b/mm/slub.c index 1d3f9835f4eabe91494f48d8ace08a5e42a895f9..163352c537ab63fb8dec4be269106c3100f86560 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -238,30 +239,62 @@ static inline void stat(const struct kmem_cache *s, enum stat_item si) * Core slab cache functions *******************************************************************/ +/* + * Returns freelist pointer (ptr). With hardening, this is obfuscated + * with an XOR of the address where the pointer is held and a per-cache + * random number. + */ +static inline void *freelist_ptr(const struct kmem_cache *s, void *ptr, + unsigned long ptr_addr) +{ +#ifdef CONFIG_SLAB_FREELIST_HARDENED + return (void *)((unsigned long)ptr ^ s->random ^ ptr_addr); +#else + return ptr; +#endif +} + +/* Returns the freelist pointer recorded at location ptr_addr. */ +static inline void *freelist_dereference(const struct kmem_cache *s, + void *ptr_addr) +{ + return freelist_ptr(s, (void *)*(unsigned long *)(ptr_addr), + (unsigned long)ptr_addr); +} + static inline void *get_freepointer(struct kmem_cache *s, void *object) { - return *(void **)(object + s->offset); + return freelist_dereference(s, object + s->offset); } static void prefetch_freepointer(const struct kmem_cache *s, void *object) { - prefetch(object + s->offset); + if (object) + prefetch(freelist_dereference(s, object + s->offset)); } static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) { + unsigned long freepointer_addr; void *p; if (!debug_pagealloc_enabled()) return get_freepointer(s, object); - probe_kernel_read(&p, (void **)(object + s->offset), sizeof(p)); - return p; + freepointer_addr = (unsigned long)object + s->offset; + probe_kernel_read(&p, (void **)freepointer_addr, sizeof(p)); + return freelist_ptr(s, p, freepointer_addr); } static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) { - *(void **)(object + s->offset) = fp; + unsigned long freeptr_addr = (unsigned long)object + s->offset; + +#ifdef CONFIG_SLAB_FREELIST_HARDENED + BUG_ON(object == fp); /* naive detection of double free or corruption */ +#endif + + *(void **)freeptr_addr = freelist_ptr(s, fp, freeptr_addr); } /* Loop over all objects in a slab */ @@ -3358,8 +3391,8 @@ static void free_kmem_cache_nodes(struct kmem_cache *s) struct kmem_cache_node *n; for_each_kmem_cache_node(s, node, n) { - kmem_cache_free(kmem_cache_node, n); s->node[node] = NULL; + kmem_cache_free(kmem_cache_node, n); } } @@ -3389,8 +3422,8 @@ static int init_kmem_cache_nodes(struct kmem_cache *s) return 0; } - s->node[node] = n; init_kmem_cache_node(n); + s->node[node] = n; } return 1; } @@ -3563,6 +3596,9 @@ static int kmem_cache_open(struct kmem_cache *s, unsigned long flags) { s->flags = kmem_cache_flags(s->size, flags, s->name, s->ctor); s->reserved = 0; +#ifdef CONFIG_SLAB_FREELIST_HARDENED + s->random = get_random_long(); +#endif if (need_reserve_slab_rcu && (s->flags & SLAB_TYPESAFE_BY_RCU)) s->reserved = sizeof(struct rcu_head); @@ -4196,7 +4232,7 @@ void __init kmem_cache_init(void) cpuhp_setup_state_nocalls(CPUHP_SLUB_DEAD, "slub:dead", NULL, slub_cpu_dead); - pr_info("SLUB: HWalign=%d, Order=%d-%d, MinObjects=%d, CPUs=%d, Nodes=%d\n", + pr_info("SLUB: HWalign=%d, Order=%d-%d, MinObjects=%d, CPUs=%u, Nodes=%d\n", cache_line_size(), slub_min_order, slub_max_order, slub_min_objects, nr_cpu_ids, nr_node_ids); @@ -4561,7 +4597,7 @@ static int list_locations(struct kmem_cache *s, char *buf, struct kmem_cache_node *n; if (!map || !alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location), - GFP_TEMPORARY)) { + GFP_KERNEL)) { kfree(map); return sprintf(buf, "Out of memory\n"); } @@ -5423,7 +5459,7 @@ static struct attribute *slab_attrs[] = { NULL }; -static struct attribute_group slab_attr_group = { +static const struct attribute_group slab_attr_group = { .attrs = slab_attrs, }; @@ -5642,13 +5678,14 @@ static void sysfs_slab_remove_workfn(struct work_struct *work) * A cache is never shut down before deactivation is * complete, so no need to worry about synchronization. */ - return; + goto out; #ifdef CONFIG_MEMCG kset_unregister(s->memcg_kset); #endif kobject_uevent(&s->kobj, KOBJ_REMOVE); kobject_del(&s->kobj); +out: kobject_put(&s->kobj); } diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index c50b1a14d55ec0f36ae718f602216dd24d591a6b..d1a39b8051e01b9f979ad93b28bf0295d7a2cea3 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -54,14 +54,9 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node) if (slab_is_available()) { struct page *page; - if (node_state(node, N_HIGH_MEMORY)) - page = alloc_pages_node( - node, GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL, - get_order(size)); - else - page = alloc_pages( - GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL, - get_order(size)); + page = alloc_pages_node(node, + GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL, + get_order(size)); if (page) return page_address(page); return NULL; diff --git a/mm/sparse.c b/mm/sparse.c index 7b4be3fd5cac074177b7f17ebdeb12dfa56d22e5..83b3bf6461af556698c457627b0bc732725a0300 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -65,14 +65,10 @@ static noinline struct mem_section __ref *sparse_index_alloc(int nid) unsigned long array_size = SECTIONS_PER_ROOT * sizeof(struct mem_section); - if (slab_is_available()) { - if (node_state(nid, N_HIGH_MEMORY)) - section = kzalloc_node(array_size, GFP_KERNEL, nid); - else - section = kzalloc(array_size, GFP_KERNEL); - } else { + if (slab_is_available()) + section = kzalloc_node(array_size, GFP_KERNEL, nid); + else section = memblock_virt_alloc_node(array_size, nid); - } return section; } @@ -630,7 +626,7 @@ void online_mem_sections(unsigned long start_pfn, unsigned long end_pfn) unsigned long pfn; for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { - unsigned long section_nr = pfn_to_section_nr(start_pfn); + unsigned long section_nr = pfn_to_section_nr(pfn); struct mem_section *ms; /* onlining code should never touch invalid ranges */ diff --git a/mm/swap.c b/mm/swap.c index 60b1d2a758522a6b7ebb02aae182dd554e22bdab..a77d68f2c1b61de1bc8102656e7e482a442963b1 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -575,7 +575,7 @@ static void lru_lazyfree_fn(struct page *page, struct lruvec *lruvec, void *arg) { if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) && - !PageUnevictable(page)) { + !PageSwapCache(page) && !PageUnevictable(page)) { bool active = PageActive(page); del_page_from_lru_list(page, lruvec, @@ -665,7 +665,7 @@ void deactivate_file_page(struct page *page) void mark_page_lazyfree(struct page *page) { if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) && - !PageUnevictable(page)) { + !PageSwapCache(page) && !PageUnevictable(page)) { struct pagevec *pvec = &get_cpu_var(lru_lazyfree_pvecs); get_page(page); @@ -765,6 +765,17 @@ void release_pages(struct page **pages, int nr, bool cold) if (is_huge_zero_page(page)) continue; + /* Device public page can not be huge page */ + if (is_device_public_page(page)) { + if (locked_pgdat) { + spin_unlock_irqrestore(&locked_pgdat->lru_lock, + flags); + locked_pgdat = NULL; + } + put_zone_device_private_or_public_page(page); + continue; + } + page = compound_head(page); if (!put_page_testzero(page)) continue; @@ -946,28 +957,34 @@ void pagevec_remove_exceptionals(struct pagevec *pvec) } /** - * pagevec_lookup - gang pagecache lookup + * pagevec_lookup_range - gang pagecache lookup * @pvec: Where the resulting pages are placed * @mapping: The address_space to search * @start: The starting page index + * @end: The final page index * @nr_pages: The maximum number of pages * - * pagevec_lookup() will search for and return a group of up to @nr_pages pages - * in the mapping. The pages are placed in @pvec. pagevec_lookup() takes a + * pagevec_lookup_range() will search for and return a group of up to @nr_pages + * pages in the mapping starting from index @start and upto index @end + * (inclusive). The pages are placed in @pvec. pagevec_lookup() takes a * reference against the pages in @pvec. * * The search returns a group of mapping-contiguous pages with ascending - * indexes. There may be holes in the indices due to not-present pages. + * indexes. There may be holes in the indices due to not-present pages. We + * also update @start to index the next page for the traversal. * - * pagevec_lookup() returns the number of pages which were found. + * pagevec_lookup_range() returns the number of pages which were found. If this + * number is smaller than @nr_pages, the end of specified range has been + * reached. */ -unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, - pgoff_t start, unsigned nr_pages) +unsigned pagevec_lookup_range(struct pagevec *pvec, + struct address_space *mapping, pgoff_t *start, pgoff_t end) { - pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages); + pvec->nr = find_get_pages_range(mapping, start, end, PAGEVEC_SIZE, + pvec->pages); return pagevec_count(pvec); } -EXPORT_SYMBOL(pagevec_lookup); +EXPORT_SYMBOL(pagevec_lookup_range); unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping, pgoff_t *index, int tag, unsigned nr_pages) diff --git a/mm/swap_state.c b/mm/swap_state.c index b68c93014f50c681b5bc1f3d9da2cd8db1fe025a..ed91091d1e68801daa22bd9e2d2a7833233adcfc 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -37,6 +37,29 @@ static const struct address_space_operations swap_aops = { struct address_space *swapper_spaces[MAX_SWAPFILES]; static unsigned int nr_swapper_spaces[MAX_SWAPFILES]; +bool swap_vma_readahead = true; + +#define SWAP_RA_MAX_ORDER_DEFAULT 3 + +static int swap_ra_max_order = SWAP_RA_MAX_ORDER_DEFAULT; + +#define SWAP_RA_WIN_SHIFT (PAGE_SHIFT / 2) +#define SWAP_RA_HITS_MASK ((1UL << SWAP_RA_WIN_SHIFT) - 1) +#define SWAP_RA_HITS_MAX SWAP_RA_HITS_MASK +#define SWAP_RA_WIN_MASK (~PAGE_MASK & ~SWAP_RA_HITS_MASK) + +#define SWAP_RA_HITS(v) ((v) & SWAP_RA_HITS_MASK) +#define SWAP_RA_WIN(v) (((v) & SWAP_RA_WIN_MASK) >> SWAP_RA_WIN_SHIFT) +#define SWAP_RA_ADDR(v) ((v) & PAGE_MASK) + +#define SWAP_RA_VAL(addr, win, hits) \ + (((addr) & PAGE_MASK) | \ + (((win) << SWAP_RA_WIN_SHIFT) & SWAP_RA_WIN_MASK) | \ + ((hits) & SWAP_RA_HITS_MASK)) + +/* Initial readahead hits is 4 to start up with a small window */ +#define GET_SWAP_RA_VAL(vma) \ + (atomic_long_read(&(vma)->swap_readahead_info) ? : 4) #define INC_CACHE_INFO(x) do { swap_cache_info.x++; } while (0) #define ADD_CACHE_INFO(x, nr) do { swap_cache_info.x += (nr); } while (0) @@ -219,6 +242,17 @@ int add_to_swap(struct page *page) * clear SWAP_HAS_CACHE flag. */ goto fail; + /* + * Normally the page will be dirtied in unmap because its pte should be + * dirty. A special case is MADV_FREE page. The page'e pte could have + * dirty bit cleared but the page's SwapBacked bit is still set because + * clearing the dirty bit and SwapBacked bit has no lock protected. For + * such page, unmap will not set dirty bit for it, so page reclaim will + * not write the page out. This can cause data corruption when the page + * is swap in later. Always setting the dirty bit for the page solves + * the problem. + */ + set_page_dirty(page); return 1; @@ -297,19 +331,36 @@ void free_pages_and_swap_cache(struct page **pages, int nr) * lock getting page table operations atomic even if we drop the page * lock before returning. */ -struct page * lookup_swap_cache(swp_entry_t entry) +struct page *lookup_swap_cache(swp_entry_t entry, struct vm_area_struct *vma, + unsigned long addr) { struct page *page; + unsigned long ra_info; + int win, hits, readahead; page = find_get_page(swap_address_space(entry), swp_offset(entry)); - if (page && likely(!PageTransCompound(page))) { + INC_CACHE_INFO(find_total); + if (page) { INC_CACHE_INFO(find_success); - if (TestClearPageReadahead(page)) - atomic_inc(&swapin_readahead_hits); + if (unlikely(PageTransCompound(page))) + return page; + readahead = TestClearPageReadahead(page); + if (vma) { + ra_info = GET_SWAP_RA_VAL(vma); + win = SWAP_RA_WIN(ra_info); + hits = SWAP_RA_HITS(ra_info); + if (readahead) + hits = min_t(int, hits + 1, SWAP_RA_HITS_MAX); + atomic_long_set(&vma->swap_readahead_info, + SWAP_RA_VAL(addr, win, hits)); + } + if (readahead) { + count_vm_event(SWAP_RA_HIT); + if (!vma) + atomic_inc(&swapin_readahead_hits); + } } - - INC_CACHE_INFO(find_total); return page; } @@ -424,22 +475,20 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, return retpage; } -static unsigned long swapin_nr_pages(unsigned long offset) +static unsigned int __swapin_nr_pages(unsigned long prev_offset, + unsigned long offset, + int hits, + int max_pages, + int prev_win) { - static unsigned long prev_offset; - unsigned int pages, max_pages, last_ra; - static atomic_t last_readahead_pages; - - max_pages = 1 << READ_ONCE(page_cluster); - if (max_pages <= 1) - return 1; + unsigned int pages, last_ra; /* * This heuristic has been found to work well on both sequential and * random loads, swapping to hard disk or to SSD: please don't ask * what the "+ 2" means, it just happens to work well, that's all. */ - pages = atomic_xchg(&swapin_readahead_hits, 0) + 2; + pages = hits + 2; if (pages == 2) { /* * We can have no readahead hits to judge by: but must not get @@ -448,7 +497,6 @@ static unsigned long swapin_nr_pages(unsigned long offset) */ if (offset != prev_offset + 1 && offset != prev_offset - 1) pages = 1; - prev_offset = offset; } else { unsigned int roundup = 4; while (roundup < pages) @@ -460,9 +508,28 @@ static unsigned long swapin_nr_pages(unsigned long offset) pages = max_pages; /* Don't shrink readahead too fast */ - last_ra = atomic_read(&last_readahead_pages) / 2; + last_ra = prev_win / 2; if (pages < last_ra) pages = last_ra; + + return pages; +} + +static unsigned long swapin_nr_pages(unsigned long offset) +{ + static unsigned long prev_offset; + unsigned int hits, pages, max_pages; + static atomic_t last_readahead_pages; + + max_pages = 1 << READ_ONCE(page_cluster); + if (max_pages <= 1) + return 1; + + hits = atomic_xchg(&swapin_readahead_hits, 0); + pages = __swapin_nr_pages(prev_offset, offset, hits, max_pages, + atomic_read(&last_readahead_pages)); + if (!hits) + prev_offset = offset; atomic_set(&last_readahead_pages, pages); return pages; @@ -496,7 +563,7 @@ struct page *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask, unsigned long start_offset, end_offset; unsigned long mask; struct blk_plug plug; - bool do_poll = true; + bool do_poll = true, page_allocated; mask = swapin_nr_pages(offset) - 1; if (!mask) @@ -512,12 +579,19 @@ struct page *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask, blk_start_plug(&plug); for (offset = start_offset; offset <= end_offset ; offset++) { /* Ok, do the async read-ahead now */ - page = read_swap_cache_async(swp_entry(swp_type(entry), offset), - gfp_mask, vma, addr, false); + page = __read_swap_cache_async( + swp_entry(swp_type(entry), offset), + gfp_mask, vma, addr, &page_allocated); if (!page) continue; - if (offset != entry_offset && likely(!PageTransCompound(page))) - SetPageReadahead(page); + if (page_allocated) { + swap_readpage(page, false); + if (offset != entry_offset && + likely(!PageTransCompound(page))) { + SetPageReadahead(page); + count_vm_event(SWAP_RA); + } + } put_page(page); } blk_finish_plug(&plug); @@ -561,3 +635,210 @@ void exit_swap_address_space(unsigned int type) synchronize_rcu(); kvfree(spaces); } + +static inline void swap_ra_clamp_pfn(struct vm_area_struct *vma, + unsigned long faddr, + unsigned long lpfn, + unsigned long rpfn, + unsigned long *start, + unsigned long *end) +{ + *start = max3(lpfn, PFN_DOWN(vma->vm_start), + PFN_DOWN(faddr & PMD_MASK)); + *end = min3(rpfn, PFN_DOWN(vma->vm_end), + PFN_DOWN((faddr & PMD_MASK) + PMD_SIZE)); +} + +struct page *swap_readahead_detect(struct vm_fault *vmf, + struct vma_swap_readahead *swap_ra) +{ + struct vm_area_struct *vma = vmf->vma; + unsigned long swap_ra_info; + struct page *page; + swp_entry_t entry; + unsigned long faddr, pfn, fpfn; + unsigned long start, end; + pte_t *pte; + unsigned int max_win, hits, prev_win, win, left; +#ifndef CONFIG_64BIT + pte_t *tpte; +#endif + + faddr = vmf->address; + entry = pte_to_swp_entry(vmf->orig_pte); + if ((unlikely(non_swap_entry(entry)))) + return NULL; + page = lookup_swap_cache(entry, vma, faddr); + if (page) + return page; + + max_win = 1 << READ_ONCE(swap_ra_max_order); + if (max_win == 1) { + swap_ra->win = 1; + return NULL; + } + + fpfn = PFN_DOWN(faddr); + swap_ra_info = GET_SWAP_RA_VAL(vma); + pfn = PFN_DOWN(SWAP_RA_ADDR(swap_ra_info)); + prev_win = SWAP_RA_WIN(swap_ra_info); + hits = SWAP_RA_HITS(swap_ra_info); + swap_ra->win = win = __swapin_nr_pages(pfn, fpfn, hits, + max_win, prev_win); + atomic_long_set(&vma->swap_readahead_info, + SWAP_RA_VAL(faddr, win, 0)); + + if (win == 1) + return NULL; + + /* Copy the PTEs because the page table may be unmapped */ + if (fpfn == pfn + 1) + swap_ra_clamp_pfn(vma, faddr, fpfn, fpfn + win, &start, &end); + else if (pfn == fpfn + 1) + swap_ra_clamp_pfn(vma, faddr, fpfn - win + 1, fpfn + 1, + &start, &end); + else { + left = (win - 1) / 2; + swap_ra_clamp_pfn(vma, faddr, fpfn - left, fpfn + win - left, + &start, &end); + } + swap_ra->nr_pte = end - start; + swap_ra->offset = fpfn - start; + pte = vmf->pte - swap_ra->offset; +#ifdef CONFIG_64BIT + swap_ra->ptes = pte; +#else + tpte = swap_ra->ptes; + for (pfn = start; pfn != end; pfn++) + *tpte++ = *pte++; +#endif + + return NULL; +} + +struct page *do_swap_page_readahead(swp_entry_t fentry, gfp_t gfp_mask, + struct vm_fault *vmf, + struct vma_swap_readahead *swap_ra) +{ + struct blk_plug plug; + struct vm_area_struct *vma = vmf->vma; + struct page *page; + pte_t *pte, pentry; + swp_entry_t entry; + unsigned int i; + bool page_allocated; + + if (swap_ra->win == 1) + goto skip; + + blk_start_plug(&plug); + for (i = 0, pte = swap_ra->ptes; i < swap_ra->nr_pte; + i++, pte++) { + pentry = *pte; + if (pte_none(pentry)) + continue; + if (pte_present(pentry)) + continue; + entry = pte_to_swp_entry(pentry); + if (unlikely(non_swap_entry(entry))) + continue; + page = __read_swap_cache_async(entry, gfp_mask, vma, + vmf->address, &page_allocated); + if (!page) + continue; + if (page_allocated) { + swap_readpage(page, false); + if (i != swap_ra->offset && + likely(!PageTransCompound(page))) { + SetPageReadahead(page); + count_vm_event(SWAP_RA); + } + } + put_page(page); + } + blk_finish_plug(&plug); + lru_add_drain(); +skip: + return read_swap_cache_async(fentry, gfp_mask, vma, vmf->address, + swap_ra->win == 1); +} + +#ifdef CONFIG_SYSFS +static ssize_t vma_ra_enabled_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", swap_vma_readahead ? "true" : "false"); +} +static ssize_t vma_ra_enabled_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + if (!strncmp(buf, "true", 4) || !strncmp(buf, "1", 1)) + swap_vma_readahead = true; + else if (!strncmp(buf, "false", 5) || !strncmp(buf, "0", 1)) + swap_vma_readahead = false; + else + return -EINVAL; + + return count; +} +static struct kobj_attribute vma_ra_enabled_attr = + __ATTR(vma_ra_enabled, 0644, vma_ra_enabled_show, + vma_ra_enabled_store); + +static ssize_t vma_ra_max_order_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", swap_ra_max_order); +} +static ssize_t vma_ra_max_order_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err, v; + + err = kstrtoint(buf, 10, &v); + if (err || v > SWAP_RA_ORDER_CEILING || v <= 0) + return -EINVAL; + + swap_ra_max_order = v; + + return count; +} +static struct kobj_attribute vma_ra_max_order_attr = + __ATTR(vma_ra_max_order, 0644, vma_ra_max_order_show, + vma_ra_max_order_store); + +static struct attribute *swap_attrs[] = { + &vma_ra_enabled_attr.attr, + &vma_ra_max_order_attr.attr, + NULL, +}; + +static struct attribute_group swap_attr_group = { + .attrs = swap_attrs, +}; + +static int __init swap_init_sysfs(void) +{ + int err; + struct kobject *swap_kobj; + + swap_kobj = kobject_create_and_add("swap", mm_kobj); + if (!swap_kobj) { + pr_err("failed to create swap kobject\n"); + return -ENOMEM; + } + err = sysfs_create_group(swap_kobj, &swap_attr_group); + if (err) { + pr_err("failed to register swap group\n"); + goto delete_obj; + } + return 0; + +delete_obj: + kobject_put(swap_kobj); + return err; +} +subsys_initcall(swap_init_sysfs); +#endif diff --git a/mm/swapfile.c b/mm/swapfile.c index 6ba4aab2db0b570a241abb8935f901833c65b862..bf91dc9e7a791d38b28ab84f10b57892fc0af9dc 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -60,7 +60,7 @@ atomic_long_t nr_swap_pages; EXPORT_SYMBOL_GPL(nr_swap_pages); /* protected with swap_lock. reading in vm_swap_full() doesn't need lock */ long total_swap_pages; -static int least_priority; +static int least_priority = -1; static const char Bad_file[] = "Bad swap file entry "; static const char Unused_file[] = "Unused swap file entry "; @@ -85,7 +85,7 @@ PLIST_HEAD(swap_active_head); * is held and the locking order requires swap_lock to be taken * before any swap_info_struct->lock. */ -static PLIST_HEAD(swap_avail_head); +struct plist_head *swap_avail_heads; static DEFINE_SPINLOCK(swap_avail_lock); struct swap_info_struct *swap_info[MAX_SWAPFILES]; @@ -96,6 +96,8 @@ static DECLARE_WAIT_QUEUE_HEAD(proc_poll_wait); /* Activity counter to indicate that a swapon or swapoff has occurred */ static atomic_t proc_poll_event = ATOMIC_INIT(0); +atomic_t nr_rotate_swap = ATOMIC_INIT(0); + static inline unsigned char swap_count(unsigned char ent) { return ent & ~SWAP_HAS_CACHE; /* may include SWAP_HAS_CONT flag */ @@ -265,6 +267,16 @@ static inline void cluster_set_null(struct swap_cluster_info *info) info->data = 0; } +static inline bool cluster_is_huge(struct swap_cluster_info *info) +{ + return info->flags & CLUSTER_FLAG_HUGE; +} + +static inline void cluster_clear_huge(struct swap_cluster_info *info) +{ + info->flags &= ~CLUSTER_FLAG_HUGE; +} + static inline struct swap_cluster_info *lock_cluster(struct swap_info_struct *si, unsigned long offset) { @@ -580,6 +592,21 @@ static bool scan_swap_map_try_ssd_cluster(struct swap_info_struct *si, return found_free; } +static void __del_from_avail_list(struct swap_info_struct *p) +{ + int nid; + + for_each_node(nid) + plist_del(&p->avail_lists[nid], &swap_avail_heads[nid]); +} + +static void del_from_avail_list(struct swap_info_struct *p) +{ + spin_lock(&swap_avail_lock); + __del_from_avail_list(p); + spin_unlock(&swap_avail_lock); +} + static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset, unsigned int nr_entries) { @@ -593,10 +620,20 @@ static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset, if (si->inuse_pages == si->pages) { si->lowest_bit = si->max; si->highest_bit = 0; - spin_lock(&swap_avail_lock); - plist_del(&si->avail_list, &swap_avail_head); - spin_unlock(&swap_avail_lock); + del_from_avail_list(si); + } +} + +static void add_to_avail_list(struct swap_info_struct *p) +{ + int nid; + + spin_lock(&swap_avail_lock); + for_each_node(nid) { + WARN_ON(!plist_node_empty(&p->avail_lists[nid])); + plist_add(&p->avail_lists[nid], &swap_avail_heads[nid]); } + spin_unlock(&swap_avail_lock); } static void swap_range_free(struct swap_info_struct *si, unsigned long offset, @@ -611,13 +648,8 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset, bool was_full = !si->highest_bit; si->highest_bit = end; - if (was_full && (si->flags & SWP_WRITEOK)) { - spin_lock(&swap_avail_lock); - WARN_ON(!plist_node_empty(&si->avail_list)); - if (plist_node_empty(&si->avail_list)) - plist_add(&si->avail_list, &swap_avail_head); - spin_unlock(&swap_avail_lock); - } + if (was_full && (si->flags & SWP_WRITEOK)) + add_to_avail_list(si); } atomic_long_add(nr_entries, &nr_swap_pages); si->inuse_pages -= nr_entries; @@ -846,7 +878,7 @@ static int swap_alloc_cluster(struct swap_info_struct *si, swp_entry_t *slot) offset = idx * SWAPFILE_CLUSTER; ci = lock_cluster(si, offset); alloc_cluster(si, idx); - cluster_set_count_flag(ci, SWAPFILE_CLUSTER, 0); + cluster_set_count_flag(ci, SWAPFILE_CLUSTER, CLUSTER_FLAG_HUGE); map = si->swap_map + offset; for (i = 0; i < SWAPFILE_CLUSTER; i++) @@ -898,6 +930,7 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[]) struct swap_info_struct *si, *next; long avail_pgs; int n_ret = 0; + int node; /* Only single cluster request supported */ WARN_ON_ONCE(n_goal > 1 && cluster); @@ -917,14 +950,15 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[]) spin_lock(&swap_avail_lock); start_over: - plist_for_each_entry_safe(si, next, &swap_avail_head, avail_list) { + node = numa_node_id(); + plist_for_each_entry_safe(si, next, &swap_avail_heads[node], avail_lists[node]) { /* requeue si to after same-priority siblings */ - plist_requeue(&si->avail_list, &swap_avail_head); + plist_requeue(&si->avail_lists[node], &swap_avail_heads[node]); spin_unlock(&swap_avail_lock); spin_lock(&si->lock); if (!si->highest_bit || !(si->flags & SWP_WRITEOK)) { spin_lock(&swap_avail_lock); - if (plist_node_empty(&si->avail_list)) { + if (plist_node_empty(&si->avail_lists[node])) { spin_unlock(&si->lock); goto nextsi; } @@ -934,13 +968,14 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[]) WARN(!(si->flags & SWP_WRITEOK), "swap_info %d in list but !SWP_WRITEOK\n", si->type); - plist_del(&si->avail_list, &swap_avail_head); + __del_from_avail_list(si); spin_unlock(&si->lock); goto nextsi; } - if (cluster) - n_ret = swap_alloc_cluster(si, swp_entries); - else + if (cluster) { + if (!(si->flags & SWP_FILE)) + n_ret = swap_alloc_cluster(si, swp_entries); + } else n_ret = scan_swap_map_slots(si, SWAP_HAS_CACHE, n_goal, swp_entries); spin_unlock(&si->lock); @@ -962,7 +997,7 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[]) * swap_avail_head list then try it, otherwise start over * if we have not gotten any slots. */ - if (plist_node_empty(&next->avail_list)) + if (plist_node_empty(&next->avail_lists[node])) goto start_over; } @@ -1168,22 +1203,57 @@ static void swapcache_free_cluster(swp_entry_t entry) struct swap_cluster_info *ci; struct swap_info_struct *si; unsigned char *map; - unsigned int i; + unsigned int i, free_entries = 0; + unsigned char val; - si = swap_info_get(entry); + si = _swap_info_get(entry); if (!si) return; ci = lock_cluster(si, offset); + VM_BUG_ON(!cluster_is_huge(ci)); map = si->swap_map + offset; for (i = 0; i < SWAPFILE_CLUSTER; i++) { - VM_BUG_ON(map[i] != SWAP_HAS_CACHE); - map[i] = 0; + val = map[i]; + VM_BUG_ON(!(val & SWAP_HAS_CACHE)); + if (val == SWAP_HAS_CACHE) + free_entries++; + } + if (!free_entries) { + for (i = 0; i < SWAPFILE_CLUSTER; i++) + map[i] &= ~SWAP_HAS_CACHE; } + cluster_clear_huge(ci); unlock_cluster(ci); - mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER); - swap_free_cluster(si, idx); - spin_unlock(&si->lock); + if (free_entries == SWAPFILE_CLUSTER) { + spin_lock(&si->lock); + ci = lock_cluster(si, offset); + memset(map, 0, SWAPFILE_CLUSTER); + unlock_cluster(ci); + mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER); + swap_free_cluster(si, idx); + spin_unlock(&si->lock); + } else if (free_entries) { + for (i = 0; i < SWAPFILE_CLUSTER; i++, entry.val++) { + if (!__swap_entry_free(si, entry, SWAP_HAS_CACHE)) + free_swap_slot(entry); + } + } +} + +int split_swap_cluster(swp_entry_t entry) +{ + struct swap_info_struct *si; + struct swap_cluster_info *ci; + unsigned long offset = swp_offset(entry); + + si = _swap_info_get(entry); + if (!si) + return -EBUSY; + ci = lock_cluster(si, offset); + cluster_clear_huge(ci); + unlock_cluster(ci); + return 0; } #else static inline void swapcache_free_cluster(swp_entry_t entry) @@ -1332,29 +1402,161 @@ int swp_swapcount(swp_entry_t entry) return count; } +#ifdef CONFIG_THP_SWAP +static bool swap_page_trans_huge_swapped(struct swap_info_struct *si, + swp_entry_t entry) +{ + struct swap_cluster_info *ci; + unsigned char *map = si->swap_map; + unsigned long roffset = swp_offset(entry); + unsigned long offset = round_down(roffset, SWAPFILE_CLUSTER); + int i; + bool ret = false; + + ci = lock_cluster_or_swap_info(si, offset); + if (!ci || !cluster_is_huge(ci)) { + if (map[roffset] != SWAP_HAS_CACHE) + ret = true; + goto unlock_out; + } + for (i = 0; i < SWAPFILE_CLUSTER; i++) { + if (map[offset + i] != SWAP_HAS_CACHE) { + ret = true; + break; + } + } +unlock_out: + unlock_cluster_or_swap_info(si, ci); + return ret; +} + +static bool page_swapped(struct page *page) +{ + swp_entry_t entry; + struct swap_info_struct *si; + + if (likely(!PageTransCompound(page))) + return page_swapcount(page) != 0; + + page = compound_head(page); + entry.val = page_private(page); + si = _swap_info_get(entry); + if (si) + return swap_page_trans_huge_swapped(si, entry); + return false; +} + +static int page_trans_huge_map_swapcount(struct page *page, int *total_mapcount, + int *total_swapcount) +{ + int i, map_swapcount, _total_mapcount, _total_swapcount; + unsigned long offset = 0; + struct swap_info_struct *si; + struct swap_cluster_info *ci = NULL; + unsigned char *map = NULL; + int mapcount, swapcount = 0; + + /* hugetlbfs shouldn't call it */ + VM_BUG_ON_PAGE(PageHuge(page), page); + + if (likely(!PageTransCompound(page))) { + mapcount = atomic_read(&page->_mapcount) + 1; + if (total_mapcount) + *total_mapcount = mapcount; + if (PageSwapCache(page)) + swapcount = page_swapcount(page); + if (total_swapcount) + *total_swapcount = swapcount; + return mapcount + swapcount; + } + + page = compound_head(page); + + _total_mapcount = _total_swapcount = map_swapcount = 0; + if (PageSwapCache(page)) { + swp_entry_t entry; + + entry.val = page_private(page); + si = _swap_info_get(entry); + if (si) { + map = si->swap_map; + offset = swp_offset(entry); + } + } + if (map) + ci = lock_cluster(si, offset); + for (i = 0; i < HPAGE_PMD_NR; i++) { + mapcount = atomic_read(&page[i]._mapcount) + 1; + _total_mapcount += mapcount; + if (map) { + swapcount = swap_count(map[offset + i]); + _total_swapcount += swapcount; + } + map_swapcount = max(map_swapcount, mapcount + swapcount); + } + unlock_cluster(ci); + if (PageDoubleMap(page)) { + map_swapcount -= 1; + _total_mapcount -= HPAGE_PMD_NR; + } + mapcount = compound_mapcount(page); + map_swapcount += mapcount; + _total_mapcount += mapcount; + if (total_mapcount) + *total_mapcount = _total_mapcount; + if (total_swapcount) + *total_swapcount = _total_swapcount; + + return map_swapcount; +} +#else +#define swap_page_trans_huge_swapped(si, entry) swap_swapcount(si, entry) +#define page_swapped(page) (page_swapcount(page) != 0) + +static int page_trans_huge_map_swapcount(struct page *page, int *total_mapcount, + int *total_swapcount) +{ + int mapcount, swapcount = 0; + + /* hugetlbfs shouldn't call it */ + VM_BUG_ON_PAGE(PageHuge(page), page); + + mapcount = page_trans_huge_mapcount(page, total_mapcount); + if (PageSwapCache(page)) + swapcount = page_swapcount(page); + if (total_swapcount) + *total_swapcount = swapcount; + return mapcount + swapcount; +} +#endif + /* * We can write to an anon page without COW if there are no other references * to it. And as a side-effect, free up its swap: because the old content * on disk will never be read, and seeking back there to write new content * later would only waste time away from clustering. * - * NOTE: total_mapcount should not be relied upon by the caller if + * NOTE: total_map_swapcount should not be relied upon by the caller if * reuse_swap_page() returns false, but it may be always overwritten * (see the other implementation for CONFIG_SWAP=n). */ -bool reuse_swap_page(struct page *page, int *total_mapcount) +bool reuse_swap_page(struct page *page, int *total_map_swapcount) { - int count; + int count, total_mapcount, total_swapcount; VM_BUG_ON_PAGE(!PageLocked(page), page); if (unlikely(PageKsm(page))) return false; - count = page_trans_huge_mapcount(page, total_mapcount); - if (count <= 1 && PageSwapCache(page)) { - count += page_swapcount(page); - if (count != 1) - goto out; + count = page_trans_huge_map_swapcount(page, &total_mapcount, + &total_swapcount); + if (total_map_swapcount) + *total_map_swapcount = total_mapcount + total_swapcount; + if (count == 1 && PageSwapCache(page) && + (likely(!PageTransCompound(page)) || + /* The remaining swap count will be freed soon */ + total_swapcount == page_swapcount(page))) { if (!PageWriteback(page)) { + page = compound_head(page); delete_from_swap_cache(page); SetPageDirty(page); } else { @@ -1370,7 +1572,7 @@ bool reuse_swap_page(struct page *page, int *total_mapcount) spin_unlock(&p->lock); } } -out: + return count <= 1; } @@ -1386,7 +1588,7 @@ int try_to_free_swap(struct page *page) return 0; if (PageWriteback(page)) return 0; - if (page_swapcount(page)) + if (page_swapped(page)) return 0; /* @@ -1407,6 +1609,7 @@ int try_to_free_swap(struct page *page) if (pm_suspended_storage()) return 0; + page = compound_head(page); delete_from_swap_cache(page); SetPageDirty(page); return 1; @@ -1428,7 +1631,8 @@ int free_swap_and_cache(swp_entry_t entry) p = _swap_info_get(entry); if (p) { count = __swap_entry_free(p, entry, 1); - if (count == SWAP_HAS_CACHE) { + if (count == SWAP_HAS_CACHE && + !swap_page_trans_huge_swapped(p, entry)) { page = find_get_page(swap_address_space(entry), swp_offset(entry)); if (page && !trylock_page(page)) { @@ -1445,7 +1649,8 @@ int free_swap_and_cache(swp_entry_t entry) */ if (PageSwapCache(page) && !PageWriteback(page) && (!page_mapped(page) || mem_cgroup_swap_full(page)) && - !swap_swapcount(p, entry)) { + !swap_page_trans_huge_swapped(p, entry)) { + page = compound_head(page); delete_from_swap_cache(page); SetPageDirty(page); } @@ -1999,7 +2204,7 @@ int try_to_unuse(unsigned int type, bool frontswap, .sync_mode = WB_SYNC_NONE, }; - swap_writepage(page, &wbc); + swap_writepage(compound_head(page), &wbc); lock_page(page); wait_on_page_writeback(page); } @@ -2012,8 +2217,9 @@ int try_to_unuse(unsigned int type, bool frontswap, * delete, since it may not have been written out to swap yet. */ if (PageSwapCache(page) && - likely(page_private(page) == entry.val)) - delete_from_swap_cache(page); + likely(page_private(page) == entry.val) && + !page_swapped(page)) + delete_from_swap_cache(compound_head(page)); /* * So we could skip searching mms once swap count went @@ -2226,10 +2432,24 @@ static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span) return generic_swapfile_activate(sis, swap_file, span); } +static int swap_node(struct swap_info_struct *p) +{ + struct block_device *bdev; + + if (p->bdev) + bdev = p->bdev; + else + bdev = p->swap_file->f_inode->i_sb->s_bdev; + + return bdev ? bdev->bd_disk->node_id : NUMA_NO_NODE; +} + static void _enable_swap_info(struct swap_info_struct *p, int prio, unsigned char *swap_map, struct swap_cluster_info *cluster_info) { + int i; + if (prio >= 0) p->prio = prio; else @@ -2239,7 +2459,16 @@ static void _enable_swap_info(struct swap_info_struct *p, int prio, * low-to-high, while swap ordering is high-to-low */ p->list.prio = -p->prio; - p->avail_list.prio = -p->prio; + for_each_node(i) { + if (p->prio >= 0) + p->avail_lists[i].prio = -p->prio; + else { + if (swap_node(p) == i) + p->avail_lists[i].prio = 1; + else + p->avail_lists[i].prio = -p->prio; + } + } p->swap_map = swap_map; p->cluster_info = cluster_info; p->flags |= SWP_WRITEOK; @@ -2258,9 +2487,7 @@ static void _enable_swap_info(struct swap_info_struct *p, int prio, * swap_info_struct. */ plist_add(&p->list, &swap_active_head); - spin_lock(&swap_avail_lock); - plist_add(&p->avail_list, &swap_avail_head); - spin_unlock(&swap_avail_lock); + add_to_avail_list(p); } static void enable_swap_info(struct swap_info_struct *p, int prio, @@ -2345,17 +2572,19 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) spin_unlock(&swap_lock); goto out_dput; } - spin_lock(&swap_avail_lock); - plist_del(&p->avail_list, &swap_avail_head); - spin_unlock(&swap_avail_lock); + del_from_avail_list(p); spin_lock(&p->lock); if (p->prio < 0) { struct swap_info_struct *si = p; + int nid; plist_for_each_entry_continue(si, &swap_active_head, list) { si->prio++; si->list.prio--; - si->avail_list.prio--; + for_each_node(nid) { + if (si->avail_lists[nid].prio != 1) + si->avail_lists[nid].prio--; + } } least_priority++; } @@ -2387,6 +2616,9 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) if (p->flags & SWP_CONTINUED) free_swap_count_continuations(p); + if (!p->bdev || !blk_queue_nonrot(bdev_get_queue(p->bdev))) + atomic_dec(&nr_rotate_swap); + mutex_lock(&swapon_mutex); spin_lock(&swap_lock); spin_lock(&p->lock); @@ -2596,6 +2828,7 @@ static struct swap_info_struct *alloc_swap_info(void) { struct swap_info_struct *p; unsigned int type; + int i; p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) @@ -2631,7 +2864,8 @@ static struct swap_info_struct *alloc_swap_info(void) } INIT_LIST_HEAD(&p->first_swap_extent.list); plist_node_init(&p->list, 0); - plist_node_init(&p->avail_list, 0); + for_each_node(i) + plist_node_init(&p->avail_lists[i], 0); p->flags = SWP_USED; spin_unlock(&swap_lock); spin_lock_init(&p->lock); @@ -2873,6 +3107,9 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) if (!capable(CAP_SYS_ADMIN)) return -EPERM; + if (!swap_avail_heads) + return -ENOMEM; + p = alloc_swap_info(); if (IS_ERR(p)) return PTR_ERR(p); @@ -2963,7 +3200,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) cluster = per_cpu_ptr(p->percpu_cluster, cpu); cluster_set_null(&cluster->index); } - } + } else + atomic_inc(&nr_rotate_swap); error = swap_cgroup_swapon(p->type, maxpages); if (error) @@ -3052,7 +3290,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) p->flags = 0; spin_unlock(&swap_lock); vfree(swap_map); - vfree(cluster_info); + kvfree(cluster_info); + kvfree(frontswap_map); if (swap_file) { if (inode && S_ISREG(inode->i_mode)) { inode_unlock(inode); @@ -3457,3 +3696,21 @@ static void free_swap_count_continuations(struct swap_info_struct *si) } } } + +static int __init swapfile_init(void) +{ + int nid; + + swap_avail_heads = kmalloc_array(nr_node_ids, sizeof(struct plist_head), + GFP_KERNEL); + if (!swap_avail_heads) { + pr_emerg("Not enough memory for swap heads, swap is disabled\n"); + return -ENOMEM; + } + + for_each_node(nid) + plist_head_init(&swap_avail_heads[nid]); + + return 0; +} +subsys_initcall(swapfile_init); diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 8bcb501bce60b84f8bbc3c79cb2790bae2daa86a..81192701964d36d609d015ce76cf14dbbb1a0dd9 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -371,6 +371,36 @@ extern ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, bool zeropage); #endif /* CONFIG_HUGETLB_PAGE */ +static __always_inline ssize_t mfill_atomic_pte(struct mm_struct *dst_mm, + pmd_t *dst_pmd, + struct vm_area_struct *dst_vma, + unsigned long dst_addr, + unsigned long src_addr, + struct page **page, + bool zeropage) +{ + ssize_t err; + + if (vma_is_anonymous(dst_vma)) { + if (!zeropage) + err = mcopy_atomic_pte(dst_mm, dst_pmd, dst_vma, + dst_addr, src_addr, page); + else + err = mfill_zeropage_pte(dst_mm, dst_pmd, + dst_vma, dst_addr); + } else { + if (!zeropage) + err = shmem_mcopy_atomic_pte(dst_mm, dst_pmd, + dst_vma, dst_addr, + src_addr, page); + else + err = shmem_mfill_zeropage_pte(dst_mm, dst_pmd, + dst_vma, dst_addr); + } + + return err; +} + static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start, unsigned long src_start, @@ -487,22 +517,8 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm, BUG_ON(pmd_none(*dst_pmd)); BUG_ON(pmd_trans_huge(*dst_pmd)); - if (vma_is_anonymous(dst_vma)) { - if (!zeropage) - err = mcopy_atomic_pte(dst_mm, dst_pmd, dst_vma, - dst_addr, src_addr, - &page); - else - err = mfill_zeropage_pte(dst_mm, dst_pmd, - dst_vma, dst_addr); - } else { - err = -EINVAL; /* if zeropage is true return -EINVAL */ - if (likely(!zeropage)) - err = shmem_mcopy_atomic_pte(dst_mm, dst_pmd, - dst_vma, dst_addr, - src_addr, &page); - } - + err = mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, dst_addr, + src_addr, &page, zeropage); cond_resched(); if (unlikely(err == -EFAULT)) { diff --git a/mm/util.c b/mm/util.c index 7b07ec852e01fa931b2b302e8df5cff9f17f62d6..34e57fae959decc1edf0805ca5bf40b1ef40d8de 100644 --- a/mm/util.c +++ b/mm/util.c @@ -614,7 +614,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) return 0; if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { - free = global_page_state(NR_FREE_PAGES); + free = global_zone_page_state(NR_FREE_PAGES); free += global_node_page_state(NR_FILE_PAGES); /* @@ -633,7 +633,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) * which are reclaimable, under pressure. The dentry * cache and most inode caches should fall into this */ - free += global_page_state(NR_SLAB_RECLAIMABLE); + free += global_node_page_state(NR_SLAB_RECLAIMABLE); /* * Leave reserved pages. The pages are not for anonymous pages. diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 8698c1c86c4dbed685269eae1ecded2f5e714368..8a43db6284ebcb9c40dfc3532d454c783ea61412 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -49,12 +49,10 @@ static void __vunmap(const void *, int); static void free_work(struct work_struct *w) { struct vfree_deferred *p = container_of(w, struct vfree_deferred, wq); - struct llist_node *llnode = llist_del_all(&p->list); - while (llnode) { - void *p = llnode; - llnode = llist_next(llnode); - __vunmap(p, 1); - } + struct llist_node *t, *llnode; + + llist_for_each_safe(llnode, t, llist_del_all(&p->list)) + __vunmap((void *)llnode, 1); } /*** Page table manipulation functions ***/ @@ -1671,7 +1669,10 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, struct page **pages; unsigned int nr_pages, array_size, i; const gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO; - const gfp_t alloc_mask = gfp_mask | __GFP_HIGHMEM | __GFP_NOWARN; + const gfp_t alloc_mask = gfp_mask | __GFP_NOWARN; + const gfp_t highmem_mask = (gfp_mask & (GFP_DMA | GFP_DMA32)) ? + 0 : + __GFP_HIGHMEM; nr_pages = get_vm_area_size(area) >> PAGE_SHIFT; array_size = (nr_pages * sizeof(struct page *)); @@ -1679,7 +1680,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, area->nr_pages = nr_pages; /* Please note that the recursion is strictly bounded. */ if (array_size > PAGE_SIZE) { - pages = __vmalloc_node(array_size, 1, nested_gfp|__GFP_HIGHMEM, + pages = __vmalloc_node(array_size, 1, nested_gfp|highmem_mask, PAGE_KERNEL, node, area->caller); } else { pages = kmalloc_node(array_size, nested_gfp, node); @@ -1700,9 +1701,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, } if (node == NUMA_NO_NODE) - page = alloc_page(alloc_mask); + page = alloc_page(alloc_mask|highmem_mask); else - page = alloc_pages_node(node, alloc_mask, 0); + page = alloc_pages_node(node, alloc_mask|highmem_mask, 0); if (unlikely(!page)) { /* Successfully allocated i pages, free them in __vunmap() */ @@ -1710,7 +1711,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, goto fail; } area->pages[i] = page; - if (gfpflags_allow_blocking(gfp_mask)) + if (gfpflags_allow_blocking(gfp_mask|highmem_mask)) cond_resched(); } @@ -2479,7 +2480,7 @@ static unsigned long pvm_determine_end(struct vmap_area **pnext, * matching slot. While scanning, if any of the areas overlaps with * existing vmap_area, the base address is pulled down to fit the * area. Scanning is repeated till all the areas fit and then all - * necessary data structres are inserted and the result is returned. + * necessary data structures are inserted and the result is returned. */ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, const size_t *sizes, int nr_vms, @@ -2507,15 +2508,11 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, if (start > offsets[last_area]) last_area = area; - for (area2 = 0; area2 < nr_vms; area2++) { + for (area2 = area + 1; area2 < nr_vms; area2++) { unsigned long start2 = offsets[area2]; unsigned long end2 = start2 + sizes[area2]; - if (area2 == area) - continue; - - BUG_ON(start2 >= start && start2 < end); - BUG_ON(end2 <= end && end2 > start); + BUG_ON(start2 < end && start < end2); } } last_end = offsets[last_area] + sizes[last_area]; diff --git a/mm/vmscan.c b/mm/vmscan.c index a1af041930a6b0a4ff3646cde896af327ce503a3..13d711dd87766a71a653c2c9e3efcba80fef3314 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -393,14 +393,15 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, unsigned long nr_to_scan = min(batch_size, total_scan); shrinkctl->nr_to_scan = nr_to_scan; + shrinkctl->nr_scanned = nr_to_scan; ret = shrinker->scan_objects(shrinker, shrinkctl); if (ret == SHRINK_STOP) break; freed += ret; - count_vm_events(SLABS_SCANNED, nr_to_scan); - total_scan -= nr_to_scan; - scanned += nr_to_scan; + count_vm_events(SLABS_SCANNED, shrinkctl->nr_scanned); + total_scan -= shrinkctl->nr_scanned; + scanned += shrinkctl->nr_scanned; cond_resched(); } @@ -535,7 +536,9 @@ static inline int is_page_cache_freeable(struct page *page) * that isolated the page, the page cache radix tree and * optional buffer heads at page->private. */ - return page_count(page) - page_has_private(page) == 2; + int radix_pins = PageTransHuge(page) && PageSwapCache(page) ? + HPAGE_PMD_NR : 1; + return page_count(page) - page_has_private(page) == 1 + radix_pins; } static int may_write_to_inode(struct inode *inode, struct scan_control *sc) @@ -665,6 +668,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page, bool reclaimed) { unsigned long flags; + int refcount; BUG_ON(!PageLocked(page)); BUG_ON(mapping != page_mapping(page)); @@ -695,11 +699,15 @@ static int __remove_mapping(struct address_space *mapping, struct page *page, * Note that if SetPageDirty is always performed via set_page_dirty, * and thus under tree_lock, then this ordering is not required. */ - if (!page_ref_freeze(page, 2)) + if (unlikely(PageTransHuge(page)) && PageSwapCache(page)) + refcount = 1 + HPAGE_PMD_NR; + else + refcount = 2; + if (!page_ref_freeze(page, refcount)) goto cannot_free; /* note: atomic_cmpxchg in page_freeze_refs provides the smp_rmb */ if (unlikely(PageDirty(page))) { - page_ref_unfreeze(page, 2); + page_ref_unfreeze(page, refcount); goto cannot_free; } @@ -1121,58 +1129,59 @@ static unsigned long shrink_page_list(struct list_head *page_list, * Try to allocate it some swap space here. * Lazyfree page could be freed directly */ - if (PageAnon(page) && PageSwapBacked(page) && - !PageSwapCache(page)) { - if (!(sc->gfp_mask & __GFP_IO)) - goto keep_locked; - if (PageTransHuge(page)) { - /* cannot split THP, skip it */ - if (!can_split_huge_page(page, NULL)) - goto activate_locked; - /* - * Split pages without a PMD map right - * away. Chances are some or all of the - * tail pages can be freed without IO. - */ - if (!compound_mapcount(page) && - split_huge_page_to_list(page, page_list)) - goto activate_locked; - } - if (!add_to_swap(page)) { - if (!PageTransHuge(page)) - goto activate_locked; - /* Split THP and swap individual base pages */ - if (split_huge_page_to_list(page, page_list)) - goto activate_locked; - if (!add_to_swap(page)) - goto activate_locked; - } - - /* XXX: We don't support THP writes */ - if (PageTransHuge(page) && - split_huge_page_to_list(page, page_list)) { - delete_from_swap_cache(page); - goto activate_locked; - } + if (PageAnon(page) && PageSwapBacked(page)) { + if (!PageSwapCache(page)) { + if (!(sc->gfp_mask & __GFP_IO)) + goto keep_locked; + if (PageTransHuge(page)) { + /* cannot split THP, skip it */ + if (!can_split_huge_page(page, NULL)) + goto activate_locked; + /* + * Split pages without a PMD map right + * away. Chances are some or all of the + * tail pages can be freed without IO. + */ + if (!compound_mapcount(page) && + split_huge_page_to_list(page, + page_list)) + goto activate_locked; + } + if (!add_to_swap(page)) { + if (!PageTransHuge(page)) + goto activate_locked; + /* Fallback to swap normal pages */ + if (split_huge_page_to_list(page, + page_list)) + goto activate_locked; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + count_vm_event(THP_SWPOUT_FALLBACK); +#endif + if (!add_to_swap(page)) + goto activate_locked; + } - may_enter_fs = 1; + may_enter_fs = 1; - /* Adding to swap updated mapping */ - mapping = page_mapping(page); + /* Adding to swap updated mapping */ + mapping = page_mapping(page); + } } else if (unlikely(PageTransHuge(page))) { /* Split file THP */ if (split_huge_page_to_list(page, page_list)) goto keep_locked; } - VM_BUG_ON_PAGE(PageTransHuge(page), page); - /* * The page is mapped into the page tables of one or more * processes. Try to unmap it here. */ if (page_mapped(page)) { - if (!try_to_unmap(page, ttu_flags | TTU_BATCH_FLUSH)) { + enum ttu_flags flags = ttu_flags | TTU_BATCH_FLUSH; + + if (unlikely(PageTransHuge(page))) + flags |= TTU_SPLIT_HUGE_PMD; + if (!try_to_unmap(page, flags)) { nr_unmap_fail++; goto activate_locked; } @@ -1312,7 +1321,11 @@ static unsigned long shrink_page_list(struct list_head *page_list, * Is there need to periodically free_page_list? It would * appear not as the counts should be low */ - list_add(&page->lru, &free_pages); + if (unlikely(PageTransHuge(page))) { + mem_cgroup_uncharge(page); + (*get_compound_page_dtor(page))(page); + } else + list_add(&page->lru, &free_pages); continue; activate_locked: @@ -1742,9 +1755,15 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, int file = is_file_lru(lru); struct pglist_data *pgdat = lruvec_pgdat(lruvec); struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat; + bool stalled = false; while (unlikely(too_many_isolated(pgdat, file, sc))) { - congestion_wait(BLK_RW_ASYNC, HZ/10); + if (stalled) + return 0; + + /* wait a bit for the reclaimer. */ + msleep(100); + stalled = true; /* We are about to die and free our memory. Return now. */ if (fatal_signal_pending(current)) @@ -3525,8 +3544,6 @@ static int kswapd(void *p) }; const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id); - lockdep_set_current_reclaim_state(GFP_KERNEL); - if (!cpumask_empty(cpumask)) set_cpus_allowed_ptr(tsk, cpumask); current->reclaim_state = &reclaim_state; @@ -3585,14 +3602,15 @@ static int kswapd(void *p) */ trace_mm_vmscan_kswapd_wake(pgdat->node_id, classzone_idx, alloc_order); + fs_reclaim_acquire(GFP_KERNEL); reclaim_order = balance_pgdat(pgdat, alloc_order, classzone_idx); + fs_reclaim_release(GFP_KERNEL); if (reclaim_order < alloc_order) goto kswapd_try_sleep; } tsk->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD); current->reclaim_state = NULL; - lockdep_clear_current_reclaim_state(); return 0; } @@ -3655,14 +3673,14 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim) unsigned int noreclaim_flag; noreclaim_flag = memalloc_noreclaim_save(); - lockdep_set_current_reclaim_state(sc.gfp_mask); + fs_reclaim_acquire(sc.gfp_mask); reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; nr_reclaimed = do_try_to_free_pages(zonelist, &sc); p->reclaim_state = NULL; - lockdep_clear_current_reclaim_state(); + fs_reclaim_release(sc.gfp_mask); memalloc_noreclaim_restore(noreclaim_flag); return nr_reclaimed; @@ -3847,7 +3865,7 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in */ noreclaim_flag = memalloc_noreclaim_save(); p->flags |= PF_SWAPWRITE; - lockdep_set_current_reclaim_state(sc.gfp_mask); + fs_reclaim_acquire(sc.gfp_mask); reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; @@ -3862,9 +3880,9 @@ static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned in } p->reclaim_state = NULL; + fs_reclaim_release(gfp_mask); current->flags &= ~PF_SWAPWRITE; memalloc_noreclaim_restore(noreclaim_flag); - lockdep_clear_current_reclaim_state(); return sc.nr_reclaimed >= nr_pages; } diff --git a/mm/vmstat.c b/mm/vmstat.c index 9a4441bbeef26d7bf39fe8bb9148a7e8a4ef5632..4bb13e72ac97c58e98cc77227a5107cd2c34c471 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -30,6 +30,8 @@ #include "internal.h" +#define NUMA_STATS_THRESHOLD (U16_MAX - 2) + #ifdef CONFIG_VM_EVENT_COUNTERS DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}}; EXPORT_PER_CPU_SYMBOL(vm_event_states); @@ -87,8 +89,10 @@ void vm_events_fold_cpu(int cpu) * vm_stat contains the global counters */ atomic_long_t vm_zone_stat[NR_VM_ZONE_STAT_ITEMS] __cacheline_aligned_in_smp; +atomic_long_t vm_numa_stat[NR_VM_NUMA_STAT_ITEMS] __cacheline_aligned_in_smp; atomic_long_t vm_node_stat[NR_VM_NODE_STAT_ITEMS] __cacheline_aligned_in_smp; EXPORT_SYMBOL(vm_zone_stat); +EXPORT_SYMBOL(vm_numa_stat); EXPORT_SYMBOL(vm_node_stat); #ifdef CONFIG_SMP @@ -604,6 +608,32 @@ EXPORT_SYMBOL(dec_node_page_state); * Fold a differential into the global counters. * Returns the number of counters updated. */ +#ifdef CONFIG_NUMA +static int fold_diff(int *zone_diff, int *numa_diff, int *node_diff) +{ + int i; + int changes = 0; + + for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) + if (zone_diff[i]) { + atomic_long_add(zone_diff[i], &vm_zone_stat[i]); + changes++; + } + + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) + if (numa_diff[i]) { + atomic_long_add(numa_diff[i], &vm_numa_stat[i]); + changes++; + } + + for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) + if (node_diff[i]) { + atomic_long_add(node_diff[i], &vm_node_stat[i]); + changes++; + } + return changes; +} +#else static int fold_diff(int *zone_diff, int *node_diff) { int i; @@ -622,6 +652,7 @@ static int fold_diff(int *zone_diff, int *node_diff) } return changes; } +#endif /* CONFIG_NUMA */ /* * Update the zone counters for the current cpu. @@ -645,6 +676,9 @@ static int refresh_cpu_vm_stats(bool do_pagesets) struct zone *zone; int i; int global_zone_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, }; +#ifdef CONFIG_NUMA + int global_numa_diff[NR_VM_NUMA_STAT_ITEMS] = { 0, }; +#endif int global_node_diff[NR_VM_NODE_STAT_ITEMS] = { 0, }; int changes = 0; @@ -666,6 +700,18 @@ static int refresh_cpu_vm_stats(bool do_pagesets) } } #ifdef CONFIG_NUMA + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) { + int v; + + v = this_cpu_xchg(p->vm_numa_stat_diff[i], 0); + if (v) { + + atomic_long_add(v, &zone->vm_numa_stat[i]); + global_numa_diff[i] += v; + __this_cpu_write(p->expire, 3); + } + } + if (do_pagesets) { cond_resched(); /* @@ -712,7 +758,12 @@ static int refresh_cpu_vm_stats(bool do_pagesets) } } +#ifdef CONFIG_NUMA + changes += fold_diff(global_zone_diff, global_numa_diff, + global_node_diff); +#else changes += fold_diff(global_zone_diff, global_node_diff); +#endif return changes; } @@ -727,6 +778,9 @@ void cpu_vm_stats_fold(int cpu) struct zone *zone; int i; int global_zone_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, }; +#ifdef CONFIG_NUMA + int global_numa_diff[NR_VM_NUMA_STAT_ITEMS] = { 0, }; +#endif int global_node_diff[NR_VM_NODE_STAT_ITEMS] = { 0, }; for_each_populated_zone(zone) { @@ -743,6 +797,18 @@ void cpu_vm_stats_fold(int cpu) atomic_long_add(v, &zone->vm_stat[i]); global_zone_diff[i] += v; } + +#ifdef CONFIG_NUMA + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) + if (p->vm_numa_stat_diff[i]) { + int v; + + v = p->vm_numa_stat_diff[i]; + p->vm_numa_stat_diff[i] = 0; + atomic_long_add(v, &zone->vm_numa_stat[i]); + global_numa_diff[i] += v; + } +#endif } for_each_online_pgdat(pgdat) { @@ -761,7 +827,11 @@ void cpu_vm_stats_fold(int cpu) } } +#ifdef CONFIG_NUMA + fold_diff(global_zone_diff, global_numa_diff, global_node_diff); +#else fold_diff(global_zone_diff, global_node_diff); +#endif } /* @@ -779,10 +849,36 @@ void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset) atomic_long_add(v, &zone->vm_stat[i]); atomic_long_add(v, &vm_zone_stat[i]); } + +#ifdef CONFIG_NUMA + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) + if (pset->vm_numa_stat_diff[i]) { + int v = pset->vm_numa_stat_diff[i]; + + pset->vm_numa_stat_diff[i] = 0; + atomic_long_add(v, &zone->vm_numa_stat[i]); + atomic_long_add(v, &vm_numa_stat[i]); + } +#endif } #endif #ifdef CONFIG_NUMA +void __inc_numa_state(struct zone *zone, + enum numa_stat_item item) +{ + struct per_cpu_pageset __percpu *pcp = zone->pageset; + u16 __percpu *p = pcp->vm_numa_stat_diff + item; + u16 v; + + v = __this_cpu_inc_return(*p); + + if (unlikely(v > NUMA_STATS_THRESHOLD)) { + zone_numa_state_add(v, zone, item); + __this_cpu_write(*p, 0); + } +} + /* * Determine the per node value of a stat item. This function * is called frequently in a NUMA machine, so try to be as @@ -801,6 +897,23 @@ unsigned long sum_zone_node_page_state(int node, return count; } +/* + * Determine the per node value of a numa stat item. To avoid deviation, + * the per cpu stat number in vm_numa_stat_diff[] is also included. + */ +unsigned long sum_zone_numa_state(int node, + enum numa_stat_item item) +{ + struct zone *zones = NODE_DATA(node)->node_zones; + int i; + unsigned long count = 0; + + for (i = 0; i < MAX_NR_ZONES; i++) + count += zone_numa_state_snapshot(zones + i, item); + + return count; +} + /* * Determine the per node value of a stat item. */ @@ -870,6 +983,9 @@ static int __fragmentation_index(unsigned int order, struct contig_page_info *in { unsigned long requested = 1UL << order; + if (WARN_ON_ONCE(order >= MAX_ORDER)) + return 0; + if (!info->free_blocks_total) return 0; @@ -934,6 +1050,9 @@ const char * const vmstat_text[] = { #if IS_ENABLED(CONFIG_ZSMALLOC) "nr_zspages", #endif + "nr_free_cma", + + /* enum numa_stat_item counters */ #ifdef CONFIG_NUMA "numa_hit", "numa_miss", @@ -942,7 +1061,6 @@ const char * const vmstat_text[] = { "numa_local", "numa_other", #endif - "nr_free_cma", /* Node-based counters */ "nr_inactive_anon", @@ -1071,6 +1189,8 @@ const char * const vmstat_text[] = { #endif "thp_zero_page_alloc", "thp_zero_page_alloc_failed", + "thp_swpout", + "thp_swpout_fallback", #endif #ifdef CONFIG_MEMORY_BALLOON "balloon_inflate", @@ -1093,11 +1213,14 @@ const char * const vmstat_text[] = { "vmacache_find_hits", "vmacache_full_flushes", #endif +#ifdef CONFIG_SWAP + "swap_ra", + "swap_ra_hit", +#endif #endif /* CONFIG_VM_EVENTS_COUNTERS */ }; #endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA */ - #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)) || \ defined(CONFIG_PROC_FS) static void *frag_start(struct seq_file *m, loff_t *pos) @@ -1250,7 +1373,7 @@ static void pagetypeinfo_showblockcount_print(struct seq_file *m, seq_putc(m, '\n'); } -/* Print out the free pages at each order for each migratetype */ +/* Print out the number of pageblocks for each migratetype */ static int pagetypeinfo_showblockcount(struct seq_file *m, void *arg) { int mtype; @@ -1375,7 +1498,8 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, seq_printf(m, "\n per-node stats"); for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) { seq_printf(m, "\n %-12s %lu", - vmstat_text[i + NR_VM_ZONE_STAT_ITEMS], + vmstat_text[i + NR_VM_ZONE_STAT_ITEMS + + NR_VM_NUMA_STAT_ITEMS], node_page_state(pgdat, i)); } } @@ -1412,6 +1536,13 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, seq_printf(m, "\n %-12s %lu", vmstat_text[i], zone_page_state(zone, i)); +#ifdef CONFIG_NUMA + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) + seq_printf(m, "\n %-12s %lu", + vmstat_text[i + NR_VM_ZONE_STAT_ITEMS], + zone_numa_state_snapshot(zone, i)); +#endif + seq_printf(m, "\n pagesets"); for_each_online_cpu(i) { struct per_cpu_pageset *pageset; @@ -1488,6 +1619,7 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos) if (*pos >= ARRAY_SIZE(vmstat_text)) return NULL; stat_items_size = NR_VM_ZONE_STAT_ITEMS * sizeof(unsigned long) + + NR_VM_NUMA_STAT_ITEMS * sizeof(unsigned long) + NR_VM_NODE_STAT_ITEMS * sizeof(unsigned long) + NR_VM_WRITEBACK_STAT_ITEMS * sizeof(unsigned long); @@ -1500,9 +1632,15 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos) if (!v) return ERR_PTR(-ENOMEM); for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) - v[i] = global_page_state(i); + v[i] = global_zone_page_state(i); v += NR_VM_ZONE_STAT_ITEMS; +#ifdef CONFIG_NUMA + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) + v[i] = global_numa_state(i); + v += NR_VM_NUMA_STAT_ITEMS; +#endif + for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) v[i] = global_node_page_state(i); v += NR_VM_NODE_STAT_ITEMS; @@ -1589,7 +1727,7 @@ int vmstat_refresh(struct ctl_table *table, int write, * which can equally be echo'ed to or cat'ted from (by root), * can be used to update the stats just before reading them. * - * Oh, and since global_page_state() etc. are so careful to hide + * Oh, and since global_zone_page_state() etc. are so careful to hide * transiently negative values, report an error here if any of * the stats is negative, so we know to go looking for imbalance. */ @@ -1604,6 +1742,16 @@ int vmstat_refresh(struct ctl_table *table, int write, err = -EINVAL; } } +#ifdef CONFIG_NUMA + for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) { + val = atomic_long_read(&vm_numa_stat[i]); + if (val < 0) { + pr_warn("%s: %s %ld\n", + __func__, vmstat_text[i + NR_VM_ZONE_STAT_ITEMS], val); + err = -EINVAL; + } + } +#endif if (err) return err; if (write) @@ -1645,13 +1793,20 @@ static bool need_update(int cpu) struct per_cpu_pageset *p = per_cpu_ptr(zone->pageset, cpu); BUILD_BUG_ON(sizeof(p->vm_stat_diff[0]) != 1); +#ifdef CONFIG_NUMA + BUILD_BUG_ON(sizeof(p->vm_numa_stat_diff[0]) != 2); +#endif + /* * The fast way of checking if there are any vmstat diffs. * This works because the diffs are byte sized items. */ if (memchr_inv(p->vm_stat_diff, 0, NR_VM_ZONE_STAT_ITEMS)) return true; - +#ifdef CONFIG_NUMA + if (memchr_inv(p->vm_numa_stat_diff, 0, NR_VM_NUMA_STAT_ITEMS)) + return true; +#endif } return false; } diff --git a/mm/z3fold.c b/mm/z3fold.c index 54f63c4a809ae123248200ee84642629c6db8ffc..b2ba2ba585f3c0ccb422531ae9dc26909ae463d4 100644 --- a/mm/z3fold.c +++ b/mm/z3fold.c @@ -23,10 +23,13 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include +#include #include +#include #include #include #include @@ -48,11 +51,15 @@ enum buddy { }; /* - * struct z3fold_header - z3fold page metadata occupying the first chunk of each + * struct z3fold_header - z3fold page metadata occupying first chunks of each * z3fold page, except for HEADLESS pages - * @buddy: links the z3fold page into the relevant list in the pool + * @buddy: links the z3fold page into the relevant list in the + * pool * @page_lock: per-page lock - * @refcount: reference cound for the z3fold page + * @refcount: reference count for the z3fold page + * @work: work_struct for page layout optimization + * @pool: pointer to the pool which this page belongs to + * @cpu: CPU which this page "belongs" to * @first_chunks: the size of the first buddy in chunks, 0 if free * @middle_chunks: the size of the middle buddy in chunks, 0 if free * @last_chunks: the size of the last buddy in chunks, 0 if free @@ -62,6 +69,9 @@ struct z3fold_header { struct list_head buddy; spinlock_t page_lock; struct kref refcount; + struct work_struct work; + struct z3fold_pool *pool; + short cpu; unsigned short first_chunks; unsigned short middle_chunks; unsigned short last_chunks; @@ -92,28 +102,39 @@ struct z3fold_header { /** * struct z3fold_pool - stores metadata for each z3fold pool - * @lock: protects all pool fields and first|last_chunk fields of any - * z3fold page in the pool - * @unbuddied: array of lists tracking z3fold pages that contain 2- buddies; - * the lists each z3fold page is added to depends on the size of - * its free region. + * @name: pool name + * @lock: protects pool unbuddied/lru lists + * @stale_lock: protects pool stale page list + * @unbuddied: per-cpu array of lists tracking z3fold pages that contain 2- + * buddies; the list each z3fold page is added to depends on + * the size of its free region. * @lru: list tracking the z3fold pages in LRU order by most recently * added buddy. + * @stale: list of pages marked for freeing * @pages_nr: number of z3fold pages in the pool. * @ops: pointer to a structure of user defined operations specified at * pool creation time. + * @compact_wq: workqueue for page layout background optimization + * @release_wq: workqueue for safe page release + * @work: work_struct for safe page release * * This structure is allocated at pool creation time and maintains metadata * pertaining to a particular z3fold pool. */ struct z3fold_pool { + const char *name; spinlock_t lock; - struct list_head unbuddied[NCHUNKS]; + spinlock_t stale_lock; + struct list_head *unbuddied; struct list_head lru; + struct list_head stale; atomic64_t pages_nr; const struct z3fold_ops *ops; struct zpool *zpool; const struct zpool_ops *zpool_ops; + struct workqueue_struct *compact_wq; + struct workqueue_struct *release_wq; + struct work_struct work; }; /* @@ -122,9 +143,10 @@ struct z3fold_pool { enum z3fold_page_flags { PAGE_HEADLESS = 0, MIDDLE_CHUNK_MAPPED, + NEEDS_COMPACTING, + PAGE_STALE }; - /***************** * Helpers *****************/ @@ -138,14 +160,19 @@ static int size_to_chunks(size_t size) #define for_each_unbuddied_list(_iter, _begin) \ for ((_iter) = (_begin); (_iter) < NCHUNKS; (_iter)++) +static void compact_page_work(struct work_struct *w); + /* Initializes the z3fold header of a newly allocated z3fold page */ -static struct z3fold_header *init_z3fold_page(struct page *page) +static struct z3fold_header *init_z3fold_page(struct page *page, + struct z3fold_pool *pool) { struct z3fold_header *zhdr = page_address(page); INIT_LIST_HEAD(&page->lru); clear_bit(PAGE_HEADLESS, &page->private); clear_bit(MIDDLE_CHUNK_MAPPED, &page->private); + clear_bit(NEEDS_COMPACTING, &page->private); + clear_bit(PAGE_STALE, &page->private); spin_lock_init(&zhdr->page_lock); kref_init(&zhdr->refcount); @@ -154,7 +181,10 @@ static struct z3fold_header *init_z3fold_page(struct page *page) zhdr->last_chunks = 0; zhdr->first_num = 0; zhdr->start_middle = 0; + zhdr->cpu = -1; + zhdr->pool = pool; INIT_LIST_HEAD(&zhdr->buddy); + INIT_WORK(&zhdr->work, compact_page_work); return zhdr; } @@ -164,21 +194,6 @@ static void free_z3fold_page(struct page *page) __free_page(page); } -static void release_z3fold_page(struct kref *ref) -{ - struct z3fold_header *zhdr; - struct page *page; - - zhdr = container_of(ref, struct z3fold_header, refcount); - page = virt_to_page(zhdr); - - if (!list_empty(&zhdr->buddy)) - list_del(&zhdr->buddy); - if (!list_empty(&page->lru)) - list_del(&page->lru); - free_z3fold_page(page); -} - /* Lock a z3fold page */ static inline void z3fold_page_lock(struct z3fold_header *zhdr) { @@ -228,6 +243,76 @@ static enum buddy handle_to_buddy(unsigned long handle) return (handle - zhdr->first_num) & BUDDY_MASK; } +static void __release_z3fold_page(struct z3fold_header *zhdr, bool locked) +{ + struct page *page = virt_to_page(zhdr); + struct z3fold_pool *pool = zhdr->pool; + + WARN_ON(!list_empty(&zhdr->buddy)); + set_bit(PAGE_STALE, &page->private); + clear_bit(NEEDS_COMPACTING, &page->private); + spin_lock(&pool->lock); + if (!list_empty(&page->lru)) + list_del(&page->lru); + spin_unlock(&pool->lock); + if (locked) + z3fold_page_unlock(zhdr); + spin_lock(&pool->stale_lock); + list_add(&zhdr->buddy, &pool->stale); + queue_work(pool->release_wq, &pool->work); + spin_unlock(&pool->stale_lock); +} + +static void __attribute__((__unused__)) + release_z3fold_page(struct kref *ref) +{ + struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, + refcount); + __release_z3fold_page(zhdr, false); +} + +static void release_z3fold_page_locked(struct kref *ref) +{ + struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, + refcount); + WARN_ON(z3fold_page_trylock(zhdr)); + __release_z3fold_page(zhdr, true); +} + +static void release_z3fold_page_locked_list(struct kref *ref) +{ + struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, + refcount); + spin_lock(&zhdr->pool->lock); + list_del_init(&zhdr->buddy); + spin_unlock(&zhdr->pool->lock); + + WARN_ON(z3fold_page_trylock(zhdr)); + __release_z3fold_page(zhdr, true); +} + +static void free_pages_work(struct work_struct *w) +{ + struct z3fold_pool *pool = container_of(w, struct z3fold_pool, work); + + spin_lock(&pool->stale_lock); + while (!list_empty(&pool->stale)) { + struct z3fold_header *zhdr = list_first_entry(&pool->stale, + struct z3fold_header, buddy); + struct page *page = virt_to_page(zhdr); + + list_del(&zhdr->buddy); + if (WARN_ON(!test_bit(PAGE_STALE, &page->private))) + continue; + spin_unlock(&pool->stale_lock); + cancel_work_sync(&zhdr->work); + free_z3fold_page(page); + cond_resched(); + spin_lock(&pool->stale_lock); + } + spin_unlock(&pool->stale_lock); +} + /* * Returns the number of free chunks in a z3fold page. * NB: can't be used with HEADLESS pages. @@ -252,46 +337,6 @@ static int num_free_chunks(struct z3fold_header *zhdr) return nfree; } -/***************** - * API Functions -*****************/ -/** - * z3fold_create_pool() - create a new z3fold pool - * @gfp: gfp flags when allocating the z3fold pool structure - * @ops: user-defined operations for the z3fold pool - * - * Return: pointer to the new z3fold pool or NULL if the metadata allocation - * failed. - */ -static struct z3fold_pool *z3fold_create_pool(gfp_t gfp, - const struct z3fold_ops *ops) -{ - struct z3fold_pool *pool; - int i; - - pool = kzalloc(sizeof(struct z3fold_pool), gfp); - if (!pool) - return NULL; - spin_lock_init(&pool->lock); - for_each_unbuddied_list(i, 0) - INIT_LIST_HEAD(&pool->unbuddied[i]); - INIT_LIST_HEAD(&pool->lru); - atomic64_set(&pool->pages_nr, 0); - pool->ops = ops; - return pool; -} - -/** - * z3fold_destroy_pool() - destroys an existing z3fold pool - * @pool: the z3fold pool to be destroyed - * - * The pool should be emptied before this function is called. - */ -static void z3fold_destroy_pool(struct z3fold_pool *pool) -{ - kfree(pool); -} - static inline void *mchunk_memmove(struct z3fold_header *zhdr, unsigned short dst_chunk) { @@ -347,6 +392,117 @@ static int z3fold_compact_page(struct z3fold_header *zhdr) return 0; } +static void do_compact_page(struct z3fold_header *zhdr, bool locked) +{ + struct z3fold_pool *pool = zhdr->pool; + struct page *page; + struct list_head *unbuddied; + int fchunks; + + page = virt_to_page(zhdr); + if (locked) + WARN_ON(z3fold_page_trylock(zhdr)); + else + z3fold_page_lock(zhdr); + if (test_bit(PAGE_STALE, &page->private) || + !test_and_clear_bit(NEEDS_COMPACTING, &page->private)) { + z3fold_page_unlock(zhdr); + return; + } + spin_lock(&pool->lock); + list_del_init(&zhdr->buddy); + spin_unlock(&pool->lock); + + z3fold_compact_page(zhdr); + unbuddied = get_cpu_ptr(pool->unbuddied); + fchunks = num_free_chunks(zhdr); + if (fchunks < NCHUNKS && + (!zhdr->first_chunks || !zhdr->middle_chunks || + !zhdr->last_chunks)) { + /* the page's not completely free and it's unbuddied */ + spin_lock(&pool->lock); + list_add(&zhdr->buddy, &unbuddied[fchunks]); + spin_unlock(&pool->lock); + zhdr->cpu = smp_processor_id(); + } + put_cpu_ptr(pool->unbuddied); + z3fold_page_unlock(zhdr); +} + +static void compact_page_work(struct work_struct *w) +{ + struct z3fold_header *zhdr = container_of(w, struct z3fold_header, + work); + + do_compact_page(zhdr, false); +} + + +/* + * API Functions + */ + +/** + * z3fold_create_pool() - create a new z3fold pool + * @name: pool name + * @gfp: gfp flags when allocating the z3fold pool structure + * @ops: user-defined operations for the z3fold pool + * + * Return: pointer to the new z3fold pool or NULL if the metadata allocation + * failed. + */ +static struct z3fold_pool *z3fold_create_pool(const char *name, gfp_t gfp, + const struct z3fold_ops *ops) +{ + struct z3fold_pool *pool = NULL; + int i, cpu; + + pool = kzalloc(sizeof(struct z3fold_pool), gfp); + if (!pool) + goto out; + spin_lock_init(&pool->lock); + spin_lock_init(&pool->stale_lock); + pool->unbuddied = __alloc_percpu(sizeof(struct list_head)*NCHUNKS, 2); + for_each_possible_cpu(cpu) { + struct list_head *unbuddied = + per_cpu_ptr(pool->unbuddied, cpu); + for_each_unbuddied_list(i, 0) + INIT_LIST_HEAD(&unbuddied[i]); + } + INIT_LIST_HEAD(&pool->lru); + INIT_LIST_HEAD(&pool->stale); + atomic64_set(&pool->pages_nr, 0); + pool->name = name; + pool->compact_wq = create_singlethread_workqueue(pool->name); + if (!pool->compact_wq) + goto out; + pool->release_wq = create_singlethread_workqueue(pool->name); + if (!pool->release_wq) + goto out_wq; + INIT_WORK(&pool->work, free_pages_work); + pool->ops = ops; + return pool; + +out_wq: + destroy_workqueue(pool->compact_wq); +out: + kfree(pool); + return NULL; +} + +/** + * z3fold_destroy_pool() - destroys an existing z3fold pool + * @pool: the z3fold pool to be destroyed + * + * The pool should be emptied before this function is called. + */ +static void z3fold_destroy_pool(struct z3fold_pool *pool) +{ + destroy_workqueue(pool->release_wq); + destroy_workqueue(pool->compact_wq); + kfree(pool); +} + /** * z3fold_alloc() - allocates a region of a given size * @pool: z3fold pool from which to allocate @@ -371,8 +527,9 @@ static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, { int chunks = 0, i, freechunks; struct z3fold_header *zhdr = NULL; + struct page *page = NULL; enum buddy bud; - struct page *page; + bool can_sleep = (gfp & __GFP_RECLAIM) == __GFP_RECLAIM; if (!size || (gfp & __GFP_HIGHMEM)) return -EINVAL; @@ -383,23 +540,57 @@ static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED - CHUNK_SIZE) bud = HEADLESS; else { + struct list_head *unbuddied; chunks = size_to_chunks(size); +lookup: /* First, try to find an unbuddied z3fold page. */ - zhdr = NULL; + unbuddied = get_cpu_ptr(pool->unbuddied); for_each_unbuddied_list(i, chunks) { - spin_lock(&pool->lock); - zhdr = list_first_entry_or_null(&pool->unbuddied[i], + struct list_head *l = &unbuddied[i]; + + zhdr = list_first_entry_or_null(READ_ONCE(l), struct z3fold_header, buddy); - if (!zhdr || !z3fold_page_trylock(zhdr)) { - spin_unlock(&pool->lock); + + if (!zhdr) continue; + + /* Re-check under lock. */ + spin_lock(&pool->lock); + l = &unbuddied[i]; + if (unlikely(zhdr != list_first_entry(READ_ONCE(l), + struct z3fold_header, buddy)) || + !z3fold_page_trylock(zhdr)) { + spin_unlock(&pool->lock); + put_cpu_ptr(pool->unbuddied); + goto lookup; } - kref_get(&zhdr->refcount); list_del_init(&zhdr->buddy); + zhdr->cpu = -1; spin_unlock(&pool->lock); page = virt_to_page(zhdr); + if (test_bit(NEEDS_COMPACTING, &page->private)) { + z3fold_page_unlock(zhdr); + zhdr = NULL; + put_cpu_ptr(pool->unbuddied); + if (can_sleep) + cond_resched(); + goto lookup; + } + + /* + * this page could not be removed from its unbuddied + * list while pool lock was held, and then we've taken + * page lock so kref_put could not be called before + * we got here, so it's safe to just call kref_get() + */ + kref_get(&zhdr->refcount); + break; + } + put_cpu_ptr(pool->unbuddied); + + if (zhdr) { if (zhdr->first_chunks == 0) { if (zhdr->middle_chunks != 0 && chunks >= zhdr->start_middle) @@ -411,32 +602,47 @@ static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, else if (zhdr->middle_chunks == 0) bud = MIDDLE; else { - z3fold_page_unlock(zhdr); - spin_lock(&pool->lock); if (kref_put(&zhdr->refcount, - release_z3fold_page)) + release_z3fold_page_locked)) atomic64_dec(&pool->pages_nr); - spin_unlock(&pool->lock); + else + z3fold_page_unlock(zhdr); pr_err("No free chunks in unbuddied\n"); WARN_ON(1); - continue; + goto lookup; } goto found; } bud = FIRST; } - /* Couldn't find unbuddied z3fold page, create new one */ - page = alloc_page(gfp); + spin_lock(&pool->stale_lock); + zhdr = list_first_entry_or_null(&pool->stale, + struct z3fold_header, buddy); + /* + * Before allocating a page, let's see if we can take one from the + * stale pages list. cancel_work_sync() can sleep so we must make + * sure it won't be called in case we're in atomic context. + */ + if (zhdr && (can_sleep || !work_pending(&zhdr->work))) { + list_del(&zhdr->buddy); + spin_unlock(&pool->stale_lock); + if (can_sleep) + cancel_work_sync(&zhdr->work); + page = virt_to_page(zhdr); + } else { + spin_unlock(&pool->stale_lock); + page = alloc_page(gfp); + } + if (!page) return -ENOMEM; atomic64_inc(&pool->pages_nr); - zhdr = init_z3fold_page(page); + zhdr = init_z3fold_page(page, pool); if (bud == HEADLESS) { set_bit(PAGE_HEADLESS, &page->private); - spin_lock(&pool->lock); goto headless; } z3fold_page_lock(zhdr); @@ -451,15 +657,21 @@ static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS; } - spin_lock(&pool->lock); if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0 || zhdr->middle_chunks == 0) { + struct list_head *unbuddied = get_cpu_ptr(pool->unbuddied); + /* Add to unbuddied list */ freechunks = num_free_chunks(zhdr); - list_add(&zhdr->buddy, &pool->unbuddied[freechunks]); + spin_lock(&pool->lock); + list_add(&zhdr->buddy, &unbuddied[freechunks]); + spin_unlock(&pool->lock); + zhdr->cpu = smp_processor_id(); + put_cpu_ptr(pool->unbuddied); } headless: + spin_lock(&pool->lock); /* Add/move z3fold page to beginning of LRU */ if (!list_empty(&page->lru)) list_del(&page->lru); @@ -487,7 +699,6 @@ static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, static void z3fold_free(struct z3fold_pool *pool, unsigned long handle) { struct z3fold_header *zhdr; - int freechunks; struct page *page; enum buddy bud; @@ -526,25 +737,27 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle) spin_unlock(&pool->lock); free_z3fold_page(page); atomic64_dec(&pool->pages_nr); - } else { - if (zhdr->first_chunks != 0 || zhdr->middle_chunks != 0 || - zhdr->last_chunks != 0) { - z3fold_compact_page(zhdr); - /* Add to the unbuddied list */ - spin_lock(&pool->lock); - if (!list_empty(&zhdr->buddy)) - list_del(&zhdr->buddy); - freechunks = num_free_chunks(zhdr); - list_add(&zhdr->buddy, &pool->unbuddied[freechunks]); - spin_unlock(&pool->lock); - } + return; + } + + if (kref_put(&zhdr->refcount, release_z3fold_page_locked_list)) { + atomic64_dec(&pool->pages_nr); + return; + } + if (test_and_set_bit(NEEDS_COMPACTING, &page->private)) { z3fold_page_unlock(zhdr); + return; + } + if (zhdr->cpu < 0 || !cpu_online(zhdr->cpu)) { spin_lock(&pool->lock); - if (kref_put(&zhdr->refcount, release_z3fold_page)) - atomic64_dec(&pool->pages_nr); + list_del_init(&zhdr->buddy); spin_unlock(&pool->lock); + zhdr->cpu = -1; + do_compact_page(zhdr, true); + return; } - + queue_work_on(zhdr->cpu, pool->compact_wq, &zhdr->work); + z3fold_page_unlock(zhdr); } /** @@ -585,9 +798,10 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle) */ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) { - int i, ret = 0, freechunks; - struct z3fold_header *zhdr; - struct page *page; + int i, ret = 0; + struct z3fold_header *zhdr = NULL; + struct page *page = NULL; + struct list_head *pos; unsigned long first_handle = 0, middle_handle = 0, last_handle = 0; spin_lock(&pool->lock); @@ -600,16 +814,24 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) spin_unlock(&pool->lock); return -EINVAL; } - page = list_last_entry(&pool->lru, struct page, lru); + list_for_each_prev(pos, &pool->lru) { + page = list_entry(pos, struct page, lru); + if (test_bit(PAGE_HEADLESS, &page->private)) + /* candidate found */ + break; + + zhdr = page_address(page); + if (!z3fold_page_trylock(zhdr)) + continue; /* can't evict at this point */ + kref_get(&zhdr->refcount); + list_del_init(&zhdr->buddy); + zhdr->cpu = -1; + } + list_del_init(&page->lru); + spin_unlock(&pool->lock); - zhdr = page_address(page); if (!test_bit(PAGE_HEADLESS, &page->private)) { - if (!list_empty(&zhdr->buddy)) - list_del_init(&zhdr->buddy); - kref_get(&zhdr->refcount); - spin_unlock(&pool->lock); - z3fold_page_lock(zhdr); /* * We need encode the handles before unlocking, since * we can race with free that will set @@ -624,11 +846,14 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) middle_handle = encode_handle(zhdr, MIDDLE); if (zhdr->last_chunks) last_handle = encode_handle(zhdr, LAST); + /* + * it's safe to unlock here because we hold a + * reference to this page + */ z3fold_page_unlock(zhdr); } else { first_handle = encode_handle(zhdr, HEADLESS); last_handle = middle_handle = 0; - spin_unlock(&pool->lock); } /* Issue the eviction callback(s) */ @@ -648,34 +873,17 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) goto next; } next: + spin_lock(&pool->lock); if (test_bit(PAGE_HEADLESS, &page->private)) { if (ret == 0) { - free_z3fold_page(page); - return 0; - } else { - spin_lock(&pool->lock); - } - } else { - z3fold_page_lock(zhdr); - if ((zhdr->first_chunks || zhdr->last_chunks || - zhdr->middle_chunks) && - !(zhdr->first_chunks && zhdr->last_chunks && - zhdr->middle_chunks)) { - z3fold_compact_page(zhdr); - /* add to unbuddied list */ - spin_lock(&pool->lock); - freechunks = num_free_chunks(zhdr); - list_add(&zhdr->buddy, - &pool->unbuddied[freechunks]); spin_unlock(&pool->lock); - } - z3fold_page_unlock(zhdr); - spin_lock(&pool->lock); - if (kref_put(&zhdr->refcount, release_z3fold_page)) { - spin_unlock(&pool->lock); - atomic64_dec(&pool->pages_nr); + free_z3fold_page(page); return 0; } + } else if (kref_put(&zhdr->refcount, release_z3fold_page)) { + atomic64_dec(&pool->pages_nr); + spin_unlock(&pool->lock); + return 0; } /* @@ -795,7 +1003,8 @@ static void *z3fold_zpool_create(const char *name, gfp_t gfp, { struct z3fold_pool *pool; - pool = z3fold_create_pool(gfp, zpool_ops ? &z3fold_zpool_ops : NULL); + pool = z3fold_create_pool(name, gfp, + zpool_ops ? &z3fold_zpool_ops : NULL); if (pool) { pool->zpool = zpool; pool->zpool_ops = zpool_ops; diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 013eea76685e1c5fea8a3ee3dcaae37acbbf2395..7c38e850a8fc5ce0c4f64090e9f9ac6ef6de7203 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -551,20 +551,23 @@ static int get_size_class_index(int size) return min_t(int, ZS_SIZE_CLASSES - 1, idx); } +/* type can be of enum type zs_stat_type or fullness_group */ static inline void zs_stat_inc(struct size_class *class, - enum zs_stat_type type, unsigned long cnt) + int type, unsigned long cnt) { class->stats.objs[type] += cnt; } +/* type can be of enum type zs_stat_type or fullness_group */ static inline void zs_stat_dec(struct size_class *class, - enum zs_stat_type type, unsigned long cnt) + int type, unsigned long cnt) { class->stats.objs[type] -= cnt; } +/* type can be of enum type zs_stat_type or fullness_group */ static inline unsigned long zs_stat_get(struct size_class *class, - enum zs_stat_type type) + int type) { return class->stats.objs[type]; } @@ -1969,6 +1972,14 @@ int zs_page_migrate(struct address_space *mapping, struct page *newpage, unsigned int obj_idx; int ret = -EAGAIN; + /* + * We cannot support the _NO_COPY case here, because copy needs to + * happen under the zs lock, which does not work with + * MIGRATE_SYNC_NO_COPY workflow. + */ + if (mode == MIGRATE_SYNC_NO_COPY) + return -EINVAL; + VM_BUG_ON_PAGE(!PageMovable(page), page); VM_BUG_ON_PAGE(!PageIsolated(page), page); @@ -1983,8 +1994,11 @@ int zs_page_migrate(struct address_space *mapping, struct page *newpage, spin_lock(&class->lock); if (!get_zspage_inuse(zspage)) { - ret = -EBUSY; - goto unlock_class; + /* + * Set "offset" to end of the page so that every loops + * skips unnecessary object scanning. + */ + offset = PAGE_SIZE; } pos = offset; @@ -2052,7 +2066,6 @@ int zs_page_migrate(struct address_space *mapping, struct page *newpage, } } kunmap_atomic(s_addr); -unlock_class: spin_unlock(&class->lock); migrate_write_unlock(zspage); @@ -2453,7 +2466,6 @@ void zs_destroy_pool(struct zs_pool *pool) } destroy_cache(pool); - kfree(pool->size_class); kfree(pool->name); kfree(pool); } diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index e2ed69850489bb79a6a055ee3264456a31acee3e..0bc31de9071a2112dbbd622dbb5646a5fe86fd3c 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -21,6 +21,12 @@ bool vlan_do_receive(struct sk_buff **skbp) if (unlikely(!skb)) return false; + if (unlikely(!(vlan_dev->flags & IFF_UP))) { + kfree_skb(skb); + *skbp = NULL; + return false; + } + skb->dev = vlan_dev; if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) { /* Our lower layer thinks this is not local, let's make sure. diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index ddfa86648f957de9eef3d45d8815eb4154b0a7bc..903a190319b94d2c09cce263684017f61d4e6d22 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -272,6 +272,7 @@ static int p9_fd_read(struct p9_client *client, void *v, int len) { int ret; struct p9_trans_fd *ts = NULL; + loff_t pos; if (client && client->status != Disconnected) ts = client->trans; @@ -282,7 +283,8 @@ static int p9_fd_read(struct p9_client *client, void *v, int len) if (!(ts->rd->f_flags & O_NONBLOCK)) p9_debug(P9_DEBUG_ERROR, "blocking read ...\n"); - ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); + pos = ts->rd->f_pos; + ret = kernel_read(ts->rd, v, len, &pos); if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) client->status = Disconnected; return ret; @@ -420,8 +422,7 @@ static void p9_read_work(struct work_struct *work) static int p9_fd_write(struct p9_client *client, void *v, int len) { - int ret; - mm_segment_t oldfs; + ssize_t ret; struct p9_trans_fd *ts = NULL; if (client && client->status != Disconnected) @@ -433,12 +434,7 @@ static int p9_fd_write(struct p9_client *client, void *v, int len) if (!(ts->wr->f_flags & O_NONBLOCK)) p9_debug(P9_DEBUG_ERROR, "blocking write ...\n"); - oldfs = get_fs(); - set_fs(get_ds()); - /* The cast to a user pointer is valid due to the set_fs() */ - ret = vfs_write(ts->wr, (__force void __user *)v, len, &ts->wr->f_pos); - set_fs(oldfs); - + ret = kernel_write(ts->wr, v, len, &ts->wr->f_pos); if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) client->status = Disconnected; return ret; diff --git a/net/Kconfig b/net/Kconfig index 7d57ef34b79cb09af2675217a0fad574c602798b..9dba2715919d7668af369a34ed2d67089b112cd4 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -166,13 +166,6 @@ menuconfig NETFILTER if NETFILTER -config NETFILTER_DEBUG - bool "Network packet filtering debugging" - depends on NETFILTER - help - You can say Y here if you want to get additional messages useful in - debugging the netfilter code. - config NETFILTER_ADVANCED bool "Advanced netfilter configuration" depends on NETFILTER @@ -235,6 +228,7 @@ source "net/openvswitch/Kconfig" source "net/vmw_vsock/Kconfig" source "net/netlink/Kconfig" source "net/mpls/Kconfig" +source "net/nsh/Kconfig" source "net/hsr/Kconfig" source "net/switchdev/Kconfig" source "net/l3mdev/Kconfig" @@ -301,6 +295,18 @@ config BPF_JIT /proc/sys/net/core/bpf_jit_harden (optional) /proc/sys/net/core/bpf_jit_kallsyms (optional) +config BPF_STREAM_PARSER + bool "enable BPF STREAM_PARSER" + depends on BPF_SYSCALL + select STREAM_PARSER + ---help--- + Enabling this allows a stream parser to be used with + BPF_MAP_TYPE_SOCKMAP. + + BPF_MAP_TYPE_SOCKMAP provides a map type to use with network sockets. + It can be used to enforce socket policy, implement socket redirects, + etc. + config NET_FLOW_LIMIT bool depends on RPS @@ -364,7 +370,6 @@ endmenu source "net/ax25/Kconfig" source "net/can/Kconfig" -source "net/irda/Kconfig" source "net/bluetooth/Kconfig" source "net/rxrpc/Kconfig" source "net/kcm/Kconfig" diff --git a/net/Makefile b/net/Makefile index bed80fa398b7f888ae80da7b4e7c15f424be70e2..ae2fe2283d2f728aa93df9ebf0ea46592eb9c757 100644 --- a/net/Makefile +++ b/net/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_NETROM) += netrom/ obj-$(CONFIG_ROSE) += rose/ obj-$(CONFIG_AX25) += ax25/ obj-$(CONFIG_CAN) += can/ -obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_BT) += bluetooth/ obj-$(CONFIG_SUNRPC) += sunrpc/ obj-$(CONFIG_AF_RXRPC) += rxrpc/ @@ -76,6 +75,7 @@ obj-$(CONFIG_NET_IFE) += ife/ obj-$(CONFIG_OPENVSWITCH) += openvswitch/ obj-$(CONFIG_VSOCKETS) += vmw_vsock/ obj-$(CONFIG_MPLS) += mpls/ +obj-$(CONFIG_NET_NSH) += nsh/ obj-$(CONFIG_HSR) += hsr/ ifneq ($(CONFIG_NET_SWITCHDEV),) obj-y += switchdev/ diff --git a/net/atm/clip.c b/net/atm/clip.c index f271a7bcf5b2e63702ba159cb44cfef2b730dba6..65f706e4344c39f47dc27c4f2b12d742c1dd0547 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -617,7 +617,7 @@ static void atmarpd_close(struct atm_vcc *vcc) module_put(THIS_MODULE); } -static struct atmdev_ops atmarpd_dev_ops = { +static const struct atmdev_ops atmarpd_dev_ops = { .close = atmarpd_close }; diff --git a/net/atm/lec.c b/net/atm/lec.c index 093fe87077312b3174f8f105e7b0efdfe3679add..a3d93a1bb133e338f944e60e57a532fbae57aedb 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -486,7 +486,7 @@ static void lec_atm_close(struct atm_vcc *vcc) module_put(THIS_MODULE); } -static struct atmdev_ops lecdev_ops = { +static const struct atmdev_ops lecdev_ops = { .close = lec_atm_close, .send = lec_atm_send }; diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 680a4b9095a14dcf7eabb235300a19082746f7b6..5677147209e8181ce2e9eff308bc0ed82b548e45 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -779,7 +779,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb) netif_rx(new_skb); } -static struct atmdev_ops mpc_ops = { /* only send is required */ +static const struct atmdev_ops mpc_ops = { /* only send is required */ .close = mpoad_close, .send = msg_from_mpoad }; diff --git a/net/atm/signaling.c b/net/atm/signaling.c index 983c3a21a13316a9eeafa29fc3ba53dfffe97c81..0a20f6e953ac94136a3cbd5995ca6ea061ec5959 100644 --- a/net/atm/signaling.c +++ b/net/atm/signaling.c @@ -217,7 +217,7 @@ static void sigd_close(struct atm_vcc *vcc) read_unlock(&vcc_sklist_lock); } -static struct atmdev_ops sigd_dev_ops = { +static const struct atmdev_ops sigd_dev_ops = { .close = sigd_close, .send = sigd_send }; diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index a3501173e200d8713bb43d48e8e9a6bb2576835b..83ba5483455a334dc559626c8e1682fe9f357fa7 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -729,11 +729,9 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr, const unsigned char *packet_buff, int packet_len, bool direct_link) { - unsigned char *skb_buff; unsigned long new_direct_link_flag; - skb_buff = skb_put_data(forw_packet_aggr->skb, packet_buff, - packet_len); + skb_put_data(forw_packet_aggr->skb, packet_buff, packet_len); forw_packet_aggr->packet_len += packet_len; forw_packet_aggr->num_packets++; @@ -1281,7 +1279,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, batadv_ogm_packet->tq = combined_tq; batadv_dbg(BATADV_DBG_BATMAN, bat_priv, - "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n", + "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n", orig_node->orig, orig_neigh_node->orig, total_count, neigh_rq_count, tq_own, tq_asym_penalty, tq_iface_penalty, batadv_ogm_packet->tq, if_incoming->net_dev->name, diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index 1e3dc374bfde960bde0731ad1acc26fc2cbe482d..8be61734fc43c6b2be61a8b987eb48a4cafee815 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -137,7 +137,7 @@ static void batadv_v_ogm_send(struct work_struct *work) struct batadv_priv *bat_priv; struct batadv_ogm2_packet *ogm_packet; struct sk_buff *skb, *skb_tmp; - unsigned char *ogm_buff, *pkt_buff; + unsigned char *ogm_buff; int ogm_buff_len; u16 tvlv_len = 0; int ret; @@ -166,7 +166,7 @@ static void batadv_v_ogm_send(struct work_struct *work) goto reschedule; skb_reserve(skb, ETH_HLEN); - pkt_buff = skb_put_data(skb, ogm_buff, ogm_buff_len); + skb_put_data(skb, ogm_buff, ogm_buff_len); ogm_packet = (struct batadv_ogm2_packet *)skb->data; ogm_packet->seqno = htonl(atomic_read(&bat_priv->bat_v.ogm_seqno)); @@ -200,7 +200,7 @@ static void batadv_v_ogm_send(struct work_struct *work) type = "unknown"; } - batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 from ourselve on %s surpressed: %s\n", + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 from ourselves on %s suppressed: %s\n", hard_iface->net_dev->name, type); batadv_hardif_put(hard_iface); @@ -683,18 +683,18 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, ogm_throughput = ntohl(ogm_packet->throughput); batadv_dbg(BATADV_DBG_BATMAN, bat_priv, - "Received OGM2 packet via NB: %pM, IF: %s [%pM] (from OG: %pM, seqno %u, troughput %u, TTL %u, V %u, tvlv_len %u)\n", + "Received OGM2 packet via NB: %pM, IF: %s [%pM] (from OG: %pM, seqno %u, throughput %u, TTL %u, V %u, tvlv_len %u)\n", ethhdr->h_source, if_incoming->net_dev->name, if_incoming->net_dev->dev_addr, ogm_packet->orig, ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl, ogm_packet->version, ntohs(ogm_packet->tvlv_len)); - /* If the troughput metric is 0, immediately drop the packet. No need to - * create orig_node / neigh_node for an unusable route. + /* If the throughput metric is 0, immediately drop the packet. No need + * to create orig_node / neigh_node for an unusable route. */ if (ogm_throughput == 0) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, - "Drop packet: originator packet with troughput metric of 0\n"); + "Drop packet: originator packet with throughput metric of 0\n"); return; } @@ -762,7 +762,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, type = "unknown"; } - batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 packet from %pM on %s surpressed: %s\n", + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 packet from %pM on %s suppressed: %s\n", ogm_packet->orig, hard_iface->net_dev->name, type); diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 6930d6b50f99128b993554b30d1d283da34af957..b6cfa78e9381f5dca63e7a4a8d05f136d823c4db 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -834,7 +834,7 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset) last_seen_msecs = last_seen_msecs % 60000; last_seen_secs = last_seen_msecs / 1000; - seq_printf(seq, " * %15pI4 %14pM %4i %6i:%02i\n", + seq_printf(seq, " * %15pI4 %pM %4i %6i:%02i\n", &dat_entry->ip, dat_entry->mac_addr, batadv_print_vid(dat_entry->vid), last_seen_mins, last_seen_secs); diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 2be8f1f4652958f7c90ee0237f9df986a87beb30..05cc7637c0642df80a46926ee2f845789f056c10 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -24,7 +24,7 @@ #define BATADV_DRIVER_DEVICE "batman-adv" #ifndef BATADV_SOURCE_VERSION -#define BATADV_SOURCE_VERSION "2017.2" +#define BATADV_SOURCE_VERSION "2017.3" #endif /* B.A.T.M.A.N. parameters */ diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index d239a9d72ac365d5bfb6916addd0d39cdab55423..054a65e6eb68b3b65417cb02c9b4bfecf65e7646 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -911,7 +911,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) type = "unknown"; } - batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "BCAST packet from orig %pM on %s surpressed: %s\n", + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "BCAST packet from orig %pM on %s suppressed: %s\n", bcast_packet->orig, hard_iface->net_dev->name, type); diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index e1133bc634b5e8ed9a4639677e577a0d52e7c1d5..8a3ce79b1307b7f260ce2f64e96bdacfb9a322f0 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1549,9 +1549,41 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, return found; } +/** + * batadv_tt_global_sync_flags - update TT sync flags + * @tt_global: the TT global entry to update sync flags in + * + * Updates the sync flag bits in the tt_global flag attribute with a logical + * OR of all sync flags from any of its TT orig entries. + */ +static void +batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global) +{ + struct batadv_tt_orig_list_entry *orig_entry; + const struct hlist_head *head; + u16 flags = BATADV_NO_FLAGS; + + rcu_read_lock(); + head = &tt_global->orig_list; + hlist_for_each_entry_rcu(orig_entry, head, list) + flags |= orig_entry->flags; + rcu_read_unlock(); + + flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); + tt_global->common.flags = flags; +} + +/** + * batadv_tt_global_orig_entry_add - add or update a TT orig entry + * @tt_global: the TT global entry to add an orig entry in + * @orig_node: the originator to add an orig entry for + * @ttvn: translation table version number of this changeset + * @flags: TT sync flags + */ static void batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, - struct batadv_orig_node *orig_node, int ttvn) + struct batadv_orig_node *orig_node, int ttvn, + u8 flags) { struct batadv_tt_orig_list_entry *orig_entry; @@ -1561,7 +1593,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, * was added during a "temporary client detection" */ orig_entry->ttvn = ttvn; - goto out; + orig_entry->flags = flags; + goto sync_flags; } orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC); @@ -1573,6 +1606,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, batadv_tt_global_size_inc(orig_node, tt_global->common.vid); orig_entry->orig_node = orig_node; orig_entry->ttvn = ttvn; + orig_entry->flags = flags; kref_init(&orig_entry->refcount); spin_lock_bh(&tt_global->list_lock); @@ -1582,6 +1616,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, spin_unlock_bh(&tt_global->list_lock); atomic_inc(&tt_global->orig_list_count); +sync_flags: + batadv_tt_global_sync_flags(tt_global); out: if (orig_entry) batadv_tt_orig_list_entry_put(orig_entry); @@ -1703,10 +1739,10 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, } /* the change can carry possible "attribute" flags like the - * TT_CLIENT_WIFI, therefore they have to be copied in the + * TT_CLIENT_TEMP, therefore they have to be copied in the * client entry */ - common->flags |= flags; + common->flags |= flags & (~BATADV_TT_SYNC_MASK); /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a @@ -1723,7 +1759,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, } add_orig_entry: /* add the new orig_entry (if needed) or update it */ - batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); + batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn, + flags & BATADV_TT_SYNC_MASK); batadv_dbg(BATADV_DBG_TT, bat_priv, "Creating new global tt entry: %pM (vid: %d, via %pM)\n", @@ -1946,6 +1983,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, struct batadv_tt_orig_list_entry *orig, bool best) { + u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; void *hdr; struct batadv_orig_node_vlan *vlan; u8 last_ttvn; @@ -1975,7 +2013,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) || nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) || nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || - nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) + nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags)) goto nla_put_failure; if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) @@ -2589,6 +2627,7 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, unsigned short vid) { struct batadv_hashtable *hash = bat_priv->tt.global_hash; + struct batadv_tt_orig_list_entry *tt_orig; struct batadv_tt_common_entry *tt_common; struct batadv_tt_global_entry *tt_global; struct hlist_head *head; @@ -2627,8 +2666,9 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, /* find out if this global entry is announced by this * originator */ - if (!batadv_tt_global_entry_has_orig(tt_global, - orig_node)) + tt_orig = batadv_tt_global_orig_entry_find(tt_global, + orig_node); + if (!tt_orig) continue; /* use network order to read the VID: this ensures that @@ -2640,10 +2680,12 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, /* compute the CRC on flags that have to be kept in sync * among nodes */ - flags = tt_common->flags & BATADV_TT_SYNC_MASK; + flags = tt_orig->flags; crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags)); crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); + + batadv_tt_orig_list_entry_put(tt_orig); } rcu_read_unlock(); } diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index ea43a64492479809fe6bdf95b436792078f50e9f..a62795868794103d7e712ba91def5997dc3a5779 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1260,6 +1260,7 @@ struct batadv_tt_global_entry { * struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client * @orig_node: pointer to orig node announcing this non-mesh client * @ttvn: translation table version number which added the non-mesh client + * @flags: per orig entry TT sync flags * @list: list node for batadv_tt_global_entry::orig_list * @refcount: number of contexts the object is used * @rcu: struct used for freeing in an RCU-safe manner @@ -1267,6 +1268,7 @@ struct batadv_tt_global_entry { struct batadv_tt_orig_list_entry { struct batadv_orig_node *orig_node; u8 ttvn; + u8 flags; struct hlist_node list; struct kref refcount; struct rcu_head rcu; diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index ab3b654b05cc87e19a965d0419efb7d45bd4b94e..4e2576fc0c59932cbb1f3c98c150764b91bb52c1 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -273,9 +273,6 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, struct lowpan_peer *peer) { const u8 *saddr; - struct lowpan_btle_dev *dev; - - dev = lowpan_btle_dev(netdev); saddr = peer->lladdr; @@ -618,12 +615,8 @@ static void ifup(struct net_device *netdev) static void ifdown(struct net_device *netdev) { - int err; - rtnl_lock(); - err = dev_close(netdev); - if (err < 0) - BT_INFO("iface %s cannot be closed (%d)", netdev->name, err); + dev_close(netdev); rtnl_unlock(); } diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 68f951b3e85aa725485bef77de63f162f0241d97..db82a40875e8da3c9ad39881046d27bd8f0ee596 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -45,6 +45,11 @@ config BT_BREDR bool "Bluetooth Classic (BR/EDR) features" depends on BT default y + help + Bluetooth Classic includes support for Basic Rate (BR) + available with Bluetooth version 1.0b or later and support + for Enhanced Data Rate (EDR) available with Bluetooth + version 2.0 or later. source "net/bluetooth/rfcomm/Kconfig" @@ -58,11 +63,18 @@ config BT_HS bool "Bluetooth High Speed (HS) features" depends on BT_BREDR default y + help + Bluetooth High Speed includes support for off-loading + Bluetooth connections via 802.11 (wifi) physical layer + available with Bluetooth version 3.0 or later. config BT_LE bool "Bluetooth Low Energy (LE) features" depends on BT default y + help + Bluetooth Low Energy includes support low-energy physical + layer available with Bluetooth version 4.0 or later. config BT_6LOWPAN tristate "Bluetooth 6LoWPAN support" diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index ca7a35ebaefb61095f278106adc8d5529a247d31..aa300f3a0d51bda11c13766abbc536e33f2e0a2d 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -13,7 +13,7 @@ static void bt_link_release(struct device *dev) kfree(conn); } -static struct device_type bt_link = { +static const struct device_type bt_link = { .name = "link", .release = bt_link_release, }; @@ -86,7 +86,7 @@ static void bt_host_release(struct device *dev) module_put(THIS_MODULE); } -static struct device_type bt_host = { +static const struct device_type bt_host = { .name = "host", .release = bt_host_release, }; diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 002743ea509c2035f78212097bb00af2b0392d1c..8112893037bdc0afee1247dad7ac6433ac0168bb 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -734,7 +734,7 @@ static void hidp_stop(struct hid_device *hid) hid->claimed = 0; } -static struct hid_ll_driver hidp_hid_driver = { +struct hid_ll_driver hidp_hid_driver = { .parse = hidp_parse, .start = hidp_start, .stop = hidp_stop, @@ -743,6 +743,7 @@ static struct hid_ll_driver hidp_hid_driver = { .raw_request = hidp_raw_request, .output_report = hidp_output_report, }; +EXPORT_SYMBOL_GPL(hidp_hid_driver); /* This function sets up the hid device. It does not add it to the HID system. That is done in hidp_add_connection(). */ diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 303c779bfe38ea9e88b5415d7a3f904a520140d9..43ba91c440bcd65bd9f24258a28d01492cf6ac13 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -58,7 +58,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, u8 ident, u16 dlen, void *data); static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); -static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size); static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, @@ -1473,7 +1473,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } @@ -2987,12 +2987,15 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, return len; } -static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) +static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size) { struct l2cap_conf_opt *opt = *ptr; BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val); + if (size < L2CAP_CONF_OPT_SIZE + len) + return; + opt->type = type; opt->len = len; @@ -3017,7 +3020,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) *ptr += L2CAP_CONF_OPT_SIZE + len; } -static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) +static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size) { struct l2cap_conf_efs efs; @@ -3045,7 +3048,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) } l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, size); } static void l2cap_ack_timeout(struct work_struct *work) @@ -3191,11 +3194,12 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan) chan->ack_win = chan->tx_win; } -static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) { struct l2cap_conf_req *req = data; struct l2cap_conf_rfc rfc = { .mode = chan->mode }; void *ptr = req->data; + void *endptr = data + data_size; u16 size; BT_DBG("chan %p", chan); @@ -3220,7 +3224,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) done: if (chan->imtu != L2CAP_DEFAULT_MTU) - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); switch (chan->mode) { case L2CAP_MODE_BASIC: @@ -3239,7 +3243,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) rfc.max_pdu_size = 0; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); break; case L2CAP_MODE_ERTM: @@ -3259,21 +3263,21 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) L2CAP_DEFAULT_TX_WINDOW); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) - l2cap_add_opt_efs(&ptr, chan); + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); if (test_bit(FLAG_EXT_CTRL, &chan->flags)) l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, - chan->tx_win); + chan->tx_win, endptr - ptr); if (chan->conn->feat_mask & L2CAP_FEAT_FCS) if (chan->fcs == L2CAP_FCS_NONE || test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { chan->fcs = L2CAP_FCS_NONE; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, - chan->fcs); + chan->fcs, endptr - ptr); } break; @@ -3291,17 +3295,17 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) rfc.max_pdu_size = cpu_to_le16(size); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) - l2cap_add_opt_efs(&ptr, chan); + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); if (chan->conn->feat_mask & L2CAP_FEAT_FCS) if (chan->fcs == L2CAP_FCS_NONE || test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { chan->fcs = L2CAP_FCS_NONE; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, - chan->fcs); + chan->fcs, endptr - ptr); } break; } @@ -3312,10 +3316,11 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) return ptr - data; } -static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) +static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) { struct l2cap_conf_rsp *rsp = data; void *ptr = rsp->data; + void *endptr = data + data_size; void *req = chan->conf_req; int len = chan->conf_len; int type, hint, olen; @@ -3417,7 +3422,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) return -ECONNREFUSED; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); } if (result == L2CAP_CONF_SUCCESS) { @@ -3430,7 +3435,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) chan->omtu = mtu; set_bit(CONF_MTU_DONE, &chan->conf_state); } - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); if (remote_efs) { if (chan->local_stype != L2CAP_SERV_NOTRAFIC && @@ -3444,7 +3449,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, endptr - ptr); } else { /* Send PENDING Conf Rsp */ result = L2CAP_CONF_PENDING; @@ -3477,7 +3482,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) set_bit(CONF_MODE_DONE, &chan->conf_state); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, - sizeof(rfc), (unsigned long) &rfc); + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { chan->remote_id = efs.id; @@ -3491,7 +3496,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) le32_to_cpu(efs.sdu_itime); l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, endptr - ptr); } break; @@ -3505,7 +3510,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) set_bit(CONF_MODE_DONE, &chan->conf_state); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc, endptr - ptr); break; @@ -3527,10 +3532,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) } static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, - void *data, u16 *result) + void *data, size_t size, u16 *result) { struct l2cap_conf_req *req = data; void *ptr = req->data; + void *endptr = data + size; int type, olen; unsigned long val; struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; @@ -3548,13 +3554,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, chan->imtu = L2CAP_DEFAULT_MIN_MTU; } else chan->imtu = val; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); break; case L2CAP_CONF_FLUSH_TO: chan->flush_to = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, - 2, chan->flush_to); + 2, chan->flush_to, endptr - ptr); break; case L2CAP_CONF_RFC: @@ -3568,13 +3574,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, chan->fcs = 0; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, - sizeof(rfc), (unsigned long) &rfc); + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); break; case L2CAP_CONF_EWS: chan->ack_win = min_t(u16, val, chan->ack_win); l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, - chan->tx_win); + chan->tx_win, endptr - ptr); break; case L2CAP_CONF_EFS: @@ -3587,7 +3593,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, return -ECONNREFUSED; l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs, endptr - ptr); break; case L2CAP_CONF_FCS: @@ -3692,7 +3698,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) return; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } @@ -3900,7 +3906,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, u8 buf[128]; set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } @@ -3978,7 +3984,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, break; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, req), req); + l2cap_build_conf_req(chan, req, sizeof(req)), req); chan->num_conf_req++; break; @@ -4090,7 +4096,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, } /* Complete config. */ - len = l2cap_parse_conf_req(chan, rsp); + len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp)); if (len < 0) { l2cap_send_disconn_req(chan, ECONNRESET); goto unlock; @@ -4124,7 +4130,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { u8 buf[64]; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } @@ -4184,7 +4190,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, char buf[64]; len = l2cap_parse_conf_rsp(chan, rsp->data, len, - buf, &result); + buf, sizeof(buf), &result); if (len < 0) { l2cap_send_disconn_req(chan, ECONNRESET); goto done; @@ -4214,7 +4220,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, /* throw out any old stored conf requests */ result = L2CAP_CONF_SUCCESS; len = l2cap_parse_conf_rsp(chan, rsp->data, len, - req, &result); + req, sizeof(req), &result); if (len < 0) { l2cap_send_disconn_req(chan, ECONNRESET); goto done; @@ -4791,7 +4797,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result, set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } } @@ -7465,7 +7471,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); chan->num_conf_req++; } diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index aa4cf64e32a67b9263d0c5729b8f2f73289f22f1..63e65d9b4b24c648edb4927f943e5fce59180f5f 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -30,10 +30,10 @@ #include -void baswap(bdaddr_t *dst, bdaddr_t *src) +void baswap(bdaddr_t *dst, const bdaddr_t *src) { - unsigned char *d = (unsigned char *) dst; - unsigned char *s = (unsigned char *) src; + const unsigned char *s = (const unsigned char *)src; + unsigned char *d = (unsigned char *)dst; unsigned int i; for (i = 0; i < 6; i++) diff --git a/net/bluetooth/selftest.c b/net/bluetooth/selftest.c index ee92c925ecc5d3ac42bc041f60924da80672e1b8..34a1227f43910e9d728e6a312e5933a9231aed9f 100644 --- a/net/bluetooth/selftest.c +++ b/net/bluetooth/selftest.c @@ -164,7 +164,7 @@ static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32], ret = -EINVAL; out: - kfree(dhkey_a); + kfree(tmp); return ret; } diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 861ae2a165f4dc3271b648794486e6a768590733..f6b6a92f1c486aa94390a6bbe48de6c221110a22 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -53,6 +53,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) brstats->tx_bytes += skb->len; u64_stats_update_end(&brstats->syncp); + br_switchdev_frame_unmark(skb); BR_INPUT_SKB_CB(skb)->brdev = dev; skb_reset_mac_header(skb); diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index a5e4a736a9840420baa91c429bb0e29ff4d0f904..4ea5c8bbe286aa8c299c98bd1d69530875bc2057 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "br_private.h" static struct kmem_cache *br_fdb_cache __read_mostly; @@ -169,29 +170,13 @@ static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr) } } -static void fdb_del_external_learn(struct net_bridge_fdb_entry *f) -{ - struct switchdev_obj_port_fdb fdb = { - .obj = { - .orig_dev = f->dst->dev, - .id = SWITCHDEV_OBJ_ID_PORT_FDB, - .flags = SWITCHDEV_F_DEFER, - }, - .vid = f->vlan_id, - }; - - ether_addr_copy(fdb.addr, f->addr.addr); - switchdev_port_obj_del(f->dst->dev, &fdb.obj); -} - static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f) { + trace_fdb_delete(br, f); + if (f->is_static) fdb_del_hw_addr(br, f->addr.addr); - if (f->added_by_external_learn) - fdb_del_external_learn(f); - hlist_del_init_rcu(&f->hlist); fdb_notify(br, f, RTM_DELNEIGH); call_rcu(&f->rcu, fdb_rcu_free); @@ -598,8 +583,10 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, fdb->updated = now; if (unlikely(added_by_user)) fdb->added_by_user = 1; - if (unlikely(fdb_modified)) + if (unlikely(fdb_modified)) { + trace_br_fdb_update(br, source, addr, vid, added_by_user); fdb_notify(br, fdb, RTM_NEWNEIGH); + } } } else { spin_lock(&br->hash_lock); @@ -608,6 +595,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, if (fdb) { if (unlikely(added_by_user)) fdb->added_by_user = 1; + trace_br_fdb_update(br, source, addr, vid, added_by_user); fdb_notify(br, fdb, RTM_NEWNEIGH); } } @@ -888,6 +876,8 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct net_bridge *br = NULL; int err = 0; + trace_br_fdb_add(ndm, dev, addr, vid, nlh_flags); + if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) { pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state); return -EINVAL; @@ -1084,6 +1074,8 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, bool modified = false; int err = 0; + trace_br_fdb_external_learn_add(br, p, addr, vid); + spin_lock_bh(&br->hash_lock); head = &br->hash[br_mac_hash(addr, vid)]; diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index a0b11e7d67d9ad6857f394a8a71b1cd2ce244eb7..ca01def49af0666a451599aa6e00ecb55c8286c8 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -713,9 +713,9 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void br_mdb_init(void) { - rtnl_register(PF_BRIDGE, RTM_GETMDB, NULL, br_mdb_dump, NULL); - rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, NULL); - rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, NULL); + rtnl_register(PF_BRIDGE, RTM_GETMDB, NULL, br_mdb_dump, 0); + rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, 0); + rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, 0); } void br_mdb_uninit(void) diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 2261e5194c82cf72cfce944de61eb263b4375157..c2eea1b8737a154f561eba1c46999f351c28b112 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -887,7 +887,7 @@ EXPORT_SYMBOL_GPL(br_netfilter_enable); /* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because * br_dev_queue_push_xmit is called afterwards */ -static struct nf_hook_ops br_nf_ops[] __read_mostly = { +static const struct nf_hook_ops br_nf_ops[] = { { .hook = br_nf_pre_routing, .pf = NFPROTO_BRIDGE, @@ -985,22 +985,25 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net, int (*okfn)(struct net *, struct sock *, struct sk_buff *)) { - struct nf_hook_entry *elem; + const struct nf_hook_entries *e; struct nf_hook_state state; + struct nf_hook_ops **ops; + unsigned int i; int ret; - for (elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]); - elem && nf_hook_entry_priority(elem) <= NF_BR_PRI_BRNF; - elem = rcu_dereference(elem->next)) - ; - - if (!elem) + e = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]); + if (!e) return okfn(net, sk, skb); + ops = nf_hook_entries_get_hook_ops(e); + for (i = 0; i < e->num_hook_entries && + ops[i]->priority <= NF_BR_PRI_BRNF; i++) + ; + nf_hook_state_init(&state, hook, NFPROTO_BRIDGE, indev, outdev, sk, net, okfn); - ret = nf_hook_slow(skb, &state, elem); + ret = nf_hook_slow(skb, &state, e, i); if (ret == 1) ret = okfn(net, sk, skb); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index fd9ee73e0a6d6bfb0f1de47811e74012071d5196..e870cfc85b1476e0cd9456a51e6ee161d962d4f3 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -1091,6 +1091,11 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p, unsigned long mask); void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type); + +static inline void br_switchdev_frame_unmark(struct sk_buff *skb) +{ + skb->offload_fwd_mark = 0; +} #else static inline int nbp_switchdev_mark_set(struct net_bridge_port *p) { @@ -1119,6 +1124,10 @@ static inline void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) { } + +static inline void br_switchdev_frame_unmark(struct sk_buff *skb) +{ +} #endif /* CONFIG_NET_SWITCHDEV */ #endif diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c index 181a44d0f1da6364a8965b54cf13aa6a5e44ef22..f6b1c7de059d8053e5820e66ae4bc354f6461b84 100644 --- a/net/bridge/br_switchdev.c +++ b/net/bridge/br_switchdev.c @@ -115,7 +115,7 @@ br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac, void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) { - if (!fdb->added_by_user) + if (!fdb->added_by_user || !fdb->dst) return; switch (type) { diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c index d06968bdf5ec7f1d0d11d48892e7fc792592f245..2b46c50abce0395594f2891b9b4f71e7a4516591 100644 --- a/net/bridge/netfilter/ebt_ip.c +++ b/net/bridge/netfilter/ebt_ip.c @@ -64,14 +64,14 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par) if (NF_INVF(info, EBT_IP_DPORT, dst < info->dport[0] || dst > info->dport[1])) - return false; + return false; } if (info->bitmask & EBT_IP_SPORT) { u32 src = ntohs(pptr->src); if (NF_INVF(info, EBT_IP_SPORT, src < info->sport[0] || src > info->sport[1])) - return false; + return false; } } return true; diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c index 4617491be41e76b27ada6d843511fe75b2611624..2a5a52a53ec430924616cfc1518b6314423a1da5 100644 --- a/net/bridge/netfilter/ebt_ip6.c +++ b/net/bridge/netfilter/ebt_ip6.c @@ -89,7 +89,7 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) if (NF_INVF(info, EBT_IP6_SPORT, src < info->sport[0] || src > info->sport[1])) - return false; + return false; } if ((info->bitmask & EBT_IP6_ICMP6) && NF_INVF(info, EBT_IP6_ICMP6, diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index f22ef7c219137231e13e756b2695b281b90b9dd8..45a00dbdbcad647f2342caa9fc9181f27b7f3a77 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -70,7 +70,7 @@ ebt_out_hook(void *priv, struct sk_buff *skb, return ebt_do_table(skb, state, state->net->xt.frame_filter); } -static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { +static const struct nf_hook_ops ebt_ops_filter[] = { { .hook = ebt_in_hook, .pf = NFPROTO_BRIDGE, diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 2f7a4f314406382a655a94d2ce384226ab906bfb..57cd5bb154e7071096f3205cb5200e277e04c69d 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -48,7 +48,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks) return 0; } -static struct ebt_table frame_nat = { +static const struct ebt_table frame_nat = { .name = "nat", .table = &initial_table, .valid_hooks = NAT_VALID_HOOKS, @@ -70,7 +70,7 @@ ebt_nat_out(void *priv, struct sk_buff *skb, return ebt_do_table(skb, state, state->net->xt.frame_nat); } -static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { +static const struct nf_hook_ops ebt_ops_nat[] = { { .hook = ebt_nat_out, .pf = NFPROTO_BRIDGE, diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 9c6e619f452bc96770a8e340d3879adce6dadd2a..83951f978445e5b9daede1eac715cec0d9f42987 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -252,13 +252,11 @@ unsigned int ebt_do_table(struct sk_buff *skb, } if (verdict == EBT_RETURN) { letsreturn: -#ifdef CONFIG_NETFILTER_DEBUG - if (sp == 0) { - BUGPRINT("RETURN on base chain"); + if (WARN(sp == 0, "RETURN on base chain")) { /* act like this is EBT_CONTINUE */ goto letscontinue; } -#endif + sp--; /* put all the local variables right */ i = cs[sp].n; @@ -271,26 +269,24 @@ unsigned int ebt_do_table(struct sk_buff *skb, } if (verdict == EBT_CONTINUE) goto letscontinue; -#ifdef CONFIG_NETFILTER_DEBUG - if (verdict < 0) { - BUGPRINT("bogus standard verdict\n"); + + if (WARN(verdict < 0, "bogus standard verdict\n")) { read_unlock_bh(&table->lock); return NF_DROP; } -#endif + /* jump to a udc */ cs[sp].n = i + 1; cs[sp].chaininfo = chaininfo; cs[sp].e = ebt_next_entry(point); i = 0; chaininfo = (struct ebt_entries *) (base + verdict); -#ifdef CONFIG_NETFILTER_DEBUG - if (chaininfo->distinguisher) { - BUGPRINT("jump to non-chain\n"); + + if (WARN(chaininfo->distinguisher, "jump to non-chain\n")) { read_unlock_bh(&table->lock); return NF_DROP; } -#endif + nentries = chaininfo->nentries; point = (struct ebt_entry *)chaininfo->data; counter_base = cb_base + chaininfo->counter_offset; @@ -1069,15 +1065,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, #ifdef CONFIG_AUDIT if (audit_enabled) { - struct audit_buffer *ab; - - ab = audit_log_start(current->audit_context, GFP_KERNEL, - AUDIT_NETFILTER_CFG); - if (ab) { - audit_log_format(ab, "table=%s family=%u entries=%u", - repl->name, AF_BRIDGE, repl->nentries); - audit_log_end(ab); - } + audit_log(current->audit_context, GFP_KERNEL, + AUDIT_NETFILTER_CFG, + "table=%s family=%u entries=%u", + repl->name, AF_BRIDGE, repl->nentries); } #endif return ret; diff --git a/net/can/gw.c b/net/can/gw.c index 29748d844c3fac1bda35d494cdc1474fe81849a9..73a02af4b5d76015df42b7eae46f2ba153e79f5c 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -1031,15 +1031,15 @@ static __init int cgw_module_init(void) notifier.notifier_call = cgw_notifier; register_netdevice_notifier(¬ifier); - if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs, NULL)) { + if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs, 0)) { unregister_netdevice_notifier(¬ifier); kmem_cache_destroy(cgw_cache); return -ENOBUFS; } /* Only the first call to __rtnl_register can fail */ - __rtnl_register(PF_CAN, RTM_NEWROUTE, cgw_create_job, NULL, NULL); - __rtnl_register(PF_CAN, RTM_DELROUTE, cgw_remove_job, NULL, NULL); + __rtnl_register(PF_CAN, RTM_NEWROUTE, cgw_create_job, NULL, 0); + __rtnl_register(PF_CAN, RTM_DELROUTE, cgw_remove_job, NULL, 0); return 0; } diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c index 746b145bfd113975e1f17399d845e2fcbdc7541a..417df675c71b0a2e53a25b0f7e9195c6f3c7804e 100644 --- a/net/ceph/crush/mapper.c +++ b/net/ceph/crush/mapper.c @@ -306,7 +306,7 @@ static __u32 *get_choose_arg_weights(const struct crush_bucket_straw2 *bucket, const struct crush_choose_arg *arg, int position) { - if (!arg || !arg->weight_set || arg->weight_set_size == 0) + if (!arg || !arg->weight_set) return bucket->item_weights; if (position >= arg->weight_set_size) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index b7cc615d42efdb2219771c7a83c0acd5fa9ea9f5..a67298c7e0cd4f8f7a441fa938af57e37c4bd4da 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1287,10 +1287,10 @@ static void prepare_write_message(struct ceph_connection *con) if (m->needs_out_seq) { m->hdr.seq = cpu_to_le64(++con->out_seq); m->needs_out_seq = false; - } - if (con->ops->reencode_message) - con->ops->reencode_message(m); + if (con->ops->reencode_message) + con->ops->reencode_message(m); + } dout("prepare_write_message %p seq %lld type %d len %d+%d+%zd\n", m, con->out_seq, le16_to_cpu(m->hdr.type), diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 875675765531361fffa503707a9a98e4596664dd..63edc6e5f0269f21275d6b7be5673e41ba5a9177 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -676,7 +676,8 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, /* * Do a synchronous statfs(). */ -int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) +int ceph_monc_do_statfs(struct ceph_mon_client *monc, u64 data_pool, + struct ceph_statfs *buf) { struct ceph_mon_generic_request *req; struct ceph_mon_statfs *h; @@ -696,6 +697,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) goto out; req->u.st = buf; + req->request->hdr.version = cpu_to_le16(2); mutex_lock(&monc->mutex); register_generic_request(req); @@ -705,6 +707,8 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) h->monhdr.session_mon = cpu_to_le16(-1); h->monhdr.session_mon_tid = 0; h->fsid = monc->monmap->fsid; + h->contains_data_pool = (data_pool != CEPH_NOPOOL); + h->data_pool = cpu_to_le64(data_pool); send_generic_request(monc, req); mutex_unlock(&monc->mutex); diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 901bb8221366253efb0baa139aee4fa62e8e71e0..e02f01f534e2a582557fb489aefe43d6c05aa0db 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -863,8 +863,6 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst, dst->cls.method_len = src->cls.method_len; dst->cls.indata_len = cpu_to_le32(src->cls.indata_len); break; - case CEPH_OSD_OP_STARTSYNC: - break; case CEPH_OSD_OP_WATCH: dst->watch.cookie = cpu_to_le64(src->watch.cookie); dst->watch.ver = cpu_to_le64(0); @@ -916,9 +914,6 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst, * if the file was recently truncated, we include information about its * old and new size so that the object can be updated appropriately. (we * avoid synchronously deleting truncated objects because it's slow.) - * - * if @do_sync, include a 'startsync' command so that the osd will flush - * data quickly. */ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, struct ceph_file_layout *layout, @@ -1337,6 +1332,8 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc, bool legacy_change; bool split = false; bool sort_bitwise = ceph_osdmap_flag(osdc, CEPH_OSDMAP_SORTBITWISE); + bool recovery_deletes = ceph_osdmap_flag(osdc, + CEPH_OSDMAP_RECOVERY_DELETES); enum calc_target_result ct_res; int ret; @@ -1399,6 +1396,8 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc, pi->pg_num, t->sort_bitwise, sort_bitwise, + t->recovery_deletes, + recovery_deletes, &last_pgid)) force_resend = true; @@ -1421,6 +1420,7 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc, t->pg_num = pi->pg_num; t->pg_num_mask = pi->pg_num_mask; t->sort_bitwise = sort_bitwise; + t->recovery_deletes = recovery_deletes; t->osd = acting.primary; } @@ -1918,10 +1918,12 @@ static void encode_request_partial(struct ceph_osd_request *req, } ceph_encode_32(&p, req->r_attempts); /* retry_attempt */ - BUG_ON(p != end - 8); /* space for features */ + BUG_ON(p > end - 8); /* space for features */ msg->hdr.version = cpu_to_le16(8); /* MOSDOp v8 */ /* front_len is finalized in encode_request_finish() */ + msg->front.iov_len = p - msg->front.iov_base; + msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); msg->hdr.data_len = cpu_to_le32(data_len); /* * The header "data_off" is a hint to the receiver allowing it @@ -1937,11 +1939,12 @@ static void encode_request_partial(struct ceph_osd_request *req, static void encode_request_finish(struct ceph_msg *msg) { void *p = msg->front.iov_base; + void *const partial_end = p + msg->front.iov_len; void *const end = p + msg->front_alloc_len; if (CEPH_HAVE_FEATURE(msg->con->peer_features, RESEND_ON_SPLIT)) { /* luminous OSD -- encode features and be done */ - p = end - 8; + p = partial_end; ceph_encode_64(&p, msg->con->peer_features); } else { struct { @@ -1984,7 +1987,7 @@ static void encode_request_finish(struct ceph_msg *msg) oid_len = p - oid; tail = p; - tail_len = (end - p) - 8; + tail_len = partial_end - p; p = msg->front.iov_base; ceph_encode_copy(&p, &head.client_inc, sizeof(head.client_inc)); diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 64ae9f89773a1c44f84858eb7622599a81f25de6..79d14d70b7ea7e032ecffec839b2f44ee4fe7cdc 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -295,6 +295,10 @@ static int decode_choose_args(void **p, void *end, struct crush_map *c) ret = decode_choose_arg(p, end, arg); if (ret) goto fail; + + if (arg->ids_size && + arg->ids_size != c->buckets[bucket_index]->size) + goto e_inval; } insert_choose_arg_map(&c->choose_args, arg_map); @@ -2078,6 +2082,8 @@ bool ceph_is_new_interval(const struct ceph_osds *old_acting, u32 new_pg_num, bool old_sort_bitwise, bool new_sort_bitwise, + bool old_recovery_deletes, + bool new_recovery_deletes, const struct ceph_pg *pgid) { return !osds_equal(old_acting, new_acting) || @@ -2085,7 +2091,8 @@ bool ceph_is_new_interval(const struct ceph_osds *old_acting, old_size != new_size || old_min_size != new_min_size || ceph_pg_is_split(pgid, old_pg_num, new_pg_num) || - old_sort_bitwise != new_sort_bitwise; + old_sort_bitwise != new_sort_bitwise || + old_recovery_deletes != new_recovery_deletes; } static int calc_pg_rank(int osd, const struct ceph_osds *acting) @@ -2301,10 +2308,17 @@ static u32 raw_pg_to_pps(struct ceph_pg_pool_info *pi, } } +/* + * Magic value used for a "default" fallback choose_args, used if the + * crush_choose_arg_map passed to do_crush() does not exist. If this + * also doesn't exist, fall back to canonical weights. + */ +#define CEPH_DEFAULT_CHOOSE_ARGS -1 + static int do_crush(struct ceph_osdmap *map, int ruleno, int x, int *result, int result_max, const __u32 *weight, int weight_max, - u64 choose_args_index) + s64 choose_args_index) { struct crush_choose_arg_map *arg_map; int r; @@ -2313,6 +2327,9 @@ static int do_crush(struct ceph_osdmap *map, int ruleno, int x, arg_map = lookup_choose_arg_map(&map->crush->choose_args, choose_args_index); + if (!arg_map) + arg_map = lookup_choose_arg_map(&map->crush->choose_args, + CEPH_DEFAULT_CHOOSE_ARGS); mutex_lock(&map->crush_workspace_mutex); r = crush_do_rule(map->crush, ruleno, x, result, result_max, @@ -2423,7 +2440,7 @@ static void apply_upmap(struct ceph_osdmap *osdmap, for (i = 0; i < pg->pg_upmap.len; i++) raw->osds[i] = pg->pg_upmap.osds[i]; raw->size = pg->pg_upmap.len; - return; + /* check and apply pg_upmap_items, if any */ } pg = lookup_pg_mapping(&osdmap->pg_upmap_items, pgid); @@ -2454,10 +2471,8 @@ static void apply_upmap(struct ceph_osdmap *osdmap, pos = j; } } - if (!exists && pos >= 0) { + if (!exists && pos >= 0) raw->osds[pos] = to; - return; - } } } } diff --git a/net/compat.c b/net/compat.c index 6ded6c821d7a21f296d14db02552ea1c71643051..22381719718c4fbd5d63b8836e3161026b59a459 100644 --- a/net/compat.c +++ b/net/compat.c @@ -185,6 +185,13 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk, ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen); } + /* + * check the length of messages copied in is the same as the + * what we get from the first loop + */ + if ((char *)kcmsg - (char *)kcmsg_base != kcmlen) + goto Einval; + /* Ok, looks like we made it. Hook it up and return success. */ kmsg->msg_control = kcmsg_base; kmsg->msg_controllen = kcmlen; diff --git a/net/core/Makefile b/net/core/Makefile index 79f9479e965812c635b5337ff89d393a7176d9ab..56d771a887b6c7d57eda434a461b6a305f92fa38 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -9,9 +9,9 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ - sock_diag.o dev_ioctl.o tso.o sock_reuseport.o + sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ + fib_notifier.o -obj-$(CONFIG_XFRM) += flow.o obj-y += net-sysfs.o obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o diff --git a/net/core/datagram.c b/net/core/datagram.c index ee5647bd91b3f3a864dccdc46098b30e8561377d..f7fb7e3f2acf33e42e1140372d87dc543a2f2c7c 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -169,14 +169,20 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, int *peeked, int *off, int *err, struct sk_buff **last) { + bool peek_at_off = false; struct sk_buff *skb; - int _off = *off; + int _off = 0; + + if (unlikely(flags & MSG_PEEK && *off >= 0)) { + peek_at_off = true; + _off = *off; + } *last = queue->prev; skb_queue_walk(queue, skb) { if (flags & MSG_PEEK) { - if (_off >= skb->len && (skb->len || _off || - skb->peeked)) { + if (peek_at_off && _off >= skb->len && + (_off || skb->peeked)) { _off -= skb->len; continue; } @@ -356,7 +362,7 @@ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue, if (flags & MSG_PEEK) { err = -ENOENT; spin_lock_bh(&sk_queue->lock); - if (skb == skb_peek(sk_queue)) { + if (skb->next) { __skb_unlink(skb, sk_queue); refcount_dec(&skb->users); if (destructor) @@ -573,27 +579,12 @@ int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, } EXPORT_SYMBOL(skb_copy_datagram_from_iter); -/** - * zerocopy_sg_from_iter - Build a zerocopy datagram from an iov_iter - * @skb: buffer to copy - * @from: the source to copy from - * - * The function will first copy up to headlen, and then pin the userspace - * pages and build frags through them. - * - * Returns 0, -EFAULT or -EMSGSIZE. - */ -int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) +int __zerocopy_sg_from_iter(struct sock *sk, struct sk_buff *skb, + struct iov_iter *from, size_t length) { - int len = iov_iter_count(from); - int copy = min_t(int, skb_headlen(skb), len); - int frag = 0; + int frag = skb_shinfo(skb)->nr_frags; - /* copy up to skb headlen */ - if (skb_copy_datagram_from_iter(skb, 0, from, copy)) - return -EFAULT; - - while (iov_iter_count(from)) { + while (length && iov_iter_count(from)) { struct page *pages[MAX_SKB_FRAGS]; size_t start; ssize_t copied; @@ -603,18 +594,24 @@ int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) if (frag == MAX_SKB_FRAGS) return -EMSGSIZE; - copied = iov_iter_get_pages(from, pages, ~0U, + copied = iov_iter_get_pages(from, pages, length, MAX_SKB_FRAGS - frag, &start); if (copied < 0) return -EFAULT; iov_iter_advance(from, copied); + length -= copied; truesize = PAGE_ALIGN(copied + start); skb->data_len += copied; skb->len += copied; skb->truesize += truesize; - refcount_add(truesize, &skb->sk->sk_wmem_alloc); + if (sk && sk->sk_type == SOCK_STREAM) { + sk->sk_wmem_queued += truesize; + sk_mem_charge(sk, truesize); + } else { + refcount_add(truesize, &skb->sk->sk_wmem_alloc); + } while (copied) { int size = min_t(int, copied, PAGE_SIZE - start); skb_fill_page_desc(skb, frag++, pages[n], start, size); @@ -625,6 +622,28 @@ int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) } return 0; } +EXPORT_SYMBOL(__zerocopy_sg_from_iter); + +/** + * zerocopy_sg_from_iter - Build a zerocopy datagram from an iov_iter + * @skb: buffer to copy + * @from: the source to copy from + * + * The function will first copy up to headlen, and then pin the userspace + * pages and build frags through them. + * + * Returns 0, -EFAULT or -EMSGSIZE. + */ +int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) +{ + int copy = min_t(int, skb_headlen(skb), iov_iter_count(from)); + + /* copy up to skb headlen */ + if (skb_copy_datagram_from_iter(skb, 0, from, copy)) + return -EFAULT; + + return __zerocopy_sg_from_iter(NULL, skb, from, ~0U); +} EXPORT_SYMBOL(zerocopy_sg_from_iter); static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, diff --git a/net/core/dev.c b/net/core/dev.c index 8515f8fe0460ae08e08e269a47524e0738714626..588b473194a8a8ce23bde368b2b0350a3317db8b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -144,6 +144,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -1413,7 +1414,7 @@ int dev_open(struct net_device *dev) } EXPORT_SYMBOL(dev_open); -static int __dev_close_many(struct list_head *head) +static void __dev_close_many(struct list_head *head) { struct net_device *dev; @@ -1455,23 +1456,18 @@ static int __dev_close_many(struct list_head *head) dev->flags &= ~IFF_UP; netpoll_poll_enable(dev); } - - return 0; } -static int __dev_close(struct net_device *dev) +static void __dev_close(struct net_device *dev) { - int retval; LIST_HEAD(single); list_add(&dev->close_list, &single); - retval = __dev_close_many(&single); + __dev_close_many(&single); list_del(&single); - - return retval; } -int dev_close_many(struct list_head *head, bool unlink) +void dev_close_many(struct list_head *head, bool unlink) { struct net_device *dev, *tmp; @@ -1488,8 +1484,6 @@ int dev_close_many(struct list_head *head, bool unlink) if (unlink) list_del_init(&dev->close_list); } - - return 0; } EXPORT_SYMBOL(dev_close_many); @@ -1502,7 +1496,7 @@ EXPORT_SYMBOL(dev_close_many); * is then deactivated and finally a %NETDEV_DOWN is sent to the notifier * chain. */ -int dev_close(struct net_device *dev) +void dev_close(struct net_device *dev) { if (dev->flags & IFF_UP) { LIST_HEAD(single); @@ -1511,7 +1505,6 @@ int dev_close(struct net_device *dev) dev_close_many(&single, true); list_del(&single); } - return 0; } EXPORT_SYMBOL(dev_close); @@ -1860,7 +1853,7 @@ static inline int deliver_skb(struct sk_buff *skb, struct packet_type *pt_prev, struct net_device *orig_dev) { - if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) + if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) return -ENOMEM; refcount_inc(&skb->users); return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); @@ -1955,8 +1948,12 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) goto again; } out_unlock: - if (pt_prev) - pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); + if (pt_prev) { + if (!skb_orphan_frags_rx(skb2, GFP_ATOMIC)) + pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); + else + kfree_skb(skb2); + } rcu_read_unlock(); } EXPORT_SYMBOL_GPL(dev_queue_xmit_nit); @@ -2738,8 +2735,7 @@ EXPORT_SYMBOL(skb_mac_gso_segment); static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path) { if (tx_path) - return skb->ip_summed != CHECKSUM_PARTIAL && - skb->ip_summed != CHECKSUM_NONE; + return skb->ip_summed != CHECKSUM_PARTIAL; return skb->ip_summed == CHECKSUM_NONE; } @@ -3865,6 +3861,122 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, return NET_RX_DROP; } +static u32 netif_receive_generic_xdp(struct sk_buff *skb, + struct bpf_prog *xdp_prog) +{ + struct xdp_buff xdp; + u32 act = XDP_DROP; + void *orig_data; + int hlen, off; + u32 mac_len; + + /* Reinjected packets coming from act_mirred or similar should + * not get XDP generic processing. + */ + if (skb_cloned(skb)) + return XDP_PASS; + + if (skb_linearize(skb)) + goto do_drop; + + /* The XDP program wants to see the packet starting at the MAC + * header. + */ + mac_len = skb->data - skb_mac_header(skb); + hlen = skb_headlen(skb) + mac_len; + xdp.data = skb->data - mac_len; + xdp.data_end = xdp.data + hlen; + xdp.data_hard_start = skb->data - skb_headroom(skb); + orig_data = xdp.data; + + act = bpf_prog_run_xdp(xdp_prog, &xdp); + + off = xdp.data - orig_data; + if (off > 0) + __skb_pull(skb, off); + else if (off < 0) + __skb_push(skb, -off); + skb->mac_header += off; + + switch (act) { + case XDP_REDIRECT: + case XDP_TX: + __skb_push(skb, mac_len); + /* fall through */ + case XDP_PASS: + break; + + default: + bpf_warn_invalid_xdp_action(act); + /* fall through */ + case XDP_ABORTED: + trace_xdp_exception(skb->dev, xdp_prog, act); + /* fall through */ + case XDP_DROP: + do_drop: + kfree_skb(skb); + break; + } + + return act; +} + +/* When doing generic XDP we have to bypass the qdisc layer and the + * network taps in order to match in-driver-XDP behavior. + */ +void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog) +{ + struct net_device *dev = skb->dev; + struct netdev_queue *txq; + bool free_skb = true; + int cpu, rc; + + txq = netdev_pick_tx(dev, skb, NULL); + cpu = smp_processor_id(); + HARD_TX_LOCK(dev, txq, cpu); + if (!netif_xmit_stopped(txq)) { + rc = netdev_start_xmit(skb, dev, txq, 0); + if (dev_xmit_complete(rc)) + free_skb = false; + } + HARD_TX_UNLOCK(dev, txq); + if (free_skb) { + trace_xdp_exception(dev, xdp_prog, XDP_TX); + kfree_skb(skb); + } +} +EXPORT_SYMBOL_GPL(generic_xdp_tx); + +static struct static_key generic_xdp_needed __read_mostly; + +int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb) +{ + if (xdp_prog) { + u32 act = netif_receive_generic_xdp(skb, xdp_prog); + int err; + + if (act != XDP_PASS) { + switch (act) { + case XDP_REDIRECT: + err = xdp_do_generic_redirect(skb->dev, skb, + xdp_prog); + if (err) + goto out_redir; + /* fallthru to submit skb */ + case XDP_TX: + generic_xdp_tx(skb, xdp_prog); + break; + } + return XDP_DROP; + } + } + return XDP_PASS; +out_redir: + kfree_skb(skb); + return XDP_DROP; +} +EXPORT_SYMBOL_GPL(do_xdp_generic); + static int netif_rx_internal(struct sk_buff *skb) { int ret; @@ -3872,6 +3984,24 @@ static int netif_rx_internal(struct sk_buff *skb) net_timestamp_check(netdev_tstamp_prequeue, skb); trace_netif_rx(skb); + + if (static_key_false(&generic_xdp_needed)) { + int ret; + + preempt_disable(); + rcu_read_lock(); + ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb); + rcu_read_unlock(); + preempt_enable(); + + /* Consider XDP consuming the packet a success from + * the netdev point of view we do not want to count + * this as an error. + */ + if (ret != XDP_PASS) + return NET_RX_SUCCESS; + } + #ifdef CONFIG_RPS if (static_key_false(&rps_needed)) { struct rps_dev_flow voidflow, *rflow = &voidflow; @@ -4292,7 +4422,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc) } if (pt_prev) { - if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) + if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) goto drop; else ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); @@ -4338,8 +4468,6 @@ static int __netif_receive_skb(struct sk_buff *skb) return ret; } -static struct static_key generic_xdp_needed __read_mostly; - static int generic_xdp_install(struct net_device *dev, struct netdev_xdp *xdp) { struct bpf_prog *old = rtnl_dereference(dev->xdp_prog); @@ -4373,89 +4501,6 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_xdp *xdp) return ret; } -static u32 netif_receive_generic_xdp(struct sk_buff *skb, - struct bpf_prog *xdp_prog) -{ - struct xdp_buff xdp; - u32 act = XDP_DROP; - void *orig_data; - int hlen, off; - u32 mac_len; - - /* Reinjected packets coming from act_mirred or similar should - * not get XDP generic processing. - */ - if (skb_cloned(skb)) - return XDP_PASS; - - if (skb_linearize(skb)) - goto do_drop; - - /* The XDP program wants to see the packet starting at the MAC - * header. - */ - mac_len = skb->data - skb_mac_header(skb); - hlen = skb_headlen(skb) + mac_len; - xdp.data = skb->data - mac_len; - xdp.data_end = xdp.data + hlen; - xdp.data_hard_start = skb->data - skb_headroom(skb); - orig_data = xdp.data; - - act = bpf_prog_run_xdp(xdp_prog, &xdp); - - off = xdp.data - orig_data; - if (off > 0) - __skb_pull(skb, off); - else if (off < 0) - __skb_push(skb, -off); - - switch (act) { - case XDP_TX: - __skb_push(skb, mac_len); - /* fall through */ - case XDP_PASS: - break; - - default: - bpf_warn_invalid_xdp_action(act); - /* fall through */ - case XDP_ABORTED: - trace_xdp_exception(skb->dev, xdp_prog, act); - /* fall through */ - case XDP_DROP: - do_drop: - kfree_skb(skb); - break; - } - - return act; -} - -/* When doing generic XDP we have to bypass the qdisc layer and the - * network taps in order to match in-driver-XDP behavior. - */ -static void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog) -{ - struct net_device *dev = skb->dev; - struct netdev_queue *txq; - bool free_skb = true; - int cpu, rc; - - txq = netdev_pick_tx(dev, skb, NULL); - cpu = smp_processor_id(); - HARD_TX_LOCK(dev, txq, cpu); - if (!netif_xmit_stopped(txq)) { - rc = netdev_start_xmit(skb, dev, txq, 0); - if (dev_xmit_complete(rc)) - free_skb = false; - } - HARD_TX_UNLOCK(dev, txq); - if (free_skb) { - trace_xdp_exception(dev, xdp_prog, XDP_TX); - kfree_skb(skb); - } -} - static int netif_receive_skb_internal(struct sk_buff *skb) { int ret; @@ -4465,23 +4510,20 @@ static int netif_receive_skb_internal(struct sk_buff *skb) if (skb_defer_rx_timestamp(skb)) return NET_RX_SUCCESS; - rcu_read_lock(); - if (static_key_false(&generic_xdp_needed)) { - struct bpf_prog *xdp_prog = rcu_dereference(skb->dev->xdp_prog); + int ret; - if (xdp_prog) { - u32 act = netif_receive_generic_xdp(skb, xdp_prog); + preempt_disable(); + rcu_read_lock(); + ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb); + rcu_read_unlock(); + preempt_enable(); - if (act != XDP_PASS) { - rcu_read_unlock(); - if (act == XDP_TX) - generic_xdp_tx(skb, xdp_prog); - return NET_RX_DROP; - } - } + if (ret != XDP_PASS) + return NET_RX_DROP; } + rcu_read_lock(); #ifdef CONFIG_RPS if (static_key_false(&rps_needed)) { struct rps_dev_flow voidflow, *rflow = &voidflow; @@ -5289,6 +5331,7 @@ static void busy_poll_stop(struct napi_struct *napi, void *have_poll_lock) * Ideally, a new ndo_busy_poll_stop() could avoid another round. */ rc = napi->poll(napi, BUSY_POLL_BUDGET); + trace_napi_poll(napi, rc, BUSY_POLL_BUDGET); netpoll_poll_unlock(have_poll_lock); if (rc == BUSY_POLL_BUDGET) __napi_schedule(napi); @@ -5667,12 +5710,13 @@ EXPORT_SYMBOL(netdev_has_upper_dev_all_rcu); * Find out if a device is linked to an upper device and return true in case * it is. The caller must hold the RTNL lock. */ -static bool netdev_has_any_upper_dev(struct net_device *dev) +bool netdev_has_any_upper_dev(struct net_device *dev) { ASSERT_RTNL(); return !list_empty(&dev->adj_list.upper); } +EXPORT_SYMBOL(netdev_has_any_upper_dev); /** * netdev_master_upper_dev_get - Get master upper device @@ -6689,8 +6733,12 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags) */ ret = 0; - if ((old_flags ^ flags) & IFF_UP) - ret = ((old_flags & IFF_UP) ? __dev_close : __dev_open)(dev); + if ((old_flags ^ flags) & IFF_UP) { + if (old_flags & IFF_UP) + __dev_close(dev); + else + ret = __dev_open(dev); + } if ((flags ^ dev->gflags) & IFF_PROMISC) { int inc = (flags & IFF_PROMISC) ? 1 : -1; @@ -7235,24 +7283,6 @@ static netdev_features_t netdev_fix_features(struct net_device *dev, features &= ~NETIF_F_GSO; } - /* UFO needs SG and checksumming */ - if (features & NETIF_F_UFO) { - /* maybe split UFO into V4 and V6? */ - if (!(features & NETIF_F_HW_CSUM) && - ((features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) != - (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) { - netdev_dbg(dev, - "Dropping NETIF_F_UFO since no checksum offload features.\n"); - features &= ~NETIF_F_UFO; - } - - if (!(features & NETIF_F_SG)) { - netdev_dbg(dev, - "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n"); - features &= ~NETIF_F_UFO; - } - } - /* GSO partial features require GSO partial be set */ if ((features & dev->gso_partial_features) && !(features & NETIF_F_GSO_PARTIAL)) { @@ -7313,8 +7343,27 @@ int __netdev_update_features(struct net_device *dev) netdev_for_each_lower_dev(dev, lower, iter) netdev_sync_lower_features(dev, lower, features); - if (!err) + if (!err) { + netdev_features_t diff = features ^ dev->features; + + if (diff & NETIF_F_RX_UDP_TUNNEL_PORT) { + /* udp_tunnel_{get,drop}_rx_info both need + * NETIF_F_RX_UDP_TUNNEL_PORT enabled on the + * device, or they won't do anything. + * Thus we need to update dev->features + * *before* calling udp_tunnel_get_rx_info, + * but *after* calling udp_tunnel_drop_rx_info. + */ + if (features & NETIF_F_RX_UDP_TUNNEL_PORT) { + dev->features = features; + udp_tunnel_get_rx_info(dev); + } else { + udp_tunnel_drop_rx_info(dev); + } + } + dev->features = features; + } return err < 0 ? 0 : 1; } @@ -7516,6 +7565,12 @@ int register_netdevice(struct net_device *dev) */ dev->hw_features |= NETIF_F_SOFT_FEATURES; dev->features |= NETIF_F_SOFT_FEATURES; + + if (dev->netdev_ops->ndo_udp_tunnel_add) { + dev->features |= NETIF_F_RX_UDP_TUNNEL_PORT; + dev->hw_features |= NETIF_F_RX_UDP_TUNNEL_PORT; + } + dev->wanted_features = dev->features & dev->hw_features; if (!(dev->flags & IFF_LOOPBACK)) diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 06b147d7d9e2e7d8d305dd9b173d9bc1a7e9a676..709a4e6fb447fda886046308de5b613a88ff9dfa 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -263,6 +263,8 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) return dev_set_mtu(dev, ifr->ifr_mtu); case SIOCSIFHWADDR: + if (dev->addr_len > sizeof(struct sockaddr)) + return -EINVAL; return dev_set_mac_address(dev, &ifr->ifr_hwaddr); case SIOCSIFHWBROADCAST: diff --git a/net/core/devlink.c b/net/core/devlink.c index a0adfc31a3fe854cd52600f6b2924255aee521c2..7d430c1d9c3ed9be22f558d9297ac65e5d64ec7d 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -29,6 +29,57 @@ #define CREATE_TRACE_POINTS #include +static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = { + { + .name = "destination mac", + .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, + .bitwidth = 48, + }, +}; + +struct devlink_dpipe_header devlink_dpipe_header_ethernet = { + .name = "ethernet", + .id = DEVLINK_DPIPE_HEADER_ETHERNET, + .fields = devlink_dpipe_fields_ethernet, + .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet), + .global = true, +}; +EXPORT_SYMBOL(devlink_dpipe_header_ethernet); + +static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = { + { + .name = "destination ip", + .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP, + .bitwidth = 32, + }, +}; + +struct devlink_dpipe_header devlink_dpipe_header_ipv4 = { + .name = "ipv4", + .id = DEVLINK_DPIPE_HEADER_IPV4, + .fields = devlink_dpipe_fields_ipv4, + .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4), + .global = true, +}; +EXPORT_SYMBOL(devlink_dpipe_header_ipv4); + +static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = { + { + .name = "destination ip", + .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP, + .bitwidth = 128, + }, +}; + +struct devlink_dpipe_header devlink_dpipe_header_ipv6 = { + .name = "ipv6", + .id = DEVLINK_DPIPE_HEADER_IPV6, + .fields = devlink_dpipe_fields_ipv6, + .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6), + .global = true, +}; +EXPORT_SYMBOL(devlink_dpipe_header_ipv6); + EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg); static LIST_HEAD(devlink_list); @@ -1613,13 +1664,15 @@ static int devlink_dpipe_table_put(struct sk_buff *skb, struct devlink_dpipe_table *table) { struct nlattr *table_attr; + u64 table_size; + table_size = table->table_ops->size_get(table->priv); table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE); if (!table_attr) return -EMSGSIZE; if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) || - nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table->size, + nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size, DEVLINK_ATTR_PAD)) goto nla_put_failure; if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, @@ -1960,6 +2013,28 @@ int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) } EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); +void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry) + +{ + unsigned int value_count, value_index; + struct devlink_dpipe_value *value; + + value = entry->action_values; + value_count = entry->action_values_count; + for (value_index = 0; value_index < value_count; value_index++) { + kfree(value[value_index].value); + kfree(value[value_index].mask); + } + + value = entry->match_values; + value_count = entry->match_values_count; + for (value_index = 0; value_index < value_count; value_index++) { + kfree(value[value_index].value); + kfree(value[value_index].mask); + } +} +EXPORT_SYMBOL(devlink_dpipe_entry_clear); + static int devlink_dpipe_entries_fill(struct genl_info *info, enum devlink_command cmd, int flags, struct devlink_dpipe_table *table) @@ -2684,20 +2759,21 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); * @table_name: table name * @table_ops: table ops * @priv: priv - * @size: size * @counter_control_extern: external control for counters */ int devlink_dpipe_table_register(struct devlink *devlink, const char *table_name, struct devlink_dpipe_table_ops *table_ops, - void *priv, u64 size, - bool counter_control_extern) + void *priv, bool counter_control_extern) { struct devlink_dpipe_table *table; if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name)) return -EEXIST; + if (WARN_ON(!table_ops->size_get)) + return -EINVAL; + table = kzalloc(sizeof(*table), GFP_KERNEL); if (!table) return -ENOMEM; @@ -2705,7 +2781,6 @@ int devlink_dpipe_table_register(struct devlink *devlink, table->name = table_name; table->table_ops = table_ops; table->priv = priv; - table->size = size; table->counter_control_extern = counter_control_extern; mutex_lock(&devlink_mutex); diff --git a/net/core/dst.c b/net/core/dst.c index 00aa972ad1a1a451c24f3f8211243ad35c19433a..a6c47da7d0f8bf8a871c73aaedc21360712e03b2 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -55,7 +55,7 @@ const struct dst_metrics dst_default_metrics = { * We really want to avoid false sharing on this variable, and catch * any writes on it. */ - .refcnt = ATOMIC_INIT(1), + .refcnt = REFCOUNT_INIT(1), }; void dst_init(struct dst_entry *dst, struct dst_ops *ops, @@ -213,7 +213,7 @@ u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old) struct dst_metrics *old_p = (struct dst_metrics *)__DST_METRICS_PTR(old); unsigned long prev, new; - atomic_set(&p->refcnt, 1); + refcount_set(&p->refcnt, 1); memcpy(p->metrics, old_p->metrics, sizeof(p->metrics)); new = (unsigned long) p; @@ -225,7 +225,7 @@ u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old) if (prev & DST_METRICS_READ_ONLY) p = NULL; } else if (prev & DST_METRICS_REFCOUNTED) { - if (atomic_dec_and_test(&old_p->refcnt)) + if (refcount_dec_and_test(&old_p->refcnt)) kfree(old_p); } } @@ -299,7 +299,8 @@ EXPORT_SYMBOL_GPL(metadata_dst_alloc); void metadata_dst_free(struct metadata_dst *md_dst) { #ifdef CONFIG_DST_CACHE - dst_cache_destroy(&md_dst->u.tun_info.dst_cache); + if (md_dst->type == METADATA_IP_TUNNEL) + dst_cache_destroy(&md_dst->u.tun_info.dst_cache); #endif kfree(md_dst); } diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 674b6c9cec18afae6f1b597a6e978d5a1fe6c7fe..3228411ada0fa77e2796b733a695826282d82df9 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -76,7 +76,6 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] [NETIF_F_LRO_BIT] = "rx-lro", [NETIF_F_TSO_BIT] = "tx-tcp-segmentation", - [NETIF_F_UFO_BIT] = "tx-udp-fragmentation", [NETIF_F_GSO_ROBUST_BIT] = "tx-gso-robust", [NETIF_F_TSO_ECN_BIT] = "tx-tcp-ecn-segmentation", [NETIF_F_TSO_MANGLEID_BIT] = "tx-tcp-mangleid-segmentation", @@ -106,6 +105,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] [NETIF_F_HW_TC_BIT] = "hw-tc-offload", [NETIF_F_HW_ESP_BIT] = "esp-hw-offload", [NETIF_F_HW_ESP_TX_CSUM_BIT] = "esp-tx-csum-hw-offload", + [NETIF_F_RX_UDP_TUNNEL_PORT_BIT] = "rx-udp_tunnel-port-offload", }; static const char @@ -299,9 +299,6 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd) case ETHTOOL_GTSO: case ETHTOOL_STSO: return NETIF_F_ALL_TSO; - case ETHTOOL_GUFO: - case ETHTOOL_SUFO: - return NETIF_F_UFO; case ETHTOOL_GGSO: case ETHTOOL_SGSO: return NETIF_F_GSO; @@ -528,6 +525,8 @@ convert_link_ksettings_to_legacy_settings( = link_ksettings->base.eth_tp_mdix; legacy_settings->eth_tp_mdix_ctrl = link_ksettings->base.eth_tp_mdix_ctrl; + legacy_settings->transceiver + = link_ksettings->base.transceiver; return retval; } @@ -2515,6 +2514,33 @@ static int set_phy_tunable(struct net_device *dev, void __user *useraddr) return ret; } +static int ethtool_get_fecparam(struct net_device *dev, void __user *useraddr) +{ + struct ethtool_fecparam fecparam = { ETHTOOL_GFECPARAM }; + + if (!dev->ethtool_ops->get_fecparam) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_fecparam(dev, &fecparam); + + if (copy_to_user(useraddr, &fecparam, sizeof(fecparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_fecparam(struct net_device *dev, void __user *useraddr) +{ + struct ethtool_fecparam fecparam; + + if (!dev->ethtool_ops->set_fecparam) + return -EOPNOTSUPP; + + if (copy_from_user(&fecparam, useraddr, sizeof(fecparam))) + return -EFAULT; + + return dev->ethtool_ops->set_fecparam(dev, &fecparam); +} + /* The main entry point in this file. Called from net/core/dev_ioctl.c */ int dev_ethtool(struct net *net, struct ifreq *ifr) @@ -2555,7 +2581,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GPHYSTATS: case ETHTOOL_GTSO: case ETHTOOL_GPERMADDR: - case ETHTOOL_GUFO: case ETHTOOL_GGSO: case ETHTOOL_GGRO: case ETHTOOL_GFLAGS: @@ -2574,6 +2599,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GTUNABLE: case ETHTOOL_PHY_GTUNABLE: case ETHTOOL_GLINKSETTINGS: + case ETHTOOL_GFECPARAM: break; default: if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) @@ -2723,7 +2749,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GRXCSUM: case ETHTOOL_GSG: case ETHTOOL_GTSO: - case ETHTOOL_GUFO: case ETHTOOL_GGSO: case ETHTOOL_GGRO: rc = ethtool_get_one_feature(dev, useraddr, ethcmd); @@ -2732,7 +2757,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_SRXCSUM: case ETHTOOL_SSG: case ETHTOOL_STSO: - case ETHTOOL_SUFO: case ETHTOOL_SGSO: case ETHTOOL_SGRO: rc = ethtool_set_one_feature(dev, useraddr, ethcmd); @@ -2785,6 +2809,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_PHY_STUNABLE: rc = set_phy_tunable(dev, useraddr); break; + case ETHTOOL_GFECPARAM: + rc = ethtool_get_fecparam(dev, useraddr); + break; + case ETHTOOL_SFECPARAM: + rc = ethtool_set_fecparam(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } diff --git a/net/core/fib_notifier.c b/net/core/fib_notifier.c new file mode 100644 index 0000000000000000000000000000000000000000..4fc202dbdfb607c6042c2de12b71b4a3b1fa2fef --- /dev/null +++ b/net/core/fib_notifier.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static ATOMIC_NOTIFIER_HEAD(fib_chain); + +int call_fib_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct fib_notifier_info *info) +{ + info->net = net; + return nb->notifier_call(nb, event_type, info); +} +EXPORT_SYMBOL(call_fib_notifier); + +int call_fib_notifiers(struct net *net, enum fib_event_type event_type, + struct fib_notifier_info *info) +{ + info->net = net; + return atomic_notifier_call_chain(&fib_chain, event_type, info); +} +EXPORT_SYMBOL(call_fib_notifiers); + +static unsigned int fib_seq_sum(void) +{ + struct fib_notifier_ops *ops; + unsigned int fib_seq = 0; + struct net *net; + + rtnl_lock(); + for_each_net(net) { + list_for_each_entry(ops, &net->fib_notifier_ops, list) { + if (!try_module_get(ops->owner)) + continue; + fib_seq += ops->fib_seq_read(net); + module_put(ops->owner); + } + } + rtnl_unlock(); + + return fib_seq; +} + +static int fib_net_dump(struct net *net, struct notifier_block *nb) +{ + struct fib_notifier_ops *ops; + + list_for_each_entry_rcu(ops, &net->fib_notifier_ops, list) { + int err; + + if (!try_module_get(ops->owner)) + continue; + err = ops->fib_dump(net, nb); + module_put(ops->owner); + if (err) + return err; + } + + return 0; +} + +static bool fib_dump_is_consistent(struct notifier_block *nb, + void (*cb)(struct notifier_block *nb), + unsigned int fib_seq) +{ + atomic_notifier_chain_register(&fib_chain, nb); + if (fib_seq == fib_seq_sum()) + return true; + atomic_notifier_chain_unregister(&fib_chain, nb); + if (cb) + cb(nb); + return false; +} + +#define FIB_DUMP_MAX_RETRIES 5 +int register_fib_notifier(struct notifier_block *nb, + void (*cb)(struct notifier_block *nb)) +{ + int retries = 0; + int err; + + do { + unsigned int fib_seq = fib_seq_sum(); + struct net *net; + + rcu_read_lock(); + for_each_net_rcu(net) { + err = fib_net_dump(net, nb); + if (err) + goto err_fib_net_dump; + } + rcu_read_unlock(); + + if (fib_dump_is_consistent(nb, cb, fib_seq)) + return 0; + } while (++retries < FIB_DUMP_MAX_RETRIES); + + return -EBUSY; + +err_fib_net_dump: + rcu_read_unlock(); + return err; +} +EXPORT_SYMBOL(register_fib_notifier); + +int unregister_fib_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&fib_chain, nb); +} +EXPORT_SYMBOL(unregister_fib_notifier); + +static int __fib_notifier_ops_register(struct fib_notifier_ops *ops, + struct net *net) +{ + struct fib_notifier_ops *o; + + list_for_each_entry(o, &net->fib_notifier_ops, list) + if (ops->family == o->family) + return -EEXIST; + list_add_tail_rcu(&ops->list, &net->fib_notifier_ops); + return 0; +} + +struct fib_notifier_ops * +fib_notifier_ops_register(const struct fib_notifier_ops *tmpl, struct net *net) +{ + struct fib_notifier_ops *ops; + int err; + + ops = kmemdup(tmpl, sizeof(*ops), GFP_KERNEL); + if (!ops) + return ERR_PTR(-ENOMEM); + + err = __fib_notifier_ops_register(ops, net); + if (err) + goto err_register; + + return ops; + +err_register: + kfree(ops); + return ERR_PTR(err); +} +EXPORT_SYMBOL(fib_notifier_ops_register); + +void fib_notifier_ops_unregister(struct fib_notifier_ops *ops) +{ + list_del_rcu(&ops->list); + kfree_rcu(ops, rcu); +} +EXPORT_SYMBOL(fib_notifier_ops_unregister); + +static int __net_init fib_notifier_net_init(struct net *net) +{ + INIT_LIST_HEAD(&net->fib_notifier_ops); + return 0; +} + +static struct pernet_operations fib_notifier_net_ops = { + .init = fib_notifier_net_init, +}; + +static int __init fib_notifier_init(void) +{ + return register_pernet_subsys(&fib_notifier_net_ops); +} + +subsys_initcall(fib_notifier_init); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index fdcb1bcd2afad5737a2c11fab55a3c214b86388d..9a6d97c1d8104eac629273337ca8999a86118533 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -299,6 +299,67 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, } EXPORT_SYMBOL_GPL(fib_rules_lookup); +static int call_fib_rule_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct fib_rule *rule, int family) +{ + struct fib_rule_notifier_info info = { + .info.family = family, + .rule = rule, + }; + + return call_fib_notifier(nb, net, event_type, &info.info); +} + +static int call_fib_rule_notifiers(struct net *net, + enum fib_event_type event_type, + struct fib_rule *rule, + struct fib_rules_ops *ops) +{ + struct fib_rule_notifier_info info = { + .info.family = ops->family, + .rule = rule, + }; + + ops->fib_rules_seq++; + return call_fib_notifiers(net, event_type, &info.info); +} + +/* Called with rcu_read_lock() */ +int fib_rules_dump(struct net *net, struct notifier_block *nb, int family) +{ + struct fib_rules_ops *ops; + struct fib_rule *rule; + + ops = lookup_rules_ops(net, family); + if (!ops) + return -EAFNOSUPPORT; + list_for_each_entry_rcu(rule, &ops->rules_list, list) + call_fib_rule_notifier(nb, net, FIB_EVENT_RULE_ADD, rule, + family); + rules_ops_put(ops); + + return 0; +} +EXPORT_SYMBOL_GPL(fib_rules_dump); + +unsigned int fib_rules_seq_read(struct net *net, int family) +{ + unsigned int fib_rules_seq; + struct fib_rules_ops *ops; + + ASSERT_RTNL(); + + ops = lookup_rules_ops(net, family); + if (!ops) + return 0; + fib_rules_seq = ops->fib_rules_seq; + rules_ops_put(ops); + + return fib_rules_seq; +} +EXPORT_SYMBOL_GPL(fib_rules_seq_read); + static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb, struct fib_rules_ops *ops) { @@ -548,6 +609,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, if (rule->tun_id) ip_tunnel_need_metadata(); + call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule, ops); notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid); flush_route_cache(ops); rules_ops_put(ops); @@ -687,6 +749,7 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, } } + call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule, ops); notify_rule_change(RTM_DELRULE, rule, ops, nlh, NETLINK_CB(skb).portid); fib_rule_put(rule); @@ -963,9 +1026,9 @@ static struct pernet_operations fib_rules_net_ops = { static int __init fib_rules_init(void) { int err; - rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule, NULL); + rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule, 0); err = register_pernet_subsys(&fib_rules_net_ops); if (err < 0) diff --git a/net/core/filter.c b/net/core/filter.c index f44fc22fd45aca4941c618abf97eb48494a67c16..74b8c91fb5f4461da58c73568976bc9834c4612b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -55,6 +55,7 @@ #include #include #include +#include /** * sk_filter_trim_cap - run a packet through a socket filter @@ -513,14 +514,27 @@ static int bpf_convert_filter(struct sock_filter *prog, int len, break; } - /* Convert JEQ into JNE when 'jump_true' is next insn. */ - if (fp->jt == 0 && BPF_OP(fp->code) == BPF_JEQ) { - insn->code = BPF_JMP | BPF_JNE | bpf_src; + /* Convert some jumps when 'jump_true' is next insn. */ + if (fp->jt == 0) { + switch (BPF_OP(fp->code)) { + case BPF_JEQ: + insn->code = BPF_JMP | BPF_JNE | bpf_src; + break; + case BPF_JGT: + insn->code = BPF_JMP | BPF_JLE | bpf_src; + break; + case BPF_JGE: + insn->code = BPF_JMP | BPF_JLT | bpf_src; + break; + default: + goto jmp_rest; + } + target = i + fp->jf + 1; BPF_EMIT_JMP; break; } - +jmp_rest: /* Other jumps are mapped into two insns: Jxx and JA. */ target = i + fp->jt + 1; insn->code = BPF_JMP | BPF_OP(fp->code) | bpf_src; @@ -975,10 +989,14 @@ static bool __sk_filter_charge(struct sock *sk, struct sk_filter *fp) bool sk_filter_charge(struct sock *sk, struct sk_filter *fp) { - bool ret = __sk_filter_charge(sk, fp); - if (ret) - refcount_inc(&fp->refcnt); - return ret; + if (!refcount_inc_not_zero(&fp->refcnt)) + return false; + + if (!__sk_filter_charge(sk, fp)) { + sk_filter_release(fp); + return false; + } + return true; } static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp) @@ -1778,6 +1796,9 @@ static const struct bpf_func_proto bpf_clone_redirect_proto = { struct redirect_info { u32 ifindex; u32 flags; + struct bpf_map *map; + struct bpf_map *map_to_flush; + unsigned long map_owner; }; static DEFINE_PER_CPU(struct redirect_info, redirect_info); @@ -1818,6 +1839,45 @@ static const struct bpf_func_proto bpf_redirect_proto = { .arg2_type = ARG_ANYTHING, }; +BPF_CALL_3(bpf_sk_redirect_map, struct bpf_map *, map, u32, key, u64, flags) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + + if (unlikely(flags)) + return SK_ABORTED; + + ri->ifindex = key; + ri->flags = flags; + ri->map = map; + + return SK_REDIRECT; +} + +struct sock *do_sk_redirect_map(void) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + struct sock *sk = NULL; + + if (ri->map) { + sk = __sock_map_lookup_elem(ri->map, ri->ifindex); + + ri->ifindex = 0; + ri->map = NULL; + /* we do not clear flags for future lookup */ + } + + return sk; +} + +static const struct bpf_func_proto bpf_sk_redirect_map_proto = { + .func = bpf_sk_redirect_map, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_CONST_MAP_PTR, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_ANYTHING, +}; + BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb) { return task_get_classid(skb); @@ -2024,8 +2084,8 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) return ret; if (skb_is_gso(skb)) { - /* SKB_GSO_UDP stays as is. SKB_GSO_TCPV4 needs to - * be changed into SKB_GSO_TCPV6. + /* SKB_GSO_TCPV4 needs to be changed into + * SKB_GSO_TCPV6. */ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV4; @@ -2060,8 +2120,8 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) return ret; if (skb_is_gso(skb)) { - /* SKB_GSO_UDP stays as is. SKB_GSO_TCPV6 needs to - * be changed into SKB_GSO_TCPV4. + /* SKB_GSO_TCPV6 needs to be changed into + * SKB_GSO_TCPV4. */ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV6; @@ -2412,6 +2472,217 @@ static const struct bpf_func_proto bpf_xdp_adjust_head_proto = { .arg2_type = ARG_ANYTHING, }; +static int __bpf_tx_xdp(struct net_device *dev, + struct bpf_map *map, + struct xdp_buff *xdp, + u32 index) +{ + int err; + + if (!dev->netdev_ops->ndo_xdp_xmit) { + return -EOPNOTSUPP; + } + + err = dev->netdev_ops->ndo_xdp_xmit(dev, xdp); + if (err) + return err; + if (map) + __dev_map_insert_ctx(map, index); + else + dev->netdev_ops->ndo_xdp_flush(dev); + return 0; +} + +void xdp_do_flush_map(void) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + struct bpf_map *map = ri->map_to_flush; + + ri->map_to_flush = NULL; + if (map) + __dev_map_flush(map); +} +EXPORT_SYMBOL_GPL(xdp_do_flush_map); + +static inline bool xdp_map_invalid(const struct bpf_prog *xdp_prog, + unsigned long aux) +{ + return (unsigned long)xdp_prog->aux != aux; +} + +static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp, + struct bpf_prog *xdp_prog) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + unsigned long map_owner = ri->map_owner; + struct bpf_map *map = ri->map; + struct net_device *fwd = NULL; + u32 index = ri->ifindex; + int err; + + ri->ifindex = 0; + ri->map = NULL; + ri->map_owner = 0; + + if (unlikely(xdp_map_invalid(xdp_prog, map_owner))) { + err = -EFAULT; + map = NULL; + goto err; + } + + fwd = __dev_map_lookup_elem(map, index); + if (!fwd) { + err = -EINVAL; + goto err; + } + if (ri->map_to_flush && ri->map_to_flush != map) + xdp_do_flush_map(); + + err = __bpf_tx_xdp(fwd, map, xdp, index); + if (unlikely(err)) + goto err; + + ri->map_to_flush = map; + _trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index); + return 0; +err: + _trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err); + return err; +} + +int xdp_do_redirect(struct net_device *dev, struct xdp_buff *xdp, + struct bpf_prog *xdp_prog) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + struct net_device *fwd; + u32 index = ri->ifindex; + int err; + + if (ri->map) + return xdp_do_redirect_map(dev, xdp, xdp_prog); + + fwd = dev_get_by_index_rcu(dev_net(dev), index); + ri->ifindex = 0; + if (unlikely(!fwd)) { + err = -EINVAL; + goto err; + } + + err = __bpf_tx_xdp(fwd, NULL, xdp, 0); + if (unlikely(err)) + goto err; + + _trace_xdp_redirect(dev, xdp_prog, index); + return 0; +err: + _trace_xdp_redirect_err(dev, xdp_prog, index, err); + return err; +} +EXPORT_SYMBOL_GPL(xdp_do_redirect); + +int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb, + struct bpf_prog *xdp_prog) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + unsigned long map_owner = ri->map_owner; + struct bpf_map *map = ri->map; + struct net_device *fwd = NULL; + u32 index = ri->ifindex; + unsigned int len; + int err = 0; + + ri->ifindex = 0; + ri->map = NULL; + ri->map_owner = 0; + + if (map) { + if (unlikely(xdp_map_invalid(xdp_prog, map_owner))) { + err = -EFAULT; + map = NULL; + goto err; + } + fwd = __dev_map_lookup_elem(map, index); + } else { + fwd = dev_get_by_index_rcu(dev_net(dev), index); + } + if (unlikely(!fwd)) { + err = -EINVAL; + goto err; + } + + if (unlikely(!(fwd->flags & IFF_UP))) { + err = -ENETDOWN; + goto err; + } + + len = fwd->mtu + fwd->hard_header_len + VLAN_HLEN; + if (skb->len > len) { + err = -EMSGSIZE; + goto err; + } + + skb->dev = fwd; + map ? _trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index) + : _trace_xdp_redirect(dev, xdp_prog, index); + return 0; +err: + map ? _trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err) + : _trace_xdp_redirect_err(dev, xdp_prog, index, err); + return err; +} +EXPORT_SYMBOL_GPL(xdp_do_generic_redirect); + +BPF_CALL_2(bpf_xdp_redirect, u32, ifindex, u64, flags) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + + if (unlikely(flags)) + return XDP_ABORTED; + + ri->ifindex = ifindex; + ri->flags = flags; + ri->map = NULL; + ri->map_owner = 0; + + return XDP_REDIRECT; +} + +static const struct bpf_func_proto bpf_xdp_redirect_proto = { + .func = bpf_xdp_redirect, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_ANYTHING, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_4(bpf_xdp_redirect_map, struct bpf_map *, map, u32, ifindex, u64, flags, + unsigned long, map_owner) +{ + struct redirect_info *ri = this_cpu_ptr(&redirect_info); + + if (unlikely(flags)) + return XDP_ABORTED; + + ri->ifindex = ifindex; + ri->flags = flags; + ri->map = map; + ri->map_owner = map_owner; + + return XDP_REDIRECT; +} + +/* Note, arg4 is hidden from users and populated by the verifier + * with the right pointer. + */ +static const struct bpf_func_proto bpf_xdp_redirect_map_proto = { + .func = bpf_xdp_redirect_map, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_CONST_MAP_PTR, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_ANYTHING, +}; + bool bpf_helper_changes_pkt_data(void *func) { if (func == bpf_skb_vlan_push || @@ -2836,15 +3107,12 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, sk->sk_prot->setsockopt == tcp_setsockopt) { if (optname == TCP_CONGESTION) { char name[TCP_CA_NAME_MAX]; + bool reinit = bpf_sock->op > BPF_SOCK_OPS_NEEDS_ECN; strncpy(name, optval, min_t(long, optlen, TCP_CA_NAME_MAX-1)); name[TCP_CA_NAME_MAX-1] = 0; - ret = tcp_set_congestion_control(sk, name, false); - if (!ret && bpf_sock->op > BPF_SOCK_OPS_NEEDS_ECN) - /* replacing an existing ca */ - tcp_reinit_congestion_control(sk, - inet_csk(sk)->icsk_ca_ops); + ret = tcp_set_congestion_control(sk, name, false, reinit); } else { struct tcp_sock *tp = tcp_sk(sk); @@ -2872,7 +3140,6 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, ret = -EINVAL; } } - ret = -EINVAL; #endif } else { ret = -EINVAL; @@ -2919,6 +3186,20 @@ bpf_base_func_proto(enum bpf_func_id func_id) } } +static const struct bpf_func_proto * +sock_filter_func_proto(enum bpf_func_id func_id) +{ + switch (func_id) { + /* inet and inet6 sockets are created in a process + * context so there is always a valid uid/gid + */ + case BPF_FUNC_get_current_uid_gid: + return &bpf_get_current_uid_gid_proto; + default: + return bpf_base_func_proto(func_id); + } +} + static const struct bpf_func_proto * sk_filter_func_proto(enum bpf_func_id func_id) { @@ -3011,6 +3292,10 @@ xdp_func_proto(enum bpf_func_id func_id) return &bpf_get_smp_processor_id_proto; case BPF_FUNC_xdp_adjust_head: return &bpf_xdp_adjust_head_proto; + case BPF_FUNC_redirect: + return &bpf_xdp_redirect_proto; + case BPF_FUNC_redirect_map: + return &bpf_xdp_redirect_map_proto; default: return bpf_base_func_proto(func_id); } @@ -3049,6 +3334,32 @@ static const struct bpf_func_proto * switch (func_id) { case BPF_FUNC_setsockopt: return &bpf_setsockopt_proto; + case BPF_FUNC_sock_map_update: + return &bpf_sock_map_update_proto; + default: + return bpf_base_func_proto(func_id); + } +} + +static const struct bpf_func_proto *sk_skb_func_proto(enum bpf_func_id func_id) +{ + switch (func_id) { + case BPF_FUNC_skb_store_bytes: + return &bpf_skb_store_bytes_proto; + case BPF_FUNC_skb_load_bytes: + return &bpf_skb_load_bytes_proto; + case BPF_FUNC_skb_pull_data: + return &bpf_skb_pull_data_proto; + case BPF_FUNC_skb_change_tail: + return &bpf_skb_change_tail_proto; + case BPF_FUNC_skb_change_head: + return &bpf_skb_change_head_proto; + case BPF_FUNC_get_socket_cookie: + return &bpf_get_socket_cookie_proto; + case BPF_FUNC_get_socket_uid: + return &bpf_get_socket_uid_proto; + case BPF_FUNC_sk_redirect_map: + return &bpf_sk_redirect_map_proto; default: return bpf_base_func_proto(func_id); } @@ -3106,6 +3417,10 @@ static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type if (off + size > offsetofend(struct __sk_buff, cb[4])) return false; break; + case bpf_ctx_range_till(struct __sk_buff, remote_ip6[0], remote_ip6[3]): + case bpf_ctx_range_till(struct __sk_buff, local_ip6[0], local_ip6[3]): + case bpf_ctx_range_till(struct __sk_buff, remote_ip4, remote_ip4): + case bpf_ctx_range_till(struct __sk_buff, local_ip4, local_ip4): case bpf_ctx_range(struct __sk_buff, data): case bpf_ctx_range(struct __sk_buff, data_end): if (size != size_default) @@ -3134,6 +3449,7 @@ static bool sk_filter_is_valid_access(int off, int size, case bpf_ctx_range(struct __sk_buff, tc_classid): case bpf_ctx_range(struct __sk_buff, data): case bpf_ctx_range(struct __sk_buff, data_end): + case bpf_ctx_range_till(struct __sk_buff, family, local_port): return false; } @@ -3155,6 +3471,7 @@ static bool lwt_is_valid_access(int off, int size, { switch (off) { case bpf_ctx_range(struct __sk_buff, tc_classid): + case bpf_ctx_range_till(struct __sk_buff, family, local_port): return false; } @@ -3188,6 +3505,8 @@ static bool sock_filter_is_valid_access(int off, int size, if (type == BPF_WRITE) { switch (off) { case offsetof(struct bpf_sock, bound_dev_if): + case offsetof(struct bpf_sock, mark): + case offsetof(struct bpf_sock, priority): break; default: return false; @@ -3205,8 +3524,8 @@ static bool sock_filter_is_valid_access(int off, int size, return true; } -static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write, - const struct bpf_prog *prog) +static int bpf_unclone_prologue(struct bpf_insn *insn_buf, bool direct_write, + const struct bpf_prog *prog, int drop_verdict) { struct bpf_insn *insn = insn_buf; @@ -3233,7 +3552,7 @@ static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write, * return TC_ACT_SHOT; */ *insn++ = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2); - *insn++ = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, TC_ACT_SHOT); + *insn++ = BPF_ALU32_IMM(BPF_MOV, BPF_REG_0, drop_verdict); *insn++ = BPF_EXIT_INSN(); /* restore: */ @@ -3244,6 +3563,12 @@ static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write, return insn - insn_buf; } +static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write, + const struct bpf_prog *prog) +{ + return bpf_unclone_prologue(insn_buf, direct_write, prog, TC_ACT_SHOT); +} + static bool tc_cls_act_is_valid_access(int off, int size, enum bpf_access_type type, struct bpf_insn_access_aux *info) @@ -3268,6 +3593,8 @@ static bool tc_cls_act_is_valid_access(int off, int size, case bpf_ctx_range(struct __sk_buff, data_end): info->reg_type = PTR_TO_PACKET_END; break; + case bpf_ctx_range_till(struct __sk_buff, family, local_port): + return false; } return bpf_skb_is_valid_access(off, size, type, info); @@ -3306,7 +3633,11 @@ static bool xdp_is_valid_access(int off, int size, void bpf_warn_invalid_xdp_action(u32 act) { - WARN_ONCE(1, "Illegal XDP return value %u, expect packet loss\n", act); + const u32 act_max = XDP_REDIRECT; + + WARN_ONCE(1, "%s XDP return value %u, expect packet loss!\n", + act > act_max ? "Illegal" : "Driver unsupported", + act); } EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); @@ -3340,6 +3671,41 @@ static bool sock_ops_is_valid_access(int off, int size, return __is_valid_sock_ops_access(off, size); } +static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write, + const struct bpf_prog *prog) +{ + return bpf_unclone_prologue(insn_buf, direct_write, prog, SK_DROP); +} + +static bool sk_skb_is_valid_access(int off, int size, + enum bpf_access_type type, + struct bpf_insn_access_aux *info) +{ + if (type == BPF_WRITE) { + switch (off) { + case bpf_ctx_range(struct __sk_buff, mark): + case bpf_ctx_range(struct __sk_buff, tc_index): + case bpf_ctx_range(struct __sk_buff, priority): + break; + default: + return false; + } + } + + switch (off) { + case bpf_ctx_range(struct __sk_buff, tc_classid): + return false; + case bpf_ctx_range(struct __sk_buff, data): + info->reg_type = PTR_TO_PACKET; + break; + case bpf_ctx_range(struct __sk_buff, data_end): + info->reg_type = PTR_TO_PACKET_END; + break; + } + + return bpf_skb_is_valid_access(off, size, type, info); +} + static u32 bpf_convert_ctx_access(enum bpf_access_type type, const struct bpf_insn *si, struct bpf_insn *insn_buf, @@ -3505,6 +3871,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type, bpf_target_off(struct sk_buff, tc_index, 2, target_size)); #else + *target_size = 2; if (type == BPF_WRITE) *insn++ = BPF_MOV64_REG(si->dst_reg, si->dst_reg); else @@ -3520,9 +3887,110 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type, *insn++ = BPF_JMP_IMM(BPF_JGE, si->dst_reg, MIN_NAPI_ID, 1); *insn++ = BPF_MOV64_IMM(si->dst_reg, 0); #else + *target_size = 4; *insn++ = BPF_MOV64_IMM(si->dst_reg, 0); #endif break; + case offsetof(struct __sk_buff, family): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_family) != 2); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->dst_reg, + bpf_target_off(struct sock_common, + skc_family, + 2, target_size)); + break; + case offsetof(struct __sk_buff, remote_ip4): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_daddr) != 4); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + bpf_target_off(struct sock_common, + skc_daddr, + 4, target_size)); + break; + case offsetof(struct __sk_buff, local_ip4): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, + skc_rcv_saddr) != 4); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + bpf_target_off(struct sock_common, + skc_rcv_saddr, + 4, target_size)); + break; + case offsetof(struct __sk_buff, remote_ip6[0]) ... + offsetof(struct __sk_buff, remote_ip6[3]): +#if IS_ENABLED(CONFIG_IPV6) + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, + skc_v6_daddr.s6_addr32[0]) != 4); + + off = si->off; + off -= offsetof(struct __sk_buff, remote_ip6[0]); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + offsetof(struct sock_common, + skc_v6_daddr.s6_addr32[0]) + + off); +#else + *insn++ = BPF_MOV32_IMM(si->dst_reg, 0); +#endif + break; + case offsetof(struct __sk_buff, local_ip6[0]) ... + offsetof(struct __sk_buff, local_ip6[3]): +#if IS_ENABLED(CONFIG_IPV6) + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, + skc_v6_rcv_saddr.s6_addr32[0]) != 4); + + off = si->off; + off -= offsetof(struct __sk_buff, local_ip6[0]); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + offsetof(struct sock_common, + skc_v6_rcv_saddr.s6_addr32[0]) + + off); +#else + *insn++ = BPF_MOV32_IMM(si->dst_reg, 0); +#endif + break; + + case offsetof(struct __sk_buff, remote_port): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_dport) != 2); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->dst_reg, + bpf_target_off(struct sock_common, + skc_dport, + 2, target_size)); +#ifndef __BIG_ENDIAN_BITFIELD + *insn++ = BPF_ALU32_IMM(BPF_LSH, si->dst_reg, 16); +#endif + break; + + case offsetof(struct __sk_buff, local_port): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_num) != 2); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, sk), + si->dst_reg, si->src_reg, + offsetof(struct sk_buff, sk)); + *insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->dst_reg, + bpf_target_off(struct sock_common, + skc_num, 2, target_size)); + break; } return insn - insn_buf; @@ -3547,6 +4015,28 @@ static u32 sock_filter_convert_ctx_access(enum bpf_access_type type, offsetof(struct sock, sk_bound_dev_if)); break; + case offsetof(struct bpf_sock, mark): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_mark) != 4); + + if (type == BPF_WRITE) + *insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg, + offsetof(struct sock, sk_mark)); + else + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, + offsetof(struct sock, sk_mark)); + break; + + case offsetof(struct bpf_sock, priority): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_priority) != 4); + + if (type == BPF_WRITE) + *insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg, + offsetof(struct sock, sk_priority)); + else + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg, + offsetof(struct sock, sk_priority)); + break; + case offsetof(struct bpf_sock, family): BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_family) != 2); @@ -3796,7 +4286,7 @@ const struct bpf_verifier_ops lwt_xmit_prog_ops = { }; const struct bpf_verifier_ops cg_sock_prog_ops = { - .get_func_proto = bpf_base_func_proto, + .get_func_proto = sock_filter_func_proto, .is_valid_access = sock_filter_is_valid_access, .convert_ctx_access = sock_filter_convert_ctx_access, }; @@ -3807,6 +4297,13 @@ const struct bpf_verifier_ops sock_ops_prog_ops = { .convert_ctx_access = sock_ops_convert_ctx_access, }; +const struct bpf_verifier_ops sk_skb_prog_ops = { + .get_func_proto = sk_skb_func_proto, + .is_valid_access = sk_skb_is_valid_access, + .convert_ctx_access = bpf_convert_ctx_access, + .gen_prologue = sk_skb_prologue, +}; + int sk_detach_filter(struct sock *sk) { int ret = -ENOENT; diff --git a/net/core/flow.c b/net/core/flow.c deleted file mode 100644 index f7f5d1932a2720767dd31f4033f196815ff08447..0000000000000000000000000000000000000000 --- a/net/core/flow.c +++ /dev/null @@ -1,516 +0,0 @@ -/* flow.c: Generic flow cache. - * - * Copyright (C) 2003 Alexey N. Kuznetsov (kuznet@ms2.inr.ac.ru) - * Copyright (C) 2003 David S. Miller (davem@redhat.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct flow_cache_entry { - union { - struct hlist_node hlist; - struct list_head gc_list; - } u; - struct net *net; - u16 family; - u8 dir; - u32 genid; - struct flowi key; - struct flow_cache_object *object; -}; - -struct flow_flush_info { - struct flow_cache *cache; - atomic_t cpuleft; - struct completion completion; -}; - -static struct kmem_cache *flow_cachep __read_mostly; - -#define flow_cache_hash_size(cache) (1U << (cache)->hash_shift) -#define FLOW_HASH_RND_PERIOD (10 * 60 * HZ) - -static void flow_cache_new_hashrnd(unsigned long arg) -{ - struct flow_cache *fc = (void *) arg; - int i; - - for_each_possible_cpu(i) - per_cpu_ptr(fc->percpu, i)->hash_rnd_recalc = 1; - - fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; - add_timer(&fc->rnd_timer); -} - -static int flow_entry_valid(struct flow_cache_entry *fle, - struct netns_xfrm *xfrm) -{ - if (atomic_read(&xfrm->flow_cache_genid) != fle->genid) - return 0; - if (fle->object && !fle->object->ops->check(fle->object)) - return 0; - return 1; -} - -static void flow_entry_kill(struct flow_cache_entry *fle, - struct netns_xfrm *xfrm) -{ - if (fle->object) - fle->object->ops->delete(fle->object); - kmem_cache_free(flow_cachep, fle); -} - -static void flow_cache_gc_task(struct work_struct *work) -{ - struct list_head gc_list; - struct flow_cache_entry *fce, *n; - struct netns_xfrm *xfrm = container_of(work, struct netns_xfrm, - flow_cache_gc_work); - - INIT_LIST_HEAD(&gc_list); - spin_lock_bh(&xfrm->flow_cache_gc_lock); - list_splice_tail_init(&xfrm->flow_cache_gc_list, &gc_list); - spin_unlock_bh(&xfrm->flow_cache_gc_lock); - - list_for_each_entry_safe(fce, n, &gc_list, u.gc_list) { - flow_entry_kill(fce, xfrm); - atomic_dec(&xfrm->flow_cache_gc_count); - } -} - -static void flow_cache_queue_garbage(struct flow_cache_percpu *fcp, - unsigned int deleted, - struct list_head *gc_list, - struct netns_xfrm *xfrm) -{ - if (deleted) { - atomic_add(deleted, &xfrm->flow_cache_gc_count); - fcp->hash_count -= deleted; - spin_lock_bh(&xfrm->flow_cache_gc_lock); - list_splice_tail(gc_list, &xfrm->flow_cache_gc_list); - spin_unlock_bh(&xfrm->flow_cache_gc_lock); - schedule_work(&xfrm->flow_cache_gc_work); - } -} - -static void __flow_cache_shrink(struct flow_cache *fc, - struct flow_cache_percpu *fcp, - unsigned int shrink_to) -{ - struct flow_cache_entry *fle; - struct hlist_node *tmp; - LIST_HEAD(gc_list); - unsigned int deleted = 0; - struct netns_xfrm *xfrm = container_of(fc, struct netns_xfrm, - flow_cache_global); - unsigned int i; - - for (i = 0; i < flow_cache_hash_size(fc); i++) { - unsigned int saved = 0; - - hlist_for_each_entry_safe(fle, tmp, - &fcp->hash_table[i], u.hlist) { - if (saved < shrink_to && - flow_entry_valid(fle, xfrm)) { - saved++; - } else { - deleted++; - hlist_del(&fle->u.hlist); - list_add_tail(&fle->u.gc_list, &gc_list); - } - } - } - - flow_cache_queue_garbage(fcp, deleted, &gc_list, xfrm); -} - -static void flow_cache_shrink(struct flow_cache *fc, - struct flow_cache_percpu *fcp) -{ - unsigned int shrink_to = fc->low_watermark / flow_cache_hash_size(fc); - - __flow_cache_shrink(fc, fcp, shrink_to); -} - -static void flow_new_hash_rnd(struct flow_cache *fc, - struct flow_cache_percpu *fcp) -{ - get_random_bytes(&fcp->hash_rnd, sizeof(u32)); - fcp->hash_rnd_recalc = 0; - __flow_cache_shrink(fc, fcp, 0); -} - -static u32 flow_hash_code(struct flow_cache *fc, - struct flow_cache_percpu *fcp, - const struct flowi *key, - unsigned int keysize) -{ - const u32 *k = (const u32 *) key; - const u32 length = keysize * sizeof(flow_compare_t) / sizeof(u32); - - return jhash2(k, length, fcp->hash_rnd) - & (flow_cache_hash_size(fc) - 1); -} - -/* I hear what you're saying, use memcmp. But memcmp cannot make - * important assumptions that we can here, such as alignment. - */ -static int flow_key_compare(const struct flowi *key1, const struct flowi *key2, - unsigned int keysize) -{ - const flow_compare_t *k1, *k1_lim, *k2; - - k1 = (const flow_compare_t *) key1; - k1_lim = k1 + keysize; - - k2 = (const flow_compare_t *) key2; - - do { - if (*k1++ != *k2++) - return 1; - } while (k1 < k1_lim); - - return 0; -} - -struct flow_cache_object * -flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir, - flow_resolve_t resolver, void *ctx) -{ - struct flow_cache *fc = &net->xfrm.flow_cache_global; - struct flow_cache_percpu *fcp; - struct flow_cache_entry *fle, *tfle; - struct flow_cache_object *flo; - unsigned int keysize; - unsigned int hash; - - local_bh_disable(); - fcp = this_cpu_ptr(fc->percpu); - - fle = NULL; - flo = NULL; - - keysize = flow_key_size(family); - if (!keysize) - goto nocache; - - /* Packet really early in init? Making flow_cache_init a - * pre-smp initcall would solve this. --RR */ - if (!fcp->hash_table) - goto nocache; - - if (fcp->hash_rnd_recalc) - flow_new_hash_rnd(fc, fcp); - - hash = flow_hash_code(fc, fcp, key, keysize); - hlist_for_each_entry(tfle, &fcp->hash_table[hash], u.hlist) { - if (tfle->net == net && - tfle->family == family && - tfle->dir == dir && - flow_key_compare(key, &tfle->key, keysize) == 0) { - fle = tfle; - break; - } - } - - if (unlikely(!fle)) { - if (fcp->hash_count > fc->high_watermark) - flow_cache_shrink(fc, fcp); - - if (atomic_read(&net->xfrm.flow_cache_gc_count) > - 2 * num_online_cpus() * fc->high_watermark) { - flo = ERR_PTR(-ENOBUFS); - goto ret_object; - } - - fle = kmem_cache_alloc(flow_cachep, GFP_ATOMIC); - if (fle) { - fle->net = net; - fle->family = family; - fle->dir = dir; - memcpy(&fle->key, key, keysize * sizeof(flow_compare_t)); - fle->object = NULL; - hlist_add_head(&fle->u.hlist, &fcp->hash_table[hash]); - fcp->hash_count++; - } - } else if (likely(fle->genid == atomic_read(&net->xfrm.flow_cache_genid))) { - flo = fle->object; - if (!flo) - goto ret_object; - flo = flo->ops->get(flo); - if (flo) - goto ret_object; - } else if (fle->object) { - flo = fle->object; - flo->ops->delete(flo); - fle->object = NULL; - } - -nocache: - flo = NULL; - if (fle) { - flo = fle->object; - fle->object = NULL; - } - flo = resolver(net, key, family, dir, flo, ctx); - if (fle) { - fle->genid = atomic_read(&net->xfrm.flow_cache_genid); - if (!IS_ERR(flo)) - fle->object = flo; - else - fle->genid--; - } else { - if (!IS_ERR_OR_NULL(flo)) - flo->ops->delete(flo); - } -ret_object: - local_bh_enable(); - return flo; -} -EXPORT_SYMBOL(flow_cache_lookup); - -static void flow_cache_flush_tasklet(unsigned long data) -{ - struct flow_flush_info *info = (void *)data; - struct flow_cache *fc = info->cache; - struct flow_cache_percpu *fcp; - struct flow_cache_entry *fle; - struct hlist_node *tmp; - LIST_HEAD(gc_list); - unsigned int deleted = 0; - struct netns_xfrm *xfrm = container_of(fc, struct netns_xfrm, - flow_cache_global); - unsigned int i; - - fcp = this_cpu_ptr(fc->percpu); - for (i = 0; i < flow_cache_hash_size(fc); i++) { - hlist_for_each_entry_safe(fle, tmp, - &fcp->hash_table[i], u.hlist) { - if (flow_entry_valid(fle, xfrm)) - continue; - - deleted++; - hlist_del(&fle->u.hlist); - list_add_tail(&fle->u.gc_list, &gc_list); - } - } - - flow_cache_queue_garbage(fcp, deleted, &gc_list, xfrm); - - if (atomic_dec_and_test(&info->cpuleft)) - complete(&info->completion); -} - -/* - * Return whether a cpu needs flushing. Conservatively, we assume - * the presence of any entries means the core may require flushing, - * since the flow_cache_ops.check() function may assume it's running - * on the same core as the per-cpu cache component. - */ -static int flow_cache_percpu_empty(struct flow_cache *fc, int cpu) -{ - struct flow_cache_percpu *fcp; - unsigned int i; - - fcp = per_cpu_ptr(fc->percpu, cpu); - for (i = 0; i < flow_cache_hash_size(fc); i++) - if (!hlist_empty(&fcp->hash_table[i])) - return 0; - return 1; -} - -static void flow_cache_flush_per_cpu(void *data) -{ - struct flow_flush_info *info = data; - struct tasklet_struct *tasklet; - - tasklet = &this_cpu_ptr(info->cache->percpu)->flush_tasklet; - tasklet->data = (unsigned long)info; - tasklet_schedule(tasklet); -} - -void flow_cache_flush(struct net *net) -{ - struct flow_flush_info info; - cpumask_var_t mask; - int i, self; - - /* Track which cpus need flushing to avoid disturbing all cores. */ - if (!alloc_cpumask_var(&mask, GFP_KERNEL)) - return; - cpumask_clear(mask); - - /* Don't want cpus going down or up during this. */ - get_online_cpus(); - mutex_lock(&net->xfrm.flow_flush_sem); - info.cache = &net->xfrm.flow_cache_global; - for_each_online_cpu(i) - if (!flow_cache_percpu_empty(info.cache, i)) - cpumask_set_cpu(i, mask); - atomic_set(&info.cpuleft, cpumask_weight(mask)); - if (atomic_read(&info.cpuleft) == 0) - goto done; - - init_completion(&info.completion); - - local_bh_disable(); - self = cpumask_test_and_clear_cpu(smp_processor_id(), mask); - on_each_cpu_mask(mask, flow_cache_flush_per_cpu, &info, 0); - if (self) - flow_cache_flush_tasklet((unsigned long)&info); - local_bh_enable(); - - wait_for_completion(&info.completion); - -done: - mutex_unlock(&net->xfrm.flow_flush_sem); - put_online_cpus(); - free_cpumask_var(mask); -} - -static void flow_cache_flush_task(struct work_struct *work) -{ - struct netns_xfrm *xfrm = container_of(work, struct netns_xfrm, - flow_cache_flush_work); - struct net *net = container_of(xfrm, struct net, xfrm); - - flow_cache_flush(net); -} - -void flow_cache_flush_deferred(struct net *net) -{ - schedule_work(&net->xfrm.flow_cache_flush_work); -} - -static int flow_cache_cpu_prepare(struct flow_cache *fc, int cpu) -{ - struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); - unsigned int sz = sizeof(struct hlist_head) * flow_cache_hash_size(fc); - - if (!fcp->hash_table) { - fcp->hash_table = kzalloc_node(sz, GFP_KERNEL, cpu_to_node(cpu)); - if (!fcp->hash_table) { - pr_err("NET: failed to allocate flow cache sz %u\n", sz); - return -ENOMEM; - } - fcp->hash_rnd_recalc = 1; - fcp->hash_count = 0; - tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0); - } - return 0; -} - -static int flow_cache_cpu_up_prep(unsigned int cpu, struct hlist_node *node) -{ - struct flow_cache *fc = hlist_entry_safe(node, struct flow_cache, node); - - return flow_cache_cpu_prepare(fc, cpu); -} - -static int flow_cache_cpu_dead(unsigned int cpu, struct hlist_node *node) -{ - struct flow_cache *fc = hlist_entry_safe(node, struct flow_cache, node); - struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); - - __flow_cache_shrink(fc, fcp, 0); - return 0; -} - -int flow_cache_init(struct net *net) -{ - int i; - struct flow_cache *fc = &net->xfrm.flow_cache_global; - - if (!flow_cachep) - flow_cachep = kmem_cache_create("flow_cache", - sizeof(struct flow_cache_entry), - 0, SLAB_PANIC, NULL); - spin_lock_init(&net->xfrm.flow_cache_gc_lock); - INIT_LIST_HEAD(&net->xfrm.flow_cache_gc_list); - INIT_WORK(&net->xfrm.flow_cache_gc_work, flow_cache_gc_task); - INIT_WORK(&net->xfrm.flow_cache_flush_work, flow_cache_flush_task); - mutex_init(&net->xfrm.flow_flush_sem); - atomic_set(&net->xfrm.flow_cache_gc_count, 0); - - fc->hash_shift = 10; - fc->low_watermark = 2 * flow_cache_hash_size(fc); - fc->high_watermark = 4 * flow_cache_hash_size(fc); - - fc->percpu = alloc_percpu(struct flow_cache_percpu); - if (!fc->percpu) - return -ENOMEM; - - if (cpuhp_state_add_instance(CPUHP_NET_FLOW_PREPARE, &fc->node)) - goto err; - - setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd, - (unsigned long) fc); - fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; - add_timer(&fc->rnd_timer); - - return 0; - -err: - for_each_possible_cpu(i) { - struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, i); - kfree(fcp->hash_table); - fcp->hash_table = NULL; - } - - free_percpu(fc->percpu); - fc->percpu = NULL; - - return -ENOMEM; -} -EXPORT_SYMBOL(flow_cache_init); - -void flow_cache_fini(struct net *net) -{ - int i; - struct flow_cache *fc = &net->xfrm.flow_cache_global; - - del_timer_sync(&fc->rnd_timer); - - cpuhp_state_remove_instance_nocalls(CPUHP_NET_FLOW_PREPARE, &fc->node); - - for_each_possible_cpu(i) { - struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, i); - kfree(fcp->hash_table); - fcp->hash_table = NULL; - } - - free_percpu(fc->percpu); - fc->percpu = NULL; -} -EXPORT_SYMBOL(flow_cache_fini); - -void __init flow_cache_hp_init(void) -{ - int ret; - - ret = cpuhp_setup_state_multi(CPUHP_NET_FLOW_PREPARE, - "net/flow:prepare", - flow_cache_cpu_up_prep, - flow_cache_cpu_dead); - WARN_ON(ret < 0); -} diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index fc5fc4594c908049c5141858338848c8d12eb0d5..0a977373d0033a1bffc81effd5ceb22f84515e0e 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -114,12 +115,6 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto, } EXPORT_SYMBOL(__skb_flow_get_ports); -enum flow_dissect_ret { - FLOW_DISSECT_RET_OUT_GOOD, - FLOW_DISSECT_RET_OUT_BAD, - FLOW_DISSECT_RET_OUT_PROTO_AGAIN, -}; - static enum flow_dissect_ret __skb_flow_dissect_mpls(const struct sk_buff *skb, struct flow_dissector *flow_dissector, @@ -340,7 +335,7 @@ __skb_flow_dissect_gre(const struct sk_buff *skb, if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) return FLOW_DISSECT_RET_OUT_GOOD; - return FLOW_DISSECT_RET_OUT_PROTO_AGAIN; + return FLOW_DISSECT_RET_PROTO_AGAIN; } static void @@ -401,6 +396,18 @@ __skb_flow_dissect_ipv6(const struct sk_buff *skb, key_ip->ttl = iph->hop_limit; } +/* Maximum number of protocol headers that can be parsed in + * __skb_flow_dissect + */ +#define MAX_FLOW_DISSECT_HDRS 15 + +static bool skb_flow_dissect_allowed(int *num_hdrs) +{ + ++*num_hdrs; + + return (*num_hdrs <= MAX_FLOW_DISSECT_HDRS); +} + /** * __skb_flow_dissect - extract the flow_keys struct and return it * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified @@ -430,7 +437,9 @@ bool __skb_flow_dissect(const struct sk_buff *skb, struct flow_dissector_key_icmp *key_icmp; struct flow_dissector_key_tags *key_tags; struct flow_dissector_key_vlan *key_vlan; + enum flow_dissect_ret fdret; bool skip_vlan = false; + int num_hdrs = 0; u8 ip_proto = 0; bool ret; @@ -440,6 +449,19 @@ bool __skb_flow_dissect(const struct sk_buff *skb, skb->vlan_proto : skb->protocol; nhoff = skb_network_offset(skb); hlen = skb_headlen(skb); +#if IS_ENABLED(CONFIG_NET_DSA) + if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) { + const struct dsa_device_ops *ops; + int offset; + + ops = skb->dev->dsa_ptr->tag_ops; + if (ops->flow_dissect && + !ops->flow_dissect(skb, &proto, &offset)) { + hlen -= offset; + nhoff += offset; + } + } +#endif } /* It is ensured by skb_flow_dissector_init() that control key will @@ -468,14 +490,19 @@ bool __skb_flow_dissect(const struct sk_buff *skb, } proto_again: + fdret = FLOW_DISSECT_RET_CONTINUE; + switch (proto) { case htons(ETH_P_IP): { const struct iphdr *iph; struct iphdr _iph; -ip: + iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph); - if (!iph || iph->ihl < 5) - goto out_bad; + if (!iph || iph->ihl < 5) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } + nhoff += iph->ihl * 4; ip_proto = iph->protocol; @@ -495,19 +522,25 @@ bool __skb_flow_dissect(const struct sk_buff *skb, key_control->flags |= FLOW_DIS_IS_FRAGMENT; if (iph->frag_off & htons(IP_OFFSET)) { - goto out_good; + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; } else { key_control->flags |= FLOW_DIS_FIRST_FRAG; - if (!(flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) - goto out_good; + if (!(flags & + FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) { + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; + } } } __skb_flow_dissect_ipv4(skb, flow_dissector, target_container, data, iph); - if (flags & FLOW_DISSECTOR_F_STOP_AT_L3) - goto out_good; + if (flags & FLOW_DISSECTOR_F_STOP_AT_L3) { + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; + } break; } @@ -515,10 +548,11 @@ bool __skb_flow_dissect(const struct sk_buff *skb, const struct ipv6hdr *iph; struct ipv6hdr _iph; -ipv6: iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph); - if (!iph) - goto out_bad; + if (!iph) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } ip_proto = iph->nexthdr; nhoff += sizeof(struct ipv6hdr); @@ -547,15 +581,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb, target_container); key_tags->flow_label = ntohl(flow_label); } - if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) - goto out_good; + if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) { + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; + } } __skb_flow_dissect_ipv6(skb, flow_dissector, target_container, data, iph); if (flags & FLOW_DISSECTOR_F_STOP_AT_L3) - goto out_good; + fdret = FLOW_DISSECT_RET_OUT_GOOD; break; } @@ -571,12 +607,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb, if (!vlan_tag_present || eth_type_vlan(skb->protocol)) { vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan); - if (!vlan) - goto out_bad; + if (!vlan) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } + proto = vlan->h_vlan_encapsulated_proto; nhoff += sizeof(*vlan); - if (skip_vlan) - goto proto_again; + if (skip_vlan) { + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; + } } skip_vlan = true; @@ -599,7 +640,8 @@ bool __skb_flow_dissect(const struct sk_buff *skb, } } - goto proto_again; + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; } case htons(ETH_P_PPP_SES): { struct { @@ -607,18 +649,27 @@ bool __skb_flow_dissect(const struct sk_buff *skb, __be16 proto; } *hdr, _hdr; hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr); - if (!hdr) - goto out_bad; + if (!hdr) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } + proto = hdr->proto; nhoff += PPPOE_SES_HLEN; switch (proto) { case htons(PPP_IP): - goto ip; + proto = htons(ETH_P_IP); + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; case htons(PPP_IPV6): - goto ipv6; + proto = htons(ETH_P_IPV6); + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; default: - goto out_bad; + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; } + break; } case htons(ETH_P_TIPC): { struct { @@ -626,8 +677,10 @@ bool __skb_flow_dissect(const struct sk_buff *skb, __be32 srcnode; } *hdr, _hdr; hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr); - if (!hdr) - goto out_bad; + if (!hdr) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_TIPC_ADDRS)) { @@ -637,56 +690,64 @@ bool __skb_flow_dissect(const struct sk_buff *skb, key_addrs->tipcaddrs.srcnode = hdr->srcnode; key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS; } - goto out_good; + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; } case htons(ETH_P_MPLS_UC): case htons(ETH_P_MPLS_MC): -mpls: - switch (__skb_flow_dissect_mpls(skb, flow_dissector, + fdret = __skb_flow_dissect_mpls(skb, flow_dissector, target_container, data, - nhoff, hlen)) { - case FLOW_DISSECT_RET_OUT_GOOD: - goto out_good; - case FLOW_DISSECT_RET_OUT_BAD: - default: - goto out_bad; - } + nhoff, hlen); + break; case htons(ETH_P_FCOE): - if ((hlen - nhoff) < FCOE_HEADER_LEN) - goto out_bad; + if ((hlen - nhoff) < FCOE_HEADER_LEN) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } nhoff += FCOE_HEADER_LEN; - goto out_good; + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; case htons(ETH_P_ARP): case htons(ETH_P_RARP): - switch (__skb_flow_dissect_arp(skb, flow_dissector, + fdret = __skb_flow_dissect_arp(skb, flow_dissector, target_container, data, - nhoff, hlen)) { - case FLOW_DISSECT_RET_OUT_GOOD: - goto out_good; - case FLOW_DISSECT_RET_OUT_BAD: - default: - goto out_bad; - } + nhoff, hlen); + break; + + default: + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } + + /* Process result of proto processing */ + switch (fdret) { + case FLOW_DISSECT_RET_OUT_GOOD: + goto out_good; + case FLOW_DISSECT_RET_PROTO_AGAIN: + if (skb_flow_dissect_allowed(&num_hdrs)) + goto proto_again; + goto out_good; + case FLOW_DISSECT_RET_CONTINUE: + case FLOW_DISSECT_RET_IPPROTO_AGAIN: + break; + case FLOW_DISSECT_RET_OUT_BAD: default: goto out_bad; } ip_proto_again: + fdret = FLOW_DISSECT_RET_CONTINUE; + switch (ip_proto) { case IPPROTO_GRE: - switch (__skb_flow_dissect_gre(skb, key_control, flow_dissector, + fdret = __skb_flow_dissect_gre(skb, key_control, flow_dissector, target_container, data, - &proto, &nhoff, &hlen, flags)) { - case FLOW_DISSECT_RET_OUT_GOOD: - goto out_good; - case FLOW_DISSECT_RET_OUT_BAD: - goto out_bad; - case FLOW_DISSECT_RET_OUT_PROTO_AGAIN: - goto proto_again; - } + &proto, &nhoff, &hlen, flags); + break; + case NEXTHDR_HOP: case NEXTHDR_ROUTING: case NEXTHDR_DEST: { @@ -697,13 +758,16 @@ bool __skb_flow_dissect(const struct sk_buff *skb, opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr), data, hlen, &_opthdr); - if (!opthdr) - goto out_bad; + if (!opthdr) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } ip_proto = opthdr[0]; nhoff += (opthdr[1] + 1) << 3; - goto ip_proto_again; + fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN; + break; } case NEXTHDR_FRAGMENT: { struct frag_hdr _fh, *fh; @@ -714,8 +778,10 @@ bool __skb_flow_dissect(const struct sk_buff *skb, fh = __skb_header_pointer(skb, nhoff, sizeof(_fh), data, hlen, &_fh); - if (!fh) - goto out_bad; + if (!fh) { + fdret = FLOW_DISSECT_RET_OUT_BAD; + break; + } key_control->flags |= FLOW_DIS_IS_FRAGMENT; @@ -724,34 +790,50 @@ bool __skb_flow_dissect(const struct sk_buff *skb, if (!(fh->frag_off & htons(IP6_OFFSET))) { key_control->flags |= FLOW_DIS_FIRST_FRAG; - if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) - goto ip_proto_again; + if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) { + fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN; + break; + } } - goto out_good; + + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; } case IPPROTO_IPIP: proto = htons(ETH_P_IP); key_control->flags |= FLOW_DIS_ENCAPSULATION; - if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) - goto out_good; + if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) { + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; + } + + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; - goto ip; case IPPROTO_IPV6: proto = htons(ETH_P_IPV6); key_control->flags |= FLOW_DIS_ENCAPSULATION; - if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) - goto out_good; + if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) { + fdret = FLOW_DISSECT_RET_OUT_GOOD; + break; + } + + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; + - goto ipv6; case IPPROTO_MPLS: proto = htons(ETH_P_MPLS_UC); - goto mpls; + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; + case IPPROTO_TCP: __skb_flow_dissect_tcp(skb, flow_dissector, target_container, data, nhoff, hlen); break; + default: break; } @@ -773,6 +855,24 @@ bool __skb_flow_dissect(const struct sk_buff *skb, key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen); } + /* Process result of IP proto processing */ + switch (fdret) { + case FLOW_DISSECT_RET_PROTO_AGAIN: + if (skb_flow_dissect_allowed(&num_hdrs)) + goto proto_again; + break; + case FLOW_DISSECT_RET_IPPROTO_AGAIN: + if (skb_flow_dissect_allowed(&num_hdrs)) + goto ip_proto_again; + break; + case FLOW_DISSECT_RET_OUT_GOOD: + case FLOW_DISSECT_RET_CONTINUE: + break; + case FLOW_DISSECT_RET_OUT_BAD: + default: + goto out_bad; + } + out_good: ret = true; @@ -998,51 +1098,6 @@ __u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb) } EXPORT_SYMBOL(skb_get_hash_perturb); -__u32 __skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 *fl6) -{ - struct flow_keys keys; - - memset(&keys, 0, sizeof(keys)); - - memcpy(&keys.addrs.v6addrs.src, &fl6->saddr, - sizeof(keys.addrs.v6addrs.src)); - memcpy(&keys.addrs.v6addrs.dst, &fl6->daddr, - sizeof(keys.addrs.v6addrs.dst)); - keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; - keys.ports.src = fl6->fl6_sport; - keys.ports.dst = fl6->fl6_dport; - keys.keyid.keyid = fl6->fl6_gre_key; - keys.tags.flow_label = (__force u32)fl6->flowlabel; - keys.basic.ip_proto = fl6->flowi6_proto; - - __skb_set_sw_hash(skb, flow_hash_from_keys(&keys), - flow_keys_have_l4(&keys)); - - return skb->hash; -} -EXPORT_SYMBOL(__skb_get_hash_flowi6); - -__u32 __skb_get_hash_flowi4(struct sk_buff *skb, const struct flowi4 *fl4) -{ - struct flow_keys keys; - - memset(&keys, 0, sizeof(keys)); - - keys.addrs.v4addrs.src = fl4->saddr; - keys.addrs.v4addrs.dst = fl4->daddr; - keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; - keys.ports.src = fl4->fl4_sport; - keys.ports.dst = fl4->fl4_dport; - keys.keyid.keyid = fl4->fl4_gre_key; - keys.basic.ip_proto = fl4->flowi4_proto; - - __skb_set_sw_hash(skb, flow_hash_from_keys(&keys), - flow_keys_have_l4(&keys)); - - return skb->hash; -} -EXPORT_SYMBOL(__skb_get_hash_flowi4); - u32 __skb_get_poff(const struct sk_buff *skb, void *data, const struct flow_keys *keys, int hlen) { diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 0385dece1f6fe5e26df1ce5f40956a79a2eebbf4..7c1ffd6f950172c1915d8e5fa2b5e3f77e4f4c78 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -83,10 +83,10 @@ static void est_timer(unsigned long arg) u64 rate, brate; est_fetch_counters(est, &b); - brate = (b.bytes - est->last_bytes) << (8 - est->ewma_log); + brate = (b.bytes - est->last_bytes) << (10 - est->ewma_log - est->intvl_log); brate -= (est->avbps >> est->ewma_log); - rate = (u64)(b.packets - est->last_packets) << (8 - est->ewma_log); + rate = (u64)(b.packets - est->last_packets) << (10 - est->ewma_log - est->intvl_log); rate -= (est->avpps >> est->ewma_log); write_seqcount_begin(&est->seq); diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index d9cb3532f1ddc85ead8e14cba075d72a2b6c47df..0b171756453c878ec613b0d4db91a7f657fba159 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c @@ -44,6 +44,8 @@ static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type) return "SEG6"; case LWTUNNEL_ENCAP_BPF: return "BPF"; + case LWTUNNEL_ENCAP_SEG6_LOCAL: + return "SEG6LOCAL"; case LWTUNNEL_ENCAP_IP6: case LWTUNNEL_ENCAP_IP: case LWTUNNEL_ENCAP_NONE: @@ -65,7 +67,7 @@ struct lwtunnel_state *lwtunnel_state_alloc(int encap_len) return lws; } -EXPORT_SYMBOL(lwtunnel_state_alloc); +EXPORT_SYMBOL_GPL(lwtunnel_state_alloc); static const struct lwtunnel_encap_ops __rcu * lwtun_encaps[LWTUNNEL_ENCAP_MAX + 1] __read_mostly; @@ -80,7 +82,7 @@ int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *ops, &lwtun_encaps[num], NULL, ops) ? 0 : -1; } -EXPORT_SYMBOL(lwtunnel_encap_add_ops); +EXPORT_SYMBOL_GPL(lwtunnel_encap_add_ops); int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *ops, unsigned int encap_type) @@ -99,7 +101,7 @@ int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *ops, return ret; } -EXPORT_SYMBOL(lwtunnel_encap_del_ops); +EXPORT_SYMBOL_GPL(lwtunnel_encap_del_ops); int lwtunnel_build_state(u16 encap_type, struct nlattr *encap, unsigned int family, @@ -138,7 +140,7 @@ int lwtunnel_build_state(u16 encap_type, return ret; } -EXPORT_SYMBOL(lwtunnel_build_state); +EXPORT_SYMBOL_GPL(lwtunnel_build_state); int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack) { @@ -175,7 +177,7 @@ int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack) return ret; } -EXPORT_SYMBOL(lwtunnel_valid_encap_type); +EXPORT_SYMBOL_GPL(lwtunnel_valid_encap_type); int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining, struct netlink_ext_ack *extack) @@ -205,7 +207,7 @@ int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining, return 0; } -EXPORT_SYMBOL(lwtunnel_valid_encap_type_attr); +EXPORT_SYMBOL_GPL(lwtunnel_valid_encap_type_attr); void lwtstate_free(struct lwtunnel_state *lws) { @@ -219,7 +221,7 @@ void lwtstate_free(struct lwtunnel_state *lws) } module_put(ops->owner); } -EXPORT_SYMBOL(lwtstate_free); +EXPORT_SYMBOL_GPL(lwtstate_free); int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate) { @@ -259,7 +261,7 @@ int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate) return (ret == -EOPNOTSUPP ? 0 : ret); } -EXPORT_SYMBOL(lwtunnel_fill_encap); +EXPORT_SYMBOL_GPL(lwtunnel_fill_encap); int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate) { @@ -281,7 +283,7 @@ int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate) return ret; } -EXPORT_SYMBOL(lwtunnel_get_encap_size); +EXPORT_SYMBOL_GPL(lwtunnel_get_encap_size); int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b) { @@ -309,7 +311,7 @@ int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b) return ret; } -EXPORT_SYMBOL(lwtunnel_cmp_encap); +EXPORT_SYMBOL_GPL(lwtunnel_cmp_encap); int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) { @@ -343,7 +345,7 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) return ret; } -EXPORT_SYMBOL(lwtunnel_output); +EXPORT_SYMBOL_GPL(lwtunnel_output); int lwtunnel_xmit(struct sk_buff *skb) { @@ -378,7 +380,7 @@ int lwtunnel_xmit(struct sk_buff *skb) return ret; } -EXPORT_SYMBOL(lwtunnel_xmit); +EXPORT_SYMBOL_GPL(lwtunnel_xmit); int lwtunnel_input(struct sk_buff *skb) { @@ -412,4 +414,4 @@ int lwtunnel_input(struct sk_buff *skb) return ret; } -EXPORT_SYMBOL(lwtunnel_input); +EXPORT_SYMBOL_GPL(lwtunnel_input); diff --git a/net/core/neighbour.c b/net/core/neighbour.c index d0713627deb61623524c4b5cd26454abe92fc6d9..16a1a4c4eb57fa1147f230916e2e62e18ef89562 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -3261,13 +3261,13 @@ EXPORT_SYMBOL(neigh_sysctl_unregister); static int __init neigh_init(void) { - rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_GETNEIGH, NULL, neigh_dump_info, NULL); + rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_GETNEIGH, NULL, neigh_dump_info, 0); rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info, - NULL); - rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, NULL); + 0); + rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0); return 0; } diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index b4f9922b6f233da3d4a189b80b12034f6f7fddeb..927a6dcbad9668c6cb8b5afe150e8b4233d6a66b 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -97,7 +97,8 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, return restart_syscall(); if (dev_isalive(netdev)) { - if ((ret = (*set)(netdev, new)) == 0) + ret = (*set)(netdev, new); + if (ret == 0) ret = len; } rtnl_unlock(); @@ -160,6 +161,7 @@ static ssize_t broadcast_show(struct device *dev, struct device_attribute *attr, char *buf) { struct net_device *ndev = to_net_dev(dev); + if (dev_isalive(ndev)) return sysfs_format_mac(buf, ndev->broadcast, ndev->addr_len); return -EINVAL; @@ -170,7 +172,7 @@ static int change_carrier(struct net_device *dev, unsigned long new_carrier) { if (!netif_running(dev)) return -EINVAL; - return dev_change_carrier(dev, (bool) new_carrier); + return dev_change_carrier(dev, (bool)new_carrier); } static ssize_t carrier_store(struct device *dev, struct device_attribute *attr, @@ -183,9 +185,10 @@ static ssize_t carrier_show(struct device *dev, struct device_attribute *attr, char *buf) { struct net_device *netdev = to_net_dev(dev); - if (netif_running(netdev)) { + + if (netif_running(netdev)) return sprintf(buf, fmt_dec, !!netif_carrier_ok(netdev)); - } + return -EINVAL; } static DEVICE_ATTR_RW(carrier); @@ -290,6 +293,7 @@ static ssize_t carrier_changes_show(struct device *dev, char *buf) { struct net_device *netdev = to_net_dev(dev); + return sprintf(buf, fmt_dec, atomic_read(&netdev->carrier_changes)); } @@ -299,7 +303,7 @@ static DEVICE_ATTR_RO(carrier_changes); static int change_mtu(struct net_device *dev, unsigned long new_mtu) { - return dev_set_mtu(dev, (int) new_mtu); + return dev_set_mtu(dev, (int)new_mtu); } static ssize_t mtu_store(struct device *dev, struct device_attribute *attr, @@ -311,7 +315,7 @@ NETDEVICE_SHOW_RW(mtu, fmt_dec); static int change_flags(struct net_device *dev, unsigned long new_flags) { - return dev_change_flags(dev, (unsigned int) new_flags); + return dev_change_flags(dev, (unsigned int)new_flags); } static ssize_t flags_store(struct device *dev, struct device_attribute *attr, @@ -362,8 +366,8 @@ static int change_gro_flush_timeout(struct net_device *dev, unsigned long val) } static ssize_t gro_flush_timeout_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -412,7 +416,7 @@ static DEVICE_ATTR_RW(ifalias); static int change_group(struct net_device *dev, unsigned long new_group) { - dev_set_group(dev, (int) new_group); + dev_set_group(dev, (int)new_group); return 0; } @@ -426,7 +430,7 @@ static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store); static int change_proto_down(struct net_device *dev, unsigned long proto_down) { - return dev_change_proto_down(dev, (bool) proto_down); + return dev_change_proto_down(dev, (bool)proto_down); } static ssize_t proto_down_store(struct device *dev, @@ -508,7 +512,7 @@ static ssize_t phys_switch_id_show(struct device *dev, } static DEVICE_ATTR_RO(phys_switch_id); -static struct attribute *net_class_attrs[] = { +static struct attribute *net_class_attrs[] __ro_after_init = { &dev_attr_netdev_group.attr, &dev_attr_type.attr, &dev_attr_dev_id.attr, @@ -549,14 +553,14 @@ static ssize_t netstat_show(const struct device *d, ssize_t ret = -EINVAL; WARN_ON(offset > sizeof(struct rtnl_link_stats64) || - offset % sizeof(u64) != 0); + offset % sizeof(u64) != 0); read_lock(&dev_base_lock); if (dev_isalive(dev)) { struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp); - ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *) stats) + offset)); + ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *)stats) + offset)); } read_unlock(&dev_base_lock); return ret; @@ -565,7 +569,7 @@ static ssize_t netstat_show(const struct device *d, /* generate a read-only statistics attribute */ #define NETSTAT_ENTRY(name) \ static ssize_t name##_show(struct device *d, \ - struct device_attribute *attr, char *buf) \ + struct device_attribute *attr, char *buf) \ { \ return netstat_show(d, attr, buf, \ offsetof(struct rtnl_link_stats64, name)); \ @@ -597,7 +601,7 @@ NETSTAT_ENTRY(rx_compressed); NETSTAT_ENTRY(tx_compressed); NETSTAT_ENTRY(rx_nohandler); -static struct attribute *netstat_attrs[] = { +static struct attribute *netstat_attrs[] __ro_after_init = { &dev_attr_rx_packets.attr, &dev_attr_tx_packets.attr, &dev_attr_rx_bytes.attr, @@ -625,7 +629,6 @@ static struct attribute *netstat_attrs[] = { NULL }; - static const struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, @@ -647,33 +650,33 @@ static const struct attribute_group wireless_group = { #endif /* CONFIG_SYSFS */ #ifdef CONFIG_SYSFS -#define to_rx_queue_attr(_attr) container_of(_attr, \ - struct rx_queue_attribute, attr) +#define to_rx_queue_attr(_attr) \ + container_of(_attr, struct rx_queue_attribute, attr) #define to_rx_queue(obj) container_of(obj, struct netdev_rx_queue, kobj) static ssize_t rx_queue_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct rx_queue_attribute *attribute = to_rx_queue_attr(attr); + const struct rx_queue_attribute *attribute = to_rx_queue_attr(attr); struct netdev_rx_queue *queue = to_rx_queue(kobj); if (!attribute->show) return -EIO; - return attribute->show(queue, attribute, buf); + return attribute->show(queue, buf); } static ssize_t rx_queue_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { - struct rx_queue_attribute *attribute = to_rx_queue_attr(attr); + const struct rx_queue_attribute *attribute = to_rx_queue_attr(attr); struct netdev_rx_queue *queue = to_rx_queue(kobj); if (!attribute->store) return -EIO; - return attribute->store(queue, attribute, buf, count); + return attribute->store(queue, buf, count); } static const struct sysfs_ops rx_queue_sysfs_ops = { @@ -682,8 +685,7 @@ static const struct sysfs_ops rx_queue_sysfs_ops = { }; #ifdef CONFIG_RPS -static ssize_t show_rps_map(struct netdev_rx_queue *queue, - struct rx_queue_attribute *attribute, char *buf) +static ssize_t show_rps_map(struct netdev_rx_queue *queue, char *buf) { struct rps_map *map; cpumask_var_t mask; @@ -706,8 +708,7 @@ static ssize_t show_rps_map(struct netdev_rx_queue *queue, } static ssize_t store_rps_map(struct netdev_rx_queue *queue, - struct rx_queue_attribute *attribute, - const char *buf, size_t len) + const char *buf, size_t len) { struct rps_map *old_map, *map; cpumask_var_t mask; @@ -727,8 +728,8 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue, } map = kzalloc(max_t(unsigned int, - RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES), - GFP_KERNEL); + RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES), + GFP_KERNEL); if (!map) { free_cpumask_var(mask); return -ENOMEM; @@ -738,9 +739,9 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue, for_each_cpu_and(cpu, mask, cpu_online_mask) map->cpus[i++] = cpu; - if (i) + if (i) { map->len = i; - else { + } else { kfree(map); map = NULL; } @@ -765,7 +766,6 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue, } static ssize_t show_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, - struct rx_queue_attribute *attr, char *buf) { struct rps_dev_flow_table *flow_table; @@ -788,8 +788,7 @@ static void rps_dev_flow_table_release(struct rcu_head *rcu) } static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, - struct rx_queue_attribute *attr, - const char *buf, size_t len) + const char *buf, size_t len) { unsigned long mask, count; struct rps_dev_flow_table *table, *old_table; @@ -831,8 +830,9 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, table->mask = mask; for (count = 0; count <= mask; count++) table->flows[count].cpu = RPS_NO_CPU; - } else + } else { table = NULL; + } spin_lock(&rps_dev_flow_lock); old_table = rcu_dereference_protected(queue->rps_flow_table, @@ -846,16 +846,15 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, return len; } -static struct rx_queue_attribute rps_cpus_attribute = - __ATTR(rps_cpus, S_IRUGO | S_IWUSR, show_rps_map, store_rps_map); - +static struct rx_queue_attribute rps_cpus_attribute __ro_after_init + = __ATTR(rps_cpus, S_IRUGO | S_IWUSR, show_rps_map, store_rps_map); -static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute = - __ATTR(rps_flow_cnt, S_IRUGO | S_IWUSR, - show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt); +static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute __ro_after_init + = __ATTR(rps_flow_cnt, S_IRUGO | S_IWUSR, + show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt); #endif /* CONFIG_RPS */ -static struct attribute *rx_queue_default_attrs[] = { +static struct attribute *rx_queue_default_attrs[] __ro_after_init = { #ifdef CONFIG_RPS &rps_cpus_attribute.attr, &rps_dev_flow_table_cnt_attribute.attr, @@ -870,7 +869,6 @@ static void rx_queue_release(struct kobject *kobj) struct rps_map *map; struct rps_dev_flow_table *flow_table; - map = rcu_dereference_protected(queue->rps_map, 1); if (map) { RCU_INIT_POINTER(queue->rps_map, NULL); @@ -900,7 +898,7 @@ static const void *rx_queue_namespace(struct kobject *kobj) return ns; } -static struct kobj_type rx_queue_ktype = { +static struct kobj_type rx_queue_ktype __ro_after_init = { .sysfs_ops = &rx_queue_sysfs_ops, .release = rx_queue_release, .default_attrs = rx_queue_default_attrs, @@ -915,22 +913,21 @@ static int rx_queue_add_kobject(struct net_device *dev, int index) kobj->kset = dev->queues_kset; error = kobject_init_and_add(kobj, &rx_queue_ktype, NULL, - "rx-%u", index); + "rx-%u", index); if (error) - goto exit; + return error; if (dev->sysfs_rx_queue_group) { error = sysfs_create_group(kobj, dev->sysfs_rx_queue_group); - if (error) - goto exit; + if (error) { + kobject_put(kobj); + return error; + } } kobject_uevent(kobj, KOBJ_ADD); dev_hold(queue->dev); - return error; -exit: - kobject_put(kobj); return error; } #endif /* CONFIG_SYSFS */ @@ -976,39 +973,40 @@ net_rx_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) */ struct netdev_queue_attribute { struct attribute attr; - ssize_t (*show)(struct netdev_queue *queue, - struct netdev_queue_attribute *attr, char *buf); + ssize_t (*show)(struct netdev_queue *queue, char *buf); ssize_t (*store)(struct netdev_queue *queue, - struct netdev_queue_attribute *attr, const char *buf, size_t len); + const char *buf, size_t len); }; -#define to_netdev_queue_attr(_attr) container_of(_attr, \ - struct netdev_queue_attribute, attr) +#define to_netdev_queue_attr(_attr) \ + container_of(_attr, struct netdev_queue_attribute, attr) #define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj) static ssize_t netdev_queue_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); + const struct netdev_queue_attribute *attribute + = to_netdev_queue_attr(attr); struct netdev_queue *queue = to_netdev_queue(kobj); if (!attribute->show) return -EIO; - return attribute->show(queue, attribute, buf); + return attribute->show(queue, buf); } static ssize_t netdev_queue_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { - struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); + const struct netdev_queue_attribute *attribute + = to_netdev_queue_attr(attr); struct netdev_queue *queue = to_netdev_queue(kobj); if (!attribute->store) return -EIO; - return attribute->store(queue, attribute, buf, count); + return attribute->store(queue, buf, count); } static const struct sysfs_ops netdev_queue_sysfs_ops = { @@ -1016,9 +1014,7 @@ static const struct sysfs_ops netdev_queue_sysfs_ops = { .store = netdev_queue_attr_store, }; -static ssize_t show_trans_timeout(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, - char *buf) +static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf) { unsigned long trans_timeout; @@ -1040,8 +1036,7 @@ static unsigned int get_netdev_queue_index(struct netdev_queue *queue) return i; } -static ssize_t show_traffic_class(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, +static ssize_t traffic_class_show(struct netdev_queue *queue, char *buf) { struct net_device *dev = queue->dev; @@ -1055,16 +1050,14 @@ static ssize_t show_traffic_class(struct netdev_queue *queue, } #ifdef CONFIG_XPS -static ssize_t show_tx_maxrate(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, +static ssize_t tx_maxrate_show(struct netdev_queue *queue, char *buf) { return sprintf(buf, "%lu\n", queue->tx_maxrate); } -static ssize_t set_tx_maxrate(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, - const char *buf, size_t len) +static ssize_t tx_maxrate_store(struct netdev_queue *queue, + const char *buf, size_t len) { struct net_device *dev = queue->dev; int err, index = get_netdev_queue_index(queue); @@ -1089,16 +1082,15 @@ static ssize_t set_tx_maxrate(struct netdev_queue *queue, return err; } -static struct netdev_queue_attribute queue_tx_maxrate = - __ATTR(tx_maxrate, S_IRUGO | S_IWUSR, - show_tx_maxrate, set_tx_maxrate); +static struct netdev_queue_attribute queue_tx_maxrate __ro_after_init + = __ATTR_RW(tx_maxrate); #endif -static struct netdev_queue_attribute queue_trans_timeout = - __ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL); +static struct netdev_queue_attribute queue_trans_timeout __ro_after_init + = __ATTR_RO(tx_timeout); -static struct netdev_queue_attribute queue_traffic_class = - __ATTR(traffic_class, S_IRUGO, show_traffic_class, NULL); +static struct netdev_queue_attribute queue_traffic_class __ro_after_init + = __ATTR_RO(traffic_class); #ifdef CONFIG_BQL /* @@ -1115,9 +1107,9 @@ static ssize_t bql_set(const char *buf, const size_t count, unsigned int value; int err; - if (!strcmp(buf, "max") || !strcmp(buf, "max\n")) + if (!strcmp(buf, "max") || !strcmp(buf, "max\n")) { value = DQL_MAX_LIMIT; - else { + } else { err = kstrtouint(buf, 10, &value); if (err < 0) return err; @@ -1131,7 +1123,6 @@ static ssize_t bql_set(const char *buf, const size_t count, } static ssize_t bql_show_hold_time(struct netdev_queue *queue, - struct netdev_queue_attribute *attr, char *buf) { struct dql *dql = &queue->dql; @@ -1140,7 +1131,6 @@ static ssize_t bql_show_hold_time(struct netdev_queue *queue, } static ssize_t bql_set_hold_time(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, const char *buf, size_t len) { struct dql *dql = &queue->dql; @@ -1156,12 +1146,11 @@ static ssize_t bql_set_hold_time(struct netdev_queue *queue, return len; } -static struct netdev_queue_attribute bql_hold_time_attribute = - __ATTR(hold_time, S_IRUGO | S_IWUSR, bql_show_hold_time, - bql_set_hold_time); +static struct netdev_queue_attribute bql_hold_time_attribute __ro_after_init + = __ATTR(hold_time, S_IRUGO | S_IWUSR, + bql_show_hold_time, bql_set_hold_time); static ssize_t bql_show_inflight(struct netdev_queue *queue, - struct netdev_queue_attribute *attr, char *buf) { struct dql *dql = &queue->dql; @@ -1169,33 +1158,31 @@ static ssize_t bql_show_inflight(struct netdev_queue *queue, return sprintf(buf, "%u\n", dql->num_queued - dql->num_completed); } -static struct netdev_queue_attribute bql_inflight_attribute = +static struct netdev_queue_attribute bql_inflight_attribute __ro_after_init = __ATTR(inflight, S_IRUGO, bql_show_inflight, NULL); #define BQL_ATTR(NAME, FIELD) \ static ssize_t bql_show_ ## NAME(struct netdev_queue *queue, \ - struct netdev_queue_attribute *attr, \ char *buf) \ { \ return bql_show(buf, queue->dql.FIELD); \ } \ \ static ssize_t bql_set_ ## NAME(struct netdev_queue *queue, \ - struct netdev_queue_attribute *attr, \ const char *buf, size_t len) \ { \ return bql_set(buf, len, &queue->dql.FIELD); \ } \ \ -static struct netdev_queue_attribute bql_ ## NAME ## _attribute = \ - __ATTR(NAME, S_IRUGO | S_IWUSR, bql_show_ ## NAME, \ - bql_set_ ## NAME); +static struct netdev_queue_attribute bql_ ## NAME ## _attribute __ro_after_init \ + = __ATTR(NAME, S_IRUGO | S_IWUSR, \ + bql_show_ ## NAME, bql_set_ ## NAME) -BQL_ATTR(limit, limit) -BQL_ATTR(limit_max, max_limit) -BQL_ATTR(limit_min, min_limit) +BQL_ATTR(limit, limit); +BQL_ATTR(limit_max, max_limit); +BQL_ATTR(limit_min, min_limit); -static struct attribute *dql_attrs[] = { +static struct attribute *dql_attrs[] __ro_after_init = { &bql_limit_attribute.attr, &bql_limit_max_attribute.attr, &bql_limit_min_attribute.attr, @@ -1211,8 +1198,8 @@ static const struct attribute_group dql_group = { #endif /* CONFIG_BQL */ #ifdef CONFIG_XPS -static ssize_t show_xps_map(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, char *buf) +static ssize_t xps_cpus_show(struct netdev_queue *queue, + char *buf) { struct net_device *dev = queue->dev; int cpu, len, num_tc = 1, tc = 0; @@ -1258,9 +1245,8 @@ static ssize_t show_xps_map(struct netdev_queue *queue, return len < PAGE_SIZE ? len : -EINVAL; } -static ssize_t store_xps_map(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, - const char *buf, size_t len) +static ssize_t xps_cpus_store(struct netdev_queue *queue, + const char *buf, size_t len) { struct net_device *dev = queue->dev; unsigned long index; @@ -1288,11 +1274,11 @@ static ssize_t store_xps_map(struct netdev_queue *queue, return err ? : len; } -static struct netdev_queue_attribute xps_cpus_attribute = - __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map); +static struct netdev_queue_attribute xps_cpus_attribute __ro_after_init + = __ATTR_RW(xps_cpus); #endif /* CONFIG_XPS */ -static struct attribute *netdev_queue_default_attrs[] = { +static struct attribute *netdev_queue_default_attrs[] __ro_after_init = { &queue_trans_timeout.attr, &queue_traffic_class.attr, #ifdef CONFIG_XPS @@ -1322,7 +1308,7 @@ static const void *netdev_queue_namespace(struct kobject *kobj) return ns; } -static struct kobj_type netdev_queue_ktype = { +static struct kobj_type netdev_queue_ktype __ro_after_init = { .sysfs_ops = &netdev_queue_sysfs_ops, .release = netdev_queue_release, .default_attrs = netdev_queue_default_attrs, @@ -1337,23 +1323,22 @@ static int netdev_queue_add_kobject(struct net_device *dev, int index) kobj->kset = dev->queues_kset; error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL, - "tx-%u", index); + "tx-%u", index); if (error) - goto exit; + return error; #ifdef CONFIG_BQL error = sysfs_create_group(kobj, &dql_group); - if (error) - goto exit; + if (error) { + kobject_put(kobj); + return error; + } #endif kobject_uevent(kobj, KOBJ_ADD); dev_hold(queue->dev); return 0; -exit: - kobject_put(kobj); - return error; } #endif /* CONFIG_SYSFS */ @@ -1395,7 +1380,7 @@ static int register_queue_kobjects(struct net_device *dev) #ifdef CONFIG_SYSFS dev->queues_kset = kset_create_and_add("queues", - NULL, &dev->dev.kobj); + NULL, &dev->dev.kobj); if (!dev->queues_kset) return -ENOMEM; real_rx = dev->real_num_rx_queues; @@ -1463,7 +1448,7 @@ static const void *net_netlink_ns(struct sock *sk) return sock_net(sk); } -struct kobj_ns_type_operations net_ns_type_operations = { +const struct kobj_ns_type_operations net_ns_type_operations = { .type = KOBJ_NS_TYPE_NET, .current_may_mount = net_current_may_mount, .grab_current_ns = net_grab_current_ns, @@ -1485,7 +1470,8 @@ static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) /* pass ifindex to uevent. * ifindex is useful as it won't change (interface name may change) - * and is what RtNetlink uses natively. */ + * and is what RtNetlink uses natively. + */ retval = add_uevent_var(env, "IFINDEX=%d", dev->ifindex); exit: @@ -1513,7 +1499,7 @@ static const void *net_namespace(struct device *d) return dev_net(dev); } -static struct class net_class = { +static struct class net_class __ro_after_init = { .name = "net", .dev_release = netdev_release, .dev_groups = net_class_groups, @@ -1560,7 +1546,7 @@ EXPORT_SYMBOL(of_find_net_device_by_node); */ void netdev_unregister_kobject(struct net_device *ndev) { - struct device *dev = &(ndev->dev); + struct device *dev = &ndev->dev; if (!atomic_read(&dev_net(ndev)->count)) dev_set_uevent_suppress(dev, 1); @@ -1577,7 +1563,7 @@ void netdev_unregister_kobject(struct net_device *ndev) /* Create sysfs entries for network device. */ int netdev_register_kobject(struct net_device *ndev) { - struct device *dev = &(ndev->dev); + struct device *dev = &ndev->dev; const struct attribute_group **groups = ndev->sysfs_groups; int error = 0; @@ -1620,14 +1606,14 @@ int netdev_register_kobject(struct net_device *ndev) return error; } -int netdev_class_create_file_ns(struct class_attribute *class_attr, +int netdev_class_create_file_ns(const struct class_attribute *class_attr, const void *ns) { return class_create_file_ns(&net_class, class_attr, ns); } EXPORT_SYMBOL(netdev_class_create_file_ns); -void netdev_class_remove_file_ns(struct class_attribute *class_attr, +void netdev_class_remove_file_ns(const struct class_attribute *class_attr, const void *ns) { class_remove_file_ns(&net_class, class_attr, ns); diff --git a/net/core/net-traces.c b/net/core/net-traces.c index 92da5e4ceb4f42105ca3d1a436eb8df99bfd3eaf..1132820c8e62c362d5437c64a2a53c4b3b8dc381 100644 --- a/net/core/net-traces.c +++ b/net/core/net-traces.c @@ -32,10 +32,18 @@ #include #include #include +#include #if IS_ENABLED(CONFIG_IPV6) #include EXPORT_TRACEPOINT_SYMBOL_GPL(fib6_table_lookup); #endif +#if IS_ENABLED(CONFIG_BRIDGE) +#include +EXPORT_TRACEPOINT_SYMBOL_GPL(br_fdb_add); +EXPORT_TRACEPOINT_SYMBOL_GPL(br_fdb_external_learn_add); +EXPORT_TRACEPOINT_SYMBOL_GPL(fdb_delete); +EXPORT_TRACEPOINT_SYMBOL_GPL(br_fdb_update); +#endif EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 8726d051f31dd2ddce96a8cd7b1ccf50435f0d92..6cfdc7c84c480f41b784f417d28f7a622c296e81 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -855,9 +855,10 @@ static int __init net_ns_init(void) register_pernet_subsys(&net_ns_ops); - rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL, NULL); + rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL, + RTNL_FLAG_DOIT_UNLOCKED); rtnl_register(PF_UNSPEC, RTM_GETNSID, rtnl_net_getid, rtnl_net_dumpid, - NULL); + RTNL_FLAG_DOIT_UNLOCKED); return 0; } diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c index 029a61ac6cdd8a0b4dd54d2be3c5bdf047a82cb0..5e4f04004a49a38ba9d8f2535aa293eeab898155 100644 --- a/net/core/netclassid_cgroup.c +++ b/net/core/netclassid_cgroup.c @@ -100,7 +100,7 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft, cs->classid = (u32)value; - css_task_iter_start(css, &it); + css_task_iter_start(css, 0, &it); while ((p = css_task_iter_next(&it))) { task_lock(p); iterate_fd(p->files, 0, update_classid_sock, diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 8357f164c66092b9c99996782d29de246c54dbd6..912731bed7b71b9208f3947b49c4b93922f7ab0d 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -666,7 +666,7 @@ int netpoll_setup(struct netpoll *np) int err; rtnl_lock(); - if (np->dev_name) { + if (np->dev_name[0]) { struct net *net = current->nsproxy->net_ns; ndev = __dev_get_by_name(net, np->dev_name); } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 9201e3621351144f1fde497dfa1025d93d0a76f9..d4bcdcc68e9268f0c6b4bbf918d5af2e6b71be4e 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -62,7 +62,7 @@ struct rtnl_link { rtnl_doit_func doit; rtnl_dumpit_func dumpit; - rtnl_calcit_func calcit; + unsigned int flags; }; static DEFINE_MUTEX(rtnl_mutex); @@ -127,7 +127,8 @@ bool lockdep_rtnl_is_held(void) EXPORT_SYMBOL(lockdep_rtnl_is_held); #endif /* #ifdef CONFIG_PROVE_LOCKING */ -static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; +static struct rtnl_link __rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1]; +static refcount_t rtnl_msg_handlers_ref[RTNL_FAMILY_MAX + 1]; static inline int rtm_msgindex(int msgtype) { @@ -143,58 +144,13 @@ static inline int rtm_msgindex(int msgtype) return msgindex; } -static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex) -{ - struct rtnl_link *tab; - - if (protocol <= RTNL_FAMILY_MAX) - tab = rtnl_msg_handlers[protocol]; - else - tab = NULL; - - if (tab == NULL || tab[msgindex].doit == NULL) - tab = rtnl_msg_handlers[PF_UNSPEC]; - - return tab[msgindex].doit; -} - -static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) -{ - struct rtnl_link *tab; - - if (protocol <= RTNL_FAMILY_MAX) - tab = rtnl_msg_handlers[protocol]; - else - tab = NULL; - - if (tab == NULL || tab[msgindex].dumpit == NULL) - tab = rtnl_msg_handlers[PF_UNSPEC]; - - return tab[msgindex].dumpit; -} - -static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) -{ - struct rtnl_link *tab; - - if (protocol <= RTNL_FAMILY_MAX) - tab = rtnl_msg_handlers[protocol]; - else - tab = NULL; - - if (tab == NULL || tab[msgindex].calcit == NULL) - tab = rtnl_msg_handlers[PF_UNSPEC]; - - return tab[msgindex].calcit; -} - /** * __rtnl_register - Register a rtnetlink message type * @protocol: Protocol family or PF_UNSPEC * @msgtype: rtnetlink message type * @doit: Function pointer called for each request message * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message - * @calcit: Function pointer to calc size of dump message + * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions * * Registers the specified function pointers (at least one of them has * to be non-NULL) to be called whenever a request message for the @@ -208,7 +164,7 @@ static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) */ int __rtnl_register(int protocol, int msgtype, rtnl_doit_func doit, rtnl_dumpit_func dumpit, - rtnl_calcit_func calcit) + unsigned int flags) { struct rtnl_link *tab; int msgindex; @@ -216,23 +172,20 @@ int __rtnl_register(int protocol, int msgtype, BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); msgindex = rtm_msgindex(msgtype); - tab = rtnl_msg_handlers[protocol]; + tab = rcu_dereference_raw(rtnl_msg_handlers[protocol]); if (tab == NULL) { tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL); if (tab == NULL) return -ENOBUFS; - rtnl_msg_handlers[protocol] = tab; + rcu_assign_pointer(rtnl_msg_handlers[protocol], tab); } if (doit) tab[msgindex].doit = doit; - if (dumpit) tab[msgindex].dumpit = dumpit; - - if (calcit) - tab[msgindex].calcit = calcit; + tab[msgindex].flags |= flags; return 0; } @@ -249,9 +202,9 @@ EXPORT_SYMBOL_GPL(__rtnl_register); */ void rtnl_register(int protocol, int msgtype, rtnl_doit_func doit, rtnl_dumpit_func dumpit, - rtnl_calcit_func calcit) + unsigned int flags) { - if (__rtnl_register(protocol, msgtype, doit, dumpit, calcit) < 0) + if (__rtnl_register(protocol, msgtype, doit, dumpit, flags) < 0) panic("Unable to register rtnetlink message handler, " "protocol = %d, message type = %d\n", protocol, msgtype); @@ -267,17 +220,23 @@ EXPORT_SYMBOL_GPL(rtnl_register); */ int rtnl_unregister(int protocol, int msgtype) { + struct rtnl_link *handlers; int msgindex; BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); msgindex = rtm_msgindex(msgtype); - if (rtnl_msg_handlers[protocol] == NULL) + rtnl_lock(); + handlers = rtnl_dereference(rtnl_msg_handlers[protocol]); + if (!handlers) { + rtnl_unlock(); return -ENOENT; + } - rtnl_msg_handlers[protocol][msgindex].doit = NULL; - rtnl_msg_handlers[protocol][msgindex].dumpit = NULL; - rtnl_msg_handlers[protocol][msgindex].calcit = NULL; + handlers[msgindex].doit = NULL; + handlers[msgindex].dumpit = NULL; + handlers[msgindex].flags = 0; + rtnl_unlock(); return 0; } @@ -292,10 +251,20 @@ EXPORT_SYMBOL_GPL(rtnl_unregister); */ void rtnl_unregister_all(int protocol) { + struct rtnl_link *handlers; + BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX); - kfree(rtnl_msg_handlers[protocol]); - rtnl_msg_handlers[protocol] = NULL; + rtnl_lock(); + handlers = rtnl_dereference(rtnl_msg_handlers[protocol]); + RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); + rtnl_unlock(); + + synchronize_net(); + + while (refcount_read(&rtnl_msg_handlers_ref[protocol]) > 1) + schedule(); + kfree(handlers); } EXPORT_SYMBOL_GPL(rtnl_unregister_all); @@ -433,16 +402,24 @@ static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev) { struct net_device *master_dev; const struct rtnl_link_ops *ops; + size_t size = 0; - master_dev = netdev_master_upper_dev_get((struct net_device *) dev); + rcu_read_lock(); + + master_dev = netdev_master_upper_dev_get_rcu((struct net_device *)dev); if (!master_dev) - return 0; + goto out; + ops = master_dev->rtnl_link_ops; if (!ops || !ops->get_slave_size) - return 0; + goto out; /* IFLA_INFO_SLAVE_DATA + nested data */ - return nla_total_size(sizeof(struct nlattr)) + + size = nla_total_size(sizeof(struct nlattr)) + ops->get_slave_size(master_dev, dev); + +out: + rcu_read_unlock(); + return size; } static size_t rtnl_link_get_size(const struct net_device *dev) @@ -1644,8 +1621,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) s_h = cb->args[0]; s_idx = cb->args[1]; - cb->seq = net->dev_base_seq; - /* A hack to preserve kernel<->userspace interface. * The correct header is ifinfomsg. It is consistent with rtnl_getlink. * However, before Linux v3.9 the code here assumed rtgenmsg and that's @@ -1691,8 +1666,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) goto out_err; } - - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); cont: idx++; } @@ -1702,6 +1675,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) out_err: cb->args[1] = idx; cb->args[0] = h; + cb->seq = net->dev_base_seq; + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); return err; } @@ -2831,11 +2806,13 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) * traverse the list of net devices and compute the minimum * buffer size based upon the filter mask. */ - list_for_each_entry(dev, &net->dev_base_head, dev_list) { + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size, if_nlmsg_size(dev, ext_filter_mask)); } + rcu_read_unlock(); return nlmsg_total_size(min_ifinfo_dump_size); } @@ -2847,19 +2824,29 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) if (s_idx == 0) s_idx = 1; + for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) { int type = cb->nlh->nlmsg_type-RTM_BASE; + struct rtnl_link *handlers; + rtnl_dumpit_func dumpit; + if (idx < s_idx || idx == PF_PACKET) continue; - if (rtnl_msg_handlers[idx] == NULL || - rtnl_msg_handlers[idx][type].dumpit == NULL) + + handlers = rtnl_dereference(rtnl_msg_handlers[idx]); + if (!handlers) continue; + + dumpit = READ_ONCE(handlers[type].dumpit); + if (!dumpit) + continue; + if (idx > s_idx) { memset(&cb->args[0], 0, sizeof(cb->args)); cb->prev_seq = 0; cb->seq = 0; } - if (rtnl_msg_handlers[idx][type].dumpit(skb, cb)) + if (dumpit(skb, cb)) break; } cb->family = idx; @@ -3867,6 +3854,9 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev, return -EMSGSIZE; ifsm = nlmsg_data(nlh); + ifsm->family = PF_UNSPEC; + ifsm->pad1 = 0; + ifsm->pad2 = 0; ifsm->ifindex = dev->ifindex; ifsm->filter_mask = filter_mask; @@ -4162,11 +4152,13 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { struct net *net = sock_net(skb->sk); + struct rtnl_link *handlers; + int err = -EOPNOTSUPP; rtnl_doit_func doit; + unsigned int flags; int kind; int family; int type; - int err; type = nlh->nlmsg_type; if (type > RTM_MAX) @@ -4184,20 +4176,40 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) return -EPERM; + if (family >= ARRAY_SIZE(rtnl_msg_handlers)) + family = PF_UNSPEC; + + rcu_read_lock(); + handlers = rcu_dereference(rtnl_msg_handlers[family]); + if (!handlers) { + family = PF_UNSPEC; + handlers = rcu_dereference(rtnl_msg_handlers[family]); + } + if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { struct sock *rtnl; rtnl_dumpit_func dumpit; - rtnl_calcit_func calcit; u16 min_dump_alloc = 0; - dumpit = rtnl_get_dumpit(family, type); - if (dumpit == NULL) - return -EOPNOTSUPP; - calcit = rtnl_get_calcit(family, type); - if (calcit) - min_dump_alloc = calcit(skb, nlh); + dumpit = READ_ONCE(handlers[type].dumpit); + if (!dumpit) { + family = PF_UNSPEC; + handlers = rcu_dereference(rtnl_msg_handlers[PF_UNSPEC]); + if (!handlers) + goto err_unlock; + + dumpit = READ_ONCE(handlers[type].dumpit); + if (!dumpit) + goto err_unlock; + } + + refcount_inc(&rtnl_msg_handlers_ref[family]); + + if (type == RTM_GETLINK - RTM_BASE) + min_dump_alloc = rtnl_calcit(skb, nlh); + + rcu_read_unlock(); - __rtnl_unlock(); rtnl = net->rtnl; { struct netlink_dump_control c = { @@ -4206,22 +4218,47 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, }; err = netlink_dump_start(rtnl, skb, nlh, &c); } - rtnl_lock(); + refcount_dec(&rtnl_msg_handlers_ref[family]); return err; } - doit = rtnl_get_doit(family, type); - if (doit == NULL) - return -EOPNOTSUPP; + doit = READ_ONCE(handlers[type].doit); + if (!doit) { + family = PF_UNSPEC; + handlers = rcu_dereference(rtnl_msg_handlers[family]); + } + + flags = READ_ONCE(handlers[type].flags); + if (flags & RTNL_FLAG_DOIT_UNLOCKED) { + refcount_inc(&rtnl_msg_handlers_ref[family]); + doit = READ_ONCE(handlers[type].doit); + rcu_read_unlock(); + if (doit) + err = doit(skb, nlh, extack); + refcount_dec(&rtnl_msg_handlers_ref[family]); + return err; + } - return doit(skb, nlh, extack); + rcu_read_unlock(); + + rtnl_lock(); + handlers = rtnl_dereference(rtnl_msg_handlers[family]); + if (handlers) { + doit = READ_ONCE(handlers[type].doit); + if (doit) + err = doit(skb, nlh, extack); + } + rtnl_unlock(); + return err; + +err_unlock: + rcu_read_unlock(); + return -EOPNOTSUPP; } static void rtnetlink_rcv(struct sk_buff *skb) { - rtnl_lock(); netlink_rcv_skb(skb, &rtnetlink_rcv_msg); - rtnl_unlock(); } static int rtnetlink_bind(struct net *net, int group) @@ -4294,29 +4331,34 @@ static struct pernet_operations rtnetlink_net_ops = { void __init rtnetlink_init(void) { + int i; + + for (i = 0; i < ARRAY_SIZE(rtnl_msg_handlers_ref); i++) + refcount_set(&rtnl_msg_handlers_ref[i], 1); + if (register_pernet_subsys(&rtnetlink_net_ops)) panic("rtnetlink_init: cannot initialize rtnetlink\n"); register_netdevice_notifier(&rtnetlink_dev_notifier); rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, - rtnl_dump_ifinfo, rtnl_calcit); - rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL); + rtnl_dump_ifinfo, 0); + rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, 0); - rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL); - rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL); - rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, NULL); + rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0); + rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0); + rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0); - rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); - rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); - rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); + rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0); + rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0); + rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, 0); - rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL); - rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL); - rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL); + rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0); + rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0); + rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump, - NULL); + 0); } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f990eb8b30a9c4a57ef39d34413dd2f2a75babb6..16982de649b97b92423a4f9f5eac1e98ca803370 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -158,31 +158,6 @@ static void *__kmalloc_reserve(size_t size, gfp_t flags, int node, * */ -struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) -{ - struct sk_buff *skb; - - /* Get the HEAD */ - skb = kmem_cache_alloc_node(skbuff_head_cache, - gfp_mask & ~__GFP_DMA, node); - if (!skb) - goto out; - - /* - * Only clear those fields we need to clear, not those that we will - * actually initialise below. Hence, don't put any more fields after - * the tail pointer in struct sk_buff! - */ - memset(skb, 0, offsetof(struct sk_buff, tail)); - skb->head = NULL; - skb->truesize = sizeof(struct sk_buff); - refcount_set(&skb->users, 1); - - skb->mac_header = (typeof(skb->mac_header))~0U; -out: - return skb; -} - /** * __alloc_skb - allocate a network buffer * @size: size to allocate @@ -592,21 +567,10 @@ static void skb_release_data(struct sk_buff *skb) for (i = 0; i < shinfo->nr_frags; i++) __skb_frag_unref(&shinfo->frags[i]); - /* - * If skb buf is from userspace, we need to notify the caller - * the lower device DMA has done; - */ - if (shinfo->tx_flags & SKBTX_DEV_ZEROCOPY) { - struct ubuf_info *uarg; - - uarg = shinfo->destructor_arg; - if (uarg->callback) - uarg->callback(uarg, true); - } - if (shinfo->frag_list) kfree_skb_list(shinfo->frag_list); + skb_zcopy_clear(skb, true); skb_free_head(skb); } @@ -720,14 +684,7 @@ EXPORT_SYMBOL(kfree_skb_list); */ void skb_tx_error(struct sk_buff *skb) { - if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { - struct ubuf_info *uarg; - - uarg = skb_shinfo(skb)->destructor_arg; - if (uarg->callback) - uarg->callback(uarg, false); - skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; - } + skb_zcopy_clear(skb, true); } EXPORT_SYMBOL(skb_tx_error); @@ -753,17 +710,13 @@ EXPORT_SYMBOL(consume_skb); * consume_stateless_skb - free an skbuff, assuming it is stateless * @skb: buffer to free * - * Works like consume_skb(), but this variant assumes that all the head - * states have been already dropped. + * Alike consume_skb(), but this variant assumes that this is the last + * skb reference and all the head states have been already dropped */ -void consume_stateless_skb(struct sk_buff *skb) +void __consume_stateless_skb(struct sk_buff *skb) { - if (!skb_unref(skb)) - return; - trace_consume_skb(skb); - if (likely(skb->head)) - skb_release_data(skb); + skb_release_data(skb); kfree_skbmem(skb); } @@ -941,6 +894,267 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src) } EXPORT_SYMBOL_GPL(skb_morph); +static int mm_account_pinned_pages(struct mmpin *mmp, size_t size) +{ + unsigned long max_pg, num_pg, new_pg, old_pg; + struct user_struct *user; + + if (capable(CAP_IPC_LOCK) || !size) + return 0; + + num_pg = (size >> PAGE_SHIFT) + 2; /* worst case */ + max_pg = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + user = mmp->user ? : current_user(); + + do { + old_pg = atomic_long_read(&user->locked_vm); + new_pg = old_pg + num_pg; + if (new_pg > max_pg) + return -ENOBUFS; + } while (atomic_long_cmpxchg(&user->locked_vm, old_pg, new_pg) != + old_pg); + + if (!mmp->user) { + mmp->user = get_uid(user); + mmp->num_pg = num_pg; + } else { + mmp->num_pg += num_pg; + } + + return 0; +} + +static void mm_unaccount_pinned_pages(struct mmpin *mmp) +{ + if (mmp->user) { + atomic_long_sub(mmp->num_pg, &mmp->user->locked_vm); + free_uid(mmp->user); + } +} + +struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size) +{ + struct ubuf_info *uarg; + struct sk_buff *skb; + + WARN_ON_ONCE(!in_task()); + + if (!sock_flag(sk, SOCK_ZEROCOPY)) + return NULL; + + skb = sock_omalloc(sk, 0, GFP_KERNEL); + if (!skb) + return NULL; + + BUILD_BUG_ON(sizeof(*uarg) > sizeof(skb->cb)); + uarg = (void *)skb->cb; + uarg->mmp.user = NULL; + + if (mm_account_pinned_pages(&uarg->mmp, size)) { + kfree_skb(skb); + return NULL; + } + + uarg->callback = sock_zerocopy_callback; + uarg->id = ((u32)atomic_inc_return(&sk->sk_zckey)) - 1; + uarg->len = 1; + uarg->bytelen = size; + uarg->zerocopy = 1; + refcount_set(&uarg->refcnt, 1); + sock_hold(sk); + + return uarg; +} +EXPORT_SYMBOL_GPL(sock_zerocopy_alloc); + +static inline struct sk_buff *skb_from_uarg(struct ubuf_info *uarg) +{ + return container_of((void *)uarg, struct sk_buff, cb); +} + +struct ubuf_info *sock_zerocopy_realloc(struct sock *sk, size_t size, + struct ubuf_info *uarg) +{ + if (uarg) { + const u32 byte_limit = 1 << 19; /* limit to a few TSO */ + u32 bytelen, next; + + /* realloc only when socket is locked (TCP, UDP cork), + * so uarg->len and sk_zckey access is serialized + */ + if (!sock_owned_by_user(sk)) { + WARN_ON_ONCE(1); + return NULL; + } + + bytelen = uarg->bytelen + size; + if (uarg->len == USHRT_MAX - 1 || bytelen > byte_limit) { + /* TCP can create new skb to attach new uarg */ + if (sk->sk_type == SOCK_STREAM) + goto new_alloc; + return NULL; + } + + next = (u32)atomic_read(&sk->sk_zckey); + if ((u32)(uarg->id + uarg->len) == next) { + if (mm_account_pinned_pages(&uarg->mmp, size)) + return NULL; + uarg->len++; + uarg->bytelen = bytelen; + atomic_set(&sk->sk_zckey, ++next); + sock_zerocopy_get(uarg); + return uarg; + } + } + +new_alloc: + return sock_zerocopy_alloc(sk, size); +} +EXPORT_SYMBOL_GPL(sock_zerocopy_realloc); + +static bool skb_zerocopy_notify_extend(struct sk_buff *skb, u32 lo, u16 len) +{ + struct sock_exterr_skb *serr = SKB_EXT_ERR(skb); + u32 old_lo, old_hi; + u64 sum_len; + + old_lo = serr->ee.ee_info; + old_hi = serr->ee.ee_data; + sum_len = old_hi - old_lo + 1ULL + len; + + if (sum_len >= (1ULL << 32)) + return false; + + if (lo != old_hi + 1) + return false; + + serr->ee.ee_data += len; + return true; +} + +void sock_zerocopy_callback(struct ubuf_info *uarg, bool success) +{ + struct sk_buff *tail, *skb = skb_from_uarg(uarg); + struct sock_exterr_skb *serr; + struct sock *sk = skb->sk; + struct sk_buff_head *q; + unsigned long flags; + u32 lo, hi; + u16 len; + + mm_unaccount_pinned_pages(&uarg->mmp); + + /* if !len, there was only 1 call, and it was aborted + * so do not queue a completion notification + */ + if (!uarg->len || sock_flag(sk, SOCK_DEAD)) + goto release; + + len = uarg->len; + lo = uarg->id; + hi = uarg->id + len - 1; + + serr = SKB_EXT_ERR(skb); + memset(serr, 0, sizeof(*serr)); + serr->ee.ee_errno = 0; + serr->ee.ee_origin = SO_EE_ORIGIN_ZEROCOPY; + serr->ee.ee_data = hi; + serr->ee.ee_info = lo; + if (!success) + serr->ee.ee_code |= SO_EE_CODE_ZEROCOPY_COPIED; + + q = &sk->sk_error_queue; + spin_lock_irqsave(&q->lock, flags); + tail = skb_peek_tail(q); + if (!tail || SKB_EXT_ERR(tail)->ee.ee_origin != SO_EE_ORIGIN_ZEROCOPY || + !skb_zerocopy_notify_extend(tail, lo, len)) { + __skb_queue_tail(q, skb); + skb = NULL; + } + spin_unlock_irqrestore(&q->lock, flags); + + sk->sk_error_report(sk); + +release: + consume_skb(skb); + sock_put(sk); +} +EXPORT_SYMBOL_GPL(sock_zerocopy_callback); + +void sock_zerocopy_put(struct ubuf_info *uarg) +{ + if (uarg && refcount_dec_and_test(&uarg->refcnt)) { + if (uarg->callback) + uarg->callback(uarg, uarg->zerocopy); + else + consume_skb(skb_from_uarg(uarg)); + } +} +EXPORT_SYMBOL_GPL(sock_zerocopy_put); + +void sock_zerocopy_put_abort(struct ubuf_info *uarg) +{ + if (uarg) { + struct sock *sk = skb_from_uarg(uarg)->sk; + + atomic_dec(&sk->sk_zckey); + uarg->len--; + + sock_zerocopy_put(uarg); + } +} +EXPORT_SYMBOL_GPL(sock_zerocopy_put_abort); + +extern int __zerocopy_sg_from_iter(struct sock *sk, struct sk_buff *skb, + struct iov_iter *from, size_t length); + +int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb, + struct msghdr *msg, int len, + struct ubuf_info *uarg) +{ + struct ubuf_info *orig_uarg = skb_zcopy(skb); + struct iov_iter orig_iter = msg->msg_iter; + int err, orig_len = skb->len; + + /* An skb can only point to one uarg. This edge case happens when + * TCP appends to an skb, but zerocopy_realloc triggered a new alloc. + */ + if (orig_uarg && uarg != orig_uarg) + return -EEXIST; + + err = __zerocopy_sg_from_iter(sk, skb, &msg->msg_iter, len); + if (err == -EFAULT || (err == -EMSGSIZE && skb->len == orig_len)) { + /* Streams do not free skb on error. Reset to prev state. */ + msg->msg_iter = orig_iter; + ___pskb_trim(skb, orig_len); + return err; + } + + skb_zcopy_set(skb, uarg); + return skb->len - orig_len; +} +EXPORT_SYMBOL_GPL(skb_zerocopy_iter_stream); + +static int skb_zerocopy_clone(struct sk_buff *nskb, struct sk_buff *orig, + gfp_t gfp_mask) +{ + if (skb_zcopy(orig)) { + if (skb_zcopy(nskb)) { + /* !gfp_mask callers are verified to !skb_zcopy(nskb) */ + if (!gfp_mask) { + WARN_ON_ONCE(1); + return -ENOMEM; + } + if (skb_uarg(nskb) == skb_uarg(orig)) + return 0; + if (skb_copy_ubufs(nskb, GFP_ATOMIC)) + return -EIO; + } + skb_zcopy_set(nskb, skb_uarg(orig)); + } + return 0; +} + /** * skb_copy_ubufs - copy userspace skb frags buffers to kernel * @skb: the skb to modify @@ -958,15 +1172,19 @@ EXPORT_SYMBOL_GPL(skb_morph); */ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) { - int i; int num_frags = skb_shinfo(skb)->nr_frags; struct page *page, *head = NULL; - struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg; + int i, new_frags; + u32 d_off; - for (i = 0; i < num_frags; i++) { - u8 *vaddr; - skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + if (!num_frags) + return 0; + + if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) + return -EINVAL; + new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; + for (i = 0; i < new_frags; i++) { page = alloc_page(gfp_mask); if (!page) { while (head) { @@ -976,28 +1194,51 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) } return -ENOMEM; } - vaddr = kmap_atomic(skb_frag_page(f)); - memcpy(page_address(page), - vaddr + f->page_offset, skb_frag_size(f)); - kunmap_atomic(vaddr); set_page_private(page, (unsigned long)head); head = page; } + page = head; + d_off = 0; + for (i = 0; i < num_frags; i++) { + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + u32 p_off, p_len, copied; + struct page *p; + u8 *vaddr; + + skb_frag_foreach_page(f, f->page_offset, skb_frag_size(f), + p, p_off, p_len, copied) { + u32 copy, done = 0; + vaddr = kmap_atomic(p); + + while (done < p_len) { + if (d_off == PAGE_SIZE) { + d_off = 0; + page = (struct page *)page_private(page); + } + copy = min_t(u32, PAGE_SIZE - d_off, p_len - done); + memcpy(page_address(page) + d_off, + vaddr + p_off + done, copy); + done += copy; + d_off += copy; + } + kunmap_atomic(vaddr); + } + } + /* skb frags release userspace buffers */ for (i = 0; i < num_frags; i++) skb_frag_unref(skb, i); - uarg->callback(uarg, false); - /* skb frags point to kernel buffers */ - for (i = num_frags - 1; i >= 0; i--) { - __skb_fill_page_desc(skb, i, head, 0, - skb_shinfo(skb)->frags[i].size); + for (i = 0; i < new_frags - 1; i++) { + __skb_fill_page_desc(skb, i, head, 0, PAGE_SIZE); head = (struct page *)page_private(head); } + __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); + skb_shinfo(skb)->nr_frags = new_frags; - skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; + skb_zcopy_clear(skb, false); return 0; } EXPORT_SYMBOL_GPL(skb_copy_ubufs); @@ -1158,7 +1399,8 @@ struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom, if (skb_shinfo(skb)->nr_frags) { int i; - if (skb_orphan_frags(skb, gfp_mask)) { + if (skb_orphan_frags(skb, gfp_mask) || + skb_zerocopy_clone(n, skb, gfp_mask)) { kfree_skb(n); n = NULL; goto out; @@ -1235,9 +1477,10 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, * be since all we did is relocate the values */ if (skb_cloned(skb)) { - /* copy this zero copy skb frags */ if (skb_orphan_frags(skb, gfp_mask)) goto nofrags; + if (skb_zcopy(skb)) + refcount_inc(&skb_uarg(skb)->refcnt); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) skb_frag_ref(skb, i); @@ -1363,18 +1606,20 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, EXPORT_SYMBOL(skb_copy_expand); /** - * skb_pad - zero pad the tail of an skb + * __skb_pad - zero pad the tail of an skb * @skb: buffer to pad * @pad: space to pad + * @free_on_error: free buffer on error * * Ensure that a buffer is followed by a padding area that is zero * filled. Used by network drivers which may DMA or transfer data * beyond the buffer end onto the wire. * - * May return error in out of memory cases. The skb is freed on error. + * May return error in out of memory cases. The skb is freed on error + * if @free_on_error is true. */ -int skb_pad(struct sk_buff *skb, int pad) +int __skb_pad(struct sk_buff *skb, int pad, bool free_on_error) { int err; int ntail; @@ -1403,10 +1648,11 @@ int skb_pad(struct sk_buff *skb, int pad) return 0; free_skb: - kfree_skb(skb); + if (free_on_error) + kfree_skb(skb); return err; } -EXPORT_SYMBOL(skb_pad); +EXPORT_SYMBOL(__skb_pad); /** * pskb_put - add data to the tail of a potentially fragmented buffer @@ -1719,6 +1965,8 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta) if (eat) { skb_shinfo(skb)->frags[k].page_offset += eat; skb_frag_size_sub(&skb_shinfo(skb)->frags[k], eat); + if (!i) + goto end; eat = 0; } k++; @@ -1726,9 +1974,13 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta) } skb_shinfo(skb)->nr_frags = k; +end: skb->tail += delta; skb->data_len -= delta; + if (!skb->data_len) + skb_zcopy_clear(skb, false); + return skb_tail_pointer(skb); } EXPORT_SYMBOL(__pskb_pull_tail); @@ -1776,16 +2028,20 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) end = start + skb_frag_size(f); if ((copy = end - offset) > 0) { + u32 p_off, p_len, copied; + struct page *p; u8 *vaddr; if (copy > len) copy = len; - vaddr = kmap_atomic(skb_frag_page(f)); - memcpy(to, - vaddr + f->page_offset + offset - start, - copy); - kunmap_atomic(vaddr); + skb_frag_foreach_page(f, + f->page_offset + offset - start, + copy, p, p_off, p_len, copied) { + vaddr = kmap_atomic(p); + memcpy(to + copied, vaddr + p_off, p_len); + kunmap_atomic(vaddr); + } if ((len -= copy) == 0) return 0; @@ -2005,6 +2261,107 @@ int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset, } EXPORT_SYMBOL_GPL(skb_splice_bits); +/* Send skb data on a socket. Socket must be locked. */ +int skb_send_sock_locked(struct sock *sk, struct sk_buff *skb, int offset, + int len) +{ + unsigned int orig_len = len; + struct sk_buff *head = skb; + unsigned short fragidx; + int slen, ret; + +do_frag_list: + + /* Deal with head data */ + while (offset < skb_headlen(skb) && len) { + struct kvec kv; + struct msghdr msg; + + slen = min_t(int, len, skb_headlen(skb) - offset); + kv.iov_base = skb->data + offset; + kv.iov_len = slen; + memset(&msg, 0, sizeof(msg)); + + ret = kernel_sendmsg_locked(sk, &msg, &kv, 1, slen); + if (ret <= 0) + goto error; + + offset += ret; + len -= ret; + } + + /* All the data was skb head? */ + if (!len) + goto out; + + /* Make offset relative to start of frags */ + offset -= skb_headlen(skb); + + /* Find where we are in frag list */ + for (fragidx = 0; fragidx < skb_shinfo(skb)->nr_frags; fragidx++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[fragidx]; + + if (offset < frag->size) + break; + + offset -= frag->size; + } + + for (; len && fragidx < skb_shinfo(skb)->nr_frags; fragidx++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[fragidx]; + + slen = min_t(size_t, len, frag->size - offset); + + while (slen) { + ret = kernel_sendpage_locked(sk, frag->page.p, + frag->page_offset + offset, + slen, MSG_DONTWAIT); + if (ret <= 0) + goto error; + + len -= ret; + offset += ret; + slen -= ret; + } + + offset = 0; + } + + if (len) { + /* Process any frag lists */ + + if (skb == head) { + if (skb_has_frag_list(skb)) { + skb = skb_shinfo(skb)->frag_list; + goto do_frag_list; + } + } else if (skb->next) { + skb = skb->next; + goto do_frag_list; + } + } + +out: + return orig_len - len; + +error: + return orig_len == len ? ret : orig_len - len; +} +EXPORT_SYMBOL_GPL(skb_send_sock_locked); + +/* Send skb data on a socket. */ +int skb_send_sock(struct sock *sk, struct sk_buff *skb, int offset, int len) +{ + int ret = 0; + + lock_sock(sk); + ret = skb_send_sock_locked(sk, skb, offset, len); + release_sock(sk); + + return ret; +} +EXPORT_SYMBOL_GPL(skb_send_sock); + /** * skb_store_bits - store bits from kernel buffer to skb * @skb: destination buffer @@ -2044,15 +2401,20 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { + u32 p_off, p_len, copied; + struct page *p; u8 *vaddr; if (copy > len) copy = len; - vaddr = kmap_atomic(skb_frag_page(frag)); - memcpy(vaddr + frag->page_offset + offset - start, - from, copy); - kunmap_atomic(vaddr); + skb_frag_foreach_page(frag, + frag->page_offset + offset - start, + copy, p, p_off, p_len, copied) { + vaddr = kmap_atomic(p); + memcpy(vaddr + p_off, from + copied, p_len); + kunmap_atomic(vaddr); + } if ((len -= copy) == 0) return 0; @@ -2117,20 +2479,27 @@ __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { + u32 p_off, p_len, copied; + struct page *p; __wsum csum2; u8 *vaddr; if (copy > len) copy = len; - vaddr = kmap_atomic(skb_frag_page(frag)); - csum2 = ops->update(vaddr + frag->page_offset + - offset - start, copy, 0); - kunmap_atomic(vaddr); - csum = ops->combine(csum, csum2, pos, copy); + + skb_frag_foreach_page(frag, + frag->page_offset + offset - start, + copy, p, p_off, p_len, copied) { + vaddr = kmap_atomic(p); + csum2 = ops->update(vaddr + p_off, p_len, 0); + kunmap_atomic(vaddr); + csum = ops->combine(csum, csum2, pos, p_len); + pos += p_len; + } + if (!(len -= copy)) return csum; offset += copy; - pos += copy; } start = end; } @@ -2203,24 +2572,31 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); if ((copy = end - offset) > 0) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + u32 p_off, p_len, copied; + struct page *p; __wsum csum2; u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; if (copy > len) copy = len; - vaddr = kmap_atomic(skb_frag_page(frag)); - csum2 = csum_partial_copy_nocheck(vaddr + - frag->page_offset + - offset - start, to, - copy, 0); - kunmap_atomic(vaddr); - csum = csum_block_add(csum, csum2, pos); + + skb_frag_foreach_page(frag, + frag->page_offset + offset - start, + copy, p, p_off, p_len, copied) { + vaddr = kmap_atomic(p); + csum2 = csum_partial_copy_nocheck(vaddr + p_off, + to + copied, + p_len, 0); + kunmap_atomic(vaddr); + csum = csum_block_add(csum, csum2, pos); + pos += p_len; + } + if (!(len -= copy)) return csum; offset += copy; to += copy; - pos += copy; } start = end; } @@ -2360,6 +2736,7 @@ skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen) skb_tx_error(from); return -ENOMEM; } + skb_zerocopy_clone(to, from, GFP_ATOMIC); for (i = 0; i < skb_shinfo(from)->nr_frags; i++) { if (!len) @@ -2657,6 +3034,7 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len) skb_shinfo(skb1)->tx_flags |= skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; + skb_zerocopy_clone(skb1, skb, 0); if (len < pos) /* Split line is inside header. */ skb_split_inside_header(skb, skb1, len, pos); else /* Second chunk has no header, nothing to copy. */ @@ -2700,6 +3078,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) if (skb_headlen(skb)) return 0; + if (skb_zcopy(tgt) || skb_zcopy(skb)) + return 0; todo = shiftlen; from = 0; @@ -3273,6 +3653,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & SKBTX_SHARED_FRAG; + if (skb_zerocopy_clone(nskb, head_skb, GFP_ATOMIC)) + goto err; while (pos < offset + len) { if (i >= nfrags) { @@ -4396,6 +4778,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, if (skb_has_frag_list(to) || skb_has_frag_list(from)) return false; + if (skb_zcopy(to) || skb_zcopy(from)) + return false; if (skb_headlen(from) != 0) { struct page *page; diff --git a/net/core/sock.c b/net/core/sock.c index ac2a404c73eb83fc100ed0a2d3bee40ad5a2044c..23953b741a41fbcf4a6ffb0dd5bf05bd5266b99d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -307,16 +307,6 @@ static struct lock_class_key af_wlock_keys[AF_MAX]; static struct lock_class_key af_elock_keys[AF_MAX]; static struct lock_class_key af_kern_callback_keys[AF_MAX]; -/* Take into consideration the size of the struct sk_buff overhead in the - * determination of these values, since that is non-constant across - * platforms. This makes socket queueing behavior and performance - * not depend upon such differences. - */ -#define _SK_MEM_PACKETS 256 -#define _SK_MEM_OVERHEAD SKB_TRUESIZE(256) -#define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) -#define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) - /* Run time adjustable parameters. */ __u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX; EXPORT_SYMBOL(sysctl_wmem_max); @@ -1055,6 +1045,20 @@ int sock_setsockopt(struct socket *sock, int level, int optname, if (val == 1) dst_negative_advice(sk); break; + + case SO_ZEROCOPY: + if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) + ret = -ENOTSUPP; + else if (sk->sk_protocol != IPPROTO_TCP) + ret = -ENOTSUPP; + else if (sk->sk_state != TCP_CLOSE) + ret = -EBUSY; + else if (val < 0 || val > 1) + ret = -EINVAL; + else + sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool); + break; + default: ret = -ENOPROTOOPT; break; @@ -1383,6 +1387,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, v.val64 = sock_gen_cookie(sk); break; + case SO_ZEROCOPY: + v.val = sock_flag(sk, SOCK_ZEROCOPY); + break; + default: /* We implement the SO_SNDLOWAT etc to not be settable * (1003.1g 7). @@ -1646,6 +1654,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) sock_copy(newsk, sk); + newsk->sk_prot_creator = sk->sk_prot; + /* SANITY */ if (likely(newsk->sk_net_refcnt)) get_net(sock_net(newsk)); @@ -1670,16 +1680,20 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) atomic_set(&newsk->sk_drops, 0); newsk->sk_send_head = NULL; newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; + atomic_set(&newsk->sk_zckey, 0); sock_reset_flag(newsk, SOCK_DONE); - filter = rcu_dereference_protected(newsk->sk_filter, 1); + rcu_read_lock(); + filter = rcu_dereference(sk->sk_filter); if (filter != NULL) /* though it's an empty new sock, the charging may fail * if sysctl_optmem_max was changed between creation of * original socket and cloning */ is_charged = sk_filter_charge(newsk, filter); + RCU_INIT_POINTER(newsk->sk_filter, filter); + rcu_read_unlock(); if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) { /* We need to make sure that we don't uncharge the new @@ -1757,7 +1771,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; sk->sk_route_caps &= ~sk->sk_route_nocaps; if (sk_can_gso(sk)) { - if (dst->header_len) { + if (dst->header_len && !xfrm_dst_offload_ok(dst)) { sk->sk_route_caps &= ~NETIF_F_GSO_MASK; } else { sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; @@ -1923,6 +1937,33 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, } EXPORT_SYMBOL(sock_wmalloc); +static void sock_ofree(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + + atomic_sub(skb->truesize, &sk->sk_omem_alloc); +} + +struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size, + gfp_t priority) +{ + struct sk_buff *skb; + + /* small safe race: SKB_TRUESIZE may differ from final skb->truesize */ + if (atomic_read(&sk->sk_omem_alloc) + SKB_TRUESIZE(size) > + sysctl_optmem_max) + return NULL; + + skb = alloc_skb(size, priority); + if (!skb) + return NULL; + + atomic_add(skb->truesize, &sk->sk_omem_alloc); + skb->sk = sk; + skb->destructor = sock_ofree; + return skb; +} + /* * Allocate a memory block from the socket's option memory buffer. */ @@ -2408,9 +2449,6 @@ EXPORT_SYMBOL(__sk_mem_reclaim); int sk_set_peek_off(struct sock *sk, int val) { - if (val < 0) - return -EINVAL; - sk->sk_peek_off = val; return 0; } @@ -2500,6 +2538,12 @@ int sock_no_sendmsg(struct socket *sock, struct msghdr *m, size_t len) } EXPORT_SYMBOL(sock_no_sendmsg); +int sock_no_sendmsg_locked(struct sock *sk, struct msghdr *m, size_t len) +{ + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(sock_no_sendmsg_locked); + int sock_no_recvmsg(struct socket *sock, struct msghdr *m, size_t len, int flags) { @@ -2528,6 +2572,22 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz } EXPORT_SYMBOL(sock_no_sendpage); +ssize_t sock_no_sendpage_locked(struct sock *sk, struct page *page, + int offset, size_t size, int flags) +{ + ssize_t res; + struct msghdr msg = {.msg_flags = flags}; + struct kvec iov; + char *kaddr = kmap(page); + + iov.iov_base = kaddr + offset; + iov.iov_len = size; + res = kernel_sendmsg_locked(sk, &msg, &iov, 1, size); + kunmap(page); + return res; +} +EXPORT_SYMBOL(sock_no_sendpage_locked); + /* * Default Socket Callbacks */ @@ -2673,6 +2733,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; sk->sk_stamp = SK_DEFAULT_STAMP; + atomic_set(&sk->sk_zckey, 0); #ifdef CONFIG_NET_RX_BUSY_POLL sk->sk_napi_id = 0; diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 733f523707acfb8c9a296436a0b6c5d603bc3f4e..bae7d78aa06895dd9237abc6f1bc2ae3db23f38b 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1938,8 +1938,8 @@ static int __init dcbnl_init(void) { INIT_LIST_HEAD(&dcb_app_list); - rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); + rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0); return 0; } diff --git a/net/dccp/feat.c b/net/dccp/feat.c index 1704948e6a12bc87827c71ccb4e81de8b8c2c9f7..f227f002c73d382fecd98c8857ce4c9139cb7a8a 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -1471,9 +1471,12 @@ int dccp_feat_init(struct sock *sk) * singleton values (which always leads to failure). * These settings can still (later) be overridden via sockopts. */ - if (ccid_get_builtin_ccids(&tx.val, &tx.len) || - ccid_get_builtin_ccids(&rx.val, &rx.len)) + if (ccid_get_builtin_ccids(&tx.val, &tx.len)) return -ENOBUFS; + if (ccid_get_builtin_ccids(&rx.val, &rx.len)) { + kfree(tx.val); + return -ENOBUFS; + } if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) || !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len)) diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index f85d901f4e3fc02741ad20f3ff3066108af1e7e8..001c08696334bba0ceb896c116e595b814af0667 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -256,7 +256,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) sk = __inet_lookup_established(net, &dccp_hashinfo, iph->daddr, dh->dccph_dport, iph->saddr, ntohs(dh->dccph_sport), - inet_iif(skb)); + inet_iif(skb), 0); if (!sk) { __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); return; @@ -631,6 +631,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) goto drop_and_free; inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); + reqsk_put(req); return 0; drop_and_free: @@ -803,7 +804,7 @@ static int dccp_v4_rcv(struct sk_buff *skb) lookup: sk = __inet_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh), - dh->dccph_sport, dh->dccph_dport, &refcounted); + dh->dccph_sport, dh->dccph_dport, 0, &refcounted); if (!sk) { dccp_pr_debug("failed to look up flow ID in table and " "get corresponding socket\n"); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index c376af5bfdfb34774d82de6858ec0e4b6e3380bb..5df7857fc0f3aeefb2ed0324d97d13cb68551383 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include "dccp.h" #include "ipv6.h" @@ -89,7 +91,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, sk = __inet6_lookup_established(net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport, &hdr->saddr, ntohs(dh->dccph_sport), - inet6_iif(skb)); + inet6_iif(skb), 0); if (!sk) { __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), @@ -380,6 +382,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) goto drop_and_free; inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); + reqsk_put(req); return 0; drop_and_free: @@ -596,19 +599,13 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) --ANK (980728) */ if (np->rxopt.all) - /* - * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below - * (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example. - */ opt_skb = skb_clone(skb, GFP_ATOMIC); if (sk->sk_state == DCCP_OPEN) { /* Fast path */ if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) goto reset; - if (opt_skb) { - /* XXX This is where we would goto ipv6_pktoptions. */ - __kfree_skb(opt_skb); - } + if (opt_skb) + goto ipv6_pktoptions; return 0; } @@ -639,10 +636,8 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) goto reset; - if (opt_skb) { - /* XXX This is where we would goto ipv6_pktoptions. */ - __kfree_skb(opt_skb); - } + if (opt_skb) + goto ipv6_pktoptions; return 0; reset: @@ -652,6 +647,35 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) __kfree_skb(opt_skb); kfree_skb(skb); return 0; + +/* Handling IPV6_PKTOPTIONS skb the similar + * way it's done for net/ipv6/tcp_ipv6.c + */ +ipv6_pktoptions: + if (!((1 << sk->sk_state) & (DCCPF_CLOSED | DCCPF_LISTEN))) { + if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo) + np->mcast_oif = inet6_iif(opt_skb); + if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) + np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; + if (np->rxopt.bits.rxflow || np->rxopt.bits.rxtclass) + np->rcv_flowinfo = ip6_flowinfo(ipv6_hdr(opt_skb)); + if (np->repflow) + np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); + if (ipv6_opt_accepted(sk, opt_skb, + &DCCP_SKB_CB(opt_skb)->header.h6)) { + skb_set_owner_r(opt_skb, sk); + memmove(IP6CB(opt_skb), + &DCCP_SKB_CB(opt_skb)->header.h6, + sizeof(struct inet6_skb_parm)); + opt_skb = xchg(&np->pktoptions, opt_skb); + } else { + __kfree_skb(opt_skb); + opt_skb = xchg(&np->pktoptions, NULL); + } + } + + kfree_skb(opt_skb); + return 0; } static int dccp_v6_rcv(struct sk_buff *skb) @@ -686,7 +710,7 @@ static int dccp_v6_rcv(struct sk_buff *skb) lookup: sk = __inet6_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh), dh->dccph_sport, dh->dccph_dport, - inet6_iif(skb), &refcounted); + inet6_iif(skb), 0, &refcounted); if (!sk) { dccp_pr_debug("failed to look up flow ID in table and " "get corresponding socket\n"); diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 9fe25bf6329691ecf0acdc35df7278b074d446c1..b68168fcc06aa1981258eca4857511329af62f9a 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -170,6 +171,15 @@ const char *dccp_packet_name(const int type) EXPORT_SYMBOL_GPL(dccp_packet_name); +static void dccp_sk_destruct(struct sock *sk) +{ + struct dccp_sock *dp = dccp_sk(sk); + + ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); + dp->dccps_hc_tx_ccid = NULL; + inet_sock_destruct(sk); +} + int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) { struct dccp_sock *dp = dccp_sk(sk); @@ -179,6 +189,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) icsk->icsk_syn_retries = sysctl_dccp_request_retries; sk->sk_state = DCCP_CLOSED; sk->sk_write_space = dccp_write_space; + sk->sk_destruct = dccp_sk_destruct; icsk->icsk_sync_mss = dccp_sync_mss; dp->dccps_mss_cache = 536; dp->dccps_rate_last = jiffies; @@ -201,10 +212,7 @@ void dccp_destroy_sock(struct sock *sk) { struct dccp_sock *dp = dccp_sk(sk); - /* - * DCCP doesn't use sk_write_queue, just sk_send_head - * for retransmissions - */ + __skb_queue_purge(&sk->sk_write_queue); if (sk->sk_send_head != NULL) { kfree_skb(sk->sk_send_head); sk->sk_send_head = NULL; @@ -222,8 +230,7 @@ void dccp_destroy_sock(struct sock *sk) dp->dccps_hc_rx_ackvec = NULL; } ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk); - ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); - dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL; + dp->dccps_hc_rx_ccid = NULL; /* clean up feature negotiation state */ dccp_feat_list_purge(&dp->dccps_featneg); diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index fa0110b57ca122f858ac93e557cb8cb10556f0a9..4d339de56862ce5c9bdf7a82f2bc3506553d43a0 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -1419,9 +1419,9 @@ void __init dn_dev_init(void) dn_dev_devices_on(); - rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL, NULL); - rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL, NULL); - rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr, NULL); + rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL, 0); + rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL, 0); + rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr, 0); proc_create("decnet_dev", S_IRUGO, init_net.proc_net, &dn_dev_seq_fops); diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index f9f6fb3f3c5b3dd520263448a784a99925c87b09..3d37464c8b4aa4be97333b95216b89aa9e711e9e 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -791,8 +791,8 @@ void __init dn_fib_init(void) register_dnaddr_notifier(&dn_fib_dnaddr_notifier); - rtnl_register(PF_DECnet, RTM_NEWROUTE, dn_fib_rtm_newroute, NULL, NULL); - rtnl_register(PF_DECnet, RTM_DELROUTE, dn_fib_rtm_delroute, NULL, NULL); + rtnl_register(PF_DECnet, RTM_NEWROUTE, dn_fib_rtm_newroute, NULL, 0); + rtnl_register(PF_DECnet, RTM_DELROUTE, dn_fib_rtm_delroute, NULL, 0); } diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 21dedf6fd0f76dec22b2b3685beb89cfefea7ded..22bf0b95d6edc3c27ef3a99d27cb70a1551e3e0e 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -94,7 +94,7 @@ struct neigh_table dn_neigh_table = { [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ, [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ, [NEIGH_VAR_GC_STALETIME] = 60 * HZ, - [NEIGH_VAR_QUEUE_LEN_BYTES] = 64*1024, + [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX, [NEIGH_VAR_PROXY_QLEN] = 0, [NEIGH_VAR_ANYCAST_DELAY] = 0, [NEIGH_VAR_PROXY_DELAY] = 0, diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index bcbe548f8854e103146932c0a7006b1ba04f3bfd..0bd3afd01dd2994bcbfc6d3a79a47cf8a25a7df0 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1922,10 +1922,10 @@ void __init dn_route_init(void) #ifdef CONFIG_DECNET_ROUTER rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, - dn_fib_dump, NULL); + dn_fib_dump, 0); #else rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, - dn_cache_dump, NULL); + dn_cache_dump, 0); #endif } diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index aa8ffecc46a439fa129dfea9c1f4d4e525ad3796..ab395e55cd7895691682548b4c042dfbc3a7b127 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -115,7 +115,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) RCV_SKB_FAIL(-EINVAL); } -static struct nf_hook_ops dnrmg_ops __read_mostly = { +static const struct nf_hook_ops dnrmg_ops = { .hook = dnrmg_hook, .pf = NFPROTO_DECNET, .hooknum = NF_DN_ROUTE, diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 416ac4ef9ba9c5d77f36e6902cf031628f72cc05..03c58b0eb082a5e5c125e2184bb29c80023cf017 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -67,17 +67,17 @@ const struct dsa_device_ops *dsa_device_ops[DSA_TAG_LAST] = { [DSA_TAG_PROTO_NONE] = &none_ops, }; -int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, - struct dsa_port *dport, int port) +int dsa_cpu_dsa_setup(struct dsa_port *port) { - struct device_node *port_dn = dport->dn; + struct device_node *port_dn = port->dn; + struct dsa_switch *ds = port->ds; struct phy_device *phydev; int ret, mode; if (of_phy_is_fixed_link(port_dn)) { ret = of_phy_register_fixed_link(port_dn); if (ret) { - dev_err(dev, "failed to register fixed PHY\n"); + dev_err(ds->dev, "failed to register fixed PHY\n"); return ret; } phydev = of_phy_find_device(port_dn); @@ -90,7 +90,7 @@ int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, genphy_config_init(phydev); genphy_read_status(phydev); if (ds->ops->adjust_link) - ds->ops->adjust_link(ds, port, phydev); + ds->ops->adjust_link(ds, port->index, phydev); put_device(&phydev->mdio.dev); } @@ -186,10 +186,12 @@ struct net_device *dsa_dev_to_net_device(struct device *dev) EXPORT_SYMBOL_GPL(dsa_dev_to_net_device); static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) + struct packet_type *pt, struct net_device *unused) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct sk_buff *nskb = NULL; + struct pcpu_sw_netstats *s; + struct dsa_slave_priv *p; if (unlikely(dst == NULL)) { kfree_skb(skb); @@ -200,19 +202,23 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, if (!skb) return 0; - nskb = dst->rcv(skb, dev, pt, orig_dev); + nskb = dst->rcv(skb, dev, pt); if (!nskb) { kfree_skb(skb); return 0; } skb = nskb; + p = netdev_priv(skb->dev); skb_push(skb, ETH_HLEN); skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, skb->dev); - skb->dev->stats.rx_packets++; - skb->dev->stats.rx_bytes += skb->len; + s = this_cpu_ptr(p->stats64); + u64_stats_update_begin(&s->syncp); + s->rx_packets++; + s->rx_bytes += skb->len; + u64_stats_update_end(&s->syncp); netif_receive_skb(skb); @@ -220,6 +226,11 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, } #ifdef CONFIG_PM_SLEEP +static bool dsa_is_port_initialized(struct dsa_switch *ds, int p) +{ + return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev; +} + int dsa_switch_suspend(struct dsa_switch *ds) { int i, ret = 0; @@ -271,10 +282,22 @@ static struct packet_type dsa_pack_type __read_mostly = { .func = dsa_switch_rcv, }; +static struct workqueue_struct *dsa_owq; + +bool dsa_schedule_work(struct work_struct *work) +{ + return queue_work(dsa_owq, work); +} + static int __init dsa_init_module(void) { int rc; + dsa_owq = alloc_ordered_workqueue("dsa_ordered", + WQ_MEM_RECLAIM); + if (!dsa_owq) + return -ENOMEM; + rc = dsa_slave_register_notifier(); if (rc) return rc; @@ -294,6 +317,7 @@ static void __exit dsa_cleanup_module(void) dsa_slave_unregister_notifier(); dev_remove_pack(&dsa_pack_type); dsa_legacy_unregister(); + destroy_workqueue(dsa_owq); } module_exit(dsa_cleanup_module); diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 56e46090526bb3baf26b5e06478cdd66ccc94280..873af0108e243fc269f591ec7d7c59a9c8b374fc 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -219,7 +219,7 @@ static int dsa_dsa_port_apply(struct dsa_port *port) struct dsa_switch *ds = port->ds; int err; - err = dsa_cpu_dsa_setup(ds, ds->dev, port, port->index); + err = dsa_cpu_dsa_setup(port); if (err) { dev_warn(ds->dev, "Failed to setup dsa port %d: %d\n", port->index, err); @@ -243,7 +243,7 @@ static int dsa_cpu_port_apply(struct dsa_port *port) struct dsa_switch *ds = port->ds; int err; - err = dsa_cpu_dsa_setup(ds, ds->dev, port, port->index); + err = dsa_cpu_dsa_setup(port); if (err) { dev_warn(ds->dev, "Failed to setup cpu port %d: %d\n", port->index, err); @@ -275,7 +275,7 @@ static int dsa_user_port_apply(struct dsa_port *port) if (!name) name = "eth%d"; - err = dsa_slave_create(ds, ds->dev, port->index, name); + err = dsa_slave_create(port, name); if (err) { dev_warn(ds->dev, "Failed to create slave %d: %d\n", port->index, err); @@ -509,21 +509,22 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, dst->cpu_dp->netdev = ethernet_dev; } + /* Initialize cpu_port_mask now for drv->setup() + * to have access to a correct value, just like what + * net/dsa/dsa.c::dsa_switch_setup_one does. + */ + ds->cpu_port_mask |= BIT(index); + tag_protocol = ds->ops->get_tag_protocol(ds); dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol); if (IS_ERR(dst->tag_ops)) { dev_warn(ds->dev, "No tagger for this switch\n"); + ds->cpu_port_mask &= ~BIT(index); return PTR_ERR(dst->tag_ops); } dst->rcv = dst->tag_ops->rcv; - /* Initialize cpu_port_mask now for drv->setup() - * to have access to a correct value, just like what - * net/dsa/dsa.c::dsa_switch_setup_one does. - */ - ds->cpu_port_mask |= BIT(index); - return 0; } @@ -576,7 +577,7 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) return err; } - if (!dst->cpu_dp->netdev) { + if (!dst->cpu_dp) { pr_warn("Tree has no master device\n"); return -EINVAL; } diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 55982cc39b24d79077f3120f47f54d4e621286c6..9c3eeb72462d88cfa77704884ad083c8e462bf5b 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -43,10 +43,10 @@ struct dsa_notifier_bridge_info { /* DSA_NOTIFIER_FDB_* */ struct dsa_notifier_fdb_info { - const struct switchdev_obj_port_fdb *fdb; - struct switchdev_trans *trans; int sw_index; int port; + const unsigned char *addr; + u16 vid; }; /* DSA_NOTIFIER_MDB_* */ @@ -65,18 +65,13 @@ struct dsa_notifier_vlan_info { int port; }; -struct dsa_device_ops { - struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); - struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev); -}; - struct dsa_slave_priv { /* Copy of dp->ds->dst->tag_ops->xmit for faster access in hot path */ struct sk_buff * (*xmit)(struct sk_buff *skb, struct net_device *dev); + struct pcpu_sw_netstats *stats64; + /* DSA port data, such as switch, port index, etc. */ struct dsa_port *dp; @@ -99,16 +94,23 @@ struct dsa_slave_priv { }; /* dsa.c */ -int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, - struct dsa_port *dport, int port); +int dsa_cpu_dsa_setup(struct dsa_port *port); void dsa_cpu_dsa_destroy(struct dsa_port *dport); const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol); int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp); void dsa_cpu_port_ethtool_restore(struct dsa_port *cpu_dp); +bool dsa_schedule_work(struct work_struct *work); /* legacy.c */ int dsa_legacy_register(void); void dsa_legacy_unregister(void); +int dsa_legacy_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, u16 vid, + u16 flags); +int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, u16 vid); /* port.c */ int dsa_port_set_state(struct dsa_port *dp, u8 state, @@ -120,35 +122,25 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering, struct switchdev_trans *trans); int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock, struct switchdev_trans *trans); -int dsa_port_fdb_add(struct dsa_port *dp, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans); -int dsa_port_fdb_del(struct dsa_port *dp, - const struct switchdev_obj_port_fdb *fdb); -int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb, - switchdev_obj_dump_cb_t *cb); +int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, + u16 vid); +int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr, + u16 vid); int dsa_port_mdb_add(struct dsa_port *dp, const struct switchdev_obj_port_mdb *mdb, struct switchdev_trans *trans); int dsa_port_mdb_del(struct dsa_port *dp, const struct switchdev_obj_port_mdb *mdb); -int dsa_port_mdb_dump(struct dsa_port *dp, struct switchdev_obj_port_mdb *mdb, - switchdev_obj_dump_cb_t *cb); int dsa_port_vlan_add(struct dsa_port *dp, const struct switchdev_obj_port_vlan *vlan, struct switchdev_trans *trans); int dsa_port_vlan_del(struct dsa_port *dp, const struct switchdev_obj_port_vlan *vlan); -int dsa_port_vlan_dump(struct dsa_port *dp, - struct switchdev_obj_port_vlan *vlan, - switchdev_obj_dump_cb_t *cb); - /* slave.c */ extern const struct dsa_device_ops notag_netdev_ops; void dsa_slave_mii_bus_init(struct dsa_switch *ds); void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops); -int dsa_slave_create(struct dsa_switch *ds, struct device *parent, - int port, const char *name); +int dsa_slave_create(struct dsa_port *port, const char *name); void dsa_slave_destroy(struct net_device *slave_dev); int dsa_slave_suspend(struct net_device *slave_dev); int dsa_slave_resume(struct net_device *slave_dev); diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c index 1d7a3282f2a7c20e5d21e2ce57bd56e39785d1bc..91e6f7981d3912b5187494183a812c3a281ba766 100644 --- a/net/dsa/legacy.c +++ b/net/dsa/legacy.c @@ -78,25 +78,23 @@ dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr, } /* basic switch operations **************************************************/ -static int dsa_cpu_dsa_setups(struct dsa_switch *ds, struct device *dev) +static int dsa_cpu_dsa_setups(struct dsa_switch *ds) { - struct dsa_port *dport; int ret, port; for (port = 0; port < ds->num_ports; port++) { if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))) continue; - dport = &ds->ports[port]; - ret = dsa_cpu_dsa_setup(ds, dev, dport, port); + ret = dsa_cpu_dsa_setup(&ds->ports[port]); if (ret) return ret; } return 0; } -static int dsa_switch_setup_one(struct dsa_switch *ds, struct net_device *master, - struct device *parent) +static int dsa_switch_setup_one(struct dsa_switch *ds, + struct net_device *master) { const struct dsa_switch_ops *ops = ds->ops; struct dsa_switch_tree *dst = ds->dst; @@ -176,7 +174,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct net_device *master } if (!ds->slave_mii_bus && ops->phy_read) { - ds->slave_mii_bus = devm_mdiobus_alloc(parent); + ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev); if (!ds->slave_mii_bus) return -ENOMEM; dsa_slave_mii_bus_init(ds); @@ -196,14 +194,14 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct net_device *master if (!(ds->enabled_port_mask & (1 << i))) continue; - ret = dsa_slave_create(ds, parent, i, cd->port_names[i]); + ret = dsa_slave_create(&ds->ports[i], cd->port_names[i]); if (ret < 0) netdev_err(master, "[%d]: can't create dsa slave device for port %d(%s): %d\n", index, i, cd->port_names[i], ret); } /* Perform configuration of the CPU and DSA ports */ - ret = dsa_cpu_dsa_setups(ds, parent); + ret = dsa_cpu_dsa_setups(ds); if (ret < 0) netdev_err(master, "[%d] : can't configure CPU and DSA ports\n", index); @@ -252,7 +250,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, struct net_device *master, ds->ops = ops; ds->priv = priv; - ret = dsa_switch_setup_one(ds, master, parent); + ret = dsa_switch_setup_one(ds, master); if (ret) return ERR_PTR(ret); @@ -741,6 +739,28 @@ static int dsa_resume(struct device *d) } #endif +/* legacy way, bypassing the bridge *****************************************/ +int dsa_legacy_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, u16 vid, + u16 flags) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_port *dp = p->dp; + + return dsa_port_fdb_add(dp, addr, vid); +} + +int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, u16 vid) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_port *dp = p->dp; + + return dsa_port_fdb_del(dp, addr, vid); +} + static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa_suspend, dsa_resume); static const struct of_device_id dsa_of_match_table[] = { diff --git a/net/dsa/port.c b/net/dsa/port.c index efc3bce3a89d7068af05b213e344bc64a0a46675..659676ba3f8b495a6b539727d6031215e6e1dfee 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -146,43 +146,33 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock, return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info); } -int dsa_port_fdb_add(struct dsa_port *dp, - const struct switchdev_obj_port_fdb *fdb, - struct switchdev_trans *trans) +int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, + u16 vid) { struct dsa_notifier_fdb_info info = { .sw_index = dp->ds->index, .port = dp->index, - .trans = trans, - .fdb = fdb, + .addr = addr, + .vid = vid, }; return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info); } -int dsa_port_fdb_del(struct dsa_port *dp, - const struct switchdev_obj_port_fdb *fdb) +int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr, + u16 vid) { struct dsa_notifier_fdb_info info = { .sw_index = dp->ds->index, .port = dp->index, - .fdb = fdb, + .addr = addr, + .vid = vid, + }; return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info); } -int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb, - switchdev_obj_dump_cb_t *cb) -{ - struct dsa_switch *ds = dp->ds; - - if (ds->ops->port_fdb_dump) - return ds->ops->port_fdb_dump(ds, dp->index, fdb, cb); - - return -EOPNOTSUPP; -} - int dsa_port_mdb_add(struct dsa_port *dp, const struct switchdev_obj_port_mdb *mdb, struct switchdev_trans *trans) @@ -209,17 +199,6 @@ int dsa_port_mdb_del(struct dsa_port *dp, return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info); } -int dsa_port_mdb_dump(struct dsa_port *dp, struct switchdev_obj_port_mdb *mdb, - switchdev_obj_dump_cb_t *cb) -{ - struct dsa_switch *ds = dp->ds; - - if (ds->ops->port_mdb_dump) - return ds->ops->port_mdb_dump(ds, dp->index, mdb, cb); - - return -EOPNOTSUPP; -} - int dsa_port_vlan_add(struct dsa_port *dp, const struct switchdev_obj_port_vlan *vlan, struct switchdev_trans *trans) @@ -245,15 +224,3 @@ int dsa_port_vlan_del(struct dsa_port *dp, return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); } - -int dsa_port_vlan_dump(struct dsa_port *dp, - struct switchdev_obj_port_vlan *vlan, - switchdev_obj_dump_cb_t *cb) -{ - struct dsa_switch *ds = dp->ds; - - if (ds->ops->port_vlan_dump) - return ds->ops->port_vlan_dump(ds, dp->index, vlan, cb); - - return -EOPNOTSUPP; -} diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 9507bd38cf0441578de213178e23a692d8aed072..865e29e62bad87e7fede6599ace0645ebbd2d196 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -199,6 +199,83 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) return 0; } +struct dsa_slave_dump_ctx { + struct net_device *dev; + struct sk_buff *skb; + struct netlink_callback *cb; + int idx; +}; + +static int +dsa_slave_port_fdb_do_dump(const unsigned char *addr, u16 vid, + bool is_static, void *data) +{ + struct dsa_slave_dump_ctx *dump = data; + u32 portid = NETLINK_CB(dump->cb->skb).portid; + u32 seq = dump->cb->nlh->nlmsg_seq; + struct nlmsghdr *nlh; + struct ndmsg *ndm; + + if (dump->idx < dump->cb->args[2]) + goto skip; + + nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH, + sizeof(*ndm), NLM_F_MULTI); + if (!nlh) + return -EMSGSIZE; + + ndm = nlmsg_data(nlh); + ndm->ndm_family = AF_BRIDGE; + ndm->ndm_pad1 = 0; + ndm->ndm_pad2 = 0; + ndm->ndm_flags = NTF_SELF; + ndm->ndm_type = 0; + ndm->ndm_ifindex = dump->dev->ifindex; + ndm->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE; + + if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, addr)) + goto nla_put_failure; + + if (vid && nla_put_u16(dump->skb, NDA_VLAN, vid)) + goto nla_put_failure; + + nlmsg_end(dump->skb, nlh); + +skip: + dump->idx++; + return 0; + +nla_put_failure: + nlmsg_cancel(dump->skb, nlh); + return -EMSGSIZE; +} + +static int +dsa_slave_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, + struct net_device *dev, struct net_device *filter_dev, + int *idx) +{ + struct dsa_slave_dump_ctx dump = { + .dev = dev, + .skb = skb, + .cb = cb, + .idx = *idx, + }; + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_port *dp = p->dp; + struct dsa_switch *ds = dp->ds; + int err; + + if (!ds->ops->port_fdb_dump) + return -EOPNOTSUPP; + + err = ds->ops->port_fdb_dump(ds, dp->index, + dsa_slave_port_fdb_do_dump, + &dump); + *idx = dump.idx; + return err; +} + static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct dsa_slave_priv *p = netdev_priv(dev); @@ -250,9 +327,6 @@ static int dsa_slave_port_obj_add(struct net_device *dev, */ switch (obj->id) { - case SWITCHDEV_OBJ_ID_PORT_FDB: - err = dsa_port_fdb_add(dp, SWITCHDEV_OBJ_PORT_FDB(obj), trans); - break; case SWITCHDEV_OBJ_ID_PORT_MDB: err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj), trans); break; @@ -276,9 +350,6 @@ static int dsa_slave_port_obj_del(struct net_device *dev, int err; switch (obj->id) { - case SWITCHDEV_OBJ_ID_PORT_FDB: - err = dsa_port_fdb_del(dp, SWITCHDEV_OBJ_PORT_FDB(obj)); - break; case SWITCHDEV_OBJ_ID_PORT_MDB: err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); break; @@ -293,32 +364,6 @@ static int dsa_slave_port_obj_del(struct net_device *dev, return err; } -static int dsa_slave_port_obj_dump(struct net_device *dev, - struct switchdev_obj *obj, - switchdev_obj_dump_cb_t *cb) -{ - struct dsa_slave_priv *p = netdev_priv(dev); - struct dsa_port *dp = p->dp; - int err; - - switch (obj->id) { - case SWITCHDEV_OBJ_ID_PORT_FDB: - err = dsa_port_fdb_dump(dp, SWITCHDEV_OBJ_PORT_FDB(obj), cb); - break; - case SWITCHDEV_OBJ_ID_PORT_MDB: - err = dsa_port_mdb_dump(dp, SWITCHDEV_OBJ_PORT_MDB(obj), cb); - break; - case SWITCHDEV_OBJ_ID_PORT_VLAN: - err = dsa_port_vlan_dump(dp, SWITCHDEV_OBJ_PORT_VLAN(obj), cb); - break; - default: - err = -EOPNOTSUPP; - break; - } - - return err; -} - static int dsa_slave_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) { @@ -330,6 +375,9 @@ static int dsa_slave_port_attr_get(struct net_device *dev, attr->u.ppid.id_len = sizeof(ds->index); memcpy(&attr->u.ppid.id, &ds->index, attr->u.ppid.id_len); break; + case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT: + attr->u.brport_flags_support = 0; + break; default: return -EOPNOTSUPP; } @@ -352,10 +400,14 @@ static inline netdev_tx_t dsa_netpoll_send_skb(struct dsa_slave_priv *p, static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); + struct pcpu_sw_netstats *s; struct sk_buff *nskb; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + s = this_cpu_ptr(p->stats64); + u64_stats_update_begin(&s->syncp); + s->tx_packets++; + s->tx_bytes += skb->len; + u64_stats_update_end(&s->syncp); /* Transmit function may have to reallocate the original SKB, * in which case it must have freed it. Only free it here on error. @@ -594,11 +646,26 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, { struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_switch *ds = p->dp->ds; - - data[0] = dev->stats.tx_packets; - data[1] = dev->stats.tx_bytes; - data[2] = dev->stats.rx_packets; - data[3] = dev->stats.rx_bytes; + struct pcpu_sw_netstats *s; + unsigned int start; + int i; + + for_each_possible_cpu(i) { + u64 tx_packets, tx_bytes, rx_packets, rx_bytes; + + s = per_cpu_ptr(p->stats64, i); + do { + start = u64_stats_fetch_begin_irq(&s->syncp); + tx_packets = s->tx_packets; + tx_bytes = s->tx_bytes; + rx_packets = s->rx_packets; + rx_bytes = s->rx_bytes; + } while (u64_stats_fetch_retry_irq(&s->syncp, start)); + data[0] += tx_packets; + data[1] += tx_bytes; + data[2] += rx_packets; + data[3] += rx_bytes; + } if (ds->ops->get_ethtool_stats) ds->ops->get_ethtool_stats(ds, p->dp->index, data + 4); } @@ -648,17 +715,24 @@ static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e) struct dsa_switch *ds = p->dp->ds; int ret; - if (!ds->ops->set_eee) + /* Port's PHY and MAC both need to be EEE capable */ + if (!p->phy) + return -ENODEV; + + if (!ds->ops->set_mac_eee) return -EOPNOTSUPP; - ret = ds->ops->set_eee(ds, p->dp->index, p->phy, e); + ret = ds->ops->set_mac_eee(ds, p->dp->index, e); if (ret) return ret; - if (p->phy) - ret = phy_ethtool_set_eee(p->phy, e); + if (e->eee_enabled) { + ret = phy_init_eee(p->phy, 0); + if (ret) + return ret; + } - return ret; + return phy_ethtool_set_eee(p->phy, e); } static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) @@ -667,17 +741,18 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) struct dsa_switch *ds = p->dp->ds; int ret; - if (!ds->ops->get_eee) + /* Port's PHY and MAC both need to be EEE capable */ + if (!p->phy) + return -ENODEV; + + if (!ds->ops->get_mac_eee) return -EOPNOTSUPP; - ret = ds->ops->get_eee(ds, p->dp->index, e); + ret = ds->ops->get_mac_eee(ds, p->dp->index, e); if (ret) return ret; - if (p->phy) - ret = phy_ethtool_get_eee(p->phy, e); - - return ret; + return phy_ethtool_get_eee(p->phy, e); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -747,12 +822,12 @@ dsa_slave_mall_tc_entry_find(struct dsa_slave_priv *p, } static int dsa_slave_add_cls_matchall(struct net_device *dev, - __be16 protocol, struct tc_cls_matchall_offload *cls, bool ingress) { struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_mall_tc_entry *mall_tc_entry; + __be16 protocol = cls->common.protocol; struct dsa_switch *ds = p->dp->ds; struct net *net = dev_net(dev); struct dsa_slave_priv *to_p; @@ -765,7 +840,7 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev, if (!ds->ops->port_mirror_add) return err; - if (!tc_single_action(cls->exts)) + if (!tcf_exts_has_one_action(cls->exts)) return err; tcf_exts_to_list(cls->exts, &actions); @@ -836,31 +911,71 @@ static void dsa_slave_del_cls_matchall(struct net_device *dev, kfree(mall_tc_entry); } -static int dsa_slave_setup_tc(struct net_device *dev, u32 handle, - u32 chain_index, __be16 protocol, - struct tc_to_netdev *tc) +static int dsa_slave_setup_tc_cls_matchall(struct net_device *dev, + struct tc_cls_matchall_offload *cls) { - bool ingress = TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS); + bool ingress; - if (chain_index) + if (is_classid_clsact_ingress(cls->common.classid)) + ingress = true; + else if (is_classid_clsact_egress(cls->common.classid)) + ingress = false; + else return -EOPNOTSUPP; - switch (tc->type) { - case TC_SETUP_MATCHALL: - switch (tc->cls_mall->command) { - case TC_CLSMATCHALL_REPLACE: - return dsa_slave_add_cls_matchall(dev, protocol, - tc->cls_mall, - ingress); - case TC_CLSMATCHALL_DESTROY: - dsa_slave_del_cls_matchall(dev, tc->cls_mall); - return 0; - } + if (cls->common.chain_index) + return -EOPNOTSUPP; + + switch (cls->command) { + case TC_CLSMATCHALL_REPLACE: + return dsa_slave_add_cls_matchall(dev, cls, ingress); + case TC_CLSMATCHALL_DESTROY: + dsa_slave_del_cls_matchall(dev, cls); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int dsa_slave_setup_tc(struct net_device *dev, enum tc_setup_type type, + void *type_data) +{ + switch (type) { + case TC_SETUP_CLSMATCHALL: + return dsa_slave_setup_tc_cls_matchall(dev, type_data); default: return -EOPNOTSUPP; } } +static void dsa_slave_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct pcpu_sw_netstats *s; + unsigned int start; + int i; + + netdev_stats_to_stats64(stats, &dev->stats); + for_each_possible_cpu(i) { + u64 tx_packets, tx_bytes, rx_packets, rx_bytes; + + s = per_cpu_ptr(p->stats64, i); + do { + start = u64_stats_fetch_begin_irq(&s->syncp); + tx_packets = s->tx_packets; + tx_bytes = s->tx_bytes; + rx_packets = s->rx_packets; + rx_bytes = s->rx_bytes; + } while (u64_stats_fetch_retry_irq(&s->syncp, start)); + + stats->tx_packets += tx_packets; + stats->tx_bytes += tx_bytes; + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; + } +} + void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops) { ops->get_sset_count = dsa_cpu_port_get_sset_count; @@ -921,9 +1036,9 @@ static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_change_rx_flags = dsa_slave_change_rx_flags, .ndo_set_rx_mode = dsa_slave_set_rx_mode, .ndo_set_mac_address = dsa_slave_set_mac_address, - .ndo_fdb_add = switchdev_port_fdb_add, - .ndo_fdb_del = switchdev_port_fdb_del, - .ndo_fdb_dump = switchdev_port_fdb_dump, + .ndo_fdb_add = dsa_legacy_fdb_add, + .ndo_fdb_del = dsa_legacy_fdb_del, + .ndo_fdb_dump = dsa_slave_fdb_dump, .ndo_do_ioctl = dsa_slave_ioctl, .ndo_get_iflink = dsa_slave_get_iflink, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -931,11 +1046,9 @@ static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_netpoll_cleanup = dsa_slave_netpoll_cleanup, .ndo_poll_controller = dsa_slave_poll_controller, #endif - .ndo_bridge_getlink = switchdev_port_bridge_getlink, - .ndo_bridge_setlink = switchdev_port_bridge_setlink, - .ndo_bridge_dellink = switchdev_port_bridge_dellink, .ndo_get_phys_port_name = dsa_slave_get_phys_port_name, .ndo_setup_tc = dsa_slave_setup_tc, + .ndo_get_stats64 = dsa_slave_get_stats64, }; static const struct switchdev_ops dsa_slave_switchdev_ops = { @@ -943,7 +1056,6 @@ static const struct switchdev_ops dsa_slave_switchdev_ops = { .switchdev_port_attr_set = dsa_slave_port_attr_set, .switchdev_port_obj_add = dsa_slave_port_obj_add, .switchdev_port_obj_del = dsa_slave_port_obj_del, - .switchdev_port_obj_dump = dsa_slave_port_obj_dump, }; static struct device_type dsa_type = { @@ -1134,9 +1246,9 @@ int dsa_slave_resume(struct net_device *slave_dev) return 0; } -int dsa_slave_create(struct dsa_switch *ds, struct device *parent, - int port, const char *name) +int dsa_slave_create(struct dsa_port *port, const char *name) { + struct dsa_switch *ds = port->ds; struct dsa_switch_tree *dst = ds->dst; struct net_device *master; struct net_device *slave_dev; @@ -1147,8 +1259,12 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, cpu_dp = ds->dst->cpu_dp; master = cpu_dp->netdev; - slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, - NET_NAME_UNKNOWN, ether_setup); + if (!ds->num_tx_queues) + ds->num_tx_queues = 1; + + slave_dev = alloc_netdev_mqs(sizeof(struct dsa_slave_priv), name, + NET_NAME_UNKNOWN, ether_setup, + ds->num_tx_queues, 1); if (slave_dev == NULL) return -ENOMEM; @@ -1166,12 +1282,17 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, NULL); - SET_NETDEV_DEV(slave_dev, parent); - slave_dev->dev.of_node = ds->ports[port].dn; + SET_NETDEV_DEV(slave_dev, port->ds->dev); + slave_dev->dev.of_node = port->dn; slave_dev->vlan_features = master->vlan_features; p = netdev_priv(slave_dev); - p->dp = &ds->ports[port]; + p->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!p->stats64) { + free_netdev(slave_dev); + return -ENOMEM; + } + p->dp = port; INIT_LIST_HEAD(&p->mall_tc_list); p->xmit = dst->tag_ops->xmit; @@ -1179,27 +1300,34 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, p->old_link = -1; p->old_duplex = -1; - ds->ports[port].netdev = slave_dev; - ret = register_netdev(slave_dev); - if (ret) { - netdev_err(master, "error %d registering interface %s\n", - ret, slave_dev->name); - ds->ports[port].netdev = NULL; - free_netdev(slave_dev); - return ret; - } + port->netdev = slave_dev; netif_carrier_off(slave_dev); ret = dsa_slave_phy_setup(p, slave_dev); if (ret) { netdev_err(master, "error %d setting up slave phy\n", ret); - unregister_netdev(slave_dev); - free_netdev(slave_dev); - return ret; + goto out_free; + } + + ret = register_netdev(slave_dev); + if (ret) { + netdev_err(master, "error %d registering interface %s\n", + ret, slave_dev->name); + goto out_phy; } return 0; + +out_phy: + phy_disconnect(p->phy); + if (of_phy_is_fixed_link(p->dp->dn)) + of_phy_deregister_fixed_link(p->dp->dn); +out_free: + free_percpu(p->stats64); + free_netdev(slave_dev); + port->netdev = NULL; + return ret; } void dsa_slave_destroy(struct net_device *slave_dev) @@ -1217,6 +1345,7 @@ void dsa_slave_destroy(struct net_device *slave_dev) of_phy_deregister_fixed_link(port_dn); } unregister_netdev(slave_dev); + free_percpu(p->stats64); free_netdev(slave_dev); } @@ -1259,19 +1388,142 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb, return NOTIFY_DONE; } +struct dsa_switchdev_event_work { + struct work_struct work; + struct switchdev_notifier_fdb_info fdb_info; + struct net_device *dev; + unsigned long event; +}; + +static void dsa_slave_switchdev_event_work(struct work_struct *work) +{ + struct dsa_switchdev_event_work *switchdev_work = + container_of(work, struct dsa_switchdev_event_work, work); + struct net_device *dev = switchdev_work->dev; + struct switchdev_notifier_fdb_info *fdb_info; + struct dsa_slave_priv *p = netdev_priv(dev); + int err; + + rtnl_lock(); + switch (switchdev_work->event) { + case SWITCHDEV_FDB_ADD_TO_DEVICE: + fdb_info = &switchdev_work->fdb_info; + err = dsa_port_fdb_add(p->dp, fdb_info->addr, fdb_info->vid); + if (err) { + netdev_dbg(dev, "fdb add failed err=%d\n", err); + break; + } + call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, dev, + &fdb_info->info); + break; + + case SWITCHDEV_FDB_DEL_TO_DEVICE: + fdb_info = &switchdev_work->fdb_info; + err = dsa_port_fdb_del(p->dp, fdb_info->addr, fdb_info->vid); + if (err) { + netdev_dbg(dev, "fdb del failed err=%d\n", err); + dev_close(dev); + } + break; + } + rtnl_unlock(); + + kfree(switchdev_work->fdb_info.addr); + kfree(switchdev_work); + dev_put(dev); +} + +static int +dsa_slave_switchdev_fdb_work_init(struct dsa_switchdev_event_work * + switchdev_work, + const struct switchdev_notifier_fdb_info * + fdb_info) +{ + memcpy(&switchdev_work->fdb_info, fdb_info, + sizeof(switchdev_work->fdb_info)); + switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC); + if (!switchdev_work->fdb_info.addr) + return -ENOMEM; + ether_addr_copy((u8 *)switchdev_work->fdb_info.addr, + fdb_info->addr); + return 0; +} + +/* Called under rcu_read_lock() */ +static int dsa_slave_switchdev_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = switchdev_notifier_info_to_dev(ptr); + struct dsa_switchdev_event_work *switchdev_work; + + if (!dsa_slave_dev_check(dev)) + return NOTIFY_DONE; + + switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + if (!switchdev_work) + return NOTIFY_BAD; + + INIT_WORK(&switchdev_work->work, + dsa_slave_switchdev_event_work); + switchdev_work->dev = dev; + switchdev_work->event = event; + + switch (event) { + case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */ + case SWITCHDEV_FDB_DEL_TO_DEVICE: + if (dsa_slave_switchdev_fdb_work_init(switchdev_work, + ptr)) + goto err_fdb_work_init; + dev_hold(dev); + break; + default: + kfree(switchdev_work); + return NOTIFY_DONE; + } + + dsa_schedule_work(&switchdev_work->work); + return NOTIFY_OK; + +err_fdb_work_init: + kfree(switchdev_work); + return NOTIFY_BAD; +} + static struct notifier_block dsa_slave_nb __read_mostly = { - .notifier_call = dsa_slave_netdevice_event, + .notifier_call = dsa_slave_netdevice_event, +}; + +static struct notifier_block dsa_slave_switchdev_notifier = { + .notifier_call = dsa_slave_switchdev_event, }; int dsa_slave_register_notifier(void) { - return register_netdevice_notifier(&dsa_slave_nb); + int err; + + err = register_netdevice_notifier(&dsa_slave_nb); + if (err) + return err; + + err = register_switchdev_notifier(&dsa_slave_switchdev_notifier); + if (err) + goto err_switchdev_nb; + + return 0; + +err_switchdev_nb: + unregister_netdevice_notifier(&dsa_slave_nb); + return err; } void dsa_slave_unregister_notifier(void) { int err; + err = unregister_switchdev_notifier(&dsa_slave_switchdev_notifier); + if (err) + pr_err("DSA: failed to unregister switchdev notifier (%d)\n", err); + err = unregister_netdevice_notifier(&dsa_slave_nb); if (err) pr_err("DSA: failed to unregister slave notifier (%d)\n", err); diff --git a/net/dsa/switch.c b/net/dsa/switch.c index 97e2e9c8cf3f02a6ad1d3382119efc7924a76989..e6c06aa349a6fd1930a6c343d4d643cccfa8cb92 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -83,30 +83,20 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds, static int dsa_switch_fdb_add(struct dsa_switch *ds, struct dsa_notifier_fdb_info *info) { - const struct switchdev_obj_port_fdb *fdb = info->fdb; - struct switchdev_trans *trans = info->trans; - /* Do not care yet about other switch chips of the fabric */ if (ds->index != info->sw_index) return 0; - if (switchdev_trans_ph_prepare(trans)) { - if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add) - return -EOPNOTSUPP; - - return ds->ops->port_fdb_prepare(ds, info->port, fdb, trans); - } - - ds->ops->port_fdb_add(ds, info->port, fdb, trans); + if (!ds->ops->port_fdb_add) + return -EOPNOTSUPP; - return 0; + return ds->ops->port_fdb_add(ds, info->port, info->addr, + info->vid); } static int dsa_switch_fdb_del(struct dsa_switch *ds, struct dsa_notifier_fdb_info *info) { - const struct switchdev_obj_port_fdb *fdb = info->fdb; - /* Do not care yet about other switch chips of the fabric */ if (ds->index != info->sw_index) return 0; @@ -114,7 +104,8 @@ static int dsa_switch_fdb_del(struct dsa_switch *ds, if (!ds->ops->port_fdb_del) return -EOPNOTSUPP; - return ds->ops->port_fdb_del(ds, info->port, fdb); + return ds->ops->port_fdb_del(ds, info->port, info->addr, + info->vid); } static int dsa_switch_mdb_add(struct dsa_switch *ds, diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index c697d981517744fbc523d3bd0e3b8204a3a427f8..dbb016434ace8e3952d707c57f41b9e9eab48dd3 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -62,6 +62,7 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); + u16 queue = skb_get_queue_mapping(skb); u8 *brcm_tag; if (skb_cow_head(skb, BRCM_TAG_LEN) < 0) @@ -78,7 +79,7 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev * deprecated */ brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) | - ((skb->priority << BRCM_IG_TC_SHIFT) & BRCM_IG_TC_MASK); + ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT); brcm_tag[1] = 0; brcm_tag[2] = 0; if (p->dp->index == 8) @@ -89,8 +90,7 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev } static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 12867a4b458f17259d8fb89781b56b92a494d09d..fbf9ca954773d1b0b616f9e3f2ef2f70a1370e86 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -65,8 +65,7 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) } static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_switch *ds; diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c index 67a9d26f9075072c906b9a15bf9747d132eeafb4..76367ba1b2e2433466fb56040e775637a6b41a8f 100644 --- a/net/dsa/tag_edsa.c +++ b/net/dsa/tag_edsa.c @@ -78,8 +78,7 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) } static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_switch *ds; diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c index fab41de8e9837b512709b3c853ffb4831fe08317..010ca0a336c46a34f6a89d8c6975ca4b00642e6e 100644 --- a/net/dsa/tag_ksz.c +++ b/net/dsa/tag_ksz.c @@ -42,6 +42,10 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev) padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len; if (skb_tailroom(skb) >= padlen + KSZ_INGRESS_TAG_LEN) { + /* Let dsa_slave_xmit() free skb */ + if (__skb_put_padto(skb, skb->len + padlen, false)) + return NULL; + nskb = skb; } else { nskb = alloc_skb(NET_IP_ALIGN + skb->len + @@ -56,12 +60,15 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev) skb_set_transport_header(nskb, skb_transport_header(skb) - skb->head); skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len)); - kfree_skb(skb); - } - /* skb is freed when it fails */ - if (skb_put_padto(nskb, nskb->len + padlen)) - return NULL; + /* Let skb_put_padto() free nskb, and let dsa_slave_xmit() free + * skb + */ + if (skb_put_padto(nskb, nskb->len + padlen)) + return NULL; + + consume_skb(skb); + } tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN); tag[0] = 0; @@ -71,8 +78,7 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev) } static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index 247774d149f9f90e1170d3cd65d6f2fdb473b28d..0b9826105e421b77a22f77b7d8d7686655580ddb 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -39,7 +39,6 @@ */ #define LAN9303_TAG_LEN 4 -#define LAN9303_MAX_PORTS 3 static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -69,7 +68,7 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) } static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) + struct packet_type *pt) { u16 *lan9303_tag; struct dsa_switch_tree *dst = dev->dsa_ptr; @@ -104,7 +103,7 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev, source_port = ntohs(lan9303_tag[1]) & 0x3; - if (source_port >= LAN9303_MAX_PORTS) { + if (source_port >= ds->num_ports) { dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n"); return NULL; } diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c index 2f32b7ea3365ce87f61e6a5002fbe45a4228e85f..ec8ee5f43255e7d95ace5b44f3c04860bd0b8507 100644 --- a/net/dsa/tag_mtk.c +++ b/net/dsa/tag_mtk.c @@ -44,8 +44,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, } static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_switch *ds; @@ -87,7 +86,17 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, return skb; } +static int mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto, + int *offset) +{ + *offset = 4; + *proto = ((__be16 *)skb->data)[1]; + + return 0; +} + const struct dsa_device_ops mtk_netdev_ops = { - .xmit = mtk_tag_xmit, - .rcv = mtk_tag_rcv, + .xmit = mtk_tag_xmit, + .rcv = mtk_tag_rcv, + .flow_dissect = mtk_tag_flow_dissect, }; diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c index 1867a3d11f280d8c345d57386acd3ef357833b19..1d4c70711c0f456e0bcb6f970954e3f1f45dc9b3 100644 --- a/net/dsa/tag_qca.c +++ b/net/dsa/tag_qca.c @@ -63,8 +63,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) } static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index b09e56214005c7cf9e257eb777882b234a2d6f18..d2fd4923aa3eb3d1d56f20dd159d0ca87408b835 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c @@ -40,7 +40,7 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev) skb_set_network_header(nskb, skb_network_header(skb) - skb->head); skb_set_transport_header(nskb, skb_transport_header(skb) - skb->head); skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len)); - kfree_skb(skb); + consume_skb(skb); if (padlen) { skb_put_zero(nskb, padlen); @@ -56,8 +56,7 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev) } static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, - struct net_device *orig_dev) + struct packet_type *pt) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 4e7bdb213cd076e44b5a36b2168413682bb23f68..172d8309f89e52b1c06781571873520a41ef9036 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -314,7 +314,8 @@ static void send_hsr_supervision_frame(struct hsr_port *master, hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload)); ether_addr_copy(hsr_sp->MacAddressA, master->dev->dev_addr); - skb_put_padto(skb, ETH_ZLEN + HSR_HLEN); + if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) + return; hsr_forward_skb(skb, master); return; diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c index de2661cd0328500414c652af202a8928bd9ad89c..974765b7d92a75546fe5ae5dbc332078a54f627a 100644 --- a/net/ieee802154/6lowpan/core.c +++ b/net/ieee802154/6lowpan/core.c @@ -54,7 +54,7 @@ static int open_count; -static struct header_ops lowpan_header_ops = { +static const struct header_ops lowpan_header_ops = { .create = lowpan_header_create, }; diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c index 30d875dff6b54658f2671ae48a4e1fce8b750c3e..f85b08baff160307516d8367a1f60dfc555f3c6c 100644 --- a/net/ieee802154/6lowpan/reassembly.c +++ b/net/ieee802154/6lowpan/reassembly.c @@ -580,19 +580,14 @@ static int __net_init lowpan_frags_init_net(struct net *net) { struct netns_ieee802154_lowpan *ieee802154_lowpan = net_ieee802154_lowpan(net); - int res; ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH; ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH; ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT; - res = inet_frags_init_net(&ieee802154_lowpan->frags); - if (res) - return res; - res = lowpan_frags_ns_sysctl_register(net); - if (res) - inet_frags_uninit_net(&ieee802154_lowpan->frags); - return res; + inet_frags_init_net(&ieee802154_lowpan->frags); + + return lowpan_frags_ns_sysctl_register(net); } static void __net_exit lowpan_frags_exit_net(struct net *net) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 76c2077c3f5b697bf8e0d4b030b70dde8fc70345..e31108e5ef79c574751bb23773b41c2daf6e0975 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -944,6 +944,8 @@ const struct proto_ops inet_stream_ops = { .sendpage = inet_sendpage, .splice_read = tcp_splice_read, .read_sock = tcp_read_sock, + .sendmsg_locked = tcp_sendmsg_locked, + .sendpage_locked = tcp_sendpage_locked, .peek_len = tcp_peek_len, #ifdef CONFIG_COMPAT .compat_setsockopt = compat_sock_common_setsockopt, @@ -1219,10 +1221,9 @@ EXPORT_SYMBOL(inet_sk_rebuild_header); struct sk_buff *inet_gso_segment(struct sk_buff *skb, netdev_features_t features) { - bool udpfrag = false, fixedid = false, gso_partial, encap; + bool fixedid = false, gso_partial, encap; struct sk_buff *segs = ERR_PTR(-EINVAL); const struct net_offload *ops; - unsigned int offset = 0; struct iphdr *iph; int proto, tot_len; int nhoff; @@ -1257,7 +1258,6 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, segs = ERR_PTR(-EPROTONOSUPPORT); if (!skb->encapsulation || encap) { - udpfrag = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP); fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID); /* fixed ID is invalid if DF bit is not set */ @@ -1277,13 +1277,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, skb = segs; do { iph = (struct iphdr *)(skb_mac_header(skb) + nhoff); - if (udpfrag) { - iph->frag_off = htons(offset >> 3); - if (skb->next) - iph->frag_off |= htons(IP_MF); - offset += skb->len - nhoff - ihl; - tot_len = skb->len - nhoff; - } else if (skb_is_gso(skb)) { + if (skb_is_gso(skb)) { if (!fixedid) { iph->id = htons(id); id += skb_shinfo(skb)->gso_segs; @@ -1602,6 +1596,9 @@ static const struct net_protocol igmp_protocol = { }; #endif +/* thinking of making this const? Don't. + * early_demux can change based on sysctl. + */ static struct net_protocol tcp_protocol = { .early_demux = tcp_v4_early_demux, .early_demux_handler = tcp_v4_early_demux, @@ -1612,6 +1609,9 @@ static struct net_protocol tcp_protocol = { .icmp_strict_tag_validation = 1, }; +/* thinking of making this const? Don't. + * early_demux can change based on sysctl. + */ static struct net_protocol udp_protocol = { .early_demux = udp_v4_early_demux, .early_demux_handler = udp_v4_early_demux, @@ -1731,6 +1731,13 @@ static __net_init int inet_init_net(struct net *net) net->ipv4.sysctl_ip_prot_sock = PROT_SOCK; #endif + /* Some igmp sysctl, whose values are always used */ + net->ipv4.sysctl_igmp_max_memberships = 20; + net->ipv4.sysctl_igmp_max_msf = 10; + /* IGMP reports for link-local multicast groups are enabled by default */ + net->ipv4.sysctl_igmp_llm_reports = 1; + net->ipv4.sysctl_igmp_qrv = 2; + return 0; } @@ -1771,6 +1778,11 @@ static const struct net_offload ipip_offload = { }, }; +static int __init ipip_offload_init(void) +{ + return inet_add_offload(&ipip_offload, IPPROTO_IPIP); +} + static int __init ipv4_offload_init(void) { /* @@ -1780,9 +1792,10 @@ static int __init ipv4_offload_init(void) pr_crit("%s: Cannot add UDP protocol offload\n", __func__); if (tcpv4_offload_init() < 0) pr_crit("%s: Cannot add TCP protocol offload\n", __func__); + if (ipip_offload_init() < 0) + pr_crit("%s: Cannot add IPIP protocol offload\n", __func__); dev_add_offload(&ip_packet_offload); - inet_add_offload(&ipip_offload, IPPROTO_IPIP); return 0; } diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 8b52179ddc6e54eabf6d3c2ed0132083228680bb..7c45b8896709815c5dde5972fd57cb5c3bcb2648 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -171,7 +171,7 @@ struct neigh_table arp_tbl = { [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ, [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ, [NEIGH_VAR_GC_STALETIME] = 60 * HZ, - [NEIGH_VAR_QUEUE_LEN_BYTES] = 64 * 1024, + [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX, [NEIGH_VAR_PROXY_QLEN] = 64, [NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ, [NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10, diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index c4c6e1969ed0606ff9fb4ea46609f75b249e589b..2ae8f54cb32148f2499f78ecbf29259db36bd207 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1523,9 +1523,17 @@ unsigned char *cipso_v4_optptr(const struct sk_buff *skb) int taglen; for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 0; ) { - if (optptr[0] == IPOPT_CIPSO) + switch (optptr[0]) { + case IPOPT_CIPSO: return optptr; - taglen = optptr[1]; + case IPOPT_END: + return NULL; + case IPOPT_NOOP: + taglen = 1; + break; + default: + taglen = optptr[1]; + } optlen -= taglen; optptr += taglen; } diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 38d9af9b917c08685deb3288baab84189ec9c9a0..d7adc06165998947efc6cda8bed31c77c0976d14 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -2491,9 +2491,9 @@ void __init devinet_init(void) rtnl_af_register(&inet_af_ops); - rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, NULL); - rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL); - rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL); + rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, 0); + rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, 0); + rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, 0); rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf, - inet_netconf_dump_devconf, NULL); + inet_netconf_dump_devconf, 0); } diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 0cbee0a666ffd2a1b7451b0b07513b1cf1cebfc0..b00e4a43b4dc8538e016f8d1c23707a1f49060a8 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -258,7 +258,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * esp_output_udp_encap(x, skb, esp); if (!skb_cloned(skb)) { - if (tailen <= skb_availroom(skb)) { + if (tailen <= skb_tailroom(skb)) { nfrags = 1; trailer = skb; tail = skb_tail_pointer(trailer); @@ -292,8 +292,6 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * kunmap_atomic(vaddr); - spin_unlock_bh(&x->lock); - nfrags = skb_shinfo(skb)->nr_frags; __skb_fill_page_desc(skb, nfrags, page, pfrag->offset, @@ -301,6 +299,9 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * skb_shinfo(skb)->nr_frags = ++nfrags; pfrag->offset = pfrag->offset + allocsize; + + spin_unlock_bh(&x->lock); + nfrags++; skb->len += tailen; @@ -381,7 +382,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * (unsigned char *)esph - skb->data, assoclen + ivlen + esp->clen + alen); if (unlikely(err < 0)) - goto error; + goto error_free; if (!esp->inplace) { int allocsize; @@ -392,7 +393,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * spin_lock_bh(&x->lock); if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) { spin_unlock_bh(&x->lock); - goto error; + goto error_free; } skb_shinfo(skb)->nr_frags = 1; @@ -409,7 +410,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * (unsigned char *)esph - skb->data, assoclen + ivlen + esp->clen + alen); if (unlikely(err < 0)) - goto error; + goto error_free; } if ((x->props.flags & XFRM_STATE_ESN)) @@ -442,8 +443,9 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * if (sg != dsg) esp_ssg_unref(x, tmp); - kfree(tmp); +error_free: + kfree(tmp); error: return err; } @@ -499,18 +501,59 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) return esp_output_tail(x, skb, &esp); } +static inline int esp_remove_trailer(struct sk_buff *skb) +{ + struct xfrm_state *x = xfrm_input_state(skb); + struct xfrm_offload *xo = xfrm_offload(skb); + struct crypto_aead *aead = x->data; + int alen, hlen, elen; + int padlen, trimlen; + __wsum csumdiff; + u8 nexthdr[2]; + int ret; + + alen = crypto_aead_authsize(aead); + hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); + elen = skb->len - hlen; + + if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { + ret = xo->proto; + goto out; + } + + if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) + BUG(); + + ret = -EINVAL; + padlen = nexthdr[0]; + if (padlen + 2 + alen >= elen) { + net_dbg_ratelimited("ipsec esp packet is garbage padlen=%d, elen=%d\n", + padlen + 2, elen - alen); + goto out; + } + + trimlen = alen + padlen + 2; + if (skb->ip_summed == CHECKSUM_COMPLETE) { + csumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0); + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } + pskb_trim(skb, skb->len - trimlen); + + ret = nexthdr[1]; + +out: + return ret; +} + int esp_input_done2(struct sk_buff *skb, int err) { const struct iphdr *iph; struct xfrm_state *x = xfrm_input_state(skb); struct xfrm_offload *xo = xfrm_offload(skb); struct crypto_aead *aead = x->data; - int alen = crypto_aead_authsize(aead); int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); - int elen = skb->len - hlen; int ihl; - u8 nexthdr[2]; - int padlen; if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) kfree(ESP_SKB_CB(skb)->tmp); @@ -518,16 +561,10 @@ int esp_input_done2(struct sk_buff *skb, int err) if (unlikely(err)) goto out; - if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) - BUG(); - - err = -EINVAL; - padlen = nexthdr[0]; - if (padlen + 2 + alen >= elen) + err = esp_remove_trailer(skb); + if (unlikely(err < 0)) goto out; - /* ... check padding bits here. Silly. :-) */ - iph = ip_hdr(skb); ihl = iph->ihl * 4; @@ -568,15 +605,12 @@ int esp_input_done2(struct sk_buff *skb, int err) skb->ip_summed = CHECKSUM_UNNECESSARY; } - pskb_trim(skb, skb->len - alen - padlen - 2); - __skb_pull(skb, hlen); + skb_pull_rcsum(skb, hlen); if (x->props.mode == XFRM_MODE_TUNNEL) skb_reset_transport_header(skb); else skb_set_transport_header(skb, -ihl); - err = nexthdr[1]; - /* RFC4303: Drop dummy packets without any error */ if (err == IPPROTO_NONE) err = -EINVAL; @@ -695,8 +729,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) sg_init_table(sg, nfrags); err = skb_to_sgvec(skb, sg, 0, skb->len); - if (unlikely(err < 0)) + if (unlikely(err < 0)) { + kfree(tmp); goto out; + } skb->ip_summed = CHECKSUM_NONE; diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index e0666016a7642c017b4693d32723245adc484982..f8b918c766b0af1e572ed895dcf2435af92016a9 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -182,11 +182,13 @@ static struct sk_buff *esp4_gso_segment(struct sk_buff *skb, static int esp_input_tail(struct xfrm_state *x, struct sk_buff *skb) { struct crypto_aead *aead = x->data; + struct xfrm_offload *xo = xfrm_offload(skb); if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead))) return -EINVAL; - skb->ip_summed = CHECKSUM_NONE; + if (!(xo->flags & CRYPTO_DONE)) + skb->ip_summed = CHECKSUM_NONE; return esp_input_done2(skb, 0); } @@ -257,7 +259,7 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features_ esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32)); err = esp_output_tail(x, skb, &esp); - if (err < 0) + if (err) return err; secpath_reset(skb); @@ -303,3 +305,4 @@ module_init(esp4_offload_init); module_exit(esp4_offload_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert "); +MODULE_ALIAS_XFRM_OFFLOAD_TYPE(AF_INET, XFRM_PROTO_ESP); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 044d2a159a3c51bef90acd029067ef047ccaa046..37819ab4cc74935b35b01108d187897f5acac896 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1247,22 +1247,28 @@ static int __net_init ip_fib_net_init(struct net *net) int err; size_t size = sizeof(struct hlist_head) * FIB_TABLE_HASHSZ; - net->ipv4.fib_seq = 0; + err = fib4_notifier_init(net); + if (err) + return err; /* Avoid false sharing : Use at least a full cache line */ size = max_t(size_t, size, L1_CACHE_BYTES); net->ipv4.fib_table_hash = kzalloc(size, GFP_KERNEL); - if (!net->ipv4.fib_table_hash) - return -ENOMEM; + if (!net->ipv4.fib_table_hash) { + err = -ENOMEM; + goto err_table_hash_alloc; + } err = fib4_rules_init(net); if (err < 0) - goto fail; + goto err_rules_init; return 0; -fail: +err_rules_init: kfree(net->ipv4.fib_table_hash); +err_table_hash_alloc: + fib4_notifier_exit(net); return err; } @@ -1292,6 +1298,7 @@ static void ip_fib_net_exit(struct net *net) #endif rtnl_unlock(); kfree(net->ipv4.fib_table_hash); + fib4_notifier_exit(net); } static int __net_init fib_net_init(struct net *net) @@ -1341,7 +1348,7 @@ void __init ip_fib_init(void) register_netdevice_notifier(&fib_netdev_notifier); register_inetaddr_notifier(&fib_inetaddr_notifier); - rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL); - rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL); - rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL); + rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, 0); + rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, 0); + rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, 0); } diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 769ab87ebc4ba07204c285fe26d6cd20220f1076..5b2af19cfb5b75e50c80d7e4c647bc790f58368d 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -32,6 +32,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, struct netlink_ext_ack *extack); int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, struct netlink_ext_ack *extack); +bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi); int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos, struct fib_info *fi, unsigned int); diff --git a/net/ipv4/fib_notifier.c b/net/ipv4/fib_notifier.c index e0714d975947160565dfb1bd9a86bc7a592c73b1..cfd420b0572c98cb99dc9217b668f01be3050acd 100644 --- a/net/ipv4/fib_notifier.c +++ b/net/ipv4/fib_notifier.c @@ -1,86 +1,73 @@ #include #include -#include +#include #include +#include #include +#include #include #include -static ATOMIC_NOTIFIER_HEAD(fib_chain); - -int call_fib_notifier(struct notifier_block *nb, struct net *net, - enum fib_event_type event_type, - struct fib_notifier_info *info) +int call_fib4_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct fib_notifier_info *info) { - info->net = net; - return nb->notifier_call(nb, event_type, info); + info->family = AF_INET; + return call_fib_notifier(nb, net, event_type, info); } -int call_fib_notifiers(struct net *net, enum fib_event_type event_type, - struct fib_notifier_info *info) +int call_fib4_notifiers(struct net *net, enum fib_event_type event_type, + struct fib_notifier_info *info) { + ASSERT_RTNL(); + + info->family = AF_INET; net->ipv4.fib_seq++; - info->net = net; - return atomic_notifier_call_chain(&fib_chain, event_type, info); + return call_fib_notifiers(net, event_type, info); } -static unsigned int fib_seq_sum(void) +static unsigned int fib4_seq_read(struct net *net) { - unsigned int fib_seq = 0; - struct net *net; - - rtnl_lock(); - for_each_net(net) - fib_seq += net->ipv4.fib_seq; - rtnl_unlock(); + ASSERT_RTNL(); - return fib_seq; + return net->ipv4.fib_seq + fib4_rules_seq_read(net); } -static bool fib_dump_is_consistent(struct notifier_block *nb, - void (*cb)(struct notifier_block *nb), - unsigned int fib_seq) +static int fib4_dump(struct net *net, struct notifier_block *nb) { - atomic_notifier_chain_register(&fib_chain, nb); - if (fib_seq == fib_seq_sum()) - return true; - atomic_notifier_chain_unregister(&fib_chain, nb); - if (cb) - cb(nb); - return false; + int err; + + err = fib4_rules_dump(net, nb); + if (err) + return err; + + fib_notify(net, nb); + + return 0; } -#define FIB_DUMP_MAX_RETRIES 5 -int register_fib_notifier(struct notifier_block *nb, - void (*cb)(struct notifier_block *nb)) -{ - int retries = 0; +static const struct fib_notifier_ops fib4_notifier_ops_template = { + .family = AF_INET, + .fib_seq_read = fib4_seq_read, + .fib_dump = fib4_dump, + .owner = THIS_MODULE, +}; - do { - unsigned int fib_seq = fib_seq_sum(); - struct net *net; +int __net_init fib4_notifier_init(struct net *net) +{ + struct fib_notifier_ops *ops; - /* Mutex semantics guarantee that every change done to - * FIB tries before we read the change sequence counter - * is now visible to us. - */ - rcu_read_lock(); - for_each_net_rcu(net) { - fib_rules_notify(net, nb); - fib_notify(net, nb); - } - rcu_read_unlock(); + net->ipv4.fib_seq = 0; - if (fib_dump_is_consistent(nb, cb, fib_seq)) - return 0; - } while (++retries < FIB_DUMP_MAX_RETRIES); + ops = fib_notifier_ops_register(&fib4_notifier_ops_template, net); + if (IS_ERR(ops)) + return PTR_ERR(ops); + net->ipv4.notifier_ops = ops; - return -EBUSY; + return 0; } -EXPORT_SYMBOL(register_fib_notifier); -int unregister_fib_notifier(struct notifier_block *nb) +void __net_exit fib4_notifier_exit(struct net *net) { - return atomic_notifier_chain_unregister(&fib_chain, nb); + fib_notifier_ops_unregister(net->ipv4.notifier_ops); } -EXPORT_SYMBOL(unregister_fib_notifier); diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 778ecf977eb2bd7b7b3808691aaf818fc4bd680d..35d646a62ad454ddced6a614dc7e10b67447a3f0 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -68,6 +68,16 @@ bool fib4_rule_default(const struct fib_rule *rule) } EXPORT_SYMBOL_GPL(fib4_rule_default); +int fib4_rules_dump(struct net *net, struct notifier_block *nb) +{ + return fib_rules_dump(net, nb, AF_INET); +} + +unsigned int fib4_rules_seq_read(struct net *net) +{ + return fib_rules_seq_read(net, AF_INET); +} + int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res, unsigned int flags) { @@ -185,38 +195,6 @@ static struct fib_table *fib_empty_table(struct net *net) return NULL; } -static int call_fib_rule_notifier(struct notifier_block *nb, struct net *net, - enum fib_event_type event_type, - struct fib_rule *rule) -{ - struct fib_rule_notifier_info info = { - .rule = rule, - }; - - return call_fib_notifier(nb, net, event_type, &info.info); -} - -static int call_fib_rule_notifiers(struct net *net, - enum fib_event_type event_type, - struct fib_rule *rule) -{ - struct fib_rule_notifier_info info = { - .rule = rule, - }; - - return call_fib_notifiers(net, event_type, &info.info); -} - -/* Called with rcu_read_lock() */ -void fib_rules_notify(struct net *net, struct notifier_block *nb) -{ - struct fib_rules_ops *ops = net->ipv4.rules_ops; - struct fib_rule *rule; - - list_for_each_entry_rcu(rule, &ops->rules_list, list) - call_fib_rule_notifier(nb, net, FIB_EVENT_RULE_ADD, rule); -} - static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = { FRA_GENERIC_POLICY, [FRA_FLOW] = { .type = NLA_U32 }, @@ -273,7 +251,6 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, rule4->tos = frh->tos; net->ipv4.fib_has_custom_rules = true; - call_fib_rule_notifiers(net, FIB_EVENT_RULE_ADD, rule); err = 0; errout: @@ -295,7 +272,6 @@ static int fib4_rule_delete(struct fib_rule *rule) net->ipv4.fib_num_tclassid_users--; #endif net->ipv4.fib_has_custom_rules = true; - call_fib_rule_notifiers(net, FIB_EVENT_RULE_DEL, rule); errout: return err; } diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 2221001038084af89b6f9fa0e306c2320ece4a3f..57a5d48acee84b27de00d49640220ae8e5167389 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "fib_lookup.h" @@ -219,7 +220,7 @@ static void free_fib_info_rcu(struct rcu_head *head) } endfor_nexthops(fi); m = fi->fib_metrics; - if (m != &dst_default_metrics && atomic_dec_and_test(&m->refcnt)) + if (m != &dst_default_metrics && refcount_dec_and_test(&m->refcnt)) kfree(m); kfree(fi); } @@ -695,6 +696,40 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, return 0; } +bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) +{ + struct nlattr *nla; + int remaining; + + if (!cfg->fc_mx) + return true; + + nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { + int type = nla_type(nla); + u32 val; + + if (!type) + continue; + if (type > RTAX_MAX) + return false; + + if (type == RTAX_CC_ALGO) { + char tmp[TCP_CA_NAME_MAX]; + bool ecn_ca = false; + + nla_strlcpy(tmp, nla, sizeof(tmp)); + val = tcp_ca_get_key_by_name(tmp, &ecn_ca); + } else { + val = nla_get_u32(nla); + } + + if (fi->fib_metrics->metrics[type - 1] != val) + return false; + } + + return true; +} + /* * Picture @@ -1083,15 +1118,17 @@ struct fib_info *fib_create_info(struct fib_config *cfg, fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); if (!fi) goto failure; - fib_info_cnt++; if (cfg->fc_mx) { fi->fib_metrics = kzalloc(sizeof(*fi->fib_metrics), GFP_KERNEL); - if (!fi->fib_metrics) - goto failure; - atomic_set(&fi->fib_metrics->refcnt, 1); - } else + if (unlikely(!fi->fib_metrics)) { + kfree(fi); + return ERR_PTR(err); + } + refcount_set(&fi->fib_metrics->refcnt, 1); + } else { fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics; - + } + fib_info_cnt++; fi->fib_net = net; fi->fib_protocol = cfg->fc_protocol; fi->fib_scope = cfg->fc_scope; @@ -1342,6 +1379,8 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event, IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev)) rtm->rtm_flags |= RTNH_F_DEAD; } + if (fi->fib_nh->nh_flags & RTNH_F_OFFLOAD) + rtm->rtm_flags |= RTNH_F_OFFLOAD; #ifdef CONFIG_IP_ROUTE_CLASSID if (fi->fib_nh[0].nh_tclassid && nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid)) @@ -1449,14 +1488,14 @@ static int call_fib_nh_notifiers(struct fib_nh *fib_nh, if (IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) && fib_nh->nh_flags & RTNH_F_LINKDOWN) break; - return call_fib_notifiers(dev_net(fib_nh->nh_dev), event_type, - &info.info); + return call_fib4_notifiers(dev_net(fib_nh->nh_dev), event_type, + &info.info); case FIB_EVENT_NH_DEL: - if ((IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) && + if ((in_dev && IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) && fib_nh->nh_flags & RTNH_F_LINKDOWN) || (fib_nh->nh_flags & RTNH_F_DEAD)) - return call_fib_notifiers(dev_net(fib_nh->nh_dev), - event_type, &info.info); + return call_fib4_notifiers(dev_net(fib_nh->nh_dev), + event_type, &info.info); default: break; } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 64668c69dda6ae8103fe8baf3ef42526007325dd..c636650a6a7025a8baefaa2c42070ffdea7ea171 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include "fib_lookup.h" @@ -97,7 +98,7 @@ static int call_fib_entry_notifier(struct notifier_block *nb, struct net *net, .type = type, .tb_id = tb_id, }; - return call_fib_notifier(nb, net, event_type, &info.info); + return call_fib4_notifier(nb, net, event_type, &info.info); } static int call_fib_entry_notifiers(struct net *net, @@ -113,7 +114,7 @@ static int call_fib_entry_notifiers(struct net *net, .type = type, .tb_id = tb_id, }; - return call_fib_notifiers(net, event_type, &info.info); + return call_fib4_notifiers(net, event_type, &info.info); } #define MAX_STAT_DEPTH 32 @@ -1562,7 +1563,8 @@ int fib_table_delete(struct net *net, struct fib_table *tb, fi->fib_prefsrc == cfg->fc_prefsrc) && (!cfg->fc_protocol || fi->fib_protocol == cfg->fc_protocol) && - fib_nh_match(cfg, fi, extack) == 0) { + fib_nh_match(cfg, fi, extack) == 0 && + fib_metrics_match(cfg, fi)) { fa_to_delete = fa; break; } diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index 8e0257d0120097770e37017439684a2345619f5e..1540db65241a6fd4d96b00546f13a3e3d3cd1815 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -450,6 +450,7 @@ static struct sk_buff **gue_gro_receive(struct sock *sk, out: NAPI_GRO_CB(skb)->flush |= flush; skb_gro_remcsum_cleanup(skb, &grc); + skb->remcsum_offload = 0; return pp; } diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index d5cac99170b194151b16f614508f7fa0933ff2e1..416bb304a281a41970944e5f979eaf4c8aa1ad03 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c @@ -24,7 +24,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, __be16 protocol = skb->protocol; u16 mac_len = skb->mac_len; int gre_offset, outer_hlen; - bool need_csum, ufo, gso_partial; + bool need_csum, gso_partial; if (!skb->encapsulation) goto out; @@ -47,20 +47,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, need_csum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_GRE_CSUM); skb->encap_hdr_csum = need_csum; - ufo = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP); - features &= skb->dev->hw_enc_features; - /* The only checksum offload we care about from here on out is the - * outer one so strip the existing checksum feature flags based - * on the fact that we will be computing our checksum in software. - */ - if (ufo) { - features &= ~NETIF_F_CSUM_MASK; - if (!need_csum) - features |= NETIF_F_HW_CSUM; - } - /* segment inner packet. */ segs = skb_mac_gso_segment(skb, features); if (IS_ERR_OR_NULL(segs)) { diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c2be26b98b5fc2ff4c3e3706ce179f4c0f332b69..681e33998e03b609fdca83a83e0fc62a3fee8c39 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -412,7 +412,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) int type = icmp_param->data.icmph.type; int code = icmp_param->data.icmph.code; - if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb)) + if (ip_options_echo(net, &icmp_param->replyopts.opt.opt, skb)) return; /* Needed by both icmp_global_allow and icmp_xmit_lock */ @@ -694,7 +694,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) iph->tos; mark = IP4_REPLY_MARK(net, skb_in->mark); - if (ip_options_echo(&icmp_param.replyopts.opt.opt, skb_in)) + if (ip_options_echo(net, &icmp_param.replyopts.opt.opt, skb_in)) goto out_unlock; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 28f14afd0dd3a392da3b84c5e791fffaf46ad254..ab183af0b5b6a8f9b7fd02b32b56d32487518f7a 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1007,10 +1007,18 @@ int igmp_rcv(struct sk_buff *skb) { /* This basically follows the spec line by line -- see RFC1112 */ struct igmphdr *ih; - struct in_device *in_dev = __in_dev_get_rcu(skb->dev); + struct net_device *dev = skb->dev; + struct in_device *in_dev; int len = skb->len; bool dropped = true; + if (netif_is_l3_master(dev)) { + dev = dev_get_by_index_rcu(dev_net(dev), IPCB(skb)->iif); + if (!dev) + goto drop; + } + + in_dev = __in_dev_get_rcu(dev); if (!in_dev) goto drop; @@ -2549,7 +2557,8 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, /* * check if a multicast source filter allows delivery for a given */ -int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) +int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, + int dif, int sdif) { struct inet_sock *inet = inet_sk(sk); struct ip_mc_socklist *pmc; @@ -2564,7 +2573,8 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) rcu_read_lock(); for_each_pmc_rcu(inet, pmc) { if (pmc->multi.imr_multiaddr.s_addr == loc_addr && - pmc->multi.imr_ifindex == dif) + (pmc->multi.imr_ifindex == dif || + (sdif && pmc->multi.imr_ifindex == sdif))) break; } ret = inet->mc_all; @@ -2974,12 +2984,6 @@ static int __net_init igmp_net_init(struct net *net) goto out_sock; } - /* Sysctl initialization */ - net->ipv4.sysctl_igmp_max_memberships = 20; - net->ipv4.sysctl_igmp_max_msf = 10; - /* IGMP reports for link-local multicast groups are enabled by default */ - net->ipv4.sysctl_igmp_llm_reports = 1; - net->ipv4.sysctl_igmp_qrv = 2; return 0; out_sock: diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 4089c013cb03b12e31ddffbb7ae903542c012ae0..c039c937ba90c7aec39ba2687bceb8253ead70aa 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -266,7 +266,7 @@ static inline int sk_reuseport_match(struct inet_bind_bucket *tb, #if IS_ENABLED(CONFIG_IPV6) if (tb->fast_sk_family == AF_INET6) return ipv6_rcv_saddr_equal(&tb->fast_v6_rcv_saddr, - &sk->sk_v6_rcv_saddr, + inet6_rcv_saddr(sk), tb->fast_rcv_saddr, sk->sk_rcv_saddr, tb->fast_ipv6_only, @@ -321,13 +321,14 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) goto fail_unlock; } success: - if (!hlist_empty(&tb->owners)) { + if (hlist_empty(&tb->owners)) { tb->fastreuse = reuse; if (sk->sk_reuseport) { tb->fastreuseport = FASTREUSEPORT_ANY; tb->fastuid = uid; tb->fast_rcv_saddr = sk->sk_rcv_saddr; tb->fast_ipv6_only = ipv6_only_sock(sk); + tb->fast_sk_family = sk->sk_family; #if IS_ENABLED(CONFIG_IPV6) tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr; #endif @@ -354,6 +355,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) tb->fastuid = uid; tb->fast_rcv_saddr = sk->sk_rcv_saddr; tb->fast_ipv6_only = ipv6_only_sock(sk); + tb->fast_sk_family = sk->sk_family; #if IS_ENABLED(CONFIG_IPV6) tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr; #endif @@ -916,7 +918,6 @@ static void inet_child_forget(struct sock *sk, struct request_sock *req, tcp_sk(child)->fastopen_rsk = NULL; } inet_csk_destroy_sock(child); - reqsk_put(req); } struct sock *inet_csk_reqsk_queue_add(struct sock *sk, @@ -987,6 +988,7 @@ void inet_csk_listen_stop(struct sock *sk) sock_hold(child); inet_child_forget(sk, req, child); + reqsk_put(req); bh_unlock_sock(child); local_bh_enable(); sock_put(child); diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 3828b3a805cdeae87f4ad9300f35fff048e23691..c9c35b61a027e83535eae478d927b7b46334ba4a 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -93,8 +93,17 @@ void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk) } EXPORT_SYMBOL_GPL(inet_diag_msg_common_fill); -static size_t inet_sk_attr_size(void) +static size_t inet_sk_attr_size(struct sock *sk, + const struct inet_diag_req_v2 *req, + bool net_admin) { + const struct inet_diag_handler *handler; + size_t aux = 0; + + handler = inet_diag_table[req->sdiag_protocol]; + if (handler && handler->idiag_get_aux_size) + aux = handler->idiag_get_aux_size(sk, net_admin); + return nla_total_size(sizeof(struct tcp_info)) + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ + nla_total_size(1) /* INET_DIAG_TOS */ @@ -105,6 +114,7 @@ static size_t inet_sk_attr_size(void) + nla_total_size(SK_MEMINFO_VARS * sizeof(u32)) + nla_total_size(TCP_CA_NAME_MAX) + nla_total_size(sizeof(struct tcpvegas_info)) + + aux + 64; } @@ -260,6 +270,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, handler->idiag_get_info(sk, r, info); + if (ext & (1 << (INET_DIAG_INFO - 1)) && handler->idiag_get_aux) + if (handler->idiag_get_aux(sk, net_admin, skb) < 0) + goto errout; + if (sk->sk_state < TCP_TIME_WAIT) { union tcp_cc_info info; size_t sz = 0; @@ -274,6 +288,17 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, goto errout; } + if (ext & (1 << (INET_DIAG_CLASS_ID - 1))) { + u32 classid = 0; + +#ifdef CONFIG_SOCK_CGROUP_DATA + classid = sock_cgroup_classid(&sk->sk_cgrp_data); +#endif + + if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid)) + goto errout; + } + out: nlmsg_end(skb, nlh); return 0; @@ -438,6 +463,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, const struct nlmsghdr *nlh, const struct inet_diag_req_v2 *req) { + bool net_admin = netlink_net_capable(in_skb, CAP_NET_ADMIN); struct net *net = sock_net(in_skb->sk); struct sk_buff *rep; struct sock *sk; @@ -447,7 +473,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, if (IS_ERR(sk)) return PTR_ERR(sk); - rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL); + rep = nlmsg_new(inet_sk_attr_size(sk, req, net_admin), GFP_KERNEL); if (!rep) { err = -ENOMEM; goto out; @@ -456,8 +482,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, err = sk_diag_fill(sk, rep, req, sk_user_ns(NETLINK_CB(in_skb).sk), NETLINK_CB(in_skb).portid, - nlh->nlmsg_seq, 0, nlh, - netlink_net_capable(in_skb, CAP_NET_ADMIN)); + nlh->nlmsg_seq, 0, nlh, net_admin); if (err < 0) { WARN_ON(err == -EMSGSIZE); nlmsg_free(rep); diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 96e95e83cc61625c2e36ecf48d02292411bef25f..af74d0433453d9751e1b6e26bcbe251d173bee4b 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -234,10 +234,8 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f) cond_resched(); if (read_seqretry(&f->rnd_seqlock, seq) || - percpu_counter_sum(&nf->mem)) + sum_frag_mem_limit(nf)) goto evict_again; - - percpu_counter_destroy(&nf->mem); } EXPORT_SYMBOL(inet_frags_exit_net); diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 2e3389d614d1689856c3a8a9929dba8f7e7e1a37..597bb4cfe805281a5a7cb1f8d1334c2103d34dc8 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -170,7 +170,7 @@ EXPORT_SYMBOL_GPL(__inet_inherit_port); static inline int compute_score(struct sock *sk, struct net *net, const unsigned short hnum, const __be32 daddr, - const int dif, bool exact_dif) + const int dif, const int sdif, bool exact_dif) { int score = -1; struct inet_sock *inet = inet_sk(sk); @@ -185,9 +185,13 @@ static inline int compute_score(struct sock *sk, struct net *net, score += 4; } if (sk->sk_bound_dev_if || exact_dif) { - if (sk->sk_bound_dev_if != dif) + bool dev_match = (sk->sk_bound_dev_if == dif || + sk->sk_bound_dev_if == sdif); + + if (exact_dif && !dev_match) return -1; - score += 4; + if (sk->sk_bound_dev_if && dev_match) + score += 4; } if (sk->sk_incoming_cpu == raw_smp_processor_id()) score++; @@ -208,7 +212,7 @@ struct sock *__inet_lookup_listener(struct net *net, struct sk_buff *skb, int doff, const __be32 saddr, __be16 sport, const __be32 daddr, const unsigned short hnum, - const int dif) + const int dif, const int sdif) { unsigned int hash = inet_lhashfn(net, hnum); struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash]; @@ -218,7 +222,8 @@ struct sock *__inet_lookup_listener(struct net *net, u32 phash = 0; sk_for_each_rcu(sk, &ilb->head) { - score = compute_score(sk, net, hnum, daddr, dif, exact_dif); + score = compute_score(sk, net, hnum, daddr, + dif, sdif, exact_dif); if (score > hiscore) { reuseport = sk->sk_reuseport; if (reuseport) { @@ -268,7 +273,7 @@ struct sock *__inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, const __be32 saddr, const __be16 sport, const __be32 daddr, const u16 hnum, - const int dif) + const int dif, const int sdif) { INET_ADDR_COOKIE(acookie, saddr, daddr); const __portpair ports = INET_COMBINED_PORTS(sport, hnum); @@ -286,11 +291,12 @@ struct sock *__inet_lookup_established(struct net *net, if (sk->sk_hash != hash) continue; if (likely(INET_MATCH(sk, net, acookie, - saddr, daddr, ports, dif))) { + saddr, daddr, ports, dif, sdif))) { if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) goto out; if (unlikely(!INET_MATCH(sk, net, acookie, - saddr, daddr, ports, dif))) { + saddr, daddr, ports, + dif, sdif))) { sock_gen_put(sk); goto begin; } @@ -321,9 +327,10 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, __be32 daddr = inet->inet_rcv_saddr; __be32 saddr = inet->inet_daddr; int dif = sk->sk_bound_dev_if; + struct net *net = sock_net(sk); + int sdif = l3mdev_master_ifindex_by_index(net, dif); INET_ADDR_COOKIE(acookie, saddr, daddr); const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport); - struct net *net = sock_net(sk); unsigned int hash = inet_ehashfn(net, daddr, lport, saddr, inet->inet_dport); struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); @@ -339,7 +346,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, continue; if (likely(INET_MATCH(sk2, net, acookie, - saddr, daddr, ports, dif))) { + saddr, daddr, ports, dif, sdif))) { if (sk2->sk_state == TCP_TIME_WAIT) { tw = inet_twsk(sk2); if (twsk_unique(sk, sk2, twp)) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index c5a117cc66198ca0fe9d49e1c15f3c3110a0d634..b20c8ac640811e1b4c5416134181dd77675db878 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -33,7 +33,7 @@ * also be removed if the pool is overloaded i.e. if the total amount of * entries is greater-or-equal than the threshold. * - * Node pool is organised as an AVL tree. + * Node pool is organised as an RB tree. * Such an implementation has been chosen not just for fun. It's a way to * prevent easy and efficient DoS attacks by creating hash collisions. A huge * amount of long living nodes in a single hash slot would significantly delay @@ -45,7 +45,7 @@ * AND reference count being 0. * 3. Global variable peer_total is modified under the pool lock. * 4. struct inet_peer fields modification: - * avl_left, avl_right, avl_parent, avl_height: pool lock + * rb_node: pool lock * refcnt: atomically against modifications on other CPU; * usually under some other lock to prevent node disappearing * daddr: unchangeable @@ -53,30 +53,15 @@ static struct kmem_cache *peer_cachep __read_mostly; -static LIST_HEAD(gc_list); -static const int gc_delay = 60 * HZ; -static struct delayed_work gc_work; -static DEFINE_SPINLOCK(gc_lock); - -#define node_height(x) x->avl_height - -#define peer_avl_empty ((struct inet_peer *)&peer_fake_node) -#define peer_avl_empty_rcu ((struct inet_peer __rcu __force *)&peer_fake_node) -static const struct inet_peer peer_fake_node = { - .avl_left = peer_avl_empty_rcu, - .avl_right = peer_avl_empty_rcu, - .avl_height = 0 -}; - void inet_peer_base_init(struct inet_peer_base *bp) { - bp->root = peer_avl_empty_rcu; + bp->rb_root = RB_ROOT; seqlock_init(&bp->lock); bp->total = 0; } EXPORT_SYMBOL_GPL(inet_peer_base_init); -#define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */ +#define PEER_MAX_GC 32 /* Exported for sysctl_net_ipv4. */ int inet_peer_threshold __read_mostly = 65536 + 128; /* start to throw entries more @@ -84,53 +69,6 @@ int inet_peer_threshold __read_mostly = 65536 + 128; /* start to throw entries m int inet_peer_minttl __read_mostly = 120 * HZ; /* TTL under high load: 120 sec */ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min */ -static void inetpeer_gc_worker(struct work_struct *work) -{ - struct inet_peer *p, *n, *c; - struct list_head list; - - spin_lock_bh(&gc_lock); - list_replace_init(&gc_list, &list); - spin_unlock_bh(&gc_lock); - - if (list_empty(&list)) - return; - - list_for_each_entry_safe(p, n, &list, gc_list) { - - if (need_resched()) - cond_resched(); - - c = rcu_dereference_protected(p->avl_left, 1); - if (c != peer_avl_empty) { - list_add_tail(&c->gc_list, &list); - p->avl_left = peer_avl_empty_rcu; - } - - c = rcu_dereference_protected(p->avl_right, 1); - if (c != peer_avl_empty) { - list_add_tail(&c->gc_list, &list); - p->avl_right = peer_avl_empty_rcu; - } - - n = list_entry(p->gc_list.next, struct inet_peer, gc_list); - - if (refcount_read(&p->refcnt) == 1) { - list_del(&p->gc_list); - kmem_cache_free(peer_cachep, p); - } - } - - if (list_empty(&list)) - return; - - spin_lock_bh(&gc_lock); - list_splice(&list, &gc_list); - spin_unlock_bh(&gc_lock); - - schedule_delayed_work(&gc_work, gc_delay); -} - /* Called from ip_output.c:ip_init */ void __init inet_initpeers(void) { @@ -153,225 +91,65 @@ void __init inet_initpeers(void) sizeof(struct inet_peer), 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); - - INIT_DEFERRABLE_WORK(&gc_work, inetpeer_gc_worker); } -#define rcu_deref_locked(X, BASE) \ - rcu_dereference_protected(X, lockdep_is_held(&(BASE)->lock.lock)) - -/* - * Called with local BH disabled and the pool lock held. - */ -#define lookup(_daddr, _stack, _base) \ -({ \ - struct inet_peer *u; \ - struct inet_peer __rcu **v; \ - \ - stackptr = _stack; \ - *stackptr++ = &_base->root; \ - for (u = rcu_deref_locked(_base->root, _base); \ - u != peer_avl_empty;) { \ - int cmp = inetpeer_addr_cmp(_daddr, &u->daddr); \ - if (cmp == 0) \ - break; \ - if (cmp == -1) \ - v = &u->avl_left; \ - else \ - v = &u->avl_right; \ - *stackptr++ = v; \ - u = rcu_deref_locked(*v, _base); \ - } \ - u; \ -}) - -/* - * Called with rcu_read_lock() - * Because we hold no lock against a writer, its quite possible we fall - * in an endless loop. - * But every pointer we follow is guaranteed to be valid thanks to RCU. - * We exit from this function if number of links exceeds PEER_MAXDEPTH - */ -static struct inet_peer *lookup_rcu(const struct inetpeer_addr *daddr, - struct inet_peer_base *base) +/* Called with rcu_read_lock() or base->lock held */ +static struct inet_peer *lookup(const struct inetpeer_addr *daddr, + struct inet_peer_base *base, + unsigned int seq, + struct inet_peer *gc_stack[], + unsigned int *gc_cnt, + struct rb_node **parent_p, + struct rb_node ***pp_p) { - struct inet_peer *u = rcu_dereference(base->root); - int count = 0; + struct rb_node **pp, *parent, *next; + struct inet_peer *p; + + pp = &base->rb_root.rb_node; + parent = NULL; + while (1) { + int cmp; - while (u != peer_avl_empty) { - int cmp = inetpeer_addr_cmp(daddr, &u->daddr); + next = rcu_dereference_raw(*pp); + if (!next) + break; + parent = next; + p = rb_entry(parent, struct inet_peer, rb_node); + cmp = inetpeer_addr_cmp(daddr, &p->daddr); if (cmp == 0) { - /* Before taking a reference, check if this entry was - * deleted (refcnt=0) - */ - if (!refcount_inc_not_zero(&u->refcnt)) { - u = NULL; - } - return u; + if (!refcount_inc_not_zero(&p->refcnt)) + break; + return p; + } + if (gc_stack) { + if (*gc_cnt < PEER_MAX_GC) + gc_stack[(*gc_cnt)++] = p; + } else if (unlikely(read_seqretry(&base->lock, seq))) { + break; } if (cmp == -1) - u = rcu_dereference(u->avl_left); + pp = &next->rb_left; else - u = rcu_dereference(u->avl_right); - if (unlikely(++count == PEER_MAXDEPTH)) - break; + pp = &next->rb_right; } + *parent_p = parent; + *pp_p = pp; return NULL; } -/* Called with local BH disabled and the pool lock held. */ -#define lookup_rightempty(start, base) \ -({ \ - struct inet_peer *u; \ - struct inet_peer __rcu **v; \ - *stackptr++ = &start->avl_left; \ - v = &start->avl_left; \ - for (u = rcu_deref_locked(*v, base); \ - u->avl_right != peer_avl_empty_rcu;) { \ - v = &u->avl_right; \ - *stackptr++ = v; \ - u = rcu_deref_locked(*v, base); \ - } \ - u; \ -}) - -/* Called with local BH disabled and the pool lock held. - * Variable names are the proof of operation correctness. - * Look into mm/map_avl.c for more detail description of the ideas. - */ -static void peer_avl_rebalance(struct inet_peer __rcu **stack[], - struct inet_peer __rcu ***stackend, - struct inet_peer_base *base) -{ - struct inet_peer __rcu **nodep; - struct inet_peer *node, *l, *r; - int lh, rh; - - while (stackend > stack) { - nodep = *--stackend; - node = rcu_deref_locked(*nodep, base); - l = rcu_deref_locked(node->avl_left, base); - r = rcu_deref_locked(node->avl_right, base); - lh = node_height(l); - rh = node_height(r); - if (lh > rh + 1) { /* l: RH+2 */ - struct inet_peer *ll, *lr, *lrl, *lrr; - int lrh; - ll = rcu_deref_locked(l->avl_left, base); - lr = rcu_deref_locked(l->avl_right, base); - lrh = node_height(lr); - if (lrh <= node_height(ll)) { /* ll: RH+1 */ - RCU_INIT_POINTER(node->avl_left, lr); /* lr: RH or RH+1 */ - RCU_INIT_POINTER(node->avl_right, r); /* r: RH */ - node->avl_height = lrh + 1; /* RH+1 or RH+2 */ - RCU_INIT_POINTER(l->avl_left, ll); /* ll: RH+1 */ - RCU_INIT_POINTER(l->avl_right, node); /* node: RH+1 or RH+2 */ - l->avl_height = node->avl_height + 1; - RCU_INIT_POINTER(*nodep, l); - } else { /* ll: RH, lr: RH+1 */ - lrl = rcu_deref_locked(lr->avl_left, base);/* lrl: RH or RH-1 */ - lrr = rcu_deref_locked(lr->avl_right, base);/* lrr: RH or RH-1 */ - RCU_INIT_POINTER(node->avl_left, lrr); /* lrr: RH or RH-1 */ - RCU_INIT_POINTER(node->avl_right, r); /* r: RH */ - node->avl_height = rh + 1; /* node: RH+1 */ - RCU_INIT_POINTER(l->avl_left, ll); /* ll: RH */ - RCU_INIT_POINTER(l->avl_right, lrl); /* lrl: RH or RH-1 */ - l->avl_height = rh + 1; /* l: RH+1 */ - RCU_INIT_POINTER(lr->avl_left, l); /* l: RH+1 */ - RCU_INIT_POINTER(lr->avl_right, node); /* node: RH+1 */ - lr->avl_height = rh + 2; - RCU_INIT_POINTER(*nodep, lr); - } - } else if (rh > lh + 1) { /* r: LH+2 */ - struct inet_peer *rr, *rl, *rlr, *rll; - int rlh; - rr = rcu_deref_locked(r->avl_right, base); - rl = rcu_deref_locked(r->avl_left, base); - rlh = node_height(rl); - if (rlh <= node_height(rr)) { /* rr: LH+1 */ - RCU_INIT_POINTER(node->avl_right, rl); /* rl: LH or LH+1 */ - RCU_INIT_POINTER(node->avl_left, l); /* l: LH */ - node->avl_height = rlh + 1; /* LH+1 or LH+2 */ - RCU_INIT_POINTER(r->avl_right, rr); /* rr: LH+1 */ - RCU_INIT_POINTER(r->avl_left, node); /* node: LH+1 or LH+2 */ - r->avl_height = node->avl_height + 1; - RCU_INIT_POINTER(*nodep, r); - } else { /* rr: RH, rl: RH+1 */ - rlr = rcu_deref_locked(rl->avl_right, base);/* rlr: LH or LH-1 */ - rll = rcu_deref_locked(rl->avl_left, base);/* rll: LH or LH-1 */ - RCU_INIT_POINTER(node->avl_right, rll); /* rll: LH or LH-1 */ - RCU_INIT_POINTER(node->avl_left, l); /* l: LH */ - node->avl_height = lh + 1; /* node: LH+1 */ - RCU_INIT_POINTER(r->avl_right, rr); /* rr: LH */ - RCU_INIT_POINTER(r->avl_left, rlr); /* rlr: LH or LH-1 */ - r->avl_height = lh + 1; /* r: LH+1 */ - RCU_INIT_POINTER(rl->avl_right, r); /* r: LH+1 */ - RCU_INIT_POINTER(rl->avl_left, node); /* node: LH+1 */ - rl->avl_height = lh + 2; - RCU_INIT_POINTER(*nodep, rl); - } - } else { - node->avl_height = (lh > rh ? lh : rh) + 1; - } - } -} - -/* Called with local BH disabled and the pool lock held. */ -#define link_to_pool(n, base) \ -do { \ - n->avl_height = 1; \ - n->avl_left = peer_avl_empty_rcu; \ - n->avl_right = peer_avl_empty_rcu; \ - /* lockless readers can catch us now */ \ - rcu_assign_pointer(**--stackptr, n); \ - peer_avl_rebalance(stack, stackptr, base); \ -} while (0) - static void inetpeer_free_rcu(struct rcu_head *head) { kmem_cache_free(peer_cachep, container_of(head, struct inet_peer, rcu)); } -static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base, - struct inet_peer __rcu **stack[PEER_MAXDEPTH]) -{ - struct inet_peer __rcu ***stackptr, ***delp; - - if (lookup(&p->daddr, stack, base) != p) - BUG(); - delp = stackptr - 1; /* *delp[0] == p */ - if (p->avl_left == peer_avl_empty_rcu) { - *delp[0] = p->avl_right; - --stackptr; - } else { - /* look for a node to insert instead of p */ - struct inet_peer *t; - t = lookup_rightempty(p, base); - BUG_ON(rcu_deref_locked(*stackptr[-1], base) != t); - **--stackptr = t->avl_left; - /* t is removed, t->daddr > x->daddr for any - * x in p->avl_left subtree. - * Put t in the old place of p. */ - RCU_INIT_POINTER(*delp[0], t); - t->avl_left = p->avl_left; - t->avl_right = p->avl_right; - t->avl_height = p->avl_height; - BUG_ON(delp[1] != &p->avl_left); - delp[1] = &t->avl_left; /* was &p->avl_left */ - } - peer_avl_rebalance(stack, stackptr, base); - base->total--; - call_rcu(&p->rcu, inetpeer_free_rcu); -} - /* perform garbage collect on all items stacked during a lookup */ -static int inet_peer_gc(struct inet_peer_base *base, - struct inet_peer __rcu **stack[PEER_MAXDEPTH], - struct inet_peer __rcu ***stackptr) +static void inet_peer_gc(struct inet_peer_base *base, + struct inet_peer *gc_stack[], + unsigned int gc_cnt) { - struct inet_peer *p, *gchead = NULL; + struct inet_peer *p; __u32 delta, ttl; - int cnt = 0; + int i; if (base->total >= inet_peer_threshold) ttl = 0; /* be aggressive */ @@ -379,43 +157,38 @@ static int inet_peer_gc(struct inet_peer_base *base, ttl = inet_peer_maxttl - (inet_peer_maxttl - inet_peer_minttl) / HZ * base->total / inet_peer_threshold * HZ; - stackptr--; /* last stack slot is peer_avl_empty */ - while (stackptr > stack) { - stackptr--; - p = rcu_deref_locked(**stackptr, base); - if (refcount_read(&p->refcnt) == 1) { - smp_rmb(); - delta = (__u32)jiffies - p->dtime; - if (delta >= ttl && refcount_dec_if_one(&p->refcnt)) { - p->gc_next = gchead; - gchead = p; - } - } + for (i = 0; i < gc_cnt; i++) { + p = gc_stack[i]; + delta = (__u32)jiffies - p->dtime; + if (delta < ttl || !refcount_dec_if_one(&p->refcnt)) + gc_stack[i] = NULL; } - while ((p = gchead) != NULL) { - gchead = p->gc_next; - cnt++; - unlink_from_pool(p, base, stack); + for (i = 0; i < gc_cnt; i++) { + p = gc_stack[i]; + if (p) { + rb_erase(&p->rb_node, &base->rb_root); + base->total--; + call_rcu(&p->rcu, inetpeer_free_rcu); + } } - return cnt; } struct inet_peer *inet_getpeer(struct inet_peer_base *base, const struct inetpeer_addr *daddr, int create) { - struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; - struct inet_peer *p; - unsigned int sequence; - int invalidated, gccnt = 0; + struct inet_peer *p, *gc_stack[PEER_MAX_GC]; + struct rb_node **pp, *parent; + unsigned int gc_cnt, seq; + int invalidated; /* Attempt a lockless lookup first. * Because of a concurrent writer, we might not find an existing entry. */ rcu_read_lock(); - sequence = read_seqbegin(&base->lock); - p = lookup_rcu(daddr, base); - invalidated = read_seqretry(&base->lock, sequence); + seq = read_seqbegin(&base->lock); + p = lookup(daddr, base, seq, NULL, &gc_cnt, &parent, &pp); + invalidated = read_seqretry(&base->lock, seq); rcu_read_unlock(); if (p) @@ -428,36 +201,31 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base, /* retry an exact lookup, taking the lock before. * At least, nodes should be hot in our cache. */ + parent = NULL; write_seqlock_bh(&base->lock); -relookup: - p = lookup(daddr, stack, base); - if (p != peer_avl_empty) { - refcount_inc(&p->refcnt); - write_sequnlock_bh(&base->lock); - return p; - } - if (!gccnt) { - gccnt = inet_peer_gc(base, stack, stackptr); - if (gccnt && create) - goto relookup; - } - p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL; - if (p) { - p->daddr = *daddr; - refcount_set(&p->refcnt, 2); - atomic_set(&p->rid, 0); - p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; - p->rate_tokens = 0; - /* 60*HZ is arbitrary, but chosen enough high so that the first - * calculation of tokens is at its maximum. - */ - p->rate_last = jiffies - 60*HZ; - INIT_LIST_HEAD(&p->gc_list); - /* Link the node. */ - link_to_pool(p, base); - base->total++; + gc_cnt = 0; + p = lookup(daddr, base, seq, gc_stack, &gc_cnt, &parent, &pp); + if (!p && create) { + p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC); + if (p) { + p->daddr = *daddr; + refcount_set(&p->refcnt, 2); + atomic_set(&p->rid, 0); + p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; + p->rate_tokens = 0; + /* 60*HZ is arbitrary, but chosen enough high so that the first + * calculation of tokens is at its maximum. + */ + p->rate_last = jiffies - 60*HZ; + + rb_link_node(&p->rb_node, parent, pp); + rb_insert_color(&p->rb_node, &base->rb_root); + base->total++; + } } + if (gc_cnt) + inet_peer_gc(base, gc_stack, gc_cnt); write_sequnlock_bh(&base->lock); return p; @@ -467,8 +235,9 @@ EXPORT_SYMBOL_GPL(inet_getpeer); void inet_putpeer(struct inet_peer *p) { p->dtime = (__u32)jiffies; - smp_mb__before_atomic(); - refcount_dec(&p->refcnt); + + if (refcount_dec_and_test(&p->refcnt)) + call_rcu(&p->rcu, inetpeer_free_rcu); } EXPORT_SYMBOL_GPL(inet_putpeer); @@ -513,30 +282,16 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout) } EXPORT_SYMBOL(inet_peer_xrlim_allow); -static void inetpeer_inval_rcu(struct rcu_head *head) -{ - struct inet_peer *p = container_of(head, struct inet_peer, gc_rcu); - - spin_lock_bh(&gc_lock); - list_add_tail(&p->gc_list, &gc_list); - spin_unlock_bh(&gc_lock); - - schedule_delayed_work(&gc_work, gc_delay); -} - void inetpeer_invalidate_tree(struct inet_peer_base *base) { - struct inet_peer *root; - - write_seqlock_bh(&base->lock); + struct inet_peer *p, *n; - root = rcu_deref_locked(base->root, base); - if (root != peer_avl_empty) { - base->root = peer_avl_empty_rcu; - base->total = 0; - call_rcu(&root->gc_rcu, inetpeer_inval_rcu); + rbtree_postorder_for_each_entry_safe(p, n, &base->rb_root, rb_node) { + inet_putpeer(p); + cond_resched(); } - write_sequnlock_bh(&base->lock); + base->rb_root = RB_ROOT; + base->total = 0; } EXPORT_SYMBOL(inetpeer_invalidate_tree); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 9a8cfac503dc8c83e24a7b168dbd4da781a30284..46408c220d9dcb59380b15a17c1ce3f277c9ba8f 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -844,8 +844,6 @@ static void __init ip4_frags_ctl_register(void) static int __net_init ipv4_frags_init_net(struct net *net) { - int res; - /* Fragment cache limits. * * The fragment memory accounting code, (tries to) account for @@ -871,13 +869,9 @@ static int __net_init ipv4_frags_init_net(struct net *net) net->ipv4.frags.max_dist = 64; - res = inet_frags_init_net(&net->ipv4.frags); - if (res) - return res; - res = ip4_frags_ns_ctl_register(net); - if (res) - inet_frags_uninit_net(&net->ipv4.frags); - return res; + inet_frags_init_net(&net->ipv4.frags); + + return ip4_frags_ns_ctl_register(net); } static void __net_exit ipv4_frags_exit_net(struct net *net) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 7a7829e839c24ee624a046079f25545e035d5bc7..467e44d7587dcf6dc9eeb3845b1fe069b6c8389e 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -48,6 +48,7 @@ #include #include #include +#include /* Problems & solutions @@ -112,9 +113,12 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); static struct rtnl_link_ops ipgre_link_ops __read_mostly; static int ipgre_tunnel_init(struct net_device *dev); +static void erspan_build_header(struct sk_buff *skb, + __be32 id, u32 index, bool truncate); static unsigned int ipgre_net_id __read_mostly; static unsigned int gre_tap_net_id __read_mostly; +static unsigned int erspan_net_id __read_mostly; static void ipgre_err(struct sk_buff *skb, u32 info, const struct tnl_ptk_info *tpi) @@ -246,6 +250,79 @@ static void gre_err(struct sk_buff *skb, u32 info) ipgre_err(skb, info, &tpi); } +static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, + int gre_hdr_len) +{ + struct net *net = dev_net(skb->dev); + struct metadata_dst *tun_dst = NULL; + struct ip_tunnel_net *itn; + struct ip_tunnel *tunnel; + struct erspanhdr *ershdr; + const struct iphdr *iph; + __be32 index; + int len; + + itn = net_generic(net, erspan_net_id); + len = gre_hdr_len + sizeof(*ershdr); + + if (unlikely(!pskb_may_pull(skb, len))) + return -ENOMEM; + + iph = ip_hdr(skb); + ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len); + + /* The original GRE header does not have key field, + * Use ERSPAN 10-bit session ID as key. + */ + tpi->key = cpu_to_be32(ntohs(ershdr->session_id) & ID_MASK); + index = ershdr->md.index; + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, + tpi->flags | TUNNEL_KEY, + iph->saddr, iph->daddr, tpi->key); + + if (tunnel) { + if (__iptunnel_pull_header(skb, + gre_hdr_len + sizeof(*ershdr), + htons(ETH_P_TEB), + false, false) < 0) + goto drop; + + if (tunnel->collect_md) { + struct ip_tunnel_info *info; + struct erspan_metadata *md; + __be64 tun_id; + __be16 flags; + + tpi->flags |= TUNNEL_KEY; + flags = tpi->flags; + tun_id = key32_to_tunnel_id(tpi->key); + + tun_dst = ip_tun_rx_dst(skb, flags, + tun_id, sizeof(*md)); + if (!tun_dst) + return PACKET_REJECT; + + md = ip_tunnel_info_opts(&tun_dst->u.tun_info); + if (!md) + return PACKET_REJECT; + + md->index = index; + info = &tun_dst->u.tun_info; + info->key.tun_flags |= TUNNEL_ERSPAN_OPT; + info->options_len = sizeof(*md); + } else { + tunnel->index = ntohl(index); + } + + skb_reset_mac_header(skb); + ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); + return PACKET_RCVD; + } +drop: + kfree_skb(skb); + return PACKET_RCVD; +} + static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, struct ip_tunnel_net *itn, int hdr_len, bool raw_proto) { @@ -328,6 +405,11 @@ static int gre_rcv(struct sk_buff *skb) if (hdr_len < 0) goto drop; + if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) { + if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD) + return 0; + } + if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD) return 0; @@ -376,39 +458,33 @@ static struct rtable *gre_get_rt(struct sk_buff *skb, return ip_route_output_key(net, fl); } -static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, - __be16 proto) +static struct rtable *prepare_fb_xmit(struct sk_buff *skb, + struct net_device *dev, + struct flowi4 *fl, + int tunnel_hlen) { struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; struct rtable *rt = NULL; - struct flowi4 fl; int min_headroom; - int tunnel_hlen; - __be16 df, flags; bool use_cache; int err; tun_info = skb_tunnel_info(skb); - if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || - ip_tunnel_info_af(tun_info) != AF_INET)) - goto err_free_skb; - key = &tun_info->key; use_cache = ip_tunnel_dst_cache_usable(skb, tun_info); + if (use_cache) - rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl.saddr); + rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl->saddr); if (!rt) { - rt = gre_get_rt(skb, dev, &fl, key); + rt = gre_get_rt(skb, dev, fl, key); if (IS_ERR(rt)) - goto err_free_skb; + goto err_free_skb; if (use_cache) dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst, - fl.saddr); + fl->saddr); } - tunnel_hlen = gre_calc_hlen(key->tun_flags); - min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len + tunnel_hlen + sizeof(struct iphdr); if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) { @@ -420,6 +496,37 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, if (unlikely(err)) goto err_free_rt; } + return rt; + +err_free_rt: + ip_rt_put(rt); +err_free_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return NULL; +} + +static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, + __be16 proto) +{ + struct ip_tunnel_info *tun_info; + const struct ip_tunnel_key *key; + struct rtable *rt = NULL; + struct flowi4 fl; + int tunnel_hlen; + __be16 df, flags; + + tun_info = skb_tunnel_info(skb); + if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || + ip_tunnel_info_af(tun_info) != AF_INET)) + goto err_free_skb; + + key = &tun_info->key; + tunnel_hlen = gre_calc_hlen(key->tun_flags); + + rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen); + if (!rt) + return; /* Push Tunnel header. */ if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM))) @@ -442,6 +549,64 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, dev->stats.tx_dropped++; } +static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev, + __be16 proto) +{ + struct ip_tunnel *tunnel = netdev_priv(dev); + struct ip_tunnel_info *tun_info; + const struct ip_tunnel_key *key; + struct erspan_metadata *md; + struct rtable *rt = NULL; + bool truncate = false; + struct flowi4 fl; + int tunnel_hlen; + __be16 df; + + tun_info = skb_tunnel_info(skb); + if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || + ip_tunnel_info_af(tun_info) != AF_INET)) + goto err_free_skb; + + key = &tun_info->key; + + /* ERSPAN has fixed 8 byte GRE header */ + tunnel_hlen = 8 + sizeof(struct erspanhdr); + + rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen); + if (!rt) + return; + + if (gre_handle_offloads(skb, false)) + goto err_free_rt; + + if (skb->len > dev->mtu) { + pskb_trim(skb, dev->mtu); + truncate = true; + } + + md = ip_tunnel_info_opts(tun_info); + if (!md) + goto err_free_rt; + + erspan_build_header(skb, tunnel_id_to_key32(key->tun_id), + ntohl(md->index), truncate); + + gre_build_header(skb, 8, TUNNEL_SEQ, + htons(ETH_P_ERSPAN), 0, htonl(tunnel->o_seqno++)); + + df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; + + iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE, + key->tos, key->ttl, df, false); + return; + +err_free_rt: + ip_rt_put(rt); +err_free_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; +} + static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) { struct ip_tunnel_info *info = skb_tunnel_info(skb); @@ -503,6 +668,86 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } +static inline u8 tos_to_cos(u8 tos) +{ + u8 dscp, cos; + + dscp = tos >> 2; + cos = dscp >> 3; + return cos; +} + +static void erspan_build_header(struct sk_buff *skb, + __be32 id, u32 index, bool truncate) +{ + struct iphdr *iphdr = ip_hdr(skb); + struct ethhdr *eth = eth_hdr(skb); + enum erspan_encap_type enc_type; + struct erspanhdr *ershdr; + struct qtag_prefix { + __be16 eth_type; + __be16 tci; + } *qp; + u16 vlan_tci = 0; + + enc_type = ERSPAN_ENCAP_NOVLAN; + + /* If mirrored packet has vlan tag, extract tci and + * perserve vlan header in the mirrored frame. + */ + if (eth->h_proto == htons(ETH_P_8021Q)) { + qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN); + vlan_tci = ntohs(qp->tci); + enc_type = ERSPAN_ENCAP_INFRAME; + } + + skb_push(skb, sizeof(*ershdr)); + ershdr = (struct erspanhdr *)skb->data; + memset(ershdr, 0, sizeof(*ershdr)); + + ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) | + (ERSPAN_VERSION << VER_OFFSET)); + ershdr->session_id = htons((u16)(ntohl(id) & ID_MASK) | + ((tos_to_cos(iphdr->tos) << COS_OFFSET) & COS_MASK) | + (enc_type << EN_OFFSET & EN_MASK) | + ((truncate << T_OFFSET) & T_MASK)); + ershdr->md.index = htonl(index & INDEX_MASK); +} + +static netdev_tx_t erspan_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct ip_tunnel *tunnel = netdev_priv(dev); + bool truncate = false; + + if (tunnel->collect_md) { + erspan_fb_xmit(skb, dev, skb->protocol); + return NETDEV_TX_OK; + } + + if (gre_handle_offloads(skb, false)) + goto free_skb; + + if (skb_cow_head(skb, dev->needed_headroom)) + goto free_skb; + + if (skb->len - dev->hard_header_len > dev->mtu) { + pskb_trim(skb, dev->mtu); + truncate = true; + } + + /* Push ERSPAN header */ + erspan_build_header(skb, tunnel->parms.o_key, tunnel->index, truncate); + tunnel->parms.o_flags &= ~TUNNEL_KEY; + __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN)); + return NETDEV_TX_OK; + +free_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; +} + static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -828,6 +1073,42 @@ static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[], return ipgre_tunnel_validate(tb, data, extack); } +static int erspan_validate(struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + __be16 flags = 0; + int ret; + + if (!data) + return 0; + + ret = ipgre_tap_validate(tb, data, extack); + if (ret) + return ret; + + /* ERSPAN should only have GRE sequence and key flag */ + if (data[IFLA_GRE_OFLAGS]) + flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]); + if (data[IFLA_GRE_IFLAGS]) + flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]); + if (!data[IFLA_GRE_COLLECT_METADATA] && + flags != (GRE_SEQ | GRE_KEY)) + return -EINVAL; + + /* ERSPAN Session ID only has 10-bit. Since we reuse + * 32-bit key field as ID, check it's range. + */ + if (data[IFLA_GRE_IKEY] && + (ntohl(nla_get_be32(data[IFLA_GRE_IKEY])) & ~ID_MASK)) + return -EINVAL; + + if (data[IFLA_GRE_OKEY] && + (ntohl(nla_get_be32(data[IFLA_GRE_OKEY])) & ~ID_MASK)) + return -EINVAL; + + return 0; +} + static int ipgre_netlink_parms(struct net_device *dev, struct nlattr *data[], struct nlattr *tb[], @@ -892,6 +1173,13 @@ static int ipgre_netlink_parms(struct net_device *dev, if (data[IFLA_GRE_FWMARK]) *fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]); + if (data[IFLA_GRE_ERSPAN_INDEX]) { + t->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); + + if (t->index & ~INDEX_MASK) + return -EINVAL; + } + return 0; } @@ -933,6 +1221,7 @@ static int gre_tap_init(struct net_device *dev) { __gre_tunnel_init(dev); dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + netif_keep_dst(dev); return ip_tunnel_init(dev); } @@ -949,6 +1238,39 @@ static const struct net_device_ops gre_tap_netdev_ops = { .ndo_fill_metadata_dst = gre_fill_metadata_dst, }; +static int erspan_tunnel_init(struct net_device *dev) +{ + struct ip_tunnel *tunnel = netdev_priv(dev); + int t_hlen; + + tunnel->tun_hlen = 8; + tunnel->parms.iph.protocol = IPPROTO_GRE; + tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen + + sizeof(struct erspanhdr); + t_hlen = tunnel->hlen + sizeof(struct iphdr); + + dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4; + dev->mtu = ETH_DATA_LEN - t_hlen - 4; + dev->features |= GRE_FEATURES; + dev->hw_features |= GRE_FEATURES; + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + netif_keep_dst(dev); + + return ip_tunnel_init(dev); +} + +static const struct net_device_ops erspan_netdev_ops = { + .ndo_init = erspan_tunnel_init, + .ndo_uninit = ip_tunnel_uninit, + .ndo_start_xmit = erspan_xmit, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = ip_tunnel_change_mtu, + .ndo_get_stats64 = ip_tunnel_get_stats64, + .ndo_get_iflink = ip_tunnel_get_iflink, + .ndo_fill_metadata_dst = gre_fill_metadata_dst, +}; + static void ipgre_tap_setup(struct net_device *dev) { ether_setup(dev); @@ -1041,6 +1363,8 @@ static size_t ipgre_get_size(const struct net_device *dev) nla_total_size(1) + /* IFLA_GRE_FWMARK */ nla_total_size(4) + + /* IFLA_GRE_ERSPAN_INDEX */ + nla_total_size(4) + 0; } @@ -1083,12 +1407,25 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev) goto nla_put_failure; } + if (t->index) + if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index)) + goto nla_put_failure; + return 0; nla_put_failure: return -EMSGSIZE; } +static void erspan_setup(struct net_device *dev) +{ + ether_setup(dev); + dev->netdev_ops = &erspan_netdev_ops; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + ip_tunnel_setup(dev, erspan_net_id); +} + static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = { [IFLA_GRE_LINK] = { .type = NLA_U32 }, [IFLA_GRE_IFLAGS] = { .type = NLA_U16 }, @@ -1107,6 +1444,7 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = { [IFLA_GRE_COLLECT_METADATA] = { .type = NLA_FLAG }, [IFLA_GRE_IGNORE_DF] = { .type = NLA_U8 }, [IFLA_GRE_FWMARK] = { .type = NLA_U32 }, + [IFLA_GRE_ERSPAN_INDEX] = { .type = NLA_U32 }, }; static struct rtnl_link_ops ipgre_link_ops __read_mostly = { @@ -1139,6 +1477,21 @@ static struct rtnl_link_ops ipgre_tap_ops __read_mostly = { .get_link_net = ip_tunnel_get_link_net, }; +static struct rtnl_link_ops erspan_link_ops __read_mostly = { + .kind = "erspan", + .maxtype = IFLA_GRE_MAX, + .policy = ipgre_policy, + .priv_size = sizeof(struct ip_tunnel), + .setup = erspan_setup, + .validate = erspan_validate, + .newlink = ipgre_newlink, + .changelink = ipgre_changelink, + .dellink = ip_tunnel_dellink, + .get_size = ipgre_get_size, + .fill_info = ipgre_fill_info, + .get_link_net = ip_tunnel_get_link_net, +}; + struct net_device *gretap_fb_dev_create(struct net *net, const char *name, u8 name_assign_type) { @@ -1202,6 +1555,26 @@ static struct pernet_operations ipgre_tap_net_ops = { .size = sizeof(struct ip_tunnel_net), }; +static int __net_init erspan_init_net(struct net *net) +{ + return ip_tunnel_init_net(net, erspan_net_id, + &erspan_link_ops, "erspan0"); +} + +static void __net_exit erspan_exit_net(struct net *net) +{ + struct ip_tunnel_net *itn = net_generic(net, erspan_net_id); + + ip_tunnel_delete_net(itn, &erspan_link_ops); +} + +static struct pernet_operations erspan_net_ops = { + .init = erspan_init_net, + .exit = erspan_exit_net, + .id = &erspan_net_id, + .size = sizeof(struct ip_tunnel_net), +}; + static int __init ipgre_init(void) { int err; @@ -1214,7 +1587,11 @@ static int __init ipgre_init(void) err = register_pernet_device(&ipgre_tap_net_ops); if (err < 0) - goto pnet_tap_faied; + goto pnet_tap_failed; + + err = register_pernet_device(&erspan_net_ops); + if (err < 0) + goto pnet_erspan_failed; err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO); if (err < 0) { @@ -1230,15 +1607,23 @@ static int __init ipgre_init(void) if (err < 0) goto tap_ops_failed; + err = rtnl_link_register(&erspan_link_ops); + if (err < 0) + goto erspan_link_failed; + return 0; +erspan_link_failed: + rtnl_link_unregister(&ipgre_tap_ops); tap_ops_failed: rtnl_link_unregister(&ipgre_link_ops); rtnl_link_failed: gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO); add_proto_failed: + unregister_pernet_device(&erspan_net_ops); +pnet_erspan_failed: unregister_pernet_device(&ipgre_tap_net_ops); -pnet_tap_faied: +pnet_tap_failed: unregister_pernet_device(&ipgre_net_ops); return err; } @@ -1247,9 +1632,11 @@ static void __exit ipgre_fini(void) { rtnl_link_unregister(&ipgre_tap_ops); rtnl_link_unregister(&ipgre_link_ops); + rtnl_link_unregister(&erspan_link_ops); gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO); unregister_pernet_device(&ipgre_tap_net_ops); unregister_pernet_device(&ipgre_net_ops); + unregister_pernet_device(&erspan_net_ops); } module_init(ipgre_init); @@ -1257,5 +1644,7 @@ module_exit(ipgre_fini); MODULE_LICENSE("GPL"); MODULE_ALIAS_RTNL_LINK("gre"); MODULE_ALIAS_RTNL_LINK("gretap"); +MODULE_ALIAS_RTNL_LINK("erspan"); MODULE_ALIAS_NETDEV("gre0"); MODULE_ALIAS_NETDEV("gretap0"); +MODULE_ALIAS_NETDEV("erspan0"); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index fa2dc8f692c631f1ff7fe814c3ee27f0de2a41d8..57fc13c6ab2b7843a4fdb11680c82fc342f465c7 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -311,9 +311,10 @@ static inline bool ip_rcv_options(struct sk_buff *skb) static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { const struct iphdr *iph = ip_hdr(skb); - struct rtable *rt; + int (*edemux)(struct sk_buff *skb); struct net_device *dev = skb->dev; - void (*edemux)(struct sk_buff *skb); + struct rtable *rt; + int err; /* if ingress device is enslaved to an L3 master device pass the * skb to its handler for processing @@ -331,7 +332,9 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) { - edemux(skb); + err = edemux(skb); + if (unlikely(err)) + goto drop_error; /* must reload iph, skb->head might have changed */ iph = ip_hdr(skb); } @@ -342,13 +345,10 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) * how the packet travels inside Linux networking. */ if (!skb_valid_dst(skb)) { - int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, dev); - if (unlikely(err)) { - if (err == -EXDEV) - __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); - goto drop; - } + err = ip_route_input_noref(skb, iph->daddr, iph->saddr, + iph->tos, dev); + if (unlikely(err)) + goto drop_error; } #ifdef CONFIG_IP_ROUTE_CLASSID @@ -399,6 +399,11 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) drop: kfree_skb(skb); return NET_RX_DROP; + +drop_error: + if (err == -EXDEV) + __NET_INC_STATS(net, LINUX_MIB_IPRPFILTER); + goto drop; } /* diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 93157f2f4758e581579a623e3c6cb04dfdedb037..525ae88d1e586e0c5d3abf6c64a22e5367a01a8d 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -86,8 +86,8 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt, * NOTE: dopt cannot point to skb. */ -int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, - const struct ip_options *sopt) +int __ip_options_echo(struct net *net, struct ip_options *dopt, + struct sk_buff *skb, const struct ip_options *sopt) { unsigned char *sptr, *dptr; int soffset, doffset; @@ -140,7 +140,7 @@ int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, __be32 addr; memcpy(&addr, dptr+soffset-1, 4); - if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) { + if (inet_addr_type(net, addr) != RTN_UNICAST) { dopt->ts_needtime = 1; soffset += 8; } @@ -174,9 +174,6 @@ int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, doffset -= 4; } if (doffset > 3) { - __be32 daddr = fib_compute_spec_dst(skb); - - memcpy(&start[doffset-1], &daddr, 4); dopt->faddr = faddr; dptr[0] = start[0]; dptr[1] = doffset+3; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 50c74cd890bc79ed6c85c958c5397d833e9aa74a..e8e675be60ec0044007c660bae1bb4d12c9a484e 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -853,61 +853,6 @@ csum_page(struct page *page, int offset, int copy) return csum; } -static inline int ip_ufo_append_data(struct sock *sk, - struct sk_buff_head *queue, - int getfrag(void *from, char *to, int offset, int len, - int odd, struct sk_buff *skb), - void *from, int length, int hh_len, int fragheaderlen, - int transhdrlen, int maxfraglen, unsigned int flags) -{ - struct sk_buff *skb; - int err; - - /* There is support for UDP fragmentation offload by network - * device, so create one single skb packet containing complete - * udp datagram - */ - skb = skb_peek_tail(queue); - if (!skb) { - skb = sock_alloc_send_skb(sk, - hh_len + fragheaderlen + transhdrlen + 20, - (flags & MSG_DONTWAIT), &err); - - if (!skb) - return err; - - /* reserve space for Hardware header */ - skb_reserve(skb, hh_len); - - /* create space for UDP/IP header */ - skb_put(skb, fragheaderlen + transhdrlen); - - /* initialize network header pointer */ - skb_reset_network_header(skb); - - /* initialize protocol header pointer */ - skb->transport_header = skb->network_header + fragheaderlen; - - skb->csum = 0; - - if (flags & MSG_CONFIRM) - skb_set_dst_pending_confirm(skb, 1); - - __skb_queue_tail(queue, skb); - } else if (skb_is_gso(skb)) { - goto append; - } - - skb->ip_summed = CHECKSUM_PARTIAL; - /* specify the length of each IP datagram fragment */ - skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; - skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - -append: - return skb_append_datato_frags(sk, skb, getfrag, from, - (length - transhdrlen)); -} - static int __ip_append_data(struct sock *sk, struct flowi4 *fl4, struct sk_buff_head *queue, @@ -965,18 +910,6 @@ static int __ip_append_data(struct sock *sk, csummode = CHECKSUM_PARTIAL; cork->length += length; - if ((((length + (skb ? skb->len : fragheaderlen)) > mtu) || - (skb && skb_is_gso(skb))) && - (sk->sk_protocol == IPPROTO_UDP) && - (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && - (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) { - err = ip_ufo_append_data(sk, queue, getfrag, from, length, - hh_len, fragheaderlen, transhdrlen, - maxfraglen, flags); - if (err) - goto error; - return 0; - } /* So, what's going on in the loop below? * @@ -1287,27 +1220,14 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, if (!skb) return -EINVAL; - if ((size + skb->len > mtu) && - (sk->sk_protocol == IPPROTO_UDP) && - (rt->dst.dev->features & NETIF_F_UFO)) { - if (skb->ip_summed != CHECKSUM_PARTIAL) - return -EOPNOTSUPP; - - skb_shinfo(skb)->gso_size = mtu - fragheaderlen; - skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - } cork->length += size; while (size > 0) { - if (skb_is_gso(skb)) { - len = size; - } else { + /* Check if the remaining data fits into current packet. */ + len = mtu - skb->len; + if (len < size) + len = maxfraglen - skb->len; - /* Check if the remaining data fits into current packet. */ - len = mtu - skb->len; - if (len < size) - len = maxfraglen - skb->len; - } if (len <= 0) { struct sk_buff *skb_prev; int alloclen; @@ -1601,7 +1521,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, int err; int oif; - if (__ip_options_echo(&replyopts.opt.opt, skb, sopt)) + if (__ip_options_echo(net, &replyopts.opt.opt, skb, sopt)) return; ipc.addr = daddr; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ecc4b4a2413e337c059a3468f584575497b8457b..a599aa83fdadfa62f09dbee1038d06fbc3155fd4 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -80,7 +80,8 @@ static void ip_cmsg_recv_opts(struct msghdr *msg, struct sk_buff *skb) } -static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb) +static void ip_cmsg_recv_retopts(struct net *net, struct msghdr *msg, + struct sk_buff *skb) { unsigned char optbuf[sizeof(struct ip_options) + 40]; struct ip_options *opt = (struct ip_options *)optbuf; @@ -88,7 +89,7 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb) if (IPCB(skb)->opt.optlen == 0) return; - if (ip_options_echo(opt, skb)) { + if (ip_options_echo(net, opt, skb)) { msg->msg_flags |= MSG_CTRUNC; return; } @@ -204,7 +205,7 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, } if (flags & IP_CMSG_RETOPTS) { - ip_cmsg_recv_retopts(msg, skb); + ip_cmsg_recv_retopts(sock_net(sk), msg, skb); flags &= ~IP_CMSG_RETOPTS; if (!flags) @@ -1219,22 +1220,20 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) * (e.g., process binds socket to eth0 for Tx which is * redirected to loopback in the rtable/dst). */ + struct rtable *rt = skb_rtable(skb); + bool l3slave = ipv4_l3mdev_skb(IPCB(skb)->flags); + if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX) pktinfo->ipi_ifindex = inet_iif(skb); + else if (l3slave && rt && rt->rt_iif) + pktinfo->ipi_ifindex = rt->rt_iif; pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb); } else { pktinfo->ipi_ifindex = 0; pktinfo->ipi_spec_dst.s_addr = 0; } - /* We need to keep the dst for __ip_options_echo() - * We could restrict the test to opt.ts_needtime || opt.srr, - * but the following is good enough as IP options are not often used. - */ - if (unlikely(IPCB(skb)->opt.optlen)) - skb_dst_force(skb); - else - skb_dst_drop(skb); + skb_dst_drop(skb); } int ip_setsockopt(struct sock *sk, int level, diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 129d1a3616f838c9b487cf2392d1d9eb09dcfa5a..e9805ad664ac24c3405ad015cfaab89dc1c95279 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -176,7 +176,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, return cand; t = rcu_dereference(itn->collect_md_tun); - if (t) + if (t && t->dev->flags & IFF_UP) return t; if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP) @@ -618,8 +618,8 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto) ip_rt_put(rt); goto tx_dropped; } - iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, key->tos, - key->ttl, df, !net_eq(tunnel->net, dev_net(dev))); + iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl, + df, !net_eq(tunnel->net, dev_net(dev))); return; tx_error: dev->stats.tx_errors++; diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 0192c255e5088394792cb55b416c46e39b5839fd..89453cf62158fbdcb18bf28494e9b54ee143558f 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -168,6 +168,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, struct ip_tunnel_parm *parms = &tunnel->parms; struct dst_entry *dst = skb_dst(skb); struct net_device *tdev; /* Device to other host */ + int pkt_len = skb->len; int err; int mtu; @@ -229,7 +230,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, err = dst_output(tunnel->net, skb->sk, skb); if (net_xmit_eval(err) == 0) - err = skb->len; + err = pkt_len; iptunnel_xmit_stats(dev, err); return NETDEV_TX_OK; @@ -584,33 +585,6 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = { .get_link_net = ip_tunnel_get_link_net, }; -static bool is_vti_tunnel(const struct net_device *dev) -{ - return dev->netdev_ops == &vti_netdev_ops; -} - -static int vti_device_event(struct notifier_block *unused, - unsigned long event, void *ptr) -{ - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struct ip_tunnel *tunnel = netdev_priv(dev); - - if (!is_vti_tunnel(dev)) - return NOTIFY_DONE; - - switch (event) { - case NETDEV_DOWN: - if (!net_eq(tunnel->net, dev_net(dev))) - xfrm_garbage_collect(tunnel->net); - break; - } - return NOTIFY_DONE; -} - -static struct notifier_block vti_notifier_block __read_mostly = { - .notifier_call = vti_device_event, -}; - static int __init vti_init(void) { const char *msg; @@ -618,8 +592,6 @@ static int __init vti_init(void) pr_info("IPv4 over IPsec tunneling driver\n"); - register_netdevice_notifier(&vti_notifier_block); - msg = "tunnel device"; err = register_pernet_device(&vti_net_ops); if (err < 0) @@ -652,7 +624,6 @@ static int __init vti_init(void) xfrm_proto_esp_failed: unregister_pernet_device(&vti_net_ops); pernet_dev_failed: - unregister_netdevice_notifier(&vti_notifier_block); pr_err("vti init: failed to register %s\n", msg); return err; } @@ -664,7 +635,6 @@ static void __exit vti_fini(void) xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP); unregister_pernet_device(&vti_net_ops); - unregister_netdevice_notifier(&vti_notifier_block); } module_init(vti_init); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 06863ea3fc5b8c5582a70b14a4da9ecc67851822..c9b3e6e069aea65a88c20b0702450240f7f83417 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -3114,14 +3114,14 @@ int __init ip_mr_init(void) } #endif rtnl_register(RTNL_FAMILY_IPMR, RTM_GETROUTE, - ipmr_rtm_getroute, ipmr_rtm_dumproute, NULL); + ipmr_rtm_getroute, ipmr_rtm_dumproute, 0); rtnl_register(RTNL_FAMILY_IPMR, RTM_NEWROUTE, - ipmr_rtm_route, NULL, NULL); + ipmr_rtm_route, NULL, 0); rtnl_register(RTNL_FAMILY_IPMR, RTM_DELROUTE, - ipmr_rtm_route, NULL, NULL); + ipmr_rtm_route, NULL, 0); rtnl_register(RTNL_FAMILY_IPMR, RTM_GETLINK, - NULL, ipmr_rtm_dumplink, NULL); + NULL, ipmr_rtm_dumplink, 0); return 0; #ifdef CONFIG_IP_PIMSM_V2 diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 0bc3c3d73e61e00a04d73f32800256a62c8943a5..9e2770fd00be5eda1a633893c42b59378ab52f17 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -268,14 +268,14 @@ unsigned int arpt_do_table(struct sk_buff *skb, acpar.targinfo = t->data; verdict = t->u.kernel.target->target(skb, &acpar); - /* Target might have changed stuff. */ - arp = arp_hdr(skb); - - if (verdict == XT_CONTINUE) + if (verdict == XT_CONTINUE) { + /* Target might have changed stuff. */ + arp = arp_hdr(skb); e = arpt_next_entry(e); - else + } else { /* Verdict */ break; + } } while (!acpar.hotdrop); xt_write_recseq_end(addend); local_bh_enable(); @@ -629,6 +629,7 @@ static void get_counters(const struct xt_table_info *t, ADD_COUNTER(counters[i], bcnt, pcnt); ++i; + cond_resched(); } } } @@ -1117,7 +1118,6 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, struct xt_table_info *newinfo, unsigned char *base) { struct xt_entry_target *t; - struct xt_target *target; struct arpt_entry *de; unsigned int origsize; int h; @@ -1132,7 +1132,6 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, de->target_offset = e->target_offset - (origsize - *size); t = compat_arpt_get_target(e); - target = t->u.kernel.target; xt_compat_target_from_user(t, dstptr, size); de->next_offset = e->next_offset - (origsize - *size); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2a55a40211cbfb94a9ade41c33678bba4be2a7e4..39286e543ee683fee9ee7d302d860ec3ee0ea104 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -35,12 +35,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("IPv4 packet filter"); -#ifdef CONFIG_NETFILTER_DEBUG -#define IP_NF_ASSERT(x) WARN_ON(!(x)) -#else -#define IP_NF_ASSERT(x) -#endif - void *ipt_alloc_initial_table(const struct xt_table *info) { return xt_alloc_initial_table(ipt, IPT); @@ -151,7 +145,7 @@ static const char *const comments[] = { [NF_IP_TRACE_COMMENT_POLICY] = "policy", }; -static struct nf_loginfo trace_loginfo = { +static const struct nf_loginfo trace_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { @@ -263,7 +257,7 @@ ipt_do_table(struct sk_buff *skb, acpar.hotdrop = false; acpar.state = state; - IP_NF_ASSERT(table->valid_hooks & (1 << hook)); + WARN_ON(!(table->valid_hooks & (1 << hook))); local_bh_disable(); addend = xt_write_recseq_begin(); private = table->private; @@ -293,7 +287,7 @@ ipt_do_table(struct sk_buff *skb, const struct xt_entry_match *ematch; struct xt_counters *counter; - IP_NF_ASSERT(e); + WARN_ON(!e); if (!ip_packet_match(ip, indev, outdev, &e->ip, acpar.fragoff)) { no_match: @@ -312,7 +306,7 @@ ipt_do_table(struct sk_buff *skb, ADD_COUNTER(*counter, skb->len, 1); t = ipt_get_target(e); - IP_NF_ASSERT(t->u.kernel.target); + WARN_ON(!t->u.kernel.target); #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) /* The packet is traced: log it */ @@ -352,13 +346,14 @@ ipt_do_table(struct sk_buff *skb, acpar.targinfo = t->data; verdict = t->u.kernel.target->target(skb, &acpar); - /* Target might have changed stuff. */ - ip = ip_hdr(skb); - if (verdict == XT_CONTINUE) + if (verdict == XT_CONTINUE) { + /* Target might have changed stuff. */ + ip = ip_hdr(skb); e = ipt_next_entry(e); - else + } else { /* Verdict */ break; + } } while (!acpar.hotdrop); xt_write_recseq_end(addend); @@ -781,6 +776,7 @@ get_counters(const struct xt_table_info *t, ADD_COUNTER(counters[i], bcnt, pcnt); ++i; /* macro does multi eval of i */ + cond_resched(); } } } @@ -1355,7 +1351,6 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, struct xt_table_info *newinfo, unsigned char *base) { struct xt_entry_target *t; - struct xt_target *target; struct ipt_entry *de; unsigned int origsize; int h; @@ -1374,7 +1369,6 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, de->target_offset = e->target_offset - (origsize - *size); t = compat_ipt_get_target(e); - target = t->u.kernel.target; xt_compat_target_from_user(t, dstptr, size); de->next_offset = e->next_offset - (origsize - *size); diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 7d72decb80f9f9c4150bd2a42c4b802ba1fd7f17..17b4ca562944c35b50015bbc40aa580ca62ddfb7 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -117,7 +117,8 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c) * functions are also incrementing the refcount on their own, * so it's safe to remove the entry even if it's in use. */ #ifdef CONFIG_PROC_FS - proc_remove(c->pde); + if (cn->procdir) + proc_remove(c->pde); #endif return; } @@ -624,7 +625,7 @@ arp_mangle(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops cip_arp_ops __read_mostly = { +static const struct nf_hook_ops cip_arp_ops = { .hook = arp_mangle, .pf = NFPROTO_ARP, .hooknum = NF_ARP_OUT, @@ -815,6 +816,7 @@ static void clusterip_net_exit(struct net *net) #ifdef CONFIG_PROC_FS struct clusterip_net *cn = net_generic(net, clusterip_net_id); proc_remove(cn->procdir); + cn->procdir = NULL; #endif nf_unregister_net_hook(net, &cip_arp_ops); } diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index f1528f7175a8c18697cb4b5da776acc670076e49..811689e523c310dc41b71f6ec9fcff3d2749e590 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -416,7 +416,7 @@ static unsigned int ipv4_synproxy_hook(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = { +static const struct nf_hook_ops ipv4_synproxy_ops[] = { { .hook = ipv4_synproxy_hook, .pf = NFPROTO_IPV4, diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c index 138a24bc76ad9d215e1e9b836405774adaac02e7..a1a07b338ccfd5468b4fe80557af693b0e4f8861 100644 --- a/net/ipv4/netfilter/iptable_nat.c +++ b/net/ipv4/netfilter/iptable_nat.c @@ -67,7 +67,7 @@ static unsigned int iptable_nat_ipv4_local_fn(void *priv, return nf_nat_ipv4_local_fn(priv, skb, state, iptable_nat_do_chain); } -static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = { +static const struct nf_hook_ops nf_nat_ipv4_ops[] = { /* Before packet filtering, change destination */ { .hook = iptable_nat_ipv4_in, diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 2e14ed11a35cfc83db845e972521b2e8894f97c6..fe374da4bc13efa1eaa02ec630fd065ef8dcb118 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -63,13 +63,6 @@ static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -static void ipv4_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "src=%pI4 dst=%pI4 ", - &tuple->src.u3.ip, &tuple->dst.u3.ip); -} - static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, unsigned int *dataoff, u_int8_t *protonum) { @@ -174,7 +167,7 @@ static unsigned int ipv4_conntrack_local(void *priv, /* Connection tracking may drop packets, but never alters them, so make it the first hook. */ -static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { +static const struct nf_hook_ops ipv4_conntrack_ops[] = { { .hook = ipv4_conntrack_in, .pf = NFPROTO_IPV4, @@ -303,11 +296,6 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[], return 0; } - -static int ipv4_nlattr_tuple_size(void) -{ - return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1); -} #endif static struct nf_sockopt_ops so_getorigdst = { @@ -358,16 +346,15 @@ static void ipv4_hooks_unregister(struct net *net) struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .l3proto = PF_INET, - .name = "ipv4", .pkt_to_tuple = ipv4_pkt_to_tuple, .invert_tuple = ipv4_invert_tuple, - .print_tuple = ipv4_print_tuple, .get_l4proto = ipv4_get_l4proto, #if IS_ENABLED(CONFIG_NF_CT_NETLINK) .tuple_to_nlattr = ipv4_tuple_to_nlattr, - .nlattr_tuple_size = ipv4_nlattr_tuple_size, .nlattr_to_tuple = ipv4_nlattr_to_tuple, .nla_policy = ipv4_nla_policy, + .nla_size = NLA_ALIGN(NLA_HDRLEN + sizeof(u32)) + /* CTA_IP_V4_SRC */ + NLA_ALIGN(NLA_HDRLEN + sizeof(u32)), /* CTA_IP_V4_DST */ #endif .net_ns_get = ipv4_hooks_register, .net_ns_put = ipv4_hooks_unregister, @@ -398,24 +385,12 @@ static struct nf_conntrack_l4proto *builtin_l4proto4[] = { static int ipv4_net_init(struct net *net) { - int ret = 0; - - ret = nf_ct_l4proto_pernet_register(net, builtin_l4proto4, - ARRAY_SIZE(builtin_l4proto4)); - if (ret < 0) - return ret; - ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv4); - if (ret < 0) { - pr_err("nf_conntrack_ipv4: pernet registration failed\n"); - nf_ct_l4proto_pernet_unregister(net, builtin_l4proto4, - ARRAY_SIZE(builtin_l4proto4)); - } - return ret; + return nf_ct_l4proto_pernet_register(net, builtin_l4proto4, + ARRAY_SIZE(builtin_l4proto4)); } static void ipv4_net_exit(struct net *net) { - nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv4); nf_ct_l4proto_pernet_unregister(net, builtin_l4proto4, ARRAY_SIZE(builtin_l4proto4)); } @@ -433,6 +408,11 @@ static int __init nf_conntrack_l3proto_ipv4_init(void) need_conntrack(); +#if IS_ENABLED(CONFIG_NF_CT_NETLINK) + if (WARN_ON(nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1) != + nf_conntrack_l3proto_ipv4.nla_size)) + return -EINVAL; +#endif ret = nf_register_sockopt(&so_getorigdst); if (ret < 0) { pr_err("Unable to register netfilter socket option\n"); diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 73c591d8a9a8e5295000f702e1b32e6a643e30e0..a046c298413aec4a5920191b3873bf37682a44e8 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -71,16 +71,6 @@ static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -/* Print out the per-protocol part of the tuple. */ -static void icmp_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "type=%u code=%u id=%u ", - tuple->dst.u.icmp.type, - tuple->dst.u.icmp.code, - ntohs(tuple->src.u.icmp.id)); -} - static unsigned int *icmp_get_timeouts(struct net *net) { return &icmp_pernet(net)->timeout; @@ -92,7 +82,6 @@ static int icmp_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeout) { /* Do not immediately delete the connection after the first @@ -137,7 +126,7 @@ icmp_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, enum ip_conntrack_info ctinfo; struct nf_conntrack_zone tmp; - NF_CT_ASSERT(!skb_nfct(skb)); + WARN_ON(skb_nfct(skb)); zone = nf_ct_zone_tmpl(tmpl, skb, &tmp); /* Are they talking about one of our connections? */ @@ -362,10 +351,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_ICMP, - .name = "icmp", .pkt_to_tuple = icmp_pkt_to_tuple, .invert_tuple = icmp_invert_tuple, - .print_tuple = icmp_print_tuple, .packet = icmp_packet, .get_timeouts = icmp_get_timeouts, .new = icmp_new, diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index 346bf7ccac0881bc86c7d019987281d9dc8db62e..37fe1616ca0bcb27ca2a4772dc93851d00b7929a 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c @@ -90,7 +90,7 @@ static unsigned int ipv4_conntrack_defrag(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops ipv4_defrag_ops[] = { +static const struct nf_hook_ops ipv4_defrag_ops[] = { { .hook = ipv4_conntrack_defrag, .pf = NFPROTO_IPV4, diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c index 2f3895ddc275d2e72b2f93d816a27f41b292384a..df5c2a2061a4b1e76c2d26f4b9b44164883a4dcb 100644 --- a/net/ipv4/netfilter/nf_log_arp.c +++ b/net/ipv4/netfilter/nf_log_arp.c @@ -25,7 +25,7 @@ #include #include -static struct nf_loginfo default_loginfo = { +static const struct nf_loginfo default_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c index c83a9963269bf689d7c4285c89ef1a4228bc739b..4388de0e5380c6423fbdfe7438727900fc297d7c 100644 --- a/net/ipv4/netfilter/nf_log_ipv4.c +++ b/net/ipv4/netfilter/nf_log_ipv4.c @@ -24,7 +24,7 @@ #include #include -static struct nf_loginfo default_loginfo = { +static const struct nf_loginfo default_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 574f7ebba0b6238d8e61ffd08dead06a07a619c5..ac8342dcb55eb51680d1f4559d57c2e99509b505 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -252,16 +252,16 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, if (set_h245_addr(skb, protoff, data, dataoff, taddr, &ct->tuplehash[!dir].tuple.dst.u3, htons((port & htons(1)) ? nated_port + 1 : - nated_port)) == 0) { - /* Save ports */ - info->rtp_port[i][dir] = rtp_port; - info->rtp_port[i][!dir] = htons(nated_port); - } else { + nated_port))) { nf_ct_unexpect_related(rtp_exp); nf_ct_unexpect_related(rtcp_exp); return -1; } + /* Save ports */ + info->rtp_port[i][dir] = rtp_port; + info->rtp_port[i][!dir] = htons(nated_port); + /* Success */ pr_debug("nf_nat_h323: expect RTP %pI4:%hu->%pI4:%hu\n", &rtp_exp->tuple.src.u3.ip, @@ -370,15 +370,15 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, /* Modify signal */ if (set_h225_addr(skb, protoff, data, dataoff, taddr, &ct->tuplehash[!dir].tuple.dst.u3, - htons(nated_port)) == 0) { - /* Save ports */ - info->sig_port[dir] = port; - info->sig_port[!dir] = htons(nated_port); - } else { + htons(nated_port))) { nf_ct_unexpect_related(exp); return -1; } + /* Save ports */ + info->sig_port[dir] = port; + info->sig_port[!dir] = htons(nated_port); + pr_debug("nf_nat_q931: expect H.245 %pI4:%hu->%pI4:%hu\n", &exp->tuple.src.u3.ip, ntohs(exp->tuple.src.u.tcp.port), @@ -462,24 +462,27 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, /* Modify signal */ if (set_h225_addr(skb, protoff, data, 0, &taddr[idx], &ct->tuplehash[!dir].tuple.dst.u3, - htons(nated_port)) == 0) { - /* Save ports */ - info->sig_port[dir] = port; - info->sig_port[!dir] = htons(nated_port); - - /* Fix for Gnomemeeting */ - if (idx > 0 && - get_h225_addr(ct, *data, &taddr[0], &addr, &port) && - (ntohl(addr.ip) & 0xff000000) == 0x7f000000) { - set_h225_addr(skb, protoff, data, 0, &taddr[0], - &ct->tuplehash[!dir].tuple.dst.u3, - info->sig_port[!dir]); - } - } else { + htons(nated_port))) { nf_ct_unexpect_related(exp); return -1; } + /* Save ports */ + info->sig_port[dir] = port; + info->sig_port[!dir] = htons(nated_port); + + /* Fix for Gnomemeeting */ + if (idx > 0 && + get_h225_addr(ct, *data, &taddr[0], &addr, &port) && + (ntohl(addr.ip) & 0xff000000) == 0x7f000000) { + if (set_h225_addr(skb, protoff, data, 0, &taddr[0], + &ct->tuplehash[!dir].tuple.dst.u3, + info->sig_port[!dir])) { + nf_ct_unexpect_related(exp); + return -1; + } + } + /* Success */ pr_debug("nf_nat_ras: expect Q.931 %pI4:%hu->%pI4:%hu\n", &exp->tuple.src.u3.ip, @@ -550,9 +553,9 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, } /* Modify signal */ - if (!set_h225_addr(skb, protoff, data, dataoff, taddr, - &ct->tuplehash[!dir].tuple.dst.u3, - htons(nated_port)) == 0) { + if (set_h225_addr(skb, protoff, data, dataoff, taddr, + &ct->tuplehash[!dir].tuple.dst.u3, + htons(nated_port))) { nf_ct_unexpect_related(exp); return -1; } diff --git a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c index feedd759ca8043c3eff37e22d0f1c8301b229da2..a0f37b2082682690f55ae64a089f46c0068faf3f 100644 --- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c @@ -190,7 +190,7 @@ int nf_nat_icmp_reply_translation(struct sk_buff *skb, struct nf_conntrack_tuple target; unsigned long statusbit; - NF_CT_ASSERT(ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY); + WARN_ON(ctinfo != IP_CT_RELATED && ctinfo != IP_CT_RELATED_REPLY); if (!skb_make_writable(skb, hdrlen + sizeof(*inside))) return 0; @@ -306,8 +306,8 @@ nf_nat_ipv4_fn(void *priv, struct sk_buff *skb, default: /* ESTABLISHED */ - NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || - ctinfo == IP_CT_ESTABLISHED_REPLY); + WARN_ON(ctinfo != IP_CT_ESTABLISHED && + ctinfo != IP_CT_ESTABLISHED_REPLY); if (nf_nat_oif_changed(state->hook, ctinfo, nat, state->out)) goto oif_changed; } diff --git a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c index f39037fca923566c9d75c7b88d881cd3a50a6992..0c366aad89cb47bcad1e553f388825a40730f6d9 100644 --- a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c +++ b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c @@ -34,12 +34,12 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum, const struct rtable *rt; __be32 newsrc, nh; - NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); + WARN_ON(hooknum != NF_INET_POST_ROUTING); ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || - ctinfo == IP_CT_RELATED_REPLY)); + WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || + ctinfo == IP_CT_RELATED_REPLY))); /* Source address is 0.0.0.0 - locally generated packet that is * probably not supposed to be masqueraded. @@ -96,7 +96,7 @@ static int masq_device_event(struct notifier_block *this, * conntracks which were associated with that device, * and forget them. */ - NF_CT_ASSERT(dev->ifindex != 0); + WARN_ON(dev->ifindex == 0); nf_ct_iterate_cleanup_net(net, device_cmp, (void *)(long)dev->ifindex, 0, 0); diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c index de3681df2ce71c7341d96dd5d2540ab110ac80eb..e50976e3c2133e40796c28d9c42652868a88c35c 100644 --- a/net/ipv4/netfilter/nft_fib_ipv4.c +++ b/net/ipv4/netfilter/nft_fib_ipv4.c @@ -32,9 +32,10 @@ void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { const struct nft_fib *priv = nft_expr_priv(expr); + int noff = skb_network_offset(pkt->skb); u32 *dst = ®s->data[priv->dreg]; const struct net_device *dev = NULL; - const struct iphdr *iph; + struct iphdr *iph, _iph; __be32 addr; if (priv->flags & NFTA_FIB_F_IIF) @@ -42,7 +43,12 @@ void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs, else if (priv->flags & NFTA_FIB_F_OIF) dev = nft_out(pkt); - iph = ip_hdr(pkt->skb); + iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph); + if (!iph) { + regs->verdict.code = NFT_BREAK; + return; + } + if (priv->flags & NFTA_FIB_F_DADDR) addr = iph->daddr; else @@ -61,8 +67,9 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { const struct nft_fib *priv = nft_expr_priv(expr); + int noff = skb_network_offset(pkt->skb); u32 *dest = ®s->data[priv->dreg]; - const struct iphdr *iph; + struct iphdr *iph, _iph; struct fib_result res; struct flowi4 fl4 = { .flowi4_scope = RT_SCOPE_UNIVERSE, @@ -95,7 +102,12 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, return; } - iph = ip_hdr(pkt->skb); + iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph); + if (!iph) { + regs->verdict.code = NFT_BREAK; + return; + } + if (ipv4_is_zeronet(iph->saddr)) { if (ipv4_is_lbcast(iph->daddr) || ipv4_is_local_multicast(iph->daddr)) { diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 43eb6567b3a0a2add9a1d36019eae5b6d5caf657..127153f1ed8a7894e0b2d2059af08bdcc6a00236 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -206,12 +206,7 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("DelayedACKLost", LINUX_MIB_DELAYEDACKLOST), SNMP_MIB_ITEM("ListenOverflows", LINUX_MIB_LISTENOVERFLOWS), SNMP_MIB_ITEM("ListenDrops", LINUX_MIB_LISTENDROPS), - SNMP_MIB_ITEM("TCPPrequeued", LINUX_MIB_TCPPREQUEUED), - SNMP_MIB_ITEM("TCPDirectCopyFromBacklog", LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG), - SNMP_MIB_ITEM("TCPDirectCopyFromPrequeue", LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE), - SNMP_MIB_ITEM("TCPPrequeueDropped", LINUX_MIB_TCPPREQUEUEDROPPED), SNMP_MIB_ITEM("TCPHPHits", LINUX_MIB_TCPHPHITS), - SNMP_MIB_ITEM("TCPHPHitsToUser", LINUX_MIB_TCPHPHITSTOUSER), SNMP_MIB_ITEM("TCPPureAcks", LINUX_MIB_TCPPUREACKS), SNMP_MIB_ITEM("TCPHPAcks", LINUX_MIB_TCPHPACKS), SNMP_MIB_ITEM("TCPRenoRecovery", LINUX_MIB_TCPRENORECOVERY), @@ -230,14 +225,12 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPSackFailures", LINUX_MIB_TCPSACKFAILURES), SNMP_MIB_ITEM("TCPLossFailures", LINUX_MIB_TCPLOSSFAILURES), SNMP_MIB_ITEM("TCPFastRetrans", LINUX_MIB_TCPFASTRETRANS), - SNMP_MIB_ITEM("TCPForwardRetrans", LINUX_MIB_TCPFORWARDRETRANS), SNMP_MIB_ITEM("TCPSlowStartRetrans", LINUX_MIB_TCPSLOWSTARTRETRANS), SNMP_MIB_ITEM("TCPTimeouts", LINUX_MIB_TCPTIMEOUTS), SNMP_MIB_ITEM("TCPLossProbes", LINUX_MIB_TCPLOSSPROBES), SNMP_MIB_ITEM("TCPLossProbeRecovery", LINUX_MIB_TCPLOSSPROBERECOVERY), SNMP_MIB_ITEM("TCPRenoRecoveryFail", LINUX_MIB_TCPRENORECOVERYFAIL), SNMP_MIB_ITEM("TCPSackRecoveryFail", LINUX_MIB_TCPSACKRECOVERYFAIL), - SNMP_MIB_ITEM("TCPSchedulerFailed", LINUX_MIB_TCPSCHEDULERFAILED), SNMP_MIB_ITEM("TCPRcvCollapsed", LINUX_MIB_TCPRCVCOLLAPSED), SNMP_MIB_ITEM("TCPDSACKOldSent", LINUX_MIB_TCPDSACKOLDSENT), SNMP_MIB_ITEM("TCPDSACKOfoSent", LINUX_MIB_TCPDSACKOFOSENT), diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b0bb5d0a30bd50b84f0d6a3bccd39b996b4678b3..33b70bfd1122f08f4897ea6a68eb51e3a74bb1e5 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -122,7 +122,8 @@ void raw_unhash_sk(struct sock *sk) EXPORT_SYMBOL_GPL(raw_unhash_sk); struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, - unsigned short num, __be32 raddr, __be32 laddr, int dif) + unsigned short num, __be32 raddr, __be32 laddr, + int dif, int sdif) { sk_for_each_from(sk) { struct inet_sock *inet = inet_sk(sk); @@ -130,7 +131,8 @@ struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, if (net_eq(sock_net(sk), net) && inet->inet_num == num && !(inet->inet_daddr && inet->inet_daddr != raddr) && !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && - !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) + !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && + sk->sk_bound_dev_if != sdif)) goto found; /* gotcha */ } sk = NULL; @@ -171,6 +173,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb) */ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) { + int sdif = inet_sdif(skb); struct sock *sk; struct hlist_head *head; int delivered = 0; @@ -184,13 +187,13 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) net = dev_net(skb->dev); sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, iph->saddr, iph->daddr, - skb->dev->ifindex); + skb->dev->ifindex, sdif); while (sk) { delivered = 1; if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) && ip_mc_sf_allow(sk, iph->daddr, iph->saddr, - skb->dev->ifindex)) { + skb->dev->ifindex, sdif)) { struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); /* Not releasing hash table! */ @@ -199,7 +202,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) } sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, iph->saddr, iph->daddr, - skb->dev->ifindex); + skb->dev->ifindex, sdif); } out: read_unlock(&raw_v4_hashinfo.lock); @@ -297,12 +300,15 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) read_lock(&raw_v4_hashinfo.lock); raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); if (raw_sk) { + int dif = skb->dev->ifindex; + int sdif = inet_sdif(skb); + iph = (const struct iphdr *)skb->data; net = dev_net(skb->dev); while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, iph->daddr, iph->saddr, - skb->dev->ifindex)) != NULL) { + dif, sdif)) != NULL) { raw_err(raw_sk, skb, info); raw_sk = sk_next(raw_sk); iph = (const struct iphdr *)skb->data; diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c index e1a51ca68d23c324b6643234c6af399aacca83e0..c200065ef9a5e49b022eeb2286d59eaf822136f9 100644 --- a/net/ipv4/raw_diag.c +++ b/net/ipv4/raw_diag.c @@ -46,13 +46,13 @@ static struct sock *raw_lookup(struct net *net, struct sock *from, sk = __raw_v4_lookup(net, from, r->sdiag_raw_protocol, r->id.idiag_dst[0], r->id.idiag_src[0], - r->id.idiag_if); + r->id.idiag_if, 0); #if IS_ENABLED(CONFIG_IPV6) else sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol, (const struct in6_addr *)r->id.idiag_src, (const struct in6_addr *)r->id.idiag_dst, - r->id.idiag_if); + r->id.idiag_if, 0); #endif return sk; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0383e66f59bcef3bd6b8627edae9aa2d34139f5d..ac6fde5d45f14dd258ffd6a8a5ba7a3f1ed0bf63 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1267,7 +1267,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) if (mtu) return mtu; - mtu = dst->dev->mtu; + mtu = READ_ONCE(dst->dev->mtu); if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { if (rt->rt_uses_gateway && mtu > 576) @@ -1398,7 +1398,7 @@ static void ipv4_dst_destroy(struct dst_entry *dst) struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); struct rtable *rt = (struct rtable *) dst; - if (p != &dst_default_metrics && atomic_dec_and_test(&p->refcnt)) + if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) kfree(p); if (!list_empty(&rt->rt_uncached)) { @@ -1456,7 +1456,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, dst_init_metrics(&rt->dst, fi->fib_metrics->metrics, true); if (fi->fib_metrics != &dst_default_metrics) { rt->dst._metrics |= DST_METRICS_REFCOUNTED; - atomic_inc(&fi->fib_metrics->refcnt); + refcount_inc(&fi->fib_metrics->refcnt); } #ifdef CONFIG_IP_ROUTE_CLASSID rt->dst.tclassid = nh->nh_tclassid; @@ -1520,43 +1520,56 @@ struct rtable *rt_dst_alloc(struct net_device *dev, EXPORT_SYMBOL(rt_dst_alloc); /* called in rcu_read_lock() section */ -static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, - u8 tos, struct net_device *dev, int our) +int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, + u8 tos, struct net_device *dev, + struct in_device *in_dev, u32 *itag) { - struct rtable *rth; - struct in_device *in_dev = __in_dev_get_rcu(dev); - unsigned int flags = RTCF_MULTICAST; - u32 itag = 0; int err; /* Primary sanity checks. */ - if (!in_dev) return -EINVAL; if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) || skb->protocol != htons(ETH_P_IP)) - goto e_inval; + return -EINVAL; if (ipv4_is_loopback(saddr) && !IN_DEV_ROUTE_LOCALNET(in_dev)) - goto e_inval; + return -EINVAL; if (ipv4_is_zeronet(saddr)) { if (!ipv4_is_local_multicast(daddr)) - goto e_inval; + return -EINVAL; } else { err = fib_validate_source(skb, saddr, 0, tos, 0, dev, - in_dev, &itag); + in_dev, itag); if (err < 0) - goto e_err; + return err; } + return 0; +} + +/* called in rcu_read_lock() section */ +static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, + u8 tos, struct net_device *dev, int our) +{ + struct in_device *in_dev = __in_dev_get_rcu(dev); + unsigned int flags = RTCF_MULTICAST; + struct rtable *rth; + u32 itag = 0; + int err; + + err = ip_mc_validate_source(skb, daddr, saddr, tos, dev, in_dev, &itag); + if (err) + return err; + if (our) flags |= RTCF_LOCAL; rth = rt_dst_alloc(dev_net(dev)->loopback_dev, flags, RTN_MULTICAST, IN_DEV_CONF_GET(in_dev, NOPOLICY), false, false); if (!rth) - goto e_nobufs; + return -ENOBUFS; #ifdef CONFIG_IP_ROUTE_CLASSID rth->dst.tclassid = itag; @@ -1572,13 +1585,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, skb_dst_set(skb, &rth->dst); return 0; - -e_nobufs: - return -ENOBUFS; -e_inval: - return -EINVAL; -e_err: - return err; } @@ -2236,7 +2242,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (!rth) return ERR_PTR(-ENOBUFS); - rth->rt_iif = orig_oif ? : 0; + rth->rt_iif = orig_oif; if (res->table) rth->rt_table_id = res->table->tb_id; @@ -2439,6 +2445,12 @@ struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4, /* L3 master device is the loopback for that domain */ dev_out = l3mdev_master_dev_rcu(FIB_RES_DEV(*res)) ? : net->loopback_dev; + + /* make sure orig_oif points to fib result device even + * though packet rx/tx happens over loopback or l3mdev + */ + orig_oif = FIB_RES_OIF(*res); + fl4->flowi4_oif = dev_out->ifindex; flags |= RTCF_LOCAL; goto make_route; @@ -2750,26 +2762,34 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, err = 0; if (IS_ERR(rt)) err = PTR_ERR(rt); + else + skb_dst_set(skb, &rt->dst); } if (err) goto errout_free; - skb_dst_set(skb, &rt->dst); if (rtm->rtm_flags & RTM_F_NOTIFY) rt->rt_flags |= RTCF_NOTIFY; if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE) table_id = rt->rt_table_id; - if (rtm->rtm_flags & RTM_F_FIB_MATCH) + if (rtm->rtm_flags & RTM_F_FIB_MATCH) { + if (!res.fi) { + err = fib_props[res.type].error; + if (!err) + err = -EHOSTUNREACH; + goto errout_free; + } err = fib_dump_info(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, RTM_NEWROUTE, table_id, rt->rt_type, res.prefix, res.prefixlen, fl4.flowi4_tos, res.fi, 0); - else + } else { err = rt_fill_info(net, dst, src, table_id, &fl4, skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq); + } if (err < 0) goto errout_free; @@ -3067,7 +3087,8 @@ int __init ip_rt_init(void) xfrm_init(); xfrm4_init(); #endif - rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); + rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, + RTNL_FLAG_DOIT_UNLOCKED); #ifdef CONFIG_SYSCTL register_pernet_subsys(&sysctl_route_ops); diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 03ad8778c395334ed53a250bccc0b991cd85c2f2..b1bb1b3a108232d56aa82383422d68b5ff9da3ed 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) */ - ireq->opt = tcp_v4_save_options(skb); + ireq->opt = tcp_v4_save_options(sock_net(sk), skb); if (security_inet_conn_request(sk, skb, req)) { reqsk_free(req); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 9bf8097260660e7621ba670d59b9991aa6b146fe..0d3c038d7b0454eb2213ad88eb7ebfe27504b2ee 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -45,6 +45,9 @@ static int tcp_syn_retries_max = MAX_TCP_SYNCNT; static int ip_ping_group_range_min[] = { 0, 0 }; static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; +/* obsolete */ +static int sysctl_tcp_low_latency __read_mostly; + /* Update system visible IP port range */ static void set_local_port_range(struct net *net, int range[2]) { diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 71ce33decd971feee72f225b2bf7ccaf2f5f456f..5091402720abca1737b60ab51266e9b40b588188 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -269,6 +269,7 @@ #include #include #include +#include #include #include @@ -388,6 +389,19 @@ static int retrans_to_secs(u8 retrans, int timeout, int rto_max) return period; } +static u64 tcp_compute_delivery_rate(const struct tcp_sock *tp) +{ + u32 rate = READ_ONCE(tp->rate_delivered); + u32 intv = READ_ONCE(tp->rate_interval_us); + u64 rate64 = 0; + + if (rate && intv) { + rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC; + do_div(rate64, intv); + } + return rate64; +} + /* Address-family independent initialization for a tcp_sock. * * NOTE: A lot of things set to zero explicitly by call to @@ -400,7 +414,6 @@ void tcp_init_sock(struct sock *sk) tp->out_of_order_queue = RB_ROOT; tcp_init_xmit_timers(sk); - tcp_prequeue_init(tp); INIT_LIST_HEAD(&tp->tsq_node); icsk->icsk_rto = TCP_TIMEOUT_INIT; @@ -1034,23 +1047,29 @@ ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, } EXPORT_SYMBOL_GPL(do_tcp_sendpages); -int tcp_sendpage(struct sock *sk, struct page *page, int offset, - size_t size, int flags) +int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, + size_t size, int flags) { - ssize_t res; - if (!(sk->sk_route_caps & NETIF_F_SG) || !sk_check_csum_caps(sk)) - return sock_no_sendpage(sk->sk_socket, page, offset, size, - flags); - - lock_sock(sk); + return sock_no_sendpage_locked(sk, page, offset, size, flags); tcp_rate_check_app_limited(sk); /* is sending application-limited? */ - res = do_tcp_sendpages(sk, page, offset, size, flags); + return do_tcp_sendpages(sk, page, offset, size, flags); +} +EXPORT_SYMBOL_GPL(tcp_sendpage_locked); + +int tcp_sendpage(struct sock *sk, struct page *page, int offset, + size_t size, int flags) +{ + int ret; + + lock_sock(sk); + ret = tcp_sendpage_locked(sk, page, offset, size, flags); release_sock(sk); - return res; + + return ret; } EXPORT_SYMBOL(tcp_sendpage); @@ -1144,9 +1163,10 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, return err; } -int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) +int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) { struct tcp_sock *tp = tcp_sk(sk); + struct ubuf_info *uarg = NULL; struct sk_buff *skb; struct sockcm_cookie sockc; int flags, err, copied = 0; @@ -1155,9 +1175,25 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) bool sg; long timeo; - lock_sock(sk); - flags = msg->msg_flags; + + if (flags & MSG_ZEROCOPY && size) { + if (sk->sk_state != TCP_ESTABLISHED) { + err = -EINVAL; + goto out_err; + } + + skb = tcp_send_head(sk) ? tcp_write_queue_tail(sk) : NULL; + uarg = sock_zerocopy_realloc(sk, size, skb_zcopy(skb)); + if (!uarg) { + err = -ENOBUFS; + goto out_err; + } + + if (!(sk_check_csum_caps(sk) && sk->sk_route_caps & NETIF_F_SG)) + uarg->zerocopy = 0; + } + if (unlikely(flags & MSG_FASTOPEN || inet_sk(sk)->defer_connect)) { err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); if (err == -EINPROGRESS && copied_syn > 0) @@ -1281,7 +1317,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) err = skb_add_data_nocache(sk, skb, &msg->msg_iter, copy); if (err) goto do_fault; - } else { + } else if (!uarg || !uarg->zerocopy) { bool merge = true; int i = skb_shinfo(skb)->nr_frags; struct page_frag *pfrag = sk_page_frag(sk); @@ -1319,6 +1355,13 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) page_ref_inc(pfrag->page); } pfrag->offset += copy; + } else { + err = skb_zerocopy_iter_stream(sk, skb, msg, copy, uarg); + if (err == -EMSGSIZE || err == -EEXIST) + goto new_segment; + if (err < 0) + goto do_error; + copy = err; } if (!copied) @@ -1365,7 +1408,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) tcp_push(sk, flags, mss_now, tp->nonagle, size_goal); } out_nopush: - release_sock(sk); + sock_zerocopy_put(uarg); return copied + copied_syn; do_fault: @@ -1382,6 +1425,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) if (copied + copied_syn) goto out; out_err: + sock_zerocopy_put_abort(uarg); err = sk_stream_error(sk, flags, err); /* make sure we wake any epoll edge trigger waiter */ if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 && @@ -1389,9 +1433,20 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) sk->sk_write_space(sk); tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); } - release_sock(sk); return err; } +EXPORT_SYMBOL_GPL(tcp_sendmsg_locked); + +int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) +{ + int ret; + + lock_sock(sk); + ret = tcp_sendmsg_locked(sk, msg, size); + release_sock(sk); + + return ret; +} EXPORT_SYMBOL(tcp_sendmsg); /* @@ -1525,20 +1580,6 @@ static void tcp_cleanup_rbuf(struct sock *sk, int copied) tcp_send_ack(sk); } -static void tcp_prequeue_process(struct sock *sk) -{ - struct sk_buff *skb; - struct tcp_sock *tp = tcp_sk(sk); - - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPPREQUEUED); - - while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) - sk_backlog_rcv(sk, skb); - - /* Clear memory counter. */ - tp->ucopy.memory = 0; -} - static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) { struct sk_buff *skb; @@ -1652,6 +1693,61 @@ int tcp_peek_len(struct socket *sock) } EXPORT_SYMBOL(tcp_peek_len); +static void tcp_update_recv_tstamps(struct sk_buff *skb, + struct scm_timestamping *tss) +{ + if (skb->tstamp) + tss->ts[0] = ktime_to_timespec(skb->tstamp); + else + tss->ts[0] = (struct timespec) {0}; + + if (skb_hwtstamps(skb)->hwtstamp) + tss->ts[2] = ktime_to_timespec(skb_hwtstamps(skb)->hwtstamp); + else + tss->ts[2] = (struct timespec) {0}; +} + +/* Similar to __sock_recv_timestamp, but does not require an skb */ +void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, + struct scm_timestamping *tss) +{ + struct timeval tv; + bool has_timestamping = false; + + if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) { + if (sock_flag(sk, SOCK_RCVTSTAMP)) { + if (sock_flag(sk, SOCK_RCVTSTAMPNS)) { + put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, + sizeof(tss->ts[0]), &tss->ts[0]); + } else { + tv.tv_sec = tss->ts[0].tv_sec; + tv.tv_usec = tss->ts[0].tv_nsec / 1000; + + put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, + sizeof(tv), &tv); + } + } + + if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) + has_timestamping = true; + else + tss->ts[0] = (struct timespec) {0}; + } + + if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) { + if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) + has_timestamping = true; + else + tss->ts[2] = (struct timespec) {0}; + } + + if (has_timestamping) { + tss->ts[1] = (struct timespec) {0}; + put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING, + sizeof(*tss), tss); + } +} + /* * This routine copies from a sock struct into the user buffer. * @@ -1671,9 +1767,10 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, int err; int target; /* Read at least this many bytes */ long timeo; - struct task_struct *user_recv = NULL; struct sk_buff *skb, *last; u32 urg_hole = 0; + struct scm_timestamping tss; + bool has_tss = false; if (unlikely(flags & MSG_ERRQUEUE)) return inet_recv_error(sk, msg, len, addr_len); @@ -1806,51 +1903,6 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, tcp_cleanup_rbuf(sk, copied); - if (!sysctl_tcp_low_latency && tp->ucopy.task == user_recv) { - /* Install new reader */ - if (!user_recv && !(flags & (MSG_TRUNC | MSG_PEEK))) { - user_recv = current; - tp->ucopy.task = user_recv; - tp->ucopy.msg = msg; - } - - tp->ucopy.len = len; - - WARN_ON(tp->copied_seq != tp->rcv_nxt && - !(flags & (MSG_PEEK | MSG_TRUNC))); - - /* Ugly... If prequeue is not empty, we have to - * process it before releasing socket, otherwise - * order will be broken at second iteration. - * More elegant solution is required!!! - * - * Look: we have the following (pseudo)queues: - * - * 1. packets in flight - * 2. backlog - * 3. prequeue - * 4. receive_queue - * - * Each queue can be processed only if the next ones - * are empty. At this point we have empty receive_queue. - * But prequeue _can_ be not empty after 2nd iteration, - * when we jumped to start of loop because backlog - * processing added something to receive_queue. - * We cannot release_sock(), because backlog contains - * packets arrived _after_ prequeued ones. - * - * Shortly, algorithm is clear --- to process all - * the queues in order. We could make it more directly, - * requeueing packets from backlog to prequeue, if - * is not empty. It is more elegant, but eats cycles, - * unfortunately. - */ - if (!skb_queue_empty(&tp->ucopy.prequeue)) - goto do_prequeue; - - /* __ Set realtime policy in scheduler __ */ - } - if (copied >= target) { /* Do not sleep, just process backlog. */ release_sock(sk); @@ -1859,31 +1911,6 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, sk_wait_data(sk, &timeo, last); } - if (user_recv) { - int chunk; - - /* __ Restore normal policy in scheduler __ */ - - chunk = len - tp->ucopy.len; - if (chunk != 0) { - NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG, chunk); - len -= chunk; - copied += chunk; - } - - if (tp->rcv_nxt == tp->copied_seq && - !skb_queue_empty(&tp->ucopy.prequeue)) { -do_prequeue: - tcp_prequeue_process(sk); - - chunk = len - tp->ucopy.len; - if (chunk != 0) { - NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, chunk); - len -= chunk; - copied += chunk; - } - } - } if ((flags & MSG_PEEK) && (peek_seq - copied - urg_hole != tp->copied_seq)) { net_dbg_ratelimited("TCP(%s:%d): Application bug, race in MSG_PEEK\n", @@ -1941,6 +1968,10 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, if (used + offset < skb->len) continue; + if (TCP_SKB_CB(skb)->has_rxtstamp) { + tcp_update_recv_tstamps(skb, &tss); + has_tss = true; + } if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) goto found_fin_ok; if (!(flags & MSG_PEEK)) @@ -1955,29 +1986,13 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, break; } while (len > 0); - if (user_recv) { - if (!skb_queue_empty(&tp->ucopy.prequeue)) { - int chunk; - - tp->ucopy.len = copied > 0 ? len : 0; - - tcp_prequeue_process(sk); - - if (copied > 0 && (chunk = len - tp->ucopy.len) != 0) { - NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE, chunk); - len -= chunk; - copied += chunk; - } - } - - tp->ucopy.task = NULL; - tp->ucopy.len = 0; - } - /* According to UNIX98, msg_name/msg_namelen are ignored * on connected socket. I was just happy when found this 8) --ANK */ + if (has_tss) + tcp_recv_timestamp(msg, sk, &tss); + /* Clean up data we have read: This will do ACK frames. */ tcp_cleanup_rbuf(sk, copied); @@ -2481,7 +2496,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, name[val] = 0; lock_sock(sk); - err = tcp_set_congestion_control(sk, name, true); + err = tcp_set_congestion_control(sk, name, true, true); release_sock(sk); return err; } @@ -2823,7 +2838,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) { const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); - u32 now, intv; + u32 now; u64 rate64; bool slow; u32 rate; @@ -2922,13 +2937,9 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_data_segs_out = tp->data_segs_out; info->tcpi_delivery_rate_app_limited = tp->rate_app_limited ? 1 : 0; - rate = READ_ONCE(tp->rate_delivered); - intv = READ_ONCE(tp->rate_interval_us); - if (rate && intv) { - rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC; - do_div(rate64, intv); + rate64 = tcp_compute_delivery_rate(tp); + if (rate64) info->tcpi_delivery_rate = rate64; - } unlock_sock_fast(sk, slow); } EXPORT_SYMBOL_GPL(tcp_get_info); @@ -2938,8 +2949,12 @@ struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk) const struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *stats; struct tcp_info info; + u64 rate64; + u32 rate; - stats = alloc_skb(5 * nla_total_size_64bit(sizeof(u64)), GFP_ATOMIC); + stats = alloc_skb(7 * nla_total_size_64bit(sizeof(u64)) + + 3 * nla_total_size(sizeof(u32)) + + 2 * nla_total_size(sizeof(u8)), GFP_ATOMIC); if (!stats) return NULL; @@ -2954,6 +2969,20 @@ struct sk_buff *tcp_get_timestamping_opt_stats(const struct sock *sk) tp->data_segs_out, TCP_NLA_PAD); nla_put_u64_64bit(stats, TCP_NLA_TOTAL_RETRANS, tp->total_retrans, TCP_NLA_PAD); + + rate = READ_ONCE(sk->sk_pacing_rate); + rate64 = rate != ~0U ? rate : ~0ULL; + nla_put_u64_64bit(stats, TCP_NLA_PACING_RATE, rate64, TCP_NLA_PAD); + + rate64 = tcp_compute_delivery_rate(tp); + nla_put_u64_64bit(stats, TCP_NLA_DELIVERY_RATE, rate64, TCP_NLA_PAD); + + nla_put_u32(stats, TCP_NLA_SND_CWND, tp->snd_cwnd); + nla_put_u32(stats, TCP_NLA_REORDERING, tp->reordering); + nla_put_u32(stats, TCP_NLA_MIN_RTT, tcp_min_rtt(tp)); + + nla_put_u8(stats, TCP_NLA_RECUR_RETRANS, inet_csk(sk)->icsk_retransmits); + nla_put_u8(stats, TCP_NLA_DELIVERY_RATE_APP_LMT, !!tp->rate_app_limited); return stats; } diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c index 609965f0e29836ed95605a2c7f3170e67c641058..fc36143774130c8949ecb58dc066b2c5f6271081 100644 --- a/net/ipv4/tcp_bic.c +++ b/net/ipv4/tcp_bic.c @@ -49,7 +49,6 @@ MODULE_PARM_DESC(smooth_part, "log(B/(B*Smin))/log(B/(B-1))+B, # of RTT from Wma struct bictcp { u32 cnt; /* increase cwnd by 1 after ACKs */ u32 last_max_cwnd; /* last maximum snd_cwnd */ - u32 loss_cwnd; /* congestion window at last loss */ u32 last_cwnd; /* the last snd_cwnd */ u32 last_time; /* time when updated last_cwnd */ u32 epoch_start; /* beginning of an epoch */ @@ -72,7 +71,6 @@ static void bictcp_init(struct sock *sk) struct bictcp *ca = inet_csk_ca(sk); bictcp_reset(ca); - ca->loss_cwnd = 0; if (initial_ssthresh) tcp_sk(sk)->snd_ssthresh = initial_ssthresh; @@ -172,22 +170,12 @@ static u32 bictcp_recalc_ssthresh(struct sock *sk) else ca->last_max_cwnd = tp->snd_cwnd; - ca->loss_cwnd = tp->snd_cwnd; - if (tp->snd_cwnd <= low_window) return max(tp->snd_cwnd >> 1U, 2U); else return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U); } -static u32 bictcp_undo_cwnd(struct sock *sk) -{ - const struct tcp_sock *tp = tcp_sk(sk); - const struct bictcp *ca = inet_csk_ca(sk); - - return max(tp->snd_cwnd, ca->loss_cwnd); -} - static void bictcp_state(struct sock *sk, u8 new_state) { if (new_state == TCP_CA_Loss) @@ -214,7 +202,7 @@ static struct tcp_congestion_ops bictcp __read_mostly = { .ssthresh = bictcp_recalc_ssthresh, .cong_avoid = bictcp_cong_avoid, .set_state = bictcp_state, - .undo_cwnd = bictcp_undo_cwnd, + .undo_cwnd = tcp_reno_undo_cwnd, .pkts_acked = bictcp_acked, .owner = THIS_MODULE, .name = "bic", diff --git a/net/ipv4/tcp_cdg.c b/net/ipv4/tcp_cdg.c index 50a0f3e51d5ba3ec544674b667371d7dfb3dc1b4..66ac69f7bd1958908d6f641f2143aa0850171f04 100644 --- a/net/ipv4/tcp_cdg.c +++ b/net/ipv4/tcp_cdg.c @@ -85,7 +85,6 @@ struct cdg { u8 state; u8 delack; u32 rtt_seq; - u32 undo_cwnd; u32 shadow_wnd; u16 backoff_cnt; u16 sample_cnt; @@ -330,8 +329,6 @@ static u32 tcp_cdg_ssthresh(struct sock *sk) struct cdg *ca = inet_csk_ca(sk); struct tcp_sock *tp = tcp_sk(sk); - ca->undo_cwnd = tp->snd_cwnd; - if (ca->state == CDG_BACKOFF) return max(2U, (tp->snd_cwnd * min(1024U, backoff_beta)) >> 10); @@ -344,13 +341,6 @@ static u32 tcp_cdg_ssthresh(struct sock *sk) return max(2U, tp->snd_cwnd >> 1); } -static u32 tcp_cdg_undo_cwnd(struct sock *sk) -{ - struct cdg *ca = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, ca->undo_cwnd); -} - static void tcp_cdg_cwnd_event(struct sock *sk, const enum tcp_ca_event ev) { struct cdg *ca = inet_csk_ca(sk); @@ -403,7 +393,7 @@ struct tcp_congestion_ops tcp_cdg __read_mostly = { .cong_avoid = tcp_cdg_cong_avoid, .cwnd_event = tcp_cdg_cwnd_event, .pkts_acked = tcp_cdg_acked, - .undo_cwnd = tcp_cdg_undo_cwnd, + .undo_cwnd = tcp_reno_undo_cwnd, .ssthresh = tcp_cdg_ssthresh, .release = tcp_cdg_release, .init = tcp_cdg_init, diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index fde983f6376be98247b9f2ff3d0307c2502e6392..2f26124fd1601ad23662d1fc9152b4370270c112 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c @@ -189,8 +189,8 @@ void tcp_init_congestion_control(struct sock *sk) INET_ECN_dontxmit(sk); } -void tcp_reinit_congestion_control(struct sock *sk, - const struct tcp_congestion_ops *ca) +static void tcp_reinit_congestion_control(struct sock *sk, + const struct tcp_congestion_ops *ca) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -338,7 +338,7 @@ int tcp_set_allowed_congestion_control(char *val) * tcp_reinit_congestion_control (if the current congestion control was * already initialized. */ -int tcp_set_congestion_control(struct sock *sk, const char *name, bool load) +int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, bool reinit) { struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_congestion_ops *ca; @@ -360,9 +360,18 @@ int tcp_set_congestion_control(struct sock *sk, const char *name, bool load) if (!ca) { err = -ENOENT; } else if (!load) { - icsk->icsk_ca_ops = ca; - if (!try_module_get(ca->owner)) + const struct tcp_congestion_ops *old_ca = icsk->icsk_ca_ops; + + if (try_module_get(ca->owner)) { + if (reinit) { + tcp_reinit_congestion_control(sk, ca); + } else { + icsk->icsk_ca_ops = ca; + module_put(old_ca->owner); + } + } else { err = -EBUSY; + } } else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))) { err = -EPERM; @@ -456,7 +465,7 @@ u32 tcp_reno_undo_cwnd(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); - return max(tp->snd_cwnd, tp->snd_ssthresh << 1); + return max(tp->snd_cwnd, tp->prior_cwnd); } EXPORT_SYMBOL_GPL(tcp_reno_undo_cwnd); diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 57ae5b5ae643efad106f5d6ac224ca54a52f9689..78bfadfcf342695ed2e7f02626ddd1fda7d4d543 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c @@ -83,7 +83,6 @@ MODULE_PARM_DESC(hystart_ack_delta, "spacing between ack's indicating train (mse struct bictcp { u32 cnt; /* increase cwnd by 1 after ACKs */ u32 last_max_cwnd; /* last maximum snd_cwnd */ - u32 loss_cwnd; /* congestion window at last loss */ u32 last_cwnd; /* the last snd_cwnd */ u32 last_time; /* time when updated last_cwnd */ u32 bic_origin_point;/* origin point of bic function */ @@ -142,7 +141,6 @@ static void bictcp_init(struct sock *sk) struct bictcp *ca = inet_csk_ca(sk); bictcp_reset(ca); - ca->loss_cwnd = 0; if (hystart) bictcp_hystart_reset(sk); @@ -366,18 +364,9 @@ static u32 bictcp_recalc_ssthresh(struct sock *sk) else ca->last_max_cwnd = tp->snd_cwnd; - ca->loss_cwnd = tp->snd_cwnd; - return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U); } -static u32 bictcp_undo_cwnd(struct sock *sk) -{ - struct bictcp *ca = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); -} - static void bictcp_state(struct sock *sk, u8 new_state) { if (new_state == TCP_CA_Loss) { @@ -470,7 +459,7 @@ static struct tcp_congestion_ops cubictcp __read_mostly = { .ssthresh = bictcp_recalc_ssthresh, .cong_avoid = bictcp_cong_avoid, .set_state = bictcp_state, - .undo_cwnd = bictcp_undo_cwnd, + .undo_cwnd = tcp_reno_undo_cwnd, .cwnd_event = bictcp_cwnd_event, .pkts_acked = bictcp_acked, .owner = THIS_MODULE, diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index a748c74aa8b781626d7a7805eef0f50da8e11328..abbf0edcf6c26f3b39dffe46949875bebbdc7f51 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -16,6 +16,7 @@ #include +#include #include static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, @@ -36,6 +37,100 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, tcp_get_info(sk, info); } +#ifdef CONFIG_TCP_MD5SIG +static void tcp_diag_md5sig_fill(struct tcp_diag_md5sig *info, + const struct tcp_md5sig_key *key) +{ + info->tcpm_family = key->family; + info->tcpm_prefixlen = key->prefixlen; + info->tcpm_keylen = key->keylen; + memcpy(info->tcpm_key, key->key, key->keylen); + + if (key->family == AF_INET) + info->tcpm_addr[0] = key->addr.a4.s_addr; + #if IS_ENABLED(CONFIG_IPV6) + else if (key->family == AF_INET6) + memcpy(&info->tcpm_addr, &key->addr.a6, + sizeof(info->tcpm_addr)); + #endif +} + +static int tcp_diag_put_md5sig(struct sk_buff *skb, + const struct tcp_md5sig_info *md5sig) +{ + const struct tcp_md5sig_key *key; + struct tcp_diag_md5sig *info; + struct nlattr *attr; + int md5sig_count = 0; + + hlist_for_each_entry_rcu(key, &md5sig->head, node) + md5sig_count++; + if (md5sig_count == 0) + return 0; + + attr = nla_reserve(skb, INET_DIAG_MD5SIG, + md5sig_count * sizeof(struct tcp_diag_md5sig)); + if (!attr) + return -EMSGSIZE; + + info = nla_data(attr); + memset(info, 0, md5sig_count * sizeof(struct tcp_diag_md5sig)); + hlist_for_each_entry_rcu(key, &md5sig->head, node) { + tcp_diag_md5sig_fill(info++, key); + if (--md5sig_count == 0) + break; + } + + return 0; +} +#endif + +static int tcp_diag_get_aux(struct sock *sk, bool net_admin, + struct sk_buff *skb) +{ +#ifdef CONFIG_TCP_MD5SIG + if (net_admin) { + struct tcp_md5sig_info *md5sig; + int err = 0; + + rcu_read_lock(); + md5sig = rcu_dereference(tcp_sk(sk)->md5sig_info); + if (md5sig) + err = tcp_diag_put_md5sig(skb, md5sig); + rcu_read_unlock(); + if (err < 0) + return err; + } +#endif + + return 0; +} + +static size_t tcp_diag_get_aux_size(struct sock *sk, bool net_admin) +{ + size_t size = 0; + +#ifdef CONFIG_TCP_MD5SIG + if (net_admin && sk_fullsock(sk)) { + const struct tcp_md5sig_info *md5sig; + const struct tcp_md5sig_key *key; + size_t md5sig_count = 0; + + rcu_read_lock(); + md5sig = rcu_dereference(tcp_sk(sk)->md5sig_info); + if (md5sig) { + hlist_for_each_entry_rcu(key, &md5sig->head, node) + md5sig_count++; + } + rcu_read_unlock(); + size += nla_total_size(md5sig_count * + sizeof(struct tcp_diag_md5sig)); + } +#endif + + return size; +} + static void tcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, const struct inet_diag_req_v2 *r, struct nlattr *bc) { @@ -68,13 +163,15 @@ static int tcp_diag_destroy(struct sk_buff *in_skb, #endif static const struct inet_diag_handler tcp_diag_handler = { - .dump = tcp_diag_dump, - .dump_one = tcp_diag_dump_one, - .idiag_get_info = tcp_diag_get_info, - .idiag_type = IPPROTO_TCP, - .idiag_info_size = sizeof(struct tcp_info), + .dump = tcp_diag_dump, + .dump_one = tcp_diag_dump_one, + .idiag_get_info = tcp_diag_get_info, + .idiag_get_aux = tcp_diag_get_aux, + .idiag_get_aux_size = tcp_diag_get_aux_size, + .idiag_type = IPPROTO_TCP, + .idiag_info_size = sizeof(struct tcp_info), #ifdef CONFIG_INET_DIAG_DESTROY - .destroy = tcp_diag_destroy, + .destroy = tcp_diag_destroy, #endif }; diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index ce9c7fef200f3a493de69e87464e7a1e0ba9d889..e3c33220c41810c87d1d6eebdd5de0b71930aed0 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -171,7 +171,6 @@ void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb) static struct sock *tcp_fastopen_create_child(struct sock *sk, struct sk_buff *skb, - struct dst_entry *dst, struct request_sock *req) { struct tcp_sock *tp; @@ -278,8 +277,7 @@ static bool tcp_fastopen_queue_check(struct sock *sk) */ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, struct request_sock *req, - struct tcp_fastopen_cookie *foc, - struct dst_entry *dst) + struct tcp_fastopen_cookie *foc) { struct tcp_fastopen_cookie valid_foc = { .len = -1 }; bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1; @@ -312,7 +310,7 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, * data in SYN_RECV state. */ fastopen: - child = tcp_fastopen_create_child(sk, skb, dst, req); + child = tcp_fastopen_create_child(sk, skb, req); if (child) { foc->len = -1; NET_INC_STATS(sock_net(sk), diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c index 6d9879e93648a0c60579586242643ba364f4e506..d1c33c91eadc34f187f59f583f21b41f243ab171 100644 --- a/net/ipv4/tcp_highspeed.c +++ b/net/ipv4/tcp_highspeed.c @@ -94,7 +94,6 @@ static const struct hstcp_aimd_val { struct hstcp { u32 ai; - u32 loss_cwnd; }; static void hstcp_init(struct sock *sk) @@ -153,22 +152,14 @@ static u32 hstcp_ssthresh(struct sock *sk) const struct tcp_sock *tp = tcp_sk(sk); struct hstcp *ca = inet_csk_ca(sk); - ca->loss_cwnd = tp->snd_cwnd; /* Do multiplicative decrease */ return max(tp->snd_cwnd - ((tp->snd_cwnd * hstcp_aimd_vals[ca->ai].md) >> 8), 2U); } -static u32 hstcp_cwnd_undo(struct sock *sk) -{ - const struct hstcp *ca = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); -} - static struct tcp_congestion_ops tcp_highspeed __read_mostly = { .init = hstcp_init, .ssthresh = hstcp_ssthresh, - .undo_cwnd = hstcp_cwnd_undo, + .undo_cwnd = tcp_reno_undo_cwnd, .cong_avoid = hstcp_cong_avoid, .owner = THIS_MODULE, diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 3eb78cde6ff0a22b7b411f0ae4258b6ef74ffe73..082d479462fa953784de52fe2d5361f943756f7e 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c @@ -66,7 +66,6 @@ static inline void htcp_reset(struct htcp *ca) static u32 htcp_cwnd_undo(struct sock *sk) { - const struct tcp_sock *tp = tcp_sk(sk); struct htcp *ca = inet_csk_ca(sk); if (ca->undo_last_cong) { @@ -76,7 +75,7 @@ static u32 htcp_cwnd_undo(struct sock *sk) ca->undo_last_cong = 0; } - return max(tp->snd_cwnd, (tp->snd_ssthresh << 7) / ca->beta); + return tcp_reno_undo_cwnd(sk); } static inline void measure_rtt(struct sock *sk, u32 srtt) diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 60352ff4f5a85f065793a5fb21c0d69713a0453a..7c843578f2333db58100cedbc2a9d0784f72d861 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c @@ -48,7 +48,6 @@ struct illinois { u32 end_seq; /* right edge of current RTT */ u32 alpha; /* Additive increase */ u32 beta; /* Muliplicative decrease */ - u32 loss_cwnd; /* cwnd on loss */ u16 acked; /* # packets acked by current ACK */ u8 rtt_above; /* average rtt has gone above threshold */ u8 rtt_low; /* # of rtts measurements below threshold */ @@ -297,18 +296,10 @@ static u32 tcp_illinois_ssthresh(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct illinois *ca = inet_csk_ca(sk); - ca->loss_cwnd = tp->snd_cwnd; /* Multiplicative decrease */ return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->beta) >> BETA_SHIFT), 2U); } -static u32 tcp_illinois_cwnd_undo(struct sock *sk) -{ - const struct illinois *ca = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); -} - /* Extract info for Tcp socket info provided via netlink. */ static size_t tcp_illinois_info(struct sock *sk, u32 ext, int *attr, union tcp_cc_info *info) @@ -336,7 +327,7 @@ static size_t tcp_illinois_info(struct sock *sk, u32 ext, int *attr, static struct tcp_congestion_ops tcp_illinois __read_mostly = { .init = tcp_illinois_init, .ssthresh = tcp_illinois_ssthresh, - .undo_cwnd = tcp_illinois_cwnd_undo, + .undo_cwnd = tcp_reno_undo_cwnd, .cong_avoid = tcp_illinois_cong_avoid, .set_state = tcp_illinois_state, .get_info = tcp_illinois_info, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2920e0cb09f8d3e743eb4f49c16060ba1af48ed4..c5d7656beeee29b3c92e1c8824dbf00d3fa32d28 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -107,6 +107,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2; #define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ +#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ #define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ #define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ @@ -1951,6 +1952,7 @@ void tcp_enter_loss(struct sock *sk) !after(tp->high_seq, tp->snd_una) || (icsk->icsk_ca_state == TCP_CA_Loss && !icsk->icsk_retransmits)) { tp->prior_ssthresh = tcp_current_ssthresh(sk); + tp->prior_cwnd = tp->snd_cwnd; tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk); tcp_ca_event(sk, CA_EVENT_LOSS); tcp_init_undo(tp); @@ -2520,8 +2522,8 @@ static inline void tcp_end_cwnd_reduction(struct sock *sk) return; /* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */ - if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || - (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) { + if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH && + (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || tp->undo_marker)) { tp->snd_cwnd = tp->snd_ssthresh; tp->snd_cwnd_stamp = tcp_jiffies32; } @@ -3004,21 +3006,24 @@ void tcp_rearm_rto(struct sock *sk) /* Offset the time elapsed after installing regular RTO */ if (icsk->icsk_pending == ICSK_TIME_REO_TIMEOUT || icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) { - struct sk_buff *skb = tcp_write_queue_head(sk); - u64 rto_time_stamp = skb->skb_mstamp + - jiffies_to_usecs(rto); - s64 delta_us = rto_time_stamp - tp->tcp_mstamp; + s64 delta_us = tcp_rto_delta_us(sk); /* delta_us may not be positive if the socket is locked * when the retrans timer fires and is rescheduled. */ - if (delta_us > 0) - rto = usecs_to_jiffies(delta_us); + rto = usecs_to_jiffies(max_t(int, delta_us, 1)); } inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto, TCP_RTO_MAX); } } +/* Try to schedule a loss probe; if that doesn't work, then schedule an RTO. */ +static void tcp_set_xmit_timer(struct sock *sk) +{ + if (!tcp_schedule_loss_probe(sk)) + tcp_rearm_rto(sk); +} + /* If we get here, the whole TSO packet has not been acked. */ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) { @@ -3180,7 +3185,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, ca_rtt_us, sack->rate); if (flag & FLAG_ACKED) { - tcp_rearm_rto(sk); + flag |= FLAG_SET_XMIT_TIMER; /* set TLP or RTO timer */ if (unlikely(icsk->icsk_mtup.probe_size && !after(tp->mtu_probe.probe_seq_end, tp->snd_una))) { tcp_mtup_probe_success(sk); @@ -3208,7 +3213,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, * after when the head was last (re)transmitted. Otherwise the * timeout may continue to extend in loss recovery. */ - tcp_rearm_rto(sk); + flag |= FLAG_SET_XMIT_TIMER; /* set TLP or RTO timer */ } if (icsk->icsk_ca_ops->pkts_acked) { @@ -3580,9 +3585,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) if (after(ack, tp->snd_nxt)) goto invalid_ack; - if (icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) - tcp_rearm_rto(sk); - if (after(ack, prior_snd_una)) { flag |= FLAG_SND_UNA_ADVANCED; icsk->icsk_retransmits = 0; @@ -3647,18 +3649,20 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked, &sack_state); + if (tp->tlp_high_seq) + tcp_process_tlp_ack(sk, ack, flag); + /* If needed, reset TLP/RTO timer; RACK may later override this. */ + if (flag & FLAG_SET_XMIT_TIMER) + tcp_set_xmit_timer(sk); + if (tcp_ack_is_dubious(sk, flag)) { is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit); } - if (tp->tlp_high_seq) - tcp_process_tlp_ack(sk, ack, flag); if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP)) sk_dst_confirm(sk); - if (icsk->icsk_pending == ICSK_TIME_RETRANS) - tcp_schedule_loss_probe(sk); delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ lost = tp->lost - lost; /* freshly marked lost */ tcp_rate_gen(sk, delivered, lost, sack_state.rate); @@ -4264,9 +4268,15 @@ static void tcp_sack_remove(struct tcp_sock *tp) tp->rx_opt.num_sacks = num_sacks; } +enum tcp_queue { + OOO_QUEUE, + RCV_QUEUE, +}; + /** * tcp_try_coalesce - try to merge skb to prior one * @sk: socket + * @dest: destination queue * @to: prior buffer * @from: buffer to add in queue * @fragstolen: pointer to boolean @@ -4278,6 +4288,7 @@ static void tcp_sack_remove(struct tcp_sock *tp) * Returns true if caller should free @from instead of queueing it */ static bool tcp_try_coalesce(struct sock *sk, + enum tcp_queue dest, struct sk_buff *to, struct sk_buff *from, bool *fragstolen) @@ -4299,6 +4310,15 @@ static bool tcp_try_coalesce(struct sock *sk, TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq; TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq; TCP_SKB_CB(to)->tcp_flags |= TCP_SKB_CB(from)->tcp_flags; + + if (TCP_SKB_CB(from)->has_rxtstamp) { + TCP_SKB_CB(to)->has_rxtstamp = true; + if (dest == OOO_QUEUE) + TCP_SKB_CB(to)->swtstamp = TCP_SKB_CB(from)->swtstamp; + else + to->tstamp = from->tstamp; + } + return true; } @@ -4333,6 +4353,9 @@ static void tcp_ofo_queue(struct sock *sk) } p = rb_next(p); rb_erase(&skb->rbnode, &tp->out_of_order_queue); + /* Replace tstamp which was stomped by rbnode */ + if (TCP_SKB_CB(skb)->has_rxtstamp) + skb->tstamp = TCP_SKB_CB(skb)->swtstamp; if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { SOCK_DEBUG(sk, "ofo packet was already received\n"); @@ -4344,7 +4367,8 @@ static void tcp_ofo_queue(struct sock *sk) TCP_SKB_CB(skb)->end_seq); tail = skb_peek_tail(&sk->sk_receive_queue); - eaten = tail && tcp_try_coalesce(sk, tail, skb, &fragstolen); + eaten = tail && tcp_try_coalesce(sk, RCV_QUEUE, + tail, skb, &fragstolen); tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN; if (!eaten) @@ -4398,6 +4422,10 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) return; } + /* Stash tstamp to avoid being stomped on by rbnode */ + if (TCP_SKB_CB(skb)->has_rxtstamp) + TCP_SKB_CB(skb)->swtstamp = skb->tstamp; + /* Disable header prediction. */ tp->pred_flags = 0; inet_csk_schedule_ack(sk); @@ -4425,7 +4453,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) /* In the typical case, we are adding an skb to the end of the list. * Use of ooo_last_skb avoids the O(Log(N)) rbtree lookup. */ - if (tcp_try_coalesce(sk, tp->ooo_last_skb, skb, &fragstolen)) { + if (tcp_try_coalesce(sk, OOO_QUEUE, tp->ooo_last_skb, + skb, &fragstolen)) { coalesce_done: tcp_grow_window(sk, skb); kfree_skb_partial(skb, fragstolen); @@ -4475,7 +4504,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) __kfree_skb(skb1); goto merge_right; } - } else if (tcp_try_coalesce(sk, skb1, skb, &fragstolen)) { + } else if (tcp_try_coalesce(sk, OOO_QUEUE, skb1, + skb, &fragstolen)) { goto coalesce_done; } p = &parent->rb_right; @@ -4526,7 +4556,8 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int __skb_pull(skb, hdrlen); eaten = (tail && - tcp_try_coalesce(sk, tail, skb, fragstolen)) ? 1 : 0; + tcp_try_coalesce(sk, RCV_QUEUE, tail, + skb, fragstolen)) ? 1 : 0; tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq); if (!eaten) { __skb_queue_tail(&sk->sk_receive_queue, skb); @@ -4588,8 +4619,8 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); - bool fragstolen = false; - int eaten = -1; + bool fragstolen; + int eaten; if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { __kfree_skb(skb); @@ -4611,32 +4642,13 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) goto out_of_window; /* Ok. In sequence. In window. */ - if (tp->ucopy.task == current && - tp->copied_seq == tp->rcv_nxt && tp->ucopy.len && - sock_owned_by_user(sk) && !tp->urg_data) { - int chunk = min_t(unsigned int, skb->len, - tp->ucopy.len); - - __set_current_state(TASK_RUNNING); - - if (!skb_copy_datagram_msg(skb, 0, tp->ucopy.msg, chunk)) { - tp->ucopy.len -= chunk; - tp->copied_seq += chunk; - eaten = (chunk == skb->len); - tcp_rcv_space_adjust(sk); - } - } - - if (eaten <= 0) { queue_and_out: - if (eaten < 0) { - if (skb_queue_len(&sk->sk_receive_queue) == 0) - sk_forced_mem_schedule(sk, skb->truesize); - else if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) - goto drop; - } - eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); - } + if (skb_queue_len(&sk->sk_receive_queue) == 0) + sk_forced_mem_schedule(sk, skb->truesize); + else if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) + goto drop; + + eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); if (skb->len) tcp_event_data_recv(sk, skb); @@ -5186,26 +5198,6 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, const struct tcphdr *t } } -static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) -{ - struct tcp_sock *tp = tcp_sk(sk); - int chunk = skb->len - hlen; - int err; - - if (skb_csum_unnecessary(skb)) - err = skb_copy_datagram_msg(skb, hlen, tp->ucopy.msg, chunk); - else - err = skb_copy_and_csum_datagram_msg(skb, hlen, tp->ucopy.msg); - - if (!err) { - tp->ucopy.len -= chunk; - tp->copied_seq += chunk; - tcp_rcv_space_adjust(sk); - } - - return err; -} - /* Accept RST for rcv_nxt - 1 after a FIN. * When tcp connections are abruptly terminated from Mac OSX (via ^C), a * FIN is sent followed by a RST packet. The RST is sent with the same @@ -5358,8 +5350,9 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, * tcp_data_queue when everything is OK. */ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, - const struct tcphdr *th, unsigned int len) + const struct tcphdr *th) { + unsigned int len = skb->len; struct tcp_sock *tp = tcp_sk(sk); tcp_mstamp_refresh(tp); @@ -5445,56 +5438,28 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, int eaten = 0; bool fragstolen = false; - if (tp->ucopy.task == current && - tp->copied_seq == tp->rcv_nxt && - len - tcp_header_len <= tp->ucopy.len && - sock_owned_by_user(sk)) { - __set_current_state(TASK_RUNNING); - - if (!tcp_copy_to_iovec(sk, skb, tcp_header_len)) { - /* Predicted packet is in window by definition. - * seq == rcv_nxt and rcv_wup <= rcv_nxt. - * Hence, check seq<=rcv_wup reduces to: - */ - if (tcp_header_len == - (sizeof(struct tcphdr) + - TCPOLEN_TSTAMP_ALIGNED) && - tp->rcv_nxt == tp->rcv_wup) - tcp_store_ts_recent(tp); - - tcp_rcv_rtt_measure_ts(sk, skb); - - __skb_pull(skb, tcp_header_len); - tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); - NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPHPHITSTOUSER); - eaten = 1; - } - } - if (!eaten) { - if (tcp_checksum_complete(skb)) - goto csum_error; + if (tcp_checksum_complete(skb)) + goto csum_error; - if ((int)skb->truesize > sk->sk_forward_alloc) - goto step5; + if ((int)skb->truesize > sk->sk_forward_alloc) + goto step5; - /* Predicted packet is in window by definition. - * seq == rcv_nxt and rcv_wup <= rcv_nxt. - * Hence, check seq<=rcv_wup reduces to: - */ - if (tcp_header_len == - (sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) && - tp->rcv_nxt == tp->rcv_wup) - tcp_store_ts_recent(tp); + /* Predicted packet is in window by definition. + * seq == rcv_nxt and rcv_wup <= rcv_nxt. + * Hence, check seq<=rcv_wup reduces to: + */ + if (tcp_header_len == + (sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) && + tp->rcv_nxt == tp->rcv_wup) + tcp_store_ts_recent(tp); - tcp_rcv_rtt_measure_ts(sk, skb); + tcp_rcv_rtt_measure_ts(sk, skb); - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPHPHITS); + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPHPHITS); - /* Bulk data transfer: receiver */ - eaten = tcp_queue_rcv(sk, skb, tcp_header_len, - &fragstolen); - } + /* Bulk data transfer: receiver */ + eaten = tcp_queue_rcv(sk, skb, tcp_header_len, + &fragstolen); tcp_event_data_recv(sk, skb); @@ -5588,7 +5553,6 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) __tcp_fast_path_on(tp, tp->snd_wnd); else tp->pred_flags = 0; - } static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, @@ -6303,9 +6267,9 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, struct tcp_sock *tp = tcp_sk(sk); struct net *net = sock_net(sk); struct sock *fastopen_sk = NULL; - struct dst_entry *dst = NULL; struct request_sock *req; bool want_cookie = false; + struct dst_entry *dst; struct flowi fl; /* TW buckets are converted to open requests without @@ -6355,6 +6319,10 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, if (tmp_opt.tstamp_ok) tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb); + dst = af_ops->route_req(sk, &fl, req); + if (!dst) + goto drop_and_free; + if (!want_cookie && !isn) { /* Kill the following clause, if you dislike this way. */ if (!net->ipv4.sysctl_tcp_syncookies && @@ -6375,11 +6343,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, isn = af_ops->init_seq(skb); } - if (!dst) { - dst = af_ops->route_req(sk, &fl, req); - if (!dst) - goto drop_and_free; - } tcp_ecn_create_request(req, skb, sk, dst); @@ -6395,7 +6358,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, tcp_openreq_init_rwin(req, sk, dst); if (!want_cookie) { tcp_reqsk_record_syn(sk, req, skb); - fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); + fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc); } if (fastopen_sk) { af_ops->send_synack(fastopen_sk, dst, &fl, req, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a20e7f03d5f7d81ccf7e92de9bfbbcc3e2df6718..85164d4d3e537537c87d74c00172592c860d4dfb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -85,8 +85,6 @@ #include #include -int sysctl_tcp_low_latency __read_mostly; - #ifdef CONFIG_TCP_MD5SIG static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key, __be32 daddr, __be32 saddr, const struct tcphdr *th); @@ -385,7 +383,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) sk = __inet_lookup_established(net, &tcp_hashinfo, iph->daddr, th->dest, iph->saddr, ntohs(th->source), - inet_iif(icmp_skb)); + inet_iif(icmp_skb), 0); if (!sk) { __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); return; @@ -661,7 +659,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) sk1 = __inet_lookup_listener(net, &tcp_hashinfo, NULL, 0, ip_hdr(skb)->saddr, th->source, ip_hdr(skb)->daddr, - ntohs(th->source), inet_iif(skb)); + ntohs(th->source), inet_iif(skb), + tcp_v4_sdif(skb)); /* don't send rst if it can't find key */ if (!sk1) goto out; @@ -1269,7 +1268,7 @@ static void tcp_v4_init_req(struct request_sock *req, sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - ireq->opt = tcp_v4_save_options(skb); + ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); } static struct dst_entry *tcp_v4_route_req(const struct sock *sk, @@ -1458,7 +1457,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) sk->sk_rx_dst = NULL; } } - tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len); + tcp_rcv_established(sk, skb, tcp_hdr(skb)); return 0; } @@ -1504,28 +1503,28 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) } EXPORT_SYMBOL(tcp_v4_do_rcv); -void tcp_v4_early_demux(struct sk_buff *skb) +int tcp_v4_early_demux(struct sk_buff *skb) { const struct iphdr *iph; const struct tcphdr *th; struct sock *sk; if (skb->pkt_type != PACKET_HOST) - return; + return 0; if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr))) - return; + return 0; iph = ip_hdr(skb); th = tcp_hdr(skb); if (th->doff < sizeof(struct tcphdr) / 4) - return; + return 0; sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo, iph->saddr, th->source, iph->daddr, ntohs(th->dest), - skb->skb_iif); + skb->skb_iif, inet_sdif(skb)); if (sk) { skb->sk = sk; skb->destructor = sock_edemux; @@ -1539,63 +1538,9 @@ void tcp_v4_early_demux(struct sk_buff *skb) skb_dst_set_noref(skb, dst); } } + return 0; } -/* Packet is added to VJ-style prequeue for processing in process - * context, if a reader task is waiting. Apparently, this exciting - * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) - * failed somewhere. Latency? Burstiness? Well, at least now we will - * see, why it failed. 8)8) --ANK - * - */ -bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (sysctl_tcp_low_latency || !tp->ucopy.task) - return false; - - if (skb->len <= tcp_hdrlen(skb) && - skb_queue_len(&tp->ucopy.prequeue) == 0) - return false; - - /* Before escaping RCU protected region, we need to take care of skb - * dst. Prequeue is only enabled for established sockets. - * For such sockets, we might need the skb dst only to set sk->sk_rx_dst - * Instead of doing full sk_rx_dst validity here, let's perform - * an optimistic check. - */ - if (likely(sk->sk_rx_dst)) - skb_dst_drop(skb); - else - skb_dst_force_safe(skb); - - __skb_queue_tail(&tp->ucopy.prequeue, skb); - tp->ucopy.memory += skb->truesize; - if (skb_queue_len(&tp->ucopy.prequeue) >= 32 || - tp->ucopy.memory + atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { - struct sk_buff *skb1; - - BUG_ON(sock_owned_by_user(sk)); - __NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPPREQUEUEDROPPED, - skb_queue_len(&tp->ucopy.prequeue)); - - while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) - sk_backlog_rcv(sk, skb1); - - tp->ucopy.memory = 0; - } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { - wake_up_interruptible_sync_poll(sk_sleep(sk), - POLLIN | POLLRDNORM | POLLRDBAND); - if (!inet_csk_ack_scheduled(sk)) - inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, - (3 * tcp_rto_min(sk)) / 4, - TCP_RTO_MAX); - } - return true; -} -EXPORT_SYMBOL(tcp_prequeue); - bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) { u32 limit = sk->sk_rcvbuf + sk->sk_sndbuf; @@ -1645,6 +1590,7 @@ EXPORT_SYMBOL(tcp_filter); int tcp_v4_rcv(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); + int sdif = inet_sdif(skb); const struct iphdr *iph; const struct tcphdr *th; bool refcounted; @@ -1692,10 +1638,12 @@ int tcp_v4_rcv(struct sk_buff *skb) TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); TCP_SKB_CB(skb)->sacked = 0; + TCP_SKB_CB(skb)->has_rxtstamp = + skb->tstamp || skb_hwtstamps(skb)->hwtstamp; lookup: sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source, - th->dest, &refcounted); + th->dest, sdif, &refcounted); if (!sk) goto no_tcp_socket; @@ -1722,15 +1670,15 @@ int tcp_v4_rcv(struct sk_buff *skb) */ sock_hold(sk); refcounted = true; - nsk = tcp_check_req(sk, skb, req, false); + nsk = NULL; + if (!tcp_filter(sk, skb)) + nsk = tcp_check_req(sk, skb, req, false); if (!nsk) { reqsk_put(req); goto discard_and_relse; } if (nsk == sk) { reqsk_put(req); - } else if (tcp_filter(sk, skb)) { - goto discard_and_relse; } else if (tcp_child_process(sk, nsk, skb)) { tcp_v4_send_reset(nsk, skb); goto discard_and_relse; @@ -1770,8 +1718,7 @@ int tcp_v4_rcv(struct sk_buff *skb) tcp_segs_in(tcp_sk(sk), skb); ret = 0; if (!sock_owned_by_user(sk)) { - if (!tcp_prequeue(sk, skb)) - ret = tcp_v4_do_rcv(sk, skb); + ret = tcp_v4_do_rcv(sk, skb); } else if (tcp_add_backlog(sk, skb)) { goto discard_and_relse; } @@ -1824,7 +1771,8 @@ int tcp_v4_rcv(struct sk_buff *skb) __tcp_hdrlen(th), iph->saddr, th->source, iph->daddr, th->dest, - inet_iif(skb)); + inet_iif(skb), + sdif); if (sk2) { inet_twsk_deschedule_put(inet_twsk(sk)); sk = sk2; @@ -1936,9 +1884,6 @@ void tcp_v4_destroy_sock(struct sock *sk) } #endif - /* Clean prequeue, it must be empty really */ - __skb_queue_purge(&tp->ucopy.prequeue); - /* Clean up a referenced TCP bind bucket. */ if (inet_csk(sk)->icsk_bind_hash) inet_put_port(sk); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 0ff83c1637d894b7e653bcbc7be35099d036ea07..188a6f31356db0d0b7825aa476888467f7c0dfd8 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -445,7 +445,6 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, newtp->snd_sml = newtp->snd_una = newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1; - tcp_prequeue_init(newtp); INIT_LIST_HEAD(&newtp->tsq_node); tcp_init_wl(newtp, treq->rcv_isn); diff --git a/net/ipv4/tcp_nv.c b/net/ipv4/tcp_nv.c index 6d650ed3cb598c0027b1c25e75f115b01402da31..1ff73982e28c58ecd0faa787e5ee30793e30dea8 100644 --- a/net/ipv4/tcp_nv.c +++ b/net/ipv4/tcp_nv.c @@ -86,7 +86,6 @@ struct tcpnv { * < 0 => less than 1 packet/RTT */ u8 available8; u16 available16; - u32 loss_cwnd; /* cwnd at last loss */ u8 nv_allow_cwnd_growth:1, /* whether cwnd can grow */ nv_reset:1, /* whether to reset values */ nv_catchup:1; /* whether we are growing because @@ -121,7 +120,6 @@ static inline void tcpnv_reset(struct tcpnv *ca, struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); ca->nv_reset = 0; - ca->loss_cwnd = 0; ca->nv_no_cong_cnt = 0; ca->nv_rtt_cnt = 0; ca->nv_last_rtt = 0; @@ -177,19 +175,10 @@ static void tcpnv_cong_avoid(struct sock *sk, u32 ack, u32 acked) static u32 tcpnv_recalc_ssthresh(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); - struct tcpnv *ca = inet_csk_ca(sk); - ca->loss_cwnd = tp->snd_cwnd; return max((tp->snd_cwnd * nv_loss_dec_factor) >> 10, 2U); } -static u32 tcpnv_undo_cwnd(struct sock *sk) -{ - struct tcpnv *ca = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); -} - static void tcpnv_state(struct sock *sk, u8 new_state) { struct tcpnv *ca = inet_csk_ca(sk); @@ -446,7 +435,7 @@ static struct tcp_congestion_ops tcpnv __read_mostly = { .ssthresh = tcpnv_recalc_ssthresh, .cong_avoid = tcpnv_cong_avoid, .set_state = tcpnv_state, - .undo_cwnd = tcpnv_undo_cwnd, + .undo_cwnd = tcp_reno_undo_cwnd, .pkts_acked = tcpnv_acked, .get_info = tcpnv_get_info, diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 4e985dea1dd24fdecfbf9b47d51cff698e97cd2f..0bc9e46a53696578eb6e911f2f75e6b34c80894f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -991,6 +991,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, struct tcp_skb_cb *tcb; struct tcp_out_options opts; unsigned int tcp_options_size, tcp_header_size; + struct sk_buff *oskb = NULL; struct tcp_md5sig_key *md5; struct tcphdr *th; int err; @@ -998,12 +999,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, BUG_ON(!skb || !tcp_skb_pcount(skb)); tp = tcp_sk(sk); - skb->skb_mstamp = tp->tcp_mstamp; if (clone_it) { TCP_SKB_CB(skb)->tx.in_flight = TCP_SKB_CB(skb)->end_seq - tp->snd_una; - tcp_rate_skb_sent(sk, skb); - + oskb = skb; if (unlikely(skb_cloned(skb))) skb = pskb_copy(skb, gfp_mask); else @@ -1011,6 +1010,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, if (unlikely(!skb)) return -ENOBUFS; } + skb->skb_mstamp = tp->tcp_mstamp; inet = inet_sk(sk); tcb = TCP_SKB_CB(skb); @@ -1122,12 +1122,15 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl); - if (likely(err <= 0)) - return err; - - tcp_enter_cwr(sk); - - return net_xmit_eval(err); + if (unlikely(err > 0)) { + tcp_enter_cwr(sk); + err = net_xmit_eval(err); + } + if (!err && oskb) { + oskb->skb_mstamp = tp->tcp_mstamp; + tcp_rate_skb_sent(sk, oskb); + } + return err; } /* This routine just queues the buffer for sending. @@ -1803,40 +1806,6 @@ static bool tcp_snd_wnd_test(const struct tcp_sock *tp, return !after(end_seq, tcp_wnd_end(tp)); } -/* This checks if the data bearing packet SKB (usually tcp_send_head(sk)) - * should be put on the wire right now. If so, it returns the number of - * packets allowed by the congestion window. - */ -static unsigned int tcp_snd_test(const struct sock *sk, struct sk_buff *skb, - unsigned int cur_mss, int nonagle) -{ - const struct tcp_sock *tp = tcp_sk(sk); - unsigned int cwnd_quota; - - tcp_init_tso_segs(skb, cur_mss); - - if (!tcp_nagle_test(tp, skb, cur_mss, nonagle)) - return 0; - - cwnd_quota = tcp_cwnd_test(tp, skb); - if (cwnd_quota && !tcp_snd_wnd_test(tp, skb, cur_mss)) - cwnd_quota = 0; - - return cwnd_quota; -} - -/* Test if sending is allowed right now. */ -bool tcp_may_send_now(struct sock *sk) -{ - const struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb = tcp_send_head(sk); - - return skb && - tcp_snd_test(sk, skb, tcp_current_mss(sk), - (tcp_skb_is_last(sk, skb) ? - tp->nonagle : TCP_NAGLE_PUSH)); -} - /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet * which is put after SKB on the list. It is very much like * tcp_fragment() except that it may make several kinds of assumptions @@ -2202,9 +2171,10 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb, static void tcp_chrono_set(struct tcp_sock *tp, const enum tcp_chrono new) { const u32 now = tcp_jiffies32; + enum tcp_chrono old = tp->chrono_type; - if (tp->chrono_type > TCP_CHRONO_UNSPEC) - tp->chrono_stat[tp->chrono_type - 1] += now - tp->chrono_start; + if (old > TCP_CHRONO_UNSPEC) + tp->chrono_stat[old - 1] += now - tp->chrono_start; tp->chrono_start = now; tp->chrono_type = new; } @@ -2376,24 +2346,14 @@ bool tcp_schedule_loss_probe(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); - u32 timeout, tlp_time_stamp, rto_time_stamp; - u32 rtt = usecs_to_jiffies(tp->srtt_us >> 3); + u32 timeout, rto_delta_us; - /* No consecutive loss probes. */ - if (WARN_ON(icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)) { - tcp_rearm_rto(sk); - return false; - } /* Don't do any loss probe on a Fast Open connection before 3WHS * finishes. */ if (tp->fastopen_rsk) return false; - /* TLP is only scheduled when next timer event is RTO. */ - if (icsk->icsk_pending != ICSK_TIME_RETRANS) - return false; - /* Schedule a loss probe in 2*RTT for SACK capable connections * in Open state, that are either limited by cwnd or application. */ @@ -2406,25 +2366,25 @@ bool tcp_schedule_loss_probe(struct sock *sk) tcp_send_head(sk)) return false; - /* Probe timeout is at least 1.5*rtt + TCP_DELACK_MAX to account + /* Probe timeout is 2*rtt. Add minimum RTO to account * for delayed ack when there's one outstanding packet. If no RTT * sample is available then probe after TCP_TIMEOUT_INIT. */ - timeout = rtt << 1 ? : TCP_TIMEOUT_INIT; - if (tp->packets_out == 1) - timeout = max_t(u32, timeout, - (rtt + (rtt >> 1) + TCP_DELACK_MAX)); - timeout = max_t(u32, timeout, msecs_to_jiffies(10)); - - /* If RTO is shorter, just schedule TLP in its place. */ - tlp_time_stamp = tcp_jiffies32 + timeout; - rto_time_stamp = (u32)inet_csk(sk)->icsk_timeout; - if ((s32)(tlp_time_stamp - rto_time_stamp) > 0) { - s32 delta = rto_time_stamp - tcp_jiffies32; - if (delta > 0) - timeout = delta; + if (tp->srtt_us) { + timeout = usecs_to_jiffies(tp->srtt_us >> 2); + if (tp->packets_out == 1) + timeout += TCP_RTO_MIN; + else + timeout += TCP_TIMEOUT_MIN; + } else { + timeout = TCP_TIMEOUT_INIT; } + /* If the RTO formula yields an earlier time, then use that time. */ + rto_delta_us = tcp_rto_delta_us(sk); /* How far in future is RTO? */ + if (rto_delta_us > 0) + timeout = min_t(u32, timeout, usecs_to_jiffies(rto_delta_us)); + inet_csk_reset_xmit_timer(sk, ICSK_TIME_LOSS_PROBE, timeout, TCP_RTO_MAX); return true; @@ -2878,10 +2838,11 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) skb_headroom(skb) >= 0xFFFF)) { struct sk_buff *nskb; - skb->skb_mstamp = tp->tcp_mstamp; nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC); err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : -ENOBUFS; + if (!err) + skb->skb_mstamp = tp->tcp_mstamp; } else { err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); } @@ -3428,6 +3389,10 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) goto done; } + /* data was not sent, this is our new send_head */ + sk->sk_send_head = syn_data; + tp->packets_out -= tcp_skb_pcount(syn_data); + fallback: /* Send a regular SYN with Fast Open cookie request option */ if (fo->cookie.len > 0) @@ -3448,6 +3413,10 @@ int tcp_connect(struct sock *sk) int err; tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB); + + if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) + return -EHOSTUNREACH; /* Routing failure or similar. */ + tcp_connect_init(sk); if (unlikely(tp->repair)) { @@ -3476,6 +3445,11 @@ int tcp_connect(struct sock *sk) */ tp->snd_nxt = tp->write_seq; tp->pushed_seq = tp->write_seq; + buff = tcp_send_head(sk); + if (unlikely(buff)) { + tp->snd_nxt = TCP_SKB_CB(buff)->seq; + tp->pushed_seq = TCP_SKB_CB(buff)->seq; + } TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS); /* Timer for repeating the SYN until an answer. */ diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index f6c50af24a64737672f7ede2ff41158bfed5f1b4..697f4c67b2e35dc333fa55ce2291ae9fb8484f7d 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c @@ -105,8 +105,9 @@ static inline int tcp_probe_avail(void) * Note: arguments must match tcp_rcv_established()! */ static void jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, - const struct tcphdr *th, unsigned int len) + const struct tcphdr *th) { + unsigned int len = skb->len; const struct tcp_sock *tp = tcp_sk(sk); const struct inet_sock *inet = inet_sk(sk); @@ -145,7 +146,7 @@ static void jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, BUG(); } - p->length = skb->len; + p->length = len; p->snd_nxt = tp->snd_nxt; p->snd_una = tp->snd_una; p->snd_cwnd = tp->snd_cwnd; diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c index fe9a493d02082d3830f37854d5f169f769844ffb..449cd914d58e1df8352fd9180fbdb5b0feef683c 100644 --- a/net/ipv4/tcp_recovery.c +++ b/net/ipv4/tcp_recovery.c @@ -113,7 +113,7 @@ void tcp_rack_mark_lost(struct sock *sk) tp->rack.advanced = 0; tcp_rack_detect_loss(sk, &timeout); if (timeout) { - timeout = usecs_to_jiffies(timeout + TCP_REO_TIMEOUT_MIN); + timeout = usecs_to_jiffies(timeout) + TCP_TIMEOUT_MIN; inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT, timeout, inet_csk(sk)->icsk_rto); } diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c index f2123075ce6e1be4753e26bb1db81423e272caef..addc122f88186fb04579e0ee60fd4a7adad9f97d 100644 --- a/net/ipv4/tcp_scalable.c +++ b/net/ipv4/tcp_scalable.c @@ -15,10 +15,6 @@ #define TCP_SCALABLE_AI_CNT 50U #define TCP_SCALABLE_MD_SCALE 3 -struct scalable { - u32 loss_cwnd; -}; - static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 acked) { struct tcp_sock *tp = tcp_sk(sk); @@ -36,23 +32,13 @@ static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 acked) static u32 tcp_scalable_ssthresh(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); - struct scalable *ca = inet_csk_ca(sk); - - ca->loss_cwnd = tp->snd_cwnd; return max(tp->snd_cwnd - (tp->snd_cwnd>>TCP_SCALABLE_MD_SCALE), 2U); } -static u32 tcp_scalable_cwnd_undo(struct sock *sk) -{ - const struct scalable *ca = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); -} - static struct tcp_congestion_ops tcp_scalable __read_mostly = { .ssthresh = tcp_scalable_ssthresh, - .undo_cwnd = tcp_scalable_cwnd_undo, + .undo_cwnd = tcp_reno_undo_cwnd, .cong_avoid = tcp_scalable_cong_avoid, .owner = THIS_MODULE, diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c0feeeef962aa31401ee90f8bd015c2aae2ef932..655dd8d7f064f998f7caa323822dfffe9984ebdf 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -239,7 +239,6 @@ static int tcp_write_timeout(struct sock *sk) /* Called with BH disabled */ void tcp_delack_timer_handler(struct sock *sk) { - struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); sk_mem_reclaim_partial(sk); @@ -254,17 +253,6 @@ void tcp_delack_timer_handler(struct sock *sk) } icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER; - if (!skb_queue_empty(&tp->ucopy.prequeue)) { - struct sk_buff *skb; - - __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSCHEDULERFAILED); - - while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) - sk_backlog_rcv(sk, skb); - - tp->ucopy.memory = 0; - } - if (inet_csk_ack_scheduled(sk)) { if (!icsk->icsk_ack.pingpong) { /* Delayed ACK missed: inflate ATO. */ @@ -652,7 +640,8 @@ static void tcp_keepalive_timer (unsigned long data) goto death; } - if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE) + if (!sock_flag(sk, SOCK_KEEPOPEN) || + ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT))) goto out; elapsed = keepalive_time_when(tp); diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c index 2417f55374c593c89b2aeb1ec4f6e6e74bb1395f..6bb9e14c710a7e2bfa58ee63ff6e02461a22cbec 100644 --- a/net/ipv4/tcp_ulp.c +++ b/net/ipv4/tcp_ulp.c @@ -122,14 +122,14 @@ int tcp_set_ulp(struct sock *sk, const char *name) ulp_ops = __tcp_ulp_find_autoload(name); if (!ulp_ops) - err = -ENOENT; - else - err = ulp_ops->init(sk); + return -ENOENT; - if (err) - goto out; + err = ulp_ops->init(sk); + if (err) { + module_put(ulp_ops->owner); + return err; + } icsk->icsk_ulp_ops = ulp_ops; - out: - return err; + return 0; } diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c index 76005d4b8dfc2287009628aa07912e0183ea2f05..6fcf482d611ba16e667d8b8024ac97658d45f84f 100644 --- a/net/ipv4/tcp_veno.c +++ b/net/ipv4/tcp_veno.c @@ -30,7 +30,6 @@ struct veno { u32 basertt; /* the min of all Veno rtt measurements seen (in usec) */ u32 inc; /* decide whether to increase cwnd */ u32 diff; /* calculate the diff rate */ - u32 loss_cwnd; /* cwnd when loss occured */ }; /* There are several situations when we must "re-start" Veno: @@ -194,7 +193,6 @@ static u32 tcp_veno_ssthresh(struct sock *sk) const struct tcp_sock *tp = tcp_sk(sk); struct veno *veno = inet_csk_ca(sk); - veno->loss_cwnd = tp->snd_cwnd; if (veno->diff < beta) /* in "non-congestive state", cut cwnd by 1/5 */ return max(tp->snd_cwnd * 4 / 5, 2U); @@ -203,17 +201,10 @@ static u32 tcp_veno_ssthresh(struct sock *sk) return max(tp->snd_cwnd >> 1U, 2U); } -static u32 tcp_veno_cwnd_undo(struct sock *sk) -{ - const struct veno *veno = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, veno->loss_cwnd); -} - static struct tcp_congestion_ops tcp_veno __read_mostly = { .init = tcp_veno_init, .ssthresh = tcp_veno_ssthresh, - .undo_cwnd = tcp_veno_cwnd_undo, + .undo_cwnd = tcp_reno_undo_cwnd, .cong_avoid = tcp_veno_cong_avoid, .pkts_acked = tcp_veno_pkts_acked, .set_state = tcp_veno_state, diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index e6ff99c4bd3b6914a6e79dc3bb94aa45176dae9e..96e829b2e2fcb8f4539a5b7591a558828feeafbd 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c @@ -37,7 +37,6 @@ struct yeah { u32 fast_count; u32 pkts_acked; - u32 loss_cwnd; }; static void tcp_yeah_init(struct sock *sk) @@ -220,22 +219,14 @@ static u32 tcp_yeah_ssthresh(struct sock *sk) yeah->fast_count = 0; yeah->reno_count = max(yeah->reno_count>>1, 2U); - yeah->loss_cwnd = tp->snd_cwnd; return max_t(int, tp->snd_cwnd - reduction, 2); } -static u32 tcp_yeah_cwnd_undo(struct sock *sk) -{ - const struct yeah *yeah = inet_csk_ca(sk); - - return max(tcp_sk(sk)->snd_cwnd, yeah->loss_cwnd); -} - static struct tcp_congestion_ops tcp_yeah __read_mostly = { .init = tcp_yeah_init, .ssthresh = tcp_yeah_ssthresh, - .undo_cwnd = tcp_yeah_cwnd_undo, + .undo_cwnd = tcp_reno_undo_cwnd, .cong_avoid = tcp_yeah_cong_avoid, .set_state = tcp_vegas_state, .cwnd_event = tcp_vegas_cwnd_event, diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b057653ceca9208d1e1765525e5492876c0b651e..5676237d2b0f88e3bd400af3e1c375e51c333847 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -380,8 +380,8 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum) static int compute_score(struct sock *sk, struct net *net, __be32 saddr, __be16 sport, - __be32 daddr, unsigned short hnum, int dif, - bool exact_dif) + __be32 daddr, unsigned short hnum, + int dif, int sdif, bool exact_dif) { int score; struct inet_sock *inet; @@ -413,10 +413,15 @@ static int compute_score(struct sock *sk, struct net *net, } if (sk->sk_bound_dev_if || exact_dif) { - if (sk->sk_bound_dev_if != dif) + bool dev_match = (sk->sk_bound_dev_if == dif || + sk->sk_bound_dev_if == sdif); + + if (exact_dif && !dev_match) return -1; - score += 4; + if (sk->sk_bound_dev_if && dev_match) + score += 4; } + if (sk->sk_incoming_cpu == raw_smp_processor_id()) score++; return score; @@ -436,10 +441,11 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr, /* called with rcu_read_lock() */ static struct sock *udp4_lib_lookup2(struct net *net, - __be32 saddr, __be16 sport, - __be32 daddr, unsigned int hnum, int dif, bool exact_dif, - struct udp_hslot *hslot2, - struct sk_buff *skb) + __be32 saddr, __be16 sport, + __be32 daddr, unsigned int hnum, + int dif, int sdif, bool exact_dif, + struct udp_hslot *hslot2, + struct sk_buff *skb) { struct sock *sk, *result; int score, badness, matches = 0, reuseport = 0; @@ -449,7 +455,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, badness = 0; udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { score = compute_score(sk, net, saddr, sport, - daddr, hnum, dif, exact_dif); + daddr, hnum, dif, sdif, exact_dif); if (score > badness) { reuseport = sk->sk_reuseport; if (reuseport) { @@ -477,8 +483,8 @@ static struct sock *udp4_lib_lookup2(struct net *net, * harder than this. -DaveM */ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, - __be16 sport, __be32 daddr, __be16 dport, - int dif, struct udp_table *udptable, struct sk_buff *skb) + __be16 sport, __be32 daddr, __be16 dport, int dif, + int sdif, struct udp_table *udptable, struct sk_buff *skb) { struct sock *sk, *result; unsigned short hnum = ntohs(dport); @@ -496,7 +502,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, goto begin; result = udp4_lib_lookup2(net, saddr, sport, - daddr, hnum, dif, + daddr, hnum, dif, sdif, exact_dif, hslot2, skb); if (!result) { unsigned int old_slot2 = slot2; @@ -511,7 +517,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, goto begin; result = udp4_lib_lookup2(net, saddr, sport, - daddr, hnum, dif, + daddr, hnum, dif, sdif, exact_dif, hslot2, skb); } return result; @@ -521,7 +527,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, badness = 0; sk_for_each_rcu(sk, &hslot->head) { score = compute_score(sk, net, saddr, sport, - daddr, hnum, dif, exact_dif); + daddr, hnum, dif, sdif, exact_dif); if (score > badness) { reuseport = sk->sk_reuseport; if (reuseport) { @@ -554,7 +560,7 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, return __udp4_lib_lookup(dev_net(skb->dev), iph->saddr, sport, iph->daddr, dport, inet_iif(skb), - udptable, skb); + inet_sdif(skb), udptable, skb); } struct sock *udp4_lib_lookup_skb(struct sk_buff *skb, @@ -576,7 +582,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, struct sock *sk; sk = __udp4_lib_lookup(net, saddr, sport, daddr, dport, - dif, &udp_table, NULL); + dif, 0, &udp_table, NULL); if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; return sk; @@ -587,7 +593,7 @@ EXPORT_SYMBOL_GPL(udp4_lib_lookup); static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk, __be16 loc_port, __be32 loc_addr, __be16 rmt_port, __be32 rmt_addr, - int dif, unsigned short hnum) + int dif, int sdif, unsigned short hnum) { struct inet_sock *inet = inet_sk(sk); @@ -597,9 +603,10 @@ static inline bool __udp_is_mcast_sock(struct net *net, struct sock *sk, (inet->inet_dport != rmt_port && inet->inet_dport) || (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) || ipv6_only_sock(sk) || - (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) + (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && + sk->sk_bound_dev_if != sdif)) return false; - if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif)) + if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif, sdif)) return false; return true; } @@ -628,8 +635,8 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) struct net *net = dev_net(skb->dev); sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, - iph->saddr, uh->source, skb->dev->ifindex, udptable, - NULL); + iph->saddr, uh->source, skb->dev->ifindex, 0, + udptable, NULL); if (!sk) { __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); return; /* No socket for error */ @@ -802,7 +809,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4) if (is_udplite) /* UDP-Lite */ csum = udplite_csum(skb); - else if (sk->sk_no_check_tx) { /* UDP csum disabled */ + else if (sk->sk_no_check_tx) { /* UDP csum off */ skb->ip_summed = CHECKSUM_NONE; goto send; @@ -1163,34 +1170,36 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, return ret; } -#if BITS_PER_LONG == 64 +#define UDP_SKB_IS_STATELESS 0x80000000 + static void udp_set_dev_scratch(struct sk_buff *skb) { - struct udp_dev_scratch *scratch; + struct udp_dev_scratch *scratch = udp_skb_scratch(skb); BUILD_BUG_ON(sizeof(struct udp_dev_scratch) > sizeof(long)); - scratch = (struct udp_dev_scratch *)&skb->dev_scratch; - scratch->truesize = skb->truesize; + scratch->_tsize_state = skb->truesize; +#if BITS_PER_LONG == 64 scratch->len = skb->len; scratch->csum_unnecessary = !!skb_csum_unnecessary(skb); scratch->is_linear = !skb_is_nonlinear(skb); +#endif + /* all head states execept sp (dst, sk, nf) are always cleared by + * udp_rcv() and we need to preserve secpath, if present, to eventually + * process IP_CMSG_PASSSEC at recvmsg() time + */ + if (likely(!skb_sec_path(skb))) + scratch->_tsize_state |= UDP_SKB_IS_STATELESS; } static int udp_skb_truesize(struct sk_buff *skb) { - return ((struct udp_dev_scratch *)&skb->dev_scratch)->truesize; -} -#else -static void udp_set_dev_scratch(struct sk_buff *skb) -{ - skb->dev_scratch = skb->truesize; + return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS; } -static int udp_skb_truesize(struct sk_buff *skb) +static bool udp_skb_has_head_state(struct sk_buff *skb) { - return skb->dev_scratch; + return !(udp_skb_scratch(skb)->_tsize_state & UDP_SKB_IS_STATELESS); } -#endif /* fully reclaim rmem/fwd memory allocated for skb */ static void udp_rmem_release(struct sock *sk, int size, int partial, @@ -1388,12 +1397,15 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) unlock_sock_fast(sk, slow); } - /* we cleared the head states previously only if the skb lacks any IP - * options, see __udp_queue_rcv_skb(). + if (!skb_unref(skb)) + return; + + /* In the more common cases we cleared the head states previously, + * see __udp_queue_rcv_skb(). */ - if (unlikely(IPCB(skb)->opt.optlen > 0)) + if (unlikely(udp_skb_has_head_state(skb))) skb_release_head_state(skb); - consume_stateless_skb(skb); + __consume_stateless_skb(skb); } EXPORT_SYMBOL_GPL(skb_consume_udp); @@ -1576,7 +1588,8 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, return ip_recv_error(sk, msg, len, addr_len); try_again: - peeking = off = sk_peek_offset(sk, flags); + peeking = flags & MSG_PEEK; + off = sk_peek_offset(sk, flags); skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err); if (!skb) return err; @@ -1784,13 +1797,6 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) sk_mark_napi_id_once(sk, skb); } - /* At recvmsg() time we need skb->dst to process IP options-related - * cmsg, elsewhere can we clear all pending head states while they are - * hot in the cache - */ - if (likely(IPCB(skb)->opt.optlen == 0)) - skb_release_head_state(skb); - rc = __udp_enqueue_schedule_skb(sk, skb); if (rc < 0) { int is_udplite = IS_UDPLITE(sk); @@ -1811,8 +1817,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) static struct static_key udp_encap_needed __read_mostly; void udp_encap_enable(void) { - if (!static_key_enabled(&udp_encap_needed)) - static_key_slow_inc(&udp_encap_needed); + static_key_enable(&udp_encap_needed); } EXPORT_SYMBOL(udp_encap_enable); @@ -1930,15 +1935,18 @@ static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) /* For TCP sockets, sk_rx_dst is protected by socket lock * For UDP, we use xchg() to guard against concurrent changes. */ -static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) +bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) { struct dst_entry *old; if (dst_hold_safe(dst)) { old = xchg(&sk->sk_rx_dst, dst); dst_release(old); + return old != dst; } + return false; } +EXPORT_SYMBOL(udp_sk_rx_dst_set); /* * Multicasts and broadcasts go to each listener. @@ -1957,6 +1965,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10); unsigned int offset = offsetof(typeof(*sk), sk_node); int dif = skb->dev->ifindex; + int sdif = inet_sdif(skb); struct hlist_node *node; struct sk_buff *nskb; @@ -1971,7 +1980,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) { if (!__udp_is_mcast_sock(net, sk, uh->dest, daddr, - uh->source, saddr, dif, hnum)) + uh->source, saddr, dif, sdif, hnum)) continue; if (!first) { @@ -2161,7 +2170,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net, __be16 loc_port, __be32 loc_addr, __be16 rmt_port, __be32 rmt_addr, - int dif) + int dif, int sdif) { struct sock *sk, *result; unsigned short hnum = ntohs(loc_port); @@ -2175,7 +2184,7 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net, result = NULL; sk_for_each_rcu(sk, &hslot->head) { if (__udp_is_mcast_sock(net, sk, loc_port, loc_addr, - rmt_port, rmt_addr, dif, hnum)) { + rmt_port, rmt_addr, dif, sdif, hnum)) { if (result) return NULL; result = sk; @@ -2192,7 +2201,7 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net, static struct sock *__udp4_lib_demux_lookup(struct net *net, __be16 loc_port, __be32 loc_addr, __be16 rmt_port, __be32 rmt_addr, - int dif) + int dif, int sdif) { unsigned short hnum = ntohs(loc_port); unsigned int hash2 = udp4_portaddr_hash(net, loc_addr, hnum); @@ -2204,7 +2213,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net, udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { if (INET_MATCH(sk, net, acookie, rmt_addr, - loc_addr, ports, dif)) + loc_addr, ports, dif, sdif)) return sk; /* Only check first socket in chain */ break; @@ -2212,47 +2221,50 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net, return NULL; } -void udp_v4_early_demux(struct sk_buff *skb) +int udp_v4_early_demux(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); + struct in_device *in_dev = NULL; const struct iphdr *iph; const struct udphdr *uh; struct sock *sk = NULL; struct dst_entry *dst; int dif = skb->dev->ifindex; + int sdif = inet_sdif(skb); int ours; /* validate the packet */ if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) - return; + return 0; iph = ip_hdr(skb); uh = udp_hdr(skb); if (skb->pkt_type == PACKET_BROADCAST || skb->pkt_type == PACKET_MULTICAST) { - struct in_device *in_dev = __in_dev_get_rcu(skb->dev); + in_dev = __in_dev_get_rcu(skb->dev); if (!in_dev) - return; + return 0; /* we are supposed to accept bcast packets */ if (skb->pkt_type == PACKET_MULTICAST) { ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, iph->protocol); if (!ours) - return; + return 0; } sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, - uh->source, iph->saddr, dif); + uh->source, iph->saddr, + dif, sdif); } else if (skb->pkt_type == PACKET_HOST) { sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr, - uh->source, iph->saddr, dif); + uh->source, iph->saddr, dif, sdif); } if (!sk || !refcount_inc_not_zero(&sk->sk_refcnt)) - return; + return 0; skb->sk = sk; skb->destructor = sock_efree; @@ -2261,12 +2273,23 @@ void udp_v4_early_demux(struct sk_buff *skb) if (dst) dst = dst_check(dst, 0); if (dst) { + u32 itag = 0; + /* set noref for now. * any place which wants to hold dst has to call * dst_hold_safe() */ skb_dst_set_noref(skb, dst); + + /* for unconnected multicast sockets we need to validate + * the source on each packet + */ + if (!inet_sk(sk)->inet_daddr && in_dev) + return ip_mc_validate_source(skb, iph->daddr, + iph->saddr, iph->tos, + skb->dev, in_dev, &itag); } + return 0; } int udp_rcv(struct sk_buff *skb) diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index 4515836d2a3ac309c9305a4ee1ce95fa0b6e26d4..d0390d844ac840e4db3da1f9257e14ded78ba333 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c @@ -45,7 +45,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, sk = __udp4_lib_lookup(net, req->id.idiag_src[0], req->id.idiag_sport, req->id.idiag_dst[0], req->id.idiag_dport, - req->id.idiag_if, tbl, NULL); + req->id.idiag_if, 0, tbl, NULL); #if IS_ENABLED(CONFIG_IPV6) else if (req->sdiag_family == AF_INET6) sk = __udp6_lib_lookup(net, @@ -53,7 +53,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, req->id.idiag_sport, (struct in6_addr *)req->id.idiag_dst, req->id.idiag_dport, - req->id.idiag_if, tbl, NULL); + req->id.idiag_if, 0, tbl, NULL); #endif if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; @@ -182,7 +182,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb, sk = __udp4_lib_lookup(net, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_src[0], req->id.idiag_sport, - req->id.idiag_if, tbl, NULL); + req->id.idiag_if, 0, tbl, NULL); #if IS_ENABLED(CONFIG_IPV6) else if (req->sdiag_family == AF_INET6) { if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) && @@ -190,7 +190,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb, sk = __udp4_lib_lookup(net, req->id.idiag_dst[3], req->id.idiag_dport, req->id.idiag_src[3], req->id.idiag_sport, - req->id.idiag_if, tbl, NULL); + req->id.idiag_if, 0, tbl, NULL); else sk = __udp6_lib_lookup(net, @@ -198,7 +198,7 @@ static int __udp_diag_destroy(struct sk_buff *in_skb, req->id.idiag_dport, (struct in6_addr *)req->id.idiag_src, req->id.idiag_sport, - req->id.idiag_if, tbl, NULL); + req->id.idiag_if, 0, tbl, NULL); } #endif else { diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 781250151d40ee4559f7b90d15dccad8ffaeafd0..97658bfc1b58ab8a19026811e3aa917e598e554b 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -21,7 +21,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb, __be16 new_protocol, bool is_ipv6) { int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); - bool remcsum, need_csum, offload_csum, ufo, gso_partial; + bool remcsum, need_csum, offload_csum, gso_partial; struct sk_buff *segs = ERR_PTR(-EINVAL); struct udphdr *uh = udp_hdr(skb); u16 mac_offset = skb->mac_header; @@ -61,8 +61,6 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb, remcsum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TUNNEL_REMCSUM); skb->remcsum_offload = remcsum; - ufo = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP); - need_ipsec = skb_dst(skb) && dst_xfrm(skb_dst(skb)); /* Try to offload checksum if possible */ offload_csum = !!(need_csum && @@ -77,7 +75,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb, * outer one so strip the existing checksum feature flags and * instead set the flag based on our outer checksum offload value. */ - if (remcsum || ufo) { + if (remcsum) { features &= ~NETIF_F_CSUM_MASK; if (!need_csum || offload_csum) features |= NETIF_F_HW_CSUM; @@ -189,66 +187,16 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, } EXPORT_SYMBOL(skb_udp_tunnel_segment); -static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, - netdev_features_t features) +static struct sk_buff *udp4_tunnel_segment(struct sk_buff *skb, + netdev_features_t features) { struct sk_buff *segs = ERR_PTR(-EINVAL); - unsigned int mss; - __wsum csum; - struct udphdr *uh; - struct iphdr *iph; if (skb->encapsulation && (skb_shinfo(skb)->gso_type & - (SKB_GSO_UDP_TUNNEL|SKB_GSO_UDP_TUNNEL_CSUM))) { + (SKB_GSO_UDP_TUNNEL|SKB_GSO_UDP_TUNNEL_CSUM))) segs = skb_udp_tunnel_segment(skb, features, false); - goto out; - } - if (!pskb_may_pull(skb, sizeof(struct udphdr))) - goto out; - - mss = skb_shinfo(skb)->gso_size; - if (unlikely(skb->len <= mss)) - goto out; - - if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { - /* Packet is from an untrusted source, reset gso_segs. */ - - skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss); - - segs = NULL; - goto out; - } - - /* Do software UFO. Complete and fill in the UDP checksum as - * HW cannot do checksum of UDP packets sent as multiple - * IP fragments. - */ - - uh = udp_hdr(skb); - iph = ip_hdr(skb); - - uh->check = 0; - csum = skb_checksum(skb, 0, skb->len, 0); - uh->check = udp_v4_check(skb->len, iph->saddr, iph->daddr, csum); - if (uh->check == 0) - uh->check = CSUM_MANGLED_0; - - skb->ip_summed = CHECKSUM_NONE; - - /* If there is no outer header we can fake a checksum offload - * due to the fact that we have already done the checksum in - * software prior to segmenting the frame. - */ - if (!skb->encap_hdr_csum) - features |= NETIF_F_HW_CSUM; - - /* Fragment the skb. IP headers of the fragments are updated in - * inet_gso_segment() - */ - segs = skb_segment(skb, features); -out: return segs; } @@ -382,7 +330,7 @@ static int udp4_gro_complete(struct sk_buff *skb, int nhoff) static const struct net_offload udpv4_offload = { .callbacks = { - .gso_segment = udp4_ufo_fragment, + .gso_segment = udp4_tunnel_segment, .gro_receive = udp4_gro_receive, .gro_complete = udp4_gro_complete, }, diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c index 58bd39fb14b452f27fcac7702f1ab6fb2293efce..6539ff15e9a3420db867bc2174aab3e196f97e43 100644 --- a/net/ipv4/udp_tunnel.c +++ b/net/ipv4/udp_tunnel.c @@ -82,7 +82,8 @@ void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock, struct sock *sk = sock->sk; struct udp_tunnel_info ti; - if (!dev->netdev_ops->ndo_udp_tunnel_add) + if (!dev->netdev_ops->ndo_udp_tunnel_add || + !(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT)) return; ti.type = type; @@ -93,6 +94,24 @@ void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock, } EXPORT_SYMBOL_GPL(udp_tunnel_push_rx_port); +void udp_tunnel_drop_rx_port(struct net_device *dev, struct socket *sock, + unsigned short type) +{ + struct sock *sk = sock->sk; + struct udp_tunnel_info ti; + + if (!dev->netdev_ops->ndo_udp_tunnel_del || + !(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT)) + return; + + ti.type = type; + ti.sa_family = sk->sk_family; + ti.port = inet_sk(sk)->inet_sport; + + dev->netdev_ops->ndo_udp_tunnel_del(dev, &ti); +} +EXPORT_SYMBOL_GPL(udp_tunnel_drop_rx_port); + /* Notify netdevs that UDP port started listening */ void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type) { @@ -109,6 +128,8 @@ void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type) for_each_netdev_rcu(net, dev) { if (!dev->netdev_ops->ndo_udp_tunnel_add) continue; + if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT)) + continue; dev->netdev_ops->ndo_udp_tunnel_add(dev, &ti); } rcu_read_unlock(); @@ -131,6 +152,8 @@ void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type) for_each_netdev_rcu(net, dev) { if (!dev->netdev_ops->ndo_udp_tunnel_del) continue; + if (!(dev->features & NETIF_F_RX_UDP_TUNNEL_PORT)) + continue; dev->netdev_ops->ndo_udp_tunnel_del(dev, &ti); } rcu_read_unlock(); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 71b4ecc195c707b3e2ce9dab974f6d68a5e5c5eb..d7bf0b0418858cac8c2689fea8bfe3e83a160a15 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -20,7 +20,8 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, int tos, int oif, const xfrm_address_t *saddr, - const xfrm_address_t *daddr) + const xfrm_address_t *daddr, + u32 mark) { struct rtable *rt; @@ -28,6 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, fl4->daddr = daddr->a4; fl4->flowi4_tos = tos; fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif); + fl4->flowi4_mark = mark; if (saddr) fl4->saddr = saddr->a4; @@ -42,20 +44,22 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif, const xfrm_address_t *saddr, - const xfrm_address_t *daddr) + const xfrm_address_t *daddr, + u32 mark) { struct flowi4 fl4; - return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr); + return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr, mark); } static int xfrm4_get_saddr(struct net *net, int oif, - xfrm_address_t *saddr, xfrm_address_t *daddr) + xfrm_address_t *saddr, xfrm_address_t *daddr, + u32 mark) { struct dst_entry *dst; struct flowi4 fl4; - dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr); + dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr, mark); if (IS_ERR(dst)) return -EHOSTUNREACH; @@ -213,14 +217,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) fl4->flowi4_tos = iph->tos; } -static inline int xfrm4_garbage_collect(struct dst_ops *ops) -{ - struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops); - - xfrm_garbage_collect_deferred(net); - return (dst_entries_get_slow(ops) > ops->gc_thresh * 2); -} - static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu) { @@ -259,14 +255,13 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static struct dst_ops xfrm4_dst_ops_template = { .family = AF_INET, - .gc = xfrm4_garbage_collect, .update_pmtu = xfrm4_update_pmtu, .redirect = xfrm4_redirect, .cow_metrics = dst_cow_metrics_generic, .destroy = xfrm4_dst_destroy, .ifdown = xfrm4_dst_ifdown, .local_out = __ip_local_out, - .gc_thresh = INT_MAX, + .gc_thresh = 32768, }; static const struct xfrm_policy_afinfo xfrm4_policy_afinfo = { diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 48c452959d2c2fe687472c3732fe40246a8c863a..ea71e4b0ab7aea80fc6b564fddeea7a6b01feaeb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -308,22 +308,12 @@ config IPV6_SEG6_LWTUNNEL depends on IPV6 select LWTUNNEL select DST_CACHE + select IPV6_MULTIPLE_TABLES ---help--- Support for encapsulation of packets within an outer IPv6 header and a Segment Routing Header using the lightweight - tunnels mechanism. - - If unsure, say N. - -config IPV6_SEG6_INLINE - bool "IPv6: direct Segment Routing Header insertion " - depends on IPV6_SEG6_LWTUNNEL - ---help--- - Support for direct insertion of the Segment Routing Header, - also known as inline mode. Be aware that direct insertion of - extension headers (as opposed to encapsulation) may break - multiple mechanisms such as PMTUD or IPSec AH. Use this feature - only if you know exactly what you are doing. + tunnels mechanism. Also enable support for advanced local + processing of SRv6 packets based on their active segment. If unsure, say N. diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index 217e9ff0e24b6db62307d27ddc50f1a88c2da73e..10e342363793550c6b8ef5a114f73be91f237335 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile @@ -9,7 +9,7 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \ raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \ exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o \ - udp_offload.o seg6.o + udp_offload.o seg6.o fib6_notifier.o ipv6-offload := ip6_offload.o tcpv6_offload.o exthdrs_offload.o @@ -23,7 +23,7 @@ ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o ipv6-$(CONFIG_PROC_FS) += proc.o ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o ipv6-$(CONFIG_NETLABEL) += calipso.o -ipv6-$(CONFIG_IPV6_SEG6_LWTUNNEL) += seg6_iptunnel.o +ipv6-$(CONFIG_IPV6_SEG6_LWTUNNEL) += seg6_iptunnel.o seg6_local.o ipv6-$(CONFIG_IPV6_SEG6_HMAC) += seg6_hmac.o ipv6-objs += $(ipv6-y) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3c46e9513a31d04eeb1e76384f146b759ae38eed..96861c702c069d67112cace3196e657fbfaabf87 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1399,10 +1399,18 @@ static inline int ipv6_saddr_preferred(int type) return 0; } -static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) +static bool ipv6_use_optimistic_addr(struct net *net, + struct inet6_dev *idev) { #ifdef CONFIG_IPV6_OPTIMISTIC_DAD - return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic; + if (!idev) + return false; + if (!net->ipv6.devconf_all->optimistic_dad && !idev->cnf.optimistic_dad) + return false; + if (!net->ipv6.devconf_all->use_optimistic && !idev->cnf.use_optimistic) + return false; + + return true; #else return false; #endif @@ -1472,7 +1480,7 @@ static int ipv6_get_saddr_eval(struct net *net, /* Rule 3: Avoid deprecated and optimistic addresses */ u8 avoid = IFA_F_DEPRECATED; - if (!ipv6_use_optimistic_addr(score->ifa->idev)) + if (!ipv6_use_optimistic_addr(net, score->ifa->idev)) avoid |= IFA_F_OPTIMISTIC; ret = ipv6_saddr_preferred(score->addr_type) || !(score->ifa->flags & avoid); @@ -2460,7 +2468,8 @@ int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev, int max_addresses = in6_dev->cnf.max_addresses; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD - if (in6_dev->cnf.optimistic_dad && + if ((net->ipv6.devconf_all->optimistic_dad || + in6_dev->cnf.optimistic_dad) && !net->ipv6.devconf_all->forwarding && sllao) addr_flags |= IFA_F_OPTIMISTIC; #endif @@ -3030,9 +3039,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) static void init_loopback(struct net_device *dev) { struct inet6_dev *idev; - struct net_device *sp_dev; - struct inet6_ifaddr *sp_ifa; - struct rt6_info *sp_rt; /* ::1 */ @@ -3045,45 +3051,6 @@ static void init_loopback(struct net_device *dev) } add_addr(idev, &in6addr_loopback, 128, IFA_HOST); - - /* Add routes to other interface's IPv6 addresses */ - for_each_netdev(dev_net(dev), sp_dev) { - if (!strcmp(sp_dev->name, dev->name)) - continue; - - idev = __in6_dev_get(sp_dev); - if (!idev) - continue; - - read_lock_bh(&idev->lock); - list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { - - if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) - continue; - - if (sp_ifa->rt) { - /* This dst has been added to garbage list when - * lo device down, release this obsolete dst and - * reallocate a new router for ifa. - */ - if (!atomic_read(&sp_ifa->rt->rt6i_ref)) { - ip6_rt_put(sp_ifa->rt); - sp_ifa->rt = NULL; - } else { - continue; - } - } - - sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); - - /* Failure cases are ignored */ - if (!IS_ERR(sp_rt)) { - sp_ifa->rt = sp_rt; - ip6_ins_rt(sp_rt); - } - } - read_unlock_bh(&idev->lock); - } } void addrconf_add_linklocal(struct inet6_dev *idev, @@ -3093,7 +3060,8 @@ void addrconf_add_linklocal(struct inet6_dev *idev, u32 addr_flags = flags | IFA_F_PERMANENT; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD - if (idev->cnf.optimistic_dad && + if ((dev_net(idev->dev)->ipv6.devconf_all->optimistic_dad || + idev->cnf.optimistic_dad) && !dev_net(idev->dev)->ipv6.devconf_all->forwarding) addr_flags |= IFA_F_OPTIMISTIC; #endif @@ -3321,11 +3289,11 @@ static void addrconf_gre_config(struct net_device *dev) static int fixup_permanent_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) { - /* rt6i_ref == 0 means the host route was removed from the + /* !rt6i_node means the host route was removed from the * FIB, for example, if 'lo' device is taken down. In that * case regenerate the host route. */ - if (!ifp->rt || !atomic_read(&ifp->rt->rt6i_ref)) { + if (!ifp->rt || !ifp->rt->rt6i_node) { struct rt6_info *rt, *prev; rt = addrconf_dst_alloc(idev, &ifp->addr, false); @@ -3852,6 +3820,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) goto out; if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || + dev_net(dev)->ipv6.devconf_all->accept_dad < 1 || idev->cnf.accept_dad < 1 || !(ifp->flags&IFA_F_TENTATIVE) || ifp->flags & IFA_F_NODAD) { @@ -3883,7 +3852,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) */ if (ifp->flags & IFA_F_OPTIMISTIC) { ip6_ins_rt(ifp->rt); - if (ipv6_use_optimistic_addr(idev)) { + if (ipv6_use_optimistic_addr(dev_net(dev), idev)) { /* Because optimistic nodes can use this address, * notify listeners. If DAD fails, RTM_DELADDR is sent. */ @@ -3939,7 +3908,9 @@ static void addrconf_dad_work(struct work_struct *w) action = DAD_ABORT; ifp->state = INET6_IFADDR_STATE_POSTDAD; - if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6 && + if ((dev_net(idev->dev)->ipv6.devconf_all->accept_dad > 1 || + idev->cnf.accept_dad > 1) && + !idev->cnf.disable_ipv6 && !(ifp->flags & IFA_F_STABLE_PRIVACY)) { struct in6_addr addr; @@ -4982,9 +4953,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) /* Don't send DELADDR notification for TENTATIVE address, * since NEWADDR notification is sent only after removing - * TENTATIVE flag. + * TENTATIVE flag, if DAD has not failed. */ - if (ifa->flags & IFA_F_TENTATIVE && event == RTM_DELADDR) + if (ifa->flags & IFA_F_TENTATIVE && !(ifa->flags & IFA_F_DADFAILED) && + event == RTM_DELADDR) return; skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); @@ -5556,7 +5528,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) * our DAD process, so we don't need * to do it again */ - if (!(ifp->rt->rt6i_node)) + if (!rcu_access_pointer(ifp->rt->rt6i_node)) ip6_ins_rt(ifp->rt); if (ifp->idev->cnf.forwarding) addrconf_join_anycast(ifp); @@ -6605,21 +6577,21 @@ int __init addrconf_init(void) rtnl_af_register(&inet6_ops); err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo, - NULL); + 0); if (err < 0) goto errout; /* Only the first call to __rtnl_register can fail */ - __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL, NULL); - __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL, NULL); + __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL, 0); + __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL, 0); __rtnl_register(PF_INET6, RTM_GETADDR, inet6_rtm_getaddr, - inet6_dump_ifaddr, NULL); + inet6_dump_ifaddr, 0); __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, - inet6_dump_ifmcaddr, NULL); + inet6_dump_ifmcaddr, 0); __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, - inet6_dump_ifacaddr, NULL); + inet6_dump_ifacaddr, 0); __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, - inet6_netconf_dump_devconf, NULL); + inet6_netconf_dump_devconf, 0); ipv6_addr_label_rtnl_register(); diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 7a428f65c7ece0b7155e26ba4afbf9e37f7f8690..b055bc79f56d555c89684116c1580984950f77a8 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c @@ -405,6 +405,18 @@ static const struct nla_policy ifal_policy[IFAL_MAX+1] = { [IFAL_LABEL] = { .len = sizeof(u32), }, }; +static bool addrlbl_ifindex_exists(struct net *net, int ifindex) +{ + + struct net_device *dev; + + rcu_read_lock(); + dev = dev_get_by_index_rcu(net, ifindex); + rcu_read_unlock(); + + return dev != NULL; +} + static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { @@ -439,7 +451,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, switch (nlh->nlmsg_type) { case RTM_NEWADDRLABEL: if (ifal->ifal_index && - !__dev_get_by_index(net, ifal->ifal_index)) + !addrlbl_ifindex_exists(net, ifal->ifal_index)) return -EINVAL; err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen, @@ -548,7 +560,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh, return -EINVAL; if (ifal->ifal_index && - !__dev_get_by_index(net, ifal->ifal_index)) + !addrlbl_ifindex_exists(net, ifal->ifal_index)) return -EINVAL; if (!tb[IFAL_ADDRESS]) @@ -593,10 +605,10 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh, void __init ipv6_addr_label_rtnl_register(void) { __rtnl_register(PF_INET6, RTM_NEWADDRLABEL, ip6addrlbl_newdel, - NULL, NULL); + NULL, RTNL_FLAG_DOIT_UNLOCKED); __rtnl_register(PF_INET6, RTM_DELADDRLABEL, ip6addrlbl_newdel, - NULL, NULL); + NULL, RTNL_FLAG_DOIT_UNLOCKED); __rtnl_register(PF_INET6, RTM_GETADDRLABEL, ip6addrlbl_get, - ip6addrlbl_dump, NULL); + ip6addrlbl_dump, RTNL_FLAG_DOIT_UNLOCKED); } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index a88b5b5b79558948dcbad84cbdda99c1d574102e..fe5262fd6aa5c2e270f910a8b0231ec3b2929a81 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -210,7 +210,8 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; np->mc_loop = 1; np->pmtudisc = IPV6_PMTUDISC_WANT; - np->autoflowlabel = ip6_default_np_autolabel(sock_net(sk)); + np->autoflowlabel = ip6_default_np_autolabel(net); + np->repflow = net->ipv6.sysctl.flowlabel_reflect; sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; /* Init the ipv4 part of the socket since we can have sockets @@ -554,6 +555,8 @@ const struct proto_ops inet6_stream_ops = { .recvmsg = inet_recvmsg, /* ok */ .mmap = sock_no_mmap, .sendpage = inet_sendpage, + .sendmsg_locked = tcp_sendmsg_locked, + .sendpage_locked = tcp_sendpage_locked, .splice_read = tcp_splice_read, .read_sock = tcp_read_sock, .peek_len = tcp_peek_len, diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 9ed35473dcb53bd6ae52f8f86e1558410bbcd7b6..89910e2c10f4a63bcd285e28820141266f6d056f 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -226,7 +226,7 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info int tailen = esp->tailen; if (!skb_cloned(skb)) { - if (tailen <= skb_availroom(skb)) { + if (tailen <= skb_tailroom(skb)) { nfrags = 1; trailer = skb; tail = skb_tail_pointer(trailer); @@ -260,8 +260,6 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info kunmap_atomic(vaddr); - spin_unlock_bh(&x->lock); - nfrags = skb_shinfo(skb)->nr_frags; __skb_fill_page_desc(skb, nfrags, page, pfrag->offset, @@ -269,6 +267,9 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info skb_shinfo(skb)->nr_frags = ++nfrags; pfrag->offset = pfrag->offset + allocsize; + + spin_unlock_bh(&x->lock); + nfrags++; skb->len += tailen; @@ -345,7 +346,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info (unsigned char *)esph - skb->data, assoclen + ivlen + esp->clen + alen); if (unlikely(err < 0)) - goto error; + goto error_free; if (!esp->inplace) { int allocsize; @@ -356,7 +357,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info spin_lock_bh(&x->lock); if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) { spin_unlock_bh(&x->lock); - goto error; + goto error_free; } skb_shinfo(skb)->nr_frags = 1; @@ -373,7 +374,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info (unsigned char *)esph - skb->data, assoclen + ivlen + esp->clen + alen); if (unlikely(err < 0)) - goto error; + goto error_free; } if ((x->props.flags & XFRM_STATE_ESN)) @@ -406,8 +407,9 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info if (sg != dsg) esp_ssg_unref(x, tmp); - kfree(tmp); +error_free: + kfree(tmp); error: return err; } @@ -461,28 +463,30 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) return esp6_output_tail(x, skb, &esp); } -int esp6_input_done2(struct sk_buff *skb, int err) +static inline int esp_remove_trailer(struct sk_buff *skb) { struct xfrm_state *x = xfrm_input_state(skb); struct xfrm_offload *xo = xfrm_offload(skb); struct crypto_aead *aead = x->data; - int alen = crypto_aead_authsize(aead); - int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); - int elen = skb->len - hlen; - int hdr_len = skb_network_header_len(skb); - int padlen; + int alen, hlen, elen; + int padlen, trimlen; + __wsum csumdiff; u8 nexthdr[2]; + int ret; - if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) - kfree(ESP_SKB_CB(skb)->tmp); + alen = crypto_aead_authsize(aead); + hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); + elen = skb->len - hlen; - if (unlikely(err)) + if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { + ret = xo->proto; goto out; + } if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) BUG(); - err = -EINVAL; + ret = -EINVAL; padlen = nexthdr[0]; if (padlen + 2 + alen >= elen) { net_dbg_ratelimited("ipsec esp packet is garbage padlen=%d, elen=%d\n", @@ -490,17 +494,46 @@ int esp6_input_done2(struct sk_buff *skb, int err) goto out; } - /* ... check padding bits here. Silly. :-) */ + trimlen = alen + padlen + 2; + if (skb->ip_summed == CHECKSUM_COMPLETE) { + csumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0); + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } + pskb_trim(skb, skb->len - trimlen); - pskb_trim(skb, skb->len - alen - padlen - 2); - __skb_pull(skb, hlen); + ret = nexthdr[1]; + +out: + return ret; +} + +int esp6_input_done2(struct sk_buff *skb, int err) +{ + struct xfrm_state *x = xfrm_input_state(skb); + struct xfrm_offload *xo = xfrm_offload(skb); + struct crypto_aead *aead = x->data; + int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); + int hdr_len = skb_network_header_len(skb); + + if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) + kfree(ESP_SKB_CB(skb)->tmp); + + if (unlikely(err)) + goto out; + + err = esp_remove_trailer(skb); + if (unlikely(err < 0)) + goto out; + + skb_postpull_rcsum(skb, skb_network_header(skb), + skb_network_header_len(skb)); + skb_pull_rcsum(skb, hlen); if (x->props.mode == XFRM_MODE_TUNNEL) skb_reset_transport_header(skb); else skb_set_transport_header(skb, -hdr_len); - err = nexthdr[1]; - /* RFC4303: Drop dummy packets without any error */ if (err == IPPROTO_NONE) err = -EINVAL; diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index f02f131f6435a967de395b9a7069051c93a039d7..333a478aa1610441ce08e3ac82e92d3b48e3222d 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -209,11 +209,13 @@ static struct sk_buff *esp6_gso_segment(struct sk_buff *skb, static int esp6_input_tail(struct xfrm_state *x, struct sk_buff *skb) { struct crypto_aead *aead = x->data; + struct xfrm_offload *xo = xfrm_offload(skb); if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead))) return -EINVAL; - skb->ip_summed = CHECKSUM_NONE; + if (!(xo->flags & CRYPTO_DONE)) + skb->ip_summed = CHECKSUM_NONE; return esp6_input_done2(skb, 0); } @@ -286,7 +288,7 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32)); err = esp6_output_tail(x, skb, &esp); - if (err < 0) + if (err) return err; secpath_reset(skb); @@ -332,3 +334,4 @@ module_init(esp6_offload_init); module_exit(esp6_offload_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert "); +MODULE_ALIAS_XFRM_OFFLOAD_TYPE(AF_INET6, XFRM_PROTO_ESP); diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 4996d734f1d2a8c535aa34f3bd7a7186279a07c2..95516138e861ccbe039e9938a0aa98d21865f953 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -756,6 +756,7 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) goto drop; + IP6CB(skb)->flags |= IP6SKB_JUMBOGRAM; return true; drop: @@ -881,7 +882,7 @@ static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto, (hops - 1) * sizeof(struct in6_addr)); sr_phdr->segments[0] = **addr_p; - *addr_p = &sr_ihdr->segments[hops - 1]; + *addr_p = &sr_ihdr->segments[sr_ihdr->segments_left]; #ifdef CONFIG_IPV6_SEG6_HMAC if (sr_has_hmac(sr_phdr)) { @@ -1173,7 +1174,7 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6, { struct ipv6_sr_hdr *srh = (struct ipv6_sr_hdr *)opt->srcrt; - fl6->daddr = srh->segments[srh->first_segment]; + fl6->daddr = srh->segments[srh->segments_left]; break; } default: diff --git a/net/ipv6/fib6_notifier.c b/net/ipv6/fib6_notifier.c new file mode 100644 index 0000000000000000000000000000000000000000..05f82baaa99ef13dcd419b91fd4460eba54a6ab6 --- /dev/null +++ b/net/ipv6/fib6_notifier.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int call_fib6_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct fib_notifier_info *info) +{ + info->family = AF_INET6; + return call_fib_notifier(nb, net, event_type, info); +} + +int call_fib6_notifiers(struct net *net, enum fib_event_type event_type, + struct fib_notifier_info *info) +{ + info->family = AF_INET6; + return call_fib_notifiers(net, event_type, info); +} + +static unsigned int fib6_seq_read(struct net *net) +{ + return fib6_tables_seq_read(net) + fib6_rules_seq_read(net); +} + +static int fib6_dump(struct net *net, struct notifier_block *nb) +{ + int err; + + err = fib6_rules_dump(net, nb); + if (err) + return err; + + return fib6_tables_dump(net, nb); +} + +static const struct fib_notifier_ops fib6_notifier_ops_template = { + .family = AF_INET6, + .fib_seq_read = fib6_seq_read, + .fib_dump = fib6_dump, + .owner = THIS_MODULE, +}; + +int __net_init fib6_notifier_init(struct net *net) +{ + struct fib_notifier_ops *ops; + + ops = fib_notifier_ops_register(&fib6_notifier_ops_template, net); + if (IS_ERR(ops)) + return PTR_ERR(ops); + net->ipv6.notifier_ops = ops; + + return 0; +} + +void __net_exit fib6_notifier_exit(struct net *net) +{ + fib_notifier_ops_unregister(net->ipv6.notifier_ops); +} diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index ec849d88a66205742b1a58c4959c08eeffc3f6d7..b240f24a6e523c387cfc3320ac056a2544f8cffe 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -14,6 +14,7 @@ */ #include +#include #include #include @@ -29,22 +30,65 @@ struct fib6_rule { u8 tclass; }; -struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, - int flags, pol_lookup_t lookup) +static bool fib6_rule_matchall(const struct fib_rule *rule) +{ + struct fib6_rule *r = container_of(rule, struct fib6_rule, common); + + if (r->dst.plen || r->src.plen || r->tclass) + return false; + return fib_rule_matchall(rule); +} + +bool fib6_rule_default(const struct fib_rule *rule) { - struct fib_lookup_arg arg = { - .lookup_ptr = lookup, - .flags = FIB_LOOKUP_NOREF, - }; + if (!fib6_rule_matchall(rule) || rule->action != FR_ACT_TO_TBL || + rule->l3mdev) + return false; + if (rule->table != RT6_TABLE_LOCAL && rule->table != RT6_TABLE_MAIN) + return false; + return true; +} +EXPORT_SYMBOL_GPL(fib6_rule_default); - /* update flow if oif or iif point to device enslaved to l3mdev */ - l3mdev_update_flow(net, flowi6_to_flowi(fl6)); +int fib6_rules_dump(struct net *net, struct notifier_block *nb) +{ + return fib_rules_dump(net, nb, AF_INET6); +} - fib_rules_lookup(net->ipv6.fib6_rules_ops, - flowi6_to_flowi(fl6), flags, &arg); +unsigned int fib6_rules_seq_read(struct net *net) +{ + return fib_rules_seq_read(net, AF_INET6); +} - if (arg.result) - return arg.result; +struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, + int flags, pol_lookup_t lookup) +{ + if (net->ipv6.fib6_has_custom_rules) { + struct fib_lookup_arg arg = { + .lookup_ptr = lookup, + .flags = FIB_LOOKUP_NOREF, + }; + + /* update flow if oif or iif point to device enslaved to l3mdev */ + l3mdev_update_flow(net, flowi6_to_flowi(fl6)); + + fib_rules_lookup(net->ipv6.fib6_rules_ops, + flowi6_to_flowi(fl6), flags, &arg); + + if (arg.result) + return arg.result; + } else { + struct rt6_info *rt; + + rt = lookup(net, net->ipv6.fib6_local_tbl, fl6, flags); + if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN) + return &rt->dst; + ip6_rt_put(rt); + rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); + if (rt->dst.error != -EAGAIN) + return &rt->dst; + ip6_rt_put(rt); + } dst_hold(&net->ipv6.ip6_null_entry->dst); return &net->ipv6.ip6_null_entry->dst; @@ -214,6 +258,7 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, rule6->dst.plen = frh->dst_len; rule6->tclass = frh->tos; + net->ipv6.fib6_has_custom_rules = true; err = 0; errout: return err; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 8d7b113958b1332be11545069fafa8072a64e6a2..5acb54405b10b637962a7c59c9badb6b4f4f17bd 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -399,6 +399,24 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, return ERR_PTR(err); } +static int icmp6_iif(const struct sk_buff *skb) +{ + int iif = skb->dev->ifindex; + + /* for local traffic to local address, skb dev is the loopback + * device. Check if there is a dst attached to the skb and if so + * get the real device index. + */ + if (unlikely(iif == LOOPBACK_IFINDEX)) { + const struct rt6_info *rt6 = skb_rt6_info(skb); + + if (rt6) + iif = rt6->rt6i_idev->dev->ifindex; + } + + return iif; +} + /* * Send an ICMP message in response to a packet in error */ @@ -459,9 +477,9 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, * Source addr check */ - if (__ipv6_addr_needs_scope_id(addr_type)) - iif = skb->dev->ifindex; - else { + if (__ipv6_addr_needs_scope_id(addr_type)) { + iif = icmp6_iif(skb); + } else { dst = skb_dst(skb); iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev); } @@ -508,6 +526,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, fl6.fl6_icmp_type = type; fl6.fl6_icmp_code = code; fl6.flowi6_uid = sock_net_uid(net, NULL); + fl6.mp_hash = rt6_multipath_hash(&fl6, skb); security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); sk = icmpv6_xmit_lock(net); @@ -682,7 +701,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) fl6.daddr = ipv6_hdr(skb)->saddr; if (saddr) fl6.saddr = *saddr; - fl6.flowi6_oif = skb->dev->ifindex; + fl6.flowi6_oif = icmp6_iif(skb); fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY; fl6.flowi6_mark = mark; fl6.flowi6_uid = sock_net_uid(net, NULL); diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 77f7f8c7d93d67483f241616123380f9d8e6ba84..5bd419c1abc8b7ba3c564eb33ff6611dabcb47fb 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -208,7 +208,7 @@ ila_nf_input(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops ila_nf_hook_ops[] __read_mostly = { +static const struct nf_hook_ops ila_nf_hook_ops[] = { { .hook = ila_nf_input, .pf = NFPROTO_IPV6, diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index b13b8f93079dae620e9e9fe58233baef01ecf84f..b01858f5deb1711f24c0c38cba0a3e61d43b390c 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -56,7 +56,7 @@ struct sock *__inet6_lookup_established(struct net *net, const __be16 sport, const struct in6_addr *daddr, const u16 hnum, - const int dif) + const int dif, const int sdif) { struct sock *sk; const struct hlist_nulls_node *node; @@ -73,12 +73,12 @@ struct sock *__inet6_lookup_established(struct net *net, sk_nulls_for_each_rcu(sk, node, &head->chain) { if (sk->sk_hash != hash) continue; - if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif)) + if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif)) continue; if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) goto out; - if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif))) { + if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))) { sock_gen_put(sk); goto begin; } @@ -96,7 +96,7 @@ EXPORT_SYMBOL(__inet6_lookup_established); static inline int compute_score(struct sock *sk, struct net *net, const unsigned short hnum, const struct in6_addr *daddr, - const int dif, bool exact_dif) + const int dif, const int sdif, bool exact_dif) { int score = -1; @@ -110,9 +110,13 @@ static inline int compute_score(struct sock *sk, struct net *net, score++; } if (sk->sk_bound_dev_if || exact_dif) { - if (sk->sk_bound_dev_if != dif) + bool dev_match = (sk->sk_bound_dev_if == dif || + sk->sk_bound_dev_if == sdif); + + if (exact_dif && !dev_match) return -1; - score++; + if (sk->sk_bound_dev_if && dev_match) + score++; } if (sk->sk_incoming_cpu == raw_smp_processor_id()) score++; @@ -126,7 +130,7 @@ struct sock *inet6_lookup_listener(struct net *net, struct sk_buff *skb, int doff, const struct in6_addr *saddr, const __be16 sport, const struct in6_addr *daddr, - const unsigned short hnum, const int dif) + const unsigned short hnum, const int dif, const int sdif) { unsigned int hash = inet_lhashfn(net, hnum); struct inet_listen_hashbucket *ilb = &hashinfo->listening_hash[hash]; @@ -136,7 +140,7 @@ struct sock *inet6_lookup_listener(struct net *net, u32 phash = 0; sk_for_each(sk, &ilb->head) { - score = compute_score(sk, net, hnum, daddr, dif, exact_dif); + score = compute_score(sk, net, hnum, daddr, dif, sdif, exact_dif); if (score > hiscore) { reuseport = sk->sk_reuseport; if (reuseport) { @@ -171,7 +175,7 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo, bool refcounted; sk = __inet6_lookup(net, hashinfo, skb, doff, saddr, sport, daddr, - ntohs(dport), dif, &refcounted); + ntohs(dport), dif, 0, &refcounted); if (sk && !refcounted && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; return sk; @@ -187,8 +191,9 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, const struct in6_addr *daddr = &sk->sk_v6_rcv_saddr; const struct in6_addr *saddr = &sk->sk_v6_daddr; const int dif = sk->sk_bound_dev_if; - const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport); struct net *net = sock_net(sk); + const int sdif = l3mdev_master_ifindex_by_index(net, dif); + const __portpair ports = INET_COMBINED_PORTS(inet->inet_dport, lport); const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, inet->inet_dport); struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); @@ -203,7 +208,8 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, if (sk2->sk_hash != hash) continue; - if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports, dif))) { + if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports, + dif, sdif))) { if (sk2->sk_state == TCP_TIME_WAIT) { tw = inet_twsk(sk2); if (twsk_unique(sk, sk2, twp)) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ebb299cf72b7e81b77999d43d2e7f83212386f73..e5308d7cbd75c4fb67861082382122d445cf5b74 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -148,12 +149,24 @@ static struct fib6_node *node_alloc(void) return fn; } -static void node_free(struct fib6_node *fn) +static void node_free_immediate(struct fib6_node *fn) { kmem_cache_free(fib6_node_kmem, fn); } -static void rt6_free_pcpu(struct rt6_info *non_pcpu_rt) +static void node_free_rcu(struct rcu_head *head) +{ + struct fib6_node *fn = container_of(head, struct fib6_node, rcu); + + kmem_cache_free(fib6_node_kmem, fn); +} + +static void node_free(struct fib6_node *fn) +{ + call_rcu(&fn->rcu, node_free_rcu); +} + +void rt6_free_pcpu(struct rt6_info *non_pcpu_rt) { int cpu; @@ -176,14 +189,12 @@ static void rt6_free_pcpu(struct rt6_info *non_pcpu_rt) free_percpu(non_pcpu_rt->rt6i_pcpu); non_pcpu_rt->rt6i_pcpu = NULL; } +EXPORT_SYMBOL_GPL(rt6_free_pcpu); -static void rt6_release(struct rt6_info *rt) +static void fib6_free_table(struct fib6_table *table) { - if (atomic_dec_and_test(&rt->rt6i_ref)) { - rt6_free_pcpu(rt); - dst_dev_put(&rt->dst); - dst_release(&rt->dst); - } + inetpeer_invalidate_tree(&table->tb6_peers); + kfree(table); } static void fib6_link_table(struct net *net, struct fib6_table *tb) @@ -302,6 +313,109 @@ static void __net_init fib6_tables_init(struct net *net) #endif +unsigned int fib6_tables_seq_read(struct net *net) +{ + unsigned int h, fib_seq = 0; + + rcu_read_lock(); + for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { + struct hlist_head *head = &net->ipv6.fib_table_hash[h]; + struct fib6_table *tb; + + hlist_for_each_entry_rcu(tb, head, tb6_hlist) { + read_lock_bh(&tb->tb6_lock); + fib_seq += tb->fib_seq; + read_unlock_bh(&tb->tb6_lock); + } + } + rcu_read_unlock(); + + return fib_seq; +} + +static int call_fib6_entry_notifier(struct notifier_block *nb, struct net *net, + enum fib_event_type event_type, + struct rt6_info *rt) +{ + struct fib6_entry_notifier_info info = { + .rt = rt, + }; + + return call_fib6_notifier(nb, net, event_type, &info.info); +} + +static int call_fib6_entry_notifiers(struct net *net, + enum fib_event_type event_type, + struct rt6_info *rt) +{ + struct fib6_entry_notifier_info info = { + .rt = rt, + }; + + rt->rt6i_table->fib_seq++; + return call_fib6_notifiers(net, event_type, &info.info); +} + +struct fib6_dump_arg { + struct net *net; + struct notifier_block *nb; +}; + +static void fib6_rt_dump(struct rt6_info *rt, struct fib6_dump_arg *arg) +{ + if (rt == arg->net->ipv6.ip6_null_entry) + return; + call_fib6_entry_notifier(arg->nb, arg->net, FIB_EVENT_ENTRY_ADD, rt); +} + +static int fib6_node_dump(struct fib6_walker *w) +{ + struct rt6_info *rt; + + for (rt = w->leaf; rt; rt = rt->dst.rt6_next) + fib6_rt_dump(rt, w->args); + w->leaf = NULL; + return 0; +} + +static void fib6_table_dump(struct net *net, struct fib6_table *tb, + struct fib6_walker *w) +{ + w->root = &tb->tb6_root; + read_lock_bh(&tb->tb6_lock); + fib6_walk(net, w); + read_unlock_bh(&tb->tb6_lock); +} + +/* Called with rcu_read_lock() */ +int fib6_tables_dump(struct net *net, struct notifier_block *nb) +{ + struct fib6_dump_arg arg; + struct fib6_walker *w; + unsigned int h; + + w = kzalloc(sizeof(*w), GFP_ATOMIC); + if (!w) + return -ENOMEM; + + w->func = fib6_node_dump; + arg.net = net; + arg.nb = nb; + w->args = &arg; + + for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { + struct hlist_head *head = &net->ipv6.fib_table_hash[h]; + struct fib6_table *tb; + + hlist_for_each_entry_rcu(tb, head, tb6_hlist) + fib6_table_dump(net, tb, w); + } + + kfree(w); + + return 0; +} + static int fib6_dump_node(struct fib6_walker *w) { int res; @@ -601,9 +715,9 @@ static struct fib6_node *fib6_add_1(struct fib6_node *root, if (!in || !ln) { if (in) - node_free(in); + node_free_immediate(in); if (ln) - node_free(ln); + node_free_immediate(ln); return ERR_PTR(-ENOMEM); } @@ -733,8 +847,6 @@ static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, } fn = fn->parent; } - /* No more references are possible at this point. */ - BUG_ON(atomic_read(&rt->rt6i_ref) != 1); } } @@ -877,8 +989,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, rt->dst.rt6_next = iter; *ins = rt; - rt->rt6i_node = fn; + rcu_assign_pointer(rt->rt6i_node, fn); atomic_inc(&rt->rt6i_ref); + call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_ADD, + rt); if (!info->skip_notify) inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags); info->nl_net->ipv6.rt6_stats->fib_rt_entries++; @@ -903,9 +1017,11 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, return err; *ins = rt; - rt->rt6i_node = fn; + rcu_assign_pointer(rt->rt6i_node, fn); rt->dst.rt6_next = iter->dst.rt6_next; atomic_inc(&rt->rt6i_ref); + call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_REPLACE, + rt); if (!info->skip_notify) inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE); if (!(fn->fn_flags & RTN_RTINFO)) { @@ -913,7 +1029,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, fn->fn_flags |= RTN_RTINFO; } nsiblings = iter->rt6i_nsiblings; + iter->rt6i_node = NULL; fib6_purge_rt(iter, fn, info->nl_net); + if (fn->rr_ptr == iter) + fn->rr_ptr = NULL; rt6_release(iter); if (nsiblings) { @@ -925,7 +1044,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, break; if (rt6_qualify_for_ecmp(iter)) { *ins = iter->dst.rt6_next; + iter->rt6i_node = NULL; fib6_purge_rt(iter, fn, info->nl_net); + if (fn->rr_ptr == iter) + fn->rr_ptr = NULL; rt6_release(iter); nsiblings--; } else { @@ -1014,7 +1136,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, /* Create subtree root node */ sfn = node_alloc(); if (!sfn) - goto st_failure; + goto failure; sfn->leaf = info->nl_net->ipv6.ip6_null_entry; atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref); @@ -1031,12 +1153,12 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, if (IS_ERR(sn)) { /* If it is failed, discard just allocated - root, and then (in st_failure) stale node + root, and then (in failure) stale node in main tree. */ - node_free(sfn); + node_free_immediate(sfn); err = PTR_ERR(sn); - goto st_failure; + goto failure; } /* Now link new subtree to main tree */ @@ -1051,7 +1173,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, if (IS_ERR(sn)) { err = PTR_ERR(sn); - goto st_failure; + goto failure; } } @@ -1092,18 +1214,17 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, atomic_inc(&pn->leaf->rt6i_ref); } #endif - /* Always release dst as dst->__refcnt is guaranteed - * to be taken before entering this function - */ - dst_release_immediate(&rt->dst); + goto failure; } return err; -#ifdef CONFIG_IPV6_SUBTREES - /* Subtree creation failed, probably main tree node - is orphan. If it is, shoot it. +failure: + /* fn->leaf could be NULL if fn is an intermediate node and we + * failed to add the new route to it in both subtree creation + * failure and fib6_add_rt2node() failure case. + * In both cases, fib6_repair_tree() should be called to fix + * fn->leaf. */ -st_failure: if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT))) fib6_repair_tree(info->nl_net, fn); /* Always release dst as dst->__refcnt is guaranteed @@ -1111,7 +1232,6 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, */ dst_release_immediate(&rt->dst); return err; -#endif } /* @@ -1459,6 +1579,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, fib6_purge_rt(rt, fn, net); + call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, rt); if (!info->skip_notify) inet6_rt_notify(RTM_DELROUTE, rt, info, 0); rt6_release(rt); @@ -1466,8 +1587,9 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, int fib6_del(struct rt6_info *rt, struct nl_info *info) { + struct fib6_node *fn = rcu_dereference_protected(rt->rt6i_node, + lockdep_is_held(&rt->rt6i_table->tb6_lock)); struct net *net = info->nl_net; - struct fib6_node *fn = rt->rt6i_node; struct rt6_info **rtp; #if RT6_DEBUG >= 2 @@ -1656,7 +1778,9 @@ static int fib6_clean_node(struct fib6_walker *w) if (res) { #if RT6_DEBUG >= 2 pr_debug("%s: del failed: rt=%p@%p err=%d\n", - __func__, rt, rt->rt6i_node, res); + __func__, rt, + rcu_access_pointer(rt->rt6i_node), + res); #endif continue; } @@ -1778,8 +1902,10 @@ static int fib6_age(struct rt6_info *rt, void *arg) } gc_args->more++; } else if (rt->rt6i_flags & RTF_CACHE) { + if (time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) + rt->dst.obsolete = DST_OBSOLETE_KILL; if (atomic_read(&rt->dst.__refcnt) == 1 && - time_after_eq(now, rt->dst.lastuse + gc_args->timeout)) { + rt->dst.obsolete == DST_OBSOLETE_KILL) { RT6_TRACE("aging clone %p\n", rt); return -1; } else if (rt->rt6i_flags & RTF_GATEWAY) { @@ -1839,6 +1965,11 @@ static void fib6_gc_timer_cb(unsigned long arg) static int __net_init fib6_net_init(struct net *net) { size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ; + int err; + + err = fib6_notifier_init(net); + if (err) + return err; spin_lock_init(&net->ipv6.fib6_gc_lock); rwlock_init(&net->ipv6.fib6_walker_lock); @@ -1891,22 +2022,31 @@ static int __net_init fib6_net_init(struct net *net) out_rt6_stats: kfree(net->ipv6.rt6_stats); out_timer: + fib6_notifier_exit(net); return -ENOMEM; } static void fib6_net_exit(struct net *net) { + unsigned int i; + rt6_ifdown(net, NULL); del_timer_sync(&net->ipv6.ip6_fib_timer); -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers); - kfree(net->ipv6.fib6_local_tbl); -#endif - inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers); - kfree(net->ipv6.fib6_main_tbl); + for (i = 0; i < FIB6_TABLE_HASHSZ; i++) { + struct hlist_head *head = &net->ipv6.fib_table_hash[i]; + struct hlist_node *tmp; + struct fib6_table *tb; + + hlist_for_each_entry_safe(tb, tmp, head, tb6_hlist) { + hlist_del(&tb->tb6_hlist); + fib6_free_table(tb); + } + } + kfree(net->ipv6.fib_table_hash); kfree(net->ipv6.rt6_stats); + fib6_notifier_exit(net); } static struct pernet_operations fib6_net_ops = { @@ -1930,7 +2070,7 @@ int __init fib6_init(void) goto out_kmem_cache_create; ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib, - NULL); + 0); if (ret) goto out_unregister_subsys; diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 67ff2aaf5dcbbe9f64482e2a251f061be8007770..1602b491b281123f691a4a7afc4ba5fe0a99ac55 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -432,7 +432,9 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt, } break; case ICMPV6_PKT_TOOBIG: - mtu = be32_to_cpu(info) - offset; + mtu = be32_to_cpu(info) - offset - t->tun_hlen; + if (t->dev->type == ARPHRD_ETHER) + mtu -= ETH_HLEN; if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; t->dev->mtu = mtu; @@ -938,24 +940,25 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev, } static int ip6gre_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, - const void *daddr, const void *saddr, unsigned int len) + unsigned short type, const void *daddr, + const void *saddr, unsigned int len) { struct ip6_tnl *t = netdev_priv(dev); - struct ipv6hdr *ipv6h = skb_push(skb, t->hlen); - __be16 *p = (__be16 *)(ipv6h+1); + struct ipv6hdr *ipv6h; + __be16 *p; - ip6_flow_hdr(ipv6h, 0, - ip6_make_flowlabel(dev_net(dev), skb, - t->fl.u.ip6.flowlabel, true, - &t->fl.u.ip6)); + ipv6h = skb_push(skb, t->hlen + sizeof(*ipv6h)); + ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb, + t->fl.u.ip6.flowlabel, + true, &t->fl.u.ip6)); ipv6h->hop_limit = t->parms.hop_limit; ipv6h->nexthdr = NEXTHDR_GRE; ipv6h->saddr = t->parms.laddr; ipv6h->daddr = t->parms.raddr; - p[0] = t->parms.o_flags; - p[1] = htons(type); + p = (__be16 *)(ipv6h + 1); + p[0] = t->parms.o_flags; + p[1] = htons(type); /* * Set the source hardware address. @@ -1308,6 +1311,7 @@ static void ip6gre_tap_setup(struct net_device *dev) dev->features |= NETIF_F_NETNS_LOCAL; dev->priv_flags &= ~IFF_TX_SKB_SHARING; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + netif_keep_dst(dev); } static bool ip6gre_netlink_encap_parms(struct nlattr *data[], diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 1422d6c083773549d667dc88ffe07d447d5c8e97..43ca864327c73015f1724879d7ee8268a0de513b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -673,8 +673,6 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, *prevhdr = NEXTHDR_FRAGMENT; tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); if (!tmp_hdr) { - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), - IPSTATS_MIB_FRAGFAILS); err = -ENOMEM; goto fail; } @@ -789,8 +787,6 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + hroom + troom, GFP_ATOMIC); if (!frag) { - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), - IPSTATS_MIB_FRAGFAILS); err = -ENOMEM; goto fail; } @@ -1114,69 +1110,6 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, } EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); -static inline int ip6_ufo_append_data(struct sock *sk, - struct sk_buff_head *queue, - int getfrag(void *from, char *to, int offset, int len, - int odd, struct sk_buff *skb), - void *from, int length, int hh_len, int fragheaderlen, - int exthdrlen, int transhdrlen, int mtu, - unsigned int flags, const struct flowi6 *fl6) - -{ - struct sk_buff *skb; - int err; - - /* There is support for UDP large send offload by network - * device, so create one single skb packet containing complete - * udp datagram - */ - skb = skb_peek_tail(queue); - if (!skb) { - skb = sock_alloc_send_skb(sk, - hh_len + fragheaderlen + transhdrlen + 20, - (flags & MSG_DONTWAIT), &err); - if (!skb) - return err; - - /* reserve space for Hardware header */ - skb_reserve(skb, hh_len); - - /* create space for UDP/IP header */ - skb_put(skb, fragheaderlen + transhdrlen); - - /* initialize network header pointer */ - skb_set_network_header(skb, exthdrlen); - - /* initialize protocol header pointer */ - skb->transport_header = skb->network_header + fragheaderlen; - - skb->protocol = htons(ETH_P_IPV6); - skb->csum = 0; - - if (flags & MSG_CONFIRM) - skb_set_dst_pending_confirm(skb, 1); - - __skb_queue_tail(queue, skb); - } else if (skb_is_gso(skb)) { - goto append; - } - - skb->ip_summed = CHECKSUM_PARTIAL; - /* Specify the length of each IPv6 datagram fragment. - * It has to be a multiple of 8. - */ - skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - - sizeof(struct frag_hdr)) & ~7; - skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk), - &fl6->daddr, - &fl6->saddr); - -append: - return skb_append_datato_frags(sk, skb, getfrag, from, - (length - transhdrlen)); -} - static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, gfp_t gfp) { @@ -1385,19 +1318,6 @@ static int __ip6_append_data(struct sock *sk, */ cork->length += length; - if ((((length + (skb ? skb->len : headersize)) > mtu) || - (skb && skb_is_gso(skb))) && - (sk->sk_protocol == IPPROTO_UDP) && - (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && - (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { - err = ip6_ufo_append_data(sk, queue, getfrag, from, length, - hh_len, fragheaderlen, exthdrlen, - transhdrlen, mtu, flags, fl6); - if (err) - goto error; - return 0; - } - if (!skb) goto alloc_new_skb; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 3a0ba2ae4b0f69659638b3e5521dcf9d4393dc75..a1c24443cd9e01de9c6e2d5d68c0f8426e25ceec 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -171,7 +171,7 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_ } t = rcu_dereference(ip6n->collect_md_tun); - if (t) + if (t && t->dev->flags & IFF_UP) return t; t = rcu_dereference(ip6n->tnls_wc[0]); @@ -1043,6 +1043,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, struct dst_entry *dst = NULL, *ndst = NULL; struct net_device *tdev; int mtu; + unsigned int eth_hlen = t->dev->type == ARPHRD_ETHER ? ETH_HLEN : 0; unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen; unsigned int max_headroom = psh_hlen; bool use_cache = false; @@ -1124,7 +1125,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, t->parms.name); goto tx_err_dst_release; } - mtu = dst_mtu(dst) - psh_hlen - t->tun_hlen; + mtu = dst_mtu(dst) - eth_hlen - psh_hlen - t->tun_hlen; if (encap_limit >= 0) { max_headroom += 8; mtu -= 8; @@ -1133,7 +1134,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, mtu = IPV6_MIN_MTU; if (skb_dst(skb) && !t->parms.collect_md) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); - if (skb->len - t->tun_hlen > mtu && !skb_is_gso(skb)) { + if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { *pmtu = mtu; err = -EMSGSIZE; goto tx_err_dst_release; @@ -1184,6 +1185,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, init_tel_txopt(&opt, encap_limit); ipv6_push_frag_opts(skb, &opt.ops, &proto); } + hop_limit = hop_limit ? : ip6_dst_hoplimit(dst); /* Calculate max headroom for all the headers and adjust * needed_headroom if necessary. @@ -2258,6 +2260,9 @@ static int __init ip6_tunnel_init(void) { int err; + if (!ipv6_mod_enabled()) + return -EOPNOTSUPP; + err = register_pernet_device(&ip6_tnl_net_ops); if (err < 0) goto out_pernet; diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 486c2305f53c258c1c68b6f04ba54c17bdcf7820..bcdc2d557de13914b5046dece683614eb5f8f8c8 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -445,6 +445,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) struct dst_entry *dst = skb_dst(skb); struct net_device *tdev; struct xfrm_state *x; + int pkt_len = skb->len; int err = -1; int mtu; @@ -502,7 +503,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); u64_stats_update_begin(&tstats->syncp); - tstats->tx_bytes += skb->len; + tstats->tx_bytes += pkt_len; tstats->tx_packets++; u64_stats_update_end(&tstats->syncp); } else { @@ -1145,33 +1146,6 @@ static struct xfrm6_protocol vti_ipcomp6_protocol __read_mostly = { .priority = 100, }; -static bool is_vti6_tunnel(const struct net_device *dev) -{ - return dev->netdev_ops == &vti6_netdev_ops; -} - -static int vti6_device_event(struct notifier_block *unused, - unsigned long event, void *ptr) -{ - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struct ip6_tnl *t = netdev_priv(dev); - - if (!is_vti6_tunnel(dev)) - return NOTIFY_DONE; - - switch (event) { - case NETDEV_DOWN: - if (!net_eq(t->net, dev_net(dev))) - xfrm_garbage_collect(t->net); - break; - } - return NOTIFY_DONE; -} - -static struct notifier_block vti6_notifier_block __read_mostly = { - .notifier_call = vti6_device_event, -}; - /** * vti6_tunnel_init - register protocol and reserve needed resources * @@ -1182,8 +1156,6 @@ static int __init vti6_tunnel_init(void) const char *msg; int err; - register_netdevice_notifier(&vti6_notifier_block); - msg = "tunnel device"; err = register_pernet_device(&vti6_net_ops); if (err < 0) @@ -1216,7 +1188,6 @@ static int __init vti6_tunnel_init(void) xfrm_proto_esp_failed: unregister_pernet_device(&vti6_net_ops); pernet_dev_failed: - unregister_netdevice_notifier(&vti6_notifier_block); pr_err("vti6 init: failed to register %s\n", msg); return err; } @@ -1231,7 +1202,6 @@ static void __exit vti6_tunnel_cleanup(void) xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH); xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP); unregister_pernet_device(&vti6_net_ops); - unregister_netdevice_notifier(&vti6_notifier_block); } module_init(vti6_tunnel_init); diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 7454850f20984a954682caef51db98f79ede5833..f5500f5444e9845b8b6ed423a7ce63e559dd0c40 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1427,7 +1427,7 @@ int __init ip6_mr_init(void) } #endif rtnl_register(RTNL_FAMILY_IP6MR, RTM_GETROUTE, NULL, - ip6mr_rtm_dumproute, NULL); + ip6mr_rtm_dumproute, 0); return 0; #ifdef CONFIG_IPV6_PIMSM_V2 add_proto_fail: diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 02d795fe3d7f2c5e6e922a25dbbe69c8139919b6..a5e466d4e09310ed99c391fea4bb6126d83fbb56 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -242,7 +242,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, pktopt = xchg(&np->pktoptions, NULL); kfree_skb(pktopt); - sk->sk_destruct = inet_sock_destruct; /* * ... and add it to the refcnt debug socks count * in the new family. -acme diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0327c1f2e6fc5a8d22795afb476a1639bb341e99..266a530414d7be4f1e7be922e465bbab46f7cbac 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -127,7 +127,7 @@ struct neigh_table nd_tbl = { [NEIGH_VAR_BASE_REACHABLE_TIME] = ND_REACHABLE_TIME, [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ, [NEIGH_VAR_GC_STALETIME] = 60 * HZ, - [NEIGH_VAR_QUEUE_LEN_BYTES] = 64 * 1024, + [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX, [NEIGH_VAR_PROXY_QLEN] = 64, [NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ, [NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10, @@ -1779,6 +1779,7 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, static struct notifier_block ndisc_netdev_notifier = { .notifier_call = ndisc_netdev_event, + .priority = ADDRCONF_NOTIFY_PRIORITY - 5, }; #ifdef CONFIG_SYSCTL diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 1f90644056ac784f1a455751796d5fa0d9441915..01bd3ee5ebc685f1c1735dfe375633d49c2c5437 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -39,12 +39,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("IPv6 packet filter"); -#ifdef CONFIG_NETFILTER_DEBUG -#define IP_NF_ASSERT(x) WARN_ON(!(x)) -#else -#define IP_NF_ASSERT(x) -#endif - void *ip6t_alloc_initial_table(const struct xt_table *info) { return xt_alloc_initial_table(ip6t, IP6T); @@ -176,7 +170,7 @@ static const char *const comments[] = { [NF_IP6_TRACE_COMMENT_POLICY] = "policy", }; -static struct nf_loginfo trace_loginfo = { +static const struct nf_loginfo trace_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { @@ -284,7 +278,7 @@ ip6t_do_table(struct sk_buff *skb, acpar.hotdrop = false; acpar.state = state; - IP_NF_ASSERT(table->valid_hooks & (1 << hook)); + WARN_ON(!(table->valid_hooks & (1 << hook))); local_bh_disable(); addend = xt_write_recseq_begin(); @@ -315,7 +309,7 @@ ip6t_do_table(struct sk_buff *skb, const struct xt_entry_match *ematch; struct xt_counters *counter; - IP_NF_ASSERT(e); + WARN_ON(!e); acpar.thoff = 0; if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, &acpar.thoff, &acpar.fragoff, &acpar.hotdrop)) { @@ -335,7 +329,7 @@ ip6t_do_table(struct sk_buff *skb, ADD_COUNTER(*counter, skb->len, 1); t = ip6t_get_target_c(e); - IP_NF_ASSERT(t->u.kernel.target); + WARN_ON(!t->u.kernel.target); #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) /* The packet is traced: log it */ @@ -801,6 +795,7 @@ get_counters(const struct xt_table_info *t, ADD_COUNTER(counters[i], bcnt, pcnt); ++i; + cond_resched(); } } } diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index ce203dd729e0686af769c1b9e4997286d00e01d4..a5cd43d75393db2152fa5a4edb0b505d20fc2f45 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -438,7 +438,7 @@ static unsigned int ipv6_synproxy_hook(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = { +static const struct nf_hook_ops ipv6_synproxy_ops[] = { { .hook = ipv6_synproxy_hook, .pf = NFPROTO_IPV6, diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index 7d2bd940291fd47a68977ec86b7ac0952744c432..991512576c8c8601b54a41d4c7f417500fa5f53d 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c @@ -69,7 +69,7 @@ static unsigned int ip6table_nat_local_fn(void *priv, return nf_nat_ipv6_local_fn(priv, skb, state, ip6table_nat_do_chain); } -static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { +static const struct nf_hook_ops nf_nat_ipv6_ops[] = { /* Before packet filtering, change destination */ { .hook = ip6table_nat_in, diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 4e34024868334427194992d8033d0d58a0361d3b..fe01dc953c56ab1ae421a3b3b9ba93f495d4cfe7 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -67,13 +67,6 @@ static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -static void ipv6_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "src=%pI6 dst=%pI6 ", - tuple->src.u3.ip6, tuple->dst.u3.ip6); -} - static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, unsigned int *dataoff, u_int8_t *protonum) { @@ -191,7 +184,7 @@ static unsigned int ipv6_conntrack_local(void *priv, return nf_conntrack_in(state->net, PF_INET6, state->hook, skb); } -static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { +static const struct nf_hook_ops ipv6_conntrack_ops[] = { { .hook = ipv6_conntrack_in, .pf = NFPROTO_IPV6, @@ -308,11 +301,6 @@ static int ipv6_nlattr_to_tuple(struct nlattr *tb[], return 0; } - -static int ipv6_nlattr_tuple_size(void) -{ - return nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1); -} #endif static int ipv6_hooks_register(struct net *net) @@ -353,16 +341,15 @@ static void ipv6_hooks_unregister(struct net *net) struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { .l3proto = PF_INET6, - .name = "ipv6", .pkt_to_tuple = ipv6_pkt_to_tuple, .invert_tuple = ipv6_invert_tuple, - .print_tuple = ipv6_print_tuple, .get_l4proto = ipv6_get_l4proto, #if IS_ENABLED(CONFIG_NF_CT_NETLINK) .tuple_to_nlattr = ipv6_tuple_to_nlattr, - .nlattr_tuple_size = ipv6_nlattr_tuple_size, .nlattr_to_tuple = ipv6_nlattr_to_tuple, .nla_policy = ipv6_nla_policy, + .nla_size = NLA_ALIGN(NLA_HDRLEN + sizeof(u32[4])) + + NLA_ALIGN(NLA_HDRLEN + sizeof(u32[4])), #endif .net_ns_get = ipv6_hooks_register, .net_ns_put = ipv6_hooks_unregister, @@ -398,25 +385,12 @@ static struct nf_conntrack_l4proto *builtin_l4proto6[] = { static int ipv6_net_init(struct net *net) { - int ret = 0; - - ret = nf_ct_l4proto_pernet_register(net, builtin_l4proto6, - ARRAY_SIZE(builtin_l4proto6)); - if (ret < 0) - return ret; - - ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv6); - if (ret < 0) { - pr_err("nf_conntrack_ipv6: pernet registration failed.\n"); - nf_ct_l4proto_pernet_unregister(net, builtin_l4proto6, - ARRAY_SIZE(builtin_l4proto6)); - } - return ret; + return nf_ct_l4proto_pernet_register(net, builtin_l4proto6, + ARRAY_SIZE(builtin_l4proto6)); } static void ipv6_net_exit(struct net *net) { - nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv6); nf_ct_l4proto_pernet_unregister(net, builtin_l4proto6, ARRAY_SIZE(builtin_l4proto6)); } @@ -434,6 +408,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) need_conntrack(); +#if IS_ENABLED(CONFIG_NF_CT_NETLINK) + if (WARN_ON(nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1) != + nf_conntrack_l3proto_ipv6.nla_size)) + return -EINVAL; +#endif + ret = nf_register_sockopt(&so_getorigdst6); if (ret < 0) { pr_err("Unable to register netfilter socket option\n"); diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index d5f028e33f658bd62deb5b9b0737c33366a22a83..a9e1fd1a853673d222ce6360db359187929c0811 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -84,16 +84,6 @@ static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -/* Print out the per-protocol part of the tuple. */ -static void icmpv6_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "type=%u code=%u id=%u ", - tuple->dst.u.icmp.type, - tuple->dst.u.icmp.code, - ntohs(tuple->src.u.icmp.id)); -} - static unsigned int *icmpv6_get_timeouts(struct net *net) { return &icmpv6_pernet(net)->timeout; @@ -105,7 +95,6 @@ static int icmpv6_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeout) { /* Do not immediately delete the connection after the first @@ -131,11 +120,6 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, pr_debug("icmpv6: can't create new conn with type %u\n", type + 128); nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple); - if (LOG_INVALID(nf_ct_net(ct), IPPROTO_ICMPV6)) - nf_log_packet(nf_ct_net(ct), PF_INET6, 0, skb, NULL, - NULL, NULL, - "nf_ct_icmpv6: invalid new with type %d ", - type + 128); return false; } return true; @@ -144,8 +128,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, static int icmpv6_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, - unsigned int icmp6off, - unsigned int hooknum) + unsigned int icmp6off) { struct nf_conntrack_tuple intuple, origtuple; const struct nf_conntrack_tuple_hash *h; @@ -153,7 +136,7 @@ icmpv6_error_message(struct net *net, struct nf_conn *tmpl, enum ip_conntrack_info ctinfo; struct nf_conntrack_zone tmp; - NF_CT_ASSERT(!skb_nfct(skb)); + WARN_ON(skb_nfct(skb)); /* Are they talking about one of our connections? */ if (!nf_ct_get_tuplepr(skb, @@ -229,7 +212,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl, if (icmp6h->icmp6_type >= 128) return NF_ACCEPT; - return icmpv6_error_message(net, tmpl, skb, dataoff, hooknum); + return icmpv6_error_message(net, tmpl, skb, dataoff); } #if IS_ENABLED(CONFIG_NF_CT_NETLINK) @@ -367,10 +350,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = { .l3proto = PF_INET6, .l4proto = IPPROTO_ICMPV6, - .name = "icmpv6", .pkt_to_tuple = icmpv6_pkt_to_tuple, .invert_tuple = icmpv6_invert_tuple, - .print_tuple = icmpv6_print_tuple, .packet = icmpv6_packet, .get_timeouts = icmpv6_get_timeouts, .new = icmpv6_new, diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 986d4ca38832b17703b09e50209ec133885c7276..b263bf3a19f7aba9452f511030fc8a3dfdeaf0fa 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -622,18 +622,12 @@ EXPORT_SYMBOL_GPL(nf_ct_frag6_gather); static int nf_ct_net_init(struct net *net) { - int res; - net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH; net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT; - res = inet_frags_init_net(&net->nf_frag.frags); - if (res) - return res; - res = nf_ct_frag6_sysctl_register(net); - if (res) - inet_frags_uninit_net(&net->nf_frag.frags); - return res; + inet_frags_init_net(&net->nf_frag.frags); + + return nf_ct_frag6_sysctl_register(net); } static void nf_ct_net_exit(struct net *net) diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index ada60d1a991b7c2e421884f0a8c4361d6f81f10a..b326da59257f60396cda3daddfd643a3cec262a5 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -74,7 +74,7 @@ static unsigned int ipv6_defrag(void *priv, return err == 0 ? NF_ACCEPT : NF_DROP; } -static struct nf_hook_ops ipv6_defrag_ops[] = { +static const struct nf_hook_ops ipv6_defrag_ops[] = { { .hook = ipv6_defrag, .pf = NFPROTO_IPV6, diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c index 97c724224da7b2b12e4dea38c3ff6dcf218f1a3a..b397a8fe88b9391e462146391901a360969547c0 100644 --- a/net/ipv6/netfilter/nf_log_ipv6.c +++ b/net/ipv6/netfilter/nf_log_ipv6.c @@ -25,7 +25,7 @@ #include #include -static struct nf_loginfo default_loginfo = { +static const struct nf_loginfo default_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c index b2b4f031b3a16b1f9f374221396ad02ccc79744e..46d6dba506989756eba4bcb0d51877b3c7b40eb6 100644 --- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c @@ -196,7 +196,7 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conntrack_tuple target; unsigned long statusbit; - NF_CT_ASSERT(ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY); + WARN_ON(ctinfo != IP_CT_RELATED && ctinfo != IP_CT_RELATED_REPLY); if (!skb_make_writable(skb, hdrlen + sizeof(*inside))) return 0; @@ -319,8 +319,8 @@ nf_nat_ipv6_fn(void *priv, struct sk_buff *skb, default: /* ESTABLISHED */ - NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || - ctinfo == IP_CT_ESTABLISHED_REPLY); + WARN_ON(ctinfo != IP_CT_ESTABLISHED && + ctinfo != IP_CT_ESTABLISHED_REPLY); if (nf_nat_oif_changed(state->hook, ctinfo, nat, state->out)) goto oif_changed; } diff --git a/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c b/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c index d7b679037baee5c1c79a477e9774a023ea9550e3..98f61fcb91088cfebd1e77d998f3b445816e0ef2 100644 --- a/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c +++ b/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c @@ -36,8 +36,8 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range *range, struct nf_nat_range newrange; ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || - ctinfo == IP_CT_RELATED_REPLY)); + WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || + ctinfo == IP_CT_RELATED_REPLY))); if (ipv6_dev_get_saddr(nf_ct_net(ct), out, &ipv6_hdr(skb)->daddr, 0, &src) < 0) diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c index 43f91d9b086c7d5c66860ae2eef4ace040acbcff..54b5899543ef5dc158534061afabe957f1e80ed3 100644 --- a/net/ipv6/netfilter/nft_fib_ipv6.c +++ b/net/ipv6/netfilter/nft_fib_ipv6.c @@ -25,9 +25,9 @@ static int get_ifindex(const struct net_device *dev) static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv, const struct nft_pktinfo *pkt, - const struct net_device *dev) + const struct net_device *dev, + struct ipv6hdr *iph) { - const struct ipv6hdr *iph = ipv6_hdr(pkt->skb); int lookup_flags = 0; if (priv->flags & NFTA_FIB_F_DADDR) { @@ -55,7 +55,8 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv, } static u32 __nft_fib6_eval_type(const struct nft_fib *priv, - const struct nft_pktinfo *pkt) + const struct nft_pktinfo *pkt, + struct ipv6hdr *iph) { const struct net_device *dev = NULL; const struct nf_ipv6_ops *v6ops; @@ -77,7 +78,7 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv, else if (priv->flags & NFTA_FIB_F_OIF) dev = nft_out(pkt); - nft_fib6_flowi_init(&fl6, priv, pkt, dev); + nft_fib6_flowi_init(&fl6, priv, pkt, dev, iph); v6ops = nf_get_ipv6_ops(); if (dev && v6ops && v6ops->chk_addr(nft_net(pkt), &fl6.daddr, dev, true)) @@ -131,9 +132,17 @@ void nft_fib6_eval_type(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { const struct nft_fib *priv = nft_expr_priv(expr); + int noff = skb_network_offset(pkt->skb); u32 *dest = ®s->data[priv->dreg]; + struct ipv6hdr *iph, _iph; - *dest = __nft_fib6_eval_type(priv, pkt); + iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph); + if (!iph) { + regs->verdict.code = NFT_BREAK; + return; + } + + *dest = __nft_fib6_eval_type(priv, pkt, iph); } EXPORT_SYMBOL_GPL(nft_fib6_eval_type); @@ -141,8 +150,10 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { const struct nft_fib *priv = nft_expr_priv(expr); + int noff = skb_network_offset(pkt->skb); const struct net_device *oif = NULL; u32 *dest = ®s->data[priv->dreg]; + struct ipv6hdr *iph, _iph; struct flowi6 fl6 = { .flowi6_iif = LOOPBACK_IFINDEX, .flowi6_proto = pkt->tprot, @@ -155,7 +166,13 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, else if (priv->flags & NFTA_FIB_F_OIF) oif = nft_out(pkt); - lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif); + iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph); + if (!iph) { + regs->verdict.code = NFT_BREAK; + return; + } + + lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph); if (nft_hook(pkt) == NF_INET_PRE_ROUTING && nft_fib_is_loopback(pkt->skb, nft_in(pkt))) { diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c index abb2c307fbe8337ce1714e7392072c945ed5af51..a338bbc33cf3cd895fa77e137d6f6389e9a6519c 100644 --- a/net/ipv6/output_core.c +++ b/net/ipv6/output_core.c @@ -86,7 +86,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) while (offset <= packet_len) { struct ipv6_opt_hdr *exthdr; - unsigned int len; switch (**nexthdr) { @@ -112,10 +111,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + offset); - len = ipv6_optlen(exthdr); - if (len + offset >= IPV6_MAXPLEN) + offset += ipv6_optlen(exthdr); + if (offset > IPV6_MAXPLEN) return -EINVAL; - offset += len; *nexthdr = &exthdr->nexthdr; } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 60be012fe7085cc7a199e84333cef5ee95ed1f04..e4462b0ff801b71b8ae3a48f446a0fdd93bb22c2 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -72,7 +72,7 @@ EXPORT_SYMBOL_GPL(raw_v6_hashinfo); struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, unsigned short num, const struct in6_addr *loc_addr, - const struct in6_addr *rmt_addr, int dif) + const struct in6_addr *rmt_addr, int dif, int sdif) { bool is_multicast = ipv6_addr_is_multicast(loc_addr); @@ -86,7 +86,9 @@ struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) continue; - if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) + if (sk->sk_bound_dev_if && + sk->sk_bound_dev_if != dif && + sk->sk_bound_dev_if != sdif) continue; if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { @@ -178,7 +180,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) goto out; net = dev_net(skb->dev); - sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, inet6_iif(skb)); + sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, + inet6_iif(skb), inet6_sdif(skb)); while (sk) { int filtered; @@ -222,7 +225,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) } } sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr, - inet6_iif(skb)); + inet6_iif(skb), inet6_sdif(skb)); } out: read_unlock(&raw_v6_hashinfo.lock); @@ -378,7 +381,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, net = dev_net(skb->dev); while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, - inet6_iif(skb)))) { + inet6_iif(skb), inet6_iif(skb)))) { rawv6_err(sk, skb, NULL, type, code, inner_offset, info); sk = sk_next(sk); diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index e1da5b888cc4901711d573075f8ae4eada7f086e..846012eae52680e00108deb65c356f5024f94552 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -714,19 +714,13 @@ static void ip6_frags_sysctl_unregister(void) static int __net_init ipv6_frags_init_net(struct net *net) { - int res; - net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH; net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; - res = inet_frags_init_net(&net->ipv6.frags); - if (res) - return res; - res = ip6_frags_ns_sysctl_register(net); - if (res) - inet_frags_uninit_net(&net->ipv6.frags); - return res; + inet_frags_init_net(&net->ipv6.frags); + + return ip6_frags_ns_sysctl_register(net); } static void __net_exit ipv6_frags_exit_net(struct net *net) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4d30c96a819dee548ec34704a34b22774fac5da1..26cc9f483b6d282f0a665bfc4c2c206da7981921 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -417,14 +417,11 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, struct net_device *loopback_dev = dev_net(dev)->loopback_dev; - if (dev != loopback_dev) { - if (idev && idev->dev == dev) { - struct inet6_dev *loopback_idev = - in6_dev_get(loopback_dev); - if (loopback_idev) { - rt->rt6i_idev = loopback_idev; - in6_dev_put(idev); - } + if (idev && idev->dev != loopback_dev) { + struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); + if (loopback_idev) { + rt->rt6i_idev = loopback_idev; + in6_dev_put(idev); } } } @@ -443,21 +440,12 @@ static bool rt6_check_expired(const struct rt6_info *rt) if (time_after(jiffies, rt->dst.expires)) return true; } else if (rt->dst.from) { - return rt6_check_expired((struct rt6_info *) rt->dst.from); + return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK || + rt6_check_expired((struct rt6_info *)rt->dst.from); } return false; } -/* Multipath route selection: - * Hash based function using packet header and flowlabel. - * Adapted from fib_info_hashfn() - */ -static int rt6_info_hash_nhsfn(unsigned int candidate_count, - const struct flowi6 *fl6) -{ - return get_hash_from_flowi6(fl6) % candidate_count; -} - static struct rt6_info *rt6_multipath_select(struct rt6_info *match, struct flowi6 *fl6, int oif, int strict) @@ -465,7 +453,13 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match, struct rt6_info *sibling, *next_sibling; int route_choosen; - route_choosen = rt6_info_hash_nhsfn(match->rt6i_nsiblings + 1, fl6); + /* We might have already computed the hash for ICMPv6 errors. In such + * case it will always be non-zero. Otherwise now is the time to do it. + */ + if (!fl6->mp_hash) + fl6->mp_hash = rt6_multipath_hash(fl6, NULL); + + route_choosen = fl6->mp_hash % (match->rt6i_nsiblings + 1); /* Don't change the route, if route_choosen == 0 * (siblings does not include ourself) */ @@ -961,10 +955,34 @@ int ip6_ins_rt(struct rt6_info *rt) return __ip6_ins_rt(rt, &info, &mxc, NULL); } +/* called with rcu_lock held */ +static struct net_device *ip6_rt_get_dev_rcu(struct rt6_info *rt) +{ + struct net_device *dev = rt->dst.dev; + + if (rt->rt6i_flags & RTF_LOCAL) { + /* for copies of local routes, dst->dev needs to be the + * device if it is a master device, the master device if + * device is enslaved, and the loopback as the default + */ + if (netif_is_l3_slave(dev) && + !rt6_need_strict(&rt->rt6i_dst.addr)) + dev = l3mdev_master_dev_rcu(dev); + else if (!netif_is_l3_master(dev)) + dev = dev_net(dev)->loopback_dev; + /* last case is netif_is_l3_master(dev) is true in which + * case we want dev returned to be dev + */ + } + + return dev; +} + static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort, const struct in6_addr *daddr, const struct in6_addr *saddr) { + struct net_device *dev; struct rt6_info *rt; /* @@ -974,8 +992,10 @@ static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort, if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU)) ort = (struct rt6_info *)ort->dst.from; - rt = __ip6_dst_alloc(dev_net(ort->dst.dev), ort->dst.dev, 0); - + rcu_read_lock(); + dev = ip6_rt_get_dev_rcu(ort); + rt = __ip6_dst_alloc(dev_net(dev), dev, 0); + rcu_read_unlock(); if (!rt) return NULL; @@ -1003,11 +1023,13 @@ static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort, static struct rt6_info *ip6_rt_pcpu_alloc(struct rt6_info *rt) { + struct net_device *dev; struct rt6_info *pcpu_rt; - pcpu_rt = __ip6_dst_alloc(dev_net(rt->dst.dev), - rt->dst.dev, rt->dst.flags); - + rcu_read_lock(); + dev = ip6_rt_get_dev_rcu(rt); + pcpu_rt = __ip6_dst_alloc(dev_net(dev), dev, rt->dst.flags); + rcu_read_unlock(); if (!pcpu_rt) return NULL; ip6_rt_copy_init(pcpu_rt, rt); @@ -1189,6 +1211,54 @@ struct dst_entry *ip6_route_input_lookup(struct net *net, } EXPORT_SYMBOL_GPL(ip6_route_input_lookup); +static void ip6_multipath_l3_keys(const struct sk_buff *skb, + struct flow_keys *keys) +{ + const struct ipv6hdr *outer_iph = ipv6_hdr(skb); + const struct ipv6hdr *key_iph = outer_iph; + const struct ipv6hdr *inner_iph; + const struct icmp6hdr *icmph; + struct ipv6hdr _inner_iph; + + if (likely(outer_iph->nexthdr != IPPROTO_ICMPV6)) + goto out; + + icmph = icmp6_hdr(skb); + if (icmph->icmp6_type != ICMPV6_DEST_UNREACH && + icmph->icmp6_type != ICMPV6_PKT_TOOBIG && + icmph->icmp6_type != ICMPV6_TIME_EXCEED && + icmph->icmp6_type != ICMPV6_PARAMPROB) + goto out; + + inner_iph = skb_header_pointer(skb, + skb_transport_offset(skb) + sizeof(*icmph), + sizeof(_inner_iph), &_inner_iph); + if (!inner_iph) + goto out; + + key_iph = inner_iph; +out: + memset(keys, 0, sizeof(*keys)); + keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; + keys->addrs.v6addrs.src = key_iph->saddr; + keys->addrs.v6addrs.dst = key_iph->daddr; + keys->tags.flow_label = ip6_flowinfo(key_iph); + keys->basic.ip_proto = key_iph->nexthdr; +} + +/* if skb is set it will be used and fl6 can be NULL */ +u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb) +{ + struct flow_keys hash_keys; + + if (skb) { + ip6_multipath_l3_keys(skb, &hash_keys); + return flow_hash_from_keys(&hash_keys); + } + + return get_hash_from_flowi6(fl6); +} + void ip6_route_input(struct sk_buff *skb) { const struct ipv6hdr *iph = ipv6_hdr(skb); @@ -1207,6 +1277,8 @@ void ip6_route_input(struct sk_buff *skb) tun_info = skb_tunnel_info(skb); if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX)) fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id; + if (unlikely(fl6.flowi6_proto == IPPROTO_ICMPV6)) + fl6.mp_hash = rt6_multipath_hash(&fl6, skb); skb_dst_drop(skb); skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); } @@ -1292,7 +1364,9 @@ static void rt6_dst_from_metrics_check(struct rt6_info *rt) static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie) { - if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie)) + u32 rt_cookie = 0; + + if (!rt6_get_cookie_safe(rt, &rt_cookie) || rt_cookie != cookie) return NULL; if (rt6_check_expired(rt)) @@ -1360,8 +1434,14 @@ static void ip6_link_failure(struct sk_buff *skb) if (rt->rt6i_flags & RTF_CACHE) { if (dst_hold_safe(&rt->dst)) ip6_del_rt(rt); - } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) { - rt->rt6i_node->fn_sernum = -1; + } else { + struct fib6_node *fn; + + rcu_read_lock(); + fn = rcu_dereference(rt->rt6i_node); + if (fn && (rt->rt6i_flags & RTF_DEFAULT)) + fn->fn_sernum = -1; + rcu_read_unlock(); } } } @@ -1378,7 +1458,8 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 mtu) static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt) { return !(rt->rt6i_flags & RTF_CACHE) && - (rt->rt6i_flags & RTF_PCPU || rt->rt6i_node); + (rt->rt6i_flags & RTF_PCPU || + rcu_access_pointer(rt->rt6i_node)); } static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, @@ -2351,6 +2432,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu if (on_link) nrt->rt6i_flags &= ~RTF_GATEWAY; + nrt->rt6i_protocol = RTPROT_REDIRECT; nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; if (ip6_ins_rt(nrt)) @@ -2461,6 +2543,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net, .fc_dst_len = prefixlen, .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | RTF_UP | RTF_PREF(pref), + .fc_protocol = RTPROT_RA, .fc_nlinfo.portid = 0, .fc_nlinfo.nlh = NULL, .fc_nlinfo.nl_net = net, @@ -2513,6 +2596,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, .fc_ifindex = dev->ifindex, .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), + .fc_protocol = RTPROT_RA, .fc_nlinfo.portid = 0, .fc_nlinfo.nlh = NULL, .fc_nlinfo.nl_net = dev_net(dev), @@ -2688,15 +2772,9 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, { u32 tb_id; struct net *net = dev_net(idev->dev); - struct net_device *dev = net->loopback_dev; + struct net_device *dev = idev->dev; struct rt6_info *rt; - /* use L3 Master device as loopback for host routes if device - * is enslaved and address is not link local or multicast - */ - if (!rt6_need_strict(addr)) - dev = l3mdev_master_dev_rcu(idev->dev) ? : dev; - rt = ip6_dst_alloc(net, dev, DST_NOCOUNT); if (!rt) return ERR_PTR(-ENOMEM); @@ -3327,6 +3405,9 @@ static int rt6_nexthop_info(struct sk_buff *skb, struct rt6_info *rt, goto nla_put_failure; } + if (rt->rt6i_nh_flags & RTNH_F_OFFLOAD) + *flags |= RTNH_F_OFFLOAD; + /* not needed for multipath encoding b/c it has a rtnexthop struct */ if (!skip_oif && rt->dst.dev && nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) @@ -3424,14 +3505,6 @@ static int rt6_fill_node(struct net *net, rtm->rtm_flags = 0; rtm->rtm_scope = RT_SCOPE_UNIVERSE; rtm->rtm_protocol = rt->rt6i_protocol; - if (rt->rt6i_flags & RTF_DYNAMIC) - rtm->rtm_protocol = RTPROT_REDIRECT; - else if (rt->rt6i_flags & RTF_ADDRCONF) { - if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO)) - rtm->rtm_protocol = RTPROT_RA; - else - rtm->rtm_protocol = RTPROT_KERNEL; - } if (rt->rt6i_flags & RTF_CACHE) rtm->rtm_flags |= RTM_F_CLONED; @@ -3613,8 +3686,11 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, struct net_device *dev; int flags = 0; - dev = __dev_get_by_index(net, iif); + rcu_read_lock(); + + dev = dev_get_by_index_rcu(net, iif); if (!dev) { + rcu_read_unlock(); err = -ENODEV; goto errout; } @@ -3626,15 +3702,19 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, if (!fibmatch) dst = ip6_route_input_lookup(net, dev, &fl6, flags); + else + dst = ip6_route_lookup(net, &fl6, 0); + + rcu_read_unlock(); } else { fl6.flowi6_oif = oif; if (!fibmatch) dst = ip6_route_output(net, NULL, &fl6); + else + dst = ip6_route_lookup(net, &fl6, 0); } - if (fibmatch) - dst = ip6_route_lookup(net, &fl6, 0); rt = container_of(dst, struct rt6_info, dst); if (rt->dst.error) { @@ -3729,10 +3809,10 @@ static int ip6_route_dev_notify(struct notifier_block *this, /* NETDEV_UNREGISTER could be fired for multiple times by * netdev_wait_allrefs(). Make sure we only call this once. */ - in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev); + in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES - in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev); - in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev); + in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); + in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); #endif } @@ -3926,6 +4006,7 @@ static int __net_init ip6_route_net_init(struct net *net) ip6_template_metrics, true); #ifdef CONFIG_IPV6_MULTIPLE_TABLES + net->ipv6.fib6_has_custom_rules = false; net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, sizeof(*net->ipv6.ip6_prohibit_entry), GFP_KERNEL); @@ -4101,9 +4182,10 @@ int __init ip6_route_init(void) goto fib6_rules_init; ret = -ENOBUFS; - if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || - __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || - __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) + if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, 0) || + __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, 0) || + __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, + RTNL_FLAG_DOIT_UNLOCKED)) goto out_register_late_subsys; ret = register_netdevice_notifier(&ip6_route_dev_notifier); diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c index 15fba55e3da816424b3f68adf05a2989204ff667..c814077709562cc070d21936c8bf101136d6aefe 100644 --- a/net/ipv6/seg6.c +++ b/net/ipv6/seg6.c @@ -40,7 +40,7 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len) if (((srh->hdrlen + 1) << 3) != len) return false; - if (srh->segments_left != srh->first_segment) + if (srh->segments_left > srh->first_segment) return false; tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4); @@ -456,6 +456,10 @@ int __init seg6_init(void) err = seg6_iptunnel_init(); if (err) goto out_unregister_pernet; + + err = seg6_local_init(); + if (err) + goto out_unregister_pernet; #endif #ifdef CONFIG_IPV6_SEG6_HMAC @@ -471,6 +475,7 @@ int __init seg6_init(void) #ifdef CONFIG_IPV6_SEG6_HMAC out_unregister_iptun: #ifdef CONFIG_IPV6_SEG6_LWTUNNEL + seg6_local_exit(); seg6_iptunnel_exit(); #endif #endif diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c index f950cb53d5e3c9b460bff5f72f108af4f1b2d29a..33fb35cbfac132b1a85cd2c9ce62b4344cbe8afe 100644 --- a/net/ipv6/seg6_hmac.c +++ b/net/ipv6/seg6_hmac.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -110,7 +111,7 @@ static struct seg6_hmac_algo *__hmac_get_algo(u8 alg_id) struct seg6_hmac_algo *algo; int i, alg_count; - alg_count = sizeof(hmac_algos) / sizeof(struct seg6_hmac_algo); + alg_count = ARRAY_SIZE(hmac_algos); for (i = 0; i < alg_count; i++) { algo = &hmac_algos[i]; if (algo->alg_id == alg_id) @@ -360,7 +361,7 @@ static int seg6_hmac_init_algo(void) struct shash_desc *shash; int i, alg_count, cpu; - alg_count = sizeof(hmac_algos) / sizeof(struct seg6_hmac_algo); + alg_count = ARRAY_SIZE(hmac_algos); for (i = 0; i < alg_count; i++) { struct crypto_shash **p_tfm; @@ -421,7 +422,7 @@ void seg6_hmac_exit(void) struct seg6_hmac_algo *algo = NULL; int i, alg_count, cpu; - alg_count = sizeof(hmac_algos) / sizeof(struct seg6_hmac_algo); + alg_count = ARRAY_SIZE(hmac_algos); for (i = 0; i < alg_count; i++) { algo = &hmac_algos[i]; for_each_possible_cpu(cpu) { diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index 264d772d3c7d303bd0cc0520702a54e3b3e8671e..bd6cc688bd199ae98cc1be8d0851b08cb6709486 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c @@ -91,7 +91,7 @@ static void set_tun_src(struct net *net, struct net_device *dev, } /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ -static int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) +int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) { struct net *net = dev_net(skb_dst(skb)->dev); struct ipv6hdr *hdr, *inner_hdr; @@ -116,15 +116,22 @@ static int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) * hlim will be decremented in ip6_forward() afterwards and * decapsulation will overwrite inner hlim with outer hlim */ - ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)), - ip6_flowlabel(inner_hdr)); - hdr->hop_limit = inner_hdr->hop_limit; + + if (skb->protocol == htons(ETH_P_IPV6)) { + ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)), + ip6_flowlabel(inner_hdr)); + hdr->hop_limit = inner_hdr->hop_limit; + } else { + ip6_flow_hdr(hdr, 0, 0); + hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb)); + } + hdr->nexthdr = NEXTHDR_ROUTING; isrh = (void *)hdr + sizeof(*hdr); memcpy(isrh, osrh, hdrlen); - isrh->nexthdr = NEXTHDR_IPV6; + isrh->nexthdr = proto; hdr->daddr = isrh->segments[isrh->first_segment]; set_tun_src(net, skb->dev, &hdr->daddr, &hdr->saddr); @@ -141,10 +148,10 @@ static int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) return 0; } +EXPORT_SYMBOL_GPL(seg6_do_srh_encap); /* insert an SRH within an IPv6 packet, just after the IPv6 header */ -#ifdef CONFIG_IPV6_SEG6_INLINE -static int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) +int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) { struct ipv6hdr *hdr, *oldhdr; struct ipv6_sr_hdr *isrh; @@ -193,13 +200,13 @@ static int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) return 0; } -#endif +EXPORT_SYMBOL_GPL(seg6_do_srh_inline); static int seg6_do_srh(struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); struct seg6_iptunnel_encap *tinfo; - int err = 0; + int proto, err = 0; tinfo = seg6_encap_lwtunnel(dst->lwtstate); @@ -209,19 +216,47 @@ static int seg6_do_srh(struct sk_buff *skb) } switch (tinfo->mode) { -#ifdef CONFIG_IPV6_SEG6_INLINE case SEG6_IPTUN_MODE_INLINE: + if (skb->protocol != htons(ETH_P_IPV6)) + return -EINVAL; + err = seg6_do_srh_inline(skb, tinfo->srh); + if (err) + return err; + skb_reset_inner_headers(skb); break; -#endif case SEG6_IPTUN_MODE_ENCAP: - err = seg6_do_srh_encap(skb, tinfo->srh); + if (skb->protocol == htons(ETH_P_IPV6)) + proto = IPPROTO_IPV6; + else if (skb->protocol == htons(ETH_P_IP)) + proto = IPPROTO_IPIP; + else + return -EINVAL; + + err = seg6_do_srh_encap(skb, tinfo->srh, proto); + if (err) + return err; + + skb->protocol = htons(ETH_P_IPV6); break; - } + case SEG6_IPTUN_MODE_L2ENCAP: + if (!skb_mac_header_was_set(skb)) + return -EINVAL; - if (err) - return err; + if (pskb_expand_head(skb, skb->mac_len, 0, GFP_ATOMIC) < 0) + return -ENOMEM; + + skb_mac_header_rebuild(skb); + skb_push(skb, skb->mac_len); + + err = seg6_do_srh_encap(skb, tinfo->srh, NEXTHDR_NONE); + if (err) + return err; + + skb->protocol = htons(ETH_P_IPV6); + break; + } ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); skb_set_transport_header(skb, sizeof(struct ipv6hdr)); @@ -336,6 +371,9 @@ static int seg6_build_state(struct nlattr *nla, struct seg6_lwt *slwt; int err; + if (family != AF_INET && family != AF_INET6) + return -EINVAL; + err = nla_parse_nested(tb, SEG6_IPTUNNEL_MAX, nla, seg6_iptunnel_policy, extack); @@ -357,12 +395,15 @@ static int seg6_build_state(struct nlattr *nla, return -EINVAL; switch (tuninfo->mode) { -#ifdef CONFIG_IPV6_SEG6_INLINE case SEG6_IPTUN_MODE_INLINE: + if (family != AF_INET6) + return -EINVAL; + break; -#endif case SEG6_IPTUN_MODE_ENCAP: break; + case SEG6_IPTUN_MODE_L2ENCAP: + break; default: return -EINVAL; } @@ -386,8 +427,11 @@ static int seg6_build_state(struct nlattr *nla, memcpy(&slwt->tuninfo, tuninfo, tuninfo_len); newts->type = LWTUNNEL_ENCAP_SEG6; - newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT | - LWTUNNEL_STATE_INPUT_REDIRECT; + newts->flags |= LWTUNNEL_STATE_INPUT_REDIRECT; + + if (tuninfo->mode != SEG6_IPTUN_MODE_L2ENCAP) + newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT; + newts->headroom = seg6_lwt_headroom(tuninfo); *ts = newts; diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c new file mode 100644 index 0000000000000000000000000000000000000000..825b8e01f94762c483f20e41218cdd26e83b4d50 --- /dev/null +++ b/net/ipv6/seg6_local.c @@ -0,0 +1,934 @@ +/* + * SR-IPv6 implementation + * + * Author: + * David Lebrun + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_IPV6_SEG6_HMAC +#include +#endif +#include + +struct seg6_local_lwt; + +struct seg6_action_desc { + int action; + unsigned long attrs; + int (*input)(struct sk_buff *skb, struct seg6_local_lwt *slwt); + int static_headroom; +}; + +struct seg6_local_lwt { + int action; + struct ipv6_sr_hdr *srh; + int table; + struct in_addr nh4; + struct in6_addr nh6; + int iif; + int oif; + + int headroom; + struct seg6_action_desc *desc; +}; + +static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt) +{ + return (struct seg6_local_lwt *)lwt->data; +} + +static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb) +{ + struct ipv6_sr_hdr *srh; + int len, srhoff = 0; + + if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0) + return NULL; + + if (!pskb_may_pull(skb, srhoff + sizeof(*srh))) + return NULL; + + srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); + + len = (srh->hdrlen + 1) << 3; + + if (!pskb_may_pull(skb, srhoff + len)) + return NULL; + + if (!seg6_validate_srh(srh, len)) + return NULL; + + return srh; +} + +static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb) +{ + struct ipv6_sr_hdr *srh; + + srh = get_srh(skb); + if (!srh) + return NULL; + + if (srh->segments_left == 0) + return NULL; + +#ifdef CONFIG_IPV6_SEG6_HMAC + if (!seg6_hmac_validate_skb(skb)) + return NULL; +#endif + + return srh; +} + +static bool decap_and_validate(struct sk_buff *skb, int proto) +{ + struct ipv6_sr_hdr *srh; + unsigned int off = 0; + + srh = get_srh(skb); + if (srh && srh->segments_left > 0) + return false; + +#ifdef CONFIG_IPV6_SEG6_HMAC + if (srh && !seg6_hmac_validate_skb(skb)) + return false; +#endif + + if (ipv6_find_hdr(skb, &off, proto, NULL, NULL) < 0) + return false; + + if (!pskb_pull(skb, off)) + return false; + + skb_postpull_rcsum(skb, skb_network_header(skb), off); + + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb->encapsulation = 0; + + return true; +} + +static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr) +{ + struct in6_addr *addr; + + srh->segments_left--; + addr = srh->segments + srh->segments_left; + *daddr = *addr; +} + +static void lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr, + u32 tbl_id) +{ + struct net *net = dev_net(skb->dev); + struct ipv6hdr *hdr = ipv6_hdr(skb); + int flags = RT6_LOOKUP_F_HAS_SADDR; + struct dst_entry *dst = NULL; + struct rt6_info *rt; + struct flowi6 fl6; + + fl6.flowi6_iif = skb->dev->ifindex; + fl6.daddr = nhaddr ? *nhaddr : hdr->daddr; + fl6.saddr = hdr->saddr; + fl6.flowlabel = ip6_flowinfo(hdr); + fl6.flowi6_mark = skb->mark; + fl6.flowi6_proto = hdr->nexthdr; + + if (nhaddr) + fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH; + + if (!tbl_id) { + dst = ip6_route_input_lookup(net, skb->dev, &fl6, flags); + } else { + struct fib6_table *table; + + table = fib6_get_table(net, tbl_id); + if (!table) + goto out; + + rt = ip6_pol_route(net, table, 0, &fl6, flags); + dst = &rt->dst; + } + + if (dst && dst->dev->flags & IFF_LOOPBACK && !dst->error) { + dst_release(dst); + dst = NULL; + } + +out: + if (!dst) { + rt = net->ipv6.ip6_blk_hole_entry; + dst = &rt->dst; + dst_hold(dst); + } + + skb_dst_drop(skb); + skb_dst_set(skb, dst); +} + +/* regular endpoint function */ +static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + + srh = get_and_validate_srh(skb); + if (!srh) + goto drop; + + advance_nextseg(srh, &ipv6_hdr(skb)->daddr); + + lookup_nexthop(skb, NULL, 0); + + return dst_input(skb); + +drop: + kfree_skb(skb); + return -EINVAL; +} + +/* regular endpoint, and forward to specified nexthop */ +static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + + srh = get_and_validate_srh(skb); + if (!srh) + goto drop; + + advance_nextseg(srh, &ipv6_hdr(skb)->daddr); + + lookup_nexthop(skb, &slwt->nh6, 0); + + return dst_input(skb); + +drop: + kfree_skb(skb); + return -EINVAL; +} + +static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + + srh = get_and_validate_srh(skb); + if (!srh) + goto drop; + + advance_nextseg(srh, &ipv6_hdr(skb)->daddr); + + lookup_nexthop(skb, NULL, slwt->table); + + return dst_input(skb); + +drop: + kfree_skb(skb); + return -EINVAL; +} + +/* decapsulate and forward inner L2 frame on specified interface */ +static int input_action_end_dx2(struct sk_buff *skb, + struct seg6_local_lwt *slwt) +{ + struct net *net = dev_net(skb->dev); + struct net_device *odev; + struct ethhdr *eth; + + if (!decap_and_validate(skb, NEXTHDR_NONE)) + goto drop; + + if (!pskb_may_pull(skb, ETH_HLEN)) + goto drop; + + skb_reset_mac_header(skb); + eth = (struct ethhdr *)skb->data; + + /* To determine the frame's protocol, we assume it is 802.3. This avoids + * a call to eth_type_trans(), which is not really relevant for our + * use case. + */ + if (!eth_proto_is_802_3(eth->h_proto)) + goto drop; + + odev = dev_get_by_index_rcu(net, slwt->oif); + if (!odev) + goto drop; + + /* As we accept Ethernet frames, make sure the egress device is of + * the correct type. + */ + if (odev->type != ARPHRD_ETHER) + goto drop; + + if (!(odev->flags & IFF_UP) || !netif_carrier_ok(odev)) + goto drop; + + skb_orphan(skb); + + if (skb_warn_if_lro(skb)) + goto drop; + + skb_forward_csum(skb); + + if (skb->len - ETH_HLEN > odev->mtu) + goto drop; + + skb->dev = odev; + skb->protocol = eth->h_proto; + + return dev_queue_xmit(skb); + +drop: + kfree_skb(skb); + return -EINVAL; +} + +/* decapsulate and forward to specified nexthop */ +static int input_action_end_dx6(struct sk_buff *skb, + struct seg6_local_lwt *slwt) +{ + struct in6_addr *nhaddr = NULL; + + /* this function accepts IPv6 encapsulated packets, with either + * an SRH with SL=0, or no SRH. + */ + + if (!decap_and_validate(skb, IPPROTO_IPV6)) + goto drop; + + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) + goto drop; + + /* The inner packet is not associated to any local interface, + * so we do not call netif_rx(). + * + * If slwt->nh6 is set to ::, then lookup the nexthop for the + * inner packet's DA. Otherwise, use the specified nexthop. + */ + + if (!ipv6_addr_any(&slwt->nh6)) + nhaddr = &slwt->nh6; + + lookup_nexthop(skb, nhaddr, 0); + + return dst_input(skb); +drop: + kfree_skb(skb); + return -EINVAL; +} + +static int input_action_end_dx4(struct sk_buff *skb, + struct seg6_local_lwt *slwt) +{ + struct iphdr *iph; + __be32 nhaddr; + int err; + + if (!decap_and_validate(skb, IPPROTO_IPIP)) + goto drop; + + if (!pskb_may_pull(skb, sizeof(struct iphdr))) + goto drop; + + skb->protocol = htons(ETH_P_IP); + + iph = ip_hdr(skb); + + nhaddr = slwt->nh4.s_addr ?: iph->daddr; + + skb_dst_drop(skb); + + err = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev); + if (err) + goto drop; + + return dst_input(skb); + +drop: + kfree_skb(skb); + return -EINVAL; +} + +static int input_action_end_dt6(struct sk_buff *skb, + struct seg6_local_lwt *slwt) +{ + if (!decap_and_validate(skb, IPPROTO_IPV6)) + goto drop; + + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) + goto drop; + + lookup_nexthop(skb, NULL, slwt->table); + + return dst_input(skb); + +drop: + kfree_skb(skb); + return -EINVAL; +} + +/* push an SRH on top of the current one */ +static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + int err = -EINVAL; + + srh = get_and_validate_srh(skb); + if (!srh) + goto drop; + + err = seg6_do_srh_inline(skb, slwt->srh); + if (err) + goto drop; + + ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); + skb_set_transport_header(skb, sizeof(struct ipv6hdr)); + + lookup_nexthop(skb, NULL, 0); + + return dst_input(skb); + +drop: + kfree_skb(skb); + return err; +} + +/* encapsulate within an outer IPv6 header and a specified SRH */ +static int input_action_end_b6_encap(struct sk_buff *skb, + struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + int err = -EINVAL; + + srh = get_and_validate_srh(skb); + if (!srh) + goto drop; + + advance_nextseg(srh, &ipv6_hdr(skb)->daddr); + + skb_reset_inner_headers(skb); + skb->encapsulation = 1; + + err = seg6_do_srh_encap(skb, slwt->srh, IPPROTO_IPV6); + if (err) + goto drop; + + ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); + skb_set_transport_header(skb, sizeof(struct ipv6hdr)); + + lookup_nexthop(skb, NULL, 0); + + return dst_input(skb); + +drop: + kfree_skb(skb); + return err; +} + +static struct seg6_action_desc seg6_action_table[] = { + { + .action = SEG6_LOCAL_ACTION_END, + .attrs = 0, + .input = input_action_end, + }, + { + .action = SEG6_LOCAL_ACTION_END_X, + .attrs = (1 << SEG6_LOCAL_NH6), + .input = input_action_end_x, + }, + { + .action = SEG6_LOCAL_ACTION_END_T, + .attrs = (1 << SEG6_LOCAL_TABLE), + .input = input_action_end_t, + }, + { + .action = SEG6_LOCAL_ACTION_END_DX2, + .attrs = (1 << SEG6_LOCAL_OIF), + .input = input_action_end_dx2, + }, + { + .action = SEG6_LOCAL_ACTION_END_DX6, + .attrs = (1 << SEG6_LOCAL_NH6), + .input = input_action_end_dx6, + }, + { + .action = SEG6_LOCAL_ACTION_END_DX4, + .attrs = (1 << SEG6_LOCAL_NH4), + .input = input_action_end_dx4, + }, + { + .action = SEG6_LOCAL_ACTION_END_DT6, + .attrs = (1 << SEG6_LOCAL_TABLE), + .input = input_action_end_dt6, + }, + { + .action = SEG6_LOCAL_ACTION_END_B6, + .attrs = (1 << SEG6_LOCAL_SRH), + .input = input_action_end_b6, + }, + { + .action = SEG6_LOCAL_ACTION_END_B6_ENCAP, + .attrs = (1 << SEG6_LOCAL_SRH), + .input = input_action_end_b6_encap, + .static_headroom = sizeof(struct ipv6hdr), + } +}; + +static struct seg6_action_desc *__get_action_desc(int action) +{ + struct seg6_action_desc *desc; + int i, count; + + count = sizeof(seg6_action_table) / sizeof(struct seg6_action_desc); + for (i = 0; i < count; i++) { + desc = &seg6_action_table[i]; + if (desc->action == action) + return desc; + } + + return NULL; +} + +static int seg6_local_input(struct sk_buff *skb) +{ + struct dst_entry *orig_dst = skb_dst(skb); + struct seg6_action_desc *desc; + struct seg6_local_lwt *slwt; + + if (skb->protocol != htons(ETH_P_IPV6)) { + kfree_skb(skb); + return -EINVAL; + } + + slwt = seg6_local_lwtunnel(orig_dst->lwtstate); + desc = slwt->desc; + + return desc->input(skb, slwt); +} + +static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = { + [SEG6_LOCAL_ACTION] = { .type = NLA_U32 }, + [SEG6_LOCAL_SRH] = { .type = NLA_BINARY }, + [SEG6_LOCAL_TABLE] = { .type = NLA_U32 }, + [SEG6_LOCAL_NH4] = { .type = NLA_BINARY, + .len = sizeof(struct in_addr) }, + [SEG6_LOCAL_NH6] = { .type = NLA_BINARY, + .len = sizeof(struct in6_addr) }, + [SEG6_LOCAL_IIF] = { .type = NLA_U32 }, + [SEG6_LOCAL_OIF] = { .type = NLA_U32 }, +}; + +static int parse_nla_srh(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + int len; + + srh = nla_data(attrs[SEG6_LOCAL_SRH]); + len = nla_len(attrs[SEG6_LOCAL_SRH]); + + /* SRH must contain at least one segment */ + if (len < sizeof(*srh) + sizeof(struct in6_addr)) + return -EINVAL; + + if (!seg6_validate_srh(srh, len)) + return -EINVAL; + + slwt->srh = kmalloc(len, GFP_KERNEL); + if (!slwt->srh) + return -ENOMEM; + + memcpy(slwt->srh, srh, len); + + slwt->headroom += len; + + return 0; +} + +static int put_nla_srh(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct ipv6_sr_hdr *srh; + struct nlattr *nla; + int len; + + srh = slwt->srh; + len = (srh->hdrlen + 1) << 3; + + nla = nla_reserve(skb, SEG6_LOCAL_SRH, len); + if (!nla) + return -EMSGSIZE; + + memcpy(nla_data(nla), srh, len); + + return 0; +} + +static int cmp_nla_srh(struct seg6_local_lwt *a, struct seg6_local_lwt *b) +{ + int len = (a->srh->hdrlen + 1) << 3; + + if (len != ((b->srh->hdrlen + 1) << 3)) + return 1; + + return memcmp(a->srh, b->srh, len); +} + +static int parse_nla_table(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]); + + return 0; +} + +static int put_nla_table(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table)) + return -EMSGSIZE; + + return 0; +} + +static int cmp_nla_table(struct seg6_local_lwt *a, struct seg6_local_lwt *b) +{ + if (a->table != b->table) + return 1; + + return 0; +} + +static int parse_nla_nh4(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]), + sizeof(struct in_addr)); + + return 0; +} + +static int put_nla_nh4(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct nlattr *nla; + + nla = nla_reserve(skb, SEG6_LOCAL_NH4, sizeof(struct in_addr)); + if (!nla) + return -EMSGSIZE; + + memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr)); + + return 0; +} + +static int cmp_nla_nh4(struct seg6_local_lwt *a, struct seg6_local_lwt *b) +{ + return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr)); +} + +static int parse_nla_nh6(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]), + sizeof(struct in6_addr)); + + return 0; +} + +static int put_nla_nh6(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + struct nlattr *nla; + + nla = nla_reserve(skb, SEG6_LOCAL_NH6, sizeof(struct in6_addr)); + if (!nla) + return -EMSGSIZE; + + memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr)); + + return 0; +} + +static int cmp_nla_nh6(struct seg6_local_lwt *a, struct seg6_local_lwt *b) +{ + return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr)); +} + +static int parse_nla_iif(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]); + + return 0; +} + +static int put_nla_iif(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif)) + return -EMSGSIZE; + + return 0; +} + +static int cmp_nla_iif(struct seg6_local_lwt *a, struct seg6_local_lwt *b) +{ + if (a->iif != b->iif) + return 1; + + return 0; +} + +static int parse_nla_oif(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]); + + return 0; +} + +static int put_nla_oif(struct sk_buff *skb, struct seg6_local_lwt *slwt) +{ + if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif)) + return -EMSGSIZE; + + return 0; +} + +static int cmp_nla_oif(struct seg6_local_lwt *a, struct seg6_local_lwt *b) +{ + if (a->oif != b->oif) + return 1; + + return 0; +} + +struct seg6_action_param { + int (*parse)(struct nlattr **attrs, struct seg6_local_lwt *slwt); + int (*put)(struct sk_buff *skb, struct seg6_local_lwt *slwt); + int (*cmp)(struct seg6_local_lwt *a, struct seg6_local_lwt *b); +}; + +static struct seg6_action_param seg6_action_params[SEG6_LOCAL_MAX + 1] = { + [SEG6_LOCAL_SRH] = { .parse = parse_nla_srh, + .put = put_nla_srh, + .cmp = cmp_nla_srh }, + + [SEG6_LOCAL_TABLE] = { .parse = parse_nla_table, + .put = put_nla_table, + .cmp = cmp_nla_table }, + + [SEG6_LOCAL_NH4] = { .parse = parse_nla_nh4, + .put = put_nla_nh4, + .cmp = cmp_nla_nh4 }, + + [SEG6_LOCAL_NH6] = { .parse = parse_nla_nh6, + .put = put_nla_nh6, + .cmp = cmp_nla_nh6 }, + + [SEG6_LOCAL_IIF] = { .parse = parse_nla_iif, + .put = put_nla_iif, + .cmp = cmp_nla_iif }, + + [SEG6_LOCAL_OIF] = { .parse = parse_nla_oif, + .put = put_nla_oif, + .cmp = cmp_nla_oif }, +}; + +static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt) +{ + struct seg6_action_param *param; + struct seg6_action_desc *desc; + int i, err; + + desc = __get_action_desc(slwt->action); + if (!desc) + return -EINVAL; + + if (!desc->input) + return -EOPNOTSUPP; + + slwt->desc = desc; + slwt->headroom += desc->static_headroom; + + for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { + if (desc->attrs & (1 << i)) { + if (!attrs[i]) + return -EINVAL; + + param = &seg6_action_params[i]; + + err = param->parse(attrs, slwt); + if (err < 0) + return err; + } + } + + return 0; +} + +static int seg6_local_build_state(struct nlattr *nla, unsigned int family, + const void *cfg, struct lwtunnel_state **ts, + struct netlink_ext_ack *extack) +{ + struct nlattr *tb[SEG6_LOCAL_MAX + 1]; + struct lwtunnel_state *newts; + struct seg6_local_lwt *slwt; + int err; + + if (family != AF_INET6) + return -EINVAL; + + err = nla_parse_nested(tb, SEG6_LOCAL_MAX, nla, seg6_local_policy, + extack); + + if (err < 0) + return err; + + if (!tb[SEG6_LOCAL_ACTION]) + return -EINVAL; + + newts = lwtunnel_state_alloc(sizeof(*slwt)); + if (!newts) + return -ENOMEM; + + slwt = seg6_local_lwtunnel(newts); + slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]); + + err = parse_nla_action(tb, slwt); + if (err < 0) + goto out_free; + + newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL; + newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT; + newts->headroom = slwt->headroom; + + *ts = newts; + + return 0; + +out_free: + kfree(slwt->srh); + kfree(newts); + return err; +} + +static void seg6_local_destroy_state(struct lwtunnel_state *lwt) +{ + struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); + + kfree(slwt->srh); +} + +static int seg6_local_fill_encap(struct sk_buff *skb, + struct lwtunnel_state *lwt) +{ + struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); + struct seg6_action_param *param; + int i, err; + + if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action)) + return -EMSGSIZE; + + for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { + if (slwt->desc->attrs & (1 << i)) { + param = &seg6_action_params[i]; + err = param->put(skb, slwt); + if (err < 0) + return err; + } + } + + return 0; +} + +static int seg6_local_get_encap_size(struct lwtunnel_state *lwt) +{ + struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); + unsigned long attrs; + int nlsize; + + nlsize = nla_total_size(4); /* action */ + + attrs = slwt->desc->attrs; + + if (attrs & (1 << SEG6_LOCAL_SRH)) + nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3); + + if (attrs & (1 << SEG6_LOCAL_TABLE)) + nlsize += nla_total_size(4); + + if (attrs & (1 << SEG6_LOCAL_NH4)) + nlsize += nla_total_size(4); + + if (attrs & (1 << SEG6_LOCAL_NH6)) + nlsize += nla_total_size(16); + + if (attrs & (1 << SEG6_LOCAL_IIF)) + nlsize += nla_total_size(4); + + if (attrs & (1 << SEG6_LOCAL_OIF)) + nlsize += nla_total_size(4); + + return nlsize; +} + +static int seg6_local_cmp_encap(struct lwtunnel_state *a, + struct lwtunnel_state *b) +{ + struct seg6_local_lwt *slwt_a, *slwt_b; + struct seg6_action_param *param; + int i; + + slwt_a = seg6_local_lwtunnel(a); + slwt_b = seg6_local_lwtunnel(b); + + if (slwt_a->action != slwt_b->action) + return 1; + + if (slwt_a->desc->attrs != slwt_b->desc->attrs) + return 1; + + for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { + if (slwt_a->desc->attrs & (1 << i)) { + param = &seg6_action_params[i]; + if (param->cmp(slwt_a, slwt_b)) + return 1; + } + } + + return 0; +} + +static const struct lwtunnel_encap_ops seg6_local_ops = { + .build_state = seg6_local_build_state, + .destroy_state = seg6_local_destroy_state, + .input = seg6_local_input, + .fill_encap = seg6_local_fill_encap, + .get_encap_size = seg6_local_get_encap_size, + .cmp_encap = seg6_local_cmp_encap, + .owner = THIS_MODULE, +}; + +int __init seg6_local_init(void) +{ + return lwtunnel_encap_add_ops(&seg6_local_ops, + LWTUNNEL_ENCAP_SEG6_LOCAL); +} + +void seg6_local_exit(void) +{ + lwtunnel_encap_del_ops(&seg6_local_ops, LWTUNNEL_ENCAP_SEG6_LOCAL); +} diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 69c50e737c5462384a4c6a82b500c96621b53392..6fbf8ae5e52cccd10bca77793a368ee3166bf01e 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -90,6 +90,13 @@ static struct ctl_table ipv6_table_template[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "flowlabel_reflect", + .data = &init_net.ipv6.sysctl.flowlabel_reflect, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { } }; @@ -149,6 +156,7 @@ static int __net_init ipv6_sysctl_net_init(struct net *net) ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay; ipv6_table[7].data = &net->ipv6.sysctl.flowlabel_state_ranges; ipv6_table[8].data = &net->ipv6.sysctl.ip_nonlocal_bind; + ipv6_table[9].data = &net->ipv6.sysctl.flowlabel_reflect; ipv6_route_table = ipv6_route_sysctl_init(net); if (!ipv6_route_table) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2521690d62d6e591af594c3629f71f004240ed68..64d94afa427f81fd7a505b1cfd1c0be66c273810 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -350,7 +350,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, sk = __inet6_lookup_established(net, &tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr, ntohs(th->source), - skb->dev->ifindex); + skb->dev->ifindex, inet6_sdif(skb)); if (!sk) { __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), @@ -918,7 +918,8 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) &tcp_hashinfo, NULL, 0, &ipv6h->saddr, th->source, &ipv6h->daddr, - ntohs(th->source), tcp_v6_iif(skb)); + ntohs(th->source), tcp_v6_iif(skb), + tcp_v6_sdif(skb)); if (!sk1) goto out; @@ -1296,7 +1297,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) } } - tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len); + tcp_rcv_established(sk, skb, tcp_hdr(skb)); if (opt_skb) goto ipv6_pktoptions; return 0; @@ -1393,10 +1394,13 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); TCP_SKB_CB(skb)->sacked = 0; + TCP_SKB_CB(skb)->has_rxtstamp = + skb->tstamp || skb_hwtstamps(skb)->hwtstamp; } static int tcp_v6_rcv(struct sk_buff *skb) { + int sdif = inet6_sdif(skb); const struct tcphdr *th; const struct ipv6hdr *hdr; bool refcounted; @@ -1430,7 +1434,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) lookup: sk = __inet6_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), - th->source, th->dest, inet6_iif(skb), + th->source, th->dest, inet6_iif(skb), sdif, &refcounted); if (!sk) goto no_tcp_socket; @@ -1456,7 +1460,9 @@ static int tcp_v6_rcv(struct sk_buff *skb) } sock_hold(sk); refcounted = true; - nsk = tcp_check_req(sk, skb, req, false); + nsk = NULL; + if (!tcp_filter(sk, skb)) + nsk = tcp_check_req(sk, skb, req, false); if (!nsk) { reqsk_put(req); goto discard_and_relse; @@ -1464,8 +1470,6 @@ static int tcp_v6_rcv(struct sk_buff *skb) if (nsk == sk) { reqsk_put(req); tcp_v6_restore_cb(skb); - } else if (tcp_filter(sk, skb)) { - goto discard_and_relse; } else if (tcp_child_process(sk, nsk, skb)) { tcp_v6_send_reset(nsk, skb); goto discard_and_relse; @@ -1505,8 +1509,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) tcp_segs_in(tcp_sk(sk), skb); ret = 0; if (!sock_owned_by_user(sk)) { - if (!tcp_prequeue(sk, skb)) - ret = tcp_v6_do_rcv(sk, skb); + ret = tcp_v6_do_rcv(sk, skb); } else if (tcp_add_backlog(sk, skb)) { goto discard_and_relse; } @@ -1564,7 +1567,8 @@ static int tcp_v6_rcv(struct sk_buff *skb) skb, __tcp_hdrlen(th), &ipv6_hdr(skb)->saddr, th->source, &ipv6_hdr(skb)->daddr, - ntohs(th->dest), tcp_v6_iif(skb)); + ntohs(th->dest), tcp_v6_iif(skb), + sdif); if (sk2) { struct inet_timewait_sock *tw = inet_twsk(sk); inet_twsk_deschedule_put(tw); @@ -1611,7 +1615,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb) sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo, &hdr->saddr, th->source, &hdr->daddr, ntohs(th->dest), - inet6_iif(skb)); + inet6_iif(skb), inet6_sdif(skb)); if (sk) { skb->sk = sk; skb->destructor = sock_edemux; @@ -1945,6 +1949,9 @@ struct proto tcpv6_prot = { .diag_destroy = tcp_abort, }; +/* thinking of making this const? Don't. + * early_demux can change based on sysctl. + */ static struct inet6_protocol tcpv6_protocol = { .early_demux = tcp_v6_early_demux, .early_demux_handler = tcp_v6_early_demux, diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 4a3e65626e8baddf5d7d1c246e6e5fded2b08b8a..40d7234c27b991e54f5cfbacb5d7081e8277ae56 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -129,7 +129,7 @@ static void udp_v6_rehash(struct sock *sk) static int compute_score(struct sock *sk, struct net *net, const struct in6_addr *saddr, __be16 sport, const struct in6_addr *daddr, unsigned short hnum, - int dif, bool exact_dif) + int dif, int sdif, bool exact_dif) { int score; struct inet_sock *inet; @@ -161,9 +161,13 @@ static int compute_score(struct sock *sk, struct net *net, } if (sk->sk_bound_dev_if || exact_dif) { - if (sk->sk_bound_dev_if != dif) + bool dev_match = (sk->sk_bound_dev_if == dif || + sk->sk_bound_dev_if == sdif); + + if (exact_dif && !dev_match) return -1; - score++; + if (sk->sk_bound_dev_if && dev_match) + score++; } if (sk->sk_incoming_cpu == raw_smp_processor_id()) @@ -175,9 +179,9 @@ static int compute_score(struct sock *sk, struct net *net, /* called with rcu_read_lock() */ static struct sock *udp6_lib_lookup2(struct net *net, const struct in6_addr *saddr, __be16 sport, - const struct in6_addr *daddr, unsigned int hnum, int dif, - bool exact_dif, struct udp_hslot *hslot2, - struct sk_buff *skb) + const struct in6_addr *daddr, unsigned int hnum, + int dif, int sdif, bool exact_dif, + struct udp_hslot *hslot2, struct sk_buff *skb) { struct sock *sk, *result; int score, badness, matches = 0, reuseport = 0; @@ -187,7 +191,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, badness = -1; udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { score = compute_score(sk, net, saddr, sport, - daddr, hnum, dif, exact_dif); + daddr, hnum, dif, sdif, exact_dif); if (score > badness) { reuseport = sk->sk_reuseport; if (reuseport) { @@ -214,10 +218,10 @@ static struct sock *udp6_lib_lookup2(struct net *net, /* rcu_read_lock() must be held */ struct sock *__udp6_lib_lookup(struct net *net, - const struct in6_addr *saddr, __be16 sport, - const struct in6_addr *daddr, __be16 dport, - int dif, struct udp_table *udptable, - struct sk_buff *skb) + const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, + int dif, int sdif, struct udp_table *udptable, + struct sk_buff *skb) { struct sock *sk, *result; unsigned short hnum = ntohs(dport); @@ -235,7 +239,7 @@ struct sock *__udp6_lib_lookup(struct net *net, goto begin; result = udp6_lib_lookup2(net, saddr, sport, - daddr, hnum, dif, exact_dif, + daddr, hnum, dif, sdif, exact_dif, hslot2, skb); if (!result) { unsigned int old_slot2 = slot2; @@ -250,7 +254,7 @@ struct sock *__udp6_lib_lookup(struct net *net, goto begin; result = udp6_lib_lookup2(net, saddr, sport, - daddr, hnum, dif, + daddr, hnum, dif, sdif, exact_dif, hslot2, skb); } @@ -261,7 +265,7 @@ struct sock *__udp6_lib_lookup(struct net *net, badness = -1; sk_for_each_rcu(sk, &hslot->head) { score = compute_score(sk, net, saddr, sport, daddr, hnum, dif, - exact_dif); + sdif, exact_dif); if (score > badness) { reuseport = sk->sk_reuseport; if (reuseport) { @@ -291,14 +295,10 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, struct udp_table *udptable) { const struct ipv6hdr *iph = ipv6_hdr(skb); - struct sock *sk; - sk = skb_steal_sock(skb); - if (unlikely(sk)) - return sk; return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, &iph->daddr, dport, inet6_iif(skb), - udptable, skb); + inet6_sdif(skb), udptable, skb); } struct sock *udp6_lib_lookup_skb(struct sk_buff *skb, @@ -308,7 +308,7 @@ struct sock *udp6_lib_lookup_skb(struct sk_buff *skb, return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport, &iph->daddr, dport, inet6_iif(skb), - &udp_table, skb); + inet6_sdif(skb), &udp_table, skb); } EXPORT_SYMBOL_GPL(udp6_lib_lookup_skb); @@ -324,7 +324,7 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be struct sock *sk; sk = __udp6_lib_lookup(net, saddr, sport, daddr, dport, - dif, &udp_table, NULL); + dif, 0, &udp_table, NULL); if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; return sk; @@ -332,6 +332,15 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be EXPORT_SYMBOL_GPL(udp6_lib_lookup); #endif +/* do not use the scratch area len for jumbogram: their length execeeds the + * scratch area space; note that the IP6CB flags is still in the first + * cacheline, so checking for jumbograms is cheap + */ +static int udp6_skb_len(struct sk_buff *skb) +{ + return unlikely(inet6_is_jumbogram(skb)) ? skb->len : udp_skb_len(skb); +} + /* * This should be easy, if there is something there we * return it, otherwise we block. @@ -357,12 +366,13 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, return ipv6_recv_rxpmtu(sk, msg, len, addr_len); try_again: - peeking = off = sk_peek_offset(sk, flags); + peeking = flags & MSG_PEEK; + off = sk_peek_offset(sk, flags); skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err); if (!skb) return err; - ulen = udp_skb_len(skb); + ulen = udp6_skb_len(skb); copied = len; if (copied > ulen - off) copied = ulen - off; @@ -496,7 +506,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, struct net *net = dev_net(skb->dev); sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, - inet6_iif(skb), udptable, skb); + inet6_iif(skb), 0, udptable, skb); if (!sk) { __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); @@ -569,8 +579,7 @@ static __inline__ void udpv6_err(struct sk_buff *skb, static struct static_key udpv6_encap_needed __read_mostly; void udpv6_encap_enable(void) { - if (!static_key_enabled(&udpv6_encap_needed)) - static_key_slow_inc(&udpv6_encap_needed); + static_key_enable(&udpv6_encap_needed); } EXPORT_SYMBOL(udpv6_encap_enable); @@ -762,6 +771,15 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, return 0; } +static void udp6_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) +{ + if (udp_sk_rx_dst_set(sk, dst)) { + const struct rt6_info *rt = (const struct rt6_info *)dst; + + inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt); + } +} + int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, int proto) { @@ -804,6 +822,24 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, if (udp6_csum_init(skb, uh, proto)) goto csum_error; + /* Check if the socket is already available, e.g. due to early demux */ + sk = skb_steal_sock(skb); + if (sk) { + struct dst_entry *dst = skb_dst(skb); + int ret; + + if (unlikely(sk->sk_rx_dst != dst)) + udp6_sk_rx_dst_set(sk, dst); + + ret = udpv6_queue_rcv_skb(sk, skb); + sock_put(sk); + + /* a return value > 0 means to resubmit the input */ + if (ret > 0) + return ret; + return 0; + } + /* * Multicast receive code */ @@ -812,11 +848,6 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, saddr, daddr, udptable, proto); /* Unicast */ - - /* - * check socket cache ... must talk to Alan about his plans - * for sock caches... i'll skip this for now. - */ sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable); if (sk) { int ret; @@ -875,7 +906,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, static struct sock *__udp6_lib_demux_lookup(struct net *net, __be16 loc_port, const struct in6_addr *loc_addr, __be16 rmt_port, const struct in6_addr *rmt_addr, - int dif) + int dif, int sdif) { unsigned short hnum = ntohs(loc_port); unsigned int hash2 = udp6_portaddr_hash(net, loc_addr, hnum); @@ -886,7 +917,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net, udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) { if (sk->sk_state == TCP_ESTABLISHED && - INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif)) + INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif, sdif)) return sk; /* Only check first socket in chain */ break; @@ -901,6 +932,7 @@ static void udp_v6_early_demux(struct sk_buff *skb) struct sock *sk; struct dst_entry *dst; int dif = skb->dev->ifindex; + int sdif = inet6_sdif(skb); if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) @@ -912,7 +944,7 @@ static void udp_v6_early_demux(struct sk_buff *skb) sk = __udp6_lib_demux_lookup(net, uh->dest, &ipv6_hdr(skb)->daddr, uh->source, &ipv6_hdr(skb)->saddr, - dif); + dif, sdif); else return; @@ -983,6 +1015,7 @@ static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb, */ offset = skb_transport_offset(skb); skb->csum = skb_checksum(skb, offset, skb->len - offset, 0); + csum = skb->csum; skb->ip_summed = CHECKSUM_NONE; @@ -1448,6 +1481,9 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, } #endif +/* thinking of making this const? Don't. + * early_demux can change based on sysctl. + */ static struct inet6_protocol udpv6_protocol = { .early_demux = udp_v6_early_demux, .early_demux_handler = udp_v6_early_demux, diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index a2267f80febbb6f31459097f27bd89d51d0f2b11..455fd4e39333233289e9a844de512f200119ff1a 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c @@ -17,109 +17,15 @@ #include #include "ip6_offload.h" -static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, - netdev_features_t features) +static struct sk_buff *udp6_tunnel_segment(struct sk_buff *skb, + netdev_features_t features) { struct sk_buff *segs = ERR_PTR(-EINVAL); - unsigned int mss; - unsigned int unfrag_ip6hlen, unfrag_len; - struct frag_hdr *fptr; - u8 *packet_start, *prevhdr; - u8 nexthdr; - u8 frag_hdr_sz = sizeof(struct frag_hdr); - __wsum csum; - int tnl_hlen; - int err; - - mss = skb_shinfo(skb)->gso_size; - if (unlikely(skb->len <= mss)) - goto out; - - if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { - /* Packet is from an untrusted source, reset gso_segs. */ - - skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss); - - /* Set the IPv6 fragment id if not set yet */ - if (!skb_shinfo(skb)->ip6_frag_id) - ipv6_proxy_select_ident(dev_net(skb->dev), skb); - - segs = NULL; - goto out; - } if (skb->encapsulation && skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL|SKB_GSO_UDP_TUNNEL_CSUM)) segs = skb_udp_tunnel_segment(skb, features, true); - else { - const struct ipv6hdr *ipv6h; - struct udphdr *uh; - - if (!pskb_may_pull(skb, sizeof(struct udphdr))) - goto out; - - /* Do software UFO. Complete and fill in the UDP checksum as HW cannot - * do checksum of UDP packets sent as multiple IP fragments. - */ - - uh = udp_hdr(skb); - ipv6h = ipv6_hdr(skb); - - uh->check = 0; - csum = skb_checksum(skb, 0, skb->len, 0); - uh->check = udp_v6_check(skb->len, &ipv6h->saddr, - &ipv6h->daddr, csum); - if (uh->check == 0) - uh->check = CSUM_MANGLED_0; - - skb->ip_summed = CHECKSUM_NONE; - - /* If there is no outer header we can fake a checksum offload - * due to the fact that we have already done the checksum in - * software prior to segmenting the frame. - */ - if (!skb->encap_hdr_csum) - features |= NETIF_F_HW_CSUM; - - /* Check if there is enough headroom to insert fragment header. */ - tnl_hlen = skb_tnl_header_len(skb); - if (skb->mac_header < (tnl_hlen + frag_hdr_sz)) { - if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz)) - goto out; - } - - /* Find the unfragmentable header and shift it left by frag_hdr_sz - * bytes to insert fragment header. - */ - err = ip6_find_1stfragopt(skb, &prevhdr); - if (err < 0) - return ERR_PTR(err); - unfrag_ip6hlen = err; - nexthdr = *prevhdr; - *prevhdr = NEXTHDR_FRAGMENT; - unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + - unfrag_ip6hlen + tnl_hlen; - packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset; - memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len); - - SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz; - skb->mac_header -= frag_hdr_sz; - skb->network_header -= frag_hdr_sz; - - fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); - fptr->nexthdr = nexthdr; - fptr->reserved = 0; - if (!skb_shinfo(skb)->ip6_frag_id) - ipv6_proxy_select_ident(dev_net(skb->dev), skb); - fptr->identification = skb_shinfo(skb)->ip6_frag_id; - - /* Fragment the skb. ipv6 header and the remaining fields of the - * fragment header are updated in ipv6_gso_segment() - */ - segs = skb_segment(skb, features); - } -out: return segs; } @@ -169,7 +75,7 @@ static int udp6_gro_complete(struct sk_buff *skb, int nhoff) static const struct net_offload udpv6_offload = { .callbacks = { - .gso_segment = udp6_ufo_fragment, + .gso_segment = udp6_tunnel_segment, .gro_receive = udp6_gro_receive, .gro_complete = udp6_gro_complete, }, diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 3ef5d913e7a3b5a7407bb926d5ff354ae778ccb8..f95943a13abc7a520b4d0ee245e9c846d68eaf6e 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -34,6 +34,7 @@ EXPORT_SYMBOL(xfrm6_rcv_spi); int xfrm6_transport_finish(struct sk_buff *skb, int async) { struct xfrm_offload *xo = xfrm_offload(skb); + int nhlen = skb->data - skb_network_header(skb); skb_network_header(skb)[IP6CB(skb)->nhoff] = XFRM_MODE_SKB_CB(skb)->protocol; @@ -43,8 +44,9 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) return 1; #endif - __skb_push(skb, skb->data - skb_network_header(skb)); + __skb_push(skb, nhlen); ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); + skb_postpush_rcsum(skb, skb_network_header(skb), nhlen); if (xo && (xo->flags & XFRM_GRO)) { skb_mac_header_rebuild(skb); diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 79651bc71bf0d48d54e47d75cef0cd3f686e16ab..11d1314ab6c5c027bdefb6a4283773fd58307bd5 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -27,7 +27,8 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, const xfrm_address_t *saddr, - const xfrm_address_t *daddr) + const xfrm_address_t *daddr, + u32 mark) { struct flowi6 fl6; struct dst_entry *dst; @@ -36,6 +37,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif); fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; + fl6.flowi6_mark = mark; memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); if (saddr) memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr)); @@ -52,12 +54,13 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, } static int xfrm6_get_saddr(struct net *net, int oif, - xfrm_address_t *saddr, xfrm_address_t *daddr) + xfrm_address_t *saddr, xfrm_address_t *daddr, + u32 mark) { struct dst_entry *dst; struct net_device *dev; - dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr); + dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark); if (IS_ERR(dst)) return -EHOSTUNREACH; @@ -214,14 +217,6 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) } } -static inline int xfrm6_garbage_collect(struct dst_ops *ops) -{ - struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); - - xfrm_garbage_collect_deferred(net); - return dst_entries_get_fast(ops) > ops->gc_thresh * 2; -} - static void xfrm6_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu) { @@ -279,14 +274,13 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static struct dst_ops xfrm6_dst_ops_template = { .family = AF_INET6, - .gc = xfrm6_garbage_collect, .update_pmtu = xfrm6_update_pmtu, .redirect = xfrm6_redirect, .cow_metrics = dst_cow_metrics_generic, .destroy = xfrm6_dst_destroy, .ifdown = xfrm6_dst_ifdown, .local_out = __ip6_local_out, - .gc_thresh = INT_MAX, + .gc_thresh = 32768, }; static const struct xfrm_policy_afinfo xfrm6_policy_afinfo = { diff --git a/net/kcm/kcmproc.c b/net/kcm/kcmproc.c index c343ac60bf502eca0577f75c06d72f1418559079..c748e8a6a72caf35a8016255a39a4910386bb72d 100644 --- a/net/kcm/kcmproc.c +++ b/net/kcm/kcmproc.c @@ -155,8 +155,8 @@ static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq, seq_printf(seq, " psock-%-5u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8d ", psock->index, - psock->strp.stats.rx_msgs, - psock->strp.stats.rx_bytes, + psock->strp.stats.msgs, + psock->strp.stats.bytes, psock->stats.tx_msgs, psock->stats.tx_bytes, psock->sk->sk_receive_queue.qlen, @@ -170,22 +170,22 @@ static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq, if (psock->tx_stopped) seq_puts(seq, "TxStop "); - if (psock->strp.rx_stopped) + if (psock->strp.stopped) seq_puts(seq, "RxStop "); if (psock->tx_kcm) seq_printf(seq, "Rsvd-%d ", psock->tx_kcm->index); - if (!psock->strp.rx_paused && !psock->ready_rx_msg) { + if (!psock->strp.paused && !psock->ready_rx_msg) { if (psock->sk->sk_receive_queue.qlen) { - if (psock->strp.rx_need_bytes) + if (psock->strp.need_bytes) seq_printf(seq, "RxWait=%u ", - psock->strp.rx_need_bytes); + psock->strp.need_bytes); else seq_printf(seq, "RxWait "); } } else { - if (psock->strp.rx_paused) + if (psock->strp.paused) seq_puts(seq, "RxPause "); if (psock->ready_rx_msg) @@ -371,20 +371,20 @@ static int kcm_stats_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n", "", - strp_stats.rx_msgs, - strp_stats.rx_bytes, + strp_stats.msgs, + strp_stats.bytes, psock_stats.tx_msgs, psock_stats.tx_bytes, psock_stats.reserved, psock_stats.unreserved, - strp_stats.rx_aborts, - strp_stats.rx_interrupted, - strp_stats.rx_unrecov_intr, - strp_stats.rx_mem_fail, - strp_stats.rx_need_more_hdr, - strp_stats.rx_bad_hdr_len, - strp_stats.rx_msg_too_big, - strp_stats.rx_msg_timeouts, + strp_stats.aborts, + strp_stats.interrupted, + strp_stats.unrecov_intr, + strp_stats.mem_fail, + strp_stats.need_more_hdr, + strp_stats.bad_hdr_len, + strp_stats.msg_too_big, + strp_stats.msg_timeouts, psock_stats.tx_aborts); return 0; diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index da49191f7ad0d7edfda0c10762ef5f7471a8f6ac..af4e76ac88ff0817398d1d7460a41f0cd5fe6f30 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c @@ -96,12 +96,12 @@ static void kcm_update_rx_mux_stats(struct kcm_mux *mux, struct kcm_psock *psock) { STRP_STATS_ADD(mux->stats.rx_bytes, - psock->strp.stats.rx_bytes - + psock->strp.stats.bytes - psock->saved_rx_bytes); mux->stats.rx_msgs += - psock->strp.stats.rx_msgs - psock->saved_rx_msgs; - psock->saved_rx_msgs = psock->strp.stats.rx_msgs; - psock->saved_rx_bytes = psock->strp.stats.rx_bytes; + psock->strp.stats.msgs - psock->saved_rx_msgs; + psock->saved_rx_msgs = psock->strp.stats.msgs; + psock->saved_rx_bytes = psock->strp.stats.bytes; } static void kcm_update_tx_mux_stats(struct kcm_mux *mux, @@ -1118,7 +1118,7 @@ static int kcm_recvmsg(struct socket *sock, struct msghdr *msg, struct kcm_sock *kcm = kcm_sk(sk); int err = 0; long timeo; - struct strp_rx_msg *rxm; + struct strp_msg *stm; int copied = 0; struct sk_buff *skb; @@ -1132,26 +1132,26 @@ static int kcm_recvmsg(struct socket *sock, struct msghdr *msg, /* Okay, have a message on the receive queue */ - rxm = strp_rx_msg(skb); + stm = strp_msg(skb); - if (len > rxm->full_len) - len = rxm->full_len; + if (len > stm->full_len) + len = stm->full_len; - err = skb_copy_datagram_msg(skb, rxm->offset, msg, len); + err = skb_copy_datagram_msg(skb, stm->offset, msg, len); if (err < 0) goto out; copied = len; if (likely(!(flags & MSG_PEEK))) { KCM_STATS_ADD(kcm->stats.rx_bytes, copied); - if (copied < rxm->full_len) { + if (copied < stm->full_len) { if (sock->type == SOCK_DGRAM) { /* Truncated message */ msg->msg_flags |= MSG_TRUNC; goto msg_finished; } - rxm->offset += copied; - rxm->full_len -= copied; + stm->offset += copied; + stm->full_len -= copied; } else { msg_finished: /* Finished with message */ @@ -1175,7 +1175,7 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos, struct sock *sk = sock->sk; struct kcm_sock *kcm = kcm_sk(sk); long timeo; - struct strp_rx_msg *rxm; + struct strp_msg *stm; int err = 0; ssize_t copied; struct sk_buff *skb; @@ -1192,12 +1192,12 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos, /* Okay, have a message on the receive queue */ - rxm = strp_rx_msg(skb); + stm = strp_msg(skb); - if (len > rxm->full_len) - len = rxm->full_len; + if (len > stm->full_len) + len = stm->full_len; - copied = skb_splice_bits(skb, sk, rxm->offset, pipe, len, flags); + copied = skb_splice_bits(skb, sk, stm->offset, pipe, len, flags); if (copied < 0) { err = copied; goto err_out; @@ -1205,8 +1205,8 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos, KCM_STATS_ADD(kcm->stats.rx_bytes, copied); - rxm->offset += copied; - rxm->full_len -= copied; + stm->offset += copied; + stm->full_len -= copied; /* We have no way to return MSG_EOR. If all the bytes have been * read we still leave the message in the receive socket buffer. @@ -1376,13 +1376,21 @@ static int kcm_attach(struct socket *sock, struct socket *csock, struct kcm_psock *psock = NULL, *tpsock; struct list_head *head; int index = 0; - struct strp_callbacks cb; + static const struct strp_callbacks cb = { + .rcv_msg = kcm_rcv_strparser, + .parse_msg = kcm_parse_func_strparser, + .read_sock_done = kcm_read_sock_done, + }; int err; csk = csock->sk; if (!csk) return -EINVAL; + /* We must prevent loops or risk deadlock ! */ + if (csk->sk_family == PF_KCM) + return -EOPNOTSUPP; + psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL); if (!psock) return -ENOMEM; @@ -1391,11 +1399,6 @@ static int kcm_attach(struct socket *sock, struct socket *csock, psock->sk = csk; psock->bpf_prog = prog; - cb.rcv_msg = kcm_rcv_strparser; - cb.abort_parser = NULL; - cb.parse_msg = kcm_parse_func_strparser; - cb.read_sock_done = kcm_read_sock_done; - err = strp_init(&psock->strp, csk, &cb); if (err) { kmem_cache_free(kcm_psockp, psock); diff --git a/net/key/af_key.c b/net/key/af_key.c index ca9d3ae665e76ea847a4ce03b4d275f80d7705bc..a00d607e7224d422e6f3ae3b139bee9706852d7b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -228,7 +228,7 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2, #define BROADCAST_ONE 1 #define BROADCAST_REGISTERED 2 #define BROADCAST_PROMISC_ONLY 4 -static int pfkey_broadcast(struct sk_buff *skb, +static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, int broadcast_flags, struct sock *one_sk, struct net *net) { @@ -278,7 +278,7 @@ static int pfkey_broadcast(struct sk_buff *skb, rcu_read_unlock(); if (one_sk != NULL) - err = pfkey_broadcast_one(skb, &skb2, GFP_KERNEL, one_sk); + err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk); kfree_skb(skb2); kfree_skb(skb); @@ -311,7 +311,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk) hdr = (struct sadb_msg *) pfk->dump.skb->data; hdr->sadb_msg_seq = 0; hdr->sadb_msg_errno = rc; - pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb = NULL; } @@ -355,7 +355,7 @@ static int pfkey_error(const struct sadb_msg *orig, int err, struct sock *sk) hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); - pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk)); + pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk)); return 0; } @@ -1389,7 +1389,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_ xfrm_state_put(x); - pfkey_broadcast(resp_skb, BROADCAST_ONE, sk, net); + pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net); return 0; } @@ -1476,7 +1476,7 @@ static int key_notify_sa(struct xfrm_state *x, const struct km_event *c) hdr->sadb_msg_seq = c->seq; hdr->sadb_msg_pid = c->portid; - pfkey_broadcast(skb, BROADCAST_ALL, NULL, xs_net(x)); + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x)); return 0; } @@ -1589,7 +1589,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, const struct sadb_msg out_hdr->sadb_msg_reserved = 0; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; - pfkey_broadcast(out_skb, BROADCAST_ONE, sk, sock_net(sk)); + pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk)); return 0; } @@ -1694,8 +1694,8 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad return -ENOBUFS; } - pfkey_broadcast(supp_skb, BROADCAST_REGISTERED, sk, sock_net(sk)); - + pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk, + sock_net(sk)); return 0; } @@ -1712,7 +1712,8 @@ static int unicast_flush_resp(struct sock *sk, const struct sadb_msg *ihdr) hdr->sadb_msg_errno = (uint8_t) 0; hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); - return pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk)); + return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk, + sock_net(sk)); } static int key_notify_sa_flush(const struct km_event *c) @@ -1733,7 +1734,7 @@ static int key_notify_sa_flush(const struct km_event *c) hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); hdr->sadb_msg_reserved = 0; - pfkey_broadcast(skb, BROADCAST_ALL, NULL, c->net); + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); return 0; } @@ -1790,7 +1791,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr) out_hdr->sadb_msg_pid = pfk->dump.msg_portid; if (pfk->dump.skb) - pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb = out_skb; @@ -1878,7 +1879,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, const struct sadb new_hdr->sadb_msg_errno = 0; } - pfkey_broadcast(skb, BROADCAST_ALL, NULL, sock_net(sk)); + pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk)); return 0; } @@ -2206,7 +2207,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, const struct km_ev out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_seq = c->seq; out_hdr->sadb_msg_pid = c->portid; - pfkey_broadcast(out_skb, BROADCAST_ALL, NULL, xp_net(xp)); + pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); return 0; } @@ -2398,8 +2399,6 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa out: xfrm_pol_put(xp); - if (err == 0) - xfrm_garbage_collect(net); return err; } @@ -2426,7 +2425,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, const struc out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; - pfkey_broadcast(out_skb, BROADCAST_ONE, sk, xp_net(xp)); + pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp)); err = 0; out: @@ -2650,8 +2649,6 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_ out: xfrm_pol_put(xp); - if (delete && err == 0) - xfrm_garbage_collect(net); return err; } @@ -2682,7 +2679,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr) out_hdr->sadb_msg_pid = pfk->dump.msg_portid; if (pfk->dump.skb) - pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE, + pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk, sock_net(&pfk->sk)); pfk->dump.skb = out_skb; @@ -2739,7 +2736,7 @@ static int key_notify_policy_flush(const struct km_event *c) hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); hdr->sadb_msg_reserved = 0; - pfkey_broadcast(skb_out, BROADCAST_ALL, NULL, c->net); + pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); return 0; } @@ -2751,8 +2748,6 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, const struct sad int err, err2; err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, true); - if (!err) - xfrm_garbage_collect(net); err2 = unicast_flush_resp(sk, hdr); if (err || err2) { if (err == -ESRCH) /* empty table - old silent behavior */ @@ -2803,7 +2798,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadb void *ext_hdrs[SADB_EXT_MAX]; int err; - pfkey_broadcast(skb_clone(skb, GFP_KERNEL), + pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); memset(ext_hdrs, 0, sizeof(ext_hdrs)); @@ -3024,7 +3019,8 @@ static int key_notify_sa_expire(struct xfrm_state *x, const struct km_event *c) out_hdr->sadb_msg_seq = 0; out_hdr->sadb_msg_pid = 0; - pfkey_broadcast(out_skb, BROADCAST_REGISTERED, NULL, xs_net(x)); + pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, + xs_net(x)); return 0; } @@ -3212,7 +3208,8 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_ctx->ctx_len); } - return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x)); + return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, + xs_net(x)); } static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, @@ -3408,7 +3405,8 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, n_port->sadb_x_nat_t_port_port = sport; n_port->sadb_x_nat_t_port_reserved = 0; - return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x)); + return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL, + xs_net(x)); } #ifdef CONFIG_NET_KEY_MIGRATE @@ -3599,7 +3597,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, } /* broadcast migrate message to sockets */ - pfkey_broadcast(skb, BROADCAST_ALL, NULL, &init_net); + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net); return 0; diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index b0c2d4ae781d2114cdb09269d27768f0632a1776..02d61101b108dcc6b8360e3184f9432cf2192955 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -113,7 +113,6 @@ struct l2tp_net { spinlock_t l2tp_session_hlist_lock; }; -static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) { @@ -127,39 +126,6 @@ static inline struct l2tp_net *l2tp_pernet(const struct net *net) return net_generic(net, l2tp_net_id); } -/* Tunnel reference counts. Incremented per session that is added to - * the tunnel. - */ -static inline void l2tp_tunnel_inc_refcount_1(struct l2tp_tunnel *tunnel) -{ - refcount_inc(&tunnel->ref_count); -} - -static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel) -{ - if (refcount_dec_and_test(&tunnel->ref_count)) - l2tp_tunnel_free(tunnel); -} -#ifdef L2TP_REFCNT_DEBUG -#define l2tp_tunnel_inc_refcount(_t) \ -do { \ - pr_debug("l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_t)->name, \ - refcount_read(&_t->ref_count)); \ - l2tp_tunnel_inc_refcount_1(_t); \ -} while (0) -#define l2tp_tunnel_dec_refcount(_t) \ -do { \ - pr_debug("l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_t)->name, \ - refcount_read(&_t->ref_count)); \ - l2tp_tunnel_dec_refcount_1(_t); \ -} while (0) -#else -#define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t) -#define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t) -#endif - /* Session hash global list for L2TPv3. * The session_id SHOULD be random according to RFC3931, but several * L2TP implementations use incrementing session_ids. So we do a real @@ -229,6 +195,27 @@ l2tp_session_id_hash(struct l2tp_tunnel *tunnel, u32 session_id) return &tunnel->session_hlist[hash_32(session_id, L2TP_HASH_BITS)]; } +/* Lookup a tunnel. A new reference is held on the returned tunnel. */ +struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id) +{ + const struct l2tp_net *pn = l2tp_pernet(net); + struct l2tp_tunnel *tunnel; + + rcu_read_lock_bh(); + list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { + if (tunnel->tunnel_id == tunnel_id) { + l2tp_tunnel_inc_refcount(tunnel); + rcu_read_unlock_bh(); + + return tunnel; + } + } + rcu_read_unlock_bh(); + + return NULL; +} +EXPORT_SYMBOL_GPL(l2tp_tunnel_get); + /* Lookup a session. A new reference is held on the returned session. * Optionally calls session->ref() too if do_ref is true. */ @@ -342,13 +329,21 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, struct hlist_head *g_head; struct hlist_head *head; struct l2tp_net *pn; + int err; head = l2tp_session_id_hash(tunnel, session->session_id); write_lock_bh(&tunnel->hlist_lock); + if (!tunnel->acpt_newsess) { + err = -ENODEV; + goto err_tlock; + } + hlist_for_each_entry(session_walk, head, hlist) - if (session_walk->session_id == session->session_id) - goto exist; + if (session_walk->session_id == session->session_id) { + err = -EEXIST; + goto err_tlock; + } if (tunnel->version == L2TP_HDR_VER_3) { pn = l2tp_pernet(tunnel->l2tp_net); @@ -356,12 +351,21 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, session->session_id); spin_lock_bh(&pn->l2tp_session_hlist_lock); + hlist_for_each_entry(session_walk, g_head, global_hlist) - if (session_walk->session_id == session->session_id) - goto exist_glob; + if (session_walk->session_id == session->session_id) { + err = -EEXIST; + goto err_tlock_pnlock; + } + l2tp_tunnel_inc_refcount(tunnel); + sock_hold(tunnel->sock); hlist_add_head_rcu(&session->global_hlist, g_head); + spin_unlock_bh(&pn->l2tp_session_hlist_lock); + } else { + l2tp_tunnel_inc_refcount(tunnel); + sock_hold(tunnel->sock); } hlist_add_head(&session->hlist, head); @@ -369,12 +373,12 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, return 0; -exist_glob: +err_tlock_pnlock: spin_unlock_bh(&pn->l2tp_session_hlist_lock); -exist: +err_tlock: write_unlock_bh(&tunnel->hlist_lock); - return -EEXIST; + return err; } /* Lookup a tunnel by id @@ -1264,7 +1268,6 @@ static void l2tp_tunnel_destruct(struct sock *sk) /* Remove hooks into tunnel socket */ sk->sk_destruct = tunnel->old_sk_destruct; sk->sk_user_data = NULL; - tunnel->sock = NULL; /* Remove the tunnel struct from the tunnel list */ pn = l2tp_pernet(tunnel->l2tp_net); @@ -1274,6 +1277,8 @@ static void l2tp_tunnel_destruct(struct sock *sk) atomic_dec(&l2tp_tunnel_count); l2tp_tunnel_closeall(tunnel); + + tunnel->sock = NULL; l2tp_tunnel_dec_refcount(tunnel); /* Call the original destructor */ @@ -1298,6 +1303,7 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel) tunnel->name); write_lock_bh(&tunnel->hlist_lock); + tunnel->acpt_newsess = false; for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { again: hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { @@ -1308,6 +1314,9 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel) hlist_del_init(&session->hlist); + if (test_and_set_bit(0, &session->dead)) + goto again; + if (session->ref != NULL) (*session->ref)(session); @@ -1348,17 +1357,6 @@ static void l2tp_udp_encap_destroy(struct sock *sk) } } -/* Really kill the tunnel. - * Come here only when all sessions have been cleared from the tunnel. - */ -static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel) -{ - BUG_ON(refcount_read(&tunnel->ref_count) != 0); - BUG_ON(tunnel->sock != NULL); - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: free...\n", tunnel->name); - kfree_rcu(tunnel, rcu); -} - /* Workqueue tunnel deletion function */ static void l2tp_tunnel_del_work(struct work_struct *work) { @@ -1605,6 +1603,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 tunnel->magic = L2TP_TUNNEL_MAGIC; sprintf(&tunnel->name[0], "tunl %u", tunnel_id); rwlock_init(&tunnel->hlist_lock); + tunnel->acpt_newsess = true; /* The net we belong to */ tunnel->l2tp_net = net; @@ -1689,14 +1688,12 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create); /* This function is used by the netlink TUNNEL_DELETE command. */ -int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) +void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) { - l2tp_tunnel_inc_refcount(tunnel); - if (false == queue_work(l2tp_wq, &tunnel->del_work)) { - l2tp_tunnel_dec_refcount(tunnel); - return 1; + if (!test_and_set_bit(0, &tunnel->dead)) { + l2tp_tunnel_inc_refcount(tunnel); + queue_work(l2tp_wq, &tunnel->del_work); } - return 0; } EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); @@ -1754,6 +1751,9 @@ EXPORT_SYMBOL_GPL(__l2tp_session_unhash); */ int l2tp_session_delete(struct l2tp_session *session) { + if (test_and_set_bit(0, &session->dead)) + return 0; + if (session->ref) (*session->ref)(session); __l2tp_session_unhash(session); @@ -1844,6 +1844,8 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn l2tp_session_set_header_len(session, tunnel->version); + refcount_set(&session->ref_count, 1); + err = l2tp_session_add_to_tunnel(tunnel, session); if (err) { kfree(session); @@ -1851,15 +1853,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn return ERR_PTR(err); } - /* Bump the reference count. The session context is deleted - * only when this drops to zero. - */ - refcount_set(&session->ref_count, 1); - l2tp_tunnel_inc_refcount(tunnel); - - /* Ensure tunnel socket isn't deleted */ - sock_hold(tunnel->sock); - /* Ignore management session in session count value */ if (session->session_id != 0) atomic_inc(&l2tp_session_count); diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index cdb6e3327f744040f8510ad0882c2f620509dfb9..67c79d9b5c6cb418221f1c06df62c48117405b4c 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -76,6 +76,7 @@ struct l2tp_session_cfg { struct l2tp_session { int magic; /* should be * L2TP_SESSION_MAGIC */ + long dead; struct l2tp_tunnel *tunnel; /* back pointer to tunnel * context */ @@ -160,8 +161,15 @@ struct l2tp_tunnel_cfg { struct l2tp_tunnel { int magic; /* Should be L2TP_TUNNEL_MAGIC */ + + unsigned long dead; + struct rcu_head rcu; rwlock_t hlist_lock; /* protect session_hlist */ + bool acpt_newsess; /* Indicates whether this + * tunnel accepts new sessions. + * Protected by hlist_lock. + */ struct hlist_head session_hlist[L2TP_HASH_SIZE]; /* hashed list of sessions, * hashed by id */ @@ -197,7 +205,9 @@ struct l2tp_tunnel { }; struct l2tp_nl_cmd_ops { - int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); + int (*session_create)(struct net *net, struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, + struct l2tp_session_cfg *cfg); int (*session_delete)(struct l2tp_session *session); }; @@ -231,6 +241,8 @@ static inline struct l2tp_tunnel *l2tp_sock_to_tunnel(struct sock *sk) return tunnel; } +struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id); + struct l2tp_session *l2tp_session_get(const struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, bool do_ref); @@ -246,7 +258,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp); void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel); -int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); +void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, @@ -269,6 +281,17 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type); int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg); +static inline void l2tp_tunnel_inc_refcount(struct l2tp_tunnel *tunnel) +{ + refcount_inc(&tunnel->ref_count); +} + +static inline void l2tp_tunnel_dec_refcount(struct l2tp_tunnel *tunnel) +{ + if (refcount_dec_and_test(&tunnel->ref_count)) + kfree_rcu(tunnel, rcu); +} + /* Session reference counts. Incremented when code obtains a reference * to a session. */ diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 4de2ec94b08cbf5aba016da754b799c46d5f378a..014a7bc2a872514cf4422302a92b692ecda31c27 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -44,7 +44,6 @@ struct l2tp_eth { struct net_device *dev; struct sock *tunnel_sock; struct l2tp_session *session; - struct list_head list; atomic_long_t tx_bytes; atomic_long_t tx_packets; atomic_long_t tx_dropped; @@ -58,17 +57,6 @@ struct l2tp_eth_sess { struct net_device *dev; }; -/* per-net private data for this module */ -static unsigned int l2tp_eth_net_id; -struct l2tp_eth_net { - struct list_head l2tp_eth_dev_list; - spinlock_t l2tp_eth_lock; -}; - -static inline struct l2tp_eth_net *l2tp_eth_pernet(struct net *net) -{ - return net_generic(net, l2tp_eth_net_id); -} static int l2tp_eth_dev_init(struct net_device *dev) { @@ -84,12 +72,6 @@ static int l2tp_eth_dev_init(struct net_device *dev) static void l2tp_eth_dev_uninit(struct net_device *dev) { - struct l2tp_eth *priv = netdev_priv(dev); - struct l2tp_eth_net *pn = l2tp_eth_pernet(dev_net(dev)); - - spin_lock(&pn->l2tp_eth_lock); - list_del_init(&priv->list); - spin_unlock(&pn->l2tp_eth_lock); dev_put(dev); } @@ -262,23 +244,17 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel, dev->needed_headroom += session->hdr_len; } -static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) +static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, + struct l2tp_session_cfg *cfg) { unsigned char name_assign_type; struct net_device *dev; char name[IFNAMSIZ]; - struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct l2tp_eth *priv; struct l2tp_eth_sess *spriv; int rc; - struct l2tp_eth_net *pn; - - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (!tunnel) { - rc = -ENODEV; - goto out; - } if (cfg->ifname) { strlcpy(name, cfg->ifname, IFNAMSIZ); @@ -310,7 +286,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p priv = netdev_priv(dev); priv->dev = dev; priv->session = session; - INIT_LIST_HEAD(&priv->list); priv->tunnel_sock = tunnel->sock; session->recv_skb = l2tp_eth_dev_recv; @@ -331,10 +306,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p strlcpy(session->ifname, dev->name, IFNAMSIZ); dev_hold(dev); - pn = l2tp_eth_pernet(dev_net(dev)); - spin_lock(&pn->l2tp_eth_lock); - list_add(&priv->list, &pn->l2tp_eth_dev_list); - spin_unlock(&pn->l2tp_eth_lock); return 0; @@ -347,22 +318,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p return rc; } -static __net_init int l2tp_eth_init_net(struct net *net) -{ - struct l2tp_eth_net *pn = net_generic(net, l2tp_eth_net_id); - - INIT_LIST_HEAD(&pn->l2tp_eth_dev_list); - spin_lock_init(&pn->l2tp_eth_lock); - - return 0; -} - -static struct pernet_operations l2tp_eth_net_ops = { - .init = l2tp_eth_init_net, - .id = &l2tp_eth_net_id, - .size = sizeof(struct l2tp_eth_net), -}; - static const struct l2tp_nl_cmd_ops l2tp_eth_nl_cmd_ops = { .session_create = l2tp_eth_create, @@ -376,25 +331,18 @@ static int __init l2tp_eth_init(void) err = l2tp_nl_register_ops(L2TP_PWTYPE_ETH, &l2tp_eth_nl_cmd_ops); if (err) - goto out; - - err = register_pernet_device(&l2tp_eth_net_ops); - if (err) - goto out_unreg; + goto err; pr_info("L2TP ethernet pseudowire support (L2TPv3)\n"); return 0; -out_unreg: - l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH); -out: +err: return err; } static void __exit l2tp_eth_exit(void) { - unregister_pernet_device(&l2tp_eth_net_ops); l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH); } diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 12cfcd0ca807396d18e061e9bcf4c29e760b2563..7135f4645d3aa64ae2c37f1c99544de84c650aaa 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -65,10 +65,12 @@ static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info, (info->attrs[L2TP_ATTR_CONN_ID])) { tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel) + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (tunnel) { session = l2tp_session_get(net, tunnel, session_id, do_ref); + l2tp_tunnel_dec_refcount(tunnel); + } } return session; @@ -271,8 +273,8 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel == NULL) { + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (!tunnel) { ret = -ENODEV; goto out; } @@ -282,6 +284,8 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info (void) l2tp_tunnel_delete(tunnel); + l2tp_tunnel_dec_refcount(tunnel); + out: return ret; } @@ -299,8 +303,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel == NULL) { + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (!tunnel) { ret = -ENODEV; goto out; } @@ -311,6 +315,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, L2TP_CMD_TUNNEL_MODIFY); + l2tp_tunnel_dec_refcount(tunnel); + out: return ret; } @@ -438,34 +444,37 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; - goto out; + goto err; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel == NULL) { - ret = -ENODEV; - goto out; - } - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { ret = -ENOMEM; - goto out; + goto err; + } + + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (!tunnel) { + ret = -ENODEV; + goto err_nlmsg; } ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq, NLM_F_ACK, tunnel, L2TP_CMD_TUNNEL_GET); if (ret < 0) - goto err_out; + goto err_nlmsg_tunnel; + + l2tp_tunnel_dec_refcount(tunnel); return genlmsg_unicast(net, msg, info->snd_portid); -err_out: +err_nlmsg_tunnel: + l2tp_tunnel_dec_refcount(tunnel); +err_nlmsg: nlmsg_free(msg); - -out: +err: return ret; } @@ -509,8 +518,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ret = -EINVAL; goto out; } + tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); + tunnel = l2tp_tunnel_get(net, tunnel_id); if (!tunnel) { ret = -ENODEV; goto out; @@ -518,24 +528,24 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf if (!info->attrs[L2TP_ATTR_SESSION_ID]) { ret = -EINVAL; - goto out; + goto out_tunnel; } session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) { ret = -EINVAL; - goto out; + goto out_tunnel; } peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]); if (!info->attrs[L2TP_ATTR_PW_TYPE]) { ret = -EINVAL; - goto out; + goto out_tunnel; } cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]); if (cfg.pw_type >= __L2TP_PWTYPE_MAX) { ret = -EINVAL; - goto out; + goto out_tunnel; } if (tunnel->version > 2) { @@ -557,7 +567,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]); if (len > 8) { ret = -EINVAL; - goto out; + goto out_tunnel; } cfg.cookie_len = len; memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len); @@ -566,7 +576,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]); if (len > 8) { ret = -EINVAL; - goto out; + goto out_tunnel; } cfg.peer_cookie_len = len; memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len); @@ -609,7 +619,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) || (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) { ret = -EPROTONOSUPPORT; - goto out; + goto out_tunnel; } /* Check that pseudowire-specific params are present */ @@ -619,7 +629,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf case L2TP_PWTYPE_ETH_VLAN: if (!info->attrs[L2TP_ATTR_VLAN_ID]) { ret = -EINVAL; - goto out; + goto out_tunnel; } break; case L2TP_PWTYPE_ETH: @@ -633,10 +643,10 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf break; } - ret = -EPROTONOSUPPORT; - if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create) - ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id, - session_id, peer_session_id, &cfg); + ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel, + session_id, + peer_session_id, + &cfg); if (ret >= 0) { session = l2tp_session_get(net, tunnel, session_id, false); @@ -647,6 +657,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf } } +out_tunnel: + l2tp_tunnel_dec_refcount(tunnel); out: return ret; } diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index f0edb720907946eb5e79f47017133d8a1c60ada7..bc6e8bfc5be4997e421c0b5326a8b37e2ffc9901 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -437,11 +437,11 @@ static void pppol2tp_session_close(struct l2tp_session *session) BUG_ON(session->magic != L2TP_SESSION_MAGIC); - if (sock) { + if (sock) inet_shutdown(sock, SEND_SHUTDOWN); - /* Don't let the session go away before our socket does */ - l2tp_session_inc_refcount(session); - } + + /* Don't let the session go away before our socket does */ + l2tp_session_inc_refcount(session); } /* Really kill the session socket. (Called from sock_put() if @@ -788,25 +788,20 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, #ifdef CONFIG_L2TP_V3 -/* Called when creating sessions via the netlink interface. - */ -static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) +/* Called when creating sessions via the netlink interface. */ +static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, + struct l2tp_session_cfg *cfg) { int error; - struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct pppol2tp_session *ps; - tunnel = l2tp_tunnel_find(net, tunnel_id); - - /* Error if we can't find the tunnel */ - error = -ENOENT; - if (tunnel == NULL) - goto out; - /* Error if tunnel socket is not prepped */ - if (tunnel->sock == NULL) + if (!tunnel->sock) { + error = -ENOENT; goto out; + } /* Default MTU values. */ if (cfg->mtu == 0) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 8708cbe8af5bbcabc5c7ea295c6a0abd15a8eb84..2849a1fc41c5dbbe06a7e5c9fbb4ff6276c84394 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -7,7 +7,7 @@ * Copyright 2006-2007 Jiri Benc * Copyright 2007, Michael Wu * Copyright 2007-2010, Intel Corporation - * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2015-2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -245,10 +245,10 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d ieee80211_tx_skb(sdata, skb); } -void __ieee80211_start_rx_ba_session(struct sta_info *sta, - u8 dialog_token, u16 timeout, - u16 start_seq_num, u16 ba_policy, u16 tid, - u16 buf_size, bool tx, bool auto_seq) +void ___ieee80211_start_rx_ba_session(struct sta_info *sta, + u8 dialog_token, u16 timeout, + u16 start_seq_num, u16 ba_policy, u16 tid, + u16 buf_size, bool tx, bool auto_seq) { struct ieee80211_local *local = sta->sdata->local; struct tid_ampdu_rx *tid_agg_rx; @@ -267,7 +267,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, ht_dbg(sta->sdata, "STA %pM requests BA session on unsupported tid %d\n", sta->sta.addr, tid); - goto end_no_lock; + goto end; } if (!sta->sta.ht_cap.ht_supported) { @@ -275,14 +275,14 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, "STA %pM erroneously requests BA session on tid %d w/o QoS\n", sta->sta.addr, tid); /* send a response anyway, it's an error case if we get here */ - goto end_no_lock; + goto end; } if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { ht_dbg(sta->sdata, "Suspend in progress - Denying ADDBA request (%pM tid %d)\n", sta->sta.addr, tid); - goto end_no_lock; + goto end; } /* sanity check for incoming parameters: @@ -296,7 +296,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, ht_dbg_ratelimited(sta->sdata, "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", sta->sta.addr, tid, ba_policy, buf_size); - goto end_no_lock; + goto end; } /* determine default buffer size */ if (buf_size == 0) @@ -311,7 +311,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, buf_size, sta->sta.addr); /* examine state machine */ - mutex_lock(&sta->ampdu_mlme.mtx); + lockdep_assert_held(&sta->ampdu_mlme.mtx); if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) { if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) { @@ -415,15 +415,25 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, __clear_bit(tid, sta->ampdu_mlme.unexpected_agg); sta->ampdu_mlme.tid_rx_token[tid] = dialog_token; } - mutex_unlock(&sta->ampdu_mlme.mtx); -end_no_lock: if (tx) ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid, dialog_token, status, 1, buf_size, timeout); } +void __ieee80211_start_rx_ba_session(struct sta_info *sta, + u8 dialog_token, u16 timeout, + u16 start_seq_num, u16 ba_policy, u16 tid, + u16 buf_size, bool tx, bool auto_seq) +{ + mutex_lock(&sta->ampdu_mlme.mtx); + ___ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, tx, auto_seq); + mutex_unlock(&sta->ampdu_mlme.mtx); +} + void ieee80211_process_addba_request(struct ieee80211_local *local, struct sta_info *sta, struct ieee80211_mgmt *mgmt, @@ -466,3 +476,23 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, rcu_read_unlock(); } EXPORT_SYMBOL(ieee80211_manage_rx_ba_offl); + +void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif, + const u8 *addr, unsigned int tid) +{ + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + + rcu_read_lock(); + sta = sta_info_get_bss(sdata, addr); + if (!sta) + goto unlock; + + set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired); + ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); + + unlock: + rcu_read_unlock(); +} +EXPORT_SYMBOL(ieee80211_rx_ba_timer_expired); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index cbd48762256cb26a4f06efdd3ae91994f99f7a44..bef516ec47f94c19f57da37d80c744bb534deeb4 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -226,7 +226,11 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable) clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); + local_bh_disable(); + rcu_read_lock(); drv_wake_tx_queue(sta->sdata->local, txqi); + rcu_read_unlock(); + local_bh_enable(); } /* @@ -436,7 +440,7 @@ static void sta_addba_resp_timer_expired(unsigned long data) test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { rcu_read_unlock(); ht_dbg(sta->sdata, - "timer expired on %pM tid %d but we are not (or no longer) expecting addBA response there\n", + "timer expired on %pM tid %d not expecting addBA response\n", sta->sta.addr, tid); return; } @@ -639,7 +643,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + HT_AGG_RETRIES_PERIOD)) { ht_dbg(sdata, - "BA request denied - waiting a grace period after %d failed requests on %pM tid %u\n", + "BA request denied - %d failed requests on %pM tid %u\n", sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid); ret = -EBUSY; goto err_unlock_sta; diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index c92df492e8988ee55e5146acb715e5403ff135e3..d6d0b4201e40bf2eadc2ac7051192c7ca5551439 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -300,6 +300,24 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, /* stopping might queue the work again - so cancel only afterwards */ cancel_work_sync(&sta->ampdu_mlme.work); + + /* + * In case the tear down is part of a reconfigure due to HW restart + * request, it is possible that the low level driver requested to stop + * the BA session, so handle it to properly clean tid_tx data. + */ + mutex_lock(&sta->ampdu_mlme.mtx); + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { + struct tid_ampdu_tx *tid_tx = + rcu_dereference_protected_tid_tx(sta, i); + + if (!tid_tx) + continue; + + if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state)) + ieee80211_stop_tx_ba_cb(sta, i, tid_tx); + } + mutex_unlock(&sta->ampdu_mlme.mtx); } void ieee80211_ba_session_work(struct work_struct *work) @@ -333,9 +351,9 @@ void ieee80211_ba_session_work(struct work_struct *work) if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_manage_offl)) - __ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, - IEEE80211_MAX_AMPDU_BUF, - false, true); + ___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, + IEEE80211_MAX_AMPDU_BUF, + false, true); if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS, sta->ampdu_mlme.tid_rx_manage_offl)) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2197c62a0a6e1166418123964f64d4f8487e88ea..9675814f64dbcc9807e69452e4ad93a4dfe42556 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1760,6 +1760,10 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, u8 dialog_token, u16 timeout, u16 start_seq_num, u16 ba_policy, u16 tid, u16 buf_size, bool tx, bool auto_seq); +void ___ieee80211_start_rx_ba_session(struct sta_info *sta, + u8 dialog_token, u16 timeout, + u16 start_seq_num, u16 ba_policy, u16 tid, + u16 buf_size, bool tx, bool auto_seq); void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, enum ieee80211_agg_stop_reason reason); void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9228ac73c429921673bf2c058e821a07dcdfec92..f75029abf7286d54708b1739ee5faa89a43fe2ff 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -731,7 +731,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) sdata->vif.type == NL80211_IFTYPE_AP_VLAN || local->ops->wake_tx_queue) { /* XXX: for AP_VLAN, actually track AP queues */ - netif_tx_start_all_queues(dev); + if (dev) + netif_tx_start_all_queues(dev); } else if (dev) { unsigned long flags; int n_acs = IEEE80211_NUM_ACS; @@ -792,6 +793,7 @@ static int ieee80211_open(struct net_device *dev) static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_down) { + struct ieee80211_sub_if_data *txq_sdata = sdata; struct ieee80211_local *local = sdata->local; struct fq *fq = &local->fq; unsigned long flags; @@ -937,6 +939,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: + txq_sdata = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + mutex_lock(&local->mtx); list_del(&sdata->u.vlan.list); mutex_unlock(&local->mtx); @@ -1007,8 +1012,17 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - if (sdata->vif.txq) { - struct txq_info *txqi = to_txq_info(sdata->vif.txq); + if (txq_sdata->vif.txq) { + struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq); + + /* + * FIXME FIXME + * + * We really shouldn't purge the *entire* txqi since that + * contains frames for the other AP_VLANs (and possibly + * the AP itself) as well, but there's no API in FQ now + * to be able to filter. + */ spin_lock_bh(&fq->lock); ieee80211_txq_purge(local, txqi); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b588e593b0ec175a72251345174928b724e83838..3b8e2709d8dea14ba4711de7d7d5c6ed5b48473a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3155,7 +3155,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, if (len < 24 + 6) return; - reassoc = ieee80211_is_reassoc_req(mgmt->frame_control); + reassoc = ieee80211_is_reassoc_resp(mgmt->frame_control); capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); aid = le16_to_cpu(mgmt->u.assoc_resp.aid); diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index f8e7a8bbc618727bada48c27d59bc01ed5a18498..faf4f60550001df531bd6b808fbafc8b74a28d30 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, if (!cookie) return -ENOENT; + flush_work(&local->hw_roc_start); + mutex_lock(&local->mtx); list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { if (!mgmt_tx && roc->cookie != cookie) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8858f4f185e90953d096ec28debc21f5dd2bc20d..94826680cf2b54e2a6254146856b495d0ba5e861 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1276,11 +1276,6 @@ static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); } -static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi) -{ - IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif; -} - static u32 codel_skb_len_func(const struct sk_buff *skb) { return skb->len; @@ -3414,6 +3409,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_tx_info *info; struct ieee80211_tx_data tx; ieee80211_tx_result r; + struct ieee80211_vif *vif; spin_lock_bh(&fq->lock); @@ -3430,8 +3426,6 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, if (!skb) goto out; - ieee80211_set_skb_vif(skb, txqi); - hdr = (struct ieee80211_hdr *)skb->data; info = IEEE80211_SKB_CB(skb); @@ -3488,6 +3482,34 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, } } + switch (tx.sdata->vif.type) { + case NL80211_IFTYPE_MONITOR: + if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) { + vif = &tx.sdata->vif; + break; + } + tx.sdata = rcu_dereference(local->monitor_sdata); + if (tx.sdata) { + vif = &tx.sdata->vif; + info->hw_queue = + vif->hw_queue[skb_get_queue_mapping(skb)]; + } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) { + ieee80211_free_txskb(&local->hw, skb); + goto begin; + } else { + vif = NULL; + } + break; + case NL80211_IFTYPE_AP_VLAN: + tx.sdata = container_of(tx.sdata->bss, + struct ieee80211_sub_if_data, u.ap); + /* fall through */ + default: + vif = &tx.sdata->vif; + break; + } + + IEEE80211_SKB_CB(skb)->control.vif = vif; out: spin_unlock_bh(&fq->lock); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 259698de569ffa6a93c2738f85d6fd6af142eb9a..6aef6793d05236c19afe00a51f4ddc91bc060a39 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1436,7 +1436,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, WLAN_EID_SSID_LIST, WLAN_EID_CHANNEL_USAGE, WLAN_EID_INTERWORKING, - /* mesh ID can't happen here */ + WLAN_EID_MESH_ID, /* 60 GHz can't happen here right now */ }; noffset = ieee80211_ie_split(ie, ie_len, diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index ea4f481839dd9a3d16ec2e87922e87e2684d094c..c5b9ce41d66fadc903c9341c7808ec3d3ce89933 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -2479,12 +2479,12 @@ static int __init mpls_init(void) rtnl_af_register(&mpls_af_ops); - rtnl_register(PF_MPLS, RTM_NEWROUTE, mpls_rtm_newroute, NULL, NULL); - rtnl_register(PF_MPLS, RTM_DELROUTE, mpls_rtm_delroute, NULL, NULL); + rtnl_register(PF_MPLS, RTM_NEWROUTE, mpls_rtm_newroute, NULL, 0); + rtnl_register(PF_MPLS, RTM_DELROUTE, mpls_rtm_delroute, NULL, 0); rtnl_register(PF_MPLS, RTM_GETROUTE, mpls_getroute, mpls_dump_routes, - NULL); + 0); rtnl_register(PF_MPLS, RTM_GETNETCONF, mpls_netconf_get_devconf, - mpls_netconf_dump_devconf, NULL); + mpls_netconf_dump_devconf, 0); err = 0; out: return err; diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index 1308a56f259149e7aee910f5e84dfe3e14819ec9..af3d636534efb8b81fc47547f2fb027f61f5be34 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h @@ -180,6 +180,7 @@ struct ncsi_channel { #define NCSI_CHANNEL_INACTIVE 1 #define NCSI_CHANNEL_ACTIVE 2 #define NCSI_CHANNEL_INVISIBLE 3 + bool reconfigure_needed; spinlock_t lock; /* Protect filters etc */ struct ncsi_package *package; struct ncsi_channel_version version; @@ -235,6 +236,9 @@ enum { ncsi_dev_state_probe_dp, ncsi_dev_state_config_sp = 0x0301, ncsi_dev_state_config_cis, + ncsi_dev_state_config_clear_vids, + ncsi_dev_state_config_svf, + ncsi_dev_state_config_ev, ncsi_dev_state_config_sma, ncsi_dev_state_config_ebf, #if IS_ENABLED(CONFIG_IPV6) @@ -253,6 +257,12 @@ enum { ncsi_dev_state_suspend_done }; +struct vlan_vid { + struct list_head list; + __be16 proto; + u16 vid; +}; + struct ncsi_dev_priv { struct ncsi_dev ndev; /* Associated NCSI device */ unsigned int flags; /* NCSI device flags */ @@ -276,6 +286,7 @@ struct ncsi_dev_priv { struct work_struct work; /* For channel management */ struct packet_type ptype; /* NCSI packet Rx handler */ struct list_head node; /* Form NCSI device list */ + struct list_head vlan_vids; /* List of active VLAN IDs */ }; struct ncsi_cmd_arg { diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c index 5e03ed190e18bba62f1ca3f432d1b87751a2175d..7567ca63aae24b689e368219826df1be0982446b 100644 --- a/net/ncsi/ncsi-cmd.c +++ b/net/ncsi/ncsi-cmd.c @@ -139,9 +139,9 @@ static int ncsi_cmd_handler_svf(struct sk_buff *skb, struct ncsi_cmd_svf_pkt *cmd; cmd = skb_put_zero(skb, sizeof(*cmd)); - cmd->vlan = htons(nca->words[0]); - cmd->index = nca->bytes[2]; - cmd->enable = nca->bytes[3]; + cmd->vlan = htons(nca->words[1]); + cmd->index = nca->bytes[6]; + cmd->enable = nca->bytes[7]; ncsi_cmd_build_header(&cmd->cmd.common, nca); return 0; @@ -153,7 +153,7 @@ static int ncsi_cmd_handler_ev(struct sk_buff *skb, struct ncsi_cmd_ev_pkt *cmd; cmd = skb_put_zero(skb, sizeof(*cmd)); - cmd->mode = nca->bytes[0]; + cmd->mode = nca->bytes[3]; ncsi_cmd_build_header(&cmd->cmd.common, nca); return 0; @@ -228,7 +228,7 @@ static struct ncsi_cmd_handler { { NCSI_PKT_CMD_AE, 8, ncsi_cmd_handler_ae }, { NCSI_PKT_CMD_SL, 8, ncsi_cmd_handler_sl }, { NCSI_PKT_CMD_GLS, 0, ncsi_cmd_handler_default }, - { NCSI_PKT_CMD_SVF, 4, ncsi_cmd_handler_svf }, + { NCSI_PKT_CMD_SVF, 8, ncsi_cmd_handler_svf }, { NCSI_PKT_CMD_EV, 4, ncsi_cmd_handler_ev }, { NCSI_PKT_CMD_DV, 0, ncsi_cmd_handler_default }, { NCSI_PKT_CMD_SMA, 8, ncsi_cmd_handler_sma }, diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index a3bd5fa8ad093a3fb7533f00186111bf9a19c2ed..3fd3c39e627836117f250fc7d5037415491ee6f5 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c @@ -38,6 +38,25 @@ static inline int ncsi_filter_size(int table) return sizes[table]; } +u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index) +{ + struct ncsi_channel_filter *ncf; + int size; + + ncf = nc->filters[table]; + if (!ncf) + return NULL; + + size = ncsi_filter_size(table); + if (size < 0) + return NULL; + + return ncf->data + size * index; +} + +/* Find the first active filter in a filter table that matches the given + * data parameter. If data is NULL, this returns the first active filter. + */ int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data) { struct ncsi_channel_filter *ncf; @@ -58,7 +77,7 @@ int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data) index = -1; while ((index = find_next_bit(bitmap, ncf->total, index + 1)) < ncf->total) { - if (!memcmp(ncf->data + size * index, data, size)) { + if (!data || !memcmp(ncf->data + size * index, data, size)) { spin_unlock_irqrestore(&nc->lock, flags); return index; } @@ -639,6 +658,95 @@ static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp) nd->state = ncsi_dev_state_functional; } +/* Check the VLAN filter bitmap for a set filter, and construct a + * "Set VLAN Filter - Disable" packet if found. + */ +static int clear_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc, + struct ncsi_cmd_arg *nca) +{ + int index; + u32 *data; + u16 vid; + + index = ncsi_find_filter(nc, NCSI_FILTER_VLAN, NULL); + if (index < 0) { + /* Filter table empty */ + return -1; + } + + data = ncsi_get_filter(nc, NCSI_FILTER_VLAN, index); + if (!data) { + netdev_err(ndp->ndev.dev, + "ncsi: failed to retrieve filter %d\n", index); + /* Set the VLAN id to 0 - this will still disable the entry in + * the filter table, but we won't know what it was. + */ + vid = 0; + } else { + vid = *(u16 *)data; + } + + netdev_printk(KERN_DEBUG, ndp->ndev.dev, + "ncsi: removed vlan tag %u at index %d\n", + vid, index + 1); + ncsi_remove_filter(nc, NCSI_FILTER_VLAN, index); + + nca->type = NCSI_PKT_CMD_SVF; + nca->words[1] = vid; + /* HW filter index starts at 1 */ + nca->bytes[6] = index + 1; + nca->bytes[7] = 0x00; + return 0; +} + +/* Find an outstanding VLAN tag and constuct a "Set VLAN Filter - Enable" + * packet. + */ +static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc, + struct ncsi_cmd_arg *nca) +{ + struct vlan_vid *vlan = NULL; + int index = 0; + + list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { + index = ncsi_find_filter(nc, NCSI_FILTER_VLAN, &vlan->vid); + if (index < 0) { + /* New tag to add */ + netdev_printk(KERN_DEBUG, ndp->ndev.dev, + "ncsi: new vlan id to set: %u\n", + vlan->vid); + break; + } + netdev_printk(KERN_DEBUG, ndp->ndev.dev, + "vid %u already at filter pos %d\n", + vlan->vid, index); + } + + if (!vlan || index >= 0) { + netdev_printk(KERN_DEBUG, ndp->ndev.dev, + "no vlan ids left to set\n"); + return -1; + } + + index = ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan->vid); + if (index < 0) { + netdev_err(ndp->ndev.dev, + "Failed to add new VLAN tag, error %d\n", index); + return -1; + } + + netdev_printk(KERN_DEBUG, ndp->ndev.dev, + "ncsi: set vid %u in packet, index %u\n", + vlan->vid, index + 1); + nca->type = NCSI_PKT_CMD_SVF; + nca->words[1] = vlan->vid; + /* HW filter index starts at 1 */ + nca->bytes[6] = index + 1; + nca->bytes[7] = 0x01; + + return 0; +} + static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) { struct ncsi_dev *nd = &ndp->ndev; @@ -683,8 +791,11 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) if (ret) goto error; - nd->state = ncsi_dev_state_config_sma; + nd->state = ncsi_dev_state_config_clear_vids; break; + case ncsi_dev_state_config_clear_vids: + case ncsi_dev_state_config_svf: + case ncsi_dev_state_config_ev: case ncsi_dev_state_config_sma: case ncsi_dev_state_config_ebf: #if IS_ENABLED(CONFIG_IPV6) @@ -699,11 +810,40 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) nca.package = np->id; nca.channel = nc->id; + /* Clear any active filters on the channel before setting */ + if (nd->state == ncsi_dev_state_config_clear_vids) { + ret = clear_one_vid(ndp, nc, &nca); + if (ret) { + nd->state = ncsi_dev_state_config_svf; + schedule_work(&ndp->work); + break; + } + /* Repeat */ + nd->state = ncsi_dev_state_config_clear_vids; + /* Add known VLAN tags to the filter */ + } else if (nd->state == ncsi_dev_state_config_svf) { + ret = set_one_vid(ndp, nc, &nca); + if (ret) { + nd->state = ncsi_dev_state_config_ev; + schedule_work(&ndp->work); + break; + } + /* Repeat */ + nd->state = ncsi_dev_state_config_svf; + /* Enable/Disable the VLAN filter */ + } else if (nd->state == ncsi_dev_state_config_ev) { + if (list_empty(&ndp->vlan_vids)) { + nca.type = NCSI_PKT_CMD_DV; + } else { + nca.type = NCSI_PKT_CMD_EV; + nca.bytes[3] = NCSI_CAP_VLAN_NO; + } + nd->state = ncsi_dev_state_config_sma; + } else if (nd->state == ncsi_dev_state_config_sma) { /* Use first entry in unicast filter table. Note that * the MAC filter table starts from entry 1 instead of * 0. */ - if (nd->state == ncsi_dev_state_config_sma) { nca.type = NCSI_PKT_CMD_SMA; for (index = 0; index < 6; index++) nca.bytes[index] = dev->dev_addr[index]; @@ -751,6 +891,25 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) break; case ncsi_dev_state_config_done: spin_lock_irqsave(&nc->lock, flags); + if (nc->reconfigure_needed) { + /* This channel's configuration has been updated + * part-way during the config state - start the + * channel configuration over + */ + nc->reconfigure_needed = false; + nc->state = NCSI_CHANNEL_INACTIVE; + spin_unlock_irqrestore(&nc->lock, flags); + + spin_lock_irqsave(&ndp->lock, flags); + list_add_tail_rcu(&nc->link, &ndp->channel_queue); + spin_unlock_irqrestore(&ndp->lock, flags); + + netdev_printk(KERN_DEBUG, dev, + "Dirty NCSI channel state reset\n"); + ncsi_process_next_channel(ndp); + break; + } + if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) { hot_nc = nc; nc->state = NCSI_CHANNEL_ACTIVE; @@ -1191,6 +1350,150 @@ static struct notifier_block ncsi_inet6addr_notifier = { }; #endif /* CONFIG_IPV6 */ +static int ncsi_kick_channels(struct ncsi_dev_priv *ndp) +{ + struct ncsi_dev *nd = &ndp->ndev; + struct ncsi_channel *nc; + struct ncsi_package *np; + unsigned long flags; + unsigned int n = 0; + + NCSI_FOR_EACH_PACKAGE(ndp, np) { + NCSI_FOR_EACH_CHANNEL(np, nc) { + spin_lock_irqsave(&nc->lock, flags); + + /* Channels may be busy, mark dirty instead of + * kicking if; + * a) not ACTIVE (configured) + * b) in the channel_queue (to be configured) + * c) it's ndev is in the config state + */ + if (nc->state != NCSI_CHANNEL_ACTIVE) { + if ((ndp->ndev.state & 0xff00) == + ncsi_dev_state_config || + !list_empty(&nc->link)) { + netdev_printk(KERN_DEBUG, nd->dev, + "ncsi: channel %p marked dirty\n", + nc); + nc->reconfigure_needed = true; + } + spin_unlock_irqrestore(&nc->lock, flags); + continue; + } + + spin_unlock_irqrestore(&nc->lock, flags); + + ncsi_stop_channel_monitor(nc); + spin_lock_irqsave(&nc->lock, flags); + nc->state = NCSI_CHANNEL_INACTIVE; + spin_unlock_irqrestore(&nc->lock, flags); + + spin_lock_irqsave(&ndp->lock, flags); + list_add_tail_rcu(&nc->link, &ndp->channel_queue); + spin_unlock_irqrestore(&ndp->lock, flags); + + netdev_printk(KERN_DEBUG, nd->dev, + "ncsi: kicked channel %p\n", nc); + n++; + } + } + + return n; +} + +int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + struct ncsi_channel_filter *ncf; + struct ncsi_dev_priv *ndp; + unsigned int n_vids = 0; + struct vlan_vid *vlan; + struct ncsi_dev *nd; + bool found = false; + + if (vid == 0) + return 0; + + nd = ncsi_find_dev(dev); + if (!nd) { + netdev_warn(dev, "ncsi: No net_device?\n"); + return 0; + } + + ndp = TO_NCSI_DEV_PRIV(nd); + ncf = ndp->hot_channel->filters[NCSI_FILTER_VLAN]; + + /* Add the VLAN id to our internal list */ + list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { + n_vids++; + if (vlan->vid == vid) { + netdev_printk(KERN_DEBUG, dev, + "vid %u already registered\n", vid); + return 0; + } + } + + if (n_vids >= ncf->total) { + netdev_info(dev, + "NCSI Channel supports up to %u VLAN tags but %u are already set\n", + ncf->total, n_vids); + return -EINVAL; + } + + vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + if (!vlan) + return -ENOMEM; + + vlan->proto = proto; + vlan->vid = vid; + list_add_rcu(&vlan->list, &ndp->vlan_vids); + + netdev_printk(KERN_DEBUG, dev, "Added new vid %u\n", vid); + + found = ncsi_kick_channels(ndp) != 0; + + return found ? ncsi_process_next_channel(ndp) : 0; +} +EXPORT_SYMBOL_GPL(ncsi_vlan_rx_add_vid); + +int ncsi_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + struct vlan_vid *vlan, *tmp; + struct ncsi_dev_priv *ndp; + struct ncsi_dev *nd; + bool found = false; + + if (vid == 0) + return 0; + + nd = ncsi_find_dev(dev); + if (!nd) { + netdev_warn(dev, "ncsi: no net_device?\n"); + return 0; + } + + ndp = TO_NCSI_DEV_PRIV(nd); + + /* Remove the VLAN id from our internal list */ + list_for_each_entry_safe(vlan, tmp, &ndp->vlan_vids, list) + if (vlan->vid == vid) { + netdev_printk(KERN_DEBUG, dev, + "vid %u found, removing\n", vid); + list_del_rcu(&vlan->list); + found = true; + kfree(vlan); + } + + if (!found) { + netdev_err(dev, "ncsi: vid %u wasn't registered!\n", vid); + return -EINVAL; + } + + found = ncsi_kick_channels(ndp) != 0; + + return found ? ncsi_process_next_channel(ndp) : 0; +} +EXPORT_SYMBOL_GPL(ncsi_vlan_rx_kill_vid); + struct ncsi_dev *ncsi_register_dev(struct net_device *dev, void (*handler)(struct ncsi_dev *ndev)) { @@ -1215,6 +1518,7 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev, nd->handler = handler; ndp->pending_req_num = 0; INIT_LIST_HEAD(&ndp->channel_queue); + INIT_LIST_HEAD(&ndp->vlan_vids); INIT_WORK(&ndp->work, ncsi_dev_work); /* Initialize private NCSI device */ diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h index 3ea49ed0a935be3c9cd09511991edc574aa4b250..91b4b66438df8468056ecdefd670a1e5ad846a38 100644 --- a/net/ncsi/ncsi-pkt.h +++ b/net/ncsi/ncsi-pkt.h @@ -104,7 +104,7 @@ struct ncsi_cmd_svf_pkt { unsigned char index; /* VLAN table index */ unsigned char enable; /* Enable or disable */ __be32 checksum; /* Checksum */ - unsigned char pad[14]; + unsigned char pad[18]; }; /* Enable VLAN */ diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index 087db775b3dc798a3a3d255ddc5ece52fdd41c74..265b9a892d4171bc74572891edb631dabac98c41 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c @@ -354,7 +354,8 @@ static int ncsi_rsp_handler_svf(struct ncsi_request *nr) /* Add or remove the VLAN filter */ if (!(cmd->enable & 0x1)) { - ret = ncsi_remove_filter(nc, NCSI_FILTER_VLAN, cmd->index); + /* HW indexes from 1 */ + ret = ncsi_remove_filter(nc, NCSI_FILTER_VLAN, cmd->index - 1); } else { vlan = ntohs(cmd->vlan); ret = ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan); @@ -693,7 +694,14 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr) ncf->index = i; ncf->total = cnt; - ncf->bitmap = 0x0ul; + if (i == NCSI_FILTER_VLAN) { + /* Set VLAN filters active so they are cleared in + * first configuration state + */ + ncf->bitmap = U64_MAX; + } else { + ncf->bitmap = 0x0ul; + } nc->filters[i] = ncf; } diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 9b28864cc36a9e19406a015493ee3249bd2afd2c..e4a13cc8a2e7635841a29be9901412ab2904c3ae 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -636,6 +636,15 @@ config NFT_FWD_NETDEV help This option enables packet forwarding for the "netdev" family. +config NFT_FIB_NETDEV + depends on NFT_FIB_IPV4 + depends on NFT_FIB_IPV6 + tristate "Netfilter nf_tables netdev fib lookups support" + help + This option allows using the FIB expression from the netdev table. + The lookup will be delegated to the IPv4 or IPv6 FIB depending + on the protocol of the packet. + endif # NF_TABLES_NETDEV endif # NF_TABLES diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 91338091930141c0707239b04d0b8a42f05027b6..d3891c93edd6e32a9e3f38e660e2b35f11f427f9 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -100,6 +100,7 @@ obj-$(CONFIG_NFT_REDIR) += nft_redir.o obj-$(CONFIG_NFT_HASH) += nft_hash.o obj-$(CONFIG_NFT_FIB) += nft_fib.o obj-$(CONFIG_NFT_FIB_INET) += nft_fib_inet.o +obj-$(CONFIG_NFT_FIB_NETDEV) += nft_fib_netdev.o # nf_tables netdev obj-$(CONFIG_NFT_DUP_NETDEV) += nft_dup_netdev.o diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 974cf2a3795aaa8ea68a17d60349d4b1cfad9496..52cd2901a097b3b468f1107d9d870260aaff11e3 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -62,10 +62,182 @@ EXPORT_SYMBOL(nf_hooks_needed); #endif static DEFINE_MUTEX(nf_hook_mutex); + +/* max hooks per family/hooknum */ +#define MAX_HOOK_COUNT 1024 + #define nf_entry_dereference(e) \ rcu_dereference_protected(e, lockdep_is_held(&nf_hook_mutex)) -static struct nf_hook_entry __rcu **nf_hook_entry_head(struct net *net, const struct nf_hook_ops *reg) +static struct nf_hook_entries *allocate_hook_entries_size(u16 num) +{ + struct nf_hook_entries *e; + size_t alloc = sizeof(*e) + + sizeof(struct nf_hook_entry) * num + + sizeof(struct nf_hook_ops *) * num; + + if (num == 0) + return NULL; + + e = kvzalloc(alloc, GFP_KERNEL); + if (e) + e->num_hook_entries = num; + return e; +} + +static unsigned int accept_all(void *priv, + struct sk_buff *skb, + const struct nf_hook_state *state) +{ + return NF_ACCEPT; /* ACCEPT makes nf_hook_slow call next hook */ +} + +static const struct nf_hook_ops dummy_ops = { + .hook = accept_all, + .priority = INT_MIN, +}; + +static struct nf_hook_entries * +nf_hook_entries_grow(const struct nf_hook_entries *old, + const struct nf_hook_ops *reg) +{ + unsigned int i, alloc_entries, nhooks, old_entries; + struct nf_hook_ops **orig_ops = NULL; + struct nf_hook_ops **new_ops; + struct nf_hook_entries *new; + bool inserted = false; + + alloc_entries = 1; + old_entries = old ? old->num_hook_entries : 0; + + if (old) { + orig_ops = nf_hook_entries_get_hook_ops(old); + + for (i = 0; i < old_entries; i++) { + if (orig_ops[i] != &dummy_ops) + alloc_entries++; + } + } + + if (alloc_entries > MAX_HOOK_COUNT) + return ERR_PTR(-E2BIG); + + new = allocate_hook_entries_size(alloc_entries); + if (!new) + return ERR_PTR(-ENOMEM); + + new_ops = nf_hook_entries_get_hook_ops(new); + + i = 0; + nhooks = 0; + while (i < old_entries) { + if (orig_ops[i] == &dummy_ops) { + ++i; + continue; + } + if (inserted || reg->priority > orig_ops[i]->priority) { + new_ops[nhooks] = (void *)orig_ops[i]; + new->hooks[nhooks] = old->hooks[i]; + i++; + } else { + new_ops[nhooks] = (void *)reg; + new->hooks[nhooks].hook = reg->hook; + new->hooks[nhooks].priv = reg->priv; + inserted = true; + } + nhooks++; + } + + if (!inserted) { + new_ops[nhooks] = (void *)reg; + new->hooks[nhooks].hook = reg->hook; + new->hooks[nhooks].priv = reg->priv; + } + + return new; +} + +static void hooks_validate(const struct nf_hook_entries *hooks) +{ +#ifdef CONFIG_DEBUG_KERNEL + struct nf_hook_ops **orig_ops; + int prio = INT_MIN; + size_t i = 0; + + orig_ops = nf_hook_entries_get_hook_ops(hooks); + + for (i = 0; i < hooks->num_hook_entries; i++) { + if (orig_ops[i] == &dummy_ops) + continue; + + WARN_ON(orig_ops[i]->priority < prio); + + if (orig_ops[i]->priority > prio) + prio = orig_ops[i]->priority; + } +#endif +} + +/* + * __nf_hook_entries_try_shrink - try to shrink hook array + * + * @pp -- location of hook blob + * + * Hook unregistration must always succeed, so to-be-removed hooks + * are replaced by a dummy one that will just move to next hook. + * + * This counts the current dummy hooks, attempts to allocate new blob, + * copies the live hooks, then replaces and discards old one. + * + * return values: + * + * Returns address to free, or NULL. + */ +static void *__nf_hook_entries_try_shrink(struct nf_hook_entries __rcu **pp) +{ + struct nf_hook_entries *old, *new = NULL; + unsigned int i, j, skip = 0, hook_entries; + struct nf_hook_ops **orig_ops; + struct nf_hook_ops **new_ops; + + old = nf_entry_dereference(*pp); + if (WARN_ON_ONCE(!old)) + return NULL; + + orig_ops = nf_hook_entries_get_hook_ops(old); + for (i = 0; i < old->num_hook_entries; i++) { + if (orig_ops[i] == &dummy_ops) + skip++; + } + + /* if skip == hook_entries all hooks have been removed */ + hook_entries = old->num_hook_entries; + if (skip == hook_entries) + goto out_assign; + + if (skip == 0) + return NULL; + + hook_entries -= skip; + new = allocate_hook_entries_size(hook_entries); + if (!new) + return NULL; + + new_ops = nf_hook_entries_get_hook_ops(new); + for (i = 0, j = 0; i < old->num_hook_entries; i++) { + if (orig_ops[i] == &dummy_ops) + continue; + new->hooks[j] = old->hooks[i]; + new_ops[j] = (void *)orig_ops[i]; + j++; + } + hooks_validate(new); +out_assign: + rcu_assign_pointer(*pp, new); + return old; +} + +static struct nf_hook_entries __rcu **nf_hook_entry_head(struct net *net, const struct nf_hook_ops *reg) { if (reg->pf != NFPROTO_NETDEV) return net->nf.hooks[reg->pf]+reg->hooknum; @@ -76,13 +248,14 @@ static struct nf_hook_entry __rcu **nf_hook_entry_head(struct net *net, const st return ®->dev->nf_hooks_ingress; } #endif + WARN_ON_ONCE(1); return NULL; } int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) { - struct nf_hook_entry __rcu **pp; - struct nf_hook_entry *entry, *p; + struct nf_hook_entries *p, *new_hooks; + struct nf_hook_entries __rcu **pp; if (reg->pf == NFPROTO_NETDEV) { #ifndef CONFIG_NETFILTER_INGRESS @@ -98,23 +271,19 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) if (!pp) return -EINVAL; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - nf_hook_entry_init(entry, reg); - mutex_lock(&nf_hook_mutex); - /* Find the spot in the list */ - for (; (p = nf_entry_dereference(*pp)) != NULL; pp = &p->next) { - if (reg->priority < nf_hook_entry_priority(p)) - break; - } - rcu_assign_pointer(entry->next, p); - rcu_assign_pointer(*pp, entry); + p = nf_entry_dereference(*pp); + new_hooks = nf_hook_entries_grow(p, reg); + + if (!IS_ERR(new_hooks)) + rcu_assign_pointer(*pp, new_hooks); mutex_unlock(&nf_hook_mutex); + if (IS_ERR(new_hooks)) + return PTR_ERR(new_hooks); + + hooks_validate(new_hooks); #ifdef CONFIG_NETFILTER_INGRESS if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) net_inc_ingress_queue(); @@ -122,48 +291,74 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) #ifdef HAVE_JUMP_LABEL static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); #endif + synchronize_net(); + BUG_ON(p == new_hooks); + kvfree(p); return 0; } EXPORT_SYMBOL(nf_register_net_hook); -static struct nf_hook_entry * -__nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) +/* + * __nf_unregister_net_hook - remove a hook from blob + * + * @oldp: current address of hook blob + * @unreg: hook to unregister + * + * This cannot fail, hook unregistration must always succeed. + * Therefore replace the to-be-removed hook with a dummy hook. + */ +static void __nf_unregister_net_hook(struct nf_hook_entries *old, + const struct nf_hook_ops *unreg) { - struct nf_hook_entry __rcu **pp; - struct nf_hook_entry *p; - - pp = nf_hook_entry_head(net, reg); - if (WARN_ON_ONCE(!pp)) - return NULL; + struct nf_hook_ops **orig_ops; + bool found = false; + unsigned int i; - mutex_lock(&nf_hook_mutex); - for (; (p = nf_entry_dereference(*pp)) != NULL; pp = &p->next) { - if (nf_hook_entry_ops(p) == reg) { - rcu_assign_pointer(*pp, p->next); - break; - } - } - mutex_unlock(&nf_hook_mutex); - if (!p) { - WARN(1, "nf_unregister_net_hook: hook not found!\n"); - return NULL; + orig_ops = nf_hook_entries_get_hook_ops(old); + for (i = 0; i < old->num_hook_entries; i++) { + if (orig_ops[i] != unreg) + continue; + WRITE_ONCE(old->hooks[i].hook, accept_all); + WRITE_ONCE(orig_ops[i], &dummy_ops); + found = true; + break; } + + if (found) { #ifdef CONFIG_NETFILTER_INGRESS - if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) - net_dec_ingress_queue(); + if (unreg->pf == NFPROTO_NETDEV && unreg->hooknum == NF_NETDEV_INGRESS) + net_dec_ingress_queue(); #endif #ifdef HAVE_JUMP_LABEL - static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]); + static_key_slow_dec(&nf_hooks_needed[unreg->pf][unreg->hooknum]); #endif - - return p; + } else { + WARN_ONCE(1, "hook not found, pf %d num %d", unreg->pf, unreg->hooknum); + } } void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) { - struct nf_hook_entry *p = __nf_unregister_net_hook(net, reg); + struct nf_hook_entries __rcu **pp; + struct nf_hook_entries *p; unsigned int nfq; + pp = nf_hook_entry_head(net, reg); + if (!pp) + return; + + mutex_lock(&nf_hook_mutex); + + p = nf_entry_dereference(*pp); + if (WARN_ON_ONCE(!p)) { + mutex_unlock(&nf_hook_mutex); + return; + } + + __nf_unregister_net_hook(p, reg); + + p = __nf_hook_entries_try_shrink(pp); + mutex_unlock(&nf_hook_mutex); if (!p) return; @@ -173,7 +368,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) nfq = nf_queue_nf_hook_drop(net); if (nfq) synchronize_net(); - kfree(p); + kvfree(p); } EXPORT_SYMBOL(nf_unregister_net_hook); @@ -200,26 +395,59 @@ EXPORT_SYMBOL(nf_register_net_hooks); void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg, unsigned int hookcount) { - struct nf_hook_entry *to_free[16]; - unsigned int i, n, nfq; + struct nf_hook_entries *to_free[16], *p; + struct nf_hook_entries __rcu **pp; + unsigned int i, j, n; + + mutex_lock(&nf_hook_mutex); + for (i = 0; i < hookcount; i++) { + pp = nf_hook_entry_head(net, ®[i]); + if (!pp) + continue; + + p = nf_entry_dereference(*pp); + if (WARN_ON_ONCE(!p)) + continue; + __nf_unregister_net_hook(p, ®[i]); + } + mutex_unlock(&nf_hook_mutex); do { n = min_t(unsigned int, hookcount, ARRAY_SIZE(to_free)); - for (i = 0; i < n; i++) - to_free[i] = __nf_unregister_net_hook(net, ®[i]); + mutex_lock(&nf_hook_mutex); - synchronize_net(); + for (i = 0, j = 0; i < hookcount && j < n; i++) { + pp = nf_hook_entry_head(net, ®[i]); + if (!pp) + continue; + + p = nf_entry_dereference(*pp); + if (!p) + continue; + + to_free[j] = __nf_hook_entries_try_shrink(pp); + if (to_free[j]) + ++j; + } + + mutex_unlock(&nf_hook_mutex); + + if (j) { + unsigned int nfq; - /* need 2nd synchronize_net() if nfqueue is used, skb - * can get reinjected right before nf_queue_hook_drop() - */ - nfq = nf_queue_nf_hook_drop(net); - if (nfq) synchronize_net(); - for (i = 0; i < n; i++) - kfree(to_free[i]); + /* need 2nd synchronize_net() if nfqueue is used, skb + * can get reinjected right before nf_queue_hook_drop() + */ + nfq = nf_queue_nf_hook_drop(net); + if (nfq) + synchronize_net(); + + for (i = 0; i < j; i++) + kvfree(to_free[i]); + } reg += n; hookcount -= n; @@ -230,16 +458,15 @@ EXPORT_SYMBOL(nf_unregister_net_hooks); /* Returns 1 if okfn() needs to be executed by the caller, * -EPERM for NF_DROP, 0 otherwise. Caller must hold rcu_read_lock. */ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, - struct nf_hook_entry *entry) + const struct nf_hook_entries *e, unsigned int s) { unsigned int verdict; int ret; - do { - verdict = nf_hook_entry_hookfn(entry, skb, state); + for (; s < e->num_hook_entries; s++) { + verdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state); switch (verdict & NF_VERDICT_MASK) { case NF_ACCEPT: - entry = rcu_dereference(entry->next); break; case NF_DROP: kfree_skb(skb); @@ -248,8 +475,8 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, ret = -EPERM; return ret; case NF_QUEUE: - ret = nf_queue(skb, state, &entry, verdict); - if (ret == 1 && entry) + ret = nf_queue(skb, state, e, s, verdict); + if (ret == 1) continue; return ret; default: @@ -258,7 +485,7 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, */ return 0; } - } while (entry); + } return 1; } diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index f236c0bc7b3f3e171e4303dd7c5379f34011812f..51063d9ed0f75d53be7a59738bf859570cd67d9b 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h @@ -1041,12 +1041,24 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, static int mtype_head(struct ip_set *set, struct sk_buff *skb) { - const struct htype *h = set->data; + struct htype *h = set->data; const struct htable *t; struct nlattr *nested; size_t memsize; u8 htable_bits; + /* If any members have expired, set->elements will be wrong + * mytype_expire function will update it with the right count. + * we do not hold set->lock here, so grab it first. + * set->elements can still be incorrect in the case of a huge set, + * because elements might time out during the listing. + */ + if (SET_WITH_TIMEOUT(set)) { + spin_lock_bh(&set->lock); + mtype_expire(set, h); + spin_unlock_bh(&set->lock); + } + rcu_read_lock_bh(); t = rcu_dereference_bh_nfnl(h->table); memsize = mtype_ahash_memsize(h, t) + set->ext_size; diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index e31956b58abaf85404b60f1e3fa5a404d7ecc2c3..5cb7cac9177d8bb2b2a37e887aed7a8b7378980c 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -125,14 +125,12 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb) s->cnt.inbytes += skb->len; u64_stats_update_end(&s->syncp); - rcu_read_lock(); svc = rcu_dereference(dest->svc); s = this_cpu_ptr(svc->stats.cpustats); u64_stats_update_begin(&s->syncp); s->cnt.inpkts++; s->cnt.inbytes += skb->len; u64_stats_update_end(&s->syncp); - rcu_read_unlock(); s = this_cpu_ptr(ipvs->tot_stats.cpustats); u64_stats_update_begin(&s->syncp); @@ -159,14 +157,12 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb) s->cnt.outbytes += skb->len; u64_stats_update_end(&s->syncp); - rcu_read_lock(); svc = rcu_dereference(dest->svc); s = this_cpu_ptr(svc->stats.cpustats); u64_stats_update_begin(&s->syncp); s->cnt.outpkts++; s->cnt.outbytes += skb->len; u64_stats_update_end(&s->syncp); - rcu_read_unlock(); s = this_cpu_ptr(ipvs->tot_stats.cpustats); u64_stats_update_begin(&s->syncp); @@ -1222,7 +1218,6 @@ static struct ip_vs_conn *__ip_vs_rs_conn_out(unsigned int hooknum, if (!pptr) return NULL; - rcu_read_lock(); dest = ip_vs_find_real_service(ipvs, af, iph->protocol, &iph->saddr, pptr[0]); if (dest) { @@ -1237,7 +1232,6 @@ static struct ip_vs_conn *__ip_vs_rs_conn_out(unsigned int hooknum, pptr[0], pptr[1]); } } - rcu_read_unlock(); return cp; } @@ -1689,11 +1683,9 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related, if (dest) { struct ip_vs_dest_dst *dest_dst; - rcu_read_lock(); dest_dst = rcu_dereference(dest->dest_dst); if (dest_dst) mtu = dst_mtu(dest_dst->dst_cache); - rcu_read_unlock(); } if (mtu > 68 + sizeof(struct iphdr)) mtu -= sizeof(struct iphdr); @@ -2109,7 +2101,7 @@ ip_vs_forward_icmp_v6(void *priv, struct sk_buff *skb, #endif -static struct nf_hook_ops ip_vs_ops[] __read_mostly = { +static const struct nf_hook_ops ip_vs_ops[] = { /* After packet filtering, change source only for VS/NAT */ { .hook = ip_vs_reply4, diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 1fa3c2307b6ea0173bbcf13c3d0b5cca8c68cba9..4f940d7eb2f7e4587b6543219e801f80a5a19b79 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -550,18 +550,15 @@ bool ip_vs_has_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol, /* Check for "full" addressed entries */ hash = ip_vs_rs_hashkey(af, daddr, dport); - rcu_read_lock(); hlist_for_each_entry_rcu(dest, &ipvs->rs_table[hash], d_list) { if (dest->port == dport && dest->af == af && ip_vs_addr_equal(af, &dest->addr, daddr) && (dest->protocol == protocol || dest->vfwmark)) { /* HIT */ - rcu_read_unlock(); return true; } } - rcu_read_unlock(); return false; } diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index fb780be76d15a05c0d66e8a7f5ea58ee32dacdb9..3e17d32b629d18e97f85fe8e543431562cdf3c6e 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -269,13 +269,11 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, * hopefully it will succeed on the retransmitted * packet. */ - rcu_read_lock(); mangled = nf_nat_mangle_tcp_packet(skb, ct, ctinfo, iph->ihl * 4, start - data, end - start, buf, buf_len); - rcu_read_unlock(); if (mangled) { ip_vs_nfct_expect_related(skb, ct, n_cp, IPPROTO_TCP, 0, 0); diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 3ffad4adaddf97fb77946bdb3558b0d2fcecd88e..57c8ee66491eb8a66944afa3250396c36b11b218 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -24,9 +24,13 @@ sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, if (sh) { sch = skb_header_pointer(skb, iph->len + sizeof(_sctph), sizeof(_schunkh), &_schunkh); - if (sch && (sch->type == SCTP_CID_INIT || - sysctl_sloppy_sctp(ipvs))) + if (sch) { + if (sch->type == SCTP_CID_ABORT || + !(sysctl_sloppy_sctp(ipvs) || + sch->type == SCTP_CID_INIT)) + return 1; ports = &sh->source; + } } } else { ports = skb_header_pointer( @@ -38,7 +42,6 @@ sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, return 0; } - rcu_read_lock(); if (likely(!ip_vs_iph_inverse(iph))) svc = ip_vs_service_find(ipvs, af, skb->mark, iph->protocol, &iph->daddr, ports[1]); @@ -53,7 +56,6 @@ sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, * It seems that we are very loaded. * We have to drop this packet :( */ - rcu_read_unlock(); *verdict = NF_DROP; return 0; } @@ -67,11 +69,9 @@ sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, *verdict = ip_vs_leave(svc, skb, pd, iph); else *verdict = NF_DROP; - rcu_read_unlock(); return 0; } } - rcu_read_unlock(); /* NF_ACCEPT */ return 1; } @@ -526,12 +526,10 @@ static int sctp_app_conn_bind(struct ip_vs_conn *cp) /* Lookup application incarnations and bind the right one */ hash = sctp_app_hashkey(cp->vport); - rcu_read_lock(); list_for_each_entry_rcu(inc, &ipvs->sctp_apps[hash], p_list) { if (inc->port == cp->vport) { if (unlikely(!ip_vs_app_inc_get(inc))) break; - rcu_read_unlock(); IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->" "%s:%u to app %s on port %u\n", @@ -544,11 +542,10 @@ static int sctp_app_conn_bind(struct ip_vs_conn *cp) cp->app = inc; if (inc->init_conn) result = inc->init_conn(inc, cp); - goto out; + break; } } - rcu_read_unlock(); -out: + return result; } diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index 12dc8d5bc37d7ea03ba8448514a6d3caf03a62b0..121a321b91bea816909fc7acb9a2b4316ff7abc9 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -63,7 +63,6 @@ tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, } /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */ - rcu_read_lock(); if (likely(!ip_vs_iph_inverse(iph))) svc = ip_vs_service_find(ipvs, af, skb->mark, iph->protocol, @@ -80,7 +79,6 @@ tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, * It seems that we are very loaded. * We have to drop this packet :( */ - rcu_read_unlock(); *verdict = NF_DROP; return 0; } @@ -95,11 +93,9 @@ tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, *verdict = ip_vs_leave(svc, skb, pd, iph); else *verdict = NF_DROP; - rcu_read_unlock(); return 0; } } - rcu_read_unlock(); /* NF_ACCEPT */ return 1; } @@ -661,12 +657,10 @@ tcp_app_conn_bind(struct ip_vs_conn *cp) /* Lookup application incarnations and bind the right one */ hash = tcp_app_hashkey(cp->vport); - rcu_read_lock(); list_for_each_entry_rcu(inc, &ipvs->tcp_apps[hash], p_list) { if (inc->port == cp->vport) { if (unlikely(!ip_vs_app_inc_get(inc))) break; - rcu_read_unlock(); IP_VS_DBG_BUF(9, "%s(): Binding conn %s:%u->" "%s:%u to app %s on port %u\n", @@ -680,12 +674,10 @@ tcp_app_conn_bind(struct ip_vs_conn *cp) cp->app = inc; if (inc->init_conn) result = inc->init_conn(inc, cp); - goto out; + break; } } - rcu_read_unlock(); - out: return result; } diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index e494e9a88c7fb4d089845727bbc63778d352de4f..30e11cd6aa8a96562c7cfb4e1cb42a43e5ab830e 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -53,7 +53,6 @@ udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, return 0; } - rcu_read_lock(); if (likely(!ip_vs_iph_inverse(iph))) svc = ip_vs_service_find(ipvs, af, skb->mark, iph->protocol, &iph->daddr, ports[1]); @@ -69,7 +68,6 @@ udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, * It seems that we are very loaded. * We have to drop this packet :( */ - rcu_read_unlock(); *verdict = NF_DROP; return 0; } @@ -84,11 +82,9 @@ udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, *verdict = ip_vs_leave(svc, skb, pd, iph); else *verdict = NF_DROP; - rcu_read_unlock(); return 0; } } - rcu_read_unlock(); /* NF_ACCEPT */ return 1; } @@ -410,12 +406,10 @@ static int udp_app_conn_bind(struct ip_vs_conn *cp) /* Lookup application incarnations and bind the right one */ hash = udp_app_hashkey(cp->vport); - rcu_read_lock(); list_for_each_entry_rcu(inc, &ipvs->udp_apps[hash], p_list) { if (inc->port == cp->vport) { if (unlikely(!ip_vs_app_inc_get(inc))) break; - rcu_read_unlock(); IP_VS_DBG_BUF(9, "%s(): Binding conn %s:%u->" "%s:%u to app %s on port %u\n", @@ -429,12 +423,10 @@ static int udp_app_conn_bind(struct ip_vs_conn *cp) cp->app = inc; if (inc->init_conn) result = inc->init_conn(inc, cp); - goto out; + break; } } - rcu_read_unlock(); - out: return result; } diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 2eab1e0400f48a5816239cbb95a6b192169137bf..90d396814798e15d327aafe89c4bbb5a611da480 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -678,7 +678,6 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); if (__ip_vs_get_out_rt(cp->ipvs, cp->af, skb, NULL, iph->daddr, IP_VS_RT_MODE_NON_LOCAL, NULL, ipvsh) < 0) goto tx_error; @@ -689,14 +688,12 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; ip_vs_send_or_cont(NFPROTO_IPV4, skb, cp, 0); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; tx_error: kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -710,7 +707,6 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); if (__ip_vs_get_out_rt_v6(cp->ipvs, cp->af, skb, NULL, &iph->daddr, NULL, ipvsh, 0, IP_VS_RT_MODE_NON_LOCAL) < 0) @@ -720,14 +716,12 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; ip_vs_send_or_cont(NFPROTO_IPV6, skb, cp, 0); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; tx_error: kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -746,7 +740,6 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); /* check if it is a connection of no-client-port */ if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) { __be16 _pt, *p; @@ -815,14 +808,12 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; rc = ip_vs_nat_send_or_cont(NFPROTO_IPV4, skb, cp, local); - rcu_read_unlock(); LeaveFunction(10); return rc; tx_error: kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -837,7 +828,6 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); /* check if it is a connection of no-client-port */ if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT && !ipvsh->fragoffs)) { __be16 _pt, *p; @@ -906,7 +896,6 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; rc = ip_vs_nat_send_or_cont(NFPROTO_IPV6, skb, cp, local); - rcu_read_unlock(); LeaveFunction(10); return rc; @@ -914,7 +903,6 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, tx_error: LeaveFunction(10); kfree_skb(skb); - rcu_read_unlock(); return NF_STOLEN; } #endif @@ -1035,7 +1023,6 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); local = __ip_vs_get_out_rt(ipvs, cp->af, skb, cp->dest, cp->daddr.ip, IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL | @@ -1043,10 +1030,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_RT_MODE_TUNNEL, &saddr, ipvsh); if (local < 0) goto tx_error; - if (local) { - rcu_read_unlock(); + if (local) return ip_vs_send_or_cont(NFPROTO_IPV4, skb, cp, 1); - } rt = skb_rtable(skb); tdev = rt->dst.dev; @@ -1095,7 +1080,6 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, ip_local_out(net, skb->sk, skb); else if (ret == NF_DROP) kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); @@ -1104,7 +1088,6 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, tx_error: if (!IS_ERR(skb)) kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -1127,7 +1110,6 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); local = __ip_vs_get_out_rt_v6(cp->ipvs, cp->af, skb, cp->dest, &cp->daddr.in6, &saddr, ipvsh, 1, @@ -1136,10 +1118,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_RT_MODE_TUNNEL); if (local < 0) goto tx_error; - if (local) { - rcu_read_unlock(); + if (local) return ip_vs_send_or_cont(NFPROTO_IPV6, skb, cp, 1); - } rt = (struct rt6_info *) skb_dst(skb); tdev = rt->dst.dev; @@ -1185,7 +1165,6 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, ip6_local_out(cp->ipvs->net, skb->sk, skb); else if (ret == NF_DROP) kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); @@ -1194,7 +1173,6 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, tx_error: if (!IS_ERR(skb)) kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -1213,17 +1191,14 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); local = __ip_vs_get_out_rt(cp->ipvs, cp->af, skb, cp->dest, cp->daddr.ip, IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL | IP_VS_RT_MODE_KNOWN_NH, NULL, ipvsh); if (local < 0) goto tx_error; - if (local) { - rcu_read_unlock(); + if (local) return ip_vs_send_or_cont(NFPROTO_IPV4, skb, cp, 1); - } ip_send_check(ip_hdr(skb)); @@ -1231,14 +1206,12 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; ip_vs_send_or_cont(NFPROTO_IPV4, skb, cp, 0); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; tx_error: kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -1252,7 +1225,6 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rcu_read_lock(); local = __ip_vs_get_out_rt_v6(cp->ipvs, cp->af, skb, cp->dest, &cp->daddr.in6, NULL, ipvsh, 0, @@ -1261,23 +1233,19 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_RT_MODE_KNOWN_NH); if (local < 0) goto tx_error; - if (local) { - rcu_read_unlock(); + if (local) return ip_vs_send_or_cont(NFPROTO_IPV6, skb, cp, 1); - } /* Another hack: avoid icmp_send in ip_fragment */ skb->ignore_df = 1; ip_vs_send_or_cont(NFPROTO_IPV6, skb, cp, 0); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; tx_error: kfree_skb(skb); - rcu_read_unlock(); LeaveFunction(10); return NF_STOLEN; } @@ -1322,7 +1290,6 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, rt_mode = (hooknum != NF_INET_FORWARD) ? IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL | IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL; - rcu_read_lock(); local = __ip_vs_get_out_rt(cp->ipvs, cp->af, skb, cp->dest, cp->daddr.ip, rt_mode, NULL, iph); if (local < 0) @@ -1368,12 +1335,10 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; rc = ip_vs_nat_send_or_cont(NFPROTO_IPV4, skb, cp, local); - rcu_read_unlock(); goto out; tx_error: kfree_skb(skb); - rcu_read_unlock(); rc = NF_STOLEN; out: LeaveFunction(10); @@ -1414,7 +1379,6 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, rt_mode = (hooknum != NF_INET_FORWARD) ? IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL | IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL; - rcu_read_lock(); local = __ip_vs_get_out_rt_v6(cp->ipvs, cp->af, skb, cp->dest, &cp->daddr.in6, NULL, ipvsh, 0, rt_mode); if (local < 0) @@ -1460,12 +1424,10 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, skb->ignore_df = 1; rc = ip_vs_nat_send_or_cont(NFPROTO_IPV6, skb, cp, local); - rcu_read_unlock(); goto out; tx_error: kfree_skb(skb); - rcu_read_unlock(); rc = NF_STOLEN; out: LeaveFunction(10); diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c index 4e99cca61612ffe301cf5babb771b52170713b02..ecc3ab78463392c825ea63a03fefa4134666630c 100644 --- a/net/netfilter/nf_conntrack_broadcast.c +++ b/net/netfilter/nf_conntrack_broadcast.c @@ -40,7 +40,6 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) goto out; - rcu_read_lock(); in_dev = __in_dev_get_rcu(rt->dst.dev); if (in_dev != NULL) { for_primary_ifa(in_dev) { @@ -50,7 +49,6 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, } } endfor_ifa(in_dev); } - rcu_read_unlock(); if (mask == 0) goto out; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 9979f46c81dce32bc2288cfd4561c571f5bea4c5..01130392b7c0f536dc5afb74ff24d5b49cbd9f8a 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -56,6 +56,8 @@ #include #include +#include "nf_internals.h" + #define NF_CONNTRACK_VERSION "0.5.0" int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, @@ -96,19 +98,26 @@ static struct conntrack_gc_work conntrack_gc_work; void nf_conntrack_lock(spinlock_t *lock) __acquires(lock) { + /* 1) Acquire the lock */ spin_lock(lock); - while (unlikely(nf_conntrack_locks_all)) { - spin_unlock(lock); - /* - * Order the 'nf_conntrack_locks_all' load vs. the - * spin_unlock_wait() loads below, to ensure - * that 'nf_conntrack_locks_all_lock' is indeed held: - */ - smp_rmb(); /* spin_lock(&nf_conntrack_locks_all_lock) */ - spin_unlock_wait(&nf_conntrack_locks_all_lock); - spin_lock(lock); - } + /* 2) read nf_conntrack_locks_all, with ACQUIRE semantics + * It pairs with the smp_store_release() in nf_conntrack_all_unlock() + */ + if (likely(smp_load_acquire(&nf_conntrack_locks_all) == false)) + return; + + /* fast path failed, unlock */ + spin_unlock(lock); + + /* Slow path 1) get global lock */ + spin_lock(&nf_conntrack_locks_all_lock); + + /* Slow path 2) get the lock we want */ + spin_lock(lock); + + /* Slow path 3) release the global lock */ + spin_unlock(&nf_conntrack_locks_all_lock); } EXPORT_SYMBOL_GPL(nf_conntrack_lock); @@ -149,28 +158,27 @@ static void nf_conntrack_all_lock(void) int i; spin_lock(&nf_conntrack_locks_all_lock); - nf_conntrack_locks_all = true; - /* - * Order the above store of 'nf_conntrack_locks_all' against - * the spin_unlock_wait() loads below, such that if - * nf_conntrack_lock() observes 'nf_conntrack_locks_all' - * we must observe nf_conntrack_locks[] held: - */ - smp_mb(); /* spin_lock(&nf_conntrack_locks_all_lock) */ + nf_conntrack_locks_all = true; for (i = 0; i < CONNTRACK_LOCKS; i++) { - spin_unlock_wait(&nf_conntrack_locks[i]); + spin_lock(&nf_conntrack_locks[i]); + + /* This spin_unlock provides the "release" to ensure that + * nf_conntrack_locks_all==true is visible to everyone that + * acquired spin_lock(&nf_conntrack_locks[]). + */ + spin_unlock(&nf_conntrack_locks[i]); } } static void nf_conntrack_all_unlock(void) { - /* - * All prior stores must be complete before we clear + /* All prior stores must be complete before we clear * 'nf_conntrack_locks_all'. Otherwise nf_conntrack_lock() * might observe the false value but not the entire - * critical section: + * critical section. + * It pairs with the smp_load_acquire() in nf_conntrack_lock() */ smp_store_release(&nf_conntrack_locks_all, false); spin_unlock(&nf_conntrack_locks_all_lock); @@ -248,8 +256,8 @@ bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff, u_int16_t l3num, struct net *net, struct nf_conntrack_tuple *tuple) { - struct nf_conntrack_l3proto *l3proto; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l3proto *l3proto; + const struct nf_conntrack_l4proto *l4proto; unsigned int protoff; u_int8_t protonum; int ret; @@ -398,22 +406,19 @@ static void destroy_conntrack(struct nf_conntrack *nfct) { struct nf_conn *ct = (struct nf_conn *)nfct; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; pr_debug("destroy_conntrack(%p)\n", ct); - NF_CT_ASSERT(atomic_read(&nfct->use) == 0); + WARN_ON(atomic_read(&nfct->use) != 0); if (unlikely(nf_ct_is_template(ct))) { nf_ct_tmpl_free(ct); return; } - rcu_read_lock(); l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); if (l4proto->destroy) l4proto->destroy(ct); - rcu_read_unlock(); - local_bh_disable(); /* Expectations will have been removed in clean_from_lists, * except TFTP can create an expectation on the first packet, @@ -695,7 +700,7 @@ static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb, { /* This is the conntrack entry already in hashes that won race. */ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); if (l4proto->allow_clash && @@ -757,12 +762,11 @@ __nf_conntrack_confirm(struct sk_buff *skb) * connections for unconfirmed conns. But packet copies and * REJECT will give spurious warnings here. */ - /* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */ /* No external references means no one else could have * confirmed us. */ - NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); + WARN_ON(nf_ct_is_confirmed(ct)); pr_debug("Confirming conntrack %p\n", ct); /* We have to check the DYING flag after unlink to prevent * a race against nf_ct_get_next_corpse() possibly called from @@ -1084,7 +1088,7 @@ static void gc_worker(struct work_struct *work) static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work) { - INIT_DELAYED_WORK(&gc_work->dwork, gc_worker); + INIT_DEFERRABLE_WORK(&gc_work->dwork, gc_worker); gc_work->next_gc_run = HZ; gc_work->exiting = false; } @@ -1161,7 +1165,7 @@ void nf_conntrack_free(struct nf_conn *ct) /* A freed object has refcnt == 0, that's * the golden rule for SLAB_TYPESAFE_BY_RCU */ - NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 0); + WARN_ON(atomic_read(&ct->ct_general.use) != 0); nf_ct_ext_destroy(ct); nf_ct_ext_free(ct); @@ -1177,8 +1181,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free); static noinline struct nf_conntrack_tuple_hash * init_conntrack(struct net *net, struct nf_conn *tmpl, const struct nf_conntrack_tuple *tuple, - struct nf_conntrack_l3proto *l3proto, - struct nf_conntrack_l4proto *l4proto, + const struct nf_conntrack_l3proto *l3proto, + const struct nf_conntrack_l4proto *l4proto, struct sk_buff *skb, unsigned int dataoff, u32 hash) { @@ -1289,8 +1293,8 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, unsigned int dataoff, u_int16_t l3num, u_int8_t protonum, - struct nf_conntrack_l3proto *l3proto, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l3proto *l3proto, + const struct nf_conntrack_l4proto *l4proto) { const struct nf_conntrack_zone *zone; struct nf_conntrack_tuple tuple; @@ -1345,10 +1349,10 @@ unsigned int nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, struct sk_buff *skb) { + const struct nf_conntrack_l3proto *l3proto; + const struct nf_conntrack_l4proto *l4proto; struct nf_conn *ct, *tmpl; enum ip_conntrack_info ctinfo; - struct nf_conntrack_l3proto *l3proto; - struct nf_conntrack_l4proto *l4proto; unsigned int *timeouts; unsigned int dataoff; u_int8_t protonum; @@ -1415,7 +1419,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, /* Decide what timeout policy we want to apply to this flow. */ timeouts = nf_ct_timeout_lookup(net, ct, l4proto); - ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts); + ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, timeouts); if (ret <= 0) { /* Invalid: inverse of the return code tells * the netfilter core what to do */ @@ -1469,7 +1473,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, struct nf_conn_help *help = nfct_help(ct); /* Should be unconfirmed, so not in hash table yet */ - NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); + WARN_ON(nf_ct_is_confirmed(ct)); pr_debug("Altering reply tuple of %p to ", ct); nf_ct_dump_tuple(newreply); @@ -1491,7 +1495,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, unsigned long extra_jiffies, int do_acct) { - NF_CT_ASSERT(skb); + WARN_ON(!skb); /* Only update if this is not a fixed timeout */ if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) @@ -1689,6 +1693,18 @@ __nf_ct_unconfirmed_destroy(struct net *net) } } +void nf_ct_unconfirmed_destroy(struct net *net) +{ + might_sleep(); + + if (atomic_read(&net->ct.count) > 0) { + __nf_ct_unconfirmed_destroy(net); + nf_queue_nf_hook_drop(net); + synchronize_net(); + } +} +EXPORT_SYMBOL_GPL(nf_ct_unconfirmed_destroy); + void nf_ct_iterate_cleanup_net(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data, u32 portid, int report) @@ -1700,14 +1716,10 @@ void nf_ct_iterate_cleanup_net(struct net *net, if (atomic_read(&net->ct.count) == 0) return; - __nf_ct_unconfirmed_destroy(net); - d.iter = iter; d.data = data; d.net = net; - synchronize_net(); - nf_ct_iterate_cleanup(iter_net_only, &d, portid, report); } EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup_net); @@ -1733,6 +1745,7 @@ nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data), void *data) if (atomic_read(&net->ct.count) == 0) continue; __nf_ct_unconfirmed_destroy(net); + nf_queue_nf_hook_drop(net); } rtnl_unlock(); diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 899c2c36da136fe3e7268e44437a8d49d73789e2..64778f9a85481fd69faff2fcd0eaa64031ab06d9 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -51,8 +51,8 @@ void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, struct nf_conn_help *master_help = nfct_help(exp->master); struct net *net = nf_ct_exp_net(exp); - NF_CT_ASSERT(master_help); - NF_CT_ASSERT(!timer_pending(&exp->timeout)); + WARN_ON(!master_help); + WARN_ON(timer_pending(&exp->timeout)); hlist_del_rcu(&exp->hnode); net->ct.expect_count--; @@ -368,12 +368,6 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) /* two references : one for hash insert, one for the timer */ refcount_add(2, &exp->use); - hlist_add_head_rcu(&exp->lnode, &master_help->expectations); - master_help->expecting[exp->class]++; - - hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); - net->ct.expect_count++; - setup_timer(&exp->timeout, nf_ct_expectation_timed_out, (unsigned long)exp); helper = rcu_dereference_protected(master_help->helper, @@ -384,6 +378,12 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) } add_timer(&exp->timeout); + hlist_add_head_rcu(&exp->lnode, &master_help->expectations); + master_help->expecting[exp->class]++; + + hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); + net->ct.expect_count++; + NF_CT_STAT_INC(net, expect_create); } @@ -474,6 +474,60 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, } EXPORT_SYMBOL_GPL(nf_ct_expect_related_report); +void nf_ct_expect_iterate_destroy(bool (*iter)(struct nf_conntrack_expect *e, void *data), + void *data) +{ + struct nf_conntrack_expect *exp; + const struct hlist_node *next; + unsigned int i; + + spin_lock_bh(&nf_conntrack_expect_lock); + + for (i = 0; i < nf_ct_expect_hsize; i++) { + hlist_for_each_entry_safe(exp, next, + &nf_ct_expect_hash[i], + hnode) { + if (iter(exp, data) && del_timer(&exp->timeout)) { + nf_ct_unlink_expect(exp); + nf_ct_expect_put(exp); + } + } + } + + spin_unlock_bh(&nf_conntrack_expect_lock); +} +EXPORT_SYMBOL_GPL(nf_ct_expect_iterate_destroy); + +void nf_ct_expect_iterate_net(struct net *net, + bool (*iter)(struct nf_conntrack_expect *e, void *data), + void *data, + u32 portid, int report) +{ + struct nf_conntrack_expect *exp; + const struct hlist_node *next; + unsigned int i; + + spin_lock_bh(&nf_conntrack_expect_lock); + + for (i = 0; i < nf_ct_expect_hsize; i++) { + hlist_for_each_entry_safe(exp, next, + &nf_ct_expect_hash[i], + hnode) { + + if (!net_eq(nf_ct_exp_net(exp), net)) + continue; + + if (iter(exp, data) && del_timer(&exp->timeout)) { + nf_ct_unlink_expect_report(exp, portid, report); + nf_ct_expect_put(exp); + } + } + } + + spin_unlock_bh(&nf_conntrack_expect_lock); +} +EXPORT_SYMBOL_GPL(nf_ct_expect_iterate_net); + #ifdef CONFIG_NF_CONNTRACK_PROCFS struct ct_expect_iter_state { struct seq_net_private p; diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 6c605e88ebae238ce618b9e808a4da0dc697d95c..9fe0ddc333fbb263d98e639b1cb869b24e0b619c 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -47,7 +47,7 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) struct nf_ct_ext_type *t; /* Conntrack must not be confirmed to avoid races on reallocation. */ - NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); + WARN_ON(nf_ct_is_confirmed(ct)); old = ct->ext; diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 9129bb3b51535a76f3aeef83c8f16fb13ee6f656..551a1eddf0fab75eccf803b9711e069e61e60d5d 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -437,12 +437,22 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) } EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); -void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) +static bool expect_iter_me(struct nf_conntrack_expect *exp, void *data) { - struct nf_conntrack_expect *exp; - const struct hlist_node *next; - unsigned int i; + struct nf_conn_help *help = nfct_help(exp->master); + const struct nf_conntrack_helper *me = data; + const struct nf_conntrack_helper *this; + + if (exp->helper == me) + return true; + this = rcu_dereference_protected(help->helper, + lockdep_is_held(&nf_conntrack_expect_lock)); + return this == me; +} + +void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) +{ mutex_lock(&nf_ct_helper_mutex); hlist_del_rcu(&me->hnode); nf_ct_helper_count--; @@ -453,21 +463,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) */ synchronize_rcu(); - /* Get rid of expectations */ - spin_lock_bh(&nf_conntrack_expect_lock); - for (i = 0; i < nf_ct_expect_hsize; i++) { - hlist_for_each_entry_safe(exp, next, - &nf_ct_expect_hash[i], hnode) { - struct nf_conn_help *help = nfct_help(exp->master); - if ((rcu_dereference_protected( - help->helper, - lockdep_is_held(&nf_conntrack_expect_lock) - ) == me || exp->helper == me)) - nf_ct_remove_expect(exp); - } - } - spin_unlock_bh(&nf_conntrack_expect_lock); - + nf_ct_expect_iterate_destroy(expect_iter_me, NULL); nf_ct_iterate_destroy(unhelp, me); } EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c index cf9ace70bececf1573d8ef2d6d75387155dc6258..397e6911214f86fbfc799dd814395a0562732b1f 100644 --- a/net/netfilter/nf_conntrack_l3proto_generic.c +++ b/net/netfilter/nf_conntrack_l3proto_generic.c @@ -49,11 +49,6 @@ static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -static void generic_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ -} - static int generic_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, unsigned int *dataoff, u_int8_t *protonum) { @@ -64,10 +59,8 @@ static int generic_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, struct nf_conntrack_l3proto nf_conntrack_l3proto_generic __read_mostly = { .l3proto = PF_UNSPEC, - .name = "unknown", .pkt_to_tuple = generic_pkt_to_tuple, .invert_tuple = generic_invert_tuple, - .print_tuple = generic_print_tuple, .get_l4proto = generic_get_l4proto, }; EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 7999e70c3bfbe69f1374087cf9bd8c16d7e813cd..de4053d84364b245e1593f7fa7d1d3cbff2de4fe 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -61,8 +61,8 @@ MODULE_LICENSE("GPL"); static char __initdata version[] = "0.93"; static int ctnetlink_dump_tuples_proto(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_l4proto *l4proto) { int ret = 0; struct nlattr *nest_parms; @@ -86,7 +86,7 @@ static int ctnetlink_dump_tuples_proto(struct sk_buff *skb, static int ctnetlink_dump_tuples_ip(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple, - struct nf_conntrack_l3proto *l3proto) + const struct nf_conntrack_l3proto *l3proto) { int ret = 0; struct nlattr *nest_parms; @@ -109,9 +109,9 @@ static int ctnetlink_dump_tuples_ip(struct sk_buff *skb, static int ctnetlink_dump_tuples(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { + const struct nf_conntrack_l3proto *l3proto; + const struct nf_conntrack_l4proto *l4proto; int ret; - struct nf_conntrack_l3proto *l3proto; - struct nf_conntrack_l4proto *l4proto; rcu_read_lock(); l3proto = __nf_ct_l3proto_find(tuple->src.l3num); @@ -163,7 +163,7 @@ static int ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct) static int ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct) { - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; struct nlattr *nest_proto; int ret; @@ -535,17 +535,16 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, static inline size_t ctnetlink_proto_size(const struct nf_conn *ct) { - struct nf_conntrack_l3proto *l3proto; - struct nf_conntrack_l4proto *l4proto; - size_t len = 0; + const struct nf_conntrack_l3proto *l3proto; + const struct nf_conntrack_l4proto *l4proto; + size_t len; - rcu_read_lock(); l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); - len += l3proto->nla_size; + len = l3proto->nla_size; + len *= 3u; /* ORIG, REPLY, MASTER */ l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); len += l4proto->nla_size; - rcu_read_unlock(); return len; } @@ -664,7 +663,6 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) nfmsg->version = NFNETLINK_V0; nfmsg->res_id = 0; - rcu_read_lock(); zone = nf_ct_zone(ct); nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); @@ -736,8 +734,6 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) && ctnetlink_dump_mark(skb, ct) < 0) goto nla_put_failure; #endif - rcu_read_unlock(); - nlmsg_end(skb, nlh); err = nfnetlink_send(skb, net, item->portid, group, item->report, GFP_ATOMIC); @@ -747,7 +743,6 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) return 0; nla_put_failure: - rcu_read_unlock(); nlmsg_cancel(skb, nlh); nlmsg_failure: kfree_skb(skb); @@ -941,8 +936,8 @@ static const struct nla_policy proto_nla_policy[CTA_PROTO_MAX+1] = { static int ctnetlink_parse_tuple_proto(struct nlattr *attr, struct nf_conntrack_tuple *tuple) { + const struct nf_conntrack_l4proto *l4proto; struct nlattr *tb[CTA_PROTO_MAX+1]; - struct nf_conntrack_l4proto *l4proto; int ret = 0; ret = nla_parse_nested(tb, CTA_PROTO_MAX, attr, proto_nla_policy, @@ -1585,8 +1580,8 @@ static int ctnetlink_change_protoinfo(struct nf_conn *ct, const struct nlattr * const cda[]) { const struct nlattr *attr = cda[CTA_PROTOINFO]; + const struct nf_conntrack_l4proto *l4proto; struct nlattr *tb[CTA_PROTOINFO_MAX+1]; - struct nf_conntrack_l4proto *l4proto; int err = 0; err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy, @@ -2213,7 +2208,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct) const struct nf_conntrack_zone *zone; struct nlattr *nest_parms; - rcu_read_lock(); zone = nf_ct_zone(ct); nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); @@ -2272,11 +2266,9 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct) #endif if (ctnetlink_dump_labels(skb, ct) < 0) goto nla_put_failure; - rcu_read_unlock(); return 0; nla_put_failure: - rcu_read_unlock(); return -ENOSPC; } @@ -2483,11 +2475,11 @@ static int ctnetlink_exp_dump_mask(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple_mask *mask) { - int ret; - struct nf_conntrack_l3proto *l3proto; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l3proto *l3proto; + const struct nf_conntrack_l4proto *l4proto; struct nf_conntrack_tuple m; struct nlattr *nest_parms; + int ret; memset(&m, 0xFF, sizeof(m)); memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3)); @@ -2661,17 +2653,14 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) nfmsg->version = NFNETLINK_V0; nfmsg->res_id = 0; - rcu_read_lock(); if (ctnetlink_exp_dump_expect(skb, exp) < 0) goto nla_put_failure; - rcu_read_unlock(); nlmsg_end(skb, nlh); nfnetlink_send(skb, net, item->portid, group, item->report, GFP_ATOMIC); return 0; nla_put_failure: - rcu_read_unlock(); nlmsg_cancel(skb, nlh); nlmsg_failure: kfree_skb(skb); @@ -2910,6 +2899,21 @@ static int ctnetlink_get_expect(struct net *net, struct sock *ctnl, return err == -EAGAIN ? -ENOBUFS : err; } +static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data) +{ + const struct nf_conn_help *m_help; + const char *name = data; + + m_help = nfct_help(exp->master); + + return strcmp(m_help->helper->name, name) == 0; +} + +static bool expect_iter_all(struct nf_conntrack_expect *exp, void *data) +{ + return true; +} + static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const cda[], @@ -2918,10 +2922,8 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, struct nf_conntrack_expect *exp; struct nf_conntrack_tuple tuple; struct nfgenmsg *nfmsg = nlmsg_data(nlh); - struct hlist_node *next; u_int8_t u3 = nfmsg->nfgen_family; struct nf_conntrack_zone zone; - unsigned int i; int err; if (cda[CTA_EXPECT_TUPLE]) { @@ -2961,49 +2963,15 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, nf_ct_expect_put(exp); } else if (cda[CTA_EXPECT_HELP_NAME]) { char *name = nla_data(cda[CTA_EXPECT_HELP_NAME]); - struct nf_conn_help *m_help; - - /* delete all expectations for this helper */ - spin_lock_bh(&nf_conntrack_expect_lock); - for (i = 0; i < nf_ct_expect_hsize; i++) { - hlist_for_each_entry_safe(exp, next, - &nf_ct_expect_hash[i], - hnode) { - - if (!net_eq(nf_ct_exp_net(exp), net)) - continue; - m_help = nfct_help(exp->master); - if (!strcmp(m_help->helper->name, name) && - del_timer(&exp->timeout)) { - nf_ct_unlink_expect_report(exp, - NETLINK_CB(skb).portid, - nlmsg_report(nlh)); - nf_ct_expect_put(exp); - } - } - } - spin_unlock_bh(&nf_conntrack_expect_lock); + nf_ct_expect_iterate_net(net, expect_iter_name, name, + NETLINK_CB(skb).portid, + nlmsg_report(nlh)); } else { /* This basically means we have to flush everything*/ - spin_lock_bh(&nf_conntrack_expect_lock); - for (i = 0; i < nf_ct_expect_hsize; i++) { - hlist_for_each_entry_safe(exp, next, - &nf_ct_expect_hash[i], - hnode) { - - if (!net_eq(nf_ct_exp_net(exp), net)) - continue; - - if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect_report(exp, - NETLINK_CB(skb).portid, - nlmsg_report(nlh)); - nf_ct_expect_put(exp); - } - } - } - spin_unlock_bh(&nf_conntrack_expect_lock); + nf_ct_expect_iterate_net(net, expect_iter_all, NULL, + NETLINK_CB(skb).portid, + nlmsg_report(nlh)); } return 0; diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 6959e93063d4c957017b97e08dfca27b775461c2..11562f2a08bb0d21f97831dcf7ab1ca539ce334e 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -113,7 +113,6 @@ static void pptp_expectfn(struct nf_conn *ct, /* Can you see how rusty this code is, compared with the pre-2.6.11 * one? That's what happened to my shiny newnat of 2002 ;( -HW */ - rcu_read_lock(); nf_nat_pptp_expectfn = rcu_dereference(nf_nat_pptp_hook_expectfn); if (nf_nat_pptp_expectfn && ct->master->status & IPS_NAT_MASK) nf_nat_pptp_expectfn(ct, exp); @@ -136,7 +135,6 @@ static void pptp_expectfn(struct nf_conn *ct, pr_debug("not found\n"); } } - rcu_read_unlock(); } static int destroy_sibling_or_exp(struct net *net, struct nf_conn *ct, diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 1dcad229c3cc7290c9e89bea109ebf6098e79b21..b3e489c859ec442e654ab007ec344aa8b7c00940 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -65,7 +65,7 @@ nf_ct_unregister_sysctl(struct ctl_table_header **header, } #endif -struct nf_conntrack_l4proto * +const struct nf_conntrack_l4proto * __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto) { if (unlikely(l3proto >= NFPROTO_NUMPROTO || nf_ct_protos[l3proto] == NULL)) @@ -77,7 +77,7 @@ EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find); /* this is guaranteed to always return a valid protocol helper, since * it falls back to generic_protocol */ -struct nf_conntrack_l3proto * +const struct nf_conntrack_l3proto * nf_ct_l3proto_find_get(u_int16_t l3proto) { struct nf_conntrack_l3proto *p; @@ -95,8 +95,8 @@ EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get); int nf_ct_l3proto_try_module_get(unsigned short l3proto) { + const struct nf_conntrack_l3proto *p; int ret; - struct nf_conntrack_l3proto *p; retry: p = nf_ct_l3proto_find_get(l3proto); if (p == &nf_conntrack_l3proto_generic) { @@ -173,10 +173,10 @@ void nf_ct_netns_put(struct net *net, u8 nfproto) } EXPORT_SYMBOL_GPL(nf_ct_netns_put); -struct nf_conntrack_l4proto * +const struct nf_conntrack_l4proto * nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num) { - struct nf_conntrack_l4proto *p; + const struct nf_conntrack_l4proto *p; rcu_read_lock(); p = __nf_ct_l4proto_find(l3num, l4num); @@ -188,7 +188,7 @@ nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num) } EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get); -void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p) +void nf_ct_l4proto_put(const struct nf_conntrack_l4proto *p) { module_put(p->me); } @@ -196,28 +196,28 @@ EXPORT_SYMBOL_GPL(nf_ct_l4proto_put); static int kill_l3proto(struct nf_conn *i, void *data) { - return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto; + return nf_ct_l3num(i) == ((const struct nf_conntrack_l3proto *)data)->l3proto; } static int kill_l4proto(struct nf_conn *i, void *data) { - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; l4proto = data; return nf_ct_protonum(i) == l4proto->l4proto && nf_ct_l3num(i) == l4proto->l3proto; } -int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto) +int nf_ct_l3proto_register(const struct nf_conntrack_l3proto *proto) { int ret = 0; struct nf_conntrack_l3proto *old; if (proto->l3proto >= NFPROTO_NUMPROTO) return -EBUSY; - - if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size) +#if IS_ENABLED(CONFIG_NF_CT_NETLINK) + if (proto->tuple_to_nlattr && proto->nla_size == 0) return -EINVAL; - +#endif mutex_lock(&nf_ct_proto_mutex); old = rcu_dereference_protected(nf_ct_l3protos[proto->l3proto], lockdep_is_held(&nf_ct_proto_mutex)); @@ -226,9 +226,6 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto) goto out_unlock; } - if (proto->nlattr_tuple_size) - proto->nla_size = 3 * proto->nlattr_tuple_size(); - rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto); out_unlock: @@ -238,21 +235,7 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto) } EXPORT_SYMBOL_GPL(nf_ct_l3proto_register); -#ifdef CONFIG_SYSCTL -extern unsigned int nf_conntrack_default_on; - -int nf_ct_l3proto_pernet_register(struct net *net, - struct nf_conntrack_l3proto *proto) -{ - if (nf_conntrack_default_on == 0) - return 0; - - return proto->net_ns_get ? proto->net_ns_get(net) : 0; -} -EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_register); -#endif - -void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto) +void nf_ct_l3proto_unregister(const struct nf_conntrack_l3proto *proto) { BUG_ON(proto->l3proto >= NFPROTO_NUMPROTO); @@ -266,27 +249,12 @@ void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto) synchronize_rcu(); /* Remove all contrack entries for this protocol */ - nf_ct_iterate_destroy(kill_l3proto, proto); + nf_ct_iterate_destroy(kill_l3proto, (void*)proto); } EXPORT_SYMBOL_GPL(nf_ct_l3proto_unregister); -void nf_ct_l3proto_pernet_unregister(struct net *net, - struct nf_conntrack_l3proto *proto) -{ - /* - * nf_conntrack_default_on *might* have registered hooks. - * ->net_ns_put must cope with more puts() than get(), i.e. - * if nf_conntrack_default_on was 0 at time of - * nf_ct_l3proto_pernet_register invocation this net_ns_put() - * should be a noop. - */ - if (proto->net_ns_put) - proto->net_ns_put(net); -} -EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister); - static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l4proto *l4proto) { if (l4proto->get_net_proto) { /* statically built-in protocols use static per-net */ @@ -301,7 +269,7 @@ static struct nf_proto_net *nf_ct_l4proto_net(struct net *net, static int nf_ct_l4proto_register_sysctl(struct net *net, struct nf_proto_net *pn, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l4proto *l4proto) { int err = 0; @@ -324,8 +292,8 @@ int nf_ct_l4proto_register_sysctl(struct net *net, static void nf_ct_l4proto_unregister_sysctl(struct net *net, - struct nf_proto_net *pn, - struct nf_conntrack_l4proto *l4proto) + struct nf_proto_net *pn, + const struct nf_conntrack_l4proto *l4proto) { #ifdef CONFIG_SYSCTL if (pn->ctl_table_header != NULL) @@ -395,7 +363,7 @@ int nf_ct_l4proto_register_one(struct nf_conntrack_l4proto *l4proto) EXPORT_SYMBOL_GPL(nf_ct_l4proto_register_one); int nf_ct_l4proto_pernet_register_one(struct net *net, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l4proto *l4proto) { int ret = 0; struct nf_proto_net *pn = NULL; @@ -420,7 +388,7 @@ int nf_ct_l4proto_pernet_register_one(struct net *net, } EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register_one); -static void __nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *l4proto) +static void __nf_ct_l4proto_unregister_one(const struct nf_conntrack_l4proto *l4proto) { BUG_ON(l4proto->l3proto >= ARRAY_SIZE(nf_ct_protos)); @@ -433,7 +401,7 @@ static void __nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *l4proto) &nf_conntrack_l4proto_generic); } -void nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *l4proto) +void nf_ct_l4proto_unregister_one(const struct nf_conntrack_l4proto *l4proto) { mutex_lock(&nf_ct_proto_mutex); __nf_ct_l4proto_unregister_one(l4proto); @@ -444,7 +412,7 @@ void nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *l4proto) EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister_one); void nf_ct_l4proto_pernet_unregister_one(struct net *net, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l4proto *l4proto) { struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto); @@ -469,8 +437,8 @@ int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto[], } if (i != num_proto) { ver = l4proto[i]->l3proto == PF_INET6 ? 6 : 4; - pr_err("nf_conntrack_ipv%d: can't register %s%d proto.\n", - ver, l4proto[i]->name, ver); + pr_err("nf_conntrack_ipv%d: can't register l4 %d proto.\n", + ver, l4proto[i]->l4proto); nf_ct_l4proto_unregister(l4proto, i); } return ret; @@ -478,7 +446,7 @@ int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto[], EXPORT_SYMBOL_GPL(nf_ct_l4proto_register); int nf_ct_l4proto_pernet_register(struct net *net, - struct nf_conntrack_l4proto *l4proto[], + struct nf_conntrack_l4proto *const l4proto[], unsigned int num_proto) { int ret = -EINVAL; @@ -490,8 +458,8 @@ int nf_ct_l4proto_pernet_register(struct net *net, break; } if (i != num_proto) { - pr_err("nf_conntrack_%s%d: pernet registration failed\n", - l4proto[i]->name, + pr_err("nf_conntrack_proto_%d %d: pernet registration failed\n", + l4proto[i]->l4proto, l4proto[i]->l3proto == PF_INET6 ? 6 : 4); nf_ct_l4proto_pernet_unregister(net, l4proto, i); } @@ -514,8 +482,8 @@ void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto[], EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister); void nf_ct_l4proto_pernet_unregister(struct net *net, - struct nf_conntrack_l4proto *l4proto[], - unsigned int num_proto) + struct nf_conntrack_l4proto *const l4proto[], + unsigned int num_proto) { while (num_proto-- != 0) nf_ct_l4proto_pernet_unregister_one(net, l4proto[num_proto]); diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index 4707d997558af98a2057c418348f1776667ec606..0f5a4d79f6b85637277371f1705c04b9235f2324 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -469,7 +469,7 @@ static unsigned int *dccp_get_timeouts(struct net *net) static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info ctinfo, - u_int8_t pf, unsigned int hooknum, + u_int8_t pf, unsigned int *timeouts) { struct net *net = nf_ct_net(ct); @@ -623,18 +623,12 @@ static bool dccp_can_early_drop(const struct nf_conn *ct) return false; } -static void dccp_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "sport=%hu dport=%hu ", - ntohs(tuple->src.u.dccp.port), - ntohs(tuple->dst.u.dccp.port)); -} - +#ifdef CONFIG_NF_CONNTRACK_PROCFS static void dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct) { seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]); } +#endif #if IS_ENABLED(CONFIG_NF_CT_NETLINK) static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, @@ -880,7 +874,6 @@ static struct nf_proto_net *dccp_get_net_proto(struct net *net) struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = { .l3proto = AF_INET, .l4proto = IPPROTO_DCCP, - .name = "dccp", .pkt_to_tuple = dccp_pkt_to_tuple, .invert_tuple = dccp_invert_tuple, .new = dccp_new, @@ -888,8 +881,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = { .get_timeouts = dccp_get_timeouts, .error = dccp_error, .can_early_drop = dccp_can_early_drop, - .print_tuple = dccp_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = dccp_print_conntrack, +#endif #if IS_ENABLED(CONFIG_NF_CT_NETLINK) .to_nlattr = dccp_to_nlattr, .nlattr_size = dccp_nlattr_size, @@ -916,7 +910,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4); struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = { .l3proto = AF_INET6, .l4proto = IPPROTO_DCCP, - .name = "dccp", .pkt_to_tuple = dccp_pkt_to_tuple, .invert_tuple = dccp_invert_tuple, .new = dccp_new, @@ -924,8 +917,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = { .get_timeouts = dccp_get_timeouts, .error = dccp_error, .can_early_drop = dccp_can_early_drop, - .print_tuple = dccp_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = dccp_print_conntrack, +#endif #if IS_ENABLED(CONFIG_NF_CT_NETLINK) .to_nlattr = dccp_to_nlattr, .nlattr_size = dccp_nlattr_size, diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index d5868bad33a7ef1fd85e4dfffe024041d048d00a..9cd40700842e6c6aeb254c6b2583f610d51db393 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -17,21 +17,9 @@ static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; static bool nf_generic_should_process(u8 proto) { switch (proto) { -#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE - case IPPROTO_SCTP: - return false; -#endif -#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE - case IPPROTO_DCCP: - return false; -#endif #ifdef CONFIG_NF_CT_PROTO_GRE_MODULE case IPPROTO_GRE: return false; -#endif -#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE - case IPPROTO_UDPLITE: - return false; #endif default: return true; @@ -62,12 +50,6 @@ static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -/* Print out the per-protocol part of the tuple. */ -static void generic_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ -} - static unsigned int *generic_get_timeouts(struct net *net) { return &(generic_pernet(net)->timeout); @@ -79,7 +61,6 @@ static int generic_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeout) { nf_ct_refresh_acct(ct, ctinfo, skb, *timeout); @@ -187,10 +168,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = { .l3proto = PF_UNSPEC, .l4proto = 255, - .name = "unknown", .pkt_to_tuple = generic_pkt_to_tuple, .invert_tuple = generic_invert_tuple, - .print_tuple = generic_print_tuple, .packet = generic_packet, .get_timeouts = generic_get_timeouts, .new = generic_new, diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 87bb40a3feb58e371e3fc899ab7c8b4dd2f38859..09a90484c27d585bfca7d4761f68a58afb15a2b0 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -224,15 +224,7 @@ static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, return true; } -/* print gre part of tuple */ -static void gre_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "srckey=0x%x dstkey=0x%x ", - ntohs(tuple->src.u.gre.key), - ntohs(tuple->dst.u.gre.key)); -} - +#ifdef CONFIG_NF_CONNTRACK_PROCFS /* print private data for conntrack */ static void gre_print_conntrack(struct seq_file *s, struct nf_conn *ct) { @@ -240,6 +232,7 @@ static void gre_print_conntrack(struct seq_file *s, struct nf_conn *ct) (ct->proto.gre.timeout / HZ), (ct->proto.gre.stream_timeout / HZ)); } +#endif static unsigned int *gre_get_timeouts(struct net *net) { @@ -252,7 +245,6 @@ static int gre_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) { /* If we've seen traffic both ways, this is a GRE connection. @@ -364,11 +356,11 @@ static int gre_init_net(struct net *net, u_int16_t proto) static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = { .l3proto = AF_INET, .l4proto = IPPROTO_GRE, - .name = "gre", .pkt_to_tuple = gre_pkt_to_tuple, .invert_tuple = gre_invert_tuple, - .print_tuple = gre_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = gre_print_conntrack, +#endif .get_timeouts = gre_get_timeouts, .packet = gre_packet, .new = gre_new, diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 6eef29d2eec4090efbe654baf4190137417fd943..6303a88af12b0b5116b9808ac9c0ac370bcb33e6 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -174,20 +174,13 @@ static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -/* Print out the per-protocol part of the tuple. */ -static void sctp_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "sport=%hu dport=%hu ", - ntohs(tuple->src.u.sctp.port), - ntohs(tuple->dst.u.sctp.port)); -} - +#ifdef CONFIG_NF_CONNTRACK_PROCFS /* Print out the private part of the conntrack. */ static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct) { seq_printf(s, "%s ", sctp_conntrack_names[ct->proto.sctp.state]); } +#endif #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \ for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0; \ @@ -314,7 +307,6 @@ static int sctp_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) { enum sctp_conntrack new_state, old_state; @@ -791,11 +783,11 @@ static struct nf_proto_net *sctp_get_net_proto(struct net *net) struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_SCTP, - .name = "sctp", .pkt_to_tuple = sctp_pkt_to_tuple, .invert_tuple = sctp_invert_tuple, - .print_tuple = sctp_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = sctp_print_conntrack, +#endif .packet = sctp_packet, .get_timeouts = sctp_get_timeouts, .new = sctp_new, @@ -828,11 +820,11 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4); struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { .l3proto = PF_INET6, .l4proto = IPPROTO_SCTP, - .name = "sctp", .pkt_to_tuple = sctp_pkt_to_tuple, .invert_tuple = sctp_invert_tuple, - .print_tuple = sctp_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = sctp_print_conntrack, +#endif .packet = sctp_packet, .get_timeouts = sctp_get_timeouts, .new = sctp_new, diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 9758a7dfd83ef95c0bcab1257d63cb38d9faed88..cba1c6ffe51aff7bbdf3ef0ee0cff350881dbf7a 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -301,20 +301,13 @@ static bool tcp_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -/* Print out the per-protocol part of the tuple. */ -static void tcp_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "sport=%hu dport=%hu ", - ntohs(tuple->src.u.tcp.port), - ntohs(tuple->dst.u.tcp.port)); -} - +#ifdef CONFIG_NF_CONNTRACK_PROCFS /* Print out the private part of the conntrack. */ static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct) { seq_printf(s, "%s ", tcp_conntrack_names[ct->proto.tcp.state]); } +#endif static unsigned int get_conntrack_index(const struct tcphdr *tcph) { @@ -810,7 +803,6 @@ static int tcp_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) { struct net *net = nf_ct_net(ct); @@ -1556,11 +1548,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_TCP, - .name = "tcp", .pkt_to_tuple = tcp_pkt_to_tuple, .invert_tuple = tcp_invert_tuple, - .print_tuple = tcp_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = tcp_print_conntrack, +#endif .packet = tcp_packet, .get_timeouts = tcp_get_timeouts, .new = tcp_new, @@ -1594,11 +1586,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly = { .l3proto = PF_INET6, .l4proto = IPPROTO_TCP, - .name = "tcp", .pkt_to_tuple = tcp_pkt_to_tuple, .invert_tuple = tcp_invert_tuple, - .print_tuple = tcp_print_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS .print_conntrack = tcp_print_conntrack, +#endif .packet = tcp_packet, .get_timeouts = tcp_get_timeouts, .new = tcp_new, diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index f6ebce6178ca65d040382af45bc962862b883d4a..8af734cd1a946be575c6cb55b662a754b5d5ca84 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -63,15 +63,6 @@ static bool udp_invert_tuple(struct nf_conntrack_tuple *tuple, return true; } -/* Print out the per-protocol part of the tuple. */ -static void udp_print_tuple(struct seq_file *s, - const struct nf_conntrack_tuple *tuple) -{ - seq_printf(s, "sport=%hu dport=%hu ", - ntohs(tuple->src.u.udp.port), - ntohs(tuple->dst.u.udp.port)); -} - static unsigned int *udp_get_timeouts(struct net *net) { return udp_pernet(net)->timeouts; @@ -83,7 +74,6 @@ static int udp_packet(struct nf_conn *ct, unsigned int dataoff, enum ip_conntrack_info ctinfo, u_int8_t pf, - unsigned int hooknum, unsigned int *timeouts) { /* If we've seen traffic both ways, this is some kind of UDP @@ -313,11 +303,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_UDP, - .name = "udp", .allow_clash = true, .pkt_to_tuple = udp_pkt_to_tuple, .invert_tuple = udp_invert_tuple, - .print_tuple = udp_print_tuple, .packet = udp_packet, .get_timeouts = udp_get_timeouts, .new = udp_new, @@ -347,11 +335,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_UDPLITE, - .name = "udplite", .allow_clash = true, .pkt_to_tuple = udp_pkt_to_tuple, .invert_tuple = udp_invert_tuple, - .print_tuple = udp_print_tuple, .packet = udp_packet, .get_timeouts = udp_get_timeouts, .new = udp_new, @@ -381,11 +367,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly = { .l3proto = PF_INET6, .l4proto = IPPROTO_UDP, - .name = "udp", .allow_clash = true, .pkt_to_tuple = udp_pkt_to_tuple, .invert_tuple = udp_invert_tuple, - .print_tuple = udp_print_tuple, .packet = udp_packet, .get_timeouts = udp_get_timeouts, .new = udp_new, @@ -415,11 +399,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = { .l3proto = PF_INET6, .l4proto = IPPROTO_UDPLITE, - .name = "udplite", .allow_clash = true, .pkt_to_tuple = udp_pkt_to_tuple, .invert_tuple = udp_invert_tuple, - .print_tuple = udp_print_tuple, .packet = udp_packet, .get_timeouts = udp_get_timeouts, .new = udp_new, diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index d38af4274335b9bed6de1edb4b0c4ae6fdf96656..4dbb5bad4363ba9f67fea15160bb7b0b88ae9c38 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -884,7 +884,6 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, tuple.dst.u3 = *daddr; tuple.dst.u.udp.port = port; - rcu_read_lock(); do { exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); @@ -918,10 +917,8 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, goto err1; } - if (skip_expect) { - rcu_read_unlock(); + if (skip_expect) return NF_ACCEPT; - } rtp_exp = nf_ct_expect_alloc(ct); if (rtp_exp == NULL) @@ -952,7 +949,6 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, err2: nf_ct_expect_put(rtp_exp); err1: - rcu_read_unlock(); return ret; } diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index ccb5cb9043e0e769ba463759a69f4d9f36e122e0..5a101caa3e1279058970882ab1294ef5a7434f8c 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -41,8 +41,62 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_l3proto *l3proto, const struct nf_conntrack_l4proto *l4proto) { - l3proto->print_tuple(s, tuple); - l4proto->print_tuple(s, tuple); + switch (l3proto->l3proto) { + case NFPROTO_IPV4: + seq_printf(s, "src=%pI4 dst=%pI4 ", + &tuple->src.u3.ip, &tuple->dst.u3.ip); + break; + case NFPROTO_IPV6: + seq_printf(s, "src=%pI6 dst=%pI6 ", + tuple->src.u3.ip6, tuple->dst.u3.ip6); + break; + default: + break; + } + + switch (l4proto->l4proto) { + case IPPROTO_ICMP: + seq_printf(s, "type=%u code=%u id=%u ", + tuple->dst.u.icmp.type, + tuple->dst.u.icmp.code, + ntohs(tuple->src.u.icmp.id)); + break; + case IPPROTO_TCP: + seq_printf(s, "sport=%hu dport=%hu ", + ntohs(tuple->src.u.tcp.port), + ntohs(tuple->dst.u.tcp.port)); + break; + case IPPROTO_UDPLITE: /* fallthrough */ + case IPPROTO_UDP: + seq_printf(s, "sport=%hu dport=%hu ", + ntohs(tuple->src.u.udp.port), + ntohs(tuple->dst.u.udp.port)); + + break; + case IPPROTO_DCCP: + seq_printf(s, "sport=%hu dport=%hu ", + ntohs(tuple->src.u.dccp.port), + ntohs(tuple->dst.u.dccp.port)); + break; + case IPPROTO_SCTP: + seq_printf(s, "sport=%hu dport=%hu ", + ntohs(tuple->src.u.sctp.port), + ntohs(tuple->dst.u.sctp.port)); + break; + case IPPROTO_ICMPV6: + seq_printf(s, "type=%u code=%u id=%u ", + tuple->dst.u.icmp.type, + tuple->dst.u.icmp.code, + ntohs(tuple->src.u.icmp.id)); + break; + case IPPROTO_GRE: + seq_printf(s, "srckey=0x%x dstkey=0x%x ", + ntohs(tuple->src.u.gre.key), + ntohs(tuple->dst.u.gre.key)); + break; + default: + break; + } } EXPORT_SYMBOL_GPL(print_tuple); @@ -198,6 +252,31 @@ ct_show_delta_time(struct seq_file *s, const struct nf_conn *ct) } #endif +static const char* l3proto_name(u16 proto) +{ + switch (proto) { + case AF_INET: return "ipv4"; + case AF_INET6: return "ipv6"; + } + + return "unknown"; +} + +static const char* l4proto_name(u16 proto) +{ + switch (proto) { + case IPPROTO_ICMP: return "icmp"; + case IPPROTO_TCP: return "tcp"; + case IPPROTO_UDP: return "udp"; + case IPPROTO_DCCP: return "dccp"; + case IPPROTO_GRE: return "gre"; + case IPPROTO_SCTP: return "sctp"; + case IPPROTO_UDPLITE: return "udplite"; + } + + return "unknown"; +} + /* return 0 on success, 1 in case of error */ static int ct_seq_show(struct seq_file *s, void *v) { @@ -208,7 +287,7 @@ static int ct_seq_show(struct seq_file *s, void *v) struct net *net = seq_file_net(s); int ret = 0; - NF_CT_ASSERT(ct); + WARN_ON(!ct); if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) return 0; @@ -225,14 +304,14 @@ static int ct_seq_show(struct seq_file *s, void *v) goto release; l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); - NF_CT_ASSERT(l3proto); + WARN_ON(!l3proto); l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); - NF_CT_ASSERT(l4proto); + WARN_ON(!l4proto); ret = -ENOSPC; seq_printf(s, "%-8s %u %-8s %u %ld ", - l3proto->name, nf_ct_l3num(ct), - l4proto->name, nf_ct_protonum(ct), + l3proto_name(l3proto->l3proto), nf_ct_l3num(ct), + l4proto_name(l4proto->l4proto), nf_ct_protonum(ct), nf_ct_expires(ct) / HZ); if (l4proto->print_conntrack) @@ -452,9 +531,6 @@ static int log_invalid_proto_max __read_mostly = 255; /* size the user *wants to set */ static unsigned int nf_conntrack_htable_size_user __read_mostly; -extern unsigned int nf_conntrack_default_on; -unsigned int nf_conntrack_default_on __read_mostly = 1; - static int nf_conntrack_hash_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) @@ -520,13 +596,6 @@ static struct ctl_table nf_ct_sysctl_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, - { - .procname = "nf_conntrack_default_on", - .data = &nf_conntrack_default_on, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = proc_dointvec, - }, { } }; diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h index bfa742da83aff37dfc8b426e1d193f0de056fb6f..49f87ec093a3918f8a6a6948ca1cd763222d6999 100644 --- a/net/netfilter/nf_internals.h +++ b/net/netfilter/nf_internals.h @@ -5,17 +5,11 @@ #include #include -#ifdef CONFIG_NETFILTER_DEBUG -#define NFDEBUG(format, args...) printk(KERN_DEBUG format , ## args) -#else -#define NFDEBUG(format, args...) -#endif - /* nf_queue.c */ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, - struct nf_hook_entry **entryp, unsigned int verdict); + const struct nf_hook_entries *entries, unsigned int index, + unsigned int verdict); unsigned int nf_queue_nf_hook_drop(struct net *net); -int __init netfilter_queue_init(void); /* nf_log.c */ int __init netfilter_log_init(void); diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index eb541786ccb7c79b3498477dfefc2927368f1a6f..af8345fc4fbde30adad608b61a4fd293b4554584 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -30,19 +30,17 @@ #include #include +static spinlock_t nf_nat_locks[CONNTRACK_LOCKS]; + static DEFINE_MUTEX(nf_nat_proto_mutex); static const struct nf_nat_l3proto __rcu *nf_nat_l3protos[NFPROTO_NUMPROTO] __read_mostly; static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO] __read_mostly; -struct nf_nat_conn_key { - const struct net *net; - const struct nf_conntrack_tuple *tuple; - const struct nf_conntrack_zone *zone; -}; - -static struct rhltable nf_nat_bysource_table; +static struct hlist_head *nf_nat_bysource __read_mostly; +static unsigned int nf_nat_htable_size __read_mostly; +static unsigned int nf_nat_hash_rnd __read_mostly; inline const struct nf_nat_l3proto * __nf_nat_l3proto_find(u8 family) @@ -118,17 +116,19 @@ int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family) EXPORT_SYMBOL(nf_xfrm_me_harder); #endif /* CONFIG_XFRM */ -static u32 nf_nat_bysource_hash(const void *data, u32 len, u32 seed) +/* We keep an extra hash for each conntrack, for fast searching. */ +static unsigned int +hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple) { - const struct nf_conntrack_tuple *t; - const struct nf_conn *ct = data; + unsigned int hash; + + get_random_once(&nf_nat_hash_rnd, sizeof(nf_nat_hash_rnd)); - t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; /* Original src, to ensure we map it consistently if poss. */ + hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32), + tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n)); - seed ^= net_hash_mix(nf_ct_net(ct)); - return jhash2((const u32 *)&t->src, sizeof(t->src) / sizeof(u32), - t->dst.protonum ^ seed); + return reciprocal_scale(hash, nf_nat_htable_size); } /* Is this tuple already taken? (not by us) */ @@ -184,28 +184,6 @@ same_src(const struct nf_conn *ct, t->src.u.all == tuple->src.u.all); } -static int nf_nat_bysource_cmp(struct rhashtable_compare_arg *arg, - const void *obj) -{ - const struct nf_nat_conn_key *key = arg->key; - const struct nf_conn *ct = obj; - - if (!same_src(ct, key->tuple) || - !net_eq(nf_ct_net(ct), key->net) || - !nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL)) - return 1; - - return 0; -} - -static struct rhashtable_params nf_nat_bysource_params = { - .head_offset = offsetof(struct nf_conn, nat_bysource), - .obj_hashfn = nf_nat_bysource_hash, - .obj_cmpfn = nf_nat_bysource_cmp, - .nelem_hint = 256, - .min_size = 1024, -}; - /* Only called for SRC manip */ static int find_appropriate_src(struct net *net, @@ -216,26 +194,22 @@ find_appropriate_src(struct net *net, struct nf_conntrack_tuple *result, const struct nf_nat_range *range) { + unsigned int h = hash_by_src(net, tuple); const struct nf_conn *ct; - struct nf_nat_conn_key key = { - .net = net, - .tuple = tuple, - .zone = zone - }; - struct rhlist_head *hl, *h; - - hl = rhltable_lookup(&nf_nat_bysource_table, &key, - nf_nat_bysource_params); - - rhl_for_each_entry_rcu(ct, h, hl, nat_bysource) { - nf_ct_invert_tuplepr(result, - &ct->tuplehash[IP_CT_DIR_REPLY].tuple); - result->dst = tuple->dst; - if (in_range(l3proto, l4proto, result, range)) - return 1; + hlist_for_each_entry_rcu(ct, &nf_nat_bysource[h], nat_bysource) { + if (same_src(ct, tuple) && + net_eq(net, nf_ct_net(ct)) && + nf_ct_zone_equal(ct, zone, IP_CT_DIR_ORIGINAL)) { + /* Copy source part from reply tuple. */ + nf_ct_invert_tuplepr(result, + &ct->tuplehash[IP_CT_DIR_REPLY].tuple); + result->dst = tuple->dst; + + if (in_range(l3proto, l4proto, result, range)) + return 1; + } } - return 0; } @@ -408,15 +382,18 @@ nf_nat_setup_info(struct nf_conn *ct, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype) { + struct net *net = nf_ct_net(ct); struct nf_conntrack_tuple curr_tuple, new_tuple; /* Can't setup nat info for confirmed ct. */ if (nf_ct_is_confirmed(ct)) return NF_ACCEPT; - NF_CT_ASSERT(maniptype == NF_NAT_MANIP_SRC || - maniptype == NF_NAT_MANIP_DST); - BUG_ON(nf_nat_initialized(ct, maniptype)); + WARN_ON(maniptype != NF_NAT_MANIP_SRC && + maniptype != NF_NAT_MANIP_DST); + + if (WARN_ON(nf_nat_initialized(ct, maniptype))) + return NF_DROP; /* What we've got will look like inverse of reply. Normally * this is what is in the conntrack, except for prior @@ -441,25 +418,22 @@ nf_nat_setup_info(struct nf_conn *ct, else ct->status |= IPS_DST_NAT; - if (nfct_help(ct)) + if (nfct_help(ct) && !nfct_seqadj(ct)) if (!nfct_seqadj_ext_add(ct)) return NF_DROP; } if (maniptype == NF_NAT_MANIP_SRC) { - struct nf_nat_conn_key key = { - .net = nf_ct_net(ct), - .tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, - .zone = nf_ct_zone(ct), - }; - int err; - - err = rhltable_insert_key(&nf_nat_bysource_table, - &key, - &ct->nat_bysource, - nf_nat_bysource_params); - if (err) - return NF_DROP; + unsigned int srchash; + spinlock_t *lock; + + srchash = hash_by_src(net, + &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + lock = &nf_nat_locks[srchash % CONNTRACK_LOCKS]; + spin_lock_bh(lock); + hlist_add_head_rcu(&ct->nat_bysource, + &nf_nat_bysource[srchash]); + spin_unlock_bh(lock); } /* It's done. */ @@ -553,6 +527,16 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data) return i->status & IPS_NAT_MASK ? 1 : 0; } +static void __nf_nat_cleanup_conntrack(struct nf_conn *ct) +{ + unsigned int h; + + h = hash_by_src(nf_ct_net(ct), &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + spin_lock_bh(&nf_nat_locks[h % CONNTRACK_LOCKS]); + hlist_del_rcu(&ct->nat_bysource); + spin_unlock_bh(&nf_nat_locks[h % CONNTRACK_LOCKS]); +} + static int nf_nat_proto_clean(struct nf_conn *ct, void *data) { if (nf_nat_proto_remove(ct, data)) @@ -568,8 +552,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) * will delete entry from already-freed table. */ clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); - rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, - nf_nat_bysource_params); + __nf_nat_cleanup_conntrack(ct); /* don't delete conntrack. Although that would make things a lot * simpler, we'd end up flushing all conntracks on nat rmmod. @@ -698,8 +681,7 @@ EXPORT_SYMBOL_GPL(nf_nat_l3proto_unregister); static void nf_nat_cleanup_conntrack(struct nf_conn *ct) { if (ct->status & IPS_SRC_NAT_DONE) - rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, - nf_nat_bysource_params); + __nf_nat_cleanup_conntrack(ct); } static struct nf_ct_ext_type nat_extend __read_mostly = { @@ -821,19 +803,27 @@ static struct nf_ct_helper_expectfn follow_master_nat = { static int __init nf_nat_init(void) { - int ret; + int ret, i; - ret = rhltable_init(&nf_nat_bysource_table, &nf_nat_bysource_params); - if (ret) - return ret; + /* Leave them the same for the moment. */ + nf_nat_htable_size = nf_conntrack_htable_size; + if (nf_nat_htable_size < CONNTRACK_LOCKS) + nf_nat_htable_size = CONNTRACK_LOCKS; + + nf_nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 0); + if (!nf_nat_bysource) + return -ENOMEM; ret = nf_ct_extend_register(&nat_extend); if (ret < 0) { - rhltable_destroy(&nf_nat_bysource_table); + nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); printk(KERN_ERR "nf_nat_core: Unable to register extension\n"); return ret; } + for (i = 0; i < CONNTRACK_LOCKS; i++) + spin_lock_init(&nf_nat_locks[i]); + nf_ct_helper_expectfn_register(&follow_master_nat); BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); @@ -863,8 +853,8 @@ static void __exit nf_nat_cleanup(void) for (i = 0; i < NFPROTO_NUMPROTO; i++) kfree(nf_nat_l4protos[i]); - - rhltable_destroy(&nf_nat_bysource_table); + synchronize_net(); + nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); } MODULE_LICENSE("GPL"); diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c index 86067560a3184f26c521e35b8f63e4952c95955e..25b06b959118d287d574ae649dae4a863aab6f13 100644 --- a/net/netfilter/nf_nat_redirect.c +++ b/net/netfilter/nf_nat_redirect.c @@ -38,11 +38,11 @@ nf_nat_redirect_ipv4(struct sk_buff *skb, __be32 newdst; struct nf_nat_range newrange; - NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING || - hooknum == NF_INET_LOCAL_OUT); + WARN_ON(hooknum != NF_INET_PRE_ROUTING && + hooknum != NF_INET_LOCAL_OUT); ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); + WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))); /* Local packets: make them go to loopback */ if (hooknum == NF_INET_LOCAL_OUT) { diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 043850c9d154dcf128903d7dba6b17ea5ff20370..f7e21953b1debd354f162e4118414fd93d57824b 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -109,9 +109,11 @@ unsigned int nf_queue_nf_hook_drop(struct net *net) return count; } +EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop); static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, - struct nf_hook_entry *hook_entry, unsigned int queuenum) + const struct nf_hook_entries *entries, + unsigned int index, unsigned int queuenum) { int status = -ENOENT; struct nf_queue_entry *entry = NULL; @@ -139,7 +141,7 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, *entry = (struct nf_queue_entry) { .skb = skb, .state = *state, - .hook = hook_entry, + .hook_index = index, .size = sizeof(*entry) + afinfo->route_key_size, }; @@ -162,18 +164,16 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, /* Packets leaving via this function must come back through nf_reinject(). */ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, - struct nf_hook_entry **entryp, unsigned int verdict) + const struct nf_hook_entries *entries, unsigned int index, + unsigned int verdict) { - struct nf_hook_entry *entry = *entryp; int ret; - ret = __nf_queue(skb, state, entry, verdict >> NF_VERDICT_QBITS); + ret = __nf_queue(skb, state, entries, index, verdict >> NF_VERDICT_QBITS); if (ret < 0) { if (ret == -ESRCH && - (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) { - *entryp = rcu_dereference(entry->next); + (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) return 1; - } kfree_skb(skb); } @@ -182,33 +182,56 @@ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, static unsigned int nf_iterate(struct sk_buff *skb, struct nf_hook_state *state, - struct nf_hook_entry **entryp) + const struct nf_hook_entries *hooks, + unsigned int *index) { - unsigned int verdict; + const struct nf_hook_entry *hook; + unsigned int verdict, i = *index; - do { + while (i < hooks->num_hook_entries) { + hook = &hooks->hooks[i]; repeat: - verdict = nf_hook_entry_hookfn((*entryp), skb, state); + verdict = nf_hook_entry_hookfn(hook, skb, state); if (verdict != NF_ACCEPT) { if (verdict != NF_REPEAT) return verdict; goto repeat; } - *entryp = rcu_dereference((*entryp)->next); - } while (*entryp); + i++; + } + *index = i; return NF_ACCEPT; } +/* Caller must hold rcu read-side lock */ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) { - struct nf_hook_entry *hook_entry = entry->hook; + const struct nf_hook_entry *hook_entry; + const struct nf_hook_entries *hooks; struct sk_buff *skb = entry->skb; const struct nf_afinfo *afinfo; + const struct net *net; + unsigned int i; int err; + u8 pf; + + net = entry->state.net; + pf = entry->state.pf; + + hooks = rcu_dereference(net->nf.hooks[pf][entry->state.hook]); nf_queue_entry_release_refs(entry); + i = entry->hook_index; + if (WARN_ON_ONCE(i >= hooks->num_hook_entries)) { + kfree_skb(skb); + kfree(entry); + return; + } + + hook_entry = &hooks->hooks[i]; + /* Continue traversal iff userspace said ok... */ if (verdict == NF_REPEAT) verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state); @@ -220,27 +243,22 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) } if (verdict == NF_ACCEPT) { - hook_entry = rcu_dereference(hook_entry->next); - if (hook_entry) next_hook: - verdict = nf_iterate(skb, &entry->state, &hook_entry); + ++i; + verdict = nf_iterate(skb, &entry->state, hooks, &i); } switch (verdict & NF_VERDICT_MASK) { case NF_ACCEPT: case NF_STOP: -okfn: local_bh_disable(); entry->state.okfn(entry->state.net, entry->state.sk, skb); local_bh_enable(); break; case NF_QUEUE: - err = nf_queue(skb, &entry->state, &hook_entry, verdict); - if (err == 1) { - if (hook_entry) - goto next_hook; - goto okfn; - } + err = nf_queue(skb, &entry->state, hooks, i, verdict); + if (err == 1) + goto next_hook; break; case NF_STOLEN: break; diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c index c68c1e58b3628930495c5fe5a24f00f15adc1537..d2a9e6b5d01f7018a8390ed46f4bfe66eb74e9ef 100644 --- a/net/netfilter/nf_sockopt.c +++ b/net/netfilter/nf_sockopt.c @@ -33,7 +33,7 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg) reg->set_optmin, reg->set_optmax) || overlap(ops->get_optmin, ops->get_optmax, reg->get_optmin, reg->get_optmax))) { - NFDEBUG("nf_sock overlap: %u-%u/%u-%u v %u-%u/%u-%u\n", + pr_debug("nf_sock overlap: %u-%u/%u-%u v %u-%u/%u-%u\n", ops->set_optmin, ops->set_optmax, ops->get_optmin, ops->get_optmax, reg->set_optmin, reg->set_optmax, diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 7843efa33c598f9d1785bc64e99246941213d571..929927171426a6e286bd5cc4412aaa99b77fec77 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -726,7 +726,10 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, if (table == NULL) goto err2; - nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN); + table->name = nla_strdup(name, GFP_KERNEL); + if (table->name == NULL) + goto err3; + INIT_LIST_HEAD(&table->chains); INIT_LIST_HEAD(&table->sets); INIT_LIST_HEAD(&table->objects); @@ -735,10 +738,12 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); if (err < 0) - goto err3; + goto err4; list_add_tail_rcu(&table->list, &afi->tables); return 0; +err4: + kfree(table->name); err3: kfree(table); err2: @@ -855,6 +860,10 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, if (IS_ERR(table)) return PTR_ERR(table); + if (nlh->nlmsg_flags & NLM_F_NONREC && + table->use > 0) + return -EBUSY; + ctx.afi = afi; ctx.table = table; @@ -865,6 +874,7 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx) { BUG_ON(ctx->table->use > 0); + kfree(ctx->table->name); kfree(ctx->table); module_put(ctx->afi->owner); } @@ -1240,10 +1250,14 @@ static void nf_tables_chain_destroy(struct nft_chain *chain) module_put(basechain->type->owner); free_percpu(basechain->stats); + if (basechain->stats) + static_branch_dec(&nft_counters_enabled); if (basechain->ops[0].dev != NULL) dev_put(basechain->ops[0].dev); + kfree(chain->name); kfree(basechain); } else { + kfree(chain->name); kfree(chain); } } @@ -1325,155 +1339,18 @@ static void nft_chain_release_hook(struct nft_chain_hook *hook) dev_put(hook->dev); } -static int nf_tables_newchain(struct net *net, struct sock *nlsk, - struct sk_buff *skb, const struct nlmsghdr *nlh, - const struct nlattr * const nla[], - struct netlink_ext_ack *extack) +static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, + u8 policy, bool create) { - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); - const struct nlattr * uninitialized_var(name); - struct nft_af_info *afi; - struct nft_table *table; + const struct nlattr * const *nla = ctx->nla; + struct nft_table *table = ctx->table; + struct nft_af_info *afi = ctx->afi; + struct nft_base_chain *basechain; + struct nft_stats __percpu *stats; + struct net *net = ctx->net; struct nft_chain *chain; - struct nft_base_chain *basechain = NULL; - u8 genmask = nft_genmask_next(net); - int family = nfmsg->nfgen_family; - u8 policy = NF_ACCEPT; - u64 handle = 0; unsigned int i; - struct nft_stats __percpu *stats; int err; - bool create; - struct nft_ctx ctx; - - create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; - - afi = nf_tables_afinfo_lookup(net, family, true); - if (IS_ERR(afi)) - return PTR_ERR(afi); - - table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask); - if (IS_ERR(table)) - return PTR_ERR(table); - - chain = NULL; - name = nla[NFTA_CHAIN_NAME]; - - if (nla[NFTA_CHAIN_HANDLE]) { - handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE])); - chain = nf_tables_chain_lookup_byhandle(table, handle, genmask); - if (IS_ERR(chain)) - return PTR_ERR(chain); - } else { - chain = nf_tables_chain_lookup(table, name, genmask); - if (IS_ERR(chain)) { - if (PTR_ERR(chain) != -ENOENT) - return PTR_ERR(chain); - chain = NULL; - } - } - - if (nla[NFTA_CHAIN_POLICY]) { - if (chain != NULL && - !nft_is_base_chain(chain)) - return -EOPNOTSUPP; - - if (chain == NULL && - nla[NFTA_CHAIN_HOOK] == NULL) - return -EOPNOTSUPP; - - policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY])); - switch (policy) { - case NF_DROP: - case NF_ACCEPT: - break; - default: - return -EINVAL; - } - } - - if (chain != NULL) { - struct nft_stats *stats = NULL; - struct nft_trans *trans; - - if (nlh->nlmsg_flags & NLM_F_EXCL) - return -EEXIST; - if (nlh->nlmsg_flags & NLM_F_REPLACE) - return -EOPNOTSUPP; - - if (nla[NFTA_CHAIN_HOOK]) { - struct nft_base_chain *basechain; - struct nft_chain_hook hook; - struct nf_hook_ops *ops; - - if (!nft_is_base_chain(chain)) - return -EBUSY; - - err = nft_chain_parse_hook(net, nla, afi, &hook, - create); - if (err < 0) - return err; - - basechain = nft_base_chain(chain); - if (basechain->type != hook.type) { - nft_chain_release_hook(&hook); - return -EBUSY; - } - - for (i = 0; i < afi->nops; i++) { - ops = &basechain->ops[i]; - if (ops->hooknum != hook.num || - ops->priority != hook.priority || - ops->dev != hook.dev) { - nft_chain_release_hook(&hook); - return -EBUSY; - } - } - nft_chain_release_hook(&hook); - } - - if (nla[NFTA_CHAIN_HANDLE] && name) { - struct nft_chain *chain2; - - chain2 = nf_tables_chain_lookup(table, - nla[NFTA_CHAIN_NAME], - genmask); - if (IS_ERR(chain2)) - return PTR_ERR(chain2); - } - - if (nla[NFTA_CHAIN_COUNTERS]) { - if (!nft_is_base_chain(chain)) - return -EOPNOTSUPP; - - stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]); - if (IS_ERR(stats)) - return PTR_ERR(stats); - } - - nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); - trans = nft_trans_alloc(&ctx, NFT_MSG_NEWCHAIN, - sizeof(struct nft_trans_chain)); - if (trans == NULL) { - free_percpu(stats); - return -ENOMEM; - } - - nft_trans_chain_stats(trans) = stats; - nft_trans_chain_update(trans) = true; - - if (nla[NFTA_CHAIN_POLICY]) - nft_trans_chain_policy(trans) = policy; - else - nft_trans_chain_policy(trans) = -1; - - if (nla[NFTA_CHAIN_HANDLE] && name) { - nla_strlcpy(nft_trans_chain_name(trans), name, - NFT_CHAIN_MAXNAMELEN); - } - list_add_tail(&trans->list, &net->nft.commit_list); - return 0; - } if (table->use == UINT_MAX) return -EOVERFLOW; @@ -1504,14 +1381,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, return PTR_ERR(stats); } basechain->stats = stats; - } else { - stats = netdev_alloc_pcpu_stats(struct nft_stats); - if (stats == NULL) { - nft_chain_release_hook(&hook); - kfree(basechain); - return -ENOMEM; - } - rcu_assign_pointer(basechain->stats, stats); + static_branch_inc(&nft_counters_enabled); } hookfn = hook.type->hooks[hook.num]; @@ -1539,31 +1409,204 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, if (chain == NULL) return -ENOMEM; } - INIT_LIST_HEAD(&chain->rules); chain->handle = nf_tables_alloc_handle(table); chain->table = table; - nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN); + chain->name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL); + if (!chain->name) { + err = -ENOMEM; + goto err1; + } err = nf_tables_register_hooks(net, table, chain, afi->nops); if (err < 0) goto err1; - nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); - err = nft_trans_chain_add(&ctx, NFT_MSG_NEWCHAIN); + ctx->chain = chain; + err = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN); if (err < 0) goto err2; table->use++; list_add_tail_rcu(&chain->list, &table->chains); + return 0; err2: nf_tables_unregister_hooks(net, table, chain, afi->nops); err1: nf_tables_chain_destroy(chain); + return err; } +static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy, + bool create) +{ + const struct nlattr * const *nla = ctx->nla; + struct nft_table *table = ctx->table; + struct nft_chain *chain = ctx->chain; + struct nft_af_info *afi = ctx->afi; + struct nft_base_chain *basechain; + struct nft_stats *stats = NULL; + struct nft_chain_hook hook; + const struct nlattr *name; + struct nf_hook_ops *ops; + struct nft_trans *trans; + int err, i; + + if (nla[NFTA_CHAIN_HOOK]) { + if (!nft_is_base_chain(chain)) + return -EBUSY; + + err = nft_chain_parse_hook(ctx->net, nla, ctx->afi, &hook, + create); + if (err < 0) + return err; + + basechain = nft_base_chain(chain); + if (basechain->type != hook.type) { + nft_chain_release_hook(&hook); + return -EBUSY; + } + + for (i = 0; i < afi->nops; i++) { + ops = &basechain->ops[i]; + if (ops->hooknum != hook.num || + ops->priority != hook.priority || + ops->dev != hook.dev) { + nft_chain_release_hook(&hook); + return -EBUSY; + } + } + nft_chain_release_hook(&hook); + } + + if (nla[NFTA_CHAIN_HANDLE] && + nla[NFTA_CHAIN_NAME]) { + struct nft_chain *chain2; + + chain2 = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], + genmask); + if (IS_ERR(chain2)) + return PTR_ERR(chain2); + } + + if (nla[NFTA_CHAIN_COUNTERS]) { + if (!nft_is_base_chain(chain)) + return -EOPNOTSUPP; + + stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]); + if (IS_ERR(stats)) + return PTR_ERR(stats); + } + + trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN, + sizeof(struct nft_trans_chain)); + if (trans == NULL) { + free_percpu(stats); + return -ENOMEM; + } + + nft_trans_chain_stats(trans) = stats; + nft_trans_chain_update(trans) = true; + + if (nla[NFTA_CHAIN_POLICY]) + nft_trans_chain_policy(trans) = policy; + else + nft_trans_chain_policy(trans) = -1; + + name = nla[NFTA_CHAIN_NAME]; + if (nla[NFTA_CHAIN_HANDLE] && name) { + nft_trans_chain_name(trans) = + nla_strdup(name, GFP_KERNEL); + if (!nft_trans_chain_name(trans)) { + kfree(trans); + free_percpu(stats); + return -ENOMEM; + } + } + list_add_tail(&trans->list, &ctx->net->nft.commit_list); + + return 0; +} + +static int nf_tables_newchain(struct net *net, struct sock *nlsk, + struct sk_buff *skb, const struct nlmsghdr *nlh, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) +{ + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + const struct nlattr * uninitialized_var(name); + u8 genmask = nft_genmask_next(net); + int family = nfmsg->nfgen_family; + struct nft_af_info *afi; + struct nft_table *table; + struct nft_chain *chain; + u8 policy = NF_ACCEPT; + struct nft_ctx ctx; + u64 handle = 0; + bool create; + + create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; + + afi = nf_tables_afinfo_lookup(net, family, true); + if (IS_ERR(afi)) + return PTR_ERR(afi); + + table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask); + if (IS_ERR(table)) + return PTR_ERR(table); + + chain = NULL; + name = nla[NFTA_CHAIN_NAME]; + + if (nla[NFTA_CHAIN_HANDLE]) { + handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE])); + chain = nf_tables_chain_lookup_byhandle(table, handle, genmask); + if (IS_ERR(chain)) + return PTR_ERR(chain); + } else { + chain = nf_tables_chain_lookup(table, name, genmask); + if (IS_ERR(chain)) { + if (PTR_ERR(chain) != -ENOENT) + return PTR_ERR(chain); + chain = NULL; + } + } + + if (nla[NFTA_CHAIN_POLICY]) { + if (chain != NULL && + !nft_is_base_chain(chain)) + return -EOPNOTSUPP; + + if (chain == NULL && + nla[NFTA_CHAIN_HOOK] == NULL) + return -EOPNOTSUPP; + + policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY])); + switch (policy) { + case NF_DROP: + case NF_ACCEPT: + break; + default: + return -EINVAL; + } + } + + nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); + + if (chain != NULL) { + if (nlh->nlmsg_flags & NLM_F_EXCL) + return -EEXIST; + if (nlh->nlmsg_flags & NLM_F_REPLACE) + return -EOPNOTSUPP; + + return nf_tables_updchain(&ctx, genmask, policy, create); + } + + return nf_tables_addchain(&ctx, family, genmask, policy, create); +} + static int nf_tables_delchain(struct net *net, struct sock *nlsk, struct sk_buff *skb, const struct nlmsghdr *nlh, const struct nlattr * const nla[], @@ -1574,8 +1617,11 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, struct nft_af_info *afi; struct nft_table *table; struct nft_chain *chain; + struct nft_rule *rule; int family = nfmsg->nfgen_family; struct nft_ctx ctx; + u32 use; + int err; afi = nf_tables_afinfo_lookup(net, family, false); if (IS_ERR(afi)) @@ -1588,11 +1634,30 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask); if (IS_ERR(chain)) return PTR_ERR(chain); - if (chain->use > 0) + + if (nlh->nlmsg_flags & NLM_F_NONREC && + chain->use > 0) return -EBUSY; nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); + use = chain->use; + list_for_each_entry(rule, &chain->rules, list) { + if (!nft_is_active_next(net, rule)) + continue; + use--; + + err = nft_delrule(&ctx, rule); + if (err < 0) + return err; + } + + /* There are rules and elements that are still holding references to us, + * we cannot do a recursive removal in this case. + */ + if (use > 0) + return -EBUSY; + return nft_delchain(&ctx); } @@ -1977,8 +2042,8 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, } struct nft_rule_dump_ctx { - char table[NFT_TABLE_MAXNAMELEN]; - char chain[NFT_CHAIN_MAXNAMELEN]; + char *table; + char *chain; }; static int nf_tables_dump_rules(struct sk_buff *skb, @@ -2002,7 +2067,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb, continue; list_for_each_entry_rcu(table, &afi->tables, list) { - if (ctx && ctx->table[0] && + if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0) continue; @@ -2042,7 +2107,13 @@ static int nf_tables_dump_rules(struct sk_buff *skb, static int nf_tables_dump_rules_done(struct netlink_callback *cb) { - kfree(cb->data); + struct nft_rule_dump_ctx *ctx = cb->data; + + if (ctx) { + kfree(ctx->table); + kfree(ctx->chain); + kfree(ctx); + } return 0; } @@ -2074,12 +2145,23 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk, if (!ctx) return -ENOMEM; - if (nla[NFTA_RULE_TABLE]) - nla_strlcpy(ctx->table, nla[NFTA_RULE_TABLE], - sizeof(ctx->table)); - if (nla[NFTA_RULE_CHAIN]) - nla_strlcpy(ctx->chain, nla[NFTA_RULE_CHAIN], - sizeof(ctx->chain)); + if (nla[NFTA_RULE_TABLE]) { + ctx->table = nla_strdup(nla[NFTA_RULE_TABLE], + GFP_KERNEL); + if (!ctx->table) { + kfree(ctx); + return -ENOMEM; + } + } + if (nla[NFTA_RULE_CHAIN]) { + ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN], + GFP_KERNEL); + if (!ctx->chain) { + kfree(ctx->table); + kfree(ctx); + return -ENOMEM; + } + } c.data = ctx; } @@ -2621,7 +2703,7 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set, unsigned long *inuse; unsigned int n = 0, min = 0; - p = strnchr(name, NFT_SET_MAXNAMELEN, '%'); + p = strchr(name, '%'); if (p != NULL) { if (p[1] != 'd' || strchr(p + 2, '%')) return -EINVAL; @@ -2652,7 +2734,10 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set, free_page((unsigned long)inuse); } - snprintf(set->name, sizeof(set->name), name, min + n); + set->name = kasprintf(GFP_KERNEL, name, min + n); + if (!set->name) + return -ENOMEM; + list_for_each_entry(i, &ctx->table->sets, list) { if (!nft_is_active_next(ctx->net, i)) continue; @@ -2929,7 +3014,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, struct nft_table *table; struct nft_set *set; struct nft_ctx ctx; - char name[NFT_SET_MAXNAMELEN]; + char *name; unsigned int size; bool create; u64 timeout; @@ -3075,8 +3160,14 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, goto err1; } - nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name)); + name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL); + if (!name) { + err = -ENOMEM; + goto err2; + } + err = nf_tables_set_alloc_name(&ctx, set, name); + kfree(name); if (err < 0) goto err2; @@ -3126,6 +3217,7 @@ static void nft_set_destroy(struct nft_set *set) { set->ops->destroy(set); module_put(set->ops->type->owner); + kfree(set->name); kvfree(set); } @@ -3159,7 +3251,9 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk, set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask); if (IS_ERR(set)) return PTR_ERR(set); - if (!list_empty(&set->bindings)) + + if (!list_empty(&set->bindings) || + (nlh->nlmsg_flags & NLM_F_NONREC && atomic_read(&set->nelems) > 0)) return -EBUSY; return nft_delset(&ctx, set); @@ -4209,7 +4303,7 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table, list_for_each_entry(obj, &table->objects, list) { if (!nla_strcmp(nla, obj->name) && - objtype == obj->type->type && + objtype == obj->ops->type->type && nft_active_genmask(obj, genmask)) return obj; } @@ -4231,6 +4325,7 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, const struct nlattr *attr) { struct nlattr *tb[type->maxattr + 1]; + const struct nft_object_ops *ops; struct nft_object *obj; int err; @@ -4243,16 +4338,27 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1)); } + if (type->select_ops) { + ops = type->select_ops(ctx, (const struct nlattr * const *)tb); + if (IS_ERR(ops)) { + err = PTR_ERR(ops); + goto err1; + } + } else { + ops = type->ops; + } + err = -ENOMEM; - obj = kzalloc(sizeof(struct nft_object) + type->size, GFP_KERNEL); + obj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL); if (obj == NULL) goto err1; - err = type->init(ctx, (const struct nlattr * const *)tb, obj); + err = ops->init(ctx, (const struct nlattr * const *)tb, obj); if (err < 0) goto err2; - obj->type = type; + obj->ops = ops; + return obj; err2: kfree(obj); @@ -4268,7 +4374,7 @@ static int nft_object_dump(struct sk_buff *skb, unsigned int attr, nest = nla_nest_start(skb, attr); if (!nest) goto nla_put_failure; - if (obj->type->dump(skb, obj, reset) < 0) + if (obj->ops->dump(skb, obj, reset) < 0) goto nla_put_failure; nla_nest_end(skb, nest); return 0; @@ -4363,18 +4469,24 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, goto err1; } obj->table = table; - nla_strlcpy(obj->name, nla[NFTA_OBJ_NAME], NFT_OBJ_MAXNAMELEN); + obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL); + if (!obj->name) { + err = -ENOMEM; + goto err2; + } err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj); if (err < 0) - goto err2; + goto err3; list_add_tail_rcu(&obj->list, &table->objects); table->use++; return 0; +err3: + kfree(obj->name); err2: - if (obj->type->destroy) - obj->type->destroy(obj); + if (obj->ops->destroy) + obj->ops->destroy(obj); kfree(obj); err1: module_put(type->owner); @@ -4401,7 +4513,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net, if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) || nla_put_string(skb, NFTA_OBJ_NAME, obj->name) || - nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->type->type)) || + nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) || nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) || nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset)) goto nla_put_failure; @@ -4415,7 +4527,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net, } struct nft_obj_filter { - char table[NFT_OBJ_MAXNAMELEN]; + char *table; u32 type; }; @@ -4455,7 +4567,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) goto cont; if (filter && filter->type != NFT_OBJECT_UNSPEC && - obj->type->type != filter->type) + obj->ops->type->type != filter->type) goto cont; if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid, @@ -4480,7 +4592,10 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) static int nf_tables_dump_obj_done(struct netlink_callback *cb) { - kfree(cb->data); + struct nft_obj_filter *filter = cb->data; + + kfree(filter->table); + kfree(filter); return 0; } @@ -4494,9 +4609,13 @@ nft_obj_filter_alloc(const struct nlattr * const nla[]) if (!filter) return ERR_PTR(-ENOMEM); - if (nla[NFTA_OBJ_TABLE]) - nla_strlcpy(filter->table, nla[NFTA_OBJ_TABLE], - NFT_TABLE_MAXNAMELEN); + if (nla[NFTA_OBJ_TABLE]) { + filter->table = nla_strdup(nla[NFTA_OBJ_TABLE], GFP_KERNEL); + if (!filter->table) { + kfree(filter); + return ERR_PTR(-ENOMEM); + } + } if (nla[NFTA_OBJ_TYPE]) filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE])); @@ -4576,10 +4695,11 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk, static void nft_obj_destroy(struct nft_object *obj) { - if (obj->type->destroy) - obj->type->destroy(obj); + if (obj->ops->destroy) + obj->ops->destroy(obj); - module_put(obj->type->owner); + module_put(obj->ops->type->owner); + kfree(obj->name); kfree(obj); } @@ -4662,6 +4782,7 @@ static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, { struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; + char buf[TASK_COMM_LEN]; int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN); nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0); @@ -4673,7 +4794,9 @@ static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(net->nft.base_seq & 0xffff); - if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq))) + if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) || + nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) || + nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current))) goto nla_put_failure; nlmsg_end(skb, nlh); @@ -4842,7 +4965,7 @@ static void nft_chain_commit_update(struct nft_trans *trans) { struct nft_base_chain *basechain; - if (nft_trans_chain_name(trans)[0]) + if (nft_trans_chain_name(trans)) strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans)); if (!nft_is_base_chain(trans->ctx.chain)) diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 65dbeadcb11888263527dfff874288ce437744d8..dfd0bf3810d2e81690a4a2d3ac5648cb8d881090 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -29,7 +29,7 @@ static const char *const comments[__NFT_TRACETYPE_MAX] = { [NFT_TRACETYPE_RULE] = "rule", }; -static struct nf_loginfo trace_loginfo = { +static const struct nf_loginfo trace_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { @@ -114,6 +114,22 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr, return true; } +DEFINE_STATIC_KEY_FALSE(nft_counters_enabled); + +static noinline void nft_update_chain_stats(const struct nft_chain *chain, + const struct nft_pktinfo *pkt) +{ + struct nft_stats *stats; + + local_bh_disable(); + stats = this_cpu_ptr(rcu_dereference(nft_base_chain(chain)->stats)); + u64_stats_update_begin(&stats->syncp); + stats->pkts++; + stats->bytes += pkt->skb->len; + u64_stats_update_end(&stats->syncp); + local_bh_enable(); +} + struct nft_jumpstack { const struct nft_chain *chain; const struct nft_rule *rule; @@ -130,7 +146,6 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) struct nft_regs regs; unsigned int stackptr = 0; struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; - struct nft_stats *stats; int rulenum; unsigned int gencursor = nft_genmask_cur(net); struct nft_traceinfo info; @@ -220,13 +235,8 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) nft_trace_packet(&info, basechain, NULL, -1, NFT_TRACETYPE_POLICY); - rcu_read_lock_bh(); - stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats)); - u64_stats_update_begin(&stats->syncp); - stats->pkts++; - stats->bytes += pkt->skb->len; - u64_stats_update_end(&stats->syncp); - rcu_read_unlock_bh(); + if (static_branch_unlikely(&nft_counters_enabled)) + nft_update_chain_stats(basechain, pkt); return nft_base_chain(basechain)->policy; } diff --git a/net/netfilter/nf_tables_trace.c b/net/netfilter/nf_tables_trace.c index e1b15e7a5793f6b877f63a95dc20ce2626caf7f5..e1dc527a493b8ba38b9fbea1a20d9a405613d50c 100644 --- a/net/netfilter/nf_tables_trace.c +++ b/net/netfilter/nf_tables_trace.c @@ -162,6 +162,27 @@ static int nf_trace_fill_rule_info(struct sk_buff *nlskb, NFTA_TRACE_PAD); } +static bool nft_trace_have_verdict_chain(struct nft_traceinfo *info) +{ + switch (info->type) { + case NFT_TRACETYPE_RETURN: + case NFT_TRACETYPE_RULE: + break; + default: + return false; + } + + switch (info->verdict->code) { + case NFT_JUMP: + case NFT_GOTO: + break; + default: + return false; + } + + return true; +} + void nft_trace_notify(struct nft_traceinfo *info) { const struct nft_pktinfo *pkt = info->pkt; @@ -175,13 +196,12 @@ void nft_trace_notify(struct nft_traceinfo *info) return; size = nlmsg_total_size(sizeof(struct nfgenmsg)) + - nla_total_size(NFT_TABLE_MAXNAMELEN) + - nla_total_size(NFT_CHAIN_MAXNAMELEN) + + nla_total_size(strlen(info->chain->table->name)) + + nla_total_size(strlen(info->chain->name)) + nla_total_size_64bit(sizeof(__be64)) + /* rule handle */ nla_total_size(sizeof(__be32)) + /* trace type */ nla_total_size(0) + /* VERDICT, nested */ nla_total_size(sizeof(u32)) + /* verdict code */ - nla_total_size(NFT_CHAIN_MAXNAMELEN) + /* jump target */ nla_total_size(sizeof(u32)) + /* id */ nla_total_size(NFT_TRACETYPE_LL_HSIZE) + nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) + @@ -194,6 +214,9 @@ void nft_trace_notify(struct nft_traceinfo *info) nla_total_size(sizeof(u32)) + /* nfproto */ nla_total_size(sizeof(u32)); /* policy */ + if (nft_trace_have_verdict_chain(info)) + size += nla_total_size(strlen(info->verdict->chain->name)); /* jump target */ + skb = nlmsg_new(size, GFP_ATOMIC); if (!skb) return; @@ -217,14 +240,11 @@ void nft_trace_notify(struct nft_traceinfo *info) if (trace_fill_id(skb, pkt->skb)) goto nla_put_failure; - if (info->chain) { - if (nla_put_string(skb, NFTA_TRACE_CHAIN, - info->chain->name)) - goto nla_put_failure; - if (nla_put_string(skb, NFTA_TRACE_TABLE, - info->chain->table->name)) - goto nla_put_failure; - } + if (nla_put_string(skb, NFTA_TRACE_CHAIN, info->chain->name)) + goto nla_put_failure; + + if (nla_put_string(skb, NFTA_TRACE_TABLE, info->chain->table->name)) + goto nla_put_failure; if (nf_trace_fill_rule_info(skb, info)) goto nla_put_failure; diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 400e9ae971533439ed1711c63ce222a5833ee105..32b1c0b44e791552693b33f9d24dff8936164542 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -47,7 +47,8 @@ static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { }; static int -ctnl_timeout_parse_policy(void *timeouts, struct nf_conntrack_l4proto *l4proto, +ctnl_timeout_parse_policy(void *timeouts, + const struct nf_conntrack_l4proto *l4proto, struct net *net, const struct nlattr *attr) { int ret = 0; @@ -74,7 +75,7 @@ static int cttimeout_new_timeout(struct net *net, struct sock *ctnl, { __u16 l3num; __u8 l4num; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; struct ctnl_timeout *timeout, *matching = NULL; char *name; int ret; @@ -158,7 +159,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; unsigned int flags = portid ? NLM_F_MULTI : 0; - struct nf_conntrack_l4proto *l4proto = timeout->l4proto; + const struct nf_conntrack_l4proto *l4proto = timeout->l4proto; event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event); nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); @@ -363,10 +364,10 @@ static int cttimeout_default_set(struct net *net, struct sock *ctnl, const struct nlattr * const cda[], struct netlink_ext_ack *extack) { + const struct nf_conntrack_l4proto *l4proto; + unsigned int *timeouts; __u16 l3num; __u8 l4num; - struct nf_conntrack_l4proto *l4proto; - unsigned int *timeouts; int ret; if (!cda[CTA_TIMEOUT_L3PROTO] || @@ -401,7 +402,7 @@ static int cttimeout_default_set(struct net *net, struct sock *ctnl, static int cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid, u32 seq, u32 type, int event, - struct nf_conntrack_l4proto *l4proto) + const struct nf_conntrack_l4proto *l4proto) { struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; @@ -453,11 +454,11 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl, const struct nlattr * const cda[], struct netlink_ext_ack *extack) { - __u16 l3num; - __u8 l4num; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l4proto *l4proto; struct sk_buff *skb2; int ret, err; + __u16 l3num; + __u8 l4num; if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO]) return -EINVAL; @@ -505,7 +506,6 @@ ctnl_timeout_find_get(struct net *net, const char *name) { struct ctnl_timeout *timeout, *matching = NULL; - rcu_read_lock(); list_for_each_entry_rcu(timeout, &net->nfct_timeout_list, head) { if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0) continue; @@ -521,7 +521,6 @@ ctnl_timeout_find_get(struct net *net, const char *name) break; } err: - rcu_read_unlock(); return matching; } @@ -572,6 +571,7 @@ static void __net_exit cttimeout_net_exit(struct net *net) { struct ctnl_timeout *cur, *tmp; + nf_ct_unconfirmed_destroy(net); ctnl_untimeout(net, NULL); list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) { diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index c684ba95dbb49447b0ddb2a7a1f27b54536a5a03..cad6498f10b03fca0e873eb8718734b471a65f9c 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -606,7 +606,7 @@ __build_packet_message(struct nfnl_log_net *log, return -1; } -static struct nf_loginfo default_loginfo = { +static const struct nf_loginfo default_loginfo = { .type = NF_LOG_TYPE_ULOG, .u = { .ulog = { diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 16fa04086880c5390ed35c8d1e1bc90c923d45de..c9796629858f795629f0de0c60e0cd41acc85a80 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -41,6 +41,10 @@ #include "../bridge/br_private.h" #endif +#if IS_ENABLED(CONFIG_NF_CONNTRACK) +#include +#endif + #define NFQNL_QMAX_DEFAULT 1024 /* We're using struct nlattr which has 16bit nla_len. Note that nla_len @@ -612,6 +616,18 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, return NULL; } +static bool nf_ct_drop_unconfirmed(const struct nf_queue_entry *entry) +{ +#if IS_ENABLED(CONFIG_NF_CONNTRACK) + static const unsigned long flags = IPS_CONFIRMED | IPS_DYING; + const struct nf_conn *ct = (void *)skb_nfct(entry->skb); + + if (ct && ((ct->status & flags) == IPS_DYING)) + return true; +#endif + return false; +} + static int __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue, struct nf_queue_entry *entry) @@ -628,6 +644,9 @@ __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue, } spin_lock_bh(&queue->lock); + if (nf_ct_drop_unconfirmed(entry)) + goto err_out_free_nskb; + if (queue->queue_total >= queue->queue_maxlen) { if (queue->flags & NFQA_CFG_F_FAIL_OPEN) { failopen = 1; @@ -928,7 +947,6 @@ static unsigned int nfqnl_nf_hook_drop(struct net *net) unsigned int instances = 0; int i; - rcu_read_lock(); for (i = 0; i < INSTANCE_BUCKETS; i++) { struct nfqnl_instance *inst; struct hlist_head *head = &q->instance_table[i]; @@ -938,7 +956,6 @@ static unsigned int nfqnl_nf_hook_drop(struct net *net) instances++; } } - rcu_read_unlock(); return instances; } diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index f5a7cb68694e76db73dec897ad51305f29bb8981..b89f4f65b2a0fbbcd725001e58ae373ab2c3156b 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -305,7 +305,7 @@ static int nft_target_validate(const struct nft_ctx *ctx, const struct nf_hook_ops *ops = &basechain->ops[0]; hook_mask = 1 << ops->hooknum; - if (!(hook_mask & target->hooks)) + if (target->hooks && !(hook_mask & target->hooks)) return -EINVAL; ret = nft_compat_chain_validate_dependency(target->table, @@ -484,7 +484,7 @@ static int nft_match_validate(const struct nft_ctx *ctx, const struct nf_hook_ops *ops = &basechain->ops[0]; hook_mask = 1 << ops->hooknum; - if (!(hook_mask & match->hooks)) + if (match->hooks && !(hook_mask & match->hooks)) return -EINVAL; ret = nft_compat_chain_validate_dependency(match->table, diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c index 67a710ebde09da21464da4bb22a78a36c791274d..eefe3b4099252f573ef3c7cbd9acafd273f9ea82 100644 --- a/net/netfilter/nft_counter.c +++ b/net/netfilter/nft_counter.c @@ -175,15 +175,21 @@ static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = { [NFTA_COUNTER_BYTES] = { .type = NLA_U64 }, }; -static struct nft_object_type nft_counter_obj __read_mostly = { - .type = NFT_OBJECT_COUNTER, +static struct nft_object_type nft_counter_obj_type; +static const struct nft_object_ops nft_counter_obj_ops = { + .type = &nft_counter_obj_type, .size = sizeof(struct nft_counter_percpu_priv), - .maxattr = NFTA_COUNTER_MAX, - .policy = nft_counter_policy, .eval = nft_counter_obj_eval, .init = nft_counter_obj_init, .destroy = nft_counter_obj_destroy, .dump = nft_counter_obj_dump, +}; + +static struct nft_object_type nft_counter_obj_type __read_mostly = { + .type = NFT_OBJECT_COUNTER, + .ops = &nft_counter_obj_ops, + .maxattr = NFTA_COUNTER_MAX, + .policy = nft_counter_policy, .owner = THIS_MODULE, }; @@ -271,7 +277,7 @@ static int __init nft_counter_module_init(void) for_each_possible_cpu(cpu) seqcount_init(per_cpu_ptr(&nft_counter_seq, cpu)); - err = nft_register_obj(&nft_counter_obj); + err = nft_register_obj(&nft_counter_obj_type); if (err < 0) return err; @@ -281,14 +287,14 @@ static int __init nft_counter_module_init(void) return 0; err1: - nft_unregister_obj(&nft_counter_obj); + nft_unregister_obj(&nft_counter_obj_type); return err; } static void __exit nft_counter_module_exit(void) { nft_unregister_expr(&nft_counter_type); - nft_unregister_obj(&nft_counter_obj); + nft_unregister_obj(&nft_counter_obj_type); } module_init(nft_counter_module_init); diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 1678e9e75e8ee7d22301d6083ddeb04dd39ab385..bd0975d7dd6fe235418b904fe1b7cddd600b1663 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -904,15 +904,21 @@ static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = { [NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 }, }; -static struct nft_object_type nft_ct_helper_obj __read_mostly = { - .type = NFT_OBJECT_CT_HELPER, +static struct nft_object_type nft_ct_helper_obj_type; +static const struct nft_object_ops nft_ct_helper_obj_ops = { + .type = &nft_ct_helper_obj_type, .size = sizeof(struct nft_ct_helper_obj), - .maxattr = NFTA_CT_HELPER_MAX, - .policy = nft_ct_helper_policy, .eval = nft_ct_helper_obj_eval, .init = nft_ct_helper_obj_init, .destroy = nft_ct_helper_obj_destroy, .dump = nft_ct_helper_obj_dump, +}; + +static struct nft_object_type nft_ct_helper_obj_type __read_mostly = { + .type = NFT_OBJECT_CT_HELPER, + .ops = &nft_ct_helper_obj_ops, + .maxattr = NFTA_CT_HELPER_MAX, + .policy = nft_ct_helper_policy, .owner = THIS_MODULE, }; @@ -930,7 +936,7 @@ static int __init nft_ct_module_init(void) if (err < 0) goto err1; - err = nft_register_obj(&nft_ct_helper_obj); + err = nft_register_obj(&nft_ct_helper_obj_type); if (err < 0) goto err2; @@ -945,7 +951,7 @@ static int __init nft_ct_module_init(void) static void __exit nft_ct_module_exit(void) { - nft_unregister_obj(&nft_ct_helper_obj); + nft_unregister_obj(&nft_ct_helper_obj_type); nft_unregister_expr(&nft_notrack_type); nft_unregister_expr(&nft_ct_type); } diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index 1ec49fe5845f1ec8f289f411d456a5765303e244..a0a93d987a3bd440dc19bafe9e65b023c6baf217 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -8,6 +8,7 @@ * Development of this code funded by Astaro AG (http://www.astaro.com/) */ +#include #include #include #include @@ -23,6 +24,7 @@ struct nft_exthdr { u8 len; u8 op; enum nft_registers dreg:8; + enum nft_registers sreg:8; u8 flags; }; @@ -61,6 +63,26 @@ static void nft_exthdr_ipv6_eval(const struct nft_expr *expr, regs->verdict.code = NFT_BREAK; } +static void * +nft_tcp_header_pointer(const struct nft_pktinfo *pkt, + unsigned int len, void *buffer, unsigned int *tcphdr_len) +{ + struct tcphdr *tcph; + + if (!pkt->tprot_set || pkt->tprot != IPPROTO_TCP) + return NULL; + + tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff, sizeof(*tcph), buffer); + if (!tcph) + return NULL; + + *tcphdr_len = __tcp_hdrlen(tcph); + if (*tcphdr_len < sizeof(*tcph) || *tcphdr_len > len) + return NULL; + + return skb_header_pointer(pkt->skb, pkt->xt.thoff, *tcphdr_len, buffer); +} + static void nft_exthdr_tcp_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) @@ -72,18 +94,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr, struct tcphdr *tcph; u8 *opt; - if (!pkt->tprot_set || pkt->tprot != IPPROTO_TCP) - goto err; - - tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff, sizeof(*tcph), buff); - if (!tcph) - goto err; - - tcphdr_len = __tcp_hdrlen(tcph); - if (tcphdr_len < sizeof(*tcph)) - goto err; - - tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff, tcphdr_len, buff); + tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); if (!tcph) goto err; @@ -115,6 +126,88 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr, regs->verdict.code = NFT_BREAK; } +static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + u8 buff[sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE]; + struct nft_exthdr *priv = nft_expr_priv(expr); + unsigned int i, optl, tcphdr_len, offset; + struct tcphdr *tcph; + u8 *opt; + u32 src; + + tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); + if (!tcph) + return; + + opt = (u8 *)tcph; + for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { + union { + u8 octet; + __be16 v16; + __be32 v32; + } old, new; + + optl = optlen(opt, i); + + if (priv->type != opt[i]) + continue; + + if (i + optl > tcphdr_len || priv->len + priv->offset > optl) + return; + + if (!skb_make_writable(pkt->skb, pkt->xt.thoff + i + priv->len)) + return; + + tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, + &tcphdr_len); + if (!tcph) + return; + + src = regs->data[priv->sreg]; + offset = i + priv->offset; + + switch (priv->len) { + case 2: + old.v16 = get_unaligned((u16 *)(opt + offset)); + new.v16 = src; + + switch (priv->type) { + case TCPOPT_MSS: + /* increase can cause connection to stall */ + if (ntohs(old.v16) <= ntohs(new.v16)) + return; + break; + } + + if (old.v16 == new.v16) + return; + + put_unaligned(new.v16, (u16*)(opt + offset)); + inet_proto_csum_replace2(&tcph->check, pkt->skb, + old.v16, new.v16, false); + break; + case 4: + new.v32 = src; + old.v32 = get_unaligned((u32 *)(opt + offset)); + + if (old.v32 == new.v32) + return; + + put_unaligned(new.v32, (u32*)(opt + offset)); + inet_proto_csum_replace4(&tcph->check, pkt->skb, + old.v32, new.v32, false); + break; + default: + WARN_ON_ONCE(1); + break; + } + + return; + } +} + static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { [NFTA_EXTHDR_DREG] = { .type = NLA_U32 }, [NFTA_EXTHDR_TYPE] = { .type = NLA_U8 }, @@ -171,12 +264,57 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, NFT_DATA_VALUE, priv->len); } -static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr) +static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) { - const struct nft_exthdr *priv = nft_expr_priv(expr); + struct nft_exthdr *priv = nft_expr_priv(expr); + u32 offset, len, flags = 0, op = NFT_EXTHDR_OP_IPV6; + int err; - if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg)) - goto nla_put_failure; + if (!tb[NFTA_EXTHDR_SREG] || + !tb[NFTA_EXTHDR_TYPE] || + !tb[NFTA_EXTHDR_OFFSET] || + !tb[NFTA_EXTHDR_LEN]) + return -EINVAL; + + if (tb[NFTA_EXTHDR_DREG] || tb[NFTA_EXTHDR_FLAGS]) + return -EINVAL; + + err = nft_parse_u32_check(tb[NFTA_EXTHDR_OFFSET], U8_MAX, &offset); + if (err < 0) + return err; + + err = nft_parse_u32_check(tb[NFTA_EXTHDR_LEN], U8_MAX, &len); + if (err < 0) + return err; + + if (offset < 2) + return -EOPNOTSUPP; + + switch (len) { + case 2: break; + case 4: break; + default: + return -EOPNOTSUPP; + } + + err = nft_parse_u32_check(tb[NFTA_EXTHDR_OP], U8_MAX, &op); + if (err < 0) + return err; + + priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); + priv->offset = offset; + priv->len = len; + priv->sreg = nft_parse_register(tb[NFTA_EXTHDR_SREG]); + priv->flags = flags; + priv->op = op; + + return nft_validate_register_load(priv->sreg, priv->len); +} + +static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv) +{ if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) goto nla_put_failure; if (nla_put_be32(skb, NFTA_EXTHDR_OFFSET, htonl(priv->offset))) @@ -193,6 +331,26 @@ static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr) return -1; } +static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr) +{ + const struct nft_exthdr *priv = nft_expr_priv(expr); + + if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg)) + return -1; + + return nft_exthdr_dump_common(skb, priv); +} + +static int nft_exthdr_dump_set(struct sk_buff *skb, const struct nft_expr *expr) +{ + const struct nft_exthdr *priv = nft_expr_priv(expr); + + if (nft_dump_register(skb, NFTA_EXTHDR_SREG, priv->sreg)) + return -1; + + return nft_exthdr_dump_common(skb, priv); +} + static struct nft_expr_type nft_exthdr_type; static const struct nft_expr_ops nft_exthdr_ipv6_ops = { .type = &nft_exthdr_type, @@ -210,6 +368,14 @@ static const struct nft_expr_ops nft_exthdr_tcp_ops = { .dump = nft_exthdr_dump, }; +static const struct nft_expr_ops nft_exthdr_tcp_set_ops = { + .type = &nft_exthdr_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), + .eval = nft_exthdr_tcp_set_eval, + .init = nft_exthdr_tcp_set_init, + .dump = nft_exthdr_dump_set, +}; + static const struct nft_expr_ops * nft_exthdr_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) @@ -219,12 +385,21 @@ nft_exthdr_select_ops(const struct nft_ctx *ctx, if (!tb[NFTA_EXTHDR_OP]) return &nft_exthdr_ipv6_ops; - op = ntohl(nla_get_u32(tb[NFTA_EXTHDR_OP])); + if (tb[NFTA_EXTHDR_SREG] && tb[NFTA_EXTHDR_DREG]) + return ERR_PTR(-EOPNOTSUPP); + + op = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OP])); switch (op) { case NFT_EXTHDR_OP_TCPOPT: - return &nft_exthdr_tcp_ops; + if (tb[NFTA_EXTHDR_SREG]) + return &nft_exthdr_tcp_set_ops; + if (tb[NFTA_EXTHDR_DREG]) + return &nft_exthdr_tcp_ops; + break; case NFT_EXTHDR_OP_IPV6: - return &nft_exthdr_ipv6_ops; + if (tb[NFTA_EXTHDR_DREG]) + return &nft_exthdr_ipv6_ops; + break; } return ERR_PTR(-EOPNOTSUPP); diff --git a/net/netfilter/nft_fib_netdev.c b/net/netfilter/nft_fib_netdev.c new file mode 100644 index 0000000000000000000000000000000000000000..3997ee36cfbd53dec727370e0f3ea46da1cd267c --- /dev/null +++ b/net/netfilter/nft_fib_netdev.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017 Pablo M. Bermudo Garay + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This code is based on net/netfilter/nft_fib_inet.c, written by + * Florian Westphal . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static void nft_fib_netdev_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + const struct nft_fib *priv = nft_expr_priv(expr); + + switch (ntohs(pkt->skb->protocol)) { + case ETH_P_IP: + switch (priv->result) { + case NFT_FIB_RESULT_OIF: + case NFT_FIB_RESULT_OIFNAME: + return nft_fib4_eval(expr, regs, pkt); + case NFT_FIB_RESULT_ADDRTYPE: + return nft_fib4_eval_type(expr, regs, pkt); + } + break; + case ETH_P_IPV6: + switch (priv->result) { + case NFT_FIB_RESULT_OIF: + case NFT_FIB_RESULT_OIFNAME: + return nft_fib6_eval(expr, regs, pkt); + case NFT_FIB_RESULT_ADDRTYPE: + return nft_fib6_eval_type(expr, regs, pkt); + } + break; + } + + regs->verdict.code = NFT_BREAK; +} + +static struct nft_expr_type nft_fib_netdev_type; +static const struct nft_expr_ops nft_fib_netdev_ops = { + .type = &nft_fib_netdev_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_fib)), + .eval = nft_fib_netdev_eval, + .init = nft_fib_init, + .dump = nft_fib_dump, + .validate = nft_fib_validate, +}; + +static struct nft_expr_type nft_fib_netdev_type __read_mostly = { + .family = NFPROTO_NETDEV, + .name = "fib", + .ops = &nft_fib_netdev_ops, + .policy = nft_fib_policy, + .maxattr = NFTA_FIB_MAX, + .owner = THIS_MODULE, +}; + +static int __init nft_fib_netdev_module_init(void) +{ + return nft_register_expr(&nft_fib_netdev_type); +} + +static void __exit nft_fib_netdev_module_exit(void) +{ + nft_unregister_expr(&nft_fib_netdev_type); +} + +module_init(nft_fib_netdev_module_init); +module_exit(nft_fib_netdev_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Pablo M. Bermudo Garay "); +MODULE_ALIAS_NFT_AF_EXPR(5, "fib"); diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index 18dd57a526513bd726944fa7ad7a9e41fcfb0251..a9fc298ef4c3a9be6c1a4b9fb65cacfd71c3dc46 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c @@ -65,19 +65,23 @@ static int nft_limit_init(struct nft_limit *limit, limit->nsecs = unit * NSEC_PER_SEC; if (limit->rate == 0 || limit->nsecs < unit) return -EOVERFLOW; - limit->tokens = limit->tokens_max = limit->nsecs; - - if (tb[NFTA_LIMIT_BURST]) { - u64 rate; + if (tb[NFTA_LIMIT_BURST]) limit->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST])); + else + limit->burst = 0; - rate = limit->rate + limit->burst; - if (rate < limit->rate) - return -EOVERFLOW; + if (limit->rate + limit->burst < limit->rate) + return -EOVERFLOW; + + /* The token bucket size limits the number of tokens can be + * accumulated. tokens_max specifies the bucket size. + * tokens_max = unit * (rate + burst) / rate. + */ + limit->tokens = div_u64(limit->nsecs * (limit->rate + limit->burst), + limit->rate); + limit->tokens_max = limit->tokens; - limit->rate = rate; - } if (tb[NFTA_LIMIT_FLAGS]) { u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS])); @@ -95,9 +99,8 @@ static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit, { u32 flags = limit->invert ? NFT_LIMIT_F_INV : 0; u64 secs = div_u64(limit->nsecs, NSEC_PER_SEC); - u64 rate = limit->rate - limit->burst; - if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(rate), + if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(limit->rate), NFTA_LIMIT_PAD) || nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs), NFTA_LIMIT_PAD) || @@ -165,9 +168,9 @@ static const struct nft_expr_ops nft_limit_pkts_ops = { .dump = nft_limit_pkts_dump, }; -static void nft_limit_pkt_bytes_eval(const struct nft_expr *expr, - struct nft_regs *regs, - const struct nft_pktinfo *pkt) +static void nft_limit_bytes_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) { struct nft_limit *priv = nft_expr_priv(expr); u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate); @@ -176,29 +179,29 @@ static void nft_limit_pkt_bytes_eval(const struct nft_expr *expr, regs->verdict.code = NFT_BREAK; } -static int nft_limit_pkt_bytes_init(const struct nft_ctx *ctx, - const struct nft_expr *expr, - const struct nlattr * const tb[]) +static int nft_limit_bytes_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) { struct nft_limit *priv = nft_expr_priv(expr); return nft_limit_init(priv, tb); } -static int nft_limit_pkt_bytes_dump(struct sk_buff *skb, - const struct nft_expr *expr) +static int nft_limit_bytes_dump(struct sk_buff *skb, + const struct nft_expr *expr) { const struct nft_limit *priv = nft_expr_priv(expr); return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES); } -static const struct nft_expr_ops nft_limit_pkt_bytes_ops = { +static const struct nft_expr_ops nft_limit_bytes_ops = { .type = &nft_limit_type, .size = NFT_EXPR_SIZE(sizeof(struct nft_limit)), - .eval = nft_limit_pkt_bytes_eval, - .init = nft_limit_pkt_bytes_init, - .dump = nft_limit_pkt_bytes_dump, + .eval = nft_limit_bytes_eval, + .init = nft_limit_bytes_init, + .dump = nft_limit_bytes_dump, }; static const struct nft_expr_ops * @@ -212,7 +215,7 @@ nft_limit_select_ops(const struct nft_ctx *ctx, case NFT_LIMIT_PKTS: return &nft_limit_pkts_ops; case NFT_LIMIT_PKT_BYTES: - return &nft_limit_pkt_bytes_ops; + return &nft_limit_bytes_ops; } return ERR_PTR(-EOPNOTSUPP); } @@ -226,14 +229,133 @@ static struct nft_expr_type nft_limit_type __read_mostly = { .owner = THIS_MODULE, }; +static void nft_limit_obj_pkts_eval(struct nft_object *obj, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + struct nft_limit_pkts *priv = nft_obj_data(obj); + + if (nft_limit_eval(&priv->limit, priv->cost)) + regs->verdict.code = NFT_BREAK; +} + +static int nft_limit_obj_pkts_init(const struct nft_ctx *ctx, + const struct nlattr * const tb[], + struct nft_object *obj) +{ + struct nft_limit_pkts *priv = nft_obj_data(obj); + int err; + + err = nft_limit_init(&priv->limit, tb); + if (err < 0) + return err; + + priv->cost = div64_u64(priv->limit.nsecs, priv->limit.rate); + return 0; +} + +static int nft_limit_obj_pkts_dump(struct sk_buff *skb, + struct nft_object *obj, + bool reset) +{ + const struct nft_limit_pkts *priv = nft_obj_data(obj); + + return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS); +} + +static struct nft_object_type nft_limit_obj_type; +static const struct nft_object_ops nft_limit_obj_pkts_ops = { + .type = &nft_limit_obj_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_limit_pkts)), + .init = nft_limit_obj_pkts_init, + .eval = nft_limit_obj_pkts_eval, + .dump = nft_limit_obj_pkts_dump, +}; + +static void nft_limit_obj_bytes_eval(struct nft_object *obj, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + struct nft_limit *priv = nft_obj_data(obj); + u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate); + + if (nft_limit_eval(priv, cost)) + regs->verdict.code = NFT_BREAK; +} + +static int nft_limit_obj_bytes_init(const struct nft_ctx *ctx, + const struct nlattr * const tb[], + struct nft_object *obj) +{ + struct nft_limit *priv = nft_obj_data(obj); + + return nft_limit_init(priv, tb); +} + +static int nft_limit_obj_bytes_dump(struct sk_buff *skb, + struct nft_object *obj, + bool reset) +{ + const struct nft_limit *priv = nft_obj_data(obj); + + return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES); +} + +static struct nft_object_type nft_limit_obj_type; +static const struct nft_object_ops nft_limit_obj_bytes_ops = { + .type = &nft_limit_obj_type, + .size = sizeof(struct nft_limit), + .init = nft_limit_obj_bytes_init, + .eval = nft_limit_obj_bytes_eval, + .dump = nft_limit_obj_bytes_dump, +}; + +static const struct nft_object_ops * +nft_limit_obj_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) +{ + if (!tb[NFTA_LIMIT_TYPE]) + return &nft_limit_obj_pkts_ops; + + switch (ntohl(nla_get_be32(tb[NFTA_LIMIT_TYPE]))) { + case NFT_LIMIT_PKTS: + return &nft_limit_obj_pkts_ops; + case NFT_LIMIT_PKT_BYTES: + return &nft_limit_obj_bytes_ops; + } + return ERR_PTR(-EOPNOTSUPP); +} + +static struct nft_object_type nft_limit_obj_type __read_mostly = { + .select_ops = nft_limit_obj_select_ops, + .type = NFT_OBJECT_LIMIT, + .maxattr = NFTA_LIMIT_MAX, + .policy = nft_limit_policy, + .owner = THIS_MODULE, +}; + static int __init nft_limit_module_init(void) { - return nft_register_expr(&nft_limit_type); + int err; + + err = nft_register_obj(&nft_limit_obj_type); + if (err < 0) + return err; + + err = nft_register_expr(&nft_limit_type); + if (err < 0) + goto err1; + + return 0; +err1: + nft_unregister_obj(&nft_limit_obj_type); + return err; } static void __exit nft_limit_module_exit(void) { nft_unregister_expr(&nft_limit_type); + nft_unregister_obj(&nft_limit_obj_type); } module_init(nft_limit_module_init); @@ -242,3 +364,4 @@ module_exit(nft_limit_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy "); MODULE_ALIAS_NFT_EXPR("limit"); +MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_LIMIT); diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c index 1dd428fbaaa3f836e7bcecb50355f60c14d8faad..7bcdc48f3d737a45758da58102638eab6f7cd7cf 100644 --- a/net/netfilter/nft_objref.c +++ b/net/netfilter/nft_objref.c @@ -22,7 +22,7 @@ static void nft_objref_eval(const struct nft_expr *expr, { struct nft_object *obj = nft_objref_priv(expr); - obj->type->eval(obj, regs, pkt); + obj->ops->eval(obj, regs, pkt); } static int nft_objref_init(const struct nft_ctx *ctx, @@ -54,7 +54,8 @@ static int nft_objref_dump(struct sk_buff *skb, const struct nft_expr *expr) const struct nft_object *obj = nft_objref_priv(expr); if (nla_put_string(skb, NFTA_OBJREF_IMM_NAME, obj->name) || - nla_put_be32(skb, NFTA_OBJREF_IMM_TYPE, htonl(obj->type->type))) + nla_put_be32(skb, NFTA_OBJREF_IMM_TYPE, + htonl(obj->ops->type->type))) goto nla_put_failure; return 0; @@ -104,7 +105,7 @@ static void nft_objref_map_eval(const struct nft_expr *expr, return; } obj = *nft_set_ext_obj(ext); - obj->type->eval(obj, regs, pkt); + obj->ops->eval(obj, regs, pkt); } static int nft_objref_map_init(const struct nft_ctx *ctx, diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c index 7d699bbd45b0eaae1574a094f54a85d8219d390a..e110b0ebbf58b02b5b4ae8e9b8f9ad804ac861ba 100644 --- a/net/netfilter/nft_payload.c +++ b/net/netfilter/nft_payload.c @@ -184,7 +184,7 @@ static bool nft_payload_udp_checksum(struct sk_buff *skb, unsigned int thoff) if (!uh) return false; - return uh->check; + return (__force bool)uh->check; } static int nft_payload_l4csum_offset(const struct nft_pktinfo *pkt, diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c index 25e33159be57882fcf9875725079188dfaa7d113..0ed124a93fcf3ee1149df52de147b19df712cfb9 100644 --- a/net/netfilter/nft_quota.c +++ b/net/netfilter/nft_quota.c @@ -151,14 +151,20 @@ static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj, return nft_quota_do_dump(skb, priv, reset); } -static struct nft_object_type nft_quota_obj __read_mostly = { - .type = NFT_OBJECT_QUOTA, +static struct nft_object_type nft_quota_obj_type; +static const struct nft_object_ops nft_quota_obj_ops = { + .type = &nft_quota_obj_type, .size = sizeof(struct nft_quota), - .maxattr = NFTA_QUOTA_MAX, - .policy = nft_quota_policy, .init = nft_quota_obj_init, .eval = nft_quota_obj_eval, .dump = nft_quota_obj_dump, +}; + +static struct nft_object_type nft_quota_obj_type __read_mostly = { + .type = NFT_OBJECT_QUOTA, + .ops = &nft_quota_obj_ops, + .maxattr = NFTA_QUOTA_MAX, + .policy = nft_quota_policy, .owner = THIS_MODULE, }; @@ -209,7 +215,7 @@ static int __init nft_quota_module_init(void) { int err; - err = nft_register_obj(&nft_quota_obj); + err = nft_register_obj(&nft_quota_obj_type); if (err < 0) return err; @@ -219,14 +225,14 @@ static int __init nft_quota_module_init(void) return 0; err1: - nft_unregister_obj(&nft_quota_obj); + nft_unregister_obj(&nft_quota_obj_type); return err; } static void __exit nft_quota_module_exit(void) { nft_unregister_expr(&nft_quota_type); - nft_unregister_obj(&nft_quota_obj); + nft_unregister_obj(&nft_quota_obj_type); } module_init(nft_quota_module_init); diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c index c7383d8f88d0b2fa90b9bc9d94df20e6198dd2de..a6b7d05aeacf475b69d85c4256251111612f2ffc 100644 --- a/net/netfilter/nft_rt.c +++ b/net/netfilter/nft_rt.c @@ -23,6 +23,43 @@ struct nft_rt { enum nft_registers dreg:8; }; +static u16 get_tcpmss(const struct nft_pktinfo *pkt, const struct dst_entry *skbdst) +{ + u32 minlen = sizeof(struct ipv6hdr), mtu = dst_mtu(skbdst); + const struct sk_buff *skb = pkt->skb; + const struct nf_afinfo *ai; + struct flowi fl; + + memset(&fl, 0, sizeof(fl)); + + switch (nft_pf(pkt)) { + case NFPROTO_IPV4: + fl.u.ip4.daddr = ip_hdr(skb)->saddr; + minlen = sizeof(struct iphdr) + sizeof(struct tcphdr); + break; + case NFPROTO_IPV6: + fl.u.ip6.daddr = ipv6_hdr(skb)->saddr; + minlen = sizeof(struct ipv6hdr) + sizeof(struct tcphdr); + break; + } + + ai = nf_get_afinfo(nft_pf(pkt)); + if (ai) { + struct dst_entry *dst = NULL; + + ai->route(nft_net(pkt), &dst, &fl, false); + if (dst) { + mtu = min(mtu, dst_mtu(dst)); + dst_release(dst); + } + } + + if (mtu <= minlen || mtu > 0xffff) + return TCP_MSS_DEFAULT; + + return mtu - minlen; +} + static void nft_rt_get_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) @@ -46,8 +83,8 @@ static void nft_rt_get_eval(const struct nft_expr *expr, if (nft_pf(pkt) != NFPROTO_IPV4) goto err; - *dest = rt_nexthop((const struct rtable *)dst, - ip_hdr(skb)->daddr); + *dest = (__force u32)rt_nexthop((const struct rtable *)dst, + ip_hdr(skb)->daddr); break; case NFT_RT_NEXTHOP6: if (nft_pf(pkt) != NFPROTO_IPV6) @@ -57,6 +94,9 @@ static void nft_rt_get_eval(const struct nft_expr *expr, &ipv6_hdr(skb)->daddr), sizeof(struct in6_addr)); break; + case NFT_RT_TCPMSS: + nft_reg_store16(dest, get_tcpmss(pkt, dst)); + break; default: WARN_ON(1); goto err; @@ -67,7 +107,7 @@ static void nft_rt_get_eval(const struct nft_expr *expr, regs->verdict.code = NFT_BREAK; } -const struct nla_policy nft_rt_policy[NFTA_RT_MAX + 1] = { +static const struct nla_policy nft_rt_policy[NFTA_RT_MAX + 1] = { [NFTA_RT_DREG] = { .type = NLA_U32 }, [NFTA_RT_KEY] = { .type = NLA_U32 }, }; @@ -94,6 +134,9 @@ static int nft_rt_get_init(const struct nft_ctx *ctx, case NFT_RT_NEXTHOP6: len = sizeof(struct in6_addr); break; + case NFT_RT_TCPMSS: + len = sizeof(u16); + break; default: return -EOPNOTSUPP; } @@ -118,6 +161,29 @@ static int nft_rt_get_dump(struct sk_buff *skb, return -1; } +static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, + const struct nft_data **data) +{ + const struct nft_rt *priv = nft_expr_priv(expr); + unsigned int hooks; + + switch (priv->key) { + case NFT_RT_NEXTHOP4: + case NFT_RT_NEXTHOP6: + case NFT_RT_CLASSID: + return 0; + case NFT_RT_TCPMSS: + hooks = (1 << NF_INET_FORWARD) | + (1 << NF_INET_LOCAL_OUT) | + (1 << NF_INET_POST_ROUTING); + break; + default: + return -EINVAL; + } + + return nft_chain_validate_hooks(ctx->chain, hooks); +} + static struct nft_expr_type nft_rt_type; static const struct nft_expr_ops nft_rt_get_ops = { .type = &nft_rt_type, @@ -125,6 +191,7 @@ static const struct nft_expr_ops nft_rt_get_ops = { .eval = nft_rt_get_eval, .init = nft_rt_get_init, .dump = nft_rt_get_dump, + .validate = nft_rt_validate, }; static struct nft_expr_type nft_rt_type __read_mostly = { diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index bce5382f1d49dfdff6432714d480b75b95c48945..d83a4ec5900d4a21dc39f74e8ba8a28a8b74a91e 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -19,8 +19,9 @@ #include struct nft_rbtree { - rwlock_t lock; struct rb_root root; + rwlock_t lock; + seqcount_t count; }; struct nft_rbtree_elem { @@ -40,8 +41,9 @@ static bool nft_rbtree_equal(const struct nft_set *set, const void *this, return memcmp(this, nft_set_ext_key(&interval->ext), set->klen) == 0; } -static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, - const u32 *key, const struct nft_set_ext **ext) +static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set, + const u32 *key, const struct nft_set_ext **ext, + unsigned int seq) { struct nft_rbtree *priv = nft_set_priv(set); const struct nft_rbtree_elem *rbe, *interval = NULL; @@ -50,15 +52,17 @@ static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, const void *this; int d; - read_lock_bh(&priv->lock); - parent = priv->root.rb_node; + parent = rcu_dereference_raw(priv->root.rb_node); while (parent != NULL) { + if (read_seqcount_retry(&priv->count, seq)) + return false; + rbe = rb_entry(parent, struct nft_rbtree_elem, node); this = nft_set_ext_key(&rbe->ext); d = memcmp(this, key, set->klen); if (d < 0) { - parent = parent->rb_left; + parent = rcu_dereference_raw(parent->rb_left); if (interval && nft_rbtree_equal(set, this, interval) && nft_rbtree_interval_end(this) && @@ -66,15 +70,14 @@ static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, continue; interval = rbe; } else if (d > 0) - parent = parent->rb_right; + parent = rcu_dereference_raw(parent->rb_right); else { if (!nft_set_elem_active(&rbe->ext, genmask)) { - parent = parent->rb_left; + parent = rcu_dereference_raw(parent->rb_left); continue; } if (nft_rbtree_interval_end(rbe)) goto out; - read_unlock_bh(&priv->lock); *ext = &rbe->ext; return true; @@ -84,15 +87,32 @@ static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, if (set->flags & NFT_SET_INTERVAL && interval != NULL && nft_set_elem_active(&interval->ext, genmask) && !nft_rbtree_interval_end(interval)) { - read_unlock_bh(&priv->lock); *ext = &interval->ext; return true; } out: - read_unlock_bh(&priv->lock); return false; } +static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set, + const u32 *key, const struct nft_set_ext **ext) +{ + struct nft_rbtree *priv = nft_set_priv(set); + unsigned int seq = read_seqcount_begin(&priv->count); + bool ret; + + ret = __nft_rbtree_lookup(net, set, key, ext, seq); + if (ret || !read_seqcount_retry(&priv->count, seq)) + return ret; + + read_lock_bh(&priv->lock); + seq = read_seqcount_begin(&priv->count); + ret = __nft_rbtree_lookup(net, set, key, ext, seq); + read_unlock_bh(&priv->lock); + + return ret; +} + static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, struct nft_rbtree_elem *new, struct nft_set_ext **ext) @@ -130,7 +150,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, } } } - rb_link_node(&new->node, parent, p); + rb_link_node_rcu(&new->node, parent, p); rb_insert_color(&new->node, &priv->root); return 0; } @@ -144,7 +164,9 @@ static int nft_rbtree_insert(const struct net *net, const struct nft_set *set, int err; write_lock_bh(&priv->lock); + write_seqcount_begin(&priv->count); err = __nft_rbtree_insert(net, set, rbe, ext); + write_seqcount_end(&priv->count); write_unlock_bh(&priv->lock); return err; @@ -158,7 +180,9 @@ static void nft_rbtree_remove(const struct net *net, struct nft_rbtree_elem *rbe = elem->priv; write_lock_bh(&priv->lock); + write_seqcount_begin(&priv->count); rb_erase(&rbe->node, &priv->root); + write_seqcount_end(&priv->count); write_unlock_bh(&priv->lock); } @@ -264,6 +288,7 @@ static int nft_rbtree_init(const struct nft_set *set, struct nft_rbtree *priv = nft_set_priv(set); rwlock_init(&priv->lock); + seqcount_init(&priv->count); priv->root = RB_ROOT; return 0; } diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index e1648238a9c99d234d77ab1711d18db9d49926bd..c83a3b5e1c6c2a91b713b6681a794bd79ab3fa08 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1192,16 +1192,10 @@ xt_replace_table(struct xt_table *table, #ifdef CONFIG_AUDIT if (audit_enabled) { - struct audit_buffer *ab; - - ab = audit_log_start(current->audit_context, GFP_KERNEL, - AUDIT_NETFILTER_CFG); - if (ab) { - audit_log_format(ab, "table=%s family=%u entries=%u", - table->name, table->af, - private->number); - audit_log_end(ab); - } + audit_log(current->audit_context, GFP_KERNEL, + AUDIT_NETFILTER_CFG, + "table=%s family=%u entries=%u", + table->name, table->af, private->number); } #endif diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 623ef37de886fa22fd508a1261f0c1934f767e5f..5a152e2acfd5816718981c2db470ce3fa69b1ce6 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -121,9 +121,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, { #ifdef CONFIG_NF_CONNTRACK_TIMEOUT typeof(nf_ct_timeout_find_get_hook) timeout_find_get; + const struct nf_conntrack_l4proto *l4proto; struct ctnl_timeout *timeout; struct nf_conn_timeout *timeout_ext; - struct nf_conntrack_l4proto *l4proto; int ret = 0; u8 proto; diff --git a/net/netfilter/xt_NETMAP.c b/net/netfilter/xt_NETMAP.c index e45a01255e7047b8c8295f87fd303ebeafe5e105..58aa9dd3c5b7559c7001e7ab74e9ef75bca106cf 100644 --- a/net/netfilter/xt_NETMAP.c +++ b/net/netfilter/xt_NETMAP.c @@ -77,10 +77,10 @@ netmap_tg4(struct sk_buff *skb, const struct xt_action_param *par) const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; struct nf_nat_range newrange; - NF_CT_ASSERT(xt_hooknum(par) == NF_INET_PRE_ROUTING || - xt_hooknum(par) == NF_INET_POST_ROUTING || - xt_hooknum(par) == NF_INET_LOCAL_OUT || - xt_hooknum(par) == NF_INET_LOCAL_IN); + WARN_ON(xt_hooknum(par) != NF_INET_PRE_ROUTING && + xt_hooknum(par) != NF_INET_POST_ROUTING && + xt_hooknum(par) != NF_INET_LOCAL_OUT && + xt_hooknum(par) != NF_INET_LOCAL_IN); ct = nf_ct_get(skb, &ctinfo); netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index c64aca611ac5c5f81ad7c925652bbb90554763ac..9dae4d665965e89d8b2699eeba8a0be6d3059952 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -62,11 +62,9 @@ static u_int32_t tcpmss_reverse_mtu(struct net *net, memset(fl6, 0, sizeof(*fl6)); fl6->daddr = ipv6_hdr(skb)->saddr; } - rcu_read_lock(); ai = nf_get_afinfo(family); if (ai != NULL) ai->route(net, (struct dst_entry **)&rt, &fl, false); - rcu_read_unlock(); if (rt != NULL) { mtu = dst_mtu(&rt->dst); diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index d767e35fff6bd8a56373ba1f6622a534bf36253d..17d7705e3bd41d5bbaf0ff6aba98a56f472a8388 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c @@ -70,13 +70,11 @@ tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr) return user_laddr; laddr = 0; - rcu_read_lock(); indev = __in_dev_get_rcu(skb->dev); for_primary_ifa(indev) { laddr = ifa->ifa_local; break; } endfor_ifa(indev); - rcu_read_unlock(); return laddr ? laddr : daddr; } @@ -125,7 +123,7 @@ nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp, __tcp_hdrlen(tcph), saddr, sport, daddr, dport, - in->ifindex); + in->ifindex, 0); if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; @@ -195,7 +193,7 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp, thoff + __tcp_hdrlen(tcph), saddr, sport, daddr, ntohs(dport), - in->ifindex); + in->ifindex, 0); if (sk && !refcount_inc_not_zero(&sk->sk_refcnt)) sk = NULL; @@ -208,7 +206,7 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp, case NFT_LOOKUP_ESTABLISHED: sk = __inet6_lookup_established(net, &tcp_hashinfo, saddr, sport, daddr, ntohs(dport), - in->ifindex); + in->ifindex, 0); break; default: BUG(); @@ -391,7 +389,6 @@ tproxy_laddr6(struct sk_buff *skb, const struct in6_addr *user_laddr, return user_laddr; laddr = NULL; - rcu_read_lock(); indev = __in6_dev_get(skb->dev); if (indev) { read_lock_bh(&indev->lock); @@ -404,7 +401,6 @@ tproxy_laddr6(struct sk_buff *skb, const struct in6_addr *user_laddr, } read_unlock_bh(&indev->lock); } - rcu_read_unlock(); return laddr ? laddr : daddr; } diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c index e329dabde35f50a397c76d1962164f89e136bd08..3b2be2ae69875e71efeef906d998e58ec6d3eefe 100644 --- a/net/netfilter/xt_addrtype.c +++ b/net/netfilter/xt_addrtype.c @@ -47,8 +47,6 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, if (dev) flow.flowi6_oif = dev->ifindex; - rcu_read_lock(); - afinfo = nf_get_afinfo(NFPROTO_IPV6); if (afinfo != NULL) { const struct nf_ipv6_ops *v6ops; @@ -63,7 +61,6 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, } else { route_err = 1; } - rcu_read_unlock(); if (route_err) return XT_ADDRTYPE_UNREACHABLE; diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index b8fd4ab762edba5061e36e305c8048cf7a6fe846..ffa8eec980e9e1edf6a6a93581510736bf042558 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -58,8 +58,7 @@ struct xt_connlimit_rb { static spinlock_t xt_connlimit_locks[CONNLIMIT_LOCK_SLOTS] __cacheline_aligned_in_smp; struct xt_connlimit_data { - struct rb_root climit_root4[CONNLIMIT_SLOTS]; - struct rb_root climit_root6[CONNLIMIT_SLOTS]; + struct rb_root climit_root[CONNLIMIT_SLOTS]; }; static u_int32_t connlimit_rnd __read_mostly; @@ -144,7 +143,6 @@ static unsigned int check_hlist(struct net *net, unsigned int length = 0; *addit = true; - rcu_read_lock(); /* check the saved connections */ hlist_for_each_entry_safe(conn, n, head, node) { @@ -179,8 +177,6 @@ static unsigned int check_hlist(struct net *net, length++; } - rcu_read_unlock(); - return length; } @@ -297,13 +293,11 @@ static int count_them(struct net *net, int count; u32 hash; - if (family == NFPROTO_IPV6) { + if (family == NFPROTO_IPV6) hash = connlimit_iphash6(addr, mask); - root = &data->climit_root6[hash]; - } else { + else hash = connlimit_iphash(addr->ip & mask->ip); - root = &data->climit_root4[hash]; - } + root = &data->climit_root[hash]; spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); @@ -382,10 +376,8 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) return -ENOMEM; } - for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i) - info->data->climit_root4[i] = RB_ROOT; - for (i = 0; i < ARRAY_SIZE(info->data->climit_root6); ++i) - info->data->climit_root6[i] = RB_ROOT; + for (i = 0; i < ARRAY_SIZE(info->data->climit_root); ++i) + info->data->climit_root[i] = RB_ROOT; return 0; } @@ -416,10 +408,8 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) nf_ct_netns_put(par->net, par->family); - for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i) - destroy_tree(&info->data->climit_root4[i]); - for (i = 0; i < ARRAY_SIZE(info->data->climit_root6); ++i) - destroy_tree(&info->data->climit_root6[i]); + for (i = 0; i < ARRAY_SIZE(info->data->climit_root); ++i) + destroy_tree(&info->data->climit_root[i]); kfree(info->data); } diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 762e1874f28b7b1faba5b48e94f743c0414689f3..5da8746f7b88ff4c9446f256e542e823a6a561b0 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -35,6 +35,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); @@ -56,6 +57,7 @@ static inline struct hashlimit_net *hashlimit_pernet(struct net *net) } /* need to declare this at the top */ +static const struct file_operations dl_file_ops_v2; static const struct file_operations dl_file_ops_v1; static const struct file_operations dl_file_ops; @@ -87,8 +89,19 @@ struct dsthash_ent { unsigned long expires; /* precalculated expiry time */ struct { unsigned long prev; /* last modification */ - u_int64_t credit; - u_int64_t credit_cap, cost; + union { + struct { + u_int64_t credit; + u_int64_t credit_cap; + u_int64_t cost; + }; + struct { + u_int32_t interval, prev_window; + u_int64_t current_rate; + u_int64_t rate; + int64_t burst; + }; + }; } rateinfo; struct rcu_head rcu; }; @@ -99,7 +112,7 @@ struct xt_hashlimit_htable { u_int8_t family; bool rnd_initialized; - struct hashlimit_cfg2 cfg; /* config */ + struct hashlimit_cfg3 cfg; /* config */ /* used internally */ spinlock_t lock; /* lock for list_head */ @@ -116,10 +129,10 @@ struct xt_hashlimit_htable { }; static int -cfg_copy(struct hashlimit_cfg2 *to, void *from, int revision) +cfg_copy(struct hashlimit_cfg3 *to, const void *from, int revision) { if (revision == 1) { - struct hashlimit_cfg1 *cfg = from; + struct hashlimit_cfg1 *cfg = (struct hashlimit_cfg1 *)from; to->mode = cfg->mode; to->avg = cfg->avg; @@ -131,7 +144,19 @@ cfg_copy(struct hashlimit_cfg2 *to, void *from, int revision) to->srcmask = cfg->srcmask; to->dstmask = cfg->dstmask; } else if (revision == 2) { - memcpy(to, from, sizeof(struct hashlimit_cfg2)); + struct hashlimit_cfg2 *cfg = (struct hashlimit_cfg2 *)from; + + to->mode = cfg->mode; + to->avg = cfg->avg; + to->burst = cfg->burst; + to->size = cfg->size; + to->max = cfg->max; + to->gc_interval = cfg->gc_interval; + to->expire = cfg->expire; + to->srcmask = cfg->srcmask; + to->dstmask = cfg->dstmask; + } else if (revision == 3) { + memcpy(to, from, sizeof(struct hashlimit_cfg3)); } else { return -EINVAL; } @@ -240,13 +265,14 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent) } static void htable_gc(struct work_struct *work); -static int htable_create(struct net *net, struct hashlimit_cfg2 *cfg, +static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, const char *name, u_int8_t family, struct xt_hashlimit_htable **out_hinfo, int revision) { struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); struct xt_hashlimit_htable *hinfo; + const struct file_operations *fops; unsigned int size, i; int ret; @@ -254,7 +280,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg2 *cfg, size = cfg->size; } else { size = (totalram_pages << PAGE_SHIFT) / 16384 / - sizeof(struct list_head); + sizeof(struct hlist_head); if (totalram_pages > 1024 * 1024 * 1024 / PAGE_SIZE) size = 8192; if (size < 16) @@ -262,13 +288,13 @@ static int htable_create(struct net *net, struct hashlimit_cfg2 *cfg, } /* FIXME: don't use vmalloc() here or anywhere else -HW */ hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + - sizeof(struct list_head) * size); + sizeof(struct hlist_head) * size); if (hinfo == NULL) return -ENOMEM; *out_hinfo = hinfo; /* copy match config into hashtable config */ - ret = cfg_copy(&hinfo->cfg, (void *)cfg, 2); + ret = cfg_copy(&hinfo->cfg, (void *)cfg, 3); if (ret) return ret; @@ -293,11 +319,21 @@ static int htable_create(struct net *net, struct hashlimit_cfg2 *cfg, } spin_lock_init(&hinfo->lock); + switch (revision) { + case 1: + fops = &dl_file_ops_v1; + break; + case 2: + fops = &dl_file_ops_v2; + break; + default: + fops = &dl_file_ops; + } + hinfo->pde = proc_create_data(name, 0, (family == NFPROTO_IPV4) ? hashlimit_net->ipt_hashlimit : hashlimit_net->ip6t_hashlimit, - (revision == 1) ? &dl_file_ops_v1 : &dl_file_ops, - hinfo); + fops, hinfo); if (hinfo->pde == NULL) { kfree(hinfo->name); vfree(hinfo); @@ -482,6 +518,25 @@ static u32 user2credits_byte(u32 user) return (u32) (us >> 32); } +static u64 user2rate(u64 user) +{ + if (user != 0) { + return div64_u64(XT_HASHLIMIT_SCALE_v2, user); + } else { + pr_warn("invalid rate from userspace: %llu\n", user); + return 0; + } +} + +static u64 user2rate_bytes(u32 user) +{ + u64 r; + + r = user ? U32_MAX / user : U32_MAX; + r = (r - 1) << XT_HASHLIMIT_BYTE_SHIFT; + return r; +} + static void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now, u32 mode, int revision) { @@ -491,6 +546,21 @@ static void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now, if (delta == 0) return; + if (revision >= 3 && mode & XT_HASHLIMIT_RATE_MATCH) { + u64 interval = dh->rateinfo.interval * HZ; + + if (delta < interval) + return; + + dh->rateinfo.prev = now; + dh->rateinfo.prev_window = + ((dh->rateinfo.current_rate * interval) > + (delta * dh->rateinfo.rate)); + dh->rateinfo.current_rate = 0; + + return; + } + dh->rateinfo.prev = now; if (mode & XT_HASHLIMIT_BYTES) { @@ -515,7 +585,24 @@ static void rateinfo_init(struct dsthash_ent *dh, struct xt_hashlimit_htable *hinfo, int revision) { dh->rateinfo.prev = jiffies; - if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { + if (revision >= 3 && hinfo->cfg.mode & XT_HASHLIMIT_RATE_MATCH) { + dh->rateinfo.prev_window = 0; + dh->rateinfo.current_rate = 0; + if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { + dh->rateinfo.rate = + user2rate_bytes((u32)hinfo->cfg.avg); + if (hinfo->cfg.burst) + dh->rateinfo.burst = + hinfo->cfg.burst * dh->rateinfo.rate; + else + dh->rateinfo.burst = dh->rateinfo.rate; + } else { + dh->rateinfo.rate = user2rate(hinfo->cfg.avg); + dh->rateinfo.burst = + hinfo->cfg.burst + dh->rateinfo.rate; + } + dh->rateinfo.interval = hinfo->cfg.interval; + } else if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { dh->rateinfo.credit = CREDITS_PER_JIFFY_BYTES * HZ; dh->rateinfo.cost = user2credits_byte(hinfo->cfg.avg); dh->rateinfo.credit_cap = hinfo->cfg.burst; @@ -648,7 +735,7 @@ static u32 hashlimit_byte_cost(unsigned int len, struct dsthash_ent *dh) static bool hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par, struct xt_hashlimit_htable *hinfo, - const struct hashlimit_cfg2 *cfg, int revision) + const struct hashlimit_cfg3 *cfg, int revision) { unsigned long now = jiffies; struct dsthash_ent *dh; @@ -659,12 +746,12 @@ hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par, if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0) goto hotdrop; - rcu_read_lock_bh(); + local_bh_disable(); dh = dsthash_find(hinfo, &dst); if (dh == NULL) { dh = dsthash_alloc_init(hinfo, &dst, &race); if (dh == NULL) { - rcu_read_unlock_bh(); + local_bh_enable(); goto hotdrop; } else if (race) { /* Already got an entry, update expiration timeout */ @@ -680,6 +767,20 @@ hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par, rateinfo_recalc(dh, now, hinfo->cfg.mode, revision); } + if (cfg->mode & XT_HASHLIMIT_RATE_MATCH) { + cost = (cfg->mode & XT_HASHLIMIT_BYTES) ? skb->len : 1; + dh->rateinfo.current_rate += cost; + + if (!dh->rateinfo.prev_window && + (dh->rateinfo.current_rate <= dh->rateinfo.burst)) { + spin_unlock(&dh->lock); + rcu_read_unlock_bh(); + return !(cfg->mode & XT_HASHLIMIT_INVERT); + } else { + goto overlimit; + } + } + if (cfg->mode & XT_HASHLIMIT_BYTES) cost = hashlimit_byte_cost(skb->len, dh); else @@ -689,12 +790,13 @@ hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par, /* below the limit */ dh->rateinfo.credit -= cost; spin_unlock(&dh->lock); - rcu_read_unlock_bh(); + local_bh_enable(); return !(cfg->mode & XT_HASHLIMIT_INVERT); } +overlimit: spin_unlock(&dh->lock); - rcu_read_unlock_bh(); + local_bh_enable(); /* default match is underlimit - so over the limit, we need to invert */ return cfg->mode & XT_HASHLIMIT_INVERT; @@ -708,7 +810,7 @@ hashlimit_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_hashlimit_mtinfo1 *info = par->matchinfo; struct xt_hashlimit_htable *hinfo = info->hinfo; - struct hashlimit_cfg2 cfg = {}; + struct hashlimit_cfg3 cfg = {}; int ret; ret = cfg_copy(&cfg, (void *)&info->cfg, 1); @@ -720,17 +822,33 @@ hashlimit_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) } static bool -hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) +hashlimit_mt_v2(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_hashlimit_mtinfo2 *info = par->matchinfo; struct xt_hashlimit_htable *hinfo = info->hinfo; + struct hashlimit_cfg3 cfg = {}; + int ret; + + ret = cfg_copy(&cfg, (void *)&info->cfg, 2); + + if (ret) + return ret; + + return hashlimit_mt_common(skb, par, hinfo, &cfg, 2); +} + +static bool +hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) +{ + const struct xt_hashlimit_mtinfo3 *info = par->matchinfo; + struct xt_hashlimit_htable *hinfo = info->hinfo; - return hashlimit_mt_common(skb, par, hinfo, &info->cfg, 2); + return hashlimit_mt_common(skb, par, hinfo, &info->cfg, 3); } static int hashlimit_mt_check_common(const struct xt_mtchk_param *par, struct xt_hashlimit_htable **hinfo, - struct hashlimit_cfg2 *cfg, + struct hashlimit_cfg3 *cfg, const char *name, int revision) { struct net *net = par->net; @@ -753,7 +871,17 @@ static int hashlimit_mt_check_common(const struct xt_mtchk_param *par, } /* Check for overflow. */ - if (cfg->mode & XT_HASHLIMIT_BYTES) { + if (revision >= 3 && cfg->mode & XT_HASHLIMIT_RATE_MATCH) { + if (cfg->avg == 0 || cfg->avg > U32_MAX) { + pr_info("hashlimit invalid rate\n"); + return -ERANGE; + } + + if (cfg->interval == 0) { + pr_info("hashlimit invalid interval\n"); + return -EINVAL; + } + } else if (cfg->mode & XT_HASHLIMIT_BYTES) { if (user2credits_byte(cfg->avg) == 0) { pr_info("overflow, rate too high: %llu\n", cfg->avg); return -EINVAL; @@ -784,7 +912,7 @@ static int hashlimit_mt_check_common(const struct xt_mtchk_param *par, static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par) { struct xt_hashlimit_mtinfo1 *info = par->matchinfo; - struct hashlimit_cfg2 cfg = {}; + struct hashlimit_cfg3 cfg = {}; int ret; if (info->name[sizeof(info->name) - 1] != '\0') @@ -799,15 +927,40 @@ static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par) &cfg, info->name, 1); } -static int hashlimit_mt_check(const struct xt_mtchk_param *par) +static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par) { struct xt_hashlimit_mtinfo2 *info = par->matchinfo; + struct hashlimit_cfg3 cfg = {}; + int ret; + + if (info->name[sizeof(info->name) - 1] != '\0') + return -EINVAL; + + ret = cfg_copy(&cfg, (void *)&info->cfg, 2); + + if (ret) + return ret; + + return hashlimit_mt_check_common(par, &info->hinfo, + &cfg, info->name, 2); +} + +static int hashlimit_mt_check(const struct xt_mtchk_param *par) +{ + struct xt_hashlimit_mtinfo3 *info = par->matchinfo; if (info->name[sizeof(info->name) - 1] != '\0') return -EINVAL; return hashlimit_mt_check_common(par, &info->hinfo, &info->cfg, - info->name, 2); + info->name, 3); +} + +static void hashlimit_mt_destroy_v2(const struct xt_mtdtor_param *par) +{ + const struct xt_hashlimit_mtinfo2 *info = par->matchinfo; + + htable_put(info->hinfo); } static void hashlimit_mt_destroy_v1(const struct xt_mtdtor_param *par) @@ -819,7 +972,7 @@ static void hashlimit_mt_destroy_v1(const struct xt_mtdtor_param *par) static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par) { - const struct xt_hashlimit_mtinfo2 *info = par->matchinfo; + const struct xt_hashlimit_mtinfo3 *info = par->matchinfo; htable_put(info->hinfo); } @@ -840,9 +993,20 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = { .name = "hashlimit", .revision = 2, .family = NFPROTO_IPV4, - .match = hashlimit_mt, + .match = hashlimit_mt_v2, .matchsize = sizeof(struct xt_hashlimit_mtinfo2), .usersize = offsetof(struct xt_hashlimit_mtinfo2, hinfo), + .checkentry = hashlimit_mt_check_v2, + .destroy = hashlimit_mt_destroy_v2, + .me = THIS_MODULE, + }, + { + .name = "hashlimit", + .revision = 3, + .family = NFPROTO_IPV4, + .match = hashlimit_mt, + .matchsize = sizeof(struct xt_hashlimit_mtinfo3), + .usersize = offsetof(struct xt_hashlimit_mtinfo3, hinfo), .checkentry = hashlimit_mt_check, .destroy = hashlimit_mt_destroy, .me = THIS_MODULE, @@ -863,9 +1027,20 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = { .name = "hashlimit", .revision = 2, .family = NFPROTO_IPV6, - .match = hashlimit_mt, + .match = hashlimit_mt_v2, .matchsize = sizeof(struct xt_hashlimit_mtinfo2), .usersize = offsetof(struct xt_hashlimit_mtinfo2, hinfo), + .checkentry = hashlimit_mt_check_v2, + .destroy = hashlimit_mt_destroy_v2, + .me = THIS_MODULE, + }, + { + .name = "hashlimit", + .revision = 3, + .family = NFPROTO_IPV6, + .match = hashlimit_mt, + .matchsize = sizeof(struct xt_hashlimit_mtinfo3), + .usersize = offsetof(struct xt_hashlimit_mtinfo3, hinfo), .checkentry = hashlimit_mt_check, .destroy = hashlimit_mt_destroy, .me = THIS_MODULE, @@ -947,6 +1122,21 @@ static void dl_seq_print(struct dsthash_ent *ent, u_int8_t family, } } +static int dl_seq_real_show_v2(struct dsthash_ent *ent, u_int8_t family, + struct seq_file *s) +{ + const struct xt_hashlimit_htable *ht = s->private; + + spin_lock(&ent->lock); + /* recalculate to show accurate numbers */ + rateinfo_recalc(ent, jiffies, ht->cfg.mode, 2); + + dl_seq_print(ent, family, s); + + spin_unlock(&ent->lock); + return seq_has_overflowed(s); +} + static int dl_seq_real_show_v1(struct dsthash_ent *ent, u_int8_t family, struct seq_file *s) { @@ -969,7 +1159,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family, spin_lock(&ent->lock); /* recalculate to show accurate numbers */ - rateinfo_recalc(ent, jiffies, ht->cfg.mode, 2); + rateinfo_recalc(ent, jiffies, ht->cfg.mode, 3); dl_seq_print(ent, family, s); @@ -977,6 +1167,20 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family, return seq_has_overflowed(s); } +static int dl_seq_show_v2(struct seq_file *s, void *v) +{ + struct xt_hashlimit_htable *htable = s->private; + unsigned int *bucket = (unsigned int *)v; + struct dsthash_ent *ent; + + if (!hlist_empty(&htable->hash[*bucket])) { + hlist_for_each_entry(ent, &htable->hash[*bucket], node) + if (dl_seq_real_show_v2(ent, htable->family, s)) + return -1; + } + return 0; +} + static int dl_seq_show_v1(struct seq_file *s, void *v) { struct xt_hashlimit_htable *htable = s->private; @@ -1012,6 +1216,13 @@ static const struct seq_operations dl_seq_ops_v1 = { .show = dl_seq_show_v1 }; +static const struct seq_operations dl_seq_ops_v2 = { + .start = dl_seq_start, + .next = dl_seq_next, + .stop = dl_seq_stop, + .show = dl_seq_show_v2 +}; + static const struct seq_operations dl_seq_ops = { .start = dl_seq_start, .next = dl_seq_next, @@ -1019,6 +1230,18 @@ static const struct seq_operations dl_seq_ops = { .show = dl_seq_show }; +static int dl_proc_open_v2(struct inode *inode, struct file *file) +{ + int ret = seq_open(file, &dl_seq_ops_v2); + + if (!ret) { + struct seq_file *sf = file->private_data; + + sf->private = PDE_DATA(inode); + } + return ret; +} + static int dl_proc_open_v1(struct inode *inode, struct file *file) { int ret = seq_open(file, &dl_seq_ops_v1); @@ -1042,6 +1265,14 @@ static int dl_proc_open(struct inode *inode, struct file *file) return ret; } +static const struct file_operations dl_file_ops_v2 = { + .owner = THIS_MODULE, + .open = dl_proc_open_v2, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + static const struct file_operations dl_file_ops_v1 = { .owner = THIS_MODULE, .open = dl_proc_open_v1, diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c index 8107b3eb865ffe55536aed3df65964d02044b3b4..0fd14d1eb09d14ba3c1797c33b022e3e0c50c97b 100644 --- a/net/netfilter/xt_nat.c +++ b/net/netfilter/xt_nat.c @@ -58,9 +58,9 @@ xt_snat_target_v0(struct sk_buff *skb, const struct xt_action_param *par) struct nf_conn *ct; ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct != NULL && - (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || - ctinfo == IP_CT_RELATED_REPLY)); + WARN_ON(!(ct != NULL && + (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || + ctinfo == IP_CT_RELATED_REPLY))); xt_nat_convert_range(&range, &mr->range[0]); return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC); @@ -75,8 +75,8 @@ xt_dnat_target_v0(struct sk_buff *skb, const struct xt_action_param *par) struct nf_conn *ct; ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct != NULL && - (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); + WARN_ON(!(ct != NULL && + (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))); xt_nat_convert_range(&range, &mr->range[0]); return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST); @@ -90,9 +90,9 @@ xt_snat_target_v1(struct sk_buff *skb, const struct xt_action_param *par) struct nf_conn *ct; ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct != NULL && - (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || - ctinfo == IP_CT_RELATED_REPLY)); + WARN_ON(!(ct != NULL && + (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || + ctinfo == IP_CT_RELATED_REPLY))); return nf_nat_setup_info(ct, range, NF_NAT_MANIP_SRC); } @@ -105,8 +105,8 @@ xt_dnat_target_v1(struct sk_buff *skb, const struct xt_action_param *par) struct nf_conn *ct; ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct != NULL && - (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); + WARN_ON(!(ct != NULL && + (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))); return nf_nat_setup_info(ct, range, NF_NAT_MANIP_DST); } diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 71cfa9551d083fc543960b51c7b089d76f1842f0..36e14b1f061ddf7eb77327a3e717e15b6af83bfb 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c @@ -226,7 +226,6 @@ xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) sizeof(struct tcphdr), optsize, opts); } - rcu_read_lock(); list_for_each_entry_rcu(kf, &xt_osf_fingers[df], finger_entry) { int foptsize, optnum; @@ -340,7 +339,6 @@ xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) info->loglevel == XT_OSF_LOGLEVEL_FIRST) break; } - rcu_read_unlock(); if (!fcount && (info->flags & XT_OSF_LOG)) nf_log_packet(net, xt_family(p), xt_hooknum(p), skb, xt_in(p), diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 3f6c4fa78bdb717c067b57b53a0900529dcc4000..245fa350a7a85390e6767c4a0c5862f4213000fe 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -106,7 +106,7 @@ static DEFINE_SPINLOCK(recent_lock); static DEFINE_MUTEX(recent_mutex); #ifdef CONFIG_PROC_FS -static const struct file_operations recent_old_fops, recent_mt_fops; +static const struct file_operations recent_mt_fops; #endif static u_int32_t hash_rnd __read_mostly; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 5acee49db90b508cb99660dc0677a44da691640e..94c11cf0459d33bb12d26e246e7e9c66314e9e85 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -691,6 +691,9 @@ static void deferred_put_nlk_sk(struct rcu_head *head) struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu); struct sock *sk = &nlk->sk; + kfree(nlk->groups); + nlk->groups = NULL; + if (!refcount_dec_and_test(&sk->sk_refcnt)) return; @@ -769,9 +772,6 @@ static int netlink_release(struct socket *sock) netlink_table_ungrab(); } - kfree(nlk->groups); - nlk->groups = NULL; - local_bh_disable(); sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1); local_bh_enable(); @@ -955,7 +955,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, struct net *net = sock_net(sk); struct netlink_sock *nlk = nlk_sk(sk); struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; - int err; + int err = 0; long unsigned int groups = nladdr->nl_groups; bool bound; @@ -983,6 +983,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, return -EINVAL; } + netlink_lock_table(); if (nlk->netlink_bind && groups) { int group; @@ -993,7 +994,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, if (!err) continue; netlink_undo_bind(group, groups, sk); - return err; + goto unlock; } } @@ -1006,12 +1007,13 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, netlink_autobind(sock); if (err) { netlink_undo_bind(nlk->ngroups, groups, sk); - return err; + goto unlock; } } if (!groups && (nlk->groups == NULL || !(u32)nlk->groups[0])) - return 0; + goto unlock; + netlink_unlock_table(); netlink_table_grab(); netlink_update_subscriptions(sk, nlk->subscriptions + @@ -1022,6 +1024,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, netlink_table_ungrab(); return 0; + +unlock: + netlink_unlock_table(); + return err; } static int netlink_connect(struct socket *sock, struct sockaddr *addr, @@ -1079,7 +1085,9 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, nladdr->nl_groups = netlink_group_mask(nlk->dst_group); } else { nladdr->nl_pid = nlk->portid; + netlink_lock_table(); nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0; + netlink_unlock_table(); } return 0; } @@ -2262,10 +2270,13 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, mutex_unlock(nlk->cb_mutex); + ret = 0; if (cb->start) - cb->start(cb); + ret = cb->start(cb); + + if (!ret) + ret = netlink_dump(sk); - ret = netlink_dump(sk); sock_put(sk); if (ret) diff --git a/net/nsh/Kconfig b/net/nsh/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bafc3dd60c2c67d412e3327be20c7f19f6b745ea --- /dev/null +++ b/net/nsh/Kconfig @@ -0,0 +1,9 @@ +menuconfig NET_NSH + tristate "Network Service Header (NSH) protocol" + default n + ---help--- + Network Service Header is an implementation of Service Function + Chaining (RFC 7665). The current implementation in Linux supports + only MD type 1 and only with the openvswitch module. + + If unsure, say N. diff --git a/net/nsh/Makefile b/net/nsh/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c93c787385ca4454a663c08bf1d4cd29d7194323 --- /dev/null +++ b/net/nsh/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_NET_NSH) += nsh.o diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c new file mode 100644 index 0000000000000000000000000000000000000000..58fb827439a86d64df4ef1978c23b66a238275c9 --- /dev/null +++ b/net/nsh/nsh.c @@ -0,0 +1,91 @@ +/* + * Network Service Header + * + * Copyright (c) 2017 Red Hat, Inc. -- Jiri Benc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, + netdev_features_t features) +{ + struct sk_buff *segs = ERR_PTR(-EINVAL); + unsigned int nsh_len, mac_len; + __be16 proto; + int nhoff; + + skb_reset_network_header(skb); + + nhoff = skb->network_header - skb->mac_header; + mac_len = skb->mac_len; + + if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) + goto out; + nsh_len = nsh_hdr_len(nsh_hdr(skb)); + if (unlikely(!pskb_may_pull(skb, nsh_len))) + goto out; + + proto = tun_p_to_eth_p(nsh_hdr(skb)->np); + if (!proto) + goto out; + + __skb_pull(skb, nsh_len); + + skb_reset_mac_header(skb); + skb_reset_mac_len(skb); + skb->protocol = proto; + + features &= NETIF_F_SG; + segs = skb_mac_gso_segment(skb, features); + if (IS_ERR_OR_NULL(segs)) { + skb_gso_error_unwind(skb, htons(ETH_P_NSH), nsh_len, + skb->network_header - nhoff, + mac_len); + goto out; + } + + for (skb = segs; skb; skb = skb->next) { + skb->protocol = htons(ETH_P_NSH); + __skb_push(skb, nsh_len); + skb_set_mac_header(skb, -nhoff); + skb->network_header = skb->mac_header + mac_len; + skb->mac_len = mac_len; + } + +out: + return segs; +} + +static struct packet_offload nsh_packet_offload __read_mostly = { + .type = htons(ETH_P_NSH), + .priority = 15, + .callbacks = { + .gso_segment = nsh_gso_segment, + }, +}; + +static int __init nsh_init_module(void) +{ + dev_add_offload(&nsh_packet_offload); + return 0; +} + +static void __exit nsh_cleanup_module(void) +{ + dev_remove_offload(&nsh_packet_offload); +} + +module_init(nsh_init_module); +module_exit(nsh_cleanup_module); + +MODULE_AUTHOR("Jiri Benc "); +MODULE_DESCRIPTION("NSH protocol"); +MODULE_LICENSE("GPL v2"); diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index e4610676299bcdac626db1a30cd4da44ccc62c0b..a54a556fcdb57d95b4a4a6606016ead527b93d64 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -1337,6 +1337,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, goto out; } + OVS_CB(skb)->acts_origlen = acts->orig_len; err = do_execute_actions(dp, skb, key, acts->actions, acts->actions_len); diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index e3c4c6c3fef7f274aef72cda0d21fc00c72de24a..d558e882ca0c5d136f497b8f1b7d5eecfb0d32df 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -579,8 +579,8 @@ static struct nf_conn * ovs_ct_find_existing(struct net *net, const struct nf_conntrack_zone *zone, u8 l3num, struct sk_buff *skb, bool natted) { - struct nf_conntrack_l3proto *l3proto; - struct nf_conntrack_l4proto *l4proto; + const struct nf_conntrack_l3proto *l3proto; + const struct nf_conntrack_l4proto *l4proto; struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; @@ -1180,15 +1180,13 @@ static int parse_nat(const struct nlattr *attr, int type = nla_type(a); if (type > OVS_NAT_ATTR_MAX) { - OVS_NLERR(log, - "Unknown NAT attribute (type=%d, max=%d).\n", + OVS_NLERR(log, "Unknown NAT attribute (type=%d, max=%d)", type, OVS_NAT_ATTR_MAX); return -EINVAL; } if (nla_len(a) != ovs_nat_attr_lens[type][ip_vers]) { - OVS_NLERR(log, - "NAT attribute type %d has unexpected length (%d != %d).\n", + OVS_NLERR(log, "NAT attribute type %d has unexpected length (%d != %d)", type, nla_len(a), ovs_nat_attr_lens[type][ip_vers]); return -EINVAL; @@ -1198,9 +1196,7 @@ static int parse_nat(const struct nlattr *attr, case OVS_NAT_ATTR_SRC: case OVS_NAT_ATTR_DST: if (info->nat) { - OVS_NLERR(log, - "Only one type of NAT may be specified.\n" - ); + OVS_NLERR(log, "Only one type of NAT may be specified"); return -ERANGE; } info->nat |= OVS_CT_NAT; @@ -1245,13 +1241,13 @@ static int parse_nat(const struct nlattr *attr, break; default: - OVS_NLERR(log, "Unknown nat attribute (%d).\n", type); + OVS_NLERR(log, "Unknown nat attribute (%d)", type); return -EINVAL; } } if (rem > 0) { - OVS_NLERR(log, "NAT attribute has %d unknown bytes.\n", rem); + OVS_NLERR(log, "NAT attribute has %d unknown bytes", rem); return -EINVAL; } if (!info->nat) { @@ -1310,8 +1306,8 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, nla_for_each_nested(a, attr, rem) { int type = nla_type(a); - int maxlen = ovs_ct_attr_lens[type].maxlen; - int minlen = ovs_ct_attr_lens[type].minlen; + int maxlen; + int minlen; if (type > OVS_CT_ATTR_MAX) { OVS_NLERR(log, @@ -1319,6 +1315,9 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info, type, OVS_CT_ATTR_MAX); return -EINVAL; } + + maxlen = ovs_ct_attr_lens[type].maxlen; + minlen = ovs_ct_attr_lens[type].minlen; if (nla_len(a) < minlen || nla_len(a) > maxlen) { OVS_NLERR(log, "Conntrack attr type has unexpected length (type=%d, length=%d, expected=%d)", diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 45fe8c8a884df36100bc0cf26d279cb92e51bdf8..c3aec6227c91b776dd41c7c8f6a9b1d1e313aee4 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -335,8 +335,6 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, const struct dp_upcall_info *upcall_info, uint32_t cutlen) { - unsigned short gso_type = skb_shinfo(skb)->gso_type; - struct sw_flow_key later_key; struct sk_buff *segs, *nskb; int err; @@ -347,21 +345,9 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, if (segs == NULL) return -EINVAL; - if (gso_type & SKB_GSO_UDP) { - /* The initial flow key extracted by ovs_flow_key_extract() - * in this case is for a first fragment, so we need to - * properly mark later fragments. - */ - later_key = *key; - later_key.ip.frag = OVS_FRAG_TYPE_LATER; - } - /* Queue all of the segments. */ skb = segs; do { - if (gso_type & SKB_GSO_UDP && skb != segs) - key = &later_key; - err = queue_userspace_packet(dp, skb, key, upcall_info, cutlen); if (err) break; @@ -381,7 +367,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, } static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info, - unsigned int hdrlen) + unsigned int hdrlen, int actions_attrlen) { size_t size = NLMSG_ALIGN(sizeof(struct ovs_header)) + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */ @@ -398,7 +384,7 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info, /* OVS_PACKET_ATTR_ACTIONS */ if (upcall_info->actions_len) - size += nla_total_size(upcall_info->actions_len); + size += nla_total_size(actions_attrlen); /* OVS_PACKET_ATTR_MRU */ if (upcall_info->mru) @@ -465,7 +451,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, else hlen = skb->len; - len = upcall_msg_size(upcall_info, hlen - cutlen); + len = upcall_msg_size(upcall_info, hlen - cutlen, + OVS_CB(skb)->acts_origlen); user_skb = genlmsg_new(len, GFP_ATOMIC); if (!user_skb) { err = -ENOMEM; @@ -1125,7 +1112,8 @@ static int ovs_nla_init_match_and_action(struct net *net, if (!a[OVS_FLOW_ATTR_KEY]) { OVS_NLERR(log, "Flow key attribute not present in set flow."); - return -EINVAL; + error = -EINVAL; + goto error; } *acts = get_flow_actions(net, a[OVS_FLOW_ATTR_ACTIONS], key, diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 5d8dcd88815f0622a48a54f14eaf5b5b9c53b18c..480600649d0b03a185f73b587181a3136d75e9b2 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -99,11 +99,13 @@ struct datapath { * when a packet is received by OVS. * @mru: The maximum received fragement size; 0 if the packet is not * fragmented. + * @acts_origlen: The netlink size of the flow actions applied to this skb. * @cutlen: The number of bytes from the packet end to be removed. */ struct ovs_skb_cb { struct vport *input_vport; u16 mru; + u16 acts_origlen; u32 cutlen; }; #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 3f76cb765e5bb71d18c3e9a4c220ed9fa3906186..8c94cef25a72b685456b2ab3e7155b17f944abcf 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -72,8 +72,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, const struct sk_buff *skb) { struct flow_stats *stats; - int node = numa_node_id(); - int cpu = smp_processor_id(); + unsigned int cpu = smp_processor_id(); int len = skb->len + (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0); stats = rcu_dereference(flow->stats[cpu]); @@ -108,7 +107,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, __GFP_THISNODE | __GFP_NOWARN | __GFP_NOMEMALLOC, - node); + numa_node_id()); if (likely(new_stats)) { new_stats->used = jiffies; new_stats->packet_count = 1; @@ -118,6 +117,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, rcu_assign_pointer(flow->stats[cpu], new_stats); + cpumask_set_cpu(cpu, &flow->cpu_used_mask); goto unlock; } } @@ -145,7 +145,7 @@ void ovs_flow_stats_get(const struct sw_flow *flow, memset(ovs_stats, 0, sizeof(*ovs_stats)); /* We open code this to make sure cpu 0 is always considered */ - for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpu_possible_mask)) { + for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, &flow->cpu_used_mask)) { struct flow_stats *stats = rcu_dereference_ovsl(flow->stats[cpu]); if (stats) { @@ -169,7 +169,7 @@ void ovs_flow_stats_clear(struct sw_flow *flow) int cpu; /* We open code this to make sure cpu 0 is always considered */ - for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpu_possible_mask)) { + for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, &flow->cpu_used_mask)) { struct flow_stats *stats = ovsl_dereference(flow->stats[cpu]); if (stats) { @@ -584,8 +584,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) key->ip.frag = OVS_FRAG_TYPE_LATER; return 0; } - if (nh->frag_off & htons(IP_MF) || - skb_shinfo(skb)->gso_type & SKB_GSO_UDP) + if (nh->frag_off & htons(IP_MF)) key->ip.frag = OVS_FRAG_TYPE_FIRST; else key->ip.frag = OVS_FRAG_TYPE_NONE; @@ -701,9 +700,6 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) if (key->ip.frag == OVS_FRAG_TYPE_LATER) return 0; - if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) - key->ip.frag = OVS_FRAG_TYPE_FIRST; - /* Transport layer. */ if (key->ip.proto == NEXTHDR_TCP) { if (tcphdr_ok(skb)) { diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index a9bc1c875965c1814cd816446598e9602e8cc13a..1875bba4f865631f4e3122b4c53a734ced6772e7 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -219,6 +220,7 @@ struct sw_flow { */ struct sw_flow_key key; struct sw_flow_id id; + struct cpumask cpu_used_mask; struct sw_flow_mask *mask; struct sw_flow_actions __rcu *sf_acts; struct flow_stats __rcu *stats[]; /* One for each CPU. First one diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index f07d10ac35d855da399baf611c83ebd53b63b02b..e8eb427ce6d1f9bd83f714193b0c28e99c724d91 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -1255,7 +1255,7 @@ static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match, } if (!is_mask && ipv6_key->ipv6_label & htonl(0xFFF00000)) { - OVS_NLERR(log, "IPv6 flow label %x is out of range (max=%x).\n", + OVS_NLERR(log, "IPv6 flow label %x is out of range (max=%x)", ntohl(ipv6_key->ipv6_label), (1 << 20) - 1); return -EINVAL; } diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index ea7a8073fa02856469bf1f0c12ce9e5ac0fbbf5a..80ea2a71852e57b26936f3563527c066c4bc3312 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c @@ -98,6 +98,8 @@ struct sw_flow *ovs_flow_alloc(void) RCU_INIT_POINTER(flow->stats[0], stats); + cpumask_set_cpu(0, &flow->cpu_used_mask); + return flow; err: kmem_cache_free(flow_cache, flow); @@ -141,7 +143,7 @@ static void flow_free(struct sw_flow *flow) if (flow->sf_acts) ovs_nla_free_flow_actions((struct sw_flow_actions __force *)flow->sf_acts); /* We open code this to make sure cpu 0 is always considered */ - for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpu_possible_mask)) + for (cpu = 0; cpu < nr_cpu_ids; cpu = cpumask_next(cpu, &flow->cpu_used_mask)) if (flow->stats[cpu]) kmem_cache_free(flow_stats_cache, (struct flow_stats __force *)flow->stats[cpu]); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 008bb34ee3240495ecb0ed65bf55d5edd20e1186..bec01a3daf5b02bd716dbff5c9efef8d6a7982be 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -177,8 +177,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, #define BLK_PLUS_PRIV(sz_of_priv) \ (BLK_HDR_LEN + ALIGN((sz_of_priv), V3_ALIGNMENT)) -#define PGV_FROM_VMALLOC 1 - #define BLOCK_STATUS(x) ((x)->hdr.bh1.block_status) #define BLOCK_NUM_PKTS(x) ((x)->hdr.bh1.num_pkts) #define BLOCK_O2FP(x) ((x)->hdr.bh1.offset_to_first_pkt) @@ -1686,10 +1684,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) mutex_lock(&fanout_mutex); - err = -EINVAL; - if (!po->running) - goto out; - err = -EALREADY; if (po->fanout) goto out; @@ -1751,7 +1745,10 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) list_add(&match->list, &fanout_list); } err = -EINVAL; - if (match->type == type && + + spin_lock(&po->bind_lock); + if (po->running && + match->type == type && match->prot_hook.type == po->prot_hook.type && match->prot_hook.dev == po->prot_hook.dev) { err = -ENOSPC; @@ -1763,6 +1760,13 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) err = 0; } } + spin_unlock(&po->bind_lock); + + if (err && !refcount_read(&match->sk_ref)) { + list_del(&match->list); + kfree(match); + } + out: if (err && rollover) { kfree(rollover); @@ -2191,6 +2195,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct timespec ts; __u32 ts_status; bool is_drop_n_account = false; + bool do_vnet = false; /* struct tpacket{2,3}_hdr is aligned to a multiple of TPACKET_ALIGNMENT. * We may add members to them until current aligned size without forcing @@ -2241,8 +2246,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, netoff = TPACKET_ALIGN(po->tp_hdrlen + (maclen < 16 ? 16 : maclen)) + po->tp_reserve; - if (po->has_vnet_hdr) + if (po->has_vnet_hdr) { netoff += sizeof(struct virtio_net_hdr); + do_vnet = true; + } macoff = netoff - maclen; } if (po->tp_version <= TPACKET_V2) { @@ -2259,8 +2266,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, skb_set_owner_r(copy_skb, sk); } snaplen = po->rx_ring.frame_size - macoff; - if ((int)snaplen < 0) + if ((int)snaplen < 0) { snaplen = 0; + do_vnet = false; + } } } else if (unlikely(macoff + snaplen > GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len)) { @@ -2273,6 +2282,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, if (unlikely((int)snaplen < 0)) { snaplen = 0; macoff = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len; + do_vnet = false; } } spin_lock(&sk->sk_receive_queue.lock); @@ -2298,7 +2308,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, } spin_unlock(&sk->sk_receive_queue.lock); - if (po->has_vnet_hdr) { + if (do_vnet) { if (virtio_net_hdr_from_skb(skb, h.raw + macoff - sizeof(struct virtio_net_hdr), vio_le(), true)) { @@ -2830,6 +2840,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) struct virtio_net_hdr vnet_hdr = { 0 }; int offset = 0; struct packet_sock *po = pkt_sk(sk); + bool has_vnet_hdr = false; int hlen, tlen, linear; int extra_len = 0; @@ -2873,6 +2884,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) err = packet_snd_vnet_parse(msg, &len, &vnet_hdr); if (err) goto out_unlock; + has_vnet_hdr = true; } if (unlikely(sock_flag(sk, SOCK_NOFCS))) { @@ -2931,7 +2943,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) skb->priority = sk->sk_priority; skb->mark = sockc.mark; - if (po->has_vnet_hdr) { + if (has_vnet_hdr) { err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le()); if (err) goto out_free; @@ -3059,13 +3071,15 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, int ret = 0; bool unlisted = false; - if (po->fanout) - return -EINVAL; - lock_sock(sk); spin_lock(&po->bind_lock); rcu_read_lock(); + if (po->fanout) { + ret = -EINVAL; + goto out_unlock; + } + if (name) { dev = dev_get_by_name_rcu(sock_net(sk), name); if (!dev) { @@ -3700,14 +3714,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv if (optlen != sizeof(val)) return -EINVAL; - if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) - return -EBUSY; if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; if (val > INT_MAX) return -EINVAL; - po->tp_reserve = val; - return 0; + lock_sock(sk); + if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { + ret = -EBUSY; + } else { + po->tp_reserve = val; + ret = 0; + } + release_sock(sk); + return ret; } case PACKET_LOSS: { @@ -4329,7 +4348,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, register_prot_hook(sk); } spin_unlock(&po->bind_lock); - if (closing && (po->tp_version > TPACKET_V2)) { + if (pg_vec && (po->tp_version > TPACKET_V2)) { /* Because we don't support block-based V3 on tx-ring */ if (!tx_ring) prb_shutdown_retire_blk_timer(po, rb_queue); diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index 45b3af3080d8349f9e9c6e7f424f0548a79a42b0..da754fc926e72b11379216819d0608bd598d737d 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c @@ -300,15 +300,15 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb) int __init phonet_netlink_register(void) { int err = __rtnl_register(PF_PHONET, RTM_NEWADDR, addr_doit, - NULL, NULL); + NULL, 0); if (err) return err; /* Further __rtnl_register() cannot fail */ - __rtnl_register(PF_PHONET, RTM_DELADDR, addr_doit, NULL, NULL); - __rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit, NULL); - __rtnl_register(PF_PHONET, RTM_NEWROUTE, route_doit, NULL, NULL); - __rtnl_register(PF_PHONET, RTM_DELROUTE, route_doit, NULL, NULL); - __rtnl_register(PF_PHONET, RTM_GETROUTE, NULL, route_dumpit, NULL); + __rtnl_register(PF_PHONET, RTM_DELADDR, addr_doit, NULL, 0); + __rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit, 0); + __rtnl_register(PF_PHONET, RTM_NEWROUTE, route_doit, NULL, 0); + __rtnl_register(PF_PHONET, RTM_DELROUTE, route_doit, NULL, 0); + __rtnl_register(PF_PHONET, RTM_GETROUTE, NULL, route_dumpit, 0); return 0; } diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 5586609afa2728e7f138f4eed5e4818d43b1a0bb..c2f5c13550c052de0484582af9aabda3500cc030 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -1081,7 +1081,7 @@ static int __init qrtr_proto_init(void) return rc; } - rtnl_register(PF_QIPCRTR, RTM_NEWADDR, qrtr_addr_doit, NULL, NULL); + rtnl_register(PF_QIPCRTR, RTM_NEWADDR, qrtr_addr_doit, NULL, 0); return 0; } diff --git a/net/rds/bind.c b/net/rds/bind.c index 3a915bedb76c52995fdf5c09fa747f3a236a169b..75d43dc8e96b4655becce35dcaa5dd570abf4a41 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -40,7 +40,7 @@ static struct rhashtable bind_hash_table; -static struct rhashtable_params ht_parms = { +static const struct rhashtable_params ht_parms = { .nelem_hint = 768, .key_len = sizeof(u64), .key_offset = offsetof(struct rds_sock, rs_bound_key), diff --git a/net/rds/connection.c b/net/rds/connection.c index 50a3789ac23e4630e096fc4539e9fd8e99551a0e..7ee2d5d68b781684002f660b50705be9b150efdb 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -151,6 +151,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, struct rds_transport *loop_trans; unsigned long flags; int ret, i; + int npaths = (trans->t_mp_capable ? RDS_MPATH_WORKERS : 1); rcu_read_lock(); conn = rds_conn_lookup(net, head, laddr, faddr, trans); @@ -172,6 +173,12 @@ static struct rds_connection *__rds_conn_create(struct net *net, conn = ERR_PTR(-ENOMEM); goto out; } + conn->c_path = kcalloc(npaths, sizeof(struct rds_conn_path), gfp); + if (!conn->c_path) { + kmem_cache_free(rds_conn_slab, conn); + conn = ERR_PTR(-ENOMEM); + goto out; + } INIT_HLIST_NODE(&conn->c_hash_node); conn->c_laddr = laddr; @@ -181,6 +188,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, ret = rds_cong_get_maps(conn); if (ret) { + kfree(conn->c_path); kmem_cache_free(rds_conn_slab, conn); conn = ERR_PTR(ret); goto out; @@ -207,13 +215,14 @@ static struct rds_connection *__rds_conn_create(struct net *net, conn->c_trans = trans; init_waitqueue_head(&conn->c_hs_waitq); - for (i = 0; i < RDS_MPATH_WORKERS; i++) { + for (i = 0; i < npaths; i++) { __rds_conn_path_init(conn, &conn->c_path[i], is_outgoing); conn->c_path[i].cp_index = i; } ret = trans->conn_alloc(conn, gfp); if (ret) { + kfree(conn->c_path); kmem_cache_free(rds_conn_slab, conn); conn = ERR_PTR(ret); goto out; @@ -236,6 +245,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, /* Creating passive conn */ if (parent->c_passive) { trans->conn_free(conn->c_path[0].cp_transport_data); + kfree(conn->c_path); kmem_cache_free(rds_conn_slab, conn); conn = parent->c_passive; } else { @@ -252,7 +262,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, struct rds_conn_path *cp; int i; - for (i = 0; i < RDS_MPATH_WORKERS; i++) { + for (i = 0; i < npaths; i++) { cp = &conn->c_path[i]; /* The ->conn_alloc invocation may have * allocated resource for all paths, so all @@ -261,6 +271,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, if (cp->cp_transport_data) trans->conn_free(cp->cp_transport_data); } + kfree(conn->c_path); kmem_cache_free(rds_conn_slab, conn); conn = found; } else { @@ -374,13 +385,13 @@ static void rds_conn_path_destroy(struct rds_conn_path *cp) if (!cp->cp_transport_data) return; - rds_conn_path_drop(cp); - flush_work(&cp->cp_down_w); - /* make sure lingering queued work won't try to ref the conn */ cancel_delayed_work_sync(&cp->cp_send_w); cancel_delayed_work_sync(&cp->cp_recv_w); + rds_conn_path_drop(cp, true); + flush_work(&cp->cp_down_w); + /* tear down queued messages */ list_for_each_entry_safe(rm, rtmp, &cp->cp_send_queue, @@ -407,6 +418,7 @@ void rds_conn_destroy(struct rds_connection *conn) unsigned long flags; int i; struct rds_conn_path *cp; + int npaths = (conn->c_trans->t_mp_capable ? RDS_MPATH_WORKERS : 1); rdsdebug("freeing conn %p for %pI4 -> " "%pI4\n", conn, &conn->c_laddr, @@ -420,7 +432,7 @@ void rds_conn_destroy(struct rds_connection *conn) synchronize_rcu(); /* shut the connection down */ - for (i = 0; i < RDS_MPATH_WORKERS; i++) { + for (i = 0; i < npaths; i++) { cp = &conn->c_path[i]; rds_conn_path_destroy(cp); BUG_ON(!list_empty(&cp->cp_retrans)); @@ -434,6 +446,7 @@ void rds_conn_destroy(struct rds_connection *conn) rds_cong_remove_conn(conn); put_net(conn->c_net); + kfree(conn->c_path); kmem_cache_free(rds_conn_slab, conn); spin_lock_irqsave(&rds_conn_lock, flags); @@ -464,8 +477,12 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, i++, head++) { hlist_for_each_entry_rcu(conn, head, c_hash_node) { struct rds_conn_path *cp; + int npaths; + + npaths = (conn->c_trans->t_mp_capable ? + RDS_MPATH_WORKERS : 1); - for (j = 0; j < RDS_MPATH_WORKERS; j++) { + for (j = 0; j < npaths; j++) { cp = &conn->c_path[j]; if (want_send) list = &cp->cp_send_queue; @@ -486,8 +503,6 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, } spin_unlock_irqrestore(&cp->cp_lock, flags); - if (!conn->c_trans->t_mp_capable) - break; } } } @@ -571,15 +586,16 @@ static void rds_walk_conn_path_info(struct socket *sock, unsigned int len, i++, head++) { hlist_for_each_entry_rcu(conn, head, c_hash_node) { struct rds_conn_path *cp; + int npaths; - for (j = 0; j < RDS_MPATH_WORKERS; j++) { + npaths = (conn->c_trans->t_mp_capable ? + RDS_MPATH_WORKERS : 1); + for (j = 0; j < npaths; j++) { cp = &conn->c_path[j]; /* XXX no cp_lock usage.. */ if (!visitor(cp, buffer)) continue; - if (!conn->c_trans->t_mp_capable) - break; } /* We copy as much as we can fit in the buffer, @@ -664,9 +680,13 @@ void rds_conn_exit(void) /* * Force a disconnect */ -void rds_conn_path_drop(struct rds_conn_path *cp) +void rds_conn_path_drop(struct rds_conn_path *cp, bool destroy) { atomic_set(&cp->cp_state, RDS_CONN_ERROR); + + if (!destroy && cp->cp_conn->c_destroy_in_prog) + return; + queue_work(rds_wq, &cp->cp_down_w); } EXPORT_SYMBOL_GPL(rds_conn_path_drop); @@ -674,7 +694,7 @@ EXPORT_SYMBOL_GPL(rds_conn_path_drop); void rds_conn_drop(struct rds_connection *conn) { WARN_ON(conn->c_trans->t_mp_capable); - rds_conn_path_drop(&conn->c_path[0]); + rds_conn_path_drop(&conn->c_path[0], false); } EXPORT_SYMBOL_GPL(rds_conn_drop); @@ -706,5 +726,5 @@ __rds_conn_path_error(struct rds_conn_path *cp, const char *fmt, ...) vprintk(fmt, ap); va_end(ap); - rds_conn_path_drop(cp); + rds_conn_path_drop(cp, false); } diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index e10624aa6959b596a2629a9f18bb25504428545f..9722bf839d9dec7fc7c7bed5cca0818389b245ba 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -1015,8 +1015,10 @@ void rds_ib_recv_cqe_handler(struct rds_ib_connection *ic, if (rds_ib_ring_empty(&ic->i_recv_ring)) rds_ib_stats_inc(s_ib_rx_ring_empty); - if (rds_ib_ring_low(&ic->i_recv_ring)) + if (rds_ib_ring_low(&ic->i_recv_ring)) { rds_ib_recv_refill(conn, 0, GFP_NOWAIT); + rds_ib_stats_inc(s_ib_rx_refill_from_cq); + } } int rds_ib_recv_path(struct rds_conn_path *cp) @@ -1029,6 +1031,7 @@ int rds_ib_recv_path(struct rds_conn_path *cp) if (rds_conn_up(conn)) { rds_ib_attempt_ack(ic); rds_ib_recv_refill(conn, 0, GFP_KERNEL); + rds_ib_stats_inc(s_ib_rx_refill_from_thread); } return ret; diff --git a/net/rds/rds.h b/net/rds/rds.h index 516bcc89b46fdfd630dad78ad432a753e977f633..2e0315b159cb99b936d28665b4ae153f9bec2391 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -154,7 +154,7 @@ struct rds_connection { struct list_head c_map_item; unsigned long c_map_queued; - struct rds_conn_path c_path[RDS_MPATH_WORKERS]; + struct rds_conn_path *c_path; wait_queue_head_t c_hs_waitq; /* handshake waitq */ u32 c_my_gen_num; @@ -700,7 +700,7 @@ struct rds_connection *rds_conn_create_outgoing(struct net *net, void rds_conn_shutdown(struct rds_conn_path *cpath); void rds_conn_destroy(struct rds_connection *conn); void rds_conn_drop(struct rds_connection *conn); -void rds_conn_path_drop(struct rds_conn_path *cpath); +void rds_conn_path_drop(struct rds_conn_path *cpath, bool destroy); void rds_conn_connect_if_down(struct rds_connection *conn); void rds_conn_path_connect_if_down(struct rds_conn_path *cp); void rds_for_each_conn_info(struct socket *sock, unsigned int len, diff --git a/net/rds/send.c b/net/rds/send.c index 41b9f0f5bb9c7fac6f23efb8fe535dfa8b2f4530..b52cdc8ae428819a5853509a06852ec2ebc43a5a 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -273,7 +273,7 @@ int rds_send_xmit(struct rds_conn_path *cp) len = ntohl(rm->m_inc.i_hdr.h_len); if (cp->cp_unacked_packets == 0 || cp->cp_unacked_bytes < len) { - __set_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags); + set_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags); cp->cp_unacked_packets = rds_sysctl_max_unacked_packets; @@ -428,14 +428,18 @@ int rds_send_xmit(struct rds_conn_path *cp) * some work and we will skip our goto */ if (ret == 0) { + bool raced; + smp_mb(); + raced = send_gen != READ_ONCE(cp->cp_send_gen); + if ((test_bit(0, &conn->c_map_queued) || - !list_empty(&cp->cp_send_queue)) && - send_gen == READ_ONCE(cp->cp_send_gen)) { - rds_stats_inc(s_send_lock_queue_raced); + !list_empty(&cp->cp_send_queue)) && !raced) { if (batch_count < send_batch_count) goto restart; queue_delayed_work(rds_wq, &cp->cp_send_w, 1); + } else if (raced) { + rds_stats_inc(s_send_lock_queue_raced); } } out: @@ -829,7 +833,7 @@ static int rds_send_queue_rm(struct rds_sock *rs, struct rds_connection *conn, * throughput hits a certain threshold. */ if (rs->rs_snd_bytes >= rds_sk_sndbuf(rs) / 2) - __set_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags); + set_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags); list_add_tail(&rm->m_sock_item, &rs->rs_send_queue); set_bit(RDS_MSG_ON_SOCK, &rm->m_flags); diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 431404dbdad1cebe5d80cdb25de8b60db75fa87b..6b7ee71f40c63e879dc46d7bed025aac3def2c1f 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -592,7 +592,7 @@ static void rds_tcp_sysctl_reset(struct net *net) continue; /* reconnect with new parameters */ - rds_conn_path_drop(tc->t_cpath); + rds_conn_path_drop(tc->t_cpath, false); } spin_unlock_irq(&rds_tcp_conn_lock); } diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index cbe08a1fa4c71b93b0f81cd4a5782cd777c24b49..46f74dad0e164438594d9f195d906c9921bb8b23 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c @@ -69,14 +69,14 @@ void rds_tcp_state_change(struct sock *sk) if (!IS_CANONICAL(cp->cp_conn->c_laddr, cp->cp_conn->c_faddr) && rds_conn_path_transition(cp, RDS_CONN_CONNECTING, RDS_CONN_ERROR)) { - rds_conn_path_drop(cp); + rds_conn_path_drop(cp, false); } else { rds_connect_path_complete(cp, RDS_CONN_CONNECTING); } break; case TCP_CLOSE_WAIT: case TCP_CLOSE: - rds_conn_path_drop(cp); + rds_conn_path_drop(cp, false); default: break; } diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index 0d8616aa5bad00201cbda687fd836cfc59512116..dc860d1bb6088929591bb670ef96079de7c1819c 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -157,7 +157,7 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, "returned %d, " "disconnecting and reconnecting\n", &conn->c_faddr, cp->cp_index, ret); - rds_conn_path_drop(cp); + rds_conn_path_drop(cp, false); } } } diff --git a/net/rds/threads.c b/net/rds/threads.c index 2852bc1d37d452eba9745039bd389055446d78f0..f121daa402c81df6ea111da3d5bee6472629025f 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -78,7 +78,7 @@ void rds_connect_path_complete(struct rds_conn_path *cp, int curr) "current state is %d\n", __func__, atomic_read(&cp->cp_state)); - rds_conn_path_drop(cp); + rds_conn_path_drop(cp, false); return; } diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index a2ad4482376f30f7284329ee04904e4dcd114989..fb17552fd292ef5a67bff1c0da2a19e4ef06c6b8 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -336,6 +336,75 @@ void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call) } EXPORT_SYMBOL(rxrpc_kernel_end_call); +/** + * rxrpc_kernel_check_call - Check a call's state + * @sock: The socket the call is on + * @call: The call to check + * @_compl: Where to store the completion state + * @_abort_code: Where to store any abort code + * + * Allow a kernel service to query the state of a call and find out the manner + * of its termination if it has completed. Returns -EINPROGRESS if the call is + * still going, 0 if the call finished successfully, -ECONNABORTED if the call + * was aborted and an appropriate error if the call failed in some other way. + */ +int rxrpc_kernel_check_call(struct socket *sock, struct rxrpc_call *call, + enum rxrpc_call_completion *_compl, u32 *_abort_code) +{ + if (call->state != RXRPC_CALL_COMPLETE) + return -EINPROGRESS; + smp_rmb(); + *_compl = call->completion; + *_abort_code = call->abort_code; + return call->error; +} +EXPORT_SYMBOL(rxrpc_kernel_check_call); + +/** + * rxrpc_kernel_retry_call - Allow a kernel service to retry a call + * @sock: The socket the call is on + * @call: The call to retry + * @srx: The address of the peer to contact + * @key: The security context to use (defaults to socket setting) + * + * Allow a kernel service to try resending a client call that failed due to a + * network error to a new address. The Tx queue is maintained intact, thereby + * relieving the need to re-encrypt any request data that has already been + * buffered. + */ +int rxrpc_kernel_retry_call(struct socket *sock, struct rxrpc_call *call, + struct sockaddr_rxrpc *srx, struct key *key) +{ + struct rxrpc_conn_parameters cp; + struct rxrpc_sock *rx = rxrpc_sk(sock->sk); + int ret; + + _enter("%d{%d}", call->debug_id, atomic_read(&call->usage)); + + if (!key) + key = rx->key; + if (key && !key->payload.data[0]) + key = NULL; /* a no-security key */ + + memset(&cp, 0, sizeof(cp)); + cp.local = rx->local; + cp.key = key; + cp.security_level = 0; + cp.exclusive = false; + cp.service_id = srx->srx_service; + + mutex_lock(&call->user_mutex); + + ret = rxrpc_prepare_call_for_retry(rx, call); + if (ret == 0) + ret = rxrpc_retry_client_call(rx, call, &cp, srx, GFP_KERNEL); + + mutex_unlock(&call->user_mutex); + _leave(" = %d", ret); + return ret; +} +EXPORT_SYMBOL(rxrpc_kernel_retry_call); + /** * rxrpc_kernel_new_call_notification - Get notifications of new calls * @sock: The socket to intercept received messages on @@ -591,13 +660,13 @@ static int rxrpc_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *_optlen) { int optlen; - + if (level != SOL_RXRPC) return -EOPNOTSUPP; if (get_user(optlen, _optlen)) return -EFAULT; - + switch (optname) { case RXRPC_SUPPORTED_CMSG: if (optlen < sizeof(int)) @@ -606,7 +675,7 @@ static int rxrpc_getsockopt(struct socket *sock, int level, int optname, put_user(sizeof(int), _optlen)) return -EFAULT; return 0; - + default: return -EOPNOTSUPP; } diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 69b97339ff9da594a578e14437afbbaf471029c3..ea5600b747ccd2f8d16f9466711de4bbf22ce125 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include "protocol.h" #if 0 #define CHECK_SLAB_OKAY(X) \ @@ -445,6 +445,7 @@ enum rxrpc_call_flag { RXRPC_CALL_EXPOSED, /* The call was exposed to the world */ RXRPC_CALL_RX_LAST, /* Received the last packet (at rxtx_top) */ RXRPC_CALL_TX_LAST, /* Last packet in Tx buffer (at rxtx_top) */ + RXRPC_CALL_TX_LASTQ, /* Last packet has been queued */ RXRPC_CALL_SEND_PING, /* A ping will need to be sent */ RXRPC_CALL_PINGING, /* Ping in process */ RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ @@ -481,18 +482,6 @@ enum rxrpc_call_state { NR__RXRPC_CALL_STATES }; -/* - * Call completion condition (state == RXRPC_CALL_COMPLETE). - */ -enum rxrpc_call_completion { - RXRPC_CALL_SUCCEEDED, /* - Normal termination */ - RXRPC_CALL_REMOTELY_ABORTED, /* - call aborted by peer */ - RXRPC_CALL_LOCALLY_ABORTED, /* - call aborted locally on error or close */ - RXRPC_CALL_LOCAL_ERROR, /* - call failed due to local error */ - RXRPC_CALL_NETWORK_ERROR, /* - call terminated by network error */ - NR__RXRPC_CALL_COMPLETIONS -}; - /* * Call Tx congestion management modes. */ @@ -687,9 +676,15 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *, struct rxrpc_conn_parameters *, struct sockaddr_rxrpc *, unsigned long, s64, gfp_t); +int rxrpc_retry_client_call(struct rxrpc_sock *, + struct rxrpc_call *, + struct rxrpc_conn_parameters *, + struct sockaddr_rxrpc *, + gfp_t); void rxrpc_incoming_call(struct rxrpc_sock *, struct rxrpc_call *, struct sk_buff *); void rxrpc_release_call(struct rxrpc_sock *, struct rxrpc_call *); +int rxrpc_prepare_call_for_retry(struct rxrpc_sock *, struct rxrpc_call *); void rxrpc_release_calls_on_socket(struct rxrpc_sock *); bool __rxrpc_queue_call(struct rxrpc_call *); bool rxrpc_queue_call(struct rxrpc_call *); @@ -830,7 +825,6 @@ void rxrpc_process_connection(struct work_struct *); */ extern unsigned int rxrpc_connection_expiry; -int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); struct rxrpc_connection *rxrpc_alloc_connection(gfp_t); struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *, struct sk_buff *); @@ -894,7 +888,7 @@ extern struct key_type key_type_rxrpc_s; int rxrpc_request_key(struct rxrpc_sock *, char __user *, int); int rxrpc_server_keyring(struct rxrpc_sock *, char __user *, int); -int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time_t, +int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time64_t, u32); /* @@ -1060,7 +1054,8 @@ static inline void rxrpc_sysctl_exit(void) {} /* * utils.c */ -int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *); +int rxrpc_extract_addr_from_skb(struct rxrpc_local *, struct sockaddr_rxrpc *, + struct sk_buff *); static inline bool before(u32 seq1, u32 seq2) { diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index dd30d74824b0de42d1866f4449300f89c83d6724..cbd1701e813a76864da2f4cc294476cce008d878 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -223,6 +223,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx) tail = b->call_backlog_tail; while (CIRC_CNT(head, tail, size) > 0) { struct rxrpc_call *call = b->call_backlog[tail]; + call->socket = rx; if (rx->discard_new_call) { _debug("discard %lx", call->user_call_ID); rx->discard_new_call(call, call->user_call_ID); @@ -276,7 +277,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx, * anticipation - and to save on stack space. */ xpeer = b->peer_backlog[peer_tail]; - if (rxrpc_extract_addr_from_skb(&xpeer->srx, skb) < 0) + if (rxrpc_extract_addr_from_skb(local, &xpeer->srx, skb) < 0) return NULL; peer = rxrpc_lookup_incoming_peer(local, xpeer); diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index d7809a0620b4e19acd511d2bd5233e88bf2ba0b3..fcdd6555a820ed224ca01a32930ba04d0f6b58e5 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -269,11 +269,6 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage), here, NULL); - spin_lock_bh(&call->conn->params.peer->lock); - hlist_add_head(&call->error_link, - &call->conn->params.peer->error_targets); - spin_unlock_bh(&call->conn->params.peer->lock); - rxrpc_start_call_timer(call); _net("CALL new %d on CONN %d", call->debug_id, call->conn->debug_id); @@ -303,6 +298,48 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, return ERR_PTR(ret); } +/* + * Retry a call to a new address. It is expected that the Tx queue of the call + * will contain data previously packaged for an old call. + */ +int rxrpc_retry_client_call(struct rxrpc_sock *rx, + struct rxrpc_call *call, + struct rxrpc_conn_parameters *cp, + struct sockaddr_rxrpc *srx, + gfp_t gfp) +{ + const void *here = __builtin_return_address(0); + int ret; + + /* Set up or get a connection record and set the protocol parameters, + * including channel number and call ID. + */ + ret = rxrpc_connect_call(call, cp, srx, gfp); + if (ret < 0) + goto error; + + trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage), + here, NULL); + + rxrpc_start_call_timer(call); + + _net("CALL new %d on CONN %d", call->debug_id, call->conn->debug_id); + + if (!test_and_set_bit(RXRPC_CALL_EV_RESEND, &call->events)) + rxrpc_queue_call(call); + + _leave(" = 0"); + return 0; + +error: + rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, + RX_CALL_DEAD, ret); + trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage), + here, ERR_PTR(ret)); + _leave(" = %d", ret); + return ret; +} + /* * Set up an incoming call. call->conn points to the connection. * This is called in BH context and isn't allowed to fail. @@ -470,6 +507,61 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call) _leave(""); } +/* + * Prepare a kernel service call for retry. + */ +int rxrpc_prepare_call_for_retry(struct rxrpc_sock *rx, struct rxrpc_call *call) +{ + const void *here = __builtin_return_address(0); + int i; + u8 last = 0; + + _enter("{%d,%d}", call->debug_id, atomic_read(&call->usage)); + + trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage), + here, (const void *)call->flags); + + ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); + ASSERTCMP(call->completion, !=, RXRPC_CALL_REMOTELY_ABORTED); + ASSERTCMP(call->completion, !=, RXRPC_CALL_LOCALLY_ABORTED); + ASSERT(list_empty(&call->recvmsg_link)); + + del_timer_sync(&call->timer); + + _debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, call->conn); + + if (call->conn) + rxrpc_disconnect_call(call); + + if (rxrpc_is_service_call(call) || + !call->tx_phase || + call->tx_hard_ack != 0 || + call->rx_hard_ack != 0 || + call->rx_top != 0) + return -EINVAL; + + call->state = RXRPC_CALL_UNINITIALISED; + call->completion = RXRPC_CALL_SUCCEEDED; + call->call_id = 0; + call->cid = 0; + call->cong_cwnd = 0; + call->cong_extra = 0; + call->cong_ssthresh = 0; + call->cong_mode = 0; + call->cong_dup_acks = 0; + call->cong_cumul_acks = 0; + call->acks_lowest_nak = 0; + + for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) { + last |= call->rxtx_annotations[i]; + call->rxtx_annotations[i] &= RXRPC_TX_ANNO_LAST; + call->rxtx_annotations[i] |= RXRPC_TX_ANNO_RETRANS; + } + + _leave(" = 0"); + return 0; +} + /* * release all the calls associated with a socket */ diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c index eb21576803997b572902b9eaa2086327873ad778..5f9624bd311c6882bc6f751b393b4904222f5667 100644 --- a/net/rxrpc/conn_client.c +++ b/net/rxrpc/conn_client.c @@ -555,7 +555,10 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn, trace_rxrpc_client(conn, channel, rxrpc_client_chan_activate); write_lock_bh(&call->state_lock); - call->state = RXRPC_CALL_CLIENT_SEND_REQUEST; + if (!test_bit(RXRPC_CALL_TX_LASTQ, &call->flags)) + call->state = RXRPC_CALL_CLIENT_SEND_REQUEST; + else + call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY; write_unlock_bh(&call->state_lock); rxrpc_see_call(call); @@ -688,15 +691,23 @@ int rxrpc_connect_call(struct rxrpc_call *call, ret = rxrpc_get_client_conn(call, cp, srx, gfp); if (ret < 0) - return ret; + goto out; rxrpc_animate_client_conn(rxnet, call->conn); rxrpc_activate_channels(call->conn); ret = rxrpc_wait_for_channel(call, gfp); - if (ret < 0) + if (ret < 0) { rxrpc_disconnect_client_call(call); + goto out; + } + + spin_lock_bh(&call->conn->params.peer->lock); + hlist_add_head(&call->error_link, + &call->conn->params.peer->error_targets); + spin_unlock_bh(&call->conn->params.peer->lock); +out: _leave(" = %d", ret); return ret; } diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index 929b50d5afe843fd6e9e5822b483fd4e451c8013..fe575798592fec5945148694b54de90a3d78c3f6 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c @@ -72,7 +72,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local, _enter(",%x", sp->hdr.cid & RXRPC_CIDMASK); - if (rxrpc_extract_addr_from_skb(&srx, skb) < 0) + if (rxrpc_extract_addr_from_skb(local, &srx, skb) < 0) goto not_found; k.epoch = sp->hdr.epoch; diff --git a/net/rxrpc/conn_service.c b/net/rxrpc/conn_service.c index e60fcd2a4a021b2b242b2afe831e41ae99ebafae..f6fcdb3130a19a9bcb74b2d7dd5af7886ed8912d 100644 --- a/net/rxrpc/conn_service.c +++ b/net/rxrpc/conn_service.c @@ -50,12 +50,11 @@ struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *peer, else if (conn->proto.index_key > k.index_key) p = rcu_dereference_raw(p->rb_right); else - goto done; + break; conn = NULL; } } while (need_seqretry(&peer->service_conn_lock, seq)); -done: done_seqretry(&peer->service_conn_lock, seq); _leave(" = %d", conn ? conn->debug_id : -1); return conn; diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c index 54369225766ef8e43ff94f21b4fd670b2cc233a3..e7f6b8823eb6e6c6794ed78e1197c1cf8aab4858 100644 --- a/net/rxrpc/key.c +++ b/net/rxrpc/key.c @@ -92,6 +92,7 @@ static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep, const __be32 *xdr, unsigned int toklen) { struct rxrpc_key_token *token, **pptoken; + time64_t expiry; size_t plen; u32 tktlen; @@ -158,8 +159,9 @@ static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep, pptoken = &(*pptoken)->next) continue; *pptoken = token; - if (token->kad->expiry < prep->expiry) - prep->expiry = token->kad->expiry; + expiry = rxrpc_u32_to_time64(token->kad->expiry); + if (expiry < prep->expiry) + prep->expiry = expiry; _leave(" = 0"); return 0; @@ -433,6 +435,7 @@ static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep, struct rxrpc_key_token *token, **pptoken; struct rxk5_key *rxk5; const __be32 *end_xdr = xdr + (toklen >> 2); + time64_t expiry; int ret; _enter(",{%x,%x,%x,%x},%u", @@ -533,8 +536,9 @@ static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep, pptoken = &(*pptoken)->next) continue; *pptoken = token; - if (token->kad->expiry < prep->expiry) - prep->expiry = token->kad->expiry; + expiry = rxrpc_u32_to_time64(token->k5->endtime); + if (expiry < prep->expiry) + prep->expiry = expiry; _leave(" = 0"); return 0; @@ -691,6 +695,7 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep) { const struct rxrpc_key_data_v1 *v1; struct rxrpc_key_token *token, **pp; + time64_t expiry; size_t plen; u32 kver; int ret; @@ -777,8 +782,9 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep) while (*pp) pp = &(*pp)->next; *pp = token; - if (token->kad->expiry < prep->expiry) - prep->expiry = token->kad->expiry; + expiry = rxrpc_u32_to_time64(token->kad->expiry); + if (expiry < prep->expiry) + prep->expiry = expiry; token = NULL; ret = 0; @@ -955,7 +961,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval, */ int rxrpc_get_server_data_key(struct rxrpc_connection *conn, const void *session_key, - time_t expiry, + time64_t expiry, u32 kvno) { const struct cred *cred = current_cred(); @@ -982,7 +988,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn, data.kver = 1; data.v1.security_index = RXRPC_SECURITY_RXKAD; data.v1.ticket_length = 0; - data.v1.expiry = expiry; + data.v1.expiry = rxrpc_time64_to_u32(expiry); data.v1.kvno = 0; memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); diff --git a/net/rxrpc/local_event.c b/net/rxrpc/local_event.c index 540d3955c1bcc11652879c7e80630978513cc16e..93b5d910b4a130a8f2641f1a20f0d2e83b60ed56 100644 --- a/net/rxrpc/local_event.c +++ b/net/rxrpc/local_event.c @@ -39,7 +39,7 @@ static void rxrpc_send_version_request(struct rxrpc_local *local, _enter(""); - if (rxrpc_extract_addr_from_skb(&srx, skb) < 0) + if (rxrpc_extract_addr_from_skb(local, &srx, skb) < 0) return; msg.msg_name = &srx.transport; diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index 5bd2d0fa4a039235d179cb41bf7ee25aef13b594..71e6f713fbe79044d5dd35e7601bc6b6da70dba3 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c @@ -444,7 +444,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local) rxrpc_see_skb(skb, rxrpc_skb_rx_seen); sp = rxrpc_skb(skb); - if (rxrpc_extract_addr_from_skb(&srx, skb) == 0) { + if (rxrpc_extract_addr_from_skb(local, &srx, skb) == 0) { msg.msg_namelen = srx.transport_len; code = htonl(skb->priority); diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c index 1ed9c0c2e94f1c70ab0ca61fa16e87f76530f78a..7f749505e699a0ac5d8e04f832f21629643a55d0 100644 --- a/net/rxrpc/peer_event.c +++ b/net/rxrpc/peer_event.c @@ -37,6 +37,7 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, memset(&srx, 0, sizeof(srx)); srx.transport_type = local->srx.transport_type; + srx.transport_len = local->srx.transport_len; srx.transport.family = local->srx.transport.family; /* Can we see an ICMP4 packet on an ICMP6 listening socket? and vice @@ -45,7 +46,6 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, switch (srx.transport.family) { case AF_INET: srx.transport.sin.sin_port = serr->port; - srx.transport_len = sizeof(struct sockaddr_in); switch (serr->ee.ee_origin) { case SO_EE_ORIGIN_ICMP: _net("Rx ICMP"); @@ -69,7 +69,6 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, #ifdef CONFIG_AF_RXRPC_IPV6 case AF_INET6: srx.transport.sin6.sin6_port = serr->port; - srx.transport_len = sizeof(struct sockaddr_in6); switch (serr->ee.ee_origin) { case SO_EE_ORIGIN_ICMP6: _net("Rx ICMP6"); @@ -79,6 +78,9 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local, break; case SO_EE_ORIGIN_ICMP: _net("Rx ICMP on v6 sock"); + srx.transport.sin6.sin6_addr.s6_addr32[0] = 0; + srx.transport.sin6.sin6_addr.s6_addr32[1] = 0; + srx.transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); memcpy(srx.transport.sin6.sin6_addr.s6_addr + 12, skb_network_header(skb) + serr->addr_offset, sizeof(struct in_addr)); diff --git a/include/rxrpc/packet.h b/net/rxrpc/protocol.h similarity index 78% rename from include/rxrpc/packet.h rename to net/rxrpc/protocol.h index a2dcfb850b9fd4687318d5a048790ac2c62dcf2c..4bddcf3face3342b69d9aa6402da638b0687d37c 100644 --- a/include/rxrpc/packet.h +++ b/net/rxrpc/protocol.h @@ -187,49 +187,4 @@ struct rxkad_response { __be32 ticket_len; /* Kerberos ticket length */ } __packed; -/*****************************************************************************/ -/* - * RxRPC-level abort codes - */ -#define RX_CALL_DEAD -1 /* call/conn has been inactive and is shut down */ -#define RX_INVALID_OPERATION -2 /* invalid operation requested / attempted */ -#define RX_CALL_TIMEOUT -3 /* call timeout exceeded */ -#define RX_EOF -4 /* unexpected end of data on read op */ -#define RX_PROTOCOL_ERROR -5 /* low-level protocol error */ -#define RX_USER_ABORT -6 /* generic user abort */ -#define RX_ADDRINUSE -7 /* UDP port in use */ -#define RX_DEBUGI_BADTYPE -8 /* bad debugging packet type */ - -/* - * (un)marshalling abort codes (rxgen) - */ -#define RXGEN_CC_MARSHAL -450 -#define RXGEN_CC_UNMARSHAL -451 -#define RXGEN_SS_MARSHAL -452 -#define RXGEN_SS_UNMARSHAL -453 -#define RXGEN_DECODE -454 -#define RXGEN_OPCODE -455 -#define RXGEN_SS_XDRFREE -456 -#define RXGEN_CC_XDRFREE -457 - -/* - * Rx kerberos security abort codes - * - unfortunately we have no generalised security abort codes to say things - * like "unsupported security", so we have to use these instead and hope the - * other side understands - */ -#define RXKADINCONSISTENCY 19270400 /* security module structure inconsistent */ -#define RXKADPACKETSHORT 19270401 /* packet too short for security challenge */ -#define RXKADLEVELFAIL 19270402 /* security level negotiation failed */ -#define RXKADTICKETLEN 19270403 /* ticket length too short or too long */ -#define RXKADOUTOFSEQUENCE 19270404 /* packet had bad sequence number */ -#define RXKADNOAUTH 19270405 /* caller not authorised */ -#define RXKADBADKEY 19270406 /* illegal key: bad parity or weak */ -#define RXKADBADTICKET 19270407 /* security object was passed a bad ticket */ -#define RXKADUNKNOWNKEY 19270408 /* ticket contained unknown key version number */ -#define RXKADEXPIRED 19270409 /* authentication expired */ -#define RXKADSEALEDINCON 19270410 /* sealed data inconsistent */ -#define RXKADDATALEN 19270411 /* user data too long */ -#define RXKADILLEGALLEVEL 19270412 /* caller not authorised to use encrypted conns */ - #endif /* _LINUX_RXRPC_PACKET_H */ diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index 46d1a1f0b55b1c620451db900c16b0ef5fc3c013..c38b3a1de56c136f3e99096151635c226c5e02df 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -634,8 +634,8 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn) challenge.min_level = htonl(0); challenge.__padding = 0; - msg.msg_name = &conn->params.peer->srx.transport.sin; - msg.msg_namelen = sizeof(conn->params.peer->srx.transport.sin); + msg.msg_name = &conn->params.peer->srx.transport; + msg.msg_namelen = conn->params.peer->srx.transport_len; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; @@ -689,8 +689,8 @@ static int rxkad_send_response(struct rxrpc_connection *conn, _enter(""); - msg.msg_name = &conn->params.peer->srx.transport.sin; - msg.msg_namelen = sizeof(conn->params.peer->srx.transport.sin); + msg.msg_name = &conn->params.peer->srx.transport; + msg.msg_namelen = conn->params.peer->srx.transport_len; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; @@ -854,7 +854,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, struct sk_buff *skb, void *ticket, size_t ticket_len, struct rxrpc_crypt *_session_key, - time_t *_expiry, + time64_t *_expiry, u32 *_abort_code) { struct skcipher_request *req; @@ -864,7 +864,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, struct in_addr addr; unsigned int life; const char *eproto; - time_t issue, now; + time64_t issue, now; bool little_endian; int ret; u32 abort_code; @@ -960,15 +960,15 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, if (little_endian) { __le32 stamp; memcpy(&stamp, p, 4); - issue = le32_to_cpu(stamp); + issue = rxrpc_u32_to_time64(le32_to_cpu(stamp)); } else { __be32 stamp; memcpy(&stamp, p, 4); - issue = be32_to_cpu(stamp); + issue = rxrpc_u32_to_time64(be32_to_cpu(stamp)); } p += 4; - now = get_seconds(); - _debug("KIV ISSUE: %lx [%lx]", issue, now); + now = ktime_get_real_seconds(); + _debug("KIV ISSUE: %llx [%llx]", issue, now); /* check the ticket is in date */ if (issue > now) { @@ -1053,7 +1053,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn, struct rxrpc_skb_priv *sp = rxrpc_skb(skb); struct rxrpc_crypt session_key; const char *eproto; - time_t expiry; + time64_t expiry; void *ticket; u32 abort_code, version, kvno, ticket_len, level; __be32 csum; diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index b0d2cda6ec0ad802edab7a4ef22a79b80e53a204..9ea6f972767e7c902c4fbc04a1390905800f3ad6 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -61,7 +61,7 @@ static int rxrpc_wait_for_tx_window(struct rxrpc_sock *rx, call->cong_cwnd + call->cong_extra)) break; if (call->state >= RXRPC_CALL_COMPLETE) { - ret = -call->error; + ret = call->error; break; } if (signal_pending(current)) { @@ -100,12 +100,24 @@ static inline void rxrpc_instant_resend(struct rxrpc_call *call, int ix) spin_unlock_bh(&call->lock); } +/* + * Notify the owner of the call that the transmit phase is ended and the last + * packet has been queued. + */ +static void rxrpc_notify_end_tx(struct rxrpc_sock *rx, struct rxrpc_call *call, + rxrpc_notify_end_tx_t notify_end_tx) +{ + if (notify_end_tx) + notify_end_tx(&rx->sk, call, call->user_call_ID); +} + /* * Queue a DATA packet for transmission, set the resend timeout and send the * packet immediately */ -static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb, - bool last) +static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, + struct sk_buff *skb, bool last, + rxrpc_notify_end_tx_t notify_end_tx) { struct rxrpc_skb_priv *sp = rxrpc_skb(skb); rxrpc_seq_t seq = sp->hdr.seq; @@ -116,8 +128,10 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb, ASSERTCMP(seq, ==, call->tx_top + 1); - if (last) + if (last) { annotation |= RXRPC_TX_ANNO_LAST; + set_bit(RXRPC_CALL_TX_LASTQ, &call->flags); + } /* We have to set the timestamp before queueing as the retransmit * algorithm can see the packet as soon as we queue it. @@ -141,6 +155,7 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb, switch (call->state) { case RXRPC_CALL_CLIENT_SEND_REQUEST: call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY; + rxrpc_notify_end_tx(rx, call, notify_end_tx); break; case RXRPC_CALL_SERVER_ACK_REQUEST: call->state = RXRPC_CALL_SERVER_SEND_REPLY; @@ -153,6 +168,7 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb, break; case RXRPC_CALL_SERVER_SEND_REPLY: call->state = RXRPC_CALL_SERVER_AWAIT_ACK; + rxrpc_notify_end_tx(rx, call, notify_end_tx); break; default: break; @@ -189,7 +205,8 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb, */ static int rxrpc_send_data(struct rxrpc_sock *rx, struct rxrpc_call *call, - struct msghdr *msg, size_t len) + struct msghdr *msg, size_t len, + rxrpc_notify_end_tx_t notify_end_tx) { struct rxrpc_skb_priv *sp; struct sk_buff *skb; @@ -311,11 +328,6 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, call->tx_total_len -= copy; } - /* check for the far side aborting the call or a network error - * occurring */ - if (call->state == RXRPC_CALL_COMPLETE) - goto call_terminated; - /* add the packet to the send queue if it's now full */ if (sp->remain <= 0 || (msg_data_left(msg) == 0 && !more)) { @@ -350,9 +362,21 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, if (ret < 0) goto out; - rxrpc_queue_packet(call, skb, !msg_data_left(msg) && !more); + rxrpc_queue_packet(rx, call, skb, + !msg_data_left(msg) && !more, + notify_end_tx); skb = NULL; } + + /* Check for the far side aborting the call or a network error + * occurring. If this happens, save any packet that was under + * construction so that in the case of a network error, the + * call can be retried or redirected. + */ + if (call->state == RXRPC_CALL_COMPLETE) { + ret = call->error; + goto out; + } } while (msg_data_left(msg) > 0); success: @@ -362,11 +386,6 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, _leave(" = %d", ret); return ret; -call_terminated: - rxrpc_free_skb(skb, rxrpc_skb_tx_freed); - _leave(" = %d", -call->error); - return -call->error; - maybe_error: if (copied) goto success; @@ -611,7 +630,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) /* Reply phase not begun or not complete for service call. */ ret = -EPROTO; } else { - ret = rxrpc_send_data(rx, call, msg, len); + ret = rxrpc_send_data(rx, call, msg, len, NULL); } mutex_unlock(&call->user_mutex); @@ -631,6 +650,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) * @call: The call to send data through * @msg: The data to send * @len: The amount of data to send + * @notify_end_tx: Notification that the last packet is queued. * * Allow a kernel service to send data on a call. The call must be in an state * appropriate to sending data. No control data should be supplied in @msg, @@ -638,7 +658,8 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) * more data to come, otherwise this data will end the transmission phase. */ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, - struct msghdr *msg, size_t len) + struct msghdr *msg, size_t len, + rxrpc_notify_end_tx_t notify_end_tx) { int ret; @@ -656,11 +677,12 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, case RXRPC_CALL_CLIENT_SEND_REQUEST: case RXRPC_CALL_SERVER_ACK_REQUEST: case RXRPC_CALL_SERVER_SEND_REPLY: - ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len); + ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len, + notify_end_tx); break; case RXRPC_CALL_COMPLETE: read_lock_bh(&call->state_lock); - ret = -call->error; + ret = call->error; read_unlock_bh(&call->state_lock); break; default: diff --git a/net/rxrpc/utils.c b/net/rxrpc/utils.c index ff7af71c4b49815b9406061c02ad453275df026c..e801171fa351410025addaf0519b5c3844ea5b4f 100644 --- a/net/rxrpc/utils.c +++ b/net/rxrpc/utils.c @@ -17,17 +17,28 @@ /* * Fill out a peer address from a socket buffer containing a packet. */ -int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb) +int rxrpc_extract_addr_from_skb(struct rxrpc_local *local, + struct sockaddr_rxrpc *srx, + struct sk_buff *skb) { memset(srx, 0, sizeof(*srx)); switch (ntohs(skb->protocol)) { case ETH_P_IP: - srx->transport_type = SOCK_DGRAM; - srx->transport_len = sizeof(srx->transport.sin); - srx->transport.sin.sin_family = AF_INET; - srx->transport.sin.sin_port = udp_hdr(skb)->source; - srx->transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr; + if (local->srx.transport.family == AF_INET6) { + srx->transport_type = SOCK_DGRAM; + srx->transport_len = sizeof(srx->transport.sin6); + srx->transport.sin6.sin6_family = AF_INET6; + srx->transport.sin6.sin6_port = udp_hdr(skb)->source; + srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); + srx->transport.sin6.sin6_addr.s6_addr32[3] = ip_hdr(skb)->saddr; + } else { + srx->transport_type = SOCK_DGRAM; + srx->transport_len = sizeof(srx->transport.sin); + srx->transport.sin.sin_family = AF_INET; + srx->transport.sin.sin_port = udp_hdr(skb)->source; + srx->transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr; + } return 0; #ifdef CONFIG_AF_RXRPC_IPV6 diff --git a/net/sched/act_api.c b/net/sched/act_api.c index f2e9ed34a963e1a06dbefb792836919d92bf6733..da6fa82c98a8b7fb0d4e94cdfcaa0198e6972d90 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -53,10 +53,13 @@ static void tcf_action_goto_chain_exec(const struct tc_action *a, res->goto_tp = rcu_dereference_bh(chain->filter_chain); } -static void free_tcf(struct rcu_head *head) +/* XXX: For standalone actions, we don't need a RCU grace period either, because + * actions are always connected to filters and filters are already destroyed in + * RCU callbacks, so after a RCU grace period actions are already disconnected + * from filters. Readers later can not find us. + */ +static void free_tcf(struct tc_action *p) { - struct tc_action *p = container_of(head, struct tc_action, tcfa_rcu); - free_percpu(p->cpu_bstats); free_percpu(p->cpu_qstats); @@ -70,20 +73,16 @@ static void free_tcf(struct rcu_head *head) kfree(p); } -static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *p) +static void tcf_idr_remove(struct tcf_idrinfo *idrinfo, struct tc_action *p) { - spin_lock_bh(&hinfo->lock); - hlist_del(&p->tcfa_head); - spin_unlock_bh(&hinfo->lock); + spin_lock_bh(&idrinfo->lock); + idr_remove_ext(&idrinfo->action_idr, p->tcfa_index); + spin_unlock_bh(&idrinfo->lock); gen_kill_estimator(&p->tcfa_rate_est); - /* - * gen_estimator est_timer() might access p->tcfa_lock - * or bstats, wait a RCU grace period before freeing p - */ - call_rcu(&p->tcfa_rcu, free_tcf); + free_tcf(p); } -int __tcf_hash_release(struct tc_action *p, bool bind, bool strict) +int __tcf_idr_release(struct tc_action *p, bool bind, bool strict) { int ret = 0; @@ -97,55 +96,64 @@ int __tcf_hash_release(struct tc_action *p, bool bind, bool strict) if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) { if (p->ops->cleanup) p->ops->cleanup(p, bind); - tcf_hash_destroy(p->hinfo, p); + tcf_idr_remove(p->idrinfo, p); ret = ACT_P_DELETED; } } return ret; } -EXPORT_SYMBOL(__tcf_hash_release); +EXPORT_SYMBOL(__tcf_idr_release); -static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, +static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb, struct netlink_callback *cb) { - int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; + int err = 0, index = -1, s_i = 0, n_i = 0; + u32 act_flags = cb->args[2]; + unsigned long jiffy_since = cb->args[3]; struct nlattr *nest; + struct idr *idr = &idrinfo->action_idr; + struct tc_action *p; + unsigned long id = 1; - spin_lock_bh(&hinfo->lock); + spin_lock_bh(&idrinfo->lock); s_i = cb->args[0]; - for (i = 0; i < (hinfo->hmask + 1); i++) { - struct hlist_head *head; - struct tc_action *p; - - head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; - - hlist_for_each_entry_rcu(p, head, tcfa_head) { - index++; - if (index < s_i) - continue; - - nest = nla_nest_start(skb, n_i); - if (nest == NULL) - goto nla_put_failure; - err = tcf_action_dump_1(skb, p, 0, 0); - if (err < 0) { - index--; - nlmsg_trim(skb, nest); - goto done; - } - nla_nest_end(skb, nest); - n_i++; - if (n_i >= TCA_ACT_MAX_PRIO) - goto done; + idr_for_each_entry_ext(idr, p, id) { + index++; + if (index < s_i) + continue; + + if (jiffy_since && + time_after(jiffy_since, + (unsigned long)p->tcfa_tm.lastuse)) + continue; + + nest = nla_nest_start(skb, n_i); + if (!nest) + goto nla_put_failure; + err = tcf_action_dump_1(skb, p, 0, 0); + if (err < 0) { + index--; + nlmsg_trim(skb, nest); + goto done; } + nla_nest_end(skb, nest); + n_i++; + if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) && + n_i >= TCA_ACT_MAX_PRIO) + goto done; } done: - spin_unlock_bh(&hinfo->lock); - if (n_i) - cb->args[0] += n_i; + if (index >= 0) + cb->args[0] = index + 1; + + spin_unlock_bh(&idrinfo->lock); + if (n_i) { + if (act_flags & TCA_FLAG_LARGE_DUMP_ON) + cb->args[1] = n_i; + } return n_i; nla_put_failure: @@ -153,31 +161,29 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, goto done; } -static int tcf_del_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb, +static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb, const struct tc_action_ops *ops) { struct nlattr *nest; - int i = 0, n_i = 0; + int n_i = 0; int ret = -EINVAL; + struct idr *idr = &idrinfo->action_idr; + struct tc_action *p; + unsigned long id = 1; nest = nla_nest_start(skb, 0); if (nest == NULL) goto nla_put_failure; if (nla_put_string(skb, TCA_KIND, ops->kind)) goto nla_put_failure; - for (i = 0; i < (hinfo->hmask + 1); i++) { - struct hlist_head *head; - struct hlist_node *n; - struct tc_action *p; - - head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; - hlist_for_each_entry_safe(p, n, head, tcfa_head) { - ret = __tcf_hash_release(p, false, true); - if (ret == ACT_P_DELETED) { - module_put(p->ops->owner); - n_i++; - } else if (ret < 0) - goto nla_put_failure; + + idr_for_each_entry_ext(idr, p, id) { + ret = __tcf_idr_release(p, false, true); + if (ret == ACT_P_DELETED) { + module_put(ops->owner); + n_i++; + } else if (ret < 0) { + goto nla_put_failure; } } if (nla_put_u32(skb, TCA_FCNT, n_i)) @@ -194,12 +200,12 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, struct netlink_callback *cb, int type, const struct tc_action_ops *ops) { - struct tcf_hashinfo *hinfo = tn->hinfo; + struct tcf_idrinfo *idrinfo = tn->idrinfo; if (type == RTM_DELACTION) { - return tcf_del_walker(hinfo, skb, ops); + return tcf_del_walker(idrinfo, skb, ops); } else if (type == RTM_GETACTION) { - return tcf_dump_walker(hinfo, skb, cb); + return tcf_dump_walker(idrinfo, skb, cb); } else { WARN(1, "tcf_generic_walker: unknown action %d\n", type); return -EINVAL; @@ -207,40 +213,21 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, } EXPORT_SYMBOL(tcf_generic_walker); -static struct tc_action *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) +static struct tc_action *tcf_idr_lookup(u32 index, struct tcf_idrinfo *idrinfo) { struct tc_action *p = NULL; - struct hlist_head *head; - spin_lock_bh(&hinfo->lock); - head = &hinfo->htab[tcf_hash(index, hinfo->hmask)]; - hlist_for_each_entry_rcu(p, head, tcfa_head) - if (p->tcfa_index == index) - break; - spin_unlock_bh(&hinfo->lock); + spin_lock_bh(&idrinfo->lock); + p = idr_find_ext(&idrinfo->action_idr, index); + spin_unlock_bh(&idrinfo->lock); return p; } -u32 tcf_hash_new_index(struct tc_action_net *tn) +int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index) { - struct tcf_hashinfo *hinfo = tn->hinfo; - u32 val = hinfo->index; - - do { - if (++val == 0) - val = 1; - } while (tcf_hash_lookup(val, hinfo)); - - hinfo->index = val; - return val; -} -EXPORT_SYMBOL(tcf_hash_new_index); - -int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index) -{ - struct tcf_hashinfo *hinfo = tn->hinfo; - struct tc_action *p = tcf_hash_lookup(index, hinfo); + struct tcf_idrinfo *idrinfo = tn->idrinfo; + struct tc_action *p = tcf_idr_lookup(index, idrinfo); if (p) { *a = p; @@ -248,15 +235,15 @@ int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index) } return 0; } -EXPORT_SYMBOL(tcf_hash_search); +EXPORT_SYMBOL(tcf_idr_search); -bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a, - int bind) +bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a, + int bind) { - struct tcf_hashinfo *hinfo = tn->hinfo; - struct tc_action *p = NULL; + struct tcf_idrinfo *idrinfo = tn->idrinfo; + struct tc_action *p = tcf_idr_lookup(index, idrinfo); - if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { + if (index && p) { if (bind) p->tcfa_bindcnt++; p->tcfa_refcnt++; @@ -265,23 +252,25 @@ bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a, } return false; } -EXPORT_SYMBOL(tcf_hash_check); +EXPORT_SYMBOL(tcf_idr_check); -void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est) +void tcf_idr_cleanup(struct tc_action *a, struct nlattr *est) { if (est) gen_kill_estimator(&a->tcfa_rate_est); - call_rcu(&a->tcfa_rcu, free_tcf); + free_tcf(a); } -EXPORT_SYMBOL(tcf_hash_cleanup); +EXPORT_SYMBOL(tcf_idr_cleanup); -int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, - struct tc_action **a, const struct tc_action_ops *ops, - int bind, bool cpustats) +int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, + struct tc_action **a, const struct tc_action_ops *ops, + int bind, bool cpustats) { struct tc_action *p = kzalloc(ops->size, GFP_KERNEL); - struct tcf_hashinfo *hinfo = tn->hinfo; + struct tcf_idrinfo *idrinfo = tn->idrinfo; + struct idr *idr = &idrinfo->action_idr; int err = -ENOMEM; + unsigned long idr_index; if (unlikely(!p)) return -ENOMEM; @@ -304,8 +293,32 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, } } spin_lock_init(&p->tcfa_lock); - INIT_HLIST_NODE(&p->tcfa_head); - p->tcfa_index = index ? index : tcf_hash_new_index(tn); + /* user doesn't specify an index */ + if (!index) { + idr_preload(GFP_KERNEL); + spin_lock_bh(&idrinfo->lock); + err = idr_alloc_ext(idr, NULL, &idr_index, 1, 0, + GFP_ATOMIC); + spin_unlock_bh(&idrinfo->lock); + idr_preload_end(); + if (err) { +err3: + free_percpu(p->cpu_qstats); + goto err2; + } + p->tcfa_index = idr_index; + } else { + idr_preload(GFP_KERNEL); + spin_lock_bh(&idrinfo->lock); + err = idr_alloc_ext(idr, NULL, NULL, index, index + 1, + GFP_ATOMIC); + spin_unlock_bh(&idrinfo->lock); + idr_preload_end(); + if (err) + goto err3; + p->tcfa_index = index; + } + p->tcfa_tm.install = jiffies; p->tcfa_tm.lastuse = jiffies; p->tcfa_tm.firstuse = 0; @@ -314,52 +327,46 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est, &p->tcfa_rate_est, &p->tcfa_lock, NULL, est); if (err) { - free_percpu(p->cpu_qstats); - goto err2; + goto err3; } } - p->hinfo = hinfo; + p->idrinfo = idrinfo; p->ops = ops; INIT_LIST_HEAD(&p->list); *a = p; return 0; } -EXPORT_SYMBOL(tcf_hash_create); +EXPORT_SYMBOL(tcf_idr_create); -void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a) +void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a) { - struct tcf_hashinfo *hinfo = tn->hinfo; - unsigned int h = tcf_hash(a->tcfa_index, hinfo->hmask); + struct tcf_idrinfo *idrinfo = tn->idrinfo; - spin_lock_bh(&hinfo->lock); - hlist_add_head(&a->tcfa_head, &hinfo->htab[h]); - spin_unlock_bh(&hinfo->lock); + spin_lock_bh(&idrinfo->lock); + idr_replace_ext(&idrinfo->action_idr, a, a->tcfa_index); + spin_unlock_bh(&idrinfo->lock); } -EXPORT_SYMBOL(tcf_hash_insert); +EXPORT_SYMBOL(tcf_idr_insert); -void tcf_hashinfo_destroy(const struct tc_action_ops *ops, - struct tcf_hashinfo *hinfo) +void tcf_idrinfo_destroy(const struct tc_action_ops *ops, + struct tcf_idrinfo *idrinfo) { - int i; - - for (i = 0; i < hinfo->hmask + 1; i++) { - struct tc_action *p; - struct hlist_node *n; - - hlist_for_each_entry_safe(p, n, &hinfo->htab[i], tcfa_head) { - int ret; + struct idr *idr = &idrinfo->action_idr; + struct tc_action *p; + int ret; + unsigned long id = 1; - ret = __tcf_hash_release(p, false, true); - if (ret == ACT_P_DELETED) - module_put(ops->owner); - else if (ret < 0) - return; - } + idr_for_each_entry_ext(idr, p, id) { + ret = __tcf_idr_release(p, false, true); + if (ret == ACT_P_DELETED) + module_put(ops->owner); + else if (ret < 0) + return; } - kfree(hinfo->htab); + idr_destroy(&idrinfo->action_idr); } -EXPORT_SYMBOL(tcf_hashinfo_destroy); +EXPORT_SYMBOL(tcf_idrinfo_destroy); static LIST_HEAD(act_base); static DEFINE_RWLOCK(act_mod_lock); @@ -460,9 +467,10 @@ static struct tc_action_ops *tc_lookup_action(struct nlattr *kind) int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions, int nr_actions, struct tcf_result *res) { - int ret = -1, i; u32 jmp_prgcnt = 0; u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */ + int i; + int ret = TC_ACT_OK; if (skb_skip_tc_classify(skb)) return TC_ACT_OK; @@ -506,13 +514,15 @@ EXPORT_SYMBOL(tcf_action_exec); int tcf_action_destroy(struct list_head *actions, int bind) { + const struct tc_action_ops *ops; struct tc_action *a, *tmp; int ret = 0; list_for_each_entry_safe(a, tmp, actions, list) { - ret = __tcf_hash_release(a, bind, true); + ops = a->ops; + ret = __tcf_idr_release(a, bind, true); if (ret == ACT_P_DELETED) - module_put(a->ops->owner); + module_put(ops->owner); else if (ret < 0) return ret; } @@ -1068,11 +1078,18 @@ static int tcf_action_add(struct net *net, struct nlattr *nla, return tcf_add_notify(net, n, &actions, portid); } +static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON; +static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = { + [TCA_ROOT_FLAGS] = { .type = NLA_BITFIELD32, + .validation_data = &tcaa_root_flags_allowed }, + [TCA_ROOT_TIME_DELTA] = { .type = NLA_U32 }, +}; + static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, struct netlink_ext_ack *extack) { struct net *net = sock_net(skb->sk); - struct nlattr *tca[TCA_ACT_MAX + 1]; + struct nlattr *tca[TCA_ROOT_MAX + 1]; u32 portid = skb ? NETLINK_CB(skb).portid : 0; int ret = 0, ovr = 0; @@ -1080,7 +1097,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, !netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; - ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL, + ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ROOT_MAX, NULL, extack); if (ret < 0) return ret; @@ -1121,16 +1138,12 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, return ret; } -static struct nlattr *find_dump_kind(const struct nlmsghdr *n) +static struct nlattr *find_dump_kind(struct nlattr **nla) { struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1]; struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; - struct nlattr *nla[TCAA_MAX + 1]; struct nlattr *kind; - if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, - NULL, NULL) < 0) - return NULL; tb1 = nla[TCA_ACT_TAB]; if (tb1 == NULL) return NULL; @@ -1157,8 +1170,20 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) struct tc_action_ops *a_o; int ret = 0; struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh); - struct nlattr *kind = find_dump_kind(cb->nlh); + struct nlattr *tb[TCA_ROOT_MAX + 1]; + struct nlattr *count_attr = NULL; + unsigned long jiffy_since = 0; + struct nlattr *kind = NULL; + struct nla_bitfield32 bf; + u32 msecs_since = 0; + u32 act_count = 0; + + ret = nlmsg_parse(cb->nlh, sizeof(struct tcamsg), tb, TCA_ROOT_MAX, + tcaa_policy, NULL); + if (ret < 0) + return ret; + kind = find_dump_kind(tb); if (kind == NULL) { pr_info("tc_dump_action: action bad kind\n"); return 0; @@ -1168,14 +1193,32 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) if (a_o == NULL) return 0; + cb->args[2] = 0; + if (tb[TCA_ROOT_FLAGS]) { + bf = nla_get_bitfield32(tb[TCA_ROOT_FLAGS]); + cb->args[2] = bf.value; + } + + if (tb[TCA_ROOT_TIME_DELTA]) { + msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]); + } + nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, cb->nlh->nlmsg_type, sizeof(*t), 0); if (!nlh) goto out_module_put; + + if (msecs_since) + jiffy_since = jiffies - msecs_to_jiffies(msecs_since); + t = nlmsg_data(nlh); t->tca_family = AF_UNSPEC; t->tca__pad1 = 0; t->tca__pad2 = 0; + cb->args[3] = jiffy_since; + count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32)); + if (!count_attr) + goto out_module_put; nest = nla_nest_start(skb, TCA_ACT_TAB); if (nest == NULL) @@ -1188,6 +1231,9 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) if (ret > 0) { nla_nest_end(skb, nest); ret = skb->len; + act_count = cb->args[1]; + memcpy(nla_data(count_attr), &act_count, sizeof(u32)); + cb->args[1] = 0; } else nlmsg_trim(skb, b); @@ -1205,10 +1251,10 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) static int __init tc_action_init(void) { - rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, NULL); + rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action, - NULL); + 0); return 0; } diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index 9afe1337cfd109a5dc92746cec2997e7a96390ee..c0c707eb2c962520fbc6da655c8b4151bf8a4462 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c @@ -21,7 +21,6 @@ #include #include -#define BPF_TAB_MASK 15 #define ACT_BPF_NAME_LEN 256 struct tcf_bpf_cfg { @@ -295,9 +294,9 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_ACT_BPF_PARMS]); - if (!tcf_hash_check(tn, parm->index, act, bind)) { - ret = tcf_hash_create(tn, parm->index, est, act, - &act_bpf_ops, bind, true); + if (!tcf_idr_check(tn, parm->index, act, bind)) { + ret = tcf_idr_create(tn, parm->index, est, act, + &act_bpf_ops, bind, true); if (ret < 0) return ret; @@ -307,7 +306,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, if (bind) return 0; - tcf_hash_release(*act, bind); + tcf_idr_release(*act, bind); if (!replace) return -EEXIST; } @@ -343,7 +342,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, rcu_assign_pointer(prog->filter, cfg.filter); if (res == ACT_P_CREATED) { - tcf_hash_insert(tn, *act); + tcf_idr_insert(tn, *act); } else { /* make sure the program being replaced is no longer executing */ synchronize_rcu(); @@ -353,7 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, return res; out: if (res == ACT_P_CREATED) - tcf_hash_cleanup(*act, est); + tcf_idr_cleanup(*act, est); return ret; } @@ -379,7 +378,7 @@ static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, bpf_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_bpf_ops __read_mostly = { @@ -399,7 +398,7 @@ static __net_init int bpf_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, bpf_net_id); - return tc_action_net_init(tn, &act_bpf_ops, BPF_TAB_MASK); + return tc_action_net_init(tn, &act_bpf_ops); } static void __net_exit bpf_exit_net(struct net *net) diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index 2155bc6c6a1e79049de9dc9c8e611b592e42a77f..10b7a8855a6c754640c66b21af3df1e4b17de63d 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c @@ -28,8 +28,6 @@ #include #include -#define CONNMARK_TAB_MASK 3 - static unsigned int connmark_net_id; static struct tc_action_ops act_connmark_ops; @@ -119,9 +117,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_CONNMARK_PARMS]); - if (!tcf_hash_check(tn, parm->index, a, bind)) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_connmark_ops, bind, false); + if (!tcf_idr_check(tn, parm->index, a, bind)) { + ret = tcf_idr_create(tn, parm->index, est, a, + &act_connmark_ops, bind, false); if (ret) return ret; @@ -130,13 +128,13 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, ci->net = net; ci->zone = parm->zone; - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); ret = ACT_P_CREATED; } else { ci = to_connmark(*a); if (bind) return 0; - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; /* replacing action and zone */ @@ -189,7 +187,7 @@ static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, connmark_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_connmark_ops = { @@ -208,7 +206,7 @@ static __net_init int connmark_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, connmark_net_id); - return tc_action_net_init(tn, &act_connmark_ops, CONNMARK_TAB_MASK); + return tc_action_net_init(tn, &act_connmark_ops); } static void __net_exit connmark_exit_net(struct net *net) diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 3317a2f579da7dfa764f7d5d7665460ffe06438b..1c40caadcff959ba0c6cec6b8e32f7b459c42cfa 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -37,8 +37,6 @@ #include #include -#define CSUM_TAB_MASK 15 - static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { [TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), }, }; @@ -67,16 +65,16 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, return -EINVAL; parm = nla_data(tb[TCA_CSUM_PARMS]); - if (!tcf_hash_check(tn, parm->index, a, bind)) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_csum_ops, bind, false); + if (!tcf_idr_check(tn, parm->index, a, bind)) { + ret = tcf_idr_create(tn, parm->index, est, a, + &act_csum_ops, bind, false); if (ret) return ret; ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -88,7 +86,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -231,9 +229,6 @@ static int tcf_csum_ipv4_udp(struct sk_buff *skb, unsigned int ihl, const struct iphdr *iph; u16 ul; - if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_UDP) - return 1; - /* * Support both UDP and UDPLITE checksum algorithms, Don't use * udph->len to get the real length without any protocol check, @@ -287,9 +282,6 @@ static int tcf_csum_ipv6_udp(struct sk_buff *skb, unsigned int ihl, const struct ipv6hdr *ip6h; u16 ul; - if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_UDP) - return 1; - /* * Support both UDP and UDPLITE checksum algorithms, Don't use * udph->len to get the real length without any protocol check, @@ -615,7 +607,7 @@ static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, csum_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_csum_ops = { @@ -634,7 +626,7 @@ static __net_init int csum_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, csum_net_id); - return tc_action_net_init(tn, &act_csum_ops, CSUM_TAB_MASK); + return tc_action_net_init(tn, &act_csum_ops); } static void __net_exit csum_exit_net(struct net *net) diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 99afe8b1f1fb015584f303e7352da8b6171774eb..e29a48ef7fc348aefdc720cf08d1509ac5b53559 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -23,8 +23,6 @@ #include #include -#define GACT_TAB_MASK 15 - static unsigned int gact_net_id; static struct tc_action_ops act_gact_ops; @@ -92,16 +90,16 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, } #endif - if (!tcf_hash_check(tn, parm->index, a, bind)) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_gact_ops, bind, true); + if (!tcf_idr_check(tn, parm->index, a, bind)) { + ret = tcf_idr_create(tn, parm->index, est, a, + &act_gact_ops, bind, true); if (ret) return ret; ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -122,7 +120,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, } #endif if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -214,7 +212,7 @@ static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, gact_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_gact_ops = { @@ -234,7 +232,7 @@ static __net_init int gact_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, gact_net_id); - return tc_action_net_init(tn, &act_gact_ops, GACT_TAB_MASK); + return tc_action_net_init(tn, &act_gact_ops); } static void __net_exit gact_exit_net(struct net *net) diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index c5dec308b8b1eb29505fed1b9a71b3ef70f5e91a..8ccd35825b6b97f48311c1060f88a41a34f18f9a 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -34,8 +34,6 @@ #include #include -#define IFE_TAB_MASK 15 - static unsigned int ife_net_id; static int max_metacnt = IFE_META_MAX + 1; static struct tc_action_ops act_ife_ops; @@ -435,8 +433,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, struct nlattr *tb[TCA_IFE_MAX + 1]; struct nlattr *tb2[IFE_META_MAX + 1]; struct tcf_ife_info *ife; + u16 ife_type = ETH_P_IFE; struct tc_ife *parm; - u16 ife_type = 0; u8 *daddr = NULL; u8 *saddr = NULL; bool exists = false; @@ -452,30 +450,18 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_IFE_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; - if (parm->flags & IFE_ENCODE) { - /* Until we get issued the ethertype, we cant have - * a default.. - **/ - if (!tb[TCA_IFE_TYPE]) { - if (exists) - tcf_hash_release(*a, bind); - pr_info("You MUST pass etherype for encoding\n"); - return -EINVAL; - } - } - if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, &act_ife_ops, - bind, false); + ret = tcf_idr_create(tn, parm->index, est, a, &act_ife_ops, + bind, false); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -484,7 +470,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, ife->flags = parm->flags; if (parm->flags & IFE_ENCODE) { - ife_type = nla_get_u16(tb[TCA_IFE_TYPE]); + if (tb[TCA_IFE_TYPE]) + ife_type = nla_get_u16(tb[TCA_IFE_TYPE]); if (tb[TCA_IFE_DMAC]) daddr = nla_data(tb[TCA_IFE_DMAC]); if (tb[TCA_IFE_SMAC]) @@ -518,7 +505,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, if (err) { metadata_parse_err: if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (ret == ACT_P_CREATED) _tcf_ife_cleanup(*a, bind); @@ -552,7 +539,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&ife->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -811,7 +798,7 @@ static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, ife_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_ife_ops = { @@ -831,7 +818,7 @@ static __net_init int ife_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, ife_net_id); - return tc_action_net_init(tn, &act_ife_ops, IFE_TAB_MASK); + return tc_action_net_init(tn, &act_ife_ops); } static void __net_exit ife_exit_net(struct net *net) diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 36f0ced9e60c03297e195135ca5a8a53d1a3a27b..d9e399a7e3d59c8ec53e46e0862e2ca3c83988bc 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -28,19 +28,18 @@ #include -#define IPT_TAB_MASK 15 - static unsigned int ipt_net_id; static struct tc_action_ops act_ipt_ops; static unsigned int xt_net_id; static struct tc_action_ops act_xt_ops; -static int ipt_init_target(struct xt_entry_target *t, char *table, - unsigned int hook) +static int ipt_init_target(struct net *net, struct xt_entry_target *t, + char *table, unsigned int hook) { struct xt_tgchk_param par; struct xt_target *target; + struct ipt_entry e = {}; int ret = 0; target = xt_request_find_target(AF_INET, t->u.user.name, @@ -49,8 +48,10 @@ static int ipt_init_target(struct xt_entry_target *t, char *table, return PTR_ERR(target); t->u.kernel.target = target; + memset(&par, 0, sizeof(par)); + par.net = net; par.table = table; - par.entryinfo = NULL; + par.entryinfo = &e; par.target = target; par.targinfo = t->data; par.hook_mask = hook; @@ -91,10 +92,11 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { [TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) }, }; -static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, +static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla, struct nlattr *est, struct tc_action **a, const struct tc_action_ops *ops, int ovr, int bind) { + struct tc_action_net *tn = net_generic(net, id); struct nlattr *tb[TCA_IPT_MAX + 1]; struct tcf_ipt *ipt; struct xt_entry_target *td, *t; @@ -114,33 +116,33 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, if (tb[TCA_IPT_INDEX] != NULL) index = nla_get_u32(tb[TCA_IPT_INDEX]); - exists = tcf_hash_check(tn, index, a, bind); + exists = tcf_idr_check(tn, index, a, bind); if (exists && bind) return 0; if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) { if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]); if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) { if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } if (!exists) { - ret = tcf_hash_create(tn, index, est, a, ops, bind, - false); + ret = tcf_idr_create(tn, index, est, a, ops, bind, + false); if (ret) return ret; ret = ACT_P_CREATED; } else { if (bind)/* dont override defaults */ return 0; - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; @@ -159,7 +161,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, if (unlikely(!t)) goto err2; - err = ipt_init_target(t, tname, hook); + err = ipt_init_target(net, t, tname, hook); if (err < 0) goto err3; @@ -176,7 +178,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, ipt->tcfi_hook = hook; spin_unlock_bh(&ipt->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; err3: @@ -185,7 +187,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, kfree(tname); err1: if (ret == ACT_P_CREATED) - tcf_hash_cleanup(*a, est); + tcf_idr_cleanup(*a, est); return err; } @@ -193,18 +195,16 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, struct tc_action **a, int ovr, int bind) { - struct tc_action_net *tn = net_generic(net, ipt_net_id); - - return __tcf_ipt_init(tn, nla, est, a, &act_ipt_ops, ovr, bind); + return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr, + bind); } static int tcf_xt_init(struct net *net, struct nlattr *nla, struct nlattr *est, struct tc_action **a, int ovr, int bind) { - struct tc_action_net *tn = net_generic(net, xt_net_id); - - return __tcf_ipt_init(tn, nla, est, a, &act_xt_ops, ovr, bind); + return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr, + bind); } static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a, @@ -314,7 +314,7 @@ static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, ipt_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_ipt_ops = { @@ -334,7 +334,7 @@ static __net_init int ipt_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, ipt_net_id); - return tc_action_net_init(tn, &act_ipt_ops, IPT_TAB_MASK); + return tc_action_net_init(tn, &act_ipt_ops); } static void __net_exit ipt_exit_net(struct net *net) @@ -364,7 +364,7 @@ static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, xt_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_xt_ops = { @@ -384,7 +384,7 @@ static __net_init int xt_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, xt_net_id); - return tc_action_net_init(tn, &act_xt_ops, IPT_TAB_MASK); + return tc_action_net_init(tn, &act_xt_ops); } static void __net_exit xt_exit_net(struct net *net) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 1b5549ababd4690617b5ff0c3842c6cbb4806a41..416627c66f081f26ff9284de86411c3e05390b8e 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -28,7 +28,6 @@ #include #include -#define MIRRED_TAB_MASK 7 static LIST_HEAD(mirred_list); static DEFINE_SPINLOCK(mirred_list_lock); @@ -94,7 +93,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, return -EINVAL; parm = nla_data(tb[TCA_MIRRED_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; @@ -106,14 +105,14 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, break; default: if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } if (parm->ifindex) { dev = __dev_get_by_index(net, parm->ifindex); if (dev == NULL) { if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -ENODEV; } mac_header_xmit = dev_is_mac_header_xmit(dev); @@ -124,13 +123,13 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, if (!exists) { if (dev == NULL) return -EINVAL; - ret = tcf_hash_create(tn, parm->index, est, a, - &act_mirred_ops, bind, true); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_mirred_ops, bind, true); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -152,7 +151,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, spin_lock_bh(&mirred_list_lock); list_add(&m->tcfm_list, &mirred_list); spin_unlock_bh(&mirred_list_lock); - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); } return ret; @@ -283,7 +282,7 @@ static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, mirred_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static int mirred_device_event(struct notifier_block *unused, @@ -344,7 +343,7 @@ static __net_init int mirred_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, mirred_net_id); - return tc_action_net_init(tn, &act_mirred_ops, MIRRED_TAB_MASK); + return tc_action_net_init(tn, &act_mirred_ops); } static void __net_exit mirred_exit_net(struct net *net) diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 9016ab8a0649780a02d8b29f76f98f19c0283e11..c365d01b99c8b7892c16e43742a88744d7d84e54 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -29,8 +29,6 @@ #include -#define NAT_TAB_MASK 15 - static unsigned int nat_net_id; static struct tc_action_ops act_nat_ops; @@ -58,16 +56,16 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, return -EINVAL; parm = nla_data(tb[TCA_NAT_PARMS]); - if (!tcf_hash_check(tn, parm->index, a, bind)) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_nat_ops, bind, false); + if (!tcf_idr_check(tn, parm->index, a, bind)) { + ret = tcf_idr_create(tn, parm->index, est, a, + &act_nat_ops, bind, false); if (ret) return ret; ret = ACT_P_CREATED; } else { if (bind) return 0; - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -83,7 +81,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -290,7 +288,7 @@ static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, nat_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_nat_ops = { @@ -309,7 +307,7 @@ static __net_init int nat_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, nat_net_id); - return tc_action_net_init(tn, &act_nat_ops, NAT_TAB_MASK); + return tc_action_net_init(tn, &act_nat_ops); } static void __net_exit nat_exit_net(struct net *net) diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 7dc5892671c818db55b024b10d56ec2252c2f826..491fe5deb09ee7f38a6c0f892c43ffe0bce79fd1 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -24,8 +24,6 @@ #include #include -#define PEDIT_TAB_MASK 15 - static unsigned int pedit_net_id; static struct tc_action_ops act_pedit_ops; @@ -168,17 +166,17 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, if (IS_ERR(keys_ex)) return PTR_ERR(keys_ex); - if (!tcf_hash_check(tn, parm->index, a, bind)) { + if (!tcf_idr_check(tn, parm->index, a, bind)) { if (!parm->nkeys) return -EINVAL; - ret = tcf_hash_create(tn, parm->index, est, a, - &act_pedit_ops, bind, false); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_pedit_ops, bind, false); if (ret) return ret; p = to_pedit(*a); keys = kmalloc(ksize, GFP_KERNEL); if (keys == NULL) { - tcf_hash_cleanup(*a, est); + tcf_idr_cleanup(*a, est); kfree(keys_ex); return -ENOMEM; } @@ -186,7 +184,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, } else { if (bind) return 0; - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; p = to_pedit(*a); @@ -214,7 +212,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&p->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -432,7 +430,7 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, pedit_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_pedit_ops = { @@ -452,7 +450,7 @@ static __net_init int pedit_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, pedit_net_id); - return tc_action_net_init(tn, &act_pedit_ops, PEDIT_TAB_MASK); + return tc_action_net_init(tn, &act_pedit_ops); } static void __net_exit pedit_exit_net(struct net *net) diff --git a/net/sched/act_police.c b/net/sched/act_police.c index b062bc80c7cb11b0ea473916c58957b54db21594..3bb2ebf9e9aec2743033ecdc4f5763ce601bf653 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -40,8 +40,6 @@ struct tcf_police { #define to_police(pc) ((struct tcf_police *)pc) -#define POL_TAB_MASK 15 - /* old policer structure from before tc actions */ struct tc_police_compat { u32 index; @@ -101,18 +99,18 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, return -EINVAL; parm = nla_data(tb[TCA_POLICE_TBF]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; if (!exists) { - ret = tcf_hash_create(tn, parm->index, NULL, a, - &act_police_ops, bind, false); + ret = tcf_idr_create(tn, parm->index, NULL, a, + &act_police_ops, bind, false); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -188,7 +186,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, return ret; police->tcfp_t_c = ktime_get_ns(); - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; @@ -196,7 +194,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, qdisc_put_rtab(P_tab); qdisc_put_rtab(R_tab); if (ret == ACT_P_CREATED) - tcf_hash_cleanup(*a, est); + tcf_idr_cleanup(*a, est); return err; } @@ -310,7 +308,7 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, police_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } MODULE_AUTHOR("Alexey Kuznetsov"); @@ -333,7 +331,7 @@ static __net_init int police_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, police_net_id); - return tc_action_net_init(tn, &act_police_ops, POL_TAB_MASK); + return tc_action_net_init(tn, &act_police_ops); } static void __net_exit police_exit_net(struct net *net) diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 59d6645a4007818656376b02a9c5a458e028420b..ec986ae528089081ecdf8528437bbd82b7e840e1 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c @@ -25,7 +25,6 @@ #include -#define SAMPLE_TAB_MASK 7 static unsigned int sample_net_id; static struct tc_action_ops act_sample_ops; @@ -59,18 +58,18 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_SAMPLE_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_sample_ops, bind, false); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_sample_ops, bind, false); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -82,7 +81,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, psample_group = psample_group_get(net, s->psample_group_num); if (!psample_group) { if (ret == ACT_P_CREATED) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -ENOMEM; } RCU_INIT_POINTER(s->psample_group, psample_group); @@ -93,7 +92,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, } if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -221,7 +220,7 @@ static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, sample_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_sample_ops = { @@ -241,7 +240,7 @@ static __net_init int sample_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, sample_net_id); - return tc_action_net_init(tn, &act_sample_ops, SAMPLE_TAB_MASK); + return tc_action_net_init(tn, &act_sample_ops); } static void __net_exit sample_exit_net(struct net *net) diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 43605e7ce05107adb79bd1dbc562f4961eb20e51..e7b57e5071a365743de9d2c5aaa22dca445fa0d9 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -24,8 +24,6 @@ #include #include -#define SIMP_TAB_MASK 7 - static unsigned int simp_net_id; static struct tc_action_ops act_simp_ops; @@ -102,28 +100,28 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, return -EINVAL; parm = nla_data(tb[TCA_DEF_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; if (tb[TCA_DEF_DATA] == NULL) { if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } defdata = nla_data(tb[TCA_DEF_DATA]); if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_simp_ops, bind, false); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_simp_ops, bind, false); if (ret) return ret; d = to_defact(*a); ret = alloc_defdata(d, defdata); if (ret < 0) { - tcf_hash_cleanup(*a, est); + tcf_idr_cleanup(*a, est); return ret; } d->tcf_action = parm->action; @@ -131,7 +129,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, } else { d = to_defact(*a); - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; @@ -139,7 +137,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, } if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -183,7 +181,7 @@ static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, simp_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_simp_ops = { @@ -203,7 +201,7 @@ static __net_init int simp_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, simp_net_id); - return tc_action_net_init(tn, &act_simp_ops, SIMP_TAB_MASK); + return tc_action_net_init(tn, &act_simp_ops); } static void __net_exit simp_exit_net(struct net *net) diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 6b3e65d7de0c2e81240618e4500ee894819df833..59949d61f20da1031b8b47712f817c991c6bed60 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -27,8 +27,6 @@ #include #include -#define SKBEDIT_TAB_MASK 15 - static unsigned int skbedit_net_id; static struct tc_action_ops act_skbedit_ops; @@ -118,18 +116,18 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, parm = nla_data(tb[TCA_SKBEDIT_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; if (!flags) { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_skbedit_ops, bind, false); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_skbedit_ops, bind, false); if (ret) return ret; @@ -137,7 +135,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, ret = ACT_P_CREATED; } else { d = to_skbedit(*a); - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -163,7 +161,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&d->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -221,7 +219,7 @@ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, skbedit_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_skbedit_ops = { @@ -240,7 +238,7 @@ static __net_init int skbedit_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbedit_net_id); - return tc_action_net_init(tn, &act_skbedit_ops, SKBEDIT_TAB_MASK); + return tc_action_net_init(tn, &act_skbedit_ops); } static void __net_exit skbedit_exit_net(struct net *net) diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index a73c4bbcada293b2923a41572104d6f9362d37d9..b642ad3d39dd414d392e492bae091995b01cbd77 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c @@ -20,8 +20,6 @@ #include #include -#define SKBMOD_TAB_MASK 15 - static unsigned int skbmod_net_id; static struct tc_action_ops act_skbmod_ops; @@ -129,7 +127,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, if (parm->flags & SKBMOD_F_SWAPMAC) lflags = SKBMOD_F_SWAPMAC; - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; @@ -137,14 +135,14 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, return -EINVAL; if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_skbmod_ops, bind, true); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_skbmod_ops, bind, true); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -155,7 +153,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL); if (unlikely(!p)) { if (ovr) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -ENOMEM; } @@ -182,7 +180,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, kfree_rcu(p_old, rcu); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -245,7 +243,7 @@ static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_skbmod_ops = { @@ -265,7 +263,7 @@ static __net_init int skbmod_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); - return tc_action_net_init(tn, &act_skbmod_ops, SKBMOD_TAB_MASK); + return tc_action_net_init(tn, &act_skbmod_ops); } static void __net_exit skbmod_exit_net(struct net *net) diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index fd7e75679c69e050052f388675eb58060e15f493..30c96274c63826520eec062a6a5609b141bab307 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c @@ -20,8 +20,6 @@ #include #include -#define TUNNEL_KEY_TAB_MASK 15 - static unsigned int tunnel_key_net_id; static struct tc_action_ops act_tunnel_key_ops; @@ -100,7 +98,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, return -EINVAL; parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; @@ -159,14 +157,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, } if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_tunnel_key_ops, bind, true); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_tunnel_key_ops, bind, true); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -177,7 +175,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, params_new = kzalloc(sizeof(*params_new), GFP_KERNEL); if (unlikely(!params_new)) { if (ret == ACT_P_CREATED) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -ENOMEM; } @@ -193,13 +191,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, kfree_rcu(params_old, rcu); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; err_out: if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return ret; } @@ -304,7 +302,7 @@ static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_tunnel_key_ops = { @@ -324,7 +322,7 @@ static __net_init int tunnel_key_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); - return tc_action_net_init(tn, &act_tunnel_key_ops, TUNNEL_KEY_TAB_MASK); + return tc_action_net_init(tn, &act_tunnel_key_ops); } static void __net_exit tunnel_key_exit_net(struct net *net) diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 13ba3a89f675d7d5ddaeab893a9d548be735e39e..16eb067a8d8fa20c17894db8047571789c0b96e8 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -19,8 +19,6 @@ #include #include -#define VLAN_TAB_MASK 15 - static unsigned int vlan_net_id; static struct tc_action_ops act_vlan_ops; @@ -128,7 +126,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, if (!tb[TCA_VLAN_PARMS]) return -EINVAL; parm = nla_data(tb[TCA_VLAN_PARMS]); - exists = tcf_hash_check(tn, parm->index, a, bind); + exists = tcf_idr_check(tn, parm->index, a, bind); if (exists && bind) return 0; @@ -139,13 +137,13 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, case TCA_VLAN_ACT_MODIFY: if (!tb[TCA_VLAN_PUSH_VLAN_ID]) { if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]); if (push_vid >= VLAN_VID_MASK) { if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -ERANGE; } @@ -167,20 +165,20 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, break; default: if (exists) - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); return -EINVAL; } action = parm->v_action; if (!exists) { - ret = tcf_hash_create(tn, parm->index, est, a, - &act_vlan_ops, bind, false); + ret = tcf_idr_create(tn, parm->index, est, a, + &act_vlan_ops, bind, false); if (ret) return ret; ret = ACT_P_CREATED; } else { - tcf_hash_release(*a, bind); + tcf_idr_release(*a, bind); if (!ovr) return -EEXIST; } @@ -199,7 +197,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, spin_unlock_bh(&v->tcf_lock); if (ret == ACT_P_CREATED) - tcf_hash_insert(tn, *a); + tcf_idr_insert(tn, *a); return ret; } @@ -252,7 +250,7 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index) { struct tc_action_net *tn = net_generic(net, vlan_net_id); - return tcf_hash_search(tn, a, index); + return tcf_idr_search(tn, a, index); } static struct tc_action_ops act_vlan_ops = { @@ -271,7 +269,7 @@ static __net_init int vlan_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, vlan_net_id); - return tc_action_net_init(tn, &act_vlan_ops, VLAN_TAB_MASK); + return tc_action_net_init(tn, &act_vlan_ops); } static void __net_exit vlan_exit_net(struct net *net) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 39da0c5801c908e28c4e258319adefde836c6b0c..0b2219adf520b33a471dd3b8e2fdf9f46271c3f9 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -100,21 +100,6 @@ int unregister_tcf_proto_ops(struct tcf_proto_ops *ops) } EXPORT_SYMBOL(unregister_tcf_proto_ops); -static int tfilter_notify(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, struct tcf_proto *tp, - unsigned long fh, int event, bool unicast); - -static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, - struct tcf_chain *chain, int event) -{ - struct tcf_proto *tp; - - for (tp = rtnl_dereference(chain->filter_chain); - tp; tp = rtnl_dereference(tp->next)) - tfilter_notify(net, oskb, n, tp, 0, event, false); -} - /* Select new prio value from the range, managed by kernel. */ static inline u32 tcf_auto_prio(struct tcf_proto *tp) @@ -205,10 +190,11 @@ static void tcf_chain_flush(struct tcf_chain *chain) { struct tcf_proto *tp; - if (*chain->p_filter_chain) + if (chain->p_filter_chain) RCU_INIT_POINTER(*chain->p_filter_chain, NULL); while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) { RCU_INIT_POINTER(chain->filter_chain, tp->next); + tcf_chain_put(chain); tcf_proto_destroy(tp); } } @@ -216,10 +202,14 @@ static void tcf_chain_flush(struct tcf_chain *chain) static void tcf_chain_destroy(struct tcf_chain *chain) { list_del(&chain->list); - tcf_chain_flush(chain); kfree(chain); } +static void tcf_chain_hold(struct tcf_chain *chain) +{ + ++chain->refcnt; +} + struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, bool create) { @@ -227,23 +217,18 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, list_for_each_entry(chain, &block->chain_list, list) { if (chain->index == chain_index) { - chain->refcnt++; + tcf_chain_hold(chain); return chain; } } - if (create) - return tcf_chain_create(block, chain_index); - else - return NULL; + + return create ? tcf_chain_create(block, chain_index) : NULL; } EXPORT_SYMBOL(tcf_chain_get); void tcf_chain_put(struct tcf_chain *chain) { - /* Destroy unused chain, with exception of chain 0, which is the - * default one and has to be always present. - */ - if (--chain->refcnt == 0 && !chain->filter_chain && chain->index != 0) + if (--chain->refcnt == 0) tcf_chain_destroy(chain); } EXPORT_SYMBOL(tcf_chain_put); @@ -288,8 +273,31 @@ void tcf_block_put(struct tcf_block *block) if (!block) return; + /* XXX: Standalone actions are not allowed to jump to any chain, and + * bound actions should be all removed after flushing. However, + * filters are destroyed in RCU callbacks, we have to hold the chains + * first, otherwise we would always race with RCU callbacks on this list + * without proper locking. + */ + + /* Wait for existing RCU callbacks to cool down. */ + rcu_barrier(); + + /* Hold a refcnt for all chains, except 0, in case they are gone. */ + list_for_each_entry(chain, &block->chain_list, list) + if (chain->index) + tcf_chain_hold(chain); + + /* No race on the list, because no chain could be destroyed. */ + list_for_each_entry(chain, &block->chain_list, list) + tcf_chain_flush(chain); + + /* Wait for RCU callbacks to release the reference count. */ + rcu_barrier(); + + /* At this point, all the chains should have refcnt == 1. */ list_for_each_entry_safe(chain, tmp, &block->chain_list, list) - tcf_chain_destroy(chain); + tcf_chain_put(chain); kfree(block); } EXPORT_SYMBOL(tcf_block_put); @@ -367,6 +375,7 @@ static void tcf_chain_tp_insert(struct tcf_chain *chain, rcu_assign_pointer(*chain->p_filter_chain, tp); RCU_INIT_POINTER(tp->next, tcf_chain_tp_prev(chain_info)); rcu_assign_pointer(*chain_info->pprev, tp); + tcf_chain_hold(chain); } static void tcf_chain_tp_remove(struct tcf_chain *chain, @@ -378,6 +387,7 @@ static void tcf_chain_tp_remove(struct tcf_chain *chain, if (chain->p_filter_chain && tp == chain->filter_chain) RCU_INIT_POINTER(*chain->p_filter_chain, next); RCU_INIT_POINTER(*chain_info->pprev, next); + tcf_chain_put(chain); } static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain, @@ -407,6 +417,109 @@ static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain, return tp; } +static int tcf_fill_node(struct net *net, struct sk_buff *skb, + struct tcf_proto *tp, void *fh, u32 portid, + u32 seq, u16 flags, int event) +{ + struct tcmsg *tcm; + struct nlmsghdr *nlh; + unsigned char *b = skb_tail_pointer(skb); + + nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); + tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; + tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; + tcm->tcm_parent = tp->classid; + tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); + if (nla_put_string(skb, TCA_KIND, tp->ops->kind)) + goto nla_put_failure; + if (nla_put_u32(skb, TCA_CHAIN, tp->chain->index)) + goto nla_put_failure; + if (!fh) { + tcm->tcm_handle = 0; + } else { + if (tp->ops->dump && tp->ops->dump(net, tp, fh, skb, tcm) < 0) + goto nla_put_failure; + } + nlh->nlmsg_len = skb_tail_pointer(skb) - b; + return skb->len; + +out_nlmsg_trim: +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static int tfilter_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, struct tcf_proto *tp, + void *fh, int event, bool unicast) +{ + struct sk_buff *skb; + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, + n->nlmsg_flags, event) <= 0) { + kfree_skb(skb); + return -EINVAL; + } + + if (unicast) + return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); + + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); +} + +static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, struct tcf_proto *tp, + void *fh, bool unicast, bool *last) +{ + struct sk_buff *skb; + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + int err; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, + n->nlmsg_flags, RTM_DELTFILTER) <= 0) { + kfree_skb(skb); + return -EINVAL; + } + + err = tp->ops->delete(tp, fh, last); + if (err) { + kfree_skb(skb); + return err; + } + + if (unicast) + return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); + + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); +} + +static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, + struct tcf_chain *chain, int event) +{ + struct tcf_proto *tp; + + for (tp = rtnl_dereference(chain->filter_chain); + tp; tp = rtnl_dereference(tp->next)) + tfilter_notify(net, oskb, n, tp, 0, event, false); +} + /* Add/change/delete/get a filter node */ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, @@ -428,7 +541,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, struct tcf_proto *tp; const struct Qdisc_class_ops *cops; unsigned long cl; - unsigned long fh; + void *fh; int err; int tp_created; @@ -498,7 +611,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, /* Do we search for filter, attached to class? */ if (TC_H_MIN(parent)) { - cl = cops->get(q, parent); + cl = cops->find(q, parent); if (cl == 0) return -ENOENT; } @@ -567,7 +680,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, fh = tp->ops->get(tp, t->tcm_handle); - if (fh == 0) { + if (!fh) { if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { tcf_chain_tp_remove(chain, &chain_info, tp); tfilter_notify(net, skb, n, tp, fh, @@ -595,11 +708,10 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, } break; case RTM_DELTFILTER: - err = tp->ops->delete(tp, fh, &last); + err = tfilter_del_notify(net, skb, n, tp, fh, false, + &last); if (err) goto errout; - tfilter_notify(net, skb, n, tp, t->tcm_handle, - RTM_DELTFILTER, false); if (last) { tcf_chain_tp_remove(chain, &chain_info, tp); tcf_proto_destroy(tp); @@ -629,83 +741,19 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, errout: if (chain) tcf_chain_put(chain); - if (cl) - cops->put(q, cl); if (err == -EAGAIN) /* Replay the request. */ goto replay; return err; } -static int tcf_fill_node(struct net *net, struct sk_buff *skb, - struct tcf_proto *tp, unsigned long fh, u32 portid, - u32 seq, u16 flags, int event) -{ - struct tcmsg *tcm; - struct nlmsghdr *nlh; - unsigned char *b = skb_tail_pointer(skb); - - nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); - if (!nlh) - goto out_nlmsg_trim; - tcm = nlmsg_data(nlh); - tcm->tcm_family = AF_UNSPEC; - tcm->tcm__pad1 = 0; - tcm->tcm__pad2 = 0; - tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; - tcm->tcm_parent = tp->classid; - tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); - if (nla_put_string(skb, TCA_KIND, tp->ops->kind)) - goto nla_put_failure; - if (nla_put_u32(skb, TCA_CHAIN, tp->chain->index)) - goto nla_put_failure; - tcm->tcm_handle = fh; - if (RTM_DELTFILTER != event) { - tcm->tcm_handle = 0; - if (tp->ops->dump && tp->ops->dump(net, tp, fh, skb, tcm) < 0) - goto nla_put_failure; - } - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; - -out_nlmsg_trim: -nla_put_failure: - nlmsg_trim(skb, b); - return -1; -} - -static int tfilter_notify(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, struct tcf_proto *tp, - unsigned long fh, int event, bool unicast) -{ - struct sk_buff *skb; - u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; - - skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb) - return -ENOBUFS; - - if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, - n->nlmsg_flags, event) <= 0) { - kfree_skb(skb); - return -EINVAL; - } - - if (unicast) - return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); - - return rtnetlink_send(skb, net, portid, RTNLGRP_TC, - n->nlmsg_flags & NLM_F_ECHO); -} - struct tcf_dump_args { struct tcf_walker w; struct sk_buff *skb; struct netlink_callback *cb; }; -static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, - struct tcf_walker *arg) +static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg) { struct tcf_dump_args *a = (void *)arg; struct net *net = sock_net(a->skb->sk); @@ -797,17 +845,17 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) goto out; cops = q->ops->cl_ops; if (!cops) - goto errout; + goto out; if (!cops->tcf_block) - goto errout; + goto out; if (TC_H_MIN(tcm->tcm_parent)) { - cl = cops->get(q, tcm->tcm_parent); + cl = cops->find(q, tcm->tcm_parent); if (cl == 0) - goto errout; + goto out; } block = cops->tcf_block(q, cl); if (!block) - goto errout; + goto out; index_start = cb->args[0]; index = 0; @@ -822,9 +870,6 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) cb->args[0] = index; -errout: - if (cl) - cops->put(q, cl); out: return skb->len; } @@ -883,18 +928,12 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, } EXPORT_SYMBOL(tcf_exts_validate); -void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst, - struct tcf_exts *src) +void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src) { #ifdef CONFIG_NET_CLS_ACT struct tcf_exts old = *dst; - tcf_tree_lock(tp); - dst->nr_actions = src->nr_actions; - dst->actions = src->actions; - dst->type = src->type; - tcf_tree_unlock(tp); - + *dst = *src; tcf_exts_destroy(&old); #endif } @@ -915,7 +954,7 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts) #ifdef CONFIG_NET_CLS_ACT struct nlattr *nest; - if (exts->action && exts->nr_actions) { + if (exts->action && tcf_exts_has_actions(exts)) { /* * again for backward compatible mode - we want * to work with both old and new modes of entering @@ -972,7 +1011,7 @@ int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts, const struct tc_action *a; LIST_HEAD(actions); - if (tc_no_actions(exts)) + if (!tcf_exts_has_actions(exts)) return -EINVAL; tcf_exts_to_list(exts, &actions); @@ -991,10 +1030,10 @@ EXPORT_SYMBOL(tcf_exts_get_dev); static int __init tc_filter_init(void) { - rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_ctl_tfilter, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELTFILTER, tc_ctl_tfilter, NULL, NULL); + rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_ctl_tfilter, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELTFILTER, tc_ctl_tfilter, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETTFILTER, tc_ctl_tfilter, - tc_dump_tfilter, NULL); + tc_dump_tfilter, 0); return 0; } diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index c4fd63a068f98b1288bacebd5f352af6037362b9..d89ebafd22390238b868425cb5a8bbd8dec2c268 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -56,20 +56,18 @@ static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp, return -1; } -static unsigned long basic_get(struct tcf_proto *tp, u32 handle) +static void *basic_get(struct tcf_proto *tp, u32 handle) { - unsigned long l = 0UL; struct basic_head *head = rtnl_dereference(tp->root); struct basic_filter *f; list_for_each_entry(f, &head->flist, link) { if (f->handle == handle) { - l = (unsigned long) f; - break; + return f; } } - return l; + return NULL; } static int basic_init(struct tcf_proto *tp) @@ -106,10 +104,10 @@ static void basic_destroy(struct tcf_proto *tp) kfree_rcu(head, rcu); } -static int basic_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int basic_delete(struct tcf_proto *tp, void *arg, bool *last) { struct basic_head *head = rtnl_dereference(tp->root); - struct basic_filter *f = (struct basic_filter *) arg; + struct basic_filter *f = arg; list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); @@ -129,38 +127,27 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp, struct nlattr *est, bool ovr) { int err; - struct tcf_exts e; - struct tcf_ematch_tree t; - err = tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE); + err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr); if (err < 0) return err; - err = tcf_exts_validate(net, tp, tb, est, &e, ovr); - if (err < 0) - goto errout; - err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &t); + err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &f->ematches); if (err < 0) - goto errout; + return err; if (tb[TCA_BASIC_CLASSID]) { f->res.classid = nla_get_u32(tb[TCA_BASIC_CLASSID]); tcf_bind_filter(tp, &f->res, base); } - tcf_exts_change(tp, &f->exts, &e); - tcf_em_tree_change(tp, &f->ematches, &t); f->tp = tp; - return 0; -errout: - tcf_exts_destroy(&e); - return err; } static int basic_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, - struct nlattr **tca, unsigned long *arg, bool ovr) + struct nlattr **tca, void **arg, bool ovr) { int err; struct basic_head *head = rtnl_dereference(tp->root); @@ -213,7 +200,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, if (err < 0) goto errout; - *arg = (unsigned long)fnew; + *arg = fnew; if (fold) { list_replace_rcu(&fold->link, &fnew->link); @@ -239,7 +226,7 @@ static void basic_walk(struct tcf_proto *tp, struct tcf_walker *arg) if (arg->count < arg->skip) goto skip; - if (arg->fn(tp, (unsigned long) f, arg) < 0) { + if (arg->fn(tp, f, arg) < 0) { arg->stop = 1; break; } @@ -248,10 +235,18 @@ static void basic_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int basic_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static void basic_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct basic_filter *f = fh; + + if (f && f->res.classid == classid) + f->res.class = cl; +} + +static int basic_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { - struct basic_filter *f = (struct basic_filter *) fh; + struct basic_filter *f = fh; struct nlattr *nest; if (f == NULL) @@ -293,6 +288,7 @@ static struct tcf_proto_ops cls_basic_ops __read_mostly = { .delete = basic_delete, .walk = basic_walk, .dump = basic_dump, + .bind_class = basic_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index f57bd531ba98e0661768e347a2e0b80d04affe30..520c5027646aea5146f22d7898acfbc7dee3385a 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -147,24 +147,18 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, enum tc_clsbpf_command cmd) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_cls_bpf_offload bpf_offload = {}; - struct tc_to_netdev offload; + struct tc_cls_bpf_offload cls_bpf = {}; int err; - offload.type = TC_SETUP_CLSBPF; - offload.cls_bpf = &bpf_offload; - - bpf_offload.command = cmd; - bpf_offload.exts = &prog->exts; - bpf_offload.prog = prog->filter; - bpf_offload.name = prog->bpf_name; - bpf_offload.exts_integrated = prog->exts_integrated; - bpf_offload.gen_flags = prog->gen_flags; - - err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, - tp->protocol, &offload); + tc_cls_common_offload_init(&cls_bpf.common, tp); + cls_bpf.command = cmd; + cls_bpf.exts = &prog->exts; + cls_bpf.prog = prog->filter; + cls_bpf.name = prog->bpf_name; + cls_bpf.exts_integrated = prog->exts_integrated; + cls_bpf.gen_flags = prog->gen_flags; + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSBPF, &cls_bpf); if (!err && (cmd == TC_CLSBPF_ADD || cmd == TC_CLSBPF_REPLACE)) prog->gen_flags |= TCA_CLS_FLAGS_IN_HW; @@ -184,7 +178,7 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, (oldprog && tc_skip_sw(oldprog->gen_flags)); if (oldprog && oldprog->offloaded) { - if (tc_should_offload(dev, tp, prog->gen_flags)) { + if (tc_should_offload(dev, prog->gen_flags)) { cmd = TC_CLSBPF_REPLACE; } else if (!tc_skip_sw(prog->gen_flags)) { obj = oldprog; @@ -193,7 +187,7 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, return -EINVAL; } } else { - if (!tc_should_offload(dev, tp, prog->gen_flags)) + if (!tc_should_offload(dev, prog->gen_flags)) return skip_sw ? -EINVAL : 0; cmd = TC_CLSBPF_ADD; } @@ -276,11 +270,11 @@ static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog) call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu); } -static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last) { struct cls_bpf_head *head = rtnl_dereference(tp->root); - __cls_bpf_delete(tp, (struct cls_bpf_prog *) arg); + __cls_bpf_delete(tp, arg); *last = list_empty(&head->plist); return 0; } @@ -296,20 +290,17 @@ static void cls_bpf_destroy(struct tcf_proto *tp) kfree_rcu(head, rcu); } -static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) +static void *cls_bpf_get(struct tcf_proto *tp, u32 handle) { struct cls_bpf_head *head = rtnl_dereference(tp->root); struct cls_bpf_prog *prog; - unsigned long ret = 0UL; list_for_each_entry(prog, &head->plist, link) { - if (prog->handle == handle) { - ret = (unsigned long) prog; - break; - } + if (prog->handle == handle) + return prog; } - return ret; + return NULL; } static int cls_bpf_prog_from_ops(struct nlattr **tb, struct cls_bpf_prog *prog) @@ -382,13 +373,11 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog, return 0; } -static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, - struct cls_bpf_prog *prog, - unsigned long base, struct nlattr **tb, - struct nlattr *est, bool ovr) +static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp, + struct cls_bpf_prog *prog, unsigned long base, + struct nlattr **tb, struct nlattr *est, bool ovr) { bool is_bpf, is_ebpf, have_exts = false; - struct tcf_exts exts; u32 gen_flags = 0; int ret; @@ -397,30 +386,23 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) return -EINVAL; - ret = tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE); + ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr); if (ret < 0) return ret; - ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr); - if (ret < 0) - goto errout; if (tb[TCA_BPF_FLAGS]) { u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]); - if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) { - ret = -EINVAL; - goto errout; - } + if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) + return -EINVAL; have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT; } if (tb[TCA_BPF_FLAGS_GEN]) { gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]); if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || - !tc_flags_valid(gen_flags)) { - ret = -EINVAL; - goto errout; - } + !tc_flags_valid(gen_flags)) + return -EINVAL; } prog->exts_integrated = have_exts; @@ -429,19 +411,14 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) : cls_bpf_prog_from_efd(tb, prog, tp); if (ret < 0) - goto errout; + return ret; if (tb[TCA_BPF_CLASSID]) { prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]); tcf_bind_filter(tp, &prog->res, base); } - tcf_exts_change(tp, &prog->exts, &exts); return 0; - -errout: - tcf_exts_destroy(&exts); - return ret; } static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp, @@ -468,10 +445,10 @@ static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp, static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - unsigned long *arg, bool ovr) + void **arg, bool ovr) { struct cls_bpf_head *head = rtnl_dereference(tp->root); - struct cls_bpf_prog *oldprog = (struct cls_bpf_prog *) *arg; + struct cls_bpf_prog *oldprog = *arg; struct nlattr *tb[TCA_BPF_MAX + 1]; struct cls_bpf_prog *prog; int ret; @@ -508,8 +485,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, goto errout; } - ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE], - ovr); + ret = cls_bpf_set_parms(net, tp, prog, base, tb, tca[TCA_RATE], ovr); if (ret < 0) goto errout; @@ -530,7 +506,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, list_add_rcu(&prog->link, &head->plist); } - *arg = (unsigned long) prog; + *arg = prog; return 0; errout: @@ -578,10 +554,10 @@ static int cls_bpf_dump_ebpf_info(const struct cls_bpf_prog *prog, return 0; } -static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *tm) { - struct cls_bpf_prog *prog = (struct cls_bpf_prog *) fh; + struct cls_bpf_prog *prog = fh; struct nlattr *nest; u32 bpf_flags = 0; int ret; @@ -631,6 +607,14 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void cls_bpf_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct cls_bpf_prog *prog = fh; + + if (prog && prog->res.classid == classid) + prog->res.class = cl; +} + static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg) { struct cls_bpf_head *head = rtnl_dereference(tp->root); @@ -639,7 +623,7 @@ static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg) list_for_each_entry(prog, &head->plist, link) { if (arg->count < arg->skip) goto skip; - if (arg->fn(tp, (unsigned long) prog, arg) < 0) { + if (arg->fn(tp, prog, arg) < 0) { arg->stop = 1; break; } @@ -659,6 +643,7 @@ static struct tcf_proto_ops cls_bpf_ops __read_mostly = { .delete = cls_bpf_delete, .walk = cls_bpf_walk, .dump = cls_bpf_dump, + .bind_class = cls_bpf_bind_class, }; static int __init cls_bpf_init_mod(void) diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 12ce547eea04dfb57d3f47540b57e8150a8ebca4..d48452f8797528dd7ada96dae61a82b3905aa0de 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -43,9 +43,9 @@ static int cls_cgroup_classify(struct sk_buff *skb, const struct tcf_proto *tp, return tcf_exts_exec(skb, &head->exts, res); } -static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) +static void *cls_cgroup_get(struct tcf_proto *tp, u32 handle) { - return 0UL; + return NULL; } static int cls_cgroup_init(struct tcf_proto *tp) @@ -71,13 +71,11 @@ static void cls_cgroup_destroy_rcu(struct rcu_head *root) static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - unsigned long *arg, bool ovr) + void **arg, bool ovr) { struct nlattr *tb[TCA_CGROUP_MAX + 1]; struct cls_cgroup_head *head = rtnl_dereference(tp->root); struct cls_cgroup_head *new; - struct tcf_ematch_tree t; - struct tcf_exts e; int err; if (!tca[TCA_OPTIONS]) @@ -103,23 +101,13 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, if (err < 0) goto errout; - err = tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE); + err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &new->exts, ovr); if (err < 0) goto errout; - err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr); - if (err < 0) { - tcf_exts_destroy(&e); - goto errout; - } - err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t); - if (err < 0) { - tcf_exts_destroy(&e); + err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &new->ematches); + if (err < 0) goto errout; - } - - tcf_exts_change(tp, &new->exts, &e); - tcf_em_tree_change(tp, &new->ematches, &t); rcu_assign_pointer(tp->root, new); if (head) @@ -140,7 +128,7 @@ static void cls_cgroup_destroy(struct tcf_proto *tp) call_rcu(&head->rcu, cls_cgroup_destroy_rcu); } -static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int cls_cgroup_delete(struct tcf_proto *tp, void *arg, bool *last) { return -EOPNOTSUPP; } @@ -152,7 +140,7 @@ static void cls_cgroup_walk(struct tcf_proto *tp, struct tcf_walker *arg) if (arg->count < arg->skip) goto skip; - if (arg->fn(tp, (unsigned long) head, arg) < 0) { + if (arg->fn(tp, head, arg) < 0) { arg->stop = 1; return; } @@ -160,7 +148,7 @@ static void cls_cgroup_walk(struct tcf_proto *tp, struct tcf_walker *arg) arg->count++; } -static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { struct cls_cgroup_head *head = rtnl_dereference(tp->root); diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 3065752b9cda59e4cb2555acfe2ae26722152ffc..2a3a60ec5b8617c48e58d8a9339cda69be68442f 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -382,14 +382,12 @@ static void flow_destroy_filter(struct rcu_head *head) static int flow_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - unsigned long *arg, bool ovr) + void **arg, bool ovr) { struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *fold, *fnew; struct nlattr *opt = tca[TCA_OPTIONS]; struct nlattr *tb[TCA_FLOW_MAX + 1]; - struct tcf_exts e; - struct tcf_ematch_tree t; unsigned int nkeys = 0; unsigned int perturb_period = 0; u32 baseclass = 0; @@ -425,31 +423,27 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, return -EOPNOTSUPP; } - err = tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE); - if (err < 0) - goto err1; - err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr); - if (err < 0) - goto err1; + fnew = kzalloc(sizeof(*fnew), GFP_KERNEL); + if (!fnew) + return -ENOBUFS; - err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &t); + err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &fnew->ematches); if (err < 0) goto err1; - err = -ENOBUFS; - fnew = kzalloc(sizeof(*fnew), GFP_KERNEL); - if (!fnew) + err = tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE); + if (err < 0) goto err2; - err = tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE); + err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &fnew->exts, ovr); if (err < 0) - goto err3; + goto err2; - fold = (struct flow_filter *)*arg; + fold = *arg; if (fold) { err = -EINVAL; if (fold->handle != handle && handle) - goto err3; + goto err2; /* Copy fold into fnew */ fnew->tp = fold->tp; @@ -469,31 +463,31 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, if (tb[TCA_FLOW_MODE]) mode = nla_get_u32(tb[TCA_FLOW_MODE]); if (mode != FLOW_MODE_HASH && nkeys > 1) - goto err3; + goto err2; if (mode == FLOW_MODE_HASH) perturb_period = fold->perturb_period; if (tb[TCA_FLOW_PERTURB]) { if (mode != FLOW_MODE_HASH) - goto err3; + goto err2; perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ; } } else { err = -EINVAL; if (!handle) - goto err3; + goto err2; if (!tb[TCA_FLOW_KEYS]) - goto err3; + goto err2; mode = FLOW_MODE_MAP; if (tb[TCA_FLOW_MODE]) mode = nla_get_u32(tb[TCA_FLOW_MODE]); if (mode != FLOW_MODE_HASH && nkeys > 1) - goto err3; + goto err2; if (tb[TCA_FLOW_PERTURB]) { if (mode != FLOW_MODE_HASH) - goto err3; + goto err2; perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ; } @@ -511,9 +505,6 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, setup_deferrable_timer(&fnew->perturb_timer, flow_perturbation, (unsigned long)fnew); - tcf_exts_change(tp, &fnew->exts, &e); - tcf_em_tree_change(tp, &fnew->ematches, &t); - netif_keep_dst(qdisc_dev(tp->q)); if (tb[TCA_FLOW_KEYS]) { @@ -541,31 +532,29 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, if (perturb_period) mod_timer(&fnew->perturb_timer, jiffies + perturb_period); - if (*arg == 0) + if (!*arg) list_add_tail_rcu(&fnew->list, &head->filters); else list_replace_rcu(&fold->list, &fnew->list); - *arg = (unsigned long)fnew; + *arg = fnew; if (fold) call_rcu(&fold->rcu, flow_destroy_filter); return 0; -err3: - tcf_exts_destroy(&fnew->exts); err2: - tcf_em_tree_destroy(&t); - kfree(fnew); + tcf_exts_destroy(&fnew->exts); + tcf_em_tree_destroy(&fnew->ematches); err1: - tcf_exts_destroy(&e); + kfree(fnew); return err; } -static int flow_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int flow_delete(struct tcf_proto *tp, void *arg, bool *last) { struct flow_head *head = rtnl_dereference(tp->root); - struct flow_filter *f = (struct flow_filter *)arg; + struct flow_filter *f = arg; list_del_rcu(&f->list); call_rcu(&f->rcu, flow_destroy_filter); @@ -597,21 +586,21 @@ static void flow_destroy(struct tcf_proto *tp) kfree_rcu(head, rcu); } -static unsigned long flow_get(struct tcf_proto *tp, u32 handle) +static void *flow_get(struct tcf_proto *tp, u32 handle) { struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *f; list_for_each_entry(f, &head->filters, list) if (f->handle == handle) - return (unsigned long)f; - return 0; + return f; + return NULL; } -static int flow_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int flow_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { - struct flow_filter *f = (struct flow_filter *)fh; + struct flow_filter *f = fh; struct nlattr *nest; if (f == NULL) @@ -677,7 +666,7 @@ static void flow_walk(struct tcf_proto *tp, struct tcf_walker *arg) list_for_each_entry(f, &head->filters, list) { if (arg->count < arg->skip) goto skip; - if (arg->fn(tp, (unsigned long)f, arg) < 0) { + if (arg->fn(tp, f, arg) < 0) { arg->stop = 1; break; } diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 7832eb93379b3907c2b42d9cd304cfa998237396..d230cb4c809454137968be4bb1537d92bc8ebc5d 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -68,7 +68,6 @@ struct cls_fl_head { struct rhashtable ht; struct fl_flow_mask mask; struct flow_dissector dissector; - u32 hgen; bool mask_assigned; struct list_head filters; struct rhashtable_params ht_params; @@ -76,6 +75,7 @@ struct cls_fl_head { struct work_struct work; struct rcu_head rcu; }; + struct idr handle_idr; }; struct cls_fl_filter { @@ -88,7 +88,6 @@ struct cls_fl_filter { u32 handle; u32 flags; struct rcu_head rcu; - struct tc_to_netdev tc; struct net_device *hw_dev; }; @@ -211,6 +210,7 @@ static int fl_init(struct tcf_proto *tp) INIT_LIST_HEAD_RCU(&head->filters); rcu_assign_pointer(tp->root, head); + idr_init(&head->handle_idr); return 0; } @@ -225,22 +225,17 @@ static void fl_destroy_filter(struct rcu_head *head) static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f) { - struct tc_cls_flower_offload offload = {0}; + struct tc_cls_flower_offload cls_flower = {}; struct net_device *dev = f->hw_dev; - struct tc_to_netdev *tc = &f->tc; - if (!tc_can_offload(dev, tp)) + if (!tc_can_offload(dev)) return; - offload.command = TC_CLSFLOWER_DESTROY; - offload.prio = tp->prio; - offload.cookie = (unsigned long)f; + tc_cls_common_offload_init(&cls_flower.common, tp); + cls_flower.command = TC_CLSFLOWER_DESTROY; + cls_flower.cookie = (unsigned long) f; - tc->type = TC_SETUP_CLSFLOWER; - tc->cls_flower = &offload; - - dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->chain->index, - tp->protocol, tc); + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER, &cls_flower); } static int fl_hw_replace_filter(struct tcf_proto *tp, @@ -249,35 +244,31 @@ static int fl_hw_replace_filter(struct tcf_proto *tp, struct cls_fl_filter *f) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_cls_flower_offload offload = {0}; - struct tc_to_netdev *tc = &f->tc; + struct tc_cls_flower_offload cls_flower = {}; int err; - if (!tc_can_offload(dev, tp)) { + if (!tc_can_offload(dev)) { if (tcf_exts_get_dev(dev, &f->exts, &f->hw_dev) || - (f->hw_dev && !tc_can_offload(f->hw_dev, tp))) { + (f->hw_dev && !tc_can_offload(f->hw_dev))) { f->hw_dev = dev; return tc_skip_sw(f->flags) ? -EINVAL : 0; } dev = f->hw_dev; - tc->egress_dev = true; + cls_flower.egress_dev = true; } else { f->hw_dev = dev; } - offload.command = TC_CLSFLOWER_REPLACE; - offload.prio = tp->prio; - offload.cookie = (unsigned long)f; - offload.dissector = dissector; - offload.mask = mask; - offload.key = &f->mkey; - offload.exts = &f->exts; - - tc->type = TC_SETUP_CLSFLOWER; - tc->cls_flower = &offload; + tc_cls_common_offload_init(&cls_flower.common, tp); + cls_flower.command = TC_CLSFLOWER_REPLACE; + cls_flower.cookie = (unsigned long) f; + cls_flower.dissector = dissector; + cls_flower.mask = mask; + cls_flower.key = &f->mkey; + cls_flower.exts = &f->exts; - err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, tp->protocol, tc); + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER, + &cls_flower); if (!err) f->flags |= TCA_CLS_FLAGS_IN_HW; @@ -288,27 +279,26 @@ static int fl_hw_replace_filter(struct tcf_proto *tp, static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f) { - struct tc_cls_flower_offload offload = {0}; + struct tc_cls_flower_offload cls_flower = {}; struct net_device *dev = f->hw_dev; - struct tc_to_netdev *tc = &f->tc; - if (!tc_can_offload(dev, tp)) + if (!tc_can_offload(dev)) return; - offload.command = TC_CLSFLOWER_STATS; - offload.prio = tp->prio; - offload.cookie = (unsigned long)f; - offload.exts = &f->exts; - - tc->type = TC_SETUP_CLSFLOWER; - tc->cls_flower = &offload; + tc_cls_common_offload_init(&cls_flower.common, tp); + cls_flower.command = TC_CLSFLOWER_STATS; + cls_flower.cookie = (unsigned long) f; + cls_flower.exts = &f->exts; - dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, tp->protocol, tc); + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER, + &cls_flower); } static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f) { + struct cls_fl_head *head = rtnl_dereference(tp->root); + + idr_remove_ext(&head->handle_idr, f->handle); list_del_rcu(&f->list); if (!tc_skip_hw(f->flags)) fl_hw_destroy_filter(tp, f); @@ -341,20 +331,17 @@ static void fl_destroy(struct tcf_proto *tp) list_for_each_entry_safe(f, next, &head->filters, list) __fl_delete(tp, f); + idr_destroy(&head->handle_idr); __module_get(THIS_MODULE); call_rcu(&head->rcu, fl_destroy_rcu); } -static unsigned long fl_get(struct tcf_proto *tp, u32 handle) +static void *fl_get(struct tcf_proto *tp, u32 handle) { struct cls_fl_head *head = rtnl_dereference(tp->root); - struct cls_fl_filter *f; - list_for_each_entry(f, &head->filters, list) - if (f->handle == handle) - return (unsigned long) f; - return 0; + return idr_find_ext(&head->handle_idr, handle); } static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { @@ -852,15 +839,11 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, struct nlattr **tb, struct nlattr *est, bool ovr) { - struct tcf_exts e; int err; - err = tcf_exts_init(&e, TCA_FLOWER_ACT, 0); + err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr); if (err < 0) return err; - err = tcf_exts_validate(net, tp, tb, est, &e, ovr); - if (err < 0) - goto errout; if (tb[TCA_FLOWER_CLASSID]) { f->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]); @@ -869,50 +852,25 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp, err = fl_set_key(net, tb, &f->key, &mask->key); if (err) - goto errout; + return err; fl_mask_update_range(mask); fl_set_masked_key(&f->mkey, &f->key, mask); - tcf_exts_change(tp, &f->exts, &e); - return 0; -errout: - tcf_exts_destroy(&e); - return err; -} - -static u32 fl_grab_new_handle(struct tcf_proto *tp, - struct cls_fl_head *head) -{ - unsigned int i = 0x80000000; - u32 handle; - - do { - if (++head->hgen == 0x7FFFFFFF) - head->hgen = 1; - } while (--i > 0 && fl_get(tp, head->hgen)); - - if (unlikely(i == 0)) { - pr_err("Insufficient number of handles\n"); - handle = 0; - } else { - handle = head->hgen; - } - - return handle; } static int fl_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - unsigned long *arg, bool ovr) + void **arg, bool ovr) { struct cls_fl_head *head = rtnl_dereference(tp->root); - struct cls_fl_filter *fold = (struct cls_fl_filter *) *arg; + struct cls_fl_filter *fold = *arg; struct cls_fl_filter *fnew; struct nlattr **tb; struct fl_flow_mask mask = {}; + unsigned long idr_index; int err; if (!tca[TCA_OPTIONS]) @@ -943,41 +901,49 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, goto errout; if (!handle) { - handle = fl_grab_new_handle(tp, head); - if (!handle) { - err = -EINVAL; + err = idr_alloc_ext(&head->handle_idr, fnew, &idr_index, + 1, 0x80000000, GFP_KERNEL); + if (err) goto errout; - } + fnew->handle = idr_index; + } + + /* user specifies a handle and it doesn't exist */ + if (handle && !fold) { + err = idr_alloc_ext(&head->handle_idr, fnew, &idr_index, + handle, handle + 1, GFP_KERNEL); + if (err) + goto errout; + fnew->handle = idr_index; } - fnew->handle = handle; if (tb[TCA_FLOWER_FLAGS]) { fnew->flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]); if (!tc_flags_valid(fnew->flags)) { err = -EINVAL; - goto errout; + goto errout_idr; } } err = fl_set_parms(net, tp, fnew, &mask, base, tb, tca[TCA_RATE], ovr); if (err) - goto errout; + goto errout_idr; err = fl_check_assign_mask(head, &mask); if (err) - goto errout; + goto errout_idr; if (!tc_skip_sw(fnew->flags)) { if (!fold && fl_lookup(head, &fnew->mkey)) { err = -EEXIST; - goto errout; + goto errout_idr; } err = rhashtable_insert_fast(&head->ht, &fnew->ht_node, head->ht_params); if (err) - goto errout; + goto errout_idr; } if (!tc_skip_hw(fnew->flags)) { @@ -986,7 +952,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, &mask.key, fnew); if (err) - goto errout; + goto errout_idr; } if (!tc_in_hw(fnew->flags)) @@ -1000,9 +966,11 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, fl_hw_destroy_filter(tp, fold); } - *arg = (unsigned long) fnew; + *arg = fnew; if (fold) { + fnew->handle = handle; + idr_replace_ext(&head->handle_idr, fnew, fnew->handle); list_replace_rcu(&fold->list, &fnew->list); tcf_unbind_filter(tp, &fold->res); call_rcu(&fold->rcu, fl_destroy_filter); @@ -1013,6 +981,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, kfree(tb); return 0; +errout_idr: + if (fnew->handle) + idr_remove_ext(&head->handle_idr, fnew->handle); errout: tcf_exts_destroy(&fnew->exts); kfree(fnew); @@ -1021,10 +992,10 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, return err; } -static int fl_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int fl_delete(struct tcf_proto *tp, void *arg, bool *last) { struct cls_fl_head *head = rtnl_dereference(tp->root); - struct cls_fl_filter *f = (struct cls_fl_filter *) arg; + struct cls_fl_filter *f = arg; if (!tc_skip_sw(f->flags)) rhashtable_remove_fast(&head->ht, &f->ht_node, @@ -1042,7 +1013,7 @@ static void fl_walk(struct tcf_proto *tp, struct tcf_walker *arg) list_for_each_entry_rcu(f, &head->filters, list) { if (arg->count < arg->skip) goto skip; - if (arg->fn(tp, (unsigned long) f, arg) < 0) { + if (arg->fn(tp, f, arg) < 0) { arg->stop = 1; break; } @@ -1177,11 +1148,11 @@ static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask) return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask); } -static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { struct cls_fl_head *head = rtnl_dereference(tp->root); - struct cls_fl_filter *f = (struct cls_fl_filter *) fh; + struct cls_fl_filter *f = fh; struct nlattr *nest; struct fl_flow_key *key, *mask; @@ -1383,6 +1354,14 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void fl_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct cls_fl_filter *f = fh; + + if (f && f->res.classid == classid) + f->res.class = cl; +} + static struct tcf_proto_ops cls_fl_ops __read_mostly = { .kind = "flower", .classify = fl_classify, @@ -1393,6 +1372,7 @@ static struct tcf_proto_ops cls_fl_ops __read_mostly = { .delete = fl_delete, .walk = fl_walk, .dump = fl_dump, + .bind_class = fl_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index d3885362e017e1b477c6c2e4d8abea4b1e021c53..941245ad07fd4b8bb4fd97cd84fac8791c571276 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -95,20 +95,20 @@ static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, return -1; } -static unsigned long fw_get(struct tcf_proto *tp, u32 handle) +static void *fw_get(struct tcf_proto *tp, u32 handle) { struct fw_head *head = rtnl_dereference(tp->root); struct fw_filter *f; if (head == NULL) - return 0; + return NULL; f = rtnl_dereference(head->ht[fw_hash(handle)]); for (; f; f = rtnl_dereference(f->next)) { if (f->id == handle) - return (unsigned long)f; + return f; } - return 0; + return NULL; } static int fw_init(struct tcf_proto *tp) @@ -147,10 +147,10 @@ static void fw_destroy(struct tcf_proto *tp) kfree_rcu(head, rcu); } -static int fw_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int fw_delete(struct tcf_proto *tp, void *arg, bool *last) { struct fw_head *head = rtnl_dereference(tp->root); - struct fw_filter *f = (struct fw_filter *)arg; + struct fw_filter *f = arg; struct fw_filter __rcu **fp; struct fw_filter *pfp; int ret = -EINVAL; @@ -190,22 +190,17 @@ static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = { [TCA_FW_MASK] = { .type = NLA_U32 }, }; -static int -fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, - struct nlattr **tb, struct nlattr **tca, unsigned long base, - bool ovr) +static int fw_set_parms(struct net *net, struct tcf_proto *tp, + struct fw_filter *f, struct nlattr **tb, + struct nlattr **tca, unsigned long base, bool ovr) { struct fw_head *head = rtnl_dereference(tp->root); - struct tcf_exts e; u32 mask; int err; - err = tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE); + err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, ovr); if (err < 0) return err; - err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr); - if (err < 0) - goto errout; if (tb[TCA_FW_CLASSID]) { f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); @@ -216,10 +211,8 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, if (tb[TCA_FW_INDEV]) { int ret; ret = tcf_change_indev(net, tb[TCA_FW_INDEV]); - if (ret < 0) { - err = ret; - goto errout; - } + if (ret < 0) + return ret; f->ifindex = ret; } #endif /* CONFIG_NET_CLS_IND */ @@ -228,25 +221,20 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, if (tb[TCA_FW_MASK]) { mask = nla_get_u32(tb[TCA_FW_MASK]); if (mask != head->mask) - goto errout; + return err; } else if (head->mask != 0xFFFFFFFF) - goto errout; - - tcf_exts_change(tp, &f->exts, &e); + return err; return 0; -errout: - tcf_exts_destroy(&e); - return err; } static int fw_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, - u32 handle, struct nlattr **tca, unsigned long *arg, + u32 handle, struct nlattr **tca, void **arg, bool ovr) { struct fw_head *head = rtnl_dereference(tp->root); - struct fw_filter *f = (struct fw_filter *) *arg; + struct fw_filter *f = *arg; struct nlattr *opt = tca[TCA_OPTIONS]; struct nlattr *tb[TCA_FW_MAX + 1]; int err; @@ -282,7 +270,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, return err; } - err = fw_change_attrs(net, tp, fnew, tb, tca, base, ovr); + err = fw_set_parms(net, tp, fnew, tb, tca, base, ovr); if (err < 0) { tcf_exts_destroy(&fnew->exts); kfree(fnew); @@ -300,7 +288,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, tcf_unbind_filter(tp, &f->res); call_rcu(&f->rcu, fw_delete_filter); - *arg = (unsigned long)fnew; + *arg = fnew; return err; } @@ -330,14 +318,14 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, f->id = handle; f->tp = tp; - err = fw_change_attrs(net, tp, f, tb, tca, base, ovr); + err = fw_set_parms(net, tp, f, tb, tca, base, ovr); if (err < 0) goto errout; RCU_INIT_POINTER(f->next, head->ht[fw_hash(handle)]); rcu_assign_pointer(head->ht[fw_hash(handle)], f); - *arg = (unsigned long)f; + *arg = f; return 0; errout: @@ -366,7 +354,7 @@ static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg) arg->count++; continue; } - if (arg->fn(tp, (unsigned long)f, arg) < 0) { + if (arg->fn(tp, f, arg) < 0) { arg->stop = 1; return; } @@ -375,11 +363,11 @@ static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int fw_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { struct fw_head *head = rtnl_dereference(tp->root); - struct fw_filter *f = (struct fw_filter *)fh; + struct fw_filter *f = fh; struct nlattr *nest; if (f == NULL) @@ -387,7 +375,7 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, t->tcm_handle = f->id; - if (!f->res.classid && !tcf_exts_is_available(&f->exts)) + if (!f->res.classid && !tcf_exts_has_actions(&f->exts)) return skb->len; nest = nla_nest_start(skb, TCA_OPTIONS); @@ -424,6 +412,14 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void fw_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct fw_filter *f = fh; + + if (f && f->res.classid == classid) + f->res.class = cl; +} + static struct tcf_proto_ops cls_fw_ops __read_mostly = { .kind = "fw", .classify = fw_classify, @@ -434,6 +430,7 @@ static struct tcf_proto_ops cls_fw_ops __read_mostly = { .delete = fw_delete, .walk = fw_walk, .dump = fw_dump, + .bind_class = fw_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index 9dc26c32cf321e475a8f783cf423ff67562479fa..eeac606c95abe99ca3f24ab462589adbe7c86388 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -32,6 +32,7 @@ static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp, if (tc_skip_sw(head->flags)) return -1; + *res = head->res; return tcf_exts_exec(skb, &head->exts, res); } @@ -54,19 +55,16 @@ static int mall_replace_hw_filter(struct tcf_proto *tp, unsigned long cookie) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_to_netdev offload; - struct tc_cls_matchall_offload mall_offload = {0}; + struct tc_cls_matchall_offload cls_mall = {}; int err; - offload.type = TC_SETUP_MATCHALL; - offload.cls_mall = &mall_offload; - offload.cls_mall->command = TC_CLSMATCHALL_REPLACE; - offload.cls_mall->exts = &head->exts; - offload.cls_mall->cookie = cookie; + tc_cls_common_offload_init(&cls_mall.common, tp); + cls_mall.command = TC_CLSMATCHALL_REPLACE; + cls_mall.exts = &head->exts; + cls_mall.cookie = cookie; - err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, - tp->protocol, &offload); + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSMATCHALL, + &cls_mall); if (!err) head->flags |= TCA_CLS_FLAGS_IN_HW; @@ -78,17 +76,13 @@ static void mall_destroy_hw_filter(struct tcf_proto *tp, unsigned long cookie) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_to_netdev offload; - struct tc_cls_matchall_offload mall_offload = {0}; + struct tc_cls_matchall_offload cls_mall = {}; - offload.type = TC_SETUP_MATCHALL; - offload.cls_mall = &mall_offload; - offload.cls_mall->command = TC_CLSMATCHALL_DESTROY; - offload.cls_mall->exts = NULL; - offload.cls_mall->cookie = cookie; + tc_cls_common_offload_init(&cls_mall.common, tp); + cls_mall.command = TC_CLSMATCHALL_DESTROY; + cls_mall.cookie = cookie; - dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->chain->index, - tp->protocol, &offload); + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSMATCHALL, &cls_mall); } static void mall_destroy(struct tcf_proto *tp) @@ -99,15 +93,15 @@ static void mall_destroy(struct tcf_proto *tp) if (!head) return; - if (tc_should_offload(dev, tp, head->flags)) + if (tc_should_offload(dev, head->flags)) mall_destroy_hw_filter(tp, head, (unsigned long) head); call_rcu(&head->rcu, mall_destroy_rcu); } -static unsigned long mall_get(struct tcf_proto *tp, u32 handle) +static void *mall_get(struct tcf_proto *tp, u32 handle) { - return 0UL; + return NULL; } static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = { @@ -120,33 +114,23 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, struct nlattr **tb, struct nlattr *est, bool ovr) { - struct tcf_exts e; int err; - err = tcf_exts_init(&e, TCA_MATCHALL_ACT, 0); - if (err) - return err; - err = tcf_exts_validate(net, tp, tb, est, &e, ovr); + err = tcf_exts_validate(net, tp, tb, est, &head->exts, ovr); if (err < 0) - goto errout; + return err; if (tb[TCA_MATCHALL_CLASSID]) { head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]); tcf_bind_filter(tp, &head->res, base); } - - tcf_exts_change(tp, &head->exts, &e); - return 0; -errout: - tcf_exts_destroy(&e); - return err; } static int mall_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - unsigned long *arg, bool ovr) + void **arg, bool ovr) { struct cls_mall_head *head = rtnl_dereference(tp->root); struct net_device *dev = tp->q->dev_queue->dev; @@ -189,7 +173,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, if (err) goto err_set_parms; - if (tc_should_offload(dev, tp, flags)) { + if (tc_should_offload(dev, flags)) { err = mall_replace_hw_filter(tp, new, (unsigned long) new); if (err) { if (tc_skip_sw(flags)) @@ -202,7 +186,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, if (!tc_in_hw(new->flags)) new->flags |= TCA_CLS_FLAGS_NOT_IN_HW; - *arg = (unsigned long) head; + *arg = head; rcu_assign_pointer(tp->root, new); return 0; @@ -214,7 +198,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, return err; } -static int mall_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int mall_delete(struct tcf_proto *tp, void *arg, bool *last) { return -EOPNOTSUPP; } @@ -225,16 +209,16 @@ static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg) if (arg->count < arg->skip) goto skip; - if (arg->fn(tp, (unsigned long) head, arg) < 0) + if (arg->fn(tp, head, arg) < 0) arg->stop = 1; skip: arg->count++; } -static int mall_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int mall_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { - struct cls_mall_head *head = (struct cls_mall_head *) fh; + struct cls_mall_head *head = fh; struct nlattr *nest; if (!head) @@ -268,6 +252,14 @@ static int mall_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void mall_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct cls_mall_head *head = fh; + + if (head && head->res.classid == classid) + head->res.class = cl; +} + static struct tcf_proto_ops cls_mall_ops __read_mostly = { .kind = "matchall", .classify = mall_classify, @@ -278,6 +270,7 @@ static struct tcf_proto_ops cls_mall_ops __read_mostly = { .delete = mall_delete, .walk = mall_walk, .dump = mall_dump, + .bind_class = mall_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index d63d5502ee020350e72b818c5607000a21df915a..9ddde65915d22615aa93036f01ae0368783c94f6 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -113,7 +113,7 @@ static inline int route4_hash_wild(void) #define ROUTE4_APPLY_RESULT() \ { \ *res = f->res; \ - if (tcf_exts_is_available(&f->exts)) { \ + if (tcf_exts_has_actions(&f->exts)) { \ int r = tcf_exts_exec(skb, &f->exts, res); \ if (r < 0) { \ dont_cache = 1; \ @@ -216,7 +216,7 @@ static inline u32 from_hash(u32 id) return 16 + (id & 0xF); } -static unsigned long route4_get(struct tcf_proto *tp, u32 handle) +static void *route4_get(struct tcf_proto *tp, u32 handle) { struct route4_head *head = rtnl_dereference(tp->root); struct route4_bucket *b; @@ -225,11 +225,11 @@ static unsigned long route4_get(struct tcf_proto *tp, u32 handle) h1 = to_hash(handle); if (h1 > 256) - return 0; + return NULL; h2 = from_hash(handle >> 16); if (h2 > 32) - return 0; + return NULL; b = rtnl_dereference(head->table[h1]); if (b) { @@ -237,9 +237,9 @@ static unsigned long route4_get(struct tcf_proto *tp, u32 handle) f; f = rtnl_dereference(f->next)) if (f->handle == handle) - return (unsigned long)f; + return f; } - return 0; + return NULL; } static int route4_init(struct tcf_proto *tp) @@ -294,10 +294,10 @@ static void route4_destroy(struct tcf_proto *tp) kfree_rcu(head, rcu); } -static int route4_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int route4_delete(struct tcf_proto *tp, void *arg, bool *last) { struct route4_head *head = rtnl_dereference(tp->root); - struct route4_filter *f = (struct route4_filter *)arg; + struct route4_filter *f = arg; struct route4_filter __rcu **fp; struct route4_filter *nf; struct route4_bucket *b; @@ -372,37 +372,32 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp, struct route4_filter *fp; unsigned int h1; struct route4_bucket *b; - struct tcf_exts e; int err; - err = tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE); + err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr); if (err < 0) return err; - err = tcf_exts_validate(net, tp, tb, est, &e, ovr); - if (err < 0) - goto errout; - err = -EINVAL; if (tb[TCA_ROUTE4_TO]) { if (new && handle & 0x8000) - goto errout; + return -EINVAL; to = nla_get_u32(tb[TCA_ROUTE4_TO]); if (to > 0xFF) - goto errout; + return -EINVAL; nhandle = to; } if (tb[TCA_ROUTE4_FROM]) { if (tb[TCA_ROUTE4_IIF]) - goto errout; + return -EINVAL; id = nla_get_u32(tb[TCA_ROUTE4_FROM]); if (id > 0xFF) - goto errout; + return -EINVAL; nhandle |= id << 16; } else if (tb[TCA_ROUTE4_IIF]) { id = nla_get_u32(tb[TCA_ROUTE4_IIF]); if (id > 0x7FFF) - goto errout; + return -EINVAL; nhandle |= (id | 0x8000) << 16; } else nhandle |= 0xFFFF << 16; @@ -410,27 +405,25 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp, if (handle && new) { nhandle |= handle & 0x7F00; if (nhandle != handle) - goto errout; + return -EINVAL; } h1 = to_hash(nhandle); b = rtnl_dereference(head->table[h1]); if (!b) { - err = -ENOBUFS; b = kzalloc(sizeof(struct route4_bucket), GFP_KERNEL); if (b == NULL) - goto errout; + return -ENOBUFS; rcu_assign_pointer(head->table[h1], b); } else { unsigned int h2 = from_hash(nhandle >> 16); - err = -EEXIST; for (fp = rtnl_dereference(b->ht[h2]); fp; fp = rtnl_dereference(fp->next)) if (fp->handle == f->handle) - goto errout; + return -EEXIST; } if (tb[TCA_ROUTE4_TO]) @@ -450,17 +443,12 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp, tcf_bind_filter(tp, &f->res, base); } - tcf_exts_change(tp, &f->exts, &e); - return 0; -errout: - tcf_exts_destroy(&e); - return err; } static int route4_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, - struct nlattr **tca, unsigned long *arg, bool ovr) + struct nlattr **tca, void **arg, bool ovr) { struct route4_head *head = rtnl_dereference(tp->root); struct route4_filter __rcu **fp; @@ -479,7 +467,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, if (err < 0) return err; - fold = (struct route4_filter *)*arg; + fold = *arg; if (fold && handle && fold->handle != handle) return -EINVAL; @@ -537,7 +525,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, } route4_reset_fastmap(head); - *arg = (unsigned long)f; + *arg = f; if (fold) { tcf_unbind_filter(tp, &fold->res); call_rcu(&fold->rcu, route4_delete_filter); @@ -576,7 +564,7 @@ static void route4_walk(struct tcf_proto *tp, struct tcf_walker *arg) arg->count++; continue; } - if (arg->fn(tp, (unsigned long)f, arg) < 0) { + if (arg->fn(tp, f, arg) < 0) { arg->stop = 1; return; } @@ -587,10 +575,10 @@ static void route4_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int route4_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { - struct route4_filter *f = (struct route4_filter *)fh; + struct route4_filter *f = fh; struct nlattr *nest; u32 id; @@ -636,6 +624,14 @@ static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void route4_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct route4_filter *f = fh; + + if (f && f->res.classid == classid) + f->res.class = cl; +} + static struct tcf_proto_ops cls_route4_ops __read_mostly = { .kind = "route", .classify = route4_classify, @@ -646,6 +642,7 @@ static struct tcf_proto_ops cls_route4_ops __read_mostly = { .delete = route4_delete, .walk = route4_walk, .dump = route4_dump, + .bind_class = route4_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 0d9d077986992926a79af6236b8840181517679d..b1f6ed48bc729b9238d1a3502c147ca856b3a996 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -248,7 +248,7 @@ static void rsvp_replace(struct tcf_proto *tp, struct rsvp_filter *n, u32 h) BUG_ON(1); } -static unsigned long rsvp_get(struct tcf_proto *tp, u32 handle) +static void *rsvp_get(struct tcf_proto *tp, u32 handle) { struct rsvp_head *head = rtnl_dereference(tp->root); struct rsvp_session *s; @@ -257,17 +257,17 @@ static unsigned long rsvp_get(struct tcf_proto *tp, u32 handle) unsigned int h2 = (handle >> 8) & 0xFF; if (h2 > 16) - return 0; + return NULL; for (s = rtnl_dereference(head->ht[h1]); s; s = rtnl_dereference(s->next)) { for (f = rtnl_dereference(s->ht[h2]); f; f = rtnl_dereference(f->next)) { if (f->handle == handle) - return (unsigned long)f; + return f; } } - return 0; + return NULL; } static int rsvp_init(struct tcf_proto *tp) @@ -328,10 +328,10 @@ static void rsvp_destroy(struct tcf_proto *tp) kfree_rcu(data, rcu); } -static int rsvp_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int rsvp_delete(struct tcf_proto *tp, void *arg, bool *last) { struct rsvp_head *head = rtnl_dereference(tp->root); - struct rsvp_filter *nfp, *f = (struct rsvp_filter *)arg; + struct rsvp_filter *nfp, *f = arg; struct rsvp_filter __rcu **fp; unsigned int h = f->handle; struct rsvp_session __rcu **sp; @@ -389,7 +389,7 @@ static unsigned int gen_handle(struct tcf_proto *tp, unsigned salt) if ((data->hgenerator += 0x10000) == 0) data->hgenerator = 0x10000; h = data->hgenerator|salt; - if (rsvp_get(tp, h) == 0) + if (!rsvp_get(tp, h)) return h; } return 0; @@ -464,7 +464,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - unsigned long *arg, bool ovr) + void **arg, bool ovr) { struct rsvp_head *data = rtnl_dereference(tp->root); struct rsvp_filter *f, *nfp; @@ -493,7 +493,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, if (err < 0) goto errout2; - f = (struct rsvp_filter *)*arg; + f = *arg; if (f) { /* Node exists: adjust only classid */ struct rsvp_filter *n; @@ -518,7 +518,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, tcf_bind_filter(tp, &n->res, base); } - tcf_exts_change(tp, &n->exts, &e); + tcf_exts_change(&n->exts, &e); rsvp_replace(tp, n, handle); return 0; } @@ -591,7 +591,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, if (f->tunnelhdr == 0) tcf_bind_filter(tp, &f->res, base); - tcf_exts_change(tp, &f->exts, &e); + tcf_exts_change(&f->exts, &e); fp = &s->ht[h2]; for (nfp = rtnl_dereference(*fp); nfp; @@ -604,7 +604,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, RCU_INIT_POINTER(f->next, nfp); rcu_assign_pointer(*fp, f); - *arg = (unsigned long)f; + *arg = f; return 0; } } @@ -663,7 +663,7 @@ static void rsvp_walk(struct tcf_proto *tp, struct tcf_walker *arg) arg->count++; continue; } - if (arg->fn(tp, (unsigned long)f, arg) < 0) { + if (arg->fn(tp, f, arg) < 0) { arg->stop = 1; return; } @@ -674,10 +674,10 @@ static void rsvp_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int rsvp_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { - struct rsvp_filter *f = (struct rsvp_filter *)fh; + struct rsvp_filter *f = fh; struct rsvp_session *s; struct nlattr *nest; struct tc_rsvp_pinfo pinfo; @@ -723,6 +723,14 @@ static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void rsvp_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct rsvp_filter *f = fh; + + if (f && f->res.classid == classid) + f->res.class = cl; +} + static struct tcf_proto_ops RSVP_OPS __read_mostly = { .kind = RSVP_ID, .classify = rsvp_classify, @@ -733,6 +741,7 @@ static struct tcf_proto_ops RSVP_OPS __read_mostly = { .delete = rsvp_delete, .walk = rsvp_walk, .dump = rsvp_dump, + .bind_class = rsvp_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 8a8a58357c39b8e38c2d3740aaa93ed67866fe54..14a7e08b2fa9e2f8a3551f6dbc1fb38f1e8df579 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -52,7 +52,7 @@ struct tcindex_data { static inline int tcindex_filter_is_set(struct tcindex_filter_result *r) { - return tcf_exts_is_predicative(&r->exts) || r->res.classid; + return tcf_exts_has_actions(&r->exts) || r->res.classid; } static struct tcindex_filter_result *tcindex_lookup(struct tcindex_data *p, @@ -104,16 +104,16 @@ static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp, } -static unsigned long tcindex_get(struct tcf_proto *tp, u32 handle) +static void *tcindex_get(struct tcf_proto *tp, u32 handle) { struct tcindex_data *p = rtnl_dereference(tp->root); struct tcindex_filter_result *r; pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle); if (p->perfect && handle >= p->alloc_hash) - return 0; + return NULL; r = tcindex_lookup(p, handle); - return r && tcindex_filter_is_set(r) ? (unsigned long) r : 0UL; + return r && tcindex_filter_is_set(r) ? r : NULL; } static int tcindex_init(struct tcf_proto *tp) @@ -150,14 +150,14 @@ static void tcindex_destroy_fexts(struct rcu_head *head) kfree(f); } -static int tcindex_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int tcindex_delete(struct tcf_proto *tp, void *arg, bool *last) { struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; + struct tcindex_filter_result *r = arg; struct tcindex_filter __rcu **walk; struct tcindex_filter *f = NULL; - pr_debug("tcindex_delete(tp %p,arg 0x%lx),p %p\n", tp, arg, p); + pr_debug("tcindex_delete(tp %p,arg %p),p %p\n", tp, arg, p); if (p->perfect) { if (!r->res.class) return -ENOENT; @@ -192,8 +192,7 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg, bool *last) } static int tcindex_destroy_element(struct tcf_proto *tp, - unsigned long arg, - struct tcf_walker *walker) + void *arg, struct tcf_walker *walker) { bool last; @@ -419,9 +418,9 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, } if (old_r) - tcf_exts_change(tp, &r->exts, &e); + tcf_exts_change(&r->exts, &e); else - tcf_exts_change(tp, &cr.exts, &e); + tcf_exts_change(&cr.exts, &e); if (old_r && old_r != r) { err = tcindex_filter_result_init(old_r); @@ -439,7 +438,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, struct tcindex_filter *nfp; struct tcindex_filter __rcu **fp; - tcf_exts_change(tp, &f->result.exts, &r->exts); + tcf_exts_change(&f->result.exts, &r->exts); fp = cp->h + (handle % cp->hash); for (nfp = rtnl_dereference(*fp); @@ -471,17 +470,17 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, static int tcindex_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, - struct nlattr **tca, unsigned long *arg, bool ovr) + struct nlattr **tca, void **arg, bool ovr) { struct nlattr *opt = tca[TCA_OPTIONS]; struct nlattr *tb[TCA_TCINDEX_MAX + 1]; struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg; + struct tcindex_filter_result *r = *arg; int err; pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p," - "p %p,r %p,*arg 0x%lx\n", - tp, handle, tca, arg, opt, p, r, arg ? *arg : 0L); + "p %p,r %p,*arg %p\n", + tp, handle, tca, arg, opt, p, r, arg ? *arg : NULL); if (!opt) return 0; @@ -506,9 +505,7 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) if (!p->perfect[i].res.class) continue; if (walker->count >= walker->skip) { - if (walker->fn(tp, - (unsigned long) (p->perfect+i), walker) - < 0) { + if (walker->fn(tp, p->perfect + i, walker) < 0) { walker->stop = 1; return; } @@ -522,8 +519,7 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) for (f = rtnl_dereference(p->h[i]); f; f = next) { next = rtnl_dereference(f->next); if (walker->count >= walker->skip) { - if (walker->fn(tp, (unsigned long) &f->result, - walker) < 0) { + if (walker->fn(tp, &f->result, walker) < 0) { walker->stop = 1; return; } @@ -548,14 +544,14 @@ static void tcindex_destroy(struct tcf_proto *tp) } -static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static int tcindex_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh; + struct tcindex_filter_result *r = fh; struct nlattr *nest; - pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p\n", + pr_debug("tcindex_dump(tp %p,fh %p,skb %p,t %p),p %p,r %p\n", tp, fh, skb, t, p, r); pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h); @@ -610,6 +606,14 @@ static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return -1; } +static void tcindex_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct tcindex_filter_result *r = fh; + + if (r && r->res.classid == classid) + r->res.class = cl; +} + static struct tcf_proto_ops cls_tcindex_ops __read_mostly = { .kind = "tcindex", .classify = tcindex_classify, @@ -620,6 +624,7 @@ static struct tcf_proto_ops cls_tcindex_ops __read_mostly = { .delete = tcindex_delete, .walk = tcindex_walk, .dump = tcindex_dump, + .bind_class = tcindex_bind_class, .owner = THIS_MODULE, }; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 2d01195153e6c80178328c65d3b94651f3e2094f..10b8d851fc6be96c761bea127776b84d21b4fc05 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include @@ -92,6 +94,7 @@ struct tc_u_common { struct Qdisc *q; int refcnt; u32 hgenerator; + struct hlist_node hnode; struct rcu_head rcu; }; @@ -289,7 +292,7 @@ static struct tc_u_knode *u32_lookup_key(struct tc_u_hnode *ht, u32 handle) } -static unsigned long u32_get(struct tcf_proto *tp, u32 handle) +static void *u32_get(struct tcf_proto *tp, u32 handle) { struct tc_u_hnode *ht; struct tc_u_common *tp_c = tp->data; @@ -300,12 +303,12 @@ static unsigned long u32_get(struct tcf_proto *tp, u32 handle) ht = u32_lookup_ht(tp_c, TC_U32_HTID(handle)); if (!ht) - return 0; + return NULL; if (TC_U32_KEY(handle) == 0) - return (unsigned long)ht; + return ht; - return (unsigned long)u32_lookup_key(ht, handle); + return u32_lookup_key(ht, handle); } static u32 gen_new_htid(struct tc_u_common *tp_c) @@ -323,12 +326,40 @@ static u32 gen_new_htid(struct tc_u_common *tp_c) return i > 0 ? (tp_c->hgenerator|0x800)<<20 : 0; } +static struct hlist_head *tc_u_common_hash; + +#define U32_HASH_SHIFT 10 +#define U32_HASH_SIZE (1 << U32_HASH_SHIFT) + +static unsigned int tc_u_hash(const struct tcf_proto *tp) +{ + struct net_device *dev = tp->q->dev_queue->dev; + u32 qhandle = tp->q->handle; + int ifindex = dev->ifindex; + + return hash_64((u64)ifindex << 32 | qhandle, U32_HASH_SHIFT); +} + +static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp) +{ + struct tc_u_common *tc; + unsigned int h; + + h = tc_u_hash(tp); + hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) { + if (tc->q == tp->q) + return tc; + } + return NULL; +} + static int u32_init(struct tcf_proto *tp) { struct tc_u_hnode *root_ht; struct tc_u_common *tp_c; + unsigned int h; - tp_c = tp->q->u32_node; + tp_c = tc_u_common_find(tp); root_ht = kzalloc(sizeof(*root_ht), GFP_KERNEL); if (root_ht == NULL) @@ -345,7 +376,10 @@ static int u32_init(struct tcf_proto *tp) return -ENOBUFS; } tp_c->q = tp->q; - tp->q->u32_node = tp_c; + INIT_HLIST_NODE(&tp_c->hnode); + + h = tc_u_hash(tp); + hlist_add_head(&tp_c->hnode, &tc_u_common_hash[h]); } tp_c->refcnt++; @@ -431,43 +465,35 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key) static void u32_remove_hw_knode(struct tcf_proto *tp, u32 handle) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_cls_u32_offload u32_offload = {0}; - struct tc_to_netdev offload; - - offload.type = TC_SETUP_CLSU32; - offload.cls_u32 = &u32_offload; - - if (tc_should_offload(dev, tp, 0)) { - offload.cls_u32->command = TC_CLSU32_DELETE_KNODE; - offload.cls_u32->knode.handle = handle; - dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, tp->protocol, - &offload); - } + struct tc_cls_u32_offload cls_u32 = {}; + + if (!tc_should_offload(dev, 0)) + return; + + tc_cls_common_offload_init(&cls_u32.common, tp); + cls_u32.command = TC_CLSU32_DELETE_KNODE; + cls_u32.knode.handle = handle; + + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSU32, &cls_u32); } static int u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h, u32 flags) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_cls_u32_offload u32_offload = {0}; - struct tc_to_netdev offload; + struct tc_cls_u32_offload cls_u32 = {}; int err; - if (!tc_should_offload(dev, tp, flags)) + if (!tc_should_offload(dev, flags)) return tc_skip_sw(flags) ? -EINVAL : 0; - offload.type = TC_SETUP_CLSU32; - offload.cls_u32 = &u32_offload; - - offload.cls_u32->command = TC_CLSU32_NEW_HNODE; - offload.cls_u32->hnode.divisor = h->divisor; - offload.cls_u32->hnode.handle = h->handle; - offload.cls_u32->hnode.prio = h->prio; + tc_cls_common_offload_init(&cls_u32.common, tp); + cls_u32.command = TC_CLSU32_NEW_HNODE; + cls_u32.hnode.divisor = h->divisor; + cls_u32.hnode.handle = h->handle; + cls_u32.hnode.prio = h->prio; - err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, tp->protocol, - &offload); + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSU32, &cls_u32); if (tc_skip_sw(flags)) return err; @@ -477,56 +503,47 @@ static int u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h, static void u32_clear_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_cls_u32_offload u32_offload = {0}; - struct tc_to_netdev offload; + struct tc_cls_u32_offload cls_u32 = {}; - offload.type = TC_SETUP_CLSU32; - offload.cls_u32 = &u32_offload; + if (!tc_should_offload(dev, 0)) + return; - if (tc_should_offload(dev, tp, 0)) { - offload.cls_u32->command = TC_CLSU32_DELETE_HNODE; - offload.cls_u32->hnode.divisor = h->divisor; - offload.cls_u32->hnode.handle = h->handle; - offload.cls_u32->hnode.prio = h->prio; + tc_cls_common_offload_init(&cls_u32.common, tp); + cls_u32.command = TC_CLSU32_DELETE_HNODE; + cls_u32.hnode.divisor = h->divisor; + cls_u32.hnode.handle = h->handle; + cls_u32.hnode.prio = h->prio; - dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, tp->protocol, - &offload); - } + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSU32, &cls_u32); } static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n, u32 flags) { struct net_device *dev = tp->q->dev_queue->dev; - struct tc_cls_u32_offload u32_offload = {0}; - struct tc_to_netdev offload; + struct tc_cls_u32_offload cls_u32 = {}; int err; - offload.type = TC_SETUP_CLSU32; - offload.cls_u32 = &u32_offload; - - if (!tc_should_offload(dev, tp, flags)) + if (!tc_should_offload(dev, flags)) return tc_skip_sw(flags) ? -EINVAL : 0; - offload.cls_u32->command = TC_CLSU32_REPLACE_KNODE; - offload.cls_u32->knode.handle = n->handle; - offload.cls_u32->knode.fshift = n->fshift; + tc_cls_common_offload_init(&cls_u32.common, tp); + cls_u32.command = TC_CLSU32_REPLACE_KNODE; + cls_u32.knode.handle = n->handle; + cls_u32.knode.fshift = n->fshift; #ifdef CONFIG_CLS_U32_MARK - offload.cls_u32->knode.val = n->val; - offload.cls_u32->knode.mask = n->mask; + cls_u32.knode.val = n->val; + cls_u32.knode.mask = n->mask; #else - offload.cls_u32->knode.val = 0; - offload.cls_u32->knode.mask = 0; + cls_u32.knode.val = 0; + cls_u32.knode.mask = 0; #endif - offload.cls_u32->knode.sel = &n->sel; - offload.cls_u32->knode.exts = &n->exts; + cls_u32.knode.sel = &n->sel; + cls_u32.knode.exts = &n->exts; if (n->ht_down) - offload.cls_u32->knode.link_handle = n->ht_down->handle; + cls_u32.knode.link_handle = n->ht_down->handle; - err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, - tp->chain->index, tp->protocol, - &offload); + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSU32, &cls_u32); if (!err) n->flags |= TCA_CLS_FLAGS_IN_HW; @@ -602,7 +619,7 @@ static void u32_destroy(struct tcf_proto *tp) if (--tp_c->refcnt == 0) { struct tc_u_hnode *ht; - tp->q->u32_node = NULL; + hlist_del(&tp_c->hnode); for (ht = rtnl_dereference(tp_c->hlist); ht; @@ -622,9 +639,9 @@ static void u32_destroy(struct tcf_proto *tp) tp->data = NULL; } -static int u32_delete(struct tcf_proto *tp, unsigned long arg, bool *last) +static int u32_delete(struct tcf_proto *tp, void *arg, bool *last) { - struct tc_u_hnode *ht = (struct tc_u_hnode *)arg; + struct tc_u_hnode *ht = arg; struct tc_u_hnode *root_ht = rtnl_dereference(tp->root); struct tc_u_common *tp_c = tp->data; int ret = 0; @@ -723,29 +740,24 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, struct tc_u_knode *n, struct nlattr **tb, struct nlattr *est, bool ovr) { - struct tcf_exts e; int err; - err = tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE); + err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr); if (err < 0) return err; - err = tcf_exts_validate(net, tp, tb, est, &e, ovr); - if (err < 0) - goto errout; - err = -EINVAL; if (tb[TCA_U32_LINK]) { u32 handle = nla_get_u32(tb[TCA_U32_LINK]); struct tc_u_hnode *ht_down = NULL, *ht_old; if (TC_U32_KEY(handle)) - goto errout; + return -EINVAL; if (handle) { ht_down = u32_lookup_ht(ht->tp_c, handle); if (ht_down == NULL) - goto errout; + return -EINVAL; ht_down->refcnt++; } @@ -765,16 +777,11 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, int ret; ret = tcf_change_indev(net, tb[TCA_U32_INDEV]); if (ret < 0) - goto errout; + return -EINVAL; n->ifindex = ret; } #endif - tcf_exts_change(tp, &n->exts, &e); - return 0; -errout: - tcf_exts_destroy(&e); - return err; } static void u32_replace_knode(struct tcf_proto *tp, struct tc_u_common *tp_c, @@ -858,7 +865,7 @@ static struct tc_u_knode *u32_init_knode(struct tcf_proto *tp, static int u32_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, - struct nlattr **tca, unsigned long *arg, bool ovr) + struct nlattr **tca, void **arg, bool ovr) { struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *ht; @@ -885,7 +892,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; } - n = (struct tc_u_knode *)*arg; + n = *arg; if (n) { struct tc_u_knode *new; @@ -952,7 +959,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, RCU_INIT_POINTER(ht->next, tp_c->hlist); rcu_assign_pointer(tp_c->hlist, ht); - *arg = (unsigned long)ht; + *arg = ht; return 0; } @@ -1047,7 +1054,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, RCU_INIT_POINTER(n->next, pins); rcu_assign_pointer(*ins, n); - *arg = (unsigned long)n; + *arg = n; return 0; } @@ -1081,7 +1088,7 @@ static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg) if (ht->prio != tp->prio) continue; if (arg->count >= arg->skip) { - if (arg->fn(tp, (unsigned long)ht, arg) < 0) { + if (arg->fn(tp, ht, arg) < 0) { arg->stop = 1; return; } @@ -1095,7 +1102,7 @@ static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg) arg->count++; continue; } - if (arg->fn(tp, (unsigned long)n, arg) < 0) { + if (arg->fn(tp, n, arg) < 0) { arg->stop = 1; return; } @@ -1105,10 +1112,18 @@ static void u32_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } -static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, +static void u32_bind_class(void *fh, u32 classid, unsigned long cl) +{ + struct tc_u_knode *n = fh; + + if (n && n->res.classid == classid) + n->res.class = cl; +} + +static int u32_dump(struct net *net, struct tcf_proto *tp, void *fh, struct sk_buff *skb, struct tcmsg *t) { - struct tc_u_knode *n = (struct tc_u_knode *)fh; + struct tc_u_knode *n = fh; struct tc_u_hnode *ht_up, *ht_down; struct nlattr *nest; @@ -1122,7 +1137,7 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; if (TC_U32_KEY(n->handle) == 0) { - struct tc_u_hnode *ht = (struct tc_u_hnode *)fh; + struct tc_u_hnode *ht = fh; u32 divisor = ht->divisor + 1; if (nla_put_u32(skb, TCA_U32_DIVISOR, divisor)) @@ -1235,11 +1250,14 @@ static struct tcf_proto_ops cls_u32_ops __read_mostly = { .delete = u32_delete, .walk = u32_walk, .dump = u32_dump, + .bind_class = u32_bind_class, .owner = THIS_MODULE, }; static int __init init_u32(void) { + int i, ret; + pr_info("u32 classifier\n"); #ifdef CONFIG_CLS_U32_PERF pr_info(" Performance counters on\n"); @@ -1250,12 +1268,25 @@ static int __init init_u32(void) #ifdef CONFIG_NET_CLS_ACT pr_info(" Actions configured\n"); #endif - return register_tcf_proto_ops(&cls_u32_ops); + tc_u_common_hash = kvmalloc_array(U32_HASH_SIZE, + sizeof(struct hlist_head), + GFP_KERNEL); + if (!tc_u_common_hash) + return -ENOMEM; + + for (i = 0; i < U32_HASH_SIZE; i++) + INIT_HLIST_HEAD(&tc_u_common_hash[i]); + + ret = register_tcf_proto_ops(&cls_u32_ops); + if (ret) + kvfree(tc_u_common_hash); + return ret; } static void __exit exit_u32(void) { unregister_tcf_proto_ops(&cls_u32_ops); + kvfree(tc_u_common_hash); } module_init(init_u32) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index bd24a550e0f9f114598f4a398d6efd4c72672f50..c6deb74e3d2f4a007554b9cf78e4ddf7b7b84535 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -35,13 +35,7 @@ #include #include #include - -static int qdisc_notify(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, u32 clid, - struct Qdisc *old, struct Qdisc *new); -static int tclass_notify(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, struct Qdisc *q, - unsigned long cl, int event); +#include /* @@ -160,7 +154,7 @@ int register_qdisc(struct Qdisc_ops *qops) if (qops->cl_ops) { const struct Qdisc_class_ops *cops = qops->cl_ops; - if (!(cops->get && cops->put && cops->walk && cops->leaf)) + if (!(cops->find && cops->walk && cops->leaf)) goto out_einval; if (cops->tcf_block && !(cops->bind_tcf && cops->unbind_tcf)) @@ -286,9 +280,6 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) void qdisc_hash_add(struct Qdisc *q, bool invisible) { if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) { - struct Qdisc *root = qdisc_dev(q)->qdisc; - - WARN_ON_ONCE(root == &noop_qdisc); ASSERT_RTNL(); hash_add_rcu(qdisc_dev(q)->qdisc_hash, &q->hash, q->handle); if (invisible) @@ -330,12 +321,11 @@ static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) if (cops == NULL) return NULL; - cl = cops->get(p, classid); + cl = cops->find(p, classid); if (cl == 0) return NULL; leaf = cops->leaf(p, cl); - cops->put(p, cl); return leaf; } @@ -624,14 +614,10 @@ EXPORT_SYMBOL(qdisc_watchdog_cancel); static struct hlist_head *qdisc_class_hash_alloc(unsigned int n) { - unsigned int size = n * sizeof(struct hlist_head), i; struct hlist_head *h; + unsigned int i; - if (size <= PAGE_SIZE) - h = kmalloc(size, GFP_KERNEL); - else - h = (struct hlist_head *) - __get_free_pages(GFP_KERNEL, get_order(size)); + h = kvmalloc_array(n, sizeof(struct hlist_head), GFP_KERNEL); if (h != NULL) { for (i = 0; i < n; i++) @@ -640,16 +626,6 @@ static struct hlist_head *qdisc_class_hash_alloc(unsigned int n) return h; } -static void qdisc_class_hash_free(struct hlist_head *h, unsigned int n) -{ - unsigned int size = n * sizeof(struct hlist_head); - - if (size <= PAGE_SIZE) - kfree(h); - else - free_pages((unsigned long)h, get_order(size)); -} - void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash) { struct Qdisc_class_common *cl; @@ -682,7 +658,7 @@ void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash) clhash->hashmask = nmask; sch_tree_unlock(sch); - qdisc_class_hash_free(ohash, osize); + kvfree(ohash); } EXPORT_SYMBOL(qdisc_class_hash_grow); @@ -702,7 +678,7 @@ EXPORT_SYMBOL(qdisc_class_hash_init); void qdisc_class_hash_destroy(struct Qdisc_class_hash *clhash) { - qdisc_class_hash_free(clhash->hash, clhash->hashsize); + kvfree(clhash->hash); } EXPORT_SYMBOL(qdisc_class_hash_destroy); @@ -752,6 +728,7 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n, const struct Qdisc_class_ops *cops; unsigned long cl; u32 parentid; + bool notify; int drops; if (n == 0 && len == 0) @@ -764,6 +741,13 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n, if (sch->flags & TCQ_F_NOPARENT) break; + /* Notify parent qdisc only if child qdisc becomes empty. + * + * If child was empty even before update then backlog + * counter is screwed and we skip notification because + * parent class is already passive. + */ + notify = !sch->q.qlen && !WARN_ON_ONCE(!n); /* TODO: perform the search on a per txq basis */ sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); if (sch == NULL) { @@ -771,10 +755,9 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n, break; } cops = sch->ops->cl_ops; - if (cops->qlen_notify) { - cl = cops->get(sch, parentid); + if (notify && cops->qlen_notify) { + cl = cops->find(sch, parentid); cops->qlen_notify(sch, cl); - cops->put(sch, cl); } sch->q.qlen -= n; sch->qstats.backlog -= len; @@ -784,6 +767,111 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n, } EXPORT_SYMBOL(qdisc_tree_reduce_backlog); +static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, + u32 portid, u32 seq, u16 flags, int event) +{ + struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL; + struct gnet_stats_queue __percpu *cpu_qstats = NULL; + struct tcmsg *tcm; + struct nlmsghdr *nlh; + unsigned char *b = skb_tail_pointer(skb); + struct gnet_dump d; + struct qdisc_size_table *stab; + __u32 qlen; + + cond_resched(); + nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); + tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; + tcm->tcm_ifindex = qdisc_dev(q)->ifindex; + tcm->tcm_parent = clid; + tcm->tcm_handle = q->handle; + tcm->tcm_info = refcount_read(&q->refcnt); + if (nla_put_string(skb, TCA_KIND, q->ops->id)) + goto nla_put_failure; + if (q->ops->dump && q->ops->dump(q, skb) < 0) + goto nla_put_failure; + qlen = q->q.qlen; + + stab = rtnl_dereference(q->stab); + if (stab && qdisc_dump_stab(skb, stab) < 0) + goto nla_put_failure; + + if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, + NULL, &d, TCA_PAD) < 0) + goto nla_put_failure; + + if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) + goto nla_put_failure; + + if (qdisc_is_percpu_stats(q)) { + cpu_bstats = q->cpu_bstats; + cpu_qstats = q->cpu_qstats; + } + + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(q), + &d, cpu_bstats, &q->bstats) < 0 || + gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 || + gnet_stats_copy_queue(&d, cpu_qstats, &q->qstats, qlen) < 0) + goto nla_put_failure; + + if (gnet_stats_finish_copy(&d) < 0) + goto nla_put_failure; + + nlh->nlmsg_len = skb_tail_pointer(skb) - b; + return skb->len; + +out_nlmsg_trim: +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static bool tc_qdisc_dump_ignore(struct Qdisc *q, bool dump_invisible) +{ + if (q->flags & TCQ_F_BUILTIN) + return true; + if ((q->flags & TCQ_F_INVISIBLE) && !dump_invisible) + return true; + + return false; +} + +static int qdisc_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, u32 clid, + struct Qdisc *old, struct Qdisc *new) +{ + struct sk_buff *skb; + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (old && !tc_qdisc_dump_ignore(old, false)) { + if (tc_fill_qdisc(skb, old, clid, portid, n->nlmsg_seq, + 0, RTM_DELQDISC) < 0) + goto err_out; + } + if (new && !tc_qdisc_dump_ignore(new, false)) { + if (tc_fill_qdisc(skb, new, clid, portid, n->nlmsg_seq, + old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) + goto err_out; + } + + if (skb->len) + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); + +err_out: + kfree_skb(skb); + return -EINVAL; +} + static void notify_and_destroy(struct net *net, struct sk_buff *skb, struct nlmsghdr *n, u32 clid, struct Qdisc *old, struct Qdisc *new) @@ -839,7 +927,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, old = dev_graft_qdisc(dev_queue, new); if (new && i > 0) - refcount_inc(&new->refcnt); + qdisc_refcount_inc(new); if (!ingress) qdisc_destroy(old); @@ -850,7 +938,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, notify_and_destroy(net, skb, n, classid, dev->qdisc, new); if (new && !new->ops->attach) - refcount_inc(&new->refcnt); + qdisc_refcount_inc(new); dev->qdisc = new ? : &noop_qdisc; if (new && new->ops->attach) @@ -866,11 +954,11 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, err = -EOPNOTSUPP; if (cops && cops->graft) { - unsigned long cl = cops->get(parent, classid); - if (cl) { + unsigned long cl = cops->find(parent, classid); + + if (cl) err = cops->graft(parent, cl, new, &old); - cops->put(parent, cl); - } else + else err = -ENOENT; } if (!err) @@ -1259,7 +1347,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, if (q == p || (p && check_loop(q, p, 0))) return -ELOOP; - refcount_inc(&q->refcnt); + qdisc_refcount_inc(q); goto graft; } else { if (!q) @@ -1351,111 +1439,6 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, return 0; } -static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, - u32 portid, u32 seq, u16 flags, int event) -{ - struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL; - struct gnet_stats_queue __percpu *cpu_qstats = NULL; - struct tcmsg *tcm; - struct nlmsghdr *nlh; - unsigned char *b = skb_tail_pointer(skb); - struct gnet_dump d; - struct qdisc_size_table *stab; - __u32 qlen; - - cond_resched(); - nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); - if (!nlh) - goto out_nlmsg_trim; - tcm = nlmsg_data(nlh); - tcm->tcm_family = AF_UNSPEC; - tcm->tcm__pad1 = 0; - tcm->tcm__pad2 = 0; - tcm->tcm_ifindex = qdisc_dev(q)->ifindex; - tcm->tcm_parent = clid; - tcm->tcm_handle = q->handle; - tcm->tcm_info = refcount_read(&q->refcnt); - if (nla_put_string(skb, TCA_KIND, q->ops->id)) - goto nla_put_failure; - if (q->ops->dump && q->ops->dump(q, skb) < 0) - goto nla_put_failure; - qlen = q->q.qlen; - - stab = rtnl_dereference(q->stab); - if (stab && qdisc_dump_stab(skb, stab) < 0) - goto nla_put_failure; - - if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, - NULL, &d, TCA_PAD) < 0) - goto nla_put_failure; - - if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) - goto nla_put_failure; - - if (qdisc_is_percpu_stats(q)) { - cpu_bstats = q->cpu_bstats; - cpu_qstats = q->cpu_qstats; - } - - if (gnet_stats_copy_basic(qdisc_root_sleeping_running(q), - &d, cpu_bstats, &q->bstats) < 0 || - gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 || - gnet_stats_copy_queue(&d, cpu_qstats, &q->qstats, qlen) < 0) - goto nla_put_failure; - - if (gnet_stats_finish_copy(&d) < 0) - goto nla_put_failure; - - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; - -out_nlmsg_trim: -nla_put_failure: - nlmsg_trim(skb, b); - return -1; -} - -static bool tc_qdisc_dump_ignore(struct Qdisc *q, bool dump_invisible) -{ - if (q->flags & TCQ_F_BUILTIN) - return true; - if ((q->flags & TCQ_F_INVISIBLE) && !dump_invisible) - return true; - - return false; -} - -static int qdisc_notify(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, u32 clid, - struct Qdisc *old, struct Qdisc *new) -{ - struct sk_buff *skb; - u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; - - skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb) - return -ENOBUFS; - - if (old && !tc_qdisc_dump_ignore(old, false)) { - if (tc_fill_qdisc(skb, old, clid, portid, n->nlmsg_seq, - 0, RTM_DELQDISC) < 0) - goto err_out; - } - if (new && !tc_qdisc_dump_ignore(new, false)) { - if (tc_fill_qdisc(skb, new, clid, portid, n->nlmsg_seq, - old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) - goto err_out; - } - - if (skb->len) - return rtnetlink_send(skb, net, portid, RTNLGRP_TC, - n->nlmsg_flags & NLM_F_ECHO); - -err_out: - kfree_skb(skb); - return -EINVAL; -} - static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, struct netlink_callback *cb, int *q_idx_p, int s_q_idx, bool recur, @@ -1568,7 +1551,161 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) * Traffic classes manipulation. * ************************************************/ +static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, + unsigned long cl, + u32 portid, u32 seq, u16 flags, int event) +{ + struct tcmsg *tcm; + struct nlmsghdr *nlh; + unsigned char *b = skb_tail_pointer(skb); + struct gnet_dump d; + const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops; + + cond_resched(); + nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); + tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; + tcm->tcm_ifindex = qdisc_dev(q)->ifindex; + tcm->tcm_parent = q->handle; + tcm->tcm_handle = q->handle; + tcm->tcm_info = 0; + if (nla_put_string(skb, TCA_KIND, q->ops->id)) + goto nla_put_failure; + if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) + goto nla_put_failure; + + if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, + NULL, &d, TCA_PAD) < 0) + goto nla_put_failure; + + if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) + goto nla_put_failure; + + if (gnet_stats_finish_copy(&d) < 0) + goto nla_put_failure; + + nlh->nlmsg_len = skb_tail_pointer(skb) - b; + return skb->len; + +out_nlmsg_trim: +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static int tclass_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, struct Qdisc *q, + unsigned long cl, int event) +{ + struct sk_buff *skb; + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, event) < 0) { + kfree_skb(skb); + return -EINVAL; + } + + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); +} + +static int tclass_del_notify(struct net *net, + const struct Qdisc_class_ops *cops, + struct sk_buff *oskb, struct nlmsghdr *n, + struct Qdisc *q, unsigned long cl) +{ + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + struct sk_buff *skb; + int err = 0; + + if (!cops->delete) + return -EOPNOTSUPP; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, + RTM_DELTCLASS) < 0) { + kfree_skb(skb); + return -EINVAL; + } + + err = cops->delete(q, cl); + if (err) { + kfree_skb(skb); + return err; + } + + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); +} + +#ifdef CONFIG_NET_CLS + +struct tcf_bind_args { + struct tcf_walker w; + u32 classid; + unsigned long cl; +}; + +static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg) +{ + struct tcf_bind_args *a = (void *)arg; + + if (tp->ops->bind_class) { + tcf_tree_lock(tp); + tp->ops->bind_class(n, a->classid, a->cl); + tcf_tree_unlock(tp); + } + return 0; +} + +static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid, + unsigned long new_cl) +{ + const struct Qdisc_class_ops *cops = q->ops->cl_ops; + struct tcf_block *block; + struct tcf_chain *chain; + unsigned long cl; + + cl = cops->find(q, portid); + if (!cl) + return; + block = cops->tcf_block(q, cl); + if (!block) + return; + list_for_each_entry(chain, &block->chain_list, list) { + struct tcf_proto *tp; + + for (tp = rtnl_dereference(chain->filter_chain); + tp; tp = rtnl_dereference(tp->next)) { + struct tcf_bind_args arg = {}; + + arg.w.fn = tcf_node_bind; + arg.classid = clid; + arg.cl = new_cl; + tp->ops->walk(tp, &arg.w); + } + } +} + +#else + +static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid, + unsigned long new_cl) +{ +} + +#endif static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, struct netlink_ext_ack *extack) @@ -1659,7 +1796,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, clid = TC_H_MAKE(qid, clid); if (clid) - cl = cops->get(q, clid); + cl = cops->find(q, clid); if (cl == 0) { err = -ENOENT; @@ -1674,12 +1811,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, goto out; break; case RTM_DELTCLASS: - err = -EOPNOTSUPP; - if (cops->delete) - err = cops->delete(q, cl); - if (err == 0) - tclass_notify(net, skb, n, q, cl, - RTM_DELTCLASS); + err = tclass_del_notify(net, cops, skb, n, q, cl); + /* Unbind the class with flilters with 0 */ + tc_bind_tclass(q, portid, clid, 0); goto out; case RTM_GETTCLASS: err = tclass_notify(net, skb, n, q, cl, RTM_NEWTCLASS); @@ -1694,83 +1828,16 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, err = -EOPNOTSUPP; if (cops->change) err = cops->change(q, clid, portid, tca, &new_cl); - if (err == 0) + if (err == 0) { tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS); - + /* We just create a new class, need to do reverse binding. */ + if (cl != new_cl) + tc_bind_tclass(q, portid, clid, new_cl); + } out: - if (cl) - cops->put(q, cl); - return err; } - -static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, - unsigned long cl, - u32 portid, u32 seq, u16 flags, int event) -{ - struct tcmsg *tcm; - struct nlmsghdr *nlh; - unsigned char *b = skb_tail_pointer(skb); - struct gnet_dump d; - const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops; - - cond_resched(); - nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); - if (!nlh) - goto out_nlmsg_trim; - tcm = nlmsg_data(nlh); - tcm->tcm_family = AF_UNSPEC; - tcm->tcm__pad1 = 0; - tcm->tcm__pad2 = 0; - tcm->tcm_ifindex = qdisc_dev(q)->ifindex; - tcm->tcm_parent = q->handle; - tcm->tcm_handle = q->handle; - tcm->tcm_info = 0; - if (nla_put_string(skb, TCA_KIND, q->ops->id)) - goto nla_put_failure; - if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) - goto nla_put_failure; - - if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, - NULL, &d, TCA_PAD) < 0) - goto nla_put_failure; - - if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) - goto nla_put_failure; - - if (gnet_stats_finish_copy(&d) < 0) - goto nla_put_failure; - - nlh->nlmsg_len = skb_tail_pointer(skb) - b; - return skb->len; - -out_nlmsg_trim: -nla_put_failure: - nlmsg_trim(skb, b); - return -1; -} - -static int tclass_notify(struct net *net, struct sk_buff *oskb, - struct nlmsghdr *n, struct Qdisc *q, - unsigned long cl, int event) -{ - struct sk_buff *skb; - u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; - - skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb) - return -ENOBUFS; - - if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, event) < 0) { - kfree_skb(skb); - return -EINVAL; - } - - return rtnetlink_send(skb, net, portid, RTNLGRP_TC, - n->nlmsg_flags & NLM_F_ECHO); -} - struct qdisc_dump_args { struct qdisc_walker w; struct sk_buff *skb; @@ -1952,14 +2019,14 @@ static int __init pktsched_init(void) register_qdisc(&mq_qdisc_ops); register_qdisc(&noqueue_qdisc_ops); - rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL, NULL); + rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETQDISC, tc_get_qdisc, tc_dump_qdisc, - NULL); - rtnl_register(PF_UNSPEC, RTM_NEWTCLASS, tc_ctl_tclass, NULL, NULL); - rtnl_register(PF_UNSPEC, RTM_DELTCLASS, tc_ctl_tclass, NULL, NULL); + 0); + rtnl_register(PF_UNSPEC, RTM_NEWTCLASS, tc_ctl_tclass, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELTCLASS, tc_ctl_tclass, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETTCLASS, tc_ctl_tclass, tc_dump_tclass, - NULL); + 0); return 0; } diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 572fe2584e48c81dbf58d90ce9d6a4ae68d2a385..c5fcdf1a58a08824aef5b48c790a019e17134967 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -41,6 +41,7 @@ #define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back)) struct atm_flow_data { + struct Qdisc_class_common common; struct Qdisc *q; /* FIFO, TBF, etc. */ struct tcf_proto __rcu *filter_list; struct tcf_block *block; @@ -49,7 +50,6 @@ struct atm_flow_data { struct sk_buff *skb); /* chaining */ struct atm_qdisc_data *parent; /* parent qdisc */ struct socket *sock; /* for closing */ - u32 classid; /* x:y type ID */ int ref; /* reference count */ struct gnet_stats_basic_packed bstats; struct gnet_stats_queue qstats; @@ -75,7 +75,7 @@ static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid) struct atm_flow_data *flow; list_for_each_entry(flow, &p->flows, list) { - if (flow->classid == classid) + if (flow->common.classid == classid) return flow; } return NULL; @@ -108,23 +108,29 @@ static struct Qdisc *atm_tc_leaf(struct Qdisc *sch, unsigned long cl) return flow ? flow->q : NULL; } -static unsigned long atm_tc_get(struct Qdisc *sch, u32 classid) +static unsigned long atm_tc_find(struct Qdisc *sch, u32 classid) { struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch); struct atm_flow_data *flow; - pr_debug("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid); + pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid); flow = lookup_flow(sch, classid); - if (flow) - flow->ref++; - pr_debug("atm_tc_get: flow %p\n", flow); + pr_debug("%s: flow %p\n", __func__, flow); return (unsigned long)flow; } static unsigned long atm_tc_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - return atm_tc_get(sch, classid); + struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch); + struct atm_flow_data *flow; + + pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid); + flow = lookup_flow(sch, classid); + if (flow) + flow->ref++; + pr_debug("%s: flow %p\n", __func__, flow); + return (unsigned long)flow; } /* @@ -234,7 +240,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, excess = NULL; else { excess = (struct atm_flow_data *) - atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); + atm_tc_find(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); if (!excess) return -ENOENT; } @@ -262,10 +268,9 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, for (i = 1; i < 0x8000; i++) { classid = TC_H_MAKE(sch->handle, 0x8000 | i); - cl = atm_tc_get(sch, classid); + cl = atm_tc_find(sch, classid); if (!cl) break; - atm_tc_put(sch, cl); } } pr_debug("atm_tc_change: new id %x\n", classid); @@ -293,7 +298,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, flow->old_pop = flow->vcc->pop; flow->parent = p; flow->vcc->pop = sch_atm_pop; - flow->classid = classid; + flow->common.classid = classid; flow->ref = 1; flow->excess = excess; list_add(&flow->list, &p->link.list); @@ -305,8 +310,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, *arg = (unsigned long)flow; return 0; err_out: - if (excess) - atm_tc_put(sch, (unsigned long)excess); sockfd_put(sock); return error; } @@ -377,7 +380,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch, result = TC_ACT_OK; /* be nice to gcc */ flow = NULL; if (TC_H_MAJ(skb->priority) != sch->handle || - !(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority))) { + !(flow = (struct atm_flow_data *)atm_tc_find(sch, skb->priority))) { struct tcf_proto *fl; list_for_each_entry(flow, &p->flows, list) { @@ -549,7 +552,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt) p->link.vcc = NULL; p->link.sock = NULL; - p->link.classid = sch->handle; + p->link.common.classid = sch->handle; p->link.ref = 1; tasklet_init(&p->task, sch_atm_dequeue, (unsigned long)sch); return 0; @@ -572,8 +575,10 @@ static void atm_tc_destroy(struct Qdisc *sch) struct atm_flow_data *flow, *tmp; pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p); - list_for_each_entry(flow, &p->flows, list) + list_for_each_entry(flow, &p->flows, list) { tcf_block_put(flow->block); + flow->block = NULL; + } list_for_each_entry_safe(flow, tmp, &p->flows, list) { if (flow->ref > 1) @@ -594,7 +599,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, sch, p, flow, skb, tcm); if (list_empty(&flow->list)) return -EINVAL; - tcm->tcm_handle = flow->classid; + tcm->tcm_handle = flow->common.classid; tcm->tcm_info = flow->q->handle; nest = nla_nest_start(skb, TCA_OPTIONS); @@ -619,7 +624,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, goto nla_put_failure; } if (flow->excess) { - if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->classid)) + if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->common.classid)) goto nla_put_failure; } else { if (nla_put_u32(skb, TCA_ATM_EXCESS, 0)) @@ -653,8 +658,7 @@ static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb) static const struct Qdisc_class_ops atm_class_ops = { .graft = atm_tc_graft, .leaf = atm_tc_leaf, - .get = atm_tc_get, - .put = atm_tc_put, + .find = atm_tc_find, .change = atm_tc_change, .delete = atm_tc_delete, .walk = atm_tc_walk, diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 481036f6b54e4730ee27fae6236277c64d3eaa1a..dcef97fa804739df3ae3bc837e1938f3914d6d4f 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -129,7 +129,6 @@ struct cbq_class { struct tcf_proto __rcu *filter_list; struct tcf_block *block; - int refcnt; int filters; struct cbq_class *defaults[TC_PRIO_MAX + 1]; @@ -1139,6 +1138,13 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) struct tc_ratespec *r; int err; + qdisc_watchdog_init(&q->watchdog, sch); + hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); + q->delay_timer.function = cbq_undelay; + + if (!opt) + return -EINVAL; + err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy, NULL); if (err < 0) return err; @@ -1155,7 +1161,6 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) if (err < 0) goto put_rtab; - q->link.refcnt = 1; q->link.sibling = &q->link; q->link.common.classid = sch->handle; q->link.qdisc = sch; @@ -1177,9 +1182,6 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) q->link.avpkt = q->link.allot/2; q->link.minidle = -0x7FFFFFFF; - qdisc_watchdog_init(&q->watchdog, sch); - hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); - q->delay_timer.function = cbq_undelay; q->toplevel = TC_CBQ_MAXLEVEL; q->now = psched_get_time(); @@ -1385,20 +1387,14 @@ static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg) { struct cbq_class *cl = (struct cbq_class *)arg; - if (cl->q->q.qlen == 0) - cbq_deactivate_class(cl); + cbq_deactivate_class(cl); } -static unsigned long cbq_get(struct Qdisc *sch, u32 classid) +static unsigned long cbq_find(struct Qdisc *sch, u32 classid) { struct cbq_sched_data *q = qdisc_priv(sch); - struct cbq_class *cl = cbq_class_lookup(q, classid); - if (cl) { - cl->refcnt++; - return (unsigned long)cl; - } - return 0; + return (unsigned long)cbq_class_lookup(q, classid); } static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) @@ -1431,8 +1427,10 @@ static void cbq_destroy(struct Qdisc *sch) * be bound to classes which have been destroyed already. --TGR '04 */ for (h = 0; h < q->clhash.hashsize; h++) { - hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) + hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) { tcf_block_put(cl->block); + cl->block = NULL; + } } for (h = 0; h < q->clhash.hashsize; h++) { hlist_for_each_entry_safe(cl, next, &q->clhash.hash[h], @@ -1442,25 +1440,6 @@ static void cbq_destroy(struct Qdisc *sch) qdisc_class_hash_destroy(&q->clhash); } -static void cbq_put(struct Qdisc *sch, unsigned long arg) -{ - struct cbq_class *cl = (struct cbq_class *)arg; - - if (--cl->refcnt == 0) { -#ifdef CONFIG_NET_CLS_ACT - spinlock_t *root_lock = qdisc_root_sleeping_lock(sch); - struct cbq_sched_data *q = qdisc_priv(sch); - - spin_lock_bh(root_lock); - if (q->rx_class == cl) - q->rx_class = NULL; - spin_unlock_bh(root_lock); -#endif - - cbq_destroy_class(sch, cl); - } -} - static int cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, unsigned long *arg) @@ -1607,7 +1586,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t cl->R_tab = rtab; rtab = NULL; - cl->refcnt = 1; cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (!cl->q) cl->q = &noop_qdisc; @@ -1688,12 +1666,7 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg) cbq_rmprio(q, cl); sch_tree_unlock(sch); - BUG_ON(--cl->refcnt == 0); - /* - * This shouldn't happen: we "hold" one cops->get() when called - * from tc_ctl_tclass; the destroy method is done from cops->put(). - */ - + cbq_destroy_class(sch, cl); return 0; } @@ -1759,8 +1732,7 @@ static const struct Qdisc_class_ops cbq_class_ops = { .graft = cbq_graft, .leaf = cbq_leaf, .qlen_notify = cbq_qlen_notify, - .get = cbq_get, - .put = cbq_put, + .find = cbq_find, .change = cbq_change_class, .delete = cbq_delete, .walk = cbq_walk, diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index a413dc1c209803d6fbc69c3bb7d0524ad7acb2aa..2d0e8d4bdc29b00d8d681e3cdeceac13420bf8bd 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -20,7 +20,6 @@ struct drr_class { struct Qdisc_class_common common; - unsigned int refcnt; unsigned int filter_cnt; struct gnet_stats_basic_packed bstats; @@ -111,7 +110,6 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (cl == NULL) return -ENOBUFS; - cl->refcnt = 1; cl->common.classid = classid; cl->quantum = quantum; cl->qdisc = qdisc_create_dflt(sch->dev_queue, @@ -163,32 +161,15 @@ static int drr_delete_class(struct Qdisc *sch, unsigned long arg) drr_purge_queue(cl); qdisc_class_hash_remove(&q->clhash, &cl->common); - BUG_ON(--cl->refcnt == 0); - /* - * This shouldn't happen: we "hold" one cops->get() when called - * from tc_ctl_tclass; the destroy method is done from cops->put(). - */ - sch_tree_unlock(sch); - return 0; -} - -static unsigned long drr_get_class(struct Qdisc *sch, u32 classid) -{ - struct drr_class *cl = drr_find_class(sch, classid); - if (cl != NULL) - cl->refcnt++; - - return (unsigned long)cl; + drr_destroy_class(sch, cl); + return 0; } -static void drr_put_class(struct Qdisc *sch, unsigned long arg) +static unsigned long drr_search_class(struct Qdisc *sch, u32 classid) { - struct drr_class *cl = (struct drr_class *)arg; - - if (--cl->refcnt == 0) - drr_destroy_class(sch, cl); + return (unsigned long)drr_find_class(sch, classid); } static struct tcf_block *drr_tcf_block(struct Qdisc *sch, unsigned long cl) @@ -246,8 +227,7 @@ static void drr_qlen_notify(struct Qdisc *csh, unsigned long arg) { struct drr_class *cl = (struct drr_class *)arg; - if (cl->qdisc->q.qlen == 0) - list_del(&cl->alist); + list_del(&cl->alist); } static int drr_dump_class(struct Qdisc *sch, unsigned long arg, @@ -479,8 +459,7 @@ static void drr_destroy_qdisc(struct Qdisc *sch) static const struct Qdisc_class_ops drr_class_ops = { .change = drr_change_class, .delete = drr_delete_class, - .get = drr_get_class, - .put = drr_put_class, + .find = drr_search_class, .tcf_block = drr_tcf_block, .bind_tcf = drr_bind_tcf, .unbind_tcf = drr_unbind_tcf, diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 6d94fcc3592a95b14d8758731f98641af64f64f0..2836c80c7aa517f0da3c5771a68fa58b625c936b 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -85,21 +85,21 @@ static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg) return p->q; } -static unsigned long dsmark_get(struct Qdisc *sch, u32 classid) +static unsigned long dsmark_find(struct Qdisc *sch, u32 classid) { - pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", - __func__, sch, qdisc_priv(sch), classid); - return TC_H_MIN(classid) + 1; } static unsigned long dsmark_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - return dsmark_get(sch, classid); + pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", + __func__, sch, qdisc_priv(sch), classid); + + return dsmark_find(sch, classid); } -static void dsmark_put(struct Qdisc *sch, unsigned long cl) +static void dsmark_unbind_filter(struct Qdisc *sch, unsigned long cl) { } @@ -469,14 +469,13 @@ static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) static const struct Qdisc_class_ops dsmark_class_ops = { .graft = dsmark_graft, .leaf = dsmark_leaf, - .get = dsmark_get, - .put = dsmark_put, + .find = dsmark_find, .change = dsmark_change, .delete = dsmark_delete, .walk = dsmark_walk, .tcf_block = dsmark_tcf_block, .bind_tcf = dsmark_bind_filter, - .unbind_tcf = dsmark_put, + .unbind_tcf = dsmark_unbind_filter, .dump = dsmark_dump_class, }; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 337f2d6d81e42e278b63443d904955e2c6692f03..de3b57ceca7bd625c874fbece917c944aabc26d8 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -491,10 +491,8 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) if (!q->flows) return -ENOMEM; q->backlogs = kvzalloc(q->flows_cnt * sizeof(u32), GFP_KERNEL); - if (!q->backlogs) { - kvfree(q->flows); + if (!q->backlogs) return -ENOMEM; - } for (i = 0; i < q->flows_cnt; i++) { struct fq_codel_flow *flow = q->flows + i; @@ -579,7 +577,7 @@ static struct Qdisc *fq_codel_leaf(struct Qdisc *sch, unsigned long arg) return NULL; } -static unsigned long fq_codel_get(struct Qdisc *sch, u32 classid) +static unsigned long fq_codel_find(struct Qdisc *sch, u32 classid) { return 0; } @@ -592,7 +590,7 @@ static unsigned long fq_codel_bind(struct Qdisc *sch, unsigned long parent, return 0; } -static void fq_codel_put(struct Qdisc *q, unsigned long cl) +static void fq_codel_unbind(struct Qdisc *q, unsigned long cl) { } @@ -683,11 +681,10 @@ static void fq_codel_walk(struct Qdisc *sch, struct qdisc_walker *arg) static const struct Qdisc_class_ops fq_codel_class_ops = { .leaf = fq_codel_leaf, - .get = fq_codel_get, - .put = fq_codel_put, + .find = fq_codel_find, .tcf_block = fq_codel_tcf_block, .bind_tcf = fq_codel_bind, - .unbind_tcf = fq_codel_put, + .unbind_tcf = fq_codel_unbind, .dump = fq_codel_dump_class, .dump_stats = fq_codel_dump_class_stats, .walk = fq_codel_walk, diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 57ba406f1437323a4ba172d52f14a8b687b86708..bf8c81e07c70457f37eeb167764a2aa33be34ace 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -29,6 +29,7 @@ #include #include #include +#include /* Qdisc to use by default */ const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; @@ -126,7 +127,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, q->q.qlen--; } else skb = NULL; - return skb; + goto trace; } *validate = true; skb = q->skb_bad_txq; @@ -139,7 +140,8 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, q->q.qlen--; goto bulk; } - return NULL; + skb = NULL; + goto trace; } if (!(q->flags & TCQ_F_ONETXQUEUE) || !netif_xmit_frozen_or_stopped(txq)) @@ -151,6 +153,8 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, else try_bulk_dequeue_skb_slow(q, skb, packets); } +trace: + trace_qdisc_dequeue(q, txq, *packets, skb); return skb; } @@ -681,6 +685,7 @@ void qdisc_reset(struct Qdisc *qdisc) qdisc->gso_skb = NULL; } qdisc->q.qlen = 0; + qdisc->qstats.backlog = 0; } EXPORT_SYMBOL(qdisc_reset); @@ -785,7 +790,7 @@ static void attach_default_qdiscs(struct net_device *dev) dev->priv_flags & IFF_NO_QUEUE) { netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL); dev->qdisc = txq->qdisc_sleeping; - refcount_inc(&dev->qdisc->refcnt); + qdisc_refcount_inc(dev->qdisc); } else { qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT); if (qdisc) { diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index b52f74610dc7539fd7804403a6ff41b690243df7..3f88b75488b03275b152298bab0e66ea02298caa 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -110,7 +110,6 @@ enum hfsc_class_flags { struct hfsc_class { struct Qdisc_class_common cl_common; - unsigned int refcnt; /* usage count */ struct gnet_stats_basic_packed bstats; struct gnet_stats_queue qstats; @@ -829,28 +828,6 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time) } } -static void -set_active(struct hfsc_class *cl, unsigned int len) -{ - if (cl->cl_flags & HFSC_RSC) - init_ed(cl, len); - if (cl->cl_flags & HFSC_FSC) - init_vf(cl, len); - -} - -static void -set_passive(struct hfsc_class *cl) -{ - if (cl->cl_flags & HFSC_RSC) - eltree_remove(cl); - - /* - * vttree is now handled in update_vf() so that update_vf(cl, 0, 0) - * needs to be called explicitly to remove a class from vttree. - */ -} - static unsigned int qdisc_peek_len(struct Qdisc *sch) { @@ -981,6 +958,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, } if (cl != NULL) { + int old_flags; + if (parentid) { if (cl->cl_parent && cl->cl_parent->cl_common.classid != parentid) @@ -1001,6 +980,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, } sch_tree_lock(sch); + old_flags = cl->cl_flags; + if (rsc != NULL) hfsc_change_rsc(cl, rsc, cur_time); if (fsc != NULL) @@ -1009,10 +990,21 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, hfsc_change_usc(cl, usc, cur_time); if (cl->qdisc->q.qlen != 0) { - if (cl->cl_flags & HFSC_RSC) - update_ed(cl, qdisc_peek_len(cl->qdisc)); - if (cl->cl_flags & HFSC_FSC) - update_vf(cl, 0, cur_time); + int len = qdisc_peek_len(cl->qdisc); + + if (cl->cl_flags & HFSC_RSC) { + if (old_flags & HFSC_RSC) + update_ed(cl, len); + else + init_ed(cl, len); + } + + if (cl->cl_flags & HFSC_FSC) { + if (old_flags & HFSC_FSC) + update_vf(cl, 0, cur_time); + else + init_vf(cl, len); + } } sch_tree_unlock(sch); @@ -1067,7 +1059,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, hfsc_change_usc(cl, usc, 0); cl->cl_common.classid = classid; - cl->refcnt = 1; cl->sched = q; cl->cl_parent = parent; cl->qdisc = qdisc_create_dflt(sch->dev_queue, @@ -1123,13 +1114,9 @@ hfsc_delete_class(struct Qdisc *sch, unsigned long arg) hfsc_purge_queue(sch, cl); qdisc_class_hash_remove(&q->clhash, &cl->cl_common); - BUG_ON(--cl->refcnt == 0); - /* - * This shouldn't happen: we "hold" one cops->get() when called - * from tc_ctl_tclass; the destroy method is done from cops->put(). - */ - sch_tree_unlock(sch); + + hfsc_destroy_class(sch, cl); return 0; } @@ -1221,30 +1208,18 @@ hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg) { struct hfsc_class *cl = (struct hfsc_class *)arg; - if (cl->qdisc->q.qlen == 0) { - update_vf(cl, 0, 0); - set_passive(cl); - } + /* vttree is now handled in update_vf() so that update_vf(cl, 0, 0) + * needs to be called explicitly to remove a class from vttree. + */ + update_vf(cl, 0, 0); + if (cl->cl_flags & HFSC_RSC) + eltree_remove(cl); } static unsigned long -hfsc_get_class(struct Qdisc *sch, u32 classid) +hfsc_search_class(struct Qdisc *sch, u32 classid) { - struct hfsc_class *cl = hfsc_find_class(classid, sch); - - if (cl != NULL) - cl->refcnt++; - - return (unsigned long)cl; -} - -static void -hfsc_put_class(struct Qdisc *sch, unsigned long arg) -{ - struct hfsc_class *cl = (struct hfsc_class *)arg; - - if (--cl->refcnt == 0) - hfsc_destroy_class(sch, cl); + return (unsigned long)hfsc_find_class(classid, sch); } static unsigned long @@ -1418,6 +1393,8 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) struct tc_hfsc_qopt *qopt; int err; + qdisc_watchdog_init(&q->watchdog, sch); + if (opt == NULL || nla_len(opt) < sizeof(*qopt)) return -EINVAL; qopt = nla_data(opt); @@ -1428,8 +1405,11 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) return err; q->eligible = RB_ROOT; + err = tcf_block_get(&q->root.block, &q->root.filter_list); + if (err) + return err; + q->root.cl_common.classid = sch->handle; - q->root.refcnt = 1; q->root.sched = q; q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); @@ -1444,8 +1424,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) qdisc_class_hash_insert(&q->clhash, &q->root.cl_common); qdisc_class_hash_grow(sch, &q->clhash); - qdisc_watchdog_init(&q->watchdog, sch); - return 0; } @@ -1522,8 +1500,10 @@ hfsc_destroy_qdisc(struct Qdisc *sch) unsigned int i; for (i = 0; i < q->clhash.hashsize; i++) { - hlist_for_each_entry(cl, &q->clhash.hash[i], cl_common.hnode) + hlist_for_each_entry(cl, &q->clhash.hash[i], cl_common.hnode) { tcf_block_put(cl->block); + cl->block = NULL; + } } for (i = 0; i < q->clhash.hashsize; i++) { hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i], @@ -1575,7 +1555,12 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) } if (cl->qdisc->q.qlen == 1) { - set_active(cl, qdisc_pkt_len(skb)); + unsigned int len = qdisc_pkt_len(skb); + + if (cl->cl_flags & HFSC_RSC) + init_ed(cl, len); + if (cl->cl_flags & HFSC_FSC) + init_vf(cl, len); /* * If this is the first packet, isolate the head so an eventual * head drop before the first dequeue operation has no chance @@ -1639,18 +1624,18 @@ hfsc_dequeue(struct Qdisc *sch) if (realtime) cl->cl_cumul += qdisc_pkt_len(skb); - if (cl->qdisc->q.qlen != 0) { - if (cl->cl_flags & HFSC_RSC) { + if (cl->cl_flags & HFSC_RSC) { + if (cl->qdisc->q.qlen != 0) { /* update ed */ next_len = qdisc_peek_len(cl->qdisc); if (realtime) update_ed(cl, next_len); else update_d(cl, next_len); + } else { + /* the class becomes passive */ + eltree_remove(cl); } - } else { - /* the class becomes passive */ - set_passive(cl); } qdisc_bstats_update(sch, skb); @@ -1666,8 +1651,7 @@ static const struct Qdisc_class_ops hfsc_class_ops = { .graft = hfsc_graft_class, .leaf = hfsc_class_leaf, .qlen_notify = hfsc_qlen_notify, - .get = hfsc_get_class, - .put = hfsc_put_class, + .find = hfsc_search_class, .bind_tcf = hfsc_bind_tcf, .unbind_tcf = hfsc_unbind_tcf, .tcf_block = hfsc_tcf_block, diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index 51d3ba682af9ba0f69a3f3c3036519bf527cdee0..73a53c08091baafde3ef776ce9ea99cac9edfd9d 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c @@ -477,6 +477,9 @@ static void hhf_destroy(struct Qdisc *sch) kvfree(q->hhf_valid_bits[i]); } + if (!q->hh_flows) + return; + for (i = 0; i < HH_FLOWS_CNT; i++) { struct hh_flow_state *flow, *next; struct list_head *head = &q->hh_flows[i]; diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 203286ab442799a07808bd8f73af9f07b0482cbd..7e148376ba528efabe5a53a09653f9161c264be7 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -107,7 +107,6 @@ struct htb_class { struct tcf_proto __rcu *filter_list; /* class attached filters */ struct tcf_block *block; int filter_cnt; - int refcnt; /* usage count of this class */ int level; /* our level (see above) */ unsigned int children; @@ -193,6 +192,10 @@ static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch) return container_of(clc, struct htb_class, common); } +static unsigned long htb_search(struct Qdisc *sch, u32 handle) +{ + return (unsigned long)htb_find(handle, sch); +} /** * htb_classify - classify a packet into class * @@ -1017,6 +1020,9 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) int err; int i; + qdisc_watchdog_init(&q->watchdog, sch); + INIT_WORK(&q->work, htb_work_func); + if (!opt) return -EINVAL; @@ -1041,8 +1047,6 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) for (i = 0; i < TC_HTB_NUMPRIO; i++) INIT_LIST_HEAD(q->drops + i); - qdisc_watchdog_init(&q->watchdog, sch); - INIT_WORK(&q->work, htb_work_func); qdisc_skb_head_init(&q->direct_queue); if (tb[TCA_HTB_DIRECT_QLEN]) @@ -1186,16 +1190,7 @@ static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg) { struct htb_class *cl = (struct htb_class *)arg; - if (cl->un.leaf.q->q.qlen == 0) - htb_deactivate(qdisc_priv(sch), cl); -} - -static unsigned long htb_get(struct Qdisc *sch, u32 classid) -{ - struct htb_class *cl = htb_find(classid, sch); - if (cl) - cl->refcnt++; - return (unsigned long)cl; + htb_deactivate(qdisc_priv(sch), cl); } static inline int htb_parent_last_child(struct htb_class *cl) @@ -1258,8 +1253,10 @@ static void htb_destroy(struct Qdisc *sch) tcf_block_put(q->block); for (i = 0; i < q->clhash.hashsize; i++) { - hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) + hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) { tcf_block_put(cl->block); + cl->block = NULL; + } } for (i = 0; i < q->clhash.hashsize; i++) { hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i], @@ -1315,22 +1312,10 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) if (last_child) htb_parent_to_leaf(q, cl, new_q); - BUG_ON(--cl->refcnt == 0); - /* - * This shouldn't happen: we "hold" one cops->get() when called - * from tc_ctl_tclass; the destroy method is done from cops->put(). - */ - sch_tree_unlock(sch); - return 0; -} - -static void htb_put(struct Qdisc *sch, unsigned long arg) -{ - struct htb_class *cl = (struct htb_class *)arg; - if (--cl->refcnt == 0) - htb_destroy_class(sch, cl); + htb_destroy_class(sch, cl); + return 0; } static int htb_change_class(struct Qdisc *sch, u32 classid, @@ -1421,7 +1406,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, } } - cl->refcnt = 1; cl->children = 0; INIT_LIST_HEAD(&cl->un.leaf.drop_list); RB_CLEAR_NODE(&cl->pq_node); @@ -1597,8 +1581,7 @@ static const struct Qdisc_class_ops htb_class_ops = { .graft = htb_graft, .leaf = htb_leaf, .qlen_notify = htb_qlen_notify, - .get = htb_get, - .put = htb_put, + .find = htb_search, .change = htb_change_class, .delete = htb_delete, .walk = htb_walk, diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index d8a9bebcab90c369bc212527638faa4c84149f50..44de4ee51ce9fe963cc722cbad25d7b9af21a5ee 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -27,23 +27,18 @@ static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg) return NULL; } -static unsigned long ingress_get(struct Qdisc *sch, u32 classid) +static unsigned long ingress_find(struct Qdisc *sch, u32 classid) { return TC_H_MIN(classid) + 1; } -static bool ingress_cl_offload(u32 classid) -{ - return true; -} - static unsigned long ingress_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - return ingress_get(sch, classid); + return ingress_find(sch, classid); } -static void ingress_put(struct Qdisc *sch, unsigned long cl) +static void ingress_unbind_filter(struct Qdisc *sch, unsigned long cl) { } @@ -99,13 +94,11 @@ static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) static const struct Qdisc_class_ops ingress_class_ops = { .leaf = ingress_leaf, - .get = ingress_get, - .put = ingress_put, + .find = ingress_find, .walk = ingress_walk, .tcf_block = ingress_tcf_block, - .tcf_cl_offload = ingress_cl_offload, .bind_tcf = ingress_bind_filter, - .unbind_tcf = ingress_put, + .unbind_tcf = ingress_unbind_filter, }; static struct Qdisc_ops ingress_qdisc_ops __read_mostly = { @@ -123,7 +116,7 @@ struct clsact_sched_data { struct tcf_block *egress_block; }; -static unsigned long clsact_get(struct Qdisc *sch, u32 classid) +static unsigned long clsact_find(struct Qdisc *sch, u32 classid) { switch (TC_H_MIN(classid)) { case TC_H_MIN(TC_H_MIN_INGRESS): @@ -134,15 +127,10 @@ static unsigned long clsact_get(struct Qdisc *sch, u32 classid) } } -static bool clsact_cl_offload(u32 classid) -{ - return TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS); -} - static unsigned long clsact_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - return clsact_get(sch, classid); + return clsact_find(sch, classid); } static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl) @@ -194,13 +182,11 @@ static void clsact_destroy(struct Qdisc *sch) static const struct Qdisc_class_ops clsact_class_ops = { .leaf = ingress_leaf, - .get = clsact_get, - .put = ingress_put, + .find = clsact_find, .walk = ingress_walk, .tcf_block = clsact_tcf_block, - .tcf_cl_offload = clsact_cl_offload, .bind_tcf = clsact_bind_filter, - .unbind_tcf = ingress_put, + .unbind_tcf = ingress_unbind_filter, }; static struct Qdisc_ops clsact_qdisc_ops __read_mostly = { diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index cadfdd4f1e521b3d68b8fa62d5797f3ff604651d..f3a3e507422bff4eabda205b9d2f8deea82b1b8e 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -165,7 +165,7 @@ static struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl) return dev_queue->qdisc_sleeping; } -static unsigned long mq_get(struct Qdisc *sch, u32 classid) +static unsigned long mq_find(struct Qdisc *sch, u32 classid) { unsigned int ntx = TC_H_MIN(classid); @@ -174,10 +174,6 @@ static unsigned long mq_get(struct Qdisc *sch, u32 classid) return ntx; } -static void mq_put(struct Qdisc *sch, unsigned long cl) -{ -} - static int mq_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { @@ -223,8 +219,7 @@ static const struct Qdisc_class_ops mq_class_ops = { .select_queue = mq_select_queue, .graft = mq_graft, .leaf = mq_leaf, - .get = mq_get, - .put = mq_put, + .find = mq_find, .walk = mq_walk, .dump = mq_dump_class, .dump_stats = mq_dump_class_stats, diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index e0c02725cd487c2a2c5f063066f29faab8ae479d..6bcdfe6e7b63a39e1c697043375fc3c4995a4a50 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -39,11 +39,9 @@ static void mqprio_destroy(struct Qdisc *sch) } if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) { - struct tc_mqprio_qopt offload = { 0 }; - struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO, - { .mqprio = &offload } }; + struct tc_mqprio_qopt mqprio = {}; - dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, 0, &tc); + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_MQPRIO, &mqprio); } else { netdev_set_num_tc(dev, 0); } @@ -148,16 +146,14 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) * supplied and verified mapping */ if (qopt->hw) { - struct tc_mqprio_qopt offload = *qopt; - struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO, - { .mqprio = &offload } }; + struct tc_mqprio_qopt mqprio = *qopt; - err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, - 0, 0, &tc); + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_MQPRIO, + &mqprio); if (err) return err; - priv->hw_offload = offload.hw; + priv->hw_offload = mqprio.hw; } else { netdev_set_num_tc(dev, qopt->num_tc); for (i = 0; i < qopt->num_tc; i++) @@ -281,7 +277,7 @@ static struct Qdisc *mqprio_leaf(struct Qdisc *sch, unsigned long cl) return dev_queue->qdisc_sleeping; } -static unsigned long mqprio_get(struct Qdisc *sch, u32 classid) +static unsigned long mqprio_find(struct Qdisc *sch, u32 classid) { struct net_device *dev = qdisc_dev(sch); unsigned int ntx = TC_H_MIN(classid); @@ -291,10 +287,6 @@ static unsigned long mqprio_get(struct Qdisc *sch, u32 classid) return ntx; } -static void mqprio_put(struct Qdisc *sch, unsigned long cl) -{ -} - static int mqprio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { @@ -407,8 +399,7 @@ static void mqprio_walk(struct Qdisc *sch, struct qdisc_walker *arg) static const struct Qdisc_class_ops mqprio_class_ops = { .graft = mqprio_graft, .leaf = mqprio_leaf, - .get = mqprio_get, - .put = mqprio_put, + .find = mqprio_find, .walk = mqprio_walk, .dump = mqprio_dump_class, .dump_stats = mqprio_dump_class_stats, diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index f143b7bbaa0d5b00d01d36e9f6eefb54bf677e8f..ff4fc3e0facd7d98b504b5315d7cfe7d0ffdf68a 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -257,12 +257,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt) for (i = 0; i < q->max_bands; i++) q->queues[i] = &noop_qdisc; - err = multiq_tune(sch, opt); - - if (err) - kfree(q->queues); - - return err; + return multiq_tune(sch, opt); } static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb) @@ -306,7 +301,7 @@ multiq_leaf(struct Qdisc *sch, unsigned long arg) return q->queues[band]; } -static unsigned long multiq_get(struct Qdisc *sch, u32 classid) +static unsigned long multiq_find(struct Qdisc *sch, u32 classid) { struct multiq_sched_data *q = qdisc_priv(sch); unsigned long band = TC_H_MIN(classid); @@ -319,11 +314,11 @@ static unsigned long multiq_get(struct Qdisc *sch, u32 classid) static unsigned long multiq_bind(struct Qdisc *sch, unsigned long parent, u32 classid) { - return multiq_get(sch, classid); + return multiq_find(sch, classid); } -static void multiq_put(struct Qdisc *q, unsigned long cl) +static void multiq_unbind(struct Qdisc *q, unsigned long cl) { } @@ -385,12 +380,11 @@ static struct tcf_block *multiq_tcf_block(struct Qdisc *sch, unsigned long cl) static const struct Qdisc_class_ops multiq_class_ops = { .graft = multiq_graft, .leaf = multiq_leaf, - .get = multiq_get, - .put = multiq_put, + .find = multiq_find, .walk = multiq_walk, .tcf_block = multiq_tcf_block, .bind_tcf = multiq_bind, - .unbind_tcf = multiq_put, + .unbind_tcf = multiq_unbind, .dump = multiq_dump_class, .dump_stats = multiq_dump_class_stats, }; diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 1b3dd6190e9386c6f8104153eb9fdc0255e03ac5..b1266e75ca43cf5a66b951ecabccfc5b24069444 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -933,11 +933,11 @@ static int netem_init(struct Qdisc *sch, struct nlattr *opt) struct netem_sched_data *q = qdisc_priv(sch); int ret; + qdisc_watchdog_init(&q->watchdog, sch); + if (!opt) return -EINVAL; - qdisc_watchdog_init(&q->watchdog, sch); - q->loss_model = CLG_RANDOM; ret = netem_change(sch, opt); if (ret) @@ -1096,15 +1096,11 @@ static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg) return q->qdisc; } -static unsigned long netem_get(struct Qdisc *sch, u32 classid) +static unsigned long netem_find(struct Qdisc *sch, u32 classid) { return 1; } -static void netem_put(struct Qdisc *sch, unsigned long arg) -{ -} - static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker) { if (!walker->stop) { @@ -1120,8 +1116,7 @@ static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker) static const struct Qdisc_class_ops netem_class_ops = { .graft = netem_graft, .leaf = netem_leaf, - .get = netem_get, - .put = netem_put, + .find = netem_find, .walk = netem_walk, .dump = netem_dump_class, }; diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index e3e364cc9a70400be95439ca9c808acc410595af..2dd6c68ae91eefe2f4e61b40f833f136c7576871 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -80,7 +80,7 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) if (ret & __NET_XMIT_BYPASS) qdisc_qstats_drop(sch); - kfree_skb(skb); + __qdisc_drop(skb, to_free); return ret; } #endif @@ -260,7 +260,7 @@ prio_leaf(struct Qdisc *sch, unsigned long arg) return q->queues[band]; } -static unsigned long prio_get(struct Qdisc *sch, u32 classid) +static unsigned long prio_find(struct Qdisc *sch, u32 classid) { struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = TC_H_MIN(classid); @@ -272,11 +272,11 @@ static unsigned long prio_get(struct Qdisc *sch, u32 classid) static unsigned long prio_bind(struct Qdisc *sch, unsigned long parent, u32 classid) { - return prio_get(sch, classid); + return prio_find(sch, classid); } -static void prio_put(struct Qdisc *q, unsigned long cl) +static void prio_unbind(struct Qdisc *q, unsigned long cl) { } @@ -338,12 +338,11 @@ static struct tcf_block *prio_tcf_block(struct Qdisc *sch, unsigned long cl) static const struct Qdisc_class_ops prio_class_ops = { .graft = prio_graft, .leaf = prio_leaf, - .get = prio_get, - .put = prio_put, + .find = prio_find, .walk = prio_walk, .tcf_block = prio_tcf_block, .bind_tcf = prio_bind, - .unbind_tcf = prio_put, + .unbind_tcf = prio_unbind, .dump = prio_dump_class, .dump_stats = prio_dump_class_stats, }; diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 0e16dfda0bd7f43b83dbd3b46de270e7864e154c..6ddfd4991108ad9de057a22175d87f667c24f370 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -132,7 +132,6 @@ struct qfq_aggregate; struct qfq_class { struct Qdisc_class_common common; - unsigned int refcnt; unsigned int filter_cnt; struct gnet_stats_basic_packed bstats; @@ -477,7 +476,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (cl == NULL) return -ENOBUFS; - cl->refcnt = 1; cl->common.classid = classid; cl->deficit = lmax; @@ -555,32 +553,15 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg) qfq_purge_queue(cl); qdisc_class_hash_remove(&q->clhash, &cl->common); - BUG_ON(--cl->refcnt == 0); - /* - * This shouldn't happen: we "hold" one cops->get() when called - * from tc_ctl_tclass; the destroy method is done from cops->put(). - */ - sch_tree_unlock(sch); - return 0; -} - -static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid) -{ - struct qfq_class *cl = qfq_find_class(sch, classid); - if (cl != NULL) - cl->refcnt++; - - return (unsigned long)cl; + qfq_destroy_class(sch, cl); + return 0; } -static void qfq_put_class(struct Qdisc *sch, unsigned long arg) +static unsigned long qfq_search_class(struct Qdisc *sch, u32 classid) { - struct qfq_class *cl = (struct qfq_class *)arg; - - if (--cl->refcnt == 0) - qfq_destroy_class(sch, cl); + return (unsigned long)qfq_find_class(sch, classid); } static struct tcf_block *qfq_tcf_block(struct Qdisc *sch, unsigned long cl) @@ -1234,7 +1215,7 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, if (cl == NULL) { if (err & __NET_XMIT_BYPASS) qdisc_qstats_drop(sch); - kfree_skb(skb); + __qdisc_drop(skb, to_free); return err; } pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); @@ -1428,8 +1409,7 @@ static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg) struct qfq_sched *q = qdisc_priv(sch); struct qfq_class *cl = (struct qfq_class *)arg; - if (cl->qdisc->q.qlen == 0) - qfq_deactivate_class(q, cl); + qfq_deactivate_class(q, cl); } static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt) @@ -1511,8 +1491,7 @@ static void qfq_destroy_qdisc(struct Qdisc *sch) static const struct Qdisc_class_ops qfq_class_ops = { .change = qfq_change_class, .delete = qfq_delete_class, - .get = qfq_get_class, - .put = qfq_put_class, + .find = qfq_search_class, .tcf_block = qfq_tcf_block, .bind_tcf = qfq_bind_tcf, .unbind_tcf = qfq_unbind_tcf, diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 11292adce4121022a86aff0aed537be3d9319490..93b9d70a9b28f8ae423f63a57b345ab5da047b6a 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -311,15 +311,11 @@ static struct Qdisc *red_leaf(struct Qdisc *sch, unsigned long arg) return q->qdisc; } -static unsigned long red_get(struct Qdisc *sch, u32 classid) +static unsigned long red_find(struct Qdisc *sch, u32 classid) { return 1; } -static void red_put(struct Qdisc *sch, unsigned long arg) -{ -} - static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker) { if (!walker->stop) { @@ -335,8 +331,7 @@ static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker) static const struct Qdisc_class_ops red_class_ops = { .graft = red_graft, .leaf = red_leaf, - .get = red_get, - .put = red_put, + .find = red_find, .walk = red_walk, .dump = red_dump_class, }; diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 11fb6ec878d6c1179afb0b4e9fa6adaecd0bdf30..cc39e170b4aa2593177cd9364465a5bffa49839d 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -632,12 +632,12 @@ static struct Qdisc *sfb_leaf(struct Qdisc *sch, unsigned long arg) return q->qdisc; } -static unsigned long sfb_get(struct Qdisc *sch, u32 classid) +static unsigned long sfb_find(struct Qdisc *sch, u32 classid) { return 1; } -static void sfb_put(struct Qdisc *sch, unsigned long arg) +static void sfb_unbind(struct Qdisc *sch, unsigned long arg) { } @@ -683,14 +683,13 @@ static unsigned long sfb_bind(struct Qdisc *sch, unsigned long parent, static const struct Qdisc_class_ops sfb_class_ops = { .graft = sfb_graft, .leaf = sfb_leaf, - .get = sfb_get, - .put = sfb_put, + .find = sfb_find, .change = sfb_change_class, .delete = sfb_delete, .walk = sfb_walk, .tcf_block = sfb_tcf_block, .bind_tcf = sfb_bind, - .unbind_tcf = sfb_put, + .unbind_tcf = sfb_unbind, .dump = sfb_dump_class, }; diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index f80ea2cc5f1f4bdee2452c930e3650f79397f3a1..74ea863b824009acb94b956facc889dd80970edf 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -292,7 +292,7 @@ static inline void slot_queue_add(struct sfq_slot *slot, struct sk_buff *skb) slot->skblist_prev = skb; } -static unsigned int sfq_drop(struct Qdisc *sch) +static unsigned int sfq_drop(struct Qdisc *sch, struct sk_buff **to_free) { struct sfq_sched_data *q = qdisc_priv(sch); sfq_index x, d = q->cur_depth; @@ -310,9 +310,8 @@ static unsigned int sfq_drop(struct Qdisc *sch) slot->backlog -= len; sfq_dec(q, x); sch->q.qlen--; - qdisc_qstats_drop(sch); qdisc_qstats_backlog_dec(sch, skb); - kfree_skb(skb); + qdisc_drop(skb, sch, to_free); return len; } @@ -360,7 +359,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) if (hash == 0) { if (ret & __NET_XMIT_BYPASS) qdisc_qstats_drop(sch); - kfree_skb(skb); + __qdisc_drop(skb, to_free); return ret; } hash--; @@ -437,6 +436,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) qdisc_drop(head, sch, to_free); slot_queue_add(slot, skb); + qdisc_tree_reduce_backlog(sch, 0, delta); return NET_XMIT_CN; } @@ -464,12 +464,14 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) return NET_XMIT_SUCCESS; qlen = slot->qlen; - dropped = sfq_drop(sch); + dropped = sfq_drop(sch, to_free); /* Return Congestion Notification only if we dropped a packet * from this flow. */ - if (qlen != slot->qlen) + if (qlen != slot->qlen) { + qdisc_tree_reduce_backlog(sch, 0, dropped - qdisc_pkt_len(skb)); return NET_XMIT_CN; + } /* As we dropped a packet, better let upper stack know this */ qdisc_tree_reduce_backlog(sch, 1, dropped); @@ -625,6 +627,8 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) struct tc_sfq_qopt_v1 *ctl_v1 = NULL; unsigned int qlen, dropped = 0; struct red_parms *p = NULL; + struct sk_buff *to_free = NULL; + struct sk_buff *tail = NULL; if (opt->nla_len < nla_attr_size(sizeof(*ctl))) return -EINVAL; @@ -671,8 +675,13 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) } qlen = sch->q.qlen; - while (sch->q.qlen > q->limit) - dropped += sfq_drop(sch); + while (sch->q.qlen > q->limit) { + dropped += sfq_drop(sch, &to_free); + if (!tail) + tail = to_free; + } + + rtnl_kfree_skbs(to_free, tail); qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped); del_timer(&q->perturb_timer); @@ -713,13 +722,13 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt) int i; int err; + setup_deferrable_timer(&q->perturb_timer, sfq_perturbation, + (unsigned long)sch); + err = tcf_block_get(&q->block, &q->filter_list); if (err) return err; - setup_deferrable_timer(&q->perturb_timer, sfq_perturbation, - (unsigned long)sch); - for (i = 0; i < SFQ_MAX_DEPTH + 1; i++) { q->dep[i].next = i + SFQ_MAX_FLOWS; q->dep[i].prev = i + SFQ_MAX_FLOWS; @@ -805,7 +814,7 @@ static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg) return NULL; } -static unsigned long sfq_get(struct Qdisc *sch, u32 classid) +static unsigned long sfq_find(struct Qdisc *sch, u32 classid) { return 0; } @@ -818,7 +827,7 @@ static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent, return 0; } -static void sfq_put(struct Qdisc *q, unsigned long cl) +static void sfq_unbind(struct Qdisc *q, unsigned long cl) { } @@ -882,11 +891,10 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) static const struct Qdisc_class_ops sfq_class_ops = { .leaf = sfq_leaf, - .get = sfq_get, - .put = sfq_put, + .find = sfq_find, .tcf_block = sfq_tcf_block, .bind_tcf = sfq_bind, - .unbind_tcf = sfq_put, + .unbind_tcf = sfq_unbind, .dump = sfq_dump_class, .dump_stats = sfq_dump_class_stats, .walk = sfq_walk, diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index b2e4b6ad241a8e538c654ef4e8417ab756740a45..120f4f36596786746b89a2832c125e1814d6fd9b 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -425,12 +425,13 @@ static int tbf_init(struct Qdisc *sch, struct nlattr *opt) { struct tbf_sched_data *q = qdisc_priv(sch); + qdisc_watchdog_init(&q->watchdog, sch); + q->qdisc = &noop_qdisc; + if (opt == NULL) return -EINVAL; q->t_c = ktime_get_ns(); - qdisc_watchdog_init(&q->watchdog, sch); - q->qdisc = &noop_qdisc; return tbf_change(sch, opt); } @@ -510,15 +511,11 @@ static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg) return q->qdisc; } -static unsigned long tbf_get(struct Qdisc *sch, u32 classid) +static unsigned long tbf_find(struct Qdisc *sch, u32 classid) { return 1; } -static void tbf_put(struct Qdisc *sch, unsigned long arg) -{ -} - static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker) { if (!walker->stop) { @@ -534,8 +531,7 @@ static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker) static const struct Qdisc_class_ops tbf_class_ops = { .graft = tbf_graft, .leaf = tbf_leaf, - .get = tbf_get, - .put = tbf_put, + .find = tbf_find, .walk = tbf_walk, .dump = tbf_dump_class, }; diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 40ec83679d6ef17b16d5b6e612058a3d0d7222e9..dfb9651e818bb597a5f4cde0b3b7ce3d3d4fd3d5 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -63,11 +63,11 @@ static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc); /* 1st Level Abstractions. */ /* Initialize a new association from provided memory. */ -static struct sctp_association *sctp_association_init(struct sctp_association *asoc, - const struct sctp_endpoint *ep, - const struct sock *sk, - sctp_scope_t scope, - gfp_t gfp) +static struct sctp_association *sctp_association_init( + struct sctp_association *asoc, + const struct sctp_endpoint *ep, + const struct sock *sk, + enum sctp_scope scope, gfp_t gfp) { struct net *net = sock_net(sk); struct sctp_sock *sp; @@ -301,9 +301,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a /* Allocate and initialize a new association */ struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep, - const struct sock *sk, - sctp_scope_t scope, - gfp_t gfp) + const struct sock *sk, + enum sctp_scope scope, gfp_t gfp) { struct sctp_association *asoc; @@ -797,7 +796,7 @@ void sctp_assoc_del_nonprimary_peers(struct sctp_association *asoc, */ void sctp_assoc_control_transport(struct sctp_association *asoc, struct sctp_transport *transport, - sctp_transport_cmd_t command, + enum sctp_transport_cmd command, sctp_sn_error_t error) { struct sctp_ulpevent *event; @@ -1022,11 +1021,11 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) container_of(work, struct sctp_association, base.inqueue.immediate); struct net *net = sock_net(asoc->base.sk); + union sctp_subtype subtype; struct sctp_endpoint *ep; struct sctp_chunk *chunk; struct sctp_inq *inqueue; int state; - sctp_subtype_t subtype; int error = 0; /* The association should be held so we should be safe. */ @@ -1564,7 +1563,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len) * local endpoint and the remote peer. */ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, - sctp_scope_t scope, gfp_t gfp) + enum sctp_scope scope, gfp_t gfp) { int flags; diff --git a/net/sctp/auth.c b/net/sctp/auth.c index e001b01b0e68dffc088a72b1af1eecc2048e95fd..00667c50efa7abdc45dc0635ec59cc8e70878e54 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -185,9 +185,9 @@ static int sctp_auth_compare_vectors(struct sctp_auth_bytes *vector1, * are called the two key vectors. */ static struct sctp_auth_bytes *sctp_auth_make_key_vector( - sctp_random_param_t *random, - sctp_chunks_param_t *chunks, - sctp_hmac_algo_param_t *hmacs, + struct sctp_random_param *random, + struct sctp_chunks_param *chunks, + struct sctp_hmac_algo_param *hmacs, gfp_t gfp) { struct sctp_auth_bytes *new; @@ -226,10 +226,9 @@ static struct sctp_auth_bytes *sctp_auth_make_local_vector( gfp_t gfp) { return sctp_auth_make_key_vector( - (sctp_random_param_t *)asoc->c.auth_random, - (sctp_chunks_param_t *)asoc->c.auth_chunks, - (sctp_hmac_algo_param_t *)asoc->c.auth_hmacs, - gfp); + (struct sctp_random_param *)asoc->c.auth_random, + (struct sctp_chunks_param *)asoc->c.auth_chunks, + (struct sctp_hmac_algo_param *)asoc->c.auth_hmacs, gfp); } /* Make a key vector based on peer's parameters */ diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 1ebc184a0e2355e348c6c6f575e0b20a1daf5dd9..7df3704982f547eda452cac2131afae81a5c7e9e 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -45,9 +45,9 @@ #include /* Forward declarations for internal helpers. */ -static int sctp_copy_one_addr(struct net *, struct sctp_bind_addr *, - union sctp_addr *, sctp_scope_t scope, gfp_t gfp, - int flags); +static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest, + union sctp_addr *addr, enum sctp_scope scope, + gfp_t gfp, int flags); static void sctp_bind_addr_clean(struct sctp_bind_addr *); /* First Level Abstractions. */ @@ -57,7 +57,7 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *); */ int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, - sctp_scope_t scope, gfp_t gfp, + enum sctp_scope scope, gfp_t gfp, int flags) { struct sctp_sockaddr_entry *addr; @@ -440,9 +440,8 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, /* Copy out addresses from the global local address list. */ static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest, - union sctp_addr *addr, - sctp_scope_t scope, gfp_t gfp, - int flags) + union sctp_addr *addr, enum sctp_scope scope, + gfp_t gfp, int flags) { int error = 0; @@ -485,9 +484,10 @@ int sctp_is_any(struct sock *sk, const union sctp_addr *addr) } /* Is 'addr' valid for 'scope'? */ -int sctp_in_scope(struct net *net, const union sctp_addr *addr, sctp_scope_t scope) +int sctp_in_scope(struct net *net, const union sctp_addr *addr, + enum sctp_scope scope) { - sctp_scope_t addr_scope = sctp_scope(addr); + enum sctp_scope addr_scope = sctp_scope(addr); /* The unusable SCTP addresses will not be considered with * any defined scopes. @@ -545,7 +545,7 @@ int sctp_is_ep_boundall(struct sock *sk) ********************************************************************/ /* What is the scope of 'addr'? */ -sctp_scope_t sctp_scope(const union sctp_addr *addr) +enum sctp_scope sctp_scope(const union sctp_addr *addr) { struct sctp_af *af; diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 1323d41e68b82e9cb826dbc3112709db3e0166c9..3afac275ee82dbec825dd71378dffe69a53718a7 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -201,7 +201,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, struct sctp_hmac *hmac_desc = sctp_auth_asoc_get_hmac(asoc); if (hmac_desc) - max_data -= SCTP_PAD4(sizeof(sctp_auth_chunk_t) + + max_data -= SCTP_PAD4(sizeof(struct sctp_auth_chunk) + hmac_desc->hmac_len); } @@ -221,7 +221,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, asoc->outqueue.out_qlen == 0 && list_empty(&asoc->outqueue.retransmit) && msg_len > max_data) - first_len -= SCTP_PAD4(sizeof(sctp_sack_chunk_t)); + first_len -= SCTP_PAD4(sizeof(struct sctp_sack_chunk)); /* Encourage Cookie-ECHO bundling. */ if (asoc->state < SCTP_STATE_COOKIE_ECHOED) diff --git a/net/sctp/debug.c b/net/sctp/debug.c index 2e47eb2f05cbfdbad49f819e4acc4513622c1005..3f619fdcbf0a0b4a6f35ece8021c011f874a2d79 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c @@ -60,7 +60,7 @@ static const char *const sctp_cid_tbl[SCTP_NUM_BASE_CHUNK_TYPES] = { }; /* Lookup "chunk type" debug name. */ -const char *sctp_cname(const sctp_subtype_t cid) +const char *sctp_cname(const union sctp_subtype cid) { if (cid.chunk <= SCTP_CID_BASE_MAX) return sctp_cid_tbl[cid.chunk]; @@ -130,7 +130,7 @@ static const char *const sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = { }; /* Lookup primitive debug name. */ -const char *sctp_pname(const sctp_subtype_t id) +const char *sctp_pname(const union sctp_subtype id) { if (id.primitive <= SCTP_EVENT_PRIMITIVE_MAX) return sctp_primitive_tbl[id.primitive]; @@ -143,7 +143,7 @@ static const char *const sctp_other_tbl[] = { }; /* Lookup "other" debug name. */ -const char *sctp_oname(const sctp_subtype_t id) +const char *sctp_oname(const union sctp_subtype id) { if (id.other <= SCTP_EVENT_OTHER_MAX) return sctp_other_tbl[id.other]; @@ -165,7 +165,7 @@ static const char *const sctp_timer_tbl[] = { }; /* Lookup timer debug name. */ -const char *sctp_tname(const sctp_subtype_t id) +const char *sctp_tname(const union sctp_subtype id) { BUILD_BUG_ON(SCTP_EVENT_TIMEOUT_MAX + 1 != ARRAY_SIZE(sctp_timer_tbl)); diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 0e86f988f83621caaea34b3aa63772e2ec0ee7ca..ee1e601a0b116b4dd705bd5e7735102092f280b0 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -73,13 +73,13 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, * variables. There are arrays that we encode directly * into parameters to make the rest of the operations easier. */ - auth_hmacs = kzalloc(sizeof(sctp_hmac_algo_param_t) + - sizeof(__u16) * SCTP_AUTH_NUM_HMACS, gfp); + auth_hmacs = kzalloc(sizeof(*auth_hmacs) + + sizeof(__u16) * SCTP_AUTH_NUM_HMACS, gfp); if (!auth_hmacs) goto nomem; - auth_chunks = kzalloc(sizeof(sctp_chunks_param_t) + - SCTP_NUM_CHUNK_TYPES, gfp); + auth_chunks = kzalloc(sizeof(*auth_chunks) + + SCTP_NUM_CHUNK_TYPES, gfp); if (!auth_chunks) goto nomem; @@ -382,8 +382,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work) struct sctp_transport *transport; struct sctp_chunk *chunk; struct sctp_inq *inqueue; - sctp_subtype_t subtype; - sctp_state_t state; + union sctp_subtype subtype; + enum sctp_state state; int error = 0; int first_time = 1; /* is this the first time through the loop */ diff --git a/net/sctp/input.c b/net/sctp/input.c index 41eb2ec104601eb0fc9ae37851248752884992b2..92a07141fd07396a816478569f6de18a2aa13ebb 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -1111,7 +1111,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( __be16 peer_port, struct sctp_transport **transportp) { - sctp_addip_chunk_t *asconf = (struct sctp_addip_chunk *)ch; + struct sctp_addip_chunk *asconf = (struct sctp_addip_chunk *)ch; struct sctp_af *af; union sctp_addr_param *param; union sctp_addr paddr; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 2a186b201ad2c20594169633b241dacd0cc971c0..51c4887695909d171285b98ce1be779a3adedbab 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -243,8 +243,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, union sctp_addr *daddr = &t->ipaddr; union sctp_addr dst_saddr; struct in6_addr *final_p, final; + enum sctp_scope scope; __u8 matchlen = 0; - sctp_scope_t scope; memset(fl6, 0, sizeof(struct flowi6)); fl6->daddr = daddr->v6.sin6_addr; @@ -497,7 +497,7 @@ static void sctp_v6_from_addr_param(union sctp_addr *addr, static int sctp_v6_to_addr_param(const union sctp_addr *addr, union sctp_addr_param *param) { - int length = sizeof(sctp_ipv6addr_param_t); + int length = sizeof(struct sctp_ipv6addr_param); param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS; param->v6.param_hdr.length = htons(length); @@ -512,7 +512,9 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, { addr->sa.sa_family = AF_INET6; addr->v6.sin6_port = port; + addr->v6.sin6_flowinfo = 0; addr->v6.sin6_addr = *saddr; + addr->v6.sin6_scope_id = 0; } /* Compare addresses exactly. @@ -624,10 +626,10 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, } /* What is the scope of 'addr'? */ -static sctp_scope_t sctp_v6_scope(union sctp_addr *addr) +static enum sctp_scope sctp_v6_scope(union sctp_addr *addr) { + enum sctp_scope retval; int v6scope; - sctp_scope_t retval; /* The IPv6 scope is really a set of bit fields. * See IFA_* in . Map to a generic SCTP scope. diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index 105ac3327b289cbb88494c116a3a3ffa32e4b60b..aeea6da814417c4541ec95f0272aa7587a4b3ecd 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c @@ -57,7 +57,7 @@ SCTP_DBG_OBJCNT(keys); /* An array to make it easy to pretty print the debug information * to the proc fs. */ -static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = { +static struct sctp_dbg_objcnt_entry sctp_dbg_objcnt[] = { SCTP_DBG_OBJCNT_ENTRY(sock), SCTP_DBG_OBJCNT_ENTRY(ep), SCTP_DBG_OBJCNT_ENTRY(assoc), diff --git a/net/sctp/output.c b/net/sctp/output.c index 9d8504985744f8153f985695e7123f48994d3494..4a865cd06d76cd5b2aa417de618da3203f7b53e4 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -57,15 +57,15 @@ #include /* Forward declarations for private helpers. */ -static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, - struct sctp_chunk *chunk); -static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, - struct sctp_chunk *chunk); +static enum sctp_xmit __sctp_packet_append_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk); +static enum sctp_xmit sctp_packet_can_append_data(struct sctp_packet *packet, + struct sctp_chunk *chunk); static void sctp_packet_append_data(struct sctp_packet *packet, - struct sctp_chunk *chunk); -static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, - struct sctp_chunk *chunk, - u16 chunk_len); + struct sctp_chunk *chunk); +static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet, + struct sctp_chunk *chunk, + u16 chunk_len); static void sctp_packet_reset(struct sctp_packet *packet) { @@ -181,11 +181,11 @@ void sctp_packet_free(struct sctp_packet *packet) * as it can fit in the packet, but any more data that does not fit in this * packet can be sent only after receiving the COOKIE_ACK. */ -sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, - struct sctp_chunk *chunk, - int one_packet, gfp_t gfp) +enum sctp_xmit sctp_packet_transmit_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk, + int one_packet, gfp_t gfp) { - sctp_xmit_t retval; + enum sctp_xmit retval; pr_debug("%s: packet:%p size:%zu chunk:%p size:%d\n", __func__, packet, packet->size, chunk, chunk->skb ? chunk->skb->len : -1); @@ -218,12 +218,12 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, } /* Try to bundle an auth chunk into the packet. */ -static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt, - struct sctp_chunk *chunk) +static enum sctp_xmit sctp_packet_bundle_auth(struct sctp_packet *pkt, + struct sctp_chunk *chunk) { struct sctp_association *asoc = pkt->transport->asoc; + enum sctp_xmit retval = SCTP_XMIT_OK; struct sctp_chunk *auth; - sctp_xmit_t retval = SCTP_XMIT_OK; /* if we don't have an association, we can't do authentication */ if (!asoc) @@ -254,10 +254,10 @@ static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt, } /* Try to bundle a SACK with the packet. */ -static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, - struct sctp_chunk *chunk) +static enum sctp_xmit sctp_packet_bundle_sack(struct sctp_packet *pkt, + struct sctp_chunk *chunk) { - sctp_xmit_t retval = SCTP_XMIT_OK; + enum sctp_xmit retval = SCTP_XMIT_OK; /* If sending DATA and haven't aleady bundled a SACK, try to * bundle one in to the packet. @@ -299,11 +299,11 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, /* Append a chunk to the offered packet reporting back any inability to do * so. */ -static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, - struct sctp_chunk *chunk) +static enum sctp_xmit __sctp_packet_append_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk) { - sctp_xmit_t retval = SCTP_XMIT_OK; __u16 chunk_len = SCTP_PAD4(ntohs(chunk->chunk_hdr->length)); + enum sctp_xmit retval = SCTP_XMIT_OK; /* Check to see if this chunk will fit into the packet */ retval = sctp_packet_will_fit(packet, chunk, chunk_len); @@ -353,10 +353,10 @@ static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, /* Append a chunk to the offered packet reporting back any inability to do * so. */ -sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, - struct sctp_chunk *chunk) +enum sctp_xmit sctp_packet_append_chunk(struct sctp_packet *packet, + struct sctp_chunk *chunk) { - sctp_xmit_t retval = SCTP_XMIT_OK; + enum sctp_xmit retval = SCTP_XMIT_OK; pr_debug("%s: packet:%p chunk:%p\n", __func__, packet, chunk); @@ -653,8 +653,8 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) ********************************************************************/ /* This private function check to see if a chunk can be added */ -static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, - struct sctp_chunk *chunk) +static enum sctp_xmit sctp_packet_can_append_data(struct sctp_packet *packet, + struct sctp_chunk *chunk) { size_t datasize, rwnd, inflight, flight_size; struct sctp_transport *transport = packet->transport; @@ -762,12 +762,12 @@ static void sctp_packet_append_data(struct sctp_packet *packet, sctp_chunk_assign_ssn(chunk); } -static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, - struct sctp_chunk *chunk, - u16 chunk_len) +static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet, + struct sctp_chunk *chunk, + u16 chunk_len) { + enum sctp_xmit retval = SCTP_XMIT_OK; size_t psize, pmtu, maxsize; - sctp_xmit_t retval = SCTP_XMIT_OK; psize = packet->size; if (packet->transport->asoc) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index e8762702a3138cae4fd7192ecc490407b9b19a06..2966ff400755fe93e3658e09d3bb44b9d7d19d2e 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -534,7 +534,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, * one packet out. */ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, - sctp_retransmit_reason_t reason) + enum sctp_retransmit_reason reason) { struct net *net = sock_net(q->asoc->base.sk); @@ -594,14 +594,14 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, int rtx_timeout, int *start_timer) { - struct list_head *lqueue; struct sctp_transport *transport = pkt->transport; - sctp_xmit_t status; struct sctp_chunk *chunk, *chunk1; - int fast_rtx; + struct list_head *lqueue; + enum sctp_xmit status; int error = 0; int timer = 0; int done = 0; + int fast_rtx; lqueue = &q->retransmit; fast_rtx = q->fast_rtx; @@ -781,7 +781,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) struct sctp_transport *transport = NULL; struct sctp_transport *new_transport; struct sctp_chunk *chunk, *tmp; - sctp_xmit_t status; + enum sctp_xmit status; int error = 0; int start_timer = 0; int one_packet = 0; @@ -1197,7 +1197,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) static void sctp_sack_update_unack_data(struct sctp_association *assoc, struct sctp_sackhdr *sack) { - sctp_sack_variable_t *frags; + union sctp_sack_variable *frags; __u16 unack_data; int i; @@ -1224,7 +1224,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk) struct sctp_transport *transport; struct sctp_chunk *tchunk = NULL; struct list_head *lchunk, *transport_list, *temp; - sctp_sack_variable_t *frags = sack->variable; + union sctp_sack_variable *frags = sack->variable; __u32 sack_ctsn, ctsn, tsn; __u32 highest_tsn, highest_new_tsn; __u32 sack_a_rwnd; @@ -1736,10 +1736,10 @@ static void sctp_mark_missing(struct sctp_outq *q, /* Is the given TSN acked by this packet? */ static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn) { - int i; - sctp_sack_variable_t *frags; - __u16 tsn_offset, blocks; __u32 ctsn = ntohl(sack->cum_tsn_ack); + union sctp_sack_variable *frags; + __u16 tsn_offset, blocks; + int i; if (TSN_lte(tsn, ctsn)) goto pass; diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c index f0553a022859235ffed49dc190c319995a143798..c0817f7a89642c9af3e932c00f16e897f279d9d1 100644 --- a/net/sctp/primitive.c +++ b/net/sctp/primitive.c @@ -53,8 +53,8 @@ int sctp_primitive_ ## name(struct net *net, struct sctp_association *asoc, \ void *arg) { \ int error = 0; \ - sctp_event_t event_type; sctp_subtype_t subtype; \ - sctp_state_t state; \ + enum sctp_event event_type; union sctp_subtype subtype; \ + enum sctp_state state; \ struct sctp_endpoint *ep; \ \ event_type = SCTP_EVENT_T_PRIMITIVE; \ diff --git a/net/sctp/probe.c b/net/sctp/probe.c index 6cc2152e074047024436e55292b39342a2eaa51f..1280f85a598d63bf5786a4f88a19c0efac010b88 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c @@ -127,12 +127,13 @@ static const struct file_operations sctpprobe_fops = { .llseek = noop_llseek, }; -static sctp_disposition_t jsctp_sf_eat_sack(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition jsctp_sf_eat_sack( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; struct sk_buff *skb = chunk->skb; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 989a900383b57c57590bff37e3aee7426fb0b156..fcd80feb293f61bd734988f037aa8f210880fb1d 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -196,7 +196,7 @@ static void sctp_free_local_addr_list(struct net *net) /* Copy the local addresses which are valid for 'scope' into 'bp'. */ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp, - sctp_scope_t scope, gfp_t gfp, int copy_flags) + enum sctp_scope scope, gfp_t gfp, int copy_flags) { struct sctp_sockaddr_entry *addr; union sctp_addr laddr; @@ -292,7 +292,7 @@ static void sctp_v4_from_addr_param(union sctp_addr *addr, static int sctp_v4_to_addr_param(const union sctp_addr *addr, union sctp_addr_param *param) { - int length = sizeof(sctp_ipv4addr_param_t); + int length = sizeof(struct sctp_ipv4addr_param); param->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS; param->v4.param_hdr.length = htons(length); @@ -400,9 +400,9 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) * IPv4 scoping can be controlled through sysctl option * net.sctp.addr_scope_policy */ -static sctp_scope_t sctp_v4_scope(union sctp_addr *addr) +static enum sctp_scope sctp_v4_scope(union sctp_addr *addr) { - sctp_scope_t retval; + enum sctp_scope retval; /* Check for unusable SCTP addresses. */ if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) { diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c index 9a647214a91ebc583660db320307e0df1e13e5be..a72a7d925d4631e30cfb0743df392ff4cef456ca 100644 --- a/net/sctp/sctp_diag.c +++ b/net/sctp/sctp_diag.c @@ -70,7 +70,8 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb, info = nla_data(attr); list_for_each_entry_rcu(laddr, address_list, list) { - memcpy(info, &laddr->a, addrlen); + memcpy(info, &laddr->a, sizeof(laddr->a)); + memset(info + sizeof(laddr->a), 0, addrlen - sizeof(laddr->a)); info += addrlen; } @@ -93,7 +94,9 @@ static int inet_diag_msg_sctpaddrs_fill(struct sk_buff *skb, info = nla_data(attr); list_for_each_entry(from, &asoc->peer.transport_addr_list, transports) { - memcpy(info, &from->ipaddr, addrlen); + memcpy(info, &from->ipaddr, sizeof(from->ipaddr)); + memset(info + sizeof(from->ipaddr), 0, + addrlen - sizeof(from->ipaddr)); info += addrlen; } @@ -276,9 +279,11 @@ static int sctp_tsp_dump_one(struct sctp_transport *tsp, void *p) return err; } -static int sctp_sock_dump(struct sock *sk, void *p) +static int sctp_sock_dump(struct sctp_transport *tsp, void *p) { + struct sctp_endpoint *ep = tsp->asoc->ep; struct sctp_comm_param *commp = p; + struct sock *sk = ep->base.sk; struct sk_buff *skb = commp->skb; struct netlink_callback *cb = commp->cb; const struct inet_diag_req_v2 *r = commp->r; @@ -286,9 +291,7 @@ static int sctp_sock_dump(struct sock *sk, void *p) int err = 0; lock_sock(sk); - if (!sctp_sk(sk)->ep) - goto release; - list_for_each_entry(assoc, &sctp_sk(sk)->ep->asocs, asocs) { + list_for_each_entry(assoc, &ep->asocs, asocs) { if (cb->args[4] < cb->args[1]) goto next; @@ -306,7 +309,6 @@ static int sctp_sock_dump(struct sock *sk, void *p) cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh, commp->net_admin) < 0) { - cb->args[3] = 1; err = 1; goto release; } @@ -324,40 +326,30 @@ static int sctp_sock_dump(struct sock *sk, void *p) cb->args[4]++; } cb->args[1] = 0; - cb->args[2]++; cb->args[3] = 0; cb->args[4] = 0; release: release_sock(sk); - sock_put(sk); return err; } -static int sctp_get_sock(struct sctp_transport *tsp, void *p) +static int sctp_sock_filter(struct sctp_transport *tsp, void *p) { struct sctp_endpoint *ep = tsp->asoc->ep; struct sctp_comm_param *commp = p; struct sock *sk = ep->base.sk; - struct netlink_callback *cb = commp->cb; const struct inet_diag_req_v2 *r = commp->r; struct sctp_association *assoc = list_entry(ep->asocs.next, struct sctp_association, asocs); /* find the ep only once through the transports by this condition */ if (tsp->asoc != assoc) - goto out; + return 0; if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family) - goto out; - - sock_hold(sk); - cb->args[5] = (long)sk; + return 0; return 1; - -out: - cb->args[2]++; - return 0; } static int sctp_ep_dump(struct sctp_endpoint *ep, void *p) @@ -471,6 +463,7 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, .r = r, .net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN), }; + int pos = cb->args[2]; /* eps hashtable dumps * args: @@ -500,12 +493,9 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE))) goto done; -next: - cb->args[5] = 0; - sctp_for_each_transport(sctp_get_sock, net, cb->args[2], &commp); - - if (cb->args[5] && !sctp_sock_dump((struct sock *)cb->args[5], &commp)) - goto next; + sctp_for_each_transport(sctp_sock_filter, sctp_sock_dump, + net, &pos, &commp); + cb->args[2] = pos; done: cb->args[1] = cb->args[4]; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 6110447fe51dcbd206cf0e3bf78d4746f0854d3e..ca8f196b6c6c106386a65c75dccd7bc3451798ff 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -69,7 +69,8 @@ static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc, static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc, __u8 type, __u8 flags, int paylen, gfp_t gfp); -static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, +static struct sctp_cookie_param *sctp_pack_cookie( + const struct sctp_endpoint *ep, const struct sctp_association *asoc, const struct sctp_chunk *init_chunk, int *cookie_len, @@ -131,17 +132,17 @@ static const struct sctp_paramhdr prsctp_param = { * provided chunk, as most cause codes will be embedded inside an * abort chunk. */ -void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, - size_t paylen) +void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, + size_t paylen) { - sctp_errhdr_t err; + struct sctp_errhdr err; __u16 len; /* Cause code constants are now defined in network order. */ err.cause = cause_code; - len = sizeof(sctp_errhdr_t) + paylen; + len = sizeof(err) + paylen; err.length = htons(len); - chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); + chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(err), &err); } /* A helper to initialize an op error inside a @@ -150,21 +151,21 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, * if there isn't enough space in the op error chunk */ static int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, - size_t paylen) + size_t paylen) { - sctp_errhdr_t err; + struct sctp_errhdr err; __u16 len; /* Cause code constants are now defined in network order. */ err.cause = cause_code; - len = sizeof(sctp_errhdr_t) + paylen; + len = sizeof(err) + paylen; err.length = htons(len); if (skb_tailroom(chunk->skb) < len) return -ENOSPC; - chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, - sizeof(sctp_errhdr_t), - &err); + + chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, sizeof(err), &err); + return 0; } /* 3.3.2 Initiation (INIT) (1) @@ -212,32 +213,31 @@ static int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, * Supported Address Types (Note 4) Optional 12 */ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, - const struct sctp_bind_addr *bp, - gfp_t gfp, int vparam_len) + const struct sctp_bind_addr *bp, + gfp_t gfp, int vparam_len) { struct net *net = sock_net(asoc->base.sk); + struct sctp_supported_ext_param ext_param; + struct sctp_adaptation_ind_param aiparam; + struct sctp_paramhdr *auth_chunks = NULL; + struct sctp_paramhdr *auth_hmacs = NULL; + struct sctp_supported_addrs_param sat; struct sctp_endpoint *ep = asoc->ep; - struct sctp_inithdr init; - union sctp_params addrs; - size_t chunksize; struct sctp_chunk *retval = NULL; int num_types, addrs_len = 0; + struct sctp_inithdr init; + union sctp_params addrs; struct sctp_sock *sp; - sctp_supported_addrs_param_t sat; + __u8 extensions[4]; + size_t chunksize; __be16 types[2]; - sctp_adaptation_ind_param_t aiparam; - sctp_supported_ext_param_t ext_param; int num_ext = 0; - __u8 extensions[4]; - struct sctp_paramhdr *auth_chunks = NULL, - *auth_hmacs = NULL; /* RFC 2960 3.3.2 Initiation (INIT) (1) * * Note 1: The INIT chunks can contain multiple addresses that * can be IPv4 and/or IPv6 in any combination. */ - retval = NULL; /* Convert the provided bind address list to raw format. */ addrs = sctp_bind_addrs_to_raw(bp, &addrs_len, gfp); @@ -305,8 +305,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, /* If we have any extensions to report, account for that */ if (num_ext) - chunksize += SCTP_PAD4(sizeof(sctp_supported_ext_param_t) + - num_ext); + chunksize += SCTP_PAD4(sizeof(ext_param) + num_ext); /* RFC 2960 3.3.2 Initiation (INIT) (1) * @@ -348,10 +347,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, */ if (num_ext) { ext_param.param_hdr.type = SCTP_PARAM_SUPPORTED_EXT; - ext_param.param_hdr.length = - htons(sizeof(sctp_supported_ext_param_t) + num_ext); - sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), - &ext_param); + ext_param.param_hdr.length = htons(sizeof(ext_param) + num_ext); + sctp_addto_chunk(retval, sizeof(ext_param), &ext_param); sctp_addto_param(retval, num_ext, extensions); } @@ -382,26 +379,24 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, } struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - gfp_t gfp, int unkparam_len) + const struct sctp_chunk *chunk, + gfp_t gfp, int unkparam_len) { + struct sctp_supported_ext_param ext_param; + struct sctp_adaptation_ind_param aiparam; + struct sctp_paramhdr *auth_chunks = NULL; + struct sctp_paramhdr *auth_random = NULL; + struct sctp_paramhdr *auth_hmacs = NULL; + struct sctp_chunk *retval = NULL; + struct sctp_cookie_param *cookie; struct sctp_inithdr initack; - struct sctp_chunk *retval; union sctp_params addrs; struct sctp_sock *sp; - int addrs_len; - sctp_cookie_param_t *cookie; - int cookie_len; + __u8 extensions[4]; size_t chunksize; - sctp_adaptation_ind_param_t aiparam; - sctp_supported_ext_param_t ext_param; int num_ext = 0; - __u8 extensions[4]; - struct sctp_paramhdr *auth_chunks = NULL, - *auth_hmacs = NULL, - *auth_random = NULL; - - retval = NULL; + int cookie_len; + int addrs_len; /* Note: there may be no addresses to embed. */ addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, gfp); @@ -468,8 +463,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, } if (num_ext) - chunksize += SCTP_PAD4(sizeof(sctp_supported_ext_param_t) + - num_ext); + chunksize += SCTP_PAD4(sizeof(ext_param) + num_ext); /* Now allocate and fill out the chunk. */ retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize, gfp); @@ -495,10 +489,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); if (num_ext) { ext_param.param_hdr.type = SCTP_PARAM_SUPPORTED_EXT; - ext_param.param_hdr.length = - htons(sizeof(sctp_supported_ext_param_t) + num_ext); - sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), - &ext_param); + ext_param.param_hdr.length = htons(sizeof(ext_param) + num_ext); + sctp_addto_chunk(retval, sizeof(ext_param), &ext_param); sctp_addto_param(retval, num_ext, extensions); } if (asoc->peer.prsctp_capable) @@ -567,11 +559,11 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, * to insure interoperability. */ struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc, - const struct sctp_chunk *chunk) + const struct sctp_chunk *chunk) { struct sctp_chunk *retval; - void *cookie; int cookie_len; + void *cookie; cookie = asoc->peer.cookie; cookie_len = asoc->peer.cookie_len; @@ -619,7 +611,7 @@ struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc, * Set to zero on transmit and ignored on receipt. */ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc, - const struct sctp_chunk *chunk) + const struct sctp_chunk *chunk) { struct sctp_chunk *retval; @@ -664,15 +656,15 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc, * Note: The CWR is considered a Control chunk. */ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc, - const __u32 lowest_tsn, - const struct sctp_chunk *chunk) + const __u32 lowest_tsn, + const struct sctp_chunk *chunk) { struct sctp_chunk *retval; - sctp_cwrhdr_t cwr; + struct sctp_cwrhdr cwr; cwr.lowest_tsn = htonl(lowest_tsn); retval = sctp_make_control(asoc, SCTP_CID_ECN_CWR, 0, - sizeof(sctp_cwrhdr_t), GFP_ATOMIC); + sizeof(cwr), GFP_ATOMIC); if (!retval) goto nodata; @@ -699,14 +691,14 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc, /* Make an ECNE chunk. This is a congestion experienced report. */ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc, - const __u32 lowest_tsn) + const __u32 lowest_tsn) { struct sctp_chunk *retval; - sctp_ecnehdr_t ecne; + struct sctp_ecnehdr ecne; ecne.lowest_tsn = htonl(lowest_tsn); retval = sctp_make_control(asoc, SCTP_CID_ECN_ECNE, 0, - sizeof(sctp_ecnehdr_t), GFP_ATOMIC); + sizeof(ecne), GFP_ATOMIC); if (!retval) goto nodata; retval->subh.ecne_hdr = @@ -720,9 +712,9 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc, * parameters. However, do not populate the data payload. */ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc, - const struct sctp_sndrcvinfo *sinfo, - int data_len, __u8 flags, __u16 ssn, - gfp_t gfp) + const struct sctp_sndrcvinfo *sinfo, + int data_len, __u8 flags, __u16 ssn, + gfp_t gfp) { struct sctp_chunk *retval; struct sctp_datahdr dp; @@ -760,15 +752,15 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc, */ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) { - struct sctp_chunk *retval; - struct sctp_sackhdr sack; - int len; - __u32 ctsn; - __u16 num_gabs, num_dup_tsns; - struct sctp_association *aptr = (struct sctp_association *)asoc; struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; + struct sctp_association *aptr = (struct sctp_association *)asoc; struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; + __u16 num_gabs, num_dup_tsns; struct sctp_transport *trans; + struct sctp_chunk *retval; + struct sctp_sackhdr sack; + __u32 ctsn; + int len; memset(gabs, 0, sizeof(gabs)); ctsn = sctp_tsnmap_get_ctsn(map); @@ -862,15 +854,15 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc, const struct sctp_chunk *chunk) { + struct sctp_shutdownhdr shut; struct sctp_chunk *retval; - sctp_shutdownhdr_t shut; __u32 ctsn; ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); shut.cum_tsn_ack = htonl(ctsn); retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0, - sizeof(sctp_shutdownhdr_t), GFP_ATOMIC); + sizeof(shut), GFP_ATOMIC); if (!retval) goto nodata; @@ -884,7 +876,7 @@ struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc, } struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, - const struct sctp_chunk *chunk) + const struct sctp_chunk *chunk) { struct sctp_chunk *retval; @@ -907,8 +899,8 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, } struct sctp_chunk *sctp_make_shutdown_complete( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk) { struct sctp_chunk *retval; __u8 flags = 0; @@ -941,8 +933,8 @@ struct sctp_chunk *sctp_make_shutdown_complete( * association, except when responding to an INIT (sctpimpguide 2.41). */ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - const size_t hint) + const struct sctp_chunk *chunk, + const size_t hint) { struct sctp_chunk *retval; __u8 flags = 0; @@ -978,14 +970,15 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, /* Helper to create ABORT with a NO_USER_DATA error. */ struct sctp_chunk *sctp_make_abort_no_data( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk, __u32 tsn) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + __u32 tsn) { struct sctp_chunk *retval; __be32 payload; - retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) - + sizeof(tsn)); + retval = sctp_make_abort(asoc, chunk, + sizeof(struct sctp_errhdr) + sizeof(tsn)); if (!retval) goto no_mem; @@ -1020,7 +1013,8 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, void *payload = NULL; int err; - retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen); + retval = sctp_make_abort(asoc, NULL, + sizeof(struct sctp_errhdr) + paylen); if (!retval) goto err_chunk; @@ -1058,8 +1052,8 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, static void *sctp_addto_param(struct sctp_chunk *chunk, int len, const void *data) { - void *target; int chunklen = ntohs(chunk->chunk_hdr->length); + void *target; target = skb_put(chunk->skb, len); @@ -1077,16 +1071,16 @@ static void *sctp_addto_param(struct sctp_chunk *chunk, int len, /* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */ struct sctp_chunk *sctp_make_abort_violation( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - const __u8 *payload, - const size_t paylen) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + const __u8 *payload, + const size_t paylen) { struct sctp_chunk *retval; struct sctp_paramhdr phdr; - retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen + - sizeof(phdr)); + retval = sctp_make_abort(asoc, chunk, sizeof(struct sctp_errhdr) + + paylen + sizeof(phdr)); if (!retval) goto end; @@ -1103,14 +1097,14 @@ struct sctp_chunk *sctp_make_abort_violation( } struct sctp_chunk *sctp_make_violation_paramlen( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - struct sctp_paramhdr *param) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + struct sctp_paramhdr *param) { - struct sctp_chunk *retval; static const char error[] = "The following parameter had invalid length:"; - size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) + + size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr) + sizeof(*param); + struct sctp_chunk *retval; retval = sctp_make_abort(asoc, chunk, payload_len); if (!retval) @@ -1126,12 +1120,12 @@ struct sctp_chunk *sctp_make_violation_paramlen( } struct sctp_chunk *sctp_make_violation_max_retrans( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk) { - struct sctp_chunk *retval; static const char error[] = "Association exceeded its max_retans count"; - size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t); + size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr); + struct sctp_chunk *retval; retval = sctp_make_abort(asoc, chunk, payload_len); if (!retval) @@ -1146,10 +1140,10 @@ struct sctp_chunk *sctp_make_violation_max_retrans( /* Make a HEARTBEAT chunk. */ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, - const struct sctp_transport *transport) + const struct sctp_transport *transport) { + struct sctp_sender_hb_info hbinfo; struct sctp_chunk *retval; - sctp_sender_hb_info_t hbinfo; retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo), GFP_ATOMIC); @@ -1158,7 +1152,7 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, goto nodata; hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO; - hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); + hbinfo.param_hdr.length = htons(sizeof(hbinfo)); hbinfo.daddr = transport->ipaddr; hbinfo.sent_at = jiffies; hbinfo.hb_nonce = transport->hb_nonce; @@ -1175,8 +1169,9 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, } struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - const void *payload, const size_t paylen) + const struct sctp_chunk *chunk, + const void *payload, + const size_t paylen) { struct sctp_chunk *retval; @@ -1207,14 +1202,15 @@ struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc, * This routine can be used for containing multiple causes in the chunk. */ static struct sctp_chunk *sctp_make_op_error_space( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - size_t size) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + size_t size) { struct sctp_chunk *retval; retval = sctp_make_control(asoc, SCTP_CID_ERROR, 0, - sizeof(sctp_errhdr_t) + size, GFP_ATOMIC); + sizeof(struct sctp_errhdr) + size, + GFP_ATOMIC); if (!retval) goto nodata; @@ -1240,8 +1236,8 @@ static struct sctp_chunk *sctp_make_op_error_space( * to report all the errors, if the incoming chunk is large */ static inline struct sctp_chunk *sctp_make_op_error_fixed( - const struct sctp_association *asoc, - const struct sctp_chunk *chunk) + const struct sctp_association *asoc, + const struct sctp_chunk *chunk) { size_t size = asoc ? asoc->pathmtu : 0; @@ -1253,9 +1249,9 @@ static inline struct sctp_chunk *sctp_make_op_error_fixed( /* Create an Operation Error chunk. */ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, - const struct sctp_chunk *chunk, - __be16 cause_code, const void *payload, - size_t paylen, size_t reserve_tail) + const struct sctp_chunk *chunk, + __be16 cause_code, const void *payload, + size_t paylen, size_t reserve_tail) { struct sctp_chunk *retval; @@ -1274,9 +1270,9 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc) { - struct sctp_chunk *retval; - struct sctp_hmac *hmac_desc; struct sctp_authhdr auth_hdr; + struct sctp_hmac *hmac_desc; + struct sctp_chunk *retval; __u8 *hmac; /* Get the first hmac that the peer told us to use */ @@ -1285,16 +1281,16 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc) return NULL; retval = sctp_make_control(asoc, SCTP_CID_AUTH, 0, - hmac_desc->hmac_len + sizeof(sctp_authhdr_t), - GFP_ATOMIC); + hmac_desc->hmac_len + sizeof(auth_hdr), + GFP_ATOMIC); if (!retval) return NULL; auth_hdr.hmac_id = htons(hmac_desc->hmac_id); auth_hdr.shkey_id = htons(asoc->active_key_id); - retval->subh.auth_hdr = sctp_addto_chunk(retval, sizeof(sctp_authhdr_t), - &auth_hdr); + retval->subh.auth_hdr = sctp_addto_chunk(retval, sizeof(auth_hdr), + &auth_hdr); hmac = skb_put_zero(retval->skb, hmac_desc->hmac_len); @@ -1322,8 +1318,8 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc) * */ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb, - const struct sctp_association *asoc, - struct sock *sk, gfp_t gfp) + const struct sctp_association *asoc, + struct sock *sk, gfp_t gfp) { struct sctp_chunk *retval; @@ -1375,11 +1371,11 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk) * arguments, reserving enough space for a 'paylen' byte payload. */ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc, - __u8 type, __u8 flags, int paylen, - gfp_t gfp) + __u8 type, __u8 flags, int paylen, + gfp_t gfp) { - struct sctp_chunk *retval; struct sctp_chunkhdr *chunk_hdr; + struct sctp_chunk *retval; struct sk_buff *skb; struct sock *sk; @@ -1473,9 +1469,9 @@ void sctp_chunk_put(struct sctp_chunk *ch) */ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) { - void *target; int chunklen = ntohs(chunk->chunk_hdr->length); int padlen = SCTP_PAD4(chunklen) - chunklen; + void *target; skb_put_zero(chunk->skb, padlen); target = skb_put_data(chunk->skb, data, len); @@ -1528,11 +1524,10 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, */ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk) { - struct sctp_datamsg *msg; - struct sctp_chunk *lchunk; struct sctp_stream *stream; - __u16 ssn; - __u16 sid; + struct sctp_chunk *lchunk; + struct sctp_datamsg *msg; + __u16 ssn, sid; if (chunk->has_ssn) return; @@ -1577,12 +1572,12 @@ void sctp_chunk_assign_tsn(struct sctp_chunk *chunk) /* Create a CLOSED association to use with an incoming packet. */ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep, - struct sctp_chunk *chunk, - gfp_t gfp) + struct sctp_chunk *chunk, + gfp_t gfp) { struct sctp_association *asoc; + enum sctp_scope scope; struct sk_buff *skb; - sctp_scope_t scope; /* Create the bare association. */ scope = sctp_scope(sctp_source(chunk)); @@ -1601,14 +1596,15 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep, /* Build a cookie representing asoc. * This INCLUDES the param header needed to put the cookie in the INIT ACK. */ -static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const struct sctp_chunk *init_chunk, - int *cookie_len, - const __u8 *raw_addrs, int addrs_len) +static struct sctp_cookie_param *sctp_pack_cookie( + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const struct sctp_chunk *init_chunk, + int *cookie_len, const __u8 *raw_addrs, + int addrs_len) { - sctp_cookie_param_t *retval; struct sctp_signed_cookie *cookie; + struct sctp_cookie_param *retval; int headersize, bodysize; /* Header size is static data prior to the actual cookie, including @@ -1692,19 +1688,19 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, /* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */ struct sctp_association *sctp_unpack_cookie( - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - struct sctp_chunk *chunk, gfp_t gfp, - int *error, struct sctp_chunk **errp) + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + struct sctp_chunk *chunk, gfp_t gfp, + int *error, struct sctp_chunk **errp) { struct sctp_association *retval = NULL; + int headersize, bodysize, fixed_size; struct sctp_signed_cookie *cookie; + struct sk_buff *skb = chunk->skb; struct sctp_cookie *bear_cookie; - int headersize, bodysize, fixed_size; __u8 *digest = ep->digest; + enum sctp_scope scope; unsigned int len; - sctp_scope_t scope; - struct sk_buff *skb = chunk->skb; ktime_t kt; /* Header size is static data prior to the actual cookie, including @@ -1976,8 +1972,8 @@ static int sctp_process_hn_param(const struct sctp_association *asoc, static int sctp_verify_ext_param(struct net *net, union sctp_params param) { __u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr); - int have_auth = 0; int have_asconf = 0; + int have_auth = 0; int i; for (i = 0; i < num_ext; i++) { @@ -2007,10 +2003,10 @@ static int sctp_verify_ext_param(struct net *net, union sctp_params param) } static void sctp_process_ext_param(struct sctp_association *asoc, - union sctp_params param) + union sctp_params param) { - struct net *net = sock_net(asoc->base.sk); __u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr); + struct net *net = sock_net(asoc->base.sk); int i; for (i = 0; i < num_ext; i++) { @@ -2067,10 +2063,11 @@ static void sctp_process_ext_param(struct sctp_association *asoc, * SCTP_IERROR_ERROR - stop and report an error. * SCTP_IERROR_NOMEME - out of memory. */ -static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, - union sctp_params param, - struct sctp_chunk *chunk, - struct sctp_chunk **errp) +static enum sctp_ierror sctp_process_unk_param( + const struct sctp_association *asoc, + union sctp_params param, + struct sctp_chunk *chunk, + struct sctp_chunk **errp) { int retval = SCTP_IERROR_NO_ERROR; @@ -2119,13 +2116,13 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, * SCTP_IERROR_ERROR - stop processing, trigger an ERROR * SCTP_IERROR_NO_ERROR - continue with the chunk */ -static sctp_ierror_t sctp_verify_param(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - union sctp_params param, - enum sctp_cid cid, - struct sctp_chunk *chunk, - struct sctp_chunk **err_chunk) +static enum sctp_ierror sctp_verify_param(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + union sctp_params param, + enum sctp_cid cid, + struct sctp_chunk *chunk, + struct sctp_chunk **err_chunk) { struct sctp_hmac_algo_param *hmacs; int retval = SCTP_IERROR_NO_ERROR; @@ -2310,13 +2307,13 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, struct sctp_init_chunk *peer_init, gfp_t gfp) { struct net *net = sock_net(asoc->base.sk); - union sctp_params param; struct sctp_transport *transport; struct list_head *pos, *temp; - struct sctp_af *af; + union sctp_params param; union sctp_addr addr; - char *cookie; + struct sctp_af *af; int src_match = 0; + char *cookie; /* We must include the address that the INIT packet came from. * This is the only address that matters for an INIT packet. @@ -2500,16 +2497,15 @@ static int sctp_process_param(struct sctp_association *asoc, gfp_t gfp) { struct net *net = sock_net(asoc->base.sk); - union sctp_addr addr; - int i; - __u16 sat; - int retval = 1; - sctp_scope_t scope; - u32 stale; - struct sctp_af *af; + struct sctp_endpoint *ep = asoc->ep; union sctp_addr_param *addr_param; struct sctp_transport *t; - struct sctp_endpoint *ep = asoc->ep; + enum sctp_scope scope; + union sctp_addr addr; + struct sctp_af *af; + int retval = 1, i; + u32 stale; + __u16 sat; /* We maintain all INIT parameters in network byte order all the * time. This allows us to not worry about whether the parameters @@ -2617,7 +2613,7 @@ static int sctp_process_param(struct sctp_association *asoc, if (!net->sctp.addip_enable) goto fall_through; - addr_param = param.v + sizeof(sctp_addip_param_t); + addr_param = param.v + sizeof(struct sctp_addip_param); af = sctp_get_af_specific(param_type2af(addr_param->p.type)); if (af == NULL) @@ -2754,7 +2750,7 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc, union sctp_addr *addr, int vparam_len) { - sctp_addiphdr_t asconf; + struct sctp_addiphdr asconf; struct sctp_chunk *retval; int length = sizeof(asconf) + vparam_len; union sctp_addr_param addrparam; @@ -2807,22 +2803,20 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc, * */ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc, - union sctp_addr *laddr, - struct sockaddr *addrs, - int addrcnt, - __be16 flags) -{ - sctp_addip_param_t param; - struct sctp_chunk *retval; - union sctp_addr_param addr_param; - union sctp_addr *addr; - void *addr_buf; - struct sctp_af *af; - int paramlen = sizeof(param); - int addr_param_len = 0; - int totallen = 0; - int i; - int del_pickup = 0; + union sctp_addr *laddr, + struct sockaddr *addrs, + int addrcnt, __be16 flags) +{ + union sctp_addr_param addr_param; + struct sctp_addip_param param; + int paramlen = sizeof(param); + struct sctp_chunk *retval; + int addr_param_len = 0; + union sctp_addr *addr; + int totallen = 0, i; + int del_pickup = 0; + struct sctp_af *af; + void *addr_buf; /* Get total length of all the address parameters. */ addr_buf = addrs; @@ -2898,12 +2892,12 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc, struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, union sctp_addr *addr) { - sctp_addip_param_t param; - struct sctp_chunk *retval; - int len = sizeof(param); - union sctp_addr_param addrparam; - int addrlen; - struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family); + struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family); + union sctp_addr_param addrparam; + struct sctp_addip_param param; + struct sctp_chunk *retval; + int len = sizeof(param); + int addrlen; addrlen = af->to_addr_param(addr, &addrparam); if (!addrlen) @@ -2947,9 +2941,9 @@ struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc, __u32 serial, int vparam_len) { - sctp_addiphdr_t asconf; - struct sctp_chunk *retval; - int length = sizeof(asconf) + vparam_len; + struct sctp_addiphdr asconf; + struct sctp_chunk *retval; + int length = sizeof(asconf) + vparam_len; /* Create the chunk. */ retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length, @@ -2967,13 +2961,14 @@ static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *as /* Add response parameters to an ASCONF_ACK chunk. */ static void sctp_add_asconf_response(struct sctp_chunk *chunk, __be32 crr_id, - __be16 err_code, sctp_addip_param_t *asconf_param) + __be16 err_code, + struct sctp_addip_param *asconf_param) { - sctp_addip_param_t ack_param; - sctp_errhdr_t err_param; - int asconf_param_len = 0; - int err_param_len = 0; - __be16 response_type; + struct sctp_addip_param ack_param; + struct sctp_errhdr err_param; + int asconf_param_len = 0; + int err_param_len = 0; + __be16 response_type; if (SCTP_ERROR_NO_ERROR == err_code) { response_type = SCTP_PARAM_SUCCESS_REPORT; @@ -3008,15 +3003,15 @@ static void sctp_add_asconf_response(struct sctp_chunk *chunk, __be32 crr_id, /* Process a asconf parameter. */ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, - struct sctp_chunk *asconf, - sctp_addip_param_t *asconf_param) + struct sctp_chunk *asconf, + struct sctp_addip_param *asconf_param) { + union sctp_addr_param *addr_param; struct sctp_transport *peer; - struct sctp_af *af; union sctp_addr addr; - union sctp_addr_param *addr_param; + struct sctp_af *af; - addr_param = (void *)asconf_param + sizeof(sctp_addip_param_t); + addr_param = (void *)asconf_param + sizeof(*asconf_param); if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP && asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP && @@ -3141,10 +3136,11 @@ bool sctp_verify_asconf(const struct sctp_association *asoc, struct sctp_chunk *chunk, bool addr_param_needed, struct sctp_paramhdr **errp) { - sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) chunk->chunk_hdr; - union sctp_params param; + struct sctp_addip_chunk *addip; bool addr_param_seen = false; + union sctp_params param; + addip = (struct sctp_addip_chunk *)chunk->chunk_hdr; sctp_walk_params(param, addip, addip_hdr.params) { size_t length = ntohs(param.p->length); @@ -3153,7 +3149,7 @@ bool sctp_verify_asconf(const struct sctp_association *asoc, case SCTP_PARAM_ERR_CAUSE: break; case SCTP_PARAM_IPV4_ADDRESS: - if (length != sizeof(sctp_ipv4addr_param_t)) + if (length != sizeof(struct sctp_ipv4addr_param)) return false; /* ensure there is only one addr param and it's in the * beginning of addip_hdr params, or we reject it. @@ -3163,7 +3159,7 @@ bool sctp_verify_asconf(const struct sctp_association *asoc, addr_param_seen = true; break; case SCTP_PARAM_IPV6_ADDRESS: - if (length != sizeof(sctp_ipv6addr_param_t)) + if (length != sizeof(struct sctp_ipv6addr_param)) return false; if (param.v != addip->addip_hdr.params) return false; @@ -3176,13 +3172,13 @@ bool sctp_verify_asconf(const struct sctp_association *asoc, if (addr_param_needed && !addr_param_seen) return false; length = ntohs(param.addip->param_hdr.length); - if (length < sizeof(sctp_addip_param_t) + + if (length < sizeof(struct sctp_addip_param) + sizeof(**errp)) return false; break; case SCTP_PARAM_SUCCESS_REPORT: case SCTP_PARAM_ADAPTATION_LAYER_IND: - if (length != sizeof(sctp_addip_param_t)) + if (length != sizeof(struct sctp_addip_param)) return false; break; default: @@ -3208,24 +3204,24 @@ bool sctp_verify_asconf(const struct sctp_association *asoc, struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, struct sctp_chunk *asconf) { - sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) asconf->chunk_hdr; + union sctp_addr_param *addr_param; + struct sctp_addip_chunk *addip; + struct sctp_chunk *asconf_ack; bool all_param_pass = true; + struct sctp_addiphdr *hdr; + int length = 0, chunk_len; union sctp_params param; - sctp_addiphdr_t *hdr; - union sctp_addr_param *addr_param; - struct sctp_chunk *asconf_ack; - __be16 err_code; - int length = 0; - int chunk_len; - __u32 serial; + __be16 err_code; + __u32 serial; + addip = (struct sctp_addip_chunk *)asconf->chunk_hdr; chunk_len = ntohs(asconf->chunk_hdr->length) - sizeof(struct sctp_chunkhdr); - hdr = (sctp_addiphdr_t *)asconf->skb->data; + hdr = (struct sctp_addiphdr *)asconf->skb->data; serial = ntohl(hdr->serial); /* Skip the addiphdr and store a pointer to address parameter. */ - length = sizeof(sctp_addiphdr_t); + length = sizeof(*hdr); addr_param = (union sctp_addr_param *)(asconf->skb->data + length); chunk_len -= length; @@ -3291,16 +3287,16 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, /* Process a asconf parameter that is successfully acked. */ static void sctp_asconf_param_success(struct sctp_association *asoc, - sctp_addip_param_t *asconf_param) + struct sctp_addip_param *asconf_param) { - struct sctp_af *af; - union sctp_addr addr; struct sctp_bind_addr *bp = &asoc->base.bind_addr; union sctp_addr_param *addr_param; - struct sctp_transport *transport; struct sctp_sockaddr_entry *saddr; + struct sctp_transport *transport; + union sctp_addr addr; + struct sctp_af *af; - addr_param = (void *)asconf_param + sizeof(sctp_addip_param_t); + addr_param = (void *)asconf_param + sizeof(*asconf_param); /* We have checked the packet before, so we do not check again. */ af = sctp_get_af_specific(param_type2af(addr_param->p.type)); @@ -3351,14 +3347,14 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, * specific success indication is present for the parameter. */ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack, - sctp_addip_param_t *asconf_param, - int no_err) + struct sctp_addip_param *asconf_param, + int no_err) { - sctp_addip_param_t *asconf_ack_param; - sctp_errhdr_t *err_param; - int length; - int asconf_ack_len; - __be16 err_code; + struct sctp_addip_param *asconf_ack_param; + struct sctp_errhdr *err_param; + int asconf_ack_len; + __be16 err_code; + int length; if (no_err) err_code = SCTP_ERROR_NO_ERROR; @@ -3371,9 +3367,9 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack, /* Skip the addiphdr from the asconf_ack chunk and store a pointer to * the first asconf_ack parameter. */ - length = sizeof(sctp_addiphdr_t); - asconf_ack_param = (sctp_addip_param_t *)(asconf_ack->skb->data + - length); + length = sizeof(struct sctp_addiphdr); + asconf_ack_param = (struct sctp_addip_param *)(asconf_ack->skb->data + + length); asconf_ack_len -= length; while (asconf_ack_len > 0) { @@ -3382,7 +3378,7 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack, case SCTP_PARAM_SUCCESS_REPORT: return SCTP_ERROR_NO_ERROR; case SCTP_PARAM_ERR_CAUSE: - length = sizeof(sctp_addip_param_t); + length = sizeof(*asconf_ack_param); err_param = (void *)asconf_ack_param + length; asconf_ack_len -= length; if (asconf_ack_len > 0) @@ -3407,20 +3403,20 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack, int sctp_process_asconf_ack(struct sctp_association *asoc, struct sctp_chunk *asconf_ack) { - struct sctp_chunk *asconf = asoc->addip_last_asconf; - union sctp_addr_param *addr_param; - sctp_addip_param_t *asconf_param; - int length = 0; - int asconf_len = asconf->skb->len; - int all_param_pass = 0; - int no_err = 1; - int retval = 0; - __be16 err_code = SCTP_ERROR_NO_ERROR; + struct sctp_chunk *asconf = asoc->addip_last_asconf; + struct sctp_addip_param *asconf_param; + __be16 err_code = SCTP_ERROR_NO_ERROR; + union sctp_addr_param *addr_param; + int asconf_len = asconf->skb->len; + int all_param_pass = 0; + int length = 0; + int no_err = 1; + int retval = 0; /* Skip the chunkhdr and addiphdr from the last asconf sent and store * a pointer to address parameter. */ - length = sizeof(sctp_addip_chunk_t); + length = sizeof(struct sctp_addip_chunk); addr_param = (union sctp_addr_param *)(asconf->skb->data + length); asconf_len -= length; @@ -3436,7 +3432,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, * failures are indicated, then all request(s) are considered * successful. */ - if (asconf_ack->skb->len == sizeof(sctp_addiphdr_t)) + if (asconf_ack->skb->len == sizeof(struct sctp_addiphdr)) all_param_pass = 1; /* Process the TLVs contained in the last sent ASCONF chunk. */ @@ -3542,9 +3538,8 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, * \ \ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -static struct sctp_chunk *sctp_make_reconf( - const struct sctp_association *asoc, - int length) +static struct sctp_chunk *sctp_make_reconf(const struct sctp_association *asoc, + int length) { struct sctp_reconf_chunk *reconf; struct sctp_chunk *retval; @@ -3595,9 +3590,9 @@ static struct sctp_chunk *sctp_make_reconf( * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct sctp_chunk *sctp_make_strreset_req( - const struct sctp_association *asoc, - __u16 stream_num, __u16 *stream_list, - bool out, bool in) + const struct sctp_association *asoc, + __u16 stream_num, __u16 *stream_list, + bool out, bool in) { struct sctp_strreset_outreq outreq; __u16 stream_len = stream_num * 2; @@ -3649,7 +3644,7 @@ struct sctp_chunk *sctp_make_strreset_req( * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct sctp_chunk *sctp_make_strreset_tsnreq( - const struct sctp_association *asoc) + const struct sctp_association *asoc) { struct sctp_strreset_tsnreq tsnreq; __u16 length = sizeof(tsnreq); @@ -3680,8 +3675,8 @@ struct sctp_chunk *sctp_make_strreset_tsnreq( * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct sctp_chunk *sctp_make_strreset_addstrm( - const struct sctp_association *asoc, - __u16 out, __u16 in) + const struct sctp_association *asoc, + __u16 out, __u16 in) { struct sctp_strreset_addstrm addstrm; __u16 size = sizeof(addstrm); @@ -3725,9 +3720,8 @@ struct sctp_chunk *sctp_make_strreset_addstrm( * | Result | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -struct sctp_chunk *sctp_make_strreset_resp( - const struct sctp_association *asoc, - __u32 result, __u32 sn) +struct sctp_chunk *sctp_make_strreset_resp(const struct sctp_association *asoc, + __u32 result, __u32 sn) { struct sctp_strreset_resp resp; __u16 length = sizeof(resp); @@ -3762,10 +3756,10 @@ struct sctp_chunk *sctp_make_strreset_resp( * | Receiver's Next TSN (optional) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -struct sctp_chunk *sctp_make_strreset_tsnresp( - struct sctp_association *asoc, - __u32 result, __u32 sn, - __u32 sender_tsn, __u32 receiver_tsn) +struct sctp_chunk *sctp_make_strreset_tsnresp(struct sctp_association *asoc, + __u32 result, __u32 sn, + __u32 sender_tsn, + __u32 receiver_tsn) { struct sctp_strreset_resptsn tsnresp; __u16 length = sizeof(tsnresp); diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index d6e5e9e0fd6d429640e411f55b7d5ed94f6f3781..e6a2974e020e1a4232d94e6c2933eebff5f8acb4 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -51,22 +51,23 @@ #include #include -static int sctp_cmd_interpreter(sctp_event_t event_type, - sctp_subtype_t subtype, - sctp_state_t state, +static int sctp_cmd_interpreter(enum sctp_event event_type, + union sctp_subtype subtype, + enum sctp_state state, struct sctp_endpoint *ep, struct sctp_association *asoc, void *event_arg, - sctp_disposition_t status, - sctp_cmd_seq_t *commands, + enum sctp_disposition status, + struct sctp_cmd_seq *commands, gfp_t gfp); -static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, - sctp_state_t state, +static int sctp_side_effects(enum sctp_event event_type, + union sctp_subtype subtype, + enum sctp_state state, struct sctp_endpoint *ep, struct sctp_association **asoc, void *event_arg, - sctp_disposition_t status, - sctp_cmd_seq_t *commands, + enum sctp_disposition status, + struct sctp_cmd_seq *commands, gfp_t gfp); /******************************************************************** @@ -96,8 +97,8 @@ static void sctp_do_ecn_ce_work(struct sctp_association *asoc, * that was originally marked with the CE bit. */ static struct sctp_chunk *sctp_do_ecn_ecne_work(struct sctp_association *asoc, - __u32 lowest_tsn, - struct sctp_chunk *chunk) + __u32 lowest_tsn, + struct sctp_chunk *chunk) { struct sctp_chunk *repl; @@ -149,11 +150,11 @@ static void sctp_do_ecn_cwr_work(struct sctp_association *asoc, /* Generate SACK if necessary. We call this at the end of a packet. */ static int sctp_gen_sack(struct sctp_association *asoc, int force, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { + struct sctp_transport *trans = asoc->peer.last_data_from; __u32 ctsn, max_tsn_seen; struct sctp_chunk *sack; - struct sctp_transport *trans = asoc->peer.last_data_from; int error = 0; if (force || @@ -243,11 +244,11 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, */ void sctp_generate_t3_rtx_event(unsigned long peer) { - int error; struct sctp_transport *transport = (struct sctp_transport *) peer; struct sctp_association *asoc = transport->asoc; struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); + int error; /* Check whether a task is in the sock. */ @@ -280,7 +281,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer) * for timeouts which use the association as their parameter. */ static void sctp_generate_timeout_event(struct sctp_association *asoc, - sctp_event_timeout_t timeout_type) + enum sctp_event_timeout timeout_type) { struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); @@ -360,12 +361,12 @@ static void sctp_generate_autoclose_event(unsigned long data) */ void sctp_generate_heartbeat_event(unsigned long data) { - int error = 0; struct sctp_transport *transport = (struct sctp_transport *) data; struct sctp_association *asoc = transport->asoc; struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); u32 elapsed, timeout; + int error = 0; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -405,7 +406,7 @@ void sctp_generate_heartbeat_event(unsigned long data) */ void sctp_generate_proto_unreach_event(unsigned long data) { - struct sctp_transport *transport = (struct sctp_transport *) data; + struct sctp_transport *transport = (struct sctp_transport *)data; struct sctp_association *asoc = transport->asoc; struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); @@ -471,7 +472,7 @@ void sctp_generate_reconf_event(unsigned long data) /* Inject a SACK Timeout event into the state machine. */ static void sctp_generate_sack_event(unsigned long data) { - struct sctp_association *asoc = (struct sctp_association *) data; + struct sctp_association *asoc = (struct sctp_association *)data; sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK); } @@ -505,7 +506,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = { * notification SHOULD be sent to the upper layer. * */ -static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, +static void sctp_do_8_2_transport_strike(struct sctp_cmd_seq *commands, struct sctp_association *asoc, struct sctp_transport *transport, int is_hb) @@ -577,7 +578,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, } /* Worker routine to handle INIT command failure. */ -static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands, +static void sctp_cmd_init_failed(struct sctp_cmd_seq *commands, struct sctp_association *asoc, unsigned int error) { @@ -600,15 +601,16 @@ static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands, } /* Worker routine to handle SCTP_CMD_ASSOC_FAILED. */ -static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, +static void sctp_cmd_assoc_failed(struct sctp_cmd_seq *commands, struct sctp_association *asoc, - sctp_event_t event_type, - sctp_subtype_t subtype, + enum sctp_event event_type, + union sctp_subtype subtype, struct sctp_chunk *chunk, unsigned int error) { struct sctp_ulpevent *event; struct sctp_chunk *abort; + /* Cancel any partial delivery in progress. */ sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); @@ -644,7 +646,7 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, * since all other cases use "temporary" associations and can do all * their work in statefuns directly. */ -static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, +static int sctp_cmd_process_init(struct sctp_cmd_seq *commands, struct sctp_association *asoc, struct sctp_chunk *chunk, struct sctp_init_chunk *peer_init, @@ -666,7 +668,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, } /* Helper function to break out starting up of heartbeat timers. */ -static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds, +static void sctp_cmd_hb_timers_start(struct sctp_cmd_seq *cmds, struct sctp_association *asoc) { struct sctp_transport *t; @@ -679,7 +681,7 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds, sctp_transport_reset_hb_timer(t); } -static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds, +static void sctp_cmd_hb_timers_stop(struct sctp_cmd_seq *cmds, struct sctp_association *asoc) { struct sctp_transport *t; @@ -694,7 +696,7 @@ static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds, } /* Helper function to stop any pending T3-RTX timers */ -static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds, +static void sctp_cmd_t3_rtx_timers_stop(struct sctp_cmd_seq *cmds, struct sctp_association *asoc) { struct sctp_transport *t; @@ -708,12 +710,12 @@ static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds, /* Helper function to handle the reception of an HEARTBEAT ACK. */ -static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, +static void sctp_cmd_transport_on(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, struct sctp_transport *t, struct sctp_chunk *chunk) { - sctp_sender_hb_info_t *hbinfo; + struct sctp_sender_hb_info *hbinfo; int was_unconfirmed = 0; /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the @@ -767,7 +769,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, if (t->rto_pending == 0) t->rto_pending = 1; - hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; + hbinfo = (struct sctp_sender_hb_info *)chunk->skb->data; sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at)); /* Update the heartbeat timer. */ @@ -779,7 +781,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, /* Helper function to process the process SACK command. */ -static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, +static int sctp_cmd_process_sack(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, struct sctp_chunk *chunk) { @@ -801,7 +803,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, /* Helper function to set the timeout value for T2-SHUTDOWN timer and to set * the transport for a shutdown chunk. */ -static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, +static void sctp_cmd_setup_t2(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, struct sctp_chunk *chunk) { @@ -818,7 +820,7 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; } -static void sctp_cmd_assoc_update(sctp_cmd_seq_t *cmds, +static void sctp_cmd_assoc_update(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, struct sctp_association *new) { @@ -828,7 +830,7 @@ static void sctp_cmd_assoc_update(sctp_cmd_seq_t *cmds, if (!sctp_assoc_update(asoc, new)) return; - abort = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t)); + abort = sctp_make_abort(asoc, NULL, sizeof(struct sctp_errhdr)); if (abort) { sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); sctp_add_cmd_sf(cmds, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); @@ -841,9 +843,9 @@ static void sctp_cmd_assoc_update(sctp_cmd_seq_t *cmds, } /* Helper function to change the state of an association. */ -static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, +static void sctp_cmd_new_state(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, - sctp_state_t state) + enum sctp_state state) { struct sock *sk = asoc->base.sk; @@ -901,7 +903,7 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, } /* Helper function to delete an association. */ -static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds, +static void sctp_cmd_delete_tcb(struct sctp_cmd_seq *cmds, struct sctp_association *asoc) { struct sock *sk = asoc->base.sk; @@ -923,9 +925,9 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds, * destination address (we use active path instead of primary path just * because primary path may be inactive. */ -static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds, - struct sctp_association *asoc, - struct sctp_chunk *chunk) +static void sctp_cmd_setup_t4(struct sctp_cmd_seq *cmds, + struct sctp_association *asoc, + struct sctp_chunk *chunk) { struct sctp_transport *t; @@ -935,7 +937,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds, } /* Process an incoming Operation Error Chunk. */ -static void sctp_cmd_process_operr(sctp_cmd_seq_t *cmds, +static void sctp_cmd_process_operr(struct sctp_cmd_seq *cmds, struct sctp_association *asoc, struct sctp_chunk *chunk) { @@ -990,6 +992,7 @@ static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk) { struct sctp_fwdtsn_skip *skip; + /* Walk through all the skipped SSNs */ sctp_walk_fwdtsn(skip, chunk) { sctp_ulpq_skip(ulpq, ntohs(skip->stream), ntohs(skip->ssn)); @@ -1002,8 +1005,8 @@ static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq, static void sctp_cmd_del_non_primary(struct sctp_association *asoc) { struct sctp_transport *t; - struct list_head *pos; struct list_head *temp; + struct list_head *pos; list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { t = list_entry(pos, struct sctp_transport, transports); @@ -1024,9 +1027,9 @@ static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error) } /* Helper function to generate an association change event */ -static void sctp_cmd_assoc_change(sctp_cmd_seq_t *commands, - struct sctp_association *asoc, - u8 state) +static void sctp_cmd_assoc_change(struct sctp_cmd_seq *commands, + struct sctp_association *asoc, + u8 state) { struct sctp_ulpevent *ev; @@ -1039,7 +1042,7 @@ static void sctp_cmd_assoc_change(sctp_cmd_seq_t *commands, } /* Helper function to generate an adaptation indication event */ -static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands, +static void sctp_cmd_adaptation_ind(struct sctp_cmd_seq *commands, struct sctp_association *asoc) { struct sctp_ulpevent *ev; @@ -1052,8 +1055,8 @@ static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands, static void sctp_cmd_t1_timer_update(struct sctp_association *asoc, - sctp_event_timeout_t timer, - char *name) + enum sctp_event_timeout timer, + char *name) { struct sctp_transport *t; @@ -1139,22 +1142,20 @@ static void sctp_cmd_send_asconf(struct sctp_association *asoc) * If you want to understand all of lksctp, this is a * good place to start. */ -int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype, - sctp_state_t state, - struct sctp_endpoint *ep, - struct sctp_association *asoc, - void *event_arg, - gfp_t gfp) +int sctp_do_sm(struct net *net, enum sctp_event event_type, + union sctp_subtype subtype, enum sctp_state state, + struct sctp_endpoint *ep, struct sctp_association *asoc, + void *event_arg, gfp_t gfp) { - sctp_cmd_seq_t commands; - const sctp_sm_table_entry_t *state_fn; - sctp_disposition_t status; - int error = 0; - typedef const char *(printfn_t)(sctp_subtype_t); + typedef const char *(printfn_t)(union sctp_subtype); static printfn_t *table[] = { NULL, sctp_cname, sctp_tname, sctp_oname, sctp_pname, }; printfn_t *debug_fn __attribute__ ((unused)) = table[event_type]; + const struct sctp_sm_table_entry *state_fn; + struct sctp_cmd_seq commands; + enum sctp_disposition status; + int error = 0; /* Look up the state function, run it, and then process the * side effects. These three steps are the heart of lksctp. @@ -1178,13 +1179,14 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype, /***************************************************************** * This the master state function side effect processing function. *****************************************************************/ -static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, - sctp_state_t state, +static int sctp_side_effects(enum sctp_event event_type, + union sctp_subtype subtype, + enum sctp_state state, struct sctp_endpoint *ep, struct sctp_association **asoc, void *event_arg, - sctp_disposition_t status, - sctp_cmd_seq_t *commands, + enum sctp_disposition status, + struct sctp_cmd_seq *commands, gfp_t gfp) { int error; @@ -1263,29 +1265,27 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, ********************************************************************/ /* This is the side-effect interpreter. */ -static int sctp_cmd_interpreter(sctp_event_t event_type, - sctp_subtype_t subtype, - sctp_state_t state, +static int sctp_cmd_interpreter(enum sctp_event event_type, + union sctp_subtype subtype, + enum sctp_state state, struct sctp_endpoint *ep, struct sctp_association *asoc, void *event_arg, - sctp_disposition_t status, - sctp_cmd_seq_t *commands, + enum sctp_disposition status, + struct sctp_cmd_seq *commands, gfp_t gfp) { - struct sock *sk = ep->base.sk; - struct sctp_sock *sp = sctp_sk(sk); - int error = 0; - int force; - sctp_cmd_t *cmd; - struct sctp_chunk *new_obj; - struct sctp_chunk *chunk = NULL; + struct sctp_sock *sp = sctp_sk(ep->base.sk); + struct sctp_chunk *chunk = NULL, *new_obj; struct sctp_packet *packet; + struct sctp_sackhdr sackh; struct timer_list *timer; - unsigned long timeout; struct sctp_transport *t; - struct sctp_sackhdr sackh; + unsigned long timeout; + struct sctp_cmd *cmd; int local_cork = 0; + int error = 0; + int force; if (SCTP_EVENT_T_TIMEOUT != event_type) chunk = event_arg; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index b2a74c3823eea7e82a11d2812f0e235748274e7f..8f8ccded13e47c4b5403b5a27416b0d5707d1f33 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -59,103 +59,110 @@ #include #include -static struct sctp_packet *sctp_abort_pkt_new(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - struct sctp_chunk *chunk, - const void *payload, - size_t paylen); +static struct sctp_packet *sctp_abort_pkt_new( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + struct sctp_chunk *chunk, + const void *payload, size_t paylen); static int sctp_eat_data(const struct sctp_association *asoc, struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands); -static struct sctp_packet *sctp_ootb_pkt_new(struct net *net, - const struct sctp_association *asoc, - const struct sctp_chunk *chunk); + struct sctp_cmd_seq *commands); +static struct sctp_packet *sctp_ootb_pkt_new( + struct net *net, + const struct sctp_association *asoc, + const struct sctp_chunk *chunk); static void sctp_send_stale_cookie_err(struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, const struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands, + struct sctp_cmd_seq *commands, struct sctp_chunk *err_chunk); -static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands); -static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands); -static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net, +static enum sctp_disposition sctp_sf_do_5_2_6_stale( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands); +static enum sctp_disposition sctp_sf_shut_8_4_5( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands); +static enum sctp_disposition sctp_sf_tabort_8_4_8( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands); + struct sctp_cmd_seq *commands); static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); -static sctp_disposition_t sctp_stop_t1_and_abort(struct net *net, - sctp_cmd_seq_t *commands, - __be16 error, int sk_err, - const struct sctp_association *asoc, - struct sctp_transport *transport); +static enum sctp_disposition sctp_stop_t1_and_abort( + struct net *net, + struct sctp_cmd_seq *commands, + __be16 error, int sk_err, + const struct sctp_association *asoc, + struct sctp_transport *transport); -static sctp_disposition_t sctp_sf_abort_violation( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - void *arg, - sctp_cmd_seq_t *commands, - const __u8 *payload, - const size_t paylen); +static enum sctp_disposition sctp_sf_abort_violation( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + void *arg, + struct sctp_cmd_seq *commands, + const __u8 *payload, + const size_t paylen); -static sctp_disposition_t sctp_sf_violation_chunklen( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands); +static enum sctp_disposition sctp_sf_violation_chunklen( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands); -static sctp_disposition_t sctp_sf_violation_paramlen( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, void *ext, - sctp_cmd_seq_t *commands); +static enum sctp_disposition sctp_sf_violation_paramlen( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, void *ext, + struct sctp_cmd_seq *commands); -static sctp_disposition_t sctp_sf_violation_ctsn( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands); +static enum sctp_disposition sctp_sf_violation_ctsn( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands); -static sctp_disposition_t sctp_sf_violation_chunk( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands); +static enum sctp_disposition sctp_sf_violation_chunk( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands); -static sctp_ierror_t sctp_sf_authenticate(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - struct sctp_chunk *chunk); +static enum sctp_ierror sctp_sf_authenticate( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + struct sctp_chunk *chunk); -static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, +static enum sctp_disposition __sctp_sf_do_9_1_abort( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands); + struct sctp_cmd_seq *commands); /* Small helper function that checks if the chunk length * is of the appropriate length. The 'required_length' argument @@ -164,8 +171,8 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, * false = Invalid length * */ -static inline bool -sctp_chunk_length_valid(struct sctp_chunk *chunk, __u16 required_length) +static inline bool sctp_chunk_length_valid(struct sctp_chunk *chunk, + __u16 required_length) { __u16 chunk_length = ntohs(chunk->chunk_hdr->length); @@ -213,12 +220,11 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, __u16 required_length) * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_4_C(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_4_C(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; struct sctp_ulpevent *ev; @@ -299,19 +305,17 @@ sctp_disposition_t sctp_sf_do_4_C(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; - struct sctp_chunk *repl; + struct sctp_chunk *chunk = arg, *repl, *err_chunk; + struct sctp_unrecognized_param *unk_param; struct sctp_association *new_asoc; - struct sctp_chunk *err_chunk; struct sctp_packet *packet; - sctp_unrecognized_param_t *unk_param; int len; /* 6.10 Bundling @@ -435,7 +439,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net, * construct the parameters in INIT ACK by copying the * ERROR causes over. */ - unk_param = (sctp_unrecognized_param_t *) + unk_param = (struct sctp_unrecognized_param *) ((__u8 *)(err_chunk->chunk_hdr) + sizeof(struct sctp_chunkhdr)); /* Replace the cause code with the "Unrecognized parameter" @@ -495,15 +499,15 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; struct sctp_init_chunk *initchunk; + struct sctp_chunk *chunk = arg; struct sctp_chunk *err_chunk; struct sctp_packet *packet; @@ -518,7 +522,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, return sctp_sf_violation_chunk(net, ep, asoc, type, arg, commands); /* Make sure that the INIT-ACK chunk has a valid length */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_initack_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); /* Grab the INIT header. */ @@ -530,7 +534,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, (struct sctp_init_chunk *)chunk->chunk_hdr, chunk, &err_chunk)) { - sctp_error_t error = SCTP_ERROR_NO_RESOURCE; + enum sctp_error error = SCTP_ERROR_NO_RESOURCE; /* This chunk contains fatal error. It is to be discarded. * Send an ABORT, with causes. If there are no causes, @@ -645,20 +649,21 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; + struct sctp_ulpevent *ev, *ai_ev = NULL; struct sctp_association *new_asoc; struct sctp_init_chunk *peer_init; - struct sctp_chunk *repl; - struct sctp_ulpevent *ev, *ai_ev = NULL; - int error = 0; + struct sctp_chunk *chunk = arg; struct sctp_chunk *err_chk_p; + struct sctp_chunk *repl; struct sock *sk; + int error = 0; /* If the packet is an OOTB packet which is temporarily on the * control endpoint, respond with an ABORT. @@ -758,7 +763,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, */ if (chunk->auth_chunk) { struct sctp_chunk auth; - sctp_ierror_t ret; + enum sctp_ierror ret; /* Make sure that we and the peer are AUTH capable */ if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { @@ -872,11 +877,12 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; struct sctp_ulpevent *ev; @@ -950,11 +956,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net, } /* Generate and sendout a heartbeat packet. */ -static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_heartbeat( + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_transport *transport = (struct sctp_transport *) arg; struct sctp_chunk *reply; @@ -975,12 +982,12 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep, } /* Generate a HEARTBEAT packet on the given transport. */ -sctp_disposition_t sctp_sf_sendbeat_8_3(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_sendbeat_8_3(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_transport *transport = (struct sctp_transport *) arg; @@ -1023,11 +1030,12 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(struct net *net, } /* resend asoc strreset_chunk. */ -sctp_disposition_t sctp_sf_send_reconf(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_send_reconf(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_transport *transport = arg; @@ -1074,12 +1082,11 @@ sctp_disposition_t sctp_sf_send_reconf(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_beat_8_3(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_beat_8_3(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { struct sctp_paramhdr *param_hdr; struct sctp_chunk *chunk = arg; @@ -1090,7 +1097,8 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net, return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* Make sure that the HEARTBEAT chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t))) + if (!sctp_chunk_length_valid(chunk, + sizeof(struct sctp_heartbeat_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); @@ -1098,7 +1106,7 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net, * respond with a HEARTBEAT ACK that contains the Heartbeat * Information field copied from the received HEARTBEAT chunk. */ - chunk->subh.hb_hdr = (sctp_heartbeathdr_t *)chunk->skb->data; + chunk->subh.hb_hdr = (struct sctp_heartbeathdr *)chunk->skb->data; param_hdr = (struct sctp_paramhdr *)chunk->subh.hb_hdr; paylen = ntohs(chunk->chunk_hdr->length) - sizeof(struct sctp_chunkhdr); @@ -1148,34 +1156,32 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_backbeat_8_3(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_backbeat_8_3(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { + struct sctp_sender_hb_info *hbinfo; struct sctp_chunk *chunk = arg; - union sctp_addr from_addr; struct sctp_transport *link; - sctp_sender_hb_info_t *hbinfo; unsigned long max_interval; + union sctp_addr from_addr; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* Make sure that the HEARTBEAT-ACK chunk has a valid length. */ if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr) + - sizeof(sctp_sender_hb_info_t))) + sizeof(*hbinfo))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); - hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; + hbinfo = (struct sctp_sender_hb_info *)chunk->skb->data; /* Make sure that the length of the parameter is what we expect */ - if (ntohs(hbinfo->param_hdr.length) != - sizeof(sctp_sender_hb_info_t)) { + if (ntohs(hbinfo->param_hdr.length) != sizeof(*hbinfo)) return SCTP_DISPOSITION_DISCARD; - } from_addr = hbinfo->daddr; link = sctp_assoc_lookup_paddr(asoc, &from_addr); @@ -1227,15 +1233,15 @@ sctp_disposition_t sctp_sf_backbeat_8_3(struct net *net, */ static int sctp_sf_send_restart_abort(struct net *net, union sctp_addr *ssa, struct sctp_chunk *init, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { - int len; - struct sctp_packet *pkt; + struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family); union sctp_addr_param *addrparm; struct sctp_errhdr *errhdr; + char buffer[sizeof(*errhdr) + sizeof(*addrparm)]; struct sctp_endpoint *ep; - char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)]; - struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family); + struct sctp_packet *pkt; + int len; /* Build the error on the stack. We are way to malloc crazy * throughout the code today. @@ -1245,7 +1251,7 @@ static int sctp_sf_send_restart_abort(struct net *net, union sctp_addr *ssa, /* Copy into a parm format. */ len = af->to_addr_param(ssa, addrparm); - len += sizeof(sctp_errhdr_t); + len += sizeof(*errhdr); errhdr->cause = SCTP_ERROR_RESTART; errhdr->length = htons(len); @@ -1292,7 +1298,7 @@ static bool list_has_sctp_addr(const struct list_head *list, static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, const struct sctp_association *asoc, struct sctp_chunk *init, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { struct net *net = sock_net(new_asoc->base.sk); struct sctp_transport *new_addr; @@ -1412,20 +1418,19 @@ static char sctp_tietags_compare(struct sctp_association *new_asoc, /* Common helper routine for both duplicate and simulataneous INIT * chunk handling. */ -static sctp_disposition_t sctp_sf_do_unexpected_init( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_do_unexpected_init( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - sctp_disposition_t retval; - struct sctp_chunk *chunk = arg; - struct sctp_chunk *repl; + struct sctp_chunk *chunk = arg, *repl, *err_chunk; + struct sctp_unrecognized_param *unk_param; struct sctp_association *new_asoc; - struct sctp_chunk *err_chunk; + enum sctp_disposition retval; struct sctp_packet *packet; - sctp_unrecognized_param_t *unk_param; int len; /* 6.10 Bundling @@ -1555,7 +1560,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( * construct the parameters in INIT ACK by copying the * ERROR causes over. */ - unk_param = (sctp_unrecognized_param_t *) + unk_param = (struct sctp_unrecognized_param *) ((__u8 *)(err_chunk->chunk_hdr) + sizeof(struct sctp_chunkhdr)); /* Replace the cause code with the "Unrecognized parameter" @@ -1626,12 +1631,13 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_2_1_siminit(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_5_2_1_siminit( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* Call helper to do the real work for both simulataneous and * duplicate INIT chunk handling. @@ -1680,12 +1686,13 @@ sctp_disposition_t sctp_sf_do_5_2_1_siminit(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_2_2_dupinit(struct net *net, +enum sctp_disposition sctp_sf_do_5_2_2_dupinit( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { /* Call helper to do the real work for both simulataneous and * duplicate INIT chunk handling. @@ -1703,11 +1710,13 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(struct net *net, * An unexpected INIT ACK usually indicates the processing of an old or * duplicated INIT chunk. */ -sctp_disposition_t sctp_sf_do_5_2_3_initack(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_5_2_3_initack( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* Per the above section, we'll discard the chunk if we have an * endpoint. If this is an OOTB INIT-ACK, treat it as such. @@ -1723,18 +1732,19 @@ sctp_disposition_t sctp_sf_do_5_2_3_initack(struct net *net, * Section 5.2.4 * A) In this case, the peer may have restarted. */ -static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, +static enum sctp_disposition sctp_sf_do_dupcook_a( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands, + struct sctp_cmd_seq *commands, struct sctp_association *new_asoc) { struct sctp_init_chunk *peer_init; + enum sctp_disposition disposition; struct sctp_ulpevent *ev; struct sctp_chunk *repl; struct sctp_chunk *err; - sctp_disposition_t disposition; /* new_asoc is a brand-new association, so these are not yet * side effects--it is safe to run them here. @@ -1838,11 +1848,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, * after responding to the local endpoint's INIT */ /* This case represents an initialization collision. */ -static sctp_disposition_t sctp_sf_do_dupcook_b(struct net *net, +static enum sctp_disposition sctp_sf_do_dupcook_b( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands, + struct sctp_cmd_seq *commands, struct sctp_association *new_asoc) { struct sctp_init_chunk *peer_init; @@ -1909,11 +1920,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(struct net *net, * but a new tag of its own. */ /* This case represents an initialization collision. */ -static sctp_disposition_t sctp_sf_do_dupcook_c(struct net *net, +static enum sctp_disposition sctp_sf_do_dupcook_c( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands, + struct sctp_cmd_seq *commands, struct sctp_association *new_asoc) { /* The cookie should be silently discarded. @@ -1931,11 +1943,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_c(struct net *net, * enter the ESTABLISHED state, if it has not already done so. */ /* This case represents an initialization collision. */ -static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net, +static enum sctp_disposition sctp_sf_do_dupcook_d( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands, + struct sctp_cmd_seq *commands, struct sctp_association *new_asoc) { struct sctp_ulpevent *ev = NULL, *ai_ev = NULL; @@ -2026,19 +2039,20 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net, +enum sctp_disposition sctp_sf_do_5_2_4_dupcook( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { - sctp_disposition_t retval; - struct sctp_chunk *chunk = arg; struct sctp_association *new_asoc; + struct sctp_chunk *chunk = arg; + enum sctp_disposition retval; + struct sctp_chunk *err_chk_p; int error = 0; char action; - struct sctp_chunk *err_chk_p; /* Make sure that the chunk has a valid length from the protocol * perspective. In this case check to make sure we have at least @@ -2144,13 +2158,13 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net, * * See sctp_sf_do_9_1_abort(). */ -sctp_disposition_t sctp_sf_shutdown_pending_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_shutdown_pending_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -2167,7 +2181,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort( * as we do not know its true length. So, to be safe, discard the * packet. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk))) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* ADD-IP: Special case for ABORT chunks @@ -2187,12 +2201,13 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort( * * See sctp_sf_do_9_1_abort(). */ -sctp_disposition_t sctp_sf_shutdown_sent_abort(struct net *net, +enum sctp_disposition sctp_sf_shutdown_sent_abort( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -2209,7 +2224,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(struct net *net, * as we do not know its true length. So, to be safe, discard the * packet. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk))) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* ADD-IP: Special case for ABORT chunks @@ -2237,13 +2252,13 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(struct net *net, * * See sctp_sf_do_9_1_abort(). */ -sctp_disposition_t sctp_sf_shutdown_ack_sent_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_shutdown_ack_sent_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* The same T2 timer, so we should be able to use * common function with the SHUTDOWN-SENT state. @@ -2265,15 +2280,16 @@ sctp_disposition_t sctp_sf_shutdown_ack_sent_abort( * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_cookie_echoed_err(struct net *net, +enum sctp_disposition sctp_sf_cookie_echoed_err( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; - sctp_errhdr_t *err; + struct sctp_errhdr *err; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); @@ -2281,7 +2297,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(struct net *net, /* Make sure that the ERROR chunk has a valid length. * The parameter walking depends on this as well. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_operr_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); @@ -2329,20 +2345,20 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(struct net *net, * * The return value is the disposition of the chunk. */ -static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_do_5_2_6_stale( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; - u32 stale; - sctp_cookie_preserve_param_t bht; - sctp_errhdr_t *err; - struct sctp_chunk *reply; - struct sctp_bind_addr *bp; int attempts = asoc->init_err_counter + 1; + struct sctp_chunk *chunk = arg, *reply; + struct sctp_cookie_preserve_param bht; + struct sctp_bind_addr *bp; + struct sctp_errhdr *err; + u32 stale; if (attempts > asoc->max_init_attempts) { sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, @@ -2352,7 +2368,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net, return SCTP_DISPOSITION_DELETE_TCB; } - err = (sctp_errhdr_t *)(chunk->skb->data); + err = (struct sctp_errhdr *)(chunk->skb->data); /* When calculating the time extension, an implementation * SHOULD use the RTT information measured based on the @@ -2368,7 +2384,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net, * to give ample time to retransmit the new cookie and thus * yield a higher probability of success on the reattempt. */ - stale = ntohl(*(__be32 *)((u8 *)err + sizeof(sctp_errhdr_t))); + stale = ntohl(*(__be32 *)((u8 *)err + sizeof(*err))); stale = (stale * 2) / 1000; bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE; @@ -2452,12 +2468,13 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_9_1_abort(struct net *net, +enum sctp_disposition sctp_sf_do_9_1_abort( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -2474,7 +2491,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(struct net *net, * as we do not know its true length. So, to be safe, discard the * packet. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk))) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* ADD-IP: Special case for ABORT chunks @@ -2489,27 +2506,29 @@ sctp_disposition_t sctp_sf_do_9_1_abort(struct net *net, return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); } -static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, +static enum sctp_disposition __sctp_sf_do_9_1_abort( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { + __be16 error = SCTP_ERROR_NO_ERROR; struct sctp_chunk *chunk = arg; unsigned int len; - __be16 error = SCTP_ERROR_NO_ERROR; /* See if we have an error cause code in the chunk. */ len = ntohs(chunk->chunk_hdr->length); if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) { + struct sctp_errhdr *err; - sctp_errhdr_t *err; sctp_walk_errors(err, chunk->chunk_hdr); if ((void *)err != (void *)chunk->chunk_end) - return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + return sctp_sf_pdiscard(net, ep, asoc, type, arg, + commands); - error = ((sctp_errhdr_t *)chunk->skb->data)->cause; + error = ((struct sctp_errhdr *)chunk->skb->data)->cause; } sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); @@ -2526,16 +2545,17 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, * * See sctp_sf_do_9_1_abort() above. */ -sctp_disposition_t sctp_sf_cookie_wait_abort(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_cookie_wait_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { + __be16 error = SCTP_ERROR_NO_ERROR; struct sctp_chunk *chunk = arg; unsigned int len; - __be16 error = SCTP_ERROR_NO_ERROR; if (!sctp_vtag_verify_either(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); @@ -2550,13 +2570,13 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(struct net *net, * as we do not know its true length. So, to be safe, discard the * packet. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk))) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* See if we have an error cause code in the chunk. */ len = ntohs(chunk->chunk_hdr->length); if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) - error = ((sctp_errhdr_t *)chunk->skb->data)->cause; + error = ((struct sctp_errhdr *)chunk->skb->data)->cause; return sctp_stop_t1_and_abort(net, commands, error, ECONNREFUSED, asoc, chunk->transport); @@ -2565,12 +2585,13 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(struct net *net, /* * Process an incoming ICMP as an ABORT. (COOKIE-WAIT state) */ -sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(struct net *net, +enum sctp_disposition sctp_sf_cookie_wait_icmp_abort( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { return sctp_stop_t1_and_abort(net, commands, SCTP_ERROR_NO_ERROR, ENOPROTOOPT, asoc, @@ -2580,12 +2601,13 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(struct net *net, /* * Process an ABORT. (COOKIE-ECHOED state) */ -sctp_disposition_t sctp_sf_cookie_echoed_abort(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_cookie_echoed_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* There is a single T1 timer, so we should be able to use * common function with the COOKIE-WAIT state. @@ -2598,11 +2620,12 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(struct net *net, * * This is common code called by several sctp_sf_*_abort() functions above. */ -static sctp_disposition_t sctp_stop_t1_and_abort(struct net *net, - sctp_cmd_seq_t *commands, - __be16 error, int sk_err, - const struct sctp_association *asoc, - struct sctp_transport *transport) +static enum sctp_disposition sctp_stop_t1_and_abort( + struct net *net, + struct sctp_cmd_seq *commands, + __be16 error, int sk_err, + const struct sctp_association *asoc, + struct sctp_transport *transport) { pr_debug("%s: ABORT received (INIT)\n", __func__); @@ -2652,16 +2675,17 @@ static sctp_disposition_t sctp_stop_t1_and_abort(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_9_2_shutdown(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_shutdown( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { + enum sctp_disposition disposition; struct sctp_chunk *chunk = arg; - sctp_shutdownhdr_t *sdh; - sctp_disposition_t disposition; + struct sctp_shutdownhdr *sdh; struct sctp_ulpevent *ev; __u32 ctsn; @@ -2669,14 +2693,13 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(struct net *net, return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* Make sure that the SHUTDOWN chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, - sizeof(struct sctp_shutdown_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); /* Convert the elaborate header. */ - sdh = (sctp_shutdownhdr_t *)chunk->skb->data; - skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); + sdh = (struct sctp_shutdownhdr *)chunk->skb->data; + skb_pull(chunk->skb, sizeof(*sdh)); chunk->subh.shutdown_hdr = sdh; ctsn = ntohl(sdh->cum_tsn_ack); @@ -2742,27 +2765,27 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(struct net *net, * The Cumulative TSN Ack of the received SHUTDOWN chunk * MUST be processed. */ -sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_shut_ctsn( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; - sctp_shutdownhdr_t *sdh; + struct sctp_shutdownhdr *sdh; __u32 ctsn; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* Make sure that the SHUTDOWN chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, - sizeof(struct sctp_shutdown_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); - sdh = (sctp_shutdownhdr_t *)chunk->skb->data; + sdh = (struct sctp_shutdownhdr *)chunk->skb->data; ctsn = ntohl(sdh->cum_tsn_ack); if (TSN_lt(ctsn, asoc->ctsn_ack_point)) { @@ -2796,14 +2819,15 @@ sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(struct net *net, * that belong to this association, it should discard the INIT chunk and * retransmit the SHUTDOWN ACK chunk. */ -sctp_disposition_t sctp_sf_do_9_2_reshutack(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_reshutack( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = (struct sctp_chunk *) arg; + struct sctp_chunk *chunk = arg; struct sctp_chunk *reply; /* Make sure that the chunk has a valid length */ @@ -2860,26 +2884,26 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_ecn_cwr(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_ecn_cwr(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - sctp_cwrhdr_t *cwr; struct sctp_chunk *chunk = arg; + struct sctp_cwrhdr *cwr; u32 lowest_tsn; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_ecne_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); - cwr = (sctp_cwrhdr_t *) chunk->skb->data; - skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t)); + cwr = (struct sctp_cwrhdr *)chunk->skb->data; + skb_pull(chunk->skb, sizeof(*cwr)); lowest_tsn = ntohl(cwr->lowest_tsn); @@ -2916,25 +2940,24 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_ecne(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_ecne(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { - sctp_ecnehdr_t *ecne; struct sctp_chunk *chunk = arg; + struct sctp_ecnehdr *ecne; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_ecne_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); - ecne = (sctp_ecnehdr_t *) chunk->skb->data; - skb_pull(chunk->skb, sizeof(sctp_ecnehdr_t)); + ecne = (struct sctp_ecnehdr *)chunk->skb->data; + skb_pull(chunk->skb, sizeof(*ecne)); /* If this is a newer ECNE than the last CWR packet we sent out */ sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE, @@ -2973,15 +2996,15 @@ sctp_disposition_t sctp_sf_do_ecne(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_eat_data_6_2(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { + union sctp_arg force = SCTP_NOFORCE(); struct sctp_chunk *chunk = arg; - sctp_arg_t force = SCTP_NOFORCE(); int error; if (!sctp_vtag_verify(chunk, asoc)) { @@ -3093,12 +3116,13 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_eat_data_fast_4_4( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; int error; @@ -3184,22 +3208,22 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_eat_sack_6_2(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_eat_sack_6_2(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; - sctp_sackhdr_t *sackh; + struct sctp_sackhdr *sackh; __u32 ctsn; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* Make sure that the SACK chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_sack_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_sack_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); @@ -3258,12 +3282,13 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(struct net *net, * * The return value is the disposition of the chunk. */ -static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net, +static enum sctp_disposition sctp_sf_tabort_8_4_8( + struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { struct sctp_packet *packet = NULL; struct sctp_chunk *chunk = arg; @@ -3308,21 +3333,21 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_operr_notify(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_operr_notify(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; - sctp_errhdr_t *err; + struct sctp_errhdr *err; if (!sctp_vtag_verify(chunk, asoc)) return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); /* Make sure that the ERROR chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_operr_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); sctp_walk_errors(err, chunk->chunk_hdr); @@ -3346,12 +3371,12 @@ sctp_disposition_t sctp_sf_operr_notify(struct net *net, * * The return value is the disposition. */ -sctp_disposition_t sctp_sf_do_9_2_final(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_final(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; struct sctp_chunk *reply; @@ -3429,20 +3454,19 @@ sctp_disposition_t sctp_sf_do_9_2_final(struct net *net, * receiver of the OOTB packet shall discard the OOTB packet and take * no further action. */ -sctp_disposition_t sctp_sf_ootb(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_ootb(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; struct sk_buff *skb = chunk->skb; struct sctp_chunkhdr *ch; - sctp_errhdr_t *err; - __u8 *ch_end; - int ootb_shut_ack = 0; + struct sctp_errhdr *err; int ootb_cookie_ack = 0; + int ootb_shut_ack = 0; + __u8 *ch_end; SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES); @@ -3518,16 +3542,17 @@ sctp_disposition_t sctp_sf_ootb(struct net *net, * (endpoint, asoc, type, arg, commands) * * Outputs - * (sctp_disposition_t) + * (enum sctp_disposition) * * The return value is the disposition of the chunk. */ -static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_shut_8_4_5( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_packet *packet = NULL; struct sctp_chunk *chunk = arg; @@ -3584,12 +3609,12 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net, * chunks. --piggy ] * */ -sctp_disposition_t sctp_sf_do_8_5_1_E_sa(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_8_5_1_E_sa(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -3609,17 +3634,18 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(struct net *net, } /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. */ -sctp_disposition_t sctp_sf_do_asconf(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_asconf(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; - struct sctp_chunk *asconf_ack = NULL; - struct sctp_paramhdr *err_param = NULL; - sctp_addiphdr_t *hdr; - __u32 serial; + struct sctp_paramhdr *err_param = NULL; + struct sctp_chunk *asconf_ack = NULL; + struct sctp_chunk *chunk = arg; + struct sctp_addiphdr *hdr; + __u32 serial; if (!sctp_vtag_verify(chunk, asoc)) { sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, @@ -3634,14 +3660,15 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net, * described in [I-D.ietf-tsvwg-sctp-auth]. */ if (!net->sctp.addip_noauth && !chunk->auth) - return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, + commands); /* Make sure that the ASCONF ADDIP chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, sizeof(sctp_addip_chunk_t))) + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_addip_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); - hdr = (sctp_addiphdr_t *)chunk->skb->data; + hdr = (struct sctp_addiphdr *)chunk->skb->data; serial = ntohl(hdr->serial); /* Verify the ASCONF chunk before processing it. */ @@ -3725,18 +3752,19 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net, * When building TLV parameters for the ASCONF Chunk that will add or * delete IP addresses the D0 to D13 rules should be applied: */ -sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *asconf_ack = arg; - struct sctp_chunk *last_asconf = asoc->addip_last_asconf; - struct sctp_chunk *abort; - struct sctp_paramhdr *err_param = NULL; - sctp_addiphdr_t *addip_hdr; - __u32 sent_serial, rcvd_serial; + struct sctp_chunk *last_asconf = asoc->addip_last_asconf; + struct sctp_paramhdr *err_param = NULL; + struct sctp_chunk *asconf_ack = arg; + struct sctp_addiphdr *addip_hdr; + __u32 sent_serial, rcvd_serial; + struct sctp_chunk *abort; if (!sctp_vtag_verify(asconf_ack, asoc)) { sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, @@ -3751,14 +3779,16 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, * described in [I-D.ietf-tsvwg-sctp-auth]. */ if (!net->sctp.addip_noauth && !asconf_ack->auth) - return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, + commands); /* Make sure that the ADDIP chunk has a valid length. */ - if (!sctp_chunk_length_valid(asconf_ack, sizeof(sctp_addip_chunk_t))) + if (!sctp_chunk_length_valid(asconf_ack, + sizeof(struct sctp_addip_chunk))) return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); - addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data; + addip_hdr = (struct sctp_addiphdr *)asconf_ack->skb->data; rcvd_serial = ntohl(addip_hdr->serial); /* Verify the ASCONF-ACK chunk before processing it. */ @@ -3767,7 +3797,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, (void *)err_param, commands); if (last_asconf) { - addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; + addip_hdr = (struct sctp_addiphdr *)last_asconf->subh.addip_hdr; sent_serial = ntohl(addip_hdr->serial); } else { sent_serial = asoc->addip_serial - 1; @@ -3782,7 +3812,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, if (ADDIP_SERIAL_gte(rcvd_serial, sent_serial + 1) && !(asoc->addip_last_asconf)) { abort = sctp_make_abort(asoc, asconf_ack, - sizeof(sctp_errhdr_t)); + sizeof(struct sctp_errhdr)); if (abort) { sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, @@ -3818,7 +3848,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, } abort = sctp_make_abort(asoc, asconf_ack, - sizeof(sctp_errhdr_t)); + sizeof(struct sctp_errhdr)); if (abort) { sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, @@ -3841,11 +3871,12 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net, } /* RE-CONFIG Section 5.2 Upon reception of an RECONF Chunk. */ -sctp_disposition_t sctp_sf_do_reconf(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_reconf(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_paramhdr *err_param = NULL; struct sctp_chunk *chunk = arg; @@ -3917,15 +3948,15 @@ sctp_disposition_t sctp_sf_do_reconf(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_skip *skip; __u16 len; __u32 tsn; @@ -3987,16 +4018,16 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, return SCTP_DISPOSITION_DISCARD; } -sctp_disposition_t sctp_sf_eat_fwd_tsn_fast( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_eat_fwd_tsn_fast( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_skip *skip; __u16 len; __u32 tsn; @@ -4079,23 +4110,23 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast( * * The return value is the disposition of the chunk. */ -static sctp_ierror_t sctp_sf_authenticate(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - struct sctp_chunk *chunk) +static enum sctp_ierror sctp_sf_authenticate( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + struct sctp_chunk *chunk) { struct sctp_authhdr *auth_hdr; + __u8 *save_digest, *digest; struct sctp_hmac *hmac; unsigned int sig_len; __u16 key_id; - __u8 *save_digest; - __u8 *digest; /* Pull in the auth header, so we can do some more verification */ auth_hdr = (struct sctp_authhdr *)chunk->skb->data; chunk->subh.auth_hdr = auth_hdr; - skb_pull(chunk->skb, sizeof(struct sctp_authhdr)); + skb_pull(chunk->skb, sizeof(*auth_hdr)); /* Make sure that we support the HMAC algorithm from the auth * chunk. @@ -4114,7 +4145,8 @@ static sctp_ierror_t sctp_sf_authenticate(struct net *net, /* Make sure that the length of the signature matches what * we expect. */ - sig_len = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_auth_chunk_t); + sig_len = ntohs(chunk->chunk_hdr->length) - + sizeof(struct sctp_auth_chunk); hmac = sctp_auth_get_hmac(ntohs(auth_hdr->hmac_id)); if (sig_len != hmac->hmac_len) return SCTP_IERROR_PROTO_VIOLATION; @@ -4136,8 +4168,8 @@ static sctp_ierror_t sctp_sf_authenticate(struct net *net, memset(digest, 0, sig_len); sctp_auth_calculate_hmac(asoc, chunk->skb, - (struct sctp_auth_chunk *)chunk->chunk_hdr, - GFP_ATOMIC); + (struct sctp_auth_chunk *)chunk->chunk_hdr, + GFP_ATOMIC); /* Discard the packet if the digests do not match */ if (memcmp(save_digest, digest, sig_len)) { @@ -4153,17 +4185,16 @@ static sctp_ierror_t sctp_sf_authenticate(struct net *net, return SCTP_IERROR_NOMEM; } -sctp_disposition_t sctp_sf_eat_auth(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_eat_auth(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { - struct sctp_authhdr *auth_hdr; struct sctp_chunk *chunk = arg; + struct sctp_authhdr *auth_hdr; struct sctp_chunk *err_chunk; - sctp_ierror_t error; + enum sctp_ierror error; /* Make sure that the peer has AUTH capable */ if (!asoc->peer.auth_capable) @@ -4250,12 +4281,12 @@ sctp_disposition_t sctp_sf_eat_auth(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_unk_chunk(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_unk_chunk(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *unk_chunk = arg; struct sctp_chunk *err_chunk; @@ -4330,12 +4361,12 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_discard_chunk(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_discard_chunk(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -4370,12 +4401,11 @@ sctp_disposition_t sctp_sf_discard_chunk(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_pdiscard(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_pdiscard(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_DISCARDS); sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL()); @@ -4398,12 +4428,12 @@ sctp_disposition_t sctp_sf_pdiscard(struct net *net, * We simply tag the chunk as a violation. The state machine will log * the violation and continue. */ -sctp_disposition_t sctp_sf_violation(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_violation(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -4418,14 +4448,14 @@ sctp_disposition_t sctp_sf_violation(struct net *net, /* * Common function to handle a protocol violation. */ -static sctp_disposition_t sctp_sf_abort_violation( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - void *arg, - sctp_cmd_seq_t *commands, - const __u8 *payload, - const size_t paylen) +static enum sctp_disposition sctp_sf_abort_violation( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + void *arg, + struct sctp_cmd_seq *commands, + const __u8 *payload, + const size_t paylen) { struct sctp_packet *packet = NULL; struct sctp_chunk *chunk = arg; @@ -4454,11 +4484,10 @@ static sctp_disposition_t sctp_sf_abort_violation( /* Treat INIT-ACK as a special case during COOKIE-WAIT. */ if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK && !asoc->peer.i.init_tag) { - sctp_initack_chunk_t *initack; + struct sctp_initack_chunk *initack; - initack = (sctp_initack_chunk_t *)chunk->chunk_hdr; - if (!sctp_chunk_length_valid(chunk, - sizeof(sctp_initack_chunk_t))) + initack = (struct sctp_initack_chunk *)chunk->chunk_hdr; + if (!sctp_chunk_length_valid(chunk, sizeof(*initack))) abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T; else { unsigned int inittag; @@ -4521,7 +4550,7 @@ static sctp_disposition_t sctp_sf_abort_violation( * Handle a protocol violation when the chunk length is invalid. * "Invalid" length is identified as smaller than the minimal length a * given chunk can be. For example, a SACK chunk has invalid length - * if its length is set to be smaller than the size of sctp_sack_chunk_t. + * if its length is set to be smaller than the size of struct sctp_sack_chunk. * * We inform the other end by sending an ABORT with a Protocol Violation * error code. @@ -4536,18 +4565,18 @@ static sctp_disposition_t sctp_sf_abort_violation( * * Generate an ABORT chunk and terminate the association. */ -static sctp_disposition_t sctp_sf_violation_chunklen( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_violation_chunklen( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { static const char err_str[] = "The following chunk had invalid length:"; return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str, - sizeof(err_str)); + sizeof(err_str)); } /* @@ -4556,17 +4585,17 @@ static sctp_disposition_t sctp_sf_violation_chunklen( * or accumulated length in multi parameters exceeds the end of the chunk, * the length is considered as invalid. */ -static sctp_disposition_t sctp_sf_violation_paramlen( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, void *ext, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_violation_paramlen( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, void *ext, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = arg; struct sctp_paramhdr *param = ext; struct sctp_chunk *abort = NULL; + struct sctp_chunk *chunk = arg; if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) goto discard; @@ -4599,18 +4628,18 @@ static sctp_disposition_t sctp_sf_violation_paramlen( * We inform the other end by sending an ABORT with a Protocol Violation * error code. */ -static sctp_disposition_t sctp_sf_violation_ctsn( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_violation_ctsn( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { static const char err_str[] = "The cumulative tsn ack beyond the max tsn currently sent:"; return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str, - sizeof(err_str)); + sizeof(err_str)); } /* Handle protocol violation of an invalid chunk bundling. For example, @@ -4619,13 +4648,13 @@ static sctp_disposition_t sctp_sf_violation_ctsn( * statement from the specs. Additionally, there might be an attacker * on the path and we may not want to continue this communication. */ -static sctp_disposition_t sctp_sf_violation_chunk( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +static enum sctp_disposition sctp_sf_violation_chunk( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { static const char err_str[] = "The following chunk violates protocol:"; @@ -4633,7 +4662,7 @@ static sctp_disposition_t sctp_sf_violation_chunk( return sctp_sf_violation(net, ep, asoc, type, arg, commands); return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str, - sizeof(err_str)); + sizeof(err_str)); } /*************************************************************************** * These are the state functions for handling primitive (Section 10) events. @@ -4695,15 +4724,15 @@ static sctp_disposition_t sctp_sf_violation_chunk( * * The return value is a disposition. */ -sctp_disposition_t sctp_sf_do_prm_asoc(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_prm_asoc(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *repl; struct sctp_association *my_asoc; + struct sctp_chunk *repl; /* The comment below says that we enter COOKIE-WAIT AFTER * sending the INIT, but that doesn't actually work in our @@ -4807,12 +4836,12 @@ sctp_disposition_t sctp_sf_do_prm_asoc(struct net *net, * * The return value is the disposition. */ -sctp_disposition_t sctp_sf_do_prm_send(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_prm_send(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_datamsg *msg = arg; @@ -4846,15 +4875,15 @@ sctp_disposition_t sctp_sf_do_prm_send(struct net *net, * * The return value is the disposition. */ -sctp_disposition_t sctp_sf_do_9_2_prm_shutdown( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_prm_shutdown( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - int disposition; + enum sctp_disposition disposition; /* From 9.2 Shutdown of an Association * Upon receipt of the SHUTDOWN primitive from its upper @@ -4872,6 +4901,7 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown( disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type, arg, commands); } + return disposition; } @@ -4902,13 +4932,13 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown( * * The return value is the disposition. */ -sctp_disposition_t sctp_sf_do_9_1_prm_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_1_prm_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* From 9.1 Abort of an Association * Upon receipt of the ABORT primitive from its upper @@ -4940,12 +4970,12 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( } /* We tried an illegal operation on an association which is closed. */ -sctp_disposition_t sctp_sf_error_closed(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_error_closed(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR, SCTP_ERROR(-EINVAL)); return SCTP_DISPOSITION_CONSUME; @@ -4954,12 +4984,13 @@ sctp_disposition_t sctp_sf_error_closed(struct net *net, /* We tried an illegal operation on an association which is shutting * down. */ -sctp_disposition_t sctp_sf_error_shutdown(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_error_shutdown( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR, SCTP_ERROR(-ESHUTDOWN)); @@ -4980,13 +5011,13 @@ sctp_disposition_t sctp_sf_error_shutdown(struct net *net, * Outputs * (timers) */ -sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_cookie_wait_prm_shutdown( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); @@ -5015,12 +5046,13 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown( * Outputs * (timers) */ -sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_cookie_echoed_prm_shutdown( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* There is a single T1 timer, so we should be able to use * common function with the COOKIE-WAIT state. @@ -5042,13 +5074,13 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown( * Outputs * (timers) */ -sctp_disposition_t sctp_sf_cookie_wait_prm_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_cookie_wait_prm_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *abort = arg; @@ -5091,13 +5123,13 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( * Outputs * (timers) */ -sctp_disposition_t sctp_sf_cookie_echoed_prm_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_cookie_echoed_prm_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* There is a single T1 timer, so we should be able to use * common function with the COOKIE-WAIT state. @@ -5117,13 +5149,13 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort( * Outputs * (timers) */ -sctp_disposition_t sctp_sf_shutdown_pending_prm_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_shutdown_pending_prm_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* Stop the T5-shutdown guard timer. */ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, @@ -5144,13 +5176,13 @@ sctp_disposition_t sctp_sf_shutdown_pending_prm_abort( * Outputs * (timers) */ -sctp_disposition_t sctp_sf_shutdown_sent_prm_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_shutdown_sent_prm_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* Stop the T2-shutdown timer. */ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, @@ -5175,13 +5207,13 @@ sctp_disposition_t sctp_sf_shutdown_sent_prm_abort( * Outputs * (timers) */ -sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_shutdown_ack_sent_prm_abort( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { /* The same T2 timer, so we should be able to use * common function with the SHUTDOWN-SENT state. @@ -5211,13 +5243,13 @@ sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort( * o destination transport address - the transport address of the * association on which a heartbeat should be issued. */ -sctp_disposition_t sctp_sf_do_prm_requestheartbeat( +enum sctp_disposition sctp_sf_do_prm_requestheartbeat( struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, - const sctp_subtype_t type, + const union sctp_subtype type, void *arg, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg, commands)) @@ -5244,12 +5276,12 @@ sctp_disposition_t sctp_sf_do_prm_requestheartbeat( * When an endpoint has an ASCONF signaled change to be sent to the * remote endpoint it should do A1 to A9 */ -sctp_disposition_t sctp_sf_do_prm_asconf(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_prm_asconf(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -5261,11 +5293,12 @@ sctp_disposition_t sctp_sf_do_prm_asconf(struct net *net, } /* RE-CONFIG Section 5.1 RECONF Chunk Procedures */ -sctp_disposition_t sctp_sf_do_prm_reconf(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_prm_reconf(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = arg; @@ -5278,13 +5311,13 @@ sctp_disposition_t sctp_sf_do_prm_reconf(struct net *net, * * The return value is the disposition of the primitive. */ -sctp_disposition_t sctp_sf_ignore_primitive( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_ignore_primitive( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { pr_debug("%s: primitive type:%d is ignored\n", __func__, type.primitive); @@ -5302,13 +5335,13 @@ sctp_disposition_t sctp_sf_ignore_primitive( * subscribes to this event, if there is no data to be sent or * retransmit, the stack will immediately send up this notification. */ -sctp_disposition_t sctp_sf_do_no_pending_tsn( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_no_pending_tsn( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_ulpevent *event; @@ -5334,13 +5367,13 @@ sctp_disposition_t sctp_sf_do_no_pending_tsn( * * The return value is the disposition. */ -sctp_disposition_t sctp_sf_do_9_2_start_shutdown( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_start_shutdown( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *reply; @@ -5404,15 +5437,15 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( * * The return value is the disposition. */ -sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_9_2_shutdown_ack( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *chunk = (struct sctp_chunk *) arg; + struct sctp_chunk *chunk = arg; struct sctp_chunk *reply; /* There are 2 ways of getting here: @@ -5424,12 +5457,14 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( */ if (chunk) { if (!sctp_vtag_verify(chunk, asoc)) - return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + return sctp_sf_pdiscard(net, ep, asoc, type, arg, + commands); /* Make sure that the SHUTDOWN chunk has a valid length. */ - if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk_t))) - return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, - commands); + if (!sctp_chunk_length_valid( + chunk, sizeof(struct sctp_shutdown_chunk))) + return sctp_sf_violation_chunklen(net, ep, asoc, type, + arg, commands); } /* If it has no more outstanding DATA chunks, the SHUTDOWN receiver @@ -5476,12 +5511,12 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( * * The return value is the disposition of the event. */ -sctp_disposition_t sctp_sf_ignore_other(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_ignore_other(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { pr_debug("%s: the event other type:%d is ignored\n", __func__, type.other); @@ -5504,12 +5539,12 @@ sctp_disposition_t sctp_sf_ignore_other(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_do_6_3_3_rtx(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_6_3_3_rtx(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_transport *transport = arg; @@ -5592,12 +5627,12 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(struct net *net, * allow. However, an SCTP transmitter MUST NOT be more aggressive than * the following algorithms allow. */ -sctp_disposition_t sctp_sf_do_6_2_sack(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_do_6_2_sack(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { SCTP_INC_STATS(net, SCTP_MIB_DELAY_SACK_EXPIREDS); sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE()); @@ -5623,16 +5658,17 @@ sctp_disposition_t sctp_sf_do_6_2_sack(struct net *net, * (timers, events) * */ -sctp_disposition_t sctp_sf_t1_init_timer_expire(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_t1_init_timer_expire( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { + int attempts = asoc->init_err_counter + 1; struct sctp_chunk *repl = NULL; struct sctp_bind_addr *bp; - int attempts = asoc->init_err_counter + 1; pr_debug("%s: timer T1 expired (INIT)\n", __func__); @@ -5687,15 +5723,16 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(struct net *net, * (timers, events) * */ -sctp_disposition_t sctp_sf_t1_cookie_timer_expire(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_t1_cookie_timer_expire( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - struct sctp_chunk *repl = NULL; int attempts = asoc->init_err_counter + 1; + struct sctp_chunk *repl = NULL; pr_debug("%s: timer T1 expired (COOKIE-ECHO)\n", __func__); @@ -5737,12 +5774,13 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(struct net *net, * the T2-Shutdown timer, giving its peer ample opportunity to transmit * all of its queued DATA chunks that have not yet been sent. */ -sctp_disposition_t sctp_sf_t2_timer_expire(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_t2_timer_expire( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *reply = NULL; @@ -5807,13 +5845,13 @@ sctp_disposition_t sctp_sf_t2_timer_expire(struct net *net, * ADDIP Section 4.1 ASCONF CHunk Procedures * If the T4 RTO timer expires the endpoint should do B1 to B5 */ -sctp_disposition_t sctp_sf_t4_timer_expire( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_t4_timer_expire( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *chunk = asoc->addip_last_asconf; struct sctp_transport *transport = chunk->transport; @@ -5879,12 +5917,13 @@ sctp_disposition_t sctp_sf_t4_timer_expire( * At the expiration of this timer the sender SHOULD abort the association * by sending an ABORT chunk. */ -sctp_disposition_t sctp_sf_t5_timer_expire(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_t5_timer_expire( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { struct sctp_chunk *reply = NULL; @@ -5915,15 +5954,15 @@ sctp_disposition_t sctp_sf_t5_timer_expire(struct net *net, * The work that needs to be done is same as when SHUTDOWN is initiated by * the user. So this routine looks same as sctp_sf_do_9_2_prm_shutdown(). */ -sctp_disposition_t sctp_sf_autoclose_timer_expire( - struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_autoclose_timer_expire( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { - int disposition; + enum sctp_disposition disposition; SCTP_INC_STATS(net, SCTP_MIB_AUTOCLOSE_EXPIREDS); @@ -5943,6 +5982,7 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire( disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type, arg, commands); } + return disposition; } @@ -5958,12 +5998,11 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire( * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_not_impl(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_not_impl(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { return SCTP_DISPOSITION_NOT_IMPL; } @@ -5976,12 +6015,11 @@ sctp_disposition_t sctp_sf_not_impl(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_bug(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_bug(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, struct sctp_cmd_seq *commands) { return SCTP_DISPOSITION_BUG; } @@ -5997,12 +6035,12 @@ sctp_disposition_t sctp_sf_bug(struct net *net, * * The return value is the disposition of the chunk. */ -sctp_disposition_t sctp_sf_timer_ignore(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) +enum sctp_disposition sctp_sf_timer_ignore(struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const union sctp_subtype type, + void *arg, + struct sctp_cmd_seq *commands) { pr_debug("%s: timer %d ignored\n", __func__, type.chunk); @@ -6017,9 +6055,9 @@ sctp_disposition_t sctp_sf_timer_ignore(struct net *net, static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk) { struct sctp_sackhdr *sack; + __u16 num_dup_tsns; unsigned int len; __u16 num_blocks; - __u16 num_dup_tsns; /* Protect ourselves from reading too far into * the skb from a bogus sender. @@ -6041,12 +6079,12 @@ static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk) /* Create an ABORT packet to be sent as a response, with the specified * error causes. */ -static struct sctp_packet *sctp_abort_pkt_new(struct net *net, - const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - struct sctp_chunk *chunk, - const void *payload, - size_t paylen) +static struct sctp_packet *sctp_abort_pkt_new( + struct net *net, + const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + struct sctp_chunk *chunk, + const void *payload, size_t paylen) { struct sctp_packet *packet; struct sctp_chunk *abort; @@ -6083,14 +6121,14 @@ static struct sctp_packet *sctp_abort_pkt_new(struct net *net, } /* Allocate a packet for responding in the OOTB conditions. */ -static struct sctp_packet *sctp_ootb_pkt_new(struct net *net, - const struct sctp_association *asoc, - const struct sctp_chunk *chunk) +static struct sctp_packet *sctp_ootb_pkt_new( + struct net *net, + const struct sctp_association *asoc, + const struct sctp_chunk *chunk) { - struct sctp_packet *packet; struct sctp_transport *transport; - __u16 sport; - __u16 dport; + struct sctp_packet *packet; + __u16 sport, dport; __u32 vtag; /* Get the source and destination port from the inbound packet. */ @@ -6107,9 +6145,9 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net *net, switch (chunk->chunk_hdr->type) { case SCTP_CID_INIT_ACK: { - sctp_initack_chunk_t *initack; + struct sctp_initack_chunk *initack; - initack = (sctp_initack_chunk_t *)chunk->chunk_hdr; + initack = (struct sctp_initack_chunk *)chunk->chunk_hdr; vtag = ntohl(initack->init_hdr.init_tag); break; } @@ -6168,7 +6206,7 @@ static void sctp_send_stale_cookie_err(struct net *net, const struct sctp_endpoint *ep, const struct sctp_association *asoc, const struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands, + struct sctp_cmd_seq *commands, struct sctp_chunk *err_chunk) { struct sctp_packet *packet; @@ -6197,20 +6235,19 @@ static void sctp_send_stale_cookie_err(struct net *net, /* Process a data chunk */ static int sctp_eat_data(const struct sctp_association *asoc, struct sctp_chunk *chunk, - sctp_cmd_seq_t *commands) + struct sctp_cmd_seq *commands) { - struct sctp_datahdr *data_hdr; - struct sctp_chunk *err; - size_t datalen; - sctp_verb_t deliver; - int tmp; - __u32 tsn; struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); - u16 ssn; - u16 sid; + struct sctp_datahdr *data_hdr; + struct sctp_chunk *err; + enum sctp_verb deliver; + size_t datalen; u8 ordered = 0; + u16 ssn, sid; + __u32 tsn; + int tmp; data_hdr = (struct sctp_datahdr *)chunk->skb->data; chunk->subh.data_hdr = data_hdr; diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 3e958c1c4b95dad376b70d225050168849605103..79b6bee5b768d449ace9a2a4c48acbd0a02491f0 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c @@ -45,26 +45,27 @@ #include #include -static const sctp_sm_table_entry_t +static const struct sctp_sm_table_entry primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES]; -static const sctp_sm_table_entry_t +static const struct sctp_sm_table_entry other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES]; -static const sctp_sm_table_entry_t +static const struct sctp_sm_table_entry timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES]; -static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net, - enum sctp_cid cid, - sctp_state_t state); +static const struct sctp_sm_table_entry *sctp_chunk_event_lookup( + struct net *net, + enum sctp_cid cid, + enum sctp_state state); -static const sctp_sm_table_entry_t bug = { +static const struct sctp_sm_table_entry bug = { .fn = sctp_sf_bug, .name = "sctp_sf_bug" }; #define DO_LOOKUP(_max, _type, _table) \ ({ \ - const sctp_sm_table_entry_t *rtn; \ + const struct sctp_sm_table_entry *rtn; \ \ if ((event_subtype._type > (_max))) { \ pr_warn("table %p possible attack: event %d exceeds max %d\n", \ @@ -76,10 +77,11 @@ static const sctp_sm_table_entry_t bug = { rtn; \ }) -const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *net, - sctp_event_t event_type, - sctp_state_t state, - sctp_subtype_t event_subtype) +const struct sctp_sm_table_entry *sctp_sm_lookup_event( + struct net *net, + enum sctp_event event_type, + enum sctp_state state, + union sctp_subtype event_subtype) { switch (event_type) { case SCTP_EVENT_T_CHUNK: @@ -392,7 +394,8 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *net, * * For base protocol (RFC 2960). */ -static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_DATA, TYPE_SCTP_INIT, TYPE_SCTP_INIT_ACK, @@ -451,7 +454,8 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][ /* The primary index for this table is the chunk type. * The secondary index for this table is the state. */ -static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_ASCONF, TYPE_SCTP_ASCONF_ACK, }; /*state_fn_t addip_chunk_event_table[][] */ @@ -478,7 +482,8 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_ /* The primary index for this table is the chunk type. * The secondary index for this table is the state. */ -static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_FWD_TSN, }; /*state_fn_t prsctp_chunk_event_table[][] */ @@ -504,7 +509,8 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN /* The primary index for this table is the chunk type. * The secondary index for this table is the state. */ -static const sctp_sm_table_entry_t reconf_chunk_event_table[SCTP_NUM_RECONF_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +reconf_chunk_event_table[SCTP_NUM_RECONF_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_RECONF, }; /*state_fn_t reconf_chunk_event_table[][] */ @@ -530,11 +536,12 @@ static const sctp_sm_table_entry_t reconf_chunk_event_table[SCTP_NUM_RECONF_CHUN /* The primary index for this table is the chunk type. * The secondary index for this table is the state. */ -static const sctp_sm_table_entry_t auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_AUTH, }; /*state_fn_t auth_chunk_event_table[][] */ -static const sctp_sm_table_entry_t +static const struct sctp_sm_table_entry chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { /* SCTP_STATE_CLOSED */ TYPE_SCTP_FUNC(sctp_sf_ootb), @@ -691,7 +698,8 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { /* The primary index for this table is the primitive type. * The secondary index for this table is the state. */ -static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_PRIMITIVE_ASSOCIATE, TYPE_SCTP_PRIMITIVE_SHUTDOWN, TYPE_SCTP_PRIMITIVE_ABORT, @@ -739,7 +747,8 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE TYPE_SCTP_FUNC(sctp_sf_ignore_other), \ } -static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_OTHER_NO_PENDING_TSN, TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH, }; @@ -953,7 +962,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ } -static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { +static const struct sctp_sm_table_entry +timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_EVENT_TIMEOUT_NONE, TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE, TYPE_SCTP_EVENT_TIMEOUT_T1_INIT, @@ -967,9 +977,10 @@ static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][S TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE, }; -static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net, - enum sctp_cid cid, - sctp_state_t state) +static const struct sctp_sm_table_entry *sctp_chunk_event_lookup( + struct net *net, + enum sctp_cid cid, + enum sctp_state state) { if (state > SCTP_STATE_MAX) return &bug; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 1db478e345203f75733044d843a763cc3a3966e1..d4730ada7f3233367be7a0e3bb10e286a25602c8 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -100,8 +100,9 @@ static int sctp_send_asconf(struct sctp_association *asoc, struct sctp_chunk *chunk); static int sctp_do_bind(struct sock *, union sctp_addr *, int); static int sctp_autobind(struct sock *sk); -static void sctp_sock_migrate(struct sock *, struct sock *, - struct sctp_association *, sctp_socket_type_t); +static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, + struct sctp_association *assoc, + enum sctp_socket_type type); static unsigned long sctp_memory_pressure; static atomic_long_t sctp_memory_allocated; @@ -1055,7 +1056,7 @@ static int __sctp_connect(struct sock *sk, struct sctp_association *asoc2; struct sctp_transport *transport; union sctp_addr to; - sctp_scope_t scope; + enum sctp_scope scope; long timeo; int err = 0; int addrcnt = 0; @@ -1593,7 +1594,8 @@ static int sctp_error(struct sock *sk, int flags, int err) */ /* BUG: We do not implement the equivalent of sk_stream_wait_memory(). */ -static int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *); +static int sctp_msghdr_parse(const struct msghdr *msg, + struct sctp_cmsgs *cmsgs); static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) { @@ -1609,8 +1611,8 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) struct sctp_sndrcvinfo *sinfo; struct sctp_initmsg *sinit; sctp_assoc_t associd = 0; - sctp_cmsgs_t cmsgs = { NULL }; - sctp_scope_t scope; + struct sctp_cmsgs cmsgs = { NULL }; + enum sctp_scope scope; bool fill_sinfo_ttl = false, wait_connect = false; struct sctp_datamsg *datamsg; int msg_flags = msg->msg_flags; @@ -4538,8 +4540,7 @@ int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc, info->sctpi_ictrlchunks = asoc->stats.ictrlchunks; prim = asoc->peer.primary_path; - memcpy(&info->sctpi_p_address, &prim->ipaddr, - sizeof(struct sockaddr_storage)); + memcpy(&info->sctpi_p_address, &prim->ipaddr, sizeof(prim->ipaddr)); info->sctpi_p_state = prim->state; info->sctpi_p_cwnd = prim->cwnd; info->sctpi_p_srtt = prim->srtt; @@ -4657,29 +4658,39 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *), EXPORT_SYMBOL_GPL(sctp_transport_lookup_process); int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *), - struct net *net, int pos, void *p) { + int (*cb_done)(struct sctp_transport *, void *), + struct net *net, int *pos, void *p) { struct rhashtable_iter hti; - void *obj; - int err; - - err = sctp_transport_walk_start(&hti); - if (err) - return err; + struct sctp_transport *tsp; + int ret; - obj = sctp_transport_get_idx(net, &hti, pos + 1); - for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) { - struct sctp_transport *transport = obj; +again: + ret = sctp_transport_walk_start(&hti); + if (ret) + return ret; - if (!sctp_transport_hold(transport)) + tsp = sctp_transport_get_idx(net, &hti, *pos + 1); + for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) { + if (!sctp_transport_hold(tsp)) continue; - err = cb(transport, p); - sctp_transport_put(transport); - if (err) + ret = cb(tsp, p); + if (ret) break; + (*pos)++; + sctp_transport_put(tsp); } sctp_transport_walk_stop(&hti); - return err; + if (ret) { + if (cb_done && !cb_done(tsp, p)) { + (*pos)++; + sctp_transport_put(tsp); + goto again; + } + sctp_transport_put(tsp); + } + + return ret; } EXPORT_SYMBOL_GPL(sctp_for_each_transport); @@ -7445,10 +7456,10 @@ static int sctp_autobind(struct sock *sk) * msg_control * points here */ -static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) +static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs) { - struct cmsghdr *cmsg; struct msghdr *my_msg = (struct msghdr *)msg; + struct cmsghdr *cmsg; for_each_cmsghdr(cmsg, my_msg) { if (!CMSG_OK(my_msg, cmsg)) @@ -8085,7 +8096,7 @@ static inline void sctp_copy_descendant(struct sock *sk_to, */ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, struct sctp_association *assoc, - sctp_socket_type_t type) + enum sctp_socket_type type) { struct sctp_sock *oldsp = sctp_sk(oldsk); struct sctp_sock *newsp = sctp_sk(newsk); diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 0e732f68c2bfc3b791dade5a85c36628904ee490..ef7ca44d6e6afdd818c1f920b97aebbda4962edb 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -46,7 +46,7 @@ static int timer_max = 86400000; /* ms in one day */ static int int_max = INT_MAX; static int sack_timer_min = 1; static int sack_timer_max = 500; -static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ +static int addr_scope_max = SCTP_SCOPE_POLICY_MAX; static int rwnd_scale_max = 16; static int rto_alpha_min = 0; static int rto_beta_min = 0; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 80a97c8501a77be978a01ae9ec769f4c365bc14f..2d9bd3776bc8309d71048f71172149ae97a7a557 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -490,7 +490,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, * detected. */ void sctp_transport_lower_cwnd(struct sctp_transport *transport, - sctp_lower_cwnd_t reason) + enum sctp_lower_cwnd reason) { struct sctp_association *asoc = transport->asoc; diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 5f86c5062a987be610bdb3fb64878be2d6c42944..67abc0194f301239fcbf0bd6a1136aeec585e660 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -371,19 +371,19 @@ sctp_ulpevent_make_remote_error(const struct sctp_association *asoc, struct sctp_chunk *chunk, __u16 flags, gfp_t gfp) { - struct sctp_ulpevent *event; struct sctp_remote_error *sre; + struct sctp_ulpevent *event; + struct sctp_errhdr *ch; struct sk_buff *skb; - sctp_errhdr_t *ch; __be16 cause; int elen; - ch = (sctp_errhdr_t *)(chunk->skb->data); + ch = (struct sctp_errhdr *)(chunk->skb->data); cause = ch->cause; - elen = SCTP_PAD4(ntohs(ch->length)) - sizeof(sctp_errhdr_t); + elen = SCTP_PAD4(ntohs(ch->length)) - sizeof(*ch); /* Pull off the ERROR header. */ - skb_pull(chunk->skb, sizeof(sctp_errhdr_t)); + skb_pull(chunk->skb, sizeof(*ch)); /* Copy the skb to a new skb with room for us to prepend * notification with. diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 0225d62a869f8deff10565c4625df0a10464ce87..a71be33f3afeb0aaaef174ee082c4c547aab1e2d 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -265,7 +265,8 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) sctp_ulpq_clear_pd(ulpq); if (queue == &sk->sk_receive_queue && !sp->data_ready_signalled) { - sp->data_ready_signalled = 1; + if (!sock_owned_by_user(sk)) + sp->data_ready_signalled = 1; sk->sk_data_ready(sk); } return 1; diff --git a/net/smc/Kconfig b/net/smc/Kconfig index 33954852f3f89b3bd05595a159e5c2ed56d074ad..c717ef0896aa2accaee05e3cf4c10d066c61eeb3 100644 --- a/net/smc/Kconfig +++ b/net/smc/Kconfig @@ -8,10 +8,6 @@ config SMC The Linux implementation of the SMC-R solution is designed as a separate socket family SMC. - Warning: SMC will expose all memory for remote reads and writes - once a connection is established. Don't enable this option except - for tightly controlled lab environment. - Select this option if you want to run SMC socket applications config SMC_DIAG diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 6793d7348cc811f41395c5ca3a9d1f1390813646..745f145d4c4d43316f3cb30083066456497fec3a 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -282,6 +282,7 @@ int smc_netinfo_by_tcpsk(struct socket *clcsock, __be32 *subnet, u8 *prefix_len) { struct dst_entry *dst = sk_dst_get(clcsock->sk); + struct in_device *in_dev; struct sockaddr_in addr; int rc = -ENOENT; int len; @@ -298,14 +299,17 @@ int smc_netinfo_by_tcpsk(struct socket *clcsock, /* get address to which the internal TCP socket is bound */ kernel_getsockname(clcsock, (struct sockaddr *)&addr, &len); /* analyze IPv4 specific data of net_device belonging to TCP socket */ - for_ifa(dst->dev->ip_ptr) { - if (ifa->ifa_address != addr.sin_addr.s_addr) + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dst->dev); + for_ifa(in_dev) { + if (!inet_ifa_match(addr.sin_addr.s_addr, ifa)) continue; *prefix_len = inet_mask_len(ifa->ifa_mask); *subnet = ifa->ifa_address & ifa->ifa_mask; rc = 0; break; - } endfor_ifa(dst->dev->ip_ptr); + } endfor_ifa(in_dev); + rcu_read_unlock(); out_rel: dst_release(dst); @@ -338,6 +342,12 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc, union ib_gid *gid) return SMC_CLC_DECL_INTERR; smc_wr_remember_qp_attr(link); + + rc = smc_wr_reg_send(link, + smc->conn.rmb_desc->mr_rx[SMC_SINGLE_LINK]); + if (rc) + return SMC_CLC_DECL_INTERR; + /* send CONFIRM LINK response over RoCE fabric */ rc = smc_llc_send_confirm_link(link, link->smcibdev->mac[link->ibport - 1], @@ -430,12 +440,8 @@ static int smc_connect_rdma(struct smc_sock *smc) smc_conn_save_peer_info(smc, &aclc); - rc = smc_sndbuf_create(smc); - if (rc) { - reason_code = SMC_CLC_DECL_MEM; - goto decline_rdma_unlock; - } - rc = smc_rmb_create(smc); + /* create send buffer and rmb */ + rc = smc_buf_create(smc); if (rc) { reason_code = SMC_CLC_DECL_MEM; goto decline_rdma_unlock; @@ -459,7 +465,20 @@ static int smc_connect_rdma(struct smc_sock *smc) reason_code = SMC_CLC_DECL_INTERR; goto decline_rdma_unlock; } + } else { + struct smc_buf_desc *buf_desc = smc->conn.rmb_desc; + + if (!buf_desc->reused) { + /* register memory region for new rmb */ + rc = smc_wr_reg_send(link, + buf_desc->mr_rx[SMC_SINGLE_LINK]); + if (rc) { + reason_code = SMC_CLC_DECL_INTERR; + goto decline_rdma_unlock; + } + } } + smc_rmb_sync_sg_for_device(&smc->conn); rc = smc_clc_send_confirm(smc); if (rc) @@ -494,7 +513,7 @@ static int smc_connect_rdma(struct smc_sock *smc) /* RDMA setup failed, switch back to TCP */ smc->use_fallback = true; if (reason_code && (reason_code != SMC_CLC_DECL_REPLY)) { - rc = smc_clc_send_decline(smc, reason_code, 0); + rc = smc_clc_send_decline(smc, reason_code); if (rc < sizeof(struct smc_clc_msg_decline)) goto out_err; } @@ -692,6 +711,12 @@ static int smc_serv_conf_first_link(struct smc_sock *smc) int rc; link = &lgr->lnk[SMC_SINGLE_LINK]; + + rc = smc_wr_reg_send(link, + smc->conn.rmb_desc->mr_rx[SMC_SINGLE_LINK]); + if (rc) + return SMC_CLC_DECL_INTERR; + /* send CONFIRM LINK request to client over the RoCE fabric */ rc = smc_llc_send_confirm_link(link, link->smcibdev->mac[link->ibport - 1], @@ -779,27 +804,16 @@ static void smc_listen_work(struct work_struct *work) mutex_lock(&smc_create_lgr_pending); local_contact = smc_conn_create(new_smc, peeraddr.sin_addr.s_addr, smcibdev, ibport, &pclc.lcl, 0); - if (local_contact == SMC_REUSE_CONTACT) - /* lock no longer needed, free it due to following - * smc_clc_wait_msg() call - */ - mutex_unlock(&smc_create_lgr_pending); if (local_contact < 0) { rc = local_contact; if (rc == -ENOMEM) reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/ - else if (rc == -ENOLINK) - reason_code = SMC_CLC_DECL_SYNCERR; /* synchr. error */ goto decline_rdma; } link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK]; - rc = smc_sndbuf_create(new_smc); - if (rc) { - reason_code = SMC_CLC_DECL_MEM; - goto decline_rdma; - } - rc = smc_rmb_create(new_smc); + /* create send buffer and rmb */ + rc = smc_buf_create(new_smc); if (rc) { reason_code = SMC_CLC_DECL_MEM; goto decline_rdma; @@ -808,6 +822,21 @@ static void smc_listen_work(struct work_struct *work) smc_close_init(new_smc); smc_rx_init(new_smc); + if (local_contact != SMC_FIRST_CONTACT) { + struct smc_buf_desc *buf_desc = new_smc->conn.rmb_desc; + + if (!buf_desc->reused) { + /* register memory region for new rmb */ + rc = smc_wr_reg_send(link, + buf_desc->mr_rx[SMC_SINGLE_LINK]); + if (rc) { + reason_code = SMC_CLC_DECL_INTERR; + goto decline_rdma; + } + } + } + smc_rmb_sync_sg_for_device(&new_smc->conn); + rc = smc_clc_send_accept(new_smc, local_contact); if (rc) goto out_err; @@ -853,8 +882,7 @@ static void smc_listen_work(struct work_struct *work) if (newsmcsk->sk_state == SMC_INIT) newsmcsk->sk_state = SMC_ACTIVE; enqueue: - if (local_contact == SMC_FIRST_CONTACT) - mutex_unlock(&smc_create_lgr_pending); + mutex_unlock(&smc_create_lgr_pending); lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING); if (lsmc->sk.sk_state == SMC_LISTEN) { smc_accept_enqueue(&lsmc->sk, newsmcsk); @@ -873,7 +901,7 @@ static void smc_listen_work(struct work_struct *work) smc_conn_free(&new_smc->conn); new_smc->use_fallback = true; if (reason_code && (reason_code != SMC_CLC_DECL_REPLY)) { - rc = smc_clc_send_decline(new_smc, reason_code, 0); + rc = smc_clc_send_decline(new_smc, reason_code); if (rc < sizeof(struct smc_clc_msg_decline)) goto out_err; } diff --git a/net/smc/smc.h b/net/smc/smc.h index 6e44313e4467d01fbdc77f07ee7d14c50ab92ce2..0ccd6fa387ad7074cf0010cb3966f38d6c3b20cb 100644 --- a/net/smc/smc.h +++ b/net/smc/smc.h @@ -149,7 +149,7 @@ struct smc_connection { atomic_t sndbuf_space; /* remaining space in sndbuf */ u16 tx_cdc_seq; /* sequence # for CDC send */ spinlock_t send_lock; /* protect wr_sends */ - struct work_struct tx_work; /* retry of smc_cdc_msg_send */ + struct delayed_work tx_work; /* retry of smc_cdc_msg_send */ struct smc_host_cdc_msg local_rx_ctrl; /* filled during event_handl. * .prod cf. TCP rcv_nxt diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 03ec058d18df642ef7e219000a62e51bc6c0e6fe..b7dd2743fb5c0cfa11228b6c36b3a7fe3c53498e 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c @@ -95,9 +95,10 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, } if (clcm->type == SMC_CLC_DECLINE) { reason_code = SMC_CLC_DECL_REPLY; - if (ntohl(((struct smc_clc_msg_decline *)buf)->peer_diagnosis) - == SMC_CLC_DECL_SYNCERR) + if (((struct smc_clc_msg_decline *)buf)->hdr.flag) { smc->conn.lgr->sync_err = true; + smc_lgr_terminate(smc->conn.lgr); + } } out: @@ -105,8 +106,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, } /* send CLC DECLINE message across internal TCP socket */ -int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, - u8 out_of_sync) +int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info) { struct smc_clc_msg_decline dclc; struct msghdr msg; @@ -118,7 +118,7 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, dclc.hdr.type = SMC_CLC_DECLINE; dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline)); dclc.hdr.version = SMC_CLC_V1; - dclc.hdr.flag = out_of_sync ? 1 : 0; + dclc.hdr.flag = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ? 1 : 0; memcpy(dclc.id_for_peer, local_systemid, sizeof(local_systemid)); dclc.peer_diagnosis = htonl(peer_diag_info); memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); @@ -204,13 +204,13 @@ int smc_clc_send_confirm(struct smc_sock *smc) memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], ETH_ALEN); hton24(cclc.qpn, link->roce_qp->qp_num); cclc.rmb_rkey = - htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]); + htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey); cclc.conn_idx = 1; /* for now: 1 RMB = 1 RMBE */ cclc.rmbe_alert_token = htonl(conn->alert_token_local); cclc.qp_mtu = min(link->path_mtu, link->peer_mtu); cclc.rmbe_size = conn->rmbe_size_short; - cclc.rmb_dma_addr = - cpu_to_be64((u64)conn->rmb_desc->dma_addr[SMC_SINGLE_LINK]); + cclc.rmb_dma_addr = cpu_to_be64( + (u64)sg_dma_address(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl)); hton24(cclc.psn, link->psn_initial); memcpy(cclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); @@ -256,13 +256,13 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact) memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN); hton24(aclc.qpn, link->roce_qp->qp_num); aclc.rmb_rkey = - htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]); + htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey); aclc.conn_idx = 1; /* as long as 1 RMB = 1 RMBE */ aclc.rmbe_alert_token = htonl(conn->alert_token_local); aclc.qp_mtu = link->path_mtu; aclc.rmbe_size = conn->rmbe_size_short, - aclc.rmb_dma_addr = - cpu_to_be64((u64)conn->rmb_desc->dma_addr[SMC_SINGLE_LINK]); + aclc.rmb_dma_addr = cpu_to_be64( + (u64)sg_dma_address(conn->rmb_desc->sgt[SMC_SINGLE_LINK].sgl)); hton24(aclc.psn, link->psn_initial); memcpy(aclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h index 13db8ce177c91dd913fac15fdebb5e05875e0ec9..1c55414041d49b560dfdd89fe9c1ed122a073cea 100644 --- a/net/smc/smc_clc.h +++ b/net/smc/smc_clc.h @@ -106,8 +106,7 @@ struct smc_ib_device; int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, u8 expected_type); -int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, - u8 out_of_sync); +int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info); int smc_clc_send_proposal(struct smc_sock *smc, struct smc_ib_device *smcibdev, u8 ibport); int smc_clc_send_confirm(struct smc_sock *smc); diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index 3c2e166b5d222f4c932179ae442cbd88969efc92..f0d16fb825f7a545104232baacca32520cb14e08 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c @@ -174,15 +174,15 @@ int smc_close_active(struct smc_sock *smc) { struct smc_cdc_conn_state_flags *txflags = &smc->conn.local_tx_ctrl.conn_state_flags; - long timeout = SMC_MAX_STREAM_WAIT_TIMEOUT; struct smc_connection *conn = &smc->conn; struct sock *sk = &smc->sk; int old_state; + long timeout; int rc = 0; - if (sock_flag(sk, SOCK_LINGER) && - !(current->flags & PF_EXITING)) - timeout = sk->sk_lingertime; + timeout = current->flags & PF_EXITING ? + 0 : sock_flag(sk, SOCK_LINGER) ? + sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT; again: old_state = sk->sk_state; @@ -208,7 +208,7 @@ int smc_close_active(struct smc_sock *smc) case SMC_ACTIVE: smc_close_stream_wait(smc, timeout); release_sock(sk); - cancel_work_sync(&conn->tx_work); + cancel_delayed_work_sync(&conn->tx_work); lock_sock(sk); if (sk->sk_state == SMC_ACTIVE) { /* send close request */ @@ -234,7 +234,7 @@ int smc_close_active(struct smc_sock *smc) if (!smc_cdc_rxed_any_close(conn)) smc_close_stream_wait(smc, timeout); release_sock(sk); - cancel_work_sync(&conn->tx_work); + cancel_delayed_work_sync(&conn->tx_work); lock_sock(sk); if (sk->sk_err != ECONNABORTED) { /* confirm close from peer */ @@ -263,7 +263,9 @@ int smc_close_active(struct smc_sock *smc) /* peer sending PeerConnectionClosed will cause transition */ break; case SMC_PROCESSABORT: - cancel_work_sync(&conn->tx_work); + release_sock(sk); + cancel_delayed_work_sync(&conn->tx_work); + lock_sock(sk); smc_close_abort(conn); sk->sk_state = SMC_CLOSED; smc_close_wait_tx_pends(smc); @@ -411,13 +413,14 @@ void smc_close_sock_put_work(struct work_struct *work) int smc_close_shutdown_write(struct smc_sock *smc) { struct smc_connection *conn = &smc->conn; - long timeout = SMC_MAX_STREAM_WAIT_TIMEOUT; struct sock *sk = &smc->sk; int old_state; + long timeout; int rc = 0; - if (sock_flag(sk, SOCK_LINGER)) - timeout = sk->sk_lingertime; + timeout = current->flags & PF_EXITING ? + 0 : sock_flag(sk, SOCK_LINGER) ? + sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT; again: old_state = sk->sk_state; @@ -425,7 +428,7 @@ int smc_close_shutdown_write(struct smc_sock *smc) case SMC_ACTIVE: smc_close_stream_wait(smc, timeout); release_sock(sk); - cancel_work_sync(&conn->tx_work); + cancel_delayed_work_sync(&conn->tx_work); lock_sock(sk); /* send close wr request */ rc = smc_close_wr(conn); @@ -439,7 +442,7 @@ int smc_close_shutdown_write(struct smc_sock *smc) if (!smc_cdc_rxed_any_close(conn)) smc_close_stream_wait(smc, timeout); release_sock(sk); - cancel_work_sync(&conn->tx_work); + cancel_delayed_work_sync(&conn->tx_work); lock_sock(sk); /* confirm close from peer */ rc = smc_close_wr(conn); diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 3ac09a629ea1a4c38c6bc21d996a69611c1633b7..20b66e79c5d6305dddf120f09249654732842c00 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -25,8 +25,9 @@ #include "smc_cdc.h" #include "smc_close.h" -#define SMC_LGR_NUM_INCR 256 -#define SMC_LGR_FREE_DELAY (600 * HZ) +#define SMC_LGR_NUM_INCR 256 +#define SMC_LGR_FREE_DELAY_SERV (600 * HZ) +#define SMC_LGR_FREE_DELAY_CLNT (SMC_LGR_FREE_DELAY_SERV + 10) static u32 smc_lgr_num; /* unique link group number */ @@ -107,8 +108,15 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn) __smc_lgr_unregister_conn(conn); } write_unlock_bh(&lgr->conns_lock); - if (reduced && !lgr->conns_num) - schedule_delayed_work(&lgr->free_work, SMC_LGR_FREE_DELAY); + if (!reduced || lgr->conns_num) + return; + /* client link group creation always follows the server link group + * creation. For client use a somewhat higher removal delay time, + * otherwise there is a risk of out-of-sync link groups. + */ + mod_delayed_work(system_wq, &lgr->free_work, + lgr->role == SMC_CLNT ? SMC_LGR_FREE_DELAY_CLNT : + SMC_LGR_FREE_DELAY_SERV); } static void smc_lgr_free_work(struct work_struct *work) @@ -175,7 +183,6 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr, rc = smc_wr_alloc_link_mem(lnk); if (rc) goto free_lgr; - init_waitqueue_head(&lnk->wr_tx_wait); rc = smc_ib_create_protection_domain(lnk); if (rc) goto free_link_mem; @@ -207,17 +214,14 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr, return rc; } -static void smc_sndbuf_unuse(struct smc_connection *conn) +static void smc_buf_unuse(struct smc_connection *conn) { if (conn->sndbuf_desc) { conn->sndbuf_desc->used = 0; conn->sndbuf_size = 0; } -} - -static void smc_rmb_unuse(struct smc_connection *conn) -{ if (conn->rmb_desc) { + conn->rmb_desc->reused = true; conn->rmb_desc->used = 0; conn->rmbe_size = 0; } @@ -232,8 +236,7 @@ void smc_conn_free(struct smc_connection *conn) return; smc_cdc_tx_dismiss_slots(conn); smc_lgr_unregister_conn(conn); - smc_rmb_unuse(conn); - smc_sndbuf_unuse(conn); + smc_buf_unuse(conn); } static void smc_link_clear(struct smc_link *lnk) @@ -246,48 +249,57 @@ static void smc_link_clear(struct smc_link *lnk) smc_wr_free_link_mem(lnk); } -static void smc_lgr_free_sndbufs(struct smc_link_group *lgr) +static void smc_buf_free(struct smc_buf_desc *buf_desc, struct smc_link *lnk, + bool is_rmb) { - struct smc_buf_desc *sndbuf_desc, *bf_desc; - int i; - - for (i = 0; i < SMC_RMBE_SIZES; i++) { - list_for_each_entry_safe(sndbuf_desc, bf_desc, &lgr->sndbufs[i], - list) { - list_del(&sndbuf_desc->list); - smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev, - smc_uncompress_bufsize(i), - sndbuf_desc, DMA_TO_DEVICE); - kfree(sndbuf_desc->cpu_addr); - kfree(sndbuf_desc); - } + if (is_rmb) { + if (buf_desc->mr_rx[SMC_SINGLE_LINK]) + smc_ib_put_memory_region( + buf_desc->mr_rx[SMC_SINGLE_LINK]); + smc_ib_buf_unmap_sg(lnk->smcibdev, buf_desc, + DMA_FROM_DEVICE); + } else { + smc_ib_buf_unmap_sg(lnk->smcibdev, buf_desc, + DMA_TO_DEVICE); } + sg_free_table(&buf_desc->sgt[SMC_SINGLE_LINK]); + if (buf_desc->cpu_addr) + free_pages((unsigned long)buf_desc->cpu_addr, buf_desc->order); + kfree(buf_desc); } -static void smc_lgr_free_rmbs(struct smc_link_group *lgr) +static void __smc_lgr_free_bufs(struct smc_link_group *lgr, bool is_rmb) { - struct smc_buf_desc *rmb_desc, *bf_desc; struct smc_link *lnk = &lgr->lnk[SMC_SINGLE_LINK]; + struct smc_buf_desc *buf_desc, *bf_desc; + struct list_head *buf_list; int i; for (i = 0; i < SMC_RMBE_SIZES; i++) { - list_for_each_entry_safe(rmb_desc, bf_desc, &lgr->rmbs[i], + if (is_rmb) + buf_list = &lgr->rmbs[i]; + else + buf_list = &lgr->sndbufs[i]; + list_for_each_entry_safe(buf_desc, bf_desc, buf_list, list) { - list_del(&rmb_desc->list); - smc_ib_buf_unmap(lnk->smcibdev, - smc_uncompress_bufsize(i), - rmb_desc, DMA_FROM_DEVICE); - kfree(rmb_desc->cpu_addr); - kfree(rmb_desc); + list_del(&buf_desc->list); + smc_buf_free(buf_desc, lnk, is_rmb); } } } +static void smc_lgr_free_bufs(struct smc_link_group *lgr) +{ + /* free send buffers */ + __smc_lgr_free_bufs(lgr, false); + /* free rmbs */ + __smc_lgr_free_bufs(lgr, true); +} + /* remove a link group */ void smc_lgr_free(struct smc_link_group *lgr) { - smc_lgr_free_rmbs(lgr); - smc_lgr_free_sndbufs(lgr); + smc_lgr_free_bufs(lgr); smc_link_clear(&lgr->lnk[SMC_SINGLE_LINK]); kfree(lgr); } @@ -452,45 +464,25 @@ int smc_conn_create(struct smc_sock *smc, __be32 peer_in_addr, return rc ? rc : local_contact; } -/* try to reuse a sndbuf description slot of the sndbufs list for a certain - * buf_size; if not available, return NULL +/* try to reuse a sndbuf or rmb description slot for a certain + * buffer size; if not available, return NULL */ static inline -struct smc_buf_desc *smc_sndbuf_get_slot(struct smc_link_group *lgr, - int compressed_bufsize) +struct smc_buf_desc *smc_buf_get_slot(struct smc_link_group *lgr, + int compressed_bufsize, + rwlock_t *lock, + struct list_head *buf_list) { - struct smc_buf_desc *sndbuf_slot; - - read_lock_bh(&lgr->sndbufs_lock); - list_for_each_entry(sndbuf_slot, &lgr->sndbufs[compressed_bufsize], - list) { - if (cmpxchg(&sndbuf_slot->used, 0, 1) == 0) { - read_unlock_bh(&lgr->sndbufs_lock); - return sndbuf_slot; - } - } - read_unlock_bh(&lgr->sndbufs_lock); - return NULL; -} + struct smc_buf_desc *buf_slot; -/* try to reuse an rmb description slot of the rmbs list for a certain - * rmbe_size; if not available, return NULL - */ -static inline -struct smc_buf_desc *smc_rmb_get_slot(struct smc_link_group *lgr, - int compressed_bufsize) -{ - struct smc_buf_desc *rmb_slot; - - read_lock_bh(&lgr->rmbs_lock); - list_for_each_entry(rmb_slot, &lgr->rmbs[compressed_bufsize], - list) { - if (cmpxchg(&rmb_slot->used, 0, 1) == 0) { - read_unlock_bh(&lgr->rmbs_lock); - return rmb_slot; + read_lock_bh(lock); + list_for_each_entry(buf_slot, buf_list, list) { + if (cmpxchg(&buf_slot->used, 0, 1) == 0) { + read_unlock_bh(lock); + return buf_slot; } } - read_unlock_bh(&lgr->rmbs_lock); + read_unlock_bh(lock); return NULL; } @@ -503,136 +495,186 @@ static inline int smc_rmb_wnd_update_limit(int rmbe_size) return min_t(int, rmbe_size / 10, SOCK_MIN_SNDBUF / 2); } -/* create the tx buffer for an SMC socket */ -int smc_sndbuf_create(struct smc_sock *smc) +static struct smc_buf_desc *smc_new_buf_create(struct smc_link_group *lgr, + bool is_rmb, int bufsize) { - struct smc_connection *conn = &smc->conn; - struct smc_link_group *lgr = conn->lgr; - int tmp_bufsize, tmp_bufsize_short; - struct smc_buf_desc *sndbuf_desc; + struct smc_buf_desc *buf_desc; + struct smc_link *lnk; int rc; - /* use socket send buffer size (w/o overhead) as start value */ - for (tmp_bufsize_short = smc_compress_bufsize(smc->sk.sk_sndbuf / 2); - tmp_bufsize_short >= 0; tmp_bufsize_short--) { - tmp_bufsize = smc_uncompress_bufsize(tmp_bufsize_short); - /* check for reusable sndbuf_slot in the link group */ - sndbuf_desc = smc_sndbuf_get_slot(lgr, tmp_bufsize_short); - if (sndbuf_desc) { - memset(sndbuf_desc->cpu_addr, 0, tmp_bufsize); - break; /* found reusable slot */ - } - /* try to alloc a new send buffer */ - sndbuf_desc = kzalloc(sizeof(*sndbuf_desc), GFP_KERNEL); - if (!sndbuf_desc) - break; /* give up with -ENOMEM */ - sndbuf_desc->cpu_addr = kzalloc(tmp_bufsize, - GFP_KERNEL | __GFP_NOWARN | - __GFP_NOMEMALLOC | - __GFP_NORETRY); - if (!sndbuf_desc->cpu_addr) { - kfree(sndbuf_desc); - sndbuf_desc = NULL; - /* if send buffer allocation has failed, - * try a smaller one - */ - continue; - } - rc = smc_ib_buf_map(lgr->lnk[SMC_SINGLE_LINK].smcibdev, - tmp_bufsize, sndbuf_desc, - DMA_TO_DEVICE); + /* try to alloc a new buffer */ + buf_desc = kzalloc(sizeof(*buf_desc), GFP_KERNEL); + if (!buf_desc) + return ERR_PTR(-ENOMEM); + + buf_desc->cpu_addr = + (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | + __GFP_NOMEMALLOC | + __GFP_NORETRY | __GFP_ZERO, + get_order(bufsize)); + if (!buf_desc->cpu_addr) { + kfree(buf_desc); + return ERR_PTR(-EAGAIN); + } + buf_desc->order = get_order(bufsize); + + /* build the sg table from the pages */ + lnk = &lgr->lnk[SMC_SINGLE_LINK]; + rc = sg_alloc_table(&buf_desc->sgt[SMC_SINGLE_LINK], 1, + GFP_KERNEL); + if (rc) { + smc_buf_free(buf_desc, lnk, is_rmb); + return ERR_PTR(rc); + } + sg_set_buf(buf_desc->sgt[SMC_SINGLE_LINK].sgl, + buf_desc->cpu_addr, bufsize); + + /* map sg table to DMA address */ + rc = smc_ib_buf_map_sg(lnk->smcibdev, buf_desc, + is_rmb ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + /* SMC protocol depends on mapping to one DMA address only */ + if (rc != 1) { + smc_buf_free(buf_desc, lnk, is_rmb); + return ERR_PTR(-EAGAIN); + } + + /* create a new memory region for the RMB */ + if (is_rmb) { + rc = smc_ib_get_memory_region(lnk->roce_pd, + IB_ACCESS_REMOTE_WRITE | + IB_ACCESS_LOCAL_WRITE, + buf_desc); if (rc) { - kfree(sndbuf_desc->cpu_addr); - kfree(sndbuf_desc); - sndbuf_desc = NULL; - continue; /* if mapping failed, try smaller one */ + smc_buf_free(buf_desc, lnk, is_rmb); + return ERR_PTR(rc); } - sndbuf_desc->used = 1; - write_lock_bh(&lgr->sndbufs_lock); - list_add(&sndbuf_desc->list, - &lgr->sndbufs[tmp_bufsize_short]); - write_unlock_bh(&lgr->sndbufs_lock); - break; - } - if (sndbuf_desc && sndbuf_desc->cpu_addr) { - conn->sndbuf_desc = sndbuf_desc; - conn->sndbuf_size = tmp_bufsize; - smc->sk.sk_sndbuf = tmp_bufsize * 2; - atomic_set(&conn->sndbuf_space, tmp_bufsize); - return 0; - } else { - return -ENOMEM; } + + return buf_desc; } -/* create the RMB for an SMC socket (even though the SMC protocol - * allows more than one RMB-element per RMB, the Linux implementation - * uses just one RMB-element per RMB, i.e. uses an extra RMB for every - * connection in a link group - */ -int smc_rmb_create(struct smc_sock *smc) +static int __smc_buf_create(struct smc_sock *smc, bool is_rmb) { struct smc_connection *conn = &smc->conn; struct smc_link_group *lgr = conn->lgr; - int tmp_bufsize, tmp_bufsize_short; - struct smc_buf_desc *rmb_desc; - int rc; + struct smc_buf_desc *buf_desc = NULL; + struct list_head *buf_list; + int bufsize, bufsize_short; + int sk_buf_size; + rwlock_t *lock; + + if (is_rmb) + /* use socket recv buffer size (w/o overhead) as start value */ + sk_buf_size = smc->sk.sk_rcvbuf / 2; + else + /* use socket send buffer size (w/o overhead) as start value */ + sk_buf_size = smc->sk.sk_sndbuf / 2; + + for (bufsize_short = smc_compress_bufsize(smc->sk.sk_sndbuf / 2); + bufsize_short >= 0; bufsize_short--) { + + if (is_rmb) { + lock = &lgr->rmbs_lock; + buf_list = &lgr->rmbs[bufsize_short]; + } else { + lock = &lgr->sndbufs_lock; + buf_list = &lgr->sndbufs[bufsize_short]; + } + bufsize = smc_uncompress_bufsize(bufsize_short); + if ((1 << get_order(bufsize)) > SG_MAX_SINGLE_ALLOC) + continue; - /* use socket recv buffer size (w/o overhead) as start value */ - for (tmp_bufsize_short = smc_compress_bufsize(smc->sk.sk_rcvbuf / 2); - tmp_bufsize_short >= 0; tmp_bufsize_short--) { - tmp_bufsize = smc_uncompress_bufsize(tmp_bufsize_short); - /* check for reusable rmb_slot in the link group */ - rmb_desc = smc_rmb_get_slot(lgr, tmp_bufsize_short); - if (rmb_desc) { - memset(rmb_desc->cpu_addr, 0, tmp_bufsize); + /* check for reusable slot in the link group */ + buf_desc = smc_buf_get_slot(lgr, bufsize_short, lock, buf_list); + if (buf_desc) { + memset(buf_desc->cpu_addr, 0, bufsize); break; /* found reusable slot */ } - /* try to alloc a new RMB */ - rmb_desc = kzalloc(sizeof(*rmb_desc), GFP_KERNEL); - if (!rmb_desc) - break; /* give up with -ENOMEM */ - rmb_desc->cpu_addr = kzalloc(tmp_bufsize, - GFP_KERNEL | __GFP_NOWARN | - __GFP_NOMEMALLOC | - __GFP_NORETRY); - if (!rmb_desc->cpu_addr) { - kfree(rmb_desc); - rmb_desc = NULL; - /* if RMB allocation has failed, - * try a smaller one - */ + + buf_desc = smc_new_buf_create(lgr, is_rmb, bufsize); + if (PTR_ERR(buf_desc) == -ENOMEM) + break; + if (IS_ERR(buf_desc)) continue; - } - rc = smc_ib_buf_map(lgr->lnk[SMC_SINGLE_LINK].smcibdev, - tmp_bufsize, rmb_desc, - DMA_FROM_DEVICE); - if (rc) { - kfree(rmb_desc->cpu_addr); - kfree(rmb_desc); - rmb_desc = NULL; - continue; /* if mapping failed, try smaller one */ - } - rmb_desc->rkey[SMC_SINGLE_LINK] = - lgr->lnk[SMC_SINGLE_LINK].roce_pd->unsafe_global_rkey; - rmb_desc->used = 1; - write_lock_bh(&lgr->rmbs_lock); - list_add(&rmb_desc->list, - &lgr->rmbs[tmp_bufsize_short]); - write_unlock_bh(&lgr->rmbs_lock); - break; + + buf_desc->used = 1; + write_lock_bh(lock); + list_add(&buf_desc->list, buf_list); + write_unlock_bh(lock); + break; /* found */ } - if (rmb_desc && rmb_desc->cpu_addr) { - conn->rmb_desc = rmb_desc; - conn->rmbe_size = tmp_bufsize; - conn->rmbe_size_short = tmp_bufsize_short; - smc->sk.sk_rcvbuf = tmp_bufsize * 2; + + if (IS_ERR(buf_desc)) + return -ENOMEM; + + if (is_rmb) { + conn->rmb_desc = buf_desc; + conn->rmbe_size = bufsize; + conn->rmbe_size_short = bufsize_short; + smc->sk.sk_rcvbuf = bufsize * 2; atomic_set(&conn->bytes_to_rcv, 0); - conn->rmbe_update_limit = smc_rmb_wnd_update_limit(tmp_bufsize); - return 0; + conn->rmbe_update_limit = smc_rmb_wnd_update_limit(bufsize); } else { - return -ENOMEM; + conn->sndbuf_desc = buf_desc; + conn->sndbuf_size = bufsize; + smc->sk.sk_sndbuf = bufsize * 2; + atomic_set(&conn->sndbuf_space, bufsize); } + return 0; +} + +void smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn) +{ + struct smc_link_group *lgr = conn->lgr; + + smc_ib_sync_sg_for_cpu(lgr->lnk[SMC_SINGLE_LINK].smcibdev, + conn->sndbuf_desc, DMA_TO_DEVICE); +} + +void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn) +{ + struct smc_link_group *lgr = conn->lgr; + + smc_ib_sync_sg_for_device(lgr->lnk[SMC_SINGLE_LINK].smcibdev, + conn->sndbuf_desc, DMA_TO_DEVICE); +} + +void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn) +{ + struct smc_link_group *lgr = conn->lgr; + + smc_ib_sync_sg_for_cpu(lgr->lnk[SMC_SINGLE_LINK].smcibdev, + conn->rmb_desc, DMA_FROM_DEVICE); +} + +void smc_rmb_sync_sg_for_device(struct smc_connection *conn) +{ + struct smc_link_group *lgr = conn->lgr; + + smc_ib_sync_sg_for_device(lgr->lnk[SMC_SINGLE_LINK].smcibdev, + conn->rmb_desc, DMA_FROM_DEVICE); +} + +/* create the send and receive buffer for an SMC socket; + * receive buffers are called RMBs; + * (even though the SMC protocol allows more than one RMB-element per RMB, + * the Linux implementation uses just one RMB-element per RMB, i.e. uses an + * extra RMB for every connection in a link group + */ +int smc_buf_create(struct smc_sock *smc) +{ + int rc; + + /* create send buffer */ + rc = __smc_buf_create(smc, false); + if (rc) + return rc; + /* create rmb */ + rc = __smc_buf_create(smc, true); + if (rc) + smc_buf_free(smc->conn.sndbuf_desc, + &smc->conn.lgr->lnk[SMC_SINGLE_LINK], false); + return rc; } static inline int smc_rmb_reserve_rtoken_idx(struct smc_link_group *lgr) diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index b013cb43a327ea81cd8bc9e4a5ffff733f87f6a7..19c44bf4e39160deeaea80cb71f5ca781d022ab3 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h @@ -37,6 +37,14 @@ struct smc_wr_buf { u8 raw[SMC_WR_BUF_SIZE]; }; +#define SMC_WR_REG_MR_WAIT_TIME (5 * HZ)/* wait time for ib_wr_reg_mr result */ + +enum smc_wr_reg_state { + POSTED, /* ib_wr_reg_mr request posted */ + CONFIRMED, /* ib_wr_reg_mr response: successful */ + FAILED /* ib_wr_reg_mr response: failure */ +}; + struct smc_link { struct smc_ib_device *smcibdev; /* ib-device */ u8 ibport; /* port - values 1 | 2 */ @@ -65,6 +73,10 @@ struct smc_link { u64 wr_rx_id; /* seq # of last recv WR */ u32 wr_rx_cnt; /* number of WR recv buffers */ + struct ib_reg_wr wr_reg; /* WR register memory region */ + wait_queue_head_t wr_reg_wait; /* wait for wr_reg result */ + enum smc_wr_reg_state wr_reg_state; /* state of wr_reg request */ + union ib_gid gid; /* gid matching used vlan id */ u32 peer_qpn; /* QP number of peer */ enum ib_mtu path_mtu; /* used mtu */ @@ -90,14 +102,15 @@ struct smc_link { /* tx/rx buffer list element for sndbufs list and rmbs list of a lgr */ struct smc_buf_desc { struct list_head list; - u64 dma_addr[SMC_LINKS_PER_LGR_MAX]; - /* mapped address of buffer */ void *cpu_addr; /* virtual address of buffer */ - u32 rkey[SMC_LINKS_PER_LGR_MAX]; - /* for rmb only: - * rkey provided to peer + struct sg_table sgt[SMC_LINKS_PER_LGR_MAX];/* virtual buffer */ + struct ib_mr *mr_rx[SMC_LINKS_PER_LGR_MAX]; + /* for rmb only: memory region + * incl. rkey provided to peer */ + u32 order; /* allocation order */ u32 used; /* currently used / unused */ + bool reused; /* new created / reused */ }; struct smc_rtoken { /* address/key of remote RMB */ @@ -173,9 +186,11 @@ struct smc_clc_msg_accept_confirm; void smc_lgr_free(struct smc_link_group *lgr); void smc_lgr_terminate(struct smc_link_group *lgr); -int smc_sndbuf_create(struct smc_sock *smc); -int smc_rmb_create(struct smc_sock *smc); +int smc_buf_create(struct smc_sock *smc); int smc_rmb_rtoken_handling(struct smc_connection *conn, struct smc_clc_msg_accept_confirm *clc); - +void smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn); +void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn); +void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn); +void smc_rmb_sync_sg_for_device(struct smc_connection *conn); #endif diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index b31715505a358cd4e73d1af6c58a49ef7ef8ecbe..0b5852299158a71dea6c4f38b16482d80c078f56 100644 --- a/net/smc/smc_ib.c +++ b/net/smc/smc_ib.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "smc_pnet.h" @@ -192,8 +193,7 @@ int smc_ib_create_protection_domain(struct smc_link *lnk) { int rc; - lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, - IB_PD_UNSAFE_GLOBAL_RKEY); + lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, 0); rc = PTR_ERR_OR_ZERO(lnk->roce_pd); if (IS_ERR(lnk->roce_pd)) lnk->roce_pd = NULL; @@ -232,10 +232,10 @@ int smc_ib_create_queue_pair(struct smc_link *lnk) .recv_cq = lnk->smcibdev->roce_cq_recv, .srq = NULL, .cap = { - .max_send_wr = SMC_WR_BUF_CNT, /* include unsolicited rdma_writes as well, * there are max. 2 RDMA_WRITE per 1 WR_SEND */ + .max_send_wr = SMC_WR_BUF_CNT * 3, .max_recv_wr = SMC_WR_BUF_CNT * 3, .max_send_sge = SMC_IB_MAX_SEND_SGE, .max_recv_sge = 1, @@ -254,33 +254,117 @@ int smc_ib_create_queue_pair(struct smc_link *lnk) return rc; } -/* map a new TX or RX buffer to DMA */ -int smc_ib_buf_map(struct smc_ib_device *smcibdev, int buf_size, - struct smc_buf_desc *buf_slot, - enum dma_data_direction data_direction) +void smc_ib_put_memory_region(struct ib_mr *mr) { - int rc = 0; + ib_dereg_mr(mr); +} - if (buf_slot->dma_addr[SMC_SINGLE_LINK]) - return rc; /* already mapped */ - buf_slot->dma_addr[SMC_SINGLE_LINK] = - ib_dma_map_single(smcibdev->ibdev, buf_slot->cpu_addr, - buf_size, data_direction); - if (ib_dma_mapping_error(smcibdev->ibdev, - buf_slot->dma_addr[SMC_SINGLE_LINK])) - rc = -EIO; - return rc; +static int smc_ib_map_mr_sg(struct smc_buf_desc *buf_slot) +{ + unsigned int offset = 0; + int sg_num; + + /* map the largest prefix of a dma mapped SG list */ + sg_num = ib_map_mr_sg(buf_slot->mr_rx[SMC_SINGLE_LINK], + buf_slot->sgt[SMC_SINGLE_LINK].sgl, + buf_slot->sgt[SMC_SINGLE_LINK].orig_nents, + &offset, PAGE_SIZE); + + return sg_num; +} + +/* Allocate a memory region and map the dma mapped SG list of buf_slot */ +int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags, + struct smc_buf_desc *buf_slot) +{ + if (buf_slot->mr_rx[SMC_SINGLE_LINK]) + return 0; /* already done */ + + buf_slot->mr_rx[SMC_SINGLE_LINK] = + ib_alloc_mr(pd, IB_MR_TYPE_MEM_REG, 1 << buf_slot->order); + if (IS_ERR(buf_slot->mr_rx[SMC_SINGLE_LINK])) { + int rc; + + rc = PTR_ERR(buf_slot->mr_rx[SMC_SINGLE_LINK]); + buf_slot->mr_rx[SMC_SINGLE_LINK] = NULL; + return rc; + } + + if (smc_ib_map_mr_sg(buf_slot) != 1) + return -EINVAL; + + return 0; } -void smc_ib_buf_unmap(struct smc_ib_device *smcibdev, int buf_size, +/* synchronize buffer usage for cpu access */ +void smc_ib_sync_sg_for_cpu(struct smc_ib_device *smcibdev, + struct smc_buf_desc *buf_slot, + enum dma_data_direction data_direction) +{ + struct scatterlist *sg; + unsigned int i; + + /* for now there is just one DMA address */ + for_each_sg(buf_slot->sgt[SMC_SINGLE_LINK].sgl, sg, + buf_slot->sgt[SMC_SINGLE_LINK].nents, i) { + if (!sg_dma_len(sg)) + break; + ib_dma_sync_single_for_cpu(smcibdev->ibdev, + sg_dma_address(sg), + sg_dma_len(sg), + data_direction); + } +} + +/* synchronize buffer usage for device access */ +void smc_ib_sync_sg_for_device(struct smc_ib_device *smcibdev, + struct smc_buf_desc *buf_slot, + enum dma_data_direction data_direction) +{ + struct scatterlist *sg; + unsigned int i; + + /* for now there is just one DMA address */ + for_each_sg(buf_slot->sgt[SMC_SINGLE_LINK].sgl, sg, + buf_slot->sgt[SMC_SINGLE_LINK].nents, i) { + if (!sg_dma_len(sg)) + break; + ib_dma_sync_single_for_device(smcibdev->ibdev, + sg_dma_address(sg), + sg_dma_len(sg), + data_direction); + } +} + +/* Map a new TX or RX buffer SG-table to DMA */ +int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev, struct smc_buf_desc *buf_slot, enum dma_data_direction data_direction) { - if (!buf_slot->dma_addr[SMC_SINGLE_LINK]) + int mapped_nents; + + mapped_nents = ib_dma_map_sg(smcibdev->ibdev, + buf_slot->sgt[SMC_SINGLE_LINK].sgl, + buf_slot->sgt[SMC_SINGLE_LINK].orig_nents, + data_direction); + if (!mapped_nents) + return -ENOMEM; + + return mapped_nents; +} + +void smc_ib_buf_unmap_sg(struct smc_ib_device *smcibdev, + struct smc_buf_desc *buf_slot, + enum dma_data_direction data_direction) +{ + if (!buf_slot->sgt[SMC_SINGLE_LINK].sgl->dma_address) return; /* already unmapped */ - ib_dma_unmap_single(smcibdev->ibdev, *buf_slot->dma_addr, buf_size, - data_direction); - buf_slot->dma_addr[SMC_SINGLE_LINK] = 0; + + ib_dma_unmap_sg(smcibdev->ibdev, + buf_slot->sgt[SMC_SINGLE_LINK].sgl, + buf_slot->sgt[SMC_SINGLE_LINK].orig_nents, + data_direction); + buf_slot->sgt[SMC_SINGLE_LINK].sgl->dma_address = 0; } static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport) @@ -296,6 +380,7 @@ static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport) ndev = smcibdev->ibdev->get_netdev(smcibdev->ibdev, ibport); if (ndev) { memcpy(&smcibdev->mac, ndev->dev_addr, ETH_ALEN); + dev_put(ndev); } else if (!rc) { memcpy(&smcibdev->mac[ibport - 1][0], &smcibdev->gid[ibport - 1].raw[8], 3); diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h index b567152a526d48c86110a9574833e8610684af4b..9b927a33d5e6236564aab11d7b1b004958c32f52 100644 --- a/net/smc/smc_ib.h +++ b/net/smc/smc_ib.h @@ -51,12 +51,12 @@ int smc_ib_register_client(void) __init; void smc_ib_unregister_client(void); bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport); int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport); -int smc_ib_buf_map(struct smc_ib_device *smcibdev, int buf_size, - struct smc_buf_desc *buf_slot, - enum dma_data_direction data_direction); -void smc_ib_buf_unmap(struct smc_ib_device *smcibdev, int bufsize, +int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev, struct smc_buf_desc *buf_slot, enum dma_data_direction data_direction); +void smc_ib_buf_unmap_sg(struct smc_ib_device *smcibdev, + struct smc_buf_desc *buf_slot, + enum dma_data_direction data_direction); void smc_ib_dealloc_protection_domain(struct smc_link *lnk); int smc_ib_create_protection_domain(struct smc_link *lnk); void smc_ib_destroy_queue_pair(struct smc_link *lnk); @@ -65,6 +65,13 @@ int smc_ib_ready_link(struct smc_link *lnk); int smc_ib_modify_qp_rts(struct smc_link *lnk); int smc_ib_modify_qp_reset(struct smc_link *lnk); long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev); - - +int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags, + struct smc_buf_desc *buf_slot); +void smc_ib_put_memory_region(struct ib_mr *mr); +void smc_ib_sync_sg_for_cpu(struct smc_ib_device *smcibdev, + struct smc_buf_desc *buf_slot, + enum dma_data_direction data_direction); +void smc_ib_sync_sg_for_device(struct smc_ib_device *smcibdev, + struct smc_buf_desc *buf_slot, + enum dma_data_direction data_direction); #endif diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index 78f7af28ae4f25d71469d54d44f98ef4e2df94eb..31f8453c25c5854340e7f701baf0990d0002376e 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c @@ -181,8 +181,10 @@ static int smc_pnet_enter(struct smc_pnetentry *new_pnetelem) sizeof(new_pnetelem->ndev->name)) || smc_pnet_same_ibname(pnetelem, new_pnetelem->smcibdev->ibdev->name, - new_pnetelem->ib_port)) + new_pnetelem->ib_port)) { + dev_put(pnetelem->ndev); goto found; + } } list_add_tail(&new_pnetelem->list, &smc_pnettable.pnetlist); rc = 0; diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c index f0c8b089f770a229b7c805fe5b2d59da40a5c1e3..3e631ae4b6b65f1ac9f32e5a22d6fdc5b294519f 100644 --- a/net/smc/smc_rx.c +++ b/net/smc/smc_rx.c @@ -148,6 +148,8 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, size_t len, read_done = sock_intr_errno(timeo); break; } + if (!timeo) + return -EAGAIN; } if (!atomic_read(&conn->bytes_to_rcv)) { @@ -170,6 +172,7 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, size_t len, copylen, conn->rmbe_size - cons.count); chunk_len_sum = chunk_len; chunk_off = cons.count; + smc_rmb_sync_sg_for_cpu(conn); for (chunk = 0; chunk < 2; chunk++) { if (!(flags & MSG_TRUNC)) { rc = memcpy_to_msg(msg, rcvbuf_base + chunk_off, @@ -177,6 +180,7 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, size_t len, if (rc) { if (!read_done) read_done = -EFAULT; + smc_rmb_sync_sg_for_device(conn); goto out; } } @@ -190,6 +194,7 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, size_t len, chunk_len_sum += chunk_len; chunk_off = 0; /* modulo offset in recv ring buffer */ } + smc_rmb_sync_sg_for_device(conn); /* update cursors */ if (!(flags & MSG_PEEK)) { diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c index 21ec1832ab517d647ac8942ddbd5484492eb4c94..3866573288ddaf67f14943122ed6dbd941e6df3b 100644 --- a/net/smc/smc_tx.c +++ b/net/smc/smc_tx.c @@ -24,6 +24,8 @@ #include "smc_cdc.h" #include "smc_tx.h" +#define SMC_TX_WORK_DELAY HZ + /***************************** sndbuf producer *******************************/ /* callback implementation for sk.sk_write_space() @@ -174,10 +176,12 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len) copylen, conn->sndbuf_size - tx_cnt_prep); chunk_len_sum = chunk_len; chunk_off = tx_cnt_prep; + smc_sndbuf_sync_sg_for_cpu(conn); for (chunk = 0; chunk < 2; chunk++) { rc = memcpy_from_msg(sndbuf_base + chunk_off, msg, chunk_len); if (rc) { + smc_sndbuf_sync_sg_for_device(conn); if (send_done) return send_done; goto out_err; @@ -192,6 +196,7 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len) chunk_len_sum += chunk_len; chunk_off = 0; /* modulo offset in send ring buffer */ } + smc_sndbuf_sync_sg_for_device(conn); /* update cursors */ smc_curs_add(conn->sndbuf_size, &prep, copylen); smc_curs_write(&conn->tx_curs_prep, @@ -277,6 +282,7 @@ static int smc_tx_rdma_writes(struct smc_connection *conn) struct smc_link_group *lgr = conn->lgr; int to_send, rmbespace; struct smc_link *link; + dma_addr_t dma_addr; int num_sges; int rc; @@ -334,12 +340,11 @@ static int smc_tx_rdma_writes(struct smc_connection *conn) src_len = conn->sndbuf_size - sent.count; } src_len_sum = src_len; + dma_addr = sg_dma_address(conn->sndbuf_desc->sgt[SMC_SINGLE_LINK].sgl); for (dstchunk = 0; dstchunk < 2; dstchunk++) { num_sges = 0; for (srcchunk = 0; srcchunk < 2; srcchunk++) { - sges[srcchunk].addr = - conn->sndbuf_desc->dma_addr[SMC_SINGLE_LINK] + - src_off; + sges[srcchunk].addr = dma_addr + src_off; sges[srcchunk].length = src_len; sges[srcchunk].lkey = link->roce_pd->local_dma_lkey; num_sges++; @@ -403,7 +408,8 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn) goto out_unlock; } rc = 0; - schedule_work(&conn->tx_work); + schedule_delayed_work(&conn->tx_work, + SMC_TX_WORK_DELAY); } goto out_unlock; } @@ -427,7 +433,7 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn) */ static void smc_tx_work(struct work_struct *work) { - struct smc_connection *conn = container_of(work, + struct smc_connection *conn = container_of(to_delayed_work(work), struct smc_connection, tx_work); struct smc_sock *smc = container_of(conn, struct smc_sock, conn); @@ -465,7 +471,8 @@ void smc_tx_consumer_update(struct smc_connection *conn) if (!rc) rc = smc_cdc_msg_send(conn, wr_buf, pend); if (rc < 0) { - schedule_work(&conn->tx_work); + schedule_delayed_work(&conn->tx_work, + SMC_TX_WORK_DELAY); return; } smc_curs_write(&conn->rx_curs_confirmed, @@ -484,6 +491,6 @@ void smc_tx_consumer_update(struct smc_connection *conn) void smc_tx_init(struct smc_sock *smc) { smc->sk.sk_write_space = smc_tx_write_space; - INIT_WORK(&smc->conn.tx_work, smc_tx_work); + INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work); spin_lock_init(&smc->conn.send_lock); } diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index 874ee9f9d79674f9576c28f9d1dd669e03e62422..525d91e0d57e2fb3fa00ac9435df8a43bf0ea719 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c @@ -68,6 +68,16 @@ static inline void smc_wr_tx_process_cqe(struct ib_wc *wc) int i; link = wc->qp->qp_context; + + if (wc->opcode == IB_WC_REG_MR) { + if (wc->status) + link->wr_reg_state = FAILED; + else + link->wr_reg_state = CONFIRMED; + wake_up(&link->wr_reg_wait); + return; + } + pnd_snd_idx = smc_wr_tx_find_pending_index(link, wc->wr_id); if (pnd_snd_idx == link->wr_tx_cnt) return; @@ -234,7 +244,7 @@ int smc_wr_tx_send(struct smc_link *link, struct smc_wr_tx_pend_priv *priv) int rc; ib_req_notify_cq(link->smcibdev->roce_cq_send, - IB_CQ_SOLICITED_MASK | IB_CQ_REPORT_MISSED_EVENTS); + IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); pend = container_of(priv, struct smc_wr_tx_pend, priv); rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx], &failed_wr); @@ -243,6 +253,52 @@ int smc_wr_tx_send(struct smc_link *link, struct smc_wr_tx_pend_priv *priv) return rc; } +/* Register a memory region and wait for result. */ +int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr) +{ + struct ib_send_wr *failed_wr = NULL; + int rc; + + ib_req_notify_cq(link->smcibdev->roce_cq_send, + IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); + link->wr_reg_state = POSTED; + link->wr_reg.wr.wr_id = (u64)(uintptr_t)mr; + link->wr_reg.mr = mr; + link->wr_reg.key = mr->rkey; + failed_wr = &link->wr_reg.wr; + rc = ib_post_send(link->roce_qp, &link->wr_reg.wr, &failed_wr); + WARN_ON(failed_wr != &link->wr_reg.wr); + if (rc) + return rc; + + rc = wait_event_interruptible_timeout(link->wr_reg_wait, + (link->wr_reg_state != POSTED), + SMC_WR_REG_MR_WAIT_TIME); + if (!rc) { + /* timeout - terminate connections */ + struct smc_link_group *lgr; + + lgr = container_of(link, struct smc_link_group, + lnk[SMC_SINGLE_LINK]); + smc_lgr_terminate(lgr); + return -EPIPE; + } + if (rc == -ERESTARTSYS) + return -EINTR; + switch (link->wr_reg_state) { + case CONFIRMED: + rc = 0; + break; + case FAILED: + rc = -EIO; + break; + case POSTED: + rc = -EPIPE; + break; + } + return rc; +} + void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_rx_hdr_type, smc_wr_tx_filter filter, smc_wr_tx_dismisser dismisser, @@ -458,6 +514,11 @@ static void smc_wr_init_sge(struct smc_link *lnk) lnk->wr_rx_ibs[i].sg_list = &lnk->wr_rx_sges[i]; lnk->wr_rx_ibs[i].num_sge = 1; } + lnk->wr_reg.wr.next = NULL; + lnk->wr_reg.wr.num_sge = 0; + lnk->wr_reg.wr.send_flags = IB_SEND_SIGNALED; + lnk->wr_reg.wr.opcode = IB_WR_REG_MR; + lnk->wr_reg.access = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE; } void smc_wr_free_link(struct smc_link *lnk) @@ -602,6 +663,8 @@ int smc_wr_create_link(struct smc_link *lnk) smc_wr_init_sge(lnk); memset(lnk->wr_tx_mask, 0, BITS_TO_LONGS(SMC_WR_BUF_CNT) * sizeof(*lnk->wr_tx_mask)); + init_waitqueue_head(&lnk->wr_tx_wait); + init_waitqueue_head(&lnk->wr_reg_wait); return rc; dma_unmap: diff --git a/net/smc/smc_wr.h b/net/smc/smc_wr.h index 0b9beeda6053396f90b8ce5f6622ceda72a3a89d..45eb53833052f637587cf23e10316b02bf321c1c 100644 --- a/net/smc/smc_wr.h +++ b/net/smc/smc_wr.h @@ -102,5 +102,6 @@ void smc_wr_tx_dismiss_slots(struct smc_link *lnk, u8 wr_rx_hdr_type, int smc_wr_rx_register_handler(struct smc_wr_rx_handler *handler); int smc_wr_rx_post_init(struct smc_link *link); void smc_wr_rx_cq_handler(struct ib_cq *ib_cq, void *cq_context); +int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr); #endif /* SMC_WR_H */ diff --git a/net/socket.c b/net/socket.c index bf2122691fba25ae778d6fd68a179b1e9163defe..c729625eb5d36b97fb799ff418405239dc9e68e1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -652,6 +652,20 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg, } EXPORT_SYMBOL(kernel_sendmsg); +int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg, + struct kvec *vec, size_t num, size_t size) +{ + struct socket *sock = sk->sk_socket; + + if (!sock->ops->sendmsg_locked) + return sock_no_sendmsg_locked(sk, msg, size); + + iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size); + + return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); +} +EXPORT_SYMBOL(kernel_sendmsg_locked); + static bool skb_is_err_queue(const struct sk_buff *skb) { /* pkt_type of skbs enqueued on the error queue are set to @@ -1916,7 +1930,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, if (copy_from_user(&msg, umsg, sizeof(*umsg))) return -EFAULT; - kmsg->msg_control = msg.msg_control; + kmsg->msg_control = (void __force *)msg.msg_control; kmsg->msg_controllen = msg.msg_controllen; kmsg->msg_flags = msg.msg_flags; @@ -1935,7 +1949,8 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, if (msg.msg_name && kmsg->msg_namelen) { if (!save_addr) { - err = move_addr_to_kernel(msg.msg_name, kmsg->msg_namelen, + err = move_addr_to_kernel(msg.msg_name, + kmsg->msg_namelen, kmsg->msg_name); if (err < 0) return err; @@ -3375,6 +3390,19 @@ int kernel_sendpage(struct socket *sock, struct page *page, int offset, } EXPORT_SYMBOL(kernel_sendpage); +int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset, + size_t size, int flags) +{ + struct socket *sock = sk->sk_socket; + + if (sock->ops->sendpage_locked) + return sock->ops->sendpage_locked(sk, page, offset, size, + flags); + + return sock_no_sendpage_locked(sk, page, offset, size, flags); +} +EXPORT_SYMBOL(kernel_sendpage_locked); + int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg) { mm_segment_t oldfs = get_fs(); @@ -3404,7 +3432,6 @@ u32 kernel_sock_ip_overhead(struct sock *sk) struct inet_sock *inet; struct ip_options_rcu *opt; u32 overhead = 0; - bool owned_by_user; #if IS_ENABLED(CONFIG_IPV6) struct ipv6_pinfo *np; struct ipv6_txoptions *optv6 = NULL; @@ -3413,13 +3440,12 @@ u32 kernel_sock_ip_overhead(struct sock *sk) if (!sk) return overhead; - owned_by_user = sock_owned_by_user(sk); switch (sk->sk_family) { case AF_INET: inet = inet_sk(sk); overhead += sizeof(struct iphdr); opt = rcu_dereference_protected(inet->inet_opt, - owned_by_user); + sock_owned_by_user(sk)); if (opt) overhead += opt->opt.optlen; return overhead; @@ -3429,7 +3455,7 @@ u32 kernel_sock_ip_overhead(struct sock *sk) overhead += sizeof(struct ipv6hdr); if (np) optv6 = rcu_dereference_protected(np->opt, - owned_by_user); + sock_owned_by_user(sk)); if (optv6) overhead += (optv6->opt_flen + optv6->opt_nflen); return overhead; diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index b5c279b2268017e502f2028355874b62208dc3a1..d4ea46a5f233b42d56d2884bf1532ca7d9374a94 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c @@ -29,44 +29,46 @@ static struct workqueue_struct *strp_wq; -struct _strp_rx_msg { - /* Internal cb structure. struct strp_rx_msg must be first for passing +struct _strp_msg { + /* Internal cb structure. struct strp_msg must be first for passing * to upper layer. */ - struct strp_rx_msg strp; + struct strp_msg strp; int accum_len; int early_eaten; }; -static inline struct _strp_rx_msg *_strp_rx_msg(struct sk_buff *skb) +static inline struct _strp_msg *_strp_msg(struct sk_buff *skb) { - return (struct _strp_rx_msg *)((void *)skb->cb + + return (struct _strp_msg *)((void *)skb->cb + offsetof(struct qdisc_skb_cb, data)); } /* Lower lock held */ -static void strp_abort_rx_strp(struct strparser *strp, int err) +static void strp_abort_strp(struct strparser *strp, int err) { - struct sock *csk = strp->sk; - /* Unrecoverable error in receive */ - del_timer(&strp->rx_msg_timer); + del_timer(&strp->msg_timer); - if (strp->rx_stopped) + if (strp->stopped) return; - strp->rx_stopped = 1; + strp->stopped = 1; + + if (strp->sk) { + struct sock *sk = strp->sk; - /* Report an error on the lower socket */ - csk->sk_err = err; - csk->sk_error_report(csk); + /* Report an error on the lower socket */ + sk->sk_err = err; + sk->sk_error_report(sk); + } } -static void strp_start_rx_timer(struct strparser *strp) +static void strp_start_timer(struct strparser *strp, long timeo) { - if (strp->sk->sk_rcvtimeo) - mod_timer(&strp->rx_msg_timer, strp->sk->sk_rcvtimeo); + if (timeo) + mod_timer(&strp->msg_timer, timeo); } /* Lower lock held */ @@ -74,46 +76,55 @@ static void strp_parser_err(struct strparser *strp, int err, read_descriptor_t *desc) { desc->error = err; - kfree_skb(strp->rx_skb_head); - strp->rx_skb_head = NULL; + kfree_skb(strp->skb_head); + strp->skb_head = NULL; strp->cb.abort_parser(strp, err); } static inline int strp_peek_len(struct strparser *strp) { - struct socket *sock = strp->sk->sk_socket; + if (strp->sk) { + struct socket *sock = strp->sk->sk_socket; + + return sock->ops->peek_len(sock); + } - return sock->ops->peek_len(sock); + /* If we don't have an associated socket there's nothing to peek. + * Return int max to avoid stopping the strparser. + */ + + return INT_MAX; } /* Lower socket lock held */ -static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, - unsigned int orig_offset, size_t orig_len) +static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, + unsigned int orig_offset, size_t orig_len, + size_t max_msg_size, long timeo) { struct strparser *strp = (struct strparser *)desc->arg.data; - struct _strp_rx_msg *rxm; + struct _strp_msg *stm; struct sk_buff *head, *skb; size_t eaten = 0, cand_len; ssize_t extra; int err; bool cloned_orig = false; - if (strp->rx_paused) + if (strp->paused) return 0; - head = strp->rx_skb_head; + head = strp->skb_head; if (head) { /* Message already in progress */ - rxm = _strp_rx_msg(head); - if (unlikely(rxm->early_eaten)) { + stm = _strp_msg(head); + if (unlikely(stm->early_eaten)) { /* Already some number of bytes on the receive sock - * data saved in rx_skb_head, just indicate they + * data saved in skb_head, just indicate they * are consumed. */ - eaten = orig_len <= rxm->early_eaten ? - orig_len : rxm->early_eaten; - rxm->early_eaten -= eaten; + eaten = orig_len <= stm->early_eaten ? + orig_len : stm->early_eaten; + stm->early_eaten -= eaten; return eaten; } @@ -126,12 +137,12 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, */ orig_skb = skb_clone(orig_skb, GFP_ATOMIC); if (!orig_skb) { - STRP_STATS_INCR(strp->stats.rx_mem_fail); + STRP_STATS_INCR(strp->stats.mem_fail); desc->error = -ENOMEM; return 0; } if (!pskb_pull(orig_skb, orig_offset)) { - STRP_STATS_INCR(strp->stats.rx_mem_fail); + STRP_STATS_INCR(strp->stats.mem_fail); kfree_skb(orig_skb); desc->error = -ENOMEM; return 0; @@ -140,13 +151,13 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, orig_offset = 0; } - if (!strp->rx_skb_nextp) { + if (!strp->skb_nextp) { /* We are going to append to the frags_list of head. * Need to unshare the frag_list. */ err = skb_unclone(head, GFP_ATOMIC); if (err) { - STRP_STATS_INCR(strp->stats.rx_mem_fail); + STRP_STATS_INCR(strp->stats.mem_fail); desc->error = err; return 0; } @@ -165,20 +176,20 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, skb = alloc_skb(0, GFP_ATOMIC); if (!skb) { - STRP_STATS_INCR(strp->stats.rx_mem_fail); + STRP_STATS_INCR(strp->stats.mem_fail); desc->error = -ENOMEM; return 0; } skb->len = head->len; skb->data_len = head->len; skb->truesize = head->truesize; - *_strp_rx_msg(skb) = *_strp_rx_msg(head); - strp->rx_skb_nextp = &head->next; + *_strp_msg(skb) = *_strp_msg(head); + strp->skb_nextp = &head->next; skb_shinfo(skb)->frag_list = head; - strp->rx_skb_head = skb; + strp->skb_head = skb; head = skb; } else { - strp->rx_skb_nextp = + strp->skb_nextp = &skb_shinfo(head)->frag_list; } } @@ -188,112 +199,112 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, /* Always clone since we will consume something */ skb = skb_clone(orig_skb, GFP_ATOMIC); if (!skb) { - STRP_STATS_INCR(strp->stats.rx_mem_fail); + STRP_STATS_INCR(strp->stats.mem_fail); desc->error = -ENOMEM; break; } cand_len = orig_len - eaten; - head = strp->rx_skb_head; + head = strp->skb_head; if (!head) { head = skb; - strp->rx_skb_head = head; - /* Will set rx_skb_nextp on next packet if needed */ - strp->rx_skb_nextp = NULL; - rxm = _strp_rx_msg(head); - memset(rxm, 0, sizeof(*rxm)); - rxm->strp.offset = orig_offset + eaten; + strp->skb_head = head; + /* Will set skb_nextp on next packet if needed */ + strp->skb_nextp = NULL; + stm = _strp_msg(head); + memset(stm, 0, sizeof(*stm)); + stm->strp.offset = orig_offset + eaten; } else { /* Unclone since we may be appending to an skb that we * already share a frag_list with. */ err = skb_unclone(skb, GFP_ATOMIC); if (err) { - STRP_STATS_INCR(strp->stats.rx_mem_fail); + STRP_STATS_INCR(strp->stats.mem_fail); desc->error = err; break; } - rxm = _strp_rx_msg(head); - *strp->rx_skb_nextp = skb; - strp->rx_skb_nextp = &skb->next; + stm = _strp_msg(head); + *strp->skb_nextp = skb; + strp->skb_nextp = &skb->next; head->data_len += skb->len; head->len += skb->len; head->truesize += skb->truesize; } - if (!rxm->strp.full_len) { + if (!stm->strp.full_len) { ssize_t len; len = (*strp->cb.parse_msg)(strp, head); if (!len) { /* Need more header to determine length */ - if (!rxm->accum_len) { + if (!stm->accum_len) { /* Start RX timer for new message */ - strp_start_rx_timer(strp); + strp_start_timer(strp, timeo); } - rxm->accum_len += cand_len; + stm->accum_len += cand_len; eaten += cand_len; - STRP_STATS_INCR(strp->stats.rx_need_more_hdr); + STRP_STATS_INCR(strp->stats.need_more_hdr); WARN_ON(eaten != orig_len); break; } else if (len < 0) { - if (len == -ESTRPIPE && rxm->accum_len) { + if (len == -ESTRPIPE && stm->accum_len) { len = -ENODATA; - strp->rx_unrecov_intr = 1; + strp->unrecov_intr = 1; } else { - strp->rx_interrupted = 1; + strp->interrupted = 1; } strp_parser_err(strp, len, desc); break; - } else if (len > strp->sk->sk_rcvbuf) { + } else if (len > max_msg_size) { /* Message length exceeds maximum allowed */ - STRP_STATS_INCR(strp->stats.rx_msg_too_big); + STRP_STATS_INCR(strp->stats.msg_too_big); strp_parser_err(strp, -EMSGSIZE, desc); break; } else if (len <= (ssize_t)head->len - - skb->len - rxm->strp.offset) { + skb->len - stm->strp.offset) { /* Length must be into new skb (and also * greater than zero) */ - STRP_STATS_INCR(strp->stats.rx_bad_hdr_len); + STRP_STATS_INCR(strp->stats.bad_hdr_len); strp_parser_err(strp, -EPROTO, desc); break; } - rxm->strp.full_len = len; + stm->strp.full_len = len; } - extra = (ssize_t)(rxm->accum_len + cand_len) - - rxm->strp.full_len; + extra = (ssize_t)(stm->accum_len + cand_len) - + stm->strp.full_len; if (extra < 0) { /* Message not complete yet. */ - if (rxm->strp.full_len - rxm->accum_len > + if (stm->strp.full_len - stm->accum_len > strp_peek_len(strp)) { - /* Don't have the whole messages in the socket - * buffer. Set strp->rx_need_bytes to wait for + /* Don't have the whole message in the socket + * buffer. Set strp->need_bytes to wait for * the rest of the message. Also, set "early * eaten" since we've already buffered the skb * but don't consume yet per strp_read_sock. */ - if (!rxm->accum_len) { + if (!stm->accum_len) { /* Start RX timer for new message */ - strp_start_rx_timer(strp); + strp_start_timer(strp, timeo); } - strp->rx_need_bytes = rxm->strp.full_len - - rxm->accum_len; - rxm->accum_len += cand_len; - rxm->early_eaten = cand_len; - STRP_STATS_ADD(strp->stats.rx_bytes, cand_len); + strp->need_bytes = stm->strp.full_len - + stm->accum_len; + stm->accum_len += cand_len; + stm->early_eaten = cand_len; + STRP_STATS_ADD(strp->stats.bytes, cand_len); desc->count = 0; /* Stop reading socket */ break; } - rxm->accum_len += cand_len; + stm->accum_len += cand_len; eaten += cand_len; WARN_ON(eaten != orig_len); break; @@ -308,14 +319,14 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, eaten += (cand_len - extra); /* Hurray, we have a new message! */ - del_timer(&strp->rx_msg_timer); - strp->rx_skb_head = NULL; - STRP_STATS_INCR(strp->stats.rx_msgs); + del_timer(&strp->msg_timer); + strp->skb_head = NULL; + STRP_STATS_INCR(strp->stats.msgs); /* Give skb to upper layer */ strp->cb.rcv_msg(strp, head); - if (unlikely(strp->rx_paused)) { + if (unlikely(strp->paused)) { /* Upper layer paused strp */ break; } @@ -324,11 +335,33 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, if (cloned_orig) kfree_skb(orig_skb); - STRP_STATS_ADD(strp->stats.rx_bytes, eaten); + STRP_STATS_ADD(strp->stats.bytes, eaten); return eaten; } +int strp_process(struct strparser *strp, struct sk_buff *orig_skb, + unsigned int orig_offset, size_t orig_len, + size_t max_msg_size, long timeo) +{ + read_descriptor_t desc; /* Dummy arg to strp_recv */ + + desc.arg.data = strp; + + return __strp_recv(&desc, orig_skb, orig_offset, orig_len, + max_msg_size, timeo); +} +EXPORT_SYMBOL_GPL(strp_process); + +static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, + unsigned int orig_offset, size_t orig_len) +{ + struct strparser *strp = (struct strparser *)desc->arg.data; + + return __strp_recv(desc, orig_skb, orig_offset, orig_len, + strp->sk->sk_rcvbuf, strp->sk->sk_rcvtimeo); +} + static int default_read_sock_done(struct strparser *strp, int err) { return err; @@ -340,6 +373,9 @@ static int strp_read_sock(struct strparser *strp) struct socket *sock = strp->sk->sk_socket; read_descriptor_t desc; + if (unlikely(!sock || !sock->ops || !sock->ops->read_sock)) + return -EBUSY; + desc.arg.data = strp; desc.error = 0; desc.count = 1; /* give more than one skb per call */ @@ -355,101 +391,124 @@ static int strp_read_sock(struct strparser *strp) /* Lower sock lock held */ void strp_data_ready(struct strparser *strp) { - if (unlikely(strp->rx_stopped)) + if (unlikely(strp->stopped)) return; - /* This check is needed to synchronize with do_strp_rx_work. - * do_strp_rx_work acquires a process lock (lock_sock) whereas + /* This check is needed to synchronize with do_strp_work. + * do_strp_work acquires a process lock (lock_sock) whereas * the lock held here is bh_lock_sock. The two locks can be * held by different threads at the same time, but bh_lock_sock * allows a thread in BH context to safely check if the process * lock is held. In this case, if the lock is held, queue work. */ if (sock_owned_by_user(strp->sk)) { - queue_work(strp_wq, &strp->rx_work); + queue_work(strp_wq, &strp->work); return; } - if (strp->rx_paused) + if (strp->paused) return; - if (strp->rx_need_bytes) { - if (strp_peek_len(strp) >= strp->rx_need_bytes) - strp->rx_need_bytes = 0; + if (strp->need_bytes) { + if (strp_peek_len(strp) >= strp->need_bytes) + strp->need_bytes = 0; else return; } if (strp_read_sock(strp) == -ENOMEM) - queue_work(strp_wq, &strp->rx_work); + queue_work(strp_wq, &strp->work); } EXPORT_SYMBOL_GPL(strp_data_ready); -static void do_strp_rx_work(struct strparser *strp) +static void do_strp_work(struct strparser *strp) { read_descriptor_t rd_desc; - struct sock *csk = strp->sk; /* We need the read lock to synchronize with strp_data_ready. We * need the socket lock for calling strp_read_sock. */ - lock_sock(csk); + strp->cb.lock(strp); - if (unlikely(strp->rx_stopped)) + if (unlikely(strp->stopped)) goto out; - if (strp->rx_paused) + if (strp->paused) goto out; rd_desc.arg.data = strp; if (strp_read_sock(strp) == -ENOMEM) - queue_work(strp_wq, &strp->rx_work); + queue_work(strp_wq, &strp->work); out: - release_sock(csk); + strp->cb.unlock(strp); } -static void strp_rx_work(struct work_struct *w) +static void strp_work(struct work_struct *w) { - do_strp_rx_work(container_of(w, struct strparser, rx_work)); + do_strp_work(container_of(w, struct strparser, work)); } -static void strp_rx_msg_timeout(unsigned long arg) +static void strp_msg_timeout(unsigned long arg) { struct strparser *strp = (struct strparser *)arg; /* Message assembly timed out */ - STRP_STATS_INCR(strp->stats.rx_msg_timeouts); - lock_sock(strp->sk); + STRP_STATS_INCR(strp->stats.msg_timeouts); + strp->cb.lock(strp); strp->cb.abort_parser(strp, ETIMEDOUT); + strp->cb.unlock(strp); +} + +static void strp_sock_lock(struct strparser *strp) +{ + lock_sock(strp->sk); +} + +static void strp_sock_unlock(struct strparser *strp) +{ release_sock(strp->sk); } -int strp_init(struct strparser *strp, struct sock *csk, - struct strp_callbacks *cb) +int strp_init(struct strparser *strp, struct sock *sk, + const struct strp_callbacks *cb) { - struct socket *sock = csk->sk_socket; if (!cb || !cb->rcv_msg || !cb->parse_msg) return -EINVAL; - if (!sock->ops->read_sock || !sock->ops->peek_len) - return -EAFNOSUPPORT; - - memset(strp, 0, sizeof(*strp)); + /* The sk (sock) arg determines the mode of the stream parser. + * + * If the sock is set then the strparser is in receive callback mode. + * The upper layer calls strp_data_ready to kick receive processing + * and strparser calls the read_sock function on the socket to + * get packets. + * + * If the sock is not set then the strparser is in general mode. + * The upper layer calls strp_process for each skb to be parsed. + */ - strp->sk = csk; + if (!sk) { + if (!cb->lock || !cb->unlock) + return -EINVAL; + } - setup_timer(&strp->rx_msg_timer, strp_rx_msg_timeout, - (unsigned long)strp); + memset(strp, 0, sizeof(*strp)); - INIT_WORK(&strp->rx_work, strp_rx_work); + strp->sk = sk; + strp->cb.lock = cb->lock ? : strp_sock_lock; + strp->cb.unlock = cb->unlock ? : strp_sock_unlock; strp->cb.rcv_msg = cb->rcv_msg; strp->cb.parse_msg = cb->parse_msg; strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done; - strp->cb.abort_parser = cb->abort_parser ? : strp_abort_rx_strp; + strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp; + + setup_timer(&strp->msg_timer, strp_msg_timeout, + (unsigned long)strp); + + INIT_WORK(&strp->work, strp_work); return 0; } @@ -457,12 +516,12 @@ EXPORT_SYMBOL_GPL(strp_init); void strp_unpause(struct strparser *strp) { - strp->rx_paused = 0; + strp->paused = 0; - /* Sync setting rx_paused with RX work */ + /* Sync setting paused with RX work */ smp_mb(); - queue_work(strp_wq, &strp->rx_work); + queue_work(strp_wq, &strp->work); } EXPORT_SYMBOL_GPL(strp_unpause); @@ -471,27 +530,27 @@ EXPORT_SYMBOL_GPL(strp_unpause); */ void strp_done(struct strparser *strp) { - WARN_ON(!strp->rx_stopped); + WARN_ON(!strp->stopped); - del_timer_sync(&strp->rx_msg_timer); - cancel_work_sync(&strp->rx_work); + del_timer_sync(&strp->msg_timer); + cancel_work_sync(&strp->work); - if (strp->rx_skb_head) { - kfree_skb(strp->rx_skb_head); - strp->rx_skb_head = NULL; + if (strp->skb_head) { + kfree_skb(strp->skb_head); + strp->skb_head = NULL; } } EXPORT_SYMBOL_GPL(strp_done); void strp_stop(struct strparser *strp) { - strp->rx_stopped = 1; + strp->stopped = 1; } EXPORT_SYMBOL_GPL(strp_stop); void strp_check_rcv(struct strparser *strp) { - queue_work(strp_wq, &strp->rx_work); + queue_work(strp_wq, &strp->work); } EXPORT_SYMBOL_GPL(strp_check_rcv); diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index ac701c28f44f376195f27507ba1c61698d0f9b65..c2c68a15b59de07c9837599d959174b55ae353ba 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -171,10 +171,10 @@ int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs) /* * Add the temporary list to the backchannel preallocation list */ - spin_lock_bh(&xprt->bc_pa_lock); + spin_lock(&xprt->bc_pa_lock); list_splice(&tmp_list, &xprt->bc_pa_list); xprt_inc_alloc_count(xprt, min_reqs); - spin_unlock_bh(&xprt->bc_pa_lock); + spin_unlock(&xprt->bc_pa_lock); dprintk("RPC: setup backchannel transport done\n"); return 0; diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 2e49d1f892b7911ba051a4a433afac9c4266a8b3..2ad827db270422ed7f2c84aae374c234f445e6ab 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1903,6 +1903,14 @@ call_connect_status(struct rpc_task *task) task->tk_status = 0; switch (status) { case -ECONNREFUSED: + /* A positive refusal suggests a rebind is needed. */ + if (RPC_IS_SOFTCONN(task)) + break; + if (clnt->cl_autobind) { + rpc_force_rebind(clnt); + task->tk_action = call_bind; + return; + } case -ECONNRESET: case -ECONNABORTED: case -ENETUNREACH: @@ -2139,10 +2147,6 @@ call_status(struct rpc_task *task) rpc_delay(task, 3*HZ); case -ETIMEDOUT: task->tk_action = call_timeout; - if (!(task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT) - && task->tk_client->cl_discrtry) - xprt_conditional_disconnect(req->rq_xprt, - req->rq_connect_cookie); break; case -ECONNREFUSED: case -ECONNRESET: diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 85ce0db5b0a6907d8b08973f6e00057fb6ff28e4..aa04666f929db314b6daa46d206e1d405170e2b6 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -421,7 +421,7 @@ __svc_init_bc(struct svc_serv *serv) */ static struct svc_serv * __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, - struct svc_serv_ops *ops) + const struct svc_serv_ops *ops) { struct svc_serv *serv; unsigned int vers; @@ -486,7 +486,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, struct svc_serv * svc_create(struct svc_program *prog, unsigned int bufsize, - struct svc_serv_ops *ops) + const struct svc_serv_ops *ops) { return __svc_create(prog, bufsize, /*npools*/1, ops); } @@ -494,7 +494,7 @@ EXPORT_SYMBOL_GPL(svc_create); struct svc_serv * svc_create_pooled(struct svc_program *prog, unsigned int bufsize, - struct svc_serv_ops *ops) + const struct svc_serv_ops *ops) { struct svc_serv *serv; unsigned int npools = svc_pool_map_get(); diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 2b720fa35c4ff7c2ae906e9e76d13d27a2b2f008..ff8e06cd067e975eb87b55a5ff2485fd90299a0a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -421,6 +421,9 @@ static void svc_data_ready(struct sock *sk) dprintk("svc: socket %p(inet %p), busy=%d\n", svsk, sk, test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)); + + /* Refer to svc_setup_socket() for details. */ + rmb(); svsk->sk_odata(sk); if (!test_and_set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags)) svc_xprt_enqueue(&svsk->sk_xprt); @@ -437,6 +440,9 @@ static void svc_write_space(struct sock *sk) if (svsk) { dprintk("svc: socket %p(inet %p), write_space busy=%d\n", svsk, sk, test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags)); + + /* Refer to svc_setup_socket() for details. */ + rmb(); svsk->sk_owspace(sk); svc_xprt_enqueue(&svsk->sk_xprt); } @@ -687,7 +693,7 @@ static struct svc_xprt *svc_udp_create(struct svc_serv *serv, return svc_create_socket(serv, IPPROTO_UDP, net, sa, salen, flags); } -static struct svc_xprt_ops svc_udp_ops = { +static const struct svc_xprt_ops svc_udp_ops = { .xpo_create = svc_udp_create, .xpo_recvfrom = svc_udp_recvfrom, .xpo_sendto = svc_udp_sendto, @@ -760,8 +766,12 @@ static void svc_tcp_listen_data_ready(struct sock *sk) dprintk("svc: socket %p TCP (listen) state change %d\n", sk, sk->sk_state); - if (svsk) + if (svsk) { + /* Refer to svc_setup_socket() for details. */ + rmb(); svsk->sk_odata(sk); + } + /* * This callback may called twice when a new connection * is established as a child socket inherits everything @@ -794,6 +804,8 @@ static void svc_tcp_state_change(struct sock *sk) if (!svsk) printk("svc: socket %p: no user data\n", sk); else { + /* Refer to svc_setup_socket() for details. */ + rmb(); svsk->sk_ostate(sk); if (sk->sk_state != TCP_ESTABLISHED) { set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); @@ -1001,7 +1013,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) if (!bc_xprt) return -EAGAIN; - spin_lock_bh(&bc_xprt->transport_lock); + spin_lock(&bc_xprt->recv_lock); req = xprt_lookup_rqst(bc_xprt, xid); if (!req) goto unlock_notfound; @@ -1019,7 +1031,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) memcpy(dst->iov_base, src->iov_base, src->iov_len); xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); rqstp->rq_arg.len = 0; - spin_unlock_bh(&bc_xprt->transport_lock); + spin_unlock(&bc_xprt->recv_lock); return 0; unlock_notfound: printk(KERN_NOTICE @@ -1028,7 +1040,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) __func__, ntohl(calldir), bc_xprt, ntohl(xid)); unlock_eagain: - spin_unlock_bh(&bc_xprt->transport_lock); + spin_unlock(&bc_xprt->recv_lock); return -EAGAIN; } @@ -1229,7 +1241,7 @@ static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt) { } -static struct svc_xprt_ops svc_tcp_bc_ops = { +static const struct svc_xprt_ops svc_tcp_bc_ops = { .xpo_create = svc_bc_tcp_create, .xpo_detach = svc_bc_tcp_sock_detach, .xpo_free = svc_bc_sock_free, @@ -1263,7 +1275,7 @@ static void svc_cleanup_bc_xprt_sock(void) } #endif /* CONFIG_SUNRPC_BACKCHANNEL */ -static struct svc_xprt_ops svc_tcp_ops = { +static const struct svc_xprt_ops svc_tcp_ops = { .xpo_create = svc_tcp_create, .xpo_recvfrom = svc_tcp_recvfrom, .xpo_sendto = svc_tcp_sendto, @@ -1381,12 +1393,18 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, return ERR_PTR(err); } - inet->sk_user_data = svsk; svsk->sk_sock = sock; svsk->sk_sk = inet; svsk->sk_ostate = inet->sk_state_change; svsk->sk_odata = inet->sk_data_ready; svsk->sk_owspace = inet->sk_write_space; + /* + * This barrier is necessary in order to prevent race condition + * with svc_data_ready(), svc_listen_data_ready() and others + * when calling callbacks above. + */ + wmb(); + inet->sk_user_data = svsk; /* Initialize the socket */ if (sock->type == SOCK_DGRAM) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 4654a99342697e729d1c4e61242a421b72d98cf7..e741ec2b4d8e6ea5d08a8e942e3021e5a20e4c6a 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -844,6 +844,50 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid) } EXPORT_SYMBOL_GPL(xprt_lookup_rqst); +/** + * xprt_pin_rqst - Pin a request on the transport receive list + * @req: Request to pin + * + * Caller must ensure this is atomic with the call to xprt_lookup_rqst() + * so should be holding the xprt transport lock. + */ +void xprt_pin_rqst(struct rpc_rqst *req) +{ + set_bit(RPC_TASK_MSG_RECV, &req->rq_task->tk_runstate); +} +EXPORT_SYMBOL_GPL(xprt_pin_rqst); + +/** + * xprt_unpin_rqst - Unpin a request on the transport receive list + * @req: Request to pin + * + * Caller should be holding the xprt transport lock. + */ +void xprt_unpin_rqst(struct rpc_rqst *req) +{ + struct rpc_task *task = req->rq_task; + + clear_bit(RPC_TASK_MSG_RECV, &task->tk_runstate); + if (test_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate)) + wake_up_bit(&task->tk_runstate, RPC_TASK_MSG_RECV); +} +EXPORT_SYMBOL_GPL(xprt_unpin_rqst); + +static void xprt_wait_on_pinned_rqst(struct rpc_rqst *req) +__must_hold(&req->rq_xprt->recv_lock) +{ + struct rpc_task *task = req->rq_task; + + if (task && test_bit(RPC_TASK_MSG_RECV, &task->tk_runstate)) { + spin_unlock(&req->rq_xprt->recv_lock); + set_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate); + wait_on_bit(&task->tk_runstate, RPC_TASK_MSG_RECV, + TASK_UNINTERRUPTIBLE); + clear_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate); + spin_lock(&req->rq_xprt->recv_lock); + } +} + static void xprt_update_rtt(struct rpc_task *task) { struct rpc_rqst *req = task->tk_rqstp; @@ -966,13 +1010,13 @@ void xprt_transmit(struct rpc_task *task) /* * Add to the list only if we're expecting a reply */ - spin_lock_bh(&xprt->transport_lock); /* Update the softirq receive buffer */ memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(req->rq_private_buf)); /* Add request to the receive list */ + spin_lock(&xprt->recv_lock); list_add_tail(&req->rq_list, &xprt->recv); - spin_unlock_bh(&xprt->transport_lock); + spin_unlock(&xprt->recv_lock); xprt_reset_majortimeo(req); /* Turn off autodisconnect */ del_singleshot_timer_sync(&xprt->timer); @@ -1287,12 +1331,16 @@ void xprt_release(struct rpc_task *task) task->tk_ops->rpc_count_stats(task, task->tk_calldata); else if (task->tk_client) rpc_count_iostats(task, task->tk_client->cl_metrics); + spin_lock(&xprt->recv_lock); + if (!list_empty(&req->rq_list)) { + list_del(&req->rq_list); + xprt_wait_on_pinned_rqst(req); + } + spin_unlock(&xprt->recv_lock); spin_lock_bh(&xprt->transport_lock); xprt->ops->release_xprt(xprt, task); if (xprt->ops->release_request) xprt->ops->release_request(task); - if (!list_empty(&req->rq_list)) - list_del(&req->rq_list); xprt->last_used = jiffies; xprt_schedule_autodisconnect(xprt); spin_unlock_bh(&xprt->transport_lock); @@ -1318,6 +1366,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net) spin_lock_init(&xprt->transport_lock); spin_lock_init(&xprt->reserve_lock); + spin_lock_init(&xprt->recv_lock); INIT_LIST_HEAD(&xprt->free); INIT_LIST_HEAD(&xprt->recv); diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 03f6b5840764dcc2c486015edd8dc7de4cd84b26..d31d0ac5ada9a6a08fe6760a3b5e2cb4eaa552e9 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -49,6 +49,7 @@ static int rpcrdma_bc_setup_rqst(struct rpcrdma_xprt *r_xprt, if (IS_ERR(rb)) goto out_fail; req->rl_rdmabuf = rb; + xdr_buf_init(&req->rl_hdrbuf, rb->rg_base, rdmab_length(rb)); size = r_xprt->rx_data.inline_rsize; rb = rpcrdma_alloc_regbuf(size, DMA_TO_DEVICE, GFP_KERNEL); @@ -202,20 +203,24 @@ size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *xprt) */ int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst) { - struct rpc_xprt *xprt = rqst->rq_xprt; - struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); + struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt); struct rpcrdma_req *req = rpcr_to_rdmar(rqst); - struct rpcrdma_msg *headerp; - - headerp = rdmab_to_msg(req->rl_rdmabuf); - headerp->rm_xid = rqst->rq_xid; - headerp->rm_vers = rpcrdma_version; - headerp->rm_credit = - cpu_to_be32(r_xprt->rx_buf.rb_bc_srv_max_requests); - headerp->rm_type = rdma_msg; - headerp->rm_body.rm_chunks[0] = xdr_zero; - headerp->rm_body.rm_chunks[1] = xdr_zero; - headerp->rm_body.rm_chunks[2] = xdr_zero; + __be32 *p; + + rpcrdma_set_xdrlen(&req->rl_hdrbuf, 0); + xdr_init_encode(&req->rl_stream, &req->rl_hdrbuf, + req->rl_rdmabuf->rg_base); + + p = xdr_reserve_space(&req->rl_stream, 28); + if (unlikely(!p)) + return -EIO; + *p++ = rqst->rq_xid; + *p++ = rpcrdma_version; + *p++ = cpu_to_be32(r_xprt->rx_buf.rb_bc_srv_max_requests); + *p++ = rdma_msg; + *p++ = xdr_zero; + *p++ = xdr_zero; + *p = xdr_zero; if (!rpcrdma_prepare_send_sges(&r_xprt->rx_ia, req, RPCRDMA_HDRLEN_MIN, &rqst->rq_snd_buf, rpcrdma_noch)) @@ -271,9 +276,6 @@ void xprt_rdma_bc_free_rqst(struct rpc_rqst *rqst) * @xprt: transport receiving the call * @rep: receive buffer containing the call * - * Called in the RPC reply handler, which runs in a tasklet. - * Be quick about it. - * * Operational assumptions: * o Backchannel credits are ignored, just as the NFS server * forechannel currently does @@ -284,7 +286,6 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep) { struct rpc_xprt *xprt = &r_xprt->rx_xprt; - struct rpcrdma_msg *headerp; struct svc_serv *bc_serv; struct rpcrdma_req *req; struct rpc_rqst *rqst; @@ -292,24 +293,15 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, size_t size; __be32 *p; - headerp = rdmab_to_msg(rep->rr_rdmabuf); + p = xdr_inline_decode(&rep->rr_stream, 0); + size = xdr_stream_remaining(&rep->rr_stream); + #ifdef RPCRDMA_BACKCHANNEL_DEBUG pr_info("RPC: %s: callback XID %08x, length=%u\n", - __func__, be32_to_cpu(headerp->rm_xid), rep->rr_len); - pr_info("RPC: %s: %*ph\n", __func__, rep->rr_len, headerp); + __func__, be32_to_cpup(p), size); + pr_info("RPC: %s: %*ph\n", __func__, size, p); #endif - /* Sanity check: - * Need at least enough bytes for RPC/RDMA header, as code - * here references the header fields by array offset. Also, - * backward calls are always inline, so ensure there - * are some bytes beyond the RPC/RDMA header. - */ - if (rep->rr_len < RPCRDMA_HDRLEN_MIN + 24) - goto out_short; - p = (__be32 *)((unsigned char *)headerp + RPCRDMA_HDRLEN_MIN); - size = rep->rr_len - RPCRDMA_HDRLEN_MIN; - /* Grab a free bc rqst */ spin_lock(&xprt->bc_pa_lock); if (list_empty(&xprt->bc_pa_list)) { @@ -325,7 +317,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, /* Prepare rqst */ rqst->rq_reply_bytes_recvd = 0; rqst->rq_bytes_sent = 0; - rqst->rq_xid = headerp->rm_xid; + rqst->rq_xid = *p; rqst->rq_private_buf.len = size; set_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state); @@ -337,9 +329,9 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, buf->len = size; /* The receive buffer has to be hooked to the rpcrdma_req - * so that it can be reposted after the server is done - * parsing it but just before sending the backward - * direction reply. + * so that it is not released while the req is pointing + * to its buffer, and so that it can be reposted after + * the Upper Layer is done decoding it. */ req = rpcr_to_rdmar(rqst); dprintk("RPC: %s: attaching rep %p to req %p\n", @@ -367,13 +359,4 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, * when the connection is re-established. */ return; - -out_short: - pr_warn("RPC/RDMA short backward direction call\n"); - - if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, rep)) - xprt_disconnect_done(xprt); - else - pr_warn("RPC: %s: reposting rep %p\n", - __func__, rep); } diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c index d3f84bb1d44352b55b757dfe438f1cc830828767..6c7151341194635919e31b812223732c4436ba40 100644 --- a/net/sunrpc/xprtrdma/fmr_ops.c +++ b/net/sunrpc/xprtrdma/fmr_ops.c @@ -177,7 +177,7 @@ fmr_op_maxpages(struct rpcrdma_xprt *r_xprt) /* Use the ib_map_phys_fmr() verb to register a memory region * for remote access via RDMA READ or RDMA WRITE. */ -static int +static struct rpcrdma_mr_seg * fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, int nsegs, bool writing, struct rpcrdma_mw **out) { @@ -188,7 +188,7 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, mw = rpcrdma_get_mw(r_xprt); if (!mw) - return -ENOBUFS; + return ERR_PTR(-ENOBUFS); pageoff = offset_in_page(seg1->mr_offset); seg1->mr_offset -= pageoff; /* start of page */ @@ -232,13 +232,13 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, mw->mw_offset = dma_pages[0] + pageoff; *out = mw; - return mw->mw_nents; + return seg; out_dmamap_err: pr_err("rpcrdma: failed to DMA map sg %p sg_nents %d\n", mw->mw_sg, i); rpcrdma_put_mw(r_xprt, mw); - return -EIO; + return ERR_PTR(-EIO); out_maperr: pr_err("rpcrdma: ib_map_phys_fmr %u@0x%llx+%i (%d) status %i\n", @@ -247,7 +247,7 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, ib_dma_unmap_sg(r_xprt->rx_ia.ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir); rpcrdma_put_mw(r_xprt, mw); - return -EIO; + return ERR_PTR(-EIO); } /* Invalidate all memory regions that were registered for "req". diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 6aea36a38bfdcbf95bd617089221060138e5ecaa..df062e086bdbbda8eb9ec724754937ea42134505 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -344,7 +344,7 @@ frwr_wc_localinv_wake(struct ib_cq *cq, struct ib_wc *wc) /* Post a REG_MR Work Request to register a memory region * for remote access via RDMA READ or RDMA WRITE. */ -static int +static struct rpcrdma_mr_seg * frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, int nsegs, bool writing, struct rpcrdma_mw **out) { @@ -364,7 +364,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, rpcrdma_defer_mr_recovery(mw); mw = rpcrdma_get_mw(r_xprt); if (!mw) - return -ENOBUFS; + return ERR_PTR(-ENOBUFS); } while (mw->frmr.fr_state != FRMR_IS_INVALID); frmr = &mw->frmr; frmr->fr_state = FRMR_IS_VALID; @@ -401,7 +401,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, if (unlikely(n != mw->mw_nents)) goto out_mapmr_err; - dprintk("RPC: %s: Using frmr %p to map %u segments (%u bytes)\n", + dprintk("RPC: %s: Using frmr %p to map %u segments (%llu bytes)\n", __func__, frmr, mw->mw_nents, mr->length); key = (u8)(mr->rkey & 0x000000FF); @@ -429,25 +429,25 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, mw->mw_offset = mr->iova; *out = mw; - return mw->mw_nents; + return seg; out_dmamap_err: pr_err("rpcrdma: failed to DMA map sg %p sg_nents %d\n", mw->mw_sg, i); frmr->fr_state = FRMR_IS_INVALID; rpcrdma_put_mw(r_xprt, mw); - return -EIO; + return ERR_PTR(-EIO); out_mapmr_err: pr_err("rpcrdma: failed to map mr %p (%d/%d)\n", frmr->fr_mr, n, mw->mw_nents); rpcrdma_defer_mr_recovery(mw); - return -EIO; + return ERR_PTR(-EIO); out_senderr: pr_err("rpcrdma: FRMR registration ib_post_send returned %i\n", rc); rpcrdma_defer_mr_recovery(mw); - return -ENOTCONN; + return ERR_PTR(-ENOTCONN); } /* Invalidate all memory regions that were registered for "req". diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index ca4d6e4528f32ffa4f567f1b8c05872288d64650..f1889f4d48030f3a0a07eef6fa524bbc12580216 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -169,40 +169,41 @@ static bool rpcrdma_results_inline(struct rpcrdma_xprt *r_xprt, return rqst->rq_rcv_buf.buflen <= ia->ri_max_inline_read; } -/* Split "vec" on page boundaries into segments. FMR registers pages, - * not a byte range. Other modes coalesce these segments into a single - * MR when they can. +/* Split @vec on page boundaries into SGEs. FMR registers pages, not + * a byte range. Other modes coalesce these SGEs into a single MR + * when they can. + * + * Returns pointer to next available SGE, and bumps the total number + * of SGEs consumed. */ -static int -rpcrdma_convert_kvec(struct kvec *vec, struct rpcrdma_mr_seg *seg, int n) +static struct rpcrdma_mr_seg * +rpcrdma_convert_kvec(struct kvec *vec, struct rpcrdma_mr_seg *seg, + unsigned int *n) { - size_t page_offset; - u32 remaining; + u32 remaining, page_offset; char *base; base = vec->iov_base; page_offset = offset_in_page(base); remaining = vec->iov_len; - while (remaining && n < RPCRDMA_MAX_SEGS) { - seg[n].mr_page = NULL; - seg[n].mr_offset = base; - seg[n].mr_len = min_t(u32, PAGE_SIZE - page_offset, remaining); - remaining -= seg[n].mr_len; - base += seg[n].mr_len; - ++n; + while (remaining) { + seg->mr_page = NULL; + seg->mr_offset = base; + seg->mr_len = min_t(u32, PAGE_SIZE - page_offset, remaining); + remaining -= seg->mr_len; + base += seg->mr_len; + ++seg; + ++(*n); page_offset = 0; } - return n; + return seg; } -/* - * Chunk assembly from upper layer xdr_buf. - * - * Prepare the passed-in xdr_buf into representation as RPC/RDMA chunk - * elements. Segments are then coalesced when registered, if possible - * within the selected memreg mode. +/* Convert @xdrbuf into SGEs no larger than a page each. As they + * are registered, these SGEs are then coalesced into RDMA segments + * when the selected memreg mode supports it. * - * Returns positive number of segments converted, or a negative errno. + * Returns positive number of SGEs consumed, or a negative errno. */ static int @@ -210,47 +211,41 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf, unsigned int pos, enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg) { - int len, n, p, page_base; + unsigned long page_base; + unsigned int len, n; struct page **ppages; n = 0; - if (pos == 0) { - n = rpcrdma_convert_kvec(&xdrbuf->head[0], seg, n); - if (n == RPCRDMA_MAX_SEGS) - goto out_overflow; - } + if (pos == 0) + seg = rpcrdma_convert_kvec(&xdrbuf->head[0], seg, &n); len = xdrbuf->page_len; ppages = xdrbuf->pages + (xdrbuf->page_base >> PAGE_SHIFT); page_base = offset_in_page(xdrbuf->page_base); - p = 0; - while (len && n < RPCRDMA_MAX_SEGS) { - if (!ppages[p]) { - /* alloc the pagelist for receiving buffer */ - ppages[p] = alloc_page(GFP_ATOMIC); - if (!ppages[p]) + while (len) { + if (unlikely(!*ppages)) { + /* XXX: Certain upper layer operations do + * not provide receive buffer pages. + */ + *ppages = alloc_page(GFP_ATOMIC); + if (!*ppages) return -EAGAIN; } - seg[n].mr_page = ppages[p]; - seg[n].mr_offset = (void *)(unsigned long) page_base; - seg[n].mr_len = min_t(u32, PAGE_SIZE - page_base, len); - if (seg[n].mr_len > PAGE_SIZE) - goto out_overflow; - len -= seg[n].mr_len; + seg->mr_page = *ppages; + seg->mr_offset = (char *)page_base; + seg->mr_len = min_t(u32, PAGE_SIZE - page_base, len); + len -= seg->mr_len; + ++ppages; + ++seg; ++n; - ++p; - page_base = 0; /* page offset only applies to first page */ + page_base = 0; } - /* Message overflows the seg array */ - if (len && n == RPCRDMA_MAX_SEGS) - goto out_overflow; - /* When encoding a Read chunk, the tail iovec contains an * XDR pad and may be omitted. */ if (type == rpcrdma_readch && r_xprt->rx_ia.ri_implicit_roundup) - return n; + goto out; /* When encoding a Write chunk, some servers need to see an * extra segment for non-XDR-aligned Write chunks. The upper @@ -258,30 +253,81 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf, * for this purpose. */ if (type == rpcrdma_writech && r_xprt->rx_ia.ri_implicit_roundup) - return n; + goto out; - if (xdrbuf->tail[0].iov_len) { - n = rpcrdma_convert_kvec(&xdrbuf->tail[0], seg, n); - if (n == RPCRDMA_MAX_SEGS) - goto out_overflow; - } + if (xdrbuf->tail[0].iov_len) + seg = rpcrdma_convert_kvec(&xdrbuf->tail[0], seg, &n); +out: + if (unlikely(n > RPCRDMA_MAX_SEGS)) + return -EIO; return n; +} -out_overflow: - pr_err("rpcrdma: segment array overflow\n"); - return -EIO; +static inline int +encode_item_present(struct xdr_stream *xdr) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EMSGSIZE; + + *p = xdr_one; + return 0; } -static inline __be32 * +static inline int +encode_item_not_present(struct xdr_stream *xdr) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EMSGSIZE; + + *p = xdr_zero; + return 0; +} + +static void xdr_encode_rdma_segment(__be32 *iptr, struct rpcrdma_mw *mw) { *iptr++ = cpu_to_be32(mw->mw_handle); *iptr++ = cpu_to_be32(mw->mw_length); - return xdr_encode_hyper(iptr, mw->mw_offset); + xdr_encode_hyper(iptr, mw->mw_offset); } -/* XDR-encode the Read list. Supports encoding a list of read +static int +encode_rdma_segment(struct xdr_stream *xdr, struct rpcrdma_mw *mw) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 4 * sizeof(*p)); + if (unlikely(!p)) + return -EMSGSIZE; + + xdr_encode_rdma_segment(p, mw); + return 0; +} + +static int +encode_read_segment(struct xdr_stream *xdr, struct rpcrdma_mw *mw, + u32 position) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 6 * sizeof(*p)); + if (unlikely(!p)) + return -EMSGSIZE; + + *p++ = xdr_one; /* Item present */ + *p++ = cpu_to_be32(position); + xdr_encode_rdma_segment(p, mw); + return 0; +} + +/* Register and XDR encode the Read list. Supports encoding a list of read * segments that belong to a single read chunk. * * Encoding key for single-list chunks (HLOO = Handle32 Length32 Offset64): @@ -290,23 +336,20 @@ xdr_encode_rdma_segment(__be32 *iptr, struct rpcrdma_mw *mw) * N elements, position P (same P for all chunks of same arg!): * 1 - PHLOO - 1 - PHLOO - ... - 1 - PHLOO - 0 * - * Returns a pointer to the XDR word in the RDMA header following - * the end of the Read list, or an error pointer. + * Returns zero on success, or a negative errno if a failure occurred. + * @xdr is advanced to the next position in the stream. + * + * Only a single @pos value is currently supported. */ -static __be32 * -rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, - struct rpcrdma_req *req, struct rpc_rqst *rqst, - __be32 *iptr, enum rpcrdma_chunktype rtype) +static noinline int +rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req, + struct rpc_rqst *rqst, enum rpcrdma_chunktype rtype) { + struct xdr_stream *xdr = &req->rl_stream; struct rpcrdma_mr_seg *seg; struct rpcrdma_mw *mw; unsigned int pos; - int n, nsegs; - - if (rtype == rpcrdma_noch) { - *iptr++ = xdr_zero; /* item not present */ - return iptr; - } + int nsegs; pos = rqst->rq_snd_buf.head[0].iov_len; if (rtype == rpcrdma_areadch) @@ -315,40 +358,33 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_snd_buf, pos, rtype, seg); if (nsegs < 0) - return ERR_PTR(nsegs); + return nsegs; do { - n = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs, - false, &mw); - if (n < 0) - return ERR_PTR(n); + seg = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs, + false, &mw); + if (IS_ERR(seg)) + return PTR_ERR(seg); rpcrdma_push_mw(mw, &req->rl_registered); - *iptr++ = xdr_one; /* item present */ - - /* All read segments in this chunk - * have the same "position". - */ - *iptr++ = cpu_to_be32(pos); - iptr = xdr_encode_rdma_segment(iptr, mw); + if (encode_read_segment(xdr, mw, pos) < 0) + return -EMSGSIZE; dprintk("RPC: %5u %s: pos %u %u@0x%016llx:0x%08x (%s)\n", rqst->rq_task->tk_pid, __func__, pos, mw->mw_length, (unsigned long long)mw->mw_offset, - mw->mw_handle, n < nsegs ? "more" : "last"); + mw->mw_handle, mw->mw_nents < nsegs ? "more" : "last"); r_xprt->rx_stats.read_chunk_count++; - seg += n; - nsegs -= n; + nsegs -= mw->mw_nents; } while (nsegs); - /* Finish Read list */ - *iptr++ = xdr_zero; /* Next item not present */ - return iptr; + return 0; } -/* XDR-encode the Write list. Supports encoding a list containing - * one array of plain segments that belong to a single write chunk. +/* Register and XDR encode the Write list. Supports encoding a list + * containing one array of plain segments that belong to a single + * write chunk. * * Encoding key for single-list chunks (HLOO = Handle32 Length32 Offset64): * @@ -356,66 +392,65 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, * N elements: * 1 - N - HLOO - HLOO - ... - HLOO - 0 * - * Returns a pointer to the XDR word in the RDMA header following - * the end of the Write list, or an error pointer. + * Returns zero on success, or a negative errno if a failure occurred. + * @xdr is advanced to the next position in the stream. + * + * Only a single Write chunk is currently supported. */ -static __be32 * +static noinline int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req, - struct rpc_rqst *rqst, __be32 *iptr, - enum rpcrdma_chunktype wtype) + struct rpc_rqst *rqst, enum rpcrdma_chunktype wtype) { + struct xdr_stream *xdr = &req->rl_stream; struct rpcrdma_mr_seg *seg; struct rpcrdma_mw *mw; - int n, nsegs, nchunks; + int nsegs, nchunks; __be32 *segcount; - if (wtype != rpcrdma_writech) { - *iptr++ = xdr_zero; /* no Write list present */ - return iptr; - } - seg = req->rl_segments; nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, rqst->rq_rcv_buf.head[0].iov_len, wtype, seg); if (nsegs < 0) - return ERR_PTR(nsegs); + return nsegs; - *iptr++ = xdr_one; /* Write list present */ - segcount = iptr++; /* save location of segment count */ + if (encode_item_present(xdr) < 0) + return -EMSGSIZE; + segcount = xdr_reserve_space(xdr, sizeof(*segcount)); + if (unlikely(!segcount)) + return -EMSGSIZE; + /* Actual value encoded below */ nchunks = 0; do { - n = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs, - true, &mw); - if (n < 0) - return ERR_PTR(n); + seg = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs, + true, &mw); + if (IS_ERR(seg)) + return PTR_ERR(seg); rpcrdma_push_mw(mw, &req->rl_registered); - iptr = xdr_encode_rdma_segment(iptr, mw); + if (encode_rdma_segment(xdr, mw) < 0) + return -EMSGSIZE; dprintk("RPC: %5u %s: %u@0x016%llx:0x%08x (%s)\n", rqst->rq_task->tk_pid, __func__, mw->mw_length, (unsigned long long)mw->mw_offset, - mw->mw_handle, n < nsegs ? "more" : "last"); + mw->mw_handle, mw->mw_nents < nsegs ? "more" : "last"); r_xprt->rx_stats.write_chunk_count++; r_xprt->rx_stats.total_rdma_request += seg->mr_len; nchunks++; - seg += n; - nsegs -= n; + nsegs -= mw->mw_nents; } while (nsegs); /* Update count of segments in this Write chunk */ *segcount = cpu_to_be32(nchunks); - /* Finish Write list */ - *iptr++ = xdr_zero; /* Next item not present */ - return iptr; + return 0; } -/* XDR-encode the Reply chunk. Supports encoding an array of plain - * segments that belong to a single write (reply) chunk. +/* Register and XDR encode the Reply chunk. Supports encoding an array + * of plain segments that belong to a single write (reply) chunk. * * Encoding key for single-list chunks (HLOO = Handle32 Length32 Offset64): * @@ -423,58 +458,57 @@ rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req, * N elements: * 1 - N - HLOO - HLOO - ... - HLOO * - * Returns a pointer to the XDR word in the RDMA header following - * the end of the Reply chunk, or an error pointer. + * Returns zero on success, or a negative errno if a failure occurred. + * @xdr is advanced to the next position in the stream. */ -static __be32 * -rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, - struct rpcrdma_req *req, struct rpc_rqst *rqst, - __be32 *iptr, enum rpcrdma_chunktype wtype) +static noinline int +rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req, + struct rpc_rqst *rqst, enum rpcrdma_chunktype wtype) { + struct xdr_stream *xdr = &req->rl_stream; struct rpcrdma_mr_seg *seg; struct rpcrdma_mw *mw; - int n, nsegs, nchunks; + int nsegs, nchunks; __be32 *segcount; - if (wtype != rpcrdma_replych) { - *iptr++ = xdr_zero; /* no Reply chunk present */ - return iptr; - } - seg = req->rl_segments; nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, 0, wtype, seg); if (nsegs < 0) - return ERR_PTR(nsegs); + return nsegs; - *iptr++ = xdr_one; /* Reply chunk present */ - segcount = iptr++; /* save location of segment count */ + if (encode_item_present(xdr) < 0) + return -EMSGSIZE; + segcount = xdr_reserve_space(xdr, sizeof(*segcount)); + if (unlikely(!segcount)) + return -EMSGSIZE; + /* Actual value encoded below */ nchunks = 0; do { - n = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs, - true, &mw); - if (n < 0) - return ERR_PTR(n); + seg = r_xprt->rx_ia.ri_ops->ro_map(r_xprt, seg, nsegs, + true, &mw); + if (IS_ERR(seg)) + return PTR_ERR(seg); rpcrdma_push_mw(mw, &req->rl_registered); - iptr = xdr_encode_rdma_segment(iptr, mw); + if (encode_rdma_segment(xdr, mw) < 0) + return -EMSGSIZE; dprintk("RPC: %5u %s: %u@0x%016llx:0x%08x (%s)\n", rqst->rq_task->tk_pid, __func__, mw->mw_length, (unsigned long long)mw->mw_offset, - mw->mw_handle, n < nsegs ? "more" : "last"); + mw->mw_handle, mw->mw_nents < nsegs ? "more" : "last"); r_xprt->rx_stats.reply_chunk_count++; r_xprt->rx_stats.total_rdma_request += seg->mr_len; nchunks++; - seg += n; - nsegs -= n; + nsegs -= mw->mw_nents; } while (nsegs); /* Update count of segments in the Reply chunk */ *segcount = cpu_to_be32(nchunks); - return iptr; + return 0; } /* Prepare the RPC-over-RDMA header SGE. @@ -651,37 +685,52 @@ rpcrdma_unmap_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req) req->rl_mapped_sges = 0; } -/* - * Marshal a request: the primary job of this routine is to choose - * the transfer modes. See comments below. +/** + * rpcrdma_marshal_req - Marshal and send one RPC request + * @r_xprt: controlling transport + * @rqst: RPC request to be marshaled + * + * For the RPC in "rqst", this function: + * - Chooses the transfer mode (eg., RDMA_MSG or RDMA_NOMSG) + * - Registers Read, Write, and Reply chunks + * - Constructs the transport header + * - Posts a Send WR to send the transport header and request * - * Returns zero on success, otherwise a negative errno. + * Returns: + * %0 if the RPC was sent successfully, + * %-ENOTCONN if the connection was lost, + * %-EAGAIN if not enough pages are available for on-demand reply buffer, + * %-ENOBUFS if no MRs are available to register chunks, + * %-EMSGSIZE if the transport header is too small, + * %-EIO if a permanent problem occurred while marshaling. */ - int -rpcrdma_marshal_req(struct rpc_rqst *rqst) +rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst) { - struct rpc_xprt *xprt = rqst->rq_xprt; - struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); struct rpcrdma_req *req = rpcr_to_rdmar(rqst); + struct xdr_stream *xdr = &req->rl_stream; enum rpcrdma_chunktype rtype, wtype; - struct rpcrdma_msg *headerp; bool ddp_allowed; - ssize_t hdrlen; - size_t rpclen; - __be32 *iptr; + __be32 *p; + int ret; #if defined(CONFIG_SUNRPC_BACKCHANNEL) if (test_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state)) return rpcrdma_bc_marshal_reply(rqst); #endif - headerp = rdmab_to_msg(req->rl_rdmabuf); - /* don't byte-swap XID, it's already done in request */ - headerp->rm_xid = rqst->rq_xid; - headerp->rm_vers = rpcrdma_version; - headerp->rm_credit = cpu_to_be32(r_xprt->rx_buf.rb_max_requests); - headerp->rm_type = rdma_msg; + rpcrdma_set_xdrlen(&req->rl_hdrbuf, 0); + xdr_init_encode(xdr, &req->rl_hdrbuf, + req->rl_rdmabuf->rg_base); + + /* Fixed header fields */ + ret = -EMSGSIZE; + p = xdr_reserve_space(xdr, 4 * sizeof(*p)); + if (!p) + goto out_err; + *p++ = rqst->rq_xid; + *p++ = rpcrdma_version; + *p++ = cpu_to_be32(r_xprt->rx_buf.rb_max_requests); /* When the ULP employs a GSS flavor that guarantees integrity * or privacy, direct data placement of individual data items @@ -721,22 +770,17 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst) * by themselves are larger than the inline threshold. */ if (rpcrdma_args_inline(r_xprt, rqst)) { + *p++ = rdma_msg; rtype = rpcrdma_noch; - rpclen = rqst->rq_snd_buf.len; } else if (ddp_allowed && rqst->rq_snd_buf.flags & XDRBUF_WRITE) { + *p++ = rdma_msg; rtype = rpcrdma_readch; - rpclen = rqst->rq_snd_buf.head[0].iov_len + - rqst->rq_snd_buf.tail[0].iov_len; } else { r_xprt->rx_stats.nomsg_call_count++; - headerp->rm_type = htonl(RDMA_NOMSG); + *p++ = rdma_nomsg; rtype = rpcrdma_areadch; - rpclen = 0; } - req->rl_xid = rqst->rq_xid; - rpcrdma_insert_req(&r_xprt->rx_buf, req); - /* This implementation supports the following combinations * of chunk lists in one RPC-over-RDMA Call message: * @@ -759,79 +803,50 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst) * send a Call message with a Position Zero Read chunk and a * regular Read chunk at the same time. */ - iptr = headerp->rm_body.rm_chunks; - iptr = rpcrdma_encode_read_list(r_xprt, req, rqst, iptr, rtype); - if (IS_ERR(iptr)) + if (rtype != rpcrdma_noch) { + ret = rpcrdma_encode_read_list(r_xprt, req, rqst, rtype); + if (ret) + goto out_err; + } + ret = encode_item_not_present(xdr); + if (ret) goto out_err; - iptr = rpcrdma_encode_write_list(r_xprt, req, rqst, iptr, wtype); - if (IS_ERR(iptr)) + + if (wtype == rpcrdma_writech) { + ret = rpcrdma_encode_write_list(r_xprt, req, rqst, wtype); + if (ret) + goto out_err; + } + ret = encode_item_not_present(xdr); + if (ret) goto out_err; - iptr = rpcrdma_encode_reply_chunk(r_xprt, req, rqst, iptr, wtype); - if (IS_ERR(iptr)) + + if (wtype != rpcrdma_replych) + ret = encode_item_not_present(xdr); + else + ret = rpcrdma_encode_reply_chunk(r_xprt, req, rqst, wtype); + if (ret) goto out_err; - hdrlen = (unsigned char *)iptr - (unsigned char *)headerp; - dprintk("RPC: %5u %s: %s/%s: hdrlen %zd rpclen %zd\n", + dprintk("RPC: %5u %s: %s/%s: hdrlen %u rpclen\n", rqst->rq_task->tk_pid, __func__, transfertypes[rtype], transfertypes[wtype], - hdrlen, rpclen); + xdr_stream_pos(xdr)); - if (!rpcrdma_prepare_send_sges(&r_xprt->rx_ia, req, hdrlen, + if (!rpcrdma_prepare_send_sges(&r_xprt->rx_ia, req, + xdr_stream_pos(xdr), &rqst->rq_snd_buf, rtype)) { - iptr = ERR_PTR(-EIO); + ret = -EIO; goto out_err; } return 0; out_err: - if (PTR_ERR(iptr) != -ENOBUFS) { - pr_err("rpcrdma: rpcrdma_marshal_req failed, status %ld\n", - PTR_ERR(iptr)); + if (ret != -ENOBUFS) { + pr_err("rpcrdma: header marshaling failed (%d)\n", ret); r_xprt->rx_stats.failed_marshal_count++; } - return PTR_ERR(iptr); -} - -/* - * Chase down a received write or reply chunklist to get length - * RDMA'd by server. See map at rpcrdma_create_chunks()! :-) - */ -static int -rpcrdma_count_chunks(struct rpcrdma_rep *rep, int wrchunk, __be32 **iptrp) -{ - unsigned int i, total_len; - struct rpcrdma_write_chunk *cur_wchunk; - char *base = (char *)rdmab_to_msg(rep->rr_rdmabuf); - - i = be32_to_cpu(**iptrp); - cur_wchunk = (struct rpcrdma_write_chunk *) (*iptrp + 1); - total_len = 0; - while (i--) { - struct rpcrdma_segment *seg = &cur_wchunk->wc_target; - ifdebug(FACILITY) { - u64 off; - xdr_decode_hyper((__be32 *)&seg->rs_offset, &off); - dprintk("RPC: %s: chunk %d@0x%016llx:0x%08x\n", - __func__, - be32_to_cpu(seg->rs_length), - (unsigned long long)off, - be32_to_cpu(seg->rs_handle)); - } - total_len += be32_to_cpu(seg->rs_length); - ++cur_wchunk; - } - /* check and adjust for properly terminated write chunk */ - if (wrchunk) { - __be32 *w = (__be32 *) cur_wchunk; - if (*w++ != xdr_zero) - return -1; - cur_wchunk = (struct rpcrdma_write_chunk *) w; - } - if ((char *)cur_wchunk > base + rep->rr_len) - return -1; - - *iptrp = (__be32 *) cur_wchunk; - return total_len; + return ret; } /** @@ -949,37 +964,254 @@ rpcrdma_mark_remote_invalidation(struct list_head *mws, } } -#if defined(CONFIG_SUNRPC_BACKCHANNEL) /* By convention, backchannel calls arrive via rdma_msg type * messages, and never populate the chunk lists. This makes * the RPC/RDMA header small and fixed in size, so it is * straightforward to check the RPC header's direction field. */ static bool -rpcrdma_is_bcall(struct rpcrdma_msg *headerp) +rpcrdma_is_bcall(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep, + __be32 xid, __be32 proc) +#if defined(CONFIG_SUNRPC_BACKCHANNEL) { - __be32 *p = (__be32 *)headerp; + struct xdr_stream *xdr = &rep->rr_stream; + __be32 *p; - if (headerp->rm_type != rdma_msg) + if (proc != rdma_msg) return false; - if (headerp->rm_body.rm_chunks[0] != xdr_zero) + + /* Peek at stream contents without advancing. */ + p = xdr_inline_decode(xdr, 0); + + /* Chunk lists */ + if (*p++ != xdr_zero) return false; - if (headerp->rm_body.rm_chunks[1] != xdr_zero) + if (*p++ != xdr_zero) return false; - if (headerp->rm_body.rm_chunks[2] != xdr_zero) + if (*p++ != xdr_zero) return false; - /* sanity */ - if (p[7] != headerp->rm_xid) + /* RPC header */ + if (*p++ != xid) return false; - /* call direction */ - if (p[8] != cpu_to_be32(RPC_CALL)) + if (*p != cpu_to_be32(RPC_CALL)) return false; + /* Now that we are sure this is a backchannel call, + * advance to the RPC header. + */ + p = xdr_inline_decode(xdr, 3 * sizeof(*p)); + if (unlikely(!p)) + goto out_short; + + rpcrdma_bc_receive_call(r_xprt, rep); + return true; + +out_short: + pr_warn("RPC/RDMA short backward direction call\n"); + if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, rep)) + xprt_disconnect_done(&r_xprt->rx_xprt); return true; } +#else /* CONFIG_SUNRPC_BACKCHANNEL */ +{ + return false; +} #endif /* CONFIG_SUNRPC_BACKCHANNEL */ +static int decode_rdma_segment(struct xdr_stream *xdr, u32 *length) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4 * sizeof(*p)); + if (unlikely(!p)) + return -EIO; + + ifdebug(FACILITY) { + u64 offset; + u32 handle; + + handle = be32_to_cpup(p++); + *length = be32_to_cpup(p++); + xdr_decode_hyper(p, &offset); + dprintk("RPC: %s: segment %u@0x%016llx:0x%08x\n", + __func__, *length, (unsigned long long)offset, + handle); + } else { + *length = be32_to_cpup(p + 1); + } + + return 0; +} + +static int decode_write_chunk(struct xdr_stream *xdr, u32 *length) +{ + u32 segcount, seglength; + __be32 *p; + + p = xdr_inline_decode(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EIO; + + *length = 0; + segcount = be32_to_cpup(p); + while (segcount--) { + if (decode_rdma_segment(xdr, &seglength)) + return -EIO; + *length += seglength; + } + + dprintk("RPC: %s: segcount=%u, %u bytes\n", + __func__, be32_to_cpup(p), *length); + return 0; +} + +/* In RPC-over-RDMA Version One replies, a Read list is never + * expected. This decoder is a stub that returns an error if + * a Read list is present. + */ +static int decode_read_list(struct xdr_stream *xdr) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EIO; + if (unlikely(*p != xdr_zero)) + return -EIO; + return 0; +} + +/* Supports only one Write chunk in the Write list + */ +static int decode_write_list(struct xdr_stream *xdr, u32 *length) +{ + u32 chunklen; + bool first; + __be32 *p; + + *length = 0; + first = true; + do { + p = xdr_inline_decode(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EIO; + if (*p == xdr_zero) + break; + if (!first) + return -EIO; + + if (decode_write_chunk(xdr, &chunklen)) + return -EIO; + *length += chunklen; + first = false; + } while (true); + return 0; +} + +static int decode_reply_chunk(struct xdr_stream *xdr, u32 *length) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EIO; + + *length = 0; + if (*p != xdr_zero) + if (decode_write_chunk(xdr, length)) + return -EIO; + return 0; +} + +static int +rpcrdma_decode_msg(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep, + struct rpc_rqst *rqst) +{ + struct xdr_stream *xdr = &rep->rr_stream; + u32 writelist, replychunk, rpclen; + char *base; + + /* Decode the chunk lists */ + if (decode_read_list(xdr)) + return -EIO; + if (decode_write_list(xdr, &writelist)) + return -EIO; + if (decode_reply_chunk(xdr, &replychunk)) + return -EIO; + + /* RDMA_MSG sanity checks */ + if (unlikely(replychunk)) + return -EIO; + + /* Build the RPC reply's Payload stream in rqst->rq_rcv_buf */ + base = (char *)xdr_inline_decode(xdr, 0); + rpclen = xdr_stream_remaining(xdr); + r_xprt->rx_stats.fixup_copy_count += + rpcrdma_inline_fixup(rqst, base, rpclen, writelist & 3); + + r_xprt->rx_stats.total_rdma_reply += writelist; + return rpclen + xdr_align_size(writelist); +} + +static noinline int +rpcrdma_decode_nomsg(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep) +{ + struct xdr_stream *xdr = &rep->rr_stream; + u32 writelist, replychunk; + + /* Decode the chunk lists */ + if (decode_read_list(xdr)) + return -EIO; + if (decode_write_list(xdr, &writelist)) + return -EIO; + if (decode_reply_chunk(xdr, &replychunk)) + return -EIO; + + /* RDMA_NOMSG sanity checks */ + if (unlikely(writelist)) + return -EIO; + if (unlikely(!replychunk)) + return -EIO; + + /* Reply chunk buffer already is the reply vector */ + r_xprt->rx_stats.total_rdma_reply += replychunk; + return replychunk; +} + +static noinline int +rpcrdma_decode_error(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep, + struct rpc_rqst *rqst) +{ + struct xdr_stream *xdr = &rep->rr_stream; + __be32 *p; + + p = xdr_inline_decode(xdr, sizeof(*p)); + if (unlikely(!p)) + return -EIO; + + switch (*p) { + case err_vers: + p = xdr_inline_decode(xdr, 2 * sizeof(*p)); + if (!p) + break; + dprintk("RPC: %5u: %s: server reports version error (%u-%u)\n", + rqst->rq_task->tk_pid, __func__, + be32_to_cpup(p), be32_to_cpu(*(p + 1))); + break; + case err_chunk: + dprintk("RPC: %5u: %s: server reports header decoding error\n", + rqst->rq_task->tk_pid, __func__); + break; + default: + dprintk("RPC: %5u: %s: server reports unrecognized error %d\n", + rqst->rq_task->tk_pid, __func__, be32_to_cpup(p)); + } + + r_xprt->rx_stats.bad_reply_count++; + return -EREMOTEIO; +} + /* Process received RPC/RDMA messages. * * Errors must result in the RPC task either being awakened, or @@ -991,51 +1223,48 @@ rpcrdma_reply_handler(struct work_struct *work) struct rpcrdma_rep *rep = container_of(work, struct rpcrdma_rep, rr_work); struct rpcrdma_xprt *r_xprt = rep->rr_rxprt; - struct rpcrdma_buffer *buf = &r_xprt->rx_buf; struct rpc_xprt *xprt = &r_xprt->rx_xprt; - struct rpcrdma_msg *headerp; + struct xdr_stream *xdr = &rep->rr_stream; struct rpcrdma_req *req; struct rpc_rqst *rqst; - __be32 *iptr; - int rdmalen, status, rmerr; + __be32 *p, xid, vers, proc; unsigned long cwnd; - struct list_head mws; + int status; dprintk("RPC: %s: incoming rep %p\n", __func__, rep); - if (rep->rr_len == RPCRDMA_BAD_LEN) + if (rep->rr_hdrbuf.head[0].iov_len == 0) goto out_badstatus; - if (rep->rr_len < RPCRDMA_HDRLEN_ERR) + + xdr_init_decode(xdr, &rep->rr_hdrbuf, + rep->rr_hdrbuf.head[0].iov_base); + + /* Fixed transport header fields */ + p = xdr_inline_decode(xdr, 4 * sizeof(*p)); + if (unlikely(!p)) goto out_shortreply; + xid = *p++; + vers = *p++; + p++; /* credits */ + proc = *p++; - headerp = rdmab_to_msg(rep->rr_rdmabuf); -#if defined(CONFIG_SUNRPC_BACKCHANNEL) - if (rpcrdma_is_bcall(headerp)) - goto out_bcall; -#endif + if (rpcrdma_is_bcall(r_xprt, rep, xid, proc)) + return; /* Match incoming rpcrdma_rep to an rpcrdma_req to * get context for handling any incoming chunks. */ - spin_lock(&buf->rb_lock); - req = rpcrdma_lookup_req_locked(&r_xprt->rx_buf, - headerp->rm_xid); - if (!req) - goto out_nomatch; - if (req->rl_reply) - goto out_duplicate; - - list_replace_init(&req->rl_registered, &mws); - rpcrdma_mark_remote_invalidation(&mws, rep); - - /* Avoid races with signals and duplicate replies - * by marking this req as matched. - */ + spin_lock(&xprt->recv_lock); + rqst = xprt_lookup_rqst(xprt, xid); + if (!rqst) + goto out_norqst; + xprt_pin_rqst(rqst); + spin_unlock(&xprt->recv_lock); + req = rpcr_to_rdmar(rqst); req->rl_reply = rep; - spin_unlock(&buf->rb_lock); dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n", - __func__, rep, req, be32_to_cpu(headerp->rm_xid)); + __func__, rep, req, be32_to_cpu(xid)); /* Invalidate and unmap the data payloads before waking the * waiting application. This guarantees the memory regions @@ -1044,99 +1273,42 @@ rpcrdma_reply_handler(struct work_struct *work) * waking the next RPC waits until this RPC has relinquished * all its Send Queue entries. */ - if (!list_empty(&mws)) - r_xprt->rx_ia.ri_ops->ro_unmap_sync(r_xprt, &mws); + if (!list_empty(&req->rl_registered)) { + rpcrdma_mark_remote_invalidation(&req->rl_registered, rep); + r_xprt->rx_ia.ri_ops->ro_unmap_sync(r_xprt, + &req->rl_registered); + } - /* Perform XID lookup, reconstruction of the RPC reply, and - * RPC completion while holding the transport lock to ensure - * the rep, rqst, and rq_task pointers remain stable. - */ - spin_lock_bh(&xprt->transport_lock); - rqst = xprt_lookup_rqst(xprt, headerp->rm_xid); - if (!rqst) - goto out_norqst; xprt->reestablish_timeout = 0; - if (headerp->rm_vers != rpcrdma_version) + if (vers != rpcrdma_version) goto out_badversion; - /* check for expected message types */ - /* The order of some of these tests is important. */ - switch (headerp->rm_type) { + switch (proc) { case rdma_msg: - /* never expect read chunks */ - /* never expect reply chunks (two ways to check) */ - if (headerp->rm_body.rm_chunks[0] != xdr_zero || - (headerp->rm_body.rm_chunks[1] == xdr_zero && - headerp->rm_body.rm_chunks[2] != xdr_zero)) - goto badheader; - if (headerp->rm_body.rm_chunks[1] != xdr_zero) { - /* count any expected write chunks in read reply */ - /* start at write chunk array count */ - iptr = &headerp->rm_body.rm_chunks[2]; - rdmalen = rpcrdma_count_chunks(rep, 1, &iptr); - /* check for validity, and no reply chunk after */ - if (rdmalen < 0 || *iptr++ != xdr_zero) - goto badheader; - rep->rr_len -= - ((unsigned char *)iptr - (unsigned char *)headerp); - status = rep->rr_len + rdmalen; - r_xprt->rx_stats.total_rdma_reply += rdmalen; - /* special case - last chunk may omit padding */ - if (rdmalen &= 3) { - rdmalen = 4 - rdmalen; - status += rdmalen; - } - } else { - /* else ordinary inline */ - rdmalen = 0; - iptr = (__be32 *)((unsigned char *)headerp + - RPCRDMA_HDRLEN_MIN); - rep->rr_len -= RPCRDMA_HDRLEN_MIN; - status = rep->rr_len; - } - - r_xprt->rx_stats.fixup_copy_count += - rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len, - rdmalen); + status = rpcrdma_decode_msg(r_xprt, rep, rqst); break; - case rdma_nomsg: - /* never expect read or write chunks, always reply chunks */ - if (headerp->rm_body.rm_chunks[0] != xdr_zero || - headerp->rm_body.rm_chunks[1] != xdr_zero || - headerp->rm_body.rm_chunks[2] != xdr_one) - goto badheader; - iptr = (__be32 *)((unsigned char *)headerp + - RPCRDMA_HDRLEN_MIN); - rdmalen = rpcrdma_count_chunks(rep, 0, &iptr); - if (rdmalen < 0) - goto badheader; - r_xprt->rx_stats.total_rdma_reply += rdmalen; - /* Reply chunk buffer already is the reply vector - no fixup. */ - status = rdmalen; + status = rpcrdma_decode_nomsg(r_xprt, rep); break; - case rdma_error: - goto out_rdmaerr; - -badheader: + status = rpcrdma_decode_error(r_xprt, rep, rqst); + break; default: - dprintk("RPC: %5u %s: invalid rpcrdma reply (type %u)\n", - rqst->rq_task->tk_pid, __func__, - be32_to_cpu(headerp->rm_type)); status = -EIO; - r_xprt->rx_stats.bad_reply_count++; - break; } + if (status < 0) + goto out_badheader; out: + spin_lock(&xprt->recv_lock); cwnd = xprt->cwnd; xprt->cwnd = atomic_read(&r_xprt->rx_buf.rb_credits) << RPC_CWNDSHIFT; if (xprt->cwnd > cwnd) xprt_release_rqst_cong(rqst->rq_task); xprt_complete_rqst(rqst->rq_task, status); - spin_unlock_bh(&xprt->transport_lock); + xprt_unpin_rqst(rqst); + spin_unlock(&xprt->recv_lock); dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n", __func__, xprt, rqst, status); return; @@ -1149,72 +1321,38 @@ rpcrdma_reply_handler(struct work_struct *work) } return; -#if defined(CONFIG_SUNRPC_BACKCHANNEL) -out_bcall: - rpcrdma_bc_receive_call(r_xprt, rep); - return; -#endif - /* If the incoming reply terminated a pending RPC, the next * RPC call will post a replacement receive buffer as it is * being marshaled. */ out_badversion: dprintk("RPC: %s: invalid version %d\n", - __func__, be32_to_cpu(headerp->rm_vers)); + __func__, be32_to_cpu(vers)); status = -EIO; r_xprt->rx_stats.bad_reply_count++; goto out; -out_rdmaerr: - rmerr = be32_to_cpu(headerp->rm_body.rm_error.rm_err); - switch (rmerr) { - case ERR_VERS: - pr_err("%s: server reports header version error (%u-%u)\n", - __func__, - be32_to_cpu(headerp->rm_body.rm_error.rm_vers_low), - be32_to_cpu(headerp->rm_body.rm_error.rm_vers_high)); - break; - case ERR_CHUNK: - pr_err("%s: server reports header decoding error\n", - __func__); - break; - default: - pr_err("%s: server reports unknown error %d\n", - __func__, rmerr); - } - status = -EREMOTEIO; +out_badheader: + dprintk("RPC: %5u %s: invalid rpcrdma reply (type %u)\n", + rqst->rq_task->tk_pid, __func__, be32_to_cpu(proc)); r_xprt->rx_stats.bad_reply_count++; + status = -EIO; goto out; -/* The req was still available, but by the time the transport_lock +/* The req was still available, but by the time the recv_lock * was acquired, the rqst and task had been released. Thus the RPC * has already been terminated. */ out_norqst: - spin_unlock_bh(&xprt->transport_lock); - rpcrdma_buffer_put(req); - dprintk("RPC: %s: race, no rqst left for req %p\n", - __func__, req); - return; + spin_unlock(&xprt->recv_lock); + dprintk("RPC: %s: no match for incoming xid 0x%08x\n", + __func__, be32_to_cpu(xid)); + goto repost; out_shortreply: dprintk("RPC: %s: short/invalid reply\n", __func__); goto repost; -out_nomatch: - spin_unlock(&buf->rb_lock); - dprintk("RPC: %s: no match for incoming xid 0x%08x len %d\n", - __func__, be32_to_cpu(headerp->rm_xid), - rep->rr_len); - goto repost; - -out_duplicate: - spin_unlock(&buf->rb_lock); - dprintk("RPC: %s: " - "duplicate reply %p to RPC request %p: xid 0x%08x\n", - __func__, rep, req, be32_to_cpu(headerp->rm_xid)); - /* If no pending RPC transaction was matched, post a replacement * receive buffer before returning. */ diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c index c676ed0efb5af2cceb6ed59e238a0f7a0109f916..ec37ad83b068a5067ca6e76585ab817335c51768 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c @@ -52,7 +52,7 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, if (src->iov_len < 24) goto out_shortreply; - spin_lock_bh(&xprt->transport_lock); + spin_lock(&xprt->recv_lock); req = xprt_lookup_rqst(xprt, xid); if (!req) goto out_notfound; @@ -69,17 +69,20 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, else if (credits > r_xprt->rx_buf.rb_bc_max_requests) credits = r_xprt->rx_buf.rb_bc_max_requests; + spin_lock_bh(&xprt->transport_lock); cwnd = xprt->cwnd; xprt->cwnd = credits << RPC_CWNDSHIFT; if (xprt->cwnd > cwnd) xprt_release_rqst_cong(req->rq_task); + spin_unlock_bh(&xprt->transport_lock); + ret = 0; xprt_complete_rqst(req->rq_task, rcvbuf->len); rcvbuf->len = 0; out_unlock: - spin_unlock_bh(&xprt->transport_lock); + spin_unlock(&xprt->recv_lock); out: return ret; @@ -266,7 +269,7 @@ xprt_rdma_bc_put(struct rpc_xprt *xprt) module_put(THIS_MODULE); } -static struct rpc_xprt_ops xprt_rdma_bc_procs = { +static const struct rpc_xprt_ops xprt_rdma_bc_procs = { .reserve_xprt = xprt_reserve_xprt_cong, .release_xprt = xprt_release_xprt_cong, .alloc_slot = xprt_alloc_slot, diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 933f79bed27089e755053ca71bc77bbd3cdb2806..7dcda4597057373c3ae17b426e487c47c6c2c2c0 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -660,19 +660,21 @@ static int svc_rdma_build_read_segment(struct svc_rdma_read_info *info, return -EIO; } +/* Walk the segments in the Read chunk starting at @p and construct + * RDMA Read operations to pull the chunk to the server. + */ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, struct svc_rdma_read_info *info, __be32 *p) { int ret; + ret = -EINVAL; info->ri_chunklen = 0; - while (*p++ != xdr_zero) { + while (*p++ != xdr_zero && be32_to_cpup(p++) == info->ri_position) { u32 rs_handle, rs_length; u64 rs_offset; - if (be32_to_cpup(p++) != info->ri_position) - break; rs_handle = be32_to_cpup(p++); rs_length = be32_to_cpup(p++); p = xdr_decode_hyper(p, &rs_offset); @@ -689,78 +691,6 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, return ret; } -/* If there is inline content following the Read chunk, append it to - * the page list immediately following the data payload. This has to - * be done after the reader function has determined how many pages - * were consumed for RDMA Read. - * - * On entry, ri_pageno and ri_pageoff point directly to the end of the - * page list. On exit, both have been updated to the new "next byte". - * - * Assumptions: - * - Inline content fits entirely in rq_pages[0] - * - Trailing content is only a handful of bytes - */ -static int svc_rdma_copy_tail(struct svc_rqst *rqstp, - struct svc_rdma_read_info *info) -{ - struct svc_rdma_op_ctxt *head = info->ri_readctxt; - unsigned int tail_length, remaining; - u8 *srcp, *destp; - - /* Assert that all inline content fits in page 0. This is an - * implementation limit, not a protocol limit. - */ - if (head->arg.head[0].iov_len > PAGE_SIZE) { - pr_warn_once("svcrdma: too much trailing inline content\n"); - return -EINVAL; - } - - srcp = head->arg.head[0].iov_base; - srcp += info->ri_position; - tail_length = head->arg.head[0].iov_len - info->ri_position; - remaining = tail_length; - - /* If there is room on the last page in the page list, try to - * fit the trailing content there. - */ - if (info->ri_pageoff > 0) { - unsigned int len; - - len = min_t(unsigned int, remaining, - PAGE_SIZE - info->ri_pageoff); - destp = page_address(rqstp->rq_pages[info->ri_pageno]); - destp += info->ri_pageoff; - - memcpy(destp, srcp, len); - srcp += len; - destp += len; - info->ri_pageoff += len; - remaining -= len; - - if (info->ri_pageoff == PAGE_SIZE) { - info->ri_pageno++; - info->ri_pageoff = 0; - } - } - - /* Otherwise, a fresh page is needed. */ - if (remaining) { - head->arg.pages[info->ri_pageno] = - rqstp->rq_pages[info->ri_pageno]; - head->count++; - - destp = page_address(rqstp->rq_pages[info->ri_pageno]); - memcpy(destp, srcp, remaining); - info->ri_pageoff += remaining; - } - - head->arg.page_len += tail_length; - head->arg.len += tail_length; - head->arg.buflen += tail_length; - return 0; -} - /* Construct RDMA Reads to pull over a normal Read chunk. The chunk * data lands in the page list of head->arg.pages. * @@ -785,34 +715,28 @@ static int svc_rdma_build_normal_read_chunk(struct svc_rqst *rqstp, if (ret < 0) goto out; - /* Read chunk may need XDR round-up (see RFC 5666, s. 3.7). + /* Split the Receive buffer between the head and tail + * buffers at Read chunk's position. XDR roundup of the + * chunk is not included in either the pagelist or in + * the tail. */ - if (info->ri_chunklen & 3) { - u32 padlen = 4 - (info->ri_chunklen & 3); - - info->ri_chunklen += padlen; + head->arg.tail[0].iov_base = + head->arg.head[0].iov_base + info->ri_position; + head->arg.tail[0].iov_len = + head->arg.head[0].iov_len - info->ri_position; + head->arg.head[0].iov_len = info->ri_position; - /* NB: data payload always starts on XDR alignment, - * thus the pad can never contain a page boundary. - */ - info->ri_pageoff += padlen; - if (info->ri_pageoff == PAGE_SIZE) { - info->ri_pageno++; - info->ri_pageoff = 0; - } - } + /* Read chunk may need XDR roundup (see RFC 5666, s. 3.7). + * + * NFSv2/3 write decoders need the length of the tail to + * contain the size of the roundup padding. + */ + head->arg.tail[0].iov_len += 4 - (info->ri_chunklen & 3); head->arg.page_len = info->ri_chunklen; head->arg.len += info->ri_chunklen; head->arg.buflen += info->ri_chunklen; - if (info->ri_position < head->arg.head[0].iov_len) { - ret = svc_rdma_copy_tail(rqstp, info); - if (ret < 0) - goto out; - } - head->arg.head[0].iov_len = info->ri_position; - out: return ret; } diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index e660d4965b18aa2b40af11576405d4d14c283d9d..5caf8e722a118659f8b9e8c3531f60a8e738158b 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include "xprt_rdma.h" @@ -70,7 +71,7 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt); static int svc_rdma_secure_port(struct svc_rqst *); static void svc_rdma_kill_temp_xprt(struct svc_xprt *); -static struct svc_xprt_ops svc_rdma_ops = { +static const struct svc_xprt_ops svc_rdma_ops = { .xpo_create = svc_rdma_create, .xpo_recvfrom = svc_rdma_recvfrom, .xpo_sendto = svc_rdma_sendto, @@ -98,7 +99,7 @@ static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *, struct net *, static void svc_rdma_bc_detach(struct svc_xprt *); static void svc_rdma_bc_free(struct svc_xprt *); -static struct svc_xprt_ops svc_rdma_bc_ops = { +static const struct svc_xprt_ops svc_rdma_bc_ops = { .xpo_create = svc_rdma_bc_create, .xpo_detach = svc_rdma_bc_detach, .xpo_free = svc_rdma_bc_free, @@ -167,8 +168,8 @@ static bool svc_rdma_prealloc_ctxts(struct svcxprt_rdma *xprt) { unsigned int i; - /* Each RPC/RDMA credit can consume a number of send - * and receive WQEs. One ctxt is allocated for each. + /* Each RPC/RDMA credit can consume one Receive and + * one Send WQE at the same time. */ i = xprt->sc_sq_depth + xprt->sc_rq_depth; @@ -713,7 +714,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) struct ib_qp_init_attr qp_attr; struct ib_device *dev; struct sockaddr *sap; - unsigned int i; + unsigned int i, ctxts; int ret = 0; listen_rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt); @@ -742,14 +743,26 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) newxprt->sc_max_sge = min((size_t)dev->attrs.max_sge, (size_t)RPCSVC_MAXPAGES); newxprt->sc_max_req_size = svcrdma_max_req_size; - newxprt->sc_max_requests = min_t(u32, dev->attrs.max_qp_wr, - svcrdma_max_requests); - newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests); - newxprt->sc_max_bc_requests = min_t(u32, dev->attrs.max_qp_wr, - svcrdma_max_bc_requests); + newxprt->sc_max_requests = svcrdma_max_requests; + newxprt->sc_max_bc_requests = svcrdma_max_bc_requests; newxprt->sc_rq_depth = newxprt->sc_max_requests + newxprt->sc_max_bc_requests; - newxprt->sc_sq_depth = newxprt->sc_rq_depth; + if (newxprt->sc_rq_depth > dev->attrs.max_qp_wr) { + pr_warn("svcrdma: reducing receive depth to %d\n", + dev->attrs.max_qp_wr); + newxprt->sc_rq_depth = dev->attrs.max_qp_wr; + newxprt->sc_max_requests = newxprt->sc_rq_depth - 2; + newxprt->sc_max_bc_requests = 2; + } + newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests); + ctxts = rdma_rw_mr_factor(dev, newxprt->sc_port_num, RPCSVC_MAXPAGES); + ctxts *= newxprt->sc_max_requests; + newxprt->sc_sq_depth = newxprt->sc_rq_depth + ctxts; + if (newxprt->sc_sq_depth > dev->attrs.max_qp_wr) { + pr_warn("svcrdma: reducing send depth to %d\n", + dev->attrs.max_qp_wr); + newxprt->sc_sq_depth = dev->attrs.max_qp_wr; + } atomic_set(&newxprt->sc_sq_avail, newxprt->sc_sq_depth); if (!svc_rdma_prealloc_ctxts(newxprt)) @@ -784,8 +797,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) qp_attr.event_handler = qp_event_handler; qp_attr.qp_context = &newxprt->sc_xprt; qp_attr.port_num = newxprt->sc_port_num; - qp_attr.cap.max_rdma_ctxs = newxprt->sc_max_requests; - qp_attr.cap.max_send_wr = newxprt->sc_sq_depth; + qp_attr.cap.max_rdma_ctxs = ctxts; + qp_attr.cap.max_send_wr = newxprt->sc_sq_depth - ctxts; qp_attr.cap.max_recv_wr = newxprt->sc_rq_depth; qp_attr.cap.max_send_sge = newxprt->sc_max_sge; qp_attr.cap.max_recv_sge = newxprt->sc_max_sge; @@ -853,6 +866,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) dprintk(" remote address : %pIS:%u\n", sap, rpc_get_port(sap)); dprintk(" max_sge : %d\n", newxprt->sc_max_sge); dprintk(" sq_depth : %d\n", newxprt->sc_sq_depth); + dprintk(" rdma_rw_ctxs : %d\n", ctxts); dprintk(" max_requests : %d\n", newxprt->sc_max_requests); dprintk(" ord : %d\n", newxprt->sc_ord); diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index d1c458e5ec4de25b81f30fa5919cb0b9dfc5ffdf..c84e2b644e133ee13c94082b171acbe063bf3f97 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -149,7 +149,7 @@ static struct ctl_table sunrpc_table[] = { #endif -static struct rpc_xprt_ops xprt_rdma_procs; /*forward reference */ +static const struct rpc_xprt_ops xprt_rdma_procs; static void xprt_rdma_format_addresses4(struct rpc_xprt *xprt, struct sockaddr *sap) @@ -559,6 +559,7 @@ rpcrdma_get_rdmabuf(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req, r_xprt->rx_stats.hardway_register_count += size; req->rl_rdmabuf = rb; + xdr_buf_init(&req->rl_hdrbuf, rb->rg_base, rdmab_length(rb)); return true; } @@ -684,7 +685,6 @@ xprt_rdma_free(struct rpc_task *task) dprintk("RPC: %s: called on 0x%p\n", __func__, req->rl_reply); - rpcrdma_remove_req(&r_xprt->rx_buf, req); if (!list_empty(&req->rl_registered)) ia->ri_ops->ro_unmap_safe(r_xprt, req, !RPC_IS_ASYNC(task)); rpcrdma_unmap_sges(ia, req); @@ -730,7 +730,7 @@ xprt_rdma_send_request(struct rpc_task *task) if (unlikely(!list_empty(&req->rl_registered))) r_xprt->rx_ia.ri_ops->ro_unmap_safe(r_xprt, req, false); - rc = rpcrdma_marshal_req(rqst); + rc = rpcrdma_marshal_req(r_xprt, rqst); if (rc < 0) goto failed_marshal; @@ -811,7 +811,7 @@ xprt_rdma_disable_swap(struct rpc_xprt *xprt) * Plumbing for rpc transport switch and kernel module */ -static struct rpc_xprt_ops xprt_rdma_procs = { +static const struct rpc_xprt_ops xprt_rdma_procs = { .reserve_xprt = xprt_reserve_xprt_cong, .release_xprt = xprt_release_xprt_cong, /* sunrpc/xprt.c */ .alloc_slot = xprt_alloc_slot, diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index e4171f2abe37d966b82b9a858300843027e7224c..11a1fbf7e59e08e9172f4562652dc55d53240075 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -139,14 +139,11 @@ rpcrdma_wc_send(struct ib_cq *cq, struct ib_wc *wc) static void rpcrdma_update_granted_credits(struct rpcrdma_rep *rep) { - struct rpcrdma_msg *rmsgp = rdmab_to_msg(rep->rr_rdmabuf); struct rpcrdma_buffer *buffer = &rep->rr_rxprt->rx_buf; + __be32 *p = rep->rr_rdmabuf->rg_base; u32 credits; - if (rep->rr_len < RPCRDMA_HDRLEN_ERR) - return; - - credits = be32_to_cpu(rmsgp->rm_credit); + credits = be32_to_cpup(p + 2); if (credits == 0) credits = 1; /* don't deadlock */ else if (credits > buffer->rb_max_requests) @@ -173,21 +170,19 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc) goto out_fail; /* status == SUCCESS means all fields in wc are trustworthy */ - if (wc->opcode != IB_WC_RECV) - return; - dprintk("RPC: %s: rep %p opcode 'recv', length %u: success\n", __func__, rep, wc->byte_len); - rep->rr_len = wc->byte_len; + rpcrdma_set_xdrlen(&rep->rr_hdrbuf, wc->byte_len); rep->rr_wc_flags = wc->wc_flags; rep->rr_inv_rkey = wc->ex.invalidate_rkey; ib_dma_sync_single_for_cpu(rdmab_device(rep->rr_rdmabuf), rdmab_addr(rep->rr_rdmabuf), - rep->rr_len, DMA_FROM_DEVICE); + wc->byte_len, DMA_FROM_DEVICE); - rpcrdma_update_granted_credits(rep); + if (wc->byte_len >= RPCRDMA_HDRLEN_ERR) + rpcrdma_update_granted_credits(rep); out_schedule: queue_work(rpcrdma_receive_wq, &rep->rr_work); @@ -198,7 +193,7 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc) pr_err("rpcrdma: Recv: %s (%u/0x%x)\n", ib_wc_status_msg(wc->status), wc->status, wc->vendor_err); - rep->rr_len = RPCRDMA_BAD_LEN; + rpcrdma_set_xdrlen(&rep->rr_hdrbuf, 0); goto out_schedule; } @@ -974,6 +969,8 @@ rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt) rc = PTR_ERR(rep->rr_rdmabuf); goto out_free; } + xdr_buf_init(&rep->rr_hdrbuf, rep->rr_rdmabuf->rg_base, + rdmab_length(rep->rr_rdmabuf)); rep->rr_cqe.done = rpcrdma_wc_receive; rep->rr_rxprt = r_xprt; @@ -1004,7 +1001,6 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) spin_lock_init(&buf->rb_recovery_lock); INIT_LIST_HEAD(&buf->rb_mws); INIT_LIST_HEAD(&buf->rb_all); - INIT_LIST_HEAD(&buf->rb_pending); INIT_LIST_HEAD(&buf->rb_stale_mrs); INIT_DELAYED_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker); diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index b282d3f8cdd8004c6f0a6391434b6b94775c29f9..e26a97d2f922fad2cc14aa11ea0cd4287d1c26b5 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -218,18 +218,17 @@ enum { struct rpcrdma_rep { struct ib_cqe rr_cqe; - unsigned int rr_len; int rr_wc_flags; u32 rr_inv_rkey; + struct rpcrdma_regbuf *rr_rdmabuf; struct rpcrdma_xprt *rr_rxprt; struct work_struct rr_work; + struct xdr_buf rr_hdrbuf; + struct xdr_stream rr_stream; struct list_head rr_list; struct ib_recv_wr rr_recv_wr; - struct rpcrdma_regbuf *rr_rdmabuf; }; -#define RPCRDMA_BAD_LEN (~0U) - /* * struct rpcrdma_mw - external memory region metadata * @@ -341,11 +340,12 @@ enum { struct rpcrdma_buffer; struct rpcrdma_req { struct list_head rl_list; - __be32 rl_xid; unsigned int rl_mapped_sges; unsigned int rl_connect_cookie; struct rpcrdma_buffer *rl_buffer; struct rpcrdma_rep *rl_reply; + struct xdr_stream rl_stream; + struct xdr_buf rl_hdrbuf; struct ib_send_wr rl_send_wr; struct ib_sge rl_send_sge[RPCRDMA_MAX_SEND_SGES]; struct rpcrdma_regbuf *rl_rdmabuf; /* xprt header */ @@ -403,7 +403,6 @@ struct rpcrdma_buffer { int rb_send_count, rb_recv_count; struct list_head rb_send_bufs; struct list_head rb_recv_bufs; - struct list_head rb_pending; u32 rb_max_requests; atomic_t rb_credits; /* most recent credit grant */ @@ -440,24 +439,27 @@ struct rpcrdma_create_data_internal { * Statistics for RPCRDMA */ struct rpcrdma_stats { + /* accessed when sending a call */ unsigned long read_chunk_count; unsigned long write_chunk_count; unsigned long reply_chunk_count; - unsigned long long total_rdma_request; - unsigned long long total_rdma_reply; + /* rarely accessed error counters */ unsigned long long pullup_copy_count; - unsigned long long fixup_copy_count; unsigned long hardway_register_count; unsigned long failed_marshal_count; unsigned long bad_reply_count; - unsigned long nomsg_call_count; - unsigned long bcall_count; unsigned long mrs_recovered; unsigned long mrs_orphaned; unsigned long mrs_allocated; + + /* accessed when receiving a reply */ + unsigned long long total_rdma_reply; + unsigned long long fixup_copy_count; unsigned long local_inv_needed; + unsigned long nomsg_call_count; + unsigned long bcall_count; }; /* @@ -465,7 +467,8 @@ struct rpcrdma_stats { */ struct rpcrdma_xprt; struct rpcrdma_memreg_ops { - int (*ro_map)(struct rpcrdma_xprt *, + struct rpcrdma_mr_seg * + (*ro_map)(struct rpcrdma_xprt *, struct rpcrdma_mr_seg *, int, bool, struct rpcrdma_mw **); void (*ro_unmap_sync)(struct rpcrdma_xprt *, @@ -552,34 +555,6 @@ void rpcrdma_destroy_req(struct rpcrdma_req *); int rpcrdma_buffer_create(struct rpcrdma_xprt *); void rpcrdma_buffer_destroy(struct rpcrdma_buffer *); -static inline void -rpcrdma_insert_req(struct rpcrdma_buffer *buffers, struct rpcrdma_req *req) -{ - spin_lock(&buffers->rb_lock); - if (list_empty(&req->rl_list)) - list_add_tail(&req->rl_list, &buffers->rb_pending); - spin_unlock(&buffers->rb_lock); -} - -static inline struct rpcrdma_req * -rpcrdma_lookup_req_locked(struct rpcrdma_buffer *buffers, __be32 xid) -{ - struct rpcrdma_req *pos; - - list_for_each_entry(pos, &buffers->rb_pending, rl_list) - if (pos->rl_xid == xid) - return pos; - return NULL; -} - -static inline void -rpcrdma_remove_req(struct rpcrdma_buffer *buffers, struct rpcrdma_req *req) -{ - spin_lock(&buffers->rb_lock); - list_del(&req->rl_list); - spin_unlock(&buffers->rb_lock); -} - struct rpcrdma_mw *rpcrdma_get_mw(struct rpcrdma_xprt *); void rpcrdma_put_mw(struct rpcrdma_xprt *, struct rpcrdma_mw *); struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *); @@ -638,10 +613,16 @@ enum rpcrdma_chunktype { bool rpcrdma_prepare_send_sges(struct rpcrdma_ia *, struct rpcrdma_req *, u32, struct xdr_buf *, enum rpcrdma_chunktype); void rpcrdma_unmap_sges(struct rpcrdma_ia *, struct rpcrdma_req *); -int rpcrdma_marshal_req(struct rpc_rqst *); +int rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst); void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *); void rpcrdma_reply_handler(struct work_struct *work); +static inline void rpcrdma_set_xdrlen(struct xdr_buf *xdr, size_t len) +{ + xdr->head[0].iov_len = len; + xdr->len = len; +} + /* RPC/RDMA module init - xprtrdma/transport.c */ extern unsigned int xprt_rdma_max_inline_read; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 4f154d3887483e9cf1a6ab151c487e1d6113c1a8..9b5de31aa42939cbc3f6aa4a0a94d7a28f711e84 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -969,10 +969,12 @@ static void xs_local_data_read_skb(struct rpc_xprt *xprt, return; /* Look up and lock the request corresponding to the given XID */ - spin_lock_bh(&xprt->transport_lock); + spin_lock(&xprt->recv_lock); rovr = xprt_lookup_rqst(xprt, *xp); if (!rovr) goto out_unlock; + xprt_pin_rqst(rovr); + spin_unlock(&xprt->recv_lock); task = rovr->rq_task; copied = rovr->rq_private_buf.buflen; @@ -981,13 +983,16 @@ static void xs_local_data_read_skb(struct rpc_xprt *xprt, if (xs_local_copy_to_xdr(&rovr->rq_private_buf, skb)) { dprintk("RPC: sk_buff copy failed\n"); - goto out_unlock; + spin_lock(&xprt->recv_lock); + goto out_unpin; } + spin_lock(&xprt->recv_lock); xprt_complete_rqst(task, copied); - +out_unpin: + xprt_unpin_rqst(rovr); out_unlock: - spin_unlock_bh(&xprt->transport_lock); + spin_unlock(&xprt->recv_lock); } static void xs_local_data_receive(struct sock_xprt *transport) @@ -1050,10 +1055,12 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt, return; /* Look up and lock the request corresponding to the given XID */ - spin_lock_bh(&xprt->transport_lock); + spin_lock(&xprt->recv_lock); rovr = xprt_lookup_rqst(xprt, *xp); if (!rovr) goto out_unlock; + xprt_pin_rqst(rovr); + spin_unlock(&xprt->recv_lock); task = rovr->rq_task; if ((copied = rovr->rq_private_buf.buflen) > repsize) @@ -1062,16 +1069,21 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt, /* Suck it into the iovec, verify checksum if not done by hw. */ if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb)) { __UDPX_INC_STATS(sk, UDP_MIB_INERRORS); - goto out_unlock; + spin_lock(&xprt->recv_lock); + goto out_unpin; } __UDPX_INC_STATS(sk, UDP_MIB_INDATAGRAMS); + spin_lock_bh(&xprt->transport_lock); xprt_adjust_cwnd(xprt, task, copied); + spin_unlock_bh(&xprt->transport_lock); + spin_lock(&xprt->recv_lock); xprt_complete_rqst(task, copied); - +out_unpin: + xprt_unpin_rqst(rovr); out_unlock: - spin_unlock_bh(&xprt->transport_lock); + spin_unlock(&xprt->recv_lock); } static void xs_udp_data_receive(struct sock_xprt *transport) @@ -1277,25 +1289,12 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt, } len = desc->count; - if (len > transport->tcp_reclen - transport->tcp_offset) { - struct xdr_skb_reader my_desc; - - len = transport->tcp_reclen - transport->tcp_offset; - memcpy(&my_desc, desc, sizeof(my_desc)); - my_desc.count = len; - r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied, - &my_desc, xdr_skb_read_bits); - desc->count -= r; - desc->offset += r; - } else - r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied, + if (len > transport->tcp_reclen - transport->tcp_offset) + desc->count = transport->tcp_reclen - transport->tcp_offset; + r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied, desc, xdr_skb_read_bits); - if (r > 0) { - transport->tcp_copied += r; - transport->tcp_offset += r; - } - if (r != len) { + if (desc->count) { /* Error when copying to the receive buffer, * usually because we weren't able to allocate * additional buffer pages. All we can do now @@ -1315,6 +1314,10 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt, return; } + transport->tcp_copied += r; + transport->tcp_offset += r; + desc->count = len - r; + dprintk("RPC: XID %08x read %zd bytes\n", ntohl(transport->tcp_xid), r); dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, " @@ -1343,21 +1346,24 @@ static inline int xs_tcp_read_reply(struct rpc_xprt *xprt, dprintk("RPC: read reply XID %08x\n", ntohl(transport->tcp_xid)); /* Find and lock the request corresponding to this xid */ - spin_lock_bh(&xprt->transport_lock); + spin_lock(&xprt->recv_lock); req = xprt_lookup_rqst(xprt, transport->tcp_xid); if (!req) { dprintk("RPC: XID %08x request not found!\n", ntohl(transport->tcp_xid)); - spin_unlock_bh(&xprt->transport_lock); + spin_unlock(&xprt->recv_lock); return -1; } + xprt_pin_rqst(req); + spin_unlock(&xprt->recv_lock); xs_tcp_read_common(xprt, desc, req); + spin_lock(&xprt->recv_lock); if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) xprt_complete_rqst(req->rq_task, transport->tcp_copied); - - spin_unlock_bh(&xprt->transport_lock); + xprt_unpin_rqst(req); + spin_unlock(&xprt->recv_lock); return 0; } @@ -1376,11 +1382,9 @@ static int xs_tcp_read_callback(struct rpc_xprt *xprt, container_of(xprt, struct sock_xprt, xprt); struct rpc_rqst *req; - /* Look up and lock the request corresponding to the given XID */ - spin_lock_bh(&xprt->transport_lock); + /* Look up the request corresponding to the given XID */ req = xprt_lookup_bc_request(xprt, transport->tcp_xid); if (req == NULL) { - spin_unlock_bh(&xprt->transport_lock); printk(KERN_WARNING "Callback slot table overflowed\n"); xprt_force_disconnect(xprt); return -1; @@ -1391,7 +1395,6 @@ static int xs_tcp_read_callback(struct rpc_xprt *xprt, if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) xprt_complete_bc_request(req, transport->tcp_copied); - spin_unlock_bh(&xprt->transport_lock); return 0; } @@ -1516,6 +1519,7 @@ static void xs_tcp_data_receive(struct sock_xprt *transport) .arg.data = xprt, }; unsigned long total = 0; + int loop; int read = 0; mutex_lock(&transport->recv_mutex); @@ -1524,20 +1528,20 @@ static void xs_tcp_data_receive(struct sock_xprt *transport) goto out; /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ - for (;;) { + for (loop = 0; loop < 64; loop++) { lock_sock(sk); read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); if (read <= 0) { clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state); release_sock(sk); - if (!test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) - break; - } else { - release_sock(sk); - total += read; + break; } + release_sock(sk); + total += read; rd_desc.count = 65536; } + if (test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) + queue_work(xprtiod_workqueue, &transport->recv_worker); out: mutex_unlock(&transport->recv_mutex); trace_xs_tcp_data_ready(xprt, read, total); @@ -2724,7 +2728,7 @@ static void bc_destroy(struct rpc_xprt *xprt) module_put(THIS_MODULE); } -static struct rpc_xprt_ops xs_local_ops = { +static const struct rpc_xprt_ops xs_local_ops = { .reserve_xprt = xprt_reserve_xprt, .release_xprt = xs_tcp_release_xprt, .alloc_slot = xprt_alloc_slot, @@ -2742,7 +2746,7 @@ static struct rpc_xprt_ops xs_local_ops = { .disable_swap = xs_disable_swap, }; -static struct rpc_xprt_ops xs_udp_ops = { +static const struct rpc_xprt_ops xs_udp_ops = { .set_buffer_size = xs_udp_set_buffer_size, .reserve_xprt = xprt_reserve_xprt_cong, .release_xprt = xprt_release_xprt_cong, @@ -2764,7 +2768,7 @@ static struct rpc_xprt_ops xs_udp_ops = { .inject_disconnect = xs_inject_disconnect, }; -static struct rpc_xprt_ops xs_tcp_ops = { +static const struct rpc_xprt_ops xs_tcp_ops = { .reserve_xprt = xprt_reserve_xprt, .release_xprt = xs_tcp_release_xprt, .alloc_slot = xprt_lock_and_alloc_slot, @@ -2795,7 +2799,7 @@ static struct rpc_xprt_ops xs_tcp_ops = { * The rpc_xprt_ops for the server backchannel */ -static struct rpc_xprt_ops bc_tcp_ops = { +static const struct rpc_xprt_ops bc_tcp_ops = { .reserve_xprt = xprt_reserve_xprt, .release_xprt = xprt_release_xprt, .alloc_slot = xprt_alloc_slot, diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 25dc67ef9d37084f55ff7a49a2daabee6556a42c..0531b41d1f2d08fe596f01cafee1cbb323298299 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -343,8 +343,6 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj) switch (obj->id) { case SWITCHDEV_OBJ_ID_PORT_VLAN: return sizeof(struct switchdev_obj_port_vlan); - case SWITCHDEV_OBJ_ID_PORT_FDB: - return sizeof(struct switchdev_obj_port_fdb); case SWITCHDEV_OBJ_ID_PORT_MDB: return sizeof(struct switchdev_obj_port_mdb); default: @@ -534,43 +532,6 @@ int switchdev_port_obj_del(struct net_device *dev, } EXPORT_SYMBOL_GPL(switchdev_port_obj_del); -/** - * switchdev_port_obj_dump - Dump port objects - * - * @dev: port device - * @id: object ID - * @obj: object to dump - * @cb: function to call with a filled object - * - * rtnl_lock must be held. - */ -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, - switchdev_obj_dump_cb_t *cb) -{ - const struct switchdev_ops *ops = dev->switchdev_ops; - struct net_device *lower_dev; - struct list_head *iter; - int err = -EOPNOTSUPP; - - ASSERT_RTNL(); - - if (ops && ops->switchdev_port_obj_dump) - return ops->switchdev_port_obj_dump(dev, obj, cb); - - /* Switch device port(s) may be stacked under - * bond/team/vlan dev, so recurse down to dump objects on - * first port at bottom of stack. - */ - - netdev_for_each_lower_dev(dev, lower_dev, iter) { - err = switchdev_port_obj_dump(lower_dev, obj, cb); - break; - } - - return err; -} -EXPORT_SYMBOL_GPL(switchdev_port_obj_dump); - static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain); /** @@ -613,486 +574,6 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev, } EXPORT_SYMBOL_GPL(call_switchdev_notifiers); -struct switchdev_vlan_dump { - struct switchdev_obj_port_vlan vlan; - struct sk_buff *skb; - u32 filter_mask; - u16 flags; - u16 begin; - u16 end; -}; - -static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump) -{ - struct bridge_vlan_info vinfo; - - vinfo.flags = dump->flags; - - if (dump->begin == 0 && dump->end == 0) { - return 0; - } else if (dump->begin == dump->end) { - vinfo.vid = dump->begin; - if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO, - sizeof(vinfo), &vinfo)) - return -EMSGSIZE; - } else { - vinfo.vid = dump->begin; - vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN; - if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO, - sizeof(vinfo), &vinfo)) - return -EMSGSIZE; - vinfo.vid = dump->end; - vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN; - vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END; - if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO, - sizeof(vinfo), &vinfo)) - return -EMSGSIZE; - } - - return 0; -} - -static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj) -{ - struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); - struct switchdev_vlan_dump *dump = - container_of(vlan, struct switchdev_vlan_dump, vlan); - int err = 0; - - if (vlan->vid_begin > vlan->vid_end) - return -EINVAL; - - if (dump->filter_mask & RTEXT_FILTER_BRVLAN) { - dump->flags = vlan->flags; - for (dump->begin = dump->end = vlan->vid_begin; - dump->begin <= vlan->vid_end; - dump->begin++, dump->end++) { - err = switchdev_port_vlan_dump_put(dump); - if (err) - return err; - } - } else if (dump->filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) { - if (dump->begin > vlan->vid_begin && - dump->begin >= vlan->vid_end) { - if ((dump->begin - 1) == vlan->vid_end && - dump->flags == vlan->flags) { - /* prepend */ - dump->begin = vlan->vid_begin; - } else { - err = switchdev_port_vlan_dump_put(dump); - dump->flags = vlan->flags; - dump->begin = vlan->vid_begin; - dump->end = vlan->vid_end; - } - } else if (dump->end <= vlan->vid_begin && - dump->end < vlan->vid_end) { - if ((dump->end + 1) == vlan->vid_begin && - dump->flags == vlan->flags) { - /* append */ - dump->end = vlan->vid_end; - } else { - err = switchdev_port_vlan_dump_put(dump); - dump->flags = vlan->flags; - dump->begin = vlan->vid_begin; - dump->end = vlan->vid_end; - } - } else { - err = -EINVAL; - } - } - - return err; -} - -static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev, - u32 filter_mask) -{ - struct switchdev_vlan_dump dump = { - .vlan.obj.orig_dev = dev, - .vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, - .skb = skb, - .filter_mask = filter_mask, - }; - int err = 0; - - if ((filter_mask & RTEXT_FILTER_BRVLAN) || - (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) { - err = switchdev_port_obj_dump(dev, &dump.vlan.obj, - switchdev_port_vlan_dump_cb); - if (err) - goto err_out; - if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) - /* last one */ - err = switchdev_port_vlan_dump_put(&dump); - } - -err_out: - return err == -EOPNOTSUPP ? 0 : err; -} - -/** - * switchdev_port_bridge_getlink - Get bridge port attributes - * - * @dev: port device - * - * Called for SELF on rtnl_bridge_getlink to get bridge port - * attributes. - */ -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, - struct net_device *dev, u32 filter_mask, - int nlflags) -{ - struct switchdev_attr attr = { - .orig_dev = dev, - .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, - }; - u16 mode = BRIDGE_MODE_UNDEF; - u32 mask = BR_LEARNING | BR_LEARNING_SYNC | BR_FLOOD; - int err; - - if (!netif_is_bridge_port(dev)) - return -EOPNOTSUPP; - - err = switchdev_port_attr_get(dev, &attr); - if (err && err != -EOPNOTSUPP) - return err; - - return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, - attr.u.brport_flags, mask, nlflags, - filter_mask, switchdev_port_vlan_fill); -} -EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink); - -static int switchdev_port_br_setflag(struct net_device *dev, - struct nlattr *nlattr, - unsigned long brport_flag) -{ - struct switchdev_attr attr = { - .orig_dev = dev, - .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, - }; - u8 flag = nla_get_u8(nlattr); - int err; - - err = switchdev_port_attr_get(dev, &attr); - if (err) - return err; - - if (flag) - attr.u.brport_flags |= brport_flag; - else - attr.u.brport_flags &= ~brport_flag; - - return switchdev_port_attr_set(dev, &attr); -} - -static const struct nla_policy -switchdev_port_bridge_policy[IFLA_BRPORT_MAX + 1] = { - [IFLA_BRPORT_STATE] = { .type = NLA_U8 }, - [IFLA_BRPORT_COST] = { .type = NLA_U32 }, - [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, - [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, - [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, - [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, - [IFLA_BRPORT_FAST_LEAVE] = { .type = NLA_U8 }, - [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, - [IFLA_BRPORT_LEARNING_SYNC] = { .type = NLA_U8 }, - [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, -}; - -static int switchdev_port_br_setlink_protinfo(struct net_device *dev, - struct nlattr *protinfo) -{ - struct nlattr *attr; - int rem; - int err; - - err = nla_validate_nested(protinfo, IFLA_BRPORT_MAX, - switchdev_port_bridge_policy, NULL); - if (err) - return err; - - nla_for_each_nested(attr, protinfo, rem) { - switch (nla_type(attr)) { - case IFLA_BRPORT_LEARNING: - err = switchdev_port_br_setflag(dev, attr, - BR_LEARNING); - break; - case IFLA_BRPORT_LEARNING_SYNC: - err = switchdev_port_br_setflag(dev, attr, - BR_LEARNING_SYNC); - break; - case IFLA_BRPORT_UNICAST_FLOOD: - err = switchdev_port_br_setflag(dev, attr, BR_FLOOD); - break; - default: - err = -EOPNOTSUPP; - break; - } - if (err) - return err; - } - - return 0; -} - -static int switchdev_port_br_afspec(struct net_device *dev, - struct nlattr *afspec, - int (*f)(struct net_device *dev, - const struct switchdev_obj *obj)) -{ - struct nlattr *attr; - struct bridge_vlan_info *vinfo; - struct switchdev_obj_port_vlan vlan = { - .obj.orig_dev = dev, - .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, - }; - int rem; - int err; - - nla_for_each_nested(attr, afspec, rem) { - if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO) - continue; - if (nla_len(attr) != sizeof(struct bridge_vlan_info)) - return -EINVAL; - vinfo = nla_data(attr); - if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK) - return -EINVAL; - vlan.flags = vinfo->flags; - if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { - if (vlan.vid_begin) - return -EINVAL; - vlan.vid_begin = vinfo->vid; - /* don't allow range of pvids */ - if (vlan.flags & BRIDGE_VLAN_INFO_PVID) - return -EINVAL; - } else if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) { - if (!vlan.vid_begin) - return -EINVAL; - vlan.vid_end = vinfo->vid; - if (vlan.vid_end <= vlan.vid_begin) - return -EINVAL; - err = f(dev, &vlan.obj); - if (err) - return err; - vlan.vid_begin = 0; - } else { - if (vlan.vid_begin) - return -EINVAL; - vlan.vid_begin = vinfo->vid; - vlan.vid_end = vinfo->vid; - err = f(dev, &vlan.obj); - if (err) - return err; - vlan.vid_begin = 0; - } - } - - return 0; -} - -/** - * switchdev_port_bridge_setlink - Set bridge port attributes - * - * @dev: port device - * @nlh: netlink header - * @flags: netlink flags - * - * Called for SELF on rtnl_bridge_setlink to set bridge port - * attributes. - */ -int switchdev_port_bridge_setlink(struct net_device *dev, - struct nlmsghdr *nlh, u16 flags) -{ - struct nlattr *protinfo; - struct nlattr *afspec; - int err = 0; - - if (!netif_is_bridge_port(dev)) - return -EOPNOTSUPP; - - protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), - IFLA_PROTINFO); - if (protinfo) { - err = switchdev_port_br_setlink_protinfo(dev, protinfo); - if (err) - return err; - } - - afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), - IFLA_AF_SPEC); - if (afspec) - err = switchdev_port_br_afspec(dev, afspec, - switchdev_port_obj_add); - - return err; -} -EXPORT_SYMBOL_GPL(switchdev_port_bridge_setlink); - -/** - * switchdev_port_bridge_dellink - Set bridge port attributes - * - * @dev: port device - * @nlh: netlink header - * @flags: netlink flags - * - * Called for SELF on rtnl_bridge_dellink to set bridge port - * attributes. - */ -int switchdev_port_bridge_dellink(struct net_device *dev, - struct nlmsghdr *nlh, u16 flags) -{ - struct nlattr *afspec; - - if (!netif_is_bridge_port(dev)) - return -EOPNOTSUPP; - - afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), - IFLA_AF_SPEC); - if (afspec) - return switchdev_port_br_afspec(dev, afspec, - switchdev_port_obj_del); - - return 0; -} -EXPORT_SYMBOL_GPL(switchdev_port_bridge_dellink); - -/** - * switchdev_port_fdb_add - Add FDB (MAC/VLAN) entry to port - * - * @ndmsg: netlink hdr - * @nlattr: netlink attributes - * @dev: port device - * @addr: MAC address to add - * @vid: VLAN to add - * - * Add FDB entry to switch device. - */ -int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, const unsigned char *addr, - u16 vid, u16 nlm_flags) -{ - struct switchdev_obj_port_fdb fdb = { - .obj.orig_dev = dev, - .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, - .vid = vid, - }; - - ether_addr_copy(fdb.addr, addr); - return switchdev_port_obj_add(dev, &fdb.obj); -} -EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); - -/** - * switchdev_port_fdb_del - Delete FDB (MAC/VLAN) entry from port - * - * @ndmsg: netlink hdr - * @nlattr: netlink attributes - * @dev: port device - * @addr: MAC address to delete - * @vid: VLAN to delete - * - * Delete FDB entry from switch device. - */ -int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, const unsigned char *addr, - u16 vid) -{ - struct switchdev_obj_port_fdb fdb = { - .obj.orig_dev = dev, - .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, - .vid = vid, - }; - - ether_addr_copy(fdb.addr, addr); - return switchdev_port_obj_del(dev, &fdb.obj); -} -EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); - -struct switchdev_fdb_dump { - struct switchdev_obj_port_fdb fdb; - struct net_device *dev; - struct sk_buff *skb; - struct netlink_callback *cb; - int idx; -}; - -static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj) -{ - struct switchdev_obj_port_fdb *fdb = SWITCHDEV_OBJ_PORT_FDB(obj); - struct switchdev_fdb_dump *dump = - container_of(fdb, struct switchdev_fdb_dump, fdb); - u32 portid = NETLINK_CB(dump->cb->skb).portid; - u32 seq = dump->cb->nlh->nlmsg_seq; - struct nlmsghdr *nlh; - struct ndmsg *ndm; - - if (dump->idx < dump->cb->args[2]) - goto skip; - - nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH, - sizeof(*ndm), NLM_F_MULTI); - if (!nlh) - return -EMSGSIZE; - - ndm = nlmsg_data(nlh); - ndm->ndm_family = AF_BRIDGE; - ndm->ndm_pad1 = 0; - ndm->ndm_pad2 = 0; - ndm->ndm_flags = NTF_SELF; - ndm->ndm_type = 0; - ndm->ndm_ifindex = dump->dev->ifindex; - ndm->ndm_state = fdb->ndm_state; - - if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, fdb->addr)) - goto nla_put_failure; - - if (fdb->vid && nla_put_u16(dump->skb, NDA_VLAN, fdb->vid)) - goto nla_put_failure; - - nlmsg_end(dump->skb, nlh); - -skip: - dump->idx++; - return 0; - -nla_put_failure: - nlmsg_cancel(dump->skb, nlh); - return -EMSGSIZE; -} - -/** - * switchdev_port_fdb_dump - Dump port FDB (MAC/VLAN) entries - * - * @skb: netlink skb - * @cb: netlink callback - * @dev: port device - * @filter_dev: filter device - * @idx: - * - * Dump FDB entries from switch device. - */ -int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, - struct net_device *dev, - struct net_device *filter_dev, int *idx) -{ - struct switchdev_fdb_dump dump = { - .fdb.obj.orig_dev = dev, - .fdb.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, - .dev = dev, - .skb = skb, - .cb = cb, - .idx = *idx, - }; - int err; - - err = switchdev_port_obj_dump(dev, &dump.fdb.obj, - switchdev_port_fdb_dump_cb); - *idx = dump.idx; - return err; -} -EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump); - bool switchdev_port_same_parent_id(struct net_device *a, struct net_device *b) { diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index d174ee3254eecb523dbc86061d80a1e812dcc305..47ec121574ce4ef95850f688d85b50eff766a710 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -65,6 +65,8 @@ static struct tipc_bearer *bearer_get(struct net *net, int bearer_id) } static void bearer_disable(struct net *net, struct tipc_bearer *b); +static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev); /** * tipc_media_find - locates specified media object by name @@ -365,30 +367,6 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b) return 0; } -/* tipc_bearer_reset_all - reset all links on all bearers - */ -void tipc_bearer_reset_all(struct net *net) -{ - struct tipc_bearer *b; - int i; - - for (i = 0; i < MAX_BEARERS; i++) { - b = bearer_get(net, i); - if (b) - clear_bit_unlock(0, &b->up); - } - for (i = 0; i < MAX_BEARERS; i++) { - b = bearer_get(net, i); - if (b) - tipc_reset_bearer(net, b); - } - for (i = 0; i < MAX_BEARERS; i++) { - b = bearer_get(net, i); - if (b) - test_and_set_bit_lock(0, &b->up); - } -} - /** * bearer_disable * @@ -428,6 +406,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, /* Associate TIPC bearer with L2 bearer */ rcu_assign_pointer(b->media_ptr, dev); + b->pt.dev = dev; + b->pt.type = htons(ETH_P_TIPC); + b->pt.func = tipc_l2_rcv_msg; + dev_add_pack(&b->pt); memset(&b->bcast_addr, 0, sizeof(b->bcast_addr)); memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len); b->bcast_addr.media_id = b->media->type_id; @@ -447,6 +429,7 @@ void tipc_disable_l2_media(struct tipc_bearer *b) struct net_device *dev; dev = (struct net_device *)rtnl_dereference(b->media_ptr); + dev_remove_pack(&b->pt); RCU_INIT_POINTER(dev->tipc_ptr, NULL); synchronize_net(); dev_put(dev); @@ -594,11 +577,12 @@ static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev, struct tipc_bearer *b; rcu_read_lock(); - b = rcu_dereference_rtnl(dev->tipc_ptr); + b = rcu_dereference_rtnl(dev->tipc_ptr) ?: + rcu_dereference_rtnl(orig_dev->tipc_ptr); if (likely(b && test_bit(0, &b->up) && - (skb->pkt_type <= PACKET_BROADCAST))) { + (skb->pkt_type <= PACKET_MULTICAST))) { skb->next = NULL; - tipc_rcv(dev_net(dev), skb, b); + tipc_rcv(dev_net(b->pt.dev), skb, b); rcu_read_unlock(); return NET_RX_SUCCESS; } @@ -653,17 +637,12 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt, break; case NETDEV_UNREGISTER: case NETDEV_CHANGENAME: - bearer_disable(dev_net(dev), b); + bearer_disable(net, b); break; } return NOTIFY_OK; } -static struct packet_type tipc_packet_type __read_mostly = { - .type = htons(ETH_P_TIPC), - .func = tipc_l2_rcv_msg, -}; - static struct notifier_block notifier = { .notifier_call = tipc_l2_device_event, .priority = 0, @@ -671,19 +650,12 @@ static struct notifier_block notifier = { int tipc_bearer_setup(void) { - int err; - - err = register_netdevice_notifier(¬ifier); - if (err) - return err; - dev_add_pack(&tipc_packet_type); - return 0; + return register_netdevice_notifier(¬ifier); } void tipc_bearer_cleanup(void) { unregister_netdevice_notifier(¬ifier); - dev_remove_pack(&tipc_packet_type); } void tipc_bearer_stop(struct net *net) diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 635c9086e19af86b81b4dc572a7c2ee0374b02fc..42d6eeeb646ddca457aec269de1650b1269cb411 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -131,6 +131,7 @@ struct tipc_media { * @name: bearer name (format = media:interface) * @media: ptr to media structure associated with bearer * @bcast_addr: media address used in broadcasting + * @pt: packet type for bearer * @rcu: rcu struct for tipc_bearer * @priority: default link priority for bearer * @window: default window size for bearer @@ -151,6 +152,7 @@ struct tipc_bearer { char name[TIPC_MAX_BEARER_NAME]; struct tipc_media *media; struct tipc_media_addr bcast_addr; + struct packet_type pt; struct rcu_head rcu; u32 priority; u32 window; @@ -210,7 +212,6 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest); struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name); int tipc_bearer_get_name(struct net *net, char *name, u32 bearer_id); struct tipc_media *tipc_media_find(const char *name); -void tipc_bearer_reset_all(struct net *net); int tipc_bearer_setup(void); void tipc_bearer_cleanup(void); void tipc_bearer_stop(struct net *net); diff --git a/net/tipc/link.c b/net/tipc/link.c index 60820dc35a08ade9805080de4c15ff9819e150f5..ac0144f532aa66ca147ef22f288bad0980861680 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -978,15 +978,15 @@ static void link_retransmit_failure(struct tipc_link *l, struct sk_buff *skb) struct tipc_msg *hdr = buf_msg(skb); pr_warn("Retransmission failure on link <%s>\n", l->name); - link_print(l, "Resetting link "); + link_print(l, "State of link "); pr_info("Failed msg: usr %u, typ %u, len %u, err %u\n", msg_user(hdr), msg_type(hdr), msg_size(hdr), msg_errcode(hdr)); pr_info("sqno %u, prev: %x, src: %x\n", msg_seqno(hdr), msg_prevnode(hdr), msg_orignode(hdr)); } -int tipc_link_retrans(struct tipc_link *l, u16 from, u16 to, - struct sk_buff_head *xmitq) +int tipc_link_retrans(struct tipc_link *l, struct tipc_link *nacker, + u16 from, u16 to, struct sk_buff_head *xmitq) { struct sk_buff *_skb, *skb = skb_peek(&l->transmq); struct tipc_msg *hdr; @@ -997,11 +997,14 @@ int tipc_link_retrans(struct tipc_link *l, u16 from, u16 to, return 0; /* Detect repeated retransmit failures on same packet */ - if (likely(l->last_retransm != buf_seqno(skb))) { - l->last_retransm = buf_seqno(skb); - l->stale_count = 1; - } else if (++l->stale_count > 100) { + if (nacker->last_retransm != buf_seqno(skb)) { + nacker->last_retransm = buf_seqno(skb); + nacker->stale_count = 1; + } else if (++nacker->stale_count > 100) { link_retransmit_failure(l, skb); + nacker->stale_count = 0; + if (link_is_bc_sndlink(l)) + return TIPC_LINK_DOWN_EVT; return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); } @@ -1528,7 +1531,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, /* If NACK, retransmit will now start at right position */ if (gap) { - rc = tipc_link_retrans(l, ack + 1, ack + gap, xmitq); + rc = tipc_link_retrans(l, l, ack + 1, ack + gap, xmitq); l->stats.recv_nacks++; } @@ -1680,7 +1683,7 @@ int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr, return rc; if (link_bc_retr_eval(snd_l, &from, &to)) - rc = tipc_link_retrans(snd_l, from, to, xmitq); + rc = tipc_link_retrans(snd_l, l, from, to, xmitq); l->snd_nxt = peers_snd_nxt; if (link_bc_rcv_gap(l)) @@ -1775,7 +1778,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb, if (dnode == tipc_own_addr(l->net)) { tipc_link_bc_ack_rcv(l, acked, xmitq); - rc = tipc_link_retrans(l->bc_sndlink, from, to, xmitq); + rc = tipc_link_retrans(l->bc_sndlink, l, from, to, xmitq); l->stats.recv_nacks++; return rc; } diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ab3087687a32446ffa3bbfaccf206028886e6945..121e59a1d0e729088170586e6714a0245680e4c7 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -479,13 +479,14 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg, bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) { struct sk_buff *_skb = *skb; - struct tipc_msg *hdr = buf_msg(_skb); + struct tipc_msg *hdr; struct tipc_msg ohdr; - int dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE); + int dlen; if (skb_linearize(_skb)) goto exit; hdr = buf_msg(_skb); + dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE); if (msg_dest_droppable(hdr)) goto exit; if (msg_errcode(hdr)) @@ -511,8 +512,11 @@ bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC)) goto exit; + /* reassign after skb header modifications */ + hdr = buf_msg(_skb); /* Now reverse the concerned fields */ msg_set_errcode(hdr, err); + msg_set_non_seq(hdr, 0); msg_set_origport(hdr, msg_destport(&ohdr)); msg_set_destport(hdr, msg_origport(&ohdr)); msg_set_destnode(hdr, msg_prevnode(&ohdr)); @@ -547,7 +551,7 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err) return false; if (msg_errcode(msg)) return false; - *err = -TIPC_ERR_NO_NAME; + *err = TIPC_ERR_NO_NAME; if (skb_linearize(skb)) return false; msg = buf_msg(skb); diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 9bfe886ab33080f653ec1c39e0255b15709d0b76..e48f0b2c01b962dfa2b3516f9ec2f0c3b461db95 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -258,13 +258,15 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, arg = nlmsg_new(0, GFP_KERNEL); if (!arg) { kfree_skb(msg->rep); + msg->rep = NULL; return -ENOMEM; } err = __tipc_nl_compat_dumpit(cmd, msg, arg); - if (err) + if (err) { kfree_skb(msg->rep); - + msg->rep = NULL; + } kfree_skb(arg); return err; @@ -1215,7 +1217,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info) return err; } -static struct genl_ops tipc_genl_compat_ops[] = { +static const struct genl_ops tipc_genl_compat_ops[] = { { .cmd = TIPC_GENL_CMD, .doit = tipc_nl_compat_recv, diff --git a/net/tipc/node.c b/net/tipc/node.c index aeef8011ac7d82d828289f4085efe3acaa8a3945..198dbc7adbe126cdb00d8e4508ff47a250f5b2f4 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -1126,8 +1126,8 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr, strncpy(linkname, tipc_link_name(link), len); err = 0; } -exit: tipc_node_read_unlock(node); +exit: tipc_node_put(node); return err; } @@ -1284,7 +1284,7 @@ static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr, rc = tipc_bcast_sync_rcv(n->net, n->bc_entry.link, hdr); if (rc & TIPC_LINK_DOWN_EVT) { - tipc_bearer_reset_all(n->net); + tipc_node_reset_links(n); return; } @@ -1351,15 +1351,9 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id if (!skb_queue_empty(&be->inputq1)) tipc_node_mcast_rcv(n); - if (rc & TIPC_LINK_DOWN_EVT) { - /* Reception reassembly failure => reset all links to peer */ - if (!tipc_link_is_up(be->link)) - tipc_node_reset_links(n); - - /* Retransmission failure => reset all links to all peers */ - if (!tipc_link_is_up(tipc_bc_sndlink(net))) - tipc_bearer_reset_all(net); - } + /* If reassembly or retransmission failure => reset all links to peer */ + if (rc & TIPC_LINK_DOWN_EVT) + tipc_node_reset_links(n); tipc_node_put(n); } @@ -1455,10 +1449,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, /* Initiate synch mode if applicable */ if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) { syncpt = iseqno + exp_pkts - 1; - if (!tipc_link_is_up(l)) { - tipc_link_fsm_evt(l, LINK_ESTABLISH_EVT); + if (!tipc_link_is_up(l)) __tipc_node_link_up(n, bearer_id, xmitq); - } if (n->state == SELF_UP_PEER_UP) { n->sync_point = syncpt; tipc_link_fsm_evt(l, LINK_SYNCH_BEGIN_EVT); @@ -1559,6 +1551,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) /* Check/update node state before receiving */ if (unlikely(skb)) { + if (unlikely(skb_linearize(skb))) + goto discard; tipc_node_write_lock(n); if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { if (le->link) { diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 101e3597338f7c1e182c9090af0d14caf5be1b8b..d50edd6e00196af04ee7a4011d6339b100cb3537 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2255,8 +2255,8 @@ void tipc_sk_reinit(struct net *net) do { tsk = ERR_PTR(rhashtable_walk_start(&iter)); - if (tsk) - continue; + if (IS_ERR(tsk)) + goto walk_stop; while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { spin_lock_bh(&tsk->sk.sk_lock.slock); @@ -2265,7 +2265,7 @@ void tipc_sk_reinit(struct net *net) msg_set_orignode(msg, tn->own_addr); spin_unlock_bh(&tsk->sk.sk_lock.slock); } - +walk_stop: rhashtable_walk_stop(&iter); } while (tsk == ERR_PTR(-EAGAIN)); } diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 0bf91cd3733cb37ecc8ba4ccf7ae5a26cb6e966d..be3d9e3183dcb1ce929584a074755c1ce0969d0f 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -52,7 +52,6 @@ struct tipc_subscriber { struct list_head subscrp_list; }; -static void tipc_subscrp_delete(struct tipc_subscription *sub); static void tipc_subscrb_put(struct tipc_subscriber *subscriber); /** @@ -197,15 +196,19 @@ static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber, { struct list_head *subscription_list = &subscriber->subscrp_list; struct tipc_subscription *sub, *temp; + u32 timeout; spin_lock_bh(&subscriber->lock); list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) { if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) continue; - tipc_nametbl_unsubscribe(sub); - list_del(&sub->subscrp_list); - tipc_subscrp_delete(sub); + timeout = htohl(sub->evt.s.timeout, sub->swap); + if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) { + tipc_nametbl_unsubscribe(sub); + list_del(&sub->subscrp_list); + tipc_subscrp_put(sub); + } if (s) break; @@ -236,18 +239,12 @@ static void tipc_subscrb_delete(struct tipc_subscriber *subscriber) tipc_subscrb_put(subscriber); } -static void tipc_subscrp_delete(struct tipc_subscription *sub) -{ - u32 timeout = htohl(sub->evt.s.timeout, sub->swap); - - if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) - tipc_subscrp_put(sub); -} - static void tipc_subscrp_cancel(struct tipc_subscr *s, struct tipc_subscriber *subscriber) { + tipc_subscrb_get(subscriber); tipc_subscrb_subscrp_delete(subscriber, s); + tipc_subscrb_put(subscriber); } static struct tipc_subscription *tipc_subscrp_create(struct net *net, diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index fa596fa71ba70678adffb62c3423c7195e3f5a99..7d80040a37b6d54901c05964a2f8a9ab0851a2cb 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -639,7 +639,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page, return ret; } -void tls_sw_free_resources(struct sock *sk) +static void tls_sw_free_resources(struct sock *sk) { struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 7b52a380d710d238c440293b6d3b8973fc30c90c..7f46bab4ce5c84aa285d8141b4e0f822e8dab01f 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1528,26 +1528,13 @@ static inline bool too_many_unix_fds(struct task_struct *p) return false; } -#define MAX_RECURSION_LEVEL 4 - static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) { int i; - unsigned char max_level = 0; if (too_many_unix_fds(current)) return -ETOOMANYREFS; - for (i = scm->fp->count - 1; i >= 0; i--) { - struct sock *sk = unix_get_socket(scm->fp->fp[i]); - - if (sk) - max_level = max(max_level, - unix_sk(sk)->recursion_level); - } - if (unlikely(max_level > MAX_RECURSION_LEVEL)) - return -ETOOMANYREFS; - /* * Need to duplicate file references for the sake of garbage * collection. Otherwise a socket in the fps might become a @@ -1559,7 +1546,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) for (i = scm->fp->count - 1; i >= 0; i--) unix_inflight(scm->fp->user, scm->fp->fp[i]); - return max_level; + return 0; } static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) @@ -1649,7 +1636,6 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, struct sk_buff *skb; long timeo; struct scm_cookie scm; - int max_level; int data_len = 0; int sk_locked; @@ -1701,7 +1687,6 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, err = unix_scm_to_skb(&scm, skb, true); if (err < 0) goto out_free; - max_level = err + 1; skb_put(skb, len - data_len); skb->data_len = data_len; @@ -1819,8 +1804,6 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, __net_timestamp(skb); maybe_add_creds(skb, sock, other); skb_queue_tail(&other->sk_receive_queue, skb); - if (max_level > unix_sk(other)->recursion_level) - unix_sk(other)->recursion_level = max_level; unix_state_unlock(other); other->sk_data_ready(other); sock_put(other); @@ -1855,7 +1838,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, int sent = 0; struct scm_cookie scm; bool fds_sent = false; - int max_level; int data_len; wait_for_unix_gc(); @@ -1905,7 +1887,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, kfree_skb(skb); goto out_err; } - max_level = err + 1; fds_sent = true; skb_put(skb, size - data_len); @@ -1925,8 +1906,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, maybe_add_creds(skb, sock, other); skb_queue_tail(&other->sk_receive_queue, skb); - if (max_level > unix_sk(other)->recursion_level) - unix_sk(other)->recursion_level = max_level; unix_state_unlock(other); other->sk_data_ready(other); sent += size; @@ -2304,10 +2283,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, */ mutex_lock(&u->iolock); - if (flags & MSG_PEEK) - skip = sk_peek_offset(sk, flags); - else - skip = 0; + skip = max(sk_peek_offset(sk, flags), 0); do { int chunk; @@ -2324,7 +2300,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, last_len = last ? last->len : 0; again: if (skb == NULL) { - unix_sk(sk)->recursion_level = 0; if (copied >= target) goto unlock; diff --git a/net/vmw_vsock/Kconfig b/net/vmw_vsock/Kconfig index 8831e7c421672ec5775377748b940793f4f879b1..a24369d175fd6564fadcc56fd3d21e740c9eabc1 100644 --- a/net/vmw_vsock/Kconfig +++ b/net/vmw_vsock/Kconfig @@ -46,3 +46,15 @@ config VIRTIO_VSOCKETS_COMMON This option is selected by any driver which needs to access the virtio_vsock. The module will be called vmw_vsock_virtio_transport_common. + +config HYPERV_VSOCKETS + tristate "Hyper-V transport for Virtual Sockets" + depends on VSOCKETS && HYPERV + help + This module implements a Hyper-V transport for Virtual Sockets. + + Enable this transport if your Virtual Machine host supports Virtual + Sockets over Hyper-V VMBus. + + To compile this driver as a module, choose M here: the module will be + called hv_sock. If unsure, say N. diff --git a/net/vmw_vsock/Makefile b/net/vmw_vsock/Makefile index 09fc2eb29dc88898f631bfdf3e747bf16fbe4462..e63d574234a98974be767ae9b3a081cf4949d7ff 100644 --- a/net/vmw_vsock/Makefile +++ b/net/vmw_vsock/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_VSOCKETS) += vsock.o obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o obj-$(CONFIG_VIRTIO_VSOCKETS) += vmw_vsock_virtio_transport.o obj-$(CONFIG_VIRTIO_VSOCKETS_COMMON) += vmw_vsock_virtio_transport_common.o +obj-$(CONFIG_HYPERV_VSOCKETS) += hv_sock.o vsock-y += af_vsock.o af_vsock_tap.o vsock_addr.o @@ -11,3 +12,5 @@ vmw_vsock_vmci_transport-y += vmci_transport.o vmci_transport_notify.o \ vmw_vsock_virtio_transport-y += virtio_transport.o vmw_vsock_virtio_transport_common-y += virtio_transport_common.o + +hv_sock-y += hyperv_transport.o diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c new file mode 100644 index 0000000000000000000000000000000000000000..14ed5a344cdf302ba3f2d8e9dec4fb7c66fdd239 --- /dev/null +++ b/net/vmw_vsock/hyperv_transport.c @@ -0,0 +1,904 @@ +/* + * Hyper-V transport for vsock + * + * Hyper-V Sockets supplies a byte-stream based communication mechanism + * between the host and the VM. This driver implements the necessary + * support in the VM by introducing the new vsock transport. + * + * Copyright (c) 2017, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#include +#include +#include +#include +#include + +/* The host side's design of the feature requires 6 exact 4KB pages for + * recv/send rings respectively -- this is suboptimal considering memory + * consumption, however unluckily we have to live with it, before the + * host comes up with a better design in the future. + */ +#define PAGE_SIZE_4K 4096 +#define RINGBUFFER_HVS_RCV_SIZE (PAGE_SIZE_4K * 6) +#define RINGBUFFER_HVS_SND_SIZE (PAGE_SIZE_4K * 6) + +/* The MTU is 16KB per the host side's design */ +#define HVS_MTU_SIZE (1024 * 16) + +struct vmpipe_proto_header { + u32 pkt_type; + u32 data_size; +}; + +/* For recv, we use the VMBus in-place packet iterator APIs to directly copy + * data from the ringbuffer into the userspace buffer. + */ +struct hvs_recv_buf { + /* The header before the payload data */ + struct vmpipe_proto_header hdr; + + /* The payload */ + u8 data[HVS_MTU_SIZE]; +}; + +/* We can send up to HVS_MTU_SIZE bytes of payload to the host, but let's use + * a small size, i.e. HVS_SEND_BUF_SIZE, to minimize the dynamically-allocated + * buffer, because tests show there is no significant performance difference. + * + * Note: the buffer can be eliminated in the future when we add new VMBus + * ringbuffer APIs that allow us to directly copy data from userspace buffer + * to VMBus ringbuffer. + */ +#define HVS_SEND_BUF_SIZE (PAGE_SIZE_4K - sizeof(struct vmpipe_proto_header)) + +struct hvs_send_buf { + /* The header before the payload data */ + struct vmpipe_proto_header hdr; + + /* The payload */ + u8 data[HVS_SEND_BUF_SIZE]; +}; + +#define HVS_HEADER_LEN (sizeof(struct vmpacket_descriptor) + \ + sizeof(struct vmpipe_proto_header)) + +/* See 'prev_indices' in hv_ringbuffer_read(), hv_ringbuffer_write(), and + * __hv_pkt_iter_next(). + */ +#define VMBUS_PKT_TRAILER_SIZE (sizeof(u64)) + +#define HVS_PKT_LEN(payload_len) (HVS_HEADER_LEN + \ + ALIGN((payload_len), 8) + \ + VMBUS_PKT_TRAILER_SIZE) + +union hvs_service_id { + uuid_le srv_id; + + struct { + unsigned int svm_port; + unsigned char b[sizeof(uuid_le) - sizeof(unsigned int)]; + }; +}; + +/* Per-socket state (accessed via vsk->trans) */ +struct hvsock { + struct vsock_sock *vsk; + + uuid_le vm_srv_id; + uuid_le host_srv_id; + + struct vmbus_channel *chan; + struct vmpacket_descriptor *recv_desc; + + /* The length of the payload not delivered to userland yet */ + u32 recv_data_len; + /* The offset of the payload */ + u32 recv_data_off; + + /* Have we sent the zero-length packet (FIN)? */ + bool fin_sent; +}; + +/* In the VM, we support Hyper-V Sockets with AF_VSOCK, and the endpoint is + * (see struct sockaddr_vm). Note: cid is not really used here: + * when we write apps to connect to the host, we can only use VMADDR_CID_ANY + * or VMADDR_CID_HOST (both are equivalent) as the remote cid, and when we + * write apps to bind() & listen() in the VM, we can only use VMADDR_CID_ANY + * as the local cid. + * + * On the host, Hyper-V Sockets are supported by Winsock AF_HYPERV: + * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user- + * guide/make-integration-service, and the endpoint is with + * the below sockaddr: + * + * struct SOCKADDR_HV + * { + * ADDRESS_FAMILY Family; + * USHORT Reserved; + * GUID VmId; + * GUID ServiceId; + * }; + * Note: VmID is not used by Linux VM and actually it isn't transmitted via + * VMBus, because here it's obvious the host and the VM can easily identify + * each other. Though the VmID is useful on the host, especially in the case + * of Windows container, Linux VM doesn't need it at all. + * + * To make use of the AF_VSOCK infrastructure in Linux VM, we have to limit + * the available GUID space of SOCKADDR_HV so that we can create a mapping + * between AF_VSOCK port and SOCKADDR_HV Service GUID. The rule of writing + * Hyper-V Sockets apps on the host and in Linux VM is: + * + **************************************************************************** + * The only valid Service GUIDs, from the perspectives of both the host and * + * Linux VM, that can be connected by the other end, must conform to this * + * format: -facb-11e6-bd58-64006a7986d3, and the "port" must be in * + * this range [0, 0x7FFFFFFF]. * + **************************************************************************** + * + * When we write apps on the host to connect(), the GUID ServiceID is used. + * When we write apps in Linux VM to connect(), we only need to specify the + * port and the driver will form the GUID and use that to request the host. + * + * From the perspective of Linux VM: + * 1. the local ephemeral port (i.e. the local auto-bound port when we call + * connect() without explicit bind()) is generated by __vsock_bind_stream(), + * and the range is [1024, 0xFFFFFFFF). + * 2. the remote ephemeral port (i.e. the auto-generated remote port for + * a connect request initiated by the host's connect()) is generated by + * hvs_remote_addr_init() and the range is [0x80000000, 0xFFFFFFFF). + */ + +#define MAX_LISTEN_PORT ((u32)0x7FFFFFFF) +#define MAX_VM_LISTEN_PORT MAX_LISTEN_PORT +#define MAX_HOST_LISTEN_PORT MAX_LISTEN_PORT +#define MIN_HOST_EPHEMERAL_PORT (MAX_HOST_LISTEN_PORT + 1) + +/* 00000000-facb-11e6-bd58-64006a7986d3 */ +static const uuid_le srv_id_template = + UUID_LE(0x00000000, 0xfacb, 0x11e6, 0xbd, 0x58, + 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3); + +static bool is_valid_srv_id(const uuid_le *id) +{ + return !memcmp(&id->b[4], &srv_id_template.b[4], sizeof(uuid_le) - 4); +} + +static unsigned int get_port_by_srv_id(const uuid_le *svr_id) +{ + return *((unsigned int *)svr_id); +} + +static void hvs_addr_init(struct sockaddr_vm *addr, const uuid_le *svr_id) +{ + unsigned int port = get_port_by_srv_id(svr_id); + + vsock_addr_init(addr, VMADDR_CID_ANY, port); +} + +static void hvs_remote_addr_init(struct sockaddr_vm *remote, + struct sockaddr_vm *local) +{ + static u32 host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT; + struct sock *sk; + + vsock_addr_init(remote, VMADDR_CID_ANY, VMADDR_PORT_ANY); + + while (1) { + /* Wrap around ? */ + if (host_ephemeral_port < MIN_HOST_EPHEMERAL_PORT || + host_ephemeral_port == VMADDR_PORT_ANY) + host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT; + + remote->svm_port = host_ephemeral_port++; + + sk = vsock_find_connected_socket(remote, local); + if (!sk) { + /* Found an available ephemeral port */ + return; + } + + /* Release refcnt got in vsock_find_connected_socket */ + sock_put(sk); + } +} + +static void hvs_set_channel_pending_send_size(struct vmbus_channel *chan) +{ + set_channel_pending_send_size(chan, + HVS_PKT_LEN(HVS_SEND_BUF_SIZE)); + + /* See hvs_stream_has_space(): we must make sure the host has seen + * the new pending send size, before we can re-check the writable + * bytes. + */ + virt_mb(); +} + +static void hvs_clear_channel_pending_send_size(struct vmbus_channel *chan) +{ + set_channel_pending_send_size(chan, 0); + + /* Ditto */ + virt_mb(); +} + +static bool hvs_channel_readable(struct vmbus_channel *chan) +{ + u32 readable = hv_get_bytes_to_read(&chan->inbound); + + /* 0-size payload means FIN */ + return readable >= HVS_PKT_LEN(0); +} + +static int hvs_channel_readable_payload(struct vmbus_channel *chan) +{ + u32 readable = hv_get_bytes_to_read(&chan->inbound); + + if (readable > HVS_PKT_LEN(0)) { + /* At least we have 1 byte to read. We don't need to return + * the exact readable bytes: see vsock_stream_recvmsg() -> + * vsock_stream_has_data(). + */ + return 1; + } + + if (readable == HVS_PKT_LEN(0)) { + /* 0-size payload means FIN */ + return 0; + } + + /* No payload or FIN */ + return -1; +} + +static size_t hvs_channel_writable_bytes(struct vmbus_channel *chan) +{ + u32 writeable = hv_get_bytes_to_write(&chan->outbound); + size_t ret; + + /* The ringbuffer mustn't be 100% full, and we should reserve a + * zero-length-payload packet for the FIN: see hv_ringbuffer_write() + * and hvs_shutdown(). + */ + if (writeable <= HVS_PKT_LEN(1) + HVS_PKT_LEN(0)) + return 0; + + ret = writeable - HVS_PKT_LEN(1) - HVS_PKT_LEN(0); + + return round_down(ret, 8); +} + +static int hvs_send_data(struct vmbus_channel *chan, + struct hvs_send_buf *send_buf, size_t to_write) +{ + send_buf->hdr.pkt_type = 1; + send_buf->hdr.data_size = to_write; + return vmbus_sendpacket(chan, &send_buf->hdr, + sizeof(send_buf->hdr) + to_write, + 0, VM_PKT_DATA_INBAND, 0); +} + +static void hvs_channel_cb(void *ctx) +{ + struct sock *sk = (struct sock *)ctx; + struct vsock_sock *vsk = vsock_sk(sk); + struct hvsock *hvs = vsk->trans; + struct vmbus_channel *chan = hvs->chan; + + if (hvs_channel_readable(chan)) + sk->sk_data_ready(sk); + + /* See hvs_stream_has_space(): when we reach here, the writable bytes + * may be already less than HVS_PKT_LEN(HVS_SEND_BUF_SIZE). + */ + if (hv_get_bytes_to_write(&chan->outbound) > 0) + sk->sk_write_space(sk); +} + +static void hvs_close_connection(struct vmbus_channel *chan) +{ + struct sock *sk = get_per_channel_state(chan); + struct vsock_sock *vsk = vsock_sk(sk); + + sk->sk_state = SS_UNCONNECTED; + sock_set_flag(sk, SOCK_DONE); + vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN; + + sk->sk_state_change(sk); +} + +static void hvs_open_connection(struct vmbus_channel *chan) +{ + uuid_le *if_instance, *if_type; + unsigned char conn_from_host; + + struct sockaddr_vm addr; + struct sock *sk, *new = NULL; + struct vsock_sock *vnew; + struct hvsock *hvs, *hvs_new; + int ret; + + if_type = &chan->offermsg.offer.if_type; + if_instance = &chan->offermsg.offer.if_instance; + conn_from_host = chan->offermsg.offer.u.pipe.user_def[0]; + + /* The host or the VM should only listen on a port in + * [0, MAX_LISTEN_PORT] + */ + if (!is_valid_srv_id(if_type) || + get_port_by_srv_id(if_type) > MAX_LISTEN_PORT) + return; + + hvs_addr_init(&addr, conn_from_host ? if_type : if_instance); + sk = vsock_find_bound_socket(&addr); + if (!sk) + return; + + if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) || + (!conn_from_host && sk->sk_state != SS_CONNECTING)) + goto out; + + if (conn_from_host) { + if (sk->sk_ack_backlog >= sk->sk_max_ack_backlog) + goto out; + + new = __vsock_create(sock_net(sk), NULL, sk, GFP_KERNEL, + sk->sk_type, 0); + if (!new) + goto out; + + new->sk_state = SS_CONNECTING; + vnew = vsock_sk(new); + hvs_new = vnew->trans; + hvs_new->chan = chan; + } else { + hvs = vsock_sk(sk)->trans; + hvs->chan = chan; + } + + set_channel_read_mode(chan, HV_CALL_DIRECT); + ret = vmbus_open(chan, RINGBUFFER_HVS_SND_SIZE, + RINGBUFFER_HVS_RCV_SIZE, NULL, 0, + hvs_channel_cb, conn_from_host ? new : sk); + if (ret != 0) { + if (conn_from_host) { + hvs_new->chan = NULL; + sock_put(new); + } else { + hvs->chan = NULL; + } + goto out; + } + + set_per_channel_state(chan, conn_from_host ? new : sk); + vmbus_set_chn_rescind_callback(chan, hvs_close_connection); + + if (conn_from_host) { + new->sk_state = SS_CONNECTED; + sk->sk_ack_backlog++; + + hvs_addr_init(&vnew->local_addr, if_type); + hvs_remote_addr_init(&vnew->remote_addr, &vnew->local_addr); + + hvs_new->vm_srv_id = *if_type; + hvs_new->host_srv_id = *if_instance; + + vsock_insert_connected(vnew); + + lock_sock(sk); + vsock_enqueue_accept(sk, new); + release_sock(sk); + } else { + sk->sk_state = SS_CONNECTED; + sk->sk_socket->state = SS_CONNECTED; + + vsock_insert_connected(vsock_sk(sk)); + } + + sk->sk_state_change(sk); + +out: + /* Release refcnt obtained when we called vsock_find_bound_socket() */ + sock_put(sk); +} + +static u32 hvs_get_local_cid(void) +{ + return VMADDR_CID_ANY; +} + +static int hvs_sock_init(struct vsock_sock *vsk, struct vsock_sock *psk) +{ + struct hvsock *hvs; + + hvs = kzalloc(sizeof(*hvs), GFP_KERNEL); + if (!hvs) + return -ENOMEM; + + vsk->trans = hvs; + hvs->vsk = vsk; + + return 0; +} + +static int hvs_connect(struct vsock_sock *vsk) +{ + union hvs_service_id vm, host; + struct hvsock *h = vsk->trans; + + vm.srv_id = srv_id_template; + vm.svm_port = vsk->local_addr.svm_port; + h->vm_srv_id = vm.srv_id; + + host.srv_id = srv_id_template; + host.svm_port = vsk->remote_addr.svm_port; + h->host_srv_id = host.srv_id; + + return vmbus_send_tl_connect_request(&h->vm_srv_id, &h->host_srv_id); +} + +static int hvs_shutdown(struct vsock_sock *vsk, int mode) +{ + struct sock *sk = sk_vsock(vsk); + struct vmpipe_proto_header hdr; + struct hvs_send_buf *send_buf; + struct hvsock *hvs; + + if (!(mode & SEND_SHUTDOWN)) + return 0; + + lock_sock(sk); + + hvs = vsk->trans; + if (hvs->fin_sent) + goto out; + + send_buf = (struct hvs_send_buf *)&hdr; + + /* It can't fail: see hvs_channel_writable_bytes(). */ + (void)hvs_send_data(hvs->chan, send_buf, 0); + + hvs->fin_sent = true; +out: + release_sock(sk); + return 0; +} + +static void hvs_release(struct vsock_sock *vsk) +{ + struct hvsock *hvs = vsk->trans; + struct vmbus_channel *chan = hvs->chan; + + if (chan) + hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN); + + vsock_remove_sock(vsk); +} + +static void hvs_destruct(struct vsock_sock *vsk) +{ + struct hvsock *hvs = vsk->trans; + struct vmbus_channel *chan = hvs->chan; + + if (chan) + vmbus_hvsock_device_unregister(chan); + + kfree(hvs); +} + +static int hvs_dgram_bind(struct vsock_sock *vsk, struct sockaddr_vm *addr) +{ + return -EOPNOTSUPP; +} + +static int hvs_dgram_dequeue(struct vsock_sock *vsk, struct msghdr *msg, + size_t len, int flags) +{ + return -EOPNOTSUPP; +} + +static int hvs_dgram_enqueue(struct vsock_sock *vsk, + struct sockaddr_vm *remote, struct msghdr *msg, + size_t dgram_len) +{ + return -EOPNOTSUPP; +} + +static bool hvs_dgram_allow(u32 cid, u32 port) +{ + return false; +} + +static int hvs_update_recv_data(struct hvsock *hvs) +{ + struct hvs_recv_buf *recv_buf; + u32 payload_len; + + recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1); + payload_len = recv_buf->hdr.data_size; + + if (payload_len > HVS_MTU_SIZE) + return -EIO; + + if (payload_len == 0) + hvs->vsk->peer_shutdown |= SEND_SHUTDOWN; + + hvs->recv_data_len = payload_len; + hvs->recv_data_off = 0; + + return 0; +} + +static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg, + size_t len, int flags) +{ + struct hvsock *hvs = vsk->trans; + bool need_refill = !hvs->recv_desc; + struct hvs_recv_buf *recv_buf; + u32 to_read; + int ret; + + if (flags & MSG_PEEK) + return -EOPNOTSUPP; + + if (need_refill) { + hvs->recv_desc = hv_pkt_iter_first(hvs->chan); + ret = hvs_update_recv_data(hvs); + if (ret) + return ret; + } + + recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1); + to_read = min_t(u32, len, hvs->recv_data_len); + ret = memcpy_to_msg(msg, recv_buf->data + hvs->recv_data_off, to_read); + if (ret != 0) + return ret; + + hvs->recv_data_len -= to_read; + if (hvs->recv_data_len == 0) { + hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc); + if (hvs->recv_desc) { + ret = hvs_update_recv_data(hvs); + if (ret) + return ret; + } + } else { + hvs->recv_data_off += to_read; + } + + return to_read; +} + +static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg, + size_t len) +{ + struct hvsock *hvs = vsk->trans; + struct vmbus_channel *chan = hvs->chan; + struct hvs_send_buf *send_buf; + ssize_t to_write, max_writable, ret; + + BUILD_BUG_ON(sizeof(*send_buf) != PAGE_SIZE_4K); + + send_buf = kmalloc(sizeof(*send_buf), GFP_KERNEL); + if (!send_buf) + return -ENOMEM; + + max_writable = hvs_channel_writable_bytes(chan); + to_write = min_t(ssize_t, len, max_writable); + to_write = min_t(ssize_t, to_write, HVS_SEND_BUF_SIZE); + + ret = memcpy_from_msg(send_buf->data, msg, to_write); + if (ret < 0) + goto out; + + ret = hvs_send_data(hvs->chan, send_buf, to_write); + if (ret < 0) + goto out; + + ret = to_write; +out: + kfree(send_buf); + return ret; +} + +static s64 hvs_stream_has_data(struct vsock_sock *vsk) +{ + struct hvsock *hvs = vsk->trans; + s64 ret; + + if (hvs->recv_data_len > 0) + return 1; + + switch (hvs_channel_readable_payload(hvs->chan)) { + case 1: + ret = 1; + break; + case 0: + vsk->peer_shutdown |= SEND_SHUTDOWN; + ret = 0; + break; + default: /* -1 */ + ret = 0; + break; + } + + return ret; +} + +static s64 hvs_stream_has_space(struct vsock_sock *vsk) +{ + struct hvsock *hvs = vsk->trans; + struct vmbus_channel *chan = hvs->chan; + s64 ret; + + ret = hvs_channel_writable_bytes(chan); + if (ret > 0) { + hvs_clear_channel_pending_send_size(chan); + } else { + /* See hvs_channel_cb() */ + hvs_set_channel_pending_send_size(chan); + + /* Re-check the writable bytes to avoid race */ + ret = hvs_channel_writable_bytes(chan); + if (ret > 0) + hvs_clear_channel_pending_send_size(chan); + } + + return ret; +} + +static u64 hvs_stream_rcvhiwat(struct vsock_sock *vsk) +{ + return HVS_MTU_SIZE + 1; +} + +static bool hvs_stream_is_active(struct vsock_sock *vsk) +{ + struct hvsock *hvs = vsk->trans; + + return hvs->chan != NULL; +} + +static bool hvs_stream_allow(u32 cid, u32 port) +{ + /* The host's port range [MIN_HOST_EPHEMERAL_PORT, 0xFFFFFFFF) is + * reserved as ephemeral ports, which are used as the host's ports + * when the host initiates connections. + * + * Perform this check in the guest so an immediate error is produced + * instead of a timeout. + */ + if (port > MAX_HOST_LISTEN_PORT) + return false; + + if (cid == VMADDR_CID_HOST) + return true; + + return false; +} + +static +int hvs_notify_poll_in(struct vsock_sock *vsk, size_t target, bool *readable) +{ + struct hvsock *hvs = vsk->trans; + + *readable = hvs_channel_readable(hvs->chan); + return 0; +} + +static +int hvs_notify_poll_out(struct vsock_sock *vsk, size_t target, bool *writable) +{ + *writable = hvs_stream_has_space(vsk) > 0; + + return 0; +} + +static +int hvs_notify_recv_init(struct vsock_sock *vsk, size_t target, + struct vsock_transport_recv_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_recv_pre_block(struct vsock_sock *vsk, size_t target, + struct vsock_transport_recv_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_recv_pre_dequeue(struct vsock_sock *vsk, size_t target, + struct vsock_transport_recv_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_recv_post_dequeue(struct vsock_sock *vsk, size_t target, + ssize_t copied, bool data_read, + struct vsock_transport_recv_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_send_init(struct vsock_sock *vsk, + struct vsock_transport_send_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_send_pre_block(struct vsock_sock *vsk, + struct vsock_transport_send_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_send_pre_enqueue(struct vsock_sock *vsk, + struct vsock_transport_send_notify_data *d) +{ + return 0; +} + +static +int hvs_notify_send_post_enqueue(struct vsock_sock *vsk, ssize_t written, + struct vsock_transport_send_notify_data *d) +{ + return 0; +} + +static void hvs_set_buffer_size(struct vsock_sock *vsk, u64 val) +{ + /* Ignored. */ +} + +static void hvs_set_min_buffer_size(struct vsock_sock *vsk, u64 val) +{ + /* Ignored. */ +} + +static void hvs_set_max_buffer_size(struct vsock_sock *vsk, u64 val) +{ + /* Ignored. */ +} + +static u64 hvs_get_buffer_size(struct vsock_sock *vsk) +{ + return -ENOPROTOOPT; +} + +static u64 hvs_get_min_buffer_size(struct vsock_sock *vsk) +{ + return -ENOPROTOOPT; +} + +static u64 hvs_get_max_buffer_size(struct vsock_sock *vsk) +{ + return -ENOPROTOOPT; +} + +static struct vsock_transport hvs_transport = { + .get_local_cid = hvs_get_local_cid, + + .init = hvs_sock_init, + .destruct = hvs_destruct, + .release = hvs_release, + .connect = hvs_connect, + .shutdown = hvs_shutdown, + + .dgram_bind = hvs_dgram_bind, + .dgram_dequeue = hvs_dgram_dequeue, + .dgram_enqueue = hvs_dgram_enqueue, + .dgram_allow = hvs_dgram_allow, + + .stream_dequeue = hvs_stream_dequeue, + .stream_enqueue = hvs_stream_enqueue, + .stream_has_data = hvs_stream_has_data, + .stream_has_space = hvs_stream_has_space, + .stream_rcvhiwat = hvs_stream_rcvhiwat, + .stream_is_active = hvs_stream_is_active, + .stream_allow = hvs_stream_allow, + + .notify_poll_in = hvs_notify_poll_in, + .notify_poll_out = hvs_notify_poll_out, + .notify_recv_init = hvs_notify_recv_init, + .notify_recv_pre_block = hvs_notify_recv_pre_block, + .notify_recv_pre_dequeue = hvs_notify_recv_pre_dequeue, + .notify_recv_post_dequeue = hvs_notify_recv_post_dequeue, + .notify_send_init = hvs_notify_send_init, + .notify_send_pre_block = hvs_notify_send_pre_block, + .notify_send_pre_enqueue = hvs_notify_send_pre_enqueue, + .notify_send_post_enqueue = hvs_notify_send_post_enqueue, + + .set_buffer_size = hvs_set_buffer_size, + .set_min_buffer_size = hvs_set_min_buffer_size, + .set_max_buffer_size = hvs_set_max_buffer_size, + .get_buffer_size = hvs_get_buffer_size, + .get_min_buffer_size = hvs_get_min_buffer_size, + .get_max_buffer_size = hvs_get_max_buffer_size, +}; + +static int hvs_probe(struct hv_device *hdev, + const struct hv_vmbus_device_id *dev_id) +{ + struct vmbus_channel *chan = hdev->channel; + + hvs_open_connection(chan); + + /* Always return success to suppress the unnecessary error message + * in vmbus_probe(): on error the host will rescind the device in + * 30 seconds and we can do cleanup at that time in + * vmbus_onoffer_rescind(). + */ + return 0; +} + +static int hvs_remove(struct hv_device *hdev) +{ + struct vmbus_channel *chan = hdev->channel; + + vmbus_close(chan); + + return 0; +} + +/* This isn't really used. See vmbus_match() and vmbus_probe() */ +static const struct hv_vmbus_device_id id_table[] = { + {}, +}; + +static struct hv_driver hvs_drv = { + .name = "hv_sock", + .hvsock = true, + .id_table = id_table, + .probe = hvs_probe, + .remove = hvs_remove, +}; + +static int __init hvs_init(void) +{ + int ret; + + if (vmbus_proto_version < VERSION_WIN10) + return -ENODEV; + + ret = vmbus_driver_register(&hvs_drv); + if (ret != 0) + return ret; + + ret = vsock_core_init(&hvs_transport); + if (ret) { + vmbus_driver_unregister(&hvs_drv); + return ret; + } + + return 0; +} + +static void __exit hvs_exit(void) +{ + vsock_core_exit(); + vmbus_driver_unregister(&hvs_drv); +} + +module_init(hvs_init); +module_exit(hvs_exit); + +MODULE_DESCRIPTION("Hyper-V Sockets"); +MODULE_VERSION("1.0.0"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_VSOCK); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8ce85420ecb0a7e45567c9c576c6bb9691eb267d..690874293cfc6103a08eecf096a94184f36868f9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3791,8 +3791,8 @@ static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params, static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params) { const struct cfg80211_beacon_data *bcn = ¶ms->beacon; - size_t ies_len = bcn->beacon_ies_len; - const u8 *ies = bcn->beacon_ies; + size_t ies_len = bcn->tail_len; + const u8 *ies = bcn->tail; const u8 *rates; const u8 *cap; @@ -9987,6 +9987,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) if (err) return err; + if (!setup.chandef.chan) + return -EINVAL; + err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band, &setup.beacon_rate); if (err) @@ -10903,6 +10906,9 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) if (err) return err; + if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] || + !tb[NL80211_REKEY_DATA_KCK]) + return -EINVAL; if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN) return -ERANGE; if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 5fae296a6a583256f9874319dfaa9ee87e977fff..6e94f6934a0e7a47fbac086586701d07c9bb5487 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -4,6 +4,7 @@ * Copyright 2007 Johannes Berg * Copyright 2008-2011 Luis R. Rodriguez * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright 2017 Intel Deutschland GmbH * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy, { struct ieee80211_supported_band *sband = wiphy->bands[channel->band]; struct ieee80211_channel *channel_before = NULL, *channel_after = NULL; + const struct ieee80211_regdomain *regd; unsigned int i; + u32 flags; if (!is_ht40_allowed(channel)) { channel->flags |= IEEE80211_CHAN_NO_HT40; @@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy, channel_after = c; } + flags = 0; + regd = get_wiphy_regdom(wiphy); + if (regd) { + const struct ieee80211_reg_rule *reg_rule = + freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq), + regd, MHZ_TO_KHZ(20)); + + if (!IS_ERR(reg_rule)) + flags = reg_rule->flags; + } + /* * Please note that this assumes target bandwidth is 20 MHz, * if that ever changes we also need to change the below logic * to include that as well. */ - if (!is_ht40_allowed(channel_before)) + if (!is_ht40_allowed(channel_before) || + flags & NL80211_RRF_NO_HT40MINUS) channel->flags |= IEEE80211_CHAN_NO_HT40MINUS; else channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; - if (!is_ht40_allowed(channel_after)) + if (!is_ht40_allowed(channel_after) || + flags & NL80211_RRF_NO_HT40PLUS) channel->flags |= IEEE80211_CHAN_NO_HT40PLUS; else channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 5a1a98df3499841172f47b71418f95d9558158d0..ac095936552d945d864facdb6b7bacd48655b47f 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -74,7 +74,7 @@ DEFINE_RWLOCK(x25_list_lock); static const struct proto_ops x25_proto_ops; -static struct x25_address null_x25_address = {" "}; +static const struct x25_address null_x25_address = {" "}; #ifdef CONFIG_COMPAT struct compat_x25_subscrip_struct { diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 5f7e8bfa0c2dca6d811616aa7002b768d1bb51ae..acf00104ef312b563be9f3aa9698fa2a9dbdfea7 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c @@ -63,7 +63,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, xfrm_address_t *daddr; if (!x->type_offload) - return 0; + return -EINVAL; /* We don't yet support UDP encapsulation, TFC padding and ESN. */ if (x->encap || x->tfcpad || (x->props.flags & XFRM_STATE_ESN)) @@ -79,7 +79,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, daddr = &x->props.saddr; } - dst = __xfrm_dst_lookup(net, 0, 0, saddr, daddr, x->props.family); + dst = __xfrm_dst_lookup(net, 0, 0, saddr, daddr, + x->props.family, x->props.output_mark); if (IS_ERR(dst)) return 0; @@ -153,6 +154,7 @@ static int xfrm_dev_register(struct net_device *dev) static int xfrm_dev_unregister(struct net_device *dev) { + xfrm_policy_cache_flush(); return NOTIFY_DONE; } @@ -175,8 +177,7 @@ static int xfrm_dev_down(struct net_device *dev) if (dev->features & NETIF_F_HW_ESP) xfrm_dev_state_flush(dev_net(dev), dev, true); - xfrm_garbage_collect(dev_net(dev)); - + xfrm_policy_cache_flush(); return NOTIFY_DONE; } diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 923205e279f72dbab95cee827987feccc690c678..2515cd2bc5db1a56915856aa5252f2e01592c9e7 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -247,6 +247,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop; } + if (xo->status & CRYPTO_INVALID_PROTOCOL) { + XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR); + goto drop; + } + XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); goto drop; } @@ -424,6 +429,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) nf_reset(skb); if (decaps) { + skb->sp->olen = 0; skb_dst_drop(skb); gro_cells_receive(&gro_cells, skb); return 0; @@ -434,6 +440,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) err = x->inner_mode->afinfo->transport_finish(skb, xfrm_gro || async); if (xfrm_gro) { + skb->sp->olen = 0; skb_dst_drop(skb); gro_cells_receive(&gro_cells, skb); return err; diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 8c0b6722aaa87c6d346d0ba57c2e541a6703c79d..31a2e6d34dba652dd568d93ae077de3136c252ca 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -66,6 +66,9 @@ static int xfrm_output_one(struct sk_buff *skb, int err) goto error_nolock; } + if (x->props.output_mark) + skb->mark = x->props.output_mark; + err = x->outer_mode->output(x, skb); if (err) { XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEMODEERROR); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index ff61d85579292dee8a7f1e9926e11734556f4fd9..f06253969972aa3489e557faf1ef76f54b1eb3d3 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ struct xfrm_flo { u8 flags; }; +static DEFINE_PER_CPU(struct xfrm_dst *, xfrm_last_dst); +static struct work_struct *xfrm_pcpu_work __read_mostly; static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); static struct xfrm_policy_afinfo const __rcu *xfrm_policy_afinfo[AF_INET6 + 1] __read_mostly; @@ -119,7 +122,7 @@ static const struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short fa struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif, const xfrm_address_t *saddr, const xfrm_address_t *daddr, - int family) + int family, u32 mark) { const struct xfrm_policy_afinfo *afinfo; struct dst_entry *dst; @@ -128,7 +131,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif, if (unlikely(afinfo == NULL)) return ERR_PTR(-EAFNOSUPPORT); - dst = afinfo->dst_lookup(net, tos, oif, saddr, daddr); + dst = afinfo->dst_lookup(net, tos, oif, saddr, daddr, mark); rcu_read_unlock(); @@ -140,7 +143,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos, int oif, xfrm_address_t *prev_saddr, xfrm_address_t *prev_daddr, - int family) + int family, u32 mark) { struct net *net = xs_net(x); xfrm_address_t *saddr = &x->props.saddr; @@ -156,7 +159,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, daddr = x->coaddr; } - dst = __xfrm_dst_lookup(net, tos, oif, saddr, daddr, family); + dst = __xfrm_dst_lookup(net, tos, oif, saddr, daddr, family, mark); if (!IS_ERR(dst)) { if (prev_saddr != saddr) @@ -246,36 +249,6 @@ static void xfrm_policy_timer(unsigned long data) xfrm_pol_put(xp); } -static struct flow_cache_object *xfrm_policy_flo_get(struct flow_cache_object *flo) -{ - struct xfrm_policy *pol = container_of(flo, struct xfrm_policy, flo); - - if (unlikely(pol->walk.dead)) - flo = NULL; - else - xfrm_pol_hold(pol); - - return flo; -} - -static int xfrm_policy_flo_check(struct flow_cache_object *flo) -{ - struct xfrm_policy *pol = container_of(flo, struct xfrm_policy, flo); - - return !pol->walk.dead; -} - -static void xfrm_policy_flo_delete(struct flow_cache_object *flo) -{ - xfrm_pol_put(container_of(flo, struct xfrm_policy, flo)); -} - -static const struct flow_cache_ops xfrm_policy_fc_ops = { - .get = xfrm_policy_flo_get, - .check = xfrm_policy_flo_check, - .delete = xfrm_policy_flo_delete, -}; - /* Allocate xfrm_policy. Not used here, it is supposed to be used by pfkeyv2 * SPD calls. */ @@ -298,7 +271,6 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp) (unsigned long)policy); setup_timer(&policy->polq.hold_timer, xfrm_policy_queue_process, (unsigned long)policy); - policy->flo.ops = &xfrm_policy_fc_ops; } return policy; } @@ -798,7 +770,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) else hlist_add_head(&policy->bydst, chain); __xfrm_policy_link(policy, dir); - atomic_inc(&net->xfrm.flow_cache_genid); /* After previous checking, family can either be AF_INET or AF_INET6 */ if (policy->family == AF_INET) @@ -1004,6 +975,8 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid) } if (!cnt) err = -ESRCH; + else + xfrm_policy_cache_flush(); out: spin_unlock_bh(&net->xfrm.xfrm_policy_lock); return err; @@ -1175,7 +1148,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, } static struct xfrm_policy * -__xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir) +xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir) { #ifdef CONFIG_XFRM_SUB_POLICY struct xfrm_policy *pol; @@ -1187,61 +1160,6 @@ __xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir return xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, fl, family, dir); } -static int flow_to_policy_dir(int dir) -{ - if (XFRM_POLICY_IN == FLOW_DIR_IN && - XFRM_POLICY_OUT == FLOW_DIR_OUT && - XFRM_POLICY_FWD == FLOW_DIR_FWD) - return dir; - - switch (dir) { - default: - case FLOW_DIR_IN: - return XFRM_POLICY_IN; - case FLOW_DIR_OUT: - return XFRM_POLICY_OUT; - case FLOW_DIR_FWD: - return XFRM_POLICY_FWD; - } -} - -static struct flow_cache_object * -xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, - u8 dir, struct flow_cache_object *old_obj, void *ctx) -{ - struct xfrm_policy *pol; - - if (old_obj) - xfrm_pol_put(container_of(old_obj, struct xfrm_policy, flo)); - - pol = __xfrm_policy_lookup(net, fl, family, flow_to_policy_dir(dir)); - if (IS_ERR_OR_NULL(pol)) - return ERR_CAST(pol); - - /* Resolver returns two references: - * one for cache and one for caller of flow_cache_lookup() */ - xfrm_pol_hold(pol); - - return &pol->flo; -} - -static inline int policy_to_flow_dir(int dir) -{ - if (XFRM_POLICY_IN == FLOW_DIR_IN && - XFRM_POLICY_OUT == FLOW_DIR_OUT && - XFRM_POLICY_FWD == FLOW_DIR_FWD) - return dir; - switch (dir) { - default: - case XFRM_POLICY_IN: - return FLOW_DIR_IN; - case XFRM_POLICY_OUT: - return FLOW_DIR_OUT; - case XFRM_POLICY_FWD: - return FLOW_DIR_FWD; - } -} - static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, const struct flowi *fl, u16 family) { @@ -1261,7 +1179,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, } err = security_xfrm_policy_lookup(pol->security, fl->flowi_secid, - policy_to_flow_dir(dir)); + dir); if (!err) { if (!xfrm_pol_hold_rcu(pol)) goto again; @@ -1422,14 +1340,14 @@ int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk) static int xfrm_get_saddr(struct net *net, int oif, xfrm_address_t *local, - xfrm_address_t *remote, unsigned short family) + xfrm_address_t *remote, unsigned short family, u32 mark) { int err; const struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); if (unlikely(afinfo == NULL)) return -EINVAL; - err = afinfo->get_saddr(net, oif, local, remote); + err = afinfo->get_saddr(net, oif, local, remote, mark); rcu_read_unlock(); return err; } @@ -1460,7 +1378,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl, if (xfrm_addr_any(local, tmpl->encap_family)) { error = xfrm_get_saddr(net, fl->flowi_oif, &tmp, remote, - tmpl->encap_family); + tmpl->encap_family, 0); if (error) goto fail; local = &tmp; @@ -1545,58 +1463,6 @@ static int xfrm_get_tos(const struct flowi *fl, int family) return tos; } -static struct flow_cache_object *xfrm_bundle_flo_get(struct flow_cache_object *flo) -{ - struct xfrm_dst *xdst = container_of(flo, struct xfrm_dst, flo); - struct dst_entry *dst = &xdst->u.dst; - - if (xdst->route == NULL) { - /* Dummy bundle - if it has xfrms we were not - * able to build bundle as template resolution failed. - * It means we need to try again resolving. */ - if (xdst->num_xfrms > 0) - return NULL; - } else if (dst->flags & DST_XFRM_QUEUE) { - return NULL; - } else { - /* Real bundle */ - if (stale_bundle(dst)) - return NULL; - } - - dst_hold(dst); - return flo; -} - -static int xfrm_bundle_flo_check(struct flow_cache_object *flo) -{ - struct xfrm_dst *xdst = container_of(flo, struct xfrm_dst, flo); - struct dst_entry *dst = &xdst->u.dst; - - if (!xdst->route) - return 0; - if (stale_bundle(dst)) - return 0; - - return 1; -} - -static void xfrm_bundle_flo_delete(struct flow_cache_object *flo) -{ - struct xfrm_dst *xdst = container_of(flo, struct xfrm_dst, flo); - struct dst_entry *dst = &xdst->u.dst; - - /* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */ - dst->obsolete = DST_OBSOLETE_DEAD; - dst_release_immediate(dst); -} - -static const struct flow_cache_ops xfrm_bundle_fc_ops = { - .get = xfrm_bundle_flo_get, - .check = xfrm_bundle_flo_check, - .delete = xfrm_bundle_flo_delete, -}; - static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family) { const struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); @@ -1624,7 +1490,6 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family) struct dst_entry *dst = &xdst->u.dst; memset(dst + 1, 0, sizeof(*xdst) - sizeof(*dst)); - xdst->flo.ops = &xfrm_bundle_fc_ops; } else xdst = ERR_PTR(-ENOBUFS); @@ -1733,7 +1598,8 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { family = xfrm[i]->props.family; dst = xfrm_dst_lookup(xfrm[i], tos, fl->flowi_oif, - &saddr, &daddr, family); + &saddr, &daddr, family, + xfrm[i]->props.output_mark); err = PTR_ERR(dst); if (IS_ERR(dst)) goto put_states; @@ -1840,6 +1706,102 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, } +static void xfrm_last_dst_update(struct xfrm_dst *xdst, struct xfrm_dst *old) +{ + this_cpu_write(xfrm_last_dst, xdst); + if (old) + dst_release(&old->u.dst); +} + +static void __xfrm_pcpu_work_fn(void) +{ + struct xfrm_dst *old; + + old = this_cpu_read(xfrm_last_dst); + if (old && !xfrm_bundle_ok(old)) + xfrm_last_dst_update(NULL, old); +} + +static void xfrm_pcpu_work_fn(struct work_struct *work) +{ + local_bh_disable(); + rcu_read_lock(); + __xfrm_pcpu_work_fn(); + rcu_read_unlock(); + local_bh_enable(); +} + +void xfrm_policy_cache_flush(void) +{ + struct xfrm_dst *old; + bool found = 0; + int cpu; + + local_bh_disable(); + rcu_read_lock(); + for_each_possible_cpu(cpu) { + old = per_cpu(xfrm_last_dst, cpu); + if (old && !xfrm_bundle_ok(old)) { + if (smp_processor_id() == cpu) { + __xfrm_pcpu_work_fn(); + continue; + } + found = true; + break; + } + } + + rcu_read_unlock(); + local_bh_enable(); + + if (!found) + return; + + get_online_cpus(); + + for_each_possible_cpu(cpu) { + bool bundle_release; + + rcu_read_lock(); + old = per_cpu(xfrm_last_dst, cpu); + bundle_release = old && !xfrm_bundle_ok(old); + rcu_read_unlock(); + + if (!bundle_release) + continue; + + if (cpu_online(cpu)) { + schedule_work_on(cpu, &xfrm_pcpu_work[cpu]); + continue; + } + + rcu_read_lock(); + old = per_cpu(xfrm_last_dst, cpu); + if (old && !xfrm_bundle_ok(old)) { + per_cpu(xfrm_last_dst, cpu) = NULL; + dst_release(&old->u.dst); + } + rcu_read_unlock(); + } + + put_online_cpus(); +} + +static bool xfrm_pol_dead(struct xfrm_dst *xdst) +{ + unsigned int num_pols = xdst->num_pols; + unsigned int pol_dead = 0, i; + + for (i = 0; i < num_pols; i++) + pol_dead |= xdst->pols[i]->walk.dead; + + /* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */ + if (pol_dead) + xdst->u.dst.obsolete = DST_OBSOLETE_DEAD; + + return pol_dead; +} + static struct xfrm_dst * xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, const struct flowi *fl, u16 family, @@ -1847,10 +1809,23 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, { struct net *net = xp_net(pols[0]); struct xfrm_state *xfrm[XFRM_MAX_DEPTH]; + struct xfrm_dst *xdst, *old; struct dst_entry *dst; - struct xfrm_dst *xdst; int err; + xdst = this_cpu_read(xfrm_last_dst); + if (xdst && + xdst->u.dst.dev == dst_orig->dev && + xdst->num_pols == num_pols && + !xfrm_pol_dead(xdst) && + memcmp(xdst->pols, pols, + sizeof(struct xfrm_policy *) * num_pols) == 0 && + xfrm_bundle_ok(xdst)) { + dst_hold(&xdst->u.dst); + return xdst; + } + + old = xdst; /* Try to instantiate a bundle */ err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); if (err <= 0) { @@ -1871,6 +1846,9 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols); xdst->policy_genid = atomic_read(&pols[0]->genid); + atomic_set(&xdst->u.dst.__refcnt, 2); + xfrm_last_dst_update(xdst, old); + return xdst; } @@ -2051,86 +2029,39 @@ static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net, goto out; } -static struct flow_cache_object * -xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, - struct flow_cache_object *oldflo, void *ctx) +static struct xfrm_dst * +xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, struct xfrm_flo *xflo) { - struct xfrm_flo *xflo = (struct xfrm_flo *)ctx; struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; - struct xfrm_dst *xdst, *new_xdst; - int num_pols = 0, num_xfrms = 0, i, err, pol_dead; - - /* Check if the policies from old bundle are usable */ - xdst = NULL; - if (oldflo) { - xdst = container_of(oldflo, struct xfrm_dst, flo); - num_pols = xdst->num_pols; - num_xfrms = xdst->num_xfrms; - pol_dead = 0; - for (i = 0; i < num_pols; i++) { - pols[i] = xdst->pols[i]; - pol_dead |= pols[i]->walk.dead; - } - if (pol_dead) { - /* Mark DST_OBSOLETE_DEAD to fail the next - * xfrm_dst_check() - */ - xdst->u.dst.obsolete = DST_OBSOLETE_DEAD; - dst_release_immediate(&xdst->u.dst); - xdst = NULL; - num_pols = 0; - num_xfrms = 0; - oldflo = NULL; - } - } + int num_pols = 0, num_xfrms = 0, err; + struct xfrm_dst *xdst; /* Resolve policies to use if we couldn't get them from * previous cache entry */ - if (xdst == NULL) { - num_pols = 1; - pols[0] = __xfrm_policy_lookup(net, fl, family, - flow_to_policy_dir(dir)); - err = xfrm_expand_policies(fl, family, pols, + num_pols = 1; + pols[0] = xfrm_policy_lookup(net, fl, family, dir); + err = xfrm_expand_policies(fl, family, pols, &num_pols, &num_xfrms); - if (err < 0) - goto inc_error; - if (num_pols == 0) - return NULL; - if (num_xfrms <= 0) - goto make_dummy_bundle; - } + if (err < 0) + goto inc_error; + if (num_pols == 0) + return NULL; + if (num_xfrms <= 0) + goto make_dummy_bundle; - new_xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, + xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, xflo->dst_orig); - if (IS_ERR(new_xdst)) { - err = PTR_ERR(new_xdst); + if (IS_ERR(xdst)) { + err = PTR_ERR(xdst); if (err != -EAGAIN) goto error; - if (oldflo == NULL) - goto make_dummy_bundle; - dst_hold(&xdst->u.dst); - return oldflo; - } else if (new_xdst == NULL) { + goto make_dummy_bundle; + } else if (xdst == NULL) { num_xfrms = 0; - if (oldflo == NULL) - goto make_dummy_bundle; - xdst->num_xfrms = 0; - dst_hold(&xdst->u.dst); - return oldflo; + goto make_dummy_bundle; } - /* Kill the previous bundle */ - if (xdst) { - /* The policies were stolen for newly generated bundle */ - xdst->num_pols = 0; - /* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */ - xdst->u.dst.obsolete = DST_OBSOLETE_DEAD; - dst_release_immediate(&xdst->u.dst); - } - - /* We do need to return one reference for original caller */ - dst_hold(&new_xdst->u.dst); - return &new_xdst->flo; + return xdst; make_dummy_bundle: /* We found policies, but there's no bundles to instantiate: @@ -2146,17 +2077,12 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols); dst_hold(&xdst->u.dst); - return &xdst->flo; + return xdst; inc_error: XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); error: - if (xdst != NULL) { - /* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */ - xdst->u.dst.obsolete = DST_OBSOLETE_DEAD; - dst_release_immediate(&xdst->u.dst); - } else - xfrm_pols_put(pols, num_pols); + xfrm_pols_put(pols, num_pols); return ERR_PTR(err); } @@ -2187,11 +2113,10 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, const struct sock *sk, int flags) { struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; - struct flow_cache_object *flo; struct xfrm_dst *xdst; struct dst_entry *dst, *route; u16 family = dst_orig->ops->family; - u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); + u8 dir = XFRM_POLICY_OUT; int i, err, num_pols, num_xfrms = 0, drop_pols = 0; dst = NULL; @@ -2226,7 +2151,6 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, goto no_transform; } - dst_hold(&xdst->u.dst); route = xdst->route; } } @@ -2242,15 +2166,13 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, !net->xfrm.policy_count[XFRM_POLICY_OUT]) goto nopol; - flo = flow_cache_lookup(net, fl, family, dir, - xfrm_bundle_lookup, &xflo); - if (flo == NULL) + xdst = xfrm_bundle_lookup(net, fl, family, dir, &xflo); + if (xdst == NULL) goto nopol; - if (IS_ERR(flo)) { - err = PTR_ERR(flo); + if (IS_ERR(xdst)) { + err = PTR_ERR(xdst); goto dropdst; } - xdst = container_of(flo, struct xfrm_dst, flo); num_pols = xdst->num_pols; num_xfrms = xdst->num_xfrms; @@ -2449,12 +2371,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, int pi; int reverse; struct flowi fl; - u8 fl_dir; int xerr_idx = -1; reverse = dir & ~XFRM_POLICY_MASK; dir &= XFRM_POLICY_MASK; - fl_dir = policy_to_flow_dir(dir); if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR); @@ -2486,16 +2406,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, } } - if (!pol) { - struct flow_cache_object *flo; - - flo = flow_cache_lookup(net, &fl, family, fl_dir, - xfrm_policy_lookup, NULL); - if (IS_ERR_OR_NULL(flo)) - pol = ERR_CAST(flo); - else - pol = container_of(flo, struct xfrm_policy, flo); - } + if (!pol) + pol = xfrm_policy_lookup(net, &fl, family, dir); if (IS_ERR(pol)) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR); @@ -2641,11 +2553,9 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) * notice. That's what we are validating here via the * stale_bundle() check. * - * When an xdst is removed from flow cache, DST_OBSOLETE_DEAD will - * be marked on it. * When a dst is removed from the fib tree, DST_OBSOLETE_DEAD will * be marked on it. - * Both will force stable_bundle() to fail on any xdst bundle with + * This will force stale_bundle() to fail on any xdst bundle with * this dst linked in it. */ if (dst->obsolete < 0 && !stale_bundle(dst)) @@ -2685,18 +2595,6 @@ static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst) return dst; } -void xfrm_garbage_collect(struct net *net) -{ - flow_cache_flush(net); -} -EXPORT_SYMBOL(xfrm_garbage_collect); - -void xfrm_garbage_collect_deferred(struct net *net) -{ - flow_cache_flush_deferred(net); -} -EXPORT_SYMBOL(xfrm_garbage_collect_deferred); - static void xfrm_init_pmtu(struct dst_entry *dst) { do { @@ -3034,14 +2932,9 @@ static int __net_init xfrm_net_init(struct net *net) rv = xfrm_sysctl_init(net); if (rv < 0) goto out_sysctl; - rv = flow_cache_init(net); - if (rv < 0) - goto out; return 0; -out: - xfrm_sysctl_fini(net); out_sysctl: xfrm_policy_fini(net); out_policy: @@ -3054,7 +2947,6 @@ static int __net_init xfrm_net_init(struct net *net) static void __net_exit xfrm_net_exit(struct net *net) { - flow_cache_fini(net); xfrm_sysctl_fini(net); xfrm_policy_fini(net); xfrm_state_fini(net); @@ -3068,7 +2960,15 @@ static struct pernet_operations __net_initdata xfrm_net_ops = { void __init xfrm_init(void) { - flow_cache_hp_init(); + int i; + + xfrm_pcpu_work = kmalloc_array(NR_CPUS, sizeof(*xfrm_pcpu_work), + GFP_KERNEL); + BUG_ON(!xfrm_pcpu_work); + + for (i = 0; i < NR_CPUS; i++) + INIT_WORK(&xfrm_pcpu_work[i], xfrm_pcpu_work_fn); + register_pernet_subsys(&xfrm_net_ops); seqcount_init(&xfrm_policy_hash_generation); xfrm_input_init(); @@ -3308,9 +3208,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_state *x_new[XFRM_MAX_DEPTH]; struct xfrm_migrate *mp; + /* Stage 0 - sanity checks */ if ((err = xfrm_migrate_check(m, num_migrate)) < 0) goto out; + if (dir >= XFRM_POLICY_MAX) { + err = -EINVAL; + goto out; + } + /* Stage 1 - find policy */ if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) { err = -ENOENT; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 6c0956d10db601add764616df62dbe19999c29b4..0dab1cd79ce4d1afe84ba9422a740689a9ebdf71 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -296,12 +296,14 @@ int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, } EXPORT_SYMBOL(xfrm_unregister_type_offload); -static const struct xfrm_type_offload *xfrm_get_type_offload(u8 proto, unsigned short family) +static const struct xfrm_type_offload * +xfrm_get_type_offload(u8 proto, unsigned short family, bool try_load) { struct xfrm_state_afinfo *afinfo; const struct xfrm_type_offload **typemap; const struct xfrm_type_offload *type; +retry: afinfo = xfrm_state_get_afinfo(family); if (unlikely(afinfo == NULL)) return NULL; @@ -311,6 +313,12 @@ static const struct xfrm_type_offload *xfrm_get_type_offload(u8 proto, unsigned if ((type && !try_module_get(type->owner))) type = NULL; + if (!type && try_load) { + request_module("xfrm-offload-%d-%d", family, proto); + try_load = 0; + goto retry; + } + rcu_read_unlock(); return type; } @@ -724,9 +732,10 @@ int xfrm_state_flush(struct net *net, u8 proto, bool task_valid) } } } - if (cnt) + if (cnt) { err = 0; - + xfrm_policy_cache_flush(); + } out: spin_unlock_bh(&net->xfrm.xfrm_state_lock); return err; @@ -1620,6 +1629,7 @@ int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, unsigned short family, struct net *net) { + int i; int err = 0; struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); if (!afinfo) @@ -1628,6 +1638,9 @@ xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/ if (afinfo->tmpl_sort) err = afinfo->tmpl_sort(dst, src, n); + else + for (i = 0; i < n; i++) + dst[i] = src[i]; spin_unlock_bh(&net->xfrm.xfrm_state_lock); rcu_read_unlock(); return err; @@ -1638,6 +1651,7 @@ int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, unsigned short family) { + int i; int err = 0; struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); struct net *net = xs_net(*src); @@ -1648,6 +1662,9 @@ xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, spin_lock_bh(&net->xfrm.xfrm_state_lock); if (afinfo->state_sort) err = afinfo->state_sort(dst, src, n); + else + for (i = 0; i < n; i++) + dst[i] = src[i]; spin_unlock_bh(&net->xfrm.xfrm_state_lock); rcu_read_unlock(); return err; @@ -2164,7 +2181,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) return mtu - x->props.header_len; } -int __xfrm_init_state(struct xfrm_state *x, bool init_replay) +int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) { struct xfrm_state_afinfo *afinfo; struct xfrm_mode *inner_mode; @@ -2229,7 +2246,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay) if (x->type == NULL) goto error; - x->type_offload = xfrm_get_type_offload(x->id.proto, family); + x->type_offload = xfrm_get_type_offload(x->id.proto, family, offload); err = x->type->init_state(x); if (err) @@ -2257,7 +2274,7 @@ EXPORT_SYMBOL(__xfrm_init_state); int xfrm_init_state(struct xfrm_state *x) { - return __xfrm_init_state(x, true); + return __xfrm_init_state(x, true, false); } EXPORT_SYMBOL(xfrm_init_state); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 2be4c6af008a7917ae5cc1e3306c5466cae387e4..2bfbd9121e3b21b0eb793d2d3a685bd4cebde22b 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -584,7 +584,10 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, xfrm_mark_get(attrs, &x->mark); - err = __xfrm_init_state(x, false); + if (attrs[XFRMA_OUTPUT_MARK]) + x->props.output_mark = nla_get_u32(attrs[XFRMA_OUTPUT_MARK]); + + err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]); if (err) goto error; @@ -796,7 +799,7 @@ static int copy_user_offload(struct xfrm_state_offload *xso, struct sk_buff *skb return -EMSGSIZE; xuo = nla_data(attr); - + memset(xuo, 0, sizeof(*xuo)); xuo->ifindex = xso->dev->ifindex; xuo->flags = xso->flags; @@ -897,6 +900,11 @@ static int copy_to_user_state_extra(struct xfrm_state *x, ret = copy_user_offload(&x->xso, skb); if (ret) goto out; + if (x->props.output_mark) { + ret = nla_put_u32(skb, XFRMA_OUTPUT_MARK, x->props.output_mark); + if (ret) + goto out; + } if (x->security) ret = copy_sec_ctx(x->security, skb); out: @@ -1815,8 +1823,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, out: xfrm_pol_put(xp); - if (delete && err == 0) - xfrm_garbage_collect(net); return err; } @@ -1869,6 +1875,7 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct return -EMSGSIZE; id = nlmsg_data(nlh); + memset(&id->sa_id, 0, sizeof(id->sa_id)); memcpy(&id->sa_id.daddr, &x->id.daddr, sizeof(x->id.daddr)); id->sa_id.spi = x->id.spi; id->sa_id.family = x->props.family; @@ -2027,7 +2034,6 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, return 0; return err; } - xfrm_garbage_collect(net); c.data.type = type; c.event = nlh->nlmsg_type; @@ -2457,6 +2463,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { [XFRMA_PROTO] = { .type = NLA_U8 }, [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, + [XFRMA_OUTPUT_MARK] = { .len = NLA_U32 }, }; static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { @@ -2578,6 +2585,8 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct ue = nlmsg_data(nlh); copy_to_user_state(x, &ue->state); ue->hard = (c->data.hard != 0) ? 1 : 0; + /* clear the padding bytes */ + memset(&ue->hard + 1, 0, sizeof(*ue) - offsetofend(typeof(*ue), hard)); err = xfrm_mark_put(skb, &x->mark); if (err) @@ -2676,6 +2685,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) l += nla_total_size(sizeof(x->props.extra_flags)); if (x->xso.dev) l += nla_total_size(sizeof(x->xso)); + if (x->props.output_mark) + l += nla_total_size(sizeof(x->props.output_mark)); /* Must count x->lastused as it may become non-zero behind our back. */ l += nla_total_size_64bit(sizeof(u64)); @@ -2715,6 +2726,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) struct nlattr *attr; id = nlmsg_data(nlh); + memset(id, 0, sizeof(*id)); memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr)); id->spi = x->id.spi; id->family = x->props.family; diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 87246be6feb8513b4a97e74ada1ca3f2fa72fa9d..cf17c7932a6e16c2d817d24a5b9f09e8900c86be 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -37,6 +37,10 @@ hostprogs-y += xdp_tx_iptunnel hostprogs-y += test_map_in_map hostprogs-y += per_socket_stats_example hostprogs-y += load_sock_ops +hostprogs-y += xdp_redirect +hostprogs-y += xdp_redirect_map +hostprogs-y += xdp_monitor +hostprogs-y += syscall_tp # Libbpf dependencies LIBBPF := ../../tools/lib/bpf/bpf.o @@ -78,6 +82,10 @@ lwt_len_hist-objs := bpf_load.o $(LIBBPF) lwt_len_hist_user.o xdp_tx_iptunnel-objs := bpf_load.o $(LIBBPF) xdp_tx_iptunnel_user.o test_map_in_map-objs := bpf_load.o $(LIBBPF) test_map_in_map_user.o per_socket_stats_example-objs := $(LIBBPF) cookie_uid_helper_example.o +xdp_redirect-objs := bpf_load.o $(LIBBPF) xdp_redirect_user.o +xdp_redirect_map-objs := bpf_load.o $(LIBBPF) xdp_redirect_map_user.o +xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o +syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o # Tell kbuild to always build the programs always := $(hostprogs-y) @@ -119,6 +127,10 @@ always += tcp_bufs_kern.o always += tcp_cong_kern.o always += tcp_iw_kern.o always += tcp_clamp_kern.o +always += xdp_redirect_kern.o +always += xdp_redirect_map_kern.o +always += xdp_monitor_kern.o +always += syscall_tp_kern.o HOSTCFLAGS += -I$(objtree)/usr/include HOSTCFLAGS += -I$(srctree)/tools/lib/ @@ -155,6 +167,10 @@ HOSTLOADLIBES_tc_l2_redirect += -l elf HOSTLOADLIBES_lwt_len_hist += -l elf HOSTLOADLIBES_xdp_tx_iptunnel += -lelf HOSTLOADLIBES_test_map_in_map += -lelf +HOSTLOADLIBES_xdp_redirect += -lelf +HOSTLOADLIBES_xdp_redirect_map += -lelf +HOSTLOADLIBES_xdp_monitor += -lelf +HOSTLOADLIBES_syscall_tp += -lelf # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: # make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c index 899f40310bc3e3c5137f3eb9abb5292a3e1d7e08..6aa50098dfb8e177bd6c74c550a5aac2213148f1 100644 --- a/samples/bpf/bpf_load.c +++ b/samples/bpf/bpf_load.c @@ -65,6 +65,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) bool is_cgroup_skb = strncmp(event, "cgroup/skb", 10) == 0; bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0; bool is_sockops = strncmp(event, "sockops", 7) == 0; + bool is_sk_skb = strncmp(event, "sk_skb", 6) == 0; size_t insns_cnt = size / sizeof(struct bpf_insn); enum bpf_prog_type prog_type; char buf[256]; @@ -92,6 +93,8 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) prog_type = BPF_PROG_TYPE_CGROUP_SOCK; } else if (is_sockops) { prog_type = BPF_PROG_TYPE_SOCK_OPS; + } else if (is_sk_skb) { + prog_type = BPF_PROG_TYPE_SK_SKB; } else { printf("Unknown event '%s'\n", event); return -1; @@ -109,7 +112,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) if (is_xdp || is_perf_event || is_cgroup_skb || is_cgroup_sk) return 0; - if (is_socket || is_sockops) { + if (is_socket || is_sockops || is_sk_skb) { if (is_socket) event += 6; else @@ -198,7 +201,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) static int load_maps(struct bpf_map_data *maps, int nr_maps, fixup_map_cb fixup_map) { - int i; + int i, numa_node; for (i = 0; i < nr_maps; i++) { if (fixup_map) { @@ -210,21 +213,26 @@ static int load_maps(struct bpf_map_data *maps, int nr_maps, } } + numa_node = maps[i].def.map_flags & BPF_F_NUMA_NODE ? + maps[i].def.numa_node : -1; + if (maps[i].def.type == BPF_MAP_TYPE_ARRAY_OF_MAPS || maps[i].def.type == BPF_MAP_TYPE_HASH_OF_MAPS) { int inner_map_fd = map_fd[maps[i].def.inner_map_idx]; - map_fd[i] = bpf_create_map_in_map(maps[i].def.type, + map_fd[i] = bpf_create_map_in_map_node(maps[i].def.type, maps[i].def.key_size, inner_map_fd, maps[i].def.max_entries, - maps[i].def.map_flags); + maps[i].def.map_flags, + numa_node); } else { - map_fd[i] = bpf_create_map(maps[i].def.type, - maps[i].def.key_size, - maps[i].def.value_size, - maps[i].def.max_entries, - maps[i].def.map_flags); + map_fd[i] = bpf_create_map_node(maps[i].def.type, + maps[i].def.key_size, + maps[i].def.value_size, + maps[i].def.max_entries, + maps[i].def.map_flags, + numa_node); } if (map_fd[i] < 0) { printf("failed to create a map: %d %s\n", @@ -567,7 +575,8 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map) memcmp(shname, "perf_event", 10) == 0 || memcmp(shname, "socket", 6) == 0 || memcmp(shname, "cgroup/", 7) == 0 || - memcmp(shname, "sockops", 7) == 0) { + memcmp(shname, "sockops", 7) == 0 || + memcmp(shname, "sk_skb", 6) == 0) { ret = load_and_attach(shname, data->d_buf, data->d_size); if (ret != 0) diff --git a/samples/bpf/bpf_load.h b/samples/bpf/bpf_load.h index ca0563d04744fe31a472b53824a5a1135b53be48..453e3226b4ceb1ac91c96fa761a9402399dce8e1 100644 --- a/samples/bpf/bpf_load.h +++ b/samples/bpf/bpf_load.h @@ -13,6 +13,7 @@ struct bpf_map_def { unsigned int max_entries; unsigned int map_flags; unsigned int inner_map_idx; + unsigned int numa_node; }; struct bpf_map_data { diff --git a/samples/bpf/map_perf_test_kern.c b/samples/bpf/map_perf_test_kern.c index 245165817fbe63bd53ea9cf7f3a3ab6cf5e7a2fa..098c857f1eda6396317ea59a5bdfb9a52d6eb8ef 100644 --- a/samples/bpf/map_perf_test_kern.c +++ b/samples/bpf/map_perf_test_kern.c @@ -40,6 +40,8 @@ struct bpf_map_def SEC("maps") inner_lru_hash_map = { .key_size = sizeof(u32), .value_size = sizeof(long), .max_entries = MAX_ENTRIES, + .map_flags = BPF_F_NUMA_NODE, + .numa_node = 0, }; struct bpf_map_def SEC("maps") array_of_lru_hashs = { @@ -86,6 +88,13 @@ struct bpf_map_def SEC("maps") array_map = { .max_entries = MAX_ENTRIES, }; +struct bpf_map_def SEC("maps") lru_hash_lookup_map = { + .type = BPF_MAP_TYPE_LRU_HASH, + .key_size = sizeof(u32), + .value_size = sizeof(long), + .max_entries = MAX_ENTRIES, +}; + SEC("kprobe/sys_getuid") int stress_hmap(struct pt_regs *ctx) { @@ -146,12 +155,23 @@ int stress_percpu_hmap_alloc(struct pt_regs *ctx) SEC("kprobe/sys_connect") int stress_lru_hmap_alloc(struct pt_regs *ctx) { + char fmt[] = "Failed at stress_lru_hmap_alloc. ret:%dn"; + union { + u16 dst6[8]; + struct { + u16 magic0; + u16 magic1; + u16 tcase; + u16 unused16; + u32 unused32; + u32 key; + }; + } test_params; struct sockaddr_in6 *in6; - u16 test_case, dst6[8]; + u16 test_case; int addrlen, ret; - char fmt[] = "Failed at stress_lru_hmap_alloc. ret:%d\n"; long val = 1; - u32 key = bpf_get_prandom_u32(); + u32 key = 0; in6 = (struct sockaddr_in6 *)PT_REGS_PARM2(ctx); addrlen = (int)PT_REGS_PARM3(ctx); @@ -159,14 +179,18 @@ int stress_lru_hmap_alloc(struct pt_regs *ctx) if (addrlen != sizeof(*in6)) return 0; - ret = bpf_probe_read(dst6, sizeof(dst6), &in6->sin6_addr); + ret = bpf_probe_read(test_params.dst6, sizeof(test_params.dst6), + &in6->sin6_addr); if (ret) goto done; - if (dst6[0] != 0xdead || dst6[1] != 0xbeef) + if (test_params.magic0 != 0xdead || + test_params.magic1 != 0xbeef) return 0; - test_case = dst6[7]; + test_case = test_params.tcase; + if (test_case != 3) + key = bpf_get_prandom_u32(); if (test_case == 0) { ret = bpf_map_update_elem(&lru_hash_map, &key, &val, BPF_ANY); @@ -186,6 +210,16 @@ int stress_lru_hmap_alloc(struct pt_regs *ctx) ret = bpf_map_update_elem(nolocal_lru_map, &key, &val, BPF_ANY); + } else if (test_case == 3) { + u32 i; + + key = test_params.key; + +#pragma clang loop unroll(full) + for (i = 0; i < 32; i++) { + bpf_map_lookup_elem(&lru_hash_lookup_map, &key); + key++; + } } else { ret = -EINVAL; } diff --git a/samples/bpf/map_perf_test_user.c b/samples/bpf/map_perf_test_user.c index 1a8894b5ac5147c36833ffae500ddfbeb00277d1..f388254896f67b7120bcf20661691288f72e028e 100644 --- a/samples/bpf/map_perf_test_user.c +++ b/samples/bpf/map_perf_test_user.c @@ -46,6 +46,7 @@ enum test_type { HASH_LOOKUP, ARRAY_LOOKUP, INNER_LRU_HASH_PREALLOC, + LRU_HASH_LOOKUP, NR_TESTS, }; @@ -60,6 +61,7 @@ const char *test_map_names[NR_TESTS] = { [HASH_LOOKUP] = "hash_map", [ARRAY_LOOKUP] = "array_map", [INNER_LRU_HASH_PREALLOC] = "inner_lru_hash_map", + [LRU_HASH_LOOKUP] = "lru_hash_lookup_map", }; static int test_flags = ~0; @@ -67,6 +69,8 @@ static uint32_t num_map_entries; static uint32_t inner_lru_hash_size; static int inner_lru_hash_idx = -1; static int array_of_lru_hashs_idx = -1; +static int lru_hash_lookup_idx = -1; +static int lru_hash_lookup_test_entries = 32; static uint32_t max_cnt = 1000000; static int check_test_flags(enum test_type t) @@ -86,6 +90,32 @@ static void test_hash_prealloc(int cpu) cpu, max_cnt * 1000000000ll / (time_get_ns() - start_time)); } +static int pre_test_lru_hash_lookup(int tasks) +{ + int fd = map_fd[lru_hash_lookup_idx]; + uint32_t key; + long val = 1; + int ret; + + if (num_map_entries > lru_hash_lookup_test_entries) + lru_hash_lookup_test_entries = num_map_entries; + + /* Populate the lru_hash_map for LRU_HASH_LOOKUP perf test. + * + * It is fine that the user requests for a map with + * num_map_entries < 32 and some of the later lru hash lookup + * may return not found. For LRU map, we are not interested + * in such small map performance. + */ + for (key = 0; key < lru_hash_lookup_test_entries; key++) { + ret = bpf_map_update_elem(fd, &key, &val, BPF_NOEXIST); + if (ret) + return ret; + } + + return 0; +} + static void do_test_lru(enum test_type test, int cpu) { static int inner_lru_map_fds[MAX_NR_CPUS]; @@ -97,14 +127,20 @@ static void do_test_lru(enum test_type test, int cpu) if (test == INNER_LRU_HASH_PREALLOC) { int outer_fd = map_fd[array_of_lru_hashs_idx]; + unsigned int mycpu, mynode; assert(cpu < MAX_NR_CPUS); if (cpu) { + ret = syscall(__NR_getcpu, &mycpu, &mynode, NULL); + assert(!ret); + inner_lru_map_fds[cpu] = - bpf_create_map(BPF_MAP_TYPE_LRU_HASH, - sizeof(uint32_t), sizeof(long), - inner_lru_hash_size, 0); + bpf_create_map_node(BPF_MAP_TYPE_LRU_HASH, + sizeof(uint32_t), + sizeof(long), + inner_lru_hash_size, 0, + mynode); if (inner_lru_map_fds[cpu] == -1) { printf("cannot create BPF_MAP_TYPE_LRU_HASH %s(%d)\n", strerror(errno), errno); @@ -129,13 +165,17 @@ static void do_test_lru(enum test_type test, int cpu) if (test == LRU_HASH_PREALLOC) { test_name = "lru_hash_map_perf"; - in6.sin6_addr.s6_addr16[7] = 0; + in6.sin6_addr.s6_addr16[2] = 0; } else if (test == NOCOMMON_LRU_HASH_PREALLOC) { test_name = "nocommon_lru_hash_map_perf"; - in6.sin6_addr.s6_addr16[7] = 1; + in6.sin6_addr.s6_addr16[2] = 1; } else if (test == INNER_LRU_HASH_PREALLOC) { test_name = "inner_lru_hash_map_perf"; - in6.sin6_addr.s6_addr16[7] = 2; + in6.sin6_addr.s6_addr16[2] = 2; + } else if (test == LRU_HASH_LOOKUP) { + test_name = "lru_hash_lookup_perf"; + in6.sin6_addr.s6_addr16[2] = 3; + in6.sin6_addr.s6_addr32[3] = 0; } else { assert(0); } @@ -144,6 +184,11 @@ static void do_test_lru(enum test_type test, int cpu) for (i = 0; i < max_cnt; i++) { ret = connect(-1, (const struct sockaddr *)&in6, sizeof(in6)); assert(ret == -1 && errno == EBADF); + if (in6.sin6_addr.s6_addr32[3] < + lru_hash_lookup_test_entries - 32) + in6.sin6_addr.s6_addr32[3] += 32; + else + in6.sin6_addr.s6_addr32[3] = 0; } printf("%d:%s pre-alloc %lld events per sec\n", cpu, test_name, @@ -165,6 +210,11 @@ static void test_inner_lru_hash_prealloc(int cpu) do_test_lru(INNER_LRU_HASH_PREALLOC, cpu); } +static void test_lru_hash_lookup(int cpu) +{ + do_test_lru(LRU_HASH_LOOKUP, cpu); +} + static void test_percpu_hash_prealloc(int cpu) { __u64 start_time; @@ -237,6 +287,11 @@ static void test_array_lookup(int cpu) cpu, max_cnt * 1000000000ll * 64 / (time_get_ns() - start_time)); } +typedef int (*pre_test_func)(int tasks); +const pre_test_func pre_test_funcs[] = { + [LRU_HASH_LOOKUP] = pre_test_lru_hash_lookup, +}; + typedef void (*test_func)(int cpu); const test_func test_funcs[] = { [HASH_PREALLOC] = test_hash_prealloc, @@ -249,8 +304,25 @@ const test_func test_funcs[] = { [HASH_LOOKUP] = test_hash_lookup, [ARRAY_LOOKUP] = test_array_lookup, [INNER_LRU_HASH_PREALLOC] = test_inner_lru_hash_prealloc, + [LRU_HASH_LOOKUP] = test_lru_hash_lookup, }; +static int pre_test(int tasks) +{ + int i; + + for (i = 0; i < NR_TESTS; i++) { + if (pre_test_funcs[i] && check_test_flags(i)) { + int ret = pre_test_funcs[i](tasks); + + if (ret) + return ret; + } + } + + return 0; +} + static void loop(int cpu) { cpu_set_t cpuset; @@ -271,6 +343,8 @@ static void run_perf_test(int tasks) pid_t pid[tasks]; int i; + assert(!pre_test(tasks)); + for (i = 0; i < tasks; i++) { pid[i] = fork(); if (pid[i] == 0) { @@ -338,6 +412,9 @@ static void fixup_map(struct bpf_map_data *map, int idx) array_of_lru_hashs_idx = idx; } + if (!strcmp("lru_hash_lookup_map", map->name)) + lru_hash_lookup_idx = idx; + if (num_map_entries <= 0) return; diff --git a/samples/bpf/sock_flags_kern.c b/samples/bpf/sock_flags_kern.c index 533dd11a6baa9131a621b808d49ba14fc7052091..05dcdf8a4baab23ac039668f5ca73a6bb3e00a0c 100644 --- a/samples/bpf/sock_flags_kern.c +++ b/samples/bpf/sock_flags_kern.c @@ -9,8 +9,13 @@ SEC("cgroup/sock1") int bpf_prog1(struct bpf_sock *sk) { char fmt[] = "socket: family %d type %d protocol %d\n"; + char fmt2[] = "socket: uid %u gid %u\n"; + __u64 gid_uid = bpf_get_current_uid_gid(); + __u32 uid = gid_uid & 0xffffffff; + __u32 gid = gid_uid >> 32; bpf_trace_printk(fmt, sizeof(fmt), sk->family, sk->type, sk->protocol); + bpf_trace_printk(fmt2, sizeof(fmt2), uid, gid); /* block PF_INET6, SOCK_RAW, IPPROTO_ICMPV6 sockets * ie., make ping6 fail diff --git a/samples/bpf/syscall_tp_kern.c b/samples/bpf/syscall_tp_kern.c new file mode 100644 index 0000000000000000000000000000000000000000..9149c524d279313c8cf8d2805224e7b7e02966c3 --- /dev/null +++ b/samples/bpf/syscall_tp_kern.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2017 Facebook + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#include +#include "bpf_helpers.h" + +struct syscalls_enter_open_args { + unsigned long long unused; + long syscall_nr; + long filename_ptr; + long flags; + long mode; +}; + +struct syscalls_exit_open_args { + unsigned long long unused; + long syscall_nr; + long ret; +}; + +struct bpf_map_def SEC("maps") enter_open_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(u32), + .max_entries = 1, +}; + +struct bpf_map_def SEC("maps") exit_open_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(u32), + .max_entries = 1, +}; + +static __always_inline void count(void *map) +{ + u32 key = 0; + u32 *value, init_val = 1; + + value = bpf_map_lookup_elem(map, &key); + if (value) + *value += 1; + else + bpf_map_update_elem(map, &key, &init_val, BPF_NOEXIST); +} + +SEC("tracepoint/syscalls/sys_enter_open") +int trace_enter_open(struct syscalls_enter_open_args *ctx) +{ + count((void *)&enter_open_map); + return 0; +} + +SEC("tracepoint/syscalls/sys_exit_open") +int trace_enter_exit(struct syscalls_exit_open_args *ctx) +{ + count((void *)&exit_open_map); + return 0; +} diff --git a/samples/bpf/syscall_tp_user.c b/samples/bpf/syscall_tp_user.c new file mode 100644 index 0000000000000000000000000000000000000000..a3cb91ebf4e7dc13d5a823da0b97faf4a9731a9c --- /dev/null +++ b/samples/bpf/syscall_tp_user.c @@ -0,0 +1,71 @@ +/* Copyright (c) 2017 Facebook + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libbpf.h" +#include "bpf_load.h" + +/* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*. + * This requires kernel CONFIG_FTRACE_SYSCALLS to be set. + */ + +static void verify_map(int map_id) +{ + __u32 key = 0; + __u32 val; + + if (bpf_map_lookup_elem(map_id, &key, &val) != 0) { + fprintf(stderr, "map_lookup failed: %s\n", strerror(errno)); + return; + } + if (val == 0) + fprintf(stderr, "failed: map #%d returns value 0\n", map_id); +} + +int main(int argc, char **argv) +{ + struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; + char filename[256]; + int fd; + + setrlimit(RLIMIT_MEMLOCK, &r); + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); + + if (load_bpf_file(filename)) { + fprintf(stderr, "%s", bpf_log_buf); + return 1; + } + + /* current load_bpf_file has perf_event_open default pid = -1 + * and cpu = 0, which permits attached bpf execution on + * all cpus for all pid's. bpf program execution ignores + * cpu affinity. + */ + /* trigger some "open" operations */ + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "open failed: %s\n", strerror(errno)); + return 1; + } + close(fd); + + /* verify the map */ + verify_map(map_fd[0]); + verify_map(map_fd[1]); + + return 0; +} diff --git a/samples/bpf/tcbpf2_kern.c b/samples/bpf/tcbpf2_kern.c index 9c823a609e75f8d66bbe1fa31a1ecebac7f65311..370b749f5ee64b04e877f62339933e0477ba0999 100644 --- a/samples/bpf/tcbpf2_kern.c +++ b/samples/bpf/tcbpf2_kern.c @@ -17,6 +17,7 @@ #include #include #include "bpf_helpers.h" +#include "bpf_endian.h" #define _htonl __builtin_bswap32 #define ERROR(ret) do {\ @@ -38,6 +39,10 @@ struct vxlan_metadata { u32 gbp; }; +struct erspan_metadata { + __be32 index; +}; + SEC("gre_set_tunnel") int _gre_set_tunnel(struct __sk_buff *skb) { @@ -76,6 +81,63 @@ int _gre_get_tunnel(struct __sk_buff *skb) return TC_ACT_OK; } +SEC("erspan_set_tunnel") +int _erspan_set_tunnel(struct __sk_buff *skb) +{ + struct bpf_tunnel_key key; + struct erspan_metadata md; + int ret; + + __builtin_memset(&key, 0x0, sizeof(key)); + key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ + key.tunnel_id = 2; + key.tunnel_tos = 0; + key.tunnel_ttl = 64; + + ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); + if (ret < 0) { + ERROR(ret); + return TC_ACT_SHOT; + } + + md.index = htonl(123); + ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md)); + if (ret < 0) { + ERROR(ret); + return TC_ACT_SHOT; + } + + return TC_ACT_OK; +} + +SEC("erspan_get_tunnel") +int _erspan_get_tunnel(struct __sk_buff *skb) +{ + char fmt[] = "key %d remote ip 0x%x erspan index 0x%x\n"; + struct bpf_tunnel_key key; + struct erspan_metadata md; + u32 index; + int ret; + + ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); + if (ret < 0) { + ERROR(ret); + return TC_ACT_SHOT; + } + + ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md)); + if (ret < 0) { + ERROR(ret); + return TC_ACT_SHOT; + } + + index = bpf_ntohl(md.index); + bpf_trace_printk(fmt, sizeof(fmt), + key.tunnel_id, key.remote_ipv4, index); + + return TC_ACT_OK; +} + SEC("vxlan_set_tunnel") int _vxlan_set_tunnel(struct __sk_buff *skb) { @@ -147,9 +209,9 @@ int _geneve_set_tunnel(struct __sk_buff *skb) __builtin_memset(&gopt, 0x0, sizeof(gopt)); gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */ gopt.type = 0x08; - gopt.r1 = 1; + gopt.r1 = 0; gopt.r2 = 0; - gopt.r3 = 1; + gopt.r3 = 0; gopt.length = 2; /* 4-byte multiple */ *(int *) &gopt.opt_data = 0xdeadbeef; @@ -378,5 +440,4 @@ int _ip6ip6_get_tunnel(struct __sk_buff *skb) return TC_ACT_OK; } - char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c index c3cfb23e23b52832d795b2cc095f94b3f49d9f0b..e79594dd629ba34e066212d80e1549962b3c7d46 100644 --- a/samples/bpf/test_cgrp2_sock.c +++ b/samples/bpf/test_cgrp2_sock.c @@ -19,68 +19,271 @@ #include #include #include +#include #include #include "libbpf.h" char bpf_log_buf[BPF_LOG_BUF_SIZE]; -static int prog_load(int idx) +static int prog_load(__u32 idx, __u32 mark, __u32 prio) { - struct bpf_insn prog[] = { + /* save pointer to context */ + struct bpf_insn prog_start[] = { BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), + }; + struct bpf_insn prog_end[] = { + BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ + BPF_EXIT_INSN(), + }; + + /* set sk_bound_dev_if on socket */ + struct bpf_insn prog_dev[] = { BPF_MOV64_IMM(BPF_REG_3, idx), BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, bound_dev_if)), BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, bound_dev_if)), - BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ - BPF_EXIT_INSN(), }; - size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn); - return bpf_load_program(BPF_PROG_TYPE_CGROUP_SOCK, prog, insns_cnt, + /* set mark on socket */ + struct bpf_insn prog_mark[] = { + /* get uid of process */ + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, + BPF_FUNC_get_current_uid_gid), + BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff), + + /* if uid is 0, use given mark, else use the uid as the mark */ + BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_MOV64_IMM(BPF_REG_3, mark), + + /* set the mark on the new socket */ + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, mark)), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, mark)), + }; + + /* set priority on socket */ + struct bpf_insn prog_prio[] = { + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_MOV64_IMM(BPF_REG_3, prio), + BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, priority)), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, priority)), + }; + + struct bpf_insn *prog; + size_t insns_cnt; + void *p; + int ret; + + insns_cnt = sizeof(prog_start) + sizeof(prog_end); + if (idx) + insns_cnt += sizeof(prog_dev); + + if (mark) + insns_cnt += sizeof(prog_mark); + + if (prio) + insns_cnt += sizeof(prog_prio); + + p = prog = malloc(insns_cnt); + if (!prog) { + fprintf(stderr, "Failed to allocate memory for instructions\n"); + return EXIT_FAILURE; + } + + memcpy(p, prog_start, sizeof(prog_start)); + p += sizeof(prog_start); + + if (idx) { + memcpy(p, prog_dev, sizeof(prog_dev)); + p += sizeof(prog_dev); + } + + if (mark) { + memcpy(p, prog_mark, sizeof(prog_mark)); + p += sizeof(prog_mark); + } + + if (prio) { + memcpy(p, prog_prio, sizeof(prog_prio)); + p += sizeof(prog_prio); + } + + memcpy(p, prog_end, sizeof(prog_end)); + p += sizeof(prog_end); + + insns_cnt /= sizeof(struct bpf_insn); + + ret = bpf_load_program(BPF_PROG_TYPE_CGROUP_SOCK, prog, insns_cnt, "GPL", 0, bpf_log_buf, BPF_LOG_BUF_SIZE); + + free(prog); + + return ret; +} + +static int get_bind_to_device(int sd, char *name, size_t len) +{ + socklen_t optlen = len; + int rc; + + name[0] = '\0'; + rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen); + if (rc < 0) + perror("setsockopt(SO_BINDTODEVICE)"); + + return rc; +} + +static unsigned int get_somark(int sd) +{ + unsigned int mark = 0; + socklen_t optlen = sizeof(mark); + int rc; + + rc = getsockopt(sd, SOL_SOCKET, SO_MARK, &mark, &optlen); + if (rc < 0) + perror("getsockopt(SO_MARK)"); + + return mark; +} + +static unsigned int get_priority(int sd) +{ + unsigned int prio = 0; + socklen_t optlen = sizeof(prio); + int rc; + + rc = getsockopt(sd, SOL_SOCKET, SO_PRIORITY, &prio, &optlen); + if (rc < 0) + perror("getsockopt(SO_PRIORITY)"); + + return prio; +} + +static int show_sockopts(int family) +{ + unsigned int mark, prio; + char name[16]; + int sd; + + sd = socket(family, SOCK_DGRAM, 17); + if (sd < 0) { + perror("socket"); + return 1; + } + + if (get_bind_to_device(sd, name, sizeof(name)) < 0) + return 1; + + mark = get_somark(sd); + prio = get_priority(sd); + + close(sd); + + printf("sd %d: dev %s, mark %u, priority %u\n", sd, name, mark, prio); + + return 0; } static int usage(const char *argv0) { - printf("Usage: %s cg-path device-index\n", argv0); + printf("Usage:\n"); + printf(" Attach a program\n"); + printf(" %s -b bind-to-dev -m mark -p prio cg-path\n", argv0); + printf("\n"); + printf(" Detach a program\n"); + printf(" %s -d cg-path\n", argv0); + printf("\n"); + printf(" Show inherited socket settings (mark, priority, and device)\n"); + printf(" %s [-6]\n", argv0); return EXIT_FAILURE; } int main(int argc, char **argv) { + __u32 idx = 0, mark = 0, prio = 0; + const char *cgrp_path = NULL; int cg_fd, prog_fd, ret; - unsigned int idx; + int family = PF_INET; + int do_attach = 1; + int rc; + + while ((rc = getopt(argc, argv, "db:m:p:6")) != -1) { + switch (rc) { + case 'd': + do_attach = 0; + break; + case 'b': + idx = if_nametoindex(optarg); + if (!idx) { + idx = strtoumax(optarg, NULL, 0); + if (!idx) { + printf("Invalid device name\n"); + return EXIT_FAILURE; + } + } + break; + case 'm': + mark = strtoumax(optarg, NULL, 0); + break; + case 'p': + prio = strtoumax(optarg, NULL, 0); + break; + case '6': + family = PF_INET6; + break; + default: + return usage(argv[0]); + } + } - if (argc < 2) - return usage(argv[0]); + if (optind == argc) + return show_sockopts(family); - idx = if_nametoindex(argv[2]); - if (!idx) { - printf("Invalid device name\n"); + cgrp_path = argv[optind]; + if (!cgrp_path) { + fprintf(stderr, "cgroup path not given\n"); return EXIT_FAILURE; } - cg_fd = open(argv[1], O_DIRECTORY | O_RDONLY); - if (cg_fd < 0) { - printf("Failed to open cgroup path: '%s'\n", strerror(errno)); + if (do_attach && !idx && !mark && !prio) { + fprintf(stderr, + "One of device, mark or priority must be given\n"); return EXIT_FAILURE; } - prog_fd = prog_load(idx); - printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf); - - if (prog_fd < 0) { - printf("Failed to load prog: '%s'\n", strerror(errno)); + cg_fd = open(cgrp_path, O_DIRECTORY | O_RDONLY); + if (cg_fd < 0) { + printf("Failed to open cgroup path: '%s'\n", strerror(errno)); return EXIT_FAILURE; } - ret = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_INET_SOCK_CREATE, 0); - if (ret < 0) { - printf("Failed to attach prog to cgroup: '%s'\n", - strerror(errno)); - return EXIT_FAILURE; + if (do_attach) { + prog_fd = prog_load(idx, mark, prio); + if (prog_fd < 0) { + printf("Failed to load prog: '%s'\n", strerror(errno)); + printf("Output from kernel verifier:\n%s\n-------\n", + bpf_log_buf); + return EXIT_FAILURE; + } + + ret = bpf_prog_attach(prog_fd, cg_fd, + BPF_CGROUP_INET_SOCK_CREATE, 0); + if (ret < 0) { + printf("Failed to attach prog to cgroup: '%s'\n", + strerror(errno)); + return EXIT_FAILURE; + } + } else { + ret = bpf_prog_detach(cg_fd, BPF_CGROUP_INET_SOCK_CREATE); + if (ret < 0) { + printf("Failed to detach prog from cgroup: '%s'\n", + strerror(errno)); + return EXIT_FAILURE; + } } + close(cg_fd); return EXIT_SUCCESS; } diff --git a/samples/bpf/test_cgrp2_sock.sh b/samples/bpf/test_cgrp2_sock.sh index 925fd467c7cc92043eae39ba9ea76f94401f969a..a81f38eef417443858ddcaea3bb63711589e9fd4 100755 --- a/samples/bpf/test_cgrp2_sock.sh +++ b/samples/bpf/test_cgrp2_sock.sh @@ -1,47 +1,133 @@ -#!/bin/bash - -function config_device { - ip netns add at_ns0 - ip link add veth0 type veth peer name veth0b - ip link set veth0b up - ip link set veth0 netns at_ns0 - ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0 - ip netns exec at_ns0 ip addr add 2401:db00::1/64 dev veth0 nodad - ip netns exec at_ns0 ip link set dev veth0 up - ip link add foo type vrf table 1234 - ip link set foo up - ip addr add 172.16.1.101/24 dev veth0b - ip addr add 2401:db00::2/64 dev veth0b nodad - ip link set veth0b master foo +#!/bin/sh + +# Test various socket options that can be set by attaching programs to cgroups. + +CGRP_MNT="/tmp/cgroupv2-test_cgrp2_sock" + +################################################################################ +# +print_result() +{ + local rc=$1 + local status=" OK " + + [ $rc -ne 0 ] && status="FAIL" + + printf "%-50s [%4s]\n" "$2" "$status" } -function attach_bpf { - rm -rf /tmp/cgroupv2 - mkdir -p /tmp/cgroupv2 - mount -t cgroup2 none /tmp/cgroupv2 - mkdir -p /tmp/cgroupv2/foo - test_cgrp2_sock /tmp/cgroupv2/foo foo - echo $$ >> /tmp/cgroupv2/foo/cgroup.procs +check_sock() +{ + out=$(test_cgrp2_sock) + echo $out | grep -q "$1" + if [ $? -ne 0 ]; then + print_result 1 "IPv4: $2" + echo " expected: $1" + echo " have: $out" + rc=1 + else + print_result 0 "IPv4: $2" + fi } -function cleanup { - set +ex - ip netns delete at_ns0 - ip link del veth0 - ip link del foo - umount /tmp/cgroupv2 - rm -rf /tmp/cgroupv2 - set -ex +check_sock6() +{ + out=$(test_cgrp2_sock -6) + echo $out | grep -q "$1" + if [ $? -ne 0 ]; then + print_result 1 "IPv6: $2" + echo " expected: $1" + echo " have: $out" + rc=1 + else + print_result 0 "IPv6: $2" + fi } -function do_test { - ping -c1 -w1 172.16.1.100 - ping6 -c1 -w1 2401:db00::1 +################################################################################ +# + +cleanup() +{ + echo $$ >> ${CGRP_MNT}/cgroup.procs + rmdir ${CGRP_MNT}/sockopts } +cleanup_and_exit() +{ + local rc=$1 + local msg="$2" + + [ -n "$msg" ] && echo "ERROR: $msg" + + ip li del cgrp2_sock + umount ${CGRP_MNT} + + exit $rc +} + + +################################################################################ +# main + +rc=0 + +ip li add cgrp2_sock type dummy 2>/dev/null + +set -e +mkdir -p ${CGRP_MNT} +mount -t cgroup2 none ${CGRP_MNT} +set +e + + +# make sure we have a known start point cleanup 2>/dev/null -config_device -attach_bpf -do_test -cleanup -echo "*** PASS ***" + +mkdir -p ${CGRP_MNT}/sockopts +[ $? -ne 0 ] && cleanup_and_exit 1 "Failed to create cgroup hierarchy" + + +# set pid into cgroup +echo $$ > ${CGRP_MNT}/sockopts/cgroup.procs + +# no bpf program attached, so socket should show no settings +check_sock "dev , mark 0, priority 0" "No programs attached" +check_sock6 "dev , mark 0, priority 0" "No programs attached" + +# verify device is set +# +test_cgrp2_sock -b cgrp2_sock ${CGRP_MNT}/sockopts +if [ $? -ne 0 ]; then + cleanup_and_exit 1 "Failed to install program to set device" +fi +check_sock "dev cgrp2_sock, mark 0, priority 0" "Device set" +check_sock6 "dev cgrp2_sock, mark 0, priority 0" "Device set" + +# verify mark is set +# +test_cgrp2_sock -m 666 ${CGRP_MNT}/sockopts +if [ $? -ne 0 ]; then + cleanup_and_exit 1 "Failed to install program to set mark" +fi +check_sock "dev , mark 666, priority 0" "Mark set" +check_sock6 "dev , mark 666, priority 0" "Mark set" + +# verify priority is set +# +test_cgrp2_sock -p 123 ${CGRP_MNT}/sockopts +if [ $? -ne 0 ]; then + cleanup_and_exit 1 "Failed to install program to set priority" +fi +check_sock "dev , mark 0, priority 123" "Priority set" +check_sock6 "dev , mark 0, priority 123" "Priority set" + +# all 3 at once +# +test_cgrp2_sock -b cgrp2_sock -m 666 -p 123 ${CGRP_MNT}/sockopts +if [ $? -ne 0 ]; then + cleanup_and_exit 1 "Failed to install program to set device, mark and priority" +fi +check_sock "dev cgrp2_sock, mark 666, priority 123" "Priority set" +check_sock6 "dev cgrp2_sock, mark 666, priority 123" "Priority set" + +cleanup_and_exit $rc diff --git a/samples/bpf/test_tunnel_bpf.sh b/samples/bpf/test_tunnel_bpf.sh index 1ff634f187b7fd927bef6a091b96e32dbca27870..410052d9fc37088ccce56123dc746d56957d9124 100755 --- a/samples/bpf/test_tunnel_bpf.sh +++ b/samples/bpf/test_tunnel_bpf.sh @@ -32,6 +32,19 @@ function add_gre_tunnel { ip addr add dev $DEV 10.1.1.200/24 } +function add_erspan_tunnel { + # in namespace + ip netns exec at_ns0 \ + ip link add dev $DEV_NS type $TYPE seq key 2 local 172.16.1.100 remote 172.16.1.200 erspan 123 + ip netns exec at_ns0 ip link set dev $DEV_NS up + ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24 + + # out of namespace + ip link add dev $DEV type $TYPE external + ip link set dev $DEV up + ip addr add dev $DEV 10.1.1.200/24 +} + function add_vxlan_tunnel { # Set static ARP entry here because iptables set-mark works # on L3 packet, as a result not applying to ARP packets, @@ -99,6 +112,18 @@ function test_gre { cleanup } +function test_erspan { + TYPE=erspan + DEV_NS=erspan00 + DEV=erspan11 + config_device + add_erspan_tunnel + attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel + ping -c 1 10.1.1.100 + ip netns exec at_ns0 ping -c 1 10.1.1.200 + cleanup +} + function test_vxlan { TYPE=vxlan DEV_NS=vxlan00 @@ -149,15 +174,20 @@ function cleanup { ip link del veth1 ip link del ipip11 ip link del gretap11 + ip link del vxlan11 ip link del geneve11 + ip link del erspan11 pkill tcpdump pkill cat set -ex } +trap cleanup 0 2 3 6 9 cleanup echo "Testing GRE tunnel..." test_gre +echo "Testing ERSPAN tunnel..." +test_erspan echo "Testing VXLAN tunnel..." test_vxlan echo "Testing GENEVE tunnel..." diff --git a/samples/bpf/xdp_monitor_kern.c b/samples/bpf/xdp_monitor_kern.c new file mode 100644 index 0000000000000000000000000000000000000000..74f3fd8ed729533d55406336fd1d3b03b4ede5fe --- /dev/null +++ b/samples/bpf/xdp_monitor_kern.c @@ -0,0 +1,88 @@ +/* XDP monitor tool, based on tracepoints + * + * Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat Inc. + */ +#include +#include "bpf_helpers.h" + +struct bpf_map_def SEC("maps") redirect_err_cnt = { + .type = BPF_MAP_TYPE_PERCPU_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(u64), + .max_entries = 2, + /* TODO: have entries for all possible errno's */ +}; + +/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format + * Code in: kernel/include/trace/events/xdp.h + */ +struct xdp_redirect_ctx { + unsigned short common_type; // offset:0; size:2; signed:0; + unsigned char common_flags; // offset:2; size:1; signed:0; + unsigned char common_preempt_count;// offset:3; size:1; signed:0; + int common_pid; // offset:4; size:4; signed:1; + + int prog_id; // offset:8; size:4; signed:1; + u32 act; // offset:12 size:4; signed:0; + int ifindex; // offset:16 size:4; signed:1; + int err; // offset:20 size:4; signed:1; + int to_ifindex; // offset:24 size:4; signed:1; + u32 map_id; // offset:28 size:4; signed:0; + int map_index; // offset:32 size:4; signed:1; +}; // offset:36 + +enum { + XDP_REDIRECT_SUCCESS = 0, + XDP_REDIRECT_ERROR = 1 +}; + +static __always_inline +int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) +{ + u32 key = XDP_REDIRECT_ERROR; + int err = ctx->err; + u64 *cnt; + + if (!err) + key = XDP_REDIRECT_SUCCESS; + + cnt = bpf_map_lookup_elem(&redirect_err_cnt, &key); + if (!cnt) + return 0; + *cnt += 1; + + return 0; /* Indicate event was filtered (no further processing)*/ + /* + * Returning 1 here would allow e.g. a perf-record tracepoint + * to see and record these events, but it doesn't work well + * in-practice as stopping perf-record also unload this + * bpf_prog. Plus, there is additional overhead of doing so. + */ +} + +SEC("tracepoint/xdp/xdp_redirect_err") +int trace_xdp_redirect_err(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + + +SEC("tracepoint/xdp/xdp_redirect_map_err") +int trace_xdp_redirect_map_err(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + +/* Likely unloaded when prog starts */ +SEC("tracepoint/xdp/xdp_redirect") +int trace_xdp_redirect(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + +/* Likely unloaded when prog starts */ +SEC("tracepoint/xdp/xdp_redirect_map") +int trace_xdp_redirect_map(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c new file mode 100644 index 0000000000000000000000000000000000000000..b51b4f5e325757920904d826d1eae8198939e3a1 --- /dev/null +++ b/samples/bpf/xdp_monitor_user.c @@ -0,0 +1,295 @@ +/* Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat, Inc. + */ +static const char *__doc__= + "XDP monitor tool, based on tracepoints\n" +; + +static const char *__doc_err_only__= + " NOTICE: Only tracking XDP redirect errors\n" + " Enable TX success stats via '--stats'\n" + " (which comes with a per packet processing overhead)\n" +; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "libbpf.h" +#include "bpf_load.h" +#include "bpf_util.h" + +static int verbose = 1; +static bool debug = false; + +static const struct option long_options[] = { + {"help", no_argument, NULL, 'h' }, + {"debug", no_argument, NULL, 'D' }, + {"stats", no_argument, NULL, 'S' }, + {"sec", required_argument, NULL, 's' }, + {0, 0, NULL, 0 } +}; + +static void usage(char *argv[]) +{ + int i; + printf("\nDOCUMENTATION:\n%s\n", __doc__); + printf("\n"); + printf(" Usage: %s (options-see-below)\n", + argv[0]); + printf(" Listing options:\n"); + for (i = 0; long_options[i].name != 0; i++) { + printf(" --%-15s", long_options[i].name); + if (long_options[i].flag != NULL) + printf(" flag (internal value:%d)", + *long_options[i].flag); + else + printf("(internal short-option: -%c)", + long_options[i].val); + printf("\n"); + } + printf("\n"); +} + +#define NANOSEC_PER_SEC 1000000000 /* 10^9 */ +__u64 gettime(void) +{ + struct timespec t; + int res; + + res = clock_gettime(CLOCK_MONOTONIC, &t); + if (res < 0) { + fprintf(stderr, "Error with gettimeofday! (%i)\n", res); + exit(EXIT_FAILURE); + } + return (__u64) t.tv_sec * NANOSEC_PER_SEC + t.tv_nsec; +} + +enum { + REDIR_SUCCESS = 0, + REDIR_ERROR = 1, +}; +#define REDIR_RES_MAX 2 +static const char *redir_names[REDIR_RES_MAX] = { + [REDIR_SUCCESS] = "Success", + [REDIR_ERROR] = "Error", +}; +static const char *err2str(int err) +{ + if (err < REDIR_RES_MAX) + return redir_names[err]; + return NULL; +} + +struct record { + __u64 counter; + __u64 timestamp; +}; + +struct stats_record { + struct record xdp_redir[REDIR_RES_MAX]; +}; + +static void stats_print_headers(bool err_only) +{ + if (err_only) + printf("\n%s\n", __doc_err_only__); + + printf("%-14s %-10s %-18s %-9s\n", + "XDP_REDIRECT", "pps ", "pps-human-readable", "measure-period"); +} + +static void stats_print(struct stats_record *rec, + struct stats_record *prev, + bool err_only) +{ + int i = 0; + + if (err_only) + i = REDIR_ERROR; + + for (; i < REDIR_RES_MAX; i++) { + struct record *r = &rec->xdp_redir[i]; + struct record *p = &prev->xdp_redir[i]; + __u64 period = 0; + __u64 packets = 0; + double pps = 0; + double period_ = 0; + + if (p->timestamp) { + packets = r->counter - p->counter; + period = r->timestamp - p->timestamp; + if (period > 0) { + period_ = ((double) period / NANOSEC_PER_SEC); + pps = packets / period_; + } + } + + printf("%-14s %-10.0f %'-18.0f %f\n", + err2str(i), pps, pps, period_); + } +} + +static __u64 get_key32_value64_percpu(int fd, __u32 key) +{ + /* For percpu maps, userspace gets a value per possible CPU */ + unsigned int nr_cpus = bpf_num_possible_cpus(); + __u64 values[nr_cpus]; + __u64 sum = 0; + int i; + + if ((bpf_map_lookup_elem(fd, &key, values)) != 0) { + fprintf(stderr, + "ERR: bpf_map_lookup_elem failed key:0x%X\n", key); + return 0; + } + + /* Sum values from each CPU */ + for (i = 0; i < nr_cpus; i++) { + sum += values[i]; + } + return sum; +} + +static bool stats_collect(int fd, struct stats_record *rec) +{ + int i; + + /* TODO: Detect if someone unloaded the perf event_fd's, as + * this can happen by someone running perf-record -e + */ + + for (i = 0; i < REDIR_RES_MAX; i++) { + rec->xdp_redir[i].timestamp = gettime(); + rec->xdp_redir[i].counter = get_key32_value64_percpu(fd, i); + } + return true; +} + +static void stats_poll(int interval, bool err_only) +{ + struct stats_record rec, prev; + int map_fd; + + memset(&rec, 0, sizeof(rec)); + + /* Trick to pretty printf with thousands separators use %' */ + setlocale(LC_NUMERIC, "en_US"); + + /* Header */ + if (verbose) + printf("\n%s", __doc__); + + /* TODO Need more advanced stats on error types */ + if (verbose) + printf(" - Stats map: %s\n", map_data[0].name); + map_fd = map_data[0].fd; + + stats_print_headers(err_only); + fflush(stdout); + + while (1) { + memcpy(&prev, &rec, sizeof(rec)); + stats_collect(map_fd, &rec); + stats_print(&rec, &prev, err_only); + fflush(stdout); + sleep(interval); + } +} + +void print_bpf_prog_info(void) +{ + int i; + + /* Prog info */ + printf("Loaded BPF prog have %d bpf program(s)\n", prog_cnt); + for (i = 0; i < prog_cnt; i++) { + printf(" - prog_fd[%d] = fd(%d)\n", i, prog_fd[i]); + } + + /* Maps info */ + printf("Loaded BPF prog have %d map(s)\n", map_data_count); + for (i = 0; i < map_data_count; i++) { + char *name = map_data[i].name; + int fd = map_data[i].fd; + + printf(" - map_data[%d] = fd(%d) name:%s\n", i, fd, name); + } + + /* Event info */ + printf("Searching for (max:%d) event file descriptor(s)\n", prog_cnt); + for (i = 0; i < prog_cnt; i++) { + if (event_fd[i] != -1) + printf(" - event_fd[%d] = fd(%d)\n", i, event_fd[i]); + } +} + +int main(int argc, char **argv) +{ + int longindex = 0, opt; + int ret = EXIT_SUCCESS; + char bpf_obj_file[256]; + + /* Default settings: */ + bool errors_only = true; + int interval = 2; + + snprintf(bpf_obj_file, sizeof(bpf_obj_file), "%s_kern.o", argv[0]); + + /* Parse commands line args */ + while ((opt = getopt_long(argc, argv, "h", + long_options, &longindex)) != -1) { + switch (opt) { + case 'D': + debug = true; + break; + case 'S': + errors_only = false; + break; + case 's': + interval = atoi(optarg); + break; + case 'h': + default: + usage(argv); + return EXIT_FAILURE; + } + } + + if (load_bpf_file(bpf_obj_file)) { + printf("ERROR - bpf_log_buf: %s", bpf_log_buf); + return 1; + } + if (!prog_fd[0]) { + printf("ERROR - load_bpf_file: %s\n", strerror(errno)); + return 1; + } + + if (debug) { + print_bpf_prog_info(); + } + + /* Unload/stop tracepoint event by closing fd's */ + if (errors_only) { + /* The prog_fd[i] and event_fd[i] depend on the + * order the functions was defined in _kern.c + */ + close(event_fd[2]); /* tracepoint/xdp/xdp_redirect */ + close(prog_fd[2]); /* func: trace_xdp_redirect */ + close(event_fd[3]); /* tracepoint/xdp/xdp_redirect_map */ + close(prog_fd[3]); /* func: trace_xdp_redirect_map */ + } + + stats_poll(interval, errors_only); + + return ret; +} diff --git a/samples/bpf/xdp_redirect_kern.c b/samples/bpf/xdp_redirect_kern.c new file mode 100644 index 0000000000000000000000000000000000000000..8abb151e385f9cc8775cfdb929b2800c17d61c70 --- /dev/null +++ b/samples/bpf/xdp_redirect_kern.c @@ -0,0 +1,90 @@ +/* Copyright (c) 2016 John Fastabend + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#define KBUILD_MODNAME "foo" +#include +#include +#include +#include +#include +#include +#include +#include "bpf_helpers.h" + +struct bpf_map_def SEC("maps") tx_port = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(int), + .max_entries = 1, +}; + +/* Count RX packets, as XDP bpf_prog doesn't get direct TX-success + * feedback. Redirect TX errors can be caught via a tracepoint. + */ +struct bpf_map_def SEC("maps") rxcnt = { + .type = BPF_MAP_TYPE_PERCPU_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(long), + .max_entries = 1, +}; + +static void swap_src_dst_mac(void *data) +{ + unsigned short *p = data; + unsigned short dst[3]; + + dst[0] = p[0]; + dst[1] = p[1]; + dst[2] = p[2]; + p[0] = p[3]; + p[1] = p[4]; + p[2] = p[5]; + p[3] = dst[0]; + p[4] = dst[1]; + p[5] = dst[2]; +} + +SEC("xdp_redirect") +int xdp_redirect_prog(struct xdp_md *ctx) +{ + void *data_end = (void *)(long)ctx->data_end; + void *data = (void *)(long)ctx->data; + struct ethhdr *eth = data; + int rc = XDP_DROP; + int *ifindex, port = 0; + long *value; + u32 key = 0; + u64 nh_off; + + nh_off = sizeof(*eth); + if (data + nh_off > data_end) + return rc; + + ifindex = bpf_map_lookup_elem(&tx_port, &port); + if (!ifindex) + return rc; + + value = bpf_map_lookup_elem(&rxcnt, &key); + if (value) + *value += 1; + + swap_src_dst_mac(data); + return bpf_redirect(*ifindex, 0); +} + +/* Redirect require an XDP bpf_prog loaded on the TX device */ +SEC("xdp_redirect_dummy") +int xdp_redirect_dummy_prog(struct xdp_md *ctx) +{ + return XDP_PASS; +} + +char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/xdp_redirect_map_kern.c b/samples/bpf/xdp_redirect_map_kern.c new file mode 100644 index 0000000000000000000000000000000000000000..740a529ba84f238c91d5195614fe47f10a623bef --- /dev/null +++ b/samples/bpf/xdp_redirect_map_kern.c @@ -0,0 +1,92 @@ +/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#define KBUILD_MODNAME "foo" +#include +#include +#include +#include +#include +#include +#include +#include "bpf_helpers.h" + +struct bpf_map_def SEC("maps") tx_port = { + .type = BPF_MAP_TYPE_DEVMAP, + .key_size = sizeof(int), + .value_size = sizeof(int), + .max_entries = 100, +}; + +/* Count RX packets, as XDP bpf_prog doesn't get direct TX-success + * feedback. Redirect TX errors can be caught via a tracepoint. + */ +struct bpf_map_def SEC("maps") rxcnt = { + .type = BPF_MAP_TYPE_PERCPU_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(long), + .max_entries = 1, +}; + +static void swap_src_dst_mac(void *data) +{ + unsigned short *p = data; + unsigned short dst[3]; + + dst[0] = p[0]; + dst[1] = p[1]; + dst[2] = p[2]; + p[0] = p[3]; + p[1] = p[4]; + p[2] = p[5]; + p[3] = dst[0]; + p[4] = dst[1]; + p[5] = dst[2]; +} + +SEC("xdp_redirect_map") +int xdp_redirect_map_prog(struct xdp_md *ctx) +{ + void *data_end = (void *)(long)ctx->data_end; + void *data = (void *)(long)ctx->data; + struct ethhdr *eth = data; + int rc = XDP_DROP; + int vport, port = 0, m = 0; + long *value; + u32 key = 0; + u64 nh_off; + + nh_off = sizeof(*eth); + if (data + nh_off > data_end) + return rc; + + /* constant virtual port */ + vport = 0; + + /* count packet in global counter */ + value = bpf_map_lookup_elem(&rxcnt, &key); + if (value) + *value += 1; + + swap_src_dst_mac(data); + + /* send packet out physical port */ + return bpf_redirect_map(&tx_port, vport, 0); +} + +/* Redirect require an XDP bpf_prog loaded on the TX device */ +SEC("xdp_redirect_dummy") +int xdp_redirect_dummy_prog(struct xdp_md *ctx) +{ + return XDP_PASS; +} + +char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c new file mode 100644 index 0000000000000000000000000000000000000000..d4d86a273fba47d51b415836e95ae3f8e2b7a235 --- /dev/null +++ b/samples/bpf/xdp_redirect_map_user.c @@ -0,0 +1,145 @@ +/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bpf_load.h" +#include "bpf_util.h" +#include "libbpf.h" + +static int ifindex_in; +static int ifindex_out; +static bool ifindex_out_xdp_dummy_attached = true; + +static __u32 xdp_flags; + +static void int_exit(int sig) +{ + set_link_xdp_fd(ifindex_in, -1, xdp_flags); + if (ifindex_out_xdp_dummy_attached) + set_link_xdp_fd(ifindex_out, -1, xdp_flags); + exit(0); +} + +static void poll_stats(int interval, int ifindex) +{ + unsigned int nr_cpus = bpf_num_possible_cpus(); + __u64 values[nr_cpus], prev[nr_cpus]; + + memset(prev, 0, sizeof(prev)); + + while (1) { + __u64 sum = 0; + __u32 key = 0; + int i; + + sleep(interval); + assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0); + for (i = 0; i < nr_cpus; i++) + sum += (values[i] - prev[i]); + if (sum) + printf("ifindex %i: %10llu pkt/s\n", + ifindex, sum / interval); + memcpy(prev, values, sizeof(values)); + } +} + +static void usage(const char *prog) +{ + fprintf(stderr, + "usage: %s [OPTS] IFINDEX_IN IFINDEX_OUT\n\n" + "OPTS:\n" + " -S use skb-mode\n" + " -N enforce native mode\n", + prog); +} + +int main(int argc, char **argv) +{ + const char *optstr = "SN"; + char filename[256]; + int ret, opt, key = 0; + + while ((opt = getopt(argc, argv, optstr)) != -1) { + switch (opt) { + case 'S': + xdp_flags |= XDP_FLAGS_SKB_MODE; + break; + case 'N': + xdp_flags |= XDP_FLAGS_DRV_MODE; + break; + default: + usage(basename(argv[0])); + return 1; + } + } + + if (optind == argc) { + printf("usage: %s IFINDEX_IN IFINDEX_OUT\n", argv[0]); + return 1; + } + + ifindex_in = strtoul(argv[optind], NULL, 0); + ifindex_out = strtoul(argv[optind + 1], NULL, 0); + printf("input: %d output: %d\n", ifindex_in, ifindex_out); + + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); + + if (load_bpf_file(filename)) { + printf("%s", bpf_log_buf); + return 1; + } + + if (!prog_fd[0]) { + printf("load_bpf_file: %s\n", strerror(errno)); + return 1; + } + + if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) { + printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); + return 1; + } + + /* Loading dummy XDP prog on out-device */ + if (set_link_xdp_fd(ifindex_out, prog_fd[1], + (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { + printf("WARN: link set xdp fd failed on %d\n", ifindex_out); + ifindex_out_xdp_dummy_attached = false; + } + + signal(SIGINT, int_exit); + signal(SIGTERM, int_exit); + + printf("map[0] (vports) = %i, map[1] (map) = %i, map[2] (count) = %i\n", + map_fd[0], map_fd[1], map_fd[2]); + + /* populate virtual to physical port map */ + ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0); + if (ret) { + perror("bpf_update_elem"); + goto out; + } + + poll_stats(2, ifindex_out); + +out: + return 0; +} diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c new file mode 100644 index 0000000000000000000000000000000000000000..4475d837bf2c254011be58ad9e6784374c6694e6 --- /dev/null +++ b/samples/bpf/xdp_redirect_user.c @@ -0,0 +1,143 @@ +/* Copyright (c) 2016 John Fastabend + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bpf_load.h" +#include "bpf_util.h" +#include "libbpf.h" + +static int ifindex_in; +static int ifindex_out; +static bool ifindex_out_xdp_dummy_attached = true; + +static __u32 xdp_flags; + +static void int_exit(int sig) +{ + set_link_xdp_fd(ifindex_in, -1, xdp_flags); + if (ifindex_out_xdp_dummy_attached) + set_link_xdp_fd(ifindex_out, -1, xdp_flags); + exit(0); +} + +static void poll_stats(int interval, int ifindex) +{ + unsigned int nr_cpus = bpf_num_possible_cpus(); + __u64 values[nr_cpus], prev[nr_cpus]; + + memset(prev, 0, sizeof(prev)); + + while (1) { + __u64 sum = 0; + __u32 key = 0; + int i; + + sleep(interval); + assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0); + for (i = 0; i < nr_cpus; i++) + sum += (values[i] - prev[i]); + if (sum) + printf("ifindex %i: %10llu pkt/s\n", + ifindex, sum / interval); + memcpy(prev, values, sizeof(values)); + } +} + +static void usage(const char *prog) +{ + fprintf(stderr, + "usage: %s [OPTS] IFINDEX_IN IFINDEX_OUT\n\n" + "OPTS:\n" + " -S use skb-mode\n" + " -N enforce native mode\n", + prog); +} + + +int main(int argc, char **argv) +{ + const char *optstr = "SN"; + char filename[256]; + int ret, opt, key = 0; + + while ((opt = getopt(argc, argv, optstr)) != -1) { + switch (opt) { + case 'S': + xdp_flags |= XDP_FLAGS_SKB_MODE; + break; + case 'N': + xdp_flags |= XDP_FLAGS_DRV_MODE; + break; + default: + usage(basename(argv[0])); + return 1; + } + } + + if (optind == argc) { + printf("usage: %s IFINDEX_IN IFINDEX_OUT\n", argv[0]); + return 1; + } + + ifindex_in = strtoul(argv[optind], NULL, 0); + ifindex_out = strtoul(argv[optind + 1], NULL, 0); + printf("input: %d output: %d\n", ifindex_in, ifindex_out); + + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); + + if (load_bpf_file(filename)) { + printf("%s", bpf_log_buf); + return 1; + } + + if (!prog_fd[0]) { + printf("load_bpf_file: %s\n", strerror(errno)); + return 1; + } + + if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) { + printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); + return 1; + } + + /* Loading dummy XDP prog on out-device */ + if (set_link_xdp_fd(ifindex_out, prog_fd[1], + (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { + printf("WARN: link set xdp fd failed on %d\n", ifindex_out); + ifindex_out_xdp_dummy_attached = false; + } + + signal(SIGINT, int_exit); + signal(SIGTERM, int_exit); + + /* bpf redirect port */ + ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0); + if (ret) { + perror("bpf_update_elem"); + goto out; + } + + poll_stats(2, ifindex_out); + +out: + return 0; +} diff --git a/samples/sockmap/Makefile b/samples/sockmap/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9291ab8e0f8c5a089425ae65f9ee20e718e0a9ff --- /dev/null +++ b/samples/sockmap/Makefile @@ -0,0 +1,78 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := sockmap + +# Libbpf dependencies +LIBBPF := ../../tools/lib/bpf/bpf.o + +HOSTCFLAGS += -I$(objtree)/usr/include +HOSTCFLAGS += -I$(srctree)/tools/lib/ +HOSTCFLAGS += -I$(srctree)/tools/testing/selftests/bpf/ +HOSTCFLAGS += -I$(srctree)/tools/lib/ -I$(srctree)/tools/include +HOSTCFLAGS += -I$(srctree)/tools/perf + +sockmap-objs := ../bpf/bpf_load.o $(LIBBPF) sockmap_user.o + +# Tell kbuild to always build the programs +always := $(hostprogs-y) +always += sockmap_kern.o + +HOSTLOADLIBES_sockmap += -lelf -lpthread + +# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: +# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang +LLC ?= llc +CLANG ?= clang + +# Trick to allow make to be run from this directory +all: + $(MAKE) -C ../../ $(CURDIR)/ + +clean: + $(MAKE) -C ../../ M=$(CURDIR) clean + @rm -f *~ + +$(obj)/syscall_nrs.s: $(src)/syscall_nrs.c + $(call if_changed_dep,cc_s_c) + +$(obj)/syscall_nrs.h: $(obj)/syscall_nrs.s FORCE + $(call filechk,offsets,__SYSCALL_NRS_H__) + +clean-files += syscall_nrs.h + +FORCE: + + +# Verify LLVM compiler tools are available and bpf target is supported by llc +.PHONY: verify_cmds verify_target_bpf $(CLANG) $(LLC) + +verify_cmds: $(CLANG) $(LLC) + @for TOOL in $^ ; do \ + if ! (which -- "$${TOOL}" > /dev/null 2>&1); then \ + echo "*** ERROR: Cannot find LLVM tool $${TOOL}" ;\ + exit 1; \ + else true; fi; \ + done + +verify_target_bpf: verify_cmds + @if ! (${LLC} -march=bpf -mattr=help > /dev/null 2>&1); then \ + echo "*** ERROR: LLVM (${LLC}) does not support 'bpf' target" ;\ + echo " NOTICE: LLVM version >= 3.7.1 required" ;\ + exit 2; \ + else true; fi + +$(src)/*.c: verify_target_bpf + +# asm/sysreg.h - inline assembly used by it is incompatible with llvm. +# But, there is no easy way to fix it, so just exclude it since it is +# useless for BPF samples. +$(obj)/%.o: $(src)/%.c + $(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \ + -D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \ + -Wno-compare-distinct-pointer-types \ + -Wno-gnu-variable-sized-type-not-at-end \ + -Wno-address-of-packed-member -Wno-tautological-compare \ + -Wno-unknown-warning-option \ + -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@ diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c new file mode 100644 index 0000000000000000000000000000000000000000..f9b38ef82dc2449e56094b9c8c0c805673c0a7b0 --- /dev/null +++ b/samples/sockmap/sockmap_kern.c @@ -0,0 +1,108 @@ +/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include +#include "../../tools/testing/selftests/bpf/bpf_helpers.h" +#include "../../tools/testing/selftests/bpf/bpf_endian.h" + +/* Sockmap sample program connects a client and a backend together + * using cgroups. + * + * client:X <---> frontend:80 client:X <---> backend:80 + * + * For simplicity we hard code values here and bind 1:1. The hard + * coded values are part of the setup in sockmap.sh script that + * is associated with this BPF program. + * + * The bpf_printk is verbose and prints information as connections + * are established and verdicts are decided. + */ + +#define bpf_printk(fmt, ...) \ +({ \ + char ____fmt[] = fmt; \ + bpf_trace_printk(____fmt, sizeof(____fmt), \ + ##__VA_ARGS__); \ +}) + +struct bpf_map_def SEC("maps") sock_map = { + .type = BPF_MAP_TYPE_SOCKMAP, + .key_size = sizeof(int), + .value_size = sizeof(int), + .max_entries = 20, +}; + +SEC("sk_skb1") +int bpf_prog1(struct __sk_buff *skb) +{ + return skb->len; +} + +SEC("sk_skb2") +int bpf_prog2(struct __sk_buff *skb) +{ + __u32 lport = skb->local_port; + __u32 rport = skb->remote_port; + int ret = 0; + + if (lport == 10000) + ret = 10; + else + ret = 1; + + bpf_printk("sockmap: %d -> %d @ %d\n", lport, bpf_ntohl(rport), ret); + return bpf_sk_redirect_map(&sock_map, ret, 0); +} + +SEC("sockops") +int bpf_sockmap(struct bpf_sock_ops *skops) +{ + __u32 lport, rport; + int op, err = 0, index, key, ret; + + + op = (int) skops->op; + + switch (op) { + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + lport = skops->local_port; + rport = skops->remote_port; + + if (lport == 10000) { + ret = 1; + err = bpf_sock_map_update(skops, &sock_map, &ret, + BPF_NOEXIST); + bpf_printk("passive(%i -> %i) map ctx update err: %d\n", + lport, bpf_ntohl(rport), err); + } + break; + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + lport = skops->local_port; + rport = skops->remote_port; + + if (bpf_ntohl(rport) == 10001) { + ret = 10; + err = bpf_sock_map_update(skops, &sock_map, &ret, + BPF_NOEXIST); + bpf_printk("active(%i -> %i) map ctx update err: %d\n", + lport, bpf_ntohl(rport), err); + } + break; + default: + break; + } + + return 0; +} +char _license[] SEC("license") = "GPL"; diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c new file mode 100644 index 0000000000000000000000000000000000000000..7cc9d228216ff10313648a33549f10232cb05eb2 --- /dev/null +++ b/samples/sockmap/sockmap_user.c @@ -0,0 +1,294 @@ +/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../bpf/bpf_load.h" +#include "../bpf/bpf_util.h" +#include "../bpf/libbpf.h" + +int running; +void running_handler(int a); + +/* randomly selected ports for testing on lo */ +#define S1_PORT 10000 +#define S2_PORT 10001 + +static int sockmap_test_sockets(int rate, int dot) +{ + int i, sc, err, max_fd, one = 1; + int s1, s2, c1, c2, p1, p2; + struct sockaddr_in addr; + struct timeval timeout; + char buf[1024] = {0}; + int *fds[4] = {&s1, &s2, &c1, &c2}; + fd_set w; + + s1 = s2 = p1 = p2 = c1 = c2 = 0; + + /* Init sockets */ + for (i = 0; i < 4; i++) { + *fds[i] = socket(AF_INET, SOCK_STREAM, 0); + if (*fds[i] < 0) { + perror("socket s1 failed()"); + err = *fds[i]; + goto out; + } + } + + /* Allow reuse */ + for (i = 0; i < 2; i++) { + err = setsockopt(*fds[i], SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sizeof(one)); + if (err) { + perror("setsockopt failed()"); + goto out; + } + } + + /* Non-blocking sockets */ + for (i = 0; i < 4; i++) { + err = ioctl(*fds[i], FIONBIO, (char *)&one); + if (err < 0) { + perror("ioctl s1 failed()"); + goto out; + } + } + + /* Bind server sockets */ + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + addr.sin_port = htons(S1_PORT); + err = bind(s1, (struct sockaddr *)&addr, sizeof(addr)); + if (err < 0) { + perror("bind s1 failed()\n"); + goto out; + } + + addr.sin_port = htons(S2_PORT); + err = bind(s2, (struct sockaddr *)&addr, sizeof(addr)); + if (err < 0) { + perror("bind s2 failed()\n"); + goto out; + } + + /* Listen server sockets */ + addr.sin_port = htons(S1_PORT); + err = listen(s1, 32); + if (err < 0) { + perror("listen s1 failed()\n"); + goto out; + } + + addr.sin_port = htons(S2_PORT); + err = listen(s2, 32); + if (err < 0) { + perror("listen s1 failed()\n"); + goto out; + } + + /* Initiate Connect */ + addr.sin_port = htons(S1_PORT); + err = connect(c1, (struct sockaddr *)&addr, sizeof(addr)); + if (err < 0 && errno != EINPROGRESS) { + perror("connect c1 failed()\n"); + goto out; + } + + addr.sin_port = htons(S2_PORT); + err = connect(c2, (struct sockaddr *)&addr, sizeof(addr)); + if (err < 0 && errno != EINPROGRESS) { + perror("connect c2 failed()\n"); + goto out; + } + + /* Accept Connecrtions */ + p1 = accept(s1, NULL, NULL); + if (p1 < 0) { + perror("accept s1 failed()\n"); + goto out; + } + + p2 = accept(s2, NULL, NULL); + if (p2 < 0) { + perror("accept s1 failed()\n"); + goto out; + } + + max_fd = p2; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + printf("connected sockets: c1 <-> p1, c2 <-> p2\n"); + printf("cgroups binding: c1(%i) <-> s1(%i) - - - c2(%i) <-> s2(%i)\n", + c1, s1, c2, s2); + + /* Ping/Pong data from client to server */ + sc = send(c1, buf, sizeof(buf), 0); + if (sc < 0) { + perror("send failed()\n"); + goto out; + } + + do { + int s, rc, i; + + /* FD sets */ + FD_ZERO(&w); + FD_SET(c1, &w); + FD_SET(c2, &w); + FD_SET(p1, &w); + FD_SET(p2, &w); + + s = select(max_fd + 1, &w, NULL, NULL, &timeout); + if (s == -1) { + perror("select()"); + break; + } else if (!s) { + fprintf(stderr, "unexpected timeout\n"); + break; + } + + for (i = 0; i <= max_fd && s > 0; ++i) { + if (!FD_ISSET(i, &w)) + continue; + + s--; + + rc = recv(i, buf, sizeof(buf), 0); + if (rc < 0) { + if (errno != EWOULDBLOCK) { + perror("recv failed()\n"); + break; + } + } + + if (rc == 0) { + close(i); + break; + } + + sc = send(i, buf, rc, 0); + if (sc < 0) { + perror("send failed()\n"); + break; + } + } + sleep(rate); + if (dot) { + printf("."); + fflush(stdout); + + } + } while (running); + +out: + close(s1); + close(s2); + close(p1); + close(p2); + close(c1); + close(c2); + return err; +} + +int main(int argc, char **argv) +{ + int rate = 1, dot = 1; + char filename[256]; + int err, cg_fd; + char *cg_path; + + cg_path = argv[argc - 1]; + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); + + running = 1; + + /* catch SIGINT */ + signal(SIGINT, running_handler); + + if (load_bpf_file(filename)) { + fprintf(stderr, "load_bpf_file: (%s) %s\n", + filename, strerror(errno)); + return 1; + } + + /* Cgroup configuration */ + cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); + if (cg_fd < 0) { + fprintf(stderr, "ERROR: (%i) open cg path failed: %s\n", + cg_fd, cg_path); + return cg_fd; + } + + /* Attach programs to sockmap */ + err = bpf_prog_attach(prog_fd[0], map_fd[0], + BPF_SK_SKB_STREAM_PARSER, 0); + if (err) { + fprintf(stderr, "ERROR: bpf_prog_attach (sockmap): %d (%s)\n", + err, strerror(errno)); + return err; + } + + err = bpf_prog_attach(prog_fd[1], map_fd[0], + BPF_SK_SKB_STREAM_VERDICT, 0); + if (err) { + fprintf(stderr, "ERROR: bpf_prog_attach (sockmap): %d (%s)\n", + err, strerror(errno)); + return err; + } + + /* Attach to cgroups */ + err = bpf_prog_attach(prog_fd[2], cg_fd, BPF_CGROUP_SOCK_OPS, 0); + if (err) { + fprintf(stderr, "ERROR: bpf_prog_attach (groups): %d (%s)\n", + err, strerror(errno)); + return err; + } + + err = sockmap_test_sockets(rate, dot); + if (err) { + fprintf(stderr, "ERROR: test socket failed: %d\n", err); + return err; + } + return 0; +} + +void running_handler(int a) +{ + running = 0; +} diff --git a/samples/v4l/v4l2-pci-skeleton.c b/samples/v4l/v4l2-pci-skeleton.c index 93b76c3220fddc888397c0005507eeafdd1fb6a3..483e9bca944423db0f712d6a9621940447fb1674 100644 --- a/samples/v4l/v4l2-pci-skeleton.c +++ b/samples/v4l/v4l2-pci-skeleton.c @@ -282,7 +282,7 @@ static void stop_streaming(struct vb2_queue *vq) * vb2_ops_wait_prepare/finish helper functions. If q->lock would be NULL, * then this driver would have to provide these ops. */ -static struct vb2_ops skel_qops = { +static const struct vb2_ops skel_qops = { .queue_setup = queue_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index dd8e2dde0b34b3759fe6061eb5c2887f4ecd21fd..9ffd3dda3889c56a7a72229bed21ff5c49d62856 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -85,8 +85,8 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) # try-run # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) -# Exit code chooses option. "$$TMP" is can be used as temporary file and -# is automatically cleaned up. +# Exit code chooses option. "$$TMP" serves as a temporary file and is +# automatically cleaned up. try-run = $(shell set -e; \ TMP="$(TMPOUT).$$$$.tmp"; \ TMPO="$(TMPOUT).$$$$.o"; \ @@ -261,7 +261,6 @@ make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1))))) any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^) # Execute command if command has changed or prerequisite(s) are updated. -# if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ @set -e; \ $(echo-cmd) $(cmd_$(1)); \ @@ -315,7 +314,7 @@ if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \ $(rule_$(1)), @:) ### -# why - tell why a a target got build +# why - tell why a target got built # enabled by make V=2 # Output (listed in the order they are checked): # (1) - due to target is PHONY diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic index 95f7d80901524a4c966505397af6931f3e3316f3..a6c8c17808551aa146102ccb4132f8f5605ea74d 100644 --- a/scripts/Makefile.asm-generic +++ b/scripts/Makefile.asm-generic @@ -1,9 +1,9 @@ # include/asm-generic contains a lot of files that are used # verbatim by several architectures. # -# This Makefile reads the file arch/$(SRCARCH)/include/asm/Kbuild +# This Makefile reads the file arch/$(SRCARCH)/include/$(src)/Kbuild # and for each file listed in this file with generic-y creates -# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/asm) +# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/$(src)) kbuild-file := $(srctree)/arch/$(SRCARCH)/include/$(src)/Kbuild -include $(kbuild-file) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4a9a2cec0a1b52d601f9f057eb8fbb515e69de50..061d0c3a420ad58084df157a143e76133f304dc2 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -229,8 +229,8 @@ ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") endif # Due to recursion, we must skip empty.o. # The empty.o file is created in the make process in order to determine -# the target endianness and word size. It is made before all other C -# files, including recordmcount. +# the target endianness and word size. It is made before all other C +# files, including recordmcount. sub_cmd_record_mcount = \ if [ $(@) != "scripts/mod/empty.o" ]; then \ $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ @@ -245,23 +245,29 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; recordmcount_source := $(srctree)/scripts/recordmcount.pl -endif +endif # BUILD_C_RECORDMCOUNT cmd_record_mcount = \ if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \ "$(CC_FLAGS_FTRACE)" ]; then \ $(sub_cmd_record_mcount) \ fi; -endif +endif # CONFIG_FTRACE_MCOUNT_RECORD ifdef CONFIG_STACK_VALIDATION ifneq ($(SKIP_STACK_VALIDATION),1) __objtool_obj := $(objtree)/tools/objtool/objtool -objtool_args = check +objtool_args = $(if $(CONFIG_ORC_UNWINDER),orc generate,check) + ifndef CONFIG_FRAME_POINTER objtool_args += --no-fp endif +ifdef CONFIG_GCOV_KERNEL +objtool_args += --no-unreachable +else +objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable) +endif # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file @@ -276,6 +282,11 @@ objtool_obj = $(if $(patsubst y%,, \ endif # SKIP_STACK_VALIDATION endif # CONFIG_STACK_VALIDATION +# Rebuild all objects when objtool changes, or is enabled/disabled. +objtool_dep = $(objtool_obj) \ + $(wildcard include/config/orc/unwinder.h \ + include/config/stack/validation.h) + define rule_cc_o_c $(call echo-cmd,checksrc) $(cmd_checksrc) \ $(call cmd_and_fixdep,cc_o_c) \ @@ -298,13 +309,13 @@ cmd_undef_syms = echo endif # Built-in and composite module parts -$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE +$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) # Single-part modules are special since we need to mark them in $(MODVERDIR) -$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE +$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) @{ echo $(@:.o=.ko); echo $@; \ @@ -399,7 +410,7 @@ cmd_modversions_S = \ endif endif -$(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE +$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE $(call if_changed_rule,as_o_S) targets += $(real-objs-y) $(real-objs-m) $(lib-y) diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst index 34614a48b717eafa2c15f418e6e6769905e32ec1..993fb85982df2df2a7f8e20780d0cfbe3cb732e8 100644 --- a/scripts/Makefile.dtbinst +++ b/scripts/Makefile.dtbinst @@ -14,7 +14,7 @@ src := $(obj) PHONY := __dtbs_install __dtbs_install: -export dtbinst-root ?= $(obj) +export dtbinst_root ?= $(obj) include include/config/auto.conf include scripts/Kbuild.include @@ -27,7 +27,7 @@ dtbinst-dirs := $(dts-dirs) quiet_cmd_dtb_install = INSTALL $< cmd_dtb_install = mkdir -p $(2); cp $< $(2) -install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) +install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj)) $(dtbinst-files): %.dtb: $(obj)/%.dtb $(call cmd,dtb_install,$(install-dir)) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index fb3522fd87029f8e841469d2bb300ef6eb7fe1cb..ae8a1357d01df7f2220088cdae09dca4fcec43f3 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -37,6 +37,7 @@ warning-2 += $(call cc-option, -Wlogical-op) warning-2 += $(call cc-option, -Wmissing-field-initializers) warning-2 += $(call cc-option, -Wsign-compare) warning-2 += $(call cc-option, -Wmaybe-uninitialized) +warning-2 += $(call cc-option, -Wunused-macros) warning-3 := -Wbad-function-cast warning-3 += -Wcast-qual diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst deleted file mode 100644 index b2729003525323975e33b3e57cc11274ab52085b..0000000000000000000000000000000000000000 --- a/scripts/Makefile.fwinst +++ /dev/null @@ -1,70 +0,0 @@ -# ========================================================================== -# Installing firmware -# -# We don't include the .config, so all firmware files are in $(fw-shipped-) -# rather than in $(fw-shipped-y) or $(fw-shipped-m). -# ========================================================================== - -INSTALL := install -src := $(obj) - -# For modules_install installing firmware, we want to see .config -# But for firmware_install, we don't care, but don't want to require it. --include $(objtree)/.config - -include scripts/Kbuild.include -include $(src)/Makefile - -include scripts/Makefile.host - -mod-fw := $(fw-shipped-m) -# If CONFIG_FIRMWARE_IN_KERNEL isn't set, then install the -# firmware for in-kernel drivers too. -ifndef CONFIG_FIRMWARE_IN_KERNEL -mod-fw += $(fw-shipped-y) -endif - -ifneq ($(KBUILD_SRC),) -# Create output directory if not already present -_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) - -firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all)))) -# Create directories for firmware in subdirectories -_dummy := $(foreach d,$(firmware-dirs), $(shell [ -d $(d) ] || mkdir -p $(d))) -endif - -installed-mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(mod-fw)) - -installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all)) - -quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@) - cmd_install = mkdir -p $(@D); $(INSTALL) -m0644 $< $@ - -$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% - $(call cmd,install) - -PHONY += __fw_install __fw_modinst FORCE - -.PHONY: $(PHONY) - -__fw_install: $(installed-fw) - -__fw_modinst: $(installed-mod-fw) - @: - -__fw_modbuild: $(addprefix $(obj)/,$(mod-fw)) - @: - -FORCE: - -# Read all saved command lines and dependencies for the $(targets) we -# may be building using $(if_changed{,_dep}). As an optimization, we -# don't need to read them if the target does not exist; we will rebuild -# anyway in that case. - -targets := $(wildcard $(sort $(targets))) -cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) - -ifneq ($(cmd_files),) - include $(cmd_files) -endif diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 2e0e2eaa397fa05c6b25247092ba0035fd6417f8..d1f7b0d6be66da15585058dfbdbca4a7b13378ac 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -27,6 +27,7 @@ ifdef CONFIG_GCC_PLUGINS gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 58c05e5d9870b6c18a72da7dc44ff3112994946d..5e975fee0f5b44343807d2f4e92954cb521497dc 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -173,10 +173,10 @@ cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ ld_flags = $(LDFLAGS) $(ldflags-y) +DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes + dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ - -I$(srctree)/arch/$(SRCARCH)/boot/dts \ - -I$(srctree)/scripts/dtc/include-prefixes \ - -I$(srctree)/drivers/of/testcase-data \ + $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ # Finds the multi-part object the current object will be linked into @@ -194,15 +194,6 @@ endef ifdef REGENERATE_PARSERS -# GPERF -# --------------------------------------------------------------------------- -quiet_cmd_gperf = GPERF $@ - cmd_gperf = gperf -t --output-file $@ -a -C -E -g -k 1,3,$$ -p -t $< - -.PRECIOUS: $(src)/%.hash.c_shipped -$(src)/%.hash.c_shipped: $(src)/%.gperf - $(call cmd,gperf) - # LEX # --------------------------------------------------------------------------- LEX_PREFIX = $(if $(LEX_PREFIX_${baseprereq}),$(LEX_PREFIX_${baseprereq}),yy) @@ -317,7 +308,7 @@ quiet_cmd_dtc = DTC $@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(DTC) -O dtb -o $@ -b 0 \ - -i $(dir $<) $(DTC_FLAGS) \ + $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index ec10d9345bc2d9b978d8cae4d85bf2fd89ab121c..0372b33febe52f74978420c2c559adef5e815374 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -1,5 +1,5 @@ ### -# Makefile.basic lists the most basic programs used during the build process. +# This Makefile lists the most basic programs used during the build process. # The programs listed herein are what are needed to do the basic stuff, # such as fix file dependencies. # This initial step is needed to avoid files to be recompiled diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index fff818b92acb7e3e469ce06cc722f3ab0f275171..bbf62cb1f8190917e930d7003eddbf20f0fececc 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -25,7 +25,7 @@ * * So we play the same trick that "mkdep" played before. We replace * the dependency on autoconf.h by a dependency on every config - * option which is mentioned in any of the listed prequisites. + * option which is mentioned in any of the listed prerequisites. * * kconfig populates a tree in include/config/ with an empty file * for each config symbol and when the configuration is updated @@ -34,7 +34,7 @@ * the config symbols are rebuilt. * * So if the user changes his CONFIG_HIS_DRIVER option, only the objects - * which depend on "include/linux/config/his/driver.h" will be rebuilt, + * which depend on "include/config/his/driver.h" will be rebuilt, * so most likely only his driver ;-) * * The idea above dates, by the way, back to Michael E Chastain, AFAIK. @@ -75,7 +75,7 @@ * and then basically copies the ..d file to stdout, in the * process filtering out the dependency on autoconf.h and adding * dependencies on include/config/my/option.h for every - * CONFIG_MY_OPTION encountered in any of the prequisites. + * CONFIG_MY_OPTION encountered in any of the prerequisites. * * It will also filter out all the dependencies on *.ver. We need * to make sure that the generated version checksum are globally up diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2287a0bca863bf57ffabaae9de58aab0174826c3..8b80bac055e490219f97d913f33bce165960fe92 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -145,7 +145,8 @@ sub list_types { close($script); my @types = (); - for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) { + # Also catch when type or level is passed through a variable + for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { push (@types, $_); } @types = sort(uniq(@types)); @@ -2715,10 +2716,10 @@ sub process { my $typo_fix = $spelling_fix{lc($typo)}; $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); - my $msg_type = \&WARN; - $msg_type = \&CHK if ($file); - if (&{$msg_type}("TYPO_SPELLING", - "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && + my $msg_level = \&WARN; + $msg_level = \&CHK if ($file); + if (&{$msg_level}("TYPO_SPELLING", + "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && $fix) { $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; } @@ -2753,10 +2754,10 @@ sub process { $rawline =~ /\b59\s+Temple\s+Pl/i || $rawline =~ /\b51\s+Franklin\s+St/i) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - my $msg_type = \&ERROR; - $msg_type = \&CHK if ($file); - &{$msg_type}("FSF_MAILING_ADDRESS", - "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) + my $msg_level = \&ERROR; + $msg_level = \&CHK if ($file); + &{$msg_level}("FSF_MAILING_ADDRESS", + "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) } # check for Kconfig help text having a real description @@ -2875,7 +2876,7 @@ sub process { # #defines that are a single string # # There are 3 different line length message types: -# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength +# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length # LONG_LINE_STRING a string starts before but extends beyond $max_line_length # LONG_LINE all other lines longer than $max_line_length # @@ -3810,10 +3811,10 @@ sub process { # avoid BUG() or BUG_ON() if ($line =~ /\b(?:BUG|BUG_ON)\b/) { - my $msg_type = \&WARN; - $msg_type = \&CHK if ($file); - &{$msg_type}("AVOID_BUG", - "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); + my $msg_level = \&WARN; + $msg_level = \&CHK if ($file); + &{$msg_level}("AVOID_BUG", + "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); } # avoid LINUX_VERSION_CODE @@ -4339,11 +4340,11 @@ sub process { # messages are ERROR, but ?: are CHK if ($ok == 0) { - my $msg_type = \&ERROR; - $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); + my $msg_level = \&ERROR; + $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); - if (&{$msg_type}("SPACING", - "spaces required around that '$op' $at\n" . $hereptr)) { + if (&{$msg_level}("SPACING", + "spaces required around that '$op' $at\n" . $hereptr)) { $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; if (defined $fix_elements[$n + 2]) { $fix_elements[$n + 2] =~ s/^\s+//; @@ -4496,6 +4497,30 @@ sub process { } } +# check for unnecessary parentheses around comparisons in if uses + if ($^V && $^V ge 5.10.0 && defined($stat) && + $stat =~ /(^.\s*if\s*($balanced_parens))/) { + my $if_stat = $1; + my $test = substr($2, 1, -1); + my $herectx; + while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { + my $match = $1; + # avoid parentheses around potential macro args + next if ($match =~ /^\s*\w+\s*$/); + if (!defined($herectx)) { + $herectx = $here . "\n"; + my $cnt = statement_rawlines($if_stat); + for (my $n = 0; $n < $cnt; $n++) { + my $rl = raw_line($linenr, $n); + $herectx .= $rl . "\n"; + last if $rl =~ /^[ \+].*\{/; + } + } + CHK("UNNECESSARY_PARENTHESES", + "Unnecessary parentheses around '$match'\n" . $herectx); + } + } + #goto labels aren't indented, allow a single space however if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { @@ -6365,7 +6390,7 @@ sub process { exit(0); } - if (!$is_patch && $file !~ /cover-letter\.patch$/) { + if (!$is_patch && $filename !~ /cover-letter\.patch$/) { ERROR("NOT_UNIFIED_DIFF", "Does not appear to be a unified-diff format patch\n"); } diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 4b72b530c84f1f4b4e98d8342d9d62fefe8d34d6..62ea8f83d4a023a9780c6dc219d8f29ba244c506 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -873,7 +873,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no while (size--) reg = (reg << 32) | fdt32_to_cpu(*(cells++)); - snprintf(unit_addr, sizeof(unit_addr), "%zx", reg); + snprintf(unit_addr, sizeof(unit_addr), "%llx", (unsigned long long)reg); if (!streq(unitname, unit_addr)) FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", node->fullpath, unit_addr); diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff index f9a3d8d23c644a536ce0c9aaeed2c04b580af2f4..8c4fbad2055e59e973a82ce8aa6c00a58047e315 100755 --- a/scripts/dtc/dtx_diff +++ b/scripts/dtc/dtx_diff @@ -86,6 +86,7 @@ eod compile_to_dts() { dtx="$1" + dtc_include="$2" if [ -d "${dtx}" ] ; then @@ -113,7 +114,7 @@ compile_to_dts() { # ----- input is DTS (source) if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ - | ${DTC} -I dts ) ; then + | ${DTC} ${dtc_include} -I dts ) ; then return fi @@ -320,18 +321,13 @@ fi cpp_flags="\ -nostdinc \ - -I${srctree}/arch/${ARCH}/boot/dts \ -I${srctree}/scripts/dtc/include-prefixes \ - -I${srctree}/drivers/of/testcase-data \ -undef -D__DTS__" -dtc_flags="\ - -i ${srctree}/arch/${ARCH}/boot/dts/ \ - -i ${srctree}/kernel/dts \ - ${dtx_path_1_dtc_include} \ - ${dtx_path_2_dtc_include}" - -DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" +DTC="\ + ${DTC} \ + -i ${srctree}/scripts/dtc/include-prefixes \ + -O dts -qq -f ${dtc_sort} -o -" # ----- do the diff or decompile @@ -339,11 +335,11 @@ DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" if (( ${cmd_diff} )) ; then diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \ - <(compile_to_dts "${dtx_file_1}") \ - <(compile_to_dts "${dtx_file_2}") + <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \ + <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}") else - compile_to_dts "${dtx_file_1}" + compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}" fi diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index cdaac8c66734b05971c4e4476b73f9572aa936e3..0073af326449864b4da5f7a64677c0de2d5eafa2 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -436,9 +436,6 @@ static int is_pure_ops_struct(const_tree node) gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); - /* XXX: Do not apply randomization to all-ftpr structs yet. */ - return 0; - for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { const_tree fieldtype = get_field_type(field); enum tree_code code = TREE_CODE(fieldtype); diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index fa3d7a4b26f2f9299f6ad34909332475f37d5a63..3f8dd486817814c5d96bdfbd1753a909562c6829 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -16,6 +16,7 @@ * Options: * -fplugin-arg-structleak_plugin-disable * -fplugin-arg-structleak_plugin-verbose + * -fplugin-arg-structleak_plugin-byref-all * * Usage: * $ # for 4.5/4.6/C based 4.7 @@ -42,6 +43,7 @@ static struct plugin_info structleak_plugin_info = { }; static bool verbose; +static bool byref_all; static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) { @@ -150,7 +152,9 @@ static void initialize(tree var) /* these aren't the 0days you're looking for */ if (verbose) inform(DECL_SOURCE_LOCATION(var), - "userspace variable will be forcibly initialized"); + "%s variable will be forcibly initialized", + (byref_all && TREE_ADDRESSABLE(var)) ? "byref" + : "userspace"); /* build the initializer expression */ initializer = build_constructor(TREE_TYPE(var), NULL); @@ -190,7 +194,8 @@ static unsigned int structleak_execute(void) continue; /* if the type is of interest, examine the variable */ - if (TYPE_USERSPACE(type)) + if (TYPE_USERSPACE(type) || + (byref_all && TREE_ADDRESSABLE(var))) initialize(var); } @@ -232,6 +237,10 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc verbose = true; continue; } + if (!strcmp(argv[i].key, "byref-all")) { + byref_all = true; + continue; + } error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); } diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile index 8b00031f53497035b68bfe65bd682989430fe016..ab3cfe727a4eeacaadceb1d16c0234dd774bf4be 100644 --- a/scripts/gdb/linux/Makefile +++ b/scripts/gdb/linux/Makefile @@ -1,6 +1,6 @@ always := gdb-scripts -SRCTREE := $(shell cd $(srctree) && /bin/pwd) +SRCTREE := $(abspath $(srctree)) $(obj)/gdb-scripts: ifneq ($(KBUILD_SRC),) diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index aca33b98bf634b269b9857f5bc08d2e315f5f8d3..3c23bab3367bf4d389f850098faf7784ec92c004 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -9,6 +9,6 @@ HOSTCFLAGS_parse.tab.o := -I$(src) HOSTCFLAGS_lex.lex.o := -I$(src) # dependencies on generated files need to be listed explicitly -$(obj)/lex.lex.o: $(obj)/keywords.hash.c $(obj)/parse.tab.h +$(obj)/lex.lex.o: $(obj)/parse.tab.h -clean-files := keywords.hash.c lex.lex.c parse.tab.c parse.tab.h +clean-files := lex.lex.c parse.tab.c parse.tab.h diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c new file mode 100644 index 0000000000000000000000000000000000000000..9f40bcd17d07f5bbeb1ab2fa0793d632116ae06e --- /dev/null +++ b/scripts/genksyms/keywords.c @@ -0,0 +1,74 @@ +static struct resword { + const char *name; + int token; +} keywords[] = { + { "EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW }, + { "EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW }, + { "EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW }, + { "EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW }, + { "EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW }, + { "__asm", ASM_KEYW }, + { "__asm__", ASM_KEYW }, + { "__attribute", ATTRIBUTE_KEYW }, + { "__attribute__", ATTRIBUTE_KEYW }, + { "__const", CONST_KEYW }, + { "__const__", CONST_KEYW }, + { "__extension__", EXTENSION_KEYW }, + { "__inline", INLINE_KEYW }, + { "__inline__", INLINE_KEYW }, + { "__signed", SIGNED_KEYW }, + { "__signed__", SIGNED_KEYW }, + { "__typeof", TYPEOF_KEYW }, + { "__typeof__", TYPEOF_KEYW }, + { "__volatile", VOLATILE_KEYW }, + { "__volatile__", VOLATILE_KEYW }, + { "__builtin_va_list", VA_LIST_KEYW }, + + // According to rth, c99 defines "_Bool", __restrict", __restrict__", "restrict". KAO + { "_Bool", BOOL_KEYW }, + { "_restrict", RESTRICT_KEYW }, + { "__restrict__", RESTRICT_KEYW }, + { "restrict", RESTRICT_KEYW }, + { "asm", ASM_KEYW }, + + // attribute commented out in modutils 2.4.2. People are using 'attribute' as a + // field name which breaks the genksyms parser. It is not a gcc keyword anyway. + // KAO. }, + // { "attribute", ATTRIBUTE_KEYW }, + + { "auto", AUTO_KEYW }, + { "char", CHAR_KEYW }, + { "const", CONST_KEYW }, + { "double", DOUBLE_KEYW }, + { "enum", ENUM_KEYW }, + { "extern", EXTERN_KEYW }, + { "float", FLOAT_KEYW }, + { "inline", INLINE_KEYW }, + { "int", INT_KEYW }, + { "long", LONG_KEYW }, + { "register", REGISTER_KEYW }, + { "short", SHORT_KEYW }, + { "signed", SIGNED_KEYW }, + { "static", STATIC_KEYW }, + { "struct", STRUCT_KEYW }, + { "typedef", TYPEDEF_KEYW }, + { "typeof", TYPEOF_KEYW }, + { "union", UNION_KEYW }, + { "unsigned", UNSIGNED_KEYW }, + { "void", VOID_KEYW }, + { "volatile", VOLATILE_KEYW }, +}; + +#define NR_KEYWORDS (sizeof(keywords)/sizeof(struct resword)) + +static int is_reserved_word(register const char *str, register unsigned int len) +{ + int i; + for (i = 0; i < NR_KEYWORDS; i++) { + struct resword *r = keywords + i; + int l = strlen(r->name); + if (len == l && !memcmp(str, r->name, len)) + return r->token; + } + return -1; +} diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf deleted file mode 100644 index bd4c4b235588a61b27623cc2d7f00a693effd6e2..0000000000000000000000000000000000000000 --- a/scripts/genksyms/keywords.gperf +++ /dev/null @@ -1,61 +0,0 @@ -%language=ANSI-C -%define hash-function-name is_reserved_hash -%define lookup-function-name is_reserved_word -%{ -struct resword; -static const struct resword *is_reserved_word(register const char *str, register unsigned int len); -%} -struct resword { const char *name; int token; } -%% -EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW -EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW -EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW -EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW -EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW -__asm, ASM_KEYW -__asm__, ASM_KEYW -__attribute, ATTRIBUTE_KEYW -__attribute__, ATTRIBUTE_KEYW -__const, CONST_KEYW -__const__, CONST_KEYW -__extension__, EXTENSION_KEYW -__inline, INLINE_KEYW -__inline__, INLINE_KEYW -__signed, SIGNED_KEYW -__signed__, SIGNED_KEYW -__typeof, TYPEOF_KEYW -__typeof__, TYPEOF_KEYW -__volatile, VOLATILE_KEYW -__volatile__, VOLATILE_KEYW -__builtin_va_list, VA_LIST_KEYW -# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict. KAO -_Bool, BOOL_KEYW -_restrict, RESTRICT_KEYW -__restrict__, RESTRICT_KEYW -restrict, RESTRICT_KEYW -asm, ASM_KEYW -# attribute commented out in modutils 2.4.2. People are using 'attribute' as a -# field name which breaks the genksyms parser. It is not a gcc keyword anyway. -# KAO. -# attribute, ATTRIBUTE_KEYW -auto, AUTO_KEYW -char, CHAR_KEYW -const, CONST_KEYW -double, DOUBLE_KEYW -enum, ENUM_KEYW -extern, EXTERN_KEYW -float, FLOAT_KEYW -inline, INLINE_KEYW -int, INT_KEYW -long, LONG_KEYW -register, REGISTER_KEYW -short, SHORT_KEYW -signed, SIGNED_KEYW -static, STATIC_KEYW -struct, STRUCT_KEYW -typedef, TYPEDEF_KEYW -typeof, TYPEOF_KEYW -union, UNION_KEYW -unsigned, UNSIGNED_KEYW -void, VOID_KEYW -volatile, VOLATILE_KEYW diff --git a/scripts/genksyms/keywords.hash.c_shipped b/scripts/genksyms/keywords.hash.c_shipped deleted file mode 100644 index 738018ba73757d1b8f9f8b5fdd56a453bc8864ef..0000000000000000000000000000000000000000 --- a/scripts/genksyms/keywords.hash.c_shipped +++ /dev/null @@ -1,230 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.4 */ -/* Command-line: gperf -t --output-file scripts/genksyms/keywords.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/genksyms/keywords.gperf */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif - -#line 4 "scripts/genksyms/keywords.gperf" - -struct resword; -static const struct resword *is_reserved_word(register const char *str, register unsigned int len); -#line 8 "scripts/genksyms/keywords.gperf" -struct resword { const char *name; int token; }; -/* maximum key range = 98, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -is_reserved_hash (register const char *str, register unsigned int len) -{ - static const unsigned char asso_values[] = - { - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, - 101, 101, 101, 101, 101, 101, 15, 101, 101, 101, - 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 0, 101, 0, 0, 5, - 25, 20, 55, 30, 101, 15, 101, 101, 10, 0, - 10, 40, 10, 101, 10, 5, 0, 10, 15, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101 - }; - return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; -} - -#ifdef __GNUC__ -__inline -#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -const struct resword * -is_reserved_word (register const char *str, register unsigned int len) -{ - enum - { - TOTAL_KEYWORDS = 47, - MIN_WORD_LENGTH = 3, - MAX_WORD_LENGTH = 24, - MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 100 - }; - - static const struct resword wordlist[] = - { - {""}, {""}, {""}, -#line 36 "scripts/genksyms/keywords.gperf" - {"asm", ASM_KEYW}, - {""}, -#line 15 "scripts/genksyms/keywords.gperf" - {"__asm", ASM_KEYW}, - {""}, -#line 16 "scripts/genksyms/keywords.gperf" - {"__asm__", ASM_KEYW}, - {""}, {""}, -#line 27 "scripts/genksyms/keywords.gperf" - {"__typeof__", TYPEOF_KEYW}, - {""}, -#line 19 "scripts/genksyms/keywords.gperf" - {"__const", CONST_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" - {"__attribute__", ATTRIBUTE_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" - {"__const__", CONST_KEYW}, -#line 25 "scripts/genksyms/keywords.gperf" - {"__signed__", SIGNED_KEYW}, -#line 54 "scripts/genksyms/keywords.gperf" - {"static", STATIC_KEYW}, -#line 30 "scripts/genksyms/keywords.gperf" - {"__builtin_va_list", VA_LIST_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" - {"int", INT_KEYW}, -#line 42 "scripts/genksyms/keywords.gperf" - {"char", CHAR_KEYW}, -#line 43 "scripts/genksyms/keywords.gperf" - {"const", CONST_KEYW}, -#line 55 "scripts/genksyms/keywords.gperf" - {"struct", STRUCT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" - {"__restrict__", RESTRICT_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" - {"restrict", RESTRICT_KEYW}, -#line 12 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, -#line 23 "scripts/genksyms/keywords.gperf" - {"__inline__", INLINE_KEYW}, - {""}, -#line 29 "scripts/genksyms/keywords.gperf" - {"__volatile__", VOLATILE_KEYW}, -#line 10 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" - {"_restrict", RESTRICT_KEYW}, - {""}, -#line 17 "scripts/genksyms/keywords.gperf" - {"__attribute", ATTRIBUTE_KEYW}, -#line 11 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 21 "scripts/genksyms/keywords.gperf" - {"__extension__", EXTENSION_KEYW}, -#line 45 "scripts/genksyms/keywords.gperf" - {"enum", ENUM_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" - {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, -#line 46 "scripts/genksyms/keywords.gperf" - {"extern", EXTERN_KEYW}, - {""}, -#line 24 "scripts/genksyms/keywords.gperf" - {"__signed", SIGNED_KEYW}, -#line 14 "scripts/genksyms/keywords.gperf" - {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 58 "scripts/genksyms/keywords.gperf" - {"union", UNION_KEYW}, - {""}, {""}, -#line 22 "scripts/genksyms/keywords.gperf" - {"__inline", INLINE_KEYW}, -#line 41 "scripts/genksyms/keywords.gperf" - {"auto", AUTO_KEYW}, -#line 28 "scripts/genksyms/keywords.gperf" - {"__volatile", VOLATILE_KEYW}, - {""}, {""}, -#line 59 "scripts/genksyms/keywords.gperf" - {"unsigned", UNSIGNED_KEYW}, - {""}, -#line 52 "scripts/genksyms/keywords.gperf" - {"short", SHORT_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" - {"inline", INLINE_KEYW}, - {""}, -#line 61 "scripts/genksyms/keywords.gperf" - {"volatile", VOLATILE_KEYW}, -#line 50 "scripts/genksyms/keywords.gperf" - {"long", LONG_KEYW}, -#line 32 "scripts/genksyms/keywords.gperf" - {"_Bool", BOOL_KEYW}, - {""}, {""}, -#line 51 "scripts/genksyms/keywords.gperf" - {"register", REGISTER_KEYW}, -#line 60 "scripts/genksyms/keywords.gperf" - {"void", VOID_KEYW}, - {""}, -#line 44 "scripts/genksyms/keywords.gperf" - {"double", DOUBLE_KEYW}, - {""}, -#line 26 "scripts/genksyms/keywords.gperf" - {"__typeof", TYPEOF_KEYW}, - {""}, {""}, -#line 53 "scripts/genksyms/keywords.gperf" - {"signed", SIGNED_KEYW}, - {""}, {""}, {""}, {""}, -#line 57 "scripts/genksyms/keywords.gperf" - {"typeof", TYPEOF_KEYW}, -#line 56 "scripts/genksyms/keywords.gperf" - {"typedef", TYPEDEF_KEYW}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 47 "scripts/genksyms/keywords.gperf" - {"float", FLOAT_KEYW} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = is_reserved_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index 5235aa507ba533cbd631f2ba81f702d97b50925c..d29c774f51b615026b82ae22e44ce03a676e6dd9 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -94,7 +94,7 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>) /* Bring in the keyword recognizer. */ -#include "keywords.hash.c" +#include "keywords.c" /* Macros to append to our phrase collection list. */ @@ -186,10 +186,10 @@ repeat: case IDENT: APP; { - const struct resword *r = is_reserved_word(yytext, yyleng); - if (r) + int r = is_reserved_word(yytext, yyleng); + if (r >= 0) { - switch (token = r->token) + switch (token = r) { case ATTRIBUTE_KEYW: lexstate = ST_ATTRIBUTE; @@ -292,7 +292,7 @@ repeat: case ST_TYPEOF_1: if (token == IDENT) { - if (is_reserved_word(yytext, yyleng) + if (is_reserved_word(yytext, yyleng) >= 0 || find_symbol(yytext, SYM_TYPEDEF, 1)) { yyless(0); diff --git a/scripts/genksyms/lex.lex.c_shipped b/scripts/genksyms/lex.lex.c_shipped index 985c5541aae411add700c6e1158b9ebc9dca046f..ba2fda8dfdb2c62a25aae5dd11a6625f489fae28 100644 --- a/scripts/genksyms/lex.lex.c_shipped +++ b/scripts/genksyms/lex.lex.c_shipped @@ -1905,7 +1905,7 @@ void yyfree (void * ptr ) /* Bring in the keyword recognizer. */ -#include "keywords.hash.c" +#include "keywords.c" /* Macros to append to our phrase collection list. */ @@ -1995,10 +1995,10 @@ repeat: case IDENT: APP; { - const struct resword *r = is_reserved_word(yytext, yyleng); - if (r) + int r = is_reserved_word(yytext, yyleng); + if (r >= 0) { - switch (token = r->token) + switch (token = r) { case ATTRIBUTE_KEYW: lexstate = ST_ATTRIBUTE; @@ -2101,7 +2101,7 @@ repeat: case ST_TYPEOF_1: if (token == IDENT) { - if (is_reserved_word(yytext, yyleng) + if (is_reserved_word(yytext, yyleng) >= 0 || find_symbol(yytext, SYM_TYPEDEF, 1)) { yyless(0); diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 3bd5f4f302354cf8cecd78ae0ab13b9b3bf130ef..bc443201d3ef00ac2b197da0896a186891cff188 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -18,6 +18,7 @@ my $V = '0.26'; use Getopt::Long qw(:config no_auto_abbrev); use Cwd; +use File::Find; my $cur_path = fastgetcwd() . '/'; my $lk_path = "./"; @@ -58,6 +59,7 @@ my $from_filename = 0; my $pattern_depth = 0; my $version = 0; my $help = 0; +my $find_maintainer_files = 0; my $vcs_used = 0; @@ -249,6 +251,7 @@ if (!GetOptions( 'sections!' => \$sections, 'fe|file-emails!' => \$file_emails, 'f|file' => \$from_filename, + 'find-maintainer-files' => \$find_maintainer_files, 'v|version' => \$version, 'h|help|usage' => \$help, )) { @@ -307,36 +310,74 @@ if (!top_of_kernel_tree($lk_path)) { my @typevalue = (); my %keyword_hash; +my @mfiles = (); -open (my $maint, '<', "${lk_path}MAINTAINERS") - or die "$P: Can't open MAINTAINERS: $!\n"; -while (<$maint>) { - my $line = $_; - - if ($line =~ m/^([A-Z]):\s*(.*)/) { - my $type = $1; - my $value = $2; - - ##Filename pattern matching - if ($type eq "F" || $type eq "X") { - $value =~ s@\.@\\\.@g; ##Convert . to \. - $value =~ s/\*/\.\*/g; ##Convert * to .* - $value =~ s/\?/\./g; ##Convert ? to . - ##if pattern is a directory and it lacks a trailing slash, add one - if ((-d $value)) { - $value =~ s@([^/])$@$1/@; +sub read_maintainer_file { + my ($file) = @_; + + open (my $maint, '<', "$file") + or die "$P: Can't open MAINTAINERS file '$file': $!\n"; + while (<$maint>) { + my $line = $_; + + if ($line =~ m/^([A-Z]):\s*(.*)/) { + my $type = $1; + my $value = $2; + + ##Filename pattern matching + if ($type eq "F" || $type eq "X") { + $value =~ s@\.@\\\.@g; ##Convert . to \. + $value =~ s/\*/\.\*/g; ##Convert * to .* + $value =~ s/\?/\./g; ##Convert ? to . + ##if pattern is a directory and it lacks a trailing slash, add one + if ((-d $value)) { + $value =~ s@([^/])$@$1/@; + } + } elsif ($type eq "K") { + $keyword_hash{@typevalue} = $value; } - } elsif ($type eq "K") { - $keyword_hash{@typevalue} = $value; + push(@typevalue, "$type:$value"); + } elsif (!(/^\s*$/ || /^\s*\#/)) { + $line =~ s/\n$//g; + push(@typevalue, $line); } - push(@typevalue, "$type:$value"); - } elsif (!/^(\s)*$/) { - $line =~ s/\n$//g; - push(@typevalue, $line); } + close($maint); +} + +sub find_is_maintainer_file { + my ($file) = $_; + return if ($file !~ m@/MAINTAINERS$@); + $file = $File::Find::name; + return if (! -f $file); + push(@mfiles, $file); } -close($maint); +sub find_ignore_git { + return grep { $_ !~ /^\.git$/; } @_; +} + +if (-d "${lk_path}MAINTAINERS") { + opendir(DIR, "${lk_path}MAINTAINERS") or die $!; + my @files = readdir(DIR); + closedir(DIR); + foreach my $file (@files) { + push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./); + } +} + +if ($find_maintainer_files) { + find( { wanted => \&find_is_maintainer_file, + preprocess => \&find_ignore_git, + no_chdir => 1, + }, "${lk_path}"); +} else { + push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS"; +} + +foreach my $file (@mfiles) { + read_maintainer_file("$file"); +} # # Read mail address map @@ -873,7 +914,7 @@ sub top_of_kernel_tree { if ( (-f "${lk_path}COPYING") && (-f "${lk_path}CREDITS") && (-f "${lk_path}Kbuild") - && (-f "${lk_path}MAINTAINERS") + && (-e "${lk_path}MAINTAINERS") && (-f "${lk_path}Makefile") && (-f "${lk_path}README") && (-d "${lk_path}Documentation") diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index be603c4fef624669ea2bac84e1f41311713a8065..51f1c877b543d900710ccc0b75cbd0a4a590fcf5 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -5,7 +5,6 @@ config* *.lex.c *.tab.c *.tab.h -zconf.hash.c *.moc gconf.glade.h *.pot diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index eb8144643b78355cea07f301531333001cd1d608..8c12c20c55a67345f34689f6a78d1ec355eb43e0 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -191,7 +191,7 @@ gconf-objs := gconf.o zconf.tab.o hostprogs-y := conf nconf mconf kxgettext qconf gconf clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck -clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h +clean-files += zconf.tab.c zconf.lex.c gconf.glade.h clean-files += config.pot linux.pot # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) @@ -280,7 +280,7 @@ $(obj)/.tmp_gtkcheck: fi endif -$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c +$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/qconf.o: $(obj)/qconf.moc diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c new file mode 100644 index 0000000000000000000000000000000000000000..5abbc728fbc43f99ecf1693d84a2ce76b827ef12 --- /dev/null +++ b/scripts/kconfig/kconf_id.c @@ -0,0 +1,54 @@ + +static struct kconf_id kconf_id_array[] = { + { "mainmenu", T_MAINMENU, TF_COMMAND }, + { "menu", T_MENU, TF_COMMAND }, + { "endmenu", T_ENDMENU, TF_COMMAND }, + { "source", T_SOURCE, TF_COMMAND }, + { "choice", T_CHOICE, TF_COMMAND }, + { "endchoice", T_ENDCHOICE, TF_COMMAND }, + { "comment", T_COMMENT, TF_COMMAND }, + { "config", T_CONFIG, TF_COMMAND }, + { "menuconfig", T_MENUCONFIG, TF_COMMAND }, + { "help", T_HELP, TF_COMMAND }, + { "---help---", T_HELP, TF_COMMAND }, + { "if", T_IF, TF_COMMAND|TF_PARAM }, + { "endif", T_ENDIF, TF_COMMAND }, + { "depends", T_DEPENDS, TF_COMMAND }, + { "optional", T_OPTIONAL, TF_COMMAND }, + { "default", T_DEFAULT, TF_COMMAND, S_UNKNOWN }, + { "prompt", T_PROMPT, TF_COMMAND }, + { "tristate", T_TYPE, TF_COMMAND, S_TRISTATE }, + { "def_tristate", T_DEFAULT, TF_COMMAND, S_TRISTATE }, + { "bool", T_TYPE, TF_COMMAND, S_BOOLEAN }, + { "boolean", T_TYPE, TF_COMMAND, S_BOOLEAN }, + { "def_bool", T_DEFAULT, TF_COMMAND, S_BOOLEAN }, + { "int", T_TYPE, TF_COMMAND, S_INT }, + { "hex", T_TYPE, TF_COMMAND, S_HEX }, + { "string", T_TYPE, TF_COMMAND, S_STRING }, + { "select", T_SELECT, TF_COMMAND }, + { "imply", T_IMPLY, TF_COMMAND }, + { "range", T_RANGE, TF_COMMAND }, + { "visible", T_VISIBLE, TF_COMMAND }, + { "option", T_OPTION, TF_COMMAND }, + { "on", T_ON, TF_PARAM }, + { "modules", T_OPT_MODULES, TF_OPTION }, + { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, + { "env", T_OPT_ENV, TF_OPTION }, + { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, +}; + +#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id)) + +static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len) +{ + int i; + + for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) { + struct kconf_id *id = kconf_id_array+i; + int l = strlen(id->name); + + if (len == l && !memcmp(str, id->name, len)) + return id; + } + return NULL; +} diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 91ca126ea0802e40278bbbf09b3413ce59c1bc15..cdcbe43e87b368f357f8aedb44d5dac39d796e49 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -62,7 +62,7 @@ enum conf_def_mode { #define T_OPT_ALLNOCONFIG_Y 4 struct kconf_id { - int name; + const char *name; int token; unsigned int flags; enum symbol_type stype; diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf deleted file mode 100644 index ead02edec93614618822bc61d8fcc25197853df5..0000000000000000000000000000000000000000 --- a/scripts/kconfig/zconf.gperf +++ /dev/null @@ -1,50 +0,0 @@ -%language=ANSI-C -%define hash-function-name kconf_id_hash -%define lookup-function-name kconf_id_lookup -%define string-pool-name kconf_id_strings -%compare-strncmp -%enum -%pic -%struct-type - -struct kconf_id; - -static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); - -%% -mainmenu, T_MAINMENU, TF_COMMAND -menu, T_MENU, TF_COMMAND -endmenu, T_ENDMENU, TF_COMMAND -source, T_SOURCE, TF_COMMAND -choice, T_CHOICE, TF_COMMAND -endchoice, T_ENDCHOICE, TF_COMMAND -comment, T_COMMENT, TF_COMMAND -config, T_CONFIG, TF_COMMAND -menuconfig, T_MENUCONFIG, TF_COMMAND -help, T_HELP, TF_COMMAND ----help---, T_HELP, TF_COMMAND -if, T_IF, TF_COMMAND|TF_PARAM -endif, T_ENDIF, TF_COMMAND -depends, T_DEPENDS, TF_COMMAND -optional, T_OPTIONAL, TF_COMMAND -default, T_DEFAULT, TF_COMMAND, S_UNKNOWN -prompt, T_PROMPT, TF_COMMAND -tristate, T_TYPE, TF_COMMAND, S_TRISTATE -def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE -bool, T_TYPE, TF_COMMAND, S_BOOLEAN -boolean, T_TYPE, TF_COMMAND, S_BOOLEAN -def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN -int, T_TYPE, TF_COMMAND, S_INT -hex, T_TYPE, TF_COMMAND, S_HEX -string, T_TYPE, TF_COMMAND, S_STRING -select, T_SELECT, TF_COMMAND -imply, T_IMPLY, TF_COMMAND -range, T_RANGE, TF_COMMAND -visible, T_VISIBLE, TF_COMMAND -option, T_OPTION, TF_COMMAND -on, T_ON, TF_PARAM -modules, T_OPT_MODULES, TF_OPTION -defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION -env, T_OPT_ENV, TF_OPTION -allnoconfig_y, T_OPT_ALLNOCONFIG_Y,TF_OPTION -%% diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped deleted file mode 100644 index d51b15de074ae536a9ad29859fc4ff4712519e2e..0000000000000000000000000000000000000000 --- a/scripts/kconfig/zconf.hash.c_shipped +++ /dev/null @@ -1,297 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.4 */ -/* Command-line: gperf -t --output-file scripts/kconfig/zconf.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/kconfig/zconf.gperf */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif - -#line 10 "scripts/kconfig/zconf.gperf" -struct kconf_id; - -static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); -/* maximum key range = 71, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -kconf_id_hash (register const char *str, register unsigned int len) -{ - static const unsigned char asso_values[] = - { - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 0, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 10, 25, 25, - 0, 0, 0, 5, 0, 0, 73, 73, 5, 0, - 10, 5, 45, 73, 20, 20, 0, 15, 15, 73, - 20, 0, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73 - }; - register int hval = len; - - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[2]]; - /*FALLTHROUGH*/ - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; -} - -struct kconf_id_strings_t - { - char kconf_id_strings_str2[sizeof("if")]; - char kconf_id_strings_str3[sizeof("int")]; - char kconf_id_strings_str5[sizeof("endif")]; - char kconf_id_strings_str7[sizeof("default")]; - char kconf_id_strings_str8[sizeof("tristate")]; - char kconf_id_strings_str9[sizeof("endchoice")]; - char kconf_id_strings_str10[sizeof("---help---")]; - char kconf_id_strings_str12[sizeof("def_tristate")]; - char kconf_id_strings_str13[sizeof("def_bool")]; - char kconf_id_strings_str14[sizeof("defconfig_list")]; - char kconf_id_strings_str17[sizeof("on")]; - char kconf_id_strings_str18[sizeof("optional")]; - char kconf_id_strings_str21[sizeof("option")]; - char kconf_id_strings_str22[sizeof("endmenu")]; - char kconf_id_strings_str23[sizeof("mainmenu")]; - char kconf_id_strings_str25[sizeof("menuconfig")]; - char kconf_id_strings_str27[sizeof("modules")]; - char kconf_id_strings_str28[sizeof("allnoconfig_y")]; - char kconf_id_strings_str29[sizeof("menu")]; - char kconf_id_strings_str31[sizeof("select")]; - char kconf_id_strings_str32[sizeof("comment")]; - char kconf_id_strings_str33[sizeof("env")]; - char kconf_id_strings_str35[sizeof("range")]; - char kconf_id_strings_str36[sizeof("choice")]; - char kconf_id_strings_str39[sizeof("bool")]; - char kconf_id_strings_str41[sizeof("source")]; - char kconf_id_strings_str42[sizeof("visible")]; - char kconf_id_strings_str43[sizeof("hex")]; - char kconf_id_strings_str46[sizeof("config")]; - char kconf_id_strings_str47[sizeof("boolean")]; - char kconf_id_strings_str50[sizeof("imply")]; - char kconf_id_strings_str51[sizeof("string")]; - char kconf_id_strings_str54[sizeof("help")]; - char kconf_id_strings_str56[sizeof("prompt")]; - char kconf_id_strings_str72[sizeof("depends")]; - }; -static const struct kconf_id_strings_t kconf_id_strings_contents = - { - "if", - "int", - "endif", - "default", - "tristate", - "endchoice", - "---help---", - "def_tristate", - "def_bool", - "defconfig_list", - "on", - "optional", - "option", - "endmenu", - "mainmenu", - "menuconfig", - "modules", - "allnoconfig_y", - "menu", - "select", - "comment", - "env", - "range", - "choice", - "bool", - "source", - "visible", - "hex", - "config", - "boolean", - "imply", - "string", - "help", - "prompt", - "depends" - }; -#define kconf_id_strings ((const char *) &kconf_id_strings_contents) -#ifdef __GNUC__ -__inline -#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -const struct kconf_id * -kconf_id_lookup (register const char *str, register unsigned int len) -{ - enum - { - TOTAL_KEYWORDS = 35, - MIN_WORD_LENGTH = 2, - MAX_WORD_LENGTH = 14, - MIN_HASH_VALUE = 2, - MAX_HASH_VALUE = 72 - }; - - static const struct kconf_id wordlist[] = - { - {-1}, {-1}, -#line 26 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM}, -#line 37 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT}, - {-1}, -#line 27 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, - {-1}, -#line 30 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, -#line 32 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE}, -#line 20 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, -#line 25 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_HELP, TF_COMMAND}, - {-1}, -#line 33 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE}, -#line 36 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, -#line 47 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION}, - {-1}, {-1}, -#line 45 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM}, -#line 29 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND}, - {-1}, {-1}, -#line 44 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND}, -#line 17 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND}, -#line 15 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_MAINMENU, TF_COMMAND}, - {-1}, -#line 23 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND}, - {-1}, -#line 46 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, -#line 49 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPT_ALLNOCONFIG_Y,TF_OPTION}, -#line 16 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, - {-1}, -#line 40 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND}, -#line 21 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, -#line 48 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION}, - {-1}, -#line 42 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND}, -#line 19 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND}, - {-1}, {-1}, -#line 34 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, -#line 18 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND}, -#line 43 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND}, -#line 38 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX}, - {-1}, {-1}, -#line 22 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND}, -#line 35 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, {-1}, -#line 41 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str50, T_IMPLY, TF_COMMAND}, -#line 39 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING}, - {-1}, {-1}, -#line 24 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str54, T_HELP, TF_COMMAND}, - {-1}, -#line 31 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str56, T_PROMPT, TF_COMMAND}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, -#line 28 "scripts/kconfig/zconf.gperf" - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str72, T_DEPENDS, TF_COMMAND} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = kconf_id_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int o = wordlist[key].name; - if (o >= 0) - { - register const char *s = o + kconf_id_strings; - - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &wordlist[key]; - } - } - } - return 0; -} -#line 50 "scripts/kconfig/zconf.gperf" - diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 65b7515a577c537d040b5868d33d46d2e37091df..a22b285d759f9c3c387523f74e9ef485a5398f5b 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -209,8 +209,8 @@ int zconfparse (void); /* Copy the second part of user declarations. */ -/* Include zconf.hash.c here so it can see the token constants. */ -#include "zconf.hash.c" +/* Include kconf_id.c here so it can see the token constants. */ +#include "kconf_id.c" @@ -1515,7 +1515,7 @@ yyreduce: case 12: { - zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name); + zconf_error("unexpected option \"%s\"", (yyvsp[-2].id)->name); } break; @@ -2268,13 +2268,13 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok { if (id->token != endtoken) { zconf_error("unexpected '%s' within %s block", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); + id->name, zconf_tokenname(starttoken)); zconfnerrs++; return false; } if (current_menu->file != current_file) { zconf_error("'%s' in different file than '%s'", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); + id->name, zconf_tokenname(starttoken)); fprintf(stderr, "%s:%d: location of the '%s'\n", current_menu->file->name, current_menu->lineno, zconf_tokenname(starttoken)); diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 001305fa080bd3ad7b8114c111dc2cc9ff609d45..c8f396c3b190ed1cc28acc2947eeb9255d6bff74 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -101,8 +101,8 @@ static struct menu *current_menu, *current_entry; } if_entry menu_entry choice_entry %{ -/* Include zconf.hash.c here so it can see the token constants. */ -#include "zconf.hash.c" +/* Include zconf_id.c here so it can see the token constants. */ +#include "kconf_id.c" %} %% @@ -119,7 +119,7 @@ stmt_list: | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } | stmt_list option_name error T_EOL { - zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); + zconf_error("unexpected option \"%s\"", $2->name); } | stmt_list error T_EOL { zconf_error("invalid statement"); } ; @@ -551,13 +551,13 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok { if (id->token != endtoken) { zconf_error("unexpected '%s' within %s block", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); + id->name, zconf_tokenname(starttoken)); zconfnerrs++; return false; } if (current_menu->file != current_file) { zconf_error("'%s' in different file than '%s'", - kconf_id_strings + id->name, zconf_tokenname(starttoken)); + id->name, zconf_tokenname(starttoken)); fprintf(stderr, "%s:%d: location of the '%s'\n", current_menu->file->name, current_menu->lineno, zconf_tokenname(starttoken)); diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 6e36b7889001a6ef96b82ece2fef580957b75894..9d3eafea58f06a048f60291409e89ad5942d0a12 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2226,6 +2226,7 @@ sub dump_enum($$) { if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { $declaration_name = $1; my $members = $2; + $members =~ s/\s+$//; foreach my $arg (split ',', $members) { $arg =~ s/^\s*(\w+).*/$1/; @@ -2766,6 +2767,9 @@ sub process_proto_type($$) { while (1) { if ( $x =~ /([^{};]*)([{};])(.*)/ ) { + if( length $prototype ) { + $prototype .= " " + } $prototype .= $1 . $2; ($2 eq '{') && $brcount++; ($2 eq '}') && $brcount--; diff --git a/scripts/mkversion b/scripts/mkversion deleted file mode 100644 index c12addc9c7efc8b185c602a84de7a79131b49134..0000000000000000000000000000000000000000 --- a/scripts/mkversion +++ /dev/null @@ -1,6 +0,0 @@ -if [ ! -f .version ] -then - echo 1 -else - expr 0`cat .version` + 1 -fi diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 48397feb08fba88270e4e60c16f77f0ec2f483b4..98314b400a95cd819ad9352518440de1e48db581 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -47,6 +47,12 @@ enum export { export_unused_gpl, export_gpl_future, export_unknown }; +/* In kernel, this size is defined in linux/module.h; + * here we use Elf_Addr instead of long for covering cross-compile + */ + +#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr)) + #define PRINTF __attribute__ ((format (printf, 1, 2))) PRINTF void fatal(const char *fmt, ...) @@ -261,7 +267,17 @@ static enum export export_no(const char *s) return export_unknown; } -static const char *sec_name(struct elf_info *elf, int secindex); +static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) +{ + return (void *)elf->hdr + + elf->sechdrs[elf->secindex_strings].sh_offset + + sechdr->sh_name; +} + +static const char *sec_name(struct elf_info *elf, int secindex) +{ + return sech_name(elf, &elf->sechdrs[secindex]); +} #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) @@ -775,21 +791,6 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) return "(unknown)"; } -static const char *sec_name(struct elf_info *elf, int secindex) -{ - Elf_Shdr *sechdrs = elf->sechdrs; - return (void *)elf->hdr + - elf->sechdrs[elf->secindex_strings].sh_offset + - sechdrs[secindex].sh_name; -} - -static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) -{ - return (void *)elf->hdr + - elf->sechdrs[elf->secindex_strings].sh_offset + - sechdr->sh_name; -} - /* The pattern is an array of simple patterns. * "foo" will match an exact string equal to "foo" * "*foo" will match a string that ends with "foo" @@ -2116,6 +2117,23 @@ static void check_exports(struct module *mod) } } +static int check_modname_len(struct module *mod) +{ + const char *mod_name; + + mod_name = strrchr(mod->name, '/'); + if (mod_name == NULL) + mod_name = mod->name; + else + mod_name++; + if (strlen(mod_name) >= MODULE_NAME_LEN) { + merror("module name is too long [%s.ko]\n", mod->name); + return 1; + } + + return 0; +} + /** * Header for the generated file **/ @@ -2155,11 +2173,6 @@ static void add_staging_flag(struct buffer *b, const char *name) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); } -/* In kernel, this size is defined in linux/module.h; - * here we use Elf_Addr instead of long for covering cross-compile - */ -#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr)) - /** * Record CRCs for unresolved symbols **/ @@ -2490,6 +2503,7 @@ int main(int argc, char **argv) buf.pos = 0; + err |= check_modname_len(mod); add_header(&buf, mod); add_intree_flag(&buf, !external_module); add_staging_flag(&buf, mod->name); diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 71b4a8af9d4dcdf1dcec434b6be98636f468b2dd..73f9f3192b9fbf8770e6ef632723d23e8efb5b63 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -50,8 +50,6 @@ rpm-pkg rpm: FORCE $(MAKE) clean $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec $(call cmd,src_tar,$(KERNELPATH),kernel.spec) - $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version - mv -f $(objtree)/.tmp_version $(objtree)/.version rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz rm $(KERNELPATH).tar.gz kernel.spec @@ -60,9 +58,6 @@ rpm-pkg rpm: FORCE binrpm-pkg: FORCE $(MAKE) KBUILD_SRC= $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec - $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version - mv -f $(objtree)/.tmp_version $(objtree)/.version - rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ $(UTS_MACHINE) -bb $(objtree)/binkernel.spec rm binkernel.spec diff --git a/scripts/package/builddeb b/scripts/package/builddeb index aad67000e4dd76796894cbd1975d087c559ecc5c..0bc87473f68f817b81640591f75f18c3b068351c 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -92,12 +92,10 @@ else fi sourcename=$KDEB_SOURCENAME tmpdir="$objtree/debian/tmp" -fwdir="$objtree/debian/fwtmp" kernel_headers_dir="$objtree/debian/hdrtmp" libc_headers_dir="$objtree/debian/headertmp" dbg_dir="$objtree/debian/dbgtmp" packagename=linux-image-$version -fwpackagename=linux-firmware-image-$version kernel_headers_packagename=linux-headers-$version libc_headers_packagename=linux-libc-dev dbg_packagename=$packagename-dbg @@ -126,10 +124,9 @@ esac BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)" # Setup the directory structure -rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files +rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files mkdir -m 755 -p "$tmpdir/DEBIAN" mkdir -p "$tmpdir/lib" "$tmpdir/boot" -mkdir -p "$fwdir/lib/firmware/$version/" mkdir -p "$kernel_headers_dir/lib/modules/$version/" # Build and install the kernel @@ -306,7 +303,6 @@ else cat <> debian/control Package: $packagename -Suggests: $fwpackagename Architecture: any Description: Linux kernel, version $version This package contains the Linux kernel, modules and corresponding other @@ -345,22 +341,6 @@ Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch} This is useful for people who need to build external modules EOF -# Do we have firmware? Move it out of the way and build it into a package. -if [ -e "$tmpdir/lib/firmware" ]; then - mv "$tmpdir/lib/firmware"/* "$fwdir/lib/firmware/$version/" - rmdir "$tmpdir/lib/firmware" - - cat <> debian/control - -Package: $fwpackagename -Architecture: all -Description: Linux kernel firmware, version $version - This package contains firmware from the Linux kernel, version $version. -EOF - - create_package "$fwpackagename" "$fwdir" -fi - cat <> debian/control Package: $libc_headers_packagename diff --git a/scripts/package/buildtar b/scripts/package/buildtar index e046bff33589ec3ae492397fd0cd723b9efd3ae7..51f94711825610f1019c53d83ce49e8c38901ed1 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -24,20 +24,19 @@ tarball="${objtree}/linux-${KERNELRELEASE}-${ARCH}.tar" # case "${1}" in tar-pkg) - compress="cat" - file_ext="" + opts= ;; targz-pkg) - compress="gzip" - file_ext=".gz" + opts=--gzip + tarball=${tarball}.gz ;; tarbz2-pkg) - compress="bzip2" - file_ext=".bz2" + opts=--bzip2 + tarball=${tarball}.bz2 ;; tarxz-pkg) - compress="xz" - file_ext=".xz" + opts=--xz + tarball=${tarball}.xz ;; *) echo "Unknown tarball target \"${1}\" requested, please add it to ${0}." >&2 @@ -51,13 +50,14 @@ esac # rm -rf -- "${tmpdir}" mkdir -p -- "${tmpdir}/boot" - +dirs=boot # # Try to install modules # -if grep -q '^CONFIG_MODULES=y' "${objtree}/.config"; then +if grep -q '^CONFIG_MODULES=y' "${KCONFIG_CONFIG}"; then make ARCH="${ARCH}" O="${objtree}" KBUILD_SRC= INSTALL_MOD_PATH="${tmpdir}" modules_install + dirs="$dirs lib" fi @@ -65,7 +65,7 @@ fi # Install basic kernel files # cp -v -- "${objtree}/System.map" "${tmpdir}/boot/System.map-${KERNELRELEASE}" -cp -v -- "${objtree}/.config" "${tmpdir}/boot/config-${KERNELRELEASE}" +cp -v -- "${KCONFIG_CONFIG}" "${tmpdir}/boot/config-${KERNELRELEASE}" cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" @@ -124,14 +124,12 @@ esac # # Create the tarball # -( - opts= - if tar --owner=root --group=root --help >/dev/null 2>&1; then - opts="--owner=root --group=root" - fi - tar cf - -C "$tmpdir" boot/ lib/ $opts | ${compress} > "${tarball}${file_ext}" -) +if tar --owner=root --group=root --help >/dev/null 2>&1; then + opts="$opts --owner=root --group=root" +fi + +tar cf $tarball -C $tmpdir $opts $dirs -echo "Tarball successfully created in ${tarball}${file_ext}" +echo "Tarball successfully created in $tarball" exit 0 diff --git a/scripts/package/mkspec b/scripts/package/mkspec index bb43f153fd8e70fd48c32a2f92fa6699242501f7..f47f17aae135188eae37db2178db6c9911a80023 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -27,9 +27,7 @@ __KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"` echo "Name: kernel" echo "Summary: The Linux Kernel" echo "Version: $__KERNELRELEASE" -# we need to determine the NEXT version number so that uname and -# rpm -q will agree -echo "Release: `. $srctree/scripts/mkversion`" +echo "Release: $(cat .version 2>/dev/null || echo 1)" echo "License: GPL" echo "Group: System Environment/Kernel" echo "Vendor: The Linux Community" @@ -77,7 +75,7 @@ fi echo "%build" if ! $PREBUILT; then -echo "make clean && make %{?_smp_mflags}" +echo "make clean && make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}" echo "" fi @@ -88,11 +86,8 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules' echo "%else" echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules' echo "%endif" -echo 'mkdir -p $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE" -echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= mod-fw= modules_install' -echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE" -echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install +echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install' echo "%ifarch ia64" echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" @@ -119,7 +114,7 @@ if ! $PREBUILT; then echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/build" echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/source" echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE" -echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude=firmware --exclude .config.old --exclude .missing-syscalls.d\"" +echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude .config.old --exclude .missing-syscalls.d\"" echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)" echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE" echo "ln -sf /usr/src/kernels/$KERNELRELEASE build" @@ -154,7 +149,6 @@ echo '%defattr (-, root, root)' echo "/lib/modules/$KERNELRELEASE" echo "%exclude /lib/modules/$KERNELRELEASE/build" echo "%exclude /lib/modules/$KERNELRELEASE/source" -echo "/lib/firmware/$KERNELRELEASE" echo "/boot/*" echo "" echo "%files headers" diff --git a/scripts/parse-maintainers.pl b/scripts/parse-maintainers.pl index a0fe34349b24fccd9fb9b8834ea51d3e2d9e155a..e40b53db7f9fdc7c8e3f7094f8b862d66ef7651f 100644 --- a/scripts/parse-maintainers.pl +++ b/scripts/parse-maintainers.pl @@ -2,9 +2,9 @@ use strict; -my %map; +my $P = $0; -# sort comparison function +# sort comparison functions sub by_category($$) { my ($a, $b) = @_; @@ -15,20 +15,33 @@ sub by_category($$) { $a =~ s/THE REST/ZZZZZZ/g; $b =~ s/THE REST/ZZZZZZ/g; - $a cmp $b; + return $a cmp $b; } -sub alpha_output { - my $key; - my $sort_method = \&by_category; - my $sep = ""; - - foreach $key (sort $sort_method keys %map) { - if ($key ne " ") { - print $sep . $key . "\n"; - $sep = "\n"; - } - print $map{$key}; +sub by_pattern($$) { + my ($a, $b) = @_; + my $preferred_order = 'MRPLSWTQBCFXNK'; + + my $a1 = uc(substr($a, 0, 1)); + my $b1 = uc(substr($b, 0, 1)); + + my $a_index = index($preferred_order, $a1); + my $b_index = index($preferred_order, $b1); + + $a_index = 1000 if ($a_index == -1); + $b_index = 1000 if ($b_index == -1); + + if (($a1 =~ /^F$/ && $b1 =~ /^F$/) || + ($a1 =~ /^X$/ && $b1 =~ /^X$/)) { + return $a cmp $b; + } + + if ($a_index < $b_index) { + return -1; + } elsif ($a_index == $b_index) { + return 0; + } else { + return 1; } } @@ -39,39 +52,77 @@ sub trim { return $s; } +sub alpha_output { + my ($hashref, $filename) = (@_); + + open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n"; + foreach my $key (sort by_category keys %$hashref) { + if ($key eq " ") { + chomp $$hashref{$key}; + print $file $$hashref{$key}; + } else { + print $file "\n" . $key . "\n"; + foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) { + print $file ($pattern . "\n"); + } + } + } + close($file); +} + sub file_input { + my ($hashref, $filename) = (@_); + my $lastline = ""; my $case = " "; - $map{$case} = ""; + $$hashref{$case} = ""; + + open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n"; - while (<>) { + while (<$file>) { my $line = $_; # Pattern line? if ($line =~ m/^([A-Z]):\s*(.*)/) { $line = $1 . ":\t" . trim($2) . "\n"; if ($lastline eq "") { - $map{$case} = $map{$case} . $line; + $$hashref{$case} = $$hashref{$case} . $line; next; } $case = trim($lastline); - exists $map{$case} and die "Header '$case' already exists"; - $map{$case} = $line; + exists $$hashref{$case} and die "Header '$case' already exists"; + $$hashref{$case} = $line; $lastline = ""; next; } if ($case eq " ") { - $map{$case} = $map{$case} . $lastline; + $$hashref{$case} = $$hashref{$case} . $lastline; $lastline = $line; next; } trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'"); $lastline = $line; } - $map{$case} = $map{$case} . $lastline; + $$hashref{$case} = $$hashref{$case} . $lastline; + close($file); } -&file_input; -&alpha_output; +my %hash; +my %new_hash; + +file_input(\%hash, "MAINTAINERS"); + +foreach my $type (@ARGV) { + foreach my $key (keys %hash) { + if ($key =~ /$type/ || $hash{$key} =~ /$type/) { + $new_hash{$key} = $hash{$key}; + delete $hash{$key}; + } + } +} + +alpha_output(\%hash, "MAINTAINERS.new"); +alpha_output(\%new_hash, "SECTION.new"); + exit(0); diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index 6a24569c3578af93673cdd40372fdd6224638de9..672b069dcfea4b2945d07b1de74afc8203c1a6a0 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c @@ -129,11 +129,16 @@ int main(int argc, char *argv[]) for (i = 0; secclass_map[i].name; i++) { struct security_class_mapping *map = &secclass_map[i]; for (j = 0; map->perms[j]; j++) { + if (j >= 32) { + fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n", + map->name, map->perms[j]); + exit(5); + } fprintf(fout, "#define %s__%s", map->name, map->perms[j]); for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++) fprintf(fout, " "); - fprintf(fout, "0x%08xUL\n", (1< +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +my $virtenv_dir = "sphinx_1.4"; +my $requirement_file = "Documentation/sphinx/requirements.txt"; + +# +# Static vars +# + +my %missing; +my $system_release; +my $need = 0; +my $optional = 0; +my $need_symlink = 0; +my $need_sphinx = 0; +my $install = ""; + +# +# Command line arguments +# + +my $pdf = 1; +my $virtualenv = 1; + +# +# List of required texlive packages on Fedora and OpenSuse +# + +my %texlive = ( + 'amsfonts.sty' => 'texlive-amsfonts', + 'amsmath.sty' => 'texlive-amsmath', + 'amssymb.sty' => 'texlive-amsfonts', + 'amsthm.sty' => 'texlive-amscls', + 'anyfontsize.sty' => 'texlive-anyfontsize', + 'atbegshi.sty' => 'texlive-oberdiek', + 'bm.sty' => 'texlive-tools', + 'capt-of.sty' => 'texlive-capt-of', + 'cmap.sty' => 'texlive-cmap', + 'ecrm1000.tfm' => 'texlive-ec', + 'eqparbox.sty' => 'texlive-eqparbox', + 'eu1enc.def' => 'texlive-euenc', + 'fancybox.sty' => 'texlive-fancybox', + 'fancyvrb.sty' => 'texlive-fancyvrb', + 'float.sty' => 'texlive-float', + 'fncychap.sty' => 'texlive-fncychap', + 'footnote.sty' => 'texlive-mdwtools', + 'framed.sty' => 'texlive-framed', + 'luatex85.sty' => 'texlive-luatex85', + 'multirow.sty' => 'texlive-multirow', + 'needspace.sty' => 'texlive-needspace', + 'palatino.sty' => 'texlive-psnfss', + 'parskip.sty' => 'texlive-parskip', + 'polyglossia.sty' => 'texlive-polyglossia', + 'tabulary.sty' => 'texlive-tabulary', + 'threeparttable.sty' => 'texlive-threeparttable', + 'titlesec.sty' => 'texlive-titlesec', + 'ucs.sty' => 'texlive-ucs', + 'upquote.sty' => 'texlive-upquote', + 'wrapfig.sty' => 'texlive-wrapfig', +); + +# +# Subroutines that checks if a feature exists +# + +sub check_missing(%) +{ + my %map = %{$_[0]}; + + foreach my $prog (sort keys %missing) { + my $is_optional = $missing{$prog}; + + if ($is_optional) { + print "Warning: better to also install \"$prog\".\n"; + } else { + print "ERROR: please install \"$prog\", otherwise, build won't work.\n"; + } + if (defined($map{$prog})) { + $install .= " " . $map{$prog}; + } else { + $install .= " " . $prog; + } + } + + $install =~ s/^\s//; +} + +sub add_package($$) +{ + my $package = shift; + my $is_optional = shift; + + $missing{$package} = $is_optional; + if ($is_optional) { + $optional++; + } else { + $need++; + } +} + +sub check_missing_file($$$) +{ + my $file = shift; + my $package = shift; + my $is_optional = shift; + + return if(-e $file); + + add_package($package, $is_optional); +} + +sub findprog($) +{ + foreach(split(/:/, $ENV{PATH})) { + return "$_/$_[0]" if(-x "$_/$_[0]"); + } +} + +sub check_program($$) +{ + my $prog = shift; + my $is_optional = shift; + + return if findprog($prog); + + add_package($prog, $is_optional); +} + +sub check_perl_module($$) +{ + my $prog = shift; + my $is_optional = shift; + + my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null"); + return if ($err == 0); + + add_package($prog, $is_optional); +} + +sub check_python_module($$) +{ + my $prog = shift; + my $is_optional = shift; + + my $err = system("python3 -c 'import $prog' 2>/dev/null /dev/null"); + return if ($err == 0); + my $err = system("python -c 'import $prog' 2>/dev/null /dev/null"); + return if ($err == 0); + + add_package($prog, $is_optional); +} + +sub check_rpm_missing($$) +{ + my @pkgs = @{$_[0]}; + my $is_optional = $_[1]; + + foreach my $prog(@pkgs) { + my $err = system("rpm -q '$prog' 2>/dev/null >/dev/null"); + add_package($prog, $is_optional) if ($err); + } +} + +sub check_pacman_missing($$) +{ + my @pkgs = @{$_[0]}; + my $is_optional = $_[1]; + + foreach my $prog(@pkgs) { + my $err = system("pacman -Q '$prog' 2>/dev/null >/dev/null"); + add_package($prog, $is_optional) if ($err); + } +} + +sub check_missing_tex($) +{ + my $is_optional = shift; + my $kpsewhich = findprog("kpsewhich"); + + foreach my $prog(keys %texlive) { + my $package = $texlive{$prog}; + if (!$kpsewhich) { + add_package($package, $is_optional); + next; + } + my $file = qx($kpsewhich $prog); + add_package($package, $is_optional) if ($file =~ /^\s*$/); + } +} + +sub check_sphinx() +{ + return if findprog("sphinx-build"); + + if (findprog("sphinx-build-3")) { + $need_symlink = 1; + return; + } + + if ($virtualenv) { + my $prog = findprog("virtualenv-3"); + $prog = findprog("virtualenv-3.5") if (!$prog); + + check_program("virtualenv", 0) if (!$prog); + $need_sphinx = 1; + } else { + add_package("python-sphinx", 0); + } +} + +# +# Ancillary subroutines +# + +sub catcheck($) +{ + my $res = ""; + $res = qx(cat $_[0]) if (-r $_[0]); + return $res; +} + +sub which($) +{ + my $file = shift; + my @path = split ":", $ENV{PATH}; + + foreach my $dir(@path) { + my $name = $dir.'/'.$file; + return $name if (-x $name ); + } + return undef; +} + +# +# Subroutines that check distro-specific hints +# + +sub give_debian_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx-rtd-theme", + "virtualenv" => "virtualenv", + "dot" => "graphviz", + "convert" => "imagemagick", + "Pod::Usage" => "perl-modules", + "xelatex" => "texlive-xetex", + "rsvg-convert" => "librsvg2-bin", + ); + + if ($pdf) { + check_missing_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", + "fonts-dejavu", 1); + } + + check_program("dvipng", 1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo apt-get install $install\n"); +} + +sub give_redhat_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx_rtd_theme", + "virtualenv" => "python3-virtualenv", + "dot" => "graphviz", + "convert" => "ImageMagick", + "Pod::Usage" => "perl-Pod-Usage", + "xelatex" => "texlive-xetex-bin", + "rsvg-convert" => "librsvg2-tools", + ); + + my @fedora26_opt_pkgs = ( + "graphviz-gd", # Fedora 26: needed for PDF support + ); + + my @fedora_tex_pkgs = ( + "texlive-collection-fontsrecommended", + "texlive-collection-latex", + "dejavu-sans-fonts", + "dejavu-serif-fonts", + "dejavu-sans-mono-fonts", + ); + + # + # Checks valid for RHEL/CentOS version 7.x. + # + if (! $system_release =~ /Fedora/) { + $map{"virtualenv"} = "python-virtualenv"; + } + + my $release; + + $release = $1 if ($system_release =~ /Fedora\s+release\s+(\d+)/); + + check_rpm_missing(\@fedora26_opt_pkgs, 1) if ($pdf && $release >= 26); + check_rpm_missing(\@fedora_tex_pkgs, 1) if ($pdf); + check_missing_tex(1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + + if ($release >= 18) { + # dnf, for Fedora 18+ + printf("You should run:\n\n\tsudo dnf install -y $install\n"); + } else { + # yum, for RHEL (and clones) or Fedora version < 18 + printf("You should run:\n\n\tsudo yum install -y $install\n"); + } +} + +sub give_opensuse_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx_rtd_theme", + "virtualenv" => "python3-virtualenv", + "dot" => "graphviz", + "convert" => "ImageMagick", + "Pod::Usage" => "perl-Pod-Usage", + "xelatex" => "texlive-xetex-bin", + "rsvg-convert" => "rsvg-view", + ); + + my @suse_tex_pkgs = ( + "texlive-babel-english", + "texlive-caption", + "texlive-colortbl", + "texlive-courier", + "texlive-dvips", + "texlive-helvetic", + "texlive-makeindex", + "texlive-metafont", + "texlive-metapost", + "texlive-palatino", + "texlive-preview", + "texlive-times", + "texlive-zapfchan", + "texlive-zapfding", + ); + + check_rpm_missing(\@suse_tex_pkgs, 1) if ($pdf); + check_missing_tex(1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo zypper install --no-recommends $install\n"); +} + +sub give_mageia_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx_rtd_theme", + "virtualenv" => "python3-virtualenv", + "dot" => "graphviz", + "convert" => "ImageMagick", + "Pod::Usage" => "perl-Pod-Usage", + "xelatex" => "texlive", + "rsvg-convert" => "librsvg2-tools", + ); + + my @tex_pkgs = ( + "texlive-fontsextra", + ); + + check_rpm_missing(\@tex_pkgs, 1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo urpmi $install\n"); +} + +sub give_arch_linux_hints() +{ + my %map = ( + "sphinx_rtd_theme" => "python-sphinx_rtd_theme", + "virtualenv" => "python-virtualenv", + "dot" => "graphviz", + "convert" => "imagemagick", + "xelatex" => "texlive-bin", + "rsvg-convert" => "extra/librsvg", + ); + + my @archlinux_tex_pkgs = ( + "texlive-core", + "texlive-latexextra", + "ttf-dejavu", + ); + check_pacman_missing(\@archlinux_tex_pkgs, 1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo pacman -S $install\n"); +} + +sub give_gentoo_hints() +{ + my %map = ( + "sphinx_rtd_theme" => "dev-python/sphinx_rtd_theme", + "virtualenv" => "dev-python/virtualenv", + "dot" => "media-gfx/graphviz", + "convert" => "media-gfx/imagemagick", + "xelatex" => "dev-texlive/texlive-xetex media-fonts/dejavu", + "rsvg-convert" => "gnome-base/librsvg", + ); + + check_missing_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", + "media-fonts/dejavu", 1) if ($pdf); + + check_missing(\%map); + + return if (!$need && !$optional); + + printf("You should run:\n\n"); + printf("\tsudo su -c 'echo \"media-gfx/imagemagick svg png\" > /etc/portage/package.use/imagemagick'\n"); + printf("\tsudo su -c 'echo \"media-gfx/graphviz cairo pdf\" > /etc/portage/package.use/graphviz'\n"); + printf("\tsudo emerge --ask $install\n"); + +} + +sub check_distros() +{ + # Distro-specific hints + if ($system_release =~ /Red Hat Enterprise Linux/) { + give_redhat_hints; + return; + } + if ($system_release =~ /CentOS/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Scientific Linux/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Oracle Linux Server/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Fedora/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Ubuntu/) { + give_debian_hints; + return; + } + if ($system_release =~ /Debian/) { + give_debian_hints; + return; + } + if ($system_release =~ /openSUSE/) { + give_opensuse_hints; + return; + } + if ($system_release =~ /Mageia/) { + give_mageia_hints; + return; + } + if ($system_release =~ /Arch Linux/) { + give_arch_linux_hints; + return; + } + if ($system_release =~ /Gentoo/) { + give_gentoo_hints; + return; + } + + # + # Fall-back to generic hint code for other distros + # That's far from ideal, specially for LaTeX dependencies. + # + my %map = ( + "sphinx-build" => "sphinx" + ); + check_missing_tex(1) if ($pdf); + check_missing(\%map); + print "I don't know distro $system_release.\n"; + print "So, I can't provide you a hint with the install procedure.\n"; + print "There are likely missing dependencies.\n"; +} + +# +# Common dependencies +# + +sub check_needs() +{ + if ($system_release) { + print "Detected OS: $system_release.\n"; + } else { + print "Unknown OS\n"; + } + + # RHEL 7.x and clones have Sphinx version 1.1.x and incomplete texlive + if (($system_release =~ /Red Hat Enterprise Linux/) || + ($system_release =~ /CentOS/) || + ($system_release =~ /Scientific Linux/) || + ($system_release =~ /Oracle Linux Server/)) { + $virtualenv = 1; + $pdf = 0; + + printf("NOTE: On this distro, Sphinx and TexLive shipped versions are incompatible\n"); + printf("with doc build. So, use Sphinx via a Python virtual environment.\n\n"); + printf("This script can't install a TexLive version that would provide PDF.\n"); + } + + # Check for needed programs/tools + check_sphinx(); + check_perl_module("Pod::Usage", 0); + check_program("make", 0); + check_program("gcc", 0); + check_python_module("sphinx_rtd_theme", 1) if (!$virtualenv); + check_program("xelatex", 1) if ($pdf); + check_program("dot", 1); + check_program("convert", 1); + check_program("rsvg-convert", 1) if ($pdf); + + check_distros(); + + if ($need_symlink) { + printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n", + which("sphinx-build-3"); + } + if ($need_sphinx) { + my $activate = "$virtenv_dir/bin/activate"; + if (-e "$ENV{'PWD'}/$activate") { + printf "\nNeed to activate virtualenv with:\n"; + printf "\t. $activate\n"; + } else { + my $virtualenv = findprog("virtualenv-3"); + $virtualenv = findprog("virtualenv-3.5") if (!$virtualenv); + $virtualenv = findprog("virtualenv") if (!$virtualenv); + $virtualenv = "virtualenv" if (!$virtualenv); + + printf "\t$virtualenv $virtenv_dir\n"; + printf "\t. $activate\n"; + printf "\tpip install -r $requirement_file\n"; + $need++; + } + } + printf "\n"; + + print "All optional dependenties are met.\n" if (!$optional); + + if ($need == 1) { + die "Can't build as $need mandatory dependency is missing"; + } elsif ($need) { + die "Can't build as $need mandatory dependencies are missing"; + } + + print "Needed package dependencies are met.\n"; +} + +# +# Main +# + +while (@ARGV) { + my $arg = shift(@ARGV); + + if ($arg eq "--no-virtualenv") { + $virtualenv = 0; + } elsif ($arg eq "--no-pdf"){ + $pdf = 0; + } else { + print "Usage:\n\t$0 <--no-virtualenv> <--no-pdf>\n\n"; + exit -1; + } +} + +# +# Determine the system type. There's no standard unique way that would +# work with all distros with a minimal package install. So, several +# methods are used here. +# +# By default, it will use lsb_release function. If not available, it will +# fail back to reading the known different places where the distro name +# is stored +# + +$system_release = qx(lsb_release -d) if which("lsb_release"); +$system_release =~ s/Description:\s*// if ($system_release); +$system_release = catcheck("/etc/system-release") if !$system_release; +$system_release = catcheck("/etc/redhat-release") if !$system_release; +$system_release = catcheck("/etc/lsb-release") if !$system_release; +$system_release = catcheck("/etc/gentoo-release") if !$system_release; +$system_release = catcheck("/etc/issue") if !$system_release; +$system_release =~ s/\s+$//; + +check_needs; diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore index 9cdec70d72b8ed83c38ec3a271b9495b53975b2e..d5b291e94264f9784438ea38e3242ad7697cb510 100644 --- a/security/apparmor/.gitignore +++ b/security/apparmor/.gitignore @@ -1,5 +1,6 @@ # # Generated include files # +net_names.h capability_names.h rlim_names.h diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile index a16b195274dec2c48d3ee41e3cdad1b6460138c1..dafdd387d42bab8a5184efb51240123fd3a463f5 100644 --- a/security/apparmor/Makefile +++ b/security/apparmor/Makefile @@ -4,11 +4,44 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ - resource.o secid.o file.o policy_ns.o label.o + resource.o secid.o file.o policy_ns.o label.o mount.o net.o apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o -clean-files := capability_names.h rlim_names.h +clean-files := capability_names.h rlim_names.h net_names.h +# Build a lower case string table of address family names +# Transform lines from +# #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ +# #define AF_INET 2 /* Internet IP Protocol */ +# to +# [1] = "local", +# [2] = "inet", +# +# and build the securityfs entries for the mapping. +# Transforms lines from +# #define AF_INET 2 /* Internet IP Protocol */ +# to +# #define AA_SFS_AF_MASK "local inet" +quiet_cmd_make-af = GEN $@ +cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\ + sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \ + 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\ + echo "};" >> $@ ;\ + printf '%s' '\#define AA_SFS_AF_MASK "' >> $@ ;\ + sed -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \ + 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\ + $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ + +# Build a lower case string table of sock type names +# Transform lines from +# SOCK_STREAM = 1, +# to +# [1] = "stream", +quiet_cmd_make-sock = GEN $@ +cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\ + sed $^ >>$@ -r -n \ + -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\ + echo "};" >> $@ # Build a lower case string table of capability names # Transforms lines from @@ -61,6 +94,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ $(obj)/capability.o : $(obj)/capability_names.h +$(obj)/net.o : $(obj)/net_names.h $(obj)/resource.o : $(obj)/rlim_names.h $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ $(src)/Makefile @@ -68,3 +102,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \ $(src)/Makefile $(call cmd,make-rlim) +$(obj)/net_names.h : $(srctree)/include/linux/socket.h \ + $(srctree)/include/linux/net.h \ + $(src)/Makefile + $(call cmd,make-af) + $(call cmd,make-sock) diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 853c2ec8e0c9521e53fe2c6edecb0b7913cfad26..518d5928661b518c8f037db26edfed44f6270752 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -32,6 +32,7 @@ #include "include/audit.h" #include "include/context.h" #include "include/crypto.h" +#include "include/ipc.h" #include "include/policy_ns.h" #include "include/label.h" #include "include/policy.h" @@ -248,8 +249,10 @@ static struct dentry *aafs_create(const char *name, umode_t mode, inode_lock(dir); dentry = lookup_one_len(name, parent, strlen(name)); - if (IS_ERR(dentry)) + if (IS_ERR(dentry)) { + error = PTR_ERR(dentry); goto fail_lock; + } if (d_really_is_positive(dentry)) { error = -EEXIST; @@ -1443,6 +1446,10 @@ void __aafs_profile_migrate_dents(struct aa_profile *old, { int i; + AA_BUG(!old); + AA_BUG(!new); + AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock)); + for (i = 0; i < AAFS_PROF_SIZEOF; i++) { new->dents[i] = old->dents[i]; if (new->dents[i]) @@ -1506,6 +1513,9 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent) struct dentry *dent = NULL, *dir; int error; + AA_BUG(!profile); + AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock)); + if (!parent) { struct aa_profile *p; p = aa_deref_parent(profile); @@ -1731,6 +1741,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns) if (!ns) return; + AA_BUG(!mutex_is_locked(&ns->lock)); list_for_each_entry(child, &ns->base.profiles, base.list) __aafs_profile_rmdir(child); @@ -1903,6 +1914,10 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns) { struct aa_ns *parent, *next; + AA_BUG(!root); + AA_BUG(!ns); + AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock)); + /* is next namespace a child */ if (!list_empty(&ns->sub_ns)) { next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list); @@ -1937,6 +1952,9 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns) static struct aa_profile *__first_profile(struct aa_ns *root, struct aa_ns *ns) { + AA_BUG(!root); + AA_BUG(ns && !mutex_is_locked(&ns->lock)); + for (; ns; ns = __next_ns(root, ns)) { if (!list_empty(&ns->base.profiles)) return list_first_entry(&ns->base.profiles, @@ -1959,6 +1977,8 @@ static struct aa_profile *__next_profile(struct aa_profile *p) struct aa_profile *parent; struct aa_ns *ns = p->ns; + AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock)); + /* is next profile a child */ if (!list_empty(&p->base.profiles)) return list_first_entry(&p->base.profiles, typeof(*p), @@ -2127,6 +2147,11 @@ static struct aa_sfs_entry aa_sfs_entry_ptrace[] = { { } }; +static struct aa_sfs_entry aa_sfs_entry_signal[] = { + AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK), + { } +}; + static struct aa_sfs_entry aa_sfs_entry_domain[] = { AA_SFS_FILE_BOOLEAN("change_hat", 1), AA_SFS_FILE_BOOLEAN("change_hatv", 1), @@ -2151,9 +2176,14 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = { { } }; +static struct aa_sfs_entry aa_sfs_entry_mount[] = { + AA_SFS_FILE_STRING("mask", "mount umount pivot_root"), + { } +}; + static struct aa_sfs_entry aa_sfs_entry_ns[] = { AA_SFS_FILE_BOOLEAN("profile", 1), - AA_SFS_FILE_BOOLEAN("pivot_root", 1), + AA_SFS_FILE_BOOLEAN("pivot_root", 0), { } }; @@ -2172,22 +2202,25 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = { AA_SFS_DIR("policy", aa_sfs_entry_policy), AA_SFS_DIR("domain", aa_sfs_entry_domain), AA_SFS_DIR("file", aa_sfs_entry_file), + AA_SFS_DIR("network", aa_sfs_entry_network), + AA_SFS_DIR("mount", aa_sfs_entry_mount), AA_SFS_DIR("namespaces", aa_sfs_entry_ns), AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit), AA_SFS_DIR("caps", aa_sfs_entry_caps), AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace), + AA_SFS_DIR("signal", aa_sfs_entry_signal), AA_SFS_DIR("query", aa_sfs_entry_query), { } }; static struct aa_sfs_entry aa_sfs_entry_apparmor[] = { - AA_SFS_FILE_FOPS(".access", 0640, &aa_sfs_access), + AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access), AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops), AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops), - AA_SFS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops), - AA_SFS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops), - AA_SFS_FILE_FOPS("profiles", 0440, &aa_sfs_profiles_fops), + AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops), + AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops), + AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops), AA_SFS_DIR("features", aa_sfs_entry_features), { } }; diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index d0594446ae3ffffc85c3963c0f3ca5a43fe33b38..dd754b7850a82b4d129c11de0c55603de19268ba 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -374,8 +374,8 @@ static const char *next_name(int xtype, const char *name) * * Returns: refcounted label, or NULL on failure (MAYBE NULL) */ -static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, - const char **name) +struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, + const char **name) { struct aa_label *label = NULL; u32 xtype = xindex & AA_X_TYPE_MASK; @@ -758,7 +758,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) file_inode(bprm->file)->i_mode }; - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; ctx = cred_ctx(bprm->cred); @@ -807,7 +807,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) aa_label_printk(new, GFP_ATOMIC); dbg_printk("\n"); } - bprm->unsafe |= AA_SECURE_X_NEEDED; + bprm->secureexec = 1; } if (label->proxy != new->proxy) { @@ -843,23 +843,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) goto done; } -/** - * apparmor_bprm_secureexec - determine if secureexec is needed - * @bprm: binprm for exec (NOT NULL) - * - * Returns: %1 if secureexec is needed else %0 - */ -int apparmor_bprm_secureexec(struct linux_binprm *bprm) -{ - /* the decision to use secure exec is computed in set_creds - * and stored in bprm->unsafe. - */ - if (bprm->unsafe & AA_SECURE_X_NEEDED) - return 1; - - return 0; -} - /* * Functions for self directed profile change */ diff --git a/security/apparmor/file.c b/security/apparmor/file.c index 3382518b87fa507200679cb9ef660329a292debc..db80221891c66f034c1a3138f46d455a2685d102 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c @@ -21,6 +21,7 @@ #include "include/context.h" #include "include/file.h" #include "include/match.h" +#include "include/net.h" #include "include/path.h" #include "include/policy.h" #include "include/label.h" @@ -566,6 +567,32 @@ static int __file_path_perm(const char *op, struct aa_label *label, return error; } +static int __file_sock_perm(const char *op, struct aa_label *label, + struct aa_label *flabel, struct file *file, + u32 request, u32 denied) +{ + struct socket *sock = (struct socket *) file->private_data; + int error; + + AA_BUG(!sock); + + /* revalidation due to label out of date. No revocation at this time */ + if (!denied && aa_label_is_subset(flabel, label)) + return 0; + + /* TODO: improve to skip profiles cached in flabel */ + error = aa_sock_file_perm(label, op, request, sock); + if (denied) { + /* TODO: improve to skip profiles checked above */ + /* check every profile in file label to is cached */ + last_error(error, aa_sock_file_perm(flabel, op, request, sock)); + } + if (!error) + update_file_ctx(file_ctx(file), label, request); + + return error; +} + /** * aa_file_perm - do permission revalidation check & audit for @file * @op: operation being checked @@ -610,6 +637,9 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, error = __file_path_perm(op, label, flabel, file, request, denied); + else if (S_ISSOCK(file_inode(file)->i_mode)) + error = __file_sock_perm(op, label, flabel, file, request, + denied); done: rcu_read_unlock(); diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index aaf893f4e4f50c8f35f2e74c18a264f5ee583a39..829082c35faac7a932a568745068a2a3a979c124 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h @@ -27,7 +27,9 @@ #define AA_CLASS_NET 4 #define AA_CLASS_RLIMITS 5 #define AA_CLASS_DOMAIN 6 +#define AA_CLASS_MOUNT 7 #define AA_CLASS_PTRACE 9 +#define AA_CLASS_SIGNAL 10 #define AA_CLASS_LABEL 16 #define AA_CLASS_LAST AA_CLASS_LABEL diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index c68839a44351e9b184951a6535fa574293c55876..ff4316e1068d6b98ea7cbf44d21e96ff75cf9328 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h @@ -71,6 +71,10 @@ enum audit_type { #define OP_FMPROT "file_mprotect" #define OP_INHERIT "file_inherit" +#define OP_PIVOTROOT "pivotroot" +#define OP_MOUNT "mount" +#define OP_UMOUNT "umount" + #define OP_CREATE "create" #define OP_POST_CREATE "post_create" #define OP_BIND "bind" @@ -86,6 +90,7 @@ enum audit_type { #define OP_SHUTDOWN "socket_shutdown" #define OP_PTRACE "ptrace" +#define OP_SIGNAL "signal" #define OP_EXEC "exec" @@ -116,20 +121,36 @@ struct apparmor_audit_data { /* these entries require a custom callback fn */ struct { struct aa_label *peer; - struct { - const char *target; - kuid_t ouid; - } fs; + union { + struct { + kuid_t ouid; + const char *target; + } fs; + struct { + int type, protocol; + struct sock *peer_sk; + void *addr; + int addrlen; + } net; + int signal; + struct { + int rlim; + unsigned long max; + } rlim; + }; }; struct { - const char *name; - long pos; + struct aa_profile *profile; const char *ns; + long pos; } iface; struct { - int rlim; - unsigned long max; - } rlim; + const char *src_name; + const char *type; + const char *trans; + const char *data; + unsigned long flags; + } mnt; }; }; diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h index bab5810b6e9a11e9d245801938c28c89e1180c74..ac9862ff7cdf5d7bed9a365a30e8d62c1cfc0c1f 100644 --- a/security/apparmor/include/domain.h +++ b/security/apparmor/include/domain.h @@ -15,6 +15,8 @@ #include #include +#include "label.h" + #ifndef __AA_DOMAIN_H #define __AA_DOMAIN_H @@ -29,8 +31,10 @@ struct aa_domain { #define AA_CHANGE_ONEXEC 4 #define AA_CHANGE_STACK 8 +struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, + const char **name); + int apparmor_bprm_set_creds(struct linux_binprm *bprm); -int apparmor_bprm_secureexec(struct linux_binprm *bprm); void aa_free_domain_entries(struct aa_domain *domain); int aa_change_hat(const char *hats[], int count, u64 token, int flags); diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h index 001e40073ff92480e6f8b9ea88e760ebefde5b6f..4c2c8ac8842f6d8c05c4480fa2680b4ba9ab75df 100644 --- a/security/apparmor/include/file.h +++ b/security/apparmor/include/file.h @@ -101,9 +101,6 @@ static inline struct aa_label *aa_get_file_label(struct aa_file_ctx *ctx) #define AA_X_INHERIT 0x4000 #define AA_X_UNCONFINED 0x8000 -/* AA_SECURE_X_NEEDED - is passed in the bprm->unsafe field */ -#define AA_SECURE_X_NEEDED 0x8000 - /* need to make conditional which ones are being set */ struct path_cond { kuid_t uid; diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h index 656fdb81c8a0a08836b12ed614334222c0648212..5ffc218d1e748aebb6aa777ad129976e87752ddd 100644 --- a/security/apparmor/include/ipc.h +++ b/security/apparmor/include/ipc.h @@ -27,8 +27,14 @@ struct aa_profile; #define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \ AA_MAY_BE_READ | AA_MAY_BE_TRACED) +#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE) + +#define AA_SFS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \ + "segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \ + "xcpu xfsz vtalrm prof winch io pwr sys emt lost" int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, u32 request); +int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig); #endif /* __AA_IPC_H */ diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h index 9a283b722755786a2e213e591323d101d7b30816..af22dcbbcb8aa165d16d1769aba7e92eb5965ada 100644 --- a/security/apparmor/include/label.h +++ b/security/apparmor/include/label.h @@ -310,6 +310,7 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp); #define FLAG_SHOW_MODE 1 #define FLAG_VIEW_SUBNS 2 #define FLAG_HIDDEN_UNCONFINED 4 +#define FLAG_ABS_ROOT 8 int aa_label_snxprint(char *str, size_t size, struct aa_ns *view, struct aa_label *label, int flags); int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label, diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h new file mode 100644 index 0000000000000000000000000000000000000000..25d6067fa6efef03c1257045756a3cd85576403a --- /dev/null +++ b/security/apparmor/include/mount.h @@ -0,0 +1,54 @@ +/* + * AppArmor security module + * + * This file contains AppArmor file mediation function definitions. + * + * Copyright 2017 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#ifndef __AA_MOUNT_H +#define __AA_MOUNT_H + +#include +#include + +#include "domain.h" +#include "policy.h" + +/* mount perms */ +#define AA_MAY_PIVOTROOT 0x01 +#define AA_MAY_MOUNT 0x02 +#define AA_MAY_UMOUNT 0x04 +#define AA_AUDIT_DATA 0x40 +#define AA_MNT_CONT_MATCH 0x40 + +#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN) + +int aa_remount(struct aa_label *label, const struct path *path, + unsigned long flags, void *data); + +int aa_bind_mount(struct aa_label *label, const struct path *path, + const char *old_name, unsigned long flags); + + +int aa_mount_change_type(struct aa_label *label, const struct path *path, + unsigned long flags); + +int aa_move_mount(struct aa_label *label, const struct path *path, + const char *old_name); + +int aa_new_mount(struct aa_label *label, const char *dev_name, + const struct path *path, const char *type, unsigned long flags, + void *data); + +int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags); + +int aa_pivotroot(struct aa_label *label, const struct path *old_path, + const struct path *new_path); + +#endif /* __AA_MOUNT_H */ diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h new file mode 100644 index 0000000000000000000000000000000000000000..140c8efcf3644fdb6d3eadb348b7a8dd921c272c --- /dev/null +++ b/security/apparmor/include/net.h @@ -0,0 +1,114 @@ +/* + * AppArmor security module + * + * This file contains AppArmor network mediation definitions. + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009-2017 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#ifndef __AA_NET_H +#define __AA_NET_H + +#include +#include + +#include "apparmorfs.h" +#include "label.h" +#include "perms.h" +#include "policy.h" + +#define AA_MAY_SEND AA_MAY_WRITE +#define AA_MAY_RECEIVE AA_MAY_READ + +#define AA_MAY_SHUTDOWN AA_MAY_DELETE + +#define AA_MAY_CONNECT AA_MAY_OPEN +#define AA_MAY_ACCEPT 0x00100000 + +#define AA_MAY_BIND 0x00200000 +#define AA_MAY_LISTEN 0x00400000 + +#define AA_MAY_SETOPT 0x01000000 +#define AA_MAY_GETOPT 0x02000000 + +#define NET_PERMS_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE | \ + AA_MAY_SHUTDOWN | AA_MAY_BIND | AA_MAY_LISTEN | \ + AA_MAY_CONNECT | AA_MAY_ACCEPT | AA_MAY_SETATTR | \ + AA_MAY_GETATTR | AA_MAY_SETOPT | AA_MAY_GETOPT) + +#define NET_FS_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE | \ + AA_MAY_SHUTDOWN | AA_MAY_CONNECT | AA_MAY_RENAME |\ + AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_CHMOD | \ + AA_MAY_CHOWN | AA_MAY_CHGRP | AA_MAY_LOCK | \ + AA_MAY_MPROT) + +#define NET_PEER_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CONNECT | \ + AA_MAY_ACCEPT) +struct aa_sk_ctx { + struct aa_label *label; + struct aa_label *peer; + struct path path; +}; + +#define SK_CTX(X) ((X)->sk_security) +#define SOCK_ctx(X) SOCK_INODE(X)->i_security +#define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P) \ + struct lsm_network_audit NAME ## _net = { .sk = (SK), \ + .family = (F)}; \ + DEFINE_AUDIT_DATA(NAME, \ + ((SK) && (F) != AF_UNIX) ? LSM_AUDIT_DATA_NET : \ + LSM_AUDIT_DATA_NONE, \ + OP); \ + NAME.u.net = &(NAME ## _net); \ + aad(&NAME)->net.type = (T); \ + aad(&NAME)->net.protocol = (P) + +#define DEFINE_AUDIT_SK(NAME, OP, SK) \ + DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type, \ + (SK)->sk_protocol) + +/* struct aa_net - network confinement data + * @allow: basic network families permissions + * @audit: which network permissions to force audit + * @quiet: which network permissions to quiet rejects + */ +struct aa_net { + u16 allow[AF_MAX]; + u16 audit[AF_MAX]; + u16 quiet[AF_MAX]; +}; + + +extern struct aa_sfs_entry aa_sfs_entry_network[]; + +void audit_net_cb(struct audit_buffer *ab, void *va); +int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, + u32 request, u16 family, int type); +int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, + int type, int protocol); +static inline int aa_profile_af_sk_perm(struct aa_profile *profile, + struct common_audit_data *sa, + u32 request, + struct sock *sk) +{ + return aa_profile_af_perm(profile, sa, request, sk->sk_family, + sk->sk_type); +} +int aa_sk_perm(const char *op, u32 request, struct sock *sk); + +int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, + struct socket *sock); + + +static inline void aa_free_net_rules(struct aa_net *new) +{ + /* NOP */ +} + +#endif /* __AA_NET_H */ diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h index 2b27bb79aec4421665aaa6f2a2490868227bed0f..af04d5a7d73d46146f152c83529a50829b986962 100644 --- a/security/apparmor/include/perms.h +++ b/security/apparmor/include/perms.h @@ -135,9 +135,10 @@ extern struct aa_perms allperms; void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); -void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); +void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, + u32 mask); void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, - u32 chrsmask, const char **names, u32 namesmask); + u32 chrsmask, const char * const *names, u32 namesmask); void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms); void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 17fe41a9cac35e6d88f3ae738bf2b068de736ec1..4364088a0b9e2188b6353e815cca6c1b3e70fc25 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -30,6 +30,7 @@ #include "file.h" #include "lib.h" #include "label.h" +#include "net.h" #include "perms.h" #include "resource.h" @@ -111,6 +112,7 @@ struct aa_data { * @policy: general match rules governing policy * @file: The set of rules governing basic file access and domain transitions * @caps: capabilities for the profile + * @net: network controls for the profile * @rlimits: rlimits for the profile * * @dents: dentries for the profiles file entries in apparmorfs @@ -148,6 +150,7 @@ struct aa_profile { struct aa_policydb policy; struct aa_file_rules file; struct aa_caps caps; + struct aa_net net; struct aa_rlimit rlimits; struct aa_loaddata *rawdata; @@ -220,6 +223,16 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile, return 0; } +static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile, + u16 AF) { + unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET); + u16 be_af = cpu_to_be16(AF); + + if (!state) + return 0; + return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2); +} + /** * aa_get_profile - increment refcount on profile @p * @p: profile (MAYBE NULL) diff --git a/security/apparmor/include/sig_names.h b/security/apparmor/include/sig_names.h new file mode 100644 index 0000000000000000000000000000000000000000..92e62fe952926b5abdc3348884d8e2fc6b966f1d --- /dev/null +++ b/security/apparmor/include/sig_names.h @@ -0,0 +1,98 @@ +#include + +#define SIGUNKNOWN 0 +#define MAXMAPPED_SIG 35 +/* provide a mapping of arch signal to internal signal # for mediation + * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO + * map to the same entry those that may/or may not get a separate entry + */ +static const int sig_map[MAXMAPPED_SIG] = { + [0] = MAXMAPPED_SIG, /* existence test */ + [SIGHUP] = 1, + [SIGINT] = 2, + [SIGQUIT] = 3, + [SIGILL] = 4, + [SIGTRAP] = 5, /* -, 5, - */ + [SIGABRT] = 6, /* SIGIOT: -, 6, - */ + [SIGBUS] = 7, /* 10, 7, 10 */ + [SIGFPE] = 8, + [SIGKILL] = 9, + [SIGUSR1] = 10, /* 30, 10, 16 */ + [SIGSEGV] = 11, + [SIGUSR2] = 12, /* 31, 12, 17 */ + [SIGPIPE] = 13, + [SIGALRM] = 14, + [SIGTERM] = 15, +#ifdef SIGSTKFLT + [SIGSTKFLT] = 16, /* -, 16, - */ +#endif + [SIGCHLD] = 17, /* 20, 17, 18. SIGCHLD -, -, 18 */ + [SIGCONT] = 18, /* 19, 18, 25 */ + [SIGSTOP] = 19, /* 17, 19, 23 */ + [SIGTSTP] = 20, /* 18, 20, 24 */ + [SIGTTIN] = 21, /* 21, 21, 26 */ + [SIGTTOU] = 22, /* 22, 22, 27 */ + [SIGURG] = 23, /* 16, 23, 21 */ + [SIGXCPU] = 24, /* 24, 24, 30 */ + [SIGXFSZ] = 25, /* 25, 25, 31 */ + [SIGVTALRM] = 26, /* 26, 26, 28 */ + [SIGPROF] = 27, /* 27, 27, 29 */ + [SIGWINCH] = 28, /* 28, 28, 20 */ + [SIGIO] = 29, /* SIGPOLL: 23, 29, 22 */ + [SIGPWR] = 30, /* 29, 30, 19. SIGINFO 29, -, - */ +#ifdef SIGSYS + [SIGSYS] = 31, /* 12, 31, 12. often SIG LOST/UNUSED */ +#endif +#ifdef SIGEMT + [SIGEMT] = 32, /* 7, - , 7 */ +#endif +#if defined(SIGLOST) && SIGPWR != SIGLOST /* sparc */ + [SIGLOST] = 33, /* unused on Linux */ +#endif +#if defined(SIGUNUSED) && \ + defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS + [SIGUNUSED] = 34, /* -, 31, - */ +#endif +}; + +/* this table is ordered post sig_map[sig] mapping */ +static const char *const sig_names[MAXMAPPED_SIG + 1] = { + "unknown", + "hup", + "int", + "quit", + "ill", + "trap", + "abrt", + "bus", + "fpe", + "kill", + "usr1", + "segv", + "usr2", + "pipe", + "alrm", + "term", + "stkflt", + "chld", + "cont", + "stop", + "stp", + "ttin", + "ttou", + "urg", + "xcpu", + "xfsz", + "vtalrm", + "prof", + "winch", + "io", + "pwr", + "sys", + "emt", + "lost", + "unused", + + "exists", /* always last existence test mapped to MAXMAPPED_SIG */ +}; + diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c index 11e66b5bbc4266c7c9b0f4fa47d13afdf709b47f..66fb9ede9447adc71e3fd27a0b90d306b095c0fe 100644 --- a/security/apparmor/ipc.c +++ b/security/apparmor/ipc.c @@ -20,6 +20,7 @@ #include "include/context.h" #include "include/policy.h" #include "include/ipc.h" +#include "include/sig_names.h" /** * audit_ptrace_mask - convert mask to permission string @@ -121,3 +122,101 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, } +static inline int map_signal_num(int sig) +{ + if (sig > SIGRTMAX) + return SIGUNKNOWN; + else if (sig >= SIGRTMIN) + return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */ + else if (sig <= MAXMAPPED_SIG) + return sig_map[sig]; + return SIGUNKNOWN; +} + +/** + * audit_file_mask - convert mask to permission string + * @buffer: buffer to write string to (NOT NULL) + * @mask: permission mask to convert + */ +static void audit_signal_mask(struct audit_buffer *ab, u32 mask) +{ + if (mask & MAY_READ) + audit_log_string(ab, "receive"); + if (mask & MAY_WRITE) + audit_log_string(ab, "send"); +} + +/** + * audit_cb - call back for signal specific audit fields + * @ab: audit_buffer (NOT NULL) + * @va: audit struct to audit values of (NOT NULL) + */ +static void audit_signal_cb(struct audit_buffer *ab, void *va) +{ + struct common_audit_data *sa = va; + + if (aad(sa)->request & AA_SIGNAL_PERM_MASK) { + audit_log_format(ab, " requested_mask="); + audit_signal_mask(ab, aad(sa)->request); + if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) { + audit_log_format(ab, " denied_mask="); + audit_signal_mask(ab, aad(sa)->denied); + } + } + if (aad(sa)->signal <= MAXMAPPED_SIG) + audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]); + else + audit_log_format(ab, " signal=rtmin+%d", + aad(sa)->signal - 128); + audit_log_format(ab, " peer="); + aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, + FLAGS_NONE, GFP_ATOMIC); +} + +/* TODO: update to handle compound name&name2, conditionals */ +static void profile_match_signal(struct aa_profile *profile, const char *label, + int signal, struct aa_perms *perms) +{ + unsigned int state; + + /* TODO: secondary cache check */ + state = aa_dfa_next(profile->policy.dfa, + profile->policy.start[AA_CLASS_SIGNAL], + signal); + state = aa_dfa_match(profile->policy.dfa, state, label); + aa_compute_perms(profile->policy.dfa, state, perms); +} + +static int profile_signal_perm(struct aa_profile *profile, + struct aa_profile *peer, u32 request, + struct common_audit_data *sa) +{ + struct aa_perms perms; + + if (profile_unconfined(profile) || + !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL)) + return 0; + + aad(sa)->peer = &peer->label; + profile_match_signal(profile, peer->base.hname, aad(sa)->signal, + &perms); + aa_apply_modes_to_perms(profile, &perms); + return aa_check_perms(profile, &perms, request, sa, audit_signal_cb); +} + +static int aa_signal_cross_perm(struct aa_profile *sender, + struct aa_profile *target, + struct common_audit_data *sa) +{ + return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa), + profile_signal_perm(target, sender, MAY_READ, sa)); +} + +int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig) +{ + DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL); + + aad(&sa)->signal = map_signal_num(sig); + return xcheck_labels_profiles(sender, target, aa_signal_cross_perm, + &sa); +} diff --git a/security/apparmor/label.c b/security/apparmor/label.c index e052eaba1cf6ccb003c1e3ae364798bc44b1d292..c5b99b954580c940d3cc3659a48c10b22752c1f0 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -49,7 +49,7 @@ static void free_proxy(struct aa_proxy *proxy) /* p->label will not updated any more as p is dead */ aa_put_label(rcu_dereference_protected(proxy->label, true)); memset(proxy, 0, sizeof(*proxy)); - proxy->label = (struct aa_label *) PROXY_POISON; + RCU_INIT_POINTER(proxy->label, (struct aa_label *)PROXY_POISON); kfree(proxy); } } @@ -1450,9 +1450,11 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp) * cached label name is present and visible * @label->hname only exists if label is namespace hierachical */ -static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label) +static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label, + int flags) { - if (label->hname && labels_ns(label) == ns) + if (label->hname && (!ns || labels_ns(label) == ns) && + !(flags & ~FLAG_SHOW_MODE)) return true; return false; @@ -1495,7 +1497,7 @@ static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view, view = profiles_ns(profile); if (view != profile->ns && - (!prev_ns || (prev_ns && *prev_ns != profile->ns))) { + (!prev_ns || (*prev_ns != profile->ns))) { if (prev_ns) *prev_ns = profile->ns; ns_name = aa_ns_name(view, profile->ns, @@ -1605,8 +1607,13 @@ int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns, AA_BUG(!str && size != 0); AA_BUG(!label); - if (!ns) + if (flags & FLAG_ABS_ROOT) { + ns = root_ns; + len = snprintf(str, size, "="); + update_for_len(total, len, size, str); + } else if (!ns) { ns = labels_ns(label); + } label_for_each(i, label, profile) { if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) { @@ -1710,10 +1717,8 @@ void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns, AA_BUG(!ab); AA_BUG(!label); - if (!ns) - ns = labels_ns(label); - - if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) { + if (!use_label_hname(ns, label, flags) || + display_mode(ns, label, flags)) { len = aa_label_asxprint(&name, ns, label, flags, gfp); if (len == -1) { AA_DEBUG("label print error"); @@ -1738,10 +1743,7 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns, AA_BUG(!f); AA_BUG(!label); - if (!ns) - ns = labels_ns(label); - - if (!use_label_hname(ns, label)) { + if (!use_label_hname(ns, label, flags)) { char *str; int len; @@ -1764,10 +1766,7 @@ void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags, { AA_BUG(!label); - if (!ns) - ns = labels_ns(label); - - if (!use_label_hname(ns, label)) { + if (!use_label_hname(ns, label, flags)) { char *str; int len; @@ -1874,6 +1873,9 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str, if (*str == '&') str++; } + if (*str == '=') + base = &root_ns->unconfined->label; + error = vec_setup(profile, vec, len, gfp); if (error) return ERR_PTR(error); diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 08ca26bcca7703c7f74e1531879eea4dd3bf2ac9..8818621b5d956023d9fc799fbff00a0b073fabc8 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -211,7 +211,8 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) *str = '\0'; } -void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask) +void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, + u32 mask) { const char *fmt = "%s"; unsigned int i, perm = 1; @@ -229,7 +230,7 @@ void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask) } void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, - u32 chrsmask, const char **names, u32 namesmask) + u32 chrsmask, const char * const *names, u32 namesmask) { char str[33]; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 867bcd154c7e632942185a4b609f24197bf0f4ec..72b915dfcaf7eeeed1a2d428777878c81e5f4f80 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -33,11 +33,13 @@ #include "include/context.h" #include "include/file.h" #include "include/ipc.h" +#include "include/net.h" #include "include/path.h" #include "include/label.h" #include "include/policy.h" #include "include/policy_ns.h" #include "include/procattr.h" +#include "include/mount.h" /* Flag indicating whether initialization completed */ int apparmor_initialized; @@ -511,6 +513,65 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma, !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); } +static int apparmor_sb_mount(const char *dev_name, const struct path *path, + const char *type, unsigned long flags, void *data) +{ + struct aa_label *label; + int error = 0; + + /* Discard magic */ + if ((flags & MS_MGC_MSK) == MS_MGC_VAL) + flags &= ~MS_MGC_MSK; + + flags &= ~AA_MS_IGNORE_MASK; + + label = __begin_current_label_crit_section(); + if (!unconfined(label)) { + if (flags & MS_REMOUNT) + error = aa_remount(label, path, flags, data); + else if (flags & MS_BIND) + error = aa_bind_mount(label, path, dev_name, flags); + else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | + MS_UNBINDABLE)) + error = aa_mount_change_type(label, path, flags); + else if (flags & MS_MOVE) + error = aa_move_mount(label, path, dev_name); + else + error = aa_new_mount(label, dev_name, path, type, + flags, data); + } + __end_current_label_crit_section(label); + + return error; +} + +static int apparmor_sb_umount(struct vfsmount *mnt, int flags) +{ + struct aa_label *label; + int error = 0; + + label = __begin_current_label_crit_section(); + if (!unconfined(label)) + error = aa_umount(label, mnt, flags); + __end_current_label_crit_section(label); + + return error; +} + +static int apparmor_sb_pivotroot(const struct path *old_path, + const struct path *new_path) +{ + struct aa_label *label; + int error = 0; + + label = aa_get_current_label(); + if (!unconfined(label)) + error = aa_pivotroot(label, old_path, new_path); + aa_put_label(label); + + return error; +} + static int apparmor_getprocattr(struct task_struct *task, char *name, char **value) { @@ -656,12 +717,398 @@ static int apparmor_task_setrlimit(struct task_struct *task, return error; } +static int apparmor_task_kill(struct task_struct *target, struct siginfo *info, + int sig, u32 secid) +{ + struct aa_label *cl, *tl; + int error; + + if (secid) + /* TODO: after secid to label mapping is done. + * Dealing with USB IO specific behavior + */ + return 0; + cl = __begin_current_label_crit_section(); + tl = aa_get_task_label(target); + error = aa_may_signal(cl, tl, sig); + aa_put_label(tl); + __end_current_label_crit_section(cl); + + return error; +} + +/** + * apparmor_sk_alloc_security - allocate and attach the sk_security field + */ +static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags) +{ + struct aa_sk_ctx *ctx; + + ctx = kzalloc(sizeof(*ctx), flags); + if (!ctx) + return -ENOMEM; + + SK_CTX(sk) = ctx; + + return 0; +} + +/** + * apparmor_sk_free_security - free the sk_security field + */ +static void apparmor_sk_free_security(struct sock *sk) +{ + struct aa_sk_ctx *ctx = SK_CTX(sk); + + SK_CTX(sk) = NULL; + aa_put_label(ctx->label); + aa_put_label(ctx->peer); + path_put(&ctx->path); + kfree(ctx); +} + +/** + * apparmor_clone_security - clone the sk_security field + */ +static void apparmor_sk_clone_security(const struct sock *sk, + struct sock *newsk) +{ + struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *new = SK_CTX(newsk); + + new->label = aa_get_label(ctx->label); + new->peer = aa_get_label(ctx->peer); + new->path = ctx->path; + path_get(&new->path); +} + +static int aa_sock_create_perm(struct aa_label *label, int family, int type, + int protocol) +{ + AA_BUG(!label); + AA_BUG(in_interrupt()); + + return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type, + protocol); +} + + +/** + * apparmor_socket_create - check perms before creating a new socket + */ +static int apparmor_socket_create(int family, int type, int protocol, int kern) +{ + struct aa_label *label; + int error = 0; + + label = begin_current_label_crit_section(); + if (!(kern || unconfined(label))) + error = aa_sock_create_perm(label, family, type, protocol); + end_current_label_crit_section(label); + + return error; +} + +/** + * apparmor_socket_post_create - setup the per-socket security struct + * + * Note: + * - kernel sockets currently labeled unconfined but we may want to + * move to a special kernel label + * - socket may not have sk here if created with sock_create_lite or + * sock_alloc. These should be accept cases which will be handled in + * sock_graft. + */ +static int apparmor_socket_post_create(struct socket *sock, int family, + int type, int protocol, int kern) +{ + struct aa_label *label; + + if (kern) { + struct aa_ns *ns = aa_get_current_ns(); + + label = aa_get_label(ns_unconfined(ns)); + aa_put_ns(ns); + } else + label = aa_get_current_label(); + + if (sock->sk) { + struct aa_sk_ctx *ctx = SK_CTX(sock->sk); + + aa_put_label(ctx->label); + ctx->label = aa_get_label(label); + } + aa_put_label(label); + + return 0; +} + +/** + * apparmor_socket_bind - check perms before bind addr to socket + */ +static int apparmor_socket_bind(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(!address); + AA_BUG(in_interrupt()); + + return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk); +} + +/** + * apparmor_socket_connect - check perms before connecting @sock to @address + */ +static int apparmor_socket_connect(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(!address); + AA_BUG(in_interrupt()); + + return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk); +} + +/** + * apparmor_socket_list - check perms before allowing listen + */ +static int apparmor_socket_listen(struct socket *sock, int backlog) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(in_interrupt()); + + return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk); +} + +/** + * apparmor_socket_accept - check perms before accepting a new connection. + * + * Note: while @newsock is created and has some information, the accept + * has not been done. + */ +static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(!newsock); + AA_BUG(in_interrupt()); + + return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk); +} + +static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock, + struct msghdr *msg, int size) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(!msg); + AA_BUG(in_interrupt()); + + return aa_sk_perm(op, request, sock->sk); +} + +/** + * apparmor_socket_sendmsg - check perms before sending msg to another socket + */ +static int apparmor_socket_sendmsg(struct socket *sock, + struct msghdr *msg, int size) +{ + return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size); +} + +/** + * apparmor_socket_recvmsg - check perms before receiving a message + */ +static int apparmor_socket_recvmsg(struct socket *sock, + struct msghdr *msg, int size, int flags) +{ + return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size); +} + +/* revaliation, get/set attr, shutdown */ +static int aa_sock_perm(const char *op, u32 request, struct socket *sock) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(in_interrupt()); + + return aa_sk_perm(op, request, sock->sk); +} + +/** + * apparmor_socket_getsockname - check perms before getting the local address + */ +static int apparmor_socket_getsockname(struct socket *sock) +{ + return aa_sock_perm(OP_GETSOCKNAME, AA_MAY_GETATTR, sock); +} + +/** + * apparmor_socket_getpeername - check perms before getting remote address + */ +static int apparmor_socket_getpeername(struct socket *sock) +{ + return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock); +} + +/* revaliation, get/set attr, opt */ +static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, + int level, int optname) +{ + AA_BUG(!sock); + AA_BUG(!sock->sk); + AA_BUG(in_interrupt()); + + return aa_sk_perm(op, request, sock->sk); +} + +/** + * apparmor_getsockopt - check perms before getting socket options + */ +static int apparmor_socket_getsockopt(struct socket *sock, int level, + int optname) +{ + return aa_sock_opt_perm(OP_GETSOCKOPT, AA_MAY_GETOPT, sock, + level, optname); +} + +/** + * apparmor_setsockopt - check perms before setting socket options + */ +static int apparmor_socket_setsockopt(struct socket *sock, int level, + int optname) +{ + return aa_sock_opt_perm(OP_SETSOCKOPT, AA_MAY_SETOPT, sock, + level, optname); +} + +/** + * apparmor_socket_shutdown - check perms before shutting down @sock conn + */ +static int apparmor_socket_shutdown(struct socket *sock, int how) +{ + return aa_sock_perm(OP_SHUTDOWN, AA_MAY_SHUTDOWN, sock); +} + +/** + * apparmor_socket_sock_recv_skb - check perms before associating skb to sk + * + * Note: can not sleep may be called with locks held + * + * dont want protocol specific in __skb_recv_datagram() + * to deny an incoming connection socket_sock_rcv_skb() + */ +static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + return 0; +} + + +static struct aa_label *sk_peer_label(struct sock *sk) +{ + struct aa_sk_ctx *ctx = SK_CTX(sk); + + if (ctx->peer) + return ctx->peer; + + return ERR_PTR(-ENOPROTOOPT); +} + +/** + * apparmor_socket_getpeersec_stream - get security context of peer + * + * Note: for tcp only valid if using ipsec or cipso on lan + */ +static int apparmor_socket_getpeersec_stream(struct socket *sock, + char __user *optval, + int __user *optlen, + unsigned int len) +{ + char *name; + int slen, error = 0; + struct aa_label *label; + struct aa_label *peer; + + label = begin_current_label_crit_section(); + peer = sk_peer_label(sock->sk); + if (IS_ERR(peer)) { + error = PTR_ERR(peer); + goto done; + } + slen = aa_label_asxprint(&name, labels_ns(label), peer, + FLAG_SHOW_MODE | FLAG_VIEW_SUBNS | + FLAG_HIDDEN_UNCONFINED, GFP_KERNEL); + /* don't include terminating \0 in slen, it breaks some apps */ + if (slen < 0) { + error = -ENOMEM; + } else { + if (slen > len) { + error = -ERANGE; + } else if (copy_to_user(optval, name, slen)) { + error = -EFAULT; + goto out; + } + if (put_user(slen, optlen)) + error = -EFAULT; +out: + kfree(name); + + } + +done: + end_current_label_crit_section(label); + + return error; +} + +/** + * apparmor_socket_getpeersec_dgram - get security label of packet + * @sock: the peer socket + * @skb: packet data + * @secid: pointer to where to put the secid of the packet + * + * Sets the netlabel socket state on sk from parent + */ +static int apparmor_socket_getpeersec_dgram(struct socket *sock, + struct sk_buff *skb, u32 *secid) + +{ + /* TODO: requires secid support */ + return -ENOPROTOOPT; +} + +/** + * apparmor_sock_graft - Initialize newly created socket + * @sk: child sock + * @parent: parent socket + * + * Note: could set off of SOCK_CTX(parent) but need to track inode and we can + * just set sk security information off of current creating process label + * Labeling of sk for accept case - probably should be sock based + * instead of task, because of the case where an implicitly labeled + * socket is shared by different tasks. + */ +static void apparmor_sock_graft(struct sock *sk, struct socket *parent) +{ + struct aa_sk_ctx *ctx = SK_CTX(sk); + + if (!ctx->label) + ctx->label = aa_get_current_label(); +} + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), LSM_HOOK_INIT(capget, apparmor_capget), LSM_HOOK_INIT(capable, apparmor_capable), + LSM_HOOK_INIT(sb_mount, apparmor_sb_mount), + LSM_HOOK_INIT(sb_umount, apparmor_sb_umount), + LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot), + LSM_HOOK_INIT(path_link, apparmor_path_link), LSM_HOOK_INIT(path_unlink, apparmor_path_unlink), LSM_HOOK_INIT(path_symlink, apparmor_path_symlink), @@ -686,6 +1133,30 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), + LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security), + LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security), + LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security), + + LSM_HOOK_INIT(socket_create, apparmor_socket_create), + LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create), + LSM_HOOK_INIT(socket_bind, apparmor_socket_bind), + LSM_HOOK_INIT(socket_connect, apparmor_socket_connect), + LSM_HOOK_INIT(socket_listen, apparmor_socket_listen), + LSM_HOOK_INIT(socket_accept, apparmor_socket_accept), + LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg), + LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg), + LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname), + LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername), + LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt), + LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt), + LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown), + LSM_HOOK_INIT(socket_sock_rcv_skb, apparmor_socket_sock_rcv_skb), + LSM_HOOK_INIT(socket_getpeersec_stream, + apparmor_socket_getpeersec_stream), + LSM_HOOK_INIT(socket_getpeersec_dgram, + apparmor_socket_getpeersec_dgram), + LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), + LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), LSM_HOOK_INIT(cred_free, apparmor_cred_free), LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), @@ -694,9 +1165,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds), LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds), - LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec), LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), + LSM_HOOK_INIT(task_kill, apparmor_task_kill), }; /* diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c new file mode 100644 index 0000000000000000000000000000000000000000..82a64b58041d2adc62debcf572b77b7a6607678d --- /dev/null +++ b/security/apparmor/mount.c @@ -0,0 +1,696 @@ +/* + * AppArmor security module + * + * This file contains AppArmor mediation of files + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009-2017 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#include +#include +#include + +#include "include/apparmor.h" +#include "include/audit.h" +#include "include/context.h" +#include "include/domain.h" +#include "include/file.h" +#include "include/match.h" +#include "include/mount.h" +#include "include/path.h" +#include "include/policy.h" + + +static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags) +{ + if (flags & MS_RDONLY) + audit_log_format(ab, "ro"); + else + audit_log_format(ab, "rw"); + if (flags & MS_NOSUID) + audit_log_format(ab, ", nosuid"); + if (flags & MS_NODEV) + audit_log_format(ab, ", nodev"); + if (flags & MS_NOEXEC) + audit_log_format(ab, ", noexec"); + if (flags & MS_SYNCHRONOUS) + audit_log_format(ab, ", sync"); + if (flags & MS_REMOUNT) + audit_log_format(ab, ", remount"); + if (flags & MS_MANDLOCK) + audit_log_format(ab, ", mand"); + if (flags & MS_DIRSYNC) + audit_log_format(ab, ", dirsync"); + if (flags & MS_NOATIME) + audit_log_format(ab, ", noatime"); + if (flags & MS_NODIRATIME) + audit_log_format(ab, ", nodiratime"); + if (flags & MS_BIND) + audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind"); + if (flags & MS_MOVE) + audit_log_format(ab, ", move"); + if (flags & MS_SILENT) + audit_log_format(ab, ", silent"); + if (flags & MS_POSIXACL) + audit_log_format(ab, ", acl"); + if (flags & MS_UNBINDABLE) + audit_log_format(ab, flags & MS_REC ? ", runbindable" : + ", unbindable"); + if (flags & MS_PRIVATE) + audit_log_format(ab, flags & MS_REC ? ", rprivate" : + ", private"); + if (flags & MS_SLAVE) + audit_log_format(ab, flags & MS_REC ? ", rslave" : + ", slave"); + if (flags & MS_SHARED) + audit_log_format(ab, flags & MS_REC ? ", rshared" : + ", shared"); + if (flags & MS_RELATIME) + audit_log_format(ab, ", relatime"); + if (flags & MS_I_VERSION) + audit_log_format(ab, ", iversion"); + if (flags & MS_STRICTATIME) + audit_log_format(ab, ", strictatime"); + if (flags & MS_NOUSER) + audit_log_format(ab, ", nouser"); +} + +/** + * audit_cb - call back for mount specific audit fields + * @ab: audit_buffer (NOT NULL) + * @va: audit struct to audit values of (NOT NULL) + */ +static void audit_cb(struct audit_buffer *ab, void *va) +{ + struct common_audit_data *sa = va; + + if (aad(sa)->mnt.type) { + audit_log_format(ab, " fstype="); + audit_log_untrustedstring(ab, aad(sa)->mnt.type); + } + if (aad(sa)->mnt.src_name) { + audit_log_format(ab, " srcname="); + audit_log_untrustedstring(ab, aad(sa)->mnt.src_name); + } + if (aad(sa)->mnt.trans) { + audit_log_format(ab, " trans="); + audit_log_untrustedstring(ab, aad(sa)->mnt.trans); + } + if (aad(sa)->mnt.flags) { + audit_log_format(ab, " flags=\""); + audit_mnt_flags(ab, aad(sa)->mnt.flags); + audit_log_format(ab, "\""); + } + if (aad(sa)->mnt.data) { + audit_log_format(ab, " options="); + audit_log_untrustedstring(ab, aad(sa)->mnt.data); + } +} + +/** + * audit_mount - handle the auditing of mount operations + * @profile: the profile being enforced (NOT NULL) + * @op: operation being mediated (NOT NULL) + * @name: name of object being mediated (MAYBE NULL) + * @src_name: src_name of object being mediated (MAYBE_NULL) + * @type: type of filesystem (MAYBE_NULL) + * @trans: name of trans (MAYBE NULL) + * @flags: filesystem idependent mount flags + * @data: filesystem mount flags + * @request: permissions requested + * @perms: the permissions computed for the request (NOT NULL) + * @info: extra information message (MAYBE NULL) + * @error: 0 if operation allowed else failure error code + * + * Returns: %0 or error on failure + */ +static int audit_mount(struct aa_profile *profile, const char *op, + const char *name, const char *src_name, + const char *type, const char *trans, + unsigned long flags, const void *data, u32 request, + struct aa_perms *perms, const char *info, int error) +{ + int audit_type = AUDIT_APPARMOR_AUTO; + DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op); + + if (likely(!error)) { + u32 mask = perms->audit; + + if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) + mask = 0xffff; + + /* mask off perms that are not being force audited */ + request &= mask; + + if (likely(!request)) + return 0; + audit_type = AUDIT_APPARMOR_AUDIT; + } else { + /* only report permissions that were denied */ + request = request & ~perms->allow; + + if (request & perms->kill) + audit_type = AUDIT_APPARMOR_KILL; + + /* quiet known rejects, assumes quiet and kill do not overlap */ + if ((request & perms->quiet) && + AUDIT_MODE(profile) != AUDIT_NOQUIET && + AUDIT_MODE(profile) != AUDIT_ALL) + request &= ~perms->quiet; + + if (!request) + return error; + } + + aad(&sa)->name = name; + aad(&sa)->mnt.src_name = src_name; + aad(&sa)->mnt.type = type; + aad(&sa)->mnt.trans = trans; + aad(&sa)->mnt.flags = flags; + if (data && (perms->audit & AA_AUDIT_DATA)) + aad(&sa)->mnt.data = data; + aad(&sa)->info = info; + aad(&sa)->error = error; + + return aa_audit(audit_type, profile, &sa, audit_cb); +} + +/** + * match_mnt_flags - Do an ordered match on mount flags + * @dfa: dfa to match against + * @state: state to start in + * @flags: mount flags to match against + * + * Mount flags are encoded as an ordered match. This is done instead of + * checking against a simple bitmask, to allow for logical operations + * on the flags. + * + * Returns: next state after flags match + */ +static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state, + unsigned long flags) +{ + unsigned int i; + + for (i = 0; i <= 31 ; ++i) { + if ((1 << i) & flags) + state = aa_dfa_next(dfa, state, i + 1); + } + + return state; +} + +/** + * compute_mnt_perms - compute mount permission associated with @state + * @dfa: dfa to match against (NOT NULL) + * @state: state match finished in + * + * Returns: mount permissions + */ +static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa, + unsigned int state) +{ + struct aa_perms perms; + + perms.kill = 0; + perms.allow = dfa_user_allow(dfa, state); + perms.audit = dfa_user_audit(dfa, state); + perms.quiet = dfa_user_quiet(dfa, state); + perms.xindex = dfa_user_xindex(dfa, state); + + return perms; +} + +static const char * const mnt_info_table[] = { + "match succeeded", + "failed mntpnt match", + "failed srcname match", + "failed type match", + "failed flags match", + "failed data match" +}; + +/* + * Returns 0 on success else element that match failed in, this is the + * index into the mnt_info_table above + */ +static int do_match_mnt(struct aa_dfa *dfa, unsigned int start, + const char *mntpnt, const char *devname, + const char *type, unsigned long flags, + void *data, bool binary, struct aa_perms *perms) +{ + unsigned int state; + + AA_BUG(!dfa); + AA_BUG(!perms); + + state = aa_dfa_match(dfa, start, mntpnt); + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 1; + + if (devname) + state = aa_dfa_match(dfa, state, devname); + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 2; + + if (type) + state = aa_dfa_match(dfa, state, type); + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 3; + + state = match_mnt_flags(dfa, state, flags); + if (!state) + return 4; + *perms = compute_mnt_perms(dfa, state); + if (perms->allow & AA_MAY_MOUNT) + return 0; + + /* only match data if not binary and the DFA flags data is expected */ + if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) { + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 4; + + state = aa_dfa_match(dfa, state, data); + if (!state) + return 5; + *perms = compute_mnt_perms(dfa, state); + if (perms->allow & AA_MAY_MOUNT) + return 0; + } + + /* failed at end of flags match */ + return 4; +} + + +static int path_flags(struct aa_profile *profile, const struct path *path) +{ + AA_BUG(!profile); + AA_BUG(!path); + + return profile->path_flags | + (S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0); +} + +/** + * match_mnt_path_str - handle path matching for mount + * @profile: the confining profile + * @mntpath: for the mntpnt (NOT NULL) + * @buffer: buffer to be used to lookup mntpath + * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR) + * @type: string for the dev type (MAYBE NULL) + * @flags: mount flags to match + * @data: fs mount data (MAYBE NULL) + * @binary: whether @data is binary + * @devinfo: error str if (IS_ERR(@devname)) + * + * Returns: 0 on success else error + */ +static int match_mnt_path_str(struct aa_profile *profile, + const struct path *mntpath, char *buffer, + const char *devname, const char *type, + unsigned long flags, void *data, bool binary, + const char *devinfo) +{ + struct aa_perms perms = { }; + const char *mntpnt = NULL, *info = NULL; + int pos, error; + + AA_BUG(!profile); + AA_BUG(!mntpath); + AA_BUG(!buffer); + + error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer, + &mntpnt, &info, profile->disconnected); + if (error) + goto audit; + if (IS_ERR(devname)) { + error = PTR_ERR(devname); + devname = NULL; + info = devinfo; + goto audit; + } + + error = -EACCES; + pos = do_match_mnt(profile->policy.dfa, + profile->policy.start[AA_CLASS_MOUNT], + mntpnt, devname, type, flags, data, binary, &perms); + if (pos) { + info = mnt_info_table[pos]; + goto audit; + } + error = 0; + +audit: + return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL, + flags, data, AA_MAY_MOUNT, &perms, info, error); +} + +/** + * match_mnt - handle path matching for mount + * @profile: the confining profile + * @mntpath: for the mntpnt (NOT NULL) + * @buffer: buffer to be used to lookup mntpath + * @devpath: path devname/src_name (MAYBE NULL) + * @devbuffer: buffer to be used to lookup devname/src_name + * @type: string for the dev type (MAYBE NULL) + * @flags: mount flags to match + * @data: fs mount data (MAYBE NULL) + * @binary: whether @data is binary + * + * Returns: 0 on success else error + */ +static int match_mnt(struct aa_profile *profile, const struct path *path, + char *buffer, struct path *devpath, char *devbuffer, + const char *type, unsigned long flags, void *data, + bool binary) +{ + const char *devname = NULL, *info = NULL; + int error = -EACCES; + + AA_BUG(!profile); + AA_BUG(devpath && !devbuffer); + + if (devpath) { + error = aa_path_name(devpath, path_flags(profile, devpath), + devbuffer, &devname, &info, + profile->disconnected); + if (error) + devname = ERR_PTR(error); + } + + return match_mnt_path_str(profile, path, buffer, devname, type, flags, + data, binary, info); +} + +int aa_remount(struct aa_label *label, const struct path *path, + unsigned long flags, void *data) +{ + struct aa_profile *profile; + char *buffer = NULL; + bool binary; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA; + + get_buffers(buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, NULL, NULL, NULL, + flags, data, binary)); + put_buffers(buffer); + + return error; +} + +int aa_bind_mount(struct aa_label *label, const struct path *path, + const char *dev_name, unsigned long flags) +{ + struct aa_profile *profile; + char *buffer = NULL, *old_buffer = NULL; + struct path old_path; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + if (!dev_name || !*dev_name) + return -EINVAL; + + flags &= MS_REC | MS_BIND; + + error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path); + if (error) + return error; + + get_buffers(buffer, old_buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, &old_path, old_buffer, + NULL, flags, NULL, false)); + put_buffers(buffer, old_buffer); + path_put(&old_path); + + return error; +} + +int aa_mount_change_type(struct aa_label *label, const struct path *path, + unsigned long flags) +{ + struct aa_profile *profile; + char *buffer = NULL; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + /* These are the flags allowed by do_change_type() */ + flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE | + MS_UNBINDABLE); + + get_buffers(buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, NULL, NULL, NULL, + flags, NULL, false)); + put_buffers(buffer); + + return error; +} + +int aa_move_mount(struct aa_label *label, const struct path *path, + const char *orig_name) +{ + struct aa_profile *profile; + char *buffer = NULL, *old_buffer = NULL; + struct path old_path; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + if (!orig_name || !*orig_name) + return -EINVAL; + + error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path); + if (error) + return error; + + get_buffers(buffer, old_buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, &old_path, old_buffer, + NULL, MS_MOVE, NULL, false)); + put_buffers(buffer, old_buffer); + path_put(&old_path); + + return error; +} + +int aa_new_mount(struct aa_label *label, const char *dev_name, + const struct path *path, const char *type, unsigned long flags, + void *data) +{ + struct aa_profile *profile; + char *buffer = NULL, *dev_buffer = NULL; + bool binary = true; + int error; + int requires_dev = 0; + struct path tmp_path, *dev_path = NULL; + + AA_BUG(!label); + AA_BUG(!path); + + if (type) { + struct file_system_type *fstype; + + fstype = get_fs_type(type); + if (!fstype) + return -ENODEV; + binary = fstype->fs_flags & FS_BINARY_MOUNTDATA; + requires_dev = fstype->fs_flags & FS_REQUIRES_DEV; + put_filesystem(fstype); + + if (requires_dev) { + if (!dev_name || !*dev_name) + return -ENOENT; + + error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path); + if (error) + return error; + dev_path = &tmp_path; + } + } + + get_buffers(buffer, dev_buffer); + if (dev_path) { + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, dev_path, dev_buffer, + type, flags, data, binary)); + } else { + error = fn_for_each_confined(label, profile, + match_mnt_path_str(profile, path, buffer, dev_name, + type, flags, data, binary, NULL)); + } + put_buffers(buffer, dev_buffer); + if (dev_path) + path_put(dev_path); + + return error; +} + +static int profile_umount(struct aa_profile *profile, struct path *path, + char *buffer) +{ + struct aa_perms perms = { }; + const char *name = NULL, *info = NULL; + unsigned int state; + int error; + + AA_BUG(!profile); + AA_BUG(!path); + + error = aa_path_name(path, path_flags(profile, path), buffer, &name, + &info, profile->disconnected); + if (error) + goto audit; + + state = aa_dfa_match(profile->policy.dfa, + profile->policy.start[AA_CLASS_MOUNT], + name); + perms = compute_mnt_perms(profile->policy.dfa, state); + if (AA_MAY_UMOUNT & ~perms.allow) + error = -EACCES; + +audit: + return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL, + AA_MAY_UMOUNT, &perms, info, error); +} + +int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags) +{ + struct aa_profile *profile; + char *buffer = NULL; + int error; + struct path path = { .mnt = mnt, .dentry = mnt->mnt_root }; + + AA_BUG(!label); + AA_BUG(!mnt); + + get_buffers(buffer); + error = fn_for_each_confined(label, profile, + profile_umount(profile, &path, buffer)); + put_buffers(buffer); + + return error; +} + +/* helper fn for transition on pivotroot + * + * Returns: label for transition or ERR_PTR. Does not return NULL + */ +static struct aa_label *build_pivotroot(struct aa_profile *profile, + const struct path *new_path, + char *new_buffer, + const struct path *old_path, + char *old_buffer) +{ + const char *old_name, *new_name = NULL, *info = NULL; + const char *trans_name = NULL; + struct aa_perms perms = { }; + unsigned int state; + int error; + + AA_BUG(!profile); + AA_BUG(!new_path); + AA_BUG(!old_path); + + if (profile_unconfined(profile)) + return aa_get_newest_label(&profile->label); + + error = aa_path_name(old_path, path_flags(profile, old_path), + old_buffer, &old_name, &info, + profile->disconnected); + if (error) + goto audit; + error = aa_path_name(new_path, path_flags(profile, new_path), + new_buffer, &new_name, &info, + profile->disconnected); + if (error) + goto audit; + + error = -EACCES; + state = aa_dfa_match(profile->policy.dfa, + profile->policy.start[AA_CLASS_MOUNT], + new_name); + state = aa_dfa_null_transition(profile->policy.dfa, state); + state = aa_dfa_match(profile->policy.dfa, state, old_name); + perms = compute_mnt_perms(profile->policy.dfa, state); + + if (AA_MAY_PIVOTROOT & perms.allow) + error = 0; + +audit: + error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name, + NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT, + &perms, info, error); + if (error) + return ERR_PTR(error); + + return aa_get_newest_label(&profile->label); +} + +int aa_pivotroot(struct aa_label *label, const struct path *old_path, + const struct path *new_path) +{ + struct aa_profile *profile; + struct aa_label *target = NULL; + char *old_buffer = NULL, *new_buffer = NULL, *info = NULL; + int error; + + AA_BUG(!label); + AA_BUG(!old_path); + AA_BUG(!new_path); + + get_buffers(old_buffer, new_buffer); + target = fn_label_build(label, profile, GFP_ATOMIC, + build_pivotroot(profile, new_path, new_buffer, + old_path, old_buffer)); + if (!target) { + info = "label build failed"; + error = -ENOMEM; + goto fail; + } else if (!IS_ERR(target)) { + error = aa_replace_current_label(target); + if (error) { + /* TODO: audit target */ + aa_put_label(target); + goto out; + } + } else + /* already audited error */ + error = PTR_ERR(target); +out: + put_buffers(old_buffer, new_buffer); + + return error; + +fail: + /* TODO: add back in auditing of new_name and old_name */ + error = fn_for_each(label, profile, + audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */, + NULL /* old_name */, + NULL, NULL, + 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info, + error)); + goto out; +} diff --git a/security/apparmor/net.c b/security/apparmor/net.c new file mode 100644 index 0000000000000000000000000000000000000000..33d54435f8d6296f6f34b5555b0b7f6b748833c2 --- /dev/null +++ b/security/apparmor/net.c @@ -0,0 +1,184 @@ +/* + * AppArmor security module + * + * This file contains AppArmor network mediation + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009-2017 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#include "include/apparmor.h" +#include "include/audit.h" +#include "include/context.h" +#include "include/label.h" +#include "include/net.h" +#include "include/policy.h" + +#include "net_names.h" + + +struct aa_sfs_entry aa_sfs_entry_network[] = { + AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK), + { } +}; + +static const char * const net_mask_names[] = { + "unknown", + "send", + "receive", + "unknown", + + "create", + "shutdown", + "connect", + "unknown", + + "setattr", + "getattr", + "setcred", + "getcred", + + "chmod", + "chown", + "chgrp", + "lock", + + "mmap", + "mprot", + "unknown", + "unknown", + + "accept", + "bind", + "listen", + "unknown", + + "setopt", + "getopt", + "unknown", + "unknown", + + "unknown", + "unknown", + "unknown", + "unknown", +}; + + +/* audit callback for net specific fields */ +void audit_net_cb(struct audit_buffer *ab, void *va) +{ + struct common_audit_data *sa = va; + + audit_log_format(ab, " family="); + if (address_family_names[sa->u.net->family]) + audit_log_string(ab, address_family_names[sa->u.net->family]); + else + audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family); + audit_log_format(ab, " sock_type="); + if (sock_type_names[aad(sa)->net.type]) + audit_log_string(ab, sock_type_names[aad(sa)->net.type]); + else + audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type); + audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); + + if (aad(sa)->request & NET_PERMS_MASK) { + audit_log_format(ab, " requested_mask="); + aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, + net_mask_names, NET_PERMS_MASK); + + if (aad(sa)->denied & NET_PERMS_MASK) { + audit_log_format(ab, " denied_mask="); + aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, + net_mask_names, NET_PERMS_MASK); + } + } + if (aad(sa)->peer) { + audit_log_format(ab, " peer="); + aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, + FLAGS_NONE, GFP_ATOMIC); + } +} + + +/* Generic af perm */ +int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, + u32 request, u16 family, int type) +{ + struct aa_perms perms = { }; + + AA_BUG(family >= AF_MAX); + AA_BUG(type < 0 || type >= SOCK_MAX); + + if (profile_unconfined(profile)) + return 0; + + perms.allow = (profile->net.allow[family] & (1 << type)) ? + ALL_PERMS_MASK : 0; + perms.audit = (profile->net.audit[family] & (1 << type)) ? + ALL_PERMS_MASK : 0; + perms.quiet = (profile->net.quiet[family] & (1 << type)) ? + ALL_PERMS_MASK : 0; + aa_apply_modes_to_perms(profile, &perms); + + return aa_check_perms(profile, &perms, request, sa, audit_net_cb); +} + +int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, + int type, int protocol) +{ + struct aa_profile *profile; + DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); + + return fn_for_each_confined(label, profile, + aa_profile_af_perm(profile, &sa, request, family, + type)); +} + +static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, + struct sock *sk) +{ + struct aa_profile *profile; + DEFINE_AUDIT_SK(sa, op, sk); + + AA_BUG(!label); + AA_BUG(!sk); + + if (unconfined(label)) + return 0; + + return fn_for_each_confined(label, profile, + aa_profile_af_sk_perm(profile, &sa, request, sk)); +} + +int aa_sk_perm(const char *op, u32 request, struct sock *sk) +{ + struct aa_label *label; + int error; + + AA_BUG(!sk); + AA_BUG(in_interrupt()); + + /* TODO: switch to begin_current_label ???? */ + label = begin_current_label_crit_section(); + error = aa_label_sk_perm(label, op, request, sk); + end_current_label_crit_section(label); + + return error; +} + + +int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, + struct socket *sock) +{ + AA_BUG(!label); + AA_BUG(!sock); + AA_BUG(!sock->sk); + + return aa_label_sk_perm(label, op, request, sock->sk); +} diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 244ea4a4a8f0f73fdfacccd8c49cd55e1f7c695e..4243b0c3f0e4acc6d66c70ea878f32d548bebdd4 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -289,85 +289,6 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy, return NULL; } -/** - * aa_new_null_profile - create or find a null-X learning profile - * @parent: profile that caused this profile to be created (NOT NULL) - * @hat: true if the null- learning profile is a hat - * @base: name to base the null profile off of - * @gfp: type of allocation - * - * Find/Create a null- complain mode profile used in learning mode. The - * name of the profile is unique and follows the format of parent//null-XXX. - * where XXX is based on the @name or if that fails or is not supplied - * a unique number - * - * null profiles are added to the profile list but the list does not - * hold a count on them so that they are automatically released when - * not in use. - * - * Returns: new refcounted profile else NULL on failure - */ -struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, - const char *base, gfp_t gfp) -{ - struct aa_profile *profile; - char *name; - - AA_BUG(!parent); - - if (base) { - name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base), - gfp); - if (name) { - sprintf(name, "%s//null-%s", parent->base.hname, base); - goto name; - } - /* fall through to try shorter uniq */ - } - - name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp); - if (!name) - return NULL; - sprintf(name, "%s//null-%x", parent->base.hname, - atomic_inc_return(&parent->ns->uniq_null)); - -name: - /* lookup to see if this is a dup creation */ - profile = aa_find_child(parent, basename(name)); - if (profile) - goto out; - - profile = aa_alloc_profile(name, NULL, gfp); - if (!profile) - goto fail; - - profile->mode = APPARMOR_COMPLAIN; - profile->label.flags |= FLAG_NULL; - if (hat) - profile->label.flags |= FLAG_HAT; - profile->path_flags = parent->path_flags; - - /* released on free_profile */ - rcu_assign_pointer(profile->parent, aa_get_profile(parent)); - profile->ns = aa_get_ns(parent->ns); - profile->file.dfa = aa_get_dfa(nulldfa); - profile->policy.dfa = aa_get_dfa(nulldfa); - - mutex_lock(&profile->ns->lock); - __add_profile(&parent->base.profiles, profile); - mutex_unlock(&profile->ns->lock); - - /* refcount released by caller */ -out: - kfree(name); - - return profile; - -fail: - aa_free_profile(profile); - return NULL; -} - /* TODO: profile accounting - setup in remove */ /** @@ -558,6 +479,93 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base, return profile; } +/** + * aa_new_null_profile - create or find a null-X learning profile + * @parent: profile that caused this profile to be created (NOT NULL) + * @hat: true if the null- learning profile is a hat + * @base: name to base the null profile off of + * @gfp: type of allocation + * + * Find/Create a null- complain mode profile used in learning mode. The + * name of the profile is unique and follows the format of parent//null-XXX. + * where XXX is based on the @name or if that fails or is not supplied + * a unique number + * + * null profiles are added to the profile list but the list does not + * hold a count on them so that they are automatically released when + * not in use. + * + * Returns: new refcounted profile else NULL on failure + */ +struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, + const char *base, gfp_t gfp) +{ + struct aa_profile *p, *profile; + const char *bname; + char *name; + + AA_BUG(!parent); + + if (base) { + name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base), + gfp); + if (name) { + sprintf(name, "%s//null-%s", parent->base.hname, base); + goto name; + } + /* fall through to try shorter uniq */ + } + + name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp); + if (!name) + return NULL; + sprintf(name, "%s//null-%x", parent->base.hname, + atomic_inc_return(&parent->ns->uniq_null)); + +name: + /* lookup to see if this is a dup creation */ + bname = basename(name); + profile = aa_find_child(parent, bname); + if (profile) + goto out; + + profile = aa_alloc_profile(name, NULL, gfp); + if (!profile) + goto fail; + + profile->mode = APPARMOR_COMPLAIN; + profile->label.flags |= FLAG_NULL; + if (hat) + profile->label.flags |= FLAG_HAT; + profile->path_flags = parent->path_flags; + + /* released on free_profile */ + rcu_assign_pointer(profile->parent, aa_get_profile(parent)); + profile->ns = aa_get_ns(parent->ns); + profile->file.dfa = aa_get_dfa(nulldfa); + profile->policy.dfa = aa_get_dfa(nulldfa); + + mutex_lock(&profile->ns->lock); + p = __find_child(&parent->base.profiles, bname); + if (p) { + aa_free_profile(profile); + profile = aa_get_profile(p); + } else { + __add_profile(&parent->base.profiles, profile); + } + mutex_unlock(&profile->ns->lock); + + /* refcount released by caller */ +out: + kfree(name); + + return profile; + +fail: + aa_free_profile(profile); + return NULL; +} + /** * replacement_allowed - test to see if replacement is allowed * @profile: profile to test if it can be replaced (MAYBE NULL) diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c index 351d3bab3a3d2565aa970fe7011453c8fb721ea4..62a3589c62ab624156c0c01eaa8cadd72276866a 100644 --- a/security/apparmor/policy_ns.c +++ b/security/apparmor/policy_ns.c @@ -112,6 +112,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name) ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR | FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED; ns->unconfined->mode = APPARMOR_UNCONFINED; + ns->unconfined->file.dfa = aa_get_dfa(nulldfa); + ns->unconfined->policy.dfa = aa_get_dfa(nulldfa); /* ns and ns->unconfined share ns->unconfined refcount */ ns->unconfined->ns = ns; diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index c600f4dd1783252a1fc429379cb1cca8b9728c9b..5a2aec358322a930a5e6473a9e22acd64462298b 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va) audit_log_format(ab, " ns="); audit_log_untrustedstring(ab, aad(sa)->iface.ns); } - if (aad(sa)->iface.name) { + if (aad(sa)->name) { audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, aad(sa)->iface.name); + audit_log_untrustedstring(ab, aad(sa)->name); } if (aad(sa)->iface.pos) audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); @@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name, aad(&sa)->iface.pos = e->pos - e->start; aad(&sa)->iface.ns = ns_name; if (new) - aad(&sa)->iface.name = new->base.hname; + aad(&sa)->name = new->base.hname; else - aad(&sa)->iface.name = name; + aad(&sa)->name = name; aad(&sa)->info = info; aad(&sa)->error = error; @@ -275,6 +275,19 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) return 0; } +static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name) +{ + if (unpack_nameX(e, AA_U16, name)) { + if (!inbounds(e, sizeof(u16))) + return 0; + if (data) + *data = le16_to_cpu(get_unaligned((__le16 *) e->pos)); + e->pos += sizeof(u16); + return 1; + } + return 0; +} + static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) { if (unpack_nameX(e, AA_U32, name)) { @@ -448,7 +461,7 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e) */ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) { - void *pos = e->pos; + void *saved_pos = e->pos; /* exec table is optional */ if (unpack_nameX(e, AA_STRUCT, "xtable")) { @@ -511,7 +524,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) fail: aa_free_domain_entries(&profile->file.trans); - e->pos = pos; + e->pos = saved_pos; return 0; } @@ -583,7 +596,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) { struct aa_profile *profile = NULL; const char *tmpname, *tmpns = NULL, *name = NULL; - size_t ns_len; + const char *info = "failed to unpack profile"; + size_t size = 0, ns_len; struct rhashtable_params params = { 0 }; char *key = NULL; struct aa_data *data; @@ -604,8 +618,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); if (tmpns) { *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); - if (!*ns_name) + if (!*ns_name) { + info = "out of memory"; goto fail; + } name = tmpname; } @@ -624,12 +640,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) if (IS_ERR(profile->xmatch)) { error = PTR_ERR(profile->xmatch); profile->xmatch = NULL; + info = "bad xmatch"; goto fail; } /* xmatch_len is not optional if xmatch is set */ if (profile->xmatch) { - if (!unpack_u32(e, &tmp, NULL)) + if (!unpack_u32(e, &tmp, NULL)) { + info = "missing xmatch len"; goto fail; + } profile->xmatch_len = tmp; } @@ -637,8 +656,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) (void) unpack_str(e, &profile->disconnected, "disconnected"); /* per profile debug flags (complain, audit) */ - if (!unpack_nameX(e, AA_STRUCT, "flags")) + if (!unpack_nameX(e, AA_STRUCT, "flags")) { + info = "profile missing flags"; goto fail; + } + info = "failed to unpack profile flags"; if (!unpack_u32(e, &tmp, NULL)) goto fail; if (tmp & PACKED_FLAG_HAT) @@ -667,6 +689,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) /* set a default value if path_flags field is not present */ profile->path_flags = PATH_MEDIATE_DELETED; + info = "failed to unpack profile capabilities"; if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) goto fail; if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) @@ -676,6 +699,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) if (!unpack_u32(e, &tmpcap.cap[0], NULL)) goto fail; + info = "failed to unpack upper profile capabilities"; if (unpack_nameX(e, AA_STRUCT, "caps64")) { /* optional upper half of 64 bit caps */ if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) @@ -690,6 +714,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } + info = "failed to unpack extended profile capabilities"; if (unpack_nameX(e, AA_STRUCT, "capsx")) { /* optional extended caps mediation mask */ if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) @@ -700,11 +725,46 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } - if (!unpack_rlimits(e, profile)) + if (!unpack_rlimits(e, profile)) { + info = "failed to unpack profile rlimits"; goto fail; + } + + size = unpack_array(e, "net_allowed_af"); + if (size) { + + for (i = 0; i < size; i++) { + /* discard extraneous rules that this kernel will + * never request + */ + if (i >= AF_MAX) { + u16 tmp; + + if (!unpack_u16(e, &tmp, NULL) || + !unpack_u16(e, &tmp, NULL) || + !unpack_u16(e, &tmp, NULL)) + goto fail; + continue; + } + if (!unpack_u16(e, &profile->net.allow[i], NULL)) + goto fail; + if (!unpack_u16(e, &profile->net.audit[i], NULL)) + goto fail; + if (!unpack_u16(e, &profile->net.quiet[i], NULL)) + goto fail; + } + if (!unpack_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + } + if (VERSION_LT(e->version, v7)) { + /* pre v7 policy always allowed these */ + profile->net.allow[AF_UNIX] = 0xffff; + profile->net.allow[AF_NETLINK] = 0xffff; + } if (unpack_nameX(e, AA_STRUCT, "policydb")) { /* generic policy dfa - optional and may be NULL */ + info = "failed to unpack policydb"; profile->policy.dfa = unpack_dfa(e); if (IS_ERR(profile->policy.dfa)) { error = PTR_ERR(profile->policy.dfa); @@ -734,6 +794,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) if (IS_ERR(profile->file.dfa)) { error = PTR_ERR(profile->file.dfa); profile->file.dfa = NULL; + info = "failed to unpack profile file rules"; goto fail; } else if (profile->file.dfa) { if (!unpack_u32(e, &profile->file.start, "dfa_start")) @@ -746,10 +807,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) } else profile->file.dfa = aa_get_dfa(nulldfa); - if (!unpack_trans_table(e, profile)) + if (!unpack_trans_table(e, profile)) { + info = "failed to unpack profile transition table"; goto fail; + } if (unpack_nameX(e, AA_STRUCT, "data")) { + info = "out of memory"; profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); if (!profile->data) goto fail; @@ -761,8 +825,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) params.hashfn = strhash; params.obj_cmpfn = datacmp; - if (rhashtable_init(profile->data, ¶ms)) + if (rhashtable_init(profile->data, ¶ms)) { + info = "failed to init key, value hash table"; goto fail; + } while (unpack_strdup(e, &key, NULL)) { data = kzalloc(sizeof(*data), GFP_KERNEL); @@ -784,12 +850,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) profile->data->p); } - if (!unpack_nameX(e, AA_STRUCTEND, NULL)) + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { + info = "failed to unpack end of key, value data table"; goto fail; + } } - if (!unpack_nameX(e, AA_STRUCTEND, NULL)) + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { + info = "failed to unpack end of profile"; goto fail; + } return profile; @@ -798,8 +868,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) name = NULL; else if (!name) name = "unknown"; - audit_iface(profile, NULL, name, "failed to unpack profile", e, - error); + audit_iface(profile, NULL, name, info, e, error); aa_free_profile(profile); return ERR_PTR(error); @@ -832,7 +901,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns) * if not specified use previous version * Mask off everything that is not kernel abi version */ - if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) { + if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) { audit_iface(NULL, NULL, NULL, "unsupported interface version", e, error); return error; diff --git a/security/commoncap.c b/security/commoncap.c index 7abebd782d5e02d0c024ca0b2b1b189b1f4f83d1..c25e0d27537f87ea7d7d216b9448f47b83e26608 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -82,8 +82,11 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, if (ns == cred->user_ns) return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; - /* Have we tried all of the parent namespaces? */ - if (ns == &init_user_ns) + /* + * If we're already at a lower level than we're looking for, + * we're done searching. + */ + if (ns->level <= cred->user_ns->level) return -EPERM; /* @@ -285,25 +288,16 @@ int cap_capset(struct cred *new, return 0; } -/* - * Clear proposed capability sets for execve(). - */ -static inline void bprm_clear_caps(struct linux_binprm *bprm) -{ - cap_clear(bprm->cred->cap_permitted); - bprm->cap_effective = false; -} - /** * cap_inode_need_killpriv - Determine if inode change affects privileges * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV * * Determine if an inode having a change applied that's marked ATTR_KILL_PRIV * affects the security markings on that inode, and if it is, should - * inode_killpriv() be invoked or the change rejected? + * inode_killpriv() be invoked or the change rejected. * - * Returns 0 if granted; +ve if granted, but inode_killpriv() is required; and - * -ve to deny the change. + * Returns 1 if security.capability has a value, meaning inode_killpriv() + * is required, 0 otherwise, meaning inode_killpriv() is not required. */ int cap_inode_need_killpriv(struct dentry *dentry) { @@ -332,6 +326,209 @@ int cap_inode_killpriv(struct dentry *dentry) return error; } +static bool rootid_owns_currentns(kuid_t kroot) +{ + struct user_namespace *ns; + + if (!uid_valid(kroot)) + return false; + + for (ns = current_user_ns(); ; ns = ns->parent) { + if (from_kuid(ns, kroot) == 0) + return true; + if (ns == &init_user_ns) + break; + } + + return false; +} + +static __u32 sansflags(__u32 m) +{ + return m & ~VFS_CAP_FLAGS_EFFECTIVE; +} + +static bool is_v2header(size_t size, __le32 magic) +{ + __u32 m = le32_to_cpu(magic); + if (size != XATTR_CAPS_SZ_2) + return false; + return sansflags(m) == VFS_CAP_REVISION_2; +} + +static bool is_v3header(size_t size, __le32 magic) +{ + __u32 m = le32_to_cpu(magic); + + if (size != XATTR_CAPS_SZ_3) + return false; + return sansflags(m) == VFS_CAP_REVISION_3; +} + +/* + * getsecurity: We are called for security.* before any attempt to read the + * xattr from the inode itself. + * + * This gives us a chance to read the on-disk value and convert it. If we + * return -EOPNOTSUPP, then vfs_getxattr() will call the i_op handler. + * + * Note we are not called by vfs_getxattr_alloc(), but that is only called + * by the integrity subsystem, which really wants the unconverted values - + * so that's good. + */ +int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, + bool alloc) +{ + int size, ret; + kuid_t kroot; + uid_t root, mappedroot; + char *tmpbuf = NULL; + struct vfs_cap_data *cap; + struct vfs_ns_cap_data *nscap; + struct dentry *dentry; + struct user_namespace *fs_ns; + + if (strcmp(name, "capability") != 0) + return -EOPNOTSUPP; + + dentry = d_find_alias(inode); + if (!dentry) + return -EINVAL; + + size = sizeof(struct vfs_ns_cap_data); + ret = (int) vfs_getxattr_alloc(dentry, XATTR_NAME_CAPS, + &tmpbuf, size, GFP_NOFS); + dput(dentry); + + if (ret < 0) + return ret; + + fs_ns = inode->i_sb->s_user_ns; + cap = (struct vfs_cap_data *) tmpbuf; + if (is_v2header((size_t) ret, cap->magic_etc)) { + /* If this is sizeof(vfs_cap_data) then we're ok with the + * on-disk value, so return that. */ + if (alloc) + *buffer = tmpbuf; + else + kfree(tmpbuf); + return ret; + } else if (!is_v3header((size_t) ret, cap->magic_etc)) { + kfree(tmpbuf); + return -EINVAL; + } + + nscap = (struct vfs_ns_cap_data *) tmpbuf; + root = le32_to_cpu(nscap->rootid); + kroot = make_kuid(fs_ns, root); + + /* If the root kuid maps to a valid uid in current ns, then return + * this as a nscap. */ + mappedroot = from_kuid(current_user_ns(), kroot); + if (mappedroot != (uid_t)-1 && mappedroot != (uid_t)0) { + if (alloc) { + *buffer = tmpbuf; + nscap->rootid = cpu_to_le32(mappedroot); + } else + kfree(tmpbuf); + return size; + } + + if (!rootid_owns_currentns(kroot)) { + kfree(tmpbuf); + return -EOPNOTSUPP; + } + + /* This comes from a parent namespace. Return as a v2 capability */ + size = sizeof(struct vfs_cap_data); + if (alloc) { + *buffer = kmalloc(size, GFP_ATOMIC); + if (*buffer) { + struct vfs_cap_data *cap = *buffer; + __le32 nsmagic, magic; + magic = VFS_CAP_REVISION_2; + nsmagic = le32_to_cpu(nscap->magic_etc); + if (nsmagic & VFS_CAP_FLAGS_EFFECTIVE) + magic |= VFS_CAP_FLAGS_EFFECTIVE; + memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * VFS_CAP_U32); + cap->magic_etc = cpu_to_le32(magic); + } + } + kfree(tmpbuf); + return size; +} + +static kuid_t rootid_from_xattr(const void *value, size_t size, + struct user_namespace *task_ns) +{ + const struct vfs_ns_cap_data *nscap = value; + uid_t rootid = 0; + + if (size == XATTR_CAPS_SZ_3) + rootid = le32_to_cpu(nscap->rootid); + + return make_kuid(task_ns, rootid); +} + +static bool validheader(size_t size, __le32 magic) +{ + return is_v2header(size, magic) || is_v3header(size, magic); +} + +/* + * User requested a write of security.capability. If needed, update the + * xattr to change from v2 to v3, or to fixup the v3 rootid. + * + * If all is ok, we return the new size, on error return < 0. + */ +int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) +{ + struct vfs_ns_cap_data *nscap; + uid_t nsrootid; + const struct vfs_cap_data *cap = *ivalue; + __u32 magic, nsmagic; + struct inode *inode = d_backing_inode(dentry); + struct user_namespace *task_ns = current_user_ns(), + *fs_ns = inode->i_sb->s_user_ns; + kuid_t rootid; + size_t newsize; + + if (!*ivalue) + return -EINVAL; + if (!validheader(size, cap->magic_etc)) + return -EINVAL; + if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) + return -EPERM; + if (size == XATTR_CAPS_SZ_2) + if (ns_capable(inode->i_sb->s_user_ns, CAP_SETFCAP)) + /* user is privileged, just write the v2 */ + return size; + + rootid = rootid_from_xattr(*ivalue, size, task_ns); + if (!uid_valid(rootid)) + return -EINVAL; + + nsrootid = from_kuid(fs_ns, rootid); + if (nsrootid == -1) + return -EINVAL; + + newsize = sizeof(struct vfs_ns_cap_data); + nscap = kmalloc(newsize, GFP_ATOMIC); + if (!nscap) + return -ENOMEM; + nscap->rootid = cpu_to_le32(nsrootid); + nsmagic = VFS_CAP_REVISION_3; + magic = le32_to_cpu(cap->magic_etc); + if (magic & VFS_CAP_FLAGS_EFFECTIVE) + nsmagic |= VFS_CAP_FLAGS_EFFECTIVE; + nscap->magic_etc = cpu_to_le32(nsmagic); + memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32); + + kvfree(*ivalue); + *ivalue = nscap; + return newsize; +} + /* * Calculate the new process capability sets from the capability sets attached * to a file. @@ -385,7 +582,10 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data __u32 magic_etc; unsigned tocopy, i; int size; - struct vfs_cap_data caps; + struct vfs_ns_cap_data data, *nscaps = &data; + struct vfs_cap_data *caps = (struct vfs_cap_data *) &data; + kuid_t rootkuid; + struct user_namespace *fs_ns = inode->i_sb->s_user_ns; memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data)); @@ -393,18 +593,20 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data return -ENODATA; size = __vfs_getxattr((struct dentry *)dentry, inode, - XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ); + XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ); if (size == -ENODATA || size == -EOPNOTSUPP) /* no data, that's ok */ return -ENODATA; + if (size < 0) return size; if (size < sizeof(magic_etc)) return -EINVAL; - cpu_caps->magic_etc = magic_etc = le32_to_cpu(caps.magic_etc); + cpu_caps->magic_etc = magic_etc = le32_to_cpu(caps->magic_etc); + rootkuid = make_kuid(fs_ns, 0); switch (magic_etc & VFS_CAP_REVISION_MASK) { case VFS_CAP_REVISION_1: if (size != XATTR_CAPS_SZ_1) @@ -416,15 +618,27 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data return -EINVAL; tocopy = VFS_CAP_U32_2; break; + case VFS_CAP_REVISION_3: + if (size != XATTR_CAPS_SZ_3) + return -EINVAL; + tocopy = VFS_CAP_U32_3; + rootkuid = make_kuid(fs_ns, le32_to_cpu(nscaps->rootid)); + break; + default: return -EINVAL; } + /* Limit the caps to the mounter of the filesystem + * or the more limited uid specified in the xattr. + */ + if (!rootid_owns_currentns(rootkuid)) + return -ENODATA; CAP_FOR_EACH_U32(i) { if (i >= tocopy) break; - cpu_caps->permitted.cap[i] = le32_to_cpu(caps.data[i].permitted); - cpu_caps->inheritable.cap[i] = le32_to_cpu(caps.data[i].inheritable); + cpu_caps->permitted.cap[i] = le32_to_cpu(caps->data[i].permitted); + cpu_caps->inheritable.cap[i] = le32_to_cpu(caps->data[i].inheritable); } cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; @@ -443,7 +657,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c int rc = 0; struct cpu_vfs_cap_data vcaps; - bprm_clear_caps(bprm); + cap_clear(bprm->cred->cap_permitted); if (!file_caps_enabled) return 0; @@ -462,8 +676,8 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps); if (rc < 0) { if (rc == -EINVAL) - printk(KERN_NOTICE "%s: get_vfs_caps_from_disk returned %d for %s\n", - __func__, rc, bprm->filename); + printk(KERN_NOTICE "Invalid argument reading file caps for %s\n", + bprm->filename); else if (rc == -ENODATA) rc = 0; goto out; @@ -476,7 +690,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c out: if (rc) - bprm_clear_caps(bprm); + cap_clear(bprm->cred->cap_permitted); return rc; } @@ -585,8 +799,6 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) if (WARN_ON(!cap_ambient_invariant_ok(new))) return -EPERM; - bprm->cap_effective = effective; - /* * Audit candidate if current->cap_effective is set * @@ -614,33 +826,17 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) if (WARN_ON(!cap_ambient_invariant_ok(new))) return -EPERM; - return 0; -} - -/** - * cap_bprm_secureexec - Determine whether a secure execution is required - * @bprm: The execution parameters - * - * Determine whether a secure execution is required, return 1 if it is, and 0 - * if it is not. - * - * The credentials have been committed by this point, and so are no longer - * available through @bprm->cred. - */ -int cap_bprm_secureexec(struct linux_binprm *bprm) -{ - const struct cred *cred = current_cred(); - kuid_t root_uid = make_kuid(cred->user_ns, 0); - - if (!uid_eq(cred->uid, root_uid)) { - if (bprm->cap_effective) - return 1; - if (!cap_issubset(cred->cap_permitted, cred->cap_ambient)) - return 1; + /* Check for privilege-elevated exec. */ + bprm->cap_elevated = 0; + if (is_setid) { + bprm->cap_elevated = 1; + } else if (!uid_eq(new->uid, root_uid)) { + if (effective || + !cap_issubset(new->cap_permitted, new->cap_ambient)) + bprm->cap_elevated = 1; } - return (!uid_eq(cred->euid, cred->uid) || - !gid_eq(cred->egid, cred->gid)); + return 0; } /** @@ -660,15 +856,19 @@ int cap_bprm_secureexec(struct linux_binprm *bprm) int cap_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) - return -EPERM; + /* Ignore non-security xattrs */ + if (strncmp(name, XATTR_SECURITY_PREFIX, + sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) return 0; - } - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) + /* + * For XATTR_NAME_CAPS the check will be done in + * cap_convert_nscap(), called by setxattr() + */ + if (strcmp(name, XATTR_NAME_CAPS) == 0) + return 0; + + if (!capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -686,15 +886,22 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name, */ int cap_inode_removexattr(struct dentry *dentry, const char *name) { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) + /* Ignore non-security xattrs */ + if (strncmp(name, XATTR_SECURITY_PREFIX, + sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) + return 0; + + if (strcmp(name, XATTR_NAME_CAPS) == 0) { + /* security.capability gets namespaced */ + struct inode *inode = d_backing_inode(dentry); + if (!inode) + return -EINVAL; + if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) return -EPERM; return 0; } - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -1079,9 +1286,9 @@ struct security_hook_list capability_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(capget, cap_capget), LSM_HOOK_INIT(capset, cap_capset), LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), - LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec), LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), + LSM_HOOK_INIT(inode_getsecurity, cap_inode_getsecurity), LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), LSM_HOOK_INIT(mmap_file, cap_mmap_file), LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid), diff --git a/security/keys/Kconfig b/security/keys/Kconfig index a7a23b5541f85a4994e0cc83d7d132e8a5681938..91eafada3164ec9dc77074565c156988c4101554 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -45,10 +45,8 @@ config BIG_KEYS bool "Large payload keys" depends on KEYS depends on TMPFS - depends on (CRYPTO_ANSI_CPRNG = y || CRYPTO_DRBG = y) select CRYPTO_AES - select CRYPTO_ECB - select CRYPTO_RNG + select CRYPTO_GCM help This option provides support for holding large keys within the kernel (for example Kerberos ticket caches). The data may be stored out to diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 835c1ab30d01eb9a8e94b411fce09b856772efb9..e607830b6154ce4c8dbcd5563fb0d3607f680c8f 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -1,5 +1,6 @@ /* Large capacity key type * + * Copyright (C) 2017 Jason A. Donenfeld . All Rights Reserved. * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * @@ -16,10 +17,10 @@ #include #include #include +#include #include #include -#include -#include +#include /* * Layout of key payload words. @@ -49,7 +50,12 @@ enum big_key_op { /* * Key size for big_key data encryption */ -#define ENC_KEY_SIZE 16 +#define ENC_KEY_SIZE 32 + +/* + * Authentication tag length + */ +#define ENC_AUTHTAG_SIZE 16 /* * big_key defined keys take an arbitrary string as the description and an @@ -64,57 +70,62 @@ struct key_type key_type_big_key = { .destroy = big_key_destroy, .describe = big_key_describe, .read = big_key_read, + /* no ->update(); don't add it without changing big_key_crypt() nonce */ }; /* - * Crypto names for big_key data encryption + * Crypto names for big_key data authenticated encryption */ -static const char big_key_rng_name[] = "stdrng"; -static const char big_key_alg_name[] = "ecb(aes)"; +static const char big_key_alg_name[] = "gcm(aes)"; /* - * Crypto algorithms for big_key data encryption + * Crypto algorithms for big_key data authenticated encryption */ -static struct crypto_rng *big_key_rng; -static struct crypto_skcipher *big_key_skcipher; +static struct crypto_aead *big_key_aead; /* - * Generate random key to encrypt big_key data + * Since changing the key affects the entire object, we need a mutex. */ -static inline int big_key_gen_enckey(u8 *key) -{ - return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE); -} +static DEFINE_MUTEX(big_key_aead_lock); /* * Encrypt/decrypt big_key data */ static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) { - int ret = -EINVAL; + int ret; struct scatterlist sgio; - SKCIPHER_REQUEST_ON_STACK(req, big_key_skcipher); - - if (crypto_skcipher_setkey(big_key_skcipher, key, ENC_KEY_SIZE)) { + struct aead_request *aead_req; + /* We always use a zero nonce. The reason we can get away with this is + * because we're using a different randomly generated key for every + * different encryption. Notably, too, key_type_big_key doesn't define + * an .update function, so there's no chance we'll wind up reusing the + * key to encrypt updated data. Simply put: one key, one encryption. + */ + u8 zero_nonce[crypto_aead_ivsize(big_key_aead)]; + + aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL); + if (!aead_req) + return -ENOMEM; + + memset(zero_nonce, 0, sizeof(zero_nonce)); + sg_init_one(&sgio, data, datalen + (op == BIG_KEY_ENC ? ENC_AUTHTAG_SIZE : 0)); + aead_request_set_crypt(aead_req, &sgio, &sgio, datalen, zero_nonce); + aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); + aead_request_set_ad(aead_req, 0); + + mutex_lock(&big_key_aead_lock); + if (crypto_aead_setkey(big_key_aead, key, ENC_KEY_SIZE)) { ret = -EAGAIN; goto error; } - - skcipher_request_set_tfm(req, big_key_skcipher); - skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, - NULL, NULL); - - sg_init_one(&sgio, data, datalen); - skcipher_request_set_crypt(req, &sgio, &sgio, datalen, NULL); - if (op == BIG_KEY_ENC) - ret = crypto_skcipher_encrypt(req); + ret = crypto_aead_encrypt(aead_req); else - ret = crypto_skcipher_decrypt(req); - - skcipher_request_zero(req); - + ret = crypto_aead_decrypt(aead_req); error: + mutex_unlock(&big_key_aead_lock); + aead_request_free(aead_req); return ret; } @@ -146,15 +157,13 @@ int big_key_preparse(struct key_preparsed_payload *prep) * * File content is stored encrypted with randomly generated key. */ - size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); + size_t enclen = datalen + ENC_AUTHTAG_SIZE; + loff_t pos = 0; - /* prepare aligned data to encrypt */ data = kmalloc(enclen, GFP_KERNEL); if (!data) return -ENOMEM; - memcpy(data, prep->data, datalen); - memset(data + datalen, 0x00, enclen - datalen); /* generate random key */ enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL); @@ -162,13 +171,12 @@ int big_key_preparse(struct key_preparsed_payload *prep) ret = -ENOMEM; goto error; } - - ret = big_key_gen_enckey(enckey); - if (ret) + ret = get_random_bytes_wait(enckey, ENC_KEY_SIZE); + if (unlikely(ret)) goto err_enckey; /* encrypt aligned data */ - ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey); + ret = big_key_crypt(BIG_KEY_ENC, data, datalen, enckey); if (ret) goto err_enckey; @@ -179,7 +187,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) goto err_enckey; } - written = kernel_write(file, data, enclen, 0); + written = kernel_write(file, data, enclen, &pos); if (written != enclen) { ret = written; if (written >= 0) @@ -194,7 +202,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) *path = file->f_path; path_get(path); fput(file); - kfree(data); + kzfree(data); } else { /* Just store the data in a buffer */ void *data = kmalloc(datalen, GFP_KERNEL); @@ -210,9 +218,9 @@ int big_key_preparse(struct key_preparsed_payload *prep) err_fput: fput(file); err_enckey: - kfree(enckey); + kzfree(enckey); error: - kfree(data); + kzfree(data); return ret; } @@ -226,7 +234,7 @@ void big_key_free_preparse(struct key_preparsed_payload *prep) path_put(path); } - kfree(prep->payload.data[big_key_data]); + kzfree(prep->payload.data[big_key_data]); } /* @@ -258,7 +266,7 @@ void big_key_destroy(struct key *key) path->mnt = NULL; path->dentry = NULL; } - kfree(key->payload.data[big_key_data]); + kzfree(key->payload.data[big_key_data]); key->payload.data[big_key_data] = NULL; } @@ -294,7 +302,8 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) struct file *file; u8 *data; u8 *enckey = (u8 *)key->payload.data[big_key_data]; - size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); + size_t enclen = datalen + ENC_AUTHTAG_SIZE; + loff_t pos = 0; data = kmalloc(enclen, GFP_KERNEL); if (!data) @@ -307,7 +316,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) } /* read file to kernel and decrypt */ - ret = kernel_read(file, 0, data, enclen); + ret = kernel_read(file, data, enclen, &pos); if (ret >= 0 && ret != enclen) { ret = -EIO; goto err_fput; @@ -326,7 +335,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) err_fput: fput(file); error: - kfree(data); + kzfree(data); } else { ret = datalen; if (copy_to_user(buffer, key->payload.data[big_key_data], @@ -342,47 +351,31 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) */ static int __init big_key_init(void) { - struct crypto_skcipher *cipher; - struct crypto_rng *rng; int ret; - rng = crypto_alloc_rng(big_key_rng_name, 0, 0); - if (IS_ERR(rng)) { - pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng)); - return PTR_ERR(rng); - } - - big_key_rng = rng; - - /* seed RNG */ - ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng)); - if (ret) { - pr_err("Can't reset rng: %d\n", ret); - goto error_rng; - } - /* init block cipher */ - cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(cipher)) { - ret = PTR_ERR(cipher); + big_key_aead = crypto_alloc_aead(big_key_alg_name, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(big_key_aead)) { + ret = PTR_ERR(big_key_aead); pr_err("Can't alloc crypto: %d\n", ret); - goto error_rng; + return ret; + } + ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE); + if (ret < 0) { + pr_err("Can't set crypto auth tag len: %d\n", ret); + goto free_aead; } - - big_key_skcipher = cipher; ret = register_key_type(&key_type_big_key); if (ret < 0) { pr_err("Can't register type: %d\n", ret); - goto error_cipher; + goto free_aead; } return 0; -error_cipher: - crypto_free_skcipher(big_key_skcipher); -error_rng: - crypto_free_rng(big_key_rng); +free_aead: + crypto_free_aead(big_key_aead); return ret; } diff --git a/security/keys/internal.h b/security/keys/internal.h index 1c02c65470384aa076e2de6885ecba356eb44342..503adbae7b0dd0b096aa7fd672fddb0d3513d115 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -141,7 +141,7 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); -extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); +extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); extern int install_user_keyrings(void); extern int install_thread_keyring_to_cred(struct cred *); diff --git a/security/keys/key.c b/security/keys/key.c index 83da68d98b40b452a1c8b37121a6ca270387d4f6..eb914a838840df416f26af2c0cd73f87c60a5032 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -54,10 +54,10 @@ void __key_check(const struct key *key) struct key_user *key_user_lookup(kuid_t uid) { struct key_user *candidate = NULL, *user; - struct rb_node *parent = NULL; - struct rb_node **p; + struct rb_node *parent, **p; try_again: + parent = NULL; p = &key_user_tree.rb_node; spin_lock(&key_user_lock); @@ -302,6 +302,8 @@ struct key *key_alloc(struct key_type *type, const char *desc, key->flags |= 1 << KEY_FLAG_IN_QUOTA; if (flags & KEY_ALLOC_BUILT_IN) key->flags |= 1 << KEY_FLAG_BUILTIN; + if (flags & KEY_ALLOC_UID_KEYRING) + key->flags |= 1 << KEY_FLAG_UID_KEYRING; #ifdef KEY_DEBUGGING key->magic = KEY_DEBUG_MAGIC; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index ab0b337c84b4c02e4856719398edb94d1caf101a..365ff85d7e27122db220fad6d633f8e0b352209f 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -766,12 +766,17 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) key = key_ref_to_ptr(key_ref); + if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { + ret = -ENOKEY; + goto error2; + } + /* see if we can read it directly */ ret = key_permission(key_ref, KEY_NEED_READ); if (ret == 0) goto can_read_key; if (ret != -EACCES) - goto error; + goto error2; /* we can't; see if it's searchable from this process's keyrings * - we automatically take account of the fact that it may be @@ -1406,11 +1411,9 @@ long keyctl_assume_authority(key_serial_t id) } ret = keyctl_change_reqkey_auth(authkey); - if (ret < 0) - goto error; + if (ret == 0) + ret = authkey->serial; key_put(authkey); - - ret = authkey->serial; error: return ret; } diff --git a/security/keys/keyring.c b/security/keys/keyring.c index de81793f9920787101dec77eca28ddfbe91ebbc7..4fa82a8a9c0e6cb778a08874724ea546cd602ade 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -423,7 +423,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) } struct keyring_read_iterator_context { - size_t qty; + size_t buflen; size_t count; key_serial_t __user *buffer; }; @@ -435,9 +435,9 @@ static int keyring_read_iterator(const void *object, void *data) int ret; kenter("{%s,%d},,{%zu/%zu}", - key->type->name, key->serial, ctx->count, ctx->qty); + key->type->name, key->serial, ctx->count, ctx->buflen); - if (ctx->count >= ctx->qty) + if (ctx->count >= ctx->buflen) return 1; ret = put_user(key->serial, ctx->buffer); @@ -472,16 +472,12 @@ static long keyring_read(const struct key *keyring, return 0; /* Calculate how much data we could return */ - ctx.qty = nr_keys * sizeof(key_serial_t); - if (!buffer || !buflen) - return ctx.qty; - - if (buflen > ctx.qty) - ctx.qty = buflen; + return nr_keys * sizeof(key_serial_t); /* Copy the IDs of the subscribed keys into the buffer */ ctx.buffer = (key_serial_t __user *)buffer; + ctx.buflen = buflen; ctx.count = 0; ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx); if (ret < 0) { @@ -1101,15 +1097,15 @@ key_ref_t find_key_to_update(key_ref_t keyring_ref, /* * Find a keyring with the specified name. * - * All named keyrings in the current user namespace are searched, provided they - * grant Search permission directly to the caller (unless this check is - * skipped). Keyrings whose usage points have reached zero or who have been - * revoked are skipped. + * Only keyrings that have nonzero refcount, are not revoked, and are owned by a + * user in the current user namespace are considered. If @uid_keyring is %true, + * the keyring additionally must have been allocated as a user or user session + * keyring; otherwise, it must grant Search permission directly to the caller. * * Returns a pointer to the keyring with the keyring's refcount having being * incremented on success. -ENOKEY is returned if a key could not be found. */ -struct key *find_keyring_by_name(const char *name, bool skip_perm_check) +struct key *find_keyring_by_name(const char *name, bool uid_keyring) { struct key *keyring; int bucket; @@ -1137,10 +1133,15 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check) if (strcmp(keyring->description, name) != 0) continue; - if (!skip_perm_check && - key_permission(make_key_ref(keyring, 0), - KEY_NEED_SEARCH) < 0) - continue; + if (uid_keyring) { + if (!test_bit(KEY_FLAG_UID_KEYRING, + &keyring->flags)) + continue; + } else { + if (key_permission(make_key_ref(keyring, 0), + KEY_NEED_SEARCH) < 0) + continue; + } /* we've got a match but we might end up racing with * key_cleanup() if the keyring is currently 'dead' diff --git a/security/keys/proc.c b/security/keys/proc.c index bf08d02b6646ae2077b15903471bfb4575b04f5a..de834309d100206bedca18c84493af6fdb665d7a 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -187,7 +187,7 @@ static int proc_keys_show(struct seq_file *m, void *v) struct keyring_search_context ctx = { .index_key.type = key->type, .index_key.description = key->description, - .cred = current_cred(), + .cred = m->file->f_cred, .match_data.cmp = lookup_user_key_possessed, .match_data.raw_data = key, .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, @@ -207,11 +207,7 @@ static int proc_keys_show(struct seq_file *m, void *v) } } - /* check whether the current task is allowed to view the key (assuming - * non-possession) - * - the caller holds a spinlock, and thus the RCU read lock, making our - * access to __current_cred() safe - */ + /* check whether the current task is allowed to view the key */ rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW); if (rc < 0) return 0; diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 86bced9fdbdf22eb60170584d87730e1179a2744..293d3598153bf0c8611f319f4c1d7c50f364e600 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -77,7 +77,8 @@ int install_user_keyrings(void) if (IS_ERR(uid_keyring)) { uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, cred, user_keyring_perm, - KEY_ALLOC_IN_QUOTA, + KEY_ALLOC_UID_KEYRING | + KEY_ALLOC_IN_QUOTA, NULL, NULL); if (IS_ERR(uid_keyring)) { ret = PTR_ERR(uid_keyring); @@ -94,7 +95,8 @@ int install_user_keyrings(void) session_keyring = keyring_alloc(buf, user->uid, INVALID_GID, cred, user_keyring_perm, - KEY_ALLOC_IN_QUOTA, + KEY_ALLOC_UID_KEYRING | + KEY_ALLOC_IN_QUOTA, NULL, NULL); if (IS_ERR(session_keyring)) { ret = PTR_ERR(session_keyring); diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index afe9d22ab3611f2dc621db0092e1b102e005be78..6ebf1af8fce963eeb0cc4c423c153318096e65a6 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -120,6 +120,18 @@ static void request_key_auth_revoke(struct key *key) } } +static void free_request_key_auth(struct request_key_auth *rka) +{ + if (!rka) + return; + key_put(rka->target_key); + key_put(rka->dest_keyring); + if (rka->cred) + put_cred(rka->cred); + kfree(rka->callout_info); + kfree(rka); +} + /* * Destroy an instantiation authorisation token key. */ @@ -129,15 +141,7 @@ static void request_key_auth_destroy(struct key *key) kenter("{%d}", key->serial); - if (rka->cred) { - put_cred(rka->cred); - rka->cred = NULL; - } - - key_put(rka->target_key); - key_put(rka->dest_keyring); - kfree(rka->callout_info); - kfree(rka); + free_request_key_auth(rka); } /* @@ -151,22 +155,18 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, const struct cred *cred = current->cred; struct key *authkey = NULL; char desc[20]; - int ret; + int ret = -ENOMEM; kenter("%d,", target->serial); /* allocate a auth record */ - rka = kmalloc(sizeof(*rka), GFP_KERNEL); - if (!rka) { - kleave(" = -ENOMEM"); - return ERR_PTR(-ENOMEM); - } - rka->callout_info = kmalloc(callout_len, GFP_KERNEL); - if (!rka->callout_info) { - kleave(" = -ENOMEM"); - kfree(rka); - return ERR_PTR(-ENOMEM); - } + rka = kzalloc(sizeof(*rka), GFP_KERNEL); + if (!rka) + goto error; + rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL); + if (!rka->callout_info) + goto error_free_rka; + rka->callout_len = callout_len; /* see if the calling process is already servicing the key request of * another process */ @@ -176,8 +176,12 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, /* if the auth key has been revoked, then the key we're * servicing is already instantiated */ - if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags)) - goto auth_key_revoked; + if (test_bit(KEY_FLAG_REVOKED, + &cred->request_key_auth->flags)) { + up_read(&cred->request_key_auth->sem); + ret = -EKEYREVOKED; + goto error_free_rka; + } irka = cred->request_key_auth->payload.data[0]; rka->cred = get_cred(irka->cred); @@ -193,8 +197,6 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, rka->target_key = key_get(target); rka->dest_keyring = key_get(dest_keyring); - memcpy(rka->callout_info, callout_info, callout_len); - rka->callout_len = callout_len; /* allocate the auth key */ sprintf(desc, "%x", target->serial); @@ -205,32 +207,22 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL); if (IS_ERR(authkey)) { ret = PTR_ERR(authkey); - goto error_alloc; + goto error_free_rka; } /* construct the auth key */ ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); if (ret < 0) - goto error_inst; + goto error_put_authkey; kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage)); return authkey; -auth_key_revoked: - up_read(&cred->request_key_auth->sem); - kfree(rka->callout_info); - kfree(rka); - kleave("= -EKEYREVOKED"); - return ERR_PTR(-EKEYREVOKED); - -error_inst: - key_revoke(authkey); +error_put_authkey: key_put(authkey); -error_alloc: - key_put(rka->target_key); - key_put(rka->dest_keyring); - kfree(rka->callout_info); - kfree(rka); +error_free_rka: + free_request_key_auth(rka); +error: kleave("= %d", ret); return ERR_PTR(ret); } diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 28d4c3a528abce522c4c274c9233cfc03f3eadc2..67703dbe29eafb7138d050f9344438e808ab291b 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c @@ -2,7 +2,7 @@ * common LSM auditing functions * * Based on code written for SELinux by : - * Stephen Smalley, + * Stephen Smalley, * James Morris * Author : Etienne Basset, * diff --git a/security/security.c b/security/security.c index 30132378d103dea6dc3d81ae65c2a04b864d71ec..4bf0f571b4ef94df1d3c44b7fed6b7b651c1924f 100644 --- a/security/security.c +++ b/security/security.c @@ -351,11 +351,6 @@ void security_bprm_committed_creds(struct linux_binprm *bprm) call_void_hook(bprm_committed_creds, bprm); } -int security_bprm_secureexec(struct linux_binprm *bprm) -{ - return call_int_hook(bprm_secureexec, 0, bprm); -} - int security_sb_alloc(struct super_block *sb) { return call_int_hook(sb_alloc_security, 0, sb); @@ -979,11 +974,6 @@ int security_file_open(struct file *file, const struct cred *cred) return fsnotify_perm(file, MAY_OPEN); } -int security_task_create(unsigned long clone_flags) -{ - return call_int_hook(task_create, 0, clone_flags); -} - int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { return call_int_hook(task_alloc, 0, task, clone_flags); diff --git a/security/selinux/avc.c b/security/selinux/avc.c index e60c79de13e1c74ea6129cfb5431d5d2415cdc2d..2380b8d72cecbfaaf7649b4224a4d8869dddf9a0 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -1,7 +1,7 @@ /* * Implementation of the kernel access vector cache (AVC). * - * Authors: Stephen Smalley, + * Authors: Stephen Smalley, * James Morris * * Update: KaiGai, Kohei @@ -197,8 +197,6 @@ void __init avc_init(void) avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data", sizeof(struct extended_perms_data), 0, SLAB_PANIC, NULL); - - audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); } int avc_get_hash_stats(char *page) @@ -348,27 +346,26 @@ static struct avc_xperms_decision_node struct avc_xperms_decision_node *xpd_node; struct extended_perms_decision *xpd; - xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT); if (!xpd_node) return NULL; xpd = &xpd_node->xpd; if (which & XPERMS_ALLOWED) { xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + GFP_NOWAIT); if (!xpd->allowed) goto error; } if (which & XPERMS_AUDITALLOW) { xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + GFP_NOWAIT); if (!xpd->auditallow) goto error; } if (which & XPERMS_DONTAUDIT) { xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + GFP_NOWAIT); if (!xpd->dontaudit) goto error; } @@ -396,8 +393,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void) { struct avc_xperms_node *xp_node; - xp_node = kmem_cache_zalloc(avc_xperms_cachep, - GFP_ATOMIC|__GFP_NOMEMALLOC); + xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT); if (!xp_node) return xp_node; INIT_LIST_HEAD(&xp_node->xpd_head); @@ -550,7 +546,7 @@ static struct avc_node *avc_alloc_node(void) { struct avc_node *node; - node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC|__GFP_NOMEMALLOC); + node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT); if (!node) goto out; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 33fd061305c40376c7f632ebcdf6fe5fd7b1e3fc..f5d304736852f98508144c23e7325068c6ae2ee8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3,7 +3,7 @@ * * This file contains the SELinux hook function implementations. * - * Authors: Stephen Smalley, + * Authors: Stephen Smalley, * Chris Vance, * Wayne Salamon, * James Morris @@ -815,7 +815,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, if (!strcmp(sb->s_type->name, "debugfs") || !strcmp(sb->s_type->name, "tracefs") || !strcmp(sb->s_type->name, "sysfs") || - !strcmp(sb->s_type->name, "pstore")) + !strcmp(sb->s_type->name, "pstore") || + !strcmp(sb->s_type->name, "cgroup") || + !strcmp(sb->s_type->name, "cgroup2")) sbsec->flags |= SE_SBGENFS; if (!sbsec->behavior) { @@ -1303,6 +1305,7 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc case SOCK_SEQPACKET: return SECCLASS_UNIX_STREAM_SOCKET; case SOCK_DGRAM: + case SOCK_RAW: return SECCLASS_UNIX_DGRAM_SOCKET; } break; @@ -2317,6 +2320,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); int rc; + u32 av; if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2325,24 +2329,40 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, return 0; /* No change in credentials */ /* - * The only transitions we permit under NNP or nosuid - * are transitions to bounded SIDs, i.e. SIDs that are - * guaranteed to only be allowed a subset of the permissions - * of the current SID. + * If the policy enables the nnp_nosuid_transition policy capability, + * then we permit transitions under NNP or nosuid if the + * policy allows the corresponding permission between + * the old and new contexts. */ - rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); - if (rc) { - /* - * On failure, preserve the errno values for NNP vs nosuid. - * NNP: Operation not permitted for caller. - * nosuid: Permission denied to file. - */ + if (selinux_policycap_nnp_nosuid_transition) { + av = 0; if (nnp) - return -EPERM; - else - return -EACCES; + av |= PROCESS2__NNP_TRANSITION; + if (nosuid) + av |= PROCESS2__NOSUID_TRANSITION; + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + SECCLASS_PROCESS2, av, NULL); + if (!rc) + return 0; } - return 0; + + /* + * We also permit NNP or nosuid transitions to bounded SIDs, + * i.e. SIDs that are guaranteed to only be allowed a subset + * of the permissions of the current SID. + */ + rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); + if (!rc) + return 0; + + /* + * On failure, preserve the errno values for NNP vs nosuid. + * NNP: Operation not permitted for caller. + * nosuid: Permission denied to file. + */ + if (nnp) + return -EPERM; + return -EACCES; } static int selinux_bprm_set_creds(struct linux_binprm *bprm) @@ -2356,7 +2376,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) /* SELinux context only depends on initial program or script and not * the script interpreter */ - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; old_tsec = current_security(); @@ -2442,30 +2462,17 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) /* Clear any possibly unsafe personality bits on exec: */ bprm->per_clear |= PER_CLEAR_ON_SETID; - } - - return 0; -} -static int selinux_bprm_secureexec(struct linux_binprm *bprm) -{ - const struct task_security_struct *tsec = current_security(); - u32 sid, osid; - int atsecure = 0; - - sid = tsec->sid; - osid = tsec->osid; - - if (osid != sid) { /* Enable secure mode for SIDs transitions unless the noatsecure permission is granted between the two SIDs, i.e. ahp returns 0. */ - atsecure = avc_has_perm(osid, sid, - SECCLASS_PROCESS, - PROCESS__NOATSECURE, NULL); + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + SECCLASS_PROCESS, PROCESS__NOATSECURE, + NULL); + bprm->secureexec |= !!rc; } - return !!atsecure; + return 0; } static int match_file(const void *p, struct file *file, unsigned fd) @@ -6266,7 +6273,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), - LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), @@ -6530,7 +6536,7 @@ security_initcall(selinux_init); #if defined(CONFIG_NETFILTER) -static struct nf_hook_ops selinux_nf_ops[] = { +static const struct nf_hook_ops selinux_nf_ops[] = { { .hook = selinux_ipv4_postroute, .pf = NFPROTO_IPV4, diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 0999df03af8bff2fe54c084e7459ed19da5a20c2..a5004e9de11a999f56333eed055b9519d7275b39 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -1,7 +1,7 @@ /* * Access vector cache interface for object managers. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SELINUX_AVC_H_ #define _SELINUX_AVC_H_ diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index d5c328452df0161acd82bd8ec295fecc00392b86..37d57dadd476a90d6a1bef5f2104a0057d1dd44f 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h @@ -1,7 +1,7 @@ /* * Access vector cache interface for the security server. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SELINUX_AVC_SS_H_ #define _SELINUX_AVC_SS_H_ diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index b9fe3434b036d8a0e7c55716753f04735c1a9a0e..35ffb29a69cb00b34a4de5d722eaee46df310a74 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -48,6 +48,8 @@ struct security_class_mapping secclass_map[] = { "setrlimit", "rlimitinh", "dyntransition", "setcurrent", "execmem", "execstack", "execheap", "setkeycreate", "setsockcreate", "getrlimit", NULL } }, + { "process2", + { "nnp_transition", "nosuid_transition", NULL } }, { "system", { "ipc_info", "syslog_read", "syslog_mod", "syslog_console", "module_request", "module_load", NULL } }, diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 6ebc61e370ff32856ef9b164355ffd2e9645699e..1649cd18eb0bed125bb38466506309d26c647f90 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -3,7 +3,7 @@ * * This file contains the SELinux security data structures for kernel objects. * - * Author(s): Stephen Smalley, + * Author(s): Stephen Smalley, * Chris Vance, * Wayne Salamon, * James Morris diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index e91f08c16c0b2943686fe94eb3ac84b09078e5de..28dfb2f93e4dcfcb62fc77e20fe7303295905b48 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -1,7 +1,7 @@ /* * Security server interface. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, * */ @@ -73,6 +73,7 @@ enum { POLICYDB_CAPABILITY_EXTSOCKCLASS, POLICYDB_CAPABILITY_ALWAYSNETWORK, POLICYDB_CAPABILITY_CGROUPSECLABEL, + POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) @@ -84,6 +85,7 @@ extern int selinux_policycap_openperm; extern int selinux_policycap_extsockclass; extern int selinux_policycap_alwaysnetwork; extern int selinux_policycap_cgroupseclabel; +extern int selinux_policycap_nnp_nosuid_transition; /* * type_datum properties diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 1450f85b946da462e5ef3576a50d979d15574b8f..36a7ce9e11fff1acb67d1e994ff892dd495175a9 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -47,10 +47,8 @@ static inline void selinux_xfrm_notify_policyload(void) struct net *net; rtnl_lock(); - for_each_net(net) { - atomic_inc(&net->xfrm.flow_cache_genid); + for_each_net(net) rt_genid_bump_all(net); - } rtnl_unlock(); } #else diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 3628d3a868b669c9aa9267808533aaa5dc8c0d1c..2c3c7d010d8a49c584057c0ec9efbe8213286601 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -1,7 +1,7 @@ /* * Implementation of the access vector table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* Updated: Frank Mayer and Karl MacMillan diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index d946c9dc3c9ca6b2569ecd7624c3bd12f7789c77..725853cadc42111c0ee49304cafbba7509ef12b2 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -5,7 +5,7 @@ * table is used to represent the type enforcement * tables. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* Updated: Frank Mayer and Karl MacMillan diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h index 96fd947c494b64827f89e745393483669cc07d8e..33ae2aec4f3617b211c53f96361fd34281dc8005 100644 --- a/security/selinux/ss/constraint.h +++ b/security/selinux/ss/constraint.h @@ -10,7 +10,7 @@ * process from labeling an object with a different user * identity. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_CONSTRAINT_H_ #define _SS_CONSTRAINT_H_ diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index 212e3479a0d98e0b32b643ef78d97f5174b7f692..a2c0f37c42aef1ed220dbd3d8dc2088740f548dd 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h @@ -10,7 +10,7 @@ * security server and can be changed without affecting * clients of the security server. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_CONTEXT_H_ #define _SS_CONTEXT_H_ diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index ad38299164c392b1feba7a34a395a8b1dc24b504..fc28149a4f2e67ba8293cd0d2863eae484b8a7a3 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -1,7 +1,7 @@ /* * Implementation of the extensible bitmap type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Hewlett-Packard diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index 6d5a9ac4251f860da7a29b1082fe246098257b02..da1325dda550e664821e6c33e418227343047dba 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h @@ -9,7 +9,7 @@ * an explicitly specified starting bit position within * the total bitmap. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_EBITMAP_H_ #define _SS_EBITMAP_H_ diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 3858706a29fbb9d885e0722b8e3a06cdaa0ffcd4..686c3917064c5d10dddf7a4c3a6db70136f40624 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -1,7 +1,7 @@ /* * Implementation of the hash table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #include #include diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h index 953872cd84ab0a17bf161154b1dfd38080357ff5..009fb5e06172d54fafeb1478f43c6251ef8291e4 100644 --- a/security/selinux/ss/hashtab.h +++ b/security/selinux/ss/hashtab.h @@ -5,7 +5,7 @@ * functions for hash computation and key comparison are * provided by the creator of the table. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_HASHTAB_H_ #define _SS_HASHTAB_H_ diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index e1088842232c6aefd334c2bf96c51549d8a55363..d9dc34f4fadea997902a3e309170a908e89dcbdd 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -1,7 +1,7 @@ /* * Implementation of the multi-level security (MLS) policy. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Trusted Computer Solutions, Inc. diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index e4369e3e6366f89e52690e64ad16ae00ba45b985..0f0a1d65b2ceb3dba1f7fee67dbe1d9841245a9d 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -1,7 +1,7 @@ /* * Multi-level security (MLS) policy operations. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Trusted Computer Solutions, Inc. diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h index e93648774137c601f5ec90ce14a03983655ce36d..47f3702cd596ebcdff6b76b88e776eecadfea2b2 100644 --- a/security/selinux/ss/mls_types.h +++ b/security/selinux/ss/mls_types.h @@ -1,7 +1,7 @@ /* * Type definitions for the multi-level security (MLS) policy. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Trusted Computer Solutions, Inc. diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index aa6500abb178c3534b2940e0acfb48a8613768b1..6e8c8056d7adfa7f57c6f0041087a49eb1575605 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -1,7 +1,7 @@ /* * Implementation of the policy database. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 5d23eed35fa7a4a2b15beec21eb869a2213201c3..215f8f30ac5a5dcfa5126c8357da7cebf9639a1b 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -2,7 +2,7 @@ * A policy database (policydb) specifies the * configuration data for the security policy. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 2f02fa67ec2e833eefb6f98f9d6190f4012679a1..e4a1c0dc561a40a06bc10534273ddb1919798c0c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1,7 +1,7 @@ /* * Implementation of the security services. * - * Authors : Stephen Smalley, + * Authors : Stephen Smalley, * James Morris * * Updated: Trusted Computer Solutions, Inc. @@ -76,7 +76,8 @@ char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { "open_perms", "extended_socket_class", "always_check_network", - "cgroup_seclabel" + "cgroup_seclabel", + "nnp_nosuid_transition" }; int selinux_policycap_netpeer; @@ -84,6 +85,7 @@ int selinux_policycap_openperm; int selinux_policycap_extsockclass; int selinux_policycap_alwaysnetwork; int selinux_policycap_cgroupseclabel; +int selinux_policycap_nnp_nosuid_transition; static DEFINE_RWLOCK(policy_rwlock); @@ -2009,6 +2011,9 @@ static void security_load_policycaps(void) selinux_policycap_cgroupseclabel = ebitmap_get_bit(&policydb.policycaps, POLICYDB_CAPABILITY_CGROUPSECLABEL); + selinux_policycap_nnp_nosuid_transition = + ebitmap_get_bit(&policydb.policycaps, + POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION); for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) pr_info("SELinux: policy capability %s=%d\n", diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 6abcd8729ec3a6c7605ab394a7d108fe0192020a..3d9fa9556b4f97a2f2fa9c1cd252eae3ac2587ad 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -1,7 +1,7 @@ /* * Implementation of the security services. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_SERVICES_H_ #define _SS_SERVICES_H_ diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index c5f436b15d1992dc2a40999f0477728c67f7512d..6ae08efc5ae78dfd3a00885dd1ff45bc5952f788 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -1,7 +1,7 @@ /* * Implementation of the SID table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #include #include diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 84dc154d9389db3b6353443e7c6d3c1997e08a76..de5d0ea583d2535a79a7cde28b4abdc5ad28e9eb 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -2,7 +2,7 @@ * A security identifier table (sidtab) is a hash table * of security context structures indexed by SID value. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_SIDTAB_H_ #define _SS_SIDTAB_H_ diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c index 160326ee99e58b0d47388dcb98493a7d1bb0905f..d1a6745849a7beee47ddc75d372cb26ed3234a1e 100644 --- a/security/selinux/ss/symtab.c +++ b/security/selinux/ss/symtab.c @@ -1,7 +1,7 @@ /* * Implementation of the symbol table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #include #include diff --git a/security/selinux/ss/symtab.h b/security/selinux/ss/symtab.h index ca422b42fbc0beaf680cf79e2f7617f5f5255715..0bc12d587d3a20836c41b83d3c0eefd3e230633c 100644 --- a/security/selinux/ss/symtab.h +++ b/security/selinux/ss/symtab.h @@ -4,7 +4,7 @@ * is arbitrary. The symbol table type is implemented * using the hash table type (hashtab). * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_SYMTAB_H_ #define _SS_SYMTAB_H_ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 463af86812c7ac295e5d5c02b3c20a79c5f8242a..286171a16ed255e20c396fca595600488c059c2d 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -917,7 +917,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) struct superblock_smack *sbsp; int rc; - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; isp = inode->i_security; @@ -950,35 +950,9 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) bsp->smk_task = isp->smk_task; bprm->per_clear |= PER_CLEAR_ON_SETID; - return 0; -} - -/** - * smack_bprm_committing_creds - Prepare to install the new credentials - * from bprm. - * - * @bprm: binprm for exec - */ -static void smack_bprm_committing_creds(struct linux_binprm *bprm) -{ - struct task_smack *bsp = bprm->cred->security; - + /* Decide if this is a secure exec. */ if (bsp->smk_task != bsp->smk_forked) - current->pdeath_signal = 0; -} - -/** - * smack_bprm_secureexec - Return the decision to use secureexec. - * @bprm: binprm for exec - * - * Returns 0 on success. - */ -static int smack_bprm_secureexec(struct linux_binprm *bprm) -{ - struct task_smack *tsp = current_security(); - - if (tsp->smk_task != tsp->smk_forked) - return 1; + bprm->secureexec = 1; return 0; } @@ -1499,7 +1473,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) * @inode: the object * @name: attribute name * @buffer: where to put the result - * @alloc: unused + * @alloc: duplicate memory * * Returns the size of the attribute or an error code */ @@ -1512,43 +1486,38 @@ static int smack_inode_getsecurity(struct inode *inode, struct super_block *sbp; struct inode *ip = (struct inode *)inode; struct smack_known *isp; - int ilen; - int rc = 0; - if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) isp = smk_of_inode(inode); - ilen = strlen(isp->smk_known); - *buffer = isp->smk_known; - return ilen; - } - - /* - * The rest of the Smack xattrs are only on sockets. - */ - sbp = ip->i_sb; - if (sbp->s_magic != SOCKFS_MAGIC) - return -EOPNOTSUPP; + else { + /* + * The rest of the Smack xattrs are only on sockets. + */ + sbp = ip->i_sb; + if (sbp->s_magic != SOCKFS_MAGIC) + return -EOPNOTSUPP; - sock = SOCKET_I(ip); - if (sock == NULL || sock->sk == NULL) - return -EOPNOTSUPP; + sock = SOCKET_I(ip); + if (sock == NULL || sock->sk == NULL) + return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = sock->sk->sk_security; - if (strcmp(name, XATTR_SMACK_IPIN) == 0) - isp = ssp->smk_in; - else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) - isp = ssp->smk_out; - else - return -EOPNOTSUPP; + if (strcmp(name, XATTR_SMACK_IPIN) == 0) + isp = ssp->smk_in; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) + isp = ssp->smk_out; + else + return -EOPNOTSUPP; + } - ilen = strlen(isp->smk_known); - if (rc == 0) { - *buffer = isp->smk_known; - rc = ilen; + if (alloc) { + *buffer = kstrdup(isp->smk_known, GFP_KERNEL); + if (*buffer == NULL) + return -ENOMEM; } - return rc; + return strlen(isp->smk_known); } @@ -4645,8 +4614,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str), LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), - LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds), - LSM_HOOK_INIT(bprm_secureexec, smack_bprm_secureexec), LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security), LSM_HOOK_INIT(inode_free_security, smack_inode_free_security), diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index cdeb0f3243dd635ced5e9efb49fb3fb61d37e4f3..e36d17835d4ff3dffff8bb42ed3e50bb7e1af571 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -58,7 +58,7 @@ static unsigned int smack_ipv4_output(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops smack_nf_ops[] = { +static const struct nf_hook_ops smack_nf_ops[] = { { .hook = smack_ipv4_output, .pf = NFPROTO_IPV4, diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 130b4fa4f65fde0771952399a8bc4e2db60b790c..d25b705360e068c73922a0d1ca671efe72925636 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -76,7 +76,7 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) * Do only if this function is called for the first time of an execve * operation. */ - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER /* diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index a04edff8b729ebf8fff761c8c3814f1ab66b4a80..d2d96ca082b71a204f3f18e7fa207e929564e4da 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -167,7 +167,7 @@ static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new volume_control = { +static const struct snd_kcontrol_new volume_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -229,7 +229,7 @@ static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol, return n != v; } -static struct snd_kcontrol_new inputgain_control = { +static const struct snd_kcontrol_new inputgain_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Capture Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -284,7 +284,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new capture_source_control = { +static const struct snd_kcontrol_new capture_source_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* If we name this 'Input Source', it properly shows up in * alsamixer as a selection, * but it's shown under the @@ -348,7 +348,7 @@ static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol, return !err ? (v != c) : err; } -static struct snd_kcontrol_new mute_control = { +static const struct snd_kcontrol_new mute_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -476,7 +476,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new onyx_spdif_mask = { +static const struct snd_kcontrol_new onyx_spdif_mask = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), @@ -533,7 +533,7 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new onyx_spdif_ctrl = { +static const struct snd_kcontrol_new onyx_spdif_ctrl = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 733b6365dad63af5cd8bf6edc43c44d850083289..15c05755d27005624f44e2dfe33734dd7b48dbb1 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -905,8 +905,8 @@ static int tas_i2c_probe(struct i2c_client *client, goto fail; } printk(KERN_DEBUG - "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n", - (unsigned int)client->addr, node->full_name); + "snd-aoa-codec-tas: tas found, addr 0x%02x on %pOF\n", + (unsigned int)client->addr, node); return 0; fail: mutex_destroy(&tas->mtx); diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c index 053b09c79053e548c1c7c1d8deef5064e7780d29..e618531757e0d9817ebbbb426f5892937773930e 100644 --- a/sound/aoa/soundbus/i2sbus/pcm.c +++ b/sound/aoa/soundbus/i2sbus/pcm.c @@ -778,7 +778,7 @@ static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream return i2sbus_pcm_pointer(i2sdev, 0); } -static struct snd_pcm_ops i2sbus_playback_ops = { +static const struct snd_pcm_ops i2sbus_playback_ops = { .open = i2sbus_playback_open, .close = i2sbus_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -848,7 +848,7 @@ static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream return i2sbus_pcm_pointer(i2sdev, 1); } -static struct snd_pcm_ops i2sbus_record_ops = { +static const struct snd_pcm_ops i2sbus_record_ops = { .open = i2sbus_record_open, .close = i2sbus_record_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 4140b1b950544bce0fc0360402d67f7fc5a031d4..0114ffed56dd4d2655d89e950774869dc2780d05 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -348,7 +348,7 @@ static irqreturn_t aaci_irq(int irq, void *devid) /* * ALSA support. */ -static struct snd_pcm_hardware aaci_hw_info = { +static const struct snd_pcm_hardware aaci_hw_info = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -635,7 +635,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm return ret; } -static struct snd_pcm_ops aaci_playback_ops = { +static const struct snd_pcm_ops aaci_playback_ops = { .open = aaci_pcm_open, .close = aaci_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -738,7 +738,7 @@ static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops aaci_capture_ops = { +static const struct snd_pcm_ops aaci_capture_ops = { .open = aaci_pcm_open, .close = aaci_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -786,7 +786,7 @@ static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume); #endif -static struct ac97_pcm ac97_defs[] = { +static const struct ac97_pcm ac97_defs[] = { [0] = { /* Front PCM */ .exclusive = 1, .r = { diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c index 83fcfac977396cd1d365289d70ca0857bb3127c4..1c6f4b436de31868af917a1767397c7daf1c7a84 100644 --- a/sound/arm/pxa2xx-pcm.c +++ b/sound/arm/pxa2xx-pcm.c @@ -68,7 +68,7 @@ static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) return __pxa2xx_pcm_close(substream); } -static struct snd_pcm_ops pxa2xx_pcm_ops = { +static const struct snd_pcm_ops pxa2xx_pcm_ops = { .open = pxa2xx_pcm_open, .close = pxa2xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 9d2c9d9af688030d660b63badbefc3f88e553aa2..380025887aef61e2aa87a7845d12a7d1ba9b85ae 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -12,16 +12,15 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include -#include #include #include @@ -29,7 +28,6 @@ #include #include #include -#include #include #include "ac97c.h" @@ -56,7 +54,7 @@ struct atmel_ac97c { void __iomem *regs; int irq; int opened; - int reset_pin; + struct gpio_desc *reset_pin; }; #define get_chip(card) ((struct atmel_ac97c *)(card)->private_data) @@ -66,7 +64,7 @@ struct atmel_ac97c { #define ac97c_readl(chip, reg) \ __raw_readl((chip)->regs + AC97C_##reg) -static struct snd_pcm_hardware atmel_ac97c_hw = { +static const struct snd_pcm_hardware atmel_ac97c_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED @@ -461,7 +459,7 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream) return frames; } -static struct snd_pcm_ops atmel_ac97_playback_ops = { +static const struct snd_pcm_ops atmel_ac97_playback_ops = { .open = atmel_ac97c_playback_open, .close = atmel_ac97c_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -472,7 +470,7 @@ static struct snd_pcm_ops atmel_ac97_playback_ops = { .pointer = atmel_ac97c_playback_pointer, }; -static struct snd_pcm_ops atmel_ac97_capture_ops = { +static const struct snd_pcm_ops atmel_ac97_capture_ops = { .open = atmel_ac97c_capture_open, .close = atmel_ac97c_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -558,7 +556,7 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) return retval; } -static struct ac97_pcm at91_ac97_pcm_defs[] = { +static const struct ac97_pcm at91_ac97_pcm_defs[] = { /* Playback */ { .exclusive = 1, @@ -700,11 +698,11 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) ac97c_writel(chip, CAMR, 0); ac97c_writel(chip, COMR, 0); - if (gpio_is_valid(chip->reset_pin)) { - gpio_set_value(chip->reset_pin, 0); + if (!IS_ERR(chip->reset_pin)) { + gpiod_set_value(chip->reset_pin, 0); /* AC97 v2.2 specifications says minimum 1 us. */ udelay(2); - gpio_set_value(chip->reset_pin, 1); + gpiod_set_value(chip->reset_pin, 1); } else { ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA); udelay(2); @@ -712,45 +710,18 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) } } -#ifdef CONFIG_OF static const struct of_device_id atmel_ac97c_dt_ids[] = { { .compatible = "atmel,at91sam9263-ac97c", }, { } }; MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids); -static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) -{ - struct ac97c_platform_data *pdata; - struct device_node *node = dev->of_node; - - if (!node) { - dev_err(dev, "Device does not have associated DT data\n"); - return ERR_PTR(-EINVAL); - } - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - pdata->reset_pin = of_get_named_gpio(dev->of_node, "ac97-gpios", 2); - - return pdata; -} -#else -static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) -{ - dev_err(dev, "no platform data defined\n"); - return ERR_PTR(-ENXIO); -} -#endif - static int atmel_ac97c_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct snd_card *card; struct atmel_ac97c *chip; struct resource *regs; - struct ac97c_platform_data *pdata; struct clk *pclk; static struct snd_ac97_bus_ops ops = { .write = atmel_ac97c_write, @@ -765,13 +736,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev) return -ENXIO; } - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - pdata = atmel_ac97c_probe_dt(&pdev->dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_dbg(&pdev->dev, "could not get irq: %d\n", irq); @@ -783,7 +747,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "no peripheral clock\n"); return PTR_ERR(pclk); } - clk_prepare_enable(pclk); + retval = clk_prepare_enable(pclk); + if (retval) + goto err_prepare_enable; retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, THIS_MODULE, @@ -819,17 +785,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev) goto err_ioremap; } - if (gpio_is_valid(pdata->reset_pin)) { - if (gpio_request(pdata->reset_pin, "reset_pin")) { - dev_dbg(&pdev->dev, "reset pin not available\n"); - chip->reset_pin = -ENODEV; - } else { - gpio_direction_output(pdata->reset_pin, 1); - chip->reset_pin = pdata->reset_pin; - } - } else { - chip->reset_pin = -EINVAL; - } + chip->reset_pin = devm_gpiod_get_index(dev, "ac97", 2, GPIOD_OUT_HIGH); + if (IS_ERR(chip->reset_pin)) + dev_dbg(dev, "reset pin not available\n"); atmel_ac97c_reset(chip); @@ -869,9 +827,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev) return 0; err_ac97_bus: - if (gpio_is_valid(chip->reset_pin)) - gpio_free(chip->reset_pin); - iounmap(chip->regs); err_ioremap: free_irq(irq, chip); @@ -879,6 +834,7 @@ static int atmel_ac97c_probe(struct platform_device *pdev) snd_card_free(card); err_snd_card_new: clk_disable_unprepare(pclk); +err_prepare_enable: clk_put(pclk); return retval; } @@ -897,9 +853,9 @@ static int atmel_ac97c_resume(struct device *pdev) { struct snd_card *card = dev_get_drvdata(pdev); struct atmel_ac97c *chip = card->private_data; + int ret = clk_prepare_enable(chip->pclk); - clk_prepare_enable(chip->pclk); - return 0; + return ret; } static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume); @@ -913,9 +869,6 @@ static int atmel_ac97c_remove(struct platform_device *pdev) struct snd_card *card = platform_get_drvdata(pdev); struct atmel_ac97c *chip = get_chip(card); - if (gpio_is_valid(chip->reset_pin)) - gpio_free(chip->reset_pin); - ac97c_writel(chip, CAMR, 0); ac97c_writel(chip, COMR, 0); ac97c_writel(chip, MR, 0); @@ -936,7 +889,7 @@ static struct platform_driver atmel_ac97c_driver = { .driver = { .name = "atmel_ac97c", .pm = ATMEL_AC97C_PM_OPS, - .of_match_table = of_match_ptr(atmel_ac97c_dt_ids), + .of_match_table = atmel_ac97c_dt_ids, }, }; module_platform_driver(atmel_ac97c_driver); diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index fec1dfdb14adfa7c7edc9f7aa2aba35c9e0cb2a5..4490a699030b10725015e323a18a09286ea02db0 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -948,14 +948,13 @@ static const struct file_operations snd_compr_file_ops = { static int snd_compress_dev_register(struct snd_device *device) { int ret = -EINVAL; - char str[16]; struct snd_compr *compr; if (snd_BUG_ON(!device || !device->device_data)) return -EBADFD; compr = device->device_data; - pr_debug("reg %s for device %s, direction %d\n", str, compr->name, + pr_debug("reg device %s, direction %d\n", compr->name, compr->direction); /* register compressed device */ ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS, diff --git a/sound/core/control.c b/sound/core/control.c index 3c6be1452e35dfc48e74ad23e1668c633ce57b24..56b3e2d49c82321509e699217ee1085382c40ce4 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -864,14 +864,14 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, if (copy_from_user(&info, _info, sizeof(info))) return -EFAULT; - snd_power_lock(ctl->card); result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_info(ctl, &info); - snd_power_unlock(ctl->card); - if (result >= 0) - if (copy_to_user(_info, &info, sizeof(info))) - return -EFAULT; + if (result < 0) + return result; + result = snd_ctl_elem_info(ctl, &info); + if (result < 0) + return result; + if (copy_to_user(_info, &info, sizeof(info))) + return -EFAULT; return result; } @@ -881,24 +881,18 @@ static int snd_ctl_elem_read(struct snd_card *card, struct snd_kcontrol *kctl; struct snd_kcontrol_volatile *vd; unsigned int index_offset; - int result; - down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); - if (kctl == NULL) { - result = -ENOENT; - } else { - index_offset = snd_ctl_get_ioff(kctl, &control->id); - vd = &kctl->vd[index_offset]; - if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && - kctl->get != NULL) { - snd_ctl_build_ioff(&control->id, kctl, index_offset); - result = kctl->get(kctl, control); - } else - result = -EPERM; - } - up_read(&card->controls_rwsem); - return result; + if (kctl == NULL) + return -ENOENT; + + index_offset = snd_ctl_get_ioff(kctl, &control->id); + vd = &kctl->vd[index_offset]; + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get == NULL) + return -EPERM; + + snd_ctl_build_ioff(&control->id, kctl, index_offset); + return kctl->get(kctl, control); } static int snd_ctl_elem_read_user(struct snd_card *card, @@ -911,14 +905,19 @@ static int snd_ctl_elem_read_user(struct snd_card *card, if (IS_ERR(control)) return PTR_ERR(control); - snd_power_lock(card); result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_read(card, control); - snd_power_unlock(card); - if (result >= 0) - if (copy_to_user(_control, control, sizeof(*control))) - result = -EFAULT; + if (result < 0) + goto error; + + down_read(&card->controls_rwsem); + result = snd_ctl_elem_read(card, control); + up_read(&card->controls_rwsem); + if (result < 0) + goto error; + + if (copy_to_user(_control, control, sizeof(*control))) + result = -EFAULT; + error: kfree(control); return result; } @@ -931,30 +930,28 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, unsigned int index_offset; int result; - down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); - if (kctl == NULL) { - result = -ENOENT; - } else { - index_offset = snd_ctl_get_ioff(kctl, &control->id); - vd = &kctl->vd[index_offset]; - if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || - kctl->put == NULL || - (file && vd->owner && vd->owner != file)) { - result = -EPERM; - } else { - snd_ctl_build_ioff(&control->id, kctl, index_offset); - result = kctl->put(kctl, control); - } - if (result > 0) { - struct snd_ctl_elem_id id = control->id; - up_read(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); - return 0; - } + if (kctl == NULL) + return -ENOENT; + + index_offset = snd_ctl_get_ioff(kctl, &control->id); + vd = &kctl->vd[index_offset]; + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL || + (file && vd->owner && vd->owner != file)) { + return -EPERM; } - up_read(&card->controls_rwsem); - return result; + + snd_ctl_build_ioff(&control->id, kctl, index_offset); + result = kctl->put(kctl, control); + if (result < 0) + return result; + + if (result > 0) { + struct snd_ctl_elem_id id = control->id; + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); + } + + return 0; } static int snd_ctl_elem_write_user(struct snd_ctl_file *file, @@ -969,14 +966,19 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, return PTR_ERR(control); card = file->card; - snd_power_lock(card); result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_write(card, file, control); - snd_power_unlock(card); - if (result >= 0) - if (copy_to_user(_control, control, sizeof(*control))) - result = -EFAULT; + if (result < 0) + goto error; + + down_write(&card->controls_rwsem); + result = snd_ctl_elem_write(card, file, control); + up_write(&card->controls_rwsem); + if (result < 0) + goto error; + + if (copy_to_user(_control, control, sizeof(*control))) + result = -EFAULT; + error: kfree(control); return result; } @@ -1095,9 +1097,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, char *src = ue->elem_data + snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size; - mutex_lock(&ue->card->user_ctl_lock); memcpy(&ucontrol->value, src, size); - mutex_unlock(&ue->card->user_ctl_lock); return 0; } @@ -1110,60 +1110,83 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, char *dst = ue->elem_data + snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size; - mutex_lock(&ue->card->user_ctl_lock); change = memcmp(&ucontrol->value, dst, size) != 0; if (change) memcpy(dst, &ucontrol->value, size); - mutex_unlock(&ue->card->user_ctl_lock); return change; } -static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, - int op_flag, - unsigned int size, - unsigned int __user *tlv) +static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf, + unsigned int size) { - struct user_element *ue = kcontrol->private_data; - int change = 0; - void *new_data; + struct user_element *ue = kctl->private_data; + unsigned int *container; + struct snd_ctl_elem_id id; + unsigned int mask = 0; + int i; + int change; - if (op_flag == SNDRV_CTL_TLV_OP_WRITE) { - if (size > 1024 * 128) /* sane value */ - return -EINVAL; + if (size > 1024 * 128) /* sane value */ + return -EINVAL; - new_data = memdup_user(tlv, size); - if (IS_ERR(new_data)) - return PTR_ERR(new_data); - mutex_lock(&ue->card->user_ctl_lock); - change = ue->tlv_data_size != size; - if (!change) - change = memcmp(ue->tlv_data, new_data, size); - kfree(ue->tlv_data); - ue->tlv_data = new_data; - ue->tlv_data_size = size; - mutex_unlock(&ue->card->user_ctl_lock); - } else { - int ret = 0; + container = memdup_user(buf, size); + if (IS_ERR(container)) + return PTR_ERR(container); - mutex_lock(&ue->card->user_ctl_lock); - if (!ue->tlv_data_size || !ue->tlv_data) { - ret = -ENXIO; - goto err_unlock; - } - if (size < ue->tlv_data_size) { - ret = -ENOSPC; - goto err_unlock; - } - if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) - ret = -EFAULT; -err_unlock: - mutex_unlock(&ue->card->user_ctl_lock); - if (ret) - return ret; + change = ue->tlv_data_size != size; + if (!change) + change = memcmp(ue->tlv_data, container, size) != 0; + if (!change) { + kfree(container); + return 0; } + + if (ue->tlv_data == NULL) { + /* Now TLV data is available. */ + for (i = 0; i < kctl->count; ++i) + kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; + mask = SNDRV_CTL_EVENT_MASK_INFO; + } + + kfree(ue->tlv_data); + ue->tlv_data = container; + ue->tlv_data_size = size; + + mask |= SNDRV_CTL_EVENT_MASK_TLV; + for (i = 0; i < kctl->count; ++i) { + snd_ctl_build_ioff(&id, kctl, i); + snd_ctl_notify(ue->card, mask, &id); + } + return change; } +static int read_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf, + unsigned int size) +{ + struct user_element *ue = kctl->private_data; + + if (ue->tlv_data_size == 0 || ue->tlv_data == NULL) + return -ENXIO; + + if (size < ue->tlv_data_size) + return -ENOSPC; + + if (copy_to_user(buf, ue->tlv_data, ue->tlv_data_size)) + return -EFAULT; + + return 0; +} + +static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kctl, int op_flag, + unsigned int size, unsigned int __user *buf) +{ + if (op_flag == SNDRV_CTL_TLV_OP_WRITE) + return replace_user_tlv(kctl, buf, size); + else + return read_user_tlv(kctl, buf, size); +} + static int snd_ctl_elem_init_enum_names(struct user_element *ue) { char *names, *p; @@ -1267,8 +1290,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, access = SNDRV_CTL_ELEM_ACCESS_READWRITE; access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE | - SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE); - if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) + SNDRV_CTL_ELEM_ACCESS_TLV_WRITE); + + /* In initial state, nothing is available as TLV container. */ + if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; access |= SNDRV_CTL_ELEM_ACCESS_USER; @@ -1331,7 +1356,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl->get = snd_ctl_elem_user_get; if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) kctl->put = snd_ctl_elem_user_put; - if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) + if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) kctl->tlv.c = snd_ctl_elem_user_tlv; /* This function manage to free the instance on failure. */ @@ -1405,71 +1430,107 @@ static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) return 0; } +static int call_tlv_handler(struct snd_ctl_file *file, int op_flag, + struct snd_kcontrol *kctl, + struct snd_ctl_elem_id *id, + unsigned int __user *buf, unsigned int size) +{ + static const struct { + int op; + int perm; + } pairs[] = { + {SNDRV_CTL_TLV_OP_READ, SNDRV_CTL_ELEM_ACCESS_TLV_READ}, + {SNDRV_CTL_TLV_OP_WRITE, SNDRV_CTL_ELEM_ACCESS_TLV_WRITE}, + {SNDRV_CTL_TLV_OP_CMD, SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND}, + }; + struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)]; + int i; + + /* Check support of the request for this element. */ + for (i = 0; i < ARRAY_SIZE(pairs); ++i) { + if (op_flag == pairs[i].op && (vd->access & pairs[i].perm)) + break; + } + if (i == ARRAY_SIZE(pairs)) + return -ENXIO; + + if (kctl->tlv.c == NULL) + return -ENXIO; + + /* When locked, this is unavailable. */ + if (vd->owner != NULL && vd->owner != file) + return -EPERM; + + return kctl->tlv.c(kctl, op_flag, size, buf); +} + +static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id, + unsigned int __user *buf, unsigned int size) +{ + struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)]; + unsigned int len; + + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)) + return -ENXIO; + + if (kctl->tlv.p == NULL) + return -ENXIO; + + len = sizeof(unsigned int) * 2 + kctl->tlv.p[1]; + if (size < len) + return -ENOMEM; + + if (copy_to_user(buf, kctl->tlv.p, len)) + return -EFAULT; + + return 0; +} + static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, - struct snd_ctl_tlv __user *_tlv, + struct snd_ctl_tlv __user *buf, int op_flag) { - struct snd_card *card = file->card; - struct snd_ctl_tlv tlv; + struct snd_ctl_tlv header; + unsigned int *container; + unsigned int container_size; struct snd_kcontrol *kctl; + struct snd_ctl_elem_id id; struct snd_kcontrol_volatile *vd; - unsigned int len; - int err = 0; - if (copy_from_user(&tlv, _tlv, sizeof(tlv))) + if (copy_from_user(&header, buf, sizeof(header))) return -EFAULT; - if (tlv.length < sizeof(unsigned int) * 2) + + /* In design of control core, numerical ID starts at 1. */ + if (header.numid == 0) return -EINVAL; - if (!tlv.numid) + + /* At least, container should include type and length fields. */ + if (header.length < sizeof(unsigned int) * 2) return -EINVAL; - down_read(&card->controls_rwsem); - kctl = snd_ctl_find_numid(card, tlv.numid); - if (kctl == NULL) { - err = -ENOENT; - goto __kctl_end; - } - if (kctl->tlv.p == NULL) { - err = -ENXIO; - goto __kctl_end; - } - vd = &kctl->vd[tlv.numid - kctl->id.numid]; - if ((op_flag == SNDRV_CTL_TLV_OP_READ && - (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) || - (op_flag == SNDRV_CTL_TLV_OP_WRITE && - (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) || - (op_flag == SNDRV_CTL_TLV_OP_CMD && - (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) { - err = -ENXIO; - goto __kctl_end; - } + container_size = header.length; + container = buf->tlv; + + kctl = snd_ctl_find_numid(file->card, header.numid); + if (kctl == NULL) + return -ENOENT; + + /* Calculate index of the element in this set. */ + id = kctl->id; + snd_ctl_build_ioff(&id, kctl, header.numid - id.numid); + vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)]; + if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { - if (vd->owner != NULL && vd->owner != file) { - err = -EPERM; - goto __kctl_end; - } - err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); - if (err > 0) { - struct snd_ctl_elem_id id = kctl->id; - up_read(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); - return 0; - } + return call_tlv_handler(file, op_flag, kctl, &id, container, + container_size); } else { - if (op_flag != SNDRV_CTL_TLV_OP_READ) { - err = -ENXIO; - goto __kctl_end; + if (op_flag == SNDRV_CTL_TLV_OP_READ) { + return read_tlv_buf(kctl, &id, container, + container_size); } - len = kctl->tlv.p[1] + 2 * sizeof(unsigned int); - if (tlv.length < len) { - err = -ENOMEM; - goto __kctl_end; - } - if (copy_to_user(_tlv->tlv, kctl->tlv.p, len)) - err = -EFAULT; } - __kctl_end: - up_read(&card->controls_rwsem); - return err; + + /* Not supported. */ + return -ENXIO; } static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1511,11 +1572,20 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS: return snd_ctl_subscribe_events(ctl, ip); case SNDRV_CTL_IOCTL_TLV_READ: - return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ); + down_read(&ctl->card->controls_rwsem); + err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ); + up_read(&ctl->card->controls_rwsem); + return err; case SNDRV_CTL_IOCTL_TLV_WRITE: - return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE); + down_write(&ctl->card->controls_rwsem); + err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE); + up_write(&ctl->card->controls_rwsem); + return err; case SNDRV_CTL_IOCTL_TLV_COMMAND: - return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD); + down_write(&ctl->card->controls_rwsem); + err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD); + up_write(&ctl->card->controls_rwsem); + return err; case SNDRV_CTL_IOCTL_POWER: return -ENOPROTOOPT; case SNDRV_CTL_IOCTL_POWER_STATE: diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 1fa70766ffabedea3cd5d3bf20779dfb7e3fcff8..a848836a5de0468534d5eecfd24adf4bc743f9f2 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -111,12 +111,10 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) goto error; - snd_power_lock(ctl->card); err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); - if (err >= 0) - err = snd_ctl_elem_info(ctl, data); - snd_power_unlock(ctl->card); - + if (err < 0) + goto error; + err = snd_ctl_elem_info(ctl, data); if (err < 0) goto error; /* restore info to 32bit */ @@ -315,14 +313,13 @@ static int ctl_elem_read_user(struct snd_card *card, if (err < 0) goto error; - snd_power_lock(card); err = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (err >= 0) - err = snd_ctl_elem_read(card, data); - snd_power_unlock(card); - if (err >= 0) - err = copy_ctl_value_to_user(userdata, valuep, data, - type, count); + if (err < 0) + goto error; + err = snd_ctl_elem_read(card, data); + if (err < 0) + goto error; + err = copy_ctl_value_to_user(userdata, valuep, data, type, count); error: kfree(data); return err; @@ -344,14 +341,13 @@ static int ctl_elem_write_user(struct snd_ctl_file *file, if (err < 0) goto error; - snd_power_lock(card); err = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (err >= 0) - err = snd_ctl_elem_write(card, file, data); - snd_power_unlock(card); - if (err >= 0) - err = copy_ctl_value_to_user(userdata, valuep, data, - type, count); + if (err < 0) + goto error; + err = snd_ctl_elem_write(card, file, data); + if (err < 0) + goto error; + err = copy_ctl_value_to_user(userdata, valuep, data, type, count); error: kfree(data); return err; diff --git a/sound/core/device.c b/sound/core/device.c index 8918838b1999478e2d03b28dd6425005312bba02..cb0e46f66cc9e5c7feeff00b4a7e2d5416d0b2b2 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -128,7 +128,7 @@ void snd_device_disconnect(struct snd_card *card, void *device_data) if (dev) __snd_device_disconnect(dev); else - dev_dbg(card->dev, "device disconnect %p (from %pF), not found\n", + dev_dbg(card->dev, "device disconnect %p (from %pS), not found\n", device_data, __builtin_return_address(0)); } EXPORT_SYMBOL_GPL(snd_device_disconnect); @@ -152,7 +152,7 @@ void snd_device_free(struct snd_card *card, void *device_data) if (dev) __snd_device_free(dev); else - dev_dbg(card->dev, "device free %p (from %pF), not found\n", + dev_dbg(card->dev, "device free %p (from %pS), not found\n", device_data, __builtin_return_address(0)); } EXPORT_SYMBOL(snd_device_free); diff --git a/sound/core/init.c b/sound/core/init.c index b4365bcf28a7345028976e48f81080a2447cb0b4..32ebe2f6bc59667c63624710ecd16695e96d42b5 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -248,13 +248,11 @@ int snd_card_new(struct device *parent, int idx, const char *xid, INIT_LIST_HEAD(&card->devices); init_rwsem(&card->controls_rwsem); rwlock_init(&card->ctl_files_rwlock); - mutex_init(&card->user_ctl_lock); INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); INIT_LIST_HEAD(&card->files_list); #ifdef CONFIG_PM - mutex_init(&card->power_lock); init_waitqueue_head(&card->power_sleep); #endif @@ -979,8 +977,6 @@ EXPORT_SYMBOL(snd_card_file_remove); * Waits until the power-state is changed. * * Return: Zero if successful, or a negative error code. - * - * Note: the power lock must be active before call. */ int snd_power_wait(struct snd_card *card, unsigned int power_state) { @@ -1000,9 +996,7 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state) if (snd_power_get_state(card) == power_state) break; set_current_state(TASK_UNINTERRUPTIBLE); - snd_power_unlock(card); schedule_timeout(30 * HZ); - snd_power_lock(card); } remove_wait_queue(&card->power_sleep, &wait); return result; diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 89c7485519cbf2478d183428215618fb6f47d2ab..7eadb7fd807471666bfd6907934bcb2e5b0b6f6b 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -523,7 +523,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) sprintf(name, "pcm%i%c", pcm->device, pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c'); - if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL) + entry = snd_info_create_card_entry(pcm->card, name, + pcm->card->proc_root); + if (!entry) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { @@ -531,8 +533,8 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) return -ENOMEM; } pstr->proc_root = entry; - - if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { + entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root); + if (entry) { snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -542,8 +544,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) pstr->proc_info_entry = entry; #ifdef CONFIG_SND_PCM_XRUN_DEBUG - if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", - pstr->proc_root)) != NULL) { + entry = snd_info_create_card_entry(pcm->card, "xrun_debug", + pstr->proc_root); + if (entry) { entry->c.text.read = snd_pcm_xrun_debug_read; entry->c.text.write = snd_pcm_xrun_debug_write; entry->mode |= S_IWUSR; @@ -580,7 +583,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) card = substream->pcm->card; sprintf(name, "sub%i", substream->number); - if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL) + entry = snd_info_create_card_entry(card, name, + substream->pstr->proc_root); + if (!entry) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { @@ -588,8 +593,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) return -ENOMEM; } substream->proc_root = entry; - - if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "info", substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_info_read); if (snd_info_register(entry) < 0) { @@ -598,8 +603,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } } substream->proc_info_entry = entry; - - if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "hw_params", + substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_hw_params_read); if (snd_info_register(entry) < 0) { @@ -608,8 +614,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } } substream->proc_hw_params_entry = entry; - - if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "sw_params", + substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_sw_params_read); if (snd_info_register(entry) < 0) { @@ -618,8 +625,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } } substream->proc_sw_params_entry = entry; - - if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "status", + substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_status_read); if (snd_info_register(entry) < 0) { @@ -783,21 +791,27 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, INIT_LIST_HEAD(&pcm->list); if (id) strlcpy(pcm->id, id, sizeof(pcm->id)); - if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { - snd_pcm_free(pcm); - return err; - } - if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) { - snd_pcm_free(pcm); - return err; - } - if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { - snd_pcm_free(pcm); - return err; - } + + err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, + playback_count); + if (err < 0) + goto free_pcm; + + err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count); + if (err < 0) + goto free_pcm; + + err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops); + if (err < 0) + goto free_pcm; + if (rpcm) *rpcm = pcm; return 0; + +free_pcm: + snd_pcm_free(pcm); + return err; } /** @@ -1224,7 +1238,8 @@ static void snd_pcm_proc_init(void) { struct snd_info_entry *entry; - if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { + entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL); + if (entry) { snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 10f537f4d73536f49cdea0b02447a497f7af7b03..b719d0bd833ecb6d7560380db5eb3b78a9b040c4 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -547,6 +547,7 @@ struct snd_pcm_mmap_status_x32 { u32 pad2; /* alignment */ struct timespec tstamp; s32 suspended_state; + s32 pad3; struct timespec audio_tstamp; } __packed; @@ -689,10 +690,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l case SNDRV_PCM_IOCTL_XRUN: case SNDRV_PCM_IOCTL_LINK: case SNDRV_PCM_IOCTL_UNLINK: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return snd_pcm_playback_ioctl1(file, substream, cmd, argp); - else - return snd_pcm_capture_ioctl1(file, substream, cmd, argp); + return snd_pcm_common_ioctl(file, substream, cmd, argp); case SNDRV_PCM_IOCTL_HW_REFINE32: return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); case SNDRV_PCM_IOCTL_HW_PARAMS32: diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 22995cb3bd447ee0744e142b9a6500b706d85853..2fec2feac387d3134833b02d8230f2e3a05ed114 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1830,7 +1830,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, add_wait_queue(&to_check->sleep, &wait); snd_pcm_stream_unlock_irq(substream); up_read(&snd_pcm_link_rwsem); - snd_power_unlock(card); if (runtime->no_period_wakeup) tout = MAX_SCHEDULE_TIMEOUT; else { @@ -1842,7 +1841,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, tout = msecs_to_jiffies(tout * 1000); } tout = schedule_timeout_interruptible(tout); - snd_power_lock(card); down_read(&snd_pcm_link_rwsem); snd_pcm_stream_lock_irq(substream); remove_wait_queue(&to_check->sleep, &wait); @@ -2763,12 +2761,106 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg) runtime->tstamp_type = arg; return 0; } - + +static int snd_pcm_xferi_frames_ioctl(struct snd_pcm_substream *substream, + struct snd_xferi __user *_xferi) +{ + struct snd_xferi xferi; + struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_sframes_t result; + + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; + if (put_user(0, &_xferi->result)) + return -EFAULT; + if (copy_from_user(&xferi, _xferi, sizeof(xferi))) + return -EFAULT; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames); + else + result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames); + __put_user(result, &_xferi->result); + return result < 0 ? result : 0; +} + +static int snd_pcm_xfern_frames_ioctl(struct snd_pcm_substream *substream, + struct snd_xfern __user *_xfern) +{ + struct snd_xfern xfern; + struct snd_pcm_runtime *runtime = substream->runtime; + void *bufs; + snd_pcm_sframes_t result; + + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; + if (runtime->channels > 128) + return -EINVAL; + if (put_user(0, &_xfern->result)) + return -EFAULT; + if (copy_from_user(&xfern, _xfern, sizeof(xfern))) + return -EFAULT; + + bufs = memdup_user(xfern.bufs, sizeof(void *) * runtime->channels); + if (IS_ERR(bufs)) + return PTR_ERR(bufs); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_lib_writev(substream, bufs, xfern.frames); + else + result = snd_pcm_lib_readv(substream, bufs, xfern.frames); + kfree(bufs); + __put_user(result, &_xfern->result); + return result < 0 ? result : 0; +} + +static int snd_pcm_rewind_ioctl(struct snd_pcm_substream *substream, + snd_pcm_uframes_t __user *_frames) +{ + snd_pcm_uframes_t frames; + snd_pcm_sframes_t result; + + if (get_user(frames, _frames)) + return -EFAULT; + if (put_user(0, _frames)) + return -EFAULT; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_playback_rewind(substream, frames); + else + result = snd_pcm_capture_rewind(substream, frames); + __put_user(result, _frames); + return result < 0 ? result : 0; +} + +static int snd_pcm_forward_ioctl(struct snd_pcm_substream *substream, + snd_pcm_uframes_t __user *_frames) +{ + snd_pcm_uframes_t frames; + snd_pcm_sframes_t result; + + if (get_user(frames, _frames)) + return -EFAULT; + if (put_user(0, _frames)) + return -EFAULT; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_playback_forward(substream, frames); + else + result = snd_pcm_capture_forward(substream, frames); + __put_user(result, _frames); + return result < 0 ? result : 0; +} + static int snd_pcm_common_ioctl(struct file *file, struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_file *pcm_file = file->private_data; + int res; + + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; + + res = snd_power_wait(substream->pcm->card, SNDRV_CTL_POWER_D0); + if (res < 0) + return res; switch (cmd) { case SNDRV_PCM_IOCTL_PVERSION: @@ -2841,202 +2933,23 @@ static int snd_pcm_common_ioctl(struct file *file, return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream, (int)(unsigned long)arg); - } - pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd); - return -ENOTTY; -} - -static int snd_pcm_common_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - struct snd_card *card = substream->pcm->card; - int res; - - snd_power_lock(card); - res = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (res >= 0) - res = snd_pcm_common_ioctl(file, substream, cmd, arg); - snd_power_unlock(card); - return res; -} - -static int snd_pcm_playback_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) - return -EINVAL; - switch (cmd) { case SNDRV_PCM_IOCTL_WRITEI_FRAMES: - { - struct snd_xferi xferi; - struct snd_xferi __user *_xferi = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (put_user(0, &_xferi->result)) - return -EFAULT; - if (copy_from_user(&xferi, _xferi, sizeof(xferi))) - return -EFAULT; - result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames); - __put_user(result, &_xferi->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_WRITEN_FRAMES: - { - struct snd_xfern xfern; - struct snd_xfern __user *_xfern = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - void __user **bufs; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (runtime->channels > 128) - return -EINVAL; - if (put_user(0, &_xfern->result)) - return -EFAULT; - if (copy_from_user(&xfern, _xfern, sizeof(xfern))) - return -EFAULT; - - bufs = memdup_user(xfern.bufs, - sizeof(void *) * runtime->channels); - if (IS_ERR(bufs)) - return PTR_ERR(bufs); - result = snd_pcm_lib_writev(substream, bufs, xfern.frames); - kfree(bufs); - __put_user(result, &_xfern->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_REWIND: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_playback_rewind(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_FORWARD: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_playback_forward(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - } - return snd_pcm_common_ioctl1(file, substream, cmd, arg); -} - -static int snd_pcm_capture_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) - return -EINVAL; - switch (cmd) { case SNDRV_PCM_IOCTL_READI_FRAMES: - { - struct snd_xferi xferi; - struct snd_xferi __user *_xferi = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (put_user(0, &_xferi->result)) - return -EFAULT; - if (copy_from_user(&xferi, _xferi, sizeof(xferi))) - return -EFAULT; - result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames); - __put_user(result, &_xferi->result); - return result < 0 ? result : 0; - } + return snd_pcm_xferi_frames_ioctl(substream, arg); + case SNDRV_PCM_IOCTL_WRITEN_FRAMES: case SNDRV_PCM_IOCTL_READN_FRAMES: - { - struct snd_xfern xfern; - struct snd_xfern __user *_xfern = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - void *bufs; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (runtime->channels > 128) - return -EINVAL; - if (put_user(0, &_xfern->result)) - return -EFAULT; - if (copy_from_user(&xfern, _xfern, sizeof(xfern))) - return -EFAULT; - - bufs = memdup_user(xfern.bufs, - sizeof(void *) * runtime->channels); - if (IS_ERR(bufs)) - return PTR_ERR(bufs); - result = snd_pcm_lib_readv(substream, bufs, xfern.frames); - kfree(bufs); - __put_user(result, &_xfern->result); - return result < 0 ? result : 0; - } + return snd_pcm_xfern_frames_ioctl(substream, arg); case SNDRV_PCM_IOCTL_REWIND: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_capture_rewind(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } + return snd_pcm_rewind_ioctl(substream, arg); case SNDRV_PCM_IOCTL_FORWARD: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_capture_forward(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } + return snd_pcm_forward_ioctl(substream, arg); } - return snd_pcm_common_ioctl1(file, substream, cmd, arg); -} - -static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct snd_pcm_file *pcm_file; - - pcm_file = file->private_data; - - if (((cmd >> 8) & 0xff) != 'A') - return -ENOTTY; - - return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd, - (void __user *)arg); + pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd); + return -ENOTTY; } -static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) +static long snd_pcm_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct snd_pcm_file *pcm_file; @@ -3045,8 +2958,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, if (((cmd >> 8) & 0xff) != 'A') return -ENOTTY; - return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd, - (void __user *)arg); + return snd_pcm_common_ioctl(file, pcm_file->substream, cmd, + (void __user *)arg); } /** @@ -3787,7 +3700,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .release = snd_pcm_release, .llseek = no_llseek, .poll = snd_pcm_playback_poll, - .unlocked_ioctl = snd_pcm_playback_ioctl, + .unlocked_ioctl = snd_pcm_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, @@ -3801,7 +3714,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .release = snd_pcm_release, .llseek = no_llseek, .poll = snd_pcm_capture_poll, - .unlocked_ioctl = snd_pcm_capture_ioctl, + .unlocked_ioctl = snd_pcm_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, diff --git a/sound/core/seq/Kconfig b/sound/core/seq/Kconfig index a536760a94c26521a04cbe4233b1d5fa4b69e625..45c1336c6597f1b49a343b8629613fb979b0ef8b 100644 --- a/sound/core/seq/Kconfig +++ b/sound/core/seq/Kconfig @@ -47,10 +47,10 @@ config SND_SEQ_HRTIMER_DEFAULT timer. config SND_SEQ_MIDI_EVENT - def_tristate SND_RAWMIDI + tristate config SND_SEQ_MIDI - tristate + def_tristate SND_RAWMIDI select SND_SEQ_MIDI_EVENT config SND_SEQ_MIDI_EMUL diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 272c55fe17c88aec700a7552da4473349c4ce359..ea2d0ae85bd367d5ea70068ee74d925a349789c3 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1502,16 +1502,11 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) { struct snd_seq_queue_info *info = arg; - int result; struct snd_seq_queue *q; - result = snd_seq_queue_alloc(client->number, info->locked, info->flags); - if (result < 0) - return result; - - q = queueptr(result); - if (q == NULL) - return -EINVAL; + q = snd_seq_queue_alloc(client->number, info->locked, info->flags); + if (IS_ERR(q)) + return PTR_ERR(q); info->queue = q->queue; info->locked = q->locked; @@ -1521,7 +1516,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) if (!info->name[0]) snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); strlcpy(q->name, info->name, sizeof(q->name)); - queuefree(q); + snd_use_lock_free(&q->use_lock); return 0; } diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 450c5187eecb6bb083736d2d2a1aad43b98c7c3f..79e0c5604ef806d62eca084293e66222b8fe6828 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void) static void queue_use(struct snd_seq_queue *queue, int client, int use); /* allocate a new queue - - * return queue index value or negative value for error + * return pointer to new queue or ERR_PTR(-errno) for error + * The new queue's use_lock is set to 1. It is the caller's responsibility to + * call snd_use_lock_free(&q->use_lock). */ -int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) +struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) { struct snd_seq_queue *q; q = queue_new(client, locked); if (q == NULL) - return -ENOMEM; + return ERR_PTR(-ENOMEM); q->info_flags = info_flags; queue_use(q, client, 1); + snd_use_lock_use(&q->use_lock); if (queue_list_add(q) < 0) { + snd_use_lock_free(&q->use_lock); queue_delete(q); - return -ENOMEM; + return ERR_PTR(-ENOMEM); } - return q->queue; + return q; } /* delete a queue - queue must be owned by the client */ diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 30c8111477f61ed26987dc03abbe9670b36db221..719093489a2c4eec57fed70d4ba2b862cb64a9cf 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h @@ -71,7 +71,7 @@ void snd_seq_queues_delete(void); /* create new queue (constructor) */ -int snd_seq_queue_alloc(int client, int locked, unsigned int flags); +struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags); /* delete queue (destructor) */ int snd_seq_queue_delete(int client, int queueid); diff --git a/sound/core/seq_device.c b/sound/core/seq_device.c index c4acf17e9f5e50183bd3cb1226ec289f19be3843..e40a2cba5002a817876252074c91de620c6dbce2 100644 --- a/sound/core/seq_device.c +++ b/sound/core/seq_device.c @@ -148,8 +148,10 @@ void snd_seq_device_load_drivers(void) flush_work(&autoload_work); } EXPORT_SYMBOL(snd_seq_device_load_drivers); +#define cancel_autoload_drivers() cancel_work_sync(&autoload_work) #else #define queue_autoload_drivers() /* NOP */ +#define cancel_autoload_drivers() /* NOP */ #endif /* @@ -159,6 +161,7 @@ static int snd_seq_device_dev_free(struct snd_device *device) { struct snd_seq_device *dev = device->device_data; + cancel_autoload_drivers(); put_device(&dev->dev); return 0; } diff --git a/sound/core/timer.c b/sound/core/timer.c index a9b9a277e00c1bda4bd85038cc45842ac2425ee0..6cdd04a459626c86f185742d099ab16729b7d517 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -393,7 +393,8 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) if (timeri == NULL) return 0; - if ((timer = timeri->timer) != NULL) { + timer = timeri->timer; + if (timer) { if (timer->hw.c_resolution) return timer->hw.c_resolution(timer); return timer->hw.resolution; @@ -2096,8 +2097,7 @@ static int __init alsa_timer_init(void) err = snd_timer_register_system(); if (err < 0) { pr_err("ALSA: unable to register system timer (%i)\n", err); - put_device(&timer_dev); - return err; + goto put_timer; } err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0, @@ -2105,12 +2105,15 @@ static int __init alsa_timer_init(void) if (err < 0) { pr_err("ALSA: unable to register timer device (%i)\n", err); snd_timer_free_all(); - put_device(&timer_dev); - return err; + goto put_timer; } snd_timer_proc_init(); return 0; + +put_timer: + put_device(&timer_dev); + return err; } static void __exit alsa_timer_exit(void) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 54f348a4fb7811b5c9e4f13f4ace902d0fb845da..135adb17703cc4992e127f9dc881db1b715206c4 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -561,7 +561,7 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream) return bytes_to_frames(runtime, pos); } -static struct snd_pcm_hardware loopback_pcm_hardware = +static const struct snd_pcm_hardware loopback_pcm_hardware = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | @@ -750,7 +750,7 @@ static int loopback_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops loopback_playback_ops = { +static const struct snd_pcm_ops loopback_playback_ops = { .open = loopback_open, .close = loopback_close, .ioctl = snd_pcm_lib_ioctl, @@ -763,7 +763,7 @@ static struct snd_pcm_ops loopback_playback_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops loopback_capture_ops = { +static const struct snd_pcm_ops loopback_capture_ops = { .open = loopback_open, .close = loopback_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index dd5ed037adf2bb3a6fbaeacff681aaa77b56c4b2..c0939a0164a6ff4c378ffe0863e5b7e265cf46c4 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -520,7 +520,7 @@ static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) return get_dummy_ops(substream)->pointer(substream); } -static struct snd_pcm_hardware dummy_pcm_hardware = { +static const struct snd_pcm_hardware dummy_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index bdcb5721393b1b326497e7a9e4fa43c60a2c3ee5..18fd12996cf70c2cb8480684429370c17cc80e3a 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c @@ -373,7 +373,7 @@ struct snd_ml403_ac97cr { struct snd_pcm_indirect2 capture_ind2_rec; }; -static struct snd_pcm_hardware snd_ml403_ac97cr_playback = { +static const struct snd_pcm_hardware snd_ml403_ac97cr_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -392,7 +392,7 @@ static struct snd_pcm_hardware snd_ml403_ac97cr_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ml403_ac97cr_capture = { +static const struct snd_pcm_hardware snd_ml403_ac97cr_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -759,7 +759,7 @@ static int snd_ml403_ac97cr_capture_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = { +static const struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = { .open = snd_ml403_ac97cr_playback_open, .close = snd_ml403_ac97cr_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -770,7 +770,7 @@ static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = { .pointer = snd_ml403_ac97cr_pcm_pointer, }; -static struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = { +static const struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = { .open = snd_ml403_ac97cr_capture_open, .close = snd_ml403_ac97cr_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 9b86e00d7d95ffada3ac89b52671be20a2d30d38..b6715764cd1c3a3e30536ac57d46d560d369849b 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -148,7 +148,7 @@ static struct platform_driver snd_mpu401_driver = { #define IO_EXTENT 2 -static struct pnp_device_id snd_mpu401_pnpids[] = { +static const struct pnp_device_id snd_mpu401_pnpids[] = { { .id = "PNPb006" }, { .id = "" } }; diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 3a7c317ae012ab18e1172d5cc795f64db7afb953..b997222274bd96c4ea88aa0fc83cd6b2cc8567f7 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -136,7 +136,7 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id) { struct snd_mpu401 *mpu = dev_id; - if (mpu == NULL) + if (!mpu) return IRQ_NONE; _snd_mpu401_uart_interrupt(mpu); return IRQ_HANDLED; @@ -157,7 +157,7 @@ irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id) { struct snd_mpu401 *mpu = dev_id; - if (mpu == NULL) + if (!mpu) return IRQ_NONE; uart_interrupt_tx(mpu); return IRQ_HANDLED; @@ -544,10 +544,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, out_enable, in_enable, &rmidi)) < 0) return err; mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); - if (mpu == NULL) { - snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n"); - snd_device_free(card, rmidi); - return -ENOMEM; + if (!mpu) { + err = -ENOMEM; + goto free_device; } rmidi->private_data = mpu; rmidi->private_free = snd_mpu401_uart_free; @@ -559,12 +558,12 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, if (! (info_flags & MPU401_INFO_INTEGRATED)) { int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; mpu->res = request_region(port, res_size, "MPU401 UART"); - if (mpu->res == NULL) { + if (!mpu->res) { snd_printk(KERN_ERR "mpu401_uart: " "unable to grab port 0x%lx size %d\n", port, res_size); - snd_device_free(card, rmidi); - return -EBUSY; + err = -EBUSY; + goto free_device; } } if (info_flags & MPU401_INFO_MMIO) { @@ -584,8 +583,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, "MPU401 UART", (void *) mpu)) { snd_printk(KERN_ERR "mpu401_uart: " "unable to grab IRQ %d\n", irq); - snd_device_free(card, rmidi); - return -EBUSY; + err = -EBUSY; + goto free_device; } } if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK)) @@ -613,6 +612,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, if (rrawmidi) *rrawmidi = rmidi; return 0; +free_device: + snd_device_free(card, rmidi); + return err; } EXPORT_SYMBOL(snd_mpu401_uart_new); diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index d5e5b4657b4ba966501fbf53e5d77f3f59fe53e2..588963d6be281daac008fdfe70cdfcc058c9df86 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c @@ -355,10 +355,8 @@ int snd_opl3_new(struct snd_card *card, *ropl3 = NULL; opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL); - if (opl3 == NULL) { - snd_printk(KERN_ERR "opl3: cannot allocate\n"); + if (!opl3) return -ENOMEM; - } opl3->card = card; opl3->hardware = hardware; diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 7821b07415a785c70982e03803ac34601770e3a9..13c0a7e1bc2b050c2d0a3e98bd1d08cbe5bf7f1a 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -131,8 +131,8 @@ static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) { printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice); for (i = 0; i < opl3->max_voices; i++) - printk("%c", *(str + opl3->voices[i].state + 1)); - printk("\n"); + printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1)); + printk(KERN_CONT "\n"); } #endif diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 72e2d0012084730498123aee36ca4d35bb3a2a7e..0dd3f46eb03e804da8f8af663d3e270a96dc6aa1 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c @@ -108,22 +108,17 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev) return err; err = snd_pcsp_create(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; + if (!nopcm) { err = snd_pcsp_new_pcm(&pcsp_chip); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; } err = snd_pcsp_new_mixer(&pcsp_chip, nopcm); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; strcpy(card->driver, "PC-Speaker"); strcpy(card->shortname, "pcsp"); @@ -131,12 +126,14 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev) pcsp_chip.port); err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; return 0; + +free_card: + snd_card_free(card); + return err; } static int alsa_card_pcsp_init(struct device *dev) diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index 44b3632f6940c4713ed49f67612d21c3e52b2b43..2f5a35f38ce1b3b1c3426cecff3d714a9dae74de 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -285,7 +285,7 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream return bytes_to_frames(substream->runtime, pos); } -static struct snd_pcm_hardware snd_pcsp_playback = { +static const struct snd_pcm_hardware snd_pcsp_playback = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_HALF_DUPLEX | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index f684fffd1397552096fda2f74c45a97e173469d7..121357397a6d5388c00639514df1b64b7ebe9f18 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -256,8 +256,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) if (rmh->LgCmd > 1) { printk(KERN_DEBUG " "); for (i = 1; i < rmh->LgCmd; i++) - printk("0x%06x ", rmh->Cmd[i]); - printk("\n"); + printk(KERN_CONT "0x%06x ", rmh->Cmd[i]); + printk(KERN_CONT "\n"); } #endif /* Check bit M is set according to length of the command */ diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index d318a33b6cfbf860985163e7bfac8933a3905fd5..380a028469c44ad033ccdb6cd65a38a562e9417e 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -500,7 +500,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe) * playback hw information */ -static struct snd_pcm_hardware vx_pcm_playback_hw = { +static const struct snd_pcm_hardware vx_pcm_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/ /*SNDRV_PCM_INFO_RESUME*/), @@ -891,7 +891,7 @@ static const struct snd_pcm_ops vx_pcm_playback_ops = { * playback hw information */ -static struct snd_pcm_hardware vx_pcm_capture_hw = { +static const struct snd_pcm_hardware vx_pcm_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/ /*SNDRV_PCM_INFO_RESUME*/), diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h index 17678d6ab5a2d9b93e7a318c382c4f58ec1805d5..df1b1e94c43c94b82044a55801a0846efac6c1b3 100644 --- a/sound/firewire/bebob/bebob.h +++ b/sound/firewire/bebob/bebob.h @@ -58,7 +58,7 @@ enum snd_bebob_clock_type { struct snd_bebob_clock_spec { unsigned int num; const char *const *labels; - enum snd_bebob_clock_type *types; + const enum snd_bebob_clock_type *types; int (*get)(struct snd_bebob *bebob, unsigned int *id); }; struct snd_bebob_rate_spec { diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c index f1109005794944cd759b90ede92a6fc601ab251e..52b8b61ecddd2d6a467992e7c5cc48b66df6ea21 100644 --- a/sound/firewire/bebob/bebob_focusrite.c +++ b/sound/firewire/bebob/bebob_focusrite.c @@ -103,12 +103,12 @@ saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) &data, sizeof(__be32), 0); } -static enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = { +static const enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */ }; -static enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = { +static const enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* ADAT1 */ @@ -201,7 +201,7 @@ saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) } const struct snd_bebob_spec saffire_le_spec; -static enum snd_bebob_clock_type saffire_both_clk_src_types[] = { +static const enum snd_bebob_clock_type saffire_both_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, }; diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c index d10208f92edfa520ef68579f6961f5e36791bf5a..bd55620c6a479315f6787eb26de2c73bf4913eb6 100644 --- a/sound/firewire/bebob/bebob_maudio.c +++ b/sound/firewire/bebob/bebob_maudio.c @@ -340,7 +340,7 @@ static int special_set_rate(struct snd_bebob *bebob, unsigned int rate) } /* Clock source control for special firmware */ -static enum snd_bebob_clock_type special_clk_types[] = { +static const enum snd_bebob_clock_type special_clk_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, /* With digital mute */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* SPDIF/ADAT */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */ diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c index 2fdaf93e7a8d3d69d8fa28e91a611c8776b52e76..9770c2127a7a589d8497595f45c59bc4c5c195ee 100644 --- a/sound/firewire/bebob/bebob_terratec.c +++ b/sound/firewire/bebob/bebob_terratec.c @@ -8,7 +8,7 @@ #include "./bebob.h" -static enum snd_bebob_clock_type phase88_rack_clk_src_types[] = { +static const enum snd_bebob_clock_type phase88_rack_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */ diff --git a/sound/firewire/bebob/bebob_yamaha_terratec.c b/sound/firewire/bebob/bebob_yamaha_terratec.c index a6be3e7138e0586cfac6c6ee2b9e67906894f4aa..8bd78fef3516251d17fb56a64b244dfed2b4daea 100644 --- a/sound/firewire/bebob/bebob_yamaha_terratec.c +++ b/sound/firewire/bebob/bebob_yamaha_terratec.c @@ -31,7 +31,7 @@ * Yamaha GO 44 and GO 46. Yamaha and Terratec had cooperated for these models. */ -static enum snd_bebob_clock_type clk_src_types[] = { +static const enum snd_bebob_clock_type clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ }; diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 25e9f77275c4dd6ef6a39da8e9f77294f86f876c..4ddb4cdd054b860142da4356dc6abeef44b4c698 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c @@ -26,7 +26,7 @@ MODULE_LICENSE("GPL v2"); */ static bool force_two_pcm_support(struct fw_unit *unit) { - const char *const models[] = { + static const char *const models[] = { /* TC Electronic models. */ "StudioKonnekt48", /* Focusrite models. */ diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c index d12a0e3a42194cb3d728a910e9592a79671bab39..e3c16308363d62ae135b379faf592166a15e8b85 100644 --- a/sound/firewire/fireface/ff-pcm.c +++ b/sound/firewire/fireface/ff-pcm.c @@ -138,16 +138,12 @@ static int pcm_open(struct snd_pcm_substream *substream) return err; err = pcm_init_hw_params(ff, substream); - if (err < 0) { - snd_ff_stream_lock_release(ff); - return err; - } + if (err < 0) + goto release_lock; err = ff->spec->protocol->get_clock(ff, &rate, &src); - if (err < 0) { - snd_ff_stream_lock_release(ff); - return err; - } + if (err < 0) + goto release_lock; if (src != SND_FF_CLOCK_SRC_INTERNAL) { for (i = 0; i < CIP_SFC_COUNT; ++i) { @@ -159,8 +155,8 @@ static int pcm_open(struct snd_pcm_substream *substream) * streaming engine can't support. */ if (i >= CIP_SFC_COUNT) { - snd_ff_stream_lock_release(ff); - return -EIO; + err = -EIO; + goto release_lock; } substream->runtime->hw.rate_min = rate; @@ -177,6 +173,10 @@ static int pcm_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); return 0; + +release_lock: + snd_ff_stream_lock_release(ff); + return err; } static int pcm_close(struct snd_pcm_substream *substream) diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c index fcec6de80eebc724e3f59c7761c783f6371aa804..12aa15df435d1cca2bf6f3cf42b60704b2340004 100644 --- a/sound/firewire/fireface/ff-protocol-ff400.c +++ b/sound/firewire/fireface/ff-protocol-ff400.c @@ -356,7 +356,7 @@ static void ff400_dump_clock_config(struct snd_ff *ff, snd_iprintf(buffer, "Sync to clock source: %s\n", src); } -struct snd_ff_protocol snd_ff_protocol_ff400 = { +const struct snd_ff_protocol snd_ff_protocol_ff400 = { .get_clock = ff400_get_clock, .begin_session = ff400_begin_session, .finish_session = ff400_finish_session, diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c index eee7c8eac7a61908b53dfa0862b0ca0b5e98ab2a..4974bc7980e9b476611d78cc79a48275259a12b9 100644 --- a/sound/firewire/fireface/ff.c +++ b/sound/firewire/fireface/ff.c @@ -157,7 +157,7 @@ static void snd_ff_remove(struct fw_unit *unit) } } -static struct snd_ff_spec spec_ff400 = { +static const struct snd_ff_spec spec_ff400 = { .name = "Fireface400", .pcm_capture_channels = {18, 14, 10}, .pcm_playback_channels = {18, 14, 10}, diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 3cb812a500305eaa45d9cb3dcfad77a85eff2687..64df44beb95058ab42f51d195edc4f6497edea88 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -47,7 +47,7 @@ struct snd_ff_spec { unsigned int midi_in_ports; unsigned int midi_out_ports; - struct snd_ff_protocol *protocol; + const struct snd_ff_protocol *protocol; }; struct snd_ff { @@ -112,7 +112,7 @@ struct snd_ff_protocol { u64 midi_rx_port_1_reg; }; -extern struct snd_ff_protocol snd_ff_protocol_ff400; +extern const struct snd_ff_protocol snd_ff_protocol_ff400; int snd_ff_transaction_register(struct snd_ff *ff); int snd_ff_transaction_reregister(struct snd_ff *ff); diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c index beb0a0ffee57c4cfbb72845dd16a6f27b1c165ba..9c21f31b8b21c9f05ceaabcf0ce49cc86eb46681 100644 --- a/sound/firewire/fireworks/fireworks_proc.c +++ b/sound/firewire/fireworks/fireworks_proc.c @@ -12,7 +12,7 @@ static inline const char* get_phys_name(struct snd_efw_phys_grp *grp, bool input) { - const char *const ch_type[] = { + static const char *const ch_type[] = { "Analog", "S/PDIF", "ADAT", "S/PDIF or ADAT", "Mirroring", "Headphones", "I2S", "Guitar", "Pirzo Guitar", "Guitar String", }; diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 48d6dca471c6bc5713cd7a6ee7bc466c008a1997..5826aa8362f10b319c5946054c73107fef5f963f 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c @@ -444,7 +444,7 @@ static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream) static int isight_create_pcm(struct isight *isight) { - static struct snd_pcm_ops ops = { + static const struct snd_pcm_ops ops = { .open = isight_open, .close = isight_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c index f0e4d502d60482ae8374cf9f830b739eb9e38753..066b5df666f42d2259b40ee5d21492f9165e4470 100644 --- a/sound/firewire/iso-resources.c +++ b/sound/firewire/iso-resources.c @@ -210,9 +210,14 @@ EXPORT_SYMBOL(fw_iso_resources_update); */ void fw_iso_resources_free(struct fw_iso_resources *r) { - struct fw_card *card = fw_parent_device(r->unit)->card; + struct fw_card *card; int bandwidth, channel; + /* Not initialized. */ + if (r->unit == NULL) + return; + card = fw_parent_device(r->unit)->card; + mutex_lock(&r->mutex); if (r->allocated) { diff --git a/sound/firewire/motu/motu-midi.c b/sound/firewire/motu/motu-midi.c index e3acfcc53f4e3a02b4393dc3e8c97b46be3a68ef..e55cab6d79c7df91d72b6837def3a1bdb1b6bdca 100644 --- a/sound/firewire/motu/motu-midi.c +++ b/sound/firewire/motu/motu-midi.c @@ -128,12 +128,12 @@ static void set_midi_substream_names(struct snd_motu *motu, int snd_motu_create_midi_devices(struct snd_motu *motu) { - static struct snd_rawmidi_ops capture_ops = { + static const struct snd_rawmidi_ops capture_ops = { .open = midi_capture_open, .close = midi_capture_close, .trigger = midi_capture_trigger, }; - static struct snd_rawmidi_ops playback_ops = { + static const struct snd_rawmidi_ops playback_ops = { .open = midi_playback_open, .close = midi_playback_close, .trigger = midi_playback_trigger, diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c index a2b50df708743f4fce0f16303ac195a3e33ea512..4330220890e8a9b6080bd8bc30c318416215807b 100644 --- a/sound/firewire/motu/motu-pcm.c +++ b/sound/firewire/motu/motu-pcm.c @@ -145,7 +145,7 @@ static int pcm_open(struct snd_pcm_substream *substream) mutex_lock(&motu->mutex); - err = protocol->cache_packet_formats(motu); + err = snd_motu_stream_cache_packet_formats(motu); if (err < 0) goto err_locked; @@ -352,7 +352,7 @@ static int playback_ack(struct snd_pcm_substream *substream) int snd_motu_create_pcm_devices(struct snd_motu *motu) { - static struct snd_pcm_ops capture_ops = { + static const struct snd_pcm_ops capture_ops = { .open = pcm_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -365,7 +365,7 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu) .page = snd_pcm_lib_get_vmalloc_page, .mmap = snd_pcm_lib_mmap_vmalloc, }; - static struct snd_pcm_ops playback_ops = { + static const struct snd_pcm_ops playback_ops = { .open = pcm_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 05b5d287c2f3ddd3b1e0c8d9d0287fd05d7629f3..525b746330bebe2e5b878c229ad35e4931807458 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -217,12 +217,7 @@ static int v2_cache_packet_formats(struct snd_motu *motu) calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags, data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT); - motu->tx_packet_formats.midi_flag_offset = 4; - motu->tx_packet_formats.midi_byte_offset = 6; motu->tx_packet_formats.pcm_byte_offset = 10; - - motu->rx_packet_formats.midi_flag_offset = 4; - motu->rx_packet_formats.midi_byte_offset = 6; motu->rx_packet_formats.pcm_byte_offset = 10; return 0; diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index ddb647254ed224b860f0ae75b372cc32f7f91383..c7cd9864dc4d23b686c2e55059da6d1b8551c7c2 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -291,12 +291,7 @@ static int v3_cache_packet_formats(struct snd_motu *motu) V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A, V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B); - motu->tx_packet_formats.midi_flag_offset = 8; - motu->tx_packet_formats.midi_byte_offset = 7; motu->tx_packet_formats.pcm_byte_offset = 10; - - motu->rx_packet_formats.midi_flag_offset = 8; - motu->rx_packet_formats.midi_byte_offset = 7; motu->rx_packet_formats.pcm_byte_offset = 10; return 0; diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c index bd458029099e35f1872af4a53f3759e188302226..73e7a5e527fc02445cab88df91f81c4ceae883f2 100644 --- a/sound/firewire/motu/motu-stream.c +++ b/sound/firewire/motu/motu-stream.c @@ -33,7 +33,8 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate) u32 data; int err; - if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) + if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q)) midi_ports = 1; /* Set packet formation to our packet streaming engine. */ @@ -42,6 +43,12 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate) if (err < 0) return err; + if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) + midi_ports = 1; + else + midi_ports = 0; + err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports, &motu->tx_packet_formats); if (err < 0) @@ -141,6 +148,33 @@ static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream) fw_iso_resources_free(resources); } +int snd_motu_stream_cache_packet_formats(struct snd_motu *motu) +{ + int err; + + err = motu->spec->protocol->cache_packet_formats(motu); + if (err < 0) + return err; + + if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) { + motu->tx_packet_formats.midi_flag_offset = 4; + motu->tx_packet_formats.midi_byte_offset = 6; + } else if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q) { + motu->tx_packet_formats.midi_flag_offset = 8; + motu->tx_packet_formats.midi_byte_offset = 7; + } + + if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) { + motu->rx_packet_formats.midi_flag_offset = 4; + motu->rx_packet_formats.midi_byte_offset = 6; + } else if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) { + motu->rx_packet_formats.midi_flag_offset = 8; + motu->rx_packet_formats.midi_byte_offset = 7; + } + + return 0; +} + static int ensure_packet_formats(struct snd_motu *motu) { __be32 reg; @@ -184,7 +218,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) stop_both_streams(motu); } - err = protocol->cache_packet_formats(motu); + err = snd_motu_stream_cache_packet_formats(motu); if (err < 0) return err; @@ -219,24 +253,21 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) if (err < 0) { dev_err(&motu->unit->device, "fail to start isochronous comm: %d\n", err); - stop_both_streams(motu); - return err; + goto stop_streams; } err = start_isoc_ctx(motu, &motu->rx_stream); if (err < 0) { dev_err(&motu->unit->device, "fail to start IT context: %d\n", err); - stop_both_streams(motu); - return err; + goto stop_streams; } err = protocol->switch_fetching_mode(motu, true); if (err < 0) { dev_err(&motu->unit->device, "fail to enable frame fetching: %d\n", err); - stop_both_streams(motu); - return err; + goto stop_streams; } } @@ -247,12 +278,15 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) dev_err(&motu->unit->device, "fail to start IR context: %d", err); amdtp_stream_stop(&motu->rx_stream); - stop_both_streams(motu); - return err; + goto stop_streams; } } return 0; + +stop_streams: + stop_both_streams(motu); + return err; } void snd_motu_stream_stop_duplex(struct snd_motu *motu) diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index bf779cfeef0dfaea62ea5684997314a9fe02d4c0..0d6b526105ab08b8e905f2988548d3662ff37302 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -103,7 +103,10 @@ static void do_registration(struct work_struct *work) if (err < 0) goto error; - if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) { + if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) || + (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) { err = snd_motu_create_midi_devices(motu); if (err < 0) goto error; @@ -128,6 +131,7 @@ static void do_registration(struct work_struct *work) return; error: snd_motu_transaction_unregister(motu); + snd_motu_stream_destroy_duplex(motu); snd_card_free(motu->card); dev_info(&motu->unit->device, "Sound card registration failed: %d\n", err); @@ -190,20 +194,21 @@ static void motu_bus_update(struct fw_unit *unit) snd_motu_transaction_reregister(motu); } -static struct snd_motu_spec motu_828mk2 = { +static const struct snd_motu_spec motu_828mk2 = { .name = "828mk2", .protocol = &snd_motu_protocol_v2, .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | SND_MOTU_SPEC_HAS_OPT_IFACE_A | - SND_MOTU_SPEC_HAS_MIDI, + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_2ND_Q, .analog_in_ports = 8, .analog_out_ports = 8, }; -static struct snd_motu_spec motu_828mk3 = { +static const struct snd_motu_spec motu_828mk3 = { .name = "828mk3", .protocol = &snd_motu_protocol_v3, .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | @@ -213,12 +218,25 @@ static struct snd_motu_spec motu_828mk3 = { SND_MOTU_SPEC_TX_REVERB_CHUNK | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_B | - SND_MOTU_SPEC_HAS_MIDI, + SND_MOTU_SPEC_RX_MIDI_3RD_Q | + SND_MOTU_SPEC_TX_MIDI_3RD_Q, .analog_in_ports = 8, .analog_out_ports = 8, }; +static const struct snd_motu_spec motu_audio_express = { + .name = "AudioExpress", + .protocol = &snd_motu_protocol_v3, + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | + SND_MOTU_SPEC_TX_MICINST_CHUNK | + SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_3RD_Q, + .analog_in_ports = 2, + .analog_out_ports = 4, +}; + #define SND_MOTU_DEV_ENTRY(model, data) \ { \ .match_flags = IEEE1394_MATCH_VENDOR_ID | \ @@ -234,6 +252,7 @@ static const struct ieee1394_device_id motu_id_table[] = { SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2), SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */ SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */ + SND_MOTU_DEV_ENTRY(0x104800, &motu_audio_express), { } }; MODULE_DEVICE_TABLE(ieee1394, motu_id_table); diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 8d6a4a3af9cc136056a380d39cbefbfcc397c4cc..4b23cf337c4bec535172f289186fefb295919697 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -82,7 +82,10 @@ enum snd_motu_spec_flags { SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020, SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, - SND_MOTU_SPEC_HAS_MIDI = 0x0100, + SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100, + SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200, + SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400, + SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800, }; #define SND_MOTU_CLOCK_RATE_COUNT 6 @@ -146,6 +149,7 @@ void snd_motu_transaction_unregister(struct snd_motu *motu); int snd_motu_stream_init_duplex(struct snd_motu *motu); void snd_motu_stream_destroy_duplex(struct snd_motu *motu); +int snd_motu_stream_cache_packet_formats(struct snd_motu *motu); int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate); void snd_motu_stream_stop_duplex(struct snd_motu *motu); int snd_motu_stream_lock_try(struct snd_motu *motu); diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c index 93209ebd91214ed514a43a42e729f31d68e21855..02d5956658987424fdb9ca4ff8b79d68f0b47051 100644 --- a/sound/firewire/oxfw/oxfw-scs1x.c +++ b/sound/firewire/oxfw/oxfw-scs1x.c @@ -297,12 +297,6 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up) } } -static const struct snd_rawmidi_ops midi_capture_ops = { - .open = midi_capture_open, - .close = midi_capture_close, - .trigger = midi_capture_trigger, -}; - static int midi_playback_open(struct snd_rawmidi_substream *stream) { return 0; @@ -363,6 +357,11 @@ void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw) int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw) { + static const struct snd_rawmidi_ops midi_capture_ops = { + .open = midi_capture_open, + .close = midi_capture_close, + .trigger = midi_capture_trigger, + }; static const struct snd_rawmidi_ops midi_playback_ops = { .open = midi_playback_open, .close = midi_playback_close, diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c index 9dc93a7eb9da420fb871d7b28007b67b4d37f261..44ad41fb7374070458de78e991330a744d3f0aff 100644 --- a/sound/firewire/tascam/tascam.c +++ b/sound/firewire/tascam/tascam.c @@ -12,7 +12,7 @@ MODULE_DESCRIPTION("TASCAM FireWire series Driver"); MODULE_AUTHOR("Takashi Sakamoto "); MODULE_LICENSE("GPL v2"); -static struct snd_tscm_spec model_specs[] = { +static const struct snd_tscm_spec model_specs[] = { { .name = "FW-1884", .has_adat = true, diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 0659bf38948990cabfafdf0c3482dd38af2c3d11..038a180d3f8117a7455ca6914ed883173aed8863 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -336,7 +336,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); /* check whether intel graphics is present */ static bool i915_gfx_present(void) { - static struct pci_device_id ids[] = { + static const struct pci_device_id ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16 }, diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 769226515f0d6d43fa3f05f73c2db11c0385ba14..4be6c1245820530cc40c71d4e7e554221bbafc3e 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -63,7 +63,7 @@ MODULE_PARM_DESC(enable, "Enable ad1816a based soundcard."); module_param_array(clockfreq, int, NULL, 0444); MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0)."); -static struct pnp_card_device_id snd_ad1816a_pnpids[] = { +static const struct pnp_card_device_id snd_ad1816a_pnpids[] = { /* Analog Devices AD1815 */ { .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } }, /* Analog Device AD1816? */ diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 5c815f5fb044906f5e76cafe0c46e9107b2e0bd2..92320141446990bca894b58c23daf78c3a2284e2 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c @@ -339,7 +339,7 @@ static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id) } -static struct snd_pcm_hardware snd_ad1816a_playback = { +static const struct snd_pcm_hardware snd_ad1816a_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | @@ -358,7 +358,7 @@ static struct snd_pcm_hardware snd_ad1816a_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ad1816a_capture = { +static const struct snd_pcm_hardware snd_ad1816a_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | @@ -653,7 +653,7 @@ int snd_ad1816a_create(struct snd_card *card, return 0; } -static struct snd_pcm_ops snd_ad1816a_playback_ops = { +static const struct snd_pcm_ops snd_ad1816a_playback_ops = { .open = snd_ad1816a_playback_open, .close = snd_ad1816a_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -664,7 +664,7 @@ static struct snd_pcm_ops snd_ad1816a_playback_ops = { .pointer = snd_ad1816a_playback_pointer, }; -static struct snd_pcm_ops snd_ad1816a_capture_ops = { +static const struct snd_pcm_ops snd_ad1816a_capture_ops = { .open = snd_ad1816a_capture_open, .close = snd_ad1816a_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index e739b1c85c25b98c43127d1afc6270195974296b..7c8e92f62f3b925b6ac2f377e562f060e7f8362b 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -110,13 +110,17 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - strcpy(card->driver, "AD1848"); - strcpy(card->shortname, chip->pcm->name); - - sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - chip->pcm->name, chip->port, irq[n], dma1[n]); - if (thinkpad[n]) - strcat(card->longname, " [Thinkpad]"); + strlcpy(card->driver, "AD1848", sizeof(card->driver)); + strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); + + if (!thinkpad[n]) + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d", + chip->pcm->name, chip->port, irq[n], dma1[n]); + else + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d [Thinkpad]", + chip->pcm->name, chip->port, irq[n], dma1[n]); error = snd_card_register(card); if (error < 0) diff --git a/sound/isa/als100.c b/sound/isa/als100.c index bc9ea306ee02283275fb8f253b7a869cabde6c49..f63142ec287ebb094b85189cd398f1d9d66ed31b 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c @@ -79,7 +79,7 @@ struct snd_card_als100 { struct snd_sb *chip; }; -static struct pnp_card_device_id snd_als100_pnpids[] = { +static const struct pnp_card_device_id snd_als100_pnpids[] = { /* DT197A30 */ { .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } }, @@ -222,15 +222,16 @@ static int snd_card_als100_probe(int dev, if (pid->driver_data == SB_HW_DT019X) { strcpy(card->driver, "DT-019X"); strcpy(card->shortname, "Diamond Tech. DT-019X"); - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", - card->shortname, chip->name, chip->port, - irq[dev], dma8[dev]); + snprintf(card->longname, sizeof(card->longname), + "Diamond Tech. DT-019X, %s at 0x%lx, irq %d, dma %d", + chip->name, chip->port, irq[dev], dma8[dev]); } else { strcpy(card->driver, "ALS100"); strcpy(card->shortname, "Avance Logic ALS100"); - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, chip->name, chip->port, - irq[dev], dma8[dev], dma16[dev]); + snprintf(card->longname, sizeof(card->longname), + "Avance Logic ALS100, %s at 0x%lx, irq %d, dma %d&%d", + chip->name, chip->port, irq[dev], dma8[dev], + dma16[dev]); } if ((error = snd_sb16dsp_pcm(chip, 0)) < 0) { diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index fff186fa621ee94924ca79ad5e91d9104bc27fd6..4e6fad4f94d92557a3a8757399b603d43f43f4aa 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -79,7 +79,7 @@ struct snd_card_azt2320 { struct snd_wss *chip; }; -static struct pnp_card_device_id snd_azt2320_pnpids[] = { +static const struct pnp_card_device_id snd_azt2320_pnpids[] = { /* PRO16V */ { .id = "AZT1008", .devs = { { "AZT1008" }, { "AZT2001" }, } }, /* Aztech Sound Galaxy 16 */ diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index f64b29ab5cc7005eb4ea35bd76133e8a0a0d6d24..6b8c46942efb4b660b508c55ffe93d0d1bd76e0b 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -182,7 +182,7 @@ struct snd_cmi8330 { #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_cmi8330_pnpids[] = { +static const struct pnp_card_device_id snd_cmi8330_pnpids[] = { { .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } }, { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, { .id = "" } diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index e8edd9017a2f22205b64a19b2adb68fe3f27beca..d90ab9558f7fd290904d7fbfedf38c47886d77dd 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -109,13 +109,17 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - strcpy(card->driver, "CS4231"); - strcpy(card->shortname, chip->pcm->name); - - sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - chip->pcm->name, chip->port, irq[n], dma1[n]); - if (dma2[n] >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); + strlcpy(card->driver, "CS4231", sizeof(card->driver)); + strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); + + if (dma2[n] < 0) + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d", + chip->pcm->name, chip->port, irq[n], dma1[n]); + else + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d&%d", + chip->pcm->name, chip->port, irq[n], dma1[n], dma2[n]); error = snd_wss_mixer(chip); if (error < 0) diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 1f9a3b2be7a1f705e40e15e8358a46b93e50a0f9..70559e59d18f71385e7ed92644a3aeb041696b78 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -149,7 +149,7 @@ static const struct pnp_device_id snd_cs423x_pnpbiosids[] = { MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids); #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" -static struct pnp_card_device_id snd_cs423x_pnpids[] = { +static const struct pnp_card_device_id snd_cs423x_pnpids[] = { /* Philips PCA70PS */ { .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } }, /* TerraTec Maestro 32/96 (CS4232) */ @@ -419,15 +419,17 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) if (err < 0) return err; } - strcpy(card->driver, chip->pcm->name); - strcpy(card->shortname, chip->pcm->name); - sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", - chip->pcm->name, - chip->port, - irq[dev], - dma1[dev]); - if (dma2[dev] >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); + strlcpy(card->driver, chip->pcm->name, sizeof(card->driver)); + strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); + if (dma2[dev] < 0) + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %i, dma %i", + chip->pcm->name, chip->port, irq[dev], dma1[dev]); + else + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %i, dma %i&%d", + chip->pcm->name, chip->port, irq[dev], dma1[dev], + dma2[dev]); err = snd_wss_timer(chip, 0); if (err < 0) diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 36320e7f278931719d7b8f8adcb935967ce2ecab..a826c138e7f555ec3a0e3345265f646bc3ff135e 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -321,7 +321,7 @@ static int snd_es968_pnp_resume(struct pnp_card_link *pcard) } #endif -static struct pnp_card_device_id snd_es968_pnpids[] = { +static const struct pnp_card_device_id snd_es968_pnpids[] = { { .id = "ESS0968", .devs = { { "@@@0968" }, } }, { .id = "ESS0968", .devs = { { "ESS0968" }, } }, { .id = "", } /* end */ diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 5d3df96c5e5bc8dc12908f41601af5e80bcc6279..f9c0662e9a2232915ef09cefacdfcd152759abea 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -526,7 +526,7 @@ static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *su */ -static struct snd_pcm_hardware snd_es1688_playback = +static const struct snd_pcm_hardware snd_es1688_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -544,7 +544,7 @@ static struct snd_pcm_hardware snd_es1688_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_es1688_capture = +static const struct snd_pcm_hardware snd_es1688_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -706,7 +706,7 @@ int snd_es1688_create(struct snd_card *card, return err; } -static struct snd_pcm_ops snd_es1688_playback_ops = { +static const struct snd_pcm_ops snd_es1688_playback_ops = { .open = snd_es1688_playback_open, .close = snd_es1688_playback_close, .ioctl = snd_es1688_ioctl, @@ -717,7 +717,7 @@ static struct snd_pcm_ops snd_es1688_playback_ops = { .pointer = snd_es1688_playback_pointer, }; -static struct snd_pcm_ops snd_es1688_capture_ops = { +static const struct snd_pcm_ops snd_es1688_capture_ops = { .open = snd_es1688_capture_open, .close = snd_es1688_capture_close, .ioctl = snd_es1688_ioctl, diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index ae17a65840616ac8f0de9fe29a894607ff24b283..2a6960c3e2a48fe21b00e500e2b8939bf60609ba 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -838,7 +838,7 @@ static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *su return pos >> chip->dma1_shift; } -static struct snd_pcm_hardware snd_es18xx_playback = +static const struct snd_pcm_hardware snd_es18xx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | @@ -858,7 +858,7 @@ static struct snd_pcm_hardware snd_es18xx_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_es18xx_capture = +static const struct snd_pcm_hardware snd_es18xx_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | @@ -1665,7 +1665,7 @@ static int snd_es18xx_probe(struct snd_es18xx *chip, return snd_es18xx_initialize(chip, mpu_port, fm_port); } -static struct snd_pcm_ops snd_es18xx_playback_ops = { +static const struct snd_pcm_ops snd_es18xx_playback_ops = { .open = snd_es18xx_playback_open, .close = snd_es18xx_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1676,7 +1676,7 @@ static struct snd_pcm_ops snd_es18xx_playback_ops = { .pointer = snd_es18xx_playback_pointer, }; -static struct snd_pcm_ops snd_es18xx_capture_ops = { +static const struct snd_pcm_ops snd_es18xx_capture_ops = { .open = snd_es18xx_capture_open, .close = snd_es18xx_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -2017,7 +2017,7 @@ static int isa_registered; static int pnp_registered; static int pnpc_registered; -static struct pnp_device_id snd_audiodrive_pnpbiosids[] = { +static const struct pnp_device_id snd_audiodrive_pnpbiosids[] = { { .id = "ESS1869" }, { .id = "ESS1879" }, { .id = "" } /* end */ @@ -2062,7 +2062,7 @@ static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip, return 0; } -static struct pnp_card_device_id snd_audiodrive_pnpids[] = { +static const struct pnp_card_device_id snd_audiodrive_pnpids[] = { /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */ { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } }, /* ESS 1868 (integrated on Maxisound Cards) */ diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 6b3da01a93b7b0c82e612671c30277f8fbea5ebf..131b28997e1d1e1c097122770e1562d8cb13c7a9 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -650,7 +650,7 @@ static void snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus) } } -static struct snd_pcm_hardware snd_gf1_pcm_playback = +static const struct snd_pcm_hardware snd_gf1_pcm_playback = { .info = SNDRV_PCM_INFO_NONINTERLEAVED, .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | @@ -668,7 +668,7 @@ static struct snd_pcm_hardware snd_gf1_pcm_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_gf1_pcm_capture = +static const struct snd_pcm_hardware snd_gf1_pcm_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -842,7 +842,7 @@ static const struct snd_kcontrol_new snd_gf1_pcm_volume_control1 = .put = snd_gf1_pcm_volume_put }; -static struct snd_pcm_ops snd_gf1_pcm_playback_ops = { +static const struct snd_pcm_ops snd_gf1_pcm_playback_ops = { .open = snd_gf1_pcm_playback_open, .close = snd_gf1_pcm_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -856,7 +856,7 @@ static struct snd_pcm_ops snd_gf1_pcm_playback_ops = { .fill_silence = snd_gf1_pcm_playback_silence, }; -static struct snd_pcm_ops snd_gf1_pcm_capture_ops = { +static const struct snd_pcm_ops snd_gf1_pcm_capture_ops = { .open = snd_gf1_pcm_capture_open, .close = snd_gf1_pcm_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 0687b7ef3e53b5f6a6b45d7aa3ed2b7654ce735b..a6fc26bf0af21f9f9f89eb7514d9a4fe1395a1af 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -136,7 +136,7 @@ struct snd_interwave { static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id snd_interwave_pnpids[] = { +static const struct pnp_card_device_id snd_interwave_pnpids[] = { #ifndef SNDRV_STB /* Gravis UltraSound Plug & Play */ { .id = "GRV0001", .devs = { { .id = "GRV0000" } } }, diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c index 8109ab3d29d1be755edcab61a5856ed08bea5c13..569897f64fda260c6244b4817c9f31ee974e849c 100644 --- a/sound/isa/msnd/msnd.c +++ b/sound/isa/msnd/msnd.c @@ -437,7 +437,7 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, } } -static struct snd_pcm_hardware snd_msnd_playback = { +static const struct snd_pcm_hardware snd_msnd_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -456,7 +456,7 @@ static struct snd_pcm_hardware snd_msnd_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_msnd_capture = { +static const struct snd_pcm_hardware snd_msnd_capture = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -572,7 +572,7 @@ snd_msnd_playback_pointer(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_msnd_playback_ops = { +static const struct snd_pcm_ops snd_msnd_playback_ops = { .open = snd_msnd_playback_open, .close = snd_msnd_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -669,7 +669,7 @@ static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream, } -static struct snd_pcm_ops snd_msnd_capture_ops = { +static const struct snd_pcm_ops snd_msnd_capture_ops = { .open = snd_msnd_capture_open, .close = snd_msnd_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index fc4fb1904aef83284ab165508a7e7b430a45d07c..45e561c425bfbdc02b89a090961b333facad898f 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c @@ -1192,7 +1192,7 @@ static void snd_msnd_pnp_remove(struct pnp_card_link *pcard) static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id msnd_pnpids[] = { +static const struct pnp_card_device_id msnd_pnpids[] = { /* Pinnacle PnP */ { .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } }, { .id = "" } /* end */ diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 4098e3e0353d8f6d7e57428d70d491301585ac3e..7cce4cd4a23b620ae617723614243c1285fc4bf1 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -141,7 +141,7 @@ struct snd_opl3sa2 { #ifdef CONFIG_PNP -static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { +static const struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { { .id = "YMH0021" }, { .id = "NMX2210" }, /* Gateway Solo 2500 */ { .id = "" } /* end */ @@ -149,7 +149,7 @@ static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosids); -static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { +static const struct pnp_card_device_id snd_opl3sa2_pnpids[] = { /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ { .id = "YMH0020", .devs = { { "YMH0021" } } }, /* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */ diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index bcbff56f060d04e3e55b0400b0c4be79f119b0cb..8894c7c18ad673c8bcebc698f5839e336b68d30d 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -143,7 +143,7 @@ static int snd_miro_pnp_is_probed; #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_miro_pnpids[] = { +static const struct pnp_card_device_id snd_miro_pnpids[] = { /* PCM20 and PCM12 in PnP mode */ { .id = "MIR0924", .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, }, @@ -1353,9 +1353,10 @@ static int snd_miro_probe(struct snd_card *card) } strcpy(card->driver, "miro"); - sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, miro->name, codec->pcm->name, - miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2); + snprintf(card->longname, sizeof(card->longname), + "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", + card->shortname, miro->name, codec->pcm->name, + miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2); if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) rmidi = NULL; diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index ceddb392b1e336b1bb7db83d9c8823ec1d4571a9..505cd81e19fa5a40be7d5a9302bb1c0c7a867d00 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -151,7 +151,7 @@ static int snd_opti9xx_pnp_is_probed; #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_opti9xx_pnpids[] = { +static const struct pnp_card_device_id snd_opti9xx_pnpids[] = { #ifndef OPTi93X /* OPTi 82C924 */ { .id = "OPT0924", @@ -879,13 +879,15 @@ static int snd_opti9xx_probe(struct snd_card *card) strcpy(card->driver, chip->name); sprintf(card->shortname, "OPTi %s", card->driver); #if defined(CS4231) || defined(OPTi93X) - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, codec->pcm->name, - chip->wss_base + 4, irq, dma1, xdma2); + snprintf(card->longname, sizeof(card->longname), + "%s, %s at 0x%lx, irq %d, dma %d&%d", + card->shortname, codec->pcm->name, + chip->wss_base + 4, irq, dma1, xdma2); #else - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", - card->shortname, codec->pcm->name, chip->wss_base + 4, irq, - dma1); + snprintf(card->longname, sizeof(card->longname), + "%s, %s at 0x%lx, irq %d, dma %d", + card->shortname, codec->pcm->name, chip->wss_base + 4, irq, + dma1); #endif /* CS4231 || OPTi93X */ if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c index d28d712f99f4266367960814e91cdfab74c3b342..5a485504f607d774a46b8091aebc042bb493f75e 100644 --- a/sound/isa/sb/emu8000_callback.c +++ b/sound/isa/sb/emu8000_callback.c @@ -62,7 +62,7 @@ static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch); /* * set up operators */ -static struct snd_emux_operators emu8000_ops = { +static const struct snd_emux_operators emu8000_ops = { .owner = THIS_MODULE, .get_voice = get_voice, .prepare = start_voice, diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 2ee8d67871ec49111c2afe5a6883e73dba8eacb2..8f34551abd8d497a37da7d1ec514f76d48d4914c 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c @@ -157,7 +157,7 @@ static int calc_rate_offset(int hz) /* */ -static struct snd_pcm_hardware emu8k_pcm_hw = { +static const struct snd_pcm_hardware emu8k_pcm_hw = { #ifdef USE_NONINTERLEAVE .info = SNDRV_PCM_INFO_NONINTERLEAVED, #else @@ -670,7 +670,7 @@ static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs) } -static struct snd_pcm_ops emu8k_pcm_ops = { +static const struct snd_pcm_ops emu8k_pcm_ops = { .open = emu8k_pcm_open, .close = emu8k_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 917a93d696c3ac835de5ac32ed2e7142b9303ec2..8f9ebeb998f6df3416917124e6effc706416eccf 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -145,7 +145,7 @@ struct snd_card_sb16 { #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_sb16_pnpids[] = { +static const struct pnp_card_device_id snd_sb16_pnpids[] = { #ifndef SNDRV_SBAWE /* Sound Blaster 16 PnP */ { .id = "CTL0024", .devs = { { "CTL0031" } } }, diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 4be1350f664910f8aa30ed7ea70503262eaeb68b..3e39ba220c396efde2a4dd98dfa84f00b38fc3a1 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -473,7 +473,7 @@ static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *subs */ -static struct snd_pcm_hardware snd_sb16_playback = +static const struct snd_pcm_hardware snd_sb16_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -491,7 +491,7 @@ static struct snd_pcm_hardware snd_sb16_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sb16_capture = +static const struct snd_pcm_hardware snd_sb16_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -838,7 +838,7 @@ int snd_sb16dsp_configure(struct snd_sb * chip) return 0; } -static struct snd_pcm_ops snd_sb16_playback_ops = { +static const struct snd_pcm_ops snd_sb16_playback_ops = { .open = snd_sb16_playback_open, .close = snd_sb16_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -849,7 +849,7 @@ static struct snd_pcm_ops snd_sb16_playback_ops = { .pointer = snd_sb16_playback_pointer, }; -static struct snd_pcm_ops snd_sb16_capture_ops = { +static const struct snd_pcm_ops snd_sb16_capture_ops = { .open = snd_sb16_capture_open, .close = snd_sb16_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 0f302be4fb6df73b0e482310296b31df80e1bbe1..d45df5c544234d9006c0297c939d4891ab19d64d 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -447,7 +447,7 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst */ -static struct snd_pcm_hardware snd_sb8_playback = +static const struct snd_pcm_hardware snd_sb8_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -466,7 +466,7 @@ static struct snd_pcm_hardware snd_sb8_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sb8_capture = +static const struct snd_pcm_hardware snd_sb8_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -572,7 +572,7 @@ static int snd_sb8_close(struct snd_pcm_substream *substream) * Initialization part */ -static struct snd_pcm_ops snd_sb8_playback_ops = { +static const struct snd_pcm_ops snd_sb8_playback_ops = { .open = snd_sb8_open, .close = snd_sb8_close, .ioctl = snd_pcm_lib_ioctl, @@ -583,7 +583,7 @@ static struct snd_pcm_ops snd_sb8_playback_ops = { .pointer = snd_sb8_playback_pointer, }; -static struct snd_pcm_ops snd_sb8_capture_ops = { +static const struct snd_pcm_ops snd_sb8_capture_ops = { .open = snd_sb8_open, .close = snd_sb8_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 1cd2908e4f12cf1f59b895e8b2f2142edfb10e2e..733adee5afbf94915b2460a82723e8cf9a1dcf19 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -88,7 +88,7 @@ MODULE_PARM_DESC(joystick, "Enable gameport."); static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id sscape_pnpids[] = { +static const struct pnp_card_device_id sscape_pnpids[] = { { .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */ { .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */ { .id = "" } /* end */ diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index da4e9a85f0afe98402f8d12494d197d8660344ea..b1989facd73275ad1896153b521689d09a4e67be 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -88,7 +88,7 @@ MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly lo static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id snd_wavefront_pnpids[] = { +static const struct pnp_card_device_id snd_wavefront_pnpids[] = { /* Tropez */ { .id = "CSC7532", .devs = { { "CSC0000" }, { "CSC0010" }, { "PnPb006" }, { "CSC0004" } } }, /* Tropez+ */ diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 9f4e2e34cbe1d5645f703f97d6b191f8f567d834..8a852042a066a1a1354102e968cceb69b1f9b50b 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1452,7 +1452,7 @@ static int snd_wss_probe(struct snd_wss *chip) */ -static struct snd_pcm_hardware snd_wss_playback = +static const struct snd_pcm_hardware snd_wss_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1472,7 +1472,7 @@ static struct snd_pcm_hardware snd_wss_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_wss_capture = +static const struct snd_pcm_hardware snd_wss_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1901,7 +1901,7 @@ int snd_wss_create(struct snd_card *card, } EXPORT_SYMBOL(snd_wss_create); -static struct snd_pcm_ops snd_wss_playback_ops = { +static const struct snd_pcm_ops snd_wss_playback_ops = { .open = snd_wss_playback_open, .close = snd_wss_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1912,7 +1912,7 @@ static struct snd_pcm_ops snd_wss_playback_ops = { .pointer = snd_wss_playback_pointer, }; -static struct snd_pcm_ops snd_wss_capture_ops = { +static const struct snd_pcm_ops snd_wss_capture_ops = { .open = snd_wss_capture_open, .close = snd_wss_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 3318c15e324a81176886bc8996cd91b96a05dcfb..37d378a26a506c860320dc08d3642a32a9c0564b 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c @@ -496,7 +496,7 @@ static void hal2_free_dmabuf(struct hal2_codec *codec) DMA_ATTR_NON_CONSISTENT); } -static struct snd_pcm_hardware hal2_pcm_hw = { +static const struct snd_pcm_hardware hal2_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -711,7 +711,7 @@ static int hal2_capture_ack(struct snd_pcm_substream *substream) hal2_capture_transfer); } -static struct snd_pcm_ops hal2_playback_ops = { +static const struct snd_pcm_ops hal2_playback_ops = { .open = hal2_playback_open, .close = hal2_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -723,7 +723,7 @@ static struct snd_pcm_ops hal2_playback_ops = { .ack = hal2_playback_ack, }; -static struct snd_pcm_ops hal2_capture_ops = { +static const struct snd_pcm_ops hal2_capture_ops = { .open = hal2_capture_open, .close = hal2_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 0ebc1c3727df86bd2da8f6f51742a801b64bac73..71c942162c252d6feac0edf9eb9a2534870b99de 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -532,7 +532,7 @@ static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id) /* PCM part */ /* PCM hardware definition */ -static struct snd_pcm_hardware snd_sgio2audio_pcm_hw = { +static const struct snd_pcm_hardware snd_sgio2audio_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -675,7 +675,7 @@ snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream) } /* operators */ -static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { +static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = { .open = snd_sgio2audio_playback1_open, .close = snd_sgio2audio_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -688,7 +688,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { +static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = { .open = snd_sgio2audio_playback2_open, .close = snd_sgio2audio_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -701,7 +701,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops snd_sgio2audio_capture_ops = { +static const struct snd_pcm_ops snd_sgio2audio_capture_ops = { .open = snd_sgio2audio_capture_open, .close = snd_sgio2audio_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/oss/sound_firmware.h b/sound/oss/sound_firmware.h index da4c67e005ed1302a49ad80e3c8e1bcad73995c4..2be465277ba0fd48ec9a75d26f2cce4d6c8a7dd4 100644 --- a/sound/oss/sound_firmware.h +++ b/sound/oss/sound_firmware.h @@ -21,7 +21,7 @@ static inline int mod_firmware_load(const char *fn, char **fp) loff_t size; int err; - err = kernel_read_file_from_path((char *)fn, (void **)fp, &size, + err = kernel_read_file_from_path(fn, (void **)fp, &size, 131072, READING_FIRMWARE); if (err < 0) return 0; diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 5911eb35c2a3995314614dbc74fb8f456bffd7fc..f36e7006e00cab443d3072a5feb1146246e29022 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -66,7 +66,7 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for Harmony driver."); -static struct parisc_device_id snd_harmony_devtable[] = { +static const struct parisc_device_id snd_harmony_devtable[] __initconst = { /* bushmaster / flounder */ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, /* 712 / 715 */ @@ -260,7 +260,7 @@ snd_harmony_rate_bits(int rate) return HARMONY_SR_44KHZ; } -static struct snd_pcm_hardware snd_harmony_playback = +static const struct snd_pcm_hardware snd_harmony_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | @@ -281,7 +281,7 @@ static struct snd_pcm_hardware snd_harmony_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_harmony_capture = +static const struct snd_pcm_hardware snd_harmony_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | @@ -596,7 +596,7 @@ snd_harmony_hw_free(struct snd_pcm_substream *ss) return snd_pcm_lib_free_pages(ss); } -static struct snd_pcm_ops snd_harmony_playback_ops = { +static const struct snd_pcm_ops snd_harmony_playback_ops = { .open = snd_harmony_playback_open, .close = snd_harmony_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -607,7 +607,7 @@ static struct snd_pcm_ops snd_harmony_playback_ops = { .pointer = snd_harmony_playback_pointer, }; -static struct snd_pcm_ops snd_harmony_capture_ops = { +static const struct snd_pcm_ops snd_harmony_capture_ops = { .open = snd_harmony_capture_open, .close = snd_harmony_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -960,7 +960,7 @@ snd_harmony_create(struct snd_card *card, return err; } -static int +static int __init snd_harmony_probe(struct parisc_device *padev) { int err; @@ -1000,18 +1000,18 @@ snd_harmony_probe(struct parisc_device *padev) return err; } -static int +static int __exit snd_harmony_remove(struct parisc_device *padev) { snd_card_free(parisc_get_drvdata(padev)); return 0; } -static struct parisc_driver snd_harmony_driver = { +static struct parisc_driver snd_harmony_driver __refdata = { .name = "harmony", .id_table = snd_harmony_devtable, .probe = snd_harmony_probe, - .remove = snd_harmony_remove, + .remove = __exit_p(snd_harmony_remove), }; static int __init diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 8c36990e26f61ae926f48f67ea553bde5cdf8d00..0bf2c04eeadaa1f341a0f096b20ddad6114bc13f 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -283,7 +283,7 @@ snd_ad1889_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); } -static struct snd_pcm_hardware snd_ad1889_playback_hw = { +static const struct snd_pcm_hardware snd_ad1889_playback_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, .formats = SNDRV_PCM_FMTBIT_S16_LE, @@ -300,7 +300,7 @@ static struct snd_pcm_hardware snd_ad1889_playback_hw = { /*.fifo_size = 0,*/ }; -static struct snd_pcm_hardware snd_ad1889_capture_hw = { +static const struct snd_pcm_hardware snd_ad1889_capture_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, .formats = SNDRV_PCM_FMTBIT_S16_LE, diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 8567f1e5b9cfed369e02a8e51008b0b82c059097..39547e32e584c0e7deac9c824072835894efad14 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1540,7 +1540,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops snd_ali_playback_ops = { +static const struct snd_pcm_ops snd_ali_playback_ops = { .open = snd_ali_playback_open, .close = snd_ali_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1551,7 +1551,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { .pointer = snd_ali_playback_pointer, }; -static struct snd_pcm_ops snd_ali_capture_ops = { +static const struct snd_pcm_ops snd_ali_capture_ops = { .open = snd_ali_capture_open, .close = snd_ali_close, .ioctl = snd_pcm_lib_ioctl, @@ -1626,7 +1626,7 @@ static int snd_ali_modem_capture_open(struct snd_pcm_substream *substream) return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL); } -static struct snd_pcm_ops snd_ali_modem_playback_ops = { +static const struct snd_pcm_ops snd_ali_modem_playback_ops = { .open = snd_ali_modem_playback_open, .close = snd_ali_close, .ioctl = snd_pcm_lib_ioctl, @@ -1637,7 +1637,7 @@ static struct snd_pcm_ops snd_ali_modem_playback_ops = { .pointer = snd_ali_pointer, }; -static struct snd_pcm_ops snd_ali_modem_capture_ops = { +static const struct snd_pcm_ops snd_ali_modem_capture_ops = { .open = snd_ali_modem_capture_open, .close = snd_ali_close, .ioctl = snd_pcm_lib_ioctl, @@ -1653,8 +1653,8 @@ struct ali_pcm_description { char *name; unsigned int playback_num; unsigned int capture_num; - struct snd_pcm_ops *playback_ops; - struct snd_pcm_ops *capture_ops; + const struct snd_pcm_ops *playback_ops; + const struct snd_pcm_ops *capture_ops; unsigned short class; }; diff --git a/sound/pci/als300.c b/sound/pci/als300.c index ab75601d7c2c4504d7a3737801d357ad758d15fc..eaa2d853d9223cdbb5f288002b28c291501dbe93 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c @@ -328,7 +328,7 @@ static int snd_als300_ac97(struct snd_als300 *chip) * the card when it is running outside of legacy * mode. */ -static struct snd_pcm_hardware snd_als300_playback_hw = +static const struct snd_pcm_hardware snd_als300_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -347,7 +347,7 @@ static struct snd_pcm_hardware snd_als300_playback_hw = .periods_max = 2, }; -static struct snd_pcm_hardware snd_als300_capture_hw = +static const struct snd_pcm_hardware snd_als300_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 7844a75d8ed97f7a6bda5b747e2872600cca4da6..26b097edec8c90f55686dea0001925a257dfe333 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -592,7 +592,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) /*****************************************************************/ -static struct snd_pcm_hardware snd_als4000_playback = +static const struct snd_pcm_hardware snd_als4000_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -611,7 +611,7 @@ static struct snd_pcm_hardware snd_als4000_playback = .fifo_size = 0 }; -static struct snd_pcm_hardware snd_als4000_capture = +static const struct snd_pcm_hardware snd_als4000_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 976a3d23557e4792ea5c6bfad4b63cc5a7e113f0..70d023a85bf5e7b4c2415f642766cedc16ef6d95 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -558,12 +558,10 @@ static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream) struct snd_card_asihpi_pcm *dpcm; struct snd_card_asihpi *card; - BUG_ON(!substream); - dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; card = snd_pcm_substream_chip(substream); - BUG_ON(in_interrupt()); + WARN_ON(in_interrupt()); tasklet_disable(&card->t); card->llmode_streampriv = dpcm; tasklet_enable(&card->t); @@ -578,8 +576,6 @@ static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream) struct snd_card_asihpi_pcm *dpcm; struct snd_card_asihpi *card; - BUG_ON(!substream); - dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; card = snd_pcm_substream_chip(substream); diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c index ac86a1f1d3bfba36d33adb52ef6349421aa16329..9e122327dc051fb2093c69dff6f7ee11d674ab67 100644 --- a/sound/pci/asihpi/hpidebug.c +++ b/sound/pci/asihpi/hpidebug.c @@ -71,8 +71,8 @@ void hpi_debug_data(u16 *pdata, u32 len) printk(KERN_DEBUG "%p:", (pdata + i)); for (k = 0; k < cols && i < len; i++, k++) - printk("%s%04x", k == 0 ? "" : " ", pdata[i]); + printk(KERN_CONT "%s%04x", k == 0 ? "" : " ", pdata[i]); - printk("\n"); + printk(KERN_CONT "\n"); } } diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 7e3aa50b21f9d2d2f5ca49f3f9a779ab1276ee4a..5badd08e1d69cc12657410359255ab691eff62f0 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -103,6 +103,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) void __user *puhr; union hpi_message_buffer_v1 *hm; union hpi_response_buffer_v1 *hr; + u16 msg_size; u16 res_max_size; u32 uncopied_bytes; int err = 0; @@ -127,22 +128,25 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } /* Now read the message size and data from user space. */ - if (get_user(hm->h.size, (u16 __user *)puhm)) { + if (get_user(msg_size, (u16 __user *)puhm)) { err = -EFAULT; goto out; } - if (hm->h.size > sizeof(*hm)) - hm->h.size = sizeof(*hm); + if (msg_size > sizeof(*hm)) + msg_size = sizeof(*hm); /* printk(KERN_INFO "message size %d\n", hm->h.wSize); */ - uncopied_bytes = copy_from_user(hm, puhm, hm->h.size); + uncopied_bytes = copy_from_user(hm, puhm, msg_size); if (uncopied_bytes) { HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes); err = -EFAULT; goto out; } + /* Override h.size in case it is changed between two userspace fetches */ + hm->h.size = msg_size; + if (get_user(res_max_size, (u16 __user *)puhr)) { err = -EFAULT; goto out; diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index a40c918c8dff2c9e42fae0d872cfcf71ee20569f..7ae63d452bba1ca4f2f7514d1593066486a00440 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1009,7 +1009,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for all DMA types */ -static struct snd_pcm_hardware snd_atiixp_pcm_hw = +static const struct snd_pcm_hardware snd_atiixp_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1183,7 +1183,7 @@ static const struct snd_pcm_ops snd_atiixp_spdif_ops = { .pointer = snd_atiixp_pcm_pointer, }; -static struct ac97_pcm atiixp_pcm_defs[] = { +static const struct ac97_pcm atiixp_pcm_defs[] = { /* front PCM */ { .exclusive = 1, diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 52e0ea7b9b80003cd4e7cce20f34ec13fd7604e4..a586635664e041f9ce0ecf1e32e7f2280c2f823b 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -834,7 +834,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for all DMA types */ -static struct snd_pcm_hardware snd_atiixp_pcm_hw = +static const struct snd_pcm_hardware snd_atiixp_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 1aa97012451dd27f8adc955253f8426a233d5919..53714e0bf598986e0e54566d770a8bed675dae33 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -30,7 +30,7 @@ #define VORTEX_PCM_TYPE(x) (x->name[40]) /* hardware definition */ -static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = { .info = (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | @@ -51,7 +51,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { }; #ifndef CHIP_AU8820 -static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = { .info = (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | @@ -71,7 +71,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = { .periods_max = 64, }; #endif -static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = { .info = (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | @@ -94,7 +94,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = { }; #ifndef CHIP_AU8810 -static struct snd_pcm_hardware snd_vortex_playback_hw_wt = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), @@ -439,7 +439,7 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr } /* operators */ -static struct snd_pcm_ops snd_vortex_playback_ops = { +static const struct snd_pcm_ops snd_vortex_playback_ops = { .open = snd_vortex_pcm_open, .close = snd_vortex_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 8356180bfe0e15ada0031e23369370036593dcff..9a49e4243a9c0b3c3cc0f23fbbf8a202243c80ad 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -52,7 +52,7 @@ MODULE_LICENSE("GPL"); * TYPEDEFS ********************************/ /* hardware definition */ -static struct snd_pcm_hardware snd_aw2_playback_hw = { +static const struct snd_pcm_hardware snd_aw2_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), @@ -69,7 +69,7 @@ static struct snd_pcm_hardware snd_aw2_playback_hw = { .periods_max = 1024, }; -static struct snd_pcm_hardware snd_aw2_capture_hw = { +static const struct snd_pcm_hardware snd_aw2_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index de0234294c25f2b3eda1746b84111612a8b6aaff..d8ade8771a327a082d49a7b1edb05c72e25f33bf 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -353,7 +353,7 @@ static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_bt87x_digital_hw = { +static const struct snd_pcm_hardware snd_bt87x_digital_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -370,7 +370,7 @@ static struct snd_pcm_hardware snd_bt87x_digital_hw = { .periods_max = 255, }; -static struct snd_pcm_hardware snd_bt87x_analog_hw = { +static const struct snd_pcm_hardware snd_bt87x_analog_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 6165a57a94aeac79552aa2fd61f63f4cbd431a79..cd27b5536654431643a108dd04887f1f76696a65 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -296,7 +296,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = { }; /* hardware definition */ -static struct snd_pcm_hardware snd_ca0106_playback_hw = { +static const struct snd_pcm_hardware snd_ca0106_playback_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -317,7 +317,7 @@ static struct snd_pcm_hardware snd_ca0106_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ca0106_capture_hw = { +static const struct snd_pcm_hardware snd_ca0106_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -660,11 +660,9 @@ static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substre int err; epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); - if (epcm == NULL) { - dev_err(chip->card->dev, - "open_capture_channel: failed epcm alloc\n"); + if (!epcm) return -ENOMEM; - } + epcm->emu = chip; epcm->substream = substream; epcm->channel_id=channel_id; diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index a460cb63e971ac7da04447f301627d86285bc226..26a65787066420d983685f3c43f4bcc42a096eb5 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1477,7 +1477,7 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id) */ /* playback on channel A */ -static struct snd_pcm_hardware snd_cmipci_playback = +static const struct snd_pcm_hardware snd_cmipci_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1497,7 +1497,7 @@ static struct snd_pcm_hardware snd_cmipci_playback = }; /* capture on channel B */ -static struct snd_pcm_hardware snd_cmipci_capture = +static const struct snd_pcm_hardware snd_cmipci_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1517,7 +1517,7 @@ static struct snd_pcm_hardware snd_cmipci_capture = }; /* playback on channel B - stereo 16bit only? */ -static struct snd_pcm_hardware snd_cmipci_playback2 = +static const struct snd_pcm_hardware snd_cmipci_playback2 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1537,7 +1537,7 @@ static struct snd_pcm_hardware snd_cmipci_playback2 = }; /* spdif playback on channel A */ -static struct snd_pcm_hardware snd_cmipci_playback_spdif = +static const struct snd_pcm_hardware snd_cmipci_playback_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1557,7 +1557,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_spdif = }; /* spdif playback on channel A (32bit, IEC958 subframes) */ -static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe = +static const struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1577,7 +1577,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe = }; /* spdif capture on channel B */ -static struct snd_pcm_hardware snd_cmipci_capture_spdif = +static const struct snd_pcm_hardware snd_cmipci_capture_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -3295,20 +3295,23 @@ static int snd_cmipci_probe(struct pci_dev *pci, break; } - if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) { - snd_card_free(card); - return err; - } + err = snd_cmipci_create(card, pci, dev, &cm); + if (err < 0) + goto free_card; + card->private_data = cm; - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto free_card; + pci_set_drvdata(pci, card); dev++; return 0; +free_card: + snd_card_free(card); + return err; } static void snd_cmipci_remove(struct pci_dev *pci) diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index ee7ba4b0b47b6ef7e1466d5f6c2135ebc73635ff..ec4247638fa14a6748de8c949cd553846bada13d 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -847,7 +847,7 @@ static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream) snd_cs4281_peekBA0(chip, dma->regDCC) - 1; } -static struct snd_pcm_hardware snd_cs4281_playback = +static const struct snd_pcm_hardware snd_cs4281_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -872,7 +872,7 @@ static struct snd_pcm_hardware snd_cs4281_playback = .fifo_size = CS4281_FIFO_SIZE, }; -static struct snd_pcm_hardware snd_cs4281_capture = +static const struct snd_pcm_hardware snd_cs4281_capture = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 709fb1a503b780775a1ee2bc1ce9a810ae8a5523..0020fd0efc466b46e4482a106d80c23d33546504 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -1438,7 +1438,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_cs46xx_playback = +static const struct snd_pcm_hardware snd_cs46xx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -1460,7 +1460,7 @@ static struct snd_pcm_hardware snd_cs46xx_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_cs46xx_capture = +static const struct snd_pcm_hardware snd_cs46xx_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index c208c1d8dbb2b18877f0da72867c783e6bd8c4db..ee7065f6e162bb965a01ffac057360b33d13d3a7 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -33,7 +33,7 @@ #include #include "cs5535audio.h" -static struct snd_pcm_hardware snd_cs5535audio_playback = +static const struct snd_pcm_hardware snd_cs5535audio_playback = { .info = ( SNDRV_PCM_INFO_MMAP | @@ -62,7 +62,7 @@ static struct snd_pcm_hardware snd_cs5535audio_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_cs5535audio_capture = +static const struct snd_pcm_hardware snd_cs5535audio_capture = { .info = ( SNDRV_PCM_INFO_MMAP | diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 79edd88d5cd08398afb86c63b3d32b025162164e..8e6eb9d7984b88329d8ea291cf2414f299f9a819 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -2154,7 +2154,7 @@ static void hw_write_pci(struct hw *hw, u32 reg, u32 data) &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); } -static struct hw ct20k1_preset = { +static const struct hw ct20k1_preset = { .irq = -1, .card_init = hw_card_init, diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 18ee7768b7c4021b3d1f9b5a8f748a68521ee938..b866d6b2c9236d440d742cfac2ba652a7d2ab333 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -2220,7 +2220,7 @@ static void hw_write_20kx(struct hw *hw, u32 reg, u32 data) writel(data, hw->mem_base + reg); } -static struct hw ct20k2_preset = { +static const struct hw ct20k2_preset = { .irq = -1, .card_init = hw_card_init, diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 974978041558b2a08d1837432240e2abe011cf58..b36e37ae2b519b64bdf24e0b2ff9dd8ce11375f9 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -21,7 +21,7 @@ #include /* Hardware descriptions for playback */ -static struct snd_pcm_hardware ct_pcm_playback_hw = { +static const struct snd_pcm_hardware ct_pcm_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -46,7 +46,7 @@ static struct snd_pcm_hardware ct_pcm_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { +static const struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -69,7 +69,7 @@ static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { }; /* Hardware descriptions for capture */ -static struct snd_pcm_hardware ct_pcm_capture_hw = { +static const struct snd_pcm_hardware ct_pcm_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -140,27 +140,28 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; + err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024, UINT_MAX); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; apcm->timer = ct_timer_instance_new(atc->timer, apcm); if (!apcm->timer) { - kfree(apcm); - return -ENOMEM; + err = -ENOMEM; + goto free_pcm; } runtime->private_data = apcm; runtime->private_free = ct_atc_pcm_free_substream; return 0; + +free_pcm: + kfree(apcm); + return err; } static int ct_pcm_playback_close(struct snd_pcm_substream *substream) @@ -286,27 +287,28 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; + err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024, UINT_MAX); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; apcm->timer = ct_timer_instance_new(atc->timer, apcm); if (!apcm->timer) { - kfree(apcm); - return -ENOMEM; + err = -ENOMEM; + goto free_pcm; } runtime->private_data = apcm; runtime->private_free = ct_atc_pcm_free_substream; return 0; + +free_pcm: + kfree(apcm); + return err; } static int ct_pcm_capture_close(struct snd_pcm_substream *substream) diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c index c5124c3c0fd192bb8d25528f779b7755d748d057..80c4d84f9667f25601c8f7f878cd9c5bde8db05d 100644 --- a/sound/pci/ctxfi/ctresource.c +++ b/sound/pci/ctxfi/ctresource.c @@ -258,10 +258,8 @@ int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type, int rsc_mgr_uninit(struct rsc_mgr *mgr) { - if (NULL != mgr->rscs) { - kfree(mgr->rscs); - mgr->rscs = NULL; - } + kfree(mgr->rscs); + mgr->rscs = NULL; if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) { switch (mgr->type) { diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index a5a72df298013faae602f1cdcb95a7b4cda3d865..bb4c9c3c89aee0c26583096b9a23c1b8d986b5d6 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -702,10 +702,8 @@ static int srcimp_rsc_init(struct srcimp *srcimp, static int srcimp_rsc_uninit(struct srcimp *srcimp) { - if (NULL != srcimp->imappers) { - kfree(srcimp->imappers); - srcimp->imappers = NULL; - } + kfree(srcimp->imappers); + srcimp->imappers = NULL; srcimp->ops = NULL; srcimp->mgr = NULL; rsc_uninit(&srcimp->rsc); diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index d15ecf9febbfd6810e727c29f293fadbc8974904..d68f99e076a879def2241365e0dd78b3aeaa5611 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -826,7 +826,7 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) /* pcm *_ops structures */ -static struct snd_pcm_ops analog_playback_ops = { +static const struct snd_pcm_ops analog_playback_ops = { .open = pcm_analog_out_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -837,7 +837,7 @@ static struct snd_pcm_ops analog_playback_ops = { .pointer = pcm_pointer, .page = snd_pcm_sgbuf_ops_page, }; -static struct snd_pcm_ops analog_capture_ops = { +static const struct snd_pcm_ops analog_capture_ops = { .open = pcm_analog_in_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -850,7 +850,7 @@ static struct snd_pcm_ops analog_capture_ops = { }; #ifdef ECHOCARD_HAS_DIGITAL_IO #ifndef ECHOCARD_HAS_VMIXER -static struct snd_pcm_ops digital_playback_ops = { +static const struct snd_pcm_ops digital_playback_ops = { .open = pcm_digital_out_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -862,7 +862,7 @@ static struct snd_pcm_ops digital_playback_ops = { .page = snd_pcm_sgbuf_ops_page, }; #endif /* !ECHOCARD_HAS_VMIXER */ -static struct snd_pcm_ops digital_capture_ops = { +static const struct snd_pcm_ops digital_capture_ops = { .open = pcm_digital_in_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -1272,11 +1272,11 @@ static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, chip = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; uinfo->value.integer.min = ECHOGAIN_MINOUT; uinfo->value.integer.max = ECHOGAIN_MAXOUT; uinfo->dimen.d[0] = num_busses_out(chip); uinfo->dimen.d[1] = num_busses_in(chip); - uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1]; return 0; } @@ -1344,11 +1344,11 @@ static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, chip = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; uinfo->value.integer.min = ECHOGAIN_MINOUT; uinfo->value.integer.max = ECHOGAIN_MAXOUT; uinfo->dimen.d[0] = num_busses_out(chip); uinfo->dimen.d[1] = num_pipes_out(chip); - uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1]; return 0; } @@ -1728,6 +1728,7 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 96; uinfo->value.integer.min = ECHOGAIN_MINOUT; uinfo->value.integer.max = 0; #ifdef ECHOCARD_HAS_VMIXER @@ -1737,7 +1738,6 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, #endif uinfo->dimen.d[1] = 16; /* 16 channels */ uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ - uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1] * uinfo->dimen.d[2]; return 0; } diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 77a4413f4564cefdc4545d637908fb0f84f9eeb1..2c2b12a0617741a918384f77ea97bf8cfd868ee2 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -254,7 +254,7 @@ struct emu10k1x { }; /* hardware definition */ -static struct snd_pcm_hardware snd_emu10k1x_playback_hw = { +static const struct snd_pcm_hardware snd_emu10k1x_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -273,7 +273,7 @@ static struct snd_pcm_hardware snd_emu10k1x_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_emu10k1x_capture_hw = { +static const struct snd_pcm_hardware snd_emu10k1x_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index dc585959ca32c8cfbfa3aff0557a4e20c7ec1430..a2b56b188be4d90d9c51547e5fd8a7013700b14f 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -698,10 +698,18 @@ static int copy_gctl(struct snd_emu10k1 *emu, { struct snd_emu10k1_fx8010_control_old_gpr __user *octl; - if (emu->support_tlv) - return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)); + if (emu->support_tlv) { + if (in_kernel) + memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl)); + else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl))) + return -EFAULT; + return 0; + } + octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; - if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) + if (in_kernel) + memcpy(gctl, (void *)&octl[idx], sizeof(*octl)); + else if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) return -EFAULT; gctl->tlv = NULL; return 0; diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 5c9054a9f69eb24aa9440155d6b2af0f2e6065eb..2683b971721532acd8867308e57fc4fcd6a331be 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -556,7 +556,7 @@ static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_hardware snd_emu10k1_efx_playback = +static const struct snd_pcm_hardware snd_emu10k1_efx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -975,7 +975,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s * Playback support device description */ -static struct snd_pcm_hardware snd_emu10k1_playback = +static const struct snd_pcm_hardware snd_emu10k1_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -999,7 +999,7 @@ static struct snd_pcm_hardware snd_emu10k1_playback = * Capture support device description */ -static struct snd_pcm_hardware snd_emu10k1_capture = +static const struct snd_pcm_hardware snd_emu10k1_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1019,7 +1019,7 @@ static struct snd_pcm_hardware snd_emu10k1_capture = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_emu10k1_capture_efx = +static const struct snd_pcm_hardware snd_emu10k1_capture_efx = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1742,7 +1742,7 @@ static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(struct snd_pcm_subs return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr); } -static struct snd_pcm_hardware snd_emu10k1_fx8010_playback = +static const struct snd_pcm_hardware snd_emu10k1_fx8010_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index c11f1a29f35d03524cecf6bfe31314ae68366fd3..a30da78a95b7035b36e9442eefe6962f2255e4ca 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -122,7 +122,7 @@ */ /* hardware definition */ -static struct snd_pcm_hardware snd_p16v_playback_hw = { +static const struct snd_pcm_hardware snd_p16v_playback_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -143,7 +143,7 @@ static struct snd_pcm_hardware snd_p16v_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_p16v_capture_hw = { +static const struct snd_pcm_hardware snd_p16v_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index f0d978e3b27444155a03c975aea5af6257d44528..d4cd6451fdca1af1da98fd16b4bc956fae46ba65 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -1059,7 +1059,7 @@ static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *s return ptr; } -static struct snd_pcm_hardware snd_ensoniq_playback1 = +static const struct snd_pcm_hardware snd_ensoniq_playback1 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1086,7 +1086,7 @@ static struct snd_pcm_hardware snd_ensoniq_playback1 = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ensoniq_playback2 = +static const struct snd_pcm_hardware snd_ensoniq_playback2 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1106,7 +1106,7 @@ static struct snd_pcm_hardware snd_ensoniq_playback2 = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ensoniq_capture = +static const struct snd_pcm_hardware snd_ensoniq_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 069902a06f00f1aa1dea70c8a9588dba196f7eb6..9d248eb2e26cd7ecb9faca4eefdcd74561121b5f 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -900,7 +900,7 @@ static int snd_es1938_pcm_hw_free(struct snd_pcm_substream *substream) /* ---------------------------------------------------------------------- * Audio1 Capture (ADC) * ----------------------------------------------------------------------*/ -static struct snd_pcm_hardware snd_es1938_capture = +static const struct snd_pcm_hardware snd_es1938_capture = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), @@ -922,7 +922,7 @@ static struct snd_pcm_hardware snd_es1938_capture = /* ----------------------------------------------------------------------- * Audio2 Playback (DAC) * -----------------------------------------------------------------------*/ -static struct snd_pcm_hardware snd_es1938_playback = +static const struct snd_pcm_hardware snd_es1938_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 2ec2b1ce0af6a3d3e9fe4f483d29456e2b4fd94a..0b1845ca6005a187e6a567e5beda7582f44bca1a 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1290,7 +1290,7 @@ static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substr return bytes_to_frames(substream->runtime, ptr % es->dma_size); } -static struct snd_pcm_hardware snd_es1968_playback = { +static const struct snd_pcm_hardware snd_es1968_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -1311,7 +1311,7 @@ static struct snd_pcm_hardware snd_es1968_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_es1968_capture = { +static const struct snd_pcm_hardware snd_es1968_capture = { .info = (SNDRV_PCM_INFO_NONINTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 8e6b04b39dcc199a9895f5f7680066ee203fe2ea..73a67bc3586bcd55e6e0387093fcda8917e6c2e7 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -599,7 +599,7 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_fm801_playback = +static const struct snd_pcm_hardware snd_fm801_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -619,7 +619,7 @@ static struct snd_pcm_hardware snd_fm801_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_fm801_capture = +static const struct snd_pcm_hardware snd_fm801_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c index 7efa7bd7acb25089e1ff2f8ece32d97ccd7e3113..44b1e15682b92ca6e794b19c50dce3780921ed7d 100644 --- a/sound/pci/hda/dell_wmi_helper.c +++ b/sound/pci/hda/dell_wmi_helper.c @@ -5,12 +5,47 @@ #if IS_ENABLED(CONFIG_DELL_LAPTOP) #include +enum { + MICMUTE_LED_ON, + MICMUTE_LED_OFF, + MICMUTE_LED_FOLLOW_CAPTURE, + MICMUTE_LED_FOLLOW_MUTE, +}; + +static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE; +static int dell_capture; static int dell_led_value; static int (*dell_micmute_led_set_func)(int); static void (*dell_old_cap_hook)(struct hda_codec *, struct snd_kcontrol *, struct snd_ctl_elem_value *); +static void call_micmute_led_update(void) +{ + int val; + + switch (dell_led_mode) { + case MICMUTE_LED_ON: + val = 1; + break; + case MICMUTE_LED_OFF: + val = 0; + break; + case MICMUTE_LED_FOLLOW_CAPTURE: + val = dell_capture; + break; + case MICMUTE_LED_FOLLOW_MUTE: + default: + val = !dell_capture; + break; + } + + if (val == dell_led_value) + return; + dell_led_value = val; + dell_micmute_led_set_func(dell_led_value); +} + static void update_dell_wmi_micmute_led(struct hda_codec *codec, struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -22,15 +57,54 @@ static void update_dell_wmi_micmute_led(struct hda_codec *codec, return; if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { /* TODO: How do I verify if it's a mono or stereo here? */ - int val = (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) ? 0 : 1; - if (val == dell_led_value) - return; - dell_led_value = val; - if (dell_micmute_led_set_func) - dell_micmute_led_set_func(dell_led_value); + dell_capture = (ucontrol->value.integer.value[0] || + ucontrol->value.integer.value[1]); + call_micmute_led_update(); } } +static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char * const texts[] = { + "On", "Off", "Follow Capture", "Follow Mute", + }; + + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); +} + +static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = dell_led_mode; + return 0; +} + +static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int mode; + + mode = ucontrol->value.enumerated.item[0]; + if (mode > MICMUTE_LED_FOLLOW_MUTE) + mode = MICMUTE_LED_FOLLOW_MUTE; + if (mode == dell_led_mode) + return 0; + dell_led_mode = mode; + call_micmute_led_update(); + return 1; +} + +static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Mute-LED Mode", + .info = dell_mic_mute_led_mode_info, + .get = dell_mic_mute_led_mode_get, + .put = dell_mic_mute_led_mode_put, + }, + {} +}; static void alc_fixup_dell_wmi(struct hda_codec *codec, const struct hda_fixup *fix, int action) @@ -55,6 +129,7 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, dell_old_cap_hook = spec->gen.cap_sync_hook; spec->gen.cap_sync_hook = update_dell_wmi_micmute_led; removefunc = false; + add_mixer(spec, dell_mic_mute_mode_ctls); } } diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index 6efadbfb3fe3511b4726541cdd9ebd4aae6cd65d..d361bb77ca00d1979a572d7a95d13e8a0563b34f 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -100,7 +100,7 @@ static int hda_codec_driver_probe(struct device *dev) if (patch) { err = patch(codec); if (err < 0) - goto error_module; + goto error_module_put; } err = snd_hda_codec_build_pcms(codec); @@ -120,6 +120,9 @@ static int hda_codec_driver_probe(struct device *dev) return 0; error_module: + if (codec->patch_ops.free) + codec->patch_ops.free(codec); + error_module_put: module_put(owner); error: diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 821aad374a0695a46c4c265365b71a81aa134412..3db26c451837cf0e2893d1071c1a699465d89e1b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3213,8 +3213,10 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) continue; /* no substreams assigned */ dev = get_empty_pcm_device(bus, cpcm->pcm_type); - if (dev < 0) + if (dev < 0) { + cpcm->device = SNDRV_PCM_INVALID_DEVICE; continue; /* no fatal error */ + } cpcm->device = dev; err = snd_hda_attach_pcm_stream(bus, codec, cpcm); if (err < 0) { diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 60ce1cfc300f9cb419acbc67425076c120829f13..681c360f29f9d628cf4462c9bb7ef92879f27d91 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -164,6 +164,7 @@ enum { HDA_PCM_NTYPES }; +#define SNDRV_PCM_INVALID_DEVICE (-1) /* for PCM creation */ struct hda_pcm { char *name; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5ae8ddab641220f2ebb0a1e85438302e50d2b861..f958d8d54d159ccdc957d13cacbfb92973e15db4 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2389,6 +2389,9 @@ static const struct pci_device_id azx_ids[] = { /* Coffelake */ { PCI_DEVICE(0x8086, 0xa348), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Cannonlake */ + { PCI_DEVICE(0x8086, 0x9dc8), + .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON }, diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e0fb8c6d1bc274e4ff5f6a8bf55afa9852bf9026..757857313426b194c5df1a2952fb008271df3748 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -505,7 +505,7 @@ static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new ad1983_auto_smux_mixer = { +static const struct snd_kcontrol_new ad1983_auto_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", .info = ad1983_auto_smux_enum_info, @@ -788,7 +788,7 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new ad1988_auto_smux_mixer = { +static const struct snd_kcontrol_new ad1988_auto_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", .info = ad1988_auto_smux_enum_info, diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index a148176c16a98acccad573a20baade15520f83d1..3e73d5c6ccfc95155d79557d0a5292f865afe777 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4774,13 +4774,17 @@ static int patch_ca0132(struct hda_codec *codec) err = ca0132_prepare_verbs(codec); if (err < 0) - return err; + goto error; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); if (err < 0) - return err; + goto error; return 0; + + error: + ca0132_free(codec); + return err; } /* diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 8c1289963c802b34783a8a8b4af42ed55bbcd71c..a81aacf684b26341ec9257366d7c83a47962a16d 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -947,6 +947,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI), SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004), diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 53f9311370dec18fabdc0cb03820f7f24c1dab1d..c19c81d230bd7423b4153d2266a45e09333f8714 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -906,6 +906,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, hda_nid_t pin_nid, u32 stream_tag, int format) { struct hdmi_spec *spec = codec->spec; + unsigned int param; int err; err = spec->ops.pin_hbr_setup(codec, pin_nid, is_hbr_format(format)); @@ -915,6 +916,26 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, return err; } + if (is_haswell_plus(codec)) { + + /* + * on recent platforms IEC Coding Type is required for HBR + * support, read current Digital Converter settings and set + * ICT bitfield if needed. + */ + param = snd_hda_codec_read(codec, cvt_nid, 0, + AC_VERB_GET_DIGI_CONVERT_1, 0); + + param = (param >> 16) & ~(AC_DIG3_ICT); + + /* on recent platforms ICT mode is required for HBR support */ + if (is_hbr_format(format)) + param |= 0x1; + + snd_hda_codec_write(codec, cvt_nid, 0, + AC_VERB_SET_DIGI_CONVERT_3, param); + } + snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format); return 0; } @@ -2126,7 +2147,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx) static int generic_hdmi_build_controls(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; - int err; + int dev, err; int pin_idx, pcm_idx; @@ -2154,11 +2175,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) return err; snd_hda_spdif_ctls_unassign(codec, pcm_idx); - /* add control for ELD Bytes */ - err = hdmi_create_eld_ctl(codec, pcm_idx, - get_pcm_rec(spec, pcm_idx)->device); - if (err < 0) - return err; + dev = get_pcm_rec(spec, pcm_idx)->device; + if (dev != SNDRV_PCM_INVALID_DEVICE) { + /* add control for ELD Bytes */ + err = hdmi_create_eld_ctl(codec, pcm_idx, dev); + if (err < 0) + return err; + } } for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 443a45eaec3267d98ba9a3f12c5da128b762cfce..0ce71111b4e3ec0fd58940b27a0638cc9d483fd1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2296,6 +2296,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), + SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), @@ -5262,6 +5263,7 @@ enum { ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, ALC233_FIXUP_LENOVO_MULTI_CODECS, ALC294_FIXUP_LENOVO_MIC_LOCATION, + ALC700_FIXUP_INTEL_REFERENCE, }; static const struct hda_fixup alc269_fixups[] = { @@ -6057,6 +6059,21 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC700_FIXUP_INTEL_REFERENCE] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* Enables internal speaker */ + {0x20, AC_VERB_SET_COEF_INDEX, 0x45}, + {0x20, AC_VERB_SET_PROC_COEF, 0x5289}, + {0x20, AC_VERB_SET_COEF_INDEX, 0x4A}, + {0x20, AC_VERB_SET_PROC_COEF, 0x001b}, + {0x58, AC_VERB_SET_COEF_INDEX, 0x00}, + {0x58, AC_VERB_SET_PROC_COEF, 0x3888}, + {0x20, AC_VERB_SET_COEF_INDEX, 0x6f}, + {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b}, + {} + } + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -6208,6 +6225,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), + SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), @@ -6646,7 +6664,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, ALC225_STANDARD_PINS, {0x12, 0xb7a60130}, - {0x13, 0xb8a61140}, {0x17, 0x90170110}), {} }; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6cefdf6c0b758770e2615126285d7cd83d736d64..63d15b545b333b0cf0bcf282cc96e2594fe5ec9c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -961,7 +961,7 @@ static int stac_smux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_smux[smux_idx]); } -static struct snd_kcontrol_new stac_smux_mixer = { +static const struct snd_kcontrol_new stac_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", /* count set later */ diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index da5f37b7fdd0d6f2932d12c9f2baaf379331b52d..6808bed0105ef6c08c938b566e3030ecfe3de71c 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -445,7 +445,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status = * initialize the chips on M-Audio cards */ -static struct snd_akm4xxx akm_audiophile = { +static const struct snd_akm4xxx akm_audiophile = { .type = SND_AK4528, .num_adcs = 2, .num_dacs = 2, @@ -454,7 +454,7 @@ static struct snd_akm4xxx akm_audiophile = { } }; -static struct snd_ak4xxx_private akm_audiophile_priv = { +static const struct snd_ak4xxx_private akm_audiophile_priv = { .caddr = 2, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -466,7 +466,7 @@ static struct snd_ak4xxx_private akm_audiophile_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_delta410 = { +static const struct snd_akm4xxx akm_delta410 = { .type = SND_AK4529, .num_adcs = 2, .num_dacs = 8, @@ -475,7 +475,7 @@ static struct snd_akm4xxx akm_delta410 = { } }; -static struct snd_ak4xxx_private akm_delta410_priv = { +static const struct snd_ak4xxx_private akm_delta410_priv = { .caddr = 0, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -487,7 +487,7 @@ static struct snd_ak4xxx_private akm_delta410_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_delta1010lt = { +static const struct snd_akm4xxx akm_delta1010lt = { .type = SND_AK4524, .num_adcs = 8, .num_dacs = 8, @@ -497,7 +497,7 @@ static struct snd_akm4xxx akm_delta1010lt = { } }; -static struct snd_ak4xxx_private akm_delta1010lt_priv = { +static const struct snd_ak4xxx_private akm_delta1010lt_priv = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_1010LT_DOUT, @@ -509,7 +509,7 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_delta66e = { +static const struct snd_akm4xxx akm_delta66e = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -519,7 +519,7 @@ static struct snd_akm4xxx akm_delta66e = { } }; -static struct snd_ak4xxx_private akm_delta66e_priv = { +static const struct snd_ak4xxx_private akm_delta66e_priv = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_66E_DOUT, @@ -532,7 +532,7 @@ static struct snd_ak4xxx_private akm_delta66e_priv = { }; -static struct snd_akm4xxx akm_delta44 = { +static const struct snd_akm4xxx akm_delta44 = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -542,7 +542,7 @@ static struct snd_akm4xxx akm_delta44 = { } }; -static struct snd_ak4xxx_private akm_delta44_priv = { +static const struct snd_ak4xxx_private akm_delta44_priv = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, @@ -554,7 +554,7 @@ static struct snd_ak4xxx_private akm_delta44_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_vx442 = { +static const struct snd_akm4xxx akm_vx442 = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -564,7 +564,7 @@ static struct snd_akm4xxx akm_vx442 = { } }; -static struct snd_ak4xxx_private akm_vx442_priv = { +static const struct snd_ak4xxx_private akm_vx442_priv = { .caddr = 2, .cif = 0, .data_mask = ICE1712_VX442_DOUT, diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index ec07136fc288ca349fa2ab18eac27e3a7e7451eb..b8af747ecb43c63a2dc991039ece1e13b54ba32a 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -344,7 +344,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate) /* */ -static struct snd_akm4xxx akm_ews88mt = { +static const struct snd_akm4xxx akm_ews88mt = { .num_adcs = 8, .num_dacs = 8, .type = SND_AK4524, @@ -354,7 +354,7 @@ static struct snd_akm4xxx akm_ews88mt = { } }; -static struct snd_ak4xxx_private akm_ews88mt_priv = { +static const struct snd_ak4xxx_private akm_ews88mt_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -366,7 +366,7 @@ static struct snd_ak4xxx_private akm_ews88mt_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_ewx2496 = { +static const struct snd_akm4xxx akm_ewx2496 = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -375,7 +375,7 @@ static struct snd_akm4xxx akm_ewx2496 = { } }; -static struct snd_ak4xxx_private akm_ewx2496_priv = { +static const struct snd_ak4xxx_private akm_ewx2496_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -387,7 +387,7 @@ static struct snd_ak4xxx_private akm_ewx2496_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_6fire = { +static const struct snd_akm4xxx akm_6fire = { .num_adcs = 6, .num_dacs = 6, .type = SND_AK4524, @@ -396,7 +396,7 @@ static struct snd_akm4xxx akm_6fire = { } }; -static struct snd_ak4xxx_private akm_6fire_priv = { +static const struct snd_ak4xxx_private akm_6fire_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_6FIRE_SERIAL_DATA, diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index a40001c1d9e8b3ee543c3323e5639cd1fbeb4192..fa301d31745bb9b14e0a5b10ea5eb9d846e38c37 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -166,7 +166,7 @@ static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) mutex_unlock(&ice->gpio_mutex); } -static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) +static int hoontech_init(struct snd_ice1712 *ice, bool staudio) { struct hoontech_spec *spec; int box, chn; @@ -203,7 +203,10 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) ICE1712_STDSP24_3_INSEL(spec->boxbits, 0); /* let's go - activate only functions in first box */ - spec->config = 0; + if (staudio) + spec->config = ICE1712_STDSP24_MUTE; + else + spec->config = 0; /* ICE1712_STDSP24_MUTE | ICE1712_STDSP24_INSEL | ICE1712_STDSP24_DAREAR; */ @@ -226,9 +229,16 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) ICE1712_STDSP24_BOX_CHN4 | ICE1712_STDSP24_BOX_MIDI1 | ICE1712_STDSP24_BOX_MIDI2; - spec->boxconfig[1] = - spec->boxconfig[2] = - spec->boxconfig[3] = 0; + if (staudio) { + spec->boxconfig[1] = + spec->boxconfig[2] = + spec->boxconfig[3] = spec->boxconfig[0]; + } else { + spec->boxconfig[1] = + spec->boxconfig[2] = + spec->boxconfig[3] = 0; + } + snd_ice1712_stdsp24_darear(ice, (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0); snd_ice1712_stdsp24_mute(ice, @@ -248,6 +258,16 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) return 0; } +static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) +{ + return hoontech_init(ice, false); +} + +static int snd_ice1712_staudio_init(struct snd_ice1712 *ice) +{ + return hoontech_init(ice, true); +} + /* * AK4524 access */ @@ -269,7 +289,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) static int snd_ice1712_value_init(struct snd_ice1712 *ice) { /* Hoontech STDSP24 with modified hardware */ - static struct snd_akm4xxx akm_stdsp24_mv = { + static const struct snd_akm4xxx akm_stdsp24_mv = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -278,7 +298,7 @@ static int snd_ice1712_value_init(struct snd_ice1712 *ice) } }; - static struct snd_ak4xxx_private akm_stdsp24_mv_priv = { + static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_STDSP24_SERIAL_DATA, @@ -351,5 +371,14 @@ struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = { .model = "ez8", .chip_init = snd_ice1712_ez8_init, }, + { + /* STAudio ADCIII has the same SSID as Hoontech StA DSP24, + * thus identified only via the explicit model option + */ + .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII, /* a dummy id */ + .name = "STAudio ADCIII", + .model = "staudio", + .chip_init = snd_ice1712_staudio_init, + }, { } /* terminator */ }; diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h index cc1da1e69ad137225ac884cc4acb0cf3a2dd503b..7f94943392ce87814f642b2f682d4b0878fbe961 100644 --- a/sound/pci/ice1712/hoontech.h +++ b/sound/pci/ice1712/hoontech.h @@ -34,6 +34,7 @@ #define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */ #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ #define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ +#define ICE1712_SUBDEVICE_STAUDIO_ADCIII 0x00010002 /* A dummy id for STAudio ADCIII */ extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 5bb146703738a4a6f61d51d2e219da801afe59e2..0dbaccf61f332706081a748d62a3a87b997e35a3 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -282,7 +282,7 @@ static const struct snd_akm4xxx_dac_channel juli_dac[] = { }; -static struct snd_akm4xxx akm_juli_dac = { +static const struct snd_akm4xxx akm_juli_dac = { .type = SND_AK4358, .num_dacs = 8, /* DAC1 - analog out DAC2 - analog in monitor diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index e9ca89c9174bbe7124ccd7dbaeb76301ebb11cfc..67fbb28bf033a58e86132bdf6a64fff972886525 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -102,13 +102,13 @@ static const unsigned char wm_vol[256] = { #define WM_VOL_MAX (sizeof(wm_vol) - 1) #define WM_VOL_MUTE 0x8000 -static struct snd_akm4xxx akm_phase22 = { +static const struct snd_akm4xxx akm_phase22 = { .type = SND_AK4524, .num_dacs = 2, .num_adcs = 2, }; -static struct snd_ak4xxx_private akm_phase22_priv = { +static const struct snd_ak4xxx_private akm_phase22_priv = { .caddr = 2, .cif = 1, .data_mask = 1 << 4, diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index f1b3732cc6d2a6631ce551bcc45970b4e538089e..d145b5eb7ff86d978debce8eb93aaa0d4dfbc50a 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c @@ -386,7 +386,7 @@ static const struct snd_akm4xxx_adc_channel qtet_adc[] = { AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2), }; -static struct snd_akm4xxx akm_qtet_dac = { +static const struct snd_akm4xxx akm_qtet_dac = { .type = SND_AK4620, .num_dacs = 4, /* DAC1 - Output 12 */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 1d81ae67757328df9764162b0b92495158ccf89e..6669c389f33676c03bea9942d2ad911e77105805 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -235,7 +235,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { }, }; -static struct snd_akm4xxx akm_revo_front = { +static const struct snd_akm4xxx akm_revo_front = { .type = SND_AK4381, .num_dacs = 2, .ops = { @@ -244,7 +244,7 @@ static struct snd_akm4xxx akm_revo_front = { .dac_info = revo71_front, }; -static struct snd_ak4xxx_private akm_revo_front_priv = { +static const struct snd_ak4xxx_private akm_revo_front_priv = { .caddr = 1, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -256,7 +256,7 @@ static struct snd_ak4xxx_private akm_revo_front_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo_surround = { +static const struct snd_akm4xxx akm_revo_surround = { .type = SND_AK4355, .idx_offset = 1, .num_dacs = 6, @@ -266,7 +266,7 @@ static struct snd_akm4xxx akm_revo_surround = { .dac_info = revo71_surround, }; -static struct snd_ak4xxx_private akm_revo_surround_priv = { +static const struct snd_ak4xxx_private akm_revo_surround_priv = { .caddr = 3, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -278,7 +278,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo51 = { +static const struct snd_akm4xxx akm_revo51 = { .type = SND_AK4358, .num_dacs = 8, .ops = { @@ -287,7 +287,7 @@ static struct snd_akm4xxx akm_revo51 = { .dac_info = revo51_dac, }; -static struct snd_ak4xxx_private akm_revo51_priv = { +static const struct snd_ak4xxx_private akm_revo51_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -299,13 +299,13 @@ static struct snd_ak4xxx_private akm_revo51_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo51_adc = { +static const struct snd_akm4xxx akm_revo51_adc = { .type = SND_AK5365, .num_adcs = 2, .adc_info = revo51_adc, }; -static struct snd_ak4xxx_private akm_revo51_adc_priv = { +static const struct snd_ak4xxx_private akm_revo51_adc_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -346,7 +346,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = { AK_DAC("PCM Playback Volume", 2) }; -static struct snd_akm4xxx akm_ap192 = { +static const struct snd_akm4xxx akm_ap192 = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -355,7 +355,7 @@ static struct snd_akm4xxx akm_ap192 = { .dac_info = ap192_dac, }; -static struct snd_ak4xxx_private akm_ap192_priv = { +static const struct snd_ak4xxx_private akm_ap192_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index a8d7092e93dddaba94adc9bc14bbe6eaf5ae1b84..4c24346340f421cf7350fb5b9a4277a1ca71d030 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1115,7 +1115,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs return bytes_to_frames(substream->runtime, ptr); } -static struct snd_pcm_hardware snd_intel8x0_stream = +static const struct snd_pcm_hardware snd_intel8x0_stream = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1367,7 +1367,7 @@ static int snd_intel8x0_ali_spdifout_close(struct snd_pcm_substream *substream) } #endif -static struct snd_pcm_ops snd_intel8x0_playback_ops = { +static const struct snd_pcm_ops snd_intel8x0_playback_ops = { .open = snd_intel8x0_playback_open, .close = snd_intel8x0_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1378,7 +1378,7 @@ static struct snd_pcm_ops snd_intel8x0_playback_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture_ops = { .open = snd_intel8x0_capture_open, .close = snd_intel8x0_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -1389,7 +1389,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { .open = snd_intel8x0_mic_open, .close = snd_intel8x0_mic_close, .ioctl = snd_pcm_lib_ioctl, @@ -1400,7 +1400,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { .open = snd_intel8x0_mic2_open, .close = snd_intel8x0_mic2_close, .ioctl = snd_pcm_lib_ioctl, @@ -1411,7 +1411,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture2_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture2_ops = { .open = snd_intel8x0_capture2_open, .close = snd_intel8x0_capture2_close, .ioctl = snd_pcm_lib_ioctl, @@ -1422,7 +1422,7 @@ static struct snd_pcm_ops snd_intel8x0_capture2_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_spdif_ops = { +static const struct snd_pcm_ops snd_intel8x0_spdif_ops = { .open = snd_intel8x0_spdif_open, .close = snd_intel8x0_spdif_close, .ioctl = snd_pcm_lib_ioctl, @@ -1433,7 +1433,7 @@ static struct snd_pcm_ops snd_intel8x0_spdif_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { .open = snd_intel8x0_playback_open, .close = snd_intel8x0_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1444,7 +1444,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { .open = snd_intel8x0_capture_open, .close = snd_intel8x0_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -1455,7 +1455,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { .open = snd_intel8x0_mic_open, .close = snd_intel8x0_mic_close, .ioctl = snd_pcm_lib_ioctl, @@ -1466,7 +1466,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = { .open = snd_intel8x0_ali_ac97spdifout_open, .close = snd_intel8x0_ali_ac97spdifout_close, .ioctl = snd_pcm_lib_ioctl, @@ -1503,8 +1503,8 @@ static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = { struct ich_pcm_table { char *suffix; - struct snd_pcm_ops *playback_ops; - struct snd_pcm_ops *capture_ops; + const struct snd_pcm_ops *playback_ops; + const struct snd_pcm_ops *capture_ops; size_t prealloc_size; size_t prealloc_max_size; int ac97_idx; @@ -1721,7 +1721,7 @@ static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97) chip->ac97[ac97->num] = NULL; } -static struct ac97_pcm ac97_pcm_defs[] = { +static const struct ac97_pcm ac97_pcm_defs[] = { /* front PCM */ { .exclusive = 1, diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 18ff668ce7a561dcd10a013f02234bd22844ddbf..3a4769a97d290ab028b5720d0216b5d962b73013 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -611,7 +611,7 @@ static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_hardware snd_intel8x0m_stream = +static const struct snd_pcm_hardware snd_intel8x0m_stream = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -685,7 +685,7 @@ static int snd_intel8x0m_capture_close(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_intel8x0m_playback_ops = { +static const struct snd_pcm_ops snd_intel8x0m_playback_ops = { .open = snd_intel8x0m_playback_open, .close = snd_intel8x0m_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -696,7 +696,7 @@ static struct snd_pcm_ops snd_intel8x0m_playback_ops = { .pointer = snd_intel8x0m_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0m_capture_ops = { +static const struct snd_pcm_ops snd_intel8x0m_capture_ops = { .open = snd_intel8x0m_capture_open, .close = snd_intel8x0m_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -710,8 +710,8 @@ static struct snd_pcm_ops snd_intel8x0m_capture_ops = { struct ich_pcm_table { char *suffix; - struct snd_pcm_ops *playback_ops; - struct snd_pcm_ops *capture_ops; + const struct snd_pcm_ops *playback_ops; + const struct snd_pcm_ops *capture_ops; size_t prealloc_size; size_t prealloc_max_size; int ac97_idx; diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index b28fe4914d6b6db70aec6b7c18a9f33022411e5e..04cd71c74e5ceac3bdd790cc64d1e39dd4543240 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -1231,7 +1231,7 @@ static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212) return 0; } -static struct snd_pcm_hardware snd_korg1212_playback_info = +static const struct snd_pcm_hardware snd_korg1212_playback_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -1252,7 +1252,7 @@ static struct snd_pcm_hardware snd_korg1212_playback_info = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_korg1212_capture_info = +static const struct snd_pcm_hardware snd_korg1212_capture_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c index 1268ba329016f77c54bb7ed4769ab4a7ea31cc4a..310b26a756c94339c2a0e52ec14c8ed78e500b2e 100644 --- a/sound/pci/lola/lola_pcm.c +++ b/sound/pci/lola/lola_pcm.c @@ -197,7 +197,7 @@ static void lola_stream_reset(struct lola *chip, struct lola_stream *str) } } -static struct snd_pcm_hardware lola_pcm_hw = { +static const struct snd_pcm_hardware lola_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index f9c3e86d55d5515b2b834fc6e0b96410b65c8ecf..9655b08a1c52f194c7b627ba32732dab604f5929 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c @@ -77,7 +77,7 @@ MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids); /* alsa callbacks */ -static struct snd_pcm_hardware lx_caps = { +static const struct snd_pcm_hardware lx_caps = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index cafea6dc5c0105b6d1bdedc3545c5b1bcac925ec..8f20dec97843edf05df2ea27f5c816fc51f15f1e 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -1681,7 +1681,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) /* */ -static struct snd_pcm_hardware snd_m3_playback = +static const struct snd_pcm_hardware snd_m3_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -1702,7 +1702,7 @@ static struct snd_pcm_hardware snd_m3_playback = .periods_max = 1024, }; -static struct snd_pcm_hardware snd_m3_capture = +static const struct snd_pcm_hardware snd_m3_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -2622,22 +2622,18 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); - if (err < 0) { - snd_m3_free(chip); - return err; - } + if (err < 0) + goto free_chip; err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); - if (err < 0) { - snd_m3_free(chip); - return err; - } + if (err < 0) + goto free_chip; + + err = pci_request_regions(pci, card->driver); + if (err < 0) + goto free_chip; - if ((err = pci_request_regions(pci, card->driver)) < 0) { - snd_m3_free(chip); - return err; - } chip->iobase = pci_resource_start(pci, 0); /* just to be sure */ @@ -2655,8 +2651,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); - snd_m3_free(chip); - return -ENOMEM; + err = -ENOMEM; + goto free_chip; } chip->irq = pci->irq; @@ -2666,10 +2662,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, dev_warn(card->dev, "can't allocate apm buffer\n"); #endif - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_m3_free(chip); - return err; - } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) + goto free_chip; if ((err = snd_m3_mixer(chip)) < 0) return err; @@ -2699,6 +2694,10 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, *chip_ret = chip; return 0; + +free_chip: + snd_m3_free(chip); + return err; } /* @@ -2741,23 +2740,19 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) break; } - if ((err = snd_m3_create(card, pci, - external_amp[dev], - amp_gpio[dev], - &chip)) < 0) { - snd_card_free(card); - return err; - } + err = snd_m3_create(card, pci, external_amp[dev], amp_gpio[dev], &chip); + if (err < 0) + goto free_card; + card->private_data = chip; sprintf(card->shortname, "ESS %s PCI", card->driver); sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, chip->iobase, chip->irq); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto free_card; #if 0 /* TODO: not supported yet */ /* TODO enable MIDI IRQ and I/O */ @@ -2772,6 +2767,10 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) pci_set_drvdata(pci, card); dev++; return 0; + +free_card: + snd_card_free(card); + return err; } static void snd_m3_remove(struct pci_dev *pci) diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 80d439944cb52777af180a5cadfb9dcc344cbf15..a74f1ad7e7b85900583b37e050d890360b869546 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -675,7 +675,7 @@ static int snd_mixart_hw_free(struct snd_pcm_substream *subs) /* * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max */ -static struct snd_pcm_hardware snd_mixart_analog_caps = +static const struct snd_pcm_hardware snd_mixart_analog_caps = { .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -696,7 +696,7 @@ static struct snd_pcm_hardware snd_mixart_analog_caps = .periods_max = (32*1024/256), }; -static struct snd_pcm_hardware snd_mixart_digital_caps = +static const struct snd_pcm_hardware snd_mixart_digital_caps = { .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1052,10 +1052,8 @@ static int snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int }; chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (! chip) { - dev_err(card->dev, "cannot allocate chip\n"); + if (!chip) return -ENOMEM; - } chip->card = card; chip->chip_idx = idx; @@ -1313,9 +1311,6 @@ static int snd_mixart_probe(struct pci_dev *pci, } mgr->irq = pci->irq; - sprintf(mgr->shortname, "Digigram miXart"); - sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, irq %i", mgr->shortname, mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq); - /* init mailbox */ mgr->msg_fifo_readptr = 0; mgr->msg_fifo_writeptr = 0; @@ -1350,8 +1345,11 @@ static int snd_mixart_probe(struct pci_dev *pci, } strcpy(card->driver, CARD_NAME); - sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i); - sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); + snprintf(card->shortname, sizeof(card->shortname), + "Digigram miXart [PCM #%d]", i); + snprintf(card->longname, sizeof(card->longname), + "Digigram miXart at 0x%lx & 0x%lx, irq %i [PCM #%d]", + mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq, i); if ((err = snd_mixart_create(mgr, card, i)) < 0) { snd_card_free(card); diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h index 4267438715402ce8e62bc10966f3fa6cab16d397..69b3ece099ad8f386a6bc9785aa973b572e0c8ac 100644 --- a/sound/pci/mixart/mixart.h +++ b/sound/pci/mixart/mixart.h @@ -74,10 +74,6 @@ struct mixart_mgr { /* memory-maps */ struct mem_area mem[2]; - /* share the name */ - char shortname[32]; /* short name of this soundcard */ - char longname[80]; /* name of this soundcard */ - /* one and only blocking message or notification may be pending */ u32 pending_event; wait_queue_head_t msg_sleep; diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 0ef8054c393643ff45a463827fcddbba2d67cc30..b97f4ea6b56c810948fc39ca0845eec0a060ca87 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -1271,7 +1271,7 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97, } /* static resolution table */ -static struct snd_ac97_res_table nm256_res_table[] = { +static const struct snd_ac97_res_table nm256_res_table[] = { { AC97_MASTER, 0x1f1f }, { AC97_HEADPHONE, 0x1f1f }, { AC97_MASTER_MONO, 0x001f }, diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index bb7eee9d0c2bbb695159641368843620f9aa32c4..f9ae72f28ddc4f5979bf532259933f146f54cfd4 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -986,7 +986,7 @@ static int pcxhr_hw_free(struct snd_pcm_substream *subs) /* * CONFIGURATION SPACE for all pcms, mono pcm must update channels_max */ -static struct snd_pcm_hardware pcxhr_caps = +static const struct snd_pcm_hardware pcxhr_caps = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -1165,7 +1165,7 @@ int pcxhr_create_pcm(struct snd_pcxhr *chip) struct snd_pcm *pcm; char name[32]; - sprintf(name, "pcxhr %d", chip->chip_idx); + snprintf(name, sizeof(name), "pcxhr %d", chip->chip_idx); if ((err = snd_pcm_new(chip->card, name, 0, chip->nb_streams_play, chip->nb_streams_capt, &pcm)) < 0) { @@ -1215,10 +1215,8 @@ static int pcxhr_create(struct pcxhr_mgr *mgr, }; chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (! chip) { - dev_err(card->dev, "cannot allocate chip\n"); + if (!chip) return -ENOMEM; - } chip->card = card; chip->chip_idx = idx; @@ -1252,7 +1250,7 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_pcxhr *chip = entry->private_data; struct pcxhr_mgr *mgr = chip->mgr; - snd_iprintf(buffer, "\n%s\n", mgr->longname); + snd_iprintf(buffer, "\n%s\n", mgr->name); /* stats available when embedded DSP is running */ if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { @@ -1339,7 +1337,7 @@ static void pcxhr_proc_sync(struct snd_info_entry *entry, max_clock = PCXHR_CLOCK_TYPE_MAX; } - snd_iprintf(buffer, "\n%s\n", mgr->longname); + snd_iprintf(buffer, "\n%s\n", mgr->name); snd_iprintf(buffer, "Current Sample Clock\t: %s\n", texts[mgr->cur_clock_type]); snd_iprintf(buffer, "Current Sample Rate\t= %d\n", @@ -1597,10 +1595,9 @@ static int pcxhr_probe(struct pci_dev *pci, } mgr->irq = pci->irq; - sprintf(mgr->shortname, "Digigram %s", card_name); - sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i", - mgr->shortname, - mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); + snprintf(mgr->name, sizeof(mgr->name), + "Digigram at 0x%lx & 0x%lx, 0x%lx irq %i", + mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); /* ISR lock */ mutex_init(&mgr->lock); @@ -1644,8 +1641,10 @@ static int pcxhr_probe(struct pci_dev *pci, } strcpy(card->driver, DRIVER_NAME); - sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i); - sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); + snprintf(card->shortname, sizeof(card->shortname), + "Digigram [PCM #%d]", i); + snprintf(card->longname, sizeof(card->longname), + "%s [PCM #%d]", mgr->name, i); if ((err = pcxhr_create(mgr, card, i)) < 0) { snd_card_free(card); diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index 9e39e509a3ef9375db81b853b8e61983a4de9c9c..d799cbd37301be7b6ff5c22b0d4b1ed0485b21ed 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h @@ -75,8 +75,7 @@ struct pcxhr_mgr { unsigned long port[3]; /* share the name */ - char shortname[32]; /* short name of this soundcard */ - char longname[96]; /* name of this soundcard */ + char name[40]; /* name of this soundcard */ struct pcxhr_rmh *prmh; diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index 36875df30dbf0035287b787dcda5d37ec449b881..d9a1c6c50a87d2d8a8028b14c4bc32d28bb08766 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c @@ -185,7 +185,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol, return changed; } -static struct snd_kcontrol_new pcxhr_control_analog_level = { +static const struct snd_kcontrol_new pcxhr_control_analog_level = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), @@ -409,7 +409,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol, return changed; } -static struct snd_kcontrol_new snd_pcxhr_pcm_vol = +static const struct snd_kcontrol_new snd_pcxhr_pcm_vol = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index f067c76d77f82978469f8d58aa0bc6960df95a7f..44f3b48d47b1000bafaa209752c30cac2c26b164 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1315,7 +1315,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) return 0; } -static struct snd_pcm_hardware snd_riptide_playback = { +static const struct snd_pcm_hardware snd_riptide_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), @@ -1334,7 +1334,7 @@ static struct snd_pcm_hardware snd_riptide_playback = { .periods_max = 64, .fifo_size = 0, }; -static struct snd_pcm_hardware snd_riptide_capture = { +static const struct snd_pcm_hardware snd_riptide_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index e4cdef94e4a2ee972a688c2b22d33e7453b7e10f..f0906ba416d42f3330d40f796c368ce6e9b5f82b 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -314,7 +314,7 @@ static int snd_rme32_capture_copy_kernel(struct snd_pcm_substream *substream, /* * SPDIF I/O capabilities (half-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_spdif_info = { +static const struct snd_pcm_hardware snd_rme32_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -340,7 +340,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_info = { /* * ADAT I/O capabilities (half-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_adat_info = +static const struct snd_pcm_hardware snd_rme32_adat_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -365,7 +365,7 @@ static struct snd_pcm_hardware snd_rme32_adat_info = /* * SPDIF I/O capabilities (full-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { +static const struct snd_pcm_hardware snd_rme32_spdif_fd_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -391,7 +391,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { /* * ADAT I/O capabilities (full-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_adat_fd_info = +static const struct snd_pcm_hardware snd_rme32_adat_fd_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 2e19ba55e754f34d3eaa0516e6d45d591713740e..dcfa4d7a73e2bcb86e5e67fb495abe8dd26cdab6 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -384,7 +384,7 @@ snd_rme96_capture_copy_kernel(struct snd_pcm_substream *substream, /* * Digital output capabilities (S/PDIF) */ -static struct snd_pcm_hardware snd_rme96_playback_spdif_info = +static const struct snd_pcm_hardware snd_rme96_playback_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -415,7 +415,7 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info = /* * Digital input capabilities (S/PDIF) */ -static struct snd_pcm_hardware snd_rme96_capture_spdif_info = +static const struct snd_pcm_hardware snd_rme96_capture_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -446,7 +446,7 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info = /* * Digital output capabilities (ADAT) */ -static struct snd_pcm_hardware snd_rme96_playback_adat_info = +static const struct snd_pcm_hardware snd_rme96_playback_adat_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -473,7 +473,7 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info = /* * Digital input capabilities (ADAT) */ -static struct snd_pcm_hardware snd_rme96_capture_adat_info = +static const struct snd_pcm_hardware snd_rme96_capture_adat_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -1199,7 +1199,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); spin_lock_irq(&rme96->lock); - if (rme96->playback_substream != NULL) { + if (rme96->playback_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1248,7 +1248,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream) } spin_lock_irq(&rme96->lock); - if (rme96->capture_substream != NULL) { + if (rme96->capture_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1268,7 +1268,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); spin_lock_irq(&rme96->lock); - if (rme96->playback_substream != NULL) { + if (rme96->playback_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1315,7 +1315,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream) } spin_lock_irq(&rme96->lock); - if (rme96->capture_substream != NULL) { + if (rme96->capture_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1578,9 +1578,9 @@ snd_rme96_free(void *private_data) { struct rme96 *rme96 = (struct rme96 *)private_data; - if (rme96 == NULL) { + if (!rme96) return; - } + if (rme96->irq >= 0) { snd_rme96_trigger(rme96, RME96_STOP_BOTH); rme96->areg &= ~RME96_AR_DAC_EN; @@ -2481,25 +2481,20 @@ snd_rme96_probe(struct pci_dev *pci, rme96 = card->private_data; rme96->card = card; rme96->pci = pci; - if ((err = snd_rme96_create(rme96)) < 0) { - snd_card_free(card); - return err; - } + err = snd_rme96_create(rme96); + if (err) + goto free_card; #ifdef CONFIG_PM_SLEEP rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); if (!rme96->playback_suspend_buffer) { - dev_err(card->dev, - "Failed to allocate playback suspend buffer!\n"); - snd_card_free(card); - return -ENOMEM; + err = -ENOMEM; + goto free_card; } rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); if (!rme96->capture_suspend_buffer) { - dev_err(card->dev, - "Failed to allocate capture suspend buffer!\n"); - snd_card_free(card); - return -ENOMEM; + err = -ENOMEM; + goto free_card; } #endif @@ -2525,14 +2520,16 @@ snd_rme96_probe(struct pci_dev *pci, } sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, rme96->port, rme96->irq); - - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err) + goto free_card; + pci_set_drvdata(pci, card); dev++; return 0; +free_card: + snd_card_free(card); + return err; } static void snd_rme96_remove(struct pci_dev *pci) diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index fe36d44d16c6de9a8f45abd404ab4dc41c947a83..9f0f73875f01d8a0ed2a373d725a23a1e6c0b5ed 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -793,11 +793,8 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM); hdsp_write (hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { - hdsp->io_type = Multiface; - dev_info(hdsp->card->dev, "Multiface found\n"); - return 0; - } + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) + goto set_multi; hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write(hdsp, HDSP_fifoData, 0); @@ -810,20 +807,14 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write(hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { - hdsp->io_type = Multiface; - dev_info(hdsp->card->dev, "Multiface found\n"); - return 0; - } + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) + goto set_multi; hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write(hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { - hdsp->io_type = Multiface; - dev_info(hdsp->card->dev, "Multiface found\n"); - return 0; - } + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) + goto set_multi; hdsp->io_type = RPM; dev_info(hdsp->card->dev, "RPM found\n"); @@ -838,6 +829,11 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp->io_type = Digiface; } return 0; + +set_multi: + hdsp->io_type = Multiface; + dev_info(hdsp->card->dev, "Multiface found\n"); + return 0; } @@ -4211,7 +4207,7 @@ static int snd_hdsp_prepare(struct snd_pcm_substream *substream) return result; } -static struct snd_pcm_hardware snd_hdsp_playback_subinfo = +static const struct snd_pcm_hardware snd_hdsp_playback_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -4241,7 +4237,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo = .fifo_size = 0 }; -static struct snd_pcm_hardware snd_hdsp_capture_subinfo = +static const struct snd_pcm_hardware snd_hdsp_capture_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -5381,17 +5377,16 @@ static int snd_hdsp_probe(struct pci_dev *pci, card->private_free = snd_hdsp_card_free; hdsp->dev = dev; hdsp->pci = pci; - - if ((err = snd_hdsp_create(card, hdsp)) < 0) { - snd_card_free(card); - return err; - } + err = snd_hdsp_create(card, hdsp); + if (err) + goto free_card; strcpy(card->shortname, "Hammerfall DSP"); sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name, hdsp->port, hdsp->irq); - - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err) { +free_card: snd_card_free(card); return err; } diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 254c3d040118adce4d518f5a729a25fc1c4e6e1c..f20d42714e4db0378b9400247870585f8f9fb270 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1521,7 +1521,7 @@ static void hdspm_silence_playback(struct hdspm *hdspm) int n = hdspm->period_bytes; void *buf = hdspm->playback_buffer; - if (buf == NULL) + if (!buf) return; for (i = 0; i < HDSPM_MAX_CHANNELS; i++) { @@ -2061,7 +2061,7 @@ static int snd_hdspm_create_midi(struct snd_card *card, struct hdspm *hdspm, int id) { int err; - char buf[32]; + char buf[64]; hdspm->midi[id].id = id; hdspm->midi[id].hdspm = hdspm; @@ -2120,19 +2120,23 @@ static int snd_hdspm_create_midi(struct snd_card *card, if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) || (MADIface == hdspm->io_type)))) { if ((id == 0) && (MADIface == hdspm->io_type)) { - sprintf(buf, "%s MIDIoverMADI", card->shortname); + snprintf(buf, sizeof(buf), "%s MIDIoverMADI", + card->shortname); } else if ((id == 2) && (MADI == hdspm->io_type)) { - sprintf(buf, "%s MIDIoverMADI", card->shortname); + snprintf(buf, sizeof(buf), "%s MIDIoverMADI", + card->shortname); } else { - sprintf(buf, "%s MIDI %d", card->shortname, id+1); + snprintf(buf, sizeof(buf), "%s MIDI %d", + card->shortname, id+1); } err = snd_rawmidi_new(card, buf, id, 1, 1, &hdspm->midi[id].rmidi); if (err < 0) return err; - sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d", - card->id, id+1); + snprintf(hdspm->midi[id].rmidi->name, + sizeof(hdspm->midi[id].rmidi->name), + "%s MIDI %d", card->id, id+1); hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; snd_rawmidi_set_ops(hdspm->midi[id].rmidi, @@ -2148,14 +2152,16 @@ static int snd_hdspm_create_midi(struct snd_card *card, SNDRV_RAWMIDI_INFO_DUPLEX; } else { /* TCO MTC, read only */ - sprintf(buf, "%s MTC %d", card->shortname, id+1); + snprintf(buf, sizeof(buf), "%s MTC %d", + card->shortname, id+1); err = snd_rawmidi_new(card, buf, id, 1, 1, &hdspm->midi[id].rmidi); if (err < 0) return err; - sprintf(hdspm->midi[id].rmidi->name, - "%s MTC %d", card->id, id+1); + snprintf(hdspm->midi[id].rmidi->name, + sizeof(hdspm->midi[id].rmidi->name), + "%s MTC %d", card->id, id+1); hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; snd_rawmidi_set_ops(hdspm->midi[id].rmidi, @@ -4700,7 +4706,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, break; } - if (NULL != list) { + if (list) { for (idx = 0; idx < limit; idx++) { err = snd_ctl_add(card, snd_ctl_new1(&list[idx], hdspm)); @@ -6063,13 +6069,13 @@ static int snd_hdspm_open(struct snd_pcm_substream *substream) snd_hdspm_capture_subinfo; if (playback) { - if (hdspm->capture_substream == NULL) + if (!hdspm->capture_substream) hdspm_stop_audio(hdspm); hdspm->playback_pid = current->pid; hdspm->playback_substream = substream; } else { - if (hdspm->playback_substream == NULL) + if (!hdspm->playback_substream) hdspm_stop_audio(hdspm); hdspm->capture_pid = current->pid; @@ -6215,7 +6221,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, } levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms)); + s = copy_to_user(argp, levels, sizeof(*levels)); if (0 != s) { /* dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu [Levels]\n", sizeof(struct hdspm_peak_rms), s); @@ -6260,7 +6266,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, ltc.input_format = no_video; } - s = copy_to_user(argp, <c, sizeof(struct hdspm_ltc)); + s = copy_to_user(argp, <c, sizeof(ltc)); if (0 != s) { /* dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */ @@ -6351,7 +6357,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, if (copy_from_user(&mixer, argp, sizeof(mixer))) return -EFAULT; if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, - sizeof(struct hdspm_mixer))) + sizeof(*mixer.mixer))) return -EFAULT; break; @@ -6630,14 +6636,10 @@ static int snd_hdspm_create(struct snd_card *card, hdspm->irq = pci->irq; dev_dbg(card->dev, "kmalloc Mixer memory of %zd Bytes\n", - sizeof(struct hdspm_mixer)); - hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); - if (!hdspm->mixer) { - dev_err(card->dev, - "unable to kmalloc Mixer memory of %d Bytes\n", - (int)sizeof(struct hdspm_mixer)); + sizeof(*hdspm->mixer)); + hdspm->mixer = kzalloc(sizeof(*hdspm->mixer), GFP_KERNEL); + if (!hdspm->mixer) return -ENOMEM; - } hdspm->port_names_in = NULL; hdspm->port_names_out = NULL; @@ -6772,11 +6774,10 @@ static int snd_hdspm_create(struct snd_card *card, if (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_tco_detect) { hdspm->midiPorts++; - hdspm->tco = kzalloc(sizeof(struct hdspm_tco), - GFP_KERNEL); - if (NULL != hdspm->tco) { + hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL); + if (hdspm->tco) hdspm_tco_write(hdspm); - } + dev_info(card->dev, "AIO/RayDAT TCO module found\n"); } else { hdspm->tco = NULL; @@ -6787,11 +6788,10 @@ static int snd_hdspm_create(struct snd_card *card, case AES32: if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { hdspm->midiPorts++; - hdspm->tco = kzalloc(sizeof(struct hdspm_tco), - GFP_KERNEL); - if (NULL != hdspm->tco) { + hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL); + if (hdspm->tco) hdspm_tco_write(hdspm); - } + dev_info(card->dev, "MADI/AES TCO module found\n"); } else { hdspm->tco = NULL; @@ -6868,8 +6868,9 @@ static int snd_hdspm_create(struct snd_card *card, * this case, we don't set card->id to avoid collisions * when running with multiple cards. */ - if (NULL == id[hdspm->dev] && hdspm->serial != 0xFFFFFF) { - sprintf(card->id, "HDSPMx%06x", hdspm->serial); + if (!id[hdspm->dev] && hdspm->serial != 0xFFFFFF) { + snprintf(card->id, sizeof(card->id), + "HDSPMx%06x", hdspm->serial); snd_card_set_id(card, card->id); } } @@ -6938,7 +6939,7 @@ static int snd_hdspm_probe(struct pci_dev *pci, } err = snd_card_new(&pci->dev, index[dev], id[dev], - THIS_MODULE, sizeof(struct hdspm), &card); + THIS_MODULE, sizeof(*hdspm), &card); if (err < 0) return err; @@ -6948,35 +6949,36 @@ static int snd_hdspm_probe(struct pci_dev *pci, hdspm->pci = pci; err = snd_hdspm_create(card, hdspm); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; if (hdspm->io_type != MADIface) { - sprintf(card->shortname, "%s_%x", - hdspm->card_name, - hdspm->serial); - sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d", - hdspm->card_name, - hdspm->serial, - hdspm->port, hdspm->irq); + snprintf(card->shortname, sizeof(card->shortname), "%s_%x", + hdspm->card_name, hdspm->serial); + snprintf(card->longname, sizeof(card->longname), + "%s S/N 0x%x at 0x%lx, irq %d", + hdspm->card_name, hdspm->serial, + hdspm->port, hdspm->irq); } else { - sprintf(card->shortname, "%s", hdspm->card_name); - sprintf(card->longname, "%s at 0x%lx, irq %d", - hdspm->card_name, hdspm->port, hdspm->irq); + snprintf(card->shortname, sizeof(card->shortname), "%s", + hdspm->card_name); + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d", + hdspm->card_name, hdspm->port, hdspm->irq); } err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; pci_set_drvdata(pci, card); dev++; return 0; + +free_card: + snd_card_free(card); + return err; } static void snd_hdspm_remove(struct pci_dev *pci) diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 150d08898db8c700ff9f3ff803f9cf1177aa380a..df648b1d92177c30c2380b96de4e9ebd24fb07aa 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -2181,7 +2181,7 @@ static int snd_rme9652_prepare(struct snd_pcm_substream *substream) return result; } -static struct snd_pcm_hardware snd_rme9652_playback_subinfo = +static const struct snd_pcm_hardware snd_rme9652_playback_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -2205,7 +2205,7 @@ static struct snd_pcm_hardware snd_rme9652_playback_subinfo = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_rme9652_capture_subinfo = +static const struct snd_pcm_hardware snd_rme9652_capture_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -2618,19 +2618,17 @@ static int snd_rme9652_probe(struct pci_dev *pci, card->private_free = snd_rme9652_card_free; rme9652->dev = dev; rme9652->pci = pci; - - if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) { - snd_card_free(card); - return err; - } + err = snd_rme9652_create(card, rme9652, precise_ptr[dev]); + if (err) + goto free_card; strcpy(card->shortname, rme9652->card_name); sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, rme9652->port, rme9652->irq); - - - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err) { +free_card: snd_card_free(card); return err; } diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index f3860b850210152f2333be252a887d9ac6c15319..964acf302479ae45159fd930e540dca231ff7d98 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -159,7 +159,7 @@ struct sis7019 { * We'll add a constraint upon open that limits the period and buffer sample * size to values that are legal for the hardware. */ -static struct snd_pcm_hardware sis_playback_hw_info = { +static const struct snd_pcm_hardware sis_playback_hw_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -180,7 +180,7 @@ static struct snd_pcm_hardware sis_playback_hw_info = { .periods_max = (0xfff9 / 9), }; -static struct snd_pcm_hardware sis_capture_hw_info = { +static const struct snd_pcm_hardware sis_capture_hw_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -872,7 +872,7 @@ static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops sis_playback_ops = { +static const struct snd_pcm_ops sis_playback_ops = { .open = sis_playback_open, .close = sis_substream_close, .ioctl = snd_pcm_lib_ioctl, @@ -883,7 +883,7 @@ static struct snd_pcm_ops sis_playback_ops = { .pointer = sis_pcm_pointer, }; -static struct snd_pcm_ops sis_capture_ops = { +static const struct snd_pcm_ops sis_capture_ops = { .open = sis_capture_open, .close = sis_substream_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 784d762f18a770778da6c96849ca4ecba648325d..a8abb15e3c3ab0d3bce8b7c984d15d826b8699bd 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -776,7 +776,7 @@ static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(struct snd_pcm_substream return bytes_to_frames(substream->runtime, ptr); } -static struct snd_pcm_hardware snd_sonicvibes_playback = +static const struct snd_pcm_hardware snd_sonicvibes_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -795,7 +795,7 @@ static struct snd_pcm_hardware snd_sonicvibes_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sonicvibes_capture = +static const struct snd_pcm_hardware snd_sonicvibes_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 64d3b8eba4bb55cab9c8aa6959d252a101b6d021..eabd84d9ffee7728bef4184a06c4a1b9c494f870 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1727,7 +1727,7 @@ static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *sub * Playback support device description */ -static struct snd_pcm_hardware snd_trident_playback = +static const struct snd_pcm_hardware snd_trident_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1752,7 +1752,7 @@ static struct snd_pcm_hardware snd_trident_playback = * Capture support device description */ -static struct snd_pcm_hardware snd_trident_capture = +static const struct snd_pcm_hardware snd_trident_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1777,7 +1777,7 @@ static struct snd_pcm_hardware snd_trident_capture = * Foldback capture support device description */ -static struct snd_pcm_hardware snd_trident_foldback = +static const struct snd_pcm_hardware snd_trident_foldback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1801,7 +1801,7 @@ static struct snd_pcm_hardware snd_trident_foldback = * SPDIF playback support device description */ -static struct snd_pcm_hardware snd_trident_spdif = +static const struct snd_pcm_hardware snd_trident_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1822,7 +1822,7 @@ static struct snd_pcm_hardware snd_trident_spdif = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_trident_spdif_7018 = +static const struct snd_pcm_hardware snd_trident_spdif_7018 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -2093,7 +2093,7 @@ static const struct snd_pcm_ops snd_trident_nx_playback_ops = { .page = snd_pcm_sgbuf_ops_page, }; -static struct snd_pcm_ops snd_trident_capture_ops = { +static const struct snd_pcm_ops snd_trident_capture_ops = { .open = snd_trident_capture_open, .close = snd_trident_capture_close, .ioctl = snd_trident_ioctl, @@ -2104,7 +2104,7 @@ static struct snd_pcm_ops snd_trident_capture_ops = { .pointer = snd_trident_capture_pointer, }; -static struct snd_pcm_ops snd_trident_si7018_capture_ops = { +static const struct snd_pcm_ops snd_trident_si7018_capture_ops = { .open = snd_trident_capture_open, .close = snd_trident_capture_close, .ioctl = snd_trident_ioctl, @@ -3363,11 +3363,9 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident) trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4); /* allocate shadow TLB page table (virtual addresses) */ trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long)); - if (trident->tlb.shadow_entries == NULL) { - dev_err(trident->card->dev, - "unable to allocate shadow TLB entries\n"); + if (!trident->tlb.shadow_entries) return -ENOMEM; - } + /* allocate and setup silent page and initialise TLB entries */ if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) { diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index c767b8664359462023551e85a8e4b94f040beb7c..3a1c0b8b4ea276e840ce9f397cecc61610e736f6 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1150,7 +1150,7 @@ static int snd_via8233_capture_prepare(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for both playback and capture */ -static struct snd_pcm_hardware snd_via82xx_hw = +static const struct snd_pcm_hardware snd_via82xx_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 55f79b2599e7796a33a3d0bb149b9c84b58da684..8a69221c1b86db0410fa64a981bafd37e7a69c79 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -714,7 +714,7 @@ static int snd_via82xx_pcm_prepare(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for both playback and capture */ -static struct snd_pcm_hardware snd_via82xx_hw = +static const struct snd_pcm_hardware snd_via82xx_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 4faf3e1ed06a78ca3c1a46dc16fd596f51c7752b..eafdee38405931e82038683e4094c2a2d5b8a754 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -268,10 +268,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, if ((err = snd_ymfpci_create(card, pci, old_legacy_ctrl, &chip)) < 0) { - snd_card_free(card); release_and_free_resource(mpu_res); release_and_free_resource(fm_res); - return err; + goto free_card; } chip->fm_res = fm_res; chip->mpu_res = mpu_res; @@ -283,35 +282,31 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, card->shortname, chip->reg_area_phys, chip->irq); - if ((err = snd_ymfpci_pcm(chip, 0)) < 0) { - snd_card_free(card); - return err; - } - if ((err = snd_ymfpci_pcm_spdif(chip, 1)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ymfpci_pcm(chip, 0); + if (err < 0) + goto free_card; + + err = snd_ymfpci_pcm_spdif(chip, 1); + if (err < 0) + goto free_card; + err = snd_ymfpci_mixer(chip, rear_switch[dev]); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; + if (chip->ac97->ext_id & AC97_EI_SDAC) { err = snd_ymfpci_pcm_4ch(chip, 2); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; + err = snd_ymfpci_pcm2(chip, 3); - if (err < 0) { - snd_card_free(card); - return err; - } - } - if ((err = snd_ymfpci_timer(chip, 0)) < 0) { - snd_card_free(card); - return err; + if (err < 0) + goto free_card; } + err = snd_ymfpci_timer(chip, 0); + if (err < 0) + goto free_card; + if (chip->mpu_res) { if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, mpu_port[dev], @@ -336,21 +331,24 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, legacy_ctrl &= ~YMFPCI_LEGACY_FMEN; pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { - snd_card_free(card); dev_err(card->dev, "cannot create opl3 hwdep\n"); - return err; + goto free_card; } } snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto free_card; + pci_set_drvdata(pci, card); dev++; return 0; + +free_card: + snd_card_free(card); + return err; } static void snd_card_ymfpci_remove(struct pci_dev *pci) diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 1114166c685c5f7bded28c67d3786122b1913cc8..8ca2e41e58270044c1442eb8b5546688cd519c83 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -845,7 +845,7 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_ymfpci_playback = +static const struct snd_pcm_hardware snd_ymfpci_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -867,7 +867,7 @@ static struct snd_pcm_hardware snd_ymfpci_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ymfpci_capture = +static const struct snd_pcm_hardware snd_ymfpci_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -2399,59 +2399,60 @@ int snd_ymfpci_create(struct snd_card *card, dev_err(chip->card->dev, "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); - snd_ymfpci_free(chip); - return -EBUSY; + err = -EBUSY; + goto free_chip; } if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); - snd_ymfpci_free(chip); - return -EBUSY; + err = -EBUSY; + goto free_chip; } chip->irq = pci->irq; snd_ymfpci_aclink_reset(pci); if (snd_ymfpci_codec_ready(chip, 0) < 0) { - snd_ymfpci_free(chip); - return -EIO; + err = -EIO; + goto free_chip; } err = snd_ymfpci_request_firmware(chip); if (err < 0) { dev_err(chip->card->dev, "firmware request failed: %d\n", err); - snd_ymfpci_free(chip); - return err; + goto free_chip; } snd_ymfpci_download_image(chip); udelay(100); /* seems we need a delay after downloading image.. */ if (snd_ymfpci_memalloc(chip) < 0) { - snd_ymfpci_free(chip); - return -EIO; + err = -EIO; + goto free_chip; } - if ((err = snd_ymfpci_ac3_init(chip)) < 0) { - snd_ymfpci_free(chip); - return err; - } + err = snd_ymfpci_ac3_init(chip); + if (err < 0) + goto free_chip; #ifdef CONFIG_PM_SLEEP chip->saved_regs = kmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32), GFP_KERNEL); if (chip->saved_regs == NULL) { - snd_ymfpci_free(chip); - return -ENOMEM; + err = -ENOMEM; + goto free_chip; } #endif - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_ymfpci_free(chip); - return err; - } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) + goto free_chip; snd_ymfpci_proc_init(card, chip); *rchip = chip; return 0; + +free_chip: + snd_ymfpci_free(chip); + return err; } diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index b48aa0a78c19b42583d7d25e58dcdb94cb0cb61f..4a2354b5ae00b7f6a38e425b6e558f2165ed9aff 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -193,7 +193,7 @@ static int pdacf_pcm_prepare(struct snd_pcm_substream *subs) * capture hw information */ -static struct snd_pcm_hardware pdacf_pcm_capture_hw = { +static const struct snd_pcm_hardware pdacf_pcm_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID | @@ -266,7 +266,7 @@ static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *sub /* * operators for PCM capture */ -static struct snd_pcm_ops pdacf_pcm_capture_ops = { +static const struct snd_pcm_ops pdacf_pcm_capture_ops = { .open = pdacf_pcm_capture_open, .close = pdacf_pcm_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index a5843fc5ff204ee6efb32becd35e671927903f59..48dd44f8e914c3270b80da68de91d71db13086d1 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -509,7 +509,7 @@ static void snd_pmac_pcm_update(struct snd_pmac *chip, struct pmac_stream *rec) * hw info */ -static struct snd_pcm_hardware snd_pmac_playback = +static const struct snd_pcm_hardware snd_pmac_playback = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | @@ -528,7 +528,7 @@ static struct snd_pcm_hardware snd_pmac_playback = .periods_max = PMAC_MAX_FRAGS, }; -static struct snd_pcm_hardware snd_pmac_capture = +static const struct snd_pcm_hardware snd_pmac_capture = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | @@ -681,7 +681,7 @@ static int snd_pmac_capture_close(struct snd_pcm_substream *subs) /* */ -static struct snd_pcm_ops snd_pmac_playback_ops = { +static const struct snd_pcm_ops snd_pmac_playback_ops = { .open = snd_pmac_playback_open, .close = snd_pmac_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -692,7 +692,7 @@ static struct snd_pcm_ops snd_pmac_playback_ops = { .pointer = snd_pmac_playback_pointer, }; -static struct snd_pcm_ops snd_pmac_capture_ops = { +static const struct snd_pcm_ops snd_pmac_capture_ops = { .open = snd_pmac_capture_open, .close = snd_pmac_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index cdd44abfc9e0f13d0e4131dc11bb05522f7663b6..36f34f434ecb446ea1eeab31a628f8053a27edce 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -772,7 +772,7 @@ static struct snd_kcontrol_new spdif_ctls[] = { }, }; -static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = { +static const struct snd_pcm_ops snd_ps3_pcm_spdif_ops = { .open = snd_ps3_pcm_open, .close = snd_ps3_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sh/aica.c b/sound/sh/aica.c index ab4802df62e15013d72324c2731fb5b4acc08ae1..fdc680ae8aa09c037ac01cc6623e6f6d15797993 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -211,7 +211,7 @@ static void aica_chn_halt(void) } /* ALSA code below */ -static struct snd_pcm_hardware snd_pcm_aica_playback_hw = { +static const struct snd_pcm_hardware snd_pcm_aica_playback_hw = { .info = (SNDRV_PCM_INFO_NONINTERLEAVED), .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | @@ -436,7 +436,7 @@ static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER); } -static struct snd_pcm_ops snd_aicapcm_playback_ops = { +static const struct snd_pcm_ops snd_aicapcm_playback_ops = { .open = snd_aicapcm_pcm_open, .close = snd_aicapcm_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index c1e00ed715eee5c8dae8b7472b3c06aae2d58baa..834b2574786f50da6e986ff24eeffe8b3d3178db 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -93,7 +93,7 @@ static void dac_audio_set_rate(struct snd_sh_dac *chip) /* PCM INTERFACE */ -static struct snd_pcm_hardware snd_sh_dac_pcm_hw = { +static const struct snd_pcm_hardware snd_sh_dac_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -252,7 +252,7 @@ snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream) } /* pcm ops */ -static struct snd_pcm_ops snd_sh_dac_pcm_ops = { +static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { .open = snd_sh_dac_pcm_open, .close = snd_sh_dac_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -424,7 +424,7 @@ static int snd_sh_dac_probe(struct platform_device *devptr) if (err < 0) goto probe_error; - snd_printk("ALSA driver for SuperH DAC audio"); + snd_printk(KERN_INFO "ALSA driver for SuperH DAC audio"); platform_set_drvdata(devptr, card); return 0; diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index b7ef8c59b49a2bdb2895f2203e0c207170227c6f..8445edd067375d5349b0bba3bc5529c74f15d35c 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c @@ -32,7 +32,6 @@ struct atmel_classd { struct regmap *regmap; struct clk *pclk; struct clk *gclk; - struct clk *aclk; int irq; const struct atmel_classd_pdata *pdata; }; @@ -330,11 +329,6 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); - int ret; - - ret = clk_prepare_enable(dd->aclk); - if (ret) - return ret; return clk_prepare_enable(dd->gclk); } @@ -357,31 +351,31 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai, return 0; } -#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) -#define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) +#define CLASSD_GCLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) +#define CLASSD_GCLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) static struct { int rate; int sample_rate; int dsp_clk; - unsigned long aclk_rate; + unsigned long gclk_rate; } const sample_rates[] = { { 8000, CLASSD_INTPMR_FRAME_8K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 16000, CLASSD_INTPMR_FRAME_16K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 32000, CLASSD_INTPMR_FRAME_32K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 48000, CLASSD_INTPMR_FRAME_48K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 96000, CLASSD_INTPMR_FRAME_96K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 22050, CLASSD_INTPMR_FRAME_22K, - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, { 44100, CLASSD_INTPMR_FRAME_44K, - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, { 88200, CLASSD_INTPMR_FRAME_88K, - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, }; static int @@ -410,13 +404,12 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, } dev_dbg(codec->dev, - "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n", - sample_rates[best].rate, sample_rates[best].aclk_rate); + "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n", + sample_rates[best].rate, sample_rates[best].gclk_rate); clk_disable_unprepare(dd->gclk); - clk_disable_unprepare(dd->aclk); - ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate); + ret = clk_set_rate(dd->gclk, sample_rates[best].gclk_rate); if (ret) return ret; @@ -426,10 +419,6 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val); - ret = clk_prepare_enable(dd->aclk); - if (ret) - return ret; - return clk_prepare_enable(dd->gclk); } @@ -441,7 +430,6 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream, struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); clk_disable_unprepare(dd->gclk); - clk_disable_unprepare(dd->aclk); } static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, @@ -596,13 +584,6 @@ static int atmel_classd_probe(struct platform_device *pdev) return ret; } - dd->aclk = devm_clk_get(dev, "aclk"); - if (IS_ERR(dd->aclk)) { - ret = PTR_ERR(dd->aclk); - dev_err(dev, "failed to get audio clock: %d\n", ret); - return ret; - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); io_base = devm_ioremap_resource(dev, res); if (IS_ERR(io_base)) { @@ -652,7 +633,6 @@ static int atmel_classd_probe(struct platform_device *pdev) } snd_soc_card_set_drvdata(card, dd); - platform_set_drvdata(pdev, card); ret = atmel_classd_asoc_card_init(dev, card); if (ret) { diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index c917df7715d1b4fb7b315c7f81f32ebe3308f87d..8e3d34be9e690878be8c084ed9dfb1ff79a7b087 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c @@ -694,7 +694,6 @@ static int atmel_pdmic_probe(struct platform_device *pdev) } snd_soc_card_set_drvdata(card, dd); - platform_set_drvdata(pdev, card); ret = atmel_pdmic_asoc_card_init(dev, card); if (ret) { diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index 5c73061d912ad55a2cf51e75f9779bad900f9f33..301e1fc9a3773ffdb0b433284bcaa8f1b5f70b3d 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -99,7 +99,7 @@ static int db1200_i2s_startup(struct snd_pcm_substream *substream) return 0; } -static struct snd_soc_ops db1200_i2s_wm8731_ops = { +static const struct snd_soc_ops db1200_i2s_wm8731_ops = { .startup = db1200_i2s_startup, }; diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index b5d1caa04d8e77e275bfbfaaca2c9e6bd61a92ed..6a035ca0f521f71a17710dc6934d0a836338b372 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -304,7 +304,7 @@ static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops au1xpsc_pcm_ops = { +static const struct snd_pcm_ops au1xpsc_pcm_ops = { .open = au1xpsc_pcm_open, .close = au1xpsc_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index fcf5a9adde8170e67c861ca5bd75b9d84c0833af..19457e2b351ec158433497f6ca4d65c7e11c5db3 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -277,7 +277,7 @@ static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss) return bytes_to_frames(ss->runtime, location); } -static struct snd_pcm_ops alchemy_pcm_ops = { +static const struct snd_pcm_ops alchemy_pcm_ops = { .open = alchemy_pcm_open, .close = alchemy_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index bb53c705900522fdbeee6cced61d1fede15bd6d8..a2050ae5a3fe903ccde5045547529aecffd3dea6 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -474,7 +474,7 @@ static int au1xpsc_ac97_drvresume(struct device *dev) return 0; } -static struct dev_pm_ops au1xpscac97_pmops = { +static const struct dev_pm_ops au1xpscac97_pmops = { .suspend = au1xpsc_ac97_drvsuspend, .resume = au1xpsc_ac97_drvresume, }; diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 0bf9d62b91a07132fa1af21f902bfa257cdfee4b..e6eec081eaae03dd9f88f7285e6c331b79333fdf 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -392,7 +392,7 @@ static int au1xpsc_i2s_drvresume(struct device *dev) return 0; } -static struct dev_pm_ops au1xpsci2s_pmops = { +static const struct dev_pm_ops au1xpsci2s_pmops = { .suspend = au1xpsc_i2s_drvsuspend, .resume = au1xpsc_i2s_drvresume, }; diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c index e710bb0c56374b7fb97d41b588f535fc435a87e7..15c438f0f22d2e3ca8d5c53aa79ab6bbded78f04 100644 --- a/sound/soc/bcm/cygnus-ssp.c +++ b/sound/soc/bcm/cygnus-ssp.c @@ -27,12 +27,6 @@ #define DEFAULT_VCO 1354750204 -#define CYGNUS_TDM_RATE \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000) - #define CAPTURE_FCI_ID_BASE 0x180 #define CYGNUS_SSP_TRISTATE_MASK 0x001fff #define CYGNUS_PLLCLKSEL_MASK 0xf @@ -234,152 +228,20 @@ static const struct pll_macro_entry pll_predef_mclk[] = { {98304000, 2}, }; +#define CYGNUS_RATE_MIN 8000 +#define CYGNUS_RATE_MAX 384000 + /* List of valid frame sizes for tdm mode */ static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512}; -/* - * Use this relationship to derive the sampling rate (lrclk) - * lrclk = (mclk) / ((2*mclk_to_sclk_ratio) * (32 * SCLK))). - * - * Use mclk and pll_ch from the table above - * - * Valid SCLK = 0/1/2/4/8/12 - * - * mclk_to_sclk_ratio = number of MCLK per SCLK. Division is twice the - * value programmed in this field. - * Valid mclk_to_sclk_ratio = 1 through to 15 - * - * eg: To set lrclk = 48khz, set mclk = 12288000, mclk_to_sclk_ratio = 2, - * SCLK = 64 - */ -struct _ssp_clk_coeff { - u32 mclk; - u32 sclk_rate; - u32 rate; - u32 mclk_rate; +static const unsigned int cygnus_rates[] = { + 8000, 11025, 16000, 22050, 32000, 44100, 48000, + 88200, 96000, 176400, 192000, 352800, 384000 }; -static const struct _ssp_clk_coeff ssp_clk_coeff[] = { - { 4096000, 32, 16000, 4}, - { 4096000, 32, 32000, 2}, - { 4096000, 64, 8000, 4}, - { 4096000, 64, 16000, 2}, - { 4096000, 64, 32000, 1}, - { 4096000, 128, 8000, 2}, - { 4096000, 128, 16000, 1}, - { 4096000, 256, 8000, 1}, - - { 6144000, 32, 16000, 6}, - { 6144000, 32, 32000, 3}, - { 6144000, 32, 48000, 2}, - { 6144000, 32, 96000, 1}, - { 6144000, 64, 8000, 6}, - { 6144000, 64, 16000, 3}, - { 6144000, 64, 48000, 1}, - { 6144000, 128, 8000, 3}, - - { 8192000, 32, 32000, 4}, - { 8192000, 64, 16000, 4}, - { 8192000, 64, 32000, 2}, - { 8192000, 128, 8000, 4}, - { 8192000, 128, 16000, 2}, - { 8192000, 128, 32000, 1}, - { 8192000, 256, 8000, 2}, - { 8192000, 256, 16000, 1}, - { 8192000, 512, 8000, 1}, - - {12288000, 32, 32000, 6}, - {12288000, 32, 48000, 4}, - {12288000, 32, 96000, 2}, - {12288000, 32, 192000, 1}, - {12288000, 64, 16000, 6}, - {12288000, 64, 32000, 3}, - {12288000, 64, 48000, 2}, - {12288000, 64, 96000, 1}, - {12288000, 128, 8000, 6}, - {12288000, 128, 16000, 3}, - {12288000, 128, 48000, 1}, - {12288000, 256, 8000, 3}, - - {16384000, 64, 32000, 4}, - {16384000, 128, 16000, 4}, - {16384000, 128, 32000, 2}, - {16384000, 256, 8000, 4}, - {16384000, 256, 16000, 2}, - {16384000, 256, 32000, 1}, - {16384000, 512, 8000, 2}, - {16384000, 512, 16000, 1}, - - {24576000, 32, 96000, 4}, - {24576000, 32, 192000, 2}, - {24576000, 64, 32000, 6}, - {24576000, 64, 48000, 4}, - {24576000, 64, 96000, 2}, - {24576000, 64, 192000, 1}, - {24576000, 128, 16000, 6}, - {24576000, 128, 32000, 3}, - {24576000, 128, 48000, 2}, - {24576000, 256, 8000, 6}, - {24576000, 256, 16000, 3}, - {24576000, 256, 48000, 1}, - {24576000, 512, 8000, 3}, - - {49152000, 32, 192000, 4}, - {49152000, 64, 96000, 4}, - {49152000, 64, 192000, 2}, - {49152000, 128, 32000, 6}, - {49152000, 128, 48000, 4}, - {49152000, 128, 96000, 2}, - {49152000, 128, 192000, 1}, - {49152000, 256, 16000, 6}, - {49152000, 256, 32000, 3}, - {49152000, 256, 48000, 2}, - {49152000, 256, 96000, 1}, - {49152000, 512, 8000, 6}, - {49152000, 512, 16000, 3}, - {49152000, 512, 48000, 1}, - - { 5644800, 32, 22050, 4}, - { 5644800, 32, 44100, 2}, - { 5644800, 32, 88200, 1}, - { 5644800, 64, 11025, 4}, - { 5644800, 64, 22050, 2}, - { 5644800, 64, 44100, 1}, - - {11289600, 32, 44100, 4}, - {11289600, 32, 88200, 2}, - {11289600, 32, 176400, 1}, - {11289600, 64, 22050, 4}, - {11289600, 64, 44100, 2}, - {11289600, 64, 88200, 1}, - {11289600, 128, 11025, 4}, - {11289600, 128, 22050, 2}, - {11289600, 128, 44100, 1}, - - {22579200, 32, 88200, 4}, - {22579200, 32, 176400, 2}, - {22579200, 64, 44100, 4}, - {22579200, 64, 88200, 2}, - {22579200, 64, 176400, 1}, - {22579200, 128, 22050, 4}, - {22579200, 128, 44100, 2}, - {22579200, 128, 88200, 1}, - {22579200, 256, 11025, 4}, - {22579200, 256, 22050, 2}, - {22579200, 256, 44100, 1}, - - {45158400, 32, 176400, 4}, - {45158400, 64, 88200, 4}, - {45158400, 64, 176400, 2}, - {45158400, 128, 44100, 4}, - {45158400, 128, 88200, 2}, - {45158400, 128, 176400, 1}, - {45158400, 256, 22050, 4}, - {45158400, 256, 44100, 2}, - {45158400, 256, 88200, 1}, - {45158400, 512, 11025, 4}, - {45158400, 512, 22050, 2}, - {45158400, 512, 44100, 1}, +static const struct snd_pcm_hw_constraint_list cygnus_rate_constraint = { + .count = ARRAY_SIZE(cygnus_rates), + .list = cygnus_rates, }; static struct cygnus_aio_port *cygnus_dai_get_portinfo(struct snd_soc_dai *dai) @@ -679,40 +541,55 @@ static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk, return p_entry->pll_ch_num; } -static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio, - struct cygnus_audio *cygaud) +static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio) { - u32 value, i = 0; + u32 value; u32 mask = 0xf; u32 sclk; - bool found = false; - const struct _ssp_clk_coeff *p_entry = NULL; + u32 mclk_rate; + unsigned int bit_rate; + unsigned int ratio; - for (i = 0; i < ARRAY_SIZE(ssp_clk_coeff); i++) { - p_entry = &ssp_clk_coeff[i]; - if ((p_entry->rate == aio->lrclk) && - (p_entry->sclk_rate == aio->bit_per_frame) && - (p_entry->mclk == aio->mclk)) { - found = true; - break; - } - } - if (!found) { + bit_rate = aio->bit_per_frame * aio->lrclk; + + /* + * Check if the bit clock can be generated from the given MCLK. + * MCLK must be a perfect multiple of bit clock and must be one of the + * following values... (2,4,6,8,10,12,14) + */ + if ((aio->mclk % bit_rate) != 0) + return -EINVAL; + + ratio = aio->mclk / bit_rate; + switch (ratio) { + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + mclk_rate = ratio / 2; + break; + + default: dev_err(aio->cygaud->dev, - "No valid match found in ssp_clk_coeff array\n"); + "Invalid combination of MCLK and BCLK\n"); dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n", aio->lrclk, aio->bit_per_frame, aio->mclk); return -EINVAL; } - sclk = aio->bit_per_frame; - if (sclk == 512) - sclk = 0; - /* sclks_per_1fs_div = sclk cycles/32 */ - sclk /= 32; /* Set sclk rate */ switch (aio->port_type) { case PORT_TDM: + sclk = aio->bit_per_frame; + if (sclk == 512) + sclk = 0; + + /* sclks_per_1fs_div = sclk cycles/32 */ + sclk /= 32; + /* Set number of bitclks per frame */ value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); value &= ~(mask << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32); @@ -731,7 +608,7 @@ static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio, /* Set MCLK_RATE ssp port (spdif and ssp are the same) */ value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); value &= ~(0xf << I2S_OUT_MCLKRATE_SHIFT); - value |= (p_entry->mclk_rate << I2S_OUT_MCLKRATE_SHIFT); + value |= (mclk_rate << I2S_OUT_MCLKRATE_SHIFT); writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg); dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value); @@ -745,7 +622,6 @@ static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai); - struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai); int rate, bitres; u32 value; u32 mask = 0x1f; @@ -841,7 +717,7 @@ static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream, aio->lrclk = rate; if (!aio->is_slave) - ret = cygnus_ssp_set_clocks(aio, cygaud); + ret = cygnus_ssp_set_clocks(aio); return ret; } @@ -888,6 +764,11 @@ static int cygnus_ssp_startup(struct snd_pcm_substream *substream, else aio->clk_trace.cap_en = true; + substream->runtime->hw.rate_min = CYGNUS_RATE_MIN; + substream->runtime->hw.rate_max = CYGNUS_RATE_MAX; + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &cygnus_rate_constraint); return 0; } @@ -1261,9 +1142,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = { .playback = { \ .channels_min = 1, \ .channels_max = 16, \ - .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \ - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \ - SNDRV_PCM_RATE_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ @@ -1271,9 +1150,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = { .capture = { \ .channels_min = 2, \ .channels_max = 16, \ - .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \ - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \ - SNDRV_PCM_RATE_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ }, \ @@ -1288,14 +1165,12 @@ static const struct snd_soc_dai_driver cygnus_ssp_dai_info[] = { INIT_CPU_DAI(2), }; -static struct snd_soc_dai_driver cygnus_spdif_dai_info = { +static const struct snd_soc_dai_driver cygnus_spdif_dai_info = { .name = "cygnus-spdif", .playback = { .channels_min = 2, .channels_max = 2, - .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | - SNDRV_PCM_RATE_192000, + .rates = SNDRV_PCM_RATE_KNOT, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, }, diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 913e29275f4e5168804766959c9e1591fb88ef87..8c1d1983b8f9e00485037b863b9b886e58805c32 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -308,7 +308,7 @@ static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream, } #endif -static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { +static const struct snd_pcm_ops bf5xx_pcm_ac97_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 470d99abf6f64b0e504a060fd7b865e4031d05f2..51cae76f14e6ff4da1980e639f65ee37603a410f 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -318,7 +318,7 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, return 0; } -static struct snd_pcm_ops bf5xx_pcm_i2s_ops = { +static const struct snd_pcm_ops bf5xx_pcm_i2s_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c index bd3b4d4641451a1c35a5abef5e2e212ee27e5685..819cff149a25f80c3d42822c26783132dfce1af3 100644 --- a/sound/soc/blackfin/bf6xx-i2s.c +++ b/sound/soc/blackfin/bf6xx-i2s.c @@ -164,7 +164,7 @@ static int bfin_i2s_resume(struct snd_soc_dai *dai) #define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops bfin_i2s_dai_ops = { +static const struct snd_soc_dai_ops bfin_i2s_dai_ops = { .hw_params = bfin_i2s_hw_params, .set_fmt = bfin_i2s_set_dai_fmt, }; diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c index dfb744381c42cb2288b7bb7325fdb04b04338b82..d2caadfe7b6dce5905528f7c7fea59478843cf46 100644 --- a/sound/soc/blackfin/bf6xx-sport.c +++ b/sound/soc/blackfin/bf6xx-sport.c @@ -129,7 +129,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, for (i = 0; i < fragcount; ++i) { desc[i].next_desc_addr = &(desc[i + 1]); - desc[i].start_addr = (unsigned long)buf + i*fragsize; + desc[i].start_addr = (unsigned long)buf + i * fragsize; desc[i].cfg = cfg; desc[i].x_count = count; desc[i].x_modify = wdsize; @@ -138,7 +138,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, } /* make circular */ - desc[fragcount-1].next_desc_addr = desc; + desc[fragcount - 1].next_desc_addr = desc; } int sport_config_tx_dma(struct sport_device *sport, void *buf, @@ -148,7 +148,7 @@ int sport_config_tx_dma(struct sport_device *sport, void *buf, unsigned int cfg; dma_addr_t addr; - count = fragsize/sport->wdsize; + count = fragsize / sport->wdsize; if (sport->tx_desc) dma_free_coherent(NULL, sport->tx_desc_size, @@ -166,8 +166,7 @@ int sport_config_tx_dma(struct sport_device *sport, void *buf, cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6; setup_desc(sport->tx_desc, buf, fragcount, fragsize, - cfg|DMAEN, count, sport->wdsize); - + cfg | DMAEN, count, sport->wdsize); return 0; } EXPORT_SYMBOL(sport_config_tx_dma); @@ -179,7 +178,7 @@ int sport_config_rx_dma(struct sport_device *sport, void *buf, unsigned int cfg; dma_addr_t addr; - count = fragsize/sport->wdsize; + count = fragsize / sport->wdsize; if (sport->rx_desc) dma_free_coherent(NULL, sport->rx_desc_size, @@ -198,8 +197,7 @@ int sport_config_rx_dma(struct sport_device *sport, void *buf, | WNR | NDSIZE_6; setup_desc(sport->rx_desc, buf, fragcount, fragsize, - cfg|DMAEN, count, sport->wdsize); - + cfg | DMAEN, count, sport->wdsize); return 0; } EXPORT_SYMBOL(sport_config_rx_dma); @@ -226,7 +224,7 @@ static irqreturn_t sport_tx_irq(int irq, void *dev_id) static unsigned long status; status = get_dma_curr_irqstat(sport->tx_dma_chan); - if (status & (DMA_DONE|DMA_ERR)) { + if (status & (DMA_DONE | DMA_ERR)) { clear_dma_irqstat(sport->tx_dma_chan); SSYNC(); } @@ -241,7 +239,7 @@ static irqreturn_t sport_rx_irq(int irq, void *dev_id) unsigned long status; status = get_dma_curr_irqstat(sport->rx_dma_chan); - if (status & (DMA_DONE|DMA_ERR)) { + if (status & (DMA_DONE | DMA_ERR)) { clear_dma_irqstat(sport->rx_dma_chan); SSYNC(); } @@ -388,26 +386,24 @@ struct sport_device *sport_create(struct platform_device *pdev) int ret; sport = kzalloc(sizeof(*sport), GFP_KERNEL); - if (!sport) { - dev_err(dev, "Unable to allocate memory for sport device\n"); + if (!sport) return NULL; - } + sport->pdev = pdev; ret = sport_get_resource(sport); - if (ret) { - kfree(sport); - return NULL; - } + if (ret) + goto free_data; ret = sport_request_resource(sport); - if (ret) { - kfree(sport); - return NULL; - } + if (ret) + goto free_data; dev_dbg(dev, "SPORT create success\n"); return sport; +free_data: + kfree(sport); + return NULL; } EXPORT_SYMBOL(sport_create); diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index 85962657aabe02bc72db1ba50a3f0b195e05da08..c53bd6f2c2d7f6179420c0f6db37b8d1b41c1838 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -56,7 +56,7 @@ static int edb93xx_hw_params(struct snd_pcm_substream *substream, SND_SOC_CLOCK_OUT); } -static struct snd_soc_ops edb93xx_ops = { +static const struct snd_soc_ops edb93xx_ops = { .hw_params = edb93xx_hw_params, }; diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 98089df08df62e6c738f95b08c204be10970598e..2334ec19e7ebb74d4e9b60db5fe37bb4abf6a10f 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -45,7 +45,7 @@ static int snappercl15_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops snappercl15_ops = { +static const struct snd_soc_ops snappercl15_ops = { .hw_params = snappercl15_hw_params, }; diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b013a4c62b6334dd44ae4b833aef9b6de35cfa21..848c5fe49bc7a46592c80086dd6a77974d0fd795 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1355,7 +1355,7 @@ static struct regmap *pm860x_get_regmap(struct device *dev) return pm860x->regmap; } -static struct snd_soc_codec_driver soc_codec_dev_pm860x = { +static const struct snd_soc_codec_driver soc_codec_dev_pm860x = { .probe = pm860x_probe, .remove = pm860x_remove, .set_bias_level = pm860x_set_bias_level, diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6c78b0b49b8145c24740d93c4174c059d91ddae9..c367d11079bc90feec2ad0fa748d7ffc3035faba 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -60,6 +60,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_CS4271_I2C if I2C select SND_SOC_CS4271_SPI if SPI_MASTER select SND_SOC_CS42XX8_I2C if I2C + select SND_SOC_CS43130 if I2C select SND_SOC_CS4349 if I2C select SND_SOC_CS47L24 if MFD_CS47L24 select SND_SOC_CS53L30 if I2C @@ -71,7 +72,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DA732X if I2C select SND_SOC_DA9055 if I2C select SND_SOC_DIO2125 - select SND_SOC_DMIC + select SND_SOC_DMIC if GPIOLIB select SND_SOC_ES8316 if I2C select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C @@ -114,6 +115,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM5102A select SND_SOC_PCM512x_I2C if I2C select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RT274 if I2C select SND_SOC_RT286 if I2C select SND_SOC_RT298 if I2C select SND_SOC_RT5514 if I2C @@ -173,6 +175,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8400 if MFD_WM8400 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8523 if I2C + select SND_SOC_WM8524 if GPIOLIB select SND_SOC_WM8580 if I2C select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8727 @@ -486,6 +489,11 @@ config SND_SOC_CS42XX8_I2C select SND_SOC_CS42XX8 select REGMAP_I2C +# Cirrus Logic CS43130 HiFi DAC +config SND_SOC_CS43130 + tristate "Cirrus Logic CS43130 CODEC" + depends on I2C + # Cirrus Logic CS4349 HiFi DAC config SND_SOC_CS4349 tristate "Cirrus Logic CS4349 CODEC" @@ -716,11 +724,17 @@ config SND_SOC_RL6231 config SND_SOC_RL6347A tristate + default y if SND_SOC_RT274=y default y if SND_SOC_RT286=y default y if SND_SOC_RT298=y + default m if SND_SOC_RT274=m default m if SND_SOC_RT286=m default m if SND_SOC_RT298=m +config SND_SOC_RT274 + tristate + depends on I2C + config SND_SOC_RT286 tristate depends on I2C @@ -967,6 +981,10 @@ config SND_SOC_WM8523 tristate "Wolfson Microelectronics WM8523 DAC" depends on I2C +config SND_SOC_WM8524 + tristate "Wolfson Microelectronics WM8524 DAC" + depends on GPIOLIB + config SND_SOC_WM8580 tristate "Wolfson Microelectronics WM8580 and WM8581 CODECs" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 1755a54e3dc9379668de08326ed14b724fe4e4da..77c18189c9adb72244b91a5e657fb0393afc9117 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -53,6 +53,7 @@ snd-soc-cs4271-i2c-objs := cs4271-i2c.o snd-soc-cs4271-spi-objs := cs4271-spi.o snd-soc-cs42xx8-objs := cs42xx8.o snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o +snd-soc-cs43130-objs := cs43130.o snd-soc-cs4349-objs := cs4349.o snd-soc-cs47l24-objs := cs47l24.o snd-soc-cs53l30-objs := cs53l30.o @@ -113,6 +114,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o snd-soc-pcm512x-spi-objs := pcm512x-spi.o snd-soc-rl6231-objs := rl6231.o snd-soc-rl6347a-objs := rl6347a.o +snd-soc-rt274-objs := rt274.o snd-soc-rt286-objs := rt286.o snd-soc-rt298-objs := rt298.o snd-soc-rt5514-objs := rt5514.o @@ -182,6 +184,7 @@ snd-soc-wm8350-objs := wm8350.o snd-soc-wm8400-objs := wm8400.o snd-soc-wm8510-objs := wm8510.o snd-soc-wm8523-objs := wm8523.o +snd-soc-wm8524-objs := wm8524.o snd-soc-wm8580-objs := wm8580.o snd-soc-wm8711-objs := wm8711.o snd-soc-wm8727-objs := wm8727.o @@ -290,6 +293,7 @@ obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o +obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o @@ -320,6 +324,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o +obj-$(CONFIG_SND_SOC_MAX98371) += snd-soc-max98371.o obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o @@ -349,6 +354,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o +obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o @@ -372,6 +378,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o +obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o @@ -414,6 +421,7 @@ obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o +obj-$(CONFIG_SND_SOC_WM8524) += snd-soc-wm8524.o obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 312b2a11abb6a124ccf66778dec2ee7548f76486..006627b8c3a840d7823b74de64053dc281385435 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2523,7 +2523,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) return status; } -static struct snd_soc_codec_driver ab8500_codec_driver = { +static const struct snd_soc_codec_driver ab8500_codec_driver = { .probe = ab8500_codec_probe, .component_driver = { .controls = ab8500_ctrls, diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index f7f04c6be01e78402e6901fe14ed35fa7754921b..440b4ce543764be82f354e42fc45f6a5ad4b3c90 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -112,7 +112,7 @@ static int ac97_soc_resume(struct snd_soc_codec *codec) #define ac97_soc_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_ac97 = { +static const struct snd_soc_codec_driver soc_codec_dev_ac97 = { .probe = ac97_soc_probe, .suspend = ac97_soc_suspend, .resume = ac97_soc_resume, diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index a478239aadacca6815167c8d1ea8205f34aa035d..d0361caad09e08e51ba2f6f6e0bebc8905be85c9 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -321,7 +321,7 @@ static int ad1836_remove(struct snd_soc_codec *codec) AD1836_ADC_SERFMT_MASK, 0); } -static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { +static const struct snd_soc_codec_driver soc_codec_dev_ad1836 = { .probe = ad1836_probe, .remove = ad1836_remove, .suspend = ad1836_suspend, diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index d643557d89a74d753567ed75821ebb16a0477415..d10988eec0c10a236454dc146956d735e2ec98c6 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -408,7 +408,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ad193x = { +static const struct snd_soc_codec_driver soc_codec_dev_ad193x = { .probe = ad193x_codec_probe, .component_driver = { .controls = ad193x_snd_controls, diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index b7c1b9f4bf5f9d070e6daaa656a0059e644aff26..ce89bfb42094b4d678d9992bbd3c76e068914015 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -295,7 +295,7 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { +static const struct snd_soc_codec_driver soc_codec_dev_ad1980 = { .probe = ad1980_soc_probe, .remove = ad1980_soc_remove, diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index 3e358a49442d2ded0af95b0ba8dccab006912806..d8d86a0fea605941a8f4295d3fd4cff88eec941b 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -54,7 +54,7 @@ static struct snd_soc_dai_driver ad73311_dai = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, }; -static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { +static const struct snd_soc_codec_driver soc_codec_dev_ad73311 = { .component_driver = { .dapm_widgets = ad73311_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 8fa9045571ff44f7b9a698197d8d066e42695e64..a865945d776a4b08f88b0fdd2f1d40ea59c38a1c 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1458,7 +1458,7 @@ static const struct regmap_config adau1373_regmap_config = { .num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults), }; -static struct snd_soc_codec_driver adau1373_codec_driver = { +static const struct snd_soc_codec_driver adau1373_codec_driver = { .probe = adau1373_probe, .resume = adau1373_resume, .set_bias_level = adau1373_set_bias_level, diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 3bad1bc8c00a3d93d74c6f419c96f30a479e4afb..805afac8146bbf52bf059df02f2d17a673aad3ae 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -757,7 +757,7 @@ static int adau1701_resume(struct snd_soc_codec *codec) #define adau1701_suspend NULL #endif /* CONFIG_PM */ -static struct snd_soc_codec_driver adau1701_codec_drv = { +static const struct snd_soc_codec_driver adau1701_codec_drv = { .probe = adau1701_probe, .remove = adau1701_remove, .resume = adau1701_resume, diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index b319db6a69f8dd073fe39a25998b0212cb5d94e2..e384f212beb2cc7cd90320952e1dda41c5064d1a 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -388,8 +388,7 @@ static int adau1977_power_disable(struct adau1977 *adau1977) regcache_mark_dirty(adau1977->regmap); - if (adau1977->reset_gpio) - gpiod_set_value_cansleep(adau1977->reset_gpio, 0); + gpiod_set_value_cansleep(adau1977->reset_gpio, 0); regcache_cache_only(adau1977->regmap, true); @@ -420,8 +419,7 @@ static int adau1977_power_enable(struct adau1977 *adau1977) goto err_disable_avdd; } - if (adau1977->reset_gpio) - gpiod_set_value_cansleep(adau1977->reset_gpio, 1); + gpiod_set_value_cansleep(adau1977->reset_gpio, 1); regcache_cache_only(adau1977->regmap, false); @@ -867,7 +865,7 @@ static int adau1977_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver adau1977_codec_driver = { +static const struct snd_soc_codec_driver adau1977_codec_driver = { .probe = adau1977_codec_probe, .set_bias_level = adau1977_set_bias_level, .set_sysclk = adau1977_set_sysclk, diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 6e793ebb588333c7ee39ee851ccb6c66ad746ad3..da7ca81f47cfb46f0a968cc6fcf908735593d115 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -825,7 +825,7 @@ static int adav80x_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver adav80x_codec_driver = { +static const struct snd_soc_codec_driver adav80x_codec_driver = { .probe = adav80x_probe, .resume = adav80x_resume, .set_bias_level = adav80x_set_bias_level, diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 90c756d183b46168204839e56ae117694116a37c..b7f0057c023951457e3968588f8842ec46cdb491 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -58,7 +58,7 @@ static struct snd_soc_dai_driver ads117x_dai = { .formats = ADS117X_FORMATS,}, }; -static struct snd_soc_codec_driver soc_codec_dev_ads117x = { +static const struct snd_soc_codec_driver soc_codec_dev_ads117x = { .component_driver = { .dapm_widgets = ads117x_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 1a9d233c94d00f68f47fdc4313759666559140eb..dbb184118f2e47314c91501428cb8b46c97f7fbc 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -242,7 +242,7 @@ static int ak4104_soc_resume(struct snd_soc_codec *codec) #define ak4104_soc_resume NULL #endif /* CONFIG_PM */ -static struct snd_soc_codec_driver soc_codec_device_ak4104 = { +static const struct snd_soc_codec_driver soc_codec_device_ak4104 = { .probe = ak4104_probe, .remove = ak4104_remove, .suspend = ak4104_soc_suspend, diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 66cfffde9a122e5369fb5f6561e730206cfbd6bd..e3c157dc88db3c796030159ae2487f1efb8e7a59 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -390,7 +390,7 @@ static const struct regmap_config ak4535_regmap = { .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults), }; -static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .resume = ak4535_resume, .set_bias_level = ak4535_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index b92c548b9d299048964c63a1daf27351d773f624..0bb4fe5c122a4b17ac19b88df6e5ef0abeb1a837 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c @@ -64,7 +64,7 @@ static struct snd_soc_dai_driver ak4554_dai = { .symmetric_rates = 1, }; -static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4554 = { .component_driver = { .dapm_widgets = ak4554_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 690edebf029eb53c213ace00c88e39b14c6b3d75..b95bb8b52e51214b6ecbfd8a83a8462e47aea6f3 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -522,7 +522,7 @@ static int ak4613_resume(struct snd_soc_codec *codec) return regcache_sync(regmap); } -static struct snd_soc_codec_driver soc_codec_dev_ak4613 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4613 = { .suspend = ak4613_suspend, .resume = ak4613_resume, .set_bias_level = ak4613_set_bias_level, diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index ebdaf56c1d61336d96518f8e4e32aad603cab89c..60142ff32d4f28139bbddc585befed1c0e17532b 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -524,7 +524,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4641 = { .component_driver = { .controls = ak4641_snd_controls, .num_controls = ARRAY_SIZE(ak4641_snd_controls), diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 66de8a2013a6b1e5b2c54f9512a18e324ed3b81f..29530c567bd9dd41d09220966618931b7612142f 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -550,7 +550,7 @@ static int ak4642_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4642 = { .probe = ak4642_probe, .suspend = ak4642_suspend, .resume = ak4642_resume, diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 6088afaabf62c56d63a0fea375761e4a247477b0..dcfdff56fc5a1efefaee683251b069285408ba07 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -610,7 +610,7 @@ static struct snd_soc_dai_driver ak4671_dai = { .ops = &ak4671_dai_ops, }; -static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4671 = { .set_bias_level = ak4671_set_bias_level, .component_driver = { .controls = ak4671_snd_controls, diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index 0ef2df223336700ec1b55c70eb073b0960e2a18d..d0e16c03815cc89228a50f74284cddbf9dfa69cd 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c @@ -69,7 +69,7 @@ static int ak5386_soc_resume(struct snd_soc_codec *codec) #define ak5386_soc_resume NULL #endif /* CONFIG_PM */ -static struct snd_soc_codec_driver soc_codec_ak5386 = { +static const struct snd_soc_codec_driver soc_codec_ak5386 = { .probe = ak5386_soc_probe, .remove = ak5386_soc_remove, .suspend = ak5386_soc_suspend, diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index d2e3a3ef7499bce2d25009a811d9d94a26d4fee3..1db965a93632d8a52835ecf37d55c5963ee9bd4d 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -951,7 +951,7 @@ static int alc5623_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_alc5623 = { +static const struct snd_soc_codec_driver soc_codec_device_alc5623 = { .probe = alc5623_probe, .suspend = alc5623_suspend, .resume = alc5623_resume, diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 0a734d910850b1305b1fa5ee67efc571576bfbf5..a1149f6a8450e71031c5bb3dd21c82a468c11700 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -710,7 +710,7 @@ const struct soc_enum arizona_anc_input_src[] = { ARRAY_SIZE(arizona_anc_input_src_text), arizona_anc_input_src_text), SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL, - ARIZONA_FCL_MIC_MODE_SEL, + ARIZONA_FCL_MIC_MODE_SEL_SHIFT, ARRAY_SIZE(arizona_anc_channel_src_text), arizona_anc_channel_src_text), SOC_ENUM_SINGLE(ARIZONA_ANC_SRC, @@ -718,7 +718,7 @@ const struct soc_enum arizona_anc_input_src[] = { ARRAY_SIZE(arizona_anc_input_src_text), arizona_anc_input_src_text), SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL, - ARIZONA_FCR_MIC_MODE_SEL, + ARIZONA_FCR_MIC_MODE_SEL_SHIFT, ARRAY_SIZE(arizona_anc_channel_src_text), arizona_anc_channel_src_text), }; diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index 8014e697d5407d0b43f3bf03089a349c31e0b03a..806191addb44daedc0fbfca98bbabb0be4be8509 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c @@ -62,7 +62,7 @@ static struct snd_soc_dai_driver bt_sco_dai[] = { } }; -static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { +static const struct snd_soc_codec_driver soc_codec_dev_bt_sco = { .component_driver = { .dapm_widgets = bt_sco_widgets, .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 7a2d9a2ee4276de62e659f1372224fa84e4cdc73..6ed2cc374768735f88092c0b4e92be720bfe0fce 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -128,7 +128,7 @@ static struct regmap *cq93vc_get_regmap(struct device *dev) return davinci_vc->regmap; } -static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { +static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = { .set_bias_level = cq93vc_set_bias_level, .get_regmap = cq93vc_get_regmap, .component_driver = { diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6df29fa30fb9d8d17216026b925fb8df1ba7dc3c..854cf8f27605a87c97bc2e93a530bcd4a9ce5108 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -831,7 +831,7 @@ static int cs35l33_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs35l33 = { .probe = cs35l33_probe, .set_bias_level = cs35l33_set_bias_level, @@ -869,8 +869,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev) dev_dbg(dev, "%s\n", __func__); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); ret = regulator_bulk_enable(cs35l33->num_core_supplies, cs35l33->core_supplies); @@ -881,8 +880,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev) regcache_cache_only(cs35l33->regmap, false); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); @@ -1191,8 +1189,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client, return ret; } - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); regcache_cache_only(cs35l33->regmap, false); @@ -1262,8 +1259,7 @@ static int cs35l33_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); pm_runtime_disable(&client->dev); regulator_bulk_disable(cs35l33->num_core_supplies, diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 0a747c66cc6ccc593036775f51ae4eaa050cc850..1e05026bedcadeb422c3f6069db0a0d5e9a83e1f 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -779,7 +779,7 @@ static int cs35l34_probe(struct snd_soc_codec *codec) } -static struct snd_soc_codec_driver soc_codec_dev_cs35l34 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs35l34 = { .probe = cs35l34_probe, .component_driver = { @@ -1138,8 +1138,7 @@ static int cs35l34_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); - if (cs35l34->reset_gpio) - gpiod_set_value_cansleep(cs35l34->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l34->reset_gpio, 0); pm_runtime_disable(&client->dev); regulator_bulk_disable(cs35l34->num_core_supplies, diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index f1ee184ecab2994424cdca4a6d9a1bbfd526bd5f..129978d1243ebcdd3a1558c1c0f1f0dd2056bdd7 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1079,7 +1079,7 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_cs35l35 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs35l35 = { .probe = cs35l35_codec_probe, .set_sysclk = cs35l35_codec_set_sysclk, .component_driver = { diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index d8824773dc29985bbed7f6f52d1646bdee41790b..49a80627af121d9f45d4adc6ffbd8530c553993a 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -639,7 +639,7 @@ static int cs4271_codec_remove(struct snd_soc_codec *codec) return 0; }; -static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs4271 = { .probe = cs4271_codec_probe, .remove = cs4271_codec_remove, .suspend = cs4271_soc_suspend, diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 55e4520cdcaf923f6c2b8d0f00027157aafb57a5..a2324a0e72ee516c6dfb6069a462f588734e06bf 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -911,7 +911,7 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute) SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops cs42l42_ops = { +static const struct snd_soc_dai_ops cs42l42_ops = { .hw_params = cs42l42_pcm_hw_params, .set_fmt = cs42l42_set_dai_fmt, .set_sysclk = cs42l42_set_sysclk, @@ -1898,8 +1898,7 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) snd_soc_unregister_codec(&i2c_client->dev); /* Hold down reset */ - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); return 0; } @@ -1913,8 +1912,7 @@ static int cs42l42_runtime_suspend(struct device *dev) regcache_mark_dirty(cs42l42->regmap); /* Hold down reset */ - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); /* remove power */ regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), @@ -1937,8 +1935,7 @@ static int cs42l42_runtime_resume(struct device *dev) return ret; } - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); regcache_cache_only(cs42l42->regmap, false); regcache_sync(cs42l42->regmap); diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 96cfe38943cd44aa29885c76fbe48b4b8391d9a3..f8072f1897d4c47a7d91c9c6d00eedffd9ef2fba 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -504,7 +504,7 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { +static const struct snd_soc_codec_driver soc_codec_device_cs42l51 = { .probe = cs42l51_codec_probe, .component_driver = { diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c new file mode 100644 index 0000000000000000000000000000000000000000..643e37fc218e14a61fe5ff5a63739659d3330dad --- /dev/null +++ b/sound/soc/codecs/cs43130.c @@ -0,0 +1,2694 @@ +/* + * cs43130.c -- CS43130 ALSA Soc Audio driver + * + * Copyright 2017 Cirrus Logic, Inc. + * + * Authors: Li Xu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cs43130.h" + +static const struct reg_default cs43130_reg_defaults[] = { + {CS43130_SYS_CLK_CTL_1, 0x06}, + {CS43130_SP_SRATE, 0x01}, + {CS43130_SP_BITSIZE, 0x05}, + {CS43130_PAD_INT_CFG, 0x03}, + {CS43130_PWDN_CTL, 0xFE}, + {CS43130_CRYSTAL_SET, 0x04}, + {CS43130_PLL_SET_1, 0x00}, + {CS43130_PLL_SET_2, 0x00}, + {CS43130_PLL_SET_3, 0x00}, + {CS43130_PLL_SET_4, 0x00}, + {CS43130_PLL_SET_5, 0x40}, + {CS43130_PLL_SET_6, 0x10}, + {CS43130_PLL_SET_7, 0x80}, + {CS43130_PLL_SET_8, 0x03}, + {CS43130_PLL_SET_9, 0x02}, + {CS43130_PLL_SET_10, 0x02}, + {CS43130_CLKOUT_CTL, 0x00}, + {CS43130_ASP_NUM_1, 0x01}, + {CS43130_ASP_NUM_2, 0x00}, + {CS43130_ASP_DEN_1, 0x08}, + {CS43130_ASP_DEN_2, 0x00}, + {CS43130_ASP_LRCK_HI_TIME_1, 0x1F}, + {CS43130_ASP_LRCK_HI_TIME_2, 0x00}, + {CS43130_ASP_LRCK_PERIOD_1, 0x3F}, + {CS43130_ASP_LRCK_PERIOD_2, 0x00}, + {CS43130_ASP_CLOCK_CONF, 0x0C}, + {CS43130_ASP_FRAME_CONF, 0x0A}, + {CS43130_XSP_NUM_1, 0x01}, + {CS43130_XSP_NUM_2, 0x00}, + {CS43130_XSP_DEN_1, 0x02}, + {CS43130_XSP_DEN_2, 0x00}, + {CS43130_XSP_LRCK_HI_TIME_1, 0x1F}, + {CS43130_XSP_LRCK_HI_TIME_2, 0x00}, + {CS43130_XSP_LRCK_PERIOD_1, 0x3F}, + {CS43130_XSP_LRCK_PERIOD_2, 0x00}, + {CS43130_XSP_CLOCK_CONF, 0x0C}, + {CS43130_XSP_FRAME_CONF, 0x0A}, + {CS43130_ASP_CH_1_LOC, 0x00}, + {CS43130_ASP_CH_2_LOC, 0x00}, + {CS43130_ASP_CH_1_SZ_EN, 0x06}, + {CS43130_ASP_CH_2_SZ_EN, 0x0E}, + {CS43130_XSP_CH_1_LOC, 0x00}, + {CS43130_XSP_CH_2_LOC, 0x00}, + {CS43130_XSP_CH_1_SZ_EN, 0x06}, + {CS43130_XSP_CH_2_SZ_EN, 0x0E}, + {CS43130_DSD_VOL_B, 0x78}, + {CS43130_DSD_VOL_A, 0x78}, + {CS43130_DSD_PATH_CTL_1, 0xA8}, + {CS43130_DSD_INT_CFG, 0x00}, + {CS43130_DSD_PATH_CTL_2, 0x02}, + {CS43130_DSD_PCM_MIX_CTL, 0x00}, + {CS43130_DSD_PATH_CTL_3, 0x40}, + {CS43130_HP_OUT_CTL_1, 0x30}, + {CS43130_PCM_FILT_OPT, 0x02}, + {CS43130_PCM_VOL_B, 0x78}, + {CS43130_PCM_VOL_A, 0x78}, + {CS43130_PCM_PATH_CTL_1, 0xA8}, + {CS43130_PCM_PATH_CTL_2, 0x00}, + {CS43130_CLASS_H_CTL, 0x1E}, + {CS43130_HP_DETECT, 0x04}, + {CS43130_HP_LOAD_1, 0x00}, + {CS43130_HP_MEAS_LOAD_1, 0x00}, + {CS43130_HP_MEAS_LOAD_2, 0x00}, + {CS43130_INT_MASK_1, 0xFF}, + {CS43130_INT_MASK_2, 0xFF}, + {CS43130_INT_MASK_3, 0xFF}, + {CS43130_INT_MASK_4, 0xFF}, + {CS43130_INT_MASK_5, 0xFF}, +}; + +static bool cs43130_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: + case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2: + case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2: + return true; + default: + return false; + } +} + +static bool cs43130_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1: + case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG: + case CS43130_PWDN_CTL: + case CS43130_CRYSTAL_SET: + case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5: + case CS43130_PLL_SET_6: + case CS43130_PLL_SET_7: + case CS43130_PLL_SET_8: + case CS43130_PLL_SET_9: + case CS43130_PLL_SET_10: + case CS43130_CLKOUT_CTL: + case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF: + case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF: + case CS43130_ASP_CH_1_LOC: + case CS43130_ASP_CH_2_LOC: + case CS43130_ASP_CH_1_SZ_EN: + case CS43130_ASP_CH_2_SZ_EN: + case CS43130_XSP_CH_1_LOC: + case CS43130_XSP_CH_2_LOC: + case CS43130_XSP_CH_1_SZ_EN: + case CS43130_XSP_CH_2_SZ_EN: + case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3: + case CS43130_HP_OUT_CTL_1: + case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2: + case CS43130_CLASS_H_CTL: + case CS43130_HP_DETECT: + case CS43130_HP_STATUS: + case CS43130_HP_LOAD_1: + case CS43130_HP_MEAS_LOAD_1: + case CS43130_HP_MEAS_LOAD_2: + case CS43130_HP_DC_STAT_1: + case CS43130_HP_DC_STAT_2: + case CS43130_HP_AC_STAT_1: + case CS43130_HP_AC_STAT_2: + case CS43130_HP_LOAD_STAT: + case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: + case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5: + return true; + default: + return false; + } +} + +static bool cs43130_precious_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: + return true; + default: + return false; + } +} + +struct cs43130_pll_params { + unsigned int pll_in; + u8 sclk_prediv; + u8 pll_div_int; + u32 pll_div_frac; + u8 pll_mode; + u8 pll_divout; + unsigned int pll_out; + u8 pll_cal_ratio; +}; + +static const struct cs43130_pll_params pll_ratio_table[] = { + {9600000, 0x02, 0x49, 0x800000, 0x00, 0x08, 22579200, 151}, + {9600000, 0x02, 0x50, 0x000000, 0x00, 0x08, 24576000, 164}, + + {11289600, 0x02, 0X40, 0, 0x01, 0x08, 22579200, 128}, + {11289600, 0x02, 0x44, 0x06F700, 0x0, 0x08, 24576000, 139}, + + {12000000, 0x02, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120}, + {12000000, 0x02, 0x40, 0x000000, 0x00, 0x08, 24576000, 131}, + + {12288000, 0x02, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118}, + {12288000, 0x02, 0x40, 0x000000, 0x01, 0x08, 24576000, 128}, + + {13000000, 0x02, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111}, + {13000000, 0x02, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121}, + + {19200000, 0x03, 0x49, 0x800000, 0x00, 0x08, 22579200, 151}, + {19200000, 0x03, 0x50, 0x000000, 0x00, 0x08, 24576000, 164}, + + {22579200, 0, 0, 0, 0, 0, 22579200, 0}, + {22579200, 0x03, 0x44, 0x06F700, 0x00, 0x08, 24576000, 139}, + + {24000000, 0x03, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120}, + {24000000, 0x03, 0x40, 0x000000, 0x00, 0x08, 24576000, 131}, + + {24576000, 0x03, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118}, + {24576000, 0, 0, 0, 0, 0, 24576000, 0}, + + {26000000, 0x03, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111}, + {26000000, 0x03, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121}, +}; + +static const struct cs43130_pll_params *cs43130_get_pll_table( + unsigned int freq_in, unsigned int freq_out) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) { + if (pll_ratio_table[i].pll_in == freq_in && + pll_ratio_table[i].pll_out == freq_out) + return &pll_ratio_table[i]; + } + + return NULL; +} + +static int cs43130_pll_config(struct snd_soc_codec *codec) +{ + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + const struct cs43130_pll_params *pll_entry; + + dev_dbg(codec->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n", + cs43130->mclk, cs43130->mclk_int); + + pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int); + if (!pll_entry) + return -EINVAL; + + if (pll_entry->pll_cal_ratio == 0) { + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1, + CS43130_PLL_START_MASK, 0); + + cs43130->pll_bypass = true; + return 0; + } + + cs43130->pll_bypass = false; + + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_2, + CS43130_PLL_DIV_DATA_MASK, + pll_entry->pll_div_frac >> + CS43130_PLL_DIV_FRAC_0_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_3, + CS43130_PLL_DIV_DATA_MASK, + pll_entry->pll_div_frac >> + CS43130_PLL_DIV_FRAC_1_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_4, + CS43130_PLL_DIV_DATA_MASK, + pll_entry->pll_div_frac >> + CS43130_PLL_DIV_FRAC_2_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_PLL_SET_5, + pll_entry->pll_div_int); + regmap_write(cs43130->regmap, CS43130_PLL_SET_6, pll_entry->pll_divout); + regmap_write(cs43130->regmap, CS43130_PLL_SET_7, + pll_entry->pll_cal_ratio); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_8, + CS43130_PLL_MODE_MASK, + pll_entry->pll_mode << CS43130_PLL_MODE_SHIFT); + regmap_write(cs43130->regmap, CS43130_PLL_SET_9, + pll_entry->sclk_prediv); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1, + CS43130_PLL_START_MASK, 1); + + return 0; +} + +static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source, + unsigned int freq_in, unsigned int freq_out) +{ + int ret = 0; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (freq_in) { + case 9600000: + case 11289600: + case 12000000: + case 12288000: + case 13000000: + case 19200000: + case 22579200: + case 24000000: + case 24576000: + case 26000000: + cs43130->mclk = freq_in; + break; + default: + dev_err(codec->dev, + "unsupported pll input reference clock:%d\n", freq_in); + return -EINVAL; + } + + switch (freq_out) { + case 22579200: + cs43130->mclk_int = freq_out; + break; + case 24576000: + cs43130->mclk_int = freq_out; + break; + default: + dev_err(codec->dev, + "unsupported pll output ref clock: %u\n", freq_out); + return -EINVAL; + } + + ret = cs43130_pll_config(codec); + dev_dbg(codec->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass); + return ret; +} + +static int cs43130_change_clksrc(struct snd_soc_codec *codec, + enum cs43130_mclk_src_sel src) +{ + int ret; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + int mclk_int_decoded; + + if (src == cs43130->mclk_int_src) { + /* clk source has not changed */ + return 0; + } + + switch (cs43130->mclk_int) { + case CS43130_MCLK_22M: + mclk_int_decoded = CS43130_MCLK_22P5; + break; + case CS43130_MCLK_24M: + mclk_int_decoded = CS43130_MCLK_24P5; + break; + default: + dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int); + return -EINVAL; + } + + switch (src) { + case CS43130_MCLK_SRC_EXT: + cs43130->pll_bypass = true; + cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT; + if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) { + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, + 1 << CS43130_PDN_XTAL_SHIFT); + } else { + reinit_completion(&cs43130->xtal_rdy); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, 0); + ret = wait_for_completion_timeout(&cs43130->xtal_rdy, + msecs_to_jiffies(100)); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, + 1 << CS43130_XTAL_RDY_INT_SHIFT); + if (ret == 0) { + dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n"); + return -ETIMEDOUT; + } + } + + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_SRC_SEL_MASK, + src << CS43130_MCLK_SRC_SEL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_INT_MASK, + mclk_int_decoded << CS43130_MCLK_INT_SHIFT); + usleep_range(150, 200); + + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_PLL_MASK, + 1 << CS43130_PDN_PLL_SHIFT); + break; + case CS43130_MCLK_SRC_PLL: + cs43130->pll_bypass = false; + cs43130->mclk_int_src = CS43130_MCLK_SRC_PLL; + if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) { + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, + 1 << CS43130_PDN_XTAL_SHIFT); + } else { + reinit_completion(&cs43130->xtal_rdy); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, 0); + ret = wait_for_completion_timeout(&cs43130->xtal_rdy, + msecs_to_jiffies(100)); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, + 1 << CS43130_XTAL_RDY_INT_SHIFT); + if (ret == 0) { + dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n"); + return -ETIMEDOUT; + } + } + + reinit_completion(&cs43130->pll_rdy); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_PLL_RDY_INT_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_PLL_MASK, 0); + ret = wait_for_completion_timeout(&cs43130->pll_rdy, + msecs_to_jiffies(100)); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_PLL_RDY_INT_MASK, + 1 << CS43130_PLL_RDY_INT_SHIFT); + if (ret == 0) { + dev_err(codec->dev, "Timeout waiting for PLL_READY interrupt\n"); + return -ETIMEDOUT; + } + + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_SRC_SEL_MASK, + src << CS43130_MCLK_SRC_SEL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_INT_MASK, + mclk_int_decoded << CS43130_MCLK_INT_SHIFT); + usleep_range(150, 200); + break; + case CS43130_MCLK_SRC_RCO: + cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; + + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_SRC_SEL_MASK, + src << CS43130_MCLK_SRC_SEL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_INT_MASK, + CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT); + usleep_range(150, 200); + + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, + 1 << CS43130_PDN_XTAL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_PLL_MASK, + 1 << CS43130_PDN_PLL_SHIFT); + break; + default: + dev_err(codec->dev, "Invalid MCLK source value\n"); + return -EINVAL; + } + + return 0; +} + +static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = { + {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8}, + {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16}, + {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24}, + {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32}, +}; + +static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table( + unsigned int bitwidth) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) { + if (cs43130_bitwidth_table[i].bitwidth == bitwidth) + return &cs43130_bitwidth_table[i]; + } + + return NULL; +} + +static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai, + struct regmap *regmap) +{ + const struct cs43130_bitwidth_map *bw_map; + + bw_map = cs43130_get_bitwidth_table(bitwidth_dai); + if (!bw_map) + return -EINVAL; + + switch (dai_id) { + case CS43130_ASP_PCM_DAI: + case CS43130_ASP_DOP_DAI: + regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_SP_BITSIZE, + CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit); + break; + case CS43130_XSP_DOP_DAI: + regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_SP_BITSIZE, + CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit << + CS43130_XSP_BITSIZE_SHIFT); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct cs43130_rate_map cs43130_rate_table[] = { + {32000, CS43130_ASP_SPRATE_32K}, + {44100, CS43130_ASP_SPRATE_44_1K}, + {48000, CS43130_ASP_SPRATE_48K}, + {88200, CS43130_ASP_SPRATE_88_2K}, + {96000, CS43130_ASP_SPRATE_96K}, + {176400, CS43130_ASP_SPRATE_176_4K}, + {192000, CS43130_ASP_SPRATE_192K}, + {352800, CS43130_ASP_SPRATE_352_8K}, + {384000, CS43130_ASP_SPRATE_384K}, +}; + +static const struct cs43130_rate_map *cs43130_get_rate_table(int fs) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) { + if (cs43130_rate_table[i].fs == fs) + return &cs43130_rate_table[i]; + } + + return NULL; +} + +static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs, + const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table) +{ + int i; + + for (i = 0; i < len_clk_gen_table; i++) { + if (clk_gen_table[i].mclk_int == mclk_int && + clk_gen_table[i].fs == fs) + return &clk_gen_table[i]; + } + + return NULL; +} + +static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk, + struct snd_pcm_hw_params *params, + struct cs43130_private *cs43130) +{ + u16 frm_size; + u16 hi_size; + u8 frm_delay; + u8 frm_phase; + u8 frm_data; + u8 sclk_edge; + u8 lrck_edge; + u8 clk_data; + u8 loc_ch1; + u8 loc_ch2; + u8 dai_mode_val; + const struct cs43130_clk_gen *clk_gen; + + switch (cs43130->dais[dai_id].dai_format) { + case SND_SOC_DAIFMT_I2S: + hi_size = bitwidth_sclk; + frm_delay = 2; + frm_phase = 0; + break; + case SND_SOC_DAIFMT_LEFT_J: + hi_size = bitwidth_sclk; + frm_delay = 2; + frm_phase = 1; + break; + case SND_SOC_DAIFMT_DSP_A: + hi_size = 1; + frm_delay = 2; + frm_phase = 1; + break; + case SND_SOC_DAIFMT_DSP_B: + hi_size = 1; + frm_delay = 0; + frm_phase = 1; + break; + default: + return -EINVAL; + } + + switch (cs43130->dais[dai_id].dai_mode) { + case SND_SOC_DAIFMT_CBS_CFS: + dai_mode_val = 0; + break; + case SND_SOC_DAIFMT_CBM_CFM: + dai_mode_val = 1; + break; + default: + return -EINVAL; + } + + frm_size = bitwidth_sclk * params_channels(params); + sclk_edge = 1; + lrck_edge = 0; + loc_ch1 = 0; + loc_ch2 = bitwidth_sclk * (params_channels(params) - 1); + + frm_data = frm_delay & CS43130_SP_FSD_MASK; + frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK; + + clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK; + clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) & + CS43130_SP_LCPOL_OUT_MASK; + clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) & + CS43130_SP_SCPOL_IN_MASK; + clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) & + CS43130_SP_SCPOL_OUT_MASK; + clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) & + CS43130_SP_MODE_MASK; + + switch (dai_id) { + case CS43130_ASP_PCM_DAI: + case CS43130_ASP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_MSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data); + regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1); + regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2); + regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data); + break; + case CS43130_XSP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_MSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data); + regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1); + regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2); + regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data); + break; + default: + return -EINVAL; + } + + switch (frm_size) { + case 16: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_16_clk_gen, + ARRAY_SIZE(cs43130_16_clk_gen)); + break; + case 32: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_32_clk_gen, + ARRAY_SIZE(cs43130_32_clk_gen)); + break; + case 48: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_48_clk_gen, + ARRAY_SIZE(cs43130_48_clk_gen)); + break; + case 64: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_64_clk_gen, + ARRAY_SIZE(cs43130_64_clk_gen)); + break; + default: + return -EINVAL; + } + + if (!clk_gen) + return -EINVAL; + + switch (dai_id) { + case CS43130_ASP_PCM_DAI: + case CS43130_ASP_DOP_DAI: + regmap_write(cs43130->regmap, CS43130_ASP_DEN_1, + (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> + CS43130_SP_M_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_DEN_2, + (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> + CS43130_SP_M_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_NUM_1, + (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> + CS43130_SP_N_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_NUM_2, + (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> + CS43130_SP_N_MSB_DATA_SHIFT); + break; + case CS43130_XSP_DOP_DAI: + regmap_write(cs43130->regmap, CS43130_XSP_DEN_1, + (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> + CS43130_SP_M_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_DEN_2, + (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> + CS43130_SP_M_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_NUM_1, + (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> + CS43130_SP_N_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_NUM_2, + (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> + CS43130_SP_N_MSB_DATA_SHIFT); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int cs43130_pcm_dsd_mix(bool en, struct regmap *regmap) +{ + if (en) { + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_PREP_MASK, + 1 << CS43130_MIX_PCM_PREP_SHIFT); + usleep_range(6000, 6050); + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_DSD_MASK, + 1 << CS43130_MIX_PCM_DSD_SHIFT); + } else { + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_DSD_MASK, + 0 << CS43130_MIX_PCM_DSD_SHIFT); + usleep_range(1600, 1650); + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_PREP_MASK, + 0 << CS43130_MIX_PCM_PREP_SHIFT); + } + + return 0; +} + +static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + unsigned int required_clk; + u8 dsd_speed; + + mutex_lock(&cs43130->clk_mutex); + if (!cs43130->clk_req) { + /* no DAI is currently using clk */ + if (!(CS43130_MCLK_22M % params_rate(params))) + required_clk = CS43130_MCLK_22M; + else + required_clk = CS43130_MCLK_24M; + + cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk); + if (cs43130->pll_bypass) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT); + else + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL); + } + + cs43130->clk_req++; + if (cs43130->clk_req == 2) + cs43130_pcm_dsd_mix(true, cs43130->regmap); + mutex_unlock(&cs43130->clk_mutex); + + switch (params_rate(params)) { + case 176400: + dsd_speed = 0; + break; + case 352800: + dsd_speed = 1; + break; + default: + dev_err(codec->dev, "Rate(%u) not supported\n", + params_rate(params)); + return -EINVAL; + } + + if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM) + regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG, + CS43130_DSD_MASTER, CS43130_DSD_MASTER); + else + regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG, + CS43130_DSD_MASTER, 0); + + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SPEED_MASK, + dsd_speed << CS43130_DSD_SPEED_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_DSD << + CS43130_DSD_SRC_SHIFT); + + return 0; +} + +static int cs43130_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + const struct cs43130_rate_map *rate_map; + unsigned int sclk = cs43130->dais[dai->id].sclk; + unsigned int bitwidth_sclk; + unsigned int bitwidth_dai = (unsigned int)(params_width(params)); + unsigned int required_clk; + u8 dsd_speed; + + mutex_lock(&cs43130->clk_mutex); + if (!cs43130->clk_req) { + /* no DAI is currently using clk */ + if (!(CS43130_MCLK_22M % params_rate(params))) + required_clk = CS43130_MCLK_22M; + else + required_clk = CS43130_MCLK_24M; + + cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk); + if (cs43130->pll_bypass) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT); + else + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL); + } + + cs43130->clk_req++; + if (cs43130->clk_req == 2) + cs43130_pcm_dsd_mix(true, cs43130->regmap); + mutex_unlock(&cs43130->clk_mutex); + + switch (dai->id) { + case CS43130_ASP_DOP_DAI: + case CS43130_XSP_DOP_DAI: + /* DoP bitwidth is always 24-bit */ + bitwidth_dai = 24; + sclk = params_rate(params) * bitwidth_dai * + params_channels(params); + + switch (params_rate(params)) { + case 176400: + dsd_speed = 0; + break; + case 352800: + dsd_speed = 1; + break; + default: + dev_err(codec->dev, "Rate(%u) not supported\n", + params_rate(params)); + return -EINVAL; + } + + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SPEED_MASK, + dsd_speed << CS43130_DSD_SPEED_SHIFT); + break; + case CS43130_ASP_PCM_DAI: + rate_map = cs43130_get_rate_table(params_rate(params)); + if (!rate_map) + return -EINVAL; + + regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val); + break; + default: + dev_err(codec->dev, "Invalid DAI (%d)\n", dai->id); + return -EINVAL; + } + + switch (dai->id) { + case CS43130_ASP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP << + CS43130_DSD_SRC_SHIFT); + break; + case CS43130_XSP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP << + CS43130_DSD_SRC_SHIFT); + } + + if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM) + /* Calculate SCLK in master mode if unassigned */ + sclk = params_rate(params) * bitwidth_dai * + params_channels(params); + + if (!sclk) { + /* at this point, SCLK must be set */ + dev_err(codec->dev, "SCLK freq is not set\n"); + return -EINVAL; + } + + bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params); + if (bitwidth_sclk < bitwidth_dai) { + dev_err(codec->dev, "Format not supported: SCLK freq is too low\n"); + return -EINVAL; + } + + dev_dbg(codec->dev, + "sclk = %u, fs = %d, bitwidth_dai = %u\n", + sclk, params_rate(params), bitwidth_dai); + + dev_dbg(codec->dev, + "bitwidth_sclk = %u, num_ch = %u\n", + bitwidth_sclk, params_channels(params)); + + cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap); + cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130); + + return 0; +} + +static int cs43130_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&cs43130->clk_mutex); + cs43130->clk_req--; + if (!cs43130->clk_req) { + /* no DAI is currently using clk */ + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO); + cs43130_pcm_dsd_mix(false, cs43130->regmap); + } + mutex_unlock(&cs43130->clk_mutex); + + return 0; +} + +static const DECLARE_TLV_DB_SCALE(pcm_vol_tlv, -12750, 50, 1); + +static const char * const pcm_ch_text[] = { + "Left-Right Ch", + "Left-Left Ch", + "Right-Left Ch", + "Right-Right Ch", +}; + +static const struct reg_sequence pcm_ch_en_seq[] = { + {CS43130_DXD1, 0x99}, + {0x180005, 0x8C}, + {0x180007, 0xAB}, + {0x180015, 0x31}, + {0x180017, 0xB2}, + {0x180025, 0x30}, + {0x180027, 0x84}, + {0x180035, 0x9C}, + {0x180037, 0xAE}, + {0x18000D, 0x24}, + {0x18000F, 0xA3}, + {0x18001D, 0x05}, + {0x18001F, 0xD4}, + {0x18002D, 0x0B}, + {0x18002F, 0xC7}, + {0x18003D, 0x71}, + {0x18003F, 0xE7}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence pcm_ch_dis_seq[] = { + {CS43130_DXD1, 0x99}, + {0x180005, 0x24}, + {0x180007, 0xA3}, + {0x180015, 0x05}, + {0x180017, 0xD4}, + {0x180025, 0x0B}, + {0x180027, 0xC7}, + {0x180035, 0x71}, + {0x180037, 0xE7}, + {0x18000D, 0x8C}, + {0x18000F, 0xAB}, + {0x18001D, 0x31}, + {0x18001F, 0xB2}, + {0x18002D, 0x30}, + {0x18002F, 0x84}, + {0x18003D, 0x9C}, + {0x18003F, 0xAE}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_pcm_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return snd_soc_get_enum_double(kcontrol, ucontrol); +} + +static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int *item = ucontrol->value.enumerated.item; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + if (item[0] >= e->items) + return -EINVAL; + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; + + switch (cs43130->dev_id) { + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + if (val >= 2) + regmap_multi_reg_write(cs43130->regmap, pcm_ch_en_seq, + ARRAY_SIZE(pcm_ch_en_seq)); + else + regmap_multi_reg_write(cs43130->regmap, pcm_ch_dis_seq, + ARRAY_SIZE(pcm_ch_dis_seq)); + } + + return snd_soc_put_enum_double(kcontrol, ucontrol); +} + +static SOC_ENUM_SINGLE_DECL(pcm_ch_enum, CS43130_PCM_PATH_CTL_2, 0, + pcm_ch_text); + +static const char * const pcm_spd_texts[] = { + "Fast", + "Slow", +}; + +static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7, + pcm_spd_texts); + +static const char * const dsd_texts[] = { + "Off", + "BCKA Mode", + "BCKD Mode", +}; + +static const unsigned int dsd_values[] = { + CS43130_DSD_SRC_DSD, + CS43130_DSD_SRC_ASP, + CS43130_DSD_SRC_XSP, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(dsd_enum, CS43130_DSD_INT_CFG, 0, 0x03, + dsd_texts, dsd_values); + +static const struct snd_kcontrol_new cs43130_snd_controls[] = { + SOC_DOUBLE_R_TLV("Master Playback Volume", + CS43130_PCM_VOL_A, CS43130_PCM_VOL_B, 0, 0xFF, 1, + pcm_vol_tlv), + SOC_DOUBLE_R_TLV("Master DSD Playback Volume", + CS43130_DSD_VOL_A, CS43130_DSD_VOL_B, 0, 0xFF, 1, + pcm_vol_tlv), + SOC_ENUM_EXT("PCM Ch Select", pcm_ch_enum, cs43130_pcm_ch_get, + cs43130_pcm_ch_put), + SOC_ENUM("PCM Filter Speed", pcm_spd_enum), + SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0), + SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0), + SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0), + SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0), + SOC_ENUM("DSD Phase Modulation", dsd_enum), +}; + +static const struct reg_sequence pcm_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD7, 0x01}, + {CS43130_DXD8, 0}, + {CS43130_DXD9, 0x01}, + {CS43130_DXD3, 0x12}, + {CS43130_DXD4, 0}, + {CS43130_DXD10, 0x28}, + {CS43130_DXD11, 0x28}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence dsd_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD7, 0x01}, + {CS43130_DXD8, 0}, + {CS43130_DXD9, 0x01}, + {CS43130_DXD3, 0x12}, + {CS43130_DXD4, 0}, + {CS43130_DXD10, 0x1E}, + {CS43130_DXD11, 0x20}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence pop_free_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD12, 0x0A}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence pop_free_seq2[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD13, 0x20}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence mute_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD3, 0x12}, + {CS43130_DXD5, 0x02}, + {CS43130_DXD4, 0x12}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence unmute_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD3, 0x10}, + {CS43130_DXD5, 0}, + {CS43130_DXD4, 0x16}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_dsd_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, dsd_seq, + ARRAY_SIZE(dsd_seq)); + } + break; + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_1, + CS43130_MUTE_MASK, 0); + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, unmute_seq, + ARRAY_SIZE(unmute_seq)); + } + break; + case SND_SOC_DAPM_PRE_PMD: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, mute_seq, + ARRAY_SIZE(mute_seq)); + regmap_update_bits(cs43130->regmap, + CS43130_DSD_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + /* + * DSD Power Down Sequence + * According to Design, 130ms is preferred. + */ + msleep(130); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + regmap_update_bits(cs43130->regmap, + CS43130_DSD_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + } + break; + default: + dev_err(codec->dev, "Invalid event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static int cs43130_pcm_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, pcm_seq, + ARRAY_SIZE(pcm_seq)); + } + break; + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(cs43130->regmap, CS43130_PCM_PATH_CTL_1, + CS43130_MUTE_MASK, 0); + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, unmute_seq, + ARRAY_SIZE(unmute_seq)); + } + break; + case SND_SOC_DAPM_PRE_PMD: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, mute_seq, + ARRAY_SIZE(mute_seq)); + regmap_update_bits(cs43130->regmap, + CS43130_PCM_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + /* + * PCM Power Down Sequence + * According to Design, 130ms is preferred. + */ + msleep(130); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + regmap_update_bits(cs43130->regmap, + CS43130_PCM_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + } + break; + default: + dev_err(codec->dev, "Invalid event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static const struct reg_sequence dac_postpmu_seq[] = { + {CS43130_DXD9, 0x0C}, + {CS43130_DXD3, 0x10}, + {CS43130_DXD4, 0x20}, +}; + +static const struct reg_sequence dac_postpmd_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD6, 0x01}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, pop_free_seq, + ARRAY_SIZE(pop_free_seq)); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, pop_free_seq2, + ARRAY_SIZE(pop_free_seq2)); + } + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(10000, 10050); + + regmap_write(cs43130->regmap, CS43130_DXD1, 0x99); + + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, dac_postpmu_seq, + ARRAY_SIZE(dac_postpmu_seq)); + /* + * Per datasheet, Sec. PCM Power-Up Sequence. + * According to Design, CS43130_DXD12 must be 0 to meet + * THDN and Dynamic Range spec. + */ + msleep(1000); + regmap_write(cs43130->regmap, CS43130_DXD12, 0); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + usleep_range(12000, 12010); + regmap_write(cs43130->regmap, CS43130_DXD13, 0); + } + + regmap_write(cs43130->regmap, CS43130_DXD1, 0); + break; + case SND_SOC_DAPM_POST_PMD: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, dac_postpmd_seq, + ARRAY_SIZE(dac_postpmd_seq)); + } + break; + default: + dev_err(codec->dev, "Invalid DAC event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static const struct reg_sequence hpin_prepmd_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD15, 0x64}, + {CS43130_DXD14, 0}, + {CS43130_DXD2, 0}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence hpin_postpmu_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD2, 1}, + {CS43130_DXD14, 0xDC}, + {CS43130_DXD15, 0xE4}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_hpin_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMD: + regmap_multi_reg_write(cs43130->regmap, hpin_prepmd_seq, + ARRAY_SIZE(hpin_prepmd_seq)); + break; + case SND_SOC_DAPM_PRE_PMU: + regmap_multi_reg_write(cs43130->regmap, hpin_postpmu_seq, + ARRAY_SIZE(hpin_postpmu_seq)); + break; + default: + dev_err(codec->dev, "Invalid HPIN event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dapm_widget digital_hp_widgets[] = { + SND_SOC_DAPM_OUTPUT("HPOUTA"), + SND_SOC_DAPM_OUTPUT("HPOUTB"), + + SND_SOC_DAPM_AIF_IN_E("ASPIN PCM", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_ASP_SHIFT, 1, cs43130_pcm_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_AIF_IN_E("ASPIN DoP", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_ASP_SHIFT, 1, cs43130_dsd_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_AIF_IN_E("XSPIN DoP", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_XSP_SHIFT, 1, cs43130_dsd_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_AIF_IN_E("XSPIN DSD", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_DSDIF_SHIFT, 1, cs43130_dsd_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_DAC("DSD", NULL, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_EN_SHIFT, 0), + + SND_SOC_DAPM_DAC_E("HiFi DAC", NULL, CS43130_PWDN_CTL, + CS43130_PDN_HP_SHIFT, 1, cs43130_dac_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD)), +}; + +static const struct snd_soc_dapm_widget analog_hp_widgets[] = { + SND_SOC_DAPM_DAC_E("Analog Playback", NULL, CS43130_HP_OUT_CTL_1, + CS43130_HP_IN_EN_SHIFT, 0, cs43130_hpin_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)), +}; + +static struct snd_soc_dapm_widget all_hp_widgets[ + ARRAY_SIZE(digital_hp_widgets) + + ARRAY_SIZE(analog_hp_widgets)]; + +static const struct snd_soc_dapm_route digital_hp_routes[] = { + {"ASPIN PCM", NULL, "ASP PCM Playback"}, + {"ASPIN DoP", NULL, "ASP DoP Playback"}, + {"XSPIN DoP", NULL, "XSP DoP Playback"}, + {"XSPIN DSD", NULL, "XSP DSD Playback"}, + {"DSD", NULL, "ASPIN DoP"}, + {"DSD", NULL, "XSPIN DoP"}, + {"DSD", NULL, "XSPIN DSD"}, + {"HiFi DAC", NULL, "ASPIN PCM"}, + {"HiFi DAC", NULL, "DSD"}, + {"HPOUTA", NULL, "HiFi DAC"}, + {"HPOUTB", NULL, "HiFi DAC"}, +}; + +static const struct snd_soc_dapm_route analog_hp_routes[] = { + {"HPOUTA", NULL, "Analog Playback"}, + {"HPOUTB", NULL, "Analog Playback"}, +}; + +static struct snd_soc_dapm_route all_hp_routes[ + ARRAY_SIZE(digital_hp_routes) + + ARRAY_SIZE(analog_hp_routes)]; + +static const unsigned int cs43130_asp_src_rates[] = { + 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000 +}; + +static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = { + .count = ARRAY_SIZE(cs43130_asp_src_rates), + .list = cs43130_asp_src_rates, +}; + +static int cs43130_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &cs43130_asp_constraints); +} + +static const unsigned int cs43130_dop_src_rates[] = { + 176400, 352800, +}; + +static const struct snd_pcm_hw_constraint_list cs43130_dop_constraints = { + .count = ARRAY_SIZE(cs43130_dop_src_rates), + .list = cs43130_dop_src_rates, +}; + +static int cs43130_dop_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &cs43130_dop_constraints); +} + +static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; + break; + default: + dev_err(codec->dev, "unsupported mode\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J; + break; + case SND_SOC_DAIFMT_DSP_A: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_A; + break; + case SND_SOC_DAIFMT_DSP_B: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B; + break; + default: + dev_err(codec->dev, + "unsupported audio format\n"); + return -EINVAL; + } + + dev_dbg(codec->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n", + codec_dai->id, + cs43130->dais[codec_dai->id].dai_mode, + cs43130->dais[codec_dai->id].dai_format); + + return 0; +} + +static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; + break; + default: + dev_err(codec->dev, "Unsupported DAI format.\n"); + return -EINVAL; + } + + dev_dbg(codec->dev, "dai_mode = 0x%x\n", + cs43130->dais[codec_dai->id].dai_mode); + + return 0; +} + +static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + cs43130->dais[codec_dai->id].sclk = freq; + dev_dbg(codec->dev, "dai_id = %d, sclk = %u\n", codec_dai->id, + cs43130->dais[codec_dai->id].sclk); + + return 0; +} + +static const struct snd_soc_dai_ops cs43130_pcm_ops = { + .startup = cs43130_pcm_startup, + .hw_params = cs43130_hw_params, + .hw_free = cs43130_hw_free, + .set_sysclk = cs43130_set_sysclk, + .set_fmt = cs43130_pcm_set_fmt, +}; + +static const struct snd_soc_dai_ops cs43130_dop_ops = { + .startup = cs43130_dop_startup, + .hw_params = cs43130_hw_params, + .hw_free = cs43130_hw_free, + .set_sysclk = cs43130_set_sysclk, + .set_fmt = cs43130_pcm_set_fmt, +}; + +static const struct snd_soc_dai_ops cs43130_dsd_ops = { + .startup = cs43130_dop_startup, + .hw_params = cs43130_dsd_hw_params, + .hw_free = cs43130_hw_free, + .set_fmt = cs43130_dsd_set_fmt, +}; + +static struct snd_soc_dai_driver cs43130_dai[] = { + { + .name = "cs43130-asp-pcm", + .id = CS43130_ASP_PCM_DAI, + .playback = { + .stream_name = "ASP PCM Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_PCM_FORMATS, + }, + .ops = &cs43130_pcm_ops, + .symmetric_rates = 1, + }, + { + .name = "cs43130-asp-dop", + .id = CS43130_ASP_DOP_DAI, + .playback = { + .stream_name = "ASP DoP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_DOP_FORMATS, + }, + .ops = &cs43130_dop_ops, + .symmetric_rates = 1, + }, + { + .name = "cs43130-xsp-dop", + .id = CS43130_XSP_DOP_DAI, + .playback = { + .stream_name = "XSP DoP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_DOP_FORMATS, + }, + .ops = &cs43130_dop_ops, + .symmetric_rates = 1, + }, + { + .name = "cs43130-xsp-dsd", + .id = CS43130_XSP_DSD_DAI, + .playback = { + .stream_name = "XSP DSD Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_DOP_FORMATS, + }, + .ops = &cs43130_dsd_ops, + }, + +}; + +static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec, + int clk_id, int source, unsigned int freq, + int dir) +{ + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n", + clk_id, source, freq, dir); + + switch (freq) { + case CS43130_MCLK_22M: + case CS43130_MCLK_24M: + cs43130->mclk = freq; + break; + default: + dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", freq); + return -EINVAL; + } + + if (source == CS43130_MCLK_SRC_EXT) { + cs43130->pll_bypass = true; + } else { + dev_err(codec->dev, "Invalid MCLK source\n"); + return -EINVAL; + } + + return 0; +} + +static inline u16 cs43130_get_ac_reg_val(u16 ac_freq) +{ + /* AC freq is counted in 5.94Hz step. */ + return ac_freq / 6; +} + +static int cs43130_show_dc(struct device *dev, char *buf, u8 ch) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs43130_private *cs43130 = i2c_get_clientdata(client); + + if (!cs43130->hpload_done) + return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n"); + else + return scnprintf(buf, PAGE_SIZE, "%u\n", + cs43130->hpload_dc[ch]); +} + +static ssize_t cs43130_show_dc_l(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_dc(dev, buf, HP_LEFT); +} + +static ssize_t cs43130_show_dc_r(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_dc(dev, buf, HP_RIGHT); +} + +static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = { + 24, + 43, + 93, + 200, + 431, + 928, + 2000, + 4309, + 9283, + 20000, +}; + +static int cs43130_show_ac(struct device *dev, char *buf, u8 ch) +{ + int i, j = 0, tmp; + struct i2c_client *client = to_i2c_client(dev); + struct cs43130_private *cs43130 = i2c_get_clientdata(client); + + if (cs43130->hpload_done && cs43130->ac_meas) { + for (i = 0; i < ARRAY_SIZE(cs43130_ac_freq); i++) { + tmp = scnprintf(buf + j, PAGE_SIZE - j, "%u\n", + cs43130->hpload_ac[i][ch]); + if (!tmp) + break; + + j += tmp; + } + + return j; + } else { + return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n"); + } +} + +static ssize_t cs43130_show_ac_l(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_ac(dev, buf, HP_LEFT); +} + +static ssize_t cs43130_show_ac_r(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_ac(dev, buf, HP_RIGHT); +} + +static DEVICE_ATTR(hpload_dc_l, S_IRUGO, cs43130_show_dc_l, NULL); +static DEVICE_ATTR(hpload_dc_r, S_IRUGO, cs43130_show_dc_r, NULL); +static DEVICE_ATTR(hpload_ac_l, S_IRUGO, cs43130_show_ac_l, NULL); +static DEVICE_ATTR(hpload_ac_r, S_IRUGO, cs43130_show_ac_r, NULL); + +static struct reg_sequence hp_en_cal_seq[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, + {CS43130_HP_MEAS_LOAD_2, 0}, + {CS43130_INT_MASK_4, 0}, + {CS43130_DXD1, 0x99}, + {CS43130_DXD16, 0xBB}, + {CS43130_DXD12, 0x01}, + {CS43130_DXD19, 0xCB}, + {CS43130_DXD17, 0x95}, + {CS43130_DXD18, 0x0B}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x80}, +}; + +static struct reg_sequence hp_en_cal_seq2[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, + {CS43130_HP_MEAS_LOAD_2, 0}, + {CS43130_INT_MASK_4, 0}, + {CS43130_HP_LOAD_1, 0x80}, +}; + +static struct reg_sequence hp_dis_cal_seq[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_DXD1, 0x99}, + {CS43130_DXD12, 0}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0}, +}; + +static struct reg_sequence hp_dis_cal_seq2[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0}, +}; + +static struct reg_sequence hp_dc_ch_l_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x0A}, + {CS43130_DXD17, 0x93}, + {CS43130_DXD18, 0x0A}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x81}, +}; + +static struct reg_sequence hp_dc_ch_l_seq2[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x81}, +}; + +static struct reg_sequence hp_dc_ch_r_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x8A}, + {CS43130_DXD17, 0x15}, + {CS43130_DXD18, 0x06}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x91}, +}; + +static struct reg_sequence hp_dc_ch_r_seq2[] = { + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x91}, +}; + +static struct reg_sequence hp_ac_ch_l_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x0A}, + {CS43130_DXD17, 0x93}, + {CS43130_DXD18, 0x0A}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x82}, +}; + +static struct reg_sequence hp_ac_ch_l_seq2[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x82}, +}; + +static struct reg_sequence hp_ac_ch_r_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x8A}, + {CS43130_DXD17, 0x15}, + {CS43130_DXD18, 0x06}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x92}, +}; + +static struct reg_sequence hp_ac_ch_r_seq2[] = { + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x92}, +}; + +static struct reg_sequence hp_cln_seq[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, + {CS43130_HP_MEAS_LOAD_2, 0}, +}; + +struct reg_sequences { + struct reg_sequence *seq; + int size; + unsigned int msk; +}; + +static struct reg_sequences hpload_seq1[] = { + { + .seq = hp_en_cal_seq, + .size = ARRAY_SIZE(hp_en_cal_seq), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_l_seq, + .size = ARRAY_SIZE(hp_dc_ch_l_seq), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_l_seq, + .size = ARRAY_SIZE(hp_ac_ch_l_seq), + .msk = CS43130_HPLOAD_AC_INT, + }, + { + .seq = hp_dis_cal_seq, + .size = ARRAY_SIZE(hp_dis_cal_seq), + .msk = CS43130_HPLOAD_OFF_INT, + }, + { + .seq = hp_en_cal_seq, + .size = ARRAY_SIZE(hp_en_cal_seq), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_r_seq, + .size = ARRAY_SIZE(hp_dc_ch_r_seq), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_r_seq, + .size = ARRAY_SIZE(hp_ac_ch_r_seq), + .msk = CS43130_HPLOAD_AC_INT, + }, +}; + +static struct reg_sequences hpload_seq2[] = { + { + .seq = hp_en_cal_seq2, + .size = ARRAY_SIZE(hp_en_cal_seq2), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_l_seq2, + .size = ARRAY_SIZE(hp_dc_ch_l_seq2), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_l_seq2, + .size = ARRAY_SIZE(hp_ac_ch_l_seq2), + .msk = CS43130_HPLOAD_AC_INT, + }, + { + .seq = hp_dis_cal_seq2, + .size = ARRAY_SIZE(hp_dis_cal_seq2), + .msk = CS43130_HPLOAD_OFF_INT, + }, + { + .seq = hp_en_cal_seq2, + .size = ARRAY_SIZE(hp_en_cal_seq2), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_r_seq2, + .size = ARRAY_SIZE(hp_dc_ch_r_seq2), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_r_seq2, + .size = ARRAY_SIZE(hp_ac_ch_r_seq2), + .msk = CS43130_HPLOAD_AC_INT, + }, +}; + +static int cs43130_update_hpload(unsigned int msk, int ac_idx, + struct cs43130_private *cs43130) +{ + bool left_ch = true; + unsigned int reg; + u32 addr; + u16 impedance; + struct snd_soc_codec *codec = cs43130->codec; + + switch (msk) { + case CS43130_HPLOAD_DC_INT: + case CS43130_HPLOAD_AC_INT: + break; + default: + return 0; + } + + regmap_read(cs43130->regmap, CS43130_HP_LOAD_1, ®); + if (reg & CS43130_HPLOAD_CHN_SEL) + left_ch = false; + + if (msk == CS43130_HPLOAD_DC_INT) + addr = CS43130_HP_DC_STAT_1; + else + addr = CS43130_HP_AC_STAT_1; + + regmap_read(cs43130->regmap, addr, ®); + impedance = reg >> 3; + regmap_read(cs43130->regmap, addr + 1, ®); + impedance |= reg << 5; + + if (msk == CS43130_HPLOAD_DC_INT) { + if (left_ch) + cs43130->hpload_dc[HP_LEFT] = impedance; + else + cs43130->hpload_dc[HP_RIGHT] = impedance; + + dev_dbg(codec->dev, "HP DC impedance (Ch %u): %u\n", !left_ch, + impedance); + } else { + if (left_ch) + cs43130->hpload_ac[ac_idx][HP_LEFT] = impedance; + else + cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance; + + dev_dbg(codec->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n", + cs43130->ac_freq[ac_idx], !left_ch, impedance); + } + + return 0; +} + +static int cs43130_hpload_proc(struct cs43130_private *cs43130, + struct reg_sequence *seq, int seq_size, + unsigned int rslt_msk, int ac_idx) +{ + int ret; + unsigned int msk; + u16 ac_reg_val; + struct snd_soc_codec *codec = cs43130->codec; + + reinit_completion(&cs43130->hpload_evt); + + if (rslt_msk == CS43130_HPLOAD_AC_INT) { + ac_reg_val = cs43130_get_ac_reg_val(cs43130->ac_freq[ac_idx]); + regmap_update_bits(cs43130->regmap, CS43130_HP_LOAD_1, + CS43130_HPLOAD_AC_START, 0); + regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_1, + CS43130_HP_MEAS_LOAD_MASK, + ac_reg_val >> CS43130_HP_MEAS_LOAD_1_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_2, + CS43130_HP_MEAS_LOAD_MASK, + ac_reg_val >> CS43130_HP_MEAS_LOAD_2_SHIFT); + } + + regmap_multi_reg_write(cs43130->regmap, seq, + seq_size); + + ret = wait_for_completion_timeout(&cs43130->hpload_evt, + msecs_to_jiffies(1000)); + regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk); + if (!ret) { + dev_err(codec->dev, "Timeout waiting for HPLOAD interrupt\n"); + return -1; + } + + dev_dbg(codec->dev, "HP load stat: %x, INT_MASK_4: %x\n", + cs43130->hpload_stat, msk); + if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT | + CS43130_HPLOAD_UNPLUG_INT | + CS43130_HPLOAD_OOR_INT)) || + !(cs43130->hpload_stat & rslt_msk)) { + dev_dbg(codec->dev, "HP load measure failed\n"); + return -1; + } + + return 0; +} + +static const struct reg_sequence hv_seq[][2] = { + { + {CS43130_CLASS_H_CTL, 0x1C}, + {CS43130_HP_OUT_CTL_1, 0x10}, + }, + { + {CS43130_CLASS_H_CTL, 0x1E}, + {CS43130_HP_OUT_CTL_1, 0x20}, + }, + { + {CS43130_CLASS_H_CTL, 0x1E}, + {CS43130_HP_OUT_CTL_1, 0x30}, + }, +}; + +static int cs43130_set_hv(struct regmap *regmap, u16 hpload_dc, + const u16 *dc_threshold) +{ + int i; + + for (i = 0; i < CS43130_DC_THRESHOLD; i++) { + if (hpload_dc <= dc_threshold[i]) + break; + } + + regmap_multi_reg_write(regmap, hv_seq[i], ARRAY_SIZE(hv_seq[i])); + + return 0; +} + +static void cs43130_imp_meas(struct work_struct *wk) +{ + unsigned int reg, seq_size; + int i, ret, ac_idx; + struct cs43130_private *cs43130; + struct snd_soc_codec *codec; + struct reg_sequences *hpload_seq; + + cs43130 = container_of(wk, struct cs43130_private, work); + codec = cs43130->codec; + + if (!cs43130->mclk) + return; + + cs43130->hpload_done = false; + + mutex_lock(&cs43130->clk_mutex); + if (!cs43130->clk_req) { + /* clk not in use */ + cs43130_set_pll(codec, 0, 0, cs43130->mclk, CS43130_MCLK_22M); + if (cs43130->pll_bypass) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT); + else + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL); + } + + cs43130->clk_req++; + mutex_unlock(&cs43130->clk_mutex); + + regmap_read(cs43130->regmap, CS43130_INT_STATUS_4, ®); + + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + hpload_seq = hpload_seq1; + seq_size = ARRAY_SIZE(hpload_seq1); + break; + case CS43131_CHIP_ID: + hpload_seq = hpload_seq2; + seq_size = ARRAY_SIZE(hpload_seq2); + break; + default: + WARN(1, "Invalid dev_id for meas: %d", cs43130->dev_id); + return; + } + + i = 0; + ac_idx = 0; + while (i < seq_size) { + ret = cs43130_hpload_proc(cs43130, hpload_seq[i].seq, + hpload_seq[i].size, + hpload_seq[i].msk, ac_idx); + if (ret < 0) + goto exit; + + cs43130_update_hpload(hpload_seq[i].msk, ac_idx, cs43130); + + if (cs43130->ac_meas && + hpload_seq[i].msk == CS43130_HPLOAD_AC_INT && + ac_idx < CS43130_AC_FREQ - 1) { + ac_idx++; + } else { + ac_idx = 0; + i++; + } + } + cs43130->hpload_done = true; + + if (cs43130->hpload_dc[HP_LEFT] >= CS43130_LINEOUT_LOAD) + snd_soc_jack_report(&cs43130->jack, CS43130_JACK_LINEOUT, + CS43130_JACK_MASK); + else + snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE, + CS43130_JACK_MASK); + + dev_dbg(codec->dev, "Set HP output control. DC threshold\n"); + for (i = 0; i < CS43130_DC_THRESHOLD; i++) + dev_dbg(codec->dev, "DC threshold[%d]: %u.\n", i, + cs43130->dc_threshold[i]); + + cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT], + cs43130->dc_threshold); + +exit: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + cs43130_hpload_proc(cs43130, hp_dis_cal_seq, + ARRAY_SIZE(hp_dis_cal_seq), + CS43130_HPLOAD_OFF_INT, ac_idx); + break; + case CS43131_CHIP_ID: + cs43130_hpload_proc(cs43130, hp_dis_cal_seq2, + ARRAY_SIZE(hp_dis_cal_seq2), + CS43130_HPLOAD_OFF_INT, ac_idx); + } + + regmap_multi_reg_write(cs43130->regmap, hp_cln_seq, + ARRAY_SIZE(hp_cln_seq)); + + mutex_lock(&cs43130->clk_mutex); + cs43130->clk_req--; + /* clk not in use */ + if (!cs43130->clk_req) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO); + mutex_unlock(&cs43130->clk_mutex); +} + +static irqreturn_t cs43130_irq_thread(int irq, void *data) +{ + struct cs43130_private *cs43130 = (struct cs43130_private *)data; + struct snd_soc_codec *codec = cs43130->codec; + unsigned int stickies[CS43130_NUM_INT]; + unsigned int irq_occurrence = 0; + unsigned int masks[CS43130_NUM_INT]; + int i, j; + + for (i = 0; i < ARRAY_SIZE(stickies); i++) { + regmap_read(cs43130->regmap, CS43130_INT_STATUS_1 + i, + &stickies[i]); + regmap_read(cs43130->regmap, CS43130_INT_MASK_1 + i, + &masks[i]); + } + + for (i = 0; i < ARRAY_SIZE(stickies); i++) { + stickies[i] = stickies[i] & (~masks[i]); + for (j = 0; j < 8; j++) + irq_occurrence += (stickies[i] >> j) & 1; + } + dev_dbg(codec->dev, "number of interrupts occurred (%u)\n", + irq_occurrence); + + if (!irq_occurrence) + return IRQ_NONE; + + if (stickies[0] & CS43130_XTAL_RDY_INT) { + complete(&cs43130->xtal_rdy); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_PLL_RDY_INT) { + complete(&cs43130->pll_rdy); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) { + cs43130->hpload_stat = stickies[3]; + dev_err(codec->dev, + "DC load has not completed before AC load (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) { + cs43130->hpload_stat = stickies[3]; + dev_err(codec->dev, "HP unplugged during measurement (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_OOR_INT) { + cs43130->hpload_stat = stickies[3]; + dev_err(codec->dev, "HP load out of range (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_AC_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP AC load measurement done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_DC_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP DC load measurement done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_ON_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP load state machine on done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_OFF_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP load state machine off done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_XTAL_ERR_INT) { + dev_err(codec->dev, "Crystal err: clock is not running\n"); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_HP_UNPLUG_INT) { + dev_dbg(codec->dev, "HP unplugged\n"); + cs43130->hpload_done = false; + snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_HP_PLUG_INT) { + if (cs43130->dc_meas && !cs43130->hpload_done && + !work_busy(&cs43130->work)) { + dev_dbg(codec->dev, "HP load queue work\n"); + queue_work(cs43130->wq, &cs43130->work); + } + + snd_soc_jack_report(&cs43130->jack, SND_JACK_MECHANICAL, + CS43130_JACK_MASK); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int cs43130_probe(struct snd_soc_codec *codec) +{ + int ret; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_card *card = codec->component.card; + unsigned int reg; + + cs43130->codec = codec; + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) { + regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET, + CS43130_XTAL_IBIAS_MASK, + cs43130->xtal_ibias); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, 0); + } + + ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK, + &cs43130->jack, NULL, 0); + if (ret < 0) { + dev_err(codec->dev, "Cannot create jack\n"); + return ret; + } + + cs43130->hpload_done = false; + if (cs43130->dc_meas) { + ret = device_create_file(codec->dev, &dev_attr_hpload_dc_l); + if (ret < 0) + return ret; + + ret = device_create_file(codec->dev, &dev_attr_hpload_dc_r); + if (ret < 0) + return ret; + + ret = device_create_file(codec->dev, &dev_attr_hpload_ac_l); + if (ret < 0) + return ret; + + ret = device_create_file(codec->dev, &dev_attr_hpload_ac_r); + if (ret < 0) + return ret; + + cs43130->wq = create_singlethread_workqueue("cs43130_hp"); + INIT_WORK(&cs43130->work, cs43130_imp_meas); + } + + regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, ®); + regmap_read(cs43130->regmap, CS43130_HP_STATUS, ®); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, 0); + regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT, + CS43130_HP_DETECT_CTRL_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT, + CS43130_HP_DETECT_CTRL_MASK, + CS43130_HP_DETECT_CTRL_MASK); + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_cs43130 = { + .probe = cs43130_probe, + .component_driver = { + .controls = cs43130_snd_controls, + .num_controls = ARRAY_SIZE(cs43130_snd_controls), + }, + .set_sysclk = cs43130_codec_set_sysclk, + .set_pll = cs43130_set_pll, +}; + +static const struct regmap_config cs43130_regmap = { + .reg_bits = 24, + .pad_bits = 8, + .val_bits = 8, + + .max_register = CS43130_LASTREG, + .reg_defaults = cs43130_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults), + .readable_reg = cs43130_readable_register, + .precious_reg = cs43130_precious_register, + .volatile_reg = cs43130_volatile_register, + .cache_type = REGCACHE_RBTREE, + .use_single_rw = true, /* needed for regcache_sync */ +}; + +static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = { + 50, + 120, +}; + +static int cs43130_handle_device_data(struct i2c_client *i2c_client, + struct cs43130_private *cs43130) +{ + struct device_node *np = i2c_client->dev.of_node; + unsigned int val; + int i; + + if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) { + /* Crystal is unused. System clock is used for external MCLK */ + cs43130->xtal_ibias = CS43130_XTAL_UNUSED; + return 0; + } + + switch (val) { + case 1: + cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA; + break; + case 2: + cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA; + break; + case 3: + cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA; + break; + default: + dev_err(&i2c_client->dev, + "Invalid cirrus,xtal-ibias value: %d\n", val); + return -EINVAL; + } + + cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure"); + cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure"); + + if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq, + CS43130_AC_FREQ) < 0) { + for (i = 0; i < CS43130_AC_FREQ; i++) + cs43130->ac_freq[i] = cs43130_ac_freq[i]; + } + + if (of_property_read_u16_array(np, "cirrus,dc-threshold", + cs43130->dc_threshold, + CS43130_DC_THRESHOLD) < 0) { + for (i = 0; i < CS43130_DC_THRESHOLD; i++) + cs43130->dc_threshold[i] = cs43130_dc_threshold[i]; + } + + return 0; +} + +static int cs43130_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cs43130_private *cs43130; + int ret; + unsigned int devid = 0; + unsigned int reg; + int i; + + cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL); + if (!cs43130) + return -ENOMEM; + + i2c_set_clientdata(client, cs43130); + + cs43130->regmap = devm_regmap_init_i2c(client, &cs43130_regmap); + if (IS_ERR(cs43130->regmap)) { + ret = PTR_ERR(cs43130->regmap); + return ret; + } + + if (client->dev.of_node) { + ret = cs43130_handle_device_data(client, cs43130); + if (ret != 0) + return ret; + } + for (i = 0; i < ARRAY_SIZE(cs43130->supplies); i++) + cs43130->supplies[i].supply = cs43130_supply_names[i]; + + ret = devm_regulator_bulk_get(&client->dev, + ARRAY_SIZE(cs43130->supplies), + cs43130->supplies); + if (ret != 0) { + dev_err(&client->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + ret = regulator_bulk_enable(ARRAY_SIZE(cs43130->supplies), + cs43130->supplies); + if (ret != 0) { + dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + cs43130->reset_gpio = devm_gpiod_get_optional(&client->dev, + "reset", GPIOD_OUT_LOW); + if (IS_ERR(cs43130->reset_gpio)) + return PTR_ERR(cs43130->reset_gpio); + + gpiod_set_value_cansleep(cs43130->reset_gpio, 1); + + usleep_range(2000, 2050); + + ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, ®); + + devid = (reg & 0xFF) << 12; + ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, ®); + devid |= (reg & 0xFF) << 4; + ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, ®); + devid |= (reg & 0xF0) >> 4; + + switch (devid) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + break; + default: + dev_err(&client->dev, + "CS43130 Device ID %X. Expected ID %X, %X, %X or %X\n", + devid, CS43130_CHIP_ID, CS4399_CHIP_ID, + CS43131_CHIP_ID, CS43198_CHIP_ID); + ret = -ENODEV; + goto err; + } + + cs43130->dev_id = devid; + ret = regmap_read(cs43130->regmap, CS43130_REV_ID, ®); + if (ret < 0) { + dev_err(&client->dev, "Get Revision ID failed\n"); + goto err; + } + + dev_info(&client->dev, + "Cirrus Logic CS43130 (%x), Revision: %02X\n", devid, + reg & 0xFF); + + mutex_init(&cs43130->clk_mutex); + + init_completion(&cs43130->xtal_rdy); + init_completion(&cs43130->pll_rdy); + init_completion(&cs43130->hpload_evt); + + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, cs43130_irq_thread, + IRQF_ONESHOT | IRQF_TRIGGER_LOW, + "cs43130", cs43130); + if (ret != 0) { + dev_err(&client->dev, "Failed to request IRQ: %d\n", ret); + return ret; + } + + cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; + + pm_runtime_set_autosuspend_delay(&client->dev, 100); + pm_runtime_use_autosuspend(&client->dev); + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS43131_CHIP_ID: + memcpy(all_hp_widgets, digital_hp_widgets, + sizeof(digital_hp_widgets)); + memcpy(all_hp_widgets + ARRAY_SIZE(digital_hp_widgets), + analog_hp_widgets, sizeof(analog_hp_widgets)); + memcpy(all_hp_routes, digital_hp_routes, + sizeof(digital_hp_routes)); + memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes), + analog_hp_routes, sizeof(analog_hp_routes)); + + soc_codec_dev_cs43130.component_driver.dapm_widgets = + all_hp_widgets; + soc_codec_dev_cs43130.component_driver.num_dapm_widgets = + ARRAY_SIZE(all_hp_widgets); + soc_codec_dev_cs43130.component_driver.dapm_routes = + all_hp_routes; + soc_codec_dev_cs43130.component_driver.num_dapm_routes = + ARRAY_SIZE(all_hp_routes); + break; + case CS43198_CHIP_ID: + case CS4399_CHIP_ID: + soc_codec_dev_cs43130.component_driver.dapm_widgets = + digital_hp_widgets; + soc_codec_dev_cs43130.component_driver.num_dapm_widgets = + ARRAY_SIZE(digital_hp_widgets); + soc_codec_dev_cs43130.component_driver.dapm_routes = + digital_hp_routes; + soc_codec_dev_cs43130.component_driver.num_dapm_routes = + ARRAY_SIZE(digital_hp_routes); + } + + ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130, + cs43130_dai, ARRAY_SIZE(cs43130_dai)); + if (ret < 0) { + dev_err(&client->dev, + "snd_soc_register_codec failed with ret = %d\n", ret); + goto err; + } + + regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, + CS43130_ASP_3ST_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, + CS43130_XSP_3ST_MASK, 0); + + return 0; +err: + return ret; +} + +static int cs43130_i2c_remove(struct i2c_client *client) +{ + struct cs43130_private *cs43130 = i2c_get_clientdata(client); + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, + 1 << CS43130_XTAL_ERR_INT_SHIFT); + + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, + CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT); + + if (cs43130->dc_meas) { + cancel_work_sync(&cs43130->work); + flush_workqueue(cs43130->wq); + + device_remove_file(&client->dev, &dev_attr_hpload_dc_l); + device_remove_file(&client->dev, &dev_attr_hpload_dc_r); + device_remove_file(&client->dev, &dev_attr_hpload_ac_l); + device_remove_file(&client->dev, &dev_attr_hpload_ac_r); + } + + if (cs43130->reset_gpio) + gpiod_set_value_cansleep(cs43130->reset_gpio, 0); + + pm_runtime_disable(&client->dev); + regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); + + snd_soc_unregister_codec(&client->dev); + + return 0; +} + +static int __maybe_unused cs43130_runtime_suspend(struct device *dev) +{ + struct cs43130_private *cs43130 = dev_get_drvdata(dev); + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, + 1 << CS43130_XTAL_ERR_INT_SHIFT); + + regcache_cache_only(cs43130->regmap, true); + regcache_mark_dirty(cs43130->regmap); + + gpiod_set_value_cansleep(cs43130->reset_gpio, 0); + + regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); + + return 0; +} + +static int __maybe_unused cs43130_runtime_resume(struct device *dev) +{ + struct cs43130_private *cs43130 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(CS43130_NUM_SUPPLIES, cs43130->supplies); + if (ret != 0) { + dev_err(dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + regcache_cache_only(cs43130->regmap, false); + + gpiod_set_value_cansleep(cs43130->reset_gpio, 1); + + usleep_range(2000, 2050); + + ret = regcache_sync(cs43130->regmap); + if (ret != 0) { + dev_err(dev, "Failed to restore register cache\n"); + goto err; + } + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, 0); + + return 0; +err: + regcache_cache_only(cs43130->regmap, true); + regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); + + return ret; +} + +static const struct dev_pm_ops cs43130_runtime_pm = { + SET_RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume, + NULL) +}; + +static const struct of_device_id cs43130_of_match[] = { + {.compatible = "cirrus,cs43130",}, + {.compatible = "cirrus,cs4399",}, + {.compatible = "cirrus,cs43131",}, + {.compatible = "cirrus,cs43198",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, cs43130_of_match); + +static const struct i2c_device_id cs43130_i2c_id[] = { + {"cs43130", 0}, + {"cs4399", 0}, + {"cs43131", 0}, + {"cs43198", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs43130_i2c_id); + +static struct i2c_driver cs43130_i2c_driver = { + .driver = { + .name = "cs43130", + .of_match_table = cs43130_of_match, + .pm = &cs43130_runtime_pm, + }, + .id_table = cs43130_i2c_id, + .probe = cs43130_i2c_probe, + .remove = cs43130_i2c_remove, +}; + +module_i2c_driver(cs43130_i2c_driver); + +MODULE_AUTHOR("Li Xu "); +MODULE_DESCRIPTION("Cirrus Logic CS43130 ALSA SoC Codec Driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h new file mode 100644 index 0000000000000000000000000000000000000000..781258418d893a21c7fdfdef9cf6782b7680e714 --- /dev/null +++ b/sound/soc/codecs/cs43130.h @@ -0,0 +1,546 @@ +/* + * ALSA SoC CS43130 codec driver + * + * Copyright 2017 Cirrus Logic, Inc. + * + * Author: Li Xu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef __CS43130_H__ +#define __CS43130_H__ + +/* CS43130 registers addresses */ +/* all reg address is shifted by a byte for control byte to be LSB */ +#define CS43130_FIRSTREG 0x010000 +#define CS43130_LASTREG 0x190000 +#define CS43130_CHIP_ID 0x00043130 +#define CS4399_CHIP_ID 0x00043990 +#define CS43131_CHIP_ID 0x00043131 +#define CS43198_CHIP_ID 0x00043198 +#define CS43130_DEVID_AB 0x010000 /* Device ID A & B [RO] */ +#define CS43130_DEVID_CD 0x010001 /* Device ID C & D [RO] */ +#define CS43130_DEVID_E 0x010002 /* Device ID E [RO] */ +#define CS43130_FAB_ID 0x010003 /* Fab ID [RO] */ +#define CS43130_REV_ID 0x010004 /* Revision ID [RO] */ +#define CS43130_SUBREV_ID 0x010005 /* Subrevision ID */ +#define CS43130_SYS_CLK_CTL_1 0x010006 /* System Clocking Ctl 1 */ +#define CS43130_SP_SRATE 0x01000B /* Serial Port Sample Rate */ +#define CS43130_SP_BITSIZE 0x01000C /* Serial Port Bit Size */ +#define CS43130_PAD_INT_CFG 0x01000D /* Pad Interface Config */ +#define CS43130_DXD1 0x010010 /* DXD1 */ +#define CS43130_DXD7 0x010025 /* DXD7 */ +#define CS43130_DXD19 0x010026 /* DXD19 */ +#define CS43130_DXD17 0x010027 /* DXD17 */ +#define CS43130_DXD18 0x010028 /* DXD18 */ +#define CS43130_DXD12 0x01002C /* DXD12 */ +#define CS43130_DXD8 0x01002E /* DXD8 */ +#define CS43130_PWDN_CTL 0x020000 /* Power Down Ctl */ +#define CS43130_DXD2 0x020019 /* DXD2 */ +#define CS43130_CRYSTAL_SET 0x020052 /* Crystal Setting */ +#define CS43130_PLL_SET_1 0x030001 /* PLL Setting 1 */ +#define CS43130_PLL_SET_2 0x030002 /* PLL Setting 2 */ +#define CS43130_PLL_SET_3 0x030003 /* PLL Setting 3 */ +#define CS43130_PLL_SET_4 0x030004 /* PLL Setting 4 */ +#define CS43130_PLL_SET_5 0x030005 /* PLL Setting 5 */ +#define CS43130_PLL_SET_6 0x030008 /* PLL Setting 6 */ +#define CS43130_PLL_SET_7 0x03000A /* PLL Setting 7 */ +#define CS43130_PLL_SET_8 0x03001B /* PLL Setting 8 */ +#define CS43130_PLL_SET_9 0x040002 /* PLL Setting 9 */ +#define CS43130_PLL_SET_10 0x040003 /* PLL Setting 10 */ +#define CS43130_CLKOUT_CTL 0x040004 /* CLKOUT Ctl */ +#define CS43130_ASP_NUM_1 0x040010 /* ASP Numerator 1 */ +#define CS43130_ASP_NUM_2 0x040011 /* ASP Numerator 2 */ +#define CS43130_ASP_DEN_1 0x040012 /* ASP Denominator 1 */ +#define CS43130_ASP_DEN_2 0x040013 /* ASP Denominator 2 */ +#define CS43130_ASP_LRCK_HI_TIME_1 0x040014 /* ASP LRCK High Time 1 */ +#define CS43130_ASP_LRCK_HI_TIME_2 0x040015 /* ASP LRCK High Time 2 */ +#define CS43130_ASP_LRCK_PERIOD_1 0x040016 /* ASP LRCK Period 1 */ +#define CS43130_ASP_LRCK_PERIOD_2 0x040017 /* ASP LRCK Period 2 */ +#define CS43130_ASP_CLOCK_CONF 0x040018 /* ASP Clock Config */ +#define CS43130_ASP_FRAME_CONF 0x040019 /* ASP Frame Config */ +#define CS43130_XSP_NUM_1 0x040020 /* XSP Numerator 1 */ +#define CS43130_XSP_NUM_2 0x040021 /* XSP Numerator 2 */ +#define CS43130_XSP_DEN_1 0x040022 /* XSP Denominator 1 */ +#define CS43130_XSP_DEN_2 0x040023 /* XSP Denominator 2 */ +#define CS43130_XSP_LRCK_HI_TIME_1 0x040024 /* XSP LRCK High Time 1 */ +#define CS43130_XSP_LRCK_HI_TIME_2 0x040025 /* XSP LRCK High Time 2 */ +#define CS43130_XSP_LRCK_PERIOD_1 0x040026 /* XSP LRCK Period 1 */ +#define CS43130_XSP_LRCK_PERIOD_2 0x040027 /* XSP LRCK Period 2 */ +#define CS43130_XSP_CLOCK_CONF 0x040028 /* XSP Clock Config */ +#define CS43130_XSP_FRAME_CONF 0x040029 /* XSP Frame Config */ +#define CS43130_ASP_CH_1_LOC 0x050000 /* ASP Chan 1 Location */ +#define CS43130_ASP_CH_2_LOC 0x050001 /* ASP Chan 2 Location */ +#define CS43130_ASP_CH_1_SZ_EN 0x05000A /* ASP Chan 1 Size, Enable */ +#define CS43130_ASP_CH_2_SZ_EN 0x05000B /* ASP Chan 2 Size, Enable */ +#define CS43130_XSP_CH_1_LOC 0x060000 /* XSP Chan 1 Location */ +#define CS43130_XSP_CH_2_LOC 0x060001 /* XSP Chan 2 Location */ +#define CS43130_XSP_CH_1_SZ_EN 0x06000A /* XSP Chan 1 Size, Enable */ +#define CS43130_XSP_CH_2_SZ_EN 0x06000B /* XSP Chan 2 Size, Enable */ +#define CS43130_DSD_VOL_B 0x070000 /* DSD Volume B */ +#define CS43130_DSD_VOL_A 0x070001 /* DSD Volume A */ +#define CS43130_DSD_PATH_CTL_1 0x070002 /* DSD Proc Path Sig Ctl 1 */ +#define CS43130_DSD_INT_CFG 0x070003 /* DSD Interface Config */ +#define CS43130_DSD_PATH_CTL_2 0x070004 /* DSD Proc Path Sig Ctl 2 */ +#define CS43130_DSD_PCM_MIX_CTL 0x070005 /* DSD and PCM Mixing Ctl */ +#define CS43130_DSD_PATH_CTL_3 0x070006 /* DSD Proc Path Sig Ctl 3 */ +#define CS43130_HP_OUT_CTL_1 0x080000 /* HP Output Ctl 1 */ +#define CS43130_DXD16 0x080024 /* DXD16 */ +#define CS43130_DXD13 0x080032 /* DXD13 */ +#define CS43130_PCM_FILT_OPT 0x090000 /* PCM Filter Option */ +#define CS43130_PCM_VOL_B 0x090001 /* PCM Volume B */ +#define CS43130_PCM_VOL_A 0x090002 /* PCM Volume A */ +#define CS43130_PCM_PATH_CTL_1 0x090003 /* PCM Path Signal Ctl 1 */ +#define CS43130_PCM_PATH_CTL_2 0x090004 /* PCM Path Signal Ctl 2 */ +#define CS43130_DXD6 0x090097 /* DXD6 */ +#define CS43130_CLASS_H_CTL 0x0B0000 /* Class H Ctl */ +#define CS43130_DXD15 0x0B0005 /* DXD15 */ +#define CS43130_DXD14 0x0B0006 /* DXD14 */ +#define CS43130_DXD3 0x0C0002 /* DXD3 */ +#define CS43130_DXD10 0x0C0003 /* DXD10 */ +#define CS43130_DXD11 0x0C0005 /* DXD11 */ +#define CS43130_DXD9 0x0C0006 /* DXD9 */ +#define CS43130_DXD4 0x0C0009 /* DXD4 */ +#define CS43130_DXD5 0x0C000E /* DXD5 */ +#define CS43130_HP_DETECT 0x0D0000 /* HP Detect */ +#define CS43130_HP_STATUS 0x0D0001 /* HP Status [RO] */ +#define CS43130_HP_LOAD_1 0x0E0000 /* HP Load 1 */ +#define CS43130_HP_MEAS_LOAD_1 0x0E0003 /* HP Load Measurement 1 */ +#define CS43130_HP_MEAS_LOAD_2 0x0E0004 /* HP Load Measurement 2 */ +#define CS43130_HP_DC_STAT_1 0x0E000D /* HP DC Load Status 0 [RO] */ +#define CS43130_HP_DC_STAT_2 0x0E000E /* HP DC Load Status 1 [RO] */ +#define CS43130_HP_AC_STAT_1 0x0E0010 /* HP AC Load Status 0 [RO] */ +#define CS43130_HP_AC_STAT_2 0x0E0011 /* HP AC Load Status 1 [RO] */ +#define CS43130_HP_LOAD_STAT 0x0E001A /* HP Load Status [RO] */ +#define CS43130_INT_STATUS_1 0x0F0000 /* Interrupt Status 1 */ +#define CS43130_INT_STATUS_2 0x0F0001 /* Interrupt Status 2 */ +#define CS43130_INT_STATUS_3 0x0F0002 /* Interrupt Status 3 */ +#define CS43130_INT_STATUS_4 0x0F0003 /* Interrupt Status 4 */ +#define CS43130_INT_STATUS_5 0x0F0004 /* Interrupt Status 5 */ +#define CS43130_INT_MASK_1 0x0F0010 /* Interrupt Mask 1 */ +#define CS43130_INT_MASK_2 0x0F0011 /* Interrupt Mask 2 */ +#define CS43130_INT_MASK_3 0x0F0012 /* Interrupt Mask 3 */ +#define CS43130_INT_MASK_4 0x0F0013 /* Interrupt Mask 4 */ +#define CS43130_INT_MASK_5 0x0F0014 /* Interrupt Mask 5 */ + +#define CS43130_MCLK_SRC_SEL_MASK 0x03 +#define CS43130_MCLK_SRC_SEL_SHIFT 0 +#define CS43130_MCLK_INT_MASK 0x04 +#define CS43130_MCLK_INT_SHIFT 2 +#define CS43130_CH_BITSIZE_MASK 0x03 +#define CS43130_CH_EN_MASK 0x04 +#define CS43130_CH_EN_SHIFT 2 +#define CS43130_ASP_BITSIZE_MASK 0x03 +#define CS43130_XSP_BITSIZE_MASK 0x0C +#define CS43130_XSP_BITSIZE_SHIFT 2 +#define CS43130_SP_BITSIZE_ASP_SHIFT 0 +#define CS43130_HP_DETECT_CTRL_SHIFT 6 +#define CS43130_HP_DETECT_CTRL_MASK (0x03 << CS43130_HP_DETECT_CTRL_SHIFT) +#define CS43130_HP_DETECT_INV_SHIFT 5 +#define CS43130_HP_DETECT_INV_MASK (1 << CS43130_HP_DETECT_INV_SHIFT) + +/* CS43130_INT_MASK_1 */ +#define CS43130_HP_PLUG_INT_SHIFT 6 +#define CS43130_HP_PLUG_INT (1 << CS43130_HP_PLUG_INT_SHIFT) +#define CS43130_HP_UNPLUG_INT_SHIFT 5 +#define CS43130_HP_UNPLUG_INT (1 << CS43130_HP_UNPLUG_INT_SHIFT) +#define CS43130_XTAL_RDY_INT_SHIFT 4 +#define CS43130_XTAL_RDY_INT_MASK 0x10 +#define CS43130_XTAL_RDY_INT (1 << CS43130_XTAL_RDY_INT_SHIFT) +#define CS43130_XTAL_ERR_INT_SHIFT 3 +#define CS43130_XTAL_ERR_INT (1 << CS43130_XTAL_ERR_INT_SHIFT) +#define CS43130_PLL_RDY_INT_MASK 0x04 +#define CS43130_PLL_RDY_INT_SHIFT 2 +#define CS43130_PLL_RDY_INT (1 << CS43130_PLL_RDY_INT_SHIFT) + +/* CS43130_INT_MASK_4 */ +#define CS43130_INT_MASK_ALL 0xFF +#define CS43130_HPLOAD_NO_DC_INT_SHIFT 7 +#define CS43130_HPLOAD_NO_DC_INT (1 << CS43130_HPLOAD_NO_DC_INT_SHIFT) +#define CS43130_HPLOAD_UNPLUG_INT_SHIFT 6 +#define CS43130_HPLOAD_UNPLUG_INT (1 << CS43130_HPLOAD_UNPLUG_INT_SHIFT) +#define CS43130_HPLOAD_OOR_INT_SHIFT 4 +#define CS43130_HPLOAD_OOR_INT (1 << CS43130_HPLOAD_OOR_INT_SHIFT) +#define CS43130_HPLOAD_AC_INT_SHIFT 3 +#define CS43130_HPLOAD_AC_INT (1 << CS43130_HPLOAD_AC_INT_SHIFT) +#define CS43130_HPLOAD_DC_INT_SHIFT 2 +#define CS43130_HPLOAD_DC_INT (1 << CS43130_HPLOAD_DC_INT_SHIFT) +#define CS43130_HPLOAD_OFF_INT_SHIFT 1 +#define CS43130_HPLOAD_OFF_INT (1 << CS43130_HPLOAD_OFF_INT_SHIFT) +#define CS43130_HPLOAD_ON_INT 1 + +/* CS43130_HP_LOAD_1 */ +#define CS43130_HPLOAD_EN_SHIFT 7 +#define CS43130_HPLOAD_EN (1 << CS43130_HPLOAD_EN_SHIFT) +#define CS43130_HPLOAD_CHN_SEL_SHIFT 4 +#define CS43130_HPLOAD_CHN_SEL (1 << CS43130_HPLOAD_CHN_SEL_SHIFT) +#define CS43130_HPLOAD_AC_START_SHIFT 1 +#define CS43130_HPLOAD_AC_START (1 << CS43130_HPLOAD_AC_START_SHIFT) +#define CS43130_HPLOAD_DC_START 1 + +/* Reg CS43130_SP_BITSIZE */ +#define CS43130_SP_BIT_SIZE_8 0x03 +#define CS43130_SP_BIT_SIZE_16 0x02 +#define CS43130_SP_BIT_SIZE_24 0x01 +#define CS43130_SP_BIT_SIZE_32 0x00 + +/* Reg CS43130_SP_CH_SZ_EN */ +#define CS43130_CH_BIT_SIZE_8 0x00 +#define CS43130_CH_BIT_SIZE_16 0x01 +#define CS43130_CH_BIT_SIZE_24 0x02 +#define CS43130_CH_BIT_SIZE_32 0x03 + +/* PLL */ +#define CS43130_PLL_START_MASK 0x01 +#define CS43130_PLL_MODE_MASK 0x02 +#define CS43130_PLL_MODE_SHIFT 1 + +#define CS43130_PLL_REF_PREDIV_MASK 0x3 + +#define CS43130_SP_STP_MASK 0x10 +#define CS43130_SP_STP_SHIFT 4 +#define CS43130_SP_5050_MASK 0x08 +#define CS43130_SP_5050_SHIFT 3 +#define CS43130_SP_FSD_MASK 0x07 + +#define CS43130_SP_MODE_MASK 0x10 +#define CS43130_SP_MODE_SHIFT 4 +#define CS43130_SP_SCPOL_OUT_MASK 0x08 +#define CS43130_SP_SCPOL_OUT_SHIFT 3 +#define CS43130_SP_SCPOL_IN_MASK 0x04 +#define CS43130_SP_SCPOL_IN_SHIFT 2 +#define CS43130_SP_LCPOL_OUT_MASK 0x02 +#define CS43130_SP_LCPOL_OUT_SHIFT 1 +#define CS43130_SP_LCPOL_IN_MASK 0x01 +#define CS43130_SP_LCPOL_IN_SHIFT 0 + +/* Reg CS43130_PWDN_CTL */ +#define CS43130_PDN_XSP_MASK 0x80 +#define CS43130_PDN_XSP_SHIFT 7 +#define CS43130_PDN_ASP_MASK 0x40 +#define CS43130_PDN_ASP_SHIFT 6 +#define CS43130_PDN_DSPIF_MASK 0x20 +#define CS43130_PDN_DSDIF_SHIFT 5 +#define CS43130_PDN_HP_MASK 0x10 +#define CS43130_PDN_HP_SHIFT 4 +#define CS43130_PDN_XTAL_MASK 0x08 +#define CS43130_PDN_XTAL_SHIFT 3 +#define CS43130_PDN_PLL_MASK 0x04 +#define CS43130_PDN_PLL_SHIFT 2 +#define CS43130_PDN_CLKOUT_MASK 0x02 +#define CS43130_PDN_CLKOUT_SHIFT 1 + +/* Reg CS43130_HP_OUT_CTL_1 */ +#define CS43130_HP_IN_EN_SHIFT 3 +#define CS43130_HP_IN_EN_MASK 0x08 + +/* Reg CS43130_PAD_INT_CFG */ +#define CS43130_ASP_3ST_MASK 0x01 +#define CS43130_XSP_3ST_MASK 0x02 + +/* Reg CS43130_PLL_SET_2 */ +#define CS43130_PLL_DIV_DATA_MASK 0x000000FF +#define CS43130_PLL_DIV_FRAC_0_DATA_SHIFT 0 + +/* Reg CS43130_PLL_SET_3 */ +#define CS43130_PLL_DIV_FRAC_1_DATA_SHIFT 8 + +/* Reg CS43130_PLL_SET_4 */ +#define CS43130_PLL_DIV_FRAC_2_DATA_SHIFT 16 + +/* Reg CS43130_SP_DEN_1 */ +#define CS43130_SP_M_LSB_DATA_MASK 0x00FF +#define CS43130_SP_M_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_DEN_2 */ +#define CS43130_SP_M_MSB_DATA_MASK 0xFF00 +#define CS43130_SP_M_MSB_DATA_SHIFT 8 + +/* Reg CS43130_SP_NUM_1 */ +#define CS43130_SP_N_LSB_DATA_MASK 0x00FF +#define CS43130_SP_N_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_NUM_2 */ +#define CS43130_SP_N_MSB_DATA_MASK 0xFF00 +#define CS43130_SP_N_MSB_DATA_SHIFT 8 + +/* Reg CS43130_SP_LRCK_HI_TIME_1 */ +#define CS43130_SP_LCHI_DATA_MASK 0x00FF +#define CS43130_SP_LCHI_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_LRCK_HI_TIME_2 */ +#define CS43130_SP_LCHI_MSB_DATA_SHIFT 8 + +/* Reg CS43130_SP_LRCK_PERIOD_1 */ +#define CS43130_SP_LCPR_DATA_MASK 0x00FF +#define CS43130_SP_LCPR_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_LRCK_PERIOD_2 */ +#define CS43130_SP_LCPR_MSB_DATA_SHIFT 8 + +#define CS43130_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define CS43130_DOP_FORMATS (SNDRV_PCM_FMTBIT_DSD_U16_LE | \ + SNDRV_PCM_FMTBIT_DSD_U16_BE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +/* Reg CS43130_CRYSTAL_SET */ +#define CS43130_XTAL_IBIAS_MASK 0x07 + +/* Reg CS43130_PATH_CTL_1 */ +#define CS43130_MUTE_MASK 0x03 +#define CS43130_MUTE_EN 0x03 + +/* Reg CS43130_DSD_INT_CFG */ +#define CS43130_DSD_MASTER 0x04 + +/* Reg CS43130_DSD_PATH_CTL_2 */ +#define CS43130_DSD_SRC_MASK 0x60 +#define CS43130_DSD_SRC_SHIFT 5 +#define CS43130_DSD_EN_SHIFT 4 +#define CS43130_DSD_SPEED_MASK 0x04 +#define CS43130_DSD_SPEED_SHIFT 2 + +/* Reg CS43130_DSD_PCM_MIX_CTL */ +#define CS43130_MIX_PCM_PREP_SHIFT 1 +#define CS43130_MIX_PCM_PREP_MASK 0x02 + +#define CS43130_MIX_PCM_DSD_SHIFT 0 +#define CS43130_MIX_PCM_DSD_MASK 0x01 + +/* Reg CS43130_HP_MEAS_LOAD */ +#define CS43130_HP_MEAS_LOAD_MASK 0x000000FF +#define CS43130_HP_MEAS_LOAD_1_SHIFT 0 +#define CS43130_HP_MEAS_LOAD_2_SHIFT 8 + +#define CS43130_MCLK_22M 22579200 +#define CS43130_MCLK_24M 24576000 + +#define CS43130_LINEOUT_LOAD 5000 +#define CS43130_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT) +#define CS43130_JACK_HEADPHONE (SND_JACK_MECHANICAL | \ + SND_JACK_HEADPHONE) +#define CS43130_JACK_MASK (SND_JACK_MECHANICAL | \ + SND_JACK_LINEOUT | \ + SND_JACK_HEADPHONE) + +enum cs43130_dsd_src { + CS43130_DSD_SRC_DSD = 0, + CS43130_DSD_SRC_ASP = 2, + CS43130_DSD_SRC_XSP = 3, +}; + +enum cs43130_asp_rate { + CS43130_ASP_SPRATE_32K = 0, + CS43130_ASP_SPRATE_44_1K, + CS43130_ASP_SPRATE_48K, + CS43130_ASP_SPRATE_88_2K, + CS43130_ASP_SPRATE_96K, + CS43130_ASP_SPRATE_176_4K, + CS43130_ASP_SPRATE_192K, + CS43130_ASP_SPRATE_352_8K, + CS43130_ASP_SPRATE_384K, +}; + +enum cs43130_mclk_src_sel { + CS43130_MCLK_SRC_EXT = 0, + CS43130_MCLK_SRC_PLL, + CS43130_MCLK_SRC_RCO +}; + +enum cs43130_mclk_int_freq { + CS43130_MCLK_24P5 = 0, + CS43130_MCLK_22P5, +}; + +enum cs43130_xtal_ibias { + CS43130_XTAL_UNUSED = -1, + CS43130_XTAL_IBIAS_15UA = 2, + CS43130_XTAL_IBIAS_12_5UA = 4, + CS43130_XTAL_IBIAS_7_5UA = 6, +}; + +enum cs43130_dai_id { + CS43130_ASP_PCM_DAI = 0, + CS43130_ASP_DOP_DAI, + CS43130_XSP_DOP_DAI, + CS43130_XSP_DSD_DAI, + CS43130_DAI_ID_MAX, +}; + +struct cs43130_clk_gen { + unsigned int mclk_int; + int fs; + u16 den; + u16 num; +}; + +/* frm_size = 16 */ +static const struct cs43130_clk_gen cs43130_16_clk_gen[] = { + {22579200, 32000, 441, 10,}, + {22579200, 44100, 32, 1,}, + {22579200, 48000, 147, 5,}, + {22579200, 88200, 16, 1,}, + {22579200, 96000, 147, 10,}, + {22579200, 176400, 8, 1,}, + {22579200, 192000, 147, 20,}, + {22579200, 352800, 4, 1,}, + {22579200, 384000, 147, 40,}, + {24576000, 32000, 48, 1,}, + {24576000, 44100, 5120, 147,}, + {24576000, 48000, 32, 1,}, + {24576000, 88200, 2560, 147,}, + {24576000, 96000, 16, 1,}, + {24576000, 176400, 1280, 147,}, + {24576000, 192000, 8, 1,}, + {24576000, 352800, 640, 147,}, + {24576000, 384000, 4, 1,}, +}; + +/* frm_size = 32 */ +static const struct cs43130_clk_gen cs43130_32_clk_gen[] = { + {22579200, 32000, 441, 20,}, + {22579200, 44100, 16, 1,}, + {22579200, 48000, 147, 10,}, + {22579200, 88200, 8, 1,}, + {22579200, 96000, 147, 20,}, + {22579200, 176400, 4, 1,}, + {22579200, 192000, 147, 40,}, + {22579200, 352800, 2, 1,}, + {22579200, 384000, 147, 80,}, + {24576000, 32000, 24, 1,}, + {24576000, 44100, 2560, 147,}, + {24576000, 48000, 16, 1,}, + {24576000, 88200, 1280, 147,}, + {24576000, 96000, 8, 1,}, + {24576000, 176400, 640, 147,}, + {24576000, 192000, 4, 1,}, + {24576000, 352800, 320, 147,}, + {24576000, 384000, 2, 1,}, +}; + +/* frm_size = 48 */ +static const struct cs43130_clk_gen cs43130_48_clk_gen[] = { + {22579200, 32000, 147, 100,}, + {22579200, 44100, 32, 3,}, + {22579200, 48000, 49, 5,}, + {22579200, 88200, 16, 3,}, + {22579200, 96000, 49, 10,}, + {22579200, 176400, 8, 3,}, + {22579200, 192000, 49, 20,}, + {22579200, 352800, 4, 3,}, + {22579200, 384000, 49, 40,}, + {24576000, 32000, 16, 1,}, + {24576000, 44100, 5120, 441,}, + {24576000, 48000, 32, 3,}, + {24576000, 88200, 2560, 441,}, + {24576000, 96000, 16, 3,}, + {24576000, 176400, 1280, 441,}, + {24576000, 192000, 8, 3,}, + {24576000, 352800, 640, 441,}, + {24576000, 384000, 4, 3,}, +}; + +/* frm_size = 64 */ +static const struct cs43130_clk_gen cs43130_64_clk_gen[] = { + {22579200, 32000, 441, 40,}, + {22579200, 44100, 8, 1,}, + {22579200, 48000, 147, 20,}, + {22579200, 88200, 4, 1,}, + {22579200, 96000, 147, 40,}, + {22579200, 176400, 2, 1,}, + {22579200, 192000, 147, 80,}, + {22579200, 352800, 1, 1,}, + {24576000, 32000, 12, 1,}, + {24576000, 44100, 1280, 147,}, + {24576000, 48000, 8, 1,}, + {24576000, 88200, 640, 147,}, + {24576000, 96000, 4, 1,}, + {24576000, 176400, 320, 147,}, + {24576000, 192000, 2, 1,}, + {24576000, 352800, 160, 147,}, + {24576000, 384000, 1, 1,}, +}; + +struct cs43130_bitwidth_map { + unsigned int bitwidth; + u8 sp_bit; + u8 ch_bit; +}; + +struct cs43130_rate_map { + int fs; + int val; +}; + +#define HP_LEFT 0 +#define HP_RIGHT 1 +#define CS43130_AC_FREQ 10 +#define CS43130_DC_THRESHOLD 2 + +#define CS43130_NUM_SUPPLIES 5 +static const char *const cs43130_supply_names[CS43130_NUM_SUPPLIES] = { + "VA", + "VP", + "VCP", + "VD", + "VL", +}; + +#define CS43130_NUM_INT 5 /* number of interrupt status reg */ + +struct cs43130_dai { + unsigned int sclk; + unsigned int dai_format; + unsigned int dai_mode; +}; + +struct cs43130_private { + struct snd_soc_codec *codec; + struct regmap *regmap; + struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES]; + struct gpio_desc *reset_gpio; + unsigned int dev_id; /* codec device ID */ + int xtal_ibias; + + /* shared by both DAIs */ + struct mutex clk_mutex; + int clk_req; + bool pll_bypass; + struct completion xtal_rdy; + struct completion pll_rdy; + unsigned int mclk; + unsigned int mclk_int; + int mclk_int_src; + + /* DAI specific */ + struct cs43130_dai dais[CS43130_DAI_ID_MAX]; + + /* HP load specific */ + bool dc_meas; + bool ac_meas; + bool hpload_done; + struct completion hpload_evt; + unsigned int hpload_stat; + u16 hpload_dc[2]; + u16 dc_threshold[CS43130_DC_THRESHOLD]; + u16 ac_freq[CS43130_AC_FREQ]; + u16 hpload_ac[CS43130_AC_FREQ][2]; + struct workqueue_struct *wq; + struct work_struct work; + struct snd_soc_jack jack; +}; + +#endif /* __CS43130_H__ */ diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 231ca935cdf3bdf22e7db0866a0dabfa61084e1e..0a749c79ef579bdd6bcf9688d6a24f784cfdc6db 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -255,7 +255,7 @@ static struct snd_soc_dai_driver cs4349_dai = { .symmetric_rates = 1, }; -static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs4349 = { .component_driver = { .controls = cs4349_snd_controls, .num_controls = ARRAY_SIZE(cs4349_snd_controls), diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 47e6fddef92b8e7af04e88de54ba04f0409736f6..e09fc8f037f10c5f04d62369c89852ab3b9273cc 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1183,7 +1183,7 @@ static struct regmap *cs47l24_get_regmap(struct device *dev) return priv->core.arizona->regmap; } -static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { .probe = cs47l24_codec_probe, .remove = cs47l24_codec_remove, .get_regmap = cs47l24_get_regmap, @@ -1203,7 +1203,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { }, }; -static struct snd_compr_ops cs47l24_compr_ops = { +static const struct snd_compr_ops cs47l24_compr_ops = { .open = cs47l24_open, .free = wm_adsp_compr_free, .set_params = wm_adsp_compr_set_params, @@ -1213,7 +1213,7 @@ static struct snd_compr_ops cs47l24_compr_ops = { .copy = wm_adsp_compr_copy, }; -static struct snd_soc_platform_driver cs47l24_compr_platform = { +static const struct snd_soc_platform_driver cs47l24_compr_platform = { .compr_ops = &cs47l24_compr_ops, }; diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 06933a5d0a75154fef952515b71bdda2a99050d9..c7edf2df5e36b707095817640edb525e550d92cb 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -842,8 +842,7 @@ static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream) { struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); - if (priv->mute_gpio) - gpiod_set_value_cansleep(priv->mute_gpio, mute); + gpiod_set_value_cansleep(priv->mute_gpio, mute); return 0; } @@ -892,7 +891,7 @@ static int cs53l30_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver cs53l30_driver = { +static const struct snd_soc_codec_driver cs53l30_driver = { .probe = cs53l30_codec_probe, .set_bias_level = cs53l30_set_bias_level, .idle_bias_off = true, @@ -960,8 +959,7 @@ static int cs53l30_i2c_probe(struct i2c_client *client, goto error; } - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); i2c_set_clientdata(client, cs53l30); @@ -1056,8 +1054,7 @@ static int cs53l30_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); /* Hold down reset */ - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), cs53l30->supplies); @@ -1073,8 +1070,7 @@ static int cs53l30_runtime_suspend(struct device *dev) regcache_cache_only(cs53l30->regmap, true); /* Hold down reset */ - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), cs53l30->supplies); @@ -1094,8 +1090,7 @@ static int cs53l30_runtime_resume(struct device *dev) return ret; } - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); regcache_cache_only(cs53l30->regmap, false); ret = regcache_sync(cs53l30->regmap); diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 2c12471e42a68dd7ed865cd581a1f27728da85ee..46b1fbb66ebaaf2225f87dbe29305f3f8d0178b5 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -398,7 +398,7 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) static const u8 cx20442_reg; -static struct snd_soc_codec_driver cx20442_codec_dev = { +static const struct snd_soc_codec_driver cx20442_codec_dev = { .probe = cx20442_codec_probe, .remove = cx20442_codec_remove, .set_bias_level = cx20442_set_bias_level, diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 17053dfc94cf07cafea279351d8382db829add1b..1af443ccbc51531c2039a0e889909a1439635b3f 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1164,7 +1164,7 @@ static int da7210_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da7210 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7210 = { .probe = da7210_probe, .component_driver = { diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index c3e11897f8aee212215cb8969c13cbe866de2c71..cc0b2d2eaf151cc9a6666badc829d1157875c016 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1787,7 +1787,7 @@ static int da7213_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da7213 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7213 = { .probe = da7213_probe, .set_bias_level = da7213_set_bias_level, diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 6e1940eb0653c720c646710d057c11337a01fb70..b2d42ec1dcd9f7f75e98c04dd35c06351bf3ca7b 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3035,7 +3035,7 @@ static int da7218_resume(struct snd_soc_codec *codec) #define da7218_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_da7218 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7218 = { .probe = da7218_probe, .remove = da7218_remove, .suspend = da7218_suspend, diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index f71d72c22bfc1b882a5045b2374110aee2eb1838..6f088536df32ea89014abffb112c4dfefe357fe0 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1891,7 +1891,7 @@ static int da7219_resume(struct snd_soc_codec *codec) #define da7219_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_da7219 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7219 = { .probe = da7219_probe, .remove = da7219_remove, .suspend = da7219_suspend, diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index c1cc1c1c28f26d75a24ca0ee792c615996a06d66..83db4d23c90b9590eef0723562c50f52ce0c3ee2 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1499,7 +1499,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da732x = { +static const struct snd_soc_codec_driver soc_codec_dev_da732x = { .set_bias_level = da732x_set_bias_level, .component_driver = { .controls = da732x_snd_controls, diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 4efb5f897a0c01943a6b977eb4e4eb269ee55336..bd7faaee5802e619ac25716f1faf7b261ea36fed 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1451,7 +1451,7 @@ static int da9055_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da9055 = { +static const struct snd_soc_codec_driver soc_codec_dev_da9055 = { .probe = da9055_probe, .set_bias_level = da9055_set_bias_level, diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index c82b9dc41e9a2b8ab2a3358ca96abc21dfd639cd..b88a1ee66f80135b55e7c211e4794a46e202232c 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -19,6 +19,8 @@ * */ +#include +#include #include #include #include @@ -27,6 +29,34 @@ #include #include +static int dmic_daiops_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai); + + if (!dmic_en) + return 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + gpiod_set_value(dmic_en, 1); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + gpiod_set_value(dmic_en, 0); + break; + } + + return 0; +} + +static const struct snd_soc_dai_ops dmic_dai_ops = { + .trigger = dmic_daiops_trigger, +}; + static struct snd_soc_dai_driver dmic_dai = { .name = "dmic-hifi", .capture = { @@ -38,8 +68,23 @@ static struct snd_soc_dai_driver dmic_dai = { | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, }, + .ops = &dmic_dai_ops, }; +static int dmic_codec_probe(struct snd_soc_codec *codec) +{ + struct gpio_desc *dmic_en; + + dmic_en = devm_gpiod_get_optional(codec->dev, + "dmicen", GPIOD_OUT_LOW); + if (IS_ERR(dmic_en)) + return PTR_ERR(dmic_en); + + snd_soc_codec_set_drvdata(codec, dmic_en); + + return 0; +} + static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0, SND_SOC_NOPM, 0, 0), @@ -50,7 +95,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"DMIC AIF", NULL, "DMic"}, }; -static struct snd_soc_codec_driver soc_dmic = { +static const struct snd_soc_codec_driver soc_dmic = { + .probe = dmic_codec_probe, .component_driver = { .dapm_widgets = dmic_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), @@ -73,9 +119,15 @@ static int dmic_dev_remove(struct platform_device *pdev) MODULE_ALIAS("platform:dmic-codec"); +static const struct of_device_id dmic_dev_match[] = { + {.compatible = "dmic-codec"}, + {} +}; + static struct platform_driver dmic_driver = { .driver = { .name = "dmic-codec", + .of_match_table = dmic_dev_match, }, .probe = dmic_dev_probe, .remove = dmic_dev_remove, diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c index 25ede825d349a4aeefab9ef3899c328d8c8d6d31..3869025754d83ec3848b3b755f79c8c64eed533e 100644 --- a/sound/soc/codecs/es7134.c +++ b/sound/soc/codecs/es7134.c @@ -69,7 +69,7 @@ static const struct snd_soc_dapm_route es7134_dapm_routes[] = { { "AOUTR", NULL, "DAC" }, }; -static struct snd_soc_codec_driver es7134_codec_driver = { +static const struct snd_soc_codec_driver es7134_codec_driver = { .component_driver = { .dapm_widgets = es7134_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(es7134_dapm_widgets), diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index ecc02449c569bd479d728aa929fc9093bf0a9fae..da2d353af5ba29a8c2018673bbddc626a56641cf 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -502,7 +502,7 @@ static int es8316_mute(struct snd_soc_dai *dai, int mute) #define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops es8316_ops = { +static const struct snd_soc_dai_ops es8316_ops = { .startup = es8316_pcm_startup, .hw_params = es8316_pcm_hw_params, .set_fmt = es8316_set_dai_fmt, @@ -554,7 +554,7 @@ static int es8316_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_es8316 = { +static const struct snd_soc_codec_driver soc_codec_dev_es8316 = { .probe = es8316_probe, .idle_bias_off = true, diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index ed7cc42d1ee2c16ece5306beb5f1aca7506dcaf5..bcdb8914ec16b992e26aecb718e430e6e0477e05 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -830,7 +830,7 @@ const struct regmap_config es8328_regmap_config = { }; EXPORT_SYMBOL_GPL(es8328_regmap_config); -static struct snd_soc_codec_driver es8328_codec_driver = { +static const struct snd_soc_codec_driver es8328_codec_driver = { .probe = es8328_codec_probe, .suspend = es8328_suspend, .resume = es8328_resume, diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index bc2e74ff3b2deddf653f1823329d22bf3449f8b6..e824d47cc22b0fd3cc2cfe8de4491530cd182bd5 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map { struct hdac_hdmi_cvt *cvt; }; +struct hdac_hdmi_drv_data { + unsigned int vendor_nid; +}; + struct hdac_hdmi_priv { struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS]; struct list_head pin_list; @@ -131,6 +135,7 @@ struct hdac_hdmi_priv { int num_ports; struct mutex pin_mutex; struct hdac_chmap chmap; + struct hdac_hdmi_drv_data *drv_data; }; static struct hdac_hdmi_pcm * @@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) } #define INTEL_VENDOR_NID 0x08 +#define INTEL_GLK_VENDOR_NID 0x0b #define INTEL_GET_VENDOR_VERB 0xf81 #define INTEL_SET_VENDOR_VERB 0x781 #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ @@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) { unsigned int vendor_param; + struct hdac_ext_device *edev = to_ehdac_device(hdac); + struct hdac_hdmi_priv *hdmi = edev->private_data; + unsigned int vendor_nid = hdmi->drv_data->vendor_nid; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_GET_VENDOR_VERB, 0); if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) return; vendor_param |= INTEL_EN_ALL_PIN_CVTS; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_SET_VENDOR_VERB, vendor_param); if (vendor_param == -1) return; @@ -1345,22 +1354,25 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac) { unsigned int vendor_param; + struct hdac_ext_device *edev = to_ehdac_device(hdac); + struct hdac_hdmi_priv *hdmi = edev->private_data; + unsigned int vendor_nid = hdmi->drv_data->vendor_nid; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_GET_VENDOR_VERB, 0); if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) return; /* enable DP1.2 mode */ vendor_param |= INTEL_EN_DP12; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_SET_VENDOR_VERB, vendor_param); if (vendor_param == -1) return; } -static struct snd_soc_dai_ops hdmi_dai_ops = { +static const struct snd_soc_dai_ops hdmi_dai_ops = { .startup = hdac_hdmi_pcm_open, .shutdown = hdac_hdmi_pcm_close, .hw_params = hdac_hdmi_set_hw_params, @@ -1858,7 +1870,7 @@ static void hdmi_codec_complete(struct device *dev) #define hdmi_codec_complete NULL #endif -static struct snd_soc_codec_driver hdmi_hda_codec = { +static const struct snd_soc_codec_driver hdmi_hda_codec = { .probe = hdmi_codec_probe, .remove = hdmi_codec_remove, .idle_bias_off = true, @@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx) return port->eld.info.spk_alloc; } +static struct hdac_hdmi_drv_data intel_glk_drv_data = { + .vendor_nid = INTEL_GLK_VENDOR_NID, +}; + +static struct hdac_hdmi_drv_data intel_drv_data = { + .vendor_nid = INTEL_VENDOR_NID, +}; + static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) { struct hdac_device *codec = &edev->hdac; @@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) struct hdac_ext_link *hlink = NULL; int num_dais = 0; int ret = 0; + struct hdac_driver *hdrv = drv_to_hdac_driver(codec->dev.driver); + const struct hda_device_id *hdac_id = hdac_get_device_id(codec, hdrv); /* hold the ref while we probe */ hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); @@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc; + if (hdac_id->driver_data) + hdmi_priv->drv_data = + (struct hdac_hdmi_drv_data *)hdac_id->driver_data; + else + hdmi_priv->drv_data = &intel_drv_data; + dev_set_drvdata(&codec->dev, edev); INIT_LIST_HEAD(&hdmi_priv->pin_list); @@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = { HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0), - HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", 0), + HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", + &intel_glk_drv_data), {} }; diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 22ed0dc88f0a1d42b541d3efa66a863fe0b35eb6..3abf82563408fde68c8d5398ef6cf1f7592c9b42 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -67,14 +67,14 @@ struct hdmi_codec_cea_spk_alloc { }; /* Channel maps stereo HDMI */ -const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { +static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { { .channels = 2, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, { } }; /* Channel maps for multi-channel playbacks, up to 8 n_ch */ -const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { +static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { { .channels = 2, /* CA_ID 0x00 */ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, { .channels = 4, /* CA_ID 0x01 */ @@ -326,7 +326,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) { int i; - const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { + static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR, [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC, }; @@ -340,7 +340,7 @@ static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) return spk_mask; } -void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp) +static void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp) { u8 spk_alloc; unsigned long spk_mask; @@ -399,18 +399,6 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol, return 0; } - -static const struct snd_kcontrol_new hdmi_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "ELD", - .info = hdmi_eld_ctl_info, - .get = hdmi_eld_ctl_get, - }, -}; - static int hdmi_codec_new_stream(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -668,6 +656,16 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, { struct snd_soc_dai_driver *drv = dai->driver; struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + struct snd_kcontrol *kctl; + struct snd_kcontrol_new hdmi_eld_ctl = { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "ELD", + .info = hdmi_eld_ctl_info, + .get = hdmi_eld_ctl_get, + .device = rtd->pcm->device, + }; int ret; dev_dbg(dai->dev, "%s()\n", __func__); @@ -686,14 +684,19 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - return 0; + /* add ELD ctl with the device number corresponding to the PCM stream */ + kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component); + if (!kctl) + return -ENOMEM; + + return snd_ctl_add(rtd->card->snd_card, kctl); } -static struct snd_soc_dai_driver hdmi_i2s_dai = { +static const struct snd_soc_dai_driver hdmi_i2s_dai = { .name = "i2s-hifi", .id = DAI_ID_I2S, .playback = { - .stream_name = "Playback", + .stream_name = "I2S Playback", .channels_min = 2, .channels_max = 8, .rates = HDMI_RATES, @@ -708,7 +711,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { .name = "spdif-hifi", .id = DAI_ID_SPDIF, .playback = { - .stream_name = "Playback", + .stream_name = "SPDIF Playback", .channels_min = 2, .channels_max = 2, .rates = HDMI_RATES, @@ -730,10 +733,8 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component, return ret; } -static struct snd_soc_codec_driver hdmi_codec = { +static const struct snd_soc_codec_driver hdmi_codec = { .component_driver = { - .controls = hdmi_controls, - .num_controls = ARRAY_SIZE(hdmi_controls), .dapm_widgets = hdmi_widgets, .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), .dapm_routes = hdmi_routes, diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c index dd850b93938d53737fe222e3e8c3b0dfee834280..651206273f3675bf519d0d05b4ca7313a4b504ff 100644 --- a/sound/soc/codecs/ics43432.c +++ b/sound/soc/codecs/ics43432.c @@ -37,7 +37,7 @@ static struct snd_soc_dai_driver ics43432_dai = { }, }; -static struct snd_soc_codec_driver ics43432_codec_driver = { +static const struct snd_soc_codec_driver ics43432_codec_driver = { }; static int ics43432_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index b918ba5c8ce5ce73acc35e843241b409113ea292..6b59b6f082983d006cb6c49acb6b03339429945e 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c @@ -310,7 +310,7 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream, SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops rk3036_codec_dai_ops = { +static const struct snd_soc_dai_ops rk3036_codec_dai_ops = { .set_fmt = rk3036_codec_dai_set_fmt, .hw_params = rk3036_codec_dai_hw_params, }; @@ -376,7 +376,7 @@ static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_codec_driver rk3036_codec_driver = { +static const struct snd_soc_codec_driver rk3036_codec_driver = { .probe = rk3036_codec_probe, .remove = rk3036_codec_remove, .set_bias_level = rk3036_codec_set_bias_level, diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index a4b0eded984aff2ce711fc70c84545ef3df02fcd..5ca99280ae0097bd59a36df4f6fc1c44ab8427fe 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1087,7 +1087,7 @@ static struct snd_soc_dai_driver isabelle_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_isabelle = { +static const struct snd_soc_codec_driver soc_codec_dev_isabelle = { .set_bias_level = isabelle_set_bias_level, .component_driver = { .controls = isabelle_snd_controls, diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 0290fab383da8864086e7e617051a15b65d3b1e7..6324ccdc8a5c556b00d3d80b81f8fe626743ca41 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -293,7 +293,7 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { +static const struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { .probe = jz4740_codec_dev_probe, .set_bias_level = jz4740_codec_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 558de1053f73ce52934747f50ef16a702e48a0a4..1e964079642adc5e53ad06e1bbd8fc72c7b62786 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -100,7 +100,7 @@ static const struct snd_soc_dapm_route lm4857_routes[] = { { "EP", "Earpiece", "Mode" }, }; -static struct snd_soc_component_driver lm4857_component_driver = { +static const struct snd_soc_component_driver lm4857_component_driver = { .controls = lm4857_controls, .num_controls = ARRAY_SIZE(lm4857_controls), .dapm_widgets = lm4857_dapm_widgets, diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 8d413c2677ccad5287d06a41d33c586296056985..41e09d1287b8583479b4df23c3db83ddc465ef2e 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1389,7 +1389,7 @@ static struct snd_soc_dai_driver lm49453_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { +static const struct snd_soc_codec_driver soc_codec_dev_lm49453 = { .set_bias_level = lm49453_set_bias_level, .component_driver = { .controls = lm49453_snd_controls, diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 5b82e26cd5d1ae506acebf9394629e03bfa73b12..7017c0389e73ccaad575350be8b9c1ddb72b8be1 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -151,7 +151,7 @@ static int max9768_probe(struct snd_soc_component *component) return 0; } -static struct snd_soc_component_driver max9768_component_driver = { +static const struct snd_soc_component_driver max9768_component_driver = { .probe = max9768_probe, .controls = max9768_volume, .num_controls = ARRAY_SIZE(max9768_volume), diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 72f77455582eb4ad4f76c4b0cc1713c7c007177c..f0bb830874e59ab9c2b544e961143c0a4515c6ce 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1698,7 +1698,7 @@ static int max98088_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max98088 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98088 = { .probe = max98088_probe, .remove = max98088_remove, .set_bias_level = max98088_set_bias_level, diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 66828480d484ca11912d8b163efe0c51445b155c..13bcfb1ef9b423ceb5fa2ae222340eccaed2ed69 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2499,7 +2499,7 @@ static void max98090_seq_notifier(struct snd_soc_dapm_context *dapm, } } -static struct snd_soc_codec_driver soc_codec_dev_max98090 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98090 = { .probe = max98090_probe, .remove = max98090_remove, .seq_notifier = max98090_seq_notifier, diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 6f8a757876ed9c758c2c4719c8d563f18b3e9983..5ead87d2ab1df95cfc8245a3b07aae5fb49b9f83 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2102,7 +2102,7 @@ static int max98095_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max98095 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98095 = { .probe = max98095_probe, .remove = max98095_remove, .suspend = max98095_suspend, diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 6a6b68a4cb527fc389b61d6e70524f13f11b3b5a..426ed2dae6ca292bcfd08a283a5b0703717b78e6 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -72,7 +72,7 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver max98357a_codec_driver = { +static const struct snd_soc_codec_driver max98357a_codec_driver = { .probe = max98357a_codec_probe, .component_driver = { .dapm_widgets = max98357a_dapm_widgets, diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 781be9ba8dba0f212e1939f4cb995e64024a3d49..7bc2a17c1e94087389a04d26c982ec628d795d1b 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c @@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = { }; static const struct snd_soc_codec_driver max98371_codec = { - .controls = max98371_snd_controls, - .num_controls = ARRAY_SIZE(max98371_snd_controls), - .dapm_routes = max98371_audio_map, - .num_dapm_routes = ARRAY_SIZE(max98371_audio_map), - .dapm_widgets = max98371_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets), + .component_driver = { + .controls = max98371_snd_controls, + .num_controls = ARRAY_SIZE(max98371_snd_controls), + .dapm_routes = max98371_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98371_audio_map), + .dapm_widgets = max98371_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets), + }, }; static const struct regmap_config max98371_regmap = { diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 0610840733d1629d7fdd12f3dcdcf023681b3c42..a3dfc918c278bda4b41a972c204daa031baed106 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -301,7 +301,7 @@ static int max9850_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max9850 = { +static const struct snd_soc_codec_driver soc_codec_dev_max9850 = { .probe = max9850_probe, .set_bias_level = max9850_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 499bdbfd0a2d93e7fa88da23915027a53556b238..a2dc6a47f4664637bef5c302c18758d9b421c954 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -534,7 +534,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_codec_driver max9860_codec_driver = { +static const struct snd_soc_codec_driver max9860_codec_driver = { .set_bias_level = max9860_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 2a40a69a7513817fe65753f774078f26e0aefec6..2f60924fe9196861391ed7a8234c8aab41449b10 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -350,7 +350,7 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai, return 0; } -static struct snd_soc_dai_ops max9867_dai_ops = { +static const struct snd_soc_dai_ops max9867_dai_ops = { .set_fmt = max9867_dai_set_fmt, .set_sysclk = max9867_set_dai_sysclk, .prepare = max9867_prepare, @@ -413,7 +413,7 @@ static int max9867_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver max9867_codec = { +static const struct snd_soc_codec_driver max9867_codec = { .probe = max9867_probe, .component_driver = { .controls = max9867_snd_controls, diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 1eff7e0b092e1f5773fc88f7110cb71e37d80e44..03d07bf4d942198af925cb33fe5d65de9883f3bf 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c @@ -213,8 +213,8 @@ static bool max98926_readable_register(struct device *dev, unsigned int reg) } }; -DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0); -DECLARE_TLV_DB_RANGE(max98926_current_tlv, +static DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0); +static DECLARE_TLV_DB_RANGE(max98926_current_tlv, 0, 11, TLV_DB_SCALE_ITEM(20, 20, 0), 12, 15, TLV_DB_SCALE_ITEM(320, 40, 0), ); @@ -459,7 +459,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream, #define MAX98926_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops max98926_dai_ops = { +static const struct snd_soc_dai_ops max98926_dai_ops = { .set_fmt = max98926_dai_set_fmt, .hw_params = max98926_dai_hw_params, }; @@ -496,7 +496,7 @@ static int max98926_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max98926 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98926 = { .probe = max98926_probe, .component_driver = { .controls = max98926_snd_controls, diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index b5ee29499e166d887f6e62e3b2dfcfc05ef3aa4c..d9dbbe72f8ad4cb9cfbbccba06153359cc1529bc 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -44,9 +44,9 @@ static struct reg_default max98927_reg[] = { {MAX98927_R0011_CLK_MON, 0x00}, {MAX98927_R0012_WDOG_CTRL, 0x00}, {MAX98927_R0013_WDOG_RST, 0x00}, - {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x00}, - {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x00}, - {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x00}, + {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x75}, + {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x8c}, + {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x08}, {MAX98927_R0017_PIN_CFG, 0x55}, {MAX98927_R0018_PCM_RX_EN_A, 0x00}, {MAX98927_R0019_PCM_RX_EN_B, 0x00}, @@ -82,14 +82,14 @@ static struct reg_default max98927_reg[] = { {MAX98927_R003A_AMP_EN, 0x00}, {MAX98927_R003B_SPK_SRC_SEL, 0x00}, {MAX98927_R003C_SPK_GAIN, 0x00}, - {MAX98927_R003D_SSM_CFG, 0x01}, + {MAX98927_R003D_SSM_CFG, 0x04}, {MAX98927_R003E_MEAS_EN, 0x00}, {MAX98927_R003F_MEAS_DSP_CFG, 0x04}, {MAX98927_R0040_BOOST_CTRL0, 0x00}, {MAX98927_R0041_BOOST_CTRL3, 0x00}, {MAX98927_R0042_BOOST_CTRL1, 0x00}, {MAX98927_R0043_MEAS_ADC_CFG, 0x00}, - {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x00}, + {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x01}, {MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00}, {MAX98927_R0046_ADC_CH0_DIVIDE, 0x00}, {MAX98927_R0047_ADC_CH1_DIVIDE, 0x00}, @@ -159,7 +159,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) mode = MAX98927_PCM_MASTER_MODE_MASTER; break; default: - dev_err(codec->dev, "DAI clock mode unsupported"); + dev_err(codec->dev, "DAI clock mode unsupported\n"); return -EINVAL; } @@ -175,7 +175,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE; break; default: - dev_err(codec->dev, "DAI invert mode unsupported"); + dev_err(codec->dev, "DAI invert mode unsupported\n"); return -EINVAL; } @@ -311,7 +311,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream, chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32; break; default: - dev_err(codec->dev, "format unsupported %d", + dev_err(codec->dev, "format unsupported %d\n", params_format(params)); goto err; } @@ -418,11 +418,6 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w, regmap_update_bits(max98927->regmap, MAX98927_R003A_AMP_EN, MAX98927_AMP_EN_MASK, 1); - /* enable VMON and IMON */ - regmap_update_bits(max98927->regmap, - MAX98927_R003E_MEAS_EN, - MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, - MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN); regmap_update_bits(max98927->regmap, MAX98927_R00FF_GLOBAL_SHDN, MAX98927_GLOBAL_EN_MASK, 1); @@ -434,10 +429,6 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w, regmap_update_bits(max98927->regmap, MAX98927_R003A_AMP_EN, MAX98927_AMP_EN_MASK, 0); - /* disable VMON and IMON */ - regmap_update_bits(max98927->regmap, - MAX98927_R003E_MEAS_EN, - MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0); break; default: return 0; @@ -456,14 +447,24 @@ static const struct soc_enum dai_sel_enum = static const struct snd_kcontrol_new max98927_dai_controls = SOC_DAPM_ENUM("DAI Sel", dai_sel_enum); +static const struct snd_kcontrol_new max98927_vi_control = + SOC_DAPM_SINGLE("Switch", MAX98927_R003F_MEAS_DSP_CFG, 2, 1, 0); + static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = { - SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN, 0, 0, max98927_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0, &max98927_dai_controls), SND_SOC_DAPM_OUTPUT("BE_OUT"), + SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0, + MAX98927_R003E_MEAS_EN, 0, 0), + SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0, + MAX98927_R003E_MEAS_EN, 1, 0), + SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0, + &max98927_vi_control), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON"), }; static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0); @@ -495,6 +496,13 @@ static bool max98927_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3: + case MAX98927_R004C_MEAS_ADC_CH0_READ: + case MAX98927_R004D_MEAS_ADC_CH1_READ: + case MAX98927_R004E_MEAS_ADC_CH2_READ: + case MAX98927_R0051_BROWNOUT_STATUS: + case MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ: + case MAX98927_R01FF_REV_ID: + case MAX98927_R0100_SOFT_RESET: return true; default: return false; @@ -543,11 +551,16 @@ static const struct snd_kcontrol_new max98927_snd_controls[] = { }; static const struct snd_soc_dapm_route max98927_audio_map[] = { - {"Amp Enable", NULL, "DAI_OUT"}, + /* Plabyack */ {"DAI Sel Mux", "Left", "Amp Enable"}, {"DAI Sel Mux", "Right", "Amp Enable"}, {"DAI Sel Mux", "LeftRight", "Amp Enable"}, {"BE_OUT", NULL, "DAI Sel Mux"}, + /* Capture */ + { "VI Sense", "Switch", "VMON" }, + { "VI Sense", "Switch", "IMON" }, + { "Voltage Sense", NULL, "VI Sense" }, + { "Current Sense", NULL, "VI Sense" }, }; static struct snd_soc_dai_driver max98927_dai[] = { @@ -577,7 +590,6 @@ static int max98927_probe(struct snd_soc_codec *codec) max98927->codec = codec; codec->control_data = max98927->regmap; - codec->cache_bypass = 1; /* Software Reset */ regmap_write(max98927->regmap, @@ -694,6 +706,31 @@ static int max98927_probe(struct snd_soc_codec *codec) return 0; } +#ifdef CONFIG_PM_SLEEP +static int max98927_suspend(struct device *dev) +{ + struct max98927_priv *max98927 = dev_get_drvdata(dev); + + regcache_cache_only(max98927->regmap, true); + regcache_mark_dirty(max98927->regmap); + return 0; +} +static int max98927_resume(struct device *dev) +{ + struct max98927_priv *max98927 = dev_get_drvdata(dev); + + regmap_write(max98927->regmap, + MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET); + regcache_cache_only(max98927->regmap, false); + regcache_sync(max98927->regmap); + return 0; +} +#endif + +static const struct dev_pm_ops max98927_pm = { + SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume) +}; + static const struct snd_soc_codec_driver soc_codec_dev_max98927 = { .probe = max98927_probe, .component_driver = { @@ -721,14 +758,14 @@ static void max98927_slot_config(struct i2c_client *i2c, struct max98927_priv *max98927) { int value; + struct device *dev = &i2c->dev; - if (!of_property_read_u32(i2c->dev.of_node, - "vmon-slot-no", &value)) + if (!device_property_read_u32(dev, "vmon-slot-no", &value)) max98927->v_l_slot = value & 0xF; else max98927->v_l_slot = 0; - if (!of_property_read_u32(i2c->dev.of_node, - "imon-slot-no", &value)) + + if (!device_property_read_u32(dev, "imon-slot-no", &value)) max98927->i_l_slot = value & 0xF; else max98927->i_l_slot = 1; @@ -827,7 +864,7 @@ static struct i2c_driver max98927_i2c_driver = { .name = "max98927", .of_match_table = of_match_ptr(max98927_of_match), .acpi_match_table = ACPI_PTR(max98927_acpi_match), - .pm = NULL, + .pm = &max98927_pm, }, .probe = max98927_i2c_probe, .remove = max98927_i2c_remove, diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 90562703dcfdb1eb8c3a76c87303457173c7a28b..4fd8d1dc4eefca8624f33819706de3fc79996eb1 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -733,7 +733,7 @@ static struct regmap *mc13783_get_regmap(struct device *dev) return dev_get_regmap(dev->parent, NULL); } -static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { +static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = { .probe = mc13783_probe, .remove = mc13783_remove, .get_regmap = mc13783_get_regmap, diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 69e5e18880c53c35835b0bb8e5b5eb749c0c16b7..5cc960d8211e3c6f8608900456210fe715d3bac5 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -537,7 +537,7 @@ static int ml26124_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ml26124 = { +static const struct snd_soc_codec_driver soc_codec_dev_ml26124 = { .probe = ml26124_probe, .set_bias_level = ml26124_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index a78802920c3cc098af2526a4ba335dba0df5a59f..549c269acc7dfd0a084c333f08076b77390d1c79 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -12,9 +12,16 @@ #include #include #include +#include #define CDC_D_REVISION1 (0xf000) #define CDC_D_PERPH_SUBTYPE (0xf005) +#define CDC_D_INT_EN_SET (0x015) +#define CDC_D_INT_EN_CLR (0x016) +#define MBHC_SWITCH_INT BIT(7) +#define MBHC_MIC_ELECTRICAL_INS_REM_DET BIT(6) +#define MBHC_BUTTON_PRESS_DET BIT(5) +#define MBHC_BUTTON_RELEASE_DET BIT(4) #define CDC_D_CDC_RST_CTL (0xf046) #define RST_CTL_DIG_SW_RST_N_MASK BIT(7) #define RST_CTL_DIG_SW_RST_N_RESET 0 @@ -36,7 +43,9 @@ #define CDC_D_CDC_DIG_CLK_CTL (0xf04A) #define DIG_CLK_CTL_RXD1_CLK_EN BIT(0) #define DIG_CLK_CTL_RXD2_CLK_EN BIT(1) -#define DIG_CLK_CTL_RXD3_CLK_EN BIT(3) +#define DIG_CLK_CTL_RXD3_CLK_EN BIT(2) +#define DIG_CLK_CTL_D_MBHC_CLK_EN_MASK BIT(3) +#define DIG_CLK_CTL_D_MBHC_CLK_EN BIT(3) #define DIG_CLK_CTL_TXD_CLK_EN BIT(4) #define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6) #define DIG_CLK_CTL_NCP_CLK_EN BIT(6) @@ -93,8 +102,12 @@ #define MICB_1_EN_TX3_GND_SEL_TX_GND 0 #define CDC_A_MICB_1_VAL (0xf141) +#define MICB_MIN_VAL 1600 +#define MICB_STEP_SIZE 50 +#define MICB_VOLTAGE_REGVAL(v) ((v - MICB_MIN_VAL)/MICB_STEP_SIZE) #define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3) #define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3) +#define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3) #define CDC_A_MICB_1_CTL (0xf142) #define MICB_1_CTL_CFILT_REF_SEL_MASK BIT(1) @@ -128,8 +141,51 @@ #define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_GND 0 #define CDC_A_MICB_2_EN (0xf144) +#define CDC_A_MICB_2_EN_ENABLE BIT(7) +#define CDC_A_MICB_2_PULL_DOWN_EN_MASK BIT(5) +#define CDC_A_MICB_2_PULL_DOWN_EN BIT(5) #define CDC_A_TX_1_2_ATEST_CTL_2 (0xf145) #define CDC_A_MASTER_BIAS_CTL (0xf146) +#define CDC_A_MBHC_DET_CTL_1 (0xf147) +#define CDC_A_MBHC_DET_CTL_L_DET_EN BIT(7) +#define CDC_A_MBHC_DET_CTL_GND_DET_EN BIT(6) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION BIT(5) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_REMOVAL (0) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK BIT(5) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT (5) +#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO BIT(4) +#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MANUAL BIT(3) +#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MASK GENMASK(4, 3) +#define CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN BIT(2) +#define CDC_A_MBHC_DET_CTL_2 (0xf150) +#define CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 (BIT(7) | BIT(6)) +#define CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD BIT(5) +#define CDC_A_PLUG_TYPE_MASK GENMASK(4, 3) +#define CDC_A_HPHL_PLUG_TYPE_NO BIT(4) +#define CDC_A_GND_PLUG_TYPE_NO BIT(3) +#define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN_MASK BIT(0) +#define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN BIT(0) +#define CDC_A_MBHC_FSM_CTL (0xf151) +#define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN BIT(7) +#define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK BIT(7) +#define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA (0x3 << 4) +#define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK GENMASK(6, 4) +#define CDC_A_MBHC_DBNC_TIMER (0xf152) +#define CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS BIT(3) +#define CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS (0x9 << 4) +#define CDC_A_MBHC_BTN0_ZDET_CTL_0 (0xf153) +#define CDC_A_MBHC_BTN1_ZDET_CTL_1 (0xf154) +#define CDC_A_MBHC_BTN2_ZDET_CTL_2 (0xf155) +#define CDC_A_MBHC_BTN3_CTL (0xf156) +#define CDC_A_MBHC_BTN4_CTL (0xf157) +#define CDC_A_MBHC_BTN_VREF_FINE_SHIFT (2) +#define CDC_A_MBHC_BTN_VREF_FINE_MASK GENMASK(4, 2) +#define CDC_A_MBHC_BTN_VREF_COARSE_MASK GENMASK(7, 5) +#define CDC_A_MBHC_BTN_VREF_COARSE_SHIFT (5) +#define CDC_A_MBHC_BTN_VREF_MASK (CDC_A_MBHC_BTN_VREF_COARSE_MASK | \ + CDC_A_MBHC_BTN_VREF_FINE_MASK) +#define CDC_A_MBHC_RESULT_1 (0xf158) +#define CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK GENMASK(4, 0) #define CDC_A_TX_1_EN (0xf160) #define CDC_A_TX_2_EN (0xf161) #define CDC_A_TX_1_2_TEST_CTL_1 (0xf162) @@ -213,18 +269,37 @@ #define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE) +static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4; +static int hs_jack_mask = SND_JACK_HEADPHONE | SND_JACK_HEADSET; + static const char * const supply_names[] = { "vdd-cdc-io", "vdd-cdc-tx-rx-cx", }; +#define MBHC_MAX_BUTTONS (5) + struct pm8916_wcd_analog_priv { u16 pmic_rev; u16 codec_version; + bool mbhc_btn_enabled; + /* special event to detect accessory type */ + bool mbhc_btn0_pressed; + bool detect_accessory_type; struct clk *mclk; + struct snd_soc_codec *codec; struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; + struct snd_soc_jack *jack; + bool hphl_jack_type_normally_open; + bool gnd_jack_type_normally_open; + /* Voltage threshold when internal current source of 100uA is used */ + u32 vref_btn_cs[MBHC_MAX_BUTTONS]; + /* Voltage threshold when microphone bias is ON */ + u32 vref_btn_micb[MBHC_MAX_BUTTONS]; unsigned int micbias1_cap_mode; unsigned int micbias2_cap_mode; + unsigned int micbias_mv; }; static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" }; @@ -265,18 +340,25 @@ static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = { static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec) { + struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec); + snd_soc_update_bits(codec, CDC_A_MICB_1_CTL, MICB_1_CTL_EXT_PRECHARG_EN_MASK | MICB_1_CTL_INT_PRECHARG_BYP_MASK, MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE); - snd_soc_write(codec, CDC_A_MICB_1_VAL, MICB_1_VAL_MICB_OUT_VAL_V2P70V); - /* - * Special headset needs MICBIAS as 2.7V so wait for - * 50 msec for the MICBIAS to reach 2.7 volts. - */ - msleep(50); + if (wcd->micbias_mv) { + snd_soc_write(codec, CDC_A_MICB_1_VAL, + MICB_VOLTAGE_REGVAL(wcd->micbias_mv)); + /* + * Special headset needs MICBIAS as 2.7V so wait for + * 50 msec for the MICBIAS to reach 2.7 volts. + */ + if (wcd->micbias_mv >= 2700) + msleep(50); + } + snd_soc_update_bits(codec, CDC_A_MICB_1_CTL, MICB_1_CTL_EXT_PRECHARG_EN_MASK | MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0); @@ -361,6 +443,97 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct wcd->micbias1_cap_mode); } +static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd) +{ + struct snd_soc_codec *codec = wcd->codec; + u32 plug_type = 0; + u32 int_en_mask; + + snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1, + CDC_A_MBHC_DET_CTL_L_DET_EN | + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION | + CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO | + CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN); + + if (wcd->hphl_jack_type_normally_open) + plug_type |= CDC_A_HPHL_PLUG_TYPE_NO; + + if (wcd->gnd_jack_type_normally_open) + plug_type |= CDC_A_GND_PLUG_TYPE_NO; + + snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2, + CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 | + CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD | + plug_type | + CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN); + + + snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER, + CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS | + CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS); + + /* enable MBHC clock */ + snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL, + DIG_CLK_CTL_D_MBHC_CLK_EN_MASK, + DIG_CLK_CTL_D_MBHC_CLK_EN); + + int_en_mask = MBHC_SWITCH_INT; + if (wcd->mbhc_btn_enabled) + int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET; + + snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0); + snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask); + wcd->mbhc_btn0_pressed = false; + wcd->detect_accessory_type = true; +} + +static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv, + bool micbias2_enabled) +{ + struct snd_soc_codec *codec = priv->codec; + u32 coarse, fine, reg_val, reg_addr; + int *vrefs, i; + + if (!micbias2_enabled) { /* use internal 100uA Current source */ + /* Enable internal 2.2k Internal Rbias Resistor */ + snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS, + MICB_1_INT_TX2_INT_RBIAS_EN_MASK, + MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE); + /* Remove pull down on MIC BIAS2 */ + snd_soc_update_bits(codec, CDC_A_MICB_2_EN, + CDC_A_MICB_2_PULL_DOWN_EN_MASK, + 0); + /* enable 100uA internal current source */ + snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL, + CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK, + CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA); + } + snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL, + CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK, + CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN); + + if (micbias2_enabled) + vrefs = &priv->vref_btn_micb[0]; + else + vrefs = &priv->vref_btn_cs[0]; + + /* program vref ranges for all the buttons */ + reg_addr = CDC_A_MBHC_BTN0_ZDET_CTL_0; + for (i = 0; i < MBHC_MAX_BUTTONS; i++) { + /* split mv in to coarse parts of 100mv & fine parts of 12mv */ + coarse = (vrefs[i] / 100); + fine = ((vrefs[i] % 100) / 12); + reg_val = (coarse << CDC_A_MBHC_BTN_VREF_COARSE_SHIFT) | + (fine << CDC_A_MBHC_BTN_VREF_FINE_SHIFT); + snd_soc_update_bits(codec, reg_addr, + CDC_A_MBHC_BTN_VREF_MASK, + reg_val); + reg_addr++; + } + + return 0; +} + static int pm8916_wcd_analog_enable_micbias_int2(struct snd_soc_dapm_widget *w, struct snd_kcontrol @@ -369,6 +542,15 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + pm8916_mbhc_configure_bias(wcd, true); + break; + case SND_SOC_DAPM_POST_PMD: + pm8916_mbhc_configure_bias(wcd, false); + break; + } + return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg, wcd->micbias2_cap_mode); } @@ -536,6 +718,14 @@ static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec) snd_soc_write(codec, wcd_reg_defaults_2_0[reg].reg, wcd_reg_defaults_2_0[reg].def); + priv->codec = codec; + + snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL, + RST_CTL_DIG_SW_RST_N_MASK, + RST_CTL_DIG_SW_RST_N_REMOVE_RESET); + + pm8916_wcd_setup_mbhc(priv); + return 0; } @@ -543,6 +733,9 @@ static int pm8916_wcd_analog_remove(struct snd_soc_codec *codec) { struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev); + snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL, + RST_CTL_DIG_SW_RST_N_MASK, 0); + return regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); } @@ -731,32 +924,128 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0), }; +static int pm8916_wcd_analog_set_jack(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, + void *data) +{ + struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec); + + wcd->jack = jack; + + return 0; +} + static struct regmap *pm8916_get_regmap(struct device *dev) { return dev_get_regmap(dev->parent, NULL); } -static int pm8916_wcd_analog_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg) { - snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL, - RST_CTL_DIG_SW_RST_N_MASK, - RST_CTL_DIG_SW_RST_N_REMOVE_RESET); + struct pm8916_wcd_analog_priv *priv = arg; - return 0; + if (priv->detect_accessory_type) { + struct snd_soc_codec *codec = priv->codec; + u32 val = snd_soc_read(codec, CDC_A_MBHC_RESULT_1); + + /* check if its BTN0 thats released */ + if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK)) + priv->mbhc_btn0_pressed = false; + + } else { + snd_soc_jack_report(priv->jack, 0, btn_mask); + } + + return IRQ_HANDLED; } -static void pm8916_wcd_analog_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg) { - snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL, - RST_CTL_DIG_SW_RST_N_MASK, 0); + struct pm8916_wcd_analog_priv *priv = arg; + struct snd_soc_codec *codec = priv->codec; + u32 btn_result; + + btn_result = snd_soc_read(codec, CDC_A_MBHC_RESULT_1) & + CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK; + + switch (btn_result) { + case 0xf: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_4, btn_mask); + break; + case 0x7: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_3, btn_mask); + break; + case 0x3: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_2, btn_mask); + break; + case 0x1: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_1, btn_mask); + break; + case 0x0: + /* handle BTN_0 specially for type detection */ + if (priv->detect_accessory_type) + priv->mbhc_btn0_pressed = true; + else + snd_soc_jack_report(priv->jack, + SND_JACK_BTN_0, btn_mask); + break; + default: + dev_err(codec->dev, + "Unexpected button press result (%x)", btn_result); + break; + } + + return IRQ_HANDLED; } -static struct snd_soc_dai_ops pm8916_wcd_analog_dai_ops = { - .startup = pm8916_wcd_analog_startup, - .shutdown = pm8916_wcd_analog_shutdown, -}; +static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg) +{ + struct pm8916_wcd_analog_priv *priv = arg; + struct snd_soc_codec *codec = priv->codec; + bool ins = false; + + if (snd_soc_read(codec, CDC_A_MBHC_DET_CTL_1) & + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK) + ins = true; + + /* Set the detection type appropriately */ + snd_soc_update_bits(codec, CDC_A_MBHC_DET_CTL_1, + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK, + (!ins << CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT)); + + + if (ins) { /* hs insertion */ + bool micbias_enabled = false; + + if (snd_soc_read(codec, CDC_A_MICB_2_EN) & + CDC_A_MICB_2_EN_ENABLE) + micbias_enabled = true; + + pm8916_mbhc_configure_bias(priv, micbias_enabled); + + /* + * if only a btn0 press event is receive just before + * insert event then its a 3 pole headphone else if + * both press and release event received then its + * a headset. + */ + if (priv->mbhc_btn0_pressed) + snd_soc_jack_report(priv->jack, + SND_JACK_HEADPHONE, hs_jack_mask); + else + snd_soc_jack_report(priv->jack, + SND_JACK_HEADSET, hs_jack_mask); + + priv->detect_accessory_type = false; + + } else { /* removal */ + snd_soc_jack_report(priv->jack, 0, hs_jack_mask); + priv->detect_accessory_type = true; + priv->mbhc_btn0_pressed = false; + } + + return IRQ_HANDLED; +} static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = { [0] = { @@ -769,7 +1058,6 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = { .channels_min = 1, .channels_max = 3, }, - .ops = &pm8916_wcd_analog_dai_ops, }, [1] = { .name = "pm8916_wcd_analog_pdm_tx", @@ -781,13 +1069,13 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = { .channels_min = 1, .channels_max = 4, }, - .ops = &pm8916_wcd_analog_dai_ops, }, }; -static struct snd_soc_codec_driver pm8916_wcd_analog = { +static const struct snd_soc_codec_driver pm8916_wcd_analog = { .probe = pm8916_wcd_analog_probe, .remove = pm8916_wcd_analog_remove, + .set_jack = pm8916_wcd_analog_set_jack, .get_regmap = pm8916_get_regmap, .component_driver = { .controls = pm8916_wcd_analog_snd_controls, @@ -802,6 +1090,7 @@ static struct snd_soc_codec_driver pm8916_wcd_analog = { static int pm8916_wcd_analog_parse_dt(struct device *dev, struct pm8916_wcd_analog_priv *priv) { + int rval; if (of_property_read_bool(dev->of_node, "qcom,micbias1-ext-cap")) priv->micbias1_cap_mode = MICB_1_EN_EXT_BYP_CAP; @@ -813,6 +1102,42 @@ static int pm8916_wcd_analog_parse_dt(struct device *dev, else priv->micbias2_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP; + of_property_read_u32(dev->of_node, "qcom,micbias-lvl", + &priv->micbias_mv); + + if (of_property_read_bool(dev->of_node, + "qcom,hphl-jack-type-normally-open")) + priv->hphl_jack_type_normally_open = true; + else + priv->hphl_jack_type_normally_open = false; + + if (of_property_read_bool(dev->of_node, + "qcom,gnd-jack-type-normally-open")) + priv->gnd_jack_type_normally_open = true; + else + priv->gnd_jack_type_normally_open = false; + + priv->mbhc_btn_enabled = true; + rval = of_property_read_u32_array(dev->of_node, + "qcom,mbhc-vthreshold-low", + &priv->vref_btn_cs[0], + MBHC_MAX_BUTTONS); + if (rval < 0) { + priv->mbhc_btn_enabled = false; + } else { + rval = of_property_read_u32_array(dev->of_node, + "qcom,mbhc-vthreshold-high", + &priv->vref_btn_micb[0], + MBHC_MAX_BUTTONS); + if (rval < 0) + priv->mbhc_btn_enabled = false; + } + + if (!priv->mbhc_btn_enabled) + dev_err(dev, + "DT property missing, MBHC btn detection disabled\n"); + + return 0; } @@ -820,7 +1145,7 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) { struct pm8916_wcd_analog_priv *priv; struct device *dev = &pdev->dev; - int ret, i; + int ret, i, irq; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -852,6 +1177,48 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) return ret; } + irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); + if (irq < 0) { + dev_err(dev, "failed to get mbhc switch irq\n"); + return irq; + } + + ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "mbhc switch irq", priv); + if (ret) + dev_err(dev, "cannot request mbhc switch irq\n"); + + if (priv->mbhc_btn_enabled) { + irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); + if (irq < 0) { + dev_err(dev, "failed to get button press irq\n"); + return irq; + } + + ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "mbhc btn press irq", priv); + if (ret) + dev_err(dev, "cannot request mbhc button press irq\n"); + + irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); + if (irq < 0) { + dev_err(dev, "failed to get button release irq\n"); + return irq; + } + + ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "mbhc btn release irq", priv); + if (ret) + dev_err(dev, "cannot request mbhc button release irq\n"); + + } + dev_set_drvdata(dev, priv); return snd_soc_register_codec(dev, &pm8916_wcd_analog, diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index f690442af8c9409d21a6558ec910e672a6c8b4cb..66df8f810f0d740772a62d965466358012d91d4f 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -218,6 +218,8 @@ static const char *const rx_mix1_text[] = { static const char *const dec_mux_text[] = { "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2" }; + +static const char *const cic_mux_text[] = { "AMIC", "DMIC" }; static const char *const rx_mix2_text[] = { "ZERO", "IIR1", "IIR2" }; static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" }; @@ -256,11 +258,21 @@ static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE( static const struct soc_enum dec2_mux_enum = SOC_ENUM_SINGLE( LPASS_CDC_CONN_TX_B1_CTL, 3, 6, dec_mux_text); +/* CIC */ +static const struct soc_enum cic1_mux_enum = SOC_ENUM_SINGLE( + LPASS_CDC_TX1_MUX_CTL, 0, 2, cic_mux_text); +static const struct soc_enum cic2_mux_enum = SOC_ENUM_SINGLE( + LPASS_CDC_TX2_MUX_CTL, 0, 2, cic_mux_text); + /* RDAC2 MUX */ static const struct snd_kcontrol_new dec1_mux = SOC_DAPM_ENUM( "DEC1 MUX Mux", dec1_mux_enum); static const struct snd_kcontrol_new dec2_mux = SOC_DAPM_ENUM( "DEC2 MUX Mux", dec2_mux_enum); +static const struct snd_kcontrol_new cic1_mux = SOC_DAPM_ENUM( + "CIC1 MUX Mux", cic1_mux_enum); +static const struct snd_kcontrol_new cic2_mux = SOC_DAPM_ENUM( + "CIC2 MUX Mux", cic2_mux_enum); static const struct snd_kcontrol_new rx_mix1_inp1_mux = SOC_DAPM_ENUM( "RX1 MIX1 INP1 Mux", rx_mix1_inp_enum[0]); static const struct snd_kcontrol_new rx_mix1_inp2_mux = SOC_DAPM_ENUM( @@ -500,6 +512,8 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, &rx3_mix1_inp3_mux), + SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux), + SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux), /* TX */ SND_SOC_DAPM_MIXER("ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -536,6 +550,8 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { /* Connectivity Clock */ SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, LPASS_CDC_CLK_OTHR_CTL, 2, 0, NULL, 0), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), }; @@ -568,6 +584,15 @@ static int msm8916_wcd_digital_codec_probe(struct snd_soc_codec *codec) return 0; } +static int msm8916_wcd_digital_codec_set_sysclk(struct snd_soc_codec *codec, + int clk_id, int source, + unsigned int freq, int dir) +{ + struct msm8916_wcd_digital_priv *p = dev_get_drvdata(codec->dev); + + return clk_set_rate(p->mclk, freq); +} + static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -646,6 +671,11 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = { {"AIF1 Capture", NULL, "I2S TX2"}, {"AIF1 Capture", NULL, "I2S TX3"}, + {"CIC1 MUX", "DMIC", "DEC1 MUX"}, + {"CIC1 MUX", "AMIC", "DEC1 MUX"}, + {"CIC2 MUX", "DMIC", "DEC2 MUX"}, + {"CIC2 MUX", "AMIC", "DEC2 MUX"}, + /* Decimator Inputs */ {"DEC1 MUX", "DMIC1", "DMIC1"}, {"DEC1 MUX", "DMIC2", "DMIC2"}, @@ -664,8 +694,8 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = { {"DMIC1", NULL, "DMIC_CLK"}, {"DMIC2", NULL, "DMIC_CLK"}, - {"I2S TX1", NULL, "DEC1 MUX"}, - {"I2S TX2", NULL, "DEC2 MUX"}, + {"I2S TX1", NULL, "CIC1 MUX"}, + {"I2S TX2", NULL, "CIC2 MUX"}, {"I2S TX1", NULL, "TX_I2S_CLK"}, {"I2S TX2", NULL, "TX_I2S_CLK"}, @@ -788,7 +818,7 @@ static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream, LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0); } -static struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = { +static const struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = { .startup = msm8916_wcd_digital_startup, .shutdown = msm8916_wcd_digital_shutdown, .hw_params = msm8916_wcd_digital_hw_params, @@ -821,8 +851,9 @@ static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = { }, }; -static struct snd_soc_codec_driver msm8916_wcd_digital = { +static const struct snd_soc_codec_driver msm8916_wcd_digital = { .probe = msm8916_wcd_digital_codec_probe, + .set_sysclk = msm8916_wcd_digital_codec_set_sysclk, .component_driver = { .controls = msm8916_wcd_digital_snd_controls, .num_controls = ARRAY_SIZE(msm8916_wcd_digital_snd_controls), diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index c8bcb1db966de689d2e95413e6c618e7e6b8ad0e..f9c9933acffb60ee50c9c7ec062e3cc278bedf60 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -735,7 +735,7 @@ static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver nau8540_codec_driver = { +static const struct snd_soc_codec_driver nau8540_codec_driver = { .set_sysclk = nau8540_set_sysclk, .set_pll = nau8540_set_pll, .suspend = nau8540_suspend, diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index e45518629968b53ab01a044459a237f0ef1eb29f..c8e2451ae0a3700a52d111afaebb7482e53957d9 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -808,7 +808,7 @@ static const struct regmap_config nau8810_regmap_config = { .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults), }; -static struct snd_soc_codec_driver nau8810_codec_driver = { +static const struct snd_soc_codec_driver nau8810_codec_driver = { .set_bias_level = nau8810_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 3a309b18035e7ab29f5762e8d8331be388ae187e..0240759f951c7ea22b06004aa0e26320bba224fa 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -1469,7 +1469,7 @@ static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver nau8824_codec_driver = { +static const struct snd_soc_codec_driver nau8824_codec_driver = { .probe = nau8824_codec_probe, .set_sysclk = nau8824_set_sysclk, .set_pll = nau8824_set_pll, diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 46a30eaa7ace095a39e011790e992bcb1a3f87c9..714ce17da717c0edbc8817aa482dc1f2ec6fbcbe 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -260,11 +260,11 @@ static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) if (timeout) { ret = down_timeout(&nau8825->xtalk_sem, timeout); if (ret < 0) - dev_warn(nau8825->dev, "Acquire semaphone timeout\n"); + dev_warn(nau8825->dev, "Acquire semaphore timeout\n"); } else { ret = down_interruptible(&nau8825->xtalk_sem); if (ret < 0) - dev_warn(nau8825->dev, "Acquire semaphone fail\n"); + dev_warn(nau8825->dev, "Acquire semaphore fail\n"); } return ret; @@ -1299,7 +1299,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, NAU8825_I2S_DL_MASK, val_len); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); return 0; @@ -1361,7 +1361,7 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, NAU8825_I2S_MS_MASK, ctrl2_val); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); return 0; @@ -2140,7 +2140,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_MCLK: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2150,7 +2150,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, /* MCLK not changed by clock tree */ regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER, NAU8825_CLK_MCLK_SRC_MASK, 0); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); ret = nau8825_mclk_prepare(nau8825, freq); @@ -2188,7 +2188,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_FLL_MCLK: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2201,7 +2201,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, regmap_update_bits(regmap, NAU8825_REG_FLL3, NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK, NAU8825_FLL_CLK_SRC_MCLK | 0); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); ret = nau8825_mclk_prepare(nau8825, freq); @@ -2210,7 +2210,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_FLL_BLK: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2226,7 +2226,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK, NAU8825_FLL_CLK_SRC_BLK | (0xf << NAU8825_GAIN_ERR_SFT)); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); if (nau8825->mclk_freq) { @@ -2236,7 +2236,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_FLL_FS: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2252,7 +2252,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK, NAU8825_FLL_CLK_SRC_FS | (0xf << NAU8825_GAIN_ERR_SFT)); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); if (nau8825->mclk_freq) { @@ -2388,7 +2388,7 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver nau8825_codec_driver = { +static const struct snd_soc_codec_driver nau8825_codec_driver = { .probe = nau8825_codec_probe, .remove = nau8825_codec_remove, .set_sysclk = nau8825_set_sysclk, @@ -2563,7 +2563,7 @@ static int nau8825_i2c_probe(struct i2c_client *i2c, return PTR_ERR(nau8825->regmap); nau8825->dev = dev; nau8825->irq = i2c->irq; - /* Initiate parameters, semaphone and work queue which are needed in + /* Initiate parameters, semaphore and work queue which are needed in * cross talk suppression measurment function. */ nau8825->xtalk_state = NAU8825_XTALK_DONE; diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 0b14efab6280dd88b7a72c7df84fb3625a15f650..c7e28dd2e8153bc359494bdd9cb87728dcb1d0a0 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -288,7 +288,7 @@ static const struct regmap_config pcm1681_regmap = { .readable_reg = pcm1681_accessible_reg, }; -static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { +static const struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { .component_driver = { .controls = pcm1681_controls, .num_controls = ARRAY_SIZE(pcm1681_controls), diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index b813a154ddd97e1c31f79e815a938db0538531e3..82a3d9db32cb87b84b78cb07d40b3a34a636a59e 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -205,7 +205,7 @@ const struct regmap_config pcm179x_regmap_config = { }; EXPORT_SYMBOL_GPL(pcm179x_regmap_config); -static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { +static const struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .component_driver = { .controls = pcm179x_controls, .num_controls = ARRAY_SIZE(pcm179x_controls), diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 708af05486f634012da081f78421b676b21d1f7c..e59d8ffb93bd65a2a6319aa3c24e7dc4d603a708 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -98,7 +98,7 @@ static struct snd_soc_dai_driver pcm3008_dai = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { +static const struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { .component_driver = { .dapm_widgets = pcm3008_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 72b19e62f6267698aea45d2410d616d91c1825cb..68feae262476492ae3a0b30855dbb09e96fa187e 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -30,9 +30,6 @@ #include "pcm512x.h" -#define DIV_ROUND_DOWN_ULL(ll, d) \ - ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) - #define PCM512x_NUM_SUPPLIES 3 static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { "AVDD", @@ -1344,7 +1341,7 @@ static struct snd_soc_dai_driver pcm512x_dai = { .ops = &pcm512x_dai_ops, }; -static struct snd_soc_codec_driver pcm512x_codec_driver = { +static const struct snd_soc_codec_driver pcm512x_codec_driver = { .set_bias_level = pcm512x_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c new file mode 100644 index 0000000000000000000000000000000000000000..8f92e5c4dd9d7b34dc2b9e0ff34ec9d045f9f5d9 --- /dev/null +++ b/sound/soc/codecs/rt274.c @@ -0,0 +1,1229 @@ +/* + * rt274.c -- RT274 ALSA SoC audio codec driver + * + * Copyright 2017 Realtek Semiconductor Corp. + * Author: Bard Liao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rl6347a.h" +#include "rt274.h" + +#define RT274_VENDOR_ID 0x10ec0274 + +struct rt274_priv { + struct reg_default *index_cache; + int index_cache_size; + struct regmap *regmap; + struct snd_soc_codec *codec; + struct i2c_client *i2c; + struct snd_soc_jack *jack; + struct delayed_work jack_detect_work; + int sys_clk; + int clk_id; + int fs; + bool master; +}; + +static const struct reg_default rt274_index_def[] = { + { 0x00, 0x1004 }, + { 0x01, 0xaaaa }, + { 0x02, 0x88aa }, + { 0x03, 0x0002 }, + { 0x04, 0xaa09 }, + { 0x05, 0x0700 }, + { 0x06, 0x6110 }, + { 0x07, 0x0200 }, + { 0x08, 0xa807 }, + { 0x09, 0x0021 }, + { 0x0a, 0x7770 }, + { 0x0b, 0x7770 }, + { 0x0c, 0x002b }, + { 0x0d, 0x2420 }, + { 0x0e, 0x65c0 }, + { 0x0f, 0x7770 }, + { 0x10, 0x0420 }, + { 0x11, 0x7418 }, + { 0x12, 0x6bd0 }, + { 0x13, 0x645f }, + { 0x14, 0x0400 }, + { 0x15, 0x8ccc }, + { 0x16, 0x4c50 }, + { 0x17, 0xff00 }, + { 0x18, 0x0003 }, + { 0x19, 0x2c11 }, + { 0x1a, 0x830b }, + { 0x1b, 0x4e4b }, + { 0x1c, 0x0000 }, + { 0x1d, 0x0000 }, + { 0x1e, 0x0000 }, + { 0x1f, 0x0000 }, + { 0x20, 0x51ff }, + { 0x21, 0x8000 }, + { 0x22, 0x8f00 }, + { 0x23, 0x88f4 }, + { 0x24, 0x0000 }, + { 0x25, 0x0000 }, + { 0x26, 0x0000 }, + { 0x27, 0x0000 }, + { 0x28, 0x0000 }, + { 0x29, 0x3000 }, + { 0x2a, 0x0000 }, + { 0x2b, 0x0000 }, + { 0x2c, 0x0f00 }, + { 0x2d, 0x100f }, + { 0x2e, 0x2902 }, + { 0x2f, 0xe280 }, + { 0x30, 0x1000 }, + { 0x31, 0x8400 }, + { 0x32, 0x5aaa }, + { 0x33, 0x8420 }, + { 0x34, 0xa20c }, + { 0x35, 0x096a }, + { 0x36, 0x5757 }, + { 0x37, 0xfe05 }, + { 0x38, 0x4901 }, + { 0x39, 0x110a }, + { 0x3a, 0x0010 }, + { 0x3b, 0x60d9 }, + { 0x3c, 0xf214 }, + { 0x3d, 0xc2ba }, + { 0x3e, 0xa928 }, + { 0x3f, 0x0000 }, + { 0x40, 0x9800 }, + { 0x41, 0x0000 }, + { 0x42, 0x2000 }, + { 0x43, 0x3d90 }, + { 0x44, 0x4900 }, + { 0x45, 0x5289 }, + { 0x46, 0x0004 }, + { 0x47, 0xa47a }, + { 0x48, 0xd049 }, + { 0x49, 0x0049 }, + { 0x4a, 0xa83b }, + { 0x4b, 0x0777 }, + { 0x4c, 0x065c }, + { 0x4d, 0x7fff }, + { 0x4e, 0x7fff }, + { 0x4f, 0x0000 }, + { 0x50, 0x0000 }, + { 0x51, 0x0000 }, + { 0x52, 0xbf5f }, + { 0x53, 0x3320 }, + { 0x54, 0xcc00 }, + { 0x55, 0x0000 }, + { 0x56, 0x3f00 }, + { 0x57, 0x0000 }, + { 0x58, 0x0000 }, + { 0x59, 0x0000 }, + { 0x5a, 0x1300 }, + { 0x5b, 0x005f }, + { 0x5c, 0x0000 }, + { 0x5d, 0x1001 }, + { 0x5e, 0x1000 }, + { 0x5f, 0x0000 }, + { 0x60, 0x5554 }, + { 0x61, 0xffc0 }, + { 0x62, 0xa000 }, + { 0x63, 0xd010 }, + { 0x64, 0x0000 }, + { 0x65, 0x3fb1 }, + { 0x66, 0x1881 }, + { 0x67, 0xc810 }, + { 0x68, 0x2000 }, + { 0x69, 0xfff0 }, + { 0x6a, 0x0300 }, + { 0x6b, 0x5060 }, + { 0x6c, 0x0000 }, + { 0x6d, 0x0000 }, + { 0x6e, 0x0c25 }, + { 0x6f, 0x0c0b }, + { 0x70, 0x8000 }, + { 0x71, 0x4008 }, + { 0x72, 0x0000 }, + { 0x73, 0x0800 }, + { 0x74, 0xa28f }, + { 0x75, 0xa050 }, + { 0x76, 0x7fe8 }, + { 0x77, 0xdb8c }, + { 0x78, 0x0000 }, + { 0x79, 0x0000 }, + { 0x7a, 0x2a96 }, + { 0x7b, 0x800f }, + { 0x7c, 0x0200 }, + { 0x7d, 0x1600 }, + { 0x7e, 0x0000 }, + { 0x7f, 0x0000 }, +}; +#define INDEX_CACHE_SIZE ARRAY_SIZE(rt274_index_def) + +static const struct reg_default rt274_reg[] = { + { 0x00170500, 0x00000400 }, + { 0x00220000, 0x00000031 }, + { 0x00239000, 0x00000057 }, + { 0x0023a000, 0x00000057 }, + { 0x00270500, 0x00000400 }, + { 0x00370500, 0x00000400 }, + { 0x00870500, 0x00000400 }, + { 0x00920000, 0x00000031 }, + { 0x00935000, 0x00000097 }, + { 0x00936000, 0x00000097 }, + { 0x00970500, 0x00000400 }, + { 0x00b37000, 0x00000400 }, + { 0x00b37200, 0x00000400 }, + { 0x00b37300, 0x00000400 }, + { 0x00c37000, 0x00000400 }, + { 0x00c37100, 0x00000400 }, + { 0x01270500, 0x00000400 }, + { 0x01370500, 0x00000400 }, + { 0x01371f00, 0x411111f0 }, + { 0x01937000, 0x00000000 }, + { 0x01970500, 0x00000400 }, + { 0x02050000, 0x0000001b }, + { 0x02139000, 0x00000080 }, + { 0x0213a000, 0x00000080 }, + { 0x02170100, 0x00000001 }, + { 0x02170500, 0x00000400 }, + { 0x02170700, 0x00000000 }, + { 0x02270100, 0x00000000 }, + { 0x02370100, 0x00000000 }, + { 0x01970700, 0x00000020 }, + { 0x00830000, 0x00000097 }, + { 0x00930000, 0x00000097 }, + { 0x01270700, 0x00000000 }, +}; + +static bool rt274_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0 ... 0xff: + case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): + case RT274_GET_HP_SENSE: + case RT274_GET_MIC_SENSE: + case RT274_PROC_COEF: + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0): + return true; + default: + return false; + } + + +} + +static bool rt274_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0 ... 0xff: + case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): + case RT274_GET_HP_SENSE: + case RT274_GET_MIC_SENSE: + case RT274_SET_AUDIO_POWER: + case RT274_SET_HPO_POWER: + case RT274_SET_DMIC1_POWER: + case RT274_LOUT_MUX: + case RT274_HPO_MUX: + case RT274_ADC0_MUX: + case RT274_ADC1_MUX: + case RT274_SET_MIC: + case RT274_SET_PIN_HPO: + case RT274_SET_PIN_LOUT3: + case RT274_SET_PIN_DMIC1: + case RT274_SET_AMP_GAIN_HPO: + case RT274_SET_DMIC2_DEFAULT: + case RT274_DAC0L_GAIN: + case RT274_DAC0R_GAIN: + case RT274_DAC1L_GAIN: + case RT274_DAC1R_GAIN: + case RT274_ADCL_GAIN: + case RT274_ADCR_GAIN: + case RT274_MIC_GAIN: + case RT274_HPOL_GAIN: + case RT274_HPOR_GAIN: + case RT274_LOUTL_GAIN: + case RT274_LOUTR_GAIN: + case RT274_DAC_FORMAT: + case RT274_ADC_FORMAT: + case RT274_COEF_INDEX: + case RT274_PROC_COEF: + case RT274_SET_AMP_GAIN_ADC_IN1: + case RT274_SET_AMP_GAIN_ADC_IN2: + case RT274_SET_POWER(RT274_DAC_OUT0): + case RT274_SET_POWER(RT274_DAC_OUT1): + case RT274_SET_POWER(RT274_ADC_IN1): + case RT274_SET_POWER(RT274_ADC_IN2): + case RT274_SET_POWER(RT274_DMIC2): + case RT274_SET_POWER(RT274_MIC): + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0): + return true; + default: + return false; + } +} + +#ifdef CONFIG_PM +static void rt274_index_sync(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < INDEX_CACHE_SIZE; i++) { + snd_soc_write(codec, rt274->index_cache[i].reg, + rt274->index_cache[i].def); + } +} +#endif + +static int rt274_jack_detect(struct rt274_priv *rt274, bool *hp, bool *mic) +{ + unsigned int buf; + + *hp = false; + *mic = false; + + if (!rt274->codec) + return -EINVAL; + + regmap_read(rt274->regmap, RT274_GET_HP_SENSE, &buf); + *hp = buf & 0x80000000; + regmap_read(rt274->regmap, RT274_GET_MIC_SENSE, &buf); + *mic = buf & 0x80000000; + + pr_debug("*hp = %d *mic = %d\n", *hp, *mic); + + return 0; +} + +static void rt274_jack_detect_work(struct work_struct *work) +{ + struct rt274_priv *rt274 = + container_of(work, struct rt274_priv, jack_detect_work.work); + int status = 0; + bool hp = false; + bool mic = false; + + if (rt274_jack_detect(rt274, &hp, &mic) < 0) + return; + + if (hp == true) + status |= SND_JACK_HEADPHONE; + + if (mic == true) + status |= SND_JACK_MICROPHONE; + + snd_soc_jack_report(rt274->jack, status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); +} + +static irqreturn_t rt274_irq(int irq, void *data); + +static int rt274_mic_detect(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, void *data) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + if (jack == NULL) { + /* Disable jack detection */ + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_IRQ_EN, RT274_IRQ_DIS); + + return 0; + } + rt274->jack = jack; + + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_IRQ_EN, RT274_IRQ_EN); + + /* Send an initial report */ + rt274_irq(0, rt274); + + return 0; +} + +static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); +static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); + +static const struct snd_kcontrol_new rt274_snd_controls[] = { + SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT274_DAC0L_GAIN, + RT274_DAC0R_GAIN, 0, 0x7f, 0, out_vol_tlv), + SOC_DOUBLE_R_TLV("DAC1 Playback Volume", RT274_DAC1L_GAIN, + RT274_DAC1R_GAIN, 0, 0x7f, 0, out_vol_tlv), + SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT274_ADCL_GAIN, + RT274_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), + SOC_DOUBLE_R("ADC0 Capture Switch", RT274_ADCL_GAIN, + RT274_ADCR_GAIN, RT274_MUTE_SFT, 1, 1), + SOC_SINGLE_TLV("AMIC Volume", RT274_MIC_GAIN, + 0, 0x3, 0, mic_vol_tlv), +}; + +static const struct snd_kcontrol_new hpol_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOL_GAIN, + RT274_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new hpor_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOR_GAIN, + RT274_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new loutl_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTL_GAIN, + RT274_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new loutr_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTR_GAIN, + RT274_MUTE_SFT, 1, 1); + +/* ADC0 source */ +static const char * const rt274_adc_src[] = { + "Mic", "Line1", "Line2", "Dmic" +}; + +static SOC_ENUM_SINGLE_DECL( + rt274_adc0_enum, RT274_ADC0_MUX, RT274_ADC_SEL_SFT, + rt274_adc_src); + +static const struct snd_kcontrol_new rt274_adc0_mux = + SOC_DAPM_ENUM("ADC 0 source", rt274_adc0_enum); + +static SOC_ENUM_SINGLE_DECL( + rt274_adc1_enum, RT274_ADC1_MUX, RT274_ADC_SEL_SFT, + rt274_adc_src); + +static const struct snd_kcontrol_new rt274_adc1_mux = + SOC_DAPM_ENUM("ADC 1 source", rt274_adc1_enum); + +static const char * const rt274_dac_src[] = { + "DAC OUT0", "DAC OUT1" +}; +/* HP-OUT source */ +static SOC_ENUM_SINGLE_DECL(rt274_hpo_enum, RT274_HPO_MUX, + 0, rt274_dac_src); + +static const struct snd_kcontrol_new rt274_hpo_mux = +SOC_DAPM_ENUM("HPO source", rt274_hpo_enum); + +/* Line out source */ +static SOC_ENUM_SINGLE_DECL(rt274_lout_enum, RT274_LOUT_MUX, + 0, rt274_dac_src); + +static const struct snd_kcontrol_new rt274_lout_mux = +SOC_DAPM_ENUM("LOUT source", rt274_lout_enum); + +static const struct snd_soc_dapm_widget rt274_dapm_widgets[] = { + /* Input Lines */ + SND_SOC_DAPM_INPUT("DMIC1 Pin"), + SND_SOC_DAPM_INPUT("DMIC2 Pin"), + SND_SOC_DAPM_INPUT("MIC"), + SND_SOC_DAPM_INPUT("LINE1"), + SND_SOC_DAPM_INPUT("LINE2"), + + /* DMIC */ + SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* ADCs */ + SND_SOC_DAPM_ADC("ADC 0", NULL, RT274_SET_STREAMID_ADC1, 4, 0), + SND_SOC_DAPM_ADC("ADC 1", NULL, RT274_SET_STREAMID_ADC2, 4, 0), + + /* ADC Mux */ + SND_SOC_DAPM_MUX("ADC 0 Mux", SND_SOC_NOPM, 0, 0, + &rt274_adc0_mux), + SND_SOC_DAPM_MUX("ADC 1 Mux", SND_SOC_NOPM, 0, 0, + &rt274_adc1_mux), + + /* Audio Interface */ + SND_SOC_DAPM_AIF_IN("AIF1RXL", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF1RXR", "AIF1 Playback", 1, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1TXL", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1TXR", "AIF1 Capture", 1, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF2RXL", "AIF1 Playback", 2, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF2RXR", "AIF1 Playback", 3, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF2TXL", "AIF1 Capture", 2, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF2TXR", "AIF1 Capture", 3, SND_SOC_NOPM, 0, 0), + + /* Output Side */ + /* DACs */ + SND_SOC_DAPM_DAC("DAC 0", NULL, RT274_SET_STREAMID_DAC0, 4, 0), + SND_SOC_DAPM_DAC("DAC 1", NULL, RT274_SET_STREAMID_DAC1, 4, 0), + + /* Output Mux */ + SND_SOC_DAPM_MUX("HPO Mux", SND_SOC_NOPM, 0, 0, &rt274_hpo_mux), + SND_SOC_DAPM_MUX("LOUT Mux", SND_SOC_NOPM, 0, 0, &rt274_lout_mux), + + SND_SOC_DAPM_SUPPLY("HP Power", RT274_SET_PIN_HPO, + RT274_SET_PIN_SFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("LOUT Power", RT274_SET_PIN_LOUT3, + RT274_SET_PIN_SFT, 0, NULL, 0), + + /* Output Mixer */ + SND_SOC_DAPM_PGA("DAC OUT0", SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_PGA("DAC OUT1", SND_SOC_NOPM, 0, 0, + NULL, 0), + + /* Output Pga */ + SND_SOC_DAPM_SWITCH("LOUT L", SND_SOC_NOPM, 0, 0, + &loutl_enable_control), + SND_SOC_DAPM_SWITCH("LOUT R", SND_SOC_NOPM, 0, 0, + &loutr_enable_control), + SND_SOC_DAPM_SWITCH("HPO L", SND_SOC_NOPM, 0, 0, + &hpol_enable_control), + SND_SOC_DAPM_SWITCH("HPO R", SND_SOC_NOPM, 0, 0, + &hpor_enable_control), + + /* Output Lines */ + SND_SOC_DAPM_OUTPUT("HPO Pin"), + SND_SOC_DAPM_OUTPUT("SPDIF"), + SND_SOC_DAPM_OUTPUT("LINE3"), +}; + +static const struct snd_soc_dapm_route rt274_dapm_routes[] = { + {"DMIC1", NULL, "DMIC1 Pin"}, + {"DMIC2", NULL, "DMIC2 Pin"}, + + {"ADC 0 Mux", "Mic", "MIC"}, + {"ADC 0 Mux", "Dmic", "DMIC1"}, + {"ADC 0 Mux", "Line1", "LINE1"}, + {"ADC 0 Mux", "Line2", "LINE2"}, + {"ADC 1 Mux", "Mic", "MIC"}, + {"ADC 1 Mux", "Dmic", "DMIC2"}, + {"ADC 1 Mux", "Line1", "LINE1"}, + {"ADC 1 Mux", "Line2", "LINE2"}, + + {"ADC 0", NULL, "ADC 0 Mux"}, + {"ADC 1", NULL, "ADC 1 Mux"}, + + {"AIF1TXL", NULL, "ADC 0"}, + {"AIF1TXR", NULL, "ADC 0"}, + {"AIF2TXL", NULL, "ADC 1"}, + {"AIF2TXR", NULL, "ADC 1"}, + + {"DAC 0", NULL, "AIF1RXL"}, + {"DAC 0", NULL, "AIF1RXR"}, + {"DAC 1", NULL, "AIF2RXL"}, + {"DAC 1", NULL, "AIF2RXR"}, + + {"DAC OUT0", NULL, "DAC 0"}, + + {"DAC OUT1", NULL, "DAC 1"}, + + {"LOUT Mux", "DAC OUT0", "DAC OUT0"}, + {"LOUT Mux", "DAC OUT1", "DAC OUT1"}, + + {"LOUT L", "Switch", "LOUT Mux"}, + {"LOUT R", "Switch", "LOUT Mux"}, + {"LOUT L", NULL, "LOUT Power"}, + {"LOUT R", NULL, "LOUT Power"}, + + {"LINE3", NULL, "LOUT L"}, + {"LINE3", NULL, "LOUT R"}, + + {"HPO Mux", "DAC OUT0", "DAC OUT0"}, + {"HPO Mux", "DAC OUT1", "DAC OUT1"}, + + {"HPO L", "Switch", "HPO Mux"}, + {"HPO R", "Switch", "HPO Mux"}, + {"HPO L", NULL, "HP Power"}, + {"HPO R", NULL, "HP Power"}, + + {"HPO Pin", NULL, "HPO L"}, + {"HPO Pin", NULL, "HPO R"}, +}; + +static int rt274_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + unsigned int val = 0; + int d_len_code = 0, c_len_code = 0; + + switch (params_rate(params)) { + /* bit 14 0:48K 1:44.1K */ + case 44100: + case 48000: + break; + default: + dev_err(codec->dev, "Unsupported sample rate %d\n", + params_rate(params)); + return -EINVAL; + } + switch (rt274->sys_clk) { + case 12288000: + case 24576000: + if (params_rate(params) != 48000) { + dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n", + params_rate(params), rt274->sys_clk); + return -EINVAL; + } + break; + case 11289600: + case 22579200: + if (params_rate(params) != 44100) { + dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n", + params_rate(params), rt274->sys_clk); + return -EINVAL; + } + break; + } + + if (params_channels(params) <= 16) { + /* bit 3:0 Number of Channel */ + val |= (params_channels(params) - 1); + } else { + dev_err(codec->dev, "Unsupported channels %d\n", + params_channels(params)); + return -EINVAL; + } + + switch (params_width(params)) { + /* bit 6:4 Bits per Sample */ + case 16: + d_len_code = 0; + c_len_code = 0; + val |= (0x1 << 4); + break; + case 32: + d_len_code = 2; + c_len_code = 3; + val |= (0x4 << 4); + break; + case 20: + d_len_code = 1; + c_len_code = 1; + val |= (0x2 << 4); + break; + case 24: + d_len_code = 2; + c_len_code = 2; + val |= (0x3 << 4); + break; + case 8: + d_len_code = 3; + c_len_code = 0; + break; + default: + return -EINVAL; + } + + if (rt274->master) + c_len_code = 0x3; + + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, 0xc018, d_len_code << 3 | c_len_code << 14); + dev_dbg(codec->dev, "format val = 0x%x\n", val); + + snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x407f, val); + snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x407f, val); + + return 0; +} + +static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M); + rt274->master = true; + break; + case SND_SOC_DAIFMT_CBS_CFS: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S); + rt274->master = false; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_I2S); + break; + case SND_SOC_DAIFMT_LEFT_J: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_LJ); + break; + case SND_SOC_DAIFMT_DSP_A: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMA); + break; + case SND_SOC_DAIFMT_DSP_B: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMB); + break; + default: + return -EINVAL; + } + /* bit 15 Stream Type 0:PCM 1:Non-PCM */ + snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x8000, 0); + snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x8000, 0); + + return 0; +} + +static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, + unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + switch (source) { + case RT274_PLL2_S_MCLK: + snd_soc_update_bits(codec, RT274_PLL2_CTRL, + RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_MCLK); + break; + default: + dev_warn(codec->dev, "invalid pll source, use BCLK\n"); + case RT274_PLL2_S_BCLK: + snd_soc_update_bits(codec, RT274_PLL2_CTRL, + RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK); + break; + } + + if (source == RT274_PLL2_S_BCLK) { + snd_soc_update_bits(codec, RT274_MCLK_CTRL, + (0x3 << 12), (0x3 << 12)); + switch (rt274->fs) { + case 50: + snd_soc_write(codec, 0x7a, 0xaab6); + snd_soc_write(codec, 0x7b, 0x0301); + snd_soc_write(codec, 0x7c, 0x04fe); + break; + case 64: + snd_soc_write(codec, 0x7a, 0xaa96); + snd_soc_write(codec, 0x7b, 0x8003); + snd_soc_write(codec, 0x7c, 0x081e); + break; + case 128: + snd_soc_write(codec, 0x7a, 0xaa96); + snd_soc_write(codec, 0x7b, 0x8003); + snd_soc_write(codec, 0x7c, 0x080e); + break; + default: + dev_warn(codec->dev, "invalid freq_in, assume 4.8M\n"); + case 100: + snd_soc_write(codec, 0x7a, 0xaab6); + snd_soc_write(codec, 0x7b, 0x0301); + snd_soc_write(codec, 0x7c, 0x047e); + break; + } + } + + return 0; +} + +static int rt274_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + unsigned int clk_src, mclk_en; + + dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq); + + switch (clk_id) { + case RT274_SCLK_S_MCLK: + mclk_en = RT274_MCLK_MODE_EN; + clk_src = RT274_CLK_SRC_MCLK; + break; + case RT274_SCLK_S_PLL1: + mclk_en = RT274_MCLK_MODE_DIS; + clk_src = RT274_CLK_SRC_MCLK; + break; + case RT274_SCLK_S_PLL2: + mclk_en = RT274_MCLK_MODE_EN; + clk_src = RT274_CLK_SRC_PLL2; + break; + default: + mclk_en = RT274_MCLK_MODE_DIS; + clk_src = RT274_CLK_SRC_MCLK; + dev_warn(codec->dev, "invalid sysclk source, use PLL1\n"); + break; + } + snd_soc_update_bits(codec, RT274_MCLK_CTRL, + RT274_MCLK_MODE_MASK, mclk_en); + snd_soc_update_bits(codec, RT274_CLK_CTRL, + RT274_CLK_SRC_MASK, clk_src); + + switch (freq) { + case 19200000: + if (clk_id == RT274_SCLK_S_MCLK) { + dev_err(codec->dev, "Should not use MCLK\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, + RT274_I2S_CTRL2, 0x40, 0x40); + break; + case 24000000: + if (clk_id == RT274_SCLK_S_MCLK) { + dev_err(codec->dev, "Should not use MCLK\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, + RT274_I2S_CTRL2, 0x40, 0x0); + break; + case 12288000: + case 11289600: + snd_soc_update_bits(codec, + RT274_MCLK_CTRL, 0x1fcf, 0x0008); + break; + case 24576000: + case 22579200: + snd_soc_update_bits(codec, + RT274_MCLK_CTRL, 0x1fcf, 0x1543); + break; + default: + dev_err(codec->dev, "Unsupported system clock\n"); + return -EINVAL; + } + + rt274->sys_clk = freq; + rt274->clk_id = clk_id; + + return 0; +} + +static int rt274_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio); + rt274->fs = ratio; + if ((ratio / 50) == 0) + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, 0x1000, 0x1000); + else + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, 0x1000, 0x0); + + + return 0; +} + +static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, int slot_width) + +{ + struct snd_soc_codec *codec = dai->codec; + + if (rx_mask || tx_mask) { + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_EN); + } else { + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_DIS); + return 0; + } + + switch (slots) { + case 4: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_4CH); + break; + case 2: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_2CH); + break; + default: + dev_err(codec->dev, + "Support 2 or 4 slots TDM only\n"); + return -EINVAL; + } + + return 0; +} + +static int rt274_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_PREPARE: + if (SND_SOC_BIAS_STANDBY == + snd_soc_codec_get_bias_level(codec)) { + snd_soc_write(codec, + RT274_SET_AUDIO_POWER, AC_PWRST_D0); + } + break; + + case SND_SOC_BIAS_STANDBY: + snd_soc_write(codec, + RT274_SET_AUDIO_POWER, AC_PWRST_D3); + break; + + default: + break; + } + + return 0; +} + +static irqreturn_t rt274_irq(int irq, void *data) +{ + struct rt274_priv *rt274 = data; + bool hp = false; + bool mic = false; + int ret, status = 0; + + /* Clear IRQ */ + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_IRQ_CLR, RT274_IRQ_CLR); + + ret = rt274_jack_detect(rt274, &hp, &mic); + + if (ret == 0) { + if (hp == true) + status |= SND_JACK_HEADPHONE; + + if (mic == true) + status |= SND_JACK_MICROPHONE; + + snd_soc_jack_report(rt274->jack, status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + + pm_wakeup_event(&rt274->i2c->dev, 300); + } + + return IRQ_HANDLED; +} + +static int rt274_probe(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + rt274->codec = codec; + + if (rt274->i2c->irq) { + INIT_DELAYED_WORK(&rt274->jack_detect_work, + rt274_jack_detect_work); + schedule_delayed_work(&rt274->jack_detect_work, + msecs_to_jiffies(1250)); + } + + return 0; +} + +static int rt274_remove(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + cancel_delayed_work_sync(&rt274->jack_detect_work); + + return 0; +} + +#ifdef CONFIG_PM +static int rt274_suspend(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + regcache_cache_only(rt274->regmap, true); + regcache_mark_dirty(rt274->regmap); + + return 0; +} + +static int rt274_resume(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + regcache_cache_only(rt274->regmap, false); + rt274_index_sync(codec); + regcache_sync(rt274->regmap); + + return 0; +} +#else +#define rt274_suspend NULL +#define rt274_resume NULL +#endif + +#define RT274_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) +#define RT274_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) + +static const struct snd_soc_dai_ops rt274_aif_dai_ops = { + .hw_params = rt274_hw_params, + .set_fmt = rt274_set_dai_fmt, + .set_sysclk = rt274_set_dai_sysclk, + .set_pll = rt274_set_dai_pll, + .set_bclk_ratio = rt274_set_bclk_ratio, + .set_tdm_slot = rt274_set_tdm_slot, +}; + +static struct snd_soc_dai_driver rt274_dai[] = { + { + .name = "rt274-aif1", + .id = RT274_AIF1, + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = RT274_STEREO_RATES, + .formats = RT274_FORMATS, + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = RT274_STEREO_RATES, + .formats = RT274_FORMATS, + }, + .ops = &rt274_aif_dai_ops, + .symmetric_rates = 1, + }, +}; + +static const struct snd_soc_codec_driver soc_codec_dev_rt274 = { + .probe = rt274_probe, + .remove = rt274_remove, + .suspend = rt274_suspend, + .resume = rt274_resume, + .set_bias_level = rt274_set_bias_level, + .idle_bias_off = true, + .component_driver = { + .controls = rt274_snd_controls, + .num_controls = ARRAY_SIZE(rt274_snd_controls), + .dapm_widgets = rt274_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rt274_dapm_widgets), + .dapm_routes = rt274_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(rt274_dapm_routes), + }, + .set_jack = rt274_mic_detect, +}; + +static const struct regmap_config rt274_regmap = { + .reg_bits = 32, + .val_bits = 32, + .max_register = 0x05bfffff, + .volatile_reg = rt274_volatile_register, + .readable_reg = rt274_readable_register, + .reg_write = rl6347a_hw_write, + .reg_read = rl6347a_hw_read, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = rt274_reg, + .num_reg_defaults = ARRAY_SIZE(rt274_reg), +}; + +#ifdef CONFIG_OF +static const struct of_device_id rt274_of_match[] = { + {.compatible = "realtek,rt274"}, + {}, +}; +MODULE_DEVICE_TABLE(of, rt274_of_match); +#endif + +static const struct i2c_device_id rt274_i2c_id[] = { + {"rt274", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, rt274_i2c_id); + +static const struct acpi_device_id rt274_acpi_match[] = { + { "10EC0274", 0 }, + { "INT34C2", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, rt274_acpi_match); + +static int rt274_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct rt274_priv *rt274; + + int ret; + unsigned int val; + + rt274 = devm_kzalloc(&i2c->dev, sizeof(*rt274), + GFP_KERNEL); + if (rt274 == NULL) + return -ENOMEM; + + rt274->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt274_regmap); + if (IS_ERR(rt274->regmap)) { + ret = PTR_ERR(rt274->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + regmap_read(rt274->regmap, + RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val); + if (val != RT274_VENDOR_ID) { + dev_err(&i2c->dev, + "Device with ID register %#x is not rt274\n", val); + return -ENODEV; + } + + rt274->index_cache = devm_kmemdup(&i2c->dev, rt274_index_def, + sizeof(rt274_index_def), GFP_KERNEL); + if (!rt274->index_cache) + return -ENOMEM; + + rt274->index_cache_size = INDEX_CACHE_SIZE; + rt274->i2c = i2c; + i2c_set_clientdata(i2c, rt274); + + /* reset codec */ + regmap_write(rt274->regmap, RT274_RESET, 0); + regmap_update_bits(rt274->regmap, 0x1a, 0x4000, 0x4000); + + /* Set Pad PDB is floating */ + regmap_update_bits(rt274->regmap, RT274_PAD_CTRL12, 0x3, 0x0); + regmap_write(rt274->regmap, RT274_COEF5b_INDEX, 0x01); + regmap_write(rt274->regmap, RT274_COEF5b_COEF, 0x8540); + regmap_update_bits(rt274->regmap, 0x6f, 0x0100, 0x0100); + /* Combo jack auto detect */ + regmap_write(rt274->regmap, 0x4a, 0x201b); + /* Aux mode off */ + regmap_update_bits(rt274->regmap, 0x6f, 0x3000, 0x2000); + /* HP DC Calibration */ + regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0x0); + /* Set NID=58h.Index 00h [15]= 1b; */ + regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00); + regmap_write(rt274->regmap, RT274_COEF58_COEF, 0xb888); + msleep(500); + regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0xb); + regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00); + regmap_write(rt274->regmap, RT274_COEF58_COEF, 0x3888); + /* Set pin widget */ + regmap_write(rt274->regmap, RT274_SET_PIN_HPO, 0x40); + regmap_write(rt274->regmap, RT274_SET_PIN_LOUT3, 0x40); + regmap_write(rt274->regmap, RT274_SET_MIC, 0x20); + regmap_write(rt274->regmap, RT274_SET_PIN_DMIC1, 0x20); + + regmap_update_bits(rt274->regmap, RT274_I2S_CTRL2, 0xc004, 0x4004); + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_GPI2_SEL_MASK, RT274_GPI2_SEL_DMIC_CLK); + + /* jack detection */ + regmap_write(rt274->regmap, RT274_UNSOLICITED_HP_OUT, 0x81); + regmap_write(rt274->regmap, RT274_UNSOLICITED_MIC, 0x82); + + if (rt274->i2c->irq) { + ret = request_threaded_irq(rt274->i2c->irq, NULL, rt274_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt274", rt274); + if (ret != 0) { + dev_err(&i2c->dev, + "Failed to reguest IRQ: %d\n", ret); + return ret; + } + } + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt274, + rt274_dai, ARRAY_SIZE(rt274_dai)); + + return ret; +} + +static int rt274_i2c_remove(struct i2c_client *i2c) +{ + struct rt274_priv *rt274 = i2c_get_clientdata(i2c); + + if (i2c->irq) + free_irq(i2c->irq, rt274); + snd_soc_unregister_codec(&i2c->dev); + + return 0; +} + + +static struct i2c_driver rt274_i2c_driver = { + .driver = { + .name = "rt274", + .acpi_match_table = ACPI_PTR(rt274_acpi_match), +#ifdef CONFIG_OF + .of_match_table = of_match_ptr(rt274_of_match), +#endif + }, + .probe = rt274_i2c_probe, + .remove = rt274_i2c_remove, + .id_table = rt274_i2c_id, +}; + +module_i2c_driver(rt274_i2c_driver); + +MODULE_DESCRIPTION("ASoC RT274 driver"); +MODULE_AUTHOR("Bard Liao "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rt274.h b/sound/soc/codecs/rt274.h new file mode 100644 index 0000000000000000000000000000000000000000..4fd1bcb73dba92c7ecaf06aedac05547b1cfa2e3 --- /dev/null +++ b/sound/soc/codecs/rt274.h @@ -0,0 +1,217 @@ +/* + * rt274.h -- RT274 ALSA SoC audio driver + * + * Copyright 2016 Realtek Microelectronics + * Author: Bard Liao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __RT274_H__ +#define __RT274_H__ + +#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) + +#define RT274_AUDIO_FUNCTION_GROUP 0x01 +#define RT274_DAC_OUT0 0x02 +#define RT274_DAC_OUT1 0x03 +#define RT274_ADC_IN2 0x08 +#define RT274_ADC_IN1 0x09 +#define RT274_DIG_CVT 0x0a +#define RT274_DMIC1 0x12 +#define RT274_DMIC2 0x13 +#define RT274_MIC 0x19 +#define RT274_LINE1 0x1a +#define RT274_LINE2 0x1b +#define RT274_LINE3 0x16 +#define RT274_SPDIF 0x1e +#define RT274_VENDOR_REGISTERS 0x20 +#define RT274_HP_OUT 0x21 +#define RT274_MIXER_IN1 0x22 +#define RT274_MIXER_IN2 0x23 +#define RT274_INLINE_CMD 0x55 + +#define RT274_SET_PIN_SFT 6 +#define RT274_SET_PIN_ENABLE 0x40 +#define RT274_SET_PIN_DISABLE 0 +#define RT274_SET_EAPD_HIGH 0x2 +#define RT274_SET_EAPD_LOW 0 + +#define RT274_MUTE_SFT 7 + +/* Verb commands */ +#define RT274_RESET\ + VERB_CMD(AC_VERB_SET_CODEC_RESET, RT274_AUDIO_FUNCTION_GROUP, 0) +#define RT274_GET_PARAM(NID, PARAM) VERB_CMD(AC_VERB_PARAMETERS, NID, PARAM) +#define RT274_SET_POWER(NID) VERB_CMD(AC_VERB_SET_POWER_STATE, NID, 0) +#define RT274_SET_AUDIO_POWER RT274_SET_POWER(RT274_AUDIO_FUNCTION_GROUP) +#define RT274_SET_HPO_POWER RT274_SET_POWER(RT274_HP_OUT) +#define RT274_SET_DMIC1_POWER RT274_SET_POWER(RT274_DMIC1) +#define RT274_LOUT_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_LINE3, 0) +#define RT274_HPO_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_HP_OUT, 0) +#define RT274_ADC0_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_MIXER_IN1, 0) +#define RT274_ADC1_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_MIXER_IN2, 0) +#define RT274_SET_MIC\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_MIC, 0) +#define RT274_SET_PIN_LOUT3\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_LINE3, 0) +#define RT274_SET_PIN_HPO\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0) +#define RT274_SET_PIN_DMIC1\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0) +#define RT274_SET_PIN_SPDIF\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_SPDIF, 0) +#define RT274_SET_PIN_DIG_CVT\ + VERB_CMD(AC_VERB_SET_DIGI_CONVERT_1, RT274_DIG_CVT, 0) +#define RT274_SET_AMP_GAIN_HPO\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0) +#define RT274_SET_AMP_GAIN_ADC_IN1\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0) +#define RT274_SET_AMP_GAIN_ADC_IN2\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0) +#define RT274_GET_HP_SENSE\ + VERB_CMD(AC_VERB_GET_PIN_SENSE, RT274_HP_OUT, 0) +#define RT274_GET_MIC_SENSE\ + VERB_CMD(AC_VERB_GET_PIN_SENSE, RT274_MIC, 0) +#define RT274_SET_DMIC2_DEFAULT\ + VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT274_DMIC2, 0) +#define RT274_SET_SPDIF_DEFAULT\ + VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT274_SPDIF, 0) +#define RT274_DAC0L_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0xa000) +#define RT274_DAC0R_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0x9000) +#define RT274_DAC1L_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0xa000) +#define RT274_DAC1R_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0x9000) +#define RT274_ADCL_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0x6000) +#define RT274_ADCR_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0x5000) +#define RT274_MIC_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_MIC, 0x7000) +#define RT274_LOUTL_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_LINE3, 0xa000) +#define RT274_LOUTR_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_LINE3, 0x9000) +#define RT274_HPOL_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0xa000) +#define RT274_HPOR_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0x9000) +#define RT274_DAC_FORMAT\ + VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT274_DAC_OUT0, 0) +#define RT274_ADC_FORMAT\ + VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT274_ADC_IN1, 0) +#define RT274_COEF_INDEX\ + VERB_CMD(AC_VERB_SET_COEF_INDEX, RT274_VENDOR_REGISTERS, 0) +#define RT274_PROC_COEF\ + VERB_CMD(AC_VERB_SET_PROC_COEF, RT274_VENDOR_REGISTERS, 0) +#define RT274_UNSOLICITED_INLINE_CMD\ + VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_INLINE_CMD, 0) +#define RT274_UNSOLICITED_HP_OUT\ + VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_HP_OUT, 0) +#define RT274_UNSOLICITED_MIC\ + VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_MIC, 0) +#define RT274_COEF58_INDEX\ + VERB_CMD(AC_VERB_SET_COEF_INDEX, 0x58, 0) +#define RT274_COEF58_COEF\ + VERB_CMD(AC_VERB_SET_PROC_COEF, 0x58, 0) +#define RT274_COEF5b_INDEX\ + VERB_CMD(AC_VERB_SET_COEF_INDEX, 0x5b, 0) +#define RT274_COEF5b_COEF\ + VERB_CMD(AC_VERB_SET_PROC_COEF, 0x5b, 0) +#define RT274_SET_STREAMID_DAC0\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_DAC_OUT0, 0) +#define RT274_SET_STREAMID_DAC1\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_DAC_OUT1, 0) +#define RT274_SET_STREAMID_ADC1\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_ADC_IN1, 0) +#define RT274_SET_STREAMID_ADC2\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_ADC_IN2, 0) + +/* Index registers */ +#define RT274_EAPD_GPIO_IRQ_CTRL 0x10 +#define RT274_PAD_CTRL12 0x35 +#define RT274_I2S_CTRL1 0x63 +#define RT274_I2S_CTRL2 0x64 +#define RT274_MCLK_CTRL 0x71 +#define RT274_CLK_CTRL 0x72 +#define RT274_PLL2_CTRL 0x7b + + +/* EAPD GPIO IRQ control (Index 0x10) */ +#define RT274_IRQ_DIS (0x0 << 13) +#define RT274_IRQ_EN (0x1 << 13) +#define RT274_IRQ_CLR (0x1 << 12) +#define RT274_GPI2_SEL_MASK (0x3 << 7) +#define RT274_GPI2_SEL_GPIO2 (0x0 << 7) +#define RT274_GPI2_SEL_I2S (0x1 << 7) +#define RT274_GPI2_SEL_DMIC_CLK (0x2 << 7) +#define RT274_GPI2_SEL_CBJ (0x3 << 7) + +/* Front I2S_Interface control 1 (Index 0x63) */ +#define RT274_I2S_MODE_MASK (0x1 << 11) +#define RT274_I2S_MODE_S (0x0 << 11) +#define RT274_I2S_MODE_M (0x1 << 11) +#define RT274_TDM_DIS (0x0 << 10) +#define RT274_TDM_EN (0x1 << 10) +#define RT274_TDM_CH_NUM (0x1 << 7) +#define RT274_TDM_2CH (0x0 << 7) +#define RT274_TDM_4CH (0x1 << 7) +#define RT274_I2S_FMT_MASK (0x3 << 8) +#define RT274_I2S_FMT_I2S (0x0 << 8) +#define RT274_I2S_FMT_LJ (0x1 << 8) +#define RT274_I2S_FMT_PCMA (0x2 << 8) +#define RT274_I2S_FMT_PCMB (0x3 << 8) + +/* MCLK clock domain control (Index 0x71) */ +#define RT274_MCLK_MODE_MASK (0x1 << 14) +#define RT274_MCLK_MODE_DIS (0x0 << 14) +#define RT274_MCLK_MODE_EN (0x1 << 14) + +/* Clock control (Index 0x72) */ +#define RT274_CLK_SRC_MASK (0x7 << 3) +#define RT274_CLK_SRC_MCLK (0x0 << 3) +#define RT274_CLK_SRC_PLL2 (0x3 << 3) + +/* PLL2 control (Index 0x7b) */ +#define RT274_PLL2_SRC_MASK (0x1 << 13) +#define RT274_PLL2_SRC_MCLK (0x0 << 13) +#define RT274_PLL2_SRC_BCLK (0x1 << 13) + +/* HP-OUT (0x21) */ +#define RT274_M_HP_MUX_SFT 14 +#define RT274_HP_SEL_MASK 0x1 +#define RT274_HP_SEL_SFT 0 +#define RT274_HP_SEL_F 0 +#define RT274_HP_SEL_S 1 + +/* ADC (0x22) (0x23) */ +#define RT274_ADC_SEL_MASK 0x7 +#define RT274_ADC_SEL_SFT 0 +#define RT274_ADC_SEL_MIC 0 +#define RT274_ADC_SEL_LINE1 1 +#define RT274_ADC_SEL_LINE2 2 +#define RT274_ADC_SEL_DMIC 3 + +#define RT274_SCLK_S_MCLK 0 +#define RT274_SCLK_S_PLL1 1 +#define RT274_SCLK_S_PLL2 2 + +#define RT274_PLL2_S_MCLK 0 +#define RT274_PLL2_S_BCLK 1 + +enum { + RT274_AIF1, + RT274_AIFS, +}; + +#endif /* __RT274_H__ */ + diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 7899a2cdeb42f46c5d76cd051319a4b547b1ed04..af6325c78292d2e49eae9021887d437b9aac9e22 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1046,7 +1046,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { }; -static struct snd_soc_codec_driver soc_codec_dev_rt286 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt286 = { .probe = rt286_probe, .remove = rt286_remove, .suspend = rt286_suspend, diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index d9e96e65e1c43f95cebd224960da0bd53de5c27d..ce963768449f188a804ad86136650b5afd540024 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1113,7 +1113,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { }; -static struct snd_soc_codec_driver soc_codec_dev_rt298 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt298 = { .probe = rt298_probe, .remove = rt298_remove, .suspend = rt298_suspend, diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 7ed62e8c80b4bfe98093f9166e68683a051dccdf..ed6e5373916c390fb15dfc9efd943c9c55f7d819 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c @@ -43,9 +43,7 @@ struct rt5514_dsp { struct mutex dma_lock; struct snd_pcm_substream *substream; unsigned int buf_base, buf_limit, buf_rp; - size_t buf_size; - size_t dma_offset; - size_t dsp_offset; + size_t buf_size, get_size, dma_offset; }; static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = { @@ -80,6 +78,8 @@ static void rt5514_spi_copy_work(struct work_struct *work) container_of(work, struct rt5514_dsp, copy_work.work); struct snd_pcm_runtime *runtime; size_t period_bytes, truncated_bytes = 0; + unsigned int cur_wp, remain_data; + u8 buf[8]; mutex_lock(&rt5514_dsp->dma_lock); if (!rt5514_dsp->substream) { @@ -90,8 +90,24 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime = rt5514_dsp->substream->runtime; period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream); - if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes) - period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset; + if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) { + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + if (cur_wp >= rt5514_dsp->buf_rp) + remain_data = (cur_wp - rt5514_dsp->buf_rp); + else + remain_data = + (rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) + + (cur_wp - rt5514_dsp->buf_base); + + if (remain_data < period_bytes) { + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + goto done; + } + } if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) { rt5514_spi_burst_read(rt5514_dsp->buf_rp, @@ -112,24 +128,62 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime->dma_area + rt5514_dsp->dma_offset + truncated_bytes, period_bytes - truncated_bytes); - rt5514_dsp->buf_rp = rt5514_dsp->buf_base + - period_bytes - truncated_bytes; + rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes - + truncated_bytes; } + rt5514_dsp->get_size += period_bytes; rt5514_dsp->dma_offset += period_bytes; if (rt5514_dsp->dma_offset >= runtime->dma_bytes) rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset += period_bytes; - snd_pcm_period_elapsed(rt5514_dsp->substream); - if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 5); + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + done: mutex_unlock(&rt5514_dsp->dma_lock); } +static irqreturn_t rt5514_spi_irq(int irq, void *data) +{ + struct rt5514_dsp *rt5514_dsp = data; + u8 buf[8]; + + rt5514_dsp->get_size = 0; + + /** + * The address area x1800XXXX is the register address, and it cannot + * support spi burst read perfectly. So we use the spi burst read + * individually to make sure the data correctly. + */ + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + if (rt5514_dsp->buf_rp % 8) + rt5514_dsp->buf_rp = (rt5514_dsp->buf_rp / 8) * 8; + + rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base; + + if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && + rt5514_dsp->buf_rp && rt5514_dsp->buf_size) + schedule_delayed_work(&rt5514_dsp->copy_work, 0); + + return IRQ_HANDLED; +} + /* PCM for streaming audio from the DSP buffer */ static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream) { @@ -150,6 +204,7 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream, ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); rt5514_dsp->substream = substream; + rt5514_dsp->dma_offset = 0; mutex_unlock(&rt5514_dsp->dma_lock); return ret; @@ -170,59 +225,6 @@ static int rt5514_spi_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_vmalloc_buffer(substream); } -static int rt5514_spi_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - u8 buf[8]; - - rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset = 0; - - /** - * The address area x1800XXXX is the register address, and it cannot - * support spi burst read perfectly. So we use the spi burst read - * individually to make sure the data correctly. - */ - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_RP, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_SIZE, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_size = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - return 0; -} - -static int rt5514_spi_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - - if (cmd == SNDRV_PCM_TRIGGER_START) { - if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && - rt5514_dsp->buf_rp && rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 0); - } - - return 0; -} - static snd_pcm_uframes_t rt5514_spi_pcm_pointer( struct snd_pcm_substream *substream) { @@ -238,8 +240,6 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = { .open = rt5514_spi_pcm_open, .hw_params = rt5514_spi_hw_params, .hw_free = rt5514_spi_hw_free, - .trigger = rt5514_spi_trigger, - .prepare = rt5514_spi_prepare, .pointer = rt5514_spi_pcm_pointer, .mmap = snd_pcm_lib_mmap_vmalloc, .page = snd_pcm_lib_get_vmalloc_page, @@ -248,6 +248,7 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = { static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform) { struct rt5514_dsp *rt5514_dsp; + int ret; rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp), GFP_KERNEL); @@ -257,10 +258,21 @@ static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform) INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work); snd_soc_platform_set_drvdata(platform, rt5514_dsp); + if (rt5514_spi->irq) { + ret = devm_request_threaded_irq(&rt5514_spi->dev, + rt5514_spi->irq, NULL, rt5514_spi_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5514-spi", + rt5514_dsp); + if (ret) + dev_err(&rt5514_spi->dev, + "%s Failed to reguest IRQ: %d\n", __func__, + ret); + } + return 0; } -static struct snd_soc_platform_driver rt5514_spi_platform = { +static const struct snd_soc_platform_driver rt5514_spi_platform = { .probe = rt5514_spi_pcm_probe, .ops = &rt5514_spi_pcm_ops, }; diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h index f69b1cdf2f9b16af715317b9b91ebfaef567ffea..a6434ee6ff037c11c945a3358a90070de316b09c 100644 --- a/sound/soc/codecs/rt5514-spi.h +++ b/sound/soc/codecs/rt5514-spi.h @@ -17,10 +17,9 @@ */ #define RT5514_SPI_BUF_LEN 240 -#define RT5514_BUFFER_VOICE_BASE 0x18001034 -#define RT5514_BUFFER_VOICE_LIMIT 0x18001038 -#define RT5514_BUFFER_VOICE_RP 0x1800103c -#define RT5514_BUFFER_VOICE_SIZE 0x18001040 +#define RT5514_BUFFER_VOICE_BASE 0x18000200 +#define RT5514_BUFFER_VOICE_LIMIT 0x18000204 +#define RT5514_BUFFER_VOICE_WP 0x1800020c /* SPI Command */ enum { diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 1b6796c4c471cc536e5d2dc6e3a10fb23d6bff66..0945d212b8dca9d34d19b273d9075977075964e1 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -31,7 +31,7 @@ #include "rl6231.h" #include "rt5514.h" -#if defined(CONFIG_SND_SOC_RT5514_SPI) +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) #include "rt5514-spi.h" #endif @@ -63,6 +63,9 @@ static const struct reg_sequence rt5514_patch[] = { {RT5514_SRC_CTRL, 0x44000eee}, {RT5514_ANA_CTRL_LDO10, 0x00028604}, {RT5514_ANA_CTRL_ADCFED, 0x00000800}, + {RT5514_ASRC_IN_CTRL1, 0x00000003}, + {RT5514_DOWNFILTER0_CTRL3, 0x10000362}, + {RT5514_DOWNFILTER1_CTRL3, 0x10000362}, }; static const struct reg_default rt5514_reg[] = { @@ -88,10 +91,10 @@ static const struct reg_default rt5514_reg[] = { {RT5514_DELAY_BUF_CTRL3, 0x00000000}, {RT5514_DOWNFILTER0_CTRL1, 0x00020c2f}, {RT5514_DOWNFILTER0_CTRL2, 0x00020c2f}, - {RT5514_DOWNFILTER0_CTRL3, 0x00000362}, + {RT5514_DOWNFILTER0_CTRL3, 0x10000362}, {RT5514_DOWNFILTER1_CTRL1, 0x00020c2f}, {RT5514_DOWNFILTER1_CTRL2, 0x00020c2f}, - {RT5514_DOWNFILTER1_CTRL3, 0x00000362}, + {RT5514_DOWNFILTER1_CTRL3, 0x10000362}, {RT5514_ANA_CTRL_LDO10, 0x00028604}, {RT5514_ANA_CTRL_LDO18_16, 0x02000345}, {RT5514_ANA_CTRL_ADC12, 0x0000a2a8}, @@ -311,7 +314,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, request_firmware(&fw, RT5514_FIRMWARE1, codec->dev); if (fw) { -#if defined(CONFIG_SND_SOC_RT5514_SPI) +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ff60000, fw->data, ((fw->size/8)+1)*8); #else @@ -324,7 +327,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, request_firmware(&fw, RT5514_FIRMWARE2, codec->dev); if (fw) { -#if defined(CONFIG_SND_SOC_RT5514_SPI) +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ffc0000, fw->data, ((fw->size/8)+1)*8); #else @@ -335,6 +338,39 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, fw = NULL; } + if (rt5514->model_buf && rt5514->model_len) { +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) + int ret; + + ret = rt5514_spi_burst_write(0x4ff80000, + rt5514->model_buf, + ((rt5514->model_len / 8) + 1) * 8); + if (ret) { + dev_err(codec->dev, + "Model load failed %d\n", ret); + return ret; + } +#else + dev_err(codec->dev, + "No SPI driver for loading firmware\n"); +#endif + } else { + request_firmware(&fw, RT5514_FIRMWARE3, + codec->dev); + if (fw) { +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) + rt5514_spi_burst_write(0x4ff80000, + fw->data, + ((fw->size/8)+1)*8); +#else + dev_err(codec->dev, + "No SPI driver to load fw\n"); +#endif + release_firmware(fw); + fw = NULL; + } + } + /* DSP run */ regmap_write(rt5514->i2c_regmap, 0x18002f00, 0x00055148); @@ -349,6 +385,34 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, return 0; } +static int rt5514_hotword_model_put(struct snd_kcontrol *kcontrol, + const unsigned int __user *bytes, unsigned int size) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); + struct snd_soc_codec *codec = rt5514->codec; + int ret = 0; + + if (rt5514->model_buf || rt5514->model_len < size) { + if (rt5514->model_buf) + devm_kfree(codec->dev, rt5514->model_buf); + rt5514->model_buf = devm_kmalloc(codec->dev, size, GFP_KERNEL); + if (!rt5514->model_buf) { + ret = -ENOMEM; + goto done; + } + } + + /* Skips the TLV header. */ + bytes += 2; + + if (copy_from_user(rt5514->model_buf, bytes, size)) + ret = -EFAULT; +done: + rt5514->model_len = (ret ? 0 : size); + return ret; +} + static const struct snd_kcontrol_new rt5514_snd_controls[] = { SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), @@ -360,6 +424,8 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = { adc_vol_tlv), SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), + SND_SOC_BYTES_TLV("Hotword Model", 0x8504, + NULL, rt5514_hotword_model_put), }; /* ADC Mixer*/ @@ -471,33 +537,13 @@ static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, return 0; } -static int rt5514_pre_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int rt5514_i2s_use_asrc(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /** - * If the DSP is enabled in start of recording, the DSP - * should be disabled, and sync back to normal recording - * settings to make sure recording properly. - */ - if (rt5514->dsp_enabled) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write(rt5514->i2c_regmap, - rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - } - break; - - default: - return 0; - } - - return 0; + return (rt5514->sysclk > rt5514->lrck * 384); } static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { @@ -570,6 +616,10 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { RT5514_POW_PLL1_LDO_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("PLL1", RT5514_PWR_ANA2, RT5514_POW_PLL1_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ASRC AD1", 1, RT5514_CLK_CTRL2, + RT5514_CLK_AD0_ASRC_EN_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ASRC AD2", 1, RT5514_CLK_CTRL2, + RT5514_CLK_AD1_ASRC_EN_BIT, 0, NULL, 0), /* ADC Mux */ SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, @@ -607,8 +657,6 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { /* Audio Interface */ SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_PRE("DAPM Pre", rt5514_pre_event), }; static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { @@ -669,6 +717,7 @@ static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" }, { "Stereo1 ADC MIX", NULL, "adc stereo1 filter" }, { "adc stereo1 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll }, + { "adc stereo1 filter", NULL, "ASRC AD1", rt5514_i2s_use_asrc }, { "Stereo2 DMIC Mux", "DMIC1", "DMIC1" }, { "Stereo2 DMIC Mux", "DMIC2", "DMIC2" }, @@ -685,6 +734,7 @@ static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXR" }, { "Stereo2 ADC MIX", NULL, "adc stereo2 filter" }, { "adc stereo2 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll }, + { "adc stereo2 filter", NULL, "ASRC AD2", rt5514_i2s_use_asrc }, { "AIF1TX", NULL, "Stereo1 ADC MIX"}, { "AIF1TX", NULL, "Stereo2 ADC MIX"}, @@ -737,6 +787,9 @@ static int rt5514_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1, RT5514_I2S_DL_MASK, val_len); + regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL1, + RT5514_CLK_AD_ANA1_SEL_MASK, + (pre_div + 1) << RT5514_CLK_AD_ANA1_SEL_SFT); regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2, RT5514_CLK_SYS_DIV_OUT_MASK | RT5514_SEL_ADC_OSR_MASK, pre_div << RT5514_CLK_SYS_DIV_OUT_SFT | @@ -902,11 +955,38 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, { struct snd_soc_codec *codec = dai->codec; struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); - unsigned int val = 0; + unsigned int val = 0, val2 = 0; if (rx_mask || tx_mask) val |= RT5514_TDM_MODE; + switch (tx_mask) { + case 0x3: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH2 | + RT5514_TDM_DOCKING_START_SLOT0; + break; + + case 0x30: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH2 | + RT5514_TDM_DOCKING_START_SLOT4; + break; + + case 0xf: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH4 | + RT5514_TDM_DOCKING_START_SLOT0; + break; + + case 0xf0: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH4 | + RT5514_TDM_DOCKING_START_SLOT4; + break; + + default: + break; + } + + + switch (slots) { case 4: val |= RT5514_TDMSLOT_SEL_RX_4CH | RT5514_TDMSLOT_SEL_TX_4CH; @@ -952,6 +1032,10 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, RT5514_CH_LEN_RX_MASK | RT5514_CH_LEN_TX_MASK | RT5514_TDM_MODE2, val); + regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL2, + RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH_MASK | + RT5514_TDM_DOCKING_START_MASK, val2); + return 0; } @@ -975,6 +1059,24 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec, } break; + case SND_SOC_BIAS_STANDBY: + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { + /* + * If the DSP is enabled in start of recording, the DSP + * should be disabled, and sync back to normal recording + * settings to make sure recording properly. + */ + if (rt5514->dsp_enabled) { + rt5514->dsp_enabled = 0; + regmap_multi_reg_write(rt5514->i2c_regmap, + rt5514_i2c_patch, + ARRAY_SIZE(rt5514_i2c_patch)); + regcache_mark_dirty(rt5514->regmap); + regcache_sync(rt5514->regmap); + } + } + break; + default: break; } @@ -1019,7 +1121,7 @@ static int rt5514_i2c_write(void *context, unsigned int reg, unsigned int val) #define RT5514_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -struct snd_soc_dai_ops rt5514_aif_dai_ops = { +static const struct snd_soc_dai_ops rt5514_aif_dai_ops = { .hw_params = rt5514_hw_params, .set_fmt = rt5514_set_dai_fmt, .set_sysclk = rt5514_set_dai_sysclk, @@ -1027,7 +1129,7 @@ struct snd_soc_dai_ops rt5514_aif_dai_ops = { .set_tdm_slot = rt5514_set_tdm_slot, }; -struct snd_soc_dai_driver rt5514_dai[] = { +static struct snd_soc_dai_driver rt5514_dai[] = { { .name = "rt5514-aif1", .id = 0, @@ -1042,7 +1144,7 @@ struct snd_soc_dai_driver rt5514_dai[] = { } }; -static struct snd_soc_codec_driver soc_codec_dev_rt5514 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5514 = { .probe = rt5514_probe, .idle_bias_off = true, .set_bias_level = rt5514_set_bias_level, @@ -1097,7 +1199,7 @@ MODULE_DEVICE_TABLE(of, rt5514_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5514_acpi_match[] = { +static const struct acpi_device_id rt5514_acpi_match[] = { { "10EC5514", 0}, {}, }; diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h index 02bc212a86d9c7e2d9559d7ec0b744f3c906a9e2..803311cb7e2a075aa405847a673b31cac66afc6a 100644 --- a/sound/soc/codecs/rt5514.h +++ b/sound/soc/codecs/rt5514.h @@ -37,6 +37,7 @@ #define RT5514_PLL3_CALIB_CTRL5 0x2124 #define RT5514_DELAY_BUF_CTRL1 0x2140 #define RT5514_DELAY_BUF_CTRL3 0x2148 +#define RT5514_ASRC_IN_CTRL1 0x2180 #define RT5514_DOWNFILTER0_CTRL1 0x2190 #define RT5514_DOWNFILTER0_CTRL2 0x2194 #define RT5514_DOWNFILTER0_CTRL3 0x2198 @@ -164,6 +165,18 @@ #define RT5514_I2S_DL_24 (0x2 << 0) #define RT5514_I2S_DL_8 (0x3 << 0) +/* RT5514_I2S_CTRL2 (0x2014) */ +#define RT5514_TDM_DOCKING_MODE (0x1 << 31) +#define RT5514_TDM_DOCKING_MODE_SFT 31 +#define RT5514_TDM_DOCKING_VALID_CH_MASK (0x1 << 29) +#define RT5514_TDM_DOCKING_VALID_CH_SFT 29 +#define RT5514_TDM_DOCKING_VALID_CH2 (0x0 << 29) +#define RT5514_TDM_DOCKING_VALID_CH4 (0x1 << 29) +#define RT5514_TDM_DOCKING_START_MASK (0x1 << 28) +#define RT5514_TDM_DOCKING_START_SFT 28 +#define RT5514_TDM_DOCKING_START_SLOT0 (0x0 << 28) +#define RT5514_TDM_DOCKING_START_SLOT4 (0x1 << 28) + /* RT5514_DIG_SOURCE_CTRL (0x20a4) */ #define RT5514_AD1_DMIC_INPUT_SEL (0x1 << 1) #define RT5514_AD1_DMIC_INPUT_SEL_SFT 1 @@ -185,8 +198,14 @@ #define RT5514_CLK_AD0_EN_BIT 23 #define RT5514_CLK_DMIC_OUT_SEL_MASK (0x7 << 8) #define RT5514_CLK_DMIC_OUT_SEL_SFT 8 +#define RT5514_CLK_AD_ANA1_SEL_MASK (0xf << 0) +#define RT5514_CLK_AD_ANA1_SEL_SFT 0 /* RT5514_CLK_CTRL2 (0x2108) */ +#define RT5514_CLK_AD1_ASRC_EN (0x1 << 17) +#define RT5514_CLK_AD1_ASRC_EN_BIT 17 +#define RT5514_CLK_AD0_ASRC_EN (0x1 << 16) +#define RT5514_CLK_AD0_ASRC_EN_BIT 16 #define RT5514_CLK_SYS_DIV_OUT_MASK (0x7 << 8) #define RT5514_CLK_SYS_DIV_OUT_SFT 8 #define RT5514_SEL_ADC_OSR_MASK (0x7 << 4) @@ -236,6 +255,7 @@ #define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin" #define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin" +#define RT5514_FIRMWARE3 "rt5514_dsp_fw3.bin" /* System Clock Source */ enum { @@ -262,6 +282,8 @@ struct rt5514_priv { int pll_in; int pll_out; int dsp_enabled; + u8 *model_buf; + unsigned int model_len; }; #endif /* __RT5514_H__ */ diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 7d6e0823f98f12023d2e2f95a7734ec51a6bef68..c94e94fe8297877c75f929498628b5d5adf4b654 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -1265,7 +1265,7 @@ static int rt5616_resume(struct snd_soc_codec *codec) #define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -static struct snd_soc_dai_ops rt5616_aif_dai_ops = { +static const struct snd_soc_dai_ops rt5616_aif_dai_ops = { .hw_params = rt5616_hw_params, .set_fmt = rt5616_set_dai_fmt, .set_sysclk = rt5616_set_dai_sysclk, @@ -1294,7 +1294,7 @@ static struct snd_soc_dai_driver rt5616_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5616 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5616 = { .probe = rt5616_probe, .suspend = rt5616_suspend, .resume = rt5616_resume, diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 0e418089c053ca716619da9ad79aca4090f8415b..55b04c55fb4b37b91f5e890e1daad3b8a9b4eee3 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1653,7 +1653,7 @@ static struct snd_soc_dai_driver rt5631_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5631 = { .probe = rt5631_probe, .set_bias_level = rt5631_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 1584ccc3a87bb9feffcdc09e8d800dfed045e43b..438fe52a12dfb50472437ca1204c7a2b1748ba34 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2259,7 +2259,7 @@ static struct snd_soc_dai_driver rt5640_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5640 = { .probe = rt5640_probe, .remove = rt5640_remove, .suspend = rt5640_suspend, diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 9ec58166f7c427f50d9b72ba1f6bc9cbf0362a50..a98647ac497cc7e64a99990e9ad3b0097eb829e6 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3473,7 +3473,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5645 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5645 = { .probe = rt5645_probe, .remove = rt5645_remove, .suspend = rt5645_suspend, @@ -3559,7 +3559,7 @@ static const struct acpi_device_id rt5645_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); #endif -static struct rt5645_platform_data general_platform_data = { +static const struct rt5645_platform_data general_platform_data = { .dmic1_data_pin = RT5645_DMIC1_DISABLE, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, .jd_mode = 3, @@ -3593,14 +3593,14 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { { } }; -static struct rt5645_platform_data buddy_platform_data = { +static const struct rt5645_platform_data buddy_platform_data = { .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, .jd_mode = 3, .level_trigger_irq = true, }; -static struct dmi_system_id dmi_platform_intel_broadwell[] = { +static const struct dmi_system_id dmi_platform_intel_broadwell[] = { { .ident = "Chrome Buddy", .matches = { @@ -3610,7 +3610,7 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = { { } }; -static struct rt5645_platform_data gpd_win_platform_data = { +static const struct rt5645_platform_data gpd_win_platform_data = { .jd_mode = 3, .inv_jd1_1 = true, }; @@ -3637,6 +3637,39 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = { {} }; +static struct rt5645_platform_data general_platform_data2 = { + .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, + .dmic2_data_pin = RT5645_DMIC2_DISABLE, + .jd_mode = 3, + .inv_jd1_1 = true, +}; + +static struct dmi_system_id dmi_platform_asus_t100ha[] = { + { + .ident = "ASUS T100HAN", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), + }, + }, + { } +}; + +static struct rt5645_platform_data minix_z83_4_platform_data = { + .jd_mode = 3, +}; + +static struct dmi_system_id dmi_platform_minix_z83_4[] = { + { + .ident = "MINIX Z83-4", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), + DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), + }, + }, + { } +}; + static bool rt5645_check_dp(struct device *dev) { if (device_property_present(dev, "realtek,in2-differential") || @@ -3689,6 +3722,10 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->pdata = general_platform_data; else if (dmi_check_system(dmi_platform_gpd_win)) rt5645->pdata = gpd_win_platform_data; + else if (dmi_check_system(dmi_platform_asus_t100ha)) + rt5645->pdata = general_platform_data2; + else if (dmi_check_system(dmi_platform_minix_z83_4)) + rt5645->pdata = minix_z83_4_platform_data; if (quirk != -1) { rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index db05b60d50029c3d53b1bdbc5ad5d0118687887a..da60b28ba3dff4d7ec6adf61e01f76a03b46b074 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1664,7 +1664,7 @@ static struct snd_soc_dai_driver rt5651_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5651 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5651 = { .probe = rt5651_probe, .suspend = rt5651_suspend, .resume = rt5651_resume, diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 1b7060850340bd04041079ad09f9509b6f07b9ad..71216db15eab8811775275575b573754b85889b5 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -3730,7 +3730,7 @@ static struct snd_soc_dai_driver rt5659_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5659 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5659 = { .probe = rt5659_probe, .remove = rt5659_remove, .suspend = rt5659_suspend, @@ -4222,7 +4222,7 @@ MODULE_DEVICE_TABLE(of, rt5659_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5659_acpi_match[] = { +static const struct acpi_device_id rt5659_acpi_match[] = { { "10EC5658", 0, }, { "10EC5659", 0, }, { }, diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index c93490d77f2aea38af1b7f5f3c3dbe22f27f4a4f..d22ef00e0d964e09c9930f58d62c5f5c247e1a25 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1197,7 +1197,7 @@ static struct snd_soc_dai_driver rt5660_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5660 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5660 = { .probe = rt5660_probe, .remove = rt5660_remove, .suspend = rt5660_suspend, diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index a33202affeb123aca338303d9d9c61bd7d5f5f39..ab9e0ebff5a7ffe8c24a026441538c6bd877a733 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -40,6 +40,7 @@ enum { struct rt5663_priv { struct snd_soc_codec *codec; + struct rt5663_platform_data pdata; struct regmap *regmap; struct delayed_work jack_detect_work; struct snd_soc_jack *hs_jack; @@ -57,6 +58,11 @@ struct rt5663_priv { int jack_type; }; +static const struct reg_sequence rt5663_patch_list[] = { + { 0x002a, 0x8020 }, + { 0x0086, 0x0028 }, +}; + static const struct reg_default rt5663_v2_reg[] = { { 0x0000, 0x0000 }, { 0x0001, 0xc8c8 }, @@ -466,7 +472,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0006, 0x1000 }, { 0x000a, 0x0000 }, { 0x0010, 0x000f }, - { 0x0015, 0x42c1 }, + { 0x0015, 0x42f1 }, { 0x0016, 0x0000 }, { 0x0018, 0x000b }, { 0x0019, 0xafaf }, @@ -476,7 +482,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0023, 0x0039 }, { 0x0026, 0xc0c0 }, { 0x0029, 0x8080 }, - { 0x002a, 0xa0a0 }, + { 0x002a, 0x8020 }, { 0x002c, 0x000c }, { 0x002d, 0x0000 }, { 0x0040, 0x0808 }, @@ -504,12 +510,12 @@ static const struct reg_default rt5663_reg[] = { { 0x0082, 0x0000 }, { 0x0083, 0x0000 }, { 0x0084, 0x0000 }, - { 0x0086, 0x0008 }, + { 0x0086, 0x0028 }, { 0x0087, 0x0000 }, { 0x008a, 0x0000 }, { 0x008b, 0x0000 }, { 0x008c, 0x0003 }, - { 0x008e, 0x0004 }, + { 0x008e, 0x0008 }, { 0x008f, 0x1000 }, { 0x0090, 0x0646 }, { 0x0091, 0x0e3e }, @@ -520,7 +526,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0098, 0x0000 }, { 0x009a, 0x0000 }, { 0x009f, 0x0000 }, - { 0x00ae, 0x2000 }, + { 0x00ae, 0x6000 }, { 0x00af, 0x0000 }, { 0x00b6, 0x0000 }, { 0x00b7, 0x0000 }, @@ -538,7 +544,7 @@ static const struct reg_default rt5663_reg[] = { { 0x00d9, 0x08f9 }, { 0x00db, 0x0008 }, { 0x00dc, 0x00c0 }, - { 0x00dd, 0x6724 }, + { 0x00dd, 0x6729 }, { 0x00de, 0x3131 }, { 0x00df, 0x0008 }, { 0x00e0, 0x4000 }, @@ -578,7 +584,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0116, 0x0000 }, { 0x0117, 0x0f00 }, { 0x0118, 0x0006 }, - { 0x0125, 0x2224 }, + { 0x0125, 0x2424 }, { 0x0126, 0x5550 }, { 0x0127, 0x0400 }, { 0x0128, 0x7711 }, @@ -596,8 +602,8 @@ static const struct reg_default rt5663_reg[] = { { 0x0145, 0x0002 }, { 0x0146, 0x0000 }, { 0x0160, 0x0e80 }, - { 0x0161, 0x0020 }, - { 0x0162, 0x0080 }, + { 0x0161, 0x0080 }, + { 0x0162, 0x0200 }, { 0x0163, 0x0800 }, { 0x0164, 0x0000 }, { 0x0165, 0x0000 }, @@ -676,8 +682,8 @@ static const struct reg_default rt5663_reg[] = { { 0x0251, 0x0000 }, { 0x0252, 0x028a }, { 0x02fa, 0x0000 }, - { 0x02fb, 0x0000 }, - { 0x02fc, 0x0000 }, + { 0x02fb, 0x00a4 }, + { 0x02fc, 0x0300 }, { 0x0300, 0x0000 }, { 0x03d0, 0x0000 }, { 0x03d1, 0x0000 }, @@ -1508,7 +1514,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert) static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) { struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); - int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; + int val, i = 0; dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); @@ -1543,25 +1549,68 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); snd_soc_update_bits(codec, RT5663_IRQ_1, RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); - while (i < 5) { - msleep(sleep_time[i]); - val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & - 0x0003; - dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", - __func__, val, sleep_time[i]); - i++; - if (val == 0x1 || val == 0x2 || val == 0x3) + + while (true) { + regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val); + if (!(val & 0x80)) + usleep_range(10000, 10005); + else break; + + if (i > 200) + break; + i++; } + + val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003; dev_dbg(codec->dev, "%s val = %d\n", __func__, val); + + snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, + RT5663_OSW_HP_L_MASK | RT5663_OSW_HP_R_MASK, + RT5663_OSW_HP_L_EN | RT5663_OSW_HP_R_EN); + switch (val) { case 1: case 2: rt5663->jack_type = SND_JACK_HEADSET; rt5663_enable_push_button_irq(codec, true); + + if (rt5663->pdata.dc_offset_l_manual_mic) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, + rt5663->pdata.dc_offset_l_manual_mic >> + 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3, + rt5663->pdata.dc_offset_l_manual_mic & + 0xffff); + } + + if (rt5663->pdata.dc_offset_r_manual_mic) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5, + rt5663->pdata.dc_offset_r_manual_mic >> + 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6, + rt5663->pdata.dc_offset_r_manual_mic & + 0xffff); + } break; default: rt5663->jack_type = SND_JACK_HEADPHONE; + + if (rt5663->pdata.dc_offset_l_manual) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, + rt5663->pdata.dc_offset_l_manual >> 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3, + rt5663->pdata.dc_offset_l_manual & + 0xffff); + } + + if (rt5663->pdata.dc_offset_r_manual) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5, + rt5663->pdata.dc_offset_r_manual >> 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6, + rt5663->pdata.dc_offset_r_manual & + 0xffff); + } break; } } else { @@ -1656,6 +1705,9 @@ static void rt5663_jack_detect_work(struct work_struct *work) default: dev_err(codec->dev, "Unknown CODEC Version\n"); } + + /* Delay the jack insert report to avoid pop noise */ + msleep(30); } else { /* jack is already in, report button event */ report = SND_JACK_HEADSET; @@ -1953,13 +2005,9 @@ static const struct snd_kcontrol_new rt5663_adda_r_mix[] = { static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = { SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, RT5663_M_DAC_L1_STO_L_SHIFT, 1, 1), - SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, - RT5663_M_DAC_R1_STO_L_SHIFT, 1, 1), }; static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = { - SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, - RT5663_M_DAC_L1_STO_R_SHIFT, 1, 1), SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, RT5663_M_DAC_R1_STO_R_SHIFT, 1, 1), }; @@ -2024,10 +2072,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, RT5663_HP_SIG_SRC1_SILENCE); } else { snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, - 0x000b); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, - 0x0030); snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS); snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); @@ -2036,6 +2080,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766); snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa); snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777); + snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000, + 0x8000); snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x3000); } @@ -2050,9 +2096,36 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0); snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, - 0x000b); + } + break; + + default: + return 0; + } + + return 0; +} + +static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (rt5663->codec_ver == CODEC_VER_0) { + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, + 0x0030); + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, + 0x0003); + } + break; + + case SND_SOC_DAPM_POST_PMD: + if (rt5663->codec_ver == CODEC_VER_0) { + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0); + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0); } break; @@ -2182,6 +2255,9 @@ static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0), /* Headphone*/ + SND_SOC_DAPM_SUPPLY("HP Charge Pump", SND_SOC_NOPM, 0, 0, + rt5663_charge_pump_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), @@ -2330,14 +2406,13 @@ static const struct snd_soc_dapm_route rt5663_dapm_routes[] = { { "DAC R1", NULL, "ADDA MIXR" }, { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" }, - { "STO1 DAC MIXL", "DAC R Switch", "DAC R1" }, { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" }, { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" }, { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" }, - { "STO1 DAC MIXR", "DAC L Switch", "DAC L1" }, { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" }, { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" }, + { "HP Amp", NULL, "HP Charge Pump" }, { "HP Amp", NULL, "DAC L" }, { "HP Amp", NULL, "DAC R" }, }; @@ -2860,7 +2935,7 @@ static int rt5663_resume(struct snd_soc_codec *codec) #define RT5663_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -static struct snd_soc_dai_ops rt5663_aif_dai_ops = { +static const struct snd_soc_dai_ops rt5663_aif_dai_ops = { .hw_params = rt5663_hw_params, .set_fmt = rt5663_set_dai_fmt, .set_sysclk = rt5663_set_dai_sysclk, @@ -2891,7 +2966,7 @@ static struct snd_soc_dai_driver rt5663_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5663 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5663 = { .probe = rt5663_probe, .remove = rt5663_remove, .suspend = rt5663_suspend, @@ -2956,7 +3031,7 @@ MODULE_DEVICE_TABLE(of, rt5663_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5663_acpi_match[] = { +static const struct acpi_device_id rt5663_acpi_match[] = { { "10EC5663", 0}, {}, }; @@ -2986,47 +3061,76 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) { int value, count; - regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0280); + regmap_write(rt5663->regmap, RT5663_RESET, 0x0000); + msleep(20); + regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_4, 0x00a1); + regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0380); regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000); - regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); + regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1000); regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be); - msleep(20); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be); - regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); - regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); - regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); - regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0003); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); - regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1111); + regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c); + regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324); + regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b); + msleep(30); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8000); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x0008); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_1, 0xffff); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_2, 0xffff); + regmap_write(rt5663->regmap, RT5663_CBJ_1, 0x8c10); + regmap_write(rt5663->regmap, RT5663_IL_CMD_2, 0x00c1); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb880); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4110); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4118); + + count = 0; + while (true) { + regmap_read(rt5663->regmap, RT5663_INT_ST_2, &value); + if (!(value & 0x80)) + usleep_range(10000, 10005); + else + break; + + if (++count > 200) + break; + } + + regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x0000); regmap_write(rt5663->regmap, RT5663_DEPOP_2, 0x3003); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0038); regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); - regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371); regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b); - regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x2080); + msleep(40); + regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000); regmap_write(rt5663->regmap, RT5663_BYPASS_STO_DAC, 0x000c); - regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xabba); + regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xafaa); regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_1, 0x2224); regmap_write(rt5663->regmap, RT5663_HP_OUT_EN, 0x8088); regmap_write(rt5663->regmap, RT5663_STO_DRE_9, 0x0017); regmap_write(rt5663->regmap, RT5663_STO_DRE_10, 0x0017); regmap_write(rt5663->regmap, RT5663_STO1_ADC_MIXER, 0x4040); + regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); regmap_write(rt5663->regmap, RT5663_RECMIX, 0x0005); regmap_write(rt5663->regmap, RT5663_ADDA_RST, 0xc000); regmap_write(rt5663->regmap, RT5663_STO1_HPF_ADJ1, 0x3320); regmap_write(rt5663->regmap, RT5663_HP_CALIB_2, 0x00c9); regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x004c); - regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766); - regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4702); - msleep(200); + regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x1111); + regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4402); + regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x3311); regmap_write(rt5663->regmap, RT5663_HP_CALIB_1, 0x0069); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06c2); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x7b00); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xfb00); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06ce); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6800); + regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x1100); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0057); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe800); + count = 0; while (true) { regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); @@ -3039,11 +3143,56 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) return; count++; } + + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6200); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0059); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe200); + + count = 0; + while (true) { + regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); + if (value & 0x8000) + usleep_range(10000, 10005); + else + break; + + if (count > 200) + return; + count++; + } + + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb8e0); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0x003b); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x0000); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x000b); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0008); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0000); + usleep_range(10000, 10005); +} + +static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) +{ + device_property_read_u32(dev, "realtek,dc_offset_l_manual", + &rt5663->pdata.dc_offset_l_manual); + device_property_read_u32(dev, "realtek,dc_offset_r_manual", + &rt5663->pdata.dc_offset_r_manual); + device_property_read_u32(dev, "realtek,dc_offset_l_manual_mic", + &rt5663->pdata.dc_offset_l_manual_mic); + device_property_read_u32(dev, "realtek,dc_offset_r_manual_mic", + &rt5663->pdata.dc_offset_r_manual_mic); + + return 0; } static int rt5663_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5663_priv *rt5663; int ret; unsigned int val; @@ -3057,6 +3206,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5663); + if (pdata) + rt5663->pdata = *pdata; + else + rt5663_parse_dp(rt5663, &i2c->dev); + regmap = devm_regmap_init_i2c(i2c, &temp_regmap); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); @@ -3105,6 +3259,20 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, regmap_write(rt5663->regmap, RT5663_RESET, 0); dev_dbg(&i2c->dev, "calibrate done\n"); + switch (rt5663->codec_ver) { + case CODEC_VER_1: + break; + case CODEC_VER_0: + ret = regmap_register_patch(rt5663->regmap, rt5663_patch_list, + ARRAY_SIZE(rt5663_patch_list)); + if (ret != 0) + dev_warn(&i2c->dev, + "Failed to apply regmap patch: %d\n", ret); + break; + default: + dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); + } + /* GPIO1 as IRQ */ regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5663_GP1_PIN_MASK, RT5663_GP1_PIN_IRQ); diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h index 4621812c94d8a718c8c80fbae463fd560f4e646c..c5a9b69579ad216d9b039359910e8c10acfa1832 100644 --- a/sound/soc/codecs/rt5663.h +++ b/sound/soc/codecs/rt5663.h @@ -12,6 +12,8 @@ #ifndef __RT5663_H__ #define __RT5663_H__ +#include + /* Info */ #define RT5663_RESET 0x0000 #define RT5663_VENDOR_ID 0x00fd diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 370ed54d1e1590f1036a4ff4425c0462245d3360..f05d362c4e23b859ccc823502751a91d9417c023 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -1381,6 +1381,16 @@ static void rt5665_jack_detect_handler(struct work_struct *work) mutex_unlock(&rt5665->calibrate_mutex); } +static const char * const rt5665_clk_sync[] = { + "I2S1_1", "I2S1_2", "I2S2", "I2S3", "IF2 Slave", "IF3 Slave" +}; + +static const struct soc_enum rt5665_enum[] = { + SOC_ENUM_SINGLE(RT5665_I2S1_SDP, 11, 5, rt5665_clk_sync), + SOC_ENUM_SINGLE(RT5665_I2S2_SDP, 11, 5, rt5665_clk_sync), + SOC_ENUM_SINGLE(RT5665_I2S3_SDP, 11, 5, rt5665_clk_sync), +}; + static const struct snd_kcontrol_new rt5665_snd_controls[] = { /* Headphone Output Volume */ SOC_DOUBLE_R_EXT_TLV("Headphone Playback Volume", RT5665_HPL_GAIN, @@ -1392,6 +1402,9 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = { RT5665_L_VOL_SFT, 15, 1, snd_soc_get_volsw, rt5665_mono_vol_put, mono_vol_tlv), + SOC_SINGLE_TLV("MONOVOL Playback Volume", RT5665_MONO_OUT, + RT5665_L_VOL_SFT, 39, 1, out_vol_tlv), + /* Output Volume */ SOC_DOUBLE_TLV("OUT Playback Volume", RT5665_LOUT, RT5665_L_VOL_SFT, RT5665_R_VOL_SFT, 39, 1, out_vol_tlv), @@ -1446,6 +1459,11 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = { SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5665_STO2_ADC_BOOST, RT5665_STO2_ADC_L_BST_SFT, RT5665_STO2_ADC_R_BST_SFT, 3, 0, adc_bst_tlv), + + /* I2S3 CLK Source */ + SOC_ENUM("I2S1 Master Clk Sel", rt5665_enum[0]), + SOC_ENUM("I2S2 Master Clk Sel", rt5665_enum[1]), + SOC_ENUM("I2S3 Master Clk Sel", rt5665_enum[2]), }; /** @@ -4098,9 +4116,12 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, rt5665->lrck[dai->id] = params_rate(params); pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]); if (pre_div < 0) { - dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", - rt5665->lrck[dai->id], dai->id); - return -EINVAL; + dev_warn(codec->dev, "Force using PLL"); + snd_soc_codec_set_pll(codec, 0, RT5665_PLL1_S_MCLK, + rt5665->sysclk, rt5665->lrck[dai->id] * 512); + snd_soc_codec_set_sysclk(codec, RT5665_SCLK_S_PLL1, 0, + rt5665->lrck[dai->id] * 512, 0); + pre_div = 1; } frame_size = snd_soc_params_to_frame_size(params); if (frame_size < 0) { @@ -4183,6 +4204,15 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, break; } + if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S2_M_PD_MASK, pre_div << RT5665_I2S2_M_PD_SFT); + } + if (rt5665->master[RT5665_AIF3]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S3_M_PD_MASK, pre_div << RT5665_I2S3_M_PD_SFT); + } + return 0; } @@ -4259,7 +4289,7 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, int source, unsigned int freq, int dir) { struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); - unsigned int reg_val = 0; + unsigned int reg_val = 0, src = 0; if (freq == rt5665->sysclk && clk_id == rt5665->sysclk_src) return 0; @@ -4267,12 +4297,15 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, switch (clk_id) { case RT5665_SCLK_S_MCLK: reg_val |= RT5665_SCLK_SRC_MCLK; + src = RT5665_CLK_SRC_MCLK; break; case RT5665_SCLK_S_PLL1: reg_val |= RT5665_SCLK_SRC_PLL1; + src = RT5665_CLK_SRC_PLL1; break; case RT5665_SCLK_S_RCCLK: reg_val |= RT5665_SCLK_SRC_RCCLK; + src = RT5665_CLK_SRC_RCCLK; break; default: dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); @@ -4280,6 +4313,16 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, } snd_soc_update_bits(codec, RT5665_GLB_CLK, RT5665_SCLK_SRC_MASK, reg_val); + + if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S2_SRC_MASK, src << RT5665_I2S2_SRC_SFT); + } + if (rt5665->master[RT5665_AIF3]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S3_SRC_MASK, src << RT5665_I2S3_SRC_SFT); + } + rt5665->sysclk = freq; rt5665->sysclk_src = clk_id; @@ -4368,12 +4411,12 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) switch (dai->id) { case RT5665_AIF2_1: case RT5665_AIF2_2: - snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, + snd_soc_update_bits(codec, RT5665_ADDA_CLK_2, RT5665_I2S_BCLK_MS2_MASK, RT5665_I2S_BCLK_MS2_64); break; case RT5665_AIF3: - snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, + snd_soc_update_bits(codec, RT5665_ADDA_CLK_2, RT5665_I2S_BCLK_MS3_MASK, RT5665_I2S_BCLK_MS3_64); break; @@ -4562,7 +4605,7 @@ static struct snd_soc_dai_driver rt5665_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5665 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5665 = { .probe = rt5665_probe, .remove = rt5665_remove, .suspend = rt5665_suspend, @@ -4927,7 +4970,7 @@ MODULE_DEVICE_TABLE(of, rt5665_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5665_acpi_match[] = { +static const struct acpi_device_id rt5665_acpi_match[] = { {"10EC5665", 0,}, {"10EC5666", 0,}, {"10EC5668", 0,}, diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h index 1db5c6a62a8e0c872e24fc6474031cbdfb72ab80..5ddebd6a4a1b5508fd158a0f1ac88ecf29b3fed8 100644 --- a/sound/soc/codecs/rt5665.h +++ b/sound/soc/codecs/rt5665.h @@ -1628,6 +1628,27 @@ #define RT5665_PWR_CLK1M_PD (0x0 << 8) #define RT5665_PWR_CLK1M_PU (0x1 << 8) +/* I2S Master Mode Clock Control 1 (0x00a0) */ +#define RT5665_CLK_SRC_MCLK (0x0) +#define RT5665_CLK_SRC_PLL1 (0x1) +#define RT5665_CLK_SRC_RCCLK (0x2) +#define RT5665_I2S_PD_1 (0x0) +#define RT5665_I2S_PD_2 (0x1) +#define RT5665_I2S_PD_3 (0x2) +#define RT5665_I2S_PD_4 (0x3) +#define RT5665_I2S_PD_6 (0x4) +#define RT5665_I2S_PD_8 (0x5) +#define RT5665_I2S_PD_12 (0x6) +#define RT5665_I2S_PD_16 (0x7) +#define RT5665_I2S2_SRC_MASK (0x3 << 12) +#define RT5665_I2S2_SRC_SFT 12 +#define RT5665_I2S2_M_PD_MASK (0x7 << 8) +#define RT5665_I2S2_M_PD_SFT 8 +#define RT5665_I2S3_SRC_MASK (0x3 << 4) +#define RT5665_I2S3_SRC_SFT 4 +#define RT5665_I2S3_M_PD_MASK (0x7 << 0) +#define RT5665_I2S3_M_PD_SFT 0 + /* EQ Control 1 (0x00b0) */ #define RT5665_EQ_SRC_DAC (0x0 << 15) @@ -1692,8 +1713,8 @@ #define RT5665_GP6_PIN_MASK (0x3 << 5) #define RT5665_GP6_PIN_SFT 5 #define RT5665_GP6_PIN_GPIO6 (0x0 << 5) -#define RT5665_GP6_PIN_BCLK3 (0x0 << 5) -#define RT5665_GP6_PIN_PDM_SCL (0x1 << 5) +#define RT5665_GP6_PIN_BCLK3 (0x1 << 5) +#define RT5665_GP6_PIN_PDM_SCL (0x2 << 5) #define RT5665_GP7_PIN_MASK (0x3 << 3) #define RT5665_GP7_PIN_SFT 3 #define RT5665_GP7_PIN_GPIO7 (0x0 << 3) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 0ec7985ed306612db13bd6314ccc94733e835cce..9545764ef3eb965a75a285eb9e5a3275333f959d 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -567,7 +567,7 @@ int rt5670_set_jack_detect(struct snd_soc_codec *codec, rt5670->jack = jack; rt5670->hp_gpio.gpiod_dev = codec->dev; - rt5670->hp_gpio.name = "headphone detect"; + rt5670->hp_gpio.name = "headset"; rt5670->hp_gpio.report = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2; rt5670->hp_gpio.debounce_time = 150; @@ -1151,20 +1151,15 @@ static const char * const rt5670_stereo_adc1_src[] = { static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER, RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); -static const struct snd_kcontrol_new rt5670_sto_adc_l1_mux = - SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5670_stereo1_adc1_enum); - -static const struct snd_kcontrol_new rt5670_sto_adc_r1_mux = - SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5670_stereo1_adc1_enum); +static const struct snd_kcontrol_new rt5670_sto_adc_1_mux = + SOC_DAPM_ENUM("Stereo1 ADC 1 Mux", rt5670_stereo1_adc1_enum); static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER, RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); -static const struct snd_kcontrol_new rt5670_sto2_adc_l1_mux = - SOC_DAPM_ENUM("Stereo2 ADC L1 source", rt5670_stereo2_adc1_enum); +static const struct snd_kcontrol_new rt5670_sto2_adc_1_mux = + SOC_DAPM_ENUM("Stereo2 ADC 1 Mux", rt5670_stereo2_adc1_enum); -static const struct snd_kcontrol_new rt5670_sto2_adc_r1_mux = - SOC_DAPM_ENUM("Stereo2 ADC R1 source", rt5670_stereo2_adc1_enum); /* MX-27 MX-26 [11] */ static const char * const rt5670_stereo_adc2_src[] = { @@ -1174,20 +1169,15 @@ static const char * const rt5670_stereo_adc2_src[] = { static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER, RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); -static const struct snd_kcontrol_new rt5670_sto_adc_l2_mux = - SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5670_stereo1_adc2_enum); - -static const struct snd_kcontrol_new rt5670_sto_adc_r2_mux = - SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5670_stereo1_adc2_enum); +static const struct snd_kcontrol_new rt5670_sto_adc_2_mux = + SOC_DAPM_ENUM("Stereo1 ADC 2 Mux", rt5670_stereo1_adc2_enum); static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER, RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); -static const struct snd_kcontrol_new rt5670_sto2_adc_l2_mux = - SOC_DAPM_ENUM("Stereo2 ADC L2 source", rt5670_stereo2_adc2_enum); +static const struct snd_kcontrol_new rt5670_sto2_adc_2_mux = + SOC_DAPM_ENUM("Stereo2 ADC 2 Mux", rt5670_stereo2_adc2_enum); -static const struct snd_kcontrol_new rt5670_sto2_adc_r2_mux = - SOC_DAPM_ENUM("Stereo2 ADC R2 source", rt5670_stereo2_adc2_enum); /* MX-27 MX26 [10] */ static const char * const rt5670_stereo_adc_src[] = { @@ -1642,23 +1632,23 @@ static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = { SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, &rt5670_sto1_dmic_mux), SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_l2_mux), + &rt5670_sto_adc_2_mux), SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_r2_mux), + &rt5670_sto_adc_2_mux), SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_l1_mux), + &rt5670_sto_adc_1_mux), SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_r1_mux), + &rt5670_sto_adc_1_mux), SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0, &rt5670_sto2_dmic_mux), SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_l2_mux), + &rt5670_sto2_adc_2_mux), SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_r2_mux), + &rt5670_sto2_adc_2_mux), SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_l1_mux), + &rt5670_sto2_adc_1_mux), SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_r1_mux), + &rt5670_sto2_adc_1_mux), SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0, &rt5670_sto2_adc_lr_mux), SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0, @@ -2743,6 +2733,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, + .symmetric_rates = 1, }, { .name = "rt5670-aif2", @@ -2762,10 +2753,11 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, + .symmetric_rates = 1, }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5670 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5670 = { .probe = rt5670_probe, .remove = rt5670_remove, .suspend = rt5670_suspend, @@ -2859,6 +2851,17 @@ static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode2[] = { {} }; +static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode3[] = { + { + .ident = "Dell Venue 8 Pro 5855", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5855"), + }, + }, + {} +}; + static int rt5670_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2888,6 +2891,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; rt5670->pdata.dev_gpio = true; rt5670->pdata.jd_mode = 2; + } else if (dmi_check_system(dmi_platform_intel_bytcht_jdmode3)) { + rt5670->pdata.dmic_en = true; + rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; + rt5670->pdata.dev_gpio = true; + rt5670->pdata.jd_mode = 3; } rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 36e530a36c8241d5005c8e8f5f933f2a405c3434..0791fec398fb63a67c88d206b28536b6e5571079 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -779,9 +780,7 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) return 0; } -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); -static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0); @@ -4624,35 +4623,27 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) struct regmap_irq_chip_data *data = rt5677->irq_data; int irq; - if (offset >= RT5677_GPIO1 && offset <= RT5677_GPIO3) { - if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || - (rt5677->pdata.jd1_gpio == 2 && - offset == RT5677_GPIO2) || - (rt5677->pdata.jd1_gpio == 3 && - offset == RT5677_GPIO3)) { - irq = RT5677_IRQ_JD1; - } else { - return -ENXIO; - } - } - - if (offset >= RT5677_GPIO4 && offset <= RT5677_GPIO6) { - if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || - (rt5677->pdata.jd2_gpio == 2 && - offset == RT5677_GPIO5) || - (rt5677->pdata.jd2_gpio == 3 && - offset == RT5677_GPIO6)) { - irq = RT5677_IRQ_JD2; - } else if ((rt5677->pdata.jd3_gpio == 1 && - offset == RT5677_GPIO4) || - (rt5677->pdata.jd3_gpio == 2 && - offset == RT5677_GPIO5) || - (rt5677->pdata.jd3_gpio == 3 && - offset == RT5677_GPIO6)) { - irq = RT5677_IRQ_JD3; - } else { - return -ENXIO; - } + if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || + (rt5677->pdata.jd1_gpio == 2 && + offset == RT5677_GPIO2) || + (rt5677->pdata.jd1_gpio == 3 && + offset == RT5677_GPIO3)) { + irq = RT5677_IRQ_JD1; + } else if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || + (rt5677->pdata.jd2_gpio == 2 && + offset == RT5677_GPIO5) || + (rt5677->pdata.jd2_gpio == 3 && + offset == RT5677_GPIO6)) { + irq = RT5677_IRQ_JD2; + } else if ((rt5677->pdata.jd3_gpio == 1 && + offset == RT5677_GPIO4) || + (rt5677->pdata.jd3_gpio == 2 && + offset == RT5677_GPIO5) || + (rt5677->pdata.jd3_gpio == 3 && + offset == RT5677_GPIO6)) { + irq = RT5677_IRQ_JD3; + } else { + return -ENXIO; } return regmap_irq_get_virq(data, irq); @@ -4968,7 +4959,7 @@ static struct snd_soc_dai_driver rt5677_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5677 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5677 = { .probe = rt5677_probe, .remove = rt5677_remove, .suspend = rt5677_suspend, @@ -5026,18 +5017,16 @@ static const struct i2c_device_id rt5677_i2c_id[] = { MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); static const struct of_device_id rt5677_of_match[] = { - { .compatible = "realtek,rt5677", }, + { .compatible = "realtek,rt5677", RT5677 }, { } }; MODULE_DEVICE_TABLE(of, rt5677_of_match); -#ifdef CONFIG_ACPI static const struct acpi_device_id rt5677_acpi_match[] = { { "RT5677CE", RT5677 }, { } }; MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match); -#endif static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, struct device *dev) @@ -5147,7 +5136,6 @@ static void rt5677_free_irq(struct i2c_client *i2c) static int rt5677_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct rt5677_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5677_priv *rt5677; int ret; unsigned int val; @@ -5159,16 +5147,25 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5677); - rt5677->type = id->driver_data; + if (i2c->dev.of_node) { + const struct of_device_id *match_id; + + match_id = of_match_device(rt5677_of_match, &i2c->dev); + if (match_id) + rt5677->type = (enum rt5677_type)match_id->data; - if (pdata) - rt5677->pdata = *pdata; - else if (i2c->dev.of_node) rt5677_read_device_properties(rt5677, &i2c->dev); - else if (ACPI_HANDLE(&i2c->dev)) + } else if (ACPI_HANDLE(&i2c->dev)) { + const struct acpi_device_id *acpi_id; + + acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev); + if (acpi_id) + rt5677->type = (enum rt5677_type)acpi_id->driver_data; + rt5677_read_acpi_properties(rt5677, &i2c->dev); - else + } else { return -EINVAL; + } /* pow-ldo2 and reset are optional. The codec pins may be statically * connected on the board without gpios. If the gpio device property diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index d46855a42c4087c6305af06c5a1be0d16d153a0a..97239973edc4df2eb26afb845160776474af1579 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -12,7 +12,6 @@ #ifndef __RT5677_H__ #define __RT5677_H__ -#include #include #include @@ -1761,6 +1760,35 @@ enum { RT5677_I2S4_SOURCE = (0x1 << 18), }; +enum rt5677_dmic2_clk { + RT5677_DMIC_CLK1 = 0, + RT5677_DMIC_CLK2 = 1, +}; + +struct rt5677_platform_data { + /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ + bool in1_diff; + bool in2_diff; + bool lout1_diff; + bool lout2_diff; + bool lout3_diff; + /* DMIC2 clock source selection */ + enum rt5677_dmic2_clk dmic2_clk_pin; + + /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ + u8 gpio_config[6]; + + /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */ + unsigned int jd1_gpio; + /* jd2 and jd3 can select 0 ~ 3 as + OFF, GPIO4, GPIO5 and GPIO6 respectively */ + unsigned int jd2_gpio; + unsigned int jd3_gpio; + + /* Set MICBIAS1 VDD 1v8 or 3v3 */ + bool micbias1_vdd_3v3; +}; + struct rt5677_priv { struct snd_soc_codec *codec; struct rt5677_platform_data pdata; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 8f6814c1eb6b34aa7b83c04c87594cca18b90152..f2bb4feba3b67a03bbb9f4bdb5f9f8c7524282ee 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -409,7 +409,7 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol, static int avc_get_threshold(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int db, i; u16 reg = snd_soc_read(codec, SGTL5000_DAP_AVC_THRESHOLD); @@ -442,7 +442,7 @@ static int avc_get_threshold(struct snd_kcontrol *kcontrol, static int avc_put_threshold(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int db; u16 reg; @@ -1248,7 +1248,7 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver sgtl5000_driver = { +static const struct snd_soc_codec_driver sgtl5000_driver = { .probe = sgtl5000_probe, .remove = sgtl5000_remove, .set_bias_level = sgtl5000_set_bias_level, diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 5344f4aa8fde74bdb78f302aa711100e391cd3d5..354dc0d64f11fbd29f59d324c8fd4fb9449acaee 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -236,7 +236,7 @@ static struct regmap *si476x_get_regmap(struct device *dev) return dev_get_regmap(dev->parent, NULL); } -static struct snd_soc_codec_driver soc_codec_dev_si476x = { +static const struct snd_soc_codec_driver soc_codec_dev_si476x = { .get_regmap = si476x_get_regmap, .component_driver = { .dapm_widgets = si476x_dapm_widgets, diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 6bfd25c289d1924b4cc3d33892dba97e3366a351..7ae8c181d1a4284aebe5e6095a897df3a6c73854 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -429,13 +429,15 @@ static int sirf_audio_codec_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = { +static const struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = { .probe = sirf_audio_codec_probe, .remove = sirf_audio_codec_remove, - .dapm_widgets = sirf_audio_codec_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), - .dapm_routes = sirf_audio_codec_map, - .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), + .component_driver = { + .dapm_widgets = sirf_audio_codec_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), + .dapm_routes = sirf_audio_codec_map, + .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), + }, .idle_bias_off = true, }; diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index eae54c37cff948fcb38f0665d0a3dfd16e1acba1..887923e688499090cf16ef4b4be15da6320a2904 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -883,7 +883,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver sn95031_codec = { +static const struct snd_soc_codec_driver sn95031_codec = { .probe = sn95031_codec_probe, .set_bias_level = sn95031_set_vaud_bias, .idle_bias_off = true, diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 234f87b54838b964d6c42ab5db5c0214824b5707..7acd05140a810c53065186ce6aa6dfa22235c6f7 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c @@ -37,7 +37,7 @@ static const struct snd_soc_dapm_route dir_routes[] = { SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) -static struct snd_soc_codec_driver soc_codec_spdif_dir = { +static const struct snd_soc_codec_driver soc_codec_spdif_dir = { .component_driver = { .dapm_widgets = dir_widgets, .num_dapm_widgets = ARRAY_SIZE(dir_widgets), diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index ee367536a4980a930984f386e515a84f3517de9f..063a64ff82d3ed9c764f917b22f22ff291d3c3d1 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c @@ -37,7 +37,7 @@ static const struct snd_soc_dapm_route dit_routes[] = { { "spdif-out", NULL, "Playback" }, }; -static struct snd_soc_codec_driver soc_codec_spdif_dit = { +static const struct snd_soc_codec_driver soc_codec_spdif_dit = { .component_driver = { .dapm_widgets = dit_widgets, .num_dapm_widgets = ARRAY_SIZE(dit_widgets), diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 38a85f3adc802ffea8c577065e69e9f9617ec081..15486fd16269d1719d8d080d1e939c0208b309ae 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -710,7 +710,7 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id, SSM2518_POWER1_NO_BCLK, val); } -static struct snd_soc_codec_driver ssm2518_codec_driver = { +static const struct snd_soc_codec_driver ssm2518_codec_driver = { .set_bias_level = ssm2518_set_bias_level, .set_sysclk = ssm2518_set_sysclk, .idle_bias_off = true, diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 993bde29ca1bcc6e611bf8d7b7b1f83caa0ce396..9b341c23f62bdf26f2f007efb76c8709104dc48a 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -591,7 +591,7 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec) return ret; } -static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { +static const struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { .probe = ssm260x_codec_probe, .resume = ssm2602_resume, .set_bias_level = ssm2602_set_bias_level, diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index a622623e8558a44090a0ec4869f2aff3f70aa524..4afeddef77285386959bf106b66c5ac6b91e0c41 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -417,7 +417,7 @@ static struct snd_soc_dai_driver ssm4567_dai = { .ops = &ssm4567_dai_ops, }; -static struct snd_soc_codec_driver ssm4567_codec_driver = { +static const struct snd_soc_codec_driver ssm4567_codec_driver = { .set_bias_level = ssm4567_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 0790ae8530d96dba77d25165aefb8f5f2ad88779..5b888476d9ff110b26cc6d42f1a7c808f05027ea 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -847,8 +847,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, msleep(300); sta32x_watchdog_stop(sta32x); - if (sta32x->gpiod_nreset) - gpiod_set_value(sta32x->gpiod_nreset, 0); + gpiod_set_value(sta32x->gpiod_nreset, 0); regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 9de7fe8af25508203ed9b9fa1f31491c2cdcee58..c66363a2cac7150e7240b1fd1c52bf547cf219e6 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -307,7 +307,7 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { +static const struct snd_soc_codec_driver soc_codec_dev_stac9766 = { .component_driver = { .controls = stac9766_snd_ac97_controls, .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 8840f72f3c4ad7f2a2b5f8bcb0cb54745d8dfbf1..87307dd0f12e8feab5a3e163a4cdec60d8333750 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -192,7 +192,7 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec, * pll_clk = (.5 * pll_clkin * J.D) / 2^p * Need to fill in J and D here based on incoming freq */ - unsigned int d; + unsigned int d, q, t; u8 j; u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK; u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1); @@ -200,9 +200,12 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec, p = (p >> 7); recalc: - j = (pll_clk * 2 * (1 << p)) / pll_clkin; - d = (pll_clk * 2 * (1 << p)) % pll_clkin; - d /= (pll_clkin / 10000); + t = (pll_clk * 2) << p; + j = t / pll_clkin; + d = t % pll_clkin; + t = pll_clkin / 10000; + q = d / (t + 1); + d = q + ((9999 - pll_clkin % 10000) * (d / t - q)) / 10000; if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) { if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) { @@ -660,7 +663,7 @@ static int tas2552_resume(struct snd_soc_codec *codec) #define tas2552_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_tas2552 = { +static const struct snd_soc_codec_driver soc_codec_dev_tas2552 = { .probe = tas2552_codec_probe, .remove = tas2552_codec_remove, .suspend = tas2552_suspend, diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index b7de857abb16bd5fa4cc28abdf76332040a23234..199272d5cb6a84cff97e74acd750b24ffe7b230d 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -885,7 +885,7 @@ static int tas5086_remove(struct snd_soc_codec *codec) return 0; }; -static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { +static const struct snd_soc_codec_driver soc_codec_dev_tas5086 = { .probe = tas5086_probe, .remove = tas5086_remove, .suspend = tas5086_soc_suspend, diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index c65b917598d2e20e7a93f3759c86e1f59bdf15f4..a736a2a6976c2fb6eefd2994c413ea35159b3724 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c @@ -483,7 +483,7 @@ static const struct snd_soc_dapm_route tas5720_audio_map[] = { { "OUT", NULL, "DAC" }, }; -static struct snd_soc_codec_driver soc_codec_dev_tas5720 = { +static const struct snd_soc_codec_driver soc_codec_dev_tas5720 = { .probe = tas5720_codec_probe, .remove = tas5720_codec_remove, .suspend = tas5720_suspend, @@ -507,7 +507,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5720 = { #define TAS5720_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\ SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops tas5720_speaker_dai_ops = { +static const struct snd_soc_dai_ops tas5720_speaker_dai_ops = { .hw_params = tas5720_hw_params, .set_fmt = tas5720_set_dai_fmt, .set_tdm_slot = tas5720_set_dai_tdm_slot, diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 628a8eeaab689eb85b6d3dba54ec5a98aefe6da0..3d42138a7974c0c3df1e2b10207ff54b37c5c229 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -576,7 +576,7 @@ static int tlv320aic23_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { +static const struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { .probe = tlv320aic23_codec_probe, .resume = tlv320aic23_resume, .set_bias_level = tlv320aic23_set_bias_level, diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 14aa96d417198500bf94a037e58592fad654119f..89421caaeb707709a3ee6a9c4876f71677cdd1d7 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -319,7 +319,7 @@ static int aic26_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver aic26_soc_codec_dev = { +static const struct snd_soc_codec_driver aic26_soc_codec_dev = { .probe = aic26_probe, .component_driver = { .controls = aic26_snd_controls, diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index d7d03c92cb8a6103b4c9db2148fe706e3bf68cfe..54a87a905eb63a4cc94e0d2f214992a1011d2cc2 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1185,7 +1185,7 @@ static int aic31xx_codec_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_driver_aic31xx = { +static const struct snd_soc_codec_driver soc_codec_driver_aic31xx = { .probe = aic31xx_codec_probe, .remove = aic31xx_codec_remove, .set_bias_level = aic31xx_set_bias_level, diff --git a/sound/soc/codecs/tlv320aic32x4-i2c.c b/sound/soc/codecs/tlv320aic32x4-i2c.c index 59606cf3008f26a5694fe730df79d12f902422c3..385fa2e9525abe2c89fc624baef239b2541b7328 100644 --- a/sound/soc/codecs/tlv320aic32x4-i2c.c +++ b/sound/soc/codecs/tlv320aic32x4-i2c.c @@ -47,12 +47,14 @@ static int aic32x4_i2c_remove(struct i2c_client *i2c) static const struct i2c_device_id aic32x4_i2c_id[] = { { "tlv320aic32x4", 0 }, + { "tlv320aic32x6", 1 }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); static const struct of_device_id aic32x4_of_id[] = { { .compatible = "ti,tlv320aic32x4", }, + { .compatible = "ti,tlv320aic32x6", }, { /* senitel */ } }; MODULE_DEVICE_TABLE(of, aic32x4_of_id); diff --git a/sound/soc/codecs/tlv320aic32x4-spi.c b/sound/soc/codecs/tlv320aic32x4-spi.c index 724fcdd491b212449527a08e7e900421dfecc44e..07d78ae51e05c77bbd0a93410d0df2449be5d759 100644 --- a/sound/soc/codecs/tlv320aic32x4-spi.c +++ b/sound/soc/codecs/tlv320aic32x4-spi.c @@ -48,12 +48,14 @@ static int aic32x4_spi_remove(struct spi_device *spi) static const struct spi_device_id aic32x4_spi_id[] = { { "tlv320aic32x4", 0 }, + { "tlv320aic32x6", 1 }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, aic32x4_spi_id); static const struct of_device_id aic32x4_of_id[] = { { .compatible = "ti,tlv320aic32x4", }, + { .compatible = "ti,tlv320aic32x6", }, { /* senitel */ } }; MODULE_DEVICE_TABLE(of, aic32x4_of_id); diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 28fdfc5ec54430d82083bc2e62d727ae5b046699..e694f5f04eb90c6ef94e9fcb251ba450612ba5a4 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -74,6 +74,152 @@ struct aic32x4_priv { struct regulator *supply_iov; struct regulator *supply_dv; struct regulator *supply_av; + + struct aic32x4_setup_data *setup; + struct device *dev; +}; + +static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + + val = snd_soc_read(codec, AIC32X4_DINCTL); + + ucontrol->value.integer.value[0] = (val & 0x01); + + return 0; +}; + +static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + u8 gpio_check; + + val = snd_soc_read(codec, AIC32X4_DOUTCTL); + gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED); + if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) { + printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP2_GPIO_OUT_HIGH)) + return 0; + + if (ucontrol->value.integer.value[0]) + val |= ucontrol->value.integer.value[0]; + else + val &= ~AIC32X4_MFP2_GPIO_OUT_HIGH; + + snd_soc_write(codec, AIC32X4_DOUTCTL, val); + + return 0; +}; + +static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + + val = snd_soc_read(codec, AIC32X4_SCLKCTL); + + ucontrol->value.integer.value[0] = (val & 0x01); + + return 0; +}; + +static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + u8 gpio_check; + + val = snd_soc_read(codec, AIC32X4_MISOCTL); + gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED); + if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) { + printk(KERN_ERR "%s: MFP4 is not configure as a GPIO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP5_GPIO_OUT_HIGH)) + return 0; + + if (ucontrol->value.integer.value[0]) + val |= ucontrol->value.integer.value[0]; + else + val &= ~AIC32X4_MFP5_GPIO_OUT_HIGH; + + snd_soc_write(codec, AIC32X4_MISOCTL, val); + + return 0; +}; + +static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + + val = snd_soc_read(codec, AIC32X4_GPIOCTL); + ucontrol->value.integer.value[0] = ((val & 0x2) >> 1); + + return 0; +}; + +static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + u8 gpio_check; + + val = snd_soc_read(codec, AIC32X4_GPIOCTL); + gpio_check = (val & AIC32X4_MFP5_GPIO_OUTPUT); + if (gpio_check != AIC32X4_MFP5_GPIO_OUTPUT) { + printk(KERN_ERR "%s: MFP5 is not configure as a GPIO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0] == (val & 0x1)) + return 0; + + if (ucontrol->value.integer.value[0]) + val |= ucontrol->value.integer.value[0]; + else + val &= 0xfe; + + snd_soc_write(codec, AIC32X4_GPIOCTL, val); + + return 0; +}; + +static const struct snd_kcontrol_new aic32x4_mfp1[] = { + SOC_SINGLE_BOOL_EXT("MFP1 GPIO", 0, aic32x4_get_mfp1_gpio, NULL), +}; + +static const struct snd_kcontrol_new aic32x4_mfp2[] = { + SOC_SINGLE_BOOL_EXT("MFP2 GPIO", 0, NULL, aic32x4_set_mfp2_gpio), +}; + +static const struct snd_kcontrol_new aic32x4_mfp3[] = { + SOC_SINGLE_BOOL_EXT("MFP3 GPIO", 0, aic32x4_get_mfp3_gpio, NULL), +}; + +static const struct snd_kcontrol_new aic32x4_mfp4[] = { + SOC_SINGLE_BOOL_EXT("MFP4 GPIO", 0, NULL, aic32x4_set_mfp4_gpio), +}; + +static const struct snd_kcontrol_new aic32x4_mfp5[] = { + SOC_SINGLE_BOOL_EXT("MFP5 GPIO", 0, aic32x4_get_mfp5_gpio, + aic32x4_set_mfp5_gpio), }; /* 0dB min, 0.5dB steps */ @@ -734,6 +880,52 @@ static struct snd_soc_dai_driver aic32x4_dai = { .symmetric_rates = 1, }; +static void aic32x4_setup_gpios(struct snd_soc_codec *codec) +{ + struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); + + /* setup GPIO functions */ + /* MFP1 */ + if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_DINCTL, + aic32x4->setup->gpio_func[0]); + snd_soc_add_codec_controls(codec, aic32x4_mfp1, + ARRAY_SIZE(aic32x4_mfp1)); + } + + /* MFP2 */ + if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_DOUTCTL, + aic32x4->setup->gpio_func[1]); + snd_soc_add_codec_controls(codec, aic32x4_mfp2, + ARRAY_SIZE(aic32x4_mfp2)); + } + + /* MFP3 */ + if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_SCLKCTL, + aic32x4->setup->gpio_func[2]); + snd_soc_add_codec_controls(codec, aic32x4_mfp3, + ARRAY_SIZE(aic32x4_mfp3)); + } + + /* MFP4 */ + if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_MISOCTL, + aic32x4->setup->gpio_func[3]); + snd_soc_add_codec_controls(codec, aic32x4_mfp4, + ARRAY_SIZE(aic32x4_mfp4)); + } + + /* MFP5 */ + if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_GPIOCTL, + aic32x4->setup->gpio_func[4]); + snd_soc_add_codec_controls(codec, aic32x4_mfp5, + ARRAY_SIZE(aic32x4_mfp5)); + } +} + static int aic32x4_codec_probe(struct snd_soc_codec *codec) { struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); @@ -746,6 +938,9 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec) snd_soc_write(codec, AIC32X4_RESET, 0x01); + if (aic32x4->setup) + aic32x4_setup_gpios(codec); + /* Power platform configuration */ if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN | @@ -792,7 +987,7 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { +static const struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { .probe = aic32x4_codec_probe, .set_bias_level = aic32x4_set_bias_level, .suspend_bias_off = true, @@ -810,10 +1005,20 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, struct device_node *np) { + struct aic32x4_setup_data *aic32x4_setup; + + aic32x4_setup = devm_kzalloc(aic32x4->dev, sizeof(*aic32x4_setup), + GFP_KERNEL); + if (!aic32x4_setup) + return -ENOMEM; + aic32x4->swapdacs = false; aic32x4->micpga_routing = 0; aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0); + if (of_property_read_u32_array(np, "aic32x4-gpio-func", + aic32x4_setup->gpio_func, 5) >= 0) + aic32x4->setup = aic32x4_setup; return 0; } @@ -932,6 +1137,7 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap) if (aic32x4 == NULL) return -ENOMEM; + aic32x4->dev = dev; dev_set_drvdata(dev, aic32x4); if (pdata) { diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h index a197dd51addc242ab71ac4fc3bb581eb7648fb66..da7cec482bcbf3cc6f9db4f714342335c1cda60e 100644 --- a/sound/soc/codecs/tlv320aic32x4.h +++ b/sound/soc/codecs/tlv320aic32x4.h @@ -44,8 +44,11 @@ int aic32x4_remove(struct device *dev); #define AIC32X4_IFACE4 31 #define AIC32X4_IFACE5 32 #define AIC32X4_IFACE6 33 +#define AIC32X4_GPIOCTL 52 #define AIC32X4_DOUTCTL 53 #define AIC32X4_DINCTL 54 +#define AIC32X4_MISOCTL 55 +#define AIC32X4_SCLKCTL 56 #define AIC32X4_DACSPB 60 #define AIC32X4_ADCSPB 61 #define AIC32X4_DACSETUP 63 diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 29bf8c81ae028c0dad3dbff8c4cde406bf693c07..06f92571eba4622a89ae808911fd0b510ec2eed2 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -93,6 +93,8 @@ struct aic3x_priv { /* Selects the micbias voltage */ enum aic3x_micbias_voltage micbias_vg; + /* Output Common-Mode Voltage */ + u8 ocmv; }; static const struct reg_default aic3x_reg[] = { @@ -1572,6 +1574,10 @@ static int aic3x_init(struct snd_soc_codec *codec) break; } + /* Output common-mode voltage = 1.5 V */ + snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK, + aic3x->ocmv << HPOUT_SC_OCMV_SHIFT); + return 0; } @@ -1684,7 +1690,7 @@ static int aic3x_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_aic3x = { +static const struct snd_soc_codec_driver soc_codec_dev_aic3x = { .set_bias_level = aic3x_set_bias_level, .idle_bias_off = true, .probe = aic3x_probe, @@ -1699,6 +1705,43 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { }, }; +static void aic3x_configure_ocmv(struct i2c_client *client) +{ + struct device_node *np = client->dev.of_node; + struct aic3x_priv *aic3x = i2c_get_clientdata(client); + u32 value; + int dvdd, avdd; + + if (np && !of_property_read_u32(np, "ai3x-ocmv", &value)) { + /* OCMV setting is forced by DT */ + if (value <= 3) { + aic3x->ocmv = value; + return; + } + } + + dvdd = regulator_get_voltage(aic3x->supplies[1].consumer); + avdd = regulator_get_voltage(aic3x->supplies[2].consumer); + + if (avdd > 3600000 || dvdd > 1950000) { + dev_warn(&client->dev, + "Too high supply voltage(s) AVDD: %d, DVDD: %d\n", + avdd, dvdd); + } else if (avdd == 3600000 && dvdd == 1950000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_8V; + } else if (avdd > 3300000 && dvdd > 1800000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_65V; + } else if (avdd > 3000000 && dvdd > 1650000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_5V; + } else if (avdd >= 2700000 && dvdd >= 1525000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_35V; + } else { + dev_warn(&client->dev, + "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n", + avdd, dvdd); + } +} + /* * AIC3X 2 wire address can be up to 4 devices with device addresses * 0x18, 0x19, 0x1A, 0x1B @@ -1816,6 +1859,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, goto err_gpio; } + aic3x_configure_ocmv(i2c); + if (aic3x->model == AIC3X_MODEL_3007) { ret = regmap_register_patch(aic3x->regmap, aic3007_class_d, ARRAY_SIZE(aic3007_class_d)); diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 89fa692df206d3c5f1bbf9c3c1eca7700f5a7a6a..34c35196aa0dfcc663b239103ac733b5e0551d23 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -243,6 +243,14 @@ #define MICBIAS_LEVEL_SHIFT (6) #define MICBIAS_LEVEL_MASK (3 << 6) +/* HPOUT_SC */ +#define HPOUT_SC_OCMV_MASK (3 << 6) +#define HPOUT_SC_OCMV_SHIFT (6) +#define HPOUT_SC_OCMV_1_35V 0 +#define HPOUT_SC_OCMV_1_5V 1 +#define HPOUT_SC_OCMV_1_65V 2 +#define HPOUT_SC_OCMV_1_8V 3 + /* headset detection / button API */ /* The AIC3x supports detection of stereo headsets (GND + left + right signal) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 7bcf01efdf9ad0df4253c40958df35fc1f01e5f7..5b94a151539ce1f828e4af7feb643be9d62eb7fd 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1433,7 +1433,7 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { +static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { .read = dac33_read_reg_cache, .write = dac33_write_locked, .set_bias_level = dac33_set_bias_level, diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a2104d68169d9e6bc9aa30fe8269070a6dc88e40..c482b2e7a7d2a55d7ead20e56a680da6c0791378 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -2191,7 +2191,7 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { +static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .probe = twl4030_soc_probe, .remove = twl4030_soc_remove, .read = twl4030_read, diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 2b6ad09e08868323e3e9bef25bd26b33bb5e2949..1773ff84ee3b23a659341efed47aa0d41770b78b 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1123,8 +1123,8 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->plug_irq = platform_get_irq(pdev, 0); if (priv->plug_irq < 0) { - dev_err(codec->dev, "invalid irq\n"); - return -EINVAL; + dev_err(codec->dev, "invalid irq: %d\n", priv->plug_irq); + return priv->plug_irq; } INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); @@ -1155,7 +1155,7 @@ static int twl6040_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { +static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .probe = twl6040_probe, .remove = twl6040_remove, .read = twl6040_read, diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 5fdee874406d72b1d444a9e3823dbe34c41e66cf..77c9cc4467b82d65f3f595a1cca5d6cddffe8fe8 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -518,7 +518,7 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_uda134x = { +static const struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, .set_bias_level = uda134x_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 61cdc79840e70743229f5919bfc5aa3293f38270..926c81ae81853477241c1deecb5400a226f1665a 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -720,7 +720,7 @@ static int uda1380_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { +static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .probe = uda1380_probe, .read = uda1380_read_reg_cache, .write = uda1380_write, diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index fcffb6e707d9b8fcdacddb77d445eb5d738837ef..942f1644973e8dd52b4b68d71cbc73123b249cd5 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -480,7 +480,7 @@ static int wl1273_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_wl1273 = { +static const struct snd_soc_codec_driver soc_codec_dev_wl1273 = { .probe = wl1273_probe, .remove = wl1273_remove, diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 1fe358e6be6126572a924911742f111bc7eb5c44..72486bf072f2854de417804afab7002158f8b333 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2017,7 +2017,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = { }, }; -static struct snd_compr_ops wm5102_compr_ops = { +static const struct snd_compr_ops wm5102_compr_ops = { .open = wm5102_open, .free = wm_adsp_compr_free, .set_params = wm_adsp_compr_set_params, @@ -2027,7 +2027,7 @@ static struct snd_compr_ops wm5102_compr_ops = { .copy = wm_adsp_compr_copy, }; -static struct snd_soc_platform_driver wm5102_compr_platform = { +static const struct snd_soc_platform_driver wm5102_compr_platform = { .compr_ops = &wm5102_compr_ops, }; diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 1bc942152effa8f22e7202abd9d245a7ed8eb587..858a24fc28e80065052d4bff98831680197c5927 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2372,7 +2372,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = { }, }; -static struct snd_compr_ops wm5110_compr_ops = { +static const struct snd_compr_ops wm5110_compr_ops = { .open = wm5110_open, .free = wm_adsp_compr_free, .set_params = wm_adsp_compr_set_params, @@ -2382,7 +2382,7 @@ static struct snd_compr_ops wm5110_compr_ops = { .copy = wm_adsp_compr_copy, }; -static struct snd_soc_platform_driver wm5110_compr_platform = { +static const struct snd_soc_platform_driver wm5110_compr_platform = { .compr_ops = &wm5110_compr_ops, }; diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 6d0a2723bfde7e06956934d1792f719263353699..c7c33e98fbcb94424cda05b76a9ecc63753719f7 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -100,7 +100,7 @@ static const struct snd_soc_dapm_route wm8523_dapm_routes[] = { { "LINEVOUTR", NULL, "DAC" }, }; -static struct { +static const struct { int value; int ratio; } lrclk_ratios[WM8523_NUM_RATES] = { @@ -113,10 +113,10 @@ static struct { { 7, 1152 }, }; -static struct { +static const struct { int value; int ratio; -} bclk_ratios[WM8523_NUM_RATES] = { +} bclk_ratios[] = { { 2, 32 }, { 3, 64 }, { 4, 128 }, diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c new file mode 100644 index 0000000000000000000000000000000000000000..856a6950a451a3c10636c9fd898e390bfe3348ed --- /dev/null +++ b/sound/soc/codecs/wm8524.c @@ -0,0 +1,261 @@ +/* + * wm8524.c -- WM8524 ALSA SoC Audio driver + * + * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2017 NXP + * + * Based on WM8523 ALSA SoC Audio driver written by Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WM8524_NUM_RATES 7 + +/* codec private data */ +struct wm8524_priv { + struct gpio_desc *mute; + unsigned int sysclk; + unsigned int rate_constraint_list[WM8524_NUM_RATES]; + struct snd_pcm_hw_constraint_list rate_constraint; +}; + + +static const struct snd_soc_dapm_widget wm8524_dapm_widgets[] = { +SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_OUTPUT("LINEVOUTL"), +SND_SOC_DAPM_OUTPUT("LINEVOUTR"), +}; + +static const struct snd_soc_dapm_route wm8524_dapm_routes[] = { + { "LINEVOUTL", NULL, "DAC" }, + { "LINEVOUTR", NULL, "DAC" }, +}; + +static const struct { + int value; + int ratio; +} lrclk_ratios[WM8524_NUM_RATES] = { + { 1, 128 }, + { 2, 192 }, + { 3, 256 }, + { 4, 384 }, + { 5, 512 }, + { 6, 768 }, + { 7, 1152 }, +}; + +static int wm8524_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + + /* The set of sample rates that can be supported depends on the + * MCLK supplied to the CODEC - enforce this. + */ + if (!wm8524->sysclk) { + dev_err(codec->dev, + "No MCLK configured, call set_sysclk() on init\n"); + return -EINVAL; + } + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &wm8524->rate_constraint); + + gpiod_set_value_cansleep(wm8524->mute, 1); + + return 0; +} + +static void wm8524_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + + gpiod_set_value_cansleep(wm8524->mute, 0); +} + +static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + int i, j = 0; + + wm8524->sysclk = freq; + + wm8524->rate_constraint.count = 0; + for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { + val = freq / lrclk_ratios[i].ratio; + /* Check that it's a standard rate since core can't + * cope with others and having the odd rates confuses + * constraint matching. + */ + switch (val) { + case 8000: + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + case 176400: + case 192000: + dev_dbg(codec->dev, "Supported sample rate: %dHz\n", + val); + wm8524->rate_constraint_list[j++] = val; + wm8524->rate_constraint.count++; + break; + default: + dev_dbg(codec->dev, "Skipping sample rate: %dHz\n", + val); + } + } + + /* Need at least one supported rate... */ + if (wm8524->rate_constraint.count == 0) + return -EINVAL; + + return 0; +} + +static int wm8524_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK | + SND_SOC_DAIFMT_MASTER_MASK); + + if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS)) { + dev_err(codec_dai->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + return 0; +} + +static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(dai->codec); + + if (wm8524->mute) + gpiod_set_value_cansleep(wm8524->mute, mute); + + return 0; +} + +#define WM8524_RATES SNDRV_PCM_RATE_8000_192000 + +#define WM8524_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +static const struct snd_soc_dai_ops wm8524_dai_ops = { + .startup = wm8524_startup, + .shutdown = wm8524_shutdown, + .set_sysclk = wm8524_set_dai_sysclk, + .set_fmt = wm8524_set_fmt, + .mute_stream = wm8524_mute_stream, +}; + +static struct snd_soc_dai_driver wm8524_dai = { + .name = "wm8524-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8524_RATES, + .formats = WM8524_FORMATS, + }, + .ops = &wm8524_dai_ops, +}; + +static int wm8524_probe(struct snd_soc_codec *codec) +{ + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + + wm8524->rate_constraint.list = &wm8524->rate_constraint_list[0]; + wm8524->rate_constraint.count = + ARRAY_SIZE(wm8524->rate_constraint_list); + + return 0; +} + +static const struct snd_soc_codec_driver soc_codec_dev_wm8524 = { + .probe = wm8524_probe, + + .component_driver = { + .dapm_widgets = wm8524_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8524_dapm_widgets), + .dapm_routes = wm8524_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8524_dapm_routes), + }, +}; + +static const struct of_device_id wm8524_of_match[] = { + { .compatible = "wlf,wm8524" }, + { /* sentinel*/ } +}; +MODULE_DEVICE_TABLE(of, wm8524_of_match); + +static int wm8524_codec_probe(struct platform_device *pdev) +{ + struct wm8524_priv *wm8524; + int ret; + + wm8524 = devm_kzalloc(&pdev->dev, sizeof(struct wm8524_priv), + GFP_KERNEL); + if (wm8524 == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, wm8524); + + wm8524->mute = devm_gpiod_get(&pdev->dev, "wlf,mute", GPIOD_OUT_LOW); + if (IS_ERR(wm8524->mute)) { + ret = PTR_ERR(wm8524->mute); + dev_err(&pdev->dev, "Failed to get mute line: %d\n", ret); + return ret; + } + + ret = snd_soc_register_codec(&pdev->dev, + &soc_codec_dev_wm8524, &wm8524_dai, 1); + if (ret < 0) + dev_err(&pdev->dev, "Failed to register codec: %d\n", ret); + + return ret; +} + +static int wm8524_codec_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static struct platform_driver wm8524_codec_driver = { + .probe = wm8524_codec_probe, + .remove = wm8524_codec_remove, + .driver = { + .name = "wm8524-codec", + .of_match_table = wm8524_of_match, + }, +}; +module_platform_driver(wm8524_codec_driver); + +MODULE_DESCRIPTION("ASoC WM8524 driver"); +MODULE_AUTHOR("Mihai Serban "); +MODULE_ALIAS("platform:wm8524-codec"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index af95d648265b3e92e345101542b332aee35191d4..fc69b87443d80489382b97332de6d5ad12a58ec8 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -623,8 +623,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) return ret; } - if (wm8804->reset) - gpiod_set_value_cansleep(wm8804->reset, 1); + gpiod_set_value_cansleep(wm8804->reset, 1); ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); if (ret < 0) { diff --git a/sound/soc/codecs/zx_aud96p22.c b/sound/soc/codecs/zx_aud96p22.c index 032fb7cf6cbdfce68f00577c41243561b9534742..ca1932d137385f054cb53cf69056940a6284792c 100644 --- a/sound/soc/codecs/zx_aud96p22.c +++ b/sound/soc/codecs/zx_aud96p22.c @@ -261,7 +261,7 @@ static const struct snd_soc_dapm_route aud96p22_dapm_routes[] = { { "LINEOUTMN", NULL, "LD2" }, }; -static struct snd_soc_codec_driver aud96p22_driver = { +static const struct snd_soc_codec_driver aud96p22_driver = { .component_driver = { .controls = aud96p22_snd_controls, .num_controls = ARRAY_SIZE(aud96p22_snd_controls), @@ -312,7 +312,7 @@ static int aud96p22_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } -static struct snd_soc_dai_ops aud96p22_dai_ops = { +static const struct snd_soc_dai_ops aud96p22_dai_ops = { .set_fmt = aud96p22_set_fmt, }; @@ -382,7 +382,7 @@ static int aud96p22_i2c_remove(struct i2c_client *i2c) return 0; } -const struct of_device_id aud96p22_dt_ids[] = { +static const struct of_device_id aud96p22_dt_ids[] = { { .compatible = "zte,zx-aud96p22", }, { } }; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 56ec1d301ac2927b5ebabb123a28c2a56dbc532f..f395bbc7c354549d089ecfbb8a633e0d4e2aadac 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1602,8 +1602,6 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of( pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dev_err(&pdev->dev, - "Failed to allocate memory for pdata\n"); ret = -ENOMEM; return pdata; } @@ -1853,6 +1851,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mcasp->context.xrsr_regs = devm_kzalloc(&pdev->dev, sizeof(u32) * mcasp->num_serializer, GFP_KERNEL); + if (!mcasp->context.xrsr_regs) { + ret = -ENOMEM; + goto err; + } #endif mcasp->serial_dir = pdata->serial_dir; mcasp->version = pdata->version; diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index c77d9218795adba25d2ae54665a8e21b769d6ee7..5415b72393fafac24fd685f0bed9c7740083975e 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -210,11 +210,8 @@ static int davinci_vcif_probe(struct platform_device *pdev) davinci_vcif_dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_vcif_dev), GFP_KERNEL); - if (!davinci_vcif_dev) { - dev_dbg(&pdev->dev, - "could not allocate memory for private data\n"); + if (!davinci_vcif_dev) return -ENOMEM; - } /* DMA tx params */ davinci_vcif_dev->davinci_vc = davinci_vc; diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index 91606763818089ffe2c4d058eb214f1e5714765a..e27e21f8569a0e9719c2c90a801189dd0507c8a3 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -381,7 +381,7 @@ static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) return ret; } -static struct snd_soc_dai_ops dw_i2s_dai_ops = { +static const struct snd_soc_dai_ops dw_i2s_dai_ops = { .startup = dw_i2s_startup, .shutdown = dw_i2s_shutdown, .hw_params = dw_i2s_hw_params, @@ -617,10 +617,8 @@ static int dw_i2s_probe(struct platform_device *pdev) const char *clk_id; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_warn(&pdev->dev, "kzalloc fail\n"); + if (!dev) return -ENOMEM; - } dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); if (!dw_i2s_dai) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 9998aea2359794fff4b9ccb82b7ab3ee375437aa..2db4d0c80d332cbf406273f822d1a061114cf250 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -683,7 +683,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&priv->card, priv); ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); - if (ret) + if (ret && ret != -EPROBE_DEFER) dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); asrc_fail: diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 8cfffa70c144aff3c8f8157d3e7c000c85236620..806d39927318f97d55baf39739f8b7e14467f438 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -542,7 +542,7 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static struct snd_soc_dai_ops fsl_asrc_dai_ops = { +static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { .hw_params = fsl_asrc_dai_hw_params, .hw_free = fsl_asrc_dai_hw_free, .trigger = fsl_asrc_dai_trigger, diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 282d841840b1cfbea8d1ca97c3b764d21101d15c..e1b97e59275a9ebdc31f85cc7e8aa883b0ad1700 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -20,7 +20,7 @@ #define FSL_ASRC_DMABUF_SIZE (256 * 1024) -static struct snd_pcm_hardware snd_imx_hardware = { +static const struct snd_pcm_hardware snd_imx_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -279,10 +279,8 @@ static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream) struct fsl_asrc_pair *pair; pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL); - if (!pair) { - dev_err(dev, "failed to allocate pair\n"); + if (!pair) return -ENOMEM; - } pair->asrc_priv = asrc_priv; diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index ccadefceeff2c00e1e6e9ed2f74225d00a9a3cde..0c11f434a37461fb6cf9786ed32d36083b7acb9f 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -63,7 +63,6 @@ struct dma_object { struct ccsr_dma_channel __iomem *channel; unsigned int irq; bool assigned; - char path[1]; }; /* @@ -870,7 +869,7 @@ static struct device_node *find_ssi_node(struct device_node *dma_channel_np) return NULL; } -static struct snd_pcm_ops fsl_dma_ops = { +static const struct snd_pcm_ops fsl_dma_ops = { .open = fsl_dma_open, .close = fsl_dma_close, .ioctl = snd_pcm_lib_ioctl, @@ -897,20 +896,18 @@ static int fsl_soc_dma_probe(struct platform_device *pdev) ret = of_address_to_resource(ssi_np, 0, &res); if (ret) { - dev_err(&pdev->dev, "could not determine resources for %s\n", - ssi_np->full_name); + dev_err(&pdev->dev, "could not determine resources for %pOF\n", + ssi_np); of_node_put(ssi_np); return ret; } - dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL); + dma = kzalloc(sizeof(*dma), GFP_KERNEL); if (!dma) { - dev_err(&pdev->dev, "could not allocate dma object\n"); of_node_put(ssi_np); return -ENOMEM; } - strcpy(dma->path, np->full_name); dma->dai.ops = &fsl_dma_ops; dma->dai.pcm_new = fsl_dma_new; dma->dai.pcm_free = fsl_dma_free_dma_buffers; diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 809a069d490b1a2ba91eaaca599b387f0d496b40..cef79a1a620b7dc3105572e6987c358da8db8a30 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -620,7 +620,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static struct snd_soc_dai_ops fsl_esai_dai_ops = { +static const struct snd_soc_dai_ops fsl_esai_dai_ops = { .startup = fsl_esai_startup, .shutdown = fsl_esai_shutdown, .trigger = fsl_esai_trigger, diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 1ff467c9598a355381981af24bc2a67befbe7713..7e6cc4da00887d25e4c549c273dc3e0b4874c586 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -626,7 +626,7 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops fsl_spdif_dai_ops = { +static const struct snd_soc_dai_ops fsl_spdif_dai_ops = { .startup = fsl_spdif_startup, .hw_params = fsl_spdif_hw_params, .trigger = fsl_spdif_trigger, diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 173cb8496641353b63177acba147278541c36370..64598d1183f8f14613a844333ff6c9c2da21f6bc 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1432,10 +1432,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private), GFP_KERNEL); - if (!ssi_private) { - dev_err(&pdev->dev, "could not allocate DAI object\n"); + if (!ssi_private) return -ENOMEM; - } ssi_private->soc = of_id->data; ssi_private->dev = &pdev->dev; diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index fc57da341d6106e029c6766370421b9cdc97e8f5..392d5eef356d3a8a90cb2b4cb52c07d5520ebbc0 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -268,13 +268,13 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, ret = of_property_read_u32(child, "fsl,audmux-port", &port); if (ret) { - dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n", - child->full_name); + dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%pOF\"\n", + child); continue; } if (!of_property_read_bool(child, "fsl,port-config")) { - dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n", - child->full_name); + dev_warn(&pdev->dev, "child node \"%pOF\" does not have property fsl,port-config\n", + child); continue; } @@ -292,15 +292,15 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, } if (ret != -EOVERFLOW) { - dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n", - i, child->full_name); + dev_err(&pdev->dev, "Failed to read u32 at index %d of child %pOF\n", + i, child); continue; } if (audmux_type == IMX31_AUDMUX) { if (i % 2) { - dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n", - child->full_name); + dev_err(&pdev->dev, "One pdcr value is missing in child node %pOF\n", + child); continue; } imx_audmux_v2_configure_port(port, ptcr, pdcr); diff --git a/sound/soc/fsl/imx-es8328.c b/sound/soc/fsl/imx-es8328.c index 20e7400e2611e41ef057d9b2e22413a7c6a73c98..9953438086e4783f9fd6ea52a26eb99a0e9da00b 100644 --- a/sound/soc/fsl/imx-es8328.c +++ b/sound/soc/fsl/imx-es8328.c @@ -203,9 +203,6 @@ static int imx_es8328_remove(struct platform_device *pdev) { struct imx_es8328_data *data = platform_get_drvdata(pdev); - snd_soc_jack_free_gpios(&headset_jack, ARRAY_SIZE(headset_jack_gpios), - headset_jack_gpios); - snd_soc_unregister_card(&data->card); return 0; diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 92410f7ca1fafab6dcf6132808c758eea49f67c1..4e5fefee111eb285c1005edcbf22dd9d1c47d6f2 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -154,7 +154,7 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream return bytes_to_frames(substream->runtime, iprtd->offset); } -static struct snd_pcm_hardware snd_imx_hardware = { +static const struct snd_pcm_hardware snd_imx_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -227,7 +227,7 @@ static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, return ret; } -static struct snd_pcm_ops imx_pcm_ops = { +static const struct snd_pcm_ops imx_pcm_ops = { .open = snd_imx_open, .close = snd_imx_close, .ioctl = snd_pcm_lib_ioctl, @@ -341,7 +341,7 @@ static void imx_pcm_fiq_free(struct snd_pcm *pcm) imx_pcm_free(pcm); } -static struct snd_soc_platform_driver imx_soc_platform_fiq = { +static const struct snd_soc_platform_driver imx_soc_platform_fiq = { .ops = &imx_pcm_ops, .pcm_new = imx_pcm_fiq_new, .pcm_free = imx_pcm_fiq_free, diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index b95132e2f9dc299d82c783810982c2d5b768fb35..06790615e04eb70dac42167706857b4d7f63498c 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -527,6 +527,10 @@ static int imx_ssi_probe(struct platform_device *pdev) } ssi->irq = platform_get_irq(pdev, 0); + if (ssi->irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq); + return ssi->irq; + } ssi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ssi->clk)) { diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 1f7e70bfbd5506a4088143d8ee9dfff0e059ee2d..e63029f1aabc0b499985226c9624950cb146737c 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -287,7 +287,7 @@ psc_dma_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_pcm_ops psc_dma_ops = { +static const struct snd_pcm_ops psc_dma_ops = { .open = psc_dma_open, .close = psc_dma_close, .hw_free = psc_dma_hw_free, @@ -356,7 +356,7 @@ static void psc_dma_free(struct snd_pcm *pcm) } } -static struct snd_soc_platform_driver mpc5200_audio_dma_platform = { +static const struct snd_soc_platform_driver mpc5200_audio_dma_platform = { .ops = &psc_dma_ops, .pcm_new = &psc_dma_new, .pcm_free = &psc_dma_free, diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 105ec3a6e30df8340d62d1be45e1bb8577956672..488c52f9405fcd2fb7ec909d7fdda4bbf8b36e81 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -95,7 +95,7 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream) asoc_simple_card_clk_disable(&dai_props->codec_dai); } -static struct snd_soc_ops asoc_graph_card_ops = { +static const struct snd_soc_ops asoc_graph_card_ops = { .startup = asoc_graph_card_startup, .shutdown = asoc_graph_card_shutdown, }; @@ -224,9 +224,11 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { ret = asoc_graph_card_dai_link_of(it.node, priv, idx++); - of_node_put(it.node); - if (ret < 0) + if (ret < 0) { + of_node_put(it.node); + return ret; + } } return asoc_simple_card_parse_card_name(card, NULL); @@ -239,10 +241,8 @@ static int asoc_graph_get_dais_count(struct device *dev) int count = 0; int rc; - of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { + of_for_each_phandle(&it, rc, node, "dais", NULL, 0) count++; - of_node_put(it.node); - } return count; } @@ -325,6 +325,7 @@ MODULE_DEVICE_TABLE(of, asoc_graph_of_match); static struct platform_driver asoc_graph_card = { .driver = { .name = "asoc-audio-graph-card", + .pm = &snd_soc_pm_ops, .of_match_table = asoc_graph_of_match, }, .probe = asoc_graph_card_probe, diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c index dcd2df37bc3bfbd78e1f0d7bbb50b5192a89cc2d..a967aa143d51864cb03e3c9f8fcb9c7ea72c8a51 100644 --- a/sound/soc/generic/audio-graph-scu-card.c +++ b/sound/soc/generic/audio-graph-scu-card.c @@ -56,7 +56,7 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream) asoc_simple_card_clk_disable(dai_props); } -static struct snd_soc_ops asoc_graph_card_ops = { +static const struct snd_soc_ops asoc_graph_card_ops = { .startup = asoc_graph_card_startup, .shutdown = asoc_graph_card_shutdown, }; @@ -215,7 +215,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_ep = of_graph_get_remote_endpoint(cpu_ep); rcpu_ep = of_graph_get_remote_endpoint(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(rcpu_ep); @@ -232,8 +231,10 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &daifmt); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } dai_idx = 0; @@ -250,7 +251,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_port = of_graph_get_port_parent(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(codec_port); @@ -266,13 +266,17 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) /* Back-End (= Codec) */ ret = asoc_graph_card_dai_link_of(codec_ep, priv, daifmt, dai_idx++, 0); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } else { /* Front-End (= CPU) */ ret = asoc_graph_card_dai_link_of(cpu_ep, priv, daifmt, dai_idx++, 1); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } } } @@ -306,7 +310,6 @@ static int asoc_graph_get_dais_count(struct device *dev) codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_port = of_graph_get_port_parent(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(codec_port); @@ -398,6 +401,7 @@ MODULE_DEVICE_TABLE(of, asoc_graph_of_match); static struct platform_driver asoc_graph_card = { .driver = { .name = "asoc-audio-graph-scu-card", + .pm = &snd_soc_pm_ops, .of_match_table = asoc_graph_of_match, }, .probe = asoc_graph_card_probe, diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 26d64fa40c9cf1438f43a08d8f45b15ac0184fa9..3751a07de6aac1c6bab6e670abd9c91832fd7f51 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -132,7 +132,7 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card, /* Parse the card name from DT */ ret = snd_soc_of_parse_card_name(card, "label"); - if (ret < 0) { + if (ret < 0 || !card->name) { char prop[128]; snprintf(prop, sizeof(prop), "%sname", prefix); @@ -196,7 +196,11 @@ int asoc_simple_card_parse_clk(struct device *dev, simple_dai->sysclk = clk_get_rate(clk); } - dev_dbg(dev, "%s : sysclk = %d\n", name, simple_dai->sysclk); + if (of_property_read_bool(node, "system-clock-direction-out")) + simple_dai->clk_direction = SND_SOC_CLOCK_OUT; + + dev_dbg(dev, "%s : sysclk = %d, direction %d\n", name, + simple_dai->sysclk, simple_dai->clk_direction); return 0; } @@ -263,6 +267,9 @@ static int asoc_simple_card_get_dai_id(struct device_node *ep) id = i; i++; } + + of_node_put(node); + if (id < 0) return -ENODEV; @@ -282,11 +289,6 @@ int asoc_simple_card_parse_graph_dai(struct device_node *ep, if (!dai_name) return 0; - /* - * of_graph_get_port_parent() will call - * of_node_put(). So, call of_node_get() here - */ - of_node_get(ep); node = of_graph_get_port_parent(ep); /* Get dai->name */ @@ -310,7 +312,8 @@ int asoc_simple_card_init_dai(struct snd_soc_dai *dai, int ret; if (simple_dai->sysclk) { - ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0); + ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, + simple_dai->clk_direction); if (ret && ret != -ENOTSUPP) { dev_err(dai->dev, "simple-card: set_sysclk error\n"); return ret; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index dfaf48ff88b02b8f23413acc6b22552058cf372b..6959a74a6f4919bbb948476a94382872c37d8b85 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -104,12 +104,6 @@ static int asoc_simple_card_init_jack(struct snd_soc_card *card, return 0; } -static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack) -{ - if (gpio_is_valid(sjack->gpio.gpio)) - snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio); -} - static int asoc_simple_card_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -493,10 +487,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev) static int asoc_simple_card_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct simple_card_data *priv = snd_soc_card_get_drvdata(card); - - asoc_simple_card_remove_jack(&priv->hp_jack); - asoc_simple_card_remove_jack(&priv->mic_jack); return asoc_simple_card_clean_reference(card); } diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c index a75b385455c4f62c0f473baea203f94b9c990a8b..48606c63562a7694a83fe7b4d38210908d38ad4e 100644 --- a/sound/soc/generic/simple-scu-card.c +++ b/sound/soc/generic/simple-scu-card.c @@ -191,6 +191,10 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) if (!node) return -EINVAL; + ret = asoc_simple_card_of_parse_widgets(card, PREFIX); + if (ret < 0) + return ret; + ret = asoc_simple_card_of_parse_routing(card, PREFIX, 0); if (ret < 0) return ret; @@ -296,6 +300,7 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match); static struct platform_driver asoc_simple_card = { .driver = { .name = "simple-scu-audio-card", + .pm = &snd_soc_pm_ops, .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c index b193d3beb25330ca6fe8ccb73cda9f8987eefb32..0c8f86d4020e7af3fb3a1ce2e23104f58eb662b8 100644 --- a/sound/soc/hisilicon/hi6210-i2s.c +++ b/sound/soc/hisilicon/hi6210-i2s.c @@ -517,7 +517,7 @@ static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai) } -static struct snd_soc_dai_ops hi6210_i2s_dai_ops = { +static const struct snd_soc_dai_ops hi6210_i2s_dai_ops = { .trigger = hi6210_i2s_trigger, .hw_params = hi6210_i2s_hw_params, .set_fmt = hi6210_i2s_set_fmt, diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index 0389203f85608edfababa699086278d4c51ccb69..567f9767fb73ed174473f7bee4d5df74b7b5cbea 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -443,7 +443,7 @@ static int img_i2s_in_probe(struct platform_device *pdev) SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE; i2s->dai_driver.ops = &img_i2s_in_dai_ops; - rst = devm_reset_control_get(dev, "rst"); + rst = devm_reset_control_get_exclusive(dev, "rst"); if (IS_ERR(rst)) { if (PTR_ERR(rst) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index 5f997135a8aecdf5a89f8155d054c4544c697dad..78b7f6cd675b72a64d54749256525f2a7d19f417 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -446,7 +446,7 @@ static int img_i2s_out_probe(struct platform_device *pdev) i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20); - i2s->rst = devm_reset_control_get(&pdev->dev, "rst"); + i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(i2s->rst)) { if (PTR_ERR(i2s->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c index 33ceb207ee7040ab8f32b5ef5e7546099bd42617..23b0f0f6ec9cb698742bafc7f7a3b80a790679ce 100644 --- a/sound/soc/img/img-parallel-out.c +++ b/sound/soc/img/img-parallel-out.c @@ -224,7 +224,7 @@ static int img_prl_out_probe(struct platform_device *pdev) prl->base = base; - prl->rst = devm_reset_control_get(&pdev->dev, "rst"); + prl->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(prl->rst)) { if (PTR_ERR(prl->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c index 4d9953d318af449e4ef5543a52c8f120de131444..8adfd65d43902896a482cf37a2b98f8c8abb935f 100644 --- a/sound/soc/img/img-spdif-in.c +++ b/sound/soc/img/img-spdif-in.c @@ -727,7 +727,7 @@ static int img_spdif_in_probe(struct platform_device *pdev) if (ret) return ret; - rst = devm_reset_control_get(&pdev->dev, "rst"); + rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(rst)) { if (PTR_ERR(rst) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c index 08f93a5dadfe954b60cd5a86760598876134c6dd..383655da2e60d601a372d8f9229c0f5642ff9d62 100644 --- a/sound/soc/img/img-spdif-out.c +++ b/sound/soc/img/img-spdif-out.c @@ -334,7 +334,7 @@ static int img_spdif_out_probe(struct platform_device *pdev) spdif->base = base; - spdif->rst = devm_reset_control_get(&pdev->dev, "rst"); + spdif->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(spdif->rst)) { if (PTR_ERR(spdif->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index b301bfff1c09ca06a10692c47352366aa096493b..b3c7f554ec30efb4b66603e17b714777ededc215 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -255,11 +255,12 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode" - depends on X86_INTEL_LPSS && I2C + depends on X86_INTEL_LPSS && I2C && SPI select SND_SOC_INTEL_SST select SND_SOC_INTEL_SKYLAKE select SND_SOC_RT5663 select SND_SOC_RT5514 + select SND_SOC_RT5514_SPI select SND_SOC_MAX98927 select SND_SOC_HDAC_HDMI help diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index b082b31023d59e648034c8d5ffc718c202a72e60..43e7fdd19f291b0ade6a484117c99d28b44da22e 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -76,7 +76,7 @@ int sst_unregister_dsp(struct sst_device *dev) } EXPORT_SYMBOL_GPL(sst_unregister_dsp); -static struct snd_pcm_hardware sst_platform_pcm_hw = { +static const struct snd_pcm_hardware sst_platform_pcm_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_DOUBLE | SNDRV_PCM_INFO_PAUSE | @@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream, } } -static struct snd_soc_dai_ops sst_media_dai_ops = { +static const struct snd_soc_dai_ops sst_media_dai_ops = { .startup = sst_media_open, .shutdown = sst_media_close, .prepare = sst_media_prepare, @@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = { .mute_stream = sst_media_digital_mute, }; -static struct snd_soc_dai_ops sst_compr_dai_ops = { +static const struct snd_soc_dai_ops sst_compr_dai_ops = { .mute_stream = sst_media_digital_mute, }; -static struct snd_soc_dai_ops sst_be_dai_ops = { +static const struct snd_soc_dai_ops sst_be_dai_ops = { .startup = sst_enable_ssp, .hw_params = sst_be_hw_params, .set_fmt = sst_set_format, @@ -705,7 +705,7 @@ static int sst_soc_probe(struct snd_soc_platform *platform) return sst_dsp_init_v2_dpcm(platform); } -static struct snd_soc_platform_driver sst_soc_platform_drv = { +static const struct snd_soc_platform_driver sst_soc_platform_drv = { .probe = sst_soc_probe, .ops = &sst_platform_ops, .compr_ops = &sst_platform_compr_ops, diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c index ce689c5af5abca7428afe57a88dbee3513fae1b3..71af5449be90235ddc04a8cc4fe33fe159334f10 100644 --- a/sound/soc/intel/atom/sst/sst_drv_interface.c +++ b/sound/soc/intel/atom/sst/sst_drv_interface.c @@ -407,7 +407,7 @@ static int sst_cdev_caps(struct snd_compr_caps *caps) return 0; } -static struct snd_compr_codec_caps caps_mp3 = { +static const struct snd_compr_codec_caps caps_mp3 = { .num_descriptors = 1, .descriptor[0].max_ch = 2, .descriptor[0].sample_rates[0] = 48000, @@ -424,7 +424,7 @@ static struct snd_compr_codec_caps caps_mp3 = { .descriptor[0].formats = 0, }; -static struct snd_compr_codec_caps caps_aac = { +static const struct snd_compr_codec_caps caps_aac = { .num_descriptors = 2, .descriptor[1].max_ch = 2, .descriptor[0].sample_rates[0] = 48000, diff --git a/sound/soc/intel/atom/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c index 3a0b3bf0af97f71ea4eb7c5235aceaeca8c218b8..6906ee624cf6f4e16caa6456fdad8e80ed03cd4e 100644 --- a/sound/soc/intel/atom/sst/sst_pci.c +++ b/sound/soc/intel/atom/sst/sst_pci.c @@ -181,7 +181,7 @@ static void intel_sst_remove(struct pci_dev *pci) } /* PCI Routines */ -static struct pci_device_id intel_sst_ids[] = { +static const struct pci_device_id intel_sst_ids[] = { { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, { 0, } }; diff --git a/sound/soc/intel/baytrail/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c index 4765ad4745444b68929f4282271a6b5cdfe0a9be..c54529320f0720560b7cc396a59b70f793fa11d8 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-pcm.c +++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c @@ -309,7 +309,7 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream, return snd_pcm_lib_default_mmap(substream, vma); } -static struct snd_pcm_ops sst_byt_pcm_ops = { +static const struct snd_pcm_ops sst_byt_pcm_ops = { .open = sst_byt_pcm_open, .close = sst_byt_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -395,7 +395,7 @@ static int sst_byt_pcm_remove(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver byt_soc_platform = { +static const struct snd_soc_platform_driver byt_soc_platform = { .probe = sst_byt_pcm_probe, .remove = sst_byt_pcm_remove, .ops = &sst_byt_pcm_ops, diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 0c3a3cbcb884c080c24275551f5ee6d2e329ad98..7843104fadcbf2eff7915ffe3c903d5152ad86cf 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = { { "iDisp2 Tx", NULL, "iDisp2_out"}, { "hifi1", NULL, "iDisp1 Tx"}, { "iDisp1 Tx", NULL, "iDisp1_out"}, +}; + +static const struct snd_soc_dapm_route geminilake_rt298_map[] = { + /* speaker */ + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "SPOL"}, + + /* HP jack connectors - unknown if we have jack detect */ + {"Headphone Jack", NULL, "HPO Pin"}, + + /* other jacks */ + {"MIC1", NULL, "Mic Jack"}, + + /* digital mics */ + {"DMIC1 Pin", NULL, "DMIC2"}, + {"DMic", NULL, "SoC DMIC"}, + + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI2", NULL, "hif7-0 Output"}, + + /* CODEC BE connections */ + { "AIF1 Playback", NULL, "ssp2 Tx"}, + { "ssp2 Tx", NULL, "codec0_out"}, + { "ssp2 Tx", NULL, "codec1_out"}, + + { "codec0_in", NULL, "ssp2 Rx" }, + { "ssp2 Rx", NULL, "AIF1 Capture" }, + { "dmic01_hifi", NULL, "DMIC01 Rx" }, + { "DMIC01 Rx", NULL, "Capture" }, + + { "hifi3", NULL, "iDisp3 Tx"}, + { "iDisp3 Tx", NULL, "iDisp3_out"}, + { "hifi2", NULL, "iDisp2 Tx"}, + { "iDisp2 Tx", NULL, "iDisp2_out"}, + { "hifi1", NULL, "iDisp1 Tx"}, + { "iDisp1 Tx", NULL, "iDisp1_out"}, }; static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) @@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card) /* broxton audio machine driver for SPT + RT298S */ static struct snd_soc_card broxton_rt298 = { .name = "broxton-rt298", - .owner = THIS_MODULE, .dai_link = broxton_rt298_dais, .num_links = ARRAY_SIZE(broxton_rt298_dais), .controls = broxton_controls, @@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = { }; +static struct snd_soc_card geminilake_rt298 = { + .name = "geminilake-rt298", + .dai_link = broxton_rt298_dais, + .num_links = ARRAY_SIZE(broxton_rt298_dais), + .controls = broxton_controls, + .num_controls = ARRAY_SIZE(broxton_controls), + .dapm_widgets = broxton_widgets, + .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), + .dapm_routes = geminilake_rt298_map, + .num_dapm_routes = ARRAY_SIZE(geminilake_rt298_map), + .fully_routed = true, + .late_probe = bxt_card_late_probe, +}; + static int broxton_audio_probe(struct platform_device *pdev) { struct bxt_rt286_private *ctx; + struct snd_soc_card *card = + (struct snd_soc_card *)pdev->id_entry->driver_data; + int i; + + for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) { + if (!strncmp(card->dai_link[i].codec_name, "i2c-INT343A:00", + I2C_NAME_SIZE)) { + if (!strncmp(card->name, "broxton-rt298", + PLATFORM_NAME_SIZE)) { + card->dai_link[i].name = "SSP5-Codec"; + card->dai_link[i].cpu_dai_name = "SSP5 Pin"; + } else if (!strncmp(card->name, "geminilake-rt298", + PLATFORM_NAME_SIZE)) { + card->dai_link[i].name = "SSP2-Codec"; + card->dai_link[i].cpu_dai_name = "SSP2 Pin"; + } + } + } ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); if (!ctx) @@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - broxton_rt298.dev = &pdev->dev; - snd_soc_card_set_drvdata(&broxton_rt298, ctx); + card->dev = &pdev->dev; + snd_soc_card_set_drvdata(card, ctx); - return devm_snd_soc_register_card(&pdev->dev, &broxton_rt298); + return devm_snd_soc_register_card(&pdev->dev, card); } +static const struct platform_device_id bxt_board_ids[] = { + { .name = "bxt_alc298s_i2s", .driver_data = + (unsigned long)&broxton_rt298 }, + { .name = "glk_alc298s_i2s", .driver_data = + (unsigned long)&geminilake_rt298 }, + {} +}; + static struct platform_driver broxton_audio = { .probe = broxton_audio_probe, .driver = { .name = "bxt_alc298s_i2s", .pm = &snd_soc_pm_ops, }, + .id_table = bxt_board_ids, }; module_platform_driver(broxton_audio) @@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur "); MODULE_DESCRIPTION("Intel SST Audio for Broxton"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:bxt_alc298s_i2s"); +MODULE_ALIAS("platform:glk_alc298s_i2s"); diff --git a/sound/soc/intel/boards/byt-max98090.c b/sound/soc/intel/boards/byt-max98090.c index 047be7fa0ce9f86a1462063b18184a8d984e1404..0f8b8209c0203d80ccc88aa0e65a5cc4cfe1807a 100644 --- a/sound/soc/intel/boards/byt-max98090.c +++ b/sound/soc/intel/boards/byt-max98090.c @@ -173,20 +173,8 @@ static int byt_max98090_probe(struct platform_device *pdev) return 0; } -static int byt_max98090_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct byt_max98090_private *priv = snd_soc_card_get_drvdata(card); - - snd_soc_jack_free_gpios(&priv->jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return 0; -} - static struct platform_driver byt_max98090_driver = { .probe = byt_max98090_probe, - .remove = byt_max98090_remove, .driver = { .name = "byt-max98090", .pm = &snd_soc_pm_ops, diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index bc2a52de06a39729ac6aae83c38e08e822575445..f597d558222388e0b52302395ecfbf22a5a127d7 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -184,6 +184,13 @@ static int cht_aif1_hw_params(struct snd_pcm_substream *substream, return 0; } +static const struct acpi_gpio_params headset_gpios = { 0, 0, false }; + +static const struct acpi_gpio_mapping cht_rt5672_gpios[] = { + { "headset-gpios", &headset_gpios, 1 }, + {}, +}; + static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; @@ -191,6 +198,9 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_codec *codec = codec_dai->codec; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); + if (devm_acpi_dev_add_driver_gpios(codec->dev, cht_rt5672_gpios)) + dev_warn(runtime->dev, "Unable to add GPIO mapping table\n"); + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); if (ret < 0) { diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index f9ba9778815742aa166433fe69e96a2c62dad6c5..7f76074207063a5da6ad8c9874002646d42c88c1 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -34,7 +34,7 @@ #define MAXIM_DEV0_NAME "i2c-MX98927:00" #define MAXIM_DEV1_NAME "i2c-MX98927:01" -static struct snd_soc_card kabylake_audio_card; +static struct snd_soc_card *kabylake_audio_card; static const struct snd_pcm_hw_constraint_list *dmic_constraints; static struct snd_soc_jack skylake_hdmi[3]; @@ -52,6 +52,8 @@ struct kbl_rt5663_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_HS_PB, + KBL_DPCM_AUDIO_ECHO_REF_CP, KBL_DPCM_AUDIO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, KBL_DPCM_AUDIO_HDMI1_PB, @@ -72,8 +74,9 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), + SND_SOC_DAPM_SPK("HDMI3", NULL), }; @@ -91,20 +94,22 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1N", NULL, "Headset Mic" }, { "DMic", NULL, "SoC DMIC" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, - /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, + { "ssp0 Tx", NULL, "spk_out" }, { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, + { "ssp1 Tx", NULL, "hs_out" }, - { "codec0_in", NULL, "ssp1 Rx" }, + { "hs_in", NULL, "ssp1 Rx" }, { "ssp1 Rx", NULL, "AIF Capture" }, + /* IV feedback path */ + { "codec0_fb_in", NULL, "ssp0 Rx"}, + { "ssp0 Rx", NULL, "Left HiFi Capture" }, + { "ssp0 Rx", NULL, "Right HiFi Capture" }, + /* DMIC */ { "dmic01_hifi", NULL, "DMIC01 Rx" }, { "DMIC01 Rx", NULL, "DMIC AIF" }, @@ -117,6 +122,49 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "iDisp1 Tx", NULL, "iDisp1_out"}, }; +enum { + KBL_DPCM_AUDIO_5663_PB = 0, + KBL_DPCM_AUDIO_5663_CP, + KBL_DPCM_AUDIO_5663_HDMI1_PB, + KBL_DPCM_AUDIO_5663_HDMI2_PB, +}; + +static const struct snd_kcontrol_new kabylake_5663_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_SPK("DP", NULL), + SND_SOC_DAPM_SPK("HDMI", NULL), +}; + +static const struct snd_soc_dapm_route kabylake_5663_map[] = { + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + + /* other jacks */ + { "IN1P", NULL, "Headset Mic" }, + { "IN1N", NULL, "Headset Mic" }, + + { "HDMI", NULL, "hif5 Output" }, + { "DP", NULL, "hif6 Output" }, + + /* CODEC BE connections */ + { "AIF Playback", NULL, "ssp1 Tx" }, + { "ssp1 Tx", NULL, "codec1_out" }, + + { "codec0_in", NULL, "ssp1 Rx" }, + { "ssp1 Rx", NULL, "AIF Capture" }, + + { "hifi2", NULL, "iDisp2 Tx"}, + { "iDisp2 Tx", NULL, "iDisp2_out"}, + { "hifi1", NULL, "iDisp1 Tx"}, + { "iDisp1 Tx", NULL, "iDisp1_out"}, +}; + static struct snd_soc_codec_conf max98927_codec_conf[] = { { .dev_name = MAXIM_DEV0_NAME, @@ -165,7 +213,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(&kabylake_audio_card, "Headset Jack", + ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->kabylake_headset, NULL, 0); @@ -173,8 +221,18 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); return ret; } - rt5663_set_jack_detect(codec, &ctx->kabylake_headset); + return ret; +} + +static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = kabylake_rt5663_codec_init(rtd); + if (ret) + return ret; + ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); if (ret) { dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret); @@ -184,7 +242,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_dai *dai = rtd->codec_dai; @@ -194,7 +252,7 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) if (!pcm) return -ENOMEM; - pcm->device = KBL_DPCM_AUDIO_HDMI1_PB; + pcm->device = device; pcm->codec_dai = dai; list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); @@ -202,47 +260,36 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) { - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = KBL_DPCM_AUDIO_HDMI2_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); +} - return 0; +static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); } static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = KBL_DPCM_AUDIO_HDMI3_PB; - pcm->codec_dai = dai; + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); +} - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); +static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB); +} - return 0; +static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB); } static unsigned int rates[] = { 48000, }; -static struct snd_pcm_hw_constraint_list constraints_rates = { +static const struct snd_pcm_hw_constraint_list constraints_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, @@ -252,7 +299,7 @@ static unsigned int channels[] = { 2, }; -static struct snd_pcm_hw_constraint_list constraints_channels = { +static const struct snd_pcm_hw_constraint_list constraints_channels = { .count = ARRAY_SIZE(channels), .list = channels, .mask = 0, @@ -312,11 +359,13 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->codec_dai; int ret; - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ - rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1); + rt5663_sel_asrc_clk_src(codec_dai->codec, + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, + RT5663_CLK_SEL_I2S1_ASRC); + ret = snd_soc_dai_set_sysclk(codec_dai, + RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); @@ -381,7 +430,7 @@ static unsigned int rates_16000[] = { 16000, }; -static struct snd_pcm_hw_constraint_list constraints_16000 = { +static const struct snd_pcm_hw_constraint_list constraints_16000 = { .count = ARRAY_SIZE(rates_16000), .list = rates_16000, }; @@ -443,6 +492,28 @@ static struct snd_soc_dai_link kabylake_dais[] = { .dpcm_capture = 1, .ops = &kabylake_rt5663_fe_ops, }, + [KBL_DPCM_AUDIO_HS_PB] = { + .name = "Kbl Audio Headset Playback", + .stream_name = "Headset Audio", + .cpu_dai_name = "System Pin2", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_ECHO_REF_CP] = { + .name = "Kbl Audio Echo Reference cap", + .stream_name = "Echoreference Capture", + .cpu_dai_name = "Echoref Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .init = NULL, + .capture_only = 1, + .nonatomic = 1, + }, [KBL_DPCM_AUDIO_REF_CP] = { .name = "Kbl Audio Reference cap", .stream_name = "Wake on Voice", @@ -538,7 +609,7 @@ static struct snd_soc_dai_link kabylake_dais[] = { .no_pcm = 1, .codec_name = "i2c-10EC5663:00", .codec_dai_name = KBL_REALTEK_CODEC_DAI, - .init = kabylake_rt5663_codec_init, + .init = kabylake_rt5663_max98927_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ignore_pmdown_time = 1, @@ -594,15 +665,119 @@ static struct snd_soc_dai_link kabylake_dais[] = { }, }; +static struct snd_soc_dai_link kabylake_5663_dais[] = { + /* Front End DAI links */ + [KBL_DPCM_AUDIO_5663_PB] = { + .name = "Kbl Audio Port", + .stream_name = "Audio", + .cpu_dai_name = "System Pin", + .platform_name = "0000:00:1f.3", + .dynamic = 1, + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_playback = 1, + .ops = &kabylake_rt5663_fe_ops, + }, + [KBL_DPCM_AUDIO_5663_CP] = { + .name = "Kbl Audio Capture Port", + .stream_name = "Audio Record", + .cpu_dai_name = "System Pin", + .platform_name = "0000:00:1f.3", + .dynamic = 1, + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_capture = 1, + .ops = &kabylake_rt5663_fe_ops, + }, + [KBL_DPCM_AUDIO_5663_HDMI1_PB] = { + .name = "Kbl HDMI Port1", + .stream_name = "Hdmi1", + .cpu_dai_name = "HDMI1 Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = NULL, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_5663_HDMI2_PB] = { + .name = "Kbl HDMI Port2", + .stream_name = "Hdmi2", + .cpu_dai_name = "HDMI2 Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = NULL, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .nonatomic = 1, + .dynamic = 1, + }, + + /* Back End DAI links */ + { + /* SSP1 - Codec */ + .name = "SSP1-Codec", + .id = 0, + .cpu_dai_name = "SSP1 Pin", + .platform_name = "0000:00:1f.3", + .no_pcm = 1, + .codec_name = "i2c-10EC5663:00", + .codec_dai_name = KBL_REALTEK_CODEC_DAI, + .init = kabylake_rt5663_codec_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ignore_pmdown_time = 1, + .be_hw_params_fixup = kabylake_ssp_fixup, + .ops = &kabylake_rt5663_ops, + .dpcm_playback = 1, + .dpcm_capture = 1, + }, + { + .name = "iDisp1", + .id = 1, + .cpu_dai_name = "iDisp1 Pin", + .codec_name = "ehdaudio0D2", + .codec_dai_name = "intel-hdmi-hifi1", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = kabylake_5663_hdmi1_init, + .no_pcm = 1, + }, + { + .name = "iDisp2", + .id = 2, + .cpu_dai_name = "iDisp2 Pin", + .codec_name = "ehdaudio0D2", + .codec_dai_name = "intel-hdmi-hifi2", + .platform_name = "0000:00:1f.3", + .init = kabylake_5663_hdmi2_init, + .dpcm_playback = 1, + .no_pcm = 1, + }, +}; + #define NAME_SIZE 32 static int kabylake_card_late_probe(struct snd_soc_card *card) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_hdmi_pcm *pcm; + struct snd_soc_codec *codec = NULL; int err, i = 0; char jack_name[NAME_SIZE]; list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + codec = pcm->codec_dai->codec; snprintf(jack_name, sizeof(jack_name), "HDMI/DP, pcm=%d Jack", pcm->device); err = snd_soc_card_jack_new(card, jack_name, @@ -620,11 +795,14 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) i++; } - return 0; + if (!codec) + return -EINVAL; + + return hdac_hdmi_jack_port_init(codec, &card->dapm); } /* kabylake audio machine driver for SPT + RT5663 */ -static struct snd_soc_card kabylake_audio_card = { +static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = { .name = "kblrt5663max", .owner = THIS_MODULE, .dai_link = kabylake_dais, @@ -641,6 +819,22 @@ static struct snd_soc_card kabylake_audio_card = { .late_probe = kabylake_card_late_probe, }; +/* kabylake audio machine driver for RT5663 */ +static struct snd_soc_card kabylake_audio_card_rt5663 = { + .name = "kblrt5663", + .owner = THIS_MODULE, + .dai_link = kabylake_5663_dais, + .num_links = ARRAY_SIZE(kabylake_5663_dais), + .controls = kabylake_5663_controls, + .num_controls = ARRAY_SIZE(kabylake_5663_controls), + .dapm_widgets = kabylake_5663_widgets, + .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets), + .dapm_routes = kabylake_5663_map, + .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map), + .fully_routed = true, + .late_probe = kabylake_card_late_probe, +}; + static int kabylake_audio_probe(struct platform_device *pdev) { struct kbl_rt5663_private *ctx; @@ -652,19 +846,30 @@ static int kabylake_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - kabylake_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&kabylake_audio_card, ctx); + kabylake_audio_card = + (struct snd_soc_card *)pdev->id_entry->driver_data; + + kabylake_audio_card->dev = &pdev->dev; + snd_soc_card_set_drvdata(kabylake_audio_card, ctx); pdata = dev_get_drvdata(&pdev->dev); if (pdata) dmic_constraints = pdata->dmic_num == 2 ? &constraints_dmic_2ch : &constraints_dmic_channels; - return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card); + return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); } static const struct platform_device_id kbl_board_ids[] = { - { .name = "kbl_rt5663_m98927" }, + { + .name = "kbl_rt5663", + .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663, + }, + { + .name = "kbl_rt5663_m98927", + .driver_data = + (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927, + }, { } }; @@ -684,4 +889,5 @@ MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode"); MODULE_AUTHOR("Naveen M "); MODULE_AUTHOR("Harsha Priya "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:kbl_rt5663"); MODULE_ALIAS("platform:kbl_rt5663_m98927"); diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 3fe4a080709598dba91fa8965b1a37fd98c36b68..88ff542200075634e9a6b6e0fd0a7f1ba1dbaf7a 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -18,6 +18,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -62,7 +63,10 @@ struct kbl_codec_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_HS_PB, + KBL_DPCM_AUDIO_ECHO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, + KBL_DPCM_AUDIO_RT5514_DSP, KBL_DPCM_AUDIO_HDMI1_PB, KBL_DPCM_AUDIO_HDMI2_PB, }; @@ -81,8 +85,8 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_MIC("DMIC", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), }; @@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1P", NULL, "Headset Mic" }, { "IN1N", NULL, "Headset Mic" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, - /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, + { "ssp0 Tx", NULL, "spk_out" }, { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, + { "ssp1 Tx", NULL, "hs_out" }, - { "codec0_in", NULL, "ssp1 Rx" }, + { "hs_in", NULL, "ssp1 Rx" }, { "ssp1 Rx", NULL, "AIF Capture" }, { "codec1_in", NULL, "ssp0 Rx" }, { "ssp0 Rx", NULL, "AIF1 Capture" }, + /* IV feedback path */ + { "codec0_fb_in", NULL, "ssp0 Rx"}, + { "ssp0 Rx", NULL, "Left HiFi Capture" }, + { "ssp0 Rx", NULL, "Right HiFi Capture" }, + /* DMIC */ { "DMIC1L", NULL, "DMIC" }, { "DMIC1R", NULL, "DMIC" }, @@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) int ret; struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_jack *jack; /* * Headset buttons map to the google Reference headset. @@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } + jack = &ctx->kabylake_headset; + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + rt5663_set_jack_detect(codec, &ctx->kabylake_headset); ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC"); @@ -319,7 +332,9 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ - rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1); + rt5663_sel_asrc_clk_src(codec_dai->codec, + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, + RT5663_CLK_SEL_I2S1_ASRC); ret = snd_soc_dai_set_sysclk(codec_dai, RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); @@ -349,27 +364,25 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, return ret; } - ret = snd_soc_dai_set_pll(codec_dai, 0, - RT5514_PLL1_S_BCLK, RT5514_AIF1_BCLK_FREQ, - RT5514_AIF1_SYSCLK_FREQ); + ret = snd_soc_dai_set_sysclk(codec_dai, + RT5514_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); if (ret < 0) { - dev_err(rtd->dev, "set bclk err: %d\n", ret); + dev_err(rtd->dev, "set sysclk err: %d\n", ret); return ret; } - - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5514_SCLK_S_PLL1, RT5514_AIF1_SYSCLK_FREQ, - SND_SOC_CLOCK_IN); + } + if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); if (ret < 0) { - dev_err(rtd->dev, "set sclk err: %d\n", ret); + dev_err(rtd->dev, "DEV0 TDM slot err:%d\n", ret); return ret; } } - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME) || - !strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF0, 3, 8, 16); + + if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); + dev_err(rtd->dev, "DEV1 TDM slot err:%d\n", ret); return ret; } } @@ -449,6 +462,36 @@ static struct snd_soc_dai_link kabylake_dais[] = { .dpcm_capture = 1, .ops = &kabylake_rt5663_fe_ops, }, + [KBL_DPCM_AUDIO_HS_PB] = { + .name = "Kbl Audio Headset Playback", + .stream_name = "Headset Audio", + .cpu_dai_name = "System Pin2", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_ECHO_REF_CP] = { + .name = "Kbl Audio Echo Reference cap", + .stream_name = "Echoreference Capture", + .cpu_dai_name = "Echoref Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .init = NULL, + .capture_only = 1, + .nonatomic = 1, + }, + [KBL_DPCM_AUDIO_RT5514_DSP] = { + .name = "rt5514 dsp", + .stream_name = "Wake on Voice", + .cpu_dai_name = "spi-PRP0001:00", + .platform_name = "spi-PRP0001:00", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + }, [KBL_DPCM_AUDIO_DMIC_CP] = { .name = "Kbl Audio DMIC cap", .stream_name = "dmiccap", @@ -555,10 +598,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_hdmi_pcm *pcm; + struct snd_soc_codec *codec = NULL; int err, i = 0; char jack_name[NAME_SIZE]; list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + codec = pcm->codec_dai->codec; err = snd_soc_card_jack_new(card, jack_name, SND_JACK_AVOUT, &ctx->kabylake_hdmi[i], NULL, 0); @@ -572,7 +617,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) i++; } - return 0; + if (!codec) + return -EINVAL; + + return hdac_hdmi_jack_port_init(codec, &card->dapm); } /* diff --git a/sound/soc/intel/boards/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c index 4e08885f37aaf87ed55103e1a210deae9893ec0e..6f44acfb4aae7337aa1f4009e0a6c0b71efad2c3 100644 --- a/sound/soc/intel/boards/mfld_machine.c +++ b/sound/soc/intel/boards/mfld_machine.c @@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev) /* audio interrupt base of SRAM location where * interrupts are stored by System FW */ mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC); - if (!mc_drv_ctx) { - pr_err("allocation failed\n"); + if (!mc_drv_ctx) return -ENOMEM; - } irq_mem = platform_get_resource_byname( pdev, IORESOURCE_MEM, "IRQ_BASE"); diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c index 9e4094e2c6e319a02aefecd039e68d5fd1465201..c044400540ec837689f0c6e19634c77eb3e2135c 100644 --- a/sound/soc/intel/haswell/sst-haswell-pcm.c +++ b/sound/soc/intel/haswell/sst-haswell-pcm.c @@ -1135,7 +1135,7 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver hsw_soc_platform = { +static const struct snd_soc_platform_driver hsw_soc_platform = { .probe = hsw_pcm_probe, .remove = hsw_pcm_remove, .ops = &hsw_pcm_ops, diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile index e7d77722d56010dee2f3ea16f3642f4d63a56d1f..3380deb81015a95fec9a4ccff0b32166e7b8819c 100644 --- a/sound/soc/intel/skylake/Makefile +++ b/sound/soc/intel/skylake/Makefile @@ -8,7 +8,8 @@ endif obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o # Skylake IPC Support -snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o \ - skl-sst.o bxt-sst.o skl-sst-utils.o +snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \ + skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o \ + skl-sst-utils.o obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index cf11b84888b9044c94495beba67c539e35f8a816..4524211960e4a4a5941f08a8a2066096e471cf6f 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -530,7 +530,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) return 0; } -static struct skl_dsp_fw_ops bxt_fw_ops = { +static const struct skl_dsp_fw_ops bxt_fw_ops = { .set_state_D0 = bxt_set_dsp_D0, .set_state_D3 = bxt_set_dsp_D3, .set_state_D0i3 = bxt_schedule_dsp_D0i3, @@ -581,10 +581,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); + ret = skl_ipc_init(dev, skl); + if (ret) { + skl_dsp_free(sst); + return ret; + } + /* set the D0i3 check */ skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0; - skl->cores.count = 2; skl->boot_complete = false; init_waitqueue_head(&skl->boot_wait); INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); @@ -629,11 +634,6 @@ void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) release_firmware(ctx->dsp->fw); skl_freeup_uuid_list(ctx); skl_ipc_free(&ctx->ipc); - ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); - - if (ctx->dsp->addr.lpe) - iounmap(ctx->dsp->addr.lpe); - ctx->dsp->ops->free(ctx->dsp); } EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.c b/sound/soc/intel/skylake/cnl-sst-dsp.c new file mode 100644 index 0000000000000000000000000000000000000000..2f8326707c21da955fbb0918e1a1145f9d91a28e --- /dev/null +++ b/sound/soc/intel/skylake/cnl-sst-dsp.c @@ -0,0 +1,274 @@ +/* + * cnl-sst-dsp.c - CNL SST library generic function + * + * Copyright (C) 2016-17, Intel Corporation. + * Author: Guneshwor Singh + * + * Modified from: + * SKL SST library generic function + * Copyright (C) 2014-15, Intel Corporation. + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include "../common/sst-dsp.h" +#include "../common/sst-ipc.h" +#include "../common/sst-dsp-priv.h" +#include "cnl-sst-dsp.h" + +/* various timeout values */ +#define CNL_DSP_PU_TO 50 +#define CNL_DSP_PD_TO 50 +#define CNL_DSP_RESET_TO 50 + +static int +cnl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, + CNL_ADSP_REG_ADSPCS, CNL_ADSPCS_CRST(core_mask), + CNL_ADSPCS_CRST(core_mask)); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, + CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CRST(core_mask), + CNL_ADSPCS_CRST(core_mask), + CNL_DSP_RESET_TO, + "Set reset"); +} + +static int +cnl_dsp_core_unset_reset_state(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CRST(core_mask), 0); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, + CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CRST(core_mask), + 0, + CNL_DSP_RESET_TO, + "Unset reset"); +} + +static bool is_cnl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask) +{ + int val; + bool is_enable; + + val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPCS); + + is_enable = (val & CNL_ADSPCS_CPA(core_mask)) && + (val & CNL_ADSPCS_SPA(core_mask)) && + !(val & CNL_ADSPCS_CRST(core_mask)) && + !(val & CNL_ADSPCS_CSTALL(core_mask)); + + dev_dbg(ctx->dev, "DSP core(s) enabled? %d: core_mask %#x\n", + is_enable, core_mask); + + return is_enable; +} + +static int cnl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* stall core */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CSTALL(core_mask), + CNL_ADSPCS_CSTALL(core_mask)); + + /* set reset state */ + return cnl_dsp_core_set_reset_state(ctx, core_mask); +} + +static int cnl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + int ret; + + /* unset reset state */ + ret = cnl_dsp_core_unset_reset_state(ctx, core_mask); + if (ret < 0) + return ret; + + /* run core */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CSTALL(core_mask), 0); + + if (!is_cnl_dsp_core_enable(ctx, core_mask)) { + cnl_dsp_reset_core(ctx, core_mask); + dev_err(ctx->dev, "DSP core mask %#x enable failed\n", + core_mask); + ret = -EIO; + } + + return ret; +} + +static int cnl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_SPA(core_mask), + CNL_ADSPCS_SPA(core_mask)); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CPA(core_mask), + CNL_ADSPCS_CPA(core_mask), + CNL_DSP_PU_TO, + "Power up"); +} + +static int cnl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_SPA(core_mask), 0); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, + CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CPA(core_mask), + 0, + CNL_DSP_PD_TO, + "Power down"); +} + +int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + int ret; + + /* power up */ + ret = cnl_dsp_core_power_up(ctx, core_mask); + if (ret < 0) { + dev_dbg(ctx->dev, "DSP core mask %#x power up failed", + core_mask); + return ret; + } + + return cnl_dsp_start_core(ctx, core_mask); +} + +int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + int ret; + + ret = cnl_dsp_reset_core(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "DSP core mask %#x reset failed\n", + core_mask); + return ret; + } + + /* power down core*/ + ret = cnl_dsp_core_power_down(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "DSP core mask %#x power down failed\n", + core_mask); + return ret; + } + + if (is_cnl_dsp_core_enable(ctx, core_mask)) { + dev_err(ctx->dev, "DSP core mask %#x disable failed\n", + core_mask); + ret = -EIO; + } + + return ret; +} + +irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id) +{ + struct sst_dsp *ctx = dev_id; + u32 val; + irqreturn_t ret = IRQ_NONE; + + spin_lock(&ctx->spinlock); + + val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS); + ctx->intr_status = val; + + if (val == 0xffffffff) { + spin_unlock(&ctx->spinlock); + return IRQ_NONE; + } + + if (val & CNL_ADSPIS_IPC) { + cnl_ipc_int_disable(ctx); + ret = IRQ_WAKE_THREAD; + } + + spin_unlock(&ctx->spinlock); + + return ret; +} + +void cnl_dsp_free(struct sst_dsp *dsp) +{ + cnl_ipc_int_disable(dsp); + + free_irq(dsp->irq, dsp); + cnl_ipc_op_int_disable(dsp); + cnl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK); +} +EXPORT_SYMBOL_GPL(cnl_dsp_free); + +void cnl_ipc_int_enable(struct sst_dsp *ctx) +{ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_ADSPIC, + CNL_ADSPIC_IPC, CNL_ADSPIC_IPC); +} + +void cnl_ipc_int_disable(struct sst_dsp *ctx) +{ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPIC, + CNL_ADSPIC_IPC, 0); +} + +void cnl_ipc_op_int_enable(struct sst_dsp *ctx) +{ + /* enable IPC DONE interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, + CNL_ADSP_REG_HIPCCTL_DONE); + + /* enable IPC BUSY interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_BUSY, + CNL_ADSP_REG_HIPCCTL_BUSY); +} + +void cnl_ipc_op_int_disable(struct sst_dsp *ctx) +{ + /* disable IPC DONE interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, 0); + + /* disable IPC BUSY interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_BUSY, 0); +} + +bool cnl_ipc_int_status(struct sst_dsp *ctx) +{ + return sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS) & + CNL_ADSPIS_IPC; +} + +void cnl_ipc_free(struct sst_generic_ipc *ipc) +{ + cnl_ipc_op_int_disable(ipc->dsp); + sst_ipc_fini(ipc); +} diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.h b/sound/soc/intel/skylake/cnl-sst-dsp.h new file mode 100644 index 0000000000000000000000000000000000000000..09bd218df5c4f2cd911f7f501653c8a3f837d7b3 --- /dev/null +++ b/sound/soc/intel/skylake/cnl-sst-dsp.h @@ -0,0 +1,112 @@ +/* + * Cannonlake SST DSP Support + * + * Copyright (C) 2016-17, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __CNL_SST_DSP_H__ +#define __CNL_SST_DSP_H__ + +struct sst_dsp; +struct skl_sst; +struct sst_dsp_device; +struct sst_generic_ipc; + +/* Intel HD Audio General DSP Registers */ +#define CNL_ADSP_GEN_BASE 0x0 +#define CNL_ADSP_REG_ADSPCS (CNL_ADSP_GEN_BASE + 0x04) +#define CNL_ADSP_REG_ADSPIC (CNL_ADSP_GEN_BASE + 0x08) +#define CNL_ADSP_REG_ADSPIS (CNL_ADSP_GEN_BASE + 0x0c) + +/* Intel HD Audio Inter-Processor Communication Registers */ +#define CNL_ADSP_IPC_BASE 0xc0 +#define CNL_ADSP_REG_HIPCTDR (CNL_ADSP_IPC_BASE + 0x00) +#define CNL_ADSP_REG_HIPCTDA (CNL_ADSP_IPC_BASE + 0x04) +#define CNL_ADSP_REG_HIPCTDD (CNL_ADSP_IPC_BASE + 0x08) +#define CNL_ADSP_REG_HIPCIDR (CNL_ADSP_IPC_BASE + 0x10) +#define CNL_ADSP_REG_HIPCIDA (CNL_ADSP_IPC_BASE + 0x14) +#define CNL_ADSP_REG_HIPCIDD (CNL_ADSP_IPC_BASE + 0x18) +#define CNL_ADSP_REG_HIPCCTL (CNL_ADSP_IPC_BASE + 0x28) + +/* HIPCTDR */ +#define CNL_ADSP_REG_HIPCTDR_BUSY BIT(31) + +/* HIPCTDA */ +#define CNL_ADSP_REG_HIPCTDA_DONE BIT(31) + +/* HIPCIDR */ +#define CNL_ADSP_REG_HIPCIDR_BUSY BIT(31) + +/* HIPCIDA */ +#define CNL_ADSP_REG_HIPCIDA_DONE BIT(31) + +/* CNL HIPCCTL */ +#define CNL_ADSP_REG_HIPCCTL_DONE BIT(1) +#define CNL_ADSP_REG_HIPCCTL_BUSY BIT(0) + +/* CNL HIPCT */ +#define CNL_ADSP_REG_HIPCT_BUSY BIT(31) + +/* Intel HD Audio SRAM Window 1 */ +#define CNL_ADSP_SRAM1_BASE 0xa0000 + +#define CNL_ADSP_MMIO_LEN 0x10000 + +#define CNL_ADSP_W0_STAT_SZ 0x1000 + +#define CNL_ADSP_W0_UP_SZ 0x1000 + +#define CNL_ADSP_W1_SZ 0x1000 + +#define CNL_FW_STS_MASK 0xf + +#define CNL_ADSPIC_IPC 0x1 +#define CNL_ADSPIS_IPC 0x1 + +#define CNL_DSP_CORES 4 +#define CNL_DSP_CORES_MASK ((1 << CNL_DSP_CORES) - 1) + +/* core reset - asserted high */ +#define CNL_ADSPCS_CRST_SHIFT 0 +#define CNL_ADSPCS_CRST(x) (x << CNL_ADSPCS_CRST_SHIFT) + +/* core run/stall - when set to 1 core is stalled */ +#define CNL_ADSPCS_CSTALL_SHIFT 8 +#define CNL_ADSPCS_CSTALL(x) (x << CNL_ADSPCS_CSTALL_SHIFT) + +/* set power active - when set to 1 turn core on */ +#define CNL_ADSPCS_SPA_SHIFT 16 +#define CNL_ADSPCS_SPA(x) (x << CNL_ADSPCS_SPA_SHIFT) + +/* current power active - power status of cores, set by hardware */ +#define CNL_ADSPCS_CPA_SHIFT 24 +#define CNL_ADSPCS_CPA(x) (x << CNL_ADSPCS_CPA_SHIFT) + +int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core); +int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core); +irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id); +void cnl_dsp_free(struct sst_dsp *dsp); + +void cnl_ipc_int_enable(struct sst_dsp *ctx); +void cnl_ipc_int_disable(struct sst_dsp *ctx); +void cnl_ipc_op_int_enable(struct sst_dsp *ctx); +void cnl_ipc_op_int_disable(struct sst_dsp *ctx); +bool cnl_ipc_int_status(struct sst_dsp *ctx); +void cnl_ipc_free(struct sst_generic_ipc *ipc); + +int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp); +int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx); +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); + +#endif /*__CNL_SST_DSP_H__*/ diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c new file mode 100644 index 0000000000000000000000000000000000000000..387de388ce29405be5ad10875cb66a17adf39f55 --- /dev/null +++ b/sound/soc/intel/skylake/cnl-sst.c @@ -0,0 +1,497 @@ +/* + * cnl-sst.c - DSP library functions for CNL platform + * + * Copyright (C) 2016-17, Intel Corporation. + * + * Author: Guneshwor Singh + * + * Modified from: + * HDA DSP library functions for SKL platform + * Copyright (C) 2014-15, Intel Corporation. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include + +#include "../common/sst-dsp.h" +#include "../common/sst-dsp-priv.h" +#include "../common/sst-ipc.h" +#include "cnl-sst-dsp.h" +#include "skl-sst-dsp.h" +#include "skl-sst-ipc.h" + +#define CNL_FW_ROM_INIT 0x1 +#define CNL_FW_INIT 0x5 +#define CNL_IPC_PURGE 0x01004000 +#define CNL_INIT_TIMEOUT 300 +#define CNL_BASEFW_TIMEOUT 3000 + +#define CNL_ADSP_SRAM0_BASE 0x80000 + +/* Firmware status window */ +#define CNL_ADSP_FW_STATUS CNL_ADSP_SRAM0_BASE +#define CNL_ADSP_ERROR_CODE (CNL_ADSP_FW_STATUS + 0x4) + +#define CNL_INSTANCE_ID 0 +#define CNL_BASE_FW_MODULE_ID 0 +#define CNL_ADSP_FW_HDR_OFFSET 0x2000 +#define CNL_ROM_CTRL_DMA_ID 0x9 + +static int cnl_prepare_fw(struct sst_dsp *ctx, const void *fwdata, u32 fwsize) +{ + + int ret, stream_tag; + + stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab); + if (stream_tag <= 0) { + dev_err(ctx->dev, "dma prepare failed: 0%#x\n", stream_tag); + return stream_tag; + } + + ctx->dsp_ops.stream_tag = stream_tag; + memcpy(ctx->dmab.area, fwdata, fwsize); + + /* purge FW request */ + sst_dsp_shim_write(ctx, CNL_ADSP_REG_HIPCIDR, + CNL_ADSP_REG_HIPCIDR_BUSY | (CNL_IPC_PURGE | + ((stream_tag - 1) << CNL_ROM_CTRL_DMA_ID))); + + ret = cnl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK); + if (ret < 0) { + dev_err(ctx->dev, "dsp boot core failed ret: %d\n", ret); + ret = -EIO; + goto base_fw_load_failed; + } + + /* enable interrupt */ + cnl_ipc_int_enable(ctx); + cnl_ipc_op_int_enable(ctx); + + ret = sst_dsp_register_poll(ctx, CNL_ADSP_FW_STATUS, CNL_FW_STS_MASK, + CNL_FW_ROM_INIT, CNL_INIT_TIMEOUT, + "rom load"); + if (ret < 0) { + dev_err(ctx->dev, "rom init timeout, ret: %d\n", ret); + goto base_fw_load_failed; + } + + return 0; + +base_fw_load_failed: + ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); + cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); + + return ret; +} + +static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) +{ + int ret; + + ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag); + ret = sst_dsp_register_poll(ctx, CNL_ADSP_FW_STATUS, CNL_FW_STS_MASK, + CNL_FW_INIT, CNL_BASEFW_TIMEOUT, + "firmware boot"); + + ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag); + ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag); + + return ret; +} + +static int cnl_load_base_firmware(struct sst_dsp *ctx) +{ + struct firmware stripped_fw; + struct skl_sst *cnl = ctx->thread_context; + int ret; + + if (!ctx->fw) { + ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); + if (ret < 0) { + dev_err(ctx->dev, "request firmware failed: %d\n", ret); + goto cnl_load_base_firmware_failed; + } + } + + /* parse uuids if first boot */ + if (cnl->is_first_boot) { + ret = snd_skl_parse_uuids(ctx, ctx->fw, + CNL_ADSP_FW_HDR_OFFSET, 0); + if (ret < 0) + goto cnl_load_base_firmware_failed; + } + + stripped_fw.data = ctx->fw->data; + stripped_fw.size = ctx->fw->size; + skl_dsp_strip_extended_manifest(&stripped_fw); + + ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); + if (ret < 0) { + dev_err(ctx->dev, "prepare firmware failed: %d\n", ret); + goto cnl_load_base_firmware_failed; + } + + ret = sst_transfer_fw_host_dma(ctx); + if (ret < 0) { + dev_err(ctx->dev, "transfer firmware failed: %d\n", ret); + cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); + goto cnl_load_base_firmware_failed; + } + + ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete, + msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); + if (ret == 0) { + dev_err(ctx->dev, "FW ready timed-out\n"); + cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); + ret = -EIO; + goto cnl_load_base_firmware_failed; + } + + cnl->fw_loaded = true; + + return 0; + +cnl_load_base_firmware_failed: + release_firmware(ctx->fw); + ctx->fw = NULL; + + return ret; +} + +static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) +{ + struct skl_sst *cnl = ctx->thread_context; + unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); + struct skl_ipc_dxstate_info dx; + int ret; + + if (!cnl->fw_loaded) { + cnl->boot_complete = false; + ret = cnl_load_base_firmware(ctx); + if (ret < 0) { + dev_err(ctx->dev, "fw reload failed: %d\n", ret); + return ret; + } + + cnl->cores.state[core_id] = SKL_DSP_RUNNING; + return ret; + } + + ret = cnl_dsp_enable_core(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "enable dsp core %d failed: %d\n", + core_id, ret); + goto err; + } + + if (core_id == SKL_DSP_CORE0_ID) { + /* enable interrupt */ + cnl_ipc_int_enable(ctx); + cnl_ipc_op_int_enable(ctx); + cnl->boot_complete = false; + + ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete, + msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); + if (ret == 0) { + dev_err(ctx->dev, + "dsp boot timeout, status=%#x error=%#x\n", + sst_dsp_shim_read(ctx, CNL_ADSP_FW_STATUS), + sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE)); + goto err; + } + } else { + dx.core_mask = core_mask; + dx.dx_mask = core_mask; + + ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID, + CNL_BASE_FW_MODULE_ID, &dx); + if (ret < 0) { + dev_err(ctx->dev, "set_dx failed, core: %d ret: %d\n", + core_id, ret); + goto err; + } + } + cnl->cores.state[core_id] = SKL_DSP_RUNNING; + + return 0; +err: + cnl_dsp_disable_core(ctx, core_mask); + + return ret; +} + +static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) +{ + struct skl_sst *cnl = ctx->thread_context; + unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); + struct skl_ipc_dxstate_info dx; + int ret; + + dx.core_mask = core_mask; + dx.dx_mask = SKL_IPC_D3_MASK; + + ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID, + CNL_BASE_FW_MODULE_ID, &dx); + if (ret < 0) { + dev_err(ctx->dev, + "dsp core %d to d3 failed; continue reset\n", + core_id); + cnl->fw_loaded = false; + } + + /* disable interrupts if core 0 */ + if (core_id == SKL_DSP_CORE0_ID) { + skl_ipc_op_int_disable(ctx); + skl_ipc_int_disable(ctx); + } + + ret = cnl_dsp_disable_core(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "disable dsp core %d failed: %d\n", + core_id, ret); + return ret; + } + + cnl->cores.state[core_id] = SKL_DSP_RESET; + + return ret; +} + +static unsigned int cnl_get_errno(struct sst_dsp *ctx) +{ + return sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE); +} + +static const struct skl_dsp_fw_ops cnl_fw_ops = { + .set_state_D0 = cnl_set_dsp_D0, + .set_state_D3 = cnl_set_dsp_D3, + .load_fw = cnl_load_base_firmware, + .get_fw_errcode = cnl_get_errno, +}; + +static struct sst_ops cnl_ops = { + .irq_handler = cnl_dsp_sst_interrupt, + .write = sst_shim32_write, + .read = sst_shim32_read, + .ram_read = sst_memcpy_fromio_32, + .ram_write = sst_memcpy_toio_32, + .free = cnl_dsp_free, +}; + +#define CNL_IPC_GLB_NOTIFY_RSP_SHIFT 29 +#define CNL_IPC_GLB_NOTIFY_RSP_MASK 0x1 +#define CNL_IPC_GLB_NOTIFY_RSP_TYPE(x) (((x) >> CNL_IPC_GLB_NOTIFY_RSP_SHIFT) \ + & CNL_IPC_GLB_NOTIFY_RSP_MASK) + +static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) +{ + struct sst_dsp *dsp = context; + struct skl_sst *cnl = sst_dsp_get_thread_context(dsp); + struct sst_generic_ipc *ipc = &cnl->ipc; + struct skl_ipc_header header = {0}; + u32 hipcida, hipctdr, hipctdd; + int ipc_irq = 0; + + /* here we handle ipc interrupts only */ + if (!(dsp->intr_status & CNL_ADSPIS_IPC)) + return IRQ_NONE; + + hipcida = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDA); + hipctdr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDR); + + /* reply message from dsp */ + if (hipcida & CNL_ADSP_REG_HIPCIDA_DONE) { + sst_dsp_shim_update_bits(dsp, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, 0); + + /* clear done bit - tell dsp operation is complete */ + sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCIDA, + CNL_ADSP_REG_HIPCIDA_DONE, CNL_ADSP_REG_HIPCIDA_DONE); + + ipc_irq = 1; + + /* unmask done interrupt */ + sst_dsp_shim_update_bits(dsp, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, CNL_ADSP_REG_HIPCCTL_DONE); + } + + /* new message from dsp */ + if (hipctdr & CNL_ADSP_REG_HIPCTDR_BUSY) { + hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD); + header.primary = hipctdr; + header.extension = hipctdd; + dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", + header.primary); + dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", + header.extension); + + if (CNL_IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { + /* Handle Immediate reply from DSP Core */ + skl_ipc_process_reply(ipc, header); + } else { + dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n"); + skl_ipc_process_notification(ipc, header); + } + /* clear busy interrupt */ + sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCTDR, + CNL_ADSP_REG_HIPCTDR_BUSY, CNL_ADSP_REG_HIPCTDR_BUSY); + + /* set done bit to ack dsp */ + sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCTDA, + CNL_ADSP_REG_HIPCTDA_DONE, CNL_ADSP_REG_HIPCTDA_DONE); + ipc_irq = 1; + } + + if (ipc_irq == 0) + return IRQ_NONE; + + cnl_ipc_int_enable(dsp); + + /* continue to send any remaining messages */ + schedule_work(&ipc->kwork); + + return IRQ_HANDLED; +} + +static struct sst_dsp_device cnl_dev = { + .thread = cnl_dsp_irq_thread_handler, + .ops = &cnl_ops, +}; + +static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) +{ + struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); + + if (msg->tx_size) + sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); + sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, + header->extension); + sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, + header->primary | CNL_ADSP_REG_HIPCIDR_BUSY); +} + +static bool cnl_ipc_is_dsp_busy(struct sst_dsp *dsp) +{ + u32 hipcidr; + + hipcidr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDR); + + return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY); +} + +static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl) +{ + struct sst_generic_ipc *ipc; + int err; + + ipc = &cnl->ipc; + ipc->dsp = cnl->dsp; + ipc->dev = dev; + + ipc->tx_data_max_size = CNL_ADSP_W1_SZ; + ipc->rx_data_max_size = CNL_ADSP_W0_UP_SZ; + + err = sst_ipc_init(ipc); + if (err) + return err; + + /* + * overriding tx_msg and is_dsp_busy since + * ipc registers are different for cnl + */ + ipc->ops.tx_msg = cnl_ipc_tx_msg; + ipc->ops.tx_data_copy = skl_ipc_tx_data_copy; + ipc->ops.is_dsp_busy = cnl_ipc_is_dsp_busy; + + return 0; +} + +int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp) +{ + struct skl_sst *cnl; + struct sst_dsp *sst; + int ret; + + ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &cnl_dev); + if (ret < 0) { + dev_err(dev, "%s: no device\n", __func__); + return ret; + } + + cnl = *dsp; + sst = cnl->dsp; + sst->fw_ops = cnl_fw_ops; + sst->addr.lpe = mmio_base; + sst->addr.shim = mmio_base; + sst->addr.sram0_base = CNL_ADSP_SRAM0_BASE; + sst->addr.sram1_base = CNL_ADSP_SRAM1_BASE; + sst->addr.w0_stat_sz = CNL_ADSP_W0_STAT_SZ; + sst->addr.w0_up_sz = CNL_ADSP_W0_UP_SZ; + + sst_dsp_mailbox_init(sst, (CNL_ADSP_SRAM0_BASE + CNL_ADSP_W0_STAT_SZ), + CNL_ADSP_W0_UP_SZ, CNL_ADSP_SRAM1_BASE, + CNL_ADSP_W1_SZ); + + ret = cnl_ipc_init(dev, cnl); + if (ret) { + skl_dsp_free(sst); + return ret; + } + + cnl->boot_complete = false; + init_waitqueue_head(&cnl->boot_wait); + + return 0; +} +EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); + +int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx) +{ + int ret; + struct sst_dsp *sst = ctx->dsp; + + ret = ctx->dsp->fw_ops.load_fw(sst); + if (ret < 0) { + dev_err(dev, "load base fw failed: %d", ret); + return ret; + } + + skl_dsp_init_core_state(sst); + + ctx->is_first_boot = false; + + return 0; +} +EXPORT_SYMBOL_GPL(cnl_sst_init_fw); + +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) +{ + if (ctx->dsp->fw) + release_firmware(ctx->dsp->fw); + + skl_freeup_uuid_list(ctx); + cnl_ipc_free(&ctx->ipc); + + ctx->dsp->ops->free(ctx->dsp); +} +EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Intel Cannonlake IPC driver"); diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index eca85827dbd2af68f1bece9718650023dd91fbd4..89f70133c8e4e344ea5f8365dd257a0ef47de56e 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -22,6 +22,7 @@ #include #include #include "skl-sst-dsp.h" +#include "cnl-sst-dsp.h" #include "skl-sst-ipc.h" #include "skl.h" #include "../common/sst-dsp.h" @@ -201,6 +202,7 @@ static struct skl_dsp_loader_ops bxt_get_loader_ops(void) static const struct skl_dsp_ops dsp_ops[] = { { .id = 0x9d70, + .num_cores = 2, .loader_ops = skl_get_loader_ops, .init = skl_sst_dsp_init, .init_fw = skl_sst_init_fw, @@ -208,6 +210,7 @@ static const struct skl_dsp_ops dsp_ops[] = { }, { .id = 0x9d71, + .num_cores = 2, .loader_ops = skl_get_loader_ops, .init = kbl_sst_dsp_init, .init_fw = skl_sst_init_fw, @@ -215,6 +218,7 @@ static const struct skl_dsp_ops dsp_ops[] = { }, { .id = 0x5a98, + .num_cores = 2, .loader_ops = bxt_get_loader_ops, .init = bxt_sst_dsp_init, .init_fw = bxt_sst_init_fw, @@ -222,11 +226,20 @@ static const struct skl_dsp_ops dsp_ops[] = { }, { .id = 0x3198, + .num_cores = 2, .loader_ops = bxt_get_loader_ops, .init = bxt_sst_dsp_init, .init_fw = bxt_sst_init_fw, .cleanup = bxt_sst_dsp_cleanup }, + { + .id = 0x9dc8, + .num_cores = 4, + .loader_ops = bxt_get_loader_ops, + .init = cnl_sst_dsp_init, + .init_fw = cnl_sst_init_fw, + .cleanup = cnl_sst_dsp_cleanup + }, }; const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) @@ -249,6 +262,7 @@ int skl_init_dsp(struct skl *skl) struct skl_dsp_loader_ops loader_ops; int irq = bus->irq; const struct skl_dsp_ops *ops; + struct skl_dsp_cores *cores; int ret; /* enable ppcap interrupt */ @@ -263,8 +277,10 @@ int skl_init_dsp(struct skl *skl) } ops = skl_get_dsp_ops(skl->pci->device); - if (!ops) - return -EIO; + if (!ops) { + ret = -EIO; + goto unmap_mmio; + } loader_ops = ops->loader_ops(); ret = ops->init(bus->dev, mmio_base, irq, @@ -272,11 +288,35 @@ int skl_init_dsp(struct skl *skl) &skl->skl_sst); if (ret < 0) - return ret; + goto unmap_mmio; skl->skl_sst->dsp_ops = ops; + cores = &skl->skl_sst->cores; + cores->count = ops->num_cores; + + cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL); + if (!cores->state) { + ret = -ENOMEM; + goto unmap_mmio; + } + + cores->usage_count = kcalloc(cores->count, sizeof(*cores->usage_count), + GFP_KERNEL); + if (!cores->usage_count) { + ret = -ENOMEM; + goto free_core_state; + } + dev_dbg(bus->dev, "dsp registration status=%d\n", ret); + return 0; + +free_core_state: + kfree(cores->state); + +unmap_mmio: + iounmap(mmio_base); + return ret; } @@ -291,6 +331,9 @@ int skl_free_dsp(struct skl *skl) ctx->dsp_ops->cleanup(bus->dev, ctx); + kfree(ctx->cores.state); + kfree(ctx->cores.usage_count); + if (ctx->dsp->addr.lpe) iounmap(ctx->dsp->addr.lpe); @@ -400,9 +443,12 @@ static void skl_set_base_module_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_base_cfg *base_cfg) { - struct skl_module_fmt *format = &mconfig->in_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_res *res = &module->resources[mconfig->res_idx]; + struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *format = &fmt->inputs[0].fmt; - base_cfg->audio_fmt.number_of_channels = (u8)format->channels; + base_cfg->audio_fmt.number_of_channels = format->channels; base_cfg->audio_fmt.s_freq = format->s_freq; base_cfg->audio_fmt.bit_depth = format->bit_depth; @@ -417,10 +463,10 @@ static void skl_set_base_module_format(struct skl_sst *ctx, base_cfg->audio_fmt.interleaving = format->interleaving_style; - base_cfg->cps = mconfig->mcps; - base_cfg->ibs = mconfig->ibs; - base_cfg->obs = mconfig->obs; - base_cfg->is_pages = mconfig->mem_pages; + base_cfg->cps = res->cps; + base_cfg->ibs = res->ibs; + base_cfg->obs = res->obs; + base_cfg->is_pages = res->is_pages; } /* @@ -508,6 +554,9 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, struct skl_cpr_cfg *cpr_mconfig) { u32 dma_io_buf; + struct skl_module_res *res; + int res_idx = mconfig->res_idx; + struct skl *skl = get_skl_ctx(ctx->dev); cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig); @@ -516,19 +565,27 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, return; } + if (skl->nr_modules) { + res = &mconfig->module->resources[mconfig->res_idx]; + cpr_mconfig->gtw_cfg.dma_buffer_size = res->dma_buffer_size; + goto skip_buf_size_calc; + } else { + res = &mconfig->module->resources[res_idx]; + } + switch (mconfig->hw_conn_type) { case SKL_CONN_SOURCE: if (mconfig->dev_type == SKL_DEVICE_HDAHOST) - dma_io_buf = mconfig->ibs; + dma_io_buf = res->ibs; else - dma_io_buf = mconfig->obs; + dma_io_buf = res->obs; break; case SKL_CONN_SINK: if (mconfig->dev_type == SKL_DEVICE_HDAHOST) - dma_io_buf = mconfig->obs; + dma_io_buf = res->obs; else - dma_io_buf = mconfig->ibs; + dma_io_buf = res->ibs; break; default: @@ -540,6 +597,15 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, cpr_mconfig->gtw_cfg.dma_buffer_size = mconfig->dma_buffer_size * dma_io_buf; + /* fallback to 2ms default value */ + if (!cpr_mconfig->gtw_cfg.dma_buffer_size) { + if (mconfig->hw_conn_type == SKL_CONN_SOURCE) + cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->obs; + else + cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->ibs; + } + +skip_buf_size_calc: cpr_mconfig->cpr_feature_mask = 0; cpr_mconfig->gtw_cfg.config_length = 0; @@ -587,7 +653,9 @@ static void skl_setup_out_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_audio_data_format *out_fmt) { - struct skl_module_fmt *format = &mconfig->out_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *format = &fmt->outputs[0].fmt; out_fmt->number_of_channels = (u8)format->channels; out_fmt->s_freq = format->s_freq; @@ -612,7 +680,9 @@ static void skl_set_src_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_src_module_cfg *src_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *fmt = &iface->outputs[0].fmt; skl_set_base_module_format(ctx, mconfig, (struct skl_base_cfg *)src_mconfig); @@ -629,7 +699,9 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_up_down_mixer_cfg *mixer_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *fmt = &iface->outputs[0].fmt; int i = 0; skl_set_base_module_format(ctx, mconfig, @@ -942,7 +1014,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg { dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", __func__, src_module->id.module_id, src_module->id.pvt_id); - dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, + dev_dbg(ctx->dev, "%s: dst_module=%d dst_instance=%d\n", __func__, dst_module->id.module_id, dst_module->id.pvt_id); dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", @@ -962,8 +1034,8 @@ int skl_unbind_modules(struct skl_sst *ctx, struct skl_ipc_bind_unbind_msg msg; struct skl_module_inst_id src_id = src_mcfg->id; struct skl_module_inst_id dst_id = dst_mcfg->id; - int in_max = dst_mcfg->max_in_queue; - int out_max = src_mcfg->max_out_queue; + int in_max = dst_mcfg->module->max_input_pins; + int out_max = src_mcfg->module->max_output_pins; int src_index, dst_index, src_pin_state, dst_pin_state; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); @@ -1011,6 +1083,21 @@ int skl_unbind_modules(struct skl_sst *ctx, return ret; } +static void fill_pin_params(struct skl_audio_data_format *pin_fmt, + struct skl_module_fmt *format) +{ + pin_fmt->number_of_channels = format->channels; + pin_fmt->s_freq = format->s_freq; + pin_fmt->bit_depth = format->bit_depth; + pin_fmt->valid_bit_depth = format->valid_bit_depth; + pin_fmt->ch_cfg = format->ch_cfg; + pin_fmt->sample_type = format->sample_type; + pin_fmt->channel_map = format->ch_map; + pin_fmt->interleaving = format->interleaving_style; +} + +#define CPR_SINK_FMT_PARAM_ID 2 + /* * Once a module is instantiated it need to be 'bind' with other modules in * the pipeline. For binding we need to find the module pins which are bind @@ -1022,11 +1109,15 @@ int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg *src_mcfg, struct skl_module_cfg *dst_mcfg) { - int ret; + int ret = 0; struct skl_ipc_bind_unbind_msg msg; - int in_max = dst_mcfg->max_in_queue; - int out_max = src_mcfg->max_out_queue; + int in_max = dst_mcfg->module->max_input_pins; + int out_max = src_mcfg->module->max_output_pins; int src_index, dst_index; + struct skl_module_fmt *format; + struct skl_cpr_pin_fmt pin_fmt; + struct skl_module *module; + struct skl_module_iface *fmt; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); @@ -1045,6 +1136,29 @@ int skl_bind_modules(struct skl_sst *ctx, return -EINVAL; } + /* + * Copier module requires the separate large_config_set_ipc to + * configure the pins other than 0 + */ + if (src_mcfg->m_type == SKL_MODULE_TYPE_COPIER && src_index > 0) { + pin_fmt.sink_id = src_index; + module = src_mcfg->module; + fmt = &module->formats[src_mcfg->fmt_idx]; + + /* Input fmt is same as that of src module input cfg */ + format = &fmt->inputs[0].fmt; + fill_pin_params(&(pin_fmt.src_fmt), format); + + format = &fmt->outputs[src_index].fmt; + fill_pin_params(&(pin_fmt.dst_fmt), format); + ret = skl_set_module_params(ctx, (void *)&pin_fmt, + sizeof(struct skl_cpr_pin_fmt), + CPR_SINK_FMT_PARAM_ID, src_mcfg); + + if (ret < 0) + goto out; + } + msg.dst_queue = dst_index; dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", @@ -1062,11 +1176,12 @@ int skl_bind_modules(struct skl_sst *ctx, src_mcfg->m_state = SKL_MODULE_BIND_DONE; src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; - } else { - /* error case , if IPC fails, clear the queue index */ - skl_free_queue(src_mcfg->m_out_pin, src_index); - skl_free_queue(dst_mcfg->m_in_pin, dst_index); + return ret; } +out: + /* error case , if IPC fails, clear the queue index */ + skl_free_queue(src_mcfg->m_out_pin, src_index); + skl_free_queue(dst_mcfg->m_in_pin, dst_index); return ret; } diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 0ebea34a4988833e4033ae0ce280fc87b3598ad7..2b1e513b1680e4c73130710c318e8fe50855c59c 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -33,7 +33,7 @@ #define HDA_STEREO 2 #define HDA_QUAD 4 -static struct snd_pcm_hardware azx_pcm_hw = { +static const struct snd_pcm_hardware azx_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops skl_pcm_dai_ops = { +static const struct snd_soc_dai_ops skl_pcm_dai_ops = { .startup = skl_pcm_open, .shutdown = skl_pcm_close, .prepare = skl_pcm_prepare, @@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = { .trigger = skl_pcm_trigger, }; -static struct snd_soc_dai_ops skl_dmic_dai_ops = { +static const struct snd_soc_dai_ops skl_dmic_dai_ops = { .hw_params = skl_be_hw_params, }; -static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { +static const struct snd_soc_dai_ops skl_be_ssp_dai_ops = { .hw_params = skl_be_hw_params, }; -static struct snd_soc_dai_ops skl_link_dai_ops = { +static const struct snd_soc_dai_ops skl_link_dai_ops = { .prepare = skl_link_pcm_prepare, .hw_params = skl_link_hw_params, .hw_free = skl_link_hw_free, @@ -674,6 +674,32 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { .sig_bits = 32, }, }, +{ + .name = "System Pin2", + .ops = &skl_pcm_dai_ops, + .playback = { + .stream_name = "Headset Playback", + .channels_min = HDA_MONO, + .channels_max = HDA_STEREO, + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, +}, +{ + .name = "Echoref Pin", + .ops = &skl_pcm_dai_ops, + .capture = { + .stream_name = "Echoreference Capture", + .channels_min = HDA_STEREO, + .channels_max = HDA_STEREO, + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, +}, { .name = "Reference Pin", .ops = &skl_pcm_dai_ops, @@ -1194,8 +1220,11 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) { struct skl_sst *ctx = skl->skl_sst; + struct skl_module_inst_id *pin_id; + uuid_le *uuid_mod, *uuid_tplg; + struct skl_module *skl_module; struct uuid_module *module; - uuid_le *uuid_mod; + int i, ret = -EIO; uuid_mod = (uuid_le *)mconfig->guid; @@ -1207,12 +1236,45 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) list_for_each_entry(module, &ctx->uuid_list, list) { if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { mconfig->id.module_id = module->id; - mconfig->is_loadable = module->is_loadable; - return 0; + if (mconfig->module) + mconfig->module->loadable = module->is_loadable; + ret = 0; + break; + } + } + + if (ret) + return ret; + + uuid_mod = &module->uuid; + ret = -EIO; + for (i = 0; i < skl->nr_modules; i++) { + skl_module = skl->modules[i]; + uuid_tplg = &skl_module->uuid; + if (!uuid_le_cmp(*uuid_mod, *uuid_tplg)) { + mconfig->module = skl_module; + ret = 0; + break; } } + if (skl->nr_modules && ret) + return ret; - return -EIO; + list_for_each_entry(module, &ctx->uuid_list, list) { + for (i = 0; i < MAX_IN_QUEUE; i++) { + pin_id = &mconfig->m_in_pin[i].id; + if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid)) + pin_id->module_id = module->id; + } + + for (i = 0; i < MAX_OUT_QUEUE; i++) { + pin_id = &mconfig->m_out_pin[i].id; + if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid)) + pin_id->module_id = module->id; + } + } + + return 0; } static int skl_populate_modules(struct skl *skl) @@ -1284,7 +1346,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver skl_platform_drv = { +static const struct snd_soc_platform_driver skl_platform_drv = { .probe = skl_platform_soc_probe, .ops = &skl_platform_ops, .pcm_new = skl_pcm_new, diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c index 08332723c70029fa49fa3b991b68b358cc1d4158..19ee1d4f3bdff5b2ff5973d702c9ddf714de38ea 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.c +++ b/sound/soc/intel/skylake/skl-sst-dsp.c @@ -47,7 +47,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx) skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1; - for (i = SKL_DSP_CORE0_ID + 1; i < SKL_DSP_CORES_MAX; i++) { + for (i = SKL_DSP_CORE0_ID + 1; i < skl->cores.count; i++) { skl->cores.state[i] = SKL_DSP_RESET; skl->cores.usage_count[i] = 0; } @@ -351,6 +351,8 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) return -EINVAL; } + skl->cores.usage_count[core_id]++; + if (skl->cores.state[core_id] == SKL_DSP_RESET) { ret = ctx->fw_ops.set_state_D0(ctx, core_id); if (ret < 0) { @@ -359,8 +361,6 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) } } - skl->cores.usage_count[core_id]++; - out: dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", core_id, skl->cores.state[core_id], diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index 498b15345b1a657d608a3fcff773dae206e819b0..5234fafb758a0efdd65a60f30f290b24f8d5e780 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c @@ -283,7 +283,7 @@ enum skl_ipc_module_msg { IPC_MOD_SET_D0IX = 8 }; -static void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, +void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, size_t tx_size) { if (tx_size) @@ -347,7 +347,7 @@ static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc, } -static int skl_ipc_process_notification(struct sst_generic_ipc *ipc, +int skl_ipc_process_notification(struct sst_generic_ipc *ipc, struct skl_ipc_header header) { struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); @@ -406,7 +406,7 @@ static int skl_ipc_set_reply_error_code(u32 reply) } } -static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, +void skl_ipc_process_reply(struct sst_generic_ipc *ipc, struct skl_ipc_header header) { struct ipc_message *msg; diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index e057da2713c6cbfe188ff0165c17a0026c7d2476..55f2d2ce09df4017fc0c27a8229e5696dc4834d4 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h @@ -44,12 +44,10 @@ struct skl_ipc_header { u32 extension; }; -#define SKL_DSP_CORES_MAX 2 - struct skl_dsp_cores { unsigned int count; - enum skl_dsp_states state[SKL_DSP_CORES_MAX]; - int usage_count[SKL_DSP_CORES_MAX]; + enum skl_dsp_states *state; + int *usage_count; }; /** @@ -214,4 +212,10 @@ void skl_ipc_free(struct sst_generic_ipc *ipc); int skl_ipc_init(struct device *dev, struct skl_sst *skl); void skl_clear_module_cnt(struct sst_dsp *ctx); +void skl_ipc_process_reply(struct sst_generic_ipc *ipc, + struct skl_ipc_header header); +int skl_ipc_process_notification(struct sst_generic_ipc *ipc, + struct skl_ipc_header header); +void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, + size_t tx_size); #endif /* __SKL_IPC_H */ diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index 81ee251881b448bca09791246f4ab6a2cfc29871..369ef7ce981c799b8fab344ab4f3bfdfa34ed829 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c @@ -368,7 +368,6 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, { struct skl_sst *skl; struct sst_dsp *sst; - int ret; skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); if (skl == NULL) @@ -388,15 +387,12 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, sst->dsp_ops = dsp_ops; init_waitqueue_head(&skl->mod_load_wait); INIT_LIST_HEAD(&sst->module_list); - ret = skl_ipc_init(dev, skl); - if (ret) - return ret; skl->is_first_boot = true; if (dsp) *dsp = skl; - return ret; + return 0; } int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index aba9ea11ac749d7aa285218cc0530fbbd1b34615..a436abf2fe3f38b65e93f9637de0f804b859a2aa 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -503,7 +503,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx) } } -static struct skl_dsp_fw_ops skl_fw_ops = { +static const struct skl_dsp_fw_ops skl_fw_ops = { .set_state_D0 = skl_set_dsp_D0, .set_state_D3 = skl_set_dsp_D3, .load_fw = skl_load_base_firmware, @@ -512,7 +512,7 @@ static struct skl_dsp_fw_ops skl_fw_ops = { .unload_mod = skl_unload_module, }; -static struct skl_dsp_fw_ops kbl_fw_ops = { +static const struct skl_dsp_fw_ops kbl_fw_ops = { .set_state_D0 = skl_set_dsp_D0, .set_state_D3 = skl_set_dsp_D3, .load_fw = skl_load_base_firmware, @@ -561,9 +561,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); - sst->fw_ops = skl_fw_ops; + ret = skl_ipc_init(dev, skl); + if (ret) { + skl_dsp_free(sst); + return ret; + } - skl->cores.count = 2; + sst->fw_ops = skl_fw_ops; return 0; } diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 68c3f121efc3b22a4caff235303be07ba9914721..22f768ca3c73be752b208ac52b06ed52be53bada 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -49,6 +49,9 @@ static const int mic_quatro_list[][SKL_CH_QUATRO] = { {0, 1, 2, 3}, }; +#define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \ + ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq)) + void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps) { struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3; @@ -153,8 +156,10 @@ static bool skl_is_pipe_mcps_avail(struct skl *skl, struct skl_module_cfg *mconfig) { struct skl_sst *ctx = skl->skl_sst; + u8 res_idx = mconfig->res_idx; + struct skl_module_res *res = &mconfig->module->resources[res_idx]; - if (skl->resource.mcps + mconfig->mcps > skl->resource.max_mcps) { + if (skl->resource.mcps + res->cps > skl->resource.max_mcps) { dev_err(ctx->dev, "%s: module_id %d instance %d\n", __func__, mconfig->id.module_id, mconfig->id.instance_id); @@ -170,7 +175,10 @@ static bool skl_is_pipe_mcps_avail(struct skl *skl, static void skl_tplg_alloc_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) { - skl->resource.mcps += mconfig->mcps; + u8 res_idx = mconfig->res_idx; + struct skl_module_res *res = &mconfig->module->resources[res_idx]; + + skl->resource.mcps += res->cps; } /* @@ -179,7 +187,11 @@ static void skl_tplg_alloc_pipe_mcps(struct skl *skl, static void skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) { - skl->resource.mcps -= mconfig->mcps; + u8 res_idx = mconfig->res_idx; + struct skl_module_res *res = &mconfig->module->resources[res_idx]; + + res = &mconfig->module->resources[res_idx]; + skl->resource.mcps -= res->cps; } /* @@ -195,17 +207,21 @@ skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig) static void skl_dump_mconfig(struct skl_sst *ctx, struct skl_module_cfg *mcfg) { + struct skl_module_iface *iface = &mcfg->module->formats[0]; + dev_dbg(ctx->dev, "Dumping config\n"); dev_dbg(ctx->dev, "Input Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg); - dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth); + dev_dbg(ctx->dev, "channels = %d\n", iface->inputs[0].fmt.channels); + dev_dbg(ctx->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq); + dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg); + dev_dbg(ctx->dev, "valid bit depth = %d\n", + iface->inputs[0].fmt.valid_bit_depth); dev_dbg(ctx->dev, "Output Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq); - dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg); + dev_dbg(ctx->dev, "channels = %d\n", iface->outputs[0].fmt.channels); + dev_dbg(ctx->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); + dev_dbg(ctx->dev, "valid bit depth = %d\n", + iface->outputs[0].fmt.valid_bit_depth); + dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg); } static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs) @@ -273,8 +289,8 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg, struct skl_module_fmt *in_fmt, *out_fmt; /* Fixups will be applied to pin 0 only */ - in_fmt = &m_cfg->in_fmt[0]; - out_fmt = &m_cfg->out_fmt[0]; + in_fmt = &m_cfg->module->formats[0].inputs[0].fmt; + out_fmt = &m_cfg->module->formats[0].outputs[0].fmt; if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (is_fe) { @@ -312,21 +328,23 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, { int multiplier = 1; struct skl_module_fmt *in_fmt, *out_fmt; + struct skl_module_res *res; /* Since fixups is applied to pin 0 only, ibs, obs needs * change for pin 0 only */ - in_fmt = &mcfg->in_fmt[0]; - out_fmt = &mcfg->out_fmt[0]; + res = &mcfg->module->resources[0]; + in_fmt = &mcfg->module->formats[0].inputs[0].fmt; + out_fmt = &mcfg->module->formats[0].outputs[0].fmt; if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) multiplier = 5; - mcfg->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) * + res->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) * in_fmt->channels * (in_fmt->bit_depth >> 3) * multiplier; - mcfg->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) * + res->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) * out_fmt->channels * (out_fmt->bit_depth >> 3) * multiplier; } @@ -365,6 +383,8 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, struct nhlt_specific_cfg *cfg; struct skl *skl = get_skl_ctx(ctx->dev); u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); + int fmt_idx = m_cfg->fmt_idx; + struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; /* check if we already have blob */ if (m_cfg->formats_config.caps_size > 0) @@ -375,23 +395,23 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, case SKL_DEVICE_DMIC: link_type = NHLT_LINK_DMIC; dir = SNDRV_PCM_STREAM_CAPTURE; - s_freq = m_cfg->in_fmt[0].s_freq; - s_fmt = m_cfg->in_fmt[0].bit_depth; - ch = m_cfg->in_fmt[0].channels; + s_freq = m_iface->inputs[0].fmt.s_freq; + s_fmt = m_iface->inputs[0].fmt.bit_depth; + ch = m_iface->inputs[0].fmt.channels; break; case SKL_DEVICE_I2S: link_type = NHLT_LINK_SSP; if (m_cfg->hw_conn_type == SKL_CONN_SOURCE) { dir = SNDRV_PCM_STREAM_PLAYBACK; - s_freq = m_cfg->out_fmt[0].s_freq; - s_fmt = m_cfg->out_fmt[0].bit_depth; - ch = m_cfg->out_fmt[0].channels; + s_freq = m_iface->outputs[0].fmt.s_freq; + s_fmt = m_iface->outputs[0].fmt.bit_depth; + ch = m_iface->outputs[0].fmt.channels; } else { dir = SNDRV_PCM_STREAM_CAPTURE; - s_freq = m_cfg->in_fmt[0].s_freq; - s_fmt = m_cfg->in_fmt[0].bit_depth; - ch = m_cfg->in_fmt[0].channels; + s_freq = m_iface->inputs[0].fmt.s_freq; + s_fmt = m_iface->inputs[0].fmt.bit_depth; + ch = m_iface->inputs[0].fmt.channels; } break; @@ -549,6 +569,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) struct snd_soc_dapm_widget *w; struct skl_module_cfg *mconfig; struct skl_sst *ctx = skl->skl_sst; + u8 cfg_idx; int ret = 0; list_for_each_entry(w_module, &pipe->w_list, node) { @@ -564,11 +585,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) return -EIO; } + cfg_idx = mconfig->pipe->cur_config_idx; + mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; + mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; + /* check resource available */ if (!skl_is_pipe_mcps_avail(skl, mconfig)) return -ENOMEM; - if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { + if (mconfig->module->loadable && ctx->dsp->fw_ops.load_mod) { ret = ctx->dsp->fw_ops.load_mod(ctx->dsp, mconfig->id.module_id, mconfig->guid); if (ret < 0) @@ -596,24 +621,35 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) if (mconfig->id.pvt_id < 0) return ret; skl_tplg_set_module_init_data(w); + + ret = skl_dsp_get_core(ctx->dsp, mconfig->core_id); + if (ret < 0) { + dev_err(ctx->dev, "Failed to wake up core %d ret=%d\n", + mconfig->core_id, ret); + return ret; + } + ret = skl_init_module(ctx, mconfig); if (ret < 0) { skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); - return ret; + goto err; } skl_tplg_alloc_pipe_mcps(skl, mconfig); ret = skl_tplg_set_module_params(w, ctx); if (ret < 0) - return ret; + goto err; } return 0; +err: + skl_dsp_put_core(ctx->dsp, mconfig->core_id); + return ret; } static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, struct skl_pipe *pipe) { - int ret; + int ret = 0; struct skl_pipe_module *w_module = NULL; struct skl_module_cfg *mconfig = NULL; @@ -622,7 +658,7 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, mconfig = w_module->w->priv; uuid_mod = (uuid_le *)mconfig->guid; - if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && + if (mconfig->module->loadable && ctx->dsp->fw_ops.unload_mod && mconfig->m_state > SKL_MODULE_UNINIT) { ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp, mconfig->id.module_id); @@ -630,10 +666,76 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, return -EIO; } skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); + + ret = skl_dsp_put_core(ctx->dsp, mconfig->core_id); + if (ret < 0) { + /* don't return; continue with other modules */ + dev_err(ctx->dev, "Failed to sleep core %d ret=%d\n", + mconfig->core_id, ret); + } } /* no modules to unload in this path, so return */ - return 0; + return ret; +} + +/* + * Here, we select pipe format based on the pipe type and pipe + * direction to determine the current config index for the pipeline. + * The config index is then used to select proper module resources. + * Intermediate pipes currently have a fixed format hence we select the + * 0th configuratation by default for such pipes. + */ +static int +skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) +{ + struct skl_sst *ctx = skl->skl_sst; + struct skl_pipe *pipe = mconfig->pipe; + struct skl_pipe_params *params = pipe->p_params; + struct skl_path_config *pconfig = &pipe->configs[0]; + struct skl_pipe_fmt *fmt = NULL; + bool in_fmt = false; + int i; + + if (pipe->nr_cfgs == 0) { + pipe->cur_config_idx = 0; + return 0; + } + + if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) { + dev_dbg(ctx->dev, "No conn_type detected, take 0th config\n"); + pipe->cur_config_idx = 0; + pipe->memory_pages = pconfig->mem_pages; + + return 0; + } + + if ((pipe->conn_type == SKL_PIPE_CONN_TYPE_FE && + pipe->direction == SNDRV_PCM_STREAM_PLAYBACK) || + (pipe->conn_type == SKL_PIPE_CONN_TYPE_BE && + pipe->direction == SNDRV_PCM_STREAM_CAPTURE)) + in_fmt = true; + + for (i = 0; i < pipe->nr_cfgs; i++) { + pconfig = &pipe->configs[i]; + if (in_fmt) + fmt = &pconfig->in_fmt; + else + fmt = &pconfig->out_fmt; + + if (CHECK_HW_PARAMS(params->ch, params->s_freq, params->s_fmt, + fmt->channels, fmt->freq, fmt->bps)) { + pipe->cur_config_idx = i; + pipe->memory_pages = pconfig->mem_pages; + dev_dbg(ctx->dev, "Using pipe config: %d\n", i); + + return 0; + } + } + + dev_err(ctx->dev, "Invalid pipe config: %d %d %d for pipe: %d\n", + params->ch, params->s_freq, params->s_fmt, pipe->ppl_id); + return -EINVAL; } /* @@ -655,6 +757,10 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, struct skl_sst *ctx = skl->skl_sst; struct skl_module_deferred_bind *modules; + ret = skl_tplg_get_pipe_config(skl, mconfig); + if (ret < 0) + return ret; + /* check resource available */ if (!skl_is_pipe_mcps_avail(skl, mconfig)) return -EBUSY; @@ -758,12 +864,12 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, * check all out/in pins are in bind state. * if so set the module param */ - for (i = 0; i < mcfg->max_out_queue; i++) { + for (i = 0; i < mcfg->module->max_output_pins; i++) { if (mcfg->m_out_pin[i].pin_state != SKL_PIN_BIND_DONE) return 0; } - for (i = 0; i < mcfg->max_in_queue; i++) { + for (i = 0; i < mcfg->module->max_input_pins; i++) { if (mcfg->m_in_pin[i].pin_state != SKL_PIN_BIND_DONE) return 0; } @@ -814,7 +920,7 @@ static int skl_tplg_module_add_deferred_bind(struct skl *skl, int i; /* only supported for module with static pin connection */ - for (i = 0; i < dst->max_in_queue; i++) { + for (i = 0; i < dst->module->max_input_pins; i++) { struct skl_module_pin *pin = &dst->m_in_pin[i]; if (pin->is_dynamic) @@ -925,7 +1031,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, } } - if (!sink) + if (!sink && next_sink) return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig); return 0; @@ -1074,7 +1180,7 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, if (ret) return ret; - for (i = 0; i < sink_mconfig->max_in_queue; i++) { + for (i = 0; i < sink_mconfig->module->max_input_pins; i++) { if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) { src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg; if (!src_mconfig) @@ -1185,7 +1291,7 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, if (ret) return ret; - for (i = 0; i < src_mconfig->max_out_queue; i++) { + for (i = 0; i < src_mconfig->module->max_output_pins; i++) { if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) { sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg; if (!sink_mconfig) @@ -1479,14 +1585,22 @@ int skl_tplg_update_pipe_params(struct device *dev, struct skl_module_cfg *mconfig, struct skl_pipe_params *params) { + struct skl_module_res *res = &mconfig->module->resources[0]; + struct skl *skl = get_skl_ctx(dev); struct skl_module_fmt *format = NULL; + u8 cfg_idx = mconfig->pipe->cur_config_idx; skl_tplg_fill_dma_id(mconfig, params); + mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; + mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; + + if (skl->nr_modules) + return 0; if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) - format = &mconfig->in_fmt[0]; + format = &mconfig->module->formats[0].inputs[0].fmt; else - format = &mconfig->out_fmt[0]; + format = &mconfig->module->formats[0].outputs[0].fmt; /* set the hw_params */ format->s_freq = params->s_freq; @@ -1514,11 +1628,11 @@ int skl_tplg_update_pipe_params(struct device *dev, } if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mconfig->ibs = (format->s_freq / 1000) * + res->ibs = (format->s_freq / 1000) * (format->channels) * (format->bit_depth >> 3); } else { - mconfig->obs = (format->s_freq / 1000) * + res->obs = (format->s_freq / 1000) * (format->channels) * (format->bit_depth >> 3); } @@ -1792,6 +1906,54 @@ static const struct snd_soc_tplg_kcontrol_ops skl_tplg_kcontrol_ops[] = { }, }; +static int skl_tplg_fill_pipe_cfg(struct device *dev, + struct skl_pipe *pipe, u32 tkn, + u32 tkn_val, int conf_idx, int dir) +{ + struct skl_pipe_fmt *fmt; + struct skl_path_config *config; + + switch (dir) { + case SKL_DIR_IN: + fmt = &pipe->configs[conf_idx].in_fmt; + break; + + case SKL_DIR_OUT: + fmt = &pipe->configs[conf_idx].out_fmt; + break; + + default: + dev_err(dev, "Invalid direction: %d\n", dir); + return -EINVAL; + } + + config = &pipe->configs[conf_idx]; + + switch (tkn) { + case SKL_TKN_U32_CFG_FREQ: + fmt->freq = tkn_val; + break; + + case SKL_TKN_U8_CFG_CHAN: + fmt->channels = tkn_val; + break; + + case SKL_TKN_U8_CFG_BPS: + fmt->bps = tkn_val; + break; + + case SKL_TKN_U32_PATH_MEM_PGS: + config->mem_pages = tkn_val; + break; + + default: + dev_err(dev, "Invalid token config: %d\n", tkn); + return -EINVAL; + } + + return 0; +} + static int skl_tplg_fill_pipe_tkn(struct device *dev, struct skl_pipe *pipe, u32 tkn, u32 tkn_val) @@ -1814,6 +1976,14 @@ static int skl_tplg_fill_pipe_tkn(struct device *dev, pipe->lp_mode = tkn_val; break; + case SKL_TKN_U32_PIPE_DIRECTION: + pipe->direction = tkn_val; + break; + + case SKL_TKN_U32_NUM_CONFIGS: + pipe->nr_cfgs = tkn_val; + break; + default: dev_err(dev, "Token not handled %d\n", tkn); return -EINVAL; @@ -1930,27 +2100,9 @@ static int skl_tplg_fill_pins_info(struct device *dev, * on the direction */ static int skl_tplg_fill_fmt(struct device *dev, - struct skl_module_cfg *mconfig, u32 tkn, - u32 value, u32 dir, u32 pin_count) + struct skl_module_fmt *dst_fmt, + u32 tkn, u32 value) { - struct skl_module_fmt *dst_fmt; - - switch (dir) { - case SKL_DIR_IN: - dst_fmt = mconfig->in_fmt; - dst_fmt += pin_count; - break; - - case SKL_DIR_OUT: - dst_fmt = mconfig->out_fmt; - dst_fmt += pin_count; - break; - - default: - dev_err(dev, "Invalid direction value\n"); - return -EINVAL; - } - switch (tkn) { case SKL_TKN_U32_FMT_CH: dst_fmt->channels = value; @@ -1992,6 +2144,32 @@ static int skl_tplg_fill_fmt(struct device *dev, return 0; } +static int skl_tplg_widget_fill_fmt(struct device *dev, + struct skl_module_iface *fmt, + u32 tkn, u32 val, u32 dir, int fmt_idx) +{ + struct skl_module_fmt *dst_fmt; + + if (!fmt) + return -EINVAL; + + switch (dir) { + case SKL_DIR_IN: + dst_fmt = &fmt->inputs[fmt_idx].fmt; + break; + + case SKL_DIR_OUT: + dst_fmt = &fmt->outputs[fmt_idx].fmt; + break; + + default: + dev_err(dev, "Invalid direction: %d\n", dir); + return -EINVAL; + } + + return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val); +} + static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig, struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) { @@ -2014,6 +2192,108 @@ static void skl_tplg_fill_pin_dynamic_val( mpin[i].is_dynamic = value; } +/* + * Resource table in the manifest has pin specific resources + * like pin and pin buffer size + */ +static int skl_tplg_manifest_pin_res_tkn(struct device *dev, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + struct skl_module_res *res, int pin_idx, int dir) +{ + struct skl_module_pin_resources *m_pin; + + switch (dir) { + case SKL_DIR_IN: + m_pin = &res->input[pin_idx]; + break; + + case SKL_DIR_OUT: + m_pin = &res->output[pin_idx]; + break; + + default: + dev_err(dev, "Invalid pin direction: %d\n", dir); + return -EINVAL; + } + + switch (tkn_elem->token) { + case SKL_TKN_MM_U32_RES_PIN_ID: + m_pin->pin_index = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_PIN_BUF: + m_pin->buf_size = tkn_elem->value; + break; + + default: + dev_err(dev, "Invalid token: %d\n", tkn_elem->token); + return -EINVAL; + } + + return 0; +} + +/* + * Fill module specific resources from the manifest's resource + * table like CPS, DMA size, mem_pages. + */ +static int skl_tplg_fill_res_tkn(struct device *dev, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + struct skl_module_res *res, + int pin_idx, int dir) +{ + int ret, tkn_count = 0; + + if (!res) + return -EINVAL; + + switch (tkn_elem->token) { + case SKL_TKN_MM_U32_CPS: + res->cps = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_DMA_SIZE: + res->dma_buffer_size = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_CPC: + res->cpc = tkn_elem->value; + break; + + case SKL_TKN_U32_MEM_PAGES: + res->is_pages = tkn_elem->value; + break; + + case SKL_TKN_U32_OBS: + res->obs = tkn_elem->value; + break; + + case SKL_TKN_U32_IBS: + res->ibs = tkn_elem->value; + break; + + case SKL_TKN_U32_MAX_MCPS: + res->cps = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_RES_PIN_ID: + case SKL_TKN_MM_U32_PIN_BUF: + ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res, + pin_idx, dir); + if (ret < 0) + return ret; + break; + + default: + dev_err(dev, "Not a res type token: %d", tkn_elem->token); + return -EINVAL; + + } + tkn_count++; + + return tkn_count; +} + /* * Parse tokens to fill up the module private data */ @@ -2024,49 +2304,54 @@ static int skl_tplg_get_token(struct device *dev, int tkn_count = 0; int ret; static int is_pipe_exists; - static int pin_index, dir; + static int pin_index, dir, conf_idx; + struct skl_module_iface *iface = NULL; + struct skl_module_res *res = NULL; + int res_idx = mconfig->res_idx; + int fmt_idx = mconfig->fmt_idx; + + /* + * If the manifest structure contains no modules, fill all + * the module data to 0th index. + * res_idx and fmt_idx are default set to 0. + */ + if (skl->nr_modules == 0) { + res = &mconfig->module->resources[res_idx]; + iface = &mconfig->module->formats[fmt_idx]; + } if (tkn_elem->token > SKL_TKN_MAX) return -EINVAL; switch (tkn_elem->token) { case SKL_TKN_U8_IN_QUEUE_COUNT: - mconfig->max_in_queue = tkn_elem->value; - mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue * - sizeof(*mconfig->m_in_pin), - GFP_KERNEL); - if (!mconfig->m_in_pin) - return -ENOMEM; - + mconfig->module->max_input_pins = tkn_elem->value; break; case SKL_TKN_U8_OUT_QUEUE_COUNT: - mconfig->max_out_queue = tkn_elem->value; - mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue * - sizeof(*mconfig->m_out_pin), - GFP_KERNEL); - - if (!mconfig->m_out_pin) - return -ENOMEM; - + mconfig->module->max_output_pins = tkn_elem->value; break; case SKL_TKN_U8_DYN_IN_PIN: + if (!mconfig->m_in_pin) + mconfig->m_in_pin = devm_kzalloc(dev, MAX_IN_QUEUE * + sizeof(*mconfig->m_in_pin), GFP_KERNEL); if (!mconfig->m_in_pin) return -ENOMEM; - skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, - mconfig->max_in_queue, tkn_elem->value); - + skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, MAX_IN_QUEUE, + tkn_elem->value); break; case SKL_TKN_U8_DYN_OUT_PIN: + if (!mconfig->m_out_pin) + mconfig->m_out_pin = devm_kzalloc(dev, MAX_IN_QUEUE * + sizeof(*mconfig->m_in_pin), GFP_KERNEL); if (!mconfig->m_out_pin) return -ENOMEM; - skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, - mconfig->max_out_queue, tkn_elem->value); - + skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, MAX_OUT_QUEUE, + tkn_elem->value); break; case SKL_TKN_U8_TIME_SLOT: @@ -2094,19 +2379,13 @@ static int skl_tplg_get_token(struct device *dev, break; case SKL_TKN_U32_MEM_PAGES: - mconfig->mem_pages = tkn_elem->value; - break; - case SKL_TKN_U32_MAX_MCPS: - mconfig->mcps = tkn_elem->value; - break; - case SKL_TKN_U32_OBS: - mconfig->obs = tkn_elem->value; - break; - case SKL_TKN_U32_IBS: - mconfig->ibs = tkn_elem->value; + ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, dir, pin_index); + if (ret < 0) + return ret; + break; case SKL_TKN_U32_VBUS_ID: @@ -2139,10 +2418,16 @@ static int skl_tplg_get_token(struct device *dev, break; + case SKL_TKN_U32_PIPE_CONFIG_ID: + conf_idx = tkn_elem->value; + break; + case SKL_TKN_U32_PIPE_CONN_TYPE: case SKL_TKN_U32_PIPE_PRIORITY: case SKL_TKN_U32_PIPE_MEM_PGS: case SKL_TKN_U32_PMODE: + case SKL_TKN_U32_PIPE_DIRECTION: + case SKL_TKN_U32_NUM_CONFIGS: if (is_pipe_exists) { ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe, tkn_elem->token, tkn_elem->value); @@ -2152,6 +2437,27 @@ static int skl_tplg_get_token(struct device *dev, break; + case SKL_TKN_U32_PATH_MEM_PGS: + case SKL_TKN_U32_CFG_FREQ: + case SKL_TKN_U8_CFG_CHAN: + case SKL_TKN_U8_CFG_BPS: + if (mconfig->pipe->nr_cfgs) { + ret = skl_tplg_fill_pipe_cfg(dev, mconfig->pipe, + tkn_elem->token, tkn_elem->value, + conf_idx, dir); + if (ret < 0) + return ret; + } + break; + + case SKL_TKN_CFG_MOD_RES_ID: + mconfig->mod_cfg[conf_idx].res_idx = tkn_elem->value; + break; + + case SKL_TKN_CFG_MOD_FMT_ID: + mconfig->mod_cfg[conf_idx].fmt_idx = tkn_elem->value; + break; + /* * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both * direction and the pin count. The first four bits represent @@ -2172,7 +2478,7 @@ static int skl_tplg_get_token(struct device *dev, case SKL_TKN_U32_FMT_INTERLEAVE: case SKL_TKN_U32_FMT_SAMPLE_TYPE: case SKL_TKN_U32_FMT_CH_MAP: - ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token, + ret = skl_tplg_widget_fill_fmt(dev, iface, tkn_elem->token, tkn_elem->value, dir, pin_index); if (ret < 0) @@ -2397,11 +2703,11 @@ static void skl_clear_pin_config(struct snd_soc_platform *platform, strlen(platform->component.name))) { mconfig = w->priv; pipe = mconfig->pipe; - for (i = 0; i < mconfig->max_in_queue; i++) { + for (i = 0; i < mconfig->module->max_input_pins; i++) { mconfig->m_in_pin[i].in_use = false; mconfig->m_in_pin[i].pin_state = SKL_PIN_UNBIND; } - for (i = 0; i < mconfig->max_out_queue; i++) { + for (i = 0; i < mconfig->module->max_output_pins; i++) { mconfig->m_out_pin[i].in_use = false; mconfig->m_out_pin[i].pin_state = SKL_PIN_UNBIND; } @@ -2460,6 +2766,13 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, if (!mconfig) return -ENOMEM; + if (skl->nr_modules == 0) { + mconfig->module = devm_kzalloc(bus->dev, + sizeof(*mconfig->module), GFP_KERNEL); + if (!mconfig->module) + return -ENOMEM; + } + w->priv = mconfig; /* @@ -2602,13 +2915,13 @@ static int skl_tplg_fill_str_mfest_tkn(struct device *dev, str_elem->string, ARRAY_SIZE(skl->skl_sst->lib_info[ref_count].name)); ref_count++; - tkn_count++; break; default: dev_err(dev, "Not a string token %d\n", str_elem->token); break; } + tkn_count++; return tkn_count; } @@ -2634,26 +2947,236 @@ static int skl_tplg_get_str_tkn(struct device *dev, return tkn_count; } +static int skl_tplg_manifest_fill_fmt(struct device *dev, + struct skl_module_iface *fmt, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + u32 dir, int fmt_idx) +{ + struct skl_module_pin_fmt *dst_fmt; + struct skl_module_fmt *mod_fmt; + int ret; + + if (!fmt) + return -EINVAL; + + switch (dir) { + case SKL_DIR_IN: + dst_fmt = &fmt->inputs[fmt_idx]; + break; + + case SKL_DIR_OUT: + dst_fmt = &fmt->outputs[fmt_idx]; + break; + + default: + dev_err(dev, "Invalid direction: %d\n", dir); + return -EINVAL; + } + + mod_fmt = &dst_fmt->fmt; + + switch (tkn_elem->token) { + case SKL_TKN_MM_U32_INTF_PIN_ID: + dst_fmt->id = tkn_elem->value; + break; + + default: + ret = skl_tplg_fill_fmt(dev, mod_fmt, tkn_elem->token, + tkn_elem->value); + if (ret < 0) + return ret; + break; + } + + return 0; +} + +static int skl_tplg_fill_mod_info(struct device *dev, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + struct skl_module *mod) +{ + + if (!mod) + return -EINVAL; + + switch (tkn_elem->token) { + case SKL_TKN_U8_IN_PIN_TYPE: + mod->input_pin_type = tkn_elem->value; + break; + + case SKL_TKN_U8_OUT_PIN_TYPE: + mod->output_pin_type = tkn_elem->value; + break; + + case SKL_TKN_U8_IN_QUEUE_COUNT: + mod->max_input_pins = tkn_elem->value; + break; + + case SKL_TKN_U8_OUT_QUEUE_COUNT: + mod->max_output_pins = tkn_elem->value; + break; + + case SKL_TKN_MM_U8_NUM_RES: + mod->nr_resources = tkn_elem->value; + break; + + case SKL_TKN_MM_U8_NUM_INTF: + mod->nr_interfaces = tkn_elem->value; + break; + + default: + dev_err(dev, "Invalid mod info token %d", tkn_elem->token); + return -EINVAL; + } + + return 0; +} + + static int skl_tplg_get_int_tkn(struct device *dev, struct snd_soc_tplg_vendor_value_elem *tkn_elem, struct skl *skl) { - int tkn_count = 0; + int tkn_count = 0, ret; + static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; + struct skl_module_res *res = NULL; + struct skl_module_iface *fmt = NULL; + struct skl_module *mod = NULL; + int i; + + if (skl->modules) { + mod = skl->modules[mod_idx]; + res = &mod->resources[res_val_idx]; + fmt = &mod->formats[intf_val_idx]; + } switch (tkn_elem->token) { case SKL_TKN_U32_LIB_COUNT: skl->skl_sst->lib_count = tkn_elem->value; - tkn_count++; + break; + + case SKL_TKN_U8_NUM_MOD: + skl->nr_modules = tkn_elem->value; + skl->modules = devm_kcalloc(dev, skl->nr_modules, + sizeof(*skl->modules), GFP_KERNEL); + if (!skl->modules) + return -ENOMEM; + + for (i = 0; i < skl->nr_modules; i++) { + skl->modules[i] = devm_kzalloc(dev, + sizeof(struct skl_module), GFP_KERNEL); + if (!skl->modules[i]) + return -ENOMEM; + } + break; + + case SKL_TKN_MM_U8_MOD_IDX: + mod_idx = tkn_elem->value; + break; + + case SKL_TKN_U8_IN_PIN_TYPE: + case SKL_TKN_U8_OUT_PIN_TYPE: + case SKL_TKN_U8_IN_QUEUE_COUNT: + case SKL_TKN_U8_OUT_QUEUE_COUNT: + case SKL_TKN_MM_U8_NUM_RES: + case SKL_TKN_MM_U8_NUM_INTF: + ret = skl_tplg_fill_mod_info(dev, tkn_elem, mod); + if (ret < 0) + return ret; + break; + + case SKL_TKN_U32_DIR_PIN_COUNT: + dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK; + pin_idx = (tkn_elem->value & SKL_PIN_COUNT_MASK) >> 4; + break; + + case SKL_TKN_MM_U32_RES_ID: + if (!res) + return -EINVAL; + + res->id = tkn_elem->value; + res_val_idx = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_FMT_ID: + if (!fmt) + return -EINVAL; + + fmt->fmt_idx = tkn_elem->value; + intf_val_idx = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_CPS: + case SKL_TKN_MM_U32_DMA_SIZE: + case SKL_TKN_MM_U32_CPC: + case SKL_TKN_U32_MEM_PAGES: + case SKL_TKN_U32_OBS: + case SKL_TKN_U32_IBS: + case SKL_TKN_MM_U32_RES_PIN_ID: + case SKL_TKN_MM_U32_PIN_BUF: + ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_idx, dir); + if (ret < 0) + return ret; + + break; + + case SKL_TKN_MM_U32_NUM_IN_FMT: + if (!fmt) + return -EINVAL; + + res->nr_input_pins = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_NUM_OUT_FMT: + if (!fmt) + return -EINVAL; + + res->nr_output_pins = tkn_elem->value; + break; + + case SKL_TKN_U32_FMT_CH: + case SKL_TKN_U32_FMT_FREQ: + case SKL_TKN_U32_FMT_BIT_DEPTH: + case SKL_TKN_U32_FMT_SAMPLE_SIZE: + case SKL_TKN_U32_FMT_CH_CONFIG: + case SKL_TKN_U32_FMT_INTERLEAVE: + case SKL_TKN_U32_FMT_SAMPLE_TYPE: + case SKL_TKN_U32_FMT_CH_MAP: + case SKL_TKN_MM_U32_INTF_PIN_ID: + ret = skl_tplg_manifest_fill_fmt(dev, fmt, tkn_elem, + dir, pin_idx); + if (ret < 0) + return ret; break; default: dev_err(dev, "Not a manifest token %d\n", tkn_elem->token); return -EINVAL; } + tkn_count++; return tkn_count; } +static int skl_tplg_get_manifest_uuid(struct device *dev, + struct skl *skl, + struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) +{ + static int ref_count; + struct skl_module *mod; + + if (uuid_tkn->token == SKL_TKN_UUID) { + mod = skl->modules[ref_count]; + memcpy(&mod->uuid, &uuid_tkn->uuid, sizeof(uuid_tkn->uuid)); + ref_count++; + } else { + dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token); + return -EINVAL; + } + + return 0; +} + /* * Fill the manifest structure by parsing the tokens based on the * type. @@ -2686,7 +3209,11 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, continue; case SND_SOC_TPLG_TUPLE_TYPE_UUID: - dev_warn(dev, "no uuid tokens for skl tplf manifest\n"); + ret = skl_tplg_get_manifest_uuid(dev, skl, array->uuid); + if (ret < 0) + return ret; + + tuple_size += sizeof(*array->uuid); continue; default: @@ -2703,14 +3230,12 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, tkn_count = tkn_count + ret; tkn_elem++; - tuple_size += tkn_count * - sizeof(struct snd_soc_tplg_vendor_value_elem); - break; } + tuple_size += (tkn_count * sizeof(*tkn_elem)); tkn_count = 0; } - return 0; + return off; } /* @@ -2733,11 +3258,10 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, num_blocks = ret; off += array->size; - array = (struct snd_soc_tplg_vendor_array *) - (manifest->priv.data + off); - /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */ while (num_blocks > 0) { + array = (struct snd_soc_tplg_vendor_array *) + (manifest->priv.data + off); ret = skl_tplg_get_desc_blocks(dev, array); if (ret < 0) @@ -2771,6 +3295,7 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, } else { return -EINVAL; } + off += ret; } return 0; diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index c25e8868b84e670cb765f815d2b69f409c245c22..2717db92036b4cc58ac7148904b41d00d16d4805 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -44,6 +44,13 @@ #define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF #define SKL_MIC_SEL_SWITCH 0x3 +#define SKL_OUTPUT_PIN 0 +#define SKL_INPUT_PIN 1 +#define SKL_MAX_PATH_CONFIGS 8 +#define SKL_MAX_MODULES_IN_PIPE 8 +#define SKL_MAX_MODULE_FORMATS 32 +#define SKL_MAX_MODULE_RESOURCES 32 + enum skl_channel_index { SKL_CHANNEL_LEFT = 0, SKL_CHANNEL_RIGHT = 1, @@ -131,6 +138,11 @@ struct skl_cpr_cfg { struct skl_cpr_gtw_cfg gtw_cfg; } __packed; +struct skl_cpr_pin_fmt { + u32 sink_id; + struct skl_audio_data_format src_fmt; + struct skl_audio_data_format dst_fmt; +} __packed; struct skl_src_module_cfg { struct skl_base_cfg base_cfg; @@ -214,6 +226,7 @@ struct skl_kpb_params { }; struct skl_module_inst_id { + uuid_le mod_uuid; int module_id; u32 instance_id; int pvt_id; @@ -266,6 +279,23 @@ struct skl_pipe_params { unsigned int link_bps; }; +struct skl_pipe_fmt { + u32 freq; + u8 channels; + u8 bps; +}; + +struct skl_pipe_mcfg { + u8 res_idx; + u8 fmt_idx; +}; + +struct skl_path_config { + u8 mem_pages; + struct skl_pipe_fmt in_fmt; + struct skl_pipe_fmt out_fmt; +}; + struct skl_pipe { u8 ppl_id; u8 pipe_priority; @@ -274,6 +304,10 @@ struct skl_pipe { u8 lp_mode; struct skl_pipe_params *p_params; enum skl_pipe_state state; + u8 direction; + u8 cur_config_idx; + u8 nr_cfgs; + struct skl_path_config configs[SKL_MAX_PATH_CONFIGS]; struct list_head w_list; bool passthru; }; @@ -292,9 +326,57 @@ enum d0i3_capability { SKL_D0I3_NON_STREAMING = 2, }; +struct skl_module_pin_fmt { + u8 id; + struct skl_module_fmt fmt; +}; + +struct skl_module_iface { + u8 fmt_idx; + u8 nr_in_fmt; + u8 nr_out_fmt; + struct skl_module_pin_fmt inputs[MAX_IN_QUEUE]; + struct skl_module_pin_fmt outputs[MAX_OUT_QUEUE]; +}; + +struct skl_module_pin_resources { + u8 pin_index; + u32 buf_size; +}; + +struct skl_module_res { + u8 id; + u32 is_pages; + u32 cps; + u32 ibs; + u32 obs; + u32 dma_buffer_size; + u32 cpc; + u8 nr_input_pins; + u8 nr_output_pins; + struct skl_module_pin_resources input[MAX_IN_QUEUE]; + struct skl_module_pin_resources output[MAX_OUT_QUEUE]; +}; + +struct skl_module { + uuid_le uuid; + u8 loadable; + u8 input_pin_type; + u8 output_pin_type; + u8 max_input_pins; + u8 max_output_pins; + u8 nr_resources; + u8 nr_interfaces; + struct skl_module_res resources[SKL_MAX_MODULE_RESOURCES]; + struct skl_module_iface formats[SKL_MAX_MODULE_FORMATS]; +}; + struct skl_module_cfg { u8 guid[16]; struct skl_module_inst_id id; + struct skl_module *module; + int res_idx; + int fmt_idx; u8 domain; bool homogenous_inputs; bool homogenous_outputs; @@ -329,6 +411,7 @@ struct skl_module_cfg { enum skl_module_state m_state; struct skl_pipe *pipe; struct skl_specific_cfg formats_config; + struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE]; }; struct skl_algo_data { diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 334917ee41cf8ede4aa443cc9eb8d7653e6471ac..f94b484abb992e92c156e10f9144b1368d93d969 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -415,7 +415,7 @@ static int skl_free(struct hdac_ext_bus *ebus) snd_hdac_ext_stop_streams(ebus); if (bus->irq >= 0) - free_irq(bus->irq, (void *)bus); + free_irq(bus->irq, (void *)ebus); snd_hdac_bus_free_stream_pages(bus); snd_hdac_stream_free_all(ebus); snd_hdac_link_free_all(ebus); @@ -528,7 +528,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr) } /* Codec initialization */ -static int skl_codec_create(struct hdac_ext_bus *ebus) +static void skl_codec_create(struct hdac_ext_bus *ebus) { struct hdac_bus *bus = ebus_to_hbus(ebus); int c, max_slots; @@ -559,8 +559,6 @@ static int skl_codec_create(struct hdac_ext_bus *ebus) } } } - - return 0; } static const struct hdac_bus_ops bus_core_ops = { @@ -612,9 +610,7 @@ static void skl_probe_work(struct work_struct *work) dev_info(bus->dev, "no hda codecs found!\n"); /* create codec instances */ - err = skl_codec_create(ebus); - if (err < 0) - goto out_err; + skl_codec_create(ebus); if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { err = snd_hdac_display_power(bus, false); @@ -702,6 +698,8 @@ static int skl_first_init(struct hdac_ext_bus *ebus) return -ENXIO; } + skl_init_chip(bus, true); + snd_hdac_bus_parse_capabilities(bus); if (skl_acquire_irq(ebus, 0) < 0) @@ -879,12 +877,12 @@ static void skl_remove(struct pci_dev *pci) static struct sst_codecs skl_codecs = { .num_codecs = 1, - .codecs = {"NAU88L25"} + .codecs = {"10508825"} }; static struct sst_codecs kbl_codecs = { .num_codecs = 1, - .codecs = {"NAU88L25"} + .codecs = {"10508825"} }; static struct sst_codecs bxt_codecs = { @@ -941,6 +939,7 @@ static struct sst_acpi_mach sst_bxtp_devdata[] = { .machine_quirk = sst_acpi_codec_list, .quirk_data = &bxt_codecs, }, + {} }; static struct sst_acpi_mach sst_kbl_devdata[] = { @@ -981,6 +980,11 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { .quirk_data = &kbl_poppy_codecs, .pdata = &skl_dmic_data }, + { + .id = "10EC5663", + .drv_name = "kbl_rt5663", + .fw_filename = "intel/dsp_fw_kbl.bin", + }, {} }; @@ -991,6 +995,15 @@ static struct sst_acpi_mach sst_glk_devdata[] = { .drv_name = "glk_alc298s_i2s", .fw_filename = "intel/dsp_fw_glk.bin", }, + {} +}; + +static const struct sst_acpi_mach sst_cnl_devdata[] = { + { + .id = "INT34C2", + .drv_name = "cnl_rt274", + .fw_filename = "intel/dsp_fw_cnl.bin", + }, }; /* PCI IDs */ @@ -1007,6 +1020,9 @@ static const struct pci_device_id skl_ids[] = { /* GLK */ { PCI_DEVICE(0x8086, 0x3198), .driver_data = (unsigned long)&sst_glk_devdata}, + /* CNL */ + { PCI_DEVICE(0x8086, 0x9dc8), + .driver_data = (unsigned long)&sst_cnl_devdata}, { 0, } }; MODULE_DEVICE_TABLE(pci, skl_ids); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index a6b134b4c037d52bc5fc948b8064c9f2b7f577b3..8d9d6899f761b2a55991ebea505a0e9f9a964fd8 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -71,6 +71,8 @@ struct skl { struct work_struct probe_work; struct skl_debug *debugfs; + u8 nr_modules; + struct skl_module **modules; }; #define skl_to_ebus(s) (&(s)->ebus) @@ -90,6 +92,7 @@ struct skl_machine_pdata { struct skl_dsp_ops { int id; + unsigned int num_cores; struct skl_dsp_loader_ops (*loader_ops)(void); int (*init)(struct device *dev, void __iomem *mmio_base, int irq, const char *fw_name, diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 794a3499e567c3a907e70b8c1c57aafce6aab207..99394c03699819343d351a932ec84799001e7d2d 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -133,6 +133,7 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream, { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf, ctrl; + int ret; if (dai->active) return 0; @@ -141,7 +142,9 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream, ctrl |= JZ_AIC_CTRL_FLUSH; jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); - clk_prepare_enable(i2s->clk_i2s); + ret = clk_prepare_enable(i2s->clk_i2s); + if (ret) + return ret; conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); conf |= JZ_AIC_CONF_ENABLE; @@ -352,11 +355,18 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf; + int ret; - clk_prepare_enable(i2s->clk_aic); + ret = clk_prepare_enable(i2s->clk_aic); + if (ret) + return ret; if (dai->active) { - clk_prepare_enable(i2s->clk_i2s); + ret = clk_prepare_enable(i2s->clk_i2s); + if (ret) { + clk_disable_unprepare(i2s->clk_aic); + return ret; + } conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); conf |= JZ_AIC_CONF_ENABLE; @@ -387,8 +397,11 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf; + int ret; - clk_prepare_enable(i2s->clk_aic); + ret = clk_prepare_enable(i2s->clk_aic); + if (ret) + return ret; jz4740_i2c_init_pcm_config(i2s); snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index dafd22e874e99139ccca45599fd8393c93f75dd2..cf23af159acf46cd54daaf78af50cf2f6ab326f9 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -27,7 +27,7 @@ static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) return snd_soc_dai_get_drvdata(soc_runtime->cpu_dai); } -static struct snd_pcm_hardware kirkwood_dma_snd_hw = { +static const struct snd_pcm_hardware kirkwood_dma_snd_hw = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 3a36d60e178504637963a3193f2a60514e0d272f..105a73cc5158519da5f62e256c4a72c1e5d40c49 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -538,10 +538,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) int err; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "allocation failed\n"); + if (!priv) return -ENOMEM; - } + dev_set_drvdata(&pdev->dev, priv); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -550,9 +549,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) return PTR_ERR(priv->io); priv->irq = platform_get_irq(pdev, 0); - if (priv->irq <= 0) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); - return -ENXIO; + if (priv->irq < 0) { + dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq); + return priv->irq; } if (np) { diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c index b815ecc6bbf6b39eb279d08fdb9ee5384bdda48f..affa7fb25dd9080b853672d9669d0820205443cf 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c @@ -75,7 +75,7 @@ int mt2701_init_clock(struct mtk_base_afe *afe) for (i = 0; i < MT2701_CLOCK_NUM; i++) { afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); - if (IS_ERR(aud_clks[i])) { + if (IS_ERR(afe_priv->clocks[i])) { dev_warn(afe->dev, "%s devm_clk_get %s fail\n", __func__, aud_clks[i]); return PTR_ERR(aud_clks[i]); diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c index bc5d4db94de6947ffc53b80e8ad3a8a3b4561ae7..8fda182f849b1758b776192752f1654add8ab2e7 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c @@ -595,7 +595,7 @@ static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = { }; /* MRG BE DAIs */ -static struct snd_soc_dai_ops mt2701_btmrg_ops = { +static const struct snd_soc_dai_ops mt2701_btmrg_ops = { .startup = mt2701_btmrg_startup, .shutdown = mt2701_btmrg_shutdown, .hw_params = mt2701_btmrg_hw_params, @@ -1496,14 +1496,12 @@ static int mt2701_afe_runtime_resume(struct device *dev) static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) { - int ret, i; - unsigned int irq_id; struct mtk_base_afe *afe; struct mt2701_afe_private *afe_priv; struct resource *res; struct device *dev; + int i, irq_id, ret; - ret = 0; afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); if (!afe) return -ENOMEM; @@ -1516,11 +1514,12 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) afe->dev = &pdev->dev; dev = afe->dev; - irq_id = platform_get_irq(pdev, 0); - if (!irq_id) { - dev_err(dev, "%s no irq found\n", dev->of_node->name); - return -ENXIO; + irq_id = platform_get_irq_byname(pdev, "asys"); + if (irq_id < 0) { + dev_err(dev, "unable to get ASYS IRQ\n"); + return irq_id; } + ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); if (ret) { diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c index 5e383eb456a4b22d1adc6aca0d65efa7b53a350c..99c15219dbc819404a14c4ea322f1a4eaf3ade45 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c @@ -222,7 +222,6 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev) mt8173_rt5650_rt5514_codecs[1].of_node; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index fed1f15a39c24003885afe273d340a98c8599756..42de84ca8c8443450d049f4d22d2f249f5d3fa3b 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c @@ -279,7 +279,6 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) } card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index a78470839b65e0edcd5d69dd599a6b398dc340a0..e69c141d8ed4c9a72d18187d1701c903cec41331 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c @@ -311,7 +311,6 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) return -EINVAL; } card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index b42f301c6b960490d9392902e16e1dbbf78045a7..156aa7c00787860b1f26267ffcf4267601433acf 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -125,7 +125,9 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, * * If MCLK is not used, we just set saif clk to 512*fs. */ - clk_prepare_enable(master_saif->clk); + ret = clk_prepare_enable(master_saif->clk); + if (ret) + return ret; if (master_saif->mclk_in_use) { switch (mclk / rate) { @@ -388,6 +390,7 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); + int ret; /* clear error status to 0 for each re-open */ saif->fifo_underrun = 0; @@ -401,7 +404,9 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, __raw_writel(BM_SAIF_CTRL_CLKGATE, saif->base + SAIF_CTRL + MXS_CLR_ADDR); - clk_prepare(saif->clk); + ret = clk_prepare(saif->clk); + if (ret) + return ret; return 0; } @@ -468,7 +473,9 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - clk_prepare(master_saif->clk); + ret = clk_prepare(master_saif->clk); + if (ret) + return ret; } scr = __raw_readl(saif->base + SAIF_CTRL); diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index a96276e773328b39b0feb1d6d603b77a672d2048..2ed3240cc68210b38ac4b215f0eddc4bff2d943b 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -140,7 +140,6 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev) } card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) { diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index 2cca055fd806cdb80e7226557af943533680c2f8..bd6dfa218d59844eaec9ff37a0f74652997d0f43 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c @@ -271,7 +271,7 @@ static int nuc900_dma_mmap(struct snd_pcm_substream *substream, runtime->dma_addr, runtime->dma_bytes); } -static struct snd_pcm_ops nuc900_dma_ops = { +static const struct snd_pcm_ops nuc900_dma_ops = { .open = nuc900_dma_open, .close = nuc900_dma_close, .ioctl = snd_pcm_lib_ioctl, @@ -299,7 +299,7 @@ static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_platform_driver nuc900_soc_platform = { +static const struct snd_soc_platform_driver nuc900_soc_platform = { .ops = &nuc900_dma_ops, .pcm_new = nuc900_dma_new, }; diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 16cc95fa45731b3f9ed6f47896b95b0eadf3a025..6c49f3d6fd965bcbfe984f2fcf457c2bc832181b 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -513,15 +513,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int ams_delta_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&ams_delta_hook_switch, - ARRAY_SIZE(ams_delta_hook_switch_gpios), - ams_delta_hook_switch_gpios); - - return 0; -} - /* DAI glue - connects codec <--> CPU */ static struct snd_soc_dai_link ams_delta_dai_link = { .name = "CX20442", @@ -540,7 +531,6 @@ static struct snd_soc_dai_link ams_delta_dai_link = { static struct snd_soc_card ams_delta_audio_card = { .name = "AMS_DELTA", .owner = THIS_MODULE, - .remove = ams_delta_card_remove, .dai_link = &ams_delta_dai_link, .num_links = 1, diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c index 888133f9e65d0188def0b7cb374621d940a0b1b8..3e9cc4842a1db14c2e8b0dc0a60dd462305f07aa 100644 --- a/sound/soc/omap/omap-hdmi-audio.c +++ b/sound/soc/omap/omap-hdmi-audio.c @@ -337,14 +337,11 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) ad->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; mutex_init(&ad->current_stream_lock); - switch (ha->dss_version) { - case OMAPDSS_VER_OMAP4430_ES1: - case OMAPDSS_VER_OMAP4430_ES2: - case OMAPDSS_VER_OMAP4: + switch (ha->version) { + case 4: dai_drv = &omap4_hdmi_dai; break; - case OMAPDSS_VER_OMAP5: - case OMAPDSS_VER_DRA7xx: + case 5: dai_drv = &omap5_hdmi_dai; break; default: diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 94e9ff791f3aa5b9d053b1acf4b14b0a0a99203a..aca2c43d0f03ee69421416d4d1e55c12de4a46f0 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -162,7 +162,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, runtime->dma_addr, runtime->dma_bytes); } -static struct snd_pcm_ops omap_pcm_ops = { +static const struct snd_pcm_ops omap_pcm_ops = { .open = omap_pcm_open, .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, @@ -243,7 +243,7 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver omap_soc_platform = { +static const struct snd_soc_platform_driver omap_soc_platform = { .ops = &omap_pcm_ops, .pcm_new = omap_pcm_new, .pcm_free = omap_pcm_free_dma_buffers, diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index a24b0dedabb9b20501f98247ea1a0dc311f52d7b..cccc316743fa682680bdf2d1d6e70b9cf8cc2ef7 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -208,18 +208,6 @@ static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int omap_twl4030_card_remove(struct snd_soc_card *card) -{ - struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); - - if (priv->jack_detect > 0) - snd_soc_jack_free_gpios(&priv->hs_jack, - ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return 0; -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { { @@ -247,7 +235,6 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { /* Audio machine driver */ static struct snd_soc_card omap_twl4030_card = { .owner = THIS_MODULE, - .remove = omap_twl4030_card_remove, .dai_link = omap_twl4030_dai_links, .num_links = ARRAY_SIZE(omap_twl4030_dai_links), diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 3aeb65feaea1de397a7dfee59a0b5d036a22ebd5..57448bd5ad7703cb9084ce7409c4656721103f2f 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -311,14 +311,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int rx51_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), - rx51_av_jack_gpios); - - return 0; -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link rx51_dai[] = { { @@ -361,7 +353,6 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = { static struct snd_soc_card rx51_sound_card = { .name = "RX-51", .owner = THIS_MODULE, - .remove = rx51_card_remove, .dai_link = rx51_dai, .num_links = ARRAY_SIZE(rx51_dai), .aux_dev = rx51_aux_dev, diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 960744e46edc0549854f2ec5e28e68bf8a60a232..484ab3c2ad672fc819aa6101f0e442e507b8e785 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -1,6 +1,7 @@ config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" depends on ARCH_PXA || COMPILE_TEST + depends on HAS_DMA select SND_PXA2XX_LIB help Say Y or M if you want to add support for codecs attached to diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index a9ac881c2e143acef4e655e0056269ab813ff32b..6cdef5d4954e5cc397abe2613e363522c0f68d0c 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c @@ -138,13 +138,6 @@ static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int hx4700_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio); - - return 0; -} - /* hx4700 digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link hx4700_dai = { .name = "ak4641", @@ -163,7 +156,6 @@ static struct snd_soc_dai_link hx4700_dai = { static struct snd_soc_card snd_soc_card_hx4700 = { .name = "iPAQ hx4700", .owner = THIS_MODULE, - .remove = hx4700_card_remove, .dai_link = &hx4700_dai, .num_links = 1, .dapm_widgets = hx4700_dapm_widgets, diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 5b5f1a442891ab8b2f9afbfb4fedcb4218bc0dac..624d9bd5dadd2701c02f5103a71b12b00cd85cd9 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -131,7 +131,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream, vma->vm_end - vma->vm_start, vma->vm_page_prot); } -static struct snd_pcm_ops mmp_pcm_ops = { +static const struct snd_pcm_ops mmp_pcm_ops = { .open = mmp_pcm_open, .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, @@ -211,7 +211,7 @@ static int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver mmp_soc_platform = { +static const struct snd_soc_platform_driver mmp_soc_platform = { .ops = &mmp_pcm_ops, .pcm_new = mmp_pcm_new, .pcm_free = mmp_pcm_free_dma_buffers, diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 9cc35012e6e5904f39673da1e5c116f068dc90c5..64b85e30c1f87205e981b0a4ef119d40d2197758 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -380,7 +380,7 @@ static int mmp_sspa_probe(struct snd_soc_dai *dai) SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops mmp_sspa_dai_ops = { +static const struct snd_soc_dai_ops mmp_sspa_dai_ops = { .startup = mmp_sspa_startup, .shutdown = mmp_sspa_shutdown, .trigger = mmp_sspa_trigger, diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index b51d7a0755d5c7868769c803fa16cbc61a36a81f..e64958d8bff0d727ca0712a495c28297f53a5940 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -45,7 +45,7 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops pxa2xx_pcm_ops = { +static const struct snd_pcm_ops pxa2xx_pcm_ops = { .open = __pxa2xx_pcm_open, .close = __pxa2xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -84,7 +84,7 @@ static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver pxa2xx_soc_platform = { +static const struct snd_soc_platform_driver pxa2xx_soc_platform = { .ops = &pxa2xx_pcm_ops, .pcm_new = pxa2xx_soc_pcm_new, .pcm_free = pxa2xx_pcm_free_dma_buffers, diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index d084d746829988f5e76c3131e894e3e74e1ff786..d49adc822a110ed2a9b61f1916570ed70065a3fd 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c @@ -21,12 +21,16 @@ #include #include #include +#include #include +#include #include struct apq8016_sbc_data { void __iomem *mic_iomux; void __iomem *spkr_iomux; + struct snd_soc_jack jack; + bool jack_setup; struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ }; @@ -34,13 +38,16 @@ struct apq8016_sbc_data { #define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17) #define MIC_CTRL_TLMM_SCLK_EN BIT(1) #define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16)) +#define DEFAULT_MCLK_RATE 9600000 static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_codec *codec; + struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_card *card = rtd->card; struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); - int rval = 0; + int i, rval; switch (cpu_dai->id) { case MI2S_PRIMARY: @@ -63,12 +70,54 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) default: dev_err(card->dev, "unsupported cpu dai configuration\n"); - rval = -EINVAL; - break; + return -EINVAL; + + } + + if (!pdata->jack_setup) { + struct snd_jack *jack; + + rval = snd_soc_card_jack_new(card, "Headset Jack", + SND_JACK_HEADSET | + SND_JACK_HEADPHONE | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | + SND_JACK_BTN_4, + &pdata->jack, NULL, 0); + + if (rval < 0) { + dev_err(card->dev, "Unable to add Headphone Jack\n"); + return rval; + } + jack = pdata->jack.jack; + + snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA); + snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + pdata->jack_setup = true; + } + + for (i = 0 ; i < dai_link->num_codecs; i++) { + struct snd_soc_dai *dai = rtd->codec_dais[i]; + + codec = dai->codec; + /* Set default mclk for internal codec */ + rval = snd_soc_codec_set_sysclk(codec, 0, 0, DEFAULT_MCLK_RATE, + SND_SOC_CLOCK_IN); + if (rval != 0 && rval != -ENOTSUPP) { + dev_warn(card->dev, "Failed to set mclk: %d\n", rval); + return rval; + } + rval = snd_soc_codec_set_jack(codec, &pdata->jack, NULL); + if (rval != 0 && rval != -ENOTSUPP) { + dev_warn(card->dev, "Failed to set jack: %d\n", rval); + return rval; + } } - return rval; + return 0; } static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) @@ -191,7 +240,6 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev) if (IS_ERR(data->spkr_iomux)) return PTR_ERR(data->spkr_iomux); - platform_set_drvdata(pdev, data); snd_soc_card_set_drvdata(card, data); return devm_snd_soc_register_card(&pdev->dev, card); diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c index 7aabf08de3d4aeca35bc9e2b2a8297eb814d3c1d..e1945e1772cda976a1a9c689c5f36c750e5a3ff2 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -32,7 +32,7 @@ struct lpass_pcm_data { #define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) #define LPASS_PLATFORM_PERIODS 2 -static struct snd_pcm_hardware lpass_platform_pcm_hardware = { +static const struct snd_pcm_hardware lpass_platform_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -557,7 +557,7 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm) } } -static struct snd_soc_platform_driver lpass_platform_driver = { +static const struct snd_soc_platform_driver lpass_platform_driver = { .pcm_new = lpass_platform_pcm_new, .pcm_free = lpass_platform_pcm_free, .ops = &lpass_platform_pcm_ops, diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c index c5207af1410485f32e664c2c640f1411683fcd9e..a9fa972466ad155fd4b681bdb530bd953b13e55a 100644 --- a/sound/soc/qcom/storm.c +++ b/sound/soc/qcom/storm.c @@ -99,7 +99,6 @@ static int storm_platform_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = snd_soc_of_parse_card_name(card, "qcom,model"); if (ret) { diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index c84487805876addf89bb6cd12f71e32a306f94b9..b0825370d262f43730a9e96afd8a6d8239579797 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -68,6 +68,8 @@ config SND_SOC_RK3399_GRU_SOUND select SND_SOC_RT5514 select SND_SOC_DA7219 select SND_SOC_RT5514_SPI + select SND_SOC_HDMI_CODEC + select SND_SOC_DMIC help Say Y or M here if you want to add support multiple codecs for SoC audio on Rockchip RK3399 GRU boards. diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c index dbc53e48c52c5bfc0f1aaf4cfa550706a0936ad7..fa44e3901336d97342a1e158a2c1c066f9d0bc41 100644 --- a/sound/soc/rockchip/rk3288_hdmi_analog.c +++ b/sound/soc/rockchip/rk3288_hdmi_analog.c @@ -147,7 +147,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime) return 0; } -static struct snd_soc_ops rk_ops = { +static const struct snd_soc_ops rk_ops = { .hw_params = rk_hw_params, }; @@ -272,8 +272,6 @@ static int snd_rk_mc_probe(struct platform_device *pdev) return ret; } - platform_set_drvdata(pdev, card); - return ret; } diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index 3475c61a5fa0bf76f989bd21bf43815b75aef627..0513fe48035309a90e806eec2cebbb9765338132 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -38,7 +38,7 @@ #define SOUND_FS 256 -static unsigned int rt5514_dmic_delay; +static unsigned int dmic_wakeup_delay; static struct snd_soc_jack rockchip_sound_jack; @@ -126,7 +126,7 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream, } /* Wait for DMIC stable */ - msleep(rt5514_dmic_delay); + msleep(dmic_wakeup_delay); return 0; } @@ -228,6 +228,67 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int rockchip_sound_cdndp_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int mclk, ret; + + /* in bypass mode, the mclk has to be one of the frequencies below */ + switch (params_rate(params)) { + case 8000: + case 16000: + case 24000: + case 32000: + case 48000: + case 64000: + case 96000: + mclk = 12288000; + break; + case 11025: + case 22050: + case 44100: + case 88200: + mclk = 11289600; + break; + default: + return -EINVAL; + } + + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, + SND_SOC_CLOCK_OUT); + if (ret < 0) { + dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret); + return ret; + } + + return 0; +} + +static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int mclk; + int ret; + + mclk = params_rate(params) * SOUND_FS; + + ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); + if (ret) { + dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", + __func__, mclk, ret); + return ret; + } + + /* Wait for DMIC stable */ + msleep(dmic_wakeup_delay); + + return 0; +} + static const struct snd_soc_ops rockchip_sound_max98357a_ops = { .hw_params = rockchip_sound_max98357a_hw_params, }; @@ -240,16 +301,70 @@ static const struct snd_soc_ops rockchip_sound_da7219_ops = { .hw_params = rockchip_sound_da7219_hw_params, }; +static const struct snd_soc_ops rockchip_sound_cdndp_ops = { + .hw_params = rockchip_sound_cdndp_hw_params, +}; + +static const struct snd_soc_ops rockchip_sound_dmic_ops = { + .hw_params = rockchip_sound_dmic_hw_params, +}; + +static struct snd_soc_card rockchip_sound_card = { + .name = "rk3399-gru-sound", + .owner = THIS_MODULE, + .dapm_widgets = rockchip_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), + .dapm_routes = rockchip_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), + .controls = rockchip_controls, + .num_controls = ARRAY_SIZE(rockchip_controls), +}; + enum { + DAILINK_CDNDP, + DAILINK_DA7219, + DAILINK_DMIC, DAILINK_MAX98357A, DAILINK_RT5514, - DAILINK_DA7219, DAILINK_RT5514_DSP, }; -#define DAILINK_ENTITIES (DAILINK_DA7219 + 1) +static const char * const dailink_compat[] = { + [DAILINK_CDNDP] = "rockchip,rk3399-cdn-dp", + [DAILINK_DA7219] = "dlg,da7219", + [DAILINK_DMIC] = "dmic-codec", + [DAILINK_MAX98357A] = "maxim,max98357a", + [DAILINK_RT5514] = "realtek,rt5514-i2c", + [DAILINK_RT5514_DSP] = "realtek,rt5514-spi", +}; -static struct snd_soc_dai_link rockchip_dailinks[] = { +static const struct snd_soc_dai_link rockchip_dais[] = { + [DAILINK_CDNDP] = { + .name = "DP", + .stream_name = "DP PCM", + .codec_dai_name = "i2s-hifi", + .ops = &rockchip_sound_cdndp_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + }, + [DAILINK_DA7219] = { + .name = "DA7219", + .stream_name = "DA7219 PCM", + .codec_dai_name = "da7219-hifi", + .init = rockchip_sound_da7219_init, + .ops = &rockchip_sound_da7219_ops, + /* set da7219 as slave */ + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + }, + [DAILINK_DMIC] = { + .name = "DMIC", + .stream_name = "DMIC PCM", + .codec_dai_name = "dmic-hifi", + .ops = &rockchip_sound_dmic_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + }, [DAILINK_MAX98357A] = { .name = "MAX98357A", .stream_name = "MAX98357A PCM", @@ -268,108 +383,95 @@ static struct snd_soc_dai_link rockchip_dailinks[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, }, - [DAILINK_DA7219] = { - .name = "DA7219", - .stream_name = "DA7219 PCM", - .codec_dai_name = "da7219-hifi", - .init = rockchip_sound_da7219_init, - .ops = &rockchip_sound_da7219_ops, - /* set da7219 as slave */ - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - }, /* RT5514 DSP for voice wakeup via spi bus */ [DAILINK_RT5514_DSP] = { .name = "RT5514 DSP", .stream_name = "Wake on Voice", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", + .codec_dai_name = "rt5514-dsp-cpu-dai", }, }; -static struct snd_soc_card rockchip_sound_card = { - .name = "rk3399-gru-sound", - .owner = THIS_MODULE, - .dai_link = rockchip_dailinks, - .num_links = ARRAY_SIZE(rockchip_dailinks), - .dapm_widgets = rockchip_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), - .dapm_routes = rockchip_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), - .controls = rockchip_controls, - .num_controls = ARRAY_SIZE(rockchip_controls), -}; - -static int rockchip_sound_match_stub(struct device *dev, void *data) +static int rockchip_sound_codec_node_match(struct device_node *np_codec) { - return 1; -} + int i; -static int rockchip_sound_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &rockchip_sound_card; - struct device_node *cpu_node; - struct device *dev; - struct device_driver *drv; - int i, ret; - - cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0); - if (!cpu_node) { - dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n"); - return -EINVAL; + for (i = 0; i < ARRAY_SIZE(dailink_compat); i++) { + if (of_device_is_compatible(np_codec, dailink_compat[i])) + return i; } + return -1; +} - for (i = 0; i < DAILINK_ENTITIES; i++) { - rockchip_dailinks[i].platform_of_node = cpu_node; - rockchip_dailinks[i].cpu_of_node = cpu_node; - - rockchip_dailinks[i].codec_of_node = - of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i); - if (!rockchip_dailinks[i].codec_of_node) { - dev_err(&pdev->dev, - "Property[%d] 'rockchip,codec' missing or invalid\n", i); +static int rockchip_sound_of_parse_dais(struct device *dev, + struct snd_soc_card *card) +{ + struct device_node *np_cpu, *np_cpu0, *np_cpu1; + struct device_node *np_codec; + struct snd_soc_dai_link *dai; + int i, index; + + card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais), + GFP_KERNEL); + if (!card->dai_link) + return -ENOMEM; + + np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0); + np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1); + + card->num_links = 0; + for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) { + np_codec = of_parse_phandle(dev->of_node, + "rockchip,codec", i); + if (!np_codec) + break; + + if (!of_device_is_available(np_codec)) + continue; + + index = rockchip_sound_codec_node_match(np_codec); + if (index < 0) + continue; + + np_cpu = (index == DAILINK_CDNDP) ? np_cpu1 : np_cpu0; + if (!np_cpu) { + dev_err(dev, "Missing 'rockchip,cpu' for %s\n", + rockchip_dais[index].name); return -EINVAL; } - } - /** - * To acquire the spi driver of the rt5514 and set the dai-links names - * for soc_bind_dai_link - */ - drv = driver_find("rt5514", &spi_bus_type); - if (!drv) { - dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n"); - return -EINVAL; + dai = &card->dai_link[card->num_links++]; + *dai = rockchip_dais[index]; + + dai->codec_of_node = np_codec; + dai->platform_of_node = np_cpu; + dai->cpu_of_node = np_cpu; } - dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub); - if (!dev) { - dev_err(&pdev->dev, "Can not find the rt5514 device\n"); - return -ENODEV; + return 0; +} + +static int rockchip_sound_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &rockchip_sound_card; + int ret; + + ret = rockchip_sound_of_parse_dais(&pdev->dev, card); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret); + return ret; } - /* Set DMIC delay */ - ret = device_property_read_u32(&pdev->dev, "dmic-delay", - &rt5514_dmic_delay); + /* Set DMIC wakeup delay */ + ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms", + &dmic_wakeup_delay); if (ret) { - rt5514_dmic_delay = 0; + dmic_wakeup_delay = 0; dev_dbg(&pdev->dev, - "no optional property 'dmic-delay' found, default: no delay\n"); + "no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n"); } - rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL); - rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL); - rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL); - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", - __func__, ret); - - return ret; + return devm_snd_soc_register_card(&pdev->dev, card); } static const struct of_device_id rockchip_sound_of_match[] = { diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 199338fdeda0cea1fefedefd02d843fc00d465a7..b6590467fd140c9cbfa8e802af70a5fe390da9f4 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -579,10 +579,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev) int val; i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); - if (!i2s) { - dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n"); + if (!i2s) return -ENOMEM; - } i2s->dev = &pdev->dev; diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index c5ddeed97260f52e4aa2f994358d42a856696ed4..400e29edb1c9c4db4d3afbbad2b6a41952100a22 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -249,7 +249,7 @@ static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops rockchip_pdm_dai_ops = { +static const struct snd_soc_dai_ops rockchip_pdm_dai_ops = { .set_fmt = rockchip_pdm_set_fmt, .trigger = rockchip_pdm_trigger, .hw_params = rockchip_pdm_hw_params, diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 5f5825faeb2a4331177595eaabcd0600b9d2476e..051935162d7bf30ef7d26b293257d5d8a4fae7e8 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -170,14 +170,6 @@ static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int h1940_uda1380_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - /* s3c24xx digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link h1940_uda1380_dai[] = { { @@ -197,7 +189,6 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { static struct snd_soc_card h1940_asoc = { .name = "h1940", .owner = THIS_MODULE, - .remove = h1940_uda1380_card_remove, .dai_link = h1940_uda1380_dai, .num_links = ARRAY_SIZE(h1940_uda1380_dai), diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index af3ba4d4ccc58106e5c42d89d1a2ffe631959157..10a4da06c0a1477388758f30b2aaf61ae8a5ef12 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -50,6 +50,7 @@ struct samsung_i2s_variant_regs { struct samsung_i2s_dai_data { u32 quirks; + unsigned int pcm_rates; const struct samsung_i2s_variant_regs *i2s_variant_regs; }; @@ -550,7 +551,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, goto err; } - clk_prepare_enable(i2s->op_clk); + ret = clk_prepare_enable(i2s->op_clk); + if (ret) + goto err; i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); /* Over-ride the other's */ @@ -1076,13 +1079,13 @@ static const struct snd_soc_component_driver samsung_i2s_component = { .name = "samsung-i2s", }; -#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 - #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, + const struct samsung_i2s_dai_data *i2s_dai_data, + bool sec) { struct i2s_dai *i2s; @@ -1101,13 +1104,13 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) i2s->i2s_dai_drv.resume = i2s_resume; i2s->i2s_dai_drv.playback.channels_min = 1; i2s->i2s_dai_drv.playback.channels_max = 2; - i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.playback.rates = i2s_dai_data->pcm_rates; i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; if (!sec) { i2s->i2s_dai_drv.capture.channels_min = 1; i2s->i2s_dai_drv.capture.channels_max = 2; - i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.capture.rates = i2s_dai_data->pcm_rates; i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; } return i2s; @@ -1132,10 +1135,19 @@ static int i2s_runtime_suspend(struct device *dev) static int i2s_runtime_resume(struct device *dev) { struct i2s_dai *i2s = dev_get_drvdata(dev); + int ret; - clk_prepare_enable(i2s->clk); - if (i2s->op_clk) - clk_prepare_enable(i2s->op_clk); + ret = clk_prepare_enable(i2s->clk); + if (ret) + return ret; + + if (i2s->op_clk) { + ret = clk_prepare_enable(i2s->op_clk); + if (ret) { + clk_disable_unprepare(i2s->clk); + return ret; + } + } writel(i2s->suspend_i2scon, i2s->addr + I2SCON); writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); @@ -1242,7 +1254,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) i2s_dai_data = (struct samsung_i2s_dai_data *) platform_get_device_id(pdev)->driver_data; - pri_dai = i2s_alloc_dai(pdev, false); + pri_dai = i2s_alloc_dai(pdev, i2s_dai_data, false); if (!pri_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); return -ENOMEM; @@ -1316,7 +1328,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) goto err_disable_clk; if (quirks & QUIRK_SEC_DAI) { - sec_dai = i2s_alloc_dai(pdev, true); + sec_dai = i2s_alloc_dai(pdev, i2s_dai_data, true); if (!sec_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); ret = -ENOMEM; @@ -1376,13 +1388,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) static int samsung_i2s_remove(struct platform_device *pdev) { - struct i2s_dai *pri_dai, *sec_dai; + struct i2s_dai *pri_dai; pri_dai = dev_get_drvdata(&pdev->dev); - sec_dai = pri_dai->sec_dai; - - pri_dai->sec_dai = NULL; - sec_dai->pri_dai = NULL; pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1452,29 +1460,34 @@ static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = { static const struct samsung_i2s_dai_data i2sv3_dai_type = { .quirks = QUIRK_NO_MUXPSR, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_IDMA, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv6_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv6_regs, }; static const struct samsung_i2s_dai_data i2sv7_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM, + .pcm_rates = SNDRV_PCM_RATE_8000_192000, .i2s_variant_regs = &i2sv7_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv5_i2s1_regs, }; diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 3e408158625dbb3d1c22d20d54b6b735f36524df..a635df61f928c7f1164206754a937fa79010dc60 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -325,7 +325,7 @@ static int idma_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops idma_ops = { +static const struct snd_pcm_ops idma_ops = { .open = idma_open, .close = idma_close, .ioctl = snd_pcm_lib_ioctl, @@ -399,7 +399,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr) } EXPORT_SYMBOL_GPL(idma_reg_addr_init); -static struct snd_soc_platform_driver asoc_idma_platform = { +static const struct snd_soc_platform_driver asoc_idma_platform = { .ops = &idma_ops, .pcm_new = idma_new, .pcm_free = idma_free, diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 7fcb51faa2a0e98803cbc8ac67cd370b7f2fd02b..529b10dc532b7bbc125ca893e1cffd3108db0938 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -79,7 +79,7 @@ static int jive_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops jive_ops = { +static const struct snd_soc_ops jive_ops = { .hw_params = jive_hw_params, }; diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 0c0b00e40646657b4592d2b646f183d76d456442..44b6de5a331aeb0e9b21b4c67697baff3b0f31d7 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c @@ -19,8 +19,8 @@ struct odroid_priv { struct snd_soc_card card; struct snd_soc_dai_link dai_link; - struct clk *pll; - struct clk *rclk; + struct clk *clk_i2s_bus; + struct clk *sclk_i2s; }; static int odroid_card_startup(struct snd_pcm_substream *substream) @@ -42,29 +42,34 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream, switch (params_rate(params)) { case 32000: case 64000: - pll_freq = 131072000U; + pll_freq = 131072006U; break; case 44100: case 88200: case 176400: - pll_freq = 180633600U; + pll_freq = 180633609U; break; case 48000: case 96000: case 192000: - pll_freq = 196608000U; + pll_freq = 196608001U; break; default: return -EINVAL; } - ret = clk_set_rate(priv->pll, pll_freq + 1); + ret = clk_set_rate(priv->clk_i2s_bus, pll_freq / 2 + 1); if (ret < 0) return ret; - rclk_freq = params_rate(params) * 256 * 4; + /* + * We add 1 to the rclk_freq value in order to avoid too low clock + * frequency values due to the EPLL output frequency not being exact + * multiple of the audio sampling rate. + */ + rclk_freq = params_rate(params) * 256 + 1; - ret = clk_set_rate(priv->rclk, rclk_freq); + ret = clk_set_rate(priv->sclk_i2s, rclk_freq); if (ret < 0) return ret; @@ -118,14 +123,6 @@ static int odroid_audio_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(card, priv); - priv->pll = devm_clk_get(dev, "epll"); - if (IS_ERR(priv->pll)) - return PTR_ERR(priv->pll); - - priv->rclk = devm_clk_get(dev, "i2s_rclk"); - if (IS_ERR(priv->rclk)) - return PTR_ERR(priv->rclk); - ret = snd_soc_of_parse_card_name(card, "model"); if (ret < 0) return ret; @@ -171,14 +168,31 @@ static int odroid_audio_probe(struct platform_device *pdev) link->name = "Primary"; link->stream_name = link->name; + + priv->sclk_i2s = of_clk_get_by_name(link->cpu_of_node, "i2s_opclk1"); + if (IS_ERR(priv->sclk_i2s)) { + ret = PTR_ERR(priv->sclk_i2s); + goto err_put_i2s_n; + } + + priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node, "iis"); + if (IS_ERR(priv->clk_i2s_bus)) { + ret = PTR_ERR(priv->clk_i2s_bus); + goto err_put_sclk; + } + ret = devm_snd_soc_register_card(dev, card); if (ret < 0) { dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); - goto err_put_i2s_n; + goto err_put_clk_i2s; } return 0; +err_put_clk_i2s: + clk_put(priv->clk_i2s_bus); +err_put_sclk: + clk_put(priv->sclk_i2s); err_put_i2s_n: of_node_put(link->cpu_of_node); err_put_codec_n: @@ -192,6 +206,8 @@ static int odroid_audio_remove(struct platform_device *pdev) of_node_put(priv->dai_link.cpu_of_node); odroid_put_codec_of_nodes(&priv->dai_link); + clk_put(priv->sclk_i2s); + clk_put(priv->clk_i2s_bus); return 0; } diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index d50a6377c23d5a3c90a5917869236833fab309d8..37f95eee15587f9e06488f89f866c3a7e561937d 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -522,7 +522,9 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to get audio-bus clock\n"); return PTR_ERR(pcm->cclk); } - clk_prepare_enable(pcm->cclk); + ret = clk_prepare_enable(pcm->cclk); + if (ret) + return ret; /* record our pcm structure for later use in the callbacks */ dev_set_drvdata(&pdev->dev, pcm); @@ -533,7 +535,9 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) ret = PTR_ERR(pcm->pclk); goto err_dis_cclk; } - clk_prepare_enable(pcm->pclk); + ret = clk_prepare_enable(pcm->pclk); + if (ret) + goto err_dis_cclk; s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO; s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO; diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index fa096abe9e75689b58e46bb818810838a78c6080..a064ca7d78c352e267ec11bd2e7cfcef0200f8c5 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -31,7 +31,6 @@ #include "s3c24xx-i2s.h" static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); -static int rx1950_uda1380_card_remove(struct snd_soc_card *card); static int rx1950_startup(struct snd_pcm_substream *substream); static int rx1950_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); @@ -118,7 +117,6 @@ static const struct snd_soc_dapm_route audio_map[] = { static struct snd_soc_card rx1950_asoc = { .name = "rx1950", .owner = THIS_MODULE, - .remove = rx1950_uda1380_card_remove, .dai_link = rx1950_uda1380_dai, .num_links = ARRAY_SIZE(rx1950_uda1380_dai), @@ -219,14 +217,6 @@ static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int rx1950_uda1380_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - static int __init rx1950_init(void) { int ret; diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 8f42deaa184be0a759cf226958cc7904bd311270..58c3e9bfc6b7665f9c3bc108f291bba5f7c89479 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -27,7 +27,7 @@ #undef S3C_IIS_V2_SUPPORTED -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \ +#if defined(CONFIG_CPU_S3C2412) \ || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210) #define S3C_IIS_V2_SUPPORTED #endif @@ -634,11 +634,10 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, i2s->iis_pclk = clk_get(dev, "iis"); if (IS_ERR(i2s->iis_pclk)) { dev_err(dev, "failed to get iis_clock\n"); - iounmap(i2s->regs); return -ENOENT; } - clk_enable(i2s->iis_pclk); + clk_prepare_enable(i2s->iis_pclk); /* Mark ourselves as in TXRX mode so we can run through our cleanup * process without warnings. */ @@ -652,6 +651,15 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, } EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); +void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, + struct s3c_i2sv2_info *i2s) +{ + clk_disable_unprepare(i2s->iis_pclk); + clk_put(i2s->iis_pclk); + i2s->iis_pclk = NULL; +} +EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup); + #ifdef CONFIG_PM static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) { diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index 182d80564e374b81fd2bbd86a159ebe1bfd137e1..3fca20f7a853da8708be4f95f7c48e1ce500b9ad 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h @@ -91,6 +91,13 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, struct s3c_i2sv2_info *i2s, unsigned long base); +/** + * s3c_i2sv2_cleanup - cleanup resources allocated in s3c_i2sv2_probe + * @dai: The ASoC DAI structure supplied to the original probe. + * @i2s: Our local i2s structure to fill in. + */ +extern void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, + struct s3c_i2sv2_info *i2s); /** * s3c_i2sv2_register_component - register component and dai with soc core * @dev: DAI device diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 0a4718207e6ec41ae9f1535c5757066c73710f6a..cc0840fff5aae4a0f02d84e66b69d0b927f372c0 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -65,26 +65,33 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk"); if (IS_ERR(s3c2412_i2s.iis_cclk)) { pr_err("failed to get i2sclk clock\n"); - return PTR_ERR(s3c2412_i2s.iis_cclk); + ret = PTR_ERR(s3c2412_i2s.iis_cclk); + goto err; } /* Set MPLL as the source for IIS CLK */ clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); - clk_prepare_enable(s3c2412_i2s.iis_cclk); - - s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; + ret = clk_prepare_enable(s3c2412_i2s.iis_cclk); + if (ret) + goto err; /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); return 0; + +err: + s3c_i2sv2_cleanup(dai, &s3c2412_i2s); + + return ret; } static int s3c2412_i2s_remove(struct snd_soc_dai *dai) { clk_disable_unprepare(s3c2412_i2s.iis_cclk); + s3c_i2sv2_cleanup(dai, &s3c2412_i2s); return 0; } diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 91e6871e5413a64898e33339d41903d15cba7f41..8d58d02183bf5bd57c4143483cff54f08db6c97a 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -340,6 +340,7 @@ EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) { + int ret; snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, &s3c24xx_i2s_pcm_stereo_in); @@ -348,7 +349,9 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) pr_err("failed to get iis_clock\n"); return PTR_ERR(s3c24xx_i2s.iis_clk); } - clk_prepare_enable(s3c24xx_i2s.iis_clk); + ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); + if (ret) + return ret; /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), @@ -377,7 +380,11 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) { - clk_prepare_enable(s3c24xx_i2s.iis_clk); + int ret; + + ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); + if (ret) + return ret; writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index dcc008d1e1ab1bd896665b2c1cec40c73e497199..6de63f3e37d55b892040d5a85415faa1f2401c4d 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c @@ -211,7 +211,7 @@ static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) return 0; } -static struct snd_soc_ops simtec_snd_ops = { +static const struct snd_soc_ops simtec_snd_ops = { .hw_params = simtec_hw_params, }; diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 55538e333cc8958463b86500afc39fc11f546037..5fb3bab6bbfefea6860a1fe19c4cff55d31a2f7b 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -199,7 +199,7 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops s3c24xx_uda134x_ops = { +static const struct snd_soc_ops s3c24xx_uda134x_ops = { .startup = s3c24xx_uda134x_startup, .shutdown = s3c24xx_uda134x_shutdown, .hw_params = s3c24xx_uda134x_hw_params, @@ -237,7 +237,6 @@ static int s3c24xx_uda134x_probe(struct platform_device *pdev) mutex_init(&priv->clk_lock); card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, priv); ret = devm_snd_soc_register_card(&pdev->dev, card); diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 425ee2ba37f0725ce6873a5dcde3c2f1d52a46a8..cf0f54e652c16c6558d94d4dbf2505a6cb080d39 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -160,14 +160,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int smartq_wm8987_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios), - smartq_jack_gpios); - - return 0; -} - static struct snd_soc_dai_link smartq_dai[] = { { .name = "wm8987", @@ -186,7 +178,6 @@ static struct snd_soc_dai_link smartq_dai[] = { static struct snd_soc_card snd_soc_smartq = { .name = "SmartQ", .owner = THIS_MODULE, - .remove = smartq_wm8987_card_remove, .dai_link = smartq_dai, .num_links = ARRAY_SIZE(smartq_dai), diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index a2f2363fe1c29d136434121377ccb5d3f4363f71..7fc7cc6d1530ef2e8c703f0229da988ecee29dc8 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -144,7 +144,7 @@ static int smdk_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops smdk_spdif_ops = { +static const struct snd_soc_ops smdk_spdif_ops = { .hw_params = smdk_hw_params, }; diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 779504f54bc074fcaec0ce179483b3a4a1bc17ee..cb59911e65c043aca0cb9989b70ed8546bcf53aa 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -391,7 +391,9 @@ static int spdif_probe(struct platform_device *pdev) ret = -ENOENT; goto err0; } - clk_prepare_enable(spdif->pclk); + ret = clk_prepare_enable(spdif->pclk); + if (ret) + goto err0; spdif->sclk = devm_clk_get(&pdev->dev, "sclk_spdif"); if (IS_ERR(spdif->sclk)) { @@ -399,7 +401,9 @@ static int spdif_probe(struct platform_device *pdev) ret = -ENOENT; goto err1; } - clk_prepare_enable(spdif->sclk); + ret = clk_prepare_enable(spdif->sclk); + if (ret) + goto err1; /* Request S/PDIF Register's memory region */ if (!request_mem_region(mem_res->start, diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c index 24cc9d63ce87f0e09716d655ce567916e766ca1c..68698f3d72f96931ffc20b50510da436a2a87166 100644 --- a/sound/soc/samsung/tm2_wm5110.c +++ b/sound/soc/samsung/tm2_wm5110.c @@ -318,7 +318,7 @@ static const struct snd_kcontrol_new tm2_controls[] = { SOC_DAPM_PIN_SWITCH("Headset Mic"), }; -const struct snd_soc_dapm_widget tm2_dapm_widgets[] = { +static const struct snd_soc_dapm_widget tm2_dapm_widgets[] = { SND_SOC_DAPM_HP("HP", NULL), SND_SOC_DAPM_SPK("SPK", NULL), SND_SOC_DAPM_SPK("RCV", NULL), @@ -521,7 +521,7 @@ static void tm2_pm_complete(struct device *dev) tm2_start_sysclk(card); } -const struct dev_pm_ops tm2_pm_ops = { +static const struct dev_pm_ops tm2_pm_ops = { .prepare = tm2_pm_prepare, .suspend = snd_soc_suspend, .resume = snd_soc_resume, diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 8fad4441c87dc15248a0fe6eeb2d8f1ca1dc5e89..1e7d417b53ef22a199c6c0d78f9bcad281e8eb19 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -89,7 +89,7 @@ struct camelot_pcm { #define DMABRG_PREALLOC_BUFFER 32 * 1024 #define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 -static struct snd_pcm_hardware camelot_pcm_hardware = { +static const struct snd_pcm_hardware camelot_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -294,7 +294,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream) return bytes_to_frames(runtime, pos); } -static struct snd_pcm_ops camelot_pcm_ops = { +static const struct snd_pcm_ops camelot_pcm_ops = { .open = camelot_pcm_open, .close = camelot_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -320,7 +320,7 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_platform_driver sh7760_soc_platform = { +static const struct snd_soc_platform_driver sh7760_soc_platform = { .ops = &camelot_pcm_ops, .pcm_new = camelot_pcm_new, }; diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 7c4bdd82bb955bbbd35d5c78f5bd780da4ef7178..6d3c7706d93fbc1019377b48212c41e521a4b0e9 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1710,7 +1710,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = { * pcm ops */ -static struct snd_pcm_hardware fsi_pcm_hardware = { +static const struct snd_pcm_hardware fsi_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID, @@ -1755,7 +1755,7 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) return fsi_sample2frame(fsi, io->buff_sample_pos); } -static struct snd_pcm_ops fsi_pcm_ops = { +static const struct snd_pcm_ops fsi_pcm_ops = { .open = fsi_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = fsi_hw_params, @@ -1818,7 +1818,7 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { }, }; -static struct snd_soc_platform_driver fsi_soc_platform = { +static const struct snd_soc_platform_driver fsi_soc_platform = { .ops = &fsi_pcm_ops, .pcm_new = fsi_pcm_new, }; @@ -1962,10 +1962,8 @@ static int fsi_probe(struct platform_device *pdev) } master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL); - if (!master) { - dev_err(&pdev->dev, "Could not allocate master\n"); + if (!master) return -ENOMEM; - } master->base = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); @@ -2109,7 +2107,7 @@ static int fsi_resume(struct device *dev) return 0; } -static struct dev_pm_ops fsi_pm_ops = { +static const struct dev_pm_ops fsi_pm_ops = { .suspend = fsi_suspend, .resume = fsi_resume, }; diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 84c51037a7d07a5771c0510a412a4f7e5a3ae84b..624aaf569feff86a042056a15da5a7557636fae9 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -315,6 +315,8 @@ static const struct snd_soc_component_driver sh4_hac_component = { static int hac_soc_platform_probe(struct platform_device *pdev) { + int ret; + ret = snd_soc_set_ac97_ops(&hac_ac97_ops); if (ret != 0) return ret; diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 672bcd4c252bd3d17b3c1981be0e9b9ed5e53cc0..ecb057ff9fbb66d12c034ee44d2efba2d0577f0d 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -98,7 +98,7 @@ static int migor_hw_free(struct snd_pcm_substream *substream) return 0; } -static struct snd_soc_ops migor_dai_ops = { +static const struct snd_soc_ops migor_dai_ops = { .hw_params = migor_hw_params, .hw_free = migor_hw_free, }; diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 197cb3ec075f3de5905d4ccf002b0700311154e0..938baff86ef280a9b6f6d93a4e4e7283a3ea9eb8 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -586,10 +586,8 @@ int rsnd_adg_probe(struct rsnd_priv *priv) int ret; adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); - if (!adg) { - dev_err(dev, "ADG allocate failed\n"); + if (!adg) return -ENOMEM; - } ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, NULL, NULL, 0, 0); @@ -610,6 +608,13 @@ void rsnd_adg_remove(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct device_node *np = dev->of_node; + struct rsnd_adg *adg = priv->adg; + struct clk *clk; + int i; + + for_each_rsnd_clkout(clk, adg, i) + if (adg->clkout[i]) + clk_unregister_fixed_rate(adg->clkout[i]); of_clk_del_provider(np); diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3f2ced26ed3755b0eae995689fd13ae00fab9779..107133297e8dd169855e3953ebcf0ca630ef336a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -726,7 +726,6 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, case 2: case 6: case 8: - case 16: /* TDM Extend Mode */ rsnd_rdai_channels_set(rdai, slots); rsnd_rdai_ssi_lane_set(rdai, 1); @@ -740,7 +739,7 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, } static unsigned int rsnd_soc_hw_channels_list[] = { - 2, 6, 8, 16, + 2, 6, 8, }; static unsigned int rsnd_soc_hw_rate_list[] = { @@ -844,12 +843,28 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, ir, &ic); } -static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, - struct snd_soc_dai *dai) +static const struct snd_pcm_hardware rsnd_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID, + .buffer_bytes_max = 64 * 1024, + .period_bytes_min = 32, + .period_bytes_max = 8192, + .periods_min = 1, + .periods_max = 32, + .fifo_size = 256, +}; + +static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); + struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); struct snd_pcm_hw_constraint_list *constraint = &rdai->constraint; + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int max_channels = rsnd_rdai_channels_get(rdai); + int ret; int i; /* @@ -866,34 +881,26 @@ static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, constraint->count = i + 1; } + snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware); + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, constraint); + snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + /* * Sampling Rate / Channel Limitation * It depends on Clock Master Mode */ - if (!rsnd_rdai_is_clk_master(rdai)) - return; - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - rsnd_soc_hw_rule_rate, dai, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - rsnd_soc_hw_rule_channels, dai, - SNDRV_PCM_HW_PARAM_RATE, -1); -} - -static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); - struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); - struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); - int ret; - - /* rsnd_io_to_runtime() is not yet enabled here */ - rsnd_soc_hw_constraint(substream->runtime, dai); + if (rsnd_rdai_is_clk_master(rdai)) { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + rsnd_soc_hw_rule_rate, dai, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + rsnd_soc_hw_rule_channels, dai, + SNDRV_PCM_HW_PARAM_RATE, -1); + } /* * call rsnd_dai_call without spinlock @@ -1017,7 +1024,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, drv->playback.rates = RSND_RATES; drv->playback.formats = RSND_FMTS; drv->playback.channels_min = 2; - drv->playback.channels_max = 16; + drv->playback.channels_max = 8; drv->playback.stream_name = rdai->playback.name; snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE, @@ -1025,7 +1032,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, drv->capture.rates = RSND_RATES; drv->capture.formats = RSND_FMTS; drv->capture.channels_min = 2; - drv->capture.channels_max = 16; + drv->capture.channels_max = 8; drv->capture.stream_name = rdai->capture.name; rdai->playback.rdai = rdai; @@ -1105,31 +1112,6 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) /* * pcm ops */ -static struct snd_pcm_hardware rsnd_pcm_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, - .buffer_bytes_max = 64 * 1024, - .period_bytes_min = 32, - .period_bytes_max = 8192, - .periods_min = 1, - .periods_max = 32, - .fifo_size = 256, -}; - -static int rsnd_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int ret = 0; - - snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware); - - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - - return ret; -} - static int rsnd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { @@ -1158,8 +1140,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) return pointer; } -static struct snd_pcm_ops rsnd_pcm_ops = { - .open = rsnd_pcm_open, +static const struct snd_pcm_ops rsnd_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = rsnd_hw_params, .hw_free = snd_pcm_lib_free_pages, @@ -1169,11 +1150,10 @@ static struct snd_pcm_ops rsnd_pcm_ops = { /* * snd_kcontrol */ -#define kcontrol_to_cfg(kctrl) ((struct rsnd_kctrl_cfg *)kctrl->private_value) static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { - struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl); if (cfg->texts) { uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -1199,7 +1179,7 @@ static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc) { - struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl); int i; for (i = 0; i < cfg->size; i++) @@ -1214,8 +1194,7 @@ static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc) { - struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl); int i, change = 0; if (!cfg->accept(cfg->io)) @@ -1232,7 +1211,7 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, } if (change && cfg->update) - cfg->update(cfg->io, mod); + cfg->update(cfg->io, cfg->mod); return change; } @@ -1284,14 +1263,13 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, .index = rtd->num, .get = rsnd_kctrl_get, .put = rsnd_kctrl_put, - .private_value = (unsigned long)cfg, }; int ret; if (size > RSND_MAX_CHANNELS) return -EINVAL; - kctrl = snd_ctl_new1(&knew, mod); + kctrl = snd_ctl_new1(&knew, cfg); if (!kctrl) return -ENOMEM; @@ -1307,6 +1285,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, cfg->card = card; cfg->kctrl = kctrl; cfg->io = io; + cfg->mod = mod; return 0; } @@ -1339,7 +1318,7 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); } -static struct snd_soc_platform_driver rsnd_soc_platform = { +static const struct snd_soc_platform_driver rsnd_soc_platform = { .ops = &rsnd_pcm_ops, .pcm_new = rsnd_pcm_new, }; @@ -1422,10 +1401,8 @@ static int rsnd_probe(struct platform_device *pdev) * init priv data */ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "priv allocate failed\n"); + if (!priv) return -ENODEV; - } priv->pdev = pdev; priv->flags = (unsigned long)of_device_get_match_data(dev); diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 4ba8f2fe7a4c47f08f046de4062e8ff7e9279cc4..e7f53f44165d78b423c56a1623bbc2cfe965e0e6 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -394,13 +394,16 @@ int rsnd_ctu_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_ctu_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, clk, rsnd_mod_get_status, RSND_MOD_CTU, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_ctu_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 60aa5e96a49f97b3b3c3d384a7a36b4ad89a7041..041ec1080d52fa2429096c394459828552d47db2 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -604,8 +604,8 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, dma_addr_t in_addr; } dma_addrs[3][2][3] = { /* SRC */ + /* Capture */ {{{ 0, 0 }, - /* Capture */ { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, /* Playback */ diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 99d2d9459e755a46f630b36f93611e88c4feeae6..1743ade3cc55563c04204b37b70d57254f41cae8 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -380,13 +380,16 @@ int rsnd_dvc_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_dvc_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, clk, rsnd_mod_get_status, RSND_MOD_DVC, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_dvc_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index ee00e3516911ef32b6fbdd3113f49776231b96a1..f04c4100043a11f39c68d55bca3c99f8dca6ea04 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -406,10 +406,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv) int ret; gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); - if (!gen) { - dev_err(dev, "GEN allocate failed\n"); + if (!gen) return -ENOMEM; - } priv->gen = gen; diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 195fc7bb22afb6519fb574af7b28832d2defda6b..6c4826c189a42d06eec412cf0086b9721faa28be 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -168,13 +168,16 @@ int rsnd_mix_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_mix_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, clk, rsnd_mod_get_status, RSND_MOD_MIX, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_mix_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 99c57611df886a0700f7978cb93b5279b7c2498d..c5de71f2dc8c429b9ed3aabab509ded1651b92f9 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -614,6 +614,7 @@ struct rsnd_kctrl_cfg { struct rsnd_dai_stream *io; struct snd_card *card; struct snd_kcontrol *kctrl; + struct rsnd_mod *mod; }; #define RSND_MAX_CHANNELS 8 diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 7aa239e28491525053d4dd957bf2cc4d2f4b056c..510b68a483b4056ec9e211d651b3638e1dac9c84 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -27,7 +27,6 @@ struct rsnd_src { #define RSND_SRC_NAME_SIZE 16 #define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id) -#define rsnd_src_to_dma(src) ((src)->dma) #define rsnd_src_nr(priv) ((priv)->src_nr) #define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val) @@ -108,7 +107,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv, int is_play = rsnd_io_is_play(io); /* - * * Playback * runtime_rate -> [SRC] -> convert_rate * @@ -203,13 +201,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, use_src = (fin != fout) | rsnd_src_sync_is_enabled(mod); /* - * SRC_ADINR + * SRC_ADINR */ adinr = rsnd_get_adinr_bit(mod, io) | rsnd_runtime_channel_original(io); /* - * SRC_IFSCR / SRC_IFSVR + * SRC_IFSCR / SRC_IFSVR */ ifscr = 0; fsrate = 0; @@ -223,7 +221,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, } /* - * SRC_SRCCR / SRC_ROUTE_MODE0 + * SRC_SRCCR / SRC_ROUTE_MODE0 */ cr = 0x00011110; route = 0x0; @@ -581,20 +579,24 @@ int rsnd_src_probe(struct rsnd_priv *priv) src->irq = irq_of_parse_and_map(np, 0); if (!src->irq) { ret = -EINVAL; + of_node_put(np); goto rsnd_src_probe_done; } clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_src_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(src), &rsnd_src_ops, clk, rsnd_mod_get_status, RSND_MOD_SRC, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_src_probe_done; + } skip: i++; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 46feddd78ee26f0e7fa90e40500914ef5b4edfe3..fffc07e7262741781dbe1bf00e9acb05c3c5a766 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -72,6 +72,7 @@ struct rsnd_ssi { u32 cr_own; u32 cr_clk; u32 cr_mode; + u32 cr_en; u32 wsr; int chan; int rate; @@ -89,6 +90,7 @@ struct rsnd_ssi { #define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */ #define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */ #define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */ +#define RSND_SSI_PROBED (1 << 4) #define for_each_rsnd_ssi(pos, priv, i) \ for (i = 0; \ @@ -97,25 +99,27 @@ struct rsnd_ssi { i++) #define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id) -#define rsnd_ssi_to_dma(mod) ((ssi)->dma) #define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) -#define rsnd_ssi_mode_flags(p) ((p)->flags) +#define rsnd_ssi_flags_has(p, f) ((p)->flags & f) +#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f) +#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f)) #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) #define rsnd_ssi_is_multi_slave(mod, io) \ (rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod))) #define rsnd_ssi_is_run_mods(mod, io) \ (rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod))) +#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod)) int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io) { struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI0) + if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI0)) return RSND_SSI_HDMI_PORT0; - if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI1) + if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI1)) return RSND_SSI_HDMI_PORT1; return 0; @@ -130,7 +134,7 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) if (!rsnd_ssi_is_dma_mode(mod)) return 0; - if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF)) + if (!(rsnd_ssi_flags_has(ssi, RSND_SSI_NO_BUSIF))) use_busif = 1; if (rsnd_io_to_mod_src(io)) use_busif = 1; @@ -255,7 +259,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); int chan = rsnd_runtime_channel_for_ssi(io); int idx, ret; unsigned int main_rate; @@ -266,7 +269,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (!rsnd_rdai_is_clk_master(rdai)) return 0; - if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) + if (!rsnd_ssi_can_output_clk(mod)) return 0; if (rsnd_ssi_is_multi_slave(mod, io)) @@ -291,6 +294,16 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (ret < 0) return ret; + /* + * SSI clock will be output contiguously + * by below settings. + * This means, rsnd_ssi_master_clk_start() + * and rsnd_ssi_register_setup() are necessary + * for SSI parent + * + * SSICR : FORCE, SCKD, SWSD + * SSIWSR : CONT + */ ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(idx); ssi->wsr = CONT; ssi->rate = rate; @@ -307,12 +320,11 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod, { struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); if (!rsnd_rdai_is_clk_master(rdai)) return; - if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) + if (!rsnd_ssi_can_output_clk(mod)) return; if (ssi->usrcnt > 1) @@ -335,6 +347,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, u32 wsr; int is_tdm; + if (rsnd_ssi_is_parent(mod, io)) + return; + is_tdm = rsnd_runtime_is_ssi_tdm(io); /* @@ -393,7 +408,8 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod) rsnd_mod_write(mod, SSIWSR, ssi->wsr); rsnd_mod_write(mod, SSICR, ssi->cr_own | ssi->cr_clk | - ssi->cr_mode); /* without EN */ + ssi->cr_mode | + ssi->cr_en); } static void rsnd_ssi_pointer_init(struct rsnd_mod *mod, @@ -472,8 +488,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, if (ret < 0) return ret; - if (!rsnd_ssi_is_parent(mod, io)) - rsnd_ssi_config_init(mod, io); + rsnd_ssi_config_init(mod, io); rsnd_ssi_register_setup(mod); @@ -544,6 +559,8 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + if (!rsnd_ssi_is_run_mods(mod, io)) return 0; @@ -554,7 +571,19 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, if (rsnd_ssi_multi_slaves_runtime(io)) return 0; - rsnd_mod_bset(mod, SSICR, EN, EN); + /* + * EN is for data output. + * SSI parent EN is not needed. + */ + if (rsnd_ssi_is_parent(mod, io)) + return 0; + + ssi->cr_en = EN; + + rsnd_mod_write(mod, SSICR, ssi->cr_own | + ssi->cr_clk | + ssi->cr_mode | + ssi->cr_en); return 0; } @@ -569,13 +598,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, if (!rsnd_ssi_is_run_mods(mod, io)) return 0; - /* - * don't stop if not last user - * see also - * rsnd_ssi_start - * rsnd_ssi_interrupt - */ - if (ssi->usrcnt > 1) + if (rsnd_ssi_is_parent(mod, io)) return 0; /* @@ -595,6 +618,8 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, rsnd_mod_write(mod, SSICR, cr); /* disabled all */ rsnd_ssi_status_check(mod, IIRQ); + ssi->cr_en = 0; + return 0; } @@ -760,15 +785,47 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod, /* * SSI might be called again as PIO fallback * It is easy to manual handling for IRQ request/free + * + * OTOH, this function might be called many times if platform is + * using MIX. It needs xxx_attach() many times on xxx_probe(). + * Because of it, we can't control .probe/.remove calling count by + * mod->status. + * But it don't need to call request_irq() many times. + * Let's control it by RSND_SSI_PROBED flag. */ - ret = request_irq(ssi->irq, - rsnd_ssi_interrupt, - IRQF_SHARED, - dev_name(dev), mod); + if (!rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) { + ret = request_irq(ssi->irq, + rsnd_ssi_interrupt, + IRQF_SHARED, + dev_name(dev), mod); + + rsnd_ssi_flags_set(ssi, RSND_SSI_PROBED); + } return ret; } +static int rsnd_ssi_common_remove(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io); + + /* Do nothing if non SSI (= SSI parent, multi SSI) mod */ + if (pure_ssi_mod != mod) + return 0; + + /* PIO will request IRQ again */ + if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) { + free_irq(ssi->irq, mod); + + rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED); + } + + return 0; +} + static int rsnd_ssi_pointer(struct rsnd_mod *mod, struct rsnd_dai_stream *io, snd_pcm_uframes_t *pointer) @@ -784,6 +841,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .name = SSI_NAME, .probe = rsnd_ssi_common_probe, + .remove = rsnd_ssi_common_remove, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, .start = rsnd_ssi_start, @@ -818,23 +876,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, return ret; } -static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); - - /* Do nothing for SSI parent mod */ - if (ssi_parent_mod == mod) - return 0; - - /* PIO will request IRQ again */ - free_irq(ssi->irq, mod); - - return 0; -} - static int rsnd_ssi_fallback(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -876,7 +917,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .name = SSI_NAME, .dma_req = rsnd_ssi_dma_req, .probe = rsnd_ssi_dma_probe, - .remove = rsnd_ssi_dma_remove, + .remove = rsnd_ssi_common_remove, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, .start = rsnd_ssi_start, @@ -962,13 +1003,13 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv, ssi = rsnd_mod_to_ssi(mod); if (strstr(remote_ep->full_name, "hdmi0")) { - ssi->flags |= RSND_SSI_HDMI0; + rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI0); dev_dbg(dev, "%s[%d] connected to HDMI0\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); } if (strstr(remote_ep->full_name, "hdmi1")) { - ssi->flags |= RSND_SSI_HDMI1; + rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI1); dev_dbg(dev, "%s[%d] connected to HDMI1\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); } @@ -1001,7 +1042,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); + return !!(rsnd_ssi_flags_has(ssi, RSND_SSI_CLK_PIN_SHARE)); } static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io, @@ -1079,18 +1120,20 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_ssi_probe_done; } if (of_get_property(np, "shared-pin", NULL)) - ssi->flags |= RSND_SSI_CLK_PIN_SHARE; + rsnd_ssi_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE); if (of_get_property(np, "no-busif", NULL)) - ssi->flags |= RSND_SSI_NO_BUSIF; + rsnd_ssi_flags_set(ssi, RSND_SSI_NO_BUSIF); ssi->irq = irq_of_parse_and_map(np, 0); if (!ssi->irq) { ret = -EINVAL; + of_node_put(np); goto rsnd_ssi_probe_done; } @@ -1101,8 +1144,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, rsnd_ssi_get_status, RSND_MOD_SSI, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_ssi_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index bed2c9c0004b8fb0c6ccb1d9215443f4846e1eba..4d948757d300d04be3bfca3c63f78c68085a8506 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -250,7 +250,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ssiu *ssiu; - static struct rsnd_mod_ops *ops; + struct rsnd_mod_ops *ops; int i, nr, ret; /* same number to SSI */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 4a22aadac29484aae7b4621d7b6c523cd49bb3d7..160502947da20b238364745e620a6bd5e2baf1f4 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -333,7 +333,7 @@ static void siu_dai_spbstop(struct siu_port *port_info) /* API functions */ /* Playback and capture hardware properties are identical */ -static struct snd_pcm_hardware siu_dai_pcm_hw = { +static const struct snd_pcm_hardware siu_dai_pcm_hw = { .info = SNDRV_PCM_INFO_INTERLEAVED, .formats = SNDRV_PCM_FMTBIT_S16, .rates = SNDRV_PCM_RATE_8000_48000, diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 82902f56e82fec8f8d9758e4b133167dca6e54ee..3118cb0ee3f2ccfbeb3184546e9d16953ea04bf5 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -593,7 +593,7 @@ static void siu_pcm_free(struct snd_pcm *pcm) dev_dbg(pcm->card->dev, "%s\n", __func__); } -static struct snd_pcm_ops siu_pcm_ops = { +static const struct snd_pcm_ops siu_pcm_ops = { .open = siu_pcm_open, .close = siu_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 206f36bf43e8b8720db54a8b463305561979a20d..2cb8d3b55fbc210cd76d110df6d9fb11c976cb50 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -737,9 +737,6 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) } /* check client and interface hw capabilities */ - snprintf(new_name, sizeof(new_name), "%s %s-%d", - rtd->dai_link->stream_name, codec_dai->name, num); - if (codec_dai->driver->playback.channels_min) playback = 1; if (codec_dai->driver->capture.channels_min) @@ -758,21 +755,18 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) return -EINVAL; } - if(playback) + if (playback) direction = SND_COMPRESS_PLAYBACK; else direction = SND_COMPRESS_CAPTURE; compr = kzalloc(sizeof(*compr), GFP_KERNEL); - if (compr == NULL) { - snd_printk(KERN_ERR "Cannot allocate compr\n"); + if (!compr) return -ENOMEM; - } compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops), GFP_KERNEL); - if (compr->ops == NULL) { - dev_err(rtd->card->dev, "Cannot allocate compressed ops\n"); + if (!compr->ops) { ret = -ENOMEM; goto compr_err; } @@ -797,19 +791,18 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) else if (rtd->dai_link->dpcm_capture) be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); - } else + } else { + snprintf(new_name, sizeof(new_name), "%s %s-%d", + rtd->dai_link->stream_name, codec_dai->name, num); + memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); + } /* Add copy callback for not memory mapped DSPs */ if (platform->driver->compr_ops && platform->driver->compr_ops->copy) compr->ops->copy = soc_compr_copy; mutex_init(&compr->lock); - - snprintf(new_name, sizeof(new_name), "%s %s-%d", - rtd->dai_link->stream_name, - rtd->codec_dai->name, num); - ret = snd_compress_new(rtd->card->snd_card, num, direction, new_name, compr); if (ret < 0) { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 921622a019448394687655034f52befb4abfd6ec..fee4b0ef5566cf9e8de0bf5c568706da9cab2ea2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -339,11 +339,12 @@ static void soc_cleanup_component_debugfs(struct snd_soc_component *component) static void soc_init_codec_debugfs(struct snd_soc_component *component) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct dentry *debugfs_reg; - codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, - codec->component.debugfs_root, - codec, &codec_reg_fops); - if (!codec->debugfs_reg) + debugfs_reg = debugfs_create_file("codec_reg", 0644, + codec->component.debugfs_root, + codec, &codec_reg_fops); + if (!debugfs_reg) dev_warn(codec->dev, "ASoC: Failed to create codec register debugfs file\n"); } @@ -494,7 +495,7 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card) static void snd_soc_debugfs_init(void) { snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); - if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) { + if (IS_ERR_OR_NULL(snd_soc_debugfs_root)) { pr_warn("ASoC: Failed to create debugfs directory\n"); snd_soc_debugfs_root = NULL; return; @@ -550,6 +551,54 @@ static inline void snd_soc_debugfs_exit(void) #endif +static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_component *component) +{ + struct snd_soc_rtdcom_list *rtdcom; + struct snd_soc_rtdcom_list *new_rtdcom; + + for_each_rtdcom(rtd, rtdcom) { + /* already connected */ + if (rtdcom->component == component) + return 0; + } + + new_rtdcom = kmalloc(sizeof(*new_rtdcom), GFP_KERNEL); + if (!new_rtdcom) + return -ENOMEM; + + new_rtdcom->component = component; + INIT_LIST_HEAD(&new_rtdcom->list); + + list_add_tail(&new_rtdcom->list, &rtd->component_list); + + return 0; +} + +static void snd_soc_rtdcom_del_all(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2; + + for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) + kfree(rtdcom1); + + INIT_LIST_HEAD(&rtd->component_list); +} + +struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, + const char *driver_name) +{ + struct snd_soc_rtdcom_list *rtdcom; + + for_each_rtdcom(rtd, rtdcom) { + if ((rtdcom->component->driver->name == driver_name) || + strcmp(rtdcom->component->driver->name, driver_name) == 0) + return rtdcom->component; + } + + return NULL; +} + struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, const char *dai_link, int stream) { @@ -574,6 +623,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( if (!rtd) return NULL; + INIT_LIST_HEAD(&rtd->component_list); rtd->card = card; rtd->dai_link = dai_link; rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) * @@ -591,6 +641,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) { if (rtd && rtd->codec_dais) kfree(rtd->codec_dais); + snd_soc_rtdcom_del_all(rtd); kfree(rtd); } @@ -653,9 +704,7 @@ int snd_soc_suspend(struct device *dev) /* Due to the resume being scheduled into a workqueue we could * suspend before that's finished - wait for it to complete. */ - snd_power_lock(card->snd_card); snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0); - snd_power_unlock(card->snd_card); /* we're going to block userspace touching us until resume completes */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); @@ -949,7 +998,7 @@ static struct snd_soc_component *soc_find_component( /** * snd_soc_find_dai - Find a registered DAI * - * @dlc: name of the DAI and optional component info to match + * @dlc: name of the DAI or the DAI driver and optional component info to match * * This function will search all registered components and their DAIs to * find the DAI of the same name. The component's of_node and name @@ -977,7 +1026,9 @@ struct snd_soc_dai *snd_soc_find_dai( if (dlc->name && strcmp(component->name, dlc->name)) continue; list_for_each_entry(dai, &component->dai_list, list) { - if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)) + if (dlc->dai_name && strcmp(dai->name, dlc->dai_name) + && (!dai->driver->name + || strcmp(dai->driver->name, dlc->dai_name))) continue; return dai; @@ -1049,6 +1100,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd; struct snd_soc_dai_link_component *codecs = dai_link->codecs; struct snd_soc_dai_link_component cpu_dai_component; + struct snd_soc_component *component; struct snd_soc_dai **codec_dais; struct snd_soc_platform *platform; struct device_node *platform_of_node; @@ -1076,6 +1128,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, dai_link->cpu_dai_name); goto _err_defer; } + snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component); rtd->num_codecs = dai_link->num_codecs; @@ -1088,6 +1141,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, codecs[i].dai_name); goto _err_defer; } + snd_soc_rtdcom_add(rtd, codec_dais[i]->component); } /* Single codec links expect codec and codec_dai in runtime data */ @@ -1099,6 +1153,23 @@ static int soc_bind_dai_link(struct snd_soc_card *card, if (!platform_name && !dai_link->platform_of_node) platform_name = "snd-soc-dummy"; + /* find one from the set of registered platforms */ + list_for_each_entry(component, &component_list, list) { + platform_of_node = component->dev->of_node; + if (!platform_of_node && component->dev->parent->of_node) + platform_of_node = component->dev->parent->of_node; + + if (dai_link->platform_of_node) { + if (platform_of_node != dai_link->platform_of_node) + continue; + } else { + if (strcmp(component->name, platform_name)) + continue; + } + + snd_soc_rtdcom_add(rtd, component); + } + /* find one from the set of registered platforms */ list_for_each_entry(platform, &platform_list, list) { platform_of_node = platform->dev->of_node; @@ -1184,27 +1255,15 @@ static void soc_remove_link_dais(struct snd_soc_card *card, static void soc_remove_link_components(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd, int order) { - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_platform *platform = rtd->platform; struct snd_soc_component *component; - int i; + struct snd_soc_rtdcom_list *rtdcom; - /* remove the platform */ - if (platform && platform->component.driver->remove_order == order) - soc_remove_component(&platform->component); + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; - /* remove the CODEC-side CODEC */ - for (i = 0; i < rtd->num_codecs; i++) { - component = rtd->codec_dais[i]->component; if (component->driver->remove_order == order) soc_remove_component(component); } - - /* remove any CPU-side CODEC */ - if (cpu_dai) { - if (cpu_dai->component->driver->remove_order == order) - soc_remove_component(cpu_dai->component); - } } static void soc_remove_dai_links(struct snd_soc_card *card) @@ -1451,9 +1510,10 @@ static int soc_probe_component(struct snd_soc_card *card, soc_init_component_debugfs(component); - if (component->dapm_widgets) { - ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets, - component->num_dapm_widgets); + if (component->driver->dapm_widgets) { + ret = snd_soc_dapm_new_controls(dapm, + component->driver->dapm_widgets, + component->driver->num_dapm_widgets); if (ret != 0) { dev_err(component->dev, @@ -1495,12 +1555,14 @@ static int soc_probe_component(struct snd_soc_card *card, } } - if (component->controls) - snd_soc_add_component_controls(component, component->controls, - component->num_controls); - if (component->dapm_routes) - snd_soc_dapm_add_routes(dapm, component->dapm_routes, - component->num_dapm_routes); + if (component->driver->controls) + snd_soc_add_component_controls(component, + component->driver->controls, + component->driver->num_controls); + if (component->driver->dapm_routes) + snd_soc_dapm_add_routes(dapm, + component->driver->dapm_routes, + component->driver->num_dapm_routes); list_add(&dapm->list, &card->dapm_list); list_add(&component->card_list, &card->component_dev_list); @@ -1556,21 +1618,13 @@ static int soc_probe_link_components(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd, int order) { - struct snd_soc_platform *platform = rtd->platform; struct snd_soc_component *component; - int i, ret; + struct snd_soc_rtdcom_list *rtdcom; + int ret; - /* probe the CPU-side component, if it is a CODEC */ - component = rtd->cpu_dai->component; - if (component->driver->probe_order == order) { - ret = soc_probe_component(card, component); - if (ret < 0) - return ret; - } + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; - /* probe the CODEC-side components */ - for (i = 0; i < rtd->num_codecs; i++) { - component = rtd->codec_dais[i]->component; if (component->driver->probe_order == order) { ret = soc_probe_component(card, component); if (ret < 0) @@ -1578,13 +1632,6 @@ static int soc_probe_link_components(struct snd_soc_card *card, } } - /* probe the platform */ - if (platform->component.driver->probe_order == order) { - ret = soc_probe_component(card, &platform->component); - if (ret < 0) - return ret; - } - return 0; } @@ -2587,11 +2634,9 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, { if (dai->driver && dai->driver->ops->set_sysclk) return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); - else if (dai->codec && dai->codec->driver->set_sysclk) - return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0, - freq, dir); - else - return -ENOTSUPP; + + return snd_soc_component_set_sysclk(dai->component, clk_id, 0, + freq, dir); } EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); @@ -2616,6 +2661,32 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk); +/** + * snd_soc_component_set_sysclk - configure COMPONENT system or master clock. + * @component: COMPONENT + * @clk_id: DAI specific clock ID + * @source: Source for the clock + * @freq: new clock frequency in Hz + * @dir: new clock direction - input/output. + * + * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. + */ +int snd_soc_component_set_sysclk(struct snd_soc_component *component, int clk_id, + int source, unsigned int freq, int dir) +{ + /* will be removed */ + if (component->set_sysclk) + return component->set_sysclk(component, clk_id, source, + freq, dir); + + if (component->driver->set_sysclk) + return component->driver->set_sysclk(component, clk_id, source, + freq, dir); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk); + /** * snd_soc_dai_set_clkdiv - configure DAI clock dividers. * @dai: DAI @@ -2652,11 +2723,9 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source, if (dai->driver && dai->driver->ops->set_pll) return dai->driver->ops->set_pll(dai, pll_id, source, freq_in, freq_out); - else if (dai->codec && dai->codec->driver->set_pll) - return dai->codec->driver->set_pll(dai->codec, pll_id, source, - freq_in, freq_out); - else - return -EINVAL; + + return snd_soc_component_set_pll(dai->component, pll_id, source, + freq_in, freq_out); } EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); @@ -2681,6 +2750,33 @@ int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll); +/* + * snd_soc_component_set_pll - configure component PLL. + * @component: COMPONENT + * @pll_id: DAI specific PLL ID + * @source: DAI specific source for the PLL + * @freq_in: PLL input clock frequency in Hz + * @freq_out: requested PLL output clock frequency in Hz + * + * Configures and enables PLL to generate output clock based on input clock. + */ +int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, + int source, unsigned int freq_in, + unsigned int freq_out) +{ + /* will be removed */ + if (component->set_pll) + return component->set_pll(component, pll_id, source, + freq_in, freq_out); + + if (component->driver->set_pll) + return component->driver->set_pll(component, pll_id, source, + freq_in, freq_out); + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_pll); + /** * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio. * @dai: DAI @@ -3171,10 +3267,11 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->remove = component->driver->remove; component->suspend = component->driver->suspend; component->resume = component->driver->resume; - component->pcm_new = component->driver->pcm_new; - component->pcm_free = component->driver->pcm_free; + component->set_sysclk = component->driver->set_sysclk; + component->set_pll = component->driver->set_pll; + component->set_jack = component->driver->set_jack; - dapm = &component->dapm; + dapm = snd_soc_component_get_dapm(component); dapm->dev = dev; dapm->component = component; dapm->bias_level = SND_SOC_BIAS_OFF; @@ -3184,13 +3281,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, if (driver->stream_event) dapm->stream_event = snd_soc_component_stream_event; - component->controls = driver->controls; - component->num_controls = driver->num_controls; - component->dapm_widgets = driver->dapm_widgets; - component->num_dapm_widgets = driver->num_dapm_widgets; - component->dapm_routes = driver->dapm_routes; - component->num_dapm_routes = driver->num_dapm_routes; - INIT_LIST_HEAD(&component->dai_list); mutex_init(&component->io_mutex); @@ -3282,67 +3372,79 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) } int snd_soc_register_component(struct device *dev, - const struct snd_soc_component_driver *cmpnt_drv, + const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai) { - struct snd_soc_component *cmpnt; + struct snd_soc_component *component; int ret; - cmpnt = kzalloc(sizeof(*cmpnt), GFP_KERNEL); - if (!cmpnt) { + component = kzalloc(sizeof(*component), GFP_KERNEL); + if (!component) { dev_err(dev, "ASoC: Failed to allocate memory\n"); return -ENOMEM; } - ret = snd_soc_component_initialize(cmpnt, cmpnt_drv, dev); + ret = snd_soc_component_initialize(component, component_driver, dev); if (ret) goto err_free; - cmpnt->ignore_pmdown_time = true; - cmpnt->registered_as_component = true; + component->ignore_pmdown_time = true; + component->registered_as_component = true; - ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai, true); + ret = snd_soc_register_dais(component, dai_drv, num_dai, true); if (ret < 0) { dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); goto err_cleanup; } - snd_soc_component_add(cmpnt); + snd_soc_component_add(component); return 0; err_cleanup: - snd_soc_component_cleanup(cmpnt); + snd_soc_component_cleanup(component); err_free: - kfree(cmpnt); + kfree(component); return ret; } EXPORT_SYMBOL_GPL(snd_soc_register_component); /** - * snd_soc_unregister_component - Unregister a component from the ASoC core + * snd_soc_unregister_component - Unregister all related component + * from the ASoC core * * @dev: The device to unregister */ -void snd_soc_unregister_component(struct device *dev) +static int __snd_soc_unregister_component(struct device *dev) { - struct snd_soc_component *cmpnt; + struct snd_soc_component *component; + int found = 0; mutex_lock(&client_mutex); - list_for_each_entry(cmpnt, &component_list, list) { - if (dev == cmpnt->dev && cmpnt->registered_as_component) - goto found; + list_for_each_entry(component, &component_list, list) { + if (dev != component->dev || + !component->registered_as_component) + continue; + + snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); + snd_soc_component_del_unlocked(component); + found = 1; + break; } mutex_unlock(&client_mutex); - return; -found: - snd_soc_tplg_component_remove(cmpnt, SND_SOC_TPLG_INDEX_ALL); - snd_soc_component_del_unlocked(cmpnt); - mutex_unlock(&client_mutex); - snd_soc_component_cleanup(cmpnt); - kfree(cmpnt); + if (found) { + snd_soc_component_cleanup(component); + kfree(component); + } + + return found; +} + +void snd_soc_unregister_component(struct device *dev) +{ + while (__snd_soc_unregister_component(dev)); } EXPORT_SYMBOL_GPL(snd_soc_unregister_component); @@ -3360,25 +3462,6 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component) platform->driver->remove(platform); } -static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_platform *platform = rtd->platform; - - if (platform->driver->pcm_new) - return platform->driver->pcm_new(rtd); - else - return 0; -} - -static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_soc_platform *platform = rtd->platform; - - if (platform->driver->pcm_free) - platform->driver->pcm_free(pcm); -} - /** * snd_soc_add_platform - Add a platform to the ASoC core * @dev: The parent device for the platform @@ -3402,10 +3485,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->component.probe = snd_soc_platform_drv_probe; if (platform_drv->remove) platform->component.remove = snd_soc_platform_drv_remove; - if (platform_drv->pcm_new) - platform->component.pcm_new = snd_soc_platform_drv_pcm_new; - if (platform_drv->pcm_free) - platform->component.pcm_free = snd_soc_platform_drv_pcm_free; #ifdef CONFIG_DEBUG_FS platform->component.debugfs_prefix = "platform"; @@ -3582,6 +3661,31 @@ static int snd_soc_codec_drv_read(struct snd_soc_component *component, return 0; } +static int snd_soc_codec_set_sysclk_(struct snd_soc_component *component, + int clk_id, int source, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return snd_soc_codec_set_sysclk(codec, clk_id, source, freq, dir); +} + +static int snd_soc_codec_set_pll_(struct snd_soc_component *component, + int pll_id, int source, unsigned int freq_in, + unsigned int freq_out) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return snd_soc_codec_set_pll(codec, pll_id, source, freq_in, freq_out); +} + +static int snd_soc_codec_set_jack_(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return snd_soc_codec_set_jack(codec, jack, data); +} + static int snd_soc_codec_set_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { @@ -3633,6 +3737,12 @@ int snd_soc_register_codec(struct device *dev, codec->component.write = snd_soc_codec_drv_write; if (codec_drv->read) codec->component.read = snd_soc_codec_drv_read; + if (codec_drv->set_sysclk) + codec->component.set_sysclk = snd_soc_codec_set_sysclk_; + if (codec_drv->set_pll) + codec->component.set_pll = snd_soc_codec_set_pll_; + if (codec_drv->set_jack) + codec->component.set_jack = snd_soc_codec_set_jack_; codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; dapm = snd_soc_codec_get_dapm(codec); @@ -4113,6 +4223,8 @@ int snd_soc_get_dai_id(struct device_node *ep) } mutex_unlock(&client_mutex); + of_node_put(node); + return ret; } EXPORT_SYMBOL_GPL(snd_soc_get_dai_id); diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7daf21fee355b22c0a522d51c3de723fd6b7a1fd..99902ae1a2d95d9c6e295be964929a7b68c7acca 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -22,6 +22,12 @@ #include #include +struct jack_gpio_tbl { + int count; + struct snd_soc_jack *jack; + struct snd_soc_jack_gpio *gpios; +}; + /** * snd_soc_codec_set_jack - configure codec jack. * @codec: CODEC @@ -36,10 +42,32 @@ int snd_soc_codec_set_jack(struct snd_soc_codec *codec, if (codec->driver->set_jack) return codec->driver->set_jack(codec, jack, data); else - return -EINVAL; + return -ENOTSUPP; } EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack); +/** + * snd_soc_component_set_jack - configure component jack. + * @component: COMPONENTs + * @jack: structure to use for the jack + * @data: can be used if codec driver need extra data for configuring jack + * + * Configures and enables jack detection function. + */ +int snd_soc_component_set_jack(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + /* will be removed */ + if (component->set_jack) + return component->set_jack(component, jack, data); + + if (component->driver->set_jack) + return component->driver->set_jack(component, jack, data); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_jack); + /** * snd_soc_card_jack_new - Create a new jack * @card: ASoC card @@ -333,6 +361,28 @@ static int snd_soc_jack_pm_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static void jack_free_gpios(struct snd_soc_jack *jack, int count, + struct snd_soc_jack_gpio *gpios) +{ + int i; + + for (i = 0; i < count; i++) { + gpiod_unexport(gpios[i].desc); + unregister_pm_notifier(&gpios[i].pm_notifier); + free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); + cancel_delayed_work_sync(&gpios[i].work); + gpiod_put(gpios[i].desc); + gpios[i].jack = NULL; + } +} + +static void jack_devres_free_gpios(struct device *dev, void *res) +{ + struct jack_gpio_tbl *tbl = res; + + jack_free_gpios(tbl->jack, tbl->count, tbl->gpios); +} + /** * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack * @@ -347,6 +397,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { int i, ret; + struct jack_gpio_tbl *tbl; + + tbl = devres_alloc(jack_devres_free_gpios, sizeof(*tbl), GFP_KERNEL); + if (!tbl) + return -ENOMEM; + tbl->jack = jack; + tbl->count = count; + tbl->gpios = gpios; for (i = 0; i < count; i++) { if (!gpios[i].name) { @@ -424,12 +482,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, msecs_to_jiffies(gpios[i].debounce_time)); } + devres_add(jack->card->dev, tbl); return 0; err: gpio_free(gpios[i].gpio); undo: - snd_soc_jack_free_gpios(jack, i, gpios); + jack_free_gpios(jack, i, gpios); + devres_free(tbl); return ret; } @@ -471,16 +531,8 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods); void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { - int i; - - for (i = 0; i < count; i++) { - gpiod_unexport(gpios[i].desc); - unregister_pm_notifier(&gpios[i].pm_notifier); - free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); - cancel_delayed_work_sync(&gpios[i].work); - gpiod_put(gpios[i].desc); - gpios[i].jack = NULL; - } + jack_free_gpios(jack, count, gpios); + devres_destroy(jack->card->dev, jack_devres_free_gpios, NULL, NULL); } EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios); #endif /* CONFIG_GPIOLIB */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index dcc5ece0866832bbb11e353b1ac0b797e48b1065..94b88b897c3bb1acd0d8b18922a8286f5cadd081 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -181,6 +181,10 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", be->dai_link->name, event, dir); + if ((event == SND_SOC_DAPM_STREAM_STOP) && + (be->dpcm[dir].users >= 1)) + continue; + snd_soc_dapm_stream_event(be, dir, event); } @@ -450,6 +454,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai; const char *codec_dai_name = "multicodec"; @@ -458,10 +464,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) pinctrl_pm_select_default_state(cpu_dai->dev); for (i = 0; i < rtd->num_codecs; i++) pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev); - pm_runtime_get_sync(cpu_dai->dev); - for (i = 0; i < rtd->num_codecs; i++) - pm_runtime_get_sync(rtd->codec_dais[i]->dev); - pm_runtime_get_sync(platform->dev); + + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + pm_runtime_get_sync(component->dev); + } mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); @@ -599,15 +607,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) out: mutex_unlock(&rtd->pcm_mutex); - pm_runtime_mark_last_busy(platform->dev); - pm_runtime_put_autosuspend(platform->dev); - for (i = 0; i < rtd->num_codecs; i++) { - pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev); - pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev); + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); } - pm_runtime_mark_last_busy(cpu_dai->dev); - pm_runtime_put_autosuspend(cpu_dai->dev); for (i = 0; i < rtd->num_codecs; i++) { if (!rtd->codec_dais[i]->active) pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev); @@ -655,6 +661,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai; int i; @@ -711,17 +719,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) mutex_unlock(&rtd->pcm_mutex); - pm_runtime_mark_last_busy(platform->dev); - pm_runtime_put_autosuspend(platform->dev); + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; - for (i = 0; i < rtd->num_codecs; i++) { - pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev); - pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); } - pm_runtime_mark_last_busy(cpu_dai->dev); - pm_runtime_put_autosuspend(cpu_dai->dev); - for (i = 0; i < rtd->num_codecs; i++) { if (!rtd->codec_dais[i]->active) pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev); @@ -2628,25 +2632,12 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) return ret; } -static void soc_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_soc_component *component; - - list_for_each_entry(component, &rtd->card->component_dev_list, - card_list) { - if (component->pcm_free) - component->pcm_free(pcm); - } -} - /* create a new pcm */ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) { struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_component *component; struct snd_pcm *pcm; char new_name[64]; int ret = 0, playback = 0, capture = 0; @@ -2756,18 +2747,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) if (capture) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); - list_for_each_entry(component, &rtd->card->component_dev_list, card_list) { - if (component->pcm_new) { - ret = component->pcm_new(rtd); - if (ret < 0) { - dev_err(component->dev, - "ASoC: pcm constructor failed: %d\n", - ret); - return ret; - } + if (platform->driver->pcm_new) { + ret = platform->driver->pcm_new(rtd); + if (ret < 0) { + dev_err(platform->dev, + "ASoC: pcm constructor failed: %d\n", + ret); + return ret; } } - pcm->private_free = soc_pcm_free; + + pcm->private_free = platform->driver->pcm_free; out: dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name, @@ -3010,8 +3000,7 @@ void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) return; } - rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444, - rtd->debugfs_dpcm_root, - rtd, &dpcm_state_fops); + debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root, + rtd, &dpcm_state_fops); } #endif diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 644d9a9ebfbc592f7fabf677bd8d721cee8b3196..e30aacbcfc291931dfb9723bcf35f0f66a220a4b 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -284,7 +284,7 @@ static const struct snd_pcm_ops dummy_dma_ops = { .ioctl = snd_pcm_lib_ioctl, }; -static struct snd_soc_platform_driver dummy_platform = { +static const struct snd_soc_platform_driver dummy_platform = { .ops = &dummy_dma_ops, }; diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index 977a078eb92f236a005bbc232167ab862b339d07..78a6a360b4a65d83288b5abcc9c298ac954e301d 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -151,7 +151,7 @@ static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd, return ret; } -static struct snd_soc_dai_ops spdif_in_dai_ops = { +static const struct snd_soc_dai_ops spdif_in_dai_ops = { .shutdown = spdif_in_shutdown, .trigger = spdif_in_trigger, .hw_params = spdif_in_hw_params, @@ -216,15 +216,15 @@ static int spdif_in_probe(struct platform_device *pdev) return -EINVAL; host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); - if (!host) { - dev_warn(&pdev->dev, "kzalloc fail\n"); + if (!host) return -ENOMEM; - } host->io_base = io_base; host->irq = platform_get_irq(pdev, 0); - if (host->irq < 0) - return -EINVAL; + if (host->irq < 0) { + dev_warn(&pdev->dev, "failed to get IRQ: %d\n", host->irq); + return host->irq; + } host->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index 0a72d52d533ee6f8c657dde689231141cbe26505..58d5843811f9421a96fa66ec84b452678bf8ce59 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c @@ -282,10 +282,8 @@ static int spdif_out_probe(struct platform_device *pdev) int ret; host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); - if (!host) { - dev_warn(&pdev->dev, "kzalloc fail\n"); + if (!host) return -ENOMEM; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->io_base = devm_ioremap_resource(&pdev->dev, res); diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 8052629a89dfd2d4328b139b218f5e75ca9c33e3..6d0bf78d114d0da74f5b61f5c576c12483d562d9 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -840,7 +840,7 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, } /* Reset */ - rst = devm_reset_control_get(&pdev->dev, NULL); + rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index f7713314913b9844ebed680b5179af906101bc2a..1258bef4dcb37e8f8a9e0ea9d69466d64ccd02ed 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -85,7 +85,7 @@ static int stm32_sai_probe(struct platform_device *pdev) } /* reset */ - rst = reset_control_get(&pdev->dev, NULL); + rst = reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 4e4250bdb75a83a4d73e6a250fc4edef6f26df1d..84cc5678beba5e9367e981c765cad3045aabe32f 100644 --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -930,7 +930,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev) return ret; } - rst = devm_reset_control_get(&pdev->dev, NULL); + rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 150069987c0c3e5fd463636be8e46a832834cb1b..baa9007464ed7458d3c2ba4a777e6f83903989cf 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -762,7 +762,7 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = { { "Mic1", NULL, "VMIC" }, }; -static struct snd_soc_codec_driver sun4i_codec_codec = { +static const struct snd_soc_codec_driver sun4i_codec_codec = { .component_driver = { .controls = sun4i_codec_controls, .num_controls = ARRAY_SIZE(sun4i_codec_controls), @@ -1068,7 +1068,7 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = { { "Right ADC", NULL, "Right ADC Mixer" }, }; -static struct snd_soc_codec_driver sun6i_codec_codec = { +static const struct snd_soc_codec_driver sun6i_codec_codec = { .component_driver = { .controls = sun6i_codec_codec_widgets, .num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets), @@ -1096,7 +1096,7 @@ static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = { }; -static struct snd_soc_codec_driver sun8i_a23_codec_codec = { +static const struct snd_soc_codec_driver sun8i_a23_codec_codec = { .component_driver = { .controls = sun8i_a23_codec_codec_controls, .num_controls = ARRAY_SIZE(sun8i_a23_codec_codec_controls), @@ -1171,9 +1171,8 @@ static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w, { struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card); - if (scodec->gpio_pa) - gpiod_set_value_cansleep(scodec->gpio_pa, - !!SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(scodec->gpio_pa, + !!SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -1574,7 +1573,8 @@ static int sun4i_codec_probe(struct platform_device *pdev) } if (quirks->has_reset) { - scodec->rst = devm_reset_control_get(&pdev->dev, NULL); + scodec->rst = devm_reset_control_get_exclusive(&pdev->dev, + NULL); if (IS_ERR(scodec->rst)) { dev_err(&pdev->dev, "Failed to get reset control\n"); return PTR_ERR(scodec->rst); @@ -1655,7 +1655,6 @@ static int sun4i_codec_probe(struct platform_device *pdev) goto err_unregister_codec; } - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, scodec); ret = snd_soc_register_card(card); diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 3635bbc72cbcd3f4053569195007f57762758e7f..04f92583a9696569aeac2a92084643a94cbe57d6 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -50,6 +50,8 @@ #define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0) #define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0) #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0) +#define SUN4I_I2S_FMT0_POLARITY_INVERTED (1) +#define SUN4I_I2S_FMT0_POLARITY_NORMAL (0) #define SUN4I_I2S_FMT1_REG 0x08 #define SUN4I_I2S_FIFO_TX_REG 0x0c @@ -82,7 +84,7 @@ #define SUN4I_I2S_TX_CNT_REG 0x2c #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 -#define SUN4I_I2S_TX_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) +#define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2)) @@ -90,6 +92,83 @@ #define SUN4I_I2S_RX_CHAN_SEL_REG 0x38 #define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c +/* Defines required for sun8i-h3 support */ +#define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) +#define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) + +#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) +#define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) + +#define SUN8I_I2S_INT_STA_REG 0x0c +#define SUN8I_I2S_FIFO_TX_REG 0x20 + +#define SUN8I_I2S_CHAN_CFG_REG 0x30 +#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(6, 4) +#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) (chan - 1) +#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(2, 0) +#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1) + +#define SUN8I_I2S_TX_CHAN_MAP_REG 0x44 +#define SUN8I_I2S_TX_CHAN_SEL_REG 0x34 +#define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(13, 11) +#define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 12) +#define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4) +#define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4) + +#define SUN8I_I2S_RX_CHAN_SEL_REG 0x54 +#define SUN8I_I2S_RX_CHAN_MAP_REG 0x58 + +/** + * struct sun4i_i2s_quirks - Differences between SoC variants. + * + * @has_reset: SoC needs reset deasserted. + * @has_slave_select_bit: SoC has a bit to enable slave mode. + * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. + * @has_chcfg: tx and rx slot number need to be set. + * @has_chsel_tx_chen: SoC requires that the tx channels are enabled. + * @has_chsel_offset: SoC uses offset for selecting dai operational mode. + * @reg_offset_txdata: offset of the tx fifo. + * @sun4i_i2s_regmap: regmap config to use. + * @mclk_offset: Value by which mclkdiv needs to be adjusted. + * @bclk_offset: Value by which bclkdiv needs to be adjusted. + * @fmt_offset: Value by which wss and sr needs to be adjusted. + * @field_clkdiv_mclk_en: regmap field to enable mclk output. + * @field_fmt_wss: regmap field to set word select size. + * @field_fmt_sr: regmap field to set sample resolution. + * @field_fmt_bclk: regmap field to set clk polarity. + * @field_fmt_lrclk: regmap field to set frame polarity. + * @field_fmt_mode: regmap field to set the operational mode. + * @field_txchanmap: location of the tx channel mapping register. + * @field_rxchanmap: location of the rx channel mapping register. + * @field_txchansel: location of the tx channel select bit fields. + * @field_rxchansel: location of the rx channel select bit fields. + */ +struct sun4i_i2s_quirks { + bool has_reset; + bool has_slave_select_bit; + bool has_fmt_set_lrck_period; + bool has_chcfg; + bool has_chsel_tx_chen; + bool has_chsel_offset; + unsigned int reg_offset_txdata; /* TX FIFO */ + const struct regmap_config *sun4i_i2s_regmap; + unsigned int mclk_offset; + unsigned int bclk_offset; + unsigned int fmt_offset; + + /* Register fields for i2s */ + struct reg_field field_clkdiv_mclk_en; + struct reg_field field_fmt_wss; + struct reg_field field_fmt_sr; + struct reg_field field_fmt_bclk; + struct reg_field field_fmt_lrclk; + struct reg_field field_fmt_mode; + struct reg_field field_txchanmap; + struct reg_field field_rxchanmap; + struct reg_field field_txchansel; + struct reg_field field_rxchansel; +}; + struct sun4i_i2s { struct clk *bus_clk; struct clk *mod_clk; @@ -100,6 +179,20 @@ struct sun4i_i2s { struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data; + + /* Register fields for i2s */ + struct regmap_field *field_clkdiv_mclk_en; + struct regmap_field *field_fmt_wss; + struct regmap_field *field_fmt_sr; + struct regmap_field *field_fmt_bclk; + struct regmap_field *field_fmt_lrclk; + struct regmap_field *field_fmt_mode; + struct regmap_field *field_txchanmap; + struct regmap_field *field_rxchanmap; + struct regmap_field *field_txchansel; + struct regmap_field *field_rxchansel; + + const struct sun4i_i2s_quirks *variant; }; struct sun4i_i2s_clk_div { @@ -114,6 +207,7 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = { { .div = 8, .val = 3 }, { .div = 12, .val = 4 }, { .div = 16, .val = 5 }, + /* TODO - extend divide ratio supported by newer SoCs */ }; static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { @@ -125,6 +219,7 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { { .div = 12, .val = 5 }, { .div = 16, .val = 6 }, { .div = 24, .val = 7 }, + /* TODO - extend divide ratio supported by newer SoCs */ }; static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, @@ -226,10 +321,21 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, if (mclk_div < 0) return -EINVAL; + /* Adjust the clock division values if needed */ + bclk_div += i2s->variant->bclk_offset; + mclk_div += i2s->variant->mclk_offset; + regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | - SUN4I_I2S_CLK_DIV_MCLK(mclk_div) | - SUN4I_I2S_CLK_DIV_MCLK_EN); + SUN4I_I2S_CLK_DIV_MCLK(mclk_div)); + + regmap_field_write(i2s->field_clkdiv_mclk_en, 1); + + /* Set sync period */ + if (i2s->variant->has_fmt_set_lrck_period) + regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, + SUN8I_I2S_FMT0_LRCK_PERIOD_MASK, + SUN8I_I2S_FMT0_LRCK_PERIOD(32)); return 0; } @@ -239,12 +345,38 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); - int sr, wss; + int sr, wss, channels; u32 width; - if (params_channels(params) != 2) + channels = params_channels(params); + if (channels != 2) return -EINVAL; + if (i2s->variant->has_chcfg) { + regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, + SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, + SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); + regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, + SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, + SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); + } + + /* Map the channels for playback and capture */ + regmap_field_write(i2s->field_txchanmap, 0x76543210); + regmap_field_write(i2s->field_rxchanmap, 0x00003210); + + /* Configure the channels */ + regmap_field_write(i2s->field_txchansel, + SUN4I_I2S_CHAN_SEL(params_channels(params))); + + regmap_field_write(i2s->field_rxchansel, + SUN4I_I2S_CHAN_SEL(params_channels(params))); + + if (i2s->variant->has_chsel_tx_chen) + regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, + SUN8I_I2S_TX_CHAN_EN_MASK, + SUN8I_I2S_TX_CHAN_EN(channels)); + switch (params_physical_width(params)) { case 16: width = DMA_SLAVE_BUSWIDTH_2_BYTES; @@ -264,9 +396,10 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, - SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK, - SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr)); + regmap_field_write(i2s->field_fmt_wss, + wss + i2s->variant->fmt_offset); + regmap_field_write(i2s->field_fmt_sr, + sr + i2s->variant->fmt_offset); return sun4i_i2s_set_clk_rate(i2s, params_rate(params), params_width(params)); @@ -276,11 +409,15 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); u32 val; + u32 offset = 0; + u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; + u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; /* DAI Mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: val = SUN4I_I2S_FMT0_FMT_I2S; + offset = 1; break; case SND_SOC_DAIFMT_LEFT_J: val = SUN4I_I2S_FMT0_FMT_LEFT_J; @@ -292,59 +429,89 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, - SUN4I_I2S_FMT0_FMT_MASK, - val); + if (i2s->variant->has_chsel_offset) { + /* + * offset being set indicates that we're connected to an i2s + * device, however offset is only used on the sun8i block and + * i2s shares the same setting with the LJ format. Increment + * val so that the bit to value to write is correct. + */ + if (offset > 0) + val++; + /* blck offset determines whether i2s or LJ */ + regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, + SUN8I_I2S_TX_CHAN_OFFSET_MASK, + SUN8I_I2S_TX_CHAN_OFFSET(offset)); + } + + regmap_field_write(i2s->field_fmt_mode, val); /* DAI clock polarity */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_IF: /* Invert both clocks */ - val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | - SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED; + bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; + lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; break; case SND_SOC_DAIFMT_IB_NF: /* Invert bit clock */ - val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | - SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL; + bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; break; case SND_SOC_DAIFMT_NB_IF: /* Invert frame clock */ - val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED | - SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL; + lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; break; case SND_SOC_DAIFMT_NB_NF: - /* Nothing to do for both normal cases */ - val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL | - SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL; break; default: return -EINVAL; } - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, - SUN4I_I2S_FMT0_BCLK_POLARITY_MASK | - SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK, - val); - - /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* BCLK and LRCLK master */ - val = SUN4I_I2S_CTRL_MODE_MASTER; - break; - case SND_SOC_DAIFMT_CBM_CFM: - /* BCLK and LRCLK slave */ - val = SUN4I_I2S_CTRL_MODE_SLAVE; - break; - default: - return -EINVAL; + regmap_field_write(i2s->field_fmt_bclk, bclk_polarity); + regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity); + + if (i2s->variant->has_slave_select_bit) { + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* BCLK and LRCLK master */ + val = SUN4I_I2S_CTRL_MODE_MASTER; + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* BCLK and LRCLK slave */ + val = SUN4I_I2S_CTRL_MODE_SLAVE; + break; + default: + return -EINVAL; + } + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_MODE_MASK, + val); + } else { + /* + * The newer i2s block does not have a slave select bit, + * instead the clk pins are configured as inputs. + */ + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* BCLK and LRCLK master */ + val = SUN8I_I2S_CTRL_BCLK_OUT | + SUN8I_I2S_CTRL_LRCK_OUT; + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* BCLK and LRCLK slave */ + val = 0; + break; + default: + return -EINVAL; + } + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN8I_I2S_CTRL_BCLK_OUT | + SUN8I_I2S_CTRL_LRCK_OUT, + val); } - regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, - SUN4I_I2S_CTRL_MODE_MASK, - val); - /* Set significant bits in our FIFOs */ regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK | @@ -459,21 +626,14 @@ static int sun4i_i2s_startup(struct snd_pcm_substream *substream, struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); /* Enable the whole hardware block */ - regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, - SUN4I_I2S_CTRL_GL_EN); + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN); /* Enable the first output line */ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, SUN4I_I2S_CTRL_SDO_EN_MASK, SUN4I_I2S_CTRL_SDO_EN(0)); - /* Enable the first two channels */ - regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG, - SUN4I_I2S_TX_CHAN_SEL(2)); - - /* Map them to the two first samples coming in */ - regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, - SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1)); return clk_prepare_enable(i2s->mod_clk); } @@ -490,7 +650,8 @@ static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream, SUN4I_I2S_CTRL_SDO_EN_MASK, 0); /* Disable the whole hardware block */ - regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0); + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_GL_EN, 0); } static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, @@ -589,6 +750,27 @@ static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg) } } +static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SUN8I_I2S_FIFO_TX_REG: + return false; + + default: + return true; + } +} + +static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg) +{ + if (reg == SUN8I_I2S_INT_STA_REG) + return true; + if (reg == SUN8I_I2S_FIFO_TX_REG) + return false; + + return sun4i_i2s_volatile_reg(dev, reg); +} + static const struct reg_default sun4i_i2s_reg_defaults[] = { { SUN4I_I2S_CTRL_REG, 0x00000000 }, { SUN4I_I2S_FMT0_REG, 0x0000000c }, @@ -602,6 +784,20 @@ static const struct reg_default sun4i_i2s_reg_defaults[] = { { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 }, }; +static const struct reg_default sun8i_i2s_reg_defaults[] = { + { SUN4I_I2S_CTRL_REG, 0x00060000 }, + { SUN4I_I2S_FMT0_REG, 0x00000033 }, + { SUN4I_I2S_FMT1_REG, 0x00000030 }, + { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 }, + { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 }, + { SUN4I_I2S_CLK_DIV_REG, 0x00000000 }, + { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 }, + { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 }, + { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 }, + { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 }, + { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 }, +}; + static const struct regmap_config sun4i_i2s_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -616,6 +812,19 @@ static const struct regmap_config sun4i_i2s_regmap_config = { .volatile_reg = sun4i_i2s_volatile_reg, }; +static const struct regmap_config sun8i_i2s_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = SUN8I_I2S_RX_CHAN_MAP_REG, + .cache_type = REGCACHE_FLAT, + .reg_defaults = sun8i_i2s_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(sun8i_i2s_reg_defaults), + .writeable_reg = sun4i_i2s_wr_reg, + .readable_reg = sun8i_i2s_rd_reg, + .volatile_reg = sun8i_i2s_volatile_reg, +}; + static int sun4i_i2s_runtime_resume(struct device *dev) { struct sun4i_i2s *i2s = dev_get_drvdata(dev); @@ -654,22 +863,129 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) return 0; } -struct sun4i_i2s_quirks { - bool has_reset; -}; - static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { - .has_reset = false, + .has_reset = false, + .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, + .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .has_slave_select_bit = true, + .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), + .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), }; static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { - .has_reset = true, + .has_reset = true, + .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, + .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .has_slave_select_bit = true, + .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), + .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), +}; + +static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { + .has_reset = true, + .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, + .sun4i_i2s_regmap = &sun8i_i2s_regmap_config, + .mclk_offset = 1, + .bclk_offset = 2, + .fmt_offset = 3, + .has_fmt_set_lrck_period = true, + .has_chcfg = true, + .has_chsel_tx_chen = true, + .has_chsel_offset = true, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), + .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), + .field_txchanmap = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2), }; +static int sun4i_i2s_init_regmap_fields(struct device *dev, + struct sun4i_i2s *i2s) +{ + i2s->field_clkdiv_mclk_en = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_clkdiv_mclk_en); + if (IS_ERR(i2s->field_clkdiv_mclk_en)) + return PTR_ERR(i2s->field_clkdiv_mclk_en); + + i2s->field_fmt_wss = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_wss); + if (IS_ERR(i2s->field_fmt_wss)) + return PTR_ERR(i2s->field_fmt_wss); + + i2s->field_fmt_sr = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_sr); + if (IS_ERR(i2s->field_fmt_sr)) + return PTR_ERR(i2s->field_fmt_sr); + + i2s->field_fmt_bclk = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_bclk); + if (IS_ERR(i2s->field_fmt_bclk)) + return PTR_ERR(i2s->field_fmt_bclk); + + i2s->field_fmt_lrclk = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_lrclk); + if (IS_ERR(i2s->field_fmt_lrclk)) + return PTR_ERR(i2s->field_fmt_lrclk); + + i2s->field_fmt_mode = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_mode); + if (IS_ERR(i2s->field_fmt_mode)) + return PTR_ERR(i2s->field_fmt_mode); + + i2s->field_txchanmap = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_txchanmap); + if (IS_ERR(i2s->field_txchanmap)) + return PTR_ERR(i2s->field_txchanmap); + + i2s->field_rxchanmap = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_rxchanmap); + if (IS_ERR(i2s->field_rxchanmap)) + return PTR_ERR(i2s->field_rxchanmap); + + i2s->field_txchansel = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_txchansel); + if (IS_ERR(i2s->field_txchansel)) + return PTR_ERR(i2s->field_txchansel); + + i2s->field_rxchansel = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_rxchansel); + return PTR_ERR_OR_ZERO(i2s->field_rxchansel); +} + static int sun4i_i2s_probe(struct platform_device *pdev) { struct sun4i_i2s *i2s; - const struct sun4i_i2s_quirks *quirks; struct resource *res; void __iomem *regs; int irq, ret; @@ -690,8 +1006,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) return irq; } - quirks = of_device_get_match_data(&pdev->dev); - if (!quirks) { + i2s->variant = of_device_get_match_data(&pdev->dev); + if (!i2s->variant) { dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); return -ENODEV; } @@ -703,7 +1019,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev) } i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, - &sun4i_i2s_regmap_config); + i2s->variant->sun4i_i2s_regmap); if (IS_ERR(i2s->regmap)) { dev_err(&pdev->dev, "Regmap initialisation failed\n"); return PTR_ERR(i2s->regmap); @@ -715,8 +1031,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) return PTR_ERR(i2s->mod_clk); } - if (quirks->has_reset) { - i2s->rst = devm_reset_control_get(&pdev->dev, NULL); + if (i2s->variant->has_reset) { + i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(i2s->rst)) { dev_err(&pdev->dev, "Failed to get reset control\n"); return PTR_ERR(i2s->rst); @@ -732,7 +1048,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) } } - i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG; + i2s->playback_dma_data.addr = res->start + + i2s->variant->reg_offset_txdata; i2s->playback_dma_data.maxburst = 8; i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG; @@ -759,6 +1076,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev) goto err_suspend; } + ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s); + if (ret) { + dev_err(&pdev->dev, "Could not initialise regmap fields\n"); + goto err_suspend; + } + return 0; err_suspend: @@ -797,6 +1120,10 @@ static const struct of_device_id sun4i_i2s_match[] = { .compatible = "allwinner,sun6i-a31-i2s", .data = &sun6i_a31_i2s_quirks, }, + { + .compatible = "allwinner,sun8i-h3-i2s", + .data = &sun8i_h3_i2s_quirks, + }, {} }; MODULE_DEVICE_TABLE(of, sun4i_i2s_match); diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index eaefd07a5ed080ecbe9373378a767cfffd6faf68..b4af4aabead1339887e69d2acdd20ee342c58171 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c @@ -458,11 +458,16 @@ static int sun4i_spdif_runtime_suspend(struct device *dev) static int sun4i_spdif_runtime_resume(struct device *dev) { struct sun4i_spdif_dev *host = dev_get_drvdata(dev); + int ret; - clk_prepare_enable(host->spdif_clk); - clk_prepare_enable(host->apb_clk); + ret = clk_prepare_enable(host->spdif_clk); + if (ret) + return ret; + ret = clk_prepare_enable(host->apb_clk); + if (ret) + clk_disable_unprepare(host->spdif_clk); - return 0; + return ret; } static int sun4i_spdif_probe(struct platform_device *pdev) @@ -520,7 +525,8 @@ static int sun4i_spdif_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); if (quirks->has_reset) { - host->rst = devm_reset_control_get_optional(&pdev->dev, NULL); + host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, + NULL); if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; dev_err(&pdev->dev, "Failed to get reset: %d\n", ret); diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 5723c3404f6bd6a896aed90b8b37d143de26c075..abfb710df7cbceb54c9fc60ab7502f088d630874 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -341,7 +341,7 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { "AIF1 Slot 0 Right"}, }; -static struct snd_soc_dai_ops sun8i_codec_dai_ops = { +static const struct snd_soc_dai_ops sun8i_codec_dai_ops = { .hw_params = sun8i_codec_hw_params, .set_fmt = sun8i_set_fmt, }; @@ -360,7 +360,7 @@ static struct snd_soc_dai_driver sun8i_codec_dai = { .ops = &sun8i_codec_dai_ops, }; -static struct snd_soc_codec_driver sun8i_soc_codec = { +static const struct snd_soc_codec_driver sun8i_soc_codec = { .component_driver = { .dapm_widgets = sun8i_codec_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets), diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index efbe8d4c019eefa5c77b3e500c2eec248ff0410f..6875fc39a575194152bd6006ddb9c9e481539c3d 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -9,8 +9,8 @@ config SND_SOC_TEGRA Say Y or M here if you want support for SoC audio on Tegra. config SND_SOC_TEGRA20_AC97 - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 AC97 interface" + depends on SND_SOC_TEGRA select SND_SOC_AC97_BUS select SND_SOC_TEGRA20_DAS help @@ -19,16 +19,16 @@ config SND_SOC_TEGRA20_AC97 machine drivers to support below. config SND_SOC_TEGRA20_DAS - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 DAS module" + depends on SND_SOC_TEGRA help Say Y or M if you want to add support for the Tegra20 DAS module. You will also need to select the individual machine drivers to support below. config SND_SOC_TEGRA20_I2S - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 I2S interface" + depends on SND_SOC_TEGRA select SND_SOC_TEGRA20_DAS help Say Y or M if you want to add support for codecs attached to the @@ -36,8 +36,8 @@ config SND_SOC_TEGRA20_I2S machine drivers to support below. config SND_SOC_TEGRA20_SPDIF - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 SPDIF interface" + depends on SND_SOC_TEGRA default m help Say Y or M if you want to add support for the Tegra20 SPDIF interface. @@ -45,16 +45,16 @@ config SND_SOC_TEGRA20_SPDIF below. config SND_SOC_TEGRA30_AHUB - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_3x_SOC + tristate "Tegra30 AHUB module" + depends on SND_SOC_TEGRA help - Say Y or M if you want to add support for the Tegra20 AHUB module. + Say Y or M if you want to add support for the Tegra30 AHUB module. You will also need to select the individual machine drivers to support below. config SND_SOC_TEGRA30_I2S - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_3x_SOC + tristate "Tegra30 I2S interface" + depends on SND_SOC_TEGRA select SND_SOC_TEGRA30_AHUB help Say Y or M if you want to add support for codecs attached to the @@ -64,8 +64,6 @@ config SND_SOC_TEGRA30_I2S config SND_SOC_TEGRA_RT5640 tristate "SoC Audio support for Tegra boards using an RT5640 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_RT5640 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -74,8 +72,6 @@ config SND_SOC_TEGRA_RT5640 config SND_SOC_TEGRA_WM8753 tristate "SoC Audio support for Tegra boards using a WM8753 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_WM8753 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -84,8 +80,6 @@ config SND_SOC_TEGRA_WM8753 config SND_SOC_TEGRA_WM8903 tristate "SoC Audio support for Tegra boards using a WM8903 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_WM8903 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -94,7 +88,7 @@ config SND_SOC_TEGRA_WM8903 config SND_SOC_TEGRA_WM9712 tristate "SoC Audio support for Tegra boards using a WM9712 codec" - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC && GPIOLIB + depends on SND_SOC_TEGRA && GPIOLIB select SND_SOC_TEGRA20_AC97 select SND_SOC_WM9712 help @@ -104,7 +98,6 @@ config SND_SOC_TEGRA_WM9712 config SND_SOC_TEGRA_TRIMSLICE tristate "SoC Audio support for TrimSlice board" depends on SND_SOC_TEGRA && I2C - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC select SND_SOC_TLV320AIC23_I2C help Say Y or M here if you want to add support for SoC audio on the @@ -113,7 +106,6 @@ config SND_SOC_TEGRA_TRIMSLICE config SND_SOC_TEGRA_ALC5632 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC select SND_SOC_ALC5632 help Say Y or M here if you want to add support for SoC audio on the @@ -122,8 +114,6 @@ config SND_SOC_TEGRA_ALC5632 config SND_SOC_TEGRA_MAX98090 tristate "SoC Audio support for Tegra boards using a MAX98090 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_MAX98090 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -132,8 +122,6 @@ config SND_SOC_TEGRA_MAX98090 config SND_SOC_TEGRA_RT5677 tristate "SoC Audio support for Tegra boards using a RT5677 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_RT5677 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -142,8 +130,6 @@ config SND_SOC_TEGRA_RT5677 config SND_SOC_TEGRA_SGTL5000 tristate "SoC Audio support for Tegra boards using a SGTL5000 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_SGTL5000 help Say Y or M here if you want to add support for SoC audio on Tegra diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 8c10ae7982bad992cc94f60db565ee3791f7bc3a..43679aeeb12beadc948d23bc59a174a72b50ecac 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -544,8 +544,8 @@ static int tegra30_ahub_probe(struct platform_device *pdev) soc_data->mod_list_mask)) continue; - rst = reset_control_get(&pdev->dev, - configlink_mods[i].rst_name); + rst = reset_control_get_exclusive(&pdev->dev, + configlink_mods[i].rst_name); if (IS_ERR(rst)) { dev_err(&pdev->dev, "Can't get reset %s\n", configlink_mods[i].rst_name); diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index b2b279c96029d90e5039701b5d8e2c955db2d43c..0b176ea24914ba7923c7de246a780839f1e56a89 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -275,7 +275,7 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { +static const struct snd_soc_dai_ops tegra30_i2s_dai_ops = { .set_fmt = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 0509902512ccd38a02376c0dc41a603d75f9a572..5197d6b18cb6758915c23d50b6f8b8dc7a515d07 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -124,18 +124,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_alc5632_card_remove(struct snd_soc_card *card) -{ - struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1, - &tegra_alc5632_hp_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_alc5632_dai = { .name = "ALC5632", .stream_name = "ALC5632 PCM", @@ -150,7 +138,6 @@ static struct snd_soc_dai_link tegra_alc5632_dai = { static struct snd_soc_card snd_soc_tegra_alc5632 = { .name = "tegra-alc5632", .owner = THIS_MODULE, - .remove = tegra_alc5632_card_remove, .dai_link = &tegra_alc5632_dai, .num_links = 1, .controls = tegra_alc5632_controls, @@ -173,7 +160,6 @@ static int tegra_alc5632_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, alc5632); alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c index c34a54d6e8121b9a6ba6c2b996112908eac25778..cf142e2c7bd796c1c993cfc64847ea7d29583606 100644 --- a/sound/soc/tegra/tegra_max98090.c +++ b/sound/soc/tegra/tegra_max98090.c @@ -176,23 +176,6 @@ static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_max98090_card_remove(struct snd_soc_card *card) -{ - struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_max98090_hp_jack, 1, - &tegra_max98090_hp_jack_gpio); - } - - if (gpio_is_valid(machine->gpio_mic_det)) { - snd_soc_jack_free_gpios(&tegra_max98090_mic_jack, 1, - &tegra_max98090_mic_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_max98090_dai = { .name = "max98090", .stream_name = "max98090 PCM", @@ -206,7 +189,6 @@ static struct snd_soc_dai_link tegra_max98090_dai = { static struct snd_soc_card snd_soc_tegra_max98090 = { .name = "tegra-max98090", .owner = THIS_MODULE, - .remove = tegra_max98090_card_remove, .dai_link = &tegra_max98090_dai, .num_links = 1, .controls = tegra_max98090_controls, @@ -229,7 +211,6 @@ static int tegra_max98090_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 93a356802345aeefd00c4171fd55032c9802e15c..fc81b48aa9d6afded35a7b7588c7e3142965e7cf 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -126,18 +126,6 @@ static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_rt5640_card_remove(struct snd_soc_card *card) -{ - struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_rt5640_hp_jack, 1, - &tegra_rt5640_hp_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_rt5640_dai = { .name = "RT5640", .stream_name = "RT5640 PCM", @@ -151,7 +139,6 @@ static struct snd_soc_dai_link tegra_rt5640_dai = { static struct snd_soc_card snd_soc_tegra_rt5640 = { .name = "tegra-rt5640", .owner = THIS_MODULE, - .remove = tegra_rt5640_card_remove, .dai_link = &tegra_rt5640_dai, .num_links = 1, .controls = tegra_rt5640_controls, @@ -174,7 +161,6 @@ static int tegra_rt5640_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_hp_det = of_get_named_gpio_flags( diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c index ebf58d0e0f10b222c70d3db17ffec334c191358c..0e4805c7b4cadb20a0017cda4828d80af753a6fc 100644 --- a/sound/soc/tegra/tegra_rt5677.c +++ b/sound/soc/tegra/tegra_rt5677.c @@ -169,23 +169,6 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_rt5677_card_remove(struct snd_soc_card *card) -{ - struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_rt5677_hp_jack, 1, - &tegra_rt5677_hp_jack_gpio); - } - - if (gpio_is_valid(machine->gpio_mic_present)) { - snd_soc_jack_free_gpios(&tegra_rt5677_mic_jack, 1, - &tegra_rt5677_mic_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_rt5677_dai = { .name = "RT5677", .stream_name = "RT5677 PCM", @@ -199,7 +182,6 @@ static struct snd_soc_dai_link tegra_rt5677_dai = { static struct snd_soc_card snd_soc_tegra_rt5677 = { .name = "tegra-rt5677", .owner = THIS_MODULE, - .remove = tegra_rt5677_card_remove, .dai_link = &tegra_rt5677_dai, .num_links = 1, .controls = tegra_rt5677_controls, @@ -222,7 +204,6 @@ static int tegra_rt5677_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c index 6dda01f6998349d6d6f80d629af08480392bf776..45a4aa9d2a479a2c5ff82ac39ec06c30bf0952d2 100644 --- a/sound/soc/tegra/tegra_sgtl5000.c +++ b/sound/soc/tegra/tegra_sgtl5000.c @@ -124,7 +124,6 @@ static int tegra_sgtl5000_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); ret = snd_soc_of_parse_card_name(card, "nvidia,model"); diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index d0ab0026a4cd879e906d388979d0f02af52d0c56..23a810e3bacc01c893be09e51c605c10d904cccd 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -132,7 +132,6 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); ret = snd_soc_of_parse_card_name(card, "nvidia,model"); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index dbfb49298ae8bea177237482f9d8dc58169bdf1e..18bdae59a4df716a8e59bb7fe15c08287b6f8d77 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -203,12 +203,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card) snd_soc_get_pcm_runtime(card, card->dai_link[0].name); struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_codec *codec = codec_dai->codec; - struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1, - &tegra_wm8903_hp_jack_gpio); - } wm8903_mic_detect(codec, NULL, 0, 0); @@ -252,7 +246,6 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios", diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index c9cd2243262715ecfd929b44c6e7c99dee1d7aac..864a3345972e5a17421ed904df58d61abf650338 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -81,7 +81,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->codec = platform_device_alloc("wm9712-codec", -1); diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index c9dcad9bb93123b6b901ad3a3db33bfad0f3b19e..99bcdd979eb2955cb484f773cbb1c1dcb6a830b4 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -127,7 +127,6 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, trimslice); trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(np, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index 7912bf09dc4d70c66f19316c6c8f2b5a0d60357c..a2bb68fea5a32ae0ccb76f235d6c7ef4df399052 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -271,7 +271,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops txx9aclc_pcm_ops = { +static const struct snd_pcm_ops txx9aclc_pcm_ops = { .open = txx9aclc_pcm_open, .close = txx9aclc_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -403,7 +403,7 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver txx9aclc_soc_platform = { +static const struct snd_soc_platform_driver txx9aclc_soc_platform = { .probe = txx9aclc_pcm_probe, .remove = txx9aclc_pcm_remove, .ops = &txx9aclc_pcm_ops, diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index b50f68a439cebaf5d28ac38331e165b31e72ead2..070a6880980e89f5dc60d443b9fd5682715d7226 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -33,6 +33,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_0", .cpu_dai_name = "ux500-msp-i2s.1", .codec_dai_name = "ab8500-codec-dai.0", + .platform_name = "ux500-msp-i2s.1", .codec_name = "ab8500-codec.0", .init = mop500_ab8500_machine_init, .ops = mop500_ab8500_ops, @@ -42,6 +43,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_1", .cpu_dai_name = "ux500-msp-i2s.3", .codec_dai_name = "ab8500-codec-dai.1", + .platform_name = "ux500-msp-i2s.3", .codec_name = "ab8500-codec.0", .init = NULL, .ops = mop500_ab8500_ops, @@ -85,6 +87,8 @@ static int mop500_of_probe(struct platform_device *pdev, for (i = 0; i < 2; i++) { mop500_dai_links[i].cpu_of_node = msp_np[i]; mop500_dai_links[i].cpu_dai_name = NULL; + mop500_dai_links[i].platform_of_node = msp_np[i]; + mop500_dai_links[i].platform_name = NULL; mop500_dai_links[i].codec_of_node = codec_np; mop500_dai_links[i].codec_name = NULL; } @@ -111,7 +115,6 @@ static int mop500_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n", __func__, mop500_card.name); - platform_set_drvdata(pdev, &mop500_card); snd_soc_card_set_drvdata(&mop500_card, NULL); diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index ec5152aa3f6ed2a9b1eeeea37b967d1d689d2dad..625b72a5facda409bc3ad1f6822871a0cc05451b 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -707,7 +707,7 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops ux500_msp_dai_ops[] = { +static const struct snd_soc_dai_ops ux500_msp_dai_ops[] = { { .set_sysclk = ux500_msp_dai_set_dai_sysclk, .set_fmt = ux500_msp_dai_set_dai_fmt, diff --git a/sound/soc/zte/zx-i2s.c b/sound/soc/zte/zx-i2s.c index 8bbad1d72bc560deae51537af1eec50b83186812..9a0565937d1ff5ba7127a6754edf4b8ec6589e57 100644 --- a/sound/soc/zte/zx-i2s.c +++ b/sound/soc/zte/zx-i2s.c @@ -357,7 +357,7 @@ static void zx_i2s_shutdown(struct snd_pcm_substream *substream, clk_disable_unprepare(zx_i2s->dai_pclk); } -static struct snd_soc_dai_ops zx_i2s_dai_ops = { +static const struct snd_soc_dai_ops zx_i2s_dai_ops = { .trigger = zx_i2s_trigger, .hw_params = zx_i2s_hw_params, .set_fmt = zx_i2s_set_fmt, diff --git a/sound/soc/zte/zx-spdif.c b/sound/soc/zte/zx-spdif.c index 9fa6463ce5d75a58f471bfbfd0a64b948755641f..b143f9f682d2f6e9c889a1dc2dc81b79b6fd504d 100644 --- a/sound/soc/zte/zx-spdif.c +++ b/sound/soc/zte/zx-spdif.c @@ -264,7 +264,7 @@ static void zx_spdif_shutdown(struct snd_pcm_substream *substream, (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE \ | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops zx_spdif_dai_ops = { +static const struct snd_soc_dai_ops zx_spdif_dai_ops = { .trigger = zx_spdif_trigger, .startup = zx_spdif_startup, .shutdown = zx_spdif_shutdown, diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c index bd632cc503b3a3e6aed20f8e1076cdda62020ff5..dc955272f58b07350b042852e20209c9fc9fb08a 100644 --- a/sound/soc/zte/zx-tdm.c +++ b/sound/soc/zte/zx-tdm.c @@ -309,7 +309,7 @@ static void zx_tdm_shutdown(struct snd_pcm_substream *substream, clk_disable_unprepare(zx_tdm->dai_wclk); } -static struct snd_soc_dai_ops zx_tdm_dai_ops = { +static const struct snd_soc_dai_ops zx_tdm_dai_ops = { .trigger = zx_tdm_trigger, .hw_params = zx_tdm_hw_params, .set_fmt = zx_tdm_set_fmt, diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 35c1f6ae773f051e159c896d4565901f69258f68..56f17410fcea742434a0cc106b3b04f13a674936 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -666,7 +666,7 @@ static snd_pcm_uframes_t snd_amd7930_capture_pointer(struct snd_pcm_substream *s } /* Playback and capture have identical properties. */ -static struct snd_pcm_hardware snd_amd7930_pcm_hw = +static const struct snd_pcm_hardware snd_amd7930_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -733,7 +733,7 @@ static int snd_amd7930_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); } -static struct snd_pcm_ops snd_amd7930_playback_ops = { +static const struct snd_pcm_ops snd_amd7930_playback_ops = { .open = snd_amd7930_playback_open, .close = snd_amd7930_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -744,7 +744,7 @@ static struct snd_pcm_ops snd_amd7930_playback_ops = { .pointer = snd_amd7930_playback_pointer, }; -static struct snd_pcm_ops snd_amd7930_capture_ops = { +static const struct snd_pcm_ops snd_amd7930_capture_ops = { .open = snd_amd7930_capture_open, .close = snd_amd7930_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 3d7d425fbd24d9af3fa534f268a3f0aeb2e7580b..e73c962590eb689f446cd1f17d179aab3e292b9b 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1089,7 +1089,7 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) return 0; /* all things are ok.. */ } -static struct snd_pcm_hardware snd_cs4231_playback = { +static const struct snd_pcm_hardware snd_cs4231_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1113,7 +1113,7 @@ static struct snd_pcm_hardware snd_cs4231_playback = { .periods_max = 1024, }; -static struct snd_pcm_hardware snd_cs4231_capture = { +static const struct snd_pcm_hardware snd_cs4231_capture = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1203,7 +1203,7 @@ static int snd_cs4231_capture_close(struct snd_pcm_substream *substream) * XXX the audio AUXIO register... */ -static struct snd_pcm_ops snd_cs4231_playback_ops = { +static const struct snd_pcm_ops snd_cs4231_playback_ops = { .open = snd_cs4231_playback_open, .close = snd_cs4231_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1214,7 +1214,7 @@ static struct snd_pcm_ops snd_cs4231_playback_ops = { .pointer = snd_cs4231_playback_pointer, }; -static struct snd_pcm_ops snd_cs4231_capture_ops = { +static const struct snd_pcm_ops snd_cs4231_capture_ops = { .open = snd_cs4231_capture_open, .close = snd_cs4231_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 52063b2626677144d8f47585147cc129011f93c7..abc7bd5055eb12d4709fc5251b8ffe5cb4bbc4d4 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -1980,7 +1980,7 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id) /**************************************************************************** PCM Interface ****************************************************************************/ -static struct snd_pcm_hardware snd_dbri_pcm_hw = { +static const struct snd_pcm_hardware snd_dbri_pcm_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -2213,7 +2213,7 @@ static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream) return ret; } -static struct snd_pcm_ops snd_dbri_ops = { +static const struct snd_pcm_ops snd_dbri_ops = { .open = snd_dbri_open, .close = snd_dbri_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index fac7e6eb9529c26d2bb3e30ceaba11b42f55d15b..1ef52edeb5384cea2daa4d701b660a28fc2de6d2 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c @@ -322,7 +322,7 @@ snd_at73c213_pcm_pointer(struct snd_pcm_substream *substream) return pos; } -static struct snd_pcm_ops at73c213_playback_ops = { +static const struct snd_pcm_ops at73c213_playback_ops = { .open = snd_at73c213_pcm_open, .close = snd_at73c213_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c index 55579f6b8cb2ed36566cb0c24685d743489b1a4f..396c406d0f779e2d776524a8f9792fd9efafa14e 100644 --- a/sound/synth/emux/emux_seq.c +++ b/sound/synth/emux/emux_seq.c @@ -99,7 +99,7 @@ snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index) sprintf(tmpname, "%s Port %d", emu->name, i); p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS, 0, &pinfo); - if (p == NULL) { + if (!p) { snd_printk(KERN_ERR "can't create port\n"); return -ENOMEM; } @@ -144,13 +144,13 @@ snd_emux_create_port(struct snd_emux *emu, char *name, int i, type, cap; /* Allocate structures for this channel */ - if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "no memory\n"); + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) return NULL; - } - p->chset.channels = kcalloc(max_channels, sizeof(struct snd_midi_channel), GFP_KERNEL); - if (p->chset.channels == NULL) { - snd_printk(KERN_ERR "no memory\n"); + + p->chset.channels = kcalloc(max_channels, sizeof(*p->chset.channels), + GFP_KERNEL); + if (!p->chset.channels) { kfree(p); return NULL; } @@ -370,8 +370,8 @@ int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card) if (emu->midi_ports <= 0) return 0; - emu->vmidi = kcalloc(emu->midi_ports, sizeof(struct snd_rawmidi *), GFP_KERNEL); - if (emu->vmidi == NULL) + emu->vmidi = kcalloc(emu->midi_ports, sizeof(*emu->vmidi), GFP_KERNEL); + if (!emu->vmidi) return -ENOMEM; for (i = 0; i < emu->midi_ports; i++) { @@ -403,7 +403,7 @@ int snd_emux_delete_virmidi(struct snd_emux *emu) { int i; - if (emu->vmidi == NULL) + if (!emu->vmidi) return 0; for (i = 0; i < emu->midi_ports; i++) { diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index dcddfc354ba683c65a5266a0c448d625371d21b7..c7641cb506164cf268a9a2e2657f777875af2d3c 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c @@ -143,37 +143,32 @@ static int usb6fire_chip_probe(struct usb_interface *intf, chip->card = card; ret = usb6fire_comm_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = usb6fire_midi_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = usb6fire_pcm_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = usb6fire_control_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = snd_card_register(card); if (ret < 0) { dev_err(&intf->dev, "cannot register card."); - usb6fire_chip_destroy(chip); - return ret; + goto destroy_chip; } usb_set_intfdata(intf, chip); return 0; + +destroy_chip: + usb6fire_chip_destroy(chip); + return ret; } static void usb6fire_chip_disconnect(struct usb_interface *intf) @@ -198,7 +193,7 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf) } } -static struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x0ccd, diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 36f4115eb1cddfcc89aaaead0138ef92d92672f2..224a6a5d1c0e7a6d9b2b359ea7b94b9588bf360c 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -555,7 +555,7 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer( return ret; } -static struct snd_pcm_ops pcm_ops = { +static const struct snd_pcm_ops pcm_ops = { .open = usb6fire_pcm_open, .close = usb6fire_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c index 2ff9d578753a7b7d20ece51ff45bdb503586a519..7371e5b0603564e37190d074b5ae9506c80c3e32 100644 --- a/sound/usb/bcd2000/bcd2000.c +++ b/sound/usb/bcd2000/bcd2000.c @@ -29,7 +29,7 @@ #define PREFIX "snd-bcd2000: " #define BUFSIZE 64 -static struct usb_device_id id_table[] = { +static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1397, 0x00bd) }, { }, }; diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 8f66ba730d69d943196ddd7629e777083846b9ec..fb1c1eac0b5ef3b56cd9b9873d46f694eda43457 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -338,7 +338,7 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) } /* operators for both playback and capture */ -static struct snd_pcm_ops snd_usb_caiaq_ops = { +static const struct snd_pcm_ops snd_usb_caiaq_ops = { .open = snd_usb_caiaq_substream_open, .close = snd_usb_caiaq_substream_close, .ioctl = snd_pcm_lib_ioctl, @@ -722,7 +722,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) int i, frame; struct urb **urbs; struct usb_device *usb_dev = cdev->chip.dev; - struct device *dev = caiaqdev_to_dev(cdev); unsigned int pipe; pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? @@ -731,7 +730,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); if (!urbs) { - dev_err(dev, "unable to kmalloc() urbs, OOM!?\n"); *ret = -ENOMEM; return NULL; } @@ -746,7 +744,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) urbs[i]->transfer_buffer = kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); if (!urbs[i]->transfer_buffer) { - dev_err(dev, "unable to kmalloc() transfer buffer, OOM!?\n"); *ret = -ENOMEM; return urbs; } diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index b871ba407e4ec8aa710c5f79a99f2e52fb7741b7..0fb6b1b7926170030661c6724e1be6260da6cfa6 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -81,7 +81,7 @@ enum { DEPTH_32 = 3 }; -static struct usb_device_id snd_usb_id_table[] = { +static const struct usb_device_id snd_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = USB_VID_NATIVEINSTRUMENTS, diff --git a/sound/usb/card.c b/sound/usb/card.c index 6640277a725b6565adfb9665077903ff51940c34..23d1d23aefec375c2c857f090f4920894e4bc7f8 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -221,6 +221,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) struct usb_interface_descriptor *altsd; void *control_header; int i, protocol; + int rest_bytes; /* find audiocontrol interface */ host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; @@ -235,6 +236,15 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) return -EINVAL; } + rest_bytes = (void *)(host_iface->extra + host_iface->extralen) - + control_header; + + /* just to be sure -- this shouldn't hit at all */ + if (rest_bytes <= 0) { + dev_err(&dev->dev, "invalid control header\n"); + return -EINVAL; + } + switch (protocol) { default: dev_warn(&dev->dev, @@ -245,11 +255,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) case UAC_VERSION_1: { struct uac1_ac_header_descriptor *h1 = control_header; + if (rest_bytes < sizeof(*h1)) { + dev_err(&dev->dev, "too short v1 buffer descriptor\n"); + return -EINVAL; + } + if (!h1->bInCollection) { dev_info(&dev->dev, "skipping empty audio interface (v1)\n"); return -EINVAL; } + if (rest_bytes < h1->bLength) { + dev_err(&dev->dev, "invalid buffer length (v1)\n"); + return -EINVAL; + } + if (h1->bLength < sizeof(*h1) + h1->bInCollection) { dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n"); return -EINVAL; @@ -486,7 +506,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id) return false; } -static struct usb_device_id usb_audio_ids[]; /* defined below */ +static const struct usb_device_id usb_audio_ids[]; /* defined below */ /* look for the corresponding quirk */ static const struct snd_usb_audio_quirk * @@ -814,7 +834,7 @@ static int usb_audio_reset_resume(struct usb_interface *intf) #define usb_audio_reset_resume NULL #endif /* CONFIG_PM */ -static struct usb_device_id usb_audio_ids [] = { +static const struct usb_device_id usb_audio_ids [] = { #include "quirks-table.h" { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), .bInterfaceClass = USB_CLASS_AUDIO, diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index 33db205dd12b57d8b53436d5fd2eb9ff6cc2a22a..175d8d6b7f59922f120b84bffa092a04ddbe6bd3 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -513,7 +513,7 @@ static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub) return bytes_to_frames(alsa_sub->runtime, dma_offset); } -static struct snd_pcm_ops pcm_ops = { +static const struct snd_pcm_ops pcm_ops = { .open = hiface_pcm_open, .close = hiface_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/usb/midi.c b/sound/usb/midi.c index a35f414672373caa75a550be4b171bc20990f09f..a92e2b2a91ecf54b2fdbfd4e1e6636e83fef778c 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -242,8 +242,8 @@ static void dump_urb(const char *type, const u8 *data, int length) { snd_printk(KERN_DEBUG "%s packet: [", type); for (; length > 0; ++data, --length) - printk(" %02x", *data); - printk(" ]\n"); + printk(KERN_CONT " %02x", *data); + printk(KERN_CONT " ]\n"); } #else #define dump_urb(type, data, length) /* nothing */ @@ -2435,10 +2435,8 @@ int __snd_usbmidi_create(struct snd_card *card, err = -ENXIO; break; } - if (err < 0) { - kfree(umidi); - return err; - } + if (err < 0) + goto free_midi; /* create rawmidi device */ out_ports = 0; @@ -2448,23 +2446,25 @@ int __snd_usbmidi_create(struct snd_card *card, in_ports += hweight16(endpoints[i].in_cables); } err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); - if (err < 0) { - kfree(umidi); - return err; - } + if (err < 0) + goto free_midi; /* create endpoint/port structures */ if (quirk && quirk->type == QUIRK_MIDI_MIDIMAN) err = snd_usbmidi_create_endpoints_midiman(umidi, &endpoints[0]); else err = snd_usbmidi_create_endpoints(umidi, endpoints); - if (err < 0) { - return err; - } + if (err < 0) + goto exit; usb_autopm_get_interface_no_resume(umidi->iface); list_add_tail(&umidi->list, midi_list); return 0; + +free_midi: + kfree(umidi); +exit: + return err; } EXPORT_SYMBOL(__snd_usbmidi_create); diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index c19a5dd056317128f3fbc9e2b02dc4f775454c6b..386fbfd5c6176059b5b87b5cf53a0dbcc6193777 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -890,7 +890,7 @@ static snd_pcm_uframes_t playback_pcm_pointer(struct snd_pcm_substream *subs) return ua101_pcm_pointer(ua, &ua->playback); } -static struct snd_pcm_ops capture_pcm_ops = { +static const struct snd_pcm_ops capture_pcm_ops = { .open = capture_pcm_open, .close = capture_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -903,7 +903,7 @@ static struct snd_pcm_ops capture_pcm_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops playback_pcm_ops = { +static const struct snd_pcm_ops playback_pcm_ops = { .open = playback_pcm_open, .close = playback_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -1366,7 +1366,7 @@ static void ua101_disconnect(struct usb_interface *interface) mutex_unlock(&devices_mutex); } -static struct usb_device_id ua101_ids[] = { +static const struct usb_device_id ua101_ids[] = { { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */ { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */ { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 082736c539bc14eec73a1afad11e2a3cd5577d89..9732edf77f860dbb668ea14206097914e2fcbdf5 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -318,12 +318,15 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, while (timeout-- > 0) { idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); - if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, idx, buf, val_len) >= val_len) { + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + validx, idx, buf, val_len); + if (err >= val_len) { *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); err = 0; goto out; + } else if (err == -ETIMEDOUT) { + goto out; } } usb_audio_dbg(chip, @@ -483,12 +486,15 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, while (timeout-- > 0) { idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); - if (snd_usb_ctl_msg(chip->dev, - usb_sndctrlpipe(chip->dev, 0), request, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - validx, idx, buf, val_len) >= 0) { + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + validx, idx, buf, val_len); + if (err >= 0) { err = 0; goto out; + } else if (err == -ETIMEDOUT) { + goto out; } } usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", @@ -542,6 +548,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, if (size < sizeof(scale)) return -ENOMEM; + if (cval->min_mute) + scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE; scale[2] = cval->dBmin; scale[3] = cval->dBmax; if (copy_to_user(_tlv, scale, sizeof(scale))) diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 3417ef347e40432482b84de271a3bb98c8724297..2b4b067646ab099653fe7ea79d9af1570e2971f6 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -64,6 +64,7 @@ struct usb_mixer_elem_info { int cached; int cache_val[MAX_CHANNELS]; u8 initialized; + u8 min_mute; void *private_data; }; diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e3d1dec48ee49f21d4efe4627fc3c264d76fcfe2..e1e7ce9ab217f6f716fc95da5d1544279c0d1b75 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1878,6 +1878,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, if (unitid == 7 && cval->control == UAC_FU_VOLUME) snd_dragonfly_quirk_db_scale(mixer, cval, kctl); break; + /* lowest playback value is muted on C-Media devices */ + case USB_ID(0x0d8c, 0x000c): + case USB_ID(0x0d8c, 0x0014): + if (strstr(kctl->id.name, "Playback")) + cval->min_mute = 1; + break; } } diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 9aa5b18554812a949503375e23764b3d926a0f2d..b9c9a19f9588a8c2eab67e6bd2ad8e5b531c7655 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -857,7 +857,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) return ret; } -static struct snd_pcm_hardware snd_usb_hardware = +static const struct snd_pcm_hardware snd_usb_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -1690,7 +1690,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream return -EINVAL; } -static struct snd_pcm_ops snd_usb_playback_ops = { +static const struct snd_pcm_ops snd_usb_playback_ops = { .open = snd_usb_playback_open, .close = snd_usb_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1703,7 +1703,7 @@ static struct snd_pcm_ops snd_usb_playback_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops snd_usb_capture_ops = { +static const struct snd_pcm_ops snd_usb_capture_ops = { .open = snd_usb_capture_open, .close = snd_usb_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index d7b0b0a3a2db55617a908e2fe4a8a2af90082e02..b8cb57aeec77fa69f7194aa57b2d0fff163731c1 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -146,10 +146,9 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, unsigned *rate_table = NULL; fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); - if (!fp) { - usb_audio_err(chip, "cannot memdup\n"); + if (!fp) return -ENOMEM; - } + INIT_LIST_HEAD(&fp->list); if (fp->nr_rates > MAX_NR_RATES) { kfree(fp); @@ -1138,10 +1137,13 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) case USB_ID(0x047F, 0x02F7): /* Plantronics BT-600 */ case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */ case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */ + case USB_ID(0x047F, 0xC022): /* Plantronics C310 */ + case USB_ID(0x047F, 0xC036): /* Plantronics C520-M */ case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ + case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */ case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */ case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */ @@ -1308,10 +1310,13 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(20); - /* Zoom R16/24 needs a tiny delay here, otherwise requests like - * get/set frequency return as failed despite actually succeeding. + /* Zoom R16/24, Logitech H650e, Jabra 550a needs a tiny delay here, + * otherwise requests like get/set frequency return as failed despite + * actually succeeding. */ - if (chip->usb_id == USB_ID(0x1686, 0x00dd) && + if ((chip->usb_id == USB_ID(0x1686, 0x00dd) || + chip->usb_id == USB_ID(0x046d, 0x0a46) || + chip->usb_id == USB_ID(0x0b0e, 0x0349)) && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(1); } @@ -1374,6 +1379,10 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, } } break; + case USB_ID(0x16d0, 0x0a23): + if (fp->altsetting == 2) + return SNDRV_PCM_FMTBIT_DSD_U32_BE; + break; default: break; diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 8e9548bc1f1a922e6ceb5c99450da8ba28ee22ff..d1776e5517ffee4687c1200fff51cb3fb52fbf2a 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -658,10 +658,8 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) continue; fp = kzalloc(sizeof(*fp), GFP_KERNEL); - if (! fp) { - dev_err(&dev->dev, "cannot malloc\n"); + if (!fp) return -ENOMEM; - } fp->iface = iface_no; fp->altsetting = altno; diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index a33e31b2fc2fe62f4fee9d57b0bb8c7890298fe5..159da1f3924e984ccacdb6dcb349adc6080bb9b5 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -508,8 +508,7 @@ static bool us122l_create_card(struct snd_card *card) err = us122l_create_usbmidi(card); if (err < 0) { snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err); - us122l_stop(us122l); - return false; + goto stop; } err = usb_stream_hwdep_new(card); if (err < 0) { @@ -518,10 +517,13 @@ static bool us122l_create_card(struct snd_card *card) list_for_each(p, &us122l->midi_list) snd_usbmidi_disconnect(p); - us122l_stop(us122l); - return false; + goto stop; } return true; + +stop: + us122l_stop(us122l); + return false; } static void snd_us122l_free(struct snd_card *card) @@ -736,7 +738,7 @@ static int snd_us122l_resume(struct usb_interface *intf) return err; } -static struct usb_device_id snd_us122l_usb_id_table[] = { +static const struct usb_device_id snd_us122l_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x0644, diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index bf618e1500acb3488193b90e6e7dc4469e22509d..e229abd216526cae577aafd3dd2f2f3ed3abc5ba 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c @@ -191,7 +191,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, } pg = get_order(read_size); - sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg); + sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO| + __GFP_NOWARN, pg); if (!sk->s) { snd_printk(KERN_WARNING "couldn't __get_free_pages()\n"); goto out; @@ -211,7 +212,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, pg = get_order(write_size); sk->write_page = - (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg); + (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO| + __GFP_NOWARN, pg); if (!sk->write_page) { snd_printk(KERN_WARNING "couldn't __get_free_pages()\n"); usb_stream_free(sk); @@ -352,20 +354,22 @@ static int submit_urbs(struct usb_stream_kernel *sk, int err; prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb); err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "%i\n", err); - return err; - } + if (err < 0) + goto report_failure; + sk->idle_inurb = sk->completed_inurb; sk->completed_inurb = inurb; err = usb_submit_urb(sk->idle_outurb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "%i\n", err); - return err; - } + if (err < 0) + goto report_failure; + sk->idle_outurb = sk->completed_outurb; sk->completed_outurb = outurb; return 0; + +report_failure: + snd_printk(KERN_ERR "%i\n", err); + return err; } #ifdef DEBUG_LOOP_BACK @@ -625,9 +629,9 @@ static void i_capture_start(struct urb *urb) urb->iso_frame_desc[0].actual_length); for (pack = 1; pack < urb->number_of_packets; ++pack) { int l = urb->iso_frame_desc[pack].actual_length; - printk(" %i", l); + printk(KERN_CONT " %i", l); } - printk("\n"); + printk(KERN_CONT "\n"); } #endif if (!empty && s->state < usb_stream_sync1) diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 91e0e2a4808c99f8d9193342908343875f745fdd..4569c0efac0a864b557d4a597aff1c3bffad8957 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -313,7 +313,7 @@ static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S) } -static struct usb_device_id snd_usX2Y_usb_id_table[] = { +static const struct usb_device_id snd_usX2Y_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x1604, diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index dd40ca9d858a7db5a65c60bda74969196033b88a..f93b355756e6027e694257c0e2ab829767c7be98 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -419,10 +419,8 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs) if (is_playback && NULL == subs->tmpbuf) { /* allocate a temporary buffer for playback */ subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL); - if (NULL == subs->tmpbuf) { - snd_printk(KERN_ERR "cannot malloc tmpbuf\n"); + if (!subs->tmpbuf) return -ENOMEM; - } } /* allocate and initialize data urbs */ for (i = 0; i < NRURBS; i++) { @@ -907,7 +905,7 @@ static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_usX2Y_pcm_ops = +static const struct snd_pcm_ops snd_usX2Y_pcm_ops = { .open = snd_usX2Y_pcm_open, .close = snd_usX2Y_pcm_close, @@ -949,10 +947,9 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; i <= SNDRV_PCM_STREAM_CAPTURE; ++i) { usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL); - if (NULL == usX2Y_substream[i]) { - snd_printk(KERN_ERR "cannot malloc\n"); + if (!usX2Y_substream[i]) return -ENOMEM; - } + usX2Y_substream[i]->usX2Y = usX2Y(card); } diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index d51c7fd7835bb1b8e54a521fb6e9a668781bdb5e..0d050528a4e154dd856e3120fa464ffddb179ca4 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -587,7 +587,7 @@ static int snd_usX2Y_usbpcm_close(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_usX2Y_usbpcm_ops = +static const struct snd_pcm_ops snd_usX2Y_usbpcm_ops = { .open = snd_usX2Y_usbpcm_open, .close = snd_usX2Y_usbpcm_close, diff --git a/tools/Makefile b/tools/Makefile index 221e1ce78b06bb43bb344b36e01cd6dd72b10feb..9dfede37c8ff8a4729ba05c60c963d3561d4cfcd 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -18,7 +18,6 @@ help: @echo ' iio - IIO tools' @echo ' kvm_stat - top-like utility for displaying kvm statistics' @echo ' leds - LEDs tools' - @echo ' lguest - a minimal 32-bit x86 hypervisor' @echo ' liblockdep - user-space wrapper for kernel locking-validator' @echo ' net - misc networking tools' @echo ' perf - Linux performance measurement and analysis tool' @@ -90,10 +89,10 @@ freefall: FORCE kvm_stat: FORCE $(call descend,kvm/$@) -all: acpi cgroup cpupower gpio hv firewire lguest liblockdep \ - perf selftests turbostat usb \ +all: acpi cgroup cpupower gpio hv firewire liblockdep \ + perf selftests spi turbostat usb \ virtio vm net x86_energy_perf_policy \ - tmon freefall objtool kvm_stat + tmon freefall iio objtool kvm_stat acpi_install: $(call descend,power/$(@:_install=),install) @@ -101,7 +100,7 @@ acpi_install: cpupower_install: $(call descend,power/$(@:_install=),install) -cgroup_install firewire_install gpio_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install: +cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install net_install objtool_install: $(call descend,$(@:_install=),install) liblockdep_install: @@ -123,7 +122,7 @@ kvm_stat_install: $(call descend,kvm/$(@:_install=),install) install: acpi_install cgroup_install cpupower_install gpio_install \ - hv_install firewire_install lguest_install liblockdep_install \ + hv_install firewire_install iio_install liblockdep_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install vm_install net_install x86_energy_perf_policy_install \ tmon_install freefall_install objtool_install kvm_stat_install @@ -134,7 +133,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean objtool_clean leds_clean: +cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean objtool_clean leds_clean: $(call descend,$(@:_clean=),clean) liblockdep_clean: @@ -168,7 +167,7 @@ freefall_clean: build_clean: $(call descend,build,clean) -clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ +clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \ perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h index 5e3c673fa3f4435b027fbc634815be10c26cf39f..5db2d4c6a55faf7940be63b8b03ee2a7383fe988 100644 --- a/tools/arch/arm/include/uapi/asm/kvm.h +++ b/tools/arch/arm/include/uapi/asm/kvm.h @@ -203,6 +203,14 @@ struct kvm_arch_memory_slot { #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff #define VGIC_LEVEL_INFO_LINE_LEVEL 0 +/* Device Control API on vcpu fd */ +#define KVM_ARM_VCPU_PMU_V3_CTRL 0 +#define KVM_ARM_VCPU_PMU_V3_IRQ 0 +#define KVM_ARM_VCPU_PMU_V3_INIT 1 +#define KVM_ARM_VCPU_TIMER_CTRL 1 +#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 +#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 + #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 #define KVM_DEV_ARM_ITS_SAVE_TABLES 1 #define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 70eea2ecc6631cab3d718c3958cd0513a7f7e6a3..9f3ca24bbcc6c28da8e1fbaf0d97998c11e93261 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -232,6 +232,9 @@ struct kvm_arch_memory_slot { #define KVM_ARM_VCPU_PMU_V3_CTRL 0 #define KVM_ARM_VCPU_PMU_V3_IRQ 0 #define KVM_ARM_VCPU_PMU_V3_INIT 1 +#define KVM_ARM_VCPU_TIMER_CTRL 1 +#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 +#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 diff --git a/tools/arch/parisc/include/uapi/asm/mman.h b/tools/arch/parisc/include/uapi/asm/mman.h index 03d8d5b7ae7f4ff35ef033ca71f034f8b5868040..286c0bd7457349182e2facab487d8e3ebb54a143 100644 --- a/tools/arch/parisc/include/uapi/asm/mman.h +++ b/tools/arch/parisc/include/uapi/asm/mman.h @@ -36,9 +36,7 @@ #define PROT_READ 0x1 #define PROT_SEM 0x8 #define PROT_WRITE 0x2 -/* MADV_HWPOISON is undefined on parisc, fix it for perf */ #define MADV_HWPOISON 100 -/* MADV_SOFT_OFFLINE is undefined on parisc, fix it for perf */ #define MADV_SOFT_OFFLINE 101 /* MAP_32BIT is undefined on parisc, fix it for perf */ #define MAP_32BIT 0 diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h index 07fbeb927834f3a96278414aedaa59ea580ae8de..8cf8f0c96906dcb3e213524d733bc6a5aa584885 100644 --- a/tools/arch/powerpc/include/uapi/asm/kvm.h +++ b/tools/arch/powerpc/include/uapi/asm/kvm.h @@ -60,6 +60,12 @@ struct kvm_regs { #define KVM_SREGS_E_FSL_PIDn (1 << 0) /* PID1/PID2 */ +/* flags for kvm_run.flags */ +#define KVM_RUN_PPC_NMI_DISP_MASK (3 << 0) +#define KVM_RUN_PPC_NMI_DISP_FULLY_RECOV (1 << 0) +#define KVM_RUN_PPC_NMI_DISP_LIMITED_RECOV (2 << 0) +#define KVM_RUN_PPC_NMI_DISP_NOT_RECOV (3 << 0) + /* * Feature bits indicate which sections of the sregs struct are valid, * both in KVM_GET_SREGS and KVM_SET_SREGS. On KVM_SET_SREGS, registers diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h index 3dd2a1d308dd0b92c36c3c5ca5276fd19838f252..cd7359e23d869465d1cb70b637c64c85283e37ac 100644 --- a/tools/arch/s390/include/uapi/asm/kvm.h +++ b/tools/arch/s390/include/uapi/asm/kvm.h @@ -28,6 +28,7 @@ #define KVM_DEV_FLIC_CLEAR_IO_IRQ 8 #define KVM_DEV_FLIC_AISM 9 #define KVM_DEV_FLIC_AIRQ_INJECT 10 +#define KVM_DEV_FLIC_AISM_ALL 11 /* * We can have up to 4*64k pending subchannels + 8 adapter interrupts, * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. @@ -53,6 +54,11 @@ struct kvm_s390_ais_req { __u16 mode; }; +struct kvm_s390_ais_all { + __u8 simm; + __u8 nimm; +}; + #define KVM_S390_IO_ADAPTER_MASK 1 #define KVM_S390_IO_ADAPTER_MAP 2 #define KVM_S390_IO_ADAPTER_UNMAP 3 @@ -70,6 +76,7 @@ struct kvm_s390_io_adapter_req { #define KVM_S390_VM_TOD 1 #define KVM_S390_VM_CRYPTO 2 #define KVM_S390_VM_CPU_MODEL 3 +#define KVM_S390_VM_MIGRATION 4 /* kvm attributes for mem_ctrl */ #define KVM_S390_VM_MEM_ENABLE_CMMA 0 @@ -81,6 +88,12 @@ struct kvm_s390_io_adapter_req { /* kvm attributes for KVM_S390_VM_TOD */ #define KVM_S390_VM_TOD_LOW 0 #define KVM_S390_VM_TOD_HIGH 1 +#define KVM_S390_VM_TOD_EXT 2 + +struct kvm_s390_vm_tod_clock { + __u8 epoch_idx; + __u64 tod; +}; /* kvm attributes for KVM_S390_VM_CPU_MODEL */ /* processor related attributes are r/w */ @@ -151,6 +164,11 @@ struct kvm_s390_vm_cpu_subfunc { #define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2 #define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3 +/* kvm attributes for migration mode */ +#define KVM_S390_VM_MIGRATION_STOP 0 +#define KVM_S390_VM_MIGRATION_START 1 +#define KVM_S390_VM_MIGRATION_STATUS 2 + /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { /* general purpose regs for s390 */ diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 2701e5f8145bd250c3a35dc12cab5839e16ff30d..2519c6c801c917d7a30b3826c86679edf18616d5 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -177,7 +177,7 @@ #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ #define X86_FEATURE_PTSC ( 6*32+27) /* performance time-stamp counter */ -#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ +#define X86_FEATURE_PERFCTR_LLC ( 6*32+28) /* Last Level Cache performance counter extensions */ #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ /* @@ -196,6 +196,7 @@ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ @@ -286,6 +287,8 @@ #define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ +#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ +#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h index 5dff775af7cd6456f7177d9ce5888ae78dc6bc10..c10c9128f54e6b7296014a74e7a253a1eedaacd9 100644 --- a/tools/arch/x86/include/asm/disabled-features.h +++ b/tools/arch/x86/include/asm/disabled-features.h @@ -21,11 +21,13 @@ # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) +# define DISABLE_PCID 0 #else # define DISABLE_VME 0 # define DISABLE_K6_MTRR 0 # define DISABLE_CYRIX_ARR 0 # define DISABLE_CENTAUR_MCR 0 +# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31)) #endif /* CONFIG_X86_64 */ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS @@ -49,7 +51,7 @@ #define DISABLED_MASK1 0 #define DISABLED_MASK2 0 #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) -#define DISABLED_MASK4 0 +#define DISABLED_MASK4 (DISABLE_PCID) #define DISABLED_MASK5 0 #define DISABLED_MASK6 0 #define DISABLED_MASK7 0 diff --git a/tools/arch/x86/include/asm/unistd_32.h b/tools/arch/x86/include/asm/unistd_32.h index 88b3f8c8920cac566838d1443e40d49b52e612df..0e4312ffc945e3d23e3f2c161cc7ca3e0d55185b 100644 --- a/tools/arch/x86/include/asm/unistd_32.h +++ b/tools/arch/x86/include/asm/unistd_32.h @@ -10,3 +10,6 @@ #ifndef __NR_getcpu # define __NR_getcpu 318 #endif +#ifndef __NR_setns +# define __NR_setns 346 +#endif diff --git a/tools/arch/x86/include/asm/unistd_64.h b/tools/arch/x86/include/asm/unistd_64.h index fbdb70ee8837ef1ec34b9aff174faf9efe87de07..dd56bb36132a58f72ccc025db500a1523d703f5c 100644 --- a/tools/arch/x86/include/asm/unistd_64.h +++ b/tools/arch/x86/include/asm/unistd_64.h @@ -10,3 +10,6 @@ #ifndef __NR_getcpu # define __NR_getcpu 309 #endif +#ifndef __NR_setns +#define __NR_setns 308 +#endif diff --git a/tools/arch/x86/include/uapi/asm/unistd.h b/tools/arch/x86/include/uapi/asm/unistd.h new file mode 100644 index 0000000000000000000000000000000000000000..a26df0d75cd059294822dcea96180270c7654383 --- /dev/null +++ b/tools/arch/x86/include/uapi/asm/unistd.h @@ -0,0 +1,17 @@ +#ifndef _UAPI_ASM_X86_UNISTD_H +#define _UAPI_ASM_X86_UNISTD_H + +/* x32 syscall flag bit */ +#define __X32_SYSCALL_BIT 0x40000000 + +#ifndef __KERNEL__ +# ifdef __i386__ +# include +# elif defined(__ILP32__) +# include +# else +# include +# endif +#endif + +#endif /* _UAPI_ASM_X86_UNISTD_H */ diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 523911f316ce5e65511962f0c13fe0032a06427a..c71a05b9c984f8b38dda2f201caf90ae15fcef52 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -64,7 +64,8 @@ FEATURE_TESTS_BASIC := \ get_cpuid \ bpf \ sched_getcpu \ - sdt + sdt \ + setns # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list # of all feature tests diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index e35e4e5ad192e6126404b4f5ee52e397e2bb22db..ee2546ddf02831c587ef1d217c69a3d17b140705 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -49,7 +49,8 @@ FILES= \ test-sdt.bin \ test-cxx.bin \ test-jvmti.bin \ - test-sched_getcpu.bin + test-sched_getcpu.bin \ + test-setns.bin FILES := $(addprefix $(OUTPUT),$(FILES)) @@ -95,6 +96,9 @@ $(OUTPUT)test-glibc.bin: $(OUTPUT)test-sched_getcpu.bin: $(BUILD) +$(OUTPUT)test-setns.bin: + $(BUILD) + DWARFLIBS := -ldw ifeq ($(findstring -static,${LDFLAGS}),-static) DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index cc6c7c01f4cadd5f8fe28ced947b9c80a2a0515d..b5cfc64457716f0c6eeda10db2d5c1a916f73395 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -153,6 +153,10 @@ # include "test-sdt.c" #undef main +#define main main_test_setns +# include "test-setns.c" +#undef main + int main(int argc, char *argv[]) { main_test_libpython(); @@ -188,6 +192,7 @@ int main(int argc, char *argv[]) main_test_libcrypto(); main_test_sched_getcpu(); main_test_sdt(); + main_test_setns(); return 0; } diff --git a/tools/build/feature/test-bpf.c b/tools/build/feature/test-bpf.c index 7598361ef1f10898ea73d944ae0b0c02c4725d99..da2172ff9662d0e86ffd132b6041b30ea232eb87 100644 --- a/tools/build/feature/test-bpf.c +++ b/tools/build/feature/test-bpf.c @@ -11,6 +11,8 @@ # define __NR_bpf 280 # elif defined(__sparc__) # define __NR_bpf 349 +# elif defined(__s390__) +# define __NR_bpf 351 # else # error __NR_bpf not defined. libbpf does not support your arch. # endif diff --git a/tools/build/feature/test-setns.c b/tools/build/feature/test-setns.c new file mode 100644 index 0000000000000000000000000000000000000000..1f714d2a658b11cd3c88926df7b271e9737e5989 --- /dev/null +++ b/tools/build/feature/test-setns.c @@ -0,0 +1,7 @@ +#define _GNU_SOURCE +#include + +int main(void) +{ + return setns(0, 0); +} diff --git a/tools/build/tests/ex/Makefile b/tools/build/tests/ex/Makefile index c50d5782ad5a967472a75f84a9d3a81fee19eecf..027d6c8a58a7400042102bd1b1874e67ab81db87 100644 --- a/tools/build/tests/ex/Makefile +++ b/tools/build/tests/ex/Makefile @@ -8,7 +8,7 @@ ex: include $(srctree)/tools/build/Makefile.include ex: ex-in.o libex-in.o - gcc -o $@ $^ + $(CC) -o $@ $^ ex.%: fixdep FORCE make -f $(srctree)/tools/build/Makefile.build dir=. $@ diff --git a/tools/hv/bondvf.sh b/tools/hv/bondvf.sh deleted file mode 100755 index 89b25068cd98775d9f10f3cb409012034b34ed3e..0000000000000000000000000000000000000000 --- a/tools/hv/bondvf.sh +++ /dev/null @@ -1,232 +0,0 @@ -#!/bin/bash - -# This example script creates bonding network devices based on synthetic NIC -# (the virtual network adapter usually provided by Hyper-V) and the matching -# VF NIC (SRIOV virtual function). So the synthetic NIC and VF NIC can -# function as one network device, and fail over to the synthetic NIC if VF is -# down. -# -# Usage: -# - After configured vSwitch and vNIC with SRIOV, start Linux virtual -# machine (VM) -# - Run this scripts on the VM. It will create configuration files in -# distro specific directory. -# - Reboot the VM, so that the bonding config are enabled. -# -# The config files are DHCP by default. You may edit them if you need to change -# to Static IP or change other settings. -# - -sysdir=/sys/class/net -netvsc_cls={f8615163-df3e-46c5-913f-f2d2f965ed0e} -bondcnt=0 - -# Detect Distro -if [ -f /etc/redhat-release ]; -then - cfgdir=/etc/sysconfig/network-scripts - distro=redhat -elif grep -q 'Ubuntu' /etc/issue -then - cfgdir=/etc/network - distro=ubuntu -elif grep -q 'SUSE' /etc/issue -then - cfgdir=/etc/sysconfig/network - distro=suse -else - echo "Unsupported Distro" - exit 1 -fi - -echo Detected Distro: $distro, or compatible - -# Get a list of ethernet names -list_eth=(`cd $sysdir && ls -d */ | cut -d/ -f1 | grep -v bond`) -eth_cnt=${#list_eth[@]} - -echo List of net devices: - -# Get the MAC addresses -for (( i=0; i < $eth_cnt; i++ )) -do - list_mac[$i]=`cat $sysdir/${list_eth[$i]}/address` - echo ${list_eth[$i]}, ${list_mac[$i]} -done - -# Find NIC with matching MAC -for (( i=0; i < $eth_cnt-1; i++ )) -do - for (( j=i+1; j < $eth_cnt; j++ )) - do - if [ "${list_mac[$i]}" = "${list_mac[$j]}" ] - then - list_match[$i]=${list_eth[$j]} - break - fi - done -done - -function create_eth_cfg_redhat { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo DEVICE=$1 >>$fn - echo TYPE=Ethernet >>$fn - echo BOOTPROTO=none >>$fn - echo UUID=`uuidgen` >>$fn - echo ONBOOT=yes >>$fn - echo PEERDNS=yes >>$fn - echo IPV6INIT=yes >>$fn - echo MASTER=$2 >>$fn - echo SLAVE=yes >>$fn -} - -function create_eth_cfg_pri_redhat { - create_eth_cfg_redhat $1 $2 -} - -function create_bond_cfg_redhat { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo DEVICE=$1 >>$fn - echo TYPE=Bond >>$fn - echo BOOTPROTO=dhcp >>$fn - echo UUID=`uuidgen` >>$fn - echo ONBOOT=yes >>$fn - echo PEERDNS=yes >>$fn - echo IPV6INIT=yes >>$fn - echo BONDING_MASTER=yes >>$fn - echo BONDING_OPTS=\"mode=active-backup miimon=100 primary=$2\" >>$fn -} - -function del_eth_cfg_ubuntu { - local mainfn=$cfgdir/interfaces - local fnlist=( $mainfn ) - - local dirlist=(`awk '/^[ \t]*source/{print $2}' $mainfn`) - - local i - for i in "${dirlist[@]}" - do - fnlist+=(`ls $i 2>/dev/null`) - done - - local tmpfl=$(mktemp) - - local nic_start='^[ \t]*(auto|iface|mapping|allow-.*)[ \t]+'$1 - local nic_end='^[ \t]*(auto|iface|mapping|allow-.*|source)' - - local fn - for fn in "${fnlist[@]}" - do - awk "/$nic_end/{x=0} x{next} /$nic_start/{x=1;next} 1" \ - $fn >$tmpfl - - cp $tmpfl $fn - done - - rm $tmpfl -} - -function create_eth_cfg_ubuntu { - local fn=$cfgdir/interfaces - - del_eth_cfg_ubuntu $1 - echo $'\n'auto $1 >>$fn - echo iface $1 inet manual >>$fn - echo bond-master $2 >>$fn -} - -function create_eth_cfg_pri_ubuntu { - local fn=$cfgdir/interfaces - - del_eth_cfg_ubuntu $1 - echo $'\n'allow-hotplug $1 >>$fn - echo iface $1 inet manual >>$fn - echo bond-master $2 >>$fn - echo bond-primary $1 >>$fn -} - -function create_bond_cfg_ubuntu { - local fn=$cfgdir/interfaces - - del_eth_cfg_ubuntu $1 - - echo $'\n'auto $1 >>$fn - echo iface $1 inet dhcp >>$fn - echo bond-mode active-backup >>$fn - echo bond-miimon 100 >>$fn - echo bond-slaves none >>$fn -} - -function create_eth_cfg_suse { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo BOOTPROTO=none >>$fn - echo STARTMODE=auto >>$fn -} - -function create_eth_cfg_pri_suse { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo BOOTPROTO=none >>$fn - echo STARTMODE=hotplug >>$fn -} - -function create_bond_cfg_suse { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo BOOTPROTO=dhcp >>$fn - echo STARTMODE=auto >>$fn - echo BONDING_MASTER=yes >>$fn - echo BONDING_SLAVE_0=$2 >>$fn - echo BONDING_SLAVE_1=$3 >>$fn - echo BONDING_MODULE_OPTS=\'mode=active-backup miimon=100 primary=$2\' >>$fn -} - -function create_bond { - local bondname=bond$bondcnt - local primary - local secondary - - local class_id1=`cat $sysdir/$1/device/class_id 2>/dev/null` - local class_id2=`cat $sysdir/$2/device/class_id 2>/dev/null` - - if [ "$class_id1" = "$netvsc_cls" ] - then - primary=$2 - secondary=$1 - elif [ "$class_id2" = "$netvsc_cls" ] - then - primary=$1 - secondary=$2 - else - return 0 - fi - - echo $'\nBond name:' $bondname - - echo configuring $primary - create_eth_cfg_pri_$distro $primary $bondname - - echo configuring $secondary - create_eth_cfg_$distro $secondary $bondname - - echo creating: $bondname with primary slave: $primary - create_bond_cfg_$distro $bondname $primary $secondary - - let bondcnt=bondcnt+1 -} - -for (( i=0; i < $eth_cnt-1; i++ )) -do - if [ -n "${list_match[$i]}" ] - then - create_bond ${list_eth[$i]} ${list_match[$i]} - fi -done diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c index 26ae609a94488b1059515dfcb059c3aa3d3af41a..457a1521f32fe6cc6cb3493cdde8105c187c0d44 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -138,14 +138,17 @@ void print_usage(char *argv[]) int main(int argc, char *argv[]) { - int fcopy_fd, len; + int fcopy_fd; int error; int daemonize = 1, long_index = 0, opt; int version = FCOPY_CURRENT_VERSION; - char *buffer[4096 * 2]; - struct hv_fcopy_hdr *in_msg; + union { + struct hv_fcopy_hdr hdr; + struct hv_start_fcopy start; + struct hv_do_fcopy copy; + __u32 kernel_modver; + } buffer = { }; int in_handshake = 1; - __u32 kernel_modver; static struct option long_options[] = { {"help", no_argument, 0, 'h' }, @@ -195,32 +198,31 @@ int main(int argc, char *argv[]) * In this loop we process fcopy messages after the * handshake is complete. */ - len = pread(fcopy_fd, buffer, (4096 * 2), 0); + ssize_t len; + + len = pread(fcopy_fd, &buffer, sizeof(buffer), 0); if (len < 0) { syslog(LOG_ERR, "pread failed: %s", strerror(errno)); exit(EXIT_FAILURE); } if (in_handshake) { - if (len != sizeof(kernel_modver)) { + if (len != sizeof(buffer.kernel_modver)) { syslog(LOG_ERR, "invalid version negotiation"); exit(EXIT_FAILURE); } - kernel_modver = *(__u32 *)buffer; in_handshake = 0; - syslog(LOG_INFO, "kernel module version: %d", - kernel_modver); + syslog(LOG_INFO, "kernel module version: %u", + buffer.kernel_modver); continue; } - in_msg = (struct hv_fcopy_hdr *)buffer; - - switch (in_msg->operation) { + switch (buffer.hdr.operation) { case START_FILE_COPY: - error = hv_start_fcopy((struct hv_start_fcopy *)in_msg); + error = hv_start_fcopy(&buffer.start); break; case WRITE_TO_FILE: - error = hv_copy_data((struct hv_do_fcopy *)in_msg); + error = hv_copy_data(&buffer.copy); break; case COMPLETE_FCOPY: error = hv_copy_finished(); @@ -231,7 +233,7 @@ int main(int argc, char *argv[]) default: syslog(LOG_ERR, "Unknown operation: %d", - in_msg->operation); + buffer.hdr.operation); } diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 88b20e007c05d58291dcbc675a1519a72893143c..eaa3bec273c8e21fcb15fbf5ee0407017b12c036 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -1136,7 +1136,7 @@ static int process_ip_string(FILE *f, char *ip_string, int type) int i = 0; int j = 0; char str[256]; - char sub_str[10]; + char sub_str[13]; int offset = 0; memset(addr, 0, sizeof(addr)); diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 7ba54195934c9aba4083b28b2ea02ce2b2c456db..b2b4ebffab8ca491cb31f47c52c2e8406a546328 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +72,7 @@ static int vss_operate(int operation) char match[] = "/dev/"; FILE *mounts; struct mntent *ent; + struct stat sb; char errdir[1024] = {0}; unsigned int cmd; int error = 0, root_seen = 0, save_errno = 0; @@ -92,6 +95,10 @@ static int vss_operate(int operation) while ((ent = getmntent(mounts))) { if (strncmp(ent->mnt_fsname, match, strlen(match))) continue; + if (stat(ent->mnt_fsname, &sb) == -1) + continue; + if (S_ISBLK(sb.st_mode) && major(sb.st_rdev) == LOOP_MAJOR) + continue; if (hasmntopt(ent, MNTOPT_RO) != NULL) continue; if (strcmp(ent->mnt_type, "vfat") == 0) diff --git a/tools/iio/Build b/tools/iio/Build new file mode 100644 index 0000000000000000000000000000000000000000..f74cbda647100c7606d77a6a09765042e1ca0326 --- /dev/null +++ b/tools/iio/Build @@ -0,0 +1,3 @@ +lsiio-y += lsiio.o iio_utils.o +iio_event_monitor-y += iio_event_monitor.o iio_utils.o +iio_generic_buffer-y += iio_generic_buffer.o iio_utils.o diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 8f08e03a9a5ecab158aa51e2c3493909d8c05b3c..d4d956020adf5ec92067269bdedb79ce7da75402 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -1,31 +1,67 @@ +include ../scripts/Makefile.include + +bindir ?= /usr/bin + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +# Do not use make's built-in rules +# (this improves performance and avoids hard-to-debug behaviour); +MAKEFLAGS += -r + CC = $(CROSS_COMPILE)gcc -CFLAGS += -Wall -g -D_GNU_SOURCE -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include +LD = $(CROSS_COMPILE)ld +CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include -BINDIR=usr/bin -INSTALL_PROGRAM=install -m 755 -p -DEL_FILE=rm -f +ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer +ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) -all: iio_event_monitor lsiio iio_generic_buffer +all: $(ALL_PROGRAMS) -iio_event_monitor: iio_event_monitor.o iio_utils.o +export srctree OUTPUT CC LD CFLAGS +include $(srctree)/tools/build/Makefile.include -lsiio: lsiio.o iio_utils.o +# +# We need the following to be outside of kernel tree +# +$(OUTPUT)include/linux/iio: ../../include/uapi/linux/iio + mkdir -p $(OUTPUT)include/linux/iio 2>&1 || true + ln -sf $(CURDIR)/../../include/uapi/linux/iio/events.h $@ + ln -sf $(CURDIR)/../../include/uapi/linux/iio/types.h $@ -iio_generic_buffer: iio_generic_buffer.o iio_utils.o +prepare: $(OUTPUT)include/linux/iio -%.o: %.c iio_utils.h +LSIIO_IN := $(OUTPUT)lsiio-in.o +$(LSIIO_IN): prepare FORCE + $(Q)$(MAKE) $(build)=lsiio +$(OUTPUT)lsiio: $(LSIIO_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -install: - - mkdir -p $(INSTALL_ROOT)/$(BINDIR) - - $(INSTALL_PROGRAM) "iio_event_monitor" "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor" - - $(INSTALL_PROGRAM) "lsiio" "$(INSTALL_ROOT)/$(BINDIR)/lsiio" - - $(INSTALL_PROGRAM) "iio_generic_buffer" "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer" +IIO_EVENT_MONITOR_IN := $(OUTPUT)iio_event_monitor-in.o +$(IIO_EVENT_MONITOR_IN): prepare FORCE + $(Q)$(MAKE) $(build)=iio_event_monitor +$(OUTPUT)iio_event_monitor: $(IIO_EVENT_MONITOR_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -uninstall: - $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor" - $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/lsiio" - $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer" +IIO_GENERIC_BUFFER_IN := $(OUTPUT)iio_generic_buffer-in.o +$(IIO_GENERIC_BUFFER_IN): prepare FORCE + $(Q)$(MAKE) $(build)=iio_generic_buffer +$(OUTPUT)iio_generic_buffer: $(IIO_GENERIC_BUFFER_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -.PHONY: clean clean: - rm -f *.o iio_event_monitor lsiio iio_generic_buffer + rm -f $(ALL_PROGRAMS) + rm -rf $(OUTPUT)include/linux/iio + find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + +install: $(ALL_PROGRAMS) + install -d -m 755 $(DESTDIR)$(bindir); \ + for program in $(ALL_PROGRAMS); do \ + install $$program $(DESTDIR)$(bindir); \ + done + +FORCE: + +.PHONY: all install clean FORCE prepare diff --git a/tools/include/asm-generic/hugetlb_encode.h b/tools/include/asm-generic/hugetlb_encode.h new file mode 100644 index 0000000000000000000000000000000000000000..e4732d3c2998264857772faac64409c69ff8e43d --- /dev/null +++ b/tools/include/asm-generic/hugetlb_encode.h @@ -0,0 +1,34 @@ +#ifndef _ASM_GENERIC_HUGETLB_ENCODE_H_ +#define _ASM_GENERIC_HUGETLB_ENCODE_H_ + +/* + * Several system calls take a flag to request "hugetlb" huge pages. + * Without further specification, these system calls will use the + * system's default huge page size. If a system supports multiple + * huge page sizes, the desired huge page size can be specified in + * bits [26:31] of the flag arguments. The value in these 6 bits + * will encode the log2 of the huge page size. + * + * The following definitions are associated with this huge page size + * encoding in flag arguments. System call specific header files + * that use this encoding should include this file. They can then + * provide definitions based on these with their own specific prefix. + * for example: + * #define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT + */ + +#define HUGETLB_FLAG_ENCODE_SHIFT 26 +#define HUGETLB_FLAG_ENCODE_MASK 0x3f + +#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT) + +#endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */ diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h index bd39b2090ad1ba226112fcd74bf46ca15406912a..3723b9f8f964365d768ea163c0b3ea87e9be69ca 100644 --- a/tools/include/linux/compiler-gcc.h +++ b/tools/include/linux/compiler-gcc.h @@ -21,11 +21,14 @@ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) #define noinline __attribute__((noinline)) - +#ifndef __packed #define __packed __attribute__((packed)) - +#endif +#ifndef __noreturn #define __noreturn __attribute__((noreturn)) - +#endif +#ifndef __aligned #define __aligned(x) __attribute__((aligned(x))) +#endif #define __printf(a, b) __attribute__((format(printf, a, b))) #define __scanf(a, b) __attribute__((format(scanf, a, b))) diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h index 7d410260661bf0794fb9d9e9b9cb5df8b63bf51e..edfeaba954295a76c1c842253004404365436208 100644 --- a/tools/include/linux/coresight-pmu.h +++ b/tools/include/linux/coresight-pmu.h @@ -24,6 +24,12 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 + +/* ETMv4 CONFIGR programming bits for the ETM OPTs */ +#define ETM4_CFG_BIT_CYCACC 4 +#define ETM4_CFG_BIT_TS 11 +#define ETM4_CFG_BIT_RETSTK 12 static inline int coresight_get_trace_id(int cpu) { diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index d62b56cf8c12eedcdda935bc1180c4b4b70270b9..a30fad536f52080a8d6351f258858a89fa61f927 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -1,8 +1,8 @@ #ifndef _TOOLS_LINUX_STRING_H_ #define _TOOLS_LINUX_STRING_H_ - #include /* for size_t */ +#include void *memdup(const void *src, size_t len); @@ -18,6 +18,14 @@ extern size_t strlcpy(char *dest, const char *src, size_t size); char *str_error_r(int errnum, char *buf, size_t buflen); -int prefixcmp(const char *str, const char *prefix); +/** + * strstarts - does @str start with @prefix? + * @str: string to examine + * @prefix: prefix to look for. + */ +static inline bool strstarts(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} #endif /* _LINUX_STRING_H_ */ diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h new file mode 100644 index 0000000000000000000000000000000000000000..ac190958c981442f1c2072097487705039c8706b --- /dev/null +++ b/tools/include/uapi/asm-generic/fcntl.h @@ -0,0 +1,220 @@ +#ifndef _ASM_GENERIC_FCNTL_H +#define _ASM_GENERIC_FCNTL_H + +#include + +/* + * FMODE_EXEC is 0x20 + * FMODE_NONOTIFY is 0x4000000 + * These cannot be used by userspace O_* until internal and external open + * flags are split. + * -Eric Paris + */ + +/* + * When introducing new O_* bits, please check its uniqueness in fcntl_init(). + */ + +#define O_ACCMODE 00000003 +#define O_RDONLY 00000000 +#define O_WRONLY 00000001 +#define O_RDWR 00000002 +#ifndef O_CREAT +#define O_CREAT 00000100 /* not fcntl */ +#endif +#ifndef O_EXCL +#define O_EXCL 00000200 /* not fcntl */ +#endif +#ifndef O_NOCTTY +#define O_NOCTTY 00000400 /* not fcntl */ +#endif +#ifndef O_TRUNC +#define O_TRUNC 00001000 /* not fcntl */ +#endif +#ifndef O_APPEND +#define O_APPEND 00002000 +#endif +#ifndef O_NONBLOCK +#define O_NONBLOCK 00004000 +#endif +#ifndef O_DSYNC +#define O_DSYNC 00010000 /* used to be O_SYNC, see below */ +#endif +#ifndef FASYNC +#define FASYNC 00020000 /* fcntl, for BSD compatibility */ +#endif +#ifndef O_DIRECT +#define O_DIRECT 00040000 /* direct disk access hint */ +#endif +#ifndef O_LARGEFILE +#define O_LARGEFILE 00100000 +#endif +#ifndef O_DIRECTORY +#define O_DIRECTORY 00200000 /* must be a directory */ +#endif +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 00400000 /* don't follow links */ +#endif +#ifndef O_NOATIME +#define O_NOATIME 01000000 +#endif +#ifndef O_CLOEXEC +#define O_CLOEXEC 02000000 /* set close_on_exec */ +#endif + +/* + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * the O_SYNC flag. We continue to use the existing numerical value + * for O_DSYNC semantics now, but using the correct symbolic name for it. + * This new value is used to request true Posix O_SYNC semantics. It is + * defined in this strange way to make sure applications compiled against + * new headers get at least O_DSYNC semantics on older kernels. + * + * This has the nice side-effect that we can simply test for O_DSYNC + * wherever we do not care if O_DSYNC or O_SYNC is used. + * + * Note: __O_SYNC must never be used directly. + */ +#ifndef O_SYNC +#define __O_SYNC 04000000 +#define O_SYNC (__O_SYNC|O_DSYNC) +#endif + +#ifndef O_PATH +#define O_PATH 010000000 +#endif + +#ifndef __O_TMPFILE +#define __O_TMPFILE 020000000 +#endif + +/* a horrid kludge trying to make sure that this will fail on old kernels */ +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) + +#ifndef O_NDELAY +#define O_NDELAY O_NONBLOCK +#endif + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#ifndef F_GETLK +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 +#endif +#ifndef F_SETOWN +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ +#endif +#ifndef F_SETSIG +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ +#endif + +#ifndef CONFIG_64BIT +#ifndef F_GETLK64 +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 +#endif +#endif + +#ifndef F_SETOWN_EX +#define F_SETOWN_EX 15 +#define F_GETOWN_EX 16 +#endif + +#ifndef F_GETOWNER_UIDS +#define F_GETOWNER_UIDS 17 +#endif + +/* + * Open File Description Locks + * + * Usually record locks held by a process are released on *any* close and are + * not inherited across a fork(). + * + * These cmd values will set locks that conflict with process-associated + * record locks, but are "owned" by the open file description, not the + * process. This means that they are inherited across fork() like BSD (flock) + * locks, and they are only released automatically when the last reference to + * the the open file against which they were acquired is put. + */ +#define F_OFD_GETLK 36 +#define F_OFD_SETLK 37 +#define F_OFD_SETLKW 38 + +#define F_OWNER_TID 0 +#define F_OWNER_PID 1 +#define F_OWNER_PGRP 2 + +struct f_owner_ex { + int type; + __kernel_pid_t pid; +}; + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#ifndef F_RDLCK +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 +#endif + +/* for old implementation of bsd flock () */ +#ifndef F_EXLCK +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ +#endif + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#define LOCK_MAND 32 /* This is a mandatory flock ... */ +#define LOCK_READ 64 /* which allows concurrent read operations */ +#define LOCK_WRITE 128 /* which allows concurrent write operations */ +#define LOCK_RW 192 /* which allows concurrent read & write ops */ + +#define F_LINUX_SPECIFIC_BASE 1024 + +#ifndef HAVE_ARCH_STRUCT_FLOCK +#ifndef __ARCH_FLOCK_PAD +#define __ARCH_FLOCK_PAD +#endif + +struct flock { + short l_type; + short l_whence; + __kernel_off_t l_start; + __kernel_off_t l_len; + __kernel_pid_t l_pid; + __ARCH_FLOCK_PAD +}; +#endif + +#ifndef HAVE_ARCH_STRUCT_FLOCK64 +#ifndef __ARCH_FLOCK64_PAD +#define __ARCH_FLOCK64_PAD +#endif + +struct flock64 { + short l_type; + short l_whence; + __kernel_loff_t l_start; + __kernel_loff_t l_len; + __kernel_pid_t l_pid; + __ARCH_FLOCK64_PAD +}; +#endif + +#endif /* _ASM_GENERIC_FCNTL_H */ diff --git a/tools/include/uapi/asm-generic/ioctls.h b/tools/include/uapi/asm-generic/ioctls.h new file mode 100644 index 0000000000000000000000000000000000000000..14baf9f23a14b952e76e9d4aaa7030e53e5092ed --- /dev/null +++ b/tools/include/uapi/asm-generic/ioctls.h @@ -0,0 +1,118 @@ +#ifndef __ASM_GENERIC_IOCTLS_H +#define __ASM_GENERIC_IOCTLS_H + +#include + +/* + * These are the most common definitions for tty ioctl numbers. + * Most of them do not use the recommended _IOC(), but there is + * probably some source code out there hardcoding the number, + * so we might as well use them for all new platforms. + * + * The architectures that use different values here typically + * try to be compatible with some Unix variants for the same + * architecture. + */ + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TCGETS2 _IOR('T', 0x2A, struct termios2) +#define TCSETS2 _IOW('T', 0x2B, struct termios2) +#define TCSETSW2 _IOW('T', 0x2C, struct termios2) +#define TCSETSF2 _IOW('T', 0x2D, struct termios2) +#define TIOCGRS485 0x542E +#ifndef TIOCSRS485 +#define TIOCSRS485 0x542F +#endif +#define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ +#define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ +#define TCGETX 0x5432 /* SYS5 TCGETX compatibility */ +#define TCSETX 0x5433 +#define TCSETXF 0x5434 +#define TCSETXW 0x5435 +#define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ +#define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ + +#define FIONCLEX 0x5450 +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* + * Some arches already define FIOQSIZE due to a historical + * conflict with a Hayes modem-specific ioctl value. + */ +#ifndef FIOQSIZE +# define FIOQSIZE 0x5460 +#endif + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ASM_GENERIC_IOCTLS_H */ diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h index 8c27db0c5c08ce84fc7299bd9bff2cee571b9397..203268f9231e155d72307995989feab4857defe7 100644 --- a/tools/include/uapi/asm-generic/mman-common.h +++ b/tools/include/uapi/asm-generic/mman-common.h @@ -58,20 +58,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h new file mode 100644 index 0000000000000000000000000000000000000000..97677cd6964db099689f96f11b9731c748bebcfa --- /dev/null +++ b/tools/include/uapi/drm/drm.h @@ -0,0 +1,955 @@ +/** + * \file drm.h + * Header for the Direct Rendering Manager + * + * \author Rickard E. (Rik) Faith + * + * \par Acknowledgments: + * Dec 1999, Richard Henderson , move to generic \c cmpxchg. + */ + +/* + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_H_ +#define _DRM_H_ + +#if defined(__KERNEL__) + +#include +#include +typedef unsigned int drm_handle_t; + +#elif defined(__linux__) + +#include +#include +typedef unsigned int drm_handle_t; + +#else /* One of the BSDs */ + +#include +#include +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; +typedef size_t __kernel_size_t; +typedef unsigned long drm_handle_t; + +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ +#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ +#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ +#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ + +#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ +#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ +#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) +#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) +#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) + +typedef unsigned int drm_context_t; +typedef unsigned int drm_drawable_t; +typedef unsigned int drm_magic_t; + +/** + * Cliprect. + * + * \warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well + * + * \note KW: Actually it's illegal to change either for + * backwards-compatibility reasons. + */ +struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +}; + +/** + * Drawable information. + */ +struct drm_drawable_info { + unsigned int num_rects; + struct drm_clip_rect *rects; +}; + +/** + * Texture region, + */ +struct drm_tex_region { + unsigned char next; + unsigned char prev; + unsigned char in_use; + unsigned char padding; + unsigned int age; +}; + +/** + * Hardware lock. + * + * The lock structure is a simple cache-line aligned integer. To avoid + * processor bus contention on a multiprocessor system, there should not be any + * other data stored in the same cache line. + */ +struct drm_hw_lock { + __volatile__ unsigned int lock; /**< lock variable */ + char padding[60]; /**< Pad to cache line */ +}; + +/** + * DRM_IOCTL_VERSION ioctl argument type. + * + * \sa drmGetVersion(). + */ +struct drm_version { + int version_major; /**< Major version */ + int version_minor; /**< Minor version */ + int version_patchlevel; /**< Patch level */ + __kernel_size_t name_len; /**< Length of name buffer */ + char __user *name; /**< Name of driver */ + __kernel_size_t date_len; /**< Length of date buffer */ + char __user *date; /**< User-space buffer to hold date */ + __kernel_size_t desc_len; /**< Length of desc buffer */ + char __user *desc; /**< User-space buffer to hold desc */ +}; + +/** + * DRM_IOCTL_GET_UNIQUE ioctl argument type. + * + * \sa drmGetBusid() and drmSetBusId(). + */ +struct drm_unique { + __kernel_size_t unique_len; /**< Length of unique */ + char __user *unique; /**< Unique name for driver instantiation */ +}; + +struct drm_list { + int count; /**< Length of user-space structures */ + struct drm_version __user *version; +}; + +struct drm_block { + int unused; +}; + +/** + * DRM_IOCTL_CONTROL ioctl argument type. + * + * \sa drmCtlInstHandler() and drmCtlUninstHandler(). + */ +struct drm_control { + enum { + DRM_ADD_COMMAND, + DRM_RM_COMMAND, + DRM_INST_HANDLER, + DRM_UNINST_HANDLER + } func; + int irq; +}; + +/** + * Type of memory to map. + */ +enum drm_map_type { + _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ + _DRM_REGISTERS = 1, /**< no caching, no core dump */ + _DRM_SHM = 2, /**< shared, cached */ + _DRM_AGP = 3, /**< AGP/GART */ + _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ + _DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */ +}; + +/** + * Memory mapping flags. + */ +enum drm_map_flags { + _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ + _DRM_READ_ONLY = 0x02, + _DRM_LOCKED = 0x04, /**< shared, cached, locked */ + _DRM_KERNEL = 0x08, /**< kernel requires access */ + _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ + _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80 /**< Managed by driver */ +}; + +struct drm_ctx_priv_map { + unsigned int ctx_id; /**< Context requesting private mapping */ + void *handle; /**< Handle of map */ +}; + +/** + * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls + * argument type. + * + * \sa drmAddMap(). + */ +struct drm_map { + unsigned long offset; /**< Requested physical address (0 for SAREA)*/ + unsigned long size; /**< Requested physical size (bytes) */ + enum drm_map_type type; /**< Type of memory to map */ + enum drm_map_flags flags; /**< Flags */ + void *handle; /**< User-space: "Handle" to pass to mmap() */ + /**< Kernel-space: kernel-virtual address */ + int mtrr; /**< MTRR slot used */ + /* Private data */ +}; + +/** + * DRM_IOCTL_GET_CLIENT ioctl argument type. + */ +struct drm_client { + int idx; /**< Which client desired? */ + int auth; /**< Is client authenticated? */ + unsigned long pid; /**< Process ID */ + unsigned long uid; /**< User ID */ + unsigned long magic; /**< Magic */ + unsigned long iocs; /**< Ioctl count */ +}; + +enum drm_stat_type { + _DRM_STAT_LOCK, + _DRM_STAT_OPENS, + _DRM_STAT_CLOSES, + _DRM_STAT_IOCTLS, + _DRM_STAT_LOCKS, + _DRM_STAT_UNLOCKS, + _DRM_STAT_VALUE, /**< Generic value */ + _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */ + _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */ + + _DRM_STAT_IRQ, /**< IRQ */ + _DRM_STAT_PRIMARY, /**< Primary DMA bytes */ + _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */ + _DRM_STAT_DMA, /**< DMA */ + _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ + _DRM_STAT_MISSED /**< Missed DMA opportunity */ + /* Add to the *END* of the list */ +}; + +/** + * DRM_IOCTL_GET_STATS ioctl argument type. + */ +struct drm_stats { + unsigned long count; + struct { + unsigned long value; + enum drm_stat_type type; + } data[15]; +}; + +/** + * Hardware locking flags. + */ +enum drm_lock_flags { + _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ + _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ + _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ + _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ + /* These *HALT* flags aren't supported yet + -- they will be used to support the + full-screen DGA-like mode. */ + _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ + _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ +}; + +/** + * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. + * + * \sa drmGetLock() and drmUnlock(). + */ +struct drm_lock { + int context; + enum drm_lock_flags flags; +}; + +/** + * DMA flags + * + * \warning + * These values \e must match xf86drm.h. + * + * \sa drm_dma. + */ +enum drm_dma_flags { + /* Flags for DMA buffer dispatch */ + _DRM_DMA_BLOCK = 0x01, /**< + * Block until buffer dispatched. + * + * \note The buffer may not yet have + * been processed by the hardware -- + * getting a hardware lock with the + * hardware quiescent will ensure + * that the buffer has been + * processed. + */ + _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ + _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ + + /* Flags for DMA buffer request */ + _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ + _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ + _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ +}; + +/** + * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. + * + * \sa drmAddBufs(). + */ +struct drm_buf_desc { + int count; /**< Number of buffers of this size */ + int size; /**< Size in bytes */ + int low_mark; /**< Low water mark */ + int high_mark; /**< High water mark */ + enum { + _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ + _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ + _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ + _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ + _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ + } flags; + unsigned long agp_start; /**< + * Start address of where the AGP buffers are + * in the AGP aperture + */ +}; + +/** + * DRM_IOCTL_INFO_BUFS ioctl argument type. + */ +struct drm_buf_info { + int count; /**< Entries in list */ + struct drm_buf_desc __user *list; +}; + +/** + * DRM_IOCTL_FREE_BUFS ioctl argument type. + */ +struct drm_buf_free { + int count; + int __user *list; +}; + +/** + * Buffer information + * + * \sa drm_buf_map. + */ +struct drm_buf_pub { + int idx; /**< Index into the master buffer list */ + int total; /**< Buffer size */ + int used; /**< Amount of buffer in use (for DMA) */ + void __user *address; /**< Address of buffer */ +}; + +/** + * DRM_IOCTL_MAP_BUFS ioctl argument type. + */ +struct drm_buf_map { + int count; /**< Length of the buffer list */ +#ifdef __cplusplus + void __user *virt; +#else + void __user *virtual; /**< Mmap'd area in user-virtual */ +#endif + struct drm_buf_pub __user *list; /**< Buffer information */ +}; + +/** + * DRM_IOCTL_DMA ioctl argument type. + * + * Indices here refer to the offset into the buffer list in drm_buf_get. + * + * \sa drmDMA(). + */ +struct drm_dma { + int context; /**< Context handle */ + int send_count; /**< Number of buffers to send */ + int __user *send_indices; /**< List of handles to buffers */ + int __user *send_sizes; /**< Lengths of data to send */ + enum drm_dma_flags flags; /**< Flags */ + int request_count; /**< Number of buffers requested */ + int request_size; /**< Desired size for buffers */ + int __user *request_indices; /**< Buffer information */ + int __user *request_sizes; + int granted_count; /**< Number of buffers granted */ +}; + +enum drm_ctx_flags { + _DRM_CONTEXT_PRESERVED = 0x01, + _DRM_CONTEXT_2DONLY = 0x02 +}; + +/** + * DRM_IOCTL_ADD_CTX ioctl argument type. + * + * \sa drmCreateContext() and drmDestroyContext(). + */ +struct drm_ctx { + drm_context_t handle; + enum drm_ctx_flags flags; +}; + +/** + * DRM_IOCTL_RES_CTX ioctl argument type. + */ +struct drm_ctx_res { + int count; + struct drm_ctx __user *contexts; +}; + +/** + * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. + */ +struct drm_draw { + drm_drawable_t handle; +}; + +/** + * DRM_IOCTL_UPDATE_DRAW ioctl argument type. + */ +typedef enum { + DRM_DRAWABLE_CLIPRECTS +} drm_drawable_info_type_t; + +struct drm_update_draw { + drm_drawable_t handle; + unsigned int type; + unsigned int num; + unsigned long long data; +}; + +/** + * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. + */ +struct drm_auth { + drm_magic_t magic; +}; + +/** + * DRM_IOCTL_IRQ_BUSID ioctl argument type. + * + * \sa drmGetInterruptFromBusID(). + */ +struct drm_irq_busid { + int irq; /**< IRQ number */ + int busnum; /**< bus number */ + int devnum; /**< device number */ + int funcnum; /**< function number */ +}; + +enum drm_vblank_seq_type { + _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + /* bits 1-6 are reserved for high crtcs */ + _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e, + _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ + _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ + _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ + _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ + _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */ +}; +#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1 + +#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) +#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ + _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) + +struct drm_wait_vblank_request { + enum drm_vblank_seq_type type; + unsigned int sequence; + unsigned long signal; +}; + +struct drm_wait_vblank_reply { + enum drm_vblank_seq_type type; + unsigned int sequence; + long tval_sec; + long tval_usec; +}; + +/** + * DRM_IOCTL_WAIT_VBLANK ioctl argument type. + * + * \sa drmWaitVBlank(). + */ +union drm_wait_vblank { + struct drm_wait_vblank_request request; + struct drm_wait_vblank_reply reply; +}; + +#define _DRM_PRE_MODESET 1 +#define _DRM_POST_MODESET 2 + +/** + * DRM_IOCTL_MODESET_CTL ioctl argument type + * + * \sa drmModesetCtl(). + */ +struct drm_modeset_ctl { + __u32 crtc; + __u32 cmd; +}; + +/** + * DRM_IOCTL_AGP_ENABLE ioctl argument type. + * + * \sa drmAgpEnable(). + */ +struct drm_agp_mode { + unsigned long mode; /**< AGP mode */ +}; + +/** + * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. + * + * \sa drmAgpAlloc() and drmAgpFree(). + */ +struct drm_agp_buffer { + unsigned long size; /**< In bytes -- will round to page boundary */ + unsigned long handle; /**< Used for binding / unbinding */ + unsigned long type; /**< Type of memory to allocate */ + unsigned long physical; /**< Physical used by i810 */ +}; + +/** + * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. + * + * \sa drmAgpBind() and drmAgpUnbind(). + */ +struct drm_agp_binding { + unsigned long handle; /**< From drm_agp_buffer */ + unsigned long offset; /**< In bytes -- will round to page boundary */ +}; + +/** + * DRM_IOCTL_AGP_INFO ioctl argument type. + * + * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(), + * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), + * drmAgpVendorId() and drmAgpDeviceId(). + */ +struct drm_agp_info { + int agp_version_major; + int agp_version_minor; + unsigned long mode; + unsigned long aperture_base; /* physical address */ + unsigned long aperture_size; /* bytes */ + unsigned long memory_allowed; /* bytes */ + unsigned long memory_used; + + /* PCI information */ + unsigned short id_vendor; + unsigned short id_device; +}; + +/** + * DRM_IOCTL_SG_ALLOC ioctl argument type. + */ +struct drm_scatter_gather { + unsigned long size; /**< In bytes -- will round to page boundary */ + unsigned long handle; /**< Used for mapping / unmapping */ +}; + +/** + * DRM_IOCTL_SET_VERSION ioctl argument type. + */ +struct drm_set_version { + int drm_di_major; + int drm_di_minor; + int drm_dd_major; + int drm_dd_minor; +}; + +/** DRM_IOCTL_GEM_CLOSE ioctl argument type */ +struct drm_gem_close { + /** Handle of the object to be closed. */ + __u32 handle; + __u32 pad; +}; + +/** DRM_IOCTL_GEM_FLINK ioctl argument type */ +struct drm_gem_flink { + /** Handle for the object being named */ + __u32 handle; + + /** Returned global name */ + __u32 name; +}; + +/** DRM_IOCTL_GEM_OPEN ioctl argument type */ +struct drm_gem_open { + /** Name of object being opened */ + __u32 name; + + /** Returned handle for the object */ + __u32 handle; + + /** Returned size of the object */ + __u64 size; +}; + +#define DRM_CAP_DUMB_BUFFER 0x1 +#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 +#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 +#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 +#define DRM_CAP_PRIME 0x5 +#define DRM_PRIME_CAP_IMPORT 0x1 +#define DRM_PRIME_CAP_EXPORT 0x2 +#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 +#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 +/* + * The CURSOR_WIDTH and CURSOR_HEIGHT capabilities return a valid widthxheight + * combination for the hardware cursor. The intention is that a hardware + * agnostic userspace can query a cursor plane size to use. + * + * Note that the cross-driver contract is to merely return a valid size; + * drivers are free to attach another meaning on top, eg. i915 returns the + * maximum plane size. + */ +#define DRM_CAP_CURSOR_WIDTH 0x8 +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#define DRM_CAP_ADDFB2_MODIFIERS 0x10 +#define DRM_CAP_PAGE_FLIP_TARGET 0x11 +#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12 +#define DRM_CAP_SYNCOBJ 0x13 + +/** DRM_IOCTL_GET_CAP ioctl argument type */ +struct drm_get_cap { + __u64 capability; + __u64 value; +}; + +/** + * DRM_CLIENT_CAP_STEREO_3D + * + * if set to 1, the DRM core will expose the stereo 3D capabilities of the + * monitor by advertising the supported 3D layouts in the flags of struct + * drm_mode_modeinfo. + */ +#define DRM_CLIENT_CAP_STEREO_3D 1 + +/** + * DRM_CLIENT_CAP_UNIVERSAL_PLANES + * + * If set to 1, the DRM core will expose all planes (overlay, primary, and + * cursor) to userspace. + */ +#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 + +/** + * DRM_CLIENT_CAP_ATOMIC + * + * If set to 1, the DRM core will expose atomic properties to userspace + */ +#define DRM_CLIENT_CAP_ATOMIC 3 + +/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ +struct drm_set_client_cap { + __u64 capability; + __u64 value; +}; + +#define DRM_RDWR O_RDWR +#define DRM_CLOEXEC O_CLOEXEC +struct drm_prime_handle { + __u32 handle; + + /** Flags.. only applicable for handle->fd */ + __u32 flags; + + /** Returned dmabuf file descriptor */ + __s32 fd; +}; + +struct drm_syncobj_create { + __u32 handle; +#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) + __u32 flags; +}; + +struct drm_syncobj_destroy { + __u32 handle; + __u32 pad; +}; + +#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0) +#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0) +struct drm_syncobj_handle { + __u32 handle; + __u32 flags; + + __s32 fd; + __u32 pad; +}; + +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) +struct drm_syncobj_wait { + __u64 handles; + /* absolute timeout */ + __s64 timeout_nsec; + __u32 count_handles; + __u32 flags; + __u32 first_signaled; /* only valid when not waiting all */ + __u32 pad; +}; + +struct drm_syncobj_array { + __u64 handles; + __u32 count_handles; + __u32 pad; +}; + +#if defined(__cplusplus) +} +#endif + +#include "drm_mode.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) + +#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version) +#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique) +#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth) +#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid) +#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map) +#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) +#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) +#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) +#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) +#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) +#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) +#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) +#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap) +#define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW( 0x0d, struct drm_set_client_cap) + +#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) +#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) +#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) +#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block) +#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control) +#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map) +#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc) +#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc) +#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info) +#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map) +#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free) + +#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map) + +#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) +#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) + +#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) +#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) + +#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) +#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) +#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) +#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx) +#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx) +#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx) +#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res) +#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw) +#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw) +#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma) +#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock) +#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) +#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) + +#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle) +#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle) + +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) +#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer) +#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) + +#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather) +#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) + +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) + +#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) + +#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) +#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) +#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) /* deprecated (never worked) */ +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) /* deprecated (never worked) */ + +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) +#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) +#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) +#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) +#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) +#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) + +#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) +#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) +#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) +#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) +#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) +#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) +#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) +#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) +#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) +#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) +#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) +#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob) +#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob) + +#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create) +#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) +#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) +#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) +#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait) +#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) +#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) + +/** + * Device specific ioctls should only be in their respective headers + * The device specific ioctl range is from 0x40 to 0x9f. + * Generic IOCTLS restart at 0xA0. + * + * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and + * drmCommandReadWrite(). + */ +#define DRM_COMMAND_BASE 0x40 +#define DRM_COMMAND_END 0xA0 + +/** + * Header for events written back to userspace on the drm fd. The + * type defines the type of event, the length specifies the total + * length of the event (including the header), and user_data is + * typically a 64 bit value passed with the ioctl that triggered the + * event. A read on the drm fd will always only return complete + * events, that is, if for example the read buffer is 100 bytes, and + * there are two 64 byte events pending, only one will be returned. + * + * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and + * up are chipset specific. + */ +struct drm_event { + __u32 type; + __u32 length; +}; + +#define DRM_EVENT_VBLANK 0x01 +#define DRM_EVENT_FLIP_COMPLETE 0x02 + +struct drm_event_vblank { + struct drm_event base; + __u64 user_data; + __u32 tv_sec; + __u32 tv_usec; + __u32 sequence; + __u32 crtc_id; /* 0 on older kernels that do not support this */ +}; + +/* typedef area */ +#ifndef __KERNEL__ +typedef struct drm_clip_rect drm_clip_rect_t; +typedef struct drm_drawable_info drm_drawable_info_t; +typedef struct drm_tex_region drm_tex_region_t; +typedef struct drm_hw_lock drm_hw_lock_t; +typedef struct drm_version drm_version_t; +typedef struct drm_unique drm_unique_t; +typedef struct drm_list drm_list_t; +typedef struct drm_block drm_block_t; +typedef struct drm_control drm_control_t; +typedef enum drm_map_type drm_map_type_t; +typedef enum drm_map_flags drm_map_flags_t; +typedef struct drm_ctx_priv_map drm_ctx_priv_map_t; +typedef struct drm_map drm_map_t; +typedef struct drm_client drm_client_t; +typedef enum drm_stat_type drm_stat_type_t; +typedef struct drm_stats drm_stats_t; +typedef enum drm_lock_flags drm_lock_flags_t; +typedef struct drm_lock drm_lock_t; +typedef enum drm_dma_flags drm_dma_flags_t; +typedef struct drm_buf_desc drm_buf_desc_t; +typedef struct drm_buf_info drm_buf_info_t; +typedef struct drm_buf_free drm_buf_free_t; +typedef struct drm_buf_pub drm_buf_pub_t; +typedef struct drm_buf_map drm_buf_map_t; +typedef struct drm_dma drm_dma_t; +typedef union drm_wait_vblank drm_wait_vblank_t; +typedef struct drm_agp_mode drm_agp_mode_t; +typedef enum drm_ctx_flags drm_ctx_flags_t; +typedef struct drm_ctx drm_ctx_t; +typedef struct drm_ctx_res drm_ctx_res_t; +typedef struct drm_draw drm_draw_t; +typedef struct drm_update_draw drm_update_draw_t; +typedef struct drm_auth drm_auth_t; +typedef struct drm_irq_busid drm_irq_busid_t; +typedef enum drm_vblank_seq_type drm_vblank_seq_type_t; + +typedef struct drm_agp_buffer drm_agp_buffer_t; +typedef struct drm_agp_binding drm_agp_binding_t; +typedef struct drm_agp_info drm_agp_info_t; +typedef struct drm_scatter_gather drm_scatter_gather_t; +typedef struct drm_set_version drm_set_version_t; +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h new file mode 100644 index 0000000000000000000000000000000000000000..6598fb76d2c27741d2c916f914b70c5f472911f9 --- /dev/null +++ b/tools/include/uapi/drm/i915_drm.h @@ -0,0 +1,1521 @@ +/* + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _UAPI_I915_DRM_H_ +#define _UAPI_I915_DRM_H_ + +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Please note that modifications to all structs defined here are + * subject to backwards-compatibility constraints. + */ + +/** + * DOC: uevents generated by i915 on it's device node + * + * I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch + * event from the gpu l3 cache. Additional information supplied is ROW, + * BANK, SUBBANK, SLICE of the affected cacheline. Userspace should keep + * track of these events and if a specific cache-line seems to have a + * persistent error remap it with the l3 remapping tool supplied in + * intel-gpu-tools. The value supplied with the event is always 1. + * + * I915_ERROR_UEVENT - Generated upon error detection, currently only via + * hangcheck. The error detection event is a good indicator of when things + * began to go badly. The value supplied with the event is a 1 upon error + * detection, and a 0 upon reset completion, signifying no more error + * exists. NOTE: Disabling hangcheck or reset via module parameter will + * cause the related events to not be seen. + * + * I915_RESET_UEVENT - Event is generated just before an attempt to reset the + * the GPU. The value supplied with the event is always 1. NOTE: Disable + * reset via module parameter will cause this event to not be seen. + */ +#define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR" +#define I915_ERROR_UEVENT "ERROR" +#define I915_RESET_UEVENT "RESET" + +/* + * MOCS indexes used for GPU surfaces, defining the cacheability of the + * surface data and the coherency for this data wrt. CPU vs. GPU accesses. + */ +enum i915_mocs_table_index { + /* + * Not cached anywhere, coherency between CPU and GPU accesses is + * guaranteed. + */ + I915_MOCS_UNCACHED, + /* + * Cacheability and coherency controlled by the kernel automatically + * based on the DRM_I915_GEM_SET_CACHING IOCTL setting and the current + * usage of the surface (used for display scanout or not). + */ + I915_MOCS_PTE, + /* + * Cached in all GPU caches available on the platform. + * Coherency between CPU and GPU accesses to the surface is not + * guaranteed without extra synchronization. + */ + I915_MOCS_CACHED, +}; + +/* Each region is a minimum of 16k, and there are at most 255 of them. + */ +#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use + * of chars for next/prev indices */ +#define I915_LOG_MIN_TEX_REGION_SIZE 14 + +typedef struct _drm_i915_init { + enum { + I915_INIT_DMA = 0x01, + I915_CLEANUP_DMA = 0x02, + I915_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drm_i915_init_t; + +typedef struct _drm_i915_sarea { + struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; + + /* fill out some space for old userspace triple buffer */ + drm_handle_t unused_handle; + __u32 unused1, unused2, unused3; + + /* buffer object handles for static buffers. May change + * over the lifetime of the client. + */ + __u32 front_bo_handle; + __u32 back_bo_handle; + __u32 unused_bo_handle; + __u32 depth_bo_handle; + +} drm_i915_sarea_t; + +/* due to userspace building against these headers we need some compat here */ +#define planeA_x pipeA_x +#define planeA_y pipeA_y +#define planeA_w pipeA_w +#define planeA_h pipeA_h +#define planeB_x pipeB_x +#define planeB_y pipeB_y +#define planeB_w pipeB_w +#define planeB_h pipeB_h + +/* Flags for perf_boxes + */ +#define I915_BOX_RING_EMPTY 0x1 +#define I915_BOX_FLIP 0x2 +#define I915_BOX_WAIT 0x4 +#define I915_BOX_TEXTURE_LOAD 0x8 +#define I915_BOX_LOST_CONTEXT 0x10 + +/* + * i915 specific ioctls. + * + * The device specific ioctl range is [DRM_COMMAND_BASE, DRM_COMMAND_END) ie + * [0x40, 0xa0) (a0 is excluded). The numbers below are defined as offset + * against DRM_COMMAND_BASE and should be between [0x0, 0x60). + */ +#define DRM_I915_INIT 0x00 +#define DRM_I915_FLUSH 0x01 +#define DRM_I915_FLIP 0x02 +#define DRM_I915_BATCHBUFFER 0x03 +#define DRM_I915_IRQ_EMIT 0x04 +#define DRM_I915_IRQ_WAIT 0x05 +#define DRM_I915_GETPARAM 0x06 +#define DRM_I915_SETPARAM 0x07 +#define DRM_I915_ALLOC 0x08 +#define DRM_I915_FREE 0x09 +#define DRM_I915_INIT_HEAP 0x0a +#define DRM_I915_CMDBUFFER 0x0b +#define DRM_I915_DESTROY_HEAP 0x0c +#define DRM_I915_SET_VBLANK_PIPE 0x0d +#define DRM_I915_GET_VBLANK_PIPE 0x0e +#define DRM_I915_VBLANK_SWAP 0x0f +#define DRM_I915_HWS_ADDR 0x11 +#define DRM_I915_GEM_INIT 0x13 +#define DRM_I915_GEM_EXECBUFFER 0x14 +#define DRM_I915_GEM_PIN 0x15 +#define DRM_I915_GEM_UNPIN 0x16 +#define DRM_I915_GEM_BUSY 0x17 +#define DRM_I915_GEM_THROTTLE 0x18 +#define DRM_I915_GEM_ENTERVT 0x19 +#define DRM_I915_GEM_LEAVEVT 0x1a +#define DRM_I915_GEM_CREATE 0x1b +#define DRM_I915_GEM_PREAD 0x1c +#define DRM_I915_GEM_PWRITE 0x1d +#define DRM_I915_GEM_MMAP 0x1e +#define DRM_I915_GEM_SET_DOMAIN 0x1f +#define DRM_I915_GEM_SW_FINISH 0x20 +#define DRM_I915_GEM_SET_TILING 0x21 +#define DRM_I915_GEM_GET_TILING 0x22 +#define DRM_I915_GEM_GET_APERTURE 0x23 +#define DRM_I915_GEM_MMAP_GTT 0x24 +#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 +#define DRM_I915_GEM_MADVISE 0x26 +#define DRM_I915_OVERLAY_PUT_IMAGE 0x27 +#define DRM_I915_OVERLAY_ATTRS 0x28 +#define DRM_I915_GEM_EXECBUFFER2 0x29 +#define DRM_I915_GEM_EXECBUFFER2_WR DRM_I915_GEM_EXECBUFFER2 +#define DRM_I915_GET_SPRITE_COLORKEY 0x2a +#define DRM_I915_SET_SPRITE_COLORKEY 0x2b +#define DRM_I915_GEM_WAIT 0x2c +#define DRM_I915_GEM_CONTEXT_CREATE 0x2d +#define DRM_I915_GEM_CONTEXT_DESTROY 0x2e +#define DRM_I915_GEM_SET_CACHING 0x2f +#define DRM_I915_GEM_GET_CACHING 0x30 +#define DRM_I915_REG_READ 0x31 +#define DRM_I915_GET_RESET_STATS 0x32 +#define DRM_I915_GEM_USERPTR 0x33 +#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 +#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 +#define DRM_I915_PERF_OPEN 0x36 +#define DRM_I915_PERF_ADD_CONFIG 0x37 +#define DRM_I915_PERF_REMOVE_CONFIG 0x38 + +#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) +#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) +#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) +#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) +#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) +#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) +#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t) +#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t) +#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t) +#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) +#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) +#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) +#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) +#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) +#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) +#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) +#define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) +#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) +#define DRM_IOCTL_I915_GEM_EXECBUFFER2_WR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2_WR, struct drm_i915_gem_execbuffer2) +#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) +#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) +#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) +#define DRM_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching) +#define DRM_IOCTL_I915_GEM_GET_CACHING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching) +#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE) +#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) +#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) +#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) +#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) +#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) +#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) +#define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt) +#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain) +#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish) +#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) +#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) +#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) +#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) +#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) +#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) +#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) +#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) +#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) +#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait) +#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create) +#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy) +#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read) +#define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats) +#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr) +#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) +#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) +#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) +#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config) +#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64) + +/* Allow drivers to submit batchbuffers directly to hardware, relying + * on the security mechanisms provided by hardware. + */ +typedef struct drm_i915_batchbuffer { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ + int num_cliprects; /* mulitpass with multiple cliprects? */ + struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ +} drm_i915_batchbuffer_t; + +/* As above, but pass a pointer to userspace buffer which can be + * validated by the kernel prior to sending to hardware. + */ +typedef struct _drm_i915_cmdbuffer { + char __user *buf; /* pointer to userspace command buffer */ + int sz; /* nr bytes in buf */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ + int num_cliprects; /* mulitpass with multiple cliprects? */ + struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ +} drm_i915_cmdbuffer_t; + +/* Userspace can request & wait on irq's: + */ +typedef struct drm_i915_irq_emit { + int __user *irq_seq; +} drm_i915_irq_emit_t; + +typedef struct drm_i915_irq_wait { + int irq_seq; +} drm_i915_irq_wait_t; + +/* Ioctl to query kernel params: + */ +#define I915_PARAM_IRQ_ACTIVE 1 +#define I915_PARAM_ALLOW_BATCHBUFFER 2 +#define I915_PARAM_LAST_DISPATCH 3 +#define I915_PARAM_CHIPSET_ID 4 +#define I915_PARAM_HAS_GEM 5 +#define I915_PARAM_NUM_FENCES_AVAIL 6 +#define I915_PARAM_HAS_OVERLAY 7 +#define I915_PARAM_HAS_PAGEFLIPPING 8 +#define I915_PARAM_HAS_EXECBUF2 9 +#define I915_PARAM_HAS_BSD 10 +#define I915_PARAM_HAS_BLT 11 +#define I915_PARAM_HAS_RELAXED_FENCING 12 +#define I915_PARAM_HAS_COHERENT_RINGS 13 +#define I915_PARAM_HAS_EXEC_CONSTANTS 14 +#define I915_PARAM_HAS_RELAXED_DELTA 15 +#define I915_PARAM_HAS_GEN7_SOL_RESET 16 +#define I915_PARAM_HAS_LLC 17 +#define I915_PARAM_HAS_ALIASING_PPGTT 18 +#define I915_PARAM_HAS_WAIT_TIMEOUT 19 +#define I915_PARAM_HAS_SEMAPHORES 20 +#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 +#define I915_PARAM_HAS_VEBOX 22 +#define I915_PARAM_HAS_SECURE_BATCHES 23 +#define I915_PARAM_HAS_PINNED_BATCHES 24 +#define I915_PARAM_HAS_EXEC_NO_RELOC 25 +#define I915_PARAM_HAS_EXEC_HANDLE_LUT 26 +#define I915_PARAM_HAS_WT 27 +#define I915_PARAM_CMD_PARSER_VERSION 28 +#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29 +#define I915_PARAM_MMAP_VERSION 30 +#define I915_PARAM_HAS_BSD2 31 +#define I915_PARAM_REVISION 32 +#define I915_PARAM_SUBSLICE_TOTAL 33 +#define I915_PARAM_EU_TOTAL 34 +#define I915_PARAM_HAS_GPU_RESET 35 +#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 +#define I915_PARAM_HAS_POOLED_EU 38 +#define I915_PARAM_MIN_EU_IN_POOL 39 +#define I915_PARAM_MMAP_GTT_VERSION 40 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution + * priorities and the driver will attempt to execute batches in priority order. + */ +#define I915_PARAM_HAS_SCHEDULER 41 +#define I915_PARAM_HUC_STATUS 42 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of + * synchronisation with implicit fencing on individual objects. + * See EXEC_OBJECT_ASYNC. + */ +#define I915_PARAM_HAS_EXEC_ASYNC 43 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports explicit fence support - + * both being able to pass in a sync_file fd to wait upon before executing, + * and being able to return a new sync_file fd that is signaled when the + * current request is complete. See I915_EXEC_FENCE_IN and I915_EXEC_FENCE_OUT. + */ +#define I915_PARAM_HAS_EXEC_FENCE 44 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to capture + * user specified bufffers for post-mortem debugging of GPU hangs. See + * EXEC_OBJECT_CAPTURE. + */ +#define I915_PARAM_HAS_EXEC_CAPTURE 45 + +#define I915_PARAM_SLICE_MASK 46 + +/* Assuming it's uniform for each slice, this queries the mask of subslices + * per-slice for this system. + */ +#define I915_PARAM_SUBSLICE_MASK 47 + +/* + * Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying the batch buffer + * as the first execobject as opposed to the last. See I915_EXEC_BATCH_FIRST. + */ +#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of + * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY. + */ +#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 + +typedef struct drm_i915_getparam { + __s32 param; + /* + * WARNING: Using pointers instead of fixed-size u64 means we need to write + * compat32 code. Don't repeat this mistake. + */ + int __user *value; +} drm_i915_getparam_t; + +/* Ioctl to set kernel params: + */ +#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I915_SETPARAM_ALLOW_BATCHBUFFER 3 +#define I915_SETPARAM_NUM_USED_FENCES 4 + +typedef struct drm_i915_setparam { + int param; + int value; +} drm_i915_setparam_t; + +/* A memory manager for regions of shared memory: + */ +#define I915_MEM_REGION_AGP 1 + +typedef struct drm_i915_mem_alloc { + int region; + int alignment; + int size; + int __user *region_offset; /* offset from start of fb or agp */ +} drm_i915_mem_alloc_t; + +typedef struct drm_i915_mem_free { + int region; + int region_offset; +} drm_i915_mem_free_t; + +typedef struct drm_i915_mem_init_heap { + int region; + int size; + int start; +} drm_i915_mem_init_heap_t; + +/* Allow memory manager to be torn down and re-initialized (eg on + * rotate): + */ +typedef struct drm_i915_mem_destroy_heap { + int region; +} drm_i915_mem_destroy_heap_t; + +/* Allow X server to configure which pipes to monitor for vblank signals + */ +#define DRM_I915_VBLANK_PIPE_A 1 +#define DRM_I915_VBLANK_PIPE_B 2 + +typedef struct drm_i915_vblank_pipe { + int pipe; +} drm_i915_vblank_pipe_t; + +/* Schedule buffer swap at given vertical blank: + */ +typedef struct drm_i915_vblank_swap { + drm_drawable_t drawable; + enum drm_vblank_seq_type seqtype; + unsigned int sequence; +} drm_i915_vblank_swap_t; + +typedef struct drm_i915_hws_addr { + __u64 addr; +} drm_i915_hws_addr_t; + +struct drm_i915_gem_init { + /** + * Beginning offset in the GTT to be managed by the DRM memory + * manager. + */ + __u64 gtt_start; + /** + * Ending offset in the GTT to be managed by the DRM memory + * manager. + */ + __u64 gtt_end; +}; + +struct drm_i915_gem_create { + /** + * Requested size for the object. + * + * The (page-aligned) allocated size for the object will be returned. + */ + __u64 size; + /** + * Returned handle for the object. + * + * Object handles are nonzero. + */ + __u32 handle; + __u32 pad; +}; + +struct drm_i915_gem_pread { + /** Handle for the object being read. */ + __u32 handle; + __u32 pad; + /** Offset into the object to read from */ + __u64 offset; + /** Length of data to read */ + __u64 size; + /** + * Pointer to write the data into. + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 data_ptr; +}; + +struct drm_i915_gem_pwrite { + /** Handle for the object being written to. */ + __u32 handle; + __u32 pad; + /** Offset into the object to write to */ + __u64 offset; + /** Length of data to write */ + __u64 size; + /** + * Pointer to read the data from. + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 data_ptr; +}; + +struct drm_i915_gem_mmap { + /** Handle for the object being mapped. */ + __u32 handle; + __u32 pad; + /** Offset in the object to map. */ + __u64 offset; + /** + * Length of data to map. + * + * The value will be page-aligned. + */ + __u64 size; + /** + * Returned pointer the data was mapped at. + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 addr_ptr; + + /** + * Flags for extended behaviour. + * + * Added in version 2. + */ + __u64 flags; +#define I915_MMAP_WC 0x1 +}; + +struct drm_i915_gem_mmap_gtt { + /** Handle for the object being mapped. */ + __u32 handle; + __u32 pad; + /** + * Fake offset to use for subsequent mmap call + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 offset; +}; + +struct drm_i915_gem_set_domain { + /** Handle for the object */ + __u32 handle; + + /** New read domains */ + __u32 read_domains; + + /** New write domain */ + __u32 write_domain; +}; + +struct drm_i915_gem_sw_finish { + /** Handle for the object */ + __u32 handle; +}; + +struct drm_i915_gem_relocation_entry { + /** + * Handle of the buffer being pointed to by this relocation entry. + * + * It's appealing to make this be an index into the mm_validate_entry + * list to refer to the buffer, but this allows the driver to create + * a relocation list for state buffers and not re-write it per + * exec using the buffer. + */ + __u32 target_handle; + + /** + * Value to be added to the offset of the target buffer to make up + * the relocation entry. + */ + __u32 delta; + + /** Offset in the buffer the relocation entry will be written into */ + __u64 offset; + + /** + * Offset value of the target buffer that the relocation entry was last + * written as. + * + * If the buffer has the same offset as last time, we can skip syncing + * and writing the relocation. This value is written back out by + * the execbuffer ioctl when the relocation is written. + */ + __u64 presumed_offset; + + /** + * Target memory domains read by this operation. + */ + __u32 read_domains; + + /** + * Target memory domains written by this operation. + * + * Note that only one domain may be written by the whole + * execbuffer operation, so that where there are conflicts, + * the application will get -EINVAL back. + */ + __u32 write_domain; +}; + +/** @{ + * Intel memory domains + * + * Most of these just align with the various caches in + * the system and are used to flush and invalidate as + * objects end up cached in different domains. + */ +/** CPU cache */ +#define I915_GEM_DOMAIN_CPU 0x00000001 +/** Render cache, used by 2D and 3D drawing */ +#define I915_GEM_DOMAIN_RENDER 0x00000002 +/** Sampler cache, used by texture engine */ +#define I915_GEM_DOMAIN_SAMPLER 0x00000004 +/** Command queue, used to load batch buffers */ +#define I915_GEM_DOMAIN_COMMAND 0x00000008 +/** Instruction cache, used by shader programs */ +#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010 +/** Vertex address cache */ +#define I915_GEM_DOMAIN_VERTEX 0x00000020 +/** GTT domain - aperture and scanout */ +#define I915_GEM_DOMAIN_GTT 0x00000040 +/** WC domain - uncached access */ +#define I915_GEM_DOMAIN_WC 0x00000080 +/** @} */ + +struct drm_i915_gem_exec_object { + /** + * User's handle for a buffer to be bound into the GTT for this + * operation. + */ + __u32 handle; + + /** Number of relocations to be performed on this buffer */ + __u32 relocation_count; + /** + * Pointer to array of struct drm_i915_gem_relocation_entry containing + * the relocations to be performed in this buffer. + */ + __u64 relocs_ptr; + + /** Required alignment in graphics aperture */ + __u64 alignment; + + /** + * Returned value of the updated offset of the object, for future + * presumed_offset writes. + */ + __u64 offset; +}; + +struct drm_i915_gem_execbuffer { + /** + * List of buffers to be validated with their relocations to be + * performend on them. + * + * This is a pointer to an array of struct drm_i915_gem_validate_entry. + * + * These buffers must be listed in an order such that all relocations + * a buffer is performing refer to buffers that have already appeared + * in the validate list. + */ + __u64 buffers_ptr; + __u32 buffer_count; + + /** Offset in the batchbuffer to start execution from. */ + __u32 batch_start_offset; + /** Bytes used in batchbuffer from batch_start_offset */ + __u32 batch_len; + __u32 DR1; + __u32 DR4; + __u32 num_cliprects; + /** This is a struct drm_clip_rect *cliprects */ + __u64 cliprects_ptr; +}; + +struct drm_i915_gem_exec_object2 { + /** + * User's handle for a buffer to be bound into the GTT for this + * operation. + */ + __u32 handle; + + /** Number of relocations to be performed on this buffer */ + __u32 relocation_count; + /** + * Pointer to array of struct drm_i915_gem_relocation_entry containing + * the relocations to be performed in this buffer. + */ + __u64 relocs_ptr; + + /** Required alignment in graphics aperture */ + __u64 alignment; + + /** + * When the EXEC_OBJECT_PINNED flag is specified this is populated by + * the user with the GTT offset at which this object will be pinned. + * When the I915_EXEC_NO_RELOC flag is specified this must contain the + * presumed_offset of the object. + * During execbuffer2 the kernel populates it with the value of the + * current GTT offset of the object, for future presumed_offset writes. + */ + __u64 offset; + +#define EXEC_OBJECT_NEEDS_FENCE (1<<0) +#define EXEC_OBJECT_NEEDS_GTT (1<<1) +#define EXEC_OBJECT_WRITE (1<<2) +#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) +#define EXEC_OBJECT_PINNED (1<<4) +#define EXEC_OBJECT_PAD_TO_SIZE (1<<5) +/* The kernel implicitly tracks GPU activity on all GEM objects, and + * synchronises operations with outstanding rendering. This includes + * rendering on other devices if exported via dma-buf. However, sometimes + * this tracking is too coarse and the user knows better. For example, + * if the object is split into non-overlapping ranges shared between different + * clients or engines (i.e. suballocating objects), the implicit tracking + * by kernel assumes that each operation affects the whole object rather + * than an individual range, causing needless synchronisation between clients. + * The kernel will also forgo any CPU cache flushes prior to rendering from + * the object as the client is expected to be also handling such domain + * tracking. + * + * The kernel maintains the implicit tracking in order to manage resources + * used by the GPU - this flag only disables the synchronisation prior to + * rendering with this object in this execbuf. + * + * Opting out of implicit synhronisation requires the user to do its own + * explicit tracking to avoid rendering corruption. See, for example, + * I915_PARAM_HAS_EXEC_FENCE to order execbufs and execute them asynchronously. + */ +#define EXEC_OBJECT_ASYNC (1<<6) +/* Request that the contents of this execobject be copied into the error + * state upon a GPU hang involving this batch for post-mortem debugging. + * These buffers are recorded in no particular order as "user" in + * /sys/class/drm/cardN/error. Query I915_PARAM_HAS_EXEC_CAPTURE to see + * if the kernel supports this flag. + */ +#define EXEC_OBJECT_CAPTURE (1<<7) +/* All remaining bits are MBZ and RESERVED FOR FUTURE USE */ +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_CAPTURE<<1) + __u64 flags; + + union { + __u64 rsvd1; + __u64 pad_to_size; + }; + __u64 rsvd2; +}; + +struct drm_i915_gem_exec_fence { + /** + * User's handle for a drm_syncobj to wait on or signal. + */ + __u32 handle; + +#define I915_EXEC_FENCE_WAIT (1<<0) +#define I915_EXEC_FENCE_SIGNAL (1<<1) + __u32 flags; +}; + +struct drm_i915_gem_execbuffer2 { + /** + * List of gem_exec_object2 structs + */ + __u64 buffers_ptr; + __u32 buffer_count; + + /** Offset in the batchbuffer to start execution from. */ + __u32 batch_start_offset; + /** Bytes used in batchbuffer from batch_start_offset */ + __u32 batch_len; + __u32 DR1; + __u32 DR4; + __u32 num_cliprects; + /** + * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY + * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a + * struct drm_i915_gem_exec_fence *fences. + */ + __u64 cliprects_ptr; +#define I915_EXEC_RING_MASK (7<<0) +#define I915_EXEC_DEFAULT (0<<0) +#define I915_EXEC_RENDER (1<<0) +#define I915_EXEC_BSD (2<<0) +#define I915_EXEC_BLT (3<<0) +#define I915_EXEC_VEBOX (4<<0) + +/* Used for switching the constants addressing mode on gen4+ RENDER ring. + * Gen6+ only supports relative addressing to dynamic state (default) and + * absolute addressing. + * + * These flags are ignored for the BSD and BLT rings. + */ +#define I915_EXEC_CONSTANTS_MASK (3<<6) +#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */ +#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6) +#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */ + __u64 flags; + __u64 rsvd1; /* now used for context info */ + __u64 rsvd2; +}; + +/** Resets the SO write offset registers for transform feedback on gen7. */ +#define I915_EXEC_GEN7_SOL_RESET (1<<8) + +/** Request a privileged ("secure") batch buffer. Note only available for + * DRM_ROOT_ONLY | DRM_MASTER processes. + */ +#define I915_EXEC_SECURE (1<<9) + +/** Inform the kernel that the batch is and will always be pinned. This + * negates the requirement for a workaround to be performed to avoid + * an incoherent CS (such as can be found on 830/845). If this flag is + * not passed, the kernel will endeavour to make sure the batch is + * coherent with the CS before execution. If this flag is passed, + * userspace assumes the responsibility for ensuring the same. + */ +#define I915_EXEC_IS_PINNED (1<<10) + +/** Provide a hint to the kernel that the command stream and auxiliary + * state buffers already holds the correct presumed addresses and so the + * relocation process may be skipped if no buffers need to be moved in + * preparation for the execbuffer. + */ +#define I915_EXEC_NO_RELOC (1<<11) + +/** Use the reloc.handle as an index into the exec object array rather + * than as the per-file handle. + */ +#define I915_EXEC_HANDLE_LUT (1<<12) + +/** Used for switching BSD rings on the platforms with two BSD rings */ +#define I915_EXEC_BSD_SHIFT (13) +#define I915_EXEC_BSD_MASK (3 << I915_EXEC_BSD_SHIFT) +/* default ping-pong mode */ +#define I915_EXEC_BSD_DEFAULT (0 << I915_EXEC_BSD_SHIFT) +#define I915_EXEC_BSD_RING1 (1 << I915_EXEC_BSD_SHIFT) +#define I915_EXEC_BSD_RING2 (2 << I915_EXEC_BSD_SHIFT) + +/** Tell the kernel that the batchbuffer is processed by + * the resource streamer. + */ +#define I915_EXEC_RESOURCE_STREAMER (1<<15) + +/* Setting I915_EXEC_FENCE_IN implies that lower_32_bits(rsvd2) represent + * a sync_file fd to wait upon (in a nonblocking manner) prior to executing + * the batch. + * + * Returns -EINVAL if the sync_file fd cannot be found. + */ +#define I915_EXEC_FENCE_IN (1<<16) + +/* Setting I915_EXEC_FENCE_OUT causes the ioctl to return a sync_file fd + * in the upper_32_bits(rsvd2) upon success. Ownership of the fd is given + * to the caller, and it should be close() after use. (The fd is a regular + * file descriptor and will be cleaned up on process termination. It holds + * a reference to the request, but nothing else.) + * + * The sync_file fd can be combined with other sync_file and passed either + * to execbuf using I915_EXEC_FENCE_IN, to atomic KMS ioctls (so that a flip + * will only occur after this request completes), or to other devices. + * + * Using I915_EXEC_FENCE_OUT requires use of + * DRM_IOCTL_I915_GEM_EXECBUFFER2_WR ioctl so that the result is written + * back to userspace. Failure to do so will cause the out-fence to always + * be reported as zero, and the real fence fd to be leaked. + */ +#define I915_EXEC_FENCE_OUT (1<<17) + +/* + * Traditionally the execbuf ioctl has only considered the final element in + * the execobject[] to be the executable batch. Often though, the client + * will known the batch object prior to construction and being able to place + * it into the execobject[] array first can simplify the relocation tracking. + * Setting I915_EXEC_BATCH_FIRST tells execbuf to use element 0 of the + * execobject[] as the * batch instead (the default is to use the last + * element). + */ +#define I915_EXEC_BATCH_FIRST (1<<18) + +/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr + * define an array of i915_gem_exec_fence structures which specify a set of + * dma fences to wait upon or signal. + */ +#define I915_EXEC_FENCE_ARRAY (1<<19) + +#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1)) + +#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) +#define i915_execbuffer2_set_context_id(eb2, context) \ + (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK +#define i915_execbuffer2_get_context_id(eb2) \ + ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK) + +struct drm_i915_gem_pin { + /** Handle of the buffer to be pinned. */ + __u32 handle; + __u32 pad; + + /** alignment required within the aperture */ + __u64 alignment; + + /** Returned GTT offset of the buffer. */ + __u64 offset; +}; + +struct drm_i915_gem_unpin { + /** Handle of the buffer to be unpinned. */ + __u32 handle; + __u32 pad; +}; + +struct drm_i915_gem_busy { + /** Handle of the buffer to check for busy */ + __u32 handle; + + /** Return busy status + * + * A return of 0 implies that the object is idle (after + * having flushed any pending activity), and a non-zero return that + * the object is still in-flight on the GPU. (The GPU has not yet + * signaled completion for all pending requests that reference the + * object.) An object is guaranteed to become idle eventually (so + * long as no new GPU commands are executed upon it). Due to the + * asynchronous nature of the hardware, an object reported + * as busy may become idle before the ioctl is completed. + * + * Furthermore, if the object is busy, which engine is busy is only + * provided as a guide. There are race conditions which prevent the + * report of which engines are busy from being always accurate. + * However, the converse is not true. If the object is idle, the + * result of the ioctl, that all engines are idle, is accurate. + * + * The returned dword is split into two fields to indicate both + * the engines on which the object is being read, and the + * engine on which it is currently being written (if any). + * + * The low word (bits 0:15) indicate if the object is being written + * to by any engine (there can only be one, as the GEM implicit + * synchronisation rules force writes to be serialised). Only the + * engine for the last write is reported. + * + * The high word (bits 16:31) are a bitmask of which engines are + * currently reading from the object. Multiple engines may be + * reading from the object simultaneously. + * + * The value of each engine is the same as specified in the + * EXECBUFFER2 ioctl, i.e. I915_EXEC_RENDER, I915_EXEC_BSD etc. + * Note I915_EXEC_DEFAULT is a symbolic value and is mapped to + * the I915_EXEC_RENDER engine for execution, and so it is never + * reported as active itself. Some hardware may have parallel + * execution engines, e.g. multiple media engines, which are + * mapped to the same identifier in the EXECBUFFER2 ioctl and + * so are not separately reported for busyness. + * + * Caveat emptor: + * Only the boolean result of this query is reliable; that is whether + * the object is idle or busy. The report of which engines are busy + * should be only used as a heuristic. + */ + __u32 busy; +}; + +/** + * I915_CACHING_NONE + * + * GPU access is not coherent with cpu caches. Default for machines without an + * LLC. + */ +#define I915_CACHING_NONE 0 +/** + * I915_CACHING_CACHED + * + * GPU access is coherent with cpu caches and furthermore the data is cached in + * last-level caches shared between cpu cores and the gpu GT. Default on + * machines with HAS_LLC. + */ +#define I915_CACHING_CACHED 1 +/** + * I915_CACHING_DISPLAY + * + * Special GPU caching mode which is coherent with the scanout engines. + * Transparently falls back to I915_CACHING_NONE on platforms where no special + * cache mode (like write-through or gfdt flushing) is available. The kernel + * automatically sets this mode when using a buffer as a scanout target. + * Userspace can manually set this mode to avoid a costly stall and clflush in + * the hotpath of drawing the first frame. + */ +#define I915_CACHING_DISPLAY 2 + +struct drm_i915_gem_caching { + /** + * Handle of the buffer to set/get the caching level of. */ + __u32 handle; + + /** + * Cacheing level to apply or return value + * + * bits0-15 are for generic caching control (i.e. the above defined + * values). bits16-31 are reserved for platform-specific variations + * (e.g. l3$ caching on gen7). */ + __u32 caching; +}; + +#define I915_TILING_NONE 0 +#define I915_TILING_X 1 +#define I915_TILING_Y 2 +#define I915_TILING_LAST I915_TILING_Y + +#define I915_BIT_6_SWIZZLE_NONE 0 +#define I915_BIT_6_SWIZZLE_9 1 +#define I915_BIT_6_SWIZZLE_9_10 2 +#define I915_BIT_6_SWIZZLE_9_11 3 +#define I915_BIT_6_SWIZZLE_9_10_11 4 +/* Not seen by userland */ +#define I915_BIT_6_SWIZZLE_UNKNOWN 5 +/* Seen by userland. */ +#define I915_BIT_6_SWIZZLE_9_17 6 +#define I915_BIT_6_SWIZZLE_9_10_17 7 + +struct drm_i915_gem_set_tiling { + /** Handle of the buffer to have its tiling state updated */ + __u32 handle; + + /** + * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X, + * I915_TILING_Y). + * + * This value is to be set on request, and will be updated by the + * kernel on successful return with the actual chosen tiling layout. + * + * The tiling mode may be demoted to I915_TILING_NONE when the system + * has bit 6 swizzling that can't be managed correctly by GEM. + * + * Buffer contents become undefined when changing tiling_mode. + */ + __u32 tiling_mode; + + /** + * Stride in bytes for the object when in I915_TILING_X or + * I915_TILING_Y. + */ + __u32 stride; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping. + */ + __u32 swizzle_mode; +}; + +struct drm_i915_gem_get_tiling { + /** Handle of the buffer to get tiling state for. */ + __u32 handle; + + /** + * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X, + * I915_TILING_Y). + */ + __u32 tiling_mode; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping. + */ + __u32 swizzle_mode; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping whilst bound. + */ + __u32 phys_swizzle_mode; +}; + +struct drm_i915_gem_get_aperture { + /** Total size of the aperture used by i915_gem_execbuffer, in bytes */ + __u64 aper_size; + + /** + * Available space in the aperture used by i915_gem_execbuffer, in + * bytes + */ + __u64 aper_available_size; +}; + +struct drm_i915_get_pipe_from_crtc_id { + /** ID of CRTC being requested **/ + __u32 crtc_id; + + /** pipe of requested CRTC **/ + __u32 pipe; +}; + +#define I915_MADV_WILLNEED 0 +#define I915_MADV_DONTNEED 1 +#define __I915_MADV_PURGED 2 /* internal state */ + +struct drm_i915_gem_madvise { + /** Handle of the buffer to change the backing store advice */ + __u32 handle; + + /* Advice: either the buffer will be needed again in the near future, + * or wont be and could be discarded under memory pressure. + */ + __u32 madv; + + /** Whether the backing store still exists. */ + __u32 retained; +}; + +/* flags */ +#define I915_OVERLAY_TYPE_MASK 0xff +#define I915_OVERLAY_YUV_PLANAR 0x01 +#define I915_OVERLAY_YUV_PACKED 0x02 +#define I915_OVERLAY_RGB 0x03 + +#define I915_OVERLAY_DEPTH_MASK 0xff00 +#define I915_OVERLAY_RGB24 0x1000 +#define I915_OVERLAY_RGB16 0x2000 +#define I915_OVERLAY_RGB15 0x3000 +#define I915_OVERLAY_YUV422 0x0100 +#define I915_OVERLAY_YUV411 0x0200 +#define I915_OVERLAY_YUV420 0x0300 +#define I915_OVERLAY_YUV410 0x0400 + +#define I915_OVERLAY_SWAP_MASK 0xff0000 +#define I915_OVERLAY_NO_SWAP 0x000000 +#define I915_OVERLAY_UV_SWAP 0x010000 +#define I915_OVERLAY_Y_SWAP 0x020000 +#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000 + +#define I915_OVERLAY_FLAGS_MASK 0xff000000 +#define I915_OVERLAY_ENABLE 0x01000000 + +struct drm_intel_overlay_put_image { + /* various flags and src format description */ + __u32 flags; + /* source picture description */ + __u32 bo_handle; + /* stride values and offsets are in bytes, buffer relative */ + __u16 stride_Y; /* stride for packed formats */ + __u16 stride_UV; + __u32 offset_Y; /* offset for packet formats */ + __u32 offset_U; + __u32 offset_V; + /* in pixels */ + __u16 src_width; + __u16 src_height; + /* to compensate the scaling factors for partially covered surfaces */ + __u16 src_scan_width; + __u16 src_scan_height; + /* output crtc description */ + __u32 crtc_id; + __u16 dst_x; + __u16 dst_y; + __u16 dst_width; + __u16 dst_height; +}; + +/* flags */ +#define I915_OVERLAY_UPDATE_ATTRS (1<<0) +#define I915_OVERLAY_UPDATE_GAMMA (1<<1) +#define I915_OVERLAY_DISABLE_DEST_COLORKEY (1<<2) +struct drm_intel_overlay_attrs { + __u32 flags; + __u32 color_key; + __s32 brightness; + __u32 contrast; + __u32 saturation; + __u32 gamma0; + __u32 gamma1; + __u32 gamma2; + __u32 gamma3; + __u32 gamma4; + __u32 gamma5; +}; + +/* + * Intel sprite handling + * + * Color keying works with a min/mask/max tuple. Both source and destination + * color keying is allowed. + * + * Source keying: + * Sprite pixels within the min & max values, masked against the color channels + * specified in the mask field, will be transparent. All other pixels will + * be displayed on top of the primary plane. For RGB surfaces, only the min + * and mask fields will be used; ranged compares are not allowed. + * + * Destination keying: + * Primary plane pixels that match the min value, masked against the color + * channels specified in the mask field, will be replaced by corresponding + * pixels from the sprite plane. + * + * Note that source & destination keying are exclusive; only one can be + * active on a given plane. + */ + +#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */ +#define I915_SET_COLORKEY_DESTINATION (1<<1) +#define I915_SET_COLORKEY_SOURCE (1<<2) +struct drm_intel_sprite_colorkey { + __u32 plane_id; + __u32 min_value; + __u32 channel_mask; + __u32 max_value; + __u32 flags; +}; + +struct drm_i915_gem_wait { + /** Handle of BO we shall wait on */ + __u32 bo_handle; + __u32 flags; + /** Number of nanoseconds to wait, Returns time remaining. */ + __s64 timeout_ns; +}; + +struct drm_i915_gem_context_create { + /* output: id of new context*/ + __u32 ctx_id; + __u32 pad; +}; + +struct drm_i915_gem_context_destroy { + __u32 ctx_id; + __u32 pad; +}; + +struct drm_i915_reg_read { + /* + * Register offset. + * For 64bit wide registers where the upper 32bits don't immediately + * follow the lower 32bits, the offset of the lower 32bits must + * be specified + */ + __u64 offset; + __u64 val; /* Return value */ +}; +/* Known registers: + * + * Render engine timestamp - 0x2358 + 64bit - gen7+ + * - Note this register returns an invalid value if using the default + * single instruction 8byte read, in order to workaround that use + * offset (0x2538 | 1) instead. + * + */ + +struct drm_i915_reset_stats { + __u32 ctx_id; + __u32 flags; + + /* All resets since boot/module reload, for all contexts */ + __u32 reset_count; + + /* Number of batches lost when active in GPU, for this context */ + __u32 batch_active; + + /* Number of batches lost pending for execution, for this context */ + __u32 batch_pending; + + __u32 pad; +}; + +struct drm_i915_gem_userptr { + __u64 user_ptr; + __u64 user_size; + __u32 flags; +#define I915_USERPTR_READ_ONLY 0x1 +#define I915_USERPTR_UNSYNCHRONIZED 0x80000000 + /** + * Returned handle for the object. + * + * Object handles are nonzero. + */ + __u32 handle; +}; + +struct drm_i915_gem_context_param { + __u32 ctx_id; + __u32 size; + __u64 param; +#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1 +#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2 +#define I915_CONTEXT_PARAM_GTT_SIZE 0x3 +#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4 +#define I915_CONTEXT_PARAM_BANNABLE 0x5 + __u64 value; +}; + +enum drm_i915_oa_format { + I915_OA_FORMAT_A13 = 1, /* HSW only */ + I915_OA_FORMAT_A29, /* HSW only */ + I915_OA_FORMAT_A13_B8_C8, /* HSW only */ + I915_OA_FORMAT_B4_C8, /* HSW only */ + I915_OA_FORMAT_A45_B8_C8, /* HSW only */ + I915_OA_FORMAT_B4_C8_A16, /* HSW only */ + I915_OA_FORMAT_C4_B8, /* HSW+ */ + + /* Gen8+ */ + I915_OA_FORMAT_A12, + I915_OA_FORMAT_A12_B8_C8, + I915_OA_FORMAT_A32u40_A4u32_B8_C8, + + I915_OA_FORMAT_MAX /* non-ABI */ +}; + +enum drm_i915_perf_property_id { + /** + * Open the stream for a specific context handle (as used with + * execbuffer2). A stream opened for a specific context this way + * won't typically require root privileges. + */ + DRM_I915_PERF_PROP_CTX_HANDLE = 1, + + /** + * A value of 1 requests the inclusion of raw OA unit reports as + * part of stream samples. + */ + DRM_I915_PERF_PROP_SAMPLE_OA, + + /** + * The value specifies which set of OA unit metrics should be + * be configured, defining the contents of any OA unit reports. + */ + DRM_I915_PERF_PROP_OA_METRICS_SET, + + /** + * The value specifies the size and layout of OA unit reports. + */ + DRM_I915_PERF_PROP_OA_FORMAT, + + /** + * Specifying this property implicitly requests periodic OA unit + * sampling and (at least on Haswell) the sampling frequency is derived + * from this exponent as follows: + * + * 80ns * 2^(period_exponent + 1) + */ + DRM_I915_PERF_PROP_OA_EXPONENT, + + DRM_I915_PERF_PROP_MAX /* non-ABI */ +}; + +struct drm_i915_perf_open_param { + __u32 flags; +#define I915_PERF_FLAG_FD_CLOEXEC (1<<0) +#define I915_PERF_FLAG_FD_NONBLOCK (1<<1) +#define I915_PERF_FLAG_DISABLED (1<<2) + + /** The number of u64 (id, value) pairs */ + __u32 num_properties; + + /** + * Pointer to array of u64 (id, value) pairs configuring the stream + * to open. + */ + __u64 properties_ptr; +}; + +/** + * Enable data capture for a stream that was either opened in a disabled state + * via I915_PERF_FLAG_DISABLED or was later disabled via + * I915_PERF_IOCTL_DISABLE. + * + * It is intended to be cheaper to disable and enable a stream than it may be + * to close and re-open a stream with the same configuration. + * + * It's undefined whether any pending data for the stream will be lost. + */ +#define I915_PERF_IOCTL_ENABLE _IO('i', 0x0) + +/** + * Disable data capture for a stream. + * + * It is an error to try and read a stream that is disabled. + */ +#define I915_PERF_IOCTL_DISABLE _IO('i', 0x1) + +/** + * Common to all i915 perf records + */ +struct drm_i915_perf_record_header { + __u32 type; + __u16 pad; + __u16 size; +}; + +enum drm_i915_perf_record_type { + + /** + * Samples are the work horse record type whose contents are extensible + * and defined when opening an i915 perf stream based on the given + * properties. + * + * Boolean properties following the naming convention + * DRM_I915_PERF_SAMPLE_xyz_PROP request the inclusion of 'xyz' data in + * every sample. + * + * The order of these sample properties given by userspace has no + * affect on the ordering of data within a sample. The order is + * documented here. + * + * struct { + * struct drm_i915_perf_record_header header; + * + * { u32 oa_report[]; } && DRM_I915_PERF_PROP_SAMPLE_OA + * }; + */ + DRM_I915_PERF_RECORD_SAMPLE = 1, + + /* + * Indicates that one or more OA reports were not written by the + * hardware. This can happen for example if an MI_REPORT_PERF_COUNT + * command collides with periodic sampling - which would be more likely + * at higher sampling frequencies. + */ + DRM_I915_PERF_RECORD_OA_REPORT_LOST = 2, + + /** + * An error occurred that resulted in all pending OA reports being lost. + */ + DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3, + + DRM_I915_PERF_RECORD_MAX /* non-ABI */ +}; + +/** + * Structure to upload perf dynamic configuration into the kernel. + */ +struct drm_i915_perf_oa_config { + /** String formatted like "%08x-%04x-%04x-%04x-%012x" */ + char uuid[36]; + + __u32 n_mux_regs; + __u32 n_boolean_regs; + __u32 n_flex_regs; + + __u64 __user mux_regs_ptr; + __u64 __user boolean_regs_ptr; + __u64 __user flex_regs_ptr; +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* _UAPI_I915_DRM_H_ */ diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index ce2988be4f0eac843de17f563c360a795943f35e..43ab5c402f98f3c2dc15ccc49ec475530a39e401 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -30,9 +30,14 @@ #define BPF_FROM_LE BPF_TO_LE #define BPF_FROM_BE BPF_TO_BE +/* jmp encodings */ #define BPF_JNE 0x50 /* jump != */ +#define BPF_JLT 0xa0 /* LT is unsigned, '<' */ +#define BPF_JLE 0xb0 /* LE is unsigned, '<=' */ #define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ #define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ +#define BPF_JSLT 0xc0 /* SLT is signed, '<' */ +#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */ #define BPF_CALL 0x80 /* function call */ #define BPF_EXIT 0x90 /* function return */ @@ -104,6 +109,8 @@ enum bpf_map_type { BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_ARRAY_OF_MAPS, BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, }; enum bpf_prog_type { @@ -121,6 +128,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_LWT_OUT, BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, }; enum bpf_attach_type { @@ -128,6 +136,8 @@ enum bpf_attach_type { BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, + BPF_SK_SKB_STREAM_PARSER, + BPF_SK_SKB_STREAM_VERDICT, __MAX_BPF_ATTACH_TYPE }; @@ -153,6 +163,7 @@ enum bpf_attach_type { #define BPF_NOEXIST 1 /* create new element if it didn't exist */ #define BPF_EXIST 2 /* update existing element */ +/* flags for BPF_MAP_CREATE command */ #define BPF_F_NO_PREALLOC (1U << 0) /* Instead of having one common LRU list in the * BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list @@ -161,6 +172,8 @@ enum bpf_attach_type { * across different LRU lists. */ #define BPF_F_NO_COMMON_LRU (1U << 1) +/* Specify numa node during map creation */ +#define BPF_F_NUMA_NODE (1U << 2) union bpf_attr { struct { /* anonymous struct used by BPF_MAP_CREATE command */ @@ -168,8 +181,13 @@ union bpf_attr { __u32 key_size; /* size of key in bytes */ __u32 value_size; /* size of value in bytes */ __u32 max_entries; /* max number of entries in a map */ - __u32 map_flags; /* prealloc or not */ + __u32 map_flags; /* BPF_MAP_CREATE related + * flags defined above. + */ __u32 inner_map_fd; /* fd pointing to the inner map */ + __u32 numa_node; /* numa node (effective only if + * BPF_F_NUMA_NODE is set). + */ }; struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ @@ -344,9 +362,20 @@ union bpf_attr { * int bpf_redirect(ifindex, flags) * redirect to another netdev * @ifindex: ifindex of the net device - * @flags: bit 0 - if set, redirect to ingress instead of egress - * other bits - reserved - * Return: TC_ACT_REDIRECT + * @flags: + * cls_bpf: + * bit 0 - if set, redirect to ingress instead of egress + * other bits - reserved + * xdp_bpf: + * all bits - reserved + * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error + * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error + * int bpf_redirect_map(map, key, flags) + * redirect to endpoint in map + * @map: pointer to dev map + * @key: index in map to lookup + * @flags: -- + * Return: XDP_REDIRECT on success or XDP_ABORT on error * * u32 bpf_get_route_realm(skb) * retrieve a dst's tclassid @@ -539,6 +568,20 @@ union bpf_attr { * @mode: operation mode (enum bpf_adj_room_mode) * @flags: reserved for future use * Return: 0 on success or negative error code + * + * int bpf_sk_redirect_map(map, key, flags) + * Redirect skb to a sock in map using key as a lookup key for the + * sock in map. + * @map: pointer to sockmap + * @key: key to lookup sock in map + * @flags: reserved for future use + * Return: SK_REDIRECT + * + * int bpf_sock_map_update(skops, map, key, flags) + * @skops: pointer to bpf_sock_ops + * @map: pointer to sockmap to update + * @key: key to insert/update sock in map + * @flags: same flags as map update elem */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -591,7 +634,10 @@ union bpf_attr { FN(get_socket_uid), \ FN(set_hash), \ FN(setsockopt), \ - FN(skb_adjust_room), + FN(skb_adjust_room), \ + FN(redirect_map), \ + FN(sk_redirect_map), \ + FN(sock_map_update), \ /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call @@ -643,7 +689,7 @@ enum bpf_func_id { /* Mode for BPF_FUNC_skb_adjust_room helper. */ enum bpf_adj_room_mode { - BPF_ADJ_ROOM_NET_OPTS, + BPF_ADJ_ROOM_NET, }; /* user accessible mirror of in-kernel sk_buff. @@ -668,6 +714,15 @@ struct __sk_buff { __u32 data; __u32 data_end; __u32 napi_id; + + /* accessed by BPF_PROG_TYPE_sk_skb types */ + __u32 family; + __u32 remote_ip4; /* Stored in network byte order */ + __u32 local_ip4; /* Stored in network byte order */ + __u32 remote_ip6[4]; /* Stored in network byte order */ + __u32 local_ip6[4]; /* Stored in network byte order */ + __u32 remote_port; /* Stored in network byte order */ + __u32 local_port; /* stored in host byte order */ }; struct bpf_tunnel_key { @@ -703,20 +758,23 @@ struct bpf_sock { __u32 family; __u32 type; __u32 protocol; + __u32 mark; + __u32 priority; }; #define XDP_PACKET_HEADROOM 256 /* User return codes for XDP prog type. * A valid XDP program must return one of these defined values. All other - * return codes are reserved for future use. Unknown return codes will result - * in packet drop. + * return codes are reserved for future use. Unknown return codes will + * result in packet drops and a warning via bpf_warn_invalid_xdp_action(). */ enum xdp_action { XDP_ABORTED = 0, XDP_DROP, XDP_PASS, XDP_TX, + XDP_REDIRECT, }; /* user accessible metadata for XDP packet hook @@ -727,6 +785,12 @@ struct xdp_md { __u32 data_end; }; +enum sk_action { + SK_ABORTED = 0, + SK_DROP, + SK_REDIRECT, +}; + #define BPF_TAG_SIZE 8 struct bpf_prog_info { @@ -750,6 +814,8 @@ struct bpf_map_info { /* User bpf_sock_ops struct to access socket values and specify request ops * and their replies. + * Some of this fields are in network (bigendian) byte order and may need + * to be converted before use (bpf_ntohl() defined in samples/bpf/bpf_endian.h). * New fields can only be added at the end of this structure */ struct bpf_sock_ops { @@ -759,12 +825,12 @@ struct bpf_sock_ops { __u32 replylong[4]; }; __u32 family; - __u32 remote_ip4; - __u32 local_ip4; - __u32 remote_ip6[4]; - __u32 local_ip6[4]; - __u32 remote_port; - __u32 local_port; + __u32 remote_ip4; /* Stored in network byte order */ + __u32 local_ip4; /* Stored in network byte order */ + __u32 remote_ip6[4]; /* Stored in network byte order */ + __u32 local_ip6[4]; /* Stored in network byte order */ + __u32 remote_port; /* Stored in network byte order */ + __u32 local_port; /* stored in host byte order */ }; /* List of known BPF sock_ops operators. diff --git a/tools/include/uapi/linux/fcntl.h b/tools/include/uapi/linux/fcntl.h index 813afd6eee713e68fa4b88e6aabf6aecce1993e1..ec69d55bcec73974d4c44ef1d1555166f28d800f 100644 --- a/tools/include/uapi/linux/fcntl.h +++ b/tools/include/uapi/linux/fcntl.h @@ -42,6 +42,27 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ /* (1U << 31) is reserved for signed error codes */ +/* + * Set/Get write life time hints. {GET,SET}_RW_HINT operate on the + * underlying inode, while {GET,SET}_FILE_RW_HINT operate only on + * the specific file. + */ +#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11) +#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12) +#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13) +#define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14) + +/* + * Valid hint values for F_{GET,SET}_RW_HINT. 0 is "not set", or can be + * used to clear any hints previously set. + */ +#define RWF_WRITE_LIFE_NOT_SET 0 +#define RWH_WRITE_LIFE_NONE 1 +#define RWH_WRITE_LIFE_SHORT 2 +#define RWH_WRITE_LIFE_MEDIUM 3 +#define RWH_WRITE_LIFE_LONG 4 +#define RWH_WRITE_LIFE_EXTREME 5 + /* * Types of directory notifications that may be requested. */ diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h new file mode 100644 index 0000000000000000000000000000000000000000..83888758741184f969f3b8fd1738e38bdc24da78 --- /dev/null +++ b/tools/include/uapi/linux/kvm.h @@ -0,0 +1,1420 @@ +#ifndef __LINUX_KVM_H +#define __LINUX_KVM_H + +/* + * Userspace interface for /dev/kvm - kernel based virtual machine + * + * Note: you must update KVM_API_VERSION if you change this interface. + */ + +#include +#include +#include +#include + +#define KVM_API_VERSION 12 + +/* *** Deprecated interfaces *** */ + +#define KVM_TRC_SHIFT 16 + +#define KVM_TRC_ENTRYEXIT (1 << KVM_TRC_SHIFT) +#define KVM_TRC_HANDLER (1 << (KVM_TRC_SHIFT + 1)) + +#define KVM_TRC_VMENTRY (KVM_TRC_ENTRYEXIT + 0x01) +#define KVM_TRC_VMEXIT (KVM_TRC_ENTRYEXIT + 0x02) +#define KVM_TRC_PAGE_FAULT (KVM_TRC_HANDLER + 0x01) + +#define KVM_TRC_HEAD_SIZE 12 +#define KVM_TRC_CYCLE_SIZE 8 +#define KVM_TRC_EXTRA_MAX 7 + +#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) +#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) +#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04) +#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05) +#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06) +#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07) +#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08) +#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09) +#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A) +#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B) +#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C) +#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D) +#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E) +#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F) +#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10) +#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11) +#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12) +#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13) +#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) +#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15) +#define KVM_TRC_GTLB_WRITE (KVM_TRC_HANDLER + 0x16) +#define KVM_TRC_STLB_WRITE (KVM_TRC_HANDLER + 0x17) +#define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18) +#define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19) + +struct kvm_user_trace_setup { + __u32 buf_size; + __u32 buf_nr; +}; + +#define __KVM_DEPRECATED_MAIN_W_0x06 \ + _IOW(KVMIO, 0x06, struct kvm_user_trace_setup) +#define __KVM_DEPRECATED_MAIN_0x07 _IO(KVMIO, 0x07) +#define __KVM_DEPRECATED_MAIN_0x08 _IO(KVMIO, 0x08) + +#define __KVM_DEPRECATED_VM_R_0x70 _IOR(KVMIO, 0x70, struct kvm_assigned_irq) + +struct kvm_breakpoint { + __u32 enabled; + __u32 padding; + __u64 address; +}; + +struct kvm_debug_guest { + __u32 enabled; + __u32 pad; + struct kvm_breakpoint breakpoints[4]; + __u32 singlestep; +}; + +#define __KVM_DEPRECATED_VCPU_W_0x87 _IOW(KVMIO, 0x87, struct kvm_debug_guest) + +/* *** End of deprecated interfaces *** */ + + +/* for KVM_CREATE_MEMORY_REGION */ +struct kvm_memory_region { + __u32 slot; + __u32 flags; + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ +}; + +/* for KVM_SET_USER_MEMORY_REGION */ +struct kvm_userspace_memory_region { + __u32 slot; + __u32 flags; + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ + __u64 userspace_addr; /* start of the userspace allocated memory */ +}; + +/* + * The bit 0 ~ bit 15 of kvm_memory_region::flags are visible for userspace, + * other bits are reserved for kvm internal use which are defined in + * include/linux/kvm_host.h. + */ +#define KVM_MEM_LOG_DIRTY_PAGES (1UL << 0) +#define KVM_MEM_READONLY (1UL << 1) + +/* for KVM_IRQ_LINE */ +struct kvm_irq_level { + /* + * ACPI gsi notion of irq. + * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47.. + * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23.. + * For ARM: See Documentation/virtual/kvm/api.txt + */ + union { + __u32 irq; + __s32 status; + }; + __u32 level; +}; + + +struct kvm_irqchip { + __u32 chip_id; + __u32 pad; + union { + char dummy[512]; /* reserving space */ +#ifdef __KVM_HAVE_PIT + struct kvm_pic_state pic; +#endif +#ifdef __KVM_HAVE_IOAPIC + struct kvm_ioapic_state ioapic; +#endif + } chip; +}; + +/* for KVM_CREATE_PIT2 */ +struct kvm_pit_config { + __u32 flags; + __u32 pad[15]; +}; + +#define KVM_PIT_SPEAKER_DUMMY 1 + +struct kvm_s390_skeys { + __u64 start_gfn; + __u64 count; + __u64 skeydata_addr; + __u32 flags; + __u32 reserved[9]; +}; + +#define KVM_S390_CMMA_PEEK (1 << 0) + +/** + * kvm_s390_cmma_log - Used for CMMA migration. + * + * Used both for input and output. + * + * @start_gfn: Guest page number to start from. + * @count: Size of the result buffer. + * @flags: Control operation mode via KVM_S390_CMMA_* flags + * @remaining: Used with KVM_S390_GET_CMMA_BITS. Indicates how many dirty + * pages are still remaining. + * @mask: Used with KVM_S390_SET_CMMA_BITS. Bitmap of bits to actually set + * in the PGSTE. + * @values: Pointer to the values buffer. + * + * Used in KVM_S390_{G,S}ET_CMMA_BITS ioctls. + */ +struct kvm_s390_cmma_log { + __u64 start_gfn; + __u32 count; + __u32 flags; + union { + __u64 remaining; + __u64 mask; + }; + __u64 values; +}; + +struct kvm_hyperv_exit { +#define KVM_EXIT_HYPERV_SYNIC 1 +#define KVM_EXIT_HYPERV_HCALL 2 + __u32 type; + union { + struct { + __u32 msr; + __u64 control; + __u64 evt_page; + __u64 msg_page; + } synic; + struct { + __u64 input; + __u64 result; + __u64 params[2]; + } hcall; + } u; +}; + +#define KVM_S390_GET_SKEYS_NONE 1 +#define KVM_S390_SKEYS_MAX 1048576 + +#define KVM_EXIT_UNKNOWN 0 +#define KVM_EXIT_EXCEPTION 1 +#define KVM_EXIT_IO 2 +#define KVM_EXIT_HYPERCALL 3 +#define KVM_EXIT_DEBUG 4 +#define KVM_EXIT_HLT 5 +#define KVM_EXIT_MMIO 6 +#define KVM_EXIT_IRQ_WINDOW_OPEN 7 +#define KVM_EXIT_SHUTDOWN 8 +#define KVM_EXIT_FAIL_ENTRY 9 +#define KVM_EXIT_INTR 10 +#define KVM_EXIT_SET_TPR 11 +#define KVM_EXIT_TPR_ACCESS 12 +#define KVM_EXIT_S390_SIEIC 13 +#define KVM_EXIT_S390_RESET 14 +#define KVM_EXIT_DCR 15 /* deprecated */ +#define KVM_EXIT_NMI 16 +#define KVM_EXIT_INTERNAL_ERROR 17 +#define KVM_EXIT_OSI 18 +#define KVM_EXIT_PAPR_HCALL 19 +#define KVM_EXIT_S390_UCONTROL 20 +#define KVM_EXIT_WATCHDOG 21 +#define KVM_EXIT_S390_TSCH 22 +#define KVM_EXIT_EPR 23 +#define KVM_EXIT_SYSTEM_EVENT 24 +#define KVM_EXIT_S390_STSI 25 +#define KVM_EXIT_IOAPIC_EOI 26 +#define KVM_EXIT_HYPERV 27 + +/* For KVM_EXIT_INTERNAL_ERROR */ +/* Emulate instruction failed. */ +#define KVM_INTERNAL_ERROR_EMULATION 1 +/* Encounter unexpected simultaneous exceptions. */ +#define KVM_INTERNAL_ERROR_SIMUL_EX 2 +/* Encounter unexpected vm-exit due to delivery event. */ +#define KVM_INTERNAL_ERROR_DELIVERY_EV 3 + +/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ +struct kvm_run { + /* in */ + __u8 request_interrupt_window; + __u8 immediate_exit; + __u8 padding1[6]; + + /* out */ + __u32 exit_reason; + __u8 ready_for_interrupt_injection; + __u8 if_flag; + __u16 flags; + + /* in (pre_kvm_run), out (post_kvm_run) */ + __u64 cr8; + __u64 apic_base; + +#ifdef __KVM_S390 + /* the processor status word for s390 */ + __u64 psw_mask; /* psw upper half */ + __u64 psw_addr; /* psw lower half */ +#endif + union { + /* KVM_EXIT_UNKNOWN */ + struct { + __u64 hardware_exit_reason; + } hw; + /* KVM_EXIT_FAIL_ENTRY */ + struct { + __u64 hardware_entry_failure_reason; + } fail_entry; + /* KVM_EXIT_EXCEPTION */ + struct { + __u32 exception; + __u32 error_code; + } ex; + /* KVM_EXIT_IO */ + struct { +#define KVM_EXIT_IO_IN 0 +#define KVM_EXIT_IO_OUT 1 + __u8 direction; + __u8 size; /* bytes */ + __u16 port; + __u32 count; + __u64 data_offset; /* relative to kvm_run start */ + } io; + /* KVM_EXIT_DEBUG */ + struct { + struct kvm_debug_exit_arch arch; + } debug; + /* KVM_EXIT_MMIO */ + struct { + __u64 phys_addr; + __u8 data[8]; + __u32 len; + __u8 is_write; + } mmio; + /* KVM_EXIT_HYPERCALL */ + struct { + __u64 nr; + __u64 args[6]; + __u64 ret; + __u32 longmode; + __u32 pad; + } hypercall; + /* KVM_EXIT_TPR_ACCESS */ + struct { + __u64 rip; + __u32 is_write; + __u32 pad; + } tpr_access; + /* KVM_EXIT_S390_SIEIC */ + struct { + __u8 icptcode; + __u16 ipa; + __u32 ipb; + } s390_sieic; + /* KVM_EXIT_S390_RESET */ +#define KVM_S390_RESET_POR 1 +#define KVM_S390_RESET_CLEAR 2 +#define KVM_S390_RESET_SUBSYSTEM 4 +#define KVM_S390_RESET_CPU_INIT 8 +#define KVM_S390_RESET_IPL 16 + __u64 s390_reset_flags; + /* KVM_EXIT_S390_UCONTROL */ + struct { + __u64 trans_exc_code; + __u32 pgm_code; + } s390_ucontrol; + /* KVM_EXIT_DCR (deprecated) */ + struct { + __u32 dcrn; + __u32 data; + __u8 is_write; + } dcr; + /* KVM_EXIT_INTERNAL_ERROR */ + struct { + __u32 suberror; + /* Available with KVM_CAP_INTERNAL_ERROR_DATA: */ + __u32 ndata; + __u64 data[16]; + } internal; + /* KVM_EXIT_OSI */ + struct { + __u64 gprs[32]; + } osi; + /* KVM_EXIT_PAPR_HCALL */ + struct { + __u64 nr; + __u64 ret; + __u64 args[9]; + } papr_hcall; + /* KVM_EXIT_S390_TSCH */ + struct { + __u16 subchannel_id; + __u16 subchannel_nr; + __u32 io_int_parm; + __u32 io_int_word; + __u32 ipb; + __u8 dequeued; + } s390_tsch; + /* KVM_EXIT_EPR */ + struct { + __u32 epr; + } epr; + /* KVM_EXIT_SYSTEM_EVENT */ + struct { +#define KVM_SYSTEM_EVENT_SHUTDOWN 1 +#define KVM_SYSTEM_EVENT_RESET 2 +#define KVM_SYSTEM_EVENT_CRASH 3 + __u32 type; + __u64 flags; + } system_event; + /* KVM_EXIT_S390_STSI */ + struct { + __u64 addr; + __u8 ar; + __u8 reserved; + __u8 fc; + __u8 sel1; + __u16 sel2; + } s390_stsi; + /* KVM_EXIT_IOAPIC_EOI */ + struct { + __u8 vector; + } eoi; + /* KVM_EXIT_HYPERV */ + struct kvm_hyperv_exit hyperv; + /* Fix the size of the union. */ + char padding[256]; + }; + + /* + * shared registers between kvm and userspace. + * kvm_valid_regs specifies the register classes set by the host + * kvm_dirty_regs specified the register classes dirtied by userspace + * struct kvm_sync_regs is architecture specific, as well as the + * bits for kvm_valid_regs and kvm_dirty_regs + */ + __u64 kvm_valid_regs; + __u64 kvm_dirty_regs; + union { + struct kvm_sync_regs regs; + char padding[2048]; + } s; +}; + +/* for KVM_REGISTER_COALESCED_MMIO / KVM_UNREGISTER_COALESCED_MMIO */ + +struct kvm_coalesced_mmio_zone { + __u64 addr; + __u32 size; + __u32 pad; +}; + +struct kvm_coalesced_mmio { + __u64 phys_addr; + __u32 len; + __u32 pad; + __u8 data[8]; +}; + +struct kvm_coalesced_mmio_ring { + __u32 first, last; + struct kvm_coalesced_mmio coalesced_mmio[0]; +}; + +#define KVM_COALESCED_MMIO_MAX \ + ((PAGE_SIZE - sizeof(struct kvm_coalesced_mmio_ring)) / \ + sizeof(struct kvm_coalesced_mmio)) + +/* for KVM_TRANSLATE */ +struct kvm_translation { + /* in */ + __u64 linear_address; + + /* out */ + __u64 physical_address; + __u8 valid; + __u8 writeable; + __u8 usermode; + __u8 pad[5]; +}; + +/* for KVM_S390_MEM_OP */ +struct kvm_s390_mem_op { + /* in */ + __u64 gaddr; /* the guest address */ + __u64 flags; /* flags */ + __u32 size; /* amount of bytes */ + __u32 op; /* type of operation */ + __u64 buf; /* buffer in userspace */ + __u8 ar; /* the access register number */ + __u8 reserved[31]; /* should be set to 0 */ +}; +/* types for kvm_s390_mem_op->op */ +#define KVM_S390_MEMOP_LOGICAL_READ 0 +#define KVM_S390_MEMOP_LOGICAL_WRITE 1 +/* flags for kvm_s390_mem_op->flags */ +#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0) +#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1) + +/* for KVM_INTERRUPT */ +struct kvm_interrupt { + /* in */ + __u32 irq; +}; + +/* for KVM_GET_DIRTY_LOG */ +struct kvm_dirty_log { + __u32 slot; + __u32 padding1; + union { + void __user *dirty_bitmap; /* one bit per page */ + __u64 padding2; + }; +}; + +/* for KVM_SET_SIGNAL_MASK */ +struct kvm_signal_mask { + __u32 len; + __u8 sigset[0]; +}; + +/* for KVM_TPR_ACCESS_REPORTING */ +struct kvm_tpr_access_ctl { + __u32 enabled; + __u32 flags; + __u32 reserved[8]; +}; + +/* for KVM_SET_VAPIC_ADDR */ +struct kvm_vapic_addr { + __u64 vapic_addr; +}; + +/* for KVM_SET_MP_STATE */ + +/* not all states are valid on all architectures */ +#define KVM_MP_STATE_RUNNABLE 0 +#define KVM_MP_STATE_UNINITIALIZED 1 +#define KVM_MP_STATE_INIT_RECEIVED 2 +#define KVM_MP_STATE_HALTED 3 +#define KVM_MP_STATE_SIPI_RECEIVED 4 +#define KVM_MP_STATE_STOPPED 5 +#define KVM_MP_STATE_CHECK_STOP 6 +#define KVM_MP_STATE_OPERATING 7 +#define KVM_MP_STATE_LOAD 8 + +struct kvm_mp_state { + __u32 mp_state; +}; + +struct kvm_s390_psw { + __u64 mask; + __u64 addr; +}; + +/* valid values for type in kvm_s390_interrupt */ +#define KVM_S390_SIGP_STOP 0xfffe0000u +#define KVM_S390_PROGRAM_INT 0xfffe0001u +#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u +#define KVM_S390_RESTART 0xfffe0003u +#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u +#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u +#define KVM_S390_MCHK 0xfffe1000u +#define KVM_S390_INT_CLOCK_COMP 0xffff1004u +#define KVM_S390_INT_CPU_TIMER 0xffff1005u +#define KVM_S390_INT_VIRTIO 0xffff2603u +#define KVM_S390_INT_SERVICE 0xffff2401u +#define KVM_S390_INT_EMERGENCY 0xffff1201u +#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u +/* Anything below 0xfffe0000u is taken by INT_IO */ +#define KVM_S390_INT_IO(ai,cssid,ssid,schid) \ + (((schid)) | \ + ((ssid) << 16) | \ + ((cssid) << 18) | \ + ((ai) << 26)) +#define KVM_S390_INT_IO_MIN 0x00000000u +#define KVM_S390_INT_IO_MAX 0xfffdffffu +#define KVM_S390_INT_IO_AI_MASK 0x04000000u + + +struct kvm_s390_interrupt { + __u32 type; + __u32 parm; + __u64 parm64; +}; + +struct kvm_s390_io_info { + __u16 subchannel_id; + __u16 subchannel_nr; + __u32 io_int_parm; + __u32 io_int_word; +}; + +struct kvm_s390_ext_info { + __u32 ext_params; + __u32 pad; + __u64 ext_params2; +}; + +struct kvm_s390_pgm_info { + __u64 trans_exc_code; + __u64 mon_code; + __u64 per_address; + __u32 data_exc_code; + __u16 code; + __u16 mon_class_nr; + __u8 per_code; + __u8 per_atmid; + __u8 exc_access_id; + __u8 per_access_id; + __u8 op_access_id; +#define KVM_S390_PGM_FLAGS_ILC_VALID 0x01 +#define KVM_S390_PGM_FLAGS_ILC_0 0x02 +#define KVM_S390_PGM_FLAGS_ILC_1 0x04 +#define KVM_S390_PGM_FLAGS_ILC_MASK 0x06 +#define KVM_S390_PGM_FLAGS_NO_REWIND 0x08 + __u8 flags; + __u8 pad[2]; +}; + +struct kvm_s390_prefix_info { + __u32 address; +}; + +struct kvm_s390_extcall_info { + __u16 code; +}; + +struct kvm_s390_emerg_info { + __u16 code; +}; + +#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01 +struct kvm_s390_stop_info { + __u32 flags; +}; + +struct kvm_s390_mchk_info { + __u64 cr14; + __u64 mcic; + __u64 failing_storage_address; + __u32 ext_damage_code; + __u32 pad; + __u8 fixed_logout[16]; +}; + +struct kvm_s390_irq { + __u64 type; + union { + struct kvm_s390_io_info io; + struct kvm_s390_ext_info ext; + struct kvm_s390_pgm_info pgm; + struct kvm_s390_emerg_info emerg; + struct kvm_s390_extcall_info extcall; + struct kvm_s390_prefix_info prefix; + struct kvm_s390_stop_info stop; + struct kvm_s390_mchk_info mchk; + char reserved[64]; + } u; +}; + +struct kvm_s390_irq_state { + __u64 buf; + __u32 flags; + __u32 len; + __u32 reserved[4]; +}; + +/* for KVM_SET_GUEST_DEBUG */ + +#define KVM_GUESTDBG_ENABLE 0x00000001 +#define KVM_GUESTDBG_SINGLESTEP 0x00000002 + +struct kvm_guest_debug { + __u32 control; + __u32 pad; + struct kvm_guest_debug_arch arch; +}; + +enum { + kvm_ioeventfd_flag_nr_datamatch, + kvm_ioeventfd_flag_nr_pio, + kvm_ioeventfd_flag_nr_deassign, + kvm_ioeventfd_flag_nr_virtio_ccw_notify, + kvm_ioeventfd_flag_nr_fast_mmio, + kvm_ioeventfd_flag_nr_max, +}; + +#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) +#define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) +#define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) + +#define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1) + +struct kvm_ioeventfd { + __u64 datamatch; + __u64 addr; /* legal pio/mmio address */ + __u32 len; /* 1, 2, 4, or 8 bytes; or 0 to ignore length */ + __s32 fd; + __u32 flags; + __u8 pad[36]; +}; + +/* for KVM_ENABLE_CAP */ +struct kvm_enable_cap { + /* in */ + __u32 cap; + __u32 flags; + __u64 args[4]; + __u8 pad[64]; +}; + +/* for KVM_PPC_GET_PVINFO */ + +#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) + +struct kvm_ppc_pvinfo { + /* out */ + __u32 flags; + __u32 hcall[4]; + __u8 pad[108]; +}; + +/* for KVM_PPC_GET_SMMU_INFO */ +#define KVM_PPC_PAGE_SIZES_MAX_SZ 8 + +struct kvm_ppc_one_page_size { + __u32 page_shift; /* Page shift (or 0) */ + __u32 pte_enc; /* Encoding in the HPTE (>>12) */ +}; + +struct kvm_ppc_one_seg_page_size { + __u32 page_shift; /* Base page shift of segment (or 0) */ + __u32 slb_enc; /* SLB encoding for BookS */ + struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ]; +}; + +#define KVM_PPC_PAGE_SIZES_REAL 0x00000001 +#define KVM_PPC_1T_SEGMENTS 0x00000002 + +struct kvm_ppc_smmu_info { + __u64 flags; + __u32 slb_size; + __u16 data_keys; /* # storage keys supported for data */ + __u16 instr_keys; /* # storage keys supported for instructions */ + struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; +}; + +/* for KVM_PPC_RESIZE_HPT_{PREPARE,COMMIT} */ +struct kvm_ppc_resize_hpt { + __u64 flags; + __u32 shift; + __u32 pad; +}; + +#define KVMIO 0xAE + +/* machine type bits, to be used as argument to KVM_CREATE_VM */ +#define KVM_VM_S390_UCONTROL 1 + +/* on ppc, 0 indicate default, 1 should force HV and 2 PR */ +#define KVM_VM_PPC_HV 1 +#define KVM_VM_PPC_PR 2 + +/* on MIPS, 0 forces trap & emulate, 1 forces VZ ASE */ +#define KVM_VM_MIPS_TE 0 +#define KVM_VM_MIPS_VZ 1 + +#define KVM_S390_SIE_PAGE_OFFSET 1 + +/* + * ioctls for /dev/kvm fds: + */ +#define KVM_GET_API_VERSION _IO(KVMIO, 0x00) +#define KVM_CREATE_VM _IO(KVMIO, 0x01) /* returns a VM fd */ +#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 0x02, struct kvm_msr_list) + +#define KVM_S390_ENABLE_SIE _IO(KVMIO, 0x06) +/* + * Check if a kvm extension is available. Argument is extension number, + * return is 1 (yes) or 0 (no, sorry). + */ +#define KVM_CHECK_EXTENSION _IO(KVMIO, 0x03) +/* + * Get size for mmap(vcpu_fd) + */ +#define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */ +#define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2) +#define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06 +#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 +#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 +#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2) + +/* + * Extension capability list. + */ +#define KVM_CAP_IRQCHIP 0 +#define KVM_CAP_HLT 1 +#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2 +#define KVM_CAP_USER_MEMORY 3 +#define KVM_CAP_SET_TSS_ADDR 4 +#define KVM_CAP_VAPIC 6 +#define KVM_CAP_EXT_CPUID 7 +#define KVM_CAP_CLOCKSOURCE 8 +#define KVM_CAP_NR_VCPUS 9 /* returns recommended max vcpus per vm */ +#define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ +#define KVM_CAP_PIT 11 +#define KVM_CAP_NOP_IO_DELAY 12 +#define KVM_CAP_PV_MMU 13 +#define KVM_CAP_MP_STATE 14 +#define KVM_CAP_COALESCED_MMIO 15 +#define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ +#define KVM_CAP_IOMMU 18 +/* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ +#define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 +#define KVM_CAP_USER_NMI 22 +#ifdef __KVM_HAVE_GUEST_DEBUG +#define KVM_CAP_SET_GUEST_DEBUG 23 +#endif +#ifdef __KVM_HAVE_PIT +#define KVM_CAP_REINJECT_CONTROL 24 +#endif +#define KVM_CAP_IRQ_ROUTING 25 +#define KVM_CAP_IRQ_INJECT_STATUS 26 +#define KVM_CAP_ASSIGN_DEV_IRQ 29 +/* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */ +#define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30 +#ifdef __KVM_HAVE_MCE +#define KVM_CAP_MCE 31 +#endif +#define KVM_CAP_IRQFD 32 +#ifdef __KVM_HAVE_PIT +#define KVM_CAP_PIT2 33 +#endif +#define KVM_CAP_SET_BOOT_CPU_ID 34 +#ifdef __KVM_HAVE_PIT_STATE2 +#define KVM_CAP_PIT_STATE2 35 +#endif +#define KVM_CAP_IOEVENTFD 36 +#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37 +#ifdef __KVM_HAVE_XEN_HVM +#define KVM_CAP_XEN_HVM 38 +#endif +#define KVM_CAP_ADJUST_CLOCK 39 +#define KVM_CAP_INTERNAL_ERROR_DATA 40 +#ifdef __KVM_HAVE_VCPU_EVENTS +#define KVM_CAP_VCPU_EVENTS 41 +#endif +#define KVM_CAP_S390_PSW 42 +#define KVM_CAP_PPC_SEGSTATE 43 +#define KVM_CAP_HYPERV 44 +#define KVM_CAP_HYPERV_VAPIC 45 +#define KVM_CAP_HYPERV_SPIN 46 +#define KVM_CAP_PCI_SEGMENT 47 +#define KVM_CAP_PPC_PAIRED_SINGLES 48 +#define KVM_CAP_INTR_SHADOW 49 +#ifdef __KVM_HAVE_DEBUGREGS +#define KVM_CAP_DEBUGREGS 50 +#endif +#define KVM_CAP_X86_ROBUST_SINGLESTEP 51 +#define KVM_CAP_PPC_OSI 52 +#define KVM_CAP_PPC_UNSET_IRQ 53 +#define KVM_CAP_ENABLE_CAP 54 +#ifdef __KVM_HAVE_XSAVE +#define KVM_CAP_XSAVE 55 +#endif +#ifdef __KVM_HAVE_XCRS +#define KVM_CAP_XCRS 56 +#endif +#define KVM_CAP_PPC_GET_PVINFO 57 +#define KVM_CAP_PPC_IRQ_LEVEL 58 +#define KVM_CAP_ASYNC_PF 59 +#define KVM_CAP_TSC_CONTROL 60 +#define KVM_CAP_GET_TSC_KHZ 61 +#define KVM_CAP_PPC_BOOKE_SREGS 62 +#define KVM_CAP_SPAPR_TCE 63 +#define KVM_CAP_PPC_SMT 64 +#define KVM_CAP_PPC_RMA 65 +#define KVM_CAP_MAX_VCPUS 66 /* returns max vcpus per vm */ +#define KVM_CAP_PPC_HIOR 67 +#define KVM_CAP_PPC_PAPR 68 +#define KVM_CAP_SW_TLB 69 +#define KVM_CAP_ONE_REG 70 +#define KVM_CAP_S390_GMAP 71 +#define KVM_CAP_TSC_DEADLINE_TIMER 72 +#define KVM_CAP_S390_UCONTROL 73 +#define KVM_CAP_SYNC_REGS 74 +#define KVM_CAP_PCI_2_3 75 +#define KVM_CAP_KVMCLOCK_CTRL 76 +#define KVM_CAP_SIGNAL_MSI 77 +#define KVM_CAP_PPC_GET_SMMU_INFO 78 +#define KVM_CAP_S390_COW 79 +#define KVM_CAP_PPC_ALLOC_HTAB 80 +#define KVM_CAP_READONLY_MEM 81 +#define KVM_CAP_IRQFD_RESAMPLE 82 +#define KVM_CAP_PPC_BOOKE_WATCHDOG 83 +#define KVM_CAP_PPC_HTAB_FD 84 +#define KVM_CAP_S390_CSS_SUPPORT 85 +#define KVM_CAP_PPC_EPR 86 +#define KVM_CAP_ARM_PSCI 87 +#define KVM_CAP_ARM_SET_DEVICE_ADDR 88 +#define KVM_CAP_DEVICE_CTRL 89 +#define KVM_CAP_IRQ_MPIC 90 +#define KVM_CAP_PPC_RTAS 91 +#define KVM_CAP_IRQ_XICS 92 +#define KVM_CAP_ARM_EL1_32BIT 93 +#define KVM_CAP_SPAPR_MULTITCE 94 +#define KVM_CAP_EXT_EMUL_CPUID 95 +#define KVM_CAP_HYPERV_TIME 96 +#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97 +#define KVM_CAP_ENABLE_CAP_VM 98 +#define KVM_CAP_S390_IRQCHIP 99 +#define KVM_CAP_IOEVENTFD_NO_LENGTH 100 +#define KVM_CAP_VM_ATTRIBUTES 101 +#define KVM_CAP_ARM_PSCI_0_2 102 +#define KVM_CAP_PPC_FIXUP_HCALL 103 +#define KVM_CAP_PPC_ENABLE_HCALL 104 +#define KVM_CAP_CHECK_EXTENSION_VM 105 +#define KVM_CAP_S390_USER_SIGP 106 +#define KVM_CAP_S390_VECTOR_REGISTERS 107 +#define KVM_CAP_S390_MEM_OP 108 +#define KVM_CAP_S390_USER_STSI 109 +#define KVM_CAP_S390_SKEYS 110 +#define KVM_CAP_MIPS_FPU 111 +#define KVM_CAP_MIPS_MSA 112 +#define KVM_CAP_S390_INJECT_IRQ 113 +#define KVM_CAP_S390_IRQ_STATE 114 +#define KVM_CAP_PPC_HWRNG 115 +#define KVM_CAP_DISABLE_QUIRKS 116 +#define KVM_CAP_X86_SMM 117 +#define KVM_CAP_MULTI_ADDRESS_SPACE 118 +#define KVM_CAP_GUEST_DEBUG_HW_BPS 119 +#define KVM_CAP_GUEST_DEBUG_HW_WPS 120 +#define KVM_CAP_SPLIT_IRQCHIP 121 +#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122 +#define KVM_CAP_HYPERV_SYNIC 123 +#define KVM_CAP_S390_RI 124 +#define KVM_CAP_SPAPR_TCE_64 125 +#define KVM_CAP_ARM_PMU_V3 126 +#define KVM_CAP_VCPU_ATTRIBUTES 127 +#define KVM_CAP_MAX_VCPU_ID 128 +#define KVM_CAP_X2APIC_API 129 +#define KVM_CAP_S390_USER_INSTR0 130 +#define KVM_CAP_MSI_DEVID 131 +#define KVM_CAP_PPC_HTM 132 +#define KVM_CAP_SPAPR_RESIZE_HPT 133 +#define KVM_CAP_PPC_MMU_RADIX 134 +#define KVM_CAP_PPC_MMU_HASH_V3 135 +#define KVM_CAP_IMMEDIATE_EXIT 136 +#define KVM_CAP_MIPS_VZ 137 +#define KVM_CAP_MIPS_TE 138 +#define KVM_CAP_MIPS_64BIT 139 +#define KVM_CAP_S390_GS 140 +#define KVM_CAP_S390_AIS 141 +#define KVM_CAP_SPAPR_TCE_VFIO 142 +#define KVM_CAP_X86_GUEST_MWAIT 143 +#define KVM_CAP_ARM_USER_IRQ 144 +#define KVM_CAP_S390_CMMA_MIGRATION 145 +#define KVM_CAP_PPC_FWNMI 146 +#define KVM_CAP_PPC_SMT_POSSIBLE 147 +#define KVM_CAP_HYPERV_SYNIC2 148 +#define KVM_CAP_HYPERV_VP_INDEX 149 + +#ifdef KVM_CAP_IRQ_ROUTING + +struct kvm_irq_routing_irqchip { + __u32 irqchip; + __u32 pin; +}; + +struct kvm_irq_routing_msi { + __u32 address_lo; + __u32 address_hi; + __u32 data; + union { + __u32 pad; + __u32 devid; + }; +}; + +struct kvm_irq_routing_s390_adapter { + __u64 ind_addr; + __u64 summary_addr; + __u64 ind_offset; + __u32 summary_offset; + __u32 adapter_id; +}; + +struct kvm_irq_routing_hv_sint { + __u32 vcpu; + __u32 sint; +}; + +/* gsi routing entry types */ +#define KVM_IRQ_ROUTING_IRQCHIP 1 +#define KVM_IRQ_ROUTING_MSI 2 +#define KVM_IRQ_ROUTING_S390_ADAPTER 3 +#define KVM_IRQ_ROUTING_HV_SINT 4 + +struct kvm_irq_routing_entry { + __u32 gsi; + __u32 type; + __u32 flags; + __u32 pad; + union { + struct kvm_irq_routing_irqchip irqchip; + struct kvm_irq_routing_msi msi; + struct kvm_irq_routing_s390_adapter adapter; + struct kvm_irq_routing_hv_sint hv_sint; + __u32 pad[8]; + } u; +}; + +struct kvm_irq_routing { + __u32 nr; + __u32 flags; + struct kvm_irq_routing_entry entries[0]; +}; + +#endif + +#ifdef KVM_CAP_MCE +/* x86 MCE */ +struct kvm_x86_mce { + __u64 status; + __u64 addr; + __u64 misc; + __u64 mcg_status; + __u8 bank; + __u8 pad1[7]; + __u64 pad2[3]; +}; +#endif + +#ifdef KVM_CAP_XEN_HVM +struct kvm_xen_hvm_config { + __u32 flags; + __u32 msr; + __u64 blob_addr_32; + __u64 blob_addr_64; + __u8 blob_size_32; + __u8 blob_size_64; + __u8 pad2[30]; +}; +#endif + +#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) +/* + * Available with KVM_CAP_IRQFD_RESAMPLE + * + * KVM_IRQFD_FLAG_RESAMPLE indicates resamplefd is valid and specifies + * the irqfd to operate in resampling mode for level triggered interrupt + * emulation. See Documentation/virtual/kvm/api.txt. + */ +#define KVM_IRQFD_FLAG_RESAMPLE (1 << 1) + +struct kvm_irqfd { + __u32 fd; + __u32 gsi; + __u32 flags; + __u32 resamplefd; + __u8 pad[16]; +}; + +/* For KVM_CAP_ADJUST_CLOCK */ + +/* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags. */ +#define KVM_CLOCK_TSC_STABLE 2 + +struct kvm_clock_data { + __u64 clock; + __u32 flags; + __u32 pad[9]; +}; + +/* For KVM_CAP_SW_TLB */ + +#define KVM_MMU_FSL_BOOKE_NOHV 0 +#define KVM_MMU_FSL_BOOKE_HV 1 + +struct kvm_config_tlb { + __u64 params; + __u64 array; + __u32 mmu_type; + __u32 array_len; +}; + +struct kvm_dirty_tlb { + __u64 bitmap; + __u32 num_dirty; +}; + +/* Available with KVM_CAP_ONE_REG */ + +#define KVM_REG_ARCH_MASK 0xff00000000000000ULL +#define KVM_REG_GENERIC 0x0000000000000000ULL + +/* + * Architecture specific registers are to be defined in arch headers and + * ORed with the arch identifier. + */ +#define KVM_REG_PPC 0x1000000000000000ULL +#define KVM_REG_X86 0x2000000000000000ULL +#define KVM_REG_IA64 0x3000000000000000ULL +#define KVM_REG_ARM 0x4000000000000000ULL +#define KVM_REG_S390 0x5000000000000000ULL +#define KVM_REG_ARM64 0x6000000000000000ULL +#define KVM_REG_MIPS 0x7000000000000000ULL + +#define KVM_REG_SIZE_SHIFT 52 +#define KVM_REG_SIZE_MASK 0x00f0000000000000ULL +#define KVM_REG_SIZE_U8 0x0000000000000000ULL +#define KVM_REG_SIZE_U16 0x0010000000000000ULL +#define KVM_REG_SIZE_U32 0x0020000000000000ULL +#define KVM_REG_SIZE_U64 0x0030000000000000ULL +#define KVM_REG_SIZE_U128 0x0040000000000000ULL +#define KVM_REG_SIZE_U256 0x0050000000000000ULL +#define KVM_REG_SIZE_U512 0x0060000000000000ULL +#define KVM_REG_SIZE_U1024 0x0070000000000000ULL + +struct kvm_reg_list { + __u64 n; /* number of regs */ + __u64 reg[0]; +}; + +struct kvm_one_reg { + __u64 id; + __u64 addr; +}; + +#define KVM_MSI_VALID_DEVID (1U << 0) +struct kvm_msi { + __u32 address_lo; + __u32 address_hi; + __u32 data; + __u32 flags; + __u32 devid; + __u8 pad[12]; +}; + +struct kvm_arm_device_addr { + __u64 id; + __u64 addr; +}; + +/* + * Device control API, available with KVM_CAP_DEVICE_CTRL + */ +#define KVM_CREATE_DEVICE_TEST 1 + +struct kvm_create_device { + __u32 type; /* in: KVM_DEV_TYPE_xxx */ + __u32 fd; /* out: device handle */ + __u32 flags; /* in: KVM_CREATE_DEVICE_xxx */ +}; + +struct kvm_device_attr { + __u32 flags; /* no flags currently defined */ + __u32 group; /* device-defined */ + __u64 attr; /* group-defined */ + __u64 addr; /* userspace address of attr data */ +}; + +#define KVM_DEV_VFIO_GROUP 1 +#define KVM_DEV_VFIO_GROUP_ADD 1 +#define KVM_DEV_VFIO_GROUP_DEL 2 +#define KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE 3 + +enum kvm_device_type { + KVM_DEV_TYPE_FSL_MPIC_20 = 1, +#define KVM_DEV_TYPE_FSL_MPIC_20 KVM_DEV_TYPE_FSL_MPIC_20 + KVM_DEV_TYPE_FSL_MPIC_42, +#define KVM_DEV_TYPE_FSL_MPIC_42 KVM_DEV_TYPE_FSL_MPIC_42 + KVM_DEV_TYPE_XICS, +#define KVM_DEV_TYPE_XICS KVM_DEV_TYPE_XICS + KVM_DEV_TYPE_VFIO, +#define KVM_DEV_TYPE_VFIO KVM_DEV_TYPE_VFIO + KVM_DEV_TYPE_ARM_VGIC_V2, +#define KVM_DEV_TYPE_ARM_VGIC_V2 KVM_DEV_TYPE_ARM_VGIC_V2 + KVM_DEV_TYPE_FLIC, +#define KVM_DEV_TYPE_FLIC KVM_DEV_TYPE_FLIC + KVM_DEV_TYPE_ARM_VGIC_V3, +#define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3 + KVM_DEV_TYPE_ARM_VGIC_ITS, +#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS + KVM_DEV_TYPE_MAX, +}; + +struct kvm_vfio_spapr_tce { + __s32 groupfd; + __s32 tablefd; +}; + +/* + * ioctls for VM fds + */ +#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region) +/* + * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns + * a vcpu fd. + */ +#define KVM_CREATE_VCPU _IO(KVMIO, 0x41) +#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log) +/* KVM_SET_MEMORY_ALIAS is obsolete: */ +#define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias) +#define KVM_SET_NR_MMU_PAGES _IO(KVMIO, 0x44) +#define KVM_GET_NR_MMU_PAGES _IO(KVMIO, 0x45) +#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46, \ + struct kvm_userspace_memory_region) +#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) +#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64) + +/* enable ucontrol for s390 */ +struct kvm_s390_ucas_mapping { + __u64 user_addr; + __u64 vcpu_addr; + __u64 length; +}; +#define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping) +#define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping) +#define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long) + +/* Device model IOC */ +#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) +#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) +#define KVM_GET_IRQCHIP _IOWR(KVMIO, 0x62, struct kvm_irqchip) +#define KVM_SET_IRQCHIP _IOR(KVMIO, 0x63, struct kvm_irqchip) +#define KVM_CREATE_PIT _IO(KVMIO, 0x64) +#define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state) +#define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state) +#define KVM_IRQ_LINE_STATUS _IOWR(KVMIO, 0x67, struct kvm_irq_level) +#define KVM_REGISTER_COALESCED_MMIO \ + _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone) +#define KVM_UNREGISTER_COALESCED_MMIO \ + _IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone) +#define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, \ + struct kvm_assigned_pci_dev) +#define KVM_SET_GSI_ROUTING _IOW(KVMIO, 0x6a, struct kvm_irq_routing) +/* deprecated, replaced by KVM_ASSIGN_DEV_IRQ */ +#define KVM_ASSIGN_IRQ __KVM_DEPRECATED_VM_R_0x70 +#define KVM_ASSIGN_DEV_IRQ _IOW(KVMIO, 0x70, struct kvm_assigned_irq) +#define KVM_REINJECT_CONTROL _IO(KVMIO, 0x71) +#define KVM_DEASSIGN_PCI_DEVICE _IOW(KVMIO, 0x72, \ + struct kvm_assigned_pci_dev) +#define KVM_ASSIGN_SET_MSIX_NR _IOW(KVMIO, 0x73, \ + struct kvm_assigned_msix_nr) +#define KVM_ASSIGN_SET_MSIX_ENTRY _IOW(KVMIO, 0x74, \ + struct kvm_assigned_msix_entry) +#define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq) +#define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd) +#define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config) +#define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78) +#define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd) +#define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config) +#define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data) +#define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data) +/* Available with KVM_CAP_PIT_STATE2 */ +#define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2) +#define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) +/* Available with KVM_CAP_PPC_GET_PVINFO */ +#define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) +/* Available with KVM_CAP_TSC_CONTROL */ +#define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2) +#define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3) +/* Available with KVM_CAP_PCI_2_3 */ +#define KVM_ASSIGN_SET_INTX_MASK _IOW(KVMIO, 0xa4, \ + struct kvm_assigned_pci_dev) +/* Available with KVM_CAP_SIGNAL_MSI */ +#define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi) +/* Available with KVM_CAP_PPC_GET_SMMU_INFO */ +#define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info) +/* Available with KVM_CAP_PPC_ALLOC_HTAB */ +#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32) +#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) +#define KVM_CREATE_SPAPR_TCE_64 _IOW(KVMIO, 0xa8, \ + struct kvm_create_spapr_tce_64) +/* Available with KVM_CAP_RMA */ +#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) +/* Available with KVM_CAP_PPC_HTAB_FD */ +#define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd) +/* Available with KVM_CAP_ARM_SET_DEVICE_ADDR */ +#define KVM_ARM_SET_DEVICE_ADDR _IOW(KVMIO, 0xab, struct kvm_arm_device_addr) +/* Available with KVM_CAP_PPC_RTAS */ +#define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO, 0xac, struct kvm_rtas_token_args) +/* Available with KVM_CAP_SPAPR_RESIZE_HPT */ +#define KVM_PPC_RESIZE_HPT_PREPARE _IOR(KVMIO, 0xad, struct kvm_ppc_resize_hpt) +#define KVM_PPC_RESIZE_HPT_COMMIT _IOR(KVMIO, 0xae, struct kvm_ppc_resize_hpt) +/* Available with KVM_CAP_PPC_RADIX_MMU or KVM_CAP_PPC_HASH_MMU_V3 */ +#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg) +/* Available with KVM_CAP_PPC_RADIX_MMU */ +#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info) + +/* ioctl for vm fd */ +#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) + +/* ioctls for fds returned by KVM_CREATE_DEVICE */ +#define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr) +#define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) +#define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) + +/* + * ioctls for vcpu fds + */ +#define KVM_RUN _IO(KVMIO, 0x80) +#define KVM_GET_REGS _IOR(KVMIO, 0x81, struct kvm_regs) +#define KVM_SET_REGS _IOW(KVMIO, 0x82, struct kvm_regs) +#define KVM_GET_SREGS _IOR(KVMIO, 0x83, struct kvm_sregs) +#define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs) +#define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation) +#define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt) +/* KVM_DEBUG_GUEST is no longer supported, use KVM_SET_GUEST_DEBUG instead */ +#define KVM_DEBUG_GUEST __KVM_DEPRECATED_VCPU_W_0x87 +#define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs) +#define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs) +#define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid) +#define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask) +#define KVM_GET_FPU _IOR(KVMIO, 0x8c, struct kvm_fpu) +#define KVM_SET_FPU _IOW(KVMIO, 0x8d, struct kvm_fpu) +#define KVM_GET_LAPIC _IOR(KVMIO, 0x8e, struct kvm_lapic_state) +#define KVM_SET_LAPIC _IOW(KVMIO, 0x8f, struct kvm_lapic_state) +#define KVM_SET_CPUID2 _IOW(KVMIO, 0x90, struct kvm_cpuid2) +#define KVM_GET_CPUID2 _IOWR(KVMIO, 0x91, struct kvm_cpuid2) +/* Available with KVM_CAP_VAPIC */ +#define KVM_TPR_ACCESS_REPORTING _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl) +/* Available with KVM_CAP_VAPIC */ +#define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr) +/* valid for virtual machine (for floating interrupt)_and_ vcpu */ +#define KVM_S390_INTERRUPT _IOW(KVMIO, 0x94, struct kvm_s390_interrupt) +/* store status for s390 */ +#define KVM_S390_STORE_STATUS_NOADDR (-1ul) +#define KVM_S390_STORE_STATUS_PREFIXED (-2ul) +#define KVM_S390_STORE_STATUS _IOW(KVMIO, 0x95, unsigned long) +/* initial ipl psw for s390 */ +#define KVM_S390_SET_INITIAL_PSW _IOW(KVMIO, 0x96, struct kvm_s390_psw) +/* initial reset for s390 */ +#define KVM_S390_INITIAL_RESET _IO(KVMIO, 0x97) +#define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state) +#define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) +/* Available with KVM_CAP_USER_NMI */ +#define KVM_NMI _IO(KVMIO, 0x9a) +/* Available with KVM_CAP_SET_GUEST_DEBUG */ +#define KVM_SET_GUEST_DEBUG _IOW(KVMIO, 0x9b, struct kvm_guest_debug) +/* MCE for x86 */ +#define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64) +#define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64) +#define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce) +/* Available with KVM_CAP_VCPU_EVENTS */ +#define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) +#define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) +/* Available with KVM_CAP_DEBUGREGS */ +#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) +#define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) +/* + * vcpu version available with KVM_ENABLE_CAP + * vm version available with KVM_CAP_ENABLE_CAP_VM + */ +#define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) +/* Available with KVM_CAP_XSAVE */ +#define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) +#define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave) +/* Available with KVM_CAP_XCRS */ +#define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) +#define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) +/* Available with KVM_CAP_SW_TLB */ +#define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb) +/* Available with KVM_CAP_ONE_REG */ +#define KVM_GET_ONE_REG _IOW(KVMIO, 0xab, struct kvm_one_reg) +#define KVM_SET_ONE_REG _IOW(KVMIO, 0xac, struct kvm_one_reg) +/* VM is being stopped by host */ +#define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad) +#define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init) +#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init) +#define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list) +/* Available with KVM_CAP_S390_MEM_OP */ +#define KVM_S390_MEM_OP _IOW(KVMIO, 0xb1, struct kvm_s390_mem_op) +/* Available with KVM_CAP_S390_SKEYS */ +#define KVM_S390_GET_SKEYS _IOW(KVMIO, 0xb2, struct kvm_s390_skeys) +#define KVM_S390_SET_SKEYS _IOW(KVMIO, 0xb3, struct kvm_s390_skeys) +/* Available with KVM_CAP_S390_INJECT_IRQ */ +#define KVM_S390_IRQ _IOW(KVMIO, 0xb4, struct kvm_s390_irq) +/* Available with KVM_CAP_S390_IRQ_STATE */ +#define KVM_S390_SET_IRQ_STATE _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state) +#define KVM_S390_GET_IRQ_STATE _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state) +/* Available with KVM_CAP_X86_SMM */ +#define KVM_SMI _IO(KVMIO, 0xb7) +/* Available with KVM_CAP_S390_CMMA_MIGRATION */ +#define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log) +#define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log) + +#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) +#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) +#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) + +struct kvm_assigned_pci_dev { + __u32 assigned_dev_id; + __u32 busnr; + __u32 devfn; + __u32 flags; + __u32 segnr; + union { + __u32 reserved[11]; + }; +}; + +#define KVM_DEV_IRQ_HOST_INTX (1 << 0) +#define KVM_DEV_IRQ_HOST_MSI (1 << 1) +#define KVM_DEV_IRQ_HOST_MSIX (1 << 2) + +#define KVM_DEV_IRQ_GUEST_INTX (1 << 8) +#define KVM_DEV_IRQ_GUEST_MSI (1 << 9) +#define KVM_DEV_IRQ_GUEST_MSIX (1 << 10) + +#define KVM_DEV_IRQ_HOST_MASK 0x00ff +#define KVM_DEV_IRQ_GUEST_MASK 0xff00 + +struct kvm_assigned_irq { + __u32 assigned_dev_id; + __u32 host_irq; /* ignored (legacy field) */ + __u32 guest_irq; + __u32 flags; + union { + __u32 reserved[12]; + }; +}; + +struct kvm_assigned_msix_nr { + __u32 assigned_dev_id; + __u16 entry_nr; + __u16 padding; +}; + +#define KVM_MAX_MSIX_PER_DEV 256 +struct kvm_assigned_msix_entry { + __u32 assigned_dev_id; + __u32 gsi; + __u16 entry; /* The index of entry in the MSI-X table */ + __u16 padding[3]; +}; + +#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0) +#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1) + +/* Available with KVM_CAP_ARM_USER_IRQ */ + +/* Bits for run->s.regs.device_irq_level */ +#define KVM_ARM_DEV_EL1_VTIMER (1 << 0) +#define KVM_ARM_DEV_EL1_PTIMER (1 << 1) +#define KVM_ARM_DEV_PMU (1 << 2) + +#endif /* __LINUX_KVM_H */ diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h index 81d8edf11789aaae96a25da00b8a8f3ec0ed83aa..a937480d7cd345f4e1b12c2e409f58c0489e8a4e 100644 --- a/tools/include/uapi/linux/mman.h +++ b/tools/include/uapi/linux/mman.h @@ -1,7 +1,8 @@ #ifndef _UAPI_LINUX_MMAN_H #define _UAPI_LINUX_MMAN_H -#include +#include +#include #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 @@ -10,4 +11,25 @@ #define OVERCOMMIT_ALWAYS 1 #define OVERCOMMIT_NEVER 2 +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT +#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK + +#define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB +#define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB +#define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB +#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB +#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB +#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB +#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB +#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB +#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB +#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB + #endif /* _UAPI_LINUX_MMAN_H */ diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h index b1c0b187acfe57da3ece7e91325536edcc9cff0c..140ae638cfd618b931ec1d298a80d1dffa4c1680 100644 --- a/tools/include/uapi/linux/perf_event.h +++ b/tools/include/uapi/linux/perf_event.h @@ -139,8 +139,9 @@ enum perf_event_sample_format { PERF_SAMPLE_IDENTIFIER = 1U << 16, PERF_SAMPLE_TRANSACTION = 1U << 17, PERF_SAMPLE_REGS_INTR = 1U << 18, + PERF_SAMPLE_PHYS_ADDR = 1U << 19, - PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */ }; /* @@ -174,6 +175,8 @@ enum perf_branch_sample_type_shift { PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14, /* no flags */ PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15, /* no cycles */ + PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16, /* save branch type */ + PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */ }; @@ -198,9 +201,30 @@ enum perf_branch_sample_type { PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT, PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT, + PERF_SAMPLE_BRANCH_TYPE_SAVE = + 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT, + PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT, }; +/* + * Common flow change classification + */ +enum { + PERF_BR_UNKNOWN = 0, /* unknown */ + PERF_BR_COND = 1, /* conditional */ + PERF_BR_UNCOND = 2, /* unconditional */ + PERF_BR_IND = 3, /* indirect */ + PERF_BR_CALL = 4, /* function call */ + PERF_BR_IND_CALL = 5, /* indirect function call */ + PERF_BR_RET = 6, /* function return */ + PERF_BR_SYSCALL = 7, /* syscall */ + PERF_BR_SYSRET = 8, /* syscall return */ + PERF_BR_COND_CALL = 9, /* conditional function call */ + PERF_BR_COND_RET = 10, /* conditional function return */ + PERF_BR_MAX, +}; + #define PERF_SAMPLE_BRANCH_PLM_ALL \ (PERF_SAMPLE_BRANCH_USER|\ PERF_SAMPLE_BRANCH_KERNEL|\ @@ -791,6 +815,7 @@ enum perf_event_type { * { u64 transaction; } && PERF_SAMPLE_TRANSACTION * { u64 abi; # enum perf_sample_regs_abi * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR + * { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR * }; */ PERF_RECORD_SAMPLE = 9, @@ -931,14 +956,20 @@ union perf_mem_data_src { mem_snoop:5, /* snoop mode */ mem_lock:2, /* lock instr */ mem_dtlb:7, /* tlb access */ - mem_rsvd:31; + mem_lvl_num:4, /* memory hierarchy level number */ + mem_remote:1, /* remote */ + mem_snoopx:2, /* snoop mode, ext */ + mem_rsvd:24; }; }; #elif defined(__BIG_ENDIAN_BITFIELD) union perf_mem_data_src { __u64 val; struct { - __u64 mem_rsvd:31, + __u64 mem_rsvd:24, + mem_snoopx:2, /* snoop mode, ext */ + mem_remote:1, /* remote */ + mem_lvl_num:4, /* memory hierarchy level number */ mem_dtlb:7, /* tlb access */ mem_lock:2, /* lock instr */ mem_snoop:5, /* snoop mode */ @@ -975,6 +1006,22 @@ union perf_mem_data_src { #define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */ #define PERF_MEM_LVL_SHIFT 5 +#define PERF_MEM_REMOTE_REMOTE 0x01 /* Remote */ +#define PERF_MEM_REMOTE_SHIFT 37 + +#define PERF_MEM_LVLNUM_L1 0x01 /* L1 */ +#define PERF_MEM_LVLNUM_L2 0x02 /* L2 */ +#define PERF_MEM_LVLNUM_L3 0x03 /* L3 */ +#define PERF_MEM_LVLNUM_L4 0x04 /* L4 */ +/* 5-0xa available */ +#define PERF_MEM_LVLNUM_ANY_CACHE 0x0b /* Any cache */ +#define PERF_MEM_LVLNUM_LFB 0x0c /* LFB */ +#define PERF_MEM_LVLNUM_RAM 0x0d /* RAM */ +#define PERF_MEM_LVLNUM_PMEM 0x0e /* PMEM */ +#define PERF_MEM_LVLNUM_NA 0x0f /* N/A */ + +#define PERF_MEM_LVLNUM_SHIFT 33 + /* snoop mode */ #define PERF_MEM_SNOOP_NA 0x01 /* not available */ #define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */ @@ -983,6 +1030,10 @@ union perf_mem_data_src { #define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */ #define PERF_MEM_SNOOP_SHIFT 19 +#define PERF_MEM_SNOOPX_FWD 0x01 /* forward */ +/* 1 free */ +#define PERF_MEM_SNOOPX_SHIFT 37 + /* locked instruction */ #define PERF_MEM_LOCK_NA 0x01 /* not available */ #define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */ @@ -1015,6 +1066,7 @@ union perf_mem_data_src { * in_tx: running in a hardware transaction * abort: aborting a hardware transaction * cycles: cycles from last branch (or 0 if not supported) + * type: branch type */ struct perf_branch_entry { __u64 from; @@ -1024,7 +1076,8 @@ struct perf_branch_entry { in_tx:1, /* in transaction */ abort:1, /* transaction abort */ cycles:16, /* cycle count to last branch */ - reserved:44; + type:4, /* branch type */ + reserved:40; }; #endif /* _UAPI_LINUX_PERF_EVENT_H */ diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h new file mode 100644 index 0000000000000000000000000000000000000000..e2a6c7b3510b4a73a60e36f83739f42c62fad6f5 --- /dev/null +++ b/tools/include/uapi/linux/sched.h @@ -0,0 +1,52 @@ +#ifndef _UAPI_LINUX_SCHED_H +#define _UAPI_LINUX_SCHED_H + +/* + * cloning flags: + */ +#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_FS 0x00000200 /* set if fs info shared between processes */ +#define CLONE_FILES 0x00000400 /* set if open files shared between processes */ +#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ +#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ +#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ +#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ +#define CLONE_THREAD 0x00010000 /* Same thread group? */ +#define CLONE_NEWNS 0x00020000 /* New mount namespace group */ +#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ +#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ +#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ +#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ +#define CLONE_DETACHED 0x00400000 /* Unused, ignored */ +#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ +#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ +#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ +#define CLONE_NEWUTS 0x04000000 /* New utsname namespace */ +#define CLONE_NEWIPC 0x08000000 /* New ipc namespace */ +#define CLONE_NEWUSER 0x10000000 /* New user namespace */ +#define CLONE_NEWPID 0x20000000 /* New pid namespace */ +#define CLONE_NEWNET 0x40000000 /* New network namespace */ +#define CLONE_IO 0x80000000 /* Clone io context */ + +/* + * Scheduling policies + */ +#define SCHED_NORMAL 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 +#define SCHED_BATCH 3 +/* SCHED_ISO: reserved but not implemented yet */ +#define SCHED_IDLE 5 +#define SCHED_DEADLINE 6 + +/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ +#define SCHED_RESET_ON_FORK 0x40000000 + +/* + * For the sched_{set,get}attr() calls + */ +#define SCHED_FLAG_RESET_ON_FORK 0x01 +#define SCHED_FLAG_RECLAIM 0x02 + +#endif /* _UAPI_LINUX_SCHED_H */ diff --git a/tools/include/uapi/linux/vhost.h b/tools/include/uapi/linux/vhost.h new file mode 100644 index 0000000000000000000000000000000000000000..60180c0b5dc6a5bce1cec4800050dc5b20df58f7 --- /dev/null +++ b/tools/include/uapi/linux/vhost.h @@ -0,0 +1,209 @@ +#ifndef _LINUX_VHOST_H +#define _LINUX_VHOST_H +/* Userspace interface for in-kernel virtio accelerators. */ + +/* vhost is used to reduce the number of system calls involved in virtio. + * + * Existing virtio net code is used in the guest without modification. + * + * This header includes interface used by userspace hypervisor for + * device configuration. + */ + +#include +#include +#include +#include +#include + +struct vhost_vring_state { + unsigned int index; + unsigned int num; +}; + +struct vhost_vring_file { + unsigned int index; + int fd; /* Pass -1 to unbind from file. */ + +}; + +struct vhost_vring_addr { + unsigned int index; + /* Option flags. */ + unsigned int flags; + /* Flag values: */ + /* Whether log address is valid. If set enables logging. */ +#define VHOST_VRING_F_LOG 0 + + /* Start of array of descriptors (virtually contiguous) */ + __u64 desc_user_addr; + /* Used structure address. Must be 32 bit aligned */ + __u64 used_user_addr; + /* Available structure address. Must be 16 bit aligned */ + __u64 avail_user_addr; + /* Logging support. */ + /* Log writes to used structure, at offset calculated from specified + * address. Address must be 32 bit aligned. */ + __u64 log_guest_addr; +}; + +/* no alignment requirement */ +struct vhost_iotlb_msg { + __u64 iova; + __u64 size; + __u64 uaddr; +#define VHOST_ACCESS_RO 0x1 +#define VHOST_ACCESS_WO 0x2 +#define VHOST_ACCESS_RW 0x3 + __u8 perm; +#define VHOST_IOTLB_MISS 1 +#define VHOST_IOTLB_UPDATE 2 +#define VHOST_IOTLB_INVALIDATE 3 +#define VHOST_IOTLB_ACCESS_FAIL 4 + __u8 type; +}; + +#define VHOST_IOTLB_MSG 0x1 + +struct vhost_msg { + int type; + union { + struct vhost_iotlb_msg iotlb; + __u8 padding[64]; + }; +}; + +struct vhost_memory_region { + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ + __u64 userspace_addr; + __u64 flags_padding; /* No flags are currently specified. */ +}; + +/* All region addresses and sizes must be 4K aligned. */ +#define VHOST_PAGE_SIZE 0x1000 + +struct vhost_memory { + __u32 nregions; + __u32 padding; + struct vhost_memory_region regions[0]; +}; + +/* ioctls */ + +#define VHOST_VIRTIO 0xAF + +/* Features bitmask for forward compatibility. Transport bits are used for + * vhost specific features. */ +#define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64) +#define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64) + +/* Set current process as the (exclusive) owner of this file descriptor. This + * must be called before any other vhost command. Further calls to + * VHOST_OWNER_SET fail until VHOST_OWNER_RESET is called. */ +#define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01) +/* Give up ownership, and reset the device to default values. + * Allows subsequent call to VHOST_OWNER_SET to succeed. */ +#define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02) + +/* Set up/modify memory layout */ +#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, struct vhost_memory) + +/* Write logging setup. */ +/* Memory writes can optionally be logged by setting bit at an offset + * (calculated from the physical address) from specified log base. + * The bit is set using an atomic 32 bit operation. */ +/* Set base address for logging. */ +#define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64) +/* Specify an eventfd file descriptor to signal on log write. */ +#define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int) + +/* Ring setup. */ +/* Set number of descriptors in ring. This parameter can not + * be modified while ring is running (bound to a device). */ +#define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state) +/* Set addresses for the ring. */ +#define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr) +/* Base value where queue looks for available descriptors */ +#define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state) +/* Get accessor: reads index, writes value in num */ +#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state) + +/* Set the vring byte order in num. Valid values are VHOST_VRING_LITTLE_ENDIAN + * or VHOST_VRING_BIG_ENDIAN (other values return -EINVAL). + * The byte order cannot be changed while the device is active: trying to do so + * returns -EBUSY. + * This is a legacy only API that is simply ignored when VIRTIO_F_VERSION_1 is + * set. + * Not all kernel configurations support this ioctl, but all configurations that + * support SET also support GET. + */ +#define VHOST_VRING_LITTLE_ENDIAN 0 +#define VHOST_VRING_BIG_ENDIAN 1 +#define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state) +#define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state) + +/* The following ioctls use eventfd file descriptors to signal and poll + * for events. */ + +/* Set eventfd to poll for added buffers */ +#define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file) +/* Set eventfd to signal when buffers have beed used */ +#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file) +/* Set eventfd to signal an error */ +#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file) +/* Set busy loop timeout (in us) */ +#define VHOST_SET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x23, \ + struct vhost_vring_state) +/* Get busy loop timeout (in us) */ +#define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24, \ + struct vhost_vring_state) + +/* VHOST_NET specific defines */ + +/* Attach virtio net ring to a raw socket, or tap device. + * The socket must be already bound to an ethernet device, this device will be + * used for transmit. Pass fd -1 to unbind from the socket and the transmit + * device. This can be used to stop the ring (e.g. for migration). */ +#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file) + +/* Feature bits */ +/* Log all write descriptors. Can be changed while device is active. */ +#define VHOST_F_LOG_ALL 26 +/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */ +#define VHOST_NET_F_VIRTIO_NET_HDR 27 + +/* VHOST_SCSI specific definitions */ + +/* + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. + * + * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + + * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage + * ABI Rev 1: January 2013. Ignore vhost_tpgt filed in struct vhost_scsi_target. + * All the targets under vhost_wwpn can be seen and used by guset. + */ + +#define VHOST_SCSI_ABI_VERSION 1 + +struct vhost_scsi_target { + int abi_version; + char vhost_wwpn[224]; /* TRANSPORT_IQN_LEN */ + unsigned short vhost_tpgt; + unsigned short reserved; +}; + +#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) +#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) +/* Changing this breaks userspace. */ +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int) +/* Set and get the events missed flag */ +#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32) +#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32) + +/* VHOST_VSOCK specific defines */ + +#define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64) +#define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int) + +#endif diff --git a/tools/include/uapi/sound/asound.h b/tools/include/uapi/sound/asound.h new file mode 100644 index 0000000000000000000000000000000000000000..87bf30b182dfd0fd20cc420896a568590c58f540 --- /dev/null +++ b/tools/include/uapi/sound/asound.h @@ -0,0 +1,1026 @@ +/* + * Advanced Linux Sound Architecture - ALSA - Driver + * Copyright (c) 1994-2003 by Jaroslav Kysela , + * Abramo Bagnara + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _UAPI__SOUND_ASOUND_H +#define _UAPI__SOUND_ASOUND_H + +#if defined(__KERNEL__) || defined(__linux__) +#include +#else +#include +#endif + +#ifndef __KERNEL__ +#include +#endif + +/* + * protocol version + */ + +#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor)) +#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff) +#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff) +#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff) +#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) \ + (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || \ + (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && \ + SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion))) + +/**************************************************************************** + * * + * Digital audio interface * + * * + ****************************************************************************/ + +struct snd_aes_iec958 { + unsigned char status[24]; /* AES/IEC958 channel status bits */ + unsigned char subcode[147]; /* AES/IEC958 subcode bits */ + unsigned char pad; /* nothing */ + unsigned char dig_subframe[4]; /* AES/IEC958 subframe bits */ +}; + +/**************************************************************************** + * * + * CEA-861 Audio InfoFrame. Used in HDMI and DisplayPort * + * * + ****************************************************************************/ + +struct snd_cea_861_aud_if { + unsigned char db1_ct_cc; /* coding type and channel count */ + unsigned char db2_sf_ss; /* sample frequency and size */ + unsigned char db3; /* not used, all zeros */ + unsigned char db4_ca; /* channel allocation code */ + unsigned char db5_dminh_lsv; /* downmix inhibit & level-shit values */ +}; + +/**************************************************************************** + * * + * Section for driver hardware dependent interface - /dev/snd/hw? * + * * + ****************************************************************************/ + +#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1) + +enum { + SNDRV_HWDEP_IFACE_OPL2 = 0, + SNDRV_HWDEP_IFACE_OPL3, + SNDRV_HWDEP_IFACE_OPL4, + SNDRV_HWDEP_IFACE_SB16CSP, /* Creative Signal Processor */ + SNDRV_HWDEP_IFACE_EMU10K1, /* FX8010 processor in EMU10K1 chip */ + SNDRV_HWDEP_IFACE_YSS225, /* Yamaha FX processor */ + SNDRV_HWDEP_IFACE_ICS2115, /* Wavetable synth */ + SNDRV_HWDEP_IFACE_SSCAPE, /* Ensoniq SoundScape ISA card (MC68EC000) */ + SNDRV_HWDEP_IFACE_VX, /* Digigram VX cards */ + SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */ + SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */ + SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */ + SNDRV_HWDEP_IFACE_BLUETOOTH, /* Bluetooth audio */ + SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */ + SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */ + SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */ + SNDRV_HWDEP_IFACE_HDA, /* HD-audio */ + SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */ + SNDRV_HWDEP_IFACE_FW_DICE, /* TC DICE FireWire device */ + SNDRV_HWDEP_IFACE_FW_FIREWORKS, /* Echo Audio Fireworks based device */ + SNDRV_HWDEP_IFACE_FW_BEBOB, /* BridgeCo BeBoB based device */ + SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */ + SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ + SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ + SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ + SNDRV_HWDEP_IFACE_FW_MOTU, /* MOTU FireWire series */ + SNDRV_HWDEP_IFACE_FW_FIREFACE, /* RME Fireface series */ + + /* Don't forget to change the following: */ + SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE +}; + +struct snd_hwdep_info { + unsigned int device; /* WR: device number */ + int card; /* R: card number */ + unsigned char id[64]; /* ID (user selectable) */ + unsigned char name[80]; /* hwdep name */ + int iface; /* hwdep interface */ + unsigned char reserved[64]; /* reserved for future */ +}; + +/* generic DSP loader */ +struct snd_hwdep_dsp_status { + unsigned int version; /* R: driver-specific version */ + unsigned char id[32]; /* R: driver-specific ID string */ + unsigned int num_dsps; /* R: number of DSP images to transfer */ + unsigned int dsp_loaded; /* R: bit flags indicating the loaded DSPs */ + unsigned int chip_ready; /* R: 1 = initialization finished */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +struct snd_hwdep_dsp_image { + unsigned int index; /* W: DSP index */ + unsigned char name[64]; /* W: ID (e.g. file name) */ + unsigned char __user *image; /* W: binary image */ + size_t length; /* W: size of image in bytes */ + unsigned long driver_data; /* W: driver-specific data */ +}; + +#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int) +#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct snd_hwdep_info) +#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status) +#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image) + +/***************************************************************************** + * * + * Digital Audio (PCM) interface - /dev/snd/pcm?? * + * * + *****************************************************************************/ + +#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14) + +typedef unsigned long snd_pcm_uframes_t; +typedef signed long snd_pcm_sframes_t; + +enum { + SNDRV_PCM_CLASS_GENERIC = 0, /* standard mono or stereo device */ + SNDRV_PCM_CLASS_MULTI, /* multichannel device */ + SNDRV_PCM_CLASS_MODEM, /* software modem class */ + SNDRV_PCM_CLASS_DIGITIZER, /* digitizer class */ + /* Don't forget to change the following: */ + SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER, +}; + +enum { + SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */ + SNDRV_PCM_SUBCLASS_MULTI_MIX, /* multichannel subdevices are mixed together */ + /* Don't forget to change the following: */ + SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX, +}; + +enum { + SNDRV_PCM_STREAM_PLAYBACK = 0, + SNDRV_PCM_STREAM_CAPTURE, + SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE, +}; + +typedef int __bitwise snd_pcm_access_t; +#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0) /* interleaved mmap */ +#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1) /* noninterleaved mmap */ +#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2) /* complex mmap */ +#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3) /* readi/writei */ +#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4) /* readn/writen */ +#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED + +typedef int __bitwise snd_pcm_format_t; +#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0) +#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1) +#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2) +#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3) +#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4) +#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5) +#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6) /* low three bytes */ +#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7) /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8) /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9) /* low three bytes */ +#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10) +#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11) +#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12) +#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13) +#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */ +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */ +#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20) +#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21) +#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22) +#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23) +#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24) +#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31) +#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43) /* in three bytes */ +#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */ +#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */ +#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */ +#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */ +#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48) /* DSD, 1-byte samples DSD (x8) */ +#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49) /* DSD, 2-byte samples DSD (x16), little endian */ +#define SNDRV_PCM_FORMAT_DSD_U32_LE ((__force snd_pcm_format_t) 50) /* DSD, 4-byte samples DSD (x32), little endian */ +#define SNDRV_PCM_FORMAT_DSD_U16_BE ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */ +#define SNDRV_PCM_FORMAT_DSD_U32_BE ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */ +#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U32_BE + +#ifdef SNDRV_LITTLE_ENDIAN +#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_LE +#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_LE +#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_LE +#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_LE +#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_LE +#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_LE +#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE +#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE +#endif +#ifdef SNDRV_BIG_ENDIAN +#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE +#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_BE +#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_BE +#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_BE +#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_BE +#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_BE +#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE +#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE +#endif + +typedef int __bitwise snd_pcm_subformat_t; +#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0) +#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD + +#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */ +#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */ +#define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */ +#define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */ +#define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020 /* need the explicit sync of appl_ptr update */ +#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */ +#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */ +#define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */ +#define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000 /* hardware transfer block of samples */ +#define SNDRV_PCM_INFO_OVERRANGE 0x00020000 /* hardware supports ADC (capture) overrange detection */ +#define SNDRV_PCM_INFO_RESUME 0x00040000 /* hardware supports stream resume after suspend */ +#define SNDRV_PCM_INFO_PAUSE 0x00080000 /* pause ioctl is supported */ +#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */ +#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ +#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ +#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ +#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* (Deprecated)has audio wall clock for audio/system time sync */ +#define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000 /* report hardware link audio time, reset on startup */ +#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000 /* report absolute hardware link audio time, not reset on startup */ +#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 /* report estimated link audio time */ +#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 /* report synchronized audio/system time */ + +#define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */ +#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ + + + +typedef int __bitwise snd_pcm_state_t; +#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */ +#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1) /* stream has a setup */ +#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2) /* stream is ready to start */ +#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3) /* stream is running */ +#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4) /* stream reached an xrun */ +#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5) /* stream is draining */ +#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6) /* stream is paused */ +#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7) /* hardware is suspended */ +#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8) /* hardware is disconnected */ +#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED + +enum { + SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000, + SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000, + SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000, +}; + +union snd_pcm_sync_id { + unsigned char id[16]; + unsigned short id16[8]; + unsigned int id32[4]; +}; + +struct snd_pcm_info { + unsigned int device; /* RO/WR (control): device number */ + unsigned int subdevice; /* RO/WR (control): subdevice number */ + int stream; /* RO/WR (control): stream direction */ + int card; /* R: card number */ + unsigned char id[64]; /* ID (user selectable) */ + unsigned char name[80]; /* name of this device */ + unsigned char subname[32]; /* subdevice name */ + int dev_class; /* SNDRV_PCM_CLASS_* */ + int dev_subclass; /* SNDRV_PCM_SUBCLASS_* */ + unsigned int subdevices_count; + unsigned int subdevices_avail; + union snd_pcm_sync_id sync; /* hardware synchronization ID */ + unsigned char reserved[64]; /* reserved for future... */ +}; + +typedef int snd_pcm_hw_param_t; +#define SNDRV_PCM_HW_PARAM_ACCESS 0 /* Access type */ +#define SNDRV_PCM_HW_PARAM_FORMAT 1 /* Format */ +#define SNDRV_PCM_HW_PARAM_SUBFORMAT 2 /* Subformat */ +#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS +#define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT + +#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8 /* Bits per sample */ +#define SNDRV_PCM_HW_PARAM_FRAME_BITS 9 /* Bits per frame */ +#define SNDRV_PCM_HW_PARAM_CHANNELS 10 /* Channels */ +#define SNDRV_PCM_HW_PARAM_RATE 11 /* Approx rate */ +#define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12 /* Approx distance between + * interrupts in us + */ +#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13 /* Approx frames between + * interrupts + */ +#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14 /* Approx bytes between + * interrupts + */ +#define SNDRV_PCM_HW_PARAM_PERIODS 15 /* Approx interrupts per + * buffer + */ +#define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16 /* Approx duration of buffer + * in us + */ +#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17 /* Size of buffer in frames */ +#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18 /* Size of buffer in bytes */ +#define SNDRV_PCM_HW_PARAM_TICK_TIME 19 /* Approx tick duration in us */ +#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS +#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME + +#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */ +#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */ +#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */ + +struct snd_interval { + unsigned int min, max; + unsigned int openmin:1, + openmax:1, + integer:1, + empty:1; +}; + +#define SNDRV_MASK_MAX 256 + +struct snd_mask { + __u32 bits[(SNDRV_MASK_MAX+31)/32]; +}; + +struct snd_pcm_hw_params { + unsigned int flags; + struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - + SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; + struct snd_mask mres[5]; /* reserved masks */ + struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - + SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; + struct snd_interval ires[9]; /* reserved intervals */ + unsigned int rmask; /* W: requested masks */ + unsigned int cmask; /* R: changed masks */ + unsigned int info; /* R: Info flags for returned setup */ + unsigned int msbits; /* R: used most significant bits */ + unsigned int rate_num; /* R: rate numerator */ + unsigned int rate_den; /* R: rate denominator */ + snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */ + unsigned char reserved[64]; /* reserved for future */ +}; + +enum { + SNDRV_PCM_TSTAMP_NONE = 0, + SNDRV_PCM_TSTAMP_ENABLE, + SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE, +}; + +struct snd_pcm_sw_params { + int tstamp_mode; /* timestamp mode */ + unsigned int period_step; + unsigned int sleep_min; /* min ticks to sleep */ + snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */ + snd_pcm_uframes_t xfer_align; /* obsolete: xfer size need to be a multiple */ + snd_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */ + snd_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */ + snd_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */ + snd_pcm_uframes_t silence_size; /* silence block size */ + snd_pcm_uframes_t boundary; /* pointers wrap point */ + unsigned int proto; /* protocol version */ + unsigned int tstamp_type; /* timestamp type (req. proto >= 2.0.12) */ + unsigned char reserved[56]; /* reserved for future */ +}; + +struct snd_pcm_channel_info { + unsigned int channel; + __kernel_off_t offset; /* mmap offset */ + unsigned int first; /* offset to first sample in bits */ + unsigned int step; /* samples distance in bits */ +}; + +enum { + /* + * first definition for backwards compatibility only, + * maps to wallclock/link time for HDAudio playback and DEFAULT/DMA time for everything else + */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0, + + /* timestamp definitions */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1, /* DMA time, reported as per hw_ptr */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK = 2, /* link time reported by sample or wallclock counter, reset on startup */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3, /* link time reported by sample or wallclock counter, not reset on startup */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4, /* link time estimated indirectly */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, /* link time synchronized with system time */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED +}; + +struct snd_pcm_status { + snd_pcm_state_t state; /* stream state */ + struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */ + struct timespec tstamp; /* reference timestamp */ + snd_pcm_uframes_t appl_ptr; /* appl ptr */ + snd_pcm_uframes_t hw_ptr; /* hw ptr */ + snd_pcm_sframes_t delay; /* current delay in frames */ + snd_pcm_uframes_t avail; /* number of frames available */ + snd_pcm_uframes_t avail_max; /* max frames available on hw since last status */ + snd_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ + snd_pcm_state_t suspended_state; /* suspended stream state */ + __u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */ + struct timespec audio_tstamp; /* sample counter, wall clock, PHC or on-demand sync'ed */ + struct timespec driver_tstamp; /* useful in case reference system tstamp is reported with delay */ + __u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */ + unsigned char reserved[52-2*sizeof(struct timespec)]; /* must be filled with zero */ +}; + +struct snd_pcm_mmap_status { + snd_pcm_state_t state; /* RO: state - SNDRV_PCM_STATE_XXXX */ + int pad1; /* Needed for 64 bit alignment */ + snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ + struct timespec tstamp; /* Timestamp */ + snd_pcm_state_t suspended_state; /* RO: suspended stream state */ + struct timespec audio_tstamp; /* from sample counter or wall clock */ +}; + +struct snd_pcm_mmap_control { + snd_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */ + snd_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ +}; + +#define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0) /* execute hwsync */ +#define SNDRV_PCM_SYNC_PTR_APPL (1<<1) /* get appl_ptr from driver (r/w op) */ +#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) /* get avail_min from driver */ + +struct snd_pcm_sync_ptr { + unsigned int flags; + union { + struct snd_pcm_mmap_status status; + unsigned char reserved[64]; + } s; + union { + struct snd_pcm_mmap_control control; + unsigned char reserved[64]; + } c; +}; + +struct snd_xferi { + snd_pcm_sframes_t result; + void __user *buf; + snd_pcm_uframes_t frames; +}; + +struct snd_xfern { + snd_pcm_sframes_t result; + void __user * __user *bufs; + snd_pcm_uframes_t frames; +}; + +enum { + SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, /* gettimeofday equivalent */ + SNDRV_PCM_TSTAMP_TYPE_MONOTONIC, /* posix_clock_monotonic equivalent */ + SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW, /* monotonic_raw (no NTP) */ + SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW, +}; + +/* channel positions */ +enum { + SNDRV_CHMAP_UNKNOWN = 0, + SNDRV_CHMAP_NA, /* N/A, silent */ + SNDRV_CHMAP_MONO, /* mono stream */ + /* this follows the alsa-lib mixer channel value + 3 */ + SNDRV_CHMAP_FL, /* front left */ + SNDRV_CHMAP_FR, /* front right */ + SNDRV_CHMAP_RL, /* rear left */ + SNDRV_CHMAP_RR, /* rear right */ + SNDRV_CHMAP_FC, /* front center */ + SNDRV_CHMAP_LFE, /* LFE */ + SNDRV_CHMAP_SL, /* side left */ + SNDRV_CHMAP_SR, /* side right */ + SNDRV_CHMAP_RC, /* rear center */ + /* new definitions */ + SNDRV_CHMAP_FLC, /* front left center */ + SNDRV_CHMAP_FRC, /* front right center */ + SNDRV_CHMAP_RLC, /* rear left center */ + SNDRV_CHMAP_RRC, /* rear right center */ + SNDRV_CHMAP_FLW, /* front left wide */ + SNDRV_CHMAP_FRW, /* front right wide */ + SNDRV_CHMAP_FLH, /* front left high */ + SNDRV_CHMAP_FCH, /* front center high */ + SNDRV_CHMAP_FRH, /* front right high */ + SNDRV_CHMAP_TC, /* top center */ + SNDRV_CHMAP_TFL, /* top front left */ + SNDRV_CHMAP_TFR, /* top front right */ + SNDRV_CHMAP_TFC, /* top front center */ + SNDRV_CHMAP_TRL, /* top rear left */ + SNDRV_CHMAP_TRR, /* top rear right */ + SNDRV_CHMAP_TRC, /* top rear center */ + /* new definitions for UAC2 */ + SNDRV_CHMAP_TFLC, /* top front left center */ + SNDRV_CHMAP_TFRC, /* top front right center */ + SNDRV_CHMAP_TSL, /* top side left */ + SNDRV_CHMAP_TSR, /* top side right */ + SNDRV_CHMAP_LLFE, /* left LFE */ + SNDRV_CHMAP_RLFE, /* right LFE */ + SNDRV_CHMAP_BC, /* bottom center */ + SNDRV_CHMAP_BLC, /* bottom left center */ + SNDRV_CHMAP_BRC, /* bottom right center */ + SNDRV_CHMAP_LAST = SNDRV_CHMAP_BRC, +}; + +#define SNDRV_CHMAP_POSITION_MASK 0xffff +#define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16) +#define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16) + +#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) +#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info) +#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) +#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int) +#define SNDRV_PCM_IOCTL_USER_PVERSION _IOW('A', 0x04, int) +#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params) +#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params) +#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12) +#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct snd_pcm_sw_params) +#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status) +#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t) +#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) +#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr) +#define SNDRV_PCM_IOCTL_STATUS_EXT _IOWR('A', 0x24, struct snd_pcm_status) +#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info) +#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40) +#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41) +#define SNDRV_PCM_IOCTL_START _IO('A', 0x42) +#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43) +#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44) +#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int) +#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t) +#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47) +#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48) +#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t) +#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi) +#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi) +#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern) +#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern) +#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int) +#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61) + +/***************************************************************************** + * * + * MIDI v1.0 interface * + * * + *****************************************************************************/ + +/* + * Raw MIDI section - /dev/snd/midi?? + */ + +#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0) + +enum { + SNDRV_RAWMIDI_STREAM_OUTPUT = 0, + SNDRV_RAWMIDI_STREAM_INPUT, + SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT, +}; + +#define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001 +#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002 +#define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004 + +struct snd_rawmidi_info { + unsigned int device; /* RO/WR (control): device number */ + unsigned int subdevice; /* RO/WR (control): subdevice number */ + int stream; /* WR: stream */ + int card; /* R: card number */ + unsigned int flags; /* SNDRV_RAWMIDI_INFO_XXXX */ + unsigned char id[64]; /* ID (user selectable) */ + unsigned char name[80]; /* name of device */ + unsigned char subname[32]; /* name of active or selected subdevice */ + unsigned int subdevices_count; + unsigned int subdevices_avail; + unsigned char reserved[64]; /* reserved for future use */ +}; + +struct snd_rawmidi_params { + int stream; + size_t buffer_size; /* queue size in bytes */ + size_t avail_min; /* minimum avail bytes for wakeup */ + unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +struct snd_rawmidi_status { + int stream; + struct timespec tstamp; /* Timestamp */ + size_t avail; /* available bytes */ + size_t xruns; /* count of overruns since last status (in bytes) */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) +#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) +#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) +#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) +#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) +#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) + +/* + * Timer section - /dev/snd/timer + */ + +#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) + +enum { + SNDRV_TIMER_CLASS_NONE = -1, + SNDRV_TIMER_CLASS_SLAVE = 0, + SNDRV_TIMER_CLASS_GLOBAL, + SNDRV_TIMER_CLASS_CARD, + SNDRV_TIMER_CLASS_PCM, + SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM, +}; + +/* slave timer classes */ +enum { + SNDRV_TIMER_SCLASS_NONE = 0, + SNDRV_TIMER_SCLASS_APPLICATION, + SNDRV_TIMER_SCLASS_SEQUENCER, /* alias */ + SNDRV_TIMER_SCLASS_OSS_SEQUENCER, /* alias */ + SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER, +}; + +/* global timers (device member) */ +#define SNDRV_TIMER_GLOBAL_SYSTEM 0 +#define SNDRV_TIMER_GLOBAL_RTC 1 /* unused */ +#define SNDRV_TIMER_GLOBAL_HPET 2 +#define SNDRV_TIMER_GLOBAL_HRTIMER 3 + +/* info flags */ +#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */ + +struct snd_timer_id { + int dev_class; + int dev_sclass; + int card; + int device; + int subdevice; +}; + +struct snd_timer_ginfo { + struct snd_timer_id tid; /* requested timer ID */ + unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ + int card; /* card number */ + unsigned char id[64]; /* timer identification */ + unsigned char name[80]; /* timer name */ + unsigned long reserved0; /* reserved for future use */ + unsigned long resolution; /* average period resolution in ns */ + unsigned long resolution_min; /* minimal period resolution in ns */ + unsigned long resolution_max; /* maximal period resolution in ns */ + unsigned int clients; /* active timer clients */ + unsigned char reserved[32]; +}; + +struct snd_timer_gparams { + struct snd_timer_id tid; /* requested timer ID */ + unsigned long period_num; /* requested precise period duration (in seconds) - numerator */ + unsigned long period_den; /* requested precise period duration (in seconds) - denominator */ + unsigned char reserved[32]; +}; + +struct snd_timer_gstatus { + struct snd_timer_id tid; /* requested timer ID */ + unsigned long resolution; /* current period resolution in ns */ + unsigned long resolution_num; /* precise current period resolution (in seconds) - numerator */ + unsigned long resolution_den; /* precise current period resolution (in seconds) - denominator */ + unsigned char reserved[32]; +}; + +struct snd_timer_select { + struct snd_timer_id id; /* bind to timer ID */ + unsigned char reserved[32]; /* reserved */ +}; + +struct snd_timer_info { + unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ + int card; /* card number */ + unsigned char id[64]; /* timer identificator */ + unsigned char name[80]; /* timer name */ + unsigned long reserved0; /* reserved for future use */ + unsigned long resolution; /* average period resolution in ns */ + unsigned char reserved[64]; /* reserved */ +}; + +#define SNDRV_TIMER_PSFLG_AUTO (1<<0) /* auto start, otherwise one-shot */ +#define SNDRV_TIMER_PSFLG_EXCLUSIVE (1<<1) /* exclusive use, precise start/stop/pause/continue */ +#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2) /* write early event to the poll queue */ + +struct snd_timer_params { + unsigned int flags; /* flags - SNDRV_MIXER_PSFLG_* */ + unsigned int ticks; /* requested resolution in ticks */ + unsigned int queue_size; /* total size of queue (32-1024) */ + unsigned int reserved0; /* reserved, was: failure locations */ + unsigned int filter; /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */ + unsigned char reserved[60]; /* reserved */ +}; + +struct snd_timer_status { + struct timespec tstamp; /* Timestamp - last update */ + unsigned int resolution; /* current period resolution in ns */ + unsigned int lost; /* counter of master tick lost */ + unsigned int overrun; /* count of read queue overruns */ + unsigned int queue; /* used queue size */ + unsigned char reserved[64]; /* reserved */ +}; + +#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) +#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id) +#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) +#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo) +#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams) +#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus) +#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select) +#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info) +#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params) +#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status) +/* The following four ioctls are changed since 1.0.9 due to confliction */ +#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0) +#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) +#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) +#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) + +struct snd_timer_read { + unsigned int resolution; + unsigned int ticks; +}; + +enum { + SNDRV_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */ + SNDRV_TIMER_EVENT_TICK, /* val = ticks */ + SNDRV_TIMER_EVENT_START, /* val = resolution in ns */ + SNDRV_TIMER_EVENT_STOP, /* val = 0 */ + SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ + SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */ + SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */ + SNDRV_TIMER_EVENT_SUSPEND, /* val = 0 */ + SNDRV_TIMER_EVENT_RESUME, /* val = resolution in ns */ + /* master timer events for slave timer instances */ + SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, + SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, + SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, + SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, + SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10, + SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10, +}; + +struct snd_timer_tread { + int event; + struct timespec tstamp; + unsigned int val; +}; + +/**************************************************************************** + * * + * Section for driver control interface - /dev/snd/control? * + * * + ****************************************************************************/ + +#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) + +struct snd_ctl_card_info { + int card; /* card number */ + int pad; /* reserved for future (was type) */ + unsigned char id[16]; /* ID of card (user selectable) */ + unsigned char driver[16]; /* Driver name */ + unsigned char name[32]; /* Short name of soundcard */ + unsigned char longname[80]; /* name + info text about soundcard */ + unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */ + unsigned char mixername[80]; /* visual mixer identification */ + unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ +}; + +typedef int __bitwise snd_ctl_elem_type_t; +#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) /* invalid */ +#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ +#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ +#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3) /* enumerated type */ +#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4) /* byte array */ +#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */ +#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */ +#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64 + +typedef int __bitwise snd_ctl_elem_iface_t; +#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */ +#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */ +#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */ +#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3) /* PCM device */ +#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */ +#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5) /* timer device */ +#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6) /* sequencer client */ +#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER + +#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0) +#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1) +#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE) +#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */ +#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3) /* when was control changed */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4) /* TLV read is possible */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5) /* TLV write is possible */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) +#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1<<6) /* TLV command is possible */ +#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) /* control does actually nothing, but may be updated */ +#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) /* write lock */ +#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28) /* kernel use a TLV callback */ +#define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) /* user space element */ +/* bits 30 and 31 are obsoleted (for indirect access) */ + +/* for further details see the ACPI and PCI power management specification */ +#define SNDRV_CTL_POWER_D0 0x0000 /* full On */ +#define SNDRV_CTL_POWER_D1 0x0100 /* partial On */ +#define SNDRV_CTL_POWER_D2 0x0200 /* partial On */ +#define SNDRV_CTL_POWER_D3 0x0300 /* Off */ +#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000) /* Off, with power */ +#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001) /* Off, without power */ + +#define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44 + +struct snd_ctl_elem_id { + unsigned int numid; /* numeric identifier, zero = invalid */ + snd_ctl_elem_iface_t iface; /* interface identifier */ + unsigned int device; /* device/client number */ + unsigned int subdevice; /* subdevice (substream) number */ + unsigned char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* ASCII name of item */ + unsigned int index; /* index of item */ +}; + +struct snd_ctl_elem_list { + unsigned int offset; /* W: first element ID to get */ + unsigned int space; /* W: count of element IDs to get */ + unsigned int used; /* R: count of element IDs set */ + unsigned int count; /* R: count of all elements */ + struct snd_ctl_elem_id __user *pids; /* R: IDs */ + unsigned char reserved[50]; +}; + +struct snd_ctl_elem_info { + struct snd_ctl_elem_id id; /* W: element ID */ + snd_ctl_elem_type_t type; /* R: value type - SNDRV_CTL_ELEM_TYPE_* */ + unsigned int access; /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */ + unsigned int count; /* count of values */ + __kernel_pid_t owner; /* owner's PID of this control */ + union { + struct { + long min; /* R: minimum value */ + long max; /* R: maximum value */ + long step; /* R: step (0 variable) */ + } integer; + struct { + long long min; /* R: minimum value */ + long long max; /* R: maximum value */ + long long step; /* R: step (0 variable) */ + } integer64; + struct { + unsigned int items; /* R: number of items */ + unsigned int item; /* W: item number */ + char name[64]; /* R: value name */ + __u64 names_ptr; /* W: names list (ELEM_ADD only) */ + unsigned int names_length; + } enumerated; + unsigned char reserved[128]; + } value; + union { + unsigned short d[4]; /* dimensions */ + unsigned short *d_ptr; /* indirect - obsoleted */ + } dimen; + unsigned char reserved[64-4*sizeof(unsigned short)]; +}; + +struct snd_ctl_elem_value { + struct snd_ctl_elem_id id; /* W: element ID */ + unsigned int indirect: 1; /* W: indirect access - obsoleted */ + union { + union { + long value[128]; + long *value_ptr; /* obsoleted */ + } integer; + union { + long long value[64]; + long long *value_ptr; /* obsoleted */ + } integer64; + union { + unsigned int item[128]; + unsigned int *item_ptr; /* obsoleted */ + } enumerated; + union { + unsigned char data[512]; + unsigned char *data_ptr; /* obsoleted */ + } bytes; + struct snd_aes_iec958 iec958; + } value; /* RO */ + struct timespec tstamp; + unsigned char reserved[128-sizeof(struct timespec)]; +}; + +struct snd_ctl_tlv { + unsigned int numid; /* control element numeric identification */ + unsigned int length; /* in bytes aligned to 4 */ + unsigned int tlv[0]; /* first TLV */ +}; + +#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) +#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info) +#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list) +#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info) +#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value) +#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value) +#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id) +#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id) +#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int) +#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info) +#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info) +#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id) +#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv) +#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv) +#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv) +#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int) +#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info) +#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int) +#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info) +#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int) +#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) +#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info) +#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) +#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) +#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) + +/* + * Read interface. + */ + +enum sndrv_ctl_event_type { + SNDRV_CTL_EVENT_ELEM = 0, + SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM, +}; + +#define SNDRV_CTL_EVENT_MASK_VALUE (1<<0) /* element value was changed */ +#define SNDRV_CTL_EVENT_MASK_INFO (1<<1) /* element info was changed */ +#define SNDRV_CTL_EVENT_MASK_ADD (1<<2) /* element was added */ +#define SNDRV_CTL_EVENT_MASK_TLV (1<<3) /* element TLV tree was changed */ +#define SNDRV_CTL_EVENT_MASK_REMOVE (~0U) /* element was removed */ + +struct snd_ctl_event { + int type; /* event type - SNDRV_CTL_EVENT_* */ + union { + struct { + unsigned int mask; + struct snd_ctl_elem_id id; + } elem; + unsigned char data8[60]; + } data; +}; + +/* + * Control names + */ + +#define SNDRV_CTL_NAME_NONE "" +#define SNDRV_CTL_NAME_PLAYBACK "Playback " +#define SNDRV_CTL_NAME_CAPTURE "Capture " + +#define SNDRV_CTL_NAME_IEC958_NONE "" +#define SNDRV_CTL_NAME_IEC958_SWITCH "Switch" +#define SNDRV_CTL_NAME_IEC958_VOLUME "Volume" +#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default" +#define SNDRV_CTL_NAME_IEC958_MASK "Mask" +#define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask" +#define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask" +#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" +#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what + +#endif /* _UAPI__SOUND_ASOUND_H */ diff --git a/tools/lguest/.gitignore b/tools/lguest/.gitignore deleted file mode 100644 index 8d9a8383a52ed6e2136347b2136c2279b26de94b..0000000000000000000000000000000000000000 --- a/tools/lguest/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -lguest -include diff --git a/tools/lguest/Makefile b/tools/lguest/Makefile deleted file mode 100644 index d04599a798025bdb006e5499d9097d290c213067..0000000000000000000000000000000000000000 --- a/tools/lguest/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This creates the demonstration utility "lguest" which runs a Linux guest. -CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE -Iinclude - -all: lguest - -include/linux/virtio_types.h: ../../include/uapi/linux/virtio_types.h - mkdir -p include/linux 2>&1 || true - ln -sf ../../../../include/uapi/linux/virtio_types.h $@ - -lguest: include/linux/virtio_types.h - -clean: - rm -f lguest - rm -rf include diff --git a/tools/lguest/extract b/tools/lguest/extract deleted file mode 100644 index 7730bb6e4b9409a08d21a598c4aba13c54f4114b..0000000000000000000000000000000000000000 --- a/tools/lguest/extract +++ /dev/null @@ -1,58 +0,0 @@ -#! /bin/sh - -set -e - -PREFIX=$1 -shift - -trap 'rm -r $TMPDIR' 0 -TMPDIR=`mktemp -d` - -exec 3>/dev/null -for f; do - while IFS=" -" read -r LINE; do - case "$LINE" in - *$PREFIX:[0-9]*:\**) - NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"` - if [ -f $TMPDIR/$NUM ]; then - echo "$TMPDIR/$NUM already exits prior to $f" - exit 1 - fi - exec 3>>$TMPDIR/$NUM - echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM - /bin/echo "$LINE" | sed -e "s/$PREFIX:[0-9]*//" -e "s/:\*/*/" >&3 - ;; - *$PREFIX:[0-9]*) - NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"` - if [ -f $TMPDIR/$NUM ]; then - echo "$TMPDIR/$NUM already exits prior to $f" - exit 1 - fi - exec 3>>$TMPDIR/$NUM - echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM - /bin/echo "$LINE" | sed "s/$PREFIX:[0-9]*//" >&3 - ;; - *:\**) - /bin/echo "$LINE" | sed -e "s/:\*/*/" -e "s,/\*\*/,," >&3 - echo >&3 - exec 3>/dev/null - ;; - *) - /bin/echo "$LINE" >&3 - ;; - esac - done < $f - echo >&3 - exec 3>/dev/null -done - -LASTFILE="" -for f in $TMPDIR/*; do - if [ "$LASTFILE" != $(cat $TMPDIR/.$(basename $f) ) ]; then - LASTFILE=$(cat $TMPDIR/.$(basename $f) ) - echo "[ $LASTFILE ]" - fi - cat $f -done - diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c deleted file mode 100644 index 897cd6f3f68720342f7b11ac6e20b4e6e027bad6..0000000000000000000000000000000000000000 --- a/tools/lguest/lguest.c +++ /dev/null @@ -1,3420 +0,0 @@ -/*P:100 - * This is the Launcher code, a simple program which lays out the "physical" - * memory for the new Guest by mapping the kernel image and the virtual - * devices, then opens /dev/lguest to tell the kernel about the Guest and - * control it. -:*/ -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef VIRTIO_F_ANY_LAYOUT -#define VIRTIO_F_ANY_LAYOUT 27 -#endif - -/*L:110 - * We can ignore the 43 include files we need for this program, but I do want - * to draw attention to the use of kernel-style types. - * - * As Linus said, "C is a Spartan language, and so should your naming be." I - * like these abbreviations, so we define them here. Note that u64 is always - * unsigned long long, which works on all Linux systems: this means that we can - * use %llu in printf for any u64. - */ -typedef unsigned long long u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; -/*:*/ - -#define VIRTIO_CONFIG_NO_LEGACY -#define VIRTIO_PCI_NO_LEGACY -#define VIRTIO_BLK_NO_LEGACY -#define VIRTIO_NET_NO_LEGACY - -/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */ -#include "../../include/uapi/linux/virtio_config.h" -#include "../../include/uapi/linux/virtio_net.h" -#include "../../include/uapi/linux/virtio_blk.h" -#include "../../include/uapi/linux/virtio_console.h" -#include "../../include/uapi/linux/virtio_rng.h" -#include -#include "../../include/uapi/linux/virtio_pci.h" -#include -#include "../../include/linux/lguest_launcher.h" - -#define BRIDGE_PFX "bridge:" -#ifndef SIOCBRADDIF -#define SIOCBRADDIF 0x89a2 /* add interface to bridge */ -#endif -/* We can have up to 256 pages for devices. */ -#define DEVICE_PAGES 256 -/* This will occupy 3 pages: it must be a power of 2. */ -#define VIRTQUEUE_NUM 256 - -/*L:120 - * verbose is both a global flag and a macro. The C preprocessor allows - * this, and although I wouldn't recommend it, it works quite nicely here. - */ -static bool verbose; -#define verbose(args...) \ - do { if (verbose) printf(args); } while(0) -/*:*/ - -/* The pointer to the start of guest memory. */ -static void *guest_base; -/* The maximum guest physical address allowed, and maximum possible. */ -static unsigned long guest_limit, guest_max, guest_mmio; -/* The /dev/lguest file descriptor. */ -static int lguest_fd; - -/* a per-cpu variable indicating whose vcpu is currently running */ -static unsigned int __thread cpu_id; - -/* 5 bit device number in the PCI_CONFIG_ADDR => 32 only */ -#define MAX_PCI_DEVICES 32 - -/* This is our list of devices. */ -struct device_list { - /* Counter to assign interrupt numbers. */ - unsigned int next_irq; - - /* Counter to print out convenient device numbers. */ - unsigned int device_num; - - /* PCI devices. */ - struct device *pci[MAX_PCI_DEVICES]; -}; - -/* The list of Guest devices, based on command line arguments. */ -static struct device_list devices; - -/* - * Just like struct virtio_pci_cfg_cap in uapi/linux/virtio_pci.h, - * but uses a u32 explicitly for the data. - */ -struct virtio_pci_cfg_cap_u32 { - struct virtio_pci_cap cap; - u32 pci_cfg_data; /* Data for BAR access. */ -}; - -struct virtio_pci_mmio { - struct virtio_pci_common_cfg cfg; - u16 notify; - u8 isr; - u8 padding; - /* Device-specific configuration follows this. */ -}; - -/* This is the layout (little-endian) of the PCI config space. */ -struct pci_config { - u16 vendor_id, device_id; - u16 command, status; - u8 revid, prog_if, subclass, class; - u8 cacheline_size, lat_timer, header_type, bist; - u32 bar[6]; - u32 cardbus_cis_ptr; - u16 subsystem_vendor_id, subsystem_device_id; - u32 expansion_rom_addr; - u8 capabilities, reserved1[3]; - u32 reserved2; - u8 irq_line, irq_pin, min_grant, max_latency; - - /* Now, this is the linked capability list. */ - struct virtio_pci_cap common; - struct virtio_pci_notify_cap notify; - struct virtio_pci_cap isr; - struct virtio_pci_cap device; - struct virtio_pci_cfg_cap_u32 cfg_access; -}; - -/* The device structure describes a single device. */ -struct device { - /* The name of this device, for --verbose. */ - const char *name; - - /* Any queues attached to this device */ - struct virtqueue *vq; - - /* Is it operational */ - bool running; - - /* Has it written FEATURES_OK but not re-checked it? */ - bool wrote_features_ok; - - /* PCI configuration */ - union { - struct pci_config config; - u32 config_words[sizeof(struct pci_config) / sizeof(u32)]; - }; - - /* Features we offer, and those accepted. */ - u64 features, features_accepted; - - /* Device-specific config hangs off the end of this. */ - struct virtio_pci_mmio *mmio; - - /* PCI MMIO resources (all in BAR0) */ - size_t mmio_size; - u32 mmio_addr; - - /* Device-specific data. */ - void *priv; -}; - -/* The virtqueue structure describes a queue attached to a device. */ -struct virtqueue { - struct virtqueue *next; - - /* Which device owns me. */ - struct device *dev; - - /* Name for printing errors. */ - const char *name; - - /* The actual ring of buffers. */ - struct vring vring; - - /* The information about this virtqueue (we only use queue_size on) */ - struct virtio_pci_common_cfg pci_config; - - /* Last available index we saw. */ - u16 last_avail_idx; - - /* How many are used since we sent last irq? */ - unsigned int pending_used; - - /* Eventfd where Guest notifications arrive. */ - int eventfd; - - /* Function for the thread which is servicing this virtqueue. */ - void (*service)(struct virtqueue *vq); - pid_t thread; -}; - -/* Remember the arguments to the program so we can "reboot" */ -static char **main_args; - -/* The original tty settings to restore on exit. */ -static struct termios orig_term; - -/* - * We have to be careful with barriers: our devices are all run in separate - * threads and so we need to make sure that changes visible to the Guest happen - * in precise order. - */ -#define wmb() __asm__ __volatile__("" : : : "memory") -#define rmb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory") -#define mb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory") - -/* Wrapper for the last available index. Makes it easier to change. */ -#define lg_last_avail(vq) ((vq)->last_avail_idx) - -/* - * The virtio configuration space is defined to be little-endian. x86 is - * little-endian too, but it's nice to be explicit so we have these helpers. - */ -#define cpu_to_le16(v16) (v16) -#define cpu_to_le32(v32) (v32) -#define cpu_to_le64(v64) (v64) -#define le16_to_cpu(v16) (v16) -#define le32_to_cpu(v32) (v32) -#define le64_to_cpu(v64) (v64) - -/* - * A real device would ignore weird/non-compliant driver behaviour. We - * stop and flag it, to help debugging Linux problems. - */ -#define bad_driver(d, fmt, ...) \ - errx(1, "%s: bad driver: " fmt, (d)->name, ## __VA_ARGS__) -#define bad_driver_vq(vq, fmt, ...) \ - errx(1, "%s vq %s: bad driver: " fmt, (vq)->dev->name, \ - vq->name, ## __VA_ARGS__) - -/* Is this iovec empty? */ -static bool iov_empty(const struct iovec iov[], unsigned int num_iov) -{ - unsigned int i; - - for (i = 0; i < num_iov; i++) - if (iov[i].iov_len) - return false; - return true; -} - -/* Take len bytes from the front of this iovec. */ -static void iov_consume(struct device *d, - struct iovec iov[], unsigned num_iov, - void *dest, unsigned len) -{ - unsigned int i; - - for (i = 0; i < num_iov; i++) { - unsigned int used; - - used = iov[i].iov_len < len ? iov[i].iov_len : len; - if (dest) { - memcpy(dest, iov[i].iov_base, used); - dest += used; - } - iov[i].iov_base += used; - iov[i].iov_len -= used; - len -= used; - } - if (len != 0) - bad_driver(d, "iovec too short!"); -} - -/*L:100 - * The Launcher code itself takes us out into userspace, that scary place where - * pointers run wild and free! Unfortunately, like most userspace programs, - * it's quite boring (which is why everyone likes to hack on the kernel!). - * Perhaps if you make up an Lguest Drinking Game at this point, it will get - * you through this section. Or, maybe not. - * - * The Launcher sets up a big chunk of memory to be the Guest's "physical" - * memory and stores it in "guest_base". In other words, Guest physical == - * Launcher virtual with an offset. - * - * This can be tough to get your head around, but usually it just means that we - * use these trivial conversion functions when the Guest gives us its - * "physical" addresses: - */ -static void *from_guest_phys(unsigned long addr) -{ - return guest_base + addr; -} - -static unsigned long to_guest_phys(const void *addr) -{ - return (addr - guest_base); -} - -/*L:130 - * Loading the Kernel. - * - * We start with couple of simple helper routines. open_or_die() avoids - * error-checking code cluttering the callers: - */ -static int open_or_die(const char *name, int flags) -{ - int fd = open(name, flags); - if (fd < 0) - err(1, "Failed to open %s", name); - return fd; -} - -/* map_zeroed_pages() takes a number of pages. */ -static void *map_zeroed_pages(unsigned int num) -{ - int fd = open_or_die("/dev/zero", O_RDONLY); - void *addr; - - /* - * We use a private mapping (ie. if we write to the page, it will be - * copied). We allocate an extra two pages PROT_NONE to act as guard - * pages against read/write attempts that exceed allocated space. - */ - addr = mmap(NULL, getpagesize() * (num+2), - PROT_NONE, MAP_PRIVATE, fd, 0); - - if (addr == MAP_FAILED) - err(1, "Mmapping %u pages of /dev/zero", num); - - if (mprotect(addr + getpagesize(), getpagesize() * num, - PROT_READ|PROT_WRITE) == -1) - err(1, "mprotect rw %u pages failed", num); - - /* - * One neat mmap feature is that you can close the fd, and it - * stays mapped. - */ - close(fd); - - /* Return address after PROT_NONE page */ - return addr + getpagesize(); -} - -/* Get some bytes which won't be mapped into the guest. */ -static unsigned long get_mmio_region(size_t size) -{ - unsigned long addr = guest_mmio; - size_t i; - - if (!size) - return addr; - - /* Size has to be a power of 2 (and multiple of 16) */ - for (i = 1; i < size; i <<= 1); - - guest_mmio += i; - - return addr; -} - -/* - * This routine is used to load the kernel or initrd. It tries mmap, but if - * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries), - * it falls back to reading the memory in. - */ -static void map_at(int fd, void *addr, unsigned long offset, unsigned long len) -{ - ssize_t r; - - /* - * We map writable even though for some segments are marked read-only. - * The kernel really wants to be writable: it patches its own - * instructions. - * - * MAP_PRIVATE means that the page won't be copied until a write is - * done to it. This allows us to share untouched memory between - * Guests. - */ - if (mmap(addr, len, PROT_READ|PROT_WRITE, - MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) - return; - - /* pread does a seek and a read in one shot: saves a few lines. */ - r = pread(fd, addr, len, offset); - if (r != len) - err(1, "Reading offset %lu len %lu gave %zi", offset, len, r); -} - -/* - * This routine takes an open vmlinux image, which is in ELF, and maps it into - * the Guest memory. ELF = Embedded Linking Format, which is the format used - * by all modern binaries on Linux including the kernel. - * - * The ELF headers give *two* addresses: a physical address, and a virtual - * address. We use the physical address; the Guest will map itself to the - * virtual address. - * - * We return the starting address. - */ -static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr) -{ - Elf32_Phdr phdr[ehdr->e_phnum]; - unsigned int i; - - /* - * Sanity checks on the main ELF header: an x86 executable with a - * reasonable number of correctly-sized program headers. - */ - if (ehdr->e_type != ET_EXEC - || ehdr->e_machine != EM_386 - || ehdr->e_phentsize != sizeof(Elf32_Phdr) - || ehdr->e_phnum < 1 || ehdr->e_phnum > 65536U/sizeof(Elf32_Phdr)) - errx(1, "Malformed elf header"); - - /* - * An ELF executable contains an ELF header and a number of "program" - * headers which indicate which parts ("segments") of the program to - * load where. - */ - - /* We read in all the program headers at once: */ - if (lseek(elf_fd, ehdr->e_phoff, SEEK_SET) < 0) - err(1, "Seeking to program headers"); - if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr)) - err(1, "Reading program headers"); - - /* - * Try all the headers: there are usually only three. A read-only one, - * a read-write one, and a "note" section which we don't load. - */ - for (i = 0; i < ehdr->e_phnum; i++) { - /* If this isn't a loadable segment, we ignore it */ - if (phdr[i].p_type != PT_LOAD) - continue; - - verbose("Section %i: size %i addr %p\n", - i, phdr[i].p_memsz, (void *)phdr[i].p_paddr); - - /* We map this section of the file at its physical address. */ - map_at(elf_fd, from_guest_phys(phdr[i].p_paddr), - phdr[i].p_offset, phdr[i].p_filesz); - } - - /* The entry point is given in the ELF header. */ - return ehdr->e_entry; -} - -/*L:150 - * A bzImage, unlike an ELF file, is not meant to be loaded. You're supposed - * to jump into it and it will unpack itself. We used to have to perform some - * hairy magic because the unpacking code scared me. - * - * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote - * a small patch to jump over the tricky bits in the Guest, so now we just read - * the funky header so we know where in the file to load, and away we go! - */ -static unsigned long load_bzimage(int fd) -{ - struct boot_params boot; - int r; - /* Modern bzImages get loaded at 1M. */ - void *p = from_guest_phys(0x100000); - - /* - * Go back to the start of the file and read the header. It should be - * a Linux boot header (see Documentation/x86/boot.txt) - */ - lseek(fd, 0, SEEK_SET); - read(fd, &boot, sizeof(boot)); - - /* Inside the setup_hdr, we expect the magic "HdrS" */ - if (memcmp(&boot.hdr.header, "HdrS", 4) != 0) - errx(1, "This doesn't look like a bzImage to me"); - - /* Skip over the extra sectors of the header. */ - lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET); - - /* Now read everything into memory. in nice big chunks. */ - while ((r = read(fd, p, 65536)) > 0) - p += r; - - /* Finally, code32_start tells us where to enter the kernel. */ - return boot.hdr.code32_start; -} - -/*L:140 - * Loading the kernel is easy when it's a "vmlinux", but most kernels - * come wrapped up in the self-decompressing "bzImage" format. With a little - * work, we can load those, too. - */ -static unsigned long load_kernel(int fd) -{ - Elf32_Ehdr hdr; - - /* Read in the first few bytes. */ - if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) - err(1, "Reading kernel"); - - /* If it's an ELF file, it starts with "\177ELF" */ - if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0) - return map_elf(fd, &hdr); - - /* Otherwise we assume it's a bzImage, and try to load it. */ - return load_bzimage(fd); -} - -/* - * This is a trivial little helper to align pages. Andi Kleen hated it because - * it calls getpagesize() twice: "it's dumb code." - * - * Kernel guys get really het up about optimization, even when it's not - * necessary. I leave this code as a reaction against that. - */ -static inline unsigned long page_align(unsigned long addr) -{ - /* Add upwards and truncate downwards. */ - return ((addr + getpagesize()-1) & ~(getpagesize()-1)); -} - -/*L:180 - * An "initial ram disk" is a disk image loaded into memory along with the - * kernel which the kernel can use to boot from without needing any drivers. - * Most distributions now use this as standard: the initrd contains the code to - * load the appropriate driver modules for the current machine. - * - * Importantly, James Morris works for RedHat, and Fedora uses initrds for its - * kernels. He sent me this (and tells me when I break it). - */ -static unsigned long load_initrd(const char *name, unsigned long mem) -{ - int ifd; - struct stat st; - unsigned long len; - - ifd = open_or_die(name, O_RDONLY); - /* fstat() is needed to get the file size. */ - if (fstat(ifd, &st) < 0) - err(1, "fstat() on initrd '%s'", name); - - /* - * We map the initrd at the top of memory, but mmap wants it to be - * page-aligned, so we round the size up for that. - */ - len = page_align(st.st_size); - map_at(ifd, from_guest_phys(mem - len), 0, st.st_size); - /* - * Once a file is mapped, you can close the file descriptor. It's a - * little odd, but quite useful. - */ - close(ifd); - verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len); - - /* We return the initrd size. */ - return len; -} -/*:*/ - -/* - * Simple routine to roll all the commandline arguments together with spaces - * between them. - */ -static void concat(char *dst, char *args[]) -{ - unsigned int i, len = 0; - - for (i = 0; args[i]; i++) { - if (i) { - strcat(dst+len, " "); - len++; - } - strcpy(dst+len, args[i]); - len += strlen(args[i]); - } - /* In case it's empty. */ - dst[len] = '\0'; -} - -/*L:185 - * This is where we actually tell the kernel to initialize the Guest. We - * saw the arguments it expects when we looked at initialize() in lguest_user.c: - * the base of Guest "physical" memory, the top physical page to allow and the - * entry point for the Guest. - */ -static void tell_kernel(unsigned long start) -{ - unsigned long args[] = { LHREQ_INITIALIZE, - (unsigned long)guest_base, - guest_limit / getpagesize(), start, - (guest_mmio+getpagesize()-1) / getpagesize() }; - verbose("Guest: %p - %p (%#lx, MMIO %#lx)\n", - guest_base, guest_base + guest_limit, - guest_limit, guest_mmio); - lguest_fd = open_or_die("/dev/lguest", O_RDWR); - if (write(lguest_fd, args, sizeof(args)) < 0) - err(1, "Writing to /dev/lguest"); -} -/*:*/ - -/*L:200 - * Device Handling. - * - * When the Guest gives us a buffer, it sends an array of addresses and sizes. - * We need to make sure it's not trying to reach into the Launcher itself, so - * we have a convenient routine which checks it and exits with an error message - * if something funny is going on: - */ -static void *_check_pointer(struct device *d, - unsigned long addr, unsigned int size, - unsigned int line) -{ - /* - * Check if the requested address and size exceeds the allocated memory, - * or addr + size wraps around. - */ - if ((addr + size) > guest_limit || (addr + size) < addr) - bad_driver(d, "%s:%i: Invalid address %#lx", - __FILE__, line, addr); - /* - * We return a pointer for the caller's convenience, now we know it's - * safe to use. - */ - return from_guest_phys(addr); -} -/* A macro which transparently hands the line number to the real function. */ -#define check_pointer(d,addr,size) _check_pointer(d, addr, size, __LINE__) - -/* - * Each buffer in the virtqueues is actually a chain of descriptors. This - * function returns the next descriptor in the chain, or vq->vring.num if we're - * at the end. - */ -static unsigned next_desc(struct device *d, struct vring_desc *desc, - unsigned int i, unsigned int max) -{ - unsigned int next; - - /* If this descriptor says it doesn't chain, we're done. */ - if (!(desc[i].flags & VRING_DESC_F_NEXT)) - return max; - - /* Check they're not leading us off end of descriptors. */ - next = desc[i].next; - /* Make sure compiler knows to grab that: we don't want it changing! */ - wmb(); - - if (next >= max) - bad_driver(d, "Desc next is %u", next); - - return next; -} - -/* - * This actually sends the interrupt for this virtqueue, if we've used a - * buffer. - */ -static void trigger_irq(struct virtqueue *vq) -{ - unsigned long buf[] = { LHREQ_IRQ, vq->dev->config.irq_line }; - - /* Don't inform them if nothing used. */ - if (!vq->pending_used) - return; - vq->pending_used = 0; - - /* - * 2.4.7.1: - * - * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: - * The driver MUST set flags to 0 or 1. - */ - if (vq->vring.avail->flags > 1) - bad_driver_vq(vq, "avail->flags = %u\n", vq->vring.avail->flags); - - /* - * 2.4.7.2: - * - * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: - * - * - The device MUST ignore the used_event value. - * - After the device writes a descriptor index into the used ring: - * - If flags is 1, the device SHOULD NOT send an interrupt. - * - If flags is 0, the device MUST send an interrupt. - */ - if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { - return; - } - - /* - * 4.1.4.5.1: - * - * If MSI-X capability is disabled, the device MUST set the Queue - * Interrupt bit in ISR status before sending a virtqueue notification - * to the driver. - */ - vq->dev->mmio->isr = 0x1; - - /* Send the Guest an interrupt tell them we used something up. */ - if (write(lguest_fd, buf, sizeof(buf)) != 0) - err(1, "Triggering irq %i", vq->dev->config.irq_line); -} - -/* - * This looks in the virtqueue for the first available buffer, and converts - * it to an iovec for convenient access. Since descriptors consist of some - * number of output then some number of input descriptors, it's actually two - * iovecs, but we pack them into one and note how many of each there were. - * - * This function waits if necessary, and returns the descriptor number found. - */ -static unsigned wait_for_vq_desc(struct virtqueue *vq, - struct iovec iov[], - unsigned int *out_num, unsigned int *in_num) -{ - unsigned int i, head, max; - struct vring_desc *desc; - u16 last_avail = lg_last_avail(vq); - - /* - * 2.4.7.1: - * - * The driver MUST handle spurious interrupts from the device. - * - * That's why this is a while loop. - */ - - /* There's nothing available? */ - while (last_avail == vq->vring.avail->idx) { - u64 event; - - /* - * Since we're about to sleep, now is a good time to tell the - * Guest about what we've used up to now. - */ - trigger_irq(vq); - - /* OK, now we need to know about added descriptors. */ - vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY; - - /* - * They could have slipped one in as we were doing that: make - * sure it's written, then check again. - */ - mb(); - if (last_avail != vq->vring.avail->idx) { - vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; - break; - } - - /* Nothing new? Wait for eventfd to tell us they refilled. */ - if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event)) - errx(1, "Event read failed?"); - - /* We don't need to be notified again. */ - vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; - } - - /* Check it isn't doing very strange things with descriptor numbers. */ - if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num) - bad_driver_vq(vq, "Guest moved used index from %u to %u", - last_avail, vq->vring.avail->idx); - - /* - * Make sure we read the descriptor number *after* we read the ring - * update; don't let the cpu or compiler change the order. - */ - rmb(); - - /* - * Grab the next descriptor number they're advertising, and increment - * the index we've seen. - */ - head = vq->vring.avail->ring[last_avail % vq->vring.num]; - lg_last_avail(vq)++; - - /* If their number is silly, that's a fatal mistake. */ - if (head >= vq->vring.num) - bad_driver_vq(vq, "Guest says index %u is available", head); - - /* When we start there are none of either input nor output. */ - *out_num = *in_num = 0; - - max = vq->vring.num; - desc = vq->vring.desc; - i = head; - - /* - * We have to read the descriptor after we read the descriptor number, - * but there's a data dependency there so the CPU shouldn't reorder - * that: no rmb() required. - */ - - do { - /* - * If this is an indirect entry, then this buffer contains a - * descriptor table which we handle as if it's any normal - * descriptor chain. - */ - if (desc[i].flags & VRING_DESC_F_INDIRECT) { - /* 2.4.5.3.1: - * - * The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT - * flag unless the VIRTIO_F_INDIRECT_DESC feature was - * negotiated. - */ - if (!(vq->dev->features_accepted & - (1<vring.desc) - bad_driver_vq(vq, "Indirect within indirect"); - - /* - * Proposed update VIRTIO-134 spells this out: - * - * A driver MUST NOT set both VIRTQ_DESC_F_INDIRECT - * and VIRTQ_DESC_F_NEXT in flags. - */ - if (desc[i].flags & VRING_DESC_F_NEXT) - bad_driver_vq(vq, "indirect and next together"); - - if (desc[i].len % sizeof(struct vring_desc)) - bad_driver_vq(vq, - "Invalid size for indirect table"); - /* - * 2.4.5.3.2: - * - * The device MUST ignore the write-only flag - * (flags&VIRTQ_DESC_F_WRITE) in the descriptor that - * refers to an indirect table. - * - * We ignore it here: :) - */ - - max = desc[i].len / sizeof(struct vring_desc); - desc = check_pointer(vq->dev, desc[i].addr, desc[i].len); - i = 0; - - /* 2.4.5.3.1: - * - * A driver MUST NOT create a descriptor chain longer - * than the Queue Size of the device. - */ - if (max > vq->pci_config.queue_size) - bad_driver_vq(vq, - "indirect has too many entries"); - } - - /* Grab the first descriptor, and check it's OK. */ - iov[*out_num + *in_num].iov_len = desc[i].len; - iov[*out_num + *in_num].iov_base - = check_pointer(vq->dev, desc[i].addr, desc[i].len); - /* If this is an input descriptor, increment that count. */ - if (desc[i].flags & VRING_DESC_F_WRITE) - (*in_num)++; - else { - /* - * If it's an output descriptor, they're all supposed - * to come before any input descriptors. - */ - if (*in_num) - bad_driver_vq(vq, - "Descriptor has out after in"); - (*out_num)++; - } - - /* If we've got too many, that implies a descriptor loop. */ - if (*out_num + *in_num > max) - bad_driver_vq(vq, "Looped descriptor"); - } while ((i = next_desc(vq->dev, desc, i, max)) != max); - - return head; -} - -/* - * After we've used one of their buffers, we tell the Guest about it. Sometime - * later we'll want to send them an interrupt using trigger_irq(); note that - * wait_for_vq_desc() does that for us if it has to wait. - */ -static void add_used(struct virtqueue *vq, unsigned int head, int len) -{ - struct vring_used_elem *used; - - /* - * The virtqueue contains a ring of used buffers. Get a pointer to the - * next entry in that used ring. - */ - used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num]; - used->id = head; - used->len = len; - /* Make sure buffer is written before we update index. */ - wmb(); - vq->vring.used->idx++; - vq->pending_used++; -} - -/* And here's the combo meal deal. Supersize me! */ -static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len) -{ - add_used(vq, head, len); - trigger_irq(vq); -} - -/* - * The Console - * - * We associate some data with the console for our exit hack. - */ -struct console_abort { - /* How many times have they hit ^C? */ - int count; - /* When did they start? */ - struct timeval start; -}; - -/* This is the routine which handles console input (ie. stdin). */ -static void console_input(struct virtqueue *vq) -{ - int len; - unsigned int head, in_num, out_num; - struct console_abort *abort = vq->dev->priv; - struct iovec iov[vq->vring.num]; - - /* Make sure there's a descriptor available. */ - head = wait_for_vq_desc(vq, iov, &out_num, &in_num); - if (out_num) - bad_driver_vq(vq, "Output buffers in console in queue?"); - - /* Read into it. This is where we usually wait. */ - len = readv(STDIN_FILENO, iov, in_num); - if (len <= 0) { - /* Ran out of input? */ - warnx("Failed to get console input, ignoring console."); - /* - * For simplicity, dying threads kill the whole Launcher. So - * just nap here. - */ - for (;;) - pause(); - } - - /* Tell the Guest we used a buffer. */ - add_used_and_trigger(vq, head, len); - - /* - * Three ^C within one second? Exit. - * - * This is such a hack, but works surprisingly well. Each ^C has to - * be in a buffer by itself, so they can't be too fast. But we check - * that we get three within about a second, so they can't be too - * slow. - */ - if (len != 1 || ((char *)iov[0].iov_base)[0] != 3) { - abort->count = 0; - return; - } - - abort->count++; - if (abort->count == 1) - gettimeofday(&abort->start, NULL); - else if (abort->count == 3) { - struct timeval now; - gettimeofday(&now, NULL); - /* Kill all Launcher processes with SIGINT, like normal ^C */ - if (now.tv_sec <= abort->start.tv_sec+1) - kill(0, SIGINT); - abort->count = 0; - } -} - -/* This is the routine which handles console output (ie. stdout). */ -static void console_output(struct virtqueue *vq) -{ - unsigned int head, out, in; - struct iovec iov[vq->vring.num]; - - /* We usually wait in here, for the Guest to give us something. */ - head = wait_for_vq_desc(vq, iov, &out, &in); - if (in) - bad_driver_vq(vq, "Input buffers in console output queue?"); - - /* writev can return a partial write, so we loop here. */ - while (!iov_empty(iov, out)) { - int len = writev(STDOUT_FILENO, iov, out); - if (len <= 0) { - warn("Write to stdout gave %i (%d)", len, errno); - break; - } - iov_consume(vq->dev, iov, out, NULL, len); - } - - /* - * We're finished with that buffer: if we're going to sleep, - * wait_for_vq_desc() will prod the Guest with an interrupt. - */ - add_used(vq, head, 0); -} - -/* - * The Network - * - * Handling output for network is also simple: we get all the output buffers - * and write them to /dev/net/tun. - */ -struct net_info { - int tunfd; -}; - -static void net_output(struct virtqueue *vq) -{ - struct net_info *net_info = vq->dev->priv; - unsigned int head, out, in; - struct iovec iov[vq->vring.num]; - - /* We usually wait in here for the Guest to give us a packet. */ - head = wait_for_vq_desc(vq, iov, &out, &in); - if (in) - bad_driver_vq(vq, "Input buffers in net output queue?"); - /* - * Send the whole thing through to /dev/net/tun. It expects the exact - * same format: what a coincidence! - */ - if (writev(net_info->tunfd, iov, out) < 0) - warnx("Write to tun failed (%d)?", errno); - - /* - * Done with that one; wait_for_vq_desc() will send the interrupt if - * all packets are processed. - */ - add_used(vq, head, 0); -} - -/* - * Handling network input is a bit trickier, because I've tried to optimize it. - * - * First we have a helper routine which tells is if from this file descriptor - * (ie. the /dev/net/tun device) will block: - */ -static bool will_block(int fd) -{ - fd_set fdset; - struct timeval zero = { 0, 0 }; - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - return select(fd+1, &fdset, NULL, NULL, &zero) != 1; -} - -/* - * This handles packets coming in from the tun device to our Guest. Like all - * service routines, it gets called again as soon as it returns, so you don't - * see a while(1) loop here. - */ -static void net_input(struct virtqueue *vq) -{ - int len; - unsigned int head, out, in; - struct iovec iov[vq->vring.num]; - struct net_info *net_info = vq->dev->priv; - - /* - * Get a descriptor to write an incoming packet into. This will also - * send an interrupt if they're out of descriptors. - */ - head = wait_for_vq_desc(vq, iov, &out, &in); - if (out) - bad_driver_vq(vq, "Output buffers in net input queue?"); - - /* - * If it looks like we'll block reading from the tun device, send them - * an interrupt. - */ - if (vq->pending_used && will_block(net_info->tunfd)) - trigger_irq(vq); - - /* - * Read in the packet. This is where we normally wait (when there's no - * incoming network traffic). - */ - len = readv(net_info->tunfd, iov, in); - if (len <= 0) - warn("Failed to read from tun (%d).", errno); - - /* - * Mark that packet buffer as used, but don't interrupt here. We want - * to wait until we've done as much work as we can. - */ - add_used(vq, head, len); -} -/*:*/ - -/* This is the helper to create threads: run the service routine in a loop. */ -static int do_thread(void *_vq) -{ - struct virtqueue *vq = _vq; - - for (;;) - vq->service(vq); - return 0; -} - -/* - * When a child dies, we kill our entire process group with SIGTERM. This - * also has the side effect that the shell restores the console for us! - */ -static void kill_launcher(int signal) -{ - kill(0, SIGTERM); -} - -static void reset_vq_pci_config(struct virtqueue *vq) -{ - vq->pci_config.queue_size = VIRTQUEUE_NUM; - vq->pci_config.queue_enable = 0; -} - -static void reset_device(struct device *dev) -{ - struct virtqueue *vq; - - verbose("Resetting device %s\n", dev->name); - - /* Clear any features they've acked. */ - dev->features_accepted = 0; - - /* We're going to be explicitly killing threads, so ignore them. */ - signal(SIGCHLD, SIG_IGN); - - /* - * 4.1.4.3.1: - * - * The device MUST present a 0 in queue_enable on reset. - * - * This means we set it here, and reset the saved ones in every vq. - */ - dev->mmio->cfg.queue_enable = 0; - - /* Get rid of the virtqueue threads */ - for (vq = dev->vq; vq; vq = vq->next) { - vq->last_avail_idx = 0; - reset_vq_pci_config(vq); - if (vq->thread != (pid_t)-1) { - kill(vq->thread, SIGTERM); - waitpid(vq->thread, NULL, 0); - vq->thread = (pid_t)-1; - } - } - dev->running = false; - dev->wrote_features_ok = false; - - /* Now we care if threads die. */ - signal(SIGCHLD, (void *)kill_launcher); -} - -static void cleanup_devices(void) -{ - unsigned int i; - - for (i = 1; i < MAX_PCI_DEVICES; i++) { - struct device *d = devices.pci[i]; - if (!d) - continue; - reset_device(d); - } - - /* If we saved off the original terminal settings, restore them now. */ - if (orig_term.c_lflag & (ISIG|ICANON|ECHO)) - tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); -} - -/*L:217 - * We do PCI. This is mainly done to let us test the kernel virtio PCI - * code. - */ - -/* Linux expects a PCI host bridge: ours is a dummy, and first on the bus. */ -static struct device pci_host_bridge; - -static void init_pci_host_bridge(void) -{ - pci_host_bridge.name = "PCI Host Bridge"; - pci_host_bridge.config.class = 0x06; /* bridge */ - pci_host_bridge.config.subclass = 0; /* host bridge */ - devices.pci[0] = &pci_host_bridge; -} - -/* The IO ports used to read the PCI config space. */ -#define PCI_CONFIG_ADDR 0xCF8 -#define PCI_CONFIG_DATA 0xCFC - -/* - * Not really portable, but does help readability: this is what the Guest - * writes to the PCI_CONFIG_ADDR IO port. - */ -union pci_config_addr { - struct { - unsigned mbz: 2; - unsigned offset: 6; - unsigned funcnum: 3; - unsigned devnum: 5; - unsigned busnum: 8; - unsigned reserved: 7; - unsigned enabled : 1; - } bits; - u32 val; -}; - -/* - * We cache what they wrote to the address port, so we know what they're - * talking about when they access the data port. - */ -static union pci_config_addr pci_config_addr; - -static struct device *find_pci_device(unsigned int index) -{ - return devices.pci[index]; -} - -/* PCI can do 1, 2 and 4 byte reads; we handle that here. */ -static void ioread(u16 off, u32 v, u32 mask, u32 *val) -{ - assert(off < 4); - assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF); - *val = (v >> (off * 8)) & mask; -} - -/* PCI can do 1, 2 and 4 byte writes; we handle that here. */ -static void iowrite(u16 off, u32 v, u32 mask, u32 *dst) -{ - assert(off < 4); - assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF); - *dst &= ~(mask << (off * 8)); - *dst |= (v & mask) << (off * 8); -} - -/* - * Where PCI_CONFIG_DATA accesses depends on the previous write to - * PCI_CONFIG_ADDR. - */ -static struct device *dev_and_reg(u32 *reg) -{ - if (!pci_config_addr.bits.enabled) - return NULL; - - if (pci_config_addr.bits.funcnum != 0) - return NULL; - - if (pci_config_addr.bits.busnum != 0) - return NULL; - - if (pci_config_addr.bits.offset * 4 >= sizeof(struct pci_config)) - return NULL; - - *reg = pci_config_addr.bits.offset; - return find_pci_device(pci_config_addr.bits.devnum); -} - -/* - * We can get invalid combinations of values while they're writing, so we - * only fault if they try to write with some invalid bar/offset/length. - */ -static bool valid_bar_access(struct device *d, - struct virtio_pci_cfg_cap_u32 *cfg_access) -{ - /* We only have 1 bar (BAR0) */ - if (cfg_access->cap.bar != 0) - return false; - - /* Check it's within BAR0. */ - if (cfg_access->cap.offset >= d->mmio_size - || cfg_access->cap.offset + cfg_access->cap.length > d->mmio_size) - return false; - - /* Check length is 1, 2 or 4. */ - if (cfg_access->cap.length != 1 - && cfg_access->cap.length != 2 - && cfg_access->cap.length != 4) - return false; - - /* - * 4.1.4.7.2: - * - * The driver MUST NOT write a cap.offset which is not a multiple of - * cap.length (ie. all accesses MUST be aligned). - */ - if (cfg_access->cap.offset % cfg_access->cap.length != 0) - return false; - - /* Return pointer into word in BAR0. */ - return true; -} - -/* Is this accessing the PCI config address port?. */ -static bool is_pci_addr_port(u16 port) -{ - return port >= PCI_CONFIG_ADDR && port < PCI_CONFIG_ADDR + 4; -} - -static bool pci_addr_iowrite(u16 port, u32 mask, u32 val) -{ - iowrite(port - PCI_CONFIG_ADDR, val, mask, - &pci_config_addr.val); - verbose("PCI%s: %#x/%x: bus %u dev %u func %u reg %u\n", - pci_config_addr.bits.enabled ? "" : " DISABLED", - val, mask, - pci_config_addr.bits.busnum, - pci_config_addr.bits.devnum, - pci_config_addr.bits.funcnum, - pci_config_addr.bits.offset); - return true; -} - -static void pci_addr_ioread(u16 port, u32 mask, u32 *val) -{ - ioread(port - PCI_CONFIG_ADDR, pci_config_addr.val, mask, val); -} - -/* Is this accessing the PCI config data port?. */ -static bool is_pci_data_port(u16 port) -{ - return port >= PCI_CONFIG_DATA && port < PCI_CONFIG_DATA + 4; -} - -static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask); - -static bool pci_data_iowrite(u16 port, u32 mask, u32 val) -{ - u32 reg, portoff; - struct device *d = dev_and_reg(®); - - /* Complain if they don't belong to a device. */ - if (!d) - return false; - - /* They can do 1 byte writes, etc. */ - portoff = port - PCI_CONFIG_DATA; - - /* - * PCI uses a weird way to determine the BAR size: the OS - * writes all 1's, and sees which ones stick. - */ - if (&d->config_words[reg] == &d->config.bar[0]) { - int i; - - iowrite(portoff, val, mask, &d->config.bar[0]); - for (i = 0; (1 << i) < d->mmio_size; i++) - d->config.bar[0] &= ~(1 << i); - return true; - } else if ((&d->config_words[reg] > &d->config.bar[0] - && &d->config_words[reg] <= &d->config.bar[6]) - || &d->config_words[reg] == &d->config.expansion_rom_addr) { - /* Allow writing to any other BAR, or expansion ROM */ - iowrite(portoff, val, mask, &d->config_words[reg]); - return true; - /* We let them override latency timer and cacheline size */ - } else if (&d->config_words[reg] == (void *)&d->config.cacheline_size) { - /* Only let them change the first two fields. */ - if (mask == 0xFFFFFFFF) - mask = 0xFFFF; - iowrite(portoff, val, mask, &d->config_words[reg]); - return true; - } else if (&d->config_words[reg] == (void *)&d->config.command - && mask == 0xFFFF) { - /* Ignore command writes. */ - return true; - } else if (&d->config_words[reg] - == (void *)&d->config.cfg_access.cap.bar - || &d->config_words[reg] - == &d->config.cfg_access.cap.length - || &d->config_words[reg] - == &d->config.cfg_access.cap.offset) { - - /* - * The VIRTIO_PCI_CAP_PCI_CFG capability - * provides a backdoor to access the MMIO - * regions without mapping them. Weird, but - * useful. - */ - iowrite(portoff, val, mask, &d->config_words[reg]); - return true; - } else if (&d->config_words[reg] == &d->config.cfg_access.pci_cfg_data) { - u32 write_mask; - - /* - * 4.1.4.7.1: - * - * Upon detecting driver write access to pci_cfg_data, the - * device MUST execute a write access at offset cap.offset at - * BAR selected by cap.bar using the first cap.length bytes - * from pci_cfg_data. - */ - - /* Must be bar 0 */ - if (!valid_bar_access(d, &d->config.cfg_access)) - return false; - - iowrite(portoff, val, mask, &d->config.cfg_access.pci_cfg_data); - - /* - * Now emulate a write. The mask we use is set by - * len, *not* this write! - */ - write_mask = (1ULL<<(8*d->config.cfg_access.cap.length)) - 1; - verbose("Window writing %#x/%#x to bar %u, offset %u len %u\n", - d->config.cfg_access.pci_cfg_data, write_mask, - d->config.cfg_access.cap.bar, - d->config.cfg_access.cap.offset, - d->config.cfg_access.cap.length); - - emulate_mmio_write(d, d->config.cfg_access.cap.offset, - d->config.cfg_access.pci_cfg_data, - write_mask); - return true; - } - - /* - * 4.1.4.1: - * - * The driver MUST NOT write into any field of the capability - * structure, with the exception of those with cap_type - * VIRTIO_PCI_CAP_PCI_CFG... - */ - return false; -} - -static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask); - -static void pci_data_ioread(u16 port, u32 mask, u32 *val) -{ - u32 reg; - struct device *d = dev_and_reg(®); - - if (!d) - return; - - /* Read through the PCI MMIO access window is special */ - if (&d->config_words[reg] == &d->config.cfg_access.pci_cfg_data) { - u32 read_mask; - - /* - * 4.1.4.7.1: - * - * Upon detecting driver read access to pci_cfg_data, the - * device MUST execute a read access of length cap.length at - * offset cap.offset at BAR selected by cap.bar and store the - * first cap.length bytes in pci_cfg_data. - */ - /* Must be bar 0 */ - if (!valid_bar_access(d, &d->config.cfg_access)) - bad_driver(d, - "Invalid cfg_access to bar%u, offset %u len %u", - d->config.cfg_access.cap.bar, - d->config.cfg_access.cap.offset, - d->config.cfg_access.cap.length); - - /* - * Read into the window. The mask we use is set by - * len, *not* this read! - */ - read_mask = (1ULL<<(8*d->config.cfg_access.cap.length))-1; - d->config.cfg_access.pci_cfg_data - = emulate_mmio_read(d, - d->config.cfg_access.cap.offset, - read_mask); - verbose("Window read %#x/%#x from bar %u, offset %u len %u\n", - d->config.cfg_access.pci_cfg_data, read_mask, - d->config.cfg_access.cap.bar, - d->config.cfg_access.cap.offset, - d->config.cfg_access.cap.length); - } - ioread(port - PCI_CONFIG_DATA, d->config_words[reg], mask, val); -} - -/*L:216 - * This is where we emulate a handful of Guest instructions. It's ugly - * and we used to do it in the kernel but it grew over time. - */ - -/* - * We use the ptrace syscall's pt_regs struct to talk about registers - * to lguest: these macros convert the names to the offsets. - */ -#define getreg(name) getreg_off(offsetof(struct user_regs_struct, name)) -#define setreg(name, val) \ - setreg_off(offsetof(struct user_regs_struct, name), (val)) - -static u32 getreg_off(size_t offset) -{ - u32 r; - unsigned long args[] = { LHREQ_GETREG, offset }; - - if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) - err(1, "Getting register %u", offset); - if (pread(lguest_fd, &r, sizeof(r), cpu_id) != sizeof(r)) - err(1, "Reading register %u", offset); - - return r; -} - -static void setreg_off(size_t offset, u32 val) -{ - unsigned long args[] = { LHREQ_SETREG, offset, val }; - - if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) - err(1, "Setting register %u", offset); -} - -/* Get register by instruction encoding */ -static u32 getreg_num(unsigned regnum, u32 mask) -{ - /* 8 bit ops use regnums 4-7 for high parts of word */ - if (mask == 0xFF && (regnum & 0x4)) - return getreg_num(regnum & 0x3, 0xFFFF) >> 8; - - switch (regnum) { - case 0: return getreg(eax) & mask; - case 1: return getreg(ecx) & mask; - case 2: return getreg(edx) & mask; - case 3: return getreg(ebx) & mask; - case 4: return getreg(esp) & mask; - case 5: return getreg(ebp) & mask; - case 6: return getreg(esi) & mask; - case 7: return getreg(edi) & mask; - } - abort(); -} - -/* Set register by instruction encoding */ -static void setreg_num(unsigned regnum, u32 val, u32 mask) -{ - /* Don't try to set bits out of range */ - assert(~(val & ~mask)); - - /* 8 bit ops use regnums 4-7 for high parts of word */ - if (mask == 0xFF && (regnum & 0x4)) { - /* Construct the 16 bits we want. */ - val = (val << 8) | getreg_num(regnum & 0x3, 0xFF); - setreg_num(regnum & 0x3, val, 0xFFFF); - return; - } - - switch (regnum) { - case 0: setreg(eax, val | (getreg(eax) & ~mask)); return; - case 1: setreg(ecx, val | (getreg(ecx) & ~mask)); return; - case 2: setreg(edx, val | (getreg(edx) & ~mask)); return; - case 3: setreg(ebx, val | (getreg(ebx) & ~mask)); return; - case 4: setreg(esp, val | (getreg(esp) & ~mask)); return; - case 5: setreg(ebp, val | (getreg(ebp) & ~mask)); return; - case 6: setreg(esi, val | (getreg(esi) & ~mask)); return; - case 7: setreg(edi, val | (getreg(edi) & ~mask)); return; - } - abort(); -} - -/* Get bytes of displacement appended to instruction, from r/m encoding */ -static u32 insn_displacement_len(u8 mod_reg_rm) -{ - /* Switch on the mod bits */ - switch (mod_reg_rm >> 6) { - case 0: - /* If mod == 0, and r/m == 101, 16-bit displacement follows */ - if ((mod_reg_rm & 0x7) == 0x5) - return 2; - /* Normally, mod == 0 means no literal displacement */ - return 0; - case 1: - /* One byte displacement */ - return 1; - case 2: - /* Four byte displacement */ - return 4; - case 3: - /* Register mode */ - return 0; - } - abort(); -} - -static void emulate_insn(const u8 insn[]) -{ - unsigned long args[] = { LHREQ_TRAP, 13 }; - unsigned int insnlen = 0, in = 0, small_operand = 0, byte_access; - unsigned int eax, port, mask; - /* - * Default is to return all-ones on IO port reads, which traditionally - * means "there's nothing there". - */ - u32 val = 0xFFFFFFFF; - - /* - * This must be the Guest kernel trying to do something, not userspace! - * The bottom two bits of the CS segment register are the privilege - * level. - */ - if ((getreg(xcs) & 3) != 0x1) - goto no_emulate; - - /* Decoding x86 instructions is icky. */ - - /* - * Around 2.6.33, the kernel started using an emulation for the - * cmpxchg8b instruction in early boot on many configurations. This - * code isn't paravirtualized, and it tries to disable interrupts. - * Ignore it, which will Mostly Work. - */ - if (insn[insnlen] == 0xfa) { - /* "cli", or Clear Interrupt Enable instruction. Skip it. */ - insnlen = 1; - goto skip_insn; - } - - /* - * 0x66 is an "operand prefix". It means a 16, not 32 bit in/out. - */ - if (insn[insnlen] == 0x66) { - small_operand = 1; - /* The instruction is 1 byte so far, read the next byte. */ - insnlen = 1; - } - - /* If the lower bit isn't set, it's a single byte access */ - byte_access = !(insn[insnlen] & 1); - - /* - * Now we can ignore the lower bit and decode the 4 opcodes - * we need to emulate. - */ - switch (insn[insnlen] & 0xFE) { - case 0xE4: /* in ,%al */ - port = insn[insnlen+1]; - insnlen += 2; - in = 1; - break; - case 0xEC: /* in (%dx),%al */ - port = getreg(edx) & 0xFFFF; - insnlen += 1; - in = 1; - break; - case 0xE6: /* out %al, */ - port = insn[insnlen+1]; - insnlen += 2; - break; - case 0xEE: /* out %al,(%dx) */ - port = getreg(edx) & 0xFFFF; - insnlen += 1; - break; - default: - /* OK, we don't know what this is, can't emulate. */ - goto no_emulate; - } - - /* Set a mask of the 1, 2 or 4 bytes, depending on size of IO */ - if (byte_access) - mask = 0xFF; - else if (small_operand) - mask = 0xFFFF; - else - mask = 0xFFFFFFFF; - - /* - * If it was an "IN" instruction, they expect the result to be read - * into %eax, so we change %eax. - */ - eax = getreg(eax); - - if (in) { - /* This is the PS/2 keyboard status; 1 means ready for output */ - if (port == 0x64) - val = 1; - else if (is_pci_addr_port(port)) - pci_addr_ioread(port, mask, &val); - else if (is_pci_data_port(port)) - pci_data_ioread(port, mask, &val); - - /* Clear the bits we're about to read */ - eax &= ~mask; - /* Copy bits in from val. */ - eax |= val & mask; - /* Now update the register. */ - setreg(eax, eax); - } else { - if (is_pci_addr_port(port)) { - if (!pci_addr_iowrite(port, mask, eax)) - goto bad_io; - } else if (is_pci_data_port(port)) { - if (!pci_data_iowrite(port, mask, eax)) - goto bad_io; - } - /* There are many other ports, eg. CMOS clock, serial - * and parallel ports, so we ignore them all. */ - } - - verbose("IO %s of %x to %u: %#08x\n", - in ? "IN" : "OUT", mask, port, eax); -skip_insn: - /* Finally, we've "done" the instruction, so move past it. */ - setreg(eip, getreg(eip) + insnlen); - return; - -bad_io: - warnx("Attempt to %s port %u (%#x mask)", - in ? "read from" : "write to", port, mask); - -no_emulate: - /* Inject trap into Guest. */ - if (write(lguest_fd, args, sizeof(args)) < 0) - err(1, "Reinjecting trap 13 for fault at %#x", getreg(eip)); -} - -static struct device *find_mmio_region(unsigned long paddr, u32 *off) -{ - unsigned int i; - - for (i = 1; i < MAX_PCI_DEVICES; i++) { - struct device *d = devices.pci[i]; - - if (!d) - continue; - if (paddr < d->mmio_addr) - continue; - if (paddr >= d->mmio_addr + d->mmio_size) - continue; - *off = paddr - d->mmio_addr; - return d; - } - return NULL; -} - -/* FIXME: Use vq array. */ -static struct virtqueue *vq_by_num(struct device *d, u32 num) -{ - struct virtqueue *vq = d->vq; - - while (num-- && vq) - vq = vq->next; - - return vq; -} - -static void save_vq_config(const struct virtio_pci_common_cfg *cfg, - struct virtqueue *vq) -{ - vq->pci_config = *cfg; -} - -static void restore_vq_config(struct virtio_pci_common_cfg *cfg, - struct virtqueue *vq) -{ - /* Only restore the per-vq part */ - size_t off = offsetof(struct virtio_pci_common_cfg, queue_size); - - memcpy((void *)cfg + off, (void *)&vq->pci_config + off, - sizeof(*cfg) - off); -} - -/* - * 4.1.4.3.2: - * - * The driver MUST configure the other virtqueue fields before - * enabling the virtqueue with queue_enable. - * - * When they enable the virtqueue, we check that their setup is valid. - */ -static void check_virtqueue(struct device *d, struct virtqueue *vq) -{ - /* Because lguest is 32 bit, all the descriptor high bits must be 0 */ - if (vq->pci_config.queue_desc_hi - || vq->pci_config.queue_avail_hi - || vq->pci_config.queue_used_hi) - bad_driver_vq(vq, "invalid 64-bit queue address"); - - /* - * 2.4.1: - * - * The driver MUST ensure that the physical address of the first byte - * of each virtqueue part is a multiple of the specified alignment - * value in the above table. - */ - if (vq->pci_config.queue_desc_lo % 16 - || vq->pci_config.queue_avail_lo % 2 - || vq->pci_config.queue_used_lo % 4) - bad_driver_vq(vq, "invalid alignment in queue addresses"); - - /* Initialize the virtqueue and check they're all in range. */ - vq->vring.num = vq->pci_config.queue_size; - vq->vring.desc = check_pointer(vq->dev, - vq->pci_config.queue_desc_lo, - sizeof(*vq->vring.desc) * vq->vring.num); - vq->vring.avail = check_pointer(vq->dev, - vq->pci_config.queue_avail_lo, - sizeof(*vq->vring.avail) - + (sizeof(vq->vring.avail->ring[0]) - * vq->vring.num)); - vq->vring.used = check_pointer(vq->dev, - vq->pci_config.queue_used_lo, - sizeof(*vq->vring.used) - + (sizeof(vq->vring.used->ring[0]) - * vq->vring.num)); - - /* - * 2.4.9.1: - * - * The driver MUST initialize flags in the used ring to 0 - * when allocating the used ring. - */ - if (vq->vring.used->flags != 0) - bad_driver_vq(vq, "invalid initial used.flags %#x", - vq->vring.used->flags); -} - -static void start_virtqueue(struct virtqueue *vq) -{ - /* - * Create stack for thread. Since the stack grows upwards, we point - * the stack pointer to the end of this region. - */ - char *stack = malloc(32768); - - /* Create a zero-initialized eventfd. */ - vq->eventfd = eventfd(0, 0); - if (vq->eventfd < 0) - err(1, "Creating eventfd"); - - /* - * CLONE_VM: because it has to access the Guest memory, and SIGCHLD so - * we get a signal if it dies. - */ - vq->thread = clone(do_thread, stack + 32768, CLONE_VM | SIGCHLD, vq); - if (vq->thread == (pid_t)-1) - err(1, "Creating clone"); -} - -static void start_virtqueues(struct device *d) -{ - struct virtqueue *vq; - - for (vq = d->vq; vq; vq = vq->next) { - if (vq->pci_config.queue_enable) - start_virtqueue(vq); - } -} - -static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) -{ - struct virtqueue *vq; - - switch (off) { - case offsetof(struct virtio_pci_mmio, cfg.device_feature_select): - /* - * 4.1.4.3.1: - * - * The device MUST present the feature bits it is offering in - * device_feature, starting at bit device_feature_select ∗ 32 - * for any device_feature_select written by the driver - */ - if (val == 0) - d->mmio->cfg.device_feature = d->features; - else if (val == 1) - d->mmio->cfg.device_feature = (d->features >> 32); - else - d->mmio->cfg.device_feature = 0; - goto feature_write_through32; - case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): - if (val > 1) - bad_driver(d, "Unexpected driver select %u", val); - goto feature_write_through32; - case offsetof(struct virtio_pci_mmio, cfg.guest_feature): - if (d->mmio->cfg.guest_feature_select == 0) { - d->features_accepted &= ~((u64)0xFFFFFFFF); - d->features_accepted |= val; - } else { - assert(d->mmio->cfg.guest_feature_select == 1); - d->features_accepted &= 0xFFFFFFFF; - d->features_accepted |= ((u64)val) << 32; - } - /* - * 2.2.1: - * - * The driver MUST NOT accept a feature which the device did - * not offer - */ - if (d->features_accepted & ~d->features) - bad_driver(d, "over-accepted features %#llx of %#llx", - d->features_accepted, d->features); - goto feature_write_through32; - case offsetof(struct virtio_pci_mmio, cfg.device_status): { - u8 prev; - - verbose("%s: device status -> %#x\n", d->name, val); - /* - * 4.1.4.3.1: - * - * The device MUST reset when 0 is written to device_status, - * and present a 0 in device_status once that is done. - */ - if (val == 0) { - reset_device(d); - goto write_through8; - } - - /* 2.1.1: The driver MUST NOT clear a device status bit. */ - if (d->mmio->cfg.device_status & ~val) - bad_driver(d, "unset of device status bit %#x -> %#x", - d->mmio->cfg.device_status, val); - - /* - * 2.1.2: - * - * The device MUST NOT consume buffers or notify the driver - * before DRIVER_OK. - */ - if (val & VIRTIO_CONFIG_S_DRIVER_OK - && !(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) - start_virtqueues(d); - - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - * - Reset the device. - * - Set the ACKNOWLEDGE status bit: the guest OS has - * notice the device. - * - Set the DRIVER status bit: the guest OS knows how - * to drive the device. - * - Read device feature bits, and write the subset - * of feature bits understood by the OS and driver - * to the device. During this step the driver MAY - * read (but MUST NOT write) the device-specific - * configuration fields to check that it can - * support the device before accepting it. - * - Set the FEATURES_OK status bit. The driver - * MUST not accept new feature bits after this - * step. - * - Re-read device status to ensure the FEATURES_OK - * bit is still set: otherwise, the device does - * not support our subset of features and the - * device is unusable. - * - Perform device-specific setup, including - * discovery of virtqueues for the device, - * optional per-bus setup, reading and possibly - * writing the device’s virtio configuration - * space, and population of virtqueues. - * - Set the DRIVER_OK status bit. At this point the - * device is “liveâ€. - */ - prev = 0; - switch (val & ~d->mmio->cfg.device_status) { - case VIRTIO_CONFIG_S_DRIVER_OK: - prev |= VIRTIO_CONFIG_S_FEATURES_OK; /* fall thru */ - case VIRTIO_CONFIG_S_FEATURES_OK: - prev |= VIRTIO_CONFIG_S_DRIVER; /* fall thru */ - case VIRTIO_CONFIG_S_DRIVER: - prev |= VIRTIO_CONFIG_S_ACKNOWLEDGE; /* fall thru */ - case VIRTIO_CONFIG_S_ACKNOWLEDGE: - break; - default: - bad_driver(d, "unknown device status bit %#x -> %#x", - d->mmio->cfg.device_status, val); - } - if (d->mmio->cfg.device_status != prev) - bad_driver(d, "unexpected status transition %#x -> %#x", - d->mmio->cfg.device_status, val); - - /* If they just wrote FEATURES_OK, we make sure they read */ - switch (val & ~d->mmio->cfg.device_status) { - case VIRTIO_CONFIG_S_FEATURES_OK: - d->wrote_features_ok = true; - break; - case VIRTIO_CONFIG_S_DRIVER_OK: - if (d->wrote_features_ok) - bad_driver(d, "did not re-read FEATURES_OK"); - break; - } - goto write_through8; - } - case offsetof(struct virtio_pci_mmio, cfg.queue_select): - vq = vq_by_num(d, val); - /* - * 4.1.4.3.1: - * - * The device MUST present a 0 in queue_size if the virtqueue - * corresponding to the current queue_select is unavailable. - */ - if (!vq) { - d->mmio->cfg.queue_size = 0; - goto write_through16; - } - /* Save registers for old vq, if it was a valid vq */ - if (d->mmio->cfg.queue_size) - save_vq_config(&d->mmio->cfg, - vq_by_num(d, d->mmio->cfg.queue_select)); - /* Restore the registers for the queue they asked for */ - restore_vq_config(&d->mmio->cfg, vq); - goto write_through16; - case offsetof(struct virtio_pci_mmio, cfg.queue_size): - /* - * 4.1.4.3.2: - * - * The driver MUST NOT write a value which is not a power of 2 - * to queue_size. - */ - if (val & (val-1)) - bad_driver(d, "invalid queue size %u", val); - if (d->mmio->cfg.queue_enable) - bad_driver(d, "changing queue size on live device"); - goto write_through16; - case offsetof(struct virtio_pci_mmio, cfg.queue_msix_vector): - bad_driver(d, "attempt to set MSIX vector to %u", val); - case offsetof(struct virtio_pci_mmio, cfg.queue_enable): { - struct virtqueue *vq = vq_by_num(d, d->mmio->cfg.queue_select); - - /* - * 4.1.4.3.2: - * - * The driver MUST NOT write a 0 to queue_enable. - */ - if (val != 1) - bad_driver(d, "setting queue_enable to %u", val); - - /* - * 3.1.1: - * - * 7. Perform device-specific setup, including discovery of - * virtqueues for the device, optional per-bus setup, - * reading and possibly writing the device’s virtio - * configuration space, and population of virtqueues. - * 8. Set the DRIVER_OK status bit. - * - * All our devices require all virtqueues to be enabled, so - * they should have done that before setting DRIVER_OK. - */ - if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK) - bad_driver(d, "enabling vq after DRIVER_OK"); - - d->mmio->cfg.queue_enable = val; - save_vq_config(&d->mmio->cfg, vq); - check_virtqueue(d, vq); - goto write_through16; - } - case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off): - bad_driver(d, "attempt to write to queue_notify_off"); - case offsetof(struct virtio_pci_mmio, cfg.queue_desc_lo): - case offsetof(struct virtio_pci_mmio, cfg.queue_desc_hi): - case offsetof(struct virtio_pci_mmio, cfg.queue_avail_lo): - case offsetof(struct virtio_pci_mmio, cfg.queue_avail_hi): - case offsetof(struct virtio_pci_mmio, cfg.queue_used_lo): - case offsetof(struct virtio_pci_mmio, cfg.queue_used_hi): - /* - * 4.1.4.3.2: - * - * The driver MUST configure the other virtqueue fields before - * enabling the virtqueue with queue_enable. - */ - if (d->mmio->cfg.queue_enable) - bad_driver(d, "changing queue on live device"); - - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - *... - * 5. Set the FEATURES_OK status bit. The driver MUST not - * accept new feature bits after this step. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK)) - bad_driver(d, "setting up vq before FEATURES_OK"); - - /* - * 6. Re-read device status to ensure the FEATURES_OK bit is - * still set... - */ - if (d->wrote_features_ok) - bad_driver(d, "didn't re-read FEATURES_OK before setup"); - - goto write_through32; - case offsetof(struct virtio_pci_mmio, notify): - vq = vq_by_num(d, val); - if (!vq) - bad_driver(d, "Invalid vq notification on %u", val); - /* Notify the process handling this vq by adding 1 to eventfd */ - write(vq->eventfd, "\1\0\0\0\0\0\0\0", 8); - goto write_through16; - case offsetof(struct virtio_pci_mmio, isr): - bad_driver(d, "Unexpected write to isr"); - /* Weird corner case: write to emerg_wr of console */ - case sizeof(struct virtio_pci_mmio) - + offsetof(struct virtio_console_config, emerg_wr): - if (strcmp(d->name, "console") == 0) { - char c = val; - write(STDOUT_FILENO, &c, 1); - goto write_through32; - } - /* Fall through... */ - default: - /* - * 4.1.4.3.2: - * - * The driver MUST NOT write to device_feature, num_queues, - * config_generation or queue_notify_off. - */ - bad_driver(d, "Unexpected write to offset %u", off); - } - -feature_write_through32: - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - *... - * - Set the DRIVER status bit: the guest OS knows how - * to drive the device. - * - Read device feature bits, and write the subset - * of feature bits understood by the OS and driver - * to the device. - *... - * - Set the FEATURES_OK status bit. The driver MUST not - * accept new feature bits after this step. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) - bad_driver(d, "feature write before VIRTIO_CONFIG_S_DRIVER"); - if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK) - bad_driver(d, "feature write after VIRTIO_CONFIG_S_FEATURES_OK"); - - /* - * 4.1.3.1: - * - * The driver MUST access each field using the “natural†access - * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for - * 16-bit fields and 8-bit accesses for 8-bit fields. - */ -write_through32: - if (mask != 0xFFFFFFFF) { - bad_driver(d, "non-32-bit write to offset %u (%#x)", - off, getreg(eip)); - return; - } - memcpy((char *)d->mmio + off, &val, 4); - return; - -write_through16: - if (mask != 0xFFFF) - bad_driver(d, "non-16-bit write to offset %u (%#x)", - off, getreg(eip)); - memcpy((char *)d->mmio + off, &val, 2); - return; - -write_through8: - if (mask != 0xFF) - bad_driver(d, "non-8-bit write to offset %u (%#x)", - off, getreg(eip)); - memcpy((char *)d->mmio + off, &val, 1); - return; -} - -static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask) -{ - u8 isr; - u32 val = 0; - - switch (off) { - case offsetof(struct virtio_pci_mmio, cfg.device_feature_select): - case offsetof(struct virtio_pci_mmio, cfg.device_feature): - case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): - case offsetof(struct virtio_pci_mmio, cfg.guest_feature): - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - *... - * - Set the DRIVER status bit: the guest OS knows how - * to drive the device. - * - Read device feature bits, and write the subset - * of feature bits understood by the OS and driver - * to the device. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) - bad_driver(d, - "feature read before VIRTIO_CONFIG_S_DRIVER"); - goto read_through32; - case offsetof(struct virtio_pci_mmio, cfg.msix_config): - bad_driver(d, "read of msix_config"); - case offsetof(struct virtio_pci_mmio, cfg.num_queues): - goto read_through16; - case offsetof(struct virtio_pci_mmio, cfg.device_status): - /* As they did read, any write of FEATURES_OK is now fine. */ - d->wrote_features_ok = false; - goto read_through8; - case offsetof(struct virtio_pci_mmio, cfg.config_generation): - /* - * 4.1.4.3.1: - * - * The device MUST present a changed config_generation after - * the driver has read a device-specific configuration value - * which has changed since any part of the device-specific - * configuration was last read. - * - * This is simple: none of our devices change config, so this - * is always 0. - */ - goto read_through8; - case offsetof(struct virtio_pci_mmio, notify): - /* - * 3.1.1: - * - * The driver MUST NOT notify the device before setting - * DRIVER_OK. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) - bad_driver(d, "notify before VIRTIO_CONFIG_S_DRIVER_OK"); - goto read_through16; - case offsetof(struct virtio_pci_mmio, isr): - if (mask != 0xFF) - bad_driver(d, "non-8-bit read from offset %u (%#x)", - off, getreg(eip)); - isr = d->mmio->isr; - /* - * 4.1.4.5.1: - * - * The device MUST reset ISR status to 0 on driver read. - */ - d->mmio->isr = 0; - return isr; - case offsetof(struct virtio_pci_mmio, padding): - bad_driver(d, "read from padding (%#x)", getreg(eip)); - default: - /* Read from device config space, beware unaligned overflow */ - if (off > d->mmio_size - 4) - bad_driver(d, "read past end (%#x)", getreg(eip)); - - /* - * 3.1.1: - * The driver MUST follow this sequence to initialize a device: - *... - * 3. Set the DRIVER status bit: the guest OS knows how to - * drive the device. - * 4. Read device feature bits, and write the subset of - * feature bits understood by the OS and driver to the - * device. During this step the driver MAY read (but MUST NOT - * write) the device-specific configuration fields to check - * that it can support the device before accepting it. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) - bad_driver(d, - "config read before VIRTIO_CONFIG_S_DRIVER"); - - if (mask == 0xFFFFFFFF) - goto read_through32; - else if (mask == 0xFFFF) - goto read_through16; - else - goto read_through8; - } - - /* - * 4.1.3.1: - * - * The driver MUST access each field using the “natural†access - * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for - * 16-bit fields and 8-bit accesses for 8-bit fields. - */ -read_through32: - if (mask != 0xFFFFFFFF) - bad_driver(d, "non-32-bit read to offset %u (%#x)", - off, getreg(eip)); - memcpy(&val, (char *)d->mmio + off, 4); - return val; - -read_through16: - if (mask != 0xFFFF) - bad_driver(d, "non-16-bit read to offset %u (%#x)", - off, getreg(eip)); - memcpy(&val, (char *)d->mmio + off, 2); - return val; - -read_through8: - if (mask != 0xFF) - bad_driver(d, "non-8-bit read to offset %u (%#x)", - off, getreg(eip)); - memcpy(&val, (char *)d->mmio + off, 1); - return val; -} - -static void emulate_mmio(unsigned long paddr, const u8 *insn) -{ - u32 val, off, mask = 0xFFFFFFFF, insnlen = 0; - struct device *d = find_mmio_region(paddr, &off); - unsigned long args[] = { LHREQ_TRAP, 14 }; - - if (!d) { - warnx("MMIO touching %#08lx (not a device)", paddr); - goto reinject; - } - - /* Prefix makes it a 16 bit op */ - if (insn[0] == 0x66) { - mask = 0xFFFF; - insnlen++; - } - - /* iowrite */ - if (insn[insnlen] == 0x89) { - /* Next byte is r/m byte: bits 3-5 are register. */ - val = getreg_num((insn[insnlen+1] >> 3) & 0x7, mask); - emulate_mmio_write(d, off, val, mask); - insnlen += 2 + insn_displacement_len(insn[insnlen+1]); - } else if (insn[insnlen] == 0x8b) { /* ioread */ - /* Next byte is r/m byte: bits 3-5 are register. */ - val = emulate_mmio_read(d, off, mask); - setreg_num((insn[insnlen+1] >> 3) & 0x7, val, mask); - insnlen += 2 + insn_displacement_len(insn[insnlen+1]); - } else if (insn[0] == 0x88) { /* 8-bit iowrite */ - mask = 0xff; - /* Next byte is r/m byte: bits 3-5 are register. */ - val = getreg_num((insn[1] >> 3) & 0x7, mask); - emulate_mmio_write(d, off, val, mask); - insnlen = 2 + insn_displacement_len(insn[1]); - } else if (insn[0] == 0x8a) { /* 8-bit ioread */ - mask = 0xff; - val = emulate_mmio_read(d, off, mask); - setreg_num((insn[1] >> 3) & 0x7, val, mask); - insnlen = 2 + insn_displacement_len(insn[1]); - } else { - warnx("Unknown MMIO instruction touching %#08lx:" - " %02x %02x %02x %02x at %u", - paddr, insn[0], insn[1], insn[2], insn[3], getreg(eip)); - reinject: - /* Inject trap into Guest. */ - if (write(lguest_fd, args, sizeof(args)) < 0) - err(1, "Reinjecting trap 14 for fault at %#x", - getreg(eip)); - return; - } - - /* Finally, we've "done" the instruction, so move past it. */ - setreg(eip, getreg(eip) + insnlen); -} - -/*L:190 - * Device Setup - * - * All devices need a descriptor so the Guest knows it exists, and a "struct - * device" so the Launcher can keep track of it. We have common helper - * routines to allocate and manage them. - */ -static void add_pci_virtqueue(struct device *dev, - void (*service)(struct virtqueue *), - const char *name) -{ - struct virtqueue **i, *vq = malloc(sizeof(*vq)); - - /* Initialize the virtqueue */ - vq->next = NULL; - vq->last_avail_idx = 0; - vq->dev = dev; - vq->name = name; - - /* - * This is the routine the service thread will run, and its Process ID - * once it's running. - */ - vq->service = service; - vq->thread = (pid_t)-1; - - /* Initialize the configuration. */ - reset_vq_pci_config(vq); - vq->pci_config.queue_notify_off = 0; - - /* Add one to the number of queues */ - vq->dev->mmio->cfg.num_queues++; - - /* - * Add to tail of list, so dev->vq is first vq, dev->vq->next is - * second. - */ - for (i = &dev->vq; *i; i = &(*i)->next); - *i = vq; -} - -/* The Guest accesses the feature bits via the PCI common config MMIO region */ -static void add_pci_feature(struct device *dev, unsigned bit) -{ - dev->features |= (1ULL << bit); -} - -/* For devices with no config. */ -static void no_device_config(struct device *dev) -{ - dev->mmio_addr = get_mmio_region(dev->mmio_size); - - dev->config.bar[0] = dev->mmio_addr; - /* Bottom 4 bits must be zero */ - assert(~(dev->config.bar[0] & 0xF)); -} - -/* This puts the device config into BAR0 */ -static void set_device_config(struct device *dev, const void *conf, size_t len) -{ - /* Set up BAR 0 */ - dev->mmio_size += len; - dev->mmio = realloc(dev->mmio, dev->mmio_size); - memcpy(dev->mmio + 1, conf, len); - - /* - * 4.1.4.6: - * - * The device MUST present at least one VIRTIO_PCI_CAP_DEVICE_CFG - * capability for any device type which has a device-specific - * configuration. - */ - /* Hook up device cfg */ - dev->config.cfg_access.cap.cap_next - = offsetof(struct pci_config, device); - - /* - * 4.1.4.6.1: - * - * The offset for the device-specific configuration MUST be 4-byte - * aligned. - */ - assert(dev->config.cfg_access.cap.cap_next % 4 == 0); - - /* Fix up device cfg field length. */ - dev->config.device.length = len; - - /* The rest is the same as the no-config case */ - no_device_config(dev); -} - -static void init_cap(struct virtio_pci_cap *cap, size_t caplen, int type, - size_t bar_offset, size_t bar_bytes, u8 next) -{ - cap->cap_vndr = PCI_CAP_ID_VNDR; - cap->cap_next = next; - cap->cap_len = caplen; - cap->cfg_type = type; - cap->bar = 0; - memset(cap->padding, 0, sizeof(cap->padding)); - cap->offset = bar_offset; - cap->length = bar_bytes; -} - -/* - * This sets up the pci_config structure, as defined in the virtio 1.0 - * standard (and PCI standard). - */ -static void init_pci_config(struct pci_config *pci, u16 type, - u8 class, u8 subclass) -{ - size_t bar_offset, bar_len; - - /* - * 4.1.4.4.1: - * - * The device MUST either present notify_off_multiplier as an even - * power of 2, or present notify_off_multiplier as 0. - * - * 2.1.2: - * - * The device MUST initialize device status to 0 upon reset. - */ - memset(pci, 0, sizeof(*pci)); - - /* 4.1.2.1: Devices MUST have the PCI Vendor ID 0x1AF4 */ - pci->vendor_id = 0x1AF4; - /* 4.1.2.1: ... PCI Device ID calculated by adding 0x1040 ... */ - pci->device_id = 0x1040 + type; - - /* - * PCI have specific codes for different types of devices. - * Linux doesn't care, but it's a good clue for people looking - * at the device. - */ - pci->class = class; - pci->subclass = subclass; - - /* - * 4.1.2.1: - * - * Non-transitional devices SHOULD have a PCI Revision ID of 1 or - * higher - */ - pci->revid = 1; - - /* - * 4.1.2.1: - * - * Non-transitional devices SHOULD have a PCI Subsystem Device ID of - * 0x40 or higher. - */ - pci->subsystem_device_id = 0x40; - - /* We use our dummy interrupt controller, and irq_line is the irq */ - pci->irq_line = devices.next_irq++; - pci->irq_pin = 0; - - /* Support for extended capabilities. */ - pci->status = (1 << 4); - - /* Link them in. */ - /* - * 4.1.4.3.1: - * - * The device MUST present at least one common configuration - * capability. - */ - pci->capabilities = offsetof(struct pci_config, common); - - /* 4.1.4.3.1 ... offset MUST be 4-byte aligned. */ - assert(pci->capabilities % 4 == 0); - - bar_offset = offsetof(struct virtio_pci_mmio, cfg); - bar_len = sizeof(((struct virtio_pci_mmio *)0)->cfg); - init_cap(&pci->common, sizeof(pci->common), VIRTIO_PCI_CAP_COMMON_CFG, - bar_offset, bar_len, - offsetof(struct pci_config, notify)); - - /* - * 4.1.4.4.1: - * - * The device MUST present at least one notification capability. - */ - bar_offset += bar_len; - bar_len = sizeof(((struct virtio_pci_mmio *)0)->notify); - - /* - * 4.1.4.4.1: - * - * The cap.offset MUST be 2-byte aligned. - */ - assert(pci->common.cap_next % 2 == 0); - - /* FIXME: Use a non-zero notify_off, for per-queue notification? */ - /* - * 4.1.4.4.1: - * - * The value cap.length presented by the device MUST be at least 2 and - * MUST be large enough to support queue notification offsets for all - * supported queues in all possible configurations. - */ - assert(bar_len >= 2); - - init_cap(&pci->notify.cap, sizeof(pci->notify), - VIRTIO_PCI_CAP_NOTIFY_CFG, - bar_offset, bar_len, - offsetof(struct pci_config, isr)); - - bar_offset += bar_len; - bar_len = sizeof(((struct virtio_pci_mmio *)0)->isr); - /* - * 4.1.4.5.1: - * - * The device MUST present at least one VIRTIO_PCI_CAP_ISR_CFG - * capability. - */ - init_cap(&pci->isr, sizeof(pci->isr), - VIRTIO_PCI_CAP_ISR_CFG, - bar_offset, bar_len, - offsetof(struct pci_config, cfg_access)); - - /* - * 4.1.4.7.1: - * - * The device MUST present at least one VIRTIO_PCI_CAP_PCI_CFG - * capability. - */ - /* This doesn't have any presence in the BAR */ - init_cap(&pci->cfg_access.cap, sizeof(pci->cfg_access), - VIRTIO_PCI_CAP_PCI_CFG, - 0, 0, 0); - - bar_offset += bar_len + sizeof(((struct virtio_pci_mmio *)0)->padding); - assert(bar_offset == sizeof(struct virtio_pci_mmio)); - - /* - * This gets sewn in and length set in set_device_config(). - * Some devices don't have a device configuration interface, so - * we never expose this if we don't call set_device_config(). - */ - init_cap(&pci->device, sizeof(pci->device), VIRTIO_PCI_CAP_DEVICE_CFG, - bar_offset, 0, 0); -} - -/* - * This routine does all the creation and setup of a new device, but we don't - * actually place the MMIO region until we know the size (if any) of the - * device-specific config. And we don't actually start the service threads - * until later. - * - * See what I mean about userspace being boring? - */ -static struct device *new_pci_device(const char *name, u16 type, - u8 class, u8 subclass) -{ - struct device *dev = malloc(sizeof(*dev)); - - /* Now we populate the fields one at a time. */ - dev->name = name; - dev->vq = NULL; - dev->running = false; - dev->wrote_features_ok = false; - dev->mmio_size = sizeof(struct virtio_pci_mmio); - dev->mmio = calloc(1, dev->mmio_size); - dev->features = (u64)1 << VIRTIO_F_VERSION_1; - dev->features_accepted = 0; - - if (devices.device_num + 1 >= MAX_PCI_DEVICES) - errx(1, "Can only handle 31 PCI devices"); - - init_pci_config(&dev->config, type, class, subclass); - assert(!devices.pci[devices.device_num+1]); - devices.pci[++devices.device_num] = dev; - - return dev; -} - -/* - * Our first setup routine is the console. It's a fairly simple device, but - * UNIX tty handling makes it uglier than it could be. - */ -static void setup_console(void) -{ - struct device *dev; - struct virtio_console_config conf; - - /* If we can save the initial standard input settings... */ - if (tcgetattr(STDIN_FILENO, &orig_term) == 0) { - struct termios term = orig_term; - /* - * Then we turn off echo, line buffering and ^C etc: We want a - * raw input stream to the Guest. - */ - term.c_lflag &= ~(ISIG|ICANON|ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - - dev = new_pci_device("console", VIRTIO_ID_CONSOLE, 0x07, 0x00); - - /* We store the console state in dev->priv, and initialize it. */ - dev->priv = malloc(sizeof(struct console_abort)); - ((struct console_abort *)dev->priv)->count = 0; - - /* - * The console needs two virtqueues: the input then the output. When - * they put something the input queue, we make sure we're listening to - * stdin. When they put something in the output queue, we write it to - * stdout. - */ - add_pci_virtqueue(dev, console_input, "input"); - add_pci_virtqueue(dev, console_output, "output"); - - /* We need a configuration area for the emerg_wr early writes. */ - add_pci_feature(dev, VIRTIO_CONSOLE_F_EMERG_WRITE); - set_device_config(dev, &conf, sizeof(conf)); - - verbose("device %u: console\n", devices.device_num); -} -/*:*/ - -/*M:010 - * Inter-guest networking is an interesting area. Simplest is to have a - * --sharenet= option which opens or creates a named pipe. This can be - * used to send packets to another guest in a 1:1 manner. - * - * More sophisticated is to use one of the tools developed for project like UML - * to do networking. - * - * Faster is to do virtio bonding in kernel. Doing this 1:1 would be - * completely generic ("here's my vring, attach to your vring") and would work - * for any traffic. Of course, namespace and permissions issues need to be - * dealt with. A more sophisticated "multi-channel" virtio_net.c could hide - * multiple inter-guest channels behind one interface, although it would - * require some manner of hotplugging new virtio channels. - * - * Finally, we could use a virtio network switch in the kernel, ie. vhost. -:*/ - -static u32 str2ip(const char *ipaddr) -{ - unsigned int b[4]; - - if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4) - errx(1, "Failed to parse IP address '%s'", ipaddr); - return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; -} - -static void str2mac(const char *macaddr, unsigned char mac[6]) -{ - unsigned int m[6]; - if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x", - &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6) - errx(1, "Failed to parse mac address '%s'", macaddr); - mac[0] = m[0]; - mac[1] = m[1]; - mac[2] = m[2]; - mac[3] = m[3]; - mac[4] = m[4]; - mac[5] = m[5]; -} - -/* - * This code is "adapted" from libbridge: it attaches the Host end of the - * network device to the bridge device specified by the command line. - * - * This is yet another James Morris contribution (I'm an IP-level guy, so I - * dislike bridging), and I just try not to break it. - */ -static void add_to_bridge(int fd, const char *if_name, const char *br_name) -{ - int ifidx; - struct ifreq ifr; - - if (!*br_name) - errx(1, "must specify bridge name"); - - ifidx = if_nametoindex(if_name); - if (!ifidx) - errx(1, "interface %s does not exist!", if_name); - - strncpy(ifr.ifr_name, br_name, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; - ifr.ifr_ifindex = ifidx; - if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) - err(1, "can't add %s to bridge %s", if_name, br_name); -} - -/* - * This sets up the Host end of the network device with an IP address, brings - * it up so packets will flow, the copies the MAC address into the hwaddr - * pointer. - */ -static void configure_device(int fd, const char *tapif, u32 ipaddr) -{ - struct ifreq ifr; - struct sockaddr_in sin; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, tapif); - - /* Don't read these incantations. Just cut & paste them like I did! */ - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(ipaddr); - memcpy(&ifr.ifr_addr, &sin, sizeof(sin)); - if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) - err(1, "Setting %s interface address", tapif); - ifr.ifr_flags = IFF_UP; - if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) - err(1, "Bringing interface %s up", tapif); -} - -static int get_tun_device(char tapif[IFNAMSIZ]) -{ - struct ifreq ifr; - int vnet_hdr_sz; - int netfd; - - /* Start with this zeroed. Messy but sure. */ - memset(&ifr, 0, sizeof(ifr)); - - /* - * We open the /dev/net/tun device and tell it we want a tap device. A - * tap device is like a tun device, only somehow different. To tell - * the truth, I completely blundered my way through this code, but it - * works now! - */ - netfd = open_or_die("/dev/net/tun", O_RDWR); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; - strcpy(ifr.ifr_name, "tap%d"); - if (ioctl(netfd, TUNSETIFF, &ifr) != 0) - err(1, "configuring /dev/net/tun"); - - if (ioctl(netfd, TUNSETOFFLOAD, - TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0) - err(1, "Could not set features for tun device"); - - /* - * We don't need checksums calculated for packets coming in this - * device: trust us! - */ - ioctl(netfd, TUNSETNOCSUM, 1); - - /* - * In virtio before 1.0 (aka legacy virtio), we added a 16-bit - * field at the end of the network header iff - * VIRTIO_NET_F_MRG_RXBUF was negotiated. For virtio 1.0, - * that became the norm, but we need to tell the tun device - * about our expanded header (which is called - * virtio_net_hdr_mrg_rxbuf in the legacy system). - */ - vnet_hdr_sz = sizeof(struct virtio_net_hdr_v1); - if (ioctl(netfd, TUNSETVNETHDRSZ, &vnet_hdr_sz) != 0) - err(1, "Setting tun header size to %u", vnet_hdr_sz); - - memcpy(tapif, ifr.ifr_name, IFNAMSIZ); - return netfd; -} - -/*L:195 - * Our network is a Host<->Guest network. This can either use bridging or - * routing, but the principle is the same: it uses the "tun" device to inject - * packets into the Host as if they came in from a normal network card. We - * just shunt packets between the Guest and the tun device. - */ -static void setup_tun_net(char *arg) -{ - struct device *dev; - struct net_info *net_info = malloc(sizeof(*net_info)); - int ipfd; - u32 ip = INADDR_ANY; - bool bridging = false; - char tapif[IFNAMSIZ], *p; - struct virtio_net_config conf; - - net_info->tunfd = get_tun_device(tapif); - - /* First we create a new network device. */ - dev = new_pci_device("net", VIRTIO_ID_NET, 0x02, 0x00); - dev->priv = net_info; - - /* Network devices need a recv and a send queue, just like console. */ - add_pci_virtqueue(dev, net_input, "rx"); - add_pci_virtqueue(dev, net_output, "tx"); - - /* - * We need a socket to perform the magic network ioctls to bring up the - * tap interface, connect to the bridge etc. Any socket will do! - */ - ipfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - if (ipfd < 0) - err(1, "opening IP socket"); - - /* If the command line was --tunnet=bridge: do bridging. */ - if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) { - arg += strlen(BRIDGE_PFX); - bridging = true; - } - - /* A mac address may follow the bridge name or IP address */ - p = strchr(arg, ':'); - if (p) { - str2mac(p+1, conf.mac); - add_pci_feature(dev, VIRTIO_NET_F_MAC); - *p = '\0'; - } - - /* arg is now either an IP address or a bridge name */ - if (bridging) - add_to_bridge(ipfd, tapif, arg); - else - ip = str2ip(arg); - - /* Set up the tun device. */ - configure_device(ipfd, tapif, ip); - - /* Expect Guest to handle everything except UFO */ - add_pci_feature(dev, VIRTIO_NET_F_CSUM); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_CSUM); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO4); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO6); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_ECN); - add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO4); - add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO6); - add_pci_feature(dev, VIRTIO_NET_F_HOST_ECN); - /* We handle indirect ring entries */ - add_pci_feature(dev, VIRTIO_RING_F_INDIRECT_DESC); - set_device_config(dev, &conf, sizeof(conf)); - - /* We don't need the socket any more; setup is done. */ - close(ipfd); - - if (bridging) - verbose("device %u: tun %s attached to bridge: %s\n", - devices.device_num, tapif, arg); - else - verbose("device %u: tun %s: %s\n", - devices.device_num, tapif, arg); -} -/*:*/ - -/* This hangs off device->priv. */ -struct vblk_info { - /* The size of the file. */ - off64_t len; - - /* The file descriptor for the file. */ - int fd; - -}; - -/*L:210 - * The Disk - * - * The disk only has one virtqueue, so it only has one thread. It is really - * simple: the Guest asks for a block number and we read or write that position - * in the file. - * - * Before we serviced each virtqueue in a separate thread, that was unacceptably - * slow: the Guest waits until the read is finished before running anything - * else, even if it could have been doing useful work. - * - * We could have used async I/O, except it's reputed to suck so hard that - * characters actually go missing from your code when you try to use it. - */ -static void blk_request(struct virtqueue *vq) -{ - struct vblk_info *vblk = vq->dev->priv; - unsigned int head, out_num, in_num, wlen; - int ret, i; - u8 *in; - struct virtio_blk_outhdr out; - struct iovec iov[vq->vring.num]; - off64_t off; - - /* - * Get the next request, where we normally wait. It triggers the - * interrupt to acknowledge previously serviced requests (if any). - */ - head = wait_for_vq_desc(vq, iov, &out_num, &in_num); - - /* Copy the output header from the front of the iov (adjusts iov) */ - iov_consume(vq->dev, iov, out_num, &out, sizeof(out)); - - /* Find and trim end of iov input array, for our status byte. */ - in = NULL; - for (i = out_num + in_num - 1; i >= out_num; i--) { - if (iov[i].iov_len > 0) { - in = iov[i].iov_base + iov[i].iov_len - 1; - iov[i].iov_len--; - break; - } - } - if (!in) - bad_driver_vq(vq, "Bad virtblk cmd with no room for status"); - - /* - * For historical reasons, block operations are expressed in 512 byte - * "sectors". - */ - off = out.sector * 512; - - if (out.type & VIRTIO_BLK_T_OUT) { - /* - * Write - * - * Move to the right location in the block file. This can fail - * if they try to write past end. - */ - if (lseek64(vblk->fd, off, SEEK_SET) != off) - err(1, "Bad seek to sector %llu", out.sector); - - ret = writev(vblk->fd, iov, out_num); - verbose("WRITE to sector %llu: %i\n", out.sector, ret); - - /* - * Grr... Now we know how long the descriptor they sent was, we - * make sure they didn't try to write over the end of the block - * file (possibly extending it). - */ - if (ret > 0 && off + ret > vblk->len) { - /* Trim it back to the correct length */ - ftruncate64(vblk->fd, vblk->len); - /* Die, bad Guest, die. */ - bad_driver_vq(vq, "Write past end %llu+%u", off, ret); - } - - wlen = sizeof(*in); - *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); - } else if (out.type & VIRTIO_BLK_T_FLUSH) { - /* Flush */ - ret = fdatasync(vblk->fd); - verbose("FLUSH fdatasync: %i\n", ret); - wlen = sizeof(*in); - *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); - } else { - /* - * Read - * - * Move to the right location in the block file. This can fail - * if they try to read past end. - */ - if (lseek64(vblk->fd, off, SEEK_SET) != off) - err(1, "Bad seek to sector %llu", out.sector); - - ret = readv(vblk->fd, iov + out_num, in_num); - if (ret >= 0) { - wlen = sizeof(*in) + ret; - *in = VIRTIO_BLK_S_OK; - } else { - wlen = sizeof(*in); - *in = VIRTIO_BLK_S_IOERR; - } - } - - /* Finished that request. */ - add_used(vq, head, wlen); -} - -/*L:198 This actually sets up a virtual block device. */ -static void setup_block_file(const char *filename) -{ - struct device *dev; - struct vblk_info *vblk; - struct virtio_blk_config conf; - - /* Create the device. */ - dev = new_pci_device("block", VIRTIO_ID_BLOCK, 0x01, 0x80); - - /* The device has one virtqueue, where the Guest places requests. */ - add_pci_virtqueue(dev, blk_request, "request"); - - /* Allocate the room for our own bookkeeping */ - vblk = dev->priv = malloc(sizeof(*vblk)); - - /* First we open the file and store the length. */ - vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE); - vblk->len = lseek64(vblk->fd, 0, SEEK_END); - - /* Tell Guest how many sectors this device has. */ - conf.capacity = cpu_to_le64(vblk->len / 512); - - /* - * Tell Guest not to put in too many descriptors at once: two are used - * for the in and out elements. - */ - add_pci_feature(dev, VIRTIO_BLK_F_SEG_MAX); - conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2); - - set_device_config(dev, &conf, sizeof(struct virtio_blk_config)); - - verbose("device %u: virtblock %llu sectors\n", - devices.device_num, le64_to_cpu(conf.capacity)); -} - -/*L:211 - * Our random number generator device reads from /dev/urandom into the Guest's - * input buffers. The usual case is that the Guest doesn't want random numbers - * and so has no buffers although /dev/urandom is still readable, whereas - * console is the reverse. - * - * The same logic applies, however. - */ -struct rng_info { - int rfd; -}; - -static void rng_input(struct virtqueue *vq) -{ - int len; - unsigned int head, in_num, out_num, totlen = 0; - struct rng_info *rng_info = vq->dev->priv; - struct iovec iov[vq->vring.num]; - - /* First we need a buffer from the Guests's virtqueue. */ - head = wait_for_vq_desc(vq, iov, &out_num, &in_num); - if (out_num) - bad_driver_vq(vq, "Output buffers in rng?"); - - /* - * Just like the console write, we loop to cover the whole iovec. - * In this case, short reads actually happen quite a bit. - */ - while (!iov_empty(iov, in_num)) { - len = readv(rng_info->rfd, iov, in_num); - if (len <= 0) - err(1, "Read from /dev/urandom gave %i", len); - iov_consume(vq->dev, iov, in_num, NULL, len); - totlen += len; - } - - /* Tell the Guest about the new input. */ - add_used(vq, head, totlen); -} - -/*L:199 - * This creates a "hardware" random number device for the Guest. - */ -static void setup_rng(void) -{ - struct device *dev; - struct rng_info *rng_info = malloc(sizeof(*rng_info)); - - /* Our device's private info simply contains the /dev/urandom fd. */ - rng_info->rfd = open_or_die("/dev/urandom", O_RDONLY); - - /* Create the new device. */ - dev = new_pci_device("rng", VIRTIO_ID_RNG, 0xff, 0); - dev->priv = rng_info; - - /* The device has one virtqueue, where the Guest places inbufs. */ - add_pci_virtqueue(dev, rng_input, "input"); - - /* We don't have any configuration space */ - no_device_config(dev); - - verbose("device %u: rng\n", devices.device_num); -} -/* That's the end of device setup. */ - -/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */ -static void __attribute__((noreturn)) restart_guest(void) -{ - unsigned int i; - - /* - * Since we don't track all open fds, we simply close everything beyond - * stderr. - */ - for (i = 3; i < FD_SETSIZE; i++) - close(i); - - /* Reset all the devices (kills all threads). */ - cleanup_devices(); - - execv(main_args[0], main_args); - err(1, "Could not exec %s", main_args[0]); -} - -/*L:220 - * Finally we reach the core of the Launcher which runs the Guest, serves - * its input and output, and finally, lays it to rest. - */ -static void __attribute__((noreturn)) run_guest(void) -{ - for (;;) { - struct lguest_pending notify; - int readval; - - /* We read from the /dev/lguest device to run the Guest. */ - readval = pread(lguest_fd, ¬ify, sizeof(notify), cpu_id); - if (readval == sizeof(notify)) { - if (notify.trap == 13) { - verbose("Emulating instruction at %#x\n", - getreg(eip)); - emulate_insn(notify.insn); - } else if (notify.trap == 14) { - verbose("Emulating MMIO at %#x\n", - getreg(eip)); - emulate_mmio(notify.addr, notify.insn); - } else - errx(1, "Unknown trap %i addr %#08x\n", - notify.trap, notify.addr); - /* ENOENT means the Guest died. Reading tells us why. */ - } else if (errno == ENOENT) { - char reason[1024] = { 0 }; - pread(lguest_fd, reason, sizeof(reason)-1, cpu_id); - errx(1, "%s", reason); - /* ERESTART means that we need to reboot the guest */ - } else if (errno == ERESTART) { - restart_guest(); - /* Anything else means a bug or incompatible change. */ - } else - err(1, "Running guest failed"); - } -} -/*L:240 - * This is the end of the Launcher. The good news: we are over halfway - * through! The bad news: the most fiendish part of the code still lies ahead - * of us. - * - * Are you ready? Take a deep breath and join me in the core of the Host, in - * "make Host". -:*/ - -static struct option opts[] = { - { "verbose", 0, NULL, 'v' }, - { "tunnet", 1, NULL, 't' }, - { "block", 1, NULL, 'b' }, - { "rng", 0, NULL, 'r' }, - { "initrd", 1, NULL, 'i' }, - { "username", 1, NULL, 'u' }, - { "chroot", 1, NULL, 'c' }, - { NULL }, -}; -static void usage(void) -{ - errx(1, "Usage: lguest [--verbose] " - "[--tunnet=(:|bridge::)\n" - "|--block=|--initrd=]...\n" - " vmlinux [args...]"); -} - -/*L:105 The main routine is where the real work begins: */ -int main(int argc, char *argv[]) -{ - /* Memory, code startpoint and size of the (optional) initrd. */ - unsigned long mem = 0, start, initrd_size = 0; - /* Two temporaries. */ - int i, c; - /* The boot information for the Guest. */ - struct boot_params *boot; - /* If they specify an initrd file to load. */ - const char *initrd_name = NULL; - - /* Password structure for initgroups/setres[gu]id */ - struct passwd *user_details = NULL; - - /* Directory to chroot to */ - char *chroot_path = NULL; - - /* Save the args: we "reboot" by execing ourselves again. */ - main_args = argv; - - /* - * First we initialize the device list. We remember next interrupt - * number to use for devices (1: remember that 0 is used by the timer). - */ - devices.next_irq = 1; - - /* We're CPU 0. In fact, that's the only CPU possible right now. */ - cpu_id = 0; - - /* - * We need to know how much memory so we can set up the device - * descriptor and memory pages for the devices as we parse the command - * line. So we quickly look through the arguments to find the amount - * of memory now. - */ - for (i = 1; i < argc; i++) { - if (argv[i][0] != '-') { - mem = atoi(argv[i]) * 1024 * 1024; - /* - * We start by mapping anonymous pages over all of - * guest-physical memory range. This fills it with 0, - * and ensures that the Guest won't be killed when it - * tries to access it. - */ - guest_base = map_zeroed_pages(mem / getpagesize() - + DEVICE_PAGES); - guest_limit = mem; - guest_max = guest_mmio = mem + DEVICE_PAGES*getpagesize(); - break; - } - } - - /* If we exit via err(), this kills all the threads, restores tty. */ - atexit(cleanup_devices); - - /* We always have a console device, and it's always device 1. */ - setup_console(); - - /* The options are fairly straight-forward */ - while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) { - switch (c) { - case 'v': - verbose = true; - break; - case 't': - setup_tun_net(optarg); - break; - case 'b': - setup_block_file(optarg); - break; - case 'r': - setup_rng(); - break; - case 'i': - initrd_name = optarg; - break; - case 'u': - user_details = getpwnam(optarg); - if (!user_details) - err(1, "getpwnam failed, incorrect username?"); - break; - case 'c': - chroot_path = optarg; - break; - default: - warnx("Unknown argument %s", argv[optind]); - usage(); - } - } - /* - * After the other arguments we expect memory and kernel image name, - * followed by command line arguments for the kernel. - */ - if (optind + 2 > argc) - usage(); - - verbose("Guest base is at %p\n", guest_base); - - /* Initialize the (fake) PCI host bridge device. */ - init_pci_host_bridge(); - - /* Now we load the kernel */ - start = load_kernel(open_or_die(argv[optind+1], O_RDONLY)); - - /* Boot information is stashed at physical address 0 */ - boot = from_guest_phys(0); - - /* Map the initrd image if requested (at top of physical memory) */ - if (initrd_name) { - initrd_size = load_initrd(initrd_name, mem); - /* - * These are the location in the Linux boot header where the - * start and size of the initrd are expected to be found. - */ - boot->hdr.ramdisk_image = mem - initrd_size; - boot->hdr.ramdisk_size = initrd_size; - /* The bootloader type 0xFF means "unknown"; that's OK. */ - boot->hdr.type_of_loader = 0xFF; - } - - /* - * The Linux boot header contains an "E820" memory map: ours is a - * simple, single region. - */ - boot->e820_entries = 1; - boot->e820_table[0] = ((struct e820_entry) { 0, mem, E820_TYPE_RAM }); - /* - * The boot header contains a command line pointer: we put the command - * line after the boot header. - */ - boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1); - /* We use a simple helper to copy the arguments separated by spaces. */ - concat((char *)(boot + 1), argv+optind+2); - - /* Set kernel alignment to 16M (CONFIG_PHYSICAL_ALIGN) */ - boot->hdr.kernel_alignment = 0x1000000; - - /* Boot protocol version: 2.07 supports the fields for lguest. */ - boot->hdr.version = 0x207; - - /* X86_SUBARCH_LGUEST tells the Guest it's an lguest. */ - boot->hdr.hardware_subarch = X86_SUBARCH_LGUEST; - - /* Tell the entry path not to try to reload segment registers. */ - boot->hdr.loadflags |= KEEP_SEGMENTS; - - /* We don't support tboot: */ - boot->tboot_addr = 0; - - /* Ensure this is 0 to prevent APM from loading: */ - boot->apm_bios_info.version = 0; - - /* We tell the kernel to initialize the Guest. */ - tell_kernel(start); - - /* Ensure that we terminate if a device-servicing child dies. */ - signal(SIGCHLD, kill_launcher); - - /* If requested, chroot to a directory */ - if (chroot_path) { - if (chroot(chroot_path) != 0) - err(1, "chroot(\"%s\") failed", chroot_path); - - if (chdir("/") != 0) - err(1, "chdir(\"/\") failed"); - - verbose("chroot done\n"); - } - - /* If requested, drop privileges */ - if (user_details) { - uid_t u; - gid_t g; - - u = user_details->pw_uid; - g = user_details->pw_gid; - - if (initgroups(user_details->pw_name, g) != 0) - err(1, "initgroups failed"); - - if (setresgid(g, g, g) != 0) - err(1, "setresgid failed"); - - if (setresuid(u, u, u) != 0) - err(1, "setresuid failed"); - - verbose("Dropping privileges completed\n"); - } - - /* Finally, run the Guest. This doesn't return. */ - run_guest(); -} -/*:*/ - -/*M:999 - * Mastery is done: you now know everything I do. - * - * But surely you have seen code, features and bugs in your wanderings which - * you now yearn to attack? That is the real game, and I look forward to you - * patching and forking lguest into the Your-Name-Here-visor. - * - * Farewell, and good coding! - * Rusty Russell. - */ diff --git a/tools/lguest/lguest.txt b/tools/lguest/lguest.txt deleted file mode 100644 index 06e1f46495112af6b3ee928f74f7621c039f8917..0000000000000000000000000000000000000000 --- a/tools/lguest/lguest.txt +++ /dev/null @@ -1,125 +0,0 @@ - __ - (___()'`; Rusty's Remarkably Unreliable Guide to Lguest - /, /` - or, A Young Coder's Illustrated Hypervisor - \\"--\\ http://lguest.ozlabs.org - -Lguest is designed to be a minimal 32-bit x86 hypervisor for the Linux kernel, -for Linux developers and users to experiment with virtualization with the -minimum of complexity. Nonetheless, it should have sufficient features to -make it useful for specific tasks, and, of course, you are encouraged to fork -and enhance it (see drivers/lguest/README). - -Features: - -- Kernel module which runs in a normal kernel. -- Simple I/O model for communication. -- Simple program to create new guests. -- Logo contains cute puppies: http://lguest.ozlabs.org - -Developer features: - -- Fun to hack on. -- No ABI: being tied to a specific kernel anyway, you can change anything. -- Many opportunities for improvement or feature implementation. - -Running Lguest: - -- The easiest way to run lguest is to use same kernel as guest and host. - You can configure them differently, but usually it's easiest not to. - - You will need to configure your kernel with the following options: - - "Processor type and features": - "Paravirtualized guest support" = Y - "Lguest guest support" = Y - "High Memory Support" = off/4GB - "Alignment value to which kernel should be aligned" = 0x100000 - (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and - CONFIG_PHYSICAL_ALIGN=0x100000) - - "Device Drivers": - "Block devices" - "Virtio block driver" = M/Y - "Network device support" - "Universal TUN/TAP device driver support" = M/Y - "Virtio network driver" = M/Y - (CONFIG_VIRTIO_BLK=m, CONFIG_VIRTIO_NET=m and CONFIG_TUN=m) - - "Virtualization" - "Linux hypervisor example code" = M/Y - (CONFIG_LGUEST=m) - -- A tool called "lguest" is available in this directory: type "make" - to build it. If you didn't build your kernel in-tree, use "make - O=". - -- Create or find a root disk image. There are several useful ones - around, such as the xm-test tiny root image at - http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img - - For more serious work, I usually use a distribution ISO image and - install it under qemu, then make multiple copies: - - dd if=/dev/zero of=rootfile bs=1M count=2048 - qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d - - Make sure that you install a getty on /dev/hvc0 if you want to log in on the - console! - -- "modprobe lg" if you built it as a module. - -- Run an lguest as root: - - tools/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 \ - --block=rootfile root=/dev/vda - - Explanation: - 64: the amount of memory to use, in MB. - - vmlinux: the kernel image found in the top of your build directory. You - can also use a standard bzImage. - - --tunnet=192.168.19.1: configures a "tap" device for networking with this - IP address. - - --block=rootfile: a file or block device which becomes /dev/vda - inside the guest. - - root=/dev/vda: this (and anything else on the command line) are - kernel boot parameters. - -- Configuring networking. I usually have the host masquerade, using - "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" and "echo 1 > - /proc/sys/net/ipv4/ip_forward". In this example, I would configure - eth0 inside the guest at 192.168.19.2. - - Another method is to bridge the tap device to an external interface - using --tunnet=bridge:, and perhaps run dhcp on the guest - to obtain an IP address. The bridge needs to be configured first: - this option simply adds the tap interface to it. - - A simple example on my system: - - ifconfig eth0 0.0.0.0 - brctl addbr lg0 - ifconfig lg0 up - brctl addif lg0 eth0 - dhclient lg0 - - Then use --tunnet=bridge:lg0 when launching the guest. - - See: - - http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge - - for general information on how to get bridging to work. - -- Random number generation. Using the --rng option will provide a - /dev/hwrng in the guest that will read from the host's /dev/random. - Use this option in conjunction with rng-tools (see ../hw_random.txt) - to provide entropy to the guest kernel's /dev/random. - -There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest - -Good luck! -Rusty Russell rusty@rustcorp.com.au. diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index eb6e0b36bfc194771c15d66c5fe257d73cdf92de..1e83e3c0744845278aa6ea03b1c440400a1188fb 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -8,22 +8,28 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) #$(info Determined 'srctree' to be $(srctree)) endif -CC = $(CROSS_COMPILE)gcc -AR = $(CROSS_COMPILE)ar -LD = $(CROSS_COMPILE)ld +CC ?= $(CROSS_COMPILE)gcc +AR ?= $(CROSS_COMPILE)ar +LD ?= $(CROSS_COMPILE)ld MAKEFLAGS += --no-print-directory LIBFILE = $(OUTPUT)libapi.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC +CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -fPIC -ifeq ($(CC), clang) +ifeq ($(DEBUG),0) +ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 else CFLAGS += -O6 endif +endif + +ifeq ($(DEBUG),0) + CFLAGS += -D_FORTIFY_SOURCE +endif # Treat warnings as errors unless directed not to ifneq ($(WERROR),0) diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 1f5300e56b44dc7bca0b269261d5f7987eb564b6..d2441db34740df88467043da598c838c13b0e7c6 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -154,12 +154,12 @@ all: fixdep $(VERSION_FILES) all_cmd all_cmd: $(CMD_TARGETS) $(BPF_IN): force elfdep bpfdep - @(test -f ../../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ + @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ - echo "Warning: tools/include/uapi/linux/bpf.h differs from kernel" >&2 )) || true - @(test -f ../../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \ + echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true + @(test -f ../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \ (diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \ - echo "Warning: tools/include/uapi/linux/bpf_common.h differs from kernel" >&2 )) || true + echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf_common.h' differs from latest version at 'include/uapi/linux/bpf_common.h'" >&2 )) || true $(Q)$(MAKE) $(build)=libbpf $(OUTPUT)libbpf.so: $(BPF_IN) @@ -189,6 +189,10 @@ install_lib: all_cmd $(call QUIET_INSTALL, $(LIB_FILE)) \ $(call do_install,$(LIB_FILE),$(libdir_SQ)) +install_headers: + $(call QUIET_INSTALL, headers) \ + $(call do_install,bpf.h,$(prefix)/include/bpf,644) + install: install_lib ### Cleaning rules diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 412a7c82995ae1cb595f6eb1637703ae8a1a359b..1d6907d379c99dd545cdc7f69b3cc78fd4215f27 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -39,6 +39,8 @@ # define __NR_bpf 280 # elif defined(__sparc__) # define __NR_bpf 349 +# elif defined(__s390__) +# define __NR_bpf 351 # else # error __NR_bpf not defined. libbpf does not support your arch. # endif @@ -55,8 +57,9 @@ static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, return syscall(__NR_bpf, cmd, attr, size); } -int bpf_create_map(enum bpf_map_type map_type, int key_size, - int value_size, int max_entries, __u32 map_flags) +int bpf_create_map_node(enum bpf_map_type map_type, int key_size, + int value_size, int max_entries, __u32 map_flags, + int node) { union bpf_attr attr; @@ -67,12 +70,24 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, attr.value_size = value_size; attr.max_entries = max_entries; attr.map_flags = map_flags; + if (node >= 0) { + attr.map_flags |= BPF_F_NUMA_NODE; + attr.numa_node = node; + } return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); } -int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, - int inner_map_fd, int max_entries, __u32 map_flags) +int bpf_create_map(enum bpf_map_type map_type, int key_size, + int value_size, int max_entries, __u32 map_flags) +{ + return bpf_create_map_node(map_type, key_size, value_size, + max_entries, map_flags, -1); +} + +int bpf_create_map_in_map_node(enum bpf_map_type map_type, int key_size, + int inner_map_fd, int max_entries, + __u32 map_flags, int node) { union bpf_attr attr; @@ -84,10 +99,21 @@ int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, attr.inner_map_fd = inner_map_fd; attr.max_entries = max_entries; attr.map_flags = map_flags; + if (node >= 0) { + attr.map_flags |= BPF_F_NUMA_NODE; + attr.numa_node = node; + } return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); } +int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, + int inner_map_fd, int max_entries, __u32 map_flags) +{ + return bpf_create_map_in_map_node(map_type, key_size, inner_map_fd, + max_entries, map_flags, -1); +} + int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, size_t insns_cnt, const char *license, __u32 kern_version, char *log_buf, size_t log_buf_sz) @@ -314,7 +340,6 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len) int err; bzero(&attr, sizeof(attr)); - bzero(info, *info_len); attr.info.bpf_fd = prog_fd; attr.info.info_len = *info_len; attr.info.info = ptr_to_u64(info); diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 418c86e69bcbfae71d93d07c7054afa08b149c18..b8ea5843c39ee7151879d39e422f9a4d41f5434a 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -24,8 +24,14 @@ #include #include +int bpf_create_map_node(enum bpf_map_type map_type, int key_size, + int value_size, int max_entries, __u32 map_flags, + int node); int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, int max_entries, __u32 map_flags); +int bpf_create_map_in_map_node(enum bpf_map_type map_type, int key_size, + int inner_map_fd, int max_entries, + __u32 map_flags, int node); int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, int inner_map_fd, int max_entries, __u32 map_flags); diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 1a2c07eb7795bb4fb43e4a97bdc721d7cbc7f3b8..35f6dfcdc56518528b964f04d7bc7033e1a2b36b 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -879,7 +879,8 @@ bpf_object__create_maps(struct bpf_object *obj) size_t j; int err = *pfd; - pr_warning("failed to create map: %s\n", + pr_warning("failed to create map (name: '%s'): %s\n", + obj->maps[i].name, strerror(errno)); for (j = 0; j < i; j++) zclose(obj->maps[j].fd); @@ -1744,3 +1745,32 @@ long libbpf_get_error(const void *ptr) return PTR_ERR(ptr); return 0; } + +int bpf_prog_load(const char *file, enum bpf_prog_type type, + struct bpf_object **pobj, int *prog_fd) +{ + struct bpf_program *prog; + struct bpf_object *obj; + int err; + + obj = bpf_object__open(file); + if (IS_ERR(obj)) + return -ENOENT; + + prog = bpf_program__next(NULL, obj); + if (!prog) { + bpf_object__close(obj); + return -ENOENT; + } + + bpf_program__set_type(prog, type); + err = bpf_object__load(obj); + if (err) { + bpf_object__close(obj); + return -EINVAL; + } + + *pobj = obj; + *prog_fd = bpf_program__fd(prog); + return 0; +} diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 32c7252f734e42f9895c4686c4236f4b259d99a3..7959086eb9c920260246dc126846282aa489d7c7 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -243,4 +243,6 @@ int bpf_map__pin(struct bpf_map *map, const char *path); long libbpf_get_error(const void *ptr); +int bpf_prog_load(const char *file, enum bpf_prog_type type, + struct bpf_object **pobj, int *prog_fd); #endif diff --git a/tools/lib/string.c b/tools/lib/string.c index 8e678af1c6ee479eae333cf5766598db5dce5208..a4246f14ded101f2dc61ca04d092b7cebe677632 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -39,27 +39,45 @@ void *memdup(const void *src, size_t len) * @s: input string * @res: result * - * This routine returns 0 iff the first character is one of 'Yy1Nn0'. - * Otherwise it will return -EINVAL. Value pointed to by res is - * updated upon finding a match. + * This routine returns 0 iff the first character is one of 'Yy1Nn0', or + * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value + * pointed to by res is updated upon finding a match. */ int strtobool(const char *s, bool *res) { + if (!s) + return -EINVAL; + switch (s[0]) { case 'y': case 'Y': case '1': *res = true; - break; + return 0; case 'n': case 'N': case '0': *res = false; - break; + return 0; + case 'o': + case 'O': + switch (s[1]) { + case 'n': + case 'N': + *res = true; + return 0; + case 'f': + case 'F': + *res = false; + return 0; + default: + break; + } default: - return -EINVAL; + break; } - return 0; + + return -EINVAL; } /** @@ -87,12 +105,3 @@ size_t __weak strlcpy(char *dest, const char *src, size_t size) } return ret; } - -int prefixcmp(const char *str, const char *prefix) -{ - for (; ; str++, prefix++) - if (!*prefix) - return 0; - else if (*str != *prefix) - return (unsigned char)*prefix - (unsigned char)*str; -} diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index 3d1c3b5b51504d3512df5825baaaeec70d6f939b..7e9f03c97e4c6027e34f6b2847bcffc6ab0e0d1c 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -21,7 +21,7 @@ LIBFILE = $(OUTPUT)libsubcmd.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC -ifeq ($(CC), clang) +ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 else CFLAGS += -O6 diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c index ba970a73d053f3c019a318dbb7fa14b9dbab9b40..0310520f918e450c06babea8042d13b5dd390d10 100644 --- a/tools/lib/subcmd/help.c +++ b/tools/lib/subcmd/help.c @@ -171,7 +171,7 @@ static void list_commands_in_dir(struct cmdnames *cmds, while ((de = readdir(dir)) != NULL) { int entlen; - if (prefixcmp(de->d_name, prefix)) + if (!strstarts(de->d_name, prefix)) continue; astrcat(&buf, de->d_name); diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c index 359bfa77f39cdebac7df82876b227d1a63975c39..2bd6fd0c1d40d40d56000a34c2b2dd99bed0ef1c 100644 --- a/tools/lib/subcmd/parse-options.c +++ b/tools/lib/subcmd/parse-options.c @@ -368,7 +368,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, return 0; } if (!rest) { - if (!prefixcmp(options->long_name, "no-")) { + if (strstarts(options->long_name, "no-")) { /* * The long name itself starts with "no-", so * accept the option without "no-" so that users @@ -381,7 +381,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, goto match; } /* Abbreviated case */ - if (!prefixcmp(options->long_name + 3, arg)) { + if (strstarts(options->long_name + 3, arg)) { flags |= OPT_UNSET; goto is_abbreviated; } @@ -406,7 +406,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, continue; } /* negated and abbreviated very much? */ - if (!prefixcmp("no-", arg)) { + if (strstarts("no-", arg)) { flags |= OPT_UNSET; goto is_abbreviated; } @@ -416,7 +416,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, flags |= OPT_UNSET; rest = skip_prefix(arg + 3, options->long_name); /* abbreviated and negated? */ - if (!rest && !prefixcmp(options->long_name, arg + 3)) + if (!rest && strstarts(options->long_name, arg + 3)) goto is_abbreviated; if (!rest) continue; @@ -456,7 +456,7 @@ static void check_typos(const char *arg, const struct option *options) if (strlen(arg) < 3) return; - if (!prefixcmp(arg, "no-")) { + if (strstarts(arg, "no-")) { fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); exit(129); } @@ -464,7 +464,7 @@ static void check_typos(const char *arg, const struct option *options) for (; options->type != OPTION_END; options++) { if (!options->long_name) continue; - if (!prefixcmp(options->long_name, arg)) { + if (strstarts(options->long_name, arg)) { fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); exit(129); } @@ -933,10 +933,10 @@ int parse_options_usage(const char * const *usagestr, if (opts->long_name == NULL) continue; - if (!prefixcmp(opts->long_name, optstr)) + if (strstarts(opts->long_name, optstr)) print_option_help(opts, 0); - if (!prefixcmp("no-", optstr) && - !prefixcmp(opts->long_name, optstr + 3)) + if (strstarts("no-", optstr) && + strstarts(opts->long_name, optstr + 3)) print_option_help(opts, 0); } diff --git a/tools/objtool/Build b/tools/objtool/Build index 6f2e1987c4d9079df4dde4db3bd427da51276c35..749becdf5b9080a1c3189d7d4972f9952cb200e5 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -1,6 +1,9 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += builtin-check.o +objtool-y += builtin-orc.o objtool-y += check.o +objtool-y += orc_gen.o +objtool-y += orc_dump.o objtool-y += elf.o objtool-y += special.o objtool-y += objtool.o diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt index 17c1195f11f428b4e21c783543c3826186b2777a..3995735a878fe796f36513b2bb22b20deaf642d1 100644 --- a/tools/objtool/Documentation/stack-validation.txt +++ b/tools/objtool/Documentation/stack-validation.txt @@ -11,9 +11,6 @@ analyzes every .o file and ensures the validity of its stack metadata. It enforces a set of rules on asm code and C inline assembly code so that stack traces can be reliable. -Currently it only checks frame pointer usage, but there are plans to add -CFI validation for C files and CFI generation for asm files. - For each function, it recursively follows all possible code paths and validates the correct frame pointer state at each instruction. @@ -23,6 +20,10 @@ alternative execution paths to a given instruction (or set of instructions). Similarly, it knows how to follow switch statements, for which gcc sometimes uses jump tables. +(Objtool also has an 'orc generate' subcommand which generates debuginfo +for the ORC unwinder. See Documentation/x86/orc-unwinder.txt in the +kernel tree for more details.) + Why do we need stack metadata validation? ----------------------------------------- @@ -93,37 +94,14 @@ a) More reliable stack traces for frame pointer enabled kernels or at the very end of the function after the stack frame has been destroyed. This is an inherent limitation of frame pointers. -b) 100% reliable stack traces for DWARF enabled kernels - - (NOTE: This is not yet implemented) - - As an alternative to frame pointers, DWARF Call Frame Information - (CFI) metadata can be used to walk the stack. Unlike frame pointers, - CFI metadata is out of band. So it doesn't affect runtime - performance and it can be reliable even when interrupts or exceptions - are involved. - - For C code, gcc automatically generates DWARF CFI metadata. But for - asm code, generating CFI is a tedious manual approach which requires - manually placed .cfi assembler macros to be scattered throughout the - code. It's clumsy and very easy to get wrong, and it makes the real - code harder to read. - - Stacktool will improve this situation in several ways. For code - which already has CFI annotations, it will validate them. For code - which doesn't have CFI annotations, it will generate them. So an - architecture can opt to strip out all the manual .cfi annotations - from their asm code and have objtool generate them instead. +b) ORC (Oops Rewind Capability) unwind table generation - We might also add a runtime stack validation debug option where we - periodically walk the stack from schedule() and/or an NMI to ensure - that the stack metadata is sane and that we reach the bottom of the - stack. + An alternative to frame pointers and DWARF, ORC unwind data can be + used to walk the stack. Unlike frame pointers, ORC data is out of + band. So it doesn't affect runtime performance and it can be + reliable even when interrupts or exceptions are involved. - So the benefit of objtool here will be that external tooling should - always show perfect stack traces. And the same will be true for - kernel warning/oops traces if the architecture has a runtime DWARF - unwinder. + For more details, see Documentation/x86/orc-unwinder.txt. c) Higher live patching compatibility rate @@ -211,15 +189,15 @@ they mean, and suggestions for how to fix them. function, add proper frame pointer logic using the FRAME_BEGIN and FRAME_END macros. Otherwise, if it's not a callable function, remove its ELF function annotation by changing ENDPROC to END, and instead - use the manual CFI hint macros in asm/undwarf.h. + use the manual unwind hint macros in asm/unwind_hints.h. If it's a GCC-compiled .c file, the error may be because the function uses an inline asm() statement which has a "call" instruction. An asm() statement with a call instruction must declare the use of the - stack pointer in its output operand. For example, on x86_64: + stack pointer in its output operand. On x86_64, this means adding + the ASM_CALL_CONSTRAINT as an output constraint: - register void *__sp asm("rsp"); - asm volatile("call func" : "+r" (__sp)); + asm volatile("call func" : ASM_CALL_CONSTRAINT); Otherwise the stack frame may not get created before the call. @@ -231,8 +209,8 @@ they mean, and suggestions for how to fix them. If the error is for an asm file, and the instruction is inside (or reachable from) a callable function, the function should be annotated with the ENTRY/ENDPROC macros (ENDPROC is the important one). - Otherwise, the code should probably be annotated with the CFI hint - macros in asm/undwarf.h so objtool and the unwinder can know the + Otherwise, the code should probably be annotated with the unwind hint + macros in asm/unwind_hints.h so objtool and the unwinder can know the stack state associated with the code. If you're 100% sure the code won't affect stack traces, or if you're @@ -258,7 +236,7 @@ they mean, and suggestions for how to fix them. instructions aren't allowed in a callable function, and are most likely part of the kernel entry code. They should usually not have the callable function annotation (ENDPROC) and should always be - annotated with the CFI hint macros in asm/undwarf.h. + annotated with the unwind hint macros in asm/unwind_hints.h. 6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame @@ -272,7 +250,7 @@ they mean, and suggestions for how to fix them. If the instruction is not actually in a callable function (e.g. kernel entry code), change ENDPROC to END and annotate manually with - the CFI hint macros in asm/undwarf.h. + the unwind hint macros in asm/unwind_hints.h. 7. file: warning: objtool: func()+0x5c: stack state mismatch @@ -288,8 +266,8 @@ they mean, and suggestions for how to fix them. Another possibility is that the code has some asm or inline asm which does some unusual things to the stack or the frame pointer. In such - cases it's probably appropriate to use the CFI hint macros in - asm/undwarf.h. + cases it's probably appropriate to use the unwind hint macros in + asm/unwind_hints.h. 8. file.o: warning: objtool: funcA() falls through to next function funcB() diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 0e2765e243c06c55060874629f085cdcee1f9502..6976c73e60c444b50320adfc081ecd6beaec681f 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -25,7 +25,8 @@ OBJTOOL_IN := $(OBJTOOL)-in.o all: $(OBJTOOL) INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi -CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -fomit-frame-pointer -O2 -g $(INCLUDES) +WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed +CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) LDFLAGS += -lelf $(LIBSUBCMD) # Allow old libelf to be used: @@ -52,6 +53,9 @@ $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \ diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \ || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true + @(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \ + diff ../../arch/x86/include/asm/orc_types.h orc_types.h >/dev/null) \ + || echo "warning: objtool: orc_types.h differs from kernel" >&2 )) || true $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h index 21aeca874edb33043f9f0cc2f4b344759bc32ad9..b0d7dc3d71b5ac21e8acb36b1c1f38bcf06879c4 100644 --- a/tools/objtool/arch.h +++ b/tools/objtool/arch.h @@ -31,8 +31,9 @@ #define INSN_RETURN 6 #define INSN_CONTEXT_SWITCH 7 #define INSN_STACK 8 -#define INSN_NOP 9 -#define INSN_OTHER 10 +#define INSN_BUG 9 +#define INSN_NOP 10 +#define INSN_OTHER 11 #define INSN_LAST INSN_OTHER enum op_dest_type { diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index a36c2eba64e7729347e46175a11f89ff5fe8ebbe..34a579f806e390337bdee738ae507364c02e7ad7 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -86,8 +86,8 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, struct insn insn; int x86_64, sign; unsigned char op1, op2, rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, - modrm = 0, modrm_mod = 0, modrm_rm = 0, modrm_reg = 0, - sib = 0; + rex_x = 0, modrm = 0, modrm_mod = 0, modrm_rm = 0, + modrm_reg = 0, sib = 0; x86_64 = is_x86_64(elf); if (x86_64 == -1) @@ -114,6 +114,7 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, rex = insn.rex_prefix.bytes[0]; rex_w = X86_REX_W(rex) >> 3; rex_r = X86_REX_R(rex) >> 2; + rex_x = X86_REX_X(rex) >> 1; rex_b = X86_REX_B(rex); } @@ -207,16 +208,28 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, break; case 0x89: - if (rex == 0x48 && modrm == 0xe5) { + if (rex_w && !rex_r && modrm_mod == 3 && modrm_reg == 4) { - /* mov %rsp, %rbp */ + /* mov %rsp, reg */ *type = INSN_STACK; op->src.type = OP_SRC_REG; op->src.reg = CFI_SP; op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_BP; + op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b]; + break; + } + + if (rex_w && !rex_b && modrm_mod == 3 && modrm_rm == 4) { + + /* mov reg, %rsp */ + *type = INSN_STACK; + op->src.type = OP_SRC_REG; + op->src.reg = op_to_cfi_reg[modrm_reg][rex_r]; + op->dest.type = OP_DEST_REG; + op->dest.reg = CFI_SP; break; } + /* fallthrough */ case 0x88: if (!rex_b && @@ -269,56 +282,33 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, break; case 0x8d: - if (rex == 0x48 && modrm == 0x65) { + if (sib == 0x24 && rex_w && !rex_b && !rex_x) { - /* lea -disp(%rbp), %rsp */ *type = INSN_STACK; - op->src.type = OP_SRC_ADD; - op->src.reg = CFI_BP; - op->src.offset = insn.displacement.value; - op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_SP; - break; - } - - if (rex == 0x4c && modrm == 0x54 && sib == 0x24 && - insn.displacement.value == 8) { - - /* - * lea 0x8(%rsp), %r10 - * - * Here r10 is the "drap" pointer, used as a stack - * pointer helper when the stack gets realigned. - */ - *type = INSN_STACK; - op->src.type = OP_SRC_ADD; + if (!insn.displacement.value) { + /* lea (%rsp), reg */ + op->src.type = OP_SRC_REG; + } else { + /* lea disp(%rsp), reg */ + op->src.type = OP_SRC_ADD; + op->src.offset = insn.displacement.value; + } op->src.reg = CFI_SP; - op->src.offset = 8; op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_R10; - break; - } + op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r]; - if (rex == 0x4c && modrm == 0x6c && sib == 0x24 && - insn.displacement.value == 16) { + } else if (rex == 0x48 && modrm == 0x65) { - /* - * lea 0x10(%rsp), %r13 - * - * Here r13 is the "drap" pointer, used as a stack - * pointer helper when the stack gets realigned. - */ + /* lea disp(%rbp), %rsp */ *type = INSN_STACK; op->src.type = OP_SRC_ADD; - op->src.reg = CFI_SP; - op->src.offset = 16; + op->src.reg = CFI_BP; + op->src.offset = insn.displacement.value; op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_R13; - break; - } + op->dest.reg = CFI_SP; - if (rex == 0x49 && modrm == 0x62 && - insn.displacement.value == -8) { + } else if (rex == 0x49 && modrm == 0x62 && + insn.displacement.value == -8) { /* * lea -0x8(%r10), %rsp @@ -332,11 +322,9 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, op->src.offset = -8; op->dest.type = OP_DEST_REG; op->dest.reg = CFI_SP; - break; - } - if (rex == 0x49 && modrm == 0x65 && - insn.displacement.value == -16) { + } else if (rex == 0x49 && modrm == 0x65 && + insn.displacement.value == -16) { /* * lea -0x10(%r13), %rsp @@ -350,7 +338,6 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, op->src.offset = -16; op->dest.type = OP_DEST_REG; op->dest.reg = CFI_SP; - break; } break; @@ -382,20 +369,27 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, case 0x0f: - if (op2 >= 0x80 && op2 <= 0x8f) + if (op2 >= 0x80 && op2 <= 0x8f) { + *type = INSN_JUMP_CONDITIONAL; - else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 || - op2 == 0x35) + + } else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 || + op2 == 0x35) { /* sysenter, sysret */ *type = INSN_CONTEXT_SWITCH; - else if (op2 == 0x0d || op2 == 0x1f) + } else if (op2 == 0x0b || op2 == 0xb9) { + + /* ud2 */ + *type = INSN_BUG; + + } else if (op2 == 0x0d || op2 == 0x1f) { /* nopl/nopw */ *type = INSN_NOP; - else if (op2 == 0xa0 || op2 == 0xa8) { + } else if (op2 == 0xa0 || op2 == 0xa8) { /* push fs/gs */ *type = INSN_STACK; diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 365c34ecab2682c109103a5255062e7e7227c84a..57254f5b2779fb02276f00eb82401a05eaaabeb0 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -29,7 +29,7 @@ #include "builtin.h" #include "check.h" -bool nofp; +bool no_fp, no_unreachable; static const char * const check_usage[] = { "objtool check [] file.o", @@ -37,7 +37,8 @@ static const char * const check_usage[] = { }; const struct option check_options[] = { - OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"), + OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"), + OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"), OPT_END(), }; @@ -52,5 +53,5 @@ int cmd_check(int argc, const char **argv) objname = argv[0]; - return check(objname, nofp); + return check(objname, no_fp, no_unreachable, false); } diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c new file mode 100644 index 0000000000000000000000000000000000000000..4c6b5c9ef073b31c3a01dd0ebb85efbccb4bfee0 --- /dev/null +++ b/tools/objtool/builtin-orc.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * objtool orc: + * + * This command analyzes a .o file and adds .orc_unwind and .orc_unwind_ip + * sections to it, which is used by the in-kernel ORC unwinder. + * + * This command is a superset of "objtool check". + */ + +#include +#include +#include "builtin.h" +#include "check.h" + + +static const char *orc_usage[] = { + "objtool orc generate [] file.o", + "objtool orc dump file.o", + NULL, +}; + +extern const struct option check_options[]; +extern bool no_fp, no_unreachable; + +int cmd_orc(int argc, const char **argv) +{ + const char *objname; + + argc--; argv++; + if (!strncmp(argv[0], "gen", 3)) { + argc = parse_options(argc, argv, check_options, orc_usage, 0); + if (argc != 1) + usage_with_options(orc_usage, check_options); + + objname = argv[0]; + + return check(objname, no_fp, no_unreachable, true); + + } + + if (!strcmp(argv[0], "dump")) { + if (argc != 2) + usage_with_options(orc_usage, check_options); + + objname = argv[1]; + + return orc_dump(objname); + } + + usage_with_options(orc_usage, check_options); + + return 0; +} diff --git a/tools/objtool/builtin.h b/tools/objtool/builtin.h index 34d2ba78a6167f2228cc0ec0d2976b1ea1e1a5f5..dd526067fed5ebcacbb45b7ce8a686437bd83d1a 100644 --- a/tools/objtool/builtin.h +++ b/tools/objtool/builtin.h @@ -18,5 +18,6 @@ #define _BUILTIN_H extern int cmd_check(int argc, const char **argv); +extern int cmd_orc(int argc, const char **argv); #endif /* _BUILTIN_H */ diff --git a/tools/objtool/cfi.h b/tools/objtool/cfi.h index 443ab2c69992d15a9058f0d2a7f6b304e2b0b7d7..2fe883c665c7b5ed66d3d1fc6cd6b51d1a618c93 100644 --- a/tools/objtool/cfi.h +++ b/tools/objtool/cfi.h @@ -40,7 +40,7 @@ #define CFI_R14 14 #define CFI_R15 15 #define CFI_RA 16 -#define CFI_NUM_REGS 17 +#define CFI_NUM_REGS 17 struct cfi_reg { int base; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 2c6d748804032b7e954b04cad263023de831f983..a0c518ecf085135711e8b06488381f53127d9fee 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -33,11 +33,11 @@ struct alternative { }; const char *objname; -static bool nofp; +static bool no_fp; struct cfi_state initial_func_cfi; -static struct instruction *find_insn(struct objtool_file *file, - struct section *sec, unsigned long offset) +struct instruction *find_insn(struct objtool_file *file, + struct section *sec, unsigned long offset) { struct instruction *insn; @@ -59,19 +59,6 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file, return next; } -static bool gcov_enabled(struct objtool_file *file) -{ - struct section *sec; - struct symbol *sym; - - for_each_sec(file, sec) - list_for_each_entry(sym, &sec->symbol_list, list) - if (!strncmp(sym->name, "__gcov_.", 8)) - return true; - - return false; -} - #define func_for_each_insn(file, func, insn) \ for (insn = find_insn(file, func->sec, func->offset); \ insn && &insn->list != &file->insn_list && \ @@ -100,7 +87,6 @@ static bool gcov_enabled(struct objtool_file *file) static bool ignore_func(struct objtool_file *file, struct symbol *func) { struct rela *rela; - struct instruction *insn; /* check for STACK_FRAME_NON_STANDARD */ if (file->whitelist && file->whitelist->rela) @@ -113,11 +99,6 @@ static bool ignore_func(struct objtool_file *file, struct symbol *func) return true; } - /* check if it has a context switching instruction */ - func_for_each_insn(file, func, insn) - if (insn->type == INSN_CONTEXT_SWITCH) - return true; - return false; } @@ -237,9 +218,12 @@ static void clear_insn_state(struct insn_state *state) memset(state, 0, sizeof(*state)); state->cfa.base = CFI_UNDEFINED; - for (i = 0; i < CFI_NUM_REGS; i++) + for (i = 0; i < CFI_NUM_REGS; i++) { state->regs[i].base = CFI_UNDEFINED; + state->vals[i].base = CFI_UNDEFINED; + } state->drap_reg = CFI_UNDEFINED; + state->drap_offset = -1; } /* @@ -259,6 +243,11 @@ static int decode_instructions(struct objtool_file *file) if (!(sec->sh.sh_flags & SHF_EXECINSTR)) continue; + if (strcmp(sec->name, ".altinstr_replacement") && + strcmp(sec->name, ".altinstr_aux") && + strncmp(sec->name, ".discard.", 9)) + sec->text = true; + for (offset = 0; offset < sec->len; offset += insn->len) { insn = malloc(sizeof(*insn)); if (!insn) { @@ -310,7 +299,7 @@ static int decode_instructions(struct objtool_file *file) } /* - * Find all uses of the unreachable() macro, which are code path dead ends. + * Mark "ud2" instructions and manually annotated dead ends. */ static int add_dead_ends(struct objtool_file *file) { @@ -319,9 +308,20 @@ static int add_dead_ends(struct objtool_file *file) struct instruction *insn; bool found; + /* + * By default, "ud2" is a dead end unless otherwise annotated, because + * GCC 7 inserts it for certain divide-by-zero cases. + */ + for_each_insn(file, insn) + if (insn->type == INSN_BUG) + insn->dead_end = true; + + /* + * Check for manually annotated dead ends. + */ sec = find_section_by_name(file->elf, ".rela.discard.unreachable"); if (!sec) - return 0; + goto reachable; list_for_each_entry(rela, &sec->rela_list, list) { if (rela->sym->type != STT_SECTION) { @@ -354,6 +354,48 @@ static int add_dead_ends(struct objtool_file *file) insn->dead_end = true; } +reachable: + /* + * These manually annotated reachable checks are needed for GCC 4.4, + * where the Linux unreachable() macro isn't supported. In that case + * GCC doesn't know the "ud2" is fatal, so it generates code as if it's + * not a dead end. + */ + sec = find_section_by_name(file->elf, ".rela.discard.reachable"); + if (!sec) + return 0; + + list_for_each_entry(rela, &sec->rela_list, list) { + if (rela->sym->type != STT_SECTION) { + WARN("unexpected relocation symbol type in %s", sec->name); + return -1; + } + insn = find_insn(file, rela->sym->sec, rela->addend); + if (insn) + insn = list_prev_entry(insn, list); + else if (rela->addend == rela->sym->sec->len) { + found = false; + list_for_each_entry_reverse(insn, &file->insn_list, list) { + if (insn->sec == rela->sym->sec) { + found = true; + break; + } + } + + if (!found) { + WARN("can't find reachable insn at %s+0x%x", + rela->sym->sec->name, rela->addend); + return -1; + } + } else { + WARN("can't find reachable insn at %s+0x%x", + rela->sym->sec->name, rela->addend); + return -1; + } + + insn->dead_end = false; + } + return 0; } @@ -874,6 +916,99 @@ static int add_switch_table_alts(struct objtool_file *file) return 0; } +static int read_unwind_hints(struct objtool_file *file) +{ + struct section *sec, *relasec; + struct rela *rela; + struct unwind_hint *hint; + struct instruction *insn; + struct cfi_reg *cfa; + int i; + + sec = find_section_by_name(file->elf, ".discard.unwind_hints"); + if (!sec) + return 0; + + relasec = sec->rela; + if (!relasec) { + WARN("missing .rela.discard.unwind_hints section"); + return -1; + } + + if (sec->len % sizeof(struct unwind_hint)) { + WARN("struct unwind_hint size mismatch"); + return -1; + } + + file->hints = true; + + for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) { + hint = (struct unwind_hint *)sec->data->d_buf + i; + + rela = find_rela_by_dest(sec, i * sizeof(*hint)); + if (!rela) { + WARN("can't find rela for unwind_hints[%d]", i); + return -1; + } + + insn = find_insn(file, rela->sym->sec, rela->addend); + if (!insn) { + WARN("can't find insn for unwind_hints[%d]", i); + return -1; + } + + cfa = &insn->state.cfa; + + if (hint->type == UNWIND_HINT_TYPE_SAVE) { + insn->save = true; + continue; + + } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) { + insn->restore = true; + insn->hint = true; + continue; + } + + insn->hint = true; + + switch (hint->sp_reg) { + case ORC_REG_UNDEFINED: + cfa->base = CFI_UNDEFINED; + break; + case ORC_REG_SP: + cfa->base = CFI_SP; + break; + case ORC_REG_BP: + cfa->base = CFI_BP; + break; + case ORC_REG_SP_INDIRECT: + cfa->base = CFI_SP_INDIRECT; + break; + case ORC_REG_R10: + cfa->base = CFI_R10; + break; + case ORC_REG_R13: + cfa->base = CFI_R13; + break; + case ORC_REG_DI: + cfa->base = CFI_DI; + break; + case ORC_REG_DX: + cfa->base = CFI_DX; + break; + default: + WARN_FUNC("unsupported unwind_hint sp base reg %d", + insn->sec, insn->offset, hint->sp_reg); + return -1; + } + + cfa->offset = hint->sp_offset; + insn->state.type = hint->type; + } + + return 0; +} + static int decode_sections(struct objtool_file *file) { int ret; @@ -904,6 +1039,10 @@ static int decode_sections(struct objtool_file *file) if (ret) return ret; + ret = read_unwind_hints(file); + if (ret) + return ret; + return 0; } @@ -947,11 +1086,34 @@ static bool has_valid_stack_frame(struct insn_state *state) return false; } +static int update_insn_state_regs(struct instruction *insn, struct insn_state *state) +{ + struct cfi_reg *cfa = &state->cfa; + struct stack_op *op = &insn->stack_op; + + if (cfa->base != CFI_SP) + return 0; + + /* push */ + if (op->dest.type == OP_DEST_PUSH) + cfa->offset += 8; + + /* pop */ + if (op->src.type == OP_SRC_POP) + cfa->offset -= 8; + + /* add immediate to sp */ + if (op->dest.type == OP_DEST_REG && op->src.type == OP_SRC_ADD && + op->dest.reg == CFI_SP && op->src.reg == CFI_SP) + cfa->offset -= op->src.offset; + + return 0; +} + static void save_reg(struct insn_state *state, unsigned char reg, int base, int offset) { - if ((arch_callee_saved_reg(reg) || - (state->drap && reg == state->drap_reg)) && + if (arch_callee_saved_reg(reg) && state->regs[reg].base == CFI_UNDEFINED) { state->regs[reg].base = base; state->regs[reg].offset = offset; @@ -1032,30 +1194,71 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) return 0; } + if (state->type == ORC_TYPE_REGS || state->type == ORC_TYPE_REGS_IRET) + return update_insn_state_regs(insn, state); + switch (op->dest.type) { case OP_DEST_REG: switch (op->src.type) { case OP_SRC_REG: - if (cfa->base == op->src.reg && cfa->base == CFI_SP && - op->dest.reg == CFI_BP && regs[CFI_BP].base == CFI_CFA && + if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP && + cfa->base == CFI_SP && + regs[CFI_BP].base == CFI_CFA && regs[CFI_BP].offset == -cfa->offset) { /* mov %rsp, %rbp */ cfa->base = op->dest.reg; state->bp_scratch = false; - } else if (state->drap) { + } + + else if (op->src.reg == CFI_SP && + op->dest.reg == CFI_BP && state->drap) { /* drap: mov %rsp, %rbp */ regs[CFI_BP].base = CFI_BP; regs[CFI_BP].offset = -state->stack_size; state->bp_scratch = false; - } else if (!nofp) { + } - WARN_FUNC("unknown stack-related register move", - insn->sec, insn->offset); - return -1; + else if (op->src.reg == CFI_SP && cfa->base == CFI_SP) { + + /* + * mov %rsp, %reg + * + * This is needed for the rare case where GCC + * does: + * + * mov %rsp, %rax + * ... + * mov %rax, %rsp + */ + state->vals[op->dest.reg].base = CFI_CFA; + state->vals[op->dest.reg].offset = -state->stack_size; + } + + else if (op->dest.reg == cfa->base) { + + /* mov %reg, %rsp */ + if (cfa->base == CFI_SP && + state->vals[op->src.reg].base == CFI_CFA) { + + /* + * This is needed for the rare case + * where GCC does something dumb like: + * + * lea 0x8(%rsp), %rcx + * ... + * mov %rcx, %rsp + */ + cfa->offset = -state->vals[op->src.reg].offset; + state->stack_size = cfa->offset; + + } else { + cfa->base = CFI_UNDEFINED; + cfa->offset = 0; + } } break; @@ -1077,11 +1280,25 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) break; } - if (op->dest.reg != CFI_BP && op->src.reg == CFI_SP && - cfa->base == CFI_SP) { + if (op->src.reg == CFI_SP && cfa->base == CFI_SP) { /* drap: lea disp(%rsp), %drap */ state->drap_reg = op->dest.reg; + + /* + * lea disp(%rsp), %reg + * + * This is needed for the rare case where GCC + * does something dumb like: + * + * lea 0x8(%rsp), %rcx + * ... + * mov %rcx, %rsp + */ + state->vals[op->dest.reg].base = CFI_CFA; + state->vals[op->dest.reg].offset = \ + -state->stack_size + op->src.offset; + break; } @@ -1118,7 +1335,6 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = state->drap_reg; cfa->offset = state->stack_size = 0; state->drap = true; - } /* @@ -1136,17 +1352,19 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = CFI_SP; } - if (regs[op->dest.reg].offset == -state->stack_size) { + if (state->drap && cfa->base == CFI_BP_INDIRECT && + op->dest.type == OP_DEST_REG && + op->dest.reg == state->drap_reg && + state->drap_offset == -state->stack_size) { - if (state->drap && cfa->base == CFI_BP_INDIRECT && - op->dest.type == OP_DEST_REG && - op->dest.reg == state->drap_reg) { + /* drap: pop %drap */ + cfa->base = state->drap_reg; + cfa->offset = 0; + state->drap_offset = -1; - /* drap: pop %drap */ - cfa->base = state->drap_reg; - cfa->offset = 0; - } + } else if (regs[op->dest.reg].offset == -state->stack_size) { + /* pop %reg */ restore_reg(state, op->dest.reg); } @@ -1157,15 +1375,19 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) break; case OP_SRC_REG_INDIRECT: + if (state->drap && op->src.reg == CFI_BP && + op->src.offset == state->drap_offset) { + + /* drap: mov disp(%rbp), %drap */ + cfa->base = state->drap_reg; + cfa->offset = 0; + state->drap_offset = -1; + } + if (state->drap && op->src.reg == CFI_BP && op->src.offset == regs[op->dest.reg].offset) { /* drap: mov disp(%rbp), %reg */ - if (op->dest.reg == state->drap_reg) { - cfa->base = state->drap_reg; - cfa->offset = 0; - } - restore_reg(state, op->dest.reg); } else if (op->src.reg == cfa->base && @@ -1201,8 +1423,8 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = CFI_BP_INDIRECT; cfa->offset = -state->stack_size; - /* save drap so we know when to undefine it */ - save_reg(state, op->src.reg, CFI_CFA, -state->stack_size); + /* save drap so we know when to restore it */ + state->drap_offset = -state->stack_size; } else if (op->src.reg == CFI_BP && cfa->base == state->drap_reg) { @@ -1222,7 +1444,7 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) } /* detect when asm code uses rbp as a scratch register */ - if (!nofp && insn->func && op->src.reg == CFI_BP && + if (!no_fp && insn->func && op->src.reg == CFI_BP && cfa->base != CFI_BP) state->bp_scratch = true; break; @@ -1236,8 +1458,8 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = CFI_BP_INDIRECT; cfa->offset = op->dest.offset; - /* save drap so we know when to undefine it */ - save_reg(state, op->src.reg, CFI_CFA, op->dest.offset); + /* save drap offset so we know when to restore it */ + state->drap_offset = op->dest.offset; } else if (regs[op->src.reg].base == CFI_UNDEFINED) { @@ -1323,12 +1545,17 @@ static bool insn_state_match(struct instruction *insn, struct insn_state *state) break; } + } else if (state1->type != state2->type) { + WARN_FUNC("stack state mismatch: type1=%d type2=%d", + insn->sec, insn->offset, state1->type, state2->type); + } else if (state1->drap != state2->drap || - (state1->drap && state1->drap_reg != state2->drap_reg)) { - WARN_FUNC("stack state mismatch: drap1=%d(%d) drap2=%d(%d)", + (state1->drap && state1->drap_reg != state2->drap_reg) || + (state1->drap && state1->drap_offset != state2->drap_offset)) { + WARN_FUNC("stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)", insn->sec, insn->offset, - state1->drap, state1->drap_reg, - state2->drap, state2->drap_reg); + state1->drap, state1->drap_reg, state1->drap_offset, + state2->drap, state2->drap_reg, state2->drap_offset); } else return true; @@ -1346,7 +1573,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, struct insn_state state) { struct alternative *alt; - struct instruction *insn; + struct instruction *insn, *next_insn; struct section *sec; struct symbol *func = NULL; int ret; @@ -1357,34 +1584,77 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, if (insn->alt_group && list_empty(&insn->alts)) { WARN_FUNC("don't know how to handle branch to middle of alternative instruction group", sec, insn->offset); - return -1; + return 1; } while (1) { - if (file->c_file && insn->func) { - if (func && func != insn->func) { - WARN("%s() falls through to next function %s()", - func->name, insn->func->name); - return 1; - } + next_insn = next_insn_same_sec(file, insn); + + + if (file->c_file && func && insn->func && func != insn->func) { + WARN("%s() falls through to next function %s()", + func->name, insn->func->name); + return 1; } - func = insn->func; + if (insn->func) + func = insn->func; if (func && insn->ignore) { WARN_FUNC("BUG: why am I validating an ignored function?", sec, insn->offset); - return -1; + return 1; } if (insn->visited) { - if (!!insn_state_match(insn, &state)) + if (!insn->hint && !insn_state_match(insn, &state)) return 1; return 0; } - insn->state = state; + if (insn->hint) { + if (insn->restore) { + struct instruction *save_insn, *i; + + i = insn; + save_insn = NULL; + func_for_each_insn_continue_reverse(file, func, i) { + if (i->save) { + save_insn = i; + break; + } + } + + if (!save_insn) { + WARN_FUNC("no corresponding CFI save for CFI restore", + sec, insn->offset); + return 1; + } + + if (!save_insn->visited) { + /* + * Oops, no state to copy yet. + * Hopefully we can reach this + * instruction from another branch + * after the save insn has been + * visited. + */ + if (insn == first) + return 0; + + WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo", + sec, insn->offset); + return 1; + } + + insn->state = save_insn->state; + } + + state = insn->state; + + } else + insn->state = state; insn->visited = true; @@ -1423,7 +1693,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, /* fallthrough */ case INSN_CALL_DYNAMIC: - if (!nofp && func && !has_valid_stack_frame(&state)) { + if (!no_fp && func && !has_valid_stack_frame(&state)) { WARN_FUNC("call without frame pointer save/setup", sec, insn->offset); return 1; @@ -1461,9 +1731,17 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, return 0; + case INSN_CONTEXT_SWITCH: + if (func && (!next_insn || !next_insn->hint)) { + WARN_FUNC("unsupported instruction in callable function", + sec, insn->offset); + return 1; + } + return 0; + case INSN_STACK: if (update_insn_state(insn, &state)) - return -1; + return 1; break; @@ -1474,7 +1752,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, if (insn->dead_end) return 0; - insn = next_insn_same_sec(file, insn); + insn = next_insn; if (!insn) { WARN("%s: unexpected end of section", sec->name); return 1; @@ -1484,6 +1762,27 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, return 0; } +static int validate_unwind_hints(struct objtool_file *file) +{ + struct instruction *insn; + int ret, warnings = 0; + struct insn_state state; + + if (!file->hints) + return 0; + + clear_insn_state(&state); + + for_each_insn(file, insn) { + if (insn->hint && !insn->visited) { + ret = validate_branch(file, insn, state); + warnings += ret; + } + } + + return warnings; +} + static bool is_kasan_insn(struct instruction *insn) { return (insn->type == INSN_CALL && @@ -1507,8 +1806,13 @@ static bool ignore_unreachable_insn(struct instruction *insn) /* * Ignore any unused exceptions. This can happen when a whitelisted * function has an exception table entry. + * + * Also ignore alternative replacement instructions. This can happen + * when a whitelisted function uses one of the ALTERNATIVE macros. */ - if (!strcmp(insn->sec->name, ".fixup")) + if (!strcmp(insn->sec->name, ".fixup") || + !strcmp(insn->sec->name, ".altinstr_replacement") || + !strcmp(insn->sec->name, ".altinstr_aux")) return true; /* @@ -1580,15 +1884,6 @@ static int validate_reachable_instructions(struct objtool_file *file) if (insn->visited || ignore_unreachable_insn(insn)) continue; - /* - * gcov produces a lot of unreachable instructions. If we get - * an unreachable warning and the file has gcov enabled, just - * ignore it, and all other such warnings for the file. Do - * this here because this is an expensive function. - */ - if (gcov_enabled(file)) - return 0; - WARN_FUNC("unreachable instruction", insn->sec, insn->offset); return 1; } @@ -1613,15 +1908,15 @@ static void cleanup(struct objtool_file *file) elf_close(file->elf); } -int check(const char *_objname, bool _nofp) +int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc) { struct objtool_file file; int ret, warnings = 0; objname = _objname; - nofp = _nofp; + no_fp = _no_fp; - file.elf = elf_open(objname); + file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY); if (!file.elf) return 1; @@ -1629,8 +1924,9 @@ int check(const char *_objname, bool _nofp) hash_init(file.insn_hash); file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard"); file.rodata = find_section_by_name(file.elf, ".rodata"); - file.ignore_unreachables = false; file.c_file = find_section_by_name(file.elf, ".comment"); + file.ignore_unreachables = no_unreachable; + file.hints = false; arch_initial_func_cfi_state(&initial_func_cfi); @@ -1647,6 +1943,11 @@ int check(const char *_objname, bool _nofp) goto out; warnings += ret; + ret = validate_unwind_hints(&file); + if (ret < 0) + goto out; + warnings += ret; + if (!warnings) { ret = validate_reachable_instructions(&file); if (ret < 0) @@ -1654,6 +1955,20 @@ int check(const char *_objname, bool _nofp) warnings += ret; } + if (orc) { + ret = create_orc(&file); + if (ret < 0) + goto out; + + ret = create_orc_sections(&file); + if (ret < 0) + goto out; + + ret = elf_write(file.elf); + if (ret < 0) + goto out; + } + out: cleanup(&file); diff --git a/tools/objtool/check.h b/tools/objtool/check.h index da85f5b00ec687290952cce155f3f27ec9c3ffad..47d9ea70a83d9f9326fb7bd68431c88337b5ce31 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h @@ -22,15 +22,18 @@ #include "elf.h" #include "cfi.h" #include "arch.h" +#include "orc.h" #include struct insn_state { struct cfi_reg cfa; struct cfi_reg regs[CFI_NUM_REGS]; int stack_size; + unsigned char type; bool bp_scratch; bool drap; - int drap_reg; + int drap_reg, drap_offset; + struct cfi_reg vals[CFI_NUM_REGS]; }; struct instruction { @@ -41,13 +44,14 @@ struct instruction { unsigned int len; unsigned char type; unsigned long immediate; - bool alt_group, visited, dead_end, ignore; + bool alt_group, visited, dead_end, ignore, hint, save, restore; struct symbol *call_dest; struct instruction *jump_dest; struct list_head alts; struct symbol *func; struct stack_op stack_op; struct insn_state state; + struct orc_entry orc; }; struct objtool_file { @@ -55,12 +59,22 @@ struct objtool_file { struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 16); struct section *rodata, *whitelist; - bool ignore_unreachables, c_file; + bool ignore_unreachables, c_file, hints; }; -int check(const char *objname, bool nofp); +int check(const char *objname, bool no_fp, bool no_unreachable, bool orc); + +struct instruction *find_insn(struct objtool_file *file, + struct section *sec, unsigned long offset); #define for_each_insn(file, insn) \ list_for_each_entry(insn, &file->insn_list, list) +#define sec_for_each_insn(file, sec, insn) \ + for (insn = find_insn(file, sec, 0); \ + insn && &insn->list != &file->insn_list && \ + insn->sec == sec; \ + insn = list_next_entry(insn, list)) + + #endif /* _CHECK_H */ diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 1a7e8aa2af582f278a95e238800ebb3a2e7b54f9..24460155c82c9b2305a2484d037be9017a00becb 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -30,16 +30,6 @@ #include "elf.h" #include "warn.h" -/* - * Fallback for systems without this "read, mmaping if possible" cmd. - */ -#ifndef ELF_C_READ_MMAP -#define ELF_C_READ_MMAP ELF_C_READ -#endif - -#define WARN_ELF(format, ...) \ - WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1)) - struct section *find_section_by_name(struct elf *elf, const char *name) { struct section *sec; @@ -185,19 +175,20 @@ static int read_sections(struct elf *elf) return -1; } - sec->data = elf_getdata(s, NULL); - if (!sec->data) { - WARN_ELF("elf_getdata"); - return -1; - } - - if (sec->data->d_off != 0 || - sec->data->d_size != sec->sh.sh_size) { - WARN("unexpected data attributes for %s", sec->name); - return -1; + if (sec->sh.sh_size != 0) { + sec->data = elf_getdata(s, NULL); + if (!sec->data) { + WARN_ELF("elf_getdata"); + return -1; + } + if (sec->data->d_off != 0 || + sec->data->d_size != sec->sh.sh_size) { + WARN("unexpected data attributes for %s", + sec->name); + return -1; + } } - - sec->len = sec->data->d_size; + sec->len = sec->sh.sh_size; } /* sanity check, one more call to elf_nextscn() should return NULL */ @@ -349,9 +340,10 @@ static int read_relas(struct elf *elf) return 0; } -struct elf *elf_open(const char *name) +struct elf *elf_open(const char *name, int flags) { struct elf *elf; + Elf_Cmd cmd; elf_version(EV_CURRENT); @@ -364,13 +356,20 @@ struct elf *elf_open(const char *name) INIT_LIST_HEAD(&elf->sections); - elf->fd = open(name, O_RDONLY); + elf->fd = open(name, flags); if (elf->fd == -1) { perror("open"); goto err; } - elf->elf = elf_begin(elf->fd, ELF_C_READ_MMAP, NULL); + if ((flags & O_ACCMODE) == O_RDONLY) + cmd = ELF_C_READ_MMAP; + else if ((flags & O_ACCMODE) == O_RDWR) + cmd = ELF_C_RDWR; + else /* O_WRONLY */ + cmd = ELF_C_WRITE; + + elf->elf = elf_begin(elf->fd, cmd, NULL); if (!elf->elf) { WARN_ELF("elf_begin"); goto err; @@ -397,6 +396,200 @@ struct elf *elf_open(const char *name) return NULL; } +struct section *elf_create_section(struct elf *elf, const char *name, + size_t entsize, int nr) +{ + struct section *sec, *shstrtab; + size_t size = entsize * nr; + struct Elf_Scn *s; + Elf_Data *data; + + sec = malloc(sizeof(*sec)); + if (!sec) { + perror("malloc"); + return NULL; + } + memset(sec, 0, sizeof(*sec)); + + INIT_LIST_HEAD(&sec->symbol_list); + INIT_LIST_HEAD(&sec->rela_list); + hash_init(sec->rela_hash); + hash_init(sec->symbol_hash); + + list_add_tail(&sec->list, &elf->sections); + + s = elf_newscn(elf->elf); + if (!s) { + WARN_ELF("elf_newscn"); + return NULL; + } + + sec->name = strdup(name); + if (!sec->name) { + perror("strdup"); + return NULL; + } + + sec->idx = elf_ndxscn(s); + sec->len = size; + sec->changed = true; + + sec->data = elf_newdata(s); + if (!sec->data) { + WARN_ELF("elf_newdata"); + return NULL; + } + + sec->data->d_size = size; + sec->data->d_align = 1; + + if (size) { + sec->data->d_buf = malloc(size); + if (!sec->data->d_buf) { + perror("malloc"); + return NULL; + } + memset(sec->data->d_buf, 0, size); + } + + if (!gelf_getshdr(s, &sec->sh)) { + WARN_ELF("gelf_getshdr"); + return NULL; + } + + sec->sh.sh_size = size; + sec->sh.sh_entsize = entsize; + sec->sh.sh_type = SHT_PROGBITS; + sec->sh.sh_addralign = 1; + sec->sh.sh_flags = SHF_ALLOC; + + + /* Add section name to .shstrtab */ + shstrtab = find_section_by_name(elf, ".shstrtab"); + if (!shstrtab) { + WARN("can't find .shstrtab section"); + return NULL; + } + + s = elf_getscn(elf->elf, shstrtab->idx); + if (!s) { + WARN_ELF("elf_getscn"); + return NULL; + } + + data = elf_newdata(s); + if (!data) { + WARN_ELF("elf_newdata"); + return NULL; + } + + data->d_buf = sec->name; + data->d_size = strlen(name) + 1; + data->d_align = 1; + + sec->sh.sh_name = shstrtab->len; + + shstrtab->len += strlen(name) + 1; + shstrtab->changed = true; + + return sec; +} + +struct section *elf_create_rela_section(struct elf *elf, struct section *base) +{ + char *relaname; + struct section *sec; + + relaname = malloc(strlen(base->name) + strlen(".rela") + 1); + if (!relaname) { + perror("malloc"); + return NULL; + } + strcpy(relaname, ".rela"); + strcat(relaname, base->name); + + sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0); + free(relaname); + if (!sec) + return NULL; + + base->rela = sec; + sec->base = base; + + sec->sh.sh_type = SHT_RELA; + sec->sh.sh_addralign = 8; + sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; + sec->sh.sh_info = base->idx; + sec->sh.sh_flags = SHF_INFO_LINK; + + return sec; +} + +int elf_rebuild_rela_section(struct section *sec) +{ + struct rela *rela; + int nr, idx = 0, size; + GElf_Rela *relas; + + nr = 0; + list_for_each_entry(rela, &sec->rela_list, list) + nr++; + + size = nr * sizeof(*relas); + relas = malloc(size); + if (!relas) { + perror("malloc"); + return -1; + } + + sec->data->d_buf = relas; + sec->data->d_size = size; + + sec->sh.sh_size = size; + + idx = 0; + list_for_each_entry(rela, &sec->rela_list, list) { + relas[idx].r_offset = rela->offset; + relas[idx].r_addend = rela->addend; + relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type); + idx++; + } + + return 0; +} + +int elf_write(struct elf *elf) +{ + struct section *sec; + Elf_Scn *s; + + /* Update section headers for changed sections: */ + list_for_each_entry(sec, &elf->sections, list) { + if (sec->changed) { + s = elf_getscn(elf->elf, sec->idx); + if (!s) { + WARN_ELF("elf_getscn"); + return -1; + } + if (!gelf_update_shdr(s, &sec->sh)) { + WARN_ELF("gelf_update_shdr"); + return -1; + } + } + } + + /* Make sure the new section header entries get updated properly. */ + elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); + + /* Write all changes to the file. */ + if (elf_update(elf->elf, ELF_C_WRITE) < 0) { + WARN_ELF("elf_update"); + return -1; + } + + return 0; +} + void elf_close(struct elf *elf) { struct section *sec, *tmpsec; diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h index 343968b778cba656d5d11d12c6141c1ef9675c82..d86e2ff14466148d3b8ae46065274956a5b3c4f8 100644 --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h @@ -28,6 +28,13 @@ # define elf_getshdrstrndx elf_getshstrndx #endif +/* + * Fallback for systems without this "read, mmaping if possible" cmd. + */ +#ifndef ELF_C_READ_MMAP +#define ELF_C_READ_MMAP ELF_C_READ +#endif + struct section { struct list_head list; GElf_Shdr sh; @@ -41,6 +48,7 @@ struct section { char *name; int idx; unsigned int len; + bool changed, text; }; struct symbol { @@ -75,7 +83,7 @@ struct elf { }; -struct elf *elf_open(const char *name); +struct elf *elf_open(const char *name, int flags); struct section *find_section_by_name(struct elf *elf, const char *name); struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); struct symbol *find_symbol_containing(struct section *sec, unsigned long offset); @@ -83,6 +91,11 @@ struct rela *find_rela_by_dest(struct section *sec, unsigned long offset); struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, unsigned int len); struct symbol *find_containing_func(struct section *sec, unsigned long offset); +struct section *elf_create_section(struct elf *elf, const char *name, size_t + entsize, int nr); +struct section *elf_create_rela_section(struct elf *elf, struct section *base); +int elf_rebuild_rela_section(struct section *sec); +int elf_write(struct elf *elf); void elf_close(struct elf *elf); #define for_each_sec(file, sec) \ diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index ecc5b1b5d15df6fddd1fe27d929f92f5111b8894..31e0f91438400677d654f0d23ea1011dc69588ed 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -42,10 +42,11 @@ struct cmd_struct { }; static const char objtool_usage_string[] = - "objtool [OPTIONS] COMMAND [ARGS]"; + "objtool COMMAND [ARGS]"; static struct cmd_struct objtool_cmds[] = { {"check", cmd_check, "Perform stack metadata validation on an object file" }, + {"orc", cmd_orc, "Generate in-place ORC unwind tables for an object file" }, }; bool help; diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h new file mode 100644 index 0000000000000000000000000000000000000000..a4139e386ef37471e7c0f71e66b6df05739e2360 --- /dev/null +++ b/tools/objtool/orc.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _ORC_H +#define _ORC_H + +#include "orc_types.h" + +struct objtool_file; + +int create_orc(struct objtool_file *file); +int create_orc_sections(struct objtool_file *file); + +int orc_dump(const char *objname); + +#endif /* _ORC_H */ diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c new file mode 100644 index 0000000000000000000000000000000000000000..36c5bf6a2675143b788e89663ee4652efbbbb582 --- /dev/null +++ b/tools/objtool/orc_dump.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include "orc.h" +#include "warn.h" + +static const char *reg_name(unsigned int reg) +{ + switch (reg) { + case ORC_REG_PREV_SP: + return "prevsp"; + case ORC_REG_DX: + return "dx"; + case ORC_REG_DI: + return "di"; + case ORC_REG_BP: + return "bp"; + case ORC_REG_SP: + return "sp"; + case ORC_REG_R10: + return "r10"; + case ORC_REG_R13: + return "r13"; + case ORC_REG_BP_INDIRECT: + return "bp(ind)"; + case ORC_REG_SP_INDIRECT: + return "sp(ind)"; + default: + return "?"; + } +} + +static const char *orc_type_name(unsigned int type) +{ + switch (type) { + case ORC_TYPE_CALL: + return "call"; + case ORC_TYPE_REGS: + return "regs"; + case ORC_TYPE_REGS_IRET: + return "iret"; + default: + return "?"; + } +} + +static void print_reg(unsigned int reg, int offset) +{ + if (reg == ORC_REG_BP_INDIRECT) + printf("(bp%+d)", offset); + else if (reg == ORC_REG_SP_INDIRECT) + printf("(sp%+d)", offset); + else if (reg == ORC_REG_UNDEFINED) + printf("(und)"); + else + printf("%s%+d", reg_name(reg), offset); +} + +int orc_dump(const char *_objname) +{ + int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0; + struct orc_entry *orc = NULL; + char *name; + unsigned long nr_sections, orc_ip_addr = 0; + size_t shstrtab_idx; + Elf *elf; + Elf_Scn *scn; + GElf_Shdr sh; + GElf_Rela rela; + GElf_Sym sym; + Elf_Data *data, *symtab = NULL, *rela_orc_ip = NULL; + + + objname = _objname; + + elf_version(EV_CURRENT); + + fd = open(objname, O_RDONLY); + if (fd == -1) { + perror("open"); + return -1; + } + + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); + if (!elf) { + WARN_ELF("elf_begin"); + return -1; + } + + if (elf_getshdrnum(elf, &nr_sections)) { + WARN_ELF("elf_getshdrnum"); + return -1; + } + + if (elf_getshdrstrndx(elf, &shstrtab_idx)) { + WARN_ELF("elf_getshdrstrndx"); + return -1; + } + + for (i = 0; i < nr_sections; i++) { + scn = elf_getscn(elf, i); + if (!scn) { + WARN_ELF("elf_getscn"); + return -1; + } + + if (!gelf_getshdr(scn, &sh)) { + WARN_ELF("gelf_getshdr"); + return -1; + } + + name = elf_strptr(elf, shstrtab_idx, sh.sh_name); + if (!name) { + WARN_ELF("elf_strptr"); + return -1; + } + + data = elf_getdata(scn, NULL); + if (!data) { + WARN_ELF("elf_getdata"); + return -1; + } + + if (!strcmp(name, ".symtab")) { + symtab = data; + } else if (!strcmp(name, ".orc_unwind")) { + orc = data->d_buf; + orc_size = sh.sh_size; + } else if (!strcmp(name, ".orc_unwind_ip")) { + orc_ip = data->d_buf; + orc_ip_addr = sh.sh_addr; + } else if (!strcmp(name, ".rela.orc_unwind_ip")) { + rela_orc_ip = data; + } + } + + if (!symtab || !orc || !orc_ip) + return 0; + + if (orc_size % sizeof(*orc) != 0) { + WARN("bad .orc_unwind section size"); + return -1; + } + + nr_entries = orc_size / sizeof(*orc); + for (i = 0; i < nr_entries; i++) { + if (rela_orc_ip) { + if (!gelf_getrela(rela_orc_ip, i, &rela)) { + WARN_ELF("gelf_getrela"); + return -1; + } + + if (!gelf_getsym(symtab, GELF_R_SYM(rela.r_info), &sym)) { + WARN_ELF("gelf_getsym"); + return -1; + } + + scn = elf_getscn(elf, sym.st_shndx); + if (!scn) { + WARN_ELF("elf_getscn"); + return -1; + } + + if (!gelf_getshdr(scn, &sh)) { + WARN_ELF("gelf_getshdr"); + return -1; + } + + name = elf_strptr(elf, shstrtab_idx, sh.sh_name); + if (!name || !*name) { + WARN_ELF("elf_strptr"); + return -1; + } + + printf("%s+%lx:", name, rela.r_addend); + + } else { + printf("%lx:", orc_ip_addr + (i * sizeof(int)) + orc_ip[i]); + } + + + printf(" sp:"); + + print_reg(orc[i].sp_reg, orc[i].sp_offset); + + printf(" bp:"); + + print_reg(orc[i].bp_reg, orc[i].bp_offset); + + printf(" type:%s\n", orc_type_name(orc[i].type)); + } + + elf_end(elf); + close(fd); + + return 0; +} diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c new file mode 100644 index 0000000000000000000000000000000000000000..e5ca31429c9bac29a9c66c4f8ddf97a94651690b --- /dev/null +++ b/tools/objtool/orc_gen.c @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include + +#include "orc.h" +#include "check.h" +#include "warn.h" + +int create_orc(struct objtool_file *file) +{ + struct instruction *insn; + + for_each_insn(file, insn) { + struct orc_entry *orc = &insn->orc; + struct cfi_reg *cfa = &insn->state.cfa; + struct cfi_reg *bp = &insn->state.regs[CFI_BP]; + + if (cfa->base == CFI_UNDEFINED) { + orc->sp_reg = ORC_REG_UNDEFINED; + continue; + } + + switch (cfa->base) { + case CFI_SP: + orc->sp_reg = ORC_REG_SP; + break; + case CFI_SP_INDIRECT: + orc->sp_reg = ORC_REG_SP_INDIRECT; + break; + case CFI_BP: + orc->sp_reg = ORC_REG_BP; + break; + case CFI_BP_INDIRECT: + orc->sp_reg = ORC_REG_BP_INDIRECT; + break; + case CFI_R10: + orc->sp_reg = ORC_REG_R10; + break; + case CFI_R13: + orc->sp_reg = ORC_REG_R13; + break; + case CFI_DI: + orc->sp_reg = ORC_REG_DI; + break; + case CFI_DX: + orc->sp_reg = ORC_REG_DX; + break; + default: + WARN_FUNC("unknown CFA base reg %d", + insn->sec, insn->offset, cfa->base); + return -1; + } + + switch(bp->base) { + case CFI_UNDEFINED: + orc->bp_reg = ORC_REG_UNDEFINED; + break; + case CFI_CFA: + orc->bp_reg = ORC_REG_PREV_SP; + break; + case CFI_BP: + orc->bp_reg = ORC_REG_BP; + break; + default: + WARN_FUNC("unknown BP base reg %d", + insn->sec, insn->offset, bp->base); + return -1; + } + + orc->sp_offset = cfa->offset; + orc->bp_offset = bp->offset; + orc->type = insn->state.type; + } + + return 0; +} + +static int create_orc_entry(struct section *u_sec, struct section *ip_relasec, + unsigned int idx, struct section *insn_sec, + unsigned long insn_off, struct orc_entry *o) +{ + struct orc_entry *orc; + struct rela *rela; + + /* populate ORC data */ + orc = (struct orc_entry *)u_sec->data->d_buf + idx; + memcpy(orc, o, sizeof(*orc)); + + /* populate rela for ip */ + rela = malloc(sizeof(*rela)); + if (!rela) { + perror("malloc"); + return -1; + } + memset(rela, 0, sizeof(*rela)); + + rela->sym = insn_sec->sym; + rela->addend = insn_off; + rela->type = R_X86_64_PC32; + rela->offset = idx * sizeof(int); + + list_add_tail(&rela->list, &ip_relasec->rela_list); + hash_add(ip_relasec->rela_hash, &rela->hash, rela->offset); + + return 0; +} + +int create_orc_sections(struct objtool_file *file) +{ + struct instruction *insn, *prev_insn; + struct section *sec, *u_sec, *ip_relasec; + unsigned int idx; + + struct orc_entry empty = { + .sp_reg = ORC_REG_UNDEFINED, + .bp_reg = ORC_REG_UNDEFINED, + .type = ORC_TYPE_CALL, + }; + + sec = find_section_by_name(file->elf, ".orc_unwind"); + if (sec) { + WARN("file already has .orc_unwind section, skipping"); + return -1; + } + + /* count the number of needed orcs */ + idx = 0; + for_each_sec(file, sec) { + if (!sec->text) + continue; + + prev_insn = NULL; + sec_for_each_insn(file, sec, insn) { + if (!prev_insn || + memcmp(&insn->orc, &prev_insn->orc, + sizeof(struct orc_entry))) { + idx++; + } + prev_insn = insn; + } + + /* section terminator */ + if (prev_insn) + idx++; + } + if (!idx) + return -1; + + + /* create .orc_unwind_ip and .rela.orc_unwind_ip sections */ + sec = elf_create_section(file->elf, ".orc_unwind_ip", sizeof(int), idx); + + ip_relasec = elf_create_rela_section(file->elf, sec); + if (!ip_relasec) + return -1; + + /* create .orc_unwind section */ + u_sec = elf_create_section(file->elf, ".orc_unwind", + sizeof(struct orc_entry), idx); + + /* populate sections */ + idx = 0; + for_each_sec(file, sec) { + if (!sec->text) + continue; + + prev_insn = NULL; + sec_for_each_insn(file, sec, insn) { + if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc, + sizeof(struct orc_entry))) { + + if (create_orc_entry(u_sec, ip_relasec, idx, + insn->sec, insn->offset, + &insn->orc)) + return -1; + + idx++; + } + prev_insn = insn; + } + + /* section terminator */ + if (prev_insn) { + if (create_orc_entry(u_sec, ip_relasec, idx, + prev_insn->sec, + prev_insn->offset + prev_insn->len, + &empty)) + return -1; + + idx++; + } + } + + if (elf_rebuild_rela_section(ip_relasec)) + return -1; + + return 0; +} diff --git a/tools/objtool/orc_types.h b/tools/objtool/orc_types.h new file mode 100644 index 0000000000000000000000000000000000000000..9c9dc579bd7db172287f5fdea9628cabaeff56af --- /dev/null +++ b/tools/objtool/orc_types.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _ORC_TYPES_H +#define _ORC_TYPES_H + +#include +#include + +/* + * The ORC_REG_* registers are base registers which are used to find other + * registers on the stack. + * + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the + * address of the previous frame: the caller's SP before it called the current + * function. + * + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in + * the current frame. + * + * The most commonly used base registers are SP and BP -- which the previous SP + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is + * usually based on. + * + * The rest of the base registers are needed for special cases like entry code + * and GCC realigned stacks. + */ +#define ORC_REG_UNDEFINED 0 +#define ORC_REG_PREV_SP 1 +#define ORC_REG_DX 2 +#define ORC_REG_DI 3 +#define ORC_REG_BP 4 +#define ORC_REG_SP 5 +#define ORC_REG_R10 6 +#define ORC_REG_R13 7 +#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_MAX 15 + +/* + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the + * caller's SP right before it made the call). Used for all callable + * functions, i.e. all C code and all callable asm functions. + * + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points + * to a fully populated pt_regs from a syscall, interrupt, or exception. + * + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset + * points to the iret return frame. + * + * The UNWIND_HINT macros are used only for the unwind_hint struct. They + * aren't used in struct orc_entry due to size and complexity constraints. + * Objtool converts them to real types when it converts the hints to orc + * entries. + */ +#define ORC_TYPE_CALL 0 +#define ORC_TYPE_REGS 1 +#define ORC_TYPE_REGS_IRET 2 +#define UNWIND_HINT_TYPE_SAVE 3 +#define UNWIND_HINT_TYPE_RESTORE 4 + +#ifndef __ASSEMBLY__ +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:2; +} __packed; + +/* + * This struct is used by asm and inline asm code to manually annotate the + * location of registers on the stack for the ORC unwinder. + * + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. + */ +struct unwind_hint { + u32 ip; + s16 sp_offset; + u8 sp_reg; + u8 type; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ORC_TYPES_H */ diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index ad54a58d7dda0e82f3bb46f95e6a5f9af8c9a42e..9074b477bff0fad4dfddf71a85b2b51bd0003114 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c @@ -173,6 +173,7 @@ int main(int argc, char **argv) "\t-D PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" "\t-b BAR test (bar number between 0..5)\n" "\t-m MSI test (msi number between 1..32)\n" + "\t-l Legacy IRQ test\n" "\t-r Read buffer test\n" "\t-w Write buffer test\n" "\t-c Copy buffer test\n" diff --git a/tools/perf/Build b/tools/perf/Build index bd8eeb60533cdee3311dd6277b728990e4e70042..b48ca40fccf9640eab3c7b650214ae662370c0cc 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -50,6 +50,6 @@ libperf-y += util/ libperf-y += arch/ libperf-y += ui/ libperf-y += scripts/ -libperf-y += trace/beauty/ +libperf-$(CONFIG_AUDIT) += trace/beauty/ gtk-y += ui/gtk/ diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 098cfb9ca8f0f73374f2ee32fdd6cb55ce32e55f..db11478e30b4a9654874123e4586d17a278e9f44 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -192,7 +192,7 @@ do-install-man: man # $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir); \ # $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) -install-man: check-man-tools man +install-man: check-man-tools man do-install-man ifdef missing_tools DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed) diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt index 4b6cdbf8f935ef993b89a05168019a9d56b795b8..76971d2e416450c24fbb24bb51db584da7661180 100644 --- a/tools/perf/Documentation/intel-pt.txt +++ b/tools/perf/Documentation/intel-pt.txt @@ -104,9 +104,9 @@ system, asynchronous, interrupt, transaction abort, trace begin, trace end, and in transaction, respectively. While it is possible to create scripts to analyze the data, an alternative -approach is available to export the data to a postgresql database. Refer to -script export-to-postgresql.py for more details, and to script -call-graph-from-postgresql.py for an example of using the database. +approach is available to export the data to a sqlite or postgresql database. +Refer to script export-to-sqlite.py or export-to-postgresql.py for more details, +and to script call-graph-from-sql.py for an example of using the database. There is also script intel-pt-events.py which provides an example of how to unpack the raw data for power events and PTWRITE. @@ -873,7 +873,7 @@ amended to take the number of elements as a parameter. $ cat ~/.perfconfig [intel-pt] - mispred-all + mispred-all = on $ perf record -e intel_pt//u ./sort 3000 Bubble sorting array of 3000 elements diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index a89273d8e74417b8d7feb4b96e7fab6a52513339..c635eab6af5409ddb6b19d249084a79aa825acf2 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -43,6 +43,10 @@ OPTIONS --quiet:: Do not show any message. (Suppress -v) +-n:: +--show-nr-samples:: + Show the number of samples for each symbol + -D:: --dump-raw-trace:: Dump raw trace in ASCII. @@ -88,6 +92,8 @@ OPTIONS --asm-raw:: Show raw instruction encoding of assembly instructions. +--show-total-period:: Show a column with the sum of periods. + --source:: Interleave source code with assembly code. Enabled by default, disable with --no-source. diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 058064db39d2d7e5cab506c5cc13911076a69a99..84681007f80f4aae6ec031e416edf1c3e866d304 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -61,6 +61,11 @@ OPTIONS --verbose:: Be more verbose. +--target-ns=PID: + Obtain mount namespace information from the target pid. This is + used when creating a uprobe for a process that resides in a + different mount namespace from the perf(1) utility. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-buildid-list[1] diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt index 73496320fca3f871ac50024aff4a5e1b7def582b..4be08a1e3f8d82e7c0035647ddd8664b23abf356 100644 --- a/tools/perf/Documentation/perf-mem.txt +++ b/tools/perf/Documentation/perf-mem.txt @@ -59,6 +59,10 @@ OPTIONS --ldload:: Specify desired latency for loads event. +-p:: +--phys-data:: + Record/Report sample physical addresses + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-report[1] diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index 165c2b1d43177b7df8870d85d7911a1a615ce7e7..d7e4869905f1d4a1d35501d87c99860bbad60c10 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -130,6 +130,11 @@ OPTIONS --max-probes=NUM:: Set the maximum number of probe points for an event. Default is 128. +--target-ns=PID: + Obtain mount namespace information from the target pid. This is + used when creating a uprobe for a process that resides in a + different mount namespace from the perf(1) utility. + -x:: --exec=PATH:: Specify path to the executable or shared library file for user @@ -264,6 +269,15 @@ Add probes at malloc() function on libc ./perf probe -x /lib/libc.so.6 malloc or ./perf probe /lib/libc.so.6 malloc +Add a uprobe to a target process running in a different mount namespace + + ./perf probe --target-ns -x /lib64/libc.so.6 malloc + +Add a USDT probe to a target process running in a different mount namespace + + ./perf probe --target-ns -x /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/lib/amd64/server/libjvm.so %sdt_hotspot:thread__sleep__end + + SEE ALSO -------- linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1] diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index b0e9e921d534c46d79da49fe0641013a64caebb6..e397453e5a465513af8d84103fd3feccb510d793 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -249,7 +249,10 @@ OPTIONS -d:: --data:: - Record the sample addresses. + Record the sample virtual addresses. + +--phys-data:: + Record the sample physical addresses. -T:: --timestamp:: @@ -332,6 +335,7 @@ following filters are defined: - no_tx: only when the target is not in a hardware transaction - abort_tx: only when the target is a hardware transaction abort - cond: conditional branches + - save_type: save branch type during sampling in case binary is not available later + The option requires at least one branch type among any, any_call, any_ret, ind_call, cond. diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 9fa84617181e47e00a93529b6a91fca3d3fbe9c2..383a98d992ed5570564bf01f90cd9a2ba513e287 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -137,6 +137,7 @@ OPTIONS - mem: type of memory access for the data at the time of the sample - snoop: type of snoop (if any) for the data at the time of the sample - dcacheline: the cacheline the data address is on at the time of the sample + - phys_daddr: physical address of data being executed on at the time of sample And the default sort keys are changed to local_weight, mem, sym, dso, symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'. diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 5ee8796be96ebae4bf3f32a177ae77b1d7c665fc..18dfcfa384542c32d110fe5873c26571d4543019 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff, - callindent, insn, insnlen, synth. + callindent, insn, insnlen, synth, phys_addr. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 698076313606a7e22df2bda7bfa365c42673a32a..c37d61682dfb1771b9b013d4669b59364f979656 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -41,13 +41,13 @@ report:: - a symbolically formed event like 'pmu/param1=0x3,param2/' where param1 and param2 are defined as formats for the PMU in - /sys/bus/event_sources/devices//format/* + /sys/bus/event_source/devices//format/* - a symbolically formed event like 'pmu/config=M,config1=N,config2=K/' where M, N, K are numbers (in decimal, hex, octal format). Acceptable values for each of 'config', 'config1' and 'config2' parameters are defined by corresponding entries in - /sys/bus/event_sources/devices//format/* + /sys/bus/event_source/devices//format/* -i:: --no-inherit:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index e71d63843f45d493611cef226a87915427dfa0c2..d864ea6fd367efb63e1a9411f6e74e8d42ab3428 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -237,6 +237,10 @@ Default is to monitor all CPUS. --hierarchy:: Enable hierarchy output. +--force:: + Don't do ownership validation. + + INTERACTIVE PROMPTING KEYS -------------------------- diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index c1e3288a2dfbcc80100a88cd8286fdc2a707c541..d53bea6bd5710561834eb576fbf81dd1006cee9f 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -37,7 +37,7 @@ OPTIONS --expr:: --event:: List of syscalls and other perf events (tracepoints, HW cache events, - etc) to show. + etc) to show. Globbing is supported, e.g.: "epoll_*", "*msg*", etc. See 'perf list' for a complete list of events. Prefixing with ! shows all syscalls but the ones specified. You may need to escape it. diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index de8b39dda7b828edf2d5acae5bd7ca6dae505369..e90c59c6d8157052341847fd02ad50a38b356a3e 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -398,6 +398,11 @@ struct auxtrace_error_event { char msg[MAX_AUXTRACE_ERROR_MSG]; }; + PERF_RECORD_HEADER_FEATURE = 80, + +Describes a header feature. These are records used in pipe-mode that +contain information that otherwise would be in perf.data file's header. + Event types Define the event attributes with their IDs. @@ -422,8 +427,9 @@ struct perf_pipe_file_header { }; The information about attrs, data, and event_types is instead in the -synthesized events PERF_RECORD_ATTR, PERF_RECORD_HEADER_TRACING_DATA and -PERF_RECORD_HEADER_EVENT_TYPE that are generated by perf record in pipe-mode. +synthesized events PERF_RECORD_ATTR, PERF_RECORD_HEADER_TRACING_DATA, +PERF_RECORD_HEADER_EVENT_TYPE, and PERF_RECORD_HEADER_FEATURE +that are generated by perf record in pipe-mode. References: diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index a29da46d180f8780507938f5183af24e189a1c21..627b7cada1442b65dbbcc600661f35caf8429cdc 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -1,34 +1,8 @@ tools/perf -tools/arch/alpha/include/asm/barrier.h -tools/arch/arm/include/asm/barrier.h -tools/arch/arm64/include/asm/barrier.h -tools/arch/ia64/include/asm/barrier.h -tools/arch/mips/include/asm/barrier.h -tools/arch/powerpc/include/asm/barrier.h -tools/arch/s390/include/asm/barrier.h -tools/arch/sh/include/asm/barrier.h -tools/arch/sparc/include/asm/barrier.h -tools/arch/sparc/include/asm/barrier_32.h -tools/arch/sparc/include/asm/barrier_64.h -tools/arch/tile/include/asm/barrier.h -tools/arch/x86/include/asm/barrier.h -tools/arch/x86/include/asm/cmpxchg.h -tools/arch/x86/include/asm/cpufeatures.h -tools/arch/x86/include/asm/disabled-features.h -tools/arch/x86/include/asm/required-features.h -tools/arch/x86/include/uapi/asm/svm.h -tools/arch/x86/include/uapi/asm/vmx.h -tools/arch/x86/include/uapi/asm/kvm.h -tools/arch/x86/include/uapi/asm/kvm_perf.h -tools/arch/x86/lib/memcpy_64.S -tools/arch/x86/lib/memset_64.S -tools/arch/s390/include/uapi/asm/kvm_perf.h -tools/arch/s390/include/uapi/asm/sie.h -tools/arch/xtensa/include/asm/barrier.h +tools/arch tools/scripts tools/build -tools/arch/x86/include/asm/atomic.h -tools/arch/x86/include/asm/rmwcc.h +tools/include tools/lib/traceevent tools/lib/api tools/lib/bpf @@ -42,52 +16,3 @@ tools/lib/find_bit.c tools/lib/bitmap.c tools/lib/str_error_r.c tools/lib/vsprintf.c -tools/include/asm/alternative-asm.h -tools/include/asm/atomic.h -tools/include/asm/barrier.h -tools/include/asm/bug.h -tools/include/asm-generic/atomic-gcc.h -tools/include/asm-generic/barrier.h -tools/include/asm-generic/bitops/arch_hweight.h -tools/include/asm-generic/bitops/atomic.h -tools/include/asm-generic/bitops/const_hweight.h -tools/include/asm-generic/bitops/__ffs.h -tools/include/asm-generic/bitops/__ffz.h -tools/include/asm-generic/bitops/__fls.h -tools/include/asm-generic/bitops/find.h -tools/include/asm-generic/bitops/fls64.h -tools/include/asm-generic/bitops/fls.h -tools/include/asm-generic/bitops/hweight.h -tools/include/asm-generic/bitops.h -tools/include/linux/atomic.h -tools/include/linux/bitops.h -tools/include/linux/compiler.h -tools/include/linux/compiler-gcc.h -tools/include/linux/coresight-pmu.h -tools/include/linux/bug.h -tools/include/linux/filter.h -tools/include/linux/hash.h -tools/include/linux/kernel.h -tools/include/linux/list.h -tools/include/linux/log2.h -tools/include/uapi/asm-generic/mman-common.h -tools/include/uapi/asm-generic/mman.h -tools/include/uapi/linux/bpf.h -tools/include/uapi/linux/bpf_common.h -tools/include/uapi/linux/fcntl.h -tools/include/uapi/linux/hw_breakpoint.h -tools/include/uapi/linux/mman.h -tools/include/uapi/linux/perf_event.h -tools/include/uapi/linux/stat.h -tools/include/linux/poison.h -tools/include/linux/rbtree.h -tools/include/linux/rbtree_augmented.h -tools/include/linux/refcount.h -tools/include/linux/string.h -tools/include/linux/stringify.h -tools/include/linux/types.h -tools/include/linux/err.h -tools/include/linux/bitmap.h -tools/include/linux/time64.h -tools/arch/*/include/uapi/asm/mman.h -tools/arch/*/include/uapi/asm/perf_regs.h diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index bdf0e87f9b2938c33dc94b0541c8a63d1965cb35..63f534a0902f29e5682570d70751ccb6035d13bb 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -35,7 +35,7 @@ ifeq ($(SRCARCH),x86) ifeq (${IS_64_BIT}, 1) CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S - LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 + LIBUNWIND_LIBS = -lunwind-x86_64 -lunwind -llzma $(call detected,CONFIG_X86_64) else LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind @@ -103,8 +103,12 @@ ifdef LIBDW_DIR LIBDW_CFLAGS := -I$(LIBDW_DIR)/include LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib endif +DWARFLIBS := -ldw +ifeq ($(findstring -static,${LDFLAGS}),-static) + DWARFLIBS += -lelf -lebl -ldl -lz -llzma -lbz2 +endif FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) -FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw +FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) $(DWARFLIBS) # for linking with debug library, run like: # make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/ @@ -144,7 +148,7 @@ ifndef DEBUG endif ifeq ($(DEBUG),0) -ifeq ($(CC), clang) +ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 else CFLAGS += -O6 @@ -180,7 +184,7 @@ ifdef PYTHON_CONFIG PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) - ifeq ($(CC), clang) + ifeq ($(CC_NO_CLANG), 1) PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS)) endif FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) @@ -330,6 +334,11 @@ ifeq ($(feature-sched_getcpu), 1) CFLAGS += -DHAVE_SCHED_GETCPU_SUPPORT endif +ifeq ($(feature-setns), 1) + CFLAGS += -DHAVE_SETNS_SUPPORT + $(call detected,CONFIG_SETNS) +endif + ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT EXTLIBS += -lelf @@ -360,10 +369,6 @@ ifndef NO_LIBELF else CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) - DWARFLIBS := -ldw - ifeq ($(findstring -static,${LDFLAGS}),-static) - DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 - endif EXTLIBS += ${DWARFLIBS} $(call detected,CONFIG_DWARF) endif # PERF_HAVE_DWARF_REGS @@ -500,6 +505,10 @@ ifndef NO_LOCAL_LIBUNWIND EXTLIBS += $(LIBUNWIND_LIBS) LDFLAGS += $(LIBUNWIND_LIBS) endif +ifeq ($(findstring -static,${LDFLAGS}),-static) + # gcc -static links libgcc_eh which contans piece of libunwind + LIBUNWIND_LDFLAGS += -Wl,--allow-multiple-definition +endif ifndef NO_LIBUNWIND CFLAGS += -DHAVE_LIBUNWIND_SUPPORT diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 5008f51a08a2118ca34723a87373acd231afb7c3..91ef44bfaf3e3891cfa22ec1b8f71ba5c2216b5a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -33,6 +33,11 @@ include ../scripts/utilities.mak # # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds. # +# Define EXCLUDE_EXTLIBS=-lmylib to exclude libmylib from the auto-generated +# EXTLIBS. +# +# Define EXTRA_PERFLIBS to pass extra libraries to PERFLIBS. +# # Define NO_DWARF if you do not want debug-info analysis feature at all. # # Define WERROR=0 to disable treating any warnings as errors. @@ -159,8 +164,8 @@ LN = ln -f MKDIR = mkdir FIND = find INSTALL = install -FLEX = flex -BISON = bison +FLEX ?= flex +BISON ?= bison STRIP = strip AWK = awk @@ -235,7 +240,7 @@ endif ifeq ($(FEATURES_DUMP),) FEATURE_DUMP_EXPORT := $(realpath $(OUTPUT)FEATURE-DUMP) else -FEATURE_DUMP_EXPORT := $(FEATURES_DUMP) +FEATURE_DUMP_EXPORT := $(realpath $(FEATURES_DUMP)) endif export prefix bindir sharedir sysconfdir DESTDIR @@ -274,7 +279,13 @@ LIBTRACEEVENT = $(TE_PATH)libtraceevent.a export LIBTRACEEVENT LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list -LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) + +# +# The static build has no dynsym table, so this does not work for +# static build. Looks like linker starts to scream about that now +# (in Fedora 26) so we need to switch it off for static build. +DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) +LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = $(if $(findstring -static,$(LDFLAGS)),,$(DYNAMIC_LIST_LDFLAGS)) LIBAPI = $(API_PATH)libapi.a export LIBAPI @@ -352,7 +363,8 @@ ifdef ASCIIDOC8 export ASCIIDOC8 endif -LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group +EXTLIBS := $(call filter-out,$(EXCLUDE_EXTLIBS),$(EXTLIBS)) +LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group ifeq ($(USE_CLANG), 1) CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema Analysis Parse Serialization @@ -375,6 +387,60 @@ export INSTALL SHELL_PATH SHELL = $(SHELL_PATH) +beauty_outdir := $(OUTPUT)trace/beauty/generated +beauty_ioctl_outdir := $(beauty_outdir)/ioctl +drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c +drm_hdr_dir := $(srctree)/tools/include/uapi/drm +drm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/drm_ioctl.sh + +# Create output directory if not already present +_dummy := $(shell [ -d '$(beauty_ioctl_outdir)' ] || mkdir -p '$(beauty_ioctl_outdir)') + +$(drm_ioctl_array): $(drm_hdr_dir)/drm.h $(drm_hdr_dir)/i915_drm.h $(drm_ioctl_tbl) + $(Q)$(SHELL) '$(drm_ioctl_tbl)' $(drm_hdr_dir) > $@ + +pkey_alloc_access_rights_array := $(beauty_outdir)/pkey_alloc_access_rights_array.c +asm_generic_hdr_dir := $(srctree)/tools/include/uapi/asm-generic/ +pkey_alloc_access_rights_tbl := $(srctree)/tools/perf/trace/beauty/pkey_alloc_access_rights.sh + +$(pkey_alloc_access_rights_array): $(asm_generic_hdr_dir)/mman-common.h $(pkey_alloc_access_rights_tbl) + $(Q)$(SHELL) '$(pkey_alloc_access_rights_tbl)' $(asm_generic_hdr_dir) > $@ + +sndrv_ctl_ioctl_array := $(beauty_ioctl_outdir)/sndrv_ctl_ioctl_array.c +sndrv_ctl_hdr_dir := $(srctree)/tools/include/uapi/sound +sndrv_ctl_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh + +$(sndrv_ctl_ioctl_array): $(sndrv_ctl_hdr_dir)/asound.h $(sndrv_ctl_ioctl_tbl) + $(Q)$(SHELL) '$(sndrv_ctl_ioctl_tbl)' $(sndrv_ctl_hdr_dir) > $@ + +sndrv_pcm_ioctl_array := $(beauty_ioctl_outdir)/sndrv_pcm_ioctl_array.c +sndrv_pcm_hdr_dir := $(srctree)/tools/include/uapi/sound +sndrv_pcm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh + +$(sndrv_pcm_ioctl_array): $(sndrv_pcm_hdr_dir)/asound.h $(sndrv_pcm_ioctl_tbl) + $(Q)$(SHELL) '$(sndrv_pcm_ioctl_tbl)' $(sndrv_pcm_hdr_dir) > $@ + +kvm_ioctl_array := $(beauty_ioctl_outdir)/kvm_ioctl_array.c +kvm_hdr_dir := $(srctree)/tools/include/uapi/linux +kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh + +$(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) + $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@ + +vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c +vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux +vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh + +$(vhost_virtio_ioctl_array): $(vhost_virtio_hdr_dir)/vhost.h $(vhost_virtio_ioctl_tbl) + $(Q)$(SHELL) '$(vhost_virtio_ioctl_tbl)' $(vhost_virtio_hdr_dir) > $@ + +perf_ioctl_array := $(beauty_ioctl_outdir)/perf_ioctl_array.c +perf_hdr_dir := $(srctree)/tools/include/uapi/linux +perf_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/perf_ioctl.sh + +$(perf_ioctl_array): $(perf_hdr_dir)/perf_event.h $(perf_ioctl_tbl) + $(Q)$(SHELL) '$(perf_ioctl_tbl)' $(perf_hdr_dir) > $@ + all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) @@ -469,7 +535,13 @@ endif __build-dir = $(subst $(OUTPUT),,$(dir $@)) build-dir = $(if $(__build-dir),$(__build-dir),.) -prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders +prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioctl_array) \ + $(pkey_alloc_access_rights_array) \ + $(sndrv_pcm_ioctl_array) \ + $(sndrv_ctl_ioctl_array) \ + $(kvm_ioctl_array) \ + $(vhost_virtio_ioctl_array) \ + $(perf_ioctl_array) $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ @@ -512,7 +584,7 @@ $(LIBJVMTI_IN): FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=jvmti obj=jvmti $(OUTPUT)$(LIBJVMTI): $(LIBJVMTI_IN) - $(QUIET_LINK)$(CC) -shared -Wl,-soname -Wl,$(LIBJVMTI) -o $@ $< -lelf -lrt + $(QUIET_LINK)$(CC) -shared -Wl,-soname -Wl,$(LIBJVMTI) -o $@ $< endif $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) @@ -703,7 +775,11 @@ install-tests: all install-gtk $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ - $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr' + $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ + $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ + $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib' install-bin: install-tools install-tests install-traceevent-plugins @@ -734,7 +810,14 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ - $(OUTPUT)pmu-events/pmu-events.c + $(OUTPUT)pmu-events/pmu-events.c \ + $(OUTPUT)$(drm_ioctl_array) \ + $(OUTPUT)$(pkey_alloc_access_rights_array) \ + $(OUTPUT)$(sndrv_ctl_ioctl_array) \ + $(OUTPUT)$(sndrv_pcm_ioctl_array) \ + $(OUTPUT)$(kvm_ioctl_array) \ + $(OUTPUT)$(vhost_virtio_ioctl_array) \ + $(OUTPUT)$(perf_ioctl_array) $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean $(python-clean) diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 7ce3d1a2513378b5e0ec8d01040364d6ddc3b5a6..fbfc055d3f4d5cc9ef5e58ead93b98535640569e 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -266,6 +266,32 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr) return config; } +#ifndef BIT +#define BIT(N) (1UL << (N)) +#endif + +static u64 cs_etmv4_get_config(struct auxtrace_record *itr) +{ + u64 config = 0; + u64 config_opts = 0; + + /* + * The perf event variable config bits represent both + * the command line options and register programming + * bits in ETMv3/PTM. For ETMv4 we must remap options + * to real bits + */ + config_opts = cs_etm_get_config(itr); + if (config_opts & BIT(ETM_OPT_CYCACC)) + config |= BIT(ETM4_CFG_BIT_CYCACC); + if (config_opts & BIT(ETM_OPT_TS)) + config |= BIT(ETM4_CFG_BIT_TS); + if (config_opts & BIT(ETM_OPT_RETSTK)) + config |= BIT(ETM4_CFG_BIT_RETSTK); + + return config; +} + static size_t cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, struct perf_evlist *evlist __maybe_unused) @@ -363,7 +389,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset, magic = __perf_cs_etmv4_magic; /* Get trace configuration register */ info->priv[*offset + CS_ETMV4_TRCCONFIGR] = - cs_etm_get_config(itr); + cs_etmv4_get_config(itr); /* Get traceID from the framework */ info->priv[*offset + CS_ETMV4_TRCTRACEIDR] = coresight_get_trace_id(cpu); diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index bf9a2594572c7ff3e94adfab36dce813476bb6a9..9c4e23d8c8cedbf0c6db4c9c13129b197be7938e 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -126,7 +126,7 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev, struct rb_node *tmp; int i = 0; - map = get_target_map(pev->target, pev->uprobes); + map = get_target_map(pev->target, pev->nsi, pev->uprobes); if (!map || map__load(map) < 0) return; diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile index 6c9211b18ec0960c31fa7486cbc55021abbf72d1..9a628a24c5c92004e1e944c2af47c0d60e1db1e2 100644 --- a/tools/perf/arch/x86/Makefile +++ b/tools/perf/arch/x86/Makefile @@ -20,7 +20,7 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') $(header): $(sys)/syscall_64.tbl $(systbl) @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \ - || echo "Warning: x86_64's syscall_64.tbl differs from kernel" >&2 )) || true + || echo "Warning: Kernel ABI header at 'tools/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@ clean:: diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c index c1625f256df362ab06ab21cc35972bdcca227381..d84b72063a30e33847e28891c16b9158bb0b8406 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -76,3 +76,49 @@ static struct ins x86__instructions[] = { { .name = "xbeginq", .ops = &jump_ops, }, { .name = "retq", .ops = &ret_ops, }, }; + +static bool x86__ins_is_fused(struct arch *arch, const char *ins1, + const char *ins2) +{ + if (arch->family != 6 || arch->model < 0x1e || strstr(ins2, "jmp")) + return false; + + if (arch->model == 0x1e) { + /* Nehalem */ + if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) || + strstr(ins1, "test")) { + return true; + } + } else { + /* Newer platform */ + if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) || + strstr(ins1, "test") || + strstr(ins1, "add") || + strstr(ins1, "sub") || + strstr(ins1, "and") || + strstr(ins1, "inc") || + strstr(ins1, "dec")) { + return true; + } + } + + return false; +} + +static int x86__cpuid_parse(struct arch *arch, char *cpuid) +{ + unsigned int family, model, stepping; + int ret; + + /* + * cpuid = "GenuineIntel,family,model,stepping" + */ + ret = sscanf(cpuid, "%*[^,],%u,%u,%u", &family, &model, &stepping); + if (ret == 3) { + arch->family = family; + arch->model = model; + return 0; + } + + return -1; +} diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h index b48de2f5813c60ac037d717a05ee408581e8dec2..4e0b806a7a0fe0cc5a1881085e251775afb7d782 100644 --- a/tools/perf/arch/x86/include/arch-tests.h +++ b/tools/perf/arch/x86/include/arch-tests.h @@ -1,11 +1,14 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H +#include +struct test; + /* Tests */ -int test__rdpmc(int subtest); -int test__perf_time_to_tsc(int subtest); -int test__insn_x86(int subtest); -int test__intel_cqm_count_nmi_context(int subtest); +int test__rdpmc(struct test *test __maybe_unused, int subtest); +int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest); +int test__insn_x86(struct test *test __maybe_unused, int subtest); +int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest); #ifdef HAVE_DWARF_UNWIND_SUPPORT struct thread; diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c index 08d9b2bc185ca039855266e5608794dad7dbfdb0..b3860586a0c2d949ba5d57b76cfd78ddeaa170d4 100644 --- a/tools/perf/arch/x86/tests/insn-x86.c +++ b/tools/perf/arch/x86/tests/insn-x86.c @@ -171,7 +171,7 @@ static int test_data_set(struct test_data *dat_set, int x86_64) * verbose (-v) option to see all the instructions and whether or not they * decoded successfuly. */ -int test__insn_x86(int subtest __maybe_unused) +int test__insn_x86(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = 0; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index f9713a71d77e8be3d7766ba91cf69556d401bedc..57f86b6e7d6f52f2743ab26fef4869883da1799d 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -36,7 +36,7 @@ static pid_t spawn(void) * the last read counter value to avoid triggering a WARN_ON_ONCE() in * smp_call_function_many() caused by sending IPIs from NMI context. */ -int test__intel_cqm_count_nmi_context(int subtest __maybe_unused) +int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index e3ae9cff2b6716617088c2baf3d962370df49b81..5dd7efb192ce962b3b56995aa707c429f5d01c71 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -37,7 +37,7 @@ * %0 is returned, otherwise %-1 is returned. If TSC conversion is not * supported then then the test passes but " (not supported)" is printed. */ -int test__perf_time_to_tsc(int subtest __maybe_unused) +int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 500cf96db9790b66dfc54a726316a83583c4a24a..17fec30a0b31af067c99817b02394e85113aca82 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -154,7 +154,7 @@ static int __test__rdpmc(void) return 0; } -int test__rdpmc(int subtest __maybe_unused) +int test__rdpmc(struct test *test __maybe_unused, int subtest __maybe_unused) { int status = 0; int wret = 0; diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 9535be57033f0c02b12d4471b2b61a272d630de0..db0ba8caf5a2475485f068b49cafaea87c29118d 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -701,6 +701,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, perf_evsel__set_sample_bit(switch_evsel, TID); perf_evsel__set_sample_bit(switch_evsel, TIME); perf_evsel__set_sample_bit(switch_evsel, CPU); + perf_evsel__reset_sample_bit(switch_evsel, BRANCH_STACK); opts->record_switch_events = false; ptr->have_sched_switch = 3; @@ -752,6 +753,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, tracking_evsel->attr.freq = 0; tracking_evsel->attr.sample_period = 1; + tracking_evsel->no_aux_samples = true; if (need_immediate) tracking_evsel->immediate = true; @@ -761,6 +763,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, /* And the CPU for switch events */ perf_evsel__set_sample_bit(tracking_evsel, CPU); } + perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK); } /* diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 7a5dc7e5c577270edaa3a36f7a916d7f3cc5a182..c38373195c4a82fd70c89efbb4ecf167f11544a4 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -177,14 +177,11 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, */ process_branch_stack(sample->branch_stack, al, sample); - sample->period = 1; - sample->weight = 1; - he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true); if (he == NULL) return -ENOMEM; - ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + ret = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); hists__inc_nr_samples(hists, true); return ret; } @@ -397,6 +394,8 @@ int cmd_annotate(int argc, const char **argv) .namespaces = perf_event__process_namespaces, .attr = perf_event__process_attr, .build_id = perf_event__process_build_id, + .tracing_data = perf_event__process_tracing_data, + .feature = perf_event__process_feature, .ordered_events = true, .ordering_requires_timestamps = true, }, @@ -404,7 +403,7 @@ int cmd_annotate(int argc, const char **argv) struct perf_data_file file = { .mode = PERF_DATA_MODE_READ, }; - const struct option options[] = { + struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", @@ -446,13 +445,20 @@ int cmd_annotate(int argc, const char **argv) "Show event group information together"), OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, "Show a column with the sum of periods"), + OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, + "Show a column with the number of samples"), OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode", "'always' (default), 'never' or 'auto' only applicable to --stdio mode", stdio__config_color, "always"), OPT_END() }; - int ret = hists__init(); + int ret; + + set_option_flag(options, 0, "show-total-period", PARSE_OPT_EXCLUSIVE); + set_option_flag(options, 0, "show-nr-samples", PARSE_OPT_EXCLUSIVE); + + ret = hists__init(); if (ret < 0) return ret; @@ -468,6 +474,11 @@ int cmd_annotate(int argc, const char **argv) annotate.sym_hist_filter = argv[0]; } + if (symbol_conf.show_nr_samples && annotate.use_gtk) { + pr_err("--show-nr-samples is not available in --gtk mode at this time\n"); + return ret; + } + if (quiet) perf_quiet_option(); diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 9eba7f1add1f9706f2b8153fb33f3574b362d5ee..e3eb6240ced0903799d3add8998111dab488205a 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -14,6 +14,7 @@ #include #include "builtin.h" #include "perf.h" +#include "namespaces.h" #include "util/cache.h" #include "util/debug.h" #include "util/header.h" @@ -165,33 +166,41 @@ static int build_id_cache__add_kcore(const char *filename, bool force) return 0; } -static int build_id_cache__add_file(const char *filename) +static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi) { char sbuild_id[SBUILD_ID_SIZE]; u8 build_id[BUILD_ID_SIZE]; int err; + struct nscookie nsc; - if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { + nsinfo__mountns_enter(nsi, &nsc); + err = filename__read_build_id(filename, &build_id, sizeof(build_id)); + nsinfo__mountns_exit(&nsc); + if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__add_s(sbuild_id, filename, + err = build_id_cache__add_s(sbuild_id, filename, nsi, false, false); pr_debug("Adding %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); return err; } -static int build_id_cache__remove_file(const char *filename) +static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; + struct nscookie nsc; int err; - if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { + nsinfo__mountns_enter(nsi, &nsc); + err = filename__read_build_id(filename, &build_id, sizeof(build_id)); + nsinfo__mountns_exit(&nsc); + if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } @@ -204,13 +213,13 @@ static int build_id_cache__remove_file(const char *filename) return err; } -static int build_id_cache__purge_path(const char *pathname) +static int build_id_cache__purge_path(const char *pathname, struct nsinfo *nsi) { struct strlist *list; struct str_node *pos; int err; - err = build_id_cache__list_build_ids(pathname, &list); + err = build_id_cache__list_build_ids(pathname, nsi, &list); if (err) goto out; @@ -234,7 +243,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) char filename[PATH_MAX]; u8 build_id[BUILD_ID_SIZE]; - if (dso__build_id_filename(dso, filename, sizeof(filename)) && + if (dso__build_id_filename(dso, filename, sizeof(filename), false) && filename__read_build_id(filename, build_id, sizeof(build_id)) != sizeof(build_id)) { if (errno == ENOENT) @@ -256,24 +265,30 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *f return 0; } -static int build_id_cache__update_file(const char *filename) +static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; + struct nscookie nsc; - int err = 0; + int err; - if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { + nsinfo__mountns_enter(nsi, &nsc); + err = filename__read_build_id(filename, &build_id, sizeof(build_id)); + nsinfo__mountns_exit(&nsc); + if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } + err = 0; build_id__sprintf(build_id, sizeof(build_id), sbuild_id); if (build_id_cache__cached(sbuild_id)) err = build_id_cache__remove_s(sbuild_id); if (!err) - err = build_id_cache__add_s(sbuild_id, filename, false, false); + err = build_id_cache__add_s(sbuild_id, filename, nsi, false, + false); pr_debug("Updating %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); @@ -286,6 +301,7 @@ int cmd_buildid_cache(int argc, const char **argv) struct strlist *list; struct str_node *pos; int ret = 0; + int ns_id = -1; bool force = false; char const *add_name_list_str = NULL, *remove_name_list_str = NULL, @@ -299,6 +315,7 @@ int cmd_buildid_cache(int argc, const char **argv) .mode = PERF_DATA_MODE_READ, }; struct perf_session *session = NULL; + struct nsinfo *nsi = NULL; const struct option buildid_cache_options[] = { OPT_STRING('a', "add", &add_name_list_str, @@ -315,6 +332,7 @@ int cmd_buildid_cache(int argc, const char **argv) OPT_STRING('u', "update", &update_name_list_str, "file list", "file(s) to update"), OPT_INCR('v', "verbose", &verbose, "be more verbose"), + OPT_INTEGER(0, "target-ns", &ns_id, "target pid for namespace context"), OPT_END() }; const char * const buildid_cache_usage[] = { @@ -330,6 +348,9 @@ int cmd_buildid_cache(int argc, const char **argv) !missing_filename && !update_name_list_str)) usage_with_options(buildid_cache_usage, buildid_cache_options); + if (ns_id > 0) + nsi = nsinfo__new(ns_id); + if (missing_filename) { file.path = missing_filename; file.force = force; @@ -348,7 +369,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(add_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__add_file(pos->s)) { + if (build_id_cache__add_file(pos->s, nsi)) { if (errno == EEXIST) { pr_debug("%s already in the cache\n", pos->s); @@ -366,7 +387,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(remove_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__remove_file(pos->s)) { + if (build_id_cache__remove_file(pos->s, nsi)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -384,7 +405,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(purge_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__purge_path(pos->s)) { + if (build_id_cache__purge_path(pos->s, nsi)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -405,7 +426,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(update_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__update_file(pos->s)) { + if (build_id_cache__update_file(pos->s, nsi)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -424,6 +445,7 @@ int cmd_buildid_cache(int argc, const char **argv) out: perf_session__delete(session); + nsinfo__zput(nsi); return ret; } diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index ece45582a48d04fcd64a05424d9128c12ba166a6..a1d82e33282c806e2763e4e6b6368f3ed6290f74 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -13,6 +13,7 @@ #include "util/util.h" #include "util/debug.h" #include "util/config.h" +#include static bool use_system_config, use_user_config; @@ -58,7 +59,7 @@ static int set_config(struct perf_config_set *set, const char *file_name, fprintf(fp, "[%s]\n", section->name); perf_config_items__for_each_entry(§ion->items, item) { - if (!use_system_config && section->from_system_config) + if (!use_system_config && item->from_system_config) continue; if (item->value) fprintf(fp, "\t%s = %s\n", @@ -79,7 +80,7 @@ static int show_spec_config(struct perf_config_set *set, const char *var) return -1; perf_config_items__for_each_entry(&set->sections, section) { - if (prefixcmp(var, section->name) != 0) + if (!strstarts(var, section->name)) continue; perf_config_items__for_each_entry(§ion->items, item) { diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index 0adb5f82335ad22534a6f7d91e4fc3b34086bb47..46cd8490baf452cc70739c605e4cdab79d9060be 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -69,7 +69,7 @@ static int cmd_data_convert(int argc, const char **argv) }; #ifndef HAVE_LIBBABELTRACE_SUPPORT - pr_err("No conversion support compiled in.\n"); + pr_err("No conversion support compiled in. perf should be compiled with environment variables LIBBABELTRACE=1 and LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n"); return -1; #endif diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index dd26c62c9893dcaebdbaf4b3193bb0684016d5e5..25a42acabee18ff5782ba4f3f7962ef5b914a3d0 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -381,7 +381,7 @@ static int perf_ftrace_config(const char *var, const char *value, void *cb) { struct perf_ftrace *ftrace = cb; - if (prefixcmp(var, "ftrace.")) + if (!strstarts(var, "ftrace.")) return 0; if (strcmp(var, "ftrace.tracer")) diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 530a7f2fa0f3e5326e9d7ea5886f97411046417f..dbe4e4153bcfb6dc6e4a348cfd0b9ded44188f99 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -90,7 +90,7 @@ static int check_emacsclient_version(void) */ finish_command(&ec_process); - if (prefixcmp(buffer.buf, "emacsclient")) { + if (!strstarts(buffer.buf, "emacsclient")) { fprintf(stderr, "Failed to parse emacsclient version.\n"); goto out; } @@ -283,7 +283,7 @@ static int perf_help_config(const char *var, const char *value, void *cb) add_man_viewer(value); return 0; } - if (!prefixcmp(var, "man.")) + if (!strstarts(var, "man.")) return add_man_viewer_info(var, value); return 0; @@ -313,7 +313,7 @@ static const char *cmd_to_page(const char *perf_cmd) if (!perf_cmd) return "perf"; - else if (!prefixcmp(perf_cmd, "perf")) + else if (!strstarts(perf_cmd, "perf")) return perf_cmd; return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ea8db38eedd10a987534da2c81a1ca83cbb2109f..2b8032908fb2424ff10a74a4ac98d1f80f3529a3 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -770,6 +770,7 @@ int cmd_inject(int argc, const char **argv) .finished_round = perf_event__repipe_oe_synth, .build_id = perf_event__repipe_op2_synth, .id_index = perf_event__repipe_op2_synth, + .feature = perf_event__repipe_op2_synth, }, .input_name = "-", .samples = LIST_HEAD_INIT(inject.samples), diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index a1497c516d85aaabc9cd6de476268f7fc7a4bdca..24ee68ecdd427b5c4a398a96c286006c56a04810 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -627,7 +627,6 @@ static const struct { { "GFP_HIGHUSER_MOVABLE", "HUM" }, { "GFP_HIGHUSER", "HU" }, { "GFP_USER", "U" }, - { "GFP_TEMPORARY", "TMP" }, { "GFP_KERNEL_ACCOUNT", "KAC" }, { "GFP_KERNEL", "K" }, { "GFP_NOFS", "NF" }, diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index e001c02907937792d373f5245be0e6489b3e5210..0f15634ef82cc003a203065f414e180a04136b26 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -23,6 +23,7 @@ struct perf_mem { bool hide_unresolved; bool dump_raw; bool force; + bool phys_addr; int operation; const char *cpu_list; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); @@ -101,6 +102,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) rec_argv[i++] = "-d"; + if (mem->phys_addr) + rec_argv[i++] = "--phys-data"; + for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { if (!perf_mem_events[j].record) continue; @@ -161,30 +165,60 @@ dump_raw_samples(struct perf_tool *tool, if (al.map != NULL) al.map->dso->hit = 1; - if (symbol_conf.field_sep) { - fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 - "%s0x%"PRIx64"%s%s:%s\n"; + if (mem->phys_addr) { + if (symbol_conf.field_sep) { + fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%016"PRIx64 + "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n"; + } else { + fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 + "%s0x%016"PRIx64"%s%5"PRIu64"%s0x%06"PRIx64 + "%s%s:%s\n"; + symbol_conf.field_sep = " "; + } + + printf(fmt, + sample->pid, + symbol_conf.field_sep, + sample->tid, + symbol_conf.field_sep, + sample->ip, + symbol_conf.field_sep, + sample->addr, + symbol_conf.field_sep, + sample->phys_addr, + symbol_conf.field_sep, + sample->weight, + symbol_conf.field_sep, + sample->data_src, + symbol_conf.field_sep, + al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + al.sym ? al.sym->name : "???"); } else { - fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 - "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n"; - symbol_conf.field_sep = " "; - } + if (symbol_conf.field_sep) { + fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 + "%s0x%"PRIx64"%s%s:%s\n"; + } else { + fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 + "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n"; + symbol_conf.field_sep = " "; + } - printf(fmt, - sample->pid, - symbol_conf.field_sep, - sample->tid, - symbol_conf.field_sep, - sample->ip, - symbol_conf.field_sep, - sample->addr, - symbol_conf.field_sep, - sample->weight, - symbol_conf.field_sep, - sample->data_src, - symbol_conf.field_sep, - al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", - al.sym ? al.sym->name : "???"); + printf(fmt, + sample->pid, + symbol_conf.field_sep, + sample->tid, + symbol_conf.field_sep, + sample->ip, + symbol_conf.field_sep, + sample->addr, + symbol_conf.field_sep, + sample->weight, + symbol_conf.field_sep, + sample->data_src, + symbol_conf.field_sep, + al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + al.sym ? al.sym->name : "???"); + } out_put: addr_location__put(&al); return 0; @@ -224,7 +258,10 @@ static int report_raw_events(struct perf_mem *mem) if (ret < 0) goto out_delete; - printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); + if (mem->phys_addr) + printf("# PID, TID, IP, ADDR, PHYS ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); + else + printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); ret = perf_session__process_events(session); @@ -254,9 +291,16 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem) * there is no weight (cost) associated with stores, so don't print * the column */ - if (!(mem->operation & MEM_OPERATION_LOAD)) - rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," - "dso_daddr,tlb,locked"; + if (!(mem->operation & MEM_OPERATION_LOAD)) { + if (mem->phys_addr) + rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," + "dso_daddr,tlb,locked,phys_daddr"; + else + rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," + "dso_daddr,tlb,locked"; + } else if (mem->phys_addr) + rep_argv[i++] = "--sort=local_weight,mem,sym,dso,symbol_daddr," + "dso_daddr,snoop,tlb,locked,phys_daddr"; for (j = 1; j < argc; j++, i++) rep_argv[i] = argv[j]; @@ -373,6 +417,7 @@ int cmd_mem(int argc, const char **argv) "separator for columns, no spaces will be added" " between columns '.' is reserved."), OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"), + OPT_BOOLEAN('p', "phys-data", &mem.phys_addr, "Record/Report sample physical addresses"), OPT_END() }; const char *const mem_subcommands[] = { "record", "report", NULL }; diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index cf9f9e9c2fc00e81c88c43b53da36ace0d9efd5c..c0065923a525fe474d2c28f94ee2042b64d3a080 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -58,6 +58,7 @@ static struct { struct line_range line_range; char *target; struct strfilter *filter; + struct nsinfo *nsi; } params; /* Parse an event definition. Note that any error must die. */ @@ -80,6 +81,9 @@ static int parse_probe_event(const char *str) params.target_used = true; } + if (params.nsi) + pev->nsi = nsinfo__get(params.nsi); + /* Parse a perf-probe command into event */ ret = parse_perf_probe_command(str, pev); pr_debug("%d arguments\n", pev->nargs); @@ -189,7 +193,7 @@ static int opt_set_target(const struct option *opt, const char *str, /* Expand given path to absolute path, except for modulename */ if (params.uprobes || strchr(str, '/')) { - tmp = realpath(str, NULL); + tmp = nsinfo__realpath(str, params.nsi); if (!tmp) { pr_warning("Failed to get the absolute path of %s: %m\n", str); return ret; @@ -208,6 +212,34 @@ static int opt_set_target(const struct option *opt, const char *str, return ret; } +static int opt_set_target_ns(const struct option *opt __maybe_unused, + const char *str, int unset __maybe_unused) +{ + int ret = -ENOENT; + pid_t ns_pid; + struct nsinfo *nsip; + + if (str) { + errno = 0; + ns_pid = (pid_t)strtol(str, NULL, 10); + if (errno != 0) { + ret = -errno; + pr_warning("Failed to parse %s as a pid: %s\n", str, + strerror(errno)); + return ret; + } + nsip = nsinfo__new(ns_pid); + if (nsip && nsip->need_setns) + params.nsi = nsinfo__get(nsip); + nsinfo__put(nsip); + + ret = 0; + } + + return ret; +} + + /* Command option callbacks */ #ifdef HAVE_DWARF_SUPPORT @@ -299,6 +331,7 @@ static void cleanup_params(void) line_range__clear(¶ms.line_range); free(params.target); strfilter__delete(params.filter); + nsinfo__put(params.nsi); memset(¶ms, 0, sizeof(params)); } @@ -383,7 +416,7 @@ static int del_perf_probe_caches(struct strfilter *filter) } strlist__for_each_entry(nd, bidlist) { - cache = probe_cache__new(nd->s); + cache = probe_cache__new(nd->s, NULL); if (!cache) continue; if (probe_cache__filter_purge(cache, filter) < 0 || @@ -554,6 +587,8 @@ __cmd_probe(int argc, const char **argv) OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"), OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", "Look for files with symbols relative to this directory"), + OPT_CALLBACK(0, "target-ns", NULL, "pid", + "target pid for namespace contexts", opt_set_target_ns), OPT_END() }; int ret; @@ -634,15 +669,15 @@ __cmd_probe(int argc, const char **argv) pr_err_with_code(" Error: Failed to show event list.", ret); return ret; case 'F': - ret = show_available_funcs(params.target, params.filter, - params.uprobes); + ret = show_available_funcs(params.target, params.nsi, + params.filter, params.uprobes); if (ret < 0) pr_err_with_code(" Error: Failed to show functions.", ret); return ret; #ifdef HAVE_DWARF_SUPPORT case 'L': ret = show_line_range(¶ms.line_range, params.target, - params.uprobes); + params.nsi, params.uprobes); if (ret < 0) pr_err_with_code(" Error: Failed to show lines.", ret); return ret; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 17a14bcce34accf2ce1cf9a466cee97cf8b72b36..56f8142ff97f1b6a1a7bb9433c1967f758d47916 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -799,6 +799,13 @@ static int record__synthesize(struct record *rec, bool tail) return 0; if (file->is_pipe) { + err = perf_event__synthesize_features( + tool, session, rec->evlist, process_synthesized_event); + if (err < 0) { + pr_err("Couldn't synthesize features.\n"); + return err; + } + err = perf_event__synthesize_attrs(tool, session, process_synthesized_event); if (err < 0) { @@ -1597,6 +1604,8 @@ static struct option __record_options[] = { OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, "per thread counts"), OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), + OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr, + "Record the sample physical addresses"), OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"), OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, &record.opts.sample_time_set, @@ -1821,7 +1830,7 @@ int cmd_record(int argc, const char **argv) record.opts.tail_synthesize = true; if (rec->evlist->nr_entries == 0 && - perf_evlist__add_default(rec->evlist) < 0) { + __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) { pr_err("Not enough memory for event selector list\n"); goto out; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 79a33eb1a10d6b2ec69d1928525b88dd15aff9c9..f9dff652dcbdb01854ad8478c2218acc5caaf2ae 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -38,6 +38,7 @@ #include "util/time-utils.h" #include "util/auxtrace.h" #include "util/units.h" +#include "util/branch.h" #include #include @@ -73,6 +74,7 @@ struct report { u64 queue_size; int socket_filter; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); + struct branch_type_stat brtype_stat; }; static int report__config(const char *var, const char *value, void *cb) @@ -113,43 +115,60 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter, struct report *rep = arg; struct hist_entry *he = iter->he; struct perf_evsel *evsel = iter->evsel; + struct perf_sample *sample = iter->sample; struct mem_info *mi; struct branch_info *bi; if (!ui__has_annotation()) return 0; - hist__account_cycles(iter->sample->branch_stack, al, iter->sample, + hist__account_cycles(sample->branch_stack, al, sample, rep->nonany_branch_mode); if (sort__mode == SORT_MODE__BRANCH) { bi = he->branch_info; - err = addr_map_symbol__inc_samples(&bi->from, evsel->idx); + err = addr_map_symbol__inc_samples(&bi->from, sample, evsel->idx); if (err) goto out; - err = addr_map_symbol__inc_samples(&bi->to, evsel->idx); + err = addr_map_symbol__inc_samples(&bi->to, sample, evsel->idx); } else if (rep->mem_mode) { mi = he->mem_info; - err = addr_map_symbol__inc_samples(&mi->daddr, evsel->idx); + err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel->idx); if (err) goto out; - err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + err = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); } else if (symbol_conf.cumulate_callchain) { if (single) - err = hist_entry__inc_addr_samples(he, evsel->idx, + err = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); } else { - err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + err = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); } out: return err; } +static int hist_iter__branch_callback(struct hist_entry_iter *iter, + struct addr_location *al __maybe_unused, + bool single __maybe_unused, + void *arg) +{ + struct hist_entry *he = iter->he; + struct report *rep = arg; + struct branch_info *bi; + + bi = he->branch_info; + branch_type_count(&rep->brtype_stat, &bi->flags, + bi->from.addr, bi->to.addr); + + return 0; +} + static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -188,6 +207,8 @@ static int process_sample_event(struct perf_tool *tool, */ if (!sample->branch_stack) goto out_put; + + iter.add_entry_cb = hist_iter__branch_callback; iter.ops = &hist_iter_branch; } else if (rep->mem_mode) { iter.ops = &hist_iter_mem; @@ -220,7 +241,7 @@ static int process_read_event(struct perf_tool *tool, const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; int err = perf_read_values_add_value(&rep->show_threads_values, event->read.pid, event->read.tid, - event->read.id, + evsel->idx, name, event->read.value); @@ -228,10 +249,6 @@ static int process_read_event(struct perf_tool *tool, return err; } - dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, - evsel ? perf_evsel__name(evsel) : "FAIL", - event->read.value); - return 0; } @@ -258,10 +275,11 @@ static int report__setup_sample_type(struct report *rep) "'perf record' without -g?\n"); return -EINVAL; } - if (symbol_conf.use_callchain) { - ui__error("Selected -g or --branch-history but no " - "callchain data. Did\n" - "you call 'perf record' without -g?\n"); + if (symbol_conf.use_callchain && + !symbol_conf.show_branchflag_count) { + ui__error("Selected -g or --branch-history.\n" + "But no callchain or branch data.\n" + "Did you call 'perf record' without -g or -b?\n"); return -1; } } else if (!callchain_param.enabled && @@ -396,7 +414,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, hists__fprintf_nr_sample_events(hists, rep, evname, stdout); hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout, - symbol_conf.use_callchain); + symbol_conf.use_callchain || + symbol_conf.show_branchflag_count); fprintf(stdout, "\n\n"); } @@ -410,6 +429,9 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, perf_read_values_destroy(&rep->show_threads_values); } + if (sort__mode == SORT_MODE__BRANCH) + branch_type_stat_display(stdout, &rep->brtype_stat); + return 0; } @@ -718,6 +740,7 @@ int cmd_report(int argc, const char **argv) .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, .auxtrace = perf_event__process_auxtrace, + .feature = perf_event__process_feature, .ordered_events = true, .ordering_requires_timestamps = true, }, @@ -943,6 +966,8 @@ int cmd_report(int argc, const char **argv) if (has_br_stack && branch_call_mode) symbol_conf.show_branchflag_count = true; + memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat)); + /* * Branch mode is a tristate: * -1 means default, so decide based on the file having branch data. @@ -988,6 +1013,10 @@ int cmd_report(int argc, const char **argv) /* Force tty output for header output and per-thread stat. */ if (report.header || report.header_only || report.show_threads) use_browser = 0; + if (report.header || report.header_only) + report.tool.show_feat_hdr = SHOW_FEAT_HEADER; + if (report.show_full_info) + report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO; if (strcmp(input_name, "-") != 0) setup_browser(true); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 83cdc0a61fd6fc38813d8bac07894a4190655438..3d4c3b5e186832d82336ae346865f697564253c2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -87,6 +87,7 @@ enum perf_output_field { PERF_OUTPUT_BRSTACKINSN = 1U << 23, PERF_OUTPUT_BRSTACKOFF = 1U << 24, PERF_OUTPUT_SYNTH = 1U << 25, + PERF_OUTPUT_PHYS_ADDR = 1U << 26, }; struct output_option { @@ -119,6 +120,7 @@ struct output_option { {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, {.str = "synth", .field = PERF_OUTPUT_SYNTH}, + {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, }; enum { @@ -175,7 +177,8 @@ static struct { PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR | - PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT, + PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT | + PERF_OUTPUT_PHYS_ADDR, .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, }, @@ -382,6 +385,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, PERF_OUTPUT_IREGS)) return -EINVAL; + if (PRINT_FIELD(PHYS_ADDR) && + perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", + PERF_OUTPUT_PHYS_ADDR)) + return -EINVAL; + return 0; } @@ -1446,6 +1454,9 @@ static void process_event(struct perf_script *script, if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) print_sample_bpf_output(sample); print_insn(sample, attr, thread, machine); + + if (PRINT_FIELD(PHYS_ADDR)) + printf("%16" PRIx64, sample->phys_addr); printf("\n"); } @@ -2199,16 +2210,11 @@ static struct script_desc *script_desc__findnew(const char *name) s = script_desc__new(name); if (!s) - goto out_delete_desc; + return NULL; script_desc__add(s); return s; - -out_delete_desc: - script_desc__delete(s); - - return NULL; } static const char *ends_with(const char *str, const char *suffix) @@ -2682,6 +2688,7 @@ int cmd_script(int argc, const char **argv) .attr = process_attr, .event_update = perf_event__process_event_update, .tracing_data = perf_event__process_tracing_data, + .feature = perf_event__process_feature, .build_id = perf_event__process_build_id, .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, @@ -2733,7 +2740,7 @@ int cmd_script(int argc, const char **argv) "Valid types: hw,sw,trace,raw,synth. " "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "addr,symoff,period,iregs,brstack,brstacksym,flags," - "bpf-output,callindent,insn,insnlen,brstackinsn,synth", + "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", parse_output_fields), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), @@ -2972,10 +2979,13 @@ int cmd_script(int argc, const char **argv) return -1; if (header || header_only) { + script.tool.show_feat_hdr = SHOW_FEAT_HEADER; perf_session__fprintf_info(session, stdout, show_full_info); if (header_only) goto out_delete; } + if (show_full_info) + script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO; if (symbol__init(&session->header.env) < 0) goto out_delete; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 48ac53b199fcb978be4b72f2c585d92cbc238421..69523ed55894338cb202804db6ffbf202410b74f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -213,10 +213,20 @@ static void perf_stat__reset_stats(void) static int create_perf_stat_counter(struct perf_evsel *evsel) { struct perf_event_attr *attr = &evsel->attr; + struct perf_evsel *leader = evsel->leader; - if (stat_config.scale) + if (stat_config.scale) { attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; + } + + /* + * The event is part of non trivial group, let's enable + * the group read (for leader) and ID retrieval for all + * members. + */ + if (leader->nr_members > 1) + attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP; attr->inherit = !no_inherit; @@ -333,13 +343,21 @@ static int read_counter(struct perf_evsel *counter) struct perf_counts_values *count; count = perf_counts(counter->counts, cpu, thread); - if (perf_evsel__read(counter, cpu, thread, count)) { + + /* + * The leader's group read loads data into its group members + * (via perf_evsel__read_counter) and sets threir count->loaded. + */ + if (!count->loaded && + perf_evsel__read_counter(counter, cpu, thread)) { counter->counts->scaled = -1; perf_counts(counter->counts, cpu, thread)->ena = 0; perf_counts(counter->counts, cpu, thread)->run = 0; return -1; } + count->loaded = false; + if (STAT_RECORD) { if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { pr_err("failed to write stat event\n"); @@ -559,6 +577,11 @@ static int store_counter_ids(struct perf_evsel *counter) return __store_counter_ids(counter, cpus, threads); } +static bool perf_evsel__should_store_id(struct perf_evsel *counter) +{ + return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID; +} + static int __run_perf_stat(int argc, const char **argv) { int interval = stat_config.interval; @@ -631,7 +654,8 @@ static int __run_perf_stat(int argc, const char **argv) if (l > unit_width) unit_width = l; - if (STAT_RECORD && store_counter_ids(counter)) + if (perf_evsel__should_store_id(counter) && + store_counter_ids(counter)) return -1; } @@ -683,7 +707,7 @@ static int __run_perf_stat(int argc, const char **argv) process_interval(); } } - wait(&status); + waitpid(child_pid, &status, 0); if (workload_exec_errno) { const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); @@ -1233,7 +1257,7 @@ static bool collect_data(struct perf_evsel *counter, if (counter->merged_stat) return false; cb(counter, data, true); - if (!no_merge) + if (!no_merge && counter->auto_merge_stats) collect_all_aliases(counter, cb, data); return true; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6052376634c058e735de5c398dd716b1317f48af..ee954bde7e3e800d308a41af7d70acc333802b67 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -134,7 +134,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) return err; } - err = symbol__disassemble(sym, map, NULL, 0, NULL); + err = symbol__disassemble(sym, map, NULL, 0, NULL, NULL); if (err == 0) { out_assign: top->sym_filter_entry = he; @@ -183,6 +183,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, + struct perf_sample *sample, int counter, u64 ip) { struct annotation *notes; @@ -199,7 +200,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, if (pthread_mutex_trylock(¬es->lock)) return; - err = hist_entry__inc_addr_samples(he, counter, ip); + err = hist_entry__inc_addr_samples(he, sample, counter, ip); pthread_mutex_unlock(¬es->lock); @@ -586,6 +587,13 @@ static void *display_thread_tui(void *arg) .refresh = top->delay_secs, }; + /* In order to read symbols from other namespaces perf to needs to call + * setns(2). This isn't permitted if the struct_fs has multiple users. + * unshare(2) the fs so that we may continue to setns into namespaces + * that we're observing. + */ + unshare(CLONE_FS); + perf_top__sort_new_samples(top); /* @@ -627,6 +635,13 @@ static void *display_thread(void *arg) struct perf_top *top = arg; int delay_msecs, c; + /* In order to read symbols from other namespaces perf to needs to call + * setns(2). This isn't permitted if the struct_fs has multiple users. + * unshare(2) the fs so that we may continue to setns into namespaces + * that we're observing. + */ + unshare(CLONE_FS); + display_setup_sig(); pthread__unblock_sigwinch(); repeat: @@ -671,7 +686,7 @@ static int hist_iter__top_callback(struct hist_entry_iter *iter, struct perf_evsel *evsel = iter->evsel; if (perf_hpp_list.sym && single) - perf_top__record_precise_ip(top, he, evsel->idx, al->addr); + perf_top__record_precise_ip(top, he, iter->sample, evsel->idx, al->addr); hist__account_cycles(iter->sample->branch_stack, al, iter->sample, !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY)); @@ -1205,6 +1220,7 @@ int cmd_top(int argc, const char **argv) "Show raw trace event output (do not use print fmt or plugins)"), OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, "Show entries in a hierarchy"), + OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"), OPT_END() }; const char * const top_usage[] = { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4b2a5d2981970baf86e4e458ef4ced256fc98c0e..771ddab94bb04746786c2b52389942f1455da48b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -64,6 +64,10 @@ # define O_CLOEXEC 02000000 #endif +#ifndef F_LINUX_SPECIFIC_BASE +# define F_LINUX_SPECIFIC_BASE 1024 +#endif + struct trace { struct perf_tool tool; struct syscalltbl *sctbl; @@ -279,34 +283,21 @@ static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void ({ struct syscall_tp *fields = evsel->priv; \ fields->name.pointer(&fields->name, sample); }) -struct strarray { - int offset; - int nr_entries; - const char **entries; -}; +size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val) +{ + int idx = val - sa->offset; -#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ - .nr_entries = ARRAY_SIZE(array), \ - .entries = array, \ -} + if (idx < 0 || idx >= sa->nr_entries) + return scnprintf(bf, size, intfmt, val); -#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \ - .offset = off, \ - .nr_entries = ARRAY_SIZE(array), \ - .entries = array, \ + return scnprintf(bf, size, "%s", sa->entries[idx]); } static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size, const char *intfmt, struct syscall_arg *arg) { - struct strarray *sa = arg->parm; - int idx = arg->val - sa->offset; - - if (idx < 0 || idx >= sa->nr_entries) - return scnprintf(bf, size, intfmt, arg->val); - - return scnprintf(bf, size, "%s", sa->entries[idx]); + return strarray__scnprintf(arg->parm, bf, size, intfmt, arg->val); } static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, @@ -317,24 +308,35 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, #define SCA_STRARRAY syscall_arg__scnprintf_strarray -#if defined(__i386__) || defined(__x86_64__) -/* - * FIXME: Make this available to all arches as soon as the ioctl beautifier - * gets rewritten to support all arches. - */ -static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, - struct syscall_arg *arg) -{ - return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg); +struct strarrays { + int nr_entries; + struct strarray **entries; +}; + +#define DEFINE_STRARRAYS(array) struct strarrays strarrays__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ } -#define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray -#endif /* defined(__i386__) || defined(__x86_64__) */ +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, + struct syscall_arg *arg) +{ + struct strarrays *sas = arg->parm; + int i; -static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, - struct syscall_arg *arg); + for (i = 0; i < sas->nr_entries; ++i) { + struct strarray *sa = sas->entries[i]; + int idx = arg->val - sa->offset; -#define SCA_FD syscall_arg__scnprintf_fd + if (idx >= 0 && idx < sa->nr_entries) { + if (sa->entries[idx] == NULL) + break; + return scnprintf(bf, size, "%s", sa->entries[idx]); + } + } + + return scnprintf(bf, size, "%d", arg->val); +} #ifndef AT_FDCWD #define AT_FDCWD -100 @@ -358,21 +360,20 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd -static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%#lx", arg->val); } -#define SCA_HEX syscall_arg__scnprintf_hex - -static size_t syscall_arg__scnprintf_int(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%d", arg->val); } -#define SCA_INT syscall_arg__scnprintf_int +size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg) +{ + return scnprintf(bf, size, "%ld", arg->val); +} static const char *bpf_cmd[] = { "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM", @@ -407,12 +408,27 @@ static DEFINE_STRARRAY(whences); static const char *fcntl_cmds[] = { "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK", - "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64", - "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX", - "F_GETOWNER_UIDS", + "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "GETLK64", + "SETLK64", "SETLKW64", "SETOWN_EX", "GETOWN_EX", + "GETOWNER_UIDS", }; static DEFINE_STRARRAY(fcntl_cmds); +static const char *fcntl_linux_specific_cmds[] = { + "SETLEASE", "GETLEASE", "NOTIFY", [5] = "CANCELLK", "DUPFD_CLOEXEC", + "SETPIPE_SZ", "GETPIPE_SZ", "ADD_SEALS", "GET_SEALS", + "GET_RW_HINT", "SET_RW_HINT", "GET_FILE_RW_HINT", "SET_FILE_RW_HINT", +}; + +static DEFINE_STRARRAY_OFFSET(fcntl_linux_specific_cmds, F_LINUX_SPECIFIC_BASE); + +static struct strarray *fcntl_cmds_arrays[] = { + &strarray__fcntl_cmds, + &strarray__fcntl_linux_specific_cmds, +}; + +static DEFINE_STRARRAYS(fcntl_cmds_arrays); + static const char *rlimit_resources[] = { "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE", "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO", @@ -495,33 +511,6 @@ static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags -#if defined(__i386__) || defined(__x86_64__) -/* - * FIXME: Make this available to all arches. - */ -#define TCGETS 0x5401 - -static const char *tioctls[] = { - "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", - "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL", - "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI", - "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC", - "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX", - "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO", - "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK", - "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2", - "TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK", - "TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG", - "TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL", - [0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG", - "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", - "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI", - "TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE", -}; - -static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); -#endif /* defined(__i386__) || defined(__x86_64__) */ - #ifndef GRND_NONBLOCK #define GRND_NONBLOCK 0x0001 #endif @@ -552,9 +541,9 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, #define SCA_GETRANDOM_FLAGS syscall_arg__scnprintf_getrandom_flags -#define STRARRAY(arg, name, array) \ - .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ - .arg_parm = { [arg] = &strarray__##array, } +#define STRARRAY(name, array) \ + { .scnprintf = SCA_STRARRAY, \ + .parm = &strarray__##array, } #include "trace/beauty/eventfd.c" #include "trace/beauty/flock.c" @@ -571,242 +560,219 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, #include "trace/beauty/socket_type.c" #include "trace/beauty/waitid_options.c" +struct syscall_arg_fmt { + size_t (*scnprintf)(char *bf, size_t size, struct syscall_arg *arg); + void *parm; + const char *name; + bool show_zero; +}; + static struct syscall_fmt { const char *name; const char *alias; - size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); - void *arg_parm[6]; - bool errmsg; + struct syscall_arg_fmt arg[6]; + u8 nr_args; bool errpid; bool timeout; bool hexret; } syscall_fmts[] = { - { .name = "access", .errmsg = true, - .arg_scnprintf = { [1] = SCA_ACCMODE, /* mode */ }, }, - { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, - { .name = "bpf", .errmsg = true, STRARRAY(0, cmd, bpf_cmd), }, + { .name = "access", + .arg = { [1] = { .scnprintf = SCA_ACCMODE, /* mode */ }, }, }, + { .name = "arch_prctl", .alias = "prctl", }, + { .name = "bpf", + .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk", .hexret = true, - .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, - { .name = "chdir", .errmsg = true, }, - { .name = "chmod", .errmsg = true, }, - { .name = "chroot", .errmsg = true, }, - { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, - { .name = "clone", .errpid = true, }, - { .name = "close", .errmsg = true, - .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, - { .name = "connect", .errmsg = true, }, - { .name = "creat", .errmsg = true, }, - { .name = "dup", .errmsg = true, }, - { .name = "dup2", .errmsg = true, }, - { .name = "dup3", .errmsg = true, }, - { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), }, - { .name = "eventfd2", .errmsg = true, - .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, - { .name = "faccessat", .errmsg = true, }, - { .name = "fadvise64", .errmsg = true, }, - { .name = "fallocate", .errmsg = true, }, - { .name = "fchdir", .errmsg = true, }, - { .name = "fchmod", .errmsg = true, }, - { .name = "fchmodat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "fchown", .errmsg = true, }, - { .name = "fchownat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "fcntl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, - .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, - { .name = "fdatasync", .errmsg = true, }, - { .name = "flock", .errmsg = true, - .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, }, - { .name = "fsetxattr", .errmsg = true, }, - { .name = "fstat", .errmsg = true, .alias = "newfstat", }, - { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, - { .name = "fstatfs", .errmsg = true, }, - { .name = "fsync", .errmsg = true, }, - { .name = "ftruncate", .errmsg = true, }, - { .name = "futex", .errmsg = true, - .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, - { .name = "futimesat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "getdents", .errmsg = true, }, - { .name = "getdents64", .errmsg = true, }, - { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, + .arg = { [0] = { .scnprintf = SCA_HEX, /* brk */ }, }, }, + { .name = "clock_gettime", + .arg = { [0] = STRARRAY(clk_id, clockid), }, }, + { .name = "clone", .errpid = true, .nr_args = 5, + .arg = { [0] = { .name = "flags", .scnprintf = SCA_CLONE_FLAGS, }, + [1] = { .name = "child_stack", .scnprintf = SCA_HEX, }, + [2] = { .name = "parent_tidptr", .scnprintf = SCA_HEX, }, + [3] = { .name = "child_tidptr", .scnprintf = SCA_HEX, }, + [4] = { .name = "tls", .scnprintf = SCA_HEX, }, }, }, + { .name = "close", + .arg = { [0] = { .scnprintf = SCA_CLOSE_FD, /* fd */ }, }, }, + { .name = "epoll_ctl", + .arg = { [1] = STRARRAY(op, epoll_ctl_ops), }, }, + { .name = "eventfd2", + .arg = { [1] = { .scnprintf = SCA_EFD_FLAGS, /* flags */ }, }, }, + { .name = "fchmodat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "fchownat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "fcntl", + .arg = { [1] = { .scnprintf = SCA_FCNTL_CMD, /* cmd */ + .parm = &strarrays__fcntl_cmds_arrays, + .show_zero = true, }, + [2] = { .scnprintf = SCA_FCNTL_ARG, /* arg */ }, }, }, + { .name = "flock", + .arg = { [1] = { .scnprintf = SCA_FLOCK, /* cmd */ }, }, }, + { .name = "fstat", .alias = "newfstat", }, + { .name = "fstatat", .alias = "newfstatat", }, + { .name = "futex", + .arg = { [1] = { .scnprintf = SCA_FUTEX_OP, /* op */ }, }, }, + { .name = "futimesat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "getitimer", + .arg = { [0] = STRARRAY(which, itimers), }, }, { .name = "getpid", .errpid = true, }, { .name = "getpgid", .errpid = true, }, { .name = "getppid", .errpid = true, }, - { .name = "getrandom", .errmsg = true, - .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, }, - { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, - { .name = "getxattr", .errmsg = true, }, - { .name = "inotify_add_watch", .errmsg = true, }, - { .name = "ioctl", .errmsg = true, - .arg_scnprintf = { + { .name = "getrandom", + .arg = { [2] = { .scnprintf = SCA_GETRANDOM_FLAGS, /* flags */ }, }, }, + { .name = "getrlimit", + .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "ioctl", + .arg = { #if defined(__i386__) || defined(__x86_64__) /* * FIXME: Make this available to all arches. */ - [1] = SCA_STRHEXARRAY, /* cmd */ - [2] = SCA_HEX, /* arg */ }, - .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, + [1] = { .scnprintf = SCA_IOCTL_CMD, /* cmd */ }, + [2] = { .scnprintf = SCA_HEX, /* arg */ }, }, }, #else - [2] = SCA_HEX, /* arg */ }, }, + [2] = { .scnprintf = SCA_HEX, /* arg */ }, }, }, #endif - { .name = "keyctl", .errmsg = true, STRARRAY(0, option, keyctl_options), }, - { .name = "kill", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "lchown", .errmsg = true, }, - { .name = "lgetxattr", .errmsg = true, }, - { .name = "linkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "listxattr", .errmsg = true, }, - { .name = "llistxattr", .errmsg = true, }, - { .name = "lremovexattr", .errmsg = true, }, - { .name = "lseek", .errmsg = true, - .arg_scnprintf = { [2] = SCA_STRARRAY, /* whence */ }, - .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, - { .name = "lsetxattr", .errmsg = true, }, - { .name = "lstat", .errmsg = true, .alias = "newlstat", }, - { .name = "lsxattr", .errmsg = true, }, - { .name = "madvise", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* start */ - [2] = SCA_MADV_BHV, /* behavior */ }, }, - { .name = "mkdir", .errmsg = true, }, - { .name = "mkdirat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "mknod", .errmsg = true, }, - { .name = "mknodat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "mlock", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, - { .name = "mlockall", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, + { .name = "keyctl", + .arg = { [0] = STRARRAY(option, keyctl_options), }, }, + { .name = "kill", + .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "linkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "lseek", + .arg = { [2] = STRARRAY(whence, whences), }, }, + { .name = "lstat", .alias = "newlstat", }, + { .name = "madvise", + .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, + [2] = { .scnprintf = SCA_MADV_BHV, /* behavior */ }, }, }, + { .name = "mkdirat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "mknodat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "mlock", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + { .name = "mlockall", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, { .name = "mmap", .hexret = true, /* The standard mmap maps to old_mmap on s390x */ #if defined(__s390x__) .alias = "old_mmap", #endif - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ - [2] = SCA_MMAP_PROT, /* prot */ - [3] = SCA_MMAP_FLAGS, /* flags */ }, }, - { .name = "mprotect", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* start */ - [2] = SCA_MMAP_PROT, /* prot */ }, }, - { .name = "mq_unlink", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FILENAME, /* u_name */ }, }, + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, + [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, + [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, }, }, + { .name = "mprotect", + .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, + [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, }, }, + { .name = "mq_unlink", + .arg = { [0] = { .scnprintf = SCA_FILENAME, /* u_name */ }, }, }, { .name = "mremap", .hexret = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ - [3] = SCA_MREMAP_FLAGS, /* flags */ - [4] = SCA_HEX, /* new_addr */ }, }, - { .name = "munlock", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, - { .name = "munmap", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, - { .name = "name_to_handle_at", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "newfstatat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "open", .errmsg = true, - .arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, }, - { .name = "open_by_handle_at", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ - [2] = SCA_OPEN_FLAGS, /* flags */ }, }, - { .name = "openat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ - [2] = SCA_OPEN_FLAGS, /* flags */ }, }, - { .name = "perf_event_open", .errmsg = true, - .arg_scnprintf = { [2] = SCA_INT, /* cpu */ - [3] = SCA_FD, /* group_fd */ - [4] = SCA_PERF_FLAGS, /* flags */ }, }, - { .name = "pipe2", .errmsg = true, - .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, }, - { .name = "poll", .errmsg = true, .timeout = true, }, - { .name = "ppoll", .errmsg = true, .timeout = true, }, - { .name = "pread", .errmsg = true, .alias = "pread64", }, - { .name = "preadv", .errmsg = true, .alias = "pread", }, - { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), }, - { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, - { .name = "pwritev", .errmsg = true, }, - { .name = "read", .errmsg = true, }, - { .name = "readlink", .errmsg = true, }, - { .name = "readlinkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "readv", .errmsg = true, }, - { .name = "recvfrom", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "recvmmsg", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "recvmsg", .errmsg = true, - .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "removexattr", .errmsg = true, }, - { .name = "renameat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "rmdir", .errmsg = true, }, - { .name = "rt_sigaction", .errmsg = true, - .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, - { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), }, - { .name = "rt_sigqueueinfo", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "rt_tgsigqueueinfo", .errmsg = true, - .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, - { .name = "sched_getattr", .errmsg = true, }, - { .name = "sched_setattr", .errmsg = true, }, - { .name = "sched_setscheduler", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SCHED_POLICY, /* policy */ }, }, - { .name = "seccomp", .errmsg = true, - .arg_scnprintf = { [0] = SCA_SECCOMP_OP, /* op */ - [1] = SCA_SECCOMP_FLAGS, /* flags */ }, }, - { .name = "select", .errmsg = true, .timeout = true, }, - { .name = "sendmmsg", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "sendmsg", .errmsg = true, - .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "sendto", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, + [3] = { .scnprintf = SCA_MREMAP_FLAGS, /* flags */ }, + [4] = { .scnprintf = SCA_HEX, /* new_addr */ }, }, }, + { .name = "munlock", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + { .name = "munmap", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + { .name = "name_to_handle_at", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "newfstatat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "open", + .arg = { [1] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, + { .name = "open_by_handle_at", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, + [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, + { .name = "openat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, + [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, + { .name = "perf_event_open", + .arg = { [2] = { .scnprintf = SCA_INT, /* cpu */ }, + [3] = { .scnprintf = SCA_FD, /* group_fd */ }, + [4] = { .scnprintf = SCA_PERF_FLAGS, /* flags */ }, }, }, + { .name = "pipe2", + .arg = { [1] = { .scnprintf = SCA_PIPE_FLAGS, /* flags */ }, }, }, + { .name = "pkey_alloc", + .arg = { [1] = { .scnprintf = SCA_PKEY_ALLOC_ACCESS_RIGHTS, /* access_rights */ }, }, }, + { .name = "pkey_free", + .arg = { [0] = { .scnprintf = SCA_INT, /* key */ }, }, }, + { .name = "pkey_mprotect", + .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, + [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, + [3] = { .scnprintf = SCA_INT, /* pkey */ }, }, }, + { .name = "poll", .timeout = true, }, + { .name = "ppoll", .timeout = true, }, + { .name = "pread", .alias = "pread64", }, + { .name = "preadv", .alias = "pread", }, + { .name = "prlimit64", + .arg = { [1] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "pwrite", .alias = "pwrite64", }, + { .name = "readlinkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "recvfrom", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "recvmmsg", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "recvmsg", + .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "renameat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "rt_sigaction", + .arg = { [0] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "rt_sigprocmask", + .arg = { [0] = STRARRAY(how, sighow), }, }, + { .name = "rt_sigqueueinfo", + .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "rt_tgsigqueueinfo", + .arg = { [2] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "sched_setscheduler", + .arg = { [1] = { .scnprintf = SCA_SCHED_POLICY, /* policy */ }, }, }, + { .name = "seccomp", + .arg = { [0] = { .scnprintf = SCA_SECCOMP_OP, /* op */ }, + [1] = { .scnprintf = SCA_SECCOMP_FLAGS, /* flags */ }, }, }, + { .name = "select", .timeout = true, }, + { .name = "sendmmsg", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "sendmsg", + .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "sendto", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "set_tid_address", .errpid = true, }, - { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, - { .name = "setpgid", .errmsg = true, }, - { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, - { .name = "setxattr", .errmsg = true, }, - { .name = "shutdown", .errmsg = true, }, - { .name = "socket", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ - [1] = SCA_SK_TYPE, /* type */ }, - .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, - { .name = "socketpair", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ - [1] = SCA_SK_TYPE, /* type */ }, - .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, - { .name = "stat", .errmsg = true, .alias = "newstat", }, - { .name = "statfs", .errmsg = true, }, - { .name = "statx", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* flags */ - [2] = SCA_STATX_FLAGS, /* flags */ - [3] = SCA_STATX_MASK, /* mask */ }, }, - { .name = "swapoff", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, }, - { .name = "swapon", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, }, - { .name = "symlinkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "tgkill", .errmsg = true, - .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, - { .name = "tkill", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "truncate", .errmsg = true, }, - { .name = "uname", .errmsg = true, .alias = "newuname", }, - { .name = "unlinkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "utime", .errmsg = true, }, - { .name = "utimensat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, }, - { .name = "utimes", .errmsg = true, }, - { .name = "vmsplice", .errmsg = true, }, + { .name = "setitimer", + .arg = { [0] = STRARRAY(which, itimers), }, }, + { .name = "setrlimit", + .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "socket", + .arg = { [0] = STRARRAY(family, socket_families), + [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, + { .name = "socketpair", + .arg = { [0] = STRARRAY(family, socket_families), + [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, + { .name = "stat", .alias = "newstat", }, + { .name = "statx", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ }, + [2] = { .scnprintf = SCA_STATX_FLAGS, /* flags */ } , + [3] = { .scnprintf = SCA_STATX_MASK, /* mask */ }, }, }, + { .name = "swapoff", + .arg = { [0] = { .scnprintf = SCA_FILENAME, /* specialfile */ }, }, }, + { .name = "swapon", + .arg = { [0] = { .scnprintf = SCA_FILENAME, /* specialfile */ }, }, }, + { .name = "symlinkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "tgkill", + .arg = { [2] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "tkill", + .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "uname", .alias = "newuname", }, + { .name = "unlinkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "utimensat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dirfd */ }, }, }, { .name = "wait4", .errpid = true, - .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, }, + .arg = { [2] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, }, { .name = "waitid", .errpid = true, - .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, }, - { .name = "write", .errmsg = true, }, - { .name = "writev", .errmsg = true, }, + .arg = { [3] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, }, }; static int syscall_fmt__cmp(const void *name, const void *fmtp) @@ -828,8 +794,7 @@ struct syscall { const char *name; bool is_exit; struct syscall_fmt *fmt; - size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); - void **arg_parm; + struct syscall_arg_fmt *arg_fmt; }; /* @@ -859,6 +824,8 @@ static size_t fprintf_duration(unsigned long t, bool calculated, FILE *fp) * filename.ptr: The filename char pointer that will be vfs_getname'd * filename.entry_str_pos: Where to insert the string translated from * filename.ptr by the vfs_getname tracepoint/kprobe. + * ret_scnprintf: syscall args may set this to a different syscall return + * formatter, for instance, fcntl may return fds, file flags, etc. */ struct thread_trace { u64 entry_time; @@ -867,6 +834,7 @@ struct thread_trace { unsigned long pfmaj, pfmin; char *entry_str; double runtime_ms; + size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); struct { unsigned long ptr; short int entry_str_pos; @@ -917,6 +885,15 @@ static struct thread_trace *thread__trace(struct thread *thread, FILE *fp) return NULL; } + +void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, + size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg)) +{ + struct thread_trace *ttrace = thread__priv(arg->thread); + + ttrace->ret_scnprintf = ret_scnprintf; +} + #define TRACE_PFMAJ (1 << 0) #define TRACE_PFMIN (1 << 1) @@ -996,8 +973,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, return ttrace->paths.table[fd]; } -static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg) { int fd = arg->val; size_t printed = scnprintf(bf, size, "%d", fd); @@ -1162,32 +1138,46 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) return err; } +static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args) +{ + int idx; + + if (nr_args == 6 && sc->fmt && sc->fmt->nr_args != 0) + nr_args = sc->fmt->nr_args; + + sc->arg_fmt = calloc(nr_args, sizeof(*sc->arg_fmt)); + if (sc->arg_fmt == NULL) + return -1; + + for (idx = 0; idx < nr_args; ++idx) { + if (sc->fmt) + sc->arg_fmt[idx] = sc->fmt->arg[idx]; + } + + sc->nr_args = nr_args; + return 0; +} + static int syscall__set_arg_fmts(struct syscall *sc) { struct format_field *field; int idx = 0, len; - sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *)); - if (sc->arg_scnprintf == NULL) - return -1; - - if (sc->fmt) - sc->arg_parm = sc->fmt->arg_parm; + for (field = sc->args; field; field = field->next, ++idx) { + if (sc->fmt && sc->fmt->arg[idx].scnprintf) + continue; - for (field = sc->args; field; field = field->next) { - if (sc->fmt && sc->fmt->arg_scnprintf[idx]) - sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; - else if (strcmp(field->type, "const char *") == 0 && + if (strcmp(field->type, "const char *") == 0 && (strcmp(field->name, "filename") == 0 || strcmp(field->name, "path") == 0 || strcmp(field->name, "pathname") == 0)) - sc->arg_scnprintf[idx] = SCA_FILENAME; + sc->arg_fmt[idx].scnprintf = SCA_FILENAME; else if (field->flags & FIELD_IS_POINTER) - sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; + sc->arg_fmt[idx].scnprintf = syscall_arg__scnprintf_hex; else if (strcmp(field->type, "pid_t") == 0) - sc->arg_scnprintf[idx] = SCA_PID; + sc->arg_fmt[idx].scnprintf = SCA_PID; else if (strcmp(field->type, "umode_t") == 0) - sc->arg_scnprintf[idx] = SCA_MODE_T; + sc->arg_fmt[idx].scnprintf = SCA_MODE_T; else if ((strcmp(field->type, "int") == 0 || strcmp(field->type, "unsigned int") == 0 || strcmp(field->type, "long") == 0) && @@ -1200,9 +1190,8 @@ static int syscall__set_arg_fmts(struct syscall *sc) * 23 unsigned int * 7 unsigned long */ - sc->arg_scnprintf[idx] = SCA_FD; + sc->arg_fmt[idx].scnprintf = SCA_FD; } - ++idx; } return 0; @@ -1247,11 +1236,13 @@ static int trace__read_syscall_info(struct trace *trace, int id) sc->tp_format = trace_event__tp_format("syscalls", tp_name); } + if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields)) + return -1; + if (IS_ERR(sc->tp_format)) return -1; sc->args = sc->tp_format->format.fields; - sc->nr_args = sc->tp_format->format.nr_fields; /* * We need to check and discard the first variable '__syscall_nr' * or 'nr' that mean the syscall number. It is needless here. @@ -1270,6 +1261,7 @@ static int trace__read_syscall_info(struct trace *trace, int id) static int trace__validate_ev_qualifier(struct trace *trace) { int err = 0, i; + size_t nr_allocated; struct str_node *pos; trace->ev_qualifier_ids.nr = strlist__nr_entries(trace->ev_qualifier); @@ -1283,13 +1275,18 @@ static int trace__validate_ev_qualifier(struct trace *trace) goto out; } + nr_allocated = trace->ev_qualifier_ids.nr; i = 0; strlist__for_each_entry(pos, trace->ev_qualifier) { const char *sc = pos->s; - int id = syscalltbl__id(trace->sctbl, sc); + int id = syscalltbl__id(trace->sctbl, sc), match_next = -1; if (id < 0) { + id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next); + if (id >= 0) + goto matches; + if (err == 0) { fputs("Error:\tInvalid syscall ", trace->output); err = -EINVAL; @@ -1299,13 +1296,37 @@ static int trace__validate_ev_qualifier(struct trace *trace) fputs(sc, trace->output); } - +matches: trace->ev_qualifier_ids.entries[i++] = id; + if (match_next == -1) + continue; + + while (1) { + id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next); + if (id < 0) + break; + if (nr_allocated == trace->ev_qualifier_ids.nr) { + void *entries; + + nr_allocated += 8; + entries = realloc(trace->ev_qualifier_ids.entries, + nr_allocated * sizeof(trace->ev_qualifier_ids.entries[0])); + if (entries == NULL) { + err = -ENOMEM; + fputs("\nError:\t Not enough memory for parsing\n", trace->output); + goto out_free; + } + trace->ev_qualifier_ids.entries = entries; + } + trace->ev_qualifier_ids.nr++; + trace->ev_qualifier_ids.entries[i++] = id; + } } if (err < 0) { fputs("\nHint:\ttry 'perf list syscalls:sys_enter_*'" "\nHint:\tand: 'man syscalls'\n", trace->output); +out_free: zfree(&trace->ev_qualifier_ids.entries); trace->ev_qualifier_ids.nr = 0; } @@ -1321,33 +1342,68 @@ static int trace__validate_ev_qualifier(struct trace *trace) * variable to read it. Most notably this avoids extended load instructions * on unaligned addresses */ +unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx) +{ + unsigned long val; + unsigned char *p = arg->args + sizeof(unsigned long) * idx; + + memcpy(&val, p, sizeof(val)); + return val; +} + +static size_t syscall__scnprintf_name(struct syscall *sc, char *bf, size_t size, + struct syscall_arg *arg) +{ + if (sc->arg_fmt && sc->arg_fmt[arg->idx].name) + return scnprintf(bf, size, "%s: ", sc->arg_fmt[arg->idx].name); + + return scnprintf(bf, size, "arg%d: ", arg->idx); +} + +static size_t syscall__scnprintf_val(struct syscall *sc, char *bf, size_t size, + struct syscall_arg *arg, unsigned long val) +{ + if (sc->arg_fmt && sc->arg_fmt[arg->idx].scnprintf) { + arg->val = val; + if (sc->arg_fmt[arg->idx].parm) + arg->parm = sc->arg_fmt[arg->idx].parm; + return sc->arg_fmt[arg->idx].scnprintf(bf, size, arg); + } + return scnprintf(bf, size, "%ld", val); +} static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, unsigned char *args, struct trace *trace, struct thread *thread) { size_t printed = 0; - unsigned char *p; unsigned long val; + u8 bit = 1; + struct syscall_arg arg = { + .args = args, + .idx = 0, + .mask = 0, + .trace = trace, + .thread = thread, + }; + struct thread_trace *ttrace = thread__priv(thread); + + /* + * Things like fcntl will set this in its 'cmd' formatter to pick the + * right formatter for the return value (an fd? file flags?), which is + * not needed for syscalls that always return a given type, say an fd. + */ + ttrace->ret_scnprintf = NULL; if (sc->args != NULL) { struct format_field *field; - u8 bit = 1; - struct syscall_arg arg = { - .idx = 0, - .mask = 0, - .trace = trace, - .thread = thread, - }; for (field = sc->args; field; field = field->next, ++arg.idx, bit <<= 1) { if (arg.mask & bit) continue; - /* special care for unaligned accesses */ - p = args + sizeof(unsigned long) * arg.idx; - memcpy(&val, p, sizeof(val)); + val = syscall_arg__val(&arg, arg.idx); /* * Suppress this argument if its value is zero and @@ -1355,23 +1411,16 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, * strarray for it. */ if (val == 0 && - !(sc->arg_scnprintf && - sc->arg_scnprintf[arg.idx] == SCA_STRARRAY && - sc->arg_parm[arg.idx])) + !(sc->arg_fmt && + (sc->arg_fmt[arg.idx].show_zero || + sc->arg_fmt[arg.idx].scnprintf == SCA_STRARRAY || + sc->arg_fmt[arg.idx].scnprintf == SCA_STRARRAYS) && + sc->arg_fmt[arg.idx].parm)) continue; printed += scnprintf(bf + printed, size - printed, "%s%s: ", printed ? ", " : "", field->name); - if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { - arg.val = val; - if (sc->arg_parm) - arg.parm = sc->arg_parm[arg.idx]; - printed += sc->arg_scnprintf[arg.idx](bf + printed, - size - printed, &arg); - } else { - printed += scnprintf(bf + printed, size - printed, - "%ld", val); - } + printed += syscall__scnprintf_val(sc, bf + printed, size - printed, &arg, val); } } else if (IS_ERR(sc->tp_format)) { /* @@ -1379,16 +1428,17 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, * may end up not having any args, like with gettid(), so only * print the raw args when we didn't manage to read it. */ - int i = 0; - - while (i < 6) { - /* special care for unaligned accesses */ - p = args + sizeof(unsigned long) * i; - memcpy(&val, p, sizeof(val)); - printed += scnprintf(bf + printed, size - printed, - "%sarg%d: %ld", - printed ? ", " : "", i, val); - ++i; + while (arg.idx < sc->nr_args) { + if (arg.mask & bit) + goto next_arg; + val = syscall_arg__val(&arg, arg.idx); + if (printed) + printed += scnprintf(bf + printed, size - printed, ", "); + printed += syscall__scnprintf_name(sc, bf + printed, size - printed, &arg); + printed += syscall__scnprintf_val(sc, bf + printed, size - printed, &arg, val); +next_arg: + ++arg.idx; + bit <<= 1; } } @@ -1635,17 +1685,31 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, } if (sc->fmt == NULL) { + if (ret < 0) + goto errno_print; signed_print: fprintf(trace->output, ") = %ld", ret); - } else if (ret < 0 && (sc->fmt->errmsg || sc->fmt->errpid)) { + } else if (ret < 0) { +errno_print: { char bf[STRERR_BUFSIZE]; const char *emsg = str_error_r(-ret, bf, sizeof(bf)), *e = audit_errno_to_name(-ret); fprintf(trace->output, ") = -1 %s %s", e, emsg); + } } else if (ret == 0 && sc->fmt->timeout) fprintf(trace->output, ") = 0 Timeout"); - else if (sc->fmt->hexret) + else if (ttrace->ret_scnprintf) { + char bf[1024]; + struct syscall_arg arg = { + .val = ret, + .thread = thread, + .trace = trace, + }; + ttrace->ret_scnprintf(bf, sizeof(bf), &arg); + ttrace->ret_scnprintf = NULL; + fprintf(trace->output, ") = %s", bf); + } else if (sc->fmt->hexret) fprintf(trace->output, ") = %#lx", ret); else if (sc->fmt->errpid) { struct thread *child = machine__find_thread(trace->host, ret, ret); @@ -2171,6 +2235,30 @@ static int trace__set_ev_qualifier_filter(struct trace *trace) goto out; } +static int trace__set_filter_loop_pids(struct trace *trace) +{ + unsigned int nr = 1; + pid_t pids[32] = { + getpid(), + }; + struct thread *thread = machine__find_thread(trace->host, pids[0], pids[0]); + + while (thread && nr < ARRAY_SIZE(pids)) { + struct thread *parent = machine__find_thread(trace->host, thread->ppid, thread->ppid); + + if (parent == NULL) + break; + + if (!strcmp(thread__comm_str(parent), "sshd")) { + pids[nr++] = parent->tid; + break; + } + thread = parent; + } + + return perf_evlist__set_filter_pids(trace->evlist, nr, pids); +} + static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = trace->evlist; @@ -2294,7 +2382,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (trace->filter_pids.nr > 0) err = perf_evlist__set_filter_pids(evlist, trace->filter_pids.nr, trace->filter_pids.entries); else if (thread_map__pid(evlist->threads, 0) == -1) - err = perf_evlist__set_filter_pid(evlist, getpid()); + err = trace__set_filter_loop_pids(trace); if (err < 0) goto out_error_mem; @@ -2756,7 +2844,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str, struct trace *trace = (struct trace *)opt->value; const char *s = str; char *sep = NULL, *lists[2] = { NULL, NULL, }; - int len = strlen(str), err = -1, list; + int len = strlen(str) + 1, err = -1, list, idx; char *strace_groups_dir = system_path(STRACE_GROUPS_DIR); char group_name[PATH_MAX]; @@ -2773,7 +2861,8 @@ static int trace__parse_events_option(const struct option *opt, const char *str, *sep = '\0'; list = 0; - if (syscalltbl__id(trace->sctbl, s) >= 0) { + if (syscalltbl__id(trace->sctbl, s) >= 0 || + syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) { list = 1; } else { path__join(group_name, sizeof(group_name), strace_groups_dir, s); diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 83fe2202382eda0cd95eafc15a726cb9022527d8..932fda54b8a661171a0ae5430e24e0e4f9645cd5 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -1,9 +1,15 @@ #!/bin/sh HEADERS=' +include/uapi/drm/drm.h +include/uapi/drm/i915_drm.h include/uapi/linux/fcntl.h +include/uapi/linux/kvm.h include/uapi/linux/perf_event.h +include/uapi/linux/sched.h include/uapi/linux/stat.h +include/uapi/linux/vhost.h +include/uapi/sound/asound.h include/linux/hash.h include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h @@ -16,6 +22,7 @@ arch/x86/include/uapi/asm/perf_regs.h arch/x86/include/uapi/asm/kvm.h arch/x86/include/uapi/asm/kvm_perf.h arch/x86/include/uapi/asm/svm.h +arch/x86/include/uapi/asm/unistd.h arch/x86/include/uapi/asm/vmx.h arch/powerpc/include/uapi/asm/kvm.h arch/s390/include/uapi/asm/kvm.h @@ -29,12 +36,13 @@ include/asm-generic/bitops/__fls.h include/asm-generic/bitops/fls.h include/asm-generic/bitops/fls64.h include/linux/coresight-pmu.h +include/uapi/asm-generic/ioctls.h include/uapi/asm-generic/mman-common.h ' check () { file=$1 - opts= + opts="--ignore-blank-lines --ignore-space-change" shift while [ -n "$*" ]; do @@ -45,7 +53,7 @@ check () { cmd="diff $opts ../$file ../../$file > /dev/null" test -f ../../$file && - eval $cmd || echo "Warning: $file differs from kernel" >&2 + eval $cmd || echo "Warning: Kernel ABI header at 'tools/$file' differs from latest version at '$file'" >&2 } @@ -55,7 +63,7 @@ for i in $HEADERS; do done # diff with extra ignore lines -check arch/x86/lib/memcpy_64.S -B -I "^EXPORT_SYMBOL" -I "^#include " -check arch/x86/lib/memset_64.S -B -I "^EXPORT_SYMBOL" -I "^#include " -check include/uapi/asm-generic/mman.h -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>" -check include/uapi/linux/mman.h -B -I "^#include <\(uapi/\)*asm/mman.h>" +check arch/x86/lib/memcpy_64.S -I "^EXPORT_SYMBOL" -I "^#include " +check arch/x86/lib/memset_64.S -I "^EXPORT_SYMBOL" -I "^#include " +check include/uapi/asm-generic/mman.h -I "^#include <\(uapi/\)*asm-generic/mman-common.h>" +check include/uapi/linux/mman.h -I "^#include <\(uapi/\)*asm/mman.h>" diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index e4b717e9eb6cf532c2d9c823c1b8f71e8da4256b..c11f0c76e90c78aa0eef8f436f59d842ce0c2201 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h @@ -9,16 +9,6 @@ #include #include -#if defined(__i386__) -#define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#define CPUINFO_PROC {"model name"} -#endif - -#if defined(__x86_64__) -#define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#define CPUINFO_PROC {"model name"} -#endif - #ifdef __powerpc__ #define CPUINFO_PROC {"cpu"} #endif @@ -43,19 +33,10 @@ #define CPUINFO_PROC {"cpu model"} #endif -#ifdef __ia64__ -#define cpu_relax() asm volatile ("hint @pause" ::: "memory") -#define CPUINFO_PROC {"model name"} -#endif - #ifdef __arm__ #define CPUINFO_PROC {"model name", "Processor"} #endif -#ifdef __aarch64__ -#define cpu_relax() asm volatile("yield" ::: "memory") -#endif - #ifdef __mips__ #define CPUINFO_PROC {"cpu model"} #endif @@ -72,13 +53,8 @@ #define CPUINFO_PROC {"core ID"} #endif -#ifdef __tile__ -#define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") -#define CPUINFO_PROC {"model name"} -#endif - -#ifndef cpu_relax -#define cpu_relax() barrier() +#ifndef CPUINFO_PROC +#define CPUINFO_PROC { "model name", } #endif static inline int diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 628a5e412cb14b00d9ead40bdcbb13db4c82bd75..2f19e03c5c40d172a3a9adcd4916c22739be700c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -89,7 +89,7 @@ struct pager_config { static int pager_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; - if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) + if (strstarts(var, "pager.") && !strcmp(var + 6, c->cmd)) c->val = perf_config_bool(var, value); return 0; } @@ -108,9 +108,9 @@ static int check_pager_config(const char *cmd) static int browser_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; - if (!prefixcmp(var, "tui.") && !strcmp(var + 4, c->cmd)) + if (strstarts(var, "tui.") && !strcmp(var + 4, c->cmd)) c->val = perf_config_bool(var, value); - if (!prefixcmp(var, "gtk.") && !strcmp(var + 4, c->cmd)) + if (strstarts(var, "gtk.") && !strcmp(var + 4, c->cmd)) c->val = perf_config_bool(var, value) ? 2 : 0; return 0; } @@ -192,7 +192,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) /* * Check remaining flags. */ - if (!prefixcmp(cmd, CMD_EXEC_PATH)) { + if (strstarts(cmd, CMD_EXEC_PATH)) { cmd += strlen(CMD_EXEC_PATH); if (*cmd == '=') set_argv_exec_path(cmd + 1); @@ -229,7 +229,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) *envchanged = 1; (*argv)++; (*argc)--; - } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { + } else if (strstarts(cmd, CMD_DEBUGFS_DIR)) { tracing_path_set(cmd + strlen(CMD_DEBUGFS_DIR)); fprintf(stderr, "dir: %s\n", tracing_path); if (envchanged) @@ -467,17 +467,23 @@ int main(int argc, const char **argv) * - cannot execute it externally (since it would just do * the same thing over again) * - * So we just directly call the internal command handler, and - * die if that one cannot handle it. + * So we just directly call the internal command handler. If that one + * fails to handle this, then maybe we just run a renamed perf binary + * that contains a dash in its name. To handle this scenario, we just + * fall through and ignore the "xxxx" part of the command string. */ - if (!prefixcmp(cmd, "perf-")) { + if (strstarts(cmd, "perf-")) { cmd += 5; argv[0] = cmd; handle_internal_command(argc, argv); - fprintf(stderr, "cannot handle %s internally", cmd); - goto out; + /* + * If the command is handled, the above function does not + * return undo changes and fall through in such a case. + */ + cmd -= 5; + argv[0] = cmd; } - if (!prefixcmp(cmd, "trace")) { + if (strstarts(cmd, "trace")) { #ifdef HAVE_LIBAUDIT_SUPPORT setup_path(); argv[0] = "trace"; @@ -495,7 +501,7 @@ int main(int argc, const char **argv) commit_pager_choice(); if (argc > 0) { - if (!prefixcmp(argv[0], "--")) + if (strstarts(argv[0], "--")) argv[0] += 2; } else { /* The user didn't specify a command; give them help */ diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 806c216a1078210a028167c26eb442cec8e219b9..dc442ba21bf6b11b05635077294d1fce2ec70e00 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -7,6 +7,7 @@ #include extern bool test_attr__enabled; +void test_attr__ready(void); void test_attr__init(void); void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, int fd, int group_fd, unsigned long flags); @@ -42,6 +43,7 @@ struct record_opts { bool no_samples; bool raw_samples; bool sample_address; + bool sample_phys_addr; bool sample_weight; bool sample_time; bool sample_time_set; diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README index 1408ade0d773bee0cf2db0ed50bfd651ba997131..c2ee3e4417fe07fc7dba639aab4549a8b6146d0b 100644 --- a/tools/perf/pmu-events/README +++ b/tools/perf/pmu-events/README @@ -85,10 +85,6 @@ users to specify events by their name: where 'pm_1plus_ppc_cmpl' is a Power8 PMU event. -In case of errors when processing files in the tools/perf/pmu-events/arch -directory, 'jevents' tries to create an empty mapping file to allow the perf -build to succeed even if the PMU event aliases cannot be used. - However some errors in processing may cause the perf build to fail. Mapfile format diff --git a/tools/perf/pmu-events/arch/powerpc/mapfile.csv b/tools/perf/pmu-events/arch/powerpc/mapfile.csv index e925baa0c30b8b0535c08a945a4036a3204aa792..a0f3a11ca19f14660ec7f3ad46ff5d8d848c66e4 100644 --- a/tools/perf/pmu-events/arch/powerpc/mapfile.csv +++ b/tools/perf/pmu-events/arch/powerpc/mapfile.csv @@ -13,9 +13,13 @@ # # Power8 entries -004b0000,1,power8.json,core -004b0201,1,power8.json,core -004c0000,1,power8.json,core -004d0000,1,power8.json,core -004d0100,1,power8.json,core -004d0200,1,power8.json,core +004b0000,1,power8,core +004b0201,1,power8,core +004c0000,1,power8,core +004d0000,1,power8,core +004d0100,1,power8,core +004d0200,1,power8,core +004c0100,1,power8,core +004e0100,1,power9,core +004e0200,1,power9,core +004e1200,1,power9,core diff --git a/tools/perf/pmu-events/arch/powerpc/power9/cache.json b/tools/perf/pmu-events/arch/powerpc/power9/cache.json new file mode 100644 index 0000000000000000000000000000000000000000..18f6645f28975be1d428c9efe8c861563f982930 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/cache.json @@ -0,0 +1,137 @@ +[ + {, + "EventCode": "0x300F4", + "EventName": "PM_THRD_CONC_RUN_INST", + "BriefDescription": "PPC Instructions Finished by this thread when all threads in the core had the run-latch set" + }, + {, + "EventCode": "0x1E056", + "EventName": "PM_CMPLU_STALL_FLUSH_ANY_THREAD", + "BriefDescription": "Cycles in which the NTC instruction is not allowed to complete because any of the 4 threads in the same core suffered a flush, which blocks completion" + }, + {, + "EventCode": "0x4D016", + "EventName": "PM_CMPLU_STALL_FXLONG", + "BriefDescription": "Completion stall due to a long latency scalar fixed point instruction (division, square root)" + }, + {, + "EventCode": "0x2D016", + "EventName": "PM_CMPLU_STALL_FXU", + "BriefDescription": "Finish stall due to a scalar fixed point or CR instruction in the execution pipeline. These instructions get routed to the ALU, ALU2, and DIV pipes" + }, + {, + "EventCode": "0x1D15C", + "EventName": "PM_MRK_DTLB_MISS_1G", + "BriefDescription": "Marked Data TLB reload (after a miss) page size 2M. Implies radix translation was used" + }, + {, + "EventCode": "0x4D12A", + "EventName": "PM_MRK_DATA_FROM_RL4_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's L4 on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x1003C", + "EventName": "PM_CMPLU_STALL_DMISS_L2L3", + "BriefDescription": "Completion stall by Dcache miss which resolved in L2/L3" + }, + {, + "EventCode": "0x4C014", + "EventName": "PM_CMPLU_STALL_LMQ_FULL", + "BriefDescription": "Finish stall because the NTF instruction was a load that missed in the L1 and the LMQ was unable to accept this load miss request because it was full" + }, + {, + "EventCode": "0x14048", + "EventName": "PM_INST_FROM_ON_CHIP_CACHE", + "BriefDescription": "The processor's Instruction cache was reloaded either shared or modified data from another core's L2/L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4D014", + "EventName": "PM_CMPLU_STALL_LOAD_FINISH", + "BriefDescription": "Finish stall because the NTF instruction was a load instruction with all its dependencies satisfied just going through the LSU pipe to finish" + }, + {, + "EventCode": "0x2404A", + "EventName": "PM_INST_FROM_RL4", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's L4 on the same Node or Group ( Remote) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1404A", + "EventName": "PM_INST_FROM_RL2L3_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x401EA", + "EventName": "PM_THRESH_EXC_128", + "BriefDescription": "Threshold counter exceeded a value of 128" + }, + {, + "EventCode": "0x400F6", + "EventName": "PM_BR_MPRED_CMPL", + "BriefDescription": "Number of Branch Mispredicts" + }, + {, + "EventCode": "0x2F140", + "EventName": "PM_MRK_DPTEG_FROM_L2_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x101E6", + "EventName": "PM_THRESH_EXC_4096", + "BriefDescription": "Threshold counter exceed a count of 4096" + }, + {, + "EventCode": "0x3D156", + "EventName": "PM_MRK_DTLB_MISS_64K", + "BriefDescription": "Marked Data TLB Miss page size 64K" + }, + {, + "EventCode": "0x4C15E", + "EventName": "PM_MRK_DTLB_MISS_16M", + "BriefDescription": "Marked Data TLB Miss page size 16M" + }, + {, + "EventCode": "0x2D15E", + "EventName": "PM_MRK_DTLB_MISS_16G", + "BriefDescription": "Marked Data TLB Miss page size 16G" + }, + {, + "EventCode": "0x3F14A", + "EventName": "PM_MRK_DPTEG_FROM_RMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group ( Remote) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4C016", + "EventName": "PM_CMPLU_STALL_DMISS_L2L3_CONFLICT", + "BriefDescription": "Completion stall due to cache miss that resolves in the L2 or L3 with a conflict" + }, + {, + "EventCode": "0x2C01A", + "EventName": "PM_CMPLU_STALL_LHS", + "BriefDescription": "Finish stall because the NTF instruction was a load that hit on an older store and it was waiting for store data" + }, + {, + "EventCode": "0x401E4", + "EventName": "PM_MRK_DTLB_MISS", + "BriefDescription": "Marked dtlb miss" + }, + {, + "EventCode": "0x24046", + "EventName": "PM_INST_FROM_RL2L3_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1002A", + "EventName": "PM_CMPLU_STALL_LARX", + "BriefDescription": "Finish stall because the NTF instruction was a larx waiting to be satisfied" + }, + {, + "EventCode": "0x3006C", + "EventName": "PM_RUN_CYC_SMT2_MODE", + "BriefDescription": "Cycles in which this thread's run latch is set and the core is in SMT2 mode" + }, + {, + "EventCode": "0x1C058", + "EventName": "PM_DTLB_MISS_16G", + "BriefDescription": "Data TLB Miss page size 16G" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/powerpc/power9/floating-point.json b/tools/perf/pmu-events/arch/powerpc/power9/floating-point.json new file mode 100644 index 0000000000000000000000000000000000000000..8a83bca26552a149defe6e06f52756e055d69250 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/floating-point.json @@ -0,0 +1,32 @@ +[ + {, + "EventCode": "0x1415A", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_LDHITST_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 with load hit store conflict due to a marked load" + }, + {, + "EventCode": "0x10058", + "EventName": "PM_MEM_LOC_THRESH_IFU", + "BriefDescription": "Local Memory above threshold for IFU speculation control" + }, + {, + "EventCode": "0x2D028", + "EventName": "PM_RADIX_PWC_L2_PDE_FROM_L2", + "BriefDescription": "A Page Directory Entry was reloaded to a level 2 page walk cache from the core's L2 data cache" + }, + {, + "EventCode": "0x30012", + "EventName": "PM_FLUSH_COMPLETION", + "BriefDescription": "The instruction that was next to complete did not complete because it suffered a flush" + }, + {, + "EventCode": "0x2D154", + "EventName": "PM_MRK_DERAT_MISS_64K", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 64K" + }, + {, + "EventCode": "0x4016E", + "EventName": "PM_THRESH_NOT_MET", + "BriefDescription": "Threshold counter did not meet threshold" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/powerpc/power9/frontend.json b/tools/perf/pmu-events/arch/powerpc/power9/frontend.json new file mode 100644 index 0000000000000000000000000000000000000000..c63a919eda981bbc972e08d55a03a35ab4208645 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/frontend.json @@ -0,0 +1,372 @@ +[ + {, + "EventCode": "0x3E15C", + "EventName": "PM_MRK_L2_TM_ST_ABORT_SISTER", + "BriefDescription": "TM marked store abort for this thread" + }, + {, + "EventCode": "0x25044", + "EventName": "PM_IPTEG_FROM_L31_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x101E8", + "EventName": "PM_THRESH_EXC_256", + "BriefDescription": "Threshold counter exceed a count of 256" + }, + {, + "EventCode": "0x4504E", + "EventName": "PM_IPTEG_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L3 due to a instruction side request" + }, + {, + "EventCode": "0x1006A", + "EventName": "PM_NTC_ISSUE_HELD_DARQ_FULL", + "BriefDescription": "The NTC instruction is being held at dispatch because there are no slots in the DARQ for it" + }, + {, + "EventCode": "0x4E016", + "EventName": "PM_CMPLU_STALL_LSAQ_ARB", + "BriefDescription": "Finish stall because the NTF instruction was a load or store that was held in LSAQ because an older instruction from SRQ or LRQ won arbitration to the LSU pipe when this instruction tried to launch" + }, + {, + "EventCode": "0x1001A", + "EventName": "PM_LSU_SRQ_FULL_CYC", + "BriefDescription": "Cycles in which the Store Queue is full on all 4 slices. This is event is not per thread. All the threads will see the same count for this core resource" + }, + {, + "EventCode": "0x1E15E", + "EventName": "PM_MRK_L2_TM_REQ_ABORT", + "BriefDescription": "TM abort" + }, + {, + "EventCode": "0x34052", + "EventName": "PM_INST_SYS_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (system) mispredicted. Either the original scope was too small (Chip/Group) or the original scope was System and it should have been smaller. Counts for an instruction fetch" + }, + {, + "EventCode": "0x20114", + "EventName": "PM_MRK_L2_RC_DISP", + "BriefDescription": "Marked Instruction RC dispatched in L2" + }, + {, + "EventCode": "0x4C044", + "EventName": "PM_DATA_FROM_L31_ECO_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's ECO L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x1C044", + "EventName": "PM_DATA_FROM_L3_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without conflict due to a demand load" + }, + {, + "EventCode": "0x44050", + "EventName": "PM_INST_SYS_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (system) ended up larger than Initial Pump Scope (Chip/Group) for an instruction fetch" + }, + {, + "EventCode": "0x30154", + "EventName": "PM_MRK_FAB_RSP_DCLAIM", + "BriefDescription": "Marked store had to do a dclaim" + }, + {, + "EventCode": "0x30014", + "EventName": "PM_CMPLU_STALL_STORE_FIN_ARB", + "BriefDescription": "Finish stall because the NTF instruction was a store waiting for a slot in the store finish pipe. This means the instruction is ready to finish but there are instructions ahead of it, using the finish pipe" + }, + {, + "EventCode": "0x3E054", + "EventName": "PM_LD_MISS_L1", + "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." + }, + {, + "EventCode": "0x2E01A", + "EventName": "PM_CMPLU_STALL_LSU_FLUSH_NEXT", + "BriefDescription": "Completion stall of one cycle because the LSU requested to flush the next iop in the sequence. It takes 1 cycle for the ISU to process this request before the LSU instruction is allowed to complete" + }, + {, + "EventCode": "0x2D01C", + "EventName": "PM_CMPLU_STALL_STCX", + "BriefDescription": "Finish stall because the NTF instruction was a stcx waiting for response from L2" + }, + {, + "EventCode": "0x2C010", + "EventName": "PM_CMPLU_STALL_LSU", + "BriefDescription": "Completion stall by LSU instruction" + }, + {, + "EventCode": "0x2C042", + "EventName": "PM_DATA_FROM_L3_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without dispatch conflicts hit on Mepf state due to a demand load" + }, + {, + "EventCode": "0x4E012", + "EventName": "PM_CMPLU_STALL_MTFPSCR", + "BriefDescription": "Completion stall because the ISU is updating the register and notifying the Effective Address Table (EAT)" + }, + {, + "EventCode": "0x100F2", + "EventName": "PM_1PLUS_PPC_CMPL", + "BriefDescription": "1 or more ppc insts finished" + }, + {, + "EventCode": "0x3001C", + "EventName": "PM_LSU_REJECT_LMQ_FULL", + "BriefDescription": "LSU Reject due to LMQ full (up to 4 per cycles)" + }, + {, + "EventCode": "0x15046", + "EventName": "PM_IPTEG_FROM_L31_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x1015E", + "EventName": "PM_MRK_FAB_RSP_RD_T_INTV", + "BriefDescription": "Sampled Read got a T intervention" + }, + {, + "EventCode": "0x101EC", + "EventName": "PM_THRESH_MET", + "BriefDescription": "threshold exceeded" + }, + {, + "EventCode": "0x10020", + "EventName": "PM_PMC4_REWIND", + "BriefDescription": "PMC4 Rewind Event" + }, + {, + "EventCode": "0x301EA", + "EventName": "PM_THRESH_EXC_1024", + "BriefDescription": "Threshold counter exceeded a value of 1024" + }, + {, + "EventCode": "0x34056", + "EventName": "PM_CMPLU_STALL_LSU_MFSPR", + "BriefDescription": "Finish stall because the NTF instruction was a mfspr instruction targeting an LSU SPR and it was waiting for the register data to be returned" + }, + {, + "EventCode": "0x44056", + "EventName": "PM_VECTOR_ST_CMPL", + "BriefDescription": "Number of vector store instructions completed" + }, + {, + "EventCode": "0x2C124", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_OTHER", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0x4C12A", + "EventName": "PM_MRK_DATA_FROM_RL2L3_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x3C056", + "EventName": "PM_DTLB_MISS_64K", + "BriefDescription": "Data TLB Miss page size 64K" + }, + {, + "EventCode": "0x30060", + "EventName": "PM_TM_TRANS_RUN_INST", + "BriefDescription": "Run instructions completed in transactional state (gated by the run latch)" + }, + {, + "EventCode": "0x2C014", + "EventName": "PM_CMPLU_STALL_STORE_FINISH", + "BriefDescription": "Finish stall because the NTF instruction was a store with all its dependencies met, just waiting to go through the LSU pipe to finish" + }, + {, + "EventCode": "0x3515A", + "EventName": "PM_MRK_DATA_FROM_ON_CHIP_CACHE_CYC", + "BriefDescription": "Duration in cycles to reload either shared or modified data from another core's L2/L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x34050", + "EventName": "PM_INST_SYS_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was system pump (prediction=correct) for an instruction fetch" + }, + {, + "EventCode": "0x3015E", + "EventName": "PM_MRK_FAB_RSP_CLAIM_RTY", + "BriefDescription": "Sampled store did a rwitm and got a rty" + }, + {, + "EventCode": "0x0", + "EventName": "PM_SUSPENDED", + "BriefDescription": "Counter OFF" + }, + {, + "EventCode": "0x10010", + "EventName": "PM_PMC4_OVERFLOW", + "BriefDescription": "Overflow from counter 4" + }, + {, + "EventCode": "0x3E04A", + "EventName": "PM_DPTEG_FROM_RMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group ( Remote) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2F152", + "EventName": "PM_MRK_FAB_RSP_DCLAIM_CYC", + "BriefDescription": "cycles L2 RC took for a dclaim" + }, + {, + "EventCode": "0x10004", + "EventName": "PM_CMPLU_STALL_LRQ_OTHER", + "BriefDescription": "Finish stall due to LRQ miscellaneous reasons, lost arbitration to LMQ slot, bank collisions, set prediction cleanup, set prediction multihit and others" + }, + {, + "EventCode": "0x4F150", + "EventName": "PM_MRK_FAB_RSP_RWITM_CYC", + "BriefDescription": "cycles L2 RC took for a rwitm" + }, + {, + "EventCode": "0x4E042", + "EventName": "PM_DPTEG_FROM_L3", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1F054", + "EventName": "PM_TLB_HIT", + "BriefDescription": "Number of times the TLB had the data required by the instruction. Applies to both HPT and RPT" + }, + {, + "EventCode": "0x2C01E", + "EventName": "PM_CMPLU_STALL_SYNC_PMU_INT", + "BriefDescription": "Cycles in which the NTC instruction is waiting for a synchronous PMU interrupt" + }, + {, + "EventCode": "0x24050", + "EventName": "PM_IOPS_CMPL", + "BriefDescription": "Internal Operations completed" + }, + {, + "EventCode": "0x1515C", + "EventName": "PM_SYNC_MRK_BR_MPRED", + "BriefDescription": "Marked Branch mispredict that can cause a synchronous interrupt" + }, + {, + "EventCode": "0x300FA", + "EventName": "PM_INST_FROM_L3MISS", + "BriefDescription": "Marked instruction was reloaded from a location beyond the local chiplet" + }, + {, + "EventCode": "0x15044", + "EventName": "PM_IPTEG_FROM_L3_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without conflict due to a instruction side request" + }, + {, + "EventCode": "0x15152", + "EventName": "PM_SYNC_MRK_BR_LINK", + "BriefDescription": "Marked Branch and link branch that can cause a synchronous interrupt" + }, + {, + "EventCode": "0x1E050", + "EventName": "PM_CMPLU_STALL_TEND", + "BriefDescription": "Finish stall because the NTF instruction was a tend instruction awaiting response from L2" + }, + {, + "EventCode": "0x1013E", + "EventName": "PM_MRK_LD_MISS_EXPOSED_CYC", + "BriefDescription": "Marked Load exposed Miss (use edge detect to count #)" + }, + {, + "EventCode": "0x25042", + "EventName": "PM_IPTEG_FROM_L3_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without dispatch conflicts hit on Mepf state. due to a instruction side request" + }, + {, + "EventCode": "0x14054", + "EventName": "PM_INST_PUMP_CPRED", + "BriefDescription": "Pump prediction correct. Counts across all types of pumps for an instruction fetch" + }, + {, + "EventCode": "0x4015E", + "EventName": "PM_MRK_FAB_RSP_RD_RTY", + "BriefDescription": "Sampled L2 reads retry count" + }, + {, + "EventCode": "0x45048", + "EventName": "PM_IPTEG_FROM_DL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x44052", + "EventName": "PM_INST_PUMP_MPRED", + "BriefDescription": "Pump misprediction. Counts across all types of pumps for an instruction fetch" + }, + {, + "EventCode": "0x30026", + "EventName": "PM_CMPLU_STALL_STORE_DATA", + "BriefDescription": "Finish stall because the next to finish instruction was a store waiting on data" + }, + {, + "EventCode": "0x301E6", + "EventName": "PM_MRK_DERAT_MISS", + "BriefDescription": "Erat Miss (TLB Access) All page sizes" + }, + {, + "EventCode": "0x24154", + "EventName": "PM_THRESH_ACC", + "BriefDescription": "This event increments every time the threshold event counter ticks. Thresholding must be enabled (via MMCRA) and the thresholding start event must occur for this counter to increment. It will stop incrementing when the thresholding stop event occurs or when thresholding is disabled, until the next time a configured thresholding start event occurs." + }, + {, + "EventCode": "0x2015E", + "EventName": "PM_MRK_FAB_RSP_RWITM_RTY", + "BriefDescription": "Sampled store did a rwitm and got a rty" + }, + {, + "EventCode": "0x200FA", + "EventName": "PM_BR_TAKEN_CMPL", + "BriefDescription": "New event for Branch Taken" + }, + {, + "EventCode": "0x35044", + "EventName": "PM_IPTEG_FROM_L31_ECO_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's ECO L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x4C010", + "EventName": "PM_CMPLU_STALL_STORE_PIPE_ARB", + "BriefDescription": "Finish stall because the NTF instruction was a store waiting for the next relaunch opportunity after an internal reject. This means the instruction is ready to relaunch and tried once but lost arbitration" + }, + {, + "EventCode": "0x4C01C", + "EventName": "PM_CMPLU_STALL_ST_FWD", + "BriefDescription": "Completion stall due to store forward" + }, + {, + "EventCode": "0x3515C", + "EventName": "PM_MRK_DATA_FROM_RL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x2D14C", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x40116", + "EventName": "PM_MRK_LARX_FIN", + "BriefDescription": "Larx finished" + }, + {, + "EventCode": "0x4C056", + "EventName": "PM_DTLB_MISS_16M", + "BriefDescription": "Data TLB Miss page size 16M" + }, + {, + "EventCode": "0x1003A", + "EventName": "PM_CMPLU_STALL_LSU_FIN", + "BriefDescription": "Finish stall because the NTF instruction was an LSU op (other than a load or a store) with all its dependencies met and just going through the LSU pipe to finish" + }, + {, + "EventCode": "0x3012A", + "EventName": "PM_MRK_L2_RC_DONE", + "BriefDescription": "Marked RC done" + }, + {, + "EventCode": "0x45044", + "EventName": "PM_IPTEG_FROM_L31_ECO_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a instruction side request" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/marked.json b/tools/perf/pmu-events/arch/powerpc/power9/marked.json new file mode 100644 index 0000000000000000000000000000000000000000..b9df54fb37e3690171f09c46f1d96d95d6e99684 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/marked.json @@ -0,0 +1,647 @@ +[ + {, + "EventCode": "0x3C052", + "EventName": "PM_DATA_SYS_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (system) mispredicted. Either the original scope was too small (Chip/Group) or the original scope was System and it should have been smaller. Counts for a demand load" + }, + {, + "EventCode": "0x3013E", + "EventName": "PM_MRK_STALL_CMPLU_CYC", + "BriefDescription": "Number of cycles the marked instruction is experiencing a stall while it is next to complete (NTC)" + }, + {, + "EventCode": "0x4F056", + "EventName": "PM_RADIX_PWC_L1_PDE_FROM_L3MISS", + "BriefDescription": "A Page Directory Entry was reloaded to a level 1 page walk cache from beyond the core's L3 data cache. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x24158", + "EventName": "PM_MRK_INST", + "BriefDescription": "An instruction was marked. Includes both Random Instruction Sampling (RIS) at decode time and Random Event Sampling (RES) at the time the configured event happens" + }, + {, + "EventCode": "0x1E046", + "EventName": "PM_DPTEG_FROM_L31_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3C04A", + "EventName": "PM_DATA_FROM_RMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group ( Remote) due to a demand load" + }, + {, + "EventCode": "0x2C01C", + "EventName": "PM_CMPLU_STALL_DMISS_REMOTE", + "BriefDescription": "Completion stall by Dcache miss which resolved from remote chip (cache or memory)" + }, + {, + "EventCode": "0x44040", + "EventName": "PM_INST_FROM_L2_DISP_CONFLICT_OTHER", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 with dispatch conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x2E050", + "EventName": "PM_DARQ0_7_9_ENTRIES", + "BriefDescription": "Cycles in which 7,8, or 9 DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x2D02E", + "EventName": "PM_RADIX_PWC_L3_PTE_FROM_L2", + "BriefDescription": "A Page Table Entry was reloaded to a level 3 page walk cache from the core's L2 data cache. This implies that a level 4 PWC access was not necessary for this translation" + }, + {, + "EventCode": "0x3F05E", + "EventName": "PM_RADIX_PWC_L3_PTE_FROM_L3", + "BriefDescription": "A Page Table Entry was reloaded to a level 3 page walk cache from the core's L3 data cache. This implies that a level 4 PWC access was not necessary for this translation" + }, + {, + "EventCode": "0x2E01E", + "EventName": "PM_CMPLU_STALL_NTC_FLUSH", + "BriefDescription": "Completion stall due to ntc flush" + }, + {, + "EventCode": "0x1F14C", + "EventName": "PM_MRK_DPTEG_FROM_LL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's L4 cache due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x20130", + "EventName": "PM_MRK_INST_DECODED", + "BriefDescription": "An instruction was marked at decode time. Random Instruction Sampling (RIS) only" + }, + {, + "EventCode": "0x3F144", + "EventName": "PM_MRK_DPTEG_FROM_L31_ECO_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's ECO L3 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D058", + "EventName": "PM_VECTOR_FLOP_CMPL", + "BriefDescription": "Vector FP instruction completed" + }, + {, + "EventCode": "0x14040", + "EventName": "PM_INST_FROM_L2_NO_CONFLICT", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 without conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4404E", + "EventName": "PM_INST_FROM_L3MISS_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded from a location other than the local core's L3 due to a instruction fetch" + }, + {, + "EventCode": "0x3003A", + "EventName": "PM_CMPLU_STALL_EXCEPTION", + "BriefDescription": "Cycles in which the NTC instruction is not allowed to complete because it was interrupted by ANY exception, which has to be serviced before the instruction can complete" + }, + {, + "EventCode": "0x4F144", + "EventName": "PM_MRK_DPTEG_FROM_L31_ECO_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3E044", + "EventName": "PM_DPTEG_FROM_L31_ECO_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's ECO L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x300F6", + "EventName": "PM_L1_DCACHE_RELOAD_VALID", + "BriefDescription": "DL1 reloaded due to Demand Load" + }, + {, + "EventCode": "0x1415E", + "EventName": "PM_MRK_DATA_FROM_L3MISS_CYC", + "BriefDescription": "Duration in cycles to reload from a location other than the local core's L3 due to a marked load" + }, + {, + "EventCode": "0x1E052", + "EventName": "PM_CMPLU_STALL_SLB", + "BriefDescription": "Finish stall because the NTF instruction was awaiting L2 response for an SLB" + }, + {, + "EventCode": "0x4404C", + "EventName": "PM_INST_FROM_DMEM", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's memory on the same Node or Group (Distant) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3000E", + "EventName": "PM_FXU_1PLUS_BUSY", + "BriefDescription": "At least one of the 4 FXU units is busy" + }, + {, + "EventCode": "0x2C048", + "EventName": "PM_DATA_FROM_LMEM", + "BriefDescription": "The processor's data cache was reloaded from the local chip's Memory due to a demand load" + }, + {, + "EventCode": "0x3000A", + "EventName": "PM_CMPLU_STALL_PM", + "BriefDescription": "Finish stall because the NTF instruction was issued to the Permute execution pipe and waiting to finish. Includes permute and decimal fixed point instructions (128 bit BCD arithmetic) + a few 128 bit fixpoint add/subtract instructions with carry. Not qualified by vector or multicycle" + }, + {, + "EventCode": "0x1504E", + "EventName": "PM_IPTEG_FROM_L2MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L2 due to a instruction side request" + }, + {, + "EventCode": "0x1C052", + "EventName": "PM_DATA_GRP_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for a demand load" + }, + {, + "EventCode": "0x30008", + "EventName": "PM_DISP_STARVED", + "BriefDescription": "Dispatched Starved" + }, + {, + "EventCode": "0x14042", + "EventName": "PM_INST_FROM_L2", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4000C", + "EventName": "PM_FREQ_UP", + "BriefDescription": "Power Management: Above Threshold A" + }, + {, + "EventCode": "0x3C050", + "EventName": "PM_DATA_SYS_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was system pump (prediction=correct) for a demand load" + }, + {, + "EventCode": "0x25040", + "EventName": "PM_IPTEG_FROM_L2_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a instruction side request" + }, + {, + "EventCode": "0x10132", + "EventName": "PM_MRK_INST_ISSUED", + "BriefDescription": "Marked instruction issued" + }, + {, + "EventCode": "0x1C046", + "EventName": "PM_DATA_FROM_L31_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x2C044", + "EventName": "PM_DATA_FROM_L31_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x2C04A", + "EventName": "PM_DATA_FROM_RL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on the same Node or Group ( Remote) due to a demand load" + }, + {, + "EventCode": "0x24044", + "EventName": "PM_INST_FROM_L31_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another core's L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4C050", + "EventName": "PM_DATA_SYS_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (system) ended up larger than Initial Pump Scope (Chip/Group) for a demand load" + }, + {, + "EventCode": "0x2C052", + "EventName": "PM_DATA_GRP_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (Group) ended up either larger or smaller than Initial Pump Scope for a demand load" + }, + {, + "EventCode": "0x2F148", + "EventName": "PM_MRK_DPTEG_FROM_LMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D01A", + "EventName": "PM_CMPLU_STALL_EIEIO", + "BriefDescription": "Finish stall because the NTF instruction is an EIEIO waiting for response from L2" + }, + {, + "EventCode": "0x4F14E", + "EventName": "PM_MRK_DPTEG_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L3 due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4F05A", + "EventName": "PM_RADIX_PWC_L4_PTE_FROM_L3", + "BriefDescription": "A Page Table Entry was reloaded to a level 4 page walk cache from the core's L3 data cache. This is the deepest level of PWC possible for a translation" + }, + {, + "EventCode": "0x1F05A", + "EventName": "PM_RADIX_PWC_L4_PTE_FROM_L2", + "BriefDescription": "A Page Table Entry was reloaded to a level 4 page walk cache from the core's L2 data cache. This is the deepest level of PWC possible for a translation" + }, + {, + "EventCode": "0x30068", + "EventName": "PM_L1_ICACHE_RELOADED_PREF", + "BriefDescription": "Counts all Icache prefetch reloads ( includes demand turned into prefetch)" + }, + {, + "EventCode": "0x4C04A", + "EventName": "PM_DATA_FROM_OFF_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a demand load" + }, + {, + "EventCode": "0x400FE", + "EventName": "PM_DATA_FROM_MEMORY", + "BriefDescription": "The processor's data cache was reloaded from a memory location including L4 from local remote or distant due to a demand load" + }, + {, + "EventCode": "0x3F058", + "EventName": "PM_RADIX_PWC_L1_PDE_FROM_L3", + "BriefDescription": "A Page Directory Entry was reloaded to a level 1 page walk cache from the core's L3 data cache" + }, + {, + "EventCode": "0x4D142", + "EventName": "PM_MRK_DATA_FROM_L3", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 due to a marked load" + }, + {, + "EventCode": "0x30050", + "EventName": "PM_SYS_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was system pump for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x30028", + "EventName": "PM_CMPLU_STALL_SPEC_FINISH", + "BriefDescription": "Finish stall while waiting for the non-speculative finish of either a stcx waiting for its result or a load waiting for non-critical sectors of data and ECC" + }, + {, + "EventCode": "0x400F4", + "EventName": "PM_RUN_PURR", + "BriefDescription": "Run_PURR" + }, + {, + "EventCode": "0x3404C", + "EventName": "PM_INST_FROM_DL4", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's L4 on a different Node or Group (Distant) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3D05A", + "EventName": "PM_NTC_ISSUE_HELD_OTHER", + "BriefDescription": "The NTC instruction is being held at dispatch during regular pipeline cycles, or because the VSU is busy with multi-cycle instructions, or because of a write-back collision with VSU" + }, + {, + "EventCode": "0x2E048", + "EventName": "PM_DPTEG_FROM_LMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2D02A", + "EventName": "PM_RADIX_PWC_L3_PDE_FROM_L2", + "BriefDescription": "A Page Directory Entry was reloaded to a level 3 page walk cache from the core's L2 data cache" + }, + {, + "EventCode": "0x1F05C", + "EventName": "PM_RADIX_PWC_L3_PDE_FROM_L3", + "BriefDescription": "A Page Directory Entry was reloaded to a level 3 page walk cache from the core's L3 data cache" + }, + {, + "EventCode": "0x4D04A", + "EventName": "PM_DARQ0_0_3_ENTRIES", + "BriefDescription": "Cycles in which 3 or less DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x1404C", + "EventName": "PM_INST_FROM_LL4", + "BriefDescription": "The processor's Instruction cache was reloaded from the local chip's L4 cache due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x200FD", + "EventName": "PM_L1_ICACHE_MISS", + "BriefDescription": "Demand iCache Miss" + }, + {, + "EventCode": "0x34040", + "EventName": "PM_INST_FROM_L2_DISP_CONFLICT_LDHITST", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 with load hit store conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x20138", + "EventName": "PM_MRK_ST_NEST", + "BriefDescription": "Marked store sent to nest" + }, + {, + "EventCode": "0x44048", + "EventName": "PM_INST_FROM_DL2L3_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x35046", + "EventName": "PM_IPTEG_FROM_L21_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L2 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x4C04E", + "EventName": "PM_DATA_FROM_L3MISS_MOD", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L3 due to a demand load" + }, + {, + "EventCode": "0x401E0", + "EventName": "PM_MRK_INST_CMPL", + "BriefDescription": "marked instruction completed" + }, + {, + "EventCode": "0x2C128", + "EventName": "PM_MRK_DATA_FROM_DL2L3_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0x34044", + "EventName": "PM_INST_FROM_L31_ECO_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another core's ECO L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4E018", + "EventName": "PM_CMPLU_STALL_NTC_DISP_FIN", + "BriefDescription": "Finish stall because the NTF instruction was one that must finish at dispatch." + }, + {, + "EventCode": "0x2E05E", + "EventName": "PM_LMQ_EMPTY_CYC", + "BriefDescription": "Cycles in which the LMQ has no pending load misses for this thread" + }, + {, + "EventCode": "0x4C122", + "EventName": "PM_DARQ1_0_3_ENTRIES", + "BriefDescription": "Cycles in which 3 or fewer DARQ1 entries (out of 12) are in use" + }, + {, + "EventCode": "0x4F058", + "EventName": "PM_RADIX_PWC_L2_PTE_FROM_L3", + "BriefDescription": "A Page Table Entry was reloaded to a level 2 page walk cache from the core's L3 data cache. This implies that level 3 and level 4 PWC accesses were not necessary for this translation" + }, + {, + "EventCode": "0x14046", + "EventName": "PM_INST_FROM_L31_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another core's L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3012C", + "EventName": "PM_MRK_ST_FWD", + "BriefDescription": "Marked st forwards" + }, + {, + "EventCode": "0x101E0", + "EventName": "PM_MRK_INST_DISP", + "BriefDescription": "The thread has dispatched a randomly sampled marked instruction" + }, + {, + "EventCode": "0x1D058", + "EventName": "PM_DARQ0_10_12_ENTRIES", + "BriefDescription": "Cycles in which 10 or more DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x300FE", + "EventName": "PM_DATA_FROM_L3MISS", + "BriefDescription": "Demand LD - L3 Miss (not L2 hit and not L3 hit)" + }, + {, + "EventCode": "0x30006", + "EventName": "PM_CMPLU_STALL_OTHER_CMPL", + "BriefDescription": "Instructions the core completed while this tread was stalled" + }, + {, + "EventCode": "0x1005C", + "EventName": "PM_CMPLU_STALL_DP", + "BriefDescription": "Finish stall because the NTF instruction was a scalar instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Not qualified multicycle. Qualified by NOT vector" + }, + {, + "EventCode": "0x1E042", + "EventName": "PM_DPTEG_FROM_L2", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1016E", + "EventName": "PM_MRK_BR_CMPL", + "BriefDescription": "Branch Instruction completed" + }, + {, + "EventCode": "0x2013A", + "EventName": "PM_MRK_BRU_FIN", + "BriefDescription": "bru marked instr finish" + }, + {, + "EventCode": "0x4F05E", + "EventName": "PM_RADIX_PWC_L3_PTE_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was reloaded to a level 3 page walk cache from beyond the core's L3 data cache. This implies that a level 4 PWC access was not necessary for this translation. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x400FC", + "EventName": "PM_ITLB_MISS", + "BriefDescription": "ITLB Reloaded. Counts 1 per ITLB miss for HPT but multiple for radix depending on number of levels traveresed" + }, + {, + "EventCode": "0x2D024", + "EventName": "PM_RADIX_PWC_L2_HIT", + "BriefDescription": "A radix translation attempt missed in the TLB but hit on both the first and second levels of page walk cache." + }, + {, + "EventCode": "0x3F056", + "EventName": "PM_RADIX_PWC_L3_HIT", + "BriefDescription": "A radix translation attempt missed in the TLB but hit on the first, second, and third levels of page walk cache." + }, + {, + "EventCode": "0x4E014", + "EventName": "PM_TM_TX_PASS_RUN_INST", + "BriefDescription": "Run instructions spent in successful transactions" + }, + {, + "EventCode": "0x1E044", + "EventName": "PM_DPTEG_FROM_L3_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without conflict due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D05A", + "EventName": "PM_NON_MATH_FLOP_CMPL", + "BriefDescription": "Non FLOP operation completed" + }, + {, + "EventCode": "0x101E2", + "EventName": "PM_MRK_BR_TAKEN_CMPL", + "BriefDescription": "Marked Branch Taken completed" + }, + {, + "EventCode": "0x3E158", + "EventName": "PM_MRK_STCX_FAIL", + "BriefDescription": "marked stcx failed" + }, + {, + "EventCode": "0x1C048", + "EventName": "PM_DATA_FROM_ON_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x1C054", + "EventName": "PM_DATA_PUMP_CPRED", + "BriefDescription": "Pump prediction correct. Counts across all types of pumps for a demand load" + }, + {, + "EventCode": "0x4405E", + "EventName": "PM_DARQ_STORE_REJECT", + "BriefDescription": "The DARQ attempted to transmit a store into an LSAQ or SRQ entry but It was rejected. Divide by PM_DARQ_STORE_XMIT to get reject ratio" + }, + {, + "EventCode": "0x1C042", + "EventName": "PM_DATA_FROM_L2", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 due to a demand load" + }, + {, + "EventCode": "0x1D14C", + "EventName": "PM_MRK_DATA_FROM_LL4", + "BriefDescription": "The processor's data cache was reloaded from the local chip's L4 cache due to a marked load" + }, + {, + "EventCode": "0x1006C", + "EventName": "PM_RUN_CYC_ST_MODE", + "BriefDescription": "Cycles run latch is set and core is in ST mode" + }, + {, + "EventCode": "0x3C044", + "EventName": "PM_DATA_FROM_L31_ECO_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's ECO L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x4C052", + "EventName": "PM_DATA_PUMP_MPRED", + "BriefDescription": "Pump misprediction. Counts across all types of pumps for a demand load" + }, + {, + "EventCode": "0x20050", + "EventName": "PM_GRP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope and data sourced across this scope was group pump for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x1F150", + "EventName": "PM_MRK_ST_L2DISP_TO_CMPL_CYC", + "BriefDescription": "cycles from L2 rc disp to l2 rc completion" + }, + {, + "EventCode": "0x4505A", + "EventName": "PM_SP_FLOP_CMPL", + "BriefDescription": "SP instruction completed" + }, + {, + "EventCode": "0x4000A", + "EventName": "PM_ISQ_36_44_ENTRIES", + "BriefDescription": "Cycles in which 36 or more Issue Queue entries are in use. This is a shared event, not per thread. There are 44 issue queue entries across 4 slices in the whole core" + }, + {, + "EventCode": "0x2C12E", + "EventName": "PM_MRK_DATA_FROM_LL4_CYC", + "BriefDescription": "Duration in cycles to reload from the local chip's L4 cache due to a marked load" + }, + {, + "EventCode": "0x2C058", + "EventName": "PM_MEM_PREF", + "BriefDescription": "Memory prefetch for this thread. Includes L4" + }, + {, + "EventCode": "0x40012", + "EventName": "PM_L1_ICACHE_RELOADED_ALL", + "BriefDescription": "Counts all Icache reloads includes demand, prefetch, prefetch turned into demand and demand turned into prefetch" + }, + {, + "EventCode": "0x4003C", + "EventName": "PM_DISP_HELD_SYNC_HOLD", + "BriefDescription": "Cycles in which dispatch is held because of a synchronizing instruction in the pipeline" + }, + {, + "EventCode": "0x3003C", + "EventName": "PM_CMPLU_STALL_NESTED_TEND", + "BriefDescription": "Completion stall because the ISU is updating the TEXASR to keep track of the nested tend and decrement the TEXASR nested level. This is a short delay" + }, + {, + "EventCode": "0x3D05C", + "EventName": "PM_DISP_HELD_HB_FULL", + "BriefDescription": "Dispatch held due to History Buffer full. Could be GPR/VSR/VMR/FPR/CR/XVF; CR; XVF (XER/VSCR/FPSCR)" + }, + {, + "EventCode": "0x30052", + "EventName": "PM_SYS_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (system) mispredicted. Either the original scope was too small (Chip/Group) or the original scope was System and it should have been smaller. Counts for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x2E044", + "EventName": "PM_DPTEG_FROM_L31_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x34048", + "EventName": "PM_INST_FROM_DL2L3_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x45042", + "EventName": "PM_IPTEG_FROM_L3", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 due to a instruction side request" + }, + {, + "EventCode": "0x15042", + "EventName": "PM_IPTEG_FROM_L2", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 due to a instruction side request" + }, + {, + "EventCode": "0x1C05E", + "EventName": "PM_MEM_LOC_THRESH_LSU_MED", + "BriefDescription": "Local memory above threshold for data prefetch" + }, + {, + "EventCode": "0x40134", + "EventName": "PM_MRK_INST_TIMEO", + "BriefDescription": "marked Instruction finish timeout (instruction lost)" + }, + {, + "EventCode": "0x1002C", + "EventName": "PM_L1_DCACHE_RELOADED_ALL", + "BriefDescription": "L1 data cache reloaded for demand. If MMCR1[16] is 1, prefetches will be included as well" + }, + {, + "EventCode": "0x30130", + "EventName": "PM_MRK_INST_FIN", + "BriefDescription": "marked instruction finished" + }, + {, + "EventCode": "0x1F14A", + "EventName": "PM_MRK_DPTEG_FROM_RL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3504E", + "EventName": "PM_DARQ0_4_6_ENTRIES", + "BriefDescription": "Cycles in which 4, 5, or 6 DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x30064", + "EventName": "PM_DARQ_STORE_XMIT", + "BriefDescription": "The DARQ attempted to transmit a store into an LSAQ or SRQ entry. Includes rejects. Not qualified by thread, so it includes counts for the whole core" + }, + {, + "EventCode": "0x45046", + "EventName": "PM_IPTEG_FROM_L21_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L2 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x2C016", + "EventName": "PM_CMPLU_STALL_PASTE", + "BriefDescription": "Finish stall because the NTF instruction was a paste waiting for response from L2" + }, + {, + "EventCode": "0x24156", + "EventName": "PM_MRK_STCX_FIN", + "BriefDescription": "Number of marked stcx instructions finished. This includes instructions in the speculative path of a branch that may be flushed" + }, + {, + "EventCode": "0x15150", + "EventName": "PM_SYNC_MRK_PROBE_NOP", + "BriefDescription": "Marked probeNops which can cause synchronous interrupts" + }, + {, + "EventCode": "0x301E4", + "EventName": "PM_MRK_BR_MPRED_CMPL", + "BriefDescription": "Marked Branch Mispredicted" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/memory.json b/tools/perf/pmu-events/arch/powerpc/power9/memory.json new file mode 100644 index 0000000000000000000000000000000000000000..9960d1c0dd4401ffb4050ecd5b16c655c787d514 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/memory.json @@ -0,0 +1,132 @@ +[ + {, + "EventCode": "0x3006E", + "EventName": "PM_NEST_REF_CLK", + "BriefDescription": "Multiply by 4 to obtain the number of PB cycles" + }, + {, + "EventCode": "0x20010", + "EventName": "PM_PMC1_OVERFLOW", + "BriefDescription": "Overflow from counter 1" + }, + {, + "EventCode": "0x2005A", + "EventName": "PM_DARQ1_7_9_ENTRIES", + "BriefDescription": "Cycles in which 7 to 9 DARQ1 entries (out of 12) are in use" + }, + {, + "EventCode": "0x3C048", + "EventName": "PM_DATA_FROM_DL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a demand load" + }, + {, + "EventCode": "0x10008", + "EventName": "PM_RUN_SPURR", + "BriefDescription": "Run SPURR" + }, + {, + "EventCode": "0x200F6", + "EventName": "PM_LSU_DERAT_MISS", + "BriefDescription": "DERAT Reloaded due to a DERAT miss" + }, + {, + "EventCode": "0x4C048", + "EventName": "PM_DATA_FROM_DL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a demand load" + }, + {, + "EventCode": "0x1D15E", + "EventName": "PM_MRK_RUN_CYC", + "BriefDescription": "Run cycles in which a marked instruction is in the pipeline" + }, + {, + "EventCode": "0x4003E", + "EventName": "PM_LD_CMPL", + "BriefDescription": "count of Loads completed" + }, + {, + "EventCode": "0x2D156", + "EventName": "PM_MRK_DTLB_MISS_4K", + "BriefDescription": "Marked Data TLB Miss page size 4k" + }, + {, + "EventCode": "0x4C042", + "EventName": "PM_DATA_FROM_L3", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 due to a demand load" + }, + {, + "EventCode": "0x4D02C", + "EventName": "PM_PMC1_REWIND", + "BriefDescription": "" + }, + {, + "EventCode": "0x15158", + "EventName": "PM_SYNC_MRK_L2HIT", + "BriefDescription": "Marked L2 Hits that can throw a synchronous interrupt" + }, + {, + "EventCode": "0x3404A", + "EventName": "PM_INST_FROM_RMEM", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's memory on the same Node or Group ( Remote) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x301E2", + "EventName": "PM_MRK_ST_CMPL", + "BriefDescription": "Marked store completed and sent to nest" + }, + {, + "EventCode": "0x1C050", + "EventName": "PM_DATA_CHIP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was chip pump (prediction=correct) for a demand load" + }, + {, + "EventCode": "0x4C040", + "EventName": "PM_DATA_FROM_L2_DISP_CONFLICT_OTHER", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with dispatch conflict due to a demand load" + }, + {, + "EventCode": "0x2E05C", + "EventName": "PM_LSU_REJECT_ERAT_MISS", + "BriefDescription": "LSU Reject due to ERAT (up to 4 per cycles)" + }, + {, + "EventCode": "0x1000A", + "EventName": "PM_PMC3_REWIND", + "BriefDescription": "PMC3 rewind event. A rewind happens when a speculative event (such as latency or CPI stack) is selected on PMC3 and the stall reason or reload source did not match the one programmed in PMC3. When this occurs, the count in PMC3 will not change." + }, + {, + "EventCode": "0x3C058", + "EventName": "PM_LARX_FIN", + "BriefDescription": "Larx finished" + }, + {, + "EventCode": "0x1C040", + "EventName": "PM_DATA_FROM_L2_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 without conflict due to a demand load" + }, + {, + "EventCode": "0x2C040", + "EventName": "PM_DATA_FROM_L2_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state due to a demand load" + }, + {, + "EventCode": "0x2E05A", + "EventName": "PM_LRQ_REJECT", + "BriefDescription": "Internal LSU reject from LRQ. Rejects cause the load to go back to LRQ, but it stays contained within the LSU once it gets issued. This event counts the number of times the LRQ attempts to relaunch an instruction after a reject. Any load can suffer multiple rejects" + }, + {, + "EventCode": "0x2C05C", + "EventName": "PM_INST_GRP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was group pump (prediction=correct) for an instruction fetch (demand only)" + }, + {, + "EventCode": "0x4D056", + "EventName": "PM_NON_FMA_FLOP_CMPL", + "BriefDescription": "Non FMA instruction completed" + }, + {, + "EventCode": "0x3E050", + "EventName": "PM_DARQ1_4_6_ENTRIES", + "BriefDescription": "Cycles in which 4, 5, or 6 DARQ1 entries (out of 12) are in use" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/powerpc/power9/other.json b/tools/perf/pmu-events/arch/powerpc/power9/other.json new file mode 100644 index 0000000000000000000000000000000000000000..54cc3be00fc2d84903ce127eb9554ec7054dd9ed --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/other.json @@ -0,0 +1,2392 @@ +[ + {, + "EventCode": "0x3084", + "EventName": "PM_ISU1_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0xF880", + "EventName": "PM_SNOOP_TLBIE", + "BriefDescription": "TLBIE snoop" + }, + {, + "EventCode": "0x4088", + "EventName": "PM_IC_DEMAND_REQ", + "BriefDescription": "Demand Instruction fetch request" + }, + {, + "EventCode": "0x20A4", + "EventName": "PM_TM_TRESUME", + "BriefDescription": "TM resume instruction completed" + }, + {, + "EventCode": "0x40008", + "EventName": "PM_SRQ_EMPTY_CYC", + "BriefDescription": "Cycles in which the SRQ has at least one (out of four) empty slice" + }, + {, + "EventCode": "0x20064", + "EventName": "PM_IERAT_RELOAD_4K", + "BriefDescription": "IERAT reloaded (after a miss) for 4K pages" + }, + {, + "EventCode": "0x260B4", + "EventName": "PM_L3_P2_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 2 (can try 4 times)" + }, + {, + "EventCode": "0x20006", + "EventName": "PM_DISP_HELD_ISSQ_FULL", + "BriefDescription": "Dispatch held due to Issue q full. Includes issue queue and branch queue" + }, + {, + "EventCode": "0x201E4", + "EventName": "PM_MRK_DATA_FROM_L3MISS", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L3 due to a marked load" + }, + {, + "EventCode": "0x4E044", + "EventName": "PM_DPTEG_FROM_L31_ECO_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40B8", + "EventName": "PM_BR_MPRED_TAKEN_CR", + "BriefDescription": "A Conditional Branch that resolved to taken was mispredicted as not taken (due to the BHT Direction Prediction)." + }, + {, + "EventCode": "0xF8AC", + "EventName": "PM_DC_DEALLOC_NO_CONF", + "BriefDescription": "A demand load referenced a line in an active fuzzy prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software.Fuzzy stream confirm (out of order effects, or pf cant keep up)" + }, + {, + "EventCode": "0xD090", + "EventName": "PM_LS0_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x40BC", + "EventName": "PM_THRD_PRIO_0_1_CYC", + "BriefDescription": "Cycles thread running at priority level 0 or 1" + }, + {, + "EventCode": "0x2084", + "EventName": "PM_FLUSH_HB_RESTORE_CYC", + "BriefDescription": "Cycles in which no new instructions can be dispatched to the ICT after a flush. History buffer recovery" + }, + {, + "EventCode": "0x4F054", + "EventName": "PM_RADIX_PWC_MISS", + "BriefDescription": "A radix translation attempt missed in the TLB and all levels of page walk cache." + }, + {, + "EventCode": "0x24048", + "EventName": "PM_INST_FROM_LMEM", + "BriefDescription": "The processor's Instruction cache was reloaded from the local chip's Memory due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0xD8B4", + "EventName": "PM_LSU0_LRQ_S0_VALID_CYC", + "BriefDescription": "Slot 0 of LRQ valid" + }, + {, + "EventCode": "0x2E052", + "EventName": "PM_TM_PASSED", + "BriefDescription": "Number of TM transactions that passed" + }, + {, + "EventCode": "0xD1A0", + "EventName": "PM_MRK_LSU_FLUSH_LHS", + "BriefDescription": "Effective Address alias flush : no EA match but Real Address match. If the data has not yet been returned for this load, the instruction will just be rejected, but if it has returned data, it will be flushed" + }, + {, + "EventCode": "0xF088", + "EventName": "PM_LSU0_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x360B2", + "EventName": "PM_L3_GRP_GUESS_WRONG_LOW", + "BriefDescription": "Initial scope=group (GS or NNS) but data from outside group (far or rem). Prediction too Low" + }, + {, + "EventCode": "0x168A6", + "EventName": "PM_TM_CAM_OVERFLOW", + "BriefDescription": "L3 TM cam overflow during L2 co of SC" + }, + {, + "EventCode": "0xE8B0", + "EventName": "PM_TEND_PEND_CYC", + "BriefDescription": "TEND latency per thread" + }, + {, + "EventCode": "0x4884", + "EventName": "PM_IBUF_FULL_CYC", + "BriefDescription": "Cycles No room in ibuff" + }, + {, + "EventCode": "0xD08C", + "EventName": "PM_LSU2_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])" + }, + {, + "EventCode": "0x300F8", + "EventName": "PM_TB_BIT_TRANS", + "BriefDescription": "timebase event" + }, + {, + "EventCode": "0x3C040", + "EventName": "PM_DATA_FROM_L2_DISP_CONFLICT_LDHITST", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with load hit store conflict due to a demand load" + }, + {, + "EventCode": "0xE0BC", + "EventName": "PM_LS0_PTE_TABLEWALK_CYC", + "BriefDescription": "Cycles when a tablewalk is pending on this thread on table 0" + }, + {, + "EventCode": "0x3884", + "EventName": "PM_ISU3_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0x460A6", + "EventName": "PM_RD_FORMING_SC", + "BriefDescription": "Read forming SC" + }, + {, + "EventCode": "0x468A0", + "EventName": "PM_L3_PF_OFF_CHIP_MEM", + "BriefDescription": "L3 PF from Off chip memory" + }, + {, + "EventCode": "0x268AA", + "EventName": "PM_L3_P1_LCO_DATA", + "BriefDescription": "LCO sent with data port 1" + }, + {, + "EventCode": "0xE894", + "EventName": "PM_LSU1_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x5888", + "EventName": "PM_IC_INVALIDATE", + "BriefDescription": "Ic line invalidated" + }, + {, + "EventCode": "0x2890", + "EventName": "PM_DISP_CLB_HELD_TLBIE", + "BriefDescription": "Dispatch Hold: Due to TLBIE" + }, + {, + "EventCode": "0x1001C", + "EventName": "PM_CMPLU_STALL_THRD", + "BriefDescription": "Completion Stalled because the thread was blocked" + }, + {, + "EventCode": "0x368A6", + "EventName": "PM_SNP_TM_HIT_T", + "BriefDescription": "Snp TM sthit T/Tn/Te" + }, + {, + "EventCode": "0x3001A", + "EventName": "PM_DATA_TABLEWALK_CYC", + "BriefDescription": "Data Tablewalk Cycles. Could be 1 or 2 active tablewalks. Includes data prefetches." + }, + {, + "EventCode": "0xD894", + "EventName": "PM_LS3_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x35158", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0xF0B4", + "EventName": "PM_DC_PREF_CONS_ALLOC", + "BriefDescription": "Prefetch stream allocated in the conservative phase by either the hardware prefetch mechanism or software prefetch" + }, + {, + "EventCode": "0xF894", + "EventName": "PM_LSU3_L1_CAM_CANCEL", + "BriefDescription": "ls3 l1 tm cam cancel" + }, + {, + "EventCode": "0x2888", + "EventName": "PM_FLUSH_DISP_TLBIE", + "BriefDescription": "Dispatch Flush: TLBIE" + }, + {, + "EventCode": "0xD1A4", + "EventName": "PM_MRK_LSU_FLUSH_SAO", + "BriefDescription": "A load-hit-load condition with Strong Address Ordering will have address compare disabled and flush" + }, + {, + "EventCode": "0x4E11E", + "EventName": "PM_MRK_DATA_FROM_DMEM_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's memory on the same Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x5894", + "EventName": "PM_LWSYNC", + "BriefDescription": "Lwsync instruction decoded and transferred" + }, + {, + "EventCode": "0x14156", + "EventName": "PM_MRK_DATA_FROM_L2_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 due to a marked load" + }, + {, + "EventCode": "0x468A6", + "EventName": "PM_RD_CLEARING_SC", + "BriefDescription": "Read clearing SC" + }, + {, + "EventCode": "0x50A0", + "EventName": "PM_HWSYNC", + "BriefDescription": "Hwsync instruction decoded and transferred" + }, + {, + "EventCode": "0x168B0", + "EventName": "PM_L3_P1_NODE_PUMP", + "BriefDescription": "L3 PF sent with nodal scope port 1, counts even retried requests" + }, + {, + "EventCode": "0xD0BC", + "EventName": "PM_LSU0_1_LRQF_FULL_CYC", + "BriefDescription": "Counts the number of cycles the LRQF is full. LRQF is the queue that holds loads between finish and completion. If it fills up, instructions stay in LRQ until completion, potentially backing up the LRQ" + }, + {, + "EventCode": "0x2D148", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_LDHITST", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with load hit store conflict due to a marked load" + }, + {, + "EventCode": "0x460A8", + "EventName": "PM_SN_HIT", + "BriefDescription": "Any port snooper hit L3. Up to 4 can happen in a cycle but we only count 1" + }, + {, + "EventCode": "0x360AA", + "EventName": "PM_L3_P0_CO_MEM", + "BriefDescription": "L3 CO to memory port 0 with or without data" + }, + {, + "EventCode": "0xF0A4", + "EventName": "PM_DC_PREF_HW_ALLOC", + "BriefDescription": "Prefetch stream allocated by the hardware prefetch mechanism" + }, + {, + "EventCode": "0xF0BC", + "EventName": "PM_LS2_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0xD0AC", + "EventName": "PM_SRQ_SYNC_CYC", + "BriefDescription": "A sync is in the S2Q (edge detect to count)" + }, + {, + "EventCode": "0x401E6", + "EventName": "PM_MRK_INST_FROM_L3MISS", + "BriefDescription": "Marked instruction was reloaded from a location beyond the local chiplet" + }, + {, + "EventCode": "0x26082", + "EventName": "PM_L2_IC_INV", + "BriefDescription": "I-cache Invalidates sent over the realod bus to the core" + }, + {, + "EventCode": "0xC8AC", + "EventName": "PM_LSU_FLUSH_RELAUNCH_MISS", + "BriefDescription": "If a load that has already returned data and has to relaunch for any reason then gets a miss (erat, setp, data cache), it will often be flushed at relaunch time because the data might be inconsistent" + }, + {, + "EventCode": "0x260A4", + "EventName": "PM_L3_LD_HIT", + "BriefDescription": "L3 Hits for demand LDs" + }, + {, + "EventCode": "0xF0A0", + "EventName": "PM_DATA_STORE", + "BriefDescription": "All ops that drain from s2q to L2 containing data" + }, + {, + "EventCode": "0x1D148", + "EventName": "PM_MRK_DATA_FROM_RMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x16088", + "EventName": "PM_L2_LOC_GUESS_CORRECT", + "BriefDescription": "L2 guess local (LNS) and guess was correct (ie data local)" + }, + {, + "EventCode": "0x160A4", + "EventName": "PM_L3_HIT", + "BriefDescription": "L3 Hits (L2 miss hitting L3, including data/instrn/xlate)" + }, + {, + "EventCode": "0xE09C", + "EventName": "PM_LSU0_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x168B4", + "EventName": "PM_L3_P1_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 1 (can try 4 times)" + }, + {, + "EventCode": "0x268AC", + "EventName": "PM_L3_RD_USAGE", + "BriefDescription": "Rotating sample of 16 RD actives" + }, + {, + "EventCode": "0x1415C", + "EventName": "PM_MRK_DATA_FROM_L3_MEPF_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 without dispatch conflicts hit on Mepf state due to a marked load" + }, + {, + "EventCode": "0xE880", + "EventName": "PM_L1_SW_PREF", + "BriefDescription": "Software L1 Prefetches, including SW Transient Prefetches" + }, + {, + "EventCode": "0x288C", + "EventName": "PM_DISP_CLB_HELD_BAL", + "BriefDescription": "Dispatch/CLB Hold: Balance Flush" + }, + {, + "EventCode": "0x101EA", + "EventName": "PM_MRK_L1_RELOAD_VALID", + "BriefDescription": "Marked demand reload" + }, + {, + "EventCode": "0x1D156", + "EventName": "PM_MRK_LD_MISS_L1_CYC", + "BriefDescription": "Marked ld latency" + }, + {, + "EventCode": "0x4C01A", + "EventName": "PM_CMPLU_STALL_DMISS_L3MISS", + "BriefDescription": "Completion stall due to cache miss resolving missed the L3" + }, + {, + "EventCode": "0x2006C", + "EventName": "PM_RUN_CYC_SMT4_MODE", + "BriefDescription": "Cycles in which this thread's run latch is set and the core is in SMT4 mode" + }, + {, + "EventCode": "0x5088", + "EventName": "PM_DECODE_FUSION_OP_PRESERV", + "BriefDescription": "Destructive op operand preservation" + }, + {, + "EventCode": "0x1D14E", + "EventName": "PM_MRK_DATA_FROM_OFF_CHIP_CACHE_CYC", + "BriefDescription": "Duration in cycles to reload either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a marked load" + }, + {, + "EventCode": "0x509C", + "EventName": "PM_FORCED_NOP", + "BriefDescription": "Instruction was forced to execute as a nop because it was found to behave like a nop (have no effect) at decode time" + }, + {, + "EventCode": "0xC098", + "EventName": "PM_LS2_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x20058", + "EventName": "PM_DARQ1_10_12_ENTRIES", + "BriefDescription": "Cycles in which 10 or more DARQ1 entries (out of 12) are in use" + }, + {, + "EventCode": "0x360A6", + "EventName": "PM_SNP_TM_HIT_M", + "BriefDescription": "Snp TM st hit M/Mu" + }, + {, + "EventCode": "0x5898", + "EventName": "PM_LINK_STACK_INVALID_PTR", + "BriefDescription": "It is most often caused by certain types of flush where the pointer is not available. Can result in the data in the link stack becoming unusable." + }, + {, + "EventCode": "0x46088", + "EventName": "PM_L2_CHIP_PUMP", + "BriefDescription": "RC requests that were local (aka chip) pump attempts" + }, + {, + "EventCode": "0x28A0", + "EventName": "PM_TM_TSUSPEND", + "BriefDescription": "TM suspend instruction completed" + }, + {, + "EventCode": "0x20054", + "EventName": "PM_L1_PREF", + "BriefDescription": "A data line was written to the L1 due to a hardware or software prefetch" + }, + {, + "EventCode": "0xF888", + "EventName": "PM_LSU1_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x4505E", + "EventName": "PM_FLOP_CMPL", + "BriefDescription": "Floating Point Operation Finished" + }, + {, + "EventCode": "0x1D144", + "EventName": "PM_MRK_DATA_FROM_L3_DISP_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0x400FA", + "EventName": "PM_RUN_INST_CMPL", + "BriefDescription": "Run_Instructions" + }, + {, + "EventCode": "0x15154", + "EventName": "PM_SYNC_MRK_L3MISS", + "BriefDescription": "Marked L3 misses that can throw a synchronous interrupt" + }, + {, + "EventCode": "0xE0B4", + "EventName": "PM_LS0_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x26884", + "EventName": "PM_DSIDE_MRU_TOUCH", + "BriefDescription": "D-side L2 MRU touch sent to L2" + }, + {, + "EventCode": "0x30134", + "EventName": "PM_MRK_ST_CMPL_INT", + "BriefDescription": "marked store finished with intervention" + }, + {, + "EventCode": "0xC0B8", + "EventName": "PM_LSU_FLUSH_SAO", + "BriefDescription": "A load-hit-load condition with Strong Address Ordering will have address compare disabled and flush" + }, + {, + "EventCode": "0x50A8", + "EventName": "PM_EAT_FORCE_MISPRED", + "BriefDescription": "XL-form branch was mispredicted due to the predicted target address missing from EAT. The EAT forces a mispredict in this case since there is no predicated target to validate. This is a rare case that may occur when the EAT is full and a branch is issued" + }, + {, + "EventCode": "0xC094", + "EventName": "PM_LS0_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0xF8BC", + "EventName": "PM_LS3_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x58B0", + "EventName": "PM_BTAC_GOOD_RESULT", + "BriefDescription": "BTAC predicts a taken branch and the BHT agrees, and the target address is correct" + }, + {, + "EventCode": "0x1C04C", + "EventName": "PM_DATA_FROM_LL4", + "BriefDescription": "The processor's data cache was reloaded from the local chip's L4 cache due to a demand load" + }, + {, + "EventCode": "0x3608E", + "EventName": "PM_TM_ST_CONF", + "BriefDescription": "TM Store (fav or non-fav) ran into conflict (failed)" + }, + {, + "EventCode": "0xD998", + "EventName": "PM_MRK_LSU_FLUSH_EMSH", + "BriefDescription": "An ERAT miss was detected after a set-p hit. Erat tracker indicates fail due to tlbmiss and the instruction gets flushed because the instruction was working on the wrong address" + }, + {, + "EventCode": "0xF8A0", + "EventName": "PM_NON_DATA_STORE", + "BriefDescription": "All ops that drain from s2q to L2 and contain no data" + }, + {, + "EventCode": "0x3F146", + "EventName": "PM_MRK_DPTEG_FROM_L21_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L2 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40A0", + "EventName": "PM_BR_UNCOND", + "BriefDescription": "Unconditional Branch Completed. HW branch prediction was not used for this branch. This can be an I-form branch, a B-form branch with BO-field set to branch always, or a B-form branch which was covenrted to a Resolve." + }, + {, + "EventCode": "0x1F056", + "EventName": "PM_RADIX_PWC_L1_HIT", + "BriefDescription": "A radix translation attempt missed in the TLB and only the first level page walk cache was a hit." + }, + {, + "EventCode": "0xF8A8", + "EventName": "PM_DC_PREF_FUZZY_CONF", + "BriefDescription": "A demand load referenced a line in an active fuzzy prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software.Fuzzy stream confirm (out of order effects, or pf cant keep up)" + }, + {, + "EventCode": "0xF8A4", + "EventName": "PM_DC_PREF_SW_ALLOC", + "BriefDescription": "Prefetch stream allocated by software prefetching" + }, + {, + "EventCode": "0xE0A0", + "EventName": "PM_LSU2_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x2894", + "EventName": "PM_TM_OUTER_TEND", + "BriefDescription": "Completion time outer tend" + }, + {, + "EventCode": "0xF098", + "EventName": "PM_XLATE_HPT_MODE", + "BriefDescription": "LSU reports every cycle the thread is in HPT translation mode (as opposed to radix mode)" + }, + {, + "EventCode": "0x2C04E", + "EventName": "PM_LD_MISS_L1_FIN", + "BriefDescription": "Number of load instructions that finished with an L1 miss. Note that even if a load spans multiple slices this event will increment only once per load op." + }, + {, + "EventCode": "0x30162", + "EventName": "PM_MRK_LSU_DERAT_MISS", + "BriefDescription": "Marked derat reload (miss) for any page size" + }, + {, + "EventCode": "0x160A0", + "EventName": "PM_L3_PF_MISS_L3", + "BriefDescription": "L3 PF missed in L3" + }, + {, + "EventCode": "0x1C04A", + "EventName": "PM_DATA_FROM_RL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a demand load" + }, + {, + "EventCode": "0xD99C", + "EventName": "PM_MRK_LSU_FLUSH_UE", + "BriefDescription": "Correctable ECC error on reload data, reported at critical data forward time" + }, + {, + "EventCode": "0x268B0", + "EventName": "PM_L3_P1_GRP_PUMP", + "BriefDescription": "L3 PF sent with grp scope port 1, counts even retried requests" + }, + {, + "EventCode": "0x30016", + "EventName": "PM_CMPLU_STALL_SRQ_FULL", + "BriefDescription": "Finish stall because the NTF instruction was a store that was held in LSAQ because the SRQ was full" + }, + {, + "EventCode": "0x40B4", + "EventName": "PM_BR_PRED_TA", + "BriefDescription": "Conditional Branch Completed that had its target address predicted. Only XL-form branches set this event. This equal the sum of CCACHE, LSTACK, and PCACHE" + }, + {, + "EventCode": "0x40AC", + "EventName": "PM_BR_MPRED_CCACHE", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to the Count Cache Target Prediction" + }, + {, + "EventCode": "0x3688A", + "EventName": "PM_L2_RTY_LD", + "BriefDescription": "RC retries on PB for any load from core (excludes DCBFs)" + }, + {, + "EventCode": "0xE08C", + "EventName": "PM_LSU0_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0xE088", + "EventName": "PM_LS2_ERAT_MISS_PREF", + "BriefDescription": "LS0 Erat miss due to prefetch" + }, + {, + "EventCode": "0xF0A8", + "EventName": "PM_DC_PREF_CONF", + "BriefDescription": "A demand load referenced a line in an active prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software. Includes forwards and backwards streams" + }, + {, + "EventCode": "0x16888", + "EventName": "PM_L2_LOC_GUESS_WRONG", + "BriefDescription": "L2 guess local (LNS) and guess was not correct (ie data not on chip)" + }, + {, + "EventCode": "0xE0A4", + "EventName": "PM_TMA_REQ_L2", + "BriefDescription": "addrs only req to L2 only on the first one,Indication that Load footprint is not expanding" + }, + {, + "EventCode": "0x5884", + "EventName": "PM_DECODE_LANES_NOT_AVAIL", + "BriefDescription": "Decode has something to transmit but dispatch lanes are not available" + }, + {, + "EventCode": "0x3C042", + "EventName": "PM_DATA_FROM_L3_DISP_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 with dispatch conflict due to a demand load" + }, + {, + "EventCode": "0x168AA", + "EventName": "PM_L3_P1_LCO_NO_DATA", + "BriefDescription": "Dataless L3 LCO sent port 1" + }, + {, + "EventCode": "0x3D140", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_OTHER_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0xC89C", + "EventName": "PM_LS1_LAUNCH_HELD_PREF", + "BriefDescription": "Number of times a load or store instruction was unable to launch/relaunch because a high priority prefetch used that relaunch cycle" + }, + {, + "EventCode": "0x4894", + "EventName": "PM_IC_RELOAD_PRIVATE", + "BriefDescription": "Reloading line was brought in private for a specific thread. Most lines are brought in shared for all eight threads. If RA does not match then invalidates and then brings it shared to other thread. In P7 line brought in private , then line was invalidat" + }, + {, + "EventCode": "0x1688E", + "EventName": "PM_TM_LD_CAUSED_FAIL", + "BriefDescription": "Non-TM Load caused any thread to fail" + }, + {, + "EventCode": "0x26084", + "EventName": "PM_L2_RCLD_DISP_FAIL_OTHER", + "BriefDescription": "All I-or-D side load dispatch attempts for this thread that failed due to reason other than address collision (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x101E4", + "EventName": "PM_MRK_L1_ICACHE_MISS", + "BriefDescription": "sampled Instruction suffered an icache Miss" + }, + {, + "EventCode": "0x20A0", + "EventName": "PM_TM_NESTED_TBEGIN", + "BriefDescription": "Completion Tm nested tbegin" + }, + {, + "EventCode": "0x368AA", + "EventName": "PM_L3_P1_CO_MEM", + "BriefDescription": "L3 CO to memory port 1 with or without data" + }, + {, + "EventCode": "0xC8A4", + "EventName": "PM_LSU3_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0xD9A4", + "EventName": "PM_MRK_LSU_FLUSH_LARX_STCX", + "BriefDescription": "A larx is flushed because an older larx has an LMQ reservation for the same thread. A stcx is flushed because an older stcx is in the LMQ. The flush happens when the older larx/stcx relaunches" + }, + {, + "EventCode": "0x4D012", + "EventName": "PM_PMC3_SAVED", + "BriefDescription": "PMC3 Rewind Value saved" + }, + {, + "EventCode": "0xE888", + "EventName": "PM_LS3_ERAT_MISS_PREF", + "BriefDescription": "LS1 Erat miss due to prefetch" + }, + {, + "EventCode": "0x368B4", + "EventName": "PM_L3_RD0_BUSY", + "BriefDescription": "Lifetime, sample of RD machine 0 valid" + }, + {, + "EventCode": "0x46080", + "EventName": "PM_L2_DISP_ALL_L2MISS", + "BriefDescription": "All successful Ld/St dispatches for this thread that were an L2 miss (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0xF8B8", + "EventName": "PM_LS1_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x408C", + "EventName": "PM_L1_DEMAND_WRITE", + "BriefDescription": "Instruction Demand sectors written into IL1" + }, + {, + "EventCode": "0x368A8", + "EventName": "PM_SN_INVL", + "BriefDescription": "Any port snooper detects a store to a line in the Sx state and invalidates the line. Up to 4 can happen in a cycle but we only count 1" + }, + {, + "EventCode": "0x160B2", + "EventName": "PM_L3_LOC_GUESS_CORRECT", + "BriefDescription": "initial scope=node/chip (LNS) and data from local node (local) (pred successful) - always PFs only" + }, + {, + "EventCode": "0x48B4", + "EventName": "PM_DECODE_FUSION_CONST_GEN", + "BriefDescription": "32-bit constant generation" + }, + {, + "EventCode": "0x4D146", + "EventName": "PM_MRK_DATA_FROM_L21_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L2 on the same chip due to a marked load" + }, + {, + "EventCode": "0xE080", + "EventName": "PM_S2Q_FULL", + "BriefDescription": "Cycles during which the S2Q is full" + }, + {, + "EventCode": "0x268B4", + "EventName": "PM_L3_P3_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 3 (can try 4 times)" + }, + {, + "EventCode": "0xD8B8", + "EventName": "PM_LSU0_LMQ_S0_VALID", + "BriefDescription": "Slot 0 of LMQ valid" + }, + {, + "EventCode": "0x2098", + "EventName": "PM_TM_NESTED_TEND", + "BriefDescription": "Completion time nested tend" + }, + {, + "EventCode": "0x36084", + "EventName": "PM_L2_RCST_DISP", + "BriefDescription": "All D-side store dispatch attempts for this thread" + }, + {, + "EventCode": "0x368A0", + "EventName": "PM_L3_PF_OFF_CHIP_CACHE", + "BriefDescription": "L3 PF from Off chip cache" + }, + {, + "EventCode": "0x20056", + "EventName": "PM_TAKEN_BR_MPRED_CMPL", + "BriefDescription": "Total number of taken branches that were incorrectly predicted as not-taken. This event counts branches completed and does not include speculative instructions" + }, + {, + "EventCode": "0x4688A", + "EventName": "PM_L2_SYS_PUMP", + "BriefDescription": "RC requests that were system pump attempts" + }, + {, + "EventCode": "0xE090", + "EventName": "PM_LSU2_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0x4001C", + "EventName": "PM_INST_IMC_MATCH_CMPL", + "BriefDescription": "IMC Match Count" + }, + {, + "EventCode": "0x40A8", + "EventName": "PM_BR_PRED_LSTACK", + "BriefDescription": "Conditional Branch Completed that used the Link Stack for Target Prediction" + }, + {, + "EventCode": "0x268A2", + "EventName": "PM_L3_CI_MISS", + "BriefDescription": "L3 castins miss (total count)" + }, + {, + "EventCode": "0x289C", + "EventName": "PM_TM_NON_FAV_TBEGIN", + "BriefDescription": "Dispatch time non favored tbegin" + }, + {, + "EventCode": "0xF08C", + "EventName": "PM_LSU2_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x360A0", + "EventName": "PM_L3_PF_ON_CHIP_CACHE", + "BriefDescription": "L3 PF from On chip cache" + }, + {, + "EventCode": "0x35152", + "EventName": "PM_MRK_DATA_FROM_L2MISS_CYC", + "BriefDescription": "Duration in cycles to reload from a location other than the local core's L2 due to a marked load" + }, + {, + "EventCode": "0x160AC", + "EventName": "PM_L3_SN_USAGE", + "BriefDescription": "Rotating sample of 16 snoop valids" + }, + {, + "EventCode": "0x16084", + "EventName": "PM_L2_RCLD_DISP", + "BriefDescription": "All I-or-D side load dispatch attempts for this thread (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x1608C", + "EventName": "PM_RC0_BUSY", + "BriefDescription": "RC mach 0 Busy. Used by PMU to sample ave RC lifetime (mach0 used as sample point)" + }, + {, + "EventCode": "0x36082", + "EventName": "PM_L2_LD_DISP", + "BriefDescription": "All successful I-or-D side load dispatches for this thread (excludes i_l2mru_tch_reqs)." + }, + {, + "EventCode": "0xF8B0", + "EventName": "PM_L3_SW_PREF", + "BriefDescription": "L3 load prefetch, sourced from a software prefetch stream, was sent to the nest" + }, + {, + "EventCode": "0xF884", + "EventName": "PM_TABLEWALK_CYC_PREF", + "BriefDescription": "tablewalk qualified for pte prefetches" + }, + {, + "EventCode": "0x4D144", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x16884", + "EventName": "PM_L2_RCLD_DISP_FAIL_ADDR", + "BriefDescription": "All I-od-D side load dispatch attempts for this thread that failed due to address collision with RC/CO/SN/SQ machine (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x460A0", + "EventName": "PM_L3_PF_ON_CHIP_MEM", + "BriefDescription": "L3 PF from On chip memory" + }, + {, + "EventCode": "0xF084", + "EventName": "PM_PTE_PREFETCH", + "BriefDescription": "PTE prefetches" + }, + {, + "EventCode": "0x2D026", + "EventName": "PM_RADIX_PWC_L1_PDE_FROM_L2", + "BriefDescription": "A Page Directory Entry was reloaded to a level 1 page walk cache from the core's L2 data cache" + }, + {, + "EventCode": "0x48B0", + "EventName": "PM_BR_MPRED_PCACHE", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to pattern cache prediction" + }, + {, + "EventCode": "0x2C126", + "EventName": "PM_MRK_DATA_FROM_L2", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 due to a marked load" + }, + {, + "EventCode": "0xE0AC", + "EventName": "PM_TM_FAIL_TLBIE", + "BriefDescription": "Transaction failed because there was a TLBIE hit in the bloom filter" + }, + {, + "EventCode": "0x260AA", + "EventName": "PM_L3_P0_LCO_DATA", + "BriefDescription": "LCO sent with data port 0" + }, + {, + "EventCode": "0x4888", + "EventName": "PM_IC_PREF_REQ", + "BriefDescription": "Instruction prefetch requests" + }, + {, + "EventCode": "0xC898", + "EventName": "PM_LS3_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x488C", + "EventName": "PM_IC_PREF_WRITE", + "BriefDescription": "Instruction prefetch written into IL1" + }, + {, + "EventCode": "0xF89C", + "EventName": "PM_XLATE_MISS", + "BriefDescription": "The LSU requested a line from L2 for translation. It may be satisfied from any source beyond L2. Includes speculative instructions" + }, + {, + "EventCode": "0x14158", + "EventName": "PM_MRK_DATA_FROM_L2_NO_CONFLICT_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 without conflict due to a marked load" + }, + {, + "EventCode": "0x35156", + "EventName": "PM_MRK_DATA_FROM_L31_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x268A6", + "EventName": "PM_TM_RST_SC", + "BriefDescription": "TM-snp rst RM SC" + }, + {, + "EventCode": "0x468A4", + "EventName": "PM_L3_TRANS_PF", + "BriefDescription": "L3 Transient prefetch received from L2" + }, + {, + "EventCode": "0x4094", + "EventName": "PM_IC_PREF_CANCEL_L2", + "BriefDescription": "L2 Squashed a demand or prefetch request" + }, + {, + "EventCode": "0x48AC", + "EventName": "PM_BR_MPRED_LSTACK", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to the Link Stack Target Prediction" + }, + {, + "EventCode": "0xE88C", + "EventName": "PM_LSU1_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0xC0B4", + "EventName": "PM_LSU_FLUSH_WRK_ARND", + "BriefDescription": "LSU workaround flush. These flushes are setup with programmable scan only latches to perform various actions when the flush macro receives a trigger from the dbg macros. These actions include things like flushing the next op encountered for a particular thread or flushing the next op that is NTC op that is encountered on a particular slice. The kind of flush that the workaround is setup to perform is highly variable." + }, + {, + "EventCode": "0x34054", + "EventName": "PM_PARTIAL_ST_FIN", + "BriefDescription": "Any store finished by an LSU slice" + }, + {, + "EventCode": "0x5880", + "EventName": "PM_THRD_PRIO_6_7_CYC", + "BriefDescription": "Cycles thread running at priority level 6 or 7" + }, + {, + "EventCode": "0x4898", + "EventName": "PM_IC_DEMAND_L2_BR_REDIRECT", + "BriefDescription": "L2 I cache demand request due to branch Mispredict ( 15 cycle path)" + }, + {, + "EventCode": "0x4880", + "EventName": "PM_BANK_CONFLICT", + "BriefDescription": "Read blocked due to interleave conflict. The ifar logic will detect an interleave conflict and kill the data that was read that cycle." + }, + {, + "EventCode": "0x360B0", + "EventName": "PM_L3_P0_SYS_PUMP", + "BriefDescription": "L3 PF sent with sys scope port 0, counts even retried requests" + }, + {, + "EventCode": "0x3006A", + "EventName": "PM_IERAT_RELOAD_64K", + "BriefDescription": "IERAT Reloaded (Miss) for a 64k page" + }, + {, + "EventCode": "0xD8BC", + "EventName": "PM_LSU2_3_LRQF_FULL_CYC", + "BriefDescription": "Counts the number of cycles the LRQF is full. LRQF is the queue that holds loads between finish and completion. If it fills up, instructions stay in LRQ until completion, potentially backing up the LRQ" + }, + {, + "EventCode": "0x46086", + "EventName": "PM_L2_SN_M_RD_DONE", + "BriefDescription": "SNP dispatched for a read and was M (true M)" + }, + {, + "EventCode": "0x40154", + "EventName": "PM_MRK_FAB_RSP_BKILL", + "BriefDescription": "Marked store had to do a bkill" + }, + {, + "EventCode": "0xF094", + "EventName": "PM_LSU2_L1_CAM_CANCEL", + "BriefDescription": "ls2 l1 tm cam cancel" + }, + {, + "EventCode": "0x2D014", + "EventName": "PM_CMPLU_STALL_LRQ_FULL", + "BriefDescription": "Finish stall because the NTF instruction was a load that was held in LSAQ (load-store address queue) because the LRQ (load-reorder queue) was full" + }, + {, + "EventCode": "0x3E05E", + "EventName": "PM_L3_CO_MEPF", + "BriefDescription": "L3 castouts in Mepf state for this thread" + }, + {, + "EventCode": "0x460A2", + "EventName": "PM_L3_LAT_CI_HIT", + "BriefDescription": "L3 Lateral Castins Hit" + }, + {, + "EventCode": "0x3D14E", + "EventName": "PM_MRK_DATA_FROM_DL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0x3D15E", + "EventName": "PM_MULT_MRK", + "BriefDescription": "mult marked instr" + }, + {, + "EventCode": "0x4084", + "EventName": "PM_EAT_FULL_CYC", + "BriefDescription": "Cycles No room in EAT" + }, + {, + "EventCode": "0x5098", + "EventName": "PM_LINK_STACK_WRONG_ADD_PRED", + "BriefDescription": "Link stack predicts wrong address, because of link stack design limitation or software violating the coding conventions" + }, + {, + "EventCode": "0x2C050", + "EventName": "PM_DATA_GRP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was group pump (prediction=correct) for a demand load" + }, + {, + "EventCode": "0xC0A4", + "EventName": "PM_LSU2_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0x58A0", + "EventName": "PM_LINK_STACK_CORRECT", + "BriefDescription": "Link stack predicts right address" + }, + {, + "EventCode": "0x4C05A", + "EventName": "PM_DTLB_MISS_1G", + "BriefDescription": "Data TLB reload (after a miss) page size 1G. Implies radix translation was used" + }, + {, + "EventCode": "0x36886", + "EventName": "PM_L2_SN_SX_I_DONE", + "BriefDescription": "SNP dispatched and went from Sx to Ix" + }, + {, + "EventCode": "0x4E04A", + "EventName": "PM_DPTEG_FROM_OFF_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2C12C", + "EventName": "PM_MRK_DATA_FROM_DL4_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's L4 on a different Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x2608E", + "EventName": "PM_TM_LD_CONF", + "BriefDescription": "TM Load (fav or non-fav) ran into conflict (failed)" + }, + {, + "EventCode": "0x4080", + "EventName": "PM_INST_FROM_L1", + "BriefDescription": "Instruction fetches from L1. L1 instruction hit" + }, + {, + "EventCode": "0xE898", + "EventName": "PM_LSU3_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x260A0", + "EventName": "PM_L3_CO_MEM", + "BriefDescription": "L3 CO to memory OR of port 0 and 1 (lossy = may undercount if two cresp come in the same cyc)" + }, + {, + "EventCode": "0x16082", + "EventName": "PM_L2_CASTOUT_MOD", + "BriefDescription": "L2 Castouts - Modified (M,Mu,Me)" + }, + {, + "EventCode": "0xC09C", + "EventName": "PM_LS0_LAUNCH_HELD_PREF", + "BriefDescription": "Number of times a load or store instruction was unable to launch/relaunch because a high priority prefetch used that relaunch cycle" + }, + {, + "EventCode": "0xC8B8", + "EventName": "PM_LSU_FLUSH_LARX_STCX", + "BriefDescription": "A larx is flushed because an older larx has an LMQ reservation for the same thread. A stcx is flushed because an older stcx is in the LMQ. The flush happens when the older larx/stcx relaunches" + }, + {, + "EventCode": "0x260A6", + "EventName": "PM_NON_TM_RST_SC", + "BriefDescription": "Non-TM snp rst TM SC" + }, + {, + "EventCode": "0x3608A", + "EventName": "PM_L2_RTY_ST", + "BriefDescription": "RC retries on PB for any store from core (excludes DCBFs)" + }, + {, + "EventCode": "0x24040", + "EventName": "PM_INST_FROM_L2_MEPF", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state. due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x209C", + "EventName": "PM_TM_FAV_TBEGIN", + "BriefDescription": "Dispatch time Favored tbegin" + }, + {, + "EventCode": "0x2D01E", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_ISSQ", + "BriefDescription": "Ict empty for this thread due to dispatch hold on this thread due to Issue q full, BRQ full, XVCF Full, Count cache, Link, Tar full" + }, + {, + "EventCode": "0x50A4", + "EventName": "PM_FLUSH_MPRED", + "BriefDescription": "Branch mispredict flushes. Includes target and address misprecition" + }, + {, + "EventCode": "0x508C", + "EventName": "PM_SHL_CREATED", + "BriefDescription": "Store-Hit-Load Table Entry Created" + }, + {, + "EventCode": "0x1504C", + "EventName": "PM_IPTEG_FROM_LL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's L4 cache due to a instruction side request" + }, + {, + "EventCode": "0x268A4", + "EventName": "PM_L3_LD_MISS", + "BriefDescription": "L3 Misses for demand LDs" + }, + {, + "EventCode": "0x26088", + "EventName": "PM_L2_GRP_GUESS_CORRECT", + "BriefDescription": "L2 guess grp (GS or NNS) and guess was correct (data intra-group AND ^on-chip)" + }, + {, + "EventCode": "0xD088", + "EventName": "PM_LSU0_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])." + }, + {, + "EventCode": "0xE8B4", + "EventName": "PM_LS1_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x1688C", + "EventName": "PM_RC_USAGE", + "BriefDescription": "Continuous 16 cycle (2to1) window where this signals rotates thru sampling each RC machine busy. PMU uses this wave to then do 16 cyc count to sample total number of machs running" + }, + {, + "EventCode": "0x3F054", + "EventName": "PM_RADIX_PWC_L4_PTE_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was reloaded to a level 4 page walk cache from beyond the core's L3 data cache. This is the deepest level of PWC possible for a translation. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x2608A", + "EventName": "PM_ISIDE_DISP_FAIL_ADDR", + "BriefDescription": "All I-side dispatch attempts for this thread that failed due to a addr collision with another machine (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x50B4", + "EventName": "PM_TAGE_CORRECT_TAKEN_CMPL", + "BriefDescription": "The TAGE overrode BHT direction prediction and it was correct. Counted at completion for taken branches only" + }, + {, + "EventCode": "0x2090", + "EventName": "PM_DISP_CLB_HELD_SB", + "BriefDescription": "Dispatch/CLB Hold: Scoreboard" + }, + {, + "EventCode": "0xE0B0", + "EventName": "PM_TM_FAIL_NON_TX_CONFLICT", + "BriefDescription": "Non transactional conflict from LSU, gets reported to TEXASR" + }, + {, + "EventCode": "0xD198", + "EventName": "PM_MRK_LSU_FLUSH_ATOMIC", + "BriefDescription": "Quad-word loads (lq) are considered atomic because they always span at least 2 slices. If a snoop or store from another thread changes the data the load is accessing between the 2 or 3 pieces of the lq instruction, the lq will be flushed" + }, + {, + "EventCode": "0x201E0", + "EventName": "PM_MRK_DATA_FROM_MEMORY", + "BriefDescription": "The processor's data cache was reloaded from a memory location including L4 from local remote or distant due to a marked load" + }, + {, + "EventCode": "0x368A2", + "EventName": "PM_L3_L2_CO_MISS", + "BriefDescription": "L2 CO miss" + }, + {, + "EventCode": "0x3608C", + "EventName": "PM_CO0_BUSY", + "BriefDescription": "CO mach 0 Busy. Used by PMU to sample ave CO lifetime (mach0 used as sample point)" + }, + {, + "EventCode": "0x2C122", + "EventName": "PM_MRK_DATA_FROM_L3_DISP_CONFLICT_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0x35154", + "EventName": "PM_MRK_DATA_FROM_L3_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 due to a marked load" + }, + {, + "EventCode": "0x1D140", + "EventName": "PM_MRK_DATA_FROM_L31_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x4404A", + "EventName": "PM_INST_FROM_OFF_CHIP_CACHE", + "BriefDescription": "The processor's Instruction cache was reloaded either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x28AC", + "EventName": "PM_TM_FAIL_SELF", + "BriefDescription": "TM aborted because a self-induced conflict occurred in Suspended state, due to one of the following: a store to a storage location that was previously accessed transactionally; a dcbf, dcbi, or icbi specify- ing a block that was previously accessed transactionally; a dcbst specifying a block that was previously written transactionally; or a tlbie that specifies a translation that was pre- viously used transactionally" + }, + {, + "EventCode": "0x45056", + "EventName": "PM_SCALAR_FLOP_CMPL", + "BriefDescription": "Scalar flop operation completed" + }, + {, + "EventCode": "0x16092", + "EventName": "PM_L2_LD_MISS_128B", + "BriefDescription": "All successful D-side load dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 128B (i.e., M=0)" + }, + {, + "EventCode": "0x2E014", + "EventName": "PM_STCX_FIN", + "BriefDescription": "Number of stcx instructions finished. This includes instructions in the speculative path of a branch that may be flushed" + }, + {, + "EventCode": "0xE0B8", + "EventName": "PM_LS2_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x2094", + "EventName": "PM_TM_OUTER_TBEGIN", + "BriefDescription": "Completion time outer tbegin" + }, + {, + "EventCode": "0x160B4", + "EventName": "PM_L3_P0_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 0 (can try 4 times)" + }, + {, + "EventCode": "0x36892", + "EventName": "PM_DSIDE_OTHER_64B_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an D-side fetch where data came EXCLUSIVELY from memory that was for hpc_read64, (RC had to fetch other 64B of a line from MC) i.e., number of times RC had to go to memory to get 'missing' 64B" + }, + {, + "EventCode": "0x20A8", + "EventName": "PM_TM_FAIL_FOOTPRINT_OVERFLOW", + "BriefDescription": "TM aborted because the tracking limit for transactional storage accesses was exceeded.. Asynchronous" + }, + {, + "EventCode": "0x30018", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_HB_FULL", + "BriefDescription": "Ict empty for this thread due to dispatch holds because the History Buffer was full. Could be GPR/VSR/VMR/FPR/CR/XVF; CR; XVF (XER/VSCR/FPSCR)" + }, + {, + "EventCode": "0xC894", + "EventName": "PM_LS1_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x360A2", + "EventName": "PM_L3_L2_CO_HIT", + "BriefDescription": "L2 CO hits" + }, + {, + "EventCode": "0x36092", + "EventName": "PM_DSIDE_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an D-side fetch where data came EXCLUSIVELY from memory (excluding hpcread64 accesses), i.e., total memory accesses by RCs" + }, + {, + "EventCode": "0x10138", + "EventName": "PM_MRK_BR_2PATH", + "BriefDescription": "marked branches which are not strongly biased" + }, + {, + "EventCode": "0x2884", + "EventName": "PM_ISYNC", + "BriefDescription": "Isync completion count per thread" + }, + {, + "EventCode": "0x16882", + "EventName": "PM_L2_CASTOUT_SHR", + "BriefDescription": "L2 Castouts - Shared (Tx,Sx)" + }, + {, + "EventCode": "0xD884", + "EventName": "PM_LSU3_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0x26092", + "EventName": "PM_L2_LD_MISS_64B", + "BriefDescription": "All successful D-side load dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 64B(i.e., M=1)" + }, + {, + "EventCode": "0x26080", + "EventName": "PM_L2_LD_MISS", + "BriefDescription": "All successful D-Side Load dispatches that were an L2 miss for this thread" + }, + {, + "EventCode": "0x3D14C", + "EventName": "PM_MRK_DATA_FROM_DMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x100FA", + "EventName": "PM_ANY_THRD_RUN_CYC", + "BriefDescription": "Cycles in which at least one thread has the run latch set" + }, + {, + "EventCode": "0x2C12A", + "EventName": "PM_MRK_DATA_FROM_RMEM_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's memory on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x25048", + "EventName": "PM_IPTEG_FROM_LMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a instruction side request" + }, + {, + "EventCode": "0xD8A8", + "EventName": "PM_ISLB_MISS", + "BriefDescription": "Instruction SLB miss - Total of all segment sizes" + }, + {, + "EventCode": "0xD19C", + "EventName": "PM_MRK_LSU_FLUSH_RELAUNCH_MISS", + "BriefDescription": "If a load that has already returned data and has to relaunch for any reason then gets a miss (erat, setp, data cache), it will often be flushed at relaunch time because the data might be inconsistent" + }, + {, + "EventCode": "0x260A2", + "EventName": "PM_L3_CI_HIT", + "BriefDescription": "L3 Castins Hit (total count)" + }, + {, + "EventCode": "0x44054", + "EventName": "PM_VECTOR_LD_CMPL", + "BriefDescription": "Number of vector load instructions completed" + }, + {, + "EventCode": "0x1E05C", + "EventName": "PM_CMPLU_STALL_NESTED_TBEGIN", + "BriefDescription": "Completion stall because the ISU is updating the TEXASR to keep track of the nested tbegin. This is a short delay, and it includes ROT" + }, + {, + "EventCode": "0x1608E", + "EventName": "PM_ST_CAUSED_FAIL", + "BriefDescription": "Non-TM Store caused any thread to fail" + }, + {, + "EventCode": "0x3080", + "EventName": "PM_ISU0_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0x1515A", + "EventName": "PM_SYNC_MRK_L2MISS", + "BriefDescription": "Marked L2 Miss that can throw a synchronous interrupt" + }, + {, + "EventCode": "0x26892", + "EventName": "PM_L2_ST_MISS_64B", + "BriefDescription": "All successful D-side store dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 64B (i.e., M=1)" + }, + {, + "EventCode": "0x2688C", + "EventName": "PM_CO_USAGE", + "BriefDescription": "Continuous 16 cycle (2to1) window where this signals rotates thru sampling each CO machine busy. PMU uses this wave to then do 16 cyc count to sample total number of machs running" + }, + {, + "EventCode": "0xD084", + "EventName": "PM_LSU2_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0x48B8", + "EventName": "PM_BR_MPRED_TAKEN_TA", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to the Target Address Prediction from the Count Cache or Link Stack. Only XL-form branches that resolved Taken set this event." + }, + {, + "EventCode": "0x50B0", + "EventName": "PM_BTAC_BAD_RESULT", + "BriefDescription": "BTAC thinks branch will be taken but it is either predicted not-taken by the BHT, or the target address is wrong (less common). In both cases, a redirect will happen" + }, + {, + "EventCode": "0xD888", + "EventName": "PM_LSU1_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])." + }, + {, + "EventCode": "0x58B4", + "EventName": "PM_TAGE_CORRECT", + "BriefDescription": "The TAGE overrode BHT direction prediction and it was correct. Includes taken and not taken and is counted at execution time" + }, + {, + "EventCode": "0x3688C", + "EventName": "PM_SN_USAGE", + "BriefDescription": "Continuous 16 cycle (2to1) window where this signals rotates thru sampling each SN machine busy. PMU uses this wave to then do 16 cyc count to sample total number of machs running" + }, + {, + "EventCode": "0x46084", + "EventName": "PM_L2_RCST_DISP_FAIL_OTHER", + "BriefDescription": "All D-side store dispatch attempts for this thread that failed due to reason other than address collision" + }, + {, + "EventCode": "0xF0AC", + "EventName": "PM_DC_PREF_STRIDED_CONF", + "BriefDescription": "A demand load referenced a line in an active strided prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software." + }, + {, + "EventCode": "0x45054", + "EventName": "PM_FMA_CMPL", + "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only. " + }, + {, + "EventCode": "0x5090", + "EventName": "PM_SHL_ST_DISABLE", + "BriefDescription": "Store-Hit-Load Table Read Hit with entry Disabled (entry was disabled due to the entry shown to not prevent the flush)" + }, + {, + "EventCode": "0x201E8", + "EventName": "PM_THRESH_EXC_512", + "BriefDescription": "Threshold counter exceeded a value of 512" + }, + {, + "EventCode": "0x5084", + "EventName": "PM_DECODE_FUSION_EXT_ADD", + "BriefDescription": "32-bit extended addition" + }, + {, + "EventCode": "0x36080", + "EventName": "PM_L2_INST", + "BriefDescription": "All successful I-side dispatches for this thread (excludes i_l2mru_tch reqs)." + }, + {, + "EventCode": "0x3504C", + "EventName": "PM_IPTEG_FROM_DL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a instruction side request" + }, + {, + "EventCode": "0xD890", + "EventName": "PM_LS1_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x1688A", + "EventName": "PM_ISIDE_DISP", + "BriefDescription": "All I-side dispatch attempts for this thread (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x468AA", + "EventName": "PM_L3_P1_CO_L31", + "BriefDescription": "L3 CO to L3.1 (LCO) port 1 with or without data" + }, + {, + "EventCode": "0x28B0", + "EventName": "PM_DISP_HELD_TBEGIN", + "BriefDescription": "This outer tbegin transaction cannot be dispatched until the previous tend instruction completes" + }, + {, + "EventCode": "0xE8A0", + "EventName": "PM_LSU3_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x2C05E", + "EventName": "PM_INST_GRP_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (Group) ended up either larger or smaller than Initial Pump Scope for an instruction fetch (demand only)" + }, + {, + "EventCode": "0xC8BC", + "EventName": "PM_STCX_SUCCESS_CMPL", + "BriefDescription": "Number of stcx instructions that completed successfully" + }, + {, + "EventCode": "0xE098", + "EventName": "PM_LSU2_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x44044", + "EventName": "PM_INST_FROM_L31_ECO_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another core's ECO L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x16886", + "EventName": "PM_CO_DISP_FAIL", + "BriefDescription": "CO dispatch failed due to all CO machines being busy" + }, + {, + "EventCode": "0x3D146", + "EventName": "PM_MRK_DATA_FROM_L3_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without conflict due to a marked load" + }, + {, + "EventCode": "0x16892", + "EventName": "PM_L2_ST_MISS_128B", + "BriefDescription": "All successful D-side store dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 128B (i.e., M=0)" + }, + {, + "EventCode": "0x26890", + "EventName": "PM_ISIDE_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an I-side fetch where data came from memory" + }, + {, + "EventCode": "0xD094", + "EventName": "PM_LS2_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x3C05E", + "EventName": "PM_MEM_RWITM", + "BriefDescription": "Memory Read With Intent to Modify for this thread" + }, + {, + "EventCode": "0x26882", + "EventName": "PM_L2_DC_INV", + "BriefDescription": "D-cache invalidates sent over the reload bus to the core" + }, + {, + "EventCode": "0xC090", + "EventName": "PM_LSU_STCX", + "BriefDescription": "STCX sent to nest, i.e. total" + }, + {, + "EventCode": "0xD080", + "EventName": "PM_LSU0_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0x2C120", + "EventName": "PM_MRK_DATA_FROM_L2_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 without conflict due to a marked load" + }, + {, + "EventCode": "0x36086", + "EventName": "PM_L2_RC_ST_DONE", + "BriefDescription": "RC did store to line that was Tx or Sx" + }, + {, + "EventCode": "0xE8AC", + "EventName": "PM_TM_FAIL_TX_CONFLICT", + "BriefDescription": "Transactional conflict from LSU, gets reported to TEXASR" + }, + {, + "EventCode": "0x48A8", + "EventName": "PM_DECODE_FUSION_LD_ST_DISP", + "BriefDescription": "32-bit displacement D-form and 16-bit displacement X-form" + }, + {, + "EventCode": "0x3D144", + "EventName": "PM_MRK_DATA_FROM_L2_MEPF_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 hit without dispatch conflicts on Mepf state. due to a marked load" + }, + {, + "EventCode": "0x44046", + "EventName": "PM_INST_FROM_L21_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another core's L2 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x40B0", + "EventName": "PM_BR_PRED_TAKEN_CR", + "BriefDescription": "Conditional Branch that had its direction predicted. I-form branches do not set this event. In addition, B-form branches which do not use the BHT do not set this event - these are branches with BO-field set to 'always taken' and branches" + }, + {, + "EventCode": "0x15040", + "EventName": "PM_IPTEG_FROM_L2_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 without conflict due to a instruction side request" + }, + {, + "EventCode": "0xD9A0", + "EventName": "PM_MRK_LSU_FLUSH_LHL_SHL", + "BriefDescription": "The instruction was flushed because of a sequential load/store consistency. If a load or store hits on an older load that has either been snooped (for loads) or has stale data (for stores)." + }, + {, + "EventCode": "0x35042", + "EventName": "PM_IPTEG_FROM_L3_DISP_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 with dispatch conflict due to a instruction side request" + }, + {, + "EventCode": "0xF898", + "EventName": "PM_XLATE_RADIX_MODE", + "BriefDescription": "LSU reports every cycle the thread is in radix translation mode (as opposed to HPT mode)" + }, + {, + "EventCode": "0x2D142", + "EventName": "PM_MRK_DATA_FROM_L3_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without dispatch conflicts hit on Mepf state. due to a marked load" + }, + {, + "EventCode": "0x160B0", + "EventName": "PM_L3_P0_NODE_PUMP", + "BriefDescription": "L3 PF sent with nodal scope port 0, counts even retried requests" + }, + {, + "EventCode": "0xD88C", + "EventName": "PM_LSU3_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])." + }, + {, + "EventCode": "0x36882", + "EventName": "PM_L2_LD_HIT", + "BriefDescription": "All successful I-or-D side load dispatches for this thread that were L2 hits (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x168AC", + "EventName": "PM_L3_CI_USAGE", + "BriefDescription": "Rotating sample of 16 CI or CO actives" + }, + {, + "EventCode": "0x20134", + "EventName": "PM_MRK_FXU_FIN", + "BriefDescription": "fxu marked instr finish" + }, + {, + "EventCode": "0x4608E", + "EventName": "PM_TM_CAP_OVERFLOW", + "BriefDescription": "TM Footprint Capacity Overflow" + }, + {, + "EventCode": "0x4F05C", + "EventName": "PM_RADIX_PWC_L2_PTE_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was reloaded to a level 2 page walk cache from beyond the core's L3 data cache. This implies that level 3 and level 4 PWC accesses were not necessary for this translation. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x40014", + "EventName": "PM_PROBE_NOP_DISP", + "BriefDescription": "ProbeNops dispatched" + }, + {, + "EventCode": "0x58A8", + "EventName": "PM_DECODE_HOLD_ICT_FULL", + "BriefDescription": "Counts the number of cycles in which the IFU was not able to decode and transmit one or more instructions because all itags were in use. This means the ICT is full for this thread" + }, + {, + "EventCode": "0x10052", + "EventName": "PM_GRP_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x2505E", + "EventName": "PM_BACK_BR_CMPL", + "BriefDescription": "Branch instruction completed with a target address less than current instruction address" + }, + {, + "EventCode": "0x2688A", + "EventName": "PM_ISIDE_DISP_FAIL_OTHER", + "BriefDescription": "All I-side dispatch attempts for this thread that failed due to a reason other than addrs collision (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x2001A", + "EventName": "PM_NTC_ALL_FIN", + "BriefDescription": "Cycles after all instructions have finished to group completed" + }, + {, + "EventCode": "0x3005A", + "EventName": "PM_ISQ_0_8_ENTRIES", + "BriefDescription": "Cycles in which 8 or less Issue Queue entries are in use. This is a shared event, not per thread" + }, + {, + "EventCode": "0x3515E", + "EventName": "PM_MRK_BACK_BR_CMPL", + "BriefDescription": "Marked branch instruction completed with a target address less than current instruction address" + }, + {, + "EventCode": "0xF890", + "EventName": "PM_LSU1_L1_CAM_CANCEL", + "BriefDescription": "ls1 l1 tm cam cancel" + }, + {, + "EventCode": "0xE884", + "EventName": "PM_LS1_ERAT_MISS_PREF", + "BriefDescription": "LS1 Erat miss due to prefetch" + }, + {, + "EventCode": "0xE89C", + "EventName": "PM_LSU1_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x28A8", + "EventName": "PM_TM_FAIL_CONF_NON_TM", + "BriefDescription": "TM aborted because a conflict occurred with a non-transactional access by another processor" + }, + {, + "EventCode": "0x16890", + "EventName": "PM_L1PF_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an L1PF where data came from memory" + }, + {, + "EventCode": "0x4504C", + "EventName": "PM_IPTEG_FROM_DMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group (Distant) due to a instruction side request" + }, + {, + "EventCode": "0x1002E", + "EventName": "PM_LMQ_MERGE", + "BriefDescription": "A demand miss collides with a prefetch for the same line" + }, + {, + "EventCode": "0x160B6", + "EventName": "PM_L3_WI0_BUSY", + "BriefDescription": "Rotating sample of 8 WI valid" + }, + {, + "EventCode": "0x368AC", + "EventName": "PM_L3_CO0_BUSY", + "BriefDescription": "Lifetime, sample of CO machine 0 valid" + }, + {, + "EventCode": "0x2E040", + "EventName": "PM_DPTEG_FROM_L2_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1D152", + "EventName": "PM_MRK_DATA_FROM_DL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on a different Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x46880", + "EventName": "PM_ISIDE_MRU_TOUCH", + "BriefDescription": "I-side L2 MRU touch sent to L2 for this thread" + }, + {, + "EventCode": "0x1C05C", + "EventName": "PM_DTLB_MISS_2M", + "BriefDescription": "Data TLB reload (after a miss) page size 2M. Implies radix translation was used" + }, + {, + "EventCode": "0x50B8", + "EventName": "PM_TAGE_OVERRIDE_WRONG", + "BriefDescription": "The TAGE overrode BHT direction prediction but it was incorrect. Counted at completion for taken branches only" + }, + {, + "EventCode": "0x160AE", + "EventName": "PM_L3_P0_PF_RTY", + "BriefDescription": "L3 PF received retry port 0, every retry counted" + }, + {, + "EventCode": "0x268B2", + "EventName": "PM_L3_LOC_GUESS_WRONG", + "BriefDescription": "Initial scope=node (LNS) but data from out side local node (near or far or rem). Prediction too Low" + }, + {, + "EventCode": "0x36088", + "EventName": "PM_L2_SYS_GUESS_CORRECT", + "BriefDescription": "L2 guess system (VGS or RNS) and guess was correct (ie data beyond-group)" + }, + {, + "EventCode": "0x589C", + "EventName": "PM_PTESYNC", + "BriefDescription": "ptesync instruction counted when the instruction is decoded and transmitted" + }, + {, + "EventCode": "0x26086", + "EventName": "PM_CO_TM_SC_FOOTPRINT", + "BriefDescription": "L2 did a cleanifdirty CO to the L3 (ie created an SC line in the L3) OR L2 TM_store hit dirty HPC line and L3 indicated SC line formed in L3 on RDR bus" + }, + {, + "EventCode": "0x1E05A", + "EventName": "PM_CMPLU_STALL_ANY_SYNC", + "BriefDescription": "Cycles in which the NTC sync instruction (isync, lwsync or hwsync) is not allowed to complete" + }, + {, + "EventCode": "0xF090", + "EventName": "PM_LSU0_L1_CAM_CANCEL", + "BriefDescription": "ls0 l1 tm cam cancel" + }, + {, + "EventCode": "0xC0A8", + "EventName": "PM_LSU_FLUSH_CI", + "BriefDescription": "Load was not issued to LSU as a cache inhibited (non-cacheable) load but it was later determined to be cache inhibited" + }, + {, + "EventCode": "0x20AC", + "EventName": "PM_TM_FAIL_CONF_TM", + "BriefDescription": "TM aborted because a conflict occurred with another transaction." + }, + {, + "EventCode": "0x588C", + "EventName": "PM_SHL_ST_DEP_CREATED", + "BriefDescription": "Store-Hit-Load Table Read Hit with entry Enabled" + }, + {, + "EventCode": "0x360AC", + "EventName": "PM_L3_SN0_BUSY", + "BriefDescription": "Lifetime, sample of snooper machine 0 valid" + }, + {, + "EventCode": "0x3005C", + "EventName": "PM_BFU_BUSY", + "BriefDescription": "Cycles in which all 4 Binary Floating Point units are busy. The BFU is running at capacity" + }, + {, + "EventCode": "0x48A0", + "EventName": "PM_BR_PRED_PCACHE", + "BriefDescription": "Conditional branch completed that used pattern cache prediction" + }, + {, + "EventCode": "0x26880", + "EventName": "PM_L2_ST_MISS", + "BriefDescription": "All successful D-Side Store dispatches that were an L2 miss for this thread" + }, + {, + "EventCode": "0xF8B4", + "EventName": "PM_DC_PREF_XCONS_ALLOC", + "BriefDescription": "Prefetch stream allocated in the Ultra conservative phase by either the hardware prefetch mechanism or software prefetch" + }, + {, + "EventCode": "0x35048", + "EventName": "PM_IPTEG_FROM_DL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x260A8", + "EventName": "PM_L3_PF_HIT_L3", + "BriefDescription": "L3 PF hit in L3 (abandoned)" + }, + {, + "EventCode": "0x360B4", + "EventName": "PM_L3_PF0_BUSY", + "BriefDescription": "Lifetime, sample of PF machine 0 valid" + }, + {, + "EventCode": "0xC0B0", + "EventName": "PM_LSU_FLUSH_UE", + "BriefDescription": "Correctable ECC error on reload data, reported at critical data forward time" + }, + {, + "EventCode": "0x4013A", + "EventName": "PM_MRK_IC_MISS", + "BriefDescription": "Marked instruction experienced I cache miss" + }, + {, + "EventCode": "0x2088", + "EventName": "PM_FLUSH_DISP_SB", + "BriefDescription": "Dispatch Flush: Scoreboard" + }, + {, + "EventCode": "0x401E8", + "EventName": "PM_MRK_DATA_FROM_L2MISS", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L2 due to a marked load" + }, + {, + "EventCode": "0x3688E", + "EventName": "PM_TM_ST_CAUSED_FAIL", + "BriefDescription": "TM Store (fav or non-fav) caused another thread to fail" + }, + {, + "EventCode": "0x460B2", + "EventName": "PM_L3_SYS_GUESS_WRONG", + "BriefDescription": "Initial scope=system (VGS or RNS) but data from local or near. Prediction too high" + }, + {, + "EventCode": "0x58B8", + "EventName": "PM_TAGE_OVERRIDE_WRONG_SPEC", + "BriefDescription": "The TAGE overrode BHT direction prediction and it was correct. Includes taken and not taken and is counted at execution time" + }, + {, + "EventCode": "0xE890", + "EventName": "PM_LSU3_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0x2898", + "EventName": "PM_TM_TABORT_TRECLAIM", + "BriefDescription": "Completion time tabortnoncd, tabortcd, treclaim" + }, + {, + "EventCode": "0x4C054", + "EventName": "PM_DERAT_MISS_16G", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 16G" + }, + {, + "EventCode": "0x268A0", + "EventName": "PM_L3_CO_L31", + "BriefDescription": "L3 CO to L3.1 OR of port 0 and 1 (lossy = may undercount if two cresps come in the same cyc)" + }, + {, + "EventCode": "0x5080", + "EventName": "PM_THRD_PRIO_4_5_CYC", + "BriefDescription": "Cycles thread running at priority level 4 or 5" + }, + {, + "EventCode": "0x2505C", + "EventName": "PM_VSU_FIN", + "BriefDescription": "VSU instruction finished. Up to 4 per cycle" + }, + {, + "EventCode": "0x40A4", + "EventName": "PM_BR_PRED_CCACHE", + "BriefDescription": "Conditional Branch Completed that used the Count Cache for Target Prediction" + }, + {, + "EventCode": "0x2E04A", + "EventName": "PM_DPTEG_FROM_RL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on the same Node or Group ( Remote) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D12E", + "EventName": "PM_MRK_DATA_FROM_DL2L3_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0xC8B4", + "EventName": "PM_LSU_FLUSH_LHL_SHL", + "BriefDescription": "The instruction was flushed because of a sequential load/store consistency. If a load or store hits on an older load that has either been snooped (for loads) or has stale data (for stores)." + }, + {, + "EventCode": "0x58A4", + "EventName": "PM_FLUSH_LSU", + "BriefDescription": "LSU flushes. Includes all lsu flushes" + }, + {, + "EventCode": "0x1D150", + "EventName": "PM_MRK_DATA_FROM_DL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0xC8A0", + "EventName": "PM_LSU1_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0x48BC", + "EventName": "PM_THRD_PRIO_2_3_CYC", + "BriefDescription": "Cycles thread running at priority level 2 or 3" + }, + {, + "EventCode": "0x10134", + "EventName": "PM_MRK_ST_DONE_L2", + "BriefDescription": "marked store completed in L2 ( RC machine done)" + }, + {, + "EventCode": "0x368B2", + "EventName": "PM_L3_GRP_GUESS_WRONG_HIGH", + "BriefDescription": "Initial scope=group (GS or NNS) but data from local node. Prediction too high" + }, + {, + "EventCode": "0xE8BC", + "EventName": "PM_LS1_PTE_TABLEWALK_CYC", + "BriefDescription": "Cycles when a tablewalk is pending on this thread on table 1" + }, + {, + "EventCode": "0x1F152", + "EventName": "PM_MRK_FAB_RSP_BKILL_CYC", + "BriefDescription": "cycles L2 RC took for a bkill" + }, + {, + "EventCode": "0x4C124", + "EventName": "PM_MRK_DATA_FROM_L3_NO_CONFLICT_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 without conflict due to a marked load" + }, + {, + "EventCode": "0x2F14A", + "EventName": "PM_MRK_DPTEG_FROM_RL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on the same Node or Group ( Remote) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x26888", + "EventName": "PM_L2_GRP_GUESS_WRONG", + "BriefDescription": "L2 guess grp (GS or NNS) and guess was not correct (ie data on-chip OR beyond-group)" + }, + {, + "EventCode": "0x368AE", + "EventName": "PM_L3_P1_CO_RTY", + "BriefDescription": "L3 CO received retry port 1 (memory only), every retry counted" + }, + {, + "EventCode": "0xC0AC", + "EventName": "PM_LSU_FLUSH_EMSH", + "BriefDescription": "An ERAT miss was detected after a set-p hit. Erat tracker indicates fail due to tlbmiss and the instruction gets flushed because the instruction was working on the wrong address" + }, + {, + "EventCode": "0x260B2", + "EventName": "PM_L3_SYS_GUESS_CORRECT", + "BriefDescription": "Initial scope=system (VGS or RNS) and data from outside group (far or rem)(pred successful)" + }, + {, + "EventCode": "0x1D146", + "EventName": "PM_MRK_DATA_FROM_MEMORY_CYC", + "BriefDescription": "Duration in cycles to reload from a memory location including L4 from local remote or distant due to a marked load" + }, + {, + "EventCode": "0xE094", + "EventName": "PM_LSU0_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x46888", + "EventName": "PM_L2_GROUP_PUMP", + "BriefDescription": "RC requests that were on group (aka nodel) pump attempts" + }, + {, + "EventCode": "0xF0B0", + "EventName": "PM_L3_LD_PREF", + "BriefDescription": "L3 load prefetch, sourced from a hardware or software stream, was sent to the nest" + }, + {, + "EventCode": "0x16080", + "EventName": "PM_L2_LD", + "BriefDescription": "All successful D-side Load dispatches for this thread (L2 miss + L2 hits)" + }, + {, + "EventCode": "0x4505C", + "EventName": "PM_MATH_FLOP_CMPL", + "BriefDescription": "Math flop instruction completed" + }, + {, + "EventCode": "0x368B0", + "EventName": "PM_L3_P1_SYS_PUMP", + "BriefDescription": "L3 PF sent with sys scope port 1, counts even retried requests" + }, + {, + "EventCode": "0x1F146", + "EventName": "PM_MRK_DPTEG_FROM_L31_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L3 on the same chip due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2000C", + "EventName": "PM_THRD_ALL_RUN_CYC", + "BriefDescription": "Cycles in which all the threads have the run latch set" + }, + {, + "EventCode": "0xC0BC", + "EventName": "PM_LSU_FLUSH_OTHER", + "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the “bad dval†back and flush all younger ops)" + }, + {, + "EventCode": "0x5094", + "EventName": "PM_IC_MISS_ICBI", + "BriefDescription": "threaded version, IC Misses where we got EA dir hit but no sector valids were on. ICBI took line out" + }, + {, + "EventCode": "0xC8A8", + "EventName": "PM_LSU_FLUSH_ATOMIC", + "BriefDescription": "Quad-word loads (lq) are considered atomic because they always span at least 2 slices. If a snoop or store from another thread changes the data the load is accessing between the 2 or 3 pieces of the lq instruction, the lq will be flushed" + }, + {, + "EventCode": "0x1E04E", + "EventName": "PM_DPTEG_FROM_L2MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L2 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D05E", + "EventName": "PM_BR_CMPL", + "BriefDescription": "Any Branch instruction completed" + }, + {, + "EventCode": "0x260B0", + "EventName": "PM_L3_P0_GRP_PUMP", + "BriefDescription": "L3 PF sent with grp scope port 0, counts even retried requests" + }, + {, + "EventCode": "0x30132", + "EventName": "PM_MRK_VSU_FIN", + "BriefDescription": "VSU marked instr finish" + }, + {, + "EventCode": "0x2D120", + "EventName": "PM_MRK_DATA_FROM_OFF_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a marked load" + }, + {, + "EventCode": "0x1E048", + "EventName": "PM_DPTEG_FROM_ON_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x16086", + "EventName": "PM_L2_SN_M_WR_DONE", + "BriefDescription": "SNP dispatched for a write and was M (true M); for DMA cacheinj this will pulse if rty/push is required (won't pulse if cacheinj is accepted)" + }, + {, + "EventCode": "0x489C", + "EventName": "PM_BR_CORECT_PRED_TAKEN_CMPL", + "BriefDescription": "Conditional Branch Completed in which the HW correctly predicted the direction as taken. Counted at completion time" + }, + {, + "EventCode": "0xF0B8", + "EventName": "PM_LS0_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x20132", + "EventName": "PM_MRK_DFU_FIN", + "BriefDescription": "Decimal Unit marked Instruction Finish" + }, + {, + "EventCode": "0x160A6", + "EventName": "PM_TM_SC_CO", + "BriefDescription": "L3 castout TM SC line" + }, + {, + "EventCode": "0xC8B0", + "EventName": "PM_LSU_FLUSH_LHS", + "BriefDescription": "Effective Address alias flush : no EA match but Real Address match. If the data has not yet been returned for this load, the instruction will just be rejected, but if it has returned data, it will be flushed" + }, + {, + "EventCode": "0x3F150", + "EventName": "PM_MRK_ST_DRAIN_TO_L2DISP_CYC", + "BriefDescription": "cycles to drain st from core to L2" + }, + {, + "EventCode": "0x168A4", + "EventName": "PM_L3_MISS", + "BriefDescription": "L3 Misses (L2 miss also missing L3, including data/instrn/xlate)" + }, + {, + "EventCode": "0xF080", + "EventName": "PM_LSU_STCX_FAIL", + "BriefDescription": "" + }, + {, + "EventCode": "0x30038", + "EventName": "PM_CMPLU_STALL_DMISS_LMEM", + "BriefDescription": "Completion stall due to cache miss that resolves in local memory" + }, + {, + "EventCode": "0x28A4", + "EventName": "PM_MRK_TEND_FAIL", + "BriefDescription": "Nested or not nested tend failed for a marked tend instruction" + }, + {, + "EventCode": "0x100FC", + "EventName": "PM_LD_REF_L1", + "BriefDescription": "All L1 D cache load references counted at finish, gated by reject" + }, + {, + "EventCode": "0xC0A0", + "EventName": "PM_LSU0_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0x468A8", + "EventName": "PM_SN_MISS", + "BriefDescription": "Any port snooper L3 miss or collision. Up to 4 can happen in a cycle but we only count 1" + }, + {, + "EventCode": "0x36888", + "EventName": "PM_L2_SYS_GUESS_WRONG", + "BriefDescription": "L2 guess system (VGS or RNS) and guess was not correct (ie data ^beyond-group)" + }, + {, + "EventCode": "0x2080", + "EventName": "PM_EE_OFF_EXT_INT", + "BriefDescription": "CyclesMSR[EE] is off and external interrupts are active" + }, + {, + "EventCode": "0xE8B8", + "EventName": "PM_LS3_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x2688E", + "EventName": "PM_TM_FAV_CAUSED_FAIL", + "BriefDescription": "TM Load (fav) caused another thread to fail" + }, + {, + "EventCode": "0x16090", + "EventName": "PM_SN0_BUSY", + "BriefDescription": "SN mach 0 Busy. Used by PMU to sample ave SN lifetime (mach0 used as sample point)" + }, + {, + "EventCode": "0x360AE", + "EventName": "PM_L3_P0_CO_RTY", + "BriefDescription": "L3 CO received retry port 0 (memory only), every retry counted" + }, + {, + "EventCode": "0x168A8", + "EventName": "PM_L3_WI_USAGE", + "BriefDescription": "Lifetime, sample of Write Inject machine 0 valid" + }, + {, + "EventCode": "0x468A2", + "EventName": "PM_L3_LAT_CI_MISS", + "BriefDescription": "L3 Lateral Castins Miss" + }, + {, + "EventCode": "0x4090", + "EventName": "PM_IC_PREF_CANCEL_PAGE", + "BriefDescription": "Prefetch Canceled due to page boundary" + }, + {, + "EventCode": "0xF09C", + "EventName": "PM_SLB_TABLEWALK_CYC", + "BriefDescription": "Cycles when a tablewalk is pending on this thread on the SLB table" + }, + {, + "EventCode": "0x460AA", + "EventName": "PM_L3_P0_CO_L31", + "BriefDescription": "L3 CO to L3.1 (LCO) port 0 with or without data" + }, + {, + "EventCode": "0x2880", + "EventName": "PM_FLUSH_DISP", + "BriefDescription": "Dispatch flush" + }, + {, + "EventCode": "0x168AE", + "EventName": "PM_L3_P1_PF_RTY", + "BriefDescription": "L3 PF received retry port 1, every retry counted" + }, + {, + "EventCode": "0x46082", + "EventName": "PM_L2_ST_DISP", + "BriefDescription": "All successful D-side store dispatches for this thread " + }, + {, + "EventCode": "0x4609E", + "EventName": "PM_L2_INST_MISS", + "BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)" + }, + {, + "EventCode": "0xE084", + "EventName": "PM_LS0_ERAT_MISS_PREF", + "BriefDescription": "LS0 Erat miss due to prefetch" + }, + {, + "EventCode": "0x409C", + "EventName": "PM_BR_PRED", + "BriefDescription": "Conditional Branch Executed in which the HW predicted the Direction or Target. Includes taken and not taken and is counted at execution time" + }, + {, + "EventCode": "0x2D144", + "EventName": "PM_MRK_DATA_FROM_L31_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x360A4", + "EventName": "PM_L3_CO_LCO", + "BriefDescription": "Total L3 COs occurred on LCO L3.1 (good cresp, may end up in mem on a retry)" + }, + {, + "EventCode": "0x4890", + "EventName": "PM_IC_PREF_CANCEL_HIT", + "BriefDescription": "Prefetch Canceled due to icache hit" + }, + {, + "EventCode": "0x268A8", + "EventName": "PM_RD_HIT_PF", + "BriefDescription": "RD machine hit L3 PF machine" + }, + {, + "EventCode": "0x16880", + "EventName": "PM_L2_ST", + "BriefDescription": "All successful D-side store dispatches for this thread (L2 miss + L2 hits)" + }, + {, + "EventCode": "0x4098", + "EventName": "PM_IC_DEMAND_L2_BHT_REDIRECT", + "BriefDescription": "L2 I cache demand request due to BHT redirect, branch redirect ( 2 bubbles 3 cycles)" + }, + {, + "EventCode": "0xD0B4", + "EventName": "PM_LSU0_SRQ_S0_VALID_CYC", + "BriefDescription": "Slot 0 of SRQ valid" + }, + {, + "EventCode": "0x160AA", + "EventName": "PM_L3_P0_LCO_NO_DATA", + "BriefDescription": "Dataless L3 LCO sent port 0" + }, + {, + "EventCode": "0x208C", + "EventName": "PM_CLB_HELD", + "BriefDescription": "CLB (control logic block - indicates quadword fetch block) Hold: Any Reason" + }, + {, + "EventCode": "0xF88C", + "EventName": "PM_LSU3_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x200F2", + "EventName": "PM_INST_DISP", + "BriefDescription": "# PPC Dispatched" + }, + {, + "EventCode": "0x4E05E", + "EventName": "PM_TM_OUTER_TBEGIN_DISP", + "BriefDescription": "Number of outer tbegin instructions dispatched. The dispatch unit determines whether the tbegin instruction is outer or nested. This is a speculative count, which includes flushed instructions" + }, + {, + "EventCode": "0x2D018", + "EventName": "PM_CMPLU_STALL_EXEC_UNIT", + "BriefDescription": "Completion stall due to execution units (FXU/VSU/CRU)" + }, + {, + "EventCode": "0x20B0", + "EventName": "PM_LSU_FLUSH_NEXT", + "BriefDescription": "LSU flush next reported at flush time. Sometimes these also come with an exception" + }, + {, + "EventCode": "0x3880", + "EventName": "PM_ISU2_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0x46882", + "EventName": "PM_L2_ST_HIT", + "BriefDescription": "All successful D-side store dispatches for this thread that were L2 hits" + }, + {, + "EventCode": "0x360A8", + "EventName": "PM_L3_CO", + "BriefDescription": "L3 castout occurring (does not include casthrough or log writes (cinj/dmaw))" + }, + {, + "EventCode": "0x368A4", + "EventName": "PM_L3_CINJ", + "BriefDescription": "L3 castin of cache inject" + }, + {, + "EventCode": "0xC890", + "EventName": "PM_LSU_NCST", + "BriefDescription": "Asserts when a i=1 store op is sent to the nest. No record of issue pipe (LS0/LS1) is maintained so this is for both pipes. Probably don't need separate LS0 and LS1" + }, + {, + "EventCode": "0xD880", + "EventName": "PM_LSU1_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0xD0B8", + "EventName": "PM_LSU_LMQ_FULL_CYC", + "BriefDescription": "Counts the number of cycles the LMQ is full" + }, + {, + "EventCode": "0x168B2", + "EventName": "PM_L3_GRP_GUESS_CORRECT", + "BriefDescription": "Initial scope=group (GS or NNS) and data from same group (near) (pred successful)" + }, + {, + "EventCode": "0x48A4", + "EventName": "PM_STOP_FETCH_PENDING_CYC", + "BriefDescription": "Fetching is stopped due to an incoming instruction that will result in a flush" + }, + {, + "EventCode": "0x36884", + "EventName": "PM_L2_RCST_DISP_FAIL_ADDR", + "BriefDescription": "All D-side store dispatch attempts for this thread that failed due to address collision with RC/CO/SN/SQ" + }, + {, + "EventCode": "0x260AC", + "EventName": "PM_L3_PF_USAGE", + "BriefDescription": "Rotating sample of 32 PF actives" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json new file mode 100644 index 0000000000000000000000000000000000000000..bc2db636dabf1612c7c698fb3555319f763755c7 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json @@ -0,0 +1,552 @@ +[ + {, + "EventCode": "0x4D04C", + "EventName": "PM_DFU_BUSY", + "BriefDescription": "Cycles in which all 4 Decimal Floating Point units are busy. The DFU is running at capacity" + }, + {, + "EventCode": "0x100F6", + "EventName": "PM_IERAT_RELOAD", + "BriefDescription": "Number of I-ERAT reloads" + }, + {, + "EventCode": "0x201E2", + "EventName": "PM_MRK_LD_MISS_L1", + "BriefDescription": "Marked DL1 Demand Miss counted at exec time. Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." + }, + {, + "EventCode": "0x40010", + "EventName": "PM_PMC3_OVERFLOW", + "BriefDescription": "Overflow from counter 3" + }, + {, + "EventCode": "0x1005A", + "EventName": "PM_CMPLU_STALL_DFLONG", + "BriefDescription": "Finish stall because the NTF instruction was a multi-cycle instruction issued to the Decimal Floating Point execution pipe and waiting to finish. Includes decimal floating point instructions + 128 bit binary floating point instructions. Qualified by multicycle" + }, + {, + "EventCode": "0x4D140", + "EventName": "PM_MRK_DATA_FROM_ON_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x3F14C", + "EventName": "PM_MRK_DPTEG_FROM_DL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1E040", + "EventName": "PM_DPTEG_FROM_L2_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 without conflict due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x24052", + "EventName": "PM_FXU_IDLE", + "BriefDescription": "Cycles in which FXU0, FXU1, FXU2, and FXU3 are all idle" + }, + {, + "EventCode": "0x1E054", + "EventName": "PM_CMPLU_STALL", + "BriefDescription": "Nothing completed and ICT not empty" + }, + {, + "EventCode": "0x2", + "EventName": "PM_INST_CMPL", + "BriefDescription": "Number of PowerPC Instructions that completed." + }, + {, + "EventCode": "0x3D058", + "EventName": "PM_VSU_DP_FSQRT_FDIV", + "BriefDescription": "vector versions of fdiv,fsqrt" + }, + {, + "EventCode": "0x10006", + "EventName": "PM_DISP_HELD", + "BriefDescription": "Dispatch Held" + }, + {, + "EventCode": "0x3D154", + "EventName": "PM_MRK_DERAT_MISS_16M", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 16M" + }, + {, + "EventCode": "0x200F8", + "EventName": "PM_EXT_INT", + "BriefDescription": "external interrupt" + }, + {, + "EventCode": "0x20008", + "EventName": "PM_ICT_EMPTY_CYC", + "BriefDescription": "Cycles in which the ICT is completely empty. No itags are assigned to any thread" + }, + {, + "EventCode": "0x4F146", + "EventName": "PM_MRK_DPTEG_FROM_L21_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L2 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10056", + "EventName": "PM_MEM_READ", + "BriefDescription": "Reads from Memory from this thread (includes data/inst/xlate/l1prefetch/inst prefetch). Includes L4" + }, + {, + "EventCode": "0x3C04C", + "EventName": "PM_DATA_FROM_DL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on a different Node or Group (Distant) due to a demand load" + }, + {, + "EventCode": "0x4E046", + "EventName": "PM_DPTEG_FROM_L21_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L2 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2E016", + "EventName": "PM_NTC_ISSUE_HELD_ARB", + "BriefDescription": "The NTC instruction is being held at dispatch because it lost arbitration onto the issue pipe to another instruction (from the same thread or a different thread)" + }, + {, + "EventCode": "0x15156", + "EventName": "PM_SYNC_MRK_FX_DIVIDE", + "BriefDescription": "Marked fixed point divide that can cause a synchronous interrupt" + }, + {, + "EventCode": "0x1C056", + "EventName": "PM_DERAT_MISS_4K", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 4K" + }, + {, + "EventCode": "0x2F142", + "EventName": "PM_MRK_DPTEG_FROM_L3_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without dispatch conflicts hit on Mepf state. due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10024", + "EventName": "PM_PMC5_OVERFLOW", + "BriefDescription": "Overflow from counter 5" + }, + {, + "EventCode": "0x2C018", + "EventName": "PM_CMPLU_STALL_DMISS_L21_L31", + "BriefDescription": "Completion stall by Dcache miss which resolved on chip ( excluding local L2/L3)" + }, + {, + "EventCode": "0x4006A", + "EventName": "PM_IERAT_RELOAD_16M", + "BriefDescription": "IERAT Reloaded (Miss) for a 16M page" + }, + {, + "EventCode": "0x4E010", + "EventName": "PM_ICT_NOSLOT_IC_L3MISS", + "BriefDescription": "Ict empty for this thread due to icache misses that were sourced from beyond the local L3. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x4D01C", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_SYNC", + "BriefDescription": "Dispatch held due to a synchronizing instruction at dispatch" + }, + {, + "EventCode": "0x2D01A", + "EventName": "PM_ICT_NOSLOT_IC_MISS", + "BriefDescription": "Ict empty for this thread due to Icache Miss" + }, + {, + "EventCode": "0x3D152", + "EventName": "PM_MRK_DERAT_MISS_1G", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 1G. Implies radix translation" + }, + {, + "EventCode": "0x4F14A", + "EventName": "PM_MRK_DPTEG_FROM_OFF_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x30058", + "EventName": "PM_TLBIE_FIN", + "BriefDescription": "tlbie finished" + }, + {, + "EventCode": "0x100F8", + "EventName": "PM_ICT_NOSLOT_CYC", + "BriefDescription": "Number of cycles the ICT has no itags assigned to this thread" + }, + {, + "EventCode": "0x3E042", + "EventName": "PM_DPTEG_FROM_L3_DISP_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 with dispatch conflict due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1F140", + "EventName": "PM_MRK_DPTEG_FROM_L2_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 without conflict due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2C05A", + "EventName": "PM_DERAT_MISS_1G", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 1G. Implies radix translation" + }, + {, + "EventCode": "0x1F058", + "EventName": "PM_RADIX_PWC_L2_PTE_FROM_L2", + "BriefDescription": "A Page Table Entry was reloaded to a level 2 page walk cache from the core's L2 data cache. This implies that level 3 and level 4 PWC accesses were not necessary for this translation" + }, + {, + "EventCode": "0x1D14A", + "EventName": "PM_MRK_DATA_FROM_RL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x10050", + "EventName": "PM_CHIP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was chip pump (prediction=correct) for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x45058", + "EventName": "PM_IC_MISS_CMPL", + "BriefDescription": "Non-speculative icache miss, counted at completion" + }, + {, + "EventCode": "0x2D150", + "EventName": "PM_MRK_DERAT_MISS_4K", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 4K" + }, + {, + "EventCode": "0x34058", + "EventName": "PM_ICT_NOSLOT_BR_MPRED_ICMISS", + "BriefDescription": "Ict empty for this thread due to Icache Miss and branch mispred" + }, + {, + "EventCode": "0x10022", + "EventName": "PM_PMC2_SAVED", + "BriefDescription": "PMC2 Rewind Value saved" + }, + {, + "EventCode": "0x2000A", + "EventName": "PM_HV_CYC", + "BriefDescription": "Cycles in which msr_hv is high. Note that this event does not take msr_pr into consideration" + }, + {, + "EventCode": "0x1F144", + "EventName": "PM_MRK_DPTEG_FROM_L3_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without conflict due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x300FC", + "EventName": "PM_DTLB_MISS", + "BriefDescription": "Data PTEG reload" + }, + {, + "EventCode": "0x2D152", + "EventName": "PM_MRK_DERAT_MISS_2M", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 2M. Implies radix translation" + }, + {, + "EventCode": "0x2C046", + "EventName": "PM_DATA_FROM_RL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a demand load" + }, + {, + "EventCode": "0x20052", + "EventName": "PM_GRP_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (Group) ended up either larger or smaller than Initial Pump Scope for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x3F05A", + "EventName": "PM_RADIX_PWC_L2_PDE_FROM_L3", + "BriefDescription": "A Page Directory Entry was reloaded to a level 2 page walk cache from the core's L3 data cache" + }, + {, + "EventCode": "0x1E04A", + "EventName": "PM_DPTEG_FROM_RL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10064", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_TBEGIN", + "BriefDescription": "the NTC instruction is being held at dispatch because it is a tbegin instruction and there is an older tbegin in the pipeline that must complete before the younger tbegin can dispatch" + }, + {, + "EventCode": "0x2E046", + "EventName": "PM_DPTEG_FROM_RL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4F14C", + "EventName": "PM_MRK_DPTEG_FROM_DMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group (Distant) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2E042", + "EventName": "PM_DPTEG_FROM_L3_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without dispatch conflicts hit on Mepf state. due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2D012", + "EventName": "PM_CMPLU_STALL_DFU", + "BriefDescription": "Finish stall because the NTF instruction was issued to the Decimal Floating Point execution pipe and waiting to finish. Includes decimal floating point instructions + 128 bit binary floating point instructions. Not qualified by multicycle" + }, + {, + "EventCode": "0x4C04C", + "EventName": "PM_DATA_FROM_DMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group (Distant) due to a demand load" + }, + {, + "EventCode": "0x30022", + "EventName": "PM_PMC4_SAVED", + "BriefDescription": "PMC4 Rewind Value saved (matched condition)" + }, + {, + "EventCode": "0x200F4", + "EventName": "PM_RUN_CYC", + "BriefDescription": "Run_cycles" + }, + {, + "EventCode": "0x400F2", + "EventName": "PM_1PLUS_PPC_DISP", + "BriefDescription": "Cycles at least one Instr Dispatched" + }, + {, + "EventCode": "0x3D148", + "EventName": "PM_MRK_DATA_FROM_L21_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another core's L2 on the same chip due to a marked load" + }, + {, + "EventCode": "0x2F146", + "EventName": "PM_MRK_DPTEG_FROM_RL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4E01A", + "EventName": "PM_ICT_NOSLOT_DISP_HELD", + "BriefDescription": "Cycles in which the NTC instruction is held at dispatch for any reason" + }, + {, + "EventCode": "0x401EC", + "EventName": "PM_THRESH_EXC_2048", + "BriefDescription": "Threshold counter exceeded a value of 2048" + }, + {, + "EventCode": "0x35150", + "EventName": "PM_MRK_DATA_FROM_RL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x3E052", + "EventName": "PM_ICT_NOSLOT_IC_L3", + "BriefDescription": "Ict empty for this thread due to icache misses that were sourced from the local L3" + }, + {, + "EventCode": "0x2405A", + "EventName": "PM_NTC_FIN", + "BriefDescription": "Cycles in which the oldest instruction in the pipeline (NTC) finishes. This event is used to account for cycles in which work is being completed in the CPI stack" + }, + {, + "EventCode": "0x40052", + "EventName": "PM_PUMP_MPRED", + "BriefDescription": "Pump misprediction. Counts across all types of pumps for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x30056", + "EventName": "PM_TM_ABORTS", + "BriefDescription": "Number of TM transactions aborted" + }, + {, + "EventCode": "0x2404C", + "EventName": "PM_INST_FROM_MEMORY", + "BriefDescription": "The processor's Instruction cache was reloaded from a memory location including L4 from local remote or distant due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1C05A", + "EventName": "PM_DERAT_MISS_2M", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 2M. Implies radix translation" + }, + {, + "EventCode": "0x30024", + "EventName": "PM_PMC6_OVERFLOW", + "BriefDescription": "Overflow from counter 6" + }, + {, + "EventCode": "0x10068", + "EventName": "PM_BRU_FIN", + "BriefDescription": "Branch Instruction Finished" + }, + {, + "EventCode": "0x30020", + "EventName": "PM_PMC2_REWIND", + "BriefDescription": "PMC2 Rewind Event (did not match condition)" + }, + {, + "EventCode": "0x40064", + "EventName": "PM_DUMMY2_REMOVE_ME", + "BriefDescription": "Space holder for LS_PC_RELOAD_RA" + }, + {, + "EventCode": "0x3F148", + "EventName": "PM_MRK_DPTEG_FROM_DL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D01E", + "EventName": "PM_ICT_NOSLOT_BR_MPRED", + "BriefDescription": "Ict empty for this thread due to branch mispred" + }, + {, + "EventCode": "0x3405E", + "EventName": "PM_IFETCH_THROTTLE", + "BriefDescription": "Cycles in which Instruction fetch throttle was active." + }, + {, + "EventCode": "0x1F148", + "EventName": "PM_MRK_DPTEG_FROM_ON_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on the same chip due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3E046", + "EventName": "PM_DPTEG_FROM_L21_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L2 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2F144", + "EventName": "PM_MRK_DPTEG_FROM_L31_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L3 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4C15C", + "EventName": "PM_MRK_DERAT_MISS_16G", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 16G" + }, + {, + "EventCode": "0x14052", + "EventName": "PM_INST_GRP_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for an instruction fetch" + }, + {, + "EventCode": "0xD0A8", + "EventName": "PM_DSLB_MISS", + "BriefDescription": "Data SLB Miss - Total of all segment sizes" + }, + {, + "EventCode": "0x4C058", + "EventName": "PM_MEM_CO", + "BriefDescription": "Memory castouts from this thread" + }, + {, + "EventCode": "0x40004", + "EventName": "PM_FXU_FIN", + "BriefDescription": "The fixed point unit Unit finished an instruction. Instructions that finish may not necessary complete." + }, + {, + "EventCode": "0x2C054", + "EventName": "PM_DERAT_MISS_64K", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 64K" + }, + {, + "EventCode": "0x10018", + "EventName": "PM_IC_DEMAND_CYC", + "BriefDescription": "Icache miss demand cycles" + }, + {, + "EventCode": "0x3C054", + "EventName": "PM_DERAT_MISS_16M", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 16M" + }, + {, + "EventCode": "0x2D14E", + "EventName": "PM_MRK_DATA_FROM_L21_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L2 on the same chip due to a marked load" + }, + {, + "EventCode": "0x3405C", + "EventName": "PM_CMPLU_STALL_DPLONG", + "BriefDescription": "Finish stall because the NTF instruction was a scalar multi-cycle instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Qualified by NOT vector AND multicycle" + }, + {, + "EventCode": "0x4D052", + "EventName": "PM_2FLOP_CMPL", + "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg " + }, + {, + "EventCode": "0x1F142", + "EventName": "PM_MRK_DPTEG_FROM_L2", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40062", + "EventName": "PM_DUMMY1_REMOVE_ME", + "BriefDescription": "Space holder for L2_PC_PM_MK_LDST_SCOPE_PRED_STATUS" + }, + {, + "EventCode": "0x4C012", + "EventName": "PM_CMPLU_STALL_ERAT_MISS", + "BriefDescription": "Finish stall because the NTF instruction was a load or store that suffered a translation miss" + }, + {, + "EventCode": "0x4D050", + "EventName": "PM_VSU_NON_FLOP_CMPL", + "BriefDescription": "Non FLOP operation completed" + }, + {, + "EventCode": "0x2E012", + "EventName": "PM_TM_TX_PASS_RUN_CYC", + "BriefDescription": "cycles spent in successful transactions" + }, + {, + "EventCode": "0x4D04E", + "EventName": "PM_VSU_FSQRT_FDIV", + "BriefDescription": "four flops operation (fdiv,fsqrt) Scalar Instructions only" + }, + {, + "EventCode": "0x4C120", + "EventName": "PM_MRK_DATA_FROM_L2_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state. due to a marked load" + }, + {, + "EventCode": "0x10062", + "EventName": "PM_LD_L3MISS_PEND_CYC", + "BriefDescription": "Cycles L3 miss was pending for this thread" + }, + {, + "EventCode": "0x2F14C", + "EventName": "PM_MRK_DPTEG_FROM_MEMORY", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a memory location including L4 from local remote or distant due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x14050", + "EventName": "PM_INST_CHIP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was chip pump (prediction=correct) for an instruction fetch" + }, + {, + "EventCode": "0x2000E", + "EventName": "PM_FXU_BUSY", + "BriefDescription": "Cycles in which all 4 FXUs are busy. The FXU is running at capacity" + }, + {, + "EventCode": "0x20066", + "EventName": "PM_TLB_MISS", + "BriefDescription": "TLB Miss (I + D)" + }, + {, + "EventCode": "0x10054", + "EventName": "PM_PUMP_CPRED", + "BriefDescription": "Pump prediction correct. Counts across all types of pumps for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x4D124", + "EventName": "PM_MRK_DATA_FROM_L31_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x400F8", + "EventName": "PM_FLUSH", + "BriefDescription": "Flush (any type)" + }, + {, + "EventCode": "0x30004", + "EventName": "PM_CMPLU_STALL_EMQ_FULL", + "BriefDescription": "Finish stall because the next to finish instruction suffered an ERAT miss and the EMQ was full" + }, + {, + "EventCode": "0x1D154", + "EventName": "PM_MRK_DATA_FROM_L21_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's L2 on the same chip due to a marked load" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pmc.json b/tools/perf/pmu-events/arch/powerpc/power9/pmc.json new file mode 100644 index 0000000000000000000000000000000000000000..3ef8a10aac8638965391ffef28052f5f2bc59ac5 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/pmc.json @@ -0,0 +1,122 @@ +[ + {, + "EventCode": "0x20036", + "EventName": "PM_BR_2PATH", + "BriefDescription": "Branches that are not strongly biased" + }, + {, + "EventCode": "0x40056", + "EventName": "PM_MEM_LOC_THRESH_LSU_HIGH", + "BriefDescription": "Local memory above threshold for LSU medium" + }, + {, + "EventCode": "0x2C056", + "EventName": "PM_DTLB_MISS_4K", + "BriefDescription": "Data TLB Miss page size 4k" + }, + {, + "EventCode": "0x40118", + "EventName": "PM_MRK_DCACHE_RELOAD_INTV", + "BriefDescription": "Combined Intervention event" + }, + {, + "EventCode": "0x4F148", + "EventName": "PM_MRK_DPTEG_FROM_DL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x301E8", + "EventName": "PM_THRESH_EXC_64", + "BriefDescription": "Threshold counter exceeded a value of 64" + }, + {, + "EventCode": "0x4E04E", + "EventName": "PM_DPTEG_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L3 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40050", + "EventName": "PM_SYS_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (system) ended up larger than Initial Pump Scope (Chip/Group) for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x1F14E", + "EventName": "PM_MRK_DPTEG_FROM_L2MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L2 due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D018", + "EventName": "PM_CMPLU_STALL_BRU", + "BriefDescription": "Completion stall due to a Branch Unit" + }, + {, + "EventCode": "0x45052", + "EventName": "PM_4FLOP_CMPL", + "BriefDescription": "4 FLOP instruction completed" + }, + {, + "EventCode": "0x3D142", + "EventName": "PM_MRK_DATA_FROM_LMEM", + "BriefDescription": "The processor's data cache was reloaded from the local chip's Memory due to a marked load" + }, + {, + "EventCode": "0x4C01E", + "EventName": "PM_CMPLU_STALL_CRYPTO", + "BriefDescription": "Finish stall because the NTF instruction was routed to the crypto execution pipe and was waiting to finish" + }, + {, + "EventCode": "0x3000C", + "EventName": "PM_FREQ_DOWN", + "BriefDescription": "Power Management: Below Threshold B" + }, + {, + "EventCode": "0x4D128", + "EventName": "PM_MRK_DATA_FROM_LMEM_CYC", + "BriefDescription": "Duration in cycles to reload from the local chip's Memory due to a marked load" + }, + {, + "EventCode": "0x4D054", + "EventName": "PM_8FLOP_CMPL", + "BriefDescription": "8 FLOP instruction completed" + }, + {, + "EventCode": "0x10026", + "EventName": "PM_TABLEWALK_CYC", + "BriefDescription": "Cycles when an instruction tablewalk is active" + }, + {, + "EventCode": "0x2C012", + "EventName": "PM_CMPLU_STALL_DCACHE_MISS", + "BriefDescription": "Finish stall because the NTF instruction was a load that missed the L1 and was waiting for the data to return from the nest" + }, + {, + "EventCode": "0x2E04C", + "EventName": "PM_DPTEG_FROM_MEMORY", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a memory location including L4 from local remote or distant due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3F142", + "EventName": "PM_MRK_DPTEG_FROM_L3_DISP_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 with dispatch conflict due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4F142", + "EventName": "PM_MRK_DPTEG_FROM_L3", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10060", + "EventName": "PM_TM_TRANS_RUN_CYC", + "BriefDescription": "run cycles in transactional state" + }, + {, + "EventCode": "0x1E04C", + "EventName": "PM_DPTEG_FROM_LL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's L4 cache due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x45050", + "EventName": "PM_1FLOP_CMPL", + "BriefDescription": "one flop (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg) operation completed" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/translation.json b/tools/perf/pmu-events/arch/powerpc/power9/translation.json new file mode 100644 index 0000000000000000000000000000000000000000..8c0f12024afaf78ea0cc85bb71204a4c1e23dd38 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/translation.json @@ -0,0 +1,232 @@ +[ + {, + "EventCode": "0x1E", + "EventName": "PM_CYC", + "BriefDescription": "Processor cycles" + }, + {, + "EventCode": "0x30010", + "EventName": "PM_PMC2_OVERFLOW", + "BriefDescription": "Overflow from counter 2" + }, + {, + "EventCode": "0x3C046", + "EventName": "PM_DATA_FROM_L21_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L2 on the same chip due to a demand load" + }, + {, + "EventCode": "0x4D05C", + "EventName": "PM_DP_QP_FLOP_CMPL", + "BriefDescription": "Double-Precion or Quad-Precision instruction completed" + }, + {, + "EventCode": "0x4E04C", + "EventName": "PM_DPTEG_FROM_DMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group (Distant) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x20016", + "EventName": "PM_ST_FIN", + "BriefDescription": "Store finish count. Includes speculative activity" + }, + {, + "EventCode": "0x44042", + "EventName": "PM_INST_FROM_L3", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1504A", + "EventName": "PM_IPTEG_FROM_RL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x40132", + "EventName": "PM_MRK_LSU_FIN", + "BriefDescription": "lsu marked instr PPC finish" + }, + {, + "EventCode": "0x3C05C", + "EventName": "PM_CMPLU_STALL_VFXU", + "BriefDescription": "Finish stall due to a vector fixed point instruction in the execution pipeline. These instructions get routed to the ALU, ALU2, and DIV pipes" + }, + {, + "EventCode": "0x30066", + "EventName": "PM_LSU_FIN", + "BriefDescription": "LSU Finished a PPC instruction (up to 4 per cycle)" + }, + {, + "EventCode": "0x2011C", + "EventName": "PM_MRK_NTC_CYC", + "BriefDescription": "Cycles during which the marked instruction is next to complete (completion is held up because the marked instruction hasn't completed yet)" + }, + {, + "EventCode": "0x3E048", + "EventName": "PM_DPTEG_FROM_DL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2E018", + "EventName": "PM_CMPLU_STALL_VFXLONG", + "BriefDescription": "Completion stall due to a long latency vector fixed point instruction (division, square root)" + }, + {, + "EventCode": "0x1C04E", + "EventName": "PM_DATA_FROM_L2MISS_MOD", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L2 due to a demand load" + }, + {, + "EventCode": "0x15048", + "EventName": "PM_IPTEG_FROM_ON_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x34046", + "EventName": "PM_INST_FROM_L21_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another core's L2 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1E058", + "EventName": "PM_STCX_FAIL", + "BriefDescription": "stcx failed" + }, + {, + "EventCode": "0x20112", + "EventName": "PM_MRK_NTF_FIN", + "BriefDescription": "Marked next to finish instruction finished" + }, + {, + "EventCode": "0x300F0", + "EventName": "PM_ST_MISS_L1", + "BriefDescription": "Store Missed L1" + }, + {, + "EventCode": "0x4C046", + "EventName": "PM_DATA_FROM_L21_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L2 on the same chip due to a demand load" + }, + {, + "EventCode": "0x2504A", + "EventName": "PM_IPTEG_FROM_RL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on the same Node or Group ( Remote) due to a instruction side request" + }, + {, + "EventCode": "0x2003E", + "EventName": "PM_LSU_LMQ_SRQ_EMPTY_CYC", + "BriefDescription": "Cycles in which the LSU is empty for all threads (lmq and srq are completely empty)" + }, + {, + "EventCode": "0x201E6", + "EventName": "PM_THRESH_EXC_32", + "BriefDescription": "Threshold counter exceeded a value of 32" + }, + {, + "EventCode": "0x4405C", + "EventName": "PM_CMPLU_STALL_VDP", + "BriefDescription": "Finish stall because the NTF instruction was a vector instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Not qualified multicycle. Qualified by vector" + }, + {, + "EventCode": "0x4D010", + "EventName": "PM_PMC1_SAVED", + "BriefDescription": "PMC1 Rewind Value saved" + }, + {, + "EventCode": "0x200FE", + "EventName": "PM_DATA_FROM_L2MISS", + "BriefDescription": "Demand LD - L2 Miss (not L2 hit)" + }, + {, + "EventCode": "0x2D14A", + "EventName": "PM_MRK_DATA_FROM_RL2L3_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x10028", + "EventName": "PM_STALL_END_ICT_EMPTY", + "BriefDescription": "The number a times the core transitioned from a stall to ICT-empty for this thread" + }, + {, + "EventCode": "0x2504C", + "EventName": "PM_IPTEG_FROM_MEMORY", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a memory location including L4 from local remote or distant due to a instruction side request" + }, + {, + "EventCode": "0x4504A", + "EventName": "PM_IPTEG_FROM_OFF_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a instruction side request" + }, + {, + "EventCode": "0x1404E", + "EventName": "PM_INST_FROM_L2MISS", + "BriefDescription": "The processor's Instruction cache was reloaded from a location other than the local core's L2 due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x34042", + "EventName": "PM_INST_FROM_L3_DISP_CONFLICT", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 with dispatch conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4E048", + "EventName": "PM_DPTEG_FROM_DL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x200F0", + "EventName": "PM_ST_CMPL", + "BriefDescription": "Stores completed from S2Q (2nd-level store queue)." + }, + {, + "EventCode": "0x4E05C", + "EventName": "PM_LSU_REJECT_LHS", + "BriefDescription": "LSU Reject due to LHS (up to 4 per cycle)" + }, + {, + "EventCode": "0x14044", + "EventName": "PM_INST_FROM_L3_NO_CONFLICT", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 without conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3E04C", + "EventName": "PM_DPTEG_FROM_DL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1F15E", + "EventName": "PM_MRK_PROBE_NOP_CMPL", + "BriefDescription": "Marked probeNops completed" + }, + {, + "EventCode": "0x20018", + "EventName": "PM_ST_FWD", + "BriefDescription": "Store forwards that finished" + }, + {, + "EventCode": "0x1D142", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x24042", + "EventName": "PM_INST_FROM_L3_MEPF", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 without dispatch conflicts hit on Mepf state. due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x25046", + "EventName": "PM_IPTEG_FROM_RL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x3504A", + "EventName": "PM_IPTEG_FROM_RMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group ( Remote) due to a instruction side request" + }, + {, + "EventCode": "0x3C05A", + "EventName": "PM_CMPLU_STALL_VDPLONG", + "BriefDescription": "Finish stall because the NTF instruction was a scalar multi-cycle instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Qualified by NOT vector AND multicycle" + }, + {, + "EventCode": "0x2E01C", + "EventName": "PM_CMPLU_STALL_TLBIE", + "BriefDescription": "Finish stall because the NTF instruction was a tlbie waiting for response from L2" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index d1a12e584c1b8e1223dd66266dac6745247e0aff..4ea068366c3e8e7a9d88a518b8a26d8a39141b08 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -34,3 +34,4 @@ GenuineIntel-6-2C,v2,westmereep-dp,core GenuineIntel-6-2C,v2,westmereep-dp,core GenuineIntel-6-25,v2,westmereep-sp,core GenuineIntel-6-2F,v2,westmereex,core +GenuineIntel-6-55,v1,skylakex,core diff --git a/tools/perf/pmu-events/arch/x86/skylakex/cache.json b/tools/perf/pmu-events/arch/x86/skylakex/cache.json new file mode 100644 index 0000000000000000000000000000000000000000..b5bc742b6fbcf6822424b05cfac99db34b9cbd02 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/cache.json @@ -0,0 +1,1672 @@ +[ + { + "EventCode": "0x24", + "UMask": "0x21", + "BriefDescription": "Demand Data Read miss L2, no rejects", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", + "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x22", + "BriefDescription": "RFO requests that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.RFO_MISS", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x24", + "BriefDescription": "L2 cache misses when fetching instructions", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.CODE_RD_MISS", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x27", + "BriefDescription": "Demand requests that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_MISS", + "PublicDescription": "Demand requests that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x38", + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.PF_MISS", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x3f", + "BriefDescription": "All requests that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.MISS", + "PublicDescription": "All requests that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x41", + "BriefDescription": "Demand Data Read requests that hit L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", + "PublicDescription": "Counts the number of demand Data Read requests that hit L2 cache. Only non rejected loads are counted.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x42", + "BriefDescription": "RFO requests that hit L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.RFO_HIT", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x44", + "BriefDescription": "L2 cache hits when fetching instructions, code reads.", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.CODE_RD_HIT", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xd8", + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.PF_HIT", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe1", + "BriefDescription": "Demand Data Read requests", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", + "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe2", + "BriefDescription": "RFO requests to L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_RFO", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe4", + "BriefDescription": "L2 code requests", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_CODE_RD", + "PublicDescription": "Counts the total number of L2 code requests.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe7", + "BriefDescription": "Demand requests to L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", + "PublicDescription": "Demand requests to L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xf8", + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_PF", + "PublicDescription": "Counts the total number of requests from the L2 hardware prefetchers.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xff", + "BriefDescription": "All L2 requests", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.REFERENCES", + "PublicDescription": "All L2 requests.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x2E", + "UMask": "0x41", + "BriefDescription": "Core-originated cacheable demand requests missed L3", + "Counter": "0,1,2,3", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all misses to the L3.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x2E", + "UMask": "0x4f", + "BriefDescription": "Core-originated cacheable demand requests that refer to L3", + "Counter": "0,1,2,3", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all accesses to the L3.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x1", + "BriefDescription": "L1D miss outstandings duration in cycles", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING", + "PublicDescription": "Counts duration of L1D miss outstanding, that is each cycle number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch.Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x1", + "BriefDescription": "Cycles with L1D load Misses outstanding.", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x1", + "BriefDescription": "Cycles with L1D load Misses outstanding from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES_ANY", + "AnyThread": "1", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x2", + "BriefDescription": "Number of times a request needed a FB entry but there was no entry available for it. That is the FB unavailability was dominant reason for blocking the request. A request includes cacheable/uncacheable demands that is load, store or SW prefetch.", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.FB_FULL", + "PublicDescription": "Number of times a request needed a FB (Fill Buffer) entry but there was no entry available for it. A request includes cacheable/uncacheable demands that are load, store or SW prefetch instructions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x51", + "UMask": "0x1", + "BriefDescription": "L1D data line replacements", + "Counter": "0,1,2,3", + "EventName": "L1D.REPLACEMENT", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x1", + "BriefDescription": "Offcore outstanding Demand Data Read transactions in uncore queue.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding Demand Data Read transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor. See the corresponding Umask under OFFCORE_REQUESTS.Note: A prefetch promoted to Demand is counted from the promotion point.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x1", + "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", + "CounterMask": "1", + "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x1", + "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", + "CounterMask": "6", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x2", + "BriefDescription": "Offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore, every cycle. ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x2", + "BriefDescription": "Cycles with offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_CODE_RD", + "CounterMask": "1", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x4", + "BriefDescription": "Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", + "PublicDescription": "Counts the number of offcore outstanding RFO (store) transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x4", + "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", + "CounterMask": "1", + "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x8", + "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x8", + "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", + "CounterMask": "1", + "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x1", + "BriefDescription": "Demand Data Read requests sent to uncore", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x2", + "BriefDescription": "Cacheable and noncachaeble code read requests", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_CODE_RD", + "PublicDescription": "Counts both cacheable and non-cacheable code read requests.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x4", + "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", + "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x8", + "BriefDescription": "Demand and prefetch data reads", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x80", + "BriefDescription": "Any memory transaction that reached the SQ.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", + "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB2", + "UMask": "0x1", + "BriefDescription": "Offcore requests buffer cannot take more entries for this thread core.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_BUFFER.SQ_FULL", + "PublicDescription": "Counts the number of cases when the offcore requests buffer cannot take more entries for the core. This can happen when the superqueue does not contain eligible entries, or when L1D writeback pending FIFO requests is full.Note: Writeback pending FIFO has six entries.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x11", + "BriefDescription": "Retired load instructions that miss the STLB.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x12", + "BriefDescription": "Retired store instructions that miss the STLB.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", + "SampleAfterValue": "100003", + "L1_Hit_Indication": "1", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x21", + "BriefDescription": "Retired load instructions with locked access.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.LOCK_LOADS", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x41", + "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x42", + "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.SPLIT_STORES", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "L1_Hit_Indication": "1", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x81", + "BriefDescription": "All retired load instructions.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.ALL_LOADS", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x82", + "BriefDescription": "All retired store instructions.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.ALL_STORES", + "SampleAfterValue": "2000003", + "L1_Hit_Indication": "1", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x1", + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x2", + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "PublicDescription": "Retired load instructions with L2 cache hits as data sources.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x4", + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache. ", + "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x8", + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x10", + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "PublicDescription": "Retired load instructions missed L2 cache as data sources.", + "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x20", + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache. ", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x40", + "BriefDescription": "Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready. ", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x1", + "BriefDescription": "Retired load instructions which data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x2", + "BriefDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", + "PublicDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache.", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x4", + "BriefDescription": "Retired load instructions which data sources were HitM responses from shared L3", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", + "PublicDescription": "Retired load instructions which data sources were HitM responses from shared L3.", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x8", + "BriefDescription": "Retired load instructions which data sources were hits in L3 without snoops required", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "PublicDescription": "Retired load instructions which data sources were hits in L3 without snoops required.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x1", + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", + "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x2", + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from remote dram", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x4", + "BriefDescription": "Retired load instructions whose data sources was remote HITM", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", + "PublicDescription": "Retired load instructions whose data sources was remote HITM.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x8", + "BriefDescription": "Retired load instructions whose data sources was forwarded from a remote cache", + "Data_LA": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_FWD", + "PublicDescription": "Retired load instructions whose data sources was forwarded from a remote cache.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD4", + "UMask": "0x4", + "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_MISC_RETIRED.UC", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xF0", + "UMask": "0x40", + "BriefDescription": "L2 writebacks that access L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_TRANS.L2_WB", + "PublicDescription": "Counts L2 writebacks that access L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF1", + "UMask": "0x1f", + "BriefDescription": "L2 cache lines filling L2", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_IN.ALL", + "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x1", + "BriefDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared state. A non-threaded event.", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.SILENT", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x2", + "BriefDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped ", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.NON_SILENT", + "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x4", + "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.USELESS_PREF", + "PublicDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x4", + "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.USELESS_HWPF", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF4", + "UMask": "0x10", + "BriefDescription": "Number of cache line split locks sent to uncore.", + "Counter": "0,1,2,3", + "EventName": "SQ_MISC.SPLIT_LOCK", + "PublicDescription": "Counts the number of cache line split locks sent to the uncore.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that have any response type.", + "MSRValue": "0x0000010001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "DEMAND_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3.", + "MSRValue": "0x3f803c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that have any response type.", + "MSRValue": "0x0000010002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "DEMAND_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3.", + "MSRValue": "0x3f803c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that have any response type.", + "MSRValue": "0x0000010004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "DEMAND_CODE_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3.", + "MSRValue": "0x3f803c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that have any response type.", + "MSRValue": "0x0000010010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L2_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3.", + "MSRValue": "0x3f803c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that have any response type.", + "MSRValue": "0x0000010020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L2_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3.", + "MSRValue": "0x3f803c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that have any response type.", + "MSRValue": "0x0000010080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L3_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3.", + "MSRValue": "0x3f803c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that have any response type.", + "MSRValue": "0x0000010100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L3_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3.", + "MSRValue": "0x3f803c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that have any response type.", + "MSRValue": "0x0000010400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L1D_AND_SW & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3.", + "MSRValue": "0x3f803c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that have any response type.", + "MSRValue": "0x0000010490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_PF_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3.", + "MSRValue": "0x3f803c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that have any response type.", + "MSRValue": "0x0000010120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_PF_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3.", + "MSRValue": "0x3f803c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that have any response type.", + "MSRValue": "0x0000010491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3.", + "MSRValue": "0x3f803c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that have any response type.", + "MSRValue": "0x0000010122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3.", + "MSRValue": "0x3f803c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json b/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json new file mode 100644 index 0000000000000000000000000000000000000000..1c09a328df36c0d7e8f5f01936a156650605d48f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json @@ -0,0 +1,88 @@ +[ + { + "EventCode": "0xC7", + "UMask": "0x1", + "BriefDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired. Each count represents 1 computation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x2", + "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x4", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired. Each count represents 2 computations. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x8", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired. Each count represents 4 computations. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element. ", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", + "PublicDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired. Each count represents 4 computations. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x10", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired. Each count represents 4 computations. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x20", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired. Each count represents 8 computations. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x40", + "BriefDescription": "Number of Packed Double-Precision FP arithmetic instructions (Use operation multiplier of 8)", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", + "PublicDescription": "Number of Packed Double-Precision FP arithmetic instructions (Use operation multiplier of 8).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x80", + "BriefDescription": "Number of Packed Single-Precision FP arithmetic instructions (Use operation multiplier of 16)", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", + "PublicDescription": "Number of Packed Single-Precision FP arithmetic instructions (Use operation multiplier of 16).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCA", + "UMask": "0x1e", + "BriefDescription": "Cycles with any input/output SSE or FP assist", + "Counter": "0,1,2,3", + "EventName": "FP_ASSIST.ANY", + "CounterMask": "1", + "PublicDescription": "Counts cycles with any input and output SSE or x87 FP assist. If an input and output assist are detected on the same cycle the event increments by 1.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/frontend.json b/tools/perf/pmu-events/arch/x86/skylakex/frontend.json new file mode 100644 index 0000000000000000000000000000000000000000..40abc0852cd663073ccf60296a92fdf47da9473d --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/frontend.json @@ -0,0 +1,482 @@ +[ + { + "EventCode": "0x79", + "UMask": "0x4", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", + "Counter": "0,1,2,3", + "EventName": "IDQ.MITE_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x4", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path", + "Counter": "0,1,2,3", + "EventName": "IDQ.MITE_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x8", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", + "Counter": "0,1,2,3", + "EventName": "IDQ.DSB_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x8", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path", + "Counter": "0,1,2,3", + "EventName": "IDQ.DSB_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x10", + "BriefDescription": "Cycles when uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_DSB_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x18", + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering 4 Uops", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_DSB_CYCLES_4_UOPS", + "CounterMask": "4", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x18", + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_DSB_CYCLES_ANY_UOPS", + "CounterMask": "1", + "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x20", + "BriefDescription": "Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_MITE_UOPS", + "PublicDescription": "Counts the number of uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x24", + "BriefDescription": "Cycles MITE is delivering 4 Uops", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_MITE_CYCLES_4_UOPS", + "CounterMask": "4", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x24", + "BriefDescription": "Cycles MITE is delivering any Uop", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_MITE_CYCLES_ANY_UOPS", + "CounterMask": "1", + "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x30", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "EventCode": "0x79", + "UMask": "0x30", + "BriefDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_SWITCHES", + "CounterMask": "1", + "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x30", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_UOPS", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x80", + "UMask": "0x4", + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_16B.IFDATA_STALL", + "PublicDescription": "Cycles where a code line fetch is stalled due to an L1 instruction cache miss. The legacy decode pipeline works at a 16 Byte granularity.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x83", + "UMask": "0x1", + "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_HIT", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x83", + "UMask": "0x2", + "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_MISS", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x83", + "UMask": "0x4", + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_STALL", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Uops not delivered to Resource Allocation Table (RAT) per thread when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", + "PublicDescription": "Counts the number of uops not delivered to Resource Allocation Table (RAT) per thread adding \u201c4 \u2013 x\u201d when Resource Allocation Table (RAT) is not stalled and Instruction Decode Queue (IDQ) delivers x uops to Resource Allocation Table (RAT) (where x belongs to {0,1,2,3}). Counting does not cover cases when: a. IDQ-Resource Allocation Table (RAT) pipe serves the other thread. b. Resource Allocation Table (RAT) is stalled for the thread (including uop drops and clear BE conditions). c. Instruction Decode Queue (IDQ) delivers four uops.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles per thread when 4 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", + "CounterMask": "4", + "PublicDescription": "Counts, on the per-thread basis, cycles when no uops are delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core =4.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles per thread when 3 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE", + "CounterMask": "3", + "PublicDescription": "Counts, on the per-thread basis, cycles when less than 1 uop is delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core >= 3.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles with less than 2 uops delivered by the front end.", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE", + "CounterMask": "2", + "PublicDescription": "Cycles with less than 2 uops delivered by the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles with less than 3 uops delivered by the front end.", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE", + "CounterMask": "1", + "PublicDescription": "Cycles with less than 3 uops delivered by the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Counts cycles FE delivered 4 uops or Resource Allocation Table (RAT) was stalling FE.", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xAB", + "UMask": "0x2", + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles.", + "Counter": "0,1,2,3", + "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", + "PublicDescription": "Counts Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles. These cycles do not include uops routed through because of the switch itself, for example, when Instruction Decode Queue (IDQ) pre-allocation is unavailable, or Instruction Decode Queue (IDQ) is full. SBD-to-MITE switch true penalty cycles happen after the merge mux (MM) receives Decode Stream Buffer (DSB) Sync-indication until receiving the first MITE uop. MM is placed before Instruction Decode Queue (IDQ) to merge uops being fed from the MITE and Decode Stream Buffer (DSB) paths. Decode Stream Buffer (DSB) inserts the Sync-indication whenever a Decode Stream Buffer (DSB)-to-MITE switch occurs.Penalty: A Decode Stream Buffer (DSB) hit followed by a Decode Stream Buffer (DSB) miss can cost up to six cycles in which no uops are delivered to the IDQ. Most often, such switches from the Decode Stream Buffer (DSB) to the legacy pipeline cost 0\u20132 cycles.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced decode stream buffer (DSB - the decoded instruction-cache) miss.", + "PEBS": "1", + "MSRValue": "0x11", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.DSB_MISS", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss. ", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", + "PEBS": "1", + "MSRValue": "0x12", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.L1I_MISS", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", + "PEBS": "1", + "MSRValue": "0x13", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.L2_MISS", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced iTLB true miss.", + "PEBS": "1", + "MSRValue": "0x14", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.ITLB_MISS", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "PEBS": "1", + "MSRValue": "0x15", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.STLB_MISS", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss. ", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x400206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 2 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x200206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_2", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x400406", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x400806", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x401006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x402006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x404006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_64", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x408006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x410006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x420006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x100206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 3 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x300206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_3", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/memory.json b/tools/perf/pmu-events/arch/x86/skylakex/memory.json new file mode 100644 index 0000000000000000000000000000000000000000..ca22a22c1abd8c86948832dc57f6627be38eb0d1 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/memory.json @@ -0,0 +1,1396 @@ +[ + { + "EventCode": "0x54", + "UMask": "0x1", + "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_CONFLICT", + "PublicDescription": "Number of times a TSX line had a cache conflict.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x2", + "BriefDescription": "Number of times a transactional abort was signaled due to a data capacity limitation for transactional reads or writes.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_CAPACITY", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x4", + "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", + "PublicDescription": "Number of times a TSX Abort was triggered due to a non-release/commit store to lock.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x8", + "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", + "PublicDescription": "Number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x10", + "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", + "PublicDescription": "Number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x20", + "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", + "PublicDescription": "Number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x40", + "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", + "PublicDescription": "Number of times we could not allocate Lock Buffer.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x1", + "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed. Since this is the count of execution, it may not always cause a transactional abort.", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x2", + "BriefDescription": "Counts the number of times a class of instructions (e.g., vzeroupper) that may cause a transactional abort was executed inside a transactional region", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC2", + "PublicDescription": "Unfriendly TSX abort triggered by a vzeroupper instruction.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x4", + "BriefDescription": "Counts the number of times an instruction execution caused the transactional nest count supported to be exceeded", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC3", + "PublicDescription": "Unfriendly TSX abort triggered by a nest count that is too deep.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x8", + "BriefDescription": "Counts the number of times a XBEGIN instruction was executed inside an HLE transactional region.", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC4", + "PublicDescription": "RTM region detected inside HLE.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x10", + "BriefDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC5", + "PublicDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x10", + "BriefDescription": "Counts number of Offcore outstanding Demand Data Read requests that miss L3 cache in the superQ every cycle.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x10", + "BriefDescription": "Cycles with at least 1 Demand Data Read requests who miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_L3_MISS_DEMAND_DATA_RD", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x10", + "BriefDescription": "Cycles with at least 6 Demand Data Read requests that miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD_GE_6", + "CounterMask": "6", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x2", + "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", + "CounterMask": "2", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x6", + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "CounterMask": "6", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x10", + "BriefDescription": "Demand Data Read requests who miss L3 cache", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC3", + "UMask": "0x2", + "BriefDescription": "Counts the number of machine clears due to memory order conflicts.", + "Counter": "0,1,2,3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "Errata": "SKL089", + "PublicDescription": "Counts the number of memory ordering Machine Clears detected. Memory Ordering Machine Clears can result from one of the following:a. memory disambiguation,b. external snoop, orc. cross SMT-HW-thread snoop (stores) hitting load buffer.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x1", + "BriefDescription": "Number of times an HLE execution started.", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.START", + "PublicDescription": "Number of times we entered an HLE region. Does not count nested transactions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x2", + "BriefDescription": "Number of times an HLE execution successfully committed", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.COMMIT", + "PublicDescription": "Number of times HLE commit succeeded.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x4", + "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one). ", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED", + "PublicDescription": "Number of times HLE abort was triggered.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x8", + "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_MEM", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x10", + "BriefDescription": "Number of times an HLE execution aborted due to hardware timer expiration.", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x20", + "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.). ", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", + "PublicDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x40", + "BriefDescription": "Number of times an HLE execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an HLE execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x80", + "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts).", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_EVENTS", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x1", + "BriefDescription": "Number of times an RTM execution started.", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.START", + "PublicDescription": "Number of times we entered an RTM region. Does not count nested transactions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x2", + "BriefDescription": "Number of times an RTM execution successfully committed", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.COMMIT", + "PublicDescription": "Number of times RTM commit succeeded.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x4", + "BriefDescription": "Number of times an RTM execution aborted due to any reasons (multiple categories may count as one). ", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED", + "PublicDescription": "Number of times RTM abort was triggered.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x8", + "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_MEM", + "PublicDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x10", + "BriefDescription": "Number of times an RTM execution aborted due to uncommon conditions.", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x20", + "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", + "PublicDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x40", + "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an RTM execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x80", + "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_EVENTS", + "PublicDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 4 cycles.", + "PEBS": "2", + "MSRValue": "0x4", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 8 cycles.", + "PEBS": "2", + "MSRValue": "0x8", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 16 cycles.", + "PEBS": "2", + "MSRValue": "0x10", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 32 cycles.", + "PEBS": "2", + "MSRValue": "0x20", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 64 cycles.", + "PEBS": "2", + "MSRValue": "0x40", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "2003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 128 cycles.", + "PEBS": "2", + "MSRValue": "0x80", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "1009", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 256 cycles.", + "PEBS": "2", + "MSRValue": "0x100", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "503", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 512 cycles.", + "PEBS": "2", + "MSRValue": "0x200", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "101", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss in the L3.", + "MSRValue": "0x3fbc000001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss in the L3.", + "MSRValue": "0x3fbc000002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss in the L3.", + "MSRValue": "0x3fbc000004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss in the L3.", + "MSRValue": "0x3fbc000010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss in the L3.", + "MSRValue": "0x3fbc000020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss in the L3.", + "MSRValue": "0x3fbc000080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss in the L3.", + "MSRValue": "0x3fbc000100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss in the L3.", + "MSRValue": "0x3fbc000400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss in the L3.", + "MSRValue": "0x3fbc000490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss in the L3.", + "MSRValue": "0x3fbc000120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss in the L3.", + "MSRValue": "0x3fbc000491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss in the L3.", + "MSRValue": "0x3fbc000122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local dram.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/other.json b/tools/perf/pmu-events/arch/x86/skylakex/other.json new file mode 100644 index 0000000000000000000000000000000000000000..70243b0b0586cad66ada01cd29d8bcb140f42a39 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/other.json @@ -0,0 +1,72 @@ +[ + { + "EventCode": "0x28", + "UMask": "0x7", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.LVL0_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for baseline license level 0. This includes non-AVX codes, SSE, AVX 128-bit, and low-current AVX 256-bit codes.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x28", + "UMask": "0x18", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX2 turbo schedule.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.LVL1_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 1. This includes high current AVX 256-bit instructions as well as low current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x28", + "UMask": "0x20", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server michroarchtecture). This includes high current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x28", + "UMask": "0x40", + "BriefDescription": "Core cycles the core was throttled due to a pending power level request.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.THROTTLE", + "PublicDescription": "Core cycles the out-of-order engine was throttled due to a pending power level request.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCB", + "UMask": "0x1", + "BriefDescription": "Number of hardware interrupts received by the processor.", + "Counter": "0,1,2,3", + "EventName": "HW_INTERRUPTS.RECEIVED", + "PublicDescription": "Counts the number of hardware interruptions received by the processor.", + "SampleAfterValue": "203", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xFE", + "UMask": "0x2", + "BriefDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly", + "Counter": "0,1,2,3", + "EventName": "IDI_MISC.WB_UPGRADE", + "PublicDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xFE", + "UMask": "0x4", + "BriefDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly", + "Counter": "0,1,2,3", + "EventName": "IDI_MISC.WB_DOWNGRADE", + "PublicDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json b/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json new file mode 100644 index 0000000000000000000000000000000000000000..0895d1e52a4a639b143183f4e9792e0475f715af --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json @@ -0,0 +1,950 @@ +[ + { + "EventCode": "0x00", + "UMask": "0x1", + "BriefDescription": "Instructions retired from execution.", + "Counter": "Fixed counter 1", + "EventName": "INST_RETIRED.ANY", + "PublicDescription": "Counts the number of instructions retired from execution. For instructions that consist of multiple micro-ops, Counts the retirement of the last micro-op of the instruction. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. INST_RETIRED.ANY_P is counted by a programmable counter and it is an architectural performance event. Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not count as retired instructions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 1" + }, + { + "EventCode": "0x00", + "UMask": "0x2", + "BriefDescription": "Core cycles when the thread is not in halt state", + "Counter": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 2" + }, + { + "EventCode": "0x00", + "UMask": "0x2", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "Counter": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.THREAD_ANY", + "AnyThread": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 2" + }, + { + "EventCode": "0x00", + "UMask": "0x3", + "BriefDescription": "Reference cycles when the core is not in halt state.", + "Counter": "Fixed counter 3", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 3" + }, + { + "EventCode": "0x03", + "UMask": "0x2", + "BriefDescription": "Loads blocked by overlapping with store buffer that cannot be forwarded .", + "Counter": "0,1,2,3", + "EventName": "LD_BLOCKS.STORE_FORWARD", + "PublicDescription": "Counts how many times the load operation got the true Block-on-Store blocking code preventing store forwarding. This includes cases when:a. preceding store conflicts with the load (incomplete overlap),b. store forwarding is impossible due to u-arch limitations,c. preceding lock RMW operations are not forwarded,d. store has the no-forward bit set (uncacheable/page-split/masked stores),e. all-blocking stores are used (mostly, fences and port I/O), and others.The most common case is a load blocked due to its address range overlapping with a preceding smaller uncompleted store. Note: This event does not take into account cases of out-of-SW-control (for example, SbTailHit), unknown physical STA, and cases of blocking loads on store due to being non-WB memory type or a lock. These cases are covered by other events. See the table of not supported store forwards in the Optimization Guide.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x03", + "UMask": "0x8", + "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use", + "Counter": "0,1,2,3", + "EventName": "LD_BLOCKS.NO_SR", + "PublicDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x07", + "UMask": "0x1", + "BriefDescription": "False dependencies in MOB due to partial compare on address.", + "Counter": "0,1,2,3", + "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", + "PublicDescription": "Counts false dependencies in MOB when the partial comparison upon loose net check and dependency was resolved by the Enhanced Loose net mechanism. This may not result in high performance penalties. Loose net checks can fail when loads and stores are 4k aliased.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0D", + "UMask": "0x1", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread (e.g. misprediction or memory nuke)", + "Counter": "0,1,2,3", + "EventName": "INT_MISC.RECOVERY_CYCLES", + "PublicDescription": "Core cycles the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0D", + "UMask": "0x1", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for any thread running on the physical core (e.g. misprediction or memory nuke).", + "Counter": "0,1,2,3", + "EventName": "INT_MISC.RECOVERY_CYCLES_ANY", + "AnyThread": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0D", + "UMask": "0x80", + "BriefDescription": "Cycles the issue-stage is waiting for front-end to fetch from resteered path following branch misprediction or machine clear events.", + "Counter": "0,1,2,3", + "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0E", + "UMask": "0x1", + "BriefDescription": "Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.ANY", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0x0E", + "UMask": "0x1", + "BriefDescription": "Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.STALL_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0E", + "UMask": "0x2", + "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", + "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to \u201cMixing Intel AVX and Intel SSE Code\u201d section of the Optimization Guide.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0E", + "UMask": "0x20", + "BriefDescription": "Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.SLOW_LEA", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x14", + "UMask": "0x1", + "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "Counter": "0,1,2,3", + "EventName": "ARITH.DIVIDER_ACTIVE", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x0", + "BriefDescription": "Thread cycles when thread is not in halt state", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x0", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.THREAD_P_ANY", + "AnyThread": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "EventCode": "0x3C", + "UMask": "0x0", + "BriefDescription": "Counts when there is a transition from ring 1, 2 or 3 to ring 0.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.RING0_TRANS", + "CounterMask": "1", + "PublicDescription": "Counts when the Current Privilege Level (CPL) transitions from ring 1, 2 or 3 to ring 0 (Kernel).", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY", + "AnyThread": "1", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK_ANY", + "AnyThread": "1", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x2", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x2", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x4C", + "UMask": "0x1", + "BriefDescription": "Demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", + "Counter": "0,1,2,3", + "EventName": "LOAD_HIT_PRE.SW_PF", + "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5E", + "UMask": "0x1", + "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", + "Counter": "0,1,2,3", + "EventName": "RS_EVENTS.EMPTY_CYCLES", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for the thread.; Note: In ST-mode, not active thread should drive 0. This is usually caused by severely costly branch mispredictions, or allocator/FE issues.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "Invert": "1", + "EventCode": "0x5E", + "UMask": "0x1", + "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate Frontend Latency Bound issues.", + "Counter": "0,1,2,3", + "EventName": "RS_EVENTS.EMPTY_END", + "CounterMask": "1", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate front-end Latency Bound issues.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x87", + "UMask": "0x1", + "BriefDescription": "Stalls caused by changing prefix length of the instruction.", + "Counter": "0,1,2,3", + "EventName": "ILD_STALL.LCP", + "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x1", + "BriefDescription": "Cycles per thread when uops are executed in port 0", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_0", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x2", + "BriefDescription": "Cycles per thread when uops are executed in port 1", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_1", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x4", + "BriefDescription": "Cycles per thread when uops are executed in port 2", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 2.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x8", + "BriefDescription": "Cycles per thread when uops are executed in port 3", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_3", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 3.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x10", + "BriefDescription": "Cycles per thread when uops are executed in port 4", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_4", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 4.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x20", + "BriefDescription": "Cycles per thread when uops are executed in port 5", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_5", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x40", + "BriefDescription": "Cycles per thread when uops are executed in port 6", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_6", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x80", + "BriefDescription": "Cycles per thread when uops are executed in port 7", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 7.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA2", + "UMask": "0x1", + "BriefDescription": "Resource-related stall cycles", + "Counter": "0,1,2,3", + "EventName": "RESOURCE_STALLS.ANY", + "PublicDescription": "Counts resource-related stall cycles. Reasons for stalls can be as follows:a. *any* u-arch structure got full (LB, SB, RS, ROB, BOB, LM, Physical Register Reclaim Table (PRRT), or Physical History Table (PHT) slots).b. *any* u-arch structure got empty (like INT/SIMD FreeLists).c. FPU control word (FPCW), MXCSR.and others. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA2", + "UMask": "0x8", + "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", + "Counter": "0,1,2,3", + "EventName": "RESOURCE_STALLS.SB", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x1", + "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x4", + "BriefDescription": "Total execution stalls.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", + "CounterMask": "4", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x5", + "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", + "CounterMask": "5", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x8", + "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", + "CounterMask": "8", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0xc", + "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", + "CounterMask": "12", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x10", + "BriefDescription": "Cycles while memory subsystem has an outstanding load.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", + "CounterMask": "16", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x14", + "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", + "CounterMask": "20", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xA6", + "UMask": "0x1", + "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", + "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x2", + "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x4", + "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x8", + "BriefDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.3_PORTS_UTIL", + "PublicDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x10", + "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", + "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x40", + "BriefDescription": "Cycles where the Store Buffer was full and no outstanding load.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA8", + "UMask": "0x1", + "BriefDescription": "Number of Uops delivered by the LSD.", + "Counter": "0,1,2,3", + "EventName": "LSD.UOPS", + "PublicDescription": "Number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA8", + "UMask": "0x1", + "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", + "Counter": "0,1,2,3", + "EventName": "LSD.CYCLES_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA8", + "UMask": "0x1", + "BriefDescription": "Cycles 4 Uops delivered by the LSD, but didn't come from the decoder.", + "Counter": "0,1,2,3", + "EventName": "LSD.CYCLES_4_UOPS", + "CounterMask": "4", + "PublicDescription": "Counts the cycles when 4 uops are delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.THREAD", + "PublicDescription": "Number of uops to be executed per-thread each cycle.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.STALL_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 1 uop was executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_1_UOP_EXEC", + "CounterMask": "1", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 2 uops were executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_2_UOPS_EXEC", + "CounterMask": "2", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 3 uops were executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_3_UOPS_EXEC", + "CounterMask": "3", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 4 uops were executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_4_UOPS_EXEC", + "CounterMask": "4", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Number of uops executed on the core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE", + "PublicDescription": "Number of uops executed from any thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", + "CounterMask": "2", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "CounterMask": "3", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", + "CounterMask": "4", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles with no micro-ops executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_NONE", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x10", + "BriefDescription": "Counts the number of x87 uops dispatched.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.X87", + "PublicDescription": "Counts the number of x87 uops executed.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC0", + "UMask": "0x0", + "BriefDescription": "Number of instructions retired. General Counter - architectural event", + "Counter": "0,1,2,3", + "EventName": "INST_RETIRED.ANY_P", + "Errata": "SKL091, SKL044", + "PublicDescription": "Counts the number of instructions (EOMs) retired. Counting covers macro-fused instructions individually (that is, increments by two).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC0", + "UMask": "0x1", + "BriefDescription": "Precise instruction retired event with HW to reduce effect of PEBS shadow in IP distribution", + "PEBS": "2", + "Counter": "1", + "EventName": "INST_RETIRED.PREC_DIST", + "Errata": "SKL091, SKL044", + "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled.", + "SampleAfterValue": "2000003", + "CounterHTOff": "1" + }, + { + "Invert": "1", + "EventCode": "0xC0", + "UMask": "0x1", + "BriefDescription": "Number of cycles using always true condition applied to PEBS instructions retired event.", + "PEBS": "2", + "Counter": "0,2,3", + "EventName": "INST_RETIRED.TOTAL_CYCLES_PS", + "CounterMask": "10", + "Errata": "SKL091, SKL044", + "PublicDescription": "Number of cycles using an always true condition applied to PEBS instructions retired event. (inst_ret< 16)", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,2,3" + }, + { + "EventCode": "0xC1", + "UMask": "0x3f", + "BriefDescription": "Number of times a microcode assist is invoked by HW other than FP-assist. Examples include AD (page Access Dirty) and AVX* related assists.", + "Counter": "0,1,2,3", + "EventName": "OTHER_ASSISTS.ANY", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC2", + "UMask": "0x2", + "BriefDescription": "Retirement slots used.", + "Counter": "0,1,2,3", + "EventName": "UOPS_RETIRED.RETIRE_SLOTS", + "PublicDescription": "Counts the retirement slots used.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xC2", + "UMask": "0x2", + "BriefDescription": "Cycles without actually retired uops.", + "Counter": "0,1,2,3", + "EventName": "UOPS_RETIRED.STALL_CYCLES", + "CounterMask": "1", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts cycles without actually retired uops.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xC2", + "UMask": "0x2", + "BriefDescription": "Cycles with less than 10 actually retired uops.", + "Counter": "0,1,2,3", + "EventName": "UOPS_RETIRED.TOTAL_CYCLES", + "CounterMask": "10", + "PublicDescription": "Number of cycles using always true condition (uops_ret < 16) applied to non PEBS uops retired event.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "EventCode": "0xC3", + "UMask": "0x1", + "BriefDescription": "Number of machine clears (nukes) of any type. ", + "Counter": "0,1,2,3", + "EventName": "MACHINE_CLEARS.COUNT", + "CounterMask": "1", + "PublicDescription": "Number of machine clears (nukes) of any type.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC3", + "UMask": "0x4", + "BriefDescription": "Self-modifying code (SMC) detected.", + "Counter": "0,1,2,3", + "EventName": "MACHINE_CLEARS.SMC", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x0", + "BriefDescription": "All (macro) branch instructions retired.", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "Errata": "SKL091", + "PublicDescription": "Counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x1", + "BriefDescription": "Conditional branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.CONDITIONAL", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts conditional branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x2", + "BriefDescription": "Direct and indirect near call instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts both direct and indirect near call instructions retired.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x4", + "BriefDescription": "All (macro) branch instructions retired. ", + "PEBS": "2", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES_PEBS", + "Errata": "SKL091", + "PublicDescription": "This is a precise version of BR_INST_RETIRED.ALL_BRANCHES that counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC4", + "UMask": "0x8", + "BriefDescription": "Return instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts return instructions retired.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x10", + "BriefDescription": "Not taken branch instructions retired.", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NOT_TAKEN", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x20", + "BriefDescription": "Taken branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NEAR_TAKEN", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts taken branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x40", + "BriefDescription": "Far branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts far branch instructions retired.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x0", + "BriefDescription": "All mispredicted macro branch instructions retired.", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x1", + "BriefDescription": "Mispredicted conditional branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.CONDITIONAL", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts mispredicted conditional branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x2", + "BriefDescription": "Mispredicted direct and indirect near call instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.NEAR_CALL", + "PublicDescription": "Counts both taken and not taken retired mispredicted direct and indirect near calls, including both register and memory indirect.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x4", + "BriefDescription": "Mispredicted macro branch instructions retired. ", + "PEBS": "2", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES_PEBS", + "PublicDescription": "This is a precise version of BR_MISP_RETIRED.ALL_BRANCHES that counts all mispredicted macro branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC5", + "UMask": "0x20", + "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCC", + "UMask": "0x20", + "BriefDescription": "Increments whenever there is an update to the LBR array.", + "Counter": "0,1,2,3", + "EventName": "ROB_MISC_EVENTS.LBR_INSERTS", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xE6", + "UMask": "0x1", + "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", + "Counter": "0,1,2,3", + "EventName": "BACLEARS.ANY", + "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json b/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json new file mode 100644 index 0000000000000000000000000000000000000000..9c7e5f8beee29ccf860160dc31ad07eb23049a0c --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json @@ -0,0 +1,172 @@ +[ + { + "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_READ", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x3", + "Unit": "iMC" + }, + { + "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_WRITE", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0xC", + "Unit": "iMC" + }, + { + "BriefDescription": "Memory controller clock ticks", + "Counter": "0,1,2,3", + "EventName": "UNC_M_CLOCKTICKS", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "UNC_M_POWER_CHANNEL_PPD", + "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.", + "MetricName": "power_channel_ppd %", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Cycles Memory is in self refresh power mode", + "Counter": "0,1,2,3", + "EventCode": "0x43", + "EventName": "UNC_M_POWER_SELF_REFRESH", + "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.", + "MetricName": "power_self_refresh %", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charges due to page misses", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_M_PRE_COUNT.PAGE_MISS", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charge for reads", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_M_PRE_COUNT.RD", + "PerPkg": "1", + "UMask": "0x4", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charge for writes", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_M_PRE_COUNT.WR", + "PerPkg": "1", + "UMask": "0x8", + "Unit": "iMC" + }, + { + "BriefDescription": "DRAM Page Activate commands sent due to a write request", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_M_ACT_COUNT.WR", + "PerPkg": "1", + "PublicDescription": "Counts DRAM Page Activate commands sent on this channel due to a write request to the iMC (Memory Controller). Activate commands are issued to open up a page on the DRAM devices so that it can be read or written to with a CAS (Column Access Select) command.", + "UMask": "0x2", + "Unit": "iMC" + }, + { + "BriefDescription": "All DRAM CAS Commands issued", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "UNC_M_CAS_COUNT.ALL", + "PerPkg": "1", + "PublicDescription": "Counts all CAS (Column Address Select) commands issued to DRAM per memory channel. CAS commands are issued to specify the address to read or write on DRAM, so this event increments for every read and write. This event counts whether AutoPrecharge (which closes the DRAM Page automatically after a read/write) is enabled or not.", + "UMask": "0xF", + "Unit": "iMC" + }, + { + "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_READ", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x3", + "Unit": "iMC" + }, + { + "BriefDescription": "All DRAM Read CAS Commands issued (does not include underfills) ", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "UNC_M_CAS_COUNT.RD_REG", + "PerPkg": "1", + "PublicDescription": "Counts CAS (Column Access Select) regular read commands issued to DRAM on a per channel basis. CAS commands are issued to specify the address to read or write on DRAM, and this event increments for every regular read. This event only counts regular reads and does not includes underfill reads due to partial write requests. This event counts whether AutoPrecharge (which closes the DRAM Page automatically after a read/write) is enabled or not.", + "UMask": "0x1", + "Unit": "iMC" + }, + { + "BriefDescription": "DRAM Underfill Read CAS Commands issued", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "UNC_M_CAS_COUNT.RD_UNDERFILL", + "PerPkg": "1", + "PublicDescription": "Counts CAS (Column Access Select) underfill read commands issued to DRAM due to a partial write, on a per channel basis. CAS commands are issued to specify the address to read or write on DRAM, and this command counts underfill reads. Partial writes must be completed by first reading in the underfill from DRAM and then merging in the partial write data before writing the full line back to DRAM. This event will generally count about the same as the number of partial writes, but may be slightly less because of partials hitting in the WPQ (due to a previous write request). ", + "UMask": "0x2", + "Unit": "iMC" + }, + { + "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_WRITE", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0xC", + "Unit": "iMC" + }, + { + "BriefDescription": "Read Pending Queue Allocations", + "Counter": "0,1,2,3", + "EventCode": "0x10", + "EventName": "UNC_M_RPQ_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts the number of read requests allocated into the Read Pending Queue (RPQ). This queue is used to schedule reads out to the memory controller and to track the requests. Requests allocate into the RPQ soon after they enter the memory controller, and need credits for an entry in this buffer before being sent from the CHA to the iMC. The requests deallocate after the read CAS command has been issued to DRAM. This event counts both Isochronous and non-Isochronous requests which were issued to the RPQ. ", + "Unit": "iMC" + }, + { + "BriefDescription": "Read Pending Queue Occupancy", + "Counter": "0,1,2,3", + "EventCode": "0x80", + "EventName": "UNC_M_RPQ_OCCUPANCY", + "PerPkg": "1", + "PublicDescription": "Counts the number of entries in the Read Pending Queue (RPQ) at each cycle. This can then be used to calculate both the average occupancy of the queue (in conjunction with the number of cycles not empty) and the average latency in the queue (in conjunction with the number of allocations). The RPQ is used to schedule reads out to the memory controller and to track the requests. Requests allocate into the RPQ soon after they enter the memory controller, and need credits for an entry in this buffer before being sent from the CHA to the iMC. They deallocate from the RPQ after the CAS command has been issued to memory.", + "Unit": "iMC" + }, + { + "BriefDescription": "Write Pending Queue Allocations", + "Counter": "0,1,2,3", + "EventCode": "0x20", + "EventName": "UNC_M_WPQ_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts the number of writes requests allocated into the Write Pending Queue (WPQ). The WPQ is used to schedule writes out to the memory controller and to track the requests. Requests allocate into the WPQ soon after they enter the memory controller, and need credits for an entry in this buffer before being sent from the CHA to the iMC (Memory Controller). The write requests deallocate after being issued to DRAM. Write requests themselves are able to complete (from the perspective of the rest of the system) as soon they have 'posted' to the iMC.", + "Unit": "iMC" + }, + { + "BriefDescription": "Write Pending Queue Occupancy", + "Counter": "0,1,2,3", + "EventCode": "0x81", + "EventName": "UNC_M_WPQ_OCCUPANCY", + "PerPkg": "1", + "PublicDescription": "Counts the number of entries in the Write Pending Queue (WPQ) at each cycle. This can then be used to calculate both the average queue occupancy (in conjunction with the number of cycles not empty) and the average latency (in conjunction with the number of allocations). The WPQ is used to schedule writes out to the memory controller and to track the requests.", + "Unit": "iMC" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json b/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json new file mode 100644 index 0000000000000000000000000000000000000000..de6e70e552e29b68b5b35c4ad47b507c977030fc --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json @@ -0,0 +1,1156 @@ +[ + { + "BriefDescription": "Uncore cache clock ticks", + "Counter": "0,1,2,3", + "EventName": "UNC_CHA_CLOCKTICKS", + "PerPkg": "1", + "Unit": "CHA" + }, + { + "BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_MISSES.UNCACHEABLE", + "Filter": "config1=0x40e33", + "PerPkg": "1", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "MMIO reads. Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_MISSES.MMIO_READ", + "Filter": "config1=0x40040e33", + "PerPkg": "1", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "MMIO writes. Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_MISSES.MMIO_WRITE", + "Filter": "config1=0x40041e33", + "PerPkg": "1", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "Streaming stores (full cache line). Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_REFERENCES.STREAMING_FULL", + "Filter": "config1=0x41833", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "Streaming stores (partial cache line). Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_REFERENCES.STREAMING_PARTIAL", + "Filter": "config1=0x41a33", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "read requests from home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.READS", + "PerPkg": "1", + "UMask": "0x03", + "Unit": "CHA" + }, + { + "BriefDescription": "read requests from local home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.READS_LOCAL", + "PerPkg": "1", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "read requests from remote home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.READS_REMOTE", + "PerPkg": "1", + "UMask": "0x02", + "Unit": "CHA" + }, + { + "BriefDescription": "write requests from home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.WRITES", + "PerPkg": "1", + "UMask": "0x0C", + "Unit": "CHA" + }, + { + "BriefDescription": "write requests from local home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.WRITES_LOCAL", + "PerPkg": "1", + "UMask": "0x04", + "Unit": "CHA" + }, + { + "BriefDescription": "write requests from remote home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.WRITES_REMOTE", + "PerPkg": "1", + "UMask": "0x08", + "Unit": "CHA" + }, + { + "BriefDescription": "UPI interconnect send bandwidth for payload. Derived from unc_upi_txl_flits.all_data", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UPI_DATA_BANDWIDTH_TX", + "PerPkg": "1", + "ScaleUnit": "7.11E-06Bytes", + "UMask": "0x0F", + "Unit": "UPI LL" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO. Derived from unc_iio_data_req_of_cpu.mem_read.part0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "LLC_MISSES.PCIE_READ", + "FCMask": "0x07", + "Filter": "ch_mask=0x1f", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "MetricName": "LLC_MISSES.PCIE_READ", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO. Derived from unc_iio_data_req_of_cpu.mem_write.part0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "LLC_MISSES.PCIE_WRITE", + "FCMask": "0x07", + "Filter": "ch_mask=0x1f", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "MetricName": "LLC_MISSES.PCIE_WRITE", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "MetricName": "LLC_MISSES.PCIE_WRITE", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 1", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 2", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 3", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "MetricName": "LLC_MISSES.PCIE_READ", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 1", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 2", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 3", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Core Cross Snoops Issued; Multiple Core Requests", + "Counter": "0,1,2,3", + "EventCode": "0x33", + "EventName": "UNC_CHA_CORE_SNP.CORE_GTONE", + "PerPkg": "1", + "PublicDescription": "Counts the number of transactions that trigger a configurable number of cross snoops. Cores are snooped if the transaction looks up the cache and determines that it is necessary based on the operation type and what CoreValid bits are set. For example, if 2 CV bits are set on a data read, the cores must have the data in S state so it is not necessary to snoop them. However, if only 1 CV bit is set the core my have modified the data. If the transaction was an RFO, it would need to invalidate the lines. This event can be filtered based on who triggered the initial snoop(s).", + "UMask": "0x42", + "Unit": "CHA" + }, + { + "BriefDescription": "Core Cross Snoops Issued; Multiple Eviction", + "Counter": "0,1,2,3", + "EventCode": "0x33", + "EventName": "UNC_CHA_CORE_SNP.EVICT_GTONE", + "PerPkg": "1", + "PublicDescription": "Counts the number of transactions that trigger a configurable number of cross snoops. Cores are snooped if the transaction looks up the cache and determines that it is necessary based on the operation type and what CoreValid bits are set. For example, if 2 CV bits are set on a data read, the cores must have the data in S state so it is not necessary to snoop them. However, if only 1 CV bit is set the core my have modified the data. If the transaction was an RFO, it would need to invalidate the lines. This event can be filtered based on who triggered the initial snoop(s).", + "UMask": "0x82", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state lookups; Snoop Not Needed", + "Counter": "0,1,2,3", + "EventCode": "0x53", + "EventName": "UNC_CHA_DIR_LOOKUP.NO_SNP", + "PerPkg": "1", + "PublicDescription": "Counts transactions that looked into the multi-socket cacheline Directory state, and therefore did not send a snoop because the Directory indicated it was not needed", + "UMask": "0x02", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state lookups; Snoop Needed", + "Counter": "0,1,2,3", + "EventCode": "0x53", + "EventName": "UNC_CHA_DIR_LOOKUP.SNP", + "PerPkg": "1", + "PublicDescription": "Counts transactions that looked into the multi-socket cacheline Directory state, and sent one or more snoops, because the Directory indicated it was needed", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state updates; Directory Updated memory write from the HA pipe", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "UNC_CHA_DIR_UPDATE.HA", + "PerPkg": "1", + "PublicDescription": "Counts only multi-socket cacheline Directory state updates memory writes issued from the HA pipe. This does not include memory write requests which are for I (Invalid) or E (Exclusive) cachelines.", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state updates; Directory Updated memory write from TOR pipe", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "UNC_CHA_DIR_UPDATE.TOR", + "PerPkg": "1", + "PublicDescription": "Counts only multi-socket cacheline Directory state updates due to memory writes issued from the TOR pipe which are the result of remote transaction hitting the SF/LLC and returning data Core2Core. This does not include memory write requests which are for I (Invalid) or E (Exclusive) cachelines.", + "UMask": "0x02", + "Unit": "CHA" + }, + { + "BriefDescription": "Read request from a remote socket which hit in the HitMe Cache to a line In the E state", + "Counter": "0,1,2,3", + "EventCode": "0x5F", + "EventName": "UNC_CHA_HITME_HIT.EX_RDS", + "PerPkg": "1", + "PublicDescription": "Counts read requests from a remote socket which hit in the HitME cache (used to cache the multi-socket Directory state) to a line in the E(Exclusive) state. This includes the following read opcodes (RdCode, RdData, RdDataMigratory, RdCur, RdInv*, Inv*)", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Normal priority reads issued to the memory controller from the CHA", + "Counter": "0,1,2,3", + "EventCode": "0x59", + "EventName": "UNC_CHA_IMC_READS_COUNT.NORMAL", + "PerPkg": "1", + "PublicDescription": "Counts when a normal (Non-Isochronous) read is issued to any of the memory controller channels from the CHA.", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "CHA to iMC Full Line Writes Issued; Full Line Non-ISOCH", + "Counter": "0,1,2,3", + "EventCode": "0x5B", + "EventName": "UNC_CHA_IMC_WRITES_COUNT.FULL", + "PerPkg": "1", + "PublicDescription": "Counts when a normal (Non-Isochronous) full line write is issued from the CHA to the any of the memory controller channels.", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Number of times that an RFO hit in S state.", + "Counter": "0,1,2,3", + "EventCode": "0x39", + "EventName": "UNC_CHA_MISC.RFO_HIT_S", + "PerPkg": "1", + "PublicDescription": "Counts when a RFO (the Read for Ownership issued before a write) request hit a cacheline in the S (Shared) state.", + "UMask": "0x08", + "Unit": "CHA" + }, + { + "BriefDescription": "Local requests for exclusive ownership of a cache line without receiving data", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.INVITOE_LOCAL", + "PerPkg": "1", + "PublicDescription": "Counts the total number of requests coming from a unit on this socket for exclusive ownership of a cache line without receiving data (INVITOE) to the CHA.", + "UMask": "0x10", + "Unit": "CHA" + }, + { + "BriefDescription": "Local requests for exclusive ownership of a cache line without receiving data", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.INVITOE_REMOTE", + "PerPkg": "1", + "PublicDescription": "Counts the total number of requests coming from a remote socket for exclusive ownership of a cache line without receiving data (INVITOE) to the CHA.", + "UMask": "0x20", + "Unit": "CHA" + }, + { + "BriefDescription": "RspCnflct* Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPCNFLCTS", + "PerPkg": "1", + "PublicDescription": "Counts when a a transaction with the opcode type RspCnflct* Snoop Response was received. This is returned when a snoop finds an existing outstanding transaction in a remote caching agent. This triggers conflict resolution hardware. This covers both the opcode RspCnflct and RspCnflctWbI.", + "UMask": "0x40", + "Unit": "CHA" + }, + { + "BriefDescription": "RspI Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPI", + "PerPkg": "1", + "PublicDescription": "Counts when a transaction with the opcode type RspI Snoop Response was received which indicates the remote cache does not have the data, or when the remote cache silently evicts data (such as when an RFO: the Read for Ownership issued before a write hits non-modified data).", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "RspIFwd Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPIFWD", + "PerPkg": "1", + "PublicDescription": "Counts when a a transaction with the opcode type RspIFwd Snoop Response was received which indicates a remote caching agent forwarded the data and the requesting agent is able to acquire the data in E (Exclusive) or M (modified) states. This is commonly returned with RFO (the Read for Ownership issued before a write) transactions. The snoop could have either been to a cacheline in the M,E,F (Modified, Exclusive or Forward) states.", + "UMask": "0x04", + "Unit": "CHA" + }, + { + "BriefDescription": "RspSFwd Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPSFWD", + "PerPkg": "1", + "PublicDescription": "Counts when a a transaction with the opcode type RspSFwd Snoop Response was received which indicates a remote caching agent forwarded the data but held on to its current copy. This is common for data and code reads that hit in a remote socket in E (Exclusive) or F (Forward) state.", + "UMask": "0x08", + "Unit": "CHA" + }, + { + "BriefDescription": "Rsp*Fwd*WB Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSP_FWD_WB", + "PerPkg": "1", + "PublicDescription": "Counts when a transaction with the opcode type Rsp*Fwd*WB Snoop Response was received which indicates the data was written back to it's home socket, and the cacheline was forwarded to the requestor socket. This snoop response is only used in >= 4 socket systems. It is used when a snoop HITM's in a remote caching agent and it directly forwards data to a requestor, and simultaneously returns data to it's home socket to be written back to memory.", + "UMask": "0x20", + "Unit": "CHA" + }, + { + "BriefDescription": "Rsp*WB Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSP_WBWB", + "PerPkg": "1", + "PublicDescription": "Counts when a transaction with the opcode type Rsp*WB Snoop Response was received which indicates which indicates the data was written back to it's home. This is returned when a non-RFO request hits a cacheline in the Modified state. The Cache can either downgrade the cacheline to a S (Shared) or I (Invalid) state depending on how the system has been configured. This reponse will also be sent when a cache requests E (Exclusive) ownership of a cache line without receiving data, because the cache must acquire ownership.", + "UMask": "0x10", + "Unit": "CHA" + }, + { + "BriefDescription": "Clockticks of the IIO Traffic Controller", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_IIO_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Counts clockticks of the 1GHz trafiic controller clock in the IIO unit.", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part0", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part0. In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part1", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part1. In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part2", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part2. In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part3", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part3. In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part0 by the CPU", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part0 by a unit on the main die (generally a core). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part1 by the CPU", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part1 by a unit on the main die (generally a core). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part2 by the CPU ", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part2 by a unit on the main die (generally a core). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part3 by the CPU ", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part3 by a unit on the main die (generally a core). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part0", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part0. In the general case, part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part1", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part1. In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part2", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part2. In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part3", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part3. In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part0 by the CPU", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part0 by a unit on the main die (generally a core). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part1 by the CPU", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part1 by a unit on the main die (generally a core). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part2 by the CPU ", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part2 by a unit on the main die (generally a core). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part3 by the CPU ", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part3 by a unit on the main die (generally a core). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part0 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part0 to a unit on the main die (generally memory). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part1 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part1 to a unit on the main die (generally memory). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part2 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part2 to a unit on the main die (generally memory). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part3 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part3 to a unit on the main die (generally memory). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part0 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part0 to a unit on the main die (generally memory). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part1 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part1 to a unit on the main die (generally memory). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part2 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part2 to a unit on the main die (generally memory). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part3 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part3 to a unit on the main die (generally memory). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Traffic in which the M2M to iMC Bypass was not taken", + "Counter": "0,1,2,3", + "EventCode": "0x22", + "EventName": "UNC_M2M_BYPASS_M2M_Egress.NOT_TAKEN", + "PerPkg": "1", + "PublicDescription": "Counts traffic in which the M2M (Mesh to Memory) to iMC (Memory Controller) bypass was not taken", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Cycles when direct to core mode (which bypasses the CHA) was disabled", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "UNC_M2M_DIRECT2CORE_NOT_TAKEN_DIRSTATE", + "PerPkg": "1", + "PublicDescription": "Counts cycles when direct to core mode (which bypasses the CHA) was disabled", + "Unit": "M2M" + }, + { + "BriefDescription": "Messages sent direct to core (bypassing the CHA)", + "Counter": "0,1,2,3", + "EventCode": "0x23", + "EventName": "UNC_M2M_DIRECT2CORE_TAKEN", + "PerPkg": "1", + "PublicDescription": "Counts when messages were sent direct to core (bypassing the CHA)", + "Unit": "M2M" + }, + { + "BriefDescription": "Number of reads in which direct to core transaction were overridden", + "Counter": "0,1,2,3", + "EventCode": "0x25", + "EventName": "UNC_M2M_DIRECT2CORE_TXN_OVERRIDE", + "PerPkg": "1", + "PublicDescription": "Counts reads in which direct to core transactions (which would have bypassed the CHA) were overridden", + "Unit": "M2M" + }, + { + "BriefDescription": "Number of reads in which direct to Intel UPI transactions were overridden", + "Counter": "0,1,2,3", + "EventCode": "0x28", + "EventName": "UNC_M2M_DIRECT2UPI_NOT_TAKEN_CREDITS", + "PerPkg": "1", + "PublicDescription": "Counts reads in which direct to Intel Ultra Path Interconnect (UPI) transactions (which would have bypassed the CHA) were overridden", + "Unit": "M2M" + }, + { + "BriefDescription": "Cycles when direct to Intel UPI was disabled", + "Counter": "0,1,2,3", + "EventCode": "0x27", + "EventName": "UNC_M2M_DIRECT2UPI_NOT_TAKEN_DIRSTATE", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the ability to send messages direct to the Intel Ultra Path Interconnect (bypassing the CHA) was disabled", + "Unit": "M2M" + }, + { + "BriefDescription": "Messages sent direct to the Intel UPI", + "Counter": "0,1,2,3", + "EventCode": "0x26", + "EventName": "UNC_M2M_DIRECT2UPI_TAKEN", + "PerPkg": "1", + "PublicDescription": "Counts when messages were sent direct to the Intel Ultra Path Interconnect (bypassing the CHA)", + "Unit": "M2M" + }, + { + "BriefDescription": "Number of reads that a message sent direct2 Intel UPI was overridden", + "Counter": "0,1,2,3", + "EventCode": "0x29", + "EventName": "UNC_M2M_DIRECT2UPI_TXN_OVERRIDE", + "PerPkg": "1", + "PublicDescription": "Counts when a read message that was sent direct to the Intel Ultra Path Interconnect (bypassing the CHA) was overridden", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookups (any state found)", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.ANY", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state, and found the cacheline marked in Any State (A, I, S or unused)", + "UMask": "0x1", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookups (cacheline found in A state) ", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.STATE_A", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state, and found the cacheline marked in the A (SnoopAll) state, indicating the cacheline is stored in another socket in any state, and we must snoop the other sockets to make sure we get the latest data. The data may be stored in any state in the local socket.", + "UMask": "0x8", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookup (cacheline found in I state) ", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.STATE_I", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state , and found the cacheline marked in the I (Invalid) state indicating the cacheline is not stored in another socket, and so there is no need to snoop the other sockets for the latest data. The data may be stored in any state in the local socket.", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookup (cacheline found in S state) ", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.STATE_S", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state , and found the cacheline marked in the S (Shared) state indicating the cacheline is either stored in another socket in the S(hared) state , and so there is no need to snoop the other sockets for the latest data. The data may be stored in any state in the local socket.", + "UMask": "0x4", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from A to I", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.A2I", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from A (SnoopAll) to I (Invalid)", + "UMask": "0x20", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from A to S", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.A2S", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from A (SnoopAll) to S (Shared)", + "UMask": "0x40", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from/to Any state ", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.ANY", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory to a new state", + "UMask": "0x1", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from I to A", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.I2A", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from I (Invalid) to A (SnoopAll)", + "UMask": "0x4", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from I to S", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.I2S", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from I (Invalid) to S (Shared)", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from S to A", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.S2A", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from S (Shared) to A (SnoopAll)", + "UMask": "0x10", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from S to I", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.S2I", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from S (Shared) to I (Invalid)", + "UMask": "0x8", + "Unit": "M2M" + }, + { + "BriefDescription": "Reads to iMC issued", + "Counter": "0,1,2,3", + "EventCode": "0x37", + "EventName": "UNC_M2M_IMC_READS.ALL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues reads to the iMC (Memory Controller). ", + "UMask": "0x4", + "Unit": "M2M" + }, + { + "BriefDescription": "Reads to iMC issued at Normal Priority (Non-Isochronous)", + "Counter": "0,1,2,3", + "EventCode": "0x37", + "EventName": "UNC_M2M_IMC_READS.NORMAL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues reads to the iMC (Memory Controller). It only counts normal priority non-isochronous reads.", + "UMask": "0x1", + "Unit": "M2M" + }, + { + "BriefDescription": "Writes to iMC issued", + "Counter": "0,1,2,3", + "EventCode": "0x38", + "EventName": "UNC_M2M_IMC_WRITES.ALL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues writes to the iMC (Memory Controller).", + "UMask": "0x10", + "Unit": "M2M" + }, + { + "BriefDescription": "Partial Non-Isochronous writes to the iMC", + "Counter": "0,1,2,3", + "EventCode": "0x38", + "EventName": "UNC_M2M_IMC_WRITES.PARTIAL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues partial writes to the iMC (Memory Controller). It only counts normal priority non-isochronous writes.", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Prefecth requests that got turn into a demand request", + "Counter": "0,1,2,3", + "EventCode": "0x56", + "EventName": "UNC_M2M_PREFCAM_DEMAND_PROMOTIONS", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) promotes a outstanding request in the prefetch queue due to a subsequent demand read request that entered the M2M with the same address. Explanatory Side Note: The Prefecth queue is made of CAM (Content Addressable Memory)", + "Unit": "M2M" + }, + { + "BriefDescription": "Inserts into the Memory Controller Prefetch Queue", + "Counter": "0,1,2,3", + "EventCode": "0x57", + "EventName": "UNC_M2M_PREFCAM_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) recieves a prefetch request and inserts it into its outstanding prefetch queue. Explanatory Side Note: the prefect queue is made from CAM: Content Addressable Memory", + "Unit": "M2M" + }, + { + "BriefDescription": "AD Ingress (from CMS) Queue Inserts", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_M2M_RxC_AD_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts when the a new entry is Received(RxC) and then added to the AD (Address Ring) Ingress Queue from the CMS (Common Mesh Stop). This is generally used for reads, and ", + "Unit": "M2M" + }, + { + "BriefDescription": "Prefetches generated by the flow control queue of the M3UPI unit.", + "Counter": "0,1,2,3", + "EventCode": "0x29", + "EventName": "UNC_M3UPI_UPI_PREFETCH_SPAWN", + "PerPkg": "1", + "PublicDescription": "Count cases where flow control queue that sits between the Intel Ultra Path Interconnect (UPI) and the mesh spawns a prefetch to the iMC (Memory Controller)", + "Unit": "M3UPI" + }, + { + "BriefDescription": "Clocks of the Intel Ultra Path Interconnect (UPI)", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_UPI_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Counts clockticks of the fixed frequency clock controlling the Intel Ultra Path Interconnect (UPI). This clock runs at1/8th the 'GT/s' speed of the UPI link. For example, a 9.6GT/s link will have a fixed Frequency of 1.2 Ghz.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Data Response packets that go direct to core", + "Counter": "0,1,2,3", + "EventCode": "0x12", + "EventName": "UNC_UPI_DIRECT_ATTEMPTS.D2C", + "PerPkg": "1", + "PublicDescription": "Counts Data Response (DRS) packets that attempted to go direct to core bypassing the CHA.", + "UMask": "0x1", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Data Response packets that go direct to Intel UPI", + "Counter": "0,1,2,3", + "EventCode": "0x12", + "EventName": "UNC_UPI_DIRECT_ATTEMPTS.D2U", + "PerPkg": "1", + "PublicDescription": "Counts Data Response (DRS) packets that attempted to go direct to Intel Ultra Path Interconnect (UPI) bypassing the CHA .", + "UMask": "0x2", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Cycles Intel UPI is in L1 power mode (shutdown)", + "Counter": "0,1,2,3", + "EventCode": "0x21", + "EventName": "UNC_UPI_L1_POWER_CYCLES", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the Intel Ultra Path Interconnect (UPI) is in L1 power mode. L1 is a mode that totally shuts down the UPI link. Link power states are per link and per direction, so for example the Tx direction could be in one state while Rx was in another, this event only coutns when both links are shutdown.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Cycles the Rx of the Intel UPI is in L0p power mode", + "Counter": "0,1,2,3", + "EventCode": "0x25", + "EventName": "UNC_UPI_RxL0P_POWER_CYCLES", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the the receive side (Rx) of the Intel Ultra Path Interconnect(UPI) is in L0p power mode. L0p is a mode where we disable 60% of the UPI lanes, decreasing our bandwidth in order to save power.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs received which bypassed the Slot0 Receive Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x31", + "EventName": "UNC_UPI_RxL_BYPASSED.SLOT0", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot0 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "UMask": "0x1", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs received which bypassed the Slot0 Receive Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x31", + "EventName": "UNC_UPI_RxL_BYPASSED.SLOT1", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot1 RxQ buffer (Receive Queue) and passed directly across the BGF and into the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "UMask": "0x2", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs received which bypassed the Slot0 Recieve Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x31", + "EventName": "UNC_UPI_RxL_BYPASSED.SLOT2", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) whcih bypassed the slot2 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "UMask": "0x4", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Valid data FLITs received from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x3", + "EventName": "UNC_UPI_RxL_FLITS.ALL_DATA", + "PerPkg": "1", + "PublicDescription": "Counts valid data FLITs (80 bit FLow control unITs: 64bits of data) received from any of the 3 Intel Ultra Path Interconnect (UPI) Receive Queue slots on this UPI unit.", + "UMask": "0x0F", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Null FLITs received from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x3", + "EventName": "UNC_UPI_RxL_FLITS.ALL_NULL", + "PerPkg": "1", + "PublicDescription": "Counts null FLITs (80 bit FLow control unITs) received from any of the 3 Intel Ultra Path Interconnect (UPI) Receive Queue slots on this UPI unit.", + "UMask": "0x27", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Protocol header and credit FLITs received from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x3", + "EventName": "UNC_UPI_RxL_FLITS.NON_DATA", + "PerPkg": "1", + "PublicDescription": "Counts protocol header and credit FLITs (80 bit FLow control unITs) received from any of the 3 UPI slots on this UPI unit.", + "UMask": "0x97", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Cycles in which the Tx of the Intel Ultra Path Interconnect (UPI) is in L0p power mode", + "Counter": "0,1,2,3", + "EventCode": "0x27", + "EventName": "UNC_UPI_TxL0P_POWER_CYCLES", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the transmit side (Tx) of the Intel Ultra Path Interconnect(UPI) is in L0p power mode. L0p is a mode where we disable 60% of the UPI lanes, decreasing our bandwidth in order to save power.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs that bypassed the TxL Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x41", + "EventName": "UNC_UPI_TxL_BYPASSED", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the TxL(transmit) FLIT buffer and pass directly out the UPI Link. Generally, when data is transmitted across the Intel Ultra Path Interconnect (UPI), it will bypass the TxQ and pass directly to the link. However, the TxQ will be used in L0p (Low Power) mode and (Link Layer Retry) LLR mode, increasing latency to transfer out to the link.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "UPI interconnect send bandwidth for payload. Derived from unc_upi_txl_flits.all_data", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UPI_DATA_BANDWIDTH_TX", + "PerPkg": "1", + "ScaleUnit": "7.11E-06Bytes", + "UMask": "0x0F", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Null FLITs transmitted from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_UPI_TxL_FLITS.ALL_NULL", + "PerPkg": "1", + "PublicDescription": "Counts null FLITs (80 bit FLow control unITs) transmitted via any of the 3 Intel Ulra Path Interconnect (UPI) slots on this UPI unit.", + "UMask": "0x27", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Idle FLITs transmitted", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_UPI_TxL_FLITS.IDLE", + "PerPkg": "1", + "PublicDescription": "Counts when the Intel Ultra Path Interconnect(UPI) transmits an idle FLIT(80 bit FLow control unITs). Every UPI cycle must be sending either data FLITs, protocol/credit FLITs or idle FLITs.", + "UMask": "0x47", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Protocol header and credit FLITs transmitted across any slot", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_UPI_TxL_FLITS.NON_DATA", + "PerPkg": "1", + "PublicDescription": "Counts protocol header and credit FLITs (80 bit FLow control unITs) transmitted across any of the 3 UPI (Ultra Path Interconnect) slots on this UPI unit.", + "UMask": "0x97", + "Unit": "UPI LL" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json b/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json new file mode 100644 index 0000000000000000000000000000000000000000..70750dab7ead1751ddf794b62a5b50c1982ec6d1 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json @@ -0,0 +1,284 @@ +[ + { + "EventCode": "0x08", + "UMask": "0x1", + "BriefDescription": "Load misses in all DTLB levels that cause page walks", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data loads that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x2", + "BriefDescription": "Demand load Miss in all translation lookaside buffer (TLB) levels causes a page walk that completes (4K).", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts demand data loads that caused a completed page walk (4K page size). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x4", + "BriefDescription": "Demand load Miss in all translation lookaside buffer (TLB) levels causes a page walk that completes (2M/4M).", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts demand data loads that caused a completed page walk (2M and 4M page sizes). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x8", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (1G)", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts load misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0xe", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts demand data loads that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a load. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a load. EPT page walk duration are excluded in Skylake microarchitecture. ", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x10", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a load. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a load.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x20", + "BriefDescription": "Loads that miss the DTLB and hit the STLB.", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x1", + "BriefDescription": "Store misses in all DTLB levels that cause page walks", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data stores that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x2", + "BriefDescription": "Store miss in all TLB levels causes a page walk that completes. (4K)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts demand data stores that caused a completed page walk (4K page size). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x4", + "BriefDescription": "Store misses in all DTLB levels that cause completed page walks (2M/4M)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts demand data stores that caused a completed page walk (2M and 4M page sizes). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x8", + "BriefDescription": "Store misses in all DTLB levels that cause completed page walks (1G)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts store misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0xe", + "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts demand data stores that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake microarchitecture. ", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x10", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x20", + "BriefDescription": "Stores that miss the DTLB and hit the STLB.", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.STLB_HIT", + "PublicDescription": "Stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x4F", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a EPT (Extended Page Table) walk for any request type.", + "Counter": "0,1,2,3", + "EventName": "EPT.WALK_PENDING", + "PublicDescription": "Counts cycles for each PMH (Page Miss Handler) that is busy with an EPT (Extended Page Table) walk for any request type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x1", + "BriefDescription": "Misses at all ITLB levels that cause page walks", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB, but the walk need not have completed.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x2", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts completed page walks (4K page size) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x4", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (2M/4M)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts completed page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x8", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (1G)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts store misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0xe", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (2M and 4M page sizes) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH (Page Miss Handler) that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake michroarchitecture. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x10", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake.", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake microarchitecture.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x20", + "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.STLB_HIT", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xAE", + "UMask": "0x1", + "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.", + "Counter": "0,1,2,3", + "EventName": "ITLB.ITLB_FLUSH", + "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xBD", + "UMask": "0x1", + "BriefDescription": "DTLB flush attempts of the thread-specific entries", + "Counter": "0,1,2,3", + "EventName": "TLB_FLUSH.DTLB_THREAD", + "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xBD", + "UMask": "0x20", + "BriefDescription": "STLB flush attempts", + "Counter": "0,1,2,3", + "EventName": "TLB_FLUSH.STLB_ANY", + "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index bd0aabb2bd0fafeb4453119eb3dcad7360816d37..d51dc9ca8861ab194c1b15287e63cc93f4c19477 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -137,6 +137,8 @@ static struct field { { "AnyThread", "any=" }, { "EdgeDetect", "edge=" }, { "SampleAfterValue", "period=" }, + { "FCMask", "fc_mask=" }, + { "PortMask", "ch_mask=" }, { NULL, NULL } }; @@ -822,10 +824,6 @@ static int process_one_file(const char *fpath, const struct stat *sb, * PMU event tables (see struct pmu_events_map). * * Write out the PMU events tables and the mapping table to pmu-event.c. - * - * If unable to process the JSON or arch files, create an empty mapping - * table so we can continue to build/use perf even if we cannot use the - * PMU event aliases. */ int main(int argc, char *argv[]) { @@ -836,6 +834,7 @@ int main(int argc, char *argv[]) const char *arch; const char *output_file; const char *start_dirname; + struct stat stbuf; prog = basename(argv[0]); if (argc < 4) { @@ -857,11 +856,17 @@ int main(int argc, char *argv[]) return 2; } + sprintf(ldirname, "%s/%s", start_dirname, arch); + + /* If architecture does not have any event lists, bail out */ + if (stat(ldirname, &stbuf) < 0) { + pr_info("%s: Arch %s has no PMU event lists\n", prog, arch); + goto empty_map; + } + /* Include pmu-events.h first */ fprintf(eventsfp, "#include \"../../pmu-events/pmu-events.h\"\n"); - sprintf(ldirname, "%s/%s", start_dirname, arch); - /* * The mapfile allows multiple CPUids to point to the same JSON file, * so, not sure if there is a need for symlinks within the pmu-events @@ -878,6 +883,9 @@ int main(int argc, char *argv[]) if (rc && verbose) { pr_info("%s: Error walking file tree %s\n", prog, ldirname); goto empty_map; + } else if (rc < 0) { + /* Make build fail */ + return 1; } else if (rc) { goto empty_map; } @@ -892,7 +900,8 @@ int main(int argc, char *argv[]) if (process_mapfile(eventsfp, mapfile)) { pr_info("%s: Error processing mapfile %s\n", prog, mapfile); - goto empty_map; + /* Make build fail */ + return 1; } return 0; diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py index 1d95009592eb3a8a8d053e1340a3e42dd412a68c..f6c84966e4f89cb2ffcd0ad8d4b94a34d134811c 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py @@ -57,6 +57,7 @@ try: 'ia64' : audit.MACH_IA64, 'ppc' : audit.MACH_PPC, 'ppc64' : audit.MACH_PPC64, + 'ppc64le' : audit.MACH_PPC64LE, 's390' : audit.MACH_S390, 's390x' : audit.MACH_S390X, 'i386' : audit.MACH_X86, diff --git a/tools/perf/scripts/python/bin/export-to-sqlite-record b/tools/perf/scripts/python/bin/export-to-sqlite-record new file mode 100644 index 0000000000000000000000000000000000000000..070204fd6d00340b55cdbd9bf7ad3eef9ff1806d --- /dev/null +++ b/tools/perf/scripts/python/bin/export-to-sqlite-record @@ -0,0 +1,8 @@ +#!/bin/bash + +# +# export perf data to a sqlite3 database. Can cover +# perf ip samples (excluding the tracepoints). No special +# record requirements, just record what you want to export. +# +perf record $@ diff --git a/tools/perf/scripts/python/bin/export-to-sqlite-report b/tools/perf/scripts/python/bin/export-to-sqlite-report new file mode 100644 index 0000000000000000000000000000000000000000..5ff6033e70ba42ce4253a00e4a922b1924e9c451 --- /dev/null +++ b/tools/perf/scripts/python/bin/export-to-sqlite-report @@ -0,0 +1,29 @@ +#!/bin/bash +# description: export perf data to a sqlite3 database +# args: [database name] [columns] [calls] +n_args=0 +for i in "$@" +do + if expr match "$i" "-" > /dev/null ; then + break + fi + n_args=$(( $n_args + 1 )) +done +if [ "$n_args" -gt 3 ] ; then + echo "usage: export-to-sqlite-report [database name] [columns] [calls]" + exit +fi +if [ "$n_args" -gt 2 ] ; then + dbname=$1 + columns=$2 + calls=$3 + shift 3 +elif [ "$n_args" -gt 1 ] ; then + dbname=$1 + columns=$2 + shift 2 +elif [ "$n_args" -gt 0 ] ; then + dbname=$1 + shift +fi +perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/export-to-sqlite.py $dbname $columns $calls diff --git a/tools/perf/scripts/python/call-graph-from-postgresql.py b/tools/perf/scripts/python/call-graph-from-sql.py similarity index 87% rename from tools/perf/scripts/python/call-graph-from-postgresql.py rename to tools/perf/scripts/python/call-graph-from-sql.py index e78fdc2a5a9d7516d4d3642b16a44bc9aed7491d..b494a67a1c679ec2e6cd89105ce09702ee76146f 100644 --- a/tools/perf/scripts/python/call-graph-from-postgresql.py +++ b/tools/perf/scripts/python/call-graph-from-sql.py @@ -1,6 +1,6 @@ #!/usr/bin/python2 -# call-graph-from-postgresql.py: create call-graph from postgresql database -# Copyright (c) 2014, Intel Corporation. +# call-graph-from-sql.py: create call-graph from sql database +# Copyright (c) 2014-2017, Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, @@ -11,18 +11,19 @@ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. -# To use this script you will need to have exported data using the -# export-to-postgresql.py script. Refer to that script for details. +# To use this script you will need to have exported data using either the +# export-to-sqlite.py or the export-to-postgresql.py script. Refer to those +# scripts for details. # -# Following on from the example in the export-to-postgresql.py script, a +# Following on from the example in the export scripts, a # call-graph can be displayed for the pt_example database like this: # -# python tools/perf/scripts/python/call-graph-from-postgresql.py pt_example +# python tools/perf/scripts/python/call-graph-from-sql.py pt_example # -# Note this script supports connecting to remote databases by setting hostname, -# port, username, password, and dbname e.g. +# Note that for PostgreSQL, this script supports connecting to remote databases +# by setting hostname, port, username, password, and dbname e.g. # -# python tools/perf/scripts/python/call-graph-from-postgresql.py "hostname=myhost username=myuser password=mypassword dbname=pt_example" +# python tools/perf/scripts/python/call-graph-from-sql.py "hostname=myhost username=myuser password=mypassword dbname=pt_example" # # The result is a GUI window with a tree representing a context-sensitive # call-graph. Expanding a couple of levels of the tree and adjusting column @@ -160,7 +161,7 @@ class TreeItem(): '( SELECT short_name FROM dsos WHERE id = ( SELECT dso_id FROM symbols WHERE id = ( SELECT symbol_id FROM call_paths WHERE id = call_path_id ) ) ), ' '( SELECT ip FROM call_paths where id = call_path_id ) ' 'FROM calls WHERE parent_call_path_id = ' + str(self.call_path_id) + ' AND comm_id = ' + str(self.comm_id) + ' AND thread_id = ' + str(self.thread_id) + - 'ORDER BY call_path_id') + ' ORDER BY call_path_id') if not ret: raise Exception("Query failed: " + query.lastError().text()) last_call_path_id = 0 @@ -291,29 +292,40 @@ class MainWindow(QMainWindow): if __name__ == '__main__': if (len(sys.argv) < 2): - print >> sys.stderr, "Usage is: call-graph-from-postgresql.py " + print >> sys.stderr, "Usage is: call-graph-from-sql.py " raise Exception("Too few arguments") dbname = sys.argv[1] - db = QSqlDatabase.addDatabase('QPSQL') - - opts = dbname.split() - for opt in opts: - if '=' in opt: - opt = opt.split('=') - if opt[0] == 'hostname': - db.setHostName(opt[1]) - elif opt[0] == 'port': - db.setPort(int(opt[1])) - elif opt[0] == 'username': - db.setUserName(opt[1]) - elif opt[0] == 'password': - db.setPassword(opt[1]) - elif opt[0] == 'dbname': - dbname = opt[1] - else: - dbname = opt + is_sqlite3 = False + try: + f = open(dbname) + if f.read(15) == "SQLite format 3": + is_sqlite3 = True + f.close() + except: + pass + + if is_sqlite3: + db = QSqlDatabase.addDatabase('QSQLITE') + else: + db = QSqlDatabase.addDatabase('QPSQL') + opts = dbname.split() + for opt in opts: + if '=' in opt: + opt = opt.split('=') + if opt[0] == 'hostname': + db.setHostName(opt[1]) + elif opt[0] == 'port': + db.setPort(int(opt[1])) + elif opt[0] == 'username': + db.setUserName(opt[1]) + elif opt[0] == 'password': + db.setPassword(opt[1]) + elif opt[0] == 'dbname': + dbname = opt[1] + else: + dbname = opt db.setDatabaseName(dbname) if not db.open(): diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 7656ff8aa066ad7f202bb2637c9f4707422894f7..efcaf6cac2eb92437426f07a3c9be5f0b2478be7 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py @@ -59,7 +59,7 @@ import datetime # pt_example=# \q # # An example of using the database is provided by the script -# call-graph-from-postgresql.py. Refer to that script for details. +# call-graph-from-sql.py. Refer to that script for details. # # Tables: # @@ -340,7 +340,8 @@ if branches: 'to_sym_offset bigint,' 'to_ip bigint,' 'branch_type integer,' - 'in_tx boolean)') + 'in_tx boolean,' + 'call_path_id bigint)') else: do_query(query, 'CREATE TABLE samples (' 'id bigint NOT NULL,' diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py new file mode 100644 index 0000000000000000000000000000000000000000..f827bf77e9d26177fe7e19cd7e65d05cb97ac366 --- /dev/null +++ b/tools/perf/scripts/python/export-to-sqlite.py @@ -0,0 +1,451 @@ +# export-to-sqlite.py: export perf data to a sqlite3 database +# Copyright (c) 2017, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. + +import os +import sys +import struct +import datetime + +# To use this script you will need to have installed package python-pyside which +# provides LGPL-licensed Python bindings for Qt. You will also need the package +# libqt4-sql-sqlite for Qt sqlite3 support. +# +# An example of using this script with Intel PT: +# +# $ perf record -e intel_pt//u ls +# $ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls +# 2017-07-31 14:26:07.326913 Creating database... +# 2017-07-31 14:26:07.538097 Writing records... +# 2017-07-31 14:26:09.889292 Adding indexes +# 2017-07-31 14:26:09.958746 Done +# +# To browse the database, sqlite3 can be used e.g. +# +# $ sqlite3 pt_example +# sqlite> .header on +# sqlite> select * from samples_view where id < 10; +# sqlite> .mode column +# sqlite> select * from samples_view where id < 10; +# sqlite> .tables +# sqlite> .schema samples_view +# sqlite> .quit +# +# An example of using the database is provided by the script +# call-graph-from-sql.py. Refer to that script for details. +# +# The database structure is practically the same as created by the script +# export-to-postgresql.py. Refer to that script for details. A notable +# difference is the 'transaction' column of the 'samples' table which is +# renamed 'transaction_' in sqlite because 'transaction' is a reserved word. + +from PySide.QtSql import * + +sys.path.append(os.environ['PERF_EXEC_PATH'] + \ + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') + +# These perf imports are not used at present +#from perf_trace_context import * +#from Core import * + +perf_db_export_mode = True +perf_db_export_calls = False +perf_db_export_callchains = False + +def usage(): + print >> sys.stderr, "Usage is: export-to-sqlite.py [] [] []" + print >> sys.stderr, "where: columns 'all' or 'branches'" + print >> sys.stderr, " calls 'calls' => create calls and call_paths table" + print >> sys.stderr, " callchains 'callchains' => create call_paths table" + raise Exception("Too few arguments") + +if (len(sys.argv) < 2): + usage() + +dbname = sys.argv[1] + +if (len(sys.argv) >= 3): + columns = sys.argv[2] +else: + columns = "all" + +if columns not in ("all", "branches"): + usage() + +branches = (columns == "branches") + +for i in range(3,len(sys.argv)): + if (sys.argv[i] == "calls"): + perf_db_export_calls = True + elif (sys.argv[i] == "callchains"): + perf_db_export_callchains = True + else: + usage() + +def do_query(q, s): + if (q.exec_(s)): + return + raise Exception("Query failed: " + q.lastError().text()) + +def do_query_(q): + if (q.exec_()): + return + raise Exception("Query failed: " + q.lastError().text()) + +print datetime.datetime.today(), "Creating database..." + +db_exists = False +try: + f = open(dbname) + f.close() + db_exists = True +except: + pass + +if db_exists: + raise Exception(dbname + " already exists") + +db = QSqlDatabase.addDatabase('QSQLITE') +db.setDatabaseName(dbname) +db.open() + +query = QSqlQuery(db) + +do_query(query, 'PRAGMA journal_mode = OFF') +do_query(query, 'BEGIN TRANSACTION') + +do_query(query, 'CREATE TABLE selected_events (' + 'id integer NOT NULL PRIMARY KEY,' + 'name varchar(80))') +do_query(query, 'CREATE TABLE machines (' + 'id integer NOT NULL PRIMARY KEY,' + 'pid integer,' + 'root_dir varchar(4096))') +do_query(query, 'CREATE TABLE threads (' + 'id integer NOT NULL PRIMARY KEY,' + 'machine_id bigint,' + 'process_id bigint,' + 'pid integer,' + 'tid integer)') +do_query(query, 'CREATE TABLE comms (' + 'id integer NOT NULL PRIMARY KEY,' + 'comm varchar(16))') +do_query(query, 'CREATE TABLE comm_threads (' + 'id integer NOT NULL PRIMARY KEY,' + 'comm_id bigint,' + 'thread_id bigint)') +do_query(query, 'CREATE TABLE dsos (' + 'id integer NOT NULL PRIMARY KEY,' + 'machine_id bigint,' + 'short_name varchar(256),' + 'long_name varchar(4096),' + 'build_id varchar(64))') +do_query(query, 'CREATE TABLE symbols (' + 'id integer NOT NULL PRIMARY KEY,' + 'dso_id bigint,' + 'sym_start bigint,' + 'sym_end bigint,' + 'binding integer,' + 'name varchar(2048))') +do_query(query, 'CREATE TABLE branch_types (' + 'id integer NOT NULL PRIMARY KEY,' + 'name varchar(80))') + +if branches: + do_query(query, 'CREATE TABLE samples (' + 'id integer NOT NULL PRIMARY KEY,' + 'evsel_id bigint,' + 'machine_id bigint,' + 'thread_id bigint,' + 'comm_id bigint,' + 'dso_id bigint,' + 'symbol_id bigint,' + 'sym_offset bigint,' + 'ip bigint,' + 'time bigint,' + 'cpu integer,' + 'to_dso_id bigint,' + 'to_symbol_id bigint,' + 'to_sym_offset bigint,' + 'to_ip bigint,' + 'branch_type integer,' + 'in_tx boolean,' + 'call_path_id bigint)') +else: + do_query(query, 'CREATE TABLE samples (' + 'id integer NOT NULL PRIMARY KEY,' + 'evsel_id bigint,' + 'machine_id bigint,' + 'thread_id bigint,' + 'comm_id bigint,' + 'dso_id bigint,' + 'symbol_id bigint,' + 'sym_offset bigint,' + 'ip bigint,' + 'time bigint,' + 'cpu integer,' + 'to_dso_id bigint,' + 'to_symbol_id bigint,' + 'to_sym_offset bigint,' + 'to_ip bigint,' + 'period bigint,' + 'weight bigint,' + 'transaction_ bigint,' + 'data_src bigint,' + 'branch_type integer,' + 'in_tx boolean,' + 'call_path_id bigint)') + +if perf_db_export_calls or perf_db_export_callchains: + do_query(query, 'CREATE TABLE call_paths (' + 'id integer NOT NULL PRIMARY KEY,' + 'parent_id bigint,' + 'symbol_id bigint,' + 'ip bigint)') +if perf_db_export_calls: + do_query(query, 'CREATE TABLE calls (' + 'id integer NOT NULL PRIMARY KEY,' + 'thread_id bigint,' + 'comm_id bigint,' + 'call_path_id bigint,' + 'call_time bigint,' + 'return_time bigint,' + 'branch_count bigint,' + 'call_id bigint,' + 'return_id bigint,' + 'parent_call_path_id bigint,' + 'flags integer)') + +# printf was added to sqlite in version 3.8.3 +sqlite_has_printf = False +try: + do_query(query, 'SELECT printf("") FROM machines') + sqlite_has_printf = True +except: + pass + +def emit_to_hex(x): + if sqlite_has_printf: + return 'printf("%x", ' + x + ')' + else: + return x + +do_query(query, 'CREATE VIEW machines_view AS ' + 'SELECT ' + 'id,' + 'pid,' + 'root_dir,' + 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest' + ' FROM machines') + +do_query(query, 'CREATE VIEW dsos_view AS ' + 'SELECT ' + 'id,' + 'machine_id,' + '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,' + 'short_name,' + 'long_name,' + 'build_id' + ' FROM dsos') + +do_query(query, 'CREATE VIEW symbols_view AS ' + 'SELECT ' + 'id,' + 'name,' + '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,' + 'dso_id,' + 'sym_start,' + 'sym_end,' + 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding' + ' FROM symbols') + +do_query(query, 'CREATE VIEW threads_view AS ' + 'SELECT ' + 'id,' + 'machine_id,' + '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,' + 'process_id,' + 'pid,' + 'tid' + ' FROM threads') + +do_query(query, 'CREATE VIEW comm_threads_view AS ' + 'SELECT ' + 'comm_id,' + '(SELECT comm FROM comms WHERE id = comm_id) AS command,' + 'thread_id,' + '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' + '(SELECT tid FROM threads WHERE id = thread_id) AS tid' + ' FROM comm_threads') + +if perf_db_export_calls or perf_db_export_callchains: + do_query(query, 'CREATE VIEW call_paths_view AS ' + 'SELECT ' + 'c.id,' + + emit_to_hex('c.ip') + ' AS ip,' + 'c.symbol_id,' + '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,' + '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,' + '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,' + 'c.parent_id,' + + emit_to_hex('p.ip') + ' AS parent_ip,' + 'p.symbol_id AS parent_symbol_id,' + '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,' + '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,' + '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name' + ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id') +if perf_db_export_calls: + do_query(query, 'CREATE VIEW calls_view AS ' + 'SELECT ' + 'calls.id,' + 'thread_id,' + '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' + '(SELECT tid FROM threads WHERE id = thread_id) AS tid,' + '(SELECT comm FROM comms WHERE id = comm_id) AS command,' + 'call_path_id,' + + emit_to_hex('ip') + ' AS ip,' + 'symbol_id,' + '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,' + 'call_time,' + 'return_time,' + 'return_time - call_time AS elapsed_time,' + 'branch_count,' + 'call_id,' + 'return_id,' + 'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,' + 'parent_call_path_id' + ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id') + +do_query(query, 'CREATE VIEW samples_view AS ' + 'SELECT ' + 'id,' + 'time,' + 'cpu,' + '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' + '(SELECT tid FROM threads WHERE id = thread_id) AS tid,' + '(SELECT comm FROM comms WHERE id = comm_id) AS command,' + '(SELECT name FROM selected_events WHERE id = evsel_id) AS event,' + + emit_to_hex('ip') + ' AS ip_hex,' + '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,' + 'sym_offset,' + '(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,' + + emit_to_hex('to_ip') + ' AS to_ip_hex,' + '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,' + 'to_sym_offset,' + '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,' + '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,' + 'in_tx' + ' FROM samples') + +do_query(query, 'END TRANSACTION') + +evsel_query = QSqlQuery(db) +evsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)") +machine_query = QSqlQuery(db) +machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)") +thread_query = QSqlQuery(db) +thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") +comm_query = QSqlQuery(db) +comm_query.prepare("INSERT INTO comms VALUES (?, ?)") +comm_thread_query = QSqlQuery(db) +comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") +dso_query = QSqlQuery(db) +dso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)") +symbol_query = QSqlQuery(db) +symbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)") +branch_type_query = QSqlQuery(db) +branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)") +sample_query = QSqlQuery(db) +if branches: + sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") +else: + sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") +if perf_db_export_calls or perf_db_export_callchains: + call_path_query = QSqlQuery(db) + call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)") +if perf_db_export_calls: + call_query = QSqlQuery(db) + call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") + +def trace_begin(): + print datetime.datetime.today(), "Writing records..." + do_query(query, 'BEGIN TRANSACTION') + # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs + evsel_table(0, "unknown") + machine_table(0, 0, "unknown") + thread_table(0, 0, 0, -1, -1) + comm_table(0, "unknown") + dso_table(0, 0, "unknown", "unknown", "") + symbol_table(0, 0, 0, 0, 0, "unknown") + sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + if perf_db_export_calls or perf_db_export_callchains: + call_path_table(0, 0, 0, 0) + +unhandled_count = 0 + +def trace_end(): + do_query(query, 'END TRANSACTION') + + print datetime.datetime.today(), "Adding indexes" + if perf_db_export_calls: + do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') + + if (unhandled_count): + print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" + print datetime.datetime.today(), "Done" + +def trace_unhandled(event_name, context, event_fields_dict): + global unhandled_count + unhandled_count += 1 + +def sched__sched_switch(*x): + pass + +def bind_exec(q, n, x): + for xx in x[0:n]: + q.addBindValue(str(xx)) + do_query_(q) + +def evsel_table(*x): + bind_exec(evsel_query, 2, x) + +def machine_table(*x): + bind_exec(machine_query, 3, x) + +def thread_table(*x): + bind_exec(thread_query, 5, x) + +def comm_table(*x): + bind_exec(comm_query, 2, x) + +def comm_thread_table(*x): + bind_exec(comm_thread_query, 3, x) + +def dso_table(*x): + bind_exec(dso_query, 5, x) + +def symbol_table(*x): + bind_exec(symbol_query, 6, x) + +def branch_type_table(*x): + bind_exec(branch_type_query, 2, x) + +def sample_table(*x): + if branches: + bind_exec(sample_query, 18, x) + else: + bind_exec(sample_query, 22, x) + +def call_path_table(*x): + bind_exec(call_path_query, 4, x) + +def call_return_table(*x): + bind_exec(call_query, 11, x) diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 84222bdb8689203924fc8f6a75f0baac4531d82c..87bf3edb037cff4d57ca17047e2dbf72c4802e5e 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -34,6 +34,7 @@ perf-y += thread-map.o perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o llvm-src-relocation.o perf-y += bpf.o perf-y += topology.o +perf-y += mem.o perf-y += cpumap.o perf-y += stat.o perf-y += event_update.o diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 0e77b2cf61ecc3453ecbf24646b1c0718b125ac5..c9aafed7da15ad4587616a98a48cb8de24570ed8 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -36,6 +36,7 @@ #define ENV "PERF_TEST_ATTR" static char *dir; +static bool ready; void test_attr__init(void) { @@ -67,6 +68,9 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, FILE *file; char path[PATH_MAX]; + if (!ready) + return 0; + snprintf(path, PATH_MAX, "%s/event-%d-%llu-%d", dir, attr->type, attr->config, fd); @@ -136,7 +140,7 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, { int errno_saved = errno; - if (store_event(attr, pid, cpu, fd, group_fd, flags)) { + if ((fd != -1) && store_event(attr, pid, cpu, fd, group_fd, flags)) { pr_err("test attr FAILED"); exit(128); } @@ -144,6 +148,12 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, errno = errno_saved; } +void test_attr__ready(void) +{ + if (unlikely(test_attr__enabled) && !ready) + ready = true; +} + static int run_dir(const char *d, const char *perf) { char v[] = "-vvvvv"; @@ -159,7 +169,7 @@ static int run_dir(const char *d, const char *perf) return system(cmd); } -int test__attr(int subtest __maybe_unused) +int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) { struct stat st; char path_perf[PATH_MAX]; diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py index cdf21a9d0c35e459f67c4d2751ec663f18913f12..6bb50e82a3e3101de32ff3aca50680aa24cc565d 100644 --- a/tools/perf/tests/attr.py +++ b/tools/perf/tests/attr.py @@ -9,6 +9,20 @@ import logging import shutil import ConfigParser +def data_equal(a, b): + # Allow multiple values in assignment separated by '|' + a_list = a.split('|') + b_list = b.split('|') + + for a_item in a_list: + for b_item in b_list: + if (a_item == b_item): + return True + elif (a_item == '*') or (b_item == '*'): + return True + + return False + class Fail(Exception): def __init__(self, test, msg): self.msg = msg @@ -82,34 +96,25 @@ class Event(dict): self.add(base) self.add(data) - def compare_data(self, a, b): - # Allow multiple values in assignment separated by '|' - a_list = a.split('|') - b_list = b.split('|') - - for a_item in a_list: - for b_item in b_list: - if (a_item == b_item): - return True - elif (a_item == '*') or (b_item == '*'): - return True - - return False - def equal(self, other): for t in Event.terms: log.debug(" [%s] %s %s" % (t, self[t], other[t])); if not self.has_key(t) or not other.has_key(t): return False - if not self.compare_data(self[t], other[t]): + if not data_equal(self[t], other[t]): return False return True + def optional(self): + if self.has_key('optional') and self['optional'] == '1': + return True + return False + def diff(self, other): for t in Event.terms: if not self.has_key(t) or not other.has_key(t): continue - if not self.compare_data(self[t], other[t]): + if not data_equal(self[t], other[t]): log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) # Test file description needs to have following sections: @@ -218,9 +223,9 @@ class Test(object): self.perf, self.command, tempdir, self.args) ret = os.WEXITSTATUS(os.system(cmd)) - log.info(" '%s' ret %d " % (cmd, ret)) + log.info(" '%s' ret '%s', expected '%s'" % (cmd, str(ret), str(self.ret))) - if ret != int(self.ret): + if not data_equal(str(ret), str(self.ret)): raise Unsup(self) def compare(self, expect, result): @@ -244,9 +249,12 @@ class Test(object): log.debug(" match: [%s] matches %s" % (exp_name, str(exp_list))) # we did not any matching event - fail - if (not exp_list): - exp_event.diff(res_event) - raise Fail(self, 'match failure'); + if not exp_list: + if exp_event.optional(): + log.debug(" %s does not match, but is optional" % exp_name) + else: + exp_event.diff(res_event) + raise Fail(self, 'match failure'); match[exp_name] = exp_list diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record index 7e6d74946e0426c015918203da976d58e8ff4626..31e0b1da830b87f243509448f3c1e26f00c2c669 100644 --- a/tools/perf/tests/attr/base-record +++ b/tools/perf/tests/attr/base-record @@ -7,7 +7,7 @@ cpu=* type=0|1 size=112 config=0 -sample_period=4000 +sample_period=* sample_type=263 read_format=0 disabled=1 @@ -15,7 +15,7 @@ inherit=1 pinned=0 exclusive=0 exclude_user=0 -exclude_kernel=0 +exclude_kernel=0|1 exclude_hv=0 exclude_idle=0 mmap=1 @@ -25,7 +25,7 @@ inherit_stat=0 enable_on_exec=1 task=0 watermark=0 -precise_ip=0 +precise_ip=0|1|2|3 mmap_data=0 sample_id_all=1 exclude_host=0|1 diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat index f4cf148f14cbd0938075a13e41f08e6f99a11a8e..4d0c2e42b64e8a9c02af5176e95f274b5ba76128 100644 --- a/tools/perf/tests/attr/base-stat +++ b/tools/perf/tests/attr/base-stat @@ -8,14 +8,14 @@ type=0 size=112 config=0 sample_period=0 -sample_type=0 +sample_type=65536 read_format=3 disabled=1 inherit=1 pinned=0 exclusive=0 exclude_user=0 -exclude_kernel=0 +exclude_kernel=0|1 exclude_hv=0 exclude_idle=0 mmap=0 diff --git a/tools/perf/tests/attr/test-record-C0 b/tools/perf/tests/attr/test-record-C0 index d6a7e43f61b3df7bc62f466a5d550d6d8493cfd9..cb0a3138fa548bb62fa7a0a22bdb9e77f8e84341 100644 --- a/tools/perf/tests/attr/test-record-C0 +++ b/tools/perf/tests/attr/test-record-C0 @@ -1,6 +1,7 @@ [config] command = record args = -C 0 kill >/dev/null 2>&1 +ret = 1 [event:base-record] cpu=0 diff --git a/tools/perf/tests/attr/test-record-basic b/tools/perf/tests/attr/test-record-basic index 55c0428370ca20cf7078f833a469fe85d3df8515..85a23cf35ba14dda52997598d5c78afb411ae812 100644 --- a/tools/perf/tests/attr/test-record-basic +++ b/tools/perf/tests/attr/test-record-basic @@ -1,5 +1,6 @@ [config] command = record args = kill >/dev/null 2>&1 +ret = 1 [event:base-record] diff --git a/tools/perf/tests/attr/test-record-branch-any b/tools/perf/tests/attr/test-record-branch-any index 1421960ed4e90cd15f14050f2cdcb0a1ee337506..81f839e2fad019ca43bb5c6be779ab26b79a0afd 100644 --- a/tools/perf/tests/attr/test-record-branch-any +++ b/tools/perf/tests/attr/test-record-branch-any @@ -1,8 +1,8 @@ [config] command = record args = -b kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any b/tools/perf/tests/attr/test-record-branch-filter-any index 915c4df0e0c22bfeb414b96faa0a50cf83e3a2df..357421f4dfcedd07c7e9a98055f2145b8c3c987d 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-any +++ b/tools/perf/tests/attr/test-record-branch-filter-any @@ -1,8 +1,8 @@ [config] command = record args = -j any kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_call b/tools/perf/tests/attr/test-record-branch-filter-any_call index 8708dbd4f373f8aad21e64fe213aa05343771719..dbc55f2ab845843a42272374bddfbc256cf58b7f 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-any_call +++ b/tools/perf/tests/attr/test-record-branch-filter-any_call @@ -1,8 +1,8 @@ [config] command = record args = -j any_call kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=16 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_ret b/tools/perf/tests/attr/test-record-branch-filter-any_ret index 0d3607a6dcbef09f5a6238f2f0c0232d4363e61e..a0824ff8e131d2e38e2ebd2d94bf07f9f7044878 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-any_ret +++ b/tools/perf/tests/attr/test-record-branch-filter-any_ret @@ -1,8 +1,8 @@ [config] command = record args = -j any_ret kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=32 diff --git a/tools/perf/tests/attr/test-record-branch-filter-hv b/tools/perf/tests/attr/test-record-branch-filter-hv index f25526740cec4f5615230901d8d2f449401dbd57..f34d6f120181e40aef44ec175e8dd4af4826b4d8 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-hv +++ b/tools/perf/tests/attr/test-record-branch-filter-hv @@ -1,8 +1,8 @@ [config] command = record args = -j hv kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-ind_call b/tools/perf/tests/attr/test-record-branch-filter-ind_call index e862dd179128d2d06e7479cf186d2fba1422a004..b86a352322487e78e362c9cc74af15946f91c247 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-ind_call +++ b/tools/perf/tests/attr/test-record-branch-filter-ind_call @@ -1,8 +1,8 @@ [config] command = record args = -j ind_call kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=64 diff --git a/tools/perf/tests/attr/test-record-branch-filter-k b/tools/perf/tests/attr/test-record-branch-filter-k index 182971e898f5f01319752e1f32a8932a2e63f0a2..d3fbc5e1858a649611ad4d1541bb9f159d7f0e5a 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-k +++ b/tools/perf/tests/attr/test-record-branch-filter-k @@ -1,8 +1,8 @@ [config] command = record args = -j k kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-u b/tools/perf/tests/attr/test-record-branch-filter-u index 83449ef9e6874be3f3d4b7dc678fb8f36afdc871..a318f0dda173669cbf3d07de3b4b1c3b145b8ba9 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-u +++ b/tools/perf/tests/attr/test-record-branch-filter-u @@ -1,8 +1,8 @@ [config] command = record args = -j u kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-count b/tools/perf/tests/attr/test-record-count index 2f841de56f6b994a370d568527c409e3303196b4..34f6cc5772636e11de8a3efbf292c12e23a99f3b 100644 --- a/tools/perf/tests/attr/test-record-count +++ b/tools/perf/tests/attr/test-record-count @@ -1,6 +1,7 @@ [config] command = record args = -c 123 kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=123 diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data index 716e143b5291196480afee1a7fa14961a8d52a99..a9cf2233b0cef33f5decbdef859823c7339a2455 100644 --- a/tools/perf/tests/attr/test-record-data +++ b/tools/perf/tests/attr/test-record-data @@ -1,10 +1,9 @@ [config] command = record args = -d kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 - # sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | # PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC sample_type=33039 diff --git a/tools/perf/tests/attr/test-record-freq b/tools/perf/tests/attr/test-record-freq index 600d0f8f2583b970d24f5263bf3e658caaff8d87..bf4cb459f0d5c4a195e5de68a4c9efaf232b2b6a 100644 --- a/tools/perf/tests/attr/test-record-freq +++ b/tools/perf/tests/attr/test-record-freq @@ -1,6 +1,7 @@ [config] command = record args = -F 100 kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=100 diff --git a/tools/perf/tests/attr/test-record-graph-default b/tools/perf/tests/attr/test-record-graph-default index 853597a9a8f6484a8446b9c8b94738ccaea37c2c..0b216e69760cd695786fe132c287ddd451e1570f 100644 --- a/tools/perf/tests/attr/test-record-graph-default +++ b/tools/perf/tests/attr/test-record-graph-default @@ -1,6 +1,7 @@ [config] command = record args = -g kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_type=295 diff --git a/tools/perf/tests/attr/test-record-graph-dwarf b/tools/perf/tests/attr/test-record-graph-dwarf index d6f324ea578cf903e0eb99c0c9cbb040855a2fdb..da2fa73bd0a2801876e8acd9f9fe364909a7508d 100644 --- a/tools/perf/tests/attr/test-record-graph-dwarf +++ b/tools/perf/tests/attr/test-record-graph-dwarf @@ -1,10 +1,12 @@ [config] command = record args = --call-graph dwarf -- kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_type=12583 +sample_type=45359 exclude_callchain_user=1 sample_stack_user=8192 # TODO different for each arch, no support for that now sample_regs_user=* +mmap_data=1 diff --git a/tools/perf/tests/attr/test-record-graph-fp b/tools/perf/tests/attr/test-record-graph-fp index 055e3bee79935d50fde8773f84b0fcadd466b1d2..625d190bb798e2bce72f306e8b34af9bf4cc3a50 100644 --- a/tools/perf/tests/attr/test-record-graph-fp +++ b/tools/perf/tests/attr/test-record-graph-fp @@ -1,6 +1,7 @@ [config] command = record args = --call-graph fp kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_type=295 diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group index 57739cacdb2aa10841b16ca1386fe6f8b0ab9db5..6e7961f6f7a570ae7ddb6c06e5f3981ea558430b 100644 --- a/tools/perf/tests/attr/test-record-group +++ b/tools/perf/tests/attr/test-record-group @@ -1,6 +1,7 @@ [config] command = record args = --group -e cycles,instructions kill >/dev/null 2>&1 +ret = 1 [event-1:base-record] fd=1 diff --git a/tools/perf/tests/attr/test-record-group-sampling b/tools/perf/tests/attr/test-record-group-sampling index 658f5d60c8735ef1b859c66b6106a41bd99567c2..ef59afd6d6356b62d51470c3232fcee68864013a 100644 --- a/tools/perf/tests/attr/test-record-group-sampling +++ b/tools/perf/tests/attr/test-record-group-sampling @@ -1,6 +1,7 @@ [config] command = record args = -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1 +ret = 1 [event-1:base-record] fd=1 diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1 index c5548d054aff5ba9ded3225494d9954f22c1e7b2..87a222d014d8392843bfc56afafb11fe015e9a78 100644 --- a/tools/perf/tests/attr/test-record-group1 +++ b/tools/perf/tests/attr/test-record-group1 @@ -1,6 +1,7 @@ [config] command = record args = -e '{cycles,instructions}' kill >/dev/null 2>&1 +ret = 1 [event-1:base-record] fd=1 diff --git a/tools/perf/tests/attr/test-record-no-delay b/tools/perf/tests/attr/test-record-no-buffering similarity index 61% rename from tools/perf/tests/attr/test-record-no-delay rename to tools/perf/tests/attr/test-record-no-buffering index f253b78cdbf29f332611ebeccd92b9f284d64a26..aa3956d8fe207f7ee28bfa3ebbc03511730212e4 100644 --- a/tools/perf/tests/attr/test-record-no-delay +++ b/tools/perf/tests/attr/test-record-no-buffering @@ -1,9 +1,9 @@ [config] command = record -args = -D kill >/dev/null 2>&1 +args = --no-buffering kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=263 watermark=0 wakeup_events=1 diff --git a/tools/perf/tests/attr/test-record-no-inherit b/tools/perf/tests/attr/test-record-no-inherit index 44edcb2edcd50b7c4696477e88f6e12176555303..560943decb87cd5ea2fd28a2b5ccc301109f3c7e 100644 --- a/tools/perf/tests/attr/test-record-no-inherit +++ b/tools/perf/tests/attr/test-record-no-inherit @@ -1,6 +1,7 @@ [config] command = record args = -i kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_type=263 diff --git a/tools/perf/tests/attr/test-record-no-samples b/tools/perf/tests/attr/test-record-no-samples index d0141b2418b5c68cd54d1efd130da65a6fc3fddc..8eb73ab639e0a7ba730bdbf2876958ef62fad7de 100644 --- a/tools/perf/tests/attr/test-record-no-samples +++ b/tools/perf/tests/attr/test-record-no-samples @@ -1,6 +1,7 @@ [config] command = record args = -n kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=0 diff --git a/tools/perf/tests/attr/test-record-period b/tools/perf/tests/attr/test-record-period index 8abc5314fc526271bde031a9cf0cdf82f14a429f..69bc748f0f27db32a8a88e08b9a5b62b17632312 100644 --- a/tools/perf/tests/attr/test-record-period +++ b/tools/perf/tests/attr/test-record-period @@ -1,6 +1,7 @@ [config] command = record args = -c 100 -P kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=100 diff --git a/tools/perf/tests/attr/test-record-raw b/tools/perf/tests/attr/test-record-raw index 4a8ef25b5f499a0c0f5b4f05b1cbf0a7e87fdd01..a188a614a44c5827a9ed373ac03129aa25e42b3c 100644 --- a/tools/perf/tests/attr/test-record-raw +++ b/tools/perf/tests/attr/test-record-raw @@ -1,7 +1,7 @@ [config] command = record args = -R kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=1415 diff --git a/tools/perf/tests/attr/test-stat-C0 b/tools/perf/tests/attr/test-stat-C0 index aa835950751ff81e8afb7e8be2d413073010e905..67717fe6a65d44e66cc5407dc3c709d32ae82d8e 100644 --- a/tools/perf/tests/attr/test-stat-C0 +++ b/tools/perf/tests/attr/test-stat-C0 @@ -4,6 +4,6 @@ args = -e cycles -C 0 kill >/dev/null 2>&1 ret = 1 [event:base-stat] -# events are enabled by default when attached to cpu -disabled=0 +# events are disabled by default when attached to cpu +disabled=1 enable_on_exec=0 diff --git a/tools/perf/tests/attr/test-stat-default b/tools/perf/tests/attr/test-stat-default index 19270f54c96ea7de0470cdf6fafb94256a590844..e911dbd4eb47eb9b1be00e9d14bebab763efb5d0 100644 --- a/tools/perf/tests/attr/test-stat-default +++ b/tools/perf/tests/attr/test-stat-default @@ -38,12 +38,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] diff --git a/tools/perf/tests/attr/test-stat-detailed-1 b/tools/perf/tests/attr/test-stat-detailed-1 index 51426b87153b5aa739f25a4f7dba2d44285c20f1..b39270a08e740a58f5ae2e9fbfdcd5658942502a 100644 --- a/tools/perf/tests/attr/test-stat-detailed-1 +++ b/tools/perf/tests/attr/test-stat-detailed-1 @@ -39,12 +39,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] diff --git a/tools/perf/tests/attr/test-stat-detailed-2 b/tools/perf/tests/attr/test-stat-detailed-2 index 8de5acc31c27ca59420b1ebab6e24a4d42518bcb..45f8e6ea34f817819d5fd71ae9b05e661425e8cb 100644 --- a/tools/perf/tests/attr/test-stat-detailed-2 +++ b/tools/perf/tests/attr/test-stat-detailed-2 @@ -39,12 +39,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] @@ -108,6 +110,7 @@ config=65538 fd=15 type=3 config=1 +optional=1 # PERF_TYPE_HW_CACHE, # PERF_COUNT_HW_CACHE_L1I << 0 | diff --git a/tools/perf/tests/attr/test-stat-detailed-3 b/tools/perf/tests/attr/test-stat-detailed-3 index 0a1f45bf7d799b63b16d5c00908cbcf1af9ada18..30ae0fb7a3fdb12c549050c4985b70c8b885e4ea 100644 --- a/tools/perf/tests/attr/test-stat-detailed-3 +++ b/tools/perf/tests/attr/test-stat-detailed-3 @@ -39,12 +39,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] @@ -108,6 +110,7 @@ config=65538 fd=15 type=3 config=1 +optional=1 # PERF_TYPE_HW_CACHE, # PERF_COUNT_HW_CACHE_L1I << 0 | @@ -162,6 +165,7 @@ config=65540 fd=21 type=3 config=512 +optional=1 # PERF_TYPE_HW_CACHE, # PERF_COUNT_HW_CACHE_L1D << 0 | @@ -171,3 +175,4 @@ config=512 fd=22 type=3 config=66048 +optional=1 diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 50f6d7afee586320b7193b88dea7f521c28aa5f6..d233ad33646319e2a4f8428454fb1d637dd1804e 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -75,7 +75,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, } -int test__backward_ring_buffer(int subtest __maybe_unused) +int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 9abe6c13090ff89ec87d5cee0c72e8467e838fa7..0d7c06584905fb4234abf4cacea86394aec09fa9 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -40,7 +40,7 @@ static int test_bitmap(const char *str) return ret; } -int test__bitmap_print(int subtest __maybe_unused) +int test__bitmap_print(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", test_bitmap("1")); TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,5")); diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 39bbb97cd30aac7704d460e0093c1d82769facf5..97937e1bc53a0c358bf34a9cc50a67f150a1b905 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -164,7 +164,7 @@ static long long bp_count(int fd) return count; } -int test__bp_signal(int subtest __maybe_unused) +int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused) { struct sigaction sa; long long count1, count2, count3; diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index 3b1ac6f31b154412a71e56be084b0f033dff6b3a..61ecd8021f49248485040c9d2523207d351554cd 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -57,7 +57,7 @@ static long long bp_count(int fd) #define EXECUTIONS 10000 #define THRESHOLD 100 -int test__bp_signal_overflow(int subtest __maybe_unused) +int test__bp_signal_overflow(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_event_attr pe; struct sigaction sa; diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75e25aeff999d8b9d79955960a41c2f0520..43f1e16486f495ba3899875f5ffd38cd91228afd 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 5876da126b584febb15b128fb28baac1b30baac9..34c22cdf4d5d9a7c9322f5593fb877bd5b8aff08 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -124,16 +124,16 @@ static int do_test(struct bpf_object *obj, int (*func)(void), struct perf_evlist *evlist; int i, ret = TEST_FAIL, err = 0, count = 0; - struct parse_events_evlist parse_evlist; + struct parse_events_state parse_state; struct parse_events_error parse_error; bzero(&parse_error, sizeof(parse_error)); - bzero(&parse_evlist, sizeof(parse_evlist)); - parse_evlist.error = &parse_error; - INIT_LIST_HEAD(&parse_evlist.list); + bzero(&parse_state, sizeof(parse_state)); + parse_state.error = &parse_error; + INIT_LIST_HEAD(&parse_state.list); - err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj, NULL); - if (err || list_empty(&parse_evlist.list)) { + err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL); + if (err || list_empty(&parse_state.list)) { pr_debug("Failed to add events selected by BPF\n"); return TEST_FAIL; } @@ -155,8 +155,8 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - perf_evlist__splice_list_tail(evlist, &parse_evlist.list); - evlist->nr_groups = parse_evlist.nr_groups; + perf_evlist__splice_list_tail(evlist, &parse_state.list); + evlist->nr_groups = parse_state.nr_groups; perf_evlist__config(evlist, &opts, NULL); @@ -321,7 +321,7 @@ static int check_env(void) return 0; } -int test__bpf(int i) +int test__bpf(struct test *test __maybe_unused, int i) { int err; @@ -351,7 +351,7 @@ const char *test__bpf_subtest_get_desc(int i __maybe_unused) return NULL; } -int test__bpf(int i __maybe_unused) +int test__bpf(struct test *test __maybe_unused, int i __maybe_unused) { pr_debug("Skip BPF test because BPF support is not compiled\n"); return TEST_SKIP; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 3ccfd58a8c3cf3e8b16cc513a67324b8f11eae7b..377bea0091638f04def45caa551992f9000aa530 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -6,7 +6,10 @@ #include #include #include +#include +#include #include +#include #include "builtin.h" #include "hist.h" #include "intlist.h" @@ -14,8 +17,10 @@ #include "debug.h" #include "color.h" #include +#include "string2.h" #include "symbol.h" #include +#include static bool dont_fork; @@ -42,6 +47,10 @@ static struct test generic_tests[] = { .desc = "Read samples using the mmap interface", .func = test__basic_mmap, }, + { + .desc = "Test data source output", + .func = test__mem, + }, { .desc = "Parse event definition strings", .func = test__parse_events, @@ -179,7 +188,7 @@ static struct test generic_tests[] = { }, { .desc = "Session topology", - .func = test_session_topology, + .func = test__session_topology, }, { .desc = "BPF filter", @@ -325,7 +334,7 @@ static int run_test(struct test *test, int subtest) } } - err = test->func(subtest); + err = test->func(test, subtest); if (!dont_fork) exit(err); } @@ -383,12 +392,143 @@ static int test_and_print(struct test *t, bool force_skip, int subtest) return err; } +static const char *shell_test__description(char *description, size_t size, + const char *path, const char *name) +{ + FILE *fp; + char filename[PATH_MAX]; + + path__join(filename, sizeof(filename), path, name); + fp = fopen(filename, "r"); + if (!fp) + return NULL; + + description = fgets(description, size, fp); + fclose(fp); + + return description ? trim(description + 1) : NULL; +} + +#define for_each_shell_test(dir, ent) \ + while ((ent = readdir(dir)) != NULL) \ + if (ent->d_type == DT_REG && ent->d_name[0] != '.') + +static const char *shell_tests__dir(char *path, size_t size) +{ + const char *devel_dirs[] = { "./tools/perf/tests", "./tests", }; + char *exec_path; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(devel_dirs); ++i) { + struct stat st; + if (!lstat(devel_dirs[i], &st)) { + scnprintf(path, size, "%s/shell", devel_dirs[i]); + if (!lstat(devel_dirs[i], &st)) + return path; + } + } + + /* Then installed path. */ + exec_path = get_argv_exec_path(); + scnprintf(path, size, "%s/tests/shell", exec_path); + free(exec_path); + return path; +} + +static int shell_tests__max_desc_width(void) +{ + DIR *dir; + struct dirent *ent; + char path_dir[PATH_MAX]; + const char *path = shell_tests__dir(path_dir, sizeof(path_dir)); + int width = 0; + + if (path == NULL) + return -1; + + dir = opendir(path); + if (!dir) + return -1; + + for_each_shell_test(dir, ent) { + char bf[256]; + const char *desc = shell_test__description(bf, sizeof(bf), path, ent->d_name); + + if (desc) { + int len = strlen(desc); + + if (width < len) + width = len; + } + } + + closedir(dir); + return width; +} + +struct shell_test { + const char *dir; + const char *file; +}; + +static int shell_test__run(struct test *test, int subdir __maybe_unused) +{ + int err; + char script[PATH_MAX]; + struct shell_test *st = test->priv; + + path__join(script, sizeof(script), st->dir, st->file); + + err = system(script); + if (!err) + return TEST_OK; + + return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL; +} + +static int run_shell_tests(int argc, const char *argv[], int i, int width) +{ + DIR *dir; + struct dirent *ent; + char path_dir[PATH_MAX]; + struct shell_test st = { + .dir = shell_tests__dir(path_dir, sizeof(path_dir)), + }; + + if (st.dir == NULL) + return -1; + + dir = opendir(st.dir); + if (!dir) + return -1; + + for_each_shell_test(dir, ent) { + int curr = i++; + char desc[256]; + struct test test = { + .desc = shell_test__description(desc, sizeof(desc), st.dir, ent->d_name), + .func = shell_test__run, + .priv = &st, + }; + + if (!perf_test__matches(&test, curr, argc, argv)) + continue; + + st.file = ent->d_name; + pr_info("%2d: %-*s:", i, width, test.desc); + test_and_print(&test, false, -1); + } + + closedir(dir); + return 0; +} + static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) { struct test *t; unsigned int j; int i = 0; - int width = 0; + int width = shell_tests__max_desc_width(); for_each_test(j, t) { int len = strlen(t->desc); @@ -455,6 +595,37 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) } } + return run_shell_tests(argc, argv, i, width); +} + +static int perf_test__list_shell(int argc, const char **argv, int i) +{ + DIR *dir; + struct dirent *ent; + char path_dir[PATH_MAX]; + const char *path = shell_tests__dir(path_dir, sizeof(path_dir)); + + if (path == NULL) + return -1; + + dir = opendir(path); + if (!dir) + return -1; + + for_each_shell_test(dir, ent) { + int curr = i++; + char bf[256]; + struct test t = { + .desc = shell_test__description(bf, sizeof(bf), path, ent->d_name), + }; + + if (!perf_test__matches(&t, curr, argc, argv)) + continue; + + pr_info("%2d: %s\n", i, t.desc); + } + + closedir(dir); return 0; } @@ -465,12 +636,17 @@ static int perf_test__list(int argc, const char **argv) int i = 0; for_each_test(j, t) { - if (argc > 1 && !strstr(t->desc, argv[1])) + int curr = i++; + + if (!perf_test__matches(t, curr, argc, argv) || + (t->is_supported && !t->is_supported())) continue; - pr_info("%2d: %s\n", ++i, t->desc); + pr_info("%2d: %s\n", i, t->desc); } + perf_test__list_shell(argc, argv, i); + return 0; } @@ -498,7 +674,7 @@ int cmd_test(int argc, const char **argv) argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); if (argc >= 1 && !strcmp(argv[0], "list")) - return perf_test__list(argc, argv); + return perf_test__list(argc - 1, argv + 1); symbol_conf.priv_size = sizeof(int); symbol_conf.sort_by_name = true; diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index c5bb2203f5a90850564397998a8af4b8cb3bfbc1..c60ec916f0f29c17bc17232898a3545af165452c 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -33,12 +33,12 @@ const char *test__clang_subtest_get_desc(int i) } #ifndef HAVE_LIBCLANGLLVM_SUPPORT -int test__clang(int i __maybe_unused) +int test__clang(struct test *test __maybe_unused, int i __maybe_unused) { return TEST_SKIP; } #else -int test__clang(int i) +int test__clang(struct test *test __maybe_unused, int i) { if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) return TEST_FAIL; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 94b7c7b02bdefbb33f2987677c11b3577ab062ec..466a462b26d12996d3b694f9be256bcf8cfc1bb4 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -237,6 +237,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al); if (!al.map || !al.map->dso) { + if (cpumode == PERF_RECORD_MISC_HYPERVISOR) { + pr_debug("Hypervisor address can not be resolved - skipping\n"); + return 0; + } + pr_debug("thread__find_addr_map failed\n"); return -1; } @@ -673,7 +678,7 @@ static int do_test_code_reading(bool try_kcore) return err; } -int test__code_reading(int subtest __maybe_unused) +int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 4478773cdb9751b4f1f5a89f97c1808ad81d1bae..199702252270f1781529031211459bf2ec79272e 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -72,7 +72,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, } -int test__cpu_map_synthesize(int subtest __maybe_unused) +int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { struct cpu_map *cpus; @@ -106,7 +106,7 @@ static int cpu_map_print(const char *str) return !strcmp(buf, str); } -int test__cpu_map_print(int subtest __maybe_unused) +int test__cpu_map_print(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 8f08df5861cb36c7b3415dd706e63cff8ad1aa46..30aead42d136137c451f4c4228b31e36bd7597bc 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -112,7 +112,7 @@ static int dso__data_fd(struct dso *dso, struct machine *machine) return fd; } -int test__dso_data(int subtest __maybe_unused) +int test__dso_data(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; struct dso *dso; @@ -247,7 +247,7 @@ static int set_fd_limit(int n) return setrlimit(RLIMIT_NOFILE, &rlim); } -int test__dso_data_cache(int subtest __maybe_unused) +int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(); @@ -307,7 +307,7 @@ int test__dso_data_cache(int subtest __maybe_unused) return 0; } -int test__dso_data_reopen(int subtest __maybe_unused) +int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(); diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 3e56d08f799566f3ea69dbd00f018df03497b862..9ba1d216a89fb48359258f6ee6b0c720f8d49ca2 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -6,7 +6,7 @@ #include "debug.h" #include "machine.h" #include "event.h" -#include "unwind.h" +#include "../util/unwind.h" #include "perf_regs.h" #include "map.h" #include "thread.h" @@ -154,7 +154,7 @@ static noinline int krava_1(struct thread *thread) return krava_2(thread); } -int test__dwarf_unwind(int subtest __maybe_unused) +int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine *machine; struct thread *thread; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 634f20c631d8f9981dc89499998e3315d7661243..b82b981c32594aa367c7f114a6bc27f77cebb9b0 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -213,7 +213,7 @@ static int test_times(int (attach)(struct perf_evlist *), * and checks that enabled and running times * match. */ -int test__event_times(int subtest __maybe_unused) +int test__event_times(struct test *test __maybe_unused, int subtest __maybe_unused) { int err, ret = 0; diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 63ecf21750eb0dca6e865cb90a57905df1fb566e..9484da2ec6b4215713059f81b66d02d3899fe9cb 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -76,7 +76,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, return 0; } -int test__event_update(int subtest __maybe_unused) +int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evlist *evlist; struct perf_evsel *evsel; diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index d2bea6f780f8a1184c67c92d96727c7ddc715046..d32759b6e38a53f43f64ad74bf058f54e3f5bf7b 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -97,7 +97,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names) #define perf_evsel__name_array_test(names) \ __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) -int test__perf_evsel__roundtrip_name_test(int subtest __maybe_unused) +int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = 0, ret = 0; diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 1984b3bbfe15d2bc6f407e1e272d3f1a95046916..5fc906d26c5ccde1d7e9100898d126300846f2a7 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -32,7 +32,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, return ret; } -int test__perf_evsel__tp_sched_test(int subtest __maybe_unused) +int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch"); int ret = 0; diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 6c6a3749aaf6bf5e7f54585e2872bcdcfc12c0a3..cb251bf523e7baf6679e945c185d81fa47d7c009 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -13,7 +13,7 @@ static int test(struct parse_ctx *ctx, const char *e, double val2) return 0; } -int test__expr(int subtest __maybe_unused) +int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) { const char *p; const char **other; @@ -31,6 +31,11 @@ int test__expr(int subtest __maybe_unused) ret |= test(&ctx, "(BAR/2)%2", 1); ret |= test(&ctx, "1 - -4", 5); ret |= test(&ctx, "(FOO-1)*2 + (BAR/2)%2 - -4", 5); + ret |= test(&ctx, "1-1 | 1", 1); + ret |= test(&ctx, "1-1 & 1", 0); + ret |= test(&ctx, "min(1,2) + 1", 2); + ret |= test(&ctx, "max(1,2) + 1", 3); + ret |= test(&ctx, "1+1 if 3*4 else 0", 2); if (ret) return ret; diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c index bc5982f42dc3a173d81e5100172578ac4bdb280b..7d3a9e2ff8977153db1c38bafbac082cd8a3269a 100644 --- a/tools/perf/tests/fdarray.c +++ b/tools/perf/tests/fdarray.c @@ -26,7 +26,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE return printed + fdarray__fprintf(fda, fp); } -int test__fdarray__filter(int subtest __maybe_unused) +int test__fdarray__filter(struct test *test __maybe_unused, int subtest __maybe_unused) { int nr_fds, expected_fd[2], fd, err = TEST_FAIL; struct fdarray *fda = fdarray__new(5, 5); @@ -104,7 +104,7 @@ int test__fdarray__filter(int subtest __maybe_unused) return err; } -int test__fdarray__add(int subtest __maybe_unused) +int test__fdarray__add(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct fdarray *fda = fdarray__new(2, 2); diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index d549a9f2c41b30f4d35eae742dbdfcb584ee804d..8d19c0200cb74c6be1b08bcdbd5860d2727e93bc 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -687,7 +687,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) return err; } -int test__hists_cumulate(int subtest __maybe_unused) +int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index df9c91f49af19927ad48bc9c103aaf8bd43e0c40..755ca551b810ca44434d4a56c1be92b86095d221 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -101,7 +101,7 @@ static int add_hist_entries(struct perf_evlist *evlist, return TEST_FAIL; } -int test__hists_filter(int subtest __maybe_unused) +int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index a26cbb79e988832af5eeddd4b9970ba37326a248..073c9c2856bc4dae2a65c3f3f90cdd9021f9acb2 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -264,7 +264,7 @@ static int validate_link(struct hists *leader, struct hists *other) return __validate_link(leader, 0) || __validate_link(other, 1); } -int test__hists_link(int subtest __maybe_unused) +int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; struct hists *hists, *first_hists; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 06e5080182d31e879b25d2cabfc43c7a9a552097..282d62eaebe2512282e222ebc78bd857192011f5 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -573,7 +573,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine) return err; } -int test__hists_output(int subtest __maybe_unused) +int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c index a5192f6a20d798990958adcfea8da970416183cd..38f765767587ae0e3c7a9a6df15ad1b892a36eb7 100644 --- a/tools/perf/tests/is_printable_array.c +++ b/tools/perf/tests/is_printable_array.c @@ -4,7 +4,7 @@ #include "debug.h" #include "print_binary.h" -int test__is_printable_array(int subtest __maybe_unused) +int test__is_printable_array(struct test *test __maybe_unused, int subtest __maybe_unused) { char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 }; char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 }; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 614e45a3c6038099fd9fe6b838db0f1988d20855..739428603b71293ce3ba5d44304a5c6aa77868ef 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -49,7 +49,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm) * when an event is disabled but a dummy software event is not disabled. If the * test passes %0 is returned, otherwise %-1 is returned. */ -int test__keep_tracking(int subtest __maybe_unused) +int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index 6cd9e5107f7784ab4c340f80a03bc786b7c264b4..8b9d4ba06c0e11177f2acec6bfe40b87a4f46727 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -50,7 +50,7 @@ static int test_is_kernel_module(const char *path, int cpumode, bool expect) #define M(path, c, e) \ TEST_ASSERT_VAL("failed", !test_is_kernel_module(path, c, e)) -int test__kmod_path__parse(int subtest __maybe_unused) +int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused) { /* path alloc_name alloc_ext kmod comp name ext */ T("/xxxx/xxxx/x-x.ko", true , true , true, false, "[x_x]", NULL); diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 482b5365e68d85b3ea4915631f398873e575d72b..5187b50dbafe558b110ef80dfbd3f4ff0a2beaef 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -132,7 +132,7 @@ test_llvm__fetch_bpf_obj(void **p_obj_buf, return ret; } -int test__llvm(int subtest) +int test__llvm(struct test *test __maybe_unused, int subtest) { int ret; void *obj_buf = NULL; diff --git a/tools/perf/tests/mem.c b/tools/perf/tests/mem.c new file mode 100644 index 0000000000000000000000000000000000000000..21952e1e6e6d844f749b09cb9323b134af53f83a --- /dev/null +++ b/tools/perf/tests/mem.c @@ -0,0 +1,56 @@ +#include "util/mem-events.h" +#include "util/symbol.h" +#include "linux/perf_event.h" +#include "util/debug.h" +#include "tests.h" +#include + +static int check(union perf_mem_data_src data_src, + const char *string) +{ + char out[100]; + char failure[100]; + struct mem_info mi = { .data_src = data_src }; + + int n; + + n = perf_mem__snp_scnprintf(out, sizeof out, &mi); + n += perf_mem__lvl_scnprintf(out + n, sizeof out - n, &mi); + snprintf(failure, sizeof failure, "unexpected %s", out); + TEST_ASSERT_VAL(failure, !strcmp(string, out)); + return 0; +} + +int test__mem(struct test *text __maybe_unused, int subtest __maybe_unused) +{ + int ret = 0; + union perf_mem_data_src src; + + memset(&src, 0, sizeof(src)); + + src.mem_lvl = PERF_MEM_LVL_HIT; + src.mem_lvl_num = 4; + + ret |= check(src, "N/AL4 hit"); + + src.mem_remote = 1; + + ret |= check(src, "N/ARemote L4 hit"); + + src.mem_lvl = PERF_MEM_LVL_MISS; + src.mem_lvl_num = PERF_MEM_LVLNUM_PMEM; + src.mem_remote = 0; + + ret |= check(src, "N/APMEM miss"); + + src.mem_remote = 1; + + ret |= check(src, "N/ARemote PMEM miss"); + + src.mem_snoopx = PERF_MEM_SNOOPX_FWD; + src.mem_lvl_num = PERF_MEM_LVLNUM_RAM; + + ret |= check(src , "FwdRemote RAM miss"); + + return ret; +} diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 15c770856aacc6363c5b2618e51bb1356debbde1..bc8a70ee46d8b6bbb734409c06205ab7247562c2 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -22,7 +22,7 @@ * Then it checks if the number of syscalls reported as perf events by * the kernel corresponds to the number of syscalls made. */ -int test__basic_mmap(int subtest __maybe_unused) +int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 6ea4d8a5d26b15ff4b3e0a228c51850260263d13..f94a4196e7c9d9a38a97d4ca60c641f2074f4e1e 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -221,7 +221,7 @@ static int mmap_events(synth_cb synth) * * by using all thread objects. */ -int test__mmap_thread_lookup(int subtest __maybe_unused) +int test__mmap_thread_lookup(struct test *test __maybe_unused, int subtest __maybe_unused) { /* perf_event__synthesize_threads synthesize */ TEST_ASSERT_VAL("failed with sythesizing all", diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 1a74dd9fd06792001f111d3ca4b42ce484319704..9cf1c35f2ad0c0289b414596f11eeb0057c22fec 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -16,7 +16,7 @@ #include "debug.h" #include "stat.h" -int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused) +int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd, cpu; struct cpu_map *cpus; @@ -115,7 +115,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused) perf_evsel__free_counts(evsel); out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); + perf_evsel__close_fd(evsel); out_evsel_delete: perf_evsel__delete(evsel); out_thread_map_delete: diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 9788fac910950d63244f83d417a1e421edd98ee4..b6ee1c41f45d674b8cc0341169bcce2b115fa368 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -14,7 +14,7 @@ #define AT_FDCWD -100 #endif -int test__syscall_openat_tp_fields(int subtest __maybe_unused) +int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .target = { diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index e44506e21ee779e33f4d8ffa7e6e6b4ebe40cc36..9dc5c5d375531fadd5429fc5417721883d267e1a 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -10,7 +10,7 @@ #include "debug.h" #include "tests.h" -int test__openat_syscall_event(int subtest __maybe_unused) +int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd; struct perf_evsel *evsel; @@ -56,7 +56,7 @@ int test__openat_syscall_event(int subtest __maybe_unused) err = 0; out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); + perf_evsel__close_fd(evsel); out_evsel_delete: perf_evsel__delete(evsel); out_thread_map_delete: diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 812a053d1941f0ad49d818371fa5aacbca4a3013..0f0b025faa4b4748928f76dd956b51499c1e0027 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1810,7 +1810,7 @@ static int test_pmu_events(void) return ret; } -int test__parse_events(int subtest __maybe_unused) +int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret1, ret2 = 0; diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index c6207db09f12850f02123525a07c0c025e08a55d..91867dcc39f0142544eaef16aea30dc4ca3cf7cb 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -68,7 +68,7 @@ struct test_attr_event { * * Return: %0 on success, %-1 if the test fails. */ -int test__parse_no_sample_id_all(int subtest __maybe_unused) +int test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest __maybe_unused) { int err; diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c index 665ecc19671c6cbc0357038819bda16a69cda1d0..bf2517d6de7079dacffb9d78e006952dd593823d 100644 --- a/tools/perf/tests/perf-hooks.c +++ b/tools/perf/tests/perf-hooks.c @@ -27,7 +27,7 @@ static void the_hook(void *_hook_flags) *p = 0; } -int test__perf_hooks(int subtest __maybe_unused) +int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused) { int hook_flags = 0; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index d37cd9588cc0357577a513bca0afe9e600b0c58f..19b650064b703b5baf5445f3eba33038bf71e651 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -37,7 +37,7 @@ static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) return cpu; } -int test__PERF_RECORD(int subtest __maybe_unused) +int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .target = { diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index a6d7aef3003056446f0b4507409d6672a63c986a..9f7f589f9c548b770518c51a3d5b33a8c19d5f7c 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -135,7 +135,7 @@ static struct list_head *test_terms_list(void) return &terms; } -int test__pmu(int subtest __maybe_unused) +int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) { char *format = test_format_dir_get(); LIST_HEAD(formats); diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c index fa79509da535403888c41cfa33a3ca3ff89033fd..598a7e058ad4f1e04afbe563b204d8cc795fd691 100644 --- a/tools/perf/tests/python-use.c +++ b/tools/perf/tests/python-use.c @@ -9,7 +9,7 @@ extern int verbose; -int test__python_use(int subtest __maybe_unused) +int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unused) { char *cmd; int ret; diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index bac5c3885b3be58180eb4fc258c72b9b0c8241be..c3858487159d7984df90333b7c254f59ebf29ad2 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -141,6 +141,9 @@ static bool samples_same(const struct perf_sample *s1, } } + if (type & PERF_SAMPLE_PHYS_ADDR) + COMP(phys_addr); + return true; } @@ -206,6 +209,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) .mask = sample_regs, .regs = regs, }, + .phys_addr = 113, }; struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},}; struct perf_sample sample_out; @@ -292,7 +296,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) * checks sample format bits separately and together. If the test passes %0 is * returned, otherwise %-1 is returned. */ -int test__sample_parsing(int subtest __maybe_unused) +int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) { const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15}; u64 sample_type; @@ -305,7 +309,7 @@ int test__sample_parsing(int subtest __maybe_unused) * were added. Please actually update the test rather than just change * the condition below. */ - if (PERF_SAMPLE_MAX > PERF_SAMPLE_REGS_INTR << 1) { + if (PERF_SAMPLE_MAX > PERF_SAMPLE_PHYS_ADDR << 1) { pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n"); return -1; } diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index 06eda675ae2c1ee3a59758c00285dc1a1f793230..a9903d9b8bc2fb272e6cea6cafa438c52c5a3234 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -33,7 +33,7 @@ static int build_id_cache__add_file(const char *filename) } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__add_s(sbuild_id, filename, false, false); + err = build_id_cache__add_s(sbuild_id, filename, NULL, false, false); if (err < 0) pr_debug("Failed to add build id cache of %s\n", filename); return err; @@ -54,7 +54,7 @@ static char *get_self_path(void) static int search_cached_probe(const char *target, const char *group, const char *event) { - struct probe_cache *cache = probe_cache__new(target); + struct probe_cache *cache = probe_cache__new(target, NULL); int ret = 0; if (!cache) { @@ -71,7 +71,7 @@ static int search_cached_probe(const char *target, return ret; } -int test__sdt_event(int subtests __maybe_unused) +int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) { int ret = TEST_FAIL; char __tempdir[] = "./test-buildid-XXXXXX"; @@ -83,6 +83,8 @@ int test__sdt_event(int subtests __maybe_unused) } /* Note that buildid_dir must be an absolute path */ tempdir = realpath(__tempdir, NULL); + if (tempdir == NULL) + goto error_rmdir; /* At first, scan itself */ set_buildid_dir(tempdir); @@ -100,14 +102,14 @@ int test__sdt_event(int subtests __maybe_unused) error_rmdir: /* Cleanup temporary buildid dir */ - rm_rf(tempdir); + rm_rf(__tempdir); error: free(tempdir); free(myself); return ret; } #else -int test__sdt_event(int subtests __maybe_unused) +int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) { pr_debug("Skip SDT event test because SDT support is not compiled\n"); return TEST_SKIP; diff --git a/tools/perf/tests/shell/lib/probe.sh b/tools/perf/tests/shell/lib/probe.sh new file mode 100644 index 0000000000000000000000000000000000000000..6293cc6609470966c1d173a722bc3744b0863e5c --- /dev/null +++ b/tools/perf/tests/shell/lib/probe.sh @@ -0,0 +1,6 @@ +# Arnaldo Carvalho de Melo , 2017 + +skip_if_no_perf_probe() { + perf probe 2>&1 | grep -q 'is not a perf-command' && return 2 + return 0 +} diff --git a/tools/perf/tests/shell/lib/probe_vfs_getname.sh b/tools/perf/tests/shell/lib/probe_vfs_getname.sh new file mode 100644 index 0000000000000000000000000000000000000000..30a950c9d407dfa8c7c672e15dc7a6b777aa1790 --- /dev/null +++ b/tools/perf/tests/shell/lib/probe_vfs_getname.sh @@ -0,0 +1,23 @@ +# Arnaldo Carvalho de Melo , 2017 + +perf probe -l 2>&1 | grep -q probe:vfs_getname +had_vfs_getname=$? + +cleanup_probe_vfs_getname() { + if [ $had_vfs_getname -eq 1 ] ; then + perf probe -q -d probe:vfs_getname + fi +} + +add_probe_vfs_getname() { + local verbose=$1 + if [ $had_vfs_getname -eq 1 ] ; then + line=$(perf probe -L getname_flags 2>&1 | egrep 'result.*=.*filename;' | sed -r 's/[[:space:]]+([[:digit:]]+)[[:space:]]+result->uptr.*/\1/') + perf probe $verbose "vfs_getname=getname_flags:${line} pathname=result->name:string" + fi +} + +skip_if_no_debuginfo() { + add_probe_vfs_getname -v 2>&1 | egrep -q "^(Failed to find the path for kernel|Debuginfo-analysis is not supported)" && return 2 + return 1 +} diff --git a/tools/perf/tests/shell/probe_vfs_getname.sh b/tools/perf/tests/shell/probe_vfs_getname.sh new file mode 100755 index 0000000000000000000000000000000000000000..9b7635184dc20e6018027045996e53648c97c61a --- /dev/null +++ b/tools/perf/tests/shell/probe_vfs_getname.sh @@ -0,0 +1,14 @@ +# Add vfs_getname probe to get syscall args filenames +# +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +skip_if_no_perf_probe || exit 2 + +. $(dirname $0)/lib/probe_vfs_getname.sh + +add_probe_vfs_getname || skip_if_no_debuginfo +err=$? +cleanup_probe_vfs_getname +exit $err diff --git a/tools/perf/tests/shell/record+script_probe_vfs_getname.sh b/tools/perf/tests/shell/record+script_probe_vfs_getname.sh new file mode 100755 index 0000000000000000000000000000000000000000..ba29535b8580a6caebfb339d4d81789b41e407ec --- /dev/null +++ b/tools/perf/tests/shell/record+script_probe_vfs_getname.sh @@ -0,0 +1,41 @@ +# Use vfs_getname probe to get syscall args filenames + +# Uses the 'perf test shell' library to add probe:vfs_getname to the system +# then use it with 'perf record' using 'touch' to write to a temp file, then +# checks that that was captured by the vfs_getname probe in the generated +# perf.data file, with the temp file name as the pathname argument. + +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +skip_if_no_perf_probe || exit 2 + +. $(dirname $0)/lib/probe_vfs_getname.sh + +perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) +file=$(mktemp /tmp/temporary_file.XXXXX) + +record_open_file() { + echo "Recording open file:" + perf record -o ${perfdata} -e probe:vfs_getname touch $file +} + +perf_script_filenames() { + echo "Looking at perf.data file for vfs_getname records for the file we touched:" + perf script -i ${perfdata} | \ + egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname: +\([[:xdigit:]]+\) +pathname=\"${file}\"" +} + +add_probe_vfs_getname || skip_if_no_debuginfo +err=$? +if [ $err -ne 0 ] ; then + exit $err +fi + +record_open_file && perf_script_filenames +err=$? +rm -f ${perfdata} +rm -f ${file} +cleanup_probe_vfs_getname +exit $err diff --git a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh new file mode 100755 index 0000000000000000000000000000000000000000..462fc755092e0b95cdf9ffd2ecf2317f4a4cf5df --- /dev/null +++ b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh @@ -0,0 +1,43 @@ +# probe libc's inet_pton & backtrace it with ping + +# Installs a probe on libc's inet_pton function, that will use uprobes, +# then use 'perf trace' on a ping to localhost asking for just one packet +# with the a backtrace 3 levels deep, check that it is what we expect. +# This needs no debuginfo package, all is done using the libc ELF symtab +# and the CFI info in the binaries. + +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +trace_libc_inet_pton_backtrace() { + idx=0 + expected[0]="PING.*bytes" + expected[1]="64 bytes from ::1.*" + expected[2]=".*ping statistics.*" + expected[3]=".*packets transmitted.*" + expected[4]="rtt min.*" + expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" + expected[6]=".*inet_pton[[:space:]]\(/usr/lib.*/libc-[0-9]+\.[0-9]+\.so\)$" + expected[7]="getaddrinfo[[:space:]]\(/usr/lib.*/libc-[0-9]+\.[0-9]+\.so\)$" + expected[8]=".*\(.*/bin/ping.*\)$" + + perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do + echo $line + echo "$line" | egrep -q "${expected[$idx]}" + if [ $? -ne 0 ] ; then + printf "FAIL: expected backtrace entry %d \"%s\" got \"%s\"\n" $idx "${expected[$idx]}" "$line" + exit 1 + fi + let idx+=1 + [ $idx -eq 9 ] && break + done +} + +skip_if_no_perf_probe && \ +perf probe -q /lib64/libc-*.so inet_pton && \ +trace_libc_inet_pton_backtrace +err=$? +rm -f ${file} +perf probe -q -d probe_libc:inet_pton +exit $err diff --git a/tools/perf/tests/shell/trace+probe_vfs_getname.sh b/tools/perf/tests/shell/trace+probe_vfs_getname.sh new file mode 100755 index 0000000000000000000000000000000000000000..2e68c5f120da87250a87b5067793e2ca75ced60c --- /dev/null +++ b/tools/perf/tests/shell/trace+probe_vfs_getname.sh @@ -0,0 +1,35 @@ +# Check open filename arg using perf trace + vfs_getname + +# Uses the 'perf test shell' library to add probe:vfs_getname to the system +# then use it with 'perf trace' using 'touch' to write to a temp file, then +# checks that that was captured by the vfs_getname was used by 'perf trace', +# that already handles "probe:vfs_getname" if present, and used in the +# "open" syscall "filename" argument beautifier. + +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +skip_if_no_perf_probe || exit 2 + +. $(dirname $0)/lib/probe_vfs_getname.sh + +file=$(mktemp /tmp/temporary_file.XXXXX) + +trace_open_vfs_getname() { + perf trace -e open touch $file 2>&1 | \ + egrep " +[0-9]+\.[0-9]+ +\( +[0-9]+\.[0-9]+ ms\): +touch\/[0-9]+ open\(filename: +${file}, +flags: CREAT\|NOCTTY\|NONBLOCK\|WRONLY, +mode: +IRUGO\|IWUGO\) += +[0-9]+$" +} + + +add_probe_vfs_getname || skip_if_no_debuginfo +err=$? +if [ $err -ne 0 ] ; then + exit $err +fi + +trace_open_vfs_getname +err=$? +rm -f ${file} +cleanup_probe_vfs_getname +exit $err diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c index 6a20ff2326bb1eb4127b8b6a76eda044d5ecb641..7f988a9390361fdef00a7eab206f3eba13cf7f83 100644 --- a/tools/perf/tests/stat.c +++ b/tools/perf/tests/stat.c @@ -45,7 +45,7 @@ static int process_stat_config_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat_config(int subtest __maybe_unused) +int test__synthesize_stat_config(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_stat_config stat_config = { .aggr_mode = AGGR_CORE, @@ -75,7 +75,7 @@ static int process_stat_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat(int subtest __maybe_unused) +int test__synthesize_stat(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_counts_values count; @@ -101,7 +101,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat_round(int subtest __maybe_unused) +int test__synthesize_stat_round(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to synthesize stat_config", !perf_event__synthesize_stat_round(NULL, 0xdeadbeef, PERF_STAT_ROUND_TYPE__INTERVAL, diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 828494db4a190945dd3da7aa0d3ae3a987a52d36..d88511f6072c2429f6c9956b83e3be803e780148 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -124,7 +124,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) return err; } -int test__sw_clock_freq(int subtest __maybe_unused) +int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 65474fd80da7216df44bc2e221660b89f4b3a02d..2acd78555192d1482fabf8bc78a6f26de91006bd 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -306,7 +306,7 @@ static int process_events(struct perf_evlist *evlist, * evsel->system_wide and evsel->tracking flags (respectively) with other events * sometimes enabled or disabled. */ -int test__switch_tracking(int subtest __maybe_unused) +int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) { const char *sched_switch = "sched:sched_switch"; struct switch_tracking switch_tracking = { .tids = NULL, }; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index cf00ebad2ef5ccefabee6324e004fc9b4d2e601b..f0881d0dd9c9f60b542e5c727689bd156e245c86 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -32,7 +32,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, * if the number of exit event reported by the kernel is 1 or not * in order to check the kernel returns correct number of event. */ -int test__task_exit(int subtest __maybe_unused) +int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 577363809c9b1b54731f7e80b291278bf2764e78..921412a6a88081ca67ddc51f46e2c533dc31beac 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -28,77 +28,79 @@ enum { struct test { const char *desc; - int (*func)(int subtest); + int (*func)(struct test *test, int subtest); struct { bool skip_if_fail; int (*get_nr)(void); const char *(*get_desc)(int subtest); } subtest; bool (*is_supported)(void); + void *priv; }; /* Tests */ -int test__vmlinux_matches_kallsyms(int subtest); -int test__openat_syscall_event(int subtest); -int test__openat_syscall_event_on_all_cpus(int subtest); -int test__basic_mmap(int subtest); -int test__PERF_RECORD(int subtest); -int test__perf_evsel__roundtrip_name_test(int subtest); -int test__perf_evsel__tp_sched_test(int subtest); -int test__syscall_openat_tp_fields(int subtest); -int test__pmu(int subtest); -int test__attr(int subtest); -int test__dso_data(int subtest); -int test__dso_data_cache(int subtest); -int test__dso_data_reopen(int subtest); -int test__parse_events(int subtest); -int test__hists_link(int subtest); -int test__python_use(int subtest); -int test__bp_signal(int subtest); -int test__bp_signal_overflow(int subtest); -int test__task_exit(int subtest); -int test__sw_clock_freq(int subtest); -int test__code_reading(int subtest); -int test__sample_parsing(int subtest); -int test__keep_tracking(int subtest); -int test__parse_no_sample_id_all(int subtest); -int test__dwarf_unwind(int subtest); -int test__expr(int subtest); -int test__hists_filter(int subtest); -int test__mmap_thread_lookup(int subtest); -int test__thread_mg_share(int subtest); -int test__hists_output(int subtest); -int test__hists_cumulate(int subtest); -int test__switch_tracking(int subtest); -int test__fdarray__filter(int subtest); -int test__fdarray__add(int subtest); -int test__kmod_path__parse(int subtest); -int test__thread_map(int subtest); -int test__llvm(int subtest); +int test__vmlinux_matches_kallsyms(struct test *test, int subtest); +int test__openat_syscall_event(struct test *test, int subtest); +int test__openat_syscall_event_on_all_cpus(struct test *test, int subtest); +int test__basic_mmap(struct test *test, int subtest); +int test__PERF_RECORD(struct test *test, int subtest); +int test__perf_evsel__roundtrip_name_test(struct test *test, int subtest); +int test__perf_evsel__tp_sched_test(struct test *test, int subtest); +int test__syscall_openat_tp_fields(struct test *test, int subtest); +int test__pmu(struct test *test, int subtest); +int test__attr(struct test *test, int subtest); +int test__dso_data(struct test *test, int subtest); +int test__dso_data_cache(struct test *test, int subtest); +int test__dso_data_reopen(struct test *test, int subtest); +int test__parse_events(struct test *test, int subtest); +int test__hists_link(struct test *test, int subtest); +int test__python_use(struct test *test, int subtest); +int test__bp_signal(struct test *test, int subtest); +int test__bp_signal_overflow(struct test *test, int subtest); +int test__task_exit(struct test *test, int subtest); +int test__mem(struct test *test, int subtest); +int test__sw_clock_freq(struct test *test, int subtest); +int test__code_reading(struct test *test, int subtest); +int test__sample_parsing(struct test *test, int subtest); +int test__keep_tracking(struct test *test, int subtest); +int test__parse_no_sample_id_all(struct test *test, int subtest); +int test__dwarf_unwind(struct test *test, int subtest); +int test__expr(struct test *test, int subtest); +int test__hists_filter(struct test *test, int subtest); +int test__mmap_thread_lookup(struct test *test, int subtest); +int test__thread_mg_share(struct test *test, int subtest); +int test__hists_output(struct test *test, int subtest); +int test__hists_cumulate(struct test *test, int subtest); +int test__switch_tracking(struct test *test, int subtest); +int test__fdarray__filter(struct test *test, int subtest); +int test__fdarray__add(struct test *test, int subtest); +int test__kmod_path__parse(struct test *test, int subtest); +int test__thread_map(struct test *test, int subtest); +int test__llvm(struct test *test, int subtest); const char *test__llvm_subtest_get_desc(int subtest); int test__llvm_subtest_get_nr(void); -int test__bpf(int subtest); +int test__bpf(struct test *test, int subtest); const char *test__bpf_subtest_get_desc(int subtest); int test__bpf_subtest_get_nr(void); -int test_session_topology(int subtest); -int test__thread_map_synthesize(int subtest); -int test__thread_map_remove(int subtest); -int test__cpu_map_synthesize(int subtest); -int test__synthesize_stat_config(int subtest); -int test__synthesize_stat(int subtest); -int test__synthesize_stat_round(int subtest); -int test__event_update(int subtest); -int test__event_times(int subtest); -int test__backward_ring_buffer(int subtest); -int test__cpu_map_print(int subtest); -int test__sdt_event(int subtest); -int test__is_printable_array(int subtest); -int test__bitmap_print(int subtest); -int test__perf_hooks(int subtest); -int test__clang(int subtest); +int test__session_topology(struct test *test, int subtest); +int test__thread_map_synthesize(struct test *test, int subtest); +int test__thread_map_remove(struct test *test, int subtest); +int test__cpu_map_synthesize(struct test *test, int subtest); +int test__synthesize_stat_config(struct test *test, int subtest); +int test__synthesize_stat(struct test *test, int subtest); +int test__synthesize_stat_round(struct test *test, int subtest); +int test__event_update(struct test *test, int subtest); +int test__event_times(struct test *test, int subtest); +int test__backward_ring_buffer(struct test *test, int subtest); +int test__cpu_map_print(struct test *test, int subtest); +int test__sdt_event(struct test *test, int subtest); +int test__is_printable_array(struct test *test, int subtest); +int test__bitmap_print(struct test *test, int subtest); +int test__perf_hooks(struct test *test, int subtest); +int test__clang(struct test *test, int subtest); const char *test__clang_subtest_get_desc(int subtest); int test__clang_subtest_get_nr(void); -int test__unit_number__scnprint(int subtest); +int test__unit_number__scnprint(struct test *test, int subtest); bool test__bp_signal_is_supported(void); diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index a63d6945807b3a0e7fe9247475068e258dbd9cdc..b3423c744f46251ca8966f3d3f32ba970b52773f 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -9,7 +9,7 @@ #define NAME (const char *) "perf" #define NAMEUL (unsigned long) NAME -int test__thread_map(int subtest __maybe_unused) +int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unused) { struct thread_map *map; @@ -76,7 +76,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__thread_map_synthesize(int subtest __maybe_unused) +int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { struct thread_map *threads; @@ -95,7 +95,7 @@ int test__thread_map_synthesize(int subtest __maybe_unused) return 0; } -int test__thread_map_remove(int subtest __maybe_unused) +int test__thread_map_remove(struct test *test __maybe_unused, int subtest __maybe_unused) { struct thread_map *threads; char *str; diff --git a/tools/perf/tests/thread-mg-share.c b/tools/perf/tests/thread-mg-share.c index 76686dd6f5ecfd235705bca7b39d7abdc237a150..b9c7f58db6c416f97e941a8ee26dc98bf9987670 100644 --- a/tools/perf/tests/thread-mg-share.c +++ b/tools/perf/tests/thread-mg-share.c @@ -4,7 +4,7 @@ #include "map.h" #include "debug.h" -int test__thread_mg_share(int subtest __maybe_unused) +int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machines machines; struct machine *machine; diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 803f893550d64c03c6354acf88045821cc7fe171..19b0561fd6f65b13f9c941cdaa7c7cceaa8ba270 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -86,7 +86,7 @@ static int check_cpu_topology(char *path, struct cpu_map *map) return 0; } -int test_session_topology(int subtest __maybe_unused) +int test__session_topology(struct test *test __maybe_unused, int subtest __maybe_unused) { char path[PATH_MAX]; struct cpu_map *map; diff --git a/tools/perf/tests/unit_number__scnprintf.c b/tools/perf/tests/unit_number__scnprintf.c index 44589de084b824319063df71ce0543f7f054088b..15cd1cf8c129d74d0499a06a874d82f4085b64af 100644 --- a/tools/perf/tests/unit_number__scnprintf.c +++ b/tools/perf/tests/unit_number__scnprintf.c @@ -5,7 +5,7 @@ #include "units.h" #include "debug.h" -int test__unit_number__scnprint(int subtest __maybe_unused) +int test__unit_number__scnprint(struct test *t __maybe_unused, int subtest __maybe_unused) { struct { u64 n; diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 8456175fc23458091aaf787a465d3a7123fd5f71..86cb8868f67f119f8f98f37074f71ec8ba4ec107 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -11,7 +11,7 @@ #define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x)) -int test__vmlinux_matches_kallsyms(int subtest __maybe_unused) +int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; struct rb_node *nd; diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index be95ac6ce84595817ddc267bc7cc77b434c26e81..175d633c6b491e5beb5257c02bdd36894268b74b 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build @@ -1 +1,7 @@ +libperf-y += clone.o +libperf-y += fcntl.o +ifeq ($(SRCARCH),$(filter $(SRCARCH),x86)) +libperf-y += ioctl.o +endif +libperf-y += pkey_alloc.o libperf-y += statx.o diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index cf50be3f17a4ff3acdd9506ce00f8cff7f280f5f..4b58581a605306c1557036cb24a18598d0711acf 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -1,13 +1,44 @@ #ifndef _PERF_TRACE_BEAUTY_H #define _PERF_TRACE_BEAUTY_H +#include #include +struct strarray { + int offset; + int nr_entries; + const char **entries; +}; + +#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \ + .offset = off, \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val); + struct trace; struct thread; +/** + * @val: value of syscall argument being formatted + * @args: All the args, use syscall_args__val(arg, nth) to access one + * @thread: tid state (maps, pid, tid, etc) + * @trace: 'perf trace' internals: all threads, etc + * @parm: private area, may be an strarray, for instance + * @idx: syscall arg idx (is this the first?) + * @mask: a syscall arg may mask another arg, see syscall_arg__scnprintf_futex_op + */ + struct syscall_arg { unsigned long val; + unsigned char *args; struct thread *thread; struct trace *trace; void *parm; @@ -15,10 +46,53 @@ struct syscall_arg { u8 mask; }; +unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx); + +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_STRARRAYS syscall_arg__scnprintf_strarrays + +size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FD syscall_arg__scnprintf_fd + +size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_HEX syscall_arg__scnprintf_hex + +size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_INT syscall_arg__scnprintf_int + +size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_LONG syscall_arg__scnprintf_long + +size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_PID syscall_arg__scnprintf_pid + +size_t syscall_arg__scnprintf_clone_flags(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_CLONE_FLAGS syscall_arg__scnprintf_clone_flags + +size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FCNTL_CMD syscall_arg__scnprintf_fcntl_cmd + +size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FCNTL_ARG syscall_arg__scnprintf_fcntl_arg + +size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_IOCTL_CMD syscall_arg__scnprintf_ioctl_cmd + +size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_PKEY_ALLOC_ACCESS_RIGHTS syscall_arg__scnprintf_pkey_alloc_access_rights + +size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags + size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_MASK syscall_arg__scnprintf_statx_mask +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size); + +void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, + size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg)); + #endif /* _PERF_TRACE_BEAUTY_H */ diff --git a/tools/perf/trace/beauty/clone.c b/tools/perf/trace/beauty/clone.c new file mode 100644 index 0000000000000000000000000000000000000000..d64d049ab9915162e220f91c3f59997d8abddc15 --- /dev/null +++ b/tools/perf/trace/beauty/clone.c @@ -0,0 +1,75 @@ +/* + * trace/beauty/cone.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include +#include +#include + +static size_t clone__scnprintf_flags(unsigned long flags, char *bf, size_t size) +{ + int printed = 0; + +#define P_FLAG(n) \ + if (flags & CLONE_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~CLONE_##n; \ + } + + P_FLAG(VM); + P_FLAG(FS); + P_FLAG(FILES); + P_FLAG(SIGHAND); + P_FLAG(PTRACE); + P_FLAG(VFORK); + P_FLAG(PARENT); + P_FLAG(THREAD); + P_FLAG(NEWNS); + P_FLAG(SYSVSEM); + P_FLAG(SETTLS); + P_FLAG(PARENT_SETTID); + P_FLAG(CHILD_CLEARTID); + P_FLAG(DETACHED); + P_FLAG(UNTRACED); + P_FLAG(CHILD_SETTID); + P_FLAG(NEWCGROUP); + P_FLAG(NEWUTS); + P_FLAG(NEWIPC); + P_FLAG(NEWUSER); + P_FLAG(NEWPID); + P_FLAG(NEWNET); + P_FLAG(IO); +#undef P_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags); + + return printed; +} + +size_t syscall_arg__scnprintf_clone_flags(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long flags = arg->val; + enum syscall_clone_args { + SCC_FLAGS = (1 << 0), + SCC_CHILD_STACK = (1 << 1), + SCC_PARENT_TIDPTR = (1 << 2), + SCC_CHILD_TIDPTR = (1 << 3), + SCC_TLS = (1 << 4), + }; + if (!(flags & CLONE_PARENT_SETTID)) + arg->mask |= SCC_PARENT_TIDPTR; + + if (!(flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))) + arg->mask |= SCC_CHILD_TIDPTR; + + if (!(flags & CLONE_SETTLS)) + arg->mask |= SCC_TLS; + + return clone__scnprintf_flags(flags, bf, size); +} diff --git a/tools/perf/trace/beauty/drm_ioctl.sh b/tools/perf/trace/beauty/drm_ioctl.sh new file mode 100755 index 0000000000000000000000000000000000000000..2149d3a98e425607c5d95888cc65a291a5c95c17 --- /dev/null +++ b/tools/perf/trace/beauty/drm_ioctl.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +drm_header_dir=$1 +printf "#ifndef DRM_COMMAND_BASE\n" +grep "#define DRM_COMMAND_BASE" $drm_header_dir/drm.h +printf "#endif\n" + +printf "static const char *drm_ioctl_cmds[] = {\n" +grep "^#define DRM_IOCTL.*DRM_IO" $drm_header_dir/drm.h | \ + sed -r 's/^#define +DRM_IOCTL_([A-Z0-9_]+)[ ]+DRM_IO[A-Z]* *\( *(0x[[:xdigit:]]+),*.*/ [\2] = "\1",/g' +grep "^#define DRM_I915_[A-Z_0-9]\+[ ]\+0x" $drm_header_dir/i915_drm.h | \ + sed -r 's/^#define +DRM_I915_([A-Z0-9_]+)[ ]+(0x[[:xdigit:]]+)/\t[DRM_COMMAND_BASE + \2] = "I915_\1",/g' +printf "};\n" diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c new file mode 100644 index 0000000000000000000000000000000000000000..9e8900c13cb1380a38e016430e572191a534b831 --- /dev/null +++ b/tools/perf/trace/beauty/fcntl.c @@ -0,0 +1,100 @@ +/* + * trace/beauty/fcntl.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include +#include + +static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size) +{ + return scnprintf(bf, size, "%s", val ? "CLOEXEC" : "0"); +} + +static size_t syscall_arg__scnprintf_fcntl_getfd(char *bf, size_t size, struct syscall_arg *arg) +{ + return fcntl__scnprintf_getfd(arg->val, bf, size); +} + +static size_t fcntl__scnprintf_getlease(unsigned long val, char *bf, size_t size) +{ + static const char *fcntl_setlease[] = { "RDLCK", "WRLCK", "UNLCK", }; + static DEFINE_STRARRAY(fcntl_setlease); + + return strarray__scnprintf(&strarray__fcntl_setlease, bf, size, "%x", val); +} + +static size_t syscall_arg__scnprintf_fcntl_getlease(char *bf, size_t size, struct syscall_arg *arg) +{ + return fcntl__scnprintf_getlease(arg->val, bf, size); +} + +size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg) +{ + if (arg->val == F_GETFL) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_open_flags); + goto mask_arg; + } + if (arg->val == F_GETFD) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fcntl_getfd); + goto mask_arg; + } + if (arg->val == F_DUPFD_CLOEXEC || arg->val == F_DUPFD) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fd); + goto out; + } + if (arg->val == F_GETOWN) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_pid); + goto mask_arg; + } + if (arg->val == F_GETLEASE) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fcntl_getlease); + goto mask_arg; + } + /* + * Some commands ignore the third fcntl argument, "arg", so mask it + */ + if (arg->val == F_GET_SEALS || + arg->val == F_GETSIG) { +mask_arg: + arg->mask |= (1 << 2); + } +out: + return syscall_arg__scnprintf_strarrays(bf, size, arg); +} + +size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg) +{ + int cmd = syscall_arg__val(arg, 1); + + if (cmd == F_DUPFD) + return syscall_arg__scnprintf_fd(bf, size, arg); + + if (cmd == F_SETFD) + return fcntl__scnprintf_getfd(arg->val, bf, size); + + if (cmd == F_SETFL) + return open__scnprintf_flags(arg->val, bf, size); + + if (cmd == F_SETOWN) + return syscall_arg__scnprintf_pid(bf, size, arg); + + if (cmd == F_SETLEASE) + return fcntl__scnprintf_getlease(arg->val, bf, size); + /* + * We still don't grab the contents of pointers on entry or exit, + * so just print them as hex numbers + */ + if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK || + cmd == F_OFD_SETLK || cmd == F_OFD_SETLKW || cmd == F_OFD_GETLK || + cmd == F_GETOWN_EX || cmd == F_SETOWN_EX || + cmd == F_GET_RW_HINT || cmd == F_SET_RW_HINT || + cmd == F_GET_FILE_RW_HINT || cmd == F_SET_FILE_RW_HINT) + return syscall_arg__scnprintf_hex(bf, size, arg); + + return syscall_arg__scnprintf_long(bf, size, arg); +} diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c new file mode 100644 index 0000000000000000000000000000000000000000..1be3b4cf082708194ca7c4c8403219eedb924c3d --- /dev/null +++ b/tools/perf/trace/beauty/ioctl.c @@ -0,0 +1,162 @@ +/* + * trace/beauty/ioctl.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include + +/* + * FIXME: to support all arches we have to improve this, for + * now, to build on older systems without things like TIOCGEXCL, + * get it directly from our copy. + * + * Right now only x86 is being supported for beautifying ioctl args + * in 'perf trace', see tools/perf/trace/beauty/Build and builtin-trace.c + */ +#include + +static size_t ioctl__scnprintf_tty_cmd(int nr, int dir, char *bf, size_t size) +{ + static const char *ioctl_tty_cmd[] = { + "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", + "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL", "TIOCSCTTY", + "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI", "TIOCGWINSZ", "TIOCSWINSZ", + "TIOCMGET", "TIOCMBIS", "TIOCMBIC", "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", + "FIONREAD", "TIOCLINUX", "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", + "FIONBIO", "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", + [_IOC_NR(TIOCSBRK)] = "TIOCSBRK", "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", + "TCSETSW2", "TCSETSF2", "TIOCGRS48", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK", + "TIOCGDEV", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG", "TIOCVHANGUP", "TIOCGPKT", + "TIOCGPTLCK", [_IOC_NR(TIOCGEXCL)] = "TIOCGEXCL", "TIOCGPTPEER", + [_IOC_NR(FIONCLEX)] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG", + "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", + "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI", + "TIOCMIWAIT", "TIOCGICOUNT", }; + static DEFINE_STRARRAY(ioctl_tty_cmd); + + if (nr < strarray__ioctl_tty_cmd.nr_entries && strarray__ioctl_tty_cmd.entries[nr] != NULL) + return scnprintf(bf, size, "%s", strarray__ioctl_tty_cmd.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'T', nr, dir); +} + +static size_t ioctl__scnprintf_drm_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/drm_ioctl_array.c" + static DEFINE_STRARRAY(drm_ioctl_cmds); + + if (nr < strarray__drm_ioctl_cmds.nr_entries && strarray__drm_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "DRM_%s", strarray__drm_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'd', nr, dir); +} + +static size_t ioctl__scnprintf_sndrv_pcm_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/sndrv_pcm_ioctl_array.c" + static DEFINE_STRARRAY(sndrv_pcm_ioctl_cmds); + + if (nr < strarray__sndrv_pcm_ioctl_cmds.nr_entries && strarray__sndrv_pcm_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "SNDRV_PCM_%s", strarray__sndrv_pcm_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'A', nr, dir); +} + +static size_t ioctl__scnprintf_sndrv_ctl_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/sndrv_ctl_ioctl_array.c" + static DEFINE_STRARRAY(sndrv_ctl_ioctl_cmds); + + if (nr < strarray__sndrv_ctl_ioctl_cmds.nr_entries && strarray__sndrv_ctl_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "SNDRV_CTL_%s", strarray__sndrv_ctl_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'U', nr, dir); +} + +static size_t ioctl__scnprintf_kvm_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/kvm_ioctl_array.c" + static DEFINE_STRARRAY(kvm_ioctl_cmds); + + if (nr < strarray__kvm_ioctl_cmds.nr_entries && strarray__kvm_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "KVM_%s", strarray__kvm_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); +} + +static size_t ioctl__scnprintf_vhost_virtio_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/vhost_virtio_ioctl_array.c" + static DEFINE_STRARRAY(vhost_virtio_ioctl_cmds); + static DEFINE_STRARRAY(vhost_virtio_ioctl_read_cmds); + struct strarray *s = (dir & _IOC_READ) ? &strarray__vhost_virtio_ioctl_read_cmds : &strarray__vhost_virtio_ioctl_cmds; + + if (nr < s->nr_entries && s->entries[nr] != NULL) + return scnprintf(bf, size, "VHOST_%s", s->entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAF, nr, dir); +} + +static size_t ioctl__scnprintf_perf_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/perf_ioctl_array.c" + static DEFINE_STRARRAY(perf_ioctl_cmds); + + if (nr < strarray__perf_ioctl_cmds.nr_entries && strarray__perf_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "PERF_%s", strarray__perf_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); +} + +static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size) +{ + int dir = _IOC_DIR(cmd), + type = _IOC_TYPE(cmd), + nr = _IOC_NR(cmd), + sz = _IOC_SIZE(cmd); + int printed = 0; + static const struct ioctl_type { + int type; + size_t (*scnprintf)(int nr, int dir, char *bf, size_t size); + } ioctl_types[] = { /* Must be ordered by type */ + { .type = '$', .scnprintf = ioctl__scnprintf_perf_cmd, }, + ['A' - '$'] = { .type = 'A', .scnprintf = ioctl__scnprintf_sndrv_pcm_cmd, }, + ['T' - '$'] = { .type = 'T', .scnprintf = ioctl__scnprintf_tty_cmd, }, + ['U' - '$'] = { .type = 'U', .scnprintf = ioctl__scnprintf_sndrv_ctl_cmd, }, + ['d' - '$'] = { .type = 'd', .scnprintf = ioctl__scnprintf_drm_cmd, }, + [0xAE - '$'] = { .type = 0xAE, .scnprintf = ioctl__scnprintf_kvm_cmd, }, + [0xAF - '$'] = { .type = 0xAF, .scnprintf = ioctl__scnprintf_vhost_virtio_cmd, }, + }; + const int nr_types = ARRAY_SIZE(ioctl_types); + + if (type >= ioctl_types[0].type && type <= ioctl_types[nr_types - 1].type) { + const int index = type - ioctl_types[0].type; + + if (ioctl_types[index].scnprintf != NULL) + return ioctl_types[index].scnprintf(nr, dir, bf, size); + } + + printed += scnprintf(bf + printed, size - printed, "%c", '('); + + if (dir == _IOC_NONE) { + printed += scnprintf(bf + printed, size - printed, "%s", "NONE"); + } else { + if (dir & _IOC_READ) + printed += scnprintf(bf + printed, size - printed, "%s", "READ"); + if (dir & _IOC_WRITE) + printed += scnprintf(bf + printed, size - printed, "%s%s", dir & _IOC_READ ? "|" : "", "WRITE"); + } + + return printed + scnprintf(bf + printed, size - printed, ", %#x, %#x, %#x)", type, nr, sz); +} + +size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long cmd = arg->val; + + return ioctl__scnprintf_cmd(cmd, bf, size); +} diff --git a/tools/perf/trace/beauty/kvm_ioctl.sh b/tools/perf/trace/beauty/kvm_ioctl.sh new file mode 100755 index 0000000000000000000000000000000000000000..bd28817afced04c6ebae4e47a6ced11dbc6e635a --- /dev/null +++ b/tools/perf/trace/beauty/kvm_ioctl.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +kvm_header_dir=$1 + +printf "static const char *kvm_ioctl_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+KVM_(\w+)[[:space:]]+_IO[RW]*\([[:space:]]*KVMIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' +egrep $regex ${kvm_header_dir}/kvm.h | \ + sed -r "s/$regex/\2 \1/g" | \ + egrep -v " ((ARM|PPC|S390)_|[GS]ET_(DEBUGREGS|PIT2|XSAVE|TSC_KHZ)|CREATE_SPAPR_TCE_64)" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index af1cfde6b97b12962045d9bc66126c217335ad21..754558f9009db2743e4d1211d25c0cb45f36ceae 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -34,6 +34,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, { int printed = 0, flags = arg->val; + if (flags & MAP_ANONYMOUS) + arg->mask |= (1 << 4) | (1 << 5); /* Mask 4th ('fd') and 5th ('offset') args, ignored */ + #define P_MMAP_FLAG(n) \ if (flags & MAP_##n) { \ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index f55a4597fc3831d9898cd2ac99919ce9e57be840..e359e041dc0e775fb92f032a9873b9953a075923 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -14,13 +14,16 @@ #define O_NOATIME 01000000 #endif -static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, - struct syscall_arg *arg) -{ - int printed = 0, flags = arg->val; +#ifndef O_TMPFILE +#define O_TMPFILE 020000000 +#endif - if (!(flags & O_CREAT)) - arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ +#undef O_LARGEFILE +#define O_LARGEFILE 00100000 + +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) +{ + int printed = 0; if (flags == 0) return scnprintf(bf, size, "RDONLY"); @@ -30,6 +33,7 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, flags &= ~O_##n; \ } + P_FLAG(RDWR); P_FLAG(APPEND); P_FLAG(ASYNC); P_FLAG(CLOEXEC); @@ -38,6 +42,8 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, P_FLAG(DIRECTORY); P_FLAG(EXCL); P_FLAG(LARGEFILE); + P_FLAG(NOFOLLOW); + P_FLAG(TMPFILE); P_FLAG(NOATIME); P_FLAG(NOCTTY); #ifdef O_NONBLOCK @@ -48,7 +54,6 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, #ifdef O_PATH P_FLAG(PATH); #endif - P_FLAG(RDWR); #ifdef O_DSYNC if ((flags & O_SYNC) == O_SYNC) printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC"); @@ -68,4 +73,12 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, return printed; } -#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags +size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) +{ + int flags = arg->val; + + if (!(flags & O_CREAT)) + arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ + + return open__scnprintf_flags(flags, bf, size); +} diff --git a/tools/perf/trace/beauty/perf_ioctl.sh b/tools/perf/trace/beauty/perf_ioctl.sh new file mode 100755 index 0000000000000000000000000000000000000000..faea4237c793d63ba3f518c2b179e0fded5295fb --- /dev/null +++ b/tools/perf/trace/beauty/perf_ioctl.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +header_dir=$1 + +printf "static const char *perf_ioctl_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+PERF_EVENT_IOC_(\w+)[[:space:]]+_IO[RW]*[[:space:]]*\([[:space:]]*.\$.[[:space:]]*,[[:space:]]*([[:digit:]]+).*' +egrep $regex ${header_dir}/perf_event.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/pid.c b/tools/perf/trace/beauty/pid.c index 07486ea65ae3c01ec30042a0b8c381dc64e9047c..b6d419e16dcf072cca23ed13d0f19c33d08f25ae 100644 --- a/tools/perf/trace/beauty/pid.c +++ b/tools/perf/trace/beauty/pid.c @@ -1,4 +1,4 @@ -static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg) +size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg) { int pid = arg->val; struct trace *trace = arg->trace; @@ -17,5 +17,3 @@ static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_a return printed; } - -#define SCA_PID syscall_arg__scnprintf_pid diff --git a/tools/perf/trace/beauty/pkey_alloc.c b/tools/perf/trace/beauty/pkey_alloc.c new file mode 100644 index 0000000000000000000000000000000000000000..2ba784a3734adb2fd7088016970c627a508511f8 --- /dev/null +++ b/tools/perf/trace/beauty/pkey_alloc.c @@ -0,0 +1,50 @@ +/* + * trace/beauty/pkey_alloc.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include +#include + +static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size) +{ + int i, printed = 0; + +#include "trace/beauty/generated/pkey_alloc_access_rights_array.c" + static DEFINE_STRARRAY(pkey_alloc_access_rights); + + if (access_rights == 0) { + const char *s = strarray__pkey_alloc_access_rights.entries[0]; + if (s) + return scnprintf(bf, size, "%s", s); + return scnprintf(bf, size, "%d", 0); + } + + for (i = 1; i < strarray__pkey_alloc_access_rights.nr_entries; ++i) { + int bit = 1 << (i - 1); + + if (!(access_rights & bit)) + continue; + + if (printed != 0) + printed += scnprintf(bf + printed, size - printed, "|"); + + if (strarray__pkey_alloc_access_rights.entries[i] != NULL) + printed += scnprintf(bf + printed, size - printed, "%s", strarray__pkey_alloc_access_rights.entries[i]); + else + printed += scnprintf(bf + printed, size - printed, "0x%#", bit); + } + + return printed; +} + +size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long cmd = arg->val; + + return pkey_alloc__scnprintf_access_rights(cmd, bf, size); +} diff --git a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh new file mode 100755 index 0000000000000000000000000000000000000000..62e51a02b8398b4c62a0180308646892001e7e63 --- /dev/null +++ b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +header_dir=$1 + +printf "static const char *pkey_alloc_access_rights[] = {\n" +regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+PKEY_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*' +egrep $regex ${header_dir}/mman-common.h | \ + sed -r "s/$regex/\2 \2 \1/g" | \ + sort | xargs printf "\t[%s ? (ilog2(%s) + 1) : 0] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh new file mode 100755 index 0000000000000000000000000000000000000000..aad5ab130539987db15336b233d50a3d03ef4082 --- /dev/null +++ b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +sound_header_dir=$1 + +printf "static const char *sndrv_ctl_ioctl_cmds[] = {\n" +grep "^#define[\t ]\+SNDRV_CTL_IOCTL_" $sound_header_dir/asound.h | \ + sed -r 's/^#define +SNDRV_CTL_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.U., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' +printf "};\n" diff --git a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh new file mode 100755 index 0000000000000000000000000000000000000000..b7e9ef6b2f558feae0c1ec1fb6fe94055c4bf903 --- /dev/null +++ b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +sound_header_dir=$1 + +printf "static const char *sndrv_pcm_ioctl_cmds[] = {\n" +grep "^#define[\t ]\+SNDRV_PCM_IOCTL_" $sound_header_dir/asound.h | \ + sed -r 's/^#define +SNDRV_PCM_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.A., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' +printf "};\n" diff --git a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh new file mode 100755 index 0000000000000000000000000000000000000000..76f1de6977870acf19cd533e518733e15d0c535f --- /dev/null +++ b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +vhost_virtio_header_dir=$1 + +printf "static const char *vhost_virtio_ioctl_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' +egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" + +printf "static const char *vhost_virtio_ioctl_read_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?R\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' +egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 83874b0e266c5ca57c73e85b4ba4b229f77b446d..d0c2007c307bbaf266a8a84d7f054c1d41994c72 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "browser.h" @@ -563,7 +564,7 @@ static int ui_browser__color_config(const char *var, const char *value, int i; /* same dir for all commands */ - if (prefixcmp(var, "colors.") != 0) + if (!strstarts(var, "colors.") != 0) return 0; for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { @@ -738,6 +739,35 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, + unsigned int row, bool arrow_down) +{ + unsigned int end_row; + + if (row >= browser->top_idx) + end_row = row - browser->top_idx; + else + return; + + SLsmg_set_char_set(1); + + if (arrow_down) { + ui_browser__gotorc(browser, end_row, column - 1); + SLsmg_write_char(SLSMG_ULCORN_CHAR); + ui_browser__gotorc(browser, end_row, column); + SLsmg_draw_hline(2); + ui_browser__gotorc(browser, end_row + 1, column - 1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + } else { + ui_browser__gotorc(browser, end_row, column - 1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + ui_browser__gotorc(browser, end_row, column); + SLsmg_draw_hline(2); + } + + SLsmg_set_char_set(0); +} + void ui_browser__init(void) { int i = 0; diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index be3b70eb5fca6e402830570c4111f10258702c04..a12eff75638b39b0f443c48d1cfab903df1c5839 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -43,6 +43,8 @@ void ui_browser__printf(struct ui_browser *browser, const char *fmt, ...); void ui_browser__write_graph(struct ui_browser *browser, int graph); void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, u64 start, u64 end); +void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, + unsigned int row, bool arrow_down); void __ui_browser__show_title(struct ui_browser *browser, const char *title); void ui_browser__show_title(struct ui_browser *browser, const char *title); int ui_browser__show(struct ui_browser *browser, const char *title, diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 27f41f28dcb49a10a1bcb2319f012d9953e552f2..786fecaf578ef706ecc347279a84ccb3389780b4 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -9,14 +9,16 @@ #include "../../util/symbol.h" #include "../../util/evsel.h" #include "../../util/config.h" +#include "../../util/evlist.h" #include #include #include +#include #include struct disasm_line_samples { - double percent; - u64 nr; + double percent; + struct sym_hist_entry he; }; #define IPC_WIDTH 6 @@ -40,6 +42,7 @@ static struct annotate_browser_opt { jump_arrows, show_linenr, show_nr_jumps, + show_nr_samples, show_total_period; } annotate_browser__opts = { .use_offset = true, @@ -108,11 +111,12 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br static int annotate_browser__pcnt_width(struct annotate_browser *ab) { - int w = 7 * ab->nr_events; + return (annotate_browser__opts.show_total_period ? 12 : 7) * ab->nr_events; +} - if (ab->have_cycles) - w += IPC_WIDTH + CYCLES_WIDTH; - return w; +static int annotate_browser__cycles_width(struct annotate_browser *ab) +{ + return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0; } static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) @@ -125,7 +129,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int (!current_entry || (browser->use_navkeypressed && !browser->navkeypressed))); int width = browser->width, printed; - int i, pcnt_width = annotate_browser__pcnt_width(ab); + int i, pcnt_width = annotate_browser__pcnt_width(ab), + cycles_width = annotate_browser__cycles_width(ab); double percent_max = 0.0; char bf[256]; bool show_title = false; @@ -149,8 +154,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int bdl->samples[i].percent, current_entry); if (annotate_browser__opts.show_total_period) { + ui_browser__printf(browser, "%11" PRIu64 " ", + bdl->samples[i].he.period); + } else if (annotate_browser__opts.show_nr_samples) { ui_browser__printf(browser, "%6" PRIu64 " ", - bdl->samples[i].nr); + bdl->samples[i].he.nr_samples); } else { ui_browser__printf(browser, "%6.2f ", bdl->samples[i].percent); @@ -160,9 +168,12 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ui_browser__set_percent_color(browser, 0, current_entry); if (!show_title) - ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); - else - ui_browser__printf(browser, "%*s", 7, "Percent"); + ui_browser__write_nstring(browser, " ", pcnt_width); + else { + ui_browser__printf(browser, "%*s", pcnt_width, + annotate_browser__opts.show_total_period ? "Period" : + annotate_browser__opts.show_nr_samples ? "Samples" : "Percent"); + } } if (ab->have_cycles) { if (dl->ipc) @@ -188,7 +199,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int width += 1; if (!*dl->line) - ui_browser__write_nstring(browser, " ", width - pcnt_width); + ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); else if (dl->offset == -1) { if (dl->line_nr && annotate_browser__opts.show_linenr) printed = scnprintf(bf, sizeof(bf), "%-*d ", @@ -197,7 +208,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int printed = scnprintf(bf, sizeof(bf), "%*s ", ab->addr_width, " "); ui_browser__write_nstring(browser, bf, printed); - ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width + 1); + ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1); } else { u64 addr = dl->offset; int color = -1; @@ -254,7 +265,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int } disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); - ui_browser__write_nstring(browser, bf, width - pcnt_width - 3 - printed); + ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); } if (current_entry) @@ -272,6 +283,25 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy return true; } +static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) +{ + struct disasm_line *pos = list_prev_entry(cursor, node); + const char *name; + + if (!pos) + return false; + + if (ins__is_lock(&pos->ins)) + name = pos->ops.locked.ins.name; + else + name = pos->ins.name; + + if (!name || !cursor->ins.name) + return false; + + return ins__is_fused(ab->arch, name, cursor->ins.name); +} + static void annotate_browser__draw_current_jump(struct ui_browser *browser) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); @@ -307,6 +337,13 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width, from, to); + + if (is_fused(ab, cursor)) { + ui_browser__mark_fused(browser, + pcnt_width + 3 + ab->addr_width, + from - 1, + to > from ? true : false); + } } static unsigned int annotate_browser__refresh(struct ui_browser *browser) @@ -422,14 +459,14 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, next = disasm__get_next_ip_line(¬es->src->source, pos); for (i = 0; i < browser->nr_events; i++) { - u64 nr_samples; + struct sym_hist_entry sample; bpos->samples[i].percent = disasm__calc_percent(notes, evsel->idx + i, pos->offset, next ? next->offset : len, - &path, &nr_samples); - bpos->samples[i].nr = nr_samples; + &path, &sample); + bpos->samples[i].he = sample; if (max_percent < bpos->samples[i].percent) max_percent = bpos->samples[i].percent; @@ -792,13 +829,14 @@ static int annotate_browser__run(struct annotate_browser *browser, "q/ESC/CTRL+C Exit\n\n" "ENTER Go to target\n" "ESC Exit\n" - "H Cycle thru hottest instructions\n" + "H Go to hottest instruction\n" + "TAB/shift+TAB Cycle thru hottest instructions\n" "j Toggle showing jump to target arrows\n" "J Toggle showing number of jump sources on targets\n" "n Search next string\n" "o Toggle disassembler output/simplified view\n" "s Toggle source code view\n" - "t Toggle total period view\n" + "t Circulate percent, total period, samples view\n" "/ Search string\n" "k Toggle line numbers\n" "r Run available scripts\n" @@ -875,8 +913,13 @@ static int annotate_browser__run(struct annotate_browser *browser, } continue; case 't': - annotate_browser__opts.show_total_period = - !annotate_browser__opts.show_total_period; + if (annotate_browser__opts.show_total_period) { + annotate_browser__opts.show_total_period = false; + annotate_browser__opts.show_nr_samples = true; + } else if (annotate_browser__opts.show_nr_samples) + annotate_browser__opts.show_nr_samples = false; + else + annotate_browser__opts.show_total_period = true; annotate_browser__update_addr_width(browser); continue; case K_LEFT: @@ -899,9 +942,11 @@ static int annotate_browser__run(struct annotate_browser *browser, int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { - /* Set default value for show_total_period. */ + /* Set default value for show_total_period and show_nr_samples */ annotate_browser__opts.show_total_period = - symbol_conf.show_total_period; + symbol_conf.show_total_period; + annotate_browser__opts.show_nr_samples = + symbol_conf.show_nr_samples; return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt); } @@ -1074,7 +1119,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, } err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - sizeof_bdl, &browser.arch); + sizeof_bdl, &browser.arch, + perf_evsel__env_cpuid(evsel)); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); @@ -1151,6 +1197,7 @@ static struct annotate_config { ANNOTATE_CFG(jump_arrows), ANNOTATE_CFG(show_linenr), ANNOTATE_CFG(show_nr_jumps), + ANNOTATE_CFG(show_nr_samples), ANNOTATE_CFG(show_total_period), ANNOTATE_CFG(use_offset), }; @@ -1170,7 +1217,7 @@ static int annotate__config(const char *var, const char *value, struct annotate_config *cfg; const char *name; - if (prefixcmp(var, "annotate.") != 0) + if (!strstarts(var, "annotate.")) return 0; name = var + 9; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 69f4570bd4f941bee8a67fc48741994ce41a127e..13dfb0a0bdeb440776b506fd413be307e716e0bf 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -166,9 +166,6 @@ static struct inline_node *inline_node__create(struct map *map, u64 ip) if (dso == NULL) return NULL; - if (dso->kernel != DSO_TYPE_USER) - return NULL; - node = dso__parse_addr_inlines(dso, map__rip_2objdump(map, ip)); @@ -934,12 +931,8 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, browser->show_dso); if (symbol_conf.show_branchflag_count) { - if (need_percent) - callchain_list_counts__printf_value(node, chain, NULL, - buf, sizeof(buf)); - else - callchain_list_counts__printf_value(NULL, chain, NULL, - buf, sizeof(buf)); + callchain_list_counts__printf_value(chain, NULL, + buf, sizeof(buf)); if (asprintf(&alloc_str2, "%s%s", str, buf) < 0) str = "Not enough memory!"; diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index d903fd493416bf557c23e9d5d4f59d5fcd83efcc..02176193f427a3b466925884930b1b0cc257ec98 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -34,10 +34,10 @@ static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym, return 0; symhist = annotation__histogram(symbol__annotation(sym), evidx); - if (!symbol_conf.event_group && !symhist->addr[dl->offset]) + if (!symbol_conf.event_group && !symhist->addr[dl->offset].nr_samples) return 0; - percent = 100.0 * symhist->addr[dl->offset] / symhist->sum; + percent = 100.0 * symhist->addr[dl->offset].nr_samples / symhist->nr_samples; markup = perf_gtk__get_percent_color(percent); if (markup) @@ -169,7 +169,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, return -1; err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - 0, NULL); + 0, NULL, NULL); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c index a0f24c7115c59f891fa894739ef4da157a9e33cf..ae91c8148edf34234e128336bd1a4cfa72938c42 100644 --- a/tools/perf/ui/progress.c +++ b/tools/perf/ui/progress.c @@ -1,3 +1,4 @@ +#include #include "../cache.h" #include "progress.h" @@ -14,10 +15,14 @@ struct ui_progress_ops *ui_progress__ops = &null_progress__ops; void ui_progress__update(struct ui_progress *p, u64 adv) { + u64 last = p->curr; + p->curr += adv; if (p->curr >= p->next) { - p->next += p->step; + u64 nr = DIV_ROUND_UP(p->curr - last, p->step); + + p->next += nr * p->step; ui_progress__ops->update(p); } } @@ -25,7 +30,7 @@ void ui_progress__update(struct ui_progress *p, u64 adv) void ui_progress__init(struct ui_progress *p, u64 total, const char *title) { p->curr = 0; - p->next = p->step = total / 16; + p->next = p->step = total / 16 ?: 1; p->total = total; p->title = title; diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 42e432bd2eb4b59a1f15f6af69c788c66a62f1af..8bdb7a50018128feb120064bdf76e93572696372 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -1,4 +1,5 @@ #include +#include #include "../../util/util.h" #include "../../util/hist.h" @@ -35,9 +36,6 @@ static size_t inline__fprintf(struct map *map, u64 ip, int left_margin, if (dso == NULL) return 0; - if (dso->kernel != DSO_TYPE_USER) - return 0; - node = dso__parse_addr_inlines(dso, map__rip_2objdump(map, ip)); if (node == NULL) @@ -126,12 +124,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node, str = callchain_list__sym_name(chain, bf, sizeof(bf), false); if (symbol_conf.show_branchflag_count) { - if (!period) - callchain_list_counts__printf_value(node, chain, NULL, - buf, sizeof(buf)); - else - callchain_list_counts__printf_value(NULL, chain, NULL, - buf, sizeof(buf)); + callchain_list_counts__printf_value(chain, NULL, + buf, sizeof(buf)); if (asprintf(&alloc_str, "%s%s", str, buf) < 0) str = "Not enough memory!"; @@ -295,7 +289,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, * displayed twice. */ if (!i++ && field_order == NULL && - sort_order && !prefixcmp(sort_order, "sym")) + sort_order && strstarts(sort_order, "sym")) continue; if (!printed) { @@ -315,7 +309,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, if (symbol_conf.show_branchflag_count) ret += callchain_list_counts__printf_value( - NULL, chain, fp, NULL, 0); + chain, fp, NULL, 0); ret += fprintf(fp, "\n"); if (++entries_printed == callchain_param.print_limit) diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 79dea95a7f688ca9fa9b16346b3fae25af797f5c..94518c1bf8b6c37896c8f90430c4056012f6b29e 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -22,6 +22,7 @@ libperf-y += rbtree.o libperf-y += libstring.o libperf-y += bitmap.o libperf-y += hweight.o +libperf-y += smt.o libperf-y += quote.o libperf-y += strbuf.o libperf-y += string.o @@ -93,6 +94,7 @@ libperf-y += drv_configs.o libperf-y += units.o libperf-y += time-utils.o libperf-y += expr-bison.o +libperf-y += branch.o libperf-$(CONFIG_LIBBPF) += bpf-loader.o libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o @@ -104,6 +106,10 @@ ifndef CONFIG_LIBELF libperf-y += symbol-minimal.o endif +ifndef CONFIG_SETNS +libperf-y += setns.o +endif + libperf-$(CONFIG_DWARF) += probe-finder.o libperf-$(CONFIG_DWARF) += dwarf-aux.o libperf-$(CONFIG_DWARF) += dwarf-regs.o diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index be1caabb92906befc755d1b99e22cb6a0439dc34..4397a8b6e6cd902ac082e0539614ea2c5dd1374a 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -47,7 +47,12 @@ struct arch { bool sorted_instructions; bool initialized; void *priv; + unsigned int model; + unsigned int family; int (*init)(struct arch *arch); + bool (*ins_is_fused)(struct arch *arch, const char *ins1, + const char *ins2); + int (*cpuid_parse)(struct arch *arch, char *cpuid); struct { char comment_char; char skip_functions_char; @@ -129,6 +134,8 @@ static struct arch architectures[] = { .name = "x86", .instructions = x86__instructions, .nr_instructions = ARRAY_SIZE(x86__instructions), + .ins_is_fused = x86__ins_is_fused, + .cpuid_parse = x86__cpuid_parse, .objdump = { .comment_char = '#', }, @@ -171,6 +178,14 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, return ins__raw_scnprintf(ins, bf, size, ops); } +bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) +{ + if (!arch || !arch->ins_is_fused) + return false; + + return arch->ins_is_fused(arch, ins1, ins2); +} + static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) { char *endptr, *tok, *name; @@ -502,6 +517,11 @@ bool ins__is_ret(const struct ins *ins) return ins->ops == &ret_ops; } +bool ins__is_lock(const struct ins *ins) +{ + return ins->ops == &lock_ops; +} + static int ins__key_cmp(const void *name, const void *insp) { const struct ins *ins = insp; @@ -590,10 +610,10 @@ int symbol__alloc_hist(struct symbol *sym) size_t sizeof_sym_hist; /* Check for overflow when calculating sizeof_sym_hist */ - if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64)) + if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) return -1; - sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); + sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry)); /* Check for overflow in zalloc argument */ if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) @@ -677,7 +697,8 @@ static int __symbol__account_cycles(struct annotation *notes, } static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, - struct annotation *notes, int evidx, u64 addr) + struct annotation *notes, int evidx, u64 addr, + struct perf_sample *sample) { unsigned offset; struct sym_hist *h; @@ -693,12 +714,15 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, offset = addr - sym->start; h = annotation__histogram(notes, evidx); - h->sum++; - h->addr[offset]++; + h->nr_samples++; + h->addr[offset].nr_samples++; + h->period += sample->period; + h->addr[offset].period += sample->period; pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 - ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, - addr, addr - sym->start, evidx, h->addr[offset]); + ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", + sym->start, sym->name, addr, addr - sym->start, evidx, + h->addr[offset].nr_samples, h->addr[offset].period); return 0; } @@ -718,7 +742,8 @@ static struct annotation *symbol__get_annotation(struct symbol *sym, bool cycles } static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, - int evidx, u64 addr) + int evidx, u64 addr, + struct perf_sample *sample) { struct annotation *notes; @@ -727,7 +752,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, notes = symbol__get_annotation(sym, false); if (notes == NULL) return -ENOMEM; - return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); + return __symbol__inc_addr_samples(sym, map, notes, evidx, addr, sample); } static int symbol__account_cycles(u64 addr, u64 start, @@ -791,14 +816,16 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, return err; } -int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) +int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, + int evidx) { - return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); + return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr, sample); } -int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) +int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, + int evidx, u64 ip) { - return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); + return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); } static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) @@ -908,11 +935,12 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa } double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, - s64 end, const char **path, u64 *nr_samples) + s64 end, const char **path, struct sym_hist_entry *sample) { struct source_line *src_line = notes->src->lines; double percent = 0.0; - *nr_samples = 0; + + sample->nr_samples = sample->period = 0; if (src_line) { size_t sizeof_src_line = sizeof(*src_line) + @@ -926,19 +954,24 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, *path = src_line->path; percent += src_line->samples[evidx].percent; - *nr_samples += src_line->samples[evidx].nr; + sample->nr_samples += src_line->samples[evidx].nr; offset++; } } else { struct sym_hist *h = annotation__histogram(notes, evidx); unsigned int hits = 0; + u64 period = 0; - while (offset < end) - hits += h->addr[offset++]; + while (offset < end) { + hits += h->addr[offset].nr_samples; + period += h->addr[offset].period; + ++offset; + } - if (h->sum) { - *nr_samples = hits; - percent = 100.0 * hits / h->sum; + if (h->nr_samples) { + sample->period = period; + sample->nr_samples = hits; + percent = 100.0 * hits / h->nr_samples; } } @@ -1037,10 +1070,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (dl->offset != -1) { const char *path = NULL; - u64 nr_samples; double percent, max_percent = 0.0; double *ppercents = &percent; - u64 *psamples = &nr_samples; + struct sym_hist_entry sample; + struct sym_hist_entry *psamples = &sample; int i, nr_percent = 1; const char *color; struct annotation *notes = symbol__annotation(sym); @@ -1054,7 +1087,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (perf_evsel__is_group_event(evsel)) { nr_percent = evsel->nr_members; ppercents = calloc(nr_percent, sizeof(double)); - psamples = calloc(nr_percent, sizeof(u64)); + psamples = calloc(nr_percent, sizeof(struct sym_hist_entry)); if (ppercents == NULL || psamples == NULL) { return -1; } @@ -1065,10 +1098,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st notes->src->lines ? i : evsel->idx + i, offset, next ? next->offset : (s64) len, - &path, &nr_samples); + &path, &sample); ppercents[i] = percent; - psamples[i] = nr_samples; + psamples[i] = sample; if (percent > max_percent) max_percent = percent; } @@ -1106,12 +1139,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st for (i = 0; i < nr_percent; i++) { percent = ppercents[i]; - nr_samples = psamples[i]; + sample = psamples[i]; color = get_percent_color(percent); if (symbol_conf.show_total_period) + color_fprintf(stdout, color, " %11" PRIu64, + sample.period); + else if (symbol_conf.show_nr_samples) color_fprintf(stdout, color, " %7" PRIu64, - nr_samples); + sample.nr_samples); else color_fprintf(stdout, color, " %7.2f", percent); } @@ -1127,13 +1163,13 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (ppercents != &percent) free(ppercents); - if (psamples != &nr_samples) + if (psamples != &sample) free(psamples); } else if (max_lines && printed >= max_lines) return 1; else { - int width = 8; + int width = symbol_conf.show_total_period ? 12 : 8; if (queue) return -1; @@ -1327,7 +1363,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil !dso__is_kcore(dso)) return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; - build_id_filename = dso__build_id_filename(dso, NULL, 0); + build_id_filename = dso__build_id_filename(dso, NULL, 0, false); if (build_id_filename) { __symbol__join_symfs(filename, filename_size, build_id_filename); free(build_id_filename); @@ -1381,7 +1417,7 @@ static const char *annotate__norm_arch(const char *arch_name) int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize, - struct arch **parch) + struct arch **parch, char *cpuid) { struct dso *dso = map->dso; char command[PATH_MAX * 2]; @@ -1418,6 +1454,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, } } + if (arch->cpuid_parse && cpuid) + arch->cpuid_parse(arch, cpuid); + pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, symfs_filename, sym->name, map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end)); @@ -1648,19 +1687,19 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, struct sym_hist *h = annotation__histogram(notes, evidx); struct rb_root tmp_root = RB_ROOT; int nr_pcnt = 1; - u64 h_sum = h->sum; + u64 nr_samples = h->nr_samples; size_t sizeof_src_line = sizeof(struct source_line); if (perf_evsel__is_group_event(evsel)) { for (i = 1; i < evsel->nr_members; i++) { h = annotation__histogram(notes, evidx + i); - h_sum += h->sum; + nr_samples += h->nr_samples; } nr_pcnt = evsel->nr_members; sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->samples); } - if (!h_sum) + if (!nr_samples) return 0; src_line = notes->src->lines = calloc(len, sizeof_src_line); @@ -1670,7 +1709,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, start = map__rip_2objdump(map, sym->start); for (i = 0; i < len; i++) { - u64 offset, nr_samples; + u64 offset; double percent_max = 0.0; src_line->nr_pcnt = nr_pcnt; @@ -1679,9 +1718,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, double percent = 0.0; h = annotation__histogram(notes, evidx + k); - nr_samples = h->addr[i]; - if (h->sum) - percent = 100.0 * nr_samples / h->sum; + nr_samples = h->addr[i].nr_samples; + if (h->nr_samples) + percent = 100.0 * nr_samples / h->nr_samples; if (percent > percent_max) percent_max = percent; @@ -1750,10 +1789,10 @@ static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) u64 len = symbol__size(sym), offset; for (offset = 0; offset < len; ++offset) - if (h->addr[offset] != 0) + if (h->addr[offset].nr_samples != 0) printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, - sym->start + offset, h->addr[offset]); - printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); + sym->start + offset, h->addr[offset].nr_samples); + printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples); } int symbol__annotate_printf(struct symbol *sym, struct map *map, @@ -1771,7 +1810,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int printed = 2, queue_len = 0; int more = 0; u64 len; - int width = 8; + int width = symbol_conf.show_total_period ? 12 : 8; int graph_dotted_len; filename = strdup(dso->long_name); @@ -1789,7 +1828,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, width *= evsel->nr_members; graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", - width, width, "Percent", d_filename, evsel_name, h->sum); + width, width, symbol_conf.show_total_period ? "Period" : + symbol_conf.show_nr_samples ? "Samples" : "Percent", + d_filename, evsel_name, h->nr_samples); printf("%-*.*s----\n", graph_dotted_len, graph_dotted_len, graph_dotted_line); @@ -1853,10 +1894,10 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) struct sym_hist *h = annotation__histogram(notes, evidx); int len = symbol__size(sym), offset; - h->sum = 0; + h->nr_samples = 0; for (offset = 0; offset < len; ++offset) { - h->addr[offset] = h->addr[offset] * 7 / 8; - h->sum += h->addr[offset]; + h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8; + h->nr_samples += h->addr[offset].nr_samples; } } @@ -1907,7 +1948,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, u64 len; if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - 0, NULL) < 0) + 0, NULL, NULL) < 0) return -1; len = symbol__size(sym); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 21055034aedd6a07177d0954d629a48862c514a1..9ce575c25fd9bd6bec2c4018836ff40f80c6ab09 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -52,7 +52,9 @@ struct ins_ops { bool ins__is_jump(const struct ins *ins); bool ins__is_call(const struct ins *ins); bool ins__is_ret(const struct ins *ins); +bool ins__is_lock(const struct ins *ins); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); +bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); struct annotation; @@ -72,16 +74,22 @@ static inline bool disasm_line__has_offset(const struct disasm_line *dl) return dl->ops.target.offset_avail; } +struct sym_hist_entry { + u64 nr_samples; + u64 period; +}; + void disasm_line__free(struct disasm_line *dl); struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos); int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw); size_t disasm__fprintf(struct list_head *head, FILE *fp); double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, - s64 end, const char **path, u64 *nr_samples); + s64 end, const char **path, struct sym_hist_entry *sample); struct sym_hist { - u64 sum; - u64 addr[0]; + u64 nr_samples; + u64 period; + struct sym_hist_entry addr[0]; }; struct cyc_hist { @@ -147,20 +155,22 @@ static inline struct annotation *symbol__annotation(struct symbol *sym) return (void *)sym - symbol_conf.priv_size; } -int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); +int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, + int evidx); int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, unsigned cycles); -int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); +int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, + int evidx, u64 addr); int symbol__alloc_hist(struct symbol *sym); void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize, - struct arch **parch); + struct arch **parch, char *cpuid); enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 4bd2d1d882af1d6e9da7561e80d572a82258b5cd..4a1264c66101bda56833f0151af25e2a41fd9de6 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -1246,7 +1246,7 @@ int bpf__config_obj(struct bpf_object *obj, if (!obj || !term || !term->config) return -EINVAL; - if (!prefixcmp(term->config, "map:")) { + if (strstarts(term->config, "map:")) { key_scan_pos = sizeof("map:") - 1; err = bpf__obj_config_map(obj, term, evlist, &key_scan_pos); goto out; diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 1356220a9f1b6eee97e56c51132f394922225d36..827f9140f3b8ab8d8d300a0471fa21ca66a27709 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -58,6 +58,46 @@ check_pos(struct bpf_insn_pos *pos) return 0; } +/* + * Convert type string (u8/u16/u32/u64/s8/s16/s32/s64 ..., see + * Documentation/trace/kprobetrace.txt) to size field of BPF_LDX_MEM + * instruction (BPF_{B,H,W,DW}). + */ +static int +argtype_to_ldx_size(const char *type) +{ + int arg_size = type ? atoi(&type[1]) : 64; + + switch (arg_size) { + case 8: + return BPF_B; + case 16: + return BPF_H; + case 32: + return BPF_W; + case 64: + default: + return BPF_DW; + } +} + +static const char * +insn_sz_to_str(int insn_sz) +{ + switch (insn_sz) { + case BPF_B: + return "BPF_B"; + case BPF_H: + return "BPF_H"; + case BPF_W: + return "BPF_W"; + case BPF_DW: + return "BPF_DW"; + default: + return "UNKNOWN"; + } +} + /* Give it a shorter name */ #define ins(i, p) append_insn((i), (p)) @@ -258,9 +298,14 @@ gen_prologue_slowpath(struct bpf_insn_pos *pos, } /* Final pass: read to registers */ - for (i = 0; i < nargs; i++) - ins(BPF_LDX_MEM(BPF_DW, BPF_PROLOGUE_START_ARG_REG + i, + for (i = 0; i < nargs; i++) { + int insn_sz = (args[i].ref) ? argtype_to_ldx_size(args[i].type) : BPF_DW; + + pr_debug("prologue: load arg %d, insn_sz is %s\n", + i, insn_sz_to_str(insn_sz)); + ins(BPF_LDX_MEM(insn_sz, BPF_PROLOGUE_START_ARG_REG + i, BPF_REG_FP, -BPF_REG_SIZE * (i + 1)), pos); + } ins(BPF_JMP_IMM(BPF_JA, BPF_REG_0, 0, JMP_TO_SUCCESS_CODE), pos); diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c new file mode 100644 index 0000000000000000000000000000000000000000..a4fce2729e505021472a172f3ac6f9abe2cd9a37 --- /dev/null +++ b/tools/perf/util/branch.c @@ -0,0 +1,147 @@ +#include "perf.h" +#include "util/util.h" +#include "util/debug.h" +#include "util/branch.h" + +static bool cross_area(u64 addr1, u64 addr2, int size) +{ + u64 align1, align2; + + align1 = addr1 & ~(size - 1); + align2 = addr2 & ~(size - 1); + + return (align1 != align2) ? true : false; +} + +#define AREA_4K 4096 +#define AREA_2M (2 * 1024 * 1024) + +void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags, + u64 from, u64 to) +{ + if (flags->type == PERF_BR_UNKNOWN || from == 0) + return; + + st->counts[flags->type]++; + + if (flags->type == PERF_BR_COND) { + if (to > from) + st->cond_fwd++; + else + st->cond_bwd++; + } + + if (cross_area(from, to, AREA_2M)) + st->cross_2m++; + else if (cross_area(from, to, AREA_4K)) + st->cross_4k++; +} + +const char *branch_type_name(int type) +{ + const char *branch_names[PERF_BR_MAX] = { + "N/A", + "COND", + "UNCOND", + "IND", + "CALL", + "IND_CALL", + "RET", + "SYSCALL", + "SYSRET", + "COND_CALL", + "COND_RET" + }; + + if (type >= 0 && type < PERF_BR_MAX) + return branch_names[type]; + + return NULL; +} + +void branch_type_stat_display(FILE *fp, struct branch_type_stat *st) +{ + u64 total = 0; + int i; + + for (i = 0; i < PERF_BR_MAX; i++) + total += st->counts[i]; + + if (total == 0) + return; + + fprintf(fp, "\n#"); + fprintf(fp, "\n# Branch Statistics:"); + fprintf(fp, "\n#"); + + if (st->cond_fwd > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "COND_FWD", + 100.0 * (double)st->cond_fwd / (double)total); + } + + if (st->cond_bwd > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "COND_BWD", + 100.0 * (double)st->cond_bwd / (double)total); + } + + if (st->cross_4k > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "CROSS_4K", + 100.0 * (double)st->cross_4k / (double)total); + } + + if (st->cross_2m > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "CROSS_2M", + 100.0 * (double)st->cross_2m / (double)total); + } + + for (i = 0; i < PERF_BR_MAX; i++) { + if (st->counts[i] > 0) + fprintf(fp, "\n%8s: %5.1f%%", + branch_type_name(i), + 100.0 * + (double)st->counts[i] / (double)total); + } +} + +static int count_str_scnprintf(int idx, const char *str, char *bf, int size) +{ + return scnprintf(bf, size, "%s%s", (idx) ? " " : " (", str); +} + +int branch_type_str(struct branch_type_stat *st, char *bf, int size) +{ + int i, j = 0, printed = 0; + u64 total = 0; + + for (i = 0; i < PERF_BR_MAX; i++) + total += st->counts[i]; + + if (total == 0) + return 0; + + if (st->cond_fwd > 0) + printed += count_str_scnprintf(j++, "COND_FWD", bf + printed, size - printed); + + if (st->cond_bwd > 0) + printed += count_str_scnprintf(j++, "COND_BWD", bf + printed, size - printed); + + for (i = 0; i < PERF_BR_MAX; i++) { + if (i == PERF_BR_COND) + continue; + + if (st->counts[i] > 0) + printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed); + } + + if (st->cross_4k > 0) + printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed); + + if (st->cross_2m > 0) + printed += count_str_scnprintf(j++, "CROSS_2M", bf + printed, size - printed); + + return printed; +} diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h new file mode 100644 index 0000000000000000000000000000000000000000..1e3c7c5cdc6346387a64af433390964e2df493d9 --- /dev/null +++ b/tools/perf/util/branch.h @@ -0,0 +1,25 @@ +#ifndef _PERF_BRANCH_H +#define _PERF_BRANCH_H 1 + +#include +#include "../perf.h" + +struct branch_type_stat { + bool branch_to; + u64 counts[PERF_BR_MAX]; + u64 cond_fwd; + u64 cond_bwd; + u64 cross_4k; + u64 cross_2m; +}; + +struct branch_flags; + +void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags, + u64 from, u64 to); + +const char *branch_type_name(int type); +void branch_type_stat_display(FILE *fp, struct branch_type_stat *st); +int branch_type_str(struct branch_type_stat *st, char *bf, int bfsize); + +#endif /* _PERF_BRANCH_H */ diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e0148b081bdfbb7cead2c118a51ca81bd238e740..c1a06fcd7e70b8c4b7fa83613a1773b6c7e57d52 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -243,12 +243,15 @@ static bool build_id_cache__valid_id(char *sbuild_id) return result; } -static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso) +static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso, + bool is_debug) { - return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf"); + return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : (is_debug ? + "debug" : "elf")); } -char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) +char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size, + bool is_debug) { bool is_kallsyms = dso__is_kallsyms((struct dso *)dso); bool is_vdso = dso__is_vdso((struct dso *)dso); @@ -270,7 +273,8 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) ret = asnprintf(&bf, size, "%s", linkname); else ret = asnprintf(&bf, size, "%s/%s", linkname, - build_id_cache__basename(is_kallsyms, is_vdso)); + build_id_cache__basename(is_kallsyms, is_vdso, + is_debug)); if (ret < 0 || (!alloc && size < (unsigned int)ret)) bf = NULL; free(linkname); @@ -285,7 +289,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) else static int write_buildid(const char *name, size_t name_len, u8 *build_id, - pid_t pid, u16 misc, int fd) + pid_t pid, u16 misc, struct feat_fd *fd) { int err; struct build_id_event b; @@ -300,14 +304,15 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id, b.header.misc = misc; b.header.size = sizeof(b) + len; - err = writen(fd, &b, sizeof(b)); + err = do_write(fd, &b, sizeof(b)); if (err < 0) return err; return write_padded(fd, name, name_len + 1, len); } -static int machine__write_buildid_table(struct machine *machine, int fd) +static int machine__write_buildid_table(struct machine *machine, + struct feat_fd *fd) { int err = 0; char nm[PATH_MAX]; @@ -352,7 +357,8 @@ static int machine__write_buildid_table(struct machine *machine, int fd) return err; } -int perf_session__write_buildid_table(struct perf_session *session, int fd) +int perf_session__write_buildid_table(struct perf_session *session, + struct feat_fd *fd) { struct rb_node *nd; int err = machine__write_buildid_table(&session->machines.host, fd); @@ -534,13 +540,14 @@ char *build_id_cache__complement(const char *incomplete_sbuild_id) } char *build_id_cache__cachedir(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso) + struct nsinfo *nsi, bool is_kallsyms, + bool is_vdso) { char *realname = (char *)name, *filename; bool slash = is_kallsyms || is_vdso; if (!slash) { - realname = realpath(name, NULL); + realname = nsinfo__realpath(name, nsi); if (!realname) return NULL; } @@ -556,13 +563,13 @@ char *build_id_cache__cachedir(const char *sbuild_id, const char *name, return filename; } -int build_id_cache__list_build_ids(const char *pathname, +int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result) { char *dir_name; int ret = 0; - dir_name = build_id_cache__cachedir(NULL, pathname, false, false); + dir_name = build_id_cache__cachedir(NULL, pathname, nsi, false, false); if (!dir_name) return -ENOMEM; @@ -576,16 +583,20 @@ int build_id_cache__list_build_ids(const char *pathname, #if defined(HAVE_LIBELF_SUPPORT) && defined(HAVE_GELF_GETNOTE_SUPPORT) static int build_id_cache__add_sdt_cache(const char *sbuild_id, - const char *realname) + const char *realname, + struct nsinfo *nsi) { struct probe_cache *cache; int ret; + struct nscookie nsc; - cache = probe_cache__new(sbuild_id); + cache = probe_cache__new(sbuild_id, nsi); if (!cache) return -1; + nsinfo__mountns_enter(nsi, &nsc); ret = probe_cache__scan_sdt(cache, realname); + nsinfo__mountns_exit(&nsc); if (ret >= 0) { pr_debug4("Found %d SDTs in %s\n", ret, realname); if (probe_cache__commit(cache) < 0) @@ -595,25 +606,56 @@ static int build_id_cache__add_sdt_cache(const char *sbuild_id, return ret; } #else -#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0) +#define build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) (0) #endif +static char *build_id_cache__find_debug(const char *sbuild_id, + struct nsinfo *nsi) +{ + char *realname = NULL; + char *debugfile; + struct nscookie nsc; + size_t len = 0; + + debugfile = calloc(1, PATH_MAX); + if (!debugfile) + goto out; + + len = __symbol__join_symfs(debugfile, PATH_MAX, + "/usr/lib/debug/.build-id/"); + snprintf(debugfile + len, PATH_MAX - len, "%.2s/%s.debug", sbuild_id, + sbuild_id + 2); + + nsinfo__mountns_enter(nsi, &nsc); + realname = realpath(debugfile, NULL); + if (realname && access(realname, R_OK)) + zfree(&realname); + nsinfo__mountns_exit(&nsc); +out: + free(debugfile); + return realname; +} + int build_id_cache__add_s(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso) + struct nsinfo *nsi, bool is_kallsyms, bool is_vdso) { const size_t size = PATH_MAX; char *realname = NULL, *filename = NULL, *dir_name = NULL, *linkname = zalloc(size), *tmp; + char *debugfile = NULL; int err = -1; if (!is_kallsyms) { - realname = realpath(name, NULL); + if (!is_vdso) + realname = nsinfo__realpath(name, nsi); + else + realname = realpath(name, NULL); if (!realname) goto out_free; } - dir_name = build_id_cache__cachedir(sbuild_id, name, - is_kallsyms, is_vdso); + dir_name = build_id_cache__cachedir(sbuild_id, name, nsi, is_kallsyms, + is_vdso); if (!dir_name) goto out_free; @@ -627,20 +669,52 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, /* Save the allocated buildid dirname */ if (asprintf(&filename, "%s/%s", dir_name, - build_id_cache__basename(is_kallsyms, is_vdso)) < 0) { + build_id_cache__basename(is_kallsyms, is_vdso, + false)) < 0) { filename = NULL; goto out_free; } if (access(filename, F_OK)) { if (is_kallsyms) { - if (copyfile("/proc/kallsyms", filename)) + if (copyfile("/proc/kallsyms", filename)) + goto out_free; + } else if (nsi && nsi->need_setns) { + if (copyfile_ns(name, filename, nsi)) goto out_free; } else if (link(realname, filename) && errno != EEXIST && copyfile(name, filename)) goto out_free; } + /* Some binaries are stripped, but have .debug files with their symbol + * table. Check to see if we can locate one of those, since the elf + * file itself may not be very useful to users of our tools without a + * symtab. + */ + if (!is_kallsyms && !is_vdso && + strncmp(".ko", name + strlen(name) - 3, 3)) { + debugfile = build_id_cache__find_debug(sbuild_id, nsi); + if (debugfile) { + zfree(&filename); + if (asprintf(&filename, "%s/%s", dir_name, + build_id_cache__basename(false, false, true)) < 0) { + filename = NULL; + goto out_free; + } + if (access(filename, F_OK)) { + if (nsi && nsi->need_setns) { + if (copyfile_ns(debugfile, filename, + nsi)) + goto out_free; + } else if (link(debugfile, filename) && + errno != EEXIST && + copyfile(debugfile, filename)) + goto out_free; + } + } + } + if (!build_id_cache__linkname(sbuild_id, linkname, size)) goto out_free; tmp = strrchr(linkname, '/'); @@ -657,27 +731,30 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, err = 0; /* Update SDT cache : error is just warned */ - if (realname && build_id_cache__add_sdt_cache(sbuild_id, realname) < 0) + if (realname && + build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) < 0) pr_debug4("Failed to update/scan SDT cache for %s\n", realname); out_free: if (!is_kallsyms) free(realname); free(filename); + free(debugfile); free(dir_name); free(linkname); return err; } static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, - const char *name, bool is_kallsyms, - bool is_vdso) + const char *name, struct nsinfo *nsi, + bool is_kallsyms, bool is_vdso) { char sbuild_id[SBUILD_ID_SIZE]; build_id__sprintf(build_id, build_id_size, sbuild_id); - return build_id_cache__add_s(sbuild_id, name, is_kallsyms, is_vdso); + return build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms, + is_vdso); } bool build_id_cache__cached(const char *sbuild_id) @@ -743,7 +820,7 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine) name = nm; } return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name, - is_kallsyms, is_vdso); + dso->nsinfo, is_kallsyms, is_vdso); } static int __dsos__cache_build_ids(struct list_head *head, diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 96690a55c62c40394444a8f23df1cd03b840acfe..c94b0dcbfd7418bbc80663af3adae9d9be5461b1 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -5,10 +5,12 @@ #define SBUILD_ID_SIZE (BUILD_ID_SIZE * 2 + 1) #include "tool.h" +#include "namespaces.h" #include extern struct perf_tool build_id__mark_dso_hit_ops; struct dso; +struct feat_fd; int build_id__sprintf(const u8 *build_id, int len, char *bf); int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id); @@ -16,7 +18,8 @@ int filename__sprintf_build_id(const char *pathname, char *sbuild_id); char *build_id_cache__kallsyms_path(const char *sbuild_id, char *bf, size_t size); -char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); +char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size, + bool is_debug); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, @@ -25,23 +28,26 @@ int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, int dsos__hit_all(struct perf_session *session); bool perf_session__read_build_ids(struct perf_session *session, bool with_hits); -int perf_session__write_buildid_table(struct perf_session *session, int fd); +int perf_session__write_buildid_table(struct perf_session *session, + struct feat_fd *fd); int perf_session__cache_build_ids(struct perf_session *session); char *build_id_cache__origname(const char *sbuild_id); char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size); char *build_id_cache__cachedir(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso); + struct nsinfo *nsi, bool is_kallsyms, + bool is_vdso); struct strlist; struct strlist *build_id_cache__list_all(bool validonly); char *build_id_cache__complement(const char *incomplete_sbuild_id); -int build_id_cache__list_build_ids(const char *pathname, +int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result); bool build_id_cache__cached(const char *sbuild_id); int build_id_cache__add_s(const char *sbuild_id, - const char *name, bool is_kallsyms, bool is_vdso); + const char *name, struct nsinfo *nsi, + bool is_kallsyms, bool is_vdso); int build_id_cache__remove_s(const char *sbuild_id); extern char buildid_dir[]; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index b4204b43ed58a83c9530ae3b75df4c01004b442e..be09d77cade02edde9973597219ac8b4ee50d3bc 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -23,6 +23,7 @@ #include "sort.h" #include "machine.h" #include "callchain.h" +#include "branch.h" #define CALLCHAIN_PARAM_DEFAULT \ .mode = CHAIN_GRAPH_ABS, \ @@ -64,8 +65,6 @@ static int parse_callchain_mode(const char *value) callchain_param.mode = CHAIN_FOLDED; return 0; } - - pr_err("Invalid callchain mode: %s\n", value); return -1; } @@ -81,8 +80,6 @@ static int parse_callchain_order(const char *value) callchain_param.order_set = true; return 0; } - - pr_err("Invalid callchain order: %s\n", value); return -1; } @@ -104,8 +101,6 @@ static int parse_callchain_sort_key(const char *value) callchain_param.branch_callstack = 1; return 0; } - - pr_err("Invalid callchain sort key: %s\n", value); return -1; } @@ -123,8 +118,6 @@ static int parse_callchain_value(const char *value) callchain_param.value = CCVAL_COUNT; return 0; } - - pr_err("Invalid callchain config key: %s\n", value); return -1; } @@ -303,7 +296,7 @@ int perf_callchain_config(const char *var, const char *value) { char *endptr; - if (prefixcmp(var, "call-graph.")) + if (!strstarts(var, "call-graph.")) return 0; var += sizeof("call-graph.") - 1; @@ -318,12 +311,27 @@ int perf_callchain_config(const char *var, const char *value) return ret; } - if (!strcmp(var, "print-type")) - return parse_callchain_mode(value); - if (!strcmp(var, "order")) - return parse_callchain_order(value); - if (!strcmp(var, "sort-key")) - return parse_callchain_sort_key(value); + if (!strcmp(var, "print-type")){ + int ret; + ret = parse_callchain_mode(value); + if (ret == -1) + pr_err("Invalid callchain mode: %s\n", value); + return ret; + } + if (!strcmp(var, "order")){ + int ret; + ret = parse_callchain_order(value); + if (ret == -1) + pr_err("Invalid callchain order: %s\n", value); + return ret; + } + if (!strcmp(var, "sort-key")){ + int ret; + ret = parse_callchain_sort_key(value); + if (ret == -1) + pr_err("Invalid callchain sort key: %s\n", value); + return ret; + } if (!strcmp(var, "threshold")) { callchain_param.min_percent = strtod(value, &endptr); if (value == endptr) { @@ -562,15 +570,33 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor) if (cursor_node->branch) { call->branch_count = 1; - if (cursor_node->branch_flags.predicted) - call->predicted_count = 1; - - if (cursor_node->branch_flags.abort) - call->abort_count = 1; - - call->cycles_count = cursor_node->branch_flags.cycles; - call->iter_count = cursor_node->nr_loop_iter; - call->samples_count = cursor_node->samples; + if (cursor_node->branch_from) { + /* + * branch_from is set with value somewhere else + * to imply it's "to" of a branch. + */ + call->brtype_stat.branch_to = true; + + if (cursor_node->branch_flags.predicted) + call->predicted_count = 1; + + if (cursor_node->branch_flags.abort) + call->abort_count = 1; + + branch_type_count(&call->brtype_stat, + &cursor_node->branch_flags, + cursor_node->branch_from, + cursor_node->ip); + } else { + /* + * It's "from" of a branch + */ + call->brtype_stat.branch_to = false; + call->cycles_count = + cursor_node->branch_flags.cycles; + call->iter_count = cursor_node->nr_loop_iter; + call->iter_cycles = cursor_node->iter_cycles; + } } list_add_tail(&call->list, &node->val); @@ -679,15 +705,32 @@ static enum match_result match_chain(struct callchain_cursor_node *node, if (node->branch) { cnode->branch_count++; - if (node->branch_flags.predicted) - cnode->predicted_count++; - - if (node->branch_flags.abort) - cnode->abort_count++; - - cnode->cycles_count += node->branch_flags.cycles; - cnode->iter_count += node->nr_loop_iter; - cnode->samples_count += node->samples; + if (node->branch_from) { + /* + * It's "to" of a branch + */ + cnode->brtype_stat.branch_to = true; + + if (node->branch_flags.predicted) + cnode->predicted_count++; + + if (node->branch_flags.abort) + cnode->abort_count++; + + branch_type_count(&cnode->brtype_stat, + &node->branch_flags, + node->branch_from, + node->ip); + } else { + /* + * It's "from" of a branch + */ + cnode->brtype_stat.branch_to = false; + cnode->cycles_count += + node->branch_flags.cycles; + cnode->iter_count += node->nr_loop_iter; + cnode->iter_cycles += node->iter_cycles; + } } return MATCH_EQ; @@ -922,7 +965,7 @@ merge_chain_branch(struct callchain_cursor *cursor, list_for_each_entry_safe(list, next_list, &src->val, list) { callchain_cursor_append(cursor, list->ip, list->ms.map, list->ms.sym, - false, NULL, 0, 0); + false, NULL, 0, 0, 0); list_del(&list->list); map__zput(list->ms.map); free(list); @@ -962,7 +1005,7 @@ int callchain_merge(struct callchain_cursor *cursor, int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, struct map *map, struct symbol *sym, bool branch, struct branch_flags *flags, - int nr_loop_iter, int samples) + int nr_loop_iter, u64 iter_cycles, u64 branch_from) { struct callchain_cursor_node *node = *cursor->last; @@ -980,12 +1023,13 @@ int callchain_cursor_append(struct callchain_cursor *cursor, node->sym = sym; node->branch = branch; node->nr_loop_iter = nr_loop_iter; - node->samples = samples; + node->iter_cycles = iter_cycles; if (flags) memcpy(&node->branch_flags, flags, sizeof(struct branch_flags)); + node->branch_from = branch_from; cursor->nr++; cursor->last = &node->next; @@ -998,11 +1042,11 @@ int sample__resolve_callchain(struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al, int max_stack) { - if (sample->callchain == NULL) + if (sample->callchain == NULL && !symbol_conf.show_branchflag_count) return 0; if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain || - perf_hpp_list.parent) { + perf_hpp_list.parent || symbol_conf.show_branchflag_count) { return thread__resolve_callchain(al->thread, cursor, evsel, sample, parent, al, max_stack); } @@ -1011,7 +1055,8 @@ int sample__resolve_callchain(struct perf_sample *sample, int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample) { - if (!symbol_conf.use_callchain || sample->callchain == NULL) + if ((!symbol_conf.use_callchain || sample->callchain == NULL) && + !symbol_conf.show_branchflag_count) return 0; return callchain_append(he->callchain, &callchain_cursor, sample->period); } @@ -1214,95 +1259,124 @@ int callchain_branch_counts(struct callchain_root *root, cycles_count); } -static int counts_str_build(char *bf, int bfsize, - u64 branch_count, u64 predicted_count, - u64 abort_count, u64 cycles_count, - u64 iter_count, u64 samples_count) +static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize) { - double predicted_percent = 0.0; - const char *null_str = ""; - char iter_str[32]; - char cycle_str[32]; - char *istr, *cstr; - u64 cycles; + int printed; - if (branch_count == 0) - return scnprintf(bf, bfsize, " (calltrace)"); + printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value); - cycles = cycles_count / branch_count; + return printed; +} - if (iter_count && samples_count) { - if (cycles > 0) - scnprintf(iter_str, sizeof(iter_str), - " iterations:%" PRId64 "", - iter_count / samples_count); - else - scnprintf(iter_str, sizeof(iter_str), - "iterations:%" PRId64 "", - iter_count / samples_count); - istr = iter_str; - } else - istr = (char *)null_str; +static int count_float_printf(int idx, const char *str, float value, + char *bf, int bfsize, float threshold) +{ + int printed; - if (cycles > 0) { - scnprintf(cycle_str, sizeof(cycle_str), - "cycles:%" PRId64 "", cycles); - cstr = cycle_str; - } else - cstr = (char *)null_str; + if (threshold != 0.0 && value < threshold) + return 0; - predicted_percent = predicted_count * 100.0 / branch_count; + printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value); - if ((predicted_count == branch_count) && (abort_count == 0)) { - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, " (%s%s)", cstr, istr); - else - return scnprintf(bf, bfsize, "%s", (char *)null_str); - } - - if ((predicted_count < branch_count) && (abort_count == 0)) { - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, - " (predicted:%.1f%% %s%s)", - predicted_percent, cstr, istr); - else { - return scnprintf(bf, bfsize, - " (predicted:%.1f%%)", - predicted_percent); - } + return printed; +} + +static int branch_to_str(char *bf, int bfsize, + u64 branch_count, u64 predicted_count, + u64 abort_count, + struct branch_type_stat *brtype_stat) +{ + int printed, i = 0; + + printed = branch_type_str(brtype_stat, bf, bfsize); + if (printed) + i++; + + if (predicted_count < branch_count) { + printed += count_float_printf(i++, "predicted", + predicted_count * 100.0 / branch_count, + bf + printed, bfsize - printed, 0.0); } - if ((predicted_count == branch_count) && (abort_count > 0)) { - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, - " (abort:%" PRId64 " %s%s)", - abort_count, cstr, istr); - else - return scnprintf(bf, bfsize, - " (abort:%" PRId64 ")", - abort_count); + if (abort_count) { + printed += count_float_printf(i++, "abort", + abort_count * 100.0 / branch_count, + bf + printed, bfsize - printed, 0.1); } - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, - " (predicted:%.1f%% abort:%" PRId64 " %s%s)", - predicted_percent, abort_count, cstr, istr); + if (i) + printed += scnprintf(bf + printed, bfsize - printed, ")"); - return scnprintf(bf, bfsize, - " (predicted:%.1f%% abort:%" PRId64 ")", - predicted_percent, abort_count); + return printed; +} + +static int branch_from_str(char *bf, int bfsize, + u64 branch_count, + u64 cycles_count, u64 iter_count, + u64 iter_cycles) +{ + int printed = 0, i = 0; + u64 cycles; + + cycles = cycles_count / branch_count; + if (cycles) { + printed += count_pri64_printf(i++, "cycles", + cycles, + bf + printed, bfsize - printed); + } + + if (iter_count) { + printed += count_pri64_printf(i++, "iter", + iter_count, + bf + printed, bfsize - printed); + + printed += count_pri64_printf(i++, "avg_cycles", + iter_cycles / iter_count, + bf + printed, bfsize - printed); + } + + if (i) + printed += scnprintf(bf + printed, bfsize - printed, ")"); + + return printed; +} + +static int counts_str_build(char *bf, int bfsize, + u64 branch_count, u64 predicted_count, + u64 abort_count, u64 cycles_count, + u64 iter_count, u64 iter_cycles, + struct branch_type_stat *brtype_stat) +{ + int printed; + + if (branch_count == 0) + return scnprintf(bf, bfsize, " (calltrace)"); + + if (brtype_stat->branch_to) { + printed = branch_to_str(bf, bfsize, branch_count, + predicted_count, abort_count, brtype_stat); + } else { + printed = branch_from_str(bf, bfsize, branch_count, + cycles_count, iter_count, iter_cycles); + } + + if (!printed) + bf[0] = 0; + + return printed; } static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, u64 branch_count, u64 predicted_count, u64 abort_count, u64 cycles_count, - u64 iter_count, u64 samples_count) + u64 iter_count, u64 iter_cycles, + struct branch_type_stat *brtype_stat) { - char str[128]; + char str[256]; counts_str_build(str, sizeof(str), branch_count, predicted_count, abort_count, cycles_count, - iter_count, samples_count); + iter_count, iter_cycles, brtype_stat); if (fp) return fprintf(fp, "%s", str); @@ -1310,31 +1384,24 @@ static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, return scnprintf(bf, bfsize, "%s", str); } -int callchain_list_counts__printf_value(struct callchain_node *node, - struct callchain_list *clist, +int callchain_list_counts__printf_value(struct callchain_list *clist, FILE *fp, char *bf, int bfsize) { u64 branch_count, predicted_count; u64 abort_count, cycles_count; - u64 iter_count = 0, samples_count = 0; + u64 iter_count, iter_cycles; branch_count = clist->branch_count; predicted_count = clist->predicted_count; abort_count = clist->abort_count; cycles_count = clist->cycles_count; - - if (node) { - struct callchain_list *call; - - list_for_each_entry(call, &node->val, list) { - iter_count += call->iter_count; - samples_count += call->samples_count; - } - } + iter_count = clist->iter_count; + iter_cycles = clist->iter_cycles; return callchain_counts_printf(fp, bf, bfsize, branch_count, predicted_count, abort_count, - cycles_count, iter_count, samples_count); + cycles_count, iter_count, iter_cycles, + &clist->brtype_stat); } static void free_callchain_node(struct callchain_node *node) @@ -1459,7 +1526,9 @@ int callchain_cursor__copy(struct callchain_cursor *dst, rc = callchain_cursor_append(dst, node->ip, node->map, node->sym, node->branch, &node->branch_flags, - node->nr_loop_iter, node->samples); + node->nr_loop_iter, + node->iter_cycles, + node->branch_from); if (rc) break; diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index c56c23dbbf72838b8758ec703759a6ad09f229a6..1ed6fc61d0a5906fe8e4e9e344c8c9fa9a925735 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -7,6 +7,7 @@ #include "event.h" #include "map.h" #include "symbol.h" +#include "branch.h" #define HELP_PAD "\t\t\t\t" @@ -118,7 +119,8 @@ struct callchain_list { u64 abort_count; u64 cycles_count; u64 iter_count; - u64 samples_count; + u64 iter_cycles; + struct branch_type_stat brtype_stat; char *srcline; struct list_head list; }; @@ -135,8 +137,9 @@ struct callchain_cursor_node { struct symbol *sym; bool branch; struct branch_flags branch_flags; + u64 branch_from; int nr_loop_iter; - int samples; + u64 iter_cycles; struct callchain_cursor_node *next; }; @@ -198,7 +201,7 @@ static inline void callchain_cursor_reset(struct callchain_cursor *cursor) int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, struct map *map, struct symbol *sym, bool branch, struct branch_flags *flags, - int nr_loop_iter, int samples); + int nr_loop_iter, u64 iter_cycles, u64 branch_from); /* Close a cursor writing session. Initialize for the reader */ static inline void callchain_cursor_commit(struct callchain_cursor *cursor) @@ -279,8 +282,7 @@ char *callchain_node__scnprintf_value(struct callchain_node *node, int callchain_node__fprintf_value(struct callchain_node *node, FILE *fp, u64 total); -int callchain_list_counts__printf_value(struct callchain_node *node, - struct callchain_list *clist, +int callchain_list_counts__printf_value(struct callchain_list *clist, FILE *fp, char *bf, int bfsize); void free_callchain(struct callchain_root *root); diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 03347748f3fadc43f070fa0b6ef789f071c30d65..0e77bc9e5f3c3b354b023e5d26efd08ead615104 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -98,8 +98,10 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) cgrp = counter->cgrp; if (!cgrp) continue; - if (!strcmp(cgrp->name, str)) + if (!strcmp(cgrp->name, str)) { + refcount_inc(&cgrp->refcnt); break; + } cgrp = NULL; } @@ -110,6 +112,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) return -1; cgrp->name = str; + refcount_set(&cgrp->refcnt, 1); cgrp->fd = open_cgroup(str); if (cgrp->fd == -1) { @@ -128,12 +131,11 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) goto found; n++; } - if (refcount_read(&cgrp->refcnt) == 0) + if (refcount_dec_and_test(&cgrp->refcnt)) free(cgrp); return -1; found: - refcount_inc(&cgrp->refcnt); counter->cgrp = cgrp; return 0; } diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 31a7dea248d03323ce238281dd54d5554eb62520..bc75596f9e79ed1b5d0b747df40e933e52deb4a0 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "sane_ctype.h" @@ -433,22 +434,22 @@ static int perf_ui_config(const char *var, const char *value) int perf_default_config(const char *var, const char *value, void *dummy __maybe_unused) { - if (!prefixcmp(var, "core.")) + if (strstarts(var, "core.")) return perf_default_core_config(var, value); - if (!prefixcmp(var, "hist.")) + if (strstarts(var, "hist.")) return perf_hist_config(var, value); - if (!prefixcmp(var, "ui.")) + if (strstarts(var, "ui.")) return perf_ui_config(var, value); - if (!prefixcmp(var, "call-graph.")) + if (strstarts(var, "call-graph.")) return perf_callchain_config(var, value); - if (!prefixcmp(var, "llvm.")) + if (strstarts(var, "llvm.")) return perf_llvm_config(var, value); - if (!prefixcmp(var, "buildid.")) + if (strstarts(var, "buildid.")) return perf_buildid_config(var, value); /* Add other config variables here. */ diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 34d8baaf558aee25793c44d268109e901673a75d..cb45a6aecf9dbc62b4d7850ac806b714f3a423cb 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -12,6 +12,7 @@ struct perf_counts_values { }; u64 values[3]; }; + bool loaded; }; struct perf_counts { diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 3149b70799fd52693bdffb709478bbedade865e2..2346cecb8ea20c867520a9ca76a24b355c0fe7e3 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -76,6 +76,8 @@ struct ctf_writer { struct bt_ctf_event_class *comm_class; struct bt_ctf_event_class *exit_class; struct bt_ctf_event_class *fork_class; + struct bt_ctf_event_class *mmap_class; + struct bt_ctf_event_class *mmap2_class; }; struct convert { @@ -506,6 +508,81 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class, return ret; } +static int +add_callchain_output_values(struct bt_ctf_event_class *event_class, + struct bt_ctf_event *event, + struct ip_callchain *callchain) +{ + struct bt_ctf_field_type *len_type, *seq_type; + struct bt_ctf_field *len_field, *seq_field; + unsigned int nr_elements = callchain->nr; + unsigned int i; + int ret; + + len_type = bt_ctf_event_class_get_field_by_name( + event_class, "perf_callchain_size"); + len_field = bt_ctf_field_create(len_type); + if (!len_field) { + pr_err("failed to create 'perf_callchain_size' for callchain output event\n"); + ret = -1; + goto put_len_type; + } + + ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements); + if (ret) { + pr_err("failed to set field value for perf_callchain_size\n"); + goto put_len_field; + } + ret = bt_ctf_event_set_payload(event, "perf_callchain_size", len_field); + if (ret) { + pr_err("failed to set payload to perf_callchain_size\n"); + goto put_len_field; + } + + seq_type = bt_ctf_event_class_get_field_by_name( + event_class, "perf_callchain"); + seq_field = bt_ctf_field_create(seq_type); + if (!seq_field) { + pr_err("failed to create 'perf_callchain' for callchain output event\n"); + ret = -1; + goto put_seq_type; + } + + ret = bt_ctf_field_sequence_set_length(seq_field, len_field); + if (ret) { + pr_err("failed to set length of 'perf_callchain'\n"); + goto put_seq_field; + } + + for (i = 0; i < nr_elements; i++) { + struct bt_ctf_field *elem_field = + bt_ctf_field_sequence_get_field(seq_field, i); + + ret = bt_ctf_field_unsigned_integer_set_value(elem_field, + ((u64 *)(callchain->ips))[i]); + + bt_ctf_field_put(elem_field); + if (ret) { + pr_err("failed to set callchain[%d]\n", i); + goto put_seq_field; + } + } + + ret = bt_ctf_event_set_payload(event, "perf_callchain", seq_field); + if (ret) + pr_err("failed to set payload for raw_data\n"); + +put_seq_field: + bt_ctf_field_put(seq_field); +put_seq_type: + bt_ctf_field_type_put(seq_type); +put_len_field: + bt_ctf_field_put(len_field); +put_len_type: + bt_ctf_field_type_put(len_type); + return ret; +} + static int add_generic_values(struct ctf_writer *cw, struct bt_ctf_event *event, struct perf_evsel *evsel, @@ -519,7 +596,6 @@ static int add_generic_values(struct ctf_writer *cw, * PERF_SAMPLE_TIME - not needed as we have it in * ctf event header * PERF_SAMPLE_READ - TODO - * PERF_SAMPLE_CALLCHAIN - TODO * PERF_SAMPLE_RAW - tracepoint fields are handled separately * PERF_SAMPLE_BRANCH_STACK - TODO * PERF_SAMPLE_REGS_USER - TODO @@ -720,6 +796,7 @@ static int process_sample_event(struct perf_tool *tool, struct bt_ctf_event_class *event_class; struct bt_ctf_event *event; int ret; + unsigned long type = evsel->attr.sample_type; if (WARN_ONCE(!priv, "Failed to setup all events.\n")) return 0; @@ -751,6 +828,13 @@ static int process_sample_event(struct perf_tool *tool, return -1; } + if (type & PERF_SAMPLE_CALLCHAIN) { + ret = add_callchain_output_values(event_class, + event, sample->callchain); + if (ret) + return -1; + } + if (perf_evsel__is_bpf_output(evsel)) { ret = add_bpf_output_values(event_class, event, sample); if (ret) @@ -833,6 +917,18 @@ __FUNC_PROCESS_NON_SAMPLE(exit, __NON_SAMPLE_SET_FIELD(fork, u32, ptid); __NON_SAMPLE_SET_FIELD(fork, u64, time); ) +__FUNC_PROCESS_NON_SAMPLE(mmap, + __NON_SAMPLE_SET_FIELD(mmap, u32, pid); + __NON_SAMPLE_SET_FIELD(mmap, u32, tid); + __NON_SAMPLE_SET_FIELD(mmap, u64_hex, start); + __NON_SAMPLE_SET_FIELD(mmap, string, filename); +) +__FUNC_PROCESS_NON_SAMPLE(mmap2, + __NON_SAMPLE_SET_FIELD(mmap2, u32, pid); + __NON_SAMPLE_SET_FIELD(mmap2, u32, tid); + __NON_SAMPLE_SET_FIELD(mmap2, u64_hex, start); + __NON_SAMPLE_SET_FIELD(mmap2, string, filename); +) #undef __NON_SAMPLE_SET_FIELD #undef __FUNC_PROCESS_NON_SAMPLE @@ -1043,6 +1139,14 @@ static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, if (type & PERF_SAMPLE_TRANSACTION) ADD_FIELD(event_class, cw->data.u64, "perf_transaction"); + if (type & PERF_SAMPLE_CALLCHAIN) { + ADD_FIELD(event_class, cw->data.u32, "perf_callchain_size"); + ADD_FIELD(event_class, + bt_ctf_field_type_sequence_create( + cw->data.u64_hex, "perf_callchain_size"), + "perf_callchain"); + } + #undef ADD_FIELD return 0; } @@ -1164,6 +1268,19 @@ __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(exit, __NON_SAMPLE_ADD_FIELD(u64, time); ) +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(u64_hex, start); + __NON_SAMPLE_ADD_FIELD(string, filename); +) + +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap2, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(u64_hex, start); + __NON_SAMPLE_ADD_FIELD(string, filename); +) #undef __NON_SAMPLE_ADD_FIELD #undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS @@ -1179,6 +1296,12 @@ static int setup_non_sample_events(struct ctf_writer *cw, if (ret) return ret; ret = add_fork_event(cw); + if (ret) + return ret; + ret = add_mmap_event(cw); + if (ret) + return ret; + ret = add_mmap2_event(cw); if (ret) return ret; return 0; @@ -1482,6 +1605,8 @@ int bt_convert__perf2ctf(const char *input, const char *path, c.tool.comm = process_comm_event; c.tool.exit = process_exit_event; c.tool.fork = process_fork_event; + c.tool.mmap = process_mmap_event; + c.tool.mmap2 = process_mmap2_event; } err = perf_config(convert__config, &c); diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index e84bbc8ec058916c968ae940ae662746495efe67..263f5a906ba5a2bde3d0898a1e19d783920fca47 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -10,6 +10,16 @@ #include "util.h" #include "debug.h" +#ifndef O_CLOEXEC +#ifdef __sparc__ +#define O_CLOEXEC 0x400000 +#elif defined(__alpha__) || defined(__hppa__) +#define O_CLOEXEC 010000000 +#else +#define O_CLOEXEC 02000000 +#endif +#endif + static bool check_pipe(struct perf_data_file *file) { struct stat st; @@ -96,7 +106,8 @@ static int open_file_write(struct perf_data_file *file) if (check_backup(file)) return -1; - fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, + S_IRUSR|S_IWUSR); if (fd < 0) pr_err("failed to open %s : %s\n", file->path, diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 4e7ab611377acd56c1be78cbd983058e5ce5142b..b9e087fb8247983f0f3aed7e984dc5eb2615de7c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -32,6 +32,7 @@ char dso__symtab_origin(const struct dso *dso) [DSO_BINARY_TYPE__JAVA_JIT] = 'j', [DSO_BINARY_TYPE__DEBUGLINK] = 'l', [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', + [DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO] = 'D', [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o', @@ -97,7 +98,12 @@ int dso__read_binary_type_filename(const struct dso *dso, break; } case DSO_BINARY_TYPE__BUILD_ID_CACHE: - if (dso__build_id_filename(dso, filename, size) == NULL) + if (dso__build_id_filename(dso, filename, size, false) == NULL) + ret = -1; + break; + + case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: + if (dso__build_id_filename(dso, filename, size, true) == NULL) ret = -1; break; @@ -504,7 +510,14 @@ static void check_data_close(void); */ static int open_dso(struct dso *dso, struct machine *machine) { - int fd = __open_dso(dso, machine); + int fd; + struct nscookie nsc; + + if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_enter(dso->nsinfo, &nsc); + fd = __open_dso(dso, machine); + if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_exit(&nsc); if (fd >= 0) { dso__list_add(dso); @@ -1236,6 +1249,7 @@ void dso__delete(struct dso *dso) dso_cache__free(dso); dso__free_a2l(dso); zfree(&dso->symsrc_filename); + nsinfo__zput(dso->nsinfo); pthread_mutex_destroy(&dso->lock); free(dso); } @@ -1301,6 +1315,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) { bool have_build_id = false; struct dso *pos; + struct nscookie nsc; list_for_each_entry(pos, head, node) { if (with_hits && !pos->hit && !dso__is_vdso(pos)) @@ -1309,11 +1324,13 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) have_build_id = true; continue; } + nsinfo__mountns_enter(pos->nsinfo, &nsc); if (filename__read_build_id(pos->long_name, pos->build_id, sizeof(pos->build_id)) > 0) { have_build_id = true; pos->has_build_id = true; } + nsinfo__mountns_exit(&nsc); } return have_build_id; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index bd061ba7b47cc8eab2ff05e4027dc22990d7c7ef..f886141678ebaf816290fc4ca274e6ef10d6525b 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -10,6 +10,7 @@ #include #include #include "map.h" +#include "namespaces.h" #include "build-id.h" enum dso_binary_type { @@ -20,6 +21,7 @@ enum dso_binary_type { DSO_BINARY_TYPE__JAVA_JIT, DSO_BINARY_TYPE__DEBUGLINK, DSO_BINARY_TYPE__BUILD_ID_CACHE, + DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO, DSO_BINARY_TYPE__FEDORA_DEBUGINFO, DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__BUILDID_DEBUGINFO, @@ -187,6 +189,7 @@ struct dso { void *priv; u64 db_id; }; + struct nsinfo *nsinfo; refcount_t refcnt; char name[0]; }; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index dc5c3bb69d73882ebbac88dfec2d16c55b56355e..1c905ba3641b6477d20317ef36bde6214baf7941 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -57,6 +57,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", [PERF_RECORD_TIME_CONV] = "TIME_CONV", + [PERF_RECORD_HEADER_FEATURE] = "FEATURE", }; static const char *perf_ns__names[] = { diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 9967c87af7a665c6a21d139c27832547ef04c790..ee7bcc898d3531356bedfb637c23266ab6f07ea5 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -142,7 +142,8 @@ struct branch_flags { u64 in_tx:1; u64 abort:1; u64 cycles:16; - u64 reserved:44; + u64 type:4; + u64 reserved:40; }; struct branch_entry { @@ -199,6 +200,7 @@ struct perf_sample { u32 cpu; u32 raw_size; u64 data_src; + u64 phys_addr; u32 flags; u16 insn_len; u8 cpumode; @@ -244,6 +246,7 @@ enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_STAT_ROUND = 77, PERF_RECORD_EVENT_UPDATE = 78, PERF_RECORD_TIME_CONV = 79, + PERF_RECORD_HEADER_FEATURE = 80, PERF_RECORD_HEADER_MAX }; @@ -609,6 +612,12 @@ struct time_conv_event { u64 time_zero; }; +struct feature_event { + struct perf_event_header header; + u64 feat_id; + char data[]; +}; + union perf_event { struct perf_event_header header; struct mmap_event mmap; @@ -639,6 +648,7 @@ union perf_event { struct stat_event stat; struct stat_round_event stat_round; struct time_conv_event time_conv; + struct feature_event feat; }; void perf_event__print_totals(void); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 46c0faf6c502b9ae31ac09901bbca31de61691bf..6a0d7ffbeba00e084054b4b8f7372c087c72510c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -242,9 +242,9 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr) } } -int perf_evlist__add_default(struct perf_evlist *evlist) +int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise) { - struct perf_evsel *evsel = perf_evsel__new_cycles(); + struct perf_evsel *evsel = perf_evsel__new_cycles(precise); if (evsel == NULL) return -ENOMEM; @@ -1419,8 +1419,6 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e { struct perf_evsel *evsel; int err = 0; - const int ncpus = cpu_map__nr(evlist->cpus), - nthreads = thread_map__nr(evlist->threads); evlist__for_each_entry(evlist, evsel) { if (evsel->filter == NULL) @@ -1430,7 +1428,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e * filters only work for tracepoint event, which doesn't have cpu limit. * So evlist and evsel should always be same. */ - err = perf_evsel__apply_filter(evsel, ncpus, nthreads, evsel->filter); + err = perf_evsel__apply_filter(evsel, evsel->filter); if (err) { *err_evsel = evsel; break; @@ -1623,13 +1621,9 @@ void perf_evlist__set_selected(struct perf_evlist *evlist, void perf_evlist__close(struct perf_evlist *evlist) { struct perf_evsel *evsel; - int ncpus = cpu_map__nr(evlist->cpus); - int nthreads = thread_map__nr(evlist->threads); - evlist__for_each_entry_reverse(evlist, evsel) { - int n = evsel->cpus ? evsel->cpus->nr : ncpus; - perf_evsel__close(evsel, n, nthreads); - } + evlist__for_each_entry_reverse(evlist, evsel) + perf_evsel__close(evsel); } static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 8d601fbdd8d6440a5292b99dc8eb080488b1a726..bf2c4936e35fca513667b07bc67b99b0f96a007d 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -115,7 +115,14 @@ void perf_evlist__delete(struct perf_evlist *evlist); void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel); -int perf_evlist__add_default(struct perf_evlist *evlist); + +int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise); + +static inline int perf_evlist__add_default(struct perf_evlist *evlist) +{ + return __perf_evlist__add_default(evlist, true); +} + int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs); @@ -258,6 +265,11 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist); void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list); +static inline bool perf_evlist__empty(struct perf_evlist *evlist) +{ + return list_empty(&evlist->entries); +} + static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) { return list_entry(evlist->entries.next, struct perf_evsel, node); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 413f74df08de7cae06b1313ef0ed4c1339ee2093..0dccdb89572cdb455724a6a48a86d96821fc53e2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -49,6 +49,7 @@ static struct { bool clockid_wrong; bool lbr_flags; bool write_backward; + bool group_read; } perf_missing_features; static clockid_t clockid; @@ -58,6 +59,8 @@ static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) return 0; } +void __weak test_attr__ready(void) { } + static void perf_evsel__no_extra_fini(struct perf_evsel *evsel __maybe_unused) { } @@ -268,16 +271,24 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) return evsel; } -struct perf_evsel *perf_evsel__new_cycles(void) +static bool perf_event_can_profile_kernel(void) +{ + return geteuid() == 0 || perf_event_paranoid() == -1; +} + +struct perf_evsel *perf_evsel__new_cycles(bool precise) { struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, - .exclude_kernel = geteuid() != 0, + .exclude_kernel = !perf_event_can_profile_kernel(), }; struct perf_evsel *evsel; event_attr_init(&attr); + + if (!precise) + goto new_event; /* * Unnamed union member, not supported as struct member named * initializer in older compilers such as gcc 4.4.7 @@ -292,7 +303,7 @@ struct perf_evsel *perf_evsel__new_cycles(void) * to kick in when we return and before perf_evsel__open() is called. */ attr.sample_period = 0; - +new_event: evsel = perf_evsel__new(&attr); if (evsel == NULL) goto out; @@ -896,8 +907,13 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, if (opts->no_samples) attr->sample_freq = 0; - if (opts->inherit_stat) + if (opts->inherit_stat) { + evsel->attr.read_format |= + PERF_FORMAT_TOTAL_TIME_ENABLED | + PERF_FORMAT_TOTAL_TIME_RUNNING | + PERF_FORMAT_ID; attr->inherit_stat = 1; + } if (opts->sample_address) { perf_evsel__set_sample_bit(evsel, ADDR); @@ -944,6 +960,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, if (opts->sample_address) perf_evsel__set_sample_bit(evsel, DATA_SRC); + if (opts->sample_phys_addr) + perf_evsel__set_sample_bit(evsel, PHYS_ADDR); + if (opts->no_buffering) { attr->watermark = 0; attr->wakeup_events = 1; @@ -1045,16 +1064,13 @@ static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthread return evsel->fd != NULL ? 0 : -ENOMEM; } -static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthreads, +static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ioc, void *arg) { int cpu, thread; - if (evsel->system_wide) - nthreads = 1; - - for (cpu = 0; cpu < ncpus; cpu++) { - for (thread = 0; thread < nthreads; thread++) { + for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { + for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { int fd = FD(evsel, cpu, thread), err = ioctl(fd, ioc, arg); @@ -1066,10 +1082,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea return 0; } -int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, - const char *filter) +int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter) { - return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_SET_FILTER, (void *)filter); } @@ -1116,20 +1131,14 @@ int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter) int perf_evsel__enable(struct perf_evsel *evsel) { - int nthreads = thread_map__nr(evsel->threads); - int ncpus = cpu_map__nr(evsel->cpus); - - return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0); } int perf_evsel__disable(struct perf_evsel *evsel) { - int nthreads = thread_map__nr(evsel->threads); - int ncpus = cpu_map__nr(evsel->cpus); - - return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0); } @@ -1179,15 +1188,12 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel) } } -void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) +void perf_evsel__close_fd(struct perf_evsel *evsel) { int cpu, thread; - if (evsel->system_wide) - nthreads = 1; - - for (cpu = 0; cpu < ncpus; cpu++) - for (thread = 0; thread < nthreads; ++thread) { + for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) + for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { close(FD(evsel, cpu, thread)); FD(evsel, cpu, thread) = -1; } @@ -1256,20 +1262,148 @@ void perf_counts_values__scale(struct perf_counts_values *count, *pscaled = scaled; } +static int perf_evsel__read_size(struct perf_evsel *evsel) +{ + u64 read_format = evsel->attr.read_format; + int entry = sizeof(u64); /* value */ + int size = 0; + int nr = 1; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + size += sizeof(u64); + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + size += sizeof(u64); + + if (read_format & PERF_FORMAT_ID) + entry += sizeof(u64); + + if (read_format & PERF_FORMAT_GROUP) { + nr = evsel->nr_members; + size += sizeof(u64); + } + + size += entry * nr; + return size; +} + int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, struct perf_counts_values *count) { + size_t size = perf_evsel__read_size(evsel); + memset(count, 0, sizeof(*count)); if (FD(evsel, cpu, thread) < 0) return -EINVAL; - if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) <= 0) + if (readn(FD(evsel, cpu, thread), count->values, size) <= 0) return -errno; return 0; } +static int +perf_evsel__read_one(struct perf_evsel *evsel, int cpu, int thread) +{ + struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread); + + return perf_evsel__read(evsel, cpu, thread, count); +} + +static void +perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread, + u64 val, u64 ena, u64 run) +{ + struct perf_counts_values *count; + + count = perf_counts(counter->counts, cpu, thread); + + count->val = val; + count->ena = ena; + count->run = run; + count->loaded = true; +} + +static int +perf_evsel__process_group_data(struct perf_evsel *leader, + int cpu, int thread, u64 *data) +{ + u64 read_format = leader->attr.read_format; + struct sample_read_value *v; + u64 nr, ena = 0, run = 0, i; + + nr = *data++; + + if (nr != (u64) leader->nr_members) + return -EINVAL; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + ena = *data++; + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + run = *data++; + + v = (struct sample_read_value *) data; + + perf_evsel__set_count(leader, cpu, thread, + v[0].value, ena, run); + + for (i = 1; i < nr; i++) { + struct perf_evsel *counter; + + counter = perf_evlist__id2evsel(leader->evlist, v[i].id); + if (!counter) + return -EINVAL; + + perf_evsel__set_count(counter, cpu, thread, + v[i].value, ena, run); + } + + return 0; +} + +static int +perf_evsel__read_group(struct perf_evsel *leader, int cpu, int thread) +{ + struct perf_stat_evsel *ps = leader->priv; + u64 read_format = leader->attr.read_format; + int size = perf_evsel__read_size(leader); + u64 *data = ps->group_data; + + if (!(read_format & PERF_FORMAT_ID)) + return -EINVAL; + + if (!perf_evsel__is_group_leader(leader)) + return -EINVAL; + + if (!data) { + data = zalloc(size); + if (!data) + return -ENOMEM; + + ps->group_data = data; + } + + if (FD(leader, cpu, thread) < 0) + return -EINVAL; + + if (readn(FD(leader, cpu, thread), data, size) <= 0) + return -errno; + + return perf_evsel__process_group_data(leader, cpu, thread, data); +} + +int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread) +{ + u64 read_format = evsel->attr.read_format; + + if (read_format & PERF_FORMAT_GROUP) + return perf_evsel__read_group(evsel, cpu, thread); + else + return perf_evsel__read_one(evsel, cpu, thread); +} + int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, int cpu, int thread, bool scale) { @@ -1338,7 +1472,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value) bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), - bit_name(WEIGHT), + bit_name(WEIGHT), bit_name(PHYS_ADDR), { .name = NULL, } }; #undef bit_name @@ -1545,6 +1679,8 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, if (perf_missing_features.lbr_flags) evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | PERF_SAMPLE_BRANCH_NO_CYCLES); + if (perf_missing_features.group_read && evsel->attr.inherit) + evsel->attr.read_format &= ~(PERF_FORMAT_GROUP|PERF_FORMAT_ID); retry_sample_id: if (perf_missing_features.sample_id_all) evsel->attr.sample_id_all = 0; @@ -1569,6 +1705,8 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, pr_debug2("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx", pid, cpus->map[cpu], group_fd, flags); + test_attr__ready(); + fd = sys_perf_event_open(&evsel->attr, pid, cpus->map[cpu], group_fd, flags); @@ -1664,31 +1802,45 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, */ if (!perf_missing_features.write_backward && evsel->attr.write_backward) { perf_missing_features.write_backward = true; + pr_debug2("switching off write_backward\n"); goto out_close; } else if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { perf_missing_features.clockid_wrong = true; + pr_debug2("switching off clockid\n"); goto fallback_missing_features; } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) { perf_missing_features.clockid = true; + pr_debug2("switching off use_clockid\n"); goto fallback_missing_features; } else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) { perf_missing_features.cloexec = true; + pr_debug2("switching off cloexec flag\n"); goto fallback_missing_features; } else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) { perf_missing_features.mmap2 = true; + pr_debug2("switching off mmap2\n"); goto fallback_missing_features; } else if (!perf_missing_features.exclude_guest && (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { perf_missing_features.exclude_guest = true; + pr_debug2("switching off exclude_guest, exclude_host\n"); goto fallback_missing_features; } else if (!perf_missing_features.sample_id_all) { perf_missing_features.sample_id_all = true; + pr_debug2("switching off sample_id_all\n"); goto retry_sample_id; } else if (!perf_missing_features.lbr_flags && (evsel->attr.branch_sample_type & (PERF_SAMPLE_BRANCH_NO_CYCLES | PERF_SAMPLE_BRANCH_NO_FLAGS))) { perf_missing_features.lbr_flags = true; + pr_debug2("switching off branch sample type no (cycles/flags)\n"); + goto fallback_missing_features; + } else if (!perf_missing_features.group_read && + evsel->attr.inherit && + (evsel->attr.read_format & PERF_FORMAT_GROUP)) { + perf_missing_features.group_read = true; + pr_debug2("switching off group read\n"); goto fallback_missing_features; } out_close: @@ -1702,12 +1854,12 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, return err; } -void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads) +void perf_evsel__close(struct perf_evsel *evsel) { if (evsel->fd == NULL) return; - perf_evsel__close_fd(evsel, ncpus, nthreads); + perf_evsel__close_fd(evsel); perf_evsel__free_fd(evsel); } @@ -2062,6 +2214,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } } + data->phys_addr = 0; + if (type & PERF_SAMPLE_PHYS_ADDR) { + data->phys_addr = *array; + array++; + } + return 0; } @@ -2167,6 +2325,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, } } + if (type & PERF_SAMPLE_PHYS_ADDR) + result += sizeof(u64); + return result; } @@ -2356,6 +2517,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, } } + if (type & PERF_SAMPLE_PHYS_ADDR) { + *array = sample->phys_addr; + array++; + } + return 0; } @@ -2535,7 +2701,9 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, "unprivileged users (without CAP_SYS_ADMIN).\n\n" "The current value is %d:\n\n" " -1: Allow use of (almost) all events by all users\n" - ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" + " Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK\n" + ">= 0: Disallow ftrace function tracepoint by users without CAP_SYS_ADMIN\n" + " Disallow raw tracepoint access by users without CAP_SYS_ADMIN\n" ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN\n\n" "To make this setting permanent, edit /etc/sysctl.conf too, e.g.:\n\n" @@ -2610,3 +2778,10 @@ char *perf_evsel__env_arch(struct perf_evsel *evsel) return evsel->evlist->env->arch; return NULL; } + +char *perf_evsel__env_cpuid(struct perf_evsel *evsel) +{ + if (evsel && evsel->evlist && evsel->evlist->env) + return evsel->evlist->env->cpuid; + return NULL; +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d101695c482cfb288db70b1f268372d4f4323f65..dd2c4b5112a561b846053719262ce967cd383e16 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -131,6 +131,7 @@ struct perf_evsel { bool cmdline_group_boundary; struct list_head config_terms; int bpf_fd; + bool auto_merge_stats; bool merged_stat; const char * metric_expr; const char * metric_name; @@ -185,7 +186,7 @@ static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char * return perf_evsel__newtp_idx(sys, name, 0); } -struct perf_evsel *perf_evsel__new_cycles(void); +struct perf_evsel *perf_evsel__new_cycles(bool precise); struct event_format *event_format__new(const char *sys, const char *name); @@ -226,7 +227,7 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel); int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); -void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); +void perf_evsel__close_fd(struct perf_evsel *evsel); void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, enum perf_event_sample_format bit); @@ -246,8 +247,7 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter); int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter); int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter); -int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, - const char *filter); +int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter); int perf_evsel__enable(struct perf_evsel *evsel); int perf_evsel__disable(struct perf_evsel *evsel); @@ -257,7 +257,7 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads); int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, struct thread_map *threads); -void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads); +void perf_evsel__close(struct perf_evsel *evsel); struct perf_sample; @@ -299,6 +299,8 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1, int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, struct perf_counts_values *count); +int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread); + int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, int cpu, int thread, bool scale); @@ -436,5 +438,6 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, attr__fprintf_f attr__fprintf, void *priv); char *perf_evsel__env_arch(struct perf_evsel *evsel); +char *perf_evsel__env_cpuid(struct perf_evsel *evsel); #endif /* __PERF_EVSEL_H */ diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index 9c2760a1a96ea8de6d1338e8b1a93b3696e770c8..400ef9eab00a08f50afc7a08fd191d0e44fe3e7b 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -1,7 +1,7 @@ #ifndef PARSE_CTX_H #define PARSE_CTX_H 1 -#define EXPR_MAX_OTHER 8 +#define EXPR_MAX_OTHER 15 #define MAX_PARSE_ID EXPR_MAX_OTHER struct parse_id { diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 954556bea36ef758ef31c5f7a1e723cc8fe50db0..432b8560cf51c8bf2d751d409d34fe516ade2582 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -4,6 +4,7 @@ #include "util/debug.h" #define IN_EXPR_Y 1 #include "expr.h" +#include "smt.h" #include #define MAXIDLEN 256 @@ -22,13 +23,15 @@ %token NUMBER %token ID +%token MIN MAX IF ELSE SMT_ON +%left MIN MAX IF %left '|' %left '^' %left '&' %left '-' '+' %left '*' '/' '%' %left NEG NOT -%type expr +%type expr if_expr %{ static int expr__lex(YYSTYPE *res, const char **pp); @@ -57,22 +60,33 @@ static int lookup_id(struct parse_ctx *ctx, char *id, double *val) %} %% -all_expr: expr { *final_val = $1; } +all_expr: if_expr { *final_val = $1; } + ; + +if_expr: + expr IF expr ELSE expr { $$ = $3 ? $1 : $5; } + | expr ; expr: NUMBER | ID { if (lookup_id(ctx, $1, &$$) < 0) { - pr_debug("%s not found", $1); + pr_debug("%s not found\n", $1); YYABORT; } } + | expr '|' expr { $$ = (long)$1 | (long)$3; } + | expr '&' expr { $$ = (long)$1 & (long)$3; } + | expr '^' expr { $$ = (long)$1 ^ (long)$3; } | expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { if ($3 == 0) YYABORT; $$ = $1 / $3; } | expr '%' expr { if ((long)$3 == 0) YYABORT; $$ = (long)$1 % (long)$3; } | '-' expr %prec NEG { $$ = -$2; } - | '(' expr ')' { $$ = $2; } + | '(' if_expr ')' { $$ = $2; } + | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; } + | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; } + | SMT_ON { $$ = smt_on() > 0; } ; %% @@ -82,13 +96,47 @@ static int expr__symbol(YYSTYPE *res, const char *p, const char **pp) char *dst = res->id; const char *s = p; - while (isalnum(*p) || *p == '_' || *p == '.') { + if (*p == '#') + *dst++ = *p++; + + while (isalnum(*p) || *p == '_' || *p == '.' || *p == ':' || *p == '@' || *p == '\\') { if (p - s >= MAXIDLEN) return -1; - *dst++ = *p++; + /* + * Allow @ instead of / to be able to specify pmu/event/ without + * conflicts with normal division. + */ + if (*p == '@') + *dst++ = '/'; + else if (*p == '\\') + *dst++ = *++p; + else + *dst++ = *p; + p++; } *dst = 0; *pp = p; + dst = res->id; + switch (dst[0]) { + case 'm': + if (!strcmp(dst, "min")) + return MIN; + if (!strcmp(dst, "max")) + return MAX; + break; + case 'i': + if (!strcmp(dst, "if")) + return IF; + break; + case 'e': + if (!strcmp(dst, "else")) + return ELSE; + break; + case '#': + if (!strcasecmp(dst, "#smt_on")) + return SMT_ON; + break; + } return ID; } @@ -102,6 +150,7 @@ static int expr__lex(YYSTYPE *res, const char **pp) p++; s = p; switch (*p++) { + case '#': case 'a' ... 'z': case 'A' ... 'Z': return expr__symbol(res, p - 1, pp); @@ -132,6 +181,19 @@ void expr__ctx_init(struct parse_ctx *ctx) ctx->num_ids = 0; } +static bool already_seen(const char *val, const char *one, const char **other, + int num_other) +{ + int i; + + if (one && !strcasecmp(one, val)) + return true; + for (i = 0; i < num_other; i++) + if (!strcasecmp(other[i], val)) + return true; + return false; +} + int expr__find_other(const char *p, const char *one, const char ***other, int *num_otherp) { @@ -151,7 +213,7 @@ int expr__find_other(const char *p, const char *one, const char ***other, err = 0; break; } - if (tok == ID && strcasecmp(one, val.id)) { + if (tok == ID && !already_seen(val.id, one, *other, num_other)) { if (num_other >= EXPR_MAX_OTHER - 1) { pr_debug("Too many extra events in %s\n", orig); break; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 76ed7d03e500fa246776689e85df53a89171f79a..605bbd5404fb36e7fc8d61ee7d99e66f1b65ba7a 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include "data.h" #include #include "asm/bug.h" +#include "tool.h" #include "sane_ctype.h" @@ -59,6 +61,15 @@ struct perf_file_attr { struct perf_file_section ids; }; +struct feat_fd { + struct perf_header *ph; + int fd; + void *buf; /* Either buf != NULL or fd >= 0 */ + ssize_t offset; + size_t size; + struct perf_evsel *events; +}; + void perf_header__set_feat(struct perf_header *header, int feat) { set_bit(feat, header->adds_features); @@ -74,28 +85,60 @@ bool perf_header__has_feat(const struct perf_header *header, int feat) return test_bit(feat, header->adds_features); } -static int do_write(int fd, const void *buf, size_t size) +static int __do_write_fd(struct feat_fd *ff, const void *buf, size_t size) { - while (size) { - int ret = write(fd, buf, size); + ssize_t ret = writen(ff->fd, buf, size); - if (ret < 0) - return -errno; + if (ret != (ssize_t)size) + return ret < 0 ? (int)ret : -1; + return 0; +} + +static int __do_write_buf(struct feat_fd *ff, const void *buf, size_t size) +{ + /* struct perf_event_header::size is u16 */ + const size_t max_size = 0xffff - sizeof(struct perf_event_header); + size_t new_size = ff->size; + void *addr; - size -= ret; - buf += ret; + if (size + ff->offset > max_size) + return -E2BIG; + + while (size > (new_size - ff->offset)) + new_size <<= 1; + new_size = min(max_size, new_size); + + if (ff->size < new_size) { + addr = realloc(ff->buf, new_size); + if (!addr) + return -ENOMEM; + ff->buf = addr; + ff->size = new_size; } + memcpy(ff->buf + ff->offset, buf, size); + ff->offset += size; + return 0; } -int write_padded(int fd, const void *bf, size_t count, size_t count_aligned) +/* Return: 0 if succeded, -ERR if failed. */ +int do_write(struct feat_fd *ff, const void *buf, size_t size) +{ + if (!ff->buf) + return __do_write_fd(ff, buf, size); + return __do_write_buf(ff, buf, size); +} + +/* Return: 0 if succeded, -ERR if failed. */ +int write_padded(struct feat_fd *ff, const void *bf, + size_t count, size_t count_aligned) { static const char zero_buf[NAME_ALIGN]; - int err = do_write(fd, bf, count); + int err = do_write(ff, bf, count); if (!err) - err = do_write(fd, zero_buf, count_aligned - count); + err = do_write(ff, zero_buf, count_aligned - count); return err; } @@ -103,7 +146,8 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned) #define string_size(str) \ (PERF_ALIGN((strlen(str) + 1), NAME_ALIGN) + sizeof(u32)) -static int do_write_string(int fd, const char *str) +/* Return: 0 if succeded, -ERR if failed. */ +static int do_write_string(struct feat_fd *ff, const char *str) { u32 len, olen; int ret; @@ -112,32 +156,80 @@ static int do_write_string(int fd, const char *str) len = PERF_ALIGN(olen, NAME_ALIGN); /* write len, incl. \0 */ - ret = do_write(fd, &len, sizeof(len)); + ret = do_write(ff, &len, sizeof(len)); if (ret < 0) return ret; - return write_padded(fd, str, olen, len); + return write_padded(ff, str, olen, len); } -static char *do_read_string(int fd, struct perf_header *ph) +static int __do_read_fd(struct feat_fd *ff, void *addr, ssize_t size) +{ + ssize_t ret = readn(ff->fd, addr, size); + + if (ret != size) + return ret < 0 ? (int)ret : -1; + return 0; +} + +static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size) +{ + if (size > (ssize_t)ff->size - ff->offset) + return -1; + + memcpy(addr, ff->buf + ff->offset, size); + ff->offset += size; + + return 0; + +} + +static int __do_read(struct feat_fd *ff, void *addr, ssize_t size) +{ + if (!ff->buf) + return __do_read_fd(ff, addr, size); + return __do_read_buf(ff, addr, size); +} + +static int do_read_u32(struct feat_fd *ff, u32 *addr) +{ + int ret; + + ret = __do_read(ff, addr, sizeof(*addr)); + if (ret) + return ret; + + if (ff->ph->needs_swap) + *addr = bswap_32(*addr); + return 0; +} + +static int do_read_u64(struct feat_fd *ff, u64 *addr) +{ + int ret; + + ret = __do_read(ff, addr, sizeof(*addr)); + if (ret) + return ret; + + if (ff->ph->needs_swap) + *addr = bswap_64(*addr); + return 0; +} + +static char *do_read_string(struct feat_fd *ff) { - ssize_t sz, ret; u32 len; char *buf; - sz = readn(fd, &len, sizeof(len)); - if (sz < (ssize_t)sizeof(len)) + if (do_read_u32(ff, &len)) return NULL; - if (ph->needs_swap) - len = bswap_32(len); - buf = malloc(len); if (!buf) return NULL; - ret = readn(fd, buf, len); - if (ret == (ssize_t)len) { + if (!__do_read(ff, buf, len)) { /* * strings are padded by zeroes * thus the actual strlen of buf @@ -150,25 +242,30 @@ static char *do_read_string(int fd, struct perf_header *ph) return NULL; } -static int write_tracing_data(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist) +static int write_tracing_data(struct feat_fd *ff, + struct perf_evlist *evlist) { - return read_tracing_data(fd, &evlist->entries); -} + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + return read_tracing_data(ff->fd, &evlist->entries); +} -static int write_build_id(int fd, struct perf_header *h, +static int write_build_id(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct perf_session *session; int err; - session = container_of(h, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); if (!perf_session__read_build_ids(session, true)) return -1; - err = perf_session__write_buildid_table(session, fd); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + + err = perf_session__write_buildid_table(session, ff); if (err < 0) { pr_debug("failed to write buildid table\n"); return err; @@ -178,7 +275,7 @@ static int write_build_id(int fd, struct perf_header *h, return 0; } -static int write_hostname(int fd, struct perf_header *h __maybe_unused, +static int write_hostname(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct utsname uts; @@ -188,10 +285,10 @@ static int write_hostname(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return -1; - return do_write_string(fd, uts.nodename); + return do_write_string(ff, uts.nodename); } -static int write_osrelease(int fd, struct perf_header *h __maybe_unused, +static int write_osrelease(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct utsname uts; @@ -201,10 +298,10 @@ static int write_osrelease(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return -1; - return do_write_string(fd, uts.release); + return do_write_string(ff, uts.release); } -static int write_arch(int fd, struct perf_header *h __maybe_unused, +static int write_arch(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct utsname uts; @@ -214,16 +311,16 @@ static int write_arch(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return -1; - return do_write_string(fd, uts.machine); + return do_write_string(ff, uts.machine); } -static int write_version(int fd, struct perf_header *h __maybe_unused, +static int write_version(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { - return do_write_string(fd, perf_version_string); + return do_write_string(ff, perf_version_string); } -static int __write_cpudesc(int fd, const char *cpuinfo_proc) +static int __write_cpudesc(struct feat_fd *ff, const char *cpuinfo_proc) { FILE *file; char *buf = NULL; @@ -273,25 +370,22 @@ static int __write_cpudesc(int fd, const char *cpuinfo_proc) } p++; } - ret = do_write_string(fd, s); + ret = do_write_string(ff, s); done: free(buf); fclose(file); return ret; } -static int write_cpudesc(int fd, struct perf_header *h __maybe_unused, +static int write_cpudesc(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { -#ifndef CPUINFO_PROC -#define CPUINFO_PROC {"model name", } -#endif const char *cpuinfo_procs[] = CPUINFO_PROC; unsigned int i; for (i = 0; i < ARRAY_SIZE(cpuinfo_procs); i++) { int ret; - ret = __write_cpudesc(fd, cpuinfo_procs[i]); + ret = __write_cpudesc(ff, cpuinfo_procs[i]); if (ret >= 0) return ret; } @@ -299,7 +393,7 @@ static int write_cpudesc(int fd, struct perf_header *h __maybe_unused, } -static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, +static int write_nrcpus(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { long nr; @@ -314,14 +408,14 @@ static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, nra = (u32)(nr & UINT_MAX); - ret = do_write(fd, &nrc, sizeof(nrc)); + ret = do_write(ff, &nrc, sizeof(nrc)); if (ret < 0) return ret; - return do_write(fd, &nra, sizeof(nra)); + return do_write(ff, &nra, sizeof(nra)); } -static int write_event_desc(int fd, struct perf_header *h __maybe_unused, +static int write_event_desc(struct feat_fd *ff, struct perf_evlist *evlist) { struct perf_evsel *evsel; @@ -333,7 +427,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, /* * write number of events */ - ret = do_write(fd, &nre, sizeof(nre)); + ret = do_write(ff, &nre, sizeof(nre)); if (ret < 0) return ret; @@ -341,12 +435,12 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, * size of perf_event_attr struct */ sz = (u32)sizeof(evsel->attr); - ret = do_write(fd, &sz, sizeof(sz)); + ret = do_write(ff, &sz, sizeof(sz)); if (ret < 0) return ret; evlist__for_each_entry(evlist, evsel) { - ret = do_write(fd, &evsel->attr, sz); + ret = do_write(ff, &evsel->attr, sz); if (ret < 0) return ret; /* @@ -357,27 +451,27 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, * type of ids, */ nri = evsel->ids; - ret = do_write(fd, &nri, sizeof(nri)); + ret = do_write(ff, &nri, sizeof(nri)); if (ret < 0) return ret; /* * write event string as passed on cmdline */ - ret = do_write_string(fd, perf_evsel__name(evsel)); + ret = do_write_string(ff, perf_evsel__name(evsel)); if (ret < 0) return ret; /* * write unique ids for this event */ - ret = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); + ret = do_write(ff, evsel->id, evsel->ids * sizeof(u64)); if (ret < 0) return ret; } return 0; } -static int write_cmdline(int fd, struct perf_header *h __maybe_unused, +static int write_cmdline(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { char buf[MAXPATHLEN]; @@ -395,16 +489,16 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused, /* account for binary path */ n = perf_env.nr_cmdline + 1; - ret = do_write(fd, &n, sizeof(n)); + ret = do_write(ff, &n, sizeof(n)); if (ret < 0) return ret; - ret = do_write_string(fd, buf); + ret = do_write_string(ff, buf); if (ret < 0) return ret; for (i = 0 ; i < perf_env.nr_cmdline; i++) { - ret = do_write_string(fd, perf_env.cmdline_argv[i]); + ret = do_write_string(ff, perf_env.cmdline_argv[i]); if (ret < 0) return ret; } @@ -557,8 +651,8 @@ static struct cpu_topo *build_cpu_topology(void) return tp; } -static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_cpu_topology(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { struct cpu_topo *tp; u32 i; @@ -568,21 +662,21 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, if (!tp) return -1; - ret = do_write(fd, &tp->core_sib, sizeof(tp->core_sib)); + ret = do_write(ff, &tp->core_sib, sizeof(tp->core_sib)); if (ret < 0) goto done; for (i = 0; i < tp->core_sib; i++) { - ret = do_write_string(fd, tp->core_siblings[i]); + ret = do_write_string(ff, tp->core_siblings[i]); if (ret < 0) goto done; } - ret = do_write(fd, &tp->thread_sib, sizeof(tp->thread_sib)); + ret = do_write(ff, &tp->thread_sib, sizeof(tp->thread_sib)); if (ret < 0) goto done; for (i = 0; i < tp->thread_sib; i++) { - ret = do_write_string(fd, tp->thread_siblings[i]); + ret = do_write_string(ff, tp->thread_siblings[i]); if (ret < 0) break; } @@ -592,11 +686,11 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, goto done; for (j = 0; j < perf_env.nr_cpus_avail; j++) { - ret = do_write(fd, &perf_env.cpu[j].core_id, + ret = do_write(ff, &perf_env.cpu[j].core_id, sizeof(perf_env.cpu[j].core_id)); if (ret < 0) return ret; - ret = do_write(fd, &perf_env.cpu[j].socket_id, + ret = do_write(ff, &perf_env.cpu[j].socket_id, sizeof(perf_env.cpu[j].socket_id)); if (ret < 0) return ret; @@ -608,8 +702,8 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, -static int write_total_mem(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_total_mem(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { char *buf = NULL; FILE *fp; @@ -629,7 +723,7 @@ static int write_total_mem(int fd, struct perf_header *h __maybe_unused, if (!ret) { n = sscanf(buf, "%*s %"PRIu64, &mem); if (n == 1) - ret = do_write(fd, &mem, sizeof(mem)); + ret = do_write(ff, &mem, sizeof(mem)); } else ret = -1; free(buf); @@ -637,7 +731,7 @@ static int write_total_mem(int fd, struct perf_header *h __maybe_unused, return ret; } -static int write_topo_node(int fd, int node) +static int write_topo_node(struct feat_fd *ff, int node) { char str[MAXPATHLEN]; char field[32]; @@ -667,11 +761,11 @@ static int write_topo_node(int fd, int node) fclose(fp); fp = NULL; - ret = do_write(fd, &mem_total, sizeof(u64)); + ret = do_write(ff, &mem_total, sizeof(u64)); if (ret) goto done; - ret = do_write(fd, &mem_free, sizeof(u64)); + ret = do_write(ff, &mem_free, sizeof(u64)); if (ret) goto done; @@ -689,7 +783,7 @@ static int write_topo_node(int fd, int node) if (p) *p = '\0'; - ret = do_write_string(fd, buf); + ret = do_write_string(ff, buf); done: free(buf); if (fp) @@ -697,8 +791,8 @@ static int write_topo_node(int fd, int node) return ret; } -static int write_numa_topology(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_numa_topology(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { char *buf = NULL; size_t len = 0; @@ -725,17 +819,17 @@ static int write_numa_topology(int fd, struct perf_header *h __maybe_unused, nr = (u32)node_map->nr; - ret = do_write(fd, &nr, sizeof(nr)); + ret = do_write(ff, &nr, sizeof(nr)); if (ret < 0) goto done; for (i = 0; i < nr; i++) { j = (u32)node_map->map[i]; - ret = do_write(fd, &j, sizeof(j)); + ret = do_write(ff, &j, sizeof(j)); if (ret < 0) break; - ret = write_topo_node(fd, i); + ret = write_topo_node(ff, i); if (ret < 0) break; } @@ -758,39 +852,40 @@ static int write_numa_topology(int fd, struct perf_header *h __maybe_unused, * }; */ -static int write_pmu_mappings(int fd, struct perf_header *h __maybe_unused, +static int write_pmu_mappings(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct perf_pmu *pmu = NULL; - off_t offset = lseek(fd, 0, SEEK_CUR); - __u32 pmu_num = 0; + u32 pmu_num = 0; int ret; - /* write real pmu_num later */ - ret = do_write(fd, &pmu_num, sizeof(pmu_num)); + /* + * Do a first pass to count number of pmu to avoid lseek so this + * works in pipe mode as well. + */ + while ((pmu = perf_pmu__scan(pmu))) { + if (!pmu->name) + continue; + pmu_num++; + } + + ret = do_write(ff, &pmu_num, sizeof(pmu_num)); if (ret < 0) return ret; while ((pmu = perf_pmu__scan(pmu))) { if (!pmu->name) continue; - pmu_num++; - ret = do_write(fd, &pmu->type, sizeof(pmu->type)); + ret = do_write(ff, &pmu->type, sizeof(pmu->type)); if (ret < 0) return ret; - ret = do_write_string(fd, pmu->name); + ret = do_write_string(ff, pmu->name); if (ret < 0) return ret; } - if (pwrite(fd, &pmu_num, sizeof(pmu_num), offset) != sizeof(pmu_num)) { - /* discard all */ - lseek(fd, offset, SEEK_SET); - return -1; - } - return 0; } @@ -806,14 +901,14 @@ static int write_pmu_mappings(int fd, struct perf_header *h __maybe_unused, * }[nr_groups]; * }; */ -static int write_group_desc(int fd, struct perf_header *h __maybe_unused, +static int write_group_desc(struct feat_fd *ff, struct perf_evlist *evlist) { u32 nr_groups = evlist->nr_groups; struct perf_evsel *evsel; int ret; - ret = do_write(fd, &nr_groups, sizeof(nr_groups)); + ret = do_write(ff, &nr_groups, sizeof(nr_groups)); if (ret < 0) return ret; @@ -824,15 +919,15 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused, u32 leader_idx = evsel->idx; u32 nr_members = evsel->nr_members; - ret = do_write_string(fd, name); + ret = do_write_string(ff, name); if (ret < 0) return ret; - ret = do_write(fd, &leader_idx, sizeof(leader_idx)); + ret = do_write(ff, &leader_idx, sizeof(leader_idx)); if (ret < 0) return ret; - ret = do_write(fd, &nr_members, sizeof(nr_members)); + ret = do_write(ff, &nr_members, sizeof(nr_members)); if (ret < 0) return ret; } @@ -849,7 +944,7 @@ int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused) return -1; } -static int write_cpuid(int fd, struct perf_header *h __maybe_unused, +static int write_cpuid(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { char buffer[64]; @@ -861,25 +956,27 @@ static int write_cpuid(int fd, struct perf_header *h __maybe_unused, return -1; write_it: - return do_write_string(fd, buffer); + return do_write_string(ff, buffer); } -static int write_branch_stack(int fd __maybe_unused, - struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_branch_stack(struct feat_fd *ff __maybe_unused, + struct perf_evlist *evlist __maybe_unused) { return 0; } -static int write_auxtrace(int fd, struct perf_header *h, +static int write_auxtrace(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct perf_session *session; int err; - session = container_of(h, struct perf_session, header); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + + session = container_of(ff->ph, struct perf_session, header); - err = auxtrace_index__write(fd, &session->auxtrace_index); + err = auxtrace_index__write(ff->fd, &session->auxtrace_index); if (err < 0) pr_err("Failed to write auxtrace index\n"); return err; @@ -1026,8 +1123,8 @@ static int build_caches(struct cpu_cache_level caches[], u32 size, u32 *cntp) #define MAX_CACHES 2000 -static int write_cache(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_cache(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { struct cpu_cache_level caches[MAX_CACHES]; u32 cnt = 0, i, version = 1; @@ -1039,11 +1136,11 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, qsort(&caches, cnt, sizeof(struct cpu_cache_level), cpu_cache_level__sort); - ret = do_write(fd, &version, sizeof(u32)); + ret = do_write(ff, &version, sizeof(u32)); if (ret < 0) goto out; - ret = do_write(fd, &cnt, sizeof(u32)); + ret = do_write(ff, &cnt, sizeof(u32)); if (ret < 0) goto out; @@ -1051,7 +1148,7 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, struct cpu_cache_level *c = &caches[i]; #define _W(v) \ - ret = do_write(fd, &c->v, sizeof(u32)); \ + ret = do_write(ff, &c->v, sizeof(u32)); \ if (ret < 0) \ goto out; @@ -1062,7 +1159,7 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, #undef _W #define _W(v) \ - ret = do_write_string(fd, (const char *) c->v); \ + ret = do_write_string(ff, (const char *) c->v); \ if (ret < 0) \ goto out; @@ -1078,69 +1175,62 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, return ret; } -static int write_stat(int fd __maybe_unused, - struct perf_header *h __maybe_unused, +static int write_stat(struct feat_fd *ff __maybe_unused, struct perf_evlist *evlist __maybe_unused) { return 0; } -static void print_hostname(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_hostname(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# hostname : %s\n", ph->env.hostname); + fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname); } -static void print_osrelease(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_osrelease(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# os release : %s\n", ph->env.os_release); + fprintf(fp, "# os release : %s\n", ff->ph->env.os_release); } -static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp) +static void print_arch(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# arch : %s\n", ph->env.arch); + fprintf(fp, "# arch : %s\n", ff->ph->env.arch); } -static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_cpudesc(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# cpudesc : %s\n", ph->env.cpu_desc); + fprintf(fp, "# cpudesc : %s\n", ff->ph->env.cpu_desc); } -static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_nrcpus(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# nrcpus online : %u\n", ph->env.nr_cpus_online); - fprintf(fp, "# nrcpus avail : %u\n", ph->env.nr_cpus_avail); + fprintf(fp, "# nrcpus online : %u\n", ff->ph->env.nr_cpus_online); + fprintf(fp, "# nrcpus avail : %u\n", ff->ph->env.nr_cpus_avail); } -static void print_version(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_version(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# perf version : %s\n", ph->env.version); + fprintf(fp, "# perf version : %s\n", ff->ph->env.version); } -static void print_cmdline(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_cmdline(struct feat_fd *ff, FILE *fp) { int nr, i; - nr = ph->env.nr_cmdline; + nr = ff->ph->env.nr_cmdline; fprintf(fp, "# cmdline : "); for (i = 0; i < nr; i++) - fprintf(fp, "%s ", ph->env.cmdline_argv[i]); + fprintf(fp, "%s ", ff->ph->env.cmdline_argv[i]); fputc('\n', fp); } -static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_cpu_topology(struct feat_fd *ff, FILE *fp) { + struct perf_header *ph = ff->ph; + int cpu_nr = ph->env.nr_cpus_avail; int nr, i; char *str; - int cpu_nr = ph->env.nr_cpus_avail; nr = ph->env.nr_sibling_cores; str = ph->env.sibling_cores; @@ -1181,31 +1271,21 @@ static void free_event_desc(struct perf_evsel *events) free(events); } -static struct perf_evsel * -read_event_desc(struct perf_header *ph, int fd) +static struct perf_evsel *read_event_desc(struct feat_fd *ff) { struct perf_evsel *evsel, *events = NULL; u64 *id; void *buf = NULL; u32 nre, sz, nr, i, j; - ssize_t ret; size_t msz; /* number of events */ - ret = readn(fd, &nre, sizeof(nre)); - if (ret != (ssize_t)sizeof(nre)) + if (do_read_u32(ff, &nre)) goto error; - if (ph->needs_swap) - nre = bswap_32(nre); - - ret = readn(fd, &sz, sizeof(sz)); - if (ret != (ssize_t)sizeof(sz)) + if (do_read_u32(ff, &sz)) goto error; - if (ph->needs_swap) - sz = bswap_32(sz); - /* buffer to hold on file attr struct */ buf = malloc(sz); if (!buf) @@ -1227,25 +1307,23 @@ read_event_desc(struct perf_header *ph, int fd) * must read entire on-file attr struct to * sync up with layout. */ - ret = readn(fd, buf, sz); - if (ret != (ssize_t)sz) + if (__do_read(ff, buf, sz)) goto error; - if (ph->needs_swap) + if (ff->ph->needs_swap) perf_event__attr_swap(buf); memcpy(&evsel->attr, buf, msz); - ret = readn(fd, &nr, sizeof(nr)); - if (ret != (ssize_t)sizeof(nr)) + if (do_read_u32(ff, &nr)) goto error; - if (ph->needs_swap) { - nr = bswap_32(nr); + if (ff->ph->needs_swap) evsel->needs_swap = true; - } - evsel->name = do_read_string(fd, ph); + evsel->name = do_read_string(ff); + if (!evsel->name) + goto error; if (!nr) continue; @@ -1257,11 +1335,8 @@ read_event_desc(struct perf_header *ph, int fd) evsel->id = id; for (j = 0 ; j < nr; j++) { - ret = readn(fd, id, sizeof(*id)); - if (ret != (ssize_t)sizeof(*id)) + if (do_read_u64(ff, id)) goto error; - if (ph->needs_swap) - *id = bswap_64(*id); id++; } } @@ -1280,12 +1355,17 @@ static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, return fprintf(fp, ", %s = %s", name, val); } -static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) +static void print_event_desc(struct feat_fd *ff, FILE *fp) { - struct perf_evsel *evsel, *events = read_event_desc(ph, fd); + struct perf_evsel *evsel, *events; u32 j; u64 *id; + if (ff->events) + events = ff->events; + else + events = read_event_desc(ff); + if (!events) { fprintf(fp, "# event desc: not available or unable to read\n"); return; @@ -1310,22 +1390,21 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) } free_event_desc(events); + ff->events = NULL; } -static void print_total_mem(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_total_mem(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# total memory : %Lu kB\n", ph->env.total_mem); + fprintf(fp, "# total memory : %llu kB\n", ff->ph->env.total_mem); } -static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_numa_topology(struct feat_fd *ff, FILE *fp) { int i; struct numa_node *n; - for (i = 0; i < ph->env.nr_numa_nodes; i++) { - n = &ph->env.numa_nodes[i]; + for (i = 0; i < ff->ph->env.nr_numa_nodes; i++) { + n = &ff->ph->env.numa_nodes[i]; fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB," " free = %"PRIu64" kB\n", @@ -1336,56 +1415,51 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, } } -static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp) +static void print_cpuid(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# cpuid : %s\n", ph->env.cpuid); + fprintf(fp, "# cpuid : %s\n", ff->ph->env.cpuid); } -static void print_branch_stack(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp) +static void print_branch_stack(struct feat_fd *ff __maybe_unused, FILE *fp) { fprintf(fp, "# contains samples with branch stack\n"); } -static void print_auxtrace(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp) +static void print_auxtrace(struct feat_fd *ff __maybe_unused, FILE *fp) { fprintf(fp, "# contains AUX area data (e.g. instruction trace)\n"); } -static void print_stat(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp) +static void print_stat(struct feat_fd *ff __maybe_unused, FILE *fp) { fprintf(fp, "# contains stat data\n"); } -static void print_cache(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp __maybe_unused) +static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused) { int i; fprintf(fp, "# CPU cache info:\n"); - for (i = 0; i < ph->env.caches_cnt; i++) { + for (i = 0; i < ff->ph->env.caches_cnt; i++) { fprintf(fp, "# "); - cpu_cache_level__fprintf(fp, &ph->env.caches[i]); + cpu_cache_level__fprintf(fp, &ff->ph->env.caches[i]); } } -static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_pmu_mappings(struct feat_fd *ff, FILE *fp) { const char *delimiter = "# pmu mappings: "; char *str, *tmp; u32 pmu_num; u32 type; - pmu_num = ph->env.nr_pmu_mappings; + pmu_num = ff->ph->env.nr_pmu_mappings; if (!pmu_num) { fprintf(fp, "# pmu mappings: not available\n"); return; } - str = ph->env.pmu_mappings; + str = ff->ph->env.pmu_mappings; while (pmu_num) { type = strtoul(str, &tmp, 0); @@ -1408,14 +1482,13 @@ static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused, fprintf(fp, "# pmu mappings: unable to read\n"); } -static void print_group_desc(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_group_desc(struct feat_fd *ff, FILE *fp) { struct perf_session *session; struct perf_evsel *evsel; u32 nr = 0; - session = container_of(ph, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); evlist__for_each_entry(session->evlist, evsel) { if (perf_evsel__is_group_leader(evsel) && @@ -1588,113 +1661,61 @@ static int perf_header__read_build_ids(struct perf_header *header, return err; } -static int process_tracing_data(struct perf_file_section *section __maybe_unused, - struct perf_header *ph __maybe_unused, - int fd, void *data) -{ - ssize_t ret = trace_report(fd, data, false); - return ret < 0 ? -1 : 0; -} - -static int process_build_id(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) - pr_debug("Failed to read buildids, continuing...\n"); - return 0; +/* Macro for features that simply need to read and store a string. */ +#define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \ +static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \ +{\ + ff->ph->env.__feat_env = do_read_string(ff); \ + return ff->ph->env.__feat_env ? 0 : -ENOMEM; \ } -static int process_hostname(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.hostname = do_read_string(fd, ph); - return ph->env.hostname ? 0 : -ENOMEM; -} +FEAT_PROCESS_STR_FUN(hostname, hostname); +FEAT_PROCESS_STR_FUN(osrelease, os_release); +FEAT_PROCESS_STR_FUN(version, version); +FEAT_PROCESS_STR_FUN(arch, arch); +FEAT_PROCESS_STR_FUN(cpudesc, cpu_desc); +FEAT_PROCESS_STR_FUN(cpuid, cpuid); -static int process_osrelease(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_tracing_data(struct feat_fd *ff, void *data) { - ph->env.os_release = do_read_string(fd, ph); - return ph->env.os_release ? 0 : -ENOMEM; -} + ssize_t ret = trace_report(ff->fd, data, false); -static int process_version(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.version = do_read_string(fd, ph); - return ph->env.version ? 0 : -ENOMEM; + return ret < 0 ? -1 : 0; } -static int process_arch(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_build_id(struct feat_fd *ff, void *data __maybe_unused) { - ph->env.arch = do_read_string(fd, ph); - return ph->env.arch ? 0 : -ENOMEM; + if (perf_header__read_build_ids(ff->ph, ff->fd, ff->offset, ff->size)) + pr_debug("Failed to read buildids, continuing...\n"); + return 0; } -static int process_nrcpus(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_nrcpus(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; - u32 nr; - - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) - return -1; - - if (ph->needs_swap) - nr = bswap_32(nr); - - ph->env.nr_cpus_avail = nr; - - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) - return -1; + int ret; + u32 nr_cpus_avail, nr_cpus_online; - if (ph->needs_swap) - nr = bswap_32(nr); + ret = do_read_u32(ff, &nr_cpus_avail); + if (ret) + return ret; - ph->env.nr_cpus_online = nr; + ret = do_read_u32(ff, &nr_cpus_online); + if (ret) + return ret; + ff->ph->env.nr_cpus_avail = (int)nr_cpus_avail; + ff->ph->env.nr_cpus_online = (int)nr_cpus_online; return 0; } -static int process_cpudesc(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.cpu_desc = do_read_string(fd, ph); - return ph->env.cpu_desc ? 0 : -ENOMEM; -} - -static int process_cpuid(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.cpuid = do_read_string(fd, ph); - return ph->env.cpuid ? 0 : -ENOMEM; -} - -static int process_total_mem(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_total_mem(struct feat_fd *ff, void *data __maybe_unused) { - uint64_t mem; - ssize_t ret; + u64 total_mem; + int ret; - ret = readn(fd, &mem, sizeof(mem)); - if (ret != sizeof(mem)) + ret = do_read_u64(ff, &total_mem); + if (ret) return -1; - - if (ph->needs_swap) - mem = bswap_64(mem); - - ph->env.total_mem = mem; + ff->ph->env.total_mem = (unsigned long long)total_mem; return 0; } @@ -1731,43 +1752,42 @@ perf_evlist__set_event_name(struct perf_evlist *evlist, } static int -process_event_desc(struct perf_file_section *section __maybe_unused, - struct perf_header *header, int fd, - void *data __maybe_unused) +process_event_desc(struct feat_fd *ff, void *data __maybe_unused) { struct perf_session *session; - struct perf_evsel *evsel, *events = read_event_desc(header, fd); + struct perf_evsel *evsel, *events = read_event_desc(ff); if (!events) return 0; - session = container_of(header, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); + + if (session->file->is_pipe) { + /* Save events for reading later by print_event_desc, + * since they can't be read again in pipe mode. */ + ff->events = events; + } + for (evsel = events; evsel->attr.size; evsel++) perf_evlist__set_event_name(session->evlist, evsel); - free_event_desc(events); + if (!session->file->is_pipe) + free_event_desc(events); return 0; } -static int process_cmdline(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_cmdline(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; char *str, *cmdline = NULL, **argv = NULL; u32 nr, i, len = 0; - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) return -1; - if (ph->needs_swap) - nr = bswap_32(nr); - - ph->env.nr_cmdline = nr; + ff->ph->env.nr_cmdline = nr; - cmdline = zalloc(section->size + nr + 1); + cmdline = zalloc(ff->size + nr + 1); if (!cmdline) return -1; @@ -1776,7 +1796,7 @@ static int process_cmdline(struct perf_file_section *section, goto error; for (i = 0; i < nr; i++) { - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1785,8 +1805,8 @@ static int process_cmdline(struct perf_file_section *section, len += strlen(str) + 1; free(str); } - ph->env.cmdline = cmdline; - ph->env.cmdline_argv = (const char **) argv; + ff->ph->env.cmdline = cmdline; + ff->ph->env.cmdline_argv = (const char **) argv; return 0; error: @@ -1795,35 +1815,29 @@ static int process_cmdline(struct perf_file_section *section, return -1; } -static int process_cpu_topology(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; u32 nr, i; char *str; struct strbuf sb; - int cpu_nr = ph->env.nr_cpus_avail; + int cpu_nr = ff->ph->env.nr_cpus_avail; u64 size = 0; + struct perf_header *ph = ff->ph; ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); if (!ph->env.cpu) return -1; - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) goto free_cpu; - if (ph->needs_swap) - nr = bswap_32(nr); - ph->env.nr_sibling_cores = nr; size += sizeof(u32); if (strbuf_init(&sb, 128) < 0) goto free_cpu; for (i = 0; i < nr; i++) { - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1835,18 +1849,14 @@ static int process_cpu_topology(struct perf_file_section *section, } ph->env.sibling_cores = strbuf_detach(&sb, NULL); - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) return -1; - if (ph->needs_swap) - nr = bswap_32(nr); - ph->env.nr_sibling_threads = nr; size += sizeof(u32); for (i = 0; i < nr; i++) { - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1862,28 +1872,20 @@ static int process_cpu_topology(struct perf_file_section *section, * The header may be from old perf, * which doesn't include core id and socket id information. */ - if (section->size <= size) { + if (ff->size <= size) { zfree(&ph->env.cpu); return 0; } for (i = 0; i < (u32)cpu_nr; i++) { - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) goto free_cpu; - if (ph->needs_swap) - nr = bswap_32(nr); - ph->env.cpu[i].core_id = nr; - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) goto free_cpu; - if (ph->needs_swap) - nr = bswap_32(nr); - if (nr != (u32)-1 && nr > (u32)cpu_nr) { pr_debug("socket_id number is too big." "You may need to upgrade the perf tool.\n"); @@ -1902,23 +1904,16 @@ static int process_cpu_topology(struct perf_file_section *section, return -1; } -static int process_numa_topology(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused) { struct numa_node *nodes, *n; - ssize_t ret; u32 nr, i; char *str; /* nr nodes */ - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) return -1; - if (ph->needs_swap) - nr = bswap_32(nr); - nodes = zalloc(sizeof(*nodes) * nr); if (!nodes) return -ENOMEM; @@ -1927,25 +1922,16 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse n = &nodes[i]; /* node number */ - ret = readn(fd, &n->node, sizeof(u32)); - if (ret != sizeof(n->node)) + if (do_read_u32(ff, &n->node)) goto error; - ret = readn(fd, &n->mem_total, sizeof(u64)); - if (ret != sizeof(u64)) + if (do_read_u64(ff, &n->mem_total)) goto error; - ret = readn(fd, &n->mem_free, sizeof(u64)); - if (ret != sizeof(u64)) + if (do_read_u64(ff, &n->mem_free)) goto error; - if (ph->needs_swap) { - n->node = bswap_32(n->node); - n->mem_total = bswap_64(n->mem_total); - n->mem_free = bswap_64(n->mem_free); - } - - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1955,8 +1941,8 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse free(str); } - ph->env.nr_numa_nodes = nr; - ph->env.numa_nodes = nodes; + ff->ph->env.nr_numa_nodes = nr; + ff->ph->env.numa_nodes = nodes; return 0; error: @@ -1964,39 +1950,30 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse return -1; } -static int process_pmu_mappings(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_pmu_mappings(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; char *name; u32 pmu_num; u32 type; struct strbuf sb; - ret = readn(fd, &pmu_num, sizeof(pmu_num)); - if (ret != sizeof(pmu_num)) + if (do_read_u32(ff, &pmu_num)) return -1; - if (ph->needs_swap) - pmu_num = bswap_32(pmu_num); - if (!pmu_num) { pr_debug("pmu mappings not available\n"); return 0; } - ph->env.nr_pmu_mappings = pmu_num; + ff->ph->env.nr_pmu_mappings = pmu_num; if (strbuf_init(&sb, 128) < 0) return -1; while (pmu_num) { - if (readn(fd, &type, sizeof(type)) != sizeof(type)) + if (do_read_u32(ff, &type)) goto error; - if (ph->needs_swap) - type = bswap_32(type); - name = do_read_string(fd, ph); + name = do_read_string(ff); if (!name) goto error; @@ -2007,12 +1984,12 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused goto error; if (!strcmp(name, "msr")) - ph->env.msr_pmu_type = type; + ff->ph->env.msr_pmu_type = type; free(name); pmu_num--; } - ph->env.pmu_mappings = strbuf_detach(&sb, NULL); + ff->ph->env.pmu_mappings = strbuf_detach(&sb, NULL); return 0; error: @@ -2020,9 +1997,7 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused return -1; } -static int process_group_desc(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused) { size_t ret = -1; u32 i, nr, nr_groups; @@ -2034,13 +2009,10 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, u32 nr_members; } *desc; - if (readn(fd, &nr_groups, sizeof(nr_groups)) != sizeof(nr_groups)) + if (do_read_u32(ff, &nr_groups)) return -1; - if (ph->needs_swap) - nr_groups = bswap_32(nr_groups); - - ph->env.nr_groups = nr_groups; + ff->ph->env.nr_groups = nr_groups; if (!nr_groups) { pr_debug("group desc not available\n"); return 0; @@ -2051,26 +2023,21 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, return -1; for (i = 0; i < nr_groups; i++) { - desc[i].name = do_read_string(fd, ph); + desc[i].name = do_read_string(ff); if (!desc[i].name) goto out_free; - if (readn(fd, &desc[i].leader_idx, sizeof(u32)) != sizeof(u32)) + if (do_read_u32(ff, &desc[i].leader_idx)) goto out_free; - if (readn(fd, &desc[i].nr_members, sizeof(u32)) != sizeof(u32)) + if (do_read_u32(ff, &desc[i].nr_members)) goto out_free; - - if (ph->needs_swap) { - desc[i].leader_idx = bswap_32(desc[i].leader_idx); - desc[i].nr_members = bswap_32(desc[i].nr_members); - } } /* * Rebuild group relationship based on the group_desc */ - session = container_of(ph, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); session->evlist->nr_groups = nr_groups; i = nr = 0; @@ -2114,44 +2081,34 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, return ret; } -static int process_auxtrace(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_auxtrace(struct feat_fd *ff, void *data __maybe_unused) { struct perf_session *session; int err; - session = container_of(ph, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); - err = auxtrace_index__process(fd, section->size, session, - ph->needs_swap); + err = auxtrace_index__process(ff->fd, ff->size, session, + ff->ph->needs_swap); if (err < 0) pr_err("Failed to process auxtrace index\n"); return err; } -static int process_cache(struct perf_file_section *section __maybe_unused, - struct perf_header *ph __maybe_unused, int fd __maybe_unused, - void *data __maybe_unused) +static int process_cache(struct feat_fd *ff, void *data __maybe_unused) { struct cpu_cache_level *caches; u32 cnt, i, version; - if (readn(fd, &version, sizeof(version)) != sizeof(version)) + if (do_read_u32(ff, &version)) return -1; - if (ph->needs_swap) - version = bswap_32(version); - if (version != 1) return -1; - if (readn(fd, &cnt, sizeof(cnt)) != sizeof(cnt)) + if (do_read_u32(ff, &cnt)) return -1; - if (ph->needs_swap) - cnt = bswap_32(cnt); - caches = zalloc(sizeof(*caches) * cnt); if (!caches) return -1; @@ -2160,10 +2117,8 @@ static int process_cache(struct perf_file_section *section __maybe_unused, struct cpu_cache_level c; #define _R(v) \ - if (readn(fd, &c.v, sizeof(u32)) != sizeof(u32))\ + if (do_read_u32(ff, &c.v))\ goto out_free_caches; \ - if (ph->needs_swap) \ - c.v = bswap_32(c.v); \ _R(level) _R(line_size) @@ -2171,9 +2126,9 @@ static int process_cache(struct perf_file_section *section __maybe_unused, _R(ways) #undef _R - #define _R(v) \ - c.v = do_read_string(fd, ph); \ - if (!c.v) \ + #define _R(v) \ + c.v = do_read_string(ff); \ + if (!c.v) \ goto out_free_caches; _R(type) @@ -2184,8 +2139,8 @@ static int process_cache(struct perf_file_section *section __maybe_unused, caches[i] = c; } - ph->env.caches = caches; - ph->env.caches_cnt = cnt; + ff->ph->env.caches = caches; + ff->ph->env.caches_cnt = cnt; return 0; out_free_caches: free(caches); @@ -2193,48 +2148,62 @@ static int process_cache(struct perf_file_section *section __maybe_unused, } struct feature_ops { - int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); - void (*print)(struct perf_header *h, int fd, FILE *fp); - int (*process)(struct perf_file_section *section, - struct perf_header *h, int fd, void *data); + int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); + void (*print)(struct feat_fd *ff, FILE *fp); + int (*process)(struct feat_fd *ff, void *data); const char *name; bool full_only; + bool synthesize; }; -#define FEAT_OPA(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func } -#define FEAT_OPP(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func, \ - .process = process_##func } -#define FEAT_OPF(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func, \ - .process = process_##func, .full_only = true } +#define FEAT_OPR(n, func, __full_only) \ + [HEADER_##n] = { \ + .name = __stringify(n), \ + .write = write_##func, \ + .print = print_##func, \ + .full_only = __full_only, \ + .process = process_##func, \ + .synthesize = true \ + } + +#define FEAT_OPN(n, func, __full_only) \ + [HEADER_##n] = { \ + .name = __stringify(n), \ + .write = write_##func, \ + .print = print_##func, \ + .full_only = __full_only, \ + .process = process_##func \ + } /* feature_ops not implemented: */ #define print_tracing_data NULL #define print_build_id NULL +#define process_branch_stack NULL +#define process_stat NULL + + static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { - FEAT_OPP(HEADER_TRACING_DATA, tracing_data), - FEAT_OPP(HEADER_BUILD_ID, build_id), - FEAT_OPP(HEADER_HOSTNAME, hostname), - FEAT_OPP(HEADER_OSRELEASE, osrelease), - FEAT_OPP(HEADER_VERSION, version), - FEAT_OPP(HEADER_ARCH, arch), - FEAT_OPP(HEADER_NRCPUS, nrcpus), - FEAT_OPP(HEADER_CPUDESC, cpudesc), - FEAT_OPP(HEADER_CPUID, cpuid), - FEAT_OPP(HEADER_TOTAL_MEM, total_mem), - FEAT_OPP(HEADER_EVENT_DESC, event_desc), - FEAT_OPP(HEADER_CMDLINE, cmdline), - FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology), - FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology), - FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), - FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings), - FEAT_OPP(HEADER_GROUP_DESC, group_desc), - FEAT_OPP(HEADER_AUXTRACE, auxtrace), - FEAT_OPA(HEADER_STAT, stat), - FEAT_OPF(HEADER_CACHE, cache), + FEAT_OPN(TRACING_DATA, tracing_data, false), + FEAT_OPN(BUILD_ID, build_id, false), + FEAT_OPR(HOSTNAME, hostname, false), + FEAT_OPR(OSRELEASE, osrelease, false), + FEAT_OPR(VERSION, version, false), + FEAT_OPR(ARCH, arch, false), + FEAT_OPR(NRCPUS, nrcpus, false), + FEAT_OPR(CPUDESC, cpudesc, false), + FEAT_OPR(CPUID, cpuid, false), + FEAT_OPR(TOTAL_MEM, total_mem, false), + FEAT_OPR(EVENT_DESC, event_desc, false), + FEAT_OPR(CMDLINE, cmdline, false), + FEAT_OPR(CPU_TOPOLOGY, cpu_topology, true), + FEAT_OPR(NUMA_TOPOLOGY, numa_topology, true), + FEAT_OPN(BRANCH_STACK, branch_stack, false), + FEAT_OPR(PMU_MAPPINGS, pmu_mappings, false), + FEAT_OPN(GROUP_DESC, group_desc, false), + FEAT_OPN(AUXTRACE, auxtrace, false), + FEAT_OPN(STAT, stat, false), + FEAT_OPN(CACHE, cache, true), }; struct header_print_data { @@ -2247,6 +2216,7 @@ static int perf_file_section__fprintf_info(struct perf_file_section *section, int feat, int fd, void *data) { struct header_print_data *hd = data; + struct feat_fd ff; if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { pr_debug("Failed to lseek to %" PRIu64 " offset for feature " @@ -2260,8 +2230,13 @@ static int perf_file_section__fprintf_info(struct perf_file_section *section, if (!feat_ops[feat].print) return 0; + ff = (struct feat_fd) { + .fd = fd, + .ph = ph, + }; + if (!feat_ops[feat].full_only || hd->full) - feat_ops[feat].print(ph, fd, hd->fp); + feat_ops[feat].print(&ff, hd->fp); else fprintf(hd->fp, "# %s info available, use -I to display\n", feat_ops[feat].name); @@ -2302,29 +2277,32 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) return 0; } -static int do_write_feat(int fd, struct perf_header *h, int type, +static int do_write_feat(struct feat_fd *ff, int type, struct perf_file_section **p, struct perf_evlist *evlist) { int err; int ret = 0; - if (perf_header__has_feat(h, type)) { + if (perf_header__has_feat(ff->ph, type)) { if (!feat_ops[type].write) return -1; - (*p)->offset = lseek(fd, 0, SEEK_CUR); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; - err = feat_ops[type].write(fd, h, evlist); + (*p)->offset = lseek(ff->fd, 0, SEEK_CUR); + + err = feat_ops[type].write(ff, evlist); if (err < 0) { pr_debug("failed to write feature %s\n", feat_ops[type].name); /* undo anything written */ - lseek(fd, (*p)->offset, SEEK_SET); + lseek(ff->fd, (*p)->offset, SEEK_SET); return -1; } - (*p)->size = lseek(fd, 0, SEEK_CUR) - (*p)->offset; + (*p)->size = lseek(ff->fd, 0, SEEK_CUR) - (*p)->offset; (*p)++; } return ret; @@ -2334,12 +2312,18 @@ static int perf_header__adds_write(struct perf_header *header, struct perf_evlist *evlist, int fd) { int nr_sections; + struct feat_fd ff; struct perf_file_section *feat_sec, *p; int sec_size; u64 sec_start; int feat; int err; + ff = (struct feat_fd){ + .fd = fd, + .ph = header, + }; + nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS); if (!nr_sections) return 0; @@ -2354,7 +2338,7 @@ static int perf_header__adds_write(struct perf_header *header, lseek(fd, sec_start + sec_size, SEEK_SET); for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { - if (do_write_feat(fd, header, feat, &p, evlist)) + if (do_write_feat(&ff, feat, &p, evlist)) perf_header__clear_feat(header, feat); } @@ -2363,7 +2347,7 @@ static int perf_header__adds_write(struct perf_header *header, * may write more than needed due to dropped feature, but * this is okay, reader will skip the mising entries */ - err = do_write(fd, feat_sec, sec_size); + err = do_write(&ff, feat_sec, sec_size); if (err < 0) pr_debug("failed to write feature section\n"); free(feat_sec); @@ -2373,14 +2357,17 @@ static int perf_header__adds_write(struct perf_header *header, int perf_header__write_pipe(int fd) { struct perf_pipe_file_header f_header; + struct feat_fd ff; int err; + ff = (struct feat_fd){ .fd = fd }; + f_header = (struct perf_pipe_file_header){ .magic = PERF_MAGIC, .size = sizeof(f_header), }; - err = do_write(fd, &f_header, sizeof(f_header)); + err = do_write(&ff, &f_header, sizeof(f_header)); if (err < 0) { pr_debug("failed to write perf pipe header\n"); return err; @@ -2397,21 +2384,23 @@ int perf_session__write_header(struct perf_session *session, struct perf_file_attr f_attr; struct perf_header *header = &session->header; struct perf_evsel *evsel; + struct feat_fd ff; u64 attr_offset; int err; + ff = (struct feat_fd){ .fd = fd}; lseek(fd, sizeof(f_header), SEEK_SET); evlist__for_each_entry(session->evlist, evsel) { evsel->id_offset = lseek(fd, 0, SEEK_CUR); - err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); + err = do_write(&ff, evsel->id, evsel->ids * sizeof(u64)); if (err < 0) { pr_debug("failed to write perf header\n"); return err; } } - attr_offset = lseek(fd, 0, SEEK_CUR); + attr_offset = lseek(ff.fd, 0, SEEK_CUR); evlist__for_each_entry(evlist, evsel) { f_attr = (struct perf_file_attr){ @@ -2421,7 +2410,7 @@ int perf_session__write_header(struct perf_session *session, .size = evsel->ids * sizeof(u64), } }; - err = do_write(fd, &f_attr, sizeof(f_attr)); + err = do_write(&ff, &f_attr, sizeof(f_attr)); if (err < 0) { pr_debug("failed to write perf header attribute\n"); return err; @@ -2456,7 +2445,7 @@ int perf_session__write_header(struct perf_session *session, memcpy(&f_header.adds_features, &header->adds_features, sizeof(header->adds_features)); lseek(fd, 0, SEEK_SET); - err = do_write(fd, &f_header, sizeof(f_header)); + err = do_write(&ff, &f_header, sizeof(f_header)); if (err < 0) { pr_debug("failed to write perf header\n"); return err; @@ -2710,6 +2699,13 @@ static int perf_file_section__process(struct perf_file_section *section, struct perf_header *ph, int feat, int fd, void *data) { + struct feat_fd fdd = { + .fd = fd, + .ph = ph, + .size = section->size, + .offset = section->offset, + }; + if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { pr_debug("Failed to lseek to %" PRIu64 " offset for feature " "%d, continuing...\n", section->offset, feat); @@ -2724,13 +2720,17 @@ static int perf_file_section__process(struct perf_file_section *section, if (!feat_ops[feat].process) return 0; - return feat_ops[feat].process(section, ph, fd, data); + return feat_ops[feat].process(&fdd, data); } static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, struct perf_header *ph, int fd, bool repipe) { + struct feat_fd ff = { + .fd = STDOUT_FILENO, + .ph = ph, + }; ssize_t ret; ret = readn(fd, header, sizeof(*header)); @@ -2745,7 +2745,7 @@ static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, if (ph->needs_swap) header->size = bswap_64(header->size); - if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0) + if (repipe && do_write(&ff, header, sizeof(*header)) < 0) return -1; return 0; @@ -2995,6 +2995,103 @@ int perf_event__synthesize_attr(struct perf_tool *tool, return err; } +int perf_event__synthesize_features(struct perf_tool *tool, + struct perf_session *session, + struct perf_evlist *evlist, + perf_event__handler_t process) +{ + struct perf_header *header = &session->header; + struct feat_fd ff; + struct feature_event *fe; + size_t sz, sz_hdr; + int feat, ret; + + sz_hdr = sizeof(fe->header); + sz = sizeof(union perf_event); + /* get a nice alignment */ + sz = PERF_ALIGN(sz, page_size); + + memset(&ff, 0, sizeof(ff)); + + ff.buf = malloc(sz); + if (!ff.buf) + return -ENOMEM; + + ff.size = sz - sz_hdr; + + for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { + if (!feat_ops[feat].synthesize) { + pr_debug("No record header feature for header :%d\n", feat); + continue; + } + + ff.offset = sizeof(*fe); + + ret = feat_ops[feat].write(&ff, evlist); + if (ret || ff.offset <= (ssize_t)sizeof(*fe)) { + pr_debug("Error writing feature\n"); + continue; + } + /* ff.buf may have changed due to realloc in do_write() */ + fe = ff.buf; + memset(fe, 0, sizeof(*fe)); + + fe->feat_id = feat; + fe->header.type = PERF_RECORD_HEADER_FEATURE; + fe->header.size = ff.offset; + + ret = process(tool, ff.buf, NULL, NULL); + if (ret) { + free(ff.buf); + return ret; + } + } + free(ff.buf); + return 0; +} + +int perf_event__process_feature(struct perf_tool *tool, + union perf_event *event, + struct perf_session *session __maybe_unused) +{ + struct feat_fd ff = { .fd = 0 }; + struct feature_event *fe = (struct feature_event *)event; + int type = fe->header.type; + u64 feat = fe->feat_id; + + if (type < 0 || type >= PERF_RECORD_HEADER_MAX) { + pr_warning("invalid record type %d in pipe-mode\n", type); + return 0; + } + if (feat == HEADER_RESERVED || feat > HEADER_LAST_FEATURE) { + pr_warning("invalid record type %d in pipe-mode\n", type); + return -1; + } + + if (!feat_ops[feat].process) + return 0; + + ff.buf = (void *)fe->data; + ff.size = event->header.size - sizeof(event->header); + ff.ph = &session->header; + + if (feat_ops[feat].process(&ff, NULL)) + return -1; + + if (!feat_ops[feat].print || !tool->show_feat_hdr) + return 0; + + if (!feat_ops[feat].full_only || + tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) { + feat_ops[feat].print(&ff, stdout); + } else { + fprintf(stdout, "# %s info available, use -I to display\n", + feat_ops[feat].name); + } + + return 0; +} + static struct event_update_event * event_update_event__new(size_t size, u64 type, u64 id) { @@ -3253,6 +3350,7 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, union perf_event ev; struct tracing_data *tdata; ssize_t size = 0, aligned_size = 0, padding; + struct feat_fd ff; int err __maybe_unused = 0; /* @@ -3287,7 +3385,9 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, */ tracing_data_put(tdata); - write_padded(fd, NULL, 0, padding); + ff = (struct feat_fd){ .fd = fd }; + if (write_padded(&ff, NULL, 0, padding)) + return -1; return aligned_size; } diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index d30109b421eef0efb6820e8c8cc036a53dbb7ff3..f7a16ee527b8ae7bcae8f0b17f2e49237824fa84 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -101,6 +101,15 @@ int perf_header__process_sections(struct perf_header *header, int fd, int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full); +int perf_event__synthesize_features(struct perf_tool *tool, + struct perf_session *session, + struct perf_evlist *evlist, + perf_event__handler_t process); + +int perf_event__process_feature(struct perf_tool *tool, + union perf_event *event, + struct perf_session *session); + int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process); @@ -144,7 +153,12 @@ bool is_perf_magic(u64 magic); #define NAME_ALIGN 64 -int write_padded(int fd, const void *bf, size_t count, size_t count_aligned); +struct feat_fd; + +int do_write(struct feat_fd *fd, const void *buf, size_t size); + +int write_padded(struct feat_fd *fd, const void *bf, + size_t count, size_t count_aligned); /* * arch specific callback diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index cf0186a088c17f90c2357f1694af2241addf4eef..e60d8d8ea4c23084240d0ca156205b102d8e789c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -167,6 +167,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) symlen = unresolved_col_width + 4 + 2; hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO); } + + hists__new_col_len(hists, HISTC_MEM_PHYS_DADDR, + unresolved_col_width + 4 + 2); + } else { symlen = unresolved_col_width + 4 + 2; hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen); @@ -749,12 +753,9 @@ iter_prepare_branch_entry(struct hist_entry_iter *iter, struct addr_location *al } static int -iter_add_single_branch_entry(struct hist_entry_iter *iter, +iter_add_single_branch_entry(struct hist_entry_iter *iter __maybe_unused, struct addr_location *al __maybe_unused) { - /* to avoid calling callback function */ - iter->he = NULL; - return 0; } @@ -1762,6 +1763,8 @@ void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *pro else use_callchain = symbol_conf.use_callchain; + use_callchain |= symbol_conf.show_branchflag_count; + output_resort(evsel__hists(evsel), prog, use_callchain, NULL); } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ee3670a388df8f825fd6c79cb698e5fb6d7e5695..e60dda26a9207c08c0dd399e6d04588fb7302a2a 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -47,6 +47,7 @@ enum hist_column { HISTC_GLOBAL_WEIGHT, HISTC_MEM_DADDR_SYMBOL, HISTC_MEM_DADDR_DSO, + HISTC_MEM_PHYS_DADDR, HISTC_MEM_LOCKED, HISTC_MEM_TLB, HISTC_MEM_LVL, diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index 7aca5d6d7e1f05ded3ee5353358d9b4f7a71ee3e..10e0814bb8d2ca6537d4c0856ddc5eaa0a9478d0 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build @@ -25,6 +25,6 @@ $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/in CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -ifneq ($(CC), clang) +ifeq ($(CC_NO_CLANG), 1) CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init endif diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index c6a15f204c03827bec7fa4cfdf879d8d9d5b89fc..209b0c82eff4660ad0612be724786fb73a0881e2 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -33,7 +33,7 @@ struct llvm_param llvm_param = { int perf_llvm_config(const char *var, const char *value) { - if (prefixcmp(var, "llvm.")) + if (!strstarts(var, "llvm.")) return 0; var += sizeof("llvm.") - 1; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 2e9eb6aa3ce2e15ccc3a60506de1b1072e2da7d9..df709363ef6902793376fee70027c41c04d06f7a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -705,7 +705,8 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) if (kdso->has_build_id) { char filename[PATH_MAX]; - if (dso__build_id_filename(kdso, filename, sizeof(filename))) + if (dso__build_id_filename(kdso, filename, sizeof(filename), + false)) printed += fprintf(fp, "[0] %s\n", filename); } @@ -1137,7 +1138,8 @@ int __weak arch__fix_module_text_start(u64 *start __maybe_unused, return 0; } -static int machine__create_module(void *arg, const char *name, u64 start) +static int machine__create_module(void *arg, const char *name, u64 start, + u64 size) { struct machine *machine = arg; struct map *map; @@ -1148,6 +1150,7 @@ static int machine__create_module(void *arg, const char *name, u64 start) map = machine__findnew_module_map(machine, start, name); if (map == NULL) return -1; + map->end = start + size; dso__kernel_module_get_build_id(map->dso, machine->root_dir); @@ -1392,7 +1395,7 @@ int machine__process_mmap2_event(struct machine *machine, map = map__new(machine, event->mmap2.start, event->mmap2.len, event->mmap2.pgoff, - event->mmap2.pid, event->mmap2.maj, + event->mmap2.maj, event->mmap2.min, event->mmap2.ino, event->mmap2.ino_generation, event->mmap2.prot, @@ -1450,7 +1453,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event map = map__new(machine, event->mmap.start, event->mmap.len, event->mmap.pgoff, - event->mmap.pid, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, event->mmap.filename, type, thread); @@ -1632,10 +1635,12 @@ static void ip__resolve_ams(struct thread *thread, ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; + ams->phys_addr = 0; } static void ip__resolve_data(struct thread *thread, - u8 m, struct addr_map_symbol *ams, u64 addr) + u8 m, struct addr_map_symbol *ams, + u64 addr, u64 phys_addr) { struct addr_location al; @@ -1655,6 +1660,7 @@ static void ip__resolve_data(struct thread *thread, ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; + ams->phys_addr = phys_addr; } struct mem_info *sample__resolve_mem(struct perf_sample *sample, @@ -1666,12 +1672,18 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, return NULL; ip__resolve_ams(al->thread, &mi->iaddr, sample->ip); - ip__resolve_data(al->thread, al->cpumode, &mi->daddr, sample->addr); + ip__resolve_data(al->thread, al->cpumode, &mi->daddr, + sample->addr, sample->phys_addr); mi->data_src.val = sample->data_src; return mi; } +struct iterations { + int nr_loop_iter; + u64 cycles; +}; + static int add_callchain_ip(struct thread *thread, struct callchain_cursor *cursor, struct symbol **parent, @@ -1680,10 +1692,12 @@ static int add_callchain_ip(struct thread *thread, u64 ip, bool branch, struct branch_flags *flags, - int nr_loop_iter, - int samples) + struct iterations *iter, + u64 branch_from) { struct addr_location al; + int nr_loop_iter = 0; + u64 iter_cycles = 0; al.filtered = 0; al.sym = NULL; @@ -1733,8 +1747,15 @@ static int add_callchain_ip(struct thread *thread, if (symbol_conf.hide_unresolved && al.sym == NULL) return 0; + + if (iter) { + nr_loop_iter = iter->nr_loop_iter; + iter_cycles = iter->cycles; + } + return callchain_cursor_append(cursor, al.addr, al.map, al.sym, - branch, flags, nr_loop_iter, samples); + branch, flags, nr_loop_iter, + iter_cycles, branch_from); } struct branch_info *sample__resolve_bstack(struct perf_sample *sample, @@ -1755,6 +1776,18 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, return bi; } +static void save_iterations(struct iterations *iter, + struct branch_entry *be, int nr) +{ + int i; + + iter->nr_loop_iter = nr; + iter->cycles = 0; + + for (i = 0; i < nr; i++) + iter->cycles += be[i].flags.cycles; +} + #define CHASHSZ 127 #define CHASHBITS 7 #define NO_ENTRY 0xff @@ -1762,7 +1795,8 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, #define PERF_MAX_BRANCH_DEPTH 127 /* Remove loops. */ -static int remove_loops(struct branch_entry *l, int nr) +static int remove_loops(struct branch_entry *l, int nr, + struct iterations *iter) { int i, j, off; unsigned char chash[CHASHSZ]; @@ -1787,8 +1821,18 @@ static int remove_loops(struct branch_entry *l, int nr) break; } if (is_loop) { - memmove(l + i, l + i + off, - (nr - (i + off)) * sizeof(*l)); + j = nr - (i + off); + if (j > 0) { + save_iterations(iter + i + off, + l + i, off); + + memmove(iter + i, iter + i + off, + j * sizeof(*iter)); + + memmove(l + i, l + i + off, + j * sizeof(*l)); + } + nr -= off; } } @@ -1813,7 +1857,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, struct ip_callchain *chain = sample->callchain; int chain_nr = min(max_stack, (int)chain->nr), i; u8 cpumode = PERF_RECORD_MISC_USER; - u64 ip; + u64 ip, branch_from = 0; for (i = 0; i < chain_nr; i++) { if (chain->ips[i] == PERF_CONTEXT_USER) @@ -1855,6 +1899,8 @@ static int resolve_lbr_callchain_sample(struct thread *thread, ip = lbr_stack->entries[0].to; branch = true; flags = &lbr_stack->entries[0].flags; + branch_from = + lbr_stack->entries[0].from; } } else { if (j < lbr_nr) { @@ -1869,12 +1915,15 @@ static int resolve_lbr_callchain_sample(struct thread *thread, ip = lbr_stack->entries[0].to; branch = true; flags = &lbr_stack->entries[0].flags; + branch_from = + lbr_stack->entries[0].from; } } err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, - branch, flags, 0, 0); + branch, flags, NULL, + branch_from); if (err) return (err < 0) ? err : 0; } @@ -1894,12 +1943,14 @@ static int thread__resolve_callchain_sample(struct thread *thread, { struct branch_stack *branch = sample->branch_stack; struct ip_callchain *chain = sample->callchain; - int chain_nr = chain->nr; + int chain_nr = 0; u8 cpumode = PERF_RECORD_MISC_USER; int i, j, err, nr_entries; int skip_idx = -1; int first_call = 0; - int nr_loop_iter; + + if (chain) + chain_nr = chain->nr; if (perf_evsel__has_branch_callstack(evsel)) { err = resolve_lbr_callchain_sample(thread, cursor, sample, parent, @@ -1929,6 +1980,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, if (branch && callchain_param.branch_callstack) { int nr = min(max_stack, (int)branch->nr); struct branch_entry be[nr]; + struct iterations iter[nr]; if (branch->nr > PERF_MAX_BRANCH_DEPTH) { pr_warning("corrupted branch chain. skipping...\n"); @@ -1938,6 +1990,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, for (i = 0; i < nr; i++) { if (callchain_param.order == ORDER_CALLEE) { be[i] = branch->entries[i]; + + if (chain == NULL) + continue; + /* * Check for overlap into the callchain. * The return address is one off compared to @@ -1955,42 +2011,30 @@ static int thread__resolve_callchain_sample(struct thread *thread, be[i] = branch->entries[branch->nr - i - 1]; } - nr_loop_iter = nr; - nr = remove_loops(be, nr); - - /* - * Get the number of iterations. - * It's only approximation, but good enough in practice. - */ - if (nr_loop_iter > nr) - nr_loop_iter = nr_loop_iter - nr + 1; - else - nr_loop_iter = 0; + memset(iter, 0, sizeof(struct iterations) * nr); + nr = remove_loops(be, nr, iter); for (i = 0; i < nr; i++) { - if (i == nr - 1) - err = add_callchain_ip(thread, cursor, parent, - root_al, - NULL, be[i].to, - true, &be[i].flags, - nr_loop_iter, 1); - else - err = add_callchain_ip(thread, cursor, parent, - root_al, - NULL, be[i].to, - true, &be[i].flags, - 0, 0); + err = add_callchain_ip(thread, cursor, parent, + root_al, + NULL, be[i].to, + true, &be[i].flags, + NULL, be[i].from); if (!err) err = add_callchain_ip(thread, cursor, parent, root_al, NULL, be[i].from, true, &be[i].flags, - 0, 0); + &iter[i], 0); if (err == -EINVAL) break; if (err) return err; } + + if (chain_nr == 0) + return 0; + chain_nr -= nr; } @@ -2015,7 +2059,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, - false, NULL, 0, 0); + false, NULL, NULL, 0); if (err) return (err < 0) ? err : 0; @@ -2032,7 +2076,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) return 0; return callchain_cursor_append(cursor, entry->ip, entry->map, entry->sym, - false, NULL, 0, 0); + false, NULL, 0, 0, 0); } static int thread__resolve_callchain_unwind(struct thread *thread, diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 2179b2deb7307c749fb171e48c784e4bc158b028..bdaa0a4edc17e344bdcae3a08dade7b276a6f5ee 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -16,6 +16,7 @@ #include "machine.h" #include #include "srcline.h" +#include "namespaces.h" #include "unwind.h" static void __maps__insert(struct maps *maps, struct map *map); @@ -145,11 +146,13 @@ void map__init(struct map *map, enum map_type type, } struct map *map__new(struct machine *machine, u64 start, u64 len, - u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, + u64 pgoff, u32 d_maj, u32 d_min, u64 ino, u64 ino_gen, u32 prot, u32 flags, char *filename, enum map_type type, struct thread *thread) { struct map *map = malloc(sizeof(*map)); + struct nsinfo *nsi = NULL; + struct nsinfo *nnsi; if (map != NULL) { char newfilename[PATH_MAX]; @@ -167,9 +170,11 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, map->ino_generation = ino_gen; map->prot = prot; map->flags = flags; + nsi = nsinfo__get(thread->nsinfo); - if ((anon || no_dso) && type == MAP__FUNCTION) { - snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); + if ((anon || no_dso) && nsi && type == MAP__FUNCTION) { + snprintf(newfilename, sizeof(newfilename), + "/tmp/perf-%d.map", nsi->pid); filename = newfilename; } @@ -179,6 +184,16 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, } if (vdso) { + /* The vdso maps are always on the host and not the + * container. Ensure that we don't use setns to look + * them up. + */ + nnsi = nsinfo__copy(nsi); + if (nnsi) { + nsinfo__put(nsi); + nnsi->need_setns = false; + nsi = nnsi; + } pgoff = 0; dso = machine__findnew_vdso(machine, thread); } else @@ -200,10 +215,12 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (type != MAP__FUNCTION) dso__set_loaded(dso, map->type); } + dso->nsinfo = nsi; dso__put(dso); } return map; out_delete: + nsinfo__put(nsi); free(map); return NULL; } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index f9e8ac8a52cde5fefb74cb87464c1346e3d08431..73aacf7a7dc4b0772f4021760d21b6efca12c327 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -141,7 +141,7 @@ struct thread; void map__init(struct map *map, enum map_type type, u64 start, u64 end, u64 pgoff, struct dso *dso); struct map *map__new(struct machine *machine, u64 start, u64 len, - u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, + u64 pgoff, u32 d_maj, u32 d_min, u64 ino, u64 ino_gen, u32 prot, u32 flags, char *filename, enum map_type type, struct thread *thread); struct map *map__new2(u64 start, struct dso *dso, enum map_type type); diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c index 06f5a3a4295c52cac138ac2526afdac04ffbf0dc..28afe5fa84d613641954515ef89ed29441ec0cd4 100644 --- a/tools/perf/util/mem-events.c +++ b/tools/perf/util/mem-events.c @@ -166,11 +166,20 @@ static const char * const mem_lvl[] = { "Uncached", }; +static const char * const mem_lvlnum[] = { + [PERF_MEM_LVLNUM_ANY_CACHE] = "Any cache", + [PERF_MEM_LVLNUM_LFB] = "LFB", + [PERF_MEM_LVLNUM_RAM] = "RAM", + [PERF_MEM_LVLNUM_PMEM] = "PMEM", + [PERF_MEM_LVLNUM_NA] = "N/A", +}; + int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info) { size_t i, l = 0; u64 m = PERF_MEM_LVL_NA; u64 hit, miss; + int printed; if (mem_info) m = mem_info->data_src.mem_lvl; @@ -184,17 +193,37 @@ int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info) /* already taken care of */ m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS); + + if (mem_info && mem_info->data_src.mem_remote) { + strcat(out, "Remote "); + l += 7; + } + + printed = 0; for (i = 0; m && i < ARRAY_SIZE(mem_lvl); i++, m >>= 1) { if (!(m & 0x1)) continue; - if (l) { + if (printed++) { strcat(out, " or "); l += 4; } l += scnprintf(out + l, sz - l, mem_lvl[i]); } - if (*out == '\0') - l += scnprintf(out, sz - l, "N/A"); + + if (mem_info && mem_info->data_src.mem_lvl_num) { + int lvl = mem_info->data_src.mem_lvl_num; + if (printed++) { + strcat(out, " or "); + l += 4; + } + if (mem_lvlnum[lvl]) + l += scnprintf(out + l, sz - l, mem_lvlnum[lvl]); + else + l += scnprintf(out + l, sz - l, "L%d", lvl); + } + + if (l == 0) + l += scnprintf(out + l, sz - l, "N/A"); if (hit) l += scnprintf(out + l, sz - l, " hit"); if (miss) @@ -231,6 +260,14 @@ int perf_mem__snp_scnprintf(char *out, size_t sz, struct mem_info *mem_info) } l += scnprintf(out + l, sz - l, snoop_access[i]); } + if (mem_info && + (mem_info->data_src.mem_snoopx & PERF_MEM_SNOOPX_FWD)) { + if (l) { + strcat(out, " or "); + l += 4; + } + l += scnprintf(out + l, sz - l, "Fwd"); + } if (*out == '\0') l += scnprintf(out, sz - l, "N/A"); @@ -279,6 +316,11 @@ int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi) u64 lvl = data_src->mem_lvl; u64 snoop = data_src->mem_snoop; u64 lock = data_src->mem_lock; + /* + * Skylake might report unknown remote level via this + * bit, consider it when evaluating remote HITMs. + */ + bool mrem = data_src->mem_remote; int err = 0; #define HITM_INC(__f) \ @@ -324,7 +366,8 @@ do { \ } if ((lvl & P(LVL, REM_RAM1)) || - (lvl & P(LVL, REM_RAM2))) { + (lvl & P(LVL, REM_RAM2)) || + mrem) { stats->rmt_dram++; if (snoop & P(SNOOP, HIT)) stats->ld_shared++; @@ -334,7 +377,8 @@ do { \ } if ((lvl & P(LVL, REM_CCE1)) || - (lvl & P(LVL, REM_CCE2))) { + (lvl & P(LVL, REM_CCE2)) || + mrem) { if (snoop & P(SNOOP, HIT)) stats->rmt_hit++; else if (snoop & P(SNOOP, HITM)) diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 67dcbcc73c7dcdd95da8af4d45e3257d38123147..a58e91197729a40305d071809b95d83b49bc8548 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -9,9 +9,14 @@ #include "namespaces.h" #include "util.h" #include "event.h" +#include +#include +#include +#include #include #include #include +#include struct namespaces *namespaces__new(struct namespaces_event *event) { @@ -35,3 +40,209 @@ void namespaces__free(struct namespaces *namespaces) { free(namespaces); } + +int nsinfo__init(struct nsinfo *nsi) +{ + char oldns[PATH_MAX]; + char spath[PATH_MAX]; + char *newns = NULL; + char *statln = NULL; + struct stat old_stat; + struct stat new_stat; + FILE *f = NULL; + size_t linesz = 0; + int rv = -1; + + if (snprintf(oldns, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX) + return rv; + + if (asprintf(&newns, "/proc/%d/ns/mnt", nsi->pid) == -1) + return rv; + + if (stat(oldns, &old_stat) < 0) + goto out; + + if (stat(newns, &new_stat) < 0) + goto out; + + /* Check if the mount namespaces differ, if so then indicate that we + * want to switch as part of looking up dso/map data. + */ + if (old_stat.st_ino != new_stat.st_ino) { + nsi->need_setns = true; + nsi->mntns_path = newns; + newns = NULL; + } + + /* If we're dealing with a process that is in a different PID namespace, + * attempt to work out the innermost tgid for the process. + */ + if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsi->pid) >= PATH_MAX) + goto out; + + f = fopen(spath, "r"); + if (f == NULL) + goto out; + + while (getline(&statln, &linesz, f) != -1) { + /* Use tgid if CONFIG_PID_NS is not defined. */ + if (strstr(statln, "Tgid:") != NULL) { + nsi->tgid = (pid_t)strtol(strrchr(statln, '\t'), + NULL, 10); + nsi->nstgid = nsi->tgid; + } + + if (strstr(statln, "NStgid:") != NULL) { + nsi->nstgid = (pid_t)strtol(strrchr(statln, '\t'), + NULL, 10); + break; + } + } + rv = 0; + +out: + if (f != NULL) + (void) fclose(f); + free(statln); + free(newns); + return rv; +} + +struct nsinfo *nsinfo__new(pid_t pid) +{ + struct nsinfo *nsi; + + if (pid == 0) + return NULL; + + nsi = calloc(1, sizeof(*nsi)); + if (nsi != NULL) { + nsi->pid = pid; + nsi->tgid = pid; + nsi->nstgid = pid; + nsi->need_setns = false; + /* Init may fail if the process exits while we're trying to look + * at its proc information. In that case, save the pid but + * don't try to enter the namespace. + */ + if (nsinfo__init(nsi) == -1) + nsi->need_setns = false; + + refcount_set(&nsi->refcnt, 1); + } + + return nsi; +} + +struct nsinfo *nsinfo__copy(struct nsinfo *nsi) +{ + struct nsinfo *nnsi; + + nnsi = calloc(1, sizeof(*nnsi)); + if (nnsi != NULL) { + nnsi->pid = nsi->pid; + nnsi->tgid = nsi->tgid; + nnsi->nstgid = nsi->nstgid; + nnsi->need_setns = nsi->need_setns; + if (nsi->mntns_path) { + nnsi->mntns_path = strdup(nsi->mntns_path); + if (!nnsi->mntns_path) { + free(nnsi); + return NULL; + } + } + refcount_set(&nnsi->refcnt, 1); + } + + return nnsi; +} + +void nsinfo__delete(struct nsinfo *nsi) +{ + zfree(&nsi->mntns_path); + free(nsi); +} + +struct nsinfo *nsinfo__get(struct nsinfo *nsi) +{ + if (nsi) + refcount_inc(&nsi->refcnt); + return nsi; +} + +void nsinfo__put(struct nsinfo *nsi) +{ + if (nsi && refcount_dec_and_test(&nsi->refcnt)) + nsinfo__delete(nsi); +} + +void nsinfo__mountns_enter(struct nsinfo *nsi, + struct nscookie *nc) +{ + char curpath[PATH_MAX]; + int oldns = -1; + int newns = -1; + + if (nc == NULL) + return; + + nc->oldns = -1; + nc->newns = -1; + + if (!nsi || !nsi->need_setns) + return; + + if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX) + return; + + oldns = open(curpath, O_RDONLY); + if (oldns < 0) + return; + + newns = open(nsi->mntns_path, O_RDONLY); + if (newns < 0) + goto errout; + + if (setns(newns, CLONE_NEWNS) < 0) + goto errout; + + nc->oldns = oldns; + nc->newns = newns; + return; + +errout: + if (oldns > -1) + close(oldns); + if (newns > -1) + close(newns); +} + +void nsinfo__mountns_exit(struct nscookie *nc) +{ + if (nc == NULL || nc->oldns == -1 || nc->newns == -1) + return; + + setns(nc->oldns, CLONE_NEWNS); + + if (nc->oldns > -1) { + close(nc->oldns); + nc->oldns = -1; + } + + if (nc->newns > -1) { + close(nc->newns); + nc->newns = -1; + } +} + +char *nsinfo__realpath(const char *path, struct nsinfo *nsi) +{ + char *rpath; + struct nscookie nsc; + + nsinfo__mountns_enter(nsi, &nsc); + rpath = realpath(path, NULL); + nsinfo__mountns_exit(&nsc); + + return rpath; +} diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 468f1e9a1484c0a8e7c20213850990955732cd43..05d82601c9a62574180eb1657dda83a4670c42e9 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -11,6 +11,7 @@ #include "../perf.h" #include +#include struct namespaces_event; @@ -23,4 +24,41 @@ struct namespaces { struct namespaces *namespaces__new(struct namespaces_event *event); void namespaces__free(struct namespaces *namespaces); +struct nsinfo { + pid_t pid; + pid_t tgid; + pid_t nstgid; + bool need_setns; + char *mntns_path; + refcount_t refcnt; +}; + +struct nscookie { + int oldns; + int newns; +}; + +int nsinfo__init(struct nsinfo *nsi); +struct nsinfo *nsinfo__new(pid_t pid); +struct nsinfo *nsinfo__copy(struct nsinfo *nsi); +void nsinfo__delete(struct nsinfo *nsi); + +struct nsinfo *nsinfo__get(struct nsinfo *nsi); +void nsinfo__put(struct nsinfo *nsi); + +void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc); +void nsinfo__mountns_exit(struct nscookie *nc); + +char *nsinfo__realpath(const char *path, struct nsinfo *nsi); + +static inline void __nsinfo__zput(struct nsinfo **nsip) +{ + if (nsip) { + nsinfo__put(*nsip); + *nsip = NULL; + } +} + +#define nsinfo__zput(nsi) __nsinfo__zput(&nsi) + #endif /* __PERF_NAMESPACES_H */ diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 38fd11504015a0753cd738f3a243b0d5d854c5b2..e71fb5f31e84db54672dede30c058eb8fc87129c 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c @@ -28,6 +28,7 @@ static const struct branch_mode branch_modes[] = { BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND), BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP), BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL), + BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE), BRANCH_END }; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 01e779b91c8ef618984fcdb8d68d526b1870828a..f6257fb4f08ceedde23f790b1aae9255f9565d13 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -34,7 +34,7 @@ #ifdef PARSER_DEBUG extern int parse_events_debug; #endif -int parse_events_parse(void *data, void *scanner); +int parse_events_parse(void *parse_state, void *scanner); static int get_config_terms(struct list_head *head_config, struct list_head *head_terms __maybe_unused); @@ -310,7 +310,7 @@ static struct perf_evsel * __add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct cpu_map *cpus, - struct list_head *config_terms) + struct list_head *config_terms, bool auto_merge_stats) { struct perf_evsel *evsel; @@ -324,6 +324,7 @@ __add_event(struct list_head *list, int *idx, evsel->cpus = cpu_map__get(cpus); evsel->own_cpus = cpu_map__get(cpus); evsel->system_wide = !!cpus; + evsel->auto_merge_stats = auto_merge_stats; if (name) evsel->name = strdup(name); @@ -339,7 +340,7 @@ static int add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct list_head *config_terms) { - return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM; + return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM; } static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) @@ -589,7 +590,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx, } struct __add_bpf_event_param { - struct parse_events_evlist *data; + struct parse_events_state *parse_state; struct list_head *list; struct list_head *head_config; }; @@ -599,7 +600,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, { LIST_HEAD(new_evsels); struct __add_bpf_event_param *param = _param; - struct parse_events_evlist *evlist = param->data; + struct parse_events_state *parse_state = param->parse_state; struct list_head *list = param->list; struct perf_evsel *pos; int err; @@ -607,8 +608,8 @@ static int add_bpf_event(const char *group, const char *event, int fd, pr_debug("add bpf event %s:%s and attach bpf program %d\n", group, event, fd); - err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, group, - event, evlist->error, + err = parse_events_add_tracepoint(&new_evsels, &parse_state->idx, group, + event, parse_state->error, param->head_config); if (err) { struct perf_evsel *evsel, *tmp; @@ -632,14 +633,14 @@ static int add_bpf_event(const char *group, const char *event, int fd, return 0; } -int parse_events_load_bpf_obj(struct parse_events_evlist *data, +int parse_events_load_bpf_obj(struct parse_events_state *parse_state, struct list_head *list, struct bpf_object *obj, struct list_head *head_config) { int err; char errbuf[BUFSIZ]; - struct __add_bpf_event_param param = {data, list, head_config}; + struct __add_bpf_event_param param = {parse_state, list, head_config}; static bool registered_unprobe_atexit = false; if (IS_ERR(obj) || !obj) { @@ -680,13 +681,13 @@ int parse_events_load_bpf_obj(struct parse_events_evlist *data, return 0; errout: - data->error->help = strdup("(add -v to see detail)"); - data->error->str = strdup(errbuf); + parse_state->error->help = strdup("(add -v to see detail)"); + parse_state->error->str = strdup(errbuf); return err; } static int -parse_events_config_bpf(struct parse_events_evlist *data, +parse_events_config_bpf(struct parse_events_state *parse_state, struct bpf_object *obj, struct list_head *head_config) { @@ -705,28 +706,28 @@ parse_events_config_bpf(struct parse_events_evlist *data, "Invalid config term for BPF object"); errbuf[BUFSIZ - 1] = '\0'; - data->error->idx = term->err_term; - data->error->str = strdup(errbuf); + parse_state->error->idx = term->err_term; + parse_state->error->str = strdup(errbuf); return -EINVAL; } - err = bpf__config_obj(obj, term, data->evlist, &error_pos); + err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos); if (err) { - bpf__strerror_config_obj(obj, term, data->evlist, + bpf__strerror_config_obj(obj, term, parse_state->evlist, &error_pos, err, errbuf, sizeof(errbuf)); - data->error->help = strdup( + parse_state->error->help = strdup( "Hint:\tValid config terms:\n" " \tmap:[].value=[value]\n" " \tmap:[].event=[event]\n" "\n" " \twhere is something like [0,3...5] or [all]\n" " \t(add -v to see detail)"); - data->error->str = strdup(errbuf); + parse_state->error->str = strdup(errbuf); if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE) - data->error->idx = term->err_val; + parse_state->error->idx = term->err_val; else - data->error->idx = term->err_term + error_pos; + parse_state->error->idx = term->err_term + error_pos; return err; } } @@ -762,7 +763,7 @@ split_bpf_config_terms(struct list_head *evt_head_config, list_move_tail(&term->list, obj_head_config); } -int parse_events_load_bpf(struct parse_events_evlist *data, +int parse_events_load_bpf(struct parse_events_state *parse_state, struct list_head *list, char *bpf_file_name, bool source, @@ -790,15 +791,15 @@ int parse_events_load_bpf(struct parse_events_evlist *data, -err, errbuf, sizeof(errbuf)); - data->error->help = strdup("(add -v to see detail)"); - data->error->str = strdup(errbuf); + parse_state->error->help = strdup("(add -v to see detail)"); + parse_state->error->str = strdup(errbuf); return err; } - err = parse_events_load_bpf_obj(data, list, obj, head_config); + err = parse_events_load_bpf_obj(parse_state, list, obj, head_config); if (err) return err; - err = parse_events_config_bpf(data, obj, &obj_head_config); + err = parse_events_config_bpf(parse_state, obj, &obj_head_config); /* * Caller doesn't know anything about obj_head_config, @@ -1184,7 +1185,7 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx, err, head_config); } -int parse_events_add_numeric(struct parse_events_evlist *data, +int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct list_head *head_config) @@ -1197,7 +1198,7 @@ int parse_events_add_numeric(struct parse_events_evlist *data, attr.config = config; if (head_config) { - if (config_attr(&attr, head_config, data->error, + if (config_attr(&attr, head_config, parse_state->error, config_term_common)) return -EINVAL; @@ -1205,13 +1206,13 @@ int parse_events_add_numeric(struct parse_events_evlist *data, return -ENOMEM; } - return add_event(list, &data->idx, &attr, + return add_event(list, &parse_state->idx, &attr, get_config_name(head_config), &config_terms); } -int parse_events_add_pmu(struct parse_events_evlist *data, +static int __parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, char *name, - struct list_head *head_config) + struct list_head *head_config, bool auto_merge_stats) { struct perf_event_attr attr; struct perf_pmu_info info; @@ -1232,7 +1233,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data, if (!head_config) { attr.type = pmu->type; - evsel = __add_event(list, &data->idx, &attr, NULL, pmu->cpus, NULL); + evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL, auto_merge_stats); return evsel ? 0 : -ENOMEM; } @@ -1243,18 +1244,18 @@ int parse_events_add_pmu(struct parse_events_evlist *data, * Configure hardcoded terms first, no need to check * return value when called with fail == 0 ;) */ - if (config_attr(&attr, head_config, data->error, config_term_pmu)) + if (config_attr(&attr, head_config, parse_state->error, config_term_pmu)) return -EINVAL; if (get_config_terms(head_config, &config_terms)) return -ENOMEM; - if (perf_pmu__config(pmu, &attr, head_config, data->error)) + if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) return -EINVAL; - evsel = __add_event(list, &data->idx, &attr, + evsel = __add_event(list, &parse_state->idx, &attr, get_config_name(head_config), pmu->cpus, - &config_terms); + &config_terms, auto_merge_stats); if (evsel) { evsel->unit = info.unit; evsel->scale = info.scale; @@ -1267,7 +1268,14 @@ int parse_events_add_pmu(struct parse_events_evlist *data, return evsel ? 0 : -ENOMEM; } -int parse_events_multi_pmu_add(struct parse_events_evlist *data, +int parse_events_add_pmu(struct parse_events_state *parse_state, + struct list_head *list, char *name, + struct list_head *head_config) +{ + return __parse_events_add_pmu(parse_state, list, name, head_config, false); +} + +int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp) { struct list_head *head; @@ -1296,8 +1304,8 @@ int parse_events_multi_pmu_add(struct parse_events_evlist *data, return -1; list_add_tail(&term->list, head); - if (!parse_events_add_pmu(data, list, - pmu->name, head)) { + if (!__parse_events_add_pmu(parse_state, list, + pmu->name, head, true)) { pr_debug("%s -> %s/%s/\n", str, pmu->name, alias->str); ok++; @@ -1628,7 +1636,7 @@ perf_pmu__parse_check(const char *name) return r ? r->type : PMU_EVENT_SYMBOL_ERR; } -static int parse_events__scanner(const char *str, void *data, int start_token) +static int parse_events__scanner(const char *str, void *parse_state, int start_token) { YY_BUFFER_STATE buffer; void *scanner; @@ -1643,7 +1651,7 @@ static int parse_events__scanner(const char *str, void *data, int start_token) #ifdef PARSER_DEBUG parse_events_debug = 1; #endif - ret = parse_events_parse(data, scanner); + ret = parse_events_parse(parse_state, scanner); parse_events__flush_buffer(buffer, scanner); parse_events__delete_buffer(buffer, scanner); @@ -1656,45 +1664,45 @@ static int parse_events__scanner(const char *str, void *data, int start_token) */ int parse_events_terms(struct list_head *terms, const char *str) { - struct parse_events_terms data = { + struct parse_events_state parse_state = { .terms = NULL, }; int ret; - ret = parse_events__scanner(str, &data, PE_START_TERMS); + ret = parse_events__scanner(str, &parse_state, PE_START_TERMS); if (!ret) { - list_splice(data.terms, terms); - zfree(&data.terms); + list_splice(parse_state.terms, terms); + zfree(&parse_state.terms); return 0; } - parse_events_terms__delete(data.terms); + parse_events_terms__delete(parse_state.terms); return ret; } int parse_events(struct perf_evlist *evlist, const char *str, struct parse_events_error *err) { - struct parse_events_evlist data = { - .list = LIST_HEAD_INIT(data.list), + struct parse_events_state parse_state = { + .list = LIST_HEAD_INIT(parse_state.list), .idx = evlist->nr_entries, .error = err, .evlist = evlist, }; int ret; - ret = parse_events__scanner(str, &data, PE_START_EVENTS); + ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS); perf_pmu__parse_cleanup(); if (!ret) { struct perf_evsel *last; - if (list_empty(&data.list)) { + if (list_empty(&parse_state.list)) { WARN_ONCE(true, "WARNING: event parser found nothing"); return -1; } - perf_evlist__splice_list_tail(evlist, &data.list); - evlist->nr_groups += data.nr_groups; + perf_evlist__splice_list_tail(evlist, &parse_state.list); + evlist->nr_groups += parse_state.nr_groups; last = perf_evlist__last(evlist); last->cmdline_group_boundary = true; @@ -2124,7 +2132,7 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, return; } strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s); + pcache = probe_cache__new(nd->s, NULL); if (!pcache) continue; list_for_each_entry(ent, &pcache->entries, node) { @@ -2520,10 +2528,10 @@ void parse_events__clear_array(struct parse_events_array *a) zfree(&a->ranges); } -void parse_events_evlist_error(struct parse_events_evlist *data, +void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str) { - struct parse_events_error *err = data->error; + struct parse_events_error *err = parse_state->error; if (!err) return; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index a235f4d6d5e514f60055db58ce5ebb0b8e723d0b..635135125111231c9f61e2971133c7f4a188eeee 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -108,16 +108,13 @@ struct parse_events_error { char *help; /* optional help string */ }; -struct parse_events_evlist { +struct parse_events_state { struct list_head list; int idx; int nr_groups; struct parse_events_error *error; struct perf_evlist *evlist; -}; - -struct parse_events_terms { - struct list_head *terms; + struct list_head *terms; }; void parse_events__shrink_config_terms(void); @@ -143,18 +140,18 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx, const char *sys, const char *event, struct parse_events_error *error, struct list_head *head_config); -int parse_events_load_bpf(struct parse_events_evlist *data, +int parse_events_load_bpf(struct parse_events_state *parse_state, struct list_head *list, char *bpf_file_name, bool source, struct list_head *head_config); /* Provide this function for perf test */ struct bpf_object; -int parse_events_load_bpf_obj(struct parse_events_evlist *data, +int parse_events_load_bpf_obj(struct parse_events_state *parse_state, struct list_head *list, struct bpf_object *obj, struct list_head *head_config); -int parse_events_add_numeric(struct parse_events_evlist *data, +int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct list_head *head_config); @@ -164,11 +161,11 @@ int parse_events_add_cache(struct list_head *list, int *idx, struct list_head *head_config); int parse_events_add_breakpoint(struct list_head *list, int *idx, void *ptr, char *type, u64 len); -int parse_events_add_pmu(struct parse_events_evlist *data, +int parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, char *name, struct list_head *head_config); -int parse_events_multi_pmu_add(struct parse_events_evlist *data, +int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp); @@ -180,7 +177,7 @@ perf_pmu__parse_check(const char *name); void parse_events__set_leader(char *name, struct list_head *list); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); -void parse_events_evlist_error(struct parse_events_evlist *data, +void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str); void print_events(const char *event_glob, bool name_only, bool quiet, diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 660fca05bc93bd8f724a9f3cef3f0f3d86abb983..c42edeac451fc809c2581f492cdc2e1741774bf7 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -53,6 +53,21 @@ static int str(yyscan_t scanner, int token) return token; } +static bool isbpf(yyscan_t scanner) +{ + char *text = parse_events_get_text(scanner); + int len = strlen(text); + + if (len < 2) + return false; + if ((text[len - 1] == 'c' || text[len - 1] == 'o') && + text[len - 2] == '.') + return true; + if (len > 4 && !strcmp(text + len - 4, ".obj")) + return true; + return false; +} + /* * This function is called when the parser gets two kind of input: * @@ -136,8 +151,8 @@ do { \ group [^,{}/]*[{][^}]*[}][^,{}/]* event_pmu [^,{}/]+[/][^/]*[/][^,{}/]* event [^,{}/]+ -bpf_object [^,{}]+\.(o|bpf) -bpf_source [^,{}]+\.c +bpf_object [^,{}]+\.(o|bpf)[a-zA-Z0-9._]* +bpf_source [^,{}]+\.c[a-zA-Z0-9._]* num_dec [0-9]+ num_hex 0x[a-fA-F0-9]+ @@ -307,8 +322,8 @@ r{num_raw_hex} { return raw(yyscanner); } {num_hex} { return value(yyscanner, 16); } {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } -{bpf_object} { return str(yyscanner, PE_BPF_OBJECT); } -{bpf_source} { return str(yyscanner, PE_BPF_SOURCE); } +{bpf_object} { if (!isbpf(yyscanner)) REJECT; return str(yyscanner, PE_BPF_OBJECT); } +{bpf_source} { if (!isbpf(yyscanner)) REJECT; return str(yyscanner, PE_BPF_SOURCE); } {name} { return pmu_str_check(yyscanner); } "/" { BEGIN(config); return '/'; } - { return '-'; } diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 04fd8c9af9f9578c0f8f44a3c8cb05cf087d992f..e81a20ea8d7df1d2c7d8313279daa834eda88415 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -1,5 +1,5 @@ %pure-parser -%parse-param {void *_data} +%parse-param {void *_parse_state} %parse-param {void *scanner} %lex-param {void* scanner} %locations @@ -17,7 +17,7 @@ #include "parse-events.h" #include "parse-events-bison.h" -void parse_events_error(YYLTYPE *loc, void *data, void *scanner, char const *msg); +void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); #define ABORT_ON(val) \ do { \ @@ -33,11 +33,11 @@ do { \ } while (0) static void inc_group_count(struct list_head *list, - struct parse_events_evlist *data) + struct parse_events_state *parse_state) { /* Count groups only have more than 1 members */ if (!list_is_last(list->next, list)) - data->nr_groups++; + parse_state->nr_groups++; } %} @@ -115,9 +115,9 @@ PE_START_TERMS start_terms start_events: groups { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; - parse_events_update_lists($1, &data->list); + parse_events_update_lists($1, &parse_state->list); } groups: @@ -159,7 +159,7 @@ PE_NAME '{' events '}' { struct list_head *list = $3; - inc_group_count(list, _data); + inc_group_count(list, _parse_state); parse_events__set_leader($1, list); $$ = list; } @@ -168,7 +168,7 @@ PE_NAME '{' events '}' { struct list_head *list = $2; - inc_group_count(list, _data); + inc_group_count(list, _parse_state); parse_events__set_leader(NULL, list); $$ = list; } @@ -225,14 +225,13 @@ event_def: event_pmu | event_pmu: PE_NAME opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list, *orig_terms, *terms; if (parse_events_copy_term_list($2, &orig_terms)) YYABORT; ALLOC_LIST(list); - if (parse_events_add_pmu(data, list, $1, $2)) { + if (parse_events_add_pmu(_parse_state, list, $1, $2)) { struct perf_pmu *pmu = NULL; int ok = 0; @@ -245,7 +244,7 @@ PE_NAME opt_event_config if (!strncmp($1, name, strlen($1))) { if (parse_events_copy_term_list(orig_terms, &terms)) YYABORT; - if (!parse_events_add_pmu(data, list, pmu->name, terms)) + if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms)) ok++; parse_events_terms__delete(terms); } @@ -262,7 +261,7 @@ PE_KERNEL_PMU_EVENT sep_dc { struct list_head *list; - if (parse_events_multi_pmu_add(_data, $1, &list) < 0) + if (parse_events_multi_pmu_add(_parse_state, $1, &list) < 0) YYABORT; $$ = list; } @@ -273,7 +272,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc char pmu_name[128]; snprintf(&pmu_name, 128, "%s-%s", $1, $3); - if (parse_events_multi_pmu_add(_data, pmu_name, &list) < 0) + if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0) YYABORT; $$ = list; } @@ -286,62 +285,60 @@ PE_VALUE_SYM_SW event_legacy_symbol: value_sym '/' event_config '/' { - struct parse_events_evlist *data = _data; struct list_head *list; int type = $1 >> 16; int config = $1 & 255; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, type, config, $3)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3)); parse_events_terms__delete($3); $$ = list; } | value_sym sep_slash_dc { - struct parse_events_evlist *data = _data; struct list_head *list; int type = $1 >> 16; int config = $1 & 255; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, type, config, NULL)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); $$ = list; } event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5, error, $6)); + ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6)); parse_events_terms__delete($6); $$ = list; } | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL, error, $4)); + ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4)); parse_events_terms__delete($4); $$ = list; } | PE_NAME_CACHE_TYPE opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL, error, $2)); + ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2)); parse_events_terms__delete($2); $$ = list; } @@ -349,44 +346,44 @@ PE_NAME_CACHE_TYPE opt_event_config event_legacy_mem: PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, $6, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, NULL, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, $4, 0)); $$ = list; } | PE_PREFIX_MEM PE_VALUE sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, NULL, 0)); $$ = list; } @@ -394,15 +391,15 @@ PE_PREFIX_MEM PE_VALUE sep_dc event_legacy_tracepoint: tracepoint_name opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); if (error) error->idx = @1.first_column; - if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event, + if (parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, error, $2)) return -1; @@ -432,11 +429,10 @@ PE_NAME ':' PE_NAME event_legacy_numeric: PE_VALUE ':' PE_VALUE opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, (u32)$1, $3, $4)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4)); parse_events_terms__delete($4); $$ = list; } @@ -444,11 +440,10 @@ PE_VALUE ':' PE_VALUE opt_event_config event_legacy_raw: PE_RAW opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, PERF_TYPE_RAW, $1, $2)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2)); parse_events_terms__delete($2); $$ = list; } @@ -456,23 +451,22 @@ PE_RAW opt_event_config event_bpf_file: PE_BPF_OBJECT opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_load_bpf(data, list, $1, false, $2)); + ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2)); parse_events_terms__delete($2); $$ = list; } | PE_BPF_SOURCE opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_load_bpf(data, list, $1, true, $2)); + ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2)); parse_events_terms__delete($2); $$ = list; } @@ -494,8 +488,8 @@ opt_event_config: start_terms: event_config { - struct parse_events_terms *data = _data; - data->terms = $1; + struct parse_events_state *parse_state = _parse_state; + parse_state->terms = $1; } event_config: @@ -685,9 +679,9 @@ sep_slash_dc: '/' | ':' | %% -void parse_events_error(YYLTYPE *loc, void *data, +void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner __maybe_unused, char const *msg __maybe_unused) { - parse_events_evlist_error(data, loc->last_column, "parser error"); + parse_events_evlist_error(parse_state, loc->last_column, "parser error"); } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a2670e9d652dfa09eebb7e53a8ed2b63a7cea152..b7aaf9b2294d81224993d220c896a2da43fda308 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -184,13 +184,19 @@ static struct map *kernel_get_module_map(const char *module) return NULL; } -struct map *get_target_map(const char *target, bool user) +struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user) { /* Init maps of given executable or kernel */ - if (user) - return dso__new_map(target); - else + if (user) { + struct map *map; + + map = dso__new_map(target); + if (map && map->dso) + map->dso->nsinfo = nsinfo__get(nsi); + return map; + } else { return kernel_get_module_map(target); + } } static int convert_exec_to_group(const char *exec, char **result) @@ -366,7 +372,8 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) static int find_alternative_probe_point(struct debuginfo *dinfo, struct perf_probe_point *pp, struct perf_probe_point *result, - const char *target, bool uprobes) + const char *target, struct nsinfo *nsi, + bool uprobes) { struct map *map = NULL; struct symbol *sym; @@ -377,7 +384,7 @@ static int find_alternative_probe_point(struct debuginfo *dinfo, if (!pp->function || pp->file) return -ENOTSUP; - map = get_target_map(target, uprobes); + map = get_target_map(target, nsi, uprobes); if (!map) return -EINVAL; @@ -421,8 +428,8 @@ static int get_alternative_probe_event(struct debuginfo *dinfo, memcpy(tmp, &pev->point, sizeof(*tmp)); memset(&pev->point, 0, sizeof(pev->point)); - ret = find_alternative_probe_point(dinfo, tmp, &pev->point, - pev->target, pev->uprobes); + ret = find_alternative_probe_point(dinfo, tmp, &pev->point, pev->target, + pev->nsi, pev->uprobes); if (ret < 0) memcpy(&pev->point, tmp, sizeof(*tmp)); @@ -444,7 +451,7 @@ static int get_alternative_line_range(struct debuginfo *dinfo, if (lr->end != INT_MAX) len = lr->end - lr->start; ret = find_alternative_probe_point(dinfo, &pp, &result, - target, user); + target, NULL, user); if (!ret) { lr->function = result.function; lr->file = result.file; @@ -457,12 +464,14 @@ static int get_alternative_line_range(struct debuginfo *dinfo, } /* Open new debuginfo of given module */ -static struct debuginfo *open_debuginfo(const char *module, bool silent) +static struct debuginfo *open_debuginfo(const char *module, struct nsinfo *nsi, + bool silent) { const char *path = module; char reason[STRERR_BUFSIZE]; struct debuginfo *ret = NULL; struct dso *dso = NULL; + struct nscookie nsc; int err; if (!module || !strchr(module, '/')) { @@ -480,6 +489,7 @@ static struct debuginfo *open_debuginfo(const char *module, bool silent) } path = dso->long_name; } + nsinfo__mountns_enter(nsi, &nsc); ret = debuginfo__new(path); if (!ret && !silent) { pr_warning("The %s file has no debug information.\n", path); @@ -489,6 +499,7 @@ static struct debuginfo *open_debuginfo(const char *module, bool silent) pr_warning("Rebuild with -g, "); pr_warning("or install an appropriate debuginfo package.\n"); } + nsinfo__mountns_exit(&nsc); return ret; } @@ -516,7 +527,7 @@ static struct debuginfo *debuginfo_cache__open(const char *module, bool silent) goto out; } - debuginfo_cache = open_debuginfo(module, silent); + debuginfo_cache = open_debuginfo(module, NULL, silent); if (!debuginfo_cache) zfree(&debuginfo_cache_path); out: @@ -531,14 +542,18 @@ static void debuginfo_cache__exit(void) } -static int get_text_start_address(const char *exec, unsigned long *address) +static int get_text_start_address(const char *exec, unsigned long *address, + struct nsinfo *nsi) { Elf *elf; GElf_Ehdr ehdr; GElf_Shdr shdr; int fd, ret = -ENOENT; + struct nscookie nsc; + nsinfo__mountns_enter(nsi, &nsc); fd = open(exec, O_RDONLY); + nsinfo__mountns_exit(&nsc); if (fd < 0) return -errno; @@ -582,7 +597,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, ret = -EINVAL; goto error; } - ret = get_text_start_address(tp->module, &stext); + ret = get_text_start_address(tp->module, &stext, NULL); if (ret < 0) goto error; addr += stext; @@ -659,7 +674,7 @@ post_process_offline_probe_trace_events(struct probe_trace_event *tevs, /* Prepare a map for offline binary */ map = dso__new_map(pathname); - if (!map || get_text_start_address(pathname, &stext) < 0) { + if (!map || get_text_start_address(pathname, &stext, NULL) < 0) { pr_warning("Failed to get ELF symbols for %s\n", pathname); return -EINVAL; } @@ -676,7 +691,8 @@ post_process_offline_probe_trace_events(struct probe_trace_event *tevs, } static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, - int ntevs, const char *exec) + int ntevs, const char *exec, + struct nsinfo *nsi) { int i, ret = 0; unsigned long stext = 0; @@ -684,7 +700,7 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, if (!exec) return 0; - ret = get_text_start_address(exec, &stext); + ret = get_text_start_address(exec, &stext, nsi); if (ret < 0) return ret; @@ -715,7 +731,7 @@ post_process_module_probe_trace_events(struct probe_trace_event *tevs, if (!module) return 0; - map = get_target_map(module, false); + map = get_target_map(module, NULL, false); if (!map || debuginfo__get_text_offset(dinfo, &text_offs, true) < 0) { pr_warning("Failed to get ELF symbols for %s\n", module); return -EINVAL; @@ -802,7 +818,8 @@ static int post_process_probe_trace_events(struct perf_probe_event *pev, int ret; if (uprobe) - ret = add_exec_to_probe_trace_events(tevs, ntevs, module); + ret = add_exec_to_probe_trace_events(tevs, ntevs, module, + pev->nsi); else if (module) /* Currently ref_reloc_sym based probe is not for drivers */ ret = post_process_module_probe_trace_events(tevs, ntevs, @@ -825,7 +842,7 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct debuginfo *dinfo; int ntevs, ret = 0; - dinfo = open_debuginfo(pev->target, !need_dwarf); + dinfo = open_debuginfo(pev->target, pev->nsi, !need_dwarf); if (!dinfo) { if (need_dwarf) return -ENOENT; @@ -945,7 +962,7 @@ static int __show_line_range(struct line_range *lr, const char *module, char sbuf[STRERR_BUFSIZE]; /* Search a line range */ - dinfo = open_debuginfo(module, false); + dinfo = open_debuginfo(module, NULL, false); if (!dinfo) return -ENOENT; @@ -1021,14 +1038,18 @@ static int __show_line_range(struct line_range *lr, const char *module, return ret; } -int show_line_range(struct line_range *lr, const char *module, bool user) +int show_line_range(struct line_range *lr, const char *module, + struct nsinfo *nsi, bool user) { int ret; + struct nscookie nsc; ret = init_probe_symbol_maps(user); if (ret < 0) return ret; + nsinfo__mountns_enter(nsi, &nsc); ret = __show_line_range(lr, module, user); + nsinfo__mountns_exit(&nsc); exit_probe_symbol_maps(); return ret; @@ -1111,7 +1132,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, if (ret < 0) return ret; - dinfo = open_debuginfo(pevs->target, false); + dinfo = open_debuginfo(pevs->target, pevs->nsi, false); if (!dinfo) { ret = -ENOENT; goto out; @@ -1155,6 +1176,7 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, int show_line_range(struct line_range *lr __maybe_unused, const char *module __maybe_unused, + struct nsinfo *nsi __maybe_unused, bool user __maybe_unused) { pr_warning("Debuginfo-analysis is not supported.\n"); @@ -2373,7 +2395,7 @@ kprobe_blacklist__find_by_address(struct list_head *blacklist, struct kprobe_blacklist_node *node; list_for_each_entry(node, blacklist, list) { - if (node->start <= address && address <= node->end) + if (node->start <= address && address < node->end) return node; } @@ -2703,6 +2725,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event *tev = NULL; struct probe_cache *cache = NULL; struct strlist *namelist[2] = {NULL, NULL}; + struct nscookie nsc; up = pev->uprobes ? 1 : 0; fd[up] = __open_probe_file_and_namelist(up, &namelist[up]); @@ -2729,7 +2752,9 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, if (ret < 0) break; + nsinfo__mountns_enter(pev->nsi, &nsc); ret = probe_file__add_event(fd[up], tev); + nsinfo__mountns_exit(&nsc); if (ret < 0) break; @@ -2744,7 +2769,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, if (ret == -EINVAL && pev->uprobes) warn_uprobe_event_compat(tev); if (ret == 0 && probe_conf.cache) { - cache = probe_cache__new(pev->target); + cache = probe_cache__new(pev->target, pev->nsi); if (!cache || probe_cache__add_entry(cache, pev, tevs, ntevs) < 0 || probe_cache__commit(cache) < 0) @@ -2805,7 +2830,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, int ret, i, j, skipped = 0; char *mod_name; - map = get_target_map(pev->target, pev->uprobes); + map = get_target_map(pev->target, pev->nsi, pev->uprobes); if (!map) { ret = -EINVAL; goto out; @@ -3094,7 +3119,7 @@ static int find_cached_events(struct perf_probe_event *pev, int ntevs = 0; int ret = 0; - cache = probe_cache__new(target); + cache = probe_cache__new(target, pev->nsi); /* Return 0 ("not found") if the target has no probe cache. */ if (!cache) return 0; @@ -3184,7 +3209,7 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev, else return find_cached_events(pev, tevs, pev->target); } - cache = probe_cache__new(pev->target); + cache = probe_cache__new(pev->target, pev->nsi); if (!cache) return 0; @@ -3345,13 +3370,16 @@ int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs) void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs) { int i, j; + struct perf_probe_event *pev; /* Loop 3: cleanup and free trace events */ for (i = 0; i < npevs; i++) { + pev = &pevs[i]; for (j = 0; j < pevs[i].ntevs; j++) clear_probe_trace_event(&pevs[i].tevs[j]); zfree(&pevs[i].tevs); pevs[i].ntevs = 0; + nsinfo__zput(pev->nsi); clear_perf_probe_event(&pevs[i]); } } @@ -3409,8 +3437,8 @@ int del_perf_probe_events(struct strfilter *filter) return ret; } -int show_available_funcs(const char *target, struct strfilter *_filter, - bool user) +int show_available_funcs(const char *target, struct nsinfo *nsi, + struct strfilter *_filter, bool user) { struct rb_node *nd; struct map *map; @@ -3421,7 +3449,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter, return ret; /* Get a symbol map */ - map = get_target_map(target, user); + map = get_target_map(target, nsi, user); if (!map) { pr_err("Failed to get a map for %s\n", (target) ? : "kernel"); return -EINVAL; diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 5812947418dd7329ca7c86d730c500bf82b51e51..078681d12168710a401f5c079b7886ac611b08a5 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -4,6 +4,7 @@ #include #include #include "intlist.h" +#include "namespaces.h" /* Probe related configurations */ struct probe_conf { @@ -92,6 +93,7 @@ struct perf_probe_event { struct perf_probe_arg *args; /* Arguments */ struct probe_trace_event *tevs; int ntevs; + struct nsinfo *nsi; /* Target namespace */ }; /* Line range */ @@ -163,10 +165,12 @@ int show_perf_probe_event(const char *group, const char *event, struct perf_probe_event *pev, const char *module, bool use_stdout); int show_perf_probe_events(struct strfilter *filter); -int show_line_range(struct line_range *lr, const char *module, bool user); +int show_line_range(struct line_range *lr, const char *module, + struct nsinfo *nsi, bool user); int show_available_vars(struct perf_probe_event *pevs, int npevs, struct strfilter *filter); -int show_available_funcs(const char *module, struct strfilter *filter, bool user); +int show_available_funcs(const char *module, struct nsinfo *nsi, + struct strfilter *filter, bool user); void arch__fix_tev_from_maps(struct perf_probe_event *pev, struct probe_trace_event *tev, struct map *map, struct symbol *sym); @@ -180,7 +184,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...) __printf(3, 4); int copy_to_probe_trace_arg(struct probe_trace_arg *tvar, struct perf_probe_arg *pvar); -struct map *get_target_map(const char *target, bool user); +struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user); void arch__post_process_probe_trace_events(struct perf_probe_event *pev, int ntevs); diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index d679389e627c1800c58b6b632ef65e67ff49d771..cdf8d83a484c1408608c78cace95da4e29b0c242 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -412,13 +412,15 @@ int probe_cache_entry__get_event(struct probe_cache_entry *entry, } /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ -static int probe_cache__open(struct probe_cache *pcache, const char *target) +static int probe_cache__open(struct probe_cache *pcache, const char *target, + struct nsinfo *nsi) { char cpath[PATH_MAX]; char sbuildid[SBUILD_ID_SIZE]; char *dir_name = NULL; bool is_kallsyms = false; int ret, fd; + struct nscookie nsc; if (target && build_id_cache__cached(target)) { /* This is a cached buildid */ @@ -431,8 +433,11 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) target = DSO__NAME_KALLSYMS; is_kallsyms = true; ret = sysfs__sprintf_build_id("/", sbuildid); - } else + } else { + nsinfo__mountns_enter(nsi, &nsc); ret = filename__sprintf_build_id(target, sbuildid); + nsinfo__mountns_exit(&nsc); + } if (ret < 0) { pr_debug("Failed to get build-id from %s.\n", target); @@ -441,7 +446,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) /* If we have no buildid cache, make it */ if (!build_id_cache__cached(sbuildid)) { - ret = build_id_cache__add_s(sbuildid, target, + ret = build_id_cache__add_s(sbuildid, target, nsi, is_kallsyms, NULL); if (ret < 0) { pr_debug("Failed to add build-id cache: %s\n", target); @@ -449,7 +454,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) } } - dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms, + dir_name = build_id_cache__cachedir(sbuildid, target, nsi, is_kallsyms, false); found: if (!dir_name) { @@ -554,7 +559,7 @@ void probe_cache__delete(struct probe_cache *pcache) free(pcache); } -struct probe_cache *probe_cache__new(const char *target) +struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi) { struct probe_cache *pcache = probe_cache__alloc(); int ret; @@ -562,7 +567,7 @@ struct probe_cache *probe_cache__new(const char *target) if (!pcache) return NULL; - ret = probe_cache__open(pcache, target); + ret = probe_cache__open(pcache, target, nsi); if (ret < 0) { pr_debug("Cache open error: %d\n", ret); goto out_err; @@ -974,7 +979,7 @@ int probe_cache__show_all_caches(struct strfilter *filter) return -EINVAL; } strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s); + pcache = probe_cache__new(nd->s, NULL); if (!pcache) continue; if (!list_empty(&pcache->entries)) { diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h index 5ecc9d3925dbb53c3190d8c6aa075c5e38bd3935..2ca4163abafeb77867a9f778e5a74f6a0599a195 100644 --- a/tools/perf/util/probe-file.h +++ b/tools/perf/util/probe-file.h @@ -51,7 +51,7 @@ int probe_file__del_strlist(int fd, struct strlist *namelist); int probe_cache_entry__get_event(struct probe_cache_entry *entry, struct probe_trace_event **tevs); -struct probe_cache *probe_cache__new(const char *target); +struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi); int probe_cache__add_entry(struct probe_cache *pcache, struct perf_probe_event *pev, struct probe_trace_event *tevs, int ntevs); @@ -69,7 +69,7 @@ int probe_cache__show_all_caches(struct strfilter *filter); bool probe_type_is_available(enum probe_type type); bool kretprobe_offset_is_supported(void); #else /* ! HAVE_LIBELF_SUPPORT */ -static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused) +static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) { return NULL; } diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 9f3b0d9754a896484fa193865d2141bd37a82ca1..e66dc495809a86d2be847561be6de861ac75de19 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -10,6 +10,7 @@ util/ctype.c util/evlist.c util/evsel.c util/cpumap.c +util/namespaces.c ../lib/bitmap.c ../lib/find_bit.c ../lib/hweight.c diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 57b7a00e6f1675de348ee7e4ae8b57389ea8318b..c7187f067d3140ab0d0c378160fa3c732a7f3e21 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -116,6 +116,34 @@ static PyObject *get_handler(const char *handler_name) return handler; } +static int get_argument_count(PyObject *handler) +{ + int arg_count = 0; + + /* + * The attribute for the code object is func_code in Python 2, + * whereas it is __code__ in Python 3.0+. + */ + PyObject *code_obj = PyObject_GetAttrString(handler, + "func_code"); + if (PyErr_Occurred()) { + PyErr_Clear(); + code_obj = PyObject_GetAttrString(handler, + "__code__"); + } + PyErr_Clear(); + if (code_obj) { + PyObject *arg_count_obj = PyObject_GetAttrString(code_obj, + "co_argcount"); + if (arg_count_obj) { + arg_count = (int) PyInt_AsLong(arg_count_obj); + Py_DECREF(arg_count_obj); + } + Py_DECREF(code_obj); + } + return arg_count; +} + static void call_object(PyObject *handler, PyObject *args, const char *die_msg) { PyObject *retval; @@ -391,13 +419,115 @@ static PyObject *python_process_callchain(struct perf_sample *sample, return pylist; } +static PyObject *get_sample_value_as_tuple(struct sample_read_value *value) +{ + PyObject *t; + + t = PyTuple_New(2); + if (!t) + Py_FatalError("couldn't create Python tuple"); + PyTuple_SetItem(t, 0, PyLong_FromUnsignedLongLong(value->id)); + PyTuple_SetItem(t, 1, PyLong_FromUnsignedLongLong(value->value)); + return t; +} + +static void set_sample_read_in_dict(PyObject *dict_sample, + struct perf_sample *sample, + struct perf_evsel *evsel) +{ + u64 read_format = evsel->attr.read_format; + PyObject *values; + unsigned int i; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { + pydict_set_item_string_decref(dict_sample, "time_enabled", + PyLong_FromUnsignedLongLong(sample->read.time_enabled)); + } + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { + pydict_set_item_string_decref(dict_sample, "time_running", + PyLong_FromUnsignedLongLong(sample->read.time_running)); + } + + if (read_format & PERF_FORMAT_GROUP) + values = PyList_New(sample->read.group.nr); + else + values = PyList_New(1); + + if (!values) + Py_FatalError("couldn't create Python list"); + + if (read_format & PERF_FORMAT_GROUP) { + for (i = 0; i < sample->read.group.nr; i++) { + PyObject *t = get_sample_value_as_tuple(&sample->read.group.values[i]); + PyList_SET_ITEM(values, i, t); + } + } else { + PyObject *t = get_sample_value_as_tuple(&sample->read.one); + PyList_SET_ITEM(values, 0, t); + } + pydict_set_item_string_decref(dict_sample, "values", values); +} + +static PyObject *get_perf_sample_dict(struct perf_sample *sample, + struct perf_evsel *evsel, + struct addr_location *al, + PyObject *callchain) +{ + PyObject *dict, *dict_sample; + + dict = PyDict_New(); + if (!dict) + Py_FatalError("couldn't create Python dictionary"); + + dict_sample = PyDict_New(); + if (!dict_sample) + Py_FatalError("couldn't create Python dictionary"); + + pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); + pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( + (const char *)&evsel->attr, sizeof(evsel->attr))); + + pydict_set_item_string_decref(dict_sample, "pid", + PyInt_FromLong(sample->pid)); + pydict_set_item_string_decref(dict_sample, "tid", + PyInt_FromLong(sample->tid)); + pydict_set_item_string_decref(dict_sample, "cpu", + PyInt_FromLong(sample->cpu)); + pydict_set_item_string_decref(dict_sample, "ip", + PyLong_FromUnsignedLongLong(sample->ip)); + pydict_set_item_string_decref(dict_sample, "time", + PyLong_FromUnsignedLongLong(sample->time)); + pydict_set_item_string_decref(dict_sample, "period", + PyLong_FromUnsignedLongLong(sample->period)); + set_sample_read_in_dict(dict_sample, sample, evsel); + pydict_set_item_string_decref(dict, "sample", dict_sample); + + pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( + (const char *)sample->raw_data, sample->raw_size)); + pydict_set_item_string_decref(dict, "comm", + PyString_FromString(thread__comm_str(al->thread))); + if (al->map) { + pydict_set_item_string_decref(dict, "dso", + PyString_FromString(al->map->dso->name)); + } + if (al->sym) { + pydict_set_item_string_decref(dict, "symbol", + PyString_FromString(al->sym->name)); + } + + pydict_set_item_string_decref(dict, "callchain", callchain); + + return dict; +} + static void python_process_tracepoint(struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al) { struct event_format *event = evsel->tp_format; PyObject *handler, *context, *t, *obj = NULL, *callchain; - PyObject *dict = NULL; + PyObject *dict = NULL, *all_entries_dict = NULL; static char handler_name[256]; struct format_field *field; unsigned long s, ns; @@ -407,10 +537,7 @@ static void python_process_tracepoint(struct perf_sample *sample, void *data = sample->raw_data; unsigned long long nsecs = sample->time; const char *comm = thread__comm_str(al->thread); - - t = PyTuple_New(MAX_FIELDS); - if (!t) - Py_FatalError("couldn't create Python tuple"); + const char *default_handler_name = "trace_unhandled"; if (!event) { snprintf(handler_name, sizeof(handler_name), @@ -427,10 +554,19 @@ static void python_process_tracepoint(struct perf_sample *sample, handler = get_handler(handler_name); if (!handler) { + handler = get_handler(default_handler_name); + if (!handler) + return; dict = PyDict_New(); if (!dict) Py_FatalError("couldn't create Python dict"); } + + t = PyTuple_New(MAX_FIELDS); + if (!t) + Py_FatalError("couldn't create Python tuple"); + + s = nsecs / NSEC_PER_SEC; ns = nsecs - s * NSEC_PER_SEC; @@ -444,8 +580,10 @@ static void python_process_tracepoint(struct perf_sample *sample, /* ip unwinding */ callchain = python_process_callchain(sample, evsel, al); + /* Need an additional reference for the perf_sample dict */ + Py_INCREF(callchain); - if (handler) { + if (!dict) { PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); PyTuple_SetItem(t, n++, PyInt_FromLong(s)); PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); @@ -484,26 +622,35 @@ static void python_process_tracepoint(struct perf_sample *sample, } else { /* FIELD_IS_NUMERIC */ obj = get_field_numeric_entry(event, field, data); } - if (handler) + if (!dict) PyTuple_SetItem(t, n++, obj); else pydict_set_item_string_decref(dict, field->name, obj); } - if (!handler) + if (dict) PyTuple_SetItem(t, n++, dict); + if (get_argument_count(handler) == (int) n + 1) { + all_entries_dict = get_perf_sample_dict(sample, evsel, al, + callchain); + PyTuple_SetItem(t, n++, all_entries_dict); + } else { + Py_DECREF(callchain); + } + if (_PyTuple_Resize(&t, n) == -1) Py_FatalError("error resizing Python tuple"); - if (handler) { + if (!dict) { call_object(handler, t, handler_name); } else { - try_call_object("trace_unhandled", t); + call_object(handler, t, default_handler_name); Py_DECREF(dict); } + Py_XDECREF(all_entries_dict); Py_DECREF(t); } @@ -795,10 +942,16 @@ static void python_process_general_event(struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al) { - PyObject *handler, *t, *dict, *callchain, *dict_sample; + PyObject *handler, *t, *dict, *callchain; static char handler_name[64]; unsigned n = 0; + snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); + + handler = get_handler(handler_name); + if (!handler) + return; + /* * Use the MAX_FIELDS to make the function expandable, though * currently there is only one item for the tuple. @@ -807,61 +960,16 @@ static void python_process_general_event(struct perf_sample *sample, if (!t) Py_FatalError("couldn't create Python tuple"); - dict = PyDict_New(); - if (!dict) - Py_FatalError("couldn't create Python dictionary"); - - dict_sample = PyDict_New(); - if (!dict_sample) - Py_FatalError("couldn't create Python dictionary"); - - snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); - - handler = get_handler(handler_name); - if (!handler) - goto exit; - - pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); - pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( - (const char *)&evsel->attr, sizeof(evsel->attr))); - - pydict_set_item_string_decref(dict_sample, "pid", - PyInt_FromLong(sample->pid)); - pydict_set_item_string_decref(dict_sample, "tid", - PyInt_FromLong(sample->tid)); - pydict_set_item_string_decref(dict_sample, "cpu", - PyInt_FromLong(sample->cpu)); - pydict_set_item_string_decref(dict_sample, "ip", - PyLong_FromUnsignedLongLong(sample->ip)); - pydict_set_item_string_decref(dict_sample, "time", - PyLong_FromUnsignedLongLong(sample->time)); - pydict_set_item_string_decref(dict_sample, "period", - PyLong_FromUnsignedLongLong(sample->period)); - pydict_set_item_string_decref(dict, "sample", dict_sample); - - pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( - (const char *)sample->raw_data, sample->raw_size)); - pydict_set_item_string_decref(dict, "comm", - PyString_FromString(thread__comm_str(al->thread))); - if (al->map) { - pydict_set_item_string_decref(dict, "dso", - PyString_FromString(al->map->dso->name)); - } - if (al->sym) { - pydict_set_item_string_decref(dict, "symbol", - PyString_FromString(al->sym->name)); - } - /* ip unwinding */ callchain = python_process_callchain(sample, evsel, al); - pydict_set_item_string_decref(dict, "callchain", callchain); + dict = get_perf_sample_dict(sample, evsel, al, callchain); PyTuple_SetItem(t, n++, dict); if (_PyTuple_Resize(&t, n) == -1) Py_FatalError("error resizing Python tuple"); call_object(handler, t, handler_name); -exit: + Py_DECREF(dict); Py_DECREF(t); } @@ -1259,6 +1367,12 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) fprintf(ofp, "%s", f->name); } + if (not_first++) + fprintf(ofp, ", "); + if (++count % 5 == 0) + fprintf(ofp, "\n\t\t"); + fprintf(ofp, "perf_sample_dict"); + fprintf(ofp, "):\n"); fprintf(ofp, "\t\tprint_header(event_name, common_cpu, " @@ -1328,6 +1442,9 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) fprintf(ofp, ")\n\n"); + fprintf(ofp, "\t\tprint 'Sample: {'+" + "get_dict_as_string(perf_sample_dict['sample'], ', ')+'}'\n\n"); + fprintf(ofp, "\t\tfor node in common_callchain:"); fprintf(ofp, "\n\t\t\tif 'sym' in node:"); fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])"); @@ -1338,15 +1455,20 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) } fprintf(ofp, "def trace_unhandled(event_name, context, " - "event_fields_dict):\n"); + "event_fields_dict, perf_sample_dict):\n"); - fprintf(ofp, "\t\tprint ' '.join(['%%s=%%s'%%(k,str(v))" - "for k,v in sorted(event_fields_dict.items())])\n\n"); + fprintf(ofp, "\t\tprint get_dict_as_string(event_fields_dict)\n"); + fprintf(ofp, "\t\tprint 'Sample: {'+" + "get_dict_as_string(perf_sample_dict['sample'], ', ')+'}'\n\n"); fprintf(ofp, "def print_header(" "event_name, cpu, secs, nsecs, pid, comm):\n" "\tprint \"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t" - "(event_name, cpu, secs, nsecs, pid, comm),\n"); + "(event_name, cpu, secs, nsecs, pid, comm),\n\n"); + + fprintf(ofp, "def get_dict_as_string(a_dict, delimiter=' '):\n" + "\treturn delimiter.join" + "(['%%s=%%s'%%(k,str(v))for k,v in sorted(a_dict.items())])\n"); fclose(ofp); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index d19c40a8104027117a2d30ad2a6aad6af8207025..a7ebd9fe8e40ee56f79a108c247d528571d8ff64 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -428,6 +428,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->stat_round = process_stat_round_stub; if (tool->time_conv == NULL) tool->time_conv = process_event_op2_stub; + if (tool->feature == NULL) + tool->feature = process_event_op2_stub; } static void swap_sample_id_all(union perf_event *event, void *data) @@ -1118,6 +1120,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, if (sample_type & PERF_SAMPLE_DATA_SRC) printf(" . data_src: 0x%"PRIx64"\n", sample->data_src); + if (sample_type & PERF_SAMPLE_PHYS_ADDR) + printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr); + if (sample_type & PERF_SAMPLE_TRANSACTION) printf("... transaction: %" PRIx64 "\n", sample->transaction); @@ -1125,6 +1130,30 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, sample_read__printf(sample, evsel->attr.read_format); } +static void dump_read(struct perf_evsel *evsel, union perf_event *event) +{ + struct read_event *read_event = &event->read; + u64 read_format; + + if (!dump_trace) + return; + + printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, + evsel ? perf_evsel__name(evsel) : "FAIL", + event->read.value); + + read_format = evsel->attr.read_format; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + printf("... time enabled : %" PRIu64 "\n", read_event->time_enabled); + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + printf("... time running : %" PRIu64 "\n", read_event->time_running); + + if (read_format & PERF_FORMAT_ID) + printf("... id : %" PRIu64 "\n", read_event->id); +} + static struct machine *machines__find_for_cpumode(struct machines *machines, union perf_event *event, struct perf_sample *sample) @@ -1269,6 +1298,7 @@ static int machines__deliver_event(struct machines *machines, evlist->stats.total_lost_samples += event->lost_samples.lost; return tool->lost_samples(tool, event, sample, machine); case PERF_RECORD_READ: + dump_read(evsel, event); return tool->read(tool, event, sample, evsel, machine); case PERF_RECORD_THROTTLE: return tool->throttle(tool, event, sample, machine); @@ -1371,6 +1401,8 @@ static s64 perf_session__process_user_event(struct perf_session *session, case PERF_RECORD_TIME_CONV: session->time_conv = event->time_conv; return tool->time_conv(tool, event, session); + case PERF_RECORD_HEADER_FEATURE: + return tool->feature(tool, event, session); default: return -EINVAL; } diff --git a/tools/perf/util/setns.c b/tools/perf/util/setns.c new file mode 100644 index 0000000000000000000000000000000000000000..ce8fc290fce8783f6e3a24beac8e3f0dcd7d2a79 --- /dev/null +++ b/tools/perf/util/setns.c @@ -0,0 +1,8 @@ +#include "util.h" +#include +#include + +int setns(int fd, int nstype) +{ + return syscall(__NR_setns, fd, nstype); +} diff --git a/tools/perf/util/smt.c b/tools/perf/util/smt.c new file mode 100644 index 0000000000000000000000000000000000000000..453f6f6f29f30342790fa879a00eff5a9442614e --- /dev/null +++ b/tools/perf/util/smt.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include "api/fs/fs.h" +#include "smt.h" + +int smt_on(void) +{ + static bool cached; + static int cached_result; + int cpu; + int ncpu; + + if (cached) + return cached_result; + + ncpu = sysconf(_SC_NPROCESSORS_CONF); + for (cpu = 0; cpu < ncpu; cpu++) { + unsigned long long siblings; + char *str; + size_t strlen; + char fn[256]; + + snprintf(fn, sizeof fn, + "devices/system/cpu/cpu%d/topology/thread_siblings", + cpu); + if (sysfs__read_str(fn, &str, &strlen) < 0) + continue; + /* Entry is hex, but does not have 0x, so need custom parser */ + siblings = strtoull(str, NULL, 16); + free(str); + if (hweight64(siblings) > 1) { + cached_result = 1; + cached = true; + break; + } + } + if (!cached) { + cached_result = 0; + cached = true; + } + return cached_result; +} diff --git a/tools/perf/util/smt.h b/tools/perf/util/smt.h new file mode 100644 index 0000000000000000000000000000000000000000..b8414b7bcbc87b45a0c38dd7c2829d74a538fe10 --- /dev/null +++ b/tools/perf/util/smt.h @@ -0,0 +1,6 @@ +#ifndef SMT_H +#define SMT_H 1 + +int smt_on(void); + +#endif diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 8b327c955a4f274a214c6c3449248046507b78ce..eb3ab902a1c0869ad0b3431a82ba7bed49ec914d 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1315,6 +1315,47 @@ struct sort_entry sort_mem_dcacheline = { .se_width_idx = HISTC_MEM_DCACHELINE, }; +static int64_t +sort__phys_daddr_cmp(struct hist_entry *left, struct hist_entry *right) +{ + uint64_t l = 0, r = 0; + + if (left->mem_info) + l = left->mem_info->daddr.phys_addr; + if (right->mem_info) + r = right->mem_info->daddr.phys_addr; + + return (int64_t)(r - l); +} + +static int hist_entry__phys_daddr_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + uint64_t addr = 0; + size_t ret = 0; + size_t len = BITS_PER_LONG / 4; + + addr = he->mem_info->daddr.phys_addr; + + ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", he->level); + + ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, addr); + + ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, ""); + + if (ret > width) + bf[width] = '\0'; + + return width; +} + +struct sort_entry sort_mem_phys_daddr = { + .se_header = "Data Physical Address", + .se_cmp = sort__phys_daddr_cmp, + .se_snprintf = hist_entry__phys_daddr_snprintf, + .se_width_idx = HISTC_MEM_PHYS_DADDR, +}; + static int64_t sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) { @@ -1547,6 +1588,7 @@ static struct sort_dimension memory_sort_dimensions[] = { DIM(SORT_MEM_LVL, "mem", sort_mem_lvl), DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop), DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline), + DIM(SORT_MEM_PHYS_DADDR, "phys_daddr", sort_mem_phys_daddr), }; #undef DIM @@ -2563,7 +2605,7 @@ static const char *get_default_sort_order(struct perf_evlist *evlist) BUG_ON(sort__mode >= ARRAY_SIZE(default_sort_orders)); - if (evlist == NULL) + if (evlist == NULL || perf_evlist__empty(evlist)) goto out_no_evlist; evlist__for_each_entry(evlist, evsel) { diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index b7c75597e18fd226c190e8fbb81ef610690f8541..f36dc4980a6c78f3bc5a005d164f3d1a637053f3 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -245,6 +245,7 @@ enum sort_type { SORT_MEM_SNOOP, SORT_MEM_DCACHELINE, SORT_MEM_IADDR_SYMBOL, + SORT_MEM_PHYS_DADDR, }; /* diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index ebc88a74e67b7129cbbd6790c34f50dcefec0de1..ed8e8d2de9427a111cb417a204979298a6aa71cb 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -155,6 +155,9 @@ static void find_address_in_section(bfd *abfd, asection *section, void *data) a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, &a2l->filename, &a2l->funcname, &a2l->line); + + if (a2l->filename && !strlen(a2l->filename)) + a2l->filename = NULL; } static struct a2l_data *addr2line_init(const char *path) @@ -248,6 +251,9 @@ static int addr2line(const char *dso_name, u64 addr, &a2l->funcname, &a2l->line) && cnt++ < MAX_INLINE_NEST) { + if (a2l->filename && !strlen(a2l->filename)) + a2l->filename = NULL; + if (node != NULL) { if (inline_list__append_dso_a2l(dso, node)) return 0; diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 719d6cb86952e5c6482e7a09070370360efe2030..a04cf56d3517fb3955e6d2a7bc3efa3132d818fc 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -70,7 +70,11 @@ static int saved_value_cmp(struct rb_node *rb_node, const void *entry) return a->ctx - b->ctx; if (a->cpu != b->cpu) return a->cpu - b->cpu; - return a->evsel - b->evsel; + if (a->evsel == b->evsel) + return 0; + if ((char *)a->evsel < (char *)b->evsel) + return -1; + return +1; } static struct rb_node *saved_value_new(struct rblist *rblist __maybe_unused, diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 53b9a994a3dc9e50aca6da360d4781d93f52dfc9..35e9848734d6108e00104de58d35e6773a2ccb95 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -128,6 +128,10 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) { + struct perf_stat_evsel *ps = evsel->priv; + + if (ps) + free(ps->group_data); zfree(&evsel->priv); } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 7522bf10b03e2fcbf26b9c67bebd41e56bff310b..eacaf958e19d2a2750af0ddc5de9f2fa993a3d86 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -28,8 +28,9 @@ enum perf_stat_evsel_id { }; struct perf_stat_evsel { - struct stats res_stats[3]; - enum perf_stat_evsel_id id; + struct stats res_stats[3]; + enum perf_stat_evsel_id id; + u64 *group_data; }; enum aggr_mode { diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 502505cf236af30226b22ff82878098060f19862..9cf781f0d8a2d797c88bf0bef5cab8759a6cbf96 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -259,7 +259,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * { uint32_t nr_rel_entries, idx; GElf_Sym sym; - u64 plt_offset; + u64 plt_offset, plt_header_size, plt_entry_size; GElf_Shdr shdr_plt; struct symbol *f; GElf_Shdr shdr_rel_plt, shdr_dynsym; @@ -326,6 +326,23 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; plt_offset = shdr_plt.sh_offset; + switch (ehdr.e_machine) { + case EM_ARM: + plt_header_size = 20; + plt_entry_size = 12; + break; + + case EM_AARCH64: + plt_header_size = 32; + plt_entry_size = 16; + break; + + default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/sparc/xtensa need to be checked */ + plt_header_size = shdr_plt.sh_entsize; + plt_entry_size = shdr_plt.sh_entsize; + break; + } + plt_offset += plt_header_size; if (shdr_rel_plt.sh_type == SHT_RELA) { GElf_Rela pos_mem, *pos; @@ -335,7 +352,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * const char *elf_name = NULL; char *demangled = NULL; symidx = GELF_R_SYM(pos->r_info); - plt_offset += shdr_plt.sh_entsize; gelf_getsym(syms, symidx, &sym); elf_name = elf_sym__name(&sym, symstrs); @@ -346,11 +362,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * "%s@plt", elf_name); free(demangled); - f = symbol__new(plt_offset, shdr_plt.sh_entsize, + f = symbol__new(plt_offset, plt_entry_size, STB_GLOBAL, sympltname); if (!f) goto out_elf_end; + plt_offset += plt_entry_size; symbols__insert(&dso->symbols[map->type], f); ++nr; } @@ -361,7 +378,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * const char *elf_name = NULL; char *demangled = NULL; symidx = GELF_R_SYM(pos->r_info); - plt_offset += shdr_plt.sh_entsize; gelf_getsym(syms, symidx, &sym); elf_name = elf_sym__name(&sym, symstrs); @@ -372,11 +388,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * "%s@plt", elf_name); free(demangled); - f = symbol__new(plt_offset, shdr_plt.sh_entsize, + f = symbol__new(plt_offset, plt_entry_size, STB_GLOBAL, sympltname); if (!f) goto out_elf_end; + plt_offset += plt_entry_size; symbols__insert(&dso->symbols[map->type], f); ++nr; } @@ -391,7 +408,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * return 0; } -char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name) +char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name) { return demangle_sym(dso, kmodule, elf_name); } @@ -1442,7 +1459,7 @@ static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci, static int kcore_copy__process_modules(void *arg, const char *name __maybe_unused, - u64 start) + u64 start, u64 size __maybe_unused) { struct kcore_copy_info *kci = arg; diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 40bf5d4c0bfd4a6bc9aa4564dc9613e66ca1d7b6..1a5aa35b0100d0a47bc5f904b5809dec3c033cbb 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -377,7 +377,7 @@ void symbol__elf_init(void) char *dso__demangle_sym(struct dso *dso __maybe_unused, int kmodule __maybe_unused, - char *elf_name __maybe_unused) + const char *elf_name __maybe_unused) { return NULL; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e7a98dbd2aed9133d99f38b71b3cac9fb297e0d6..5909ee4c7ade439c4f060724fad05927d2eff34d 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -18,6 +18,7 @@ #include "symbol.h" #include "strlist.h" #include "intlist.h" +#include "namespaces.h" #include "header.h" #include "path.h" #include "sane_ctype.h" @@ -52,6 +53,7 @@ static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__JAVA_JIT, DSO_BINARY_TYPE__DEBUGLINK, DSO_BINARY_TYPE__BUILD_ID_CACHE, + DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO, DSO_BINARY_TYPE__FEDORA_DEBUGINFO, DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__BUILDID_DEBUGINFO, @@ -231,7 +233,8 @@ void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) goto out_unlock; for (next = map__next(curr); next; next = map__next(curr)) { - curr->end = next->start; + if (!curr->end) + curr->end = next->start; curr = next; } @@ -239,7 +242,8 @@ void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) * We still haven't the actual symbols, so guess the * last map final address. */ - curr->end = ~0ULL; + if (!curr->end) + curr->end = ~0ULL; out_unlock: pthread_rwlock_unlock(&maps->lock); @@ -550,7 +554,7 @@ void dso__sort_by_name(struct dso *dso, enum map_type type) int modules__parse(const char *filename, void *arg, int (*process_module)(void *arg, const char *name, - u64 start)) + u64 start, u64 size)) { char *line = NULL; size_t n; @@ -563,8 +567,8 @@ int modules__parse(const char *filename, void *arg, while (1) { char name[PATH_MAX]; - u64 start; - char *sep; + u64 start, size; + char *sep, *endptr; ssize_t line_len; line_len = getline(&line, &n, file); @@ -596,7 +600,11 @@ int modules__parse(const char *filename, void *arg, scnprintf(name, sizeof(name), "[%s]", line); - err = process_module(arg, name, start); + size = strtoul(sep + 1, &endptr, 0); + if (*endptr != ' ' && *endptr != '\t') + continue; + + err = process_module(arg, name, start, size); if (err) break; } @@ -943,7 +951,8 @@ static struct module_info *find_module(const char *name, return NULL; } -static int __read_proc_modules(void *arg, const char *name, u64 start) +static int __read_proc_modules(void *arg, const char *name, u64 start, + u64 size __maybe_unused) { struct rb_root *modules = arg; struct module_info *mi; @@ -1325,14 +1334,15 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, return __dso__load_kallsyms(dso, filename, map, false); } -static int dso__load_perf_map(struct dso *dso, struct map *map) +static int dso__load_perf_map(const char *map_path, struct dso *dso, + struct map *map) { char *line = NULL; size_t n; FILE *file; int nr_syms = 0; - file = fopen(dso->long_name, "r"); + file = fopen(map_path, "r"); if (file == NULL) goto out_failure; @@ -1416,6 +1426,7 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, return kmod && dso->symtab_type == type; case DSO_BINARY_TYPE__BUILD_ID_CACHE: + case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: return true; case DSO_BINARY_TYPE__NOT_FOUND: @@ -1424,6 +1435,44 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, } } +/* Checks for the existence of the perf-.map file in two different + * locations. First, if the process is a separate mount namespace, check in + * that namespace using the pid of the innermost pid namespace. If's not in a + * namespace, or the file can't be found there, try in the mount namespace of + * the tracing process using our view of its pid. + */ +static int dso__find_perf_map(char *filebuf, size_t bufsz, + struct nsinfo **nsip) +{ + struct nscookie nsc; + struct nsinfo *nsi; + struct nsinfo *nnsi; + int rc = -1; + + nsi = *nsip; + + if (nsi->need_setns) { + snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nsi->nstgid); + nsinfo__mountns_enter(nsi, &nsc); + rc = access(filebuf, R_OK); + nsinfo__mountns_exit(&nsc); + if (rc == 0) + return rc; + } + + nnsi = nsinfo__copy(nsi); + if (nnsi) { + nsinfo__put(nsi); + + nnsi->need_setns = false; + snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nnsi->tgid); + *nsip = nnsi; + rc = 0; + } + + return rc; +} + int dso__load(struct dso *dso, struct map *map) { char *name; @@ -1435,8 +1484,21 @@ int dso__load(struct dso *dso, struct map *map) struct symsrc ss_[2]; struct symsrc *syms_ss = NULL, *runtime_ss = NULL; bool kmod; + bool perfmap; unsigned char build_id[BUILD_ID_SIZE]; + struct nscookie nsc; + char newmapname[PATH_MAX]; + const char *map_path = dso->long_name; + + perfmap = strncmp(dso->name, "/tmp/perf-", 10) == 0; + if (perfmap) { + if (dso->nsinfo && (dso__find_perf_map(newmapname, + sizeof(newmapname), &dso->nsinfo) == 0)) { + map_path = newmapname; + } + } + nsinfo__mountns_enter(dso->nsinfo, &nsc); pthread_mutex_lock(&dso->lock); /* check again under the dso->lock */ @@ -1461,19 +1523,19 @@ int dso__load(struct dso *dso, struct map *map) dso->adjust_symbols = 0; - if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { + if (perfmap) { struct stat st; - if (lstat(dso->name, &st) < 0) + if (lstat(map_path, &st) < 0) goto out; if (!symbol_conf.force && st.st_uid && (st.st_uid != geteuid())) { pr_warning("File %s not owned by current user or root, " - "ignoring it (use -f to override).\n", dso->name); + "ignoring it (use -f to override).\n", map_path); goto out; } - ret = dso__load_perf_map(dso, map); + ret = dso__load_perf_map(map_path, dso, map); dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : DSO_BINARY_TYPE__NOT_FOUND; goto out; @@ -1511,9 +1573,15 @@ int dso__load(struct dso *dso, struct map *map) for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) { struct symsrc *ss = &ss_[ss_pos]; bool next_slot = false; + bool is_reg; + bool nsexit; + int sirc; enum dso_binary_type symtab_type = binary_type_symtab[i]; + nsexit = (symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE || + symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO); + if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type)) continue; @@ -1521,12 +1589,20 @@ int dso__load(struct dso *dso, struct map *map) root_dir, name, PATH_MAX)) continue; - if (!is_regular_file(name)) - continue; + if (nsexit) + nsinfo__mountns_exit(&nsc); + + is_reg = is_regular_file(name); + sirc = symsrc__init(ss, dso, name, symtab_type); - /* Name is now the name of the next image to try */ - if (symsrc__init(ss, dso, name, symtab_type) < 0) + if (nsexit) + nsinfo__mountns_enter(dso->nsinfo, &nsc); + + if (!is_reg || sirc < 0) { + if (sirc >= 0) + symsrc__destroy(ss); continue; + } if (!syms_ss && symsrc__has_symtab(ss)) { syms_ss = ss; @@ -1584,6 +1660,7 @@ int dso__load(struct dso *dso, struct map *map) out: dso__set_loaded(dso, map->type); pthread_mutex_unlock(&dso->lock); + nsinfo__mountns_exit(&nsc); return ret; } @@ -1660,7 +1737,7 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map) } if (!symbol_conf.ignore_vmlinux_buildid) - filename = dso__build_id_filename(dso, NULL, 0); + filename = dso__build_id_filename(dso, NULL, 0, false); if (filename != NULL) { err = dso__load_vmlinux(dso, map, filename, true); if (err > 0) diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 41ebba9a2eb2f3849635daf67125a851ff717d95..aad99e7e179bbb8f95bd39cf0d659d136ed2ef6d 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -186,6 +186,7 @@ struct addr_map_symbol { struct symbol *sym; u64 addr; u64 al_addr; + u64 phys_addr; }; struct branch_info { @@ -273,7 +274,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size); int sysfs__read_build_id(const char *filename, void *bf, size_t size); int modules__parse(const char *filename, void *arg, int (*process_module)(void *arg, const char *name, - u64 start)); + u64 start, u64 size)); int filename__read_debuglink(const char *filename, char *debuglink, size_t size); @@ -306,7 +307,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *map); -char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name); +char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name); void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel); void symbols__insert(struct rb_root *symbols, struct symbol *sym); diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index bbb4c195757859a6b7d16ee5868dd8580963ce31..6eea7cff3d4e96473644fcd7c034a8a32abfcb10 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c @@ -15,10 +15,11 @@ #include "syscalltbl.h" #include +#include #ifdef HAVE_SYSCALL_TABLE -#include #include +#include "string2.h" #include "util.h" #if defined(__x86_64__) @@ -105,6 +106,27 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) return sc ? sc->id : -1; } +int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx) +{ + int i; + struct syscall *syscalls = tbl->syscalls.entries; + + for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) { + if (strglobmatch(syscalls[i].name, syscall_glob)) { + *idx = i; + return syscalls[i].id; + } + } + + return -1; +} + +int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx) +{ + *idx = -1; + return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx); +} + #else /* HAVE_SYSCALL_TABLE */ #include @@ -131,4 +153,15 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) { return audit_name_to_syscall(name, tbl->audit_machine); } + +int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused, + const char *syscall_glob __maybe_unused, int *idx __maybe_unused) +{ + return -1; +} + +int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx) +{ + return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx); +} #endif /* HAVE_SYSCALL_TABLE */ diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h index e2951510484f88514b721c4c374da047f2ce4f11..e9fb8786da7c83213dc321c18054fe7db9777af8 100644 --- a/tools/perf/util/syscalltbl.h +++ b/tools/perf/util/syscalltbl.h @@ -17,4 +17,7 @@ void syscalltbl__delete(struct syscalltbl *tbl); const char *syscalltbl__name(const struct syscalltbl *tbl, int id); int syscalltbl__id(struct syscalltbl *tbl, const char *name); +int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx); +int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx); + #endif /* __PERF_SYSCALLTBL_H */ diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 378c418ca0c173ddcc83425d590c32d3d71d2a39..aee9a42102bac264e89e3e698431975006c9681c 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -59,6 +59,8 @@ struct thread *thread__new(pid_t pid, pid_t tid) list_add(&comm->list, &thread->comm_list); refcount_set(&thread->refcnt, 1); RB_CLEAR_NODE(&thread->rb_node); + /* Thread holds first ref to nsdata. */ + thread->nsinfo = nsinfo__new(pid); } return thread; @@ -91,6 +93,7 @@ void thread__delete(struct thread *thread) comm__free(comm); } unwind__finish_access(thread); + nsinfo__zput(thread->nsinfo); free(thread); } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 4eb849e9098f5ca0115cb90527dd9f564476e4ea..cb1a5dd5c2b9b61db889538ba9f60eed158082e4 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -34,6 +34,7 @@ struct thread { void *priv; struct thread_stack *ts; + struct nsinfo *nsinfo; #ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space; struct unwind_libunwind_ops *unwind_libunwind_ops; diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 829471a1c6d76bc637c5fcefbeaec89b8d61d39a..d549e50db397933a5e8f48653cdbe3e09a212713 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -34,6 +34,12 @@ typedef int (*event_oe)(struct perf_tool *tool, union perf_event *event, typedef s64 (*event_op3)(struct perf_tool *tool, union perf_event *event, struct perf_session *session); +enum show_feature_header { + SHOW_FEAT_NO_HEADER = 0, + SHOW_FEAT_HEADER, + SHOW_FEAT_HEADER_FULL_INFO, +}; + struct perf_tool { event_sample sample, read; @@ -63,11 +69,13 @@ struct perf_tool { cpu_map, stat_config, stat, - stat_round; + stat_round, + feature; event_op3 auxtrace; bool ordered_events; bool ordering_requires_timestamps; bool namespace_events; + enum show_feature_header show_feat_hdr; }; #endif /* __PERF_TOOL_H */ diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 988111e0bab592369ecf197d43127dab0dc57975..4c360daa4e242cc493e4957a7d46eca62ecbca09 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -143,13 +143,17 @@ struct strlist *lsdir(const char *name, return list; } -static int slow_copyfile(const char *from, const char *to) +static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) { int err = -1; char *line = NULL; size_t n; - FILE *from_fp = fopen(from, "r"), *to_fp; + FILE *from_fp, *to_fp; + struct nscookie nsc; + nsinfo__mountns_enter(nsi, &nsc); + from_fp = fopen(from, "r"); + nsinfo__mountns_exit(&nsc); if (from_fp == NULL) goto out; @@ -198,15 +202,21 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) return size ? -1 : 0; } -int copyfile_mode(const char *from, const char *to, mode_t mode) +static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, + struct nsinfo *nsi) { int fromfd, tofd; struct stat st; - int err = -1; + int err; char *tmp = NULL, *ptr = NULL; + struct nscookie nsc; - if (stat(from, &st)) + nsinfo__mountns_enter(nsi, &nsc); + err = stat(from, &st); + nsinfo__mountns_exit(&nsc); + if (err) goto out; + err = -1; /* extra 'x' at the end is to reserve space for '.' */ if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { @@ -227,11 +237,13 @@ int copyfile_mode(const char *from, const char *to, mode_t mode) goto out_close_to; if (st.st_size == 0) { /* /proc? do it slowly... */ - err = slow_copyfile(from, tmp); + err = slow_copyfile(from, tmp, nsi); goto out_close_to; } + nsinfo__mountns_enter(nsi, &nsc); fromfd = open(from, O_RDONLY); + nsinfo__mountns_exit(&nsc); if (fromfd < 0) goto out_close_to; @@ -248,6 +260,16 @@ int copyfile_mode(const char *from, const char *to, mode_t mode) return err; } +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) +{ + return copyfile_mode_ns(from, to, 0755, nsi); +} + +int copyfile_mode(const char *from, const char *to, mode_t mode) +{ + return copyfile_mode_ns(from, to, mode, NULL); +} + int copyfile(const char *from, const char *to) { return copyfile_mode(from, to, 0755); @@ -259,6 +281,7 @@ static ssize_t ion(bool is_read, int fd, void *buf, size_t n) size_t left = n; while (left) { + /* buf must be treated as const if !is_read. */ ssize_t ret = is_read ? read(fd, buf, left) : write(fd, buf, left); @@ -286,9 +309,10 @@ ssize_t readn(int fd, void *buf, size_t n) /* * Write exactly 'n' bytes or return an error. */ -ssize_t writen(int fd, void *buf, size_t n) +ssize_t writen(int fd, const void *buf, size_t n) { - return ion(false, fd, buf, n); + /* ion does not modify buf. */ + return ion(false, fd, (void *)buf, n); } size_t hex_width(u64 v) diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 2c9e58a45310446eeb5b1af2859b8ef70e2d8089..b136c271125f02f99b017f070bbf8448ba9df426 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -12,6 +12,7 @@ #include #include #include +#include "namespaces.h" /* General helper functions */ void usage(const char *err) __noreturn; @@ -33,10 +34,11 @@ struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dire bool lsdir_no_dot_filter(const char *name, struct dirent *d); int copyfile(const char *from, const char *to); int copyfile_mode(const char *from, const char *to, mode_t mode); +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 size); ssize_t readn(int fd, void *buf, size_t n); -ssize_t writen(int fd, void *buf, size_t n); +ssize_t writen(int fd, const void *buf, size_t n); size_t hex_width(u64 v); int hex2u64(const char *ptr, u64 *val); @@ -58,4 +60,8 @@ const char *perf_tip(const char *dirpath); int sched_getcpu(void); #endif +#ifndef HAVE_SETNS_SUPPORT +int setns(int fd, int nstype); +#endif + #endif /* GIT_COMPAT_UTIL_H */ diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 5de2e15e2eda9c343246431caf0ba68d9559e614..8a32bb0095e5e61616319c4145124948f9bfb21c 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c @@ -12,7 +12,7 @@ int perf_read_values_init(struct perf_read_values *values) values->threads_max = 16; values->pid = malloc(values->threads_max * sizeof(*values->pid)); values->tid = malloc(values->threads_max * sizeof(*values->tid)); - values->value = malloc(values->threads_max * sizeof(*values->value)); + values->value = zalloc(values->threads_max * sizeof(*values->value)); if (!values->pid || !values->tid || !values->value) { pr_debug("failed to allocate read_values threads arrays"); goto out_free_pid; @@ -98,15 +98,16 @@ static int perf_read_values__findnew_thread(struct perf_read_values *values, return i; } - i = values->threads + 1; - values->value[i] = malloc(values->counters_max * sizeof(**values->value)); + i = values->threads; + + values->value[i] = zalloc(values->counters_max * sizeof(**values->value)); if (!values->value[i]) { pr_debug("failed to allocate read_values counters array"); return -ENOMEM; } values->pid[i] = pid; values->tid[i] = tid; - values->threads = i; + values->threads = i + 1; return i; } @@ -130,12 +131,16 @@ static int perf_read_values__enlarge_counters(struct perf_read_values *values) for (i = 0; i < values->threads; i++) { u64 *value = realloc(values->value[i], counters_max * sizeof(**values->value)); + int j; - if (value) { + if (!value) { pr_debug("failed to enlarge read_values ->values array"); goto out_free_name; } + for (j = values->counters_max; j < counters_max; j++) + value[j] = 0; + values->value[i] = value; } @@ -187,7 +192,7 @@ int perf_read_values_add_value(struct perf_read_values *values, if (cindex < 0) return cindex; - values->value[tindex][cindex] = value; + values->value[tindex][cindex] += value; return 0; } diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c index 7251fdbabceda5e0bb88e4b9ae83f501ea9ad517..c8f415d9877b08503d12e10e1bb0fe463c81e6f1 100644 --- a/tools/perf/util/xyarray.c +++ b/tools/perf/util/xyarray.c @@ -12,6 +12,8 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size) xy->entry_size = entry_size; xy->row_size = row_size; xy->entries = xlen * ylen; + xy->max_x = xlen; + xy->max_y = ylen; } return xy; diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h index 7f30af371b7ee692f23b9bf4aeb354584f453722..4ba726c9087072184b445ddc4e788d7000ade01d 100644 --- a/tools/perf/util/xyarray.h +++ b/tools/perf/util/xyarray.h @@ -7,6 +7,8 @@ struct xyarray { size_t row_size; size_t entry_size; size_t entries; + size_t max_x; + size_t max_y; char contents[]; }; @@ -19,4 +21,14 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y) return &xy->contents[x * xy->row_size + y * xy->entry_size]; } +static inline int xyarray__max_y(struct xyarray *xy) +{ + return xy->max_x; +} + +static inline int xyarray__max_x(struct xyarray *xy) +{ + return xy->max_y; +} + #endif /* _PERF_XYARRAY_H_ */ diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c index 82a2ff896a9559e6a860ba034d5fde6786b04dae..52a39ecf5ca18d38183a577e9d6a014bc8cb30c5 100644 --- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c +++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c @@ -759,7 +759,7 @@ static acpi_status osl_list_bios_tables(void) /* Skip NULL entries in RSDT/XSDT */ - if (!table_address) { + if (table_address == 0) { continue; } @@ -808,7 +808,8 @@ osl_get_bios_table(char *signature, u8 number_of_tables; u8 item_size; u32 current_instance = 0; - acpi_physical_address table_address = 0; + acpi_physical_address table_address; + acpi_physical_address first_table_address = 0; u32 table_length = 0; acpi_status status = AE_OK; u32 i; @@ -820,9 +821,10 @@ osl_get_bios_table(char *signature, ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) || ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) || ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { - if (instance > 0) { - return (AE_LIMIT); - } + +find_next_instance: + + table_address = 0; /* * Get the appropriate address, either 32-bit or 64-bit. Be very @@ -830,41 +832,66 @@ osl_get_bios_table(char *signature, * Note: The 64-bit addresses have priority. */ if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) { - if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) && - gbl_fadt->Xdsdt) { - table_address = - (acpi_physical_address)gbl_fadt->Xdsdt; - } else - if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT) - && gbl_fadt->dsdt) { - table_address = - (acpi_physical_address)gbl_fadt->dsdt; + if (current_instance < 2) { + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_XDSDT) && gbl_fadt->Xdsdt + && current_instance == 0) { + table_address = + (acpi_physical_address)gbl_fadt-> + Xdsdt; + } else + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_DSDT) + && gbl_fadt->dsdt != + first_table_address) { + table_address = + (acpi_physical_address)gbl_fadt-> + dsdt; + } } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { - if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) && - gbl_fadt->Xfacs) { - table_address = - (acpi_physical_address)gbl_fadt->Xfacs; - } else - if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS) - && gbl_fadt->facs) { - table_address = - (acpi_physical_address)gbl_fadt->facs; + if (current_instance < 2) { + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_XFACS) && gbl_fadt->Xfacs + && current_instance == 0) { + table_address = + (acpi_physical_address)gbl_fadt-> + Xfacs; + } else + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_FACS) + && gbl_fadt->facs != + first_table_address) { + table_address = + (acpi_physical_address)gbl_fadt-> + facs; + } } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) { if (!gbl_revision) { return (AE_BAD_SIGNATURE); } - table_address = - (acpi_physical_address)gbl_rsdp. - xsdt_physical_address; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp. + xsdt_physical_address; + } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) { - table_address = - (acpi_physical_address)gbl_rsdp. - rsdt_physical_address; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp. + rsdt_physical_address; + } } else { - table_address = (acpi_physical_address)gbl_rsdp_address; - signature = ACPI_SIG_RSDP; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp_address; + signature = ACPI_SIG_RSDP; + } + } + + if (table_address == 0) { + goto exit_find_table; } /* Now we can get the requested special table */ @@ -875,6 +902,18 @@ osl_get_bios_table(char *signature, } table_length = ap_get_table_length(mapped_table); + if (first_table_address == 0) { + first_table_address = table_address; + } + + /* Match table instance */ + + if (current_instance != instance) { + osl_unmap_table(mapped_table); + mapped_table = NULL; + current_instance++; + goto find_next_instance; + } } else { /* Case for a normal ACPI table */ if (osl_can_use_xsdt()) { @@ -913,7 +952,7 @@ osl_get_bios_table(char *signature, /* Skip NULL entries in RSDT/XSDT */ - if (!table_address) { + if (table_address == 0) { continue; } @@ -946,6 +985,8 @@ osl_get_bios_table(char *signature, } } +exit_find_table: + if (!mapped_table) { return (AE_LIMIT); } diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index 31b5a7f7401555f369800a289652185a216a5a89..d686e11936c45fd318f6b8eeedb741d8177c5696 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -61,7 +61,7 @@ static int ap_is_existing_file(char *pathname); static int ap_is_existing_file(char *pathname) { -#ifndef _GNU_EFI +#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) struct stat stat_info; if (!stat(pathname, &stat_info)) { diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index dd82afa897bde211a41a6a42ce9cb40350f35d3c..943b6b6146834384128c63b47ca6317f5be8fec4 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -300,7 +300,7 @@ static int ap_do_options(int argc, char **argv) * ******************************************************************************/ -#ifndef _GNU_EFI +#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) #else int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[]) diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index d6e1c02ddcfead4532cdc73f2d81207f62a8db5f..4c5a481a850c6d4490db28ae0d6448197e4b4517 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -26,7 +26,7 @@ endif ifneq ($(OUTPUT),) # check that the output directory actually exists -OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) +OUTDIR := $(realpath $(OUTPUT)) $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) endif diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c index 9ea91437898598bf31982f6073ec483e3d51f687..2dccf49985998d834c8d5b11003b31d573cbe683 100644 --- a/tools/power/cpupower/utils/cpupower.c +++ b/tools/power/cpupower/utils/cpupower.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ static int cmd_help(int argc, const char **argv); */ struct cpupower_cpu_info cpupower_cpu_info; int run_as_root; +int base_cpu; /* Affected cpus chosen by -c/--cpu param */ struct bitmask *cpus_chosen; @@ -174,6 +176,7 @@ int main(int argc, const char *argv[]) unsigned int i, ret; struct stat statbuf; struct utsname uts; + char pathname[32]; cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); @@ -198,17 +201,23 @@ int main(int argc, const char *argv[]) argv[0] = cmd = "help"; } - get_cpu_info(0, &cpupower_cpu_info); + base_cpu = sched_getcpu(); + if (base_cpu < 0) { + fprintf(stderr, _("No valid cpus found.\n")); + return EXIT_FAILURE; + } + + get_cpu_info(&cpupower_cpu_info); run_as_root = !geteuid(); if (run_as_root) { ret = uname(&uts); + sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); if (!ret && !strcmp(uts.machine, "x86_64") && - stat("/dev/cpu/0/msr", &statbuf) != 0) { + stat(pathname, &statbuf) != 0) { if (system("modprobe msr") == -1) fprintf(stderr, _("MSR access not available.\n")); } } - for (i = 0; i < ARRAY_SIZE(commands); i++) { struct cmd_struct *p = commands + i; diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index 39c2c7d067bba55cae5cf19983128369af1bb81c..32d37c9be791334f4984d7346eeb338f3f3f57e3 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -42,7 +42,7 @@ cpuid_func(edx); * * TBD: Should there be a cpuid alternative for this if /proc is not mounted? */ -int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info) +int get_cpu_info(struct cpupower_cpu_info *cpu_info) { FILE *fp; char value[64]; @@ -70,7 +70,7 @@ int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info) if (!strncmp(value, "processor\t: ", 12)) sscanf(value, "processor\t: %u", &proc); - if (proc != cpu) + if (proc != (unsigned int)base_cpu) continue; /* Get CPU vendor */ diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 799a18be60aa4628b2dbaa47e8484a802769b558..41da392be448a9abc63ec9032ced298095416bd6 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -34,6 +34,7 @@ /* Internationalization ****************************/ extern int run_as_root; +extern int base_cpu; extern struct bitmask *cpus_chosen; /* Global verbose (-d) stuff *********************************/ @@ -87,11 +88,11 @@ struct cpupower_cpu_info { * * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo * - * Returns 0 on success or a negativ error code + * Returns 0 on success or a negative error code * Only used on x86, below global's struct values are zero/unknown on * other archs */ -extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info); +extern int get_cpu_info(struct cpupower_cpu_info *cpu_info); extern struct cpupower_cpu_info cpupower_cpu_info; /* cpuid and cpuinfo helpers **************************/ diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index 601d719d4e60dfba6f4d104edbf4568691143cd5..a5e7ddf19dbd65bd0dd11f126b50ea9b8b5496f1 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -13,7 +13,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, *support = *active = *states = 0; - ret = get_cpu_info(0, &cpu_info); + ret = get_cpu_info(&cpu_info); if (ret) return ret; diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c index ebeaba6571a380230f921f8209a8d3155baed40b..f794d6bbb7e9f15babce828b99bd3672aa32f3bf 100644 --- a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c @@ -123,7 +123,7 @@ static int hsw_ext_start(void) previous_count[num][cpu] = val; } } - hsw_ext_get_count(TSC, &tsc_at_measure_start, 0); + hsw_ext_get_count(TSC, &tsc_at_measure_start, base_cpu); return 0; } @@ -132,7 +132,7 @@ static int hsw_ext_stop(void) unsigned long long val; int num, cpu; - hsw_ext_get_count(TSC, &tsc_at_measure_end, 0); + hsw_ext_get_count(TSC, &tsc_at_measure_end, base_cpu); for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c index c83f1606970b922af7e4ce8a2420ed57dd51b8b2..d7c2a6d13dea1a1d4734fb51842eb12b86ef0317 100644 --- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c @@ -80,7 +80,8 @@ static int *is_valid; static int mperf_get_tsc(unsigned long long *tsc) { int ret; - ret = read_msr(0, MSR_TSC, tsc); + + ret = read_msr(base_cpu, MSR_TSC, tsc); if (ret) dprint("Reading TSC MSR failed, returning %llu\n", *tsc); return ret; diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c index d2a91dd0d5637d70bfdba93ddf7d92ea84e4dc51..abf8cb5f734992fd086c32f648b4118b8c056607 100644 --- a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c @@ -129,7 +129,7 @@ static int nhm_start(void) int num, cpu; unsigned long long dbg, val; - nhm_get_count(TSC, &tsc_at_measure_start, 0); + nhm_get_count(TSC, &tsc_at_measure_start, base_cpu); for (num = 0; num < NHM_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { @@ -137,7 +137,7 @@ static int nhm_start(void) previous_count[num][cpu] = val; } } - nhm_get_count(TSC, &dbg, 0); + nhm_get_count(TSC, &dbg, base_cpu); dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start); return 0; } @@ -148,7 +148,7 @@ static int nhm_stop(void) unsigned long long dbg; int num, cpu; - nhm_get_count(TSC, &tsc_at_measure_end, 0); + nhm_get_count(TSC, &tsc_at_measure_end, base_cpu); for (num = 0; num < NHM_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { @@ -156,7 +156,7 @@ static int nhm_stop(void) current_count[num][cpu] = val; } } - nhm_get_count(TSC, &dbg, 0); + nhm_get_count(TSC, &dbg, base_cpu); dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end); return 0; diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c index efc8a69c9abafea4c492b52457d5f645254c3180..a2b45219648df47b4c648bd0ba1d982d79a2b2da 100644 --- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c @@ -120,7 +120,7 @@ static int snb_start(void) previous_count[num][cpu] = val; } } - snb_get_count(TSC, &tsc_at_measure_start, 0); + snb_get_count(TSC, &tsc_at_measure_start, base_cpu); return 0; } @@ -129,7 +129,7 @@ static int snb_stop(void) unsigned long long val; int num, cpu; - snb_get_count(TSC, &tsc_at_measure_end, 0); + snb_get_count(TSC, &tsc_at_measure_end, base_cpu); for (num = 0; num < SNB_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { diff --git a/tools/power/pm-graph/Makefile b/tools/power/pm-graph/Makefile index 4d0ccc89e6c67b7a56b2fe5c2f4fb14e1e42e9a0..32f40eacdafeeb5976ecbbb6272b10780b549043 100644 --- a/tools/power/pm-graph/Makefile +++ b/tools/power/pm-graph/Makefile @@ -4,7 +4,7 @@ DESTDIR ?= all: @echo "Nothing to build" -install : +install : uninstall install -d $(DESTDIR)$(PREFIX)/lib/pm-graph install analyze_suspend.py $(DESTDIR)$(PREFIX)/lib/pm-graph install analyze_boot.py $(DESTDIR)$(PREFIX)/lib/pm-graph @@ -17,12 +17,15 @@ install : install sleepgraph.8 $(DESTDIR)$(PREFIX)/share/man/man8 uninstall : - rm $(DESTDIR)$(PREFIX)/share/man/man8/bootgraph.8 - rm $(DESTDIR)$(PREFIX)/share/man/man8/sleepgraph.8 + rm -f $(DESTDIR)$(PREFIX)/share/man/man8/bootgraph.8 + rm -f $(DESTDIR)$(PREFIX)/share/man/man8/sleepgraph.8 - rm $(DESTDIR)$(PREFIX)/bin/bootgraph - rm $(DESTDIR)$(PREFIX)/bin/sleepgraph + rm -f $(DESTDIR)$(PREFIX)/bin/bootgraph + rm -f $(DESTDIR)$(PREFIX)/bin/sleepgraph - rm $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_boot.py - rm $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_suspend.py - rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph + rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_boot.py + rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_suspend.py + rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/*.pyc + if [ -d $(DESTDIR)$(PREFIX)/lib/pm-graph ] ; then \ + rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph; \ + fi; diff --git a/tools/power/pm-graph/analyze_boot.py b/tools/power/pm-graph/analyze_boot.py index 3e1dcbbf1adcfec240ef238f76f7126eac61b9ab..e83df141a59765b2db300ffd1cc0066a329f00f0 100755 --- a/tools/power/pm-graph/analyze_boot.py +++ b/tools/power/pm-graph/analyze_boot.py @@ -42,7 +42,7 @@ import analyze_suspend as aslib # store system values and test parameters class SystemValues(aslib.SystemValues): title = 'BootGraph' - version = 2.0 + version = '2.1' hostname = 'localhost' testtime = '' kernel = '' @@ -50,9 +50,14 @@ class SystemValues(aslib.SystemValues): ftracefile = '' htmlfile = 'bootgraph.html' outfile = '' - phoronix = False - addlogs = False + testdir = '' + testdirprefix = 'boot' + embedded = False + testlog = False + dmesglog = False + ftracelog = False useftrace = False + usecallgraph = False usedevsrc = True suspendmode = 'boot' max_graph_depth = 2 @@ -61,10 +66,12 @@ class SystemValues(aslib.SystemValues): manual = False iscronjob = False timeformat = '%.6f' + bootloader = 'grub' + blexec = [] def __init__(self): if('LOG_FILE' in os.environ and 'TEST_RESULTS_IDENTIFIER' in os.environ): - self.phoronix = True - self.addlogs = True + self.embedded = True + self.dmesglog = True self.outfile = os.environ['LOG_FILE'] self.htmlfile = os.environ['LOG_FILE'] self.hostname = platform.node() @@ -76,42 +83,80 @@ class SystemValues(aslib.SystemValues): self.kernel = self.kernelVersion(val) else: self.kernel = 'unknown' + self.testdir = datetime.now().strftime('boot-%y%m%d-%H%M%S') def kernelVersion(self, msg): return msg.split()[2] + def checkFtraceKernelVersion(self): + val = tuple(map(int, self.kernel.split('-')[0].split('.'))) + if val >= (4, 10, 0): + return True + return False def kernelParams(self): cmdline = 'initcall_debug log_buf_len=32M' if self.useftrace: - cmdline += ' trace_buf_size=128M trace_clock=global '\ + if self.cpucount > 0: + bs = min(self.memtotal / 2, 2*1024*1024) / self.cpucount + else: + bs = 131072 + cmdline += ' trace_buf_size=%dK trace_clock=global '\ 'trace_options=nooverwrite,funcgraph-abstime,funcgraph-cpu,'\ 'funcgraph-duration,funcgraph-proc,funcgraph-tail,'\ 'nofuncgraph-overhead,context-info,graph-time '\ 'ftrace=function_graph '\ 'ftrace_graph_max_depth=%d '\ 'ftrace_graph_filter=%s' % \ - (self.max_graph_depth, self.graph_filter) + (bs, self.max_graph_depth, self.graph_filter) return cmdline def setGraphFilter(self, val): - fp = open(self.tpath+'available_filter_functions') - master = fp.read().split('\n') - fp.close() + master = self.getBootFtraceFilterFunctions() + fs = '' for i in val.split(','): func = i.strip() + if func == '': + doError('badly formatted filter function string') + if '[' in func or ']' in func: + doError('loadable module functions not allowed - "%s"' % func) + if ' ' in func: + doError('spaces found in filter functions - "%s"' % func) if func not in master: doError('function "%s" not available for ftrace' % func) - self.graph_filter = val + if not fs: + fs = func + else: + fs += ','+func + if not fs: + doError('badly formatted filter function string') + self.graph_filter = fs + def getBootFtraceFilterFunctions(self): + self.rootCheck(True) + fp = open(self.tpath+'available_filter_functions') + fulllist = fp.read().split('\n') + fp.close() + list = [] + for i in fulllist: + if not i or ' ' in i or '[' in i or ']' in i: + continue + list.append(i) + return list + def myCronJob(self, line): + if '@reboot' not in line: + return False + if 'bootgraph' in line or 'analyze_boot.py' in line or '-cronjob' in line: + return True + return False def cronjobCmdString(self): cmdline = '%s -cronjob' % os.path.abspath(sys.argv[0]) args = iter(sys.argv[1:]) for arg in args: if arg in ['-h', '-v', '-cronjob', '-reboot']: continue - elif arg in ['-o', '-dmesg', '-ftrace', '-filter']: + elif arg in ['-o', '-dmesg', '-ftrace', '-func']: args.next() continue cmdline += ' '+arg if self.graph_filter != 'do_one_initcall': - cmdline += ' -filter "%s"' % self.graph_filter - cmdline += ' -o "%s"' % os.path.abspath(self.htmlfile) + cmdline += ' -func "%s"' % self.graph_filter + cmdline += ' -o "%s"' % os.path.abspath(self.testdir) return cmdline def manualRebootRequired(self): cmdline = self.kernelParams() @@ -121,6 +166,39 @@ class SystemValues(aslib.SystemValues): print '3. After reboot, re-run this tool with the same arguments but no command (w/o -reboot or -manual).\n' print 'CMDLINE="%s"' % cmdline sys.exit() + def getExec(self, cmd): + dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin', + '/usr/local/sbin', '/usr/local/bin'] + for path in dirlist: + cmdfull = os.path.join(path, cmd) + if os.path.exists(cmdfull): + return cmdfull + return '' + def blGrub(self): + blcmd = '' + for cmd in ['update-grub', 'grub-mkconfig', 'grub2-mkconfig']: + if blcmd: + break + blcmd = self.getExec(cmd) + if not blcmd: + doError('[GRUB] missing update command') + if not os.path.exists('/etc/default/grub'): + doError('[GRUB] missing /etc/default/grub') + if 'grub2' in blcmd: + cfg = '/boot/grub2/grub.cfg' + else: + cfg = '/boot/grub/grub.cfg' + if not os.path.exists(cfg): + doError('[GRUB] missing %s' % cfg) + if 'update-grub' in blcmd: + self.blexec = [blcmd] + else: + self.blexec = [blcmd, '-o', cfg] + def getBootLoader(self): + if self.bootloader == 'grub': + self.blGrub() + else: + doError('unknown boot loader: %s' % self.bootloader) sysvals = SystemValues() @@ -136,20 +214,23 @@ class Data(aslib.Data): idstr = '' html_device_id = 0 valid = False - initstart = 0.0 + tUserMode = 0.0 boottime = '' - phases = ['boot'] + phases = ['kernel', 'user'] do_one_initcall = False def __init__(self, num): self.testnumber = num self.idstr = 'a' self.dmesgtext = [] self.dmesg = { - 'boot': {'list': dict(), 'start': -1.0, 'end': -1.0, 'row': 0, 'color': '#dddddd'} + 'kernel': {'list': dict(), 'start': -1.0, 'end': -1.0, 'row': 0, + 'order': 0, 'color': 'linear-gradient(to bottom, #fff, #bcf)'}, + 'user': {'list': dict(), 'start': -1.0, 'end': -1.0, 'row': 0, + 'order': 1, 'color': '#fff'} } def deviceTopology(self): return '' - def newAction(self, phase, name, start, end, ret, ulen): + def newAction(self, phase, name, pid, start, end, ret, ulen): # new device callback for a specific phase self.html_device_id += 1 devid = '%s%d' % (self.idstr, self.html_device_id) @@ -163,41 +244,46 @@ class Data(aslib.Data): name = '%s[%d]' % (origname, i) i += 1 list[name] = {'name': name, 'start': start, 'end': end, - 'pid': 0, 'length': length, 'row': 0, 'id': devid, + 'pid': pid, 'length': length, 'row': 0, 'id': devid, 'ret': ret, 'ulen': ulen } return name - def deviceMatch(self, cg): + def deviceMatch(self, pid, cg): if cg.end - cg.start == 0: return True - list = self.dmesg['boot']['list'] - for devname in list: - dev = list[devname] - if cg.name == 'do_one_initcall': - if(cg.start <= dev['start'] and cg.end >= dev['end'] and dev['length'] > 0): - dev['ftrace'] = cg - self.do_one_initcall = True - return True - else: - if(cg.start > dev['start'] and cg.end < dev['end']): - if 'ftraces' not in dev: - dev['ftraces'] = [] - dev['ftraces'].append(cg) - return True + for p in data.phases: + list = self.dmesg[p]['list'] + for devname in list: + dev = list[devname] + if pid != dev['pid']: + continue + if cg.name == 'do_one_initcall': + if(cg.start <= dev['start'] and cg.end >= dev['end'] and dev['length'] > 0): + dev['ftrace'] = cg + self.do_one_initcall = True + return True + else: + if(cg.start > dev['start'] and cg.end < dev['end']): + if 'ftraces' not in dev: + dev['ftraces'] = [] + dev['ftraces'].append(cg) + return True return False # ----------------- FUNCTIONS -------------------- -# Function: loadKernelLog +# Function: parseKernelLog # Description: -# Load a raw kernel log from dmesg -def loadKernelLog(): +# parse a kernel log for boot data +def parseKernelLog(): + phase = 'kernel' data = Data(0) - data.dmesg['boot']['start'] = data.start = ktime = 0.0 + data.dmesg['kernel']['start'] = data.start = ktime = 0.0 sysvals.stamp = { 'time': datetime.now().strftime('%B %d %Y, %I:%M:%S %p'), 'host': sysvals.hostname, 'mode': 'boot', 'kernel': ''} + tp = aslib.TestProps() devtemp = dict() if(sysvals.dmesgfile): lf = open(sysvals.dmesgfile, 'r') @@ -205,6 +291,13 @@ def loadKernelLog(): lf = Popen('dmesg', stdout=PIPE).stdout for line in lf: line = line.replace('\r\n', '') + # grab the stamp and sysinfo + if re.match(tp.stampfmt, line): + tp.stamp = line + continue + elif re.match(tp.sysinfofmt, line): + tp.sysinfo = line + continue idx = line.find('[') if idx > 1: line = line[idx:] @@ -215,7 +308,6 @@ def loadKernelLog(): if(ktime > 120): break msg = m.group('msg') - data.end = data.initstart = ktime data.dmesgtext.append(line) if(ktime == 0.0 and re.match('^Linux version .*', msg)): if(not sysvals.stamp['kernel']): @@ -228,43 +320,39 @@ def loadKernelLog(): data.boottime = bt.strftime('%Y-%m-%d_%H:%M:%S') sysvals.stamp['time'] = bt.strftime('%B %d %Y, %I:%M:%S %p') continue - m = re.match('^calling *(?P.*)\+.*', msg) + m = re.match('^calling *(?P.*)\+.* @ (?P

    [0-9]*)', msg) if(m): - devtemp[m.group('f')] = ktime + func = m.group('f') + pid = int(m.group('p')) + devtemp[func] = (ktime, pid) continue m = re.match('^initcall *(?P.*)\+.* returned (?P.*) after (?P.*) usecs', msg) if(m): data.valid = True + data.end = ktime f, r, t = m.group('f', 'r', 't') if(f in devtemp): - data.newAction('boot', f, devtemp[f], ktime, int(r), int(t)) - data.end = ktime + start, pid = devtemp[f] + data.newAction(phase, f, pid, start, ktime, int(r), int(t)) del devtemp[f] continue if(re.match('^Freeing unused kernel memory.*', msg)): - break - - data.dmesg['boot']['end'] = data.end + data.tUserMode = ktime + data.dmesg['kernel']['end'] = ktime + data.dmesg['user']['start'] = ktime + phase = 'user' + + if tp.stamp: + sysvals.stamp = 0 + tp.parseStamp(data, sysvals) + data.dmesg['user']['end'] = data.end lf.close() return data -# Function: loadTraceLog +# Function: parseTraceLog # Description: # Check if trace is available and copy to a temp file -def loadTraceLog(data): - # load the data to a temp file if none given - if not sysvals.ftracefile: - lib = aslib.sysvals - aslib.rootCheck(True) - if not lib.verifyFtrace(): - doError('ftrace not available') - if lib.fgetVal('current_tracer').strip() != 'function_graph': - doError('ftrace not configured for a boot callgraph') - sysvals.ftracefile = '/tmp/boot_ftrace.%s.txt' % os.getpid() - call('cat '+lib.tpath+'trace > '+sysvals.ftracefile, shell=True) - if not sysvals.ftracefile: - doError('No trace data available') - +def parseTraceLog(data): # parse the trace log ftemp = dict() tp = aslib.TestProps() @@ -306,9 +394,29 @@ def loadTraceLog(data): print('Sanity check failed for %s-%d' % (proc, pid)) continue # match cg data to devices - if not data.deviceMatch(cg): + if not data.deviceMatch(pid, cg): print ' BAD: %s %s-%d [%f - %f]' % (cg.name, proc, pid, cg.start, cg.end) +# Function: retrieveLogs +# Description: +# Create copies of dmesg and/or ftrace for later processing +def retrieveLogs(): + # check ftrace is configured first + if sysvals.useftrace: + tracer = sysvals.fgetVal('current_tracer').strip() + if tracer != 'function_graph': + doError('ftrace not configured for a boot callgraph') + # create the folder and get dmesg + sysvals.systemInfo(aslib.dmidecode(sysvals.mempath)) + sysvals.initTestOutput('boot') + sysvals.writeDatafileHeader(sysvals.dmesgfile) + call('dmesg >> '+sysvals.dmesgfile, shell=True) + if not sysvals.useftrace: + return + # get ftrace + sysvals.writeDatafileHeader(sysvals.ftracefile) + call('cat '+sysvals.tpath+'trace >> '+sysvals.ftracefile, shell=True) + # Function: colorForName # Description: # Generate a repeatable color from a list for a given name @@ -353,18 +461,19 @@ def cgOverview(cg, minlen): # testruns: array of Data objects from parseKernelLog or parseTraceLog # Output: # True if the html file was created, false if it failed -def createBootGraph(data, embedded): +def createBootGraph(data): # html function templates html_srccall = '

    \n' html_timetotal = '\n'\ - ''\ + ''\ + ''\ '\n
    Time from Kernel Boot to start of User Mode: {0} msInit process starts @ {0} msLast initcall ends @ {1} ms
    \n' # device timeline devtl = aslib.Timeline(100, 20) # write the test title and general info header - devtl.createHeader(sysvals, 'noftrace') + devtl.createHeader(sysvals) # Generate the header for this timeline t0 = data.start @@ -373,84 +482,98 @@ def createBootGraph(data, embedded): if(tTotal == 0): print('ERROR: No timeline data') return False - boot_time = '%.0f'%(tTotal*1000) - devtl.html += html_timetotal.format(boot_time) + user_mode = '%.0f'%(data.tUserMode*1000) + last_init = '%.0f'%(tTotal*1000) + devtl.html += html_timetotal.format(user_mode, last_init) # determine the maximum number of rows we need to draw - phase = 'boot' - list = data.dmesg[phase]['list'] devlist = [] - for devname in list: - d = aslib.DevItem(0, phase, list[devname]) - devlist.append(d) - devtl.getPhaseRows(devlist) + for p in data.phases: + list = data.dmesg[p]['list'] + for devname in list: + d = aslib.DevItem(0, p, list[devname]) + devlist.append(d) + devtl.getPhaseRows(devlist, 0, 'start') devtl.calcTotalRows() # draw the timeline background devtl.createZoomBox() - boot = data.dmesg[phase] - length = boot['end']-boot['start'] - left = '%.3f' % (((boot['start']-t0)*100.0)/tTotal) - width = '%.3f' % ((length*100.0)/tTotal) - devtl.html += devtl.html_tblock.format(phase, left, width, devtl.scaleH) - devtl.html += devtl.html_phase.format('0', '100', \ - '%.3f'%devtl.scaleH, '%.3f'%devtl.bodyH, \ - 'white', '') + devtl.html += devtl.html_tblock.format('boot', '0', '100', devtl.scaleH) + for p in data.phases: + phase = data.dmesg[p] + length = phase['end']-phase['start'] + left = '%.3f' % (((phase['start']-t0)*100.0)/tTotal) + width = '%.3f' % ((length*100.0)/tTotal) + devtl.html += devtl.html_phase.format(left, width, \ + '%.3f'%devtl.scaleH, '%.3f'%devtl.bodyH, \ + phase['color'], '') # draw the device timeline num = 0 devstats = dict() - for devname in sorted(list): - cls, color = colorForName(devname) - dev = list[devname] - info = '@|%.3f|%.3f|%.3f|%d' % (dev['start']*1000.0, dev['end']*1000.0, - dev['ulen']/1000.0, dev['ret']) - devstats[dev['id']] = {'info':info} - dev['color'] = color - height = devtl.phaseRowHeight(0, phase, dev['row']) - top = '%.6f' % ((dev['row']*height) + devtl.scaleH) - left = '%.6f' % (((dev['start']-t0)*100)/tTotal) - width = '%.6f' % (((dev['end']-dev['start'])*100)/tTotal) - length = ' (%0.3f ms) ' % ((dev['end']-dev['start'])*1000) - devtl.html += devtl.html_device.format(dev['id'], - devname+length+'kernel_mode', left, top, '%.3f'%height, - width, devname, ' '+cls, '') - rowtop = devtl.phaseRowTop(0, phase, dev['row']) - height = '%.6f' % (devtl.rowH / 2) - top = '%.6f' % (rowtop + devtl.scaleH + (devtl.rowH / 2)) - if data.do_one_initcall: - if('ftrace' not in dev): + for phase in data.phases: + list = data.dmesg[phase]['list'] + for devname in sorted(list): + cls, color = colorForName(devname) + dev = list[devname] + info = '@|%.3f|%.3f|%.3f|%d' % (dev['start']*1000.0, dev['end']*1000.0, + dev['ulen']/1000.0, dev['ret']) + devstats[dev['id']] = {'info':info} + dev['color'] = color + height = devtl.phaseRowHeight(0, phase, dev['row']) + top = '%.6f' % ((dev['row']*height) + devtl.scaleH) + left = '%.6f' % (((dev['start']-t0)*100)/tTotal) + width = '%.6f' % (((dev['end']-dev['start'])*100)/tTotal) + length = ' (%0.3f ms) ' % ((dev['end']-dev['start'])*1000) + devtl.html += devtl.html_device.format(dev['id'], + devname+length+phase+'_mode', left, top, '%.3f'%height, + width, devname, ' '+cls, '') + rowtop = devtl.phaseRowTop(0, phase, dev['row']) + height = '%.6f' % (devtl.rowH / 2) + top = '%.6f' % (rowtop + devtl.scaleH + (devtl.rowH / 2)) + if data.do_one_initcall: + if('ftrace' not in dev): + continue + cg = dev['ftrace'] + large, stats = cgOverview(cg, 0.001) + devstats[dev['id']]['fstat'] = stats + for l in large: + left = '%f' % (((l.time-t0)*100)/tTotal) + width = '%f' % (l.length*100/tTotal) + title = '%s (%0.3fms)' % (l.name, l.length * 1000.0) + devtl.html += html_srccall.format(l.name, left, + top, height, width, title, 'x%d'%num) + num += 1 + continue + if('ftraces' not in dev): continue - cg = dev['ftrace'] - large, stats = cgOverview(cg, 0.001) - devstats[dev['id']]['fstat'] = stats - for l in large: - left = '%f' % (((l.time-t0)*100)/tTotal) - width = '%f' % (l.length*100/tTotal) - title = '%s (%0.3fms)' % (l.name, l.length * 1000.0) - devtl.html += html_srccall.format(l.name, left, - top, height, width, title, 'x%d'%num) + for cg in dev['ftraces']: + left = '%f' % (((cg.start-t0)*100)/tTotal) + width = '%f' % ((cg.end-cg.start)*100/tTotal) + cglen = (cg.end - cg.start) * 1000.0 + title = '%s (%0.3fms)' % (cg.name, cglen) + cg.id = 'x%d' % num + devtl.html += html_srccall.format(cg.name, left, + top, height, width, title, dev['id']+cg.id) num += 1 - continue - if('ftraces' not in dev): - continue - for cg in dev['ftraces']: - left = '%f' % (((cg.start-t0)*100)/tTotal) - width = '%f' % ((cg.end-cg.start)*100/tTotal) - cglen = (cg.end - cg.start) * 1000.0 - title = '%s (%0.3fms)' % (cg.name, cglen) - cg.id = 'x%d' % num - devtl.html += html_srccall.format(cg.name, left, - top, height, width, title, dev['id']+cg.id) - num += 1 # draw the time scale, try to make the number of labels readable - devtl.createTimeScale(t0, tMax, tTotal, phase) + devtl.createTimeScale(t0, tMax, tTotal, 'boot') devtl.html += '\n' # timeline is finished devtl.html += '\n\n' + # draw a legend which describes the phases by color + devtl.html += '
    \n' + pdelta = 20.0 + pmargin = 36.0 + for phase in data.phases: + order = '%.2f' % ((data.dmesg[phase]['order'] * pdelta) + pmargin) + devtl.html += devtl.html_legend.format(order, \ + data.dmesg[phase]['color'], phase+'_mode', phase[0]) + devtl.html += '
    \n' + if(sysvals.outfile == sysvals.htmlfile): hf = open(sysvals.htmlfile, 'a') else: @@ -474,7 +597,7 @@ def createBootGraph(data, embedded): .fstat td {text-align:left;width:35px;}\n\ .srccall {position:absolute;font-size:10px;z-index:7;overflow:hidden;color:black;text-align:center;white-space:nowrap;border-radius:5px;border:1px solid black;background:linear-gradient(to bottom right,#CCC,#969696);}\n\ .srccall:hover {color:white;font-weight:bold;border:1px solid white;}\n' - if(not embedded): + if(not sysvals.embedded): aslib.addCSS(hf, sysvals, 1, False, extra) # write the device timeline @@ -495,9 +618,11 @@ def createBootGraph(data, embedded): html = \ '
    \n'\ '\n'\ + '
    \n' + for p in data.phases: + phase = data.dmesg[p] + html += devtl.html_phaselet.format(p+'_mode', '0', '100', phase['color']) + html += '
    \n\n'\ '\n' hf.write(html) @@ -507,21 +632,21 @@ def createBootGraph(data, embedded): aslib.addCallgraphs(sysvals, hf, data) # add the dmesg log as a hidden div - if sysvals.addlogs: + if sysvals.dmesglog: hf.write('\n') - if(not embedded): + if(not sysvals.embedded): # write the footer and close aslib.addScriptCode(hf, [data]) hf.write('\n\n') else: # embedded out will be loaded in a page, skip the js hf.write('' % \ - (data.start*1000, data.initstart*1000)) + (data.start*1000, data.end*1000)) hf.close() return True @@ -533,17 +658,20 @@ def updateCron(restore=False): if not restore: sysvals.rootUser(True) crondir = '/var/spool/cron/crontabs/' - cronfile = crondir+'root' - backfile = crondir+'root-analyze_boot-backup' + if not os.path.exists(crondir): + crondir = '/var/spool/cron/' if not os.path.exists(crondir): doError('%s not found' % crondir) - out = Popen(['which', 'crontab'], stdout=PIPE).stdout.read() - if not out: + cronfile = crondir+'root' + backfile = crondir+'root-analyze_boot-backup' + cmd = sysvals.getExec('crontab') + if not cmd: doError('crontab not found') # on restore: move the backup cron back into place if restore: if os.path.exists(backfile): shutil.move(backfile, cronfile) + call([cmd, cronfile]) return # backup current cron and install new one with reboot if os.path.exists(cronfile): @@ -556,13 +684,13 @@ def updateCron(restore=False): fp = open(backfile, 'r') op = open(cronfile, 'w') for line in fp: - if '@reboot' not in line: + if not sysvals.myCronJob(line): op.write(line) continue fp.close() op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) op.close() - res = call('crontab %s' % cronfile, shell=True) + res = call([cmd, cronfile]) except Exception, e: print 'Exception: %s' % str(e) shutil.move(backfile, cronfile) @@ -577,25 +705,16 @@ def updateGrub(restore=False): # call update-grub on restore if restore: try: - call(['update-grub'], stderr=PIPE, stdout=PIPE, + call(sysvals.blexec, stderr=PIPE, stdout=PIPE, env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) except Exception, e: print 'Exception: %s\n' % str(e) return - # verify we can do this - sysvals.rootUser(True) - grubfile = '/etc/default/grub' - if not os.path.exists(grubfile): - print 'ERROR: Unable to set the kernel parameters via grub.\n' - sysvals.manualRebootRequired() - out = Popen(['which', 'update-grub'], stdout=PIPE).stdout.read() - if not out: - print 'ERROR: Unable to set the kernel parameters via grub.\n' - sysvals.manualRebootRequired() - # extract the option and create a grub config without it + sysvals.rootUser(True) tgtopt = 'GRUB_CMDLINE_LINUX_DEFAULT' cmdline = '' + grubfile = '/etc/default/grub' tempfile = '/etc/default/grub.analyze_boot' shutil.move(grubfile, tempfile) res = -1 @@ -622,7 +741,7 @@ def updateGrub(restore=False): # if the target option value is in quotes, strip them sp = '"' val = cmdline.strip() - if val[0] == '\'' or val[0] == '"': + if val and (val[0] == '\'' or val[0] == '"'): sp = val[0] val = val.strip(sp) cmdline = val @@ -633,7 +752,7 @@ def updateGrub(restore=False): # write out the updated target option op.write('\n%s=%s%s%s\n' % (tgtopt, sp, cmdline, sp)) op.close() - res = call('update-grub') + res = call(sysvals.blexec) os.remove(grubfile) except Exception, e: print 'Exception: %s' % str(e) @@ -641,10 +760,18 @@ def updateGrub(restore=False): # cleanup shutil.move(tempfile, grubfile) if res != 0: - doError('update-grub failed') + doError('update grub failed') -# Function: doError +# Function: updateKernelParams # Description: +# update boot conf for all kernels with our parameters +def updateKernelParams(restore=False): + # find the boot loader + sysvals.getBootLoader() + if sysvals.bootloader == 'grub': + updateGrub(restore) + +# Function: doError Description: # generic error function for catastrphic failures # Arguments: # msg: the error message to print @@ -660,7 +787,7 @@ def doError(msg, help=False): # print out the help text def printHelp(): print('') - print('%s v%.1f' % (sysvals.title, sysvals.version)) + print('%s v%s' % (sysvals.title, sysvals.version)) print('Usage: bootgraph ') print('') print('Description:') @@ -669,13 +796,19 @@ def printHelp(): print(' the start of the init process.') print('') print(' If no specific command is given the tool reads the current dmesg') - print(' and/or ftrace log and outputs bootgraph.html') + print(' and/or ftrace log and creates a timeline') + print('') + print(' Generates output files in subdirectory: boot-yymmdd-HHMMSS') + print(' HTML output: _boot.html') + print(' raw dmesg output: _boot_dmesg.txt') + print(' raw ftrace output: _boot_ftrace.txt') print('') print('Options:') print(' -h Print this help text') print(' -v Print the current tool version') print(' -addlogs Add the dmesg log to the html output') - print(' -o file Html timeline name (default: bootgraph.html)') + print(' -o name Overrides the output subdirectory name when running a new test') + print(' default: boot-{date}-{time}') print(' [advanced]') print(' -f Use ftrace to add function detail (default: disabled)') print(' -callgraph Add callgraph detail, can be very large (default: disabled)') @@ -683,13 +816,18 @@ def printHelp(): print(' -mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)') print(' -timeprec N Number of significant digits in timestamps (0:S, 3:ms, [6:us])') print(' -expandcg pre-expand the callgraph data in the html output (default: disabled)') - print(' -filter list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)') - print(' [commands]') + print(' -func list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)') + print(' -cgfilter S Filter the callgraph output in the timeline') + print(' -bl name Use the following boot loader for kernel params (default: grub)') print(' -reboot Reboot the machine automatically and generate a new timeline') - print(' -manual Show the requirements to generate a new timeline manually') - print(' -dmesg file Load a stored dmesg file (used with -ftrace)') - print(' -ftrace file Load a stored ftrace file (used with -dmesg)') + print(' -manual Show the steps to generate a new timeline manually (used with -reboot)') + print('') + print('Other commands:') print(' -flistall Print all functions capable of being captured in ftrace') + print(' -sysinfo Print out system info extracted from BIOS') + print(' [redo]') + print(' -dmesg file Create HTML output using dmesg input (used with -ftrace)') + print(' -ftrace file Create HTML output using ftrace input (used with -dmesg)') print('') return True @@ -698,14 +836,15 @@ def printHelp(): if __name__ == '__main__': # loop through the command line arguments cmd = '' - simplecmds = ['-updategrub', '-flistall'] + testrun = True + simplecmds = ['-sysinfo', '-kpupdate', '-flistall', '-checkbl'] args = iter(sys.argv[1:]) for arg in args: if(arg == '-h'): printHelp() sys.exit() elif(arg == '-v'): - print("Version %.1f" % sysvals.version) + print("Version %s" % sysvals.version) sys.exit() elif(arg in simplecmds): cmd = arg[1:] @@ -716,16 +855,32 @@ if __name__ == '__main__': sysvals.usecallgraph = True elif(arg == '-mincg'): sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) + elif(arg == '-cgfilter'): + try: + val = args.next() + except: + doError('No callgraph functions supplied', True) + sysvals.setDeviceFilter(val) + elif(arg == '-bl'): + try: + val = args.next() + except: + doError('No boot loader name supplied', True) + if val.lower() not in ['grub']: + doError('Unknown boot loader: %s' % val, True) + sysvals.bootloader = val.lower() elif(arg == '-timeprec'): sysvals.setPrecision(aslib.getArgInt('-timeprec', args, 0, 6)) elif(arg == '-maxdepth'): sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) - elif(arg == '-filter'): + elif(arg == '-func'): try: val = args.next() except: doError('No filter functions supplied', True) - aslib.rootCheck(True) + sysvals.useftrace = True + sysvals.usecallgraph = True + sysvals.rootCheck(True) sysvals.setGraphFilter(val) elif(arg == '-ftrace'): try: @@ -734,9 +889,10 @@ if __name__ == '__main__': doError('No ftrace file supplied', True) if(os.path.exists(val) == False): doError('%s does not exist' % val) + testrun = False sysvals.ftracefile = val elif(arg == '-addlogs'): - sysvals.addlogs = True + sysvals.dmesglog = True elif(arg == '-expandcg'): sysvals.cgexp = True elif(arg == '-dmesg'): @@ -748,18 +904,15 @@ if __name__ == '__main__': doError('%s does not exist' % val) if(sysvals.htmlfile == val or sysvals.outfile == val): doError('Output filename collision') + testrun = False sysvals.dmesgfile = val elif(arg == '-o'): try: val = args.next() except: - doError('No HTML filename supplied', True) - if(sysvals.dmesgfile == val or sysvals.ftracefile == val): - doError('Output filename collision') - sysvals.htmlfile = val + doError('No subdirectory name supplied', True) + sysvals.testdir = sysvals.setOutputFolder(val) elif(arg == '-reboot'): - if sysvals.iscronjob: - doError('-reboot and -cronjob are incompatible') sysvals.reboot = True elif(arg == '-manual'): sysvals.reboot = True @@ -767,58 +920,93 @@ if __name__ == '__main__': # remaining options are only for cron job use elif(arg == '-cronjob'): sysvals.iscronjob = True - if sysvals.reboot: - doError('-reboot and -cronjob are incompatible') else: doError('Invalid argument: '+arg, True) + # compatibility errors and access checks + if(sysvals.iscronjob and (sysvals.reboot or \ + sysvals.dmesgfile or sysvals.ftracefile or cmd)): + doError('-cronjob is meant for batch purposes only') + if(sysvals.reboot and (sysvals.dmesgfile or sysvals.ftracefile)): + doError('-reboot and -dmesg/-ftrace are incompatible') + if cmd or sysvals.reboot or sysvals.iscronjob or testrun: + sysvals.rootCheck(True) + if (testrun and sysvals.useftrace) or cmd == 'flistall': + if not sysvals.verifyFtrace(): + doError('Ftrace is not properly enabled') + + # run utility commands + sysvals.cpuInfo() if cmd != '': - if cmd == 'updategrub': - updateGrub() + if cmd == 'kpupdate': + updateKernelParams() elif cmd == 'flistall': - sysvals.getFtraceFilterFunctions(False) + for f in sysvals.getBootFtraceFilterFunctions(): + print f + elif cmd == 'checkbl': + sysvals.getBootLoader() + print 'Boot Loader: %s\n%s' % (sysvals.bootloader, sysvals.blexec) + elif(cmd == 'sysinfo'): + sysvals.printSystemInfo() sys.exit() - # update grub, setup a cronjob, and reboot + # reboot: update grub, setup a cronjob, and reboot if sysvals.reboot: + if (sysvals.useftrace or sysvals.usecallgraph) and \ + not sysvals.checkFtraceKernelVersion(): + doError('Ftrace functionality requires kernel v4.10 or newer') if not sysvals.manual: - updateGrub() + updateKernelParams() updateCron() call('reboot') else: sysvals.manualRebootRequired() sys.exit() - # disable the cronjob + # cronjob: remove the cronjob, grub changes, and disable ftrace if sysvals.iscronjob: updateCron(True) - updateGrub(True) + updateKernelParams(True) + try: + sysvals.fsetVal('0', 'tracing_on') + except: + pass - data = loadKernelLog() - if sysvals.useftrace: - loadTraceLog(data) - if sysvals.iscronjob: - try: - sysvals.fsetVal('0', 'tracing_on') - except: - pass + # testrun: generate copies of the logs + if testrun: + retrieveLogs() + else: + sysvals.setOutputFile() - if(sysvals.outfile and sysvals.phoronix): - fp = open(sysvals.outfile, 'w') - fp.write('pass %s initstart %.3f end %.3f boot %s\n' % - (data.valid, data.initstart*1000, data.end*1000, data.boottime)) - fp.close() - if(not data.valid): - if sysvals.dmesgfile: + # process the log data + if sysvals.dmesgfile: + data = parseKernelLog() + if(not data.valid): doError('No initcall data found in %s' % sysvals.dmesgfile) - else: - doError('No initcall data found, is initcall_debug enabled?') + if sysvals.useftrace and sysvals.ftracefile: + parseTraceLog(data) + else: + doError('dmesg file required') print(' Host: %s' % sysvals.hostname) print(' Test time: %s' % sysvals.testtime) print(' Boot time: %s' % data.boottime) print('Kernel Version: %s' % sysvals.kernel) print(' Kernel start: %.3f' % (data.start * 1000)) - print(' init start: %.3f' % (data.initstart * 1000)) + print('Usermode start: %.3f' % (data.tUserMode * 1000)) + print('Last Init Call: %.3f' % (data.end * 1000)) + + # handle embedded output logs + if(sysvals.outfile and sysvals.embedded): + fp = open(sysvals.outfile, 'w') + fp.write('pass %s initstart %.3f end %.3f boot %s\n' % + (data.valid, data.tUserMode*1000, data.end*1000, data.boottime)) + fp.close() + + createBootGraph(data) - createBootGraph(data, sysvals.phoronix) + # if running as root, change output dir owner to sudo_user + if testrun and os.path.isdir(sysvals.testdir) and \ + os.getuid() == 0 and 'SUDO_USER' in os.environ: + cmd = 'chown -R {0}:{0} {1} > /dev/null 2>&1' + call(cmd.format(os.environ['SUDO_USER'], sysvals.testdir), shell=True) diff --git a/tools/power/pm-graph/analyze_suspend.py b/tools/power/pm-graph/analyze_suspend.py index a9206e67fc1f1b0385b08323fbf36ebcb05e910c..1b60fe2037414c93018dd1a5075e794fc2c38e1f 100755 --- a/tools/power/pm-graph/analyze_suspend.py +++ b/tools/power/pm-graph/analyze_suspend.py @@ -68,10 +68,12 @@ from subprocess import call, Popen, PIPE # store system values and test parameters class SystemValues: title = 'SleepGraph' - version = '4.6' + version = '4.7' ansi = False verbose = False - addlogs = False + testlog = True + dmesglog = False + ftracelog = False mindevlen = 0.0 mincglen = 0.0 cgphase = '' @@ -79,10 +81,11 @@ class SystemValues: max_graph_depth = 0 callloopmaxgap = 0.0001 callloopmaxlen = 0.005 + cpucount = 0 + memtotal = 204800 srgap = 0 cgexp = False - outdir = '' - testdir = '.' + testdir = '' tpath = '/sys/kernel/debug/tracing/' fpdtpath = '/sys/firmware/acpi/tables/FPDT' epath = '/sys/kernel/debug/tracing/events/power/' @@ -95,14 +98,17 @@ class SystemValues: testcommand = '' mempath = '/dev/mem' powerfile = '/sys/power/state' + mempowerfile = '/sys/power/mem_sleep' suspendmode = 'mem' + memmode = '' hostname = 'localhost' prefix = 'test' teststamp = '' + sysstamp = '' dmesgstart = 0.0 dmesgfile = '' ftracefile = '' - htmlfile = '' + htmlfile = 'output.html' embedded = False rtcwake = True rtcwaketime = 15 @@ -127,9 +133,6 @@ class SystemValues: devpropfmt = '# Device Properties: .*' tracertypefmt = '# tracer: (?P.*)' firmwarefmt = '# fwsuspend (?P[0-9]*) fwresume (?P[0-9]*)$' - stampfmt = '# suspend-(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})-'+\ - '(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})'+\ - ' (?P.*) (?P.*) (?P.*)$' tracefuncs = { 'sys_sync': dict(), 'pm_prepare_console': dict(), @@ -218,7 +221,7 @@ class SystemValues: # if this is a phoronix test run, set some default options if('LOG_FILE' in os.environ and 'TEST_RESULTS_IDENTIFIER' in os.environ): self.embedded = True - self.addlogs = True + self.dmesglog = self.ftracelog = True self.htmlfile = os.environ['LOG_FILE'] self.archargs = 'args_'+platform.machine() self.hostname = platform.node() @@ -233,6 +236,13 @@ class SystemValues: self.rtcpath = rtc if (hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()): self.ansi = True + self.testdir = datetime.now().strftime('suspend-%y%m%d-%H%M%S') + def rootCheck(self, fatal=True): + if(os.access(self.powerfile, os.W_OK)): + return True + if fatal: + doError('This command requires sysfs mount and root access') + return False def rootUser(self, fatal=False): if 'USER' in os.environ and os.environ['USER'] == 'root': return True @@ -249,30 +259,60 @@ class SystemValues: args['date'] = n.strftime('%y%m%d') args['time'] = n.strftime('%H%M%S') args['hostname'] = self.hostname - self.outdir = value.format(**args) + return value.format(**args) def setOutputFile(self): - if((self.htmlfile == '') and (self.dmesgfile != '')): + if self.dmesgfile != '': m = re.match('(?P.*)_dmesg\.txt$', self.dmesgfile) if(m): self.htmlfile = m.group('name')+'.html' - if((self.htmlfile == '') and (self.ftracefile != '')): + if self.ftracefile != '': m = re.match('(?P.*)_ftrace\.txt$', self.ftracefile) if(m): self.htmlfile = m.group('name')+'.html' - if(self.htmlfile == ''): - self.htmlfile = 'output.html' - def initTestOutput(self, subdir, testpath=''): + def systemInfo(self, info): + p = c = m = b = '' + if 'baseboard-manufacturer' in info: + m = info['baseboard-manufacturer'] + elif 'system-manufacturer' in info: + m = info['system-manufacturer'] + if 'baseboard-product-name' in info: + p = info['baseboard-product-name'] + elif 'system-product-name' in info: + p = info['system-product-name'] + if 'processor-version' in info: + c = info['processor-version'] + if 'bios-version' in info: + b = info['bios-version'] + self.sysstamp = '# sysinfo | man:%s | plat:%s | cpu:%s | bios:%s | numcpu:%d | memsz:%d' % \ + (m, p, c, b, self.cpucount, self.memtotal) + def printSystemInfo(self): + self.rootCheck(True) + out = dmidecode(self.mempath, True) + fmt = '%-24s: %s' + for name in sorted(out): + print fmt % (name, out[name]) + print fmt % ('cpucount', ('%d' % self.cpucount)) + print fmt % ('memtotal', ('%d kB' % self.memtotal)) + def cpuInfo(self): + self.cpucount = 0 + fp = open('/proc/cpuinfo', 'r') + for line in fp: + if re.match('^processor[ \t]*:[ \t]*[0-9]*', line): + self.cpucount += 1 + fp.close() + fp = open('/proc/meminfo', 'r') + for line in fp: + m = re.match('^MemTotal:[ \t]*(?P[0-9]*) *kB', line) + if m: + self.memtotal = int(m.group('sz')) + break + fp.close() + def initTestOutput(self, name): self.prefix = self.hostname v = open('/proc/version', 'r').read().strip() kver = string.split(v)[2] - n = datetime.now() - testtime = n.strftime('suspend-%m%d%y-%H%M%S') - if not testpath: - testpath = n.strftime('suspend-%y%m%d-%H%M%S') - if(subdir != "."): - self.testdir = subdir+"/"+testpath - else: - self.testdir = testpath + fmt = name+'-%m%d%y-%H%M%S' + testtime = datetime.now().strftime(fmt) self.teststamp = \ '# '+testtime+' '+self.prefix+' '+self.suspendmode+' '+kver if(self.embedded): @@ -355,7 +395,7 @@ class SystemValues: continue self.tracefuncs[i] = dict() def getFtraceFilterFunctions(self, current): - rootCheck(True) + self.rootCheck(True) if not current: call('cat '+self.tpath+'available_filter_functions', shell=True) return @@ -453,7 +493,7 @@ class SystemValues: val += '\nr:%s_ret %s $retval\n' % (name, func) return val def addKprobes(self, output=False): - if len(sysvals.kprobes) < 1: + if len(self.kprobes) < 1: return if output: print(' kprobe functions in this kernel:') @@ -525,7 +565,7 @@ class SystemValues: fp.flush() fp.close() except: - pass + return False return True def fgetVal(self, path): file = self.tpath+path @@ -566,9 +606,15 @@ class SystemValues: self.cleanupFtrace() # set the trace clock to global self.fsetVal('global', 'trace_clock') - # set trace buffer to a huge value self.fsetVal('nop', 'current_tracer') - self.fsetVal('131073', 'buffer_size_kb') + # set trace buffer to a huge value + if self.usecallgraph or self.usedevsrc: + tgtsize = min(self.memtotal / 2, 2*1024*1024) + maxbuf = '%d' % (tgtsize / max(1, self.cpucount)) + if self.cpucount < 1 or not self.fsetVal(maxbuf, 'buffer_size_kb'): + self.fsetVal('131072', 'buffer_size_kb') + else: + self.fsetVal('16384', 'buffer_size_kb') # go no further if this is just a status check if testing: return @@ -641,6 +687,15 @@ class SystemValues: if not self.ansi: return str return '\x1B[%d;40m%s\x1B[m' % (color, str) + def writeDatafileHeader(self, filename, fwdata=[]): + fp = open(filename, 'w') + fp.write(self.teststamp+'\n') + fp.write(self.sysstamp+'\n') + if(self.suspendmode == 'mem' or self.suspendmode == 'command'): + for fw in fwdata: + if(fw): + fp.write('# fwsuspend %u fwresume %u\n' % (fw[0], fw[1])) + fp.close() sysvals = SystemValues() suspendmodename = { @@ -1008,6 +1063,12 @@ class Data: else: self.trimTime(self.tSuspended, \ self.tResumed-self.tSuspended, False) + def getTimeValues(self): + sktime = (self.dmesg['suspend_machine']['end'] - \ + self.tKernSus) * 1000 + rktime = (self.dmesg['resume_complete']['end'] - \ + self.dmesg['resume_machine']['start']) * 1000 + return (sktime, rktime) def setPhase(self, phase, ktime, isbegin): if(isbegin): self.dmesg[phase]['start'] = ktime @@ -1517,7 +1578,7 @@ class FTraceCallGraph: prelinedep += 1 last = 0 lasttime = line.time - virtualfname = 'execution_misalignment' + virtualfname = 'missing_function_name' if len(self.list) > 0: last = self.list[-1] lasttime = last.time @@ -1773,24 +1834,30 @@ class Timeline: html_device = '
    {6}
    \n' html_phase = '
    {5}
    \n' html_phaselet = '
    \n' + html_legend = '
     {2}
    \n' def __init__(self, rowheight, scaleheight): self.rowH = rowheight self.scaleH = scaleheight self.html = '' - def createHeader(self, sv, suppress=''): + def createHeader(self, sv): if(not sv.stamp['time']): return self.html += '
    ' \ % (sv.title, sv.version) - if sv.logmsg and 'log' not in suppress: - self.html += '' - if sv.addlogs and 'dmesg' not in suppress: - self.html += '' - if sv.addlogs and sv.ftracefile and 'ftrace' not in suppress: - self.html += '' + if sv.logmsg and sv.testlog: + self.html += '' + if sv.dmesglog: + self.html += '' + if sv.ftracelog: + self.html += '' headline_stamp = '
    {0} {1} {2} {3}
    \n' self.html += headline_stamp.format(sv.stamp['host'], sv.stamp['kernel'], sv.stamp['mode'], sv.stamp['time']) + if 'man' in sv.stamp and 'plat' in sv.stamp and 'cpu' in sv.stamp: + headline_sysinfo = '
    {0} {1} with {2}
    \n' + self.html += headline_sysinfo.format(sv.stamp['man'], + sv.stamp['plat'], sv.stamp['cpu']) + # Function: getDeviceRows # Description: # determine how may rows the device funcs will take @@ -1839,7 +1906,7 @@ class Timeline: # devlist: the list of devices/actions in a group of contiguous phases # Output: # The total number of rows needed to display this phase of the timeline - def getPhaseRows(self, devlist, row=0): + def getPhaseRows(self, devlist, row=0, sortby='length'): # clear all rows and set them to undefined remaining = len(devlist) rowdata = dict() @@ -1852,8 +1919,12 @@ class Timeline: if tp not in myphases: myphases.append(tp) dev['row'] = -1 - # sort by length 1st, then name 2nd - sortdict[item] = (float(dev['end']) - float(dev['start']), item.dev['name']) + if sortby == 'start': + # sort by start 1st, then length 2nd + sortdict[item] = (-1*float(dev['start']), float(dev['end']) - float(dev['start'])) + else: + # sort by length 1st, then name 2nd + sortdict[item] = (float(dev['end']) - float(dev['start']), item.dev['name']) if 'src' in dev: dev['devrows'] = self.getDeviceRows(dev['src']) # sort the devlist by length so that large items graph on top @@ -1995,8 +2066,13 @@ class Timeline: # A list of values describing the properties of these test runs class TestProps: stamp = '' + sysinfo = '' S0i3 = False fwdata = [] + stampfmt = '# [a-z]*-(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})-'+\ + '(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})'+\ + ' (?P.*) (?P.*) (?P.*)$' + sysinfofmt = '^# sysinfo .*' ftrace_line_fmt_fg = \ '^ *(?P